From 0d390c912263d6388ed875ee4972e8094e2ee9c0 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 13 Oct 2011 23:59:24 +0200 Subject: [PATCH 0001/1435] Fix a signedness warning Signed-off-by: Karl Palsson --- src/stlink-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 79709ac0b..ebd6e3558 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -163,7 +163,7 @@ void _stlink_usb_version(stlink_t *sl) { #if 1 /* DEBUG */ { - unsigned int i; + ssize_t i; for (i = 0; i < size; ++i) printf("%02x", buf[i]); printf("\n"); } From 4aa64b2daa46f5a36d8fa10a932833fcf66ee6f6 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 13 Oct 2011 23:25:46 +0200 Subject: [PATCH 0002/1435] Size all USB receive operations Signed-off-by: Karl Palsson --- src/stlink-usb.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index ebd6e3558..5099bfd4f 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -155,7 +155,7 @@ void _stlink_usb_version(stlink_t *sl) { buf[0] = STLINK_GET_VERSION; buf[1] = 0x80; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 6); if (size == -1) { printf("[!] send_recv\n"); return; @@ -211,7 +211,7 @@ int _stlink_usb_current_mode(stlink_t * sl) { 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, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2); if (size == -1) { printf("[!] send_recv\n"); return -1; @@ -228,7 +228,7 @@ void _stlink_usb_core_id(stlink_t * sl) { buf[0] = STLINK_DEBUG_COMMAND; buf[1] = STLINK_DEBUG_READCOREID; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 4); if (size == -1) { printf("[!] send_recv\n"); return; @@ -247,7 +247,7 @@ void _stlink_usb_status(stlink_t * sl) { buf[0] = STLINK_DEBUG_COMMAND; buf[1] = STLINK_DEBUG_GETSTATUS; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2); if (size == -1) { printf("[!] send_recv\n"); return; @@ -271,7 +271,7 @@ void _stlink_usb_force_debug(stlink_t *sl) { buf[0] = STLINK_DEBUG_COMMAND; buf[1] = STLINK_DEBUG_FORCEDEBUG; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2); if (size == -1) { printf("[!] send_recv\n"); return; @@ -290,7 +290,7 @@ void _stlink_usb_enter_swd_mode(stlink_t * sl) { buf[1] = STLINK_SWD_ENTER; buf[2] = STLINK_DEBUG_ENTER_SWD; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2); if (size == -1) { printf("[!] send_recv\n"); return; @@ -343,7 +343,7 @@ void _stlink_usb_step(stlink_t* sl) { buf[0] = STLINK_DEBUG_COMMAND; buf[1] = STLINK_DEBUG_STEPCORE; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2); if (size == -1) { printf("[!] send_recv\n"); return; @@ -363,7 +363,7 @@ void _stlink_usb_run(stlink_t* sl) { buf[0] = STLINK_DEBUG_COMMAND; buf[1] = STLINK_DEBUG_RUNCORE; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2); if (size == -1) { printf("[!] send_recv\n"); return; @@ -404,7 +404,7 @@ void _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { assert (len < 256); buf[6] = (uint8_t) len; - size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, len); if (size == -1) { printf("[!] send_recv\n"); return; From 06a737c4cc2aa1238fcb44f422e139e1c147c41f Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 14 Oct 2011 00:03:06 +0200 Subject: [PATCH 0003/1435] Assert size only if Q_BUF_LEN is smaller UINT16_MAX Signed-off-by: Karl Palsson --- src/stlink-usb.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 5099bfd4f..b417d41aa 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -182,6 +182,9 @@ void _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { 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); stlink_print_data(sl); send_only(slu, buf, len); @@ -200,6 +203,9 @@ void _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { 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 stlink_print_data(sl); send_only(slu, buf, len); } @@ -392,8 +398,9 @@ void _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { unsigned char* const buf = sl->q_buf; ssize_t size; - /* assume len < sizeof(sl->q_buf) */ - assert(len < sizeof(sl->q_buf)); // makes a compiler warning? always true? +#if Q_BUF_LEN < UINT16_MAX + assert(len < sizeof(sl->q_buf)); +#endif memset(buf, 0, sizeof (sl->q_buf)); buf[0] = STLINK_DEBUG_COMMAND; From 7abc08eeefdd4128ca55bcece97eda9c54a9e5bb Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 14 Oct 2011 00:06:41 +0200 Subject: [PATCH 0004/1435] Remove some debug output Signed-off-by: Karl Palsson --- src/stlink-usb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index b417d41aa..7bcff82da 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -186,7 +186,6 @@ void _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { assert(len < sizeof(sl->q_buf)); // makes a compiler warning? always true? #endif assert((len & 3) == 0); - stlink_print_data(sl); send_only(slu, buf, len); } @@ -206,7 +205,6 @@ void _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { #if Q_BUF_LEN < UINT16_MAX assert(len < sizeof(sl->q_buf)); // makes a compiler warning? always true? #endif - stlink_print_data(sl); send_only(slu, buf, len); } From a4e5aba21e022750633039fab9efa4119062e096 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 22 Oct 2011 02:06:07 +0000 Subject: [PATCH 0005/1435] Fix character encodings of st provided files. --- example/lcd/stm32l_discovery_lcd.c | 4 ++-- example/lcd/stm32l_discovery_lcd.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/example/lcd/stm32l_discovery_lcd.c b/example/lcd/stm32l_discovery_lcd.c index 64163de40..982a5f259 100644 --- a/example/lcd/stm32l_discovery_lcd.c +++ b/example/lcd/stm32l_discovery_lcd.c @@ -281,7 +281,7 @@ static void LCD_Conv_Char_Seg(uint8_t* c,bool point,bool column, uint8_t* digit) ch = star; break; - case '' : + case 'µ' : ch = C_UMAP; break; @@ -301,7 +301,7 @@ static void LCD_Conv_Char_Seg(uint8_t* c,bool point,bool column, uint8_t* digit) ch = C_slatch; break; - case '' : + case '°' : ch = C_percent_1; break; case '%' : diff --git a/example/lcd/stm32l_discovery_lcd.h b/example/lcd/stm32l_discovery_lcd.h index d496b8400..bb8b0d742 100644 --- a/example/lcd/stm32l_discovery_lcd.h +++ b/example/lcd/stm32l_discovery_lcd.h @@ -85,7 +85,7 @@ MSB { 1 , 1 , 0 , 0 } #define BAR3_ON t_bar[0] |= 2 #define BAR3_OFF t_bar[0] &= ~2 -/* code for '' character */ +/* code for 'µ' character */ #define C_UMAP 0x6084 /* code for 'm' character */ @@ -103,7 +103,7 @@ MSB { 1 , 1 , 0 , 0 } /* constant code for '/' */ #define C_slatch 0x00c0 -/* constant code for */ +/* constant code for ° */ #define C_percent_1 0xec00 /* constant code for small o */ From 234e144d5d5aba4fcbe1a9fd9563023f1ca81a57 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 22 Oct 2011 02:06:35 +0000 Subject: [PATCH 0006/1435] Add debug flag by default, no need not to have it in the elf. --- example/blink/Makefile | 2 +- example/lcd/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/blink/Makefile b/example/blink/Makefile index 1b310b176..0f4f71277 100644 --- a/example/blink/Makefile +++ b/example/blink/Makefile @@ -4,7 +4,7 @@ BIN_IMAGE=blink.bin CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy -CFLAGS=-O2 -mlittle-endian -mthumb +CFLAGS=-O2 -mlittle-endian -mthumb -g CFLAGS+=-mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc # to run from SRAM diff --git a/example/lcd/Makefile b/example/lcd/Makefile index 0febe4912..0f31ae68b 100644 --- a/example/lcd/Makefile +++ b/example/lcd/Makefile @@ -2,7 +2,7 @@ ELF=lcd.elf CC=arm-none-eabi-gcc -CFLAGS=-O2 -mlittle-endian -mthumb +CFLAGS=-O2 -mlittle-endian -mthumb -g CFLAGS+=-mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc CFLAGS+=-I. From 9bc72d4519e63fb1cf657a6c93008eaa8989fd01 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 22 Oct 2011 02:11:04 +0000 Subject: [PATCH 0007/1435] 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 78d3fb552..44d2e4ddf 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 ca1df75a0..0abaac620 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 4c3b44b83..c5bb1d9a1 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 4d1929c96..e3795fc32 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 cef3632ac..d1ba4fdbd 100644 --- a/doc/tutorial/tutorial.tex +++ b/doc/tutorial/tutorial.tex @@ -56,30 +56,37 @@ \section{Installing STLINK} (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 @@ \section{Building and running a program} 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 @@ \section{Building and running a program} $> 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 @@ \section{Building and running a program} 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 @@ \subsection{libstm32l\_discovery} \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 0f4f71277..e5f704525 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 929e3b9c1..0889b8161 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 000000000..77764715d --- /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 000000000..e93fd728a --- /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 000000000..4ec8203b0 --- /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 000000000..146b16ecc --- /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 000000000..6deab320c --- /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 fe0dff7ce..8a30b4113 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 c8b15e0b9..e47417437 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 e9d2774f3..a8d1b90aa 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 72f433ffe..67f0be0e6 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 cb6c6cc09..9481609f6 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 f8865e1e4..b8220de13 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 2433d6c16..ff9ef71de 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 @@ stlink_t* stlink_open_usb(const char *dev_name, const int verbose) { 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 4ed655b7e..c632a8c41 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 137eca4cf..34fbe540c 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 bd81ec1d5..343e355a3 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); From 2f7b70f1a8ef8d1204b1d16b58c4d3a160f8156a Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 22 Oct 2011 15:13:22 +0000 Subject: [PATCH 0008/1435] Add option parsing and help Supports setting the gdb listen port Supports setting which version of stlink to use Supports setting the device to use (in case autoprobing doesn't work) --- doc/tutorial/tutorial.pdf | Bin 110077 -> 110986 bytes doc/tutorial/tutorial.tex | 12 +-- gdbserver/gdb-server.c | 182 +++++++++++++++++++++++++++++--------- 3 files changed, 145 insertions(+), 49 deletions(-) diff --git a/doc/tutorial/tutorial.pdf b/doc/tutorial/tutorial.pdf index 9202ed4dc33c1bcafdcf4db30807103a22c846c8..4ffcc3e563b3df294e331eb3fae97f9843f31817 100644 GIT binary patch delta 47877 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 BI+y?e diff --git a/doc/tutorial/tutorial.tex b/doc/tutorial/tutorial.tex index d1ba4fdbd..a5548058f 100644 --- a/doc/tutorial/tutorial.tex +++ b/doc/tutorial/tutorial.tex @@ -106,12 +106,14 @@ \section{Building and running a program} are using, you must run one of the 2 commands:\\ \begin{small} \begin{lstlisting}[frame=tb] -# STM32VL discovery kit -$> sudo ./st-util /dev/sg2 +# STM32VL discovery kit (onboard ST-link) +$> sudo ./st-util --stlinkv1 [-d /dev/sg2] -# STM32L discovery kit -# 2 dummy command line arguments needed, will be fixed soon -$> sudo ./st-util fu bar +# STM32L discovery kit (onboard ST-link/V2) +$> sudo ./st-util + +# Full help for other options (listen port, version) +$> ./st-util --help \end{lstlisting} \end{small} diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 67f0be0e6..30ee01483 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -6,6 +6,7 @@ license that can be found in the LICENSE file. */ +#include #include #include #include @@ -20,6 +21,12 @@ #include "gdb-remote.h" +#define DEFAULT_LOGGING_LEVEL 10 +#define DEFAULT_GDB_LISTEN_PORT 4242 + +#define STRINGIFY_inner(name) #name +#define STRINGIFY(name) STRINGIFY_inner(name) + #define FLASH_BASE 0x08000000 #define FLASH_PAGE (sl->flash_pgsz) #define FLASH_PAGE_MASK (~((1 << 10) - 1)) @@ -77,79 +84,168 @@ struct chip_params { { 0 } }; +typedef struct _st_state_t { + // things from command line, bleh + int stlink_version; + // "/dev/serial/by-id/usb-FTDI_TTL232R-3V3_FTE531X6-if00-port0" is only 58 chars + char devicename[100]; + int logging_level; + int listen_port; +} st_state_t; + + int serve(stlink_t *sl, int port); char* make_memory_map(const struct chip_params *params, uint32_t flash_size); -int main(int argc, char** argv) { - - stlink_t *sl = NULL; - const char * HelpStr = "Usage:\n" - "\t st-util port [/dev/sgX]\n" - "\t st-util [port]\n" - "\t st-util --help\n"; +int parse_options(int argc, char** argv, st_state_t *st) { + static struct option long_options[] = { + {"help", no_argument, NULL, 'h'}, + {"verbose", optional_argument, NULL, 'v'}, + {"device", required_argument, NULL, 'd'}, + {"stlink_version", required_argument, NULL, 's'}, + {"stlinkv1", no_argument, NULL, '1'}, + {"listen_port", required_argument, NULL, 'p'}, + {0, 0, 0, 0}, + }; + const char * help_str = "%s - usage:\n\n" + " -h, --help\t\tPrint this help\n" + " -vXX, --verbose=XX\tspecify a specific verbosity level (0..99)\n" + " -v, --verbose\tspecify generally verbose logging\n" + " -d , --device=/dev/stlink2_1\n" + "\t\t\tWhere is your stlink device connected?\n" + " -s X, --stlink_version=X\n" + "\t\t\tChoose what version of stlink to use, (defaults to 2)\n" + " -1, --stlinkv1\tForce stlink version 1\n" + " -p 4242, --listen_port=1234\n" + "\t\t\tSet the gdb server listen port. " + "(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n" + ; + + + int option_index = 0; + int c; + int q; + while ((c = getopt_long(argc, argv, "hv::d:s:1p:", long_options, &option_index)) != -1) { + switch (c) { + case 0: + printf("XXXXX Shouldn't really normally come here, only if there's no corresponding option\n"); + printf("option %s", long_options[option_index].name); + if (optarg) { + printf(" with arg %s", optarg); + } + printf("\n"); + break; + case 'h': + printf(help_str, argv[0]); + exit(EXIT_SUCCESS); + break; + case 'v': + if (optarg) { + st->logging_level = atoi(optarg); + } else { + st->logging_level = DEFAULT_LOGGING_LEVEL; + } + break; + case 'd': + if (strlen(optarg) > sizeof (st->devicename)) { + fprintf(stderr, "device name too long: %ld\n", strlen(optarg)); + } else { + strcpy(st->devicename, optarg); + } + break; + case '1': + st->stlink_version = 1; + break; + case 's': + sscanf(optarg, "%i", &q); + if (q < 0 || q > 2) { + fprintf(stderr, "stlink version %d unknown!\n", q); + exit(EXIT_FAILURE); + } + st->stlink_version = q; + break; + case 'p': + sscanf(optarg, "%i", &q); + if (q < 0) { + fprintf(stderr, "Can't use a negative port to listen on: %d\n", q); + exit(EXIT_FAILURE); + } + st->listen_port = q; + break; + } + } + + if (optind < argc) { + printf("non-option ARGV-elements: "); + while (optind < argc) + printf("%s ", argv[optind++]); + printf("\n"); + } + return 0; +} - switch(argc) { - case 3 : { - //sl = stlink_quirk_open(argv[2], 0); - // FIXME - hardcoded to usb.... - sl = stlink_open_usb(10); - if(sl == NULL) return 1; - break; - } +int main(int argc, char** argv) { - case 2 : { - if (strcmp(argv[1], "--help") == 0) { - fprintf(stdout, HelpStr, NULL); - return 1; - } - } + stlink_t *sl = NULL; -#if CONFIG_USE_LIBSG - case 1 : { // Search ST-LINK (from /dev/sg0 to /dev/sg99) + st_state_t state; + memset(&state, 0, sizeof(state)); + // set defaults... + state.stlink_version = 2; + state.logging_level = 10; + state.listen_port = DEFAULT_GDB_LISTEN_PORT; + parse_options(argc, argv, &state); + switch (state.stlink_version) { + case 2: + sl = stlink_open_usb(state.logging_level); + if(sl == NULL) return 1; + break; + case 1: +#if (CONFIG_USE_LIBSG == 1) + if (strlen(state.devicename) == 0) { const int DevNumMax = 99; int ExistDevCount = 0; - for(int DevNum = 0; DevNum <= DevNumMax; DevNum++) - { - if(DevNum < 10) { + for (int DevNum = 0; DevNum <= DevNumMax; DevNum++) { + if (DevNum < 10) { char DevName[] = "/dev/sgX"; const int X_index = 7; DevName[X_index] = DevNum + '0'; - if ( !access(DevName, F_OK) ) { + if (!access(DevName, F_OK)) { sl = stlink_quirk_open(DevName, 0); ExistDevCount++; } - } - else if(DevNum < 100) { + } else if (DevNum < 100) { char DevName[] = "/dev/sgXY"; const int X_index = 7; const int Y_index = 8; - DevName[X_index] = DevNum/10 + '0'; - DevName[Y_index] = DevNum%10 + '0'; - if ( !access(DevName, F_OK) ) { + DevName[X_index] = DevNum / 10 + '0'; + DevName[Y_index] = DevNum % 10 + '0'; + if (!access(DevName, F_OK)) { sl = stlink_quirk_open(DevName, 0); ExistDevCount++; } } - if(sl != NULL) break; + if (sl != NULL) break; } - if(sl == NULL) { + if (sl == NULL) { fprintf(stdout, "\nNumber of /dev/sgX devices found: %i \n", - ExistDevCount); + ExistDevCount); fprintf(stderr, "ST-LINK not found\n"); return 1; } - break; + } else { + sl = stlink_quirk_open(state.devicename, state.logging_level); } + break; +#else + fprintf(stderr, "Support for stlink v1 disabled at build time...\n"); + fprintf(stderr, "Perhaps you're on OSX, and we haven't finished removing the libsg deps?\n"); + exit(EXIT_FAILURE); #endif - - default: { - fprintf(stderr, HelpStr, NULL); - return 1; - } } if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { @@ -200,9 +296,7 @@ int main(int argc, char** argv) { // memory map is in 1k blocks. current_memory_map = make_memory_map(params, flash_size * 0x400); - int port = 4242; - - while(serve(sl, port) == 0); + while(serve(sl, state.listen_port) == 0); /* Switch back to mass storage mode before closing. */ stlink_run(sl); From aa479e5b91a2dfd963fcc3063196bee7e159a2aa Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 22 Oct 2011 15:22:24 +0000 Subject: [PATCH 0009/1435] Update netbeans project config to reflect combined makefiles --- ...ge-gdbserver.bash => Package-Default.bash} | 2 +- nbproject/Package-library_cli.bash | 75 --- nbproject/configurations.xml | 502 ++++++++++++++++-- nbproject/project.xml | 6 +- 4 files changed, 458 insertions(+), 127 deletions(-) rename nbproject/{Package-gdbserver.bash => Package-Default.bash} (98%) delete mode 100644 nbproject/Package-library_cli.bash diff --git a/nbproject/Package-gdbserver.bash b/nbproject/Package-Default.bash similarity index 98% rename from nbproject/Package-gdbserver.bash rename to nbproject/Package-Default.bash index 722b818f6..f6abfb43c 100644 --- a/nbproject/Package-gdbserver.bash +++ b/nbproject/Package-Default.bash @@ -7,7 +7,7 @@ # Macros TOP=`pwd` CND_PLATFORM=GNU-Linux-x86 -CND_CONF=gdbserver +CND_CONF=Default CND_DISTDIR=dist CND_BUILDDIR=build NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging diff --git a/nbproject/Package-library_cli.bash b/nbproject/Package-library_cli.bash deleted file mode 100644 index 5a644728b..000000000 --- a/nbproject/Package-library_cli.bash +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash -x - -# -# Generated - do not edit! -# - -# Macros -TOP=`pwd` -CND_PLATFORM=GNU-Linux-x86 -CND_CONF=library_cli -CND_DISTDIR=dist -CND_BUILDDIR=build -NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging -TMPDIRNAME=tmp-packaging -OUTPUT_PATH=test_usb -OUTPUT_BASENAME=test_usb -PACKAGE_TOP_DIR=stlink/ - -# Functions -function checkReturnCode -{ - rc=$? - if [ $rc != 0 ] - then - exit $rc - fi -} -function makeDirectory -# $1 directory path -# $2 permission (optional) -{ - mkdir -p "$1" - checkReturnCode - if [ "$2" != "" ] - then - chmod $2 "$1" - checkReturnCode - fi -} -function copyFileToTmpDir -# $1 from-file path -# $2 to-file path -# $3 permission -{ - cp "$1" "$2" - checkReturnCode - if [ "$3" != "" ] - then - chmod $3 "$2" - checkReturnCode - fi -} - -# Setup -cd "${TOP}" -mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package -rm -rf ${NBTMPDIR} -mkdir -p ${NBTMPDIR} - -# Copy files and create directories and links -cd "${TOP}" -makeDirectory "${NBTMPDIR}/stlink/bin" -copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 - - -# Generate tar file -cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/stlink.tar -cd ${NBTMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/stlink.tar * -checkReturnCode - -# Cleanup -cd "${TOP}" -rm -rf ${NBTMPDIR} diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index 3d02ea831..794a3ab5c 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -2,7 +2,105 @@ + + + + + + main.c + + + main.c + startup_stm32l1xx_md.s + system_stm32l1xx.c + + + discover_board.h + main.c + stm32l_discovery_lcd.c + stm32l_discovery_lcd.h + + + + + + + stdint.h + + + core_cm3.c + core_cm3.h + + + stm32l1xx.h + system_stm32l1xx.h + + misc.h + stm32l1xx_adc.h + stm32l1xx_comp.h + stm32l1xx_crc.h + stm32l1xx_dac.h + stm32l1xx_dbgmcu.h + stm32l1xx_dma.h + stm32l1xx_exti.h + stm32l1xx_flash.h + stm32l1xx_gpio.h + stm32l1xx_i2c.h + stm32l1xx_iwdg.h + stm32l1xx_lcd.h + stm32l1xx_pwr.h + stm32l1xx_rcc.h + stm32l1xx_rtc.h + stm32l1xx_spi.h + stm32l1xx_syscfg.h + stm32l1xx_tim.h + stm32l1xx_usart.h + stm32l1xx_wwdg.h + + + misc.c + stm32l1xx_adc.c + stm32l1xx_comp.c + stm32l1xx_crc.c + stm32l1xx_dac.c + stm32l1xx_dbgmcu.c + stm32l1xx_dma.c + stm32l1xx_exti.c + stm32l1xx_flash.c + stm32l1xx_flash_ramfunc.c + stm32l1xx_gpio.c + stm32l1xx_i2c.c + stm32l1xx_iwdg.c + stm32l1xx_lcd.c + stm32l1xx_pwr.c + stm32l1xx_rcc.c + stm32l1xx_rtc.c + stm32l1xx_spi.c + stm32l1xx_syscfg.c + stm32l1xx_tim.c + stm32l1xx_usart.c + stm32l1xx_wwdg.c + + + + discover_board.h + discover_functions.c + discover_functions.h + icc_measure.c + icc_measure.h + icc_measure_Ram.c + main.c + stm32_tsl_conf.h + stm32l1xx_conf.h + stm32l1xx_it.c + stm32l1xx_it.h + stm32l_discovery_lcd.c + stm32l_discovery_lcd.h + system_stm32l1xx.c + + + main.c @@ -20,81 +118,393 @@ test_sg.c test_usb.c - + + + + stlink-hw.h + + + + + + + + + + + + + + + + + + - build/Makefile + Makefile ^(nbproject)$ . - build/Makefile + Makefile - - - LOCAL_SOURCES - default - - - - - ${MAKE} -f Makefile - ${MAKE} -f Makefile clean - test_usb - - - stm32l/src - /usr/include/libusb-1.0 - stm32l/build - src - - - CONFIG_USE_LIBUSB=1 - __GNUC_STDC_INLINE__=1 - __OPTIMIZE__=1 - __REGISTER_PREFIX__= - __STDC_VERSION__=199901L - __USER_LABEL_PREFIX__= - - - - - - + LOCAL_SOURCES default - gdbserver + . ${MAKE} -f Makefile ${MAKE} -f Makefile clean gdbserver/st-util - - stm32l/src - /usr/include/libusb-1.0 - stm32l/build - src - + CONFIG_USE_LIBSG=1 CONFIG_USE_LIBUSB=1 - __GNUC_STDC_INLINE__=1 - __OPTIMIZE__=1 - __REGISTER_PREFIX__= - __STDC_VERSION__=199901L - __USER_LABEL_PREFIX__= + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + src + + + + + + + . + + + DEBUG=1 + + + + + + + + + diff --git a/nbproject/project.xml b/nbproject/project.xml index 660863635..cd5248661 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -14,11 +14,7 @@ - library_cli - 0 - - - gdbserver + Default 0 From 85ff6038050093c1950e0ec69cd597f848bfa4c6 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 22 Oct 2011 15:46:19 +0000 Subject: [PATCH 0010/1435] Make the blink example build for all platforms. Less mucking around with make parameters, it's a tiny build. Verified with a VL and L board. Removed the old obsolete bin file --- doc/tutorial/tutorial.pdf | Bin 110986 -> 110993 bytes doc/tutorial/tutorial.tex | 8 +++-- example/blink/Makefile | 37 ++++++++++----------- example/blink/main.c | 68 ++++++++++++++------------------------ example/blink/o.bin | Bin 64 -> 0 bytes 5 files changed, 47 insertions(+), 66 deletions(-) delete mode 100755 example/blink/o.bin diff --git a/doc/tutorial/tutorial.pdf b/doc/tutorial/tutorial.pdf index 4ffcc3e563b3df294e331eb3fae97f9843f31817..371f805a0f1a4ddc103155c3fecc8c3a3fc972a0 100644 GIT binary patch delta 3270 zcmah|X*g638#agX6vrmew*_V;1ERm&9VMLZ3d$y8w(A$uu8e1fieW?_( z?~G8&g=DRmmT$VQ_x;iM@tr^Cy6$s7&;302{havsT*>db%6ay)gFtGyv=SuhnKbcg zmGKkKzR3+I^f5vUF2XctkC_VA+r9Rb*}~d7PIr#Wn@;ZT z0scgF^~Vx%OGgFA0^DU34t!;2nt$G$XcBN)OY8?7X=$L-+rHtYG?0fn4#5%s;jU;5L8<)dBMxwP&G~aCs z+jV-55fm_>>f!)yf1MZ^P2O^~dL|VZaIj2+a^m#rsfJHl--orMe~biKUG6vOM7QCR zyN78ZR^Nt#=C>#GdIKwLvk$II#auE!FB+KkBz72;MDg}U_8!$-3eSSB-kD#T7#eHp zM)t;=m_?9JiyVFJ)u0~yTgyc(GwL&3Lg#CoK|ogZeed$B*V#+6OHv_w5&5>d55?a_ zsQg3D8rYA+cD=|EFLXzdP9rSG{I1yz1${ zV;iI@zKH}sF8_8McZB~ZEExK2j|9;vy&Og zk-}&s)^L~Kmy~qqxf|Q8#fiWqDmit|rX@!b6!mXzz-wW@rclaUu zO2uqzu#WHQBwgP=YI-ZTSnc_dm7;k&98J@UQ8c@JL_7Pzc#bTW+vtOt; zi%VySvKW3+W2g<+=QU89Fr;4EdykRXRCeWhC+?+6=9h67bR7M8--`V76kZjjc|epG zDoJHDy?nmhYygefROWhzMmYPM05iYXU}bX}j*54BOJOFenRZ~~vcLN73I@0HE$dqE zvrv}pg+k@10IL#kI_QYVt8lE=I-ghrAUPU2)iYYZi?ZkTUGYXq`XIFedqE=7F|gdZ z#665p^Nx;AyWhr#mLQ8zm0nw=8cwa5leyWPS^7pE!H`Ed$0wwBaqpZ@hto$YSJ${M zhjwn;PnoDpfmB)Ru$tp3n97yB*P9U>>}JC2@@Gs&Vnh2Pm-o$Wn!Ae z$h#9Qp>oT`<^_o}4YFeF>v>rROzRb6S5sRJ)~3uyM649i#He?rLhux?!r$ukG-2NY z>f)XzVYa&GnrDFPe4}4@K2<9VIWSCgt`tX!k|&Bx$M_Y(rrU>IJ7wGLk^~fjo?O@- z0PWuf&Sx&Pm>6xIztYi92gfXxw=We^5n((s%u~M(9s6N(dCW4>hFagw+g?i z!yOKd_D(_jJ*{$6wcaSyem6|u@?VvUq{7_%V=ho;OpL5*68C#zl8f-k;-`@GgfulX zSzGBR;v#C4Mz#{sG~WJ6fBjkFR-y8}HHfcMgk-2(qMde{mv>(g!?jeVzAuqs)REsS zIR9afgZ3;ftph(~9e6Q@%$HgqM>sYduxBgkaNQ(2V)JZ&&ffQoHrxCYUZWXpqxq%H z@Xj0KPba;$J#xO%1ch?aryYHMGk!i=a7z@NHk}Udepklb`%TAjb)#(DX_cbrKL@=f z%C98L3iI9YqPeYI>QUsBI*c8Nk-b@C9`9m0;*j)|es94i$i(r-`pdeATbH6k86IUBJm-_qE^IdYcC$m0xbaXmib{i$vr!0Pq9t$4Y2JU%;&Erp;ZEmW zUejjVR;?d38=OaNMm9qckf+sKPqXUfZ7Lm$uuJje6E2DrL@(C7Bj~Fgs`+5>X0)-@ zNEA6%Y4_P|&ZA>wTZeI%eMmz1hUzhc$k{$eU7ne1cJtFzA;~DJKn%8yz5#@KY|W%m zEjNAmo1H>V(IFF)xw%xoC78WcpAc80fZPxxHuz*$VnP@V;@Ak#>yGReeby}s^GTM* zU_ioICHN83t1h}uey#{b-J>V~1VI3W0K!6Akh<{@MK)~R3^dq3LJNn_#sDC$s{tLlN<4 zRt+=?g@bm0I6SK`8o&@(MbH2NWW_Kz40b1mC;q)L^I*^f5d2pc`u7?EECxWcPK_sk zXqJm(nurg0vthtnZwq3}8w99mBc$NV2b6bR_yaYStlURN8ZfjIVmDfS2r4LI4)$=C0? Uud5rJ*&d6zR?qtr9$%X1AHCm}U1ChO^; z7?0buAK{&@KDnE677QPfho zBaMe^`9NW%*aVH`ov{dNuk@}++y7e#n35_p2QNR|6>|}Lz}D!r?Q^J$h;`5K?oe!E zZL0U5^$VPR!4YyyXt41857)prt@)^`f)3XM!7jGXbgtLgGO6B5_+?{~bT?L;{B^6s z`f-f(Yqb|Q-=N;wkNION&AH!t8K)eY;KY+YU#0ZY_TF;XJoWPv>9ZmfO6J@_lde2Q z6;fRZt~n&+t5;F^Y)<^)uBnJIq!o1KIZJNoYHmZ%*xdG~t>F{Nc7PSs4g}P?H)O!Y z$+5e0YTsdI#iwtnJVbY)({6e{$s3yW(PQTBk!|nmhOEE?yUB5$fw{_}JBlK+{T5Bd z64Ov{!Bsd3g3U))ljwd_+l@m&Zry1zkZ#h`fSLzYso zvCsbE6V~Ynd0j)iY)8^@vsC@W5B(CJ-<7AG)f=c^2(vGZP(M4WMAf^seLtyW*tDXf z@3}9PDBf>AI#cp_$1(4c&)bgaqJz1=%X=&@m8NJ&qU32~IhsO|vC6K6T$y1><)boN zsF63sLd-9ni>E(F?l-eT^lCdh7s|52wSMtg22xDe6|=N&P4^b++ zD3K+TCpy$#h1qLDjz9cLveMMzTwTXOp=zZCczp1@g;_?EO07bika4lx@z1O>A!A?6 z(P`Dqd4Sfprcj&yaZfFfz*-)bg*&W*e(lbjNOnY**v?bK&D8FSoS1&O=kvVg2{uQl z?`~1K-vIN~+wyAaKK{vpcT*YG$);zToM=ZY8Ht-!E|!`3S#Lf&cq~M+UV|4(_WtO+ zzeoQ4ciPQLCfj-X0_Sdi;N91(k@efOdn3DEdn(=|^m(P>%E)f%MgZN{=v8k!%5U)- z<x4kDnm(XqmHnJ#qO_c?fDv;tCra@&T`a3M!80C0O1zvIT0(L(mt0db9$ zks5yO%J#_krwF-EG{<%J5>K}uZ1ioRh}AXvctzgnSLiCTis~y2nhea?9s-cqN?|7W z>`}B;M9D&N*?ru^18+J@kLl&++%ju=hb}c&w)zq!26FXt6PoaW8gQyyo=#&?jzYr>@W_B2k666qnCZ!;XQBUq!YmQVuq4 zLqX9`o6sPWe&kvxC2>X6JWEt#=7HSwNQR>l<#ln&;I5X;&1e>Ns$865p836cdDr?3 zL;KPOn+F}kIgv`yjZNa&qcO-Bj#McFS{Lcu@*BP`Whs3*%LS@oe)exWQX+QVJ@j{j zq__bi*CAfiaHx}S!ky>oFM+0a2V%4?RLV2! zc^1W%lQmzqcUQ5L!;mktY^BZaVkjT8pHa92^YB(n3?v*`?IDHYhTT}v&dQVWdoxhF zr7C+}KtNal{bD%Q>Fmv(SLb~!ZcZEzw8iJi41e2%?5^~9=yq(vqTlGy2Ak#kP0?2z zyR1WjOX_49c^>Z8^H`d(R*#YhbMP+amlhYF-gVhO&jVU4D-6k`$uu}6^;cM@eDU$K z4yK2Ar%qI-&e`!E)$Hu}=o7NcqGQn)Gh^OZhiNY*omO~$MuwT>B)s5yt!QKNqt2+n zpl4Q2GM+!}uo-Acix$sw*zTvW0S1_F%h9o_w30M_B?ro#s54i{E@z&6tO@M-FdWYL z=}ouf$fsfp*2?2TdQZ*7o<~C(XO2$xw2yP*qIt%xv^js3ka zg`{bB&Tl==jfOqo%-7z1mFEfMW(#s|Z< zCQaUVe`Mp|u2o>Ey1NQfTRr?`arq0wxxu(9eY|Dcv8Z!et; zw^XAEE2E^5!tz_40D~LbeuT##X#Twtr|= zQ}557@Kn9t?2})9Hcd-J(mFIj}x!UBnF z_^U|?=>Le1C};}=V0bMLBCW+pL{Omj)qw$j>azYG(T_2Lf`&j42GA`vgR5~~A&i2`?5Lxlv>`VllyAekSNBfx()1OMX>A%XCJ!GB^{LE+V1 z#FB9QxnhJ49X258Lq;$J=)-tJ13W<=M>IAx!V__;`+_xrAsxki|Ci#RsH1~o`XBf6 W5B76$MXi>{ sudo ./st-util --stlinkv1 [-d /dev/sg2] -# STM32L discovery kit (onboard ST-link/V2) +# STM32L or STM32F4 discovery kit (onboard ST-link/V2) $> sudo ./st-util # Full help for other options (listen port, version) diff --git a/example/blink/Makefile b/example/blink/Makefile index e5f704525..cf7221da8 100644 --- a/example/blink/Makefile +++ b/example/blink/Makefile @@ -1,35 +1,32 @@ -EXECUTABLE=blink.elf -BIN_IMAGE=blink.bin - CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy -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 +DEF_CFLAGS=-g -O2 -mlittle-endian -mthumb -ffreestanding -nostdlib -nostdinc # to run from SRAM -CFLAGS+=-Wl,-Ttext,0x20000000 -Wl,-e,0x20000000 +DEF_CFLAGS+=-Wl,-Ttext,0x20000000 -Wl,-e,0x20000000 # to write to flash then run -# CFLAGS+=-Wl,-Ttext,0x08000000 -Wl,-e,0x08000000 +# DEF_CFLAGS+=-Wl,-Ttext,0x08000000 -Wl,-e,0x08000000 + +CFLAGS_VL=$(DEF_CFLAGS) -mcpu=cortex-m3 -DCONFIG_STM32VL_DISCOVERY=1 +CFLAGS_L=$(DEF_CFLAGS) -mcpu=cortex-m3 -DCONFIG_STM32L_DISCOVERY +CFLAGS_F4=$(DEF_CFLAGS) -mcpu=cortex-m4 -DCONFIG_STM32F4_DISCOVERY=1 -all: $(BIN_IMAGE) +all: blink_32VL.elf blink_32L.elf blink_F4.elf -$(BIN_IMAGE): $(EXECUTABLE) +%.bin: %.elf $(OBJCOPY) -O binary $^ $@ -$(EXECUTABLE): main.c - $(CC) $(CFLAGS) $^ -o $@ +blink_32VL.elf: main.c + $(CC) $(CFLAGS_VL) $^ -o $@ +blink_32L.elf: main.c + $(CC) $(CFLAGS_L) $^ -o $@ +blink_F4.elf: main.c + $(CC) $(CFLAGS_F4) $^ -o $@ clean: - rm -rf $(EXECUTABLE) - rm -rf $(BIN_IMAGE) + rm -rf *.elf + rm -rf *.bin .PHONY: all clean diff --git a/example/blink/main.c b/example/blink/main.c index 0889b8161..e0438a0db 100644 --- a/example/blink/main.c +++ b/example/blink/main.c @@ -7,36 +7,30 @@ typedef unsigned int uint32_t; #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 GPIOC 0x40011000 /* port C */ +#define GPIOC_CRH (GPIOC + 0x04) /* port configuration register high */ +#define LED_PORT_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 */ +#define LED_BLUE (1 << 8) /* port C, pin 8 */ +#define LED_GREEN (1 << 9) /* port C, pin 9 */ +#define LED_ORANGE 0 +#define LED_RED 0 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 GPIOB 0x40020400 /* port B */ +#define GPIOB_MODER (GPIOB + 0x00) /* port mode register */ +#define LED_PORT_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 */ +#define LED_BLUE (1 << 6) /* port B, pin 6 */ +#define LED_GREEN (1 << 7) /* port B, pin 7 */ +#define LED_ORANGE 0 +#define LED_RED 0 static inline void setup_leds(void) { @@ -44,26 +38,16 @@ static inline void setup_leds(void) *(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; -} - #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 GPIOD_MODER (GPIOD + 0x00) /* port mode register */ +#define LED_PORT_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 */ +#define LED_GREEN (1 << 12) /* port D, pin 12 */ +#define LED_ORANGE (1 << 13) /* port D, pin 13 */ +#define LED_RED (1 << 14) /* port D, pin 14 */ +#define LED_BLUE (1 << 15) /* port D, pin 15 */ static inline void setup_leds(void) { @@ -71,22 +55,20 @@ static inline void setup_leds(void) (1 << (13 * 2)) | (1 << (14 * 2)) | (1 << (15 * 2)); } +#else +#error "Architecture must be defined!" +#endif /* otherwise, error */ static inline void switch_leds_on(void) { - *(volatile uint32_t*)GPIOD_ODR = LED_GREEN | LED_ORANGE | LED_RED | LED_BLUE; + *(volatile uint32_t*)LED_PORT_ODR = LED_BLUE | LED_GREEN | LED_ORANGE | LED_RED; } static inline void switch_leds_off(void) { - *(volatile uint32_t*)GPIOD_ODR = 0; + *(volatile uint32_t*)LED_PORT_ODR = 0; } -#else -#error "Architecture must be defined!" -#endif /* otherwise, error */ - - #define delay() \ do { \ register unsigned int i; \ diff --git a/example/blink/o.bin b/example/blink/o.bin deleted file mode 100755 index 76324f796a6523d1acb35940d4d351466dd7773e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64 zcmZ?##KP?INzm!YCr0KYpIn?AKk+b1B>;Jh{$CslTs}D{b0i%2#LvvIpV9iyMIc{^ P8^mV<@~!?{eD@pxMXwtU From c37975c15730ac582945ea3ed85ac59284979819 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 22 Oct 2011 15:53:03 +0000 Subject: [PATCH 0011/1435] remove swallowing of ctrl-c No idea why this was added, but it's not necessary for anything I've found. --- gdbserver/gdb-server.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 30ee01483..e7efbf15b 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -32,12 +32,6 @@ #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; @@ -697,7 +691,6 @@ 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) { From 076f1086fa9c0dfa043300fb1776bc10e8eaa77f Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 22 Oct 2011 18:05:24 +0000 Subject: [PATCH 0012/1435] Remove all #ifdefs for sg-utils. We're starting on integration from github.com/afaerber So, instead of scanning all the usb devices, just open what we want. --- Makefile | 25 +++++------------------ flash/main.c | 5 ----- gdbserver/gdb-server.c | 6 ------ src/stlink-usb.c | 45 ++++++------------------------------------ src/stlink-usb.h | 6 ------ src/test_sg.c | 4 ---- 6 files changed, 11 insertions(+), 80 deletions(-) diff --git a/Makefile b/Makefile index c5bb1d9a1..bbd76a807 100644 --- a/Makefile +++ b/Makefile @@ -1,28 +1,13 @@ -# make ... for both libusb and libsg -# -# make CONFIG_USE_LIBSG=0 ... -# for just libusb -# +# make ... for both stlink v1 and stlink v2 support +## VPATH=src -SOURCES_LIB=stlink-common.c stlink-usb.c +SOURCES_LIB=stlink-common.c stlink-usb.c #stlink-sg.c OBJS_LIB=$(SOURCES_LIB:.c=.o) -TEST_PROGRAMS=test_usb +TEST_PROGRAMS=test_usb #test_sg 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=1 CFLAGS+=-DDEBUG=1 CFLAGS+=-std=gnu99 CFLAGS+=-Wall -Wextra @@ -63,7 +48,7 @@ distclean: clean $(MAKE) -C gdbserver clean flash: - $(MAKE) -C flash CONFIG_USE_LIBSG="$(CONFIG_USE_LIBSG)" + $(MAKE) -C flash gdbserver: $(MAKE) -C gdbserver diff --git a/flash/main.c b/flash/main.c index e47417437..a443f95f6 100644 --- a/flash/main.c +++ b/flash/main.c @@ -86,14 +86,9 @@ int main(int ac, char** av) if (o.devname != NULL) /* stlinkv1 */ { -#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 */ { diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index e7efbf15b..f1da63e45 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -197,7 +197,6 @@ int main(int argc, char** argv) { if(sl == NULL) return 1; break; case 1: -#if (CONFIG_USE_LIBSG == 1) if (strlen(state.devicename) == 0) { const int DevNumMax = 99; int ExistDevCount = 0; @@ -235,11 +234,6 @@ int main(int argc, char** argv) { sl = stlink_quirk_open(state.devicename, state.logging_level); } break; -#else - fprintf(stderr, "Support for stlink v1 disabled at build time...\n"); - fprintf(stderr, "Perhaps you're on OSX, and we haven't finished removing the libsg deps?\n"); - exit(EXIT_FAILURE); -#endif } if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { diff --git a/src/stlink-usb.c b/src/stlink-usb.c index ff9ef71de..57a4a2fdd 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -604,47 +604,14 @@ stlink_t* stlink_open_usb(const int verbose) { goto on_error; } - count = libusb_get_device_list(slu->libusb_ctx, &devs); - if (count < 0) { - printf("libusb_get_device_list\n"); - goto on_libusb_error; - } - - for (i = 0; i < count; ++i) { - dev = devs[i]; - slu->protocoll = is_stlink_device(dev, 0); - if (slu->protocoll > 0) break; - } - if (i == count) goto on_libusb_error; - - if (libusb_open(dev, &(slu->usb_handle))) { - printf("libusb_open()\n"); - goto on_libusb_error; + slu->usb_handle = libusb_open_device_with_vid_pid(slu->libusb_ctx, USB_ST_VID, USB_STLINK_32L_PID); + if (slu->usb_handle == NULL) { + // TODO - free usb context too... + free(slu); + fprintf(stderr, "Couldn't find any ST-Link/V2 devices"); + return NULL; } - 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; diff --git a/src/stlink-usb.h b/src/stlink-usb.h index c632a8c41..2f3b8cc3e 100644 --- a/src/stlink-usb.h +++ b/src/stlink-usb.h @@ -18,7 +18,6 @@ extern "C" { #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 -#if defined(CONFIG_USE_LIBUSB) struct stlink_libusb { libusb_context* libusb_ctx; libusb_device_handle* usb_handle; @@ -30,11 +29,6 @@ extern "C" { unsigned int sg_transfer_idx; unsigned int cmd_len; }; -#else -#error "it's all bad!" - struct stlink_libusb {}; -#endif - stlink_t* stlink_open_usb(const int verbose); diff --git a/src/test_sg.c b/src/test_sg.c index 34fbe540c..9efe6d80d 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -6,10 +6,6 @@ #include #include -#if CONFIG_USE_LIBSG -#include -#include -#endif #include "stlink-common.h" int main(int argc, char *argv[]) { From 42d2da531f52ead18091a1211a5e6206e27dc178 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 22 Oct 2011 19:09:31 +0000 Subject: [PATCH 0013/1435] flag out the only scsi specific code Also flag out some places where code appears unused. --- Makefile | 2 +- flash/main.c | 4 +++- gdbserver/gdb-server.c | 6 +++--- src/stlink-sg.c | 13 +++++++------ src/stlink-sg.h | 6 +----- src/stlink-usb.c | 7 ++++++- src/test_sg.c | 2 +- 7 files changed, 22 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index bbd76a807..2c73f165f 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ ## VPATH=src -SOURCES_LIB=stlink-common.c stlink-usb.c #stlink-sg.c +SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c OBJS_LIB=$(SOURCES_LIB:.c=.o) TEST_PROGRAMS=test_usb #test_sg LDFLAGS=-lusb-1.0 -L. -lstlink diff --git a/flash/main.c b/flash/main.c index a443f95f6..a74525a5a 100644 --- a/flash/main.c +++ b/flash/main.c @@ -1,5 +1,7 @@ /* simple wrapper around the stlink_flash_write function */ +// TODO - this should be done as just a simple flag to the st-util command line... + #include #include @@ -87,7 +89,7 @@ int main(int ac, char** av) if (o.devname != NULL) /* stlinkv1 */ { static const int scsi_verbose = 2; - sl = stlink_quirk_open(o.devname, scsi_verbose); + sl = stlink_v1_open(o.devname, scsi_verbose); if (sl == NULL) goto on_error; } else /* stlinkv2 */ diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index f1da63e45..3e2f99a96 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -207,7 +207,7 @@ int main(int argc, char** argv) { const int X_index = 7; DevName[X_index] = DevNum + '0'; if (!access(DevName, F_OK)) { - sl = stlink_quirk_open(DevName, 0); + sl = stlink_v1_open(DevName, 0); ExistDevCount++; } } else if (DevNum < 100) { @@ -217,7 +217,7 @@ int main(int argc, char** argv) { DevName[X_index] = DevNum / 10 + '0'; DevName[Y_index] = DevNum % 10 + '0'; if (!access(DevName, F_OK)) { - sl = stlink_quirk_open(DevName, 0); + sl = stlink_v1_open(DevName, 0); ExistDevCount++; } } @@ -231,7 +231,7 @@ int main(int argc, char** argv) { return 1; } } else { - sl = stlink_quirk_open(state.devicename, state.logging_level); + sl = stlink_v1_open(state.devicename, state.logging_level); } break; } diff --git a/src/stlink-sg.c b/src/stlink-sg.c index b8220de13..137f6f605 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -82,12 +82,7 @@ #include "stlink-common.h" -#if CONFIG_USE_LIBSG -// sgutils2 (apt-get install libsgutils2-dev) -#include -#include #include "stlink-sg.h" -#endif // Suspends execution of the calling process for @@ -119,15 +114,18 @@ static void clear_buf(stlink_t *sl) { void _stlink_sg_close(stlink_t *sl) { if (sl) { +#if FINISHED_WITH_SG struct stlink_libsg *slsg = sl->backend_data; scsi_pt_close_device(slsg->sg_fd); free(slsg); +#endif } } //TODO rewrite/cleanup, save the error in sl +#if FINISHED_WITH_SG static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) { struct stlink_libsg *sl = stl->backend_data; const int e = sl->do_scsi_pt_err; @@ -209,8 +207,10 @@ static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) { "category (%d)\n", cat); } } +#endif void stlink_q(stlink_t *sl) { +#if FINISHED_WITH_SG struct stlink_libsg* sg = sl->backend_data; DD(sl, "CDB["); for (int i = 0; i < CDB_SL; i++) @@ -245,6 +245,7 @@ void stlink_q(stlink_t *sl) { stlink_confirm_inq(sl, ptvp); // TODO recycle: clear_scsi_pt_obj(struct sg_pt_base * objp); destruct_scsi_pt_obj(ptvp); +#endif } // TODO thinking, cleanup @@ -803,7 +804,7 @@ stlink_t* stlink_open(const char *dev_name, const int verbose) { -stlink_t* stlink_quirk_open(const char *dev_name, const int verbose) { +stlink_t* stlink_v1_open(const char *dev_name, const int verbose) { stlink_t *sl = stlink_open(dev_name, verbose); if (sl == NULL) { diff --git a/src/stlink-sg.h b/src/stlink-sg.h index 523b7d883..afa47c51a 100644 --- a/src/stlink-sg.h +++ b/src/stlink-sg.h @@ -40,7 +40,6 @@ extern "C" { -#if defined(CONFIG_USE_LIBUSB) struct stlink_libsg { int sg_fd; int do_scsi_pt_err; @@ -63,11 +62,8 @@ extern "C" { reg reg; }; -#else - struct stlink_libsg {}; -#endif - stlink_t* stlink_quirk_open(const char *dev_name, const int verbose); + stlink_t* stlink_v1_open(const char *dev_name, const int verbose); #ifdef __cplusplus } diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 57a4a2fdd..526996144 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -116,7 +116,10 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, if (submit_wait(handle, handle->rep_trans)) return -1; res = handle->rep_trans->actual_length; } + if ((handle->protocoll == 1) && terminate) { + fprintf(stderr, "This is never used....\n"); + exit(EXIT_FAILURE); /* Read the SG reply */ unsigned char sg_buf[13]; libusb_fill_bulk_transfer @@ -172,6 +175,7 @@ static int fill_command int i = 0; memset(cmd, 0, sizeof (sl->c_buf)); if(slu->protocoll == 1) { + fprintf(stderr, "This is never used....\n"); cmd[i++] = 'U'; cmd[i++] = 'S'; cmd[i++] = 'B'; @@ -652,11 +656,12 @@ stlink_t* stlink_open_usb(const int verbose) { printf("libusb_alloc_transfer\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; slu->sg_transfer_idx = 0; + // TODO - never used at the moment, always CMD_SIZE slu->cmd_len = (slu->protocoll == 1)? STLINK_SG_SIZE: STLINK_CMD_SIZE; /* success */ diff --git a/src/test_sg.c b/src/test_sg.c index 9efe6d80d..a12ed1f40 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -37,7 +37,7 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Using sg_lib %s : scsi_pt %s\n", sg_lib_version(), scsi_pt_version()); - stlink_t *sl = stlink_quirk_open(dev_name, scsi_verbose); + stlink_t *sl = stlink_v1_open(dev_name, scsi_verbose); if (sl == NULL) return EXIT_FAILURE; From d7e37a684a3ae0c9e52e0486fe46f6d3af1c2b1d Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 22 Oct 2011 20:31:11 +0000 Subject: [PATCH 0014/1435] Replace all logging I needed some sanity... --- Makefile | 2 +- flash/main.c | 2 +- gdbserver/gdb-server.c | 19 +++++----- src/stlink-common.c | 84 +++++++++++++++++++----------------------- src/stlink-common.h | 4 -- src/stlink-sg.c | 75 +++++++++++++++++++------------------ src/stlink-usb.c | 46 ++++++++++++++--------- src/uglylogging.c | 58 +++++++++++++++++++++++++++++ src/uglylogging.h | 27 ++++++++++++++ 9 files changed, 202 insertions(+), 115 deletions(-) create mode 100644 src/uglylogging.c create mode 100644 src/uglylogging.h diff --git a/Makefile b/Makefile index 2c73f165f..c3c345a69 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ ## VPATH=src -SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c +SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c uglylogging.c OBJS_LIB=$(SOURCES_LIB:.c=.o) TEST_PROGRAMS=test_usb #test_sg LDFLAGS=-lusb-1.0 -L. -lstlink diff --git a/flash/main.c b/flash/main.c index a74525a5a..849b5d6cd 100644 --- a/flash/main.c +++ b/flash/main.c @@ -94,7 +94,7 @@ int main(int ac, char** av) } else /* stlinkv2 */ { - sl = stlink_open_usb(10); + sl = stlink_open_usb(100); if (sl == NULL) goto on_error; } diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 3e2f99a96..3af0d8a90 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -21,7 +21,7 @@ #include "gdb-remote.h" -#define DEFAULT_LOGGING_LEVEL 10 +#define DEFAULT_LOGGING_LEVEL 100 #define DEFAULT_GDB_LISTEN_PORT 4242 #define STRINGIFY_inner(name) #name @@ -188,7 +188,7 @@ int main(int argc, char** argv) { memset(&state, 0, sizeof(state)); // set defaults... state.stlink_version = 2; - state.logging_level = 10; + state.logging_level = DEFAULT_LOGGING_LEVEL; state.listen_port = DEFAULT_GDB_LISTEN_PORT; parse_options(argc, argv, &state); switch (state.stlink_version) { @@ -234,15 +234,14 @@ int main(int argc, char** argv) { sl = stlink_v1_open(state.devicename, state.logging_level); } break; - } - - 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); - } + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { + stlink_exit_dfu_mode(sl); + } + stlink_enter_swd_mode(sl); + } uint32_t chip_id = stlink_chip_id(sl); uint32_t core_id = stlink_core_id(sl); diff --git a/src/stlink-common.c b/src/stlink-common.c index 707316cc9..2693eb921 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -13,21 +13,13 @@ #include "stlink-common.h" +#include "uglylogging.h" -void D(stlink_t *sl, char *txt) { - if (sl->verbose > 1) - fputs(txt, stderr); -} - -void DD(stlink_t *sl, char *format, ...) { - if (sl->verbose > 0) { - va_list list; - va_start(list, format); - vfprintf(stderr, format, list); - va_end(list); - } -} - +#define LOG_TAG __FILE__ +#define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args) +#define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args) +#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args) +#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args) /* FPEC flash controller interface, pm0063 manual @@ -256,38 +248,38 @@ static void disable_flash_read_protection(stlink_t *sl) { // Delegates to the backends... void stlink_close(stlink_t *sl) { - D(sl, "\n*** stlink_close ***\n"); + DLOG("*** stlink_close ***\n"); sl->backend->close(sl); free(sl); } void stlink_exit_debug_mode(stlink_t *sl) { - D(sl, "\n*** stlink_exit_debug_mode ***\n"); + DLOG("*** stlink_exit_debug_mode ***\n"); sl->backend->exit_debug_mode(sl); } void stlink_enter_swd_mode(stlink_t *sl) { - D(sl, "\n*** stlink_enter_swd_mode ***\n"); + DLOG("*** stlink_enter_swd_mode ***\n"); sl->backend->enter_swd_mode(sl); } // Force the core into the debug mode -> halted state. void stlink_force_debug(stlink_t *sl) { - D(sl, "\n*** stlink_force_debug_mode ***\n"); + DLOG("*** stlink_force_debug_mode ***\n"); sl->backend->force_debug(sl); } void stlink_exit_dfu_mode(stlink_t *sl) { - D(sl, "\n*** stlink_exit_dfu_mode ***\n"); + DLOG("*** stlink_exit_dfu_mode ***\n"); sl->backend->exit_dfu_mode(sl); } uint32_t stlink_core_id(stlink_t *sl) { - D(sl, "\n*** stlink_core_id ***\n"); + DLOG("*** stlink_core_id ***\n"); sl->backend->core_id(sl); if (sl->verbose > 2) stlink_print_data(sl); - DD(sl, "core_id = 0x%08x\n", sl->core_id); + DLOG("core_id = 0x%08x\n", sl->core_id); return sl->core_id; } @@ -314,17 +306,17 @@ void stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { } void stlink_reset(stlink_t *sl) { - D(sl, "\n*** stlink_reset ***\n"); + DLOG("*** stlink_reset ***\n"); sl->backend->reset(sl); } void stlink_run(stlink_t *sl) { - D(sl, "\n*** stlink_run ***\n"); + DLOG("*** stlink_run ***\n"); sl->backend->run(sl); } void stlink_status(stlink_t *sl) { - D(sl, "\n*** stlink_status ***\n"); + DLOG("*** stlink_status ***\n"); sl->backend->status(sl); stlink_core_stat(sl); } @@ -355,26 +347,26 @@ void _parse_version(stlink_t *sl, stlink_version_t *slv) { } void stlink_version(stlink_t *sl) { - D(sl, "*** looking up stlink version\n"); + DLOG("*** looking up stlink version\n"); stlink_version_t slv; sl->backend->version(sl); _parse_version(sl, &slv); - DD(sl, "st vid = 0x%04x (expect 0x%04x)\n", slv.st_vid, USB_ST_VID); - DD(sl, "stlink pid = 0x%04x\n", slv.stlink_pid); - DD(sl, "stlink version = 0x%x\n", slv.stlink_v); - DD(sl, "jtag version = 0x%x\n", slv.jtag_v); - DD(sl, "swim version = 0x%x\n", slv.swim_v); + DLOG("st vid = 0x%04x (expect 0x%04x)\n", slv.st_vid, USB_ST_VID); + DLOG("stlink pid = 0x%04x\n", slv.stlink_pid); + DLOG("stlink version = 0x%x\n", slv.stlink_v); + DLOG("jtag version = 0x%x\n", slv.jtag_v); + DLOG("swim version = 0x%x\n", slv.swim_v); if (slv.jtag_v == 0) { - DD(sl, " notice: the firmware doesn't support a jtag/swd interface\n"); + DLOG(" notice: the firmware doesn't support a jtag/swd interface\n"); } if (slv.swim_v == 0) { - DD(sl, " notice: the firmware doesn't support a swim interface\n"); + DLOG(" notice: the firmware doesn't support a swim interface\n"); } } void stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - D(sl, "\n*** stlink_write_mem32 ***\n"); + DLOG("*** stlink_write_mem32 ***\n"); if (len % 4 != 0) { fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); return; @@ -383,7 +375,7 @@ void stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { } void stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - D(sl, "\n*** stlink_read_mem32 ***\n"); + DLOG("*** stlink_read_mem32 ***\n"); if (len % 4 != 0) { // !!! never ever: fw gives just wrong values fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); @@ -393,23 +385,23 @@ void stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { } void stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { - D(sl, "\n*** stlink_write_mem8 ***\n"); + DLOG("*** stlink_write_mem8 ***\n"); sl->backend->write_mem8(sl, addr, len); } void stlink_read_all_regs(stlink_t *sl, reg *regp) { - D(sl, "\n*** stlink_read_all_regs ***\n"); + DLOG("*** stlink_read_all_regs ***\n"); sl->backend->read_all_regs(sl, regp); } void stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) { - D(sl, "\n*** stlink_write_reg\n"); + DLOG("*** stlink_write_reg\n"); sl->backend->write_reg(sl, reg, idx); } void stlink_read_reg(stlink_t *sl, int r_idx, reg *regp) { - D(sl, "\n*** stlink_read_reg\n"); - DD(sl, " (%d) ***\n", r_idx); + DLOG("*** stlink_read_reg\n"); + DLOG(" (%d) ***\n", r_idx); if (r_idx > 20 || r_idx < 0) { fprintf(stderr, "Error: register index must be in [0..20]\n"); @@ -426,7 +418,7 @@ unsigned int is_core_halted(stlink_t *sl) { } void stlink_step(stlink_t *sl) { - D(sl, "\n*** stlink_step ***\n"); + DLOG("*** stlink_step ***\n"); sl->backend->step(sl); } @@ -434,16 +426,16 @@ int stlink_current_mode(stlink_t *sl) { int mode = sl->backend->current_mode(sl); switch (mode) { case STLINK_DEV_DFU_MODE: - DD(sl, "stlink current mode: dfu\n"); + DLOG("stlink current mode: dfu\n"); return mode; case STLINK_DEV_DEBUG_MODE: - DD(sl, "stlink current mode: debug (jtag or swd)\n"); + DLOG("stlink current mode: debug (jtag or swd)\n"); return mode; case STLINK_DEV_MASS_MODE: - DD(sl, "stlink current mode: mass\n"); + DLOG("stlink current mode: mass\n"); return mode; } - DD(sl, "stlink mode: unknown!\n"); + DLOG("stlink mode: unknown!\n"); return STLINK_DEV_UNKNOWN_MODE; } @@ -496,11 +488,11 @@ void stlink_core_stat(stlink_t *sl) { switch (sl->q_buf[0]) { case STLINK_CORE_RUNNING: sl->core_stat = STLINK_CORE_RUNNING; - DD(sl, " core status: running\n"); + DLOG(" core status: running\n"); return; case STLINK_CORE_HALTED: sl->core_stat = STLINK_CORE_HALTED; - DD(sl, " core status: halted\n"); + DLOG(" core status: halted\n"); return; default: sl->core_stat = STLINK_CORE_STAT_UNKNOWN; diff --git a/src/stlink-common.h b/src/stlink-common.h index 9481609f6..49867138c 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -181,10 +181,6 @@ extern "C" { }; - // some quick and dirty logging... - void D(stlink_t *sl, char *txt); - void DD(stlink_t *sl, char *format, ...); - //stlink_t* stlink_quirk_open(const char *dev_name, const int verbose); // delegated functions... diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 137f6f605..afce5aca4 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -81,9 +81,14 @@ #include #include "stlink-common.h" - #include "stlink-sg.h" +#include "uglylogging.h" +#define LOG_TAG __FILE__ +#define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args) +#define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args) +#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args) +#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args) // Suspends execution of the calling process for // (at least) ms milliseconds. @@ -104,7 +109,7 @@ static void clear_cdb(struct stlink_libsg *sl) { // E.g. make the valgrind happy. static void clear_buf(stlink_t *sl) { - DD(sl, "*** clear_buf ***\n"); + DLOG("*** clear_buf ***\n"); for (size_t i = 0; i < sizeof (sl->q_buf); i++) sl->q_buf[i] = 0; @@ -142,7 +147,7 @@ static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) { } const int duration = get_scsi_pt_duration_ms(ptvp); if ((stl->verbose > 1) && (duration >= 0)) - DD(stl, " duration=%d ms\n", duration); + DLOG(" duration=%d ms\n", duration); // XXX stlink fw sends broken residue, so ignore it and use the known q_len // "usb-storage quirks=483:3744:r" @@ -159,7 +164,7 @@ static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) { switch (cat) { case SCSI_PT_RESULT_GOOD: if (stl->verbose && (resid > 0)) - DD(stl, " notice: requested %d bytes but " + DLOG(" notice: requested %d bytes but " "got %d bytes, ignore [broken] residue = %d\n", stl->q_len, dsize, resid); break; @@ -168,7 +173,7 @@ static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) { sg_get_scsi_status_str( get_scsi_pt_status_response(ptvp), sizeof (buf), buf); - DD(stl, " scsi status: %s\n", buf); + DLOG(" scsi status: %s\n", buf); } return; case SCSI_PT_RESULT_SENSE: @@ -176,11 +181,11 @@ static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) { if (stl->verbose) { sg_get_sense_str("", sl->sense_buf, slen, (stl->verbose > 1), sizeof (buf), buf); - DD(stl, "%s", buf); + DLOG("%s", buf); } if (stl->verbose && (resid > 0)) { if ((stl->verbose) || (stl->q_len > 0)) - DD(stl, " requested %d bytes but " + DLOG(" requested %d bytes but " "got %d bytes\n", stl->q_len, dsize); } return; @@ -193,13 +198,13 @@ static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) { // The 'host_status' field has the following values: // [0x07] Internal error detected in the host adapter. // This may not be fatal (and the command may have succeeded). - DD(stl, " transport: %s", buf); + DLOG(" transport: %s", buf); } return; case SCSI_PT_RESULT_OS_ERR: if (stl->verbose) { get_scsi_pt_os_err_str(ptvp, sizeof (buf), buf); - DD(stl, " os: %s", buf); + DLOG(" os: %s", buf); } return; default: @@ -212,10 +217,10 @@ static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) { void stlink_q(stlink_t *sl) { #if FINISHED_WITH_SG struct stlink_libsg* sg = sl->backend_data; - DD(sl, "CDB["); + DLOG("CDB["); for (int i = 0; i < CDB_SL; i++) - DD(sl, " 0x%02x", (unsigned int) sg->cdb_cmd_blk[i]); - DD(sl, "]\n"); + DLOG(" 0x%02x", (unsigned int) sg->cdb_cmd_blk[i]); + DLOG("]\n"); // Get control command descriptor of scsi structure, // (one object per command!!) @@ -258,13 +263,13 @@ void stlink_stat(stlink_t *stl, char *txt) { switch (stl->q_buf[0]) { case STLINK_OK: - DD(stl, " %s: ok\n", txt); + DLOG(" %s: ok\n", txt); return; case STLINK_FALSE: - DD(stl, " %s: false\n", txt); + DLOG(" %s: false\n", txt); return; default: - DD(stl, " %s: unknown\n", txt); + DLOG(" %s: unknown\n", txt); } } @@ -300,7 +305,7 @@ static void parse_version(stlink_t *stl) { void _stlink_sg_version(stlink_t *stl) { struct stlink_libsg *sl = stl->backend_data; - D(stl, "\n*** stlink_version ***\n"); + DLOG("\n*** stlink_version ***\n"); clear_cdb(sl); sl->cdb_cmd_blk[0] = STLINK_GET_VERSION; stl->q_len = 6; @@ -339,7 +344,7 @@ void _stlink_sg_enter_swd_mode(stlink_t *sl) { void _stlink_sg_enter_jtag_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; - D(sl, "\n*** stlink_enter_jtag_mode ***\n"); + DLOG("\n*** stlink_enter_jtag_mode ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_JTAG; @@ -351,7 +356,7 @@ void _stlink_sg_enter_jtag_mode(stlink_t *sl) { void _stlink_sg_exit_dfu_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; - D(sl, "\n*** stlink_exit_dfu_mode ***\n"); + DLOG("\n*** stlink_exit_dfu_mode ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[0] = STLINK_DFU_COMMAND; sg->cdb_cmd_blk[1] = STLINK_DFU_EXIT; @@ -428,7 +433,7 @@ void _stlink_sg_reset(stlink_t *sl) { void _stlink_sg_status(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; - D(sl, "\n*** stlink_status ***\n"); + DLOG("\n*** stlink_status ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_GETSTATUS; sl->q_len = 2; @@ -440,7 +445,7 @@ void _stlink_sg_status(stlink_t *sl) { void _stlink_sg_force_debug(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; - D(sl, "\n*** stlink_force_debug ***\n"); + DLOG("\n*** stlink_force_debug ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_FORCEDEBUG; sl->q_len = 2; @@ -471,7 +476,7 @@ void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { for (int i = 0; i < 16; i++) { sg->reg.r[i] = read_uint32(sl->q_buf, 4 * i); if (sl->verbose > 1) - DD(sl, "r%2d = 0x%08x\n", i, sg->reg.r[i]); + DLOG("r%2d = 0x%08x\n", i, sg->reg.r[i]); } sg->reg.xpsr = read_uint32(sl->q_buf, 64); sg->reg.main_sp = read_uint32(sl->q_buf, 68); @@ -481,11 +486,11 @@ void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { if (sl->verbose < 2) return; - DD(sl, "xpsr = 0x%08x\n", sg->reg.xpsr); - DD(sl, "main_sp = 0x%08x\n", sg->reg.main_sp); - DD(sl, "process_sp = 0x%08x\n", sg->reg.process_sp); - DD(sl, "rw = 0x%08x\n", sg->reg.rw); - DD(sl, "rw2 = 0x%08x\n", sg->reg.rw2); + DLOG("xpsr = 0x%08x\n", sg->reg.xpsr); + DLOG("main_sp = 0x%08x\n", sg->reg.main_sp); + DLOG("process_sp = 0x%08x\n", sg->reg.process_sp); + DLOG("rw = 0x%08x\n", sg->reg.rw); + DLOG("rw2 = 0x%08x\n", sg->reg.rw2); } // Read an arm-core register, the index must be in the range 0..20. @@ -506,7 +511,7 @@ void _stlink_sg_read_reg(stlink_t *sl, int r_idx, reg *regp) { stlink_print_data(sl); uint32_t r = read_uint32(sl->q_buf, 0); - DD(sl, "r_idx (%2d) = 0x%08x\n", r_idx, r); + DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); switch (r_idx) { case 16: @@ -553,7 +558,7 @@ void _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) { void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { struct stlink_libsg *sg = sl->backend_data; - D(sl, "\n*** stlink_write_dreg ***\n"); + DLOG("\n*** stlink_write_dreg ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEDEBUGREG; // 2-5: address of reg of the debug module @@ -570,7 +575,7 @@ void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { void _stlink_sg_run(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; - D(sl, "\n*** stlink_run ***\n"); + DLOG("\n*** stlink_run ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_RUNCORE; sl->q_len = 2; @@ -595,7 +600,7 @@ void _stlink_sg_step(stlink_t *sl) { // see Cortex-M3 Technical Reference Manual // TODO make delegate! void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) { - D(sl, "\n*** stlink_set_hw_bp ***\n"); + DLOG("\n*** stlink_set_hw_bp ***\n"); struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_SETFP; @@ -616,7 +621,7 @@ void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) { // TODO make delegate! void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) { struct stlink_libsg *sg = sl->backend_data; - D(sl, "\n*** stlink_clr_hw_bp ***\n"); + DLOG("\n*** stlink_clr_hw_bp ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_CLEARFP; sg->cdb_cmd_blk[2] = fp_nr; @@ -805,7 +810,7 @@ stlink_t* stlink_open(const char *dev_name, const int verbose) { stlink_t* stlink_v1_open(const char *dev_name, const int verbose) { - + ugly_init(verbose); stlink_t *sl = stlink_open(dev_name, verbose); if (sl == NULL) { fputs("Error: could not open stlink device\n", stderr); @@ -825,7 +830,7 @@ stlink_t* stlink_v1_open(const char *dev_name, const int verbose) { return NULL; } - D(sl, "\n*** stlink_force_open ***\n"); + DLOG("\n*** stlink_force_open ***\n"); switch (stlink_current_mode(sl)) { case STLINK_DEV_MASS_MODE: return sl; @@ -833,10 +838,10 @@ stlink_t* stlink_v1_open(const char *dev_name, const int verbose) { // TODO go to mass? return sl; } - DD(sl, "\n*** switch the stlink to mass mode ***\n"); + DLOG("\n*** switch the stlink to mass mode ***\n"); _stlink_sg_exit_dfu_mode(sl); // exit the dfu mode -> the device is gone - DD(sl, "\n*** reopen the stlink device ***\n"); + DLOG("\n*** reopen the stlink device ***\n"); delay(1000); stlink_close(sl); delay(5000); diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 526996144..c0b0009f2 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -5,8 +5,17 @@ #include #include #include + #include "stlink-common.h" #include "stlink-usb.h" +#include "uglylogging.h" + +#define LOG_TAG __FILE__ +#define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args) +#define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args) +#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args) +#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args) + enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80}; @@ -472,11 +481,11 @@ void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { if (sl->verbose < 2) return; - DD(sl, "xpsr = 0x%08x\n", read_uint32(sl->q_buf, 64)); - DD(sl, "main_sp = 0x%08x\n", read_uint32(sl->q_buf, 68)); - DD(sl, "process_sp = 0x%08x\n", read_uint32(sl->q_buf, 72)); - DD(sl, "rw = 0x%08x\n", read_uint32(sl->q_buf, 76)); - DD(sl, "rw2 = 0x%08x\n", read_uint32(sl->q_buf, 80)); + DLOG("xpsr = 0x%08x\n", read_uint32(sl->q_buf, 64)); + DLOG("main_sp = 0x%08x\n", read_uint32(sl->q_buf, 68)); + DLOG("process_sp = 0x%08x\n", read_uint32(sl->q_buf, 72)); + DLOG("rw = 0x%08x\n", read_uint32(sl->q_buf, 76)); + DLOG("rw2 = 0x%08x\n", read_uint32(sl->q_buf, 80)); } void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { @@ -499,7 +508,7 @@ void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { sl->q_len = (size_t) size; stlink_print_data(sl); r = read_uint32(sl->q_buf, 0); - DD(sl, "r_idx (%2d) = 0x%08x\n", r_idx, r); + DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); switch (r_idx) { case 16: @@ -584,7 +593,7 @@ stlink_t* stlink_open_usb(const int verbose) { memset(sl, 0, sizeof (stlink_t)); memset(slu, 0, sizeof (struct stlink_libusb)); - sl->verbose = verbose; + ugly_init(verbose); sl->backend = &_stlink_usb_backend; sl->backend_data = slu; @@ -604,15 +613,15 @@ stlink_t* stlink_open_usb(const int verbose) { 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; + WLOG("failed to init libusb context, wrong version of libraries?\n"); + goto on_error; } slu->usb_handle = libusb_open_device_with_vid_pid(slu->libusb_ctx, USB_ST_VID, USB_STLINK_32L_PID); if (slu->usb_handle == NULL) { // TODO - free usb context too... free(slu); - fprintf(stderr, "Couldn't find any ST-Link/V2 devices"); + WLOG("Couldn't find any ST-Link/V2 devices"); return NULL; } @@ -620,14 +629,15 @@ stlink_t* stlink_open_usb(const int verbose) { int r; r = libusb_detach_kernel_driver(slu->usb_handle, 0); - if (r<0) - printf("libusb_detach_kernel_driver(() error %s\n", strerror(-r)); + if (r<0) { + WLOG("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 */ - printf("libusb_get_configuration()\n"); + WLOG("libusb_get_configuration()\n"); goto on_libusb_error; } @@ -635,25 +645,25 @@ stlink_t* stlink_open_usb(const int verbose) { printf("setting new configuration (%d -> 1)\n", config); if (libusb_set_configuration(slu->usb_handle, 1)) { /* this may fail for a previous configured device */ - printf("libusb_set_configuration()\n"); + WLOG("libusb_set_configuration() failed\n"); goto on_libusb_error; } } if (libusb_claim_interface(slu->usb_handle, 0)) { - printf("libusb_claim_interface()\n"); + WLOG("libusb_claim_interface() failed\n"); goto on_libusb_error; } slu->req_trans = libusb_alloc_transfer(0); if (slu->req_trans == NULL) { - printf("libusb_alloc_transfer\n"); + WLOG("libusb_alloc_transfer failed\n"); goto on_libusb_error; } slu->rep_trans = libusb_alloc_transfer(0); if (slu->rep_trans == NULL) { - printf("libusb_alloc_transfer\n"); + WLOG("libusb_alloc_transfer failed\n"); goto on_libusb_error; } // TODO - could use the scanning techniq from stm8 code here... @@ -666,7 +676,7 @@ stlink_t* stlink_open_usb(const int verbose) { /* success */ if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { - printf("-- exit_dfu_mode\n"); + ILOG("-- exit_dfu_mode\n"); stlink_exit_dfu_mode(sl); } stlink_version(sl); diff --git a/src/uglylogging.c b/src/uglylogging.c new file mode 100644 index 000000000..c6d07f89f --- /dev/null +++ b/src/uglylogging.c @@ -0,0 +1,58 @@ +/* + * UglyLogging. Slow, yet another wheel reinvented, but enough to make the + * rest of our code pretty enough. + * + */ + +#include +#include +#include +#include +#include + +#include "uglylogging.h" + +static int max_level; + +int ugly_init(int maximum_threshold) { + max_level = maximum_threshold; + return 0; +} + +int ugly_log(int level, const char *tag, const char *format, ...) { + if (level > max_level) { + return 0; + } + va_list args; + va_start(args, format); + time_t mytt = time(NULL); + struct tm *tt; + tt = localtime(&mytt); + fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", tt->tm_year + 1900, tt->tm_mon + 1, tt->tm_mday, tt->tm_hour, tt->tm_min, tt->tm_sec); + switch (level) { + case UDEBUG: + fprintf(stderr, "DEBUG %s: ", tag); + break; + case UINFO: + fprintf(stderr, "INFO %s: ", tag); + break; + case UWARN: + fprintf(stderr, "WARN %s: ", tag); + break; + case UERROR: + fprintf(stderr, "ERROR %s: ", tag); + break; + case UFATAL: + fprintf(stderr, "FATAL %s: ", tag); + vfprintf(stderr, format, args); + exit(EXIT_FAILURE); + // NEVER GETS HERE!!! + break; + default: + fprintf(stderr, "%d %s: ", level, tag); + break; + } + vfprintf(stderr, format, args); + va_end(args); + return 1; +} \ No newline at end of file diff --git a/src/uglylogging.h b/src/uglylogging.h new file mode 100644 index 000000000..fa34d460c --- /dev/null +++ b/src/uglylogging.h @@ -0,0 +1,27 @@ +/* + * Ugly, low performance, configurable level, logging "framework" + */ + +#ifndef UGLYLOGGING_H +#define UGLYLOGGING_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define UDEBUG 90 +#define UINFO 50 +#define UWARN 30 +#define UERROR 20 +#define UFATAL 10 + + int ugly_init(int maximum_threshold); + int ugly_log(int level, const char *tag, const char *format, ...); + + +#ifdef __cplusplus +} +#endif + +#endif /* UGLYLOGGING_H */ + From a672ee1a34f0602079c52bbd04e7d115ccb37651 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 1 Nov 2011 18:50:06 +0000 Subject: [PATCH 0015/1435] Ignore all elf outputs. Ignore pdflatex outputs --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 44d2e4ddf..0a541c78b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ /nbproject/private/ *.o +*.elf +doc/tutorial/*.log +doc/tutorial/*.aux libstlink.a test_usb test_sg -gdbserver/st-utils \ No newline at end of file +gdbserver/st-utils From ee772151c2aca1508b906982ad30944087e8143b Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 1 Nov 2011 18:51:14 +0000 Subject: [PATCH 0016/1435] Remove unneeded old files --- example/blink/default_bootloader.bin | Bin 2048 -> 0 bytes example/blink/disasm.sh | 3 --- 2 files changed, 3 deletions(-) delete mode 100755 example/blink/default_bootloader.bin delete mode 100755 example/blink/disasm.sh diff --git a/example/blink/default_bootloader.bin b/example/blink/default_bootloader.bin deleted file mode 100755 index 0e3137184c083c5657dd9bd45ffdf7846fc02962..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmah~eQaCR6+h2@{vh?zmz8Z!$m*9b&6(UKty&RAQ6G+DKc|6oLy^*{70ftFPTDo{sI=wt;@6K8?7B9)m|t({c#+~Nt1mcBn&6BbRlZIb(%y!Xz| zH7VPFd(!#3_nhP3x#!+vaDlw3jG_xAW(IU9pIHVK5~*7l0@{D(gG}NvqU#Nxp~W{AVO{ zXy${1$lk#~8G&nWp?^ht1MgbVUPX|DS(kBA9;JGby;8x)^H0x~4;PXkUl=&zgOVU; z5*+W@t#7WKG=VU>2%|VWX?jNroqx#}Zuwe>;=XERFA~yciJrpoZ_!pT5UQOO3>d5A>OYxe*s@-eNBC;#Fx5VvXpux6(x?$a)2a|2Qq>7Z#&3tI?q)q73tjm+v^#J z_nNQ4v@|8gS5d~R&XW~SfmWNS_L8Hg6`%XlU_c}5lW(jNtx=q=@p$ejO^@7w)Wia8 z5iYr?6OSf^*u+BlQQ?xCtQ{2#4hWY-vVM{D$Ho`nY2lKGEZ(>FDQH1fi{;b%sm5W# z`y`6-u7APf$o3$~u9$)>#kCf$?Lbc_m;E>r6^lG(pA(L^PxBM{rPEvPYj5Xww^w<4 z^M!NcLT+;b*>>l??yj4C+a%2^Z_}s?O>4Bx$=>;_q-yu~2(rA#pUw(a>0b4|o|p#B zy=9~2oaui^Y-mj-#er1prYH=iHmVzv1yc;_razeUESFZ~r*~`*dEZ&f4dmj51!xJY zqw$8gnDsSJEzi#%%J$9|b{`s~?_lT6z=Ogd$Nzojni(0ERKnFDXw-j4q+ZNAnu1}_ z`dMVo(&#bN-It3y!ko)jY6D`%rlM^74iBfrx9S2`mv=({3Ox|v%XA-u2nfN?PLtbR1ISMM;OQF!e%V*`1=Z11lByS^#DuRcug>P4Hsj@>gM`5%zVS(1K|@_bhIYbr?xRPDSejU#*5empJHo9(f4i3cdtpDJixcmA3e+TJ2GEzWmt z+#QJ3r{bb<(%5OdY>XMF3C)k3vG8w;uC_JB5uZyJ%a+*uLu9Jm0#$loPOKW6^MH_U zuT}0rw#``=S}eNTR{xK$3_J7ViTegm_T_^_WZE`<;{@1PZ zX5d6Kq26N);VtuZr}*mU7P1d)411`Pc{_I+*+1>?8lLxK^{v#85ACt=fqBoVo{8Qv z?D-x|Bkx?6qW(>rSQs$#!l@f&m2;(LcH=%2pM^+8KgrS9!<#T09Yqsv8* z=VoB4s#{MNyxtO@02zx-JIQ=(sqD=qyYos?tRE_jy0r3T2(8D>mD_=WW>DLju&SVe# E2h&9CasU7T diff --git a/example/blink/disasm.sh b/example/blink/disasm.sh deleted file mode 100755 index b3b46da6e..000000000 --- a/example/blink/disasm.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env sh -#/home/texane/sat/bin/arm-none-eabi-objdump -marm -Mforce-thumb -EL -b binary -D /tmp/barfoo -/home/texane/sat/bin/arm-none-eabi-objdump -marm -EL -b binary -D /tmp/barfoo From e8bae670d226061d567869d24fe3cbc175dff364 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 1 Nov 2011 21:23:16 +0000 Subject: [PATCH 0017/1435] Fix compilation for 32bit machines %Ld works for size_t only on 64 bit, the correct conversion is %zd --- gdbserver/gdb-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 3af0d8a90..65297bc0c 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -143,7 +143,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { break; case 'd': if (strlen(optarg) > sizeof (st->devicename)) { - fprintf(stderr, "device name too long: %ld\n", strlen(optarg)); + fprintf(stderr, "device name too long: %zd\n", strlen(optarg)); } else { strcpy(st->devicename, optarg); } From c0c45e259e1d7efd79c22369c7160d910e4035e0 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 1 Nov 2011 21:56:43 +0000 Subject: [PATCH 0018/1435] More generic stlinkv2 udev naming Better support for F4, or anything else that appears as an stlinkv2 --- 49-stm32l-discovery.rules => 49-stlinkv2.rules | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) rename 49-stm32l-discovery.rules => 49-stlinkv2.rules (71%) diff --git a/49-stm32l-discovery.rules b/49-stlinkv2.rules similarity index 71% rename from 49-stm32l-discovery.rules rename to 49-stlinkv2.rules index 1f3ce7795..a11215c57 100644 --- a/49-stm32l-discovery.rules +++ b/49-stlinkv2.rules @@ -1,9 +1,11 @@ -# stm32l discovery board, with onboard st/linkv2 -# +# stm32 discovery boards, with onboard st/linkv2 +# ie, STM32L, STM32F4. +# STM32VL has st/linkv1, which is quite different + SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", \ MODE:="0666", \ - SYMLINK+="stm32l_stlink%n" -# + SYMLINK+="stlinkv2_%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 From 66c50cec899fcb25e6a4ea670208defebe8759cd Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 3 Nov 2011 00:35:19 +0000 Subject: [PATCH 0019/1435] Remove sg-utils test output More bulk cleanup on the path to removing sg-utils dependencies. Trying to make test-sg as simple as possible so I can use it reliably to test on both master and my killsg branch --- src/test_sg.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/test_sg.c b/src/test_sg.c index 34fbe540c..a4db8f236 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -14,7 +14,6 @@ int main(int argc, char *argv[]) { // set scpi lib debug level: 0 for no debug info, 10 for lots - const int scsi_verbose = 2; char *dev_name; switch (argc) { @@ -37,14 +36,11 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - fputs("*** stlink access test ***\n", stderr); - fprintf(stderr, "Using sg_lib %s : scsi_pt %s\n", sg_lib_version(), - scsi_pt_version()); - - stlink_t *sl = stlink_quirk_open(dev_name, scsi_verbose); + stlink_t *sl = stlink_quirk_open(dev_name, 10); if (sl == NULL) return EXIT_FAILURE; - + + // we are in mass mode, go to swd stlink_enter_swd_mode(sl); stlink_current_mode(sl); @@ -176,7 +172,7 @@ int main(int argc, char *argv[]) { stlink_force_debug(sl); stlink_status(sl); #endif -#if 1 /* read the system bootloader */ +#if 0 /* read the system bootloader */ fputs("\n++++++++++ reading bootloader ++++++++++++++++\n\n", stderr); stlink_fread(sl, "/tmp/barfoo", sl->sys_base, sl->sys_size); #endif @@ -202,6 +198,7 @@ int main(int argc, char *argv[]) { stlink_run_at(sl, sl->sram_base); #endif +#if 0 stlink_run(sl); stlink_status(sl); //---------------------------------------------------------------------- @@ -209,6 +206,7 @@ int main(int argc, char *argv[]) { stlink_exit_debug_mode(sl); stlink_current_mode(sl); stlink_close(sl); +#endif //fflush(stderr); fflush(stdout); return EXIT_SUCCESS; From afb487cfb627762590ee1acf750a77417cf73e18 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 3 Nov 2011 00:36:31 +0000 Subject: [PATCH 0020/1435] Remove -sg's private version decoding Remove duplication of stlink version decoding, and put the decoded version information into the stlink object itself. --- src/stlink-common.c | 17 ++++++++--------- src/stlink-common.h | 1 + src/stlink-sg.c | 37 +++---------------------------------- src/stlink-sg.h | 7 ------- 4 files changed, 12 insertions(+), 50 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 707316cc9..6a9b9383d 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -356,19 +356,18 @@ void _parse_version(stlink_t *sl, stlink_version_t *slv) { void stlink_version(stlink_t *sl) { D(sl, "*** looking up stlink version\n"); - stlink_version_t slv; sl->backend->version(sl); - _parse_version(sl, &slv); + _parse_version(sl, &sl->version); - DD(sl, "st vid = 0x%04x (expect 0x%04x)\n", slv.st_vid, USB_ST_VID); - DD(sl, "stlink pid = 0x%04x\n", slv.stlink_pid); - DD(sl, "stlink version = 0x%x\n", slv.stlink_v); - DD(sl, "jtag version = 0x%x\n", slv.jtag_v); - DD(sl, "swim version = 0x%x\n", slv.swim_v); - if (slv.jtag_v == 0) { + DD(sl, "st vid = 0x%04x (expect 0x%04x)\n", sl->version.st_vid, USB_ST_VID); + DD(sl, "stlink pid = 0x%04x\n", sl->version.stlink_pid); + DD(sl, "stlink version = 0x%x\n", sl->version.stlink_v); + DD(sl, "jtag version = 0x%x\n", sl->version.jtag_v); + DD(sl, "swim version = 0x%x\n", sl->version.swim_v); + if (sl->version.jtag_v == 0) { DD(sl, " notice: the firmware doesn't support a jtag/swd interface\n"); } - if (slv.swim_v == 0) { + if (sl->version.swim_v == 0) { DD(sl, " notice: the firmware doesn't support a swim interface\n"); } } diff --git a/src/stlink-common.h b/src/stlink-common.h index 9481609f6..2ac56f2b6 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -179,6 +179,7 @@ extern "C" { stm32_addr_t sram_base; size_t sram_size; + struct stlink_version_ version; }; // some quick and dirty logging... diff --git a/src/stlink-sg.c b/src/stlink-sg.c index b8220de13..e8dee5db0 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -268,35 +268,6 @@ void stlink_stat(stlink_t *stl, char *txt) { } -static void parse_version(stlink_t *stl) { - struct stlink_libsg *sl = stl->backend_data; - - sl->st_vid = 0; - sl->stlink_pid = 0; - - if (stl->q_len <= 0) { - fprintf(stderr, "Error: could not parse the stlink version"); - return; - } - - uint32_t b0 = stl->q_buf[0]; //lsb - uint32_t b1 = stl->q_buf[1]; - uint32_t b2 = stl->q_buf[2]; - uint32_t b3 = stl->q_buf[3]; - uint32_t b4 = stl->q_buf[4]; - uint32_t b5 = stl->q_buf[5]; //msb - - // b0 b1 || b2 b3 | b4 b5 - // 4b | 6b | 6b || 2B | 2B - // stlink_v | jtag_v | swim_v || st_vid | stlink_pid - - sl->stlink_v = (b0 & 0xf0) >> 4; - sl->jtag_v = ((b0 & 0x0f) << 2) | ((b1 & 0xc0) >> 6); - sl->swim_v = b1 & 0x3f; - sl->st_vid = (b3 << 8) | b2; - sl->stlink_pid = (b5 << 8) | b4; -} - void _stlink_sg_version(stlink_t *stl) { struct stlink_libsg *sl = stl->backend_data; D(stl, "\n*** stlink_version ***\n"); @@ -305,7 +276,6 @@ void _stlink_sg_version(stlink_t *stl) { stl->q_len = 6; sl->q_addr = 0; stlink_q(stl); - parse_version(stl); } // Get stlink mode: @@ -781,7 +751,6 @@ stlink_t* stlink_open(const char *dev_name, const int verbose) { slsg->sg_fd = sg_fd; sl->core_stat = STLINK_CORE_STAT_UNKNOWN; - slsg->core_id = 0; slsg->q_addr = 0; clear_buf(sl); @@ -814,13 +783,13 @@ stlink_t* stlink_quirk_open(const char *dev_name, const int verbose) { stlink_version(sl); struct stlink_libsg *sg = sl->backend_data; - if ((sg->st_vid != USB_ST_VID) || (sg->stlink_pid != USB_STLINK_PID)) { + if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { fprintf(stderr, "Error: the device %s is not a stlink\n", dev_name); fprintf(stderr, " VID: got %04x expect %04x \n", - sg->st_vid, USB_ST_VID); + sl->version.st_vid, USB_ST_VID); fprintf(stderr, " PID: got %04x expect %04x \n", - sg->stlink_pid, USB_STLINK_PID); + sl->version.stlink_pid, USB_STLINK_PID); return NULL; } diff --git a/src/stlink-sg.h b/src/stlink-sg.h index 523b7d883..b3ab9c00e 100644 --- a/src/stlink-sg.h +++ b/src/stlink-sg.h @@ -54,13 +54,6 @@ extern "C" { // Sense (error information) data unsigned char sense_buf[SENSE_BUF_LEN]; - uint32_t st_vid; - uint32_t stlink_pid; - uint32_t stlink_v; - uint32_t jtag_v; - uint32_t swim_v; - uint32_t core_id; - reg reg; }; #else From 7de94e5491c2a5f0bba4e374c6aad6bdd61ee235 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 3 Nov 2011 00:37:32 +0000 Subject: [PATCH 0021/1435] drop non shared directories from netbeans project --- nbproject/configurations.xml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index 794a3ab5c..567946524 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -127,20 +127,6 @@ - - - - - - - - - - - - - - Date: Thu, 3 Nov 2011 01:07:15 +0000 Subject: [PATCH 0022/1435] Successfully locate and open stlinkv1 by usb Very very raw, this just finds the device and opens the usb handle. --- Makefile | 2 +- src/stlink-sg.c | 84 ++++++++++++++++++++++++++++++++++++++++++++----- src/stlink-sg.h | 3 ++ src/test_sg.c | 3 +- 4 files changed, 82 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index c3c345a69..646dde12d 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ VPATH=src SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c uglylogging.c OBJS_LIB=$(SOURCES_LIB:.c=.o) -TEST_PROGRAMS=test_usb #test_sg +TEST_PROGRAMS=test_usb test_sg LDFLAGS=-lusb-1.0 -L. -lstlink CFLAGS+=-g diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 5d1f970cd..3b9958d73 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -736,26 +736,94 @@ stlink_backend_t _stlink_sg_backend = { _stlink_sg_force_debug }; -stlink_t* stlink_open(const char *dev_name, const int verbose) { - fprintf(stderr, "\n*** stlink_open [%s] ***\n", dev_name); - int sg_fd = scsi_pt_open_device(dev_name, RDWR, verbose); - if (sg_fd < 0) { - fprintf(stderr, "error opening device: %s: %s\n", dev_name, - safe_strerror(-sg_fd)); +#if using_stm8_stuff_XXXX +stlink *stlink_open(libusb_context *usb_context) +{ + stlink *stl = malloc(sizeof(stlink)); + stl->handle = libusb_open_device_with_vid_pid(usb_context, USB_VID_ST, USB_PID_STLINK); + if (stl->handle == NULL) { + free(stl); + return NULL; + } + + libusb_device *dev = libusb_get_device(stl->handle); + struct libusb_config_descriptor *conf_desc; + int ret = libusb_get_config_descriptor(dev, 0, &conf_desc); + if (ret != LIBUSB_SUCCESS) { + libusb_close(stl->handle); + free(stl); + return NULL; + } + for (int i = 0; i < conf_desc->bNumInterfaces; i++) { + printf("interface %d\n", i); + for (int j = 0; j < conf_desc->interface[i].num_altsetting; j++) { + for (int k = 0; k < conf_desc->interface[i].altsetting[j].bNumEndpoints; k++) { + const struct libusb_endpoint_descriptor *endpoint; + endpoint = &conf_desc->interface[i].altsetting[j].endpoint[k]; + if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) { + stl->endpoint_in = endpoint->bEndpointAddress; + printf("Found IN endpoint\n"); + } else { + stl->endpoint_out = endpoint->bEndpointAddress; + printf("Found OUT endpoint\n"); + } + } + } + } + libusb_free_config_descriptor(conf_desc); + + ret = libusb_kernel_driver_active(stl->handle, 0); + if (ret == 1) { + printf("kernel driver active\n"); + } else if (ret == 0) { + //printf("kernel driver not active\n"); + } else { + fprintf(stderr, "libusb_kernel_driver_active = %d\n", ret); + } + ret = libusb_claim_interface(stl->handle, 0); + if (ret != LIBUSB_SUCCESS) { + fprintf(stderr, "claiming interface failed: %d\n", ret); + libusb_close(stl->handle); + free(stl); return NULL; } + return stl; +} +#endif + + +static stlink_t* stlink_open(const char *dev_name, const int verbose) { + fprintf(stderr, "\n*** stlink_open [%s] ***\n", dev_name); + stlink_t *sl = malloc(sizeof (stlink_t)); struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg)); if (sl == NULL || slsg == NULL) { - fprintf(stderr, "Couldn't malloc stlink and stlink_sg structures out of memory!\n"); + WLOG("Couldn't malloc stlink and stlink_sg structures out of memory!\n"); + return NULL; + } + + if (libusb_init(&(slsg->libusb_ctx))) { + WLOG("failed to init libusb context, wrong version of libraries?\n"); + free(sl); + free(slsg); return NULL; } + + slsg->handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, USB_ST_VID, USB_STLINK_PID); + if (slsg->handle == NULL) { + WLOG("Failed to find an stlink v1 by VID:PID\n"); + free(sl); + free(slsg); + return NULL; + } + + DLOG("Successfully opened stlinkv1 by libusb :)\n"); + sl->verbose = verbose; sl->backend_data = slsg; sl->backend = &_stlink_sg_backend; - slsg->sg_fd = sg_fd; sl->core_stat = STLINK_CORE_STAT_UNKNOWN; slsg->q_addr = 0; clear_buf(sl); diff --git a/src/stlink-sg.h b/src/stlink-sg.h index 723c66a05..c9776cddb 100644 --- a/src/stlink-sg.h +++ b/src/stlink-sg.h @@ -41,6 +41,9 @@ extern "C" { struct stlink_libsg { + libusb_context* libusb_ctx; + libusb_device_handle *handle; + int sg_fd; int do_scsi_pt_err; diff --git a/src/test_sg.c b/src/test_sg.c index 30f867a1f..742ba4453 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -29,10 +29,11 @@ int main(int argc, char *argv[]) { dev_name = argv[1]; break; default: + fprintf(stderr, "bzzt\n"); return EXIT_FAILURE; } - stlink_t *sl = stlink_v1_open(dev_name, 10); + stlink_t *sl = stlink_v1_open(dev_name, 99); if (sl == NULL) return EXIT_FAILURE; From 3bf3bbef0ba03fa54c531b94daaf0c4029c0af8b Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 3 Nov 2011 03:45:23 +0000 Subject: [PATCH 0023/1435] Read stlink version info via libusb. Hooray! Stage 1 complete. The stlink version can now be read by sending the scsi commands via libusb directly, instead of using sg-utils. It's very very prototype code however, but should come together from here. Major bugs: Only works when the device has been first plugged in. I'm clearly not resetting some usb state somewhere. Now that libusb is being used directly, you can use linux usb-storage quirks to completely IGNORE the device as mass storage. We'll just grab it via libusb when we want it. --- src/stlink-sg.c | 216 ++++++++++++++++++++++++++++++++++------------- src/stlink-sg.h | 4 +- src/stlink-usb.c | 2 +- 3 files changed, 159 insertions(+), 63 deletions(-) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 3b9958d73..9d71df123 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -281,7 +281,102 @@ void _stlink_sg_version(stlink_t *stl) { sl->cdb_cmd_blk[0] = STLINK_GET_VERSION; stl->q_len = 6; sl->q_addr = 0; - stlink_q(stl); +// stlink_q(stl); + // HACK use my own private version right now... + + int try = 0; + int ret = 0; + int real_transferred; + +/* + uint32_t dCBWSignature; + uint32_t dCBWTag; + uint32_t dCBWDataTransferLength; + uint8_t bmCBWFlags; + uint8_t bCBWLUN; + uint8_t bCBWCBLength; + uint8_t CBWCB[16]; + */ + +#if using_old_code_examples + /* + * and from old code? + cmd[i++] = 'U'; + cmd[i++] = 'S'; + cmd[i++] = 'B'; + cmd[i++] = 'C'; + write_uint32(&cmd[i], sg->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 */ + */ +#endif + + int i = 0; + stl->c_buf[i++] = 'U'; + stl->c_buf[i++] = 'S'; + stl->c_buf[i++] = 'B'; + stl->c_buf[i++] = 'C'; + // tag is allegedly ignored... TODO - verify + write_uint32(&stl->c_buf[i], 1); + // TODO - Does this even matter? verify with more commands.... + uint32_t command_length = STLINK_CMD_SIZE; + write_uint32(&stl->c_buf[i+4], command_length); + i+= 8; + stl->c_buf[i++] = LIBUSB_ENDPOINT_IN; + // assumption: lun is always 0; + stl->c_buf[i++] = 0; + + stl->c_buf[i++] = sizeof(sl->cdb_cmd_blk); + + // duh, now the actual data... + memcpy(&(stl->c_buf[i]), sl->cdb_cmd_blk, sizeof(sl->cdb_cmd_blk)); + + int sending_length = STLINK_SG_SIZE; + DLOG("sending length set to: %d\n", sending_length); + + // send.... + do { + DLOG("attempting tx...\n"); + ret = libusb_bulk_transfer(sl->usb_handle, sl->ep_req, stl->c_buf, sending_length, + &real_transferred, 3 * 1000); + if (ret == LIBUSB_ERROR_PIPE) { + libusb_clear_halt(sl->usb_handle, sl->ep_req); + } + try++; + } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); + if (ret != LIBUSB_SUCCESS) { + WLOG("sending failed: %d\n", ret); + return; + } + DLOG("Actually sent: %d\n", real_transferred); + + // now wait for our response... + // length copied from stlink-usb... + int rx_length = 6; + try = 0; + do { + DLOG("attempting rx\n"); + ret = libusb_bulk_transfer(sl->usb_handle, sl->ep_rep, stl->q_buf, rx_length, + &real_transferred, 3 * 1000); + if (ret == LIBUSB_ERROR_PIPE) { + libusb_clear_halt(sl->usb_handle, sl->ep_req); + } + try++; + } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); + + if (ret != LIBUSB_SUCCESS) { + WLOG("Receiving failed: %d\n", ret); + return; + } + + if (real_transferred != rx_length) { + WLOG("received unexpected amount: %d != %d\n", real_transferred, rx_length); + } + + DLOG("Actually received: %d\n", real_transferred); } // Get stlink mode: @@ -736,65 +831,8 @@ stlink_backend_t _stlink_sg_backend = { _stlink_sg_force_debug }; -#if using_stm8_stuff_XXXX -stlink *stlink_open(libusb_context *usb_context) -{ - stlink *stl = malloc(sizeof(stlink)); - stl->handle = libusb_open_device_with_vid_pid(usb_context, USB_VID_ST, USB_PID_STLINK); - if (stl->handle == NULL) { - free(stl); - return NULL; - } - - libusb_device *dev = libusb_get_device(stl->handle); - struct libusb_config_descriptor *conf_desc; - int ret = libusb_get_config_descriptor(dev, 0, &conf_desc); - if (ret != LIBUSB_SUCCESS) { - libusb_close(stl->handle); - free(stl); - return NULL; - } - for (int i = 0; i < conf_desc->bNumInterfaces; i++) { - printf("interface %d\n", i); - for (int j = 0; j < conf_desc->interface[i].num_altsetting; j++) { - for (int k = 0; k < conf_desc->interface[i].altsetting[j].bNumEndpoints; k++) { - const struct libusb_endpoint_descriptor *endpoint; - endpoint = &conf_desc->interface[i].altsetting[j].endpoint[k]; - if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) { - stl->endpoint_in = endpoint->bEndpointAddress; - printf("Found IN endpoint\n"); - } else { - stl->endpoint_out = endpoint->bEndpointAddress; - printf("Found OUT endpoint\n"); - } - } - } - } - libusb_free_config_descriptor(conf_desc); - - ret = libusb_kernel_driver_active(stl->handle, 0); - if (ret == 1) { - printf("kernel driver active\n"); - } else if (ret == 0) { - //printf("kernel driver not active\n"); - } else { - fprintf(stderr, "libusb_kernel_driver_active = %d\n", ret); - } - ret = libusb_claim_interface(stl->handle, 0); - if (ret != LIBUSB_SUCCESS) { - fprintf(stderr, "claiming interface failed: %d\n", ret); - libusb_close(stl->handle); - free(stl); - return NULL; - } - - return stl; -} -#endif - - static stlink_t* stlink_open(const char *dev_name, const int verbose) { - fprintf(stderr, "\n*** stlink_open [%s] ***\n", dev_name); + DLOG("*** stlink_open [%s] ***\n", dev_name); stlink_t *sl = malloc(sizeof (stlink_t)); struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg)); @@ -810,13 +848,69 @@ static stlink_t* stlink_open(const char *dev_name, const int verbose) { return NULL; } - slsg->handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, USB_ST_VID, USB_STLINK_PID); - if (slsg->handle == NULL) { + libusb_set_debug(slsg->libusb_ctx, 3); + + slsg->usb_handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, USB_ST_VID, USB_STLINK_PID); + if (slsg->usb_handle == NULL) { WLOG("Failed to find an stlink v1 by VID:PID\n"); + libusb_close(slsg->usb_handle); + free(sl); + free(slsg); + return NULL; + } + + // TODO + // Could read the interface config descriptor, and assert lots of the assumptions + + // assumption: numInterfaces is always 1... + if (libusb_kernel_driver_active(slsg->usb_handle, 0) == 1) { + int r = libusb_detach_kernel_driver(slsg->usb_handle, 0); + if (r < 0) { + WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-r)); + libusb_close(slsg->usb_handle); + free(sl); + free(slsg); + return NULL; + } + DLOG("Kernel driver was successfully detached\n"); + } + + int config; + if (libusb_get_configuration(slsg->usb_handle, &config)) { + /* this may fail for a previous configured device */ + WLOG("libusb_get_configuration()\n"); + libusb_close(slsg->usb_handle); + free(sl); + free(slsg); + return NULL; + + } + + // assumption: bConfigurationValue is always 1 + if (config != 1) { + WLOG("Your stlink got into a real weird configuration, trying to fix it!\n"); + DLOG("setting new configuration (%d -> 1)\n", config); + if (libusb_set_configuration(slsg->usb_handle, 1)) { + /* this may fail for a previous configured device */ + WLOG("libusb_set_configuration() failed\n"); + libusb_close(slsg->usb_handle); + free(sl); + free(slsg); + return NULL; + } + } + + if (libusb_claim_interface(slsg->usb_handle, 0)) { + WLOG("libusb_claim_interface() failed\n"); + libusb_close(slsg->usb_handle); free(sl); free(slsg); return NULL; } + + // assumption: endpoint config is fixed mang. really. + slsg->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; + slsg->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; DLOG("Successfully opened stlinkv1 by libusb :)\n"); diff --git a/src/stlink-sg.h b/src/stlink-sg.h index c9776cddb..2e27ceb5f 100644 --- a/src/stlink-sg.h +++ b/src/stlink-sg.h @@ -42,7 +42,9 @@ extern "C" { struct stlink_libsg { libusb_context* libusb_ctx; - libusb_device_handle *handle; + libusb_device_handle *usb_handle; + unsigned ep_rep; + unsigned ep_req; int sg_fd; int do_scsi_pt_err; diff --git a/src/stlink-usb.c b/src/stlink-usb.c index c0b0009f2..a81676936 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -631,8 +631,8 @@ stlink_t* stlink_open_usb(const int verbose) { r = libusb_detach_kernel_driver(slu->usb_handle, 0); if (r<0) { WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-r)); + goto on_libusb_error; } - goto on_libusb_error; } if (libusb_get_configuration(slu->usb_handle, &config)) { From f587baa03ac9598130fac7f4ab58bef4030cb8df Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 3 Nov 2011 21:28:19 +0000 Subject: [PATCH 0024/1435] Use the libusb based sense and status reading from afaerber Before, I could a single operation (get version) after plugging in, now I can issue two at least :) I suspect there are two problems still. 1, I'm not using tags properly, as the original sg-utils code seemed to skip that. 2) I'm pretty sure I need to be sending variable lengths for the cdb field. --- src/stlink-sg.c | 332 +++++++++++++++++++++++++++++++++--------------- src/stlink-sg.h | 1 + 2 files changed, 233 insertions(+), 100 deletions(-) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 9d71df123..2c52e2a4c 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -70,6 +70,7 @@ #define __USE_GNU +#include #include #include #include @@ -214,14 +215,238 @@ static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) { } #endif -void stlink_q(stlink_t *sl) { -#if FINISHED_WITH_SG +static int dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) { + char dbugblah[100]; + char *dbugp = dbugblah; + dbugp += sprintf(dbugp, "Sending CDB ["); + for (uint8_t i = 0; i < cdb_len; i++) { + dbugp += sprintf(dbugp, " %#02x", (unsigned int) cdb[i]); + } + sprintf(dbugp, "]\n"); + DLOG(dbugblah); + return 0; +} + +/** + * Wraps a CDB mass storage command in the appropriate gunk to get it down + * @param handle + * @param endpoint + * @param cdb + * @param cdb_length + * @param lun + * @param flags + * @param expected_rx_size + * @return + */ +int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint_out, + uint8_t *cdb, uint8_t cdb_length, + uint8_t lun, uint8_t flags, uint32_t expected_rx_size) { + DLOG("Sending usb m-s cmd: cdblen:%d, rxsize=%d\n", cdb_length, expected_rx_size); + dump_CDB_command(cdb, cdb_length); + + int try = 0; + int ret = 0; + int real_transferred; + int i = 0; + + uint8_t c_buf[STLINK_SG_SIZE]; + // tag is allegedly ignored... TODO - verify + uint32_t tag = 1; + c_buf[i++] = 'U'; + c_buf[i++] = 'S'; + c_buf[i++] = 'B'; + c_buf[i++] = 'C'; + write_uint32(&c_buf[i], tag); + write_uint32(&c_buf[i+4], expected_rx_size); + i+= 8; + c_buf[i++] = flags; + c_buf[i++] = lun; + + c_buf[i++] = cdb_length; + + // Now the actual CDB request + assert(cdb_length <= CDB_SL); + memcpy(&(c_buf[i]), cdb, cdb_length); + + int sending_length = STLINK_SG_SIZE; + DLOG("sending length set to: %d\n", sending_length); + + // send.... + do { + DLOG("attempting tx...\n"); + ret = libusb_bulk_transfer(handle, endpoint_out, c_buf, sending_length, + &real_transferred, SG_TIMEOUT_MSEC); + if (ret == LIBUSB_ERROR_PIPE) { + libusb_clear_halt(handle, endpoint_out); + } + try++; + } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); + if (ret != LIBUSB_SUCCESS) { + WLOG("sending failed: %d\n", ret); + return -1; + } + DLOG("Actually sent: %d, returning tag: %d\n", real_transferred, tag); + return tag; +} + + +static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t endpoint, uint32_t *tag) +{ + unsigned char csw[13]; + memset(csw, 0, sizeof(csw)); + int transferred; + int ret; + int try = 0; + do { + ret = libusb_bulk_transfer(handle, endpoint, (unsigned char *)&csw, sizeof(csw), + &transferred, SG_TIMEOUT_MSEC); + if (ret == LIBUSB_ERROR_PIPE) { + libusb_clear_halt(handle, endpoint); + } + try++; + } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); + if (ret != LIBUSB_SUCCESS) { + fprintf(stderr, "%s: receiving failed: %d\n", __func__, ret); + return -1; + } + if (transferred != sizeof(csw)) { + fprintf(stderr, "%s: received unexpected amount: %d\n", __func__, transferred); + return -1; + } + + uint32_t rsig = read_uint32(csw, 0); + uint32_t rtag = read_uint32(csw, 4); + uint32_t residue = read_uint32(csw, 8); +#define USB_CSW_SIGNATURE 0x53425355 // 'U' 'S' 'B' 'S' (reversed) + if (rsig != USB_CSW_SIGNATURE) { + WLOG("status signature was invalid: %#x\n", rsig); + return -1; + } + DLOG("residue was= %#x\n", residue); + *tag = rtag; + uint8_t rstatus = csw[12]; + DLOG("rstatus = %x\n", rstatus); + return rstatus; +} + +/** + * Straight from stm8 stlink code... + * @param handle + * @param endpoint_in + * @param endpoint_out + */ +static void +get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out) +{ + uint8_t cdb[16]; + memset(cdb, 0, sizeof(cdb)); +#define REQUEST_SENSE 0x03 +#define REQUEST_SENSE_LENGTH 18 + cdb[0] = REQUEST_SENSE; + cdb[4] = REQUEST_SENSE_LENGTH; + uint32_t tag = send_usb_mass_storage_command(handle, endpoint_out, cdb, sizeof(cdb), 0, + LIBUSB_ENDPOINT_IN, REQUEST_SENSE_LENGTH); + if (tag == 0) { + WLOG("refusing to send request sense with tag 0\n"); + return; + } + unsigned char sense[REQUEST_SENSE_LENGTH]; + int transferred; + int ret; + int try = 0; + do { + ret = libusb_bulk_transfer(handle, endpoint_in, sense, sizeof(sense), + &transferred, SG_TIMEOUT_MSEC); + if (ret == LIBUSB_ERROR_PIPE) { + libusb_clear_halt(handle, endpoint_in); + } + try++; + } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); + if (ret != LIBUSB_SUCCESS) { + WLOG("receiving sense failed: %d\n", ret); + return; + } + if (transferred != sizeof(sense)) { + WLOG("received unexpected amount of sense: %d != %d\n", transferred, sizeof(sense)); + } + uint32_t received_tag; + int status = get_usb_mass_storage_status(handle, endpoint_in, &received_tag); + if (status != 0) { + WLOG("receiving sense failed with status: %02x\n", status); + return; + } + if (sense[0] != 0x70 && sense[0] != 0x71) { + WLOG("No sense data\n"); + } else { + WLOG("Sense KCQ: %02X %02X %02X\n", sense[2] & 0x0f, sense[12], sense[13]); + } +} + +int stlink_q(stlink_t *sl) { struct stlink_libsg* sg = sl->backend_data; - DLOG("CDB["); - for (int i = 0; i < CDB_SL; i++) - DLOG(" 0x%02x", (unsigned int) sg->cdb_cmd_blk[i]); - DLOG("]\n"); + //uint8_t cdb_len = 6; // FIXME varies!!! + uint8_t cdb_len = 10; // FIXME varies!!! + uint8_t lun = 0; // always zero... + send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, cdb_len, lun, LIBUSB_ENDPOINT_IN, sl->q_len); + + + // now wait for our response... + // length copied from stlink-usb... + int rx_length = sl->q_len; + int try = 0; + int real_transferred; + int ret; + do { + DLOG("attempting rx\n"); + ret = libusb_bulk_transfer(sg->usb_handle, sg->ep_rep, sl->q_buf, rx_length, + &real_transferred, SG_TIMEOUT_MSEC); + if (ret == LIBUSB_ERROR_PIPE) { + libusb_clear_halt(sg->usb_handle, sg->ep_req); + } + try++; + } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); + if (ret != LIBUSB_SUCCESS) { + WLOG("Receiving failed: %d\n", ret); + return -1; + } + + if (real_transferred != rx_length) { + WLOG("received unexpected amount: %d != %d\n", real_transferred, rx_length); + } + + +// stm8 stuff... + + + uint32_t received_tag; + // -ve is for my errors, 0 is good, +ve is libusb sense status bytes + int status = get_usb_mass_storage_status(sg->usb_handle, sg->ep_rep, &received_tag); + if (status < 0) { + WLOG("receiving status failed: %d\n", status); + return -1; + } + if (status != 0) { + WLOG("receiving status not passed :(: %02x\n", status); + } + if (status == 1) { + get_sense(sg->usb_handle, sg->ep_rep, sg->ep_req); + return -1; + } + uint32_t tag = 1; + if (received_tag != tag) { + WLOG("received tag %d but expected %d\n", received_tag, tag); + //return -1; + } + if (rx_length > 0 && real_transferred != rx_length) { + return -1; + } + return 0; + + + DLOG("Actually received: %d\n", real_transferred); + +#if FINISHED_WITH_SG // Get control command descriptor of scsi structure, // (one object per command!!) struct sg_pt_base *ptvp = construct_scsi_pt_obj(); @@ -281,102 +506,9 @@ void _stlink_sg_version(stlink_t *stl) { sl->cdb_cmd_blk[0] = STLINK_GET_VERSION; stl->q_len = 6; sl->q_addr = 0; -// stlink_q(stl); + stlink_q(stl); // HACK use my own private version right now... - int try = 0; - int ret = 0; - int real_transferred; - -/* - uint32_t dCBWSignature; - uint32_t dCBWTag; - uint32_t dCBWDataTransferLength; - uint8_t bmCBWFlags; - uint8_t bCBWLUN; - uint8_t bCBWCBLength; - uint8_t CBWCB[16]; - */ - -#if using_old_code_examples - /* - * and from old code? - cmd[i++] = 'U'; - cmd[i++] = 'S'; - cmd[i++] = 'B'; - cmd[i++] = 'C'; - write_uint32(&cmd[i], sg->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 */ - */ -#endif - - int i = 0; - stl->c_buf[i++] = 'U'; - stl->c_buf[i++] = 'S'; - stl->c_buf[i++] = 'B'; - stl->c_buf[i++] = 'C'; - // tag is allegedly ignored... TODO - verify - write_uint32(&stl->c_buf[i], 1); - // TODO - Does this even matter? verify with more commands.... - uint32_t command_length = STLINK_CMD_SIZE; - write_uint32(&stl->c_buf[i+4], command_length); - i+= 8; - stl->c_buf[i++] = LIBUSB_ENDPOINT_IN; - // assumption: lun is always 0; - stl->c_buf[i++] = 0; - - stl->c_buf[i++] = sizeof(sl->cdb_cmd_blk); - - // duh, now the actual data... - memcpy(&(stl->c_buf[i]), sl->cdb_cmd_blk, sizeof(sl->cdb_cmd_blk)); - - int sending_length = STLINK_SG_SIZE; - DLOG("sending length set to: %d\n", sending_length); - - // send.... - do { - DLOG("attempting tx...\n"); - ret = libusb_bulk_transfer(sl->usb_handle, sl->ep_req, stl->c_buf, sending_length, - &real_transferred, 3 * 1000); - if (ret == LIBUSB_ERROR_PIPE) { - libusb_clear_halt(sl->usb_handle, sl->ep_req); - } - try++; - } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); - if (ret != LIBUSB_SUCCESS) { - WLOG("sending failed: %d\n", ret); - return; - } - DLOG("Actually sent: %d\n", real_transferred); - - // now wait for our response... - // length copied from stlink-usb... - int rx_length = 6; - try = 0; - do { - DLOG("attempting rx\n"); - ret = libusb_bulk_transfer(sl->usb_handle, sl->ep_rep, stl->q_buf, rx_length, - &real_transferred, 3 * 1000); - if (ret == LIBUSB_ERROR_PIPE) { - libusb_clear_halt(sl->usb_handle, sl->ep_req); - } - try++; - } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); - - if (ret != LIBUSB_SUCCESS) { - WLOG("Receiving failed: %d\n", ret); - return; - } - - if (real_transferred != rx_length) { - WLOG("received unexpected amount: %d != %d\n", real_transferred, rx_length); - } - - DLOG("Actually received: %d\n", real_transferred); } // Get stlink mode: diff --git a/src/stlink-sg.h b/src/stlink-sg.h index 2e27ceb5f..8485d3d88 100644 --- a/src/stlink-sg.h +++ b/src/stlink-sg.h @@ -19,6 +19,7 @@ extern "C" { #define RDWR 0 #define RO 1 #define SG_TIMEOUT_SEC 1 // actually 1 is about 2 sec +#define SG_TIMEOUT_MSEC 3 * 1000 // Each CDB can be a total of 6, 10, 12, or 16 bytes, later version // of the SCSI standard also allow for variable-length CDBs (min. CDB is 6). // the stlink needs max. 10 bytes. From 22d0777df9f4987bd60ddf6bba5ef64ac0628d8a Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 3 Nov 2011 23:16:30 +0000 Subject: [PATCH 0025/1435] Properly use tags. Doesn't help though. --- src/stlink-sg.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 2c52e2a4c..8cf669388 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -244,6 +244,11 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint DLOG("Sending usb m-s cmd: cdblen:%d, rxsize=%d\n", cdb_length, expected_rx_size); dump_CDB_command(cdb, cdb_length); + static uint32_t tag; + if (tag == 0) { + tag = 1; + } + int try = 0; int ret = 0; int real_transferred; @@ -251,12 +256,12 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint uint8_t c_buf[STLINK_SG_SIZE]; // tag is allegedly ignored... TODO - verify - uint32_t tag = 1; c_buf[i++] = 'U'; c_buf[i++] = 'S'; c_buf[i++] = 'B'; c_buf[i++] = 'C'; write_uint32(&c_buf[i], tag); + uint32_t this_tag = tag++; write_uint32(&c_buf[i+4], expected_rx_size); i+= 8; c_buf[i++] = flags; @@ -286,7 +291,7 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint return -1; } DLOG("Actually sent: %d, returning tag: %d\n", real_transferred, tag); - return tag; + return this_tag; } @@ -338,6 +343,7 @@ static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t end static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out) { + DLOG("Fetching sense...\n"); uint8_t cdb[16]; memset(cdb, 0, sizeof(cdb)); #define REQUEST_SENSE 0x03 @@ -382,12 +388,18 @@ get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_ou } } +int stlink_q2(stlink_t *sl, uint8_t cdb_len); int stlink_q(stlink_t *sl) { + return stlink_q2(sl, 10); +} + +int stlink_q2(stlink_t *sl, uint8_t cdb_len) { struct stlink_libsg* sg = sl->backend_data; //uint8_t cdb_len = 6; // FIXME varies!!! - uint8_t cdb_len = 10; // FIXME varies!!! + //uint8_t cdb_len = 10; // FIXME varies!!! uint8_t lun = 0; // always zero... - send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, cdb_len, lun, LIBUSB_ENDPOINT_IN, sl->q_len); + uint32_t tag = send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, + sg->cdb_cmd_blk, cdb_len, lun, LIBUSB_ENDPOINT_IN, sl->q_len); // now wait for our response... @@ -414,11 +426,7 @@ int stlink_q(stlink_t *sl) { if (real_transferred != rx_length) { WLOG("received unexpected amount: %d != %d\n", real_transferred, rx_length); } - - -// stm8 stuff... - - + uint32_t received_tag; // -ve is for my errors, 0 is good, +ve is libusb sense status bytes int status = get_usb_mass_storage_status(sg->usb_handle, sg->ep_rep, &received_tag); @@ -433,7 +441,6 @@ int stlink_q(stlink_t *sl) { get_sense(sg->usb_handle, sg->ep_rep, sg->ep_req); return -1; } - uint32_t tag = 1; if (received_tag != tag) { WLOG("received tag %d but expected %d\n", received_tag, tag); //return -1; @@ -1093,7 +1100,7 @@ stlink_t* stlink_v1_open(const char *dev_name, const int verbose) { return NULL; } - DLOG("\n*** stlink_force_open ***\n"); + DLOG("Reading current mode...\n"); switch (stlink_current_mode(sl)) { case STLINK_DEV_MASS_MODE: return sl; @@ -1101,8 +1108,11 @@ stlink_t* stlink_v1_open(const char *dev_name, const int verbose) { // TODO go to mass? return sl; } - DLOG("\n*** switch the stlink to mass mode ***\n"); + + DLOG("Attempting to exit DFU mode\n"); _stlink_sg_exit_dfu_mode(sl); + +#if 0 // exit the dfu mode -> the device is gone DLOG("\n*** reopen the stlink device ***\n"); delay(1000); @@ -1116,6 +1126,7 @@ stlink_t* stlink_v1_open(const char *dev_name, const int verbose) { } // re-query device info stlink_version(sl); +#endif return sl; } From 87490393e86fffb812c12e871e31f970324fd677 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 3 Nov 2011 23:24:28 +0000 Subject: [PATCH 0026/1435] Duh, don't try and do a bulk read when we requested 0 bytes back. --- src/stlink-sg.c | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 8cf669388..2253212bd 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -388,15 +388,10 @@ get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_ou } } -int stlink_q2(stlink_t *sl, uint8_t cdb_len); int stlink_q(stlink_t *sl) { - return stlink_q2(sl, 10); -} - -int stlink_q2(stlink_t *sl, uint8_t cdb_len) { struct stlink_libsg* sg = sl->backend_data; //uint8_t cdb_len = 6; // FIXME varies!!! - //uint8_t cdb_len = 10; // FIXME varies!!! + uint8_t cdb_len = 10; // FIXME varies!!! uint8_t lun = 0; // always zero... uint32_t tag = send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, cdb_len, lun, LIBUSB_ENDPOINT_IN, sl->q_len); @@ -408,23 +403,25 @@ int stlink_q2(stlink_t *sl, uint8_t cdb_len) { int try = 0; int real_transferred; int ret; - do { - DLOG("attempting rx\n"); - ret = libusb_bulk_transfer(sg->usb_handle, sg->ep_rep, sl->q_buf, rx_length, - &real_transferred, SG_TIMEOUT_MSEC); - if (ret == LIBUSB_ERROR_PIPE) { - libusb_clear_halt(sg->usb_handle, sg->ep_req); + if (rx_length > 0) { + do { + DLOG("attempting rx\n"); + ret = libusb_bulk_transfer(sg->usb_handle, sg->ep_rep, sl->q_buf, rx_length, + &real_transferred, SG_TIMEOUT_MSEC); + if (ret == LIBUSB_ERROR_PIPE) { + libusb_clear_halt(sg->usb_handle, sg->ep_req); + } + try++; + } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); + + if (ret != LIBUSB_SUCCESS) { + WLOG("Receiving failed: %d\n", ret); + return -1; } - try++; - } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); - if (ret != LIBUSB_SUCCESS) { - WLOG("Receiving failed: %d\n", ret); - return -1; - } - - if (real_transferred != rx_length) { - WLOG("received unexpected amount: %d != %d\n", real_transferred, rx_length); + if (real_transferred != rx_length) { + WLOG("received unexpected amount: %d != %d\n", real_transferred, rx_length); + } } uint32_t received_tag; @@ -1112,13 +1109,13 @@ stlink_t* stlink_v1_open(const char *dev_name, const int verbose) { DLOG("Attempting to exit DFU mode\n"); _stlink_sg_exit_dfu_mode(sl); -#if 0 // exit the dfu mode -> the device is gone DLOG("\n*** reopen the stlink device ***\n"); delay(1000); stlink_close(sl); delay(5000); + DLOG("Attempting to reopen the stlink...\n"); sl = stlink_open(dev_name, verbose); if (sl == NULL) { fputs("Error: could not open stlink device\n", stderr); @@ -1126,7 +1123,6 @@ stlink_t* stlink_v1_open(const char *dev_name, const int verbose) { } // re-query device info stlink_version(sl); -#endif return sl; } From 0f376a74a51cf3e3134b0e6f2ad0415f43968ed1 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 3 Nov 2011 23:40:27 +0000 Subject: [PATCH 0027/1435] Remove device names, we now just find it via USB ids. In the future, we might actually want device names back again, if you have multiple stlink's connected. But that would be a new device name, not scanning for /dev/sgX looking for scsi devices. --- gdbserver/gdb-server.c | 38 ++------------------------------------ src/stlink-sg.c | 18 ++++++------------ src/stlink-sg.h | 3 ++- src/test_sg.c | 21 +++++++-------------- 4 files changed, 17 insertions(+), 63 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 65297bc0c..df3657a9b 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -197,42 +197,8 @@ int main(int argc, char** argv) { if(sl == NULL) return 1; break; case 1: - if (strlen(state.devicename) == 0) { - const int DevNumMax = 99; - int ExistDevCount = 0; - - for (int DevNum = 0; DevNum <= DevNumMax; DevNum++) { - if (DevNum < 10) { - char DevName[] = "/dev/sgX"; - const int X_index = 7; - DevName[X_index] = DevNum + '0'; - if (!access(DevName, F_OK)) { - sl = stlink_v1_open(DevName, 0); - ExistDevCount++; - } - } else if (DevNum < 100) { - char DevName[] = "/dev/sgXY"; - const int X_index = 7; - const int Y_index = 8; - DevName[X_index] = DevNum / 10 + '0'; - DevName[Y_index] = DevNum % 10 + '0'; - if (!access(DevName, F_OK)) { - sl = stlink_v1_open(DevName, 0); - ExistDevCount++; - } - } - if (sl != NULL) break; - } - - if (sl == NULL) { - fprintf(stdout, "\nNumber of /dev/sgX devices found: %i \n", - ExistDevCount); - fprintf(stderr, "ST-LINK not found\n"); - return 1; - } - } else { - sl = stlink_v1_open(state.devicename, state.logging_level); - } + sl = stlink_v1_open(NULL, state.logging_level); + if(sl == NULL) return 1; break; } diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 2253212bd..64f182022 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -967,8 +967,7 @@ stlink_backend_t _stlink_sg_backend = { _stlink_sg_force_debug }; -static stlink_t* stlink_open(const char *dev_name, const int verbose) { - DLOG("*** stlink_open [%s] ***\n", dev_name); +static stlink_t* stlink_open(const int verbose) { stlink_t *sl = malloc(sizeof (stlink_t)); struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg)); @@ -1076,24 +1075,19 @@ static stlink_t* stlink_open(const char *dev_name, const int verbose) { -stlink_t* stlink_v1_open(const char *dev_name, const int verbose) { +stlink_t* stlink_v1_open(const int verbose) { ugly_init(verbose); - stlink_t *sl = stlink_open(dev_name, verbose); + stlink_t *sl = stlink_open(verbose); if (sl == NULL) { fputs("Error: could not open stlink device\n", stderr); return NULL; } stlink_version(sl); - struct stlink_libsg *sg = sl->backend_data; if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { - fprintf(stderr, "Error: the device %s is not a stlink\n", - dev_name); - fprintf(stderr, " VID: got %04x expect %04x \n", - sl->version.st_vid, USB_ST_VID); - fprintf(stderr, " PID: got %04x expect %04x \n", - sl->version.stlink_pid, USB_STLINK_PID); + ugly_log(UERROR, LOG_TAG, + "WTF? successfully opened, but unable to read version details. BROKEN!\n"); return NULL; } @@ -1116,7 +1110,7 @@ stlink_t* stlink_v1_open(const char *dev_name, const int verbose) { delay(5000); DLOG("Attempting to reopen the stlink...\n"); - sl = stlink_open(dev_name, verbose); + sl = stlink_open(verbose); if (sl == NULL) { fputs("Error: could not open stlink device\n", stderr); return NULL; diff --git a/src/stlink-sg.h b/src/stlink-sg.h index 8485d3d88..d4d7723b8 100644 --- a/src/stlink-sg.h +++ b/src/stlink-sg.h @@ -57,12 +57,13 @@ extern "C" { uint32_t q_addr; // Sense (error information) data + // obsolete, this was fed to the scsi tools unsigned char sense_buf[SENSE_BUF_LEN]; reg reg; }; - stlink_t* stlink_v1_open(const char *dev_name, const int verbose); + stlink_t* stlink_v1_open(const int verbose); #ifdef __cplusplus } diff --git a/src/test_sg.c b/src/test_sg.c index 742ba4453..a8a7022c8 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -10,33 +10,26 @@ int main(int argc, char *argv[]) { // set scpi lib debug level: 0 for no debug info, 10 for lots - char *dev_name; switch (argc) { case 1: fputs( - "\nUsage: stlink-access-test /dev/sg0, sg1, ...\n" + "\nUsage: stlink-access-test [anything at all] ...\n" "\n*** Notice: The stlink firmware violates the USB standard.\n" - "*** If you plug-in the discovery's stlink, wait a several\n" - "*** minutes to let the kernel driver swallow the broken device.\n" - "*** Watch:\ntail -f /var/log/messages\n" - "*** This command sequence can shorten the waiting time and fix some issues.\n" + "*** Because we just use libusb, we can just tell the kernel's\n" + "*** driver to simply ignore the device...\n" "*** Unplug the stlink and execute once as root:\n" - "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:lrwsro\n\n", + "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n\n", stderr); return EXIT_FAILURE; - case 2: - dev_name = argv[1]; - break; default: - fprintf(stderr, "bzzt\n"); - return EXIT_FAILURE; + break; } - stlink_t *sl = stlink_v1_open(dev_name, 99); + stlink_t *sl = stlink_v1_open(99); if (sl == NULL) return EXIT_FAILURE; - + // we are in mass mode, go to swd stlink_enter_swd_mode(sl); stlink_current_mode(sl); From 8febc74cf1aeacdd57adff1eb85ea55f096ccaec Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 4 Nov 2011 00:44:18 +0000 Subject: [PATCH 0028/1435] Fix write_mem32. Moved some of the static methods up to the top, so they can always be used, so the changes is messier than it needs to be. --- src/stlink-sg.c | 337 ++++++++++++++++++++++++++---------------------- src/test_sg.c | 41 ++++-- 2 files changed, 213 insertions(+), 165 deletions(-) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 64f182022..276986ef7 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -107,15 +107,6 @@ static void clear_cdb(struct stlink_libsg *sl) { sl->q_data_dir = Q_DATA_IN; } -// E.g. make the valgrind happy. - -static void clear_buf(stlink_t *sl) { - DLOG("*** clear_buf ***\n"); - for (size_t i = 0; i < sizeof (sl->q_buf); i++) - sl->q_buf[i] = 0; - -} - // close the device, free the allocated memory void _stlink_sg_close(stlink_t *sl) { @@ -128,92 +119,44 @@ void _stlink_sg_close(stlink_t *sl) { } } - -//TODO rewrite/cleanup, save the error in sl - -#if FINISHED_WITH_SG -static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) { - struct stlink_libsg *sl = stl->backend_data; - const int e = sl->do_scsi_pt_err; - if (e < 0) { - fprintf(stderr, "scsi_pt error: pass through os error: %s\n", - safe_strerror(-e)); - return; - } else if (e == SCSI_PT_DO_BAD_PARAMS) { - fprintf(stderr, "scsi_pt error: bad pass through setup\n"); - return; - } else if (e == SCSI_PT_DO_TIMEOUT) { - fprintf(stderr, " pass through timeout\n"); - return; +static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t endpoint, uint32_t *tag) +{ + unsigned char csw[13]; + memset(csw, 0, sizeof(csw)); + int transferred; + int ret; + int try = 0; + do { + ret = libusb_bulk_transfer(handle, endpoint, (unsigned char *)&csw, sizeof(csw), + &transferred, SG_TIMEOUT_MSEC); + if (ret == LIBUSB_ERROR_PIPE) { + libusb_clear_halt(handle, endpoint); + } + try++; + } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); + if (ret != LIBUSB_SUCCESS) { + fprintf(stderr, "%s: receiving failed: %d\n", __func__, ret); + return -1; + } + if (transferred != sizeof(csw)) { + fprintf(stderr, "%s: received unexpected amount: %d\n", __func__, transferred); + return -1; } - const int duration = get_scsi_pt_duration_ms(ptvp); - if ((stl->verbose > 1) && (duration >= 0)) - DLOG(" duration=%d ms\n", duration); - - // XXX stlink fw sends broken residue, so ignore it and use the known q_len - // "usb-storage quirks=483:3744:r" - // forces residue to be ignored and calculated, but this causes aboard if - // data_len = 0 and by some other data_len values. - - const int resid = get_scsi_pt_resid(ptvp); - const int dsize = stl->q_len - resid; - - const int cat = get_scsi_pt_result_category(ptvp); - char buf[512]; - unsigned int slen; - switch (cat) { - case SCSI_PT_RESULT_GOOD: - if (stl->verbose && (resid > 0)) - DLOG(" notice: requested %d bytes but " - "got %d bytes, ignore [broken] residue = %d\n", - stl->q_len, dsize, resid); - break; - case SCSI_PT_RESULT_STATUS: - if (stl->verbose) { - sg_get_scsi_status_str( - get_scsi_pt_status_response(ptvp), sizeof (buf), - buf); - DLOG(" scsi status: %s\n", buf); - } - return; - case SCSI_PT_RESULT_SENSE: - slen = get_scsi_pt_sense_len(ptvp); - if (stl->verbose) { - sg_get_sense_str("", sl->sense_buf, slen, (stl->verbose - > 1), sizeof (buf), buf); - DLOG("%s", buf); - } - if (stl->verbose && (resid > 0)) { - if ((stl->verbose) || (stl->q_len > 0)) - DLOG(" requested %d bytes but " - "got %d bytes\n", stl->q_len, dsize); - } - return; - case SCSI_PT_RESULT_TRANSPORT_ERR: - if (stl->verbose) { - get_scsi_pt_transport_err_str(ptvp, sizeof (buf), buf); - // http://tldp.org/HOWTO/SCSI-Generic-HOWTO/x291.html - // These codes potentially come from the firmware on a host adapter - // or from one of several hosts that an adapter driver controls. - // The 'host_status' field has the following values: - // [0x07] Internal error detected in the host adapter. - // This may not be fatal (and the command may have succeeded). - DLOG(" transport: %s", buf); - } - return; - case SCSI_PT_RESULT_OS_ERR: - if (stl->verbose) { - get_scsi_pt_os_err_str(ptvp, sizeof (buf), buf); - DLOG(" os: %s", buf); - } - return; - default: - fprintf(stderr, " unknown pass through result " - "category (%d)\n", cat); + uint32_t rsig = read_uint32(csw, 0); + uint32_t rtag = read_uint32(csw, 4); + uint32_t residue = read_uint32(csw, 8); +#define USB_CSW_SIGNATURE 0x53425355 // 'U' 'S' 'B' 'S' (reversed) + if (rsig != USB_CSW_SIGNATURE) { + WLOG("status signature was invalid: %#x\n", rsig); + return -1; } + DLOG("residue was= %#x\n", residue); + *tag = rtag; + uint8_t rstatus = csw[12]; + DLOG("rstatus = %x\n", rstatus); + return rstatus; } -#endif static int dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) { char dbugblah[100]; @@ -295,45 +238,6 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint } -static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t endpoint, uint32_t *tag) -{ - unsigned char csw[13]; - memset(csw, 0, sizeof(csw)); - int transferred; - int ret; - int try = 0; - do { - ret = libusb_bulk_transfer(handle, endpoint, (unsigned char *)&csw, sizeof(csw), - &transferred, SG_TIMEOUT_MSEC); - if (ret == LIBUSB_ERROR_PIPE) { - libusb_clear_halt(handle, endpoint); - } - try++; - } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); - if (ret != LIBUSB_SUCCESS) { - fprintf(stderr, "%s: receiving failed: %d\n", __func__, ret); - return -1; - } - if (transferred != sizeof(csw)) { - fprintf(stderr, "%s: received unexpected amount: %d\n", __func__, transferred); - return -1; - } - - uint32_t rsig = read_uint32(csw, 0); - uint32_t rtag = read_uint32(csw, 4); - uint32_t residue = read_uint32(csw, 8); -#define USB_CSW_SIGNATURE 0x53425355 // 'U' 'S' 'B' 'S' (reversed) - if (rsig != USB_CSW_SIGNATURE) { - WLOG("status signature was invalid: %#x\n", rsig); - return -1; - } - DLOG("residue was= %#x\n", residue); - *tag = rtag; - uint8_t rstatus = csw[12]; - DLOG("rstatus = %x\n", rstatus); - return rstatus; -} - /** * Straight from stm8 stlink code... * @param handle @@ -388,6 +292,143 @@ get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_ou } } + +//TODO rewrite/cleanup, save the error in sl + +#if FINISHED_WITH_SG +static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) { + struct stlink_libsg *sl = stl->backend_data; + const int e = sl->do_scsi_pt_err; + if (e < 0) { + fprintf(stderr, "scsi_pt error: pass through os error: %s\n", + safe_strerror(-e)); + return; + } else if (e == SCSI_PT_DO_BAD_PARAMS) { + fprintf(stderr, "scsi_pt error: bad pass through setup\n"); + return; + } else if (e == SCSI_PT_DO_TIMEOUT) { + fprintf(stderr, " pass through timeout\n"); + return; + } + const int duration = get_scsi_pt_duration_ms(ptvp); + if ((stl->verbose > 1) && (duration >= 0)) + DLOG(" duration=%d ms\n", duration); + + // XXX stlink fw sends broken residue, so ignore it and use the known q_len + // "usb-storage quirks=483:3744:r" + // forces residue to be ignored and calculated, but this causes aboard if + // data_len = 0 and by some other data_len values. + + const int resid = get_scsi_pt_resid(ptvp); + const int dsize = stl->q_len - resid; + + const int cat = get_scsi_pt_result_category(ptvp); + char buf[512]; + unsigned int slen; + + switch (cat) { + case SCSI_PT_RESULT_GOOD: + if (stl->verbose && (resid > 0)) + DLOG(" notice: requested %d bytes but " + "got %d bytes, ignore [broken] residue = %d\n", + stl->q_len, dsize, resid); + break; + case SCSI_PT_RESULT_STATUS: + if (stl->verbose) { + sg_get_scsi_status_str( + get_scsi_pt_status_response(ptvp), sizeof (buf), + buf); + DLOG(" scsi status: %s\n", buf); + } + return; + case SCSI_PT_RESULT_SENSE: + slen = get_scsi_pt_sense_len(ptvp); + if (stl->verbose) { + sg_get_sense_str("", sl->sense_buf, slen, (stl->verbose + > 1), sizeof (buf), buf); + DLOG("%s", buf); + } + if (stl->verbose && (resid > 0)) { + if ((stl->verbose) || (stl->q_len > 0)) + DLOG(" requested %d bytes but " + "got %d bytes\n", stl->q_len, dsize); + } + return; + case SCSI_PT_RESULT_TRANSPORT_ERR: + if (stl->verbose) { + get_scsi_pt_transport_err_str(ptvp, sizeof (buf), buf); + // http://tldp.org/HOWTO/SCSI-Generic-HOWTO/x291.html + // These codes potentially come from the firmware on a host adapter + // or from one of several hosts that an adapter driver controls. + // The 'host_status' field has the following values: + // [0x07] Internal error detected in the host adapter. + // This may not be fatal (and the command may have succeeded). + DLOG(" transport: %s", buf); + } + return; + case SCSI_PT_RESULT_OS_ERR: + if (stl->verbose) { + get_scsi_pt_os_err_str(ptvp, sizeof (buf), buf); + DLOG(" os: %s", buf); + } + return; + default: + fprintf(stderr, " unknown pass through result " + "category (%d)\n", cat); + } +} +#endif + +/** + * Just send a buffer on an endpoint, no questions asked. + * Handles repeats, and time outs. Also handles reading status reports and sense + * @param handle libusb device * + * @param endpoint_out sends + * @param endpoint_in used to read status reports back in + * @param cbuf what to send + * @param length how much to send + * @return number of bytes actually sent, or -1 for failures. + */ +int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, + unsigned char endpoint_in, unsigned char *cbuf, unsigned int length) { + int ret; + int real_transferred; + int try; + do { + DLOG("attempting tx...\n"); + ret = libusb_bulk_transfer(handle, endpoint_out, cbuf, length, + &real_transferred, SG_TIMEOUT_MSEC); + if (ret == LIBUSB_ERROR_PIPE) { + libusb_clear_halt(handle, endpoint_out); + } + try++; + } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); + if (ret != LIBUSB_SUCCESS) { + WLOG("sending failed: %d\n", ret); + return -1; + } + DLOG("Actually sent: %d\n", real_transferred); + + // now, swallow up the status, so that things behave nicely... + uint32_t received_tag; + // -ve is for my errors, 0 is good, +ve is libusb sense status bytes + int status = get_usb_mass_storage_status(handle, endpoint_in, &received_tag); + if (status < 0) { + WLOG("receiving status failed: %d\n", status); + return -1; + } + if (status != 0) { + WLOG("receiving status not passed :(: %02x\n", status); + } + if (status == 1) { + get_sense(handle, endpoint_in, endpoint_out); + return -1; + } + + return real_transferred; +} + + int stlink_q(stlink_t *sl) { struct stlink_libsg* sg = sl->backend_data; //uint8_t cdb_len = 6; // FIXME varies!!! @@ -865,11 +906,10 @@ void _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { write_uint32(sg->cdb_cmd_blk + 2, addr); write_uint16(sg->cdb_cmd_blk + 6, len); - // data_out 0-len - sl->q_len = len; - sg->q_addr = addr; - sg->q_data_dir = Q_DATA_OUT; - stlink_q(sl); + // this sends the command... + send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); + // This sends the data... + send_usb_data_only(sg->usb_handle, sg->ep_req, sg->ep_rep, sl->q_buf, len); stlink_print_data(sl); } @@ -884,11 +924,11 @@ void _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { write_uint32(sg->cdb_cmd_blk + 2, addr); write_uint16(sg->cdb_cmd_blk + 6, len); - // data_out 0-0x40-...-len - sl->q_len = len; - sg->q_addr = addr; - sg->q_data_dir = Q_DATA_OUT; - stlink_q(sl); + // this sends the command... + send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); + // This sends the data... + send_usb_data_only(sg->usb_handle, sg->ep_req, sg->ep_rep, sl->q_buf, len); + stlink_print_data(sl); } @@ -970,6 +1010,7 @@ stlink_backend_t _stlink_sg_backend = { static stlink_t* stlink_open(const int verbose) { stlink_t *sl = malloc(sizeof (stlink_t)); + memset(sl, 0, sizeof(stlink_t)); struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg)); if (sl == NULL || slsg == NULL) { WLOG("Couldn't malloc stlink and stlink_sg structures out of memory!\n"); @@ -1055,7 +1096,6 @@ static stlink_t* stlink_open(const int verbose) { sl->core_stat = STLINK_CORE_STAT_UNKNOWN; slsg->q_addr = 0; - clear_buf(sl); /* flash memory settings */ sl->flash_base = STM32_FLASH_BASE; @@ -1119,18 +1159,3 @@ stlink_t* stlink_v1_open(const int verbose) { stlink_version(sl); return sl; } - -static void __attribute__((unused)) mark_buf(stlink_t *sl) { - clear_buf(sl); - sl->q_buf[0] = 0x12; - sl->q_buf[1] = 0x34; - sl->q_buf[2] = 0x56; - sl->q_buf[3] = 0x78; - sl->q_buf[4] = 0x90; - sl->q_buf[15] = 0x42; - sl->q_buf[16] = 0x43; - sl->q_buf[63] = 0x42; - sl->q_buf[64] = 0x43; - sl->q_buf[1024 * 6 - 1] = 0x42; //6kB - sl->q_buf[1024 * 8 - 1] = 0x42; //8kB -} diff --git a/src/test_sg.c b/src/test_sg.c index a8a7022c8..d9e560c23 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -6,7 +6,31 @@ #include #include +#include #include "stlink-common.h" +#include "uglylogging.h" + +#define LOG_TAG __FILE__ +#define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args) +#define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args) +#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args) +#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args) + +static void __attribute__((unused)) mark_buf(stlink_t *sl) { + memset(sl->q_buf, 0, sizeof(sl->q_buf)); + sl->q_buf[0] = 0xaa; + sl->q_buf[1] = 0xbb; + sl->q_buf[2] = 0xcc; + sl->q_buf[3] = 0xdd; + sl->q_buf[4] = 0x11; + sl->q_buf[15] = 0x22; + sl->q_buf[16] = 0x33; + sl->q_buf[63] = 0x44; + sl->q_buf[64] = 0x69; + sl->q_buf[1024 * 6 - 1] = 0x42; //6kB + sl->q_buf[1024 * 8 - 1] = 0x42; //8kB +} + int main(int argc, char *argv[]) { // set scpi lib debug level: 0 for no debug info, 10 for lots @@ -40,14 +64,14 @@ int main(int argc, char *argv[]) { //stlink_force_debug(sl); stlink_reset(sl); stlink_status(sl); -#if 0 // core system control block stlink_read_mem32(sl, 0xe000ed00, 4); - DD(sl, "cpu id base register: SCB_CPUID = got 0x%08x expect 0x411fc231", read_uint32(sl->q_buf, 0)); + DLOG("cpu id base register: SCB_CPUID = got 0x%08x expect 0x411fc231\n", read_uint32(sl->q_buf, 0)); // no MPU stlink_read_mem32(sl, 0xe000ed90, 4); - DD(sl, "mpu type register: MPU_TYPER = got 0x%08x expect 0x0", read_uint32(sl->q_buf, 0)); + DLOG("mpu type register: MPU_TYPER = got 0x%08x expect 0x0\n", read_uint32(sl->q_buf, 0)); +#if 0 stlink_read_mem32(sl, 0xe000edf0, 4); DD(sl, "DHCSR = 0x%08x", read_uint32(sl->q_buf, 0)); @@ -105,10 +129,10 @@ int main(int argc, char *argv[]) { #if 0 // sram 0x20000000 8kB fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); - clear_buf(sl); + memset(sl->q_buf, 0, sizeof(sl->q_buf)); + mark_buf(sl); stlink_write_mem8(sl, 0x20000000, 16); - mark_buf(sl); stlink_write_mem8(sl, 0x20000000, 1); stlink_write_mem8(sl, 0x20000001, 1); stlink_write_mem8(sl, 0x2000000b, 3); @@ -117,9 +141,7 @@ int main(int argc, char *argv[]) { #if 0 // a not aligned mem32 access doesn't work indeed fputs("\n++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); - clear_buf(sl); - stlink_write_mem8(sl, 0x20000000, 32); - + memset(sl->q_buf, 0, sizeof(sl->q_buf)); mark_buf(sl); stlink_write_mem32(sl, 0x20000000, 1); stlink_read_mem32(sl, 0x20000000, 16); @@ -134,9 +156,10 @@ int main(int argc, char *argv[]) { stlink_write_mem32(sl, 0x20000000, 17); stlink_read_mem32(sl, 0x20000000, 32); #endif -#if 0 +#if 1 // sram 0x20000000 8kB fputs("++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++\n", stderr); + memset(sl->q_buf, 0, sizeof(sl->q_buf)); mark_buf(sl); stlink_write_mem8(sl, 0x20000000, 64); stlink_read_mem32(sl, 0x20000000, 64); From 2dc7d9f4ec376f9c53dbb9a0413a0b0161378d0a Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 4 Nov 2011 00:51:30 +0000 Subject: [PATCH 0029/1435] write_mem8 works too. I just misinterpreted the test results earlier. --- src/test_sg.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test_sg.c b/src/test_sg.c index d9e560c23..19a2ef510 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -126,15 +126,15 @@ int main(int argc, char *argv[]) { stlink_read_mem32(sl, 0x08000c00, 256); stlink_read_mem32(sl, 0x08000c00, 256); #endif -#if 0 +#if 1 // sram 0x20000000 8kB fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); mark_buf(sl); - stlink_write_mem8(sl, 0x20000000, 16); + //stlink_write_mem8(sl, 0x20000000, 16); - stlink_write_mem8(sl, 0x20000000, 1); - stlink_write_mem8(sl, 0x20000001, 1); + //stlink_write_mem8(sl, 0x20000000, 1); + //stlink_write_mem8(sl, 0x20000001, 1); stlink_write_mem8(sl, 0x2000000b, 3); stlink_read_mem32(sl, 0x20000000, 16); #endif @@ -156,7 +156,7 @@ int main(int argc, char *argv[]) { stlink_write_mem32(sl, 0x20000000, 17); stlink_read_mem32(sl, 0x20000000, 32); #endif -#if 1 +#if 0 // sram 0x20000000 8kB fputs("++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); From 8c7b98a4cbd9848dbd029e02f367ef7b1289044a Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 4 Nov 2011 00:54:01 +0000 Subject: [PATCH 0030/1435] blinking LEDs via stlink also works --- src/test_sg.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test_sg.c b/src/test_sg.c index 19a2ef510..899efc3a9 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -78,7 +78,7 @@ int main(int argc, char *argv[]) { stlink_read_mem32(sl, 0x4001100c, 4); DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); #endif -#if 0 +#if 1 // happy new year 2011: let blink all the leds // see "RM0041 Reference manual - STM32F100xx advanced ARM-based 32-bit MCUs" @@ -89,23 +89,23 @@ int main(int argc, char *argv[]) { #define LED_GREEN (1<<9) // pin 9 stlink_read_mem32(sl, GPIOC_CRH, 4); uint32_t io_conf = read_uint32(sl->q_buf, 0); - DD(sl, "GPIOC_CRH = 0x%08x", io_conf); + DLOG("GPIOC_CRH = 0x%08x\n", io_conf); // set: general purpose output push-pull, output mode, max speed 10 MHz. write_uint32(sl->q_buf, 0x44444411); stlink_write_mem32(sl, GPIOC_CRH, 4); - clear_buf(sl); + memset(sl->q_buf, 0, sizeof(sl->q_buf)); for (int i = 0; i < 100; i++) { write_uint32(sl->q_buf, LED_BLUE | LED_GREEN); stlink_write_mem32(sl, GPIOC_ODR, 4); /* stlink_read_mem32(sl, 0x4001100c, 4); */ /* DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); */ - delay(100); + usleep(100 * 1000); - clear_buf(sl); + memset(sl->q_buf, 0, sizeof(sl->q_buf)); stlink_write_mem32(sl, GPIOC_ODR, 4); // PC lo - delay(100); + usleep(100 * 1000); } write_uint32(sl->q_buf, io_conf); // set old state @@ -126,7 +126,7 @@ int main(int argc, char *argv[]) { stlink_read_mem32(sl, 0x08000c00, 256); stlink_read_mem32(sl, 0x08000c00, 256); #endif -#if 1 +#if 0 // sram 0x20000000 8kB fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); From a19abbb547116f343c5dcb2b3a6d0f6d1d457dae Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 4 Nov 2011 00:56:50 +0000 Subject: [PATCH 0031/1435] Writing registers works too --- src/test_sg.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/test_sg.c b/src/test_sg.c index 899efc3a9..357f43665 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -78,7 +78,7 @@ int main(int argc, char *argv[]) { stlink_read_mem32(sl, 0x4001100c, 4); DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); #endif -#if 1 +#if 0 // happy new year 2011: let blink all the leds // see "RM0041 Reference manual - STM32F100xx advanced ARM-based 32-bit MCUs" @@ -169,13 +169,14 @@ int main(int argc, char *argv[]) { stlink_read_mem32(sl, 0x20000000, 1024 * 6); stlink_read_mem32(sl, 0x20000000 + 1024 * 6, 1024 * 2); #endif -#if 0 - stlink_read_all_regs(sl); +#if 1 + reg regs; + stlink_read_all_regs(sl, ®s); stlink_step(sl); fputs("++++++++++ write r0 = 0x12345678\n", stderr); stlink_write_reg(sl, 0x12345678, 0); - stlink_read_reg(sl, 0); - stlink_read_all_regs(sl); + stlink_read_reg(sl, 0, ®s); + stlink_read_all_regs(sl, ®s); #endif #if 0 stlink_run(sl); From fd5967fba684bb0f4d83b0b72559da8021e1c995 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 4 Nov 2011 01:05:27 +0000 Subject: [PATCH 0032/1435] Fix compilation error after removing devices. --- gdbserver/gdb-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index df3657a9b..bcb3c974b 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -197,7 +197,7 @@ int main(int argc, char** argv) { if(sl == NULL) return 1; break; case 1: - sl = stlink_v1_open(NULL, state.logging_level); + sl = stlink_v1_open(state.logging_level); if(sl == NULL) return 1; break; } From 3dd1addf929f95e05fa676bab5a41515e990e16a Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 4 Nov 2011 01:05:54 +0000 Subject: [PATCH 0033/1435] Update netbeans project files. --- nbproject/configurations.xml | 355 ++++++++++++++++++++++++++++++++++- nbproject/project.xml | 4 + 2 files changed, 355 insertions(+), 4 deletions(-) diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index 567946524..47cfb040a 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -117,6 +117,8 @@ stlink-usb.h test_sg.c test_usb.c + uglylogging.c + uglylogging.h @@ -153,9 +155,11 @@ ${MAKE} -f Makefile clean gdbserver/st-util + + . + - CONFIG_USE_LIBSG=1 - CONFIG_USE_LIBUSB=1 + DEBUG=1 @@ -473,6 +477,351 @@ src + + CONFIG_USE_LIBSG=1 + CONFIG_USE_LIBUSB=1 + + + + + + + + + + + + + + + LOCAL_SOURCES + default + + + + gdbserver + ${MAKE} -f Makefile + ${MAKE} -f Makefile clean + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + src + + + CONFIG_USE_LIBSG=1 + CONFIG_USE_LIBUSB=1 + @@ -487,8 +836,6 @@ - - diff --git a/nbproject/project.xml b/nbproject/project.xml index cd5248661..580df1074 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -17,6 +17,10 @@ Default 0 + + gdbserver + 0 + From b463d50c5b34935334b26a48903c68c3893b1ff2 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 4 Nov 2011 01:56:22 +0000 Subject: [PATCH 0034/1435] Update documentation removing all sg-utils notes Just libusb now. Verified the modprobe.conf on Ubuntu 10.04 --- 10-stlink.rules | 43 ----------------------------------- README | 50 +++++++++++++++++++++++++++++++---------- TODO | 3 --- src/stlink-sg.c | 24 ++++++++++++-------- stlink.modprobe.conf | 1 - stlink_v1.modprobe.conf | 1 + 6 files changed, 54 insertions(+), 68 deletions(-) delete mode 100644 10-stlink.rules delete mode 100644 stlink.modprobe.conf create mode 100644 stlink_v1.modprobe.conf diff --git a/10-stlink.rules b/10-stlink.rules deleted file mode 100644 index 2413acd8e..000000000 --- a/10-stlink.rules +++ /dev/null @@ -1,43 +0,0 @@ -# This file was taken from arm-utilites project, located at -# http://code.google.com/p/arm-utilities/, which is licensed under GPL3. -# An explicit permission to include any code from that project in -# this one under BSD license was granted by arm-utilites author, Donald Becker. - -# This file watches for a STMicro ST-Link or STM32VLDiscovery board -# and creates a device named /dev/stlink -# See udev(7) for syntax. -# -# Written 2010,2011 by Donald Becker -# -# The STLink on the Discovery has a USB ID 0483:3744 and presents itself -# as a mass storage (i.e. SCSI) device. The SCSI emulation is signficantly -# broken, and the kernel spews error reports for a while until it is -# accepted. Further problems are encountered when if it is automatically -# mounted. -# -# Options that may prevent the mount are -# ENV{UDISKS_PRESENTATION_HIDE}:="1", -# ENV{UDISKS_PRESENTATION_NOPOLICY}:="1", -# ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}:="1" - -ACTION!="add|change", GOTO="stlink_rules_end" - -SUBSYSTEMS=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="3744", \ - MODE="0664", GROUP="tape", NAME="stlinkusb%n", ENV{STLINK}="1", \ - ENV{UDISKS_PRESENTATION_HIDE}:="1", \ - ENV{UDISKS_PRESENTATION_NOPOLICY}:="1", \ - ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}:="1", \ - OPTIONS="last_rule" - -# Other possible settings: -# OPTIONS="last_rule", ATTRS{vendor}=="STM32" - -KERNEL=="sg[0-9]*", MODE="0664", GROUP:="tape", \ - NAME+="stlink-sg%n", SYMLINK+="stlink", \ - ENV{UDISKS_PRESENTATION_HIDE}:="1", \ - ENV{UDISKS_PRESENTATION_NOPOLICY}:="1", \ - ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}:="1" - -SUBSYSTEM=="scsi", ATTR{vendor}=="STM32", MODE="0664", GROUP="tape", NAME="stlinksg-scsi%n", SYMLINK+="stlinkscsi", OPTIONS="last_rule" - -LABEL="stlink_rules_end" diff --git a/README b/README index 429b8511f..109aa2500 100644 --- a/README +++ b/README @@ -11,22 +11,47 @@ called stlink and there are 2 versions: . STLINKv1 uses SCSI passthru commands over USB, . STLINKv2 uses raw USB commands. -It means that if you are using a STM32VL board, you have to install and load -SCSI related software. First, load the sg kernel module: -# modprobe sg +Common requirements +~~~~~~~~~~~~~~~~~~~ -Then, you need to install the package libsgutils2-dev. On Ubuntu: -# sudo apt-get install libsgutils2-dev +libusb-1.0 (You probably already have this, but you'll need the +development version to compile) -LIBUSB is required for both cases. +IF YOU HAVE AN STLINKv1 +~~~~~~~~~~~~~~~~~~~~~~~ +The STLINKv1's SCSI emulation is very broken, so the best thing to do +is tell your operating system to completely ignore it. + +Options (do one of these before you plug it in) + *) modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i +or *)1. add "options usb-storage quirks=483:3744:i" to /etc/modprobe.conf + *)2. modprobe -r usb-storage && modprobe usb-storage +or *)1. cp stlink_v1.modprobe.conf /etc/modprobe.d + *)2. modprobe -r usb-storage && modprobe usb-storage + +IF YOU HAVE AN STLINKv2 +~~~~~~~~~~~~~~~~~~~~~~~ + +You're ready to go :) To run the gdb server, do (you do not need sudo if you have set up permissions correctly): -$ make -C build && sudo ./build/st-util [/dev/sgX] +$ make && [sudo] ./gdbserver/st-util + +There are a few options: + +./gdbserver/st-util - usage: -Currently, the GDB server listening port is hardcoded to 4242: + -h, --help Print this help + -vXX, --verbose=XX specify a specific verbosity level (0..99) + -v, --verbose specify generally verbose logging + -s X, --stlink_version=X + Choose what version of stlink to use, (defaults to 2) + -1, --stlinkv1 Force stlink version 1 + -p 4242, --listen_port=1234 + Set the gdb server listen port. (default port: 4242) -Then, in gdb: +Then, in gdb: (remember, you need to run an _ARM_ gdb, not an x86 gdb) (gdb) target remote :4242 Have fun! @@ -50,13 +75,14 @@ for GDB. Setting up udev rules ===================== -For convenience, you may install udev rules file, 10-stlink.rules, located +For convenience, you may install udev rules file, 49-stlinkv2.rules, located in the root of repository. You will need to copy it to /etc/udev/rules.d, and then either reboot or execute $ udevadm control --reload-rules -Udev will now create a /dev/stlink file, which will point at appropriate -/dev/sgX device. Good to not accidentally start debugging your flash drive. +Udev will now create a /dev/stlinkv2_XX file, with the appropriate permissions. +This is currently all the device is for, (only one stlinkv2 is supported at +any time presently) Running programs from SRAM ========================== diff --git a/TODO b/TODO index e3795fc32..e415e57b8 100644 --- a/TODO +++ b/TODO @@ -7,9 +7,6 @@ . 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=chibios:articles:stm32l_discovery svn checkout https://chibios.svn.sourceforge.net/svnroot/chibios/trunk ; diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 276986ef7..2bbbaf9d9 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -12,7 +12,6 @@ The stlink related constants kindly provided by Oliver Spencer (OpenOCD) for use in a GPL compatible license. - Code format ~ TAB = 8, K&R, linux kernel source, golang oriented Tested compatibility: linux, gcc >= 4.3.3 The communication is based on standard USB mass storage device @@ -31,10 +30,18 @@ CBW - Command Block Wrapper CSW - Command Status Wrapper RFU - Reserved for Future Use - scsi_pt - SCSI pass-through - sg - SCSI generic - * usb-storage.quirks + Originally, this driver used scsi pass through commands, which required the + usb-storage module to be loaded, providing the /dev/sgX links. The USB mass + storage implementation on the STLinkv1 is however terribly broken, and it can + take many minutes for the kernel to give up. + + However, in Nov 2011, the scsi pass through was replaced by raw libusb, so + instead of having to let usb-storage struggle with the device, and also greatly + limiting the portability of the driver, you can now tell usb-storage to simply + ignore this device completely. + + usb-storage.quirks http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob_plain;f=Documentation/kernel-parameters.txt Each entry has the form VID:PID:Flags where VID and PID are Vendor and Product ID values (4-digit hex numbers) and Flags is a set of characters, each corresponding @@ -54,18 +61,17 @@ Example: quirks=0419:aaf5:rl,0421:0433:rc http://permalink.gmane.org/gmane.linux.usb.general/35053 + + For the stlinkv1, you just want the following - modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:l + modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i Equivalently, you can add a line saying - options usb-storage quirks=483:3744:l + options usb-storage quirks=483:3744:i to your /etc/modprobe.conf or /etc/modprobe.d/local.conf (or add the "quirks=..." part to an existing options line for usb-storage). - - https://wiki.kubuntu.org/Kernel/Debugging/USB explains the protocoll and - would allow to replace the sg access to pure libusb access */ diff --git a/stlink.modprobe.conf b/stlink.modprobe.conf deleted file mode 100644 index e918c9006..000000000 --- a/stlink.modprobe.conf +++ /dev/null @@ -1 +0,0 @@ -options usb-storage quirks=483:3744:l diff --git a/stlink_v1.modprobe.conf b/stlink_v1.modprobe.conf new file mode 100644 index 000000000..94b3786ff --- /dev/null +++ b/stlink_v1.modprobe.conf @@ -0,0 +1 @@ +options usb-storage quirks=483:3744:i From 388606716eb050914a5c3af08a8ccf669f1c85a9 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 4 Nov 2011 02:23:17 +0000 Subject: [PATCH 0035/1435] Update tutorial docs and flash writing/reading --- doc/tutorial/tutorial.pdf | Bin 110993 -> 111736 bytes doc/tutorial/tutorial.tex | 49 ++++++++++++++++++-------------------- flash/main.c | 3 +-- 3 files changed, 24 insertions(+), 28 deletions(-) diff --git a/doc/tutorial/tutorial.pdf b/doc/tutorial/tutorial.pdf index 371f805a0f1a4ddc103155c3fecc8c3a3fc972a0..70546cb813a4c8b4f4a6d2ca15587a88e6ad88da 100644 GIT binary patch delta 55709 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

© COPYRIGHT 2010 STMicroelectronics

+ ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f10x + * @{ + */ + +#ifndef __STM32F10x_H +#define __STM32F10x_H + +#ifdef __cplusplus + extern "C" { +#endif + +#define assert_param(__p) + + +/** @addtogroup Library_configuration_section + * @{ + */ + +/* Uncomment the line below according to the target STM32 device used in your + application + */ + +#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL) + /* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */ + /* #define STM32F10X_LD_VL */ /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */ + /* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */ + /* #define STM32F10X_MD_VL */ /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */ + /* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */ + #define STM32F10X_XL /*!< STM32F10X_XL: STM32 XL-density devices */ + /* #define STM32F10X_CL */ /*!< STM32F10X_CL: STM32 Connectivity line devices */ +#endif +/* Tip: To avoid modifying this file each time you need to switch between these + devices, you can define the device in your toolchain compiler preprocessor. + + - Low density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers + where the Flash memory density ranges between 16 and 32 Kbytes. + - Low-density value line devices are STM32F100xx microcontrollers where the Flash + memory density ranges between 16 and 32 Kbytes. + - Medium density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers + where the Flash memory density ranges between 64 and 128 Kbytes. + - Medium-density value line devices are STM32F100xx microcontrollers where the + Flash memory density ranges between 64 and 128 Kbytes. + - High density devices are STM32F101xx and STM32F103xx microcontrollers where + the Flash memory density ranges between 256 and 512 Kbytes. + - XL-density devices are STM32F101xx and STM32F103xx microcontrollers where + the Flash memory density ranges between 512 and 1024 Kbytes. + - Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers. + */ + +#if !defined USE_STDPERIPH_DRIVER +/** + * @brief Comment the line below if you will not use the peripherals drivers. + In this case, these drivers will not be included and the application code will + be based on direct access to peripherals registers + */ + /*#define USE_STDPERIPH_DRIVER*/ +#endif + +/** + * @brief In the following line adjust the value of External High Speed oscillator (HSE) + used in your application + + Tip: To avoid modifying this file each time you need to use different HSE, you + can define the HSE value in your toolchain compiler preprocessor. + */ +#if !defined HSE_VALUE + #ifdef STM32F10X_CL + #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ + #else + #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ + #endif /* STM32F10X_CL */ +#endif /* HSE_VALUE */ + + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + Timeout value + */ +#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */ + +#define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/ + +/** + * @brief STM32F10x Standard Peripheral Library version number + */ +#define __STM32F10X_STDPERIPH_VERSION_MAIN (0x03) /*!< [31:16] STM32F10x Standard Peripheral Library main version */ +#define __STM32F10X_STDPERIPH_VERSION_SUB1 (0x03) /*!< [15:8] STM32F10x Standard Peripheral Library sub1 version */ +#define __STM32F10X_STDPERIPH_VERSION_SUB2 (0x00) /*!< [7:0] STM32F10x Standard Peripheral Library sub2 version */ +#define __STM32F10X_STDPERIPH_VERSION ((__STM32F10X_STDPERIPH_VERSION_MAIN << 16)\ + | (__STM32F10X_STDPERIPH_VERSION_SUB1 << 8)\ + | __STM32F10X_STDPERIPH_VERSION_SUB2) + +/** + * @} + */ + +/** @addtogroup Configuration_section_for_CMSIS + * @{ + */ + +/** + * @brief Configuration of the Cortex-M3 Processor and Core Peripherals + */ +#ifdef STM32F10X_XL + #define __MPU_PRESENT 1 /*!< STM32 XL-density devices provide an MPU */ +#else + #define __MPU_PRESENT 0 /*!< Other STM32 devices does not provide an MPU */ +#endif /* STM32F10X_XL */ +#define __NVIC_PRIO_BITS 4 /*!< STM32 uses 4 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * @brief STM32F10x Interrupt Number Definition, according to the selected device + * in @ref Library_configuration_section + */ +typedef enum IRQn +{ +/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */ + +/****** STM32 specific Interrupt Numbers *********************************************************/ + WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ + PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ + TAMPER_IRQn = 2, /*!< Tamper Interrupt */ + RTC_IRQn = 3, /*!< RTC global Interrupt */ + FLASH_IRQn = 4, /*!< FLASH global Interrupt */ + RCC_IRQn = 5, /*!< RCC global Interrupt */ + EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ + EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ + EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ + EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ + EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ + DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */ + DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */ + DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */ + DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */ + DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */ + DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */ + DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */ + +#ifdef STM32F10X_LD + ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */ + USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ + USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ + TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ + TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ +#endif /* STM32F10X_LD */ + +#ifdef STM32F10X_LD_VL + ADC1_IRQn = 18, /*!< ADC1 global Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_TIM15_IRQn = 24, /*!< TIM1 Break and TIM15 Interrupts */ + TIM1_UP_TIM16_IRQn = 25, /*!< TIM1 Update and TIM16 Interrupts */ + TIM1_TRG_COM_TIM17_IRQn = 26, /*!< TIM1 Trigger and Commutation and TIM17 Interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */ + TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */ + TIM7_IRQn = 55 /*!< TIM7 Interrupt */ +#endif /* STM32F10X_LD_VL */ + +#ifdef STM32F10X_MD + ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */ + USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ + USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ + TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ + TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ +#endif /* STM32F10X_MD */ + +#ifdef STM32F10X_MD_VL + ADC1_IRQn = 18, /*!< ADC1 global Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_TIM15_IRQn = 24, /*!< TIM1 Break and TIM15 Interrupts */ + TIM1_UP_TIM16_IRQn = 25, /*!< TIM1 Update and TIM16 Interrupts */ + TIM1_TRG_COM_TIM17_IRQn = 26, /*!< TIM1 Trigger and Commutation and TIM17 Interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */ + TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */ + TIM7_IRQn = 55 /*!< TIM7 Interrupt */ +#endif /* STM32F10X_MD_VL */ + +#ifdef STM32F10X_HD + ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */ + USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ + USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ + TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ + TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ + TIM8_BRK_IRQn = 43, /*!< TIM8 Break Interrupt */ + TIM8_UP_IRQn = 44, /*!< TIM8 Update Interrupt */ + TIM8_TRG_COM_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt */ + TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ + ADC3_IRQn = 47, /*!< ADC3 global Interrupt */ + FSMC_IRQn = 48, /*!< FSMC global Interrupt */ + SDIO_IRQn = 49, /*!< SDIO global Interrupt */ + TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ + UART4_IRQn = 52, /*!< UART4 global Interrupt */ + UART5_IRQn = 53, /*!< UART5 global Interrupt */ + TIM6_IRQn = 54, /*!< TIM6 global Interrupt */ + TIM7_IRQn = 55, /*!< TIM7 global Interrupt */ + DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */ + DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */ + DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */ + DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */ +#endif /* STM32F10X_HD */ + +#ifdef STM32F10X_XL + ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */ + USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ + USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break Interrupt and TIM9 global Interrupt */ + TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global Interrupt */ + TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ + TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global Interrupt */ + TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global Interrupt */ + TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ + TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ + ADC3_IRQn = 47, /*!< ADC3 global Interrupt */ + FSMC_IRQn = 48, /*!< FSMC global Interrupt */ + SDIO_IRQn = 49, /*!< SDIO global Interrupt */ + TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ + UART4_IRQn = 52, /*!< UART4 global Interrupt */ + UART5_IRQn = 53, /*!< UART5 global Interrupt */ + TIM6_IRQn = 54, /*!< TIM6 global Interrupt */ + TIM7_IRQn = 55, /*!< TIM7 global Interrupt */ + DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */ + DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */ + DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */ + DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */ +#endif /* STM32F10X_XL */ + +#ifdef STM32F10X_CL + ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */ + CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ + CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ + TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ + TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ + OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS WakeUp from suspend through EXTI Line Interrupt */ + TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ + UART4_IRQn = 52, /*!< UART4 global Interrupt */ + UART5_IRQn = 53, /*!< UART5 global Interrupt */ + TIM6_IRQn = 54, /*!< TIM6 global Interrupt */ + TIM7_IRQn = 55, /*!< TIM7 global Interrupt */ + DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */ + DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */ + DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */ + DMA2_Channel4_IRQn = 59, /*!< DMA2 Channel 4 global Interrupt */ + DMA2_Channel5_IRQn = 60, /*!< DMA2 Channel 5 global Interrupt */ + ETH_IRQn = 61, /*!< Ethernet global Interrupt */ + ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ + CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */ + CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */ + CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */ + CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */ + OTG_FS_IRQn = 67 /*!< USB OTG FS global Interrupt */ +#endif /* STM32F10X_CL */ +} IRQn_Type; + +/** + * @} + */ + +#include "core_cm3.h" +#include "system_stm32f10x.h" +#include + +/** @addtogroup Exported_types + * @{ + */ + +/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */ +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; + +typedef const int32_t sc32; /*!< Read Only */ +typedef const int16_t sc16; /*!< Read Only */ +typedef const int8_t sc8; /*!< Read Only */ + +typedef __IO int32_t vs32; +typedef __IO int16_t vs16; +typedef __IO int8_t vs8; + +typedef __I int32_t vsc32; /*!< Read Only */ +typedef __I int16_t vsc16; /*!< Read Only */ +typedef __I int8_t vsc8; /*!< Read Only */ + +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +typedef const uint32_t uc32; /*!< Read Only */ +typedef const uint16_t uc16; /*!< Read Only */ +typedef const uint8_t uc8; /*!< Read Only */ + +typedef __IO uint32_t vu32; +typedef __IO uint16_t vu16; +typedef __IO uint8_t vu8; + +typedef __I uint32_t vuc32; /*!< Read Only */ +typedef __I uint16_t vuc16; /*!< Read Only */ +typedef __I uint8_t vuc8; /*!< Read Only */ + +#ifndef __cplusplus +typedef enum {FALSE = 0, TRUE = !FALSE} bool; +#endif + +typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; + +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; +#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) + +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; + +/*!< STM32F10x Standard Peripheral Library old definitions (maintained for legacy purpose) */ +#define HSEStartUp_TimeOut HSE_STARTUP_TIMEOUT +#define HSE_Value HSE_VALUE +#define HSI_Value HSI_VALUE +/** + * @} + */ + +/** @addtogroup Peripheral_registers_structures + * @{ + */ + +/** + * @brief Analog to Digital Converter + */ + +typedef struct +{ + __IO uint32_t SR; + __IO uint32_t CR1; + __IO uint32_t CR2; + __IO uint32_t SMPR1; + __IO uint32_t SMPR2; + __IO uint32_t JOFR1; + __IO uint32_t JOFR2; + __IO uint32_t JOFR3; + __IO uint32_t JOFR4; + __IO uint32_t HTR; + __IO uint32_t LTR; + __IO uint32_t SQR1; + __IO uint32_t SQR2; + __IO uint32_t SQR3; + __IO uint32_t JSQR; + __IO uint32_t JDR1; + __IO uint32_t JDR2; + __IO uint32_t JDR3; + __IO uint32_t JDR4; + __IO uint32_t DR; +} ADC_TypeDef; + +/** + * @brief Backup Registers + */ + +typedef struct +{ + uint32_t RESERVED0; + __IO uint16_t DR1; + uint16_t RESERVED1; + __IO uint16_t DR2; + uint16_t RESERVED2; + __IO uint16_t DR3; + uint16_t RESERVED3; + __IO uint16_t DR4; + uint16_t RESERVED4; + __IO uint16_t DR5; + uint16_t RESERVED5; + __IO uint16_t DR6; + uint16_t RESERVED6; + __IO uint16_t DR7; + uint16_t RESERVED7; + __IO uint16_t DR8; + uint16_t RESERVED8; + __IO uint16_t DR9; + uint16_t RESERVED9; + __IO uint16_t DR10; + uint16_t RESERVED10; + __IO uint16_t RTCCR; + uint16_t RESERVED11; + __IO uint16_t CR; + uint16_t RESERVED12; + __IO uint16_t CSR; + uint16_t RESERVED13[5]; + __IO uint16_t DR11; + uint16_t RESERVED14; + __IO uint16_t DR12; + uint16_t RESERVED15; + __IO uint16_t DR13; + uint16_t RESERVED16; + __IO uint16_t DR14; + uint16_t RESERVED17; + __IO uint16_t DR15; + uint16_t RESERVED18; + __IO uint16_t DR16; + uint16_t RESERVED19; + __IO uint16_t DR17; + uint16_t RESERVED20; + __IO uint16_t DR18; + uint16_t RESERVED21; + __IO uint16_t DR19; + uint16_t RESERVED22; + __IO uint16_t DR20; + uint16_t RESERVED23; + __IO uint16_t DR21; + uint16_t RESERVED24; + __IO uint16_t DR22; + uint16_t RESERVED25; + __IO uint16_t DR23; + uint16_t RESERVED26; + __IO uint16_t DR24; + uint16_t RESERVED27; + __IO uint16_t DR25; + uint16_t RESERVED28; + __IO uint16_t DR26; + uint16_t RESERVED29; + __IO uint16_t DR27; + uint16_t RESERVED30; + __IO uint16_t DR28; + uint16_t RESERVED31; + __IO uint16_t DR29; + uint16_t RESERVED32; + __IO uint16_t DR30; + uint16_t RESERVED33; + __IO uint16_t DR31; + uint16_t RESERVED34; + __IO uint16_t DR32; + uint16_t RESERVED35; + __IO uint16_t DR33; + uint16_t RESERVED36; + __IO uint16_t DR34; + uint16_t RESERVED37; + __IO uint16_t DR35; + uint16_t RESERVED38; + __IO uint16_t DR36; + uint16_t RESERVED39; + __IO uint16_t DR37; + uint16_t RESERVED40; + __IO uint16_t DR38; + uint16_t RESERVED41; + __IO uint16_t DR39; + uint16_t RESERVED42; + __IO uint16_t DR40; + uint16_t RESERVED43; + __IO uint16_t DR41; + uint16_t RESERVED44; + __IO uint16_t DR42; + uint16_t RESERVED45; +} BKP_TypeDef; + +/** + * @brief Controller Area Network TxMailBox + */ + +typedef struct +{ + __IO uint32_t TIR; + __IO uint32_t TDTR; + __IO uint32_t TDLR; + __IO uint32_t TDHR; +} CAN_TxMailBox_TypeDef; + +/** + * @brief Controller Area Network FIFOMailBox + */ + +typedef struct +{ + __IO uint32_t RIR; + __IO uint32_t RDTR; + __IO uint32_t RDLR; + __IO uint32_t RDHR; +} CAN_FIFOMailBox_TypeDef; + +/** + * @brief Controller Area Network FilterRegister + */ + +typedef struct +{ + __IO uint32_t FR1; + __IO uint32_t FR2; +} CAN_FilterRegister_TypeDef; + +/** + * @brief Controller Area Network + */ + +typedef struct +{ + __IO uint32_t MCR; + __IO uint32_t MSR; + __IO uint32_t TSR; + __IO uint32_t RF0R; + __IO uint32_t RF1R; + __IO uint32_t IER; + __IO uint32_t ESR; + __IO uint32_t BTR; + uint32_t RESERVED0[88]; + CAN_TxMailBox_TypeDef sTxMailBox[3]; + CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; + uint32_t RESERVED1[12]; + __IO uint32_t FMR; + __IO uint32_t FM1R; + uint32_t RESERVED2; + __IO uint32_t FS1R; + uint32_t RESERVED3; + __IO uint32_t FFA1R; + uint32_t RESERVED4; + __IO uint32_t FA1R; + uint32_t RESERVED5[8]; +#ifndef STM32F10X_CL + CAN_FilterRegister_TypeDef sFilterRegister[14]; +#else + CAN_FilterRegister_TypeDef sFilterRegister[28]; +#endif /* STM32F10X_CL */ +} CAN_TypeDef; + +/** + * @brief Consumer Electronics Control (CEC) + */ +typedef struct +{ + __IO uint32_t CFGR; + __IO uint32_t OAR; + __IO uint32_t PRES; + __IO uint32_t ESR; + __IO uint32_t CSR; + __IO uint32_t TXD; + __IO uint32_t RXD; +} CEC_TypeDef; + +/** + * @brief CRC calculation unit + */ + +typedef struct +{ + __IO uint32_t DR; + __IO uint8_t IDR; + uint8_t RESERVED0; + uint16_t RESERVED1; + __IO uint32_t CR; +} CRC_TypeDef; + +/** + * @brief Digital to Analog Converter + */ + +typedef struct +{ + __IO uint32_t CR; + __IO uint32_t SWTRIGR; + __IO uint32_t DHR12R1; + __IO uint32_t DHR12L1; + __IO uint32_t DHR8R1; + __IO uint32_t DHR12R2; + __IO uint32_t DHR12L2; + __IO uint32_t DHR8R2; + __IO uint32_t DHR12RD; + __IO uint32_t DHR12LD; + __IO uint32_t DHR8RD; + __IO uint32_t DOR1; + __IO uint32_t DOR2; +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) + __IO uint32_t SR; +#endif +} DAC_TypeDef; + +/** + * @brief Debug MCU + */ + +typedef struct +{ + __IO uint32_t IDCODE; + __IO uint32_t CR; +}DBGMCU_TypeDef; + +/** + * @brief DMA Controller + */ + +typedef struct +{ + __IO uint32_t CCR; + __IO uint32_t CNDTR; + __IO uint32_t CPAR; + __IO uint32_t CMAR; +} DMA_Channel_TypeDef; + +typedef struct +{ + __IO uint32_t ISR; + __IO uint32_t IFCR; +} DMA_TypeDef; + +/** + * @brief Ethernet MAC + */ + +typedef struct +{ + __IO uint32_t MACCR; + __IO uint32_t MACFFR; + __IO uint32_t MACHTHR; + __IO uint32_t MACHTLR; + __IO uint32_t MACMIIAR; + __IO uint32_t MACMIIDR; + __IO uint32_t MACFCR; + __IO uint32_t MACVLANTR; /* 8 */ + uint32_t RESERVED0[2]; + __IO uint32_t MACRWUFFR; /* 11 */ + __IO uint32_t MACPMTCSR; + uint32_t RESERVED1[2]; + __IO uint32_t MACSR; /* 15 */ + __IO uint32_t MACIMR; + __IO uint32_t MACA0HR; + __IO uint32_t MACA0LR; + __IO uint32_t MACA1HR; + __IO uint32_t MACA1LR; + __IO uint32_t MACA2HR; + __IO uint32_t MACA2LR; + __IO uint32_t MACA3HR; + __IO uint32_t MACA3LR; /* 24 */ + uint32_t RESERVED2[40]; + __IO uint32_t MMCCR; /* 65 */ + __IO uint32_t MMCRIR; + __IO uint32_t MMCTIR; + __IO uint32_t MMCRIMR; + __IO uint32_t MMCTIMR; /* 69 */ + uint32_t RESERVED3[14]; + __IO uint32_t MMCTGFSCCR; /* 84 */ + __IO uint32_t MMCTGFMSCCR; + uint32_t RESERVED4[5]; + __IO uint32_t MMCTGFCR; + uint32_t RESERVED5[10]; + __IO uint32_t MMCRFCECR; + __IO uint32_t MMCRFAECR; + uint32_t RESERVED6[10]; + __IO uint32_t MMCRGUFCR; + uint32_t RESERVED7[334]; + __IO uint32_t PTPTSCR; + __IO uint32_t PTPSSIR; + __IO uint32_t PTPTSHR; + __IO uint32_t PTPTSLR; + __IO uint32_t PTPTSHUR; + __IO uint32_t PTPTSLUR; + __IO uint32_t PTPTSAR; + __IO uint32_t PTPTTHR; + __IO uint32_t PTPTTLR; + uint32_t RESERVED8[567]; + __IO uint32_t DMABMR; + __IO uint32_t DMATPDR; + __IO uint32_t DMARPDR; + __IO uint32_t DMARDLAR; + __IO uint32_t DMATDLAR; + __IO uint32_t DMASR; + __IO uint32_t DMAOMR; + __IO uint32_t DMAIER; + __IO uint32_t DMAMFBOCR; + uint32_t RESERVED9[9]; + __IO uint32_t DMACHTDR; + __IO uint32_t DMACHRDR; + __IO uint32_t DMACHTBAR; + __IO uint32_t DMACHRBAR; +} ETH_TypeDef; + +/** + * @brief External Interrupt/Event Controller + */ + +typedef struct +{ + __IO uint32_t IMR; + __IO uint32_t EMR; + __IO uint32_t RTSR; + __IO uint32_t FTSR; + __IO uint32_t SWIER; + __IO uint32_t PR; +} EXTI_TypeDef; + +/** + * @brief FLASH Registers + */ + +typedef struct +{ + __IO uint32_t ACR; + __IO uint32_t KEYR; + __IO uint32_t OPTKEYR; + __IO uint32_t SR; + __IO uint32_t CR; + __IO uint32_t AR; + __IO uint32_t RESERVED; + __IO uint32_t OBR; + __IO uint32_t WRPR; +#ifdef STM32F10X_XL + uint32_t RESERVED1[8]; + __IO uint32_t KEYR2; + uint32_t RESERVED2; + __IO uint32_t SR2; + __IO uint32_t CR2; + __IO uint32_t AR2; +#endif /* STM32F10X_XL */ +} FLASH_TypeDef; + +/** + * @brief Option Bytes Registers + */ + +typedef struct +{ + __IO uint16_t RDP; + __IO uint16_t USER; + __IO uint16_t Data0; + __IO uint16_t Data1; + __IO uint16_t WRP0; + __IO uint16_t WRP1; + __IO uint16_t WRP2; + __IO uint16_t WRP3; +} OB_TypeDef; + +/** + * @brief Flexible Static Memory Controller + */ + +typedef struct +{ + __IO uint32_t BTCR[8]; +} FSMC_Bank1_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank1E + */ + +typedef struct +{ + __IO uint32_t BWTR[7]; +} FSMC_Bank1E_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank2 + */ + +typedef struct +{ + __IO uint32_t PCR2; + __IO uint32_t SR2; + __IO uint32_t PMEM2; + __IO uint32_t PATT2; + uint32_t RESERVED0; + __IO uint32_t ECCR2; +} FSMC_Bank2_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank3 + */ + +typedef struct +{ + __IO uint32_t PCR3; + __IO uint32_t SR3; + __IO uint32_t PMEM3; + __IO uint32_t PATT3; + uint32_t RESERVED0; + __IO uint32_t ECCR3; +} FSMC_Bank3_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank4 + */ + +typedef struct +{ + __IO uint32_t PCR4; + __IO uint32_t SR4; + __IO uint32_t PMEM4; + __IO uint32_t PATT4; + __IO uint32_t PIO4; +} FSMC_Bank4_TypeDef; + +/** + * @brief General Purpose I/O + */ + +typedef struct +{ + __IO uint32_t CRL; + __IO uint32_t CRH; + __IO uint32_t IDR; + __IO uint32_t ODR; + __IO uint32_t BSRR; + __IO uint32_t BRR; + __IO uint32_t LCKR; +} GPIO_TypeDef; + +/** + * @brief Alternate Function I/O + */ + +typedef struct +{ + __IO uint32_t EVCR; + __IO uint32_t MAPR; + __IO uint32_t EXTICR[4]; + uint32_t RESERVED0; + __IO uint32_t MAPR2; +} AFIO_TypeDef; +/** + * @brief Inter-integrated Circuit Interface + */ + +typedef struct +{ + __IO uint16_t CR1; + uint16_t RESERVED0; + __IO uint16_t CR2; + uint16_t RESERVED1; + __IO uint16_t OAR1; + uint16_t RESERVED2; + __IO uint16_t OAR2; + uint16_t RESERVED3; + __IO uint16_t DR; + uint16_t RESERVED4; + __IO uint16_t SR1; + uint16_t RESERVED5; + __IO uint16_t SR2; + uint16_t RESERVED6; + __IO uint16_t CCR; + uint16_t RESERVED7; + __IO uint16_t TRISE; + uint16_t RESERVED8; +} I2C_TypeDef; + +/** + * @brief Independent WATCHDOG + */ + +typedef struct +{ + __IO uint32_t KR; + __IO uint32_t PR; + __IO uint32_t RLR; + __IO uint32_t SR; +} IWDG_TypeDef; + +/** + * @brief Power Control + */ + +typedef struct +{ + __IO uint32_t CR; + __IO uint32_t CSR; +} PWR_TypeDef; + +/** + * @brief Reset and Clock Control + */ + +typedef struct +{ + __IO uint32_t CR; + __IO uint32_t CFGR; + __IO uint32_t CIR; + __IO uint32_t APB2RSTR; + __IO uint32_t APB1RSTR; + __IO uint32_t AHBENR; + __IO uint32_t APB2ENR; + __IO uint32_t APB1ENR; + __IO uint32_t BDCR; + __IO uint32_t CSR; + +#ifdef STM32F10X_CL + __IO uint32_t AHBRSTR; + __IO uint32_t CFGR2; +#endif /* STM32F10X_CL */ + +#if defined STM32F10X_LD_VL || defined STM32F10X_MD_VL + uint32_t RESERVED0; + __IO uint32_t CFGR2; +#endif /* STM32F10X_LD_VL || STM32F10X_MD_VL */ +} RCC_TypeDef; + +/** + * @brief Real-Time Clock + */ + +typedef struct +{ + __IO uint16_t CRH; + uint16_t RESERVED0; + __IO uint16_t CRL; + uint16_t RESERVED1; + __IO uint16_t PRLH; + uint16_t RESERVED2; + __IO uint16_t PRLL; + uint16_t RESERVED3; + __IO uint16_t DIVH; + uint16_t RESERVED4; + __IO uint16_t DIVL; + uint16_t RESERVED5; + __IO uint16_t CNTH; + uint16_t RESERVED6; + __IO uint16_t CNTL; + uint16_t RESERVED7; + __IO uint16_t ALRH; + uint16_t RESERVED8; + __IO uint16_t ALRL; + uint16_t RESERVED9; +} RTC_TypeDef; + +/** + * @brief SD host Interface + */ + +typedef struct +{ + __IO uint32_t POWER; + __IO uint32_t CLKCR; + __IO uint32_t ARG; + __IO uint32_t CMD; + __I uint32_t RESPCMD; + __I uint32_t RESP1; + __I uint32_t RESP2; + __I uint32_t RESP3; + __I uint32_t RESP4; + __IO uint32_t DTIMER; + __IO uint32_t DLEN; + __IO uint32_t DCTRL; + __I uint32_t DCOUNT; + __I uint32_t STA; + __IO uint32_t ICR; + __IO uint32_t MASK; + uint32_t RESERVED0[2]; + __I uint32_t FIFOCNT; + uint32_t RESERVED1[13]; + __IO uint32_t FIFO; +} SDIO_TypeDef; + +/** + * @brief Serial Peripheral Interface + */ + +typedef struct +{ + __IO uint16_t CR1; + uint16_t RESERVED0; + __IO uint16_t CR2; + uint16_t RESERVED1; + __IO uint16_t SR; + uint16_t RESERVED2; + __IO uint16_t DR; + uint16_t RESERVED3; + __IO uint16_t CRCPR; + uint16_t RESERVED4; + __IO uint16_t RXCRCR; + uint16_t RESERVED5; + __IO uint16_t TXCRCR; + uint16_t RESERVED6; + __IO uint16_t I2SCFGR; + uint16_t RESERVED7; + __IO uint16_t I2SPR; + uint16_t RESERVED8; +} SPI_TypeDef; + +/** + * @brief TIM + */ + +typedef struct +{ + __IO uint16_t CR1; + uint16_t RESERVED0; + __IO uint16_t CR2; + uint16_t RESERVED1; + __IO uint16_t SMCR; + uint16_t RESERVED2; + __IO uint16_t DIER; + uint16_t RESERVED3; + __IO uint16_t SR; + uint16_t RESERVED4; + __IO uint16_t EGR; + uint16_t RESERVED5; + __IO uint16_t CCMR1; + uint16_t RESERVED6; + __IO uint16_t CCMR2; + uint16_t RESERVED7; + __IO uint16_t CCER; + uint16_t RESERVED8; + __IO uint16_t CNT; + uint16_t RESERVED9; + __IO uint16_t PSC; + uint16_t RESERVED10; + __IO uint16_t ARR; + uint16_t RESERVED11; + __IO uint16_t RCR; + uint16_t RESERVED12; + __IO uint16_t CCR1; + uint16_t RESERVED13; + __IO uint16_t CCR2; + uint16_t RESERVED14; + __IO uint16_t CCR3; + uint16_t RESERVED15; + __IO uint16_t CCR4; + uint16_t RESERVED16; + __IO uint16_t BDTR; + uint16_t RESERVED17; + __IO uint16_t DCR; + uint16_t RESERVED18; + __IO uint16_t DMAR; + uint16_t RESERVED19; +} TIM_TypeDef; + +/** + * @brief Universal Synchronous Asynchronous Receiver Transmitter + */ + +typedef struct +{ + __IO uint16_t SR; + uint16_t RESERVED0; + __IO uint16_t DR; + uint16_t RESERVED1; + __IO uint16_t BRR; + uint16_t RESERVED2; + __IO uint16_t CR1; + uint16_t RESERVED3; + __IO uint16_t CR2; + uint16_t RESERVED4; + __IO uint16_t CR3; + uint16_t RESERVED5; + __IO uint16_t GTPR; + uint16_t RESERVED6; +} USART_TypeDef; + +/** + * @brief Window WATCHDOG + */ + +typedef struct +{ + __IO uint32_t CR; + __IO uint32_t CFR; + __IO uint32_t SR; +} WWDG_TypeDef; + +/** + * @} + */ + +/** @addtogroup Peripheral_memory_map + * @{ + */ + +#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the alias region */ +#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the alias region */ + +#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM base address in the bit-band region */ +#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the bit-band region */ + +#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */ + +/*!< Peripheral memory map */ +#define APB1PERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) + +#define TIM2_BASE (APB1PERIPH_BASE + 0x0000) +#define TIM3_BASE (APB1PERIPH_BASE + 0x0400) +#define TIM4_BASE (APB1PERIPH_BASE + 0x0800) +#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00) +#define TIM6_BASE (APB1PERIPH_BASE + 0x1000) +#define TIM7_BASE (APB1PERIPH_BASE + 0x1400) +#define TIM12_BASE (APB1PERIPH_BASE + 0x1800) +#define TIM13_BASE (APB1PERIPH_BASE + 0x1C00) +#define TIM14_BASE (APB1PERIPH_BASE + 0x2000) +#define RTC_BASE (APB1PERIPH_BASE + 0x2800) +#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00) +#define IWDG_BASE (APB1PERIPH_BASE + 0x3000) +#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) +#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) +#define USART2_BASE (APB1PERIPH_BASE + 0x4400) +#define USART3_BASE (APB1PERIPH_BASE + 0x4800) +#define UART4_BASE (APB1PERIPH_BASE + 0x4C00) +#define UART5_BASE (APB1PERIPH_BASE + 0x5000) +#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) +#define CAN1_BASE (APB1PERIPH_BASE + 0x6400) +#define CAN2_BASE (APB1PERIPH_BASE + 0x6800) +#define BKP_BASE (APB1PERIPH_BASE + 0x6C00) +#define PWR_BASE (APB1PERIPH_BASE + 0x7000) +#define DAC_BASE (APB1PERIPH_BASE + 0x7400) +#define CEC_BASE (APB1PERIPH_BASE + 0x7800) + +#define AFIO_BASE (APB2PERIPH_BASE + 0x0000) +#define EXTI_BASE (APB2PERIPH_BASE + 0x0400) +#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) +#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) +#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) +#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) +#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) +#define GPIOF_BASE (APB2PERIPH_BASE + 0x1C00) +#define GPIOG_BASE (APB2PERIPH_BASE + 0x2000) +#define ADC1_BASE (APB2PERIPH_BASE + 0x2400) +#define ADC2_BASE (APB2PERIPH_BASE + 0x2800) +#define TIM1_BASE (APB2PERIPH_BASE + 0x2C00) +#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) +#define TIM8_BASE (APB2PERIPH_BASE + 0x3400) +#define USART1_BASE (APB2PERIPH_BASE + 0x3800) +#define ADC3_BASE (APB2PERIPH_BASE + 0x3C00) +#define TIM15_BASE (APB2PERIPH_BASE + 0x4000) +#define TIM16_BASE (APB2PERIPH_BASE + 0x4400) +#define TIM17_BASE (APB2PERIPH_BASE + 0x4800) +#define TIM9_BASE (APB2PERIPH_BASE + 0x4C00) +#define TIM10_BASE (APB2PERIPH_BASE + 0x5000) +#define TIM11_BASE (APB2PERIPH_BASE + 0x5400) + +#define SDIO_BASE (PERIPH_BASE + 0x18000) + +#define DMA1_BASE (AHBPERIPH_BASE + 0x0000) +#define DMA1_Channel1_BASE (AHBPERIPH_BASE + 0x0008) +#define DMA1_Channel2_BASE (AHBPERIPH_BASE + 0x001C) +#define DMA1_Channel3_BASE (AHBPERIPH_BASE + 0x0030) +#define DMA1_Channel4_BASE (AHBPERIPH_BASE + 0x0044) +#define DMA1_Channel5_BASE (AHBPERIPH_BASE + 0x0058) +#define DMA1_Channel6_BASE (AHBPERIPH_BASE + 0x006C) +#define DMA1_Channel7_BASE (AHBPERIPH_BASE + 0x0080) +#define DMA2_BASE (AHBPERIPH_BASE + 0x0400) +#define DMA2_Channel1_BASE (AHBPERIPH_BASE + 0x0408) +#define DMA2_Channel2_BASE (AHBPERIPH_BASE + 0x041C) +#define DMA2_Channel3_BASE (AHBPERIPH_BASE + 0x0430) +#define DMA2_Channel4_BASE (AHBPERIPH_BASE + 0x0444) +#define DMA2_Channel5_BASE (AHBPERIPH_BASE + 0x0458) +#define RCC_BASE (AHBPERIPH_BASE + 0x1000) +#define CRC_BASE (AHBPERIPH_BASE + 0x3000) + +#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000) /*!< Flash registers base address */ +#define OB_BASE ((uint32_t)0x1FFFF800) /*!< Flash Option Bytes base address */ + +#define ETH_BASE (AHBPERIPH_BASE + 0x8000) +#define ETH_MAC_BASE (ETH_BASE) +#define ETH_MMC_BASE (ETH_BASE + 0x0100) +#define ETH_PTP_BASE (ETH_BASE + 0x0700) +#define ETH_DMA_BASE (ETH_BASE + 0x1000) + +#define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) /*!< FSMC Bank1 registers base address */ +#define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) /*!< FSMC Bank1E registers base address */ +#define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060) /*!< FSMC Bank2 registers base address */ +#define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080) /*!< FSMC Bank3 registers base address */ +#define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0) /*!< FSMC Bank4 registers base address */ + +#define DBGMCU_BASE ((uint32_t)0xE0042000) /*!< Debug MCU registers base address */ + +/** + * @} + */ + +/** @addtogroup Peripheral_declaration + * @{ + */ + +#define TIM2 ((TIM_TypeDef *) TIM2_BASE) +#define TIM3 ((TIM_TypeDef *) TIM3_BASE) +#define TIM4 ((TIM_TypeDef *) TIM4_BASE) +#define TIM5 ((TIM_TypeDef *) TIM5_BASE) +#define TIM6 ((TIM_TypeDef *) TIM6_BASE) +#define TIM7 ((TIM_TypeDef *) TIM7_BASE) +#define TIM12 ((TIM_TypeDef *) TIM12_BASE) +#define TIM13 ((TIM_TypeDef *) TIM13_BASE) +#define TIM14 ((TIM_TypeDef *) TIM14_BASE) +#define RTC ((RTC_TypeDef *) RTC_BASE) +#define WWDG ((WWDG_TypeDef *) WWDG_BASE) +#define IWDG ((IWDG_TypeDef *) IWDG_BASE) +#define SPI2 ((SPI_TypeDef *) SPI2_BASE) +#define SPI3 ((SPI_TypeDef *) SPI3_BASE) +#define USART2 ((USART_TypeDef *) USART2_BASE) +#define USART3 ((USART_TypeDef *) USART3_BASE) +#define UART4 ((USART_TypeDef *) UART4_BASE) +#define UART5 ((USART_TypeDef *) UART5_BASE) +#define I2C1 ((I2C_TypeDef *) I2C1_BASE) +#define I2C2 ((I2C_TypeDef *) I2C2_BASE) +#define CAN1 ((CAN_TypeDef *) CAN1_BASE) +#define CAN2 ((CAN_TypeDef *) CAN2_BASE) +#define BKP ((BKP_TypeDef *) BKP_BASE) +#define PWR ((PWR_TypeDef *) PWR_BASE) +#define DAC ((DAC_TypeDef *) DAC_BASE) +#define CEC ((CEC_TypeDef *) CEC_BASE) +#define AFIO ((AFIO_TypeDef *) AFIO_BASE) +#define EXTI ((EXTI_TypeDef *) EXTI_BASE) +#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) +#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) +#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) +#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) +#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) +#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) +#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE) +#define ADC1 ((ADC_TypeDef *) ADC1_BASE) +#define ADC2 ((ADC_TypeDef *) ADC2_BASE) +#define TIM1 ((TIM_TypeDef *) TIM1_BASE) +#define SPI1 ((SPI_TypeDef *) SPI1_BASE) +#define TIM8 ((TIM_TypeDef *) TIM8_BASE) +#define USART1 ((USART_TypeDef *) USART1_BASE) +#define ADC3 ((ADC_TypeDef *) ADC3_BASE) +#define TIM15 ((TIM_TypeDef *) TIM15_BASE) +#define TIM16 ((TIM_TypeDef *) TIM16_BASE) +#define TIM17 ((TIM_TypeDef *) TIM17_BASE) +#define TIM9 ((TIM_TypeDef *) TIM9_BASE) +#define TIM10 ((TIM_TypeDef *) TIM10_BASE) +#define TIM11 ((TIM_TypeDef *) TIM11_BASE) +#define SDIO ((SDIO_TypeDef *) SDIO_BASE) +#define DMA1 ((DMA_TypeDef *) DMA1_BASE) +#define DMA2 ((DMA_TypeDef *) DMA2_BASE) +#define DMA1_Channel1 ((DMA_Channel_TypeDef *) DMA1_Channel1_BASE) +#define DMA1_Channel2 ((DMA_Channel_TypeDef *) DMA1_Channel2_BASE) +#define DMA1_Channel3 ((DMA_Channel_TypeDef *) DMA1_Channel3_BASE) +#define DMA1_Channel4 ((DMA_Channel_TypeDef *) DMA1_Channel4_BASE) +#define DMA1_Channel5 ((DMA_Channel_TypeDef *) DMA1_Channel5_BASE) +#define DMA1_Channel6 ((DMA_Channel_TypeDef *) DMA1_Channel6_BASE) +#define DMA1_Channel7 ((DMA_Channel_TypeDef *) DMA1_Channel7_BASE) +#define DMA2_Channel1 ((DMA_Channel_TypeDef *) DMA2_Channel1_BASE) +#define DMA2_Channel2 ((DMA_Channel_TypeDef *) DMA2_Channel2_BASE) +#define DMA2_Channel3 ((DMA_Channel_TypeDef *) DMA2_Channel3_BASE) +#define DMA2_Channel4 ((DMA_Channel_TypeDef *) DMA2_Channel4_BASE) +#define DMA2_Channel5 ((DMA_Channel_TypeDef *) DMA2_Channel5_BASE) +#define RCC ((RCC_TypeDef *) RCC_BASE) +#define CRC ((CRC_TypeDef *) CRC_BASE) +#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) +#define OB ((OB_TypeDef *) OB_BASE) +#define ETH ((ETH_TypeDef *) ETH_BASE) +#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE) +#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE) +#define FSMC_Bank2 ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE) +#define FSMC_Bank3 ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE) +#define FSMC_Bank4 ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE) +#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) + +/** + * @} + */ + +/** @addtogroup Exported_constants + * @{ + */ + + /** @addtogroup Peripheral_Registers_Bits_Definition + * @{ + */ + +/******************************************************************************/ +/* Peripheral Registers_Bits_Definition */ +/******************************************************************************/ + +/******************************************************************************/ +/* */ +/* CRC calculation unit */ +/* */ +/******************************************************************************/ + +/******************* Bit definition for CRC_DR register *********************/ +#define CRC_DR_DR ((uint32_t)0xFFFFFFFF) /*!< Data register bits */ + + +/******************* Bit definition for CRC_IDR register ********************/ +#define CRC_IDR_IDR ((uint8_t)0xFF) /*!< General-purpose 8-bit data register bits */ + + +/******************** Bit definition for CRC_CR register ********************/ +#define CRC_CR_RESET ((uint8_t)0x01) /*!< RESET bit */ + +/******************************************************************************/ +/* */ +/* Power Control */ +/* */ +/******************************************************************************/ + +/******************** Bit definition for PWR_CR register ********************/ +#define PWR_CR_LPDS ((uint16_t)0x0001) /*!< Low-Power Deepsleep */ +#define PWR_CR_PDDS ((uint16_t)0x0002) /*!< Power Down Deepsleep */ +#define PWR_CR_CWUF ((uint16_t)0x0004) /*!< Clear Wakeup Flag */ +#define PWR_CR_CSBF ((uint16_t)0x0008) /*!< Clear Standby Flag */ +#define PWR_CR_PVDE ((uint16_t)0x0010) /*!< Power Voltage Detector Enable */ + +#define PWR_CR_PLS ((uint16_t)0x00E0) /*!< PLS[2:0] bits (PVD Level Selection) */ +#define PWR_CR_PLS_0 ((uint16_t)0x0020) /*!< Bit 0 */ +#define PWR_CR_PLS_1 ((uint16_t)0x0040) /*!< Bit 1 */ +#define PWR_CR_PLS_2 ((uint16_t)0x0080) /*!< Bit 2 */ + +/*!< PVD level configuration */ +#define PWR_CR_PLS_2V2 ((uint16_t)0x0000) /*!< PVD level 2.2V */ +#define PWR_CR_PLS_2V3 ((uint16_t)0x0020) /*!< PVD level 2.3V */ +#define PWR_CR_PLS_2V4 ((uint16_t)0x0040) /*!< PVD level 2.4V */ +#define PWR_CR_PLS_2V5 ((uint16_t)0x0060) /*!< PVD level 2.5V */ +#define PWR_CR_PLS_2V6 ((uint16_t)0x0080) /*!< PVD level 2.6V */ +#define PWR_CR_PLS_2V7 ((uint16_t)0x00A0) /*!< PVD level 2.7V */ +#define PWR_CR_PLS_2V8 ((uint16_t)0x00C0) /*!< PVD level 2.8V */ +#define PWR_CR_PLS_2V9 ((uint16_t)0x00E0) /*!< PVD level 2.9V */ + +#define PWR_CR_DBP ((uint16_t)0x0100) /*!< Disable Backup Domain write protection */ + + +/******************* Bit definition for PWR_CSR register ********************/ +#define PWR_CSR_WUF ((uint16_t)0x0001) /*!< Wakeup Flag */ +#define PWR_CSR_SBF ((uint16_t)0x0002) /*!< Standby Flag */ +#define PWR_CSR_PVDO ((uint16_t)0x0004) /*!< PVD Output */ +#define PWR_CSR_EWUP ((uint16_t)0x0100) /*!< Enable WKUP pin */ + +/******************************************************************************/ +/* */ +/* Backup registers */ +/* */ +/******************************************************************************/ + +/******************* Bit definition for BKP_DR1 register ********************/ +#define BKP_DR1_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR2 register ********************/ +#define BKP_DR2_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR3 register ********************/ +#define BKP_DR3_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR4 register ********************/ +#define BKP_DR4_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR5 register ********************/ +#define BKP_DR5_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR6 register ********************/ +#define BKP_DR6_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR7 register ********************/ +#define BKP_DR7_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR8 register ********************/ +#define BKP_DR8_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR9 register ********************/ +#define BKP_DR9_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR10 register *******************/ +#define BKP_DR10_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR11 register *******************/ +#define BKP_DR11_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR12 register *******************/ +#define BKP_DR12_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR13 register *******************/ +#define BKP_DR13_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR14 register *******************/ +#define BKP_DR14_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR15 register *******************/ +#define BKP_DR15_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR16 register *******************/ +#define BKP_DR16_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR17 register *******************/ +#define BKP_DR17_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/****************** Bit definition for BKP_DR18 register ********************/ +#define BKP_DR18_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR19 register *******************/ +#define BKP_DR19_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR20 register *******************/ +#define BKP_DR20_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR21 register *******************/ +#define BKP_DR21_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR22 register *******************/ +#define BKP_DR22_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR23 register *******************/ +#define BKP_DR23_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR24 register *******************/ +#define BKP_DR24_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR25 register *******************/ +#define BKP_DR25_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR26 register *******************/ +#define BKP_DR26_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR27 register *******************/ +#define BKP_DR27_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR28 register *******************/ +#define BKP_DR28_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR29 register *******************/ +#define BKP_DR29_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR30 register *******************/ +#define BKP_DR30_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR31 register *******************/ +#define BKP_DR31_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR32 register *******************/ +#define BKP_DR32_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR33 register *******************/ +#define BKP_DR33_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR34 register *******************/ +#define BKP_DR34_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR35 register *******************/ +#define BKP_DR35_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR36 register *******************/ +#define BKP_DR36_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR37 register *******************/ +#define BKP_DR37_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR38 register *******************/ +#define BKP_DR38_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR39 register *******************/ +#define BKP_DR39_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR40 register *******************/ +#define BKP_DR40_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR41 register *******************/ +#define BKP_DR41_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/******************* Bit definition for BKP_DR42 register *******************/ +#define BKP_DR42_D ((uint16_t)0xFFFF) /*!< Backup data */ + +/****************** Bit definition for BKP_RTCCR register *******************/ +#define BKP_RTCCR_CAL ((uint16_t)0x007F) /*!< Calibration value */ +#define BKP_RTCCR_CCO ((uint16_t)0x0080) /*!< Calibration Clock Output */ +#define BKP_RTCCR_ASOE ((uint16_t)0x0100) /*!< Alarm or Second Output Enable */ +#define BKP_RTCCR_ASOS ((uint16_t)0x0200) /*!< Alarm or Second Output Selection */ + +/******************** Bit definition for BKP_CR register ********************/ +#define BKP_CR_TPE ((uint8_t)0x01) /*!< TAMPER pin enable */ +#define BKP_CR_TPAL ((uint8_t)0x02) /*!< TAMPER pin active level */ + +/******************* Bit definition for BKP_CSR register ********************/ +#define BKP_CSR_CTE ((uint16_t)0x0001) /*!< Clear Tamper event */ +#define BKP_CSR_CTI ((uint16_t)0x0002) /*!< Clear Tamper Interrupt */ +#define BKP_CSR_TPIE ((uint16_t)0x0004) /*!< TAMPER Pin interrupt enable */ +#define BKP_CSR_TEF ((uint16_t)0x0100) /*!< Tamper Event Flag */ +#define BKP_CSR_TIF ((uint16_t)0x0200) /*!< Tamper Interrupt Flag */ + +/******************************************************************************/ +/* */ +/* Reset and Clock Control */ +/* */ +/******************************************************************************/ + +/******************** Bit definition for RCC_CR register ********************/ +#define RCC_CR_HSION ((uint32_t)0x00000001) /*!< Internal High Speed clock enable */ +#define RCC_CR_HSIRDY ((uint32_t)0x00000002) /*!< Internal High Speed clock ready flag */ +#define RCC_CR_HSITRIM ((uint32_t)0x000000F8) /*!< Internal High Speed clock trimming */ +#define RCC_CR_HSICAL ((uint32_t)0x0000FF00) /*!< Internal High Speed clock Calibration */ +#define RCC_CR_HSEON ((uint32_t)0x00010000) /*!< External High Speed clock enable */ +#define RCC_CR_HSERDY ((uint32_t)0x00020000) /*!< External High Speed clock ready flag */ +#define RCC_CR_HSEBYP ((uint32_t)0x00040000) /*!< External High Speed clock Bypass */ +#define RCC_CR_CSSON ((uint32_t)0x00080000) /*!< Clock Security System enable */ +#define RCC_CR_PLLON ((uint32_t)0x01000000) /*!< PLL enable */ +#define RCC_CR_PLLRDY ((uint32_t)0x02000000) /*!< PLL clock ready flag */ + +#ifdef STM32F10X_CL + #define RCC_CR_PLL2ON ((uint32_t)0x04000000) /*!< PLL2 enable */ + #define RCC_CR_PLL2RDY ((uint32_t)0x08000000) /*!< PLL2 clock ready flag */ + #define RCC_CR_PLL3ON ((uint32_t)0x10000000) /*!< PLL3 enable */ + #define RCC_CR_PLL3RDY ((uint32_t)0x20000000) /*!< PLL3 clock ready flag */ +#endif /* STM32F10X_CL */ + +/******************* Bit definition for RCC_CFGR register *******************/ +/*!< SW configuration */ +#define RCC_CFGR_SW ((uint32_t)0x00000003) /*!< SW[1:0] bits (System clock Switch) */ +#define RCC_CFGR_SW_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define RCC_CFGR_SW_1 ((uint32_t)0x00000002) /*!< Bit 1 */ + +#define RCC_CFGR_SW_HSI ((uint32_t)0x00000000) /*!< HSI selected as system clock */ +#define RCC_CFGR_SW_HSE ((uint32_t)0x00000001) /*!< HSE selected as system clock */ +#define RCC_CFGR_SW_PLL ((uint32_t)0x00000002) /*!< PLL selected as system clock */ + +/*!< SWS configuration */ +#define RCC_CFGR_SWS ((uint32_t)0x0000000C) /*!< SWS[1:0] bits (System Clock Switch Status) */ +#define RCC_CFGR_SWS_0 ((uint32_t)0x00000004) /*!< Bit 0 */ +#define RCC_CFGR_SWS_1 ((uint32_t)0x00000008) /*!< Bit 1 */ + +#define RCC_CFGR_SWS_HSI ((uint32_t)0x00000000) /*!< HSI oscillator used as system clock */ +#define RCC_CFGR_SWS_HSE ((uint32_t)0x00000004) /*!< HSE oscillator used as system clock */ +#define RCC_CFGR_SWS_PLL ((uint32_t)0x00000008) /*!< PLL used as system clock */ + +/*!< HPRE configuration */ +#define RCC_CFGR_HPRE ((uint32_t)0x000000F0) /*!< HPRE[3:0] bits (AHB prescaler) */ +#define RCC_CFGR_HPRE_0 ((uint32_t)0x00000010) /*!< Bit 0 */ +#define RCC_CFGR_HPRE_1 ((uint32_t)0x00000020) /*!< Bit 1 */ +#define RCC_CFGR_HPRE_2 ((uint32_t)0x00000040) /*!< Bit 2 */ +#define RCC_CFGR_HPRE_3 ((uint32_t)0x00000080) /*!< Bit 3 */ + +#define RCC_CFGR_HPRE_DIV1 ((uint32_t)0x00000000) /*!< SYSCLK not divided */ +#define RCC_CFGR_HPRE_DIV2 ((uint32_t)0x00000080) /*!< SYSCLK divided by 2 */ +#define RCC_CFGR_HPRE_DIV4 ((uint32_t)0x00000090) /*!< SYSCLK divided by 4 */ +#define RCC_CFGR_HPRE_DIV8 ((uint32_t)0x000000A0) /*!< SYSCLK divided by 8 */ +#define RCC_CFGR_HPRE_DIV16 ((uint32_t)0x000000B0) /*!< SYSCLK divided by 16 */ +#define RCC_CFGR_HPRE_DIV64 ((uint32_t)0x000000C0) /*!< SYSCLK divided by 64 */ +#define RCC_CFGR_HPRE_DIV128 ((uint32_t)0x000000D0) /*!< SYSCLK divided by 128 */ +#define RCC_CFGR_HPRE_DIV256 ((uint32_t)0x000000E0) /*!< SYSCLK divided by 256 */ +#define RCC_CFGR_HPRE_DIV512 ((uint32_t)0x000000F0) /*!< SYSCLK divided by 512 */ + +/*!< PPRE1 configuration */ +#define RCC_CFGR_PPRE1 ((uint32_t)0x00000700) /*!< PRE1[2:0] bits (APB1 prescaler) */ +#define RCC_CFGR_PPRE1_0 ((uint32_t)0x00000100) /*!< Bit 0 */ +#define RCC_CFGR_PPRE1_1 ((uint32_t)0x00000200) /*!< Bit 1 */ +#define RCC_CFGR_PPRE1_2 ((uint32_t)0x00000400) /*!< Bit 2 */ + +#define RCC_CFGR_PPRE1_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */ +#define RCC_CFGR_PPRE1_DIV2 ((uint32_t)0x00000400) /*!< HCLK divided by 2 */ +#define RCC_CFGR_PPRE1_DIV4 ((uint32_t)0x00000500) /*!< HCLK divided by 4 */ +#define RCC_CFGR_PPRE1_DIV8 ((uint32_t)0x00000600) /*!< HCLK divided by 8 */ +#define RCC_CFGR_PPRE1_DIV16 ((uint32_t)0x00000700) /*!< HCLK divided by 16 */ + +/*!< PPRE2 configuration */ +#define RCC_CFGR_PPRE2 ((uint32_t)0x00003800) /*!< PRE2[2:0] bits (APB2 prescaler) */ +#define RCC_CFGR_PPRE2_0 ((uint32_t)0x00000800) /*!< Bit 0 */ +#define RCC_CFGR_PPRE2_1 ((uint32_t)0x00001000) /*!< Bit 1 */ +#define RCC_CFGR_PPRE2_2 ((uint32_t)0x00002000) /*!< Bit 2 */ + +#define RCC_CFGR_PPRE2_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */ +#define RCC_CFGR_PPRE2_DIV2 ((uint32_t)0x00002000) /*!< HCLK divided by 2 */ +#define RCC_CFGR_PPRE2_DIV4 ((uint32_t)0x00002800) /*!< HCLK divided by 4 */ +#define RCC_CFGR_PPRE2_DIV8 ((uint32_t)0x00003000) /*!< HCLK divided by 8 */ +#define RCC_CFGR_PPRE2_DIV16 ((uint32_t)0x00003800) /*!< HCLK divided by 16 */ + +/*!< ADCPPRE configuration */ +#define RCC_CFGR_ADCPRE ((uint32_t)0x0000C000) /*!< ADCPRE[1:0] bits (ADC prescaler) */ +#define RCC_CFGR_ADCPRE_0 ((uint32_t)0x00004000) /*!< Bit 0 */ +#define RCC_CFGR_ADCPRE_1 ((uint32_t)0x00008000) /*!< Bit 1 */ + +#define RCC_CFGR_ADCPRE_DIV2 ((uint32_t)0x00000000) /*!< PCLK2 divided by 2 */ +#define RCC_CFGR_ADCPRE_DIV4 ((uint32_t)0x00004000) /*!< PCLK2 divided by 4 */ +#define RCC_CFGR_ADCPRE_DIV6 ((uint32_t)0x00008000) /*!< PCLK2 divided by 6 */ +#define RCC_CFGR_ADCPRE_DIV8 ((uint32_t)0x0000C000) /*!< PCLK2 divided by 8 */ + +#define RCC_CFGR_PLLSRC ((uint32_t)0x00010000) /*!< PLL entry clock source */ + +#define RCC_CFGR_PLLXTPRE ((uint32_t)0x00020000) /*!< HSE divider for PLL entry */ + +/*!< PLLMUL configuration */ +#define RCC_CFGR_PLLMULL ((uint32_t)0x003C0000) /*!< PLLMUL[3:0] bits (PLL multiplication factor) */ +#define RCC_CFGR_PLLMULL_0 ((uint32_t)0x00040000) /*!< Bit 0 */ +#define RCC_CFGR_PLLMULL_1 ((uint32_t)0x00080000) /*!< Bit 1 */ +#define RCC_CFGR_PLLMULL_2 ((uint32_t)0x00100000) /*!< Bit 2 */ +#define RCC_CFGR_PLLMULL_3 ((uint32_t)0x00200000) /*!< Bit 3 */ + +#ifdef STM32F10X_CL + #define RCC_CFGR_PLLSRC_HSI_Div2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */ + #define RCC_CFGR_PLLSRC_PREDIV1 ((uint32_t)0x00010000) /*!< PREDIV1 clock selected as PLL entry clock source */ + + #define RCC_CFGR_PLLXTPRE_PREDIV1 ((uint32_t)0x00000000) /*!< PREDIV1 clock not divided for PLL entry */ + #define RCC_CFGR_PLLXTPRE_PREDIV1_Div2 ((uint32_t)0x00020000) /*!< PREDIV1 clock divided by 2 for PLL entry */ + + #define RCC_CFGR_PLLMULL4 ((uint32_t)0x00080000) /*!< PLL input clock * 4 */ + #define RCC_CFGR_PLLMULL5 ((uint32_t)0x000C0000) /*!< PLL input clock * 5 */ + #define RCC_CFGR_PLLMULL6 ((uint32_t)0x00100000) /*!< PLL input clock * 6 */ + #define RCC_CFGR_PLLMULL7 ((uint32_t)0x00140000) /*!< PLL input clock * 7 */ + #define RCC_CFGR_PLLMULL8 ((uint32_t)0x00180000) /*!< PLL input clock * 8 */ + #define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock * 9 */ + #define RCC_CFGR_PLLMULL6_5 ((uint32_t)0x00340000) /*!< PLL input clock * 6.5 */ + + #define RCC_CFGR_OTGFSPRE ((uint32_t)0x00400000) /*!< USB OTG FS prescaler */ + +/*!< MCO configuration */ + #define RCC_CFGR_MCO ((uint32_t)0x0F000000) /*!< MCO[3:0] bits (Microcontroller Clock Output) */ + #define RCC_CFGR_MCO_0 ((uint32_t)0x01000000) /*!< Bit 0 */ + #define RCC_CFGR_MCO_1 ((uint32_t)0x02000000) /*!< Bit 1 */ + #define RCC_CFGR_MCO_2 ((uint32_t)0x04000000) /*!< Bit 2 */ + #define RCC_CFGR_MCO_3 ((uint32_t)0x08000000) /*!< Bit 3 */ + + #define RCC_CFGR_MCO_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */ + #define RCC_CFGR_MCO_SYSCLK ((uint32_t)0x04000000) /*!< System clock selected as MCO source */ + #define RCC_CFGR_MCO_HSI ((uint32_t)0x05000000) /*!< HSI clock selected as MCO source */ + #define RCC_CFGR_MCO_HSE ((uint32_t)0x06000000) /*!< HSE clock selected as MCO source */ + #define RCC_CFGR_MCO_PLLCLK_Div2 ((uint32_t)0x07000000) /*!< PLL clock divided by 2 selected as MCO source */ + #define RCC_CFGR_MCO_PLL2CLK ((uint32_t)0x08000000) /*!< PLL2 clock selected as MCO source*/ + #define RCC_CFGR_MCO_PLL3CLK_Div2 ((uint32_t)0x09000000) /*!< PLL3 clock divided by 2 selected as MCO source*/ + #define RCC_CFGR_MCO_Ext_HSE ((uint32_t)0x0A000000) /*!< XT1 external 3-25 MHz oscillator clock selected as MCO source */ + #define RCC_CFGR_MCO_PLL3CLK ((uint32_t)0x0B000000) /*!< PLL3 clock selected as MCO source */ +#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) + #define RCC_CFGR_PLLSRC_HSI_Div2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */ + #define RCC_CFGR_PLLSRC_PREDIV1 ((uint32_t)0x00010000) /*!< PREDIV1 clock selected as PLL entry clock source */ + + #define RCC_CFGR_PLLXTPRE_PREDIV1 ((uint32_t)0x00000000) /*!< PREDIV1 clock not divided for PLL entry */ + #define RCC_CFGR_PLLXTPRE_PREDIV1_Div2 ((uint32_t)0x00020000) /*!< PREDIV1 clock divided by 2 for PLL entry */ + + #define RCC_CFGR_PLLMULL2 ((uint32_t)0x00000000) /*!< PLL input clock*2 */ + #define RCC_CFGR_PLLMULL3 ((uint32_t)0x00040000) /*!< PLL input clock*3 */ + #define RCC_CFGR_PLLMULL4 ((uint32_t)0x00080000) /*!< PLL input clock*4 */ + #define RCC_CFGR_PLLMULL5 ((uint32_t)0x000C0000) /*!< PLL input clock*5 */ + #define RCC_CFGR_PLLMULL6 ((uint32_t)0x00100000) /*!< PLL input clock*6 */ + #define RCC_CFGR_PLLMULL7 ((uint32_t)0x00140000) /*!< PLL input clock*7 */ + #define RCC_CFGR_PLLMULL8 ((uint32_t)0x00180000) /*!< PLL input clock*8 */ + #define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock*9 */ + #define RCC_CFGR_PLLMULL10 ((uint32_t)0x00200000) /*!< PLL input clock10 */ + #define RCC_CFGR_PLLMULL11 ((uint32_t)0x00240000) /*!< PLL input clock*11 */ + #define RCC_CFGR_PLLMULL12 ((uint32_t)0x00280000) /*!< PLL input clock*12 */ + #define RCC_CFGR_PLLMULL13 ((uint32_t)0x002C0000) /*!< PLL input clock*13 */ + #define RCC_CFGR_PLLMULL14 ((uint32_t)0x00300000) /*!< PLL input clock*14 */ + #define RCC_CFGR_PLLMULL15 ((uint32_t)0x00340000) /*!< PLL input clock*15 */ + #define RCC_CFGR_PLLMULL16 ((uint32_t)0x00380000) /*!< PLL input clock*16 */ + +/*!< MCO configuration */ + #define RCC_CFGR_MCO ((uint32_t)0x07000000) /*!< MCO[2:0] bits (Microcontroller Clock Output) */ + #define RCC_CFGR_MCO_0 ((uint32_t)0x01000000) /*!< Bit 0 */ + #define RCC_CFGR_MCO_1 ((uint32_t)0x02000000) /*!< Bit 1 */ + #define RCC_CFGR_MCO_2 ((uint32_t)0x04000000) /*!< Bit 2 */ + + #define RCC_CFGR_MCO_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */ + #define RCC_CFGR_MCO_SYSCLK ((uint32_t)0x04000000) /*!< System clock selected as MCO source */ + #define RCC_CFGR_MCO_HSI ((uint32_t)0x05000000) /*!< HSI clock selected as MCO source */ + #define RCC_CFGR_MCO_HSE ((uint32_t)0x06000000) /*!< HSE clock selected as MCO source */ + #define RCC_CFGR_MCO_PLL ((uint32_t)0x07000000) /*!< PLL clock divided by 2 selected as MCO source */ +#else + #define RCC_CFGR_PLLSRC_HSI_Div2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */ + #define RCC_CFGR_PLLSRC_HSE ((uint32_t)0x00010000) /*!< HSE clock selected as PLL entry clock source */ + + #define RCC_CFGR_PLLXTPRE_HSE ((uint32_t)0x00000000) /*!< HSE clock not divided for PLL entry */ + #define RCC_CFGR_PLLXTPRE_HSE_Div2 ((uint32_t)0x00020000) /*!< HSE clock divided by 2 for PLL entry */ + + #define RCC_CFGR_PLLMULL2 ((uint32_t)0x00000000) /*!< PLL input clock*2 */ + #define RCC_CFGR_PLLMULL3 ((uint32_t)0x00040000) /*!< PLL input clock*3 */ + #define RCC_CFGR_PLLMULL4 ((uint32_t)0x00080000) /*!< PLL input clock*4 */ + #define RCC_CFGR_PLLMULL5 ((uint32_t)0x000C0000) /*!< PLL input clock*5 */ + #define RCC_CFGR_PLLMULL6 ((uint32_t)0x00100000) /*!< PLL input clock*6 */ + #define RCC_CFGR_PLLMULL7 ((uint32_t)0x00140000) /*!< PLL input clock*7 */ + #define RCC_CFGR_PLLMULL8 ((uint32_t)0x00180000) /*!< PLL input clock*8 */ + #define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock*9 */ + #define RCC_CFGR_PLLMULL10 ((uint32_t)0x00200000) /*!< PLL input clock10 */ + #define RCC_CFGR_PLLMULL11 ((uint32_t)0x00240000) /*!< PLL input clock*11 */ + #define RCC_CFGR_PLLMULL12 ((uint32_t)0x00280000) /*!< PLL input clock*12 */ + #define RCC_CFGR_PLLMULL13 ((uint32_t)0x002C0000) /*!< PLL input clock*13 */ + #define RCC_CFGR_PLLMULL14 ((uint32_t)0x00300000) /*!< PLL input clock*14 */ + #define RCC_CFGR_PLLMULL15 ((uint32_t)0x00340000) /*!< PLL input clock*15 */ + #define RCC_CFGR_PLLMULL16 ((uint32_t)0x00380000) /*!< PLL input clock*16 */ + #define RCC_CFGR_USBPRE ((uint32_t)0x00400000) /*!< USB Device prescaler */ + +/*!< MCO configuration */ + #define RCC_CFGR_MCO ((uint32_t)0x07000000) /*!< MCO[2:0] bits (Microcontroller Clock Output) */ + #define RCC_CFGR_MCO_0 ((uint32_t)0x01000000) /*!< Bit 0 */ + #define RCC_CFGR_MCO_1 ((uint32_t)0x02000000) /*!< Bit 1 */ + #define RCC_CFGR_MCO_2 ((uint32_t)0x04000000) /*!< Bit 2 */ + + #define RCC_CFGR_MCO_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */ + #define RCC_CFGR_MCO_SYSCLK ((uint32_t)0x04000000) /*!< System clock selected as MCO source */ + #define RCC_CFGR_MCO_HSI ((uint32_t)0x05000000) /*!< HSI clock selected as MCO source */ + #define RCC_CFGR_MCO_HSE ((uint32_t)0x06000000) /*!< HSE clock selected as MCO source */ + #define RCC_CFGR_MCO_PLL ((uint32_t)0x07000000) /*!< PLL clock divided by 2 selected as MCO source */ +#endif /* STM32F10X_CL */ + +/*!<****************** Bit definition for RCC_CIR register ********************/ +#define RCC_CIR_LSIRDYF ((uint32_t)0x00000001) /*!< LSI Ready Interrupt flag */ +#define RCC_CIR_LSERDYF ((uint32_t)0x00000002) /*!< LSE Ready Interrupt flag */ +#define RCC_CIR_HSIRDYF ((uint32_t)0x00000004) /*!< HSI Ready Interrupt flag */ +#define RCC_CIR_HSERDYF ((uint32_t)0x00000008) /*!< HSE Ready Interrupt flag */ +#define RCC_CIR_PLLRDYF ((uint32_t)0x00000010) /*!< PLL Ready Interrupt flag */ +#define RCC_CIR_CSSF ((uint32_t)0x00000080) /*!< Clock Security System Interrupt flag */ +#define RCC_CIR_LSIRDYIE ((uint32_t)0x00000100) /*!< LSI Ready Interrupt Enable */ +#define RCC_CIR_LSERDYIE ((uint32_t)0x00000200) /*!< LSE Ready Interrupt Enable */ +#define RCC_CIR_HSIRDYIE ((uint32_t)0x00000400) /*!< HSI Ready Interrupt Enable */ +#define RCC_CIR_HSERDYIE ((uint32_t)0x00000800) /*!< HSE Ready Interrupt Enable */ +#define RCC_CIR_PLLRDYIE ((uint32_t)0x00001000) /*!< PLL Ready Interrupt Enable */ +#define RCC_CIR_LSIRDYC ((uint32_t)0x00010000) /*!< LSI Ready Interrupt Clear */ +#define RCC_CIR_LSERDYC ((uint32_t)0x00020000) /*!< LSE Ready Interrupt Clear */ +#define RCC_CIR_HSIRDYC ((uint32_t)0x00040000) /*!< HSI Ready Interrupt Clear */ +#define RCC_CIR_HSERDYC ((uint32_t)0x00080000) /*!< HSE Ready Interrupt Clear */ +#define RCC_CIR_PLLRDYC ((uint32_t)0x00100000) /*!< PLL Ready Interrupt Clear */ +#define RCC_CIR_CSSC ((uint32_t)0x00800000) /*!< Clock Security System Interrupt Clear */ + +#ifdef STM32F10X_CL + #define RCC_CIR_PLL2RDYF ((uint32_t)0x00000020) /*!< PLL2 Ready Interrupt flag */ + #define RCC_CIR_PLL3RDYF ((uint32_t)0x00000040) /*!< PLL3 Ready Interrupt flag */ + #define RCC_CIR_PLL2RDYIE ((uint32_t)0x00002000) /*!< PLL2 Ready Interrupt Enable */ + #define RCC_CIR_PLL3RDYIE ((uint32_t)0x00004000) /*!< PLL3 Ready Interrupt Enable */ + #define RCC_CIR_PLL2RDYC ((uint32_t)0x00200000) /*!< PLL2 Ready Interrupt Clear */ + #define RCC_CIR_PLL3RDYC ((uint32_t)0x00400000) /*!< PLL3 Ready Interrupt Clear */ +#endif /* STM32F10X_CL */ + +/***************** Bit definition for RCC_APB2RSTR register *****************/ +#define RCC_APB2RSTR_AFIORST ((uint32_t)0x00000001) /*!< Alternate Function I/O reset */ +#define RCC_APB2RSTR_IOPARST ((uint32_t)0x00000004) /*!< I/O port A reset */ +#define RCC_APB2RSTR_IOPBRST ((uint32_t)0x00000008) /*!< I/O port B reset */ +#define RCC_APB2RSTR_IOPCRST ((uint32_t)0x00000010) /*!< I/O port C reset */ +#define RCC_APB2RSTR_IOPDRST ((uint32_t)0x00000020) /*!< I/O port D reset */ +#define RCC_APB2RSTR_ADC1RST ((uint32_t)0x00000200) /*!< ADC 1 interface reset */ + +#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) +#define RCC_APB2RSTR_ADC2RST ((uint32_t)0x00000400) /*!< ADC 2 interface reset */ +#endif + +#define RCC_APB2RSTR_TIM1RST ((uint32_t)0x00000800) /*!< TIM1 Timer reset */ +#define RCC_APB2RSTR_SPI1RST ((uint32_t)0x00001000) /*!< SPI 1 reset */ +#define RCC_APB2RSTR_USART1RST ((uint32_t)0x00004000) /*!< USART1 reset */ + +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) +#define RCC_APB2RSTR_TIM15RST ((uint32_t)0x00010000) /*!< TIM15 Timer reset */ +#define RCC_APB2RSTR_TIM16RST ((uint32_t)0x00020000) /*!< TIM16 Timer reset */ +#define RCC_APB2RSTR_TIM17RST ((uint32_t)0x00040000) /*!< TIM17 Timer reset */ +#endif + +#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) + #define RCC_APB2RSTR_IOPERST ((uint32_t)0x00000040) /*!< I/O port E reset */ +#endif /* STM32F10X_LD && STM32F10X_LD_VL */ + +#if defined (STM32F10X_HD) || defined (STM32F10X_XL) + #define RCC_APB2RSTR_IOPFRST ((uint32_t)0x00000080) /*!< I/O port F reset */ + #define RCC_APB2RSTR_IOPGRST ((uint32_t)0x00000100) /*!< I/O port G reset */ + #define RCC_APB2RSTR_TIM8RST ((uint32_t)0x00002000) /*!< TIM8 Timer reset */ + #define RCC_APB2RSTR_ADC3RST ((uint32_t)0x00008000) /*!< ADC3 interface reset */ +#endif + +#ifdef STM32F10X_XL + #define RCC_APB2RSTR_TIM9RST ((uint32_t)0x00080000) /*!< TIM9 Timer reset */ + #define RCC_APB2RSTR_TIM10RST ((uint32_t)0x00100000) /*!< TIM10 Timer reset */ + #define RCC_APB2RSTR_TIM11RST ((uint32_t)0x00200000) /*!< TIM11 Timer reset */ +#endif /* STM32F10X_XL */ + +/***************** Bit definition for RCC_APB1RSTR register *****************/ +#define RCC_APB1RSTR_TIM2RST ((uint32_t)0x00000001) /*!< Timer 2 reset */ +#define RCC_APB1RSTR_TIM3RST ((uint32_t)0x00000002) /*!< Timer 3 reset */ +#define RCC_APB1RSTR_WWDGRST ((uint32_t)0x00000800) /*!< Window Watchdog reset */ +#define RCC_APB1RSTR_USART2RST ((uint32_t)0x00020000) /*!< USART 2 reset */ +#define RCC_APB1RSTR_I2C1RST ((uint32_t)0x00200000) /*!< I2C 1 reset */ + +#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) +#define RCC_APB1RSTR_CAN1RST ((uint32_t)0x02000000) /*!< CAN1 reset */ +#endif + +#define RCC_APB1RSTR_BKPRST ((uint32_t)0x08000000) /*!< Backup interface reset */ +#define RCC_APB1RSTR_PWRRST ((uint32_t)0x10000000) /*!< Power interface reset */ + +#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) + #define RCC_APB1RSTR_TIM4RST ((uint32_t)0x00000004) /*!< Timer 4 reset */ + #define RCC_APB1RSTR_SPI2RST ((uint32_t)0x00004000) /*!< SPI 2 reset */ + #define RCC_APB1RSTR_USART3RST ((uint32_t)0x00040000) /*!< RUSART 3 reset */ + #define RCC_APB1RSTR_I2C2RST ((uint32_t)0x00400000) /*!< I2C 2 reset */ +#endif /* STM32F10X_LD && STM32F10X_LD_VL */ + +#if defined (STM32F10X_HD) || defined (STM32F10X_MD) || defined (STM32F10X_LD) || defined (STM32F10X_XL) + #define RCC_APB1RSTR_USBRST ((uint32_t)0x00800000) /*!< USB Device reset */ +#endif + +#if defined (STM32F10X_HD) || defined (STM32F10X_CL) || defined (STM32F10X_XL) + #define RCC_APB1RSTR_TIM5RST ((uint32_t)0x00000008) /*!< Timer 5 reset */ + #define RCC_APB1RSTR_TIM6RST ((uint32_t)0x00000010) /*!< Timer 6 reset */ + #define RCC_APB1RSTR_TIM7RST ((uint32_t)0x00000020) /*!< Timer 7 reset */ + #define RCC_APB1RSTR_SPI3RST ((uint32_t)0x00008000) /*!< SPI 3 reset */ + #define RCC_APB1RSTR_UART4RST ((uint32_t)0x00080000) /*!< UART 4 reset */ + #define RCC_APB1RSTR_UART5RST ((uint32_t)0x00100000) /*!< UART 5 reset */ + #define RCC_APB1RSTR_DACRST ((uint32_t)0x20000000) /*!< DAC interface reset */ +#endif + +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) + #define RCC_APB1RSTR_TIM6RST ((uint32_t)0x00000010) /*!< Timer 6 reset */ + #define RCC_APB1RSTR_TIM7RST ((uint32_t)0x00000020) /*!< Timer 7 reset */ + #define RCC_APB1RSTR_DACRST ((uint32_t)0x20000000) /*!< DAC interface reset */ + #define RCC_APB1RSTR_CECRST ((uint32_t)0x40000000) /*!< CEC interface reset */ +#endif + +#ifdef STM32F10X_CL + #define RCC_APB1RSTR_CAN2RST ((uint32_t)0x04000000) /*!< CAN2 reset */ +#endif /* STM32F10X_CL */ + +#ifdef STM32F10X_XL + #define RCC_APB1RSTR_TIM12RST ((uint32_t)0x00000040) /*!< TIM12 Timer reset */ + #define RCC_APB1RSTR_TIM13RST ((uint32_t)0x00000080) /*!< TIM13 Timer reset */ + #define RCC_APB1RSTR_TIM14RST ((uint32_t)0x00000100) /*!< TIM14 Timer reset */ +#endif /* STM32F10X_XL */ + +/****************** Bit definition for RCC_AHBENR register ******************/ +#define RCC_AHBENR_DMA1EN ((uint16_t)0x0001) /*!< DMA1 clock enable */ +#define RCC_AHBENR_SRAMEN ((uint16_t)0x0004) /*!< SRAM interface clock enable */ +#define RCC_AHBENR_FLITFEN ((uint16_t)0x0010) /*!< FLITF clock enable */ +#define RCC_AHBENR_CRCEN ((uint16_t)0x0040) /*!< CRC clock enable */ + +#if defined (STM32F10X_HD) || defined (STM32F10X_CL) + #define RCC_AHBENR_DMA2EN ((uint16_t)0x0002) /*!< DMA2 clock enable */ +#endif + +#if defined (STM32F10X_HD) || defined (STM32F10X_XL) + #define RCC_AHBENR_FSMCEN ((uint16_t)0x0100) /*!< FSMC clock enable */ + #define RCC_AHBENR_SDIOEN ((uint16_t)0x0400) /*!< SDIO clock enable */ +#endif + +#ifdef STM32F10X_CL + #define RCC_AHBENR_OTGFSEN ((uint32_t)0x00001000) /*!< USB OTG FS clock enable */ + #define RCC_AHBENR_ETHMACEN ((uint32_t)0x00004000) /*!< ETHERNET MAC clock enable */ + #define RCC_AHBENR_ETHMACTXEN ((uint32_t)0x00008000) /*!< ETHERNET MAC Tx clock enable */ + #define RCC_AHBENR_ETHMACRXEN ((uint32_t)0x00010000) /*!< ETHERNET MAC Rx clock enable */ +#endif /* STM32F10X_CL */ + +/****************** Bit definition for RCC_APB2ENR register *****************/ +#define RCC_APB2ENR_AFIOEN ((uint32_t)0x00000001) /*!< Alternate Function I/O clock enable */ +#define RCC_APB2ENR_IOPAEN ((uint32_t)0x00000004) /*!< I/O port A clock enable */ +#define RCC_APB2ENR_IOPBEN ((uint32_t)0x00000008) /*!< I/O port B clock enable */ +#define RCC_APB2ENR_IOPCEN ((uint32_t)0x00000010) /*!< I/O port C clock enable */ +#define RCC_APB2ENR_IOPDEN ((uint32_t)0x00000020) /*!< I/O port D clock enable */ +#define RCC_APB2ENR_ADC1EN ((uint32_t)0x00000200) /*!< ADC 1 interface clock enable */ + +#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) +#define RCC_APB2ENR_ADC2EN ((uint32_t)0x00000400) /*!< ADC 2 interface clock enable */ +#endif + +#define RCC_APB2ENR_TIM1EN ((uint32_t)0x00000800) /*!< TIM1 Timer clock enable */ +#define RCC_APB2ENR_SPI1EN ((uint32_t)0x00001000) /*!< SPI 1 clock enable */ +#define RCC_APB2ENR_USART1EN ((uint32_t)0x00004000) /*!< USART1 clock enable */ + +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) +#define RCC_APB2ENR_TIM15EN ((uint32_t)0x00010000) /*!< TIM15 Timer clock enable */ +#define RCC_APB2ENR_TIM16EN ((uint32_t)0x00020000) /*!< TIM16 Timer clock enable */ +#define RCC_APB2ENR_TIM17EN ((uint32_t)0x00040000) /*!< TIM17 Timer clock enable */ +#endif + +#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) + #define RCC_APB2ENR_IOPEEN ((uint32_t)0x00000040) /*!< I/O port E clock enable */ +#endif /* STM32F10X_LD && STM32F10X_LD_VL */ + +#if defined (STM32F10X_HD) || defined (STM32F10X_XL) + #define RCC_APB2ENR_IOPFEN ((uint32_t)0x00000080) /*!< I/O port F clock enable */ + #define RCC_APB2ENR_IOPGEN ((uint32_t)0x00000100) /*!< I/O port G clock enable */ + #define RCC_APB2ENR_TIM8EN ((uint32_t)0x00002000) /*!< TIM8 Timer clock enable */ + #define RCC_APB2ENR_ADC3EN ((uint32_t)0x00008000) /*!< DMA1 clock enable */ +#endif + +#ifdef STM32F10X_XL + #define RCC_APB2ENR_TIM9EN ((uint32_t)0x00080000) /*!< TIM9 Timer clock enable */ + #define RCC_APB2ENR_TIM10EN ((uint32_t)0x00100000) /*!< TIM10 Timer clock enable */ + #define RCC_APB2ENR_TIM11EN ((uint32_t)0x00200000) /*!< TIM11 Timer clock enable */ +#endif + +/***************** Bit definition for RCC_APB1ENR register ******************/ +#define RCC_APB1ENR_TIM2EN ((uint32_t)0x00000001) /*!< Timer 2 clock enabled*/ +#define RCC_APB1ENR_TIM3EN ((uint32_t)0x00000002) /*!< Timer 3 clock enable */ +#define RCC_APB1ENR_WWDGEN ((uint32_t)0x00000800) /*!< Window Watchdog clock enable */ +#define RCC_APB1ENR_USART2EN ((uint32_t)0x00020000) /*!< USART 2 clock enable */ +#define RCC_APB1ENR_I2C1EN ((uint32_t)0x00200000) /*!< I2C 1 clock enable */ + +#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) +#define RCC_APB1ENR_CAN1EN ((uint32_t)0x02000000) /*!< CAN1 clock enable */ +#endif + +#define RCC_APB1ENR_BKPEN ((uint32_t)0x08000000) /*!< Backup interface clock enable */ +#define RCC_APB1ENR_PWREN ((uint32_t)0x10000000) /*!< Power interface clock enable */ + +#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) + #define RCC_APB1ENR_TIM4EN ((uint32_t)0x00000004) /*!< Timer 4 clock enable */ + #define RCC_APB1ENR_SPI2EN ((uint32_t)0x00004000) /*!< SPI 2 clock enable */ + #define RCC_APB1ENR_USART3EN ((uint32_t)0x00040000) /*!< USART 3 clock enable */ + #define RCC_APB1ENR_I2C2EN ((uint32_t)0x00400000) /*!< I2C 2 clock enable */ +#endif /* STM32F10X_LD && STM32F10X_LD_VL */ + +#if defined (STM32F10X_HD) || defined (STM32F10X_MD) || defined (STM32F10X_LD) + #define RCC_APB1ENR_USBEN ((uint32_t)0x00800000) /*!< USB Device clock enable */ +#endif + +#if defined (STM32F10X_HD) || defined (STM32F10X_CL) + #define RCC_APB1ENR_TIM5EN ((uint32_t)0x00000008) /*!< Timer 5 clock enable */ + #define RCC_APB1ENR_TIM6EN ((uint32_t)0x00000010) /*!< Timer 6 clock enable */ + #define RCC_APB1ENR_TIM7EN ((uint32_t)0x00000020) /*!< Timer 7 clock enable */ + #define RCC_APB1ENR_SPI3EN ((uint32_t)0x00008000) /*!< SPI 3 clock enable */ + #define RCC_APB1ENR_UART4EN ((uint32_t)0x00080000) /*!< UART 4 clock enable */ + #define RCC_APB1ENR_UART5EN ((uint32_t)0x00100000) /*!< UART 5 clock enable */ + #define RCC_APB1ENR_DACEN ((uint32_t)0x20000000) /*!< DAC interface clock enable */ +#endif + +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) + #define RCC_APB1ENR_TIM6EN ((uint32_t)0x00000010) /*!< Timer 6 clock enable */ + #define RCC_APB1ENR_TIM7EN ((uint32_t)0x00000020) /*!< Timer 7 clock enable */ + #define RCC_APB1ENR_DACEN ((uint32_t)0x20000000) /*!< DAC interface clock enable */ + #define RCC_APB1ENR_CECEN ((uint32_t)0x40000000) /*!< CEC interface clock enable */ +#endif + +#ifdef STM32F10X_CL + #define RCC_APB1ENR_CAN2EN ((uint32_t)0x04000000) /*!< CAN2 clock enable */ +#endif /* STM32F10X_CL */ + +#ifdef STM32F10X_XL + #define RCC_APB1ENR_TIM12EN ((uint32_t)0x00000040) /*!< TIM12 Timer clock enable */ + #define RCC_APB1ENR_TIM13EN ((uint32_t)0x00000080) /*!< TIM13 Timer clock enable */ + #define RCC_APB1ENR_TIM14EN ((uint32_t)0x00000100) /*!< TIM14 Timer clock enable */ +#endif /* STM32F10X_XL */ + +/******************* Bit definition for RCC_BDCR register *******************/ +#define RCC_BDCR_LSEON ((uint32_t)0x00000001) /*!< External Low Speed oscillator enable */ +#define RCC_BDCR_LSERDY ((uint32_t)0x00000002) /*!< External Low Speed oscillator Ready */ +#define RCC_BDCR_LSEBYP ((uint32_t)0x00000004) /*!< External Low Speed oscillator Bypass */ + +#define RCC_BDCR_RTCSEL ((uint32_t)0x00000300) /*!< RTCSEL[1:0] bits (RTC clock source selection) */ +#define RCC_BDCR_RTCSEL_0 ((uint32_t)0x00000100) /*!< Bit 0 */ +#define RCC_BDCR_RTCSEL_1 ((uint32_t)0x00000200) /*!< Bit 1 */ + +/*!< RTC congiguration */ +#define RCC_BDCR_RTCSEL_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */ +#define RCC_BDCR_RTCSEL_LSE ((uint32_t)0x00000100) /*!< LSE oscillator clock used as RTC clock */ +#define RCC_BDCR_RTCSEL_LSI ((uint32_t)0x00000200) /*!< LSI oscillator clock used as RTC clock */ +#define RCC_BDCR_RTCSEL_HSE ((uint32_t)0x00000300) /*!< HSE oscillator clock divided by 128 used as RTC clock */ + +#define RCC_BDCR_RTCEN ((uint32_t)0x00008000) /*!< RTC clock enable */ +#define RCC_BDCR_BDRST ((uint32_t)0x00010000) /*!< Backup domain software reset */ + +/******************* Bit definition for RCC_CSR register ********************/ +#define RCC_CSR_LSION ((uint32_t)0x00000001) /*!< Internal Low Speed oscillator enable */ +#define RCC_CSR_LSIRDY ((uint32_t)0x00000002) /*!< Internal Low Speed oscillator Ready */ +#define RCC_CSR_RMVF ((uint32_t)0x01000000) /*!< Remove reset flag */ +#define RCC_CSR_PINRSTF ((uint32_t)0x04000000) /*!< PIN reset flag */ +#define RCC_CSR_PORRSTF ((uint32_t)0x08000000) /*!< POR/PDR reset flag */ +#define RCC_CSR_SFTRSTF ((uint32_t)0x10000000) /*!< Software Reset flag */ +#define RCC_CSR_IWDGRSTF ((uint32_t)0x20000000) /*!< Independent Watchdog reset flag */ +#define RCC_CSR_WWDGRSTF ((uint32_t)0x40000000) /*!< Window watchdog reset flag */ +#define RCC_CSR_LPWRRSTF ((uint32_t)0x80000000) /*!< Low-Power reset flag */ + +#ifdef STM32F10X_CL +/******************* Bit definition for RCC_AHBRSTR register ****************/ + #define RCC_AHBRSTR_OTGFSRST ((uint32_t)0x00001000) /*!< USB OTG FS reset */ + #define RCC_AHBRSTR_ETHMACRST ((uint32_t)0x00004000) /*!< ETHERNET MAC reset */ + +/******************* Bit definition for RCC_CFGR2 register ******************/ +/*!< PREDIV1 configuration */ + #define RCC_CFGR2_PREDIV1 ((uint32_t)0x0000000F) /*!< PREDIV1[3:0] bits */ + #define RCC_CFGR2_PREDIV1_0 ((uint32_t)0x00000001) /*!< Bit 0 */ + #define RCC_CFGR2_PREDIV1_1 ((uint32_t)0x00000002) /*!< Bit 1 */ + #define RCC_CFGR2_PREDIV1_2 ((uint32_t)0x00000004) /*!< Bit 2 */ + #define RCC_CFGR2_PREDIV1_3 ((uint32_t)0x00000008) /*!< Bit 3 */ + + #define RCC_CFGR2_PREDIV1_DIV1 ((uint32_t)0x00000000) /*!< PREDIV1 input clock not divided */ + #define RCC_CFGR2_PREDIV1_DIV2 ((uint32_t)0x00000001) /*!< PREDIV1 input clock divided by 2 */ + #define RCC_CFGR2_PREDIV1_DIV3 ((uint32_t)0x00000002) /*!< PREDIV1 input clock divided by 3 */ + #define RCC_CFGR2_PREDIV1_DIV4 ((uint32_t)0x00000003) /*!< PREDIV1 input clock divided by 4 */ + #define RCC_CFGR2_PREDIV1_DIV5 ((uint32_t)0x00000004) /*!< PREDIV1 input clock divided by 5 */ + #define RCC_CFGR2_PREDIV1_DIV6 ((uint32_t)0x00000005) /*!< PREDIV1 input clock divided by 6 */ + #define RCC_CFGR2_PREDIV1_DIV7 ((uint32_t)0x00000006) /*!< PREDIV1 input clock divided by 7 */ + #define RCC_CFGR2_PREDIV1_DIV8 ((uint32_t)0x00000007) /*!< PREDIV1 input clock divided by 8 */ + #define RCC_CFGR2_PREDIV1_DIV9 ((uint32_t)0x00000008) /*!< PREDIV1 input clock divided by 9 */ + #define RCC_CFGR2_PREDIV1_DIV10 ((uint32_t)0x00000009) /*!< PREDIV1 input clock divided by 10 */ + #define RCC_CFGR2_PREDIV1_DIV11 ((uint32_t)0x0000000A) /*!< PREDIV1 input clock divided by 11 */ + #define RCC_CFGR2_PREDIV1_DIV12 ((uint32_t)0x0000000B) /*!< PREDIV1 input clock divided by 12 */ + #define RCC_CFGR2_PREDIV1_DIV13 ((uint32_t)0x0000000C) /*!< PREDIV1 input clock divided by 13 */ + #define RCC_CFGR2_PREDIV1_DIV14 ((uint32_t)0x0000000D) /*!< PREDIV1 input clock divided by 14 */ + #define RCC_CFGR2_PREDIV1_DIV15 ((uint32_t)0x0000000E) /*!< PREDIV1 input clock divided by 15 */ + #define RCC_CFGR2_PREDIV1_DIV16 ((uint32_t)0x0000000F) /*!< PREDIV1 input clock divided by 16 */ + +/*!< PREDIV2 configuration */ + #define RCC_CFGR2_PREDIV2 ((uint32_t)0x000000F0) /*!< PREDIV2[3:0] bits */ + #define RCC_CFGR2_PREDIV2_0 ((uint32_t)0x00000010) /*!< Bit 0 */ + #define RCC_CFGR2_PREDIV2_1 ((uint32_t)0x00000020) /*!< Bit 1 */ + #define RCC_CFGR2_PREDIV2_2 ((uint32_t)0x00000040) /*!< Bit 2 */ + #define RCC_CFGR2_PREDIV2_3 ((uint32_t)0x00000080) /*!< Bit 3 */ + + #define RCC_CFGR2_PREDIV2_DIV1 ((uint32_t)0x00000000) /*!< PREDIV2 input clock not divided */ + #define RCC_CFGR2_PREDIV2_DIV2 ((uint32_t)0x00000010) /*!< PREDIV2 input clock divided by 2 */ + #define RCC_CFGR2_PREDIV2_DIV3 ((uint32_t)0x00000020) /*!< PREDIV2 input clock divided by 3 */ + #define RCC_CFGR2_PREDIV2_DIV4 ((uint32_t)0x00000030) /*!< PREDIV2 input clock divided by 4 */ + #define RCC_CFGR2_PREDIV2_DIV5 ((uint32_t)0x00000040) /*!< PREDIV2 input clock divided by 5 */ + #define RCC_CFGR2_PREDIV2_DIV6 ((uint32_t)0x00000050) /*!< PREDIV2 input clock divided by 6 */ + #define RCC_CFGR2_PREDIV2_DIV7 ((uint32_t)0x00000060) /*!< PREDIV2 input clock divided by 7 */ + #define RCC_CFGR2_PREDIV2_DIV8 ((uint32_t)0x00000070) /*!< PREDIV2 input clock divided by 8 */ + #define RCC_CFGR2_PREDIV2_DIV9 ((uint32_t)0x00000080) /*!< PREDIV2 input clock divided by 9 */ + #define RCC_CFGR2_PREDIV2_DIV10 ((uint32_t)0x00000090) /*!< PREDIV2 input clock divided by 10 */ + #define RCC_CFGR2_PREDIV2_DIV11 ((uint32_t)0x000000A0) /*!< PREDIV2 input clock divided by 11 */ + #define RCC_CFGR2_PREDIV2_DIV12 ((uint32_t)0x000000B0) /*!< PREDIV2 input clock divided by 12 */ + #define RCC_CFGR2_PREDIV2_DIV13 ((uint32_t)0x000000C0) /*!< PREDIV2 input clock divided by 13 */ + #define RCC_CFGR2_PREDIV2_DIV14 ((uint32_t)0x000000D0) /*!< PREDIV2 input clock divided by 14 */ + #define RCC_CFGR2_PREDIV2_DIV15 ((uint32_t)0x000000E0) /*!< PREDIV2 input clock divided by 15 */ + #define RCC_CFGR2_PREDIV2_DIV16 ((uint32_t)0x000000F0) /*!< PREDIV2 input clock divided by 16 */ + +/*!< PLL2MUL configuration */ + #define RCC_CFGR2_PLL2MUL ((uint32_t)0x00000F00) /*!< PLL2MUL[3:0] bits */ + #define RCC_CFGR2_PLL2MUL_0 ((uint32_t)0x00000100) /*!< Bit 0 */ + #define RCC_CFGR2_PLL2MUL_1 ((uint32_t)0x00000200) /*!< Bit 1 */ + #define RCC_CFGR2_PLL2MUL_2 ((uint32_t)0x00000400) /*!< Bit 2 */ + #define RCC_CFGR2_PLL2MUL_3 ((uint32_t)0x00000800) /*!< Bit 3 */ + + #define RCC_CFGR2_PLL2MUL8 ((uint32_t)0x00000600) /*!< PLL2 input clock * 8 */ + #define RCC_CFGR2_PLL2MUL9 ((uint32_t)0x00000700) /*!< PLL2 input clock * 9 */ + #define RCC_CFGR2_PLL2MUL10 ((uint32_t)0x00000800) /*!< PLL2 input clock * 10 */ + #define RCC_CFGR2_PLL2MUL11 ((uint32_t)0x00000900) /*!< PLL2 input clock * 11 */ + #define RCC_CFGR2_PLL2MUL12 ((uint32_t)0x00000A00) /*!< PLL2 input clock * 12 */ + #define RCC_CFGR2_PLL2MUL13 ((uint32_t)0x00000B00) /*!< PLL2 input clock * 13 */ + #define RCC_CFGR2_PLL2MUL14 ((uint32_t)0x00000C00) /*!< PLL2 input clock * 14 */ + #define RCC_CFGR2_PLL2MUL16 ((uint32_t)0x00000E00) /*!< PLL2 input clock * 16 */ + #define RCC_CFGR2_PLL2MUL20 ((uint32_t)0x00000F00) /*!< PLL2 input clock * 20 */ + +/*!< PLL3MUL configuration */ + #define RCC_CFGR2_PLL3MUL ((uint32_t)0x0000F000) /*!< PLL3MUL[3:0] bits */ + #define RCC_CFGR2_PLL3MUL_0 ((uint32_t)0x00001000) /*!< Bit 0 */ + #define RCC_CFGR2_PLL3MUL_1 ((uint32_t)0x00002000) /*!< Bit 1 */ + #define RCC_CFGR2_PLL3MUL_2 ((uint32_t)0x00004000) /*!< Bit 2 */ + #define RCC_CFGR2_PLL3MUL_3 ((uint32_t)0x00008000) /*!< Bit 3 */ + + #define RCC_CFGR2_PLL3MUL8 ((uint32_t)0x00006000) /*!< PLL3 input clock * 8 */ + #define RCC_CFGR2_PLL3MUL9 ((uint32_t)0x00007000) /*!< PLL3 input clock * 9 */ + #define RCC_CFGR2_PLL3MUL10 ((uint32_t)0x00008000) /*!< PLL3 input clock * 10 */ + #define RCC_CFGR2_PLL3MUL11 ((uint32_t)0x00009000) /*!< PLL3 input clock * 11 */ + #define RCC_CFGR2_PLL3MUL12 ((uint32_t)0x0000A000) /*!< PLL3 input clock * 12 */ + #define RCC_CFGR2_PLL3MUL13 ((uint32_t)0x0000B000) /*!< PLL3 input clock * 13 */ + #define RCC_CFGR2_PLL3MUL14 ((uint32_t)0x0000C000) /*!< PLL3 input clock * 14 */ + #define RCC_CFGR2_PLL3MUL16 ((uint32_t)0x0000E000) /*!< PLL3 input clock * 16 */ + #define RCC_CFGR2_PLL3MUL20 ((uint32_t)0x0000F000) /*!< PLL3 input clock * 20 */ + + #define RCC_CFGR2_PREDIV1SRC ((uint32_t)0x00010000) /*!< PREDIV1 entry clock source */ + #define RCC_CFGR2_PREDIV1SRC_PLL2 ((uint32_t)0x00010000) /*!< PLL2 selected as PREDIV1 entry clock source */ + #define RCC_CFGR2_PREDIV1SRC_HSE ((uint32_t)0x00000000) /*!< HSE selected as PREDIV1 entry clock source */ + #define RCC_CFGR2_I2S2SRC ((uint32_t)0x00020000) /*!< I2S2 entry clock source */ + #define RCC_CFGR2_I2S3SRC ((uint32_t)0x00040000) /*!< I2S3 clock source */ +#endif /* STM32F10X_CL */ + +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) +/******************* Bit definition for RCC_CFGR2 register ******************/ +/*!< PREDIV1 configuration */ + #define RCC_CFGR2_PREDIV1 ((uint32_t)0x0000000F) /*!< PREDIV1[3:0] bits */ + #define RCC_CFGR2_PREDIV1_0 ((uint32_t)0x00000001) /*!< Bit 0 */ + #define RCC_CFGR2_PREDIV1_1 ((uint32_t)0x00000002) /*!< Bit 1 */ + #define RCC_CFGR2_PREDIV1_2 ((uint32_t)0x00000004) /*!< Bit 2 */ + #define RCC_CFGR2_PREDIV1_3 ((uint32_t)0x00000008) /*!< Bit 3 */ + + #define RCC_CFGR2_PREDIV1_DIV1 ((uint32_t)0x00000000) /*!< PREDIV1 input clock not divided */ + #define RCC_CFGR2_PREDIV1_DIV2 ((uint32_t)0x00000001) /*!< PREDIV1 input clock divided by 2 */ + #define RCC_CFGR2_PREDIV1_DIV3 ((uint32_t)0x00000002) /*!< PREDIV1 input clock divided by 3 */ + #define RCC_CFGR2_PREDIV1_DIV4 ((uint32_t)0x00000003) /*!< PREDIV1 input clock divided by 4 */ + #define RCC_CFGR2_PREDIV1_DIV5 ((uint32_t)0x00000004) /*!< PREDIV1 input clock divided by 5 */ + #define RCC_CFGR2_PREDIV1_DIV6 ((uint32_t)0x00000005) /*!< PREDIV1 input clock divided by 6 */ + #define RCC_CFGR2_PREDIV1_DIV7 ((uint32_t)0x00000006) /*!< PREDIV1 input clock divided by 7 */ + #define RCC_CFGR2_PREDIV1_DIV8 ((uint32_t)0x00000007) /*!< PREDIV1 input clock divided by 8 */ + #define RCC_CFGR2_PREDIV1_DIV9 ((uint32_t)0x00000008) /*!< PREDIV1 input clock divided by 9 */ + #define RCC_CFGR2_PREDIV1_DIV10 ((uint32_t)0x00000009) /*!< PREDIV1 input clock divided by 10 */ + #define RCC_CFGR2_PREDIV1_DIV11 ((uint32_t)0x0000000A) /*!< PREDIV1 input clock divided by 11 */ + #define RCC_CFGR2_PREDIV1_DIV12 ((uint32_t)0x0000000B) /*!< PREDIV1 input clock divided by 12 */ + #define RCC_CFGR2_PREDIV1_DIV13 ((uint32_t)0x0000000C) /*!< PREDIV1 input clock divided by 13 */ + #define RCC_CFGR2_PREDIV1_DIV14 ((uint32_t)0x0000000D) /*!< PREDIV1 input clock divided by 14 */ + #define RCC_CFGR2_PREDIV1_DIV15 ((uint32_t)0x0000000E) /*!< PREDIV1 input clock divided by 15 */ + #define RCC_CFGR2_PREDIV1_DIV16 ((uint32_t)0x0000000F) /*!< PREDIV1 input clock divided by 16 */ +#endif + +/******************************************************************************/ +/* */ +/* General Purpose and Alternate Function I/O */ +/* */ +/******************************************************************************/ + +/******************* Bit definition for GPIO_CRL register *******************/ +#define GPIO_CRL_MODE ((uint32_t)0x33333333) /*!< Port x mode bits */ + +#define GPIO_CRL_MODE0 ((uint32_t)0x00000003) /*!< MODE0[1:0] bits (Port x mode bits, pin 0) */ +#define GPIO_CRL_MODE0_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define GPIO_CRL_MODE0_1 ((uint32_t)0x00000002) /*!< Bit 1 */ + +#define GPIO_CRL_MODE1 ((uint32_t)0x00000030) /*!< MODE1[1:0] bits (Port x mode bits, pin 1) */ +#define GPIO_CRL_MODE1_0 ((uint32_t)0x00000010) /*!< Bit 0 */ +#define GPIO_CRL_MODE1_1 ((uint32_t)0x00000020) /*!< Bit 1 */ + +#define GPIO_CRL_MODE2 ((uint32_t)0x00000300) /*!< MODE2[1:0] bits (Port x mode bits, pin 2) */ +#define GPIO_CRL_MODE2_0 ((uint32_t)0x00000100) /*!< Bit 0 */ +#define GPIO_CRL_MODE2_1 ((uint32_t)0x00000200) /*!< Bit 1 */ + +#define GPIO_CRL_MODE3 ((uint32_t)0x00003000) /*!< MODE3[1:0] bits (Port x mode bits, pin 3) */ +#define GPIO_CRL_MODE3_0 ((uint32_t)0x00001000) /*!< Bit 0 */ +#define GPIO_CRL_MODE3_1 ((uint32_t)0x00002000) /*!< Bit 1 */ + +#define GPIO_CRL_MODE4 ((uint32_t)0x00030000) /*!< MODE4[1:0] bits (Port x mode bits, pin 4) */ +#define GPIO_CRL_MODE4_0 ((uint32_t)0x00010000) /*!< Bit 0 */ +#define GPIO_CRL_MODE4_1 ((uint32_t)0x00020000) /*!< Bit 1 */ + +#define GPIO_CRL_MODE5 ((uint32_t)0x00300000) /*!< MODE5[1:0] bits (Port x mode bits, pin 5) */ +#define GPIO_CRL_MODE5_0 ((uint32_t)0x00100000) /*!< Bit 0 */ +#define GPIO_CRL_MODE5_1 ((uint32_t)0x00200000) /*!< Bit 1 */ + +#define GPIO_CRL_MODE6 ((uint32_t)0x03000000) /*!< MODE6[1:0] bits (Port x mode bits, pin 6) */ +#define GPIO_CRL_MODE6_0 ((uint32_t)0x01000000) /*!< Bit 0 */ +#define GPIO_CRL_MODE6_1 ((uint32_t)0x02000000) /*!< Bit 1 */ + +#define GPIO_CRL_MODE7 ((uint32_t)0x30000000) /*!< MODE7[1:0] bits (Port x mode bits, pin 7) */ +#define GPIO_CRL_MODE7_0 ((uint32_t)0x10000000) /*!< Bit 0 */ +#define GPIO_CRL_MODE7_1 ((uint32_t)0x20000000) /*!< Bit 1 */ + +#define GPIO_CRL_CNF ((uint32_t)0xCCCCCCCC) /*!< Port x configuration bits */ + +#define GPIO_CRL_CNF0 ((uint32_t)0x0000000C) /*!< CNF0[1:0] bits (Port x configuration bits, pin 0) */ +#define GPIO_CRL_CNF0_0 ((uint32_t)0x00000004) /*!< Bit 0 */ +#define GPIO_CRL_CNF0_1 ((uint32_t)0x00000008) /*!< Bit 1 */ + +#define GPIO_CRL_CNF1 ((uint32_t)0x000000C0) /*!< CNF1[1:0] bits (Port x configuration bits, pin 1) */ +#define GPIO_CRL_CNF1_0 ((uint32_t)0x00000040) /*!< Bit 0 */ +#define GPIO_CRL_CNF1_1 ((uint32_t)0x00000080) /*!< Bit 1 */ + +#define GPIO_CRL_CNF2 ((uint32_t)0x00000C00) /*!< CNF2[1:0] bits (Port x configuration bits, pin 2) */ +#define GPIO_CRL_CNF2_0 ((uint32_t)0x00000400) /*!< Bit 0 */ +#define GPIO_CRL_CNF2_1 ((uint32_t)0x00000800) /*!< Bit 1 */ + +#define GPIO_CRL_CNF3 ((uint32_t)0x0000C000) /*!< CNF3[1:0] bits (Port x configuration bits, pin 3) */ +#define GPIO_CRL_CNF3_0 ((uint32_t)0x00004000) /*!< Bit 0 */ +#define GPIO_CRL_CNF3_1 ((uint32_t)0x00008000) /*!< Bit 1 */ + +#define GPIO_CRL_CNF4 ((uint32_t)0x000C0000) /*!< CNF4[1:0] bits (Port x configuration bits, pin 4) */ +#define GPIO_CRL_CNF4_0 ((uint32_t)0x00040000) /*!< Bit 0 */ +#define GPIO_CRL_CNF4_1 ((uint32_t)0x00080000) /*!< Bit 1 */ + +#define GPIO_CRL_CNF5 ((uint32_t)0x00C00000) /*!< CNF5[1:0] bits (Port x configuration bits, pin 5) */ +#define GPIO_CRL_CNF5_0 ((uint32_t)0x00400000) /*!< Bit 0 */ +#define GPIO_CRL_CNF5_1 ((uint32_t)0x00800000) /*!< Bit 1 */ + +#define GPIO_CRL_CNF6 ((uint32_t)0x0C000000) /*!< CNF6[1:0] bits (Port x configuration bits, pin 6) */ +#define GPIO_CRL_CNF6_0 ((uint32_t)0x04000000) /*!< Bit 0 */ +#define GPIO_CRL_CNF6_1 ((uint32_t)0x08000000) /*!< Bit 1 */ + +#define GPIO_CRL_CNF7 ((uint32_t)0xC0000000) /*!< CNF7[1:0] bits (Port x configuration bits, pin 7) */ +#define GPIO_CRL_CNF7_0 ((uint32_t)0x40000000) /*!< Bit 0 */ +#define GPIO_CRL_CNF7_1 ((uint32_t)0x80000000) /*!< Bit 1 */ + +/******************* Bit definition for GPIO_CRH register *******************/ +#define GPIO_CRH_MODE ((uint32_t)0x33333333) /*!< Port x mode bits */ + +#define GPIO_CRH_MODE8 ((uint32_t)0x00000003) /*!< MODE8[1:0] bits (Port x mode bits, pin 8) */ +#define GPIO_CRH_MODE8_0 ((uint32_t)0x00000001) /*!< Bit 0 */ +#define GPIO_CRH_MODE8_1 ((uint32_t)0x00000002) /*!< Bit 1 */ + +#define GPIO_CRH_MODE9 ((uint32_t)0x00000030) /*!< MODE9[1:0] bits (Port x mode bits, pin 9) */ +#define GPIO_CRH_MODE9_0 ((uint32_t)0x00000010) /*!< Bit 0 */ +#define GPIO_CRH_MODE9_1 ((uint32_t)0x00000020) /*!< Bit 1 */ + +#define GPIO_CRH_MODE10 ((uint32_t)0x00000300) /*!< MODE10[1:0] bits (Port x mode bits, pin 10) */ +#define GPIO_CRH_MODE10_0 ((uint32_t)0x00000100) /*!< Bit 0 */ +#define GPIO_CRH_MODE10_1 ((uint32_t)0x00000200) /*!< Bit 1 */ + +#define GPIO_CRH_MODE11 ((uint32_t)0x00003000) /*!< MODE11[1:0] bits (Port x mode bits, pin 11) */ +#define GPIO_CRH_MODE11_0 ((uint32_t)0x00001000) /*!< Bit 0 */ +#define GPIO_CRH_MODE11_1 ((uint32_t)0x00002000) /*!< Bit 1 */ + +#define GPIO_CRH_MODE12 ((uint32_t)0x00030000) /*!< MODE12[1:0] bits (Port x mode bits, pin 12) */ +#define GPIO_CRH_MODE12_0 ((uint32_t)0x00010000) /*!< Bit 0 */ +#define GPIO_CRH_MODE12_1 ((uint32_t)0x00020000) /*!< Bit 1 */ + +#define GPIO_CRH_MODE13 ((uint32_t)0x00300000) /*!< MODE13[1:0] bits (Port x mode bits, pin 13) */ +#define GPIO_CRH_MODE13_0 ((uint32_t)0x00100000) /*!< Bit 0 */ +#define GPIO_CRH_MODE13_1 ((uint32_t)0x00200000) /*!< Bit 1 */ + +#define GPIO_CRH_MODE14 ((uint32_t)0x03000000) /*!< MODE14[1:0] bits (Port x mode bits, pin 14) */ +#define GPIO_CRH_MODE14_0 ((uint32_t)0x01000000) /*!< Bit 0 */ +#define GPIO_CRH_MODE14_1 ((uint32_t)0x02000000) /*!< Bit 1 */ + +#define GPIO_CRH_MODE15 ((uint32_t)0x30000000) /*!< MODE15[1:0] bits (Port x mode bits, pin 15) */ +#define GPIO_CRH_MODE15_0 ((uint32_t)0x10000000) /*!< Bit 0 */ +#define GPIO_CRH_MODE15_1 ((uint32_t)0x20000000) /*!< Bit 1 */ + +#define GPIO_CRH_CNF ((uint32_t)0xCCCCCCCC) /*!< Port x configuration bits */ + +#define GPIO_CRH_CNF8 ((uint32_t)0x0000000C) /*!< CNF8[1:0] bits (Port x configuration bits, pin 8) */ +#define GPIO_CRH_CNF8_0 ((uint32_t)0x00000004) /*!< Bit 0 */ +#define GPIO_CRH_CNF8_1 ((uint32_t)0x00000008) /*!< Bit 1 */ + +#define GPIO_CRH_CNF9 ((uint32_t)0x000000C0) /*!< CNF9[1:0] bits (Port x configuration bits, pin 9) */ +#define GPIO_CRH_CNF9_0 ((uint32_t)0x00000040) /*!< Bit 0 */ +#define GPIO_CRH_CNF9_1 ((uint32_t)0x00000080) /*!< Bit 1 */ + +#define GPIO_CRH_CNF10 ((uint32_t)0x00000C00) /*!< CNF10[1:0] bits (Port x configuration bits, pin 10) */ +#define GPIO_CRH_CNF10_0 ((uint32_t)0x00000400) /*!< Bit 0 */ +#define GPIO_CRH_CNF10_1 ((uint32_t)0x00000800) /*!< Bit 1 */ + +#define GPIO_CRH_CNF11 ((uint32_t)0x0000C000) /*!< CNF11[1:0] bits (Port x configuration bits, pin 11) */ +#define GPIO_CRH_CNF11_0 ((uint32_t)0x00004000) /*!< Bit 0 */ +#define GPIO_CRH_CNF11_1 ((uint32_t)0x00008000) /*!< Bit 1 */ + +#define GPIO_CRH_CNF12 ((uint32_t)0x000C0000) /*!< CNF12[1:0] bits (Port x configuration bits, pin 12) */ +#define GPIO_CRH_CNF12_0 ((uint32_t)0x00040000) /*!< Bit 0 */ +#define GPIO_CRH_CNF12_1 ((uint32_t)0x00080000) /*!< Bit 1 */ + +#define GPIO_CRH_CNF13 ((uint32_t)0x00C00000) /*!< CNF13[1:0] bits (Port x configuration bits, pin 13) */ +#define GPIO_CRH_CNF13_0 ((uint32_t)0x00400000) /*!< Bit 0 */ +#define GPIO_CRH_CNF13_1 ((uint32_t)0x00800000) /*!< Bit 1 */ + +#define GPIO_CRH_CNF14 ((uint32_t)0x0C000000) /*!< CNF14[1:0] bits (Port x configuration bits, pin 14) */ +#define GPIO_CRH_CNF14_0 ((uint32_t)0x04000000) /*!< Bit 0 */ +#define GPIO_CRH_CNF14_1 ((uint32_t)0x08000000) /*!< Bit 1 */ + +#define GPIO_CRH_CNF15 ((uint32_t)0xC0000000) /*!< CNF15[1:0] bits (Port x configuration bits, pin 15) */ +#define GPIO_CRH_CNF15_0 ((uint32_t)0x40000000) /*!< Bit 0 */ +#define GPIO_CRH_CNF15_1 ((uint32_t)0x80000000) /*!< Bit 1 */ + +/*!<****************** Bit definition for GPIO_IDR register *******************/ +#define GPIO_IDR_IDR0 ((uint16_t)0x0001) /*!< Port input data, bit 0 */ +#define GPIO_IDR_IDR1 ((uint16_t)0x0002) /*!< Port input data, bit 1 */ +#define GPIO_IDR_IDR2 ((uint16_t)0x0004) /*!< Port input data, bit 2 */ +#define GPIO_IDR_IDR3 ((uint16_t)0x0008) /*!< Port input data, bit 3 */ +#define GPIO_IDR_IDR4 ((uint16_t)0x0010) /*!< Port input data, bit 4 */ +#define GPIO_IDR_IDR5 ((uint16_t)0x0020) /*!< Port input data, bit 5 */ +#define GPIO_IDR_IDR6 ((uint16_t)0x0040) /*!< Port input data, bit 6 */ +#define GPIO_IDR_IDR7 ((uint16_t)0x0080) /*!< Port input data, bit 7 */ +#define GPIO_IDR_IDR8 ((uint16_t)0x0100) /*!< Port input data, bit 8 */ +#define GPIO_IDR_IDR9 ((uint16_t)0x0200) /*!< Port input data, bit 9 */ +#define GPIO_IDR_IDR10 ((uint16_t)0x0400) /*!< Port input data, bit 10 */ +#define GPIO_IDR_IDR11 ((uint16_t)0x0800) /*!< Port input data, bit 11 */ +#define GPIO_IDR_IDR12 ((uint16_t)0x1000) /*!< Port input data, bit 12 */ +#define GPIO_IDR_IDR13 ((uint16_t)0x2000) /*!< Port input data, bit 13 */ +#define GPIO_IDR_IDR14 ((uint16_t)0x4000) /*!< Port input data, bit 14 */ +#define GPIO_IDR_IDR15 ((uint16_t)0x8000) /*!< Port input data, bit 15 */ + +/******************* Bit definition for GPIO_ODR register *******************/ +#define GPIO_ODR_ODR0 ((uint16_t)0x0001) /*!< Port output data, bit 0 */ +#define GPIO_ODR_ODR1 ((uint16_t)0x0002) /*!< Port output data, bit 1 */ +#define GPIO_ODR_ODR2 ((uint16_t)0x0004) /*!< Port output data, bit 2 */ +#define GPIO_ODR_ODR3 ((uint16_t)0x0008) /*!< Port output data, bit 3 */ +#define GPIO_ODR_ODR4 ((uint16_t)0x0010) /*!< Port output data, bit 4 */ +#define GPIO_ODR_ODR5 ((uint16_t)0x0020) /*!< Port output data, bit 5 */ +#define GPIO_ODR_ODR6 ((uint16_t)0x0040) /*!< Port output data, bit 6 */ +#define GPIO_ODR_ODR7 ((uint16_t)0x0080) /*!< Port output data, bit 7 */ +#define GPIO_ODR_ODR8 ((uint16_t)0x0100) /*!< Port output data, bit 8 */ +#define GPIO_ODR_ODR9 ((uint16_t)0x0200) /*!< Port output data, bit 9 */ +#define GPIO_ODR_ODR10 ((uint16_t)0x0400) /*!< Port output data, bit 10 */ +#define GPIO_ODR_ODR11 ((uint16_t)0x0800) /*!< Port output data, bit 11 */ +#define GPIO_ODR_ODR12 ((uint16_t)0x1000) /*!< Port output data, bit 12 */ +#define GPIO_ODR_ODR13 ((uint16_t)0x2000) /*!< Port output data, bit 13 */ +#define GPIO_ODR_ODR14 ((uint16_t)0x4000) /*!< Port output data, bit 14 */ +#define GPIO_ODR_ODR15 ((uint16_t)0x8000) /*!< Port output data, bit 15 */ + +/****************** Bit definition for GPIO_BSRR register *******************/ +#define GPIO_BSRR_BS0 ((uint32_t)0x00000001) /*!< Port x Set bit 0 */ +#define GPIO_BSRR_BS1 ((uint32_t)0x00000002) /*!< Port x Set bit 1 */ +#define GPIO_BSRR_BS2 ((uint32_t)0x00000004) /*!< Port x Set bit 2 */ +#define GPIO_BSRR_BS3 ((uint32_t)0x00000008) /*!< Port x Set bit 3 */ +#define GPIO_BSRR_BS4 ((uint32_t)0x00000010) /*!< Port x Set bit 4 */ +#define GPIO_BSRR_BS5 ((uint32_t)0x00000020) /*!< Port x Set bit 5 */ +#define GPIO_BSRR_BS6 ((uint32_t)0x00000040) /*!< Port x Set bit 6 */ +#define GPIO_BSRR_BS7 ((uint32_t)0x00000080) /*!< Port x Set bit 7 */ +#define GPIO_BSRR_BS8 ((uint32_t)0x00000100) /*!< Port x Set bit 8 */ +#define GPIO_BSRR_BS9 ((uint32_t)0x00000200) /*!< Port x Set bit 9 */ +#define GPIO_BSRR_BS10 ((uint32_t)0x00000400) /*!< Port x Set bit 10 */ +#define GPIO_BSRR_BS11 ((uint32_t)0x00000800) /*!< Port x Set bit 11 */ +#define GPIO_BSRR_BS12 ((uint32_t)0x00001000) /*!< Port x Set bit 12 */ +#define GPIO_BSRR_BS13 ((uint32_t)0x00002000) /*!< Port x Set bit 13 */ +#define GPIO_BSRR_BS14 ((uint32_t)0x00004000) /*!< Port x Set bit 14 */ +#define GPIO_BSRR_BS15 ((uint32_t)0x00008000) /*!< Port x Set bit 15 */ + +#define GPIO_BSRR_BR0 ((uint32_t)0x00010000) /*!< Port x Reset bit 0 */ +#define GPIO_BSRR_BR1 ((uint32_t)0x00020000) /*!< Port x Reset bit 1 */ +#define GPIO_BSRR_BR2 ((uint32_t)0x00040000) /*!< Port x Reset bit 2 */ +#define GPIO_BSRR_BR3 ((uint32_t)0x00080000) /*!< Port x Reset bit 3 */ +#define GPIO_BSRR_BR4 ((uint32_t)0x00100000) /*!< Port x Reset bit 4 */ +#define GPIO_BSRR_BR5 ((uint32_t)0x00200000) /*!< Port x Reset bit 5 */ +#define GPIO_BSRR_BR6 ((uint32_t)0x00400000) /*!< Port x Reset bit 6 */ +#define GPIO_BSRR_BR7 ((uint32_t)0x00800000) /*!< Port x Reset bit 7 */ +#define GPIO_BSRR_BR8 ((uint32_t)0x01000000) /*!< Port x Reset bit 8 */ +#define GPIO_BSRR_BR9 ((uint32_t)0x02000000) /*!< Port x Reset bit 9 */ +#define GPIO_BSRR_BR10 ((uint32_t)0x04000000) /*!< Port x Reset bit 10 */ +#define GPIO_BSRR_BR11 ((uint32_t)0x08000000) /*!< Port x Reset bit 11 */ +#define GPIO_BSRR_BR12 ((uint32_t)0x10000000) /*!< Port x Reset bit 12 */ +#define GPIO_BSRR_BR13 ((uint32_t)0x20000000) /*!< Port x Reset bit 13 */ +#define GPIO_BSRR_BR14 ((uint32_t)0x40000000) /*!< Port x Reset bit 14 */ +#define GPIO_BSRR_BR15 ((uint32_t)0x80000000) /*!< Port x Reset bit 15 */ + +/******************* Bit definition for GPIO_BRR register *******************/ +#define GPIO_BRR_BR0 ((uint16_t)0x0001) /*!< Port x Reset bit 0 */ +#define GPIO_BRR_BR1 ((uint16_t)0x0002) /*!< Port x Reset bit 1 */ +#define GPIO_BRR_BR2 ((uint16_t)0x0004) /*!< Port x Reset bit 2 */ +#define GPIO_BRR_BR3 ((uint16_t)0x0008) /*!< Port x Reset bit 3 */ +#define GPIO_BRR_BR4 ((uint16_t)0x0010) /*!< Port x Reset bit 4 */ +#define GPIO_BRR_BR5 ((uint16_t)0x0020) /*!< Port x Reset bit 5 */ +#define GPIO_BRR_BR6 ((uint16_t)0x0040) /*!< Port x Reset bit 6 */ +#define GPIO_BRR_BR7 ((uint16_t)0x0080) /*!< Port x Reset bit 7 */ +#define GPIO_BRR_BR8 ((uint16_t)0x0100) /*!< Port x Reset bit 8 */ +#define GPIO_BRR_BR9 ((uint16_t)0x0200) /*!< Port x Reset bit 9 */ +#define GPIO_BRR_BR10 ((uint16_t)0x0400) /*!< Port x Reset bit 10 */ +#define GPIO_BRR_BR11 ((uint16_t)0x0800) /*!< Port x Reset bit 11 */ +#define GPIO_BRR_BR12 ((uint16_t)0x1000) /*!< Port x Reset bit 12 */ +#define GPIO_BRR_BR13 ((uint16_t)0x2000) /*!< Port x Reset bit 13 */ +#define GPIO_BRR_BR14 ((uint16_t)0x4000) /*!< Port x Reset bit 14 */ +#define GPIO_BRR_BR15 ((uint16_t)0x8000) /*!< Port x Reset bit 15 */ + +/****************** Bit definition for GPIO_LCKR register *******************/ +#define GPIO_LCKR_LCK0 ((uint32_t)0x00000001) /*!< Port x Lock bit 0 */ +#define GPIO_LCKR_LCK1 ((uint32_t)0x00000002) /*!< Port x Lock bit 1 */ +#define GPIO_LCKR_LCK2 ((uint32_t)0x00000004) /*!< Port x Lock bit 2 */ +#define GPIO_LCKR_LCK3 ((uint32_t)0x00000008) /*!< Port x Lock bit 3 */ +#define GPIO_LCKR_LCK4 ((uint32_t)0x00000010) /*!< Port x Lock bit 4 */ +#define GPIO_LCKR_LCK5 ((uint32_t)0x00000020) /*!< Port x Lock bit 5 */ +#define GPIO_LCKR_LCK6 ((uint32_t)0x00000040) /*!< Port x Lock bit 6 */ +#define GPIO_LCKR_LCK7 ((uint32_t)0x00000080) /*!< Port x Lock bit 7 */ +#define GPIO_LCKR_LCK8 ((uint32_t)0x00000100) /*!< Port x Lock bit 8 */ +#define GPIO_LCKR_LCK9 ((uint32_t)0x00000200) /*!< Port x Lock bit 9 */ +#define GPIO_LCKR_LCK10 ((uint32_t)0x00000400) /*!< Port x Lock bit 10 */ +#define GPIO_LCKR_LCK11 ((uint32_t)0x00000800) /*!< Port x Lock bit 11 */ +#define GPIO_LCKR_LCK12 ((uint32_t)0x00001000) /*!< Port x Lock bit 12 */ +#define GPIO_LCKR_LCK13 ((uint32_t)0x00002000) /*!< Port x Lock bit 13 */ +#define GPIO_LCKR_LCK14 ((uint32_t)0x00004000) /*!< Port x Lock bit 14 */ +#define GPIO_LCKR_LCK15 ((uint32_t)0x00008000) /*!< Port x Lock bit 15 */ +#define GPIO_LCKR_LCKK ((uint32_t)0x00010000) /*!< Lock key */ + +/*----------------------------------------------------------------------------*/ + +/****************** Bit definition for AFIO_EVCR register *******************/ +#define AFIO_EVCR_PIN ((uint8_t)0x0F) /*!< PIN[3:0] bits (Pin selection) */ +#define AFIO_EVCR_PIN_0 ((uint8_t)0x01) /*!< Bit 0 */ +#define AFIO_EVCR_PIN_1 ((uint8_t)0x02) /*!< Bit 1 */ +#define AFIO_EVCR_PIN_2 ((uint8_t)0x04) /*!< Bit 2 */ +#define AFIO_EVCR_PIN_3 ((uint8_t)0x08) /*!< Bit 3 */ + +/*!< PIN configuration */ +#define AFIO_EVCR_PIN_PX0 ((uint8_t)0x00) /*!< Pin 0 selected */ +#define AFIO_EVCR_PIN_PX1 ((uint8_t)0x01) /*!< Pin 1 selected */ +#define AFIO_EVCR_PIN_PX2 ((uint8_t)0x02) /*!< Pin 2 selected */ +#define AFIO_EVCR_PIN_PX3 ((uint8_t)0x03) /*!< Pin 3 selected */ +#define AFIO_EVCR_PIN_PX4 ((uint8_t)0x04) /*!< Pin 4 selected */ +#define AFIO_EVCR_PIN_PX5 ((uint8_t)0x05) /*!< Pin 5 selected */ +#define AFIO_EVCR_PIN_PX6 ((uint8_t)0x06) /*!< Pin 6 selected */ +#define AFIO_EVCR_PIN_PX7 ((uint8_t)0x07) /*!< Pin 7 selected */ +#define AFIO_EVCR_PIN_PX8 ((uint8_t)0x08) /*!< Pin 8 selected */ +#define AFIO_EVCR_PIN_PX9 ((uint8_t)0x09) /*!< Pin 9 selected */ +#define AFIO_EVCR_PIN_PX10 ((uint8_t)0x0A) /*!< Pin 10 selected */ +#define AFIO_EVCR_PIN_PX11 ((uint8_t)0x0B) /*!< Pin 11 selected */ +#define AFIO_EVCR_PIN_PX12 ((uint8_t)0x0C) /*!< Pin 12 selected */ +#define AFIO_EVCR_PIN_PX13 ((uint8_t)0x0D) /*!< Pin 13 selected */ +#define AFIO_EVCR_PIN_PX14 ((uint8_t)0x0E) /*!< Pin 14 selected */ +#define AFIO_EVCR_PIN_PX15 ((uint8_t)0x0F) /*!< Pin 15 selected */ + +#define AFIO_EVCR_PORT ((uint8_t)0x70) /*!< PORT[2:0] bits (Port selection) */ +#define AFIO_EVCR_PORT_0 ((uint8_t)0x10) /*!< Bit 0 */ +#define AFIO_EVCR_PORT_1 ((uint8_t)0x20) /*!< Bit 1 */ +#define AFIO_EVCR_PORT_2 ((uint8_t)0x40) /*!< Bit 2 */ + +/*!< PORT configuration */ +#define AFIO_EVCR_PORT_PA ((uint8_t)0x00) /*!< Port A selected */ +#define AFIO_EVCR_PORT_PB ((uint8_t)0x10) /*!< Port B selected */ +#define AFIO_EVCR_PORT_PC ((uint8_t)0x20) /*!< Port C selected */ +#define AFIO_EVCR_PORT_PD ((uint8_t)0x30) /*!< Port D selected */ +#define AFIO_EVCR_PORT_PE ((uint8_t)0x40) /*!< Port E selected */ + +#define AFIO_EVCR_EVOE ((uint8_t)0x80) /*!< Event Output Enable */ + +/****************** Bit definition for AFIO_MAPR register *******************/ +#define AFIO_MAPR_SPI1_REMAP ((uint32_t)0x00000001) /*!< SPI1 remapping */ +#define AFIO_MAPR_I2C1_REMAP ((uint32_t)0x00000002) /*!< I2C1 remapping */ +#define AFIO_MAPR_USART1_REMAP ((uint32_t)0x00000004) /*!< USART1 remapping */ +#define AFIO_MAPR_USART2_REMAP ((uint32_t)0x00000008) /*!< USART2 remapping */ + +#define AFIO_MAPR_USART3_REMAP ((uint32_t)0x00000030) /*!< USART3_REMAP[1:0] bits (USART3 remapping) */ +#define AFIO_MAPR_USART3_REMAP_0 ((uint32_t)0x00000010) /*!< Bit 0 */ +#define AFIO_MAPR_USART3_REMAP_1 ((uint32_t)0x00000020) /*!< Bit 1 */ + +/* USART3_REMAP configuration */ +#define AFIO_MAPR_USART3_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (TX/PB10, RX/PB11, CK/PB12, CTS/PB13, RTS/PB14) */ +#define AFIO_MAPR_USART3_REMAP_PARTIALREMAP ((uint32_t)0x00000010) /*!< Partial remap (TX/PC10, RX/PC11, CK/PC12, CTS/PB13, RTS/PB14) */ +#define AFIO_MAPR_USART3_REMAP_FULLREMAP ((uint32_t)0x00000030) /*!< Full remap (TX/PD8, RX/PD9, CK/PD10, CTS/PD11, RTS/PD12) */ + +#define AFIO_MAPR_TIM1_REMAP ((uint32_t)0x000000C0) /*!< TIM1_REMAP[1:0] bits (TIM1 remapping) */ +#define AFIO_MAPR_TIM1_REMAP_0 ((uint32_t)0x00000040) /*!< Bit 0 */ +#define AFIO_MAPR_TIM1_REMAP_1 ((uint32_t)0x00000080) /*!< Bit 1 */ + +/*!< TIM1_REMAP configuration */ +#define AFIO_MAPR_TIM1_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PB12, CH1N/PB13, CH2N/PB14, CH3N/PB15) */ +#define AFIO_MAPR_TIM1_REMAP_PARTIALREMAP ((uint32_t)0x00000040) /*!< Partial remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PA6, CH1N/PA7, CH2N/PB0, CH3N/PB1) */ +#define AFIO_MAPR_TIM1_REMAP_FULLREMAP ((uint32_t)0x000000C0) /*!< Full remap (ETR/PE7, CH1/PE9, CH2/PE11, CH3/PE13, CH4/PE14, BKIN/PE15, CH1N/PE8, CH2N/PE10, CH3N/PE12) */ + +#define AFIO_MAPR_TIM2_REMAP ((uint32_t)0x00000300) /*!< TIM2_REMAP[1:0] bits (TIM2 remapping) */ +#define AFIO_MAPR_TIM2_REMAP_0 ((uint32_t)0x00000100) /*!< Bit 0 */ +#define AFIO_MAPR_TIM2_REMAP_1 ((uint32_t)0x00000200) /*!< Bit 1 */ + +/*!< TIM2_REMAP configuration */ +#define AFIO_MAPR_TIM2_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (CH1/ETR/PA0, CH2/PA1, CH3/PA2, CH4/PA3) */ +#define AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1 ((uint32_t)0x00000100) /*!< Partial remap (CH1/ETR/PA15, CH2/PB3, CH3/PA2, CH4/PA3) */ +#define AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2 ((uint32_t)0x00000200) /*!< Partial remap (CH1/ETR/PA0, CH2/PA1, CH3/PB10, CH4/PB11) */ +#define AFIO_MAPR_TIM2_REMAP_FULLREMAP ((uint32_t)0x00000300) /*!< Full remap (CH1/ETR/PA15, CH2/PB3, CH3/PB10, CH4/PB11) */ + +#define AFIO_MAPR_TIM3_REMAP ((uint32_t)0x00000C00) /*!< TIM3_REMAP[1:0] bits (TIM3 remapping) */ +#define AFIO_MAPR_TIM3_REMAP_0 ((uint32_t)0x00000400) /*!< Bit 0 */ +#define AFIO_MAPR_TIM3_REMAP_1 ((uint32_t)0x00000800) /*!< Bit 1 */ + +/*!< TIM3_REMAP configuration */ +#define AFIO_MAPR_TIM3_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (CH1/PA6, CH2/PA7, CH3/PB0, CH4/PB1) */ +#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP ((uint32_t)0x00000800) /*!< Partial remap (CH1/PB4, CH2/PB5, CH3/PB0, CH4/PB1) */ +#define AFIO_MAPR_TIM3_REMAP_FULLREMAP ((uint32_t)0x00000C00) /*!< Full remap (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9) */ + +#define AFIO_MAPR_TIM4_REMAP ((uint32_t)0x00001000) /*!< TIM4_REMAP bit (TIM4 remapping) */ + +#define AFIO_MAPR_CAN_REMAP ((uint32_t)0x00006000) /*!< CAN_REMAP[1:0] bits (CAN Alternate function remapping) */ +#define AFIO_MAPR_CAN_REMAP_0 ((uint32_t)0x00002000) /*!< Bit 0 */ +#define AFIO_MAPR_CAN_REMAP_1 ((uint32_t)0x00004000) /*!< Bit 1 */ + +/*!< CAN_REMAP configuration */ +#define AFIO_MAPR_CAN_REMAP_REMAP1 ((uint32_t)0x00000000) /*!< CANRX mapped to PA11, CANTX mapped to PA12 */ +#define AFIO_MAPR_CAN_REMAP_REMAP2 ((uint32_t)0x00004000) /*!< CANRX mapped to PB8, CANTX mapped to PB9 */ +#define AFIO_MAPR_CAN_REMAP_REMAP3 ((uint32_t)0x00006000) /*!< CANRX mapped to PD0, CANTX mapped to PD1 */ + +#define AFIO_MAPR_PD01_REMAP ((uint32_t)0x00008000) /*!< Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ +#define AFIO_MAPR_TIM5CH4_IREMAP ((uint32_t)0x00010000) /*!< TIM5 Channel4 Internal Remap */ +#define AFIO_MAPR_ADC1_ETRGINJ_REMAP ((uint32_t)0x00020000) /*!< ADC 1 External Trigger Injected Conversion remapping */ +#define AFIO_MAPR_ADC1_ETRGREG_REMAP ((uint32_t)0x00040000) /*!< ADC 1 External Trigger Regular Conversion remapping */ +#define AFIO_MAPR_ADC2_ETRGINJ_REMAP ((uint32_t)0x00080000) /*!< ADC 2 External Trigger Injected Conversion remapping */ +#define AFIO_MAPR_ADC2_ETRGREG_REMAP ((uint32_t)0x00100000) /*!< ADC 2 External Trigger Regular Conversion remapping */ + +/*!< SWJ_CFG configuration */ +#define AFIO_MAPR_SWJ_CFG ((uint32_t)0x07000000) /*!< SWJ_CFG[2:0] bits (Serial Wire JTAG configuration) */ +#define AFIO_MAPR_SWJ_CFG_0 ((uint32_t)0x01000000) /*!< Bit 0 */ +#define AFIO_MAPR_SWJ_CFG_1 ((uint32_t)0x02000000) /*!< Bit 1 */ +#define AFIO_MAPR_SWJ_CFG_2 ((uint32_t)0x04000000) /*!< Bit 2 */ + +#define AFIO_MAPR_SWJ_CFG_RESET ((uint32_t)0x00000000) /*!< Full SWJ (JTAG-DP + SW-DP) : Reset State */ +#define AFIO_MAPR_SWJ_CFG_NOJNTRST ((uint32_t)0x01000000) /*!< Full SWJ (JTAG-DP + SW-DP) but without JNTRST */ +#define AFIO_MAPR_SWJ_CFG_JTAGDISABLE ((uint32_t)0x02000000) /*!< JTAG-DP Disabled and SW-DP Enabled */ +#define AFIO_MAPR_SWJ_CFG_DISABLE ((uint32_t)0x04000000) /*!< JTAG-DP Disabled and SW-DP Disabled */ + +#ifdef STM32F10X_CL +/*!< ETH_REMAP configuration */ + #define AFIO_MAPR_ETH_REMAP ((uint32_t)0x00200000) /*!< SPI3_REMAP bit (Ethernet MAC I/O remapping) */ + +/*!< CAN2_REMAP configuration */ + #define AFIO_MAPR_CAN2_REMAP ((uint32_t)0x00400000) /*!< CAN2_REMAP bit (CAN2 I/O remapping) */ + +/*!< MII_RMII_SEL configuration */ + #define AFIO_MAPR_MII_RMII_SEL ((uint32_t)0x00800000) /*!< MII_RMII_SEL bit (Ethernet MII or RMII selection) */ + +/*!< SPI3_REMAP configuration */ + #define AFIO_MAPR_SPI3_REMAP ((uint32_t)0x10000000) /*!< SPI3_REMAP bit (SPI3 remapping) */ + +/*!< TIM2ITR1_IREMAP configuration */ + #define AFIO_MAPR_TIM2ITR1_IREMAP ((uint32_t)0x20000000) /*!< TIM2ITR1_IREMAP bit (TIM2 internal trigger 1 remapping) */ + +/*!< PTP_PPS_REMAP configuration */ + #define AFIO_MAPR_PTP_PPS_REMAP ((uint32_t)0x20000000) /*!< PTP_PPS_REMAP bit (Ethernet PTP PPS remapping) */ +#endif + +/***************** Bit definition for AFIO_EXTICR1 register *****************/ +#define AFIO_EXTICR1_EXTI0 ((uint16_t)0x000F) /*!< EXTI 0 configuration */ +#define AFIO_EXTICR1_EXTI1 ((uint16_t)0x00F0) /*!< EXTI 1 configuration */ +#define AFIO_EXTICR1_EXTI2 ((uint16_t)0x0F00) /*!< EXTI 2 configuration */ +#define AFIO_EXTICR1_EXTI3 ((uint16_t)0xF000) /*!< EXTI 3 configuration */ + +/*!< EXTI0 configuration */ +#define AFIO_EXTICR1_EXTI0_PA ((uint16_t)0x0000) /*!< PA[0] pin */ +#define AFIO_EXTICR1_EXTI0_PB ((uint16_t)0x0001) /*!< PB[0] pin */ +#define AFIO_EXTICR1_EXTI0_PC ((uint16_t)0x0002) /*!< PC[0] pin */ +#define AFIO_EXTICR1_EXTI0_PD ((uint16_t)0x0003) /*!< PD[0] pin */ +#define AFIO_EXTICR1_EXTI0_PE ((uint16_t)0x0004) /*!< PE[0] pin */ +#define AFIO_EXTICR1_EXTI0_PF ((uint16_t)0x0005) /*!< PF[0] pin */ +#define AFIO_EXTICR1_EXTI0_PG ((uint16_t)0x0006) /*!< PG[0] pin */ + +/*!< EXTI1 configuration */ +#define AFIO_EXTICR1_EXTI1_PA ((uint16_t)0x0000) /*!< PA[1] pin */ +#define AFIO_EXTICR1_EXTI1_PB ((uint16_t)0x0010) /*!< PB[1] pin */ +#define AFIO_EXTICR1_EXTI1_PC ((uint16_t)0x0020) /*!< PC[1] pin */ +#define AFIO_EXTICR1_EXTI1_PD ((uint16_t)0x0030) /*!< PD[1] pin */ +#define AFIO_EXTICR1_EXTI1_PE ((uint16_t)0x0040) /*!< PE[1] pin */ +#define AFIO_EXTICR1_EXTI1_PF ((uint16_t)0x0050) /*!< PF[1] pin */ +#define AFIO_EXTICR1_EXTI1_PG ((uint16_t)0x0060) /*!< PG[1] pin */ + +/*!< EXTI2 configuration */ +#define AFIO_EXTICR1_EXTI2_PA ((uint16_t)0x0000) /*!< PA[2] pin */ +#define AFIO_EXTICR1_EXTI2_PB ((uint16_t)0x0100) /*!< PB[2] pin */ +#define AFIO_EXTICR1_EXTI2_PC ((uint16_t)0x0200) /*!< PC[2] pin */ +#define AFIO_EXTICR1_EXTI2_PD ((uint16_t)0x0300) /*!< PD[2] pin */ +#define AFIO_EXTICR1_EXTI2_PE ((uint16_t)0x0400) /*!< PE[2] pin */ +#define AFIO_EXTICR1_EXTI2_PF ((uint16_t)0x0500) /*!< PF[2] pin */ +#define AFIO_EXTICR1_EXTI2_PG ((uint16_t)0x0600) /*!< PG[2] pin */ + +/*!< EXTI3 configuration */ +#define AFIO_EXTICR1_EXTI3_PA ((uint16_t)0x0000) /*!< PA[3] pin */ +#define AFIO_EXTICR1_EXTI3_PB ((uint16_t)0x1000) /*!< PB[3] pin */ +#define AFIO_EXTICR1_EXTI3_PC ((uint16_t)0x2000) /*!< PC[3] pin */ +#define AFIO_EXTICR1_EXTI3_PD ((uint16_t)0x3000) /*!< PD[3] pin */ +#define AFIO_EXTICR1_EXTI3_PE ((uint16_t)0x4000) /*!< PE[3] pin */ +#define AFIO_EXTICR1_EXTI3_PF ((uint16_t)0x5000) /*!< PF[3] pin */ +#define AFIO_EXTICR1_EXTI3_PG ((uint16_t)0x6000) /*!< PG[3] pin */ + +/***************** Bit definition for AFIO_EXTICR2 register *****************/ +#define AFIO_EXTICR2_EXTI4 ((uint16_t)0x000F) /*!< EXTI 4 configuration */ +#define AFIO_EXTICR2_EXTI5 ((uint16_t)0x00F0) /*!< EXTI 5 configuration */ +#define AFIO_EXTICR2_EXTI6 ((uint16_t)0x0F00) /*!< EXTI 6 configuration */ +#define AFIO_EXTICR2_EXTI7 ((uint16_t)0xF000) /*!< EXTI 7 configuration */ + +/*!< EXTI4 configuration */ +#define AFIO_EXTICR2_EXTI4_PA ((uint16_t)0x0000) /*!< PA[4] pin */ +#define AFIO_EXTICR2_EXTI4_PB ((uint16_t)0x0001) /*!< PB[4] pin */ +#define AFIO_EXTICR2_EXTI4_PC ((uint16_t)0x0002) /*!< PC[4] pin */ +#define AFIO_EXTICR2_EXTI4_PD ((uint16_t)0x0003) /*!< PD[4] pin */ +#define AFIO_EXTICR2_EXTI4_PE ((uint16_t)0x0004) /*!< PE[4] pin */ +#define AFIO_EXTICR2_EXTI4_PF ((uint16_t)0x0005) /*!< PF[4] pin */ +#define AFIO_EXTICR2_EXTI4_PG ((uint16_t)0x0006) /*!< PG[4] pin */ + +/* EXTI5 configuration */ +#define AFIO_EXTICR2_EXTI5_PA ((uint16_t)0x0000) /*!< PA[5] pin */ +#define AFIO_EXTICR2_EXTI5_PB ((uint16_t)0x0010) /*!< PB[5] pin */ +#define AFIO_EXTICR2_EXTI5_PC ((uint16_t)0x0020) /*!< PC[5] pin */ +#define AFIO_EXTICR2_EXTI5_PD ((uint16_t)0x0030) /*!< PD[5] pin */ +#define AFIO_EXTICR2_EXTI5_PE ((uint16_t)0x0040) /*!< PE[5] pin */ +#define AFIO_EXTICR2_EXTI5_PF ((uint16_t)0x0050) /*!< PF[5] pin */ +#define AFIO_EXTICR2_EXTI5_PG ((uint16_t)0x0060) /*!< PG[5] pin */ + +/*!< EXTI6 configuration */ +#define AFIO_EXTICR2_EXTI6_PA ((uint16_t)0x0000) /*!< PA[6] pin */ +#define AFIO_EXTICR2_EXTI6_PB ((uint16_t)0x0100) /*!< PB[6] pin */ +#define AFIO_EXTICR2_EXTI6_PC ((uint16_t)0x0200) /*!< PC[6] pin */ +#define AFIO_EXTICR2_EXTI6_PD ((uint16_t)0x0300) /*!< PD[6] pin */ +#define AFIO_EXTICR2_EXTI6_PE ((uint16_t)0x0400) /*!< PE[6] pin */ +#define AFIO_EXTICR2_EXTI6_PF ((uint16_t)0x0500) /*!< PF[6] pin */ +#define AFIO_EXTICR2_EXTI6_PG ((uint16_t)0x0600) /*!< PG[6] pin */ + +/*!< EXTI7 configuration */ +#define AFIO_EXTICR2_EXTI7_PA ((uint16_t)0x0000) /*!< PA[7] pin */ +#define AFIO_EXTICR2_EXTI7_PB ((uint16_t)0x1000) /*!< PB[7] pin */ +#define AFIO_EXTICR2_EXTI7_PC ((uint16_t)0x2000) /*!< PC[7] pin */ +#define AFIO_EXTICR2_EXTI7_PD ((uint16_t)0x3000) /*!< PD[7] pin */ +#define AFIO_EXTICR2_EXTI7_PE ((uint16_t)0x4000) /*!< PE[7] pin */ +#define AFIO_EXTICR2_EXTI7_PF ((uint16_t)0x5000) /*!< PF[7] pin */ +#define AFIO_EXTICR2_EXTI7_PG ((uint16_t)0x6000) /*!< PG[7] pin */ + +/***************** Bit definition for AFIO_EXTICR3 register *****************/ +#define AFIO_EXTICR3_EXTI8 ((uint16_t)0x000F) /*!< EXTI 8 configuration */ +#define AFIO_EXTICR3_EXTI9 ((uint16_t)0x00F0) /*!< EXTI 9 configuration */ +#define AFIO_EXTICR3_EXTI10 ((uint16_t)0x0F00) /*!< EXTI 10 configuration */ +#define AFIO_EXTICR3_EXTI11 ((uint16_t)0xF000) /*!< EXTI 11 configuration */ + +/*!< EXTI8 configuration */ +#define AFIO_EXTICR3_EXTI8_PA ((uint16_t)0x0000) /*!< PA[8] pin */ +#define AFIO_EXTICR3_EXTI8_PB ((uint16_t)0x0001) /*!< PB[8] pin */ +#define AFIO_EXTICR3_EXTI8_PC ((uint16_t)0x0002) /*!< PC[8] pin */ +#define AFIO_EXTICR3_EXTI8_PD ((uint16_t)0x0003) /*!< PD[8] pin */ +#define AFIO_EXTICR3_EXTI8_PE ((uint16_t)0x0004) /*!< PE[8] pin */ +#define AFIO_EXTICR3_EXTI8_PF ((uint16_t)0x0005) /*!< PF[8] pin */ +#define AFIO_EXTICR3_EXTI8_PG ((uint16_t)0x0006) /*!< PG[8] pin */ + +/*!< EXTI9 configuration */ +#define AFIO_EXTICR3_EXTI9_PA ((uint16_t)0x0000) /*!< PA[9] pin */ +#define AFIO_EXTICR3_EXTI9_PB ((uint16_t)0x0010) /*!< PB[9] pin */ +#define AFIO_EXTICR3_EXTI9_PC ((uint16_t)0x0020) /*!< PC[9] pin */ +#define AFIO_EXTICR3_EXTI9_PD ((uint16_t)0x0030) /*!< PD[9] pin */ +#define AFIO_EXTICR3_EXTI9_PE ((uint16_t)0x0040) /*!< PE[9] pin */ +#define AFIO_EXTICR3_EXTI9_PF ((uint16_t)0x0050) /*!< PF[9] pin */ +#define AFIO_EXTICR3_EXTI9_PG ((uint16_t)0x0060) /*!< PG[9] pin */ + +/*!< EXTI10 configuration */ +#define AFIO_EXTICR3_EXTI10_PA ((uint16_t)0x0000) /*!< PA[10] pin */ +#define AFIO_EXTICR3_EXTI10_PB ((uint16_t)0x0100) /*!< PB[10] pin */ +#define AFIO_EXTICR3_EXTI10_PC ((uint16_t)0x0200) /*!< PC[10] pin */ +#define AFIO_EXTICR3_EXTI10_PD ((uint16_t)0x0300) /*!< PD[10] pin */ +#define AFIO_EXTICR3_EXTI10_PE ((uint16_t)0x0400) /*!< PE[10] pin */ +#define AFIO_EXTICR3_EXTI10_PF ((uint16_t)0x0500) /*!< PF[10] pin */ +#define AFIO_EXTICR3_EXTI10_PG ((uint16_t)0x0600) /*!< PG[10] pin */ + +/*!< EXTI11 configuration */ +#define AFIO_EXTICR3_EXTI11_PA ((uint16_t)0x0000) /*!< PA[11] pin */ +#define AFIO_EXTICR3_EXTI11_PB ((uint16_t)0x1000) /*!< PB[11] pin */ +#define AFIO_EXTICR3_EXTI11_PC ((uint16_t)0x2000) /*!< PC[11] pin */ +#define AFIO_EXTICR3_EXTI11_PD ((uint16_t)0x3000) /*!< PD[11] pin */ +#define AFIO_EXTICR3_EXTI11_PE ((uint16_t)0x4000) /*!< PE[11] pin */ +#define AFIO_EXTICR3_EXTI11_PF ((uint16_t)0x5000) /*!< PF[11] pin */ +#define AFIO_EXTICR3_EXTI11_PG ((uint16_t)0x6000) /*!< PG[11] pin */ + +/***************** Bit definition for AFIO_EXTICR4 register *****************/ +#define AFIO_EXTICR4_EXTI12 ((uint16_t)0x000F) /*!< EXTI 12 configuration */ +#define AFIO_EXTICR4_EXTI13 ((uint16_t)0x00F0) /*!< EXTI 13 configuration */ +#define AFIO_EXTICR4_EXTI14 ((uint16_t)0x0F00) /*!< EXTI 14 configuration */ +#define AFIO_EXTICR4_EXTI15 ((uint16_t)0xF000) /*!< EXTI 15 configuration */ + +/* EXTI12 configuration */ +#define AFIO_EXTICR4_EXTI12_PA ((uint16_t)0x0000) /*!< PA[12] pin */ +#define AFIO_EXTICR4_EXTI12_PB ((uint16_t)0x0001) /*!< PB[12] pin */ +#define AFIO_EXTICR4_EXTI12_PC ((uint16_t)0x0002) /*!< PC[12] pin */ +#define AFIO_EXTICR4_EXTI12_PD ((uint16_t)0x0003) /*!< PD[12] pin */ +#define AFIO_EXTICR4_EXTI12_PE ((uint16_t)0x0004) /*!< PE[12] pin */ +#define AFIO_EXTICR4_EXTI12_PF ((uint16_t)0x0005) /*!< PF[12] pin */ +#define AFIO_EXTICR4_EXTI12_PG ((uint16_t)0x0006) /*!< PG[12] pin */ + +/* EXTI13 configuration */ +#define AFIO_EXTICR4_EXTI13_PA ((uint16_t)0x0000) /*!< PA[13] pin */ +#define AFIO_EXTICR4_EXTI13_PB ((uint16_t)0x0010) /*!< PB[13] pin */ +#define AFIO_EXTICR4_EXTI13_PC ((uint16_t)0x0020) /*!< PC[13] pin */ +#define AFIO_EXTICR4_EXTI13_PD ((uint16_t)0x0030) /*!< PD[13] pin */ +#define AFIO_EXTICR4_EXTI13_PE ((uint16_t)0x0040) /*!< PE[13] pin */ +#define AFIO_EXTICR4_EXTI13_PF ((uint16_t)0x0050) /*!< PF[13] pin */ +#define AFIO_EXTICR4_EXTI13_PG ((uint16_t)0x0060) /*!< PG[13] pin */ + +/*!< EXTI14 configuration */ +#define AFIO_EXTICR4_EXTI14_PA ((uint16_t)0x0000) /*!< PA[14] pin */ +#define AFIO_EXTICR4_EXTI14_PB ((uint16_t)0x0100) /*!< PB[14] pin */ +#define AFIO_EXTICR4_EXTI14_PC ((uint16_t)0x0200) /*!< PC[14] pin */ +#define AFIO_EXTICR4_EXTI14_PD ((uint16_t)0x0300) /*!< PD[14] pin */ +#define AFIO_EXTICR4_EXTI14_PE ((uint16_t)0x0400) /*!< PE[14] pin */ +#define AFIO_EXTICR4_EXTI14_PF ((uint16_t)0x0500) /*!< PF[14] pin */ +#define AFIO_EXTICR4_EXTI14_PG ((uint16_t)0x0600) /*!< PG[14] pin */ + +/*!< EXTI15 configuration */ +#define AFIO_EXTICR4_EXTI15_PA ((uint16_t)0x0000) /*!< PA[15] pin */ +#define AFIO_EXTICR4_EXTI15_PB ((uint16_t)0x1000) /*!< PB[15] pin */ +#define AFIO_EXTICR4_EXTI15_PC ((uint16_t)0x2000) /*!< PC[15] pin */ +#define AFIO_EXTICR4_EXTI15_PD ((uint16_t)0x3000) /*!< PD[15] pin */ +#define AFIO_EXTICR4_EXTI15_PE ((uint16_t)0x4000) /*!< PE[15] pin */ +#define AFIO_EXTICR4_EXTI15_PF ((uint16_t)0x5000) /*!< PF[15] pin */ +#define AFIO_EXTICR4_EXTI15_PG ((uint16_t)0x6000) /*!< PG[15] pin */ + +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) +/****************** Bit definition for AFIO_MAPR2 register ******************/ +#define AFIO_MAPR2_TIM15_REMAP ((uint32_t)0x00000001) /*!< TIM15 remapping */ +#define AFIO_MAPR2_TIM16_REMAP ((uint32_t)0x00000002) /*!< TIM16 remapping */ +#define AFIO_MAPR2_TIM17_REMAP ((uint32_t)0x00000004) /*!< TIM17 remapping */ +#define AFIO_MAPR2_CEC_REMAP ((uint32_t)0x00000008) /*!< CEC remapping */ +#define AFIO_MAPR2_TIM1_DMA_REMAP ((uint32_t)0x00000010) /*!< TIM1_DMA remapping */ +#endif + +#ifdef STM32F10X_XL +/****************** Bit definition for AFIO_MAPR2 register ******************/ +#define AFIO_MAPR2_TIM9_REMAP ((uint32_t)0x00000020) /*!< TIM9 remapping */ +#define AFIO_MAPR2_TIM10_REMAP ((uint32_t)0x00000040) /*!< TIM10 remapping */ +#define AFIO_MAPR2_TIM11_REMAP ((uint32_t)0x00000080) /*!< TIM11 remapping */ +#define AFIO_MAPR2_TIM13_REMAP ((uint32_t)0x00000100) /*!< TIM13 remapping */ +#define AFIO_MAPR2_TIM14_REMAP ((uint32_t)0x00000200) /*!< TIM14 remapping */ +#define AFIO_MAPR2_FSMC_NADV_REMAP ((uint32_t)0x00000400) /*!< FSMC NADV remapping */ +#endif + +/******************************************************************************/ +/* */ +/* SystemTick */ +/* */ +/******************************************************************************/ + +/***************** Bit definition for SysTick_CTRL register *****************/ +#define SysTick_CTRL_ENABLE ((uint32_t)0x00000001) /*!< Counter enable */ +#define SysTick_CTRL_TICKINT ((uint32_t)0x00000002) /*!< Counting down to 0 pends the SysTick handler */ +#define SysTick_CTRL_CLKSOURCE ((uint32_t)0x00000004) /*!< Clock source */ +#define SysTick_CTRL_COUNTFLAG ((uint32_t)0x00010000) /*!< Count Flag */ + +/***************** Bit definition for SysTick_LOAD register *****************/ +#define SysTick_LOAD_RELOAD ((uint32_t)0x00FFFFFF) /*!< Value to load into the SysTick Current Value Register when the counter reaches 0 */ + +/***************** Bit definition for SysTick_VAL register ******************/ +#define SysTick_VAL_CURRENT ((uint32_t)0x00FFFFFF) /*!< Current value at the time the register is accessed */ + +/***************** Bit definition for SysTick_CALIB register ****************/ +#define SysTick_CALIB_TENMS ((uint32_t)0x00FFFFFF) /*!< Reload value to use for 10ms timing */ +#define SysTick_CALIB_SKEW ((uint32_t)0x40000000) /*!< Calibration value is not exactly 10 ms */ +#define SysTick_CALIB_NOREF ((uint32_t)0x80000000) /*!< The reference clock is not provided */ + +/******************************************************************************/ +/* */ +/* Nested Vectored Interrupt Controller */ +/* */ +/******************************************************************************/ + +/****************** Bit definition for NVIC_ISER register *******************/ +#define NVIC_ISER_SETENA ((uint32_t)0xFFFFFFFF) /*!< Interrupt set enable bits */ +#define NVIC_ISER_SETENA_0 ((uint32_t)0x00000001) /*!< bit 0 */ +#define NVIC_ISER_SETENA_1 ((uint32_t)0x00000002) /*!< bit 1 */ +#define NVIC_ISER_SETENA_2 ((uint32_t)0x00000004) /*!< bit 2 */ +#define NVIC_ISER_SETENA_3 ((uint32_t)0x00000008) /*!< bit 3 */ +#define NVIC_ISER_SETENA_4 ((uint32_t)0x00000010) /*!< bit 4 */ +#define NVIC_ISER_SETENA_5 ((uint32_t)0x00000020) /*!< bit 5 */ +#define NVIC_ISER_SETENA_6 ((uint32_t)0x00000040) /*!< bit 6 */ +#define NVIC_ISER_SETENA_7 ((uint32_t)0x00000080) /*!< bit 7 */ +#define NVIC_ISER_SETENA_8 ((uint32_t)0x00000100) /*!< bit 8 */ +#define NVIC_ISER_SETENA_9 ((uint32_t)0x00000200) /*!< bit 9 */ +#define NVIC_ISER_SETENA_10 ((uint32_t)0x00000400) /*!< bit 10 */ +#define NVIC_ISER_SETENA_11 ((uint32_t)0x00000800) /*!< bit 11 */ +#define NVIC_ISER_SETENA_12 ((uint32_t)0x00001000) /*!< bit 12 */ +#define NVIC_ISER_SETENA_13 ((uint32_t)0x00002000) /*!< bit 13 */ +#define NVIC_ISER_SETENA_14 ((uint32_t)0x00004000) /*!< bit 14 */ +#define NVIC_ISER_SETENA_15 ((uint32_t)0x00008000) /*!< bit 15 */ +#define NVIC_ISER_SETENA_16 ((uint32_t)0x00010000) /*!< bit 16 */ +#define NVIC_ISER_SETENA_17 ((uint32_t)0x00020000) /*!< bit 17 */ +#define NVIC_ISER_SETENA_18 ((uint32_t)0x00040000) /*!< bit 18 */ +#define NVIC_ISER_SETENA_19 ((uint32_t)0x00080000) /*!< bit 19 */ +#define NVIC_ISER_SETENA_20 ((uint32_t)0x00100000) /*!< bit 20 */ +#define NVIC_ISER_SETENA_21 ((uint32_t)0x00200000) /*!< bit 21 */ +#define NVIC_ISER_SETENA_22 ((uint32_t)0x00400000) /*!< bit 22 */ +#define NVIC_ISER_SETENA_23 ((uint32_t)0x00800000) /*!< bit 23 */ +#define NVIC_ISER_SETENA_24 ((uint32_t)0x01000000) /*!< bit 24 */ +#define NVIC_ISER_SETENA_25 ((uint32_t)0x02000000) /*!< bit 25 */ +#define NVIC_ISER_SETENA_26 ((uint32_t)0x04000000) /*!< bit 26 */ +#define NVIC_ISER_SETENA_27 ((uint32_t)0x08000000) /*!< bit 27 */ +#define NVIC_ISER_SETENA_28 ((uint32_t)0x10000000) /*!< bit 28 */ +#define NVIC_ISER_SETENA_29 ((uint32_t)0x20000000) /*!< bit 29 */ +#define NVIC_ISER_SETENA_30 ((uint32_t)0x40000000) /*!< bit 30 */ +#define NVIC_ISER_SETENA_31 ((uint32_t)0x80000000) /*!< bit 31 */ + +/****************** Bit definition for NVIC_ICER register *******************/ +#define NVIC_ICER_CLRENA ((uint32_t)0xFFFFFFFF) /*!< Interrupt clear-enable bits */ +#define NVIC_ICER_CLRENA_0 ((uint32_t)0x00000001) /*!< bit 0 */ +#define NVIC_ICER_CLRENA_1 ((uint32_t)0x00000002) /*!< bit 1 */ +#define NVIC_ICER_CLRENA_2 ((uint32_t)0x00000004) /*!< bit 2 */ +#define NVIC_ICER_CLRENA_3 ((uint32_t)0x00000008) /*!< bit 3 */ +#define NVIC_ICER_CLRENA_4 ((uint32_t)0x00000010) /*!< bit 4 */ +#define NVIC_ICER_CLRENA_5 ((uint32_t)0x00000020) /*!< bit 5 */ +#define NVIC_ICER_CLRENA_6 ((uint32_t)0x00000040) /*!< bit 6 */ +#define NVIC_ICER_CLRENA_7 ((uint32_t)0x00000080) /*!< bit 7 */ +#define NVIC_ICER_CLRENA_8 ((uint32_t)0x00000100) /*!< bit 8 */ +#define NVIC_ICER_CLRENA_9 ((uint32_t)0x00000200) /*!< bit 9 */ +#define NVIC_ICER_CLRENA_10 ((uint32_t)0x00000400) /*!< bit 10 */ +#define NVIC_ICER_CLRENA_11 ((uint32_t)0x00000800) /*!< bit 11 */ +#define NVIC_ICER_CLRENA_12 ((uint32_t)0x00001000) /*!< bit 12 */ +#define NVIC_ICER_CLRENA_13 ((uint32_t)0x00002000) /*!< bit 13 */ +#define NVIC_ICER_CLRENA_14 ((uint32_t)0x00004000) /*!< bit 14 */ +#define NVIC_ICER_CLRENA_15 ((uint32_t)0x00008000) /*!< bit 15 */ +#define NVIC_ICER_CLRENA_16 ((uint32_t)0x00010000) /*!< bit 16 */ +#define NVIC_ICER_CLRENA_17 ((uint32_t)0x00020000) /*!< bit 17 */ +#define NVIC_ICER_CLRENA_18 ((uint32_t)0x00040000) /*!< bit 18 */ +#define NVIC_ICER_CLRENA_19 ((uint32_t)0x00080000) /*!< bit 19 */ +#define NVIC_ICER_CLRENA_20 ((uint32_t)0x00100000) /*!< bit 20 */ +#define NVIC_ICER_CLRENA_21 ((uint32_t)0x00200000) /*!< bit 21 */ +#define NVIC_ICER_CLRENA_22 ((uint32_t)0x00400000) /*!< bit 22 */ +#define NVIC_ICER_CLRENA_23 ((uint32_t)0x00800000) /*!< bit 23 */ +#define NVIC_ICER_CLRENA_24 ((uint32_t)0x01000000) /*!< bit 24 */ +#define NVIC_ICER_CLRENA_25 ((uint32_t)0x02000000) /*!< bit 25 */ +#define NVIC_ICER_CLRENA_26 ((uint32_t)0x04000000) /*!< bit 26 */ +#define NVIC_ICER_CLRENA_27 ((uint32_t)0x08000000) /*!< bit 27 */ +#define NVIC_ICER_CLRENA_28 ((uint32_t)0x10000000) /*!< bit 28 */ +#define NVIC_ICER_CLRENA_29 ((uint32_t)0x20000000) /*!< bit 29 */ +#define NVIC_ICER_CLRENA_30 ((uint32_t)0x40000000) /*!< bit 30 */ +#define NVIC_ICER_CLRENA_31 ((uint32_t)0x80000000) /*!< bit 31 */ + +/****************** Bit definition for NVIC_ISPR register *******************/ +#define NVIC_ISPR_SETPEND ((uint32_t)0xFFFFFFFF) /*!< Interrupt set-pending bits */ +#define NVIC_ISPR_SETPEND_0 ((uint32_t)0x00000001) /*!< bit 0 */ +#define NVIC_ISPR_SETPEND_1 ((uint32_t)0x00000002) /*!< bit 1 */ +#define NVIC_ISPR_SETPEND_2 ((uint32_t)0x00000004) /*!< bit 2 */ +#define NVIC_ISPR_SETPEND_3 ((uint32_t)0x00000008) /*!< bit 3 */ +#define NVIC_ISPR_SETPEND_4 ((uint32_t)0x00000010) /*!< bit 4 */ +#define NVIC_ISPR_SETPEND_5 ((uint32_t)0x00000020) /*!< bit 5 */ +#define NVIC_ISPR_SETPEND_6 ((uint32_t)0x00000040) /*!< bit 6 */ +#define NVIC_ISPR_SETPEND_7 ((uint32_t)0x00000080) /*!< bit 7 */ +#define NVIC_ISPR_SETPEND_8 ((uint32_t)0x00000100) /*!< bit 8 */ +#define NVIC_ISPR_SETPEND_9 ((uint32_t)0x00000200) /*!< bit 9 */ +#define NVIC_ISPR_SETPEND_10 ((uint32_t)0x00000400) /*!< bit 10 */ +#define NVIC_ISPR_SETPEND_11 ((uint32_t)0x00000800) /*!< bit 11 */ +#define NVIC_ISPR_SETPEND_12 ((uint32_t)0x00001000) /*!< bit 12 */ +#define NVIC_ISPR_SETPEND_13 ((uint32_t)0x00002000) /*!< bit 13 */ +#define NVIC_ISPR_SETPEND_14 ((uint32_t)0x00004000) /*!< bit 14 */ +#define NVIC_ISPR_SETPEND_15 ((uint32_t)0x00008000) /*!< bit 15 */ +#define NVIC_ISPR_SETPEND_16 ((uint32_t)0x00010000) /*!< bit 16 */ +#define NVIC_ISPR_SETPEND_17 ((uint32_t)0x00020000) /*!< bit 17 */ +#define NVIC_ISPR_SETPEND_18 ((uint32_t)0x00040000) /*!< bit 18 */ +#define NVIC_ISPR_SETPEND_19 ((uint32_t)0x00080000) /*!< bit 19 */ +#define NVIC_ISPR_SETPEND_20 ((uint32_t)0x00100000) /*!< bit 20 */ +#define NVIC_ISPR_SETPEND_21 ((uint32_t)0x00200000) /*!< bit 21 */ +#define NVIC_ISPR_SETPEND_22 ((uint32_t)0x00400000) /*!< bit 22 */ +#define NVIC_ISPR_SETPEND_23 ((uint32_t)0x00800000) /*!< bit 23 */ +#define NVIC_ISPR_SETPEND_24 ((uint32_t)0x01000000) /*!< bit 24 */ +#define NVIC_ISPR_SETPEND_25 ((uint32_t)0x02000000) /*!< bit 25 */ +#define NVIC_ISPR_SETPEND_26 ((uint32_t)0x04000000) /*!< bit 26 */ +#define NVIC_ISPR_SETPEND_27 ((uint32_t)0x08000000) /*!< bit 27 */ +#define NVIC_ISPR_SETPEND_28 ((uint32_t)0x10000000) /*!< bit 28 */ +#define NVIC_ISPR_SETPEND_29 ((uint32_t)0x20000000) /*!< bit 29 */ +#define NVIC_ISPR_SETPEND_30 ((uint32_t)0x40000000) /*!< bit 30 */ +#define NVIC_ISPR_SETPEND_31 ((uint32_t)0x80000000) /*!< bit 31 */ + +/****************** Bit definition for NVIC_ICPR register *******************/ +#define NVIC_ICPR_CLRPEND ((uint32_t)0xFFFFFFFF) /*!< Interrupt clear-pending bits */ +#define NVIC_ICPR_CLRPEND_0 ((uint32_t)0x00000001) /*!< bit 0 */ +#define NVIC_ICPR_CLRPEND_1 ((uint32_t)0x00000002) /*!< bit 1 */ +#define NVIC_ICPR_CLRPEND_2 ((uint32_t)0x00000004) /*!< bit 2 */ +#define NVIC_ICPR_CLRPEND_3 ((uint32_t)0x00000008) /*!< bit 3 */ +#define NVIC_ICPR_CLRPEND_4 ((uint32_t)0x00000010) /*!< bit 4 */ +#define NVIC_ICPR_CLRPEND_5 ((uint32_t)0x00000020) /*!< bit 5 */ +#define NVIC_ICPR_CLRPEND_6 ((uint32_t)0x00000040) /*!< bit 6 */ +#define NVIC_ICPR_CLRPEND_7 ((uint32_t)0x00000080) /*!< bit 7 */ +#define NVIC_ICPR_CLRPEND_8 ((uint32_t)0x00000100) /*!< bit 8 */ +#define NVIC_ICPR_CLRPEND_9 ((uint32_t)0x00000200) /*!< bit 9 */ +#define NVIC_ICPR_CLRPEND_10 ((uint32_t)0x00000400) /*!< bit 10 */ +#define NVIC_ICPR_CLRPEND_11 ((uint32_t)0x00000800) /*!< bit 11 */ +#define NVIC_ICPR_CLRPEND_12 ((uint32_t)0x00001000) /*!< bit 12 */ +#define NVIC_ICPR_CLRPEND_13 ((uint32_t)0x00002000) /*!< bit 13 */ +#define NVIC_ICPR_CLRPEND_14 ((uint32_t)0x00004000) /*!< bit 14 */ +#define NVIC_ICPR_CLRPEND_15 ((uint32_t)0x00008000) /*!< bit 15 */ +#define NVIC_ICPR_CLRPEND_16 ((uint32_t)0x00010000) /*!< bit 16 */ +#define NVIC_ICPR_CLRPEND_17 ((uint32_t)0x00020000) /*!< bit 17 */ +#define NVIC_ICPR_CLRPEND_18 ((uint32_t)0x00040000) /*!< bit 18 */ +#define NVIC_ICPR_CLRPEND_19 ((uint32_t)0x00080000) /*!< bit 19 */ +#define NVIC_ICPR_CLRPEND_20 ((uint32_t)0x00100000) /*!< bit 20 */ +#define NVIC_ICPR_CLRPEND_21 ((uint32_t)0x00200000) /*!< bit 21 */ +#define NVIC_ICPR_CLRPEND_22 ((uint32_t)0x00400000) /*!< bit 22 */ +#define NVIC_ICPR_CLRPEND_23 ((uint32_t)0x00800000) /*!< bit 23 */ +#define NVIC_ICPR_CLRPEND_24 ((uint32_t)0x01000000) /*!< bit 24 */ +#define NVIC_ICPR_CLRPEND_25 ((uint32_t)0x02000000) /*!< bit 25 */ +#define NVIC_ICPR_CLRPEND_26 ((uint32_t)0x04000000) /*!< bit 26 */ +#define NVIC_ICPR_CLRPEND_27 ((uint32_t)0x08000000) /*!< bit 27 */ +#define NVIC_ICPR_CLRPEND_28 ((uint32_t)0x10000000) /*!< bit 28 */ +#define NVIC_ICPR_CLRPEND_29 ((uint32_t)0x20000000) /*!< bit 29 */ +#define NVIC_ICPR_CLRPEND_30 ((uint32_t)0x40000000) /*!< bit 30 */ +#define NVIC_ICPR_CLRPEND_31 ((uint32_t)0x80000000) /*!< bit 31 */ + +/****************** Bit definition for NVIC_IABR register *******************/ +#define NVIC_IABR_ACTIVE ((uint32_t)0xFFFFFFFF) /*!< Interrupt active flags */ +#define NVIC_IABR_ACTIVE_0 ((uint32_t)0x00000001) /*!< bit 0 */ +#define NVIC_IABR_ACTIVE_1 ((uint32_t)0x00000002) /*!< bit 1 */ +#define NVIC_IABR_ACTIVE_2 ((uint32_t)0x00000004) /*!< bit 2 */ +#define NVIC_IABR_ACTIVE_3 ((uint32_t)0x00000008) /*!< bit 3 */ +#define NVIC_IABR_ACTIVE_4 ((uint32_t)0x00000010) /*!< bit 4 */ +#define NVIC_IABR_ACTIVE_5 ((uint32_t)0x00000020) /*!< bit 5 */ +#define NVIC_IABR_ACTIVE_6 ((uint32_t)0x00000040) /*!< bit 6 */ +#define NVIC_IABR_ACTIVE_7 ((uint32_t)0x00000080) /*!< bit 7 */ +#define NVIC_IABR_ACTIVE_8 ((uint32_t)0x00000100) /*!< bit 8 */ +#define NVIC_IABR_ACTIVE_9 ((uint32_t)0x00000200) /*!< bit 9 */ +#define NVIC_IABR_ACTIVE_10 ((uint32_t)0x00000400) /*!< bit 10 */ +#define NVIC_IABR_ACTIVE_11 ((uint32_t)0x00000800) /*!< bit 11 */ +#define NVIC_IABR_ACTIVE_12 ((uint32_t)0x00001000) /*!< bit 12 */ +#define NVIC_IABR_ACTIVE_13 ((uint32_t)0x00002000) /*!< bit 13 */ +#define NVIC_IABR_ACTIVE_14 ((uint32_t)0x00004000) /*!< bit 14 */ +#define NVIC_IABR_ACTIVE_15 ((uint32_t)0x00008000) /*!< bit 15 */ +#define NVIC_IABR_ACTIVE_16 ((uint32_t)0x00010000) /*!< bit 16 */ +#define NVIC_IABR_ACTIVE_17 ((uint32_t)0x00020000) /*!< bit 17 */ +#define NVIC_IABR_ACTIVE_18 ((uint32_t)0x00040000) /*!< bit 18 */ +#define NVIC_IABR_ACTIVE_19 ((uint32_t)0x00080000) /*!< bit 19 */ +#define NVIC_IABR_ACTIVE_20 ((uint32_t)0x00100000) /*!< bit 20 */ +#define NVIC_IABR_ACTIVE_21 ((uint32_t)0x00200000) /*!< bit 21 */ +#define NVIC_IABR_ACTIVE_22 ((uint32_t)0x00400000) /*!< bit 22 */ +#define NVIC_IABR_ACTIVE_23 ((uint32_t)0x00800000) /*!< bit 23 */ +#define NVIC_IABR_ACTIVE_24 ((uint32_t)0x01000000) /*!< bit 24 */ +#define NVIC_IABR_ACTIVE_25 ((uint32_t)0x02000000) /*!< bit 25 */ +#define NVIC_IABR_ACTIVE_26 ((uint32_t)0x04000000) /*!< bit 26 */ +#define NVIC_IABR_ACTIVE_27 ((uint32_t)0x08000000) /*!< bit 27 */ +#define NVIC_IABR_ACTIVE_28 ((uint32_t)0x10000000) /*!< bit 28 */ +#define NVIC_IABR_ACTIVE_29 ((uint32_t)0x20000000) /*!< bit 29 */ +#define NVIC_IABR_ACTIVE_30 ((uint32_t)0x40000000) /*!< bit 30 */ +#define NVIC_IABR_ACTIVE_31 ((uint32_t)0x80000000) /*!< bit 31 */ + +/****************** Bit definition for NVIC_PRI0 register *******************/ +#define NVIC_IPR0_PRI_0 ((uint32_t)0x000000FF) /*!< Priority of interrupt 0 */ +#define NVIC_IPR0_PRI_1 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 1 */ +#define NVIC_IPR0_PRI_2 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 2 */ +#define NVIC_IPR0_PRI_3 ((uint32_t)0xFF000000) /*!< Priority of interrupt 3 */ + +/****************** Bit definition for NVIC_PRI1 register *******************/ +#define NVIC_IPR1_PRI_4 ((uint32_t)0x000000FF) /*!< Priority of interrupt 4 */ +#define NVIC_IPR1_PRI_5 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 5 */ +#define NVIC_IPR1_PRI_6 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 6 */ +#define NVIC_IPR1_PRI_7 ((uint32_t)0xFF000000) /*!< Priority of interrupt 7 */ + +/****************** Bit definition for NVIC_PRI2 register *******************/ +#define NVIC_IPR2_PRI_8 ((uint32_t)0x000000FF) /*!< Priority of interrupt 8 */ +#define NVIC_IPR2_PRI_9 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 9 */ +#define NVIC_IPR2_PRI_10 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 10 */ +#define NVIC_IPR2_PRI_11 ((uint32_t)0xFF000000) /*!< Priority of interrupt 11 */ + +/****************** Bit definition for NVIC_PRI3 register *******************/ +#define NVIC_IPR3_PRI_12 ((uint32_t)0x000000FF) /*!< Priority of interrupt 12 */ +#define NVIC_IPR3_PRI_13 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 13 */ +#define NVIC_IPR3_PRI_14 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 14 */ +#define NVIC_IPR3_PRI_15 ((uint32_t)0xFF000000) /*!< Priority of interrupt 15 */ + +/****************** Bit definition for NVIC_PRI4 register *******************/ +#define NVIC_IPR4_PRI_16 ((uint32_t)0x000000FF) /*!< Priority of interrupt 16 */ +#define NVIC_IPR4_PRI_17 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 17 */ +#define NVIC_IPR4_PRI_18 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 18 */ +#define NVIC_IPR4_PRI_19 ((uint32_t)0xFF000000) /*!< Priority of interrupt 19 */ + +/****************** Bit definition for NVIC_PRI5 register *******************/ +#define NVIC_IPR5_PRI_20 ((uint32_t)0x000000FF) /*!< Priority of interrupt 20 */ +#define NVIC_IPR5_PRI_21 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 21 */ +#define NVIC_IPR5_PRI_22 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 22 */ +#define NVIC_IPR5_PRI_23 ((uint32_t)0xFF000000) /*!< Priority of interrupt 23 */ + +/****************** Bit definition for NVIC_PRI6 register *******************/ +#define NVIC_IPR6_PRI_24 ((uint32_t)0x000000FF) /*!< Priority of interrupt 24 */ +#define NVIC_IPR6_PRI_25 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 25 */ +#define NVIC_IPR6_PRI_26 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 26 */ +#define NVIC_IPR6_PRI_27 ((uint32_t)0xFF000000) /*!< Priority of interrupt 27 */ + +/****************** Bit definition for NVIC_PRI7 register *******************/ +#define NVIC_IPR7_PRI_28 ((uint32_t)0x000000FF) /*!< Priority of interrupt 28 */ +#define NVIC_IPR7_PRI_29 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 29 */ +#define NVIC_IPR7_PRI_30 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 30 */ +#define NVIC_IPR7_PRI_31 ((uint32_t)0xFF000000) /*!< Priority of interrupt 31 */ + +/****************** Bit definition for SCB_CPUID register *******************/ +#define SCB_CPUID_REVISION ((uint32_t)0x0000000F) /*!< Implementation defined revision number */ +#define SCB_CPUID_PARTNO ((uint32_t)0x0000FFF0) /*!< Number of processor within family */ +#define SCB_CPUID_Constant ((uint32_t)0x000F0000) /*!< Reads as 0x0F */ +#define SCB_CPUID_VARIANT ((uint32_t)0x00F00000) /*!< Implementation defined variant number */ +#define SCB_CPUID_IMPLEMENTER ((uint32_t)0xFF000000) /*!< Implementer code. ARM is 0x41 */ + +/******************* Bit definition for SCB_ICSR register *******************/ +#define SCB_ICSR_VECTACTIVE ((uint32_t)0x000001FF) /*!< Active ISR number field */ +#define SCB_ICSR_RETTOBASE ((uint32_t)0x00000800) /*!< All active exceptions minus the IPSR_current_exception yields the empty set */ +#define SCB_ICSR_VECTPENDING ((uint32_t)0x003FF000) /*!< Pending ISR number field */ +#define SCB_ICSR_ISRPENDING ((uint32_t)0x00400000) /*!< Interrupt pending flag */ +#define SCB_ICSR_ISRPREEMPT ((uint32_t)0x00800000) /*!< It indicates that a pending interrupt becomes active in the next running cycle */ +#define SCB_ICSR_PENDSTCLR ((uint32_t)0x02000000) /*!< Clear pending SysTick bit */ +#define SCB_ICSR_PENDSTSET ((uint32_t)0x04000000) /*!< Set pending SysTick bit */ +#define SCB_ICSR_PENDSVCLR ((uint32_t)0x08000000) /*!< Clear pending pendSV bit */ +#define SCB_ICSR_PENDSVSET ((uint32_t)0x10000000) /*!< Set pending pendSV bit */ +#define SCB_ICSR_NMIPENDSET ((uint32_t)0x80000000) /*!< Set pending NMI bit */ + +/******************* Bit definition for SCB_VTOR register *******************/ +#define SCB_VTOR_TBLOFF ((uint32_t)0x1FFFFF80) /*!< Vector table base offset field */ +#define SCB_VTOR_TBLBASE ((uint32_t)0x20000000) /*!< Table base in code(0) or RAM(1) */ + +/*!<***************** Bit definition for SCB_AIRCR register *******************/ +#define SCB_AIRCR_VECTRESET ((uint32_t)0x00000001) /*!< System Reset bit */ +#define SCB_AIRCR_VECTCLRACTIVE ((uint32_t)0x00000002) /*!< Clear active vector bit */ +#define SCB_AIRCR_SYSRESETREQ ((uint32_t)0x00000004) /*!< Requests chip control logic to generate a reset */ + +#define SCB_AIRCR_PRIGROUP ((uint32_t)0x00000700) /*!< PRIGROUP[2:0] bits (Priority group) */ +#define SCB_AIRCR_PRIGROUP_0 ((uint32_t)0x00000100) /*!< Bit 0 */ +#define SCB_AIRCR_PRIGROUP_1 ((uint32_t)0x00000200) /*!< Bit 1 */ +#define SCB_AIRCR_PRIGROUP_2 ((uint32_t)0x00000400) /*!< Bit 2 */ + +/* prority group configuration */ +#define SCB_AIRCR_PRIGROUP0 ((uint32_t)0x00000000) /*!< Priority group=0 (7 bits of pre-emption priority, 1 bit of subpriority) */ +#define SCB_AIRCR_PRIGROUP1 ((uint32_t)0x00000100) /*!< Priority group=1 (6 bits of pre-emption priority, 2 bits of subpriority) */ +#define SCB_AIRCR_PRIGROUP2 ((uint32_t)0x00000200) /*!< Priority group=2 (5 bits of pre-emption priority, 3 bits of subpriority) */ +#define SCB_AIRCR_PRIGROUP3 ((uint32_t)0x00000300) /*!< Priority group=3 (4 bits of pre-emption priority, 4 bits of subpriority) */ +#define SCB_AIRCR_PRIGROUP4 ((uint32_t)0x00000400) /*!< Priority group=4 (3 bits of pre-emption priority, 5 bits of subpriority) */ +#define SCB_AIRCR_PRIGROUP5 ((uint32_t)0x00000500) /*!< Priority group=5 (2 bits of pre-emption priority, 6 bits of subpriority) */ +#define SCB_AIRCR_PRIGROUP6 ((uint32_t)0x00000600) /*!< Priority group=6 (1 bit of pre-emption priority, 7 bits of subpriority) */ +#define SCB_AIRCR_PRIGROUP7 ((uint32_t)0x00000700) /*!< Priority group=7 (no pre-emption priority, 8 bits of subpriority) */ + +#define SCB_AIRCR_ENDIANESS ((uint32_t)0x00008000) /*!< Data endianness bit */ +#define SCB_AIRCR_VECTKEY ((uint32_t)0xFFFF0000) /*!< Register key (VECTKEY) - Reads as 0xFA05 (VECTKEYSTAT) */ + +/******************* Bit definition for SCB_SCR register ********************/ +#define SCB_SCR_SLEEPONEXIT ((uint8_t)0x02) /*!< Sleep on exit bit */ +#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04) /*!< Sleep deep bit */ +#define SCB_SCR_SEVONPEND ((uint8_t)0x10) /*!< Wake up from WFE */ + +/******************** Bit definition for SCB_CCR register *******************/ +#define SCB_CCR_NONBASETHRDENA ((uint16_t)0x0001) /*!< Thread mode can be entered from any level in Handler mode by controlled return value */ +#define SCB_CCR_USERSETMPEND ((uint16_t)0x0002) /*!< Enables user code to write the Software Trigger Interrupt register to trigger (pend) a Main exception */ +#define SCB_CCR_UNALIGN_TRP ((uint16_t)0x0008) /*!< Trap for unaligned access */ +#define SCB_CCR_DIV_0_TRP ((uint16_t)0x0010) /*!< Trap on Divide by 0 */ +#define SCB_CCR_BFHFNMIGN ((uint16_t)0x0100) /*!< Handlers running at priority -1 and -2 */ +#define SCB_CCR_STKALIGN ((uint16_t)0x0200) /*!< On exception entry, the SP used prior to the exception is adjusted to be 8-byte aligned */ + +/******************* Bit definition for SCB_SHPR register ********************/ +#define SCB_SHPR_PRI_N ((uint32_t)0x000000FF) /*!< Priority of system handler 4,8, and 12. Mem Manage, reserved and Debug Monitor */ +#define SCB_SHPR_PRI_N1 ((uint32_t)0x0000FF00) /*!< Priority of system handler 5,9, and 13. Bus Fault, reserved and reserved */ +#define SCB_SHPR_PRI_N2 ((uint32_t)0x00FF0000) /*!< Priority of system handler 6,10, and 14. Usage Fault, reserved and PendSV */ +#define SCB_SHPR_PRI_N3 ((uint32_t)0xFF000000) /*!< Priority of system handler 7,11, and 15. Reserved, SVCall and SysTick */ + +/****************** Bit definition for SCB_SHCSR register *******************/ +#define SCB_SHCSR_MEMFAULTACT ((uint32_t)0x00000001) /*!< MemManage is active */ +#define SCB_SHCSR_BUSFAULTACT ((uint32_t)0x00000002) /*!< BusFault is active */ +#define SCB_SHCSR_USGFAULTACT ((uint32_t)0x00000008) /*!< UsageFault is active */ +#define SCB_SHCSR_SVCALLACT ((uint32_t)0x00000080) /*!< SVCall is active */ +#define SCB_SHCSR_MONITORACT ((uint32_t)0x00000100) /*!< Monitor is active */ +#define SCB_SHCSR_PENDSVACT ((uint32_t)0x00000400) /*!< PendSV is active */ +#define SCB_SHCSR_SYSTICKACT ((uint32_t)0x00000800) /*!< SysTick is active */ +#define SCB_SHCSR_USGFAULTPENDED ((uint32_t)0x00001000) /*!< Usage Fault is pended */ +#define SCB_SHCSR_MEMFAULTPENDED ((uint32_t)0x00002000) /*!< MemManage is pended */ +#define SCB_SHCSR_BUSFAULTPENDED ((uint32_t)0x00004000) /*!< Bus Fault is pended */ +#define SCB_SHCSR_SVCALLPENDED ((uint32_t)0x00008000) /*!< SVCall is pended */ +#define SCB_SHCSR_MEMFAULTENA ((uint32_t)0x00010000) /*!< MemManage enable */ +#define SCB_SHCSR_BUSFAULTENA ((uint32_t)0x00020000) /*!< Bus Fault enable */ +#define SCB_SHCSR_USGFAULTENA ((uint32_t)0x00040000) /*!< UsageFault enable */ + +/******************* Bit definition for SCB_CFSR register *******************/ +/*!< MFSR */ +#define SCB_CFSR_IACCVIOL ((uint32_t)0x00000001) /*!< Instruction access violation */ +#define SCB_CFSR_DACCVIOL ((uint32_t)0x00000002) /*!< Data access violation */ +#define SCB_CFSR_MUNSTKERR ((uint32_t)0x00000008) /*!< Unstacking error */ +#define SCB_CFSR_MSTKERR ((uint32_t)0x00000010) /*!< Stacking error */ +#define SCB_CFSR_MMARVALID ((uint32_t)0x00000080) /*!< Memory Manage Address Register address valid flag */ +/*!< BFSR */ +#define SCB_CFSR_IBUSERR ((uint32_t)0x00000100) /*!< Instruction bus error flag */ +#define SCB_CFSR_PRECISERR ((uint32_t)0x00000200) /*!< Precise data bus error */ +#define SCB_CFSR_IMPRECISERR ((uint32_t)0x00000400) /*!< Imprecise data bus error */ +#define SCB_CFSR_UNSTKERR ((uint32_t)0x00000800) /*!< Unstacking error */ +#define SCB_CFSR_STKERR ((uint32_t)0x00001000) /*!< Stacking error */ +#define SCB_CFSR_BFARVALID ((uint32_t)0x00008000) /*!< Bus Fault Address Register address valid flag */ +/*!< UFSR */ +#define SCB_CFSR_UNDEFINSTR ((uint32_t)0x00010000) /*!< The processor attempt to excecute an undefined instruction */ +#define SCB_CFSR_INVSTATE ((uint32_t)0x00020000) /*!< Invalid combination of EPSR and instruction */ +#define SCB_CFSR_INVPC ((uint32_t)0x00040000) /*!< Attempt to load EXC_RETURN into pc illegally */ +#define SCB_CFSR_NOCP ((uint32_t)0x00080000) /*!< Attempt to use a coprocessor instruction */ +#define SCB_CFSR_UNALIGNED ((uint32_t)0x01000000) /*!< Fault occurs when there is an attempt to make an unaligned memory access */ +#define SCB_CFSR_DIVBYZERO ((uint32_t)0x02000000) /*!< Fault occurs when SDIV or DIV instruction is used with a divisor of 0 */ + +/******************* Bit definition for SCB_HFSR register *******************/ +#define SCB_HFSR_VECTTBL ((uint32_t)0x00000002) /*!< Fault occures because of vector table read on exception processing */ +#define SCB_HFSR_FORCED ((uint32_t)0x40000000) /*!< Hard Fault activated when a configurable Fault was received and cannot activate */ +#define SCB_HFSR_DEBUGEVT ((uint32_t)0x80000000) /*!< Fault related to debug */ + +/******************* Bit definition for SCB_DFSR register *******************/ +#define SCB_DFSR_HALTED ((uint8_t)0x01) /*!< Halt request flag */ +#define SCB_DFSR_BKPT ((uint8_t)0x02) /*!< BKPT flag */ +#define SCB_DFSR_DWTTRAP ((uint8_t)0x04) /*!< Data Watchpoint and Trace (DWT) flag */ +#define SCB_DFSR_VCATCH ((uint8_t)0x08) /*!< Vector catch flag */ +#define SCB_DFSR_EXTERNAL ((uint8_t)0x10) /*!< External debug request flag */ + +/******************* Bit definition for SCB_MMFAR register ******************/ +#define SCB_MMFAR_ADDRESS ((uint32_t)0xFFFFFFFF) /*!< Mem Manage fault address field */ + +/******************* Bit definition for SCB_BFAR register *******************/ +#define SCB_BFAR_ADDRESS ((uint32_t)0xFFFFFFFF) /*!< Bus fault address field */ + +/******************* Bit definition for SCB_afsr register *******************/ +#define SCB_AFSR_IMPDEF ((uint32_t)0xFFFFFFFF) /*!< Implementation defined */ + +/******************************************************************************/ +/* */ +/* External Interrupt/Event Controller */ +/* */ +/******************************************************************************/ + +/******************* Bit definition for EXTI_IMR register *******************/ +#define EXTI_IMR_MR0 ((uint32_t)0x00000001) /*!< Interrupt Mask on line 0 */ +#define EXTI_IMR_MR1 ((uint32_t)0x00000002) /*!< Interrupt Mask on line 1 */ +#define EXTI_IMR_MR2 ((uint32_t)0x00000004) /*!< Interrupt Mask on line 2 */ +#define EXTI_IMR_MR3 ((uint32_t)0x00000008) /*!< Interrupt Mask on line 3 */ +#define EXTI_IMR_MR4 ((uint32_t)0x00000010) /*!< Interrupt Mask on line 4 */ +#define EXTI_IMR_MR5 ((uint32_t)0x00000020) /*!< Interrupt Mask on line 5 */ +#define EXTI_IMR_MR6 ((uint32_t)0x00000040) /*!< Interrupt Mask on line 6 */ +#define EXTI_IMR_MR7 ((uint32_t)0x00000080) /*!< Interrupt Mask on line 7 */ +#define EXTI_IMR_MR8 ((uint32_t)0x00000100) /*!< Interrupt Mask on line 8 */ +#define EXTI_IMR_MR9 ((uint32_t)0x00000200) /*!< Interrupt Mask on line 9 */ +#define EXTI_IMR_MR10 ((uint32_t)0x00000400) /*!< Interrupt Mask on line 10 */ +#define EXTI_IMR_MR11 ((uint32_t)0x00000800) /*!< Interrupt Mask on line 11 */ +#define EXTI_IMR_MR12 ((uint32_t)0x00001000) /*!< Interrupt Mask on line 12 */ +#define EXTI_IMR_MR13 ((uint32_t)0x00002000) /*!< Interrupt Mask on line 13 */ +#define EXTI_IMR_MR14 ((uint32_t)0x00004000) /*!< Interrupt Mask on line 14 */ +#define EXTI_IMR_MR15 ((uint32_t)0x00008000) /*!< Interrupt Mask on line 15 */ +#define EXTI_IMR_MR16 ((uint32_t)0x00010000) /*!< Interrupt Mask on line 16 */ +#define EXTI_IMR_MR17 ((uint32_t)0x00020000) /*!< Interrupt Mask on line 17 */ +#define EXTI_IMR_MR18 ((uint32_t)0x00040000) /*!< Interrupt Mask on line 18 */ +#define EXTI_IMR_MR19 ((uint32_t)0x00080000) /*!< Interrupt Mask on line 19 */ + +/******************* Bit definition for EXTI_EMR register *******************/ +#define EXTI_EMR_MR0 ((uint32_t)0x00000001) /*!< Event Mask on line 0 */ +#define EXTI_EMR_MR1 ((uint32_t)0x00000002) /*!< Event Mask on line 1 */ +#define EXTI_EMR_MR2 ((uint32_t)0x00000004) /*!< Event Mask on line 2 */ +#define EXTI_EMR_MR3 ((uint32_t)0x00000008) /*!< Event Mask on line 3 */ +#define EXTI_EMR_MR4 ((uint32_t)0x00000010) /*!< Event Mask on line 4 */ +#define EXTI_EMR_MR5 ((uint32_t)0x00000020) /*!< Event Mask on line 5 */ +#define EXTI_EMR_MR6 ((uint32_t)0x00000040) /*!< Event Mask on line 6 */ +#define EXTI_EMR_MR7 ((uint32_t)0x00000080) /*!< Event Mask on line 7 */ +#define EXTI_EMR_MR8 ((uint32_t)0x00000100) /*!< Event Mask on line 8 */ +#define EXTI_EMR_MR9 ((uint32_t)0x00000200) /*!< Event Mask on line 9 */ +#define EXTI_EMR_MR10 ((uint32_t)0x00000400) /*!< Event Mask on line 10 */ +#define EXTI_EMR_MR11 ((uint32_t)0x00000800) /*!< Event Mask on line 11 */ +#define EXTI_EMR_MR12 ((uint32_t)0x00001000) /*!< Event Mask on line 12 */ +#define EXTI_EMR_MR13 ((uint32_t)0x00002000) /*!< Event Mask on line 13 */ +#define EXTI_EMR_MR14 ((uint32_t)0x00004000) /*!< Event Mask on line 14 */ +#define EXTI_EMR_MR15 ((uint32_t)0x00008000) /*!< Event Mask on line 15 */ +#define EXTI_EMR_MR16 ((uint32_t)0x00010000) /*!< Event Mask on line 16 */ +#define EXTI_EMR_MR17 ((uint32_t)0x00020000) /*!< Event Mask on line 17 */ +#define EXTI_EMR_MR18 ((uint32_t)0x00040000) /*!< Event Mask on line 18 */ +#define EXTI_EMR_MR19 ((uint32_t)0x00080000) /*!< Event Mask on line 19 */ + +/****************** Bit definition for EXTI_RTSR register *******************/ +#define EXTI_RTSR_TR0 ((uint32_t)0x00000001) /*!< Rising trigger event configuration bit of line 0 */ +#define EXTI_RTSR_TR1 ((uint32_t)0x00000002) /*!< Rising trigger event configuration bit of line 1 */ +#define EXTI_RTSR_TR2 ((uint32_t)0x00000004) /*!< Rising trigger event configuration bit of line 2 */ +#define EXTI_RTSR_TR3 ((uint32_t)0x00000008) /*!< Rising trigger event configuration bit of line 3 */ +#define EXTI_RTSR_TR4 ((uint32_t)0x00000010) /*!< Rising trigger event configuration bit of line 4 */ +#define EXTI_RTSR_TR5 ((uint32_t)0x00000020) /*!< Rising trigger event configuration bit of line 5 */ +#define EXTI_RTSR_TR6 ((uint32_t)0x00000040) /*!< Rising trigger event configuration bit of line 6 */ +#define EXTI_RTSR_TR7 ((uint32_t)0x00000080) /*!< Rising trigger event configuration bit of line 7 */ +#define EXTI_RTSR_TR8 ((uint32_t)0x00000100) /*!< Rising trigger event configuration bit of line 8 */ +#define EXTI_RTSR_TR9 ((uint32_t)0x00000200) /*!< Rising trigger event configuration bit of line 9 */ +#define EXTI_RTSR_TR10 ((uint32_t)0x00000400) /*!< Rising trigger event configuration bit of line 10 */ +#define EXTI_RTSR_TR11 ((uint32_t)0x00000800) /*!< Rising trigger event configuration bit of line 11 */ +#define EXTI_RTSR_TR12 ((uint32_t)0x00001000) /*!< Rising trigger event configuration bit of line 12 */ +#define EXTI_RTSR_TR13 ((uint32_t)0x00002000) /*!< Rising trigger event configuration bit of line 13 */ +#define EXTI_RTSR_TR14 ((uint32_t)0x00004000) /*!< Rising trigger event configuration bit of line 14 */ +#define EXTI_RTSR_TR15 ((uint32_t)0x00008000) /*!< Rising trigger event configuration bit of line 15 */ +#define EXTI_RTSR_TR16 ((uint32_t)0x00010000) /*!< Rising trigger event configuration bit of line 16 */ +#define EXTI_RTSR_TR17 ((uint32_t)0x00020000) /*!< Rising trigger event configuration bit of line 17 */ +#define EXTI_RTSR_TR18 ((uint32_t)0x00040000) /*!< Rising trigger event configuration bit of line 18 */ +#define EXTI_RTSR_TR19 ((uint32_t)0x00080000) /*!< Rising trigger event configuration bit of line 19 */ + +/****************** Bit definition for EXTI_FTSR register *******************/ +#define EXTI_FTSR_TR0 ((uint32_t)0x00000001) /*!< Falling trigger event configuration bit of line 0 */ +#define EXTI_FTSR_TR1 ((uint32_t)0x00000002) /*!< Falling trigger event configuration bit of line 1 */ +#define EXTI_FTSR_TR2 ((uint32_t)0x00000004) /*!< Falling trigger event configuration bit of line 2 */ +#define EXTI_FTSR_TR3 ((uint32_t)0x00000008) /*!< Falling trigger event configuration bit of line 3 */ +#define EXTI_FTSR_TR4 ((uint32_t)0x00000010) /*!< Falling trigger event configuration bit of line 4 */ +#define EXTI_FTSR_TR5 ((uint32_t)0x00000020) /*!< Falling trigger event configuration bit of line 5 */ +#define EXTI_FTSR_TR6 ((uint32_t)0x00000040) /*!< Falling trigger event configuration bit of line 6 */ +#define EXTI_FTSR_TR7 ((uint32_t)0x00000080) /*!< Falling trigger event configuration bit of line 7 */ +#define EXTI_FTSR_TR8 ((uint32_t)0x00000100) /*!< Falling trigger event configuration bit of line 8 */ +#define EXTI_FTSR_TR9 ((uint32_t)0x00000200) /*!< Falling trigger event configuration bit of line 9 */ +#define EXTI_FTSR_TR10 ((uint32_t)0x00000400) /*!< Falling trigger event configuration bit of line 10 */ +#define EXTI_FTSR_TR11 ((uint32_t)0x00000800) /*!< Falling trigger event configuration bit of line 11 */ +#define EXTI_FTSR_TR12 ((uint32_t)0x00001000) /*!< Falling trigger event configuration bit of line 12 */ +#define EXTI_FTSR_TR13 ((uint32_t)0x00002000) /*!< Falling trigger event configuration bit of line 13 */ +#define EXTI_FTSR_TR14 ((uint32_t)0x00004000) /*!< Falling trigger event configuration bit of line 14 */ +#define EXTI_FTSR_TR15 ((uint32_t)0x00008000) /*!< Falling trigger event configuration bit of line 15 */ +#define EXTI_FTSR_TR16 ((uint32_t)0x00010000) /*!< Falling trigger event configuration bit of line 16 */ +#define EXTI_FTSR_TR17 ((uint32_t)0x00020000) /*!< Falling trigger event configuration bit of line 17 */ +#define EXTI_FTSR_TR18 ((uint32_t)0x00040000) /*!< Falling trigger event configuration bit of line 18 */ +#define EXTI_FTSR_TR19 ((uint32_t)0x00080000) /*!< Falling trigger event configuration bit of line 19 */ + +/****************** Bit definition for EXTI_SWIER register ******************/ +#define EXTI_SWIER_SWIER0 ((uint32_t)0x00000001) /*!< Software Interrupt on line 0 */ +#define EXTI_SWIER_SWIER1 ((uint32_t)0x00000002) /*!< Software Interrupt on line 1 */ +#define EXTI_SWIER_SWIER2 ((uint32_t)0x00000004) /*!< Software Interrupt on line 2 */ +#define EXTI_SWIER_SWIER3 ((uint32_t)0x00000008) /*!< Software Interrupt on line 3 */ +#define EXTI_SWIER_SWIER4 ((uint32_t)0x00000010) /*!< Software Interrupt on line 4 */ +#define EXTI_SWIER_SWIER5 ((uint32_t)0x00000020) /*!< Software Interrupt on line 5 */ +#define EXTI_SWIER_SWIER6 ((uint32_t)0x00000040) /*!< Software Interrupt on line 6 */ +#define EXTI_SWIER_SWIER7 ((uint32_t)0x00000080) /*!< Software Interrupt on line 7 */ +#define EXTI_SWIER_SWIER8 ((uint32_t)0x00000100) /*!< Software Interrupt on line 8 */ +#define EXTI_SWIER_SWIER9 ((uint32_t)0x00000200) /*!< Software Interrupt on line 9 */ +#define EXTI_SWIER_SWIER10 ((uint32_t)0x00000400) /*!< Software Interrupt on line 10 */ +#define EXTI_SWIER_SWIER11 ((uint32_t)0x00000800) /*!< Software Interrupt on line 11 */ +#define EXTI_SWIER_SWIER12 ((uint32_t)0x00001000) /*!< Software Interrupt on line 12 */ +#define EXTI_SWIER_SWIER13 ((uint32_t)0x00002000) /*!< Software Interrupt on line 13 */ +#define EXTI_SWIER_SWIER14 ((uint32_t)0x00004000) /*!< Software Interrupt on line 14 */ +#define EXTI_SWIER_SWIER15 ((uint32_t)0x00008000) /*!< Software Interrupt on line 15 */ +#define EXTI_SWIER_SWIER16 ((uint32_t)0x00010000) /*!< Software Interrupt on line 16 */ +#define EXTI_SWIER_SWIER17 ((uint32_t)0x00020000) /*!< Software Interrupt on line 17 */ +#define EXTI_SWIER_SWIER18 ((uint32_t)0x00040000) /*!< Software Interrupt on line 18 */ +#define EXTI_SWIER_SWIER19 ((uint32_t)0x00080000) /*!< Software Interrupt on line 19 */ + +/******************* Bit definition for EXTI_PR register ********************/ +#define EXTI_PR_PR0 ((uint32_t)0x00000001) /*!< Pending bit for line 0 */ +#define EXTI_PR_PR1 ((uint32_t)0x00000002) /*!< Pending bit for line 1 */ +#define EXTI_PR_PR2 ((uint32_t)0x00000004) /*!< Pending bit for line 2 */ +#define EXTI_PR_PR3 ((uint32_t)0x00000008) /*!< Pending bit for line 3 */ +#define EXTI_PR_PR4 ((uint32_t)0x00000010) /*!< Pending bit for line 4 */ +#define EXTI_PR_PR5 ((uint32_t)0x00000020) /*!< Pending bit for line 5 */ +#define EXTI_PR_PR6 ((uint32_t)0x00000040) /*!< Pending bit for line 6 */ +#define EXTI_PR_PR7 ((uint32_t)0x00000080) /*!< Pending bit for line 7 */ +#define EXTI_PR_PR8 ((uint32_t)0x00000100) /*!< Pending bit for line 8 */ +#define EXTI_PR_PR9 ((uint32_t)0x00000200) /*!< Pending bit for line 9 */ +#define EXTI_PR_PR10 ((uint32_t)0x00000400) /*!< Pending bit for line 10 */ +#define EXTI_PR_PR11 ((uint32_t)0x00000800) /*!< Pending bit for line 11 */ +#define EXTI_PR_PR12 ((uint32_t)0x00001000) /*!< Pending bit for line 12 */ +#define EXTI_PR_PR13 ((uint32_t)0x00002000) /*!< Pending bit for line 13 */ +#define EXTI_PR_PR14 ((uint32_t)0x00004000) /*!< Pending bit for line 14 */ +#define EXTI_PR_PR15 ((uint32_t)0x00008000) /*!< Pending bit for line 15 */ +#define EXTI_PR_PR16 ((uint32_t)0x00010000) /*!< Pending bit for line 16 */ +#define EXTI_PR_PR17 ((uint32_t)0x00020000) /*!< Pending bit for line 17 */ +#define EXTI_PR_PR18 ((uint32_t)0x00040000) /*!< Pending bit for line 18 */ +#define EXTI_PR_PR19 ((uint32_t)0x00080000) /*!< Pending bit for line 19 */ + +/******************************************************************************/ +/* */ +/* DMA Controller */ +/* */ +/******************************************************************************/ + +/******************* Bit definition for DMA_ISR register ********************/ +#define DMA_ISR_GIF1 ((uint32_t)0x00000001) /*!< Channel 1 Global interrupt flag */ +#define DMA_ISR_TCIF1 ((uint32_t)0x00000002) /*!< Channel 1 Transfer Complete flag */ +#define DMA_ISR_HTIF1 ((uint32_t)0x00000004) /*!< Channel 1 Half Transfer flag */ +#define DMA_ISR_TEIF1 ((uint32_t)0x00000008) /*!< Channel 1 Transfer Error flag */ +#define DMA_ISR_GIF2 ((uint32_t)0x00000010) /*!< Channel 2 Global interrupt flag */ +#define DMA_ISR_TCIF2 ((uint32_t)0x00000020) /*!< Channel 2 Transfer Complete flag */ +#define DMA_ISR_HTIF2 ((uint32_t)0x00000040) /*!< Channel 2 Half Transfer flag */ +#define DMA_ISR_TEIF2 ((uint32_t)0x00000080) /*!< Channel 2 Transfer Error flag */ +#define DMA_ISR_GIF3 ((uint32_t)0x00000100) /*!< Channel 3 Global interrupt flag */ +#define DMA_ISR_TCIF3 ((uint32_t)0x00000200) /*!< Channel 3 Transfer Complete flag */ +#define DMA_ISR_HTIF3 ((uint32_t)0x00000400) /*!< Channel 3 Half Transfer flag */ +#define DMA_ISR_TEIF3 ((uint32_t)0x00000800) /*!< Channel 3 Transfer Error flag */ +#define DMA_ISR_GIF4 ((uint32_t)0x00001000) /*!< Channel 4 Global interrupt flag */ +#define DMA_ISR_TCIF4 ((uint32_t)0x00002000) /*!< Channel 4 Transfer Complete flag */ +#define DMA_ISR_HTIF4 ((uint32_t)0x00004000) /*!< Channel 4 Half Transfer flag */ +#define DMA_ISR_TEIF4 ((uint32_t)0x00008000) /*!< Channel 4 Transfer Error flag */ +#define DMA_ISR_GIF5 ((uint32_t)0x00010000) /*!< Channel 5 Global interrupt flag */ +#define DMA_ISR_TCIF5 ((uint32_t)0x00020000) /*!< Channel 5 Transfer Complete flag */ +#define DMA_ISR_HTIF5 ((uint32_t)0x00040000) /*!< Channel 5 Half Transfer flag */ +#define DMA_ISR_TEIF5 ((uint32_t)0x00080000) /*!< Channel 5 Transfer Error flag */ +#define DMA_ISR_GIF6 ((uint32_t)0x00100000) /*!< Channel 6 Global interrupt flag */ +#define DMA_ISR_TCIF6 ((uint32_t)0x00200000) /*!< Channel 6 Transfer Complete flag */ +#define DMA_ISR_HTIF6 ((uint32_t)0x00400000) /*!< Channel 6 Half Transfer flag */ +#define DMA_ISR_TEIF6 ((uint32_t)0x00800000) /*!< Channel 6 Transfer Error flag */ +#define DMA_ISR_GIF7 ((uint32_t)0x01000000) /*!< Channel 7 Global interrupt flag */ +#define DMA_ISR_TCIF7 ((uint32_t)0x02000000) /*!< Channel 7 Transfer Complete flag */ +#define DMA_ISR_HTIF7 ((uint32_t)0x04000000) /*!< Channel 7 Half Transfer flag */ +#define DMA_ISR_TEIF7 ((uint32_t)0x08000000) /*!< Channel 7 Transfer Error flag */ + +/******************* Bit definition for DMA_IFCR register *******************/ +#define DMA_IFCR_CGIF1 ((uint32_t)0x00000001) /*!< Channel 1 Global interrupt clearr */ +#define DMA_IFCR_CTCIF1 ((uint32_t)0x00000002) /*!< Channel 1 Transfer Complete clear */ +#define DMA_IFCR_CHTIF1 ((uint32_t)0x00000004) /*!< Channel 1 Half Transfer clear */ +#define DMA_IFCR_CTEIF1 ((uint32_t)0x00000008) /*!< Channel 1 Transfer Error clear */ +#define DMA_IFCR_CGIF2 ((uint32_t)0x00000010) /*!< Channel 2 Global interrupt clear */ +#define DMA_IFCR_CTCIF2 ((uint32_t)0x00000020) /*!< Channel 2 Transfer Complete clear */ +#define DMA_IFCR_CHTIF2 ((uint32_t)0x00000040) /*!< Channel 2 Half Transfer clear */ +#define DMA_IFCR_CTEIF2 ((uint32_t)0x00000080) /*!< Channel 2 Transfer Error clear */ +#define DMA_IFCR_CGIF3 ((uint32_t)0x00000100) /*!< Channel 3 Global interrupt clear */ +#define DMA_IFCR_CTCIF3 ((uint32_t)0x00000200) /*!< Channel 3 Transfer Complete clear */ +#define DMA_IFCR_CHTIF3 ((uint32_t)0x00000400) /*!< Channel 3 Half Transfer clear */ +#define DMA_IFCR_CTEIF3 ((uint32_t)0x00000800) /*!< Channel 3 Transfer Error clear */ +#define DMA_IFCR_CGIF4 ((uint32_t)0x00001000) /*!< Channel 4 Global interrupt clear */ +#define DMA_IFCR_CTCIF4 ((uint32_t)0x00002000) /*!< Channel 4 Transfer Complete clear */ +#define DMA_IFCR_CHTIF4 ((uint32_t)0x00004000) /*!< Channel 4 Half Transfer clear */ +#define DMA_IFCR_CTEIF4 ((uint32_t)0x00008000) /*!< Channel 4 Transfer Error clear */ +#define DMA_IFCR_CGIF5 ((uint32_t)0x00010000) /*!< Channel 5 Global interrupt clear */ +#define DMA_IFCR_CTCIF5 ((uint32_t)0x00020000) /*!< Channel 5 Transfer Complete clear */ +#define DMA_IFCR_CHTIF5 ((uint32_t)0x00040000) /*!< Channel 5 Half Transfer clear */ +#define DMA_IFCR_CTEIF5 ((uint32_t)0x00080000) /*!< Channel 5 Transfer Error clear */ +#define DMA_IFCR_CGIF6 ((uint32_t)0x00100000) /*!< Channel 6 Global interrupt clear */ +#define DMA_IFCR_CTCIF6 ((uint32_t)0x00200000) /*!< Channel 6 Transfer Complete clear */ +#define DMA_IFCR_CHTIF6 ((uint32_t)0x00400000) /*!< Channel 6 Half Transfer clear */ +#define DMA_IFCR_CTEIF6 ((uint32_t)0x00800000) /*!< Channel 6 Transfer Error clear */ +#define DMA_IFCR_CGIF7 ((uint32_t)0x01000000) /*!< Channel 7 Global interrupt clear */ +#define DMA_IFCR_CTCIF7 ((uint32_t)0x02000000) /*!< Channel 7 Transfer Complete clear */ +#define DMA_IFCR_CHTIF7 ((uint32_t)0x04000000) /*!< Channel 7 Half Transfer clear */ +#define DMA_IFCR_CTEIF7 ((uint32_t)0x08000000) /*!< Channel 7 Transfer Error clear */ + +/******************* Bit definition for DMA_CCR1 register *******************/ +#define DMA_CCR1_EN ((uint16_t)0x0001) /*!< Channel enable*/ +#define DMA_CCR1_TCIE ((uint16_t)0x0002) /*!< Transfer complete interrupt enable */ +#define DMA_CCR1_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */ +#define DMA_CCR1_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */ +#define DMA_CCR1_DIR ((uint16_t)0x0010) /*!< Data transfer direction */ +#define DMA_CCR1_CIRC ((uint16_t)0x0020) /*!< Circular mode */ +#define DMA_CCR1_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */ +#define DMA_CCR1_MINC ((uint16_t)0x0080) /*!< Memory increment mode */ + +#define DMA_CCR1_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */ +#define DMA_CCR1_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */ +#define DMA_CCR1_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */ + +#define DMA_CCR1_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */ +#define DMA_CCR1_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */ +#define DMA_CCR1_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */ + +#define DMA_CCR1_PL ((uint16_t)0x3000) /*!< PL[1:0] bits(Channel Priority level) */ +#define DMA_CCR1_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */ +#define DMA_CCR1_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */ + +#define DMA_CCR1_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */ + +/******************* Bit definition for DMA_CCR2 register *******************/ +#define DMA_CCR2_EN ((uint16_t)0x0001) /*!< Channel enable */ +#define DMA_CCR2_TCIE ((uint16_t)0x0002) /*!< ransfer complete interrupt enable */ +#define DMA_CCR2_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */ +#define DMA_CCR2_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */ +#define DMA_CCR2_DIR ((uint16_t)0x0010) /*!< Data transfer direction */ +#define DMA_CCR2_CIRC ((uint16_t)0x0020) /*!< Circular mode */ +#define DMA_CCR2_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */ +#define DMA_CCR2_MINC ((uint16_t)0x0080) /*!< Memory increment mode */ + +#define DMA_CCR2_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */ +#define DMA_CCR2_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */ +#define DMA_CCR2_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */ + +#define DMA_CCR2_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */ +#define DMA_CCR2_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */ +#define DMA_CCR2_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */ + +#define DMA_CCR2_PL ((uint16_t)0x3000) /*!< PL[1:0] bits (Channel Priority level) */ +#define DMA_CCR2_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */ +#define DMA_CCR2_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */ + +#define DMA_CCR2_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */ + +/******************* Bit definition for DMA_CCR3 register *******************/ +#define DMA_CCR3_EN ((uint16_t)0x0001) /*!< Channel enable */ +#define DMA_CCR3_TCIE ((uint16_t)0x0002) /*!< Transfer complete interrupt enable */ +#define DMA_CCR3_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */ +#define DMA_CCR3_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */ +#define DMA_CCR3_DIR ((uint16_t)0x0010) /*!< Data transfer direction */ +#define DMA_CCR3_CIRC ((uint16_t)0x0020) /*!< Circular mode */ +#define DMA_CCR3_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */ +#define DMA_CCR3_MINC ((uint16_t)0x0080) /*!< Memory increment mode */ + +#define DMA_CCR3_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */ +#define DMA_CCR3_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */ +#define DMA_CCR3_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */ + +#define DMA_CCR3_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */ +#define DMA_CCR3_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */ +#define DMA_CCR3_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */ + +#define DMA_CCR3_PL ((uint16_t)0x3000) /*!< PL[1:0] bits (Channel Priority level) */ +#define DMA_CCR3_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */ +#define DMA_CCR3_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */ + +#define DMA_CCR3_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */ + +/*!<****************** Bit definition for DMA_CCR4 register *******************/ +#define DMA_CCR4_EN ((uint16_t)0x0001) /*!
© COPYRIGHT 2010 STMicroelectronics
+ ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f10x_system + * @{ + */ + +/** + * @brief Define to prevent recursive inclusion + */ +#ifndef __SYSTEM_STM32F10X_H +#define __SYSTEM_STM32F10X_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup STM32F10x_System_Includes + * @{ + */ + +/** + * @} + */ + + +/** @addtogroup STM32F10x_System_Exported_types + * @{ + */ + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +/** + * @} + */ + +/** @addtogroup STM32F10x_System_Exported_Constants + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F10x_System_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F10x_System_Exported_Functions + * @{ + */ + +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__SYSTEM_STM32F10X_H */ + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/misc.h b/example/libs_stm/inc/stm32f10x/misc.h new file mode 100644 index 000000000..95c9541d3 --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/misc.h @@ -0,0 +1,219 @@ +/** + ****************************************************************************** + * @file misc.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the miscellaneous + * firmware library functions (add-on to CMSIS functions). + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MISC_H +#define __MISC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup MISC + * @{ + */ + +/** @defgroup MISC_Exported_Types + * @{ + */ + +/** + * @brief NVIC Init Structure definition + */ + +typedef struct +{ + uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled. + This parameter can be a value of @ref IRQn_Type + (For the complete STM32 Devices IRQ Channels list, please + refer to stm32f10x.h file) */ + + uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel + specified in NVIC_IRQChannel. This parameter can be a value + between 0 and 15 as described in the table @ref NVIC_Priority_Table */ + + uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified + in NVIC_IRQChannel. This parameter can be a value + between 0 and 15 as described in the table @ref NVIC_Priority_Table */ + + FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel + will be enabled or disabled. + This parameter can be set either to ENABLE or DISABLE */ +} NVIC_InitTypeDef; + +/** + * @} + */ + +/** @defgroup NVIC_Priority_Table + * @{ + */ + +/** +@code + The table below gives the allowed values of the pre-emption priority and subpriority according + to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function + ============================================================================================================================ + NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description + ============================================================================================================================ + NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority + | | | 4 bits for subpriority + ---------------------------------------------------------------------------------------------------------------------------- + NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority + | | | 3 bits for subpriority + ---------------------------------------------------------------------------------------------------------------------------- + NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority + | | | 2 bits for subpriority + ---------------------------------------------------------------------------------------------------------------------------- + NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority + | | | 1 bits for subpriority + ---------------------------------------------------------------------------------------------------------------------------- + NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority + | | | 0 bits for subpriority + ============================================================================================================================ +@endcode +*/ + +/** + * @} + */ + +/** @defgroup MISC_Exported_Constants + * @{ + */ + +/** @defgroup Vector_Table_Base + * @{ + */ + +#define NVIC_VectTab_RAM ((uint32_t)0x20000000) +#define NVIC_VectTab_FLASH ((uint32_t)0x08000000) +#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \ + ((VECTTAB) == NVIC_VectTab_FLASH)) +/** + * @} + */ + +/** @defgroup System_Low_Power + * @{ + */ + +#define NVIC_LP_SEVONPEND ((uint8_t)0x10) +#define NVIC_LP_SLEEPDEEP ((uint8_t)0x04) +#define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02) +#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \ + ((LP) == NVIC_LP_SLEEPDEEP) || \ + ((LP) == NVIC_LP_SLEEPONEXIT)) +/** + * @} + */ + +/** @defgroup Preemption_Priority_Group + * @{ + */ + +#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority + 4 bits for subpriority */ +#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority + 3 bits for subpriority */ +#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority + 2 bits for subpriority */ +#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority + 1 bits for subpriority */ +#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority + 0 bits for subpriority */ + +#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \ + ((GROUP) == NVIC_PriorityGroup_1) || \ + ((GROUP) == NVIC_PriorityGroup_2) || \ + ((GROUP) == NVIC_PriorityGroup_3) || \ + ((GROUP) == NVIC_PriorityGroup_4)) + +#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) + +#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) + +#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF) + +/** + * @} + */ + +/** @defgroup SysTick_clock_source + * @{ + */ + +#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) +#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004) +#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \ + ((SOURCE) == SysTick_CLKSource_HCLK_Div8)) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup MISC_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup MISC_Exported_Functions + * @{ + */ + +void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); +void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); +void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset); +void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState); +void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource); + +#ifdef __cplusplus +} +#endif + +#endif /* __MISC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_adc.h b/example/libs_stm/inc/stm32f10x/stm32f10x_adc.h new file mode 100644 index 000000000..401241c4c --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_adc.h @@ -0,0 +1,482 @@ +/** + ****************************************************************************** + * @file stm32f10x_adc.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the ADC firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_ADC_H +#define __STM32F10x_ADC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup ADC + * @{ + */ + +/** @defgroup ADC_Exported_Types + * @{ + */ + +/** + * @brief ADC Init structure definition + */ + +typedef struct +{ + uint32_t ADC_Mode; /*!< Configures the ADC to operate in independent or + dual mode. + This parameter can be a value of @ref ADC_mode */ + + FunctionalState ADC_ScanConvMode; /*!< Specifies whether the conversion is performed in + Scan (multichannels) or Single (one channel) mode. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion is performed in + Continuous or Single mode. + This parameter can be set to ENABLE or DISABLE. */ + + uint32_t ADC_ExternalTrigConv; /*!< Defines the external trigger used to start the analog + to digital conversion of regular channels. This parameter + can be a value of @ref ADC_external_trigger_sources_for_regular_channels_conversion */ + + uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment is left or right. + This parameter can be a value of @ref ADC_data_align */ + + uint8_t ADC_NbrOfChannel; /*!< Specifies the number of ADC channels that will be converted + using the sequencer for regular channel group. + This parameter must range from 1 to 16. */ +}ADC_InitTypeDef; +/** + * @} + */ + +/** @defgroup ADC_Exported_Constants + * @{ + */ + +#define IS_ADC_ALL_PERIPH(PERIPH) (((PERIPH) == ADC1) || \ + ((PERIPH) == ADC2) || \ + ((PERIPH) == ADC3)) + +#define IS_ADC_DMA_PERIPH(PERIPH) (((PERIPH) == ADC1) || \ + ((PERIPH) == ADC3)) + +/** @defgroup ADC_mode + * @{ + */ + +#define ADC_Mode_Independent ((uint32_t)0x00000000) +#define ADC_Mode_RegInjecSimult ((uint32_t)0x00010000) +#define ADC_Mode_RegSimult_AlterTrig ((uint32_t)0x00020000) +#define ADC_Mode_InjecSimult_FastInterl ((uint32_t)0x00030000) +#define ADC_Mode_InjecSimult_SlowInterl ((uint32_t)0x00040000) +#define ADC_Mode_InjecSimult ((uint32_t)0x00050000) +#define ADC_Mode_RegSimult ((uint32_t)0x00060000) +#define ADC_Mode_FastInterl ((uint32_t)0x00070000) +#define ADC_Mode_SlowInterl ((uint32_t)0x00080000) +#define ADC_Mode_AlterTrig ((uint32_t)0x00090000) + +#define IS_ADC_MODE(MODE) (((MODE) == ADC_Mode_Independent) || \ + ((MODE) == ADC_Mode_RegInjecSimult) || \ + ((MODE) == ADC_Mode_RegSimult_AlterTrig) || \ + ((MODE) == ADC_Mode_InjecSimult_FastInterl) || \ + ((MODE) == ADC_Mode_InjecSimult_SlowInterl) || \ + ((MODE) == ADC_Mode_InjecSimult) || \ + ((MODE) == ADC_Mode_RegSimult) || \ + ((MODE) == ADC_Mode_FastInterl) || \ + ((MODE) == ADC_Mode_SlowInterl) || \ + ((MODE) == ADC_Mode_AlterTrig)) +/** + * @} + */ + +/** @defgroup ADC_external_trigger_sources_for_regular_channels_conversion + * @{ + */ + +#define ADC_ExternalTrigConv_T1_CC1 ((uint32_t)0x00000000) /*!< For ADC1 and ADC2 */ +#define ADC_ExternalTrigConv_T1_CC2 ((uint32_t)0x00020000) /*!< For ADC1 and ADC2 */ +#define ADC_ExternalTrigConv_T2_CC2 ((uint32_t)0x00060000) /*!< For ADC1 and ADC2 */ +#define ADC_ExternalTrigConv_T3_TRGO ((uint32_t)0x00080000) /*!< For ADC1 and ADC2 */ +#define ADC_ExternalTrigConv_T4_CC4 ((uint32_t)0x000A0000) /*!< For ADC1 and ADC2 */ +#define ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO ((uint32_t)0x000C0000) /*!< For ADC1 and ADC2 */ + +#define ADC_ExternalTrigConv_T1_CC3 ((uint32_t)0x00040000) /*!< For ADC1, ADC2 and ADC3 */ +#define ADC_ExternalTrigConv_None ((uint32_t)0x000E0000) /*!< For ADC1, ADC2 and ADC3 */ + +#define ADC_ExternalTrigConv_T3_CC1 ((uint32_t)0x00000000) /*!< For ADC3 only */ +#define ADC_ExternalTrigConv_T2_CC3 ((uint32_t)0x00020000) /*!< For ADC3 only */ +#define ADC_ExternalTrigConv_T8_CC1 ((uint32_t)0x00060000) /*!< For ADC3 only */ +#define ADC_ExternalTrigConv_T8_TRGO ((uint32_t)0x00080000) /*!< For ADC3 only */ +#define ADC_ExternalTrigConv_T5_CC1 ((uint32_t)0x000A0000) /*!< For ADC3 only */ +#define ADC_ExternalTrigConv_T5_CC3 ((uint32_t)0x000C0000) /*!< For ADC3 only */ + +#define IS_ADC_EXT_TRIG(REGTRIG) (((REGTRIG) == ADC_ExternalTrigConv_T1_CC1) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T1_CC2) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T1_CC3) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T2_CC2) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T3_TRGO) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T4_CC4) || \ + ((REGTRIG) == ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO) || \ + ((REGTRIG) == ADC_ExternalTrigConv_None) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T3_CC1) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T2_CC3) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T8_CC1) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T8_TRGO) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T5_CC1) || \ + ((REGTRIG) == ADC_ExternalTrigConv_T5_CC3)) +/** + * @} + */ + +/** @defgroup ADC_data_align + * @{ + */ + +#define ADC_DataAlign_Right ((uint32_t)0x00000000) +#define ADC_DataAlign_Left ((uint32_t)0x00000800) +#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DataAlign_Right) || \ + ((ALIGN) == ADC_DataAlign_Left)) +/** + * @} + */ + +/** @defgroup ADC_channels + * @{ + */ + +#define ADC_Channel_0 ((uint8_t)0x00) +#define ADC_Channel_1 ((uint8_t)0x01) +#define ADC_Channel_2 ((uint8_t)0x02) +#define ADC_Channel_3 ((uint8_t)0x03) +#define ADC_Channel_4 ((uint8_t)0x04) +#define ADC_Channel_5 ((uint8_t)0x05) +#define ADC_Channel_6 ((uint8_t)0x06) +#define ADC_Channel_7 ((uint8_t)0x07) +#define ADC_Channel_8 ((uint8_t)0x08) +#define ADC_Channel_9 ((uint8_t)0x09) +#define ADC_Channel_10 ((uint8_t)0x0A) +#define ADC_Channel_11 ((uint8_t)0x0B) +#define ADC_Channel_12 ((uint8_t)0x0C) +#define ADC_Channel_13 ((uint8_t)0x0D) +#define ADC_Channel_14 ((uint8_t)0x0E) +#define ADC_Channel_15 ((uint8_t)0x0F) +#define ADC_Channel_16 ((uint8_t)0x10) +#define ADC_Channel_17 ((uint8_t)0x11) + +#define ADC_Channel_TempSensor ((uint8_t)ADC_Channel_16) +#define ADC_Channel_Vrefint ((uint8_t)ADC_Channel_17) + +#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_0) || ((CHANNEL) == ADC_Channel_1) || \ + ((CHANNEL) == ADC_Channel_2) || ((CHANNEL) == ADC_Channel_3) || \ + ((CHANNEL) == ADC_Channel_4) || ((CHANNEL) == ADC_Channel_5) || \ + ((CHANNEL) == ADC_Channel_6) || ((CHANNEL) == ADC_Channel_7) || \ + ((CHANNEL) == ADC_Channel_8) || ((CHANNEL) == ADC_Channel_9) || \ + ((CHANNEL) == ADC_Channel_10) || ((CHANNEL) == ADC_Channel_11) || \ + ((CHANNEL) == ADC_Channel_12) || ((CHANNEL) == ADC_Channel_13) || \ + ((CHANNEL) == ADC_Channel_14) || ((CHANNEL) == ADC_Channel_15) || \ + ((CHANNEL) == ADC_Channel_16) || ((CHANNEL) == ADC_Channel_17)) +/** + * @} + */ + +/** @defgroup ADC_sampling_time + * @{ + */ + +#define ADC_SampleTime_1Cycles5 ((uint8_t)0x00) +#define ADC_SampleTime_7Cycles5 ((uint8_t)0x01) +#define ADC_SampleTime_13Cycles5 ((uint8_t)0x02) +#define ADC_SampleTime_28Cycles5 ((uint8_t)0x03) +#define ADC_SampleTime_41Cycles5 ((uint8_t)0x04) +#define ADC_SampleTime_55Cycles5 ((uint8_t)0x05) +#define ADC_SampleTime_71Cycles5 ((uint8_t)0x06) +#define ADC_SampleTime_239Cycles5 ((uint8_t)0x07) +#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_1Cycles5) || \ + ((TIME) == ADC_SampleTime_7Cycles5) || \ + ((TIME) == ADC_SampleTime_13Cycles5) || \ + ((TIME) == ADC_SampleTime_28Cycles5) || \ + ((TIME) == ADC_SampleTime_41Cycles5) || \ + ((TIME) == ADC_SampleTime_55Cycles5) || \ + ((TIME) == ADC_SampleTime_71Cycles5) || \ + ((TIME) == ADC_SampleTime_239Cycles5)) +/** + * @} + */ + +/** @defgroup ADC_external_trigger_sources_for_injected_channels_conversion + * @{ + */ + +#define ADC_ExternalTrigInjecConv_T2_TRGO ((uint32_t)0x00002000) /*!< For ADC1 and ADC2 */ +#define ADC_ExternalTrigInjecConv_T2_CC1 ((uint32_t)0x00003000) /*!< For ADC1 and ADC2 */ +#define ADC_ExternalTrigInjecConv_T3_CC4 ((uint32_t)0x00004000) /*!< For ADC1 and ADC2 */ +#define ADC_ExternalTrigInjecConv_T4_TRGO ((uint32_t)0x00005000) /*!< For ADC1 and ADC2 */ +#define ADC_ExternalTrigInjecConv_Ext_IT15_TIM8_CC4 ((uint32_t)0x00006000) /*!< For ADC1 and ADC2 */ + +#define ADC_ExternalTrigInjecConv_T1_TRGO ((uint32_t)0x00000000) /*!< For ADC1, ADC2 and ADC3 */ +#define ADC_ExternalTrigInjecConv_T1_CC4 ((uint32_t)0x00001000) /*!< For ADC1, ADC2 and ADC3 */ +#define ADC_ExternalTrigInjecConv_None ((uint32_t)0x00007000) /*!< For ADC1, ADC2 and ADC3 */ + +#define ADC_ExternalTrigInjecConv_T4_CC3 ((uint32_t)0x00002000) /*!< For ADC3 only */ +#define ADC_ExternalTrigInjecConv_T8_CC2 ((uint32_t)0x00003000) /*!< For ADC3 only */ +#define ADC_ExternalTrigInjecConv_T8_CC4 ((uint32_t)0x00004000) /*!< For ADC3 only */ +#define ADC_ExternalTrigInjecConv_T5_TRGO ((uint32_t)0x00005000) /*!< For ADC3 only */ +#define ADC_ExternalTrigInjecConv_T5_CC4 ((uint32_t)0x00006000) /*!< For ADC3 only */ + +#define IS_ADC_EXT_INJEC_TRIG(INJTRIG) (((INJTRIG) == ADC_ExternalTrigInjecConv_T1_TRGO) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T1_CC4) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_TRGO) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_CC1) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC4) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_TRGO) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_Ext_IT15_TIM8_CC4) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_None) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC3) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC2) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC4) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T5_TRGO) || \ + ((INJTRIG) == ADC_ExternalTrigInjecConv_T5_CC4)) +/** + * @} + */ + +/** @defgroup ADC_injected_channel_selection + * @{ + */ + +#define ADC_InjectedChannel_1 ((uint8_t)0x14) +#define ADC_InjectedChannel_2 ((uint8_t)0x18) +#define ADC_InjectedChannel_3 ((uint8_t)0x1C) +#define ADC_InjectedChannel_4 ((uint8_t)0x20) +#define IS_ADC_INJECTED_CHANNEL(CHANNEL) (((CHANNEL) == ADC_InjectedChannel_1) || \ + ((CHANNEL) == ADC_InjectedChannel_2) || \ + ((CHANNEL) == ADC_InjectedChannel_3) || \ + ((CHANNEL) == ADC_InjectedChannel_4)) +/** + * @} + */ + +/** @defgroup ADC_analog_watchdog_selection + * @{ + */ + +#define ADC_AnalogWatchdog_SingleRegEnable ((uint32_t)0x00800200) +#define ADC_AnalogWatchdog_SingleInjecEnable ((uint32_t)0x00400200) +#define ADC_AnalogWatchdog_SingleRegOrInjecEnable ((uint32_t)0x00C00200) +#define ADC_AnalogWatchdog_AllRegEnable ((uint32_t)0x00800000) +#define ADC_AnalogWatchdog_AllInjecEnable ((uint32_t)0x00400000) +#define ADC_AnalogWatchdog_AllRegAllInjecEnable ((uint32_t)0x00C00000) +#define ADC_AnalogWatchdog_None ((uint32_t)0x00000000) + +#define IS_ADC_ANALOG_WATCHDOG(WATCHDOG) (((WATCHDOG) == ADC_AnalogWatchdog_SingleRegEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_SingleInjecEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_SingleRegOrInjecEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_AllRegEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_AllInjecEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_AllRegAllInjecEnable) || \ + ((WATCHDOG) == ADC_AnalogWatchdog_None)) +/** + * @} + */ + +/** @defgroup ADC_interrupts_definition + * @{ + */ + +#define ADC_IT_EOC ((uint16_t)0x0220) +#define ADC_IT_AWD ((uint16_t)0x0140) +#define ADC_IT_JEOC ((uint16_t)0x0480) + +#define IS_ADC_IT(IT) ((((IT) & (uint16_t)0xF81F) == 0x00) && ((IT) != 0x00)) + +#define IS_ADC_GET_IT(IT) (((IT) == ADC_IT_EOC) || ((IT) == ADC_IT_AWD) || \ + ((IT) == ADC_IT_JEOC)) +/** + * @} + */ + +/** @defgroup ADC_flags_definition + * @{ + */ + +#define ADC_FLAG_AWD ((uint8_t)0x01) +#define ADC_FLAG_EOC ((uint8_t)0x02) +#define ADC_FLAG_JEOC ((uint8_t)0x04) +#define ADC_FLAG_JSTRT ((uint8_t)0x08) +#define ADC_FLAG_STRT ((uint8_t)0x10) +#define IS_ADC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint8_t)0xE0) == 0x00) && ((FLAG) != 0x00)) +#define IS_ADC_GET_FLAG(FLAG) (((FLAG) == ADC_FLAG_AWD) || ((FLAG) == ADC_FLAG_EOC) || \ + ((FLAG) == ADC_FLAG_JEOC) || ((FLAG)== ADC_FLAG_JSTRT) || \ + ((FLAG) == ADC_FLAG_STRT)) +/** + * @} + */ + +/** @defgroup ADC_thresholds + * @{ + */ + +#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFF) + +/** + * @} + */ + +/** @defgroup ADC_injected_offset + * @{ + */ + +#define IS_ADC_OFFSET(OFFSET) ((OFFSET) <= 0xFFF) + +/** + * @} + */ + +/** @defgroup ADC_injected_length + * @{ + */ + +#define IS_ADC_INJECTED_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x4)) + +/** + * @} + */ + +/** @defgroup ADC_injected_rank + * @{ + */ + +#define IS_ADC_INJECTED_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x4)) + +/** + * @} + */ + + +/** @defgroup ADC_regular_length + * @{ + */ + +#define IS_ADC_REGULAR_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x10)) +/** + * @} + */ + +/** @defgroup ADC_regular_rank + * @{ + */ + +#define IS_ADC_REGULAR_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x10)) + +/** + * @} + */ + +/** @defgroup ADC_regular_discontinuous_mode_number + * @{ + */ + +#define IS_ADC_REGULAR_DISC_NUMBER(NUMBER) (((NUMBER) >= 0x1) && ((NUMBER) <= 0x8)) + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup ADC_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup ADC_Exported_Functions + * @{ + */ + +void ADC_DeInit(ADC_TypeDef* ADCx); +void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct); +void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct); +void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState); +void ADC_ResetCalibration(ADC_TypeDef* ADCx); +FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx); +void ADC_StartCalibration(ADC_TypeDef* ADCx); +FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx); +void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx); +void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number); +void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); +void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx); +uint32_t ADC_GetDualModeConversionValue(void); +void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv); +void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +void ADC_SoftwareStartInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); +FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx); +void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); +void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length); +void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset); +uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel); +void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog); +void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold); +void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel); +void ADC_TempSensorVrefintCmd(FunctionalState NewState); +FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG); +void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG); +ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT); +void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F10x_ADC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_bkp.h b/example/libs_stm/inc/stm32f10x/stm32f10x_bkp.h new file mode 100644 index 000000000..45c4e3500 --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_bkp.h @@ -0,0 +1,194 @@ +/** + ****************************************************************************** + * @file stm32f10x_bkp.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the BKP firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_BKP_H +#define __STM32F10x_BKP_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup BKP + * @{ + */ + +/** @defgroup BKP_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup BKP_Exported_Constants + * @{ + */ + +/** @defgroup Tamper_Pin_active_level + * @{ + */ + +#define BKP_TamperPinLevel_High ((uint16_t)0x0000) +#define BKP_TamperPinLevel_Low ((uint16_t)0x0001) +#define IS_BKP_TAMPER_PIN_LEVEL(LEVEL) (((LEVEL) == BKP_TamperPinLevel_High) || \ + ((LEVEL) == BKP_TamperPinLevel_Low)) +/** + * @} + */ + +/** @defgroup RTC_output_source_to_output_on_the_Tamper_pin + * @{ + */ + +#define BKP_RTCOutputSource_None ((uint16_t)0x0000) +#define BKP_RTCOutputSource_CalibClock ((uint16_t)0x0080) +#define BKP_RTCOutputSource_Alarm ((uint16_t)0x0100) +#define BKP_RTCOutputSource_Second ((uint16_t)0x0300) +#define IS_BKP_RTC_OUTPUT_SOURCE(SOURCE) (((SOURCE) == BKP_RTCOutputSource_None) || \ + ((SOURCE) == BKP_RTCOutputSource_CalibClock) || \ + ((SOURCE) == BKP_RTCOutputSource_Alarm) || \ + ((SOURCE) == BKP_RTCOutputSource_Second)) +/** + * @} + */ + +/** @defgroup Data_Backup_Register + * @{ + */ + +#define BKP_DR1 ((uint16_t)0x0004) +#define BKP_DR2 ((uint16_t)0x0008) +#define BKP_DR3 ((uint16_t)0x000C) +#define BKP_DR4 ((uint16_t)0x0010) +#define BKP_DR5 ((uint16_t)0x0014) +#define BKP_DR6 ((uint16_t)0x0018) +#define BKP_DR7 ((uint16_t)0x001C) +#define BKP_DR8 ((uint16_t)0x0020) +#define BKP_DR9 ((uint16_t)0x0024) +#define BKP_DR10 ((uint16_t)0x0028) +#define BKP_DR11 ((uint16_t)0x0040) +#define BKP_DR12 ((uint16_t)0x0044) +#define BKP_DR13 ((uint16_t)0x0048) +#define BKP_DR14 ((uint16_t)0x004C) +#define BKP_DR15 ((uint16_t)0x0050) +#define BKP_DR16 ((uint16_t)0x0054) +#define BKP_DR17 ((uint16_t)0x0058) +#define BKP_DR18 ((uint16_t)0x005C) +#define BKP_DR19 ((uint16_t)0x0060) +#define BKP_DR20 ((uint16_t)0x0064) +#define BKP_DR21 ((uint16_t)0x0068) +#define BKP_DR22 ((uint16_t)0x006C) +#define BKP_DR23 ((uint16_t)0x0070) +#define BKP_DR24 ((uint16_t)0x0074) +#define BKP_DR25 ((uint16_t)0x0078) +#define BKP_DR26 ((uint16_t)0x007C) +#define BKP_DR27 ((uint16_t)0x0080) +#define BKP_DR28 ((uint16_t)0x0084) +#define BKP_DR29 ((uint16_t)0x0088) +#define BKP_DR30 ((uint16_t)0x008C) +#define BKP_DR31 ((uint16_t)0x0090) +#define BKP_DR32 ((uint16_t)0x0094) +#define BKP_DR33 ((uint16_t)0x0098) +#define BKP_DR34 ((uint16_t)0x009C) +#define BKP_DR35 ((uint16_t)0x00A0) +#define BKP_DR36 ((uint16_t)0x00A4) +#define BKP_DR37 ((uint16_t)0x00A8) +#define BKP_DR38 ((uint16_t)0x00AC) +#define BKP_DR39 ((uint16_t)0x00B0) +#define BKP_DR40 ((uint16_t)0x00B4) +#define BKP_DR41 ((uint16_t)0x00B8) +#define BKP_DR42 ((uint16_t)0x00BC) + +#define IS_BKP_DR(DR) (((DR) == BKP_DR1) || ((DR) == BKP_DR2) || ((DR) == BKP_DR3) || \ + ((DR) == BKP_DR4) || ((DR) == BKP_DR5) || ((DR) == BKP_DR6) || \ + ((DR) == BKP_DR7) || ((DR) == BKP_DR8) || ((DR) == BKP_DR9) || \ + ((DR) == BKP_DR10) || ((DR) == BKP_DR11) || ((DR) == BKP_DR12) || \ + ((DR) == BKP_DR13) || ((DR) == BKP_DR14) || ((DR) == BKP_DR15) || \ + ((DR) == BKP_DR16) || ((DR) == BKP_DR17) || ((DR) == BKP_DR18) || \ + ((DR) == BKP_DR19) || ((DR) == BKP_DR20) || ((DR) == BKP_DR21) || \ + ((DR) == BKP_DR22) || ((DR) == BKP_DR23) || ((DR) == BKP_DR24) || \ + ((DR) == BKP_DR25) || ((DR) == BKP_DR26) || ((DR) == BKP_DR27) || \ + ((DR) == BKP_DR28) || ((DR) == BKP_DR29) || ((DR) == BKP_DR30) || \ + ((DR) == BKP_DR31) || ((DR) == BKP_DR32) || ((DR) == BKP_DR33) || \ + ((DR) == BKP_DR34) || ((DR) == BKP_DR35) || ((DR) == BKP_DR36) || \ + ((DR) == BKP_DR37) || ((DR) == BKP_DR38) || ((DR) == BKP_DR39) || \ + ((DR) == BKP_DR40) || ((DR) == BKP_DR41) || ((DR) == BKP_DR42)) + +#define IS_BKP_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x7F) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup BKP_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup BKP_Exported_Functions + * @{ + */ + +void BKP_DeInit(void); +void BKP_TamperPinLevelConfig(uint16_t BKP_TamperPinLevel); +void BKP_TamperPinCmd(FunctionalState NewState); +void BKP_ITConfig(FunctionalState NewState); +void BKP_RTCOutputConfig(uint16_t BKP_RTCOutputSource); +void BKP_SetRTCCalibrationValue(uint8_t CalibrationValue); +void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data); +uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR); +FlagStatus BKP_GetFlagStatus(void); +void BKP_ClearFlag(void); +ITStatus BKP_GetITStatus(void); +void BKP_ClearITPendingBit(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_BKP_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_can.h b/example/libs_stm/inc/stm32f10x/stm32f10x_can.h new file mode 100644 index 000000000..d9ae0676f --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_can.h @@ -0,0 +1,535 @@ +/** + ****************************************************************************** + * @file stm32f10x_can.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the CAN firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_CAN_H +#define __STM32F10x_CAN_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup CAN + * @{ + */ + +/** @defgroup CAN_Exported_Types + * @{ + */ + +#define IS_CAN_ALL_PERIPH(PERIPH) (((PERIPH) == CAN1) || \ + ((PERIPH) == CAN2)) + +/** + * @brief CAN init structure definition + */ + +typedef struct +{ + uint16_t CAN_Prescaler; /*!< Specifies the length of a time quantum. It ranges from 1 to 1024. */ + + uint8_t CAN_Mode; /*!< Specifies the CAN operating mode. + This parameter can be a value of @ref CAN_operating_mode */ + + uint8_t CAN_SJW; /*!< Specifies the maximum number of time quanta the CAN hardware + is allowed to lengthen or shorten a bit to perform resynchronization. + This parameter can be a value of @ref CAN_synchronisation_jump_width */ + + uint8_t CAN_BS1; /*!< Specifies the number of time quanta in Bit Segment 1. + This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_1 */ + + uint8_t CAN_BS2; /*!< Specifies the number of time quanta in Bit Segment 2. + This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */ + + FunctionalState CAN_TTCM; /*!< Enable or disable the time triggered communication mode. + This parameter can be set either to ENABLE or DISABLE. */ + + FunctionalState CAN_ABOM; /*!< Enable or disable the automatic bus-off management. + This parameter can be set either to ENABLE or DISABLE. */ + + FunctionalState CAN_AWUM; /*!< Enable or disable the automatic wake-up mode. + This parameter can be set either to ENABLE or DISABLE. */ + + FunctionalState CAN_NART; /*!< Enable or disable the no-automatic retransmission mode. + This parameter can be set either to ENABLE or DISABLE. */ + + FunctionalState CAN_RFLM; /*!< Enable or disable the Receive FIFO Locked mode. + This parameter can be set either to ENABLE or DISABLE. */ + + FunctionalState CAN_TXFP; /*!< Enable or disable the transmit FIFO priority. + This parameter can be set either to ENABLE or DISABLE. */ +} CAN_InitTypeDef; + +/** + * @brief CAN filter init structure definition + */ + +typedef struct +{ + uint16_t CAN_FilterIdHigh; /*!< Specifies the filter identification number (MSBs for a 32-bit + configuration, first one for a 16-bit configuration). + This parameter can be a value between 0x0000 and 0xFFFF */ + + uint16_t CAN_FilterIdLow; /*!< Specifies the filter identification number (LSBs for a 32-bit + configuration, second one for a 16-bit configuration). + This parameter can be a value between 0x0000 and 0xFFFF */ + + uint16_t CAN_FilterMaskIdHigh; /*!< Specifies the filter mask number or identification number, + according to the mode (MSBs for a 32-bit configuration, + first one for a 16-bit configuration). + This parameter can be a value between 0x0000 and 0xFFFF */ + + uint16_t CAN_FilterMaskIdLow; /*!< Specifies the filter mask number or identification number, + according to the mode (LSBs for a 32-bit configuration, + second one for a 16-bit configuration). + This parameter can be a value between 0x0000 and 0xFFFF */ + + uint16_t CAN_FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1) which will be assigned to the filter. + This parameter can be a value of @ref CAN_filter_FIFO */ + + uint8_t CAN_FilterNumber; /*!< Specifies the filter which will be initialized. It ranges from 0 to 13. */ + + uint8_t CAN_FilterMode; /*!< Specifies the filter mode to be initialized. + This parameter can be a value of @ref CAN_filter_mode */ + + uint8_t CAN_FilterScale; /*!< Specifies the filter scale. + This parameter can be a value of @ref CAN_filter_scale */ + + FunctionalState CAN_FilterActivation; /*!< Enable or disable the filter. + This parameter can be set either to ENABLE or DISABLE. */ +} CAN_FilterInitTypeDef; + +/** + * @brief CAN Tx message structure definition + */ + +typedef struct +{ + uint32_t StdId; /*!< Specifies the standard identifier. + This parameter can be a value between 0 to 0x7FF. */ + + uint32_t ExtId; /*!< Specifies the extended identifier. + This parameter can be a value between 0 to 0x1FFFFFFF. */ + + uint8_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted. + This parameter can be a value of @ref CAN_identifier_type */ + + uint8_t RTR; /*!< Specifies the type of frame for the message that will be transmitted. + This parameter can be a value of @ref CAN_remote_transmission_request */ + + uint8_t DLC; /*!< Specifies the length of the frame that will be transmitted. + This parameter can be a value between 0 to 8 */ + + uint8_t Data[8]; /*!< Contains the data to be transmitted. It ranges from 0 to 0xFF. */ +} CanTxMsg; + +/** + * @brief CAN Rx message structure definition + */ + +typedef struct +{ + uint32_t StdId; /*!< Specifies the standard identifier. + This parameter can be a value between 0 to 0x7FF. */ + + uint32_t ExtId; /*!< Specifies the extended identifier. + This parameter can be a value between 0 to 0x1FFFFFFF. */ + + uint8_t IDE; /*!< Specifies the type of identifier for the message that will be received. + This parameter can be a value of @ref CAN_identifier_type */ + + uint8_t RTR; /*!< Specifies the type of frame for the received message. + This parameter can be a value of @ref CAN_remote_transmission_request */ + + uint8_t DLC; /*!< Specifies the length of the frame that will be received. + This parameter can be a value between 0 to 8 */ + + uint8_t Data[8]; /*!< Contains the data to be received. It ranges from 0 to 0xFF. */ + + uint8_t FMI; /*!< Specifies the index of the filter the message stored in the mailbox passes through. + This parameter can be a value between 0 to 0xFF */ +} CanRxMsg; + +/** + * @} + */ + +/** @defgroup CAN_Exported_Constants + * @{ + */ + +/** @defgroup CAN_sleep_constants + * @{ + */ + +#define CANINITFAILED ((uint8_t)0x00) /*!< CAN initialization failed */ +#define CANINITOK ((uint8_t)0x01) /*!< CAN initialization failed */ + +/** + * @} + */ + +/** @defgroup CAN_operating_mode + * @{ + */ + +#define CAN_Mode_Normal ((uint8_t)0x00) /*!< normal mode */ +#define CAN_Mode_LoopBack ((uint8_t)0x01) /*!< loopback mode */ +#define CAN_Mode_Silent ((uint8_t)0x02) /*!< silent mode */ +#define CAN_Mode_Silent_LoopBack ((uint8_t)0x03) /*!< loopback combined with silent mode */ + +#define IS_CAN_MODE(MODE) (((MODE) == CAN_Mode_Normal) || ((MODE) == CAN_Mode_LoopBack)|| \ + ((MODE) == CAN_Mode_Silent) || ((MODE) == CAN_Mode_Silent_LoopBack)) +/** + * @} + */ + +/** @defgroup CAN_synchronisation_jump_width + * @{ + */ + +#define CAN_SJW_1tq ((uint8_t)0x00) /*!< 1 time quantum */ +#define CAN_SJW_2tq ((uint8_t)0x01) /*!< 2 time quantum */ +#define CAN_SJW_3tq ((uint8_t)0x02) /*!< 3 time quantum */ +#define CAN_SJW_4tq ((uint8_t)0x03) /*!< 4 time quantum */ + +#define IS_CAN_SJW(SJW) (((SJW) == CAN_SJW_1tq) || ((SJW) == CAN_SJW_2tq)|| \ + ((SJW) == CAN_SJW_3tq) || ((SJW) == CAN_SJW_4tq)) +/** + * @} + */ + +/** @defgroup CAN_time_quantum_in_bit_segment_1 + * @{ + */ + +#define CAN_BS1_1tq ((uint8_t)0x00) /*!< 1 time quantum */ +#define CAN_BS1_2tq ((uint8_t)0x01) /*!< 2 time quantum */ +#define CAN_BS1_3tq ((uint8_t)0x02) /*!< 3 time quantum */ +#define CAN_BS1_4tq ((uint8_t)0x03) /*!< 4 time quantum */ +#define CAN_BS1_5tq ((uint8_t)0x04) /*!< 5 time quantum */ +#define CAN_BS1_6tq ((uint8_t)0x05) /*!< 6 time quantum */ +#define CAN_BS1_7tq ((uint8_t)0x06) /*!< 7 time quantum */ +#define CAN_BS1_8tq ((uint8_t)0x07) /*!< 8 time quantum */ +#define CAN_BS1_9tq ((uint8_t)0x08) /*!< 9 time quantum */ +#define CAN_BS1_10tq ((uint8_t)0x09) /*!< 10 time quantum */ +#define CAN_BS1_11tq ((uint8_t)0x0A) /*!< 11 time quantum */ +#define CAN_BS1_12tq ((uint8_t)0x0B) /*!< 12 time quantum */ +#define CAN_BS1_13tq ((uint8_t)0x0C) /*!< 13 time quantum */ +#define CAN_BS1_14tq ((uint8_t)0x0D) /*!< 14 time quantum */ +#define CAN_BS1_15tq ((uint8_t)0x0E) /*!< 15 time quantum */ +#define CAN_BS1_16tq ((uint8_t)0x0F) /*!< 16 time quantum */ + +#define IS_CAN_BS1(BS1) ((BS1) <= CAN_BS1_16tq) +/** + * @} + */ + +/** @defgroup CAN_time_quantum_in_bit_segment_2 + * @{ + */ + +#define CAN_BS2_1tq ((uint8_t)0x00) /*!< 1 time quantum */ +#define CAN_BS2_2tq ((uint8_t)0x01) /*!< 2 time quantum */ +#define CAN_BS2_3tq ((uint8_t)0x02) /*!< 3 time quantum */ +#define CAN_BS2_4tq ((uint8_t)0x03) /*!< 4 time quantum */ +#define CAN_BS2_5tq ((uint8_t)0x04) /*!< 5 time quantum */ +#define CAN_BS2_6tq ((uint8_t)0x05) /*!< 6 time quantum */ +#define CAN_BS2_7tq ((uint8_t)0x06) /*!< 7 time quantum */ +#define CAN_BS2_8tq ((uint8_t)0x07) /*!< 8 time quantum */ + +#define IS_CAN_BS2(BS2) ((BS2) <= CAN_BS2_8tq) + +/** + * @} + */ + +/** @defgroup CAN_clock_prescaler + * @{ + */ + +#define IS_CAN_PRESCALER(PRESCALER) (((PRESCALER) >= 1) && ((PRESCALER) <= 1024)) + +/** + * @} + */ + +/** @defgroup CAN_filter_number + * @{ + */ +#ifndef STM32F10X_CL + #define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 13) +#else + #define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 27) +#endif /* STM32F10X_CL */ +/** + * @} + */ + +/** @defgroup CAN_filter_mode + * @{ + */ + +#define CAN_FilterMode_IdMask ((uint8_t)0x00) /*!< id/mask mode */ +#define CAN_FilterMode_IdList ((uint8_t)0x01) /*!< identifier list mode */ + +#define IS_CAN_FILTER_MODE(MODE) (((MODE) == CAN_FilterMode_IdMask) || \ + ((MODE) == CAN_FilterMode_IdList)) +/** + * @} + */ + +/** @defgroup CAN_filter_scale + * @{ + */ + +#define CAN_FilterScale_16bit ((uint8_t)0x00) /*!< Two 16-bit filters */ +#define CAN_FilterScale_32bit ((uint8_t)0x01) /*!< One 32-bit filter */ + +#define IS_CAN_FILTER_SCALE(SCALE) (((SCALE) == CAN_FilterScale_16bit) || \ + ((SCALE) == CAN_FilterScale_32bit)) + +/** + * @} + */ + +/** @defgroup CAN_filter_FIFO + * @{ + */ + +#define CAN_FilterFIFO0 ((uint8_t)0x00) /*!< Filter FIFO 0 assignment for filter x */ +#define CAN_FilterFIFO1 ((uint8_t)0x01) /*!< Filter FIFO 1 assignment for filter x */ +#define IS_CAN_FILTER_FIFO(FIFO) (((FIFO) == CAN_FilterFIFO0) || \ + ((FIFO) == CAN_FilterFIFO1)) + +/** + * @} + */ + +/** @defgroup Start_bank_filter_for_slave_CAN + * @{ + */ +#define IS_CAN_BANKNUMBER(BANKNUMBER) (((BANKNUMBER) >= 1) && ((BANKNUMBER) <= 27)) +/** + * @} + */ + +/** @defgroup CAN_Tx + * @{ + */ + +#define IS_CAN_TRANSMITMAILBOX(TRANSMITMAILBOX) ((TRANSMITMAILBOX) <= ((uint8_t)0x02)) +#define IS_CAN_STDID(STDID) ((STDID) <= ((uint32_t)0x7FF)) +#define IS_CAN_EXTID(EXTID) ((EXTID) <= ((uint32_t)0x1FFFFFFF)) +#define IS_CAN_DLC(DLC) ((DLC) <= ((uint8_t)0x08)) + +/** + * @} + */ + +/** @defgroup CAN_identifier_type + * @{ + */ + +#define CAN_ID_STD ((uint32_t)0x00000000) /*!< Standard Id */ +#define CAN_ID_EXT ((uint32_t)0x00000004) /*!< Extended Id */ +#define IS_CAN_IDTYPE(IDTYPE) (((IDTYPE) == CAN_ID_STD) || ((IDTYPE) == CAN_ID_EXT)) + +/** + * @} + */ + +/** @defgroup CAN_remote_transmission_request + * @{ + */ + +#define CAN_RTR_DATA ((uint32_t)0x00000000) /*!< Data frame */ +#define CAN_RTR_REMOTE ((uint32_t)0x00000002) /*!< Remote frame */ +#define IS_CAN_RTR(RTR) (((RTR) == CAN_RTR_DATA) || ((RTR) == CAN_RTR_REMOTE)) + +/** + * @} + */ + +/** @defgroup CAN_transmit_constants + * @{ + */ + +#define CANTXFAILED ((uint8_t)0x00) /*!< CAN transmission failed */ +#define CANTXOK ((uint8_t)0x01) /*!< CAN transmission succeeded */ +#define CANTXPENDING ((uint8_t)0x02) /*!< CAN transmission pending */ +#define CAN_NO_MB ((uint8_t)0x04) /*!< CAN cell did not provide an empty mailbox */ + +/** + * @} + */ + +/** @defgroup CAN_receive_FIFO_number_constants + * @{ + */ + +#define CAN_FIFO0 ((uint8_t)0x00) /*!< CAN FIFO0 used to receive */ +#define CAN_FIFO1 ((uint8_t)0x01) /*!< CAN FIFO1 used to receive */ + +#define IS_CAN_FIFO(FIFO) (((FIFO) == CAN_FIFO0) || ((FIFO) == CAN_FIFO1)) + +/** + * @} + */ + +/** @defgroup CAN_sleep_constants + * @{ + */ + +#define CANSLEEPFAILED ((uint8_t)0x00) /*!< CAN did not enter the sleep mode */ +#define CANSLEEPOK ((uint8_t)0x01) /*!< CAN entered the sleep mode */ + +/** + * @} + */ + +/** @defgroup CAN_wake_up_constants + * @{ + */ + +#define CANWAKEUPFAILED ((uint8_t)0x00) /*!< CAN did not leave the sleep mode */ +#define CANWAKEUPOK ((uint8_t)0x01) /*!< CAN leaved the sleep mode */ + +/** + * @} + */ + +/** @defgroup CAN_flags + * @{ + */ + +#define CAN_FLAG_EWG ((uint32_t)0x00000001) /*!< Error Warning Flag */ +#define CAN_FLAG_EPV ((uint32_t)0x00000002) /*!< Error Passive Flag */ +#define CAN_FLAG_BOF ((uint32_t)0x00000004) /*!< Bus-Off Flag */ + +#define IS_CAN_FLAG(FLAG) (((FLAG) == CAN_FLAG_EWG) || ((FLAG) == CAN_FLAG_EPV) ||\ + ((FLAG) == CAN_FLAG_BOF)) + +/** + * @} + */ + +/** @defgroup CAN_interrupts + * @{ + */ + +#define CAN_IT_RQCP0 ((uint32_t)0x00000005) /*!< Request completed mailbox 0 */ +#define CAN_IT_RQCP1 ((uint32_t)0x00000006) /*!< Request completed mailbox 1 */ +#define CAN_IT_RQCP2 ((uint32_t)0x00000007) /*!< Request completed mailbox 2 */ +#define CAN_IT_TME ((uint32_t)0x00000001) /*!< Transmit mailbox empty */ +#define CAN_IT_FMP0 ((uint32_t)0x00000002) /*!< FIFO 0 message pending */ +#define CAN_IT_FF0 ((uint32_t)0x00000004) /*!< FIFO 0 full */ +#define CAN_IT_FOV0 ((uint32_t)0x00000008) /*!< FIFO 0 overrun */ +#define CAN_IT_FMP1 ((uint32_t)0x00000010) /*!< FIFO 1 message pending */ +#define CAN_IT_FF1 ((uint32_t)0x00000020) /*!< FIFO 1 full */ +#define CAN_IT_FOV1 ((uint32_t)0x00000040) /*!< FIFO 1 overrun */ +#define CAN_IT_EWG ((uint32_t)0x00000100) /*!< Error warning */ +#define CAN_IT_EPV ((uint32_t)0x00000200) /*!< Error passive */ +#define CAN_IT_BOF ((uint32_t)0x00000400) /*!< Bus-off */ +#define CAN_IT_LEC ((uint32_t)0x00000800) /*!< Last error code */ +#define CAN_IT_ERR ((uint32_t)0x00008000) /*!< Error */ +#define CAN_IT_WKU ((uint32_t)0x00010000) /*!< Wake-up */ +#define CAN_IT_SLK ((uint32_t)0x00020000) /*!< Sleep */ + +#define IS_CAN_ITConfig(IT) (((IT) == CAN_IT_TME) || ((IT) == CAN_IT_FMP0) ||\ + ((IT) == CAN_IT_FF0) || ((IT) == CAN_IT_FOV0) ||\ + ((IT) == CAN_IT_FMP1) || ((IT) == CAN_IT_FF1) ||\ + ((IT) == CAN_IT_FOV1) || ((IT) == CAN_IT_EWG) ||\ + ((IT) == CAN_IT_EPV) || ((IT) == CAN_IT_BOF) ||\ + ((IT) == CAN_IT_LEC) || ((IT) == CAN_IT_ERR) ||\ + ((IT) == CAN_IT_WKU) || ((IT) == CAN_IT_SLK)) + +#define IS_CAN_ITStatus(IT) (((IT) == CAN_IT_RQCP0) || ((IT) == CAN_IT_RQCP1) ||\ + ((IT) == CAN_IT_RQCP2) || ((IT) == CAN_IT_FF0) ||\ + ((IT) == CAN_IT_FOV0) || ((IT) == CAN_IT_FF1) ||\ + ((IT) == CAN_IT_FOV1) || ((IT) == CAN_IT_EWG) ||\ + ((IT) == CAN_IT_EPV) || ((IT) == CAN_IT_BOF) ||\ + ((IT) == CAN_IT_WKU) || ((IT) == CAN_IT_SLK)) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup CAN_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup CAN_Exported_Functions + * @{ + */ + +void CAN_DeInit(CAN_TypeDef* CANx); +uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct); +void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct); +void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct); +void CAN_SlaveStartBank(uint8_t CAN_BankNumber); +void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState); +uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage); +uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox); +void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox); +void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber); +uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber); +void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage); +void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState); +uint8_t CAN_Sleep(CAN_TypeDef* CANx); +uint8_t CAN_WakeUp(CAN_TypeDef* CANx); +FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG); +void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG); +ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT); +void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_CAN_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_cec.h b/example/libs_stm/inc/stm32f10x/stm32f10x_cec.h new file mode 100644 index 000000000..233a0944f --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_cec.h @@ -0,0 +1,209 @@ +/** + ****************************************************************************** + * @file stm32f10x_cec.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the CEC firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_CEC_H +#define __STM32F10x_CEC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup CEC + * @{ + */ + + +/** @defgroup CEC_Exported_Types + * @{ + */ + +/** + * @brief CEC Init structure definition + */ +typedef struct +{ + uint16_t CEC_BitTimingMode; /*!< Configures the CEC Bit Timing Error Mode. + This parameter can be a value of @ref CEC_BitTiming_Mode */ + uint16_t CEC_BitPeriodMode; /*!< Configures the CEC Bit Period Error Mode. + This parameter can be a value of @ref CEC_BitPeriod_Mode */ +}CEC_InitTypeDef; + +/** + * @} + */ + +/** @defgroup CEC_Exported_Constants + * @{ + */ + +/** @defgroup CEC_BitTiming_Mode + * @{ + */ +#define CEC_BitTimingStdMode ((uint16_t)0x00) /*!< Bit timing error Standard Mode */ +#define CEC_BitTimingErrFreeMode CEC_CFGR_BTEM /*!< Bit timing error Free Mode */ + +#define IS_CEC_BIT_TIMING_ERROR_MODE(MODE) (((MODE) == CEC_BitTimingStdMode) || \ + ((MODE) == CEC_BitTimingErrFreeMode)) +/** + * @} + */ + +/** @defgroup CEC_BitPeriod_Mode + * @{ + */ +#define CEC_BitPeriodStdMode ((uint16_t)0x00) /*!< Bit period error Standard Mode */ +#define CEC_BitPeriodFlexibleMode CEC_CFGR_BPEM /*!< Bit period error Flexible Mode */ + +#define IS_CEC_BIT_PERIOD_ERROR_MODE(MODE) (((MODE) == CEC_BitPeriodStdMode) || \ + ((MODE) == CEC_BitPeriodFlexibleMode)) +/** + * @} + */ + + +/** @defgroup CEC_interrupts_definition + * @{ + */ +#define CEC_IT_TERR CEC_CSR_TERR +#define CEC_IT_TBTRF CEC_CSR_TBTRF +#define CEC_IT_RERR CEC_CSR_RERR +#define CEC_IT_RBTF CEC_CSR_RBTF +#define IS_CEC_GET_IT(IT) (((IT) == CEC_IT_TERR) || ((IT) == CEC_IT_TBTRF) || \ + ((IT) == CEC_IT_RERR) || ((IT) == CEC_IT_RBTF)) +/** + * @} + */ + + +/** @defgroup CEC_Own_Addres + * @{ + */ +#define IS_CEC_ADDRESS(ADDRESS) ((ADDRESS) < 0x10) +/** + * @} + */ + +/** @defgroup CEC_Prescaler + * @{ + */ +#define IS_CEC_PRESCALER(PRESCALER) ((PRESCALER) <= 0x3FFF) + +/** + * @} + */ + +/** @defgroup CEC_flags_definition + * @{ + */ + +/** + * @brief ESR register flags + */ +#define CEC_FLAG_BTE ((uint32_t)0x10010000) +#define CEC_FLAG_BPE ((uint32_t)0x10020000) +#define CEC_FLAG_RBTFE ((uint32_t)0x10040000) +#define CEC_FLAG_SBE ((uint32_t)0x10080000) +#define CEC_FLAG_ACKE ((uint32_t)0x10100000) +#define CEC_FLAG_LINE ((uint32_t)0x10200000) +#define CEC_FLAG_TBTFE ((uint32_t)0x10400000) + +/** + * @brief CSR register flags + */ +#define CEC_FLAG_TEOM ((uint32_t)0x00000002) +#define CEC_FLAG_TERR ((uint32_t)0x00000004) +#define CEC_FLAG_TBTRF ((uint32_t)0x00000008) +#define CEC_FLAG_RSOM ((uint32_t)0x00000010) +#define CEC_FLAG_REOM ((uint32_t)0x00000020) +#define CEC_FLAG_RERR ((uint32_t)0x00000040) +#define CEC_FLAG_RBTF ((uint32_t)0x00000080) + +#define IS_CEC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFF03) == 0x00) && ((FLAG) != 0x00)) + +#define IS_CEC_GET_FLAG(FLAG) (((FLAG) == CEC_FLAG_BTE) || ((FLAG) == CEC_FLAG_BPE) || \ + ((FLAG) == CEC_FLAG_RBTFE) || ((FLAG)== CEC_FLAG_SBE) || \ + ((FLAG) == CEC_FLAG_ACKE) || ((FLAG) == CEC_FLAG_LINE) || \ + ((FLAG) == CEC_FLAG_TBTFE) || ((FLAG) == CEC_FLAG_TEOM) || \ + ((FLAG) == CEC_FLAG_TERR) || ((FLAG) == CEC_FLAG_TBTRF) || \ + ((FLAG) == CEC_FLAG_RSOM) || ((FLAG) == CEC_FLAG_REOM) || \ + ((FLAG) == CEC_FLAG_RERR) || ((FLAG) == CEC_FLAG_RBTF)) + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup CEC_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup CEC_Exported_Functions + * @{ + */ +void CEC_DeInit(void); +void CEC_Init(CEC_InitTypeDef* CEC_InitStruct); +void CEC_Cmd(FunctionalState NewState); +void CEC_ITConfig(FunctionalState NewState); +void CEC_OwnAddressConfig(uint8_t CEC_OwnAddress); +void CEC_SetPrescaler(uint16_t CEC_Prescaler); +void CEC_SendDataByte(uint8_t Data); +uint8_t CEC_ReceiveDataByte(void); +void CEC_StartOfMessage(void); +void CEC_EndOfMessageCmd(FunctionalState NewState); +FlagStatus CEC_GetFlagStatus(uint32_t CEC_FLAG); +void CEC_ClearFlag(uint32_t CEC_FLAG); +ITStatus CEC_GetITStatus(uint8_t CEC_IT); +void CEC_ClearITPendingBit(uint16_t CEC_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_CEC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_crc.h b/example/libs_stm/inc/stm32f10x/stm32f10x_crc.h new file mode 100644 index 000000000..f7b2678c3 --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_crc.h @@ -0,0 +1,93 @@ +/** + ****************************************************************************** + * @file stm32f10x_crc.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the CRC firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_CRC_H +#define __STM32F10x_CRC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup CRC + * @{ + */ + +/** @defgroup CRC_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup CRC_Exported_Constants + * @{ + */ + +/** + * @} + */ + +/** @defgroup CRC_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup CRC_Exported_Functions + * @{ + */ + +void CRC_ResetDR(void); +uint32_t CRC_CalcCRC(uint32_t Data); +uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength); +uint32_t CRC_GetCRC(void); +void CRC_SetIDRegister(uint8_t IDValue); +uint8_t CRC_GetIDRegister(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_CRC_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_dac.h b/example/libs_stm/inc/stm32f10x/stm32f10x_dac.h new file mode 100644 index 000000000..16afbce49 --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_dac.h @@ -0,0 +1,316 @@ +/** + ****************************************************************************** + * @file stm32f10x_dac.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the DAC firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_DAC_H +#define __STM32F10x_DAC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup DAC + * @{ + */ + +/** @defgroup DAC_Exported_Types + * @{ + */ + +/** + * @brief DAC Init structure definition + */ + +typedef struct +{ + uint32_t DAC_Trigger; /*!< Specifies the external trigger for the selected DAC channel. + This parameter can be a value of @ref DAC_trigger_selection */ + + uint32_t DAC_WaveGeneration; /*!< Specifies whether DAC channel noise waves or triangle waves + are generated, or whether no wave is generated. + This parameter can be a value of @ref DAC_wave_generation */ + + uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*!< Specifies the LFSR mask for noise wave generation or + the maximum amplitude triangle generation for the DAC channel. + This parameter can be a value of @ref DAC_lfsrunmask_triangleamplitude */ + + uint32_t DAC_OutputBuffer; /*!< Specifies whether the DAC channel output buffer is enabled or disabled. + This parameter can be a value of @ref DAC_output_buffer */ +}DAC_InitTypeDef; + +/** + * @} + */ + +/** @defgroup DAC_Exported_Constants + * @{ + */ + +/** @defgroup DAC_trigger_selection + * @{ + */ + +#define DAC_Trigger_None ((uint32_t)0x00000000) /*!< Conversion is automatic once the DAC1_DHRxxxx register + has been loaded, and not by external trigger */ +#define DAC_Trigger_T6_TRGO ((uint32_t)0x00000004) /*!< TIM6 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_T8_TRGO ((uint32_t)0x0000000C) /*!< TIM8 TRGO selected as external conversion trigger for DAC channel + only in High-density devices*/ +#define DAC_Trigger_T3_TRGO ((uint32_t)0x0000000C) /*!< TIM8 TRGO selected as external conversion trigger for DAC channel + only in Connectivity line, Medium-density and Low-density Value Line devices */ +#define DAC_Trigger_T7_TRGO ((uint32_t)0x00000014) /*!< TIM7 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_T5_TRGO ((uint32_t)0x0000001C) /*!< TIM5 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_T15_TRGO ((uint32_t)0x0000001C) /*!< TIM15 TRGO selected as external conversion trigger for DAC channel + only in Medium-density and Low-density Value Line devices*/ +#define DAC_Trigger_T2_TRGO ((uint32_t)0x00000024) /*!< TIM2 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_T4_TRGO ((uint32_t)0x0000002C) /*!< TIM4 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_Ext_IT9 ((uint32_t)0x00000034) /*!< EXTI Line9 event selected as external conversion trigger for DAC channel */ +#define DAC_Trigger_Software ((uint32_t)0x0000003C) /*!< Conversion started by software trigger for DAC channel */ + +#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_Trigger_None) || \ + ((TRIGGER) == DAC_Trigger_T6_TRGO) || \ + ((TRIGGER) == DAC_Trigger_T8_TRGO) || \ + ((TRIGGER) == DAC_Trigger_T7_TRGO) || \ + ((TRIGGER) == DAC_Trigger_T5_TRGO) || \ + ((TRIGGER) == DAC_Trigger_T2_TRGO) || \ + ((TRIGGER) == DAC_Trigger_T4_TRGO) || \ + ((TRIGGER) == DAC_Trigger_Ext_IT9) || \ + ((TRIGGER) == DAC_Trigger_Software)) + +/** + * @} + */ + +/** @defgroup DAC_wave_generation + * @{ + */ + +#define DAC_WaveGeneration_None ((uint32_t)0x00000000) +#define DAC_WaveGeneration_Noise ((uint32_t)0x00000040) +#define DAC_WaveGeneration_Triangle ((uint32_t)0x00000080) +#define IS_DAC_GENERATE_WAVE(WAVE) (((WAVE) == DAC_WaveGeneration_None) || \ + ((WAVE) == DAC_WaveGeneration_Noise) || \ + ((WAVE) == DAC_WaveGeneration_Triangle)) +/** + * @} + */ + +/** @defgroup DAC_lfsrunmask_triangleamplitude + * @{ + */ + +#define DAC_LFSRUnmask_Bit0 ((uint32_t)0x00000000) /*!< Unmask DAC channel LFSR bit0 for noise wave generation */ +#define DAC_LFSRUnmask_Bits1_0 ((uint32_t)0x00000100) /*!< Unmask DAC channel LFSR bit[1:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits2_0 ((uint32_t)0x00000200) /*!< Unmask DAC channel LFSR bit[2:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits3_0 ((uint32_t)0x00000300) /*!< Unmask DAC channel LFSR bit[3:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits4_0 ((uint32_t)0x00000400) /*!< Unmask DAC channel LFSR bit[4:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits5_0 ((uint32_t)0x00000500) /*!< Unmask DAC channel LFSR bit[5:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits6_0 ((uint32_t)0x00000600) /*!< Unmask DAC channel LFSR bit[6:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits7_0 ((uint32_t)0x00000700) /*!< Unmask DAC channel LFSR bit[7:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits8_0 ((uint32_t)0x00000800) /*!< Unmask DAC channel LFSR bit[8:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits9_0 ((uint32_t)0x00000900) /*!< Unmask DAC channel LFSR bit[9:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits10_0 ((uint32_t)0x00000A00) /*!< Unmask DAC channel LFSR bit[10:0] for noise wave generation */ +#define DAC_LFSRUnmask_Bits11_0 ((uint32_t)0x00000B00) /*!< Unmask DAC channel LFSR bit[11:0] for noise wave generation */ +#define DAC_TriangleAmplitude_1 ((uint32_t)0x00000000) /*!< Select max triangle amplitude of 1 */ +#define DAC_TriangleAmplitude_3 ((uint32_t)0x00000100) /*!< Select max triangle amplitude of 3 */ +#define DAC_TriangleAmplitude_7 ((uint32_t)0x00000200) /*!< Select max triangle amplitude of 7 */ +#define DAC_TriangleAmplitude_15 ((uint32_t)0x00000300) /*!< Select max triangle amplitude of 15 */ +#define DAC_TriangleAmplitude_31 ((uint32_t)0x00000400) /*!< Select max triangle amplitude of 31 */ +#define DAC_TriangleAmplitude_63 ((uint32_t)0x00000500) /*!< Select max triangle amplitude of 63 */ +#define DAC_TriangleAmplitude_127 ((uint32_t)0x00000600) /*!< Select max triangle amplitude of 127 */ +#define DAC_TriangleAmplitude_255 ((uint32_t)0x00000700) /*!< Select max triangle amplitude of 255 */ +#define DAC_TriangleAmplitude_511 ((uint32_t)0x00000800) /*!< Select max triangle amplitude of 511 */ +#define DAC_TriangleAmplitude_1023 ((uint32_t)0x00000900) /*!< Select max triangle amplitude of 1023 */ +#define DAC_TriangleAmplitude_2047 ((uint32_t)0x00000A00) /*!< Select max triangle amplitude of 2047 */ +#define DAC_TriangleAmplitude_4095 ((uint32_t)0x00000B00) /*!< Select max triangle amplitude of 4095 */ + +#define IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(VALUE) (((VALUE) == DAC_LFSRUnmask_Bit0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits1_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits2_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits3_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits4_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits5_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits6_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits7_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits8_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits9_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits10_0) || \ + ((VALUE) == DAC_LFSRUnmask_Bits11_0) || \ + ((VALUE) == DAC_TriangleAmplitude_1) || \ + ((VALUE) == DAC_TriangleAmplitude_3) || \ + ((VALUE) == DAC_TriangleAmplitude_7) || \ + ((VALUE) == DAC_TriangleAmplitude_15) || \ + ((VALUE) == DAC_TriangleAmplitude_31) || \ + ((VALUE) == DAC_TriangleAmplitude_63) || \ + ((VALUE) == DAC_TriangleAmplitude_127) || \ + ((VALUE) == DAC_TriangleAmplitude_255) || \ + ((VALUE) == DAC_TriangleAmplitude_511) || \ + ((VALUE) == DAC_TriangleAmplitude_1023) || \ + ((VALUE) == DAC_TriangleAmplitude_2047) || \ + ((VALUE) == DAC_TriangleAmplitude_4095)) +/** + * @} + */ + +/** @defgroup DAC_output_buffer + * @{ + */ + +#define DAC_OutputBuffer_Enable ((uint32_t)0x00000000) +#define DAC_OutputBuffer_Disable ((uint32_t)0x00000002) +#define IS_DAC_OUTPUT_BUFFER_STATE(STATE) (((STATE) == DAC_OutputBuffer_Enable) || \ + ((STATE) == DAC_OutputBuffer_Disable)) +/** + * @} + */ + +/** @defgroup DAC_Channel_selection + * @{ + */ + +#define DAC_Channel_1 ((uint32_t)0x00000000) +#define DAC_Channel_2 ((uint32_t)0x00000010) +#define IS_DAC_CHANNEL(CHANNEL) (((CHANNEL) == DAC_Channel_1) || \ + ((CHANNEL) == DAC_Channel_2)) +/** + * @} + */ + +/** @defgroup DAC_data_alignement + * @{ + */ + +#define DAC_Align_12b_R ((uint32_t)0x00000000) +#define DAC_Align_12b_L ((uint32_t)0x00000004) +#define DAC_Align_8b_R ((uint32_t)0x00000008) +#define IS_DAC_ALIGN(ALIGN) (((ALIGN) == DAC_Align_12b_R) || \ + ((ALIGN) == DAC_Align_12b_L) || \ + ((ALIGN) == DAC_Align_8b_R)) +/** + * @} + */ + +/** @defgroup DAC_wave_generation + * @{ + */ + +#define DAC_Wave_Noise ((uint32_t)0x00000040) +#define DAC_Wave_Triangle ((uint32_t)0x00000080) +#define IS_DAC_WAVE(WAVE) (((WAVE) == DAC_Wave_Noise) || \ + ((WAVE) == DAC_Wave_Triangle)) +/** + * @} + */ + +/** @defgroup DAC_data + * @{ + */ + +#define IS_DAC_DATA(DATA) ((DATA) <= 0xFFF0) +/** + * @} + */ +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) +/** @defgroup DAC_interrupts_definition + * @{ + */ + +#define DAC_IT_DMAUDR ((uint32_t)0x00002000) +#define IS_DAC_IT(IT) (((IT) == DAC_IT_DMAUDR)) + +/** + * @} + */ + +/** @defgroup DAC_flags_definition + * @{ + */ + +#define DAC_FLAG_DMAUDR ((uint32_t)0x00002000) +#define IS_DAC_FLAG(FLAG) (((FLAG) == DAC_FLAG_DMAUDR)) + +/** + * @} + */ +#endif + +/** + * @} + */ + +/** @defgroup DAC_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup DAC_Exported_Functions + * @{ + */ + +void DAC_DeInit(void); +void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct); +void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct); +void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState); +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) +void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState); +#endif +void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState); +void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState); +void DAC_DualSoftwareTriggerCmd(FunctionalState NewState); +void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState); +void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data); +void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data); +void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1); +uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel); +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) +FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG); +void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG); +ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT); +void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F10x_DAC_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_dbgmcu.h b/example/libs_stm/inc/stm32f10x/stm32f10x_dbgmcu.h new file mode 100644 index 000000000..5a78f7355 --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_dbgmcu.h @@ -0,0 +1,118 @@ +/** + ****************************************************************************** + * @file stm32f10x_dbgmcu.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the DBGMCU + * firmware library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_DBGMCU_H +#define __STM32F10x_DBGMCU_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup DBGMCU + * @{ + */ + +/** @defgroup DBGMCU_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup DBGMCU_Exported_Constants + * @{ + */ + +#define DBGMCU_SLEEP ((uint32_t)0x00000001) +#define DBGMCU_STOP ((uint32_t)0x00000002) +#define DBGMCU_STANDBY ((uint32_t)0x00000004) +#define DBGMCU_IWDG_STOP ((uint32_t)0x00000100) +#define DBGMCU_WWDG_STOP ((uint32_t)0x00000200) +#define DBGMCU_TIM1_STOP ((uint32_t)0x00000400) +#define DBGMCU_TIM2_STOP ((uint32_t)0x00000800) +#define DBGMCU_TIM3_STOP ((uint32_t)0x00001000) +#define DBGMCU_TIM4_STOP ((uint32_t)0x00002000) +#define DBGMCU_CAN1_STOP ((uint32_t)0x00004000) +#define DBGMCU_I2C1_SMBUS_TIMEOUT ((uint32_t)0x00008000) +#define DBGMCU_I2C2_SMBUS_TIMEOUT ((uint32_t)0x00010000) +#define DBGMCU_TIM8_STOP ((uint32_t)0x00020000) +#define DBGMCU_TIM5_STOP ((uint32_t)0x00040000) +#define DBGMCU_TIM6_STOP ((uint32_t)0x00080000) +#define DBGMCU_TIM7_STOP ((uint32_t)0x00100000) +#define DBGMCU_CAN2_STOP ((uint32_t)0x00200000) +#define DBGMCU_TIM15_STOP ((uint32_t)0x00400000) +#define DBGMCU_TIM16_STOP ((uint32_t)0x00800000) +#define DBGMCU_TIM17_STOP ((uint32_t)0x01000000) +#define DBGMCU_TIM12_STOP ((uint32_t)0x02000000) +#define DBGMCU_TIM13_STOP ((uint32_t)0x04000000) +#define DBGMCU_TIM14_STOP ((uint32_t)0x08000000) +#define DBGMCU_TIM9_STOP ((uint32_t)0x10000000) +#define DBGMCU_TIM10_STOP ((uint32_t)0x20000000) +#define DBGMCU_TIM11_STOP ((uint32_t)0x40000000) + +#define IS_DBGMCU_PERIPH(PERIPH) ((((PERIPH) & 0x800000F8) == 0x00) && ((PERIPH) != 0x00)) +/** + * @} + */ + +/** @defgroup DBGMCU_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup DBGMCU_Exported_Functions + * @{ + */ + +uint32_t DBGMCU_GetREVID(void); +uint32_t DBGMCU_GetDEVID(void); +void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_DBGMCU_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_dma.h b/example/libs_stm/inc/stm32f10x/stm32f10x_dma.h new file mode 100644 index 000000000..35769abc6 --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_dma.h @@ -0,0 +1,437 @@ +/** + ****************************************************************************** + * @file stm32f10x_dma.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the DMA firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_DMA_H +#define __STM32F10x_DMA_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup DMA + * @{ + */ + +/** @defgroup DMA_Exported_Types + * @{ + */ + +/** + * @brief DMA Init structure definition + */ + +typedef struct +{ + uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Channelx. */ + + uint32_t DMA_MemoryBaseAddr; /*!< Specifies the memory base address for DMAy Channelx. */ + + uint32_t DMA_DIR; /*!< Specifies if the peripheral is the source or destination. + This parameter can be a value of @ref DMA_data_transfer_direction */ + + uint32_t DMA_BufferSize; /*!< Specifies the buffer size, in data unit, of the specified Channel. + The data unit is equal to the configuration set in DMA_PeripheralDataSize + or DMA_MemoryDataSize members depending in the transfer direction. */ + + uint32_t DMA_PeripheralInc; /*!< Specifies whether the Peripheral address register is incremented or not. + This parameter can be a value of @ref DMA_peripheral_incremented_mode */ + + uint32_t DMA_MemoryInc; /*!< Specifies whether the memory address register is incremented or not. + This parameter can be a value of @ref DMA_memory_incremented_mode */ + + uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width. + This parameter can be a value of @ref DMA_peripheral_data_size */ + + uint32_t DMA_MemoryDataSize; /*!< Specifies the Memory data width. + This parameter can be a value of @ref DMA_memory_data_size */ + + uint32_t DMA_Mode; /*!< Specifies the operation mode of the DMAy Channelx. + This parameter can be a value of @ref DMA_circular_normal_mode. + @note: The circular buffer mode cannot be used if the memory-to-memory + data transfer is configured on the selected Channel */ + + uint32_t DMA_Priority; /*!< Specifies the software priority for the DMAy Channelx. + This parameter can be a value of @ref DMA_priority_level */ + + uint32_t DMA_M2M; /*!< Specifies if the DMAy Channelx will be used in memory-to-memory transfer. + This parameter can be a value of @ref DMA_memory_to_memory */ +}DMA_InitTypeDef; + +/** + * @} + */ + +/** @defgroup DMA_Exported_Constants + * @{ + */ + +#define IS_DMA_ALL_PERIPH(PERIPH) (((PERIPH) == DMA1_Channel1) || \ + ((PERIPH) == DMA1_Channel2) || \ + ((PERIPH) == DMA1_Channel3) || \ + ((PERIPH) == DMA1_Channel4) || \ + ((PERIPH) == DMA1_Channel5) || \ + ((PERIPH) == DMA1_Channel6) || \ + ((PERIPH) == DMA1_Channel7) || \ + ((PERIPH) == DMA2_Channel1) || \ + ((PERIPH) == DMA2_Channel2) || \ + ((PERIPH) == DMA2_Channel3) || \ + ((PERIPH) == DMA2_Channel4) || \ + ((PERIPH) == DMA2_Channel5)) + +/** @defgroup DMA_data_transfer_direction + * @{ + */ + +#define DMA_DIR_PeripheralDST ((uint32_t)0x00000010) +#define DMA_DIR_PeripheralSRC ((uint32_t)0x00000000) +#define IS_DMA_DIR(DIR) (((DIR) == DMA_DIR_PeripheralDST) || \ + ((DIR) == DMA_DIR_PeripheralSRC)) +/** + * @} + */ + +/** @defgroup DMA_peripheral_incremented_mode + * @{ + */ + +#define DMA_PeripheralInc_Enable ((uint32_t)0x00000040) +#define DMA_PeripheralInc_Disable ((uint32_t)0x00000000) +#define IS_DMA_PERIPHERAL_INC_STATE(STATE) (((STATE) == DMA_PeripheralInc_Enable) || \ + ((STATE) == DMA_PeripheralInc_Disable)) +/** + * @} + */ + +/** @defgroup DMA_memory_incremented_mode + * @{ + */ + +#define DMA_MemoryInc_Enable ((uint32_t)0x00000080) +#define DMA_MemoryInc_Disable ((uint32_t)0x00000000) +#define IS_DMA_MEMORY_INC_STATE(STATE) (((STATE) == DMA_MemoryInc_Enable) || \ + ((STATE) == DMA_MemoryInc_Disable)) +/** + * @} + */ + +/** @defgroup DMA_peripheral_data_size + * @{ + */ + +#define DMA_PeripheralDataSize_Byte ((uint32_t)0x00000000) +#define DMA_PeripheralDataSize_HalfWord ((uint32_t)0x00000100) +#define DMA_PeripheralDataSize_Word ((uint32_t)0x00000200) +#define IS_DMA_PERIPHERAL_DATA_SIZE(SIZE) (((SIZE) == DMA_PeripheralDataSize_Byte) || \ + ((SIZE) == DMA_PeripheralDataSize_HalfWord) || \ + ((SIZE) == DMA_PeripheralDataSize_Word)) +/** + * @} + */ + +/** @defgroup DMA_memory_data_size + * @{ + */ + +#define DMA_MemoryDataSize_Byte ((uint32_t)0x00000000) +#define DMA_MemoryDataSize_HalfWord ((uint32_t)0x00000400) +#define DMA_MemoryDataSize_Word ((uint32_t)0x00000800) +#define IS_DMA_MEMORY_DATA_SIZE(SIZE) (((SIZE) == DMA_MemoryDataSize_Byte) || \ + ((SIZE) == DMA_MemoryDataSize_HalfWord) || \ + ((SIZE) == DMA_MemoryDataSize_Word)) +/** + * @} + */ + +/** @defgroup DMA_circular_normal_mode + * @{ + */ + +#define DMA_Mode_Circular ((uint32_t)0x00000020) +#define DMA_Mode_Normal ((uint32_t)0x00000000) +#define IS_DMA_MODE(MODE) (((MODE) == DMA_Mode_Circular) || ((MODE) == DMA_Mode_Normal)) +/** + * @} + */ + +/** @defgroup DMA_priority_level + * @{ + */ + +#define DMA_Priority_VeryHigh ((uint32_t)0x00003000) +#define DMA_Priority_High ((uint32_t)0x00002000) +#define DMA_Priority_Medium ((uint32_t)0x00001000) +#define DMA_Priority_Low ((uint32_t)0x00000000) +#define IS_DMA_PRIORITY(PRIORITY) (((PRIORITY) == DMA_Priority_VeryHigh) || \ + ((PRIORITY) == DMA_Priority_High) || \ + ((PRIORITY) == DMA_Priority_Medium) || \ + ((PRIORITY) == DMA_Priority_Low)) +/** + * @} + */ + +/** @defgroup DMA_memory_to_memory + * @{ + */ + +#define DMA_M2M_Enable ((uint32_t)0x00004000) +#define DMA_M2M_Disable ((uint32_t)0x00000000) +#define IS_DMA_M2M_STATE(STATE) (((STATE) == DMA_M2M_Enable) || ((STATE) == DMA_M2M_Disable)) + +/** + * @} + */ + +/** @defgroup DMA_interrupts_definition + * @{ + */ + +#define DMA_IT_TC ((uint32_t)0x00000002) +#define DMA_IT_HT ((uint32_t)0x00000004) +#define DMA_IT_TE ((uint32_t)0x00000008) +#define IS_DMA_CONFIG_IT(IT) ((((IT) & 0xFFFFFFF1) == 0x00) && ((IT) != 0x00)) + +#define DMA1_IT_GL1 ((uint32_t)0x00000001) +#define DMA1_IT_TC1 ((uint32_t)0x00000002) +#define DMA1_IT_HT1 ((uint32_t)0x00000004) +#define DMA1_IT_TE1 ((uint32_t)0x00000008) +#define DMA1_IT_GL2 ((uint32_t)0x00000010) +#define DMA1_IT_TC2 ((uint32_t)0x00000020) +#define DMA1_IT_HT2 ((uint32_t)0x00000040) +#define DMA1_IT_TE2 ((uint32_t)0x00000080) +#define DMA1_IT_GL3 ((uint32_t)0x00000100) +#define DMA1_IT_TC3 ((uint32_t)0x00000200) +#define DMA1_IT_HT3 ((uint32_t)0x00000400) +#define DMA1_IT_TE3 ((uint32_t)0x00000800) +#define DMA1_IT_GL4 ((uint32_t)0x00001000) +#define DMA1_IT_TC4 ((uint32_t)0x00002000) +#define DMA1_IT_HT4 ((uint32_t)0x00004000) +#define DMA1_IT_TE4 ((uint32_t)0x00008000) +#define DMA1_IT_GL5 ((uint32_t)0x00010000) +#define DMA1_IT_TC5 ((uint32_t)0x00020000) +#define DMA1_IT_HT5 ((uint32_t)0x00040000) +#define DMA1_IT_TE5 ((uint32_t)0x00080000) +#define DMA1_IT_GL6 ((uint32_t)0x00100000) +#define DMA1_IT_TC6 ((uint32_t)0x00200000) +#define DMA1_IT_HT6 ((uint32_t)0x00400000) +#define DMA1_IT_TE6 ((uint32_t)0x00800000) +#define DMA1_IT_GL7 ((uint32_t)0x01000000) +#define DMA1_IT_TC7 ((uint32_t)0x02000000) +#define DMA1_IT_HT7 ((uint32_t)0x04000000) +#define DMA1_IT_TE7 ((uint32_t)0x08000000) + +#define DMA2_IT_GL1 ((uint32_t)0x10000001) +#define DMA2_IT_TC1 ((uint32_t)0x10000002) +#define DMA2_IT_HT1 ((uint32_t)0x10000004) +#define DMA2_IT_TE1 ((uint32_t)0x10000008) +#define DMA2_IT_GL2 ((uint32_t)0x10000010) +#define DMA2_IT_TC2 ((uint32_t)0x10000020) +#define DMA2_IT_HT2 ((uint32_t)0x10000040) +#define DMA2_IT_TE2 ((uint32_t)0x10000080) +#define DMA2_IT_GL3 ((uint32_t)0x10000100) +#define DMA2_IT_TC3 ((uint32_t)0x10000200) +#define DMA2_IT_HT3 ((uint32_t)0x10000400) +#define DMA2_IT_TE3 ((uint32_t)0x10000800) +#define DMA2_IT_GL4 ((uint32_t)0x10001000) +#define DMA2_IT_TC4 ((uint32_t)0x10002000) +#define DMA2_IT_HT4 ((uint32_t)0x10004000) +#define DMA2_IT_TE4 ((uint32_t)0x10008000) +#define DMA2_IT_GL5 ((uint32_t)0x10010000) +#define DMA2_IT_TC5 ((uint32_t)0x10020000) +#define DMA2_IT_HT5 ((uint32_t)0x10040000) +#define DMA2_IT_TE5 ((uint32_t)0x10080000) + +#define IS_DMA_CLEAR_IT(IT) (((((IT) & 0xF0000000) == 0x00) || (((IT) & 0xEFF00000) == 0x00)) && ((IT) != 0x00)) + +#define IS_DMA_GET_IT(IT) (((IT) == DMA1_IT_GL1) || ((IT) == DMA1_IT_TC1) || \ + ((IT) == DMA1_IT_HT1) || ((IT) == DMA1_IT_TE1) || \ + ((IT) == DMA1_IT_GL2) || ((IT) == DMA1_IT_TC2) || \ + ((IT) == DMA1_IT_HT2) || ((IT) == DMA1_IT_TE2) || \ + ((IT) == DMA1_IT_GL3) || ((IT) == DMA1_IT_TC3) || \ + ((IT) == DMA1_IT_HT3) || ((IT) == DMA1_IT_TE3) || \ + ((IT) == DMA1_IT_GL4) || ((IT) == DMA1_IT_TC4) || \ + ((IT) == DMA1_IT_HT4) || ((IT) == DMA1_IT_TE4) || \ + ((IT) == DMA1_IT_GL5) || ((IT) == DMA1_IT_TC5) || \ + ((IT) == DMA1_IT_HT5) || ((IT) == DMA1_IT_TE5) || \ + ((IT) == DMA1_IT_GL6) || ((IT) == DMA1_IT_TC6) || \ + ((IT) == DMA1_IT_HT6) || ((IT) == DMA1_IT_TE6) || \ + ((IT) == DMA1_IT_GL7) || ((IT) == DMA1_IT_TC7) || \ + ((IT) == DMA1_IT_HT7) || ((IT) == DMA1_IT_TE7) || \ + ((IT) == DMA2_IT_GL1) || ((IT) == DMA2_IT_TC1) || \ + ((IT) == DMA2_IT_HT1) || ((IT) == DMA2_IT_TE1) || \ + ((IT) == DMA2_IT_GL2) || ((IT) == DMA2_IT_TC2) || \ + ((IT) == DMA2_IT_HT2) || ((IT) == DMA2_IT_TE2) || \ + ((IT) == DMA2_IT_GL3) || ((IT) == DMA2_IT_TC3) || \ + ((IT) == DMA2_IT_HT3) || ((IT) == DMA2_IT_TE3) || \ + ((IT) == DMA2_IT_GL4) || ((IT) == DMA2_IT_TC4) || \ + ((IT) == DMA2_IT_HT4) || ((IT) == DMA2_IT_TE4) || \ + ((IT) == DMA2_IT_GL5) || ((IT) == DMA2_IT_TC5) || \ + ((IT) == DMA2_IT_HT5) || ((IT) == DMA2_IT_TE5)) + +/** + * @} + */ + +/** @defgroup DMA_flags_definition + * @{ + */ +#define DMA1_FLAG_GL1 ((uint32_t)0x00000001) +#define DMA1_FLAG_TC1 ((uint32_t)0x00000002) +#define DMA1_FLAG_HT1 ((uint32_t)0x00000004) +#define DMA1_FLAG_TE1 ((uint32_t)0x00000008) +#define DMA1_FLAG_GL2 ((uint32_t)0x00000010) +#define DMA1_FLAG_TC2 ((uint32_t)0x00000020) +#define DMA1_FLAG_HT2 ((uint32_t)0x00000040) +#define DMA1_FLAG_TE2 ((uint32_t)0x00000080) +#define DMA1_FLAG_GL3 ((uint32_t)0x00000100) +#define DMA1_FLAG_TC3 ((uint32_t)0x00000200) +#define DMA1_FLAG_HT3 ((uint32_t)0x00000400) +#define DMA1_FLAG_TE3 ((uint32_t)0x00000800) +#define DMA1_FLAG_GL4 ((uint32_t)0x00001000) +#define DMA1_FLAG_TC4 ((uint32_t)0x00002000) +#define DMA1_FLAG_HT4 ((uint32_t)0x00004000) +#define DMA1_FLAG_TE4 ((uint32_t)0x00008000) +#define DMA1_FLAG_GL5 ((uint32_t)0x00010000) +#define DMA1_FLAG_TC5 ((uint32_t)0x00020000) +#define DMA1_FLAG_HT5 ((uint32_t)0x00040000) +#define DMA1_FLAG_TE5 ((uint32_t)0x00080000) +#define DMA1_FLAG_GL6 ((uint32_t)0x00100000) +#define DMA1_FLAG_TC6 ((uint32_t)0x00200000) +#define DMA1_FLAG_HT6 ((uint32_t)0x00400000) +#define DMA1_FLAG_TE6 ((uint32_t)0x00800000) +#define DMA1_FLAG_GL7 ((uint32_t)0x01000000) +#define DMA1_FLAG_TC7 ((uint32_t)0x02000000) +#define DMA1_FLAG_HT7 ((uint32_t)0x04000000) +#define DMA1_FLAG_TE7 ((uint32_t)0x08000000) + +#define DMA2_FLAG_GL1 ((uint32_t)0x10000001) +#define DMA2_FLAG_TC1 ((uint32_t)0x10000002) +#define DMA2_FLAG_HT1 ((uint32_t)0x10000004) +#define DMA2_FLAG_TE1 ((uint32_t)0x10000008) +#define DMA2_FLAG_GL2 ((uint32_t)0x10000010) +#define DMA2_FLAG_TC2 ((uint32_t)0x10000020) +#define DMA2_FLAG_HT2 ((uint32_t)0x10000040) +#define DMA2_FLAG_TE2 ((uint32_t)0x10000080) +#define DMA2_FLAG_GL3 ((uint32_t)0x10000100) +#define DMA2_FLAG_TC3 ((uint32_t)0x10000200) +#define DMA2_FLAG_HT3 ((uint32_t)0x10000400) +#define DMA2_FLAG_TE3 ((uint32_t)0x10000800) +#define DMA2_FLAG_GL4 ((uint32_t)0x10001000) +#define DMA2_FLAG_TC4 ((uint32_t)0x10002000) +#define DMA2_FLAG_HT4 ((uint32_t)0x10004000) +#define DMA2_FLAG_TE4 ((uint32_t)0x10008000) +#define DMA2_FLAG_GL5 ((uint32_t)0x10010000) +#define DMA2_FLAG_TC5 ((uint32_t)0x10020000) +#define DMA2_FLAG_HT5 ((uint32_t)0x10040000) +#define DMA2_FLAG_TE5 ((uint32_t)0x10080000) + +#define IS_DMA_CLEAR_FLAG(FLAG) (((((FLAG) & 0xF0000000) == 0x00) || (((FLAG) & 0xEFF00000) == 0x00)) && ((FLAG) != 0x00)) + +#define IS_DMA_GET_FLAG(FLAG) (((FLAG) == DMA1_FLAG_GL1) || ((FLAG) == DMA1_FLAG_TC1) || \ + ((FLAG) == DMA1_FLAG_HT1) || ((FLAG) == DMA1_FLAG_TE1) || \ + ((FLAG) == DMA1_FLAG_GL2) || ((FLAG) == DMA1_FLAG_TC2) || \ + ((FLAG) == DMA1_FLAG_HT2) || ((FLAG) == DMA1_FLAG_TE2) || \ + ((FLAG) == DMA1_FLAG_GL3) || ((FLAG) == DMA1_FLAG_TC3) || \ + ((FLAG) == DMA1_FLAG_HT3) || ((FLAG) == DMA1_FLAG_TE3) || \ + ((FLAG) == DMA1_FLAG_GL4) || ((FLAG) == DMA1_FLAG_TC4) || \ + ((FLAG) == DMA1_FLAG_HT4) || ((FLAG) == DMA1_FLAG_TE4) || \ + ((FLAG) == DMA1_FLAG_GL5) || ((FLAG) == DMA1_FLAG_TC5) || \ + ((FLAG) == DMA1_FLAG_HT5) || ((FLAG) == DMA1_FLAG_TE5) || \ + ((FLAG) == DMA1_FLAG_GL6) || ((FLAG) == DMA1_FLAG_TC6) || \ + ((FLAG) == DMA1_FLAG_HT6) || ((FLAG) == DMA1_FLAG_TE6) || \ + ((FLAG) == DMA1_FLAG_GL7) || ((FLAG) == DMA1_FLAG_TC7) || \ + ((FLAG) == DMA1_FLAG_HT7) || ((FLAG) == DMA1_FLAG_TE7) || \ + ((FLAG) == DMA2_FLAG_GL1) || ((FLAG) == DMA2_FLAG_TC1) || \ + ((FLAG) == DMA2_FLAG_HT1) || ((FLAG) == DMA2_FLAG_TE1) || \ + ((FLAG) == DMA2_FLAG_GL2) || ((FLAG) == DMA2_FLAG_TC2) || \ + ((FLAG) == DMA2_FLAG_HT2) || ((FLAG) == DMA2_FLAG_TE2) || \ + ((FLAG) == DMA2_FLAG_GL3) || ((FLAG) == DMA2_FLAG_TC3) || \ + ((FLAG) == DMA2_FLAG_HT3) || ((FLAG) == DMA2_FLAG_TE3) || \ + ((FLAG) == DMA2_FLAG_GL4) || ((FLAG) == DMA2_FLAG_TC4) || \ + ((FLAG) == DMA2_FLAG_HT4) || ((FLAG) == DMA2_FLAG_TE4) || \ + ((FLAG) == DMA2_FLAG_GL5) || ((FLAG) == DMA2_FLAG_TC5) || \ + ((FLAG) == DMA2_FLAG_HT5) || ((FLAG) == DMA2_FLAG_TE5)) +/** + * @} + */ + +/** @defgroup DMA_Buffer_Size + * @{ + */ + +#define IS_DMA_BUFFER_SIZE(SIZE) (((SIZE) >= 0x1) && ((SIZE) < 0x10000)) + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup DMA_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup DMA_Exported_Functions + * @{ + */ + +void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx); +void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct); +void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct); +void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState); +void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState); +uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx); +FlagStatus DMA_GetFlagStatus(uint32_t DMA_FLAG); +void DMA_ClearFlag(uint32_t DMA_FLAG); +ITStatus DMA_GetITStatus(uint32_t DMA_IT); +void DMA_ClearITPendingBit(uint32_t DMA_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F10x_DMA_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_exti.h b/example/libs_stm/inc/stm32f10x/stm32f10x_exti.h new file mode 100644 index 000000000..e5f1c5a06 --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_exti.h @@ -0,0 +1,183 @@ +/** + ****************************************************************************** + * @file stm32f10x_exti.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the EXTI firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_EXTI_H +#define __STM32F10x_EXTI_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup EXTI + * @{ + */ + +/** @defgroup EXTI_Exported_Types + * @{ + */ + +/** + * @brief EXTI mode enumeration + */ + +typedef enum +{ + EXTI_Mode_Interrupt = 0x00, + EXTI_Mode_Event = 0x04 +}EXTIMode_TypeDef; + +#define IS_EXTI_MODE(MODE) (((MODE) == EXTI_Mode_Interrupt) || ((MODE) == EXTI_Mode_Event)) + +/** + * @brief EXTI Trigger enumeration + */ + +typedef enum +{ + EXTI_Trigger_Rising = 0x08, + EXTI_Trigger_Falling = 0x0C, + EXTI_Trigger_Rising_Falling = 0x10 +}EXTITrigger_TypeDef; + +#define IS_EXTI_TRIGGER(TRIGGER) (((TRIGGER) == EXTI_Trigger_Rising) || \ + ((TRIGGER) == EXTI_Trigger_Falling) || \ + ((TRIGGER) == EXTI_Trigger_Rising_Falling)) +/** + * @brief EXTI Init Structure definition + */ + +typedef struct +{ + uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled. + This parameter can be any combination of @ref EXTI_Lines */ + + EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines. + This parameter can be a value of @ref EXTIMode_TypeDef */ + + EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines. + This parameter can be a value of @ref EXTIMode_TypeDef */ + + FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines. + This parameter can be set either to ENABLE or DISABLE */ +}EXTI_InitTypeDef; + +/** + * @} + */ + +/** @defgroup EXTI_Exported_Constants + * @{ + */ + +/** @defgroup EXTI_Lines + * @{ + */ + +#define EXTI_Line0 ((uint32_t)0x00001) /*!< External interrupt line 0 */ +#define EXTI_Line1 ((uint32_t)0x00002) /*!< External interrupt line 1 */ +#define EXTI_Line2 ((uint32_t)0x00004) /*!< External interrupt line 2 */ +#define EXTI_Line3 ((uint32_t)0x00008) /*!< External interrupt line 3 */ +#define EXTI_Line4 ((uint32_t)0x00010) /*!< External interrupt line 4 */ +#define EXTI_Line5 ((uint32_t)0x00020) /*!< External interrupt line 5 */ +#define EXTI_Line6 ((uint32_t)0x00040) /*!< External interrupt line 6 */ +#define EXTI_Line7 ((uint32_t)0x00080) /*!< External interrupt line 7 */ +#define EXTI_Line8 ((uint32_t)0x00100) /*!< External interrupt line 8 */ +#define EXTI_Line9 ((uint32_t)0x00200) /*!< External interrupt line 9 */ +#define EXTI_Line10 ((uint32_t)0x00400) /*!< External interrupt line 10 */ +#define EXTI_Line11 ((uint32_t)0x00800) /*!< External interrupt line 11 */ +#define EXTI_Line12 ((uint32_t)0x01000) /*!< External interrupt line 12 */ +#define EXTI_Line13 ((uint32_t)0x02000) /*!< External interrupt line 13 */ +#define EXTI_Line14 ((uint32_t)0x04000) /*!< External interrupt line 14 */ +#define EXTI_Line15 ((uint32_t)0x08000) /*!< External interrupt line 15 */ +#define EXTI_Line16 ((uint32_t)0x10000) /*!< External interrupt line 16 Connected to the PVD Output */ +#define EXTI_Line17 ((uint32_t)0x20000) /*!< External interrupt line 17 Connected to the RTC Alarm event */ +#define EXTI_Line18 ((uint32_t)0x40000) /*!< External interrupt line 18 Connected to the USB Device/USB OTG FS + Wakeup from suspend event */ +#define EXTI_Line19 ((uint32_t)0x80000) /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */ + +#define IS_EXTI_LINE(LINE) ((((LINE) & (uint32_t)0xFFF00000) == 0x00) && ((LINE) != (uint16_t)0x00)) +#define IS_GET_EXTI_LINE(LINE) (((LINE) == EXTI_Line0) || ((LINE) == EXTI_Line1) || \ + ((LINE) == EXTI_Line2) || ((LINE) == EXTI_Line3) || \ + ((LINE) == EXTI_Line4) || ((LINE) == EXTI_Line5) || \ + ((LINE) == EXTI_Line6) || ((LINE) == EXTI_Line7) || \ + ((LINE) == EXTI_Line8) || ((LINE) == EXTI_Line9) || \ + ((LINE) == EXTI_Line10) || ((LINE) == EXTI_Line11) || \ + ((LINE) == EXTI_Line12) || ((LINE) == EXTI_Line13) || \ + ((LINE) == EXTI_Line14) || ((LINE) == EXTI_Line15) || \ + ((LINE) == EXTI_Line16) || ((LINE) == EXTI_Line17) || \ + ((LINE) == EXTI_Line18) || ((LINE) == EXTI_Line19)) + + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup EXTI_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup EXTI_Exported_Functions + * @{ + */ + +void EXTI_DeInit(void); +void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct); +void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct); +void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line); +FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line); +void EXTI_ClearFlag(uint32_t EXTI_Line); +ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); +void EXTI_ClearITPendingBit(uint32_t EXTI_Line); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_EXTI_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_flash.h b/example/libs_stm/inc/stm32f10x/stm32f10x_flash.h new file mode 100644 index 000000000..71943013d --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_flash.h @@ -0,0 +1,425 @@ +/** + ****************************************************************************** + * @file stm32f10x_flash.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the FLASH + * firmware library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_FLASH_H +#define __STM32F10x_FLASH_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup FLASH + * @{ + */ + +/** @defgroup FLASH_Exported_Types + * @{ + */ + +/** + * @brief FLASH Status + */ + +typedef enum +{ + FLASH_BUSY = 1, + FLASH_ERROR_PG, + FLASH_ERROR_WRP, + FLASH_COMPLETE, + FLASH_TIMEOUT +}FLASH_Status; + +/** + * @} + */ + +/** @defgroup FLASH_Exported_Constants + * @{ + */ + +/** @defgroup Flash_Latency + * @{ + */ + +#define FLASH_Latency_0 ((uint32_t)0x00000000) /*!< FLASH Zero Latency cycle */ +#define FLASH_Latency_1 ((uint32_t)0x00000001) /*!< FLASH One Latency cycle */ +#define FLASH_Latency_2 ((uint32_t)0x00000002) /*!< FLASH Two Latency cycles */ +#define IS_FLASH_LATENCY(LATENCY) (((LATENCY) == FLASH_Latency_0) || \ + ((LATENCY) == FLASH_Latency_1) || \ + ((LATENCY) == FLASH_Latency_2)) +/** + * @} + */ + +/** @defgroup Half_Cycle_Enable_Disable + * @{ + */ + +#define FLASH_HalfCycleAccess_Enable ((uint32_t)0x00000008) /*!< FLASH Half Cycle Enable */ +#define FLASH_HalfCycleAccess_Disable ((uint32_t)0x00000000) /*!< FLASH Half Cycle Disable */ +#define IS_FLASH_HALFCYCLEACCESS_STATE(STATE) (((STATE) == FLASH_HalfCycleAccess_Enable) || \ + ((STATE) == FLASH_HalfCycleAccess_Disable)) +/** + * @} + */ + +/** @defgroup Prefetch_Buffer_Enable_Disable + * @{ + */ + +#define FLASH_PrefetchBuffer_Enable ((uint32_t)0x00000010) /*!< FLASH Prefetch Buffer Enable */ +#define FLASH_PrefetchBuffer_Disable ((uint32_t)0x00000000) /*!< FLASH Prefetch Buffer Disable */ +#define IS_FLASH_PREFETCHBUFFER_STATE(STATE) (((STATE) == FLASH_PrefetchBuffer_Enable) || \ + ((STATE) == FLASH_PrefetchBuffer_Disable)) +/** + * @} + */ + +/** @defgroup Option_Bytes_Write_Protection + * @{ + */ + +/* Values to be used with STM32 Low and Medium density devices */ +#define FLASH_WRProt_Pages0to3 ((uint32_t)0x00000001) /*!< STM32 Low and Medium density devices: Write protection of page 0 to 3 */ +#define FLASH_WRProt_Pages4to7 ((uint32_t)0x00000002) /*!< STM32 Low and Medium density devices: Write protection of page 4 to 7 */ +#define FLASH_WRProt_Pages8to11 ((uint32_t)0x00000004) /*!< STM32 Low and Medium density devices: Write protection of page 8 to 11 */ +#define FLASH_WRProt_Pages12to15 ((uint32_t)0x00000008) /*!< STM32 Low and Medium density devices: Write protection of page 12 to 15 */ +#define FLASH_WRProt_Pages16to19 ((uint32_t)0x00000010) /*!< STM32 Low and Medium density devices: Write protection of page 16 to 19 */ +#define FLASH_WRProt_Pages20to23 ((uint32_t)0x00000020) /*!< STM32 Low and Medium density devices: Write protection of page 20 to 23 */ +#define FLASH_WRProt_Pages24to27 ((uint32_t)0x00000040) /*!< STM32 Low and Medium density devices: Write protection of page 24 to 27 */ +#define FLASH_WRProt_Pages28to31 ((uint32_t)0x00000080) /*!< STM32 Low and Medium density devices: Write protection of page 28 to 31 */ + +/* Values to be used with STM32 Medium-density devices */ +#define FLASH_WRProt_Pages32to35 ((uint32_t)0x00000100) /*!< STM32 Medium-density devices: Write protection of page 32 to 35 */ +#define FLASH_WRProt_Pages36to39 ((uint32_t)0x00000200) /*!< STM32 Medium-density devices: Write protection of page 36 to 39 */ +#define FLASH_WRProt_Pages40to43 ((uint32_t)0x00000400) /*!< STM32 Medium-density devices: Write protection of page 40 to 43 */ +#define FLASH_WRProt_Pages44to47 ((uint32_t)0x00000800) /*!< STM32 Medium-density devices: Write protection of page 44 to 47 */ +#define FLASH_WRProt_Pages48to51 ((uint32_t)0x00001000) /*!< STM32 Medium-density devices: Write protection of page 48 to 51 */ +#define FLASH_WRProt_Pages52to55 ((uint32_t)0x00002000) /*!< STM32 Medium-density devices: Write protection of page 52 to 55 */ +#define FLASH_WRProt_Pages56to59 ((uint32_t)0x00004000) /*!< STM32 Medium-density devices: Write protection of page 56 to 59 */ +#define FLASH_WRProt_Pages60to63 ((uint32_t)0x00008000) /*!< STM32 Medium-density devices: Write protection of page 60 to 63 */ +#define FLASH_WRProt_Pages64to67 ((uint32_t)0x00010000) /*!< STM32 Medium-density devices: Write protection of page 64 to 67 */ +#define FLASH_WRProt_Pages68to71 ((uint32_t)0x00020000) /*!< STM32 Medium-density devices: Write protection of page 68 to 71 */ +#define FLASH_WRProt_Pages72to75 ((uint32_t)0x00040000) /*!< STM32 Medium-density devices: Write protection of page 72 to 75 */ +#define FLASH_WRProt_Pages76to79 ((uint32_t)0x00080000) /*!< STM32 Medium-density devices: Write protection of page 76 to 79 */ +#define FLASH_WRProt_Pages80to83 ((uint32_t)0x00100000) /*!< STM32 Medium-density devices: Write protection of page 80 to 83 */ +#define FLASH_WRProt_Pages84to87 ((uint32_t)0x00200000) /*!< STM32 Medium-density devices: Write protection of page 84 to 87 */ +#define FLASH_WRProt_Pages88to91 ((uint32_t)0x00400000) /*!< STM32 Medium-density devices: Write protection of page 88 to 91 */ +#define FLASH_WRProt_Pages92to95 ((uint32_t)0x00800000) /*!< STM32 Medium-density devices: Write protection of page 92 to 95 */ +#define FLASH_WRProt_Pages96to99 ((uint32_t)0x01000000) /*!< STM32 Medium-density devices: Write protection of page 96 to 99 */ +#define FLASH_WRProt_Pages100to103 ((uint32_t)0x02000000) /*!< STM32 Medium-density devices: Write protection of page 100 to 103 */ +#define FLASH_WRProt_Pages104to107 ((uint32_t)0x04000000) /*!< STM32 Medium-density devices: Write protection of page 104 to 107 */ +#define FLASH_WRProt_Pages108to111 ((uint32_t)0x08000000) /*!< STM32 Medium-density devices: Write protection of page 108 to 111 */ +#define FLASH_WRProt_Pages112to115 ((uint32_t)0x10000000) /*!< STM32 Medium-density devices: Write protection of page 112 to 115 */ +#define FLASH_WRProt_Pages116to119 ((uint32_t)0x20000000) /*!< STM32 Medium-density devices: Write protection of page 115 to 119 */ +#define FLASH_WRProt_Pages120to123 ((uint32_t)0x40000000) /*!< STM32 Medium-density devices: Write protection of page 120 to 123 */ +#define FLASH_WRProt_Pages124to127 ((uint32_t)0x80000000) /*!< STM32 Medium-density devices: Write protection of page 124 to 127 */ + +/* Values to be used with STM32 High-density and STM32F10X Connectivity line devices */ +#define FLASH_WRProt_Pages0to1 ((uint32_t)0x00000001) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 0 to 1 */ +#define FLASH_WRProt_Pages2to3 ((uint32_t)0x00000002) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 2 to 3 */ +#define FLASH_WRProt_Pages4to5 ((uint32_t)0x00000004) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 4 to 5 */ +#define FLASH_WRProt_Pages6to7 ((uint32_t)0x00000008) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 6 to 7 */ +#define FLASH_WRProt_Pages8to9 ((uint32_t)0x00000010) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 8 to 9 */ +#define FLASH_WRProt_Pages10to11 ((uint32_t)0x00000020) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 10 to 11 */ +#define FLASH_WRProt_Pages12to13 ((uint32_t)0x00000040) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 12 to 13 */ +#define FLASH_WRProt_Pages14to15 ((uint32_t)0x00000080) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 14 to 15 */ +#define FLASH_WRProt_Pages16to17 ((uint32_t)0x00000100) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 16 to 17 */ +#define FLASH_WRProt_Pages18to19 ((uint32_t)0x00000200) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 18 to 19 */ +#define FLASH_WRProt_Pages20to21 ((uint32_t)0x00000400) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 20 to 21 */ +#define FLASH_WRProt_Pages22to23 ((uint32_t)0x00000800) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 22 to 23 */ +#define FLASH_WRProt_Pages24to25 ((uint32_t)0x00001000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 24 to 25 */ +#define FLASH_WRProt_Pages26to27 ((uint32_t)0x00002000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 26 to 27 */ +#define FLASH_WRProt_Pages28to29 ((uint32_t)0x00004000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 28 to 29 */ +#define FLASH_WRProt_Pages30to31 ((uint32_t)0x00008000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 30 to 31 */ +#define FLASH_WRProt_Pages32to33 ((uint32_t)0x00010000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 32 to 33 */ +#define FLASH_WRProt_Pages34to35 ((uint32_t)0x00020000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 34 to 35 */ +#define FLASH_WRProt_Pages36to37 ((uint32_t)0x00040000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 36 to 37 */ +#define FLASH_WRProt_Pages38to39 ((uint32_t)0x00080000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 38 to 39 */ +#define FLASH_WRProt_Pages40to41 ((uint32_t)0x00100000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 40 to 41 */ +#define FLASH_WRProt_Pages42to43 ((uint32_t)0x00200000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 42 to 43 */ +#define FLASH_WRProt_Pages44to45 ((uint32_t)0x00400000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 44 to 45 */ +#define FLASH_WRProt_Pages46to47 ((uint32_t)0x00800000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 46 to 47 */ +#define FLASH_WRProt_Pages48to49 ((uint32_t)0x01000000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 48 to 49 */ +#define FLASH_WRProt_Pages50to51 ((uint32_t)0x02000000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 50 to 51 */ +#define FLASH_WRProt_Pages52to53 ((uint32_t)0x04000000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 52 to 53 */ +#define FLASH_WRProt_Pages54to55 ((uint32_t)0x08000000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 54 to 55 */ +#define FLASH_WRProt_Pages56to57 ((uint32_t)0x10000000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 56 to 57 */ +#define FLASH_WRProt_Pages58to59 ((uint32_t)0x20000000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 58 to 59 */ +#define FLASH_WRProt_Pages60to61 ((uint32_t)0x40000000) /*!< STM32 High-density, XL-density and Connectivity line devices: + Write protection of page 60 to 61 */ +#define FLASH_WRProt_Pages62to127 ((uint32_t)0x80000000) /*!< STM32 Connectivity line devices: Write protection of page 62 to 127 */ +#define FLASH_WRProt_Pages62to255 ((uint32_t)0x80000000) /*!< STM32 Medium-density devices: Write protection of page 62 to 255 */ +#define FLASH_WRProt_Pages62to511 ((uint32_t)0x80000000) /*!< STM32 XL-density devices: Write protection of page 62 to 511 */ + +#define FLASH_WRProt_AllPages ((uint32_t)0xFFFFFFFF) /*!< Write protection of all Pages */ + +#define IS_FLASH_WRPROT_PAGE(PAGE) (((PAGE) != 0x00000000)) + +#define IS_FLASH_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x080FFFFF)) + +#define IS_OB_DATA_ADDRESS(ADDRESS) (((ADDRESS) == 0x1FFFF804) || ((ADDRESS) == 0x1FFFF806)) + +/** + * @} + */ + +/** @defgroup Option_Bytes_IWatchdog + * @{ + */ + +#define OB_IWDG_SW ((uint16_t)0x0001) /*!< Software IWDG selected */ +#define OB_IWDG_HW ((uint16_t)0x0000) /*!< Hardware IWDG selected */ +#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW)) + +/** + * @} + */ + +/** @defgroup Option_Bytes_nRST_STOP + * @{ + */ + +#define OB_STOP_NoRST ((uint16_t)0x0002) /*!< No reset generated when entering in STOP */ +#define OB_STOP_RST ((uint16_t)0x0000) /*!< Reset generated when entering in STOP */ +#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NoRST) || ((SOURCE) == OB_STOP_RST)) + +/** + * @} + */ + +/** @defgroup Option_Bytes_nRST_STDBY + * @{ + */ + +#define OB_STDBY_NoRST ((uint16_t)0x0004) /*!< No reset generated when entering in STANDBY */ +#define OB_STDBY_RST ((uint16_t)0x0000) /*!< Reset generated when entering in STANDBY */ +#define IS_OB_STDBY_SOURCE(SOURCE) (((SOURCE) == OB_STDBY_NoRST) || ((SOURCE) == OB_STDBY_RST)) + +#ifdef STM32F10X_XL +/** + * @} + */ +/** @defgroup FLASH_Boot + * @{ + */ +#define FLASH_BOOT_Bank1 ((uint16_t)0x0000) /*!< At startup, if boot pins are set in boot from user Flash position + and this parameter is selected the device will boot from Bank1(Default) */ +#define FLASH_BOOT_Bank2 ((uint16_t)0x0001) /*!< At startup, if boot pins are set in boot from user Flash position + and this parameter is selected the device will boot from Bank 2 or Bank 1, + depending on the activation of the bank */ +#define IS_FLASH_BOOT(BOOT) (((BOOT) == FLASH_BOOT_Bank1) || ((BOOT) == FLASH_BOOT_Bank2)) +#endif +/** + * @} + */ +/** @defgroup FLASH_Interrupts + * @{ + */ +#ifdef STM32F10X_XL +#define FLASH_IT_BANK2_ERROR ((uint32_t)0x80000400) /*!< FPEC BANK2 error interrupt source */ +#define FLASH_IT_BANK2_EOP ((uint32_t)0x80001000) /*!< End of FLASH BANK2 Operation Interrupt source */ + +#define FLASH_IT_BANK1_ERROR FLASH_IT_ERROR /*!< FPEC BANK1 error interrupt source */ +#define FLASH_IT_BANK1_EOP FLASH_IT_EOP /*!< End of FLASH BANK1 Operation Interrupt source */ + +#define FLASH_IT_ERROR ((uint32_t)0x00000400) /*!< FPEC BANK1 error interrupt source */ +#define FLASH_IT_EOP ((uint32_t)0x00001000) /*!< End of FLASH BANK1 Operation Interrupt source */ +#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0x7FFFEBFF) == 0x00000000) && (((IT) != 0x00000000))) +#else +#define FLASH_IT_ERROR ((uint32_t)0x00000400) /*!< FPEC error interrupt source */ +#define FLASH_IT_EOP ((uint32_t)0x00001000) /*!< End of FLASH Operation Interrupt source */ +#define FLASH_IT_BANK1_ERROR FLASH_IT_ERROR /*!< FPEC BANK1 error interrupt source */ +#define FLASH_IT_BANK1_EOP FLASH_IT_EOP /*!< End of FLASH BANK1 Operation Interrupt source */ + +#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0xFFFFEBFF) == 0x00000000) && (((IT) != 0x00000000))) +#endif + +/** + * @} + */ + +/** @defgroup FLASH_Flags + * @{ + */ +#ifdef STM32F10X_XL +#define FLASH_FLAG_BANK2_BSY ((uint32_t)0x80000001) /*!< FLASH BANK2 Busy flag */ +#define FLASH_FLAG_BANK2_EOP ((uint32_t)0x80000020) /*!< FLASH BANK2 End of Operation flag */ +#define FLASH_FLAG_BANK2_PGERR ((uint32_t)0x80000004) /*!< FLASH BANK2 Program error flag */ +#define FLASH_FLAG_BANK2_WRPRTERR ((uint32_t)0x80000010) /*!< FLASH BANK2 Write protected error flag */ + +#define FLASH_FLAG_BANK1_BSY FLASH_FLAG_BSY /*!< FLASH BANK1 Busy flag*/ +#define FLASH_FLAG_BANK1_EOP FLASH_FLAG_EOP /*!< FLASH BANK1 End of Operation flag */ +#define FLASH_FLAG_BANK1_PGERR FLASH_FLAG_PGERR /*!< FLASH BANK1 Program error flag */ +#define FLASH_FLAG_BANK1_WRPRTERR FLASH_FLAG_WRPRTERR /*!< FLASH BANK1 Write protected error flag */ + +#define FLASH_FLAG_BSY ((uint32_t)0x00000001) /*!< FLASH Busy flag */ +#define FLASH_FLAG_EOP ((uint32_t)0x00000020) /*!< FLASH End of Operation flag */ +#define FLASH_FLAG_PGERR ((uint32_t)0x00000004) /*!< FLASH Program error flag */ +#define FLASH_FLAG_WRPRTERR ((uint32_t)0x00000010) /*!< FLASH Write protected error flag */ +#define FLASH_FLAG_OPTERR ((uint32_t)0x00000001) /*!< FLASH Option Byte error flag */ + +#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0x7FFFFFCA) == 0x00000000) && ((FLAG) != 0x00000000)) +#define IS_FLASH_GET_FLAG(FLAG) (((FLAG) == FLASH_FLAG_BSY) || ((FLAG) == FLASH_FLAG_EOP) || \ + ((FLAG) == FLASH_FLAG_PGERR) || ((FLAG) == FLASH_FLAG_WRPRTERR) || \ + ((FLAG) == FLASH_FLAG_OPTERR)|| \ + ((FLAG) == FLASH_FLAG_BANK1_BSY) || ((FLAG) == FLASH_FLAG_BANK1_EOP) || \ + ((FLAG) == FLASH_FLAG_BANK1_PGERR) || ((FLAG) == FLASH_FLAG_BANK1_WRPRTERR) || \ + ((FLAG) == FLASH_FLAG_BANK2_BSY) || ((FLAG) == FLASH_FLAG_BANK2_EOP) || \ + ((FLAG) == FLASH_FLAG_BANK2_PGERR) || ((FLAG) == FLASH_FLAG_BANK2_WRPRTERR)) +#else +#define FLASH_FLAG_BSY ((uint32_t)0x00000001) /*!< FLASH Busy flag */ +#define FLASH_FLAG_EOP ((uint32_t)0x00000020) /*!< FLASH End of Operation flag */ +#define FLASH_FLAG_PGERR ((uint32_t)0x00000004) /*!< FLASH Program error flag */ +#define FLASH_FLAG_WRPRTERR ((uint32_t)0x00000010) /*!< FLASH Write protected error flag */ +#define FLASH_FLAG_OPTERR ((uint32_t)0x00000001) /*!< FLASH Option Byte error flag */ + +#define FLASH_FLAG_BANK1_BSY FLASH_FLAG_BSY /*!< FLASH BANK1 Busy flag*/ +#define FLASH_FLAG_BANK1_EOP FLASH_FLAG_EOP /*!< FLASH BANK1 End of Operation flag */ +#define FLASH_FLAG_BANK1_PGERR FLASH_FLAG_PGERR /*!< FLASH BANK1 Program error flag */ +#define FLASH_FLAG_BANK1_WRPRTERR FLASH_FLAG_WRPRTERR /*!< FLASH BANK1 Write protected error flag */ + +#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFCA) == 0x00000000) && ((FLAG) != 0x00000000)) +#define IS_FLASH_GET_FLAG(FLAG) (((FLAG) == FLASH_FLAG_BSY) || ((FLAG) == FLASH_FLAG_EOP) || \ + ((FLAG) == FLASH_FLAG_PGERR) || ((FLAG) == FLASH_FLAG_WRPRTERR) || \ + ((FLAG) == FLASH_FLAG_BANK1_BSY) || ((FLAG) == FLASH_FLAG_BANK1_EOP) || \ + ((FLAG) == FLASH_FLAG_BANK1_PGERR) || ((FLAG) == FLASH_FLAG_BANK1_WRPRTERR) || \ + ((FLAG) == FLASH_FLAG_OPTERR)) +#endif + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FLASH_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup FLASH_Exported_Functions + * @{ + */ + +/*------------ Functions used for all STM32F10x devices -----*/ +void FLASH_SetLatency(uint32_t FLASH_Latency); +void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess); +void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer); +void FLASH_Unlock(void); +void FLASH_Lock(void); +FLASH_Status FLASH_ErasePage(uint32_t Page_Address); +FLASH_Status FLASH_EraseAllPages(void); +FLASH_Status FLASH_EraseOptionBytes(void); +FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data); +FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data); +FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data); +FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages); +FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState); +FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY); +uint32_t FLASH_GetUserOptionByte(void); +uint32_t FLASH_GetWriteProtectionOptionByte(void); +FlagStatus FLASH_GetReadOutProtectionStatus(void); +FlagStatus FLASH_GetPrefetchBufferStatus(void); +void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState); +FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG); +void FLASH_ClearFlag(uint32_t FLASH_FLAG); +FLASH_Status FLASH_GetStatus(void); +FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout); + +/*------------ New function used for all STM32F10x devices -----*/ +void FLASH_UnlockBank1(void); +void FLASH_LockBank1(void); +FLASH_Status FLASH_EraseAllBank1Pages(void); +FLASH_Status FLASH_GetBank1Status(void); +FLASH_Status FLASH_WaitForLastBank1Operation(uint32_t Timeout); + +#ifdef STM32F10X_XL +/*---- New Functions used only with STM32F10x_XL density devices -----*/ +void FLASH_UnlockBank2(void); +void FLASH_LockBank2(void); +FLASH_Status FLASH_EraseAllBank2Pages(void); +FLASH_Status FLASH_GetBank2Status(void); +FLASH_Status FLASH_WaitForLastBank2Operation(uint32_t Timeout); +FLASH_Status FLASH_BootConfig(uint16_t FLASH_BOOT); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_FLASH_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_fsmc.h b/example/libs_stm/inc/stm32f10x/stm32f10x_fsmc.h new file mode 100644 index 000000000..944f077ed --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_fsmc.h @@ -0,0 +1,716 @@ +/** + ****************************************************************************** + * @file stm32f10x_fsmc.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the FSMC firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_FSMC_H +#define __STM32F10x_FSMC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup FSMC + * @{ + */ + +/** @defgroup FSMC_Exported_Types + * @{ + */ + +/** + * @brief Timing parameters For NOR/SRAM Banks + */ + +typedef struct +{ + uint32_t FSMC_AddressSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address setup time. + This parameter can be a value between 0 and 0xF. + @note: It is not used with synchronous NOR Flash memories. */ + + uint32_t FSMC_AddressHoldTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address hold time. + This parameter can be a value between 0 and 0xF. + @note: It is not used with synchronous NOR Flash memories.*/ + + uint32_t FSMC_DataSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the data setup time. + This parameter can be a value between 0 and 0xFF. + @note: It is used for SRAMs, ROMs and asynchronous multiplexed NOR Flash memories. */ + + uint32_t FSMC_BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure + the duration of the bus turnaround. + This parameter can be a value between 0 and 0xF. + @note: It is only used for multiplexed NOR Flash memories. */ + + uint32_t FSMC_CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of HCLK cycles. + This parameter can be a value between 1 and 0xF. + @note: This parameter is not used for asynchronous NOR Flash, SRAM or ROM accesses. */ + + uint32_t FSMC_DataLatency; /*!< Defines the number of memory clock cycles to issue + to the memory before getting the first data. + The value of this parameter depends on the memory type as shown below: + - It must be set to 0 in case of a CRAM + - It is dont care in asynchronous NOR, SRAM or ROM accesses + - It may assume a value between 0 and 0xF in NOR Flash memories + with synchronous burst mode enable */ + + uint32_t FSMC_AccessMode; /*!< Specifies the asynchronous access mode. + This parameter can be a value of @ref FSMC_Access_Mode */ +}FSMC_NORSRAMTimingInitTypeDef; + +/** + * @brief FSMC NOR/SRAM Init structure definition + */ + +typedef struct +{ + uint32_t FSMC_Bank; /*!< Specifies the NOR/SRAM memory bank that will be used. + This parameter can be a value of @ref FSMC_NORSRAM_Bank */ + + uint32_t FSMC_DataAddressMux; /*!< Specifies whether the address and data values are + multiplexed on the databus or not. + This parameter can be a value of @ref FSMC_Data_Address_Bus_Multiplexing */ + + uint32_t FSMC_MemoryType; /*!< Specifies the type of external memory attached to + the corresponding memory bank. + This parameter can be a value of @ref FSMC_Memory_Type */ + + uint32_t FSMC_MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be a value of @ref FSMC_Data_Width */ + + uint32_t FSMC_BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory, + valid only with synchronous burst Flash memories. + This parameter can be a value of @ref FSMC_Burst_Access_Mode */ + + uint32_t FSMC_WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing + the Flash memory in burst mode. + This parameter can be a value of @ref FSMC_Wait_Signal_Polarity */ + + uint32_t FSMC_WrapMode; /*!< Enables or disables the Wrapped burst access mode for Flash + memory, valid only when accessing Flash memories in burst mode. + This parameter can be a value of @ref FSMC_Wrap_Mode */ + + uint32_t FSMC_WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one + clock cycle before the wait state or during the wait state, + valid only when accessing memories in burst mode. + This parameter can be a value of @ref FSMC_Wait_Timing */ + + uint32_t FSMC_WriteOperation; /*!< Enables or disables the write operation in the selected bank by the FSMC. + This parameter can be a value of @ref FSMC_Write_Operation */ + + uint32_t FSMC_WaitSignal; /*!< Enables or disables the wait-state insertion via wait + signal, valid for Flash memory access in burst mode. + This parameter can be a value of @ref FSMC_Wait_Signal */ + + uint32_t FSMC_ExtendedMode; /*!< Enables or disables the extended mode. + This parameter can be a value of @ref FSMC_Extended_Mode */ + + uint32_t FSMC_WriteBurst; /*!< Enables or disables the write burst operation. + This parameter can be a value of @ref FSMC_Write_Burst */ + + FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct; /*!< Timing Parameters for write and read access if the ExtendedMode is not used*/ + + FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct; /*!< Timing Parameters for write access if the ExtendedMode is used*/ +}FSMC_NORSRAMInitTypeDef; + +/** + * @brief Timing parameters For FSMC NAND and PCCARD Banks + */ + +typedef struct +{ + uint32_t FSMC_SetupTime; /*!< Defines the number of HCLK cycles to setup address before + the command assertion for NAND-Flash read or write access + to common/Attribute or I/O memory space (depending on + the memory space timing to be configured). + This parameter can be a value between 0 and 0xFF.*/ + + uint32_t FSMC_WaitSetupTime; /*!< Defines the minimum number of HCLK cycles to assert the + command for NAND-Flash read or write access to + common/Attribute or I/O memory space (depending on the + memory space timing to be configured). + This parameter can be a number between 0x00 and 0xFF */ + + uint32_t FSMC_HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address + (and data for write access) after the command deassertion + for NAND-Flash read or write access to common/Attribute + or I/O memory space (depending on the memory space timing + to be configured). + This parameter can be a number between 0x00 and 0xFF */ + + uint32_t FSMC_HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the + databus is kept in HiZ after the start of a NAND-Flash + write access to common/Attribute or I/O memory space (depending + on the memory space timing to be configured). + This parameter can be a number between 0x00 and 0xFF */ +}FSMC_NAND_PCCARDTimingInitTypeDef; + +/** + * @brief FSMC NAND Init structure definition + */ + +typedef struct +{ + uint32_t FSMC_Bank; /*!< Specifies the NAND memory bank that will be used. + This parameter can be a value of @ref FSMC_NAND_Bank */ + + uint32_t FSMC_Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory Bank. + This parameter can be any value of @ref FSMC_Wait_feature */ + + uint32_t FSMC_MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be any value of @ref FSMC_Data_Width */ + + uint32_t FSMC_ECC; /*!< Enables or disables the ECC computation. + This parameter can be any value of @ref FSMC_ECC */ + + uint32_t FSMC_ECCPageSize; /*!< Defines the page size for the extended ECC. + This parameter can be any value of @ref FSMC_ECC_Page_Size */ + + uint32_t FSMC_TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between CLE low and RE low. + This parameter can be a value between 0 and 0xFF. */ + + uint32_t FSMC_TARSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between ALE low and RE low. + This parameter can be a number between 0x0 and 0xFF */ + + FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_CommonSpaceTimingStruct; /*!< FSMC Common Space Timing */ + + FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_AttributeSpaceTimingStruct; /*!< FSMC Attribute Space Timing */ +}FSMC_NANDInitTypeDef; + +/** + * @brief FSMC PCCARD Init structure definition + */ + +typedef struct +{ + uint32_t FSMC_Waitfeature; /*!< Enables or disables the Wait feature for the Memory Bank. + This parameter can be any value of @ref FSMC_Wait_feature */ + + uint32_t FSMC_TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between CLE low and RE low. + This parameter can be a value between 0 and 0xFF. */ + + uint32_t FSMC_TARSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between ALE low and RE low. + This parameter can be a number between 0x0 and 0xFF */ + + + FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_CommonSpaceTimingStruct; /*!< FSMC Common Space Timing */ + + FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_AttributeSpaceTimingStruct; /*!< FSMC Attribute Space Timing */ + + FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_IOSpaceTimingStruct; /*!< FSMC IO Space Timing */ +}FSMC_PCCARDInitTypeDef; + +/** + * @} + */ + +/** @defgroup FSMC_Exported_Constants + * @{ + */ + +/** @defgroup FSMC_NORSRAM_Bank + * @{ + */ +#define FSMC_Bank1_NORSRAM1 ((uint32_t)0x00000000) +#define FSMC_Bank1_NORSRAM2 ((uint32_t)0x00000002) +#define FSMC_Bank1_NORSRAM3 ((uint32_t)0x00000004) +#define FSMC_Bank1_NORSRAM4 ((uint32_t)0x00000006) +/** + * @} + */ + +/** @defgroup FSMC_NAND_Bank + * @{ + */ +#define FSMC_Bank2_NAND ((uint32_t)0x00000010) +#define FSMC_Bank3_NAND ((uint32_t)0x00000100) +/** + * @} + */ + +/** @defgroup FSMC_PCCARD_Bank + * @{ + */ +#define FSMC_Bank4_PCCARD ((uint32_t)0x00001000) +/** + * @} + */ + +#define IS_FSMC_NORSRAM_BANK(BANK) (((BANK) == FSMC_Bank1_NORSRAM1) || \ + ((BANK) == FSMC_Bank1_NORSRAM2) || \ + ((BANK) == FSMC_Bank1_NORSRAM3) || \ + ((BANK) == FSMC_Bank1_NORSRAM4)) + +#define IS_FSMC_NAND_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \ + ((BANK) == FSMC_Bank3_NAND)) + +#define IS_FSMC_GETFLAG_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \ + ((BANK) == FSMC_Bank3_NAND) || \ + ((BANK) == FSMC_Bank4_PCCARD)) + +#define IS_FSMC_IT_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \ + ((BANK) == FSMC_Bank3_NAND) || \ + ((BANK) == FSMC_Bank4_PCCARD)) + +/** @defgroup NOR_SRAM_Controller + * @{ + */ + +/** @defgroup FSMC_Data_Address_Bus_Multiplexing + * @{ + */ + +#define FSMC_DataAddressMux_Disable ((uint32_t)0x00000000) +#define FSMC_DataAddressMux_Enable ((uint32_t)0x00000002) +#define IS_FSMC_MUX(MUX) (((MUX) == FSMC_DataAddressMux_Disable) || \ + ((MUX) == FSMC_DataAddressMux_Enable)) + +/** + * @} + */ + +/** @defgroup FSMC_Memory_Type + * @{ + */ + +#define FSMC_MemoryType_SRAM ((uint32_t)0x00000000) +#define FSMC_MemoryType_PSRAM ((uint32_t)0x00000004) +#define FSMC_MemoryType_NOR ((uint32_t)0x00000008) +#define IS_FSMC_MEMORY(MEMORY) (((MEMORY) == FSMC_MemoryType_SRAM) || \ + ((MEMORY) == FSMC_MemoryType_PSRAM)|| \ + ((MEMORY) == FSMC_MemoryType_NOR)) + +/** + * @} + */ + +/** @defgroup FSMC_Data_Width + * @{ + */ + +#define FSMC_MemoryDataWidth_8b ((uint32_t)0x00000000) +#define FSMC_MemoryDataWidth_16b ((uint32_t)0x00000010) +#define IS_FSMC_MEMORY_WIDTH(WIDTH) (((WIDTH) == FSMC_MemoryDataWidth_8b) || \ + ((WIDTH) == FSMC_MemoryDataWidth_16b)) + +/** + * @} + */ + +/** @defgroup FSMC_Burst_Access_Mode + * @{ + */ + +#define FSMC_BurstAccessMode_Disable ((uint32_t)0x00000000) +#define FSMC_BurstAccessMode_Enable ((uint32_t)0x00000100) +#define IS_FSMC_BURSTMODE(STATE) (((STATE) == FSMC_BurstAccessMode_Disable) || \ + ((STATE) == FSMC_BurstAccessMode_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_Wait_Signal_Polarity + * @{ + */ + +#define FSMC_WaitSignalPolarity_Low ((uint32_t)0x00000000) +#define FSMC_WaitSignalPolarity_High ((uint32_t)0x00000200) +#define IS_FSMC_WAIT_POLARITY(POLARITY) (((POLARITY) == FSMC_WaitSignalPolarity_Low) || \ + ((POLARITY) == FSMC_WaitSignalPolarity_High)) + +/** + * @} + */ + +/** @defgroup FSMC_Wrap_Mode + * @{ + */ + +#define FSMC_WrapMode_Disable ((uint32_t)0x00000000) +#define FSMC_WrapMode_Enable ((uint32_t)0x00000400) +#define IS_FSMC_WRAP_MODE(MODE) (((MODE) == FSMC_WrapMode_Disable) || \ + ((MODE) == FSMC_WrapMode_Enable)) + +/** + * @} + */ + +/** @defgroup FSMC_Wait_Timing + * @{ + */ + +#define FSMC_WaitSignalActive_BeforeWaitState ((uint32_t)0x00000000) +#define FSMC_WaitSignalActive_DuringWaitState ((uint32_t)0x00000800) +#define IS_FSMC_WAIT_SIGNAL_ACTIVE(ACTIVE) (((ACTIVE) == FSMC_WaitSignalActive_BeforeWaitState) || \ + ((ACTIVE) == FSMC_WaitSignalActive_DuringWaitState)) + +/** + * @} + */ + +/** @defgroup FSMC_Write_Operation + * @{ + */ + +#define FSMC_WriteOperation_Disable ((uint32_t)0x00000000) +#define FSMC_WriteOperation_Enable ((uint32_t)0x00001000) +#define IS_FSMC_WRITE_OPERATION(OPERATION) (((OPERATION) == FSMC_WriteOperation_Disable) || \ + ((OPERATION) == FSMC_WriteOperation_Enable)) + +/** + * @} + */ + +/** @defgroup FSMC_Wait_Signal + * @{ + */ + +#define FSMC_WaitSignal_Disable ((uint32_t)0x00000000) +#define FSMC_WaitSignal_Enable ((uint32_t)0x00002000) +#define IS_FSMC_WAITE_SIGNAL(SIGNAL) (((SIGNAL) == FSMC_WaitSignal_Disable) || \ + ((SIGNAL) == FSMC_WaitSignal_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_Extended_Mode + * @{ + */ + +#define FSMC_ExtendedMode_Disable ((uint32_t)0x00000000) +#define FSMC_ExtendedMode_Enable ((uint32_t)0x00004000) + +#define IS_FSMC_EXTENDED_MODE(MODE) (((MODE) == FSMC_ExtendedMode_Disable) || \ + ((MODE) == FSMC_ExtendedMode_Enable)) + +/** + * @} + */ + +/** @defgroup FSMC_Write_Burst + * @{ + */ + +#define FSMC_WriteBurst_Disable ((uint32_t)0x00000000) +#define FSMC_WriteBurst_Enable ((uint32_t)0x00080000) +#define IS_FSMC_WRITE_BURST(BURST) (((BURST) == FSMC_WriteBurst_Disable) || \ + ((BURST) == FSMC_WriteBurst_Enable)) +/** + * @} + */ + +/** @defgroup FSMC_Address_Setup_Time + * @{ + */ + +#define IS_FSMC_ADDRESS_SETUP_TIME(TIME) ((TIME) <= 0xF) + +/** + * @} + */ + +/** @defgroup FSMC_Address_Hold_Time + * @{ + */ + +#define IS_FSMC_ADDRESS_HOLD_TIME(TIME) ((TIME) <= 0xF) + +/** + * @} + */ + +/** @defgroup FSMC_Data_Setup_Time + * @{ + */ + +#define IS_FSMC_DATASETUP_TIME(TIME) (((TIME) > 0) && ((TIME) <= 0xFF)) + +/** + * @} + */ + +/** @defgroup FSMC_Bus_Turn_around_Duration + * @{ + */ + +#define IS_FSMC_TURNAROUND_TIME(TIME) ((TIME) <= 0xF) + +/** + * @} + */ + +/** @defgroup FSMC_CLK_Division + * @{ + */ + +#define IS_FSMC_CLK_DIV(DIV) ((DIV) <= 0xF) + +/** + * @} + */ + +/** @defgroup FSMC_Data_Latency + * @{ + */ + +#define IS_FSMC_DATA_LATENCY(LATENCY) ((LATENCY) <= 0xF) + +/** + * @} + */ + +/** @defgroup FSMC_Access_Mode + * @{ + */ + +#define FSMC_AccessMode_A ((uint32_t)0x00000000) +#define FSMC_AccessMode_B ((uint32_t)0x10000000) +#define FSMC_AccessMode_C ((uint32_t)0x20000000) +#define FSMC_AccessMode_D ((uint32_t)0x30000000) +#define IS_FSMC_ACCESS_MODE(MODE) (((MODE) == FSMC_AccessMode_A) || \ + ((MODE) == FSMC_AccessMode_B) || \ + ((MODE) == FSMC_AccessMode_C) || \ + ((MODE) == FSMC_AccessMode_D)) + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup NAND_PCCARD_Controller + * @{ + */ + +/** @defgroup FSMC_Wait_feature + * @{ + */ + +#define FSMC_Waitfeature_Disable ((uint32_t)0x00000000) +#define FSMC_Waitfeature_Enable ((uint32_t)0x00000002) +#define IS_FSMC_WAIT_FEATURE(FEATURE) (((FEATURE) == FSMC_Waitfeature_Disable) || \ + ((FEATURE) == FSMC_Waitfeature_Enable)) + +/** + * @} + */ + + +/** @defgroup FSMC_ECC + * @{ + */ + +#define FSMC_ECC_Disable ((uint32_t)0x00000000) +#define FSMC_ECC_Enable ((uint32_t)0x00000040) +#define IS_FSMC_ECC_STATE(STATE) (((STATE) == FSMC_ECC_Disable) || \ + ((STATE) == FSMC_ECC_Enable)) + +/** + * @} + */ + +/** @defgroup FSMC_ECC_Page_Size + * @{ + */ + +#define FSMC_ECCPageSize_256Bytes ((uint32_t)0x00000000) +#define FSMC_ECCPageSize_512Bytes ((uint32_t)0x00020000) +#define FSMC_ECCPageSize_1024Bytes ((uint32_t)0x00040000) +#define FSMC_ECCPageSize_2048Bytes ((uint32_t)0x00060000) +#define FSMC_ECCPageSize_4096Bytes ((uint32_t)0x00080000) +#define FSMC_ECCPageSize_8192Bytes ((uint32_t)0x000A0000) +#define IS_FSMC_ECCPAGE_SIZE(SIZE) (((SIZE) == FSMC_ECCPageSize_256Bytes) || \ + ((SIZE) == FSMC_ECCPageSize_512Bytes) || \ + ((SIZE) == FSMC_ECCPageSize_1024Bytes) || \ + ((SIZE) == FSMC_ECCPageSize_2048Bytes) || \ + ((SIZE) == FSMC_ECCPageSize_4096Bytes) || \ + ((SIZE) == FSMC_ECCPageSize_8192Bytes)) + +/** + * @} + */ + +/** @defgroup FSMC_TCLR_Setup_Time + * @{ + */ + +#define IS_FSMC_TCLR_TIME(TIME) ((TIME) <= 0xFF) + +/** + * @} + */ + +/** @defgroup FSMC_TAR_Setup_Time + * @{ + */ + +#define IS_FSMC_TAR_TIME(TIME) ((TIME) <= 0xFF) + +/** + * @} + */ + +/** @defgroup FSMC_Setup_Time + * @{ + */ + +#define IS_FSMC_SETUP_TIME(TIME) ((TIME) <= 0xFF) + +/** + * @} + */ + +/** @defgroup FSMC_Wait_Setup_Time + * @{ + */ + +#define IS_FSMC_WAIT_TIME(TIME) ((TIME) <= 0xFF) + +/** + * @} + */ + +/** @defgroup FSMC_Hold_Setup_Time + * @{ + */ + +#define IS_FSMC_HOLD_TIME(TIME) ((TIME) <= 0xFF) + +/** + * @} + */ + +/** @defgroup FSMC_HiZ_Setup_Time + * @{ + */ + +#define IS_FSMC_HIZ_TIME(TIME) ((TIME) <= 0xFF) + +/** + * @} + */ + +/** @defgroup FSMC_Interrupt_sources + * @{ + */ + +#define FSMC_IT_RisingEdge ((uint32_t)0x00000008) +#define FSMC_IT_Level ((uint32_t)0x00000010) +#define FSMC_IT_FallingEdge ((uint32_t)0x00000020) +#define IS_FSMC_IT(IT) ((((IT) & (uint32_t)0xFFFFFFC7) == 0x00000000) && ((IT) != 0x00000000)) +#define IS_FSMC_GET_IT(IT) (((IT) == FSMC_IT_RisingEdge) || \ + ((IT) == FSMC_IT_Level) || \ + ((IT) == FSMC_IT_FallingEdge)) +/** + * @} + */ + +/** @defgroup FSMC_Flags + * @{ + */ + +#define FSMC_FLAG_RisingEdge ((uint32_t)0x00000001) +#define FSMC_FLAG_Level ((uint32_t)0x00000002) +#define FSMC_FLAG_FallingEdge ((uint32_t)0x00000004) +#define FSMC_FLAG_FEMPT ((uint32_t)0x00000040) +#define IS_FSMC_GET_FLAG(FLAG) (((FLAG) == FSMC_FLAG_RisingEdge) || \ + ((FLAG) == FSMC_FLAG_Level) || \ + ((FLAG) == FSMC_FLAG_FallingEdge) || \ + ((FLAG) == FSMC_FLAG_FEMPT)) + +#define IS_FSMC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFF8) == 0x00000000) && ((FLAG) != 0x00000000)) + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FSMC_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup FSMC_Exported_Functions + * @{ + */ + +void FSMC_NORSRAMDeInit(uint32_t FSMC_Bank); +void FSMC_NANDDeInit(uint32_t FSMC_Bank); +void FSMC_PCCARDDeInit(void); +void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct); +void FSMC_NANDInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct); +void FSMC_PCCARDInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct); +void FSMC_NORSRAMStructInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct); +void FSMC_NANDStructInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct); +void FSMC_PCCARDStructInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct); +void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState); +void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState); +void FSMC_PCCARDCmd(FunctionalState NewState); +void FSMC_NANDECCCmd(uint32_t FSMC_Bank, FunctionalState NewState); +uint32_t FSMC_GetECC(uint32_t FSMC_Bank); +void FSMC_ITConfig(uint32_t FSMC_Bank, uint32_t FSMC_IT, FunctionalState NewState); +FlagStatus FSMC_GetFlagStatus(uint32_t FSMC_Bank, uint32_t FSMC_FLAG); +void FSMC_ClearFlag(uint32_t FSMC_Bank, uint32_t FSMC_FLAG); +ITStatus FSMC_GetITStatus(uint32_t FSMC_Bank, uint32_t FSMC_IT); +void FSMC_ClearITPendingBit(uint32_t FSMC_Bank, uint32_t FSMC_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F10x_FSMC_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_gpio.h b/example/libs_stm/inc/stm32f10x/stm32f10x_gpio.h new file mode 100644 index 000000000..aff7a5c1d --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_gpio.h @@ -0,0 +1,379 @@ +/** + ****************************************************************************** + * @file stm32f10x_gpio.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the GPIO + * firmware library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_GPIO_H +#define __STM32F10x_GPIO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup GPIO + * @{ + */ + +/** @defgroup GPIO_Exported_Types + * @{ + */ + +#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ + ((PERIPH) == GPIOB) || \ + ((PERIPH) == GPIOC) || \ + ((PERIPH) == GPIOD) || \ + ((PERIPH) == GPIOE) || \ + ((PERIPH) == GPIOF) || \ + ((PERIPH) == GPIOG)) + +/** + * @brief Output Maximum frequency selection + */ + +typedef enum +{ + GPIO_Speed_10MHz = 1, + GPIO_Speed_2MHz, + GPIO_Speed_50MHz +}GPIOSpeed_TypeDef; +#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_10MHz) || ((SPEED) == GPIO_Speed_2MHz) || \ + ((SPEED) == GPIO_Speed_50MHz)) + +/** + * @brief Configuration Mode enumeration + */ + +typedef enum +{ GPIO_Mode_AIN = 0x0, + GPIO_Mode_IN_FLOATING = 0x04, + GPIO_Mode_IPD = 0x28, + GPIO_Mode_IPU = 0x48, + GPIO_Mode_Out_OD = 0x14, + GPIO_Mode_Out_PP = 0x10, + GPIO_Mode_AF_OD = 0x1C, + GPIO_Mode_AF_PP = 0x18 +}GPIOMode_TypeDef; + +#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_AIN) || ((MODE) == GPIO_Mode_IN_FLOATING) || \ + ((MODE) == GPIO_Mode_IPD) || ((MODE) == GPIO_Mode_IPU) || \ + ((MODE) == GPIO_Mode_Out_OD) || ((MODE) == GPIO_Mode_Out_PP) || \ + ((MODE) == GPIO_Mode_AF_OD) || ((MODE) == GPIO_Mode_AF_PP)) + +/** + * @brief GPIO Init structure definition + */ + +typedef struct +{ + uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref GPIO_pins_define */ + + GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. + This parameter can be a value of @ref GPIOSpeed_TypeDef */ + + GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref GPIOMode_TypeDef */ +}GPIO_InitTypeDef; + + +/** + * @brief Bit_SET and Bit_RESET enumeration + */ + +typedef enum +{ Bit_RESET = 0, + Bit_SET +}BitAction; + +#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) + +/** + * @} + */ + +/** @defgroup GPIO_Exported_Constants + * @{ + */ + +/** @defgroup GPIO_pins_define + * @{ + */ + +#define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */ +#define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */ +#define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */ +#define GPIO_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */ +#define GPIO_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */ +#define GPIO_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */ +#define GPIO_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */ +#define GPIO_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */ +#define GPIO_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */ +#define GPIO_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */ +#define GPIO_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */ +#define GPIO_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */ +#define GPIO_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */ +#define GPIO_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */ +#define GPIO_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */ +#define GPIO_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */ +#define GPIO_Pin_All ((uint16_t)0xFFFF) /*!< All pins selected */ + +#define IS_GPIO_PIN(PIN) ((((PIN) & (uint16_t)0x00) == 0x00) && ((PIN) != (uint16_t)0x00)) + +#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \ + ((PIN) == GPIO_Pin_1) || \ + ((PIN) == GPIO_Pin_2) || \ + ((PIN) == GPIO_Pin_3) || \ + ((PIN) == GPIO_Pin_4) || \ + ((PIN) == GPIO_Pin_5) || \ + ((PIN) == GPIO_Pin_6) || \ + ((PIN) == GPIO_Pin_7) || \ + ((PIN) == GPIO_Pin_8) || \ + ((PIN) == GPIO_Pin_9) || \ + ((PIN) == GPIO_Pin_10) || \ + ((PIN) == GPIO_Pin_11) || \ + ((PIN) == GPIO_Pin_12) || \ + ((PIN) == GPIO_Pin_13) || \ + ((PIN) == GPIO_Pin_14) || \ + ((PIN) == GPIO_Pin_15)) + +/** + * @} + */ + +/** @defgroup GPIO_Remap_define + * @{ + */ + +#define GPIO_Remap_SPI1 ((uint32_t)0x00000001) /*!< SPI1 Alternate Function mapping */ +#define GPIO_Remap_I2C1 ((uint32_t)0x00000002) /*!< I2C1 Alternate Function mapping */ +#define GPIO_Remap_USART1 ((uint32_t)0x00000004) /*!< USART1 Alternate Function mapping */ +#define GPIO_Remap_USART2 ((uint32_t)0x00000008) /*!< USART2 Alternate Function mapping */ +#define GPIO_PartialRemap_USART3 ((uint32_t)0x00140010) /*!< USART3 Partial Alternate Function mapping */ +#define GPIO_FullRemap_USART3 ((uint32_t)0x00140030) /*!< USART3 Full Alternate Function mapping */ +#define GPIO_PartialRemap_TIM1 ((uint32_t)0x00160040) /*!< TIM1 Partial Alternate Function mapping */ +#define GPIO_FullRemap_TIM1 ((uint32_t)0x001600C0) /*!< TIM1 Full Alternate Function mapping */ +#define GPIO_PartialRemap1_TIM2 ((uint32_t)0x00180100) /*!< TIM2 Partial1 Alternate Function mapping */ +#define GPIO_PartialRemap2_TIM2 ((uint32_t)0x00180200) /*!< TIM2 Partial2 Alternate Function mapping */ +#define GPIO_FullRemap_TIM2 ((uint32_t)0x00180300) /*!< TIM2 Full Alternate Function mapping */ +#define GPIO_PartialRemap_TIM3 ((uint32_t)0x001A0800) /*!< TIM3 Partial Alternate Function mapping */ +#define GPIO_FullRemap_TIM3 ((uint32_t)0x001A0C00) /*!< TIM3 Full Alternate Function mapping */ +#define GPIO_Remap_TIM4 ((uint32_t)0x00001000) /*!< TIM4 Alternate Function mapping */ +#define GPIO_Remap1_CAN1 ((uint32_t)0x001D4000) /*!< CAN1 Alternate Function mapping */ +#define GPIO_Remap2_CAN1 ((uint32_t)0x001D6000) /*!< CAN1 Alternate Function mapping */ +#define GPIO_Remap_PD01 ((uint32_t)0x00008000) /*!< PD01 Alternate Function mapping */ +#define GPIO_Remap_TIM5CH4_LSI ((uint32_t)0x00200001) /*!< LSI connected to TIM5 Channel4 input capture for calibration */ +#define GPIO_Remap_ADC1_ETRGINJ ((uint32_t)0x00200002) /*!< ADC1 External Trigger Injected Conversion remapping */ +#define GPIO_Remap_ADC1_ETRGREG ((uint32_t)0x00200004) /*!< ADC1 External Trigger Regular Conversion remapping */ +#define GPIO_Remap_ADC2_ETRGINJ ((uint32_t)0x00200008) /*!< ADC2 External Trigger Injected Conversion remapping */ +#define GPIO_Remap_ADC2_ETRGREG ((uint32_t)0x00200010) /*!< ADC2 External Trigger Regular Conversion remapping */ +#define GPIO_Remap_ETH ((uint32_t)0x00200020) /*!< Ethernet remapping (only for Connectivity line devices) */ +#define GPIO_Remap_CAN2 ((uint32_t)0x00200040) /*!< CAN2 remapping (only for Connectivity line devices) */ +#define GPIO_Remap_SWJ_NoJTRST ((uint32_t)0x00300100) /*!< Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST */ +#define GPIO_Remap_SWJ_JTAGDisable ((uint32_t)0x00300200) /*!< JTAG-DP Disabled and SW-DP Enabled */ +#define GPIO_Remap_SWJ_Disable ((uint32_t)0x00300400) /*!< Full SWJ Disabled (JTAG-DP + SW-DP) */ +#define GPIO_Remap_SPI3 ((uint32_t)0x00201000) /*!< SPI3/I2S3 Alternate Function mapping (only for Connectivity line devices) */ +#define GPIO_Remap_TIM2ITR1_PTP_SOF ((uint32_t)0x00202000) /*!< Ethernet PTP output or USB OTG SOF (Start of Frame) connected + to TIM2 Internal Trigger 1 for calibration + (only for Connectivity line devices) */ +#define GPIO_Remap_PTP_PPS ((uint32_t)0x00204000) /*!< Ethernet MAC PPS_PTS output on PB05 (only for Connectivity line devices) */ + +#define GPIO_Remap_TIM15 ((uint32_t)0x80000001) /*!< TIM15 Alternate Function mapping (only for Value line devices) */ +#define GPIO_Remap_TIM16 ((uint32_t)0x80000002) /*!< TIM16 Alternate Function mapping (only for Value line devices) */ +#define GPIO_Remap_TIM17 ((uint32_t)0x80000004) /*!< TIM17 Alternate Function mapping (only for Value line devices) */ +#define GPIO_Remap_CEC ((uint32_t)0x80000008) /*!< CEC Alternate Function mapping (only for Value line devices) */ +#define GPIO_Remap_TIM1_DMA ((uint32_t)0x80000010) /*!< TIM1 DMA requests mapping (only for Value line devices) */ + +#define GPIO_Remap_TIM9 ((uint32_t)0x80000020) /*!< TIM9 Alternate Function mapping (only for XL-density devices) */ +#define GPIO_Remap_TIM10 ((uint32_t)0x80000040) /*!< TIM10 Alternate Function mapping (only for XL-density devices) */ +#define GPIO_Remap_TIM11 ((uint32_t)0x80000080) /*!< TIM11 Alternate Function mapping (only for XL-density devices) */ +#define GPIO_Remap_TIM13 ((uint32_t)0x80000100) /*!< TIM13 Alternate Function mapping (only for XL-density devices) */ +#define GPIO_Remap_TIM14 ((uint32_t)0x80000200) /*!< TIM14 Alternate Function mapping (only for XL-density devices) */ +#define GPIO_Remap_FSMC_NADV ((uint32_t)0x80000400) /*!< FSMC_NADV Alternate Function mapping (only for XL-density devices) */ + + +#define IS_GPIO_REMAP(REMAP) (((REMAP) == GPIO_Remap_SPI1) || ((REMAP) == GPIO_Remap_I2C1) || \ + ((REMAP) == GPIO_Remap_USART1) || ((REMAP) == GPIO_Remap_USART2) || \ + ((REMAP) == GPIO_PartialRemap_USART3) || ((REMAP) == GPIO_FullRemap_USART3) || \ + ((REMAP) == GPIO_PartialRemap_TIM1) || ((REMAP) == GPIO_FullRemap_TIM1) || \ + ((REMAP) == GPIO_PartialRemap1_TIM2) || ((REMAP) == GPIO_PartialRemap2_TIM2) || \ + ((REMAP) == GPIO_FullRemap_TIM2) || ((REMAP) == GPIO_PartialRemap_TIM3) || \ + ((REMAP) == GPIO_FullRemap_TIM3) || ((REMAP) == GPIO_Remap_TIM4) || \ + ((REMAP) == GPIO_Remap1_CAN1) || ((REMAP) == GPIO_Remap2_CAN1) || \ + ((REMAP) == GPIO_Remap_PD01) || ((REMAP) == GPIO_Remap_TIM5CH4_LSI) || \ + ((REMAP) == GPIO_Remap_ADC1_ETRGINJ) ||((REMAP) == GPIO_Remap_ADC1_ETRGREG) || \ + ((REMAP) == GPIO_Remap_ADC2_ETRGINJ) ||((REMAP) == GPIO_Remap_ADC2_ETRGREG) || \ + ((REMAP) == GPIO_Remap_ETH) ||((REMAP) == GPIO_Remap_CAN2) || \ + ((REMAP) == GPIO_Remap_SWJ_NoJTRST) || ((REMAP) == GPIO_Remap_SWJ_JTAGDisable) || \ + ((REMAP) == GPIO_Remap_SWJ_Disable)|| ((REMAP) == GPIO_Remap_SPI3) || \ + ((REMAP) == GPIO_Remap_TIM2ITR1_PTP_SOF) || ((REMAP) == GPIO_Remap_PTP_PPS) || \ + ((REMAP) == GPIO_Remap_TIM15) || ((REMAP) == GPIO_Remap_TIM16) || \ + ((REMAP) == GPIO_Remap_TIM17) || ((REMAP) == GPIO_Remap_CEC) || \ + ((REMAP) == GPIO_Remap_TIM1_DMA) || ((REMAP) == GPIO_Remap_TIM9) || \ + ((REMAP) == GPIO_Remap_TIM10) || ((REMAP) == GPIO_Remap_TIM11) || \ + ((REMAP) == GPIO_Remap_TIM13) || ((REMAP) == GPIO_Remap_TIM14) || \ + ((REMAP) == GPIO_Remap_FSMC_NADV)) + +/** + * @} + */ + +/** @defgroup GPIO_Port_Sources + * @{ + */ + +#define GPIO_PortSourceGPIOA ((uint8_t)0x00) +#define GPIO_PortSourceGPIOB ((uint8_t)0x01) +#define GPIO_PortSourceGPIOC ((uint8_t)0x02) +#define GPIO_PortSourceGPIOD ((uint8_t)0x03) +#define GPIO_PortSourceGPIOE ((uint8_t)0x04) +#define GPIO_PortSourceGPIOF ((uint8_t)0x05) +#define GPIO_PortSourceGPIOG ((uint8_t)0x06) +#define IS_GPIO_EVENTOUT_PORT_SOURCE(PORTSOURCE) (((PORTSOURCE) == GPIO_PortSourceGPIOA) || \ + ((PORTSOURCE) == GPIO_PortSourceGPIOB) || \ + ((PORTSOURCE) == GPIO_PortSourceGPIOC) || \ + ((PORTSOURCE) == GPIO_PortSourceGPIOD) || \ + ((PORTSOURCE) == GPIO_PortSourceGPIOE)) + +#define IS_GPIO_EXTI_PORT_SOURCE(PORTSOURCE) (((PORTSOURCE) == GPIO_PortSourceGPIOA) || \ + ((PORTSOURCE) == GPIO_PortSourceGPIOB) || \ + ((PORTSOURCE) == GPIO_PortSourceGPIOC) || \ + ((PORTSOURCE) == GPIO_PortSourceGPIOD) || \ + ((PORTSOURCE) == GPIO_PortSourceGPIOE) || \ + ((PORTSOURCE) == GPIO_PortSourceGPIOF) || \ + ((PORTSOURCE) == GPIO_PortSourceGPIOG)) + +/** + * @} + */ + +/** @defgroup GPIO_Pin_sources + * @{ + */ + +#define GPIO_PinSource0 ((uint8_t)0x00) +#define GPIO_PinSource1 ((uint8_t)0x01) +#define GPIO_PinSource2 ((uint8_t)0x02) +#define GPIO_PinSource3 ((uint8_t)0x03) +#define GPIO_PinSource4 ((uint8_t)0x04) +#define GPIO_PinSource5 ((uint8_t)0x05) +#define GPIO_PinSource6 ((uint8_t)0x06) +#define GPIO_PinSource7 ((uint8_t)0x07) +#define GPIO_PinSource8 ((uint8_t)0x08) +#define GPIO_PinSource9 ((uint8_t)0x09) +#define GPIO_PinSource10 ((uint8_t)0x0A) +#define GPIO_PinSource11 ((uint8_t)0x0B) +#define GPIO_PinSource12 ((uint8_t)0x0C) +#define GPIO_PinSource13 ((uint8_t)0x0D) +#define GPIO_PinSource14 ((uint8_t)0x0E) +#define GPIO_PinSource15 ((uint8_t)0x0F) + +#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \ + ((PINSOURCE) == GPIO_PinSource1) || \ + ((PINSOURCE) == GPIO_PinSource2) || \ + ((PINSOURCE) == GPIO_PinSource3) || \ + ((PINSOURCE) == GPIO_PinSource4) || \ + ((PINSOURCE) == GPIO_PinSource5) || \ + ((PINSOURCE) == GPIO_PinSource6) || \ + ((PINSOURCE) == GPIO_PinSource7) || \ + ((PINSOURCE) == GPIO_PinSource8) || \ + ((PINSOURCE) == GPIO_PinSource9) || \ + ((PINSOURCE) == GPIO_PinSource10) || \ + ((PINSOURCE) == GPIO_PinSource11) || \ + ((PINSOURCE) == GPIO_PinSource12) || \ + ((PINSOURCE) == GPIO_PinSource13) || \ + ((PINSOURCE) == GPIO_PinSource14) || \ + ((PINSOURCE) == GPIO_PinSource15)) + +/** + * @} + */ + +/** @defgroup Ethernet_Media_Interface + * @{ + */ +#define GPIO_ETH_MediaInterface_MII ((u32)0x00000000) +#define GPIO_ETH_MediaInterface_RMII ((u32)0x00000001) + +#define IS_GPIO_ETH_MEDIA_INTERFACE(INTERFACE) (((INTERFACE) == GPIO_ETH_MediaInterface_MII) || \ + ((INTERFACE) == GPIO_ETH_MediaInterface_RMII)) + +/** + * @} + */ +/** + * @} + */ + +/** @defgroup GPIO_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup GPIO_Exported_Functions + * @{ + */ + +void GPIO_DeInit(GPIO_TypeDef* GPIOx); +void GPIO_AFIODeInit(void); +void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); +void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); +uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); +uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); +void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); +void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); +void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource); +void GPIO_EventOutputCmd(FunctionalState NewState); +void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState); +void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource); +void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_GPIO_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_i2c.h b/example/libs_stm/inc/stm32f10x/stm32f10x_i2c.h new file mode 100644 index 000000000..d9c9346bc --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_i2c.h @@ -0,0 +1,670 @@ +/** + ****************************************************************************** + * @file stm32f10x_i2c.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the I2C firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_I2C_H +#define __STM32F10x_I2C_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup I2C + * @{ + */ + +/** @defgroup I2C_Exported_Types + * @{ + */ + +/** + * @brief I2C Init structure definition + */ + +typedef struct +{ + uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency. + This parameter must be set to a value lower than 400kHz */ + + uint16_t I2C_Mode; /*!< Specifies the I2C mode. + This parameter can be a value of @ref I2C_mode */ + + uint16_t I2C_DutyCycle; /*!< Specifies the I2C fast mode duty cycle. + This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */ + + uint16_t I2C_OwnAddress1; /*!< Specifies the first device own address. + This parameter can be a 7-bit or 10-bit address. */ + + uint16_t I2C_Ack; /*!< Enables or disables the acknowledgement. + This parameter can be a value of @ref I2C_acknowledgement */ + + uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged. + This parameter can be a value of @ref I2C_acknowledged_address */ +}I2C_InitTypeDef; + +/** + * @} + */ + + +/** @defgroup I2C_Exported_Constants + * @{ + */ + +#define IS_I2C_ALL_PERIPH(PERIPH) (((PERIPH) == I2C1) || \ + ((PERIPH) == I2C2)) +/** @defgroup I2C_mode + * @{ + */ + +#define I2C_Mode_I2C ((uint16_t)0x0000) +#define I2C_Mode_SMBusDevice ((uint16_t)0x0002) +#define I2C_Mode_SMBusHost ((uint16_t)0x000A) +#define IS_I2C_MODE(MODE) (((MODE) == I2C_Mode_I2C) || \ + ((MODE) == I2C_Mode_SMBusDevice) || \ + ((MODE) == I2C_Mode_SMBusHost)) +/** + * @} + */ + +/** @defgroup I2C_duty_cycle_in_fast_mode + * @{ + */ + +#define I2C_DutyCycle_16_9 ((uint16_t)0x4000) /*!< I2C fast mode Tlow/Thigh = 16/9 */ +#define I2C_DutyCycle_2 ((uint16_t)0xBFFF) /*!< I2C fast mode Tlow/Thigh = 2 */ +#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DutyCycle_16_9) || \ + ((CYCLE) == I2C_DutyCycle_2)) +/** + * @} + */ + +/** @defgroup I2C_acknowledgement + * @{ + */ + +#define I2C_Ack_Enable ((uint16_t)0x0400) +#define I2C_Ack_Disable ((uint16_t)0x0000) +#define IS_I2C_ACK_STATE(STATE) (((STATE) == I2C_Ack_Enable) || \ + ((STATE) == I2C_Ack_Disable)) +/** + * @} + */ + +/** @defgroup I2C_transfer_direction + * @{ + */ + +#define I2C_Direction_Transmitter ((uint8_t)0x00) +#define I2C_Direction_Receiver ((uint8_t)0x01) +#define IS_I2C_DIRECTION(DIRECTION) (((DIRECTION) == I2C_Direction_Transmitter) || \ + ((DIRECTION) == I2C_Direction_Receiver)) +/** + * @} + */ + +/** @defgroup I2C_acknowledged_address + * @{ + */ + +#define I2C_AcknowledgedAddress_7bit ((uint16_t)0x4000) +#define I2C_AcknowledgedAddress_10bit ((uint16_t)0xC000) +#define IS_I2C_ACKNOWLEDGE_ADDRESS(ADDRESS) (((ADDRESS) == I2C_AcknowledgedAddress_7bit) || \ + ((ADDRESS) == I2C_AcknowledgedAddress_10bit)) +/** + * @} + */ + +/** @defgroup I2C_registers + * @{ + */ + +#define I2C_Register_CR1 ((uint8_t)0x00) +#define I2C_Register_CR2 ((uint8_t)0x04) +#define I2C_Register_OAR1 ((uint8_t)0x08) +#define I2C_Register_OAR2 ((uint8_t)0x0C) +#define I2C_Register_DR ((uint8_t)0x10) +#define I2C_Register_SR1 ((uint8_t)0x14) +#define I2C_Register_SR2 ((uint8_t)0x18) +#define I2C_Register_CCR ((uint8_t)0x1C) +#define I2C_Register_TRISE ((uint8_t)0x20) +#define IS_I2C_REGISTER(REGISTER) (((REGISTER) == I2C_Register_CR1) || \ + ((REGISTER) == I2C_Register_CR2) || \ + ((REGISTER) == I2C_Register_OAR1) || \ + ((REGISTER) == I2C_Register_OAR2) || \ + ((REGISTER) == I2C_Register_DR) || \ + ((REGISTER) == I2C_Register_SR1) || \ + ((REGISTER) == I2C_Register_SR2) || \ + ((REGISTER) == I2C_Register_CCR) || \ + ((REGISTER) == I2C_Register_TRISE)) +/** + * @} + */ + +/** @defgroup I2C_SMBus_alert_pin_level + * @{ + */ + +#define I2C_SMBusAlert_Low ((uint16_t)0x2000) +#define I2C_SMBusAlert_High ((uint16_t)0xDFFF) +#define IS_I2C_SMBUS_ALERT(ALERT) (((ALERT) == I2C_SMBusAlert_Low) || \ + ((ALERT) == I2C_SMBusAlert_High)) +/** + * @} + */ + +/** @defgroup I2C_PEC_position + * @{ + */ + +#define I2C_PECPosition_Next ((uint16_t)0x0800) +#define I2C_PECPosition_Current ((uint16_t)0xF7FF) +#define IS_I2C_PEC_POSITION(POSITION) (((POSITION) == I2C_PECPosition_Next) || \ + ((POSITION) == I2C_PECPosition_Current)) +/** + * @} + */ + +/** @defgroup I2C_interrupts_definition + * @{ + */ + +#define I2C_IT_BUF ((uint16_t)0x0400) +#define I2C_IT_EVT ((uint16_t)0x0200) +#define I2C_IT_ERR ((uint16_t)0x0100) +#define IS_I2C_CONFIG_IT(IT) ((((IT) & (uint16_t)0xF8FF) == 0x00) && ((IT) != 0x00)) +/** + * @} + */ + +/** @defgroup I2C_interrupts_definition + * @{ + */ + +#define I2C_IT_SMBALERT ((uint32_t)0x01008000) +#define I2C_IT_TIMEOUT ((uint32_t)0x01004000) +#define I2C_IT_PECERR ((uint32_t)0x01001000) +#define I2C_IT_OVR ((uint32_t)0x01000800) +#define I2C_IT_AF ((uint32_t)0x01000400) +#define I2C_IT_ARLO ((uint32_t)0x01000200) +#define I2C_IT_BERR ((uint32_t)0x01000100) +#define I2C_IT_TXE ((uint32_t)0x06000080) +#define I2C_IT_RXNE ((uint32_t)0x06000040) +#define I2C_IT_STOPF ((uint32_t)0x02000010) +#define I2C_IT_ADD10 ((uint32_t)0x02000008) +#define I2C_IT_BTF ((uint32_t)0x02000004) +#define I2C_IT_ADDR ((uint32_t)0x02000002) +#define I2C_IT_SB ((uint32_t)0x02000001) + +#define IS_I2C_CLEAR_IT(IT) ((((IT) & (uint16_t)0x20FF) == 0x00) && ((IT) != (uint16_t)0x00)) + +#define IS_I2C_GET_IT(IT) (((IT) == I2C_IT_SMBALERT) || ((IT) == I2C_IT_TIMEOUT) || \ + ((IT) == I2C_IT_PECERR) || ((IT) == I2C_IT_OVR) || \ + ((IT) == I2C_IT_AF) || ((IT) == I2C_IT_ARLO) || \ + ((IT) == I2C_IT_BERR) || ((IT) == I2C_IT_TXE) || \ + ((IT) == I2C_IT_RXNE) || ((IT) == I2C_IT_STOPF) || \ + ((IT) == I2C_IT_ADD10) || ((IT) == I2C_IT_BTF) || \ + ((IT) == I2C_IT_ADDR) || ((IT) == I2C_IT_SB)) +/** + * @} + */ + +/** @defgroup I2C_flags_definition + * @{ + */ + +/** + * @brief SR2 register flags + */ + +#define I2C_FLAG_DUALF ((uint32_t)0x00800000) +#define I2C_FLAG_SMBHOST ((uint32_t)0x00400000) +#define I2C_FLAG_SMBDEFAULT ((uint32_t)0x00200000) +#define I2C_FLAG_GENCALL ((uint32_t)0x00100000) +#define I2C_FLAG_TRA ((uint32_t)0x00040000) +#define I2C_FLAG_BUSY ((uint32_t)0x00020000) +#define I2C_FLAG_MSL ((uint32_t)0x00010000) + +/** + * @brief SR1 register flags + */ + +#define I2C_FLAG_SMBALERT ((uint32_t)0x10008000) +#define I2C_FLAG_TIMEOUT ((uint32_t)0x10004000) +#define I2C_FLAG_PECERR ((uint32_t)0x10001000) +#define I2C_FLAG_OVR ((uint32_t)0x10000800) +#define I2C_FLAG_AF ((uint32_t)0x10000400) +#define I2C_FLAG_ARLO ((uint32_t)0x10000200) +#define I2C_FLAG_BERR ((uint32_t)0x10000100) +#define I2C_FLAG_TXE ((uint32_t)0x10000080) +#define I2C_FLAG_RXNE ((uint32_t)0x10000040) +#define I2C_FLAG_STOPF ((uint32_t)0x10000010) +#define I2C_FLAG_ADD10 ((uint32_t)0x10000008) +#define I2C_FLAG_BTF ((uint32_t)0x10000004) +#define I2C_FLAG_ADDR ((uint32_t)0x10000002) +#define I2C_FLAG_SB ((uint32_t)0x10000001) + +#define IS_I2C_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0x20FF) == 0x00) && ((FLAG) != (uint16_t)0x00)) + +#define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_DUALF) || ((FLAG) == I2C_FLAG_SMBHOST) || \ + ((FLAG) == I2C_FLAG_SMBDEFAULT) || ((FLAG) == I2C_FLAG_GENCALL) || \ + ((FLAG) == I2C_FLAG_TRA) || ((FLAG) == I2C_FLAG_BUSY) || \ + ((FLAG) == I2C_FLAG_MSL) || ((FLAG) == I2C_FLAG_SMBALERT) || \ + ((FLAG) == I2C_FLAG_TIMEOUT) || ((FLAG) == I2C_FLAG_PECERR) || \ + ((FLAG) == I2C_FLAG_OVR) || ((FLAG) == I2C_FLAG_AF) || \ + ((FLAG) == I2C_FLAG_ARLO) || ((FLAG) == I2C_FLAG_BERR) || \ + ((FLAG) == I2C_FLAG_TXE) || ((FLAG) == I2C_FLAG_RXNE) || \ + ((FLAG) == I2C_FLAG_STOPF) || ((FLAG) == I2C_FLAG_ADD10) || \ + ((FLAG) == I2C_FLAG_BTF) || ((FLAG) == I2C_FLAG_ADDR) || \ + ((FLAG) == I2C_FLAG_SB)) +/** + * @} + */ + +/** @defgroup I2C_Events + * @{ + */ + +/*======================================== + + I2C Master Events (Events grouped in order of communication) + ==========================================*/ +/** + * @brief Communication start + * + * After sending the START condition (I2C_GenerateSTART() function) the master + * has to wait for this event. It means that the Start condition has been correctly + * released on the I2C bus (the bus is free, no other devices is communicating). + * + */ +/* --EV5 */ +#define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */ + +/** + * @brief Address Acknowledge + * + * After checking on EV5 (start condition correctly released on the bus), the + * master sends the address of the slave(s) with which it will communicate + * (I2C_Send7bitAddress() function, it also determines the direction of the communication: + * Master transmitter or Receiver). Then the master has to wait that a slave acknowledges + * his address. If an acknowledge is sent on the bus, one of the following events will + * be set: + * + * 1) In case of Master Receiver (7-bit addressing): the I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED + * event is set. + * + * 2) In case of Master Transmitter (7-bit addressing): the I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED + * is set + * + * 3) In case of 10-Bit addressing mode, the master (just after generating the START + * and checking on EV5) has to send the header of 10-bit addressing mode (I2C_SendData() + * function). Then master should wait on EV9. It means that the 10-bit addressing + * header has been correctly sent on the bus. Then master should send the second part of + * the 10-bit address (LSB) using the function I2C_Send7bitAddress(). Then master + * should wait for event EV6. + * + */ + +/* --EV6 */ +#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */ +#define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL and ADDR flags */ +/* --EV9 */ +#define I2C_EVENT_MASTER_MODE_ADDRESS10 ((uint32_t)0x00030008) /* BUSY, MSL and ADD10 flags */ + +/** + * @brief Communication events + * + * If a communication is established (START condition generated and slave address + * acknowledged) then the master has to check on one of the following events for + * communication procedures: + * + * 1) Master Receiver mode: The master has to wait on the event EV7 then to read + * the data received from the slave (I2C_ReceiveData() function). + * + * 2) Master Transmitter mode: The master has to send data (I2C_SendData() + * function) then to wait on event EV8 or EV8_2. + * These two events are similar: + * - EV8 means that the data has been written in the data register and is + * being shifted out. + * - EV8_2 means that the data has been physically shifted out and output + * on the bus. + * In most cases, using EV8 is sufficient for the application. + * Using EV8_2 leads to a slower communication but ensure more reliable test. + * EV8_2 is also more suitable than EV8 for testing on the last data transmission + * (before Stop condition generation). + * + * @note In case the user software does not guarantee that this event EV7 is + * managed before the current byte end of transfer, then user may check on EV7 + * and BTF flag at the same time (ie. (I2C_EVENT_MASTER_BYTE_RECEIVED | I2C_FLAG_BTF)). + * In this case the communication may be slower. + * + */ + +/* Master RECEIVER mode -----------------------------*/ +/* --EV7 */ +#define I2C_EVENT_MASTER_BYTE_RECEIVED ((uint32_t)0x00030040) /* BUSY, MSL and RXNE flags */ + +/* Master TRANSMITTER mode --------------------------*/ +/* --EV8 */ +#define I2C_EVENT_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */ +/* --EV8_2 */ +#define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags */ + + +/*======================================== + + I2C Slave Events (Events grouped in order of communication) + ==========================================*/ + +/** + * @brief Communication start events + * + * Wait on one of these events at the start of the communication. It means that + * the I2C peripheral detected a Start condition on the bus (generated by master + * device) followed by the peripheral address. The peripheral generates an ACK + * condition on the bus (if the acknowledge feature is enabled through function + * I2C_AcknowledgeConfig()) and the events listed above are set : + * + * 1) In normal case (only one address managed by the slave), when the address + * sent by the master matches the own address of the peripheral (configured by + * I2C_OwnAddress1 field) the I2C_EVENT_SLAVE_XXX_ADDRESS_MATCHED event is set + * (where XXX could be TRANSMITTER or RECEIVER). + * + * 2) In case the address sent by the master matches the second address of the + * peripheral (configured by the function I2C_OwnAddress2Config() and enabled + * by the function I2C_DualAddressCmd()) the events I2C_EVENT_SLAVE_XXX_SECONDADDRESS_MATCHED + * (where XXX could be TRANSMITTER or RECEIVER) are set. + * + * 3) In case the address sent by the master is General Call (address 0x00) and + * if the General Call is enabled for the peripheral (using function I2C_GeneralCallCmd()) + * the following event is set I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED. + * + */ + +/* --EV1 (all the events below are variants of EV1) */ +/* 1) Case of One Single Address managed by the slave */ +#define I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ((uint32_t)0x00020002) /* BUSY and ADDR flags */ +#define I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED ((uint32_t)0x00060082) /* TRA, BUSY, TXE and ADDR flags */ + +/* 2) Case of Dual address managed by the slave */ +#define I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED ((uint32_t)0x00820000) /* DUALF and BUSY flags */ +#define I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED ((uint32_t)0x00860080) /* DUALF, TRA, BUSY and TXE flags */ + +/* 3) Case of General Call enabled for the slave */ +#define I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED ((uint32_t)0x00120000) /* GENCALL and BUSY flags */ + +/** + * @brief Communication events + * + * Wait on one of these events when EV1 has already been checked and: + * + * - Slave RECEIVER mode: + * - EV2: When the application is expecting a data byte to be received. + * - EV4: When the application is expecting the end of the communication: master + * sends a stop condition and data transmission is stopped. + * + * - Slave Transmitter mode: + * - EV3: When a byte has been transmitted by the slave and the application is expecting + * the end of the byte transmission. The two events I2C_EVENT_SLAVE_BYTE_TRANSMITTED and + * I2C_EVENT_SLAVE_BYTE_TRANSMITTING are similar. The second one can optionally be + * used when the user software doesn't guarantee the EV3 is managed before the + * current byte end of tranfer. + * - EV3_2: When the master sends a NACK in order to tell slave that data transmission + * shall end (before sending the STOP condition). In this case slave has to stop sending + * data bytes and expect a Stop condition on the bus. + * + * @note In case the user software does not guarantee that the event EV2 is + * managed before the current byte end of transfer, then user may check on EV2 + * and BTF flag at the same time (ie. (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_BTF)). + * In this case the communication may be slower. + * + */ + +/* Slave RECEIVER mode --------------------------*/ +/* --EV2 */ +#define I2C_EVENT_SLAVE_BYTE_RECEIVED ((uint32_t)0x00020040) /* BUSY and RXNE flags */ +/* --EV4 */ +#define I2C_EVENT_SLAVE_STOP_DETECTED ((uint32_t)0x00000010) /* STOPF flag */ + +/* Slave TRANSMITTER mode -----------------------*/ +/* --EV3 */ +#define I2C_EVENT_SLAVE_BYTE_TRANSMITTED ((uint32_t)0x00060084) /* TRA, BUSY, TXE and BTF flags */ +#define I2C_EVENT_SLAVE_BYTE_TRANSMITTING ((uint32_t)0x00060080) /* TRA, BUSY and TXE flags */ +/* --EV3_2 */ +#define I2C_EVENT_SLAVE_ACK_FAILURE ((uint32_t)0x00000400) /* AF flag */ + +/*=========================== End of Events Description ==========================================*/ + +#define IS_I2C_EVENT(EVENT) (((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED) || \ + ((EVENT) == I2C_EVENT_SLAVE_BYTE_RECEIVED) || \ + ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF)) || \ + ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL)) || \ + ((EVENT) == I2C_EVENT_SLAVE_BYTE_TRANSMITTED) || \ + ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF)) || \ + ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL)) || \ + ((EVENT) == I2C_EVENT_SLAVE_STOP_DETECTED) || \ + ((EVENT) == I2C_EVENT_MASTER_MODE_SELECT) || \ + ((EVENT) == I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) || \ + ((EVENT) == I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) || \ + ((EVENT) == I2C_EVENT_MASTER_BYTE_RECEIVED) || \ + ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTED) || \ + ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTING) || \ + ((EVENT) == I2C_EVENT_MASTER_MODE_ADDRESS10) || \ + ((EVENT) == I2C_EVENT_SLAVE_ACK_FAILURE)) +/** + * @} + */ + +/** @defgroup I2C_own_address1 + * @{ + */ + +#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x3FF) +/** + * @} + */ + +/** @defgroup I2C_clock_speed + * @{ + */ + +#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) >= 0x1) && ((SPEED) <= 400000)) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup I2C_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup I2C_Exported_Functions + * @{ + */ + +void I2C_DeInit(I2C_TypeDef* I2Cx); +void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct); +void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct); +void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address); +void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState); +void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data); +uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx); +void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction); +uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register); +void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert); +void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition); +void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState); +uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx); +void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); +void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle); + +/** + * @brief + **************************************************************************************** + * + * I2C State Monitoring Functions + * + **************************************************************************************** + * This I2C driver provides three different ways for I2C state monitoring + * depending on the application requirements and constraints: + * + * + * 1) Basic state monitoring: + * Using I2C_CheckEvent() function: + * It compares the status registers (SR1 and SR2) content to a given event + * (can be the combination of one or more flags). + * It returns SUCCESS if the current status includes the given flags + * and returns ERROR if one or more flags are missing in the current status. + * - When to use: + * - This function is suitable for most applications as well as for startup + * activity since the events are fully described in the product reference manual + * (RM0008). + * - It is also suitable for users who need to define their own events. + * - Limitations: + * - If an error occurs (ie. error flags are set besides to the monitored flags), + * the I2C_CheckEvent() function may return SUCCESS despite the communication + * hold or corrupted real state. + * In this case, it is advised to use error interrupts to monitor the error + * events and handle them in the interrupt IRQ handler. + * + * @note + * For error management, it is advised to use the following functions: + * - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR). + * - I2Cx_ER_IRQHandler() which is called when the error interurpt occurs. + * Where x is the peripheral instance (I2C1, I2C2 ...) + * - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into I2Cx_ER_IRQHandler() + * in order to determine which error occured. + * - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd() + * and/or I2C_GenerateStop() in order to clear the error flag and source, + * and return to correct communication status. + * + * + * 2) Advanced state monitoring: + * Using the function I2C_GetLastEvent() which returns the image of both status + * registers in a single word (uint32_t) (Status Register 2 value is shifted left + * by 16 bits and concatenated to Status Register 1). + * - When to use: + * - This function is suitable for the same applications above but it allows to + * overcome the limitations of I2C_GetFlagStatus() function (see below). + * The returned value could be compared to events already defined in the + * library (stm32f10x_i2c.h) or to custom values defined by user. + * - This function is suitable when multiple flags are monitored at the same time. + * - At the opposite of I2C_CheckEvent() function, this function allows user to + * choose when an event is accepted (when all events flags are set and no + * other flags are set or just when the needed flags are set like + * I2C_CheckEvent() function). + * - Limitations: + * - User may need to define his own events. + * - Same remark concerning the error management is applicable for this + * function if user decides to check only regular communication flags (and + * ignores error flags). + * + * + * 3) Flag-based state monitoring: + * Using the function I2C_GetFlagStatus() which simply returns the status of + * one single flag (ie. I2C_FLAG_RXNE ...). + * - When to use: + * - This function could be used for specific applications or in debug phase. + * - It is suitable when only one flag checking is needed (most I2C events + * are monitored through multiple flags). + * - Limitations: + * - When calling this function, the Status register is accessed. Some flags are + * cleared when the status register is accessed. So checking the status + * of one Flag, may clear other ones. + * - Function may need to be called twice or more in order to monitor one + * single event. + * + */ + +/** + * + * 1) Basic state monitoring + ******************************************************************************* + */ +ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT); +/** + * + * 2) Advanced state monitoring + ******************************************************************************* + */ +uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx); +/** + * + * 3) Flag-based state monitoring + ******************************************************************************* + */ +FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); +/** + * + ******************************************************************************* + */ + +void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); +ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT); +void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F10x_I2C_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_iwdg.h b/example/libs_stm/inc/stm32f10x/stm32f10x_iwdg.h new file mode 100644 index 000000000..f9a26bf18 --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_iwdg.h @@ -0,0 +1,139 @@ +/** + ****************************************************************************** + * @file stm32f10x_iwdg.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the IWDG + * firmware library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_IWDG_H +#define __STM32F10x_IWDG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup IWDG + * @{ + */ + +/** @defgroup IWDG_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup IWDG_Exported_Constants + * @{ + */ + +/** @defgroup IWDG_WriteAccess + * @{ + */ + +#define IWDG_WriteAccess_Enable ((uint16_t)0x5555) +#define IWDG_WriteAccess_Disable ((uint16_t)0x0000) +#define IS_IWDG_WRITE_ACCESS(ACCESS) (((ACCESS) == IWDG_WriteAccess_Enable) || \ + ((ACCESS) == IWDG_WriteAccess_Disable)) +/** + * @} + */ + +/** @defgroup IWDG_prescaler + * @{ + */ + +#define IWDG_Prescaler_4 ((uint8_t)0x00) +#define IWDG_Prescaler_8 ((uint8_t)0x01) +#define IWDG_Prescaler_16 ((uint8_t)0x02) +#define IWDG_Prescaler_32 ((uint8_t)0x03) +#define IWDG_Prescaler_64 ((uint8_t)0x04) +#define IWDG_Prescaler_128 ((uint8_t)0x05) +#define IWDG_Prescaler_256 ((uint8_t)0x06) +#define IS_IWDG_PRESCALER(PRESCALER) (((PRESCALER) == IWDG_Prescaler_4) || \ + ((PRESCALER) == IWDG_Prescaler_8) || \ + ((PRESCALER) == IWDG_Prescaler_16) || \ + ((PRESCALER) == IWDG_Prescaler_32) || \ + ((PRESCALER) == IWDG_Prescaler_64) || \ + ((PRESCALER) == IWDG_Prescaler_128)|| \ + ((PRESCALER) == IWDG_Prescaler_256)) +/** + * @} + */ + +/** @defgroup IWDG_Flag + * @{ + */ + +#define IWDG_FLAG_PVU ((uint16_t)0x0001) +#define IWDG_FLAG_RVU ((uint16_t)0x0002) +#define IS_IWDG_FLAG(FLAG) (((FLAG) == IWDG_FLAG_PVU) || ((FLAG) == IWDG_FLAG_RVU)) +#define IS_IWDG_RELOAD(RELOAD) ((RELOAD) <= 0xFFF) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup IWDG_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup IWDG_Exported_Functions + * @{ + */ + +void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess); +void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); +void IWDG_SetReload(uint16_t Reload); +void IWDG_ReloadCounter(void); +void IWDG_Enable(void); +FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_IWDG_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_pwr.h b/example/libs_stm/inc/stm32f10x/stm32f10x_pwr.h new file mode 100644 index 000000000..ce168da23 --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_pwr.h @@ -0,0 +1,155 @@ +/** + ****************************************************************************** + * @file stm32f10x_pwr.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the PWR firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_PWR_H +#define __STM32F10x_PWR_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup PWR + * @{ + */ + +/** @defgroup PWR_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup PWR_Exported_Constants + * @{ + */ + +/** @defgroup PVD_detection_level + * @{ + */ + +#define PWR_PVDLevel_2V2 ((uint32_t)0x00000000) +#define PWR_PVDLevel_2V3 ((uint32_t)0x00000020) +#define PWR_PVDLevel_2V4 ((uint32_t)0x00000040) +#define PWR_PVDLevel_2V5 ((uint32_t)0x00000060) +#define PWR_PVDLevel_2V6 ((uint32_t)0x00000080) +#define PWR_PVDLevel_2V7 ((uint32_t)0x000000A0) +#define PWR_PVDLevel_2V8 ((uint32_t)0x000000C0) +#define PWR_PVDLevel_2V9 ((uint32_t)0x000000E0) +#define IS_PWR_PVD_LEVEL(LEVEL) (((LEVEL) == PWR_PVDLevel_2V2) || ((LEVEL) == PWR_PVDLevel_2V3)|| \ + ((LEVEL) == PWR_PVDLevel_2V4) || ((LEVEL) == PWR_PVDLevel_2V5)|| \ + ((LEVEL) == PWR_PVDLevel_2V6) || ((LEVEL) == PWR_PVDLevel_2V7)|| \ + ((LEVEL) == PWR_PVDLevel_2V8) || ((LEVEL) == PWR_PVDLevel_2V9)) +/** + * @} + */ + +/** @defgroup Regulator_state_is_STOP_mode + * @{ + */ + +#define PWR_Regulator_ON ((uint32_t)0x00000000) +#define PWR_Regulator_LowPower ((uint32_t)0x00000001) +#define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_Regulator_ON) || \ + ((REGULATOR) == PWR_Regulator_LowPower)) +/** + * @} + */ + +/** @defgroup STOP_mode_entry + * @{ + */ + +#define PWR_STOPEntry_WFI ((uint8_t)0x01) +#define PWR_STOPEntry_WFE ((uint8_t)0x02) +#define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPEntry_WFI) || ((ENTRY) == PWR_STOPEntry_WFE)) + +/** + * @} + */ + +/** @defgroup PWR_Flag + * @{ + */ + +#define PWR_FLAG_WU ((uint32_t)0x00000001) +#define PWR_FLAG_SB ((uint32_t)0x00000002) +#define PWR_FLAG_PVDO ((uint32_t)0x00000004) +#define IS_PWR_GET_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB) || \ + ((FLAG) == PWR_FLAG_PVDO)) + +#define IS_PWR_CLEAR_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB)) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup PWR_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup PWR_Exported_Functions + * @{ + */ + +void PWR_DeInit(void); +void PWR_BackupAccessCmd(FunctionalState NewState); +void PWR_PVDCmd(FunctionalState NewState); +void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel); +void PWR_WakeUpPinCmd(FunctionalState NewState); +void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry); +void PWR_EnterSTANDBYMode(void); +FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG); +void PWR_ClearFlag(uint32_t PWR_FLAG); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_PWR_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_rcc.h b/example/libs_stm/inc/stm32f10x/stm32f10x_rcc.h new file mode 100644 index 000000000..19afe3e45 --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_rcc.h @@ -0,0 +1,726 @@ +/** + ****************************************************************************** + * @file stm32f10x_rcc.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the RCC firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_RCC_H +#define __STM32F10x_RCC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup RCC + * @{ + */ + +/** @defgroup RCC_Exported_Types + * @{ + */ + +typedef struct +{ + uint32_t SYSCLK_Frequency; /*!< returns SYSCLK clock frequency expressed in Hz */ + uint32_t HCLK_Frequency; /*!< returns HCLK clock frequency expressed in Hz */ + uint32_t PCLK1_Frequency; /*!< returns PCLK1 clock frequency expressed in Hz */ + uint32_t PCLK2_Frequency; /*!< returns PCLK2 clock frequency expressed in Hz */ + uint32_t ADCCLK_Frequency; /*!< returns ADCCLK clock frequency expressed in Hz */ +}RCC_ClocksTypeDef; + +/** + * @} + */ + +/** @defgroup RCC_Exported_Constants + * @{ + */ + +/** @defgroup HSE_configuration + * @{ + */ + +#define RCC_HSE_OFF ((uint32_t)0x00000000) +#define RCC_HSE_ON ((uint32_t)0x00010000) +#define RCC_HSE_Bypass ((uint32_t)0x00040000) +#define IS_RCC_HSE(HSE) (((HSE) == RCC_HSE_OFF) || ((HSE) == RCC_HSE_ON) || \ + ((HSE) == RCC_HSE_Bypass)) + +/** + * @} + */ + +/** @defgroup PLL_entry_clock_source + * @{ + */ + +#define RCC_PLLSource_HSI_Div2 ((uint32_t)0x00000000) + +#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_CL) + #define RCC_PLLSource_HSE_Div1 ((uint32_t)0x00010000) + #define RCC_PLLSource_HSE_Div2 ((uint32_t)0x00030000) + #define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI_Div2) || \ + ((SOURCE) == RCC_PLLSource_HSE_Div1) || \ + ((SOURCE) == RCC_PLLSource_HSE_Div2)) +#else + #define RCC_PLLSource_PREDIV1 ((uint32_t)0x00010000) + #define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI_Div2) || \ + ((SOURCE) == RCC_PLLSource_PREDIV1)) +#endif /* STM32F10X_CL */ + +/** + * @} + */ + +/** @defgroup PLL_multiplication_factor + * @{ + */ +#ifndef STM32F10X_CL + #define RCC_PLLMul_2 ((uint32_t)0x00000000) + #define RCC_PLLMul_3 ((uint32_t)0x00040000) + #define RCC_PLLMul_4 ((uint32_t)0x00080000) + #define RCC_PLLMul_5 ((uint32_t)0x000C0000) + #define RCC_PLLMul_6 ((uint32_t)0x00100000) + #define RCC_PLLMul_7 ((uint32_t)0x00140000) + #define RCC_PLLMul_8 ((uint32_t)0x00180000) + #define RCC_PLLMul_9 ((uint32_t)0x001C0000) + #define RCC_PLLMul_10 ((uint32_t)0x00200000) + #define RCC_PLLMul_11 ((uint32_t)0x00240000) + #define RCC_PLLMul_12 ((uint32_t)0x00280000) + #define RCC_PLLMul_13 ((uint32_t)0x002C0000) + #define RCC_PLLMul_14 ((uint32_t)0x00300000) + #define RCC_PLLMul_15 ((uint32_t)0x00340000) + #define RCC_PLLMul_16 ((uint32_t)0x00380000) + #define IS_RCC_PLL_MUL(MUL) (((MUL) == RCC_PLLMul_2) || ((MUL) == RCC_PLLMul_3) || \ + ((MUL) == RCC_PLLMul_4) || ((MUL) == RCC_PLLMul_5) || \ + ((MUL) == RCC_PLLMul_6) || ((MUL) == RCC_PLLMul_7) || \ + ((MUL) == RCC_PLLMul_8) || ((MUL) == RCC_PLLMul_9) || \ + ((MUL) == RCC_PLLMul_10) || ((MUL) == RCC_PLLMul_11) || \ + ((MUL) == RCC_PLLMul_12) || ((MUL) == RCC_PLLMul_13) || \ + ((MUL) == RCC_PLLMul_14) || ((MUL) == RCC_PLLMul_15) || \ + ((MUL) == RCC_PLLMul_16)) + +#else + #define RCC_PLLMul_4 ((uint32_t)0x00080000) + #define RCC_PLLMul_5 ((uint32_t)0x000C0000) + #define RCC_PLLMul_6 ((uint32_t)0x00100000) + #define RCC_PLLMul_7 ((uint32_t)0x00140000) + #define RCC_PLLMul_8 ((uint32_t)0x00180000) + #define RCC_PLLMul_9 ((uint32_t)0x001C0000) + #define RCC_PLLMul_6_5 ((uint32_t)0x00340000) + + #define IS_RCC_PLL_MUL(MUL) (((MUL) == RCC_PLLMul_4) || ((MUL) == RCC_PLLMul_5) || \ + ((MUL) == RCC_PLLMul_6) || ((MUL) == RCC_PLLMul_7) || \ + ((MUL) == RCC_PLLMul_8) || ((MUL) == RCC_PLLMul_9) || \ + ((MUL) == RCC_PLLMul_6_5)) +#endif /* STM32F10X_CL */ +/** + * @} + */ + +/** @defgroup PREDIV1_division_factor + * @{ + */ +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_CL) + #define RCC_PREDIV1_Div1 ((uint32_t)0x00000000) + #define RCC_PREDIV1_Div2 ((uint32_t)0x00000001) + #define RCC_PREDIV1_Div3 ((uint32_t)0x00000002) + #define RCC_PREDIV1_Div4 ((uint32_t)0x00000003) + #define RCC_PREDIV1_Div5 ((uint32_t)0x00000004) + #define RCC_PREDIV1_Div6 ((uint32_t)0x00000005) + #define RCC_PREDIV1_Div7 ((uint32_t)0x00000006) + #define RCC_PREDIV1_Div8 ((uint32_t)0x00000007) + #define RCC_PREDIV1_Div9 ((uint32_t)0x00000008) + #define RCC_PREDIV1_Div10 ((uint32_t)0x00000009) + #define RCC_PREDIV1_Div11 ((uint32_t)0x0000000A) + #define RCC_PREDIV1_Div12 ((uint32_t)0x0000000B) + #define RCC_PREDIV1_Div13 ((uint32_t)0x0000000C) + #define RCC_PREDIV1_Div14 ((uint32_t)0x0000000D) + #define RCC_PREDIV1_Div15 ((uint32_t)0x0000000E) + #define RCC_PREDIV1_Div16 ((uint32_t)0x0000000F) + + #define IS_RCC_PREDIV1(PREDIV1) (((PREDIV1) == RCC_PREDIV1_Div1) || ((PREDIV1) == RCC_PREDIV1_Div2) || \ + ((PREDIV1) == RCC_PREDIV1_Div3) || ((PREDIV1) == RCC_PREDIV1_Div4) || \ + ((PREDIV1) == RCC_PREDIV1_Div5) || ((PREDIV1) == RCC_PREDIV1_Div6) || \ + ((PREDIV1) == RCC_PREDIV1_Div7) || ((PREDIV1) == RCC_PREDIV1_Div8) || \ + ((PREDIV1) == RCC_PREDIV1_Div9) || ((PREDIV1) == RCC_PREDIV1_Div10) || \ + ((PREDIV1) == RCC_PREDIV1_Div11) || ((PREDIV1) == RCC_PREDIV1_Div12) || \ + ((PREDIV1) == RCC_PREDIV1_Div13) || ((PREDIV1) == RCC_PREDIV1_Div14) || \ + ((PREDIV1) == RCC_PREDIV1_Div15) || ((PREDIV1) == RCC_PREDIV1_Div16)) +#endif +/** + * @} + */ + + +/** @defgroup PREDIV1_clock_source + * @{ + */ +#ifdef STM32F10X_CL +/* PREDIV1 clock source (for STM32 connectivity line devices) */ + #define RCC_PREDIV1_Source_HSE ((uint32_t)0x00000000) + #define RCC_PREDIV1_Source_PLL2 ((uint32_t)0x00010000) + + #define IS_RCC_PREDIV1_SOURCE(SOURCE) (((SOURCE) == RCC_PREDIV1_Source_HSE) || \ + ((SOURCE) == RCC_PREDIV1_Source_PLL2)) +#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) +/* PREDIV1 clock source (for STM32 Value line devices) */ + #define RCC_PREDIV1_Source_HSE ((uint32_t)0x00000000) + + #define IS_RCC_PREDIV1_SOURCE(SOURCE) (((SOURCE) == RCC_PREDIV1_Source_HSE)) +#endif +/** + * @} + */ + +#ifdef STM32F10X_CL +/** @defgroup PREDIV2_division_factor + * @{ + */ + + #define RCC_PREDIV2_Div1 ((uint32_t)0x00000000) + #define RCC_PREDIV2_Div2 ((uint32_t)0x00000010) + #define RCC_PREDIV2_Div3 ((uint32_t)0x00000020) + #define RCC_PREDIV2_Div4 ((uint32_t)0x00000030) + #define RCC_PREDIV2_Div5 ((uint32_t)0x00000040) + #define RCC_PREDIV2_Div6 ((uint32_t)0x00000050) + #define RCC_PREDIV2_Div7 ((uint32_t)0x00000060) + #define RCC_PREDIV2_Div8 ((uint32_t)0x00000070) + #define RCC_PREDIV2_Div9 ((uint32_t)0x00000080) + #define RCC_PREDIV2_Div10 ((uint32_t)0x00000090) + #define RCC_PREDIV2_Div11 ((uint32_t)0x000000A0) + #define RCC_PREDIV2_Div12 ((uint32_t)0x000000B0) + #define RCC_PREDIV2_Div13 ((uint32_t)0x000000C0) + #define RCC_PREDIV2_Div14 ((uint32_t)0x000000D0) + #define RCC_PREDIV2_Div15 ((uint32_t)0x000000E0) + #define RCC_PREDIV2_Div16 ((uint32_t)0x000000F0) + + #define IS_RCC_PREDIV2(PREDIV2) (((PREDIV2) == RCC_PREDIV2_Div1) || ((PREDIV2) == RCC_PREDIV2_Div2) || \ + ((PREDIV2) == RCC_PREDIV2_Div3) || ((PREDIV2) == RCC_PREDIV2_Div4) || \ + ((PREDIV2) == RCC_PREDIV2_Div5) || ((PREDIV2) == RCC_PREDIV2_Div6) || \ + ((PREDIV2) == RCC_PREDIV2_Div7) || ((PREDIV2) == RCC_PREDIV2_Div8) || \ + ((PREDIV2) == RCC_PREDIV2_Div9) || ((PREDIV2) == RCC_PREDIV2_Div10) || \ + ((PREDIV2) == RCC_PREDIV2_Div11) || ((PREDIV2) == RCC_PREDIV2_Div12) || \ + ((PREDIV2) == RCC_PREDIV2_Div13) || ((PREDIV2) == RCC_PREDIV2_Div14) || \ + ((PREDIV2) == RCC_PREDIV2_Div15) || ((PREDIV2) == RCC_PREDIV2_Div16)) +/** + * @} + */ + + +/** @defgroup PLL2_multiplication_factor + * @{ + */ + + #define RCC_PLL2Mul_8 ((uint32_t)0x00000600) + #define RCC_PLL2Mul_9 ((uint32_t)0x00000700) + #define RCC_PLL2Mul_10 ((uint32_t)0x00000800) + #define RCC_PLL2Mul_11 ((uint32_t)0x00000900) + #define RCC_PLL2Mul_12 ((uint32_t)0x00000A00) + #define RCC_PLL2Mul_13 ((uint32_t)0x00000B00) + #define RCC_PLL2Mul_14 ((uint32_t)0x00000C00) + #define RCC_PLL2Mul_16 ((uint32_t)0x00000E00) + #define RCC_PLL2Mul_20 ((uint32_t)0x00000F00) + + #define IS_RCC_PLL2_MUL(MUL) (((MUL) == RCC_PLL2Mul_8) || ((MUL) == RCC_PLL2Mul_9) || \ + ((MUL) == RCC_PLL2Mul_10) || ((MUL) == RCC_PLL2Mul_11) || \ + ((MUL) == RCC_PLL2Mul_12) || ((MUL) == RCC_PLL2Mul_13) || \ + ((MUL) == RCC_PLL2Mul_14) || ((MUL) == RCC_PLL2Mul_16) || \ + ((MUL) == RCC_PLL2Mul_20)) +/** + * @} + */ + + +/** @defgroup PLL3_multiplication_factor + * @{ + */ + + #define RCC_PLL3Mul_8 ((uint32_t)0x00006000) + #define RCC_PLL3Mul_9 ((uint32_t)0x00007000) + #define RCC_PLL3Mul_10 ((uint32_t)0x00008000) + #define RCC_PLL3Mul_11 ((uint32_t)0x00009000) + #define RCC_PLL3Mul_12 ((uint32_t)0x0000A000) + #define RCC_PLL3Mul_13 ((uint32_t)0x0000B000) + #define RCC_PLL3Mul_14 ((uint32_t)0x0000C000) + #define RCC_PLL3Mul_16 ((uint32_t)0x0000E000) + #define RCC_PLL3Mul_20 ((uint32_t)0x0000F000) + + #define IS_RCC_PLL3_MUL(MUL) (((MUL) == RCC_PLL3Mul_8) || ((MUL) == RCC_PLL3Mul_9) || \ + ((MUL) == RCC_PLL3Mul_10) || ((MUL) == RCC_PLL3Mul_11) || \ + ((MUL) == RCC_PLL3Mul_12) || ((MUL) == RCC_PLL3Mul_13) || \ + ((MUL) == RCC_PLL3Mul_14) || ((MUL) == RCC_PLL3Mul_16) || \ + ((MUL) == RCC_PLL3Mul_20)) +/** + * @} + */ + +#endif /* STM32F10X_CL */ + + +/** @defgroup System_clock_source + * @{ + */ + +#define RCC_SYSCLKSource_HSI ((uint32_t)0x00000000) +#define RCC_SYSCLKSource_HSE ((uint32_t)0x00000001) +#define RCC_SYSCLKSource_PLLCLK ((uint32_t)0x00000002) +#define IS_RCC_SYSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSource_HSI) || \ + ((SOURCE) == RCC_SYSCLKSource_HSE) || \ + ((SOURCE) == RCC_SYSCLKSource_PLLCLK)) +/** + * @} + */ + +/** @defgroup AHB_clock_source + * @{ + */ + +#define RCC_SYSCLK_Div1 ((uint32_t)0x00000000) +#define RCC_SYSCLK_Div2 ((uint32_t)0x00000080) +#define RCC_SYSCLK_Div4 ((uint32_t)0x00000090) +#define RCC_SYSCLK_Div8 ((uint32_t)0x000000A0) +#define RCC_SYSCLK_Div16 ((uint32_t)0x000000B0) +#define RCC_SYSCLK_Div64 ((uint32_t)0x000000C0) +#define RCC_SYSCLK_Div128 ((uint32_t)0x000000D0) +#define RCC_SYSCLK_Div256 ((uint32_t)0x000000E0) +#define RCC_SYSCLK_Div512 ((uint32_t)0x000000F0) +#define IS_RCC_HCLK(HCLK) (((HCLK) == RCC_SYSCLK_Div1) || ((HCLK) == RCC_SYSCLK_Div2) || \ + ((HCLK) == RCC_SYSCLK_Div4) || ((HCLK) == RCC_SYSCLK_Div8) || \ + ((HCLK) == RCC_SYSCLK_Div16) || ((HCLK) == RCC_SYSCLK_Div64) || \ + ((HCLK) == RCC_SYSCLK_Div128) || ((HCLK) == RCC_SYSCLK_Div256) || \ + ((HCLK) == RCC_SYSCLK_Div512)) +/** + * @} + */ + +/** @defgroup APB1_APB2_clock_source + * @{ + */ + +#define RCC_HCLK_Div1 ((uint32_t)0x00000000) +#define RCC_HCLK_Div2 ((uint32_t)0x00000400) +#define RCC_HCLK_Div4 ((uint32_t)0x00000500) +#define RCC_HCLK_Div8 ((uint32_t)0x00000600) +#define RCC_HCLK_Div16 ((uint32_t)0x00000700) +#define IS_RCC_PCLK(PCLK) (((PCLK) == RCC_HCLK_Div1) || ((PCLK) == RCC_HCLK_Div2) || \ + ((PCLK) == RCC_HCLK_Div4) || ((PCLK) == RCC_HCLK_Div8) || \ + ((PCLK) == RCC_HCLK_Div16)) +/** + * @} + */ + +/** @defgroup RCC_Interrupt_source + * @{ + */ + +#define RCC_IT_LSIRDY ((uint8_t)0x01) +#define RCC_IT_LSERDY ((uint8_t)0x02) +#define RCC_IT_HSIRDY ((uint8_t)0x04) +#define RCC_IT_HSERDY ((uint8_t)0x08) +#define RCC_IT_PLLRDY ((uint8_t)0x10) +#define RCC_IT_CSS ((uint8_t)0x80) + +#ifndef STM32F10X_CL + #define IS_RCC_IT(IT) ((((IT) & (uint8_t)0xE0) == 0x00) && ((IT) != 0x00)) + #define IS_RCC_GET_IT(IT) (((IT) == RCC_IT_LSIRDY) || ((IT) == RCC_IT_LSERDY) || \ + ((IT) == RCC_IT_HSIRDY) || ((IT) == RCC_IT_HSERDY) || \ + ((IT) == RCC_IT_PLLRDY) || ((IT) == RCC_IT_CSS)) + #define IS_RCC_CLEAR_IT(IT) ((((IT) & (uint8_t)0x60) == 0x00) && ((IT) != 0x00)) +#else + #define RCC_IT_PLL2RDY ((uint8_t)0x20) + #define RCC_IT_PLL3RDY ((uint8_t)0x40) + #define IS_RCC_IT(IT) ((((IT) & (uint8_t)0x80) == 0x00) && ((IT) != 0x00)) + #define IS_RCC_GET_IT(IT) (((IT) == RCC_IT_LSIRDY) || ((IT) == RCC_IT_LSERDY) || \ + ((IT) == RCC_IT_HSIRDY) || ((IT) == RCC_IT_HSERDY) || \ + ((IT) == RCC_IT_PLLRDY) || ((IT) == RCC_IT_CSS) || \ + ((IT) == RCC_IT_PLL2RDY) || ((IT) == RCC_IT_PLL3RDY)) + #define IS_RCC_CLEAR_IT(IT) ((IT) != 0x00) +#endif /* STM32F10X_CL */ + + +/** + * @} + */ + +#ifndef STM32F10X_CL +/** @defgroup USB_Device_clock_source + * @{ + */ + + #define RCC_USBCLKSource_PLLCLK_1Div5 ((uint8_t)0x00) + #define RCC_USBCLKSource_PLLCLK_Div1 ((uint8_t)0x01) + + #define IS_RCC_USBCLK_SOURCE(SOURCE) (((SOURCE) == RCC_USBCLKSource_PLLCLK_1Div5) || \ + ((SOURCE) == RCC_USBCLKSource_PLLCLK_Div1)) +/** + * @} + */ +#else +/** @defgroup USB_OTG_FS_clock_source + * @{ + */ + #define RCC_OTGFSCLKSource_PLLVCO_Div3 ((uint8_t)0x00) + #define RCC_OTGFSCLKSource_PLLVCO_Div2 ((uint8_t)0x01) + + #define IS_RCC_OTGFSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_OTGFSCLKSource_PLLVCO_Div3) || \ + ((SOURCE) == RCC_OTGFSCLKSource_PLLVCO_Div2)) +/** + * @} + */ +#endif /* STM32F10X_CL */ + + +#ifdef STM32F10X_CL +/** @defgroup I2S2_clock_source + * @{ + */ + #define RCC_I2S2CLKSource_SYSCLK ((uint8_t)0x00) + #define RCC_I2S2CLKSource_PLL3_VCO ((uint8_t)0x01) + + #define IS_RCC_I2S2CLK_SOURCE(SOURCE) (((SOURCE) == RCC_I2S2CLKSource_SYSCLK) || \ + ((SOURCE) == RCC_I2S2CLKSource_PLL3_VCO)) +/** + * @} + */ + +/** @defgroup I2S3_clock_source + * @{ + */ + #define RCC_I2S3CLKSource_SYSCLK ((uint8_t)0x00) + #define RCC_I2S3CLKSource_PLL3_VCO ((uint8_t)0x01) + + #define IS_RCC_I2S3CLK_SOURCE(SOURCE) (((SOURCE) == RCC_I2S3CLKSource_SYSCLK) || \ + ((SOURCE) == RCC_I2S3CLKSource_PLL3_VCO)) +/** + * @} + */ +#endif /* STM32F10X_CL */ + + +/** @defgroup ADC_clock_source + * @{ + */ + +#define RCC_PCLK2_Div2 ((uint32_t)0x00000000) +#define RCC_PCLK2_Div4 ((uint32_t)0x00004000) +#define RCC_PCLK2_Div6 ((uint32_t)0x00008000) +#define RCC_PCLK2_Div8 ((uint32_t)0x0000C000) +#define IS_RCC_ADCCLK(ADCCLK) (((ADCCLK) == RCC_PCLK2_Div2) || ((ADCCLK) == RCC_PCLK2_Div4) || \ + ((ADCCLK) == RCC_PCLK2_Div6) || ((ADCCLK) == RCC_PCLK2_Div8)) +/** + * @} + */ + +/** @defgroup LSE_configuration + * @{ + */ + +#define RCC_LSE_OFF ((uint8_t)0x00) +#define RCC_LSE_ON ((uint8_t)0x01) +#define RCC_LSE_Bypass ((uint8_t)0x04) +#define IS_RCC_LSE(LSE) (((LSE) == RCC_LSE_OFF) || ((LSE) == RCC_LSE_ON) || \ + ((LSE) == RCC_LSE_Bypass)) +/** + * @} + */ + +/** @defgroup RTC_clock_source + * @{ + */ + +#define RCC_RTCCLKSource_LSE ((uint32_t)0x00000100) +#define RCC_RTCCLKSource_LSI ((uint32_t)0x00000200) +#define RCC_RTCCLKSource_HSE_Div128 ((uint32_t)0x00000300) +#define IS_RCC_RTCCLK_SOURCE(SOURCE) (((SOURCE) == RCC_RTCCLKSource_LSE) || \ + ((SOURCE) == RCC_RTCCLKSource_LSI) || \ + ((SOURCE) == RCC_RTCCLKSource_HSE_Div128)) +/** + * @} + */ + +/** @defgroup AHB_peripheral + * @{ + */ + +#define RCC_AHBPeriph_DMA1 ((uint32_t)0x00000001) +#define RCC_AHBPeriph_DMA2 ((uint32_t)0x00000002) +#define RCC_AHBPeriph_SRAM ((uint32_t)0x00000004) +#define RCC_AHBPeriph_FLITF ((uint32_t)0x00000010) +#define RCC_AHBPeriph_CRC ((uint32_t)0x00000040) + +#ifndef STM32F10X_CL + #define RCC_AHBPeriph_FSMC ((uint32_t)0x00000100) + #define RCC_AHBPeriph_SDIO ((uint32_t)0x00000400) + #define IS_RCC_AHB_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFAA8) == 0x00) && ((PERIPH) != 0x00)) +#else + #define RCC_AHBPeriph_OTG_FS ((uint32_t)0x00001000) + #define RCC_AHBPeriph_ETH_MAC ((uint32_t)0x00004000) + #define RCC_AHBPeriph_ETH_MAC_Tx ((uint32_t)0x00008000) + #define RCC_AHBPeriph_ETH_MAC_Rx ((uint32_t)0x00010000) + + #define IS_RCC_AHB_PERIPH(PERIPH) ((((PERIPH) & 0xFFFE2FA8) == 0x00) && ((PERIPH) != 0x00)) + #define IS_RCC_AHB_PERIPH_RESET(PERIPH) ((((PERIPH) & 0xFFFFAFFF) == 0x00) && ((PERIPH) != 0x00)) +#endif /* STM32F10X_CL */ +/** + * @} + */ + +/** @defgroup APB2_peripheral + * @{ + */ + +#define RCC_APB2Periph_AFIO ((uint32_t)0x00000001) +#define RCC_APB2Periph_GPIOA ((uint32_t)0x00000004) +#define RCC_APB2Periph_GPIOB ((uint32_t)0x00000008) +#define RCC_APB2Periph_GPIOC ((uint32_t)0x00000010) +#define RCC_APB2Periph_GPIOD ((uint32_t)0x00000020) +#define RCC_APB2Periph_GPIOE ((uint32_t)0x00000040) +#define RCC_APB2Periph_GPIOF ((uint32_t)0x00000080) +#define RCC_APB2Periph_GPIOG ((uint32_t)0x00000100) +#define RCC_APB2Periph_ADC1 ((uint32_t)0x00000200) +#define RCC_APB2Periph_ADC2 ((uint32_t)0x00000400) +#define RCC_APB2Periph_TIM1 ((uint32_t)0x00000800) +#define RCC_APB2Periph_SPI1 ((uint32_t)0x00001000) +#define RCC_APB2Periph_TIM8 ((uint32_t)0x00002000) +#define RCC_APB2Periph_USART1 ((uint32_t)0x00004000) +#define RCC_APB2Periph_ADC3 ((uint32_t)0x00008000) +#define RCC_APB2Periph_TIM15 ((uint32_t)0x00010000) +#define RCC_APB2Periph_TIM16 ((uint32_t)0x00020000) +#define RCC_APB2Periph_TIM17 ((uint32_t)0x00040000) +#define RCC_APB2Periph_TIM9 ((uint32_t)0x00080000) +#define RCC_APB2Periph_TIM10 ((uint32_t)0x00100000) +#define RCC_APB2Periph_TIM11 ((uint32_t)0x00200000) + +#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFC00002) == 0x00) && ((PERIPH) != 0x00)) +/** + * @} + */ + +/** @defgroup APB1_peripheral + * @{ + */ + +#define RCC_APB1Periph_TIM2 ((uint32_t)0x00000001) +#define RCC_APB1Periph_TIM3 ((uint32_t)0x00000002) +#define RCC_APB1Periph_TIM4 ((uint32_t)0x00000004) +#define RCC_APB1Periph_TIM5 ((uint32_t)0x00000008) +#define RCC_APB1Periph_TIM6 ((uint32_t)0x00000010) +#define RCC_APB1Periph_TIM7 ((uint32_t)0x00000020) +#define RCC_APB1Periph_TIM12 ((uint32_t)0x00000040) +#define RCC_APB1Periph_TIM13 ((uint32_t)0x00000080) +#define RCC_APB1Periph_TIM14 ((uint32_t)0x00000100) +#define RCC_APB1Periph_WWDG ((uint32_t)0x00000800) +#define RCC_APB1Periph_SPI2 ((uint32_t)0x00004000) +#define RCC_APB1Periph_SPI3 ((uint32_t)0x00008000) +#define RCC_APB1Periph_USART2 ((uint32_t)0x00020000) +#define RCC_APB1Periph_USART3 ((uint32_t)0x00040000) +#define RCC_APB1Periph_UART4 ((uint32_t)0x00080000) +#define RCC_APB1Periph_UART5 ((uint32_t)0x00100000) +#define RCC_APB1Periph_I2C1 ((uint32_t)0x00200000) +#define RCC_APB1Periph_I2C2 ((uint32_t)0x00400000) +#define RCC_APB1Periph_USB ((uint32_t)0x00800000) +#define RCC_APB1Periph_CAN1 ((uint32_t)0x02000000) +#define RCC_APB1Periph_CAN2 ((uint32_t)0x04000000) +#define RCC_APB1Periph_BKP ((uint32_t)0x08000000) +#define RCC_APB1Periph_PWR ((uint32_t)0x10000000) +#define RCC_APB1Periph_DAC ((uint32_t)0x20000000) +#define RCC_APB1Periph_CEC ((uint32_t)0x40000000) + +#define IS_RCC_APB1_PERIPH(PERIPH) ((((PERIPH) & 0x81013600) == 0x00) && ((PERIPH) != 0x00)) + +/** + * @} + */ + +/** @defgroup Clock_source_to_output_on_MCO_pin + * @{ + */ + +#define RCC_MCO_NoClock ((uint8_t)0x00) +#define RCC_MCO_SYSCLK ((uint8_t)0x04) +#define RCC_MCO_HSI ((uint8_t)0x05) +#define RCC_MCO_HSE ((uint8_t)0x06) +#define RCC_MCO_PLLCLK_Div2 ((uint8_t)0x07) + +#ifndef STM32F10X_CL + #define IS_RCC_MCO(MCO) (((MCO) == RCC_MCO_NoClock) || ((MCO) == RCC_MCO_HSI) || \ + ((MCO) == RCC_MCO_SYSCLK) || ((MCO) == RCC_MCO_HSE) || \ + ((MCO) == RCC_MCO_PLLCLK_Div2)) +#else + #define RCC_MCO_PLL2CLK ((uint8_t)0x08) + #define RCC_MCO_PLL3CLK_Div2 ((uint8_t)0x09) + #define RCC_MCO_XT1 ((uint8_t)0x0A) + #define RCC_MCO_PLL3CLK ((uint8_t)0x0B) + + #define IS_RCC_MCO(MCO) (((MCO) == RCC_MCO_NoClock) || ((MCO) == RCC_MCO_HSI) || \ + ((MCO) == RCC_MCO_SYSCLK) || ((MCO) == RCC_MCO_HSE) || \ + ((MCO) == RCC_MCO_PLLCLK_Div2) || ((MCO) == RCC_MCO_PLL2CLK) || \ + ((MCO) == RCC_MCO_PLL3CLK_Div2) || ((MCO) == RCC_MCO_XT1) || \ + ((MCO) == RCC_MCO_PLL3CLK)) +#endif /* STM32F10X_CL */ + +/** + * @} + */ + +/** @defgroup RCC_Flag + * @{ + */ + +#define RCC_FLAG_HSIRDY ((uint8_t)0x21) +#define RCC_FLAG_HSERDY ((uint8_t)0x31) +#define RCC_FLAG_PLLRDY ((uint8_t)0x39) +#define RCC_FLAG_LSERDY ((uint8_t)0x41) +#define RCC_FLAG_LSIRDY ((uint8_t)0x61) +#define RCC_FLAG_PINRST ((uint8_t)0x7A) +#define RCC_FLAG_PORRST ((uint8_t)0x7B) +#define RCC_FLAG_SFTRST ((uint8_t)0x7C) +#define RCC_FLAG_IWDGRST ((uint8_t)0x7D) +#define RCC_FLAG_WWDGRST ((uint8_t)0x7E) +#define RCC_FLAG_LPWRRST ((uint8_t)0x7F) + +#ifndef STM32F10X_CL + #define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_HSIRDY) || ((FLAG) == RCC_FLAG_HSERDY) || \ + ((FLAG) == RCC_FLAG_PLLRDY) || ((FLAG) == RCC_FLAG_LSERDY) || \ + ((FLAG) == RCC_FLAG_LSIRDY) || ((FLAG) == RCC_FLAG_PINRST) || \ + ((FLAG) == RCC_FLAG_PORRST) || ((FLAG) == RCC_FLAG_SFTRST) || \ + ((FLAG) == RCC_FLAG_IWDGRST)|| ((FLAG) == RCC_FLAG_WWDGRST)|| \ + ((FLAG) == RCC_FLAG_LPWRRST)) +#else + #define RCC_FLAG_PLL2RDY ((uint8_t)0x3B) + #define RCC_FLAG_PLL3RDY ((uint8_t)0x3D) + #define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_HSIRDY) || ((FLAG) == RCC_FLAG_HSERDY) || \ + ((FLAG) == RCC_FLAG_PLLRDY) || ((FLAG) == RCC_FLAG_LSERDY) || \ + ((FLAG) == RCC_FLAG_PLL2RDY) || ((FLAG) == RCC_FLAG_PLL3RDY) || \ + ((FLAG) == RCC_FLAG_LSIRDY) || ((FLAG) == RCC_FLAG_PINRST) || \ + ((FLAG) == RCC_FLAG_PORRST) || ((FLAG) == RCC_FLAG_SFTRST) || \ + ((FLAG) == RCC_FLAG_IWDGRST)|| ((FLAG) == RCC_FLAG_WWDGRST)|| \ + ((FLAG) == RCC_FLAG_LPWRRST)) +#endif /* STM32F10X_CL */ + +#define IS_RCC_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x1F) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup RCC_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup RCC_Exported_Functions + * @{ + */ + +void RCC_DeInit(void); +void RCC_HSEConfig(uint32_t RCC_HSE); +ErrorStatus RCC_WaitForHSEStartUp(void); +void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue); +void RCC_HSICmd(FunctionalState NewState); +void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul); +void RCC_PLLCmd(FunctionalState NewState); + +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_CL) + void RCC_PREDIV1Config(uint32_t RCC_PREDIV1_Source, uint32_t RCC_PREDIV1_Div); +#endif + +#ifdef STM32F10X_CL + void RCC_PREDIV2Config(uint32_t RCC_PREDIV2_Div); + void RCC_PLL2Config(uint32_t RCC_PLL2Mul); + void RCC_PLL2Cmd(FunctionalState NewState); + void RCC_PLL3Config(uint32_t RCC_PLL3Mul); + void RCC_PLL3Cmd(FunctionalState NewState); +#endif /* STM32F10X_CL */ + +void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource); +uint8_t RCC_GetSYSCLKSource(void); +void RCC_HCLKConfig(uint32_t RCC_SYSCLK); +void RCC_PCLK1Config(uint32_t RCC_HCLK); +void RCC_PCLK2Config(uint32_t RCC_HCLK); +void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState); + +#ifndef STM32F10X_CL + void RCC_USBCLKConfig(uint32_t RCC_USBCLKSource); +#else + void RCC_OTGFSCLKConfig(uint32_t RCC_OTGFSCLKSource); +#endif /* STM32F10X_CL */ + +void RCC_ADCCLKConfig(uint32_t RCC_PCLK2); + +#ifdef STM32F10X_CL + void RCC_I2S2CLKConfig(uint32_t RCC_I2S2CLKSource); + void RCC_I2S3CLKConfig(uint32_t RCC_I2S3CLKSource); +#endif /* STM32F10X_CL */ + +void RCC_LSEConfig(uint8_t RCC_LSE); +void RCC_LSICmd(FunctionalState NewState); +void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource); +void RCC_RTCCLKCmd(FunctionalState NewState); +void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks); +void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); +void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); +void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); + +#ifdef STM32F10X_CL +void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); +#endif /* STM32F10X_CL */ + +void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); +void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); +void RCC_BackupResetCmd(FunctionalState NewState); +void RCC_ClockSecuritySystemCmd(FunctionalState NewState); +void RCC_MCOConfig(uint8_t RCC_MCO); +FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG); +void RCC_ClearFlag(void); +ITStatus RCC_GetITStatus(uint8_t RCC_IT); +void RCC_ClearITPendingBit(uint8_t RCC_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_RCC_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_rtc.h b/example/libs_stm/inc/stm32f10x/stm32f10x_rtc.h new file mode 100644 index 000000000..833f2fea1 --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_rtc.h @@ -0,0 +1,134 @@ +/** + ****************************************************************************** + * @file stm32f10x_rtc.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the RTC firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_RTC_H +#define __STM32F10x_RTC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup RTC + * @{ + */ + +/** @defgroup RTC_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup RTC_Exported_Constants + * @{ + */ + +/** @defgroup RTC_interrupts_define + * @{ + */ + +#define RTC_IT_OW ((uint16_t)0x0004) /*!< Overflow interrupt */ +#define RTC_IT_ALR ((uint16_t)0x0002) /*!< Alarm interrupt */ +#define RTC_IT_SEC ((uint16_t)0x0001) /*!< Second interrupt */ +#define IS_RTC_IT(IT) ((((IT) & (uint16_t)0xFFF8) == 0x00) && ((IT) != 0x00)) +#define IS_RTC_GET_IT(IT) (((IT) == RTC_IT_OW) || ((IT) == RTC_IT_ALR) || \ + ((IT) == RTC_IT_SEC)) +/** + * @} + */ + +/** @defgroup RTC_interrupts_flags + * @{ + */ + +#define RTC_FLAG_RTOFF ((uint16_t)0x0020) /*!< RTC Operation OFF flag */ +#define RTC_FLAG_RSF ((uint16_t)0x0008) /*!< Registers Synchronized flag */ +#define RTC_FLAG_OW ((uint16_t)0x0004) /*!< Overflow flag */ +#define RTC_FLAG_ALR ((uint16_t)0x0002) /*!< Alarm flag */ +#define RTC_FLAG_SEC ((uint16_t)0x0001) /*!< Second flag */ +#define IS_RTC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFFF0) == 0x00) && ((FLAG) != 0x00)) +#define IS_RTC_GET_FLAG(FLAG) (((FLAG) == RTC_FLAG_RTOFF) || ((FLAG) == RTC_FLAG_RSF) || \ + ((FLAG) == RTC_FLAG_OW) || ((FLAG) == RTC_FLAG_ALR) || \ + ((FLAG) == RTC_FLAG_SEC)) +#define IS_RTC_PRESCALER(PRESCALER) ((PRESCALER) <= 0xFFFFF) + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup RTC_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup RTC_Exported_Functions + * @{ + */ + +void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState); +void RTC_EnterConfigMode(void); +void RTC_ExitConfigMode(void); +uint32_t RTC_GetCounter(void); +void RTC_SetCounter(uint32_t CounterValue); +void RTC_SetPrescaler(uint32_t PrescalerValue); +void RTC_SetAlarm(uint32_t AlarmValue); +uint32_t RTC_GetDivider(void); +void RTC_WaitForLastTask(void); +void RTC_WaitForSynchro(void); +FlagStatus RTC_GetFlagStatus(uint16_t RTC_FLAG); +void RTC_ClearFlag(uint16_t RTC_FLAG); +ITStatus RTC_GetITStatus(uint16_t RTC_IT); +void RTC_ClearITPendingBit(uint16_t RTC_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_RTC_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_sdio.h b/example/libs_stm/inc/stm32f10x/stm32f10x_sdio.h new file mode 100644 index 000000000..a6c62cd8b --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_sdio.h @@ -0,0 +1,530 @@ +/** + ****************************************************************************** + * @file stm32f10x_sdio.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the SDIO firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_SDIO_H +#define __STM32F10x_SDIO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup SDIO + * @{ + */ + +/** @defgroup SDIO_Exported_Types + * @{ + */ + +typedef struct +{ + uint32_t SDIO_ClockEdge; /*!< Specifies the clock transition on which the bit capture is made. + This parameter can be a value of @ref SDIO_Clock_Edge */ + + uint32_t SDIO_ClockBypass; /*!< Specifies whether the SDIO Clock divider bypass is + enabled or disabled. + This parameter can be a value of @ref SDIO_Clock_Bypass */ + + uint32_t SDIO_ClockPowerSave; /*!< Specifies whether SDIO Clock output is enabled or + disabled when the bus is idle. + This parameter can be a value of @ref SDIO_Clock_Power_Save */ + + uint32_t SDIO_BusWide; /*!< Specifies the SDIO bus width. + This parameter can be a value of @ref SDIO_Bus_Wide */ + + uint32_t SDIO_HardwareFlowControl; /*!< Specifies whether the SDIO hardware flow control is enabled or disabled. + This parameter can be a value of @ref SDIO_Hardware_Flow_Control */ + + uint8_t SDIO_ClockDiv; /*!< Specifies the clock frequency of the SDIO controller. + This parameter can be a value between 0x00 and 0xFF. */ + +} SDIO_InitTypeDef; + +typedef struct +{ + uint32_t SDIO_Argument; /*!< Specifies the SDIO command argument which is sent + to a card as part of a command message. If a command + contains an argument, it must be loaded into this register + before writing the command to the command register */ + + uint32_t SDIO_CmdIndex; /*!< Specifies the SDIO command index. It must be lower than 0x40. */ + + uint32_t SDIO_Response; /*!< Specifies the SDIO response type. + This parameter can be a value of @ref SDIO_Response_Type */ + + uint32_t SDIO_Wait; /*!< Specifies whether SDIO wait-for-interrupt request is enabled or disabled. + This parameter can be a value of @ref SDIO_Wait_Interrupt_State */ + + uint32_t SDIO_CPSM; /*!< Specifies whether SDIO Command path state machine (CPSM) + is enabled or disabled. + This parameter can be a value of @ref SDIO_CPSM_State */ +} SDIO_CmdInitTypeDef; + +typedef struct +{ + uint32_t SDIO_DataTimeOut; /*!< Specifies the data timeout period in card bus clock periods. */ + + uint32_t SDIO_DataLength; /*!< Specifies the number of data bytes to be transferred. */ + + uint32_t SDIO_DataBlockSize; /*!< Specifies the data block size for block transfer. + This parameter can be a value of @ref SDIO_Data_Block_Size */ + + uint32_t SDIO_TransferDir; /*!< Specifies the data transfer direction, whether the transfer + is a read or write. + This parameter can be a value of @ref SDIO_Transfer_Direction */ + + uint32_t SDIO_TransferMode; /*!< Specifies whether data transfer is in stream or block mode. + This parameter can be a value of @ref SDIO_Transfer_Type */ + + uint32_t SDIO_DPSM; /*!< Specifies whether SDIO Data path state machine (DPSM) + is enabled or disabled. + This parameter can be a value of @ref SDIO_DPSM_State */ +} SDIO_DataInitTypeDef; + +/** + * @} + */ + +/** @defgroup SDIO_Exported_Constants + * @{ + */ + +/** @defgroup SDIO_Clock_Edge + * @{ + */ + +#define SDIO_ClockEdge_Rising ((uint32_t)0x00000000) +#define SDIO_ClockEdge_Falling ((uint32_t)0x00002000) +#define IS_SDIO_CLOCK_EDGE(EDGE) (((EDGE) == SDIO_ClockEdge_Rising) || \ + ((EDGE) == SDIO_ClockEdge_Falling)) +/** + * @} + */ + +/** @defgroup SDIO_Clock_Bypass + * @{ + */ + +#define SDIO_ClockBypass_Disable ((uint32_t)0x00000000) +#define SDIO_ClockBypass_Enable ((uint32_t)0x00000400) +#define IS_SDIO_CLOCK_BYPASS(BYPASS) (((BYPASS) == SDIO_ClockBypass_Disable) || \ + ((BYPASS) == SDIO_ClockBypass_Enable)) +/** + * @} + */ + +/** @defgroup SDIO_Clock_Power_Save + * @{ + */ + +#define SDIO_ClockPowerSave_Disable ((uint32_t)0x00000000) +#define SDIO_ClockPowerSave_Enable ((uint32_t)0x00000200) +#define IS_SDIO_CLOCK_POWER_SAVE(SAVE) (((SAVE) == SDIO_ClockPowerSave_Disable) || \ + ((SAVE) == SDIO_ClockPowerSave_Enable)) +/** + * @} + */ + +/** @defgroup SDIO_Bus_Wide + * @{ + */ + +#define SDIO_BusWide_1b ((uint32_t)0x00000000) +#define SDIO_BusWide_4b ((uint32_t)0x00000800) +#define SDIO_BusWide_8b ((uint32_t)0x00001000) +#define IS_SDIO_BUS_WIDE(WIDE) (((WIDE) == SDIO_BusWide_1b) || ((WIDE) == SDIO_BusWide_4b) || \ + ((WIDE) == SDIO_BusWide_8b)) + +/** + * @} + */ + +/** @defgroup SDIO_Hardware_Flow_Control + * @{ + */ + +#define SDIO_HardwareFlowControl_Disable ((uint32_t)0x00000000) +#define SDIO_HardwareFlowControl_Enable ((uint32_t)0x00004000) +#define IS_SDIO_HARDWARE_FLOW_CONTROL(CONTROL) (((CONTROL) == SDIO_HardwareFlowControl_Disable) || \ + ((CONTROL) == SDIO_HardwareFlowControl_Enable)) +/** + * @} + */ + +/** @defgroup SDIO_Power_State + * @{ + */ + +#define SDIO_PowerState_OFF ((uint32_t)0x00000000) +#define SDIO_PowerState_ON ((uint32_t)0x00000003) +#define IS_SDIO_POWER_STATE(STATE) (((STATE) == SDIO_PowerState_OFF) || ((STATE) == SDIO_PowerState_ON)) +/** + * @} + */ + + +/** @defgroup SDIO_Interrupt_soucres + * @{ + */ + +#define SDIO_IT_CCRCFAIL ((uint32_t)0x00000001) +#define SDIO_IT_DCRCFAIL ((uint32_t)0x00000002) +#define SDIO_IT_CTIMEOUT ((uint32_t)0x00000004) +#define SDIO_IT_DTIMEOUT ((uint32_t)0x00000008) +#define SDIO_IT_TXUNDERR ((uint32_t)0x00000010) +#define SDIO_IT_RXOVERR ((uint32_t)0x00000020) +#define SDIO_IT_CMDREND ((uint32_t)0x00000040) +#define SDIO_IT_CMDSENT ((uint32_t)0x00000080) +#define SDIO_IT_DATAEND ((uint32_t)0x00000100) +#define SDIO_IT_STBITERR ((uint32_t)0x00000200) +#define SDIO_IT_DBCKEND ((uint32_t)0x00000400) +#define SDIO_IT_CMDACT ((uint32_t)0x00000800) +#define SDIO_IT_TXACT ((uint32_t)0x00001000) +#define SDIO_IT_RXACT ((uint32_t)0x00002000) +#define SDIO_IT_TXFIFOHE ((uint32_t)0x00004000) +#define SDIO_IT_RXFIFOHF ((uint32_t)0x00008000) +#define SDIO_IT_TXFIFOF ((uint32_t)0x00010000) +#define SDIO_IT_RXFIFOF ((uint32_t)0x00020000) +#define SDIO_IT_TXFIFOE ((uint32_t)0x00040000) +#define SDIO_IT_RXFIFOE ((uint32_t)0x00080000) +#define SDIO_IT_TXDAVL ((uint32_t)0x00100000) +#define SDIO_IT_RXDAVL ((uint32_t)0x00200000) +#define SDIO_IT_SDIOIT ((uint32_t)0x00400000) +#define SDIO_IT_CEATAEND ((uint32_t)0x00800000) +#define IS_SDIO_IT(IT) ((((IT) & (uint32_t)0xFF000000) == 0x00) && ((IT) != (uint32_t)0x00)) +/** + * @} + */ + +/** @defgroup SDIO_Command_Index + * @{ + */ + +#define IS_SDIO_CMD_INDEX(INDEX) ((INDEX) < 0x40) +/** + * @} + */ + +/** @defgroup SDIO_Response_Type + * @{ + */ + +#define SDIO_Response_No ((uint32_t)0x00000000) +#define SDIO_Response_Short ((uint32_t)0x00000040) +#define SDIO_Response_Long ((uint32_t)0x000000C0) +#define IS_SDIO_RESPONSE(RESPONSE) (((RESPONSE) == SDIO_Response_No) || \ + ((RESPONSE) == SDIO_Response_Short) || \ + ((RESPONSE) == SDIO_Response_Long)) +/** + * @} + */ + +/** @defgroup SDIO_Wait_Interrupt_State + * @{ + */ + +#define SDIO_Wait_No ((uint32_t)0x00000000) /*!< SDIO No Wait, TimeOut is enabled */ +#define SDIO_Wait_IT ((uint32_t)0x00000100) /*!< SDIO Wait Interrupt Request */ +#define SDIO_Wait_Pend ((uint32_t)0x00000200) /*!< SDIO Wait End of transfer */ +#define IS_SDIO_WAIT(WAIT) (((WAIT) == SDIO_Wait_No) || ((WAIT) == SDIO_Wait_IT) || \ + ((WAIT) == SDIO_Wait_Pend)) +/** + * @} + */ + +/** @defgroup SDIO_CPSM_State + * @{ + */ + +#define SDIO_CPSM_Disable ((uint32_t)0x00000000) +#define SDIO_CPSM_Enable ((uint32_t)0x00000400) +#define IS_SDIO_CPSM(CPSM) (((CPSM) == SDIO_CPSM_Enable) || ((CPSM) == SDIO_CPSM_Disable)) +/** + * @} + */ + +/** @defgroup SDIO_Response_Registers + * @{ + */ + +#define SDIO_RESP1 ((uint32_t)0x00000000) +#define SDIO_RESP2 ((uint32_t)0x00000004) +#define SDIO_RESP3 ((uint32_t)0x00000008) +#define SDIO_RESP4 ((uint32_t)0x0000000C) +#define IS_SDIO_RESP(RESP) (((RESP) == SDIO_RESP1) || ((RESP) == SDIO_RESP2) || \ + ((RESP) == SDIO_RESP3) || ((RESP) == SDIO_RESP4)) +/** + * @} + */ + +/** @defgroup SDIO_Data_Length + * @{ + */ + +#define IS_SDIO_DATA_LENGTH(LENGTH) ((LENGTH) <= 0x01FFFFFF) +/** + * @} + */ + +/** @defgroup SDIO_Data_Block_Size + * @{ + */ + +#define SDIO_DataBlockSize_1b ((uint32_t)0x00000000) +#define SDIO_DataBlockSize_2b ((uint32_t)0x00000010) +#define SDIO_DataBlockSize_4b ((uint32_t)0x00000020) +#define SDIO_DataBlockSize_8b ((uint32_t)0x00000030) +#define SDIO_DataBlockSize_16b ((uint32_t)0x00000040) +#define SDIO_DataBlockSize_32b ((uint32_t)0x00000050) +#define SDIO_DataBlockSize_64b ((uint32_t)0x00000060) +#define SDIO_DataBlockSize_128b ((uint32_t)0x00000070) +#define SDIO_DataBlockSize_256b ((uint32_t)0x00000080) +#define SDIO_DataBlockSize_512b ((uint32_t)0x00000090) +#define SDIO_DataBlockSize_1024b ((uint32_t)0x000000A0) +#define SDIO_DataBlockSize_2048b ((uint32_t)0x000000B0) +#define SDIO_DataBlockSize_4096b ((uint32_t)0x000000C0) +#define SDIO_DataBlockSize_8192b ((uint32_t)0x000000D0) +#define SDIO_DataBlockSize_16384b ((uint32_t)0x000000E0) +#define IS_SDIO_BLOCK_SIZE(SIZE) (((SIZE) == SDIO_DataBlockSize_1b) || \ + ((SIZE) == SDIO_DataBlockSize_2b) || \ + ((SIZE) == SDIO_DataBlockSize_4b) || \ + ((SIZE) == SDIO_DataBlockSize_8b) || \ + ((SIZE) == SDIO_DataBlockSize_16b) || \ + ((SIZE) == SDIO_DataBlockSize_32b) || \ + ((SIZE) == SDIO_DataBlockSize_64b) || \ + ((SIZE) == SDIO_DataBlockSize_128b) || \ + ((SIZE) == SDIO_DataBlockSize_256b) || \ + ((SIZE) == SDIO_DataBlockSize_512b) || \ + ((SIZE) == SDIO_DataBlockSize_1024b) || \ + ((SIZE) == SDIO_DataBlockSize_2048b) || \ + ((SIZE) == SDIO_DataBlockSize_4096b) || \ + ((SIZE) == SDIO_DataBlockSize_8192b) || \ + ((SIZE) == SDIO_DataBlockSize_16384b)) +/** + * @} + */ + +/** @defgroup SDIO_Transfer_Direction + * @{ + */ + +#define SDIO_TransferDir_ToCard ((uint32_t)0x00000000) +#define SDIO_TransferDir_ToSDIO ((uint32_t)0x00000002) +#define IS_SDIO_TRANSFER_DIR(DIR) (((DIR) == SDIO_TransferDir_ToCard) || \ + ((DIR) == SDIO_TransferDir_ToSDIO)) +/** + * @} + */ + +/** @defgroup SDIO_Transfer_Type + * @{ + */ + +#define SDIO_TransferMode_Block ((uint32_t)0x00000000) +#define SDIO_TransferMode_Stream ((uint32_t)0x00000004) +#define IS_SDIO_TRANSFER_MODE(MODE) (((MODE) == SDIO_TransferMode_Stream) || \ + ((MODE) == SDIO_TransferMode_Block)) +/** + * @} + */ + +/** @defgroup SDIO_DPSM_State + * @{ + */ + +#define SDIO_DPSM_Disable ((uint32_t)0x00000000) +#define SDIO_DPSM_Enable ((uint32_t)0x00000001) +#define IS_SDIO_DPSM(DPSM) (((DPSM) == SDIO_DPSM_Enable) || ((DPSM) == SDIO_DPSM_Disable)) +/** + * @} + */ + +/** @defgroup SDIO_Flags + * @{ + */ + +#define SDIO_FLAG_CCRCFAIL ((uint32_t)0x00000001) +#define SDIO_FLAG_DCRCFAIL ((uint32_t)0x00000002) +#define SDIO_FLAG_CTIMEOUT ((uint32_t)0x00000004) +#define SDIO_FLAG_DTIMEOUT ((uint32_t)0x00000008) +#define SDIO_FLAG_TXUNDERR ((uint32_t)0x00000010) +#define SDIO_FLAG_RXOVERR ((uint32_t)0x00000020) +#define SDIO_FLAG_CMDREND ((uint32_t)0x00000040) +#define SDIO_FLAG_CMDSENT ((uint32_t)0x00000080) +#define SDIO_FLAG_DATAEND ((uint32_t)0x00000100) +#define SDIO_FLAG_STBITERR ((uint32_t)0x00000200) +#define SDIO_FLAG_DBCKEND ((uint32_t)0x00000400) +#define SDIO_FLAG_CMDACT ((uint32_t)0x00000800) +#define SDIO_FLAG_TXACT ((uint32_t)0x00001000) +#define SDIO_FLAG_RXACT ((uint32_t)0x00002000) +#define SDIO_FLAG_TXFIFOHE ((uint32_t)0x00004000) +#define SDIO_FLAG_RXFIFOHF ((uint32_t)0x00008000) +#define SDIO_FLAG_TXFIFOF ((uint32_t)0x00010000) +#define SDIO_FLAG_RXFIFOF ((uint32_t)0x00020000) +#define SDIO_FLAG_TXFIFOE ((uint32_t)0x00040000) +#define SDIO_FLAG_RXFIFOE ((uint32_t)0x00080000) +#define SDIO_FLAG_TXDAVL ((uint32_t)0x00100000) +#define SDIO_FLAG_RXDAVL ((uint32_t)0x00200000) +#define SDIO_FLAG_SDIOIT ((uint32_t)0x00400000) +#define SDIO_FLAG_CEATAEND ((uint32_t)0x00800000) +#define IS_SDIO_FLAG(FLAG) (((FLAG) == SDIO_FLAG_CCRCFAIL) || \ + ((FLAG) == SDIO_FLAG_DCRCFAIL) || \ + ((FLAG) == SDIO_FLAG_CTIMEOUT) || \ + ((FLAG) == SDIO_FLAG_DTIMEOUT) || \ + ((FLAG) == SDIO_FLAG_TXUNDERR) || \ + ((FLAG) == SDIO_FLAG_RXOVERR) || \ + ((FLAG) == SDIO_FLAG_CMDREND) || \ + ((FLAG) == SDIO_FLAG_CMDSENT) || \ + ((FLAG) == SDIO_FLAG_DATAEND) || \ + ((FLAG) == SDIO_FLAG_STBITERR) || \ + ((FLAG) == SDIO_FLAG_DBCKEND) || \ + ((FLAG) == SDIO_FLAG_CMDACT) || \ + ((FLAG) == SDIO_FLAG_TXACT) || \ + ((FLAG) == SDIO_FLAG_RXACT) || \ + ((FLAG) == SDIO_FLAG_TXFIFOHE) || \ + ((FLAG) == SDIO_FLAG_RXFIFOHF) || \ + ((FLAG) == SDIO_FLAG_TXFIFOF) || \ + ((FLAG) == SDIO_FLAG_RXFIFOF) || \ + ((FLAG) == SDIO_FLAG_TXFIFOE) || \ + ((FLAG) == SDIO_FLAG_RXFIFOE) || \ + ((FLAG) == SDIO_FLAG_TXDAVL) || \ + ((FLAG) == SDIO_FLAG_RXDAVL) || \ + ((FLAG) == SDIO_FLAG_SDIOIT) || \ + ((FLAG) == SDIO_FLAG_CEATAEND)) + +#define IS_SDIO_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFF3FF800) == 0x00) && ((FLAG) != (uint32_t)0x00)) + +#define IS_SDIO_GET_IT(IT) (((IT) == SDIO_IT_CCRCFAIL) || \ + ((IT) == SDIO_IT_DCRCFAIL) || \ + ((IT) == SDIO_IT_CTIMEOUT) || \ + ((IT) == SDIO_IT_DTIMEOUT) || \ + ((IT) == SDIO_IT_TXUNDERR) || \ + ((IT) == SDIO_IT_RXOVERR) || \ + ((IT) == SDIO_IT_CMDREND) || \ + ((IT) == SDIO_IT_CMDSENT) || \ + ((IT) == SDIO_IT_DATAEND) || \ + ((IT) == SDIO_IT_STBITERR) || \ + ((IT) == SDIO_IT_DBCKEND) || \ + ((IT) == SDIO_IT_CMDACT) || \ + ((IT) == SDIO_IT_TXACT) || \ + ((IT) == SDIO_IT_RXACT) || \ + ((IT) == SDIO_IT_TXFIFOHE) || \ + ((IT) == SDIO_IT_RXFIFOHF) || \ + ((IT) == SDIO_IT_TXFIFOF) || \ + ((IT) == SDIO_IT_RXFIFOF) || \ + ((IT) == SDIO_IT_TXFIFOE) || \ + ((IT) == SDIO_IT_RXFIFOE) || \ + ((IT) == SDIO_IT_TXDAVL) || \ + ((IT) == SDIO_IT_RXDAVL) || \ + ((IT) == SDIO_IT_SDIOIT) || \ + ((IT) == SDIO_IT_CEATAEND)) + +#define IS_SDIO_CLEAR_IT(IT) ((((IT) & (uint32_t)0xFF3FF800) == 0x00) && ((IT) != (uint32_t)0x00)) + +/** + * @} + */ + +/** @defgroup SDIO_Read_Wait_Mode + * @{ + */ + +#define SDIO_ReadWaitMode_CLK ((uint32_t)0x00000001) +#define SDIO_ReadWaitMode_DATA2 ((uint32_t)0x00000000) +#define IS_SDIO_READWAIT_MODE(MODE) (((MODE) == SDIO_ReadWaitMode_CLK) || \ + ((MODE) == SDIO_ReadWaitMode_DATA2)) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup SDIO_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup SDIO_Exported_Functions + * @{ + */ + +void SDIO_DeInit(void); +void SDIO_Init(SDIO_InitTypeDef* SDIO_InitStruct); +void SDIO_StructInit(SDIO_InitTypeDef* SDIO_InitStruct); +void SDIO_ClockCmd(FunctionalState NewState); +void SDIO_SetPowerState(uint32_t SDIO_PowerState); +uint32_t SDIO_GetPowerState(void); +void SDIO_ITConfig(uint32_t SDIO_IT, FunctionalState NewState); +void SDIO_DMACmd(FunctionalState NewState); +void SDIO_SendCommand(SDIO_CmdInitTypeDef *SDIO_CmdInitStruct); +void SDIO_CmdStructInit(SDIO_CmdInitTypeDef* SDIO_CmdInitStruct); +uint8_t SDIO_GetCommandResponse(void); +uint32_t SDIO_GetResponse(uint32_t SDIO_RESP); +void SDIO_DataConfig(SDIO_DataInitTypeDef* SDIO_DataInitStruct); +void SDIO_DataStructInit(SDIO_DataInitTypeDef* SDIO_DataInitStruct); +uint32_t SDIO_GetDataCounter(void); +uint32_t SDIO_ReadData(void); +void SDIO_WriteData(uint32_t Data); +uint32_t SDIO_GetFIFOCount(void); +void SDIO_StartSDIOReadWait(FunctionalState NewState); +void SDIO_StopSDIOReadWait(FunctionalState NewState); +void SDIO_SetSDIOReadWaitMode(uint32_t SDIO_ReadWaitMode); +void SDIO_SetSDIOOperation(FunctionalState NewState); +void SDIO_SendSDIOSuspendCmd(FunctionalState NewState); +void SDIO_CommandCompletionCmd(FunctionalState NewState); +void SDIO_CEATAITCmd(FunctionalState NewState); +void SDIO_SendCEATACmd(FunctionalState NewState); +FlagStatus SDIO_GetFlagStatus(uint32_t SDIO_FLAG); +void SDIO_ClearFlag(uint32_t SDIO_FLAG); +ITStatus SDIO_GetITStatus(uint32_t SDIO_IT); +void SDIO_ClearITPendingBit(uint32_t SDIO_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_SDIO_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_spi.h b/example/libs_stm/inc/stm32f10x/stm32f10x_spi.h new file mode 100644 index 000000000..920c82697 --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_spi.h @@ -0,0 +1,490 @@ +/** + ****************************************************************************** + * @file stm32f10x_spi.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the SPI firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_SPI_H +#define __STM32F10x_SPI_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup SPI + * @{ + */ + +/** @defgroup SPI_Exported_Types + * @{ + */ + +/** + * @brief SPI Init structure definition + */ + +typedef struct +{ + uint16_t SPI_Direction; /*!< Specifies the SPI unidirectional or bidirectional data mode. + This parameter can be a value of @ref SPI_data_direction */ + + uint16_t SPI_Mode; /*!< Specifies the SPI operating mode. + This parameter can be a value of @ref SPI_mode */ + + uint16_t SPI_DataSize; /*!< Specifies the SPI data size. + This parameter can be a value of @ref SPI_data_size */ + + uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state. + This parameter can be a value of @ref SPI_Clock_Polarity */ + + uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref SPI_Clock_Phase */ + + uint16_t SPI_NSS; /*!< Specifies whether the NSS signal is managed by + hardware (NSS pin) or by software using the SSI bit. + This parameter can be a value of @ref SPI_Slave_Select_management */ + + uint16_t SPI_BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be + used to configure the transmit and receive SCK clock. + This parameter can be a value of @ref SPI_BaudRate_Prescaler. + @note The communication clock is derived from the master + clock. The slave clock does not need to be set. */ + + uint16_t SPI_FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit. + This parameter can be a value of @ref SPI_MSB_LSB_transmission */ + + uint16_t SPI_CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. */ +}SPI_InitTypeDef; + +/** + * @brief I2S Init structure definition + */ + +typedef struct +{ + + uint16_t I2S_Mode; /*!< Specifies the I2S operating mode. + This parameter can be a value of @ref I2S_Mode */ + + uint16_t I2S_Standard; /*!< Specifies the standard used for the I2S communication. + This parameter can be a value of @ref I2S_Standard */ + + uint16_t I2S_DataFormat; /*!< Specifies the data format for the I2S communication. + This parameter can be a value of @ref I2S_Data_Format */ + + uint16_t I2S_MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not. + This parameter can be a value of @ref I2S_MCLK_Output */ + + uint32_t I2S_AudioFreq; /*!< Specifies the frequency selected for the I2S communication. + This parameter can be a value of @ref I2S_Audio_Frequency */ + + uint16_t I2S_CPOL; /*!< Specifies the idle state of the I2S clock. + This parameter can be a value of @ref I2S_Clock_Polarity */ +}I2S_InitTypeDef; + +/** + * @} + */ + +/** @defgroup SPI_Exported_Constants + * @{ + */ + +#define IS_SPI_ALL_PERIPH(PERIPH) (((PERIPH) == SPI1) || \ + ((PERIPH) == SPI2) || \ + ((PERIPH) == SPI3)) + +#define IS_SPI_23_PERIPH(PERIPH) (((PERIPH) == SPI2) || \ + ((PERIPH) == SPI3)) + +/** @defgroup SPI_data_direction + * @{ + */ + +#define SPI_Direction_2Lines_FullDuplex ((uint16_t)0x0000) +#define SPI_Direction_2Lines_RxOnly ((uint16_t)0x0400) +#define SPI_Direction_1Line_Rx ((uint16_t)0x8000) +#define SPI_Direction_1Line_Tx ((uint16_t)0xC000) +#define IS_SPI_DIRECTION_MODE(MODE) (((MODE) == SPI_Direction_2Lines_FullDuplex) || \ + ((MODE) == SPI_Direction_2Lines_RxOnly) || \ + ((MODE) == SPI_Direction_1Line_Rx) || \ + ((MODE) == SPI_Direction_1Line_Tx)) +/** + * @} + */ + +/** @defgroup SPI_mode + * @{ + */ + +#define SPI_Mode_Master ((uint16_t)0x0104) +#define SPI_Mode_Slave ((uint16_t)0x0000) +#define IS_SPI_MODE(MODE) (((MODE) == SPI_Mode_Master) || \ + ((MODE) == SPI_Mode_Slave)) +/** + * @} + */ + +/** @defgroup SPI_data_size + * @{ + */ + +#define SPI_DataSize_16b ((uint16_t)0x0800) +#define SPI_DataSize_8b ((uint16_t)0x0000) +#define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DataSize_16b) || \ + ((DATASIZE) == SPI_DataSize_8b)) +/** + * @} + */ + +/** @defgroup SPI_Clock_Polarity + * @{ + */ + +#define SPI_CPOL_Low ((uint16_t)0x0000) +#define SPI_CPOL_High ((uint16_t)0x0002) +#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_CPOL_Low) || \ + ((CPOL) == SPI_CPOL_High)) +/** + * @} + */ + +/** @defgroup SPI_Clock_Phase + * @{ + */ + +#define SPI_CPHA_1Edge ((uint16_t)0x0000) +#define SPI_CPHA_2Edge ((uint16_t)0x0001) +#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_CPHA_1Edge) || \ + ((CPHA) == SPI_CPHA_2Edge)) +/** + * @} + */ + +/** @defgroup SPI_Slave_Select_management + * @{ + */ + +#define SPI_NSS_Soft ((uint16_t)0x0200) +#define SPI_NSS_Hard ((uint16_t)0x0000) +#define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_Soft) || \ + ((NSS) == SPI_NSS_Hard)) +/** + * @} + */ + +/** @defgroup SPI_BaudRate_Prescaler + * @{ + */ + +#define SPI_BaudRatePrescaler_2 ((uint16_t)0x0000) +#define SPI_BaudRatePrescaler_4 ((uint16_t)0x0008) +#define SPI_BaudRatePrescaler_8 ((uint16_t)0x0010) +#define SPI_BaudRatePrescaler_16 ((uint16_t)0x0018) +#define SPI_BaudRatePrescaler_32 ((uint16_t)0x0020) +#define SPI_BaudRatePrescaler_64 ((uint16_t)0x0028) +#define SPI_BaudRatePrescaler_128 ((uint16_t)0x0030) +#define SPI_BaudRatePrescaler_256 ((uint16_t)0x0038) +#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BaudRatePrescaler_2) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_4) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_8) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_16) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_32) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_64) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_128) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_256)) +/** + * @} + */ + +/** @defgroup SPI_MSB_LSB_transmission + * @{ + */ + +#define SPI_FirstBit_MSB ((uint16_t)0x0000) +#define SPI_FirstBit_LSB ((uint16_t)0x0080) +#define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FirstBit_MSB) || \ + ((BIT) == SPI_FirstBit_LSB)) +/** + * @} + */ + +/** @defgroup I2S_Mode + * @{ + */ + +#define I2S_Mode_SlaveTx ((uint16_t)0x0000) +#define I2S_Mode_SlaveRx ((uint16_t)0x0100) +#define I2S_Mode_MasterTx ((uint16_t)0x0200) +#define I2S_Mode_MasterRx ((uint16_t)0x0300) +#define IS_I2S_MODE(MODE) (((MODE) == I2S_Mode_SlaveTx) || \ + ((MODE) == I2S_Mode_SlaveRx) || \ + ((MODE) == I2S_Mode_MasterTx) || \ + ((MODE) == I2S_Mode_MasterRx) ) +/** + * @} + */ + +/** @defgroup I2S_Standard + * @{ + */ + +#define I2S_Standard_Phillips ((uint16_t)0x0000) +#define I2S_Standard_MSB ((uint16_t)0x0010) +#define I2S_Standard_LSB ((uint16_t)0x0020) +#define I2S_Standard_PCMShort ((uint16_t)0x0030) +#define I2S_Standard_PCMLong ((uint16_t)0x00B0) +#define IS_I2S_STANDARD(STANDARD) (((STANDARD) == I2S_Standard_Phillips) || \ + ((STANDARD) == I2S_Standard_MSB) || \ + ((STANDARD) == I2S_Standard_LSB) || \ + ((STANDARD) == I2S_Standard_PCMShort) || \ + ((STANDARD) == I2S_Standard_PCMLong)) +/** + * @} + */ + +/** @defgroup I2S_Data_Format + * @{ + */ + +#define I2S_DataFormat_16b ((uint16_t)0x0000) +#define I2S_DataFormat_16bextended ((uint16_t)0x0001) +#define I2S_DataFormat_24b ((uint16_t)0x0003) +#define I2S_DataFormat_32b ((uint16_t)0x0005) +#define IS_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == I2S_DataFormat_16b) || \ + ((FORMAT) == I2S_DataFormat_16bextended) || \ + ((FORMAT) == I2S_DataFormat_24b) || \ + ((FORMAT) == I2S_DataFormat_32b)) +/** + * @} + */ + +/** @defgroup I2S_MCLK_Output + * @{ + */ + +#define I2S_MCLKOutput_Enable ((uint16_t)0x0200) +#define I2S_MCLKOutput_Disable ((uint16_t)0x0000) +#define IS_I2S_MCLK_OUTPUT(OUTPUT) (((OUTPUT) == I2S_MCLKOutput_Enable) || \ + ((OUTPUT) == I2S_MCLKOutput_Disable)) +/** + * @} + */ + +/** @defgroup I2S_Audio_Frequency + * @{ + */ + +#define I2S_AudioFreq_96k ((uint32_t)96000) +#define I2S_AudioFreq_48k ((uint32_t)48000) +#define I2S_AudioFreq_44k ((uint32_t)44100) +#define I2S_AudioFreq_32k ((uint32_t)32000) +#define I2S_AudioFreq_22k ((uint32_t)22050) +#define I2S_AudioFreq_16k ((uint32_t)16000) +#define I2S_AudioFreq_11k ((uint32_t)11025) +#define I2S_AudioFreq_8k ((uint32_t)8000) +#define I2S_AudioFreq_Default ((uint32_t)2) +#define IS_I2S_AUDIO_FREQ(FREQ) (((FREQ) == I2S_AudioFreq_96k) || \ + ((FREQ) == I2S_AudioFreq_48k) || \ + ((FREQ) == I2S_AudioFreq_44k) || \ + ((FREQ) == I2S_AudioFreq_32k) || \ + ((FREQ) == I2S_AudioFreq_22k) || \ + ((FREQ) == I2S_AudioFreq_16k) || \ + ((FREQ) == I2S_AudioFreq_11k) || \ + ((FREQ) == I2S_AudioFreq_8k) || \ + ((FREQ) == I2S_AudioFreq_Default)) +/** + * @} + */ + +/** @defgroup I2S_Clock_Polarity + * @{ + */ + +#define I2S_CPOL_Low ((uint16_t)0x0000) +#define I2S_CPOL_High ((uint16_t)0x0008) +#define IS_I2S_CPOL(CPOL) (((CPOL) == I2S_CPOL_Low) || \ + ((CPOL) == I2S_CPOL_High)) +/** + * @} + */ + +/** @defgroup SPI_I2S_DMA_transfer_requests + * @{ + */ + +#define SPI_I2S_DMAReq_Tx ((uint16_t)0x0002) +#define SPI_I2S_DMAReq_Rx ((uint16_t)0x0001) +#define IS_SPI_I2S_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFFFC) == 0x00) && ((DMAREQ) != 0x00)) +/** + * @} + */ + +/** @defgroup SPI_NSS_internal_software_mangement + * @{ + */ + +#define SPI_NSSInternalSoft_Set ((uint16_t)0x0100) +#define SPI_NSSInternalSoft_Reset ((uint16_t)0xFEFF) +#define IS_SPI_NSS_INTERNAL(INTERNAL) (((INTERNAL) == SPI_NSSInternalSoft_Set) || \ + ((INTERNAL) == SPI_NSSInternalSoft_Reset)) +/** + * @} + */ + +/** @defgroup SPI_CRC_Transmit_Receive + * @{ + */ + +#define SPI_CRC_Tx ((uint8_t)0x00) +#define SPI_CRC_Rx ((uint8_t)0x01) +#define IS_SPI_CRC(CRC) (((CRC) == SPI_CRC_Tx) || ((CRC) == SPI_CRC_Rx)) +/** + * @} + */ + +/** @defgroup SPI_direction_transmit_receive + * @{ + */ + +#define SPI_Direction_Rx ((uint16_t)0xBFFF) +#define SPI_Direction_Tx ((uint16_t)0x4000) +#define IS_SPI_DIRECTION(DIRECTION) (((DIRECTION) == SPI_Direction_Rx) || \ + ((DIRECTION) == SPI_Direction_Tx)) +/** + * @} + */ + +/** @defgroup SPI_I2S_interrupts_definition + * @{ + */ + +#define SPI_I2S_IT_TXE ((uint8_t)0x71) +#define SPI_I2S_IT_RXNE ((uint8_t)0x60) +#define SPI_I2S_IT_ERR ((uint8_t)0x50) +#define IS_SPI_I2S_CONFIG_IT(IT) (((IT) == SPI_I2S_IT_TXE) || \ + ((IT) == SPI_I2S_IT_RXNE) || \ + ((IT) == SPI_I2S_IT_ERR)) +#define SPI_I2S_IT_OVR ((uint8_t)0x56) +#define SPI_IT_MODF ((uint8_t)0x55) +#define SPI_IT_CRCERR ((uint8_t)0x54) +#define I2S_IT_UDR ((uint8_t)0x53) +#define IS_SPI_I2S_CLEAR_IT(IT) (((IT) == SPI_IT_CRCERR)) +#define IS_SPI_I2S_GET_IT(IT) (((IT) == SPI_I2S_IT_RXNE) || ((IT) == SPI_I2S_IT_TXE) || \ + ((IT) == I2S_IT_UDR) || ((IT) == SPI_IT_CRCERR) || \ + ((IT) == SPI_IT_MODF) || ((IT) == SPI_I2S_IT_OVR)) +/** + * @} + */ + +/** @defgroup SPI_I2S_flags_definition + * @{ + */ + +#define SPI_I2S_FLAG_RXNE ((uint16_t)0x0001) +#define SPI_I2S_FLAG_TXE ((uint16_t)0x0002) +#define I2S_FLAG_CHSIDE ((uint16_t)0x0004) +#define I2S_FLAG_UDR ((uint16_t)0x0008) +#define SPI_FLAG_CRCERR ((uint16_t)0x0010) +#define SPI_FLAG_MODF ((uint16_t)0x0020) +#define SPI_I2S_FLAG_OVR ((uint16_t)0x0040) +#define SPI_I2S_FLAG_BSY ((uint16_t)0x0080) +#define IS_SPI_I2S_CLEAR_FLAG(FLAG) (((FLAG) == SPI_FLAG_CRCERR)) +#define IS_SPI_I2S_GET_FLAG(FLAG) (((FLAG) == SPI_I2S_FLAG_BSY) || ((FLAG) == SPI_I2S_FLAG_OVR) || \ + ((FLAG) == SPI_FLAG_MODF) || ((FLAG) == SPI_FLAG_CRCERR) || \ + ((FLAG) == I2S_FLAG_UDR) || ((FLAG) == I2S_FLAG_CHSIDE) || \ + ((FLAG) == SPI_I2S_FLAG_TXE) || ((FLAG) == SPI_I2S_FLAG_RXNE)) +/** + * @} + */ + +/** @defgroup SPI_CRC_polynomial + * @{ + */ + +#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) ((POLYNOMIAL) >= 0x1) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup SPI_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup SPI_Exported_Functions + * @{ + */ + +void SPI_I2S_DeInit(SPI_TypeDef* SPIx); +void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct); +void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct); +void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct); +void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct); +void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); +void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); +void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState); +void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState); +void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data); +uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx); +void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft); +void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState); +void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize); +void SPI_TransmitCRC(SPI_TypeDef* SPIx); +void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState); +uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC); +uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx); +void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction); +FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); +void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); +ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); +void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F10x_SPI_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_tim.h b/example/libs_stm/inc/stm32f10x/stm32f10x_tim.h new file mode 100644 index 000000000..500c195d2 --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_tim.h @@ -0,0 +1,1133 @@ +/** + ****************************************************************************** + * @file stm32f10x_tim.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the TIM firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_TIM_H +#define __STM32F10x_TIM_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup TIM + * @{ + */ + +/** @defgroup TIM_Exported_Types + * @{ + */ + +/** + * @brief TIM Time Base Init structure definition + * @note This sturcture is used with all TIMx except for TIM6 and TIM7. + */ + +typedef struct +{ + uint16_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. + This parameter can be a number between 0x0000 and 0xFFFF */ + + uint16_t TIM_CounterMode; /*!< Specifies the counter mode. + This parameter can be a value of @ref TIM_Counter_Mode */ + + uint16_t TIM_Period; /*!< Specifies the period value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter must be a number between 0x0000 and 0xFFFF. */ + + uint16_t TIM_ClockDivision; /*!< Specifies the clock division. + This parameter can be a value of @ref TIM_Clock_Division_CKD */ + + uint8_t TIM_RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter + reaches zero, an update event is generated and counting restarts + from the RCR value (N). + This means in PWM mode that (N+1) corresponds to: + - the number of PWM periods in edge-aligned mode + - the number of half PWM period in center-aligned mode + This parameter must be a number between 0x00 and 0xFF. + @note This parameter is valid only for TIM1 and TIM8. */ +} TIM_TimeBaseInitTypeDef; + +/** + * @brief TIM Output Compare Init structure definition + */ + +typedef struct +{ + uint16_t TIM_OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ + + uint16_t TIM_OutputState; /*!< Specifies the TIM Output Compare state. + This parameter can be a value of @ref TIM_Output_Compare_state */ + + uint16_t TIM_OutputNState; /*!< Specifies the TIM complementary Output Compare state. + This parameter can be a value of @ref TIM_Output_Compare_N_state + @note This parameter is valid only for TIM1 and TIM8. */ + + uint16_t TIM_Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between 0x0000 and 0xFFFF */ + + uint16_t TIM_OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_Output_Compare_Polarity */ + + uint16_t TIM_OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref TIM_Output_Compare_N_Polarity + @note This parameter is valid only for TIM1 and TIM8. */ + + uint16_t TIM_OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_Idle_State + @note This parameter is valid only for TIM1 and TIM8. */ + + uint16_t TIM_OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State + @note This parameter is valid only for TIM1 and TIM8. */ +} TIM_OCInitTypeDef; + +/** + * @brief TIM Input Capture Init structure definition + */ + +typedef struct +{ + + uint16_t TIM_Channel; /*!< Specifies the TIM channel. + This parameter can be a value of @ref TIM_Channel */ + + uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint16_t TIM_ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint16_t TIM_ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between 0x0 and 0xF */ +} TIM_ICInitTypeDef; + +/** + * @brief BDTR structure definition + * @note This sturcture is used only with TIM1 and TIM8. + */ + +typedef struct +{ + + uint16_t TIM_OSSRState; /*!< Specifies the Off-State selection used in Run mode. + This parameter can be a value of @ref OSSR_Off_State_Selection_for_Run_mode_state */ + + uint16_t TIM_OSSIState; /*!< Specifies the Off-State used in Idle state. + This parameter can be a value of @ref OSSI_Off_State_Selection_for_Idle_mode_state */ + + uint16_t TIM_LOCKLevel; /*!< Specifies the LOCK level parameters. + This parameter can be a value of @ref Lock_level */ + + uint16_t TIM_DeadTime; /*!< Specifies the delay time between the switching-off and the + switching-on of the outputs. + This parameter can be a number between 0x00 and 0xFF */ + + uint16_t TIM_Break; /*!< Specifies whether the TIM Break input is enabled or not. + This parameter can be a value of @ref Break_Input_enable_disable */ + + uint16_t TIM_BreakPolarity; /*!< Specifies the TIM Break Input pin polarity. + This parameter can be a value of @ref Break_Polarity */ + + uint16_t TIM_AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature is enabled or not. + This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */ +} TIM_BDTRInitTypeDef; + +/** @defgroup TIM_Exported_constants + * @{ + */ + +#define IS_TIM_ALL_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM6) || \ + ((PERIPH) == TIM7) || \ + ((PERIPH) == TIM8) || \ + ((PERIPH) == TIM9) || \ + ((PERIPH) == TIM10)|| \ + ((PERIPH) == TIM11)|| \ + ((PERIPH) == TIM12)|| \ + ((PERIPH) == TIM13)|| \ + ((PERIPH) == TIM14)|| \ + ((PERIPH) == TIM15)|| \ + ((PERIPH) == TIM16)|| \ + ((PERIPH) == TIM17)) + +/* LIST1: TIM 1 and 8 */ +#define IS_TIM_LIST1_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM8)) + +/* LIST2: TIM 1, 8, 15 16 and 17 */ +#define IS_TIM_LIST2_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM8) || \ + ((PERIPH) == TIM15)|| \ + ((PERIPH) == TIM16)|| \ + ((PERIPH) == TIM17)) + +/* LIST3: TIM 1, 2, 3, 4, 5 and 8 */ +#define IS_TIM_LIST3_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM8)) + +/* LIST4: TIM 1, 2, 3, 4, 5, 8, 15, 16 and 17 */ +#define IS_TIM_LIST4_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM8) || \ + ((PERIPH) == TIM15)|| \ + ((PERIPH) == TIM16)|| \ + ((PERIPH) == TIM17)) + +/* LIST5: TIM 1, 2, 3, 4, 5, 8 and 15 */ +#define IS_TIM_LIST5_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM8) || \ + ((PERIPH) == TIM15)) + +/* LIST6: TIM 1, 2, 3, 4, 5, 8, 9, 12 and 15 */ +#define IS_TIM_LIST6_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM8) || \ + ((PERIPH) == TIM9) || \ + ((PERIPH) == TIM12)|| \ + ((PERIPH) == TIM15)) + +/* LIST7: TIM 1, 2, 3, 4, 5, 6, 7, 8, 9, 12 and 15 */ +#define IS_TIM_LIST7_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM6) || \ + ((PERIPH) == TIM7) || \ + ((PERIPH) == TIM8) || \ + ((PERIPH) == TIM9) || \ + ((PERIPH) == TIM12)|| \ + ((PERIPH) == TIM15)) + +/* LIST8: TIM 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16 and 17 */ +#define IS_TIM_LIST8_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM8) || \ + ((PERIPH) == TIM9) || \ + ((PERIPH) == TIM10)|| \ + ((PERIPH) == TIM11)|| \ + ((PERIPH) == TIM12)|| \ + ((PERIPH) == TIM13)|| \ + ((PERIPH) == TIM14)|| \ + ((PERIPH) == TIM15)|| \ + ((PERIPH) == TIM16)|| \ + ((PERIPH) == TIM17)) + +/* LIST9: TIM 1, 2, 3, 4, 5, 6, 7, 8, 15, 16, and 17 */ +#define IS_TIM_LIST9_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM6) || \ + ((PERIPH) == TIM7) || \ + ((PERIPH) == TIM8) || \ + ((PERIPH) == TIM15)|| \ + ((PERIPH) == TIM16)|| \ + ((PERIPH) == TIM17)) + +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_and_PWM_modes + * @{ + */ + +#define TIM_OCMode_Timing ((uint16_t)0x0000) +#define TIM_OCMode_Active ((uint16_t)0x0010) +#define TIM_OCMode_Inactive ((uint16_t)0x0020) +#define TIM_OCMode_Toggle ((uint16_t)0x0030) +#define TIM_OCMode_PWM1 ((uint16_t)0x0060) +#define TIM_OCMode_PWM2 ((uint16_t)0x0070) +#define IS_TIM_OC_MODE(MODE) (((MODE) == TIM_OCMode_Timing) || \ + ((MODE) == TIM_OCMode_Active) || \ + ((MODE) == TIM_OCMode_Inactive) || \ + ((MODE) == TIM_OCMode_Toggle)|| \ + ((MODE) == TIM_OCMode_PWM1) || \ + ((MODE) == TIM_OCMode_PWM2)) +#define IS_TIM_OCM(MODE) (((MODE) == TIM_OCMode_Timing) || \ + ((MODE) == TIM_OCMode_Active) || \ + ((MODE) == TIM_OCMode_Inactive) || \ + ((MODE) == TIM_OCMode_Toggle)|| \ + ((MODE) == TIM_OCMode_PWM1) || \ + ((MODE) == TIM_OCMode_PWM2) || \ + ((MODE) == TIM_ForcedAction_Active) || \ + ((MODE) == TIM_ForcedAction_InActive)) +/** + * @} + */ + +/** @defgroup TIM_One_Pulse_Mode + * @{ + */ + +#define TIM_OPMode_Single ((uint16_t)0x0008) +#define TIM_OPMode_Repetitive ((uint16_t)0x0000) +#define IS_TIM_OPM_MODE(MODE) (((MODE) == TIM_OPMode_Single) || \ + ((MODE) == TIM_OPMode_Repetitive)) +/** + * @} + */ + +/** @defgroup TIM_Channel + * @{ + */ + +#define TIM_Channel_1 ((uint16_t)0x0000) +#define TIM_Channel_2 ((uint16_t)0x0004) +#define TIM_Channel_3 ((uint16_t)0x0008) +#define TIM_Channel_4 ((uint16_t)0x000C) +#define IS_TIM_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ + ((CHANNEL) == TIM_Channel_2) || \ + ((CHANNEL) == TIM_Channel_3) || \ + ((CHANNEL) == TIM_Channel_4)) +#define IS_TIM_PWMI_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ + ((CHANNEL) == TIM_Channel_2)) +#define IS_TIM_COMPLEMENTARY_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ + ((CHANNEL) == TIM_Channel_2) || \ + ((CHANNEL) == TIM_Channel_3)) +/** + * @} + */ + +/** @defgroup TIM_Clock_Division_CKD + * @{ + */ + +#define TIM_CKD_DIV1 ((uint16_t)0x0000) +#define TIM_CKD_DIV2 ((uint16_t)0x0100) +#define TIM_CKD_DIV4 ((uint16_t)0x0200) +#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \ + ((DIV) == TIM_CKD_DIV2) || \ + ((DIV) == TIM_CKD_DIV4)) +/** + * @} + */ + +/** @defgroup TIM_Counter_Mode + * @{ + */ + +#define TIM_CounterMode_Up ((uint16_t)0x0000) +#define TIM_CounterMode_Down ((uint16_t)0x0010) +#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020) +#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040) +#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060) +#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) || \ + ((MODE) == TIM_CounterMode_Down) || \ + ((MODE) == TIM_CounterMode_CenterAligned1) || \ + ((MODE) == TIM_CounterMode_CenterAligned2) || \ + ((MODE) == TIM_CounterMode_CenterAligned3)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Polarity + * @{ + */ + +#define TIM_OCPolarity_High ((uint16_t)0x0000) +#define TIM_OCPolarity_Low ((uint16_t)0x0002) +#define IS_TIM_OC_POLARITY(POLARITY) (((POLARITY) == TIM_OCPolarity_High) || \ + ((POLARITY) == TIM_OCPolarity_Low)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Polarity + * @{ + */ + +#define TIM_OCNPolarity_High ((uint16_t)0x0000) +#define TIM_OCNPolarity_Low ((uint16_t)0x0008) +#define IS_TIM_OCN_POLARITY(POLARITY) (((POLARITY) == TIM_OCNPolarity_High) || \ + ((POLARITY) == TIM_OCNPolarity_Low)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_state + * @{ + */ + +#define TIM_OutputState_Disable ((uint16_t)0x0000) +#define TIM_OutputState_Enable ((uint16_t)0x0001) +#define IS_TIM_OUTPUT_STATE(STATE) (((STATE) == TIM_OutputState_Disable) || \ + ((STATE) == TIM_OutputState_Enable)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_state + * @{ + */ + +#define TIM_OutputNState_Disable ((uint16_t)0x0000) +#define TIM_OutputNState_Enable ((uint16_t)0x0004) +#define IS_TIM_OUTPUTN_STATE(STATE) (((STATE) == TIM_OutputNState_Disable) || \ + ((STATE) == TIM_OutputNState_Enable)) +/** + * @} + */ + +/** @defgroup TIM_Capture_Compare_state + * @{ + */ + +#define TIM_CCx_Enable ((uint16_t)0x0001) +#define TIM_CCx_Disable ((uint16_t)0x0000) +#define IS_TIM_CCX(CCX) (((CCX) == TIM_CCx_Enable) || \ + ((CCX) == TIM_CCx_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Capture_Compare_N_state + * @{ + */ + +#define TIM_CCxN_Enable ((uint16_t)0x0004) +#define TIM_CCxN_Disable ((uint16_t)0x0000) +#define IS_TIM_CCXN(CCXN) (((CCXN) == TIM_CCxN_Enable) || \ + ((CCXN) == TIM_CCxN_Disable)) +/** + * @} + */ + +/** @defgroup Break_Input_enable_disable + * @{ + */ + +#define TIM_Break_Enable ((uint16_t)0x1000) +#define TIM_Break_Disable ((uint16_t)0x0000) +#define IS_TIM_BREAK_STATE(STATE) (((STATE) == TIM_Break_Enable) || \ + ((STATE) == TIM_Break_Disable)) +/** + * @} + */ + +/** @defgroup Break_Polarity + * @{ + */ + +#define TIM_BreakPolarity_Low ((uint16_t)0x0000) +#define TIM_BreakPolarity_High ((uint16_t)0x2000) +#define IS_TIM_BREAK_POLARITY(POLARITY) (((POLARITY) == TIM_BreakPolarity_Low) || \ + ((POLARITY) == TIM_BreakPolarity_High)) +/** + * @} + */ + +/** @defgroup TIM_AOE_Bit_Set_Reset + * @{ + */ + +#define TIM_AutomaticOutput_Enable ((uint16_t)0x4000) +#define TIM_AutomaticOutput_Disable ((uint16_t)0x0000) +#define IS_TIM_AUTOMATIC_OUTPUT_STATE(STATE) (((STATE) == TIM_AutomaticOutput_Enable) || \ + ((STATE) == TIM_AutomaticOutput_Disable)) +/** + * @} + */ + +/** @defgroup Lock_level + * @{ + */ + +#define TIM_LOCKLevel_OFF ((uint16_t)0x0000) +#define TIM_LOCKLevel_1 ((uint16_t)0x0100) +#define TIM_LOCKLevel_2 ((uint16_t)0x0200) +#define TIM_LOCKLevel_3 ((uint16_t)0x0300) +#define IS_TIM_LOCK_LEVEL(LEVEL) (((LEVEL) == TIM_LOCKLevel_OFF) || \ + ((LEVEL) == TIM_LOCKLevel_1) || \ + ((LEVEL) == TIM_LOCKLevel_2) || \ + ((LEVEL) == TIM_LOCKLevel_3)) +/** + * @} + */ + +/** @defgroup OSSI_Off_State_Selection_for_Idle_mode_state + * @{ + */ + +#define TIM_OSSIState_Enable ((uint16_t)0x0400) +#define TIM_OSSIState_Disable ((uint16_t)0x0000) +#define IS_TIM_OSSI_STATE(STATE) (((STATE) == TIM_OSSIState_Enable) || \ + ((STATE) == TIM_OSSIState_Disable)) +/** + * @} + */ + +/** @defgroup OSSR_Off_State_Selection_for_Run_mode_state + * @{ + */ + +#define TIM_OSSRState_Enable ((uint16_t)0x0800) +#define TIM_OSSRState_Disable ((uint16_t)0x0000) +#define IS_TIM_OSSR_STATE(STATE) (((STATE) == TIM_OSSRState_Enable) || \ + ((STATE) == TIM_OSSRState_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Idle_State + * @{ + */ + +#define TIM_OCIdleState_Set ((uint16_t)0x0100) +#define TIM_OCIdleState_Reset ((uint16_t)0x0000) +#define IS_TIM_OCIDLE_STATE(STATE) (((STATE) == TIM_OCIdleState_Set) || \ + ((STATE) == TIM_OCIdleState_Reset)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Idle_State + * @{ + */ + +#define TIM_OCNIdleState_Set ((uint16_t)0x0200) +#define TIM_OCNIdleState_Reset ((uint16_t)0x0000) +#define IS_TIM_OCNIDLE_STATE(STATE) (((STATE) == TIM_OCNIdleState_Set) || \ + ((STATE) == TIM_OCNIdleState_Reset)) +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Polarity + * @{ + */ + +#define TIM_ICPolarity_Rising ((uint16_t)0x0000) +#define TIM_ICPolarity_Falling ((uint16_t)0x0002) +#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \ + ((POLARITY) == TIM_ICPolarity_Falling)) +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Selection + * @{ + */ + +#define TIM_ICSelection_DirectTI ((uint16_t)0x0001) /*!< TIM Input 1, 2, 3 or 4 is selected to be + connected to IC1, IC2, IC3 or IC4, respectively */ +#define TIM_ICSelection_IndirectTI ((uint16_t)0x0002) /*!< TIM Input 1, 2, 3 or 4 is selected to be + connected to IC2, IC1, IC4 or IC3, respectively. */ +#define TIM_ICSelection_TRC ((uint16_t)0x0003) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC. */ +#define IS_TIM_IC_SELECTION(SELECTION) (((SELECTION) == TIM_ICSelection_DirectTI) || \ + ((SELECTION) == TIM_ICSelection_IndirectTI) || \ + ((SELECTION) == TIM_ICSelection_TRC)) +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Prescaler + * @{ + */ + +#define TIM_ICPSC_DIV1 ((uint16_t)0x0000) /*!< Capture performed each time an edge is detected on the capture input. */ +#define TIM_ICPSC_DIV2 ((uint16_t)0x0004) /*!< Capture performed once every 2 events. */ +#define TIM_ICPSC_DIV4 ((uint16_t)0x0008) /*!< Capture performed once every 4 events. */ +#define TIM_ICPSC_DIV8 ((uint16_t)0x000C) /*!< Capture performed once every 8 events. */ +#define IS_TIM_IC_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ICPSC_DIV1) || \ + ((PRESCALER) == TIM_ICPSC_DIV2) || \ + ((PRESCALER) == TIM_ICPSC_DIV4) || \ + ((PRESCALER) == TIM_ICPSC_DIV8)) +/** + * @} + */ + +/** @defgroup TIM_interrupt_sources + * @{ + */ + +#define TIM_IT_Update ((uint16_t)0x0001) +#define TIM_IT_CC1 ((uint16_t)0x0002) +#define TIM_IT_CC2 ((uint16_t)0x0004) +#define TIM_IT_CC3 ((uint16_t)0x0008) +#define TIM_IT_CC4 ((uint16_t)0x0010) +#define TIM_IT_COM ((uint16_t)0x0020) +#define TIM_IT_Trigger ((uint16_t)0x0040) +#define TIM_IT_Break ((uint16_t)0x0080) +#define IS_TIM_IT(IT) ((((IT) & (uint16_t)0xFF00) == 0x0000) && ((IT) != 0x0000)) + +#define IS_TIM_GET_IT(IT) (((IT) == TIM_IT_Update) || \ + ((IT) == TIM_IT_CC1) || \ + ((IT) == TIM_IT_CC2) || \ + ((IT) == TIM_IT_CC3) || \ + ((IT) == TIM_IT_CC4) || \ + ((IT) == TIM_IT_COM) || \ + ((IT) == TIM_IT_Trigger) || \ + ((IT) == TIM_IT_Break)) +/** + * @} + */ + +/** @defgroup TIM_DMA_Base_address + * @{ + */ + +#define TIM_DMABase_CR1 ((uint16_t)0x0000) +#define TIM_DMABase_CR2 ((uint16_t)0x0001) +#define TIM_DMABase_SMCR ((uint16_t)0x0002) +#define TIM_DMABase_DIER ((uint16_t)0x0003) +#define TIM_DMABase_SR ((uint16_t)0x0004) +#define TIM_DMABase_EGR ((uint16_t)0x0005) +#define TIM_DMABase_CCMR1 ((uint16_t)0x0006) +#define TIM_DMABase_CCMR2 ((uint16_t)0x0007) +#define TIM_DMABase_CCER ((uint16_t)0x0008) +#define TIM_DMABase_CNT ((uint16_t)0x0009) +#define TIM_DMABase_PSC ((uint16_t)0x000A) +#define TIM_DMABase_ARR ((uint16_t)0x000B) +#define TIM_DMABase_RCR ((uint16_t)0x000C) +#define TIM_DMABase_CCR1 ((uint16_t)0x000D) +#define TIM_DMABase_CCR2 ((uint16_t)0x000E) +#define TIM_DMABase_CCR3 ((uint16_t)0x000F) +#define TIM_DMABase_CCR4 ((uint16_t)0x0010) +#define TIM_DMABase_BDTR ((uint16_t)0x0011) +#define TIM_DMABase_DCR ((uint16_t)0x0012) +#define IS_TIM_DMA_BASE(BASE) (((BASE) == TIM_DMABase_CR1) || \ + ((BASE) == TIM_DMABase_CR2) || \ + ((BASE) == TIM_DMABase_SMCR) || \ + ((BASE) == TIM_DMABase_DIER) || \ + ((BASE) == TIM_DMABase_SR) || \ + ((BASE) == TIM_DMABase_EGR) || \ + ((BASE) == TIM_DMABase_CCMR1) || \ + ((BASE) == TIM_DMABase_CCMR2) || \ + ((BASE) == TIM_DMABase_CCER) || \ + ((BASE) == TIM_DMABase_CNT) || \ + ((BASE) == TIM_DMABase_PSC) || \ + ((BASE) == TIM_DMABase_ARR) || \ + ((BASE) == TIM_DMABase_RCR) || \ + ((BASE) == TIM_DMABase_CCR1) || \ + ((BASE) == TIM_DMABase_CCR2) || \ + ((BASE) == TIM_DMABase_CCR3) || \ + ((BASE) == TIM_DMABase_CCR4) || \ + ((BASE) == TIM_DMABase_BDTR) || \ + ((BASE) == TIM_DMABase_DCR)) +/** + * @} + */ + +/** @defgroup TIM_DMA_Burst_Length + * @{ + */ + +#define TIM_DMABurstLength_1Byte ((uint16_t)0x0000) +#define TIM_DMABurstLength_2Bytes ((uint16_t)0x0100) +#define TIM_DMABurstLength_3Bytes ((uint16_t)0x0200) +#define TIM_DMABurstLength_4Bytes ((uint16_t)0x0300) +#define TIM_DMABurstLength_5Bytes ((uint16_t)0x0400) +#define TIM_DMABurstLength_6Bytes ((uint16_t)0x0500) +#define TIM_DMABurstLength_7Bytes ((uint16_t)0x0600) +#define TIM_DMABurstLength_8Bytes ((uint16_t)0x0700) +#define TIM_DMABurstLength_9Bytes ((uint16_t)0x0800) +#define TIM_DMABurstLength_10Bytes ((uint16_t)0x0900) +#define TIM_DMABurstLength_11Bytes ((uint16_t)0x0A00) +#define TIM_DMABurstLength_12Bytes ((uint16_t)0x0B00) +#define TIM_DMABurstLength_13Bytes ((uint16_t)0x0C00) +#define TIM_DMABurstLength_14Bytes ((uint16_t)0x0D00) +#define TIM_DMABurstLength_15Bytes ((uint16_t)0x0E00) +#define TIM_DMABurstLength_16Bytes ((uint16_t)0x0F00) +#define TIM_DMABurstLength_17Bytes ((uint16_t)0x1000) +#define TIM_DMABurstLength_18Bytes ((uint16_t)0x1100) +#define IS_TIM_DMA_LENGTH(LENGTH) (((LENGTH) == TIM_DMABurstLength_1Byte) || \ + ((LENGTH) == TIM_DMABurstLength_2Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_3Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_4Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_5Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_6Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_7Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_8Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_9Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_10Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_11Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_12Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_13Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_14Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_15Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_16Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_17Bytes) || \ + ((LENGTH) == TIM_DMABurstLength_18Bytes)) +/** + * @} + */ + +/** @defgroup TIM_DMA_sources + * @{ + */ + +#define TIM_DMA_Update ((uint16_t)0x0100) +#define TIM_DMA_CC1 ((uint16_t)0x0200) +#define TIM_DMA_CC2 ((uint16_t)0x0400) +#define TIM_DMA_CC3 ((uint16_t)0x0800) +#define TIM_DMA_CC4 ((uint16_t)0x1000) +#define TIM_DMA_COM ((uint16_t)0x2000) +#define TIM_DMA_Trigger ((uint16_t)0x4000) +#define IS_TIM_DMA_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0x80FF) == 0x0000) && ((SOURCE) != 0x0000)) + +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Prescaler + * @{ + */ + +#define TIM_ExtTRGPSC_OFF ((uint16_t)0x0000) +#define TIM_ExtTRGPSC_DIV2 ((uint16_t)0x1000) +#define TIM_ExtTRGPSC_DIV4 ((uint16_t)0x2000) +#define TIM_ExtTRGPSC_DIV8 ((uint16_t)0x3000) +#define IS_TIM_EXT_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ExtTRGPSC_OFF) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV2) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV4) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV8)) +/** + * @} + */ + +/** @defgroup TIM_Internal_Trigger_Selection + * @{ + */ + +#define TIM_TS_ITR0 ((uint16_t)0x0000) +#define TIM_TS_ITR1 ((uint16_t)0x0010) +#define TIM_TS_ITR2 ((uint16_t)0x0020) +#define TIM_TS_ITR3 ((uint16_t)0x0030) +#define TIM_TS_TI1F_ED ((uint16_t)0x0040) +#define TIM_TS_TI1FP1 ((uint16_t)0x0050) +#define TIM_TS_TI2FP2 ((uint16_t)0x0060) +#define TIM_TS_ETRF ((uint16_t)0x0070) +#define IS_TIM_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ + ((SELECTION) == TIM_TS_ITR1) || \ + ((SELECTION) == TIM_TS_ITR2) || \ + ((SELECTION) == TIM_TS_ITR3) || \ + ((SELECTION) == TIM_TS_TI1F_ED) || \ + ((SELECTION) == TIM_TS_TI1FP1) || \ + ((SELECTION) == TIM_TS_TI2FP2) || \ + ((SELECTION) == TIM_TS_ETRF)) +#define IS_TIM_INTERNAL_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ + ((SELECTION) == TIM_TS_ITR1) || \ + ((SELECTION) == TIM_TS_ITR2) || \ + ((SELECTION) == TIM_TS_ITR3)) +/** + * @} + */ + +/** @defgroup TIM_TIx_External_Clock_Source + * @{ + */ + +#define TIM_TIxExternalCLK1Source_TI1 ((uint16_t)0x0050) +#define TIM_TIxExternalCLK1Source_TI2 ((uint16_t)0x0060) +#define TIM_TIxExternalCLK1Source_TI1ED ((uint16_t)0x0040) +#define IS_TIM_TIXCLK_SOURCE(SOURCE) (((SOURCE) == TIM_TIxExternalCLK1Source_TI1) || \ + ((SOURCE) == TIM_TIxExternalCLK1Source_TI2) || \ + ((SOURCE) == TIM_TIxExternalCLK1Source_TI1ED)) +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Polarity + * @{ + */ +#define TIM_ExtTRGPolarity_Inverted ((uint16_t)0x8000) +#define TIM_ExtTRGPolarity_NonInverted ((uint16_t)0x0000) +#define IS_TIM_EXT_POLARITY(POLARITY) (((POLARITY) == TIM_ExtTRGPolarity_Inverted) || \ + ((POLARITY) == TIM_ExtTRGPolarity_NonInverted)) +/** + * @} + */ + +/** @defgroup TIM_Prescaler_Reload_Mode + * @{ + */ + +#define TIM_PSCReloadMode_Update ((uint16_t)0x0000) +#define TIM_PSCReloadMode_Immediate ((uint16_t)0x0001) +#define IS_TIM_PRESCALER_RELOAD(RELOAD) (((RELOAD) == TIM_PSCReloadMode_Update) || \ + ((RELOAD) == TIM_PSCReloadMode_Immediate)) +/** + * @} + */ + +/** @defgroup TIM_Forced_Action + * @{ + */ + +#define TIM_ForcedAction_Active ((uint16_t)0x0050) +#define TIM_ForcedAction_InActive ((uint16_t)0x0040) +#define IS_TIM_FORCED_ACTION(ACTION) (((ACTION) == TIM_ForcedAction_Active) || \ + ((ACTION) == TIM_ForcedAction_InActive)) +/** + * @} + */ + +/** @defgroup TIM_Encoder_Mode + * @{ + */ + +#define TIM_EncoderMode_TI1 ((uint16_t)0x0001) +#define TIM_EncoderMode_TI2 ((uint16_t)0x0002) +#define TIM_EncoderMode_TI12 ((uint16_t)0x0003) +#define IS_TIM_ENCODER_MODE(MODE) (((MODE) == TIM_EncoderMode_TI1) || \ + ((MODE) == TIM_EncoderMode_TI2) || \ + ((MODE) == TIM_EncoderMode_TI12)) +/** + * @} + */ + + +/** @defgroup TIM_Event_Source + * @{ + */ + +#define TIM_EventSource_Update ((uint16_t)0x0001) +#define TIM_EventSource_CC1 ((uint16_t)0x0002) +#define TIM_EventSource_CC2 ((uint16_t)0x0004) +#define TIM_EventSource_CC3 ((uint16_t)0x0008) +#define TIM_EventSource_CC4 ((uint16_t)0x0010) +#define TIM_EventSource_COM ((uint16_t)0x0020) +#define TIM_EventSource_Trigger ((uint16_t)0x0040) +#define TIM_EventSource_Break ((uint16_t)0x0080) +#define IS_TIM_EVENT_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0xFF00) == 0x0000) && ((SOURCE) != 0x0000)) + +/** + * @} + */ + +/** @defgroup TIM_Update_Source + * @{ + */ + +#define TIM_UpdateSource_Global ((uint16_t)0x0000) /*!< Source of update is the counter overflow/underflow + or the setting of UG bit, or an update generation + through the slave mode controller. */ +#define TIM_UpdateSource_Regular ((uint16_t)0x0001) /*!< Source of update is counter overflow/underflow. */ +#define IS_TIM_UPDATE_SOURCE(SOURCE) (((SOURCE) == TIM_UpdateSource_Global) || \ + ((SOURCE) == TIM_UpdateSource_Regular)) +/** + * @} + */ + +/** @defgroup TIM_Ouput_Compare_Preload_State + * @{ + */ + +#define TIM_OCPreload_Enable ((uint16_t)0x0008) +#define TIM_OCPreload_Disable ((uint16_t)0x0000) +#define IS_TIM_OCPRELOAD_STATE(STATE) (((STATE) == TIM_OCPreload_Enable) || \ + ((STATE) == TIM_OCPreload_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Ouput_Compare_Fast_State + * @{ + */ + +#define TIM_OCFast_Enable ((uint16_t)0x0004) +#define TIM_OCFast_Disable ((uint16_t)0x0000) +#define IS_TIM_OCFAST_STATE(STATE) (((STATE) == TIM_OCFast_Enable) || \ + ((STATE) == TIM_OCFast_Disable)) + +/** + * @} + */ + +/** @defgroup TIM_Ouput_Compare_Clear_State + * @{ + */ + +#define TIM_OCClear_Enable ((uint16_t)0x0080) +#define TIM_OCClear_Disable ((uint16_t)0x0000) +#define IS_TIM_OCCLEAR_STATE(STATE) (((STATE) == TIM_OCClear_Enable) || \ + ((STATE) == TIM_OCClear_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Trigger_Output_Source + * @{ + */ + +#define TIM_TRGOSource_Reset ((uint16_t)0x0000) +#define TIM_TRGOSource_Enable ((uint16_t)0x0010) +#define TIM_TRGOSource_Update ((uint16_t)0x0020) +#define TIM_TRGOSource_OC1 ((uint16_t)0x0030) +#define TIM_TRGOSource_OC1Ref ((uint16_t)0x0040) +#define TIM_TRGOSource_OC2Ref ((uint16_t)0x0050) +#define TIM_TRGOSource_OC3Ref ((uint16_t)0x0060) +#define TIM_TRGOSource_OC4Ref ((uint16_t)0x0070) +#define IS_TIM_TRGO_SOURCE(SOURCE) (((SOURCE) == TIM_TRGOSource_Reset) || \ + ((SOURCE) == TIM_TRGOSource_Enable) || \ + ((SOURCE) == TIM_TRGOSource_Update) || \ + ((SOURCE) == TIM_TRGOSource_OC1) || \ + ((SOURCE) == TIM_TRGOSource_OC1Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC2Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC3Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC4Ref)) +/** + * @} + */ + +/** @defgroup TIM_Slave_Mode + * @{ + */ + +#define TIM_SlaveMode_Reset ((uint16_t)0x0004) +#define TIM_SlaveMode_Gated ((uint16_t)0x0005) +#define TIM_SlaveMode_Trigger ((uint16_t)0x0006) +#define TIM_SlaveMode_External1 ((uint16_t)0x0007) +#define IS_TIM_SLAVE_MODE(MODE) (((MODE) == TIM_SlaveMode_Reset) || \ + ((MODE) == TIM_SlaveMode_Gated) || \ + ((MODE) == TIM_SlaveMode_Trigger) || \ + ((MODE) == TIM_SlaveMode_External1)) +/** + * @} + */ + +/** @defgroup TIM_Master_Slave_Mode + * @{ + */ + +#define TIM_MasterSlaveMode_Enable ((uint16_t)0x0080) +#define TIM_MasterSlaveMode_Disable ((uint16_t)0x0000) +#define IS_TIM_MSM_STATE(STATE) (((STATE) == TIM_MasterSlaveMode_Enable) || \ + ((STATE) == TIM_MasterSlaveMode_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Flags + * @{ + */ + +#define TIM_FLAG_Update ((uint16_t)0x0001) +#define TIM_FLAG_CC1 ((uint16_t)0x0002) +#define TIM_FLAG_CC2 ((uint16_t)0x0004) +#define TIM_FLAG_CC3 ((uint16_t)0x0008) +#define TIM_FLAG_CC4 ((uint16_t)0x0010) +#define TIM_FLAG_COM ((uint16_t)0x0020) +#define TIM_FLAG_Trigger ((uint16_t)0x0040) +#define TIM_FLAG_Break ((uint16_t)0x0080) +#define TIM_FLAG_CC1OF ((uint16_t)0x0200) +#define TIM_FLAG_CC2OF ((uint16_t)0x0400) +#define TIM_FLAG_CC3OF ((uint16_t)0x0800) +#define TIM_FLAG_CC4OF ((uint16_t)0x1000) +#define IS_TIM_GET_FLAG(FLAG) (((FLAG) == TIM_FLAG_Update) || \ + ((FLAG) == TIM_FLAG_CC1) || \ + ((FLAG) == TIM_FLAG_CC2) || \ + ((FLAG) == TIM_FLAG_CC3) || \ + ((FLAG) == TIM_FLAG_CC4) || \ + ((FLAG) == TIM_FLAG_COM) || \ + ((FLAG) == TIM_FLAG_Trigger) || \ + ((FLAG) == TIM_FLAG_Break) || \ + ((FLAG) == TIM_FLAG_CC1OF) || \ + ((FLAG) == TIM_FLAG_CC2OF) || \ + ((FLAG) == TIM_FLAG_CC3OF) || \ + ((FLAG) == TIM_FLAG_CC4OF)) + + +#define IS_TIM_CLEAR_FLAG(TIM_FLAG) ((((TIM_FLAG) & (uint16_t)0xE100) == 0x0000) && ((TIM_FLAG) != 0x0000)) +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Filer_Value + * @{ + */ + +#define IS_TIM_IC_FILTER(ICFILTER) ((ICFILTER) <= 0xF) +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Filter + * @{ + */ + +#define IS_TIM_EXT_FILTER(EXTFILTER) ((EXTFILTER) <= 0xF) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup TIM_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions + * @{ + */ + +void TIM_DeInit(TIM_TypeDef* TIMx); +void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); +void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); +void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); +void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct); +void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); +void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct); +void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct); +void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState); +void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource); +void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength); +void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState); +void TIM_InternalClockConfig(TIM_TypeDef* TIMx); +void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); +void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, + uint16_t TIM_ICPolarity, uint16_t ICFilter); +void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter); +void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, + uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); +void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter); +void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode); +void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode); +void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); +void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, + uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity); +void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); +void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); +void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); +void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx); +void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN); +void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode); +void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource); +void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode); +void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource); +void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); +void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode); +void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter); +void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload); +void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1); +void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2); +void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3); +void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4); +void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); +void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); +void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); +void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); +void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD); +uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx); +uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx); +uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx); +uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx); +uint16_t TIM_GetCounter(TIM_TypeDef* TIMx); +uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx); +FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); +void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); +ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT); +void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F10x_TIM_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_usart.h b/example/libs_stm/inc/stm32f10x/stm32f10x_usart.h new file mode 100644 index 000000000..b79855a1d --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_usart.h @@ -0,0 +1,411 @@ +/** + ****************************************************************************** + * @file stm32f10x_usart.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the USART + * firmware library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_USART_H +#define __STM32F10x_USART_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup USART + * @{ + */ + +/** @defgroup USART_Exported_Types + * @{ + */ + +/** + * @brief USART Init Structure definition + */ + +typedef struct +{ + uint32_t USART_BaudRate; /*!< This member configures the USART communication baud rate. + The baud rate is computed using the following formula: + - IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate))) + - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */ + + uint16_t USART_WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref USART_Word_Length */ + + uint16_t USART_StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref USART_Stop_Bits */ + + uint16_t USART_Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref USART_Parity + @note When parity is enabled, the computed parity is inserted + at the MSB position of the transmitted data (9th bit when + the word length is set to 9 data bits; 8th bit when the + word length is set to 8 data bits). */ + + uint16_t USART_Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref USART_Mode */ + + uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled + or disabled. + This parameter can be a value of @ref USART_Hardware_Flow_Control */ +} USART_InitTypeDef; + +/** + * @brief USART Clock Init Structure definition + */ + +typedef struct +{ + + uint16_t USART_Clock; /*!< Specifies whether the USART clock is enabled or disabled. + This parameter can be a value of @ref USART_Clock */ + + uint16_t USART_CPOL; /*!< Specifies the steady state value of the serial clock. + This parameter can be a value of @ref USART_Clock_Polarity */ + + uint16_t USART_CPHA; /*!< Specifies the clock transition on which the bit capture is made. + This parameter can be a value of @ref USART_Clock_Phase */ + + uint16_t USART_LastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted + data bit (MSB) has to be output on the SCLK pin in synchronous mode. + This parameter can be a value of @ref USART_Last_Bit */ +} USART_ClockInitTypeDef; + +/** + * @} + */ + +/** @defgroup USART_Exported_Constants + * @{ + */ + +#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \ + ((PERIPH) == USART2) || \ + ((PERIPH) == USART3) || \ + ((PERIPH) == UART4) || \ + ((PERIPH) == UART5)) + +#define IS_USART_123_PERIPH(PERIPH) (((PERIPH) == USART1) || \ + ((PERIPH) == USART2) || \ + ((PERIPH) == USART3)) + +#define IS_USART_1234_PERIPH(PERIPH) (((PERIPH) == USART1) || \ + ((PERIPH) == USART2) || \ + ((PERIPH) == USART3) || \ + ((PERIPH) == UART4)) +/** @defgroup USART_Word_Length + * @{ + */ + +#define USART_WordLength_8b ((uint16_t)0x0000) +#define USART_WordLength_9b ((uint16_t)0x1000) + +#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WordLength_8b) || \ + ((LENGTH) == USART_WordLength_9b)) +/** + * @} + */ + +/** @defgroup USART_Stop_Bits + * @{ + */ + +#define USART_StopBits_1 ((uint16_t)0x0000) +#define USART_StopBits_0_5 ((uint16_t)0x1000) +#define USART_StopBits_2 ((uint16_t)0x2000) +#define USART_StopBits_1_5 ((uint16_t)0x3000) +#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_StopBits_1) || \ + ((STOPBITS) == USART_StopBits_0_5) || \ + ((STOPBITS) == USART_StopBits_2) || \ + ((STOPBITS) == USART_StopBits_1_5)) +/** + * @} + */ + +/** @defgroup USART_Parity + * @{ + */ + +#define USART_Parity_No ((uint16_t)0x0000) +#define USART_Parity_Even ((uint16_t)0x0400) +#define USART_Parity_Odd ((uint16_t)0x0600) +#define IS_USART_PARITY(PARITY) (((PARITY) == USART_Parity_No) || \ + ((PARITY) == USART_Parity_Even) || \ + ((PARITY) == USART_Parity_Odd)) +/** + * @} + */ + +/** @defgroup USART_Mode + * @{ + */ + +#define USART_Mode_Rx ((uint16_t)0x0004) +#define USART_Mode_Tx ((uint16_t)0x0008) +#define IS_USART_MODE(MODE) ((((MODE) & (uint16_t)0xFFF3) == 0x00) && ((MODE) != (uint16_t)0x00)) +/** + * @} + */ + +/** @defgroup USART_Hardware_Flow_Control + * @{ + */ +#define USART_HardwareFlowControl_None ((uint16_t)0x0000) +#define USART_HardwareFlowControl_RTS ((uint16_t)0x0100) +#define USART_HardwareFlowControl_CTS ((uint16_t)0x0200) +#define USART_HardwareFlowControl_RTS_CTS ((uint16_t)0x0300) +#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)\ + (((CONTROL) == USART_HardwareFlowControl_None) || \ + ((CONTROL) == USART_HardwareFlowControl_RTS) || \ + ((CONTROL) == USART_HardwareFlowControl_CTS) || \ + ((CONTROL) == USART_HardwareFlowControl_RTS_CTS)) +/** + * @} + */ + +/** @defgroup USART_Clock + * @{ + */ +#define USART_Clock_Disable ((uint16_t)0x0000) +#define USART_Clock_Enable ((uint16_t)0x0800) +#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_Clock_Disable) || \ + ((CLOCK) == USART_Clock_Enable)) +/** + * @} + */ + +/** @defgroup USART_Clock_Polarity + * @{ + */ + +#define USART_CPOL_Low ((uint16_t)0x0000) +#define USART_CPOL_High ((uint16_t)0x0400) +#define IS_USART_CPOL(CPOL) (((CPOL) == USART_CPOL_Low) || ((CPOL) == USART_CPOL_High)) + +/** + * @} + */ + +/** @defgroup USART_Clock_Phase + * @{ + */ + +#define USART_CPHA_1Edge ((uint16_t)0x0000) +#define USART_CPHA_2Edge ((uint16_t)0x0200) +#define IS_USART_CPHA(CPHA) (((CPHA) == USART_CPHA_1Edge) || ((CPHA) == USART_CPHA_2Edge)) + +/** + * @} + */ + +/** @defgroup USART_Last_Bit + * @{ + */ + +#define USART_LastBit_Disable ((uint16_t)0x0000) +#define USART_LastBit_Enable ((uint16_t)0x0100) +#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LastBit_Disable) || \ + ((LASTBIT) == USART_LastBit_Enable)) +/** + * @} + */ + +/** @defgroup USART_Interrupt_definition + * @{ + */ + +#define USART_IT_PE ((uint16_t)0x0028) +#define USART_IT_TXE ((uint16_t)0x0727) +#define USART_IT_TC ((uint16_t)0x0626) +#define USART_IT_RXNE ((uint16_t)0x0525) +#define USART_IT_IDLE ((uint16_t)0x0424) +#define USART_IT_LBD ((uint16_t)0x0846) +#define USART_IT_CTS ((uint16_t)0x096A) +#define USART_IT_ERR ((uint16_t)0x0060) +#define USART_IT_ORE ((uint16_t)0x0360) +#define USART_IT_NE ((uint16_t)0x0260) +#define USART_IT_FE ((uint16_t)0x0160) +#define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ + ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ + ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ + ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR)) +#define IS_USART_GET_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ + ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ + ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ + ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ORE) || \ + ((IT) == USART_IT_NE) || ((IT) == USART_IT_FE)) +#define IS_USART_CLEAR_IT(IT) (((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ + ((IT) == USART_IT_LBD) || ((IT) == USART_IT_CTS)) +/** + * @} + */ + +/** @defgroup USART_DMA_Requests + * @{ + */ + +#define USART_DMAReq_Tx ((uint16_t)0x0080) +#define USART_DMAReq_Rx ((uint16_t)0x0040) +#define IS_USART_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFF3F) == 0x00) && ((DMAREQ) != (uint16_t)0x00)) + +/** + * @} + */ + +/** @defgroup USART_WakeUp_methods + * @{ + */ + +#define USART_WakeUp_IdleLine ((uint16_t)0x0000) +#define USART_WakeUp_AddressMark ((uint16_t)0x0800) +#define IS_USART_WAKEUP(WAKEUP) (((WAKEUP) == USART_WakeUp_IdleLine) || \ + ((WAKEUP) == USART_WakeUp_AddressMark)) +/** + * @} + */ + +/** @defgroup USART_LIN_Break_Detection_Length + * @{ + */ + +#define USART_LINBreakDetectLength_10b ((uint16_t)0x0000) +#define USART_LINBreakDetectLength_11b ((uint16_t)0x0020) +#define IS_USART_LIN_BREAK_DETECT_LENGTH(LENGTH) \ + (((LENGTH) == USART_LINBreakDetectLength_10b) || \ + ((LENGTH) == USART_LINBreakDetectLength_11b)) +/** + * @} + */ + +/** @defgroup USART_IrDA_Low_Power + * @{ + */ + +#define USART_IrDAMode_LowPower ((uint16_t)0x0004) +#define USART_IrDAMode_Normal ((uint16_t)0x0000) +#define IS_USART_IRDA_MODE(MODE) (((MODE) == USART_IrDAMode_LowPower) || \ + ((MODE) == USART_IrDAMode_Normal)) +/** + * @} + */ + +/** @defgroup USART_Flags + * @{ + */ + +#define USART_FLAG_CTS ((uint16_t)0x0200) +#define USART_FLAG_LBD ((uint16_t)0x0100) +#define USART_FLAG_TXE ((uint16_t)0x0080) +#define USART_FLAG_TC ((uint16_t)0x0040) +#define USART_FLAG_RXNE ((uint16_t)0x0020) +#define USART_FLAG_IDLE ((uint16_t)0x0010) +#define USART_FLAG_ORE ((uint16_t)0x0008) +#define USART_FLAG_NE ((uint16_t)0x0004) +#define USART_FLAG_FE ((uint16_t)0x0002) +#define USART_FLAG_PE ((uint16_t)0x0001) +#define IS_USART_FLAG(FLAG) (((FLAG) == USART_FLAG_PE) || ((FLAG) == USART_FLAG_TXE) || \ + ((FLAG) == USART_FLAG_TC) || ((FLAG) == USART_FLAG_RXNE) || \ + ((FLAG) == USART_FLAG_IDLE) || ((FLAG) == USART_FLAG_LBD) || \ + ((FLAG) == USART_FLAG_CTS) || ((FLAG) == USART_FLAG_ORE) || \ + ((FLAG) == USART_FLAG_NE) || ((FLAG) == USART_FLAG_FE)) + +#define IS_USART_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFC9F) == 0x00) && ((FLAG) != (uint16_t)0x00)) +#define IS_USART_PERIPH_FLAG(PERIPH, USART_FLAG) ((((*(uint32_t*)&(PERIPH)) != UART4_BASE) &&\ + ((*(uint32_t*)&(PERIPH)) != UART5_BASE)) \ + || ((USART_FLAG) != USART_FLAG_CTS)) +#define IS_USART_BAUDRATE(BAUDRATE) (((BAUDRATE) > 0) && ((BAUDRATE) < 0x0044AA21)) +#define IS_USART_ADDRESS(ADDRESS) ((ADDRESS) <= 0xF) +#define IS_USART_DATA(DATA) ((DATA) <= 0x1FF) + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup USART_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USART_Exported_Functions + * @{ + */ + +void USART_DeInit(USART_TypeDef* USARTx); +void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct); +void USART_StructInit(USART_InitTypeDef* USART_InitStruct); +void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct); +void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct); +void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState); +void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState); +void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address); +void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp); +void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength); +void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_SendData(USART_TypeDef* USARTx, uint16_t Data); +uint16_t USART_ReceiveData(USART_TypeDef* USARTx); +void USART_SendBreak(USART_TypeDef* USARTx); +void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime); +void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler); +void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState); +void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode); +void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState); +FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); +void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG); +ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT); +void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_USART_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_wwdg.h b/example/libs_stm/inc/stm32f10x/stm32f10x_wwdg.h new file mode 100644 index 000000000..fe238cdb9 --- /dev/null +++ b/example/libs_stm/inc/stm32f10x/stm32f10x_wwdg.h @@ -0,0 +1,114 @@ +/** + ****************************************************************************** + * @file stm32f10x_wwdg.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file contains all the functions prototypes for the WWDG firmware + * library. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_WWDG_H +#define __STM32F10x_WWDG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @addtogroup WWDG + * @{ + */ + +/** @defgroup WWDG_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup WWDG_Exported_Constants + * @{ + */ + +/** @defgroup WWDG_Prescaler + * @{ + */ + +#define WWDG_Prescaler_1 ((uint32_t)0x00000000) +#define WWDG_Prescaler_2 ((uint32_t)0x00000080) +#define WWDG_Prescaler_4 ((uint32_t)0x00000100) +#define WWDG_Prescaler_8 ((uint32_t)0x00000180) +#define IS_WWDG_PRESCALER(PRESCALER) (((PRESCALER) == WWDG_Prescaler_1) || \ + ((PRESCALER) == WWDG_Prescaler_2) || \ + ((PRESCALER) == WWDG_Prescaler_4) || \ + ((PRESCALER) == WWDG_Prescaler_8)) +#define IS_WWDG_WINDOW_VALUE(VALUE) ((VALUE) <= 0x7F) +#define IS_WWDG_COUNTER(COUNTER) (((COUNTER) >= 0x40) && ((COUNTER) <= 0x7F)) + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup WWDG_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup WWDG_Exported_Functions + * @{ + */ + +void WWDG_DeInit(void); +void WWDG_SetPrescaler(uint32_t WWDG_Prescaler); +void WWDG_SetWindowValue(uint8_t WindowValue); +void WWDG_EnableIT(void); +void WWDG_SetCounter(uint8_t Counter); +void WWDG_Enable(uint8_t Counter); +FlagStatus WWDG_GetFlagStatus(void); +void WWDG_ClearFlag(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F10x_WWDG_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/Release_Notes_for_STM32F10x_StdPeriph_Driver.html b/example/libs_stm/src/stm32f10x/Release_Notes_for_STM32F10x_StdPeriph_Driver.html new file mode 100644 index 000000000..018141b98 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/Release_Notes_for_STM32F10x_StdPeriph_Driver.html @@ -0,0 +1,203 @@ + + + + + + +Release Notes for STM32F10x Standard Peripherals Library Drivers + + + + + +
+


+

+
+ + + + + + +
+ + + + + + + + + +
Back to Release page
+

Release +Notes for STM32F10x Standard Peripherals Library Drivers +(StdPeriph_Driver)

+

Copyright 2010 STMicroelectronics

+

+
+

 

+ + + + + + +
+

Contents

+
    +
  1. STM32F10x Standard Peripherals Library +Drivers update History
  2. +
  3. License
  4. +
+ + +

STM32F10x Standard +Peripherals Library Drivers  update History

3.3.0 +- 04/16/2010

+
  1. General
+
  • Add support for STM32F10x XL-density devices.
  • I2C driver: events description and management enhancement.
+
  1. STM32F10x_StdPeriph_Driver
+
  • stm32f10x_dbgmcu.h/.c
    • DBGMCU_Config() function: add new values DBGMCU_TIMx_STOP (x: 9..14) for DBGMCU_Periph parameter.
  • stm32f10x_flash.h/.c: +updated to support Bank2 of XL-density devices (up to 1MByte of Flash +memory). For more details, refer to the description provided within +stm32f10x_flash.c file.
  • stm32f10x_gpio.h/.c
    • GPIO_PinRemapConfig() function: add new values for GPIO_Remap parameter, to support new remap for FSMC_NADV pin and TIM9..11,13,14.
  • stm32f10x_i2c.h/.c: I2C events description and management enhancement.
    • I2C_CheckEvent() +function: updated to check whether the last event contains the +I2C_EVENT  (instead of check whether the last event is equal to +I2C_EVENT)
    • Add +detailed description of I2C events and how to manage them using the +functions provided by this driver. For more information, refer to +stm32f10x_i2c.h and stm32f10x_i2c.c files.
  • stm32f10x_rcc.h/.c: updated to support TIM9..TIM14 APB clock and reset configuration
  • stm32f10x_tim.h/.c: updated to support new Timers TIM9..TIM14.
  • stm32f10x_sdio.h: 
    • SDIO_SetSDIOReadWaitMode() function: correct values of SDIO_ReadWaitMode parameter
      change
        +#define +SDIO_ReadWaitMode_CLK               +  ((uint32_t)0x00000000)
        #define +SDIO_ReadWaitMode_DATA2             +((uint32_t)0x00000001)
      by
        #define +SDIO_ReadWaitMode_CLK               +  ((uint32_t)0x00000001)
        #define +SDIO_ReadWaitMode_DATA2             +((uint32_t)0x00000000)
+

3.2.0 +- 03/01/2010

+
    +
  1. General
  2. +
+
    + +
  • Add support +for STM32 Low-density Value line (STM32F100x4/6) and +Medium-density Value line (STM32F100x8/B) devices.
  • +
  • Almost +peripherals drivers were updated to support Value +line devices features
  • +
  • Drivers limitations fix and enhancements.
  • + +
+
    +
  1. STM32F10x_StdPeriph_Driver
  2. +
+
    +
  • Add new +firmware driver for CEC peripheral: stm32f10x_cec.h and stm32f10x_cec.c
  • +
  • Timers drivers stm32f10x_tim.h/.c: add support for new General Purpose Timers: TIM15, TIM16 and TIM17.
  • +
  • RCC driver: add support for new Value peripherals: HDMI-CEC, TIM15, TIM16 and TIM17.
  • +
  • GPIO driver: add new remap parameters for TIM1, TIM15, TIM16, TIM17 and HDMI-CEC: GPIO_Remap_TIM1_DMA, GPIO_Remap_TIM15, GPIO_Remap_TIM16, GPIO_Remap_TIM17, GPIO_Remap_CEC.
  • +
  • USART +driver: add support for Oversampling by 8 mode and onebit method. 2 +functions has been added: USART_OverSampling8Cmd() and +USART_OneBitMethodCmd().
    +
  • +
  • DAC +driver: add new functions handling the DAC under run feature: +DAC_ITConfig(), DAC_GetFlagStatus(), DAC_ClearFlag(), DAC_GetITStatus() +and DAC_ClearITPendingBit().
  • +
  • DBGMCU driver: add new parameters for TIM15, TIM16 and TIM17: DBGMCU_TIM15_STOP, DBGMCU_TIM16_STOP, DBGMCU_TIM17_STOP.
    +
  • +
  • FLASH +driver: the FLASH_EraseOptionBytes() function updated. This is now just +erasing the option bytes without modifying the RDP status either +enabled or disabled.
  • +
  • PWR +driver: the PWR_EnterSTOPMode() function updated. When woken up from +STOP mode, this function resets again the SLEEPDEEP bit in the +Cortex-M3 System Control register to allow Sleep mode entering.
  • + + +
+

License

+

The +enclosed firmware and all the related documentation are not covered by +a License Agreement, if you need such License you can contact your +local STMicroelectronics office.

+

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.

+

 

+
+
+

For +complete documentation on STM32(CORTEX M3) 32-Bit Microcontrollers +visit www.st.com/STM32

+
+

+
+
+

 

+
+ \ No newline at end of file diff --git a/example/libs_stm/src/stm32f10x/misc.c b/example/libs_stm/src/stm32f10x/misc.c new file mode 100644 index 000000000..b8349fab9 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/misc.c @@ -0,0 +1,223 @@ +/** + ****************************************************************************** + * @file misc.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the miscellaneous firmware functions (add-on + * to CMSIS functions). + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "misc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup MISC + * @brief MISC driver modules + * @{ + */ + +/** @defgroup MISC_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup MISC_Private_Defines + * @{ + */ + +#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) +/** + * @} + */ + +/** @defgroup MISC_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup MISC_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup MISC_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup MISC_Private_Functions + * @{ + */ + +/** + * @brief Configures the priority grouping: pre-emption priority and subpriority. + * @param NVIC_PriorityGroup: specifies the priority grouping bits length. + * This parameter can be one of the following values: + * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority + * 4 bits for subpriority + * @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority + * 3 bits for subpriority + * @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority + * 2 bits for subpriority + * @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority + * 1 bits for subpriority + * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority + * 0 bits for subpriority + * @retval None + */ +void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) +{ + /* Check the parameters */ + assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); + + /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */ + SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; +} + +/** + * @brief Initializes the NVIC peripheral according to the specified + * parameters in the NVIC_InitStruct. + * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains + * the configuration information for the specified NVIC peripheral. + * @retval None + */ +void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) +{ + uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd)); + assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority)); + assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority)); + + if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE) + { + /* Compute the Corresponding IRQ Priority --------------------------------*/ + tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08; + tmppre = (0x4 - tmppriority); + tmpsub = tmpsub >> tmppriority; + + tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; + tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub; + tmppriority = tmppriority << 0x04; + + NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority; + + /* Enable the Selected IRQ Channels --------------------------------------*/ + NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = + (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); + } + else + { + /* Disable the Selected IRQ Channels -------------------------------------*/ + NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = + (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); + } +} + +/** + * @brief Sets the vector table location and Offset. + * @param NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory. + * This parameter can be one of the following values: + * @arg NVIC_VectTab_RAM + * @arg NVIC_VectTab_FLASH + * @param Offset: Vector Table base offset field. This value must be a multiple of 0x100. + * @retval None + */ +void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) +{ + /* Check the parameters */ + assert_param(IS_NVIC_VECTTAB(NVIC_VectTab)); + assert_param(IS_NVIC_OFFSET(Offset)); + + SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80); +} + +/** + * @brief Selects the condition for the system to enter low power mode. + * @param LowPowerMode: Specifies the new mode for the system to enter low power mode. + * This parameter can be one of the following values: + * @arg NVIC_LP_SEVONPEND + * @arg NVIC_LP_SLEEPDEEP + * @arg NVIC_LP_SLEEPONEXIT + * @param NewState: new state of LP condition. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_NVIC_LP(LowPowerMode)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + SCB->SCR |= LowPowerMode; + } + else + { + SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode); + } +} + +/** + * @brief Configures the SysTick clock source. + * @param SysTick_CLKSource: specifies the SysTick clock source. + * This parameter can be one of the following values: + * @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source. + * @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source. + * @retval None + */ +void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) +{ + /* Check the parameters */ + assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); + if (SysTick_CLKSource == SysTick_CLKSource_HCLK) + { + SysTick->CTRL |= SysTick_CLKSource_HCLK; + } + else + { + SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_adc.c b/example/libs_stm/src/stm32f10x/stm32f10x_adc.c new file mode 100644 index 000000000..a027f3304 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_adc.c @@ -0,0 +1,1306 @@ +/** + ****************************************************************************** + * @file stm32f10x_adc.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the ADC firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_adc.h" +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup ADC + * @brief ADC driver modules + * @{ + */ + +/** @defgroup ADC_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup ADC_Private_Defines + * @{ + */ + +/* ADC DISCNUM mask */ +#define CR1_DISCNUM_Reset ((uint32_t)0xFFFF1FFF) + +/* ADC DISCEN mask */ +#define CR1_DISCEN_Set ((uint32_t)0x00000800) +#define CR1_DISCEN_Reset ((uint32_t)0xFFFFF7FF) + +/* ADC JAUTO mask */ +#define CR1_JAUTO_Set ((uint32_t)0x00000400) +#define CR1_JAUTO_Reset ((uint32_t)0xFFFFFBFF) + +/* ADC JDISCEN mask */ +#define CR1_JDISCEN_Set ((uint32_t)0x00001000) +#define CR1_JDISCEN_Reset ((uint32_t)0xFFFFEFFF) + +/* ADC AWDCH mask */ +#define CR1_AWDCH_Reset ((uint32_t)0xFFFFFFE0) + +/* ADC Analog watchdog enable mode mask */ +#define CR1_AWDMode_Reset ((uint32_t)0xFF3FFDFF) + +/* CR1 register Mask */ +#define CR1_CLEAR_Mask ((uint32_t)0xFFF0FEFF) + +/* ADC ADON mask */ +#define CR2_ADON_Set ((uint32_t)0x00000001) +#define CR2_ADON_Reset ((uint32_t)0xFFFFFFFE) + +/* ADC DMA mask */ +#define CR2_DMA_Set ((uint32_t)0x00000100) +#define CR2_DMA_Reset ((uint32_t)0xFFFFFEFF) + +/* ADC RSTCAL mask */ +#define CR2_RSTCAL_Set ((uint32_t)0x00000008) + +/* ADC CAL mask */ +#define CR2_CAL_Set ((uint32_t)0x00000004) + +/* ADC SWSTART mask */ +#define CR2_SWSTART_Set ((uint32_t)0x00400000) + +/* ADC EXTTRIG mask */ +#define CR2_EXTTRIG_Set ((uint32_t)0x00100000) +#define CR2_EXTTRIG_Reset ((uint32_t)0xFFEFFFFF) + +/* ADC Software start mask */ +#define CR2_EXTTRIG_SWSTART_Set ((uint32_t)0x00500000) +#define CR2_EXTTRIG_SWSTART_Reset ((uint32_t)0xFFAFFFFF) + +/* ADC JEXTSEL mask */ +#define CR2_JEXTSEL_Reset ((uint32_t)0xFFFF8FFF) + +/* ADC JEXTTRIG mask */ +#define CR2_JEXTTRIG_Set ((uint32_t)0x00008000) +#define CR2_JEXTTRIG_Reset ((uint32_t)0xFFFF7FFF) + +/* ADC JSWSTART mask */ +#define CR2_JSWSTART_Set ((uint32_t)0x00200000) + +/* ADC injected software start mask */ +#define CR2_JEXTTRIG_JSWSTART_Set ((uint32_t)0x00208000) +#define CR2_JEXTTRIG_JSWSTART_Reset ((uint32_t)0xFFDF7FFF) + +/* ADC TSPD mask */ +#define CR2_TSVREFE_Set ((uint32_t)0x00800000) +#define CR2_TSVREFE_Reset ((uint32_t)0xFF7FFFFF) + +/* CR2 register Mask */ +#define CR2_CLEAR_Mask ((uint32_t)0xFFF1F7FD) + +/* ADC SQx mask */ +#define SQR3_SQ_Set ((uint32_t)0x0000001F) +#define SQR2_SQ_Set ((uint32_t)0x0000001F) +#define SQR1_SQ_Set ((uint32_t)0x0000001F) + +/* SQR1 register Mask */ +#define SQR1_CLEAR_Mask ((uint32_t)0xFF0FFFFF) + +/* ADC JSQx mask */ +#define JSQR_JSQ_Set ((uint32_t)0x0000001F) + +/* ADC JL mask */ +#define JSQR_JL_Set ((uint32_t)0x00300000) +#define JSQR_JL_Reset ((uint32_t)0xFFCFFFFF) + +/* ADC SMPx mask */ +#define SMPR1_SMP_Set ((uint32_t)0x00000007) +#define SMPR2_SMP_Set ((uint32_t)0x00000007) + +/* ADC JDRx registers offset */ +#define JDR_Offset ((uint8_t)0x28) + +/* ADC1 DR register base address */ +#define DR_ADDRESS ((uint32_t)0x4001244C) + +/** + * @} + */ + +/** @defgroup ADC_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup ADC_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup ADC_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup ADC_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the ADCx peripheral registers to their default reset values. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @retval None + */ +void ADC_DeInit(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + + if (ADCx == ADC1) + { + /* Enable ADC1 reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, ENABLE); + /* Release ADC1 from reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, DISABLE); + } + else if (ADCx == ADC2) + { + /* Enable ADC2 reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2, ENABLE); + /* Release ADC2 from reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2, DISABLE); + } + else + { + if (ADCx == ADC3) + { + /* Enable ADC3 reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3, ENABLE); + /* Release ADC3 from reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3, DISABLE); + } + } +} + +/** + * @brief Initializes the ADCx peripheral according to the specified parameters + * in the ADC_InitStruct. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains + * the configuration information for the specified ADC peripheral. + * @retval None + */ +void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) +{ + uint32_t tmpreg1 = 0; + uint8_t tmpreg2 = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_MODE(ADC_InitStruct->ADC_Mode)); + assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ScanConvMode)); + assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ContinuousConvMode)); + assert_param(IS_ADC_EXT_TRIG(ADC_InitStruct->ADC_ExternalTrigConv)); + assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign)); + assert_param(IS_ADC_REGULAR_LENGTH(ADC_InitStruct->ADC_NbrOfChannel)); + + /*---------------------------- ADCx CR1 Configuration -----------------*/ + /* Get the ADCx CR1 value */ + tmpreg1 = ADCx->CR1; + /* Clear DUALMOD and SCAN bits */ + tmpreg1 &= CR1_CLEAR_Mask; + /* Configure ADCx: Dual mode and scan conversion mode */ + /* Set DUALMOD bits according to ADC_Mode value */ + /* Set SCAN bit according to ADC_ScanConvMode value */ + tmpreg1 |= (uint32_t)(ADC_InitStruct->ADC_Mode | ((uint32_t)ADC_InitStruct->ADC_ScanConvMode << 8)); + /* Write to ADCx CR1 */ + ADCx->CR1 = tmpreg1; + + /*---------------------------- ADCx CR2 Configuration -----------------*/ + /* Get the ADCx CR2 value */ + tmpreg1 = ADCx->CR2; + /* Clear CONT, ALIGN and EXTSEL bits */ + tmpreg1 &= CR2_CLEAR_Mask; + /* Configure ADCx: external trigger event and continuous conversion mode */ + /* Set ALIGN bit according to ADC_DataAlign value */ + /* Set EXTSEL bits according to ADC_ExternalTrigConv value */ + /* Set CONT bit according to ADC_ContinuousConvMode value */ + tmpreg1 |= (uint32_t)(ADC_InitStruct->ADC_DataAlign | ADC_InitStruct->ADC_ExternalTrigConv | + ((uint32_t)ADC_InitStruct->ADC_ContinuousConvMode << 1)); + /* Write to ADCx CR2 */ + ADCx->CR2 = tmpreg1; + + /*---------------------------- ADCx SQR1 Configuration -----------------*/ + /* Get the ADCx SQR1 value */ + tmpreg1 = ADCx->SQR1; + /* Clear L bits */ + tmpreg1 &= SQR1_CLEAR_Mask; + /* Configure ADCx: regular channel sequence length */ + /* Set L bits according to ADC_NbrOfChannel value */ + tmpreg2 |= (uint8_t) (ADC_InitStruct->ADC_NbrOfChannel - (uint8_t)1); + tmpreg1 |= (uint32_t)tmpreg2 << 20; + /* Write to ADCx SQR1 */ + ADCx->SQR1 = tmpreg1; +} + +/** + * @brief Fills each ADC_InitStruct member with its default value. + * @param ADC_InitStruct : pointer to an ADC_InitTypeDef structure which will be initialized. + * @retval None + */ +void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct) +{ + /* Reset ADC init structure parameters values */ + /* Initialize the ADC_Mode member */ + ADC_InitStruct->ADC_Mode = ADC_Mode_Independent; + /* initialize the ADC_ScanConvMode member */ + ADC_InitStruct->ADC_ScanConvMode = DISABLE; + /* Initialize the ADC_ContinuousConvMode member */ + ADC_InitStruct->ADC_ContinuousConvMode = DISABLE; + /* Initialize the ADC_ExternalTrigConv member */ + ADC_InitStruct->ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; + /* Initialize the ADC_DataAlign member */ + ADC_InitStruct->ADC_DataAlign = ADC_DataAlign_Right; + /* Initialize the ADC_NbrOfChannel member */ + ADC_InitStruct->ADC_NbrOfChannel = 1; +} + +/** + * @brief Enables or disables the specified ADC peripheral. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the ADCx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Set the ADON bit to wake up the ADC from power down mode */ + ADCx->CR2 |= CR2_ADON_Set; + } + else + { + /* Disable the selected ADC peripheral */ + ADCx->CR2 &= CR2_ADON_Reset; + } +} + +/** + * @brief Enables or disables the specified ADC DMA request. + * @param ADCx: where x can be 1 or 3 to select the ADC peripheral. + * Note: ADC2 hasn't a DMA capability. + * @param NewState: new state of the selected ADC DMA transfer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_DMA_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected ADC DMA request */ + ADCx->CR2 |= CR2_DMA_Set; + } + else + { + /* Disable the selected ADC DMA request */ + ADCx->CR2 &= CR2_DMA_Reset; + } +} + +/** + * @brief Enables or disables the specified ADC interrupts. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_IT: specifies the ADC interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg ADC_IT_EOC: End of conversion interrupt mask + * @arg ADC_IT_AWD: Analog watchdog interrupt mask + * @arg ADC_IT_JEOC: End of injected conversion interrupt mask + * @param NewState: new state of the specified ADC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState) +{ + uint8_t itmask = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_ADC_IT(ADC_IT)); + /* Get the ADC IT index */ + itmask = (uint8_t)ADC_IT; + if (NewState != DISABLE) + { + /* Enable the selected ADC interrupts */ + ADCx->CR1 |= itmask; + } + else + { + /* Disable the selected ADC interrupts */ + ADCx->CR1 &= (~(uint32_t)itmask); + } +} + +/** + * @brief Resets the selected ADC calibration registers. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @retval None + */ +void ADC_ResetCalibration(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + /* Resets the selected ADC calibartion registers */ + ADCx->CR2 |= CR2_RSTCAL_Set; +} + +/** + * @brief Gets the selected ADC reset calibration registers status. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @retval The new state of ADC reset calibration registers (SET or RESET). + */ +FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + /* Check the status of RSTCAL bit */ + if ((ADCx->CR2 & CR2_RSTCAL_Set) != (uint32_t)RESET) + { + /* RSTCAL bit is set */ + bitstatus = SET; + } + else + { + /* RSTCAL bit is reset */ + bitstatus = RESET; + } + /* Return the RSTCAL bit status */ + return bitstatus; +} + +/** + * @brief Starts the selected ADC calibration process. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @retval None + */ +void ADC_StartCalibration(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + /* Enable the selected ADC calibration process */ + ADCx->CR2 |= CR2_CAL_Set; +} + +/** + * @brief Gets the selected ADC calibration status. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @retval The new state of ADC calibration (SET or RESET). + */ +FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + /* Check the status of CAL bit */ + if ((ADCx->CR2 & CR2_CAL_Set) != (uint32_t)RESET) + { + /* CAL bit is set: calibration on going */ + bitstatus = SET; + } + else + { + /* CAL bit is reset: end of calibration */ + bitstatus = RESET; + } + /* Return the CAL bit status */ + return bitstatus; +} + +/** + * @brief Enables or disables the selected ADC software start conversion . + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the selected ADC software start conversion. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected ADC conversion on external event and start the selected + ADC conversion */ + ADCx->CR2 |= CR2_EXTTRIG_SWSTART_Set; + } + else + { + /* Disable the selected ADC conversion on external event and stop the selected + ADC conversion */ + ADCx->CR2 &= CR2_EXTTRIG_SWSTART_Reset; + } +} + +/** + * @brief Gets the selected ADC Software start conversion Status. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @retval The new state of ADC software start conversion (SET or RESET). + */ +FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + /* Check the status of SWSTART bit */ + if ((ADCx->CR2 & CR2_SWSTART_Set) != (uint32_t)RESET) + { + /* SWSTART bit is set */ + bitstatus = SET; + } + else + { + /* SWSTART bit is reset */ + bitstatus = RESET; + } + /* Return the SWSTART bit status */ + return bitstatus; +} + +/** + * @brief Configures the discontinuous mode for the selected ADC regular + * group channel. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param Number: specifies the discontinuous mode regular channel + * count value. This number must be between 1 and 8. + * @retval None + */ +void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number) +{ + uint32_t tmpreg1 = 0; + uint32_t tmpreg2 = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_REGULAR_DISC_NUMBER(Number)); + /* Get the old register value */ + tmpreg1 = ADCx->CR1; + /* Clear the old discontinuous mode channel count */ + tmpreg1 &= CR1_DISCNUM_Reset; + /* Set the discontinuous mode channel count */ + tmpreg2 = Number - 1; + tmpreg1 |= tmpreg2 << 13; + /* Store the new register value */ + ADCx->CR1 = tmpreg1; +} + +/** + * @brief Enables or disables the discontinuous mode on regular group + * channel for the specified ADC + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the selected ADC discontinuous mode + * on regular group channel. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected ADC regular discontinuous mode */ + ADCx->CR1 |= CR1_DISCEN_Set; + } + else + { + /* Disable the selected ADC regular discontinuous mode */ + ADCx->CR1 &= CR1_DISCEN_Reset; + } +} + +/** + * @brief Configures for the selected ADC regular channel its corresponding + * rank in the sequencer and its sample time. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_Channel: the ADC channel to configure. + * This parameter can be one of the following values: + * @arg ADC_Channel_0: ADC Channel0 selected + * @arg ADC_Channel_1: ADC Channel1 selected + * @arg ADC_Channel_2: ADC Channel2 selected + * @arg ADC_Channel_3: ADC Channel3 selected + * @arg ADC_Channel_4: ADC Channel4 selected + * @arg ADC_Channel_5: ADC Channel5 selected + * @arg ADC_Channel_6: ADC Channel6 selected + * @arg ADC_Channel_7: ADC Channel7 selected + * @arg ADC_Channel_8: ADC Channel8 selected + * @arg ADC_Channel_9: ADC Channel9 selected + * @arg ADC_Channel_10: ADC Channel10 selected + * @arg ADC_Channel_11: ADC Channel11 selected + * @arg ADC_Channel_12: ADC Channel12 selected + * @arg ADC_Channel_13: ADC Channel13 selected + * @arg ADC_Channel_14: ADC Channel14 selected + * @arg ADC_Channel_15: ADC Channel15 selected + * @arg ADC_Channel_16: ADC Channel16 selected + * @arg ADC_Channel_17: ADC Channel17 selected + * @param Rank: The rank in the regular group sequencer. This parameter must be between 1 to 16. + * @param ADC_SampleTime: The sample time value to be set for the selected channel. + * This parameter can be one of the following values: + * @arg ADC_SampleTime_1Cycles5: Sample time equal to 1.5 cycles + * @arg ADC_SampleTime_7Cycles5: Sample time equal to 7.5 cycles + * @arg ADC_SampleTime_13Cycles5: Sample time equal to 13.5 cycles + * @arg ADC_SampleTime_28Cycles5: Sample time equal to 28.5 cycles + * @arg ADC_SampleTime_41Cycles5: Sample time equal to 41.5 cycles + * @arg ADC_SampleTime_55Cycles5: Sample time equal to 55.5 cycles + * @arg ADC_SampleTime_71Cycles5: Sample time equal to 71.5 cycles + * @arg ADC_SampleTime_239Cycles5: Sample time equal to 239.5 cycles + * @retval None + */ +void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) +{ + uint32_t tmpreg1 = 0, tmpreg2 = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CHANNEL(ADC_Channel)); + assert_param(IS_ADC_REGULAR_RANK(Rank)); + assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); + /* if ADC_Channel_10 ... ADC_Channel_17 is selected */ + if (ADC_Channel > ADC_Channel_9) + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR1; + /* Calculate the mask to clear */ + tmpreg2 = SMPR1_SMP_Set << (3 * (ADC_Channel - 10)); + /* Clear the old channel sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 10)); + /* Set the new channel sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SMPR1 = tmpreg1; + } + else /* ADC_Channel include in ADC_Channel_[0..9] */ + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR2; + /* Calculate the mask to clear */ + tmpreg2 = SMPR2_SMP_Set << (3 * ADC_Channel); + /* Clear the old channel sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); + /* Set the new channel sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SMPR2 = tmpreg1; + } + /* For Rank 1 to 6 */ + if (Rank < 7) + { + /* Get the old register value */ + tmpreg1 = ADCx->SQR3; + /* Calculate the mask to clear */ + tmpreg2 = SQR3_SQ_Set << (5 * (Rank - 1)); + /* Clear the old SQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 1)); + /* Set the SQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SQR3 = tmpreg1; + } + /* For Rank 7 to 12 */ + else if (Rank < 13) + { + /* Get the old register value */ + tmpreg1 = ADCx->SQR2; + /* Calculate the mask to clear */ + tmpreg2 = SQR2_SQ_Set << (5 * (Rank - 7)); + /* Clear the old SQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 7)); + /* Set the SQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SQR2 = tmpreg1; + } + /* For Rank 13 to 16 */ + else + { + /* Get the old register value */ + tmpreg1 = ADCx->SQR1; + /* Calculate the mask to clear */ + tmpreg2 = SQR1_SQ_Set << (5 * (Rank - 13)); + /* Clear the old SQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 13)); + /* Set the SQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SQR1 = tmpreg1; + } +} + +/** + * @brief Enables or disables the ADCx conversion through external trigger. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the selected ADC external trigger start of conversion. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected ADC conversion on external event */ + ADCx->CR2 |= CR2_EXTTRIG_Set; + } + else + { + /* Disable the selected ADC conversion on external event */ + ADCx->CR2 &= CR2_EXTTRIG_Reset; + } +} + +/** + * @brief Returns the last ADCx conversion result data for regular channel. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @retval The Data conversion value. + */ +uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + /* Return the selected ADC conversion value */ + return (uint16_t) ADCx->DR; +} + +/** + * @brief Returns the last ADC1 and ADC2 conversion result data in dual mode. + * @retval The Data conversion value. + */ +uint32_t ADC_GetDualModeConversionValue(void) +{ + /* Return the dual mode conversion value */ + return (*(__IO uint32_t *) DR_ADDRESS); +} + +/** + * @brief Enables or disables the selected ADC automatic injected group + * conversion after regular one. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the selected ADC auto injected conversion + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected ADC automatic injected group conversion */ + ADCx->CR1 |= CR1_JAUTO_Set; + } + else + { + /* Disable the selected ADC automatic injected group conversion */ + ADCx->CR1 &= CR1_JAUTO_Reset; + } +} + +/** + * @brief Enables or disables the discontinuous mode for injected group + * channel for the specified ADC + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the selected ADC discontinuous mode + * on injected group channel. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected ADC injected discontinuous mode */ + ADCx->CR1 |= CR1_JDISCEN_Set; + } + else + { + /* Disable the selected ADC injected discontinuous mode */ + ADCx->CR1 &= CR1_JDISCEN_Reset; + } +} + +/** + * @brief Configures the ADCx external trigger for injected channels conversion. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_ExternalTrigInjecConv: specifies the ADC trigger to start injected conversion. + * This parameter can be one of the following values: + * @arg ADC_ExternalTrigInjecConv_T1_TRGO: Timer1 TRGO event selected (for ADC1, ADC2 and ADC3) + * @arg ADC_ExternalTrigInjecConv_T1_CC4: Timer1 capture compare4 selected (for ADC1, ADC2 and ADC3) + * @arg ADC_ExternalTrigInjecConv_T2_TRGO: Timer2 TRGO event selected (for ADC1 and ADC2) + * @arg ADC_ExternalTrigInjecConv_T2_CC1: Timer2 capture compare1 selected (for ADC1 and ADC2) + * @arg ADC_ExternalTrigInjecConv_T3_CC4: Timer3 capture compare4 selected (for ADC1 and ADC2) + * @arg ADC_ExternalTrigInjecConv_T4_TRGO: Timer4 TRGO event selected (for ADC1 and ADC2) + * @arg ADC_ExternalTrigInjecConv_Ext_IT15_TIM8_CC4: External interrupt line 15 or Timer8 + * capture compare4 event selected (for ADC1 and ADC2) + * @arg ADC_ExternalTrigInjecConv_T4_CC3: Timer4 capture compare3 selected (for ADC3 only) + * @arg ADC_ExternalTrigInjecConv_T8_CC2: Timer8 capture compare2 selected (for ADC3 only) + * @arg ADC_ExternalTrigInjecConv_T8_CC4: Timer8 capture compare4 selected (for ADC3 only) + * @arg ADC_ExternalTrigInjecConv_T5_TRGO: Timer5 TRGO event selected (for ADC3 only) + * @arg ADC_ExternalTrigInjecConv_T5_CC4: Timer5 capture compare4 selected (for ADC3 only) + * @arg ADC_ExternalTrigInjecConv_None: Injected conversion started by software and not + * by external trigger (for ADC1, ADC2 and ADC3) + * @retval None + */ +void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_EXT_INJEC_TRIG(ADC_ExternalTrigInjecConv)); + /* Get the old register value */ + tmpreg = ADCx->CR2; + /* Clear the old external event selection for injected group */ + tmpreg &= CR2_JEXTSEL_Reset; + /* Set the external event selection for injected group */ + tmpreg |= ADC_ExternalTrigInjecConv; + /* Store the new register value */ + ADCx->CR2 = tmpreg; +} + +/** + * @brief Enables or disables the ADCx injected channels conversion through + * external trigger + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the selected ADC external trigger start of + * injected conversion. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected ADC external event selection for injected group */ + ADCx->CR2 |= CR2_JEXTTRIG_Set; + } + else + { + /* Disable the selected ADC external event selection for injected group */ + ADCx->CR2 &= CR2_JEXTTRIG_Reset; + } +} + +/** + * @brief Enables or disables the selected ADC start of the injected + * channels conversion. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param NewState: new state of the selected ADC software start injected conversion. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_SoftwareStartInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected ADC conversion for injected group on external event and start the selected + ADC injected conversion */ + ADCx->CR2 |= CR2_JEXTTRIG_JSWSTART_Set; + } + else + { + /* Disable the selected ADC conversion on external event for injected group and stop the selected + ADC injected conversion */ + ADCx->CR2 &= CR2_JEXTTRIG_JSWSTART_Reset; + } +} + +/** + * @brief Gets the selected ADC Software start injected conversion Status. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @retval The new state of ADC software start injected conversion (SET or RESET). + */ +FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + /* Check the status of JSWSTART bit */ + if ((ADCx->CR2 & CR2_JSWSTART_Set) != (uint32_t)RESET) + { + /* JSWSTART bit is set */ + bitstatus = SET; + } + else + { + /* JSWSTART bit is reset */ + bitstatus = RESET; + } + /* Return the JSWSTART bit status */ + return bitstatus; +} + +/** + * @brief Configures for the selected ADC injected channel its corresponding + * rank in the sequencer and its sample time. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_Channel: the ADC channel to configure. + * This parameter can be one of the following values: + * @arg ADC_Channel_0: ADC Channel0 selected + * @arg ADC_Channel_1: ADC Channel1 selected + * @arg ADC_Channel_2: ADC Channel2 selected + * @arg ADC_Channel_3: ADC Channel3 selected + * @arg ADC_Channel_4: ADC Channel4 selected + * @arg ADC_Channel_5: ADC Channel5 selected + * @arg ADC_Channel_6: ADC Channel6 selected + * @arg ADC_Channel_7: ADC Channel7 selected + * @arg ADC_Channel_8: ADC Channel8 selected + * @arg ADC_Channel_9: ADC Channel9 selected + * @arg ADC_Channel_10: ADC Channel10 selected + * @arg ADC_Channel_11: ADC Channel11 selected + * @arg ADC_Channel_12: ADC Channel12 selected + * @arg ADC_Channel_13: ADC Channel13 selected + * @arg ADC_Channel_14: ADC Channel14 selected + * @arg ADC_Channel_15: ADC Channel15 selected + * @arg ADC_Channel_16: ADC Channel16 selected + * @arg ADC_Channel_17: ADC Channel17 selected + * @param Rank: The rank in the injected group sequencer. This parameter must be between 1 and 4. + * @param ADC_SampleTime: The sample time value to be set for the selected channel. + * This parameter can be one of the following values: + * @arg ADC_SampleTime_1Cycles5: Sample time equal to 1.5 cycles + * @arg ADC_SampleTime_7Cycles5: Sample time equal to 7.5 cycles + * @arg ADC_SampleTime_13Cycles5: Sample time equal to 13.5 cycles + * @arg ADC_SampleTime_28Cycles5: Sample time equal to 28.5 cycles + * @arg ADC_SampleTime_41Cycles5: Sample time equal to 41.5 cycles + * @arg ADC_SampleTime_55Cycles5: Sample time equal to 55.5 cycles + * @arg ADC_SampleTime_71Cycles5: Sample time equal to 71.5 cycles + * @arg ADC_SampleTime_239Cycles5: Sample time equal to 239.5 cycles + * @retval None + */ +void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) +{ + uint32_t tmpreg1 = 0, tmpreg2 = 0, tmpreg3 = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CHANNEL(ADC_Channel)); + assert_param(IS_ADC_INJECTED_RANK(Rank)); + assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); + /* if ADC_Channel_10 ... ADC_Channel_17 is selected */ + if (ADC_Channel > ADC_Channel_9) + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR1; + /* Calculate the mask to clear */ + tmpreg2 = SMPR1_SMP_Set << (3*(ADC_Channel - 10)); + /* Clear the old channel sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3*(ADC_Channel - 10)); + /* Set the new channel sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SMPR1 = tmpreg1; + } + else /* ADC_Channel include in ADC_Channel_[0..9] */ + { + /* Get the old register value */ + tmpreg1 = ADCx->SMPR2; + /* Calculate the mask to clear */ + tmpreg2 = SMPR2_SMP_Set << (3 * ADC_Channel); + /* Clear the old channel sample time */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set */ + tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); + /* Set the new channel sample time */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->SMPR2 = tmpreg1; + } + /* Rank configuration */ + /* Get the old register value */ + tmpreg1 = ADCx->JSQR; + /* Get JL value: Number = JL+1 */ + tmpreg3 = (tmpreg1 & JSQR_JL_Set)>> 20; + /* Calculate the mask to clear: ((Rank-1)+(4-JL-1)) */ + tmpreg2 = JSQR_JSQ_Set << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1))); + /* Clear the old JSQx bits for the selected rank */ + tmpreg1 &= ~tmpreg2; + /* Calculate the mask to set: ((Rank-1)+(4-JL-1)) */ + tmpreg2 = (uint32_t)ADC_Channel << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1))); + /* Set the JSQx bits for the selected rank */ + tmpreg1 |= tmpreg2; + /* Store the new register value */ + ADCx->JSQR = tmpreg1; +} + +/** + * @brief Configures the sequencer length for injected channels + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param Length: The sequencer length. + * This parameter must be a number between 1 to 4. + * @retval None + */ +void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length) +{ + uint32_t tmpreg1 = 0; + uint32_t tmpreg2 = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_INJECTED_LENGTH(Length)); + + /* Get the old register value */ + tmpreg1 = ADCx->JSQR; + /* Clear the old injected sequnence lenght JL bits */ + tmpreg1 &= JSQR_JL_Reset; + /* Set the injected sequnence lenght JL bits */ + tmpreg2 = Length - 1; + tmpreg1 |= tmpreg2 << 20; + /* Store the new register value */ + ADCx->JSQR = tmpreg1; +} + +/** + * @brief Set the injected channels conversion value offset + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_InjectedChannel: the ADC injected channel to set its offset. + * This parameter can be one of the following values: + * @arg ADC_InjectedChannel_1: Injected Channel1 selected + * @arg ADC_InjectedChannel_2: Injected Channel2 selected + * @arg ADC_InjectedChannel_3: Injected Channel3 selected + * @arg ADC_InjectedChannel_4: Injected Channel4 selected + * @param Offset: the offset value for the selected ADC injected channel + * This parameter must be a 12bit value. + * @retval None + */ +void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel)); + assert_param(IS_ADC_OFFSET(Offset)); + + tmp = (uint32_t)ADCx; + tmp += ADC_InjectedChannel; + + /* Set the selected injected channel data offset */ + *(__IO uint32_t *) tmp = (uint32_t)Offset; +} + +/** + * @brief Returns the ADC injected channel conversion result + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_InjectedChannel: the converted ADC injected channel. + * This parameter can be one of the following values: + * @arg ADC_InjectedChannel_1: Injected Channel1 selected + * @arg ADC_InjectedChannel_2: Injected Channel2 selected + * @arg ADC_InjectedChannel_3: Injected Channel3 selected + * @arg ADC_InjectedChannel_4: Injected Channel4 selected + * @retval The Data conversion value. + */ +uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel)); + + tmp = (uint32_t)ADCx; + tmp += ADC_InjectedChannel + JDR_Offset; + + /* Returns the selected injected channel conversion data value */ + return (uint16_t) (*(__IO uint32_t*) tmp); +} + +/** + * @brief Enables or disables the analog watchdog on single/all regular + * or injected channels + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_AnalogWatchdog: the ADC analog watchdog configuration. + * This parameter can be one of the following values: + * @arg ADC_AnalogWatchdog_SingleRegEnable: Analog watchdog on a single regular channel + * @arg ADC_AnalogWatchdog_SingleInjecEnable: Analog watchdog on a single injected channel + * @arg ADC_AnalogWatchdog_SingleRegOrInjecEnable: Analog watchdog on a single regular or injected channel + * @arg ADC_AnalogWatchdog_AllRegEnable: Analog watchdog on all regular channel + * @arg ADC_AnalogWatchdog_AllInjecEnable: Analog watchdog on all injected channel + * @arg ADC_AnalogWatchdog_AllRegAllInjecEnable: Analog watchdog on all regular and injected channels + * @arg ADC_AnalogWatchdog_None: No channel guarded by the analog watchdog + * @retval None + */ +void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_ANALOG_WATCHDOG(ADC_AnalogWatchdog)); + /* Get the old register value */ + tmpreg = ADCx->CR1; + /* Clear AWDEN, AWDENJ and AWDSGL bits */ + tmpreg &= CR1_AWDMode_Reset; + /* Set the analog watchdog enable mode */ + tmpreg |= ADC_AnalogWatchdog; + /* Store the new register value */ + ADCx->CR1 = tmpreg; +} + +/** + * @brief Configures the high and low thresholds of the analog watchdog. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param HighThreshold: the ADC analog watchdog High threshold value. + * This parameter must be a 12bit value. + * @param LowThreshold: the ADC analog watchdog Low threshold value. + * This parameter must be a 12bit value. + * @retval None + */ +void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, + uint16_t LowThreshold) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_THRESHOLD(HighThreshold)); + assert_param(IS_ADC_THRESHOLD(LowThreshold)); + /* Set the ADCx high threshold */ + ADCx->HTR = HighThreshold; + /* Set the ADCx low threshold */ + ADCx->LTR = LowThreshold; +} + +/** + * @brief Configures the analog watchdog guarded single channel + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_Channel: the ADC channel to configure for the analog watchdog. + * This parameter can be one of the following values: + * @arg ADC_Channel_0: ADC Channel0 selected + * @arg ADC_Channel_1: ADC Channel1 selected + * @arg ADC_Channel_2: ADC Channel2 selected + * @arg ADC_Channel_3: ADC Channel3 selected + * @arg ADC_Channel_4: ADC Channel4 selected + * @arg ADC_Channel_5: ADC Channel5 selected + * @arg ADC_Channel_6: ADC Channel6 selected + * @arg ADC_Channel_7: ADC Channel7 selected + * @arg ADC_Channel_8: ADC Channel8 selected + * @arg ADC_Channel_9: ADC Channel9 selected + * @arg ADC_Channel_10: ADC Channel10 selected + * @arg ADC_Channel_11: ADC Channel11 selected + * @arg ADC_Channel_12: ADC Channel12 selected + * @arg ADC_Channel_13: ADC Channel13 selected + * @arg ADC_Channel_14: ADC Channel14 selected + * @arg ADC_Channel_15: ADC Channel15 selected + * @arg ADC_Channel_16: ADC Channel16 selected + * @arg ADC_Channel_17: ADC Channel17 selected + * @retval None + */ +void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CHANNEL(ADC_Channel)); + /* Get the old register value */ + tmpreg = ADCx->CR1; + /* Clear the Analog watchdog channel select bits */ + tmpreg &= CR1_AWDCH_Reset; + /* Set the Analog watchdog channel */ + tmpreg |= ADC_Channel; + /* Store the new register value */ + ADCx->CR1 = tmpreg; +} + +/** + * @brief Enables or disables the temperature sensor and Vrefint channel. + * @param NewState: new state of the temperature sensor. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_TempSensorVrefintCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the temperature sensor and Vrefint channel*/ + ADC1->CR2 |= CR2_TSVREFE_Set; + } + else + { + /* Disable the temperature sensor and Vrefint channel*/ + ADC1->CR2 &= CR2_TSVREFE_Reset; + } +} + +/** + * @brief Checks whether the specified ADC flag is set or not. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg ADC_FLAG_AWD: Analog watchdog flag + * @arg ADC_FLAG_EOC: End of conversion flag + * @arg ADC_FLAG_JEOC: End of injected group conversion flag + * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag + * @arg ADC_FLAG_STRT: Start of regular group conversion flag + * @retval The new state of ADC_FLAG (SET or RESET). + */ +FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_GET_FLAG(ADC_FLAG)); + /* Check the status of the specified ADC flag */ + if ((ADCx->SR & ADC_FLAG) != (uint8_t)RESET) + { + /* ADC_FLAG is set */ + bitstatus = SET; + } + else + { + /* ADC_FLAG is reset */ + bitstatus = RESET; + } + /* Return the ADC_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the ADCx's pending flags. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg ADC_FLAG_AWD: Analog watchdog flag + * @arg ADC_FLAG_EOC: End of conversion flag + * @arg ADC_FLAG_JEOC: End of injected group conversion flag + * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag + * @arg ADC_FLAG_STRT: Start of regular group conversion flag + * @retval None + */ +void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_CLEAR_FLAG(ADC_FLAG)); + /* Clear the selected ADC flags */ + ADCx->SR = ~(uint32_t)ADC_FLAG; +} + +/** + * @brief Checks whether the specified ADC interrupt has occurred or not. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_IT: specifies the ADC interrupt source to check. + * This parameter can be one of the following values: + * @arg ADC_IT_EOC: End of conversion interrupt mask + * @arg ADC_IT_AWD: Analog watchdog interrupt mask + * @arg ADC_IT_JEOC: End of injected conversion interrupt mask + * @retval The new state of ADC_IT (SET or RESET). + */ +ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT) +{ + ITStatus bitstatus = RESET; + uint32_t itmask = 0, enablestatus = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_GET_IT(ADC_IT)); + /* Get the ADC IT index */ + itmask = ADC_IT >> 8; + /* Get the ADC_IT enable bit status */ + enablestatus = (ADCx->CR1 & (uint8_t)ADC_IT) ; + /* Check the status of the specified ADC interrupt */ + if (((ADCx->SR & itmask) != (uint32_t)RESET) && enablestatus) + { + /* ADC_IT is set */ + bitstatus = SET; + } + else + { + /* ADC_IT is reset */ + bitstatus = RESET; + } + /* Return the ADC_IT status */ + return bitstatus; +} + +/** + * @brief Clears the ADCxs interrupt pending bits. + * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. + * @param ADC_IT: specifies the ADC interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg ADC_IT_EOC: End of conversion interrupt mask + * @arg ADC_IT_AWD: Analog watchdog interrupt mask + * @arg ADC_IT_JEOC: End of injected conversion interrupt mask + * @retval None + */ +void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT) +{ + uint8_t itmask = 0; + /* Check the parameters */ + assert_param(IS_ADC_ALL_PERIPH(ADCx)); + assert_param(IS_ADC_IT(ADC_IT)); + /* Get the ADC IT index */ + itmask = (uint8_t)(ADC_IT >> 8); + /* Clear the selected ADC interrupt pending bits */ + ADCx->SR = ~(uint32_t)itmask; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_bkp.c b/example/libs_stm/src/stm32f10x/stm32f10x_bkp.c new file mode 100644 index 000000000..de065648f --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_bkp.c @@ -0,0 +1,311 @@ +/** + ****************************************************************************** + * @file stm32f10x_bkp.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the BKP firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_bkp.h" +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup BKP + * @brief BKP driver modules + * @{ + */ + +/** @defgroup BKP_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup BKP_Private_Defines + * @{ + */ + +/* ------------ BKP registers bit address in the alias region --------------- */ +#define BKP_OFFSET (BKP_BASE - PERIPH_BASE) + +/* --- CR Register ----*/ + +/* Alias word address of TPAL bit */ +#define CR_OFFSET (BKP_OFFSET + 0x30) +#define TPAL_BitNumber 0x01 +#define CR_TPAL_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (TPAL_BitNumber * 4)) + +/* Alias word address of TPE bit */ +#define TPE_BitNumber 0x00 +#define CR_TPE_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (TPE_BitNumber * 4)) + +/* --- CSR Register ---*/ + +/* Alias word address of TPIE bit */ +#define CSR_OFFSET (BKP_OFFSET + 0x34) +#define TPIE_BitNumber 0x02 +#define CSR_TPIE_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (TPIE_BitNumber * 4)) + +/* Alias word address of TIF bit */ +#define TIF_BitNumber 0x09 +#define CSR_TIF_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (TIF_BitNumber * 4)) + +/* Alias word address of TEF bit */ +#define TEF_BitNumber 0x08 +#define CSR_TEF_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (TEF_BitNumber * 4)) + +/* ---------------------- BKP registers bit mask ------------------------ */ + +/* RTCCR register bit mask */ +#define RTCCR_CAL_Mask ((uint16_t)0xFF80) +#define RTCCR_Mask ((uint16_t)0xFC7F) + +/* CSR register bit mask */ +#define CSR_CTE_Set ((uint16_t)0x0001) +#define CSR_CTI_Set ((uint16_t)0x0002) + +/** + * @} + */ + + +/** @defgroup BKP_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup BKP_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup BKP_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup BKP_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the BKP peripheral registers to their default reset values. + * @param None + * @retval None + */ +void BKP_DeInit(void) +{ + RCC_BackupResetCmd(ENABLE); + RCC_BackupResetCmd(DISABLE); +} + +/** + * @brief Configures the Tamper Pin active level. + * @param BKP_TamperPinLevel: specifies the Tamper Pin active level. + * This parameter can be one of the following values: + * @arg BKP_TamperPinLevel_High: Tamper pin active on high level + * @arg BKP_TamperPinLevel_Low: Tamper pin active on low level + * @retval None + */ +void BKP_TamperPinLevelConfig(uint16_t BKP_TamperPinLevel) +{ + /* Check the parameters */ + assert_param(IS_BKP_TAMPER_PIN_LEVEL(BKP_TamperPinLevel)); + *(__IO uint32_t *) CR_TPAL_BB = BKP_TamperPinLevel; +} + +/** + * @brief Enables or disables the Tamper Pin activation. + * @param NewState: new state of the Tamper Pin activation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void BKP_TamperPinCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CR_TPE_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the Tamper Pin Interrupt. + * @param NewState: new state of the Tamper Pin Interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void BKP_ITConfig(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CSR_TPIE_BB = (uint32_t)NewState; +} + +/** + * @brief Select the RTC output source to output on the Tamper pin. + * @param BKP_RTCOutputSource: specifies the RTC output source. + * This parameter can be one of the following values: + * @arg BKP_RTCOutputSource_None: no RTC output on the Tamper pin. + * @arg BKP_RTCOutputSource_CalibClock: output the RTC clock with frequency + * divided by 64 on the Tamper pin. + * @arg BKP_RTCOutputSource_Alarm: output the RTC Alarm pulse signal on + * the Tamper pin. + * @arg BKP_RTCOutputSource_Second: output the RTC Second pulse signal on + * the Tamper pin. + * @retval None + */ +void BKP_RTCOutputConfig(uint16_t BKP_RTCOutputSource) +{ + uint16_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_BKP_RTC_OUTPUT_SOURCE(BKP_RTCOutputSource)); + tmpreg = BKP->RTCCR; + /* Clear CCO, ASOE and ASOS bits */ + tmpreg &= RTCCR_Mask; + + /* Set CCO, ASOE and ASOS bits according to BKP_RTCOutputSource value */ + tmpreg |= BKP_RTCOutputSource; + /* Store the new value */ + BKP->RTCCR = tmpreg; +} + +/** + * @brief Sets RTC Clock Calibration value. + * @param CalibrationValue: specifies the RTC Clock Calibration value. + * This parameter must be a number between 0 and 0x7F. + * @retval None + */ +void BKP_SetRTCCalibrationValue(uint8_t CalibrationValue) +{ + uint16_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_BKP_CALIBRATION_VALUE(CalibrationValue)); + tmpreg = BKP->RTCCR; + /* Clear CAL[6:0] bits */ + tmpreg &= RTCCR_CAL_Mask; + /* Set CAL[6:0] bits according to CalibrationValue value */ + tmpreg |= CalibrationValue; + /* Store the new value */ + BKP->RTCCR = tmpreg; +} + +/** + * @brief Writes user data to the specified Data Backup Register. + * @param BKP_DR: specifies the Data Backup Register. + * This parameter can be BKP_DRx where x:[1, 42] + * @param Data: data to write + * @retval None + */ +void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_BKP_DR(BKP_DR)); + + tmp = (uint32_t)BKP_BASE; + tmp += BKP_DR; + + *(__IO uint32_t *) tmp = Data; +} + +/** + * @brief Reads data from the specified Data Backup Register. + * @param BKP_DR: specifies the Data Backup Register. + * This parameter can be BKP_DRx where x:[1, 42] + * @retval The content of the specified Data Backup Register + */ +uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_BKP_DR(BKP_DR)); + + tmp = (uint32_t)BKP_BASE; + tmp += BKP_DR; + + return (*(__IO uint16_t *) tmp); +} + +/** + * @brief Checks whether the Tamper Pin Event flag is set or not. + * @param None + * @retval The new state of the Tamper Pin Event flag (SET or RESET). + */ +FlagStatus BKP_GetFlagStatus(void) +{ + return (FlagStatus)(*(__IO uint32_t *) CSR_TEF_BB); +} + +/** + * @brief Clears Tamper Pin Event pending flag. + * @param None + * @retval None + */ +void BKP_ClearFlag(void) +{ + /* Set CTE bit to clear Tamper Pin Event flag */ + BKP->CSR |= CSR_CTE_Set; +} + +/** + * @brief Checks whether the Tamper Pin Interrupt has occurred or not. + * @param None + * @retval The new state of the Tamper Pin Interrupt (SET or RESET). + */ +ITStatus BKP_GetITStatus(void) +{ + return (ITStatus)(*(__IO uint32_t *) CSR_TIF_BB); +} + +/** + * @brief Clears Tamper Pin Interrupt pending bit. + * @param None + * @retval None + */ +void BKP_ClearITPendingBit(void) +{ + /* Set CTI bit to clear Tamper Pin Interrupt pending bit */ + BKP->CSR |= CSR_CTI_Set; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_can.c b/example/libs_stm/src/stm32f10x/stm32f10x_can.c new file mode 100644 index 000000000..537f333ba --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_can.c @@ -0,0 +1,990 @@ +/** + ****************************************************************************** + * @file stm32f10x_can.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the CAN firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_can.h" +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup CAN + * @brief CAN driver modules + * @{ + */ + +/** @defgroup CAN_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup CAN_Private_Defines + * @{ + */ + +/* CAN Master Control Register bits */ +#define MCR_INRQ ((uint32_t)0x00000001) /* Initialization request */ +#define MCR_SLEEP ((uint32_t)0x00000002) /* Sleep mode request */ +#define MCR_TXFP ((uint32_t)0x00000004) /* Transmit FIFO priority */ +#define MCR_RFLM ((uint32_t)0x00000008) /* Receive FIFO locked mode */ +#define MCR_NART ((uint32_t)0x00000010) /* No automatic retransmission */ +#define MCR_AWUM ((uint32_t)0x00000020) /* Automatic wake up mode */ +#define MCR_ABOM ((uint32_t)0x00000040) /* Automatic bus-off management */ +#define MCR_TTCM ((uint32_t)0x00000080) /* time triggered communication */ +#define MCR_RESET ((uint32_t)0x00008000) /* time triggered communication */ +#define MCR_DBF ((uint32_t)0x00010000) /* software master reset */ + +/* CAN Master Status Register bits */ +#define MSR_INAK ((uint32_t)0x00000001) /* Initialization acknowledge */ +#define MSR_WKUI ((uint32_t)0x00000008) /* Wake-up interrupt */ +#define MSR_SLAKI ((uint32_t)0x00000010) /* Sleep acknowledge interrupt */ + +/* CAN Transmit Status Register bits */ +#define TSR_RQCP0 ((uint32_t)0x00000001) /* Request completed mailbox0 */ +#define TSR_TXOK0 ((uint32_t)0x00000002) /* Transmission OK of mailbox0 */ +#define TSR_ABRQ0 ((uint32_t)0x00000080) /* Abort request for mailbox0 */ +#define TSR_RQCP1 ((uint32_t)0x00000100) /* Request completed mailbox1 */ +#define TSR_TXOK1 ((uint32_t)0x00000200) /* Transmission OK of mailbox1 */ +#define TSR_ABRQ1 ((uint32_t)0x00008000) /* Abort request for mailbox1 */ +#define TSR_RQCP2 ((uint32_t)0x00010000) /* Request completed mailbox2 */ +#define TSR_TXOK2 ((uint32_t)0x00020000) /* Transmission OK of mailbox2 */ +#define TSR_ABRQ2 ((uint32_t)0x00800000) /* Abort request for mailbox2 */ +#define TSR_TME0 ((uint32_t)0x04000000) /* Transmit mailbox 0 empty */ +#define TSR_TME1 ((uint32_t)0x08000000) /* Transmit mailbox 1 empty */ +#define TSR_TME2 ((uint32_t)0x10000000) /* Transmit mailbox 2 empty */ + +/* CAN Receive FIFO 0 Register bits */ +#define RF0R_FULL0 ((uint32_t)0x00000008) /* FIFO 0 full */ +#define RF0R_FOVR0 ((uint32_t)0x00000010) /* FIFO 0 overrun */ +#define RF0R_RFOM0 ((uint32_t)0x00000020) /* Release FIFO 0 output mailbox */ + +/* CAN Receive FIFO 1 Register bits */ +#define RF1R_FULL1 ((uint32_t)0x00000008) /* FIFO 1 full */ +#define RF1R_FOVR1 ((uint32_t)0x00000010) /* FIFO 1 overrun */ +#define RF1R_RFOM1 ((uint32_t)0x00000020) /* Release FIFO 1 output mailbox */ + +/* CAN Error Status Register bits */ +#define ESR_EWGF ((uint32_t)0x00000001) /* Error warning flag */ +#define ESR_EPVF ((uint32_t)0x00000002) /* Error passive flag */ +#define ESR_BOFF ((uint32_t)0x00000004) /* Bus-off flag */ + +/* CAN Mailbox Transmit Request */ +#define TMIDxR_TXRQ ((uint32_t)0x00000001) /* Transmit mailbox request */ + +/* CAN Filter Master Register bits */ +#define FMR_FINIT ((uint32_t)0x00000001) /* Filter init mode */ + +/* Time out for INAK bit */ +#define INAK_TimeOut ((uint32_t)0x0000FFFF) + +/* Time out for SLAK bit */ +#define SLAK_TimeOut ((uint32_t)0x0000FFFF) + +/** + * @} + */ + +/** @defgroup CAN_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup CAN_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup CAN_Private_FunctionPrototypes + * @{ + */ + +static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit); + +/** + * @} + */ + +/** @defgroup CAN_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the CAN peripheral registers to their default reset values. + * @param CANx: where x can be 1 or 2 to select the CAN peripheral. + * @retval None. + */ +void CAN_DeInit(CAN_TypeDef* CANx) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + + if (CANx == CAN1) + { + /* Enable CAN1 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, ENABLE); + /* Release CAN1 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, DISABLE); + } + else + { + /* Enable CAN2 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, ENABLE); + /* Release CAN2 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, DISABLE); + } +} + +/** + * @brief Initializes the CAN peripheral according to the specified + * parameters in the CAN_InitStruct. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param CAN_InitStruct: pointer to a CAN_InitTypeDef structure that + * contains the configuration information for the CAN peripheral. + * @retval Constant indicates initialization succeed which will be + * CANINITFAILED or CANINITOK. + */ +uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct) +{ + uint8_t InitStatus = CANINITFAILED; + uint32_t wait_ack = 0x00000000; + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_TTCM)); + assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_ABOM)); + assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_AWUM)); + assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_NART)); + assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_RFLM)); + assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_TXFP)); + assert_param(IS_CAN_MODE(CAN_InitStruct->CAN_Mode)); + assert_param(IS_CAN_SJW(CAN_InitStruct->CAN_SJW)); + assert_param(IS_CAN_BS1(CAN_InitStruct->CAN_BS1)); + assert_param(IS_CAN_BS2(CAN_InitStruct->CAN_BS2)); + assert_param(IS_CAN_PRESCALER(CAN_InitStruct->CAN_Prescaler)); + + /* exit from sleep mode */ + CANx->MCR &= ~MCR_SLEEP; + + /* Request initialisation */ + CANx->MCR |= MCR_INRQ ; + + /* Wait the acknowledge */ + while (((CANx->MSR & MSR_INAK) != MSR_INAK) && (wait_ack != INAK_TimeOut)) + { + wait_ack++; + } + + /* ...and check acknowledged */ + if ((CANx->MSR & MSR_INAK) != MSR_INAK) + { + InitStatus = CANINITFAILED; + } + else + { + /* Set the time triggered communication mode */ + if (CAN_InitStruct->CAN_TTCM == ENABLE) + { + CANx->MCR |= MCR_TTCM; + } + else + { + CANx->MCR &= ~MCR_TTCM; + } + + /* Set the automatic bus-off management */ + if (CAN_InitStruct->CAN_ABOM == ENABLE) + { + CANx->MCR |= MCR_ABOM; + } + else + { + CANx->MCR &= ~MCR_ABOM; + } + + /* Set the automatic wake-up mode */ + if (CAN_InitStruct->CAN_AWUM == ENABLE) + { + CANx->MCR |= MCR_AWUM; + } + else + { + CANx->MCR &= ~MCR_AWUM; + } + + /* Set the no automatic retransmission */ + if (CAN_InitStruct->CAN_NART == ENABLE) + { + CANx->MCR |= MCR_NART; + } + else + { + CANx->MCR &= ~MCR_NART; + } + + /* Set the receive FIFO locked mode */ + if (CAN_InitStruct->CAN_RFLM == ENABLE) + { + CANx->MCR |= MCR_RFLM; + } + else + { + CANx->MCR &= ~MCR_RFLM; + } + + /* Set the transmit FIFO priority */ + if (CAN_InitStruct->CAN_TXFP == ENABLE) + { + CANx->MCR |= MCR_TXFP; + } + else + { + CANx->MCR &= ~MCR_TXFP; + } + + /* Set the bit timing register */ + CANx->BTR = (uint32_t)((uint32_t)CAN_InitStruct->CAN_Mode << 30) | ((uint32_t)CAN_InitStruct->CAN_SJW << 24) | + ((uint32_t)CAN_InitStruct->CAN_BS1 << 16) | ((uint32_t)CAN_InitStruct->CAN_BS2 << 20) | + ((uint32_t)CAN_InitStruct->CAN_Prescaler - 1); + + /* Request leave initialisation */ + CANx->MCR &= ~MCR_INRQ; + + /* Wait the acknowledge */ + wait_ack = 0x00; + + while (((CANx->MSR & MSR_INAK) == MSR_INAK) && (wait_ack != INAK_TimeOut)) + { + wait_ack++; + } + + /* ...and check acknowledged */ + if ((CANx->MSR & MSR_INAK) == MSR_INAK) + { + InitStatus = CANINITFAILED; + } + else + { + InitStatus = CANINITOK ; + } + } + + /* At this step, return the status of initialization */ + return InitStatus; +} + +/** + * @brief Initializes the CAN peripheral according to the specified + * parameters in the CAN_FilterInitStruct. + * @param CAN_FilterInitStruct: pointer to a CAN_FilterInitTypeDef + * structure that contains the configuration information. + * @retval None. + */ +void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct) +{ + uint32_t filter_number_bit_pos = 0; + /* Check the parameters */ + assert_param(IS_CAN_FILTER_NUMBER(CAN_FilterInitStruct->CAN_FilterNumber)); + assert_param(IS_CAN_FILTER_MODE(CAN_FilterInitStruct->CAN_FilterMode)); + assert_param(IS_CAN_FILTER_SCALE(CAN_FilterInitStruct->CAN_FilterScale)); + assert_param(IS_CAN_FILTER_FIFO(CAN_FilterInitStruct->CAN_FilterFIFOAssignment)); + assert_param(IS_FUNCTIONAL_STATE(CAN_FilterInitStruct->CAN_FilterActivation)); + + filter_number_bit_pos = ((uint32_t)0x00000001) << CAN_FilterInitStruct->CAN_FilterNumber; + + /* Initialisation mode for the filter */ + CAN1->FMR |= FMR_FINIT; + + /* Filter Deactivation */ + CAN1->FA1R &= ~(uint32_t)filter_number_bit_pos; + + /* Filter Scale */ + if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_16bit) + { + /* 16-bit scale for the filter */ + CAN1->FS1R &= ~(uint32_t)filter_number_bit_pos; + + /* First 16-bit identifier and First 16-bit mask */ + /* Or First 16-bit identifier and Second 16-bit identifier */ + CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 = + ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow) << 16) | + (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow); + + /* Second 16-bit identifier and Second 16-bit mask */ + /* Or Third 16-bit identifier and Fourth 16-bit identifier */ + CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 = + ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) | + (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh); + } + + if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_32bit) + { + /* 32-bit scale for the filter */ + CAN1->FS1R |= filter_number_bit_pos; + /* 32-bit identifier or First 32-bit identifier */ + CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 = + ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh) << 16) | + (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow); + /* 32-bit mask or Second 32-bit identifier */ + CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 = + ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) | + (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow); + } + + /* Filter Mode */ + if (CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdMask) + { + /*Id/Mask mode for the filter*/ + CAN1->FM1R &= ~(uint32_t)filter_number_bit_pos; + } + else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */ + { + /*Identifier list mode for the filter*/ + CAN1->FM1R |= (uint32_t)filter_number_bit_pos; + } + + /* Filter FIFO assignment */ + if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_FilterFIFO0) + { + /* FIFO 0 assignation for the filter */ + CAN1->FFA1R &= ~(uint32_t)filter_number_bit_pos; + } + + if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_FilterFIFO1) + { + /* FIFO 1 assignation for the filter */ + CAN1->FFA1R |= (uint32_t)filter_number_bit_pos; + } + + /* Filter activation */ + if (CAN_FilterInitStruct->CAN_FilterActivation == ENABLE) + { + CAN1->FA1R |= filter_number_bit_pos; + } + + /* Leave the initialisation mode for the filter */ + CAN1->FMR &= ~FMR_FINIT; +} + +/** + * @brief Fills each CAN_InitStruct member with its default value. + * @param CAN_InitStruct: pointer to a CAN_InitTypeDef structure which + * will be initialized. + * @retval None. + */ +void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct) +{ + /* Reset CAN init structure parameters values */ + /* Initialize the time triggered communication mode */ + CAN_InitStruct->CAN_TTCM = DISABLE; + /* Initialize the automatic bus-off management */ + CAN_InitStruct->CAN_ABOM = DISABLE; + /* Initialize the automatic wake-up mode */ + CAN_InitStruct->CAN_AWUM = DISABLE; + /* Initialize the no automatic retransmission */ + CAN_InitStruct->CAN_NART = DISABLE; + /* Initialize the receive FIFO locked mode */ + CAN_InitStruct->CAN_RFLM = DISABLE; + /* Initialize the transmit FIFO priority */ + CAN_InitStruct->CAN_TXFP = DISABLE; + /* Initialize the CAN_Mode member */ + CAN_InitStruct->CAN_Mode = CAN_Mode_Normal; + /* Initialize the CAN_SJW member */ + CAN_InitStruct->CAN_SJW = CAN_SJW_1tq; + /* Initialize the CAN_BS1 member */ + CAN_InitStruct->CAN_BS1 = CAN_BS1_4tq; + /* Initialize the CAN_BS2 member */ + CAN_InitStruct->CAN_BS2 = CAN_BS2_3tq; + /* Initialize the CAN_Prescaler member */ + CAN_InitStruct->CAN_Prescaler = 1; +} + +/** + * @brief Select the start bank filter for slave CAN. + * @note This function applies only to STM32 Connectivity line devices. + * @param CAN_BankNumber: Select the start slave bank filter from 1..27. + * @retval None. + */ +void CAN_SlaveStartBank(uint8_t CAN_BankNumber) +{ + /* Check the parameters */ + assert_param(IS_CAN_BANKNUMBER(CAN_BankNumber)); + /* enter Initialisation mode for the filter */ + CAN1->FMR |= FMR_FINIT; + /* Select the start slave bank */ + CAN1->FMR &= (uint32_t)0xFFFFC0F1 ; + CAN1->FMR |= (uint32_t)(CAN_BankNumber)<<8; + /* Leave Initialisation mode for the filter */ + CAN1->FMR &= ~FMR_FINIT; +} + +/** + * @brief Enables or disables the specified CAN interrupts. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param CAN_IT: specifies the CAN interrupt sources to be enabled or disabled. + * This parameter can be: CAN_IT_TME, CAN_IT_FMP0, CAN_IT_FF0, + * CAN_IT_FOV0, CAN_IT_FMP1, CAN_IT_FF1, + * CAN_IT_FOV1, CAN_IT_EWG, CAN_IT_EPV, + * CAN_IT_LEC, CAN_IT_ERR, CAN_IT_WKU or + * CAN_IT_SLK. + * @param NewState: new state of the CAN interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_ITConfig(CAN_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected CAN interrupt */ + CANx->IER |= CAN_IT; + } + else + { + /* Disable the selected CAN interrupt */ + CANx->IER &= ~CAN_IT; + } +} + +/** + * @brief Initiates the transmission of a message. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param TxMessage: pointer to a structure which contains CAN Id, CAN + * DLC and CAN datas. + * @retval The number of the mailbox that is used for transmission + * or CAN_NO_MB if there is no empty mailbox. + */ +uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage) +{ + uint8_t transmit_mailbox = 0; + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_IDTYPE(TxMessage->IDE)); + assert_param(IS_CAN_RTR(TxMessage->RTR)); + assert_param(IS_CAN_DLC(TxMessage->DLC)); + + /* Select one empty transmit mailbox */ + if ((CANx->TSR&TSR_TME0) == TSR_TME0) + { + transmit_mailbox = 0; + } + else if ((CANx->TSR&TSR_TME1) == TSR_TME1) + { + transmit_mailbox = 1; + } + else if ((CANx->TSR&TSR_TME2) == TSR_TME2) + { + transmit_mailbox = 2; + } + else + { + transmit_mailbox = CAN_NO_MB; + } + + if (transmit_mailbox != CAN_NO_MB) + { + /* Set up the Id */ + CANx->sTxMailBox[transmit_mailbox].TIR &= TMIDxR_TXRQ; + if (TxMessage->IDE == CAN_ID_STD) + { + assert_param(IS_CAN_STDID(TxMessage->StdId)); + CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->StdId << 21) | TxMessage->RTR); + } + else + { + assert_param(IS_CAN_EXTID(TxMessage->ExtId)); + CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->ExtId<<3) | TxMessage->IDE | + TxMessage->RTR); + } + + + /* Set up the DLC */ + TxMessage->DLC &= (uint8_t)0x0000000F; + CANx->sTxMailBox[transmit_mailbox].TDTR &= (uint32_t)0xFFFFFFF0; + CANx->sTxMailBox[transmit_mailbox].TDTR |= TxMessage->DLC; + + /* Set up the data field */ + CANx->sTxMailBox[transmit_mailbox].TDLR = (((uint32_t)TxMessage->Data[3] << 24) | + ((uint32_t)TxMessage->Data[2] << 16) | + ((uint32_t)TxMessage->Data[1] << 8) | + ((uint32_t)TxMessage->Data[0])); + CANx->sTxMailBox[transmit_mailbox].TDHR = (((uint32_t)TxMessage->Data[7] << 24) | + ((uint32_t)TxMessage->Data[6] << 16) | + ((uint32_t)TxMessage->Data[5] << 8) | + ((uint32_t)TxMessage->Data[4])); + /* Request transmission */ + CANx->sTxMailBox[transmit_mailbox].TIR |= TMIDxR_TXRQ; + } + return transmit_mailbox; +} + +/** + * @brief Checks the transmission of a message. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param TransmitMailbox: the number of the mailbox that is used for transmission. + * @retval CANTXOK if the CAN driver transmits the message, CANTXFAILED in an other case. + */ +uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox) +{ + /* RQCP, TXOK and TME bits */ + uint8_t state = 0; + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_TRANSMITMAILBOX(TransmitMailbox)); + switch (TransmitMailbox) + { + case (0): state |= (uint8_t)((CANx->TSR & TSR_RQCP0) << 2); + state |= (uint8_t)((CANx->TSR & TSR_TXOK0) >> 0); + state |= (uint8_t)((CANx->TSR & TSR_TME0) >> 26); + break; + case (1): state |= (uint8_t)((CANx->TSR & TSR_RQCP1) >> 6); + state |= (uint8_t)((CANx->TSR & TSR_TXOK1) >> 8); + state |= (uint8_t)((CANx->TSR & TSR_TME1) >> 27); + break; + case (2): state |= (uint8_t)((CANx->TSR & TSR_RQCP2) >> 14); + state |= (uint8_t)((CANx->TSR & TSR_TXOK2) >> 16); + state |= (uint8_t)((CANx->TSR & TSR_TME2) >> 28); + break; + default: + state = CANTXFAILED; + break; + } + switch (state) + { + /* transmit pending */ + case (0x0): state = CANTXPENDING; + break; + /* transmit failed */ + case (0x5): state = CANTXFAILED; + break; + /* transmit succedeed */ + case (0x7): state = CANTXOK; + break; + default: + state = CANTXFAILED; + break; + } + return state; +} + +/** + * @brief Cancels a transmit request. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param Mailbox: Mailbox number. + * @retval None. + */ +void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_TRANSMITMAILBOX(Mailbox)); + /* abort transmission */ + switch (Mailbox) + { + case (0): CANx->TSR |= TSR_ABRQ0; + break; + case (1): CANx->TSR |= TSR_ABRQ1; + break; + case (2): CANx->TSR |= TSR_ABRQ2; + break; + default: + break; + } +} + +/** + * @brief Releases a FIFO. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param FIFONumber: FIFO to release, CAN_FIFO0 or CAN_FIFO1. + * @retval None. + */ +void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_FIFO(FIFONumber)); + /* Release FIFO0 */ + if (FIFONumber == CAN_FIFO0) + { + CANx->RF0R = RF0R_RFOM0; + } + /* Release FIFO1 */ + else /* FIFONumber == CAN_FIFO1 */ + { + CANx->RF1R = RF1R_RFOM1; + } +} + +/** + * @brief Returns the number of pending messages. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1. + * @retval NbMessage which is the number of pending message. + */ +uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber) +{ + uint8_t message_pending=0; + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_FIFO(FIFONumber)); + if (FIFONumber == CAN_FIFO0) + { + message_pending = (uint8_t)(CANx->RF0R&(uint32_t)0x03); + } + else if (FIFONumber == CAN_FIFO1) + { + message_pending = (uint8_t)(CANx->RF1R&(uint32_t)0x03); + } + else + { + message_pending = 0; + } + return message_pending; +} + +/** + * @brief Receives a message. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1. + * @param RxMessage: pointer to a structure receive message which + * contains CAN Id, CAN DLC, CAN datas and FMI number. + * @retval None. + */ +void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_FIFO(FIFONumber)); + /* Get the Id */ + RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONumber].RIR; + if (RxMessage->IDE == CAN_ID_STD) + { + RxMessage->StdId = (uint32_t)0x000007FF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 21); + } + else + { + RxMessage->ExtId = (uint32_t)0x1FFFFFFF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 3); + } + + RxMessage->RTR = (uint8_t)0x02 & CANx->sFIFOMailBox[FIFONumber].RIR; + /* Get the DLC */ + RxMessage->DLC = (uint8_t)0x0F & CANx->sFIFOMailBox[FIFONumber].RDTR; + /* Get the FMI */ + RxMessage->FMI = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDTR >> 8); + /* Get the data field */ + RxMessage->Data[0] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDLR; + RxMessage->Data[1] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 8); + RxMessage->Data[2] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 16); + RxMessage->Data[3] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 24); + RxMessage->Data[4] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDHR; + RxMessage->Data[5] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 8); + RxMessage->Data[6] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 16); + RxMessage->Data[7] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 24); + /* Release the FIFO */ + CAN_FIFORelease(CANx, FIFONumber); +} + +/** + * @brief Enables or disables the DBG Freeze for CAN. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param NewState: new state of the CAN peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable Debug Freeze */ + CANx->MCR |= MCR_DBF; + } + else + { + /* Disable Debug Freeze */ + CANx->MCR &= ~MCR_DBF; + } +} + +/** + * @brief Enters the low power mode. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @retval CANSLEEPOK if sleep entered, CANSLEEPFAILED in an other case. + */ +uint8_t CAN_Sleep(CAN_TypeDef* CANx) +{ + uint8_t sleepstatus = CANSLEEPFAILED; + + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + + /* Request Sleep mode */ + CANx->MCR = (((CANx->MCR) & (uint32_t)(~MCR_INRQ)) | MCR_SLEEP); + + /* Sleep mode status */ + if ((CANx->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) == CAN_MSR_SLAK) + { + /* Sleep mode not entered */ + sleepstatus = CANSLEEPOK; + } + /* At this step, sleep mode status */ + return (uint8_t)sleepstatus; +} + +/** + * @brief Wakes the CAN up. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @retval CANWAKEUPOK if sleep mode left, CANWAKEUPFAILED in an other case. + */ +uint8_t CAN_WakeUp(CAN_TypeDef* CANx) +{ + uint32_t wait_slak = SLAK_TimeOut ; + uint8_t wakeupstatus = CANWAKEUPFAILED; + + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + + /* Wake up request */ + CANx->MCR &= ~MCR_SLEEP; + + /* Sleep mode status */ + while(((CANx->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)&&(wait_slak!=0x00)) + { + wait_slak--; + } + if((CANx->MSR & CAN_MSR_SLAK) != CAN_MSR_SLAK) + { + /* Sleep mode exited */ + wakeupstatus = CANWAKEUPOK; + } + /* At this step, sleep mode status */ + return (uint8_t)wakeupstatus; +} + +/** + * @brief Checks whether the specified CAN flag is set or not. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param CAN_FLAG: specifies the flag to check. + * This parameter can be: CAN_FLAG_EWG, CAN_FLAG_EPV or CAN_FLAG_BOF. + * @retval The new state of CAN_FLAG (SET or RESET). + */ +FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_FLAG(CAN_FLAG)); + /* Check the status of the specified CAN flag */ + if ((CANx->ESR & CAN_FLAG) != (uint32_t)RESET) + { + /* CAN_FLAG is set */ + bitstatus = SET; + } + else + { + /* CAN_FLAG is reset */ + bitstatus = RESET; + } + /* Return the CAN_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the CAN's pending flags. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param CAN_FLAG: specifies the flag to clear. + * @retval None. + */ +void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_FLAG(CAN_FLAG)); + /* Clear the selected CAN flags */ + CANx->ESR &= ~CAN_FLAG; +} + +/** + * @brief Checks whether the specified CAN interrupt has occurred or not. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param CAN_IT: specifies the CAN interrupt source to check. + * This parameter can be: CAN_IT_RQCP0, CAN_IT_RQCP1, CAN_IT_RQCP2, + * CAN_IT_FF0, CAN_IT_FOV0, CAN_IT_FF1, + * CAN_IT_FOV1, CAN_IT_EWG, CAN_IT_EPV, + * CAN_IT_BOF, CAN_IT_WKU or CAN_IT_SLK. + * @retval The new state of CAN_IT (SET or RESET). + */ +ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT) +{ + ITStatus pendingbitstatus = RESET; + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_ITStatus(CAN_IT)); + switch (CAN_IT) + { + case CAN_IT_RQCP0: + pendingbitstatus = CheckITStatus(CANx->TSR, TSR_RQCP0); + break; + case CAN_IT_RQCP1: + pendingbitstatus = CheckITStatus(CANx->TSR, TSR_RQCP1); + break; + case CAN_IT_RQCP2: + pendingbitstatus = CheckITStatus(CANx->TSR, TSR_RQCP2); + break; + case CAN_IT_FF0: + pendingbitstatus = CheckITStatus(CANx->RF0R, RF0R_FULL0); + break; + case CAN_IT_FOV0: + pendingbitstatus = CheckITStatus(CANx->RF0R, RF0R_FOVR0); + break; + case CAN_IT_FF1: + pendingbitstatus = CheckITStatus(CANx->RF1R, RF1R_FULL1); + break; + case CAN_IT_FOV1: + pendingbitstatus = CheckITStatus(CANx->RF1R, RF1R_FOVR1); + break; + case CAN_IT_EWG: + pendingbitstatus = CheckITStatus(CANx->ESR, ESR_EWGF); + break; + case CAN_IT_EPV: + pendingbitstatus = CheckITStatus(CANx->ESR, ESR_EPVF); + break; + case CAN_IT_BOF: + pendingbitstatus = CheckITStatus(CANx->ESR, ESR_BOFF); + break; + case CAN_IT_SLK: + pendingbitstatus = CheckITStatus(CANx->MSR, MSR_SLAKI); + break; + case CAN_IT_WKU: + pendingbitstatus = CheckITStatus(CANx->MSR, MSR_WKUI); + break; + default : + pendingbitstatus = RESET; + break; + } + /* Return the CAN_IT status */ + return pendingbitstatus; +} + +/** + * @brief Clears the CANs interrupt pending bits. + * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. + * @param CAN_IT: specifies the interrupt pending bit to clear. + * @retval None. + */ +void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT) +{ + /* Check the parameters */ + assert_param(IS_CAN_ALL_PERIPH(CANx)); + assert_param(IS_CAN_ITStatus(CAN_IT)); + switch (CAN_IT) + { + case CAN_IT_RQCP0: + CANx->TSR = TSR_RQCP0; /* rc_w1*/ + break; + case CAN_IT_RQCP1: + CANx->TSR = TSR_RQCP1; /* rc_w1*/ + break; + case CAN_IT_RQCP2: + CANx->TSR = TSR_RQCP2; /* rc_w1*/ + break; + case CAN_IT_FF0: + CANx->RF0R = RF0R_FULL0; /* rc_w1*/ + break; + case CAN_IT_FOV0: + CANx->RF0R = RF0R_FOVR0; /* rc_w1*/ + break; + case CAN_IT_FF1: + CANx->RF1R = RF1R_FULL1; /* rc_w1*/ + break; + case CAN_IT_FOV1: + CANx->RF1R = RF1R_FOVR1; /* rc_w1*/ + break; + case CAN_IT_EWG: + CANx->ESR &= ~ ESR_EWGF; /* rw */ + break; + case CAN_IT_EPV: + CANx->ESR &= ~ ESR_EPVF; /* rw */ + break; + case CAN_IT_BOF: + CANx->ESR &= ~ ESR_BOFF; /* rw */ + break; + case CAN_IT_WKU: + CANx->MSR = MSR_WKUI; /* rc_w1*/ + break; + case CAN_IT_SLK: + CANx->MSR = MSR_SLAKI; /* rc_w1*/ + break; + default : + break; + } +} + +/** + * @brief Checks whether the CAN interrupt has occurred or not. + * @param CAN_Reg: specifies the CAN interrupt register to check. + * @param It_Bit: specifies the interrupt source bit to check. + * @retval The new state of the CAN Interrupt (SET or RESET). + */ +static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit) +{ + ITStatus pendingbitstatus = RESET; + + if ((CAN_Reg & It_Bit) != (uint32_t)RESET) + { + /* CAN_IT is set */ + pendingbitstatus = SET; + } + else + { + /* CAN_IT is reset */ + pendingbitstatus = RESET; + } + return pendingbitstatus; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_cec.c b/example/libs_stm/src/stm32f10x/stm32f10x_cec.c new file mode 100644 index 000000000..4ae244569 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_cec.c @@ -0,0 +1,432 @@ +/** + ****************************************************************************** + * @file stm32f10x_cec.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the CEC firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_cec.h" +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup CEC + * @brief CEC driver modules + * @{ + */ + +/** @defgroup CEC_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + + +/** @defgroup CEC_Private_Defines + * @{ + */ + +/* ------------ CEC registers bit address in the alias region ----------- */ +#define CEC_OFFSET (CEC_BASE - PERIPH_BASE) + +/* --- CFGR Register ---*/ + +/* Alias word address of PE bit */ +#define CFGR_OFFSET (CEC_OFFSET + 0x00) +#define PE_BitNumber 0x00 +#define CFGR_PE_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (PE_BitNumber * 4)) + +/* Alias word address of IE bit */ +#define IE_BitNumber 0x01 +#define CFGR_IE_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (IE_BitNumber * 4)) + +/* --- CSR Register ---*/ + +/* Alias word address of TSOM bit */ +#define CSR_OFFSET (CEC_OFFSET + 0x10) +#define TSOM_BitNumber 0x00 +#define CSR_TSOM_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (TSOM_BitNumber * 4)) + +/* Alias word address of TEOM bit */ +#define TEOM_BitNumber 0x01 +#define CSR_TEOM_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (TEOM_BitNumber * 4)) + +#define CFGR_CLEAR_Mask (uint8_t)(0xF3) /* CFGR register Mask */ +#define FLAG_Mask ((uint32_t)0x00FFFFFF) /* CEC FLAG mask */ + +/** + * @} + */ + + +/** @defgroup CEC_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup CEC_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup CEC_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + + +/** @defgroup CEC_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the CEC peripheral registers to their default reset + * values. + * @param None + * @retval None + */ +void CEC_DeInit(void) +{ + /* Enable CEC reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_CEC, ENABLE); + /* Release CEC from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_CEC, DISABLE); +} + + +/** + * @brief Initializes the CEC peripheral according to the specified + * parameters in the CEC_InitStruct. + * @param CEC_InitStruct: pointer to an CEC_InitTypeDef structure that + * contains the configuration information for the specified + * CEC peripheral. + * @retval None + */ +void CEC_Init(CEC_InitTypeDef* CEC_InitStruct) +{ + uint16_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_CEC_BIT_TIMING_ERROR_MODE(CEC_InitStruct->CEC_BitTimingMode)); + assert_param(IS_CEC_BIT_PERIOD_ERROR_MODE(CEC_InitStruct->CEC_BitPeriodMode)); + + /*---------------------------- CEC CFGR Configuration -----------------*/ + /* Get the CEC CFGR value */ + tmpreg = CEC->CFGR; + + /* Clear BTEM and BPEM bits */ + tmpreg &= CFGR_CLEAR_Mask; + + /* Configure CEC: Bit Timing Error and Bit Period Error */ + tmpreg |= (uint16_t)(CEC_InitStruct->CEC_BitTimingMode | CEC_InitStruct->CEC_BitPeriodMode); + + /* Write to CEC CFGR register*/ + CEC->CFGR = tmpreg; + +} + +/** + * @brief Enables or disables the specified CEC peripheral. + * @param NewState: new state of the CEC peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void CEC_Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CFGR_PE_BB = (uint32_t)NewState; + + if(NewState == DISABLE) + { + /* Wait until the PE bit is cleared by hardware (Idle Line detected) */ + while((CEC->CFGR & CEC_CFGR_PE) != (uint32_t)RESET) + { + } + } +} + +/** + * @brief Enables or disables the CEC interrupt. + * @param NewState: new state of the CEC interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void CEC_ITConfig(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CFGR_IE_BB = (uint32_t)NewState; +} + +/** + * @brief Defines the Own Address of the CEC device. + * @param CEC_OwnAddress: The CEC own address + * @retval None + */ +void CEC_OwnAddressConfig(uint8_t CEC_OwnAddress) +{ + /* Check the parameters */ + assert_param(IS_CEC_ADDRESS(CEC_OwnAddress)); + + /* Set the CEC own address */ + CEC->OAR = CEC_OwnAddress; +} + +/** + * @brief Sets the CEC prescaler value. + * @param CEC_Prescaler: CEC prescaler new value + * @retval None + */ +void CEC_SetPrescaler(uint16_t CEC_Prescaler) +{ + /* Check the parameters */ + assert_param(IS_CEC_PRESCALER(CEC_Prescaler)); + + /* Set the Prescaler value*/ + CEC->PRES = CEC_Prescaler; +} + +/** + * @brief Transmits single data through the CEC peripheral. + * @param Data: the data to transmit. + * @retval None + */ +void CEC_SendDataByte(uint8_t Data) +{ + /* Transmit Data */ + CEC->TXD = Data ; +} + + +/** + * @brief Returns the most recent received data by the CEC peripheral. + * @param None + * @retval The received data. + */ +uint8_t CEC_ReceiveDataByte(void) +{ + /* Receive Data */ + return (uint8_t)(CEC->RXD); +} + +/** + * @brief Starts a new message. + * @param None + * @retval None + */ +void CEC_StartOfMessage(void) +{ + /* Starts of new message */ + *(__IO uint32_t *) CSR_TSOM_BB = (uint32_t)0x1; +} + +/** + * @brief Transmits message with or without an EOM bit. + * @param NewState: new state of the CEC Tx End Of Message. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void CEC_EndOfMessageCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + /* The data byte will be transmitted with or without an EOM bit*/ + *(__IO uint32_t *) CSR_TEOM_BB = (uint32_t)NewState; +} + +/** + * @brief Gets the CEC flag status + * @param CEC_FLAG: specifies the CEC flag to check. + * This parameter can be one of the following values: + * @arg CEC_FLAG_BTE: Bit Timing Error + * @arg CEC_FLAG_BPE: Bit Period Error + * @arg CEC_FLAG_RBTFE: Rx Block Transfer Finished Error + * @arg CEC_FLAG_SBE: Start Bit Error + * @arg CEC_FLAG_ACKE: Block Acknowledge Error + * @arg CEC_FLAG_LINE: Line Error + * @arg CEC_FLAG_TBTFE: Tx Block Transfer Finsihed Error + * @arg CEC_FLAG_TEOM: Tx End Of Message + * @arg CEC_FLAG_TERR: Tx Error + * @arg CEC_FLAG_TBTRF: Tx Byte Transfer Request or Block Transfer Finished + * @arg CEC_FLAG_RSOM: Rx Start Of Message + * @arg CEC_FLAG_REOM: Rx End Of Message + * @arg CEC_FLAG_RERR: Rx Error + * @arg CEC_FLAG_RBTF: Rx Byte/Block Transfer Finished + * @retval The new state of CEC_FLAG (SET or RESET) + */ +FlagStatus CEC_GetFlagStatus(uint32_t CEC_FLAG) +{ + FlagStatus bitstatus = RESET; + uint32_t cecreg = 0, cecbase = 0; + + /* Check the parameters */ + assert_param(IS_CEC_GET_FLAG(CEC_FLAG)); + + /* Get the CEC peripheral base address */ + cecbase = (uint32_t)(CEC_BASE); + + /* Read flag register index */ + cecreg = CEC_FLAG >> 28; + + /* Get bit[23:0] of the flag */ + CEC_FLAG &= FLAG_Mask; + + if(cecreg != 0) + { + /* Flag in CEC ESR Register */ + CEC_FLAG = (uint32_t)(CEC_FLAG >> 16); + + /* Get the CEC ESR register address */ + cecbase += 0xC; + } + else + { + /* Get the CEC CSR register address */ + cecbase += 0x10; + } + + if(((*(__IO uint32_t *)cecbase) & CEC_FLAG) != (uint32_t)RESET) + { + /* CEC_FLAG is set */ + bitstatus = SET; + } + else + { + /* CEC_FLAG is reset */ + bitstatus = RESET; + } + + /* Return the CEC_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the CEC's pending flags. + * @param CEC_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg CEC_FLAG_TERR: Tx Error + * @arg CEC_FLAG_TBTRF: Tx Byte Transfer Request or Block Transfer Finished + * @arg CEC_FLAG_RSOM: Rx Start Of Message + * @arg CEC_FLAG_REOM: Rx End Of Message + * @arg CEC_FLAG_RERR: Rx Error + * @arg CEC_FLAG_RBTF: Rx Byte/Block Transfer Finished + * @retval None + */ +void CEC_ClearFlag(uint32_t CEC_FLAG) +{ + uint32_t tmp = 0x0; + + /* Check the parameters */ + assert_param(IS_CEC_CLEAR_FLAG(CEC_FLAG)); + + tmp = CEC->CSR & 0x2; + + /* Clear the selected CEC flags */ + CEC->CSR &= (uint32_t)(((~(uint32_t)CEC_FLAG) & 0xFFFFFFFC) | tmp); +} + +/** + * @brief Checks whether the specified CEC interrupt has occurred or not. + * @param CEC_IT: specifies the CEC interrupt source to check. + * This parameter can be one of the following values: + * @arg CEC_IT_TERR: Tx Error + * @arg CEC_IT_TBTF: Tx Block Transfer Finished + * @arg CEC_IT_RERR: Rx Error + * @arg CEC_IT_RBTF: Rx Block Transfer Finished + * @retval The new state of CEC_IT (SET or RESET). + */ +ITStatus CEC_GetITStatus(uint8_t CEC_IT) +{ + ITStatus bitstatus = RESET; + uint32_t enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_CEC_GET_IT(CEC_IT)); + + /* Get the CEC IT enable bit status */ + enablestatus = (CEC->CFGR & (uint8_t)CEC_CFGR_IE) ; + + /* Check the status of the specified CEC interrupt */ + if (((CEC->CSR & CEC_IT) != (uint32_t)RESET) && enablestatus) + { + /* CEC_IT is set */ + bitstatus = SET; + } + else + { + /* CEC_IT is reset */ + bitstatus = RESET; + } + /* Return the CEC_IT status */ + return bitstatus; +} + +/** + * @brief Clears the CEC's interrupt pending bits. + * @param CEC_IT: specifies the CEC interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg CEC_IT_TERR: Tx Error + * @arg CEC_IT_TBTF: Tx Block Transfer Finished + * @arg CEC_IT_RERR: Rx Error + * @arg CEC_IT_RBTF: Rx Block Transfer Finished + * @retval None + */ +void CEC_ClearITPendingBit(uint16_t CEC_IT) +{ + uint32_t tmp = 0x0; + + /* Check the parameters */ + assert_param(IS_CEC_GET_IT(CEC_IT)); + + tmp = CEC->CSR & 0x2; + + /* Clear the selected CEC interrupt pending bits */ + CEC->CSR &= (uint32_t)(((~(uint32_t)CEC_IT) & 0xFFFFFFFC) | tmp); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_crc.c b/example/libs_stm/src/stm32f10x/stm32f10x_crc.c new file mode 100644 index 000000000..c9291f4c4 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_crc.c @@ -0,0 +1,163 @@ +/** + ****************************************************************************** + * @file stm32f10x_crc.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the CRC firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_crc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup CRC + * @brief CRC driver modules + * @{ + */ + +/** @defgroup CRC_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup CRC_Private_Defines + * @{ + */ + +/* CR register bit mask */ + +#define CR_RESET_Set ((uint32_t)0x00000001) + +/** + * @} + */ + +/** @defgroup CRC_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup CRC_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup CRC_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup CRC_Private_Functions + * @{ + */ + +/** + * @brief Resets the CRC Data register (DR). + * @param None + * @retval None + */ +void CRC_ResetDR(void) +{ + /* Reset CRC generator */ + CRC->CR = CR_RESET_Set; +} + +/** + * @brief Computes the 32-bit CRC of a given data word(32-bit). + * @param Data: data word(32-bit) to compute its CRC + * @retval 32-bit CRC + */ +uint32_t CRC_CalcCRC(uint32_t Data) +{ + CRC->DR = Data; + + return (CRC->DR); +} + +/** + * @brief Computes the 32-bit CRC of a given buffer of data word(32-bit). + * @param pBuffer: pointer to the buffer containing the data to be computed + * @param BufferLength: length of the buffer to be computed + * @retval 32-bit CRC + */ +uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength) +{ + uint32_t index = 0; + + for(index = 0; index < BufferLength; index++) + { + CRC->DR = pBuffer[index]; + } + return (CRC->DR); +} + +/** + * @brief Returns the current CRC value. + * @param None + * @retval 32-bit CRC + */ +uint32_t CRC_GetCRC(void) +{ + return (CRC->DR); +} + +/** + * @brief Stores a 8-bit data in the Independent Data(ID) register. + * @param IDValue: 8-bit value to be stored in the ID register + * @retval None + */ +void CRC_SetIDRegister(uint8_t IDValue) +{ + CRC->IDR = IDValue; +} + +/** + * @brief Returns the 8-bit data stored in the Independent Data(ID) register + * @param None + * @retval 8-bit value of the ID register + */ +uint8_t CRC_GetIDRegister(void) +{ + return (CRC->IDR); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_dac.c b/example/libs_stm/src/stm32f10x/stm32f10x_dac.c new file mode 100644 index 000000000..e20b4a933 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_dac.c @@ -0,0 +1,579 @@ +/** + ****************************************************************************** + * @file stm32f10x_dac.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the DAC firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_dac.h" +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup DAC + * @brief DAC driver modules + * @{ + */ + +/** @defgroup DAC_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup DAC_Private_Defines + * @{ + */ + +/* DAC EN mask */ +#define CR_EN_Set ((uint32_t)0x00000001) + +/* DAC DMAEN mask */ +#define CR_DMAEN_Set ((uint32_t)0x00001000) + +/* CR register Mask */ +#define CR_CLEAR_Mask ((uint32_t)0x00000FFE) + +/* DAC SWTRIG mask */ +#define SWTRIGR_SWTRIG_Set ((uint32_t)0x00000001) + +/* DAC Dual Channels SWTRIG masks */ +#define DUAL_SWTRIG_Set ((uint32_t)0x00000003) +#define DUAL_SWTRIG_Reset ((uint32_t)0xFFFFFFFC) + +/* DHR registers offsets */ +#define DHR12R1_Offset ((uint32_t)0x00000008) +#define DHR12R2_Offset ((uint32_t)0x00000014) +#define DHR12RD_Offset ((uint32_t)0x00000020) + +/* DOR register offset */ +#define DOR_Offset ((uint32_t)0x0000002C) +/** + * @} + */ + +/** @defgroup DAC_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup DAC_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup DAC_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup DAC_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the DAC peripheral registers to their default reset values. + * @param None + * @retval None + */ +void DAC_DeInit(void) +{ + /* Enable DAC reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, ENABLE); + /* Release DAC from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, DISABLE); +} + +/** + * @brief Initializes the DAC peripheral according to the specified + * parameters in the DAC_InitStruct. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure that + * contains the configuration information for the specified DAC channel. + * @retval None + */ +void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct) +{ + uint32_t tmpreg1 = 0, tmpreg2 = 0; + /* Check the DAC parameters */ + assert_param(IS_DAC_TRIGGER(DAC_InitStruct->DAC_Trigger)); + assert_param(IS_DAC_GENERATE_WAVE(DAC_InitStruct->DAC_WaveGeneration)); + assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude)); + assert_param(IS_DAC_OUTPUT_BUFFER_STATE(DAC_InitStruct->DAC_OutputBuffer)); +/*---------------------------- DAC CR Configuration --------------------------*/ + /* Get the DAC CR value */ + tmpreg1 = DAC->CR; + /* Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits */ + tmpreg1 &= ~(CR_CLEAR_Mask << DAC_Channel); + /* Configure for the selected DAC channel: buffer output, trigger, wave genration, + mask/amplitude for wave genration */ + /* Set TSELx and TENx bits according to DAC_Trigger value */ + /* Set WAVEx bits according to DAC_WaveGeneration value */ + /* Set MAMPx bits according to DAC_LFSRUnmask_TriangleAmplitude value */ + /* Set BOFFx bit according to DAC_OutputBuffer value */ + tmpreg2 = (DAC_InitStruct->DAC_Trigger | DAC_InitStruct->DAC_WaveGeneration | + DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude | DAC_InitStruct->DAC_OutputBuffer); + /* Calculate CR register value depending on DAC_Channel */ + tmpreg1 |= tmpreg2 << DAC_Channel; + /* Write to DAC CR */ + DAC->CR = tmpreg1; +} + +/** + * @brief Fills each DAC_InitStruct member with its default value. + * @param DAC_InitStruct : pointer to a DAC_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct) +{ +/*--------------- Reset DAC init structure parameters values -----------------*/ + /* Initialize the DAC_Trigger member */ + DAC_InitStruct->DAC_Trigger = DAC_Trigger_None; + /* Initialize the DAC_WaveGeneration member */ + DAC_InitStruct->DAC_WaveGeneration = DAC_WaveGeneration_None; + /* Initialize the DAC_LFSRUnmask_TriangleAmplitude member */ + DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; + /* Initialize the DAC_OutputBuffer member */ + DAC_InitStruct->DAC_OutputBuffer = DAC_OutputBuffer_Enable; +} + +/** + * @brief Enables or disables the specified DAC channel. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param NewState: new state of the DAC channel. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected DAC channel */ + DAC->CR |= CR_EN_Set << DAC_Channel; + } + else + { + /* Disable the selected DAC channel */ + DAC->CR &= ~(CR_EN_Set << DAC_Channel); + } +} +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) +/** + * @brief Enables or disables the specified DAC interrupts. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_IT: specifies the DAC interrupt sources to be enabled or disabled. + * This parameter can be the following values: + * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask + * @param NewState: new state of the specified DAC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_DAC_IT(DAC_IT)); + + if (NewState != DISABLE) + { + /* Enable the selected DAC interrupts */ + DAC->CR |= (DAC_IT << DAC_Channel); + } + else + { + /* Disable the selected DAC interrupts */ + DAC->CR &= (~(uint32_t)(DAC_IT << DAC_Channel)); + } +} +#endif + +/** + * @brief Enables or disables the specified DAC channel DMA request. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param NewState: new state of the selected DAC channel DMA request. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected DAC channel DMA request */ + DAC->CR |= CR_DMAEN_Set << DAC_Channel; + } + else + { + /* Disable the selected DAC channel DMA request */ + DAC->CR &= ~(CR_DMAEN_Set << DAC_Channel); + } +} + +/** + * @brief Enables or disables the selected DAC channel software trigger. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param NewState: new state of the selected DAC channel software trigger. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable software trigger for the selected DAC channel */ + DAC->SWTRIGR |= SWTRIGR_SWTRIG_Set << (DAC_Channel >> 4); + } + else + { + /* Disable software trigger for the selected DAC channel */ + DAC->SWTRIGR &= ~(SWTRIGR_SWTRIG_Set << (DAC_Channel >> 4)); + } +} + +/** + * @brief Enables or disables simultaneously the two DAC channels software + * triggers. + * @param NewState: new state of the DAC channels software triggers. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DAC_DualSoftwareTriggerCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable software trigger for both DAC channels */ + DAC->SWTRIGR |= DUAL_SWTRIG_Set ; + } + else + { + /* Disable software trigger for both DAC channels */ + DAC->SWTRIGR &= DUAL_SWTRIG_Reset; + } +} + +/** + * @brief Enables or disables the selected DAC channel wave generation. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_Wave: Specifies the wave type to enable or disable. + * This parameter can be one of the following values: + * @arg DAC_Wave_Noise: noise wave generation + * @arg DAC_Wave_Triangle: triangle wave generation + * @param NewState: new state of the selected DAC channel wave generation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_WAVE(DAC_Wave)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected wave generation for the selected DAC channel */ + DAC->CR |= DAC_Wave << DAC_Channel; + } + else + { + /* Disable the selected wave generation for the selected DAC channel */ + DAC->CR &= ~(DAC_Wave << DAC_Channel); + } +} + +/** + * @brief Set the specified data holding register value for DAC channel1. + * @param DAC_Align: Specifies the data alignement for DAC channel1. + * This parameter can be one of the following values: + * @arg DAC_Align_8b_R: 8bit right data alignement selected + * @arg DAC_Align_12b_L: 12bit left data alignement selected + * @arg DAC_Align_12b_R: 12bit right data alignement selected + * @param Data : Data to be loaded in the selected data holding register. + * @retval None + */ +void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_DAC_ALIGN(DAC_Align)); + assert_param(IS_DAC_DATA(Data)); + + tmp = (uint32_t)DAC_BASE; + tmp += DHR12R1_Offset + DAC_Align; + + /* Set the DAC channel1 selected data holding register */ + *(__IO uint32_t *) tmp = Data; +} + +/** + * @brief Set the specified data holding register value for DAC channel2. + * @param DAC_Align: Specifies the data alignement for DAC channel2. + * This parameter can be one of the following values: + * @arg DAC_Align_8b_R: 8bit right data alignement selected + * @arg DAC_Align_12b_L: 12bit left data alignement selected + * @arg DAC_Align_12b_R: 12bit right data alignement selected + * @param Data : Data to be loaded in the selected data holding register. + * @retval None + */ +void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_DAC_ALIGN(DAC_Align)); + assert_param(IS_DAC_DATA(Data)); + + tmp = (uint32_t)DAC_BASE; + tmp += DHR12R2_Offset + DAC_Align; + + /* Set the DAC channel2 selected data holding register */ + *(__IO uint32_t *)tmp = Data; +} + +/** + * @brief Set the specified data holding register value for dual channel + * DAC. + * @param DAC_Align: Specifies the data alignement for dual channel DAC. + * This parameter can be one of the following values: + * @arg DAC_Align_8b_R: 8bit right data alignement selected + * @arg DAC_Align_12b_L: 12bit left data alignement selected + * @arg DAC_Align_12b_R: 12bit right data alignement selected + * @param Data2: Data for DAC Channel2 to be loaded in the selected data + * holding register. + * @param Data1: Data for DAC Channel1 to be loaded in the selected data + * holding register. + * @retval None + */ +void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1) +{ + uint32_t data = 0, tmp = 0; + + /* Check the parameters */ + assert_param(IS_DAC_ALIGN(DAC_Align)); + assert_param(IS_DAC_DATA(Data1)); + assert_param(IS_DAC_DATA(Data2)); + + /* Calculate and set dual DAC data holding register value */ + if (DAC_Align == DAC_Align_8b_R) + { + data = ((uint32_t)Data2 << 8) | Data1; + } + else + { + data = ((uint32_t)Data2 << 16) | Data1; + } + + tmp = (uint32_t)DAC_BASE; + tmp += DHR12RD_Offset + DAC_Align; + + /* Set the dual DAC selected data holding register */ + *(__IO uint32_t *)tmp = data; +} + +/** + * @brief Returns the last data output value of the selected DAC cahnnel. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @retval The selected DAC channel data output value. + */ +uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + + tmp = (uint32_t) DAC_BASE ; + tmp += DOR_Offset + ((uint32_t)DAC_Channel >> 2); + + /* Returns the DAC channel data output register value */ + return (uint16_t) (*(__IO uint32_t*) tmp); +} + +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) +/** + * @brief Checks whether the specified DAC flag is set or not. + * @param DAC_Channel: thee selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_FLAG: specifies the flag to check. + * This parameter can be only of the following value: + * @arg DAC_FLAG_DMAUDR: DMA underrun flag + * @retval The new state of DAC_FLAG (SET or RESET). + */ +FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_FLAG(DAC_FLAG)); + + /* Check the status of the specified DAC flag */ + if ((DAC->SR & (DAC_FLAG << DAC_Channel)) != (uint8_t)RESET) + { + /* DAC_FLAG is set */ + bitstatus = SET; + } + else + { + /* DAC_FLAG is reset */ + bitstatus = RESET; + } + /* Return the DAC_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the DAC channelx's pending flags. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_FLAG: specifies the flag to clear. + * This parameter can be of the following value: + * @arg DAC_FLAG_DMAUDR: DMA underrun flag + * @retval None + */ +void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_FLAG(DAC_FLAG)); + + /* Clear the selected DAC flags */ + DAC->SR = (DAC_FLAG << DAC_Channel); +} + +/** + * @brief Checks whether the specified DAC interrupt has occurred or not. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_IT: specifies the DAC interrupt source to check. + * This parameter can be the following values: + * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask + * @retval The new state of DAC_IT (SET or RESET). + */ +ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT) +{ + ITStatus bitstatus = RESET; + uint32_t enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_IT(DAC_IT)); + + /* Get the DAC_IT enable bit status */ + enablestatus = (DAC->CR & (DAC_IT << DAC_Channel)) ; + + /* Check the status of the specified DAC interrupt */ + if (((DAC->SR & (DAC_IT << DAC_Channel)) != (uint32_t)RESET) && enablestatus) + { + /* DAC_IT is set */ + bitstatus = SET; + } + else + { + /* DAC_IT is reset */ + bitstatus = RESET; + } + /* Return the DAC_IT status */ + return bitstatus; +} + +/** + * @brief Clears the DAC channelxs interrupt pending bits. + * @param DAC_Channel: the selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_Channel_1: DAC Channel1 selected + * @arg DAC_Channel_2: DAC Channel2 selected + * @param DAC_IT: specifies the DAC interrupt pending bit to clear. + * This parameter can be the following values: + * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask + * @retval None + */ +void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_DAC_IT(DAC_IT)); + + /* Clear the selected DAC interrupt pending bits */ + DAC->SR = (DAC_IT << DAC_Channel); +} +#endif + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_dbgmcu.c b/example/libs_stm/src/stm32f10x/stm32f10x_dbgmcu.c new file mode 100644 index 000000000..6cfceba07 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_dbgmcu.c @@ -0,0 +1,161 @@ +/** + ****************************************************************************** + * @file stm32f10x_dbgmcu.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the DBGMCU firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_dbgmcu.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup DBGMCU + * @brief DBGMCU driver modules + * @{ + */ + +/** @defgroup DBGMCU_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup DBGMCU_Private_Defines + * @{ + */ + +#define IDCODE_DEVID_Mask ((uint32_t)0x00000FFF) +/** + * @} + */ + +/** @defgroup DBGMCU_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup DBGMCU_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup DBGMCU_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup DBGMCU_Private_Functions + * @{ + */ + +/** + * @brief Returns the device revision identifier. + * @param None + * @retval Device revision identifier + */ +uint32_t DBGMCU_GetREVID(void) +{ + return(DBGMCU->IDCODE >> 16); +} + +/** + * @brief Returns the device identifier. + * @param None + * @retval Device identifier + */ +uint32_t DBGMCU_GetDEVID(void) +{ + return(DBGMCU->IDCODE & IDCODE_DEVID_Mask); +} + +/** + * @brief Configures the specified peripheral and low power mode behavior + * when the MCU under Debug mode. + * @param DBGMCU_Periph: specifies the peripheral and low power mode. + * This parameter can be any combination of the following values: + * @arg DBGMCU_SLEEP: Keep debugger connection during SLEEP mode + * @arg DBGMCU_STOP: Keep debugger connection during STOP mode + * @arg DBGMCU_STANDBY: Keep debugger connection during STANDBY mode + * @arg DBGMCU_IWDG_STOP: Debug IWDG stopped when Core is halted + * @arg DBGMCU_WWDG_STOP: Debug WWDG stopped when Core is halted + * @arg DBGMCU_TIM1_STOP: TIM1 counter stopped when Core is halted + * @arg DBGMCU_TIM2_STOP: TIM2 counter stopped when Core is halted + * @arg DBGMCU_TIM3_STOP: TIM3 counter stopped when Core is halted + * @arg DBGMCU_TIM4_STOP: TIM4 counter stopped when Core is halted + * @arg DBGMCU_CAN1_STOP: Debug CAN2 stopped when Core is halted + * @arg DBGMCU_I2C1_SMBUS_TIMEOUT: I2C1 SMBUS timeout mode stopped when Core is halted + * @arg DBGMCU_I2C2_SMBUS_TIMEOUT: I2C2 SMBUS timeout mode stopped when Core is halted + * @arg DBGMCU_TIM5_STOP: TIM5 counter stopped when Core is halted + * @arg DBGMCU_TIM6_STOP: TIM6 counter stopped when Core is halted + * @arg DBGMCU_TIM7_STOP: TIM7 counter stopped when Core is halted + * @arg DBGMCU_TIM8_STOP: TIM8 counter stopped when Core is halted + * @arg DBGMCU_CAN2_STOP: Debug CAN2 stopped when Core is halted + * @arg DBGMCU_TIM15_STOP: TIM15 counter stopped when Core is halted + * @arg DBGMCU_TIM16_STOP: TIM16 counter stopped when Core is halted + * @arg DBGMCU_TIM17_STOP: TIM17 counter stopped when Core is halted + * @arg DBGMCU_TIM9_STOP: TIM9 counter stopped when Core is halted + * @arg DBGMCU_TIM10_STOP: TIM10 counter stopped when Core is halted + * @arg DBGMCU_TIM11_STOP: TIM11 counter stopped when Core is halted + * @arg DBGMCU_TIM12_STOP: TIM12 counter stopped when Core is halted + * @arg DBGMCU_TIM13_STOP: TIM13 counter stopped when Core is halted + * @arg DBGMCU_TIM14_STOP: TIM14 counter stopped when Core is halted + * @param NewState: new state of the specified peripheral in Debug mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DBGMCU_PERIPH(DBGMCU_Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + DBGMCU->CR |= DBGMCU_Periph; + } + else + { + DBGMCU->CR &= ~DBGMCU_Periph; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_dma.c b/example/libs_stm/src/stm32f10x/stm32f10x_dma.c new file mode 100644 index 000000000..aa890c6a6 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_dma.c @@ -0,0 +1,693 @@ +/** + ****************************************************************************** + * @file stm32f10x_dma.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the DMA firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_dma.h" +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup DMA + * @brief DMA driver modules + * @{ + */ + +/** @defgroup DMA_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + +/** @defgroup DMA_Private_Defines + * @{ + */ + +/* DMA ENABLE mask */ +#define CCR_ENABLE_Set ((uint32_t)0x00000001) +#define CCR_ENABLE_Reset ((uint32_t)0xFFFFFFFE) + +/* DMA1 Channelx interrupt pending bit masks */ +#define DMA1_Channel1_IT_Mask ((uint32_t)0x0000000F) +#define DMA1_Channel2_IT_Mask ((uint32_t)0x000000F0) +#define DMA1_Channel3_IT_Mask ((uint32_t)0x00000F00) +#define DMA1_Channel4_IT_Mask ((uint32_t)0x0000F000) +#define DMA1_Channel5_IT_Mask ((uint32_t)0x000F0000) +#define DMA1_Channel6_IT_Mask ((uint32_t)0x00F00000) +#define DMA1_Channel7_IT_Mask ((uint32_t)0x0F000000) + +/* DMA2 Channelx interrupt pending bit masks */ +#define DMA2_Channel1_IT_Mask ((uint32_t)0x0000000F) +#define DMA2_Channel2_IT_Mask ((uint32_t)0x000000F0) +#define DMA2_Channel3_IT_Mask ((uint32_t)0x00000F00) +#define DMA2_Channel4_IT_Mask ((uint32_t)0x0000F000) +#define DMA2_Channel5_IT_Mask ((uint32_t)0x000F0000) + +/* DMA2 FLAG mask */ +#define FLAG_Mask ((uint32_t)0x10000000) + +/* DMA registers Masks */ +#define CCR_CLEAR_Mask ((uint32_t)0xFFFF800F) + +/** + * @} + */ + +/** @defgroup DMA_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup DMA_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup DMA_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup DMA_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the DMAy Channelx registers to their default reset + * values. + * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and + * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. + * @retval None + */ +void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + /* Disable the selected DMAy Channelx */ + DMAy_Channelx->CCR &= CCR_ENABLE_Reset; + /* Reset DMAy Channelx control register */ + DMAy_Channelx->CCR = 0; + + /* Reset DMAy Channelx remaining bytes register */ + DMAy_Channelx->CNDTR = 0; + + /* Reset DMAy Channelx peripheral address register */ + DMAy_Channelx->CPAR = 0; + + /* Reset DMAy Channelx memory address register */ + DMAy_Channelx->CMAR = 0; + + if (DMAy_Channelx == DMA1_Channel1) + { + /* Reset interrupt pending bits for DMA1 Channel1 */ + DMA1->IFCR |= DMA1_Channel1_IT_Mask; + } + else if (DMAy_Channelx == DMA1_Channel2) + { + /* Reset interrupt pending bits for DMA1 Channel2 */ + DMA1->IFCR |= DMA1_Channel2_IT_Mask; + } + else if (DMAy_Channelx == DMA1_Channel3) + { + /* Reset interrupt pending bits for DMA1 Channel3 */ + DMA1->IFCR |= DMA1_Channel3_IT_Mask; + } + else if (DMAy_Channelx == DMA1_Channel4) + { + /* Reset interrupt pending bits for DMA1 Channel4 */ + DMA1->IFCR |= DMA1_Channel4_IT_Mask; + } + else if (DMAy_Channelx == DMA1_Channel5) + { + /* Reset interrupt pending bits for DMA1 Channel5 */ + DMA1->IFCR |= DMA1_Channel5_IT_Mask; + } + else if (DMAy_Channelx == DMA1_Channel6) + { + /* Reset interrupt pending bits for DMA1 Channel6 */ + DMA1->IFCR |= DMA1_Channel6_IT_Mask; + } + else if (DMAy_Channelx == DMA1_Channel7) + { + /* Reset interrupt pending bits for DMA1 Channel7 */ + DMA1->IFCR |= DMA1_Channel7_IT_Mask; + } + else if (DMAy_Channelx == DMA2_Channel1) + { + /* Reset interrupt pending bits for DMA2 Channel1 */ + DMA2->IFCR |= DMA2_Channel1_IT_Mask; + } + else if (DMAy_Channelx == DMA2_Channel2) + { + /* Reset interrupt pending bits for DMA2 Channel2 */ + DMA2->IFCR |= DMA2_Channel2_IT_Mask; + } + else if (DMAy_Channelx == DMA2_Channel3) + { + /* Reset interrupt pending bits for DMA2 Channel3 */ + DMA2->IFCR |= DMA2_Channel3_IT_Mask; + } + else if (DMAy_Channelx == DMA2_Channel4) + { + /* Reset interrupt pending bits for DMA2 Channel4 */ + DMA2->IFCR |= DMA2_Channel4_IT_Mask; + } + else + { + if (DMAy_Channelx == DMA2_Channel5) + { + /* Reset interrupt pending bits for DMA2 Channel5 */ + DMA2->IFCR |= DMA2_Channel5_IT_Mask; + } + } +} + +/** + * @brief Initializes the DMAy Channelx according to the specified + * parameters in the DMA_InitStruct. + * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and + * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. + * @param DMA_InitStruct: pointer to a DMA_InitTypeDef structure that + * contains the configuration information for the specified DMA Channel. + * @retval None + */ +void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + assert_param(IS_DMA_DIR(DMA_InitStruct->DMA_DIR)); + assert_param(IS_DMA_BUFFER_SIZE(DMA_InitStruct->DMA_BufferSize)); + assert_param(IS_DMA_PERIPHERAL_INC_STATE(DMA_InitStruct->DMA_PeripheralInc)); + assert_param(IS_DMA_MEMORY_INC_STATE(DMA_InitStruct->DMA_MemoryInc)); + assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(DMA_InitStruct->DMA_PeripheralDataSize)); + assert_param(IS_DMA_MEMORY_DATA_SIZE(DMA_InitStruct->DMA_MemoryDataSize)); + assert_param(IS_DMA_MODE(DMA_InitStruct->DMA_Mode)); + assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority)); + assert_param(IS_DMA_M2M_STATE(DMA_InitStruct->DMA_M2M)); + +/*--------------------------- DMAy Channelx CCR Configuration -----------------*/ + /* Get the DMAy_Channelx CCR value */ + tmpreg = DMAy_Channelx->CCR; + /* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */ + tmpreg &= CCR_CLEAR_Mask; + /* Configure DMAy Channelx: data transfer, data size, priority level and mode */ + /* Set DIR bit according to DMA_DIR value */ + /* Set CIRC bit according to DMA_Mode value */ + /* Set PINC bit according to DMA_PeripheralInc value */ + /* Set MINC bit according to DMA_MemoryInc value */ + /* Set PSIZE bits according to DMA_PeripheralDataSize value */ + /* Set MSIZE bits according to DMA_MemoryDataSize value */ + /* Set PL bits according to DMA_Priority value */ + /* Set the MEM2MEM bit according to DMA_M2M value */ + tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode | + DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc | + DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize | + DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M; + + /* Write to DMAy Channelx CCR */ + DMAy_Channelx->CCR = tmpreg; + +/*--------------------------- DMAy Channelx CNDTR Configuration ---------------*/ + /* Write to DMAy Channelx CNDTR */ + DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize; + +/*--------------------------- DMAy Channelx CPAR Configuration ----------------*/ + /* Write to DMAy Channelx CPAR */ + DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr; + +/*--------------------------- DMAy Channelx CMAR Configuration ----------------*/ + /* Write to DMAy Channelx CMAR */ + DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr; +} + +/** + * @brief Fills each DMA_InitStruct member with its default value. + * @param DMA_InitStruct : pointer to a DMA_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct) +{ +/*-------------- Reset DMA init structure parameters values ------------------*/ + /* Initialize the DMA_PeripheralBaseAddr member */ + DMA_InitStruct->DMA_PeripheralBaseAddr = 0; + /* Initialize the DMA_MemoryBaseAddr member */ + DMA_InitStruct->DMA_MemoryBaseAddr = 0; + /* Initialize the DMA_DIR member */ + DMA_InitStruct->DMA_DIR = DMA_DIR_PeripheralSRC; + /* Initialize the DMA_BufferSize member */ + DMA_InitStruct->DMA_BufferSize = 0; + /* Initialize the DMA_PeripheralInc member */ + DMA_InitStruct->DMA_PeripheralInc = DMA_PeripheralInc_Disable; + /* Initialize the DMA_MemoryInc member */ + DMA_InitStruct->DMA_MemoryInc = DMA_MemoryInc_Disable; + /* Initialize the DMA_PeripheralDataSize member */ + DMA_InitStruct->DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + /* Initialize the DMA_MemoryDataSize member */ + DMA_InitStruct->DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + /* Initialize the DMA_Mode member */ + DMA_InitStruct->DMA_Mode = DMA_Mode_Normal; + /* Initialize the DMA_Priority member */ + DMA_InitStruct->DMA_Priority = DMA_Priority_Low; + /* Initialize the DMA_M2M member */ + DMA_InitStruct->DMA_M2M = DMA_M2M_Disable; +} + +/** + * @brief Enables or disables the specified DMAy Channelx. + * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and + * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. + * @param NewState: new state of the DMAy Channelx. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected DMAy Channelx */ + DMAy_Channelx->CCR |= CCR_ENABLE_Set; + } + else + { + /* Disable the selected DMAy Channelx */ + DMAy_Channelx->CCR &= CCR_ENABLE_Reset; + } +} + +/** + * @brief Enables or disables the specified DMAy Channelx interrupts. + * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and + * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. + * @param DMA_IT: specifies the DMA interrupts sources to be enabled + * or disabled. + * This parameter can be any combination of the following values: + * @arg DMA_IT_TC: Transfer complete interrupt mask + * @arg DMA_IT_HT: Half transfer interrupt mask + * @arg DMA_IT_TE: Transfer error interrupt mask + * @param NewState: new state of the specified DMA interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + assert_param(IS_DMA_CONFIG_IT(DMA_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected DMA interrupts */ + DMAy_Channelx->CCR |= DMA_IT; + } + else + { + /* Disable the selected DMA interrupts */ + DMAy_Channelx->CCR &= ~DMA_IT; + } +} + +/** + * @brief Returns the number of remaining data units in the current + * DMAy Channelx transfer. + * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and + * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. + * @retval The number of remaining data units in the current DMAy Channelx + * transfer. + */ +uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx) +{ + /* Check the parameters */ + assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); + /* Return the number of remaining data units for DMAy Channelx */ + return ((uint16_t)(DMAy_Channelx->CNDTR)); +} + +/** + * @brief Checks whether the specified DMAy Channelx flag is set or not. + * @param DMA_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg DMA1_FLAG_GL1: DMA1 Channel1 global flag. + * @arg DMA1_FLAG_TC1: DMA1 Channel1 transfer complete flag. + * @arg DMA1_FLAG_HT1: DMA1 Channel1 half transfer flag. + * @arg DMA1_FLAG_TE1: DMA1 Channel1 transfer error flag. + * @arg DMA1_FLAG_GL2: DMA1 Channel2 global flag. + * @arg DMA1_FLAG_TC2: DMA1 Channel2 transfer complete flag. + * @arg DMA1_FLAG_HT2: DMA1 Channel2 half transfer flag. + * @arg DMA1_FLAG_TE2: DMA1 Channel2 transfer error flag. + * @arg DMA1_FLAG_GL3: DMA1 Channel3 global flag. + * @arg DMA1_FLAG_TC3: DMA1 Channel3 transfer complete flag. + * @arg DMA1_FLAG_HT3: DMA1 Channel3 half transfer flag. + * @arg DMA1_FLAG_TE3: DMA1 Channel3 transfer error flag. + * @arg DMA1_FLAG_GL4: DMA1 Channel4 global flag. + * @arg DMA1_FLAG_TC4: DMA1 Channel4 transfer complete flag. + * @arg DMA1_FLAG_HT4: DMA1 Channel4 half transfer flag. + * @arg DMA1_FLAG_TE4: DMA1 Channel4 transfer error flag. + * @arg DMA1_FLAG_GL5: DMA1 Channel5 global flag. + * @arg DMA1_FLAG_TC5: DMA1 Channel5 transfer complete flag. + * @arg DMA1_FLAG_HT5: DMA1 Channel5 half transfer flag. + * @arg DMA1_FLAG_TE5: DMA1 Channel5 transfer error flag. + * @arg DMA1_FLAG_GL6: DMA1 Channel6 global flag. + * @arg DMA1_FLAG_TC6: DMA1 Channel6 transfer complete flag. + * @arg DMA1_FLAG_HT6: DMA1 Channel6 half transfer flag. + * @arg DMA1_FLAG_TE6: DMA1 Channel6 transfer error flag. + * @arg DMA1_FLAG_GL7: DMA1 Channel7 global flag. + * @arg DMA1_FLAG_TC7: DMA1 Channel7 transfer complete flag. + * @arg DMA1_FLAG_HT7: DMA1 Channel7 half transfer flag. + * @arg DMA1_FLAG_TE7: DMA1 Channel7 transfer error flag. + * @arg DMA2_FLAG_GL1: DMA2 Channel1 global flag. + * @arg DMA2_FLAG_TC1: DMA2 Channel1 transfer complete flag. + * @arg DMA2_FLAG_HT1: DMA2 Channel1 half transfer flag. + * @arg DMA2_FLAG_TE1: DMA2 Channel1 transfer error flag. + * @arg DMA2_FLAG_GL2: DMA2 Channel2 global flag. + * @arg DMA2_FLAG_TC2: DMA2 Channel2 transfer complete flag. + * @arg DMA2_FLAG_HT2: DMA2 Channel2 half transfer flag. + * @arg DMA2_FLAG_TE2: DMA2 Channel2 transfer error flag. + * @arg DMA2_FLAG_GL3: DMA2 Channel3 global flag. + * @arg DMA2_FLAG_TC3: DMA2 Channel3 transfer complete flag. + * @arg DMA2_FLAG_HT3: DMA2 Channel3 half transfer flag. + * @arg DMA2_FLAG_TE3: DMA2 Channel3 transfer error flag. + * @arg DMA2_FLAG_GL4: DMA2 Channel4 global flag. + * @arg DMA2_FLAG_TC4: DMA2 Channel4 transfer complete flag. + * @arg DMA2_FLAG_HT4: DMA2 Channel4 half transfer flag. + * @arg DMA2_FLAG_TE4: DMA2 Channel4 transfer error flag. + * @arg DMA2_FLAG_GL5: DMA2 Channel5 global flag. + * @arg DMA2_FLAG_TC5: DMA2 Channel5 transfer complete flag. + * @arg DMA2_FLAG_HT5: DMA2 Channel5 half transfer flag. + * @arg DMA2_FLAG_TE5: DMA2 Channel5 transfer error flag. + * @retval The new state of DMA_FLAG (SET or RESET). + */ +FlagStatus DMA_GetFlagStatus(uint32_t DMA_FLAG) +{ + FlagStatus bitstatus = RESET; + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_DMA_GET_FLAG(DMA_FLAG)); + + /* Calculate the used DMA */ + if ((DMA_FLAG & FLAG_Mask) != (uint32_t)RESET) + { + /* Get DMA2 ISR register value */ + tmpreg = DMA2->ISR ; + } + else + { + /* Get DMA1 ISR register value */ + tmpreg = DMA1->ISR ; + } + + /* Check the status of the specified DMA flag */ + if ((tmpreg & DMA_FLAG) != (uint32_t)RESET) + { + /* DMA_FLAG is set */ + bitstatus = SET; + } + else + { + /* DMA_FLAG is reset */ + bitstatus = RESET; + } + + /* Return the DMA_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the DMAy Channelx's pending flags. + * @param DMA_FLAG: specifies the flag to clear. + * This parameter can be any combination (for the same DMA) of the following values: + * @arg DMA1_FLAG_GL1: DMA1 Channel1 global flag. + * @arg DMA1_FLAG_TC1: DMA1 Channel1 transfer complete flag. + * @arg DMA1_FLAG_HT1: DMA1 Channel1 half transfer flag. + * @arg DMA1_FLAG_TE1: DMA1 Channel1 transfer error flag. + * @arg DMA1_FLAG_GL2: DMA1 Channel2 global flag. + * @arg DMA1_FLAG_TC2: DMA1 Channel2 transfer complete flag. + * @arg DMA1_FLAG_HT2: DMA1 Channel2 half transfer flag. + * @arg DMA1_FLAG_TE2: DMA1 Channel2 transfer error flag. + * @arg DMA1_FLAG_GL3: DMA1 Channel3 global flag. + * @arg DMA1_FLAG_TC3: DMA1 Channel3 transfer complete flag. + * @arg DMA1_FLAG_HT3: DMA1 Channel3 half transfer flag. + * @arg DMA1_FLAG_TE3: DMA1 Channel3 transfer error flag. + * @arg DMA1_FLAG_GL4: DMA1 Channel4 global flag. + * @arg DMA1_FLAG_TC4: DMA1 Channel4 transfer complete flag. + * @arg DMA1_FLAG_HT4: DMA1 Channel4 half transfer flag. + * @arg DMA1_FLAG_TE4: DMA1 Channel4 transfer error flag. + * @arg DMA1_FLAG_GL5: DMA1 Channel5 global flag. + * @arg DMA1_FLAG_TC5: DMA1 Channel5 transfer complete flag. + * @arg DMA1_FLAG_HT5: DMA1 Channel5 half transfer flag. + * @arg DMA1_FLAG_TE5: DMA1 Channel5 transfer error flag. + * @arg DMA1_FLAG_GL6: DMA1 Channel6 global flag. + * @arg DMA1_FLAG_TC6: DMA1 Channel6 transfer complete flag. + * @arg DMA1_FLAG_HT6: DMA1 Channel6 half transfer flag. + * @arg DMA1_FLAG_TE6: DMA1 Channel6 transfer error flag. + * @arg DMA1_FLAG_GL7: DMA1 Channel7 global flag. + * @arg DMA1_FLAG_TC7: DMA1 Channel7 transfer complete flag. + * @arg DMA1_FLAG_HT7: DMA1 Channel7 half transfer flag. + * @arg DMA1_FLAG_TE7: DMA1 Channel7 transfer error flag. + * @arg DMA2_FLAG_GL1: DMA2 Channel1 global flag. + * @arg DMA2_FLAG_TC1: DMA2 Channel1 transfer complete flag. + * @arg DMA2_FLAG_HT1: DMA2 Channel1 half transfer flag. + * @arg DMA2_FLAG_TE1: DMA2 Channel1 transfer error flag. + * @arg DMA2_FLAG_GL2: DMA2 Channel2 global flag. + * @arg DMA2_FLAG_TC2: DMA2 Channel2 transfer complete flag. + * @arg DMA2_FLAG_HT2: DMA2 Channel2 half transfer flag. + * @arg DMA2_FLAG_TE2: DMA2 Channel2 transfer error flag. + * @arg DMA2_FLAG_GL3: DMA2 Channel3 global flag. + * @arg DMA2_FLAG_TC3: DMA2 Channel3 transfer complete flag. + * @arg DMA2_FLAG_HT3: DMA2 Channel3 half transfer flag. + * @arg DMA2_FLAG_TE3: DMA2 Channel3 transfer error flag. + * @arg DMA2_FLAG_GL4: DMA2 Channel4 global flag. + * @arg DMA2_FLAG_TC4: DMA2 Channel4 transfer complete flag. + * @arg DMA2_FLAG_HT4: DMA2 Channel4 half transfer flag. + * @arg DMA2_FLAG_TE4: DMA2 Channel4 transfer error flag. + * @arg DMA2_FLAG_GL5: DMA2 Channel5 global flag. + * @arg DMA2_FLAG_TC5: DMA2 Channel5 transfer complete flag. + * @arg DMA2_FLAG_HT5: DMA2 Channel5 half transfer flag. + * @arg DMA2_FLAG_TE5: DMA2 Channel5 transfer error flag. + * @retval None + */ +void DMA_ClearFlag(uint32_t DMA_FLAG) +{ + /* Check the parameters */ + assert_param(IS_DMA_CLEAR_FLAG(DMA_FLAG)); + /* Calculate the used DMA */ + + if ((DMA_FLAG & FLAG_Mask) != (uint32_t)RESET) + { + /* Clear the selected DMA flags */ + DMA2->IFCR = DMA_FLAG; + } + else + { + /* Clear the selected DMA flags */ + DMA1->IFCR = DMA_FLAG; + } +} + +/** + * @brief Checks whether the specified DMAy Channelx interrupt has occurred or not. + * @param DMA_IT: specifies the DMA interrupt source to check. + * This parameter can be one of the following values: + * @arg DMA1_IT_GL1: DMA1 Channel1 global interrupt. + * @arg DMA1_IT_TC1: DMA1 Channel1 transfer complete interrupt. + * @arg DMA1_IT_HT1: DMA1 Channel1 half transfer interrupt. + * @arg DMA1_IT_TE1: DMA1 Channel1 transfer error interrupt. + * @arg DMA1_IT_GL2: DMA1 Channel2 global interrupt. + * @arg DMA1_IT_TC2: DMA1 Channel2 transfer complete interrupt. + * @arg DMA1_IT_HT2: DMA1 Channel2 half transfer interrupt. + * @arg DMA1_IT_TE2: DMA1 Channel2 transfer error interrupt. + * @arg DMA1_IT_GL3: DMA1 Channel3 global interrupt. + * @arg DMA1_IT_TC3: DMA1 Channel3 transfer complete interrupt. + * @arg DMA1_IT_HT3: DMA1 Channel3 half transfer interrupt. + * @arg DMA1_IT_TE3: DMA1 Channel3 transfer error interrupt. + * @arg DMA1_IT_GL4: DMA1 Channel4 global interrupt. + * @arg DMA1_IT_TC4: DMA1 Channel4 transfer complete interrupt. + * @arg DMA1_IT_HT4: DMA1 Channel4 half transfer interrupt. + * @arg DMA1_IT_TE4: DMA1 Channel4 transfer error interrupt. + * @arg DMA1_IT_GL5: DMA1 Channel5 global interrupt. + * @arg DMA1_IT_TC5: DMA1 Channel5 transfer complete interrupt. + * @arg DMA1_IT_HT5: DMA1 Channel5 half transfer interrupt. + * @arg DMA1_IT_TE5: DMA1 Channel5 transfer error interrupt. + * @arg DMA1_IT_GL6: DMA1 Channel6 global interrupt. + * @arg DMA1_IT_TC6: DMA1 Channel6 transfer complete interrupt. + * @arg DMA1_IT_HT6: DMA1 Channel6 half transfer interrupt. + * @arg DMA1_IT_TE6: DMA1 Channel6 transfer error interrupt. + * @arg DMA1_IT_GL7: DMA1 Channel7 global interrupt. + * @arg DMA1_IT_TC7: DMA1 Channel7 transfer complete interrupt. + * @arg DMA1_IT_HT7: DMA1 Channel7 half transfer interrupt. + * @arg DMA1_IT_TE7: DMA1 Channel7 transfer error interrupt. + * @arg DMA2_IT_GL1: DMA2 Channel1 global interrupt. + * @arg DMA2_IT_TC1: DMA2 Channel1 transfer complete interrupt. + * @arg DMA2_IT_HT1: DMA2 Channel1 half transfer interrupt. + * @arg DMA2_IT_TE1: DMA2 Channel1 transfer error interrupt. + * @arg DMA2_IT_GL2: DMA2 Channel2 global interrupt. + * @arg DMA2_IT_TC2: DMA2 Channel2 transfer complete interrupt. + * @arg DMA2_IT_HT2: DMA2 Channel2 half transfer interrupt. + * @arg DMA2_IT_TE2: DMA2 Channel2 transfer error interrupt. + * @arg DMA2_IT_GL3: DMA2 Channel3 global interrupt. + * @arg DMA2_IT_TC3: DMA2 Channel3 transfer complete interrupt. + * @arg DMA2_IT_HT3: DMA2 Channel3 half transfer interrupt. + * @arg DMA2_IT_TE3: DMA2 Channel3 transfer error interrupt. + * @arg DMA2_IT_GL4: DMA2 Channel4 global interrupt. + * @arg DMA2_IT_TC4: DMA2 Channel4 transfer complete interrupt. + * @arg DMA2_IT_HT4: DMA2 Channel4 half transfer interrupt. + * @arg DMA2_IT_TE4: DMA2 Channel4 transfer error interrupt. + * @arg DMA2_IT_GL5: DMA2 Channel5 global interrupt. + * @arg DMA2_IT_TC5: DMA2 Channel5 transfer complete interrupt. + * @arg DMA2_IT_HT5: DMA2 Channel5 half transfer interrupt. + * @arg DMA2_IT_TE5: DMA2 Channel5 transfer error interrupt. + * @retval The new state of DMA_IT (SET or RESET). + */ +ITStatus DMA_GetITStatus(uint32_t DMA_IT) +{ + ITStatus bitstatus = RESET; + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_DMA_GET_IT(DMA_IT)); + + /* Calculate the used DMA */ + if ((DMA_IT & FLAG_Mask) != (uint32_t)RESET) + { + /* Get DMA2 ISR register value */ + tmpreg = DMA2->ISR ; + } + else + { + /* Get DMA1 ISR register value */ + tmpreg = DMA1->ISR ; + } + + /* Check the status of the specified DMA interrupt */ + if ((tmpreg & DMA_IT) != (uint32_t)RESET) + { + /* DMA_IT is set */ + bitstatus = SET; + } + else + { + /* DMA_IT is reset */ + bitstatus = RESET; + } + /* Return the DMA_IT status */ + return bitstatus; +} + +/** + * @brief Clears the DMAy Channelxs interrupt pending bits. + * @param DMA_IT: specifies the DMA interrupt pending bit to clear. + * This parameter can be any combination (for the same DMA) of the following values: + * @arg DMA1_IT_GL1: DMA1 Channel1 global interrupt. + * @arg DMA1_IT_TC1: DMA1 Channel1 transfer complete interrupt. + * @arg DMA1_IT_HT1: DMA1 Channel1 half transfer interrupt. + * @arg DMA1_IT_TE1: DMA1 Channel1 transfer error interrupt. + * @arg DMA1_IT_GL2: DMA1 Channel2 global interrupt. + * @arg DMA1_IT_TC2: DMA1 Channel2 transfer complete interrupt. + * @arg DMA1_IT_HT2: DMA1 Channel2 half transfer interrupt. + * @arg DMA1_IT_TE2: DMA1 Channel2 transfer error interrupt. + * @arg DMA1_IT_GL3: DMA1 Channel3 global interrupt. + * @arg DMA1_IT_TC3: DMA1 Channel3 transfer complete interrupt. + * @arg DMA1_IT_HT3: DMA1 Channel3 half transfer interrupt. + * @arg DMA1_IT_TE3: DMA1 Channel3 transfer error interrupt. + * @arg DMA1_IT_GL4: DMA1 Channel4 global interrupt. + * @arg DMA1_IT_TC4: DMA1 Channel4 transfer complete interrupt. + * @arg DMA1_IT_HT4: DMA1 Channel4 half transfer interrupt. + * @arg DMA1_IT_TE4: DMA1 Channel4 transfer error interrupt. + * @arg DMA1_IT_GL5: DMA1 Channel5 global interrupt. + * @arg DMA1_IT_TC5: DMA1 Channel5 transfer complete interrupt. + * @arg DMA1_IT_HT5: DMA1 Channel5 half transfer interrupt. + * @arg DMA1_IT_TE5: DMA1 Channel5 transfer error interrupt. + * @arg DMA1_IT_GL6: DMA1 Channel6 global interrupt. + * @arg DMA1_IT_TC6: DMA1 Channel6 transfer complete interrupt. + * @arg DMA1_IT_HT6: DMA1 Channel6 half transfer interrupt. + * @arg DMA1_IT_TE6: DMA1 Channel6 transfer error interrupt. + * @arg DMA1_IT_GL7: DMA1 Channel7 global interrupt. + * @arg DMA1_IT_TC7: DMA1 Channel7 transfer complete interrupt. + * @arg DMA1_IT_HT7: DMA1 Channel7 half transfer interrupt. + * @arg DMA1_IT_TE7: DMA1 Channel7 transfer error interrupt. + * @arg DMA2_IT_GL1: DMA2 Channel1 global interrupt. + * @arg DMA2_IT_TC1: DMA2 Channel1 transfer complete interrupt. + * @arg DMA2_IT_HT1: DMA2 Channel1 half transfer interrupt. + * @arg DMA2_IT_TE1: DMA2 Channel1 transfer error interrupt. + * @arg DMA2_IT_GL2: DMA2 Channel2 global interrupt. + * @arg DMA2_IT_TC2: DMA2 Channel2 transfer complete interrupt. + * @arg DMA2_IT_HT2: DMA2 Channel2 half transfer interrupt. + * @arg DMA2_IT_TE2: DMA2 Channel2 transfer error interrupt. + * @arg DMA2_IT_GL3: DMA2 Channel3 global interrupt. + * @arg DMA2_IT_TC3: DMA2 Channel3 transfer complete interrupt. + * @arg DMA2_IT_HT3: DMA2 Channel3 half transfer interrupt. + * @arg DMA2_IT_TE3: DMA2 Channel3 transfer error interrupt. + * @arg DMA2_IT_GL4: DMA2 Channel4 global interrupt. + * @arg DMA2_IT_TC4: DMA2 Channel4 transfer complete interrupt. + * @arg DMA2_IT_HT4: DMA2 Channel4 half transfer interrupt. + * @arg DMA2_IT_TE4: DMA2 Channel4 transfer error interrupt. + * @arg DMA2_IT_GL5: DMA2 Channel5 global interrupt. + * @arg DMA2_IT_TC5: DMA2 Channel5 transfer complete interrupt. + * @arg DMA2_IT_HT5: DMA2 Channel5 half transfer interrupt. + * @arg DMA2_IT_TE5: DMA2 Channel5 transfer error interrupt. + * @retval None + */ +void DMA_ClearITPendingBit(uint32_t DMA_IT) +{ + /* Check the parameters */ + assert_param(IS_DMA_CLEAR_IT(DMA_IT)); + + /* Calculate the used DMA */ + if ((DMA_IT & FLAG_Mask) != (uint32_t)RESET) + { + /* Clear the selected DMA interrupt pending bits */ + DMA2->IFCR = DMA_IT; + } + else + { + /* Clear the selected DMA interrupt pending bits */ + DMA1->IFCR = DMA_IT; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_exti.c b/example/libs_stm/src/stm32f10x/stm32f10x_exti.c new file mode 100644 index 000000000..eae3253ea --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_exti.c @@ -0,0 +1,268 @@ +/** + ****************************************************************************** + * @file stm32f10x_exti.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the EXTI firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_exti.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup EXTI + * @brief EXTI driver modules + * @{ + */ + +/** @defgroup EXTI_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup EXTI_Private_Defines + * @{ + */ + +#define EXTI_LineNone ((uint32_t)0x00000) /* No interrupt selected */ + +/** + * @} + */ + +/** @defgroup EXTI_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup EXTI_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup EXTI_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup EXTI_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the EXTI peripheral registers to their default reset values. + * @param None + * @retval None + */ +void EXTI_DeInit(void) +{ + EXTI->IMR = 0x00000000; + EXTI->EMR = 0x00000000; + EXTI->RTSR = 0x00000000; + EXTI->FTSR = 0x00000000; + EXTI->PR = 0x000FFFFF; +} + +/** + * @brief Initializes the EXTI peripheral according to the specified + * parameters in the EXTI_InitStruct. + * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure + * that contains the configuration information for the EXTI peripheral. + * @retval None + */ +void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct) +{ + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode)); + assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger)); + assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line)); + assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd)); + + tmp = (uint32_t)EXTI_BASE; + + if (EXTI_InitStruct->EXTI_LineCmd != DISABLE) + { + /* Clear EXTI line configuration */ + EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line; + EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line; + + tmp += EXTI_InitStruct->EXTI_Mode; + + *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; + + /* Clear Rising Falling edge configuration */ + EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line; + EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line; + + /* Select the trigger for the selected external interrupts */ + if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling) + { + /* Rising Falling edge */ + EXTI->RTSR |= EXTI_InitStruct->EXTI_Line; + EXTI->FTSR |= EXTI_InitStruct->EXTI_Line; + } + else + { + tmp = (uint32_t)EXTI_BASE; + tmp += EXTI_InitStruct->EXTI_Trigger; + + *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; + } + } + else + { + tmp += EXTI_InitStruct->EXTI_Mode; + + /* Disable the selected external lines */ + *(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line; + } +} + +/** + * @brief Fills each EXTI_InitStruct member with its reset value. + * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct) +{ + EXTI_InitStruct->EXTI_Line = EXTI_LineNone; + EXTI_InitStruct->EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStruct->EXTI_Trigger = EXTI_Trigger_Falling; + EXTI_InitStruct->EXTI_LineCmd = DISABLE; +} + +/** + * @brief Generates a Software interrupt. + * @param EXTI_Line: specifies the EXTI lines to be enabled or disabled. + * This parameter can be any combination of EXTI_Linex where x can be (0..19). + * @retval None + */ +void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line) +{ + /* Check the parameters */ + assert_param(IS_EXTI_LINE(EXTI_Line)); + + EXTI->SWIER |= EXTI_Line; +} + +/** + * @brief Checks whether the specified EXTI line flag is set or not. + * @param EXTI_Line: specifies the EXTI line flag to check. + * This parameter can be: + * @arg EXTI_Linex: External interrupt line x where x(0..19) + * @retval The new state of EXTI_Line (SET or RESET). + */ +FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_GET_EXTI_LINE(EXTI_Line)); + + if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the EXTIs line pending flags. + * @param EXTI_Line: specifies the EXTI lines flags to clear. + * This parameter can be any combination of EXTI_Linex where x can be (0..19). + * @retval None + */ +void EXTI_ClearFlag(uint32_t EXTI_Line) +{ + /* Check the parameters */ + assert_param(IS_EXTI_LINE(EXTI_Line)); + + EXTI->PR = EXTI_Line; +} + +/** + * @brief Checks whether the specified EXTI line is asserted or not. + * @param EXTI_Line: specifies the EXTI line to check. + * This parameter can be: + * @arg EXTI_Linex: External interrupt line x where x(0..19) + * @retval The new state of EXTI_Line (SET or RESET). + */ +ITStatus EXTI_GetITStatus(uint32_t EXTI_Line) +{ + ITStatus bitstatus = RESET; + uint32_t enablestatus = 0; + /* Check the parameters */ + assert_param(IS_GET_EXTI_LINE(EXTI_Line)); + + enablestatus = EXTI->IMR & EXTI_Line; + if (((EXTI->PR & EXTI_Line) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the EXTIs line pending bits. + * @param EXTI_Line: specifies the EXTI lines to clear. + * This parameter can be any combination of EXTI_Linex where x can be (0..19). + * @retval None + */ +void EXTI_ClearITPendingBit(uint32_t EXTI_Line) +{ + /* Check the parameters */ + assert_param(IS_EXTI_LINE(EXTI_Line)); + + EXTI->PR = EXTI_Line; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_flash.c b/example/libs_stm/src/stm32f10x/stm32f10x_flash.c new file mode 100644 index 000000000..3475e6a37 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_flash.c @@ -0,0 +1,1735 @@ +/** + ****************************************************************************** + * @file stm32f10x_flash.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the FLASH firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_flash.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup FLASH + * @brief FLASH driver modules + * @{ + */ + +/** @defgroup FLASH_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup FLASH_Private_Defines + * @{ + */ + +/* Flash Access Control Register bits */ +#define ACR_LATENCY_Mask ((uint32_t)0x00000038) +#define ACR_HLFCYA_Mask ((uint32_t)0xFFFFFFF7) +#define ACR_PRFTBE_Mask ((uint32_t)0xFFFFFFEF) + +/* Flash Access Control Register bits */ +#define ACR_PRFTBS_Mask ((uint32_t)0x00000020) + +/* Flash Control Register bits */ +#define CR_PG_Set ((uint32_t)0x00000001) +#define CR_PG_Reset ((uint32_t)0x00001FFE) +#define CR_PER_Set ((uint32_t)0x00000002) +#define CR_PER_Reset ((uint32_t)0x00001FFD) +#define CR_MER_Set ((uint32_t)0x00000004) +#define CR_MER_Reset ((uint32_t)0x00001FFB) +#define CR_OPTPG_Set ((uint32_t)0x00000010) +#define CR_OPTPG_Reset ((uint32_t)0x00001FEF) +#define CR_OPTER_Set ((uint32_t)0x00000020) +#define CR_OPTER_Reset ((uint32_t)0x00001FDF) +#define CR_STRT_Set ((uint32_t)0x00000040) +#define CR_LOCK_Set ((uint32_t)0x00000080) + +/* FLASH Mask */ +#define RDPRT_Mask ((uint32_t)0x00000002) +#define WRP0_Mask ((uint32_t)0x000000FF) +#define WRP1_Mask ((uint32_t)0x0000FF00) +#define WRP2_Mask ((uint32_t)0x00FF0000) +#define WRP3_Mask ((uint32_t)0xFF000000) +#define OB_USER_BFB2 ((uint16_t)0x0008) + +/* FLASH Keys */ +#define RDP_Key ((uint16_t)0x00A5) +#define FLASH_KEY1 ((uint32_t)0x45670123) +#define FLASH_KEY2 ((uint32_t)0xCDEF89AB) + +/* FLASH BANK address */ +#define FLASH_BANK1_END_ADDRESS ((uint32_t)0x807FFFF) + +/* Delay definition */ +#define EraseTimeout ((uint32_t)0x000B0000) +#define ProgramTimeout ((uint32_t)0x00002000) +/** + * @} + */ + +/** @defgroup FLASH_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup FLASH_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup FLASH_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup FLASH_Private_Functions + * @{ + */ + +/** +@code + + This driver provides functions to configure and program the Flash memory of all STM32F10x devices, + including the latest STM32F10x_XL density devices. + + STM32F10x_XL devices feature up to 1 Mbyte with dual bank architecture for read-while-write (RWW) capability: + - bank1: fixed size of 512 Kbytes (256 pages of 2Kbytes each) + - bank2: up to 512 Kbytes (up to 256 pages of 2Kbytes each) + While other STM32F10x devices features only one bank with memory up to 512 Kbytes. + + In version V3.3.0, some functions were updated and new ones were added to support + STM32F10x_XL devices. Thus some functions manages all devices, while other are + dedicated for XL devices only. + + The table below presents the list of available functions depending on the used STM32F10x devices. + + *************************************************** + * Legacy functions used for all STM32F10x devices * + *************************************************** + +----------------------------------------------------------------------------------------------------------------------------------+ + | Functions prototypes |STM32F10x_XL|Other STM32F10x| Comments | + | | devices | devices | | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_SetLatency | Yes | Yes | No change | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_HalfCycleAccessCmd | Yes | Yes | No change | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_PrefetchBufferCmd | Yes | Yes | No change | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_Unlock | Yes | Yes | - For STM32F10X_XL devices: unlock Bank1 and Bank2. | + | | | | - For other devices: unlock Bank1 and it is equivalent | + | | | | to FLASH_UnlockBank1 function. | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_Lock | Yes | Yes | - For STM32F10X_XL devices: lock Bank1 and Bank2. | + | | | | - For other devices: lock Bank1 and it is equivalent | + | | | | to FLASH_LockBank1 function. | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_ErasePage | Yes | Yes | - For STM32F10x_XL devices: erase a page in Bank1 and Bank2 | + | | | | - For other devices: erase a page in Bank1 | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_EraseAllPages | Yes | Yes | - For STM32F10x_XL devices: erase all pages in Bank1 and Bank2 | + | | | | - For other devices: erase all pages in Bank1 | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_EraseOptionBytes | Yes | Yes | No change | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_ProgramWord | Yes | Yes | Updated to program up to 1MByte (depending on the used device) | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_ProgramHalfWord | Yes | Yes | Updated to program up to 1MByte (depending on the used device) | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_ProgramOptionByteData | Yes | Yes | No change | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_EnableWriteProtection | Yes | Yes | No change | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_ReadOutProtection | Yes | Yes | No change | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_UserOptionByteConfig | Yes | Yes | No change | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_GetUserOptionByte | Yes | Yes | No change | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_GetWriteProtectionOptionByte | Yes | Yes | No change | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_GetReadOutProtectionStatus | Yes | Yes | No change | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_GetPrefetchBufferStatus | Yes | Yes | No change | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_ITConfig | Yes | Yes | - For STM32F10x_XL devices: enable Bank1 and Bank2's interrupts| + | | | | - For other devices: enable Bank1's interrupts | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_GetFlagStatus | Yes | Yes | - For STM32F10x_XL devices: return Bank1 and Bank2's flag status| + | | | | - For other devices: return Bank1's flag status | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_ClearFlag | Yes | Yes | - For STM32F10x_XL devices: clear Bank1 and Bank2's flag | + | | | | - For other devices: clear Bank1's flag | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_GetStatus | Yes | Yes | - Return the status of Bank1 (for all devices) | + | | | | equivalent to FLASH_GetBank1Status function | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_WaitForLastOperation | Yes | Yes | - Wait for Bank1 last operation (for all devices) | + | | | | equivalent to: FLASH_WaitForLastBank1Operation function | + +----------------------------------------------------------------------------------------------------------------------------------+ + + ************************************************************************************************************************ + * New functions used for all STM32F10x devices to manage Bank1: * + * - These functions are mainly useful for STM32F10x_XL density devices, to have separate control for Bank1 and bank2 * + * - For other devices, these functions are optional (covered by functions listed above) * + ************************************************************************************************************************ + +----------------------------------------------------------------------------------------------------------------------------------+ + | Functions prototypes |STM32F10x_XL|Other STM32F10x| Comments | + | | devices | devices | | + |----------------------------------------------------------------------------------------------------------------------------------| + | FLASH_UnlockBank1 | Yes | Yes | - Unlock Bank1 | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_LockBank1 | Yes | Yes | - Lock Bank1 | + |----------------------------------------------------------------------------------------------------------------------------------| + | FLASH_EraseAllBank1Pages | Yes | Yes | - Erase all pages in Bank1 | + |----------------------------------------------------------------------------------------------------------------------------------| + | FLASH_GetBank1Status | Yes | Yes | - Return the status of Bank1 | + |----------------------------------------------------------------------------------------------------------------------------------| + | FLASH_WaitForLastBank1Operation | Yes | Yes | - Wait for Bank1 last operation | + +----------------------------------------------------------------------------------------------------------------------------------+ + + ***************************************************************************** + * New Functions used only with STM32F10x_XL density devices to manage Bank2 * + ***************************************************************************** + +----------------------------------------------------------------------------------------------------------------------------------+ + | Functions prototypes |STM32F10x_XL|Other STM32F10x| Comments | + | | devices | devices | | + |----------------------------------------------------------------------------------------------------------------------------------| + | FLASH_UnlockBank2 | Yes | No | - Unlock Bank2 | + |----------------------------------------------------------------------------------------------------------------------------------| + |FLASH_LockBank2 | Yes | No | - Lock Bank2 | + |----------------------------------------------------------------------------------------------------------------------------------| + | FLASH_EraseAllBank2Pages | Yes | No | - Erase all pages in Bank2 | + |----------------------------------------------------------------------------------------------------------------------------------| + | FLASH_GetBank2Status | Yes | No | - Return the status of Bank2 | + |----------------------------------------------------------------------------------------------------------------------------------| + | FLASH_WaitForLastBank2Operation | Yes | No | - Wait for Bank2 last operation | + |----------------------------------------------------------------------------------------------------------------------------------| + | FLASH_BootConfig | Yes | No | - Configure to boot from Bank1 or Bank2 | + +----------------------------------------------------------------------------------------------------------------------------------+ +@endcode +*/ + + +/** + * @brief Sets the code latency value. + * @note This function can be used for all STM32F10x devices. + * @param FLASH_Latency: specifies the FLASH Latency value. + * This parameter can be one of the following values: + * @arg FLASH_Latency_0: FLASH Zero Latency cycle + * @arg FLASH_Latency_1: FLASH One Latency cycle + * @arg FLASH_Latency_2: FLASH Two Latency cycles + * @retval None + */ +void FLASH_SetLatency(uint32_t FLASH_Latency) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_FLASH_LATENCY(FLASH_Latency)); + + /* Read the ACR register */ + tmpreg = FLASH->ACR; + + /* Sets the Latency value */ + tmpreg &= ACR_LATENCY_Mask; + tmpreg |= FLASH_Latency; + + /* Write the ACR register */ + FLASH->ACR = tmpreg; +} + +/** + * @brief Enables or disables the Half cycle flash access. + * @note This function can be used for all STM32F10x devices. + * @param FLASH_HalfCycleAccess: specifies the FLASH Half cycle Access mode. + * This parameter can be one of the following values: + * @arg FLASH_HalfCycleAccess_Enable: FLASH Half Cycle Enable + * @arg FLASH_HalfCycleAccess_Disable: FLASH Half Cycle Disable + * @retval None + */ +void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess) +{ + /* Check the parameters */ + assert_param(IS_FLASH_HALFCYCLEACCESS_STATE(FLASH_HalfCycleAccess)); + + /* Enable or disable the Half cycle access */ + FLASH->ACR &= ACR_HLFCYA_Mask; + FLASH->ACR |= FLASH_HalfCycleAccess; +} + +/** + * @brief Enables or disables the Prefetch Buffer. + * @note This function can be used for all STM32F10x devices. + * @param FLASH_PrefetchBuffer: specifies the Prefetch buffer status. + * This parameter can be one of the following values: + * @arg FLASH_PrefetchBuffer_Enable: FLASH Prefetch Buffer Enable + * @arg FLASH_PrefetchBuffer_Disable: FLASH Prefetch Buffer Disable + * @retval None + */ +void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer) +{ + /* Check the parameters */ + assert_param(IS_FLASH_PREFETCHBUFFER_STATE(FLASH_PrefetchBuffer)); + + /* Enable or disable the Prefetch Buffer */ + FLASH->ACR &= ACR_PRFTBE_Mask; + FLASH->ACR |= FLASH_PrefetchBuffer; +} + +/** + * @brief Unlocks the FLASH Program Erase Controller. + * @note This function can be used for all STM32F10x devices. + * - For STM32F10X_XL devices this function unlocks Bank1 and Bank2. + * - For all other devices it unlocks Bank1 and it is equivalent + * to FLASH_UnlockBank1 function.. + * @param None + * @retval None + */ +void FLASH_Unlock(void) +{ + /* Authorize the FPEC of Bank1 Access */ + FLASH->KEYR = FLASH_KEY1; + FLASH->KEYR = FLASH_KEY2; + +#ifdef STM32F10X_XL + /* Authorize the FPEC of Bank2 Access */ + FLASH->KEYR2 = FLASH_KEY1; + FLASH->KEYR2 = FLASH_KEY2; +#endif /* STM32F10X_XL */ +} +/** + * @brief Unlocks the FLASH Bank1 Program Erase Controller. + * @note This function can be used for all STM32F10x devices. + * - For STM32F10X_XL devices this function unlocks Bank1. + * - For all other devices it unlocks Bank1 and it is + * equivalent to FLASH_Unlock function. + * @param None + * @retval None + */ +void FLASH_UnlockBank1(void) +{ + /* Authorize the FPEC of Bank1 Access */ + FLASH->KEYR = FLASH_KEY1; + FLASH->KEYR = FLASH_KEY2; +} + +#ifdef STM32F10X_XL +/** + * @brief Unlocks the FLASH Bank2 Program Erase Controller. + * @note This function can be used only for STM32F10X_XL density devices. + * @param None + * @retval None + */ +void FLASH_UnlockBank2(void) +{ + /* Authorize the FPEC of Bank2 Access */ + FLASH->KEYR2 = FLASH_KEY1; + FLASH->KEYR2 = FLASH_KEY2; + +} +#endif /* STM32F10X_XL */ + +/** + * @brief Locks the FLASH Program Erase Controller. + * @note This function can be used for all STM32F10x devices. + * - For STM32F10X_XL devices this function Locks Bank1 and Bank2. + * - For all other devices it Locks Bank1 and it is equivalent + * to FLASH_LockBank1 function. + * @param None + * @retval None + */ +void FLASH_Lock(void) +{ + /* Set the Lock Bit to lock the FPEC and the CR of Bank1 */ + FLASH->CR |= CR_LOCK_Set; + +#ifdef STM32F10X_XL + /* Set the Lock Bit to lock the FPEC and the CR of Bank2 */ + FLASH->CR2 |= CR_LOCK_Set; +#endif /* STM32F10X_XL */ +} + +/** + * @brief Locks the FLASH Bank1 Program Erase Controller. + * @note this function can be used for all STM32F10x devices. + * - For STM32F10X_XL devices this function Locks Bank1. + * - For all other devices it Locks Bank1 and it is equivalent + * to FLASH_Lock function. + * @param None + * @retval None + */ +void FLASH_LockBank1(void) +{ + /* Set the Lock Bit to lock the FPEC and the CR of Bank1 */ + FLASH->CR |= CR_LOCK_Set; +} + +#ifdef STM32F10X_XL +/** + * @brief Locks the FLASH Bank2 Program Erase Controller. + * @note This function can be used only for STM32F10X_XL density devices. + * @param None + * @retval None + */ +void FLASH_LockBank2(void) +{ + /* Set the Lock Bit to lock the FPEC and the CR of Bank2 */ + FLASH->CR2 |= CR_LOCK_Set; +} +#endif /* STM32F10X_XL */ + +/** + * @brief Erases a specified FLASH page. + * @note This function can be used for all STM32F10x devices. + * @param Page_Address: The page address to be erased. + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_ErasePage(uint32_t Page_Address) +{ + FLASH_Status status = FLASH_COMPLETE; + /* Check the parameters */ + assert_param(IS_FLASH_ADDRESS(Page_Address)); + +#ifdef STM32F10X_XL + if(Page_Address < FLASH_BANK1_END_ADDRESS) + { + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank1Operation(EraseTimeout); + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to erase the page */ + FLASH->CR|= CR_PER_Set; + FLASH->AR = Page_Address; + FLASH->CR|= CR_STRT_Set; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank1Operation(EraseTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the erase operation is completed, disable the PER Bit */ + FLASH->CR &= CR_PER_Reset; + } + } + } + else + { + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank2Operation(EraseTimeout); + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to erase the page */ + FLASH->CR2|= CR_PER_Set; + FLASH->AR2 = Page_Address; + FLASH->CR2|= CR_STRT_Set; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank2Operation(EraseTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the erase operation is completed, disable the PER Bit */ + FLASH->CR2 &= CR_PER_Reset; + } + } + } +#else + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(EraseTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to erase the page */ + FLASH->CR|= CR_PER_Set; + FLASH->AR = Page_Address; + FLASH->CR|= CR_STRT_Set; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(EraseTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the erase operation is completed, disable the PER Bit */ + FLASH->CR &= CR_PER_Reset; + } + } +#endif /* STM32F10X_XL */ + + /* Return the Erase Status */ + return status; +} + +/** + * @brief Erases all FLASH pages. + * @note This function can be used for all STM32F10x devices. + * @param None + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_EraseAllPages(void) +{ + FLASH_Status status = FLASH_COMPLETE; + +#ifdef STM32F10X_XL + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank1Operation(EraseTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to erase all pages */ + FLASH->CR |= CR_MER_Set; + FLASH->CR |= CR_STRT_Set; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank1Operation(EraseTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the erase operation is completed, disable the MER Bit */ + FLASH->CR &= CR_MER_Reset; + } + } + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to erase all pages */ + FLASH->CR2 |= CR_MER_Set; + FLASH->CR2 |= CR_STRT_Set; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank2Operation(EraseTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the erase operation is completed, disable the MER Bit */ + FLASH->CR2 &= CR_MER_Reset; + } + } +#else + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(EraseTimeout); + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to erase all pages */ + FLASH->CR |= CR_MER_Set; + FLASH->CR |= CR_STRT_Set; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(EraseTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the erase operation is completed, disable the MER Bit */ + FLASH->CR &= CR_MER_Reset; + } + } +#endif /* STM32F10X_XL */ + + /* Return the Erase Status */ + return status; +} + +/** + * @brief Erases all Bank1 FLASH pages. + * @note This function can be used for all STM32F10x devices. + * - For STM32F10X_XL devices this function erases all Bank1 pages. + * - For all other devices it erases all Bank1 pages and it is equivalent + * to FLASH_EraseAllPages function. + * @param None + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_EraseAllBank1Pages(void) +{ + FLASH_Status status = FLASH_COMPLETE; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank1Operation(EraseTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to erase all pages */ + FLASH->CR |= CR_MER_Set; + FLASH->CR |= CR_STRT_Set; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank1Operation(EraseTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the erase operation is completed, disable the MER Bit */ + FLASH->CR &= CR_MER_Reset; + } + } + /* Return the Erase Status */ + return status; +} + +#ifdef STM32F10X_XL +/** + * @brief Erases all Bank2 FLASH pages. + * @note This function can be used only for STM32F10x_XL density devices. + * @param None + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_EraseAllBank2Pages(void) +{ + FLASH_Status status = FLASH_COMPLETE; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank2Operation(EraseTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to erase all pages */ + FLASH->CR2 |= CR_MER_Set; + FLASH->CR2 |= CR_STRT_Set; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank2Operation(EraseTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the erase operation is completed, disable the MER Bit */ + FLASH->CR2 &= CR_MER_Reset; + } + } + /* Return the Erase Status */ + return status; +} +#endif /* STM32F10X_XL */ + +/** + * @brief Erases the FLASH option bytes. + * @note This functions erases all option bytes except the Read protection (RDP). + * @note This function can be used for all STM32F10x devices. + * @param None + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_EraseOptionBytes(void) +{ + uint16_t rdptmp = RDP_Key; + + FLASH_Status status = FLASH_COMPLETE; + + /* Get the actual read protection Option Byte value */ + if(FLASH_GetReadOutProtectionStatus() != RESET) + { + rdptmp = 0x00; + } + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(EraseTimeout); + if(status == FLASH_COMPLETE) + { + /* Authorize the small information block programming */ + FLASH->OPTKEYR = FLASH_KEY1; + FLASH->OPTKEYR = FLASH_KEY2; + + /* if the previous operation is completed, proceed to erase the option bytes */ + FLASH->CR |= CR_OPTER_Set; + FLASH->CR |= CR_STRT_Set; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(EraseTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the erase operation is completed, disable the OPTER Bit */ + FLASH->CR &= CR_OPTER_Reset; + + /* Enable the Option Bytes Programming operation */ + FLASH->CR |= CR_OPTPG_Set; + /* Restore the last read protection Option Byte value */ + OB->RDP = (uint16_t)rdptmp; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(status != FLASH_TIMEOUT) + { + /* if the program operation is completed, disable the OPTPG Bit */ + FLASH->CR &= CR_OPTPG_Reset; + } + } + else + { + if (status != FLASH_TIMEOUT) + { + /* Disable the OPTPG Bit */ + FLASH->CR &= CR_OPTPG_Reset; + } + } + } + /* Return the erase status */ + return status; +} + +/** + * @brief Programs a word at a specified address. + * @note This function can be used for all STM32F10x devices. + * @param Address: specifies the address to be programmed. + * @param Data: specifies the data to be programmed. + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_FLASH_ADDRESS(Address)); + +#ifdef STM32F10X_XL + if(Address < FLASH_BANK1_END_ADDRESS - 2) + { + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank1Operation(ProgramTimeout); + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new first + half word */ + FLASH->CR |= CR_PG_Set; + + *(__IO uint16_t*)Address = (uint16_t)Data; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new second + half word */ + tmp = Address + 2; + + *(__IO uint16_t*) tmp = Data >> 16; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(status != FLASH_TIMEOUT) + { + /* Disable the PG Bit */ + FLASH->CR &= CR_PG_Reset; + } + } + else + { + if (status != FLASH_TIMEOUT) + { + /* Disable the PG Bit */ + FLASH->CR &= CR_PG_Reset; + } + } + } + } + else if(Address == (FLASH_BANK1_END_ADDRESS - 1)) + { + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank1Operation(ProgramTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new first + half word */ + FLASH->CR |= CR_PG_Set; + + *(__IO uint16_t*)Address = (uint16_t)Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank1Operation(ProgramTimeout); + + if(status != FLASH_TIMEOUT) + { + /* Disable the PG Bit */ + FLASH->CR &= CR_PG_Reset; + } + } + else + { + if (status != FLASH_TIMEOUT) + { + /* Disable the PG Bit */ + FLASH->CR &= CR_PG_Reset; + } + } + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank2Operation(ProgramTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new second + half word */ + FLASH->CR2 |= CR_PG_Set; + tmp = Address + 2; + + *(__IO uint16_t*) tmp = Data >> 16; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank2Operation(ProgramTimeout); + + if(status != FLASH_TIMEOUT) + { + /* Disable the PG Bit */ + FLASH->CR2 &= CR_PG_Reset; + } + } + else + { + if (status != FLASH_TIMEOUT) + { + /* Disable the PG Bit */ + FLASH->CR2 &= CR_PG_Reset; + } + } + } + else + { + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank2Operation(ProgramTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new first + half word */ + FLASH->CR2 |= CR_PG_Set; + + *(__IO uint16_t*)Address = (uint16_t)Data; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank2Operation(ProgramTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new second + half word */ + tmp = Address + 2; + + *(__IO uint16_t*) tmp = Data >> 16; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank2Operation(ProgramTimeout); + + if(status != FLASH_TIMEOUT) + { + /* Disable the PG Bit */ + FLASH->CR2 &= CR_PG_Reset; + } + } + else + { + if (status != FLASH_TIMEOUT) + { + /* Disable the PG Bit */ + FLASH->CR2 &= CR_PG_Reset; + } + } + } + } +#else + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new first + half word */ + FLASH->CR |= CR_PG_Set; + + *(__IO uint16_t*)Address = (uint16_t)Data; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new second + half word */ + tmp = Address + 2; + + *(__IO uint16_t*) tmp = Data >> 16; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(status != FLASH_TIMEOUT) + { + /* Disable the PG Bit */ + FLASH->CR &= CR_PG_Reset; + } + } + else + { + if (status != FLASH_TIMEOUT) + { + /* Disable the PG Bit */ + FLASH->CR &= CR_PG_Reset; + } + } + } +#endif /* STM32F10X_XL */ + + /* Return the Program Status */ + return status; +} + +/** + * @brief Programs a half word at a specified address. + * @note This function can be used for all STM32F10x devices. + * @param Address: specifies the address to be programmed. + * @param Data: specifies the data to be programmed. + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; + /* Check the parameters */ + assert_param(IS_FLASH_ADDRESS(Address)); + +#ifdef STM32F10X_XL + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(Address < FLASH_BANK1_END_ADDRESS) + { + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new data */ + FLASH->CR |= CR_PG_Set; + + *(__IO uint16_t*)Address = Data; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank1Operation(ProgramTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the program operation is completed, disable the PG Bit */ + FLASH->CR &= CR_PG_Reset; + } + } + } + else + { + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new data */ + FLASH->CR2 |= CR_PG_Set; + + *(__IO uint16_t*)Address = Data; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastBank2Operation(ProgramTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the program operation is completed, disable the PG Bit */ + FLASH->CR2 &= CR_PG_Reset; + } + } + } +#else + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(status == FLASH_COMPLETE) + { + /* if the previous operation is completed, proceed to program the new data */ + FLASH->CR |= CR_PG_Set; + + *(__IO uint16_t*)Address = Data; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the program operation is completed, disable the PG Bit */ + FLASH->CR &= CR_PG_Reset; + } + } +#endif /* STM32F10X_XL */ + + /* Return the Program Status */ + return status; +} + +/** + * @brief Programs a half word at a specified Option Byte Data address. + * @note This function can be used for all STM32F10x devices. + * @param Address: specifies the address to be programmed. + * This parameter can be 0x1FFFF804 or 0x1FFFF806. + * @param Data: specifies the data to be programmed. + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data) +{ + FLASH_Status status = FLASH_COMPLETE; + /* Check the parameters */ + assert_param(IS_OB_DATA_ADDRESS(Address)); + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(status == FLASH_COMPLETE) + { + /* Authorize the small information block programming */ + FLASH->OPTKEYR = FLASH_KEY1; + FLASH->OPTKEYR = FLASH_KEY2; + /* Enables the Option Bytes Programming operation */ + FLASH->CR |= CR_OPTPG_Set; + *(__IO uint16_t*)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the program operation is completed, disable the OPTPG Bit */ + FLASH->CR &= CR_OPTPG_Reset; + } + } + /* Return the Option Byte Data Program Status */ + return status; +} + +/** + * @brief Write protects the desired pages + * @note This function can be used for all STM32F10x devices. + * @param FLASH_Pages: specifies the address of the pages to be write protected. + * This parameter can be: + * @arg For @b STM32_Low-density_devices: value between FLASH_WRProt_Pages0to3 and FLASH_WRProt_Pages28to31 + * @arg For @b STM32_Medium-density_devices: value between FLASH_WRProt_Pages0to3 + * and FLASH_WRProt_Pages124to127 + * @arg For @b STM32_High-density_devices: value between FLASH_WRProt_Pages0to1 and + * FLASH_WRProt_Pages60to61 or FLASH_WRProt_Pages62to255 + * @arg For @b STM32_Connectivity_line_devices: value between FLASH_WRProt_Pages0to1 and + * FLASH_WRProt_Pages60to61 or FLASH_WRProt_Pages62to127 + * @arg For @b STM32_XL-density_devices: value between FLASH_WRProt_Pages0to1 and + * FLASH_WRProt_Pages60to61 or FLASH_WRProt_Pages62to511 + * @arg FLASH_WRProt_AllPages + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages) +{ + uint16_t WRP0_Data = 0xFFFF, WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF; + + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_FLASH_WRPROT_PAGE(FLASH_Pages)); + + FLASH_Pages = (uint32_t)(~FLASH_Pages); + WRP0_Data = (uint16_t)(FLASH_Pages & WRP0_Mask); + WRP1_Data = (uint16_t)((FLASH_Pages & WRP1_Mask) >> 8); + WRP2_Data = (uint16_t)((FLASH_Pages & WRP2_Mask) >> 16); + WRP3_Data = (uint16_t)((FLASH_Pages & WRP3_Mask) >> 24); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(status == FLASH_COMPLETE) + { + /* Authorizes the small information block programming */ + FLASH->OPTKEYR = FLASH_KEY1; + FLASH->OPTKEYR = FLASH_KEY2; + FLASH->CR |= CR_OPTPG_Set; + if(WRP0_Data != 0xFF) + { + OB->WRP0 = WRP0_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + } + if((status == FLASH_COMPLETE) && (WRP1_Data != 0xFF)) + { + OB->WRP1 = WRP1_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + } + if((status == FLASH_COMPLETE) && (WRP2_Data != 0xFF)) + { + OB->WRP2 = WRP2_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + } + + if((status == FLASH_COMPLETE)&& (WRP3_Data != 0xFF)) + { + OB->WRP3 = WRP3_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + } + + if(status != FLASH_TIMEOUT) + { + /* if the program operation is completed, disable the OPTPG Bit */ + FLASH->CR &= CR_OPTPG_Reset; + } + } + /* Return the write protection operation Status */ + return status; +} + +/** + * @brief Enables or disables the read out protection. + * @note If the user has already programmed the other option bytes before calling + * this function, he must re-program them since this function erases all option bytes. + * @note This function can be used for all STM32F10x devices. + * @param Newstate: new state of the ReadOut Protection. + * This parameter can be: ENABLE or DISABLE. + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState) +{ + FLASH_Status status = FLASH_COMPLETE; + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + status = FLASH_WaitForLastOperation(EraseTimeout); + if(status == FLASH_COMPLETE) + { + /* Authorizes the small information block programming */ + FLASH->OPTKEYR = FLASH_KEY1; + FLASH->OPTKEYR = FLASH_KEY2; + FLASH->CR |= CR_OPTER_Set; + FLASH->CR |= CR_STRT_Set; + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(EraseTimeout); + if(status == FLASH_COMPLETE) + { + /* if the erase operation is completed, disable the OPTER Bit */ + FLASH->CR &= CR_OPTER_Reset; + /* Enable the Option Bytes Programming operation */ + FLASH->CR |= CR_OPTPG_Set; + if(NewState != DISABLE) + { + OB->RDP = 0x00; + } + else + { + OB->RDP = RDP_Key; + } + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(EraseTimeout); + + if(status != FLASH_TIMEOUT) + { + /* if the program operation is completed, disable the OPTPG Bit */ + FLASH->CR &= CR_OPTPG_Reset; + } + } + else + { + if(status != FLASH_TIMEOUT) + { + /* Disable the OPTER Bit */ + FLASH->CR &= CR_OPTER_Reset; + } + } + } + /* Return the protection operation Status */ + return status; +} + +/** + * @brief Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY. + * @note This function can be used for all STM32F10x devices. + * @param OB_IWDG: Selects the IWDG mode + * This parameter can be one of the following values: + * @arg OB_IWDG_SW: Software IWDG selected + * @arg OB_IWDG_HW: Hardware IWDG selected + * @param OB_STOP: Reset event when entering STOP mode. + * This parameter can be one of the following values: + * @arg OB_STOP_NoRST: No reset generated when entering in STOP + * @arg OB_STOP_RST: Reset generated when entering in STOP + * @param OB_STDBY: Reset event when entering Standby mode. + * This parameter can be one of the following values: + * @arg OB_STDBY_NoRST: No reset generated when entering in STANDBY + * @arg OB_STDBY_RST: Reset generated when entering in STANDBY + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check the parameters */ + assert_param(IS_OB_IWDG_SOURCE(OB_IWDG)); + assert_param(IS_OB_STOP_SOURCE(OB_STOP)); + assert_param(IS_OB_STDBY_SOURCE(OB_STDBY)); + + /* Authorize the small information block programming */ + FLASH->OPTKEYR = FLASH_KEY1; + FLASH->OPTKEYR = FLASH_KEY2; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(status == FLASH_COMPLETE) + { + /* Enable the Option Bytes Programming operation */ + FLASH->CR |= CR_OPTPG_Set; + + OB->USER = OB_IWDG | (uint16_t)(OB_STOP | (uint16_t)(OB_STDBY | ((uint16_t)0xF8))); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the program operation is completed, disable the OPTPG Bit */ + FLASH->CR &= CR_OPTPG_Reset; + } + } + /* Return the Option Byte program Status */ + return status; +} + +#ifdef STM32F10X_XL +/** + * @brief Configures to boot from Bank1 or Bank2. + * @note This function can be used only for STM32F10x_XL density devices. + * @param FLASH_BOOT: select the FLASH Bank to boot from. + * This parameter can be one of the following values: + * @arg FLASH_BOOT_Bank1: At startup, if boot pins are set in boot from user Flash + * position and this parameter is selected the device will boot from Bank1(Default). + * @arg FLASH_BOOT_Bank2: At startup, if boot pins are set in boot from user Flash + * position and this parameter is selected the device will boot from Bank2 or Bank1, + * depending on the activation of the bank. The active banks are checked in + * the following order: Bank2, followed by Bank1. + * The active bank is recognized by the value programmed at the base address + * of the respective bank (corresponding to the initial stack pointer value + * in the interrupt vector table). + * For more information, please refer to AN2606 from www.st.com. + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_BootConfig(uint16_t FLASH_BOOT) +{ + FLASH_Status status = FLASH_COMPLETE; + assert_param(IS_FLASH_BOOT(FLASH_BOOT)); + /* Authorize the small information block programming */ + FLASH->OPTKEYR = FLASH_KEY1; + FLASH->OPTKEYR = FLASH_KEY2; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + + if(status == FLASH_COMPLETE) + { + /* Enable the Option Bytes Programming operation */ + FLASH->CR |= CR_OPTPG_Set; + + if(FLASH_BOOT == FLASH_BOOT_Bank1) + { + OB->USER |= OB_USER_BFB2; + } + else + { + OB->USER &= (uint16_t)(~(uint16_t)(OB_USER_BFB2)); + } + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + if(status != FLASH_TIMEOUT) + { + /* if the program operation is completed, disable the OPTPG Bit */ + FLASH->CR &= CR_OPTPG_Reset; + } + } + /* Return the Option Byte program Status */ + return status; +} +#endif /* STM32F10X_XL */ + +/** + * @brief Returns the FLASH User Option Bytes values. + * @note This function can be used for all STM32F10x devices. + * @param None + * @retval The FLASH User Option Bytes values:IWDG_SW(Bit0), RST_STOP(Bit1) + * and RST_STDBY(Bit2). + */ +uint32_t FLASH_GetUserOptionByte(void) +{ + /* Return the User Option Byte */ + return (uint32_t)(FLASH->OBR >> 2); +} + +/** + * @brief Returns the FLASH Write Protection Option Bytes Register value. + * @note This function can be used for all STM32F10x devices. + * @param None + * @retval The FLASH Write Protection Option Bytes Register value + */ +uint32_t FLASH_GetWriteProtectionOptionByte(void) +{ + /* Return the Falsh write protection Register value */ + return (uint32_t)(FLASH->WRPR); +} + +/** + * @brief Checks whether the FLASH Read Out Protection Status is set or not. + * @note This function can be used for all STM32F10x devices. + * @param None + * @retval FLASH ReadOut Protection Status(SET or RESET) + */ +FlagStatus FLASH_GetReadOutProtectionStatus(void) +{ + FlagStatus readoutstatus = RESET; + if ((FLASH->OBR & RDPRT_Mask) != (uint32_t)RESET) + { + readoutstatus = SET; + } + else + { + readoutstatus = RESET; + } + return readoutstatus; +} + +/** + * @brief Checks whether the FLASH Prefetch Buffer status is set or not. + * @note This function can be used for all STM32F10x devices. + * @param None + * @retval FLASH Prefetch Buffer Status (SET or RESET). + */ +FlagStatus FLASH_GetPrefetchBufferStatus(void) +{ + FlagStatus bitstatus = RESET; + + if ((FLASH->ACR & ACR_PRFTBS_Mask) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the new state of FLASH Prefetch Buffer Status (SET or RESET) */ + return bitstatus; +} + +/** + * @brief Enables or disables the specified FLASH interrupts. + * @note This function can be used for all STM32F10x devices. + * - For STM32F10X_XL devices, enables or disables the specified FLASH interrupts + for Bank1 and Bank2. + * - For other devices it enables or disables the specified FLASH interrupts for Bank1. + * @param FLASH_IT: specifies the FLASH interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg FLASH_IT_ERROR: FLASH Error Interrupt + * @arg FLASH_IT_EOP: FLASH end of operation Interrupt + * @param NewState: new state of the specified Flash interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState) +{ +#ifdef STM32F10X_XL + /* Check the parameters */ + assert_param(IS_FLASH_IT(FLASH_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if((FLASH_IT & 0x80000000) != 0x0) + { + if(NewState != DISABLE) + { + /* Enable the interrupt sources */ + FLASH->CR2 |= (FLASH_IT & 0x7FFFFFFF); + } + else + { + /* Disable the interrupt sources */ + FLASH->CR2 &= ~(uint32_t)(FLASH_IT & 0x7FFFFFFF); + } + } + else + { + if(NewState != DISABLE) + { + /* Enable the interrupt sources */ + FLASH->CR |= FLASH_IT; + } + else + { + /* Disable the interrupt sources */ + FLASH->CR &= ~(uint32_t)FLASH_IT; + } + } +#else + /* Check the parameters */ + assert_param(IS_FLASH_IT(FLASH_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if(NewState != DISABLE) + { + /* Enable the interrupt sources */ + FLASH->CR |= FLASH_IT; + } + else + { + /* Disable the interrupt sources */ + FLASH->CR &= ~(uint32_t)FLASH_IT; + } +#endif /* STM32F10X_XL */ +} + +/** + * @brief Checks whether the specified FLASH flag is set or not. + * @note This function can be used for all STM32F10x devices. + * - For STM32F10X_XL devices, this function checks whether the specified + * Bank1 or Bank2 flag is set or not. + * - For other devices, it checks whether the specified Bank1 flag is + * set or not. + * @param FLASH_FLAG: specifies the FLASH flag to check. + * This parameter can be one of the following values: + * @arg FLASH_FLAG_BSY: FLASH Busy flag + * @arg FLASH_FLAG_PGERR: FLASH Program error flag + * @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag + * @arg FLASH_FLAG_EOP: FLASH End of Operation flag + * @arg FLASH_FLAG_OPTERR: FLASH Option Byte error flag + * @retval The new state of FLASH_FLAG (SET or RESET). + */ +FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG) +{ + FlagStatus bitstatus = RESET; + +#ifdef STM32F10X_XL + /* Check the parameters */ + assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)) ; + if(FLASH_FLAG == FLASH_FLAG_OPTERR) + { + if((FLASH->OBR & FLASH_FLAG_OPTERR) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + } + else + { + if((FLASH_FLAG & 0x80000000) != 0x0) + { + if((FLASH->SR2 & FLASH_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + } + else + { + if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + } + } +#else + /* Check the parameters */ + assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)) ; + if(FLASH_FLAG == FLASH_FLAG_OPTERR) + { + if((FLASH->OBR & FLASH_FLAG_OPTERR) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + } + else + { + if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + } +#endif /* STM32F10X_XL */ + + /* Return the new state of FLASH_FLAG (SET or RESET) */ + return bitstatus; +} + +/** + * @brief Clears the FLASHs pending flags. + * @note This function can be used for all STM32F10x devices. + * - For STM32F10X_XL devices, this function clears Bank1 or Bank2s pending flags + * - For other devices, it clears Bank1s pending flags. + * @param FLASH_FLAG: specifies the FLASH flags to clear. + * This parameter can be any combination of the following values: + * @arg FLASH_FLAG_PGERR: FLASH Program error flag + * @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag + * @arg FLASH_FLAG_EOP: FLASH End of Operation flag + * @retval None + */ +void FLASH_ClearFlag(uint32_t FLASH_FLAG) +{ +#ifdef STM32F10X_XL + /* Check the parameters */ + assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)) ; + + if((FLASH_FLAG & 0x80000000) != 0x0) + { + /* Clear the flags */ + FLASH->SR2 = FLASH_FLAG; + } + else + { + /* Clear the flags */ + FLASH->SR = FLASH_FLAG; + } + +#else + /* Check the parameters */ + assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)) ; + + /* Clear the flags */ + FLASH->SR = FLASH_FLAG; +#endif /* STM32F10X_XL */ +} + +/** + * @brief Returns the FLASH Status. + * @note This function can be used for all STM32F10x devices, it is equivalent + * to FLASH_GetBank1Status function. + * @param None + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, + * FLASH_ERROR_WRP or FLASH_COMPLETE + */ +FLASH_Status FLASH_GetStatus(void) +{ + FLASH_Status flashstatus = FLASH_COMPLETE; + + if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY) + { + flashstatus = FLASH_BUSY; + } + else + { + if((FLASH->SR & FLASH_FLAG_PGERR) != 0) + { + flashstatus = FLASH_ERROR_PG; + } + else + { + if((FLASH->SR & FLASH_FLAG_WRPRTERR) != 0 ) + { + flashstatus = FLASH_ERROR_WRP; + } + else + { + flashstatus = FLASH_COMPLETE; + } + } + } + /* Return the Flash Status */ + return flashstatus; +} + +/** + * @brief Returns the FLASH Bank1 Status. + * @note This function can be used for all STM32F10x devices, it is equivalent + * to FLASH_GetStatus function. + * @param None + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, + * FLASH_ERROR_WRP or FLASH_COMPLETE + */ +FLASH_Status FLASH_GetBank1Status(void) +{ + FLASH_Status flashstatus = FLASH_COMPLETE; + + if((FLASH->SR & FLASH_FLAG_BANK1_BSY) == FLASH_FLAG_BSY) + { + flashstatus = FLASH_BUSY; + } + else + { + if((FLASH->SR & FLASH_FLAG_BANK1_PGERR) != 0) + { + flashstatus = FLASH_ERROR_PG; + } + else + { + if((FLASH->SR & FLASH_FLAG_BANK1_WRPRTERR) != 0 ) + { + flashstatus = FLASH_ERROR_WRP; + } + else + { + flashstatus = FLASH_COMPLETE; + } + } + } + /* Return the Flash Status */ + return flashstatus; +} + +#ifdef STM32F10X_XL +/** + * @brief Returns the FLASH Bank2 Status. + * @note This function can be used for STM32F10x_XL density devices. + * @param None + * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, + * FLASH_ERROR_WRP or FLASH_COMPLETE + */ +FLASH_Status FLASH_GetBank2Status(void) +{ + FLASH_Status flashstatus = FLASH_COMPLETE; + + if((FLASH->SR2 & (FLASH_FLAG_BANK2_BSY & 0x7FFFFFFF)) == (FLASH_FLAG_BANK2_BSY & 0x7FFFFFFF)) + { + flashstatus = FLASH_BUSY; + } + else + { + if((FLASH->SR2 & (FLASH_FLAG_BANK2_PGERR & 0x7FFFFFFF)) != 0) + { + flashstatus = FLASH_ERROR_PG; + } + else + { + if((FLASH->SR2 & (FLASH_FLAG_BANK2_WRPRTERR & 0x7FFFFFFF)) != 0 ) + { + flashstatus = FLASH_ERROR_WRP; + } + else + { + flashstatus = FLASH_COMPLETE; + } + } + } + /* Return the Flash Status */ + return flashstatus; +} +#endif /* STM32F10X_XL */ +/** + * @brief Waits for a Flash operation to complete or a TIMEOUT to occur. + * @note This function can be used for all STM32F10x devices, + * it is equivalent to FLASH_WaitForLastBank1Operation. + * - For STM32F10X_XL devices this function waits for a Bank1 Flash operation + * to complete or a TIMEOUT to occur. + * - For all other devices it waits for a Flash operation to complete + * or a TIMEOUT to occur. + * @param Timeout: FLASH progamming Timeout + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check for the Flash Status */ + status = FLASH_GetBank1Status(); + /* Wait for a Flash operation to complete or a TIMEOUT to occur */ + while((status == FLASH_BUSY) && (Timeout != 0x00)) + { + status = FLASH_GetBank1Status(); + Timeout--; + } + if(Timeout == 0x00 ) + { + status = FLASH_TIMEOUT; + } + /* Return the operation status */ + return status; +} + +/** + * @brief Waits for a Flash operation on Bank1 to complete or a TIMEOUT to occur. + * @note This function can be used for all STM32F10x devices, + * it is equivalent to FLASH_WaitForLastOperation. + * @param Timeout: FLASH progamming Timeout + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_WaitForLastBank1Operation(uint32_t Timeout) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check for the Flash Status */ + status = FLASH_GetBank1Status(); + /* Wait for a Flash operation to complete or a TIMEOUT to occur */ + while((status == FLASH_FLAG_BANK1_BSY) && (Timeout != 0x00)) + { + status = FLASH_GetBank1Status(); + Timeout--; + } + if(Timeout == 0x00 ) + { + status = FLASH_TIMEOUT; + } + /* Return the operation status */ + return status; +} + +#ifdef STM32F10X_XL +/** + * @brief Waits for a Flash operation on Bank2 to complete or a TIMEOUT to occur. + * @note This function can be used only for STM32F10x_XL density devices. + * @param Timeout: FLASH progamming Timeout + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_WaitForLastBank2Operation(uint32_t Timeout) +{ + FLASH_Status status = FLASH_COMPLETE; + + /* Check for the Flash Status */ + status = FLASH_GetBank2Status(); + /* Wait for a Flash operation to complete or a TIMEOUT to occur */ + while((status == (FLASH_FLAG_BANK2_BSY & 0x7FFFFFFF)) && (Timeout != 0x00)) + { + status = FLASH_GetBank2Status(); + Timeout--; + } + if(Timeout == 0x00 ) + { + status = FLASH_TIMEOUT; + } + /* Return the operation status */ + return status; +} +#endif /* STM32F10X_XL */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_fsmc.c b/example/libs_stm/src/stm32f10x/stm32f10x_fsmc.c new file mode 100644 index 000000000..d04221942 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_fsmc.c @@ -0,0 +1,858 @@ +/** + ****************************************************************************** + * @file stm32f10x_fsmc.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the FSMC firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_fsmc.h" +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup FSMC + * @brief FSMC driver modules + * @{ + */ + +/** @defgroup FSMC_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + +/** @defgroup FSMC_Private_Defines + * @{ + */ + +/* --------------------- FSMC registers bit mask ---------------------------- */ + +/* FSMC BCRx Mask */ +#define BCR_MBKEN_Set ((uint32_t)0x00000001) +#define BCR_MBKEN_Reset ((uint32_t)0x000FFFFE) +#define BCR_FACCEN_Set ((uint32_t)0x00000040) + +/* FSMC PCRx Mask */ +#define PCR_PBKEN_Set ((uint32_t)0x00000004) +#define PCR_PBKEN_Reset ((uint32_t)0x000FFFFB) +#define PCR_ECCEN_Set ((uint32_t)0x00000040) +#define PCR_ECCEN_Reset ((uint32_t)0x000FFFBF) +#define PCR_MemoryType_NAND ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup FSMC_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup FSMC_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup FSMC_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup FSMC_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the FSMC NOR/SRAM Banks registers to their default + * reset values. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank1_NORSRAM1: FSMC Bank1 NOR/SRAM1 + * @arg FSMC_Bank1_NORSRAM2: FSMC Bank1 NOR/SRAM2 + * @arg FSMC_Bank1_NORSRAM3: FSMC Bank1 NOR/SRAM3 + * @arg FSMC_Bank1_NORSRAM4: FSMC Bank1 NOR/SRAM4 + * @retval None + */ +void FSMC_NORSRAMDeInit(uint32_t FSMC_Bank) +{ + /* Check the parameter */ + assert_param(IS_FSMC_NORSRAM_BANK(FSMC_Bank)); + + /* FSMC_Bank1_NORSRAM1 */ + if(FSMC_Bank == FSMC_Bank1_NORSRAM1) + { + FSMC_Bank1->BTCR[FSMC_Bank] = 0x000030DB; + } + /* FSMC_Bank1_NORSRAM2, FSMC_Bank1_NORSRAM3 or FSMC_Bank1_NORSRAM4 */ + else + { + FSMC_Bank1->BTCR[FSMC_Bank] = 0x000030D2; + } + FSMC_Bank1->BTCR[FSMC_Bank + 1] = 0x0FFFFFFF; + FSMC_Bank1E->BWTR[FSMC_Bank] = 0x0FFFFFFF; +} + +/** + * @brief Deinitializes the FSMC NAND Banks registers to their default reset values. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @retval None + */ +void FSMC_NANDDeInit(uint32_t FSMC_Bank) +{ + /* Check the parameter */ + assert_param(IS_FSMC_NAND_BANK(FSMC_Bank)); + + if(FSMC_Bank == FSMC_Bank2_NAND) + { + /* Set the FSMC_Bank2 registers to their reset values */ + FSMC_Bank2->PCR2 = 0x00000018; + FSMC_Bank2->SR2 = 0x00000040; + FSMC_Bank2->PMEM2 = 0xFCFCFCFC; + FSMC_Bank2->PATT2 = 0xFCFCFCFC; + } + /* FSMC_Bank3_NAND */ + else + { + /* Set the FSMC_Bank3 registers to their reset values */ + FSMC_Bank3->PCR3 = 0x00000018; + FSMC_Bank3->SR3 = 0x00000040; + FSMC_Bank3->PMEM3 = 0xFCFCFCFC; + FSMC_Bank3->PATT3 = 0xFCFCFCFC; + } +} + +/** + * @brief Deinitializes the FSMC PCCARD Bank registers to their default reset values. + * @param None + * @retval None + */ +void FSMC_PCCARDDeInit(void) +{ + /* Set the FSMC_Bank4 registers to their reset values */ + FSMC_Bank4->PCR4 = 0x00000018; + FSMC_Bank4->SR4 = 0x00000000; + FSMC_Bank4->PMEM4 = 0xFCFCFCFC; + FSMC_Bank4->PATT4 = 0xFCFCFCFC; + FSMC_Bank4->PIO4 = 0xFCFCFCFC; +} + +/** + * @brief Initializes the FSMC NOR/SRAM Banks according to the specified + * parameters in the FSMC_NORSRAMInitStruct. + * @param FSMC_NORSRAMInitStruct : pointer to a FSMC_NORSRAMInitTypeDef + * structure that contains the configuration information for + * the FSMC NOR/SRAM specified Banks. + * @retval None + */ +void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct) +{ + /* Check the parameters */ + assert_param(IS_FSMC_NORSRAM_BANK(FSMC_NORSRAMInitStruct->FSMC_Bank)); + assert_param(IS_FSMC_MUX(FSMC_NORSRAMInitStruct->FSMC_DataAddressMux)); + assert_param(IS_FSMC_MEMORY(FSMC_NORSRAMInitStruct->FSMC_MemoryType)); + assert_param(IS_FSMC_MEMORY_WIDTH(FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth)); + assert_param(IS_FSMC_BURSTMODE(FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode)); + assert_param(IS_FSMC_WAIT_POLARITY(FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity)); + assert_param(IS_FSMC_WRAP_MODE(FSMC_NORSRAMInitStruct->FSMC_WrapMode)); + assert_param(IS_FSMC_WAIT_SIGNAL_ACTIVE(FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive)); + assert_param(IS_FSMC_WRITE_OPERATION(FSMC_NORSRAMInitStruct->FSMC_WriteOperation)); + assert_param(IS_FSMC_WAITE_SIGNAL(FSMC_NORSRAMInitStruct->FSMC_WaitSignal)); + assert_param(IS_FSMC_EXTENDED_MODE(FSMC_NORSRAMInitStruct->FSMC_ExtendedMode)); + assert_param(IS_FSMC_WRITE_BURST(FSMC_NORSRAMInitStruct->FSMC_WriteBurst)); + assert_param(IS_FSMC_ADDRESS_SETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime)); + assert_param(IS_FSMC_ADDRESS_HOLD_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime)); + assert_param(IS_FSMC_DATASETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime)); + assert_param(IS_FSMC_TURNAROUND_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration)); + assert_param(IS_FSMC_CLK_DIV(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision)); + assert_param(IS_FSMC_DATA_LATENCY(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency)); + assert_param(IS_FSMC_ACCESS_MODE(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode)); + + /* Bank1 NOR/SRAM control register configuration */ + FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank] = + (uint32_t)FSMC_NORSRAMInitStruct->FSMC_DataAddressMux | + FSMC_NORSRAMInitStruct->FSMC_MemoryType | + FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth | + FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode | + FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity | + FSMC_NORSRAMInitStruct->FSMC_WrapMode | + FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive | + FSMC_NORSRAMInitStruct->FSMC_WriteOperation | + FSMC_NORSRAMInitStruct->FSMC_WaitSignal | + FSMC_NORSRAMInitStruct->FSMC_ExtendedMode | + FSMC_NORSRAMInitStruct->FSMC_WriteBurst; + if(FSMC_NORSRAMInitStruct->FSMC_MemoryType == FSMC_MemoryType_NOR) + { + FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank] |= (uint32_t)BCR_FACCEN_Set; + } + /* Bank1 NOR/SRAM timing register configuration */ + FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank+1] = + (uint32_t)FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime << 4) | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime << 8) | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration << 16) | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision << 20) | + (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency << 24) | + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode; + + + /* Bank1 NOR/SRAM timing register for write configuration, if extended mode is used */ + if(FSMC_NORSRAMInitStruct->FSMC_ExtendedMode == FSMC_ExtendedMode_Enable) + { + assert_param(IS_FSMC_ADDRESS_SETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime)); + assert_param(IS_FSMC_ADDRESS_HOLD_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime)); + assert_param(IS_FSMC_DATASETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime)); + assert_param(IS_FSMC_CLK_DIV(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision)); + assert_param(IS_FSMC_DATA_LATENCY(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency)); + assert_param(IS_FSMC_ACCESS_MODE(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode)); + FSMC_Bank1E->BWTR[FSMC_NORSRAMInitStruct->FSMC_Bank] = + (uint32_t)FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime | + (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime << 4 )| + (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime << 8) | + (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision << 20) | + (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency << 24) | + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode; + } + else + { + FSMC_Bank1E->BWTR[FSMC_NORSRAMInitStruct->FSMC_Bank] = 0x0FFFFFFF; + } +} + +/** + * @brief Initializes the FSMC NAND Banks according to the specified + * parameters in the FSMC_NANDInitStruct. + * @param FSMC_NANDInitStruct : pointer to a FSMC_NANDInitTypeDef + * structure that contains the configuration information for the FSMC NAND specified Banks. + * @retval None + */ +void FSMC_NANDInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct) +{ + uint32_t tmppcr = 0x00000000, tmppmem = 0x00000000, tmppatt = 0x00000000; + + /* Check the parameters */ + assert_param( IS_FSMC_NAND_BANK(FSMC_NANDInitStruct->FSMC_Bank)); + assert_param( IS_FSMC_WAIT_FEATURE(FSMC_NANDInitStruct->FSMC_Waitfeature)); + assert_param( IS_FSMC_MEMORY_WIDTH(FSMC_NANDInitStruct->FSMC_MemoryDataWidth)); + assert_param( IS_FSMC_ECC_STATE(FSMC_NANDInitStruct->FSMC_ECC)); + assert_param( IS_FSMC_ECCPAGE_SIZE(FSMC_NANDInitStruct->FSMC_ECCPageSize)); + assert_param( IS_FSMC_TCLR_TIME(FSMC_NANDInitStruct->FSMC_TCLRSetupTime)); + assert_param( IS_FSMC_TAR_TIME(FSMC_NANDInitStruct->FSMC_TARSetupTime)); + assert_param(IS_FSMC_SETUP_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime)); + assert_param(IS_FSMC_SETUP_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime)); + + /* Set the tmppcr value according to FSMC_NANDInitStruct parameters */ + tmppcr = (uint32_t)FSMC_NANDInitStruct->FSMC_Waitfeature | + PCR_MemoryType_NAND | + FSMC_NANDInitStruct->FSMC_MemoryDataWidth | + FSMC_NANDInitStruct->FSMC_ECC | + FSMC_NANDInitStruct->FSMC_ECCPageSize | + (FSMC_NANDInitStruct->FSMC_TCLRSetupTime << 9 )| + (FSMC_NANDInitStruct->FSMC_TARSetupTime << 13); + + /* Set tmppmem value according to FSMC_CommonSpaceTimingStructure parameters */ + tmppmem = (uint32_t)FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime | + (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime << 8) | + (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime << 16)| + (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime << 24); + + /* Set tmppatt value according to FSMC_AttributeSpaceTimingStructure parameters */ + tmppatt = (uint32_t)FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime | + (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime << 8) | + (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime << 16)| + (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime << 24); + + if(FSMC_NANDInitStruct->FSMC_Bank == FSMC_Bank2_NAND) + { + /* FSMC_Bank2_NAND registers configuration */ + FSMC_Bank2->PCR2 = tmppcr; + FSMC_Bank2->PMEM2 = tmppmem; + FSMC_Bank2->PATT2 = tmppatt; + } + else + { + /* FSMC_Bank3_NAND registers configuration */ + FSMC_Bank3->PCR3 = tmppcr; + FSMC_Bank3->PMEM3 = tmppmem; + FSMC_Bank3->PATT3 = tmppatt; + } +} + +/** + * @brief Initializes the FSMC PCCARD Bank according to the specified + * parameters in the FSMC_PCCARDInitStruct. + * @param FSMC_PCCARDInitStruct : pointer to a FSMC_PCCARDInitTypeDef + * structure that contains the configuration information for the FSMC PCCARD Bank. + * @retval None + */ +void FSMC_PCCARDInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct) +{ + /* Check the parameters */ + assert_param(IS_FSMC_WAIT_FEATURE(FSMC_PCCARDInitStruct->FSMC_Waitfeature)); + assert_param(IS_FSMC_TCLR_TIME(FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime)); + assert_param(IS_FSMC_TAR_TIME(FSMC_PCCARDInitStruct->FSMC_TARSetupTime)); + + assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime)); + + assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime)); + assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime)); + + /* Set the PCR4 register value according to FSMC_PCCARDInitStruct parameters */ + FSMC_Bank4->PCR4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_Waitfeature | + FSMC_MemoryDataWidth_16b | + (FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime << 9) | + (FSMC_PCCARDInitStruct->FSMC_TARSetupTime << 13); + + /* Set PMEM4 register value according to FSMC_CommonSpaceTimingStructure parameters */ + FSMC_Bank4->PMEM4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime | + (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime << 8) | + (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime << 16)| + (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime << 24); + + /* Set PATT4 register value according to FSMC_AttributeSpaceTimingStructure parameters */ + FSMC_Bank4->PATT4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime | + (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime << 8) | + (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime << 16)| + (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime << 24); + + /* Set PIO4 register value according to FSMC_IOSpaceTimingStructure parameters */ + FSMC_Bank4->PIO4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime | + (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime << 8) | + (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime << 16)| + (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime << 24); +} + +/** + * @brief Fills each FSMC_NORSRAMInitStruct member with its default value. + * @param FSMC_NORSRAMInitStruct: pointer to a FSMC_NORSRAMInitTypeDef + * structure which will be initialized. + * @retval None + */ +void FSMC_NORSRAMStructInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct) +{ + /* Reset NOR/SRAM Init structure parameters values */ + FSMC_NORSRAMInitStruct->FSMC_Bank = FSMC_Bank1_NORSRAM1; + FSMC_NORSRAMInitStruct->FSMC_DataAddressMux = FSMC_DataAddressMux_Enable; + FSMC_NORSRAMInitStruct->FSMC_MemoryType = FSMC_MemoryType_SRAM; + FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; + FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; + FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; + FSMC_NORSRAMInitStruct->FSMC_WrapMode = FSMC_WrapMode_Disable; + FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; + FSMC_NORSRAMInitStruct->FSMC_WriteOperation = FSMC_WriteOperation_Enable; + FSMC_NORSRAMInitStruct->FSMC_WaitSignal = FSMC_WaitSignal_Enable; + FSMC_NORSRAMInitStruct->FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; + FSMC_NORSRAMInitStruct->FSMC_WriteBurst = FSMC_WriteBurst_Disable; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime = 0xFF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency = 0xF; + FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode = FSMC_AccessMode_A; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime = 0xFF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_BusTurnAroundDuration = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency = 0xF; + FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode = FSMC_AccessMode_A; +} + +/** + * @brief Fills each FSMC_NANDInitStruct member with its default value. + * @param FSMC_NANDInitStruct: pointer to a FSMC_NANDInitTypeDef + * structure which will be initialized. + * @retval None + */ +void FSMC_NANDStructInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct) +{ + /* Reset NAND Init structure parameters values */ + FSMC_NANDInitStruct->FSMC_Bank = FSMC_Bank2_NAND; + FSMC_NANDInitStruct->FSMC_Waitfeature = FSMC_Waitfeature_Disable; + FSMC_NANDInitStruct->FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; + FSMC_NANDInitStruct->FSMC_ECC = FSMC_ECC_Disable; + FSMC_NANDInitStruct->FSMC_ECCPageSize = FSMC_ECCPageSize_256Bytes; + FSMC_NANDInitStruct->FSMC_TCLRSetupTime = 0x0; + FSMC_NANDInitStruct->FSMC_TARSetupTime = 0x0; + FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime = 0xFC; + FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; + FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; + FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; + FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime = 0xFC; + FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; + FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; + FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; +} + +/** + * @brief Fills each FSMC_PCCARDInitStruct member with its default value. + * @param FSMC_PCCARDInitStruct: pointer to a FSMC_PCCARDInitTypeDef + * structure which will be initialized. + * @retval None + */ +void FSMC_PCCARDStructInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct) +{ + /* Reset PCCARD Init structure parameters values */ + FSMC_PCCARDInitStruct->FSMC_Waitfeature = FSMC_Waitfeature_Disable; + FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime = 0x0; + FSMC_PCCARDInitStruct->FSMC_TARSetupTime = 0x0; + FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; + FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; +} + +/** + * @brief Enables or disables the specified NOR/SRAM Memory Bank. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank1_NORSRAM1: FSMC Bank1 NOR/SRAM1 + * @arg FSMC_Bank1_NORSRAM2: FSMC Bank1 NOR/SRAM2 + * @arg FSMC_Bank1_NORSRAM3: FSMC Bank1 NOR/SRAM3 + * @arg FSMC_Bank1_NORSRAM4: FSMC Bank1 NOR/SRAM4 + * @param NewState: new state of the FSMC_Bank. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState) +{ + assert_param(IS_FSMC_NORSRAM_BANK(FSMC_Bank)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected NOR/SRAM Bank by setting the PBKEN bit in the BCRx register */ + FSMC_Bank1->BTCR[FSMC_Bank] |= BCR_MBKEN_Set; + } + else + { + /* Disable the selected NOR/SRAM Bank by clearing the PBKEN bit in the BCRx register */ + FSMC_Bank1->BTCR[FSMC_Bank] &= BCR_MBKEN_Reset; + } +} + +/** + * @brief Enables or disables the specified NAND Memory Bank. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @param NewState: new state of the FSMC_Bank. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState) +{ + assert_param(IS_FSMC_NAND_BANK(FSMC_Bank)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected NAND Bank by setting the PBKEN bit in the PCRx register */ + if(FSMC_Bank == FSMC_Bank2_NAND) + { + FSMC_Bank2->PCR2 |= PCR_PBKEN_Set; + } + else + { + FSMC_Bank3->PCR3 |= PCR_PBKEN_Set; + } + } + else + { + /* Disable the selected NAND Bank by clearing the PBKEN bit in the PCRx register */ + if(FSMC_Bank == FSMC_Bank2_NAND) + { + FSMC_Bank2->PCR2 &= PCR_PBKEN_Reset; + } + else + { + FSMC_Bank3->PCR3 &= PCR_PBKEN_Reset; + } + } +} + +/** + * @brief Enables or disables the PCCARD Memory Bank. + * @param NewState: new state of the PCCARD Memory Bank. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FSMC_PCCARDCmd(FunctionalState NewState) +{ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the PCCARD Bank by setting the PBKEN bit in the PCR4 register */ + FSMC_Bank4->PCR4 |= PCR_PBKEN_Set; + } + else + { + /* Disable the PCCARD Bank by clearing the PBKEN bit in the PCR4 register */ + FSMC_Bank4->PCR4 &= PCR_PBKEN_Reset; + } +} + +/** + * @brief Enables or disables the FSMC NAND ECC feature. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @param NewState: new state of the FSMC NAND ECC feature. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FSMC_NANDECCCmd(uint32_t FSMC_Bank, FunctionalState NewState) +{ + assert_param(IS_FSMC_NAND_BANK(FSMC_Bank)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected NAND Bank ECC function by setting the ECCEN bit in the PCRx register */ + if(FSMC_Bank == FSMC_Bank2_NAND) + { + FSMC_Bank2->PCR2 |= PCR_ECCEN_Set; + } + else + { + FSMC_Bank3->PCR3 |= PCR_ECCEN_Set; + } + } + else + { + /* Disable the selected NAND Bank ECC function by clearing the ECCEN bit in the PCRx register */ + if(FSMC_Bank == FSMC_Bank2_NAND) + { + FSMC_Bank2->PCR2 &= PCR_ECCEN_Reset; + } + else + { + FSMC_Bank3->PCR3 &= PCR_ECCEN_Reset; + } + } +} + +/** + * @brief Returns the error correction code register value. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @retval The Error Correction Code (ECC) value. + */ +uint32_t FSMC_GetECC(uint32_t FSMC_Bank) +{ + uint32_t eccval = 0x00000000; + + if(FSMC_Bank == FSMC_Bank2_NAND) + { + /* Get the ECCR2 register value */ + eccval = FSMC_Bank2->ECCR2; + } + else + { + /* Get the ECCR3 register value */ + eccval = FSMC_Bank3->ECCR3; + } + /* Return the error correction code value */ + return(eccval); +} + +/** + * @brief Enables or disables the specified FSMC interrupts. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD + * @param FSMC_IT: specifies the FSMC interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt. + * @arg FSMC_IT_Level: Level edge detection interrupt. + * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt. + * @param NewState: new state of the specified FSMC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void FSMC_ITConfig(uint32_t FSMC_Bank, uint32_t FSMC_IT, FunctionalState NewState) +{ + assert_param(IS_FSMC_IT_BANK(FSMC_Bank)); + assert_param(IS_FSMC_IT(FSMC_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected FSMC_Bank2 interrupts */ + if(FSMC_Bank == FSMC_Bank2_NAND) + { + FSMC_Bank2->SR2 |= FSMC_IT; + } + /* Enable the selected FSMC_Bank3 interrupts */ + else if (FSMC_Bank == FSMC_Bank3_NAND) + { + FSMC_Bank3->SR3 |= FSMC_IT; + } + /* Enable the selected FSMC_Bank4 interrupts */ + else + { + FSMC_Bank4->SR4 |= FSMC_IT; + } + } + else + { + /* Disable the selected FSMC_Bank2 interrupts */ + if(FSMC_Bank == FSMC_Bank2_NAND) + { + + FSMC_Bank2->SR2 &= (uint32_t)~FSMC_IT; + } + /* Disable the selected FSMC_Bank3 interrupts */ + else if (FSMC_Bank == FSMC_Bank3_NAND) + { + FSMC_Bank3->SR3 &= (uint32_t)~FSMC_IT; + } + /* Disable the selected FSMC_Bank4 interrupts */ + else + { + FSMC_Bank4->SR4 &= (uint32_t)~FSMC_IT; + } + } +} + +/** + * @brief Checks whether the specified FSMC flag is set or not. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD + * @param FSMC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg FSMC_FLAG_RisingEdge: Rising egde detection Flag. + * @arg FSMC_FLAG_Level: Level detection Flag. + * @arg FSMC_FLAG_FallingEdge: Falling egde detection Flag. + * @arg FSMC_FLAG_FEMPT: Fifo empty Flag. + * @retval The new state of FSMC_FLAG (SET or RESET). + */ +FlagStatus FSMC_GetFlagStatus(uint32_t FSMC_Bank, uint32_t FSMC_FLAG) +{ + FlagStatus bitstatus = RESET; + uint32_t tmpsr = 0x00000000; + + /* Check the parameters */ + assert_param(IS_FSMC_GETFLAG_BANK(FSMC_Bank)); + assert_param(IS_FSMC_GET_FLAG(FSMC_FLAG)); + + if(FSMC_Bank == FSMC_Bank2_NAND) + { + tmpsr = FSMC_Bank2->SR2; + } + else if(FSMC_Bank == FSMC_Bank3_NAND) + { + tmpsr = FSMC_Bank3->SR3; + } + /* FSMC_Bank4_PCCARD*/ + else + { + tmpsr = FSMC_Bank4->SR4; + } + + /* Get the flag status */ + if ((tmpsr & FSMC_FLAG) != (uint16_t)RESET ) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the flag status */ + return bitstatus; +} + +/** + * @brief Clears the FSMCs pending flags. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD + * @param FSMC_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg FSMC_FLAG_RisingEdge: Rising egde detection Flag. + * @arg FSMC_FLAG_Level: Level detection Flag. + * @arg FSMC_FLAG_FallingEdge: Falling egde detection Flag. + * @retval None + */ +void FSMC_ClearFlag(uint32_t FSMC_Bank, uint32_t FSMC_FLAG) +{ + /* Check the parameters */ + assert_param(IS_FSMC_GETFLAG_BANK(FSMC_Bank)); + assert_param(IS_FSMC_CLEAR_FLAG(FSMC_FLAG)) ; + + if(FSMC_Bank == FSMC_Bank2_NAND) + { + FSMC_Bank2->SR2 &= ~FSMC_FLAG; + } + else if(FSMC_Bank == FSMC_Bank3_NAND) + { + FSMC_Bank3->SR3 &= ~FSMC_FLAG; + } + /* FSMC_Bank4_PCCARD*/ + else + { + FSMC_Bank4->SR4 &= ~FSMC_FLAG; + } +} + +/** + * @brief Checks whether the specified FSMC interrupt has occurred or not. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD + * @param FSMC_IT: specifies the FSMC interrupt source to check. + * This parameter can be one of the following values: + * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt. + * @arg FSMC_IT_Level: Level edge detection interrupt. + * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt. + * @retval The new state of FSMC_IT (SET or RESET). + */ +ITStatus FSMC_GetITStatus(uint32_t FSMC_Bank, uint32_t FSMC_IT) +{ + ITStatus bitstatus = RESET; + uint32_t tmpsr = 0x0, itstatus = 0x0, itenable = 0x0; + + /* Check the parameters */ + assert_param(IS_FSMC_IT_BANK(FSMC_Bank)); + assert_param(IS_FSMC_GET_IT(FSMC_IT)); + + if(FSMC_Bank == FSMC_Bank2_NAND) + { + tmpsr = FSMC_Bank2->SR2; + } + else if(FSMC_Bank == FSMC_Bank3_NAND) + { + tmpsr = FSMC_Bank3->SR3; + } + /* FSMC_Bank4_PCCARD*/ + else + { + tmpsr = FSMC_Bank4->SR4; + } + + itstatus = tmpsr & FSMC_IT; + + itenable = tmpsr & (FSMC_IT >> 3); + if ((itstatus != (uint32_t)RESET) && (itenable != (uint32_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the FSMCs interrupt pending bits. + * @param FSMC_Bank: specifies the FSMC Bank to be used + * This parameter can be one of the following values: + * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND + * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND + * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD + * @param FSMC_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt. + * @arg FSMC_IT_Level: Level edge detection interrupt. + * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt. + * @retval None + */ +void FSMC_ClearITPendingBit(uint32_t FSMC_Bank, uint32_t FSMC_IT) +{ + /* Check the parameters */ + assert_param(IS_FSMC_IT_BANK(FSMC_Bank)); + assert_param(IS_FSMC_IT(FSMC_IT)); + + if(FSMC_Bank == FSMC_Bank2_NAND) + { + FSMC_Bank2->SR2 &= ~(FSMC_IT >> 3); + } + else if(FSMC_Bank == FSMC_Bank3_NAND) + { + FSMC_Bank3->SR3 &= ~(FSMC_IT >> 3); + } + /* FSMC_Bank4_PCCARD*/ + else + { + FSMC_Bank4->SR4 &= ~(FSMC_IT >> 3); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_gpio.c b/example/libs_stm/src/stm32f10x/stm32f10x_gpio.c new file mode 100644 index 000000000..0978e986e --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_gpio.c @@ -0,0 +1,642 @@ +/** + ****************************************************************************** + * @file stm32f10x_gpio.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the GPIO firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_gpio.h" +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup GPIO + * @brief GPIO driver modules + * @{ + */ + +/** @defgroup GPIO_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup GPIO_Private_Defines + * @{ + */ + +/* ------------ RCC registers bit address in the alias region ----------------*/ +#define AFIO_OFFSET (AFIO_BASE - PERIPH_BASE) + +/* --- EVENTCR Register -----*/ + +/* Alias word address of EVOE bit */ +#define EVCR_OFFSET (AFIO_OFFSET + 0x00) +#define EVOE_BitNumber ((uint8_t)0x07) +#define EVCR_EVOE_BB (PERIPH_BB_BASE + (EVCR_OFFSET * 32) + (EVOE_BitNumber * 4)) + + +/* --- MAPR Register ---*/ +/* Alias word address of MII_RMII_SEL bit */ +#define MAPR_OFFSET (AFIO_OFFSET + 0x04) +#define MII_RMII_SEL_BitNumber ((u8)0x17) +#define MAPR_MII_RMII_SEL_BB (PERIPH_BB_BASE + (MAPR_OFFSET * 32) + (MII_RMII_SEL_BitNumber * 4)) + + +#define EVCR_PORTPINCONFIG_MASK ((uint16_t)0xFF80) +#define LSB_MASK ((uint16_t)0xFFFF) +#define DBGAFR_POSITION_MASK ((uint32_t)0x000F0000) +#define DBGAFR_SWJCFG_MASK ((uint32_t)0xF0FFFFFF) +#define DBGAFR_LOCATION_MASK ((uint32_t)0x00200000) +#define DBGAFR_NUMBITS_MASK ((uint32_t)0x00100000) +/** + * @} + */ + +/** @defgroup GPIO_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup GPIO_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup GPIO_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup GPIO_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the GPIOx peripheral registers to their default reset values. + * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. + * @retval None + */ +void GPIO_DeInit(GPIO_TypeDef* GPIOx) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + if (GPIOx == GPIOA) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE); + } + else if (GPIOx == GPIOB) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE); + } + else if (GPIOx == GPIOC) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, DISABLE); + } + else if (GPIOx == GPIOD) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOD, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOD, DISABLE); + } + else if (GPIOx == GPIOE) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOE, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOE, DISABLE); + } + else if (GPIOx == GPIOF) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOF, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOF, DISABLE); + } + else + { + if (GPIOx == GPIOG) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOG, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOG, DISABLE); + } + } +} + +/** + * @brief Deinitializes the Alternate Functions (remap, event control + * and EXTI configuration) registers to their default reset values. + * @param None + * @retval None + */ +void GPIO_AFIODeInit(void) +{ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, DISABLE); +} + +/** + * @brief Initializes the GPIOx peripheral according to the specified + * parameters in the GPIO_InitStruct. + * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. + * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that + * contains the configuration information for the specified GPIO peripheral. + * @retval None + */ +void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) +{ + uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00; + uint32_t tmpreg = 0x00, pinmask = 0x00; + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); + assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); + +/*---------------------------- GPIO Mode Configuration -----------------------*/ + currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F); + if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00) + { + /* Check the parameters */ + assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed)); + /* Output mode */ + currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed; + } +/*---------------------------- GPIO CRL Configuration ------------------------*/ + /* Configure the eight low port pins */ + if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00) + { + tmpreg = GPIOx->CRL; + for (pinpos = 0x00; pinpos < 0x08; pinpos++) + { + pos = ((uint32_t)0x01) << pinpos; + /* Get the port pins position */ + currentpin = (GPIO_InitStruct->GPIO_Pin) & pos; + if (currentpin == pos) + { + pos = pinpos << 2; + /* Clear the corresponding low control register bits */ + pinmask = ((uint32_t)0x0F) << pos; + tmpreg &= ~pinmask; + /* Write the mode configuration in the corresponding bits */ + tmpreg |= (currentmode << pos); + /* Reset the corresponding ODR bit */ + if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD) + { + GPIOx->BRR = (((uint32_t)0x01) << pinpos); + } + else + { + /* Set the corresponding ODR bit */ + if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU) + { + GPIOx->BSRR = (((uint32_t)0x01) << pinpos); + } + } + } + } + GPIOx->CRL = tmpreg; + } +/*---------------------------- GPIO CRH Configuration ------------------------*/ + /* Configure the eight high port pins */ + if (GPIO_InitStruct->GPIO_Pin > 0x00FF) + { + tmpreg = GPIOx->CRH; + for (pinpos = 0x00; pinpos < 0x08; pinpos++) + { + pos = (((uint32_t)0x01) << (pinpos + 0x08)); + /* Get the port pins position */ + currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos); + if (currentpin == pos) + { + pos = pinpos << 2; + /* Clear the corresponding high control register bits */ + pinmask = ((uint32_t)0x0F) << pos; + tmpreg &= ~pinmask; + /* Write the mode configuration in the corresponding bits */ + tmpreg |= (currentmode << pos); + /* Reset the corresponding ODR bit */ + if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD) + { + GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08)); + } + /* Set the corresponding ODR bit */ + if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU) + { + GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08)); + } + } + } + GPIOx->CRH = tmpreg; + } +} + +/** + * @brief Fills each GPIO_InitStruct member with its default value. + * @param GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct) +{ + /* Reset GPIO init structure parameters values */ + GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All; + GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN_FLOATING; +} + +/** + * @brief Reads the specified input port pin. + * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bit to read. + * This parameter can be GPIO_Pin_x where x can be (0..15). + * @retval The input port pin value. + */ +uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + uint8_t bitstatus = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + + if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET) + { + bitstatus = (uint8_t)Bit_SET; + } + else + { + bitstatus = (uint8_t)Bit_RESET; + } + return bitstatus; +} + +/** + * @brief Reads the specified GPIO input data port. + * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. + * @retval GPIO input data port value. + */ +uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + return ((uint16_t)GPIOx->IDR); +} + +/** + * @brief Reads the specified output data port bit. + * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bit to read. + * This parameter can be GPIO_Pin_x where x can be (0..15). + * @retval The output port pin value. + */ +uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + uint8_t bitstatus = 0x00; + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + + if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET) + { + bitstatus = (uint8_t)Bit_SET; + } + else + { + bitstatus = (uint8_t)Bit_RESET; + } + return bitstatus; +} + +/** + * @brief Reads the specified GPIO output data port. + * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. + * @retval GPIO output data port value. + */ +uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + return ((uint16_t)GPIOx->ODR); +} + +/** + * @brief Sets the selected data port bits. + * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bits to be written. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @retval None + */ +void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + GPIOx->BSRR = GPIO_Pin; +} + +/** + * @brief Clears the selected data port bits. + * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bits to be written. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @retval None + */ +void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + GPIOx->BRR = GPIO_Pin; +} + +/** + * @brief Sets or clears the selected data port bit. + * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bit to be written. + * This parameter can be one of GPIO_Pin_x where x can be (0..15). + * @param BitVal: specifies the value to be written to the selected bit. + * This parameter can be one of the BitAction enum values: + * @arg Bit_RESET: to clear the port pin + * @arg Bit_SET: to set the port pin + * @retval None + */ +void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_BIT_ACTION(BitVal)); + + if (BitVal != Bit_RESET) + { + GPIOx->BSRR = GPIO_Pin; + } + else + { + GPIOx->BRR = GPIO_Pin; + } +} + +/** + * @brief Writes data to the specified GPIO data port. + * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. + * @param PortVal: specifies the value to be written to the port output data register. + * @retval None + */ +void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal) +{ + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + + GPIOx->ODR = PortVal; +} + +/** + * @brief Locks GPIO Pins configuration registers. + * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. + * @param GPIO_Pin: specifies the port bit to be written. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @retval None + */ +void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + uint32_t tmp = 0x00010000; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + tmp |= GPIO_Pin; + /* Set LCKK bit */ + GPIOx->LCKR = tmp; + /* Reset LCKK bit */ + GPIOx->LCKR = GPIO_Pin; + /* Set LCKK bit */ + GPIOx->LCKR = tmp; + /* Read LCKK bit*/ + tmp = GPIOx->LCKR; + /* Read LCKK bit*/ + tmp = GPIOx->LCKR; +} + +/** + * @brief Selects the GPIO pin used as Event output. + * @param GPIO_PortSource: selects the GPIO port to be used as source + * for Event output. + * This parameter can be GPIO_PortSourceGPIOx where x can be (A..E). + * @param GPIO_PinSource: specifies the pin for the Event output. + * This parameter can be GPIO_PinSourcex where x can be (0..15). + * @retval None + */ +void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource) +{ + uint32_t tmpreg = 0x00; + /* Check the parameters */ + assert_param(IS_GPIO_EVENTOUT_PORT_SOURCE(GPIO_PortSource)); + assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource)); + + tmpreg = AFIO->EVCR; + /* Clear the PORT[6:4] and PIN[3:0] bits */ + tmpreg &= EVCR_PORTPINCONFIG_MASK; + tmpreg |= (uint32_t)GPIO_PortSource << 0x04; + tmpreg |= GPIO_PinSource; + AFIO->EVCR = tmpreg; +} + +/** + * @brief Enables or disables the Event Output. + * @param NewState: new state of the Event output. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void GPIO_EventOutputCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) EVCR_EVOE_BB = (uint32_t)NewState; +} + +/** + * @brief Changes the mapping of the specified pin. + * @param GPIO_Remap: selects the pin to remap. + * This parameter can be one of the following values: + * @arg GPIO_Remap_SPI1 + * @arg GPIO_Remap_I2C1 + * @arg GPIO_Remap_USART1 + * @arg GPIO_Remap_USART2 + * @arg GPIO_PartialRemap_USART3 + * @arg GPIO_FullRemap_USART3 + * @arg GPIO_PartialRemap_TIM1 + * @arg GPIO_FullRemap_TIM1 + * @arg GPIO_PartialRemap1_TIM2 + * @arg GPIO_PartialRemap2_TIM2 + * @arg GPIO_FullRemap_TIM2 + * @arg GPIO_PartialRemap_TIM3 + * @arg GPIO_FullRemap_TIM3 + * @arg GPIO_Remap_TIM4 + * @arg GPIO_Remap1_CAN1 + * @arg GPIO_Remap2_CAN1 + * @arg GPIO_Remap_PD01 + * @arg GPIO_Remap_TIM5CH4_LSI + * @arg GPIO_Remap_ADC1_ETRGINJ + * @arg GPIO_Remap_ADC1_ETRGREG + * @arg GPIO_Remap_ADC2_ETRGINJ + * @arg GPIO_Remap_ADC2_ETRGREG + * @arg GPIO_Remap_ETH + * @arg GPIO_Remap_CAN2 + * @arg GPIO_Remap_SWJ_NoJTRST + * @arg GPIO_Remap_SWJ_JTAGDisable + * @arg GPIO_Remap_SWJ_Disable + * @arg GPIO_Remap_SPI3 + * @arg GPIO_Remap_TIM2ITR1_PTP_SOF + * @arg GPIO_Remap_PTP_PPS + * @arg GPIO_Remap_TIM15 + * @arg GPIO_Remap_TIM16 + * @arg GPIO_Remap_TIM17 + * @arg GPIO_Remap_CEC + * @arg GPIO_Remap_TIM1_DMA + * @arg GPIO_Remap_TIM9 + * @arg GPIO_Remap_TIM10 + * @arg GPIO_Remap_TIM11 + * @arg GPIO_Remap_TIM13 + * @arg GPIO_Remap_TIM14 + * @arg GPIO_Remap_FSMC_NADV + * @note If the GPIO_Remap_TIM2ITR1_PTP_SOF is enabled the TIM2 ITR1 is connected + * to Ethernet PTP output. When Reset TIM2 ITR1 is connected to USB OTG SOF output. + * @param NewState: new state of the port pin remapping. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState) +{ + uint32_t tmp = 0x00, tmp1 = 0x00, tmpreg = 0x00, tmpmask = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_REMAP(GPIO_Remap)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if((GPIO_Remap & 0x80000000) == 0x80000000) + { + tmpreg = AFIO->MAPR2; + } + else + { + tmpreg = AFIO->MAPR; + } + + tmpmask = (GPIO_Remap & DBGAFR_POSITION_MASK) >> 0x10; + tmp = GPIO_Remap & LSB_MASK; + + if ((GPIO_Remap & (DBGAFR_LOCATION_MASK | DBGAFR_NUMBITS_MASK)) == (DBGAFR_LOCATION_MASK | DBGAFR_NUMBITS_MASK)) + { + tmpreg &= DBGAFR_SWJCFG_MASK; + AFIO->MAPR &= DBGAFR_SWJCFG_MASK; + } + else if ((GPIO_Remap & DBGAFR_NUMBITS_MASK) == DBGAFR_NUMBITS_MASK) + { + tmp1 = ((uint32_t)0x03) << tmpmask; + tmpreg &= ~tmp1; + tmpreg |= ~DBGAFR_SWJCFG_MASK; + } + else + { + tmpreg &= ~(tmp << ((GPIO_Remap >> 0x15)*0x10)); + tmpreg |= ~DBGAFR_SWJCFG_MASK; + } + + if (NewState != DISABLE) + { + tmpreg |= (tmp << ((GPIO_Remap >> 0x15)*0x10)); + } + + if((GPIO_Remap & 0x80000000) == 0x80000000) + { + AFIO->MAPR2 = tmpreg; + } + else + { + AFIO->MAPR = tmpreg; + } +} + +/** + * @brief Selects the GPIO pin used as EXTI Line. + * @param GPIO_PortSource: selects the GPIO port to be used as source for EXTI lines. + * This parameter can be GPIO_PortSourceGPIOx where x can be (A..G). + * @param GPIO_PinSource: specifies the EXTI line to be configured. + * This parameter can be GPIO_PinSourcex where x can be (0..15). + * @retval None + */ +void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource) +{ + uint32_t tmp = 0x00; + /* Check the parameters */ + assert_param(IS_GPIO_EXTI_PORT_SOURCE(GPIO_PortSource)); + assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource)); + + tmp = ((uint32_t)0x0F) << (0x04 * (GPIO_PinSource & (uint8_t)0x03)); + AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp; + AFIO->EXTICR[GPIO_PinSource >> 0x02] |= (((uint32_t)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (uint8_t)0x03))); +} + +/** + * @brief Selects the Ethernet media interface. + * @note This function applies only to STM32 Connectivity line devices. + * @param GPIO_ETH_MediaInterface: specifies the Media Interface mode. + * This parameter can be one of the following values: + * @arg GPIO_ETH_MediaInterface_MII: MII mode + * @arg GPIO_ETH_MediaInterface_RMII: RMII mode + * @retval None + */ +void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface) +{ + assert_param(IS_GPIO_ETH_MEDIA_INTERFACE(GPIO_ETH_MediaInterface)); + + /* Configure MII_RMII selection bit */ + *(__IO uint32_t *) MAPR_MII_RMII_SEL_BB = GPIO_ETH_MediaInterface; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_i2c.c b/example/libs_stm/src/stm32f10x/stm32f10x_i2c.c new file mode 100644 index 000000000..32545f5ed --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_i2c.c @@ -0,0 +1,1285 @@ +/** + ****************************************************************************** + * @file stm32f10x_i2c.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the I2C firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_i2c.h" +#include "stm32f10x_rcc.h" + + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup I2C + * @brief I2C driver modules + * @{ + */ + +/** @defgroup I2C_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup I2C_Private_Defines + * @{ + */ + +/* I2C SPE mask */ +#define CR1_PE_Set ((uint16_t)0x0001) +#define CR1_PE_Reset ((uint16_t)0xFFFE) + +/* I2C START mask */ +#define CR1_START_Set ((uint16_t)0x0100) +#define CR1_START_Reset ((uint16_t)0xFEFF) + +/* I2C STOP mask */ +#define CR1_STOP_Set ((uint16_t)0x0200) +#define CR1_STOP_Reset ((uint16_t)0xFDFF) + +/* I2C ACK mask */ +#define CR1_ACK_Set ((uint16_t)0x0400) +#define CR1_ACK_Reset ((uint16_t)0xFBFF) + +/* I2C ENGC mask */ +#define CR1_ENGC_Set ((uint16_t)0x0040) +#define CR1_ENGC_Reset ((uint16_t)0xFFBF) + +/* I2C SWRST mask */ +#define CR1_SWRST_Set ((uint16_t)0x8000) +#define CR1_SWRST_Reset ((uint16_t)0x7FFF) + +/* I2C PEC mask */ +#define CR1_PEC_Set ((uint16_t)0x1000) +#define CR1_PEC_Reset ((uint16_t)0xEFFF) + +/* I2C ENPEC mask */ +#define CR1_ENPEC_Set ((uint16_t)0x0020) +#define CR1_ENPEC_Reset ((uint16_t)0xFFDF) + +/* I2C ENARP mask */ +#define CR1_ENARP_Set ((uint16_t)0x0010) +#define CR1_ENARP_Reset ((uint16_t)0xFFEF) + +/* I2C NOSTRETCH mask */ +#define CR1_NOSTRETCH_Set ((uint16_t)0x0080) +#define CR1_NOSTRETCH_Reset ((uint16_t)0xFF7F) + +/* I2C registers Masks */ +#define CR1_CLEAR_Mask ((uint16_t)0xFBF5) + +/* I2C DMAEN mask */ +#define CR2_DMAEN_Set ((uint16_t)0x0800) +#define CR2_DMAEN_Reset ((uint16_t)0xF7FF) + +/* I2C LAST mask */ +#define CR2_LAST_Set ((uint16_t)0x1000) +#define CR2_LAST_Reset ((uint16_t)0xEFFF) + +/* I2C FREQ mask */ +#define CR2_FREQ_Reset ((uint16_t)0xFFC0) + +/* I2C ADD0 mask */ +#define OAR1_ADD0_Set ((uint16_t)0x0001) +#define OAR1_ADD0_Reset ((uint16_t)0xFFFE) + +/* I2C ENDUAL mask */ +#define OAR2_ENDUAL_Set ((uint16_t)0x0001) +#define OAR2_ENDUAL_Reset ((uint16_t)0xFFFE) + +/* I2C ADD2 mask */ +#define OAR2_ADD2_Reset ((uint16_t)0xFF01) + +/* I2C F/S mask */ +#define CCR_FS_Set ((uint16_t)0x8000) + +/* I2C CCR mask */ +#define CCR_CCR_Set ((uint16_t)0x0FFF) + +/* I2C FLAG mask */ +#define FLAG_Mask ((uint32_t)0x00FFFFFF) + +/* I2C Interrupt Enable mask */ +#define ITEN_Mask ((uint32_t)0x07000000) + +/** + * @} + */ + +/** @defgroup I2C_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup I2C_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup I2C_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup I2C_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the I2Cx peripheral registers to their default reset values. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @retval None + */ +void I2C_DeInit(I2C_TypeDef* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + if (I2Cx == I2C1) + { + /* Enable I2C1 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); + /* Release I2C1 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); + } + else + { + /* Enable I2C2 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE); + /* Release I2C2 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE); + } +} + +/** + * @brief Initializes the I2Cx peripheral according to the specified + * parameters in the I2C_InitStruct. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_InitStruct: pointer to a I2C_InitTypeDef structure that + * contains the configuration information for the specified I2C peripheral. + * @retval None + */ +void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct) +{ + uint16_t tmpreg = 0, freqrange = 0; + uint16_t result = 0x04; + uint32_t pclk1 = 8000000; + RCC_ClocksTypeDef rcc_clocks; + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_CLOCK_SPEED(I2C_InitStruct->I2C_ClockSpeed)); + assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode)); + assert_param(IS_I2C_DUTY_CYCLE(I2C_InitStruct->I2C_DutyCycle)); + assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1)); + assert_param(IS_I2C_ACK_STATE(I2C_InitStruct->I2C_Ack)); + assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress)); + +/*---------------------------- I2Cx CR2 Configuration ------------------------*/ + /* Get the I2Cx CR2 value */ + tmpreg = I2Cx->CR2; + /* Clear frequency FREQ[5:0] bits */ + tmpreg &= CR2_FREQ_Reset; + /* Get pclk1 frequency value */ + RCC_GetClocksFreq(&rcc_clocks); + pclk1 = rcc_clocks.PCLK1_Frequency; + /* Set frequency bits depending on pclk1 value */ + freqrange = (uint16_t)(pclk1 / 1000000); + tmpreg |= freqrange; + /* Write to I2Cx CR2 */ + I2Cx->CR2 = tmpreg; + +/*---------------------------- I2Cx CCR Configuration ------------------------*/ + /* Disable the selected I2C peripheral to configure TRISE */ + I2Cx->CR1 &= CR1_PE_Reset; + /* Reset tmpreg value */ + /* Clear F/S, DUTY and CCR[11:0] bits */ + tmpreg = 0; + + /* Configure speed in standard mode */ + if (I2C_InitStruct->I2C_ClockSpeed <= 100000) + { + /* Standard mode speed calculate */ + result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed << 1)); + /* Test if CCR value is under 0x4*/ + if (result < 0x04) + { + /* Set minimum allowed value */ + result = 0x04; + } + /* Set speed value for standard mode */ + tmpreg |= result; + /* Set Maximum Rise Time for standard mode */ + I2Cx->TRISE = freqrange + 1; + } + /* Configure speed in fast mode */ + else /*(I2C_InitStruct->I2C_ClockSpeed <= 400000)*/ + { + if (I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_2) + { + /* Fast mode speed calculate: Tlow/Thigh = 2 */ + result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 3)); + } + else /*I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_16_9*/ + { + /* Fast mode speed calculate: Tlow/Thigh = 16/9 */ + result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 25)); + /* Set DUTY bit */ + result |= I2C_DutyCycle_16_9; + } + + /* Test if CCR value is under 0x1*/ + if ((result & CCR_CCR_Set) == 0) + { + /* Set minimum allowed value */ + result |= (uint16_t)0x0001; + } + /* Set speed value and set F/S bit for fast mode */ + tmpreg |= (uint16_t)(result | CCR_FS_Set); + /* Set Maximum Rise Time for fast mode */ + I2Cx->TRISE = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1); + } + + /* Write to I2Cx CCR */ + I2Cx->CCR = tmpreg; + /* Enable the selected I2C peripheral */ + I2Cx->CR1 |= CR1_PE_Set; + +/*---------------------------- I2Cx CR1 Configuration ------------------------*/ + /* Get the I2Cx CR1 value */ + tmpreg = I2Cx->CR1; + /* Clear ACK, SMBTYPE and SMBUS bits */ + tmpreg &= CR1_CLEAR_Mask; + /* Configure I2Cx: mode and acknowledgement */ + /* Set SMBTYPE and SMBUS bits according to I2C_Mode value */ + /* Set ACK bit according to I2C_Ack value */ + tmpreg |= (uint16_t)((uint32_t)I2C_InitStruct->I2C_Mode | I2C_InitStruct->I2C_Ack); + /* Write to I2Cx CR1 */ + I2Cx->CR1 = tmpreg; + +/*---------------------------- I2Cx OAR1 Configuration -----------------------*/ + /* Set I2Cx Own Address1 and acknowledged address */ + I2Cx->OAR1 = (I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1); +} + +/** + * @brief Fills each I2C_InitStruct member with its default value. + * @param I2C_InitStruct: pointer to an I2C_InitTypeDef structure which will be initialized. + * @retval None + */ +void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct) +{ +/*---------------- Reset I2C init structure parameters values ----------------*/ + /* initialize the I2C_ClockSpeed member */ + I2C_InitStruct->I2C_ClockSpeed = 5000; + /* Initialize the I2C_Mode member */ + I2C_InitStruct->I2C_Mode = I2C_Mode_I2C; + /* Initialize the I2C_DutyCycle member */ + I2C_InitStruct->I2C_DutyCycle = I2C_DutyCycle_2; + /* Initialize the I2C_OwnAddress1 member */ + I2C_InitStruct->I2C_OwnAddress1 = 0; + /* Initialize the I2C_Ack member */ + I2C_InitStruct->I2C_Ack = I2C_Ack_Disable; + /* Initialize the I2C_AcknowledgedAddress member */ + I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; +} + +/** + * @brief Enables or disables the specified I2C peripheral. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2Cx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C peripheral */ + I2Cx->CR1 |= CR1_PE_Set; + } + else + { + /* Disable the selected I2C peripheral */ + I2Cx->CR1 &= CR1_PE_Reset; + } +} + +/** + * @brief Enables or disables the specified I2C DMA requests. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C DMA transfer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C DMA requests */ + I2Cx->CR2 |= CR2_DMAEN_Set; + } + else + { + /* Disable the selected I2C DMA requests */ + I2Cx->CR2 &= CR2_DMAEN_Reset; + } +} + +/** + * @brief Specifies if the next DMA transfer will be the last one. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C DMA last transfer. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Next DMA transfer is the last transfer */ + I2Cx->CR2 |= CR2_LAST_Set; + } + else + { + /* Next DMA transfer is not the last transfer */ + I2Cx->CR2 &= CR2_LAST_Reset; + } +} + +/** + * @brief Generates I2Cx communication START condition. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C START condition generation. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Generate a START condition */ + I2Cx->CR1 |= CR1_START_Set; + } + else + { + /* Disable the START condition generation */ + I2Cx->CR1 &= CR1_START_Reset; + } +} + +/** + * @brief Generates I2Cx communication STOP condition. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C STOP condition generation. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Generate a STOP condition */ + I2Cx->CR1 |= CR1_STOP_Set; + } + else + { + /* Disable the STOP condition generation */ + I2Cx->CR1 &= CR1_STOP_Reset; + } +} + +/** + * @brief Enables or disables the specified I2C acknowledge feature. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C Acknowledgement. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the acknowledgement */ + I2Cx->CR1 |= CR1_ACK_Set; + } + else + { + /* Disable the acknowledgement */ + I2Cx->CR1 &= CR1_ACK_Reset; + } +} + +/** + * @brief Configures the specified I2C own address2. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param Address: specifies the 7bit I2C own address2. + * @retval None. + */ +void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address) +{ + uint16_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Get the old register value */ + tmpreg = I2Cx->OAR2; + + /* Reset I2Cx Own address2 bit [7:1] */ + tmpreg &= OAR2_ADD2_Reset; + + /* Set I2Cx Own address2 */ + tmpreg |= (uint16_t)((uint16_t)Address & (uint16_t)0x00FE); + + /* Store the new register value */ + I2Cx->OAR2 = tmpreg; +} + +/** + * @brief Enables or disables the specified I2C dual addressing mode. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C dual addressing mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable dual addressing mode */ + I2Cx->OAR2 |= OAR2_ENDUAL_Set; + } + else + { + /* Disable dual addressing mode */ + I2Cx->OAR2 &= OAR2_ENDUAL_Reset; + } +} + +/** + * @brief Enables or disables the specified I2C general call feature. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C General call. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable generall call */ + I2Cx->CR1 |= CR1_ENGC_Set; + } + else + { + /* Disable generall call */ + I2Cx->CR1 &= CR1_ENGC_Reset; + } +} + +/** + * @brief Enables or disables the specified I2C interrupts. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_IT: specifies the I2C interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg I2C_IT_BUF: Buffer interrupt mask + * @arg I2C_IT_EVT: Event interrupt mask + * @arg I2C_IT_ERR: Error interrupt mask + * @param NewState: new state of the specified I2C interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_I2C_CONFIG_IT(I2C_IT)); + + if (NewState != DISABLE) + { + /* Enable the selected I2C interrupts */ + I2Cx->CR2 |= I2C_IT; + } + else + { + /* Disable the selected I2C interrupts */ + I2Cx->CR2 &= (uint16_t)~I2C_IT; + } +} + +/** + * @brief Sends a data byte through the I2Cx peripheral. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param Data: Byte to be transmitted.. + * @retval None + */ +void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + /* Write in the DR register the data to be sent */ + I2Cx->DR = Data; +} + +/** + * @brief Returns the most recent received data by the I2Cx peripheral. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @retval The value of the received data. + */ +uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + /* Return the data in the DR register */ + return (uint8_t)I2Cx->DR; +} + +/** + * @brief Transmits the address byte to select the slave device. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param Address: specifies the slave address which will be transmitted + * @param I2C_Direction: specifies whether the I2C device will be a + * Transmitter or a Receiver. This parameter can be one of the following values + * @arg I2C_Direction_Transmitter: Transmitter mode + * @arg I2C_Direction_Receiver: Receiver mode + * @retval None. + */ +void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_DIRECTION(I2C_Direction)); + /* Test on the direction to set/reset the read/write bit */ + if (I2C_Direction != I2C_Direction_Transmitter) + { + /* Set the address bit0 for read */ + Address |= OAR1_ADD0_Set; + } + else + { + /* Reset the address bit0 for write */ + Address &= OAR1_ADD0_Reset; + } + /* Send the address */ + I2Cx->DR = Address; +} + +/** + * @brief Reads the specified I2C register and returns its value. + * @param I2C_Register: specifies the register to read. + * This parameter can be one of the following values: + * @arg I2C_Register_CR1: CR1 register. + * @arg I2C_Register_CR2: CR2 register. + * @arg I2C_Register_OAR1: OAR1 register. + * @arg I2C_Register_OAR2: OAR2 register. + * @arg I2C_Register_DR: DR register. + * @arg I2C_Register_SR1: SR1 register. + * @arg I2C_Register_SR2: SR2 register. + * @arg I2C_Register_CCR: CCR register. + * @arg I2C_Register_TRISE: TRISE register. + * @retval The value of the read register. + */ +uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_REGISTER(I2C_Register)); + + tmp = (uint32_t) I2Cx; + tmp += I2C_Register; + + /* Return the selected register value */ + return (*(__IO uint16_t *) tmp); +} + +/** + * @brief Enables or disables the specified I2C software reset. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C software reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Peripheral under reset */ + I2Cx->CR1 |= CR1_SWRST_Set; + } + else + { + /* Peripheral not under reset */ + I2Cx->CR1 &= CR1_SWRST_Reset; + } +} + +/** + * @brief Drives the SMBusAlert pin high or low for the specified I2C. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_SMBusAlert: specifies SMBAlert pin level. + * This parameter can be one of the following values: + * @arg I2C_SMBusAlert_Low: SMBAlert pin driven low + * @arg I2C_SMBusAlert_High: SMBAlert pin driven high + * @retval None + */ +void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_SMBUS_ALERT(I2C_SMBusAlert)); + if (I2C_SMBusAlert == I2C_SMBusAlert_Low) + { + /* Drive the SMBusAlert pin Low */ + I2Cx->CR1 |= I2C_SMBusAlert_Low; + } + else + { + /* Drive the SMBusAlert pin High */ + I2Cx->CR1 &= I2C_SMBusAlert_High; + } +} + +/** + * @brief Enables or disables the specified I2C PEC transfer. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2C PEC transmission. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C PEC transmission */ + I2Cx->CR1 |= CR1_PEC_Set; + } + else + { + /* Disable the selected I2C PEC transmission */ + I2Cx->CR1 &= CR1_PEC_Reset; + } +} + +/** + * @brief Selects the specified I2C PEC position. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_PECPosition: specifies the PEC position. + * This parameter can be one of the following values: + * @arg I2C_PECPosition_Next: indicates that the next byte is PEC + * @arg I2C_PECPosition_Current: indicates that current byte is PEC + * @retval None + */ +void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_PEC_POSITION(I2C_PECPosition)); + if (I2C_PECPosition == I2C_PECPosition_Next) + { + /* Next byte in shift register is PEC */ + I2Cx->CR1 |= I2C_PECPosition_Next; + } + else + { + /* Current byte in shift register is PEC */ + I2Cx->CR1 &= I2C_PECPosition_Current; + } +} + +/** + * @brief Enables or disables the PEC value calculation of the transfered bytes. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2Cx PEC value calculation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C PEC calculation */ + I2Cx->CR1 |= CR1_ENPEC_Set; + } + else + { + /* Disable the selected I2C PEC calculation */ + I2Cx->CR1 &= CR1_ENPEC_Reset; + } +} + +/** + * @brief Returns the PEC value for the specified I2C. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @retval The PEC value. + */ +uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + /* Return the selected I2C PEC value */ + return ((I2Cx->SR2) >> 8); +} + +/** + * @brief Enables or disables the specified I2C ARP. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2Cx ARP. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected I2C ARP */ + I2Cx->CR1 |= CR1_ENARP_Set; + } + else + { + /* Disable the selected I2C ARP */ + I2Cx->CR1 &= CR1_ENARP_Reset; + } +} + +/** + * @brief Enables or disables the specified I2C Clock stretching. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param NewState: new state of the I2Cx Clock stretching. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState == DISABLE) + { + /* Enable the selected I2C Clock stretching */ + I2Cx->CR1 |= CR1_NOSTRETCH_Set; + } + else + { + /* Disable the selected I2C Clock stretching */ + I2Cx->CR1 &= CR1_NOSTRETCH_Reset; + } +} + +/** + * @brief Selects the specified I2C fast mode duty cycle. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_DutyCycle: specifies the fast mode duty cycle. + * This parameter can be one of the following values: + * @arg I2C_DutyCycle_2: I2C fast mode Tlow/Thigh = 2 + * @arg I2C_DutyCycle_16_9: I2C fast mode Tlow/Thigh = 16/9 + * @retval None + */ +void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_DUTY_CYCLE(I2C_DutyCycle)); + if (I2C_DutyCycle != I2C_DutyCycle_16_9) + { + /* I2C fast mode Tlow/Thigh=2 */ + I2Cx->CCR &= I2C_DutyCycle_2; + } + else + { + /* I2C fast mode Tlow/Thigh=16/9 */ + I2Cx->CCR |= I2C_DutyCycle_16_9; + } +} + + + +/** + * @brief + **************************************************************************************** + * + * I2C State Monitoring Functions + * + **************************************************************************************** + * This I2C driver provides three different ways for I2C state monitoring + * depending on the application requirements and constraints: + * + * + * 1) Basic state monitoring: + * Using I2C_CheckEvent() function: + * It compares the status registers (SR1 and SR2) content to a given event + * (can be the combination of one or more flags). + * It returns SUCCESS if the current status includes the given flags + * and returns ERROR if one or more flags are missing in the current status. + * - When to use: + * - This function is suitable for most applciations as well as for startup + * activity since the events are fully described in the product reference manual + * (RM0008). + * - It is also suitable for users who need to define their own events. + * - Limitations: + * - If an error occurs (ie. error flags are set besides to the monitored flags), + * the I2C_CheckEvent() function may return SUCCESS despite the communication + * hold or corrupted real state. + * In this case, it is advised to use error interrupts to monitor the error + * events and handle them in the interrupt IRQ handler. + * + * @note + * For error management, it is advised to use the following functions: + * - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR). + * - I2Cx_ER_IRQHandler() which is called when the error interurpt occurs. + * Where x is the peripheral instance (I2C1, I2C2 ...) + * - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into I2Cx_ER_IRQHandler() + * in order to determine which error occured. + * - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd() + * and/or I2C_GenerateStop() in order to clear the error flag and source, + * and return to correct communication status. + * + * + * 2) Advanced state monitoring: + * Using the function I2C_GetLastEvent() which returns the image of both status + * registers in a single word (uint32_t) (Status Register 2 value is shifted left + * by 16 bits and concatenated to Status Register 1). + * - When to use: + * - This function is suitable for the same applications above but it allows to + * overcome the mentionned limitation of I2C_GetFlagStatus() function. + * The returned value could be compared to events already defined in the + * library (stm32f10x_i2c.h) or to custom values defiend by user. + * - This function is suitable when multiple flags are monitored at the same time. + * - At the opposite of I2C_CheckEvent() function, this function allows user to + * choose when an event is accepted (when all events flags are set and no + * other flags are set or just when the needed flags are set like + * I2C_CheckEvent() function). + * - Limitations: + * - User may need to define his own events. + * - Same remark concerning the error management is applicable for this + * function if user decides to check only regular communication flags (and + * ignores error flags). + * + * + * 3) Flag-based state monitoring: + * Using the function I2C_GetFlagStatus() which simply returns the status of + * one single flag (ie. I2C_FLAG_RXNE ...). + * - When to use: + * - This function could be used for specific applications or in debug phase. + * - It is suitable when only one flag checking is needed (most I2C events + * are monitored through multiple flags). + * - Limitations: + * - When calling this function, the Status register is accessed. Some flags are + * cleared when the status register is accessed. So checking the status + * of one Flag, may clear other ones. + * - Function may need to be called twice or more in order to monitor one + * single event. + * + * For detailed description of Events, please refer to section I2C_Events in + * stm32f10x_i2c.h file. + * + */ + +/** + * + * 1) Basic state monitoring + ******************************************************************************* + */ + +/** + * @brief Checks whether the last I2Cx Event is equal to the one passed + * as parameter. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_EVENT: specifies the event to be checked. + * This parameter can be one of the following values: + * @arg I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED : EV1 + * @arg I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED : EV1 + * @arg I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED : EV1 + * @arg I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED : EV1 + * @arg I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED : EV1 + * @arg I2C_EVENT_SLAVE_BYTE_RECEIVED : EV2 + * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF) : EV2 + * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL) : EV2 + * @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED : EV3 + * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF) : EV3 + * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL) : EV3 + * @arg I2C_EVENT_SLAVE_ACK_FAILURE : EV3_2 + * @arg I2C_EVENT_SLAVE_STOP_DETECTED : EV4 + * @arg I2C_EVENT_MASTER_MODE_SELECT : EV5 + * @arg I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED : EV6 + * @arg I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED : EV6 + * @arg I2C_EVENT_MASTER_BYTE_RECEIVED : EV7 + * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTING : EV8 + * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTED : EV8_2 + * @arg I2C_EVENT_MASTER_MODE_ADDRESS10 : EV9 + * + * @note: For detailed description of Events, please refer to section + * I2C_Events in stm32f10x_i2c.h file. + * + * @retval An ErrorStatus enumuration value: + * - SUCCESS: Last event is equal to the I2C_EVENT + * - ERROR: Last event is different from the I2C_EVENT + */ +ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) +{ + uint32_t lastevent = 0; + uint32_t flag1 = 0, flag2 = 0; + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_EVENT(I2C_EVENT)); + + /* Read the I2Cx status register */ + flag1 = I2Cx->SR1; + flag2 = I2Cx->SR2; + flag2 = flag2 << 16; + + /* Get the last event value from I2C status register */ + lastevent = (flag1 | flag2) & FLAG_Mask; + + /* Check whether the last event contains the I2C_EVENT */ + if ((lastevent & I2C_EVENT) == I2C_EVENT) + { + /* SUCCESS: last event is equal to I2C_EVENT */ + status = SUCCESS; + } + else + { + /* ERROR: last event is different from I2C_EVENT */ + status = ERROR; + } + /* Return status */ + return status; +} + +/** + * + * 2) Advanced state monitoring + ******************************************************************************* + */ + +/** + * @brief Returns the last I2Cx Event. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * + * @note: For detailed description of Events, please refer to section + * I2C_Events in stm32f10x_i2c.h file. + * + * @retval The last event + */ +uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx) +{ + uint32_t lastevent = 0; + uint32_t flag1 = 0, flag2 = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Read the I2Cx status register */ + flag1 = I2Cx->SR1; + flag2 = I2Cx->SR2; + flag2 = flag2 << 16; + + /* Get the last event value from I2C status register */ + lastevent = (flag1 | flag2) & FLAG_Mask; + + /* Return status */ + return lastevent; +} + +/** + * + * 3) Flag-based state monitoring + ******************************************************************************* + */ + +/** + * @brief Checks whether the specified I2C flag is set or not. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg I2C_FLAG_DUALF: Dual flag (Slave mode) + * @arg I2C_FLAG_SMBHOST: SMBus host header (Slave mode) + * @arg I2C_FLAG_SMBDEFAULT: SMBus default header (Slave mode) + * @arg I2C_FLAG_GENCALL: General call header flag (Slave mode) + * @arg I2C_FLAG_TRA: Transmitter/Receiver flag + * @arg I2C_FLAG_BUSY: Bus busy flag + * @arg I2C_FLAG_MSL: Master/Slave flag + * @arg I2C_FLAG_SMBALERT: SMBus Alert flag + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_FLAG_PECERR: PEC error in reception flag + * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) + * @arg I2C_FLAG_AF: Acknowledge failure flag + * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) + * @arg I2C_FLAG_BERR: Bus error flag + * @arg I2C_FLAG_TXE: Data register empty flag (Transmitter) + * @arg I2C_FLAG_RXNE: Data register not empty (Receiver) flag + * @arg I2C_FLAG_STOPF: Stop detection flag (Slave mode) + * @arg I2C_FLAG_ADD10: 10-bit header sent flag (Master mode) + * @arg I2C_FLAG_BTF: Byte transfer finished flag + * @arg I2C_FLAG_ADDR: Address sent flag (Master mode) ADSL + * Address matched flag (Slave mode)ENDAD + * @arg I2C_FLAG_SB: Start bit flag (Master mode) + * @retval The new state of I2C_FLAG (SET or RESET). + */ +FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) +{ + FlagStatus bitstatus = RESET; + __IO uint32_t i2creg = 0, i2cxbase = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_GET_FLAG(I2C_FLAG)); + + /* Get the I2Cx peripheral base address */ + i2cxbase = (uint32_t)I2Cx; + + /* Read flag register index */ + i2creg = I2C_FLAG >> 28; + + /* Get bit[23:0] of the flag */ + I2C_FLAG &= FLAG_Mask; + + if(i2creg != 0) + { + /* Get the I2Cx SR1 register address */ + i2cxbase += 0x14; + } + else + { + /* Flag in I2Cx SR2 Register */ + I2C_FLAG = (uint32_t)(I2C_FLAG >> 16); + /* Get the I2Cx SR2 register address */ + i2cxbase += 0x18; + } + + if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET) + { + /* I2C_FLAG is set */ + bitstatus = SET; + } + else + { + /* I2C_FLAG is reset */ + bitstatus = RESET; + } + + /* Return the I2C_FLAG status */ + return bitstatus; +} + + + +/** + * @brief Clears the I2Cx's pending flags. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg I2C_FLAG_SMBALERT: SMBus Alert flag + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_FLAG_PECERR: PEC error in reception flag + * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) + * @arg I2C_FLAG_AF: Acknowledge failure flag + * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) + * @arg I2C_FLAG_BERR: Bus error flag + * + * @note + * - STOPF (STOP detection) is cleared by software sequence: a read operation + * to I2C_SR1 register (I2C_GetFlagStatus()) followed by a write operation + * to I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral). + * - ADD10 (10-bit header sent) is cleared by software sequence: a read + * operation to I2C_SR1 (I2C_GetFlagStatus()) followed by writing the + * second byte of the address in DR register. + * - BTF (Byte Transfer Finished) is cleared by software sequence: a read + * operation to I2C_SR1 register (I2C_GetFlagStatus()) followed by a + * read/write to I2C_DR register (I2C_SendData()). + * - ADDR (Address sent) is cleared by software sequence: a read operation to + * I2C_SR1 register (I2C_GetFlagStatus()) followed by a read operation to + * I2C_SR2 register ((void)(I2Cx->SR2)). + * - SB (Start Bit) is cleared software sequence: a read operation to I2C_SR1 + * register (I2C_GetFlagStatus()) followed by a write operation to I2C_DR + * register (I2C_SendData()). + * @retval None + */ +void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) +{ + uint32_t flagpos = 0; + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_CLEAR_FLAG(I2C_FLAG)); + /* Get the I2C flag position */ + flagpos = I2C_FLAG & FLAG_Mask; + /* Clear the selected I2C flag */ + I2Cx->SR1 = (uint16_t)~flagpos; +} + +/** + * @brief Checks whether the specified I2C interrupt has occurred or not. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_IT: specifies the interrupt source to check. + * This parameter can be one of the following values: + * @arg I2C_IT_SMBALERT: SMBus Alert flag + * @arg I2C_IT_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_IT_PECERR: PEC error in reception flag + * @arg I2C_IT_OVR: Overrun/Underrun flag (Slave mode) + * @arg I2C_IT_AF: Acknowledge failure flag + * @arg I2C_IT_ARLO: Arbitration lost flag (Master mode) + * @arg I2C_IT_BERR: Bus error flag + * @arg I2C_IT_TXE: Data register empty flag (Transmitter) + * @arg I2C_IT_RXNE: Data register not empty (Receiver) flag + * @arg I2C_IT_STOPF: Stop detection flag (Slave mode) + * @arg I2C_IT_ADD10: 10-bit header sent flag (Master mode) + * @arg I2C_IT_BTF: Byte transfer finished flag + * @arg I2C_IT_ADDR: Address sent flag (Master mode) ADSL + * Address matched flag (Slave mode)ENDAD + * @arg I2C_IT_SB: Start bit flag (Master mode) + * @retval The new state of I2C_IT (SET or RESET). + */ +ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT) +{ + ITStatus bitstatus = RESET; + uint32_t enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_GET_IT(I2C_IT)); + + /* Check if the interrupt source is enabled or not */ + enablestatus = (uint32_t)(((I2C_IT & ITEN_Mask) >> 16) & (I2Cx->CR2)) ; + + /* Get bit[23:0] of the flag */ + I2C_IT &= FLAG_Mask; + + /* Check the status of the specified I2C flag */ + if (((I2Cx->SR1 & I2C_IT) != (uint32_t)RESET) && enablestatus) + { + /* I2C_IT is set */ + bitstatus = SET; + } + else + { + /* I2C_IT is reset */ + bitstatus = RESET; + } + /* Return the I2C_IT status */ + return bitstatus; +} + +/** + * @brief Clears the I2Cxs interrupt pending bits. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @param I2C_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg I2C_IT_SMBALERT: SMBus Alert interrupt + * @arg I2C_IT_TIMEOUT: Timeout or Tlow error interrupt + * @arg I2C_IT_PECERR: PEC error in reception interrupt + * @arg I2C_IT_OVR: Overrun/Underrun interrupt (Slave mode) + * @arg I2C_IT_AF: Acknowledge failure interrupt + * @arg I2C_IT_ARLO: Arbitration lost interrupt (Master mode) + * @arg I2C_IT_BERR: Bus error interrupt + * + * @note + * - STOPF (STOP detection) is cleared by software sequence: a read operation + * to I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to + * I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral). + * - ADD10 (10-bit header sent) is cleared by software sequence: a read + * operation to I2C_SR1 (I2C_GetITStatus()) followed by writing the second + * byte of the address in I2C_DR register. + * - BTF (Byte Transfer Finished) is cleared by software sequence: a read + * operation to I2C_SR1 register (I2C_GetITStatus()) followed by a + * read/write to I2C_DR register (I2C_SendData()). + * - ADDR (Address sent) is cleared by software sequence: a read operation to + * I2C_SR1 register (I2C_GetITStatus()) followed by a read operation to + * I2C_SR2 register ((void)(I2Cx->SR2)). + * - SB (Start Bit) is cleared by software sequence: a read operation to + * I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to + * I2C_DR register (I2C_SendData()). + * @retval None + */ +void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT) +{ + uint32_t flagpos = 0; + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_CLEAR_IT(I2C_IT)); + /* Get the I2C flag position */ + flagpos = I2C_IT & FLAG_Mask; + /* Clear the selected I2C flag */ + I2Cx->SR1 = (uint16_t)~flagpos; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_iwdg.c b/example/libs_stm/src/stm32f10x/stm32f10x_iwdg.c new file mode 100644 index 000000000..58ab061c3 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_iwdg.c @@ -0,0 +1,189 @@ +/** + ****************************************************************************** + * @file stm32f10x_iwdg.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the IWDG firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_iwdg.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup IWDG + * @brief IWDG driver modules + * @{ + */ + +/** @defgroup IWDG_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup IWDG_Private_Defines + * @{ + */ + +/* ---------------------- IWDG registers bit mask ----------------------------*/ + +/* KR register bit mask */ +#define KR_KEY_Reload ((uint16_t)0xAAAA) +#define KR_KEY_Enable ((uint16_t)0xCCCC) + +/** + * @} + */ + +/** @defgroup IWDG_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup IWDG_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup IWDG_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup IWDG_Private_Functions + * @{ + */ + +/** + * @brief Enables or disables write access to IWDG_PR and IWDG_RLR registers. + * @param IWDG_WriteAccess: new state of write access to IWDG_PR and IWDG_RLR registers. + * This parameter can be one of the following values: + * @arg IWDG_WriteAccess_Enable: Enable write access to IWDG_PR and IWDG_RLR registers + * @arg IWDG_WriteAccess_Disable: Disable write access to IWDG_PR and IWDG_RLR registers + * @retval None + */ +void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess) +{ + /* Check the parameters */ + assert_param(IS_IWDG_WRITE_ACCESS(IWDG_WriteAccess)); + IWDG->KR = IWDG_WriteAccess; +} + +/** + * @brief Sets IWDG Prescaler value. + * @param IWDG_Prescaler: specifies the IWDG Prescaler value. + * This parameter can be one of the following values: + * @arg IWDG_Prescaler_4: IWDG prescaler set to 4 + * @arg IWDG_Prescaler_8: IWDG prescaler set to 8 + * @arg IWDG_Prescaler_16: IWDG prescaler set to 16 + * @arg IWDG_Prescaler_32: IWDG prescaler set to 32 + * @arg IWDG_Prescaler_64: IWDG prescaler set to 64 + * @arg IWDG_Prescaler_128: IWDG prescaler set to 128 + * @arg IWDG_Prescaler_256: IWDG prescaler set to 256 + * @retval None + */ +void IWDG_SetPrescaler(uint8_t IWDG_Prescaler) +{ + /* Check the parameters */ + assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler)); + IWDG->PR = IWDG_Prescaler; +} + +/** + * @brief Sets IWDG Reload value. + * @param Reload: specifies the IWDG Reload value. + * This parameter must be a number between 0 and 0x0FFF. + * @retval None + */ +void IWDG_SetReload(uint16_t Reload) +{ + /* Check the parameters */ + assert_param(IS_IWDG_RELOAD(Reload)); + IWDG->RLR = Reload; +} + +/** + * @brief Reloads IWDG counter with value defined in the reload register + * (write access to IWDG_PR and IWDG_RLR registers disabled). + * @param None + * @retval None + */ +void IWDG_ReloadCounter(void) +{ + IWDG->KR = KR_KEY_Reload; +} + +/** + * @brief Enables IWDG (write access to IWDG_PR and IWDG_RLR registers disabled). + * @param None + * @retval None + */ +void IWDG_Enable(void) +{ + IWDG->KR = KR_KEY_Enable; +} + +/** + * @brief Checks whether the specified IWDG flag is set or not. + * @param IWDG_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg IWDG_FLAG_PVU: Prescaler Value Update on going + * @arg IWDG_FLAG_RVU: Reload Value Update on going + * @retval The new state of IWDG_FLAG (SET or RESET). + */ +FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_IWDG_FLAG(IWDG_FLAG)); + if ((IWDG->SR & IWDG_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the flag status */ + return bitstatus; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_pwr.c b/example/libs_stm/src/stm32f10x/stm32f10x_pwr.c new file mode 100644 index 000000000..a017ac681 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_pwr.c @@ -0,0 +1,316 @@ +/** + ****************************************************************************** + * @file stm32f10x_pwr.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the PWR firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_pwr.h" +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup PWR + * @brief PWR driver modules + * @{ + */ + +/** @defgroup PWR_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup PWR_Private_Defines + * @{ + */ + +/* --------- PWR registers bit address in the alias region ---------- */ +#define PWR_OFFSET (PWR_BASE - PERIPH_BASE) + +/* --- CR Register ---*/ + +/* Alias word address of DBP bit */ +#define CR_OFFSET (PWR_OFFSET + 0x00) +#define DBP_BitNumber 0x08 +#define CR_DBP_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (DBP_BitNumber * 4)) + +/* Alias word address of PVDE bit */ +#define PVDE_BitNumber 0x04 +#define CR_PVDE_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PVDE_BitNumber * 4)) + +/* --- CSR Register ---*/ + +/* Alias word address of EWUP bit */ +#define CSR_OFFSET (PWR_OFFSET + 0x04) +#define EWUP_BitNumber 0x08 +#define CSR_EWUP_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (EWUP_BitNumber * 4)) + +/* ------------------ PWR registers bit mask ------------------------ */ + +/* CR register bit mask */ +#define CR_PDDS_Set ((uint32_t)0x00000002) +#define CR_DS_Mask ((uint32_t)0xFFFFFFFC) +#define CR_CWUF_Set ((uint32_t)0x00000004) +#define CR_PLS_Mask ((uint32_t)0xFFFFFF1F) + +/* --------- Cortex System Control register bit mask ---------------- */ + +/* Cortex System Control register address */ +#define SCB_SysCtrl ((uint32_t)0xE000ED10) + +/* SLEEPDEEP bit mask */ +#define SysCtrl_SLEEPDEEP_Set ((uint32_t)0x00000004) +#define SysCtrl_SLEEPDEEP_Reset ((uint32_t)0xFFFFFFFB) + +/** + * @} + */ + +/** @defgroup PWR_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup PWR_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup PWR_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup PWR_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the PWR peripheral registers to their default reset values. + * @param None + * @retval None + */ +void PWR_DeInit(void) +{ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, DISABLE); +} + +/** + * @brief Enables or disables access to the RTC and backup registers. + * @param NewState: new state of the access to the RTC and backup registers. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_BackupAccessCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CR_DBP_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the Power Voltage Detector(PVD). + * @param NewState: new state of the PVD. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_PVDCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD). + * @param PWR_PVDLevel: specifies the PVD detection level + * This parameter can be one of the following values: + * @arg PWR_PVDLevel_2V2: PVD detection level set to 2.2V + * @arg PWR_PVDLevel_2V3: PVD detection level set to 2.3V + * @arg PWR_PVDLevel_2V4: PVD detection level set to 2.4V + * @arg PWR_PVDLevel_2V5: PVD detection level set to 2.5V + * @arg PWR_PVDLevel_2V6: PVD detection level set to 2.6V + * @arg PWR_PVDLevel_2V7: PVD detection level set to 2.7V + * @arg PWR_PVDLevel_2V8: PVD detection level set to 2.8V + * @arg PWR_PVDLevel_2V9: PVD detection level set to 2.9V + * @retval None + */ +void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_PWR_PVD_LEVEL(PWR_PVDLevel)); + tmpreg = PWR->CR; + /* Clear PLS[7:5] bits */ + tmpreg &= CR_PLS_Mask; + /* Set PLS[7:5] bits according to PWR_PVDLevel value */ + tmpreg |= PWR_PVDLevel; + /* Store the new value */ + PWR->CR = tmpreg; +} + +/** + * @brief Enables or disables the WakeUp Pin functionality. + * @param NewState: new state of the WakeUp Pin functionality. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void PWR_WakeUpPinCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CSR_EWUP_BB = (uint32_t)NewState; +} + +/** + * @brief Enters STOP mode. + * @param PWR_Regulator: specifies the regulator state in STOP mode. + * This parameter can be one of the following values: + * @arg PWR_Regulator_ON: STOP mode with regulator ON + * @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode + * @param PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction. + * This parameter can be one of the following values: + * @arg PWR_STOPEntry_WFI: enter STOP mode with WFI instruction + * @arg PWR_STOPEntry_WFE: enter STOP mode with WFE instruction + * @retval None + */ +void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_PWR_REGULATOR(PWR_Regulator)); + assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry)); + + /* Select the regulator state in STOP mode ---------------------------------*/ + tmpreg = PWR->CR; + /* Clear PDDS and LPDS bits */ + tmpreg &= CR_DS_Mask; + /* Set LPDS bit according to PWR_Regulator value */ + tmpreg |= PWR_Regulator; + /* Store the new value */ + PWR->CR = tmpreg; + /* Set SLEEPDEEP bit of Cortex System Control Register */ + *(__IO uint32_t *) SCB_SysCtrl |= SysCtrl_SLEEPDEEP_Set; + + /* Select STOP mode entry --------------------------------------------------*/ + if(PWR_STOPEntry == PWR_STOPEntry_WFI) + { + /* Request Wait For Interrupt */ + __WFI(); + } + else + { + /* Request Wait For Event */ + __WFE(); + } + + /* Reset SLEEPDEEP bit of Cortex System Control Register */ + *(__IO uint32_t *) SCB_SysCtrl &= SysCtrl_SLEEPDEEP_Reset; +} + +/** + * @brief Enters STANDBY mode. + * @param None + * @retval None + */ +void PWR_EnterSTANDBYMode(void) +{ + /* Clear Wake-up flag */ + PWR->CR |= CR_CWUF_Set; + /* Select STANDBY mode */ + PWR->CR |= CR_PDDS_Set; + /* Set SLEEPDEEP bit of Cortex System Control Register */ + *(__IO uint32_t *) SCB_SysCtrl |= SysCtrl_SLEEPDEEP_Set; +/* This option is used to ensure that store operations are completed */ +#if defined ( __CC_ARM ) + __force_stores(); +#endif + /* Request Wait For Interrupt */ + __WFI(); +} + +/** + * @brief Checks whether the specified PWR flag is set or not. + * @param PWR_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg PWR_FLAG_WU: Wake Up flag + * @arg PWR_FLAG_SB: StandBy flag + * @arg PWR_FLAG_PVDO: PVD Output + * @retval The new state of PWR_FLAG (SET or RESET). + */ +FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_PWR_GET_FLAG(PWR_FLAG)); + + if ((PWR->CSR & PWR_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the flag status */ + return bitstatus; +} + +/** + * @brief Clears the PWR's pending flags. + * @param PWR_FLAG: specifies the flag to clear. + * This parameter can be one of the following values: + * @arg PWR_FLAG_WU: Wake Up flag + * @arg PWR_FLAG_SB: StandBy flag + * @retval None + */ +void PWR_ClearFlag(uint32_t PWR_FLAG) +{ + /* Check the parameters */ + assert_param(IS_PWR_CLEAR_FLAG(PWR_FLAG)); + + PWR->CR |= PWR_FLAG << 2; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_rcc.c b/example/libs_stm/src/stm32f10x/stm32f10x_rcc.c new file mode 100644 index 000000000..0fb0d58a0 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_rcc.c @@ -0,0 +1,1477 @@ +/** + ****************************************************************************** + * @file stm32f10x_rcc.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the RCC firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup RCC + * @brief RCC driver modules + * @{ + */ + +/** @defgroup RCC_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup RCC_Private_Defines + * @{ + */ + +/* ------------ RCC registers bit address in the alias region ----------- */ +#define RCC_OFFSET (RCC_BASE - PERIPH_BASE) + +/* --- CR Register ---*/ + +/* Alias word address of HSION bit */ +#define CR_OFFSET (RCC_OFFSET + 0x00) +#define HSION_BitNumber 0x00 +#define CR_HSION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (HSION_BitNumber * 4)) + +/* Alias word address of PLLON bit */ +#define PLLON_BitNumber 0x18 +#define CR_PLLON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLON_BitNumber * 4)) + +#ifdef STM32F10X_CL + /* Alias word address of PLL2ON bit */ + #define PLL2ON_BitNumber 0x1A + #define CR_PLL2ON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLL2ON_BitNumber * 4)) + + /* Alias word address of PLL3ON bit */ + #define PLL3ON_BitNumber 0x1C + #define CR_PLL3ON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLL3ON_BitNumber * 4)) +#endif /* STM32F10X_CL */ + +/* Alias word address of CSSON bit */ +#define CSSON_BitNumber 0x13 +#define CR_CSSON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (CSSON_BitNumber * 4)) + +/* --- CFGR Register ---*/ + +/* Alias word address of USBPRE bit */ +#define CFGR_OFFSET (RCC_OFFSET + 0x04) + +#ifndef STM32F10X_CL + #define USBPRE_BitNumber 0x16 + #define CFGR_USBPRE_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (USBPRE_BitNumber * 4)) +#else + #define OTGFSPRE_BitNumber 0x16 + #define CFGR_OTGFSPRE_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (OTGFSPRE_BitNumber * 4)) +#endif /* STM32F10X_CL */ + +/* --- BDCR Register ---*/ + +/* Alias word address of RTCEN bit */ +#define BDCR_OFFSET (RCC_OFFSET + 0x20) +#define RTCEN_BitNumber 0x0F +#define BDCR_RTCEN_BB (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (RTCEN_BitNumber * 4)) + +/* Alias word address of BDRST bit */ +#define BDRST_BitNumber 0x10 +#define BDCR_BDRST_BB (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (BDRST_BitNumber * 4)) + +/* --- CSR Register ---*/ + +/* Alias word address of LSION bit */ +#define CSR_OFFSET (RCC_OFFSET + 0x24) +#define LSION_BitNumber 0x00 +#define CSR_LSION_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (LSION_BitNumber * 4)) + +#ifdef STM32F10X_CL +/* --- CFGR2 Register ---*/ + + /* Alias word address of I2S2SRC bit */ + #define CFGR2_OFFSET (RCC_OFFSET + 0x2C) + #define I2S2SRC_BitNumber 0x11 + #define CFGR2_I2S2SRC_BB (PERIPH_BB_BASE + (CFGR2_OFFSET * 32) + (I2S2SRC_BitNumber * 4)) + + /* Alias word address of I2S3SRC bit */ + #define I2S3SRC_BitNumber 0x12 + #define CFGR2_I2S3SRC_BB (PERIPH_BB_BASE + (CFGR2_OFFSET * 32) + (I2S3SRC_BitNumber * 4)) +#endif /* STM32F10X_CL */ + +/* ---------------------- RCC registers bit mask ------------------------ */ + +/* CR register bit mask */ +#define CR_HSEBYP_Reset ((uint32_t)0xFFFBFFFF) +#define CR_HSEBYP_Set ((uint32_t)0x00040000) +#define CR_HSEON_Reset ((uint32_t)0xFFFEFFFF) +#define CR_HSEON_Set ((uint32_t)0x00010000) +#define CR_HSITRIM_Mask ((uint32_t)0xFFFFFF07) + +/* CFGR register bit mask */ +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_CL) + #define CFGR_PLL_Mask ((uint32_t)0xFFC2FFFF) +#else + #define CFGR_PLL_Mask ((uint32_t)0xFFC0FFFF) +#endif /* STM32F10X_CL */ + +#define CFGR_PLLMull_Mask ((uint32_t)0x003C0000) +#define CFGR_PLLSRC_Mask ((uint32_t)0x00010000) +#define CFGR_PLLXTPRE_Mask ((uint32_t)0x00020000) +#define CFGR_SWS_Mask ((uint32_t)0x0000000C) +#define CFGR_SW_Mask ((uint32_t)0xFFFFFFFC) +#define CFGR_HPRE_Reset_Mask ((uint32_t)0xFFFFFF0F) +#define CFGR_HPRE_Set_Mask ((uint32_t)0x000000F0) +#define CFGR_PPRE1_Reset_Mask ((uint32_t)0xFFFFF8FF) +#define CFGR_PPRE1_Set_Mask ((uint32_t)0x00000700) +#define CFGR_PPRE2_Reset_Mask ((uint32_t)0xFFFFC7FF) +#define CFGR_PPRE2_Set_Mask ((uint32_t)0x00003800) +#define CFGR_ADCPRE_Reset_Mask ((uint32_t)0xFFFF3FFF) +#define CFGR_ADCPRE_Set_Mask ((uint32_t)0x0000C000) + +/* CSR register bit mask */ +#define CSR_RMVF_Set ((uint32_t)0x01000000) + +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_CL) +/* CFGR2 register bit mask */ + #define CFGR2_PREDIV1SRC ((uint32_t)0x00010000) + #define CFGR2_PREDIV1 ((uint32_t)0x0000000F) +#endif +#ifdef STM32F10X_CL + #define CFGR2_PREDIV2 ((uint32_t)0x000000F0) + #define CFGR2_PLL2MUL ((uint32_t)0x00000F00) + #define CFGR2_PLL3MUL ((uint32_t)0x0000F000) +#endif /* STM32F10X_CL */ + +/* RCC Flag Mask */ +#define FLAG_Mask ((uint8_t)0x1F) + +#ifndef HSI_Value +/* Typical Value of the HSI in Hz */ + #define HSI_Value ((uint32_t)8000000) +#endif /* HSI_Value */ + +/* CIR register byte 2 (Bits[15:8]) base address */ +#define CIR_BYTE2_ADDRESS ((uint32_t)0x40021009) + +/* CIR register byte 3 (Bits[23:16]) base address */ +#define CIR_BYTE3_ADDRESS ((uint32_t)0x4002100A) + +/* CFGR register byte 4 (Bits[31:24]) base address */ +#define CFGR_BYTE4_ADDRESS ((uint32_t)0x40021007) + +/* BDCR register base address */ +#define BDCR_ADDRESS (PERIPH_BASE + BDCR_OFFSET) + +#ifndef HSEStartUp_TimeOut +/* Time out for HSE start up */ + #define HSEStartUp_TimeOut ((uint16_t)0x0500) +#endif /* HSEStartUp_TimeOut */ + +/** + * @} + */ + +/** @defgroup RCC_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup RCC_Private_Variables + * @{ + */ + +static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; +static __I uint8_t ADCPrescTable[4] = {2, 4, 6, 8}; + +/** + * @} + */ + +/** @defgroup RCC_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup RCC_Private_Functions + * @{ + */ + +/** + * @brief Resets the RCC clock configuration to the default reset state. + * @param None + * @retval None + */ +void RCC_DeInit(void) +{ + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + + /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ +#ifndef STM32F10X_CL + RCC->CFGR &= (uint32_t)0xF8FF0000; +#else + RCC->CFGR &= (uint32_t)0xF0FF0000; +#endif /* STM32F10X_CL */ + + /* Reset HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFFF; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ + RCC->CFGR &= (uint32_t)0xFF80FFFF; + +#ifdef STM32F10X_CL + /* Reset PLL2ON and PLL3ON bits */ + RCC->CR &= (uint32_t)0xEBFFFFFF; + + /* Disable all interrupts and clear pending bits */ + RCC->CIR = 0x00FF0000; + + /* Reset CFGR2 register */ + RCC->CFGR2 = 0x00000000; +#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) + /* Disable all interrupts and clear pending bits */ + RCC->CIR = 0x009F0000; + + /* Reset CFGR2 register */ + RCC->CFGR2 = 0x00000000; +#else + /* Disable all interrupts and clear pending bits */ + RCC->CIR = 0x009F0000; +#endif /* STM32F10X_CL */ + +} + +/** + * @brief Configures the External High Speed oscillator (HSE). + * @note HSE can not be stopped if it is used directly or through the PLL as system clock. + * @param RCC_HSE: specifies the new state of the HSE. + * This parameter can be one of the following values: + * @arg RCC_HSE_OFF: HSE oscillator OFF + * @arg RCC_HSE_ON: HSE oscillator ON + * @arg RCC_HSE_Bypass: HSE oscillator bypassed with external clock + * @retval None + */ +void RCC_HSEConfig(uint32_t RCC_HSE) +{ + /* Check the parameters */ + assert_param(IS_RCC_HSE(RCC_HSE)); + /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/ + /* Reset HSEON bit */ + RCC->CR &= CR_HSEON_Reset; + /* Reset HSEBYP bit */ + RCC->CR &= CR_HSEBYP_Reset; + /* Configure HSE (RCC_HSE_OFF is already covered by the code section above) */ + switch(RCC_HSE) + { + case RCC_HSE_ON: + /* Set HSEON bit */ + RCC->CR |= CR_HSEON_Set; + break; + + case RCC_HSE_Bypass: + /* Set HSEBYP and HSEON bits */ + RCC->CR |= CR_HSEBYP_Set | CR_HSEON_Set; + break; + + default: + break; + } +} + +/** + * @brief Waits for HSE start-up. + * @param None + * @retval An ErrorStatus enumuration value: + * - SUCCESS: HSE oscillator is stable and ready to use + * - ERROR: HSE oscillator not yet ready + */ +ErrorStatus RCC_WaitForHSEStartUp(void) +{ + __IO uint32_t StartUpCounter = 0; + ErrorStatus status = ERROR; + FlagStatus HSEStatus = RESET; + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY); + StartUpCounter++; + } while((StartUpCounter != HSEStartUp_TimeOut) && (HSEStatus == RESET)); + + if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + return (status); +} + +/** + * @brief Adjusts the Internal High Speed oscillator (HSI) calibration value. + * @param HSICalibrationValue: specifies the calibration trimming value. + * This parameter must be a number between 0 and 0x1F. + * @retval None + */ +void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_RCC_CALIBRATION_VALUE(HSICalibrationValue)); + tmpreg = RCC->CR; + /* Clear HSITRIM[4:0] bits */ + tmpreg &= CR_HSITRIM_Mask; + /* Set the HSITRIM[4:0] bits according to HSICalibrationValue value */ + tmpreg |= (uint32_t)HSICalibrationValue << 3; + /* Store the new value */ + RCC->CR = tmpreg; +} + +/** + * @brief Enables or disables the Internal High Speed oscillator (HSI). + * @note HSI can not be stopped if it is used directly or through the PLL as system clock. + * @param NewState: new state of the HSI. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_HSICmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CR_HSION_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the PLL clock source and multiplication factor. + * @note This function must be used only when the PLL is disabled. + * @param RCC_PLLSource: specifies the PLL entry clock source. + * For @b STM32_Connectivity_line_devices or @b STM32_Value_line_devices, + * this parameter can be one of the following values: + * @arg RCC_PLLSource_HSI_Div2: HSI oscillator clock divided by 2 selected as PLL clock entry + * @arg RCC_PLLSource_PREDIV1: PREDIV1 clock selected as PLL clock entry + * For @b other_STM32_devices, this parameter can be one of the following values: + * @arg RCC_PLLSource_HSI_Div2: HSI oscillator clock divided by 2 selected as PLL clock entry + * @arg RCC_PLLSource_HSE_Div1: HSE oscillator clock selected as PLL clock entry + * @arg RCC_PLLSource_HSE_Div2: HSE oscillator clock divided by 2 selected as PLL clock entry + * @param RCC_PLLMul: specifies the PLL multiplication factor. + * For @b STM32_Connectivity_line_devices, this parameter can be RCC_PLLMul_x where x:{[4,9], 6_5} + * For @b other_STM32_devices, this parameter can be RCC_PLLMul_x where x:[2,16] + * @retval None + */ +void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource)); + assert_param(IS_RCC_PLL_MUL(RCC_PLLMul)); + + tmpreg = RCC->CFGR; + /* Clear PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */ + tmpreg &= CFGR_PLL_Mask; + /* Set the PLL configuration bits */ + tmpreg |= RCC_PLLSource | RCC_PLLMul; + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Enables or disables the PLL. + * @note The PLL can not be disabled if it is used as system clock. + * @param NewState: new state of the PLL. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_PLLCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_PLLON_BB = (uint32_t)NewState; +} + +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_CL) +/** + * @brief Configures the PREDIV1 division factor. + * @note + * - This function must be used only when the PLL is disabled. + * - This function applies only to STM32 Connectivity line and Value line + * devices. + * @param RCC_PREDIV1_Source: specifies the PREDIV1 clock source. + * This parameter can be one of the following values: + * @arg RCC_PREDIV1_Source_HSE: HSE selected as PREDIV1 clock + * @arg RCC_PREDIV1_Source_PLL2: PLL2 selected as PREDIV1 clock + * @note + * For @b STM32_Value_line_devices this parameter is always RCC_PREDIV1_Source_HSE + * @param RCC_PREDIV1_Div: specifies the PREDIV1 clock division factor. + * This parameter can be RCC_PREDIV1_Divx where x:[1,16] + * @retval None + */ +void RCC_PREDIV1Config(uint32_t RCC_PREDIV1_Source, uint32_t RCC_PREDIV1_Div) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PREDIV1_SOURCE(RCC_PREDIV1_Source)); + assert_param(IS_RCC_PREDIV1(RCC_PREDIV1_Div)); + + tmpreg = RCC->CFGR2; + /* Clear PREDIV1[3:0] and PREDIV1SRC bits */ + tmpreg &= ~(CFGR2_PREDIV1 | CFGR2_PREDIV1SRC); + /* Set the PREDIV1 clock source and division factor */ + tmpreg |= RCC_PREDIV1_Source | RCC_PREDIV1_Div ; + /* Store the new value */ + RCC->CFGR2 = tmpreg; +} +#endif + +#ifdef STM32F10X_CL +/** + * @brief Configures the PREDIV2 division factor. + * @note + * - This function must be used only when both PLL2 and PLL3 are disabled. + * - This function applies only to STM32 Connectivity line devices. + * @param RCC_PREDIV2_Div: specifies the PREDIV2 clock division factor. + * This parameter can be RCC_PREDIV2_Divx where x:[1,16] + * @retval None + */ +void RCC_PREDIV2Config(uint32_t RCC_PREDIV2_Div) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PREDIV2(RCC_PREDIV2_Div)); + + tmpreg = RCC->CFGR2; + /* Clear PREDIV2[3:0] bits */ + tmpreg &= ~CFGR2_PREDIV2; + /* Set the PREDIV2 division factor */ + tmpreg |= RCC_PREDIV2_Div; + /* Store the new value */ + RCC->CFGR2 = tmpreg; +} + +/** + * @brief Configures the PLL2 multiplication factor. + * @note + * - This function must be used only when the PLL2 is disabled. + * - This function applies only to STM32 Connectivity line devices. + * @param RCC_PLL2Mul: specifies the PLL2 multiplication factor. + * This parameter can be RCC_PLL2Mul_x where x:{[8,14], 16, 20} + * @retval None + */ +void RCC_PLL2Config(uint32_t RCC_PLL2Mul) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PLL2_MUL(RCC_PLL2Mul)); + + tmpreg = RCC->CFGR2; + /* Clear PLL2Mul[3:0] bits */ + tmpreg &= ~CFGR2_PLL2MUL; + /* Set the PLL2 configuration bits */ + tmpreg |= RCC_PLL2Mul; + /* Store the new value */ + RCC->CFGR2 = tmpreg; +} + + +/** + * @brief Enables or disables the PLL2. + * @note + * - The PLL2 can not be disabled if it is used indirectly as system clock + * (i.e. it is used as PLL clock entry that is used as System clock). + * - This function applies only to STM32 Connectivity line devices. + * @param NewState: new state of the PLL2. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_PLL2Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_PLL2ON_BB = (uint32_t)NewState; +} + + +/** + * @brief Configures the PLL3 multiplication factor. + * @note + * - This function must be used only when the PLL3 is disabled. + * - This function applies only to STM32 Connectivity line devices. + * @param RCC_PLL3Mul: specifies the PLL3 multiplication factor. + * This parameter can be RCC_PLL3Mul_x where x:{[8,14], 16, 20} + * @retval None + */ +void RCC_PLL3Config(uint32_t RCC_PLL3Mul) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PLL3_MUL(RCC_PLL3Mul)); + + tmpreg = RCC->CFGR2; + /* Clear PLL3Mul[3:0] bits */ + tmpreg &= ~CFGR2_PLL3MUL; + /* Set the PLL3 configuration bits */ + tmpreg |= RCC_PLL3Mul; + /* Store the new value */ + RCC->CFGR2 = tmpreg; +} + + +/** + * @brief Enables or disables the PLL3. + * @note This function applies only to STM32 Connectivity line devices. + * @param NewState: new state of the PLL3. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_PLL3Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CR_PLL3ON_BB = (uint32_t)NewState; +} +#endif /* STM32F10X_CL */ + +/** + * @brief Configures the system clock (SYSCLK). + * @param RCC_SYSCLKSource: specifies the clock source used as system clock. + * This parameter can be one of the following values: + * @arg RCC_SYSCLKSource_HSI: HSI selected as system clock + * @arg RCC_SYSCLKSource_HSE: HSE selected as system clock + * @arg RCC_SYSCLKSource_PLLCLK: PLL selected as system clock + * @retval None + */ +void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_RCC_SYSCLK_SOURCE(RCC_SYSCLKSource)); + tmpreg = RCC->CFGR; + /* Clear SW[1:0] bits */ + tmpreg &= CFGR_SW_Mask; + /* Set SW[1:0] bits according to RCC_SYSCLKSource value */ + tmpreg |= RCC_SYSCLKSource; + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Returns the clock source used as system clock. + * @param None + * @retval The clock source used as system clock. The returned value can + * be one of the following: + * - 0x00: HSI used as system clock + * - 0x04: HSE used as system clock + * - 0x08: PLL used as system clock + */ +uint8_t RCC_GetSYSCLKSource(void) +{ + return ((uint8_t)(RCC->CFGR & CFGR_SWS_Mask)); +} + +/** + * @brief Configures the AHB clock (HCLK). + * @param RCC_SYSCLK: defines the AHB clock divider. This clock is derived from + * the system clock (SYSCLK). + * This parameter can be one of the following values: + * @arg RCC_SYSCLK_Div1: AHB clock = SYSCLK + * @arg RCC_SYSCLK_Div2: AHB clock = SYSCLK/2 + * @arg RCC_SYSCLK_Div4: AHB clock = SYSCLK/4 + * @arg RCC_SYSCLK_Div8: AHB clock = SYSCLK/8 + * @arg RCC_SYSCLK_Div16: AHB clock = SYSCLK/16 + * @arg RCC_SYSCLK_Div64: AHB clock = SYSCLK/64 + * @arg RCC_SYSCLK_Div128: AHB clock = SYSCLK/128 + * @arg RCC_SYSCLK_Div256: AHB clock = SYSCLK/256 + * @arg RCC_SYSCLK_Div512: AHB clock = SYSCLK/512 + * @retval None + */ +void RCC_HCLKConfig(uint32_t RCC_SYSCLK) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_RCC_HCLK(RCC_SYSCLK)); + tmpreg = RCC->CFGR; + /* Clear HPRE[3:0] bits */ + tmpreg &= CFGR_HPRE_Reset_Mask; + /* Set HPRE[3:0] bits according to RCC_SYSCLK value */ + tmpreg |= RCC_SYSCLK; + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Configures the Low Speed APB clock (PCLK1). + * @param RCC_HCLK: defines the APB1 clock divider. This clock is derived from + * the AHB clock (HCLK). + * This parameter can be one of the following values: + * @arg RCC_HCLK_Div1: APB1 clock = HCLK + * @arg RCC_HCLK_Div2: APB1 clock = HCLK/2 + * @arg RCC_HCLK_Div4: APB1 clock = HCLK/4 + * @arg RCC_HCLK_Div8: APB1 clock = HCLK/8 + * @arg RCC_HCLK_Div16: APB1 clock = HCLK/16 + * @retval None + */ +void RCC_PCLK1Config(uint32_t RCC_HCLK) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_RCC_PCLK(RCC_HCLK)); + tmpreg = RCC->CFGR; + /* Clear PPRE1[2:0] bits */ + tmpreg &= CFGR_PPRE1_Reset_Mask; + /* Set PPRE1[2:0] bits according to RCC_HCLK value */ + tmpreg |= RCC_HCLK; + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Configures the High Speed APB clock (PCLK2). + * @param RCC_HCLK: defines the APB2 clock divider. This clock is derived from + * the AHB clock (HCLK). + * This parameter can be one of the following values: + * @arg RCC_HCLK_Div1: APB2 clock = HCLK + * @arg RCC_HCLK_Div2: APB2 clock = HCLK/2 + * @arg RCC_HCLK_Div4: APB2 clock = HCLK/4 + * @arg RCC_HCLK_Div8: APB2 clock = HCLK/8 + * @arg RCC_HCLK_Div16: APB2 clock = HCLK/16 + * @retval None + */ +void RCC_PCLK2Config(uint32_t RCC_HCLK) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_RCC_PCLK(RCC_HCLK)); + tmpreg = RCC->CFGR; + /* Clear PPRE2[2:0] bits */ + tmpreg &= CFGR_PPRE2_Reset_Mask; + /* Set PPRE2[2:0] bits according to RCC_HCLK value */ + tmpreg |= RCC_HCLK << 3; + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Enables or disables the specified RCC interrupts. + * @param RCC_IT: specifies the RCC interrupt sources to be enabled or disabled. + * + * For @b STM32_Connectivity_line_devices, this parameter can be any combination + * of the following values + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: PLL ready interrupt + * @arg RCC_IT_PLL2RDY: PLL2 ready interrupt + * @arg RCC_IT_PLL3RDY: PLL3 ready interrupt + * + * For @b other_STM32_devices, this parameter can be any combination of the + * following values + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: PLL ready interrupt + * + * @param NewState: new state of the specified RCC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_IT(RCC_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Perform Byte access to RCC_CIR bits to enable the selected interrupts */ + *(__IO uint8_t *) CIR_BYTE2_ADDRESS |= RCC_IT; + } + else + { + /* Perform Byte access to RCC_CIR bits to disable the selected interrupts */ + *(__IO uint8_t *) CIR_BYTE2_ADDRESS &= (uint8_t)~RCC_IT; + } +} + +#ifndef STM32F10X_CL +/** + * @brief Configures the USB clock (USBCLK). + * @param RCC_USBCLKSource: specifies the USB clock source. This clock is + * derived from the PLL output. + * This parameter can be one of the following values: + * @arg RCC_USBCLKSource_PLLCLK_1Div5: PLL clock divided by 1,5 selected as USB + * clock source + * @arg RCC_USBCLKSource_PLLCLK_Div1: PLL clock selected as USB clock source + * @retval None + */ +void RCC_USBCLKConfig(uint32_t RCC_USBCLKSource) +{ + /* Check the parameters */ + assert_param(IS_RCC_USBCLK_SOURCE(RCC_USBCLKSource)); + + *(__IO uint32_t *) CFGR_USBPRE_BB = RCC_USBCLKSource; +} +#else +/** + * @brief Configures the USB OTG FS clock (OTGFSCLK). + * This function applies only to STM32 Connectivity line devices. + * @param RCC_OTGFSCLKSource: specifies the USB OTG FS clock source. + * This clock is derived from the PLL output. + * This parameter can be one of the following values: + * @arg RCC_OTGFSCLKSource_PLLVCO_Div3: PLL VCO clock divided by 2 selected as USB OTG FS clock source + * @arg RCC_OTGFSCLKSource_PLLVCO_Div2: PLL VCO clock divided by 2 selected as USB OTG FS clock source + * @retval None + */ +void RCC_OTGFSCLKConfig(uint32_t RCC_OTGFSCLKSource) +{ + /* Check the parameters */ + assert_param(IS_RCC_OTGFSCLK_SOURCE(RCC_OTGFSCLKSource)); + + *(__IO uint32_t *) CFGR_OTGFSPRE_BB = RCC_OTGFSCLKSource; +} +#endif /* STM32F10X_CL */ + +/** + * @brief Configures the ADC clock (ADCCLK). + * @param RCC_PCLK2: defines the ADC clock divider. This clock is derived from + * the APB2 clock (PCLK2). + * This parameter can be one of the following values: + * @arg RCC_PCLK2_Div2: ADC clock = PCLK2/2 + * @arg RCC_PCLK2_Div4: ADC clock = PCLK2/4 + * @arg RCC_PCLK2_Div6: ADC clock = PCLK2/6 + * @arg RCC_PCLK2_Div8: ADC clock = PCLK2/8 + * @retval None + */ +void RCC_ADCCLKConfig(uint32_t RCC_PCLK2) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_RCC_ADCCLK(RCC_PCLK2)); + tmpreg = RCC->CFGR; + /* Clear ADCPRE[1:0] bits */ + tmpreg &= CFGR_ADCPRE_Reset_Mask; + /* Set ADCPRE[1:0] bits according to RCC_PCLK2 value */ + tmpreg |= RCC_PCLK2; + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +#ifdef STM32F10X_CL +/** + * @brief Configures the I2S2 clock source(I2S2CLK). + * @note + * - This function must be called before enabling I2S2 APB clock. + * - This function applies only to STM32 Connectivity line devices. + * @param RCC_I2S2CLKSource: specifies the I2S2 clock source. + * This parameter can be one of the following values: + * @arg RCC_I2S2CLKSource_SYSCLK: system clock selected as I2S2 clock entry + * @arg RCC_I2S2CLKSource_PLL3_VCO: PLL3 VCO clock selected as I2S2 clock entry + * @retval None + */ +void RCC_I2S2CLKConfig(uint32_t RCC_I2S2CLKSource) +{ + /* Check the parameters */ + assert_param(IS_RCC_I2S2CLK_SOURCE(RCC_I2S2CLKSource)); + + *(__IO uint32_t *) CFGR2_I2S2SRC_BB = RCC_I2S2CLKSource; +} + +/** + * @brief Configures the I2S3 clock source(I2S2CLK). + * @note + * - This function must be called before enabling I2S3 APB clock. + * - This function applies only to STM32 Connectivity line devices. + * @param RCC_I2S3CLKSource: specifies the I2S3 clock source. + * This parameter can be one of the following values: + * @arg RCC_I2S3CLKSource_SYSCLK: system clock selected as I2S3 clock entry + * @arg RCC_I2S3CLKSource_PLL3_VCO: PLL3 VCO clock selected as I2S3 clock entry + * @retval None + */ +void RCC_I2S3CLKConfig(uint32_t RCC_I2S3CLKSource) +{ + /* Check the parameters */ + assert_param(IS_RCC_I2S3CLK_SOURCE(RCC_I2S3CLKSource)); + + *(__IO uint32_t *) CFGR2_I2S3SRC_BB = RCC_I2S3CLKSource; +} +#endif /* STM32F10X_CL */ + +/** + * @brief Configures the External Low Speed oscillator (LSE). + * @param RCC_LSE: specifies the new state of the LSE. + * This parameter can be one of the following values: + * @arg RCC_LSE_OFF: LSE oscillator OFF + * @arg RCC_LSE_ON: LSE oscillator ON + * @arg RCC_LSE_Bypass: LSE oscillator bypassed with external clock + * @retval None + */ +void RCC_LSEConfig(uint8_t RCC_LSE) +{ + /* Check the parameters */ + assert_param(IS_RCC_LSE(RCC_LSE)); + /* Reset LSEON and LSEBYP bits before configuring the LSE ------------------*/ + /* Reset LSEON bit */ + *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF; + /* Reset LSEBYP bit */ + *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF; + /* Configure LSE (RCC_LSE_OFF is already covered by the code section above) */ + switch(RCC_LSE) + { + case RCC_LSE_ON: + /* Set LSEON bit */ + *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_ON; + break; + + case RCC_LSE_Bypass: + /* Set LSEBYP and LSEON bits */ + *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_Bypass | RCC_LSE_ON; + break; + + default: + break; + } +} + +/** + * @brief Enables or disables the Internal Low Speed oscillator (LSI). + * @note LSI can not be disabled if the IWDG is running. + * @param NewState: new state of the LSI. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_LSICmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CSR_LSION_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the RTC clock (RTCCLK). + * @note Once the RTC clock is selected it cant be changed unless the Backup domain is reset. + * @param RCC_RTCCLKSource: specifies the RTC clock source. + * This parameter can be one of the following values: + * @arg RCC_RTCCLKSource_LSE: LSE selected as RTC clock + * @arg RCC_RTCCLKSource_LSI: LSI selected as RTC clock + * @arg RCC_RTCCLKSource_HSE_Div128: HSE clock divided by 128 selected as RTC clock + * @retval None + */ +void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource) +{ + /* Check the parameters */ + assert_param(IS_RCC_RTCCLK_SOURCE(RCC_RTCCLKSource)); + /* Select the RTC clock source */ + RCC->BDCR |= RCC_RTCCLKSource; +} + +/** + * @brief Enables or disables the RTC clock. + * @note This function must be used only after the RTC clock was selected using the RCC_RTCCLKConfig function. + * @param NewState: new state of the RTC clock. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_RTCCLKCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) BDCR_RTCEN_BB = (uint32_t)NewState; +} + +/** + * @brief Returns the frequencies of different on chip clocks. + * @param RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold + * the clocks frequencies. + * @retval None + */ +void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks) +{ + uint32_t tmp = 0, pllmull = 0, pllsource = 0, presc = 0; + +#ifdef STM32F10X_CL + uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0; +#endif /* STM32F10X_CL */ + +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) + uint32_t prediv1factor = 0; +#endif + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & CFGR_SWS_Mask; + + switch (tmp) + { + case 0x00: /* HSI used as system clock */ + RCC_Clocks->SYSCLK_Frequency = HSI_Value; + break; + case 0x04: /* HSE used as system clock */ + RCC_Clocks->SYSCLK_Frequency = HSE_Value; + break; + case 0x08: /* PLL used as system clock */ + + /* Get PLL clock source and multiplication factor ----------------------*/ + pllmull = RCC->CFGR & CFGR_PLLMull_Mask; + pllsource = RCC->CFGR & CFGR_PLLSRC_Mask; + +#ifndef STM32F10X_CL + pllmull = ( pllmull >> 18) + 2; + + if (pllsource == 0x00) + {/* HSI oscillator clock divided by 2 selected as PLL clock entry */ + RCC_Clocks->SYSCLK_Frequency = (HSI_Value >> 1) * pllmull; + } + else + { + #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) + prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1; + /* HSE oscillator clock selected as PREDIV1 clock entry */ + RCC_Clocks->SYSCLK_Frequency = (HSE_Value / prediv1factor) * pllmull; + #else + /* HSE selected as PLL clock entry */ + if ((RCC->CFGR & CFGR_PLLXTPRE_Mask) != (uint32_t)RESET) + {/* HSE oscillator clock divided by 2 */ + RCC_Clocks->SYSCLK_Frequency = (HSE_Value >> 1) * pllmull; + } + else + { + RCC_Clocks->SYSCLK_Frequency = HSE_Value * pllmull; + } + #endif + } +#else + pllmull = pllmull >> 18; + + if (pllmull != 0x0D) + { + pllmull += 2; + } + else + { /* PLL multiplication factor = PLL input clock * 6.5 */ + pllmull = 13 / 2; + } + + if (pllsource == 0x00) + {/* HSI oscillator clock divided by 2 selected as PLL clock entry */ + RCC_Clocks->SYSCLK_Frequency = (HSI_Value >> 1) * pllmull; + } + else + {/* PREDIV1 selected as PLL clock entry */ + + /* Get PREDIV1 clock source and division factor */ + prediv1source = RCC->CFGR2 & CFGR2_PREDIV1SRC; + prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1; + + if (prediv1source == 0) + { /* HSE oscillator clock selected as PREDIV1 clock entry */ + RCC_Clocks->SYSCLK_Frequency = (HSE_Value / prediv1factor) * pllmull; + } + else + {/* PLL2 clock selected as PREDIV1 clock entry */ + + /* Get PREDIV2 division factor and PLL2 multiplication factor */ + prediv2factor = ((RCC->CFGR2 & CFGR2_PREDIV2) >> 4) + 1; + pll2mull = ((RCC->CFGR2 & CFGR2_PLL2MUL) >> 8 ) + 2; + RCC_Clocks->SYSCLK_Frequency = (((HSE_Value / prediv2factor) * pll2mull) / prediv1factor) * pllmull; + } + } +#endif /* STM32F10X_CL */ + break; + + default: + RCC_Clocks->SYSCLK_Frequency = HSI_Value; + break; + } + + /* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*/ + /* Get HCLK prescaler */ + tmp = RCC->CFGR & CFGR_HPRE_Set_Mask; + tmp = tmp >> 4; + presc = APBAHBPrescTable[tmp]; + /* HCLK clock frequency */ + RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc; + /* Get PCLK1 prescaler */ + tmp = RCC->CFGR & CFGR_PPRE1_Set_Mask; + tmp = tmp >> 8; + presc = APBAHBPrescTable[tmp]; + /* PCLK1 clock frequency */ + RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc; + /* Get PCLK2 prescaler */ + tmp = RCC->CFGR & CFGR_PPRE2_Set_Mask; + tmp = tmp >> 11; + presc = APBAHBPrescTable[tmp]; + /* PCLK2 clock frequency */ + RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc; + /* Get ADCCLK prescaler */ + tmp = RCC->CFGR & CFGR_ADCPRE_Set_Mask; + tmp = tmp >> 14; + presc = ADCPrescTable[tmp]; + /* ADCCLK clock frequency */ + RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK2_Frequency / presc; +} + +/** + * @brief Enables or disables the AHB peripheral clock. + * @param RCC_AHBPeriph: specifies the AHB peripheral to gates its clock. + * + * For @b STM32_Connectivity_line_devices, this parameter can be any combination + * of the following values: + * @arg RCC_AHBPeriph_DMA1 + * @arg RCC_AHBPeriph_DMA2 + * @arg RCC_AHBPeriph_SRAM + * @arg RCC_AHBPeriph_FLITF + * @arg RCC_AHBPeriph_CRC + * @arg RCC_AHBPeriph_OTG_FS + * @arg RCC_AHBPeriph_ETH_MAC + * @arg RCC_AHBPeriph_ETH_MAC_Tx + * @arg RCC_AHBPeriph_ETH_MAC_Rx + * + * For @b other_STM32_devices, this parameter can be any combination of the + * following values: + * @arg RCC_AHBPeriph_DMA1 + * @arg RCC_AHBPeriph_DMA2 + * @arg RCC_AHBPeriph_SRAM + * @arg RCC_AHBPeriph_FLITF + * @arg RCC_AHBPeriph_CRC + * @arg RCC_AHBPeriph_FSMC + * @arg RCC_AHBPeriph_SDIO + * + * @note SRAM and FLITF clock can be disabled only during sleep mode. + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHBENR |= RCC_AHBPeriph; + } + else + { + RCC->AHBENR &= ~RCC_AHBPeriph; + } +} + +/** + * @brief Enables or disables the High Speed APB (APB2) peripheral clock. + * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB, + * RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE, + * RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1, + * RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1, + * RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3, + * RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17, + * RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11 + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->APB2ENR |= RCC_APB2Periph; + } + else + { + RCC->APB2ENR &= ~RCC_APB2Periph; + } +} + +/** + * @brief Enables or disables the Low Speed APB (APB1) peripheral clock. + * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3, RCC_APB1Periph_TIM4, + * RCC_APB1Periph_TIM5, RCC_APB1Periph_TIM6, RCC_APB1Periph_TIM7, + * RCC_APB1Periph_WWDG, RCC_APB1Periph_SPI2, RCC_APB1Periph_SPI3, + * RCC_APB1Periph_USART2, RCC_APB1Periph_USART3, RCC_APB1Periph_USART4, + * RCC_APB1Periph_USART5, RCC_APB1Periph_I2C1, RCC_APB1Periph_I2C2, + * RCC_APB1Periph_USB, RCC_APB1Periph_CAN1, RCC_APB1Periph_BKP, + * RCC_APB1Periph_PWR, RCC_APB1Periph_DAC, RCC_APB1Periph_CEC, + * RCC_APB1Periph_TIM12, RCC_APB1Periph_TIM13, RCC_APB1Periph_TIM14 + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->APB1ENR |= RCC_APB1Periph; + } + else + { + RCC->APB1ENR &= ~RCC_APB1Periph; + } +} + +#ifdef STM32F10X_CL +/** + * @brief Forces or releases AHB peripheral reset. + * @note This function applies only to STM32 Connectivity line devices. + * @param RCC_AHBPeriph: specifies the AHB peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_AHBPeriph_OTG_FS + * @arg RCC_AHBPeriph_ETH_MAC + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB_PERIPH_RESET(RCC_AHBPeriph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHBRSTR |= RCC_AHBPeriph; + } + else + { + RCC->AHBRSTR &= ~RCC_AHBPeriph; + } +} +#endif /* STM32F10X_CL */ + +/** + * @brief Forces or releases High Speed APB (APB2) peripheral reset. + * @param RCC_APB2Periph: specifies the APB2 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB, + * RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE, + * RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1, + * RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1, + * RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3, + * RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17, + * RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11 + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->APB2RSTR |= RCC_APB2Periph; + } + else + { + RCC->APB2RSTR &= ~RCC_APB2Periph; + } +} + +/** + * @brief Forces or releases Low Speed APB (APB1) peripheral reset. + * @param RCC_APB1Periph: specifies the APB1 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3, RCC_APB1Periph_TIM4, + * RCC_APB1Periph_TIM5, RCC_APB1Periph_TIM6, RCC_APB1Periph_TIM7, + * RCC_APB1Periph_WWDG, RCC_APB1Periph_SPI2, RCC_APB1Periph_SPI3, + * RCC_APB1Periph_USART2, RCC_APB1Periph_USART3, RCC_APB1Periph_USART4, + * RCC_APB1Periph_USART5, RCC_APB1Periph_I2C1, RCC_APB1Periph_I2C2, + * RCC_APB1Periph_USB, RCC_APB1Periph_CAN1, RCC_APB1Periph_BKP, + * RCC_APB1Periph_PWR, RCC_APB1Periph_DAC, RCC_APB1Periph_CEC, + * RCC_APB1Periph_TIM12, RCC_APB1Periph_TIM13, RCC_APB1Periph_TIM14 + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->APB1RSTR |= RCC_APB1Periph; + } + else + { + RCC->APB1RSTR &= ~RCC_APB1Periph; + } +} + +/** + * @brief Forces or releases the Backup domain reset. + * @param NewState: new state of the Backup domain reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_BackupResetCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) BDCR_BDRST_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the Clock Security System. + * @param NewState: new state of the Clock Security System.. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_ClockSecuritySystemCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CR_CSSON_BB = (uint32_t)NewState; +} + +/** + * @brief Selects the clock source to output on MCO pin. + * @param RCC_MCO: specifies the clock source to output. + * + * For @b STM32_Connectivity_line_devices, this parameter can be one of the + * following values: + * @arg RCC_MCO_NoClock: No clock selected + * @arg RCC_MCO_SYSCLK: System clock selected + * @arg RCC_MCO_HSI: HSI oscillator clock selected + * @arg RCC_MCO_HSE: HSE oscillator clock selected + * @arg RCC_MCO_PLLCLK_Div2: PLL clock divided by 2 selected + * @arg RCC_MCO_PLL2CLK: PLL2 clock selected + * @arg RCC_MCO_PLL3CLK_Div2: PLL3 clock divided by 2 selected + * @arg RCC_MCO_XT1: External 3-25 MHz oscillator clock selected + * @arg RCC_MCO_PLL3CLK: PLL3 clock selected + * + * For @b other_STM32_devices, this parameter can be one of the following values: + * @arg RCC_MCO_NoClock: No clock selected + * @arg RCC_MCO_SYSCLK: System clock selected + * @arg RCC_MCO_HSI: HSI oscillator clock selected + * @arg RCC_MCO_HSE: HSE oscillator clock selected + * @arg RCC_MCO_PLLCLK_Div2: PLL clock divided by 2 selected + * + * @retval None + */ +void RCC_MCOConfig(uint8_t RCC_MCO) +{ + /* Check the parameters */ + assert_param(IS_RCC_MCO(RCC_MCO)); + + /* Perform Byte access to MCO bits to select the MCO source */ + *(__IO uint8_t *) CFGR_BYTE4_ADDRESS = RCC_MCO; +} + +/** + * @brief Checks whether the specified RCC flag is set or not. + * @param RCC_FLAG: specifies the flag to check. + * + * For @b STM32_Connectivity_line_devices, this parameter can be one of the + * following values: + * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready + * @arg RCC_FLAG_HSERDY: HSE oscillator clock ready + * @arg RCC_FLAG_PLLRDY: PLL clock ready + * @arg RCC_FLAG_PLL2RDY: PLL2 clock ready + * @arg RCC_FLAG_PLL3RDY: PLL3 clock ready + * @arg RCC_FLAG_LSERDY: LSE oscillator clock ready + * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready + * @arg RCC_FLAG_PINRST: Pin reset + * @arg RCC_FLAG_PORRST: POR/PDR reset + * @arg RCC_FLAG_SFTRST: Software reset + * @arg RCC_FLAG_IWDGRST: Independent Watchdog reset + * @arg RCC_FLAG_WWDGRST: Window Watchdog reset + * @arg RCC_FLAG_LPWRRST: Low Power reset + * + * For @b other_STM32_devices, this parameter can be one of the following values: + * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready + * @arg RCC_FLAG_HSERDY: HSE oscillator clock ready + * @arg RCC_FLAG_PLLRDY: PLL clock ready + * @arg RCC_FLAG_LSERDY: LSE oscillator clock ready + * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready + * @arg RCC_FLAG_PINRST: Pin reset + * @arg RCC_FLAG_PORRST: POR/PDR reset + * @arg RCC_FLAG_SFTRST: Software reset + * @arg RCC_FLAG_IWDGRST: Independent Watchdog reset + * @arg RCC_FLAG_WWDGRST: Window Watchdog reset + * @arg RCC_FLAG_LPWRRST: Low Power reset + * + * @retval The new state of RCC_FLAG (SET or RESET). + */ +FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG) +{ + uint32_t tmp = 0; + uint32_t statusreg = 0; + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_RCC_FLAG(RCC_FLAG)); + + /* Get the RCC register index */ + tmp = RCC_FLAG >> 5; + if (tmp == 1) /* The flag to check is in CR register */ + { + statusreg = RCC->CR; + } + else if (tmp == 2) /* The flag to check is in BDCR register */ + { + statusreg = RCC->BDCR; + } + else /* The flag to check is in CSR register */ + { + statusreg = RCC->CSR; + } + + /* Get the flag position */ + tmp = RCC_FLAG & FLAG_Mask; + if ((statusreg & ((uint32_t)1 << tmp)) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + + /* Return the flag status */ + return bitstatus; +} + +/** + * @brief Clears the RCC reset flags. + * @note The reset flags are: RCC_FLAG_PINRST, RCC_FLAG_PORRST, RCC_FLAG_SFTRST, + * RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST + * @param None + * @retval None + */ +void RCC_ClearFlag(void) +{ + /* Set RMVF bit to clear the reset flags */ + RCC->CSR |= CSR_RMVF_Set; +} + +/** + * @brief Checks whether the specified RCC interrupt has occurred or not. + * @param RCC_IT: specifies the RCC interrupt source to check. + * + * For @b STM32_Connectivity_line_devices, this parameter can be one of the + * following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: PLL ready interrupt + * @arg RCC_IT_PLL2RDY: PLL2 ready interrupt + * @arg RCC_IT_PLL3RDY: PLL3 ready interrupt + * @arg RCC_IT_CSS: Clock Security System interrupt + * + * For @b other_STM32_devices, this parameter can be one of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: PLL ready interrupt + * @arg RCC_IT_CSS: Clock Security System interrupt + * + * @retval The new state of RCC_IT (SET or RESET). + */ +ITStatus RCC_GetITStatus(uint8_t RCC_IT) +{ + ITStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_RCC_GET_IT(RCC_IT)); + + /* Check the status of the specified RCC interrupt */ + if ((RCC->CIR & RCC_IT) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + + /* Return the RCC_IT status */ + return bitstatus; +} + +/** + * @brief Clears the RCCs interrupt pending bits. + * @param RCC_IT: specifies the interrupt pending bit to clear. + * + * For @b STM32_Connectivity_line_devices, this parameter can be any combination + * of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: PLL ready interrupt + * @arg RCC_IT_PLL2RDY: PLL2 ready interrupt + * @arg RCC_IT_PLL3RDY: PLL3 ready interrupt + * @arg RCC_IT_CSS: Clock Security System interrupt + * + * For @b other_STM32_devices, this parameter can be any combination of the + * following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: PLL ready interrupt + * + * @arg RCC_IT_CSS: Clock Security System interrupt + * @retval None + */ +void RCC_ClearITPendingBit(uint8_t RCC_IT) +{ + /* Check the parameters */ + assert_param(IS_RCC_CLEAR_IT(RCC_IT)); + + /* Perform Byte access to RCC_CIR[23:16] bits to clear the selected interrupt + pending bits */ + *(__IO uint8_t *) CIR_BYTE3_ADDRESS = RCC_IT; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_rtc.c b/example/libs_stm/src/stm32f10x/stm32f10x_rtc.c new file mode 100644 index 000000000..2720124bd --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_rtc.c @@ -0,0 +1,341 @@ +/** + ****************************************************************************** + * @file stm32f10x_rtc.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the RTC firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_rtc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup RTC + * @brief RTC driver modules + * @{ + */ + +/** @defgroup RTC_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + +/** @defgroup RTC_Private_Defines + * @{ + */ + +#define CRL_CNF_Set ((uint16_t)0x0010) /*!< Configuration Flag Enable Mask */ +#define CRL_CNF_Reset ((uint16_t)0xFFEF) /*!< Configuration Flag Disable Mask */ +#define RTC_LSB_Mask ((uint32_t)0x0000FFFF) /*!< RTC LSB Mask */ +#define PRLH_MSB_Mask ((uint32_t)0x000F0000) /*!< RTC Prescaler MSB Mask */ + +/** + * @} + */ + +/** @defgroup RTC_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup RTC_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup RTC_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup RTC_Private_Functions + * @{ + */ + +/** + * @brief Enables or disables the specified RTC interrupts. + * @param RTC_IT: specifies the RTC interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg RTC_IT_OW: Overflow interrupt + * @arg RTC_IT_ALR: Alarm interrupt + * @arg RTC_IT_SEC: Second interrupt + * @param NewState: new state of the specified RTC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RTC_IT(RTC_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RTC->CRH |= RTC_IT; + } + else + { + RTC->CRH &= (uint16_t)~RTC_IT; + } +} + +/** + * @brief Enters the RTC configuration mode. + * @param None + * @retval None + */ +void RTC_EnterConfigMode(void) +{ + /* Set the CNF flag to enter in the Configuration Mode */ + RTC->CRL |= CRL_CNF_Set; +} + +/** + * @brief Exits from the RTC configuration mode. + * @param None + * @retval None + */ +void RTC_ExitConfigMode(void) +{ + /* Reset the CNF flag to exit from the Configuration Mode */ + RTC->CRL &= CRL_CNF_Reset; +} + +/** + * @brief Gets the RTC counter value. + * @param None + * @retval RTC counter value. + */ +uint32_t RTC_GetCounter(void) +{ + uint16_t tmp = 0; + tmp = RTC->CNTL; + return (((uint32_t)RTC->CNTH << 16 ) | tmp) ; +} + +/** + * @brief Sets the RTC counter value. + * @param CounterValue: RTC counter new value. + * @retval None + */ +void RTC_SetCounter(uint32_t CounterValue) +{ + RTC_EnterConfigMode(); + /* Set RTC COUNTER MSB word */ + RTC->CNTH = CounterValue >> 16; + /* Set RTC COUNTER LSB word */ + RTC->CNTL = (CounterValue & RTC_LSB_Mask); + RTC_ExitConfigMode(); +} + +/** + * @brief Sets the RTC prescaler value. + * @param PrescalerValue: RTC prescaler new value. + * @retval None + */ +void RTC_SetPrescaler(uint32_t PrescalerValue) +{ + /* Check the parameters */ + assert_param(IS_RTC_PRESCALER(PrescalerValue)); + + RTC_EnterConfigMode(); + /* Set RTC PRESCALER MSB word */ + RTC->PRLH = (PrescalerValue & PRLH_MSB_Mask) >> 16; + /* Set RTC PRESCALER LSB word */ + RTC->PRLL = (PrescalerValue & RTC_LSB_Mask); + RTC_ExitConfigMode(); +} + +/** + * @brief Sets the RTC alarm value. + * @param AlarmValue: RTC alarm new value. + * @retval None + */ +void RTC_SetAlarm(uint32_t AlarmValue) +{ + RTC_EnterConfigMode(); + /* Set the ALARM MSB word */ + RTC->ALRH = AlarmValue >> 16; + /* Set the ALARM LSB word */ + RTC->ALRL = (AlarmValue & RTC_LSB_Mask); + RTC_ExitConfigMode(); +} + +/** + * @brief Gets the RTC divider value. + * @param None + * @retval RTC Divider value. + */ +uint32_t RTC_GetDivider(void) +{ + uint32_t tmp = 0x00; + tmp = ((uint32_t)RTC->DIVH & (uint32_t)0x000F) << 16; + tmp |= RTC->DIVL; + return tmp; +} + +/** + * @brief Waits until last write operation on RTC registers has finished. + * @note This function must be called before any write to RTC registers. + * @param None + * @retval None + */ +void RTC_WaitForLastTask(void) +{ + /* Loop until RTOFF flag is set */ + while ((RTC->CRL & RTC_FLAG_RTOFF) == (uint16_t)RESET) + { + } +} + +/** + * @brief Waits until the RTC registers (RTC_CNT, RTC_ALR and RTC_PRL) + * are synchronized with RTC APB clock. + * @note This function must be called before any read operation after an APB reset + * or an APB clock stop. + * @param None + * @retval None + */ +void RTC_WaitForSynchro(void) +{ + /* Clear RSF flag */ + RTC->CRL &= (uint16_t)~RTC_FLAG_RSF; + /* Loop until RSF flag is set */ + while ((RTC->CRL & RTC_FLAG_RSF) == (uint16_t)RESET) + { + } +} + +/** + * @brief Checks whether the specified RTC flag is set or not. + * @param RTC_FLAG: specifies the flag to check. + * This parameter can be one the following values: + * @arg RTC_FLAG_RTOFF: RTC Operation OFF flag + * @arg RTC_FLAG_RSF: Registers Synchronized flag + * @arg RTC_FLAG_OW: Overflow flag + * @arg RTC_FLAG_ALR: Alarm flag + * @arg RTC_FLAG_SEC: Second flag + * @retval The new state of RTC_FLAG (SET or RESET). + */ +FlagStatus RTC_GetFlagStatus(uint16_t RTC_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_RTC_GET_FLAG(RTC_FLAG)); + + if ((RTC->CRL & RTC_FLAG) != (uint16_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the RTCs pending flags. + * @param RTC_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg RTC_FLAG_RSF: Registers Synchronized flag. This flag is cleared only after + * an APB reset or an APB Clock stop. + * @arg RTC_FLAG_OW: Overflow flag + * @arg RTC_FLAG_ALR: Alarm flag + * @arg RTC_FLAG_SEC: Second flag + * @retval None + */ +void RTC_ClearFlag(uint16_t RTC_FLAG) +{ + /* Check the parameters */ + assert_param(IS_RTC_CLEAR_FLAG(RTC_FLAG)); + + /* Clear the coressponding RTC flag */ + RTC->CRL &= (uint16_t)~RTC_FLAG; +} + +/** + * @brief Checks whether the specified RTC interrupt has occured or not. + * @param RTC_IT: specifies the RTC interrupts sources to check. + * This parameter can be one of the following values: + * @arg RTC_IT_OW: Overflow interrupt + * @arg RTC_IT_ALR: Alarm interrupt + * @arg RTC_IT_SEC: Second interrupt + * @retval The new state of the RTC_IT (SET or RESET). + */ +ITStatus RTC_GetITStatus(uint16_t RTC_IT) +{ + ITStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_RTC_GET_IT(RTC_IT)); + + bitstatus = (ITStatus)(RTC->CRL & RTC_IT); + if (((RTC->CRH & RTC_IT) != (uint16_t)RESET) && (bitstatus != (uint16_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the RTCs interrupt pending bits. + * @param RTC_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg RTC_IT_OW: Overflow interrupt + * @arg RTC_IT_ALR: Alarm interrupt + * @arg RTC_IT_SEC: Second interrupt + * @retval None + */ +void RTC_ClearITPendingBit(uint16_t RTC_IT) +{ + /* Check the parameters */ + assert_param(IS_RTC_IT(RTC_IT)); + + /* Clear the coressponding RTC pending bit */ + RTC->CRL &= (uint16_t)~RTC_IT; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_sdio.c b/example/libs_stm/src/stm32f10x/stm32f10x_sdio.c new file mode 100644 index 000000000..9d4a3763d --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_sdio.c @@ -0,0 +1,798 @@ +/** + ****************************************************************************** + * @file stm32f10x_sdio.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the SDIO firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_sdio.h" +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup SDIO + * @brief SDIO driver modules + * @{ + */ + +/** @defgroup SDIO_Private_TypesDefinitions + * @{ + */ + +/* ------------ SDIO registers bit address in the alias region ----------- */ +#define SDIO_OFFSET (SDIO_BASE - PERIPH_BASE) + +/* --- CLKCR Register ---*/ + +/* Alias word address of CLKEN bit */ +#define CLKCR_OFFSET (SDIO_OFFSET + 0x04) +#define CLKEN_BitNumber 0x08 +#define CLKCR_CLKEN_BB (PERIPH_BB_BASE + (CLKCR_OFFSET * 32) + (CLKEN_BitNumber * 4)) + +/* --- CMD Register ---*/ + +/* Alias word address of SDIOSUSPEND bit */ +#define CMD_OFFSET (SDIO_OFFSET + 0x0C) +#define SDIOSUSPEND_BitNumber 0x0B +#define CMD_SDIOSUSPEND_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (SDIOSUSPEND_BitNumber * 4)) + +/* Alias word address of ENCMDCOMPL bit */ +#define ENCMDCOMPL_BitNumber 0x0C +#define CMD_ENCMDCOMPL_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ENCMDCOMPL_BitNumber * 4)) + +/* Alias word address of NIEN bit */ +#define NIEN_BitNumber 0x0D +#define CMD_NIEN_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (NIEN_BitNumber * 4)) + +/* Alias word address of ATACMD bit */ +#define ATACMD_BitNumber 0x0E +#define CMD_ATACMD_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ATACMD_BitNumber * 4)) + +/* --- DCTRL Register ---*/ + +/* Alias word address of DMAEN bit */ +#define DCTRL_OFFSET (SDIO_OFFSET + 0x2C) +#define DMAEN_BitNumber 0x03 +#define DCTRL_DMAEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (DMAEN_BitNumber * 4)) + +/* Alias word address of RWSTART bit */ +#define RWSTART_BitNumber 0x08 +#define DCTRL_RWSTART_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTART_BitNumber * 4)) + +/* Alias word address of RWSTOP bit */ +#define RWSTOP_BitNumber 0x09 +#define DCTRL_RWSTOP_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTOP_BitNumber * 4)) + +/* Alias word address of RWMOD bit */ +#define RWMOD_BitNumber 0x0A +#define DCTRL_RWMOD_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWMOD_BitNumber * 4)) + +/* Alias word address of SDIOEN bit */ +#define SDIOEN_BitNumber 0x0B +#define DCTRL_SDIOEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (SDIOEN_BitNumber * 4)) + +/* ---------------------- SDIO registers bit mask ------------------------ */ + +/* --- CLKCR Register ---*/ + +/* CLKCR register clear mask */ +#define CLKCR_CLEAR_MASK ((uint32_t)0xFFFF8100) + +/* --- PWRCTRL Register ---*/ + +/* SDIO PWRCTRL Mask */ +#define PWR_PWRCTRL_MASK ((uint32_t)0xFFFFFFFC) + +/* --- DCTRL Register ---*/ + +/* SDIO DCTRL Clear Mask */ +#define DCTRL_CLEAR_MASK ((uint32_t)0xFFFFFF08) + +/* --- CMD Register ---*/ + +/* CMD Register clear mask */ +#define CMD_CLEAR_MASK ((uint32_t)0xFFFFF800) + +/* SDIO RESP Registers Address */ +#define SDIO_RESP_ADDR ((uint32_t)(SDIO_BASE + 0x14)) + +/** + * @} + */ + +/** @defgroup SDIO_Private_Defines + * @{ + */ + +/** + * @} + */ + +/** @defgroup SDIO_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup SDIO_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup SDIO_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup SDIO_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the SDIO peripheral registers to their default reset values. + * @param None + * @retval None + */ +void SDIO_DeInit(void) +{ + SDIO->POWER = 0x00000000; + SDIO->CLKCR = 0x00000000; + SDIO->ARG = 0x00000000; + SDIO->CMD = 0x00000000; + SDIO->DTIMER = 0x00000000; + SDIO->DLEN = 0x00000000; + SDIO->DCTRL = 0x00000000; + SDIO->ICR = 0x00C007FF; + SDIO->MASK = 0x00000000; +} + +/** + * @brief Initializes the SDIO peripheral according to the specified + * parameters in the SDIO_InitStruct. + * @param SDIO_InitStruct : pointer to a SDIO_InitTypeDef structure + * that contains the configuration information for the SDIO peripheral. + * @retval None + */ +void SDIO_Init(SDIO_InitTypeDef* SDIO_InitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_CLOCK_EDGE(SDIO_InitStruct->SDIO_ClockEdge)); + assert_param(IS_SDIO_CLOCK_BYPASS(SDIO_InitStruct->SDIO_ClockBypass)); + assert_param(IS_SDIO_CLOCK_POWER_SAVE(SDIO_InitStruct->SDIO_ClockPowerSave)); + assert_param(IS_SDIO_BUS_WIDE(SDIO_InitStruct->SDIO_BusWide)); + assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(SDIO_InitStruct->SDIO_HardwareFlowControl)); + +/*---------------------------- SDIO CLKCR Configuration ------------------------*/ + /* Get the SDIO CLKCR value */ + tmpreg = SDIO->CLKCR; + + /* Clear CLKDIV, PWRSAV, BYPASS, WIDBUS, NEGEDGE, HWFC_EN bits */ + tmpreg &= CLKCR_CLEAR_MASK; + + /* Set CLKDIV bits according to SDIO_ClockDiv value */ + /* Set PWRSAV bit according to SDIO_ClockPowerSave value */ + /* Set BYPASS bit according to SDIO_ClockBypass value */ + /* Set WIDBUS bits according to SDIO_BusWide value */ + /* Set NEGEDGE bits according to SDIO_ClockEdge value */ + /* Set HWFC_EN bits according to SDIO_HardwareFlowControl value */ + tmpreg |= (SDIO_InitStruct->SDIO_ClockDiv | SDIO_InitStruct->SDIO_ClockPowerSave | + SDIO_InitStruct->SDIO_ClockBypass | SDIO_InitStruct->SDIO_BusWide | + SDIO_InitStruct->SDIO_ClockEdge | SDIO_InitStruct->SDIO_HardwareFlowControl); + + /* Write to SDIO CLKCR */ + SDIO->CLKCR = tmpreg; +} + +/** + * @brief Fills each SDIO_InitStruct member with its default value. + * @param SDIO_InitStruct: pointer to an SDIO_InitTypeDef structure which + * will be initialized. + * @retval None + */ +void SDIO_StructInit(SDIO_InitTypeDef* SDIO_InitStruct) +{ + /* SDIO_InitStruct members default value */ + SDIO_InitStruct->SDIO_ClockDiv = 0x00; + SDIO_InitStruct->SDIO_ClockEdge = SDIO_ClockEdge_Rising; + SDIO_InitStruct->SDIO_ClockBypass = SDIO_ClockBypass_Disable; + SDIO_InitStruct->SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; + SDIO_InitStruct->SDIO_BusWide = SDIO_BusWide_1b; + SDIO_InitStruct->SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; +} + +/** + * @brief Enables or disables the SDIO Clock. + * @param NewState: new state of the SDIO Clock. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_ClockCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CLKCR_CLKEN_BB = (uint32_t)NewState; +} + +/** + * @brief Sets the power status of the controller. + * @param SDIO_PowerState: new state of the Power state. + * This parameter can be one of the following values: + * @arg SDIO_PowerState_OFF + * @arg SDIO_PowerState_ON + * @retval None + */ +void SDIO_SetPowerState(uint32_t SDIO_PowerState) +{ + /* Check the parameters */ + assert_param(IS_SDIO_POWER_STATE(SDIO_PowerState)); + + SDIO->POWER &= PWR_PWRCTRL_MASK; + SDIO->POWER |= SDIO_PowerState; +} + +/** + * @brief Gets the power status of the controller. + * @param None + * @retval Power status of the controller. The returned value can + * be one of the following: + * - 0x00: Power OFF + * - 0x02: Power UP + * - 0x03: Power ON + */ +uint32_t SDIO_GetPowerState(void) +{ + return (SDIO->POWER & (~PWR_PWRCTRL_MASK)); +} + +/** + * @brief Enables or disables the SDIO interrupts. + * @param SDIO_IT: specifies the SDIO interrupt sources to be enabled or disabled. + * This parameter can be one or a combination of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt + * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt + * @arg SDIO_IT_TXACT: Data transmit in progress interrupt + * @arg SDIO_IT_RXACT: Data receive in progress interrupt + * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt + * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt + * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt + * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt + * @param NewState: new state of the specified SDIO interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_ITConfig(uint32_t SDIO_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SDIO_IT(SDIO_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the SDIO interrupts */ + SDIO->MASK |= SDIO_IT; + } + else + { + /* Disable the SDIO interrupts */ + SDIO->MASK &= ~SDIO_IT; + } +} + +/** + * @brief Enables or disables the SDIO DMA request. + * @param NewState: new state of the selected SDIO DMA request. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_DMACmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) DCTRL_DMAEN_BB = (uint32_t)NewState; +} + +/** + * @brief Initializes the SDIO Command according to the specified + * parameters in the SDIO_CmdInitStruct and send the command. + * @param SDIO_CmdInitStruct : pointer to a SDIO_CmdInitTypeDef + * structure that contains the configuration information for the SDIO command. + * @retval None + */ +void SDIO_SendCommand(SDIO_CmdInitTypeDef *SDIO_CmdInitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_CMD_INDEX(SDIO_CmdInitStruct->SDIO_CmdIndex)); + assert_param(IS_SDIO_RESPONSE(SDIO_CmdInitStruct->SDIO_Response)); + assert_param(IS_SDIO_WAIT(SDIO_CmdInitStruct->SDIO_Wait)); + assert_param(IS_SDIO_CPSM(SDIO_CmdInitStruct->SDIO_CPSM)); + +/*---------------------------- SDIO ARG Configuration ------------------------*/ + /* Set the SDIO Argument value */ + SDIO->ARG = SDIO_CmdInitStruct->SDIO_Argument; + +/*---------------------------- SDIO CMD Configuration ------------------------*/ + /* Get the SDIO CMD value */ + tmpreg = SDIO->CMD; + /* Clear CMDINDEX, WAITRESP, WAITINT, WAITPEND, CPSMEN bits */ + tmpreg &= CMD_CLEAR_MASK; + /* Set CMDINDEX bits according to SDIO_CmdIndex value */ + /* Set WAITRESP bits according to SDIO_Response value */ + /* Set WAITINT and WAITPEND bits according to SDIO_Wait value */ + /* Set CPSMEN bits according to SDIO_CPSM value */ + tmpreg |= (uint32_t)SDIO_CmdInitStruct->SDIO_CmdIndex | SDIO_CmdInitStruct->SDIO_Response + | SDIO_CmdInitStruct->SDIO_Wait | SDIO_CmdInitStruct->SDIO_CPSM; + + /* Write to SDIO CMD */ + SDIO->CMD = tmpreg; +} + +/** + * @brief Fills each SDIO_CmdInitStruct member with its default value. + * @param SDIO_CmdInitStruct: pointer to an SDIO_CmdInitTypeDef + * structure which will be initialized. + * @retval None + */ +void SDIO_CmdStructInit(SDIO_CmdInitTypeDef* SDIO_CmdInitStruct) +{ + /* SDIO_CmdInitStruct members default value */ + SDIO_CmdInitStruct->SDIO_Argument = 0x00; + SDIO_CmdInitStruct->SDIO_CmdIndex = 0x00; + SDIO_CmdInitStruct->SDIO_Response = SDIO_Response_No; + SDIO_CmdInitStruct->SDIO_Wait = SDIO_Wait_No; + SDIO_CmdInitStruct->SDIO_CPSM = SDIO_CPSM_Disable; +} + +/** + * @brief Returns command index of last command for which response received. + * @param None + * @retval Returns the command index of the last command response received. + */ +uint8_t SDIO_GetCommandResponse(void) +{ + return (uint8_t)(SDIO->RESPCMD); +} + +/** + * @brief Returns response received from the card for the last command. + * @param SDIO_RESP: Specifies the SDIO response register. + * This parameter can be one of the following values: + * @arg SDIO_RESP1: Response Register 1 + * @arg SDIO_RESP2: Response Register 2 + * @arg SDIO_RESP3: Response Register 3 + * @arg SDIO_RESP4: Response Register 4 + * @retval The Corresponding response register value. + */ +uint32_t SDIO_GetResponse(uint32_t SDIO_RESP) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_RESP(SDIO_RESP)); + + tmp = SDIO_RESP_ADDR + SDIO_RESP; + + return (*(__IO uint32_t *) tmp); +} + +/** + * @brief Initializes the SDIO data path according to the specified + * parameters in the SDIO_DataInitStruct. + * @param SDIO_DataInitStruct : pointer to a SDIO_DataInitTypeDef structure that + * contains the configuration information for the SDIO command. + * @retval None + */ +void SDIO_DataConfig(SDIO_DataInitTypeDef* SDIO_DataInitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_DATA_LENGTH(SDIO_DataInitStruct->SDIO_DataLength)); + assert_param(IS_SDIO_BLOCK_SIZE(SDIO_DataInitStruct->SDIO_DataBlockSize)); + assert_param(IS_SDIO_TRANSFER_DIR(SDIO_DataInitStruct->SDIO_TransferDir)); + assert_param(IS_SDIO_TRANSFER_MODE(SDIO_DataInitStruct->SDIO_TransferMode)); + assert_param(IS_SDIO_DPSM(SDIO_DataInitStruct->SDIO_DPSM)); + +/*---------------------------- SDIO DTIMER Configuration ---------------------*/ + /* Set the SDIO Data TimeOut value */ + SDIO->DTIMER = SDIO_DataInitStruct->SDIO_DataTimeOut; + +/*---------------------------- SDIO DLEN Configuration -----------------------*/ + /* Set the SDIO DataLength value */ + SDIO->DLEN = SDIO_DataInitStruct->SDIO_DataLength; + +/*---------------------------- SDIO DCTRL Configuration ----------------------*/ + /* Get the SDIO DCTRL value */ + tmpreg = SDIO->DCTRL; + /* Clear DEN, DTMODE, DTDIR and DBCKSIZE bits */ + tmpreg &= DCTRL_CLEAR_MASK; + /* Set DEN bit according to SDIO_DPSM value */ + /* Set DTMODE bit according to SDIO_TransferMode value */ + /* Set DTDIR bit according to SDIO_TransferDir value */ + /* Set DBCKSIZE bits according to SDIO_DataBlockSize value */ + tmpreg |= (uint32_t)SDIO_DataInitStruct->SDIO_DataBlockSize | SDIO_DataInitStruct->SDIO_TransferDir + | SDIO_DataInitStruct->SDIO_TransferMode | SDIO_DataInitStruct->SDIO_DPSM; + + /* Write to SDIO DCTRL */ + SDIO->DCTRL = tmpreg; +} + +/** + * @brief Fills each SDIO_DataInitStruct member with its default value. + * @param SDIO_DataInitStruct: pointer to an SDIO_DataInitTypeDef structure which + * will be initialized. + * @retval None + */ +void SDIO_DataStructInit(SDIO_DataInitTypeDef* SDIO_DataInitStruct) +{ + /* SDIO_DataInitStruct members default value */ + SDIO_DataInitStruct->SDIO_DataTimeOut = 0xFFFFFFFF; + SDIO_DataInitStruct->SDIO_DataLength = 0x00; + SDIO_DataInitStruct->SDIO_DataBlockSize = SDIO_DataBlockSize_1b; + SDIO_DataInitStruct->SDIO_TransferDir = SDIO_TransferDir_ToCard; + SDIO_DataInitStruct->SDIO_TransferMode = SDIO_TransferMode_Block; + SDIO_DataInitStruct->SDIO_DPSM = SDIO_DPSM_Disable; +} + +/** + * @brief Returns number of remaining data bytes to be transferred. + * @param None + * @retval Number of remaining data bytes to be transferred + */ +uint32_t SDIO_GetDataCounter(void) +{ + return SDIO->DCOUNT; +} + +/** + * @brief Read one data word from Rx FIFO. + * @param None + * @retval Data received + */ +uint32_t SDIO_ReadData(void) +{ + return SDIO->FIFO; +} + +/** + * @brief Write one data word to Tx FIFO. + * @param Data: 32-bit data word to write. + * @retval None + */ +void SDIO_WriteData(uint32_t Data) +{ + SDIO->FIFO = Data; +} + +/** + * @brief Returns the number of words left to be written to or read from FIFO. + * @param None + * @retval Remaining number of words. + */ +uint32_t SDIO_GetFIFOCount(void) +{ + return SDIO->FIFOCNT; +} + +/** + * @brief Starts the SD I/O Read Wait operation. + * @param NewState: new state of the Start SDIO Read Wait operation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_StartSDIOReadWait(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) DCTRL_RWSTART_BB = (uint32_t) NewState; +} + +/** + * @brief Stops the SD I/O Read Wait operation. + * @param NewState: new state of the Stop SDIO Read Wait operation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_StopSDIOReadWait(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) DCTRL_RWSTOP_BB = (uint32_t) NewState; +} + +/** + * @brief Sets one of the two options of inserting read wait interval. + * @param SDIO_ReadWaitMode: SD I/O Read Wait operation mode. + * This parametre can be: + * @arg SDIO_ReadWaitMode_CLK: Read Wait control by stopping SDIOCLK + * @arg SDIO_ReadWaitMode_DATA2: Read Wait control using SDIO_DATA2 + * @retval None + */ +void SDIO_SetSDIOReadWaitMode(uint32_t SDIO_ReadWaitMode) +{ + /* Check the parameters */ + assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode)); + + *(__IO uint32_t *) DCTRL_RWMOD_BB = SDIO_ReadWaitMode; +} + +/** + * @brief Enables or disables the SD I/O Mode Operation. + * @param NewState: new state of SDIO specific operation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_SetSDIOOperation(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) DCTRL_SDIOEN_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the SD I/O Mode suspend command sending. + * @param NewState: new state of the SD I/O Mode suspend command. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_SendSDIOSuspendCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CMD_SDIOSUSPEND_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the command completion signal. + * @param NewState: new state of command completion signal. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_CommandCompletionCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CMD_ENCMDCOMPL_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the CE-ATA interrupt. + * @param NewState: new state of CE-ATA interrupt. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_CEATAITCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CMD_NIEN_BB = (uint32_t)((~((uint32_t)NewState)) & ((uint32_t)0x1)); +} + +/** + * @brief Sends CE-ATA command (CMD61). + * @param NewState: new state of CE-ATA command. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SDIO_SendCEATACmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CMD_ATACMD_BB = (uint32_t)NewState; +} + +/** + * @brief Checks whether the specified SDIO flag is set or not. + * @param SDIO_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed) + * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) + * @arg SDIO_FLAG_CTIMEOUT: Command response timeout + * @arg SDIO_FLAG_DTIMEOUT: Data timeout + * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error + * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error + * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed) + * @arg SDIO_FLAG_CMDSENT: Command sent (no response required) + * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero) + * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide + * bus mode. + * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed) + * @arg SDIO_FLAG_CMDACT: Command transfer in progress + * @arg SDIO_FLAG_TXACT: Data transmit in progress + * @arg SDIO_FLAG_RXACT: Data receive in progress + * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty + * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full + * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full + * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full + * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty + * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty + * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO + * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO + * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received + * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61 + * @retval The new state of SDIO_FLAG (SET or RESET). + */ +FlagStatus SDIO_GetFlagStatus(uint32_t SDIO_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_SDIO_FLAG(SDIO_FLAG)); + + if ((SDIO->STA & SDIO_FLAG) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the SDIO's pending flags. + * @param SDIO_FLAG: specifies the flag to clear. + * This parameter can be one or a combination of the following values: + * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed) + * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) + * @arg SDIO_FLAG_CTIMEOUT: Command response timeout + * @arg SDIO_FLAG_DTIMEOUT: Data timeout + * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error + * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error + * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed) + * @arg SDIO_FLAG_CMDSENT: Command sent (no response required) + * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero) + * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide + * bus mode + * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed) + * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received + * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61 + * @retval None + */ +void SDIO_ClearFlag(uint32_t SDIO_FLAG) +{ + /* Check the parameters */ + assert_param(IS_SDIO_CLEAR_FLAG(SDIO_FLAG)); + + SDIO->ICR = SDIO_FLAG; +} + +/** + * @brief Checks whether the specified SDIO interrupt has occurred or not. + * @param SDIO_IT: specifies the SDIO interrupt source to check. + * This parameter can be one of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt + * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt + * @arg SDIO_IT_TXACT: Data transmit in progress interrupt + * @arg SDIO_IT_RXACT: Data receive in progress interrupt + * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt + * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt + * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt + * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt + * @retval The new state of SDIO_IT (SET or RESET). + */ +ITStatus SDIO_GetITStatus(uint32_t SDIO_IT) +{ + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_SDIO_GET_IT(SDIO_IT)); + if ((SDIO->STA & SDIO_IT) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the SDIOs interrupt pending bits. + * @param SDIO_IT: specifies the interrupt pending bit to clear. + * This parameter can be one or a combination of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 + * @retval None + */ +void SDIO_ClearITPendingBit(uint32_t SDIO_IT) +{ + /* Check the parameters */ + assert_param(IS_SDIO_CLEAR_IT(SDIO_IT)); + + SDIO->ICR = SDIO_IT; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_spi.c b/example/libs_stm/src/stm32f10x/stm32f10x_spi.c new file mode 100644 index 000000000..b1ff419d9 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_spi.c @@ -0,0 +1,907 @@ +/** + ****************************************************************************** + * @file stm32f10x_spi.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the SPI firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_spi.h" +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup SPI + * @brief SPI driver modules + * @{ + */ + +/** @defgroup SPI_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + + +/** @defgroup SPI_Private_Defines + * @{ + */ + +/* SPI SPE mask */ +#define CR1_SPE_Set ((uint16_t)0x0040) +#define CR1_SPE_Reset ((uint16_t)0xFFBF) + +/* I2S I2SE mask */ +#define I2SCFGR_I2SE_Set ((uint16_t)0x0400) +#define I2SCFGR_I2SE_Reset ((uint16_t)0xFBFF) + +/* SPI CRCNext mask */ +#define CR1_CRCNext_Set ((uint16_t)0x1000) + +/* SPI CRCEN mask */ +#define CR1_CRCEN_Set ((uint16_t)0x2000) +#define CR1_CRCEN_Reset ((uint16_t)0xDFFF) + +/* SPI SSOE mask */ +#define CR2_SSOE_Set ((uint16_t)0x0004) +#define CR2_SSOE_Reset ((uint16_t)0xFFFB) + +/* SPI registers Masks */ +#define CR1_CLEAR_Mask ((uint16_t)0x3040) +#define I2SCFGR_CLEAR_Mask ((uint16_t)0xF040) + +/* SPI or I2S mode selection masks */ +#define SPI_Mode_Select ((uint16_t)0xF7FF) +#define I2S_Mode_Select ((uint16_t)0x0800) + +/* I2S clock source selection masks */ +#define I2S2_CLOCK_SRC ((uint32_t)(0x00020000)) +#define I2S3_CLOCK_SRC ((uint32_t)(0x00040000)) +#define I2S_MUL_MASK ((uint32_t)(0x0000F000)) +#define I2S_DIV_MASK ((uint32_t)(0x000000F0)) + +/** + * @} + */ + +/** @defgroup SPI_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup SPI_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup SPI_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup SPI_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the SPIx peripheral registers to their default + * reset values (Affects also the I2Ss). + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @retval None + */ +void SPI_I2S_DeInit(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + if (SPIx == SPI1) + { + /* Enable SPI1 reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE); + /* Release SPI1 from reset state */ + RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE); + } + else if (SPIx == SPI2) + { + /* Enable SPI2 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE); + /* Release SPI2 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE); + } + else + { + if (SPIx == SPI3) + { + /* Enable SPI3 reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE); + /* Release SPI3 from reset state */ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE); + } + } +} + +/** + * @brief Initializes the SPIx peripheral according to the specified + * parameters in the SPI_InitStruct. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure that + * contains the configuration information for the specified SPI peripheral. + * @retval None + */ +void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct) +{ + uint16_t tmpreg = 0; + + /* check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Check the SPI parameters */ + assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction)); + assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode)); + assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize)); + assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL)); + assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA)); + assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS)); + assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler)); + assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit)); + assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial)); + +/*---------------------------- SPIx CR1 Configuration ------------------------*/ + /* Get the SPIx CR1 value */ + tmpreg = SPIx->CR1; + /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */ + tmpreg &= CR1_CLEAR_Mask; + /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler + master/salve mode, CPOL and CPHA */ + /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */ + /* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */ + /* Set LSBFirst bit according to SPI_FirstBit value */ + /* Set BR bits according to SPI_BaudRatePrescaler value */ + /* Set CPOL bit according to SPI_CPOL value */ + /* Set CPHA bit according to SPI_CPHA value */ + tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode | + SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL | + SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS | + SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit); + /* Write to SPIx CR1 */ + SPIx->CR1 = tmpreg; + + /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */ + SPIx->I2SCFGR &= SPI_Mode_Select; + +/*---------------------------- SPIx CRCPOLY Configuration --------------------*/ + /* Write to SPIx CRCPOLY */ + SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial; +} + +/** + * @brief Initializes the SPIx peripheral according to the specified + * parameters in the I2S_InitStruct. + * @param SPIx: where x can be 2 or 3 to select the SPI peripheral + * (configured in I2S mode). + * @param I2S_InitStruct: pointer to an I2S_InitTypeDef structure that + * contains the configuration information for the specified SPI peripheral + * configured in I2S mode. + * @note + * The function calculates the optimal prescaler needed to obtain the most + * accurate audio frequency (depending on the I2S clock source, the PLL values + * and the product configuration). But in case the prescaler value is greater + * than 511, the default value (0x02) will be configured instead. * + * @retval None + */ +void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct) +{ + uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1; + uint32_t tmp = 0; + RCC_ClocksTypeDef RCC_Clocks; + uint32_t sourceclock = 0; + + /* Check the I2S parameters */ + assert_param(IS_SPI_23_PERIPH(SPIx)); + assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode)); + assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard)); + assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat)); + assert_param(IS_I2S_MCLK_OUTPUT(I2S_InitStruct->I2S_MCLKOutput)); + assert_param(IS_I2S_AUDIO_FREQ(I2S_InitStruct->I2S_AudioFreq)); + assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL)); + +/*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/ + /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */ + SPIx->I2SCFGR &= I2SCFGR_CLEAR_Mask; + SPIx->I2SPR = 0x0002; + + /* Get the I2SCFGR register value */ + tmpreg = SPIx->I2SCFGR; + + /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/ + if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default) + { + i2sodd = (uint16_t)0; + i2sdiv = (uint16_t)2; + } + /* If the requested audio frequency is not the default, compute the prescaler */ + else + { + /* Check the frame length (For the Prescaler computing) */ + if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b) + { + /* Packet length is 16 bits */ + packetlength = 1; + } + else + { + /* Packet length is 32 bits */ + packetlength = 2; + } + + /* Get the I2S clock source mask depending on the peripheral number */ + if(((uint32_t)SPIx) == SPI2_BASE) + { + /* The mask is relative to I2S2 */ + tmp = I2S2_CLOCK_SRC; + } + else + { + /* The mask is relative to I2S3 */ + tmp = I2S3_CLOCK_SRC; + } + + /* Check the I2S clock source configuration depending on the Device: + Only Connectivity line devices have the PLL3 VCO clock */ +#ifdef STM32F10X_CL + if((RCC->CFGR2 & tmp) != 0) + { + /* Get the configuration bits of RCC PLL3 multiplier */ + tmp = (uint32_t)((RCC->CFGR2 & I2S_MUL_MASK) >> 12); + + /* Get the value of the PLL3 multiplier */ + if((tmp > 5) && (tmp < 15)) + { + /* Multplier is between 8 and 14 (value 15 is forbidden) */ + tmp += 2; + } + else + { + if (tmp == 15) + { + /* Multiplier is 20 */ + tmp = 20; + } + } + /* Get the PREDIV2 value */ + sourceclock = (uint32_t)(((RCC->CFGR2 & I2S_DIV_MASK) >> 4) + 1); + + /* Calculate the Source Clock frequency based on PLL3 and PREDIV2 values */ + sourceclock = (uint32_t) ((HSE_Value / sourceclock) * tmp * 2); + } + else + { + /* I2S Clock source is System clock: Get System Clock frequency */ + RCC_GetClocksFreq(&RCC_Clocks); + + /* Get the source clock value: based on System Clock value */ + sourceclock = RCC_Clocks.SYSCLK_Frequency; + } +#else /* STM32F10X_HD */ + /* I2S Clock source is System clock: Get System Clock frequency */ + RCC_GetClocksFreq(&RCC_Clocks); + + /* Get the source clock value: based on System Clock value */ + sourceclock = RCC_Clocks.SYSCLK_Frequency; +#endif /* STM32F10X_CL */ + + /* Compute the Real divider depending on the MCLK output state with a flaoting point */ + if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable) + { + /* MCLK output is enabled */ + tmp = (uint16_t)(((((sourceclock / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5); + } + else + { + /* MCLK output is disabled */ + tmp = (uint16_t)(((((sourceclock / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5); + } + + /* Remove the flaoting point */ + tmp = tmp / 10; + + /* Check the parity of the divider */ + i2sodd = (uint16_t)(tmp & (uint16_t)0x0001); + + /* Compute the i2sdiv prescaler */ + i2sdiv = (uint16_t)((tmp - i2sodd) / 2); + + /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */ + i2sodd = (uint16_t) (i2sodd << 8); + } + + /* Test if the divider is 1 or 0 or greater than 0xFF */ + if ((i2sdiv < 2) || (i2sdiv > 0xFF)) + { + /* Set the default values */ + i2sdiv = 2; + i2sodd = 0; + } + + /* Write to SPIx I2SPR register the computed value */ + SPIx->I2SPR = (uint16_t)(i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput)); + + /* Configure the I2S with the SPI_InitStruct values */ + tmpreg |= (uint16_t)(I2S_Mode_Select | (uint16_t)(I2S_InitStruct->I2S_Mode | \ + (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \ + (uint16_t)I2S_InitStruct->I2S_CPOL)))); + + /* Write to SPIx I2SCFGR */ + SPIx->I2SCFGR = tmpreg; +} + +/** + * @brief Fills each SPI_InitStruct member with its default value. + * @param SPI_InitStruct : pointer to a SPI_InitTypeDef structure which will be initialized. + * @retval None + */ +void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct) +{ +/*--------------- Reset SPI init structure parameters values -----------------*/ + /* Initialize the SPI_Direction member */ + SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex; + /* initialize the SPI_Mode member */ + SPI_InitStruct->SPI_Mode = SPI_Mode_Slave; + /* initialize the SPI_DataSize member */ + SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b; + /* Initialize the SPI_CPOL member */ + SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low; + /* Initialize the SPI_CPHA member */ + SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge; + /* Initialize the SPI_NSS member */ + SPI_InitStruct->SPI_NSS = SPI_NSS_Hard; + /* Initialize the SPI_BaudRatePrescaler member */ + SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; + /* Initialize the SPI_FirstBit member */ + SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB; + /* Initialize the SPI_CRCPolynomial member */ + SPI_InitStruct->SPI_CRCPolynomial = 7; +} + +/** + * @brief Fills each I2S_InitStruct member with its default value. + * @param I2S_InitStruct : pointer to a I2S_InitTypeDef structure which will be initialized. + * @retval None + */ +void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct) +{ +/*--------------- Reset I2S init structure parameters values -----------------*/ + /* Initialize the I2S_Mode member */ + I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx; + + /* Initialize the I2S_Standard member */ + I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips; + + /* Initialize the I2S_DataFormat member */ + I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b; + + /* Initialize the I2S_MCLKOutput member */ + I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable; + + /* Initialize the I2S_AudioFreq member */ + I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default; + + /* Initialize the I2S_CPOL member */ + I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low; +} + +/** + * @brief Enables or disables the specified SPI peripheral. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the SPIx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected SPI peripheral */ + SPIx->CR1 |= CR1_SPE_Set; + } + else + { + /* Disable the selected SPI peripheral */ + SPIx->CR1 &= CR1_SPE_Reset; + } +} + +/** + * @brief Enables or disables the specified SPI peripheral (in I2S mode). + * @param SPIx: where x can be 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the SPIx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_23_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected SPI peripheral (in I2S mode) */ + SPIx->I2SCFGR |= I2SCFGR_I2SE_Set; + } + else + { + /* Disable the selected SPI peripheral (in I2S mode) */ + SPIx->I2SCFGR &= I2SCFGR_I2SE_Reset; + } +} + +/** + * @brief Enables or disables the specified SPI/I2S interrupts. + * @param SPIx: where x can be + * - 1, 2 or 3 in SPI mode + * - 2 or 3 in I2S mode + * @param SPI_I2S_IT: specifies the SPI/I2S interrupt source to be enabled or disabled. + * This parameter can be one of the following values: + * @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask + * @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask + * @arg SPI_I2S_IT_ERR: Error interrupt mask + * @param NewState: new state of the specified SPI/I2S interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState) +{ + uint16_t itpos = 0, itmask = 0 ; + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT)); + + /* Get the SPI/I2S IT index */ + itpos = SPI_I2S_IT >> 4; + + /* Set the IT mask */ + itmask = (uint16_t)1 << (uint16_t)itpos; + + if (NewState != DISABLE) + { + /* Enable the selected SPI/I2S interrupt */ + SPIx->CR2 |= itmask; + } + else + { + /* Disable the selected SPI/I2S interrupt */ + SPIx->CR2 &= (uint16_t)~itmask; + } +} + +/** + * @brief Enables or disables the SPIx/I2Sx DMA interface. + * @param SPIx: where x can be + * - 1, 2 or 3 in SPI mode + * - 2 or 3 in I2S mode + * @param SPI_I2S_DMAReq: specifies the SPI/I2S DMA transfer request to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request + * @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request + * @param NewState: new state of the selected SPI/I2S DMA transfer request. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_SPI_I2S_DMAREQ(SPI_I2S_DMAReq)); + if (NewState != DISABLE) + { + /* Enable the selected SPI/I2S DMA requests */ + SPIx->CR2 |= SPI_I2S_DMAReq; + } + else + { + /* Disable the selected SPI/I2S DMA requests */ + SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq; + } +} + +/** + * @brief Transmits a Data through the SPIx/I2Sx peripheral. + * @param SPIx: where x can be + * - 1, 2 or 3 in SPI mode + * - 2 or 3 in I2S mode + * @param Data : Data to be transmitted. + * @retval None + */ +void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Write in the DR register the data to be sent */ + SPIx->DR = Data; +} + +/** + * @brief Returns the most recent received data by the SPIx/I2Sx peripheral. + * @param SPIx: where x can be + * - 1, 2 or 3 in SPI mode + * - 2 or 3 in I2S mode + * @retval The value of the received data. + */ +uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Return the data in the DR register */ + return SPIx->DR; +} + +/** + * @brief Configures internally by software the NSS pin for the selected SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_NSSInternalSoft: specifies the SPI NSS internal state. + * This parameter can be one of the following values: + * @arg SPI_NSSInternalSoft_Set: Set NSS pin internally + * @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally + * @retval None + */ +void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft)); + if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset) + { + /* Set NSS pin internally by software */ + SPIx->CR1 |= SPI_NSSInternalSoft_Set; + } + else + { + /* Reset NSS pin internally by software */ + SPIx->CR1 &= SPI_NSSInternalSoft_Reset; + } +} + +/** + * @brief Enables or disables the SS output for the selected SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the SPIx SS output. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected SPI SS output */ + SPIx->CR2 |= CR2_SSOE_Set; + } + else + { + /* Disable the selected SPI SS output */ + SPIx->CR2 &= CR2_SSOE_Reset; + } +} + +/** + * @brief Configures the data size for the selected SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_DataSize: specifies the SPI data size. + * This parameter can be one of the following values: + * @arg SPI_DataSize_16b: Set data frame format to 16bit + * @arg SPI_DataSize_8b: Set data frame format to 8bit + * @retval None + */ +void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_DATASIZE(SPI_DataSize)); + /* Clear DFF bit */ + SPIx->CR1 &= (uint16_t)~SPI_DataSize_16b; + /* Set new DFF bit value */ + SPIx->CR1 |= SPI_DataSize; +} + +/** + * @brief Transmit the SPIx CRC value. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @retval None + */ +void SPI_TransmitCRC(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Enable the selected SPI CRC transmission */ + SPIx->CR1 |= CR1_CRCNext_Set; +} + +/** + * @brief Enables or disables the CRC value calculation of the transfered bytes. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param NewState: new state of the SPIx CRC value calculation. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the selected SPI CRC calculation */ + SPIx->CR1 |= CR1_CRCEN_Set; + } + else + { + /* Disable the selected SPI CRC calculation */ + SPIx->CR1 &= CR1_CRCEN_Reset; + } +} + +/** + * @brief Returns the transmit or the receive CRC register value for the specified SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_CRC: specifies the CRC register to be read. + * This parameter can be one of the following values: + * @arg SPI_CRC_Tx: Selects Tx CRC register + * @arg SPI_CRC_Rx: Selects Rx CRC register + * @retval The selected CRC register value.. + */ +uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC) +{ + uint16_t crcreg = 0; + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_CRC(SPI_CRC)); + if (SPI_CRC != SPI_CRC_Rx) + { + /* Get the Tx CRC register */ + crcreg = SPIx->TXCRCR; + } + else + { + /* Get the Rx CRC register */ + crcreg = SPIx->RXCRCR; + } + /* Return the selected CRC register */ + return crcreg; +} + +/** + * @brief Returns the CRC Polynomial register value for the specified SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @retval The CRC Polynomial register value. + */ +uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Return the CRC polynomial register */ + return SPIx->CRCPR; +} + +/** + * @brief Selects the data transfer direction in bi-directional mode for the specified SPI. + * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. + * @param SPI_Direction: specifies the data transfer direction in bi-directional mode. + * This parameter can be one of the following values: + * @arg SPI_Direction_Tx: Selects Tx transmission direction + * @arg SPI_Direction_Rx: Selects Rx receive direction + * @retval None + */ +void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_DIRECTION(SPI_Direction)); + if (SPI_Direction == SPI_Direction_Tx) + { + /* Set the Tx only mode */ + SPIx->CR1 |= SPI_Direction_Tx; + } + else + { + /* Set the Rx only mode */ + SPIx->CR1 &= SPI_Direction_Rx; + } +} + +/** + * @brief Checks whether the specified SPI/I2S flag is set or not. + * @param SPIx: where x can be + * - 1, 2 or 3 in SPI mode + * - 2 or 3 in I2S mode + * @param SPI_I2S_FLAG: specifies the SPI/I2S flag to check. + * This parameter can be one of the following values: + * @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag. + * @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag. + * @arg SPI_I2S_FLAG_BSY: Busy flag. + * @arg SPI_I2S_FLAG_OVR: Overrun flag. + * @arg SPI_FLAG_MODF: Mode Fault flag. + * @arg SPI_FLAG_CRCERR: CRC Error flag. + * @arg I2S_FLAG_UDR: Underrun Error flag. + * @arg I2S_FLAG_CHSIDE: Channel Side flag. + * @retval The new state of SPI_I2S_FLAG (SET or RESET). + */ +FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG)); + /* Check the status of the specified SPI/I2S flag */ + if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET) + { + /* SPI_I2S_FLAG is set */ + bitstatus = SET; + } + else + { + /* SPI_I2S_FLAG is reset */ + bitstatus = RESET; + } + /* Return the SPI_I2S_FLAG status */ + return bitstatus; +} + +/** + * @brief Clears the SPIx CRC Error (CRCERR) flag. + * @param SPIx: where x can be + * - 1, 2 or 3 in SPI mode + * @param SPI_I2S_FLAG: specifies the SPI flag to clear. + * This function clears only CRCERR flag. + * @note + * - OVR (OverRun error) flag is cleared by software sequence: a read + * operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by a read + * operation to SPI_SR register (SPI_I2S_GetFlagStatus()). + * - UDR (UnderRun error) flag is cleared by a read operation to + * SPI_SR register (SPI_I2S_GetFlagStatus()). + * - MODF (Mode Fault) flag is cleared by software sequence: a read/write + * operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by a + * write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI). + * @retval None + */ +void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_I2S_CLEAR_FLAG(SPI_I2S_FLAG)); + + /* Clear the selected SPI CRC Error (CRCERR) flag */ + SPIx->SR = (uint16_t)~SPI_I2S_FLAG; +} + +/** + * @brief Checks whether the specified SPI/I2S interrupt has occurred or not. + * @param SPIx: where x can be + * - 1, 2 or 3 in SPI mode + * - 2 or 3 in I2S mode + * @param SPI_I2S_IT: specifies the SPI/I2S interrupt source to check. + * This parameter can be one of the following values: + * @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt. + * @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt. + * @arg SPI_I2S_IT_OVR: Overrun interrupt. + * @arg SPI_IT_MODF: Mode Fault interrupt. + * @arg SPI_IT_CRCERR: CRC Error interrupt. + * @arg I2S_IT_UDR: Underrun Error interrupt. + * @retval The new state of SPI_I2S_IT (SET or RESET). + */ +ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT) +{ + ITStatus bitstatus = RESET; + uint16_t itpos = 0, itmask = 0, enablestatus = 0; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT)); + + /* Get the SPI/I2S IT index */ + itpos = 0x01 << (SPI_I2S_IT & 0x0F); + + /* Get the SPI/I2S IT mask */ + itmask = SPI_I2S_IT >> 4; + + /* Set the IT mask */ + itmask = 0x01 << itmask; + + /* Get the SPI_I2S_IT enable bit status */ + enablestatus = (SPIx->CR2 & itmask) ; + + /* Check the status of the specified SPI/I2S interrupt */ + if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus) + { + /* SPI_I2S_IT is set */ + bitstatus = SET; + } + else + { + /* SPI_I2S_IT is reset */ + bitstatus = RESET; + } + /* Return the SPI_I2S_IT status */ + return bitstatus; +} + +/** + * @brief Clears the SPIx CRC Error (CRCERR) interrupt pending bit. + * @param SPIx: where x can be + * - 1, 2 or 3 in SPI mode + * @param SPI_I2S_IT: specifies the SPI interrupt pending bit to clear. + * This function clears only CRCERR intetrrupt pending bit. + * @note + * - OVR (OverRun Error) interrupt pending bit is cleared by software + * sequence: a read operation to SPI_DR register (SPI_I2S_ReceiveData()) + * followed by a read operation to SPI_SR register (SPI_I2S_GetITStatus()). + * - UDR (UnderRun Error) interrupt pending bit is cleared by a read + * operation to SPI_SR register (SPI_I2S_GetITStatus()). + * - MODF (Mode Fault) interrupt pending bit is cleared by software sequence: + * a read/write operation to SPI_SR register (SPI_I2S_GetITStatus()) + * followed by a write operation to SPI_CR1 register (SPI_Cmd() to enable + * the SPI). + * @retval None + */ +void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT) +{ + uint16_t itpos = 0; + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_I2S_CLEAR_IT(SPI_I2S_IT)); + + /* Get the SPI IT index */ + itpos = 0x01 << (SPI_I2S_IT & 0x0F); + + /* Clear the selected SPI CRC Error (CRCERR) interrupt pending bit */ + SPIx->SR = (uint16_t)~itpos; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_tim.c b/example/libs_stm/src/stm32f10x/stm32f10x_tim.c new file mode 100644 index 000000000..c626dca35 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_tim.c @@ -0,0 +1,2834 @@ +/** + ****************************************************************************** + * @file stm32f10x_tim.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the TIM firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_tim.h" +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup TIM + * @brief TIM driver modules + * @{ + */ + +/** @defgroup TIM_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup TIM_Private_Defines + * @{ + */ + +/* ---------------------- TIM registers bit mask ------------------------ */ +#define SMCR_ETR_Mask ((uint16_t)0x00FF) +#define CCMR_Offset ((uint16_t)0x0018) +#define CCER_CCE_Set ((uint16_t)0x0001) +#define CCER_CCNE_Set ((uint16_t)0x0004) + +/** + * @} + */ + +/** @defgroup TIM_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup TIM_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup TIM_Private_FunctionPrototypes + * @{ + */ + +static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); +static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); +static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); +static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); +/** + * @} + */ + +/** @defgroup TIM_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup TIM_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup TIM_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup TIM_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the TIMx peripheral registers to their default reset values. + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @retval None + */ +void TIM_DeInit(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + if (TIMx == TIM1) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, DISABLE); + } + else if (TIMx == TIM2) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, DISABLE); + } + else if (TIMx == TIM3) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, DISABLE); + } + else if (TIMx == TIM4) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, DISABLE); + } + else if (TIMx == TIM5) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, DISABLE); + } + else if (TIMx == TIM6) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, DISABLE); + } + else if (TIMx == TIM7) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, DISABLE); + } + else if (TIMx == TIM8) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, DISABLE); + } + else if (TIMx == TIM9) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, DISABLE); + } + else if (TIMx == TIM10) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, DISABLE); + } + else if (TIMx == TIM11) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, DISABLE); + } + else if (TIMx == TIM12) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, DISABLE); + } + else if (TIMx == TIM13) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, DISABLE); + } + else if (TIMx == TIM14) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, DISABLE); + } + else if (TIMx == TIM15) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM15, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM15, DISABLE); + } + else if (TIMx == TIM16) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM16, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM16, DISABLE); + } + else + { + if (TIMx == TIM17) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM17, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM17, DISABLE); + } + } +} + +/** + * @brief Initializes the TIMx Time Base Unit peripheral according to + * the specified parameters in the TIM_TimeBaseInitStruct. + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef + * structure that contains the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) +{ + uint16_t tmpcr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode)); + assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision)); + + tmpcr1 = TIMx->CR1; + + if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM2) || (TIMx == TIM3)|| + (TIMx == TIM4) || (TIMx == TIM5)) + { + /* Select the Counter Mode */ + tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS))); + tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode; + } + + if((TIMx != TIM6) && (TIMx != TIM7)) + { + /* Set the clock division */ + tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD)); + tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision; + } + + TIMx->CR1 = tmpcr1; + + /* Set the Autoreload value */ + TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ; + + /* Set the Prescaler value */ + TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler; + + if ((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM15)|| (TIMx == TIM16) || (TIMx == TIM17)) + { + /* Set the Repetition Counter value */ + TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter; + } + + /* Generate an update event to reload the Prescaler and the Repetition counter + values immediately */ + TIMx->EGR = TIM_PSCReloadMode_Immediate; +} + +/** + * @brief Initializes the TIMx Channel1 according to the specified + * parameters in the TIM_OCInitStruct. + * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure + * that contains the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST8_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= (uint16_t)(~(uint16_t)TIM_CCER_CC1E); + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare Mode Bits */ + tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_OC1M)); + tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_CC1S)); + + /* Select the Output Compare Mode */ + tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1P)); + /* Set the Output Compare Polarity */ + tmpccer |= TIM_OCInitStruct->TIM_OCPolarity; + + /* Set the Output State */ + tmpccer |= TIM_OCInitStruct->TIM_OutputState; + + if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM15)|| + (TIMx == TIM16)|| (TIMx == TIM17)) + { + assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Output N Polarity level */ + tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1NP)); + /* Set the Output N Polarity */ + tmpccer |= TIM_OCInitStruct->TIM_OCNPolarity; + + /* Reset the Output N State */ + tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1NE)); + /* Set the Output N State */ + tmpccer |= TIM_OCInitStruct->TIM_OutputNState; + + /* Reset the Ouput Compare and Output Compare N IDLE State */ + tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS1)); + tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS1N)); + + /* Set the Output Idle state */ + tmpcr2 |= TIM_OCInitStruct->TIM_OCIdleState; + /* Set the Output N Idle state */ + tmpcr2 |= TIM_OCInitStruct->TIM_OCNIdleState; + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR1 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel2 according to the specified + * parameters in the TIM_OCInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select + * the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure + * that contains the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC2E)); + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_OC2M)); + tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S)); + + /* Select the Output Compare Mode */ + tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8); + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2P)); + /* Set the Output Compare Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 4); + + /* Set the Output State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 4); + + if((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Output N Polarity level */ + tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2NP)); + /* Set the Output N Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 4); + + /* Reset the Output N State */ + tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2NE)); + /* Set the Output N State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 4); + + /* Reset the Ouput Compare and Output Compare N IDLE State */ + tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS2)); + tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS2N)); + + /* Set the Output Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 2); + /* Set the Output N Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 2); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR2 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel3 according to the specified + * parameters in the TIM_OCInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure + * that contains the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC3E)); + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_OC3M)); + tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_CC3S)); + /* Select the Output Compare Mode */ + tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3P)); + /* Set the Output Compare Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 8); + + /* Set the Output State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 8); + + if((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Output N Polarity level */ + tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3NP)); + /* Set the Output N Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 8); + /* Reset the Output N State */ + tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3NE)); + + /* Set the Output N State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 8); + /* Reset the Ouput Compare and Output Compare N IDLE State */ + tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS3)); + tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS3N)); + /* Set the Output Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 4); + /* Set the Output N Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 4); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel4 according to the specified + * parameters in the TIM_OCInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure + * that contains the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + /* Disable the Channel 2: Reset the CC4E Bit */ + TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC4E)); + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_OC4M)); + tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_CC4S)); + + /* Select the Output Compare Mode */ + tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8); + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC4P)); + /* Set the Output Compare Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 12); + + /* Set the Output State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 12); + + if((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + /* Reset the Ouput Compare IDLE State */ + tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS4)); + /* Set the Output Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 6); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR4 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIM peripheral according to the specified + * parameters in the TIM_ICInitStruct. + * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. + * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure + * that contains the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_CHANNEL(TIM_ICInitStruct->TIM_Channel)); + assert_param(IS_TIM_IC_POLARITY(TIM_ICInitStruct->TIM_ICPolarity)); + assert_param(IS_TIM_IC_SELECTION(TIM_ICInitStruct->TIM_ICSelection)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICInitStruct->TIM_ICPrescaler)); + assert_param(IS_TIM_IC_FILTER(TIM_ICInitStruct->TIM_ICFilter)); + + if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) + { + assert_param(IS_TIM_LIST8_PERIPH(TIMx)); + /* TI1 Configuration */ + TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_2) + { + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + /* TI2 Configuration */ + TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_3) + { + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + /* TI3 Configuration */ + TI3_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC3Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else + { + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + /* TI4 Configuration */ + TI4_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC4Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } +} + +/** + * @brief Configures the TIM peripheral according to the specified + * parameters in the TIM_ICInitStruct to measure an external PWM signal. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. + * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure + * that contains the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + uint16_t icoppositepolarity = TIM_ICPolarity_Rising; + uint16_t icoppositeselection = TIM_ICSelection_DirectTI; + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + /* Select the Opposite Input Polarity */ + if (TIM_ICInitStruct->TIM_ICPolarity == TIM_ICPolarity_Rising) + { + icoppositepolarity = TIM_ICPolarity_Falling; + } + else + { + icoppositepolarity = TIM_ICPolarity_Rising; + } + /* Select the Opposite Input */ + if (TIM_ICInitStruct->TIM_ICSelection == TIM_ICSelection_DirectTI) + { + icoppositeselection = TIM_ICSelection_IndirectTI; + } + else + { + icoppositeselection = TIM_ICSelection_DirectTI; + } + if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) + { + /* TI1 Configuration */ + TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + /* TI2 Configuration */ + TI2_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else + { + /* TI2 Configuration */ + TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + /* TI1 Configuration */ + TI1_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } +} + +/** + * @brief Configures the: Break feature, dead time, Lock level, the OSSI, + * the OSSR State and the AOE(automatic output enable). + * @param TIMx: where x can be 1 or 8 to select the TIM + * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure that + * contains the BDTR Register configuration information for the TIM peripheral. + * @retval None + */ +void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OSSR_STATE(TIM_BDTRInitStruct->TIM_OSSRState)); + assert_param(IS_TIM_OSSI_STATE(TIM_BDTRInitStruct->TIM_OSSIState)); + assert_param(IS_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->TIM_LOCKLevel)); + assert_param(IS_TIM_BREAK_STATE(TIM_BDTRInitStruct->TIM_Break)); + assert_param(IS_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->TIM_BreakPolarity)); + assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->TIM_AutomaticOutput)); + /* Set the Lock level, the Break enable Bit and the Ploarity, the OSSR State, + the OSSI State, the dead time value and the Automatic Output Enable Bit */ + TIMx->BDTR = (uint32_t)TIM_BDTRInitStruct->TIM_OSSRState | TIM_BDTRInitStruct->TIM_OSSIState | + TIM_BDTRInitStruct->TIM_LOCKLevel | TIM_BDTRInitStruct->TIM_DeadTime | + TIM_BDTRInitStruct->TIM_Break | TIM_BDTRInitStruct->TIM_BreakPolarity | + TIM_BDTRInitStruct->TIM_AutomaticOutput; +} + +/** + * @brief Fills each TIM_TimeBaseInitStruct member with its default value. + * @param TIM_TimeBaseInitStruct : pointer to a TIM_TimeBaseInitTypeDef + * structure which will be initialized. + * @retval None + */ +void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) +{ + /* Set the default configuration */ + TIM_TimeBaseInitStruct->TIM_Period = 0xFFFF; + TIM_TimeBaseInitStruct->TIM_Prescaler = 0x0000; + TIM_TimeBaseInitStruct->TIM_ClockDivision = TIM_CKD_DIV1; + TIM_TimeBaseInitStruct->TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInitStruct->TIM_RepetitionCounter = 0x0000; +} + +/** + * @brief Fills each TIM_OCInitStruct member with its default value. + * @param TIM_OCInitStruct : pointer to a TIM_OCInitTypeDef structure which will + * be initialized. + * @retval None + */ +void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + /* Set the default configuration */ + TIM_OCInitStruct->TIM_OCMode = TIM_OCMode_Timing; + TIM_OCInitStruct->TIM_OutputState = TIM_OutputState_Disable; + TIM_OCInitStruct->TIM_OutputNState = TIM_OutputNState_Disable; + TIM_OCInitStruct->TIM_Pulse = 0x0000; + TIM_OCInitStruct->TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct->TIM_OCNPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct->TIM_OCIdleState = TIM_OCIdleState_Reset; + TIM_OCInitStruct->TIM_OCNIdleState = TIM_OCNIdleState_Reset; +} + +/** + * @brief Fills each TIM_ICInitStruct member with its default value. + * @param TIM_ICInitStruct : pointer to a TIM_ICInitTypeDef structure which will + * be initialized. + * @retval None + */ +void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + /* Set the default configuration */ + TIM_ICInitStruct->TIM_Channel = TIM_Channel_1; + TIM_ICInitStruct->TIM_ICPolarity = TIM_ICPolarity_Rising; + TIM_ICInitStruct->TIM_ICSelection = TIM_ICSelection_DirectTI; + TIM_ICInitStruct->TIM_ICPrescaler = TIM_ICPSC_DIV1; + TIM_ICInitStruct->TIM_ICFilter = 0x00; +} + +/** + * @brief Fills each TIM_BDTRInitStruct member with its default value. + * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure which + * will be initialized. + * @retval None + */ +void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct) +{ + /* Set the default configuration */ + TIM_BDTRInitStruct->TIM_OSSRState = TIM_OSSRState_Disable; + TIM_BDTRInitStruct->TIM_OSSIState = TIM_OSSIState_Disable; + TIM_BDTRInitStruct->TIM_LOCKLevel = TIM_LOCKLevel_OFF; + TIM_BDTRInitStruct->TIM_DeadTime = 0x00; + TIM_BDTRInitStruct->TIM_Break = TIM_Break_Disable; + TIM_BDTRInitStruct->TIM_BreakPolarity = TIM_BreakPolarity_Low; + TIM_BDTRInitStruct->TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; +} + +/** + * @brief Enables or disables the specified TIM peripheral. + * @param TIMx: where x can be 1 to 17 to select the TIMx peripheral. + * @param NewState: new state of the TIMx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the TIM Counter */ + TIMx->CR1 |= TIM_CR1_CEN; + } + else + { + /* Disable the TIM Counter */ + TIMx->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN)); + } +} + +/** + * @brief Enables or disables the TIM peripheral Main Outputs. + * @param TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIMx peripheral. + * @param NewState: new state of the TIM peripheral Main Outputs. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the TIM Main Output */ + TIMx->BDTR |= TIM_BDTR_MOE; + } + else + { + /* Disable the TIM Main Output */ + TIMx->BDTR &= (uint16_t)(~((uint16_t)TIM_BDTR_MOE)); + } +} + +/** + * @brief Enables or disables the specified TIM interrupts. + * @param TIMx: where x can be 1 to 17 to select the TIMx peripheral. + * @param TIM_IT: specifies the TIM interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * @note + * - TIM6 and TIM7 can only generate an update interrupt. + * - TIM9, TIM12 and TIM15 can have only TIM_IT_Update, TIM_IT_CC1, + * TIM_IT_CC2 or TIM_IT_Trigger. + * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1. + * - TIM_IT_Break is used only with TIM1, TIM8 and TIM15. + * - TIM_IT_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17. + * @param NewState: new state of the TIM interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_IT(TIM_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Interrupt sources */ + TIMx->DIER |= TIM_IT; + } + else + { + /* Disable the Interrupt sources */ + TIMx->DIER &= (uint16_t)~TIM_IT; + } +} + +/** + * @brief Configures the TIMx event to be generate by software. + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @param TIM_EventSource: specifies the event source. + * This parameter can be one or more of the following values: + * @arg TIM_EventSource_Update: Timer update Event source + * @arg TIM_EventSource_CC1: Timer Capture Compare 1 Event source + * @arg TIM_EventSource_CC2: Timer Capture Compare 2 Event source + * @arg TIM_EventSource_CC3: Timer Capture Compare 3 Event source + * @arg TIM_EventSource_CC4: Timer Capture Compare 4 Event source + * @arg TIM_EventSource_COM: Timer COM event source + * @arg TIM_EventSource_Trigger: Timer Trigger Event source + * @arg TIM_EventSource_Break: Timer Break event source + * @note + * - TIM6 and TIM7 can only generate an update event. + * - TIM_EventSource_COM and TIM_EventSource_Break are used only with TIM1 and TIM8. + * @retval None + */ +void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_EVENT_SOURCE(TIM_EventSource)); + + /* Set the event sources */ + TIMx->EGR = TIM_EventSource; +} + +/** + * @brief Configures the TIMxs DMA interface. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 15, 16 or 17 to select + * the TIM peripheral. + * @param TIM_DMABase: DMA Base address. + * This parameter can be one of the following values: + * @arg TIM_DMABase_CR, TIM_DMABase_CR2, TIM_DMABase_SMCR, + * TIM_DMABase_DIER, TIM1_DMABase_SR, TIM_DMABase_EGR, + * TIM_DMABase_CCMR1, TIM_DMABase_CCMR2, TIM_DMABase_CCER, + * TIM_DMABase_CNT, TIM_DMABase_PSC, TIM_DMABase_ARR, + * TIM_DMABase_RCR, TIM_DMABase_CCR1, TIM_DMABase_CCR2, + * TIM_DMABase_CCR3, TIM_DMABase_CCR4, TIM_DMABase_BDTR, + * TIM_DMABase_DCR. + * @param TIM_DMABurstLength: DMA Burst length. + * This parameter can be one value between: + * TIM_DMABurstLength_1Byte and TIM_DMABurstLength_18Bytes. + * @retval None + */ +void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_DMA_BASE(TIM_DMABase)); + assert_param(IS_TIM_DMA_LENGTH(TIM_DMABurstLength)); + /* Set the DMA Base and the DMA Burst Length */ + TIMx->DCR = TIM_DMABase | TIM_DMABurstLength; +} + +/** + * @brief Enables or disables the TIMxs DMA Requests. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 15, 16 or 17 + * to select the TIM peripheral. + * @param TIM_DMASource: specifies the DMA Request sources. + * This parameter can be any combination of the following values: + * @arg TIM_DMA_Update: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_Trigger: TIM Trigger DMA source + * @param NewState: new state of the DMA Request sources. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST9_PERIPH(TIMx)); + assert_param(IS_TIM_DMA_SOURCE(TIM_DMASource)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DMA sources */ + TIMx->DIER |= TIM_DMASource; + } + else + { + /* Disable the DMA sources */ + TIMx->DIER &= (uint16_t)~TIM_DMASource; + } +} + +/** + * @brief Configures the TIMx interrnal Clock + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 + * to select the TIM peripheral. + * @retval None + */ +void TIM_InternalClockConfig(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + /* Disable slave mode to clock the prescaler directly with the internal clock */ + TIMx->SMCR &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS)); +} + +/** + * @brief Configures the TIMx Internal Trigger as External Clock + * @param TIMx: where x can be 1, 2, 3, 4, 5, 9, 12 or 15 to select the TIM peripheral. + * @param TIM_ITRSource: Trigger source. + * This parameter can be one of the following values: + * @param TIM_TS_ITR0: Internal Trigger 0 + * @param TIM_TS_ITR1: Internal Trigger 1 + * @param TIM_TS_ITR2: Internal Trigger 2 + * @param TIM_TS_ITR3: Internal Trigger 3 + * @retval None + */ +void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_INTERNAL_TRIGGER_SELECTION(TIM_InputTriggerSource)); + /* Select the Internal Trigger */ + TIM_SelectInputTrigger(TIMx, TIM_InputTriggerSource); + /* Select the External clock mode1 */ + TIMx->SMCR |= TIM_SlaveMode_External1; +} + +/** + * @brief Configures the TIMx Trigger as External Clock + * @param TIMx: where x can be 1, 2, 3, 4, 5, 9, 12 or 15 to select the TIM peripheral. + * @param TIM_TIxExternalCLKSource: Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TIxExternalCLK1Source_TI1ED: TI1 Edge Detector + * @arg TIM_TIxExternalCLK1Source_TI1: Filtered Timer Input 1 + * @arg TIM_TIxExternalCLK1Source_TI2: Filtered Timer Input 2 + * @param TIM_ICPolarity: specifies the TIx Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @param ICFilter : specifies the filter value. + * This parameter must be a value between 0x0 and 0xF. + * @retval None + */ +void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, + uint16_t TIM_ICPolarity, uint16_t ICFilter) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_TIXCLK_SOURCE(TIM_TIxExternalCLKSource)); + assert_param(IS_TIM_IC_POLARITY(TIM_ICPolarity)); + assert_param(IS_TIM_IC_FILTER(ICFilter)); + /* Configure the Timer Input Clock Source */ + if (TIM_TIxExternalCLKSource == TIM_TIxExternalCLK1Source_TI2) + { + TI2_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); + } + else + { + TI1_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); + } + /* Select the Trigger source */ + TIM_SelectInputTrigger(TIMx, TIM_TIxExternalCLKSource); + /* Select the External clock mode1 */ + TIMx->SMCR |= TIM_SlaveMode_External1; +} + +/** + * @brief Configures the External clock Mode1 + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter) +{ + uint16_t tmpsmcr = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + /* Configure the ETR Clock source */ + TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + /* Reset the SMS Bits */ + tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS)); + /* Select the External clock mode1 */ + tmpsmcr |= TIM_SlaveMode_External1; + /* Select the Trigger selection : ETRF */ + tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS)); + tmpsmcr |= TIM_TS_ETRF; + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Configures the External clock Mode2 + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, + uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + /* Configure the ETR Clock source */ + TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + /* Enable the External clock mode2 */ + TIMx->SMCR |= TIM_SMCR_ECE; +} + +/** + * @brief Configures the TIMx External Trigger (ETR). + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter) +{ + uint16_t tmpsmcr = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + tmpsmcr = TIMx->SMCR; + /* Reset the ETR Bits */ + tmpsmcr &= SMCR_ETR_Mask; + /* Set the Prescaler, the Filter value and the Polarity */ + tmpsmcr |= (uint16_t)(TIM_ExtTRGPrescaler | (uint16_t)(TIM_ExtTRGPolarity | (uint16_t)(ExtTRGFilter << (uint16_t)8))); + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Configures the TIMx Prescaler. + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @param Prescaler: specifies the Prescaler Register value + * @param TIM_PSCReloadMode: specifies the TIM Prescaler Reload mode + * This parameter can be one of the following values: + * @arg TIM_PSCReloadMode_Update: The Prescaler is loaded at the update event. + * @arg TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediately. + * @retval None + */ +void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_PRESCALER_RELOAD(TIM_PSCReloadMode)); + /* Set the Prescaler value */ + TIMx->PSC = Prescaler; + /* Set or reset the UG Bit */ + TIMx->EGR = TIM_PSCReloadMode; +} + +/** + * @brief Specifies the TIMx Counter Mode to be used. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_CounterMode: specifies the Counter Mode to be used + * This parameter can be one of the following values: + * @arg TIM_CounterMode_Up: TIM Up Counting Mode + * @arg TIM_CounterMode_Down: TIM Down Counting Mode + * @arg TIM_CounterMode_CenterAligned1: TIM Center Aligned Mode1 + * @arg TIM_CounterMode_CenterAligned2: TIM Center Aligned Mode2 + * @arg TIM_CounterMode_CenterAligned3: TIM Center Aligned Mode3 + * @retval None + */ +void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode) +{ + uint16_t tmpcr1 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_COUNTER_MODE(TIM_CounterMode)); + tmpcr1 = TIMx->CR1; + /* Reset the CMS and DIR Bits */ + tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS))); + /* Set the Counter Mode */ + tmpcr1 |= TIM_CounterMode; + /* Write to TIMx CR1 register */ + TIMx->CR1 = tmpcr1; +} + +/** + * @brief Selects the Input Trigger source + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. + * @param TIM_InputTriggerSource: The Input Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal Trigger 0 + * @arg TIM_TS_ITR1: Internal Trigger 1 + * @arg TIM_TS_ITR2: Internal Trigger 2 + * @arg TIM_TS_ITR3: Internal Trigger 3 + * @arg TIM_TS_TI1F_ED: TI1 Edge Detector + * @arg TIM_TS_TI1FP1: Filtered Timer Input 1 + * @arg TIM_TS_TI2FP2: Filtered Timer Input 2 + * @arg TIM_TS_ETRF: External Trigger input + * @retval None + */ +void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource) +{ + uint16_t tmpsmcr = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_TRIGGER_SELECTION(TIM_InputTriggerSource)); + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + /* Reset the TS Bits */ + tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS)); + /* Set the Input Trigger source */ + tmpsmcr |= TIM_InputTriggerSource; + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Configures the TIMx Encoder Interface. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_EncoderMode: specifies the TIMx Encoder Mode. + * This parameter can be one of the following values: + * @arg TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level. + * @arg TIM_EncoderMode_TI2: Counter counts on TI2FP2 edge depending on TI1FP1 level. + * @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending + * on the level of the other input. + * @param TIM_IC1Polarity: specifies the IC1 Polarity + * This parmeter can be one of the following values: + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @param TIM_IC2Polarity: specifies the IC2 Polarity + * This parmeter can be one of the following values: + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @retval None + */ +void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, + uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity) +{ + uint16_t tmpsmcr = 0; + uint16_t tmpccmr1 = 0; + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_ENCODER_MODE(TIM_EncoderMode)); + assert_param(IS_TIM_IC_POLARITY(TIM_IC1Polarity)); + assert_param(IS_TIM_IC_POLARITY(TIM_IC2Polarity)); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Set the encoder Mode */ + tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS)); + tmpsmcr |= TIM_EncoderMode; + + /* Select the Capture Compare 1 and the Capture Compare 2 as input */ + tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S))); + tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0; + + /* Set the TI1 and the TI2 Polarities */ + tmpccer &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCER_CC1P)) & ((uint16_t)~((uint16_t)TIM_CCER_CC2P))); + tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4)); + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Forces the TIMx output 1 waveform to active or inactive level. + * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC1REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC1REF. + * @retval None + */ +void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr1 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST8_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC1M Bits */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1M); + /* Configure The Forced output Mode */ + tmpccmr1 |= TIM_ForcedAction; + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Forces the TIMx output 2 waveform to active or inactive level. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC2REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC2REF. + * @retval None + */ +void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr1 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC2M Bits */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2M); + /* Configure The Forced output Mode */ + tmpccmr1 |= (uint16_t)(TIM_ForcedAction << 8); + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Forces the TIMx output 3 waveform to active or inactive level. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC3REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC3REF. + * @retval None + */ +void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr2 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC1M Bits */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3M); + /* Configure The Forced output Mode */ + tmpccmr2 |= TIM_ForcedAction; + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Forces the TIMx output 4 waveform to active or inactive level. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC4REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC4REF. + * @retval None + */ +void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr2 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC2M Bits */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4M); + /* Configure The Forced output Mode */ + tmpccmr2 |= (uint16_t)(TIM_ForcedAction << 8); + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Enables or disables TIMx peripheral Preload register on ARR. + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @param NewState: new state of the TIMx peripheral Preload register + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Set the ARR Preload Bit */ + TIMx->CR1 |= TIM_CR1_ARPE; + } + else + { + /* Reset the ARR Preload Bit */ + TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_ARPE); + } +} + +/** + * @brief Selects the TIM peripheral Commutation event. + * @param TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIMx peripheral + * @param NewState: new state of the Commutation event. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Set the COM Bit */ + TIMx->CR2 |= TIM_CR2_CCUS; + } + else + { + /* Reset the COM Bit */ + TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCUS); + } +} + +/** + * @brief Selects the TIMx peripheral Capture Compare DMA source. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 15, 16 or 17 to select + * the TIM peripheral. + * @param NewState: new state of the Capture Compare DMA source + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Set the CCDS Bit */ + TIMx->CR2 |= TIM_CR2_CCDS; + } + else + { + /* Reset the CCDS Bit */ + TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCDS); + } +} + +/** + * @brief Sets or Resets the TIM peripheral Capture Compare Preload Control bit. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8 or 15 + * to select the TIMx peripheral + * @param NewState: new state of the Capture Compare Preload Control bit + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Set the CCPC Bit */ + TIMx->CR2 |= TIM_CR2_CCPC; + } + else + { + /* Reset the CCPC Bit */ + TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCPC); + } +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR1. + * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr1 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST8_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC1PE Bit */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1PE); + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr1 |= TIM_OCPreload; + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR2. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select + * the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr1 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC2PE Bit */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2PE); + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr1 |= (uint16_t)(TIM_OCPreload << 8); + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR3. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr2 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC3PE Bit */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3PE); + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr2 |= TIM_OCPreload; + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR4. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr2 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC4PE Bit */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4PE); + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr2 |= (uint16_t)(TIM_OCPreload << 8); + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Configures the TIMx Output Compare 1 Fast feature. + * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr1 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST8_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC1FE Bit */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1FE); + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr1 |= TIM_OCFast; + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Configures the TIMx Output Compare 2 Fast feature. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select + * the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr1 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC2FE Bit */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2FE); + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr1 |= (uint16_t)(TIM_OCFast << 8); + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Configures the TIMx Output Compare 3 Fast feature. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr2 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC3FE Bit */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3FE); + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr2 |= TIM_OCFast; + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Configures the TIMx Output Compare 4 Fast feature. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr2 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC4FE Bit */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4FE); + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr2 |= (uint16_t)(TIM_OCFast << 8); + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Clears or safeguards the OCREF1 signal on an external event + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr1 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC1CE Bit */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1CE); + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr1 |= TIM_OCClear; + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Clears or safeguards the OCREF2 signal on an external event + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr1 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + tmpccmr1 = TIMx->CCMR1; + /* Reset the OC2CE Bit */ + tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2CE); + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr1 |= (uint16_t)(TIM_OCClear << 8); + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Clears or safeguards the OCREF3 signal on an external event + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr2 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC3CE Bit */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3CE); + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr2 |= TIM_OCClear; + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Clears or safeguards the OCREF4 signal on an external event + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr2 = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + tmpccmr2 = TIMx->CCMR2; + /* Reset the OC4CE Bit */ + tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4CE); + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr2 |= (uint16_t)(TIM_OCClear << 8); + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Configures the TIMx channel 1 polarity. + * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC1 Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST8_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + tmpccer = TIMx->CCER; + /* Set or Reset the CC1P Bit */ + tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC1P); + tmpccer |= TIM_OCPolarity; + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx Channel 1N polarity. + * @param TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIM peripheral. + * @param TIM_OCNPolarity: specifies the OC1N Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) +{ + uint16_t tmpccer = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); + + tmpccer = TIMx->CCER; + /* Set or Reset the CC1NP Bit */ + tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC1NP); + tmpccer |= TIM_OCNPolarity; + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 2 polarity. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC2 Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + tmpccer = TIMx->CCER; + /* Set or Reset the CC2P Bit */ + tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC2P); + tmpccer |= (uint16_t)(TIM_OCPolarity << 4); + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx Channel 2N polarity. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCNPolarity: specifies the OC2N Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) +{ + uint16_t tmpccer = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); + + tmpccer = TIMx->CCER; + /* Set or Reset the CC2NP Bit */ + tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC2NP); + tmpccer |= (uint16_t)(TIM_OCNPolarity << 4); + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 3 polarity. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC3 Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + tmpccer = TIMx->CCER; + /* Set or Reset the CC3P Bit */ + tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC3P); + tmpccer |= (uint16_t)(TIM_OCPolarity << 8); + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx Channel 3N polarity. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCNPolarity: specifies the OC3N Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); + + tmpccer = TIMx->CCER; + /* Set or Reset the CC3NP Bit */ + tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC3NP); + tmpccer |= (uint16_t)(TIM_OCNPolarity << 8); + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 4 polarity. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC4 Polarity + * This parmeter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + tmpccer = TIMx->CCER; + /* Set or Reset the CC4P Bit */ + tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC4P); + tmpccer |= (uint16_t)(TIM_OCPolarity << 12); + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel x. + * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. + * @param TIM_Channel: specifies the TIM Channel + * This parmeter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @arg TIM_Channel_4: TIM Channel 4 + * @param TIM_CCx: specifies the TIM Channel CCxE bit new state. + * This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable. + * @retval None + */ +void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx) +{ + uint16_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST8_PERIPH(TIMx)); + assert_param(IS_TIM_CHANNEL(TIM_Channel)); + assert_param(IS_TIM_CCX(TIM_CCx)); + + tmp = CCER_CCE_Set << TIM_Channel; + + /* Reset the CCxE Bit */ + TIMx->CCER &= (uint16_t)~ tmp; + + /* Set or reset the CCxE Bit */ + TIMx->CCER |= (uint16_t)(TIM_CCx << TIM_Channel); +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel xN. + * @param TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIM peripheral. + * @param TIM_Channel: specifies the TIM Channel + * This parmeter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @param TIM_CCxN: specifies the TIM Channel CCxNE bit new state. + * This parameter can be: TIM_CCxN_Enable or TIM_CCxN_Disable. + * @retval None + */ +void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN) +{ + uint16_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_COMPLEMENTARY_CHANNEL(TIM_Channel)); + assert_param(IS_TIM_CCXN(TIM_CCxN)); + + tmp = CCER_CCNE_Set << TIM_Channel; + + /* Reset the CCxNE Bit */ + TIMx->CCER &= (uint16_t) ~tmp; + + /* Set or reset the CCxNE Bit */ + TIMx->CCER |= (uint16_t)(TIM_CCxN << TIM_Channel); +} + +/** + * @brief Selects the TIM Ouput Compare Mode. + * @note This function disables the selected channel before changing the Ouput + * Compare Mode. + * User has to enable this channel using TIM_CCxCmd and TIM_CCxNCmd functions. + * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. + * @param TIM_Channel: specifies the TIM Channel + * This parmeter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @arg TIM_Channel_4: TIM Channel 4 + * @param TIM_OCMode: specifies the TIM Output Compare Mode. + * This paramter can be one of the following values: + * @arg TIM_OCMode_Timing + * @arg TIM_OCMode_Active + * @arg TIM_OCMode_Toggle + * @arg TIM_OCMode_PWM1 + * @arg TIM_OCMode_PWM2 + * @arg TIM_ForcedAction_Active + * @arg TIM_ForcedAction_InActive + * @retval None + */ +void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode) +{ + uint32_t tmp = 0; + uint16_t tmp1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST8_PERIPH(TIMx)); + assert_param(IS_TIM_CHANNEL(TIM_Channel)); + assert_param(IS_TIM_OCM(TIM_OCMode)); + + tmp = (uint32_t) TIMx; + tmp += CCMR_Offset; + + tmp1 = CCER_CCE_Set << (uint16_t)TIM_Channel; + + /* Disable the Channel: Reset the CCxE Bit */ + TIMx->CCER &= (uint16_t) ~tmp1; + + if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3)) + { + tmp += (TIM_Channel>>1); + + /* Reset the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC1M); + + /* Configure the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp |= TIM_OCMode; + } + else + { + tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1; + + /* Reset the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2M); + + /* Configure the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp |= (uint16_t)(TIM_OCMode << 8); + } +} + +/** + * @brief Enables or Disables the TIMx Update event. + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @param NewState: new state of the TIMx UDIS bit + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Set the Update Disable Bit */ + TIMx->CR1 |= TIM_CR1_UDIS; + } + else + { + /* Reset the Update Disable Bit */ + TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_UDIS); + } +} + +/** + * @brief Configures the TIMx Update Request Interrupt source. + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @param TIM_UpdateSource: specifies the Update source. + * This parameter can be one of the following values: + * @arg TIM_UpdateSource_Regular: Source of update is the counter overflow/underflow + or the setting of UG bit, or an update generation + through the slave mode controller. + * @arg TIM_UpdateSource_Global: Source of update is counter overflow/underflow. + * @retval None + */ +void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_UPDATE_SOURCE(TIM_UpdateSource)); + if (TIM_UpdateSource != TIM_UpdateSource_Global) + { + /* Set the URS Bit */ + TIMx->CR1 |= TIM_CR1_URS; + } + else + { + /* Reset the URS Bit */ + TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_URS); + } +} + +/** + * @brief Enables or disables the TIMxs Hall sensor interface. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param NewState: new state of the TIMx Hall sensor interface. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Set the TI1S Bit */ + TIMx->CR2 |= TIM_CR2_TI1S; + } + else + { + /* Reset the TI1S Bit */ + TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_TI1S); + } +} + +/** + * @brief Selects the TIMxs One Pulse Mode. + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @param TIM_OPMode: specifies the OPM Mode to be used. + * This parameter can be one of the following values: + * @arg TIM_OPMode_Single + * @arg TIM_OPMode_Repetitive + * @retval None + */ +void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_OPM_MODE(TIM_OPMode)); + /* Reset the OPM Bit */ + TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_OPM); + /* Configure the OPM Mode */ + TIMx->CR1 |= TIM_OPMode; +} + +/** + * @brief Selects the TIMx Trigger Output Mode. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 12 or 15 to select the TIM peripheral. + * @param TIM_TRGOSource: specifies the Trigger Output source. + * This paramter can be one of the following values: + * + * - For all TIMx + * @arg TIM_TRGOSource_Reset: The UG bit in the TIM_EGR register is used as the trigger output (TRGO). + * @arg TIM_TRGOSource_Enable: The Counter Enable CEN is used as the trigger output (TRGO). + * @arg TIM_TRGOSource_Update: The update event is selected as the trigger output (TRGO). + * + * - For all TIMx except TIM6 and TIM7 + * @arg TIM_TRGOSource_OC1: The trigger output sends a positive pulse when the CC1IF flag + * is to be set, as soon as a capture or compare match occurs (TRGO). + * @arg TIM_TRGOSource_OC1Ref: OC1REF signal is used as the trigger output (TRGO). + * @arg TIM_TRGOSource_OC2Ref: OC2REF signal is used as the trigger output (TRGO). + * @arg TIM_TRGOSource_OC3Ref: OC3REF signal is used as the trigger output (TRGO). + * @arg TIM_TRGOSource_OC4Ref: OC4REF signal is used as the trigger output (TRGO). + * + * @retval None + */ +void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST7_PERIPH(TIMx)); + assert_param(IS_TIM_TRGO_SOURCE(TIM_TRGOSource)); + /* Reset the MMS Bits */ + TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_MMS); + /* Select the TRGO source */ + TIMx->CR2 |= TIM_TRGOSource; +} + +/** + * @brief Selects the TIMx Slave Mode. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. + * @param TIM_SlaveMode: specifies the Timer Slave Mode. + * This paramter can be one of the following values: + * @arg TIM_SlaveMode_Reset: Rising edge of the selected trigger signal (TRGI) re-initializes + * the counter and triggers an update of the registers. + * @arg TIM_SlaveMode_Gated: The counter clock is enabled when the trigger signal (TRGI) is high. + * @arg TIM_SlaveMode_Trigger: The counter starts at a rising edge of the trigger TRGI. + * @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter. + * @retval None + */ +void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_SLAVE_MODE(TIM_SlaveMode)); + /* Reset the SMS Bits */ + TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_SMS); + /* Select the Slave Mode */ + TIMx->SMCR |= TIM_SlaveMode; +} + +/** + * @brief Sets or Resets the TIMx Master/Slave Mode. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. + * @param TIM_MasterSlaveMode: specifies the Timer Master Slave Mode. + * This paramter can be one of the following values: + * @arg TIM_MasterSlaveMode_Enable: synchronization between the current timer + * and its slaves (through TRGO). + * @arg TIM_MasterSlaveMode_Disable: No action + * @retval None + */ +void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_MSM_STATE(TIM_MasterSlaveMode)); + /* Reset the MSM Bit */ + TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_MSM); + + /* Set or Reset the MSM Bit */ + TIMx->SMCR |= TIM_MasterSlaveMode; +} + +/** + * @brief Sets the TIMx Counter Register value + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @param Counter: specifies the Counter register new value. + * @retval None + */ +void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + /* Set the Counter Register value */ + TIMx->CNT = Counter; +} + +/** + * @brief Sets the TIMx Autoreload Register value + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @param Autoreload: specifies the Autoreload register new value. + * @retval None + */ +void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + /* Set the Autoreload Register value */ + TIMx->ARR = Autoreload; +} + +/** + * @brief Sets the TIMx Capture Compare1 Register value + * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. + * @param Compare1: specifies the Capture Compare1 register new value. + * @retval None + */ +void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST8_PERIPH(TIMx)); + /* Set the Capture Compare1 Register value */ + TIMx->CCR1 = Compare1; +} + +/** + * @brief Sets the TIMx Capture Compare2 Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. + * @param Compare2: specifies the Capture Compare2 register new value. + * @retval None + */ +void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + /* Set the Capture Compare2 Register value */ + TIMx->CCR2 = Compare2; +} + +/** + * @brief Sets the TIMx Capture Compare3 Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param Compare3: specifies the Capture Compare3 register new value. + * @retval None + */ +void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + /* Set the Capture Compare3 Register value */ + TIMx->CCR3 = Compare3; +} + +/** + * @brief Sets the TIMx Capture Compare4 Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param Compare4: specifies the Capture Compare4 register new value. + * @retval None + */ +void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + /* Set the Capture Compare4 Register value */ + TIMx->CCR4 = Compare4; +} + +/** + * @brief Sets the TIMx Input Capture 1 prescaler. + * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture1 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST8_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + /* Reset the IC1PSC Bits */ + TIMx->CCMR1 &= (uint16_t)~((uint16_t)TIM_CCMR1_IC1PSC); + /* Set the IC1PSC value */ + TIMx->CCMR1 |= TIM_ICPSC; +} + +/** + * @brief Sets the TIMx Input Capture 2 prescaler. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture2 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + /* Reset the IC2PSC Bits */ + TIMx->CCMR1 &= (uint16_t)~((uint16_t)TIM_CCMR1_IC2PSC); + /* Set the IC2PSC value */ + TIMx->CCMR1 |= (uint16_t)(TIM_ICPSC << 8); +} + +/** + * @brief Sets the TIMx Input Capture 3 prescaler. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture3 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + /* Reset the IC3PSC Bits */ + TIMx->CCMR2 &= (uint16_t)~((uint16_t)TIM_CCMR2_IC3PSC); + /* Set the IC3PSC value */ + TIMx->CCMR2 |= TIM_ICPSC; +} + +/** + * @brief Sets the TIMx Input Capture 4 prescaler. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture4 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + /* Reset the IC4PSC Bits */ + TIMx->CCMR2 &= (uint16_t)~((uint16_t)TIM_CCMR2_IC4PSC); + /* Set the IC4PSC value */ + TIMx->CCMR2 |= (uint16_t)(TIM_ICPSC << 8); +} + +/** + * @brief Sets the TIMx Clock Division value. + * @param TIMx: where x can be 1 to 17 except 6 and 7 to select + * the TIM peripheral. + * @param TIM_CKD: specifies the clock division value. + * This parameter can be one of the following value: + * @arg TIM_CKD_DIV1: TDTS = Tck_tim + * @arg TIM_CKD_DIV2: TDTS = 2*Tck_tim + * @arg TIM_CKD_DIV4: TDTS = 4*Tck_tim + * @retval None + */ +void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST8_PERIPH(TIMx)); + assert_param(IS_TIM_CKD_DIV(TIM_CKD)); + /* Reset the CKD Bits */ + TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_CKD); + /* Set the CKD value */ + TIMx->CR1 |= TIM_CKD; +} + +/** + * @brief Gets the TIMx Input Capture 1 value. + * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. + * @retval Capture Compare 1 Register value. + */ +uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST8_PERIPH(TIMx)); + /* Get the Capture 1 Register value */ + return TIMx->CCR1; +} + +/** + * @brief Gets the TIMx Input Capture 2 value. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. + * @retval Capture Compare 2 Register value. + */ +uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + /* Get the Capture 2 Register value */ + return TIMx->CCR2; +} + +/** + * @brief Gets the TIMx Input Capture 3 value. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @retval Capture Compare 3 Register value. + */ +uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + /* Get the Capture 3 Register value */ + return TIMx->CCR3; +} + +/** + * @brief Gets the TIMx Input Capture 4 value. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @retval Capture Compare 4 Register value. + */ +uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + /* Get the Capture 4 Register value */ + return TIMx->CCR4; +} + +/** + * @brief Gets the TIMx Counter value. + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @retval Counter Register value. + */ +uint16_t TIM_GetCounter(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + /* Get the Counter Register value */ + return TIMx->CNT; +} + +/** + * @brief Gets the TIMx Prescaler value. + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @retval Prescaler Register value. + */ +uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + /* Get the Prescaler Register value */ + return TIMx->PSC; +} + +/** + * @brief Checks whether the specified TIM flag is set or not. + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @param TIM_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg TIM_FLAG_Update: TIM update Flag + * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag + * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag + * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag + * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag + * @arg TIM_FLAG_COM: TIM Commutation Flag + * @arg TIM_FLAG_Trigger: TIM Trigger Flag + * @arg TIM_FLAG_Break: TIM Break Flag + * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag + * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag + * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag + * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag + * @note + * - TIM6 and TIM7 can have only one update flag. + * - TIM9, TIM12 and TIM15 can have only TIM_FLAG_Update, TIM_FLAG_CC1, + * TIM_FLAG_CC2 or TIM_FLAG_Trigger. + * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_FLAG_Update or TIM_FLAG_CC1. + * - TIM_FLAG_Break is used only with TIM1, TIM8 and TIM15. + * - TIM_FLAG_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17. + * @retval The new state of TIM_FLAG (SET or RESET). + */ +FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) +{ + ITStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_GET_FLAG(TIM_FLAG)); + + if ((TIMx->SR & TIM_FLAG) != (uint16_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the TIMx's pending flags. + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @param TIM_FLAG: specifies the flag bit to clear. + * This parameter can be any combination of the following values: + * @arg TIM_FLAG_Update: TIM update Flag + * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag + * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag + * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag + * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag + * @arg TIM_FLAG_COM: TIM Commutation Flag + * @arg TIM_FLAG_Trigger: TIM Trigger Flag + * @arg TIM_FLAG_Break: TIM Break Flag + * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag + * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag + * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag + * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag + * @note + * - TIM6 and TIM7 can have only one update flag. + * - TIM9, TIM12 and TIM15 can have only TIM_FLAG_Update, TIM_FLAG_CC1, + * TIM_FLAG_CC2 or TIM_FLAG_Trigger. + * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_FLAG_Update or TIM_FLAG_CC1. + * - TIM_FLAG_Break is used only with TIM1, TIM8 and TIM15. + * - TIM_FLAG_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17. + * @retval None + */ +void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_CLEAR_FLAG(TIM_FLAG)); + + /* Clear the flags */ + TIMx->SR = (uint16_t)~TIM_FLAG; +} + +/** + * @brief Checks whether the TIM interrupt has occurred or not. + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @param TIM_IT: specifies the TIM interrupt source to check. + * This parameter can be one of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * @note + * - TIM6 and TIM7 can generate only an update interrupt. + * - TIM9, TIM12 and TIM15 can have only TIM_IT_Update, TIM_IT_CC1, + * TIM_IT_CC2 or TIM_IT_Trigger. + * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1. + * - TIM_IT_Break is used only with TIM1, TIM8 and TIM15. + * - TIM_IT_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17. + * @retval The new state of the TIM_IT(SET or RESET). + */ +ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT) +{ + ITStatus bitstatus = RESET; + uint16_t itstatus = 0x0, itenable = 0x0; + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_GET_IT(TIM_IT)); + + itstatus = TIMx->SR & TIM_IT; + + itenable = TIMx->DIER & TIM_IT; + if ((itstatus != (uint16_t)RESET) && (itenable != (uint16_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the TIMx's interrupt pending bits. + * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. + * @param TIM_IT: specifies the pending bit to clear. + * This parameter can be any combination of the following values: + * @arg TIM_IT_Update: TIM1 update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * @note + * - TIM6 and TIM7 can generate only an update interrupt. + * - TIM9, TIM12 and TIM15 can have only TIM_IT_Update, TIM_IT_CC1, + * TIM_IT_CC2 or TIM_IT_Trigger. + * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1. + * - TIM_IT_Break is used only with TIM1, TIM8 and TIM15. + * - TIM_IT_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17. + * @retval None + */ +void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_IT(TIM_IT)); + /* Clear the IT pending Bit */ + TIMx->SR = (uint16_t)~TIM_IT; +} + +/** + * @brief Configure the TI1 as Input. + * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1. + * @arg TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2. + * @arg TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr1 = 0, tmpccer = 0; + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC1E); + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + /* Select the Input and set the filter */ + tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & ((uint16_t)~((uint16_t)TIM_CCMR1_IC1F))); + tmpccmr1 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4)); + /* Select the Polarity and set the CC1E Bit */ + tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC1P)); + tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC1E); + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI2 as Input. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 2 is selected to be connected to IC2. + * @arg TIM_ICSelection_IndirectTI: TIM Input 2 is selected to be connected to IC1. + * @arg TIM_ICSelection_TRC: TIM Input 2 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr1 = 0, tmpccer = 0, tmp = 0; + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC2E); + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + tmp = (uint16_t)(TIM_ICPolarity << 4); + /* Select the Input and set the filter */ + tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC2S)) & ((uint16_t)~((uint16_t)TIM_CCMR1_IC2F))); + tmpccmr1 |= (uint16_t)(TIM_ICFilter << 12); + tmpccmr1 |= (uint16_t)(TIM_ICSelection << 8); + /* Select the Polarity and set the CC2E Bit */ + tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC2P)); + tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC2E); + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1 ; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI3 as Input. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 3 is selected to be connected to IC3. + * @arg TIM_ICSelection_IndirectTI: TIM Input 3 is selected to be connected to IC4. + * @arg TIM_ICSelection_TRC: TIM Input 3 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; + /* Disable the Channel 3: Reset the CC3E Bit */ + TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC3E); + tmpccmr2 = TIMx->CCMR2; + tmpccer = TIMx->CCER; + tmp = (uint16_t)(TIM_ICPolarity << 8); + /* Select the Input and set the filter */ + tmpccmr2 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR2_CC3S)) & ((uint16_t)~((uint16_t)TIM_CCMR2_IC3F))); + tmpccmr2 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4)); + /* Select the Polarity and set the CC3E Bit */ + tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC3P)); + tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC3E); + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI1 as Input. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 4 is selected to be connected to IC4. + * @arg TIM_ICSelection_IndirectTI: TIM Input 4 is selected to be connected to IC3. + * @arg TIM_ICSelection_TRC: TIM Input 4 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC4E); + tmpccmr2 = TIMx->CCMR2; + tmpccer = TIMx->CCER; + tmp = (uint16_t)(TIM_ICPolarity << 12); + /* Select the Input and set the filter */ + tmpccmr2 &= (uint16_t)((uint16_t)(~(uint16_t)TIM_CCMR2_CC4S) & ((uint16_t)~((uint16_t)TIM_CCMR2_IC4F))); + tmpccmr2 |= (uint16_t)(TIM_ICSelection << 8); + tmpccmr2 |= (uint16_t)(TIM_ICFilter << 12); + + /* Select the Polarity and set the CC4E Bit */ + tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC4P)); + tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC4E); + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_usart.c b/example/libs_stm/src/stm32f10x/stm32f10x_usart.c new file mode 100644 index 000000000..fa0733e89 --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_usart.c @@ -0,0 +1,1054 @@ +/** + ****************************************************************************** + * @file stm32f10x_usart.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the USART firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_usart.h" +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup USART + * @brief USART driver modules + * @{ + */ + +/** @defgroup USART_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup USART_Private_Defines + * @{ + */ + +#define CR1_UE_Set ((uint16_t)0x2000) /*!< USART Enable Mask */ +#define CR1_UE_Reset ((uint16_t)0xDFFF) /*!< USART Disable Mask */ + +#define CR1_WAKE_Mask ((uint16_t)0xF7FF) /*!< USART WakeUp Method Mask */ + +#define CR1_RWU_Set ((uint16_t)0x0002) /*!< USART mute mode Enable Mask */ +#define CR1_RWU_Reset ((uint16_t)0xFFFD) /*!< USART mute mode Enable Mask */ +#define CR1_SBK_Set ((uint16_t)0x0001) /*!< USART Break Character send Mask */ +#define CR1_CLEAR_Mask ((uint16_t)0xE9F3) /*!< USART CR1 Mask */ +#define CR2_Address_Mask ((uint16_t)0xFFF0) /*!< USART address Mask */ + +#define CR2_LINEN_Set ((uint16_t)0x4000) /*!< USART LIN Enable Mask */ +#define CR2_LINEN_Reset ((uint16_t)0xBFFF) /*!< USART LIN Disable Mask */ + +#define CR2_LBDL_Mask ((uint16_t)0xFFDF) /*!< USART LIN Break detection Mask */ +#define CR2_STOP_CLEAR_Mask ((uint16_t)0xCFFF) /*!< USART CR2 STOP Bits Mask */ +#define CR2_CLOCK_CLEAR_Mask ((uint16_t)0xF0FF) /*!< USART CR2 Clock Mask */ + +#define CR3_SCEN_Set ((uint16_t)0x0020) /*!< USART SC Enable Mask */ +#define CR3_SCEN_Reset ((uint16_t)0xFFDF) /*!< USART SC Disable Mask */ + +#define CR3_NACK_Set ((uint16_t)0x0010) /*!< USART SC NACK Enable Mask */ +#define CR3_NACK_Reset ((uint16_t)0xFFEF) /*!< USART SC NACK Disable Mask */ + +#define CR3_HDSEL_Set ((uint16_t)0x0008) /*!< USART Half-Duplex Enable Mask */ +#define CR3_HDSEL_Reset ((uint16_t)0xFFF7) /*!< USART Half-Duplex Disable Mask */ + +#define CR3_IRLP_Mask ((uint16_t)0xFFFB) /*!< USART IrDA LowPower mode Mask */ +#define CR3_CLEAR_Mask ((uint16_t)0xFCFF) /*!< USART CR3 Mask */ + +#define CR3_IREN_Set ((uint16_t)0x0002) /*!< USART IrDA Enable Mask */ +#define CR3_IREN_Reset ((uint16_t)0xFFFD) /*!< USART IrDA Disable Mask */ +#define GTPR_LSB_Mask ((uint16_t)0x00FF) /*!< Guard Time Register LSB Mask */ +#define GTPR_MSB_Mask ((uint16_t)0xFF00) /*!< Guard Time Register MSB Mask */ +#define IT_Mask ((uint16_t)0x001F) /*!< USART Interrupt Mask */ + +/* USART OverSampling-8 Mask */ +#define CR1_OVER8_Set ((u16)0x8000) /* USART OVER8 mode Enable Mask */ +#define CR1_OVER8_Reset ((u16)0x7FFF) /* USART OVER8 mode Disable Mask */ + +/* USART One Bit Sampling Mask */ +#define CR3_ONEBITE_Set ((u16)0x0800) /* USART ONEBITE mode Enable Mask */ +#define CR3_ONEBITE_Reset ((u16)0xF7FF) /* USART ONEBITE mode Disable Mask */ + +/** + * @} + */ + +/** @defgroup USART_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USART_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USART_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup USART_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the USARTx peripheral registers to their default reset values. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: USART1, USART2, USART3, UART4 or UART5. + * @retval None + */ +void USART_DeInit(USART_TypeDef* USARTx) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + if (USARTx == USART1) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); + } + else if (USARTx == USART2) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE); + } + else if (USARTx == USART3) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE); + } + else if (USARTx == UART4) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, DISABLE); + } + else + { + if (USARTx == UART5) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, DISABLE); + } + } +} + +/** + * @brief Initializes the USARTx peripheral according to the specified + * parameters in the USART_InitStruct . + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_InitStruct: pointer to a USART_InitTypeDef structure + * that contains the configuration information for the specified USART peripheral. + * @retval None + */ +void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct) +{ + uint32_t tmpreg = 0x00, apbclock = 0x00; + uint32_t integerdivider = 0x00; + uint32_t fractionaldivider = 0x00; + uint32_t usartxbase = 0; + RCC_ClocksTypeDef RCC_ClocksStatus; + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_BAUDRATE(USART_InitStruct->USART_BaudRate)); + assert_param(IS_USART_WORD_LENGTH(USART_InitStruct->USART_WordLength)); + assert_param(IS_USART_STOPBITS(USART_InitStruct->USART_StopBits)); + assert_param(IS_USART_PARITY(USART_InitStruct->USART_Parity)); + assert_param(IS_USART_MODE(USART_InitStruct->USART_Mode)); + assert_param(IS_USART_HARDWARE_FLOW_CONTROL(USART_InitStruct->USART_HardwareFlowControl)); + /* The hardware flow control is available only for USART1, USART2 and USART3 */ + if (USART_InitStruct->USART_HardwareFlowControl != USART_HardwareFlowControl_None) + { + assert_param(IS_USART_123_PERIPH(USARTx)); + } + + usartxbase = (uint32_t)USARTx; + +/*---------------------------- USART CR2 Configuration -----------------------*/ + tmpreg = USARTx->CR2; + /* Clear STOP[13:12] bits */ + tmpreg &= CR2_STOP_CLEAR_Mask; + /* Configure the USART Stop Bits, Clock, CPOL, CPHA and LastBit ------------*/ + /* Set STOP[13:12] bits according to USART_StopBits value */ + tmpreg |= (uint32_t)USART_InitStruct->USART_StopBits; + + /* Write to USART CR2 */ + USARTx->CR2 = (uint16_t)tmpreg; + +/*---------------------------- USART CR1 Configuration -----------------------*/ + tmpreg = USARTx->CR1; + /* Clear M, PCE, PS, TE and RE bits */ + tmpreg &= CR1_CLEAR_Mask; + /* Configure the USART Word Length, Parity and mode ----------------------- */ + /* Set the M bits according to USART_WordLength value */ + /* Set PCE and PS bits according to USART_Parity value */ + /* Set TE and RE bits according to USART_Mode value */ + tmpreg |= (uint32_t)USART_InitStruct->USART_WordLength | USART_InitStruct->USART_Parity | + USART_InitStruct->USART_Mode; + /* Write to USART CR1 */ + USARTx->CR1 = (uint16_t)tmpreg; + +/*---------------------------- USART CR3 Configuration -----------------------*/ + tmpreg = USARTx->CR3; + /* Clear CTSE and RTSE bits */ + tmpreg &= CR3_CLEAR_Mask; + /* Configure the USART HFC -------------------------------------------------*/ + /* Set CTSE and RTSE bits according to USART_HardwareFlowControl value */ + tmpreg |= USART_InitStruct->USART_HardwareFlowControl; + /* Write to USART CR3 */ + USARTx->CR3 = (uint16_t)tmpreg; + +/*---------------------------- USART BRR Configuration -----------------------*/ + /* Configure the USART Baud Rate -------------------------------------------*/ + RCC_GetClocksFreq(&RCC_ClocksStatus); + if (usartxbase == USART1_BASE) + { + apbclock = RCC_ClocksStatus.PCLK2_Frequency; + } + else + { + apbclock = RCC_ClocksStatus.PCLK1_Frequency; + } + + /* Determine the integer part */ + if ((USARTx->CR1 & CR1_OVER8_Set) != 0) + { + /* Integer part computing in case Oversampling mode is 8 Samples */ + integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate))); + } + else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */ + { + /* Integer part computing in case Oversampling mode is 16 Samples */ + integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate))); + } + tmpreg = (integerdivider / 100) << 4; + + /* Determine the fractional part */ + fractionaldivider = integerdivider - (100 * (tmpreg >> 4)); + + /* Implement the fractional part in the register */ + if ((USARTx->CR1 & CR1_OVER8_Set) != 0) + { + tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07); + } + else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */ + { + tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F); + } + + /* Write to USART BRR */ + USARTx->BRR = (uint16_t)tmpreg; +} + +/** + * @brief Fills each USART_InitStruct member with its default value. + * @param USART_InitStruct: pointer to a USART_InitTypeDef structure + * which will be initialized. + * @retval None + */ +void USART_StructInit(USART_InitTypeDef* USART_InitStruct) +{ + /* USART_InitStruct members default value */ + USART_InitStruct->USART_BaudRate = 9600; + USART_InitStruct->USART_WordLength = USART_WordLength_8b; + USART_InitStruct->USART_StopBits = USART_StopBits_1; + USART_InitStruct->USART_Parity = USART_Parity_No ; + USART_InitStruct->USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + USART_InitStruct->USART_HardwareFlowControl = USART_HardwareFlowControl_None; +} + +/** + * @brief Initializes the USARTx peripheral Clock according to the + * specified parameters in the USART_ClockInitStruct . + * @param USARTx: where x can be 1, 2, 3 to select the USART peripheral. + * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef + * structure that contains the configuration information for the specified + * USART peripheral. + * @note The Smart Card mode is not available for UART4 and UART5. + * @retval None + */ +void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct) +{ + uint32_t tmpreg = 0x00; + /* Check the parameters */ + assert_param(IS_USART_123_PERIPH(USARTx)); + assert_param(IS_USART_CLOCK(USART_ClockInitStruct->USART_Clock)); + assert_param(IS_USART_CPOL(USART_ClockInitStruct->USART_CPOL)); + assert_param(IS_USART_CPHA(USART_ClockInitStruct->USART_CPHA)); + assert_param(IS_USART_LASTBIT(USART_ClockInitStruct->USART_LastBit)); + +/*---------------------------- USART CR2 Configuration -----------------------*/ + tmpreg = USARTx->CR2; + /* Clear CLKEN, CPOL, CPHA and LBCL bits */ + tmpreg &= CR2_CLOCK_CLEAR_Mask; + /* Configure the USART Clock, CPOL, CPHA and LastBit ------------*/ + /* Set CLKEN bit according to USART_Clock value */ + /* Set CPOL bit according to USART_CPOL value */ + /* Set CPHA bit according to USART_CPHA value */ + /* Set LBCL bit according to USART_LastBit value */ + tmpreg |= (uint32_t)USART_ClockInitStruct->USART_Clock | USART_ClockInitStruct->USART_CPOL | + USART_ClockInitStruct->USART_CPHA | USART_ClockInitStruct->USART_LastBit; + /* Write to USART CR2 */ + USARTx->CR2 = (uint16_t)tmpreg; +} + +/** + * @brief Fills each USART_ClockInitStruct member with its default value. + * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef + * structure which will be initialized. + * @retval None + */ +void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct) +{ + /* USART_ClockInitStruct members default value */ + USART_ClockInitStruct->USART_Clock = USART_Clock_Disable; + USART_ClockInitStruct->USART_CPOL = USART_CPOL_Low; + USART_ClockInitStruct->USART_CPHA = USART_CPHA_1Edge; + USART_ClockInitStruct->USART_LastBit = USART_LastBit_Disable; +} + +/** + * @brief Enables or disables the specified USART peripheral. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param NewState: new state of the USARTx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected USART by setting the UE bit in the CR1 register */ + USARTx->CR1 |= CR1_UE_Set; + } + else + { + /* Disable the selected USART by clearing the UE bit in the CR1 register */ + USARTx->CR1 &= CR1_UE_Reset; + } +} + +/** + * @brief Enables or disables the specified USART interrupts. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_IT: specifies the USART interrupt sources to be enabled or disabled. + * This parameter can be one of the following values: + * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) + * @arg USART_IT_LBD: LIN Break detection interrupt + * @arg USART_IT_TXE: Tansmit Data Register empty interrupt + * @arg USART_IT_TC: Transmission complete interrupt + * @arg USART_IT_RXNE: Receive Data register not empty interrupt + * @arg USART_IT_IDLE: Idle line detection interrupt + * @arg USART_IT_PE: Parity Error interrupt + * @arg USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error) + * @param NewState: new state of the specified USARTx interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState) +{ + uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00; + uint32_t usartxbase = 0x00; + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_CONFIG_IT(USART_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + /* The CTS interrupt is not available for UART4 and UART5 */ + if (USART_IT == USART_IT_CTS) + { + assert_param(IS_USART_123_PERIPH(USARTx)); + } + + usartxbase = (uint32_t)USARTx; + + /* Get the USART register index */ + usartreg = (((uint8_t)USART_IT) >> 0x05); + + /* Get the interrupt position */ + itpos = USART_IT & IT_Mask; + itmask = (((uint32_t)0x01) << itpos); + + if (usartreg == 0x01) /* The IT is in CR1 register */ + { + usartxbase += 0x0C; + } + else if (usartreg == 0x02) /* The IT is in CR2 register */ + { + usartxbase += 0x10; + } + else /* The IT is in CR3 register */ + { + usartxbase += 0x14; + } + if (NewState != DISABLE) + { + *(__IO uint32_t*)usartxbase |= itmask; + } + else + { + *(__IO uint32_t*)usartxbase &= ~itmask; + } +} + +/** + * @brief Enables or disables the USARTs DMA interface. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3 or UART4. + * @param USART_DMAReq: specifies the DMA request. + * This parameter can be any combination of the following values: + * @arg USART_DMAReq_Tx: USART DMA transmit request + * @arg USART_DMAReq_Rx: USART DMA receive request + * @param NewState: new state of the DMA Request sources. + * This parameter can be: ENABLE or DISABLE. + * @note The DMA mode is not available for UART5. + * @retval None + */ +void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_1234_PERIPH(USARTx)); + assert_param(IS_USART_DMAREQ(USART_DMAReq)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the DMA transfer for selected requests by setting the DMAT and/or + DMAR bits in the USART CR3 register */ + USARTx->CR3 |= USART_DMAReq; + } + else + { + /* Disable the DMA transfer for selected requests by clearing the DMAT and/or + DMAR bits in the USART CR3 register */ + USARTx->CR3 &= (uint16_t)~USART_DMAReq; + } +} + +/** + * @brief Sets the address of the USART node. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_Address: Indicates the address of the USART node. + * @retval None + */ +void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_ADDRESS(USART_Address)); + + /* Clear the USART address */ + USARTx->CR2 &= CR2_Address_Mask; + /* Set the USART address node */ + USARTx->CR2 |= USART_Address; +} + +/** + * @brief Selects the USART WakeUp method. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_WakeUp: specifies the USART wakeup method. + * This parameter can be one of the following values: + * @arg USART_WakeUp_IdleLine: WakeUp by an idle line detection + * @arg USART_WakeUp_AddressMark: WakeUp by an address mark + * @retval None + */ +void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_WAKEUP(USART_WakeUp)); + + USARTx->CR1 &= CR1_WAKE_Mask; + USARTx->CR1 |= USART_WakeUp; +} + +/** + * @brief Determines if the USART is in mute mode or not. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param NewState: new state of the USART mute mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the USART mute mode by setting the RWU bit in the CR1 register */ + USARTx->CR1 |= CR1_RWU_Set; + } + else + { + /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */ + USARTx->CR1 &= CR1_RWU_Reset; + } +} + +/** + * @brief Sets the USART LIN Break detection length. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_LINBreakDetectLength: specifies the LIN break detection length. + * This parameter can be one of the following values: + * @arg USART_LINBreakDetectLength_10b: 10-bit break detection + * @arg USART_LINBreakDetectLength_11b: 11-bit break detection + * @retval None + */ +void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_LIN_BREAK_DETECT_LENGTH(USART_LINBreakDetectLength)); + + USARTx->CR2 &= CR2_LBDL_Mask; + USARTx->CR2 |= USART_LINBreakDetectLength; +} + +/** + * @brief Enables or disables the USARTs LIN mode. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param NewState: new state of the USART LIN mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the LIN mode by setting the LINEN bit in the CR2 register */ + USARTx->CR2 |= CR2_LINEN_Set; + } + else + { + /* Disable the LIN mode by clearing the LINEN bit in the CR2 register */ + USARTx->CR2 &= CR2_LINEN_Reset; + } +} + +/** + * @brief Transmits single data through the USARTx peripheral. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param Data: the data to transmit. + * @retval None + */ +void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_DATA(Data)); + + /* Transmit Data */ + USARTx->DR = (Data & (uint16_t)0x01FF); +} + +/** + * @brief Returns the most recent received data by the USARTx peripheral. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @retval The received data. + */ +uint16_t USART_ReceiveData(USART_TypeDef* USARTx) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + /* Receive Data */ + return (uint16_t)(USARTx->DR & (uint16_t)0x01FF); +} + +/** + * @brief Transmits break characters. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @retval None + */ +void USART_SendBreak(USART_TypeDef* USARTx) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + /* Send break characters */ + USARTx->CR1 |= CR1_SBK_Set; +} + +/** + * @brief Sets the specified USART guard time. + * @param USARTx: where x can be 1, 2 or 3 to select the USART peripheral. + * @param USART_GuardTime: specifies the guard time. + * @note The guard time bits are not available for UART4 and UART5. + * @retval None + */ +void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime) +{ + /* Check the parameters */ + assert_param(IS_USART_123_PERIPH(USARTx)); + + /* Clear the USART Guard time */ + USARTx->GTPR &= GTPR_LSB_Mask; + /* Set the USART guard time */ + USARTx->GTPR |= (uint16_t)((uint16_t)USART_GuardTime << 0x08); +} + +/** + * @brief Sets the system clock prescaler. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_Prescaler: specifies the prescaler clock. + * @note The function is used for IrDA mode with UART4 and UART5. + * @retval None + */ +void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + + /* Clear the USART prescaler */ + USARTx->GTPR &= GTPR_MSB_Mask; + /* Set the USART prescaler */ + USARTx->GTPR |= USART_Prescaler; +} + +/** + * @brief Enables or disables the USARTs Smart Card mode. + * @param USARTx: where x can be 1, 2 or 3 to select the USART peripheral. + * @param NewState: new state of the Smart Card mode. + * This parameter can be: ENABLE or DISABLE. + * @note The Smart Card mode is not available for UART4 and UART5. + * @retval None + */ +void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_123_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the SC mode by setting the SCEN bit in the CR3 register */ + USARTx->CR3 |= CR3_SCEN_Set; + } + else + { + /* Disable the SC mode by clearing the SCEN bit in the CR3 register */ + USARTx->CR3 &= CR3_SCEN_Reset; + } +} + +/** + * @brief Enables or disables NACK transmission. + * @param USARTx: where x can be 1, 2 or 3 to select the USART peripheral. + * @param NewState: new state of the NACK transmission. + * This parameter can be: ENABLE or DISABLE. + * @note The Smart Card mode is not available for UART4 and UART5. + * @retval None + */ +void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_123_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Enable the NACK transmission by setting the NACK bit in the CR3 register */ + USARTx->CR3 |= CR3_NACK_Set; + } + else + { + /* Disable the NACK transmission by clearing the NACK bit in the CR3 register */ + USARTx->CR3 &= CR3_NACK_Reset; + } +} + +/** + * @brief Enables or disables the USARTs Half Duplex communication. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param NewState: new state of the USART Communication. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ + USARTx->CR3 |= CR3_HDSEL_Set; + } + else + { + /* Disable the Half-Duplex mode by clearing the HDSEL bit in the CR3 register */ + USARTx->CR3 &= CR3_HDSEL_Reset; + } +} + + +/** + * @brief Enables or disables the USART's 8x oversampling mode. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param NewState: new state of the USART one bit sampling methode. + * This parameter can be: ENABLE or DISABLE. + * @note + * This function has to be called before calling USART_Init() + * function in order to have correct baudrate Divider value. + * @retval None + */ +void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the 8x Oversampling mode by setting the OVER8 bit in the CR1 register */ + USARTx->CR1 |= CR1_OVER8_Set; + } + else + { + /* Disable the 8x Oversampling mode by clearing the OVER8 bit in the CR1 register */ + USARTx->CR1 &= CR1_OVER8_Reset; + } +} + +/** + * @brief Enables or disables the USART's one bit sampling methode. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param NewState: new state of the USART one bit sampling methode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the one bit method by setting the ONEBITE bit in the CR3 register */ + USARTx->CR3 |= CR3_ONEBITE_Set; + } + else + { + /* Disable tthe one bit method by clearing the ONEBITE bit in the CR3 register */ + USARTx->CR3 &= CR3_ONEBITE_Reset; + } +} + +/** + * @brief Configures the USARTs IrDA interface. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_IrDAMode: specifies the IrDA mode. + * This parameter can be one of the following values: + * @arg USART_IrDAMode_LowPower + * @arg USART_IrDAMode_Normal + * @retval None + */ +void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_IRDA_MODE(USART_IrDAMode)); + + USARTx->CR3 &= CR3_IRLP_Mask; + USARTx->CR3 |= USART_IrDAMode; +} + +/** + * @brief Enables or disables the USARTs IrDA interface. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param NewState: new state of the IrDA mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the IrDA mode by setting the IREN bit in the CR3 register */ + USARTx->CR3 |= CR3_IREN_Set; + } + else + { + /* Disable the IrDA mode by clearing the IREN bit in the CR3 register */ + USARTx->CR3 &= CR3_IREN_Reset; + } +} + +/** + * @brief Checks whether the specified USART flag is set or not. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5) + * @arg USART_FLAG_LBD: LIN Break detection flag + * @arg USART_FLAG_TXE: Transmit data register empty flag + * @arg USART_FLAG_TC: Transmission Complete flag + * @arg USART_FLAG_RXNE: Receive data register not empty flag + * @arg USART_FLAG_IDLE: Idle Line detection flag + * @arg USART_FLAG_ORE: OverRun Error flag + * @arg USART_FLAG_NE: Noise Error flag + * @arg USART_FLAG_FE: Framing Error flag + * @arg USART_FLAG_PE: Parity Error flag + * @retval The new state of USART_FLAG (SET or RESET). + */ +FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG) +{ + FlagStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_FLAG(USART_FLAG)); + /* The CTS flag is not available for UART4 and UART5 */ + if (USART_FLAG == USART_FLAG_CTS) + { + assert_param(IS_USART_123_PERIPH(USARTx)); + } + + if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the USARTx's pending flags. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_FLAG: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5). + * @arg USART_FLAG_LBD: LIN Break detection flag. + * @arg USART_FLAG_TC: Transmission Complete flag. + * @arg USART_FLAG_RXNE: Receive data register not empty flag. + * + * @note + * - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun + * error) and IDLE (Idle line detected) flags are cleared by software + * sequence: a read operation to USART_SR register (USART_GetFlagStatus()) + * followed by a read operation to USART_DR register (USART_ReceiveData()). + * - RXNE flag can be also cleared by a read to the USART_DR register + * (USART_ReceiveData()). + * - TC flag can be also cleared by software sequence: a read operation to + * USART_SR register (USART_GetFlagStatus()) followed by a write operation + * to USART_DR register (USART_SendData()). + * - TXE flag is cleared only by a write to the USART_DR register + * (USART_SendData()). + * @retval None + */ +void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG) +{ + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_CLEAR_FLAG(USART_FLAG)); + /* The CTS flag is not available for UART4 and UART5 */ + if ((USART_FLAG & USART_FLAG_CTS) == USART_FLAG_CTS) + { + assert_param(IS_USART_123_PERIPH(USARTx)); + } + + USARTx->SR = (uint16_t)~USART_FLAG; +} + +/** + * @brief Checks whether the specified USART interrupt has occurred or not. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_IT: specifies the USART interrupt source to check. + * This parameter can be one of the following values: + * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) + * @arg USART_IT_LBD: LIN Break detection interrupt + * @arg USART_IT_TXE: Tansmit Data Register empty interrupt + * @arg USART_IT_TC: Transmission complete interrupt + * @arg USART_IT_RXNE: Receive Data register not empty interrupt + * @arg USART_IT_IDLE: Idle line detection interrupt + * @arg USART_IT_ORE: OverRun Error interrupt + * @arg USART_IT_NE: Noise Error interrupt + * @arg USART_IT_FE: Framing Error interrupt + * @arg USART_IT_PE: Parity Error interrupt + * @retval The new state of USART_IT (SET or RESET). + */ +ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT) +{ + uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00; + ITStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_GET_IT(USART_IT)); + /* The CTS interrupt is not available for UART4 and UART5 */ + if (USART_IT == USART_IT_CTS) + { + assert_param(IS_USART_123_PERIPH(USARTx)); + } + + /* Get the USART register index */ + usartreg = (((uint8_t)USART_IT) >> 0x05); + /* Get the interrupt position */ + itmask = USART_IT & IT_Mask; + itmask = (uint32_t)0x01 << itmask; + + if (usartreg == 0x01) /* The IT is in CR1 register */ + { + itmask &= USARTx->CR1; + } + else if (usartreg == 0x02) /* The IT is in CR2 register */ + { + itmask &= USARTx->CR2; + } + else /* The IT is in CR3 register */ + { + itmask &= USARTx->CR3; + } + + bitpos = USART_IT >> 0x08; + bitpos = (uint32_t)0x01 << bitpos; + bitpos &= USARTx->SR; + if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + + return bitstatus; +} + +/** + * @brief Clears the USARTxs interrupt pending bits. + * @param USARTx: Select the USART or the UART peripheral. + * This parameter can be one of the following values: + * USART1, USART2, USART3, UART4 or UART5. + * @param USART_IT: specifies the interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) + * @arg USART_IT_LBD: LIN Break detection interrupt + * @arg USART_IT_TC: Transmission complete interrupt. + * @arg USART_IT_RXNE: Receive Data register not empty interrupt. + * + * @note + * - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun + * error) and IDLE (Idle line detected) pending bits are cleared by + * software sequence: a read operation to USART_SR register + * (USART_GetITStatus()) followed by a read operation to USART_DR register + * (USART_ReceiveData()). + * - RXNE pending bit can be also cleared by a read to the USART_DR register + * (USART_ReceiveData()). + * - TC pending bit can be also cleared by software sequence: a read + * operation to USART_SR register (USART_GetITStatus()) followed by a write + * operation to USART_DR register (USART_SendData()). + * - TXE pending bit is cleared only by a write to the USART_DR register + * (USART_SendData()). + * @retval None + */ +void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT) +{ + uint16_t bitpos = 0x00, itmask = 0x00; + /* Check the parameters */ + assert_param(IS_USART_ALL_PERIPH(USARTx)); + assert_param(IS_USART_CLEAR_IT(USART_IT)); + /* The CTS interrupt is not available for UART4 and UART5 */ + if (USART_IT == USART_IT_CTS) + { + assert_param(IS_USART_123_PERIPH(USARTx)); + } + + bitpos = USART_IT >> 0x08; + itmask = ((uint16_t)0x01 << (uint16_t)bitpos); + USARTx->SR = (uint16_t)~itmask; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_wwdg.c b/example/libs_stm/src/stm32f10x/stm32f10x_wwdg.c new file mode 100644 index 000000000..cd4978bbe --- /dev/null +++ b/example/libs_stm/src/stm32f10x/stm32f10x_wwdg.c @@ -0,0 +1,223 @@ +/** + ****************************************************************************** + * @file stm32f10x_wwdg.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief This file provides all the WWDG firmware functions. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_wwdg.h" +#include "stm32f10x_rcc.h" + +/** @addtogroup STM32F10x_StdPeriph_Driver + * @{ + */ + +/** @defgroup WWDG + * @brief WWDG driver modules + * @{ + */ + +/** @defgroup WWDG_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup WWDG_Private_Defines + * @{ + */ + +/* ----------- WWDG registers bit address in the alias region ----------- */ +#define WWDG_OFFSET (WWDG_BASE - PERIPH_BASE) + +/* Alias word address of EWI bit */ +#define CFR_OFFSET (WWDG_OFFSET + 0x04) +#define EWI_BitNumber 0x09 +#define CFR_EWI_BB (PERIPH_BB_BASE + (CFR_OFFSET * 32) + (EWI_BitNumber * 4)) + +/* --------------------- WWDG registers bit mask ------------------------ */ + +/* CR register bit mask */ +#define CR_WDGA_Set ((uint32_t)0x00000080) + +/* CFR register bit mask */ +#define CFR_WDGTB_Mask ((uint32_t)0xFFFFFE7F) +#define CFR_W_Mask ((uint32_t)0xFFFFFF80) +#define BIT_Mask ((uint8_t)0x7F) + +/** + * @} + */ + +/** @defgroup WWDG_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup WWDG_Private_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup WWDG_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup WWDG_Private_Functions + * @{ + */ + +/** + * @brief Deinitializes the WWDG peripheral registers to their default reset values. + * @param None + * @retval None + */ +void WWDG_DeInit(void) +{ + RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, DISABLE); +} + +/** + * @brief Sets the WWDG Prescaler. + * @param WWDG_Prescaler: specifies the WWDG Prescaler. + * This parameter can be one of the following values: + * @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1 + * @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2 + * @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4 + * @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8 + * @retval None + */ +void WWDG_SetPrescaler(uint32_t WWDG_Prescaler) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_WWDG_PRESCALER(WWDG_Prescaler)); + /* Clear WDGTB[1:0] bits */ + tmpreg = WWDG->CFR & CFR_WDGTB_Mask; + /* Set WDGTB[1:0] bits according to WWDG_Prescaler value */ + tmpreg |= WWDG_Prescaler; + /* Store the new value */ + WWDG->CFR = tmpreg; +} + +/** + * @brief Sets the WWDG window value. + * @param WindowValue: specifies the window value to be compared to the downcounter. + * This parameter value must be lower than 0x80. + * @retval None + */ +void WWDG_SetWindowValue(uint8_t WindowValue) +{ + __IO uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_WWDG_WINDOW_VALUE(WindowValue)); + /* Clear W[6:0] bits */ + + tmpreg = WWDG->CFR & CFR_W_Mask; + + /* Set W[6:0] bits according to WindowValue value */ + tmpreg |= WindowValue & (uint32_t) BIT_Mask; + + /* Store the new value */ + WWDG->CFR = tmpreg; +} + +/** + * @brief Enables the WWDG Early Wakeup interrupt(EWI). + * @param None + * @retval None + */ +void WWDG_EnableIT(void) +{ + *(__IO uint32_t *) CFR_EWI_BB = (uint32_t)ENABLE; +} + +/** + * @brief Sets the WWDG counter value. + * @param Counter: specifies the watchdog counter value. + * This parameter must be a number between 0x40 and 0x7F. + * @retval None + */ +void WWDG_SetCounter(uint8_t Counter) +{ + /* Check the parameters */ + assert_param(IS_WWDG_COUNTER(Counter)); + /* Write to T[6:0] bits to configure the counter value, no need to do + a read-modify-write; writing a 0 to WDGA bit does nothing */ + WWDG->CR = Counter & BIT_Mask; +} + +/** + * @brief Enables WWDG and load the counter value. + * @param Counter: specifies the watchdog counter value. + * This parameter must be a number between 0x40 and 0x7F. + * @retval None + */ +void WWDG_Enable(uint8_t Counter) +{ + /* Check the parameters */ + assert_param(IS_WWDG_COUNTER(Counter)); + WWDG->CR = CR_WDGA_Set | Counter; +} + +/** + * @brief Checks whether the Early Wakeup interrupt flag is set or not. + * @param None + * @retval The new state of the Early Wakeup interrupt flag (SET or RESET) + */ +FlagStatus WWDG_GetFlagStatus(void) +{ + return (FlagStatus)(WWDG->SR); +} + +/** + * @brief Clears Early Wakeup interrupt flag. + * @param None + * @retval None + */ +void WWDG_ClearFlag(void) +{ + WWDG->SR = (uint32_t)RESET; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ From a7d14c7d4e76f19901bb8dbd99bfafe9a69b5490 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 8 Nov 2011 01:13:21 +0000 Subject: [PATCH 0049/1435] Adding original source of vl factory demo It compiles, but I've got bugs preventing me from running this yet :( --- example/32vl_factory_demo/Makefile | 53 + example/32vl_factory_demo/README | 5 + example/32vl_factory_demo/main.c | 234 ++++ example/32vl_factory_demo/stm32f10x_conf.h | 76 ++ example/32vl_factory_demo/stm32f10x_it.c | 160 +++ example/32vl_factory_demo/stm32f10x_it.h | 46 + example/32vl_factory_demo/system_stm32f10x.c | 1019 ++++++++++++++++++ 7 files changed, 1593 insertions(+) create mode 100644 example/32vl_factory_demo/Makefile create mode 100644 example/32vl_factory_demo/README create mode 100644 example/32vl_factory_demo/main.c create mode 100644 example/32vl_factory_demo/stm32f10x_conf.h create mode 100644 example/32vl_factory_demo/stm32f10x_it.c create mode 100644 example/32vl_factory_demo/stm32f10x_it.h create mode 100644 example/32vl_factory_demo/system_stm32f10x.c diff --git a/example/32vl_factory_demo/Makefile b/example/32vl_factory_demo/Makefile new file mode 100644 index 000000000..81cdd56ba --- /dev/null +++ b/example/32vl_factory_demo/Makefile @@ -0,0 +1,53 @@ +# build an elf from the an3268 demonstration code +APP=32vl_factory_demo + +CC=arm-none-eabi-gcc +OBJCOPY=arm-none-eabi-objcopy + +CFLAGS=-O2 -mlittle-endian -mthumb +CFLAGS+=-mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc +ifeq ($(DEBUG),1) + CFLAGS+=-g +endif + +# to run from SRAM +CFLAGS+=-Wl,-Ttext,0x20000000 -Wl,-e,0x20000000 + +# to write to flash then run +# CFLAGS+=-Wl,-Ttext,0x08000000 -Wl,-e,0x08000000 + +PLATFORM=stm32f10x +BOARD_SUPPORT=../board_support/discovery_32vl +LIBS_STM_PATH=../libs_stm + +CFLAGS+=-I. +CFLAGS+=-I$(LIBS_STM_PATH)/inc/base +CFLAGS+=-I$(LIBS_STM_PATH)/inc/core_support +CFLAGS+=-I$(LIBS_STM_PATH)/inc/device_support +CFLAGS+=-I$(LIBS_STM_PATH)/inc/$(PLATFORM) +CFLAGS+=-I$(BOARD_SUPPORT) + +LDFLAGS+=-L$(LIBS_STM_PATH)/build -lstm32_stdperiph_f10x + + +SRCS=$(wildcard *.c) +SRCS+=$(wildcard $(BOARD_SUPPORT)/*.c) + +OBJS=$(SRCS:.c=.o) + +all: $(APP).elf + +%.bin: %.elf + $(OBJCOPY) -O binary $^ $@ + +$(APP).elf: $(OBJS) + $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $^ + +clean: + rm -rf $(OBJS) + rm -rf $(APP).* + +.PHONY: all clean diff --git a/example/32vl_factory_demo/README b/example/32vl_factory_demo/README new file mode 100644 index 000000000..28c83952d --- /dev/null +++ b/example/32vl_factory_demo/README @@ -0,0 +1,5 @@ +This source is copied from AN3268, the STM demo code for the VL discovery board. + +It was modified to add includes and things where needed, but nothing else was touched. + +Eventually, this should be usable to restore a board to virgin state. (but not yet) diff --git a/example/32vl_factory_demo/main.c b/example/32vl_factory_demo/main.c new file mode 100644 index 000000000..0043b650e --- /dev/null +++ b/example/32vl_factory_demo/main.c @@ -0,0 +1,234 @@ +/** + ****************************************************************************** + * @file Demo/src/main.c + * @author MCD Application Team + * @version V1.0.0 + * @date 09/13/2010 + * @brief Main program body + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" +#include "stm32f10x_conf.h" +#include "STM32vldiscovery.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define LSE_FAIL_FLAG 0x80 +#define LSE_PASS_FLAG 0x100 +/* Private macro -------------------------------------------------------------*/ +/* Private consts ------------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +u32 LSE_Delay = 0; +u32 count = 0; +u32 BlinkSpeed = 0; +u32 KeyState = 0; +static __IO uint32_t TimingDelay; +/* Private function prototypes -----------------------------------------------*/ +void Delay(uint32_t nTime); +void TimingDelay_Decrement(void); + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief Main program. + * @param None + * @retval None + */ + +int main(void) +{ + /* Enable GPIOx Clock */ + RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); + + /* Initialise LEDs LD3&LD4, both off */ + STM32vldiscovery_LEDInit(LED3); + STM32vldiscovery_LEDInit(LED4); + + STM32vldiscovery_LEDOff(LED3); + STM32vldiscovery_LEDOff(LED4); + + /* Initialise USER Button */ + STM32vldiscovery_PBInit(BUTTON_USER, BUTTON_MODE_GPIO); + + /* Setup SysTick Timer for 1 msec interrupts */ + if (SysTick_Config(SystemCoreClock / 1000)) + { + /* Capture error */ + while (1); + } + + /* Enable access to the backup register => LSE can be enabled */ + PWR_BackupAccessCmd(ENABLE); + + /* Enable LSE (Low Speed External Oscillation) */ + RCC_LSEConfig(RCC_LSE_ON); + + /* Check the LSE Status */ + while(1) + { + if(LSE_Delay < LSE_FAIL_FLAG) + { + /* check whether LSE is ready, with 4 seconds timeout */ + Delay (500); + LSE_Delay += 0x10; + if(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != RESET) + { + /* Set flag: LSE PASS */ + LSE_Delay |= LSE_PASS_FLAG; + /* Turn Off Led4 */ + STM32vldiscovery_LEDOff(LED4); + /* Disable LSE */ + RCC_LSEConfig(RCC_LSE_OFF); + break; + } + } + + /* LSE_FAIL_FLAG = 0x80 */ + else if(LSE_Delay >= LSE_FAIL_FLAG) + { + if(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) + { + /* Set flag: LSE FAIL */ + LSE_Delay |= LSE_FAIL_FLAG; + /* Turn On Led4 */ + STM32vldiscovery_LEDOn(LED4); + } + /* Disable LSE */ + RCC_LSEConfig(RCC_LSE_OFF); + break; + } + } + + /* main while */ + while(1) + { + if(0 == STM32vldiscovery_PBGetState(BUTTON_USER)) + { + if(KeyState == 1) + { + if(0 == STM32vldiscovery_PBGetState(BUTTON_USER)) + { + /* USER Button released */ + KeyState = 0; + /* Turn Off LED4 */ + STM32vldiscovery_LEDOff(LED4); + } + } + } + else if(STM32vldiscovery_PBGetState(BUTTON_USER)) + { + if(KeyState == 0) + { + if(STM32vldiscovery_PBGetState(BUTTON_USER)) + { + /* USER Button released */ + KeyState = 1; + /* Turn ON LED4 */ + STM32vldiscovery_LEDOn(LED4); + Delay(1000); + /* Turn OFF LED4 */ + STM32vldiscovery_LEDOff(LED4); + /* BlinkSpeed: 0 -> 1 -> 2, then re-cycle */ + BlinkSpeed ++ ; + } + } + } + count++; + Delay(100); + /* BlinkSpeed: 0 */ + if(BlinkSpeed == 0) + { + if(4 == (count % 8)) + STM32vldiscovery_LEDOn(LED3); + if(0 == (count % 8)) + STM32vldiscovery_LEDOff(LED3); + } + /* BlinkSpeed: 1 */ + if(BlinkSpeed == 1) + { + if(2 == (count % 4)) + STM32vldiscovery_LEDOn(LED3); + if(0 == (count % 4)) + STM32vldiscovery_LEDOff(LED3); + } + /* BlinkSpeed: 2 */ + if(BlinkSpeed == 2) + { + if(0 == (count % 2)) + STM32vldiscovery_LEDOn(LED3); + else + STM32vldiscovery_LEDOff(LED3); + } + /* BlinkSpeed: 3 */ + else if(BlinkSpeed == 3) + BlinkSpeed = 0; + } +} + +/** + * @brief Inserts a delay time. + * @param nTime: specifies the delay time length, in milliseconds. + * @retval None + */ +void Delay(uint32_t nTime) +{ + TimingDelay = nTime; + + while(TimingDelay != 0); +} + +/** + * @brief Decrements the TimingDelay variable. + * @param None + * @retval None + */ +void TimingDelay_Decrement(void) +{ + if (TimingDelay != 0x00) + { + TimingDelay--; + } +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t* file, uint32_t line) +{ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + + /* Infinite loop */ + while (1) + { + } +} +#endif + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/32vl_factory_demo/stm32f10x_conf.h b/example/32vl_factory_demo/stm32f10x_conf.h new file mode 100644 index 000000000..706b92ed9 --- /dev/null +++ b/example/32vl_factory_demo/stm32f10x_conf.h @@ -0,0 +1,76 @@ +/** + ****************************************************************************** + * @file Demo/inc/stm32f10x_conf.h + * @author MCD Application Team + * @version V1.0.0 + * @date 09/13/2010 + * @brief Library configuration file. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_CONF_H +#define __STM32F10x_CONF_H + +/* Includes ------------------------------------------------------------------*/ +/* Uncomment the line below to enable peripheral header file inclusion */ +/* #include "stm32f10x_adc.h" */ +/* #include "stm32f10x_bkp.h" */ +/* #include "stm32f10x_can.h" */ +/* #include "stm32f10x_crc.h" */ +/* #include "stm32f10x_dac.h" */ +/* #include "stm32f10x_dbgmcu.h" */ +/* #include "stm32f10x_dma.h" */ +#include "stm32f10x_exti.h" +#include "stm32f10x_flash.h" +/* #include "stm32f10x_fsmc.h" */ +#include "stm32f10x_gpio.h" +/* #include "stm32f10x_i2c.h" */ +/* #include "stm32f10x_iwdg.h" */ +#include "stm32f10x_pwr.h" +#include "stm32f10x_rcc.h" +/* #include "stm32f10x_rtc.h" */ +/* #include "stm32f10x_sdio.h" */ +/* #include "stm32f10x_spi.h" */ +/* #include "stm32f10x_tim.h" */ +/* #include "stm32f10x_usart.h" */ +/* #include "stm32f10x_wwdg.h" */ +#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Uncomment the line below to expanse the "assert_param" macro in the + Standard Peripheral Library drivers code */ +/* #define USE_FULL_ASSERT 1 */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT + +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0) +#endif /* USE_FULL_ASSERT */ + +#endif /* __STM32F10x_CONF_H */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/32vl_factory_demo/stm32f10x_it.c b/example/32vl_factory_demo/stm32f10x_it.c new file mode 100644 index 000000000..c1035270e --- /dev/null +++ b/example/32vl_factory_demo/stm32f10x_it.c @@ -0,0 +1,160 @@ +/** + ****************************************************************************** + * @file Demo/src/stm32f10x_it.c + * @author MCD Application Team + * @version V1.0.0 + * @date 09/13/2010 + * @brief Main Interrupt Service Routines. + * This file provides template for all exceptions handler and peripherals + * interrupt service routine. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_it.h" +void TimingDelay_Decrement(void); +/** @addtogroup Demo + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************/ +/* Cortex-M3 Processor Exceptions Handlers */ +/******************************************************************************/ + +/** + * @brief This function handles NMI exception. + * @param None + * @retval None + */ +void NMI_Handler(void) +{ +} + +/** + * @brief This function handles Hard Fault exception. + * @param None + * @retval None + */ +void HardFault_Handler(void) +{ + /* Go to infinite loop when Hard Fault exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles Memory Manage exception. + * @param None + * @retval None + */ +void MemManage_Handler(void) +{ + /* Go to infinite loop when Memory Manage exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles Bus Fault exception. + * @param None + * @retval None + */ +void BusFault_Handler(void) +{ + /* Go to infinite loop when Bus Fault exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles Usage Fault exception. + * @param None + * @retval None + */ +void UsageFault_Handler(void) +{ + /* Go to infinite loop when Usage Fault exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles SVCall exception. + * @param None + * @retval None + */ +void SVC_Handler(void) +{ +} + +/** + * @brief This function handles Debug Monitor exception. + * @param None + * @retval None + */ +void DebugMon_Handler(void) +{ +} + +/** + * @brief This function handles PendSV_Handler exception. + * @param None + * @retval None + */ +void PendSV_Handler(void) +{ +} + +/** + * @brief This function handles SysTick Handler. + * @param None + * @retval None + */ +void SysTick_Handler(void) +{ + TimingDelay_Decrement(); +} + +/******************************************************************************/ +/* STM32F10x Peripherals Interrupt Handlers */ +/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ +/* available peripheral interrupt handler's name please refer to the startup */ +/* file (startup_stm32f10x_xx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles PPP interrupt request. + * @param None + * @retval None + */ +/*void PPP_IRQHandler(void) +{ +}*/ + + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/32vl_factory_demo/stm32f10x_it.h b/example/32vl_factory_demo/stm32f10x_it.h new file mode 100644 index 000000000..e8d2b316e --- /dev/null +++ b/example/32vl_factory_demo/stm32f10x_it.h @@ -0,0 +1,46 @@ +/** + ****************************************************************************** + * @file Demo/inc/stm32f10x_it.h + * @author MCD Team + * @version V1.0.0 + * @date 09/13/2010 + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @copy + * + * 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

+ */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F10x_IT_H +#define __STM32F10x_IT_H + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x.h" + +/* Exported types ------------------------------------------------------------*/ +extern vu32 TickValue; +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); + +#endif /* __STM32F10x_IT_H */ + +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/32vl_factory_demo/system_stm32f10x.c b/example/32vl_factory_demo/system_stm32f10x.c new file mode 100644 index 000000000..aed930ec8 --- /dev/null +++ b/example/32vl_factory_demo/system_stm32f10x.c @@ -0,0 +1,1019 @@ +/** + ****************************************************************************** + * @file system_stm32f10x.c + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File. + ****************************************************************************** + * + * 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 stm32f10x_system + * @{ + */ + +/** @addtogroup STM32F10x_System_Private_Includes + * @{ + */ + +#include "stm32f10x.h" + +/** + * @} + */ + +/** @addtogroup STM32F10x_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F10x_System_Private_Defines + * @{ + */ + +/*!< Uncomment the line corresponding to the desired System clock (SYSCLK) + frequency (after reset the HSI is used as SYSCLK source) + + IMPORTANT NOTE: + ============== + 1. After each device reset the HSI is used as System clock source. + + 2. Please make sure that the selected System clock doesn't exceed your device's + maximum frequency. + + 3. If none of the define below is enabled, the HSI is used as System clock + source. + + 4. The System clock configuration functions provided within this file assume that: + - For Low and Medium density Value line devices an external 8MHz crystal + is used to drive the System clock. + - For Low, Medium and High density devices an external 8MHz crystal is + used to drive the System clock. + - For Connectivity line devices an external 25MHz crystal is used to drive + the System clock. + If you are using different crystal you have to adapt those functions accordingly. + */ + +#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) +/* #define SYSCLK_FREQ_HSE HSE_Value */ + #define SYSCLK_FREQ_24MHz 24000000 +#else +/* #define SYSCLK_FREQ_HSE HSE_Value */ +/* #define SYSCLK_FREQ_24MHz 24000000 */ +/* #define SYSCLK_FREQ_36MHz 36000000 */ +/* #define SYSCLK_FREQ_48MHz 48000000 */ +/* #define SYSCLK_FREQ_56MHz 56000000 */ +#define SYSCLK_FREQ_72MHz 72000000 +#endif + +/*!< Uncomment the following line if you need to use external SRAM mounted + on STM3210E-EVAL board (STM32 High density and XL-density devices) as data memory */ +#if defined (STM32F10X_HD) || (defined STM32F10X_XL) +/* #define DATA_IN_ExtSRAM */ +#endif + +/** + * @} + */ + +/** @addtogroup STM32F10x_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F10x_System_Private_Variables + * @{ + */ + +/******************************************************************************* +* Clock Definitions +*******************************************************************************/ +#ifdef SYSCLK_FREQ_HSE + uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!< System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_24MHz + uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /*!< System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_36MHz + uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz; /*!< System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_48MHz + uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /*!< System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_56MHz + uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /*!< System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_72MHz + uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */ +#else /*!< HSI Selected as System Clock source */ + uint32_t SystemCoreClock = HSI_Value; /*!< System Clock Frequency (Core Clock) */ +#endif + +__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; +/** + * @} + */ + +/** @addtogroup STM32F10x_System_Private_FunctionPrototypes + * @{ + */ + +static void SetSysClock(void); + +#ifdef SYSCLK_FREQ_HSE + static void SetSysClockToHSE(void); +#elif defined SYSCLK_FREQ_24MHz + static void SetSysClockTo24(void); +#elif defined SYSCLK_FREQ_36MHz + static void SetSysClockTo36(void); +#elif defined SYSCLK_FREQ_48MHz + static void SetSysClockTo48(void); +#elif defined SYSCLK_FREQ_56MHz + static void SetSysClockTo56(void); +#elif defined SYSCLK_FREQ_72MHz + static void SetSysClockTo72(void); +#endif + +#ifdef DATA_IN_ExtSRAM + static void SystemInit_ExtMemCtl(void); +#endif /* DATA_IN_ExtSRAM */ + +/** + * @} + */ + +/** @addtogroup STM32F10x_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system + * Initialize the Embedded Flash Interface, the PLL and update the + * SystemCoreClock variable. + * @note This function should be used only after reset. + * @param None + * @retval None + */ +void SystemInit (void) +{ + /* Reset the RCC clock configuration to the default reset state(for debug purpose) */ + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + + /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ +#ifndef STM32F10X_CL + RCC->CFGR &= (uint32_t)0xF8FF0000; +#else + RCC->CFGR &= (uint32_t)0xF0FF0000; +#endif /* STM32F10X_CL */ + + /* Reset HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFFF; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ + RCC->CFGR &= (uint32_t)0xFF80FFFF; + +#ifdef STM32F10X_CL + /* Reset PLL2ON and PLL3ON bits */ + RCC->CR &= (uint32_t)0xEBFFFFFF; + + /* Disable all interrupts and clear pending bits */ + RCC->CIR = 0x00FF0000; + + /* Reset CFGR2 register */ + RCC->CFGR2 = 0x00000000; +#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) + /* Disable all interrupts and clear pending bits */ + RCC->CIR = 0x009F0000; + + /* Reset CFGR2 register */ + RCC->CFGR2 = 0x00000000; +#else + /* Disable all interrupts and clear pending bits */ + RCC->CIR = 0x009F0000; +#endif /* STM32F10X_CL */ + +#if defined (STM32F10X_HD) || (defined STM32F10X_XL) + #ifdef DATA_IN_ExtSRAM + SystemInit_ExtMemCtl(); + #endif /* DATA_IN_ExtSRAM */ +#endif + + /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ + /* Configure the Flash Latency cycles and enable prefetch buffer */ + SetSysClock(); +} + +/** + * @brief Update SystemCoreClock according to Clock Register Values + * @note None + * @param None + * @retval None + */ +void SystemCoreClockUpdate (void) +{ + uint32_t tmp = 0, pllmull = 0, pllsource = 0; + +#ifdef STM32F10X_CL + uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0; +#endif /* STM32F10X_CL */ + +#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) + uint32_t prediv1factor = 0; +#endif /* STM32F10X_LD_VL or STM32F10X_MD_VL */ + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock */ + SystemCoreClock = HSI_Value; + break; + case 0x04: /* HSE used as system clock */ + SystemCoreClock = HSE_Value; + break; + case 0x08: /* PLL used as system clock */ + + /* Get PLL clock source and multiplication factor ----------------------*/ + pllmull = RCC->CFGR & RCC_CFGR_PLLMULL; + pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; + +#ifndef STM32F10X_CL + pllmull = ( pllmull >> 18) + 2; + + if (pllsource == 0x00) + { + /* HSI oscillator clock divided by 2 selected as PLL clock entry */ + SystemCoreClock = (HSI_Value >> 1) * pllmull; + } + else + { + #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) + prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; + /* HSE oscillator clock selected as PREDIV1 clock entry */ + SystemCoreClock = (HSE_Value / prediv1factor) * pllmull; + #else + /* HSE selected as PLL clock entry */ + if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET) + {/* HSE oscillator clock divided by 2 */ + SystemCoreClock = (HSE_Value >> 1) * pllmull; + } + else + { + SystemCoreClock = HSE_Value * pllmull; + } + #endif + } +#else + pllmull = pllmull >> 18; + + if (pllmull != 0x0D) + { + pllmull += 2; + } + else + { /* PLL multiplication factor = PLL input clock * 6.5 */ + pllmull = 13 / 2; + } + + if (pllsource == 0x00) + { + /* HSI oscillator clock divided by 2 selected as PLL clock entry */ + SystemCoreClock = (HSI_Value >> 1) * pllmull; + } + else + {/* PREDIV1 selected as PLL clock entry */ + + /* Get PREDIV1 clock source and division factor */ + prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC; + prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; + + if (prediv1source == 0) + { + /* HSE oscillator clock selected as PREDIV1 clock entry */ + SystemCoreClock = (HSE_Value / prediv1factor) * pllmull; + } + else + {/* PLL2 clock selected as PREDIV1 clock entry */ + + /* Get PREDIV2 division factor and PLL2 multiplication factor */ + prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1; + pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2; + SystemCoreClock = (((HSE_Value / prediv2factor) * pll2mull) / prediv1factor) * pllmull; + } + } +#endif /* STM32F10X_CL */ + break; + + default: + SystemCoreClock = HSI_Value; + 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, HCLK, PCLK2 and PCLK1 prescalers. + * @param None + * @retval None + */ +static void SetSysClock(void) +{ +#ifdef SYSCLK_FREQ_HSE + SetSysClockToHSE(); +#elif defined SYSCLK_FREQ_24MHz + SetSysClockTo24(); +#elif defined SYSCLK_FREQ_36MHz + SetSysClockTo36(); +#elif defined SYSCLK_FREQ_48MHz + SetSysClockTo48(); +#elif defined SYSCLK_FREQ_56MHz + SetSysClockTo56(); +#elif defined SYSCLK_FREQ_72MHz + SetSysClockTo72(); +#endif + + /* If none of the define above is enabled, the HSI is used as System clock + source (default after reset) */ +} + +/** + * @brief Setup the external memory controller. Called in startup_stm32f10x.s + * before jump to __main + * @param None + * @retval None + */ +#ifdef DATA_IN_ExtSRAM +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f10x_xx.s/.c before jump to main. + * This function configures the external SRAM mounted on STM3210E-EVAL + * board (STM32 High density devices). This SRAM will be used as program + * data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ +/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is + required, then adjust the Register Addresses */ + + /* Enable FSMC clock */ + RCC->AHBENR = 0x00000114; + + /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */ + RCC->APB2ENR = 0x000001E0; + +/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/ +/*---------------- SRAM Address lines configuration -------------------------*/ +/*---------------- NOE and NWE configuration --------------------------------*/ +/*---------------- NE3 configuration ----------------------------------------*/ +/*---------------- NBL0, NBL1 configuration ---------------------------------*/ + + GPIOD->CRL = 0x44BB44BB; + GPIOD->CRH = 0xBBBBBBBB; + + GPIOE->CRL = 0xB44444BB; + GPIOE->CRH = 0xBBBBBBBB; + + GPIOF->CRL = 0x44BBBBBB; + GPIOF->CRH = 0xBBBB4444; + + GPIOG->CRL = 0x44BBBBBB; + GPIOG->CRH = 0x44444B44; + +/*---------------- FSMC Configuration ---------------------------------------*/ +/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/ + + FSMC_Bank1->BTCR[4] = 0x00001011; + FSMC_Bank1->BTCR[5] = 0x00000200; +} +#endif /* DATA_IN_ExtSRAM */ + +#ifdef SYSCLK_FREQ_HSE +/** + * @brief Selects HSE as System clock source and configure HCLK, PCLK2 + * and PCLK1 prescalers. + * @note This function should be used only after reset. + * @param None + * @retval None + */ +static void SetSysClockToHSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut)); + + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + +#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL + /* Enable Prefetch Buffer */ + FLASH->ACR |= FLASH_ACR_PRFTBE; + + /* Flash 0 wait state */ + FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); + +#ifndef STM32F10X_CL + FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; +#else + if (HSE_Value <= 24000000) + { + FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; + } + else + { + FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; + } +#endif /* STM32F10X_CL */ +#endif + + /* HCLK = SYSCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; + + /* PCLK2 = HCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; + + /* PCLK1 = HCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; + + /* Select HSE as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSE; + + /* Wait till HSE is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x04) + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +} +#elif defined SYSCLK_FREQ_24MHz +/** + * @brief Sets System clock frequency to 24MHz and configure HCLK, PCLK2 + * and PCLK1 prescalers. + * @note This function should be used only after reset. + * @param None + * @retval None + */ +static void SetSysClockTo24(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut)); + + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { +#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL + /* Enable Prefetch Buffer */ + FLASH->ACR |= FLASH_ACR_PRFTBE; + + /* Flash 0 wait state */ + FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); + FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; +#endif + + /* HCLK = SYSCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; + + /* PCLK2 = HCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; + + /* PCLK1 = HCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; + +#ifdef STM32F10X_CL + /* Configure PLLs ------------------------------------------------------*/ + /* PLL configuration: PLLCLK = PREDIV1 * 6 = 24 MHz */ + RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | + RCC_CFGR_PLLMULL6); + + /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ + /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */ + RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | + RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); + RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | + RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10); + + /* Enable PLL2 */ + RCC->CR |= RCC_CR_PLL2ON; + /* Wait till PLL2 is ready */ + while((RCC->CR & RCC_CR_PLL2RDY) == 0) + { + } +#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) + /* PLL configuration: = (HSE / 2) * 6 = 24 MHz */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2 | RCC_CFGR_PLLMULL6); +#else + /* PLL configuration: = (HSE / 2) * 6 = 24 MHz */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL6); +#endif /* STM32F10X_CL */ + + /* Enable PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Select PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; + + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +} +#elif defined SYSCLK_FREQ_36MHz +/** + * @brief Sets System clock frequency to 36MHz and configure HCLK, PCLK2 + * and PCLK1 prescalers. + * @note This function should be used only after reset. + * @param None + * @retval None + */ +static void SetSysClockTo36(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut)); + + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* Enable Prefetch Buffer */ + FLASH->ACR |= FLASH_ACR_PRFTBE; + + /* Flash 1 wait state */ + FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); + FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; + + /* HCLK = SYSCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; + + /* PCLK2 = HCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; + + /* PCLK1 = HCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; + +#ifdef STM32F10X_CL + /* Configure PLLs ------------------------------------------------------*/ + + /* PLL configuration: PLLCLK = PREDIV1 * 9 = 36 MHz */ + RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | + RCC_CFGR_PLLMULL9); + + /*!< PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ + /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */ + + RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | + RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); + RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | + RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10); + + /* Enable PLL2 */ + RCC->CR |= RCC_CR_PLL2ON; + /* Wait till PLL2 is ready */ + while((RCC->CR & RCC_CR_PLL2RDY) == 0) + { + } + +#else + /* PLL configuration: PLLCLK = (HSE / 2) * 9 = 36 MHz */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL9); +#endif /* STM32F10X_CL */ + + /* Enable PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Select PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; + + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +} +#elif defined SYSCLK_FREQ_48MHz +/** + * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 + * and PCLK1 prescalers. + * @note This function should be used only after reset. + * @param None + * @retval None + */ +static void SetSysClockTo48(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut)); + + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* Enable Prefetch Buffer */ + FLASH->ACR |= FLASH_ACR_PRFTBE; + + /* Flash 1 wait state */ + FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); + FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; + + /* HCLK = SYSCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; + + /* PCLK2 = HCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; + + /* PCLK1 = HCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; + +#ifdef STM32F10X_CL + /* Configure PLLs ------------------------------------------------------*/ + /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ + /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ + + RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | + RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); + RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | + RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); + + /* Enable PLL2 */ + RCC->CR |= RCC_CR_PLL2ON; + /* Wait till PLL2 is ready */ + while((RCC->CR & RCC_CR_PLL2RDY) == 0) + { + } + + + /* PLL configuration: PLLCLK = PREDIV1 * 6 = 48 MHz */ + RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | + RCC_CFGR_PLLMULL6); +#else + /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6); +#endif /* STM32F10X_CL */ + + /* Enable PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Select PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; + + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +} + +#elif defined SYSCLK_FREQ_56MHz +/** + * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 + * and PCLK1 prescalers. + * @note This function should be used only after reset. + * @param None + * @retval None + */ +static void SetSysClockTo56(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut)); + + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* Enable Prefetch Buffer */ + FLASH->ACR |= FLASH_ACR_PRFTBE; + + /* Flash 2 wait state */ + FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); + FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; + + /* HCLK = SYSCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; + + /* PCLK2 = HCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; + + /* PCLK1 = HCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; + +#ifdef STM32F10X_CL + /* Configure PLLs ------------------------------------------------------*/ + /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ + /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ + + RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | + RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); + RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | + RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); + + /* Enable PLL2 */ + RCC->CR |= RCC_CR_PLL2ON; + /* Wait till PLL2 is ready */ + while((RCC->CR & RCC_CR_PLL2RDY) == 0) + { + } + + + /* PLL configuration: PLLCLK = PREDIV1 * 7 = 56 MHz */ + RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | + RCC_CFGR_PLLMULL7); +#else + /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL7); + +#endif /* STM32F10X_CL */ + + /* Enable PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Select PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; + + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +} + +#elif defined SYSCLK_FREQ_72MHz +/** + * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 + * and PCLK1 prescalers. + * @note This function should be used only after reset. + * @param None + * @retval None + */ +static void SetSysClockTo72(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut)); + + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* Enable Prefetch Buffer */ + FLASH->ACR |= FLASH_ACR_PRFTBE; + + /* Flash 2 wait state */ + FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); + FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; + + + /* HCLK = SYSCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; + + /* PCLK2 = HCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; + + /* PCLK1 = HCLK */ + RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; + +#ifdef STM32F10X_CL + /* Configure PLLs ------------------------------------------------------*/ + /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ + /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ + + RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | + RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); + RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | + RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); + + /* Enable PLL2 */ + RCC->CR |= RCC_CR_PLL2ON; + /* Wait till PLL2 is ready */ + while((RCC->CR & RCC_CR_PLL2RDY) == 0) + { + } + + + /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ + RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | + RCC_CFGR_PLLMULL9); +#else + /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | + RCC_CFGR_PLLMULL)); + RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); +#endif /* STM32F10X_CL */ + + /* Enable PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Select PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; + + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +} +#endif + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ From a7c80d038f3bc0ebe3a61e76c26f4dabc25977d8 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 8 Nov 2011 01:13:50 +0000 Subject: [PATCH 0050/1435] Fix linking with new names --- example/32l_dac/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/32l_dac/Makefile b/example/32l_dac/Makefile index 4bd6eb454..87773ef14 100644 --- a/example/32l_dac/Makefile +++ b/example/32l_dac/Makefile @@ -20,7 +20,7 @@ CFLAGS+=-I$(LIBS_STM_PATH)/inc/core_support CFLAGS+=-I$(LIBS_STM_PATH)/inc/device_support CFLAGS+=-I$(LIBS_STM_PATH)/inc/$(PLATFORM) -LDFLAGS+=-L$(LIBS_STM_PATH)/build -lstm32l_discovery +LDFLAGS+=-L$(LIBS_STM_PATH)/build -lstm32_stdperiph_l1xx all: $(BIN_IMAGE) From b48420e3941991b9d3f646e539499327c2417a3c Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 12 Nov 2011 18:21:46 +0000 Subject: [PATCH 0051/1435] Don't refetch the chip id on every single page erase. And update some of the logging to be a bit tidier --- src/stlink-common.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 4286cf001..f7904c0d3 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -135,10 +135,12 @@ static int unlock_flash_if(stlink_t *sl) { if (is_flash_locked(sl)) { unlock_flash(sl); - if (is_flash_locked(sl)) + if (is_flash_locked(sl)) { + WLOG("Failed to unlock flash!\n"); return -1; + } } - + ILOG("Successfully unlocked flash\n"); return 0; } @@ -741,10 +743,16 @@ int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, s return 0; } +/** + * Erase a page of flash, assumes sl is fully populated with things like chip/core ids + * @param sl stlink context + * @param page + * @return 0 on success -ve on failure + */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page) { /* page an addr in the page to erase */ - ILOG("Erasing flash page at addr: %#x\n", page); + ILOG("Erasing flash page at addr: %#x\n", page); if (sl->core_id == STM32L_CORE_ID) { #define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00) @@ -771,7 +779,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page) val = read_uint32(sl->q_buf, 0); if (val & (1 << 0)) { - fprintf(stderr, "pecr.pelock not clear (0x%x)\n", val); + WLOG("pecr.pelock not clear (%#x)\n", val); return -1; } @@ -786,7 +794,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page) val = read_uint32(sl->q_buf, 0); if (val & (1 << 1)) { - fprintf(stderr, "pecr.prglock not clear (0x%x)\n", val); + WLOG("pecr.prglock not clear (%#x)\n", val); return -1; } @@ -994,11 +1002,11 @@ int stlink_fcheck_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned len) { size_t off; flash_loader_t fl; - ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", + ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr); /* check addr range is inside the flash */ if (addr < sl->flash_base) { - WLOG("addr too low\n"); + WLOG("addr too low %#x < %#x\n", addr, sl->flash_base); return -1; } else if ((addr + len) < addr) { WLOG("addr overruns\n"); @@ -1014,6 +1022,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned return -1; } + // Make sure we've loaded the context with the chip details + stlink_core_id(sl); /* erase each page */ int page_count = 0; for (off = 0; off < len; off += sl->flash_pgsz) { @@ -1226,7 +1236,8 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons DLOG("Running flash loader, write address:%#x, size: %zd\n", target, size); // FIXME This can never return -1 if (write_buffer_to_sram(sl, fl, buf, size) == -1) { - fprintf(stderr, "write_buffer_to_sram() == -1\n"); + // IMPOSSIBLE! + WLOG("write_buffer_to_sram() == -1\n"); return -1; } From 2600d78b7cf1910d9d74f5b7057a7ddc6cd3fead Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 14 Nov 2011 02:59:38 +0000 Subject: [PATCH 0052/1435] Start to keep an uptodate list of what's been tested in what combinations --- README | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README b/README index 470c52a59..082a8f26c 100644 --- a/README +++ b/README @@ -119,3 +119,24 @@ Q: At some point I use GDB command `next', and it hangs. A: Sometimes when you will try to use GDB `next' command to skip a loop, it will use a rather inefficient single-stepping way of doing that. Set up a breakpoint manually in that case and do `continue'. + +Currently known working combinations of programmer and target +============================================================= + +STLink v1 (as found on the 32VL Discovery board) + +Known Working Targets: +* STM32F100xx (Medium Density VL) +* STM32F103 (according to jpa- o n##stm32 + +No information: +* everything else! + + +STLink v2 (as found on the 32L and F4 Discovery boards) +Known Working Targets: +* STM32F100xx (Medium Density VL, as on the 32VL Discovery board) +* ? + +Please report any and all known working combinations so I can update this! + From 93da0169c08cb7d81ba2b530ac93482de6ec7bc1 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 14 Nov 2011 03:03:07 +0000 Subject: [PATCH 0053/1435] Remove confusing distclean/clean dichotomy in the top level, make clean cleans all stlink code. in an application level, it only cleans that application --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index d35b3c4f1..f24ed13b0 100644 --- a/Makefile +++ b/Makefile @@ -42,8 +42,6 @@ clean: rm -rf $(LIBRARY) rm -rf test_usb* rm -rf test_sg* - -distclean: clean $(MAKE) -C flash clean $(MAKE) -C gdbserver clean From 55dd45cb49e5a2c639d9f60d3a1de7b1a88b93c2 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 14 Nov 2011 03:24:12 +0000 Subject: [PATCH 0054/1435] Note that many of these "examples" are busted --- example/README | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 example/README diff --git a/example/README b/example/README new file mode 100644 index 000000000..5d72e8282 --- /dev/null +++ b/example/README @@ -0,0 +1,6 @@ +Don't trust many of these examples yet... A lot of them are a work in +progress... + +A good source of examples is in the libopencm3 sources: http://sourceforge.net/projects/libopencm3/ + + From a76c9ccfb34acf2fdca97db1a8e087e43a43d9b0 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 14 Nov 2011 03:47:47 +0000 Subject: [PATCH 0055/1435] Remove lots of dead code and superfluous trace Lots of the debug code is far too verbose for anything but usb tracing. Likewise, remove all the old scsi code that was simply ifdefd out. --- src/stlink-sg.c | 182 ++---------------------------------------------- 1 file changed, 6 insertions(+), 176 deletions(-) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index c4392dbfe..f9170009b 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -113,15 +113,13 @@ static void clear_cdb(struct stlink_libsg *sl) { sl->q_data_dir = Q_DATA_IN; } -// close the device, free the allocated memory - -void _stlink_sg_close(stlink_t *sl) { +/** + * Close and free any _backend_ related information... + * @param sl + */void _stlink_sg_close(stlink_t *sl) { if (sl) { -#if FINISHED_WITH_SG struct stlink_libsg *slsg = sl->backend_data; - scsi_pt_close_device(slsg->sg_fd); free(slsg); -#endif } } @@ -141,11 +139,11 @@ static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t end try++; } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); if (ret != LIBUSB_SUCCESS) { - fprintf(stderr, "%s: receiving failed: %d\n", __func__, ret); + WLOG("%s: receiving failed: %d\n", __func__, ret); return -1; } if (transferred != sizeof(csw)) { - fprintf(stderr, "%s: received unexpected amount: %d\n", __func__, transferred); + WLOG("%s: received unexpected amount: %d\n", __func__, transferred); return -1; } @@ -157,10 +155,8 @@ static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t end WLOG("status signature was invalid: %#x\n", rsig); return -1; } - DLOG("residue was= %#x\n", residue); *tag = rtag; uint8_t rstatus = csw[12]; - DLOG("rstatus = %x\n", rstatus); return rstatus; } @@ -223,11 +219,9 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint memcpy(&(c_buf[i]), cdb, cdb_length); int sending_length = STLINK_SG_SIZE; - DLOG("sending length set to: %d\n", sending_length); // send.... do { - DLOG("attempting tx...\n"); ret = libusb_bulk_transfer(handle, endpoint_out, c_buf, sending_length, &real_transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { @@ -239,7 +233,6 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint WLOG("sending failed: %d\n", ret); return -1; } - DLOG("Actually sent: %d, returning tag: %d\n", real_transferred, tag); return this_tag; } @@ -298,93 +291,6 @@ get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_ou } } - -//TODO rewrite/cleanup, save the error in sl - -#if FINISHED_WITH_SG -static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) { - struct stlink_libsg *sl = stl->backend_data; - const int e = sl->do_scsi_pt_err; - if (e < 0) { - fprintf(stderr, "scsi_pt error: pass through os error: %s\n", - safe_strerror(-e)); - return; - } else if (e == SCSI_PT_DO_BAD_PARAMS) { - fprintf(stderr, "scsi_pt error: bad pass through setup\n"); - return; - } else if (e == SCSI_PT_DO_TIMEOUT) { - fprintf(stderr, " pass through timeout\n"); - return; - } - const int duration = get_scsi_pt_duration_ms(ptvp); - if ((stl->verbose > 1) && (duration >= 0)) - DLOG(" duration=%d ms\n", duration); - - // XXX stlink fw sends broken residue, so ignore it and use the known q_len - // "usb-storage quirks=483:3744:r" - // forces residue to be ignored and calculated, but this causes aboard if - // data_len = 0 and by some other data_len values. - - const int resid = get_scsi_pt_resid(ptvp); - const int dsize = stl->q_len - resid; - - const int cat = get_scsi_pt_result_category(ptvp); - char buf[512]; - unsigned int slen; - - switch (cat) { - case SCSI_PT_RESULT_GOOD: - if (stl->verbose && (resid > 0)) - DLOG(" notice: requested %d bytes but " - "got %d bytes, ignore [broken] residue = %d\n", - stl->q_len, dsize, resid); - break; - case SCSI_PT_RESULT_STATUS: - if (stl->verbose) { - sg_get_scsi_status_str( - get_scsi_pt_status_response(ptvp), sizeof (buf), - buf); - DLOG(" scsi status: %s\n", buf); - } - return; - case SCSI_PT_RESULT_SENSE: - slen = get_scsi_pt_sense_len(ptvp); - if (stl->verbose) { - sg_get_sense_str("", sl->sense_buf, slen, (stl->verbose - > 1), sizeof (buf), buf); - DLOG("%s", buf); - } - if (stl->verbose && (resid > 0)) { - if ((stl->verbose) || (stl->q_len > 0)) - DLOG(" requested %d bytes but " - "got %d bytes\n", stl->q_len, dsize); - } - return; - case SCSI_PT_RESULT_TRANSPORT_ERR: - if (stl->verbose) { - get_scsi_pt_transport_err_str(ptvp, sizeof (buf), buf); - // http://tldp.org/HOWTO/SCSI-Generic-HOWTO/x291.html - // These codes potentially come from the firmware on a host adapter - // or from one of several hosts that an adapter driver controls. - // The 'host_status' field has the following values: - // [0x07] Internal error detected in the host adapter. - // This may not be fatal (and the command may have succeeded). - DLOG(" transport: %s", buf); - } - return; - case SCSI_PT_RESULT_OS_ERR: - if (stl->verbose) { - get_scsi_pt_os_err_str(ptvp, sizeof (buf), buf); - DLOG(" os: %s", buf); - } - return; - default: - fprintf(stderr, " unknown pass through result " - "category (%d)\n", cat); - } -} -#endif - /** * Just send a buffer on an endpoint, no questions asked. * Handles repeats, and time outs. Also handles reading status reports and sense @@ -401,7 +307,6 @@ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, int real_transferred; int try; do { - DLOG("attempting tx...\n"); ret = libusb_bulk_transfer(handle, endpoint_out, cbuf, length, &real_transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { @@ -413,7 +318,6 @@ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, WLOG("sending failed: %d\n", ret); return -1; } - DLOG("Actually sent: %d\n", real_transferred); // now, swallow up the status, so that things behave nicely... uint32_t received_tag; @@ -452,7 +356,6 @@ int stlink_q(stlink_t *sl) { int ret; if (rx_length > 0) { do { - DLOG("attempting rx\n"); ret = libusb_bulk_transfer(sg->usb_handle, sg->ep_rep, sl->q_buf, rx_length, &real_transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { @@ -493,40 +396,6 @@ int stlink_q(stlink_t *sl) { return -1; } return 0; - - - DLOG("Actually received: %d\n", real_transferred); - -#if FINISHED_WITH_SG - // Get control command descriptor of scsi structure, - // (one object per command!!) - struct sg_pt_base *ptvp = construct_scsi_pt_obj(); - if (NULL == ptvp) { - fprintf(stderr, "construct_scsi_pt_obj: out of memory\n"); - return; - } - - set_scsi_pt_cdb(ptvp, sg->cdb_cmd_blk, sizeof (sg->cdb_cmd_blk)); - - // set buffer for sense (error information) data - set_scsi_pt_sense(ptvp, sg->sense_buf, sizeof (sg->sense_buf)); - - // Set a buffer to be used for data transferred from device - if (sg->q_data_dir == Q_DATA_IN) { - //clear_buf(sl); - set_scsi_pt_data_in(ptvp, sl->q_buf, sl->q_len); - } else { - set_scsi_pt_data_out(ptvp, sl->q_buf, sl->q_len); - } - // Executes SCSI command (or at least forwards it to lower layers). - sg->do_scsi_pt_err = do_scsi_pt(ptvp, sg->sg_fd, SG_TIMEOUT_SEC, - sl->verbose); - - // check for scsi errors - stlink_confirm_inq(sl, ptvp); - // TODO recycle: clear_scsi_pt_obj(struct sg_pt_base * objp); - destruct_scsi_pt_obj(ptvp); -#endif } // TODO thinking, cleanup @@ -552,14 +421,11 @@ void stlink_stat(stlink_t *stl, char *txt) { void _stlink_sg_version(stlink_t *stl) { struct stlink_libsg *sl = stl->backend_data; - DLOG("\n*** stlink_version ***\n"); clear_cdb(sl); sl->cdb_cmd_blk[0] = STLINK_GET_VERSION; stl->q_len = 6; sl->q_addr = 0; stlink_q(stl); - // HACK use my own private version right now... - } // Get stlink mode: @@ -681,7 +547,6 @@ void _stlink_sg_reset(stlink_t *sl) { void _stlink_sg_status(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; - DLOG("\n*** stlink_status ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_GETSTATUS; sl->q_len = 2; @@ -693,7 +558,6 @@ void _stlink_sg_status(stlink_t *sl) { void _stlink_sg_force_debug(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; - DLOG("\n*** stlink_force_debug ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_FORCEDEBUG; sl->q_len = 2; @@ -820,7 +684,6 @@ void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { void _stlink_sg_run(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; - DLOG("\n*** stlink_run ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_RUNCORE; sl->q_len = 2; @@ -935,39 +798,6 @@ void _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { stlink_print_data(sl); } -#if 0 /* not working */ - -static int write_flash_mem16 -(struct stlink* sl, uint32_t addr, uint16_t val) { - /* half word writes */ - if (addr % 2) return -1; - - /* unlock if locked */ - unlock_flash_if(sl); - - /* set flash programming chosen bit */ - set_flash_cr_pg(sl); - - write_uint16(sl->q_buf, val); - stlink_write_mem16(sl, addr, 2); - - /* wait for non business */ - wait_flash_busy(sl); - - lock_flash(sl); - - /* check the programmed value back */ - stlink_read_mem16(sl, addr, 2); - if (*(const uint16_t*) sl->q_buf != val) { - /* values differ at i * sizeof(uint16_t) */ - return -1; - } - - /* success */ - return 0; -} -#endif /* not working */ - // Exit the jtag or swd mode and enter the mass mode. void _stlink_sg_exit_debug_mode(stlink_t *stl) { From e509310406ba4db9e88ce7c0ea2aad985cb25008 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 14 Nov 2011 03:52:19 +0000 Subject: [PATCH 0056/1435] Start up stlinkv1 faster. Now that we're not using sg, and we've told the kernel to ignore the device in usb-mass storage, we don't need to close and wait 5 seconds. We can just immediately issue the command to switch modes. --- src/stlink-sg.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index f9170009b..7f0badcfe 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -467,7 +467,7 @@ void _stlink_sg_enter_jtag_mode(stlink_t *sl) { } // XXX kernel driver performs reset, the device temporally disappears - +// Suspect this is no longer the case when we have ignore on? RECHECK void _stlink_sg_exit_dfu_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_exit_dfu_mode ***\n"); @@ -964,18 +964,6 @@ stlink_t* stlink_v1_open_inner(const int verbose) { DLOG("Attempting to exit DFU mode\n"); _stlink_sg_exit_dfu_mode(sl); - // exit the dfu mode -> the device is gone - DLOG("\n*** reopen the stlink device ***\n"); - delay(1000); - stlink_close(sl); - delay(5000); - - DLOG("Attempting to reopen the stlink...\n"); - sl = stlink_open(verbose); - if (sl == NULL) { - fputs("Error: could not open stlink device\n", stderr); - return NULL; - } // re-query device info (and retest) stlink_version(sl); if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { From d019d3fc4f34297a78bf8c38c5a06053b2707862 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 14 Nov 2011 04:11:10 +0000 Subject: [PATCH 0057/1435] Turn down default logging level. And remove dead/duplicate code that is included in the opening of the device --- gdbserver/gdb-server.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index ce0549e7a..e7676219c 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -21,7 +21,7 @@ #include "gdb-remote.h" -#define DEFAULT_LOGGING_LEVEL 100 +#define DEFAULT_LOGGING_LEVEL 50 #define DEFAULT_GDB_LISTEN_PORT 4242 #define STRINGIFY_inner(name) #name @@ -169,17 +169,8 @@ int main(int argc, char** argv) { break; } - // ALLLL of this should move into "stlink_open_xxx" - - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { - if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { - stlink_exit_dfu_mode(sl); - } - stlink_enter_swd_mode(sl); - } - - uint32_t chip_id = stlink_chip_id(sl); - uint32_t core_id = stlink_core_id(sl); + uint32_t chip_id = sl->chip_id; + uint32_t core_id = sl->core_id; /* Fix chip_id for F4 */ if (((chip_id & 0xFFF) == 0x411) && (core_id == CORE_M4_R0)) { From dbe5391bd1354d651cda7c10be3c4b601ea4cdc9 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 14 Nov 2011 04:12:29 +0000 Subject: [PATCH 0058/1435] Remove dead code and unused variables --- src/stlink-common.c | 4 ++-- src/stlink-sg.c | 8 -------- src/stlink-usb.c | 31 ------------------------------- 3 files changed, 2 insertions(+), 41 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index f7904c0d3..a853d13ad 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -314,7 +314,7 @@ void stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { */ int stlink_load_device_params(stlink_t *sl) { ILOG("Loading device parameters....\n"); - chip_params_t *params = NULL; + const chip_params_t *params = NULL; uint32_t chip_id = stlink_chip_id(sl); sl->chip_id = chip_id; for(size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { @@ -547,7 +547,7 @@ void stlink_core_stat(stlink_t *sl) { } void stlink_print_data(stlink_t * sl) { - if (sl->q_len <= 0 || sl->verbose < 2) + if (sl->q_len <= 0 || sl->verbose < UDEBUG) return; if (sl->verbose > 2) fprintf(stdout, "data_len = %d 0x%x\n", sl->q_len, sl->q_len); diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 7f0badcfe..b6ac4963b 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -97,14 +97,6 @@ #define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args) #define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args) -// Suspends execution of the calling process for -// (at least) ms milliseconds. - -static void delay(int ms) { - //fprintf(stderr, "*** wait %d ms\n", ms); - usleep(1000 * ms); -} - static void clear_cdb(struct stlink_libsg *sl) { for (size_t i = 0; i < sizeof (sl->cdb_cmd_blk); i++) sl->cdb_cmd_blk[i] = 0; diff --git a/src/stlink-usb.c b/src/stlink-usb.c index b4df70efb..58c4e1d33 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -150,33 +150,6 @@ static inline int send_only } -/* 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; - - if (desc.idVendor != USB_ST_VID) - return 0; - - 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 version; -} - static int fill_command (stlink_t * sl, enum SCSI_Generic_Direction dir, uint32_t len) { struct stlink_libusb * const slu = sl->backend_data; @@ -580,11 +553,7 @@ stlink_t* stlink_open_usb(const int verbose) { struct stlink_libusb* slu = NULL; 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)); From 9ac1f0d9d69d7f30a932fcc8977d40b12a9377f6 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 14 Nov 2011 04:12:49 +0000 Subject: [PATCH 0059/1435] Fix memory leaks closing v1 hardware. Thanks valgrind --- src/stlink-sg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index b6ac4963b..062e83dbd 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -111,6 +111,8 @@ static void clear_cdb(struct stlink_libsg *sl) { */void _stlink_sg_close(stlink_t *sl) { if (sl) { struct stlink_libsg *slsg = sl->backend_data; + libusb_close(slsg->usb_handle); + libusb_exit(slsg->libusb_ctx); free(slsg); } } From 09d732d776a869d1f8cbfcb62bbed4b0a9c79a4d Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 14 Nov 2011 04:14:41 +0000 Subject: [PATCH 0060/1435] Keep netbeans happy --- nbproject/Package-flash.bash | 75 +++ nbproject/configurations.xml | 1208 ++++++++++------------------------ nbproject/project.xml | 4 - 3 files changed, 411 insertions(+), 876 deletions(-) create mode 100644 nbproject/Package-flash.bash diff --git a/nbproject/Package-flash.bash b/nbproject/Package-flash.bash new file mode 100644 index 000000000..44fd0fc43 --- /dev/null +++ b/nbproject/Package-flash.bash @@ -0,0 +1,75 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_PLATFORM=GNU-Linux-x86 +CND_CONF=flash +CND_DISTDIR=dist +CND_BUILDDIR=build +NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=MissingOutputInProject +OUTPUT_BASENAME=MissingOutputInProject +PACKAGE_TOP_DIR=stlink/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package +rm -rf ${NBTMPDIR} +mkdir -p ${NBTMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory "${NBTMPDIR}/stlink" +copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/stlink.tar +cd ${NBTMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/stlink.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${NBTMPDIR} diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index e129c44f6..f1fcd48d1 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -7,21 +7,42 @@ - - main.c - - + + discover_board.h main.c startup_stm32l1xx_md.s system_stm32l1xx.c - + discover_board.h main.c stm32l_discovery_lcd.c stm32l_discovery_lcd.h - + + main.c + startup_stm32f10x_md_vl.S + stm32f10x_conf.h + stm32f10x_it.c + stm32f10x_it.h + system_stm32f10x.c + + + main.c + + + discover_board.h + main.c + startup_stm32l1xx_md.s + system_stm32l1xx.c + + + + STM32vldiscovery.c + STM32vldiscovery.h + + + @@ -33,71 +54,149 @@ core_cm3.h + stm32f10x.h stm32l1xx.h + system_stm32f10x.h system_stm32l1xx.h - misc.h - stm32l1xx_adc.h - stm32l1xx_comp.h - stm32l1xx_crc.h - stm32l1xx_dac.h - stm32l1xx_dbgmcu.h - stm32l1xx_dma.h - stm32l1xx_exti.h - stm32l1xx_flash.h - stm32l1xx_gpio.h - stm32l1xx_i2c.h - stm32l1xx_iwdg.h - stm32l1xx_lcd.h - stm32l1xx_pwr.h - stm32l1xx_rcc.h - stm32l1xx_rtc.h - stm32l1xx_spi.h - stm32l1xx_syscfg.h - stm32l1xx_tim.h - stm32l1xx_usart.h - stm32l1xx_wwdg.h + + misc.h + stm32f10x_adc.h + stm32f10x_bkp.h + stm32f10x_can.h + stm32f10x_cec.h + stm32f10x_crc.h + stm32f10x_dac.h + stm32f10x_dbgmcu.h + stm32f10x_dma.h + stm32f10x_exti.h + stm32f10x_flash.h + stm32f10x_fsmc.h + stm32f10x_gpio.h + stm32f10x_i2c.h + stm32f10x_iwdg.h + stm32f10x_pwr.h + stm32f10x_rcc.h + stm32f10x_rtc.h + stm32f10x_sdio.h + stm32f10x_spi.h + stm32f10x_tim.h + stm32f10x_usart.h + stm32f10x_wwdg.h + + + misc.h + stm32l1xx_adc.h + stm32l1xx_comp.h + stm32l1xx_crc.h + stm32l1xx_dac.h + stm32l1xx_dbgmcu.h + stm32l1xx_dma.h + stm32l1xx_exti.h + stm32l1xx_flash.h + stm32l1xx_gpio.h + stm32l1xx_i2c.h + stm32l1xx_iwdg.h + stm32l1xx_lcd.h + stm32l1xx_pwr.h + stm32l1xx_rcc.h + stm32l1xx_rtc.h + stm32l1xx_spi.h + stm32l1xx_syscfg.h + stm32l1xx_tim.h + stm32l1xx_usart.h + stm32l1xx_wwdg.h + - misc.c - stm32l1xx_adc.c - stm32l1xx_comp.c - stm32l1xx_crc.c - stm32l1xx_dac.c - stm32l1xx_dbgmcu.c - stm32l1xx_dma.c - stm32l1xx_exti.c - stm32l1xx_flash.c - stm32l1xx_flash_ramfunc.c - stm32l1xx_gpio.c - stm32l1xx_i2c.c - stm32l1xx_iwdg.c - stm32l1xx_lcd.c - stm32l1xx_pwr.c - stm32l1xx_rcc.c - stm32l1xx_rtc.c - stm32l1xx_spi.c - stm32l1xx_syscfg.c - stm32l1xx_tim.c - stm32l1xx_usart.c - stm32l1xx_wwdg.c + + misc.c + stm32f10x_adc.c + stm32f10x_bkp.c + stm32f10x_can.c + stm32f10x_cec.c + stm32f10x_crc.c + stm32f10x_dac.c + stm32f10x_dbgmcu.c + stm32f10x_dma.c + stm32f10x_exti.c + stm32f10x_flash.c + stm32f10x_fsmc.c + stm32f10x_gpio.c + stm32f10x_i2c.c + stm32f10x_iwdg.c + stm32f10x_pwr.c + stm32f10x_rcc.c + stm32f10x_rtc.c + stm32f10x_sdio.c + stm32f10x_spi.c + stm32f10x_tim.c + stm32f10x_usart.c + stm32f10x_wwdg.c + + + misc.c + stm32l1xx_adc.c + stm32l1xx_comp.c + stm32l1xx_crc.c + stm32l1xx_dac.c + stm32l1xx_dbgmcu.c + stm32l1xx_dma.c + stm32l1xx_exti.c + stm32l1xx_flash.c + stm32l1xx_flash_ramfunc.c + stm32l1xx_gpio.c + stm32l1xx_i2c.c + stm32l1xx_iwdg.c + stm32l1xx_lcd.c + stm32l1xx_pwr.c + stm32l1xx_rcc.c + stm32l1xx_rtc.c + stm32l1xx_spi.c + stm32l1xx_syscfg.c + stm32l1xx_tim.c + stm32l1xx_usart.c + stm32l1xx_wwdg.c + - - discover_board.h - discover_functions.c - discover_functions.h - icc_measure.c - icc_measure.h - icc_measure_Ram.c - main.c - stm32_tsl_conf.h - stm32l1xx_conf.h - stm32l1xx_it.c - stm32l1xx_it.h - stm32l_discovery_lcd.c - stm32l_discovery_lcd.h - system_stm32l1xx.c + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -154,18 +253,22 @@ ${MAKE} -f Makefile ${MAKE} -f Makefile clean gdbserver/st-util - - - . - - - DEBUG=1 - - + + + + + + - + - + - - - - - - + - + - + + + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + . + + + DEBUG=1 + + + + + + + src + + + CONFIG_USE_LIBUSB=1 + DEBUG + + + src - CONFIG_USE_LIBSG=1 CONFIG_USE_LIBUSB=1 - - - - - - + + + + . + + + DEBUG=1 + + + - + LOCAL_SOURCES default - gdbserver + flash ${MAKE} -f Makefile ${MAKE} -f Makefile clean + + + DEBUG + + + + @@ -519,685 +631,37 @@ tool="0" flavor="0"> - - - - - - - - - - - - - - - - - - - - - - - + + + + src + + + CONFIG_USE_LIBUSB=1 + + + + + + + src + + + CONFIG_USE_LIBSG=1 + CONFIG_USE_LIBUSB=1 + + + + + + + . + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - src - - - CONFIG_USE_LIBSG=1 - CONFIG_USE_LIBUSB=1 - - - - - - - . - - - DEBUG=1 - - - - - - - - - - - LOCAL_SOURCES - default - - - - flash - ${MAKE} -f Makefile - ${MAKE} -f Makefile clean - - - - DEBUG - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - src - - - CONFIG_USE_LIBSG=1 - CONFIG_USE_LIBUSB=1 - - - - - - - src - - - CONFIG_USE_LIBSG=1 - CONFIG_USE_LIBUSB=1 - - - - - - - . - - - DEBUG=1 - - - - + diff --git a/nbproject/project.xml b/nbproject/project.xml index 946c06f6f..7526e4b6b 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -17,10 +17,6 @@ Default 0 - - gdbserver - 0 - flash 0 From 93b186f15b493728d1662f4a6f96aae835962f02 Mon Sep 17 00:00:00 2001 From: jnosky Date: Mon, 14 Nov 2011 16:15:31 -0500 Subject: [PATCH 0061/1435] Removed comment about STM32F4 limitations --- README | 3 --- 1 file changed, 3 deletions(-) diff --git a/README b/README index b980bbf0c..f85c6815a 100644 --- a/README +++ b/README @@ -76,9 +76,6 @@ If you would link your executable to 0x08000000 and then do (gdb) load firmware.elf then it would be written to the memory. -STM32F4: -The flash utility supports the full 1MB address space. -The gdbserver only supports up to 64kB applications at the moment. FAQ === From 67db39b0b31dc76dcc83405f7dba28ee04f90432 Mon Sep 17 00:00:00 2001 From: jnosky Date: Mon, 14 Nov 2011 16:16:57 -0500 Subject: [PATCH 0062/1435] Changed size argument to hex Address was hex, size was decimal. Now uniform to be hex --- flash/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flash/main.c b/flash/main.c index 46a8ce171..f1d0b4f84 100644 --- a/flash/main.c +++ b/flash/main.c @@ -21,6 +21,7 @@ static void usage(void) { puts("stlinkv1 command line: ./flash {read|write} /dev/sgX path addr "); puts("stlinkv2 command line: ./flash {read|write} path addr "); + puts(" use hex format for addr and "); } static int get_opts(struct opts* o, int ac, char** av) @@ -46,7 +47,7 @@ static int get_opts(struct opts* o, int ac, char** av) i = 1; } - o->size = strtoul(av[i + 3], NULL, 10); + o->size = strtoul(av[i + 3], NULL, 16); } else if (strcmp(av[0], "write") == 0) { From 768a70d3213fcfcd605961a770c5446276fd1df8 Mon Sep 17 00:00:00 2001 From: jnosky Date: Mon, 14 Nov 2011 16:20:49 -0500 Subject: [PATCH 0063/1435] Added code so gdbserver can fully support the STM32F4 variable page sizes gdbserver can now upload up to 1MB projects to flash --- gdbserver/gdb-server.c | 120 ++++++++++++++++++++++++++--------------- src/stlink-common.c | 79 ++++++++++++++------------- src/stlink-common.h | 3 +- 3 files changed, 122 insertions(+), 80 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 371d779d7..b5d66dff5 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -21,9 +21,9 @@ #include "gdb-remote.h" #define FLASH_BASE 0x08000000 + +//Allways update the FLASH_PAGE before each use, by calling stlink_calculate_pagesize #define FLASH_PAGE (sl->flash_pgsz) -#define FLASH_PAGE_MASK (~((1 << 10) - 1)) -#define FLASH_SIZE (FLASH_PAGE * 128) volatile int do_exit = 0; void ctrl_c(int sig) @@ -44,19 +44,19 @@ struct chip_params { uint32_t bootrom_base, bootrom_size; } const devices[] = { { 0x410, "F1 Medium-density device", 0x1ffff7e0, - 0x20000, 0x400, 0x5000, 0x1ffff000, 0x800 }, // table 2, pm0063 + 0x20000, 0x400, 0x5000, 0x1ffff000, 0x800 }, // table 2, pm0063 { 0x411, "F2 device", 0, /* No flash size register found in the docs*/ - 0x100000, 0x20000, 0x20000, 0x1fff0000, 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 - /*No flash size register? page size is variable */ - { 0x413, "F4 device", 0x1FFF7A10, - 0x100000, 0x4000, 0x30000, 0x1fff0000, 0x7800 }, // table 1, pm0081 + 0x8000, 0x400, 0x2800, 0x1ffff000, 0x800 }, // table 1, pm0063 + /*Page size is variable */ + { 0x413, "F4 device", 0x1FFF7A10, //RM0090 error same as unique ID + 0x100000, 0x4000, 0x30000, 0x1fff0000, 0x7800 }, // table 1, pm0081 { 0x414, "F1 High-density device", 0x1ffff7e0, - 0x80000, 0x800, 0x10000, 0x1ffff000, 0x800 }, // table 3 pm0063 + 0x80000, 0x800, 0x10000, 0x1ffff000, 0x800 }, // table 3 pm0063 // This ignores the EEPROM! (and uses the page erase size, // not the sector write protection...) - { 0x416, "L1 Med-density device", 0x1FF8004C, // table 1, pm0062 + { 0x416, "L1 Med-density device", 0x1FF8004C, // table 1, pm0062 0x20000, 0x100, 0x4000, 0x1ff00000, 0x1000 }, { 0x418, "F1 Connectivity line device", 0x1ffff7e0, 0x40000, 0x800, 0x10000, 0x1fffb000, 0x4800 }, @@ -64,18 +64,19 @@ struct chip_params { 0x20000, 0x400, 0x2000, 0x1ffff000, 0x800 }, { 0x428, "F1 High-density value line device", 0x1ffff7e0, 0x80000, 0x800, 0x8000, 0x1ffff000, 0x800 }, - { 0x430, "F1 XL-density device", 0x1ffff7e0, // pm0068 + { 0x430, "F1 XL-density device", 0x1ffff7e0, // pm0068 0x100000, 0x800, 0x18000, 0x1fffe000, 0x1800 }, { 0 } }; int serve(stlink_t *sl, int port); -char* make_memory_map(const struct chip_params *params, uint32_t flash_size); +char* make_memory_map(stlink_t *sl, const struct chip_params *params, uint32_t flash_size); int main(int argc, char** argv) { stlink_t *sl = NULL; - int port = 0; + int port = 0; + uint32_t flash_size; const char * HelpStr = "\nUsage:\n" "\tst-util [Arguments]\n" @@ -209,24 +210,29 @@ int main(int argc, char** argv) { } printf("Device connected: %s\n", params->description); - printf("Device parameters: SRAM: 0x%x bytes, Flash: up to 0x%x bytes in pages of 0x%x bytes\n", - params->sram_size, params->max_flash_size, params->flash_pagesize); - - FLASH_PAGE = params->flash_pagesize; - - //sl->flash_pgsz=0x4000; - //sl->flash_size=0x100000; - - uint32_t flash_size; - stlink_read_mem32(sl, params->flash_size_reg, 4); - flash_size = sl->q_buf[0] | (sl->q_buf[1] << 8); + if(sl->chip_id==STM32F4_CHIP_ID) { + flash_size=0x100000; //todo: RM0090 error; size register same address as unique ID + printf("Device parameters: SRAM: 0x%x bytes, Flash: up to 0x%x bytes with variable page size\n", + params->sram_size, flash_size); + } + else { + printf("Device parameters: SRAM: 0x%x bytes, Flash: up to 0x%x bytes in pages of 0x%x bytes\n", + params->sram_size, params->max_flash_size, params->flash_pagesize); + stlink_read_mem32(sl, params->flash_size_reg, 4); + flash_size = sl->q_buf[0] | (sl->q_buf[1] << 8); + //flash_size_reg is in 1k blocks. + flash_size *= 0x400; + } - //flash_size=0x100000; + /* Init PAGE_SIZE for fixed page size devices. + * stlink_calculate_pagesize will then return this value for them. + * variable pagesize devices must allways update FLASH_PAGE before use! */ + FLASH_PAGE = params->flash_pagesize; + sl->flash_size=flash_size; - printf("Flash size is %d KiB.\n", flash_size); - // memory map is in 1k blocks. - current_memory_map = make_memory_map(params, flash_size * 0x400); + printf("Flash size is %d\n", flash_size); + current_memory_map = make_memory_map(sl, params, flash_size); while(serve(sl, port) == 0); @@ -238,6 +244,28 @@ int main(int argc, char** argv) { return 0; } +static const char* const memory_map_template_F4 = + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // sram + " " //Sectors 0..3 + " 0x4000" //16kB + " " + " " //Sector 4 + " 0x10000" //64kB + " " + " " //Sectors 5..11 + " 0x20000" //128kB + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + " " // option byte area + ""; + static const char* const memory_map_template = "" "" // option byte area ""; -char* make_memory_map(const struct chip_params *params, uint32_t flash_size) { +char* make_memory_map(stlink_t *sl, const struct chip_params *params, uint32_t flash_size) { /* This will be freed in serve() */ char* map = malloc(4096); map[0] = '\0'; - snprintf(map, 4096, memory_map_template, - flash_size, - params->sram_size, - flash_size, params->flash_pagesize, - params->bootrom_base, params->bootrom_size); - + if(sl->chip_id==STM32F4_CHIP_ID) { + strcpy(map, memory_map_template_F4); + } + + else { + snprintf(map, 4096, memory_map_template, + flash_size, + params->sram_size, + flash_size, params->flash_pagesize, + params->bootrom_base, params->bootrom_size); + } return map; } @@ -491,13 +524,14 @@ struct flash_block { static struct flash_block* flash_root; -static int flash_add_block(stm32_addr_t addr, unsigned length, - stlink_t *sl) { - if(addr < FLASH_BASE || addr + length > FLASH_BASE + FLASH_SIZE) { +static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { + + if(addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) { fprintf(stderr, "flash_add_block: incorrect bounds\n"); return -1; } + stlink_calculate_pagesize(sl, addr); if(addr % FLASH_PAGE != 0 || length % FLASH_PAGE != 0) { fprintf(stderr, "flash_add_block: unaligned block\n"); return -1; @@ -568,18 +602,18 @@ static int flash_go(stlink_t *sl) { unsigned length = fb->length; for(stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += FLASH_PAGE) { + + //Update FLASH_PAGE + stlink_calculate_pagesize(sl, page); + #ifdef DEBUG printf("flash_do: page %08x\n", page); #endif - //todo:write flash already does erase so why is this here? - stlink_erase_flash_page(sl, page); - if(stlink_write_flash(sl, page, fb->data + (page - fb->addr), length > FLASH_PAGE ? FLASH_PAGE : length) < 0) goto error; - } - + } } stlink_reset(sl); diff --git a/src/stlink-common.c b/src/stlink-common.c index fcdb405ff..d55dff687 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1,4 +1,4 @@ - +#define DEBUG_FLASH 0 #include #include @@ -148,8 +148,10 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { stlink_read_mem32(sl, FLASH_F4_CR, sizeof (uint32_t)); else stlink_read_mem32(sl, FLASH_CR, sizeof (uint32_t)); - fprintf(stdout, "CR:%X\n", *(uint32_t*) sl->q_buf); - return *(uint32_t*) sl->q_buf; +#if DEBUG_FLASH + fprintf(stdout, "CR:0x%x\n", *(uint32_t*) sl->q_buf); +#endif + return *(uint32_t*) sl->q_buf; } static inline unsigned int is_flash_locked(stlink_t *sl) { @@ -281,7 +283,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { stlink_read_mem32(sl, FLASH_F4_SR, sizeof (uint32_t)); else stlink_read_mem32(sl, FLASH_SR, sizeof (uint32_t)); - //fprintf(stdout, "SR:%X\n", *(uint32_t*) sl->q_buf); + //fprintf(stdout, "SR:0x%x\n", *(uint32_t*) sl->q_buf); return *(uint32_t*) sl->q_buf; } @@ -323,7 +325,9 @@ static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n) { uint32_t x = read_flash_cr(sl); x &= ~(0x03 << 8); x |= (n << 8); - fprintf(stdout, "PSIZ:%X %X\n", x, n); +#if DEBUG_FLASH + fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n); +#endif write_uint32(sl->q_buf, x); stlink_write_mem32(sl, FLASH_F4_CR, sizeof (uint32_t)); } @@ -334,7 +338,9 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { x &= ~FLASH_F4_CR_SNB_MASK; x |= (n << FLASH_F4_CR_SNB); x |= (1 << FLASH_F4_CR_SER); - fprintf(stdout, "SNB:%X %X\n", x, n); +#if DEBUG_FLASH + fprintf(stdout, "SNB:0x%x 0x%x\n", x, n); +#endif write_uint32(sl->q_buf, x); stlink_write_mem32(sl, FLASH_F4_CR, sizeof (uint32_t)); } @@ -393,7 +399,7 @@ void stlink_identify_device(stlink_t *sl) { (sl->q_buf[3] << 24); /* 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"); + //printf("Fixing wrong chip_id for STM32F4 Rev A errata\n"); chip_id = 0x413; } sl->chip_id=chip_id; @@ -816,17 +822,17 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ } -uint32_t calculate_sectorsize(stlink_t *sl, uint32_t flashaddr){ +uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ if(sl->chip_id == STM32F4_CHIP_ID) { uint32_t sector=calculate_F4_sectornum(flashaddr); - if (sector<4) return (0x4000); - else if(sector<5) return(0x10000); - else return(0x20000); + if (sector<4) sl->flash_pgsz=0x4000; + else if(sector<5) sl->flash_pgsz=0x10000; + else sl->flash_pgsz=0x20000; } - else return (sl->flash_pgsz); + return (sl->flash_pgsz); } -int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page) +int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { /* page an addr in the page to erase */ @@ -841,13 +847,11 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page) unlock_flash_if(sl); /* select the page to erase */ - //Page is passed to us as an addr, so calculate the actual page - uint32_t addr=page; - - page=calculate_F4_sectornum(addr); + // calculate the actual page from the address + uint32_t sector=calculate_F4_sectornum(flashaddr); - fprintf(stderr, "Erasing Sector:%u SectorSize:%u\n", page, calculate_sectorsize(sl, addr)); - write_flash_cr_snb(sl, page); + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x\n", sector, stlink_calculate_pagesize(sl, flashaddr)); + write_flash_cr_snb(sl, sector); /* start erase operation */ set_flash_cr_strt(sl); @@ -858,8 +862,9 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page) /* relock the flash */ //todo: fails to program if this is in lock_flash(sl); - fprintf(stdout, "Erase Final CR:%X\n", read_flash_cr(sl)); - +#if DEBUG_FLASH + fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); +#endif } else if (sl->core_id == STM32L_CORE_ID) @@ -928,7 +933,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page) /* write 0 to the first word of the page to be erased */ memset(sl->q_buf, 0, sizeof(uint32_t)); - stlink_write_mem32(sl, page, sizeof(uint32_t)); + stlink_write_mem32(sl, flashaddr, sizeof(uint32_t)); /* reset lock bits */ stlink_read_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); @@ -948,7 +953,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page) set_flash_cr_per(sl); /* select the page to erase */ - write_flash_ar(sl, page); + write_flash_ar(sl, flashaddr); /* start erase operation, reset by hw with bsy bit */ set_flash_cr_strt(sl); @@ -1068,7 +1073,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { } else { - fprintf(stderr, "unknown coreid: %x\n", sl->core_id); + fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id); return -1; } @@ -1104,12 +1109,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned stlink_identify_device(sl); -#if 0 /* todo: use in debugging mode only */ - fprintf(stdout, "WriteFlash - addr:%x len:%x\n", addr, len); - fprintf(stdout, "CoreID:%X ChipID:%X\n", sl->core_id, sl->chip_id); -#endif - /* check addr range is inside the flash */ + stlink_calculate_pagesize(sl, addr); if (addr < sl->flash_base) { fprintf(stderr, "addr too low\n"); return -1; @@ -1128,14 +1129,20 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned } /* erase each page */ - for (off = 0; off < len; off += calculate_sectorsize(sl, addr + off) ) { - /* addr must be an addr inside the page */ + for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + off) ) { + //addr must be an addr inside the page if (stlink_erase_flash_page(sl, addr + off) == -1) { fprintf(stderr, "erase_flash_page(0x%zx) == -1\n", addr + off); return -1; } } +#if 1 /* todo: use in debugging mode only */ + fprintf(stdout, "WriteFlash - Addr:0x%x len:0x%x\n", addr, len); + //fprintf(stdout, "CoreID:0x%x ChipID:0x%x\n", sl->core_id, sl->chip_id); +#endif + + if (sl->chip_id == STM32F4_CHIP_ID) { /* todo: check write operation */ @@ -1172,7 +1179,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned lock_flash(sl); #if 0 /* todo: debug mode */ - fprintf(stdout, "Final CR:%X\n", read_flash_cr(sl)); + fprintf(stdout, "Final CR:0x%x\n", read_flash_cr(sl)); #endif @@ -1262,7 +1269,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned if (off % sl->flash_pgsz) off &= ~(sl->flash_pgsz - 1); page = addr + off; - fprintf(stderr, "invalid write @%x(%x): %x != %x. retrying.\n", + fprintf(stderr, "invalid write @0x%x(0x%x): 0x%x != 0x%x. retrying.\n", page, addr + off, read_uint32(base + off, 0), read_uint32(sl->q_buf, 0)); /* reset lock bits */ @@ -1343,7 +1350,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned if (aligned_size & (4 - 1)) aligned_size = (cmp_size + 4) & ~(4 - 1); - fprintf(stdout, "AlignedSize:%x\n", aligned_size); + fprintf(stdout, "AlignedSize:0x%x\n", aligned_size); stlink_read_mem32(sl, addr + off, aligned_size); if (memcmp(sl->q_buf, base + off, cmp_size)) @@ -1409,7 +1416,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ } else { - fprintf(stderr, "unknown coreid: %x\n", sl->core_id); + fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id); return -1; } @@ -1441,7 +1448,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } else { - fprintf(stderr, "unknown coreid: %x\n", sl->core_id); + fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id); return -1; } diff --git a/src/stlink-common.h b/src/stlink-common.h index 2230dca83..1d9e38781 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -243,7 +243,8 @@ extern "C" { // privates, publics, the rest.... // TODO sort what is private, and what is not - int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t page); + int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); + uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); uint16_t read_uint16(const unsigned char *c, const int pt); void stlink_core_stat(stlink_t *sl); void stlink_print_data(stlink_t *sl); From b55b75c3b98f4b80334cd8fb742e06e0ebe9b981 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 14 Nov 2011 23:01:03 +0000 Subject: [PATCH 0064/1435] Remove final reference to old sg/usb compilation flags --- flash/Makefile | 1 - gdbserver/Makefile | 1 - 2 files changed, 2 deletions(-) diff --git a/flash/Makefile b/flash/Makefile index dc16b62a9..412c366e5 100644 --- a/flash/Makefile +++ b/flash/Makefile @@ -1,5 +1,4 @@ CFLAGS+=-g -CFLAGS+=-DCONFIG_USE_LIBUSB=1 CFLAGS+=-DDEBUG CFLAGS+=-std=gnu99 CFLAGS+=-Wall -Wextra diff --git a/gdbserver/Makefile b/gdbserver/Makefile index c0b927e20..c81ea52b8 100644 --- a/gdbserver/Makefile +++ b/gdbserver/Makefile @@ -2,7 +2,6 @@ PRG := st-util OBJS = gdb-remote.o gdb-server.o CFLAGS+=-g -Wall -Werror -std=gnu99 -I../src -CFLAGS+=-DCONFIG_USE_LIBUSB=1 LDFLAGS=-L.. -lstlink -lusb-1.0 all: $(PRG) From 8542b23c6e899fbb0ecc7f6de27eed8133988003 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 14 Nov 2011 23:32:50 +0000 Subject: [PATCH 0065/1435] Update readme, as this is about to get messy! --- README | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README b/README index 470c52a59..28caaf878 100644 --- a/README +++ b/README @@ -1,3 +1,11 @@ +IMPORTANT SHORT TERM NOTICE: +If you are targetting F1 devices, with either stlinkv1 or v2 hardware, you +_need_ to use karlp's libwork2 branch. + +If you are targetting F4, you _need_ to use texane's master + +If you are targetting F2 or L1, please let us know how it goes! + HOWTO ===== From fd332562a79737a73c8a7e7c66b4ebbe999829be Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 15 Nov 2011 19:56:14 +0000 Subject: [PATCH 0066/1435] Fix merge problem with flash verify for F4 The F4 code had #ifdefd out the verification, as the page/sector size can be too large to read in via a single transfer. Pull the verification out to a separate function, the flash write was getting far too large anyway. --- src/stlink-common.c | 64 +++++++++++++++++++++++++++++---------------- src/stlink-common.h | 1 + 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 214f6c573..3b84cc689 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1148,6 +1148,46 @@ int stlink_fcheck_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { return res; } +/** + * Verify addr..addr+len is binary identical to base...base+len + * @param sl stlink context + * @param address stm device address + * @param data host side buffer to check against + * @param length how much + * @return 0 for success, -ve for failure + */ +int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, unsigned length) { + size_t off; + if ((sl->chip_id & 0xFFF) == STM32_CHIPID_F4) { + DLOG("(FIXME)Skipping verification for F4, not enough ram (yet)\n"); + return 0; + } + ILOG("Starting verification of write complete\n"); + for (off = 0; off < length; off += sl->flash_pgsz) { + size_t aligned_size; + + /* adjust last page size */ + size_t cmp_size = sl->flash_pgsz; + if ((off + sl->flash_pgsz) > length) + cmp_size = length - off; + + aligned_size = cmp_size; + if (aligned_size & (4 - 1)) + aligned_size = (cmp_size + 4) & ~(4 - 1); + + fprintf(stdout, "AlignedSize:%#zx\n", aligned_size); + stlink_read_mem32(sl, address + off, aligned_size); + + if (memcmp(sl->q_buf, data + off, cmp_size)) { + WLOG("Verification of flash failed at offset: %zd\n", off); + return -1; + } + } + ILOG("Flash written and verified! jolly good!\n"); + return 0; + +} + int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned len) { size_t off; flash_loader_t fl; @@ -1370,28 +1410,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned WLOG("unknown coreid, not sure how to write: %x\n", sl->core_id); return -1; } - - ILOG("Starting verification of write complete\n"); - for (off = 0; off < len; off += sl->flash_pgsz) { - size_t aligned_size; - - /* adjust last page size */ - size_t cmp_size = sl->flash_pgsz; - if ((off + sl->flash_pgsz) > len) - cmp_size = len - off; - - aligned_size = cmp_size; - if (aligned_size & (4 - 1)) - aligned_size = (cmp_size + 4) & ~(4 - 1); - - fprintf(stdout, "AlignedSize:%#zx\n", aligned_size); - stlink_read_mem32(sl, addr + off, aligned_size); - - if (memcmp(sl->q_buf, base + off, cmp_size)) - return -1; - } - ILOG("Flash written and verified! jolly good!\n"); - return 0; + + return stlink_verify_write_flash(sl, addr, base, len); } /** diff --git a/src/stlink-common.h b/src/stlink-common.h index 82967d4b5..ae02961a0 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -348,6 +348,7 @@ extern "C" { int stlink_erase_flash_mass(stlink_t* sl); int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, unsigned length); int stlink_fwrite_flash(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, unsigned length); // PUBLIC uint32_t stlink_chip_id(stlink_t *sl); From 49569ccd6bc04e7b4bcdf974433f9201fc93a337 Mon Sep 17 00:00:00 2001 From: Fabien Le Mentec Date: Sun, 20 Nov 2011 15:54:00 -0600 Subject: [PATCH 0067/1435] [update] blink_flash makefile --- example/32l_dac/Makefile | 2 +- example/blink_flash/Makefile | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/example/32l_dac/Makefile b/example/32l_dac/Makefile index 87773ef14..6c1844169 100644 --- a/example/32l_dac/Makefile +++ b/example/32l_dac/Makefile @@ -28,7 +28,7 @@ $(BIN_IMAGE): $(EXECUTABLE) $(OBJCOPY) -O binary $^ $@ $(EXECUTABLE): main.c system_stm32l1xx.c startup_stm32l1xx_md.s - $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) clean: rm -rf $(EXECUTABLE) diff --git a/example/blink_flash/Makefile b/example/blink_flash/Makefile index 46117311e..1696bf5f0 100644 --- a/example/blink_flash/Makefile +++ b/example/blink_flash/Makefile @@ -19,11 +19,16 @@ CFLAGS+=-ffreestanding -nostdlib -nostdinc # to run from FLASH CFLAGS+=-Wl,-T,stm32_flash.ld +PLATFORM=stm32l1xx +LIBS_STM_PATH=../libs_stm + # stm32l_discovery lib -CFLAGS+=-I../libstm32l_discovery/inc -CFLAGS+=-I../libstm32l_discovery/inc/base -CFLAGS+=-I../libstm32l_discovery/inc/core_support -CFLAGS+=-I../libstm32l_discovery/inc/device_support +CFLAGS+=-I$(LIBS_STM_PATH)/inc/base +CFLAGS+=-I$(LIBS_STM_PATH)/inc/core_support +CFLAGS+=-I$(LIBS_STM_PATH)/inc/device_support +CFLAGS+=-I$(LIBS_STM_PATH)/inc/$(PLATFORM) + +LDFLAGS+=-L$(LIBS_STM_PATH)/build -lstm32_stdperiph_l1xx all: $(BIN_IMAGE) @@ -31,10 +36,13 @@ $(BIN_IMAGE): $(EXECUTABLE) $(OBJCOPY) -O binary $^ $@ $(EXECUTABLE): main.c system_stm32l1xx.c startup_stm32l1xx_md.s - $(CC) $(CFLAGS) $^ -o $@ -L../libstm32l_discovery/build -lstm32l_discovery + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) clean: rm -rf $(EXECUTABLE) rm -rf $(BIN_IMAGE) +write: all + sudo ../../flash/flash write ./blink.bin 0x08000000 + .PHONY: all clean From e9586c100e33fe72e4528b21768bd155a68517e2 Mon Sep 17 00:00:00 2001 From: le mentec fabien Date: Tue, 22 Nov 2011 09:39:58 -0600 Subject: [PATCH 0068/1435] [update] apply patches from marpe@mimuw.edu.pl for flash tool: verbosity, run after programm\ --- AUTHORS | 3 ++- flash/main.c | 14 +++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index 105e25b6b..f60ebcaa2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -11,4 +11,5 @@ nelsonjm@macpod.neta ned@bike-nomad.com csamuelson@swingpal.com bravikov@gmail.com -jnosky - codegrinder69@hotmail.com \ No newline at end of file +jnosky - codegrinder69@hotmail.com +marpe@mimuw.edu.pl diff --git a/flash/main.c b/flash/main.c index 563748923..8781941cc 100644 --- a/flash/main.c +++ b/flash/main.c @@ -80,6 +80,7 @@ int main(int ac, char** av) struct opts o; int err = -1; + o.size = 0; if (get_opts(&o, ac - 1, av + 1) == -1) { printf("invalid command line\n"); @@ -89,12 +90,14 @@ int main(int ac, char** av) if (o.devname != NULL) /* stlinkv1 */ { - sl = stlink_v1_open(100); + sl = stlink_v1_open(50); + sl->verbose = 50; if (sl == NULL) goto on_error; } else /* stlinkv2 */ { - sl = stlink_open_usb(100); + sl = stlink_open_usb(50); + sl->verbose = 50; if (sl == NULL) goto on_error; } @@ -129,7 +132,12 @@ int main(int ac, char** av) err = 0; on_error: - if (sl != NULL) stlink_close(sl); + if (sl != NULL) + { + stlink_reset(sl); + stlink_run(sl); + stlink_close(sl); + } return err; } From bd1249c224ee462ea11c63e67ff95cb48b8b28ba Mon Sep 17 00:00:00 2001 From: le mentec fabien Date: Tue, 22 Nov 2011 09:54:55 -0600 Subject: [PATCH 0069/1435] [update] apply patches from marpe@mimuw.edu.pl: strict aliasing issues, busy bit waiting --- src/stlink-common.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 3b84cc689..aafd9d29f 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -122,17 +122,17 @@ uint32_t read_uint32(const unsigned char *c, const int pt) { static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { stlink_read_mem32(sl, FLASH_WRPR, sizeof (uint32_t)); - return (*(uint32_t*) sl->q_buf) & 0xff; + return read_uint32(sl->q_buf, 0) & 0xff; } static inline uint32_t read_flash_wrpr(stlink_t *sl) { stlink_read_mem32(sl, FLASH_WRPR, sizeof (uint32_t)); - return *(uint32_t*) sl->q_buf; + return read_uint32(sl->q_buf, 0); } static inline uint32_t read_flash_obr(stlink_t *sl) { stlink_read_mem32(sl, FLASH_OBR, sizeof (uint32_t)); - return *(uint32_t*) sl->q_buf; + return read_uint32(sl->q_buf, 0); } static inline uint32_t read_flash_cr(stlink_t *sl) { @@ -143,7 +143,7 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { #if DEBUG_FLASH fprintf(stdout, "CR:0x%x\n", *(uint32_t*) sl->q_buf); #endif - return *(uint32_t*) sl->q_buf; + return read_uint32(sl->q_buf, 0); } static inline unsigned int is_flash_locked(stlink_t *sl) { @@ -269,7 +269,7 @@ static void set_flash_cr_strt(stlink_t *sl) { static inline uint32_t read_flash_acr(stlink_t *sl) { stlink_read_mem32(sl, FLASH_ACR, sizeof (uint32_t)); - return *(uint32_t*) sl->q_buf; + return read_uint32(sl->q_buf, 0); } static inline uint32_t read_flash_sr(stlink_t *sl) { @@ -278,7 +278,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { else stlink_read_mem32(sl, FLASH_SR, sizeof (uint32_t)); //fprintf(stdout, "SR:0x%x\n", *(uint32_t*) sl->q_buf); - return *(uint32_t*) sl->q_buf; + return read_uint32(sl->q_buf, 0); } static inline unsigned int is_flash_busy(stlink_t *sl) { @@ -969,17 +969,36 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) write_uint32(sl->q_buf, val); stlink_write_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); - /* wait for sr.busy to be cleared */ +#if 0 /* fix_to_be_confirmed */ + + /* wait for sr.busy to be cleared + MP: Test shows that busy bit is not set here. Perhaps, PM0062 is + wrong and we do not need to wait here for clearing the busy bit. + TEXANE: ok, if experience says so and it works for you, we comment + it. If someone has a problem, please drop an email. + */ while (1) { stlink_read_mem32(sl, STM32L_FLASH_SR, sizeof(uint32_t)); if ((read_uint32(sl->q_buf, 0) & (1 << 0)) == 0) break ; } +#endif /* fix_to_be_confirmed */ + /* write 0 to the first word of the page to be erased */ memset(sl->q_buf, 0, sizeof(uint32_t)); stlink_write_mem32(sl, flashaddr, sizeof(uint32_t)); + /* MP: It is better to wait for clearing the busy bit after issuing + page erase command, even though PM0062 recommends to wait before it. + Test shows that a few iterations is performed in the following loop + before busy bit is cleared.*/ + while (1) + { + stlink_read_mem32(sl, STM32L_FLASH_SR, sizeof(uint32_t)); + if ((read_uint32(sl->q_buf, 0) & (1 << 0)) == 0) break; + } + /* reset lock bits */ stlink_read_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); val = read_uint32(sl->q_buf, 0) | (1 << 0) | (1 << 1) | (1 << 2); @@ -1175,7 +1194,6 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, if (aligned_size & (4 - 1)) aligned_size = (cmp_size + 4) & ~(4 - 1); - fprintf(stdout, "AlignedSize:%#zx\n", aligned_size); stlink_read_mem32(sl, address + off, aligned_size); if (memcmp(sl->q_buf, data + off, cmp_size)) { @@ -1272,7 +1290,6 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned else if (sl->core_id == STM32L_CORE_ID) { /* use fast word write. todo: half page. */ - uint32_t val; #if 0 /* todo: check write operation */ From 592276c9398aec17067731327587554cf6e2861b Mon Sep 17 00:00:00 2001 From: le mentec fabien Date: Tue, 22 Nov 2011 10:04:36 -0600 Subject: [PATCH 0070/1435] [update] apply patches from marpe@mimuw.edu.pl: stlink-sg.c unused/uninitialized variables --- src/stlink-sg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 062e83dbd..50c0db505 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -143,7 +143,7 @@ static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t end uint32_t rsig = read_uint32(csw, 0); uint32_t rtag = read_uint32(csw, 4); - uint32_t residue = read_uint32(csw, 8); + /* uint32_t residue = read_uint32(csw, 8); */ #define USB_CSW_SIGNATURE 0x53425355 // 'U' 'S' 'B' 'S' (reversed) if (rsig != USB_CSW_SIGNATURE) { WLOG("status signature was invalid: %#x\n", rsig); @@ -299,7 +299,7 @@ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, unsigned char endpoint_in, unsigned char *cbuf, unsigned int length) { int ret; int real_transferred; - int try; + int try = 0; do { ret = libusb_bulk_transfer(handle, endpoint_out, cbuf, length, &real_transferred, SG_TIMEOUT_MSEC); From 2edd0530a6d3dfc428bedc3d9628093775673389 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 10 Dec 2011 17:15:48 +0100 Subject: [PATCH 0071/1435] Only call strtoul when there is an argument that strtoul can work on --- flash/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flash/main.c b/flash/main.c index 8781941cc..39910b636 100644 --- a/flash/main.c +++ b/flash/main.c @@ -48,8 +48,8 @@ static int get_opts(struct opts* o, int ac, char** av) o->devname = av[1]; i = 1; } - - o->size = strtoul(av[i + 3], NULL, 16); + if (ac > 3) + o->size = strtoul(av[i + 3], NULL, 16); } else if (strcmp(av[0], "write") == 0) { From bcee01d7052c208e039a241c90138448b969d2ff Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 10 Dec 2011 17:17:25 +0100 Subject: [PATCH 0072/1435] Chevck first for NULL before writing anything to the alloceted structure --- flash/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flash/main.c b/flash/main.c index 39910b636..9033b17b6 100644 --- a/flash/main.c +++ b/flash/main.c @@ -91,14 +91,14 @@ int main(int ac, char** av) if (o.devname != NULL) /* stlinkv1 */ { sl = stlink_v1_open(50); - sl->verbose = 50; if (sl == NULL) goto on_error; + sl->verbose = 50; } else /* stlinkv2 */ { sl = stlink_open_usb(50); - sl->verbose = 50; if (sl == NULL) goto on_error; + sl->verbose = 50; } if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) From c1130cc3a68f158632ce0a92d3ff61b7d6795e69 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 10 Dec 2011 17:59:20 +0100 Subject: [PATCH 0073/1435] Fix memory leakage pathe with no V2 device found --- src/stlink-usb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 58c4e1d33..1320831d1 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -576,9 +576,8 @@ stlink_t* stlink_open_usb(const int verbose) { slu->usb_handle = libusb_open_device_with_vid_pid(slu->libusb_ctx, USB_ST_VID, USB_STLINK_32L_PID); if (slu->usb_handle == NULL) { // TODO - free usb context too... - free(slu); WLOG("Couldn't find any ST-Link/V2 devices"); - return NULL; + goto on_error; } if (libusb_kernel_driver_active(slu->usb_handle, 0) == 1) { @@ -660,6 +659,8 @@ stlink_t* stlink_open_usb(const int verbose) { return sl; on_error: + if( slu->libusb_ctx) + libusb_exit(slu->libusb_ctx); if (sl != NULL) free(sl); if (slu != NULL) free(slu); return 0; From 48b604040a78177c9695396710d75d0194935228 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 10 Dec 2011 18:08:06 +0100 Subject: [PATCH 0074/1435] Fix leakage pathes for V1 --- src/stlink-sg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 50c0db505..394417b18 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -857,6 +857,7 @@ static stlink_t* stlink_open(const int verbose) { if (slsg->usb_handle == NULL) { WLOG("Failed to find an stlink v1 by VID:PID\n"); libusb_close(slsg->usb_handle); + libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); return NULL; @@ -871,6 +872,7 @@ static stlink_t* stlink_open(const int verbose) { if (r < 0) { WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-r)); libusb_close(slsg->usb_handle); + libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); return NULL; @@ -883,6 +885,7 @@ static stlink_t* stlink_open(const int verbose) { /* this may fail for a previous configured device */ WLOG("libusb_get_configuration()\n"); libusb_close(slsg->usb_handle); + libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); return NULL; @@ -897,6 +900,7 @@ static stlink_t* stlink_open(const int verbose) { /* this may fail for a previous configured device */ WLOG("libusb_set_configuration() failed\n"); libusb_close(slsg->usb_handle); + libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); return NULL; @@ -906,6 +910,7 @@ static stlink_t* stlink_open(const int verbose) { if (libusb_claim_interface(slsg->usb_handle, 0)) { WLOG("libusb_claim_interface() failed\n"); libusb_close(slsg->usb_handle); + libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); return NULL; From face2e7babe4046dd931a93f74eee5cb5f9a4a53 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 10 Dec 2011 18:22:51 +0100 Subject: [PATCH 0075/1435] Add explicit dependancy on the stlink archive --- flash/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flash/Makefile b/flash/Makefile index 412c366e5..cb7dcd2c2 100644 --- a/flash/Makefile +++ b/flash/Makefile @@ -13,7 +13,7 @@ NAME=flash all: $(NAME) -$(NAME): $(OBJS) +$(NAME): $(OBJS) ../libstlink.a $(CC) $(CFLAGS) -o $(NAME) $(OBJS) $(LDFLAGS) %.o: %.c From e82da443bf0f113f7fc3cad71322a69f0db22360 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 10 Dec 2011 19:01:52 +0100 Subject: [PATCH 0076/1435] Print undecode chip_id too --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index aafd9d29f..ab145104c 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -457,7 +457,7 @@ int stlink_load_device_params(stlink_t *sl) { sl->sys_base = params->bootrom_base; sl->sys_size = params->bootrom_size; - ILOG("Device connected is: %s\n", params->description); + ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); // TODO make note of variable page size here..... ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %zd bytes\n", sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, From b1e89edb578e70e4fffa83394a24d8733e78143b Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 10 Dec 2011 21:27:54 +0100 Subject: [PATCH 0077/1435] More files to ignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index c23c60a36..8e974b74b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,7 @@ flash/flash *.log example/*/*.bin example/*/*.elf +example/*/*/*.bin +example/*/*/*/*.bin +example/*/*/*.a +example/*/*/*/*.a From 28956cf2c9f52b13245d0b6a9529f7f06c972aff Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Mon, 12 Dec 2011 15:22:19 +0100 Subject: [PATCH 0078/1435] Expose JTAG NRST --- src/stlink-common.c | 5 +++++ src/stlink-common.h | 3 +++ src/stlink-sg.c | 14 ++++++++++++++ src/stlink-usb.c | 21 +++++++++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index ab145104c..c614677d1 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -470,6 +470,11 @@ void stlink_reset(stlink_t *sl) { sl->backend->reset(sl); } +void stlink_jtag_reset(stlink_t *sl, int value) { + DLOG("*** stlink_jtag_reset ***\n"); + sl->backend->jtag_reset(sl, value); +} + void stlink_run(stlink_t *sl) { DLOG("*** stlink_run ***\n"); sl->backend->run(sl); diff --git a/src/stlink-common.h b/src/stlink-common.h index ae02961a0..b2a4adc5b 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -70,6 +70,7 @@ extern "C" { // TODO - possible poor names... #define STLINK_SWD_ENTER 0x30 #define STLINK_SWD_READCOREID 0x32 // TBD +#define STLINK_JTAG_DRIVE_NRST 0x3c // cortex m3 technical reference manual #define CM3_REG_CPUID 0xE000ED00 @@ -267,6 +268,7 @@ extern "C" { void (*exit_dfu_mode) (stlink_t * stl); void (*core_id) (stlink_t * stl); void (*reset) (stlink_t * stl); + void (*jtag_reset) (stlink_t * stl, int value); void (*run) (stlink_t * stl); void (*status) (stlink_t * stl); void (*version) (stlink_t *sl); @@ -330,6 +332,7 @@ extern "C" { void stlink_close(stlink_t *sl); uint32_t stlink_core_id(stlink_t *sl); void stlink_reset(stlink_t *sl); + void stlink_jtag_reset(stlink_t *sl, int value); void stlink_run(stlink_t *sl); void stlink_status(stlink_t *sl); void stlink_version(stlink_t *sl); diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 394417b18..0e4504c7f 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -537,6 +537,19 @@ void _stlink_sg_reset(stlink_t *sl) { stlink_stat(sl, "core reset"); } +// Arm-core reset -> halted state. + +void _stlink_sg_jtag_reset(stlink_t *sl, int value) { + struct stlink_libsg *sg = sl->backend_data; + clear_cdb(sg); + sg->cdb_cmd_blk[1] = STLINK_JTAG_DRIVE_NRST; + sg->cdb_cmd_blk[2] = (value)?0:1; + sl->q_len = 3; + sg->q_addr = 2; + stlink_q(sl); + stlink_stat(sl, "core reset"); +} + // Arm-core status: halted or running. void _stlink_sg_status(stlink_t *sl) { @@ -820,6 +833,7 @@ stlink_backend_t _stlink_sg_backend = { _stlink_sg_exit_dfu_mode, _stlink_sg_core_id, _stlink_sg_reset, + _stlink_sg_jtag_reset, _stlink_sg_run, _stlink_sg_status, _stlink_sg_version, diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 1320831d1..678e4c42b 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -348,6 +348,26 @@ void _stlink_usb_reset(stlink_t * sl) { } +void _stlink_usb_jtag_reset(stlink_t * sl, int value) { + struct stlink_libusb * const slu = sl->backend_data; + 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); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_JTAG_DRIVE_NRST; + cmd[i++] = (value)?0:1; + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { + printf("[!] send_recv\n"); + return; + } +} + + void _stlink_usb_step(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; @@ -533,6 +553,7 @@ stlink_backend_t _stlink_usb_backend = { _stlink_usb_exit_dfu_mode, _stlink_usb_core_id, _stlink_usb_reset, + _stlink_usb_jtag_reset, _stlink_usb_run, _stlink_usb_status, _stlink_usb_version, From 3e72f0b1b3c289ec2c3e7dce5f39c350b5584dbd Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 13 Dec 2011 13:27:32 +0100 Subject: [PATCH 0079/1435] Implement and expose single 32 memory read/write --- src/stlink-common.c | 11 +++++++++++ src/stlink-common.h | 7 +++++++ src/stlink-sg.c | 30 ++++++++++++++++++++++++++++++ src/stlink-usb.c | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index c614677d1..8bc2a8bf0 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -529,6 +529,17 @@ void stlink_version(stlink_t *sl) { } } +uint32_t stlink_read_debug32(stlink_t *sl, uint32_t addr) { + uint32_t data = sl->backend->read_debug32(sl, addr); + DLOG("*** stlink_read_debug32 %x is %#x\n", data, addr); + return data; +} + +void stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { + DLOG("*** stlink_write_debug32 %x to %#x\n", data, addr); + sl->backend->write_debug32(sl, addr, data); +} + void stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); if (len % 4 != 0) { diff --git a/src/stlink-common.h b/src/stlink-common.h index b2a4adc5b..a9834a476 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -70,6 +70,9 @@ extern "C" { // TODO - possible poor names... #define STLINK_SWD_ENTER 0x30 #define STLINK_SWD_READCOREID 0x32 // TBD +#define STLINK_JTAG_WRITEDEBUG_32BIT 0x35 +#define STLINK_JTAG_READDEBUG_32BIT 0x36 +#define STLINK_JTAG_DRIVE_NRST 0x3c #define STLINK_JTAG_DRIVE_NRST 0x3c // cortex m3 technical reference manual @@ -272,7 +275,9 @@ extern "C" { void (*run) (stlink_t * stl); void (*status) (stlink_t * stl); void (*version) (stlink_t *sl); + uint32_t (*read_debug32) (stlink_t *sl, uint32_t addr); void (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); + void (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); void (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); void (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); void (*read_all_regs) (stlink_t *sl, reg * regp); @@ -336,7 +341,9 @@ extern "C" { void stlink_run(stlink_t *sl); void stlink_status(stlink_t *sl); void stlink_version(stlink_t *sl); + uint32_t stlink_read_debug32(stlink_t *sl, uint32_t addr); void stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); + void stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); void stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); void stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); void stlink_read_all_regs(stlink_t *sl, reg *regp); diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 0e4504c7f..197d59b29 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -805,6 +805,34 @@ void _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { stlink_print_data(sl); } +// Write one DWORD data to memory + +void _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { + struct stlink_libsg *sg = sl->backend_data; + clear_cdb(sg); + sg->cdb_cmd_blk[1] = STLINK_JTAG_WRITEDEBUG_32BIT; + // 2-5: addr + write_uint32(sg->cdb_cmd_blk + 2, addr); + write_uint32(sg->cdb_cmd_blk + 6, data); + sl->q_len = 2; + stlink_q(sl); + +} + +// Read one DWORD data from memory + +uint32_t _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr) { + struct stlink_libsg *sg = sl->backend_data; + clear_cdb(sg); + sg->cdb_cmd_blk[1] = STLINK_JTAG_READDEBUG_32BIT; + // 2-5: addr + write_uint32(sg->cdb_cmd_blk + 2, addr); + sl->q_len = 8; + stlink_q(sl); + + return read_uint32(sl->q_buf, 4); +} + // Exit the jtag or swd mode and enter the mass mode. void _stlink_sg_exit_debug_mode(stlink_t *stl) { @@ -837,7 +865,9 @@ stlink_backend_t _stlink_sg_backend = { _stlink_sg_run, _stlink_sg_status, _stlink_sg_version, + _stlink_sg_read_debug32, _stlink_sg_read_mem32, + _stlink_sg_write_debug32, _stlink_sg_write_mem32, _stlink_sg_write_mem8, _stlink_sg_read_all_regs, diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 678e4c42b..4f8debc94 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -189,6 +189,44 @@ void _stlink_usb_version(stlink_t *sl) { } } +uint32_t _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const rdata = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + const int rep_len = 8; + + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_JTAG_READDEBUG_32BIT; + write_uint32(&cmd[i], addr); + size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); + if (size == -1) { + printf("[!] send_recv\n"); + return; + } + return read_uint32(rdata, 4); +} + +void _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const rdata = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + const int rep_len = 2; + + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_JTAG_WRITEDEBUG_32BIT; + write_uint32(&cmd[i], addr); + write_uint32(&cmd[i + 4], data); + size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); + if (size == -1) { + printf("[!] send_recv\n"); + return; + } +} + 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 data = sl->q_buf; @@ -557,7 +595,9 @@ stlink_backend_t _stlink_usb_backend = { _stlink_usb_run, _stlink_usb_status, _stlink_usb_version, + _stlink_usb_read_debug32, _stlink_usb_read_mem32, + _stlink_usb_write_debug32, _stlink_usb_write_mem32, _stlink_usb_write_mem8, _stlink_usb_read_all_regs, From 5eda4566d617fedd2a9d3020ddae06b394d08a5f Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 13 Dec 2011 17:48:54 +0100 Subject: [PATCH 0080/1435] Determine the device parameters explicit after running stlink_reset(). Otherwise a sleeping device (WFI) doesn't return the parameters. --- flash/main.c | 1 + src/stlink-sg.c | 1 - src/stlink-usb.c | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/flash/main.c b/flash/main.c index 9033b17b6..609a6f7d3 100644 --- a/flash/main.c +++ b/flash/main.c @@ -108,6 +108,7 @@ int main(int ac, char** av) stlink_enter_swd_mode(sl); stlink_reset(sl); + stlink_load_device_params(sl); if (o.do_read == 0) /* write */ { diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 197d59b29..991bc878b 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -1025,7 +1025,6 @@ stlink_t* stlink_v1_open(const int verbose) { } // by now, it _must_ be fully open and in a useful mode.... stlink_enter_swd_mode(sl); - stlink_load_device_params(sl); ILOG("Successfully opened a stlink v1 debugger\n"); return sl; } diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 4f8debc94..f0a469511 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -702,7 +702,6 @@ stlink_t* stlink_open_usb(const int verbose) { } stlink_version(sl); - stlink_load_device_params(sl); error = 0; From 9ef6d28cb5751c0cf589136181569f585059a8bc Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 13 Dec 2011 18:41:07 +0100 Subject: [PATCH 0081/1435] Modify shutdown seqeunce. Now a F107 in sleep mode reacts on the reset pin after running stlink --- flash/main.c | 3 +-- src/stlink-common.c | 1 + src/stlink-common.h | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/flash/main.c b/flash/main.c index 609a6f7d3..106e52c29 100644 --- a/flash/main.c +++ b/flash/main.c @@ -135,8 +135,7 @@ int main(int ac, char** av) on_error: if (sl != NULL) { - stlink_reset(sl); - stlink_run(sl); + stlink_exit_debug_mode(sl); stlink_close(sl); } diff --git a/src/stlink-common.c b/src/stlink-common.c index 8bc2a8bf0..74c5bcc7c 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -359,6 +359,7 @@ void stlink_close(stlink_t *sl) { void stlink_exit_debug_mode(stlink_t *sl) { DLOG("*** stlink_exit_debug_mode ***\n"); + stlink_write_debug32(sl, DHCSR, DBGKEY); sl->backend->exit_debug_mode(sl); } diff --git a/src/stlink-common.h b/src/stlink-common.h index a9834a476..a1442f366 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -112,6 +112,11 @@ extern "C" { /* using chip id for F4 ident, since core id is same as F1 */ #define STM32F4_CHIP_ID 0x413 +/* Cortex™-M3 Technical Reference Manual */ +/* Debug Halting Control and Status Register */ +#define DHCSR 0xe000edf0 +#define DBGKEY 0xa05f0000 + /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ #define C_BUF_LEN 32 From 03e745140d9f599801df2b779f051f7f23586b65 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 13 Dec 2011 19:56:10 +0100 Subject: [PATCH 0082/1435] Use the single WORD memory access --- src/stlink-common.c | 171 ++++++++++++++++---------------------------- 1 file changed, 62 insertions(+), 109 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 74c5bcc7c..79650ede5 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -121,29 +121,27 @@ uint32_t read_uint32(const unsigned char *c, const int pt) { } static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { - stlink_read_mem32(sl, FLASH_WRPR, sizeof (uint32_t)); - return read_uint32(sl->q_buf, 0) & 0xff; + return stlink_read_debug32(sl, FLASH_WRPR) & 0xff; } static inline uint32_t read_flash_wrpr(stlink_t *sl) { - stlink_read_mem32(sl, FLASH_WRPR, sizeof (uint32_t)); - return read_uint32(sl->q_buf, 0); + return stlink_read_debug32(sl, FLASH_WRPR); } static inline uint32_t read_flash_obr(stlink_t *sl) { - stlink_read_mem32(sl, FLASH_OBR, sizeof (uint32_t)); - return read_uint32(sl->q_buf, 0); + return stlink_read_debug32(sl, FLASH_OBR); } static inline uint32_t read_flash_cr(stlink_t *sl) { + uint32_t res; if(sl->chip_id==STM32F4_CHIP_ID) - stlink_read_mem32(sl, FLASH_F4_CR, sizeof (uint32_t)); + res = stlink_read_debug32(sl, FLASH_F4_CR); else - stlink_read_mem32(sl, FLASH_CR, sizeof (uint32_t)); + res = stlink_read_debug32(sl, FLASH_CR); #if DEBUG_FLASH - fprintf(stdout, "CR:0x%x\n", *(uint32_t*) sl->q_buf); + fprintf(stdout, "CR:0x%x\n", res); #endif - return read_uint32(sl->q_buf, 0); + return res; } static inline unsigned int is_flash_locked(stlink_t *sl) { @@ -161,16 +159,12 @@ static void unlock_flash(stlink_t *sl) { the FPEC block until next reset. */ if(sl->chip_id==STM32F4_CHIP_ID) { - write_uint32(sl->q_buf, FLASH_KEY1); - stlink_write_mem32(sl, FLASH_F4_KEYR, sizeof (uint32_t)); - write_uint32(sl->q_buf, FLASH_KEY2); - stlink_write_mem32(sl, FLASH_F4_KEYR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); + stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); } else { - write_uint32(sl->q_buf, FLASH_KEY1); - stlink_write_mem32(sl, FLASH_KEYR, sizeof (uint32_t)); - write_uint32(sl->q_buf, FLASH_KEY2); - stlink_write_mem32(sl, FLASH_KEYR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY1); + stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY2); } } @@ -192,14 +186,12 @@ static int unlock_flash_if(stlink_t *sl) { static void lock_flash(stlink_t *sl) { if(sl->chip_id==STM32F4_CHIP_ID) { const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); - write_uint32(sl->q_buf, n); - stlink_write_mem32(sl, FLASH_F4_CR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_F4_CR, n); } else { /* write to 1 only. reset by hw at unlock sequence */ const uint32_t n = read_flash_cr(sl) | (1 << FLASH_CR_LOCK); - write_uint32(sl->q_buf, n); - stlink_write_mem32(sl, FLASH_CR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_CR, n); } } @@ -208,47 +200,40 @@ static void set_flash_cr_pg(stlink_t *sl) { if(sl->chip_id==STM32F4_CHIP_ID) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_CR_PG); - write_uint32(sl->q_buf, x); - stlink_write_mem32(sl, FLASH_F4_CR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_F4_CR, x); } else { const uint32_t n = 1 << FLASH_CR_PG; - write_uint32(sl->q_buf, n); - stlink_write_mem32(sl, FLASH_CR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_CR, n); } } static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); - write_uint32(sl->q_buf, n); if(sl->chip_id==STM32F4_CHIP_ID) - stlink_write_mem32(sl, FLASH_F4_CR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_F4_CR, n); else - stlink_write_mem32(sl, FLASH_CR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_CR, n); } static void set_flash_cr_per(stlink_t *sl) { const uint32_t n = 1 << FLASH_CR_PER; - write_uint32(sl->q_buf, n); - stlink_write_mem32(sl, FLASH_CR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_CR, n); } static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PER); - write_uint32(sl->q_buf, n); - stlink_write_mem32(sl, FLASH_CR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_CR, n); } static void set_flash_cr_mer(stlink_t *sl) { const uint32_t n = 1 << FLASH_CR_MER; - write_uint32(sl->q_buf, n); - stlink_write_mem32(sl, FLASH_CR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_CR, n); } static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_MER); - write_uint32(sl->q_buf, n); - stlink_write_mem32(sl, FLASH_CR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_CR, n); } static void set_flash_cr_strt(stlink_t *sl) { @@ -256,29 +241,27 @@ static void set_flash_cr_strt(stlink_t *sl) { { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_F4_CR_STRT); - write_uint32(sl->q_buf, x); - stlink_write_mem32(sl, FLASH_F4_CR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_F4_CR, x); } else { /* assume come on the flash_cr_per path */ const uint32_t n = (1 << FLASH_CR_PER) | (1 << FLASH_CR_STRT); - write_uint32(sl->q_buf, n); - stlink_write_mem32(sl, FLASH_CR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_CR, n); } } static inline uint32_t read_flash_acr(stlink_t *sl) { - stlink_read_mem32(sl, FLASH_ACR, sizeof (uint32_t)); - return read_uint32(sl->q_buf, 0); + return stlink_read_debug32(sl, FLASH_ACR); } static inline uint32_t read_flash_sr(stlink_t *sl) { + uint32_t res; if(sl->chip_id==STM32F4_CHIP_ID) - stlink_read_mem32(sl, FLASH_F4_SR, sizeof (uint32_t)); + res = stlink_read_debug32(sl, FLASH_F4_SR); else - stlink_read_mem32(sl, FLASH_SR, sizeof (uint32_t)); + res = stlink_read_debug32(sl, FLASH_SR); //fprintf(stdout, "SR:0x%x\n", *(uint32_t*) sl->q_buf); - return read_uint32(sl->q_buf, 0); + return res; } static inline unsigned int is_flash_busy(stlink_t *sl) { @@ -300,8 +283,7 @@ static inline unsigned int is_flash_eop(stlink_t *sl) { static void __attribute__((unused)) clear_flash_sr_eop(stlink_t *sl) { const uint32_t n = read_flash_sr(sl) & ~(1 << FLASH_SR_EOP); - write_uint32(sl->q_buf, n); - stlink_write_mem32(sl, FLASH_SR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_SR, n); } static void __attribute__((unused)) wait_flash_eop(stlink_t *sl) { @@ -311,8 +293,7 @@ static void __attribute__((unused)) wait_flash_eop(stlink_t *sl) { } static inline void write_flash_ar(stlink_t *sl, uint32_t n) { - write_uint32(sl->q_buf, n); - stlink_write_mem32(sl, FLASH_AR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_AR, n); } static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n) { @@ -322,8 +303,7 @@ static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n) { #if DEBUG_FLASH fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n); #endif - write_uint32(sl->q_buf, x); - stlink_write_mem32(sl, FLASH_F4_CR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_F4_CR, x); } @@ -335,8 +315,7 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { #if DEBUG_FLASH fprintf(stdout, "SNB:0x%x 0x%x\n", x, n); #endif - write_uint32(sl->q_buf, x); - stlink_write_mem32(sl, FLASH_F4_CR, sizeof (uint32_t)); + stlink_write_debug32(sl, FLASH_F4_CR, x); } #if 0 /* todo */ @@ -935,14 +914,11 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) uint32_t val; /* disable pecr protection */ - write_uint32(sl->q_buf, 0x89abcdef); - stlink_write_mem32(sl, STM32L_FLASH_PEKEYR, sizeof(uint32_t)); - write_uint32(sl->q_buf, 0x02030405); - stlink_write_mem32(sl, STM32L_FLASH_PEKEYR, sizeof(uint32_t)); + stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); + stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405); /* check pecr.pelock is cleared */ - stlink_read_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); - val = read_uint32(sl->q_buf, 0); + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); if (val & (1 << 0)) { WLOG("pecr.pelock not clear (%#x)\n", val); @@ -950,14 +926,11 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } /* unlock program memory */ - write_uint32(sl->q_buf, 0x8c9daebf); - stlink_write_mem32(sl, STM32L_FLASH_PRGKEYR, sizeof(uint32_t)); - write_uint32(sl->q_buf, 0x13141516); - stlink_write_mem32(sl, STM32L_FLASH_PRGKEYR, sizeof(uint32_t)); + stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf); + stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516); /* check pecr.prglock is cleared */ - stlink_read_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); - val = read_uint32(sl->q_buf, 0); + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); if (val & (1 << 1)) { WLOG("pecr.prglock not clear (%#x)\n", val); @@ -966,14 +939,11 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) /* unused: unlock the option byte block */ #if 0 - write_uint32(sl->q_buf, 0xfbead9c8); - stlink_write_mem32(sl, STM32L_FLASH_OPTKEYR, sizeof(uint32_t)); - write_uint32(sl->q_buf, 0x24252627); - stlink_write_mem32(sl, STM32L_FLASH_OPTKEYR, sizeof(uint32_t)); + stlink_write_debug32(sl, STM32L_FLASH_OPTKEYR, 0xfbead9c8); + stlink_write_debug32(sl, STM32L_FLASH_OPTKEYR, 0x24252627); /* check pecr.optlock is cleared */ - stlink_read_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); - val = read_uint32(sl->q_buf, 0); + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); if (val & (1 << 2)) { fprintf(stderr, "pecr.prglock not clear\n"); @@ -983,8 +953,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) /* set pecr.{erase,prog} */ val |= (1 << 9) | (1 << 3); - write_uint32(sl->q_buf, val); - stlink_write_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); #if 0 /* fix_to_be_confirmed */ @@ -994,33 +963,27 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) TEXANE: ok, if experience says so and it works for you, we comment it. If someone has a problem, please drop an email. */ - while (1) + while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) { - stlink_read_mem32(sl, STM32L_FLASH_SR, sizeof(uint32_t)); - if ((read_uint32(sl->q_buf, 0) & (1 << 0)) == 0) break ; } #endif /* fix_to_be_confirmed */ /* write 0 to the first word of the page to be erased */ - memset(sl->q_buf, 0, sizeof(uint32_t)); - stlink_write_mem32(sl, flashaddr, sizeof(uint32_t)); + stlink_write_mem32(sl, flashaddr, 0); /* MP: It is better to wait for clearing the busy bit after issuing page erase command, even though PM0062 recommends to wait before it. Test shows that a few iterations is performed in the following loop before busy bit is cleared.*/ - while (1) + while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) { - stlink_read_mem32(sl, STM32L_FLASH_SR, sizeof(uint32_t)); - if ((read_uint32(sl->q_buf, 0) & (1 << 0)) == 0) break; } /* reset lock bits */ - stlink_read_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); - val = read_uint32(sl->q_buf, 0) | (1 << 0) | (1 << 1) | (1 << 2); - write_uint32(sl->q_buf, val); - stlink_write_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); + val = stlink_read_debug32(sl, STM32L_FLASH_PECR) + | (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); } else if (sl->core_id == STM32VL_CORE_ID) { @@ -1318,28 +1281,22 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned #endif /* todo: check write operation */ /* disable pecr protection */ - write_uint32(sl->q_buf, 0x89abcdef); - stlink_write_mem32(sl, STM32L_FLASH_PEKEYR, sizeof(uint32_t)); - write_uint32(sl->q_buf, 0x02030405); - stlink_write_mem32(sl, STM32L_FLASH_PEKEYR, sizeof(uint32_t)); + stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); + stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405); /* check pecr.pelock is cleared */ - stlink_read_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); - val = read_uint32(sl->q_buf, 0); + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); if (val & (1 << 0)) { fprintf(stderr, "pecr.pelock not clear\n"); return -1; } /* unlock program memory */ - write_uint32(sl->q_buf, 0x8c9daebf); - stlink_write_mem32(sl, STM32L_FLASH_PRGKEYR, sizeof(uint32_t)); - write_uint32(sl->q_buf, 0x13141516); - stlink_write_mem32(sl, STM32L_FLASH_PRGKEYR, sizeof(uint32_t)); + stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf); + stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516); /* check pecr.prglock is cleared */ - stlink_read_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); - val = read_uint32(sl->q_buf, 0); + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); if (val & (1 << 1)) { fprintf(stderr, "pecr.prglock not clear\n"); return -1; @@ -1361,9 +1318,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned stlink_write_mem32(sl, addr + off, sizeof(uint32_t)); /* wait for sr.busy to be cleared */ - while (1) { - stlink_read_mem32(sl, STM32L_FLASH_SR, sizeof(uint32_t)); - if ((read_uint32(sl->q_buf, 0) & (1 << 0)) == 0) break ; + while (stlink_read_debug32(sl, STM32L_FLASH_SR & (1 << 0)) != 0) { } #if 0 /* todo: check redo write operation */ @@ -1391,10 +1346,9 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned page, addr + off, read_uint32(base + off, 0), read_uint32(sl->q_buf, 0)); /* reset lock bits */ - stlink_read_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); - val = read_uint32(sl->q_buf, 0) | (1 << 0) | (1 << 1) | (1 << 2); - write_uint32(sl->q_buf, val); - stlink_write_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); + val = stlink_read_debug32(sl, STM32L_FLASH_PECR) + | (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); stlink_erase_flash_page(sl, page); @@ -1407,10 +1361,9 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned #endif /* todo: check redo write operation */ } /* reset lock bits */ - stlink_read_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); - val = read_uint32(sl->q_buf, 0) | (1 << 0) | (1 << 1) | (1 << 2); - write_uint32(sl->q_buf, val); - stlink_write_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); + val = stlink_read_debug32(sl, STM32L_FLASH_PECR) + | (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); } else if (sl->core_id == STM32VL_CORE_ID) { ILOG("Starting Flash write for VL core id\n"); /* flash loader initialization */ From 9953efb763459b201f731f330a943536182c4f05 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 13 Dec 2011 20:35:32 +0100 Subject: [PATCH 0083/1435] Use the single word accesses in the flash inner loop too. We first swap the data, then the access routine swaps the data again, but cycles are cheep and so don't need another access function --- src/stlink-common.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 79650ede5..bec79c327 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1240,6 +1240,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned #define PROGRESS_CHUNK_SIZE 0x1000 /* write a word in program memory */ for (off = 0; off < len; off += sizeof(uint32_t)) { + uint32_t data; if (sl->verbose >= 1) { if ((off & (PROGRESS_CHUNK_SIZE - 1)) == 0) { /* show progress. writing procedure is slow @@ -1250,8 +1251,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned } } - memcpy(sl->q_buf, (const void*)(base + off), sizeof(uint32_t)); - stlink_write_mem32(sl, addr + off, sizeof(uint32_t)); + write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); + stlink_write_debug32(sl, addr + off, data); /* wait for sr.busy to be cleared */ wait_flash_busy(sl); @@ -1304,6 +1305,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned /* write a word in program memory */ for (off = 0; off < len; off += sizeof(uint32_t)) { + uint32_t data; if (sl->verbose >= 1) { if ((off & (sl->flash_pgsz - 1)) == 0) { /* show progress. writing procedure is slow @@ -1314,8 +1316,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned } } - memcpy(sl->q_buf, (const void*)(base + off), sizeof(uint32_t)); - stlink_write_mem32(sl, addr + off, sizeof(uint32_t)); + write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); + stlink_write_mem32(sl, addr + off, data); /* wait for sr.busy to be cleared */ while (stlink_read_debug32(sl, STM32L_FLASH_SR & (1 << 0)) != 0) { @@ -1324,8 +1326,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned #if 0 /* todo: check redo write operation */ /* check written bytes. todo: should be on a per page basis. */ - stlink_read_mem32(sl, addr + off, sizeof(uint32_t)); - if (memcmp(sl->q_buf, base + off, sizeof(uint32_t))) { + data = stlink_read_debug32(sl, addr + off); + if (data == *(uint32_t*)(base + off)) { /* re erase the page and redo the write operation */ uint32_t page; uint32_t val; From 62ea3faf1e1d51823ed10ea985f3f36040e0d512 Mon Sep 17 00:00:00 2001 From: Fabien Le Mentec Date: Fri, 16 Dec 2011 14:07:17 -0600 Subject: [PATCH 0084/1435] [add] stlinkv1_macosx_driver from marco.cassinerio@gmail.com --- stlinkv1_macosx_driver/Makefile | 57 ++++++++++++++++++++++++++++++ stlinkv1_macosx_driver/README | 23 ++++++++++++ stlinkv1_macosx_driver/osx.tar.gz | Bin 0 -> 23264 bytes 3 files changed, 80 insertions(+) create mode 100644 stlinkv1_macosx_driver/Makefile create mode 100644 stlinkv1_macosx_driver/README create mode 100644 stlinkv1_macosx_driver/osx.tar.gz diff --git a/stlinkv1_macosx_driver/Makefile b/stlinkv1_macosx_driver/Makefile new file mode 100644 index 000000000..9947ff672 --- /dev/null +++ b/stlinkv1_macosx_driver/Makefile @@ -0,0 +1,57 @@ +# make ... for both stlink v1 and stlink v2 support +## +VPATH=src + +SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c uglylogging.c +OBJS_LIB=$(SOURCES_LIB:.c=.o) +TEST_PROGRAMS=test_usb test_sg +LDFLAGS=-L. -lstlink -lusb-1.0 + +CFLAGS+=-g +CFLAGS+=-DDEBUG=1 +CFLAGS+=-std=gnu99 +CFLAGS+=-Wall -Wextra + + +LIBRARY=libstlink.a + +all: $(LIBRARY) flash gdbserver $(TEST_PROGRAMS) + +$(LIBRARY): $(OBJS_LIB) + @echo "objs are $(OBJS_LIB)" + $(AR) -cr $@ $^ + @echo "done making library" + + +test_sg: test_sg.o $(LIBRARY) + @echo "building test_sg" + $(CC) test_sg.o $(LDFLAGS) -o $@ + +test_usb: test_usb.o $(LIBRARY) + @echo "building test_usb" + $(CC) test_usb.o $(LDFLAGS) -o $@ + @echo "done linking" + +%.o: %.c + @echo "building $^ into $@" + $(CC) $(CFLAGS) -c $^ -o $@ + @echo "done compiling" + +clean: + rm -rf $(OBJS_LIB) + rm -rf $(LIBRARY) + rm -rf test_usb* + rm -rf test_sg* + $(MAKE) -C flash clean + $(MAKE) -C gdbserver clean + +flash: + $(MAKE) -C flash + +gdbserver: + $(MAKE) -C gdbserver CONFIG_USE_LIBSG="$(CONFIG_USE_LIBSG)" + +osx_stlink_shield: + ./osx/install.sh + +.PHONY: clean all flash gdbserver diff --git a/stlinkv1_macosx_driver/README b/stlinkv1_macosx_driver/README new file mode 100644 index 000000000..23bbd860c --- /dev/null +++ b/stlinkv1_macosx_driver/README @@ -0,0 +1,23 @@ +from: marco.cassinerio@gmail.com +to: texane@gmail.com + +Hi, + +i managed to get the stlink v1 working under os x and i would like to share the solution so maybe you can +add it in your package. +The problem is that os x claims the device as scsi and libusb won't be able to connect to it. +I've created what is called a codeless driver which claims the device and has a higher priority then the +default apple mass storage driver, so the device can be accessed through libusb. + +I tested this codeless driver under OS X 10.6.8 and 10.7.2. I assume it works with any 10.6.x and 10.7.x +version as well. + +Attached to this mail you'll find the osx folder with the source code of the driver, both drivers (for +10.6.x and 10.7.x), an install.sh script and the modified Makefile, i only added a line at the end which +invoke the install.sh. + +To install the driver the user have only to do: + +sudo make osx_stlink_shield + +no reboot required. \ No newline at end of file diff --git a/stlinkv1_macosx_driver/osx.tar.gz b/stlinkv1_macosx_driver/osx.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..6e7bb275ba87719974b35d6ddb051c74b6cb914e GIT binary patch literal 23264 zcmZs>V|ZrGx-A^DW81dvj%~YR+qP}n>U3-lYNv_#Xiqk4*`8HO{LITbKC0$6rKEj^3O$5fJ@t&8?=$5ENR(fnbHU zUd_<5Nr|D6r0o!ul0U5$g_d^b4Cf0LpAiYk?~0|QOYtr2Nx_G=_*^Wmr~IY}f?Hk0 zk2$}w3-{_7kv%p zeq8lXk1y0P^*J-f!MhwFhusYm%6(je`ZoSSx#K$cVG<7;&bR_hY>ST)LJ1>^WU@#d zE{GCBy{_V!5ZXE2y=;&gBhV>f8{%o1+7B#>)47}KcK+SX<2ps3>mBG~d;C%Hd>lz# zIXv9D?ZBug?;=&m^FdKudjG{jneYN2(Q*5@I~*Z%`&elUC3t*Gh`!R7xfQ&1vq7f4_I4*Gl1iz;k+^-xDUd& zRm)Hb8tNN1vr&KG{$V%)@cxX5FdgA9;2RqF2#%t+3$a@8b*Z2P(02Ut4LXr_qzJyu z*?Vse*oM6ogs(4vUX>hp`VWebx}t#W`v-#I1_EV50Xggs^1#!yj{a!iz9x9z9g||> z*Qra^ozUNig2roa-DNG=9ooW)-vj&l=(m8mlkQ-G4_xp-v!HaCdWYc4SpWtf*uQdX zw39jk#+R=MSOjU#09UG?WLi>7vSiAp_C9YoiDdyVS&#-iKwW75aHzLcOIHB=X+Rqo z&D(C?68R0>-%hXnW^s~-=izJthX~=O;5ZKC;H!;?!{Q|TwynR<4}t>d#!jdcFS`hA zepq)91a|cSuSz7}B!REnd^YTjOgYc4?2drayp4=(4(0^!6d|7%``J9+>78LZW$){A zWygliXXNWX_{Lpr@Rude`&l7?7L%X68m^F^{O5S!%x89`CY{jNyGQaST**v3$mVFu3o(^aZv_XwJU~T|VK?0PVr;lYxFmL7G5- zLtOpx{7c^@26;d(a2sy#258bB2nr7Mtxuu<&G2vFAD}aTq1$sX0N`&_?AwsPT&lyBfAmynF5u*<%l8F`dJw6e{ z^$iR#ePC+V+GbIT#c0rcY!$X_P-y8uM4a{zr7TAq1O^fL3AFrP+yHlzY!B}otM&?# zAw}z~OjAVyf)QDj*;IjF$)Y2H$L(lF01hGEpa}&-m4Q?29%c}k%QaRiCsCuH+`r<> zXOvl3KiF)7&E~)mgCcg0cwh5kJdWh?>(j!2KmC(sW;YwdN8u-!$jTJ#0Yw~?`BoSQGga0v{kroPa%sOMqEK-*Uij3# zC>}5U>J8LgJ&O}0^jhBDk;#3_nn zp=VXD5;FyvZG7P>AQ_2wKm}IxIe#ZIAcO4vVu1pe$TUoKSey^=(GX167RD zRt&)P2UvL3n+agbn0S2=Y6Am)1n|(l&`TZ-=jL6WdUqJlOnfD>xqy4RgRV-?1W~!$ zLui84kKHza6vXfMX5#t0D$ImcSOofA84HB)KHL&z*qml}&=?_gdt68>0eSSIw&-5T z1bDv-f$4w?<_!vXf9!xv05XU6hcS)no`gQER-T-NFJA+8UVt(b!ZwqAa+=oMfK51G^f#i% z9HF~U#eX>k&CvmJLqARi+KmU~eI_&jWuI96fvXxIrvd)ki7kK7i#OOjkI6Lao_jC|joNM_na3F4 z0zQrpi{XC!oRT1(3*GXR8#*++?f{FEo3^?l=|r_v7AnMJ1lncRJhoLr)oez%1wp4R zKDMZ!jGFd}B{petryek)8}#ahcQl(n_nPJb(LbRfsuUzcfr;IC4Q)D<{*z%)tF##% zDtT4imYjI5G3ArT8gW+Wd8(+R8-#{7{%74iB>FtrR8e@y{;*`TWeMH(iXRm@_ztWE z8TOhVaUp~oi*U1CHNJ0<1VLDOJ7yDQaQan!)IH;TaxLyQ8uq-DxWCludJ5_0Q1v&o zWUX*XR=nft9g5!4G!@77qwH-J;F`}liDGozOp~>$3rz8CrEopwEm#n5=#voE!_L4Q znB%N%gH{g-j0t~iR<=~L z`Qy4ly@JkC7o4i#liucrXRnoCD#|)!LS+qScBm_!dOT{f!v-j3Rj{vDid?2ycc=s* zJ*qBEjOqtXcYreEZ=Us=`{7s&U_cpNc)9Gu(l5c~6)?ZmXbC-N5~=@fxJafb?K>oj zd$-t`C(BvCeku2qlL6UmNVNbw|?)^9qEG(Z1 z<^3sUBVplfh9?gj<2pX`wPli;}Q{#LC3wZ>_jKaB(F^%im>|5Zvz1=0DRR>$`ni z9V3D*9W#oV?A0@|jvN2kpf(}5tov;BHEB5g;lU-)NTX@u)I?_Rp*q$w3wyeRj|e+f zLgg=XGklZ5AM_g;`d(Vyy$cK;4n+;fc3I()R5w#~wo!+--_V|Ou9%phiu zCVCt%_(+`!mjMunWd_-(8!YoGS=MtHS+e6;ua>T!NUR%9@3M`^bWV?3w}g2GKqtt2 zo>5|~l0wg>tsyK|M>*@G81AHx(J?oq*=~(c$o-sC>LP6rp@5>Ii;&O_R177Tyfr%F zIH*=;vrZd!5nI%*8mVR|(F=Aip*e#%KSb5&P$nBa6zs^IAk&8AsucV!-AotBa3(C7 zM1dS4kyv5w0OGP+(D4Hm3*lDZ)lep_n*Q=dzoMKdnjeKa@5dcz4IKT&&3JyUqy@F; z9D;b7uD-(R_13P^ow(?zi}Nro-yqN8Vexd+-i>b5%$aNZ#hnI6P=--9wH*~ml| zla8h>|BybhJ@%v_abkBt+Lrk6Uw7n}E<4!LMYkzd{XS@T&YX%>|97L};PBv8!z^zs*i33zFYGp$*c>db% zB(Tp-u$5qvqsW?SqjCw;y{o$7Z4uKNVxXPqIHebx4B^~Ya{cTmwyln=2QQ14tG!;? z`xqIP(3}zb6}(Z>$8Ju$c80Q?W{uh`VOe;*la~574cM_#)RsC=Wm(+>!4E;#pb($d zp}v&mucJ;SFmdL1{;O)*$KS%7)FVfsBSCNq^Zg83mf=DTC^c}d%quyVyML~)i{ot~ z@+et%SZ4Sk8mH~FuU?&>ZXyTF9Gvk-)V{wVzY&L1y8vusxj2Uc&5A?J0#OzgGF8IB zdyjpdKdJ3`XMDp(YYsy9!CqEy<}|R)CX}?)>0L) zwzH)ETjo>;wVwxAMURO4E< zG9yZwwrUX_B>QUMYfBEZ1qk*(aqAg71}q3s^m;!-FF~+4+-l#!b!dV1dLXUdDc>6T zx*j{2i+h3@xUz%Tc;Th?2`%yAW-EBR*(|S|KbbL<ev*a^R3%eA0Y(wUcKTW1!@5hjjB7D&r3Lok=4m)~Nl(7oXI#pe zb-}J%VUT5B=@-}DXMD+0H)T#BK}0G7wx#WK(fbkutm>Uo&67^Y+IGh#JR0VXKKyM+ z)?zo+sO{q>SWD`7R`hdzKdq%cyV_O6)EGn_FvZWBJSZGKP+YNHiM*<5*n?OfTlxBH zL)q_M-9gh-(ZSjA8fpV8E;saEXJ~z>ar3DISUdaxFp?7PWoMX<-!d-owEiEeh)~>%k0_j z1;+}vBQAF1{k2m!8bg6&cj%^6`OQg=RYQzhCg@E_+A1R5-wSTu)dpdP6`; zQ*v(XPGQNvrWl%)+7DkL7O^Z`AHL-aUvdpgGNTb$_2;Iz-Hj)nR*WTEZ=5UI6qcd* zyJUW81+H&G)e!A|rj-=vWh1rgQAVM(!&zCVV69dmD&CR%q9-C`Db zx%t#=a_#%w&4X=7S@NyOt}OiQhfyDz5lVVkv$*%6b7Es<)`u2j9;qE43WPIINV|2& zuJ!JEpKO|yAf8SxT~>wYQq}%%nnuacAEbzD8=|v!Y@O#2blR_Pu+_0L=5S=3HYhTM z0XLWm6sVK)8vGSI36QEo6f#}zdJn#sSNEF2XTyhYjrp-@7?@;vS3Df+UfswXWHDHn zK4L!!9q2|w9oE6q#X57YqC3av>4OJ12R~dYG&qOY<@dpq7 z< z<<4gen5>3{_yvt9E0xzUeN%Mq4|d}YDs&<7vpOq1_omA`=Z38l0@jgGsxlyn`tcGb zShhHmT2jMV+w~8LA98A8*r2O3Dh=i{O31v|eJ)l0P^4oveiq0Ff5R|;_NzD2Czu*F ziLPxa?IDGW#clu)=zC3FnC4U8fkn=|N`hcHjt*s^qEj(w_B0hc&wwpgg{3CPb?)K$ zL21`Y78&9H!}(8-B~_I3%MQcJLEG^mlSvS)?rmr)`!1ByV6xAeR;PMxj@B$BdZvf> zVQ@hS_3Q80Vm#Ra(93~zl}6|It0o@a1ak530KbWJCJy!nQY{hUqmhB+S{nKcWIG6| z*t7^MY~9F2l)5(QIvP@5y9MJieUwjQcBBJ3!hPK4E6gDxRWk0oTcaGNAX}P(gw$A@ zlatuh0uQi_S$I>VfFo5`IvIwjL1+g_$8^)Kj~%CC*bqB6;!Nnxn(2hWP*~XNOC5mj zoywUCO|oax@b^jv6*P1~adNE0WYDulW=XSM)`9}u^0sZuQRZ*jY&#LgIRnn#85km& zEu$*kh#wjnD7ZcN@`)e_jm0fq(aXq3ek3Rl5N7$Ulin{TaDr24>QrY-sM^vDFl6dC zZV@rZs5N8}qq0AX$%Jvt_F0O|sIw|UFq48=6h+{;2oFMjAzup4otQNa|EAD`v_2bn zQp_Fu5J01l-GeS9i`tKkvNqSA4~xGYP_&A&43j)9t}PNr+iuI?NYCM$Y+Vd-V}|1B zhy*{eDcDBnzJ5DTYyv*d1^Wna#$=#*S}Ft=xX@-AOQF?K{S?5;u`rMs;R-EOx2VFp zff3VDiF|BF1as|!7wbZzGaMhu-a!wuOId2Od#7yfx-JmA1?|m2~TujvJ8-N*A;2 z%0u>?2SI3NqB>#dhKxOYgay$2V@xFTquNa(0Z#@XQ54M1$9{9CW(Gp3?k>| zd$}h5^^61H$40V?J{zU|w!O8RM{Co({gi@FDQCJKy_FUo-#YH`Z^hNEoY8R&j4BJ8 zZcOnvf{D&z0C~4~+ReCS^DFV(pJq>fa3{?%?CW}xI|MxMB^AC=>3Q)$jzk&n7SYkn&?*Sz#QGl+bXSVIE)U0g-zY(o zRfyVnrPpsdc6TIM)4v9IKo>?t$vwgoaqJTH-7;WG5Tg4AM z|KJhhWHB){T|q4sb31{_`V{05KM@Z3{+bSindMq2cGa{EEFbxbyF8qj_n5-IzuNg;K!|GR;TQvxUZzpTuqW$T+=^oYCP4 zZEYzuW<6wdGcR-U1)M1IyL+e)4?~XbHP~8W79o9S;g=4a2IIV) zM9*6N#v@-f<6hsvCa?S9U&uEisY7^;$iBBctp<*pMIsRU_NOzWz z|9C<__*RR4L*tp*oL}lY+JQyrxzIYfT6j(C&mNCC&mN1u@Ny~JeVaE^5xzNHspP!r z+5~grk>XfIJU#L5n1%$u&sx!?ksTz49ph33nuwTl$Vfkie`#xpWEgFL�_R&V`)I1TVxBwpP-mqV% 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 jOJ4Glm%QX9FL}vJUhPrLjd4{D&t0O$h%G+`s^ literal 0 HcmV?d00001 From 8e1a1afa938a961fa401d6ab60c545cb81a52136 Mon Sep 17 00:00:00 2001 From: Fabien Le Mentec Date: Fri, 16 Dec 2011 14:07:38 -0600 Subject: [PATCH 0085/1435] [update] AUTHOR --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index f60ebcaa2..8153669c7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -13,3 +13,4 @@ csamuelson@swingpal.com bravikov@gmail.com jnosky - codegrinder69@hotmail.com marpe@mimuw.edu.pl +marco.cassinerio@gmail.com From 49238681e4d98a7254747a139d537ba07efcba13 Mon Sep 17 00:00:00 2001 From: Fabien Le Mentec Date: Fri, 16 Dec 2011 14:28:15 -0600 Subject: [PATCH 0086/1435] [update] stlinkv1_macosx_driver/README --- stlinkv1_macosx_driver/README | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stlinkv1_macosx_driver/README b/stlinkv1_macosx_driver/README index 23bbd860c..adf3cca87 100644 --- a/stlinkv1_macosx_driver/README +++ b/stlinkv1_macosx_driver/README @@ -16,8 +16,10 @@ Attached to this mail you'll find the osx folder with the source code of the dri 10.6.x and 10.7.x), an install.sh script and the modified Makefile, i only added a line at the end which invoke the install.sh. -To install the driver the user have only to do: +First, unpack the osx.tar.gz contents: +tar xzvf osx.tar.gz +Then, install the driver using: sudo make osx_stlink_shield no reboot required. \ No newline at end of file From fba79be3b47738bdc8866a86c027765f1ab99a87 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 18 Dec 2011 15:03:51 +0100 Subject: [PATCH 0087/1435] Page erase for STM32L needs a real write to lowest address with 0. stink_write_mem(.., ..,0) is undedined --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index bec79c327..f89159a21 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -970,7 +970,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) #endif /* fix_to_be_confirmed */ /* write 0 to the first word of the page to be erased */ - stlink_write_mem32(sl, flashaddr, 0); + stlink_write_debug32(sl, flashaddr, 0); /* MP: It is better to wait for clearing the busy bit after issuing page erase command, even though PM0062 recommends to wait before it. From 5652cee37d2742714c6cb54983718cf5891e5c80 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 18 Dec 2011 15:21:26 +0100 Subject: [PATCH 0088/1435] Fix a wrong placed brace and and a not replaced stlink_write_mem32() that keep STM32L from programming --- src/stlink-common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index f89159a21..74d03f548 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1317,10 +1317,10 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned } write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); - stlink_write_mem32(sl, addr + off, data); + stlink_write_debug32(sl, addr + off, data); /* wait for sr.busy to be cleared */ - while (stlink_read_debug32(sl, STM32L_FLASH_SR & (1 << 0)) != 0) { + while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) { } #if 0 /* todo: check redo write operation */ From 7f0e9ada38e6e15fc8f415ba841001e74ef3e249 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 18 Dec 2011 15:40:09 +0100 Subject: [PATCH 0089/1435] Replace remaining _mem32 single word accesses with _debug32 --- src/stlink-common.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 74d03f548..632c222ef 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -368,9 +368,7 @@ uint32_t stlink_core_id(stlink_t *sl) { } uint32_t stlink_chip_id(stlink_t *sl) { - stlink_read_mem32(sl, 0xE0042000, 4); - uint32_t chip_id = sl->q_buf[0] | (sl->q_buf[1] << 8) | (sl->q_buf[2] << 16) | - (sl->q_buf[3] << 24); + uint32_t chip_id = stlink_read_debug32(sl, 0xE0042000); return chip_id; } @@ -380,8 +378,7 @@ uint32_t stlink_chip_id(stlink_t *sl) { * @param cpuid pointer to the result object */ void stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { - stlink_read_mem32(sl, CM3_REG_CPUID, 4); - uint32_t raw = read_uint32(sl->q_buf, 0); + uint32_t raw = stlink_read_debug32(sl, CM3_REG_CPUID); cpuid->implementer_id = (raw >> 24) & 0x7f; cpuid->variant = (raw >> 20) & 0xf; cpuid->part = (raw >> 4) & 0xfff; @@ -428,8 +425,7 @@ int stlink_load_device_params(stlink_t *sl) { } else if ((chip_id & 0xFFF) == STM32_CHIPID_F4) { sl->flash_size = 0x100000; //todo: RM0090 error; size register same address as unique ID } else { - stlink_read_mem32(sl, params->flash_size_reg, 4); - uint32_t flash_size = sl->q_buf[0] | (sl->q_buf[1] << 8); + uint32_t flash_size = stlink_read_debug32(sl, params->flash_size_reg) & 0xffff; sl->flash_size = flash_size * 1024; } sl->flash_pgsz = params->flash_pagesize; From 6f194ad388fedf287a6200ea7efb16c4118ca4c1 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 18 Dec 2011 16:34:16 +0100 Subject: [PATCH 0090/1435] Ignore NULL bytes at flash end when reading --- src/stlink-common.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index 632c222ef..fac7b685c 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -803,6 +803,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) int error = -1; size_t off; + int num_zero = 0; const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); if (fd == -1) { @@ -814,6 +815,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) for (off = 0; off < size; off += 1024) { size_t read_size = 1024; size_t rounded_size; + size_t index; if ((off + read_size) > size) read_size = size - off; @@ -824,12 +826,21 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) stlink_read_mem32(sl, addr + off, rounded_size); + for(index = 0; index < read_size; index ++) { + if (sl->q_buf[index] == 0) + num_zero ++; + else + num_zero = 0; + } if (write(fd, sl->q_buf, read_size) != (ssize_t) read_size) { fprintf(stderr, "write() != read_size\n"); goto on_error; } } + /* Ignore NULL Bytes at end of file */ + ftruncate(fd, size - num_zero); + /* success */ error = 0; From 379fcb3c614d540e2d854700d77c80268b207b3f Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 18 Dec 2011 16:53:16 +0100 Subject: [PATCH 0091/1435] Also ignore ZEROs at end of file when writing --- src/stlink-common.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index fac7b685c..937bf8296 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1420,11 +1420,22 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { /* write the file in flash at addr */ int err; + unsigned int num_zero = 0, index; mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { WLOG("map_file() == -1\n"); return -1; } + for(index = 0; index < mf.len; index ++) { + if (mf.base[index] == 0) + num_zero ++; + else + num_zero = 0; + } + if(num_zero != 0) { + ILOG("Ignoring %d bytes of Zeros at end of file\n",num_zero); + mf.len -= num_zero; + } err = stlink_write_flash(sl, addr, mf.base, mf.len); unmap_file(&mf); return err; From 6ab0eb83becbe28ea3f97d52b6e5fef39145f08a Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 18 Dec 2011 18:47:21 +0100 Subject: [PATCH 0092/1435] While L1 has empty flash cell erased to zero, at least F1/F4 are erased to 0xff. --- src/stlink-common.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 937bf8296..8493c4ce2 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -803,7 +803,8 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) int error = -1; size_t off; - int num_zero = 0; + int num_empty = 0; + unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM)?0:0xff; const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); if (fd == -1) { @@ -827,10 +828,10 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) stlink_read_mem32(sl, addr + off, rounded_size); for(index = 0; index < read_size; index ++) { - if (sl->q_buf[index] == 0) - num_zero ++; + if (sl->q_buf[index] == erased_pattern) + num_empty ++; else - num_zero = 0; + num_empty = 0; } if (write(fd, sl->q_buf, read_size) != (ssize_t) read_size) { fprintf(stderr, "write() != read_size\n"); @@ -839,7 +840,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) } /* Ignore NULL Bytes at end of file */ - ftruncate(fd, size - num_zero); + ftruncate(fd, size - num_empty); /* success */ error = 0; @@ -1420,21 +1421,22 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { /* write the file in flash at addr */ int err; - unsigned int num_zero = 0, index; + unsigned int num_empty = 0, index; + unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM)?0:0xff; mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { WLOG("map_file() == -1\n"); return -1; } for(index = 0; index < mf.len; index ++) { - if (mf.base[index] == 0) - num_zero ++; + if (mf.base[index] == erased_pattern) + num_empty ++; else - num_zero = 0; + num_empty = 0; } - if(num_zero != 0) { - ILOG("Ignoring %d bytes of Zeros at end of file\n",num_zero); - mf.len -= num_zero; + if(num_empty != 0) { + ILOG("Ignoring %d bytes of Zeros at end of file\n",num_empty); + mf.len -= num_empty; } err = stlink_write_flash(sl, addr, mf.base, mf.len); unmap_file(&mf); From 92cdf49e287dfb483f046cae4edc2afa4ceecaab Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 18 Dec 2011 19:03:58 +0100 Subject: [PATCH 0093/1435] Clip flash read request to maximum flash size --- src/stlink-common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index 8493c4ce2..b49e21ab0 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -812,6 +812,9 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) return -1; } + if (size > sl->flash_size) + size = sl->flash_size; + /* do the copy by 1k blocks */ for (off = 0; off < size; off += 1024) { size_t read_size = 1024; From da8f7b1a6aed42b7535db1eabe64c274bbb815a2 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 18 Dec 2011 19:13:46 +0100 Subject: [PATCH 0094/1435] If no read size is given, read the whole flash --- src/stlink-common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index b49e21ab0..77ab98d02 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -812,6 +812,9 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) return -1; } + if (size <1) + size = sl->flash_size; + if (size > sl->flash_size) size = sl->flash_size; From 1785fd73c58b27a5732928398aa4a528fbce96ad Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 18 Dec 2011 19:24:32 +0100 Subject: [PATCH 0095/1435] Add a TODO to check for Supply Voltage before setting F4 paralleisme to 32 bits --- src/stlink-common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index 77ab98d02..5a5131424 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1245,6 +1245,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned /* First unlock the cr */ unlock_flash_if(sl); + /* TODO: Check that Voltage range is 2.7 - 3.6 V */ /* set parallelisim to 32 bit*/ write_flash_cr_psiz(sl, 2); From 82c638ed83f69e36439763c0e48074829178a24b Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 18 Dec 2011 21:44:40 +0100 Subject: [PATCH 0096/1435] For gdbserver, use the same initialization sequence like for flashing --- gdbserver/gdb-server.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 6033040a3..6961cdcce 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -160,6 +160,8 @@ int main(int argc, char** argv) { break; } + stlink_reset(sl); + stlink_load_device_params(sl); printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); sl->verbose=0; From 7eb080490ce34e3daf6e0ab10743113acbc5a635 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 18 Dec 2011 23:35:20 +0100 Subject: [PATCH 0097/1435] Move reset/load_param in the open functions, as requested by Karl --- flash/main.c | 3 --- gdbserver/gdb-server.c | 2 -- src/stlink-sg.c | 2 ++ src/stlink-usb.c | 2 ++ 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/flash/main.c b/flash/main.c index 106e52c29..d61b22bd0 100644 --- a/flash/main.c +++ b/flash/main.c @@ -107,9 +107,6 @@ int main(int ac, char** av) if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); - stlink_reset(sl); - stlink_load_device_params(sl); - if (o.do_read == 0) /* write */ { err = stlink_fwrite_flash(sl, o.filename, o.addr); diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 6961cdcce..6033040a3 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -160,8 +160,6 @@ int main(int argc, char** argv) { break; } - stlink_reset(sl); - stlink_load_device_params(sl); printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); sl->verbose=0; diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 991bc878b..e45fe48ed 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -985,6 +985,8 @@ stlink_t* stlink_v1_open_inner(const int verbose) { return NULL; } + stlink_reset(sl); + stlink_load_device_params(sl); stlink_version(sl); if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { ugly_log(UERROR, LOG_TAG, diff --git a/src/stlink-usb.c b/src/stlink-usb.c index f0a469511..04f0b2cbe 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -701,6 +701,8 @@ stlink_t* stlink_open_usb(const int verbose) { stlink_enter_swd_mode(sl); } + stlink_reset(sl); + stlink_load_device_params(sl); stlink_version(sl); error = 0; From 40c9d08c6072237b1fb0a8bc86668de81d9068b8 Mon Sep 17 00:00:00 2001 From: Friedrich Beckmann Date: Tue, 3 Jan 2012 23:52:44 +0100 Subject: [PATCH 0098/1435] moved the device parameter loading at the end of initialization for V1 devices- fixed the problem of non working V1 devices --- src/stlink-sg.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index e45fe48ed..3d4a9b798 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -985,8 +985,6 @@ stlink_t* stlink_v1_open_inner(const int verbose) { return NULL; } - stlink_reset(sl); - stlink_load_device_params(sl); stlink_version(sl); if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { ugly_log(UERROR, LOG_TAG, @@ -1016,6 +1014,7 @@ stlink_t* stlink_v1_open_inner(const int verbose) { "WTF? successfully opened, but unable to read version details. BROKEN!\n"); return NULL; } + return sl; } @@ -1027,6 +1026,9 @@ stlink_t* stlink_v1_open(const int verbose) { } // by now, it _must_ be fully open and in a useful mode.... stlink_enter_swd_mode(sl); + /* Now we are ready to read the parameters */ + stlink_reset(sl); + stlink_load_device_params(sl); ILOG("Successfully opened a stlink v1 debugger\n"); return sl; } From 8e5b2b51bfa4e422c43b6862db7413a7d5b14fd5 Mon Sep 17 00:00:00 2001 From: Friedrich Beckmann Date: Tue, 3 Jan 2012 23:58:01 +0100 Subject: [PATCH 0099/1435] Added the library to the list of dependencies as in flash --- gdbserver/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdbserver/Makefile b/gdbserver/Makefile index c81ea52b8..8cca5726d 100644 --- a/gdbserver/Makefile +++ b/gdbserver/Makefile @@ -6,7 +6,7 @@ LDFLAGS=-L.. -lstlink -lusb-1.0 all: $(PRG) -$(PRG): $(OBJS) +$(PRG): $(OBJS) ../libstlink.a $(CC) -o $@ $^ $(LDFLAGS) clean: From 081eae3087ac42127262452aee1808aa3d0b8abc Mon Sep 17 00:00:00 2001 From: Fabien Le Mentec Date: Wed, 4 Jan 2012 00:55:47 -0600 Subject: [PATCH 0100/1435] [fix] valueless return warning --- src/stlink-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 04f0b2cbe..65d92ecab 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -203,7 +203,7 @@ uint32_t _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr) { size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return 0; } return read_uint32(rdata, 4); } From b90309b66046e5d48467fc0433e477baa87eec67 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 13 Jan 2012 19:16:15 +0100 Subject: [PATCH 0101/1435] Less noisy output for STM32L erase/program, but still showing progess --- src/stlink-common.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 5a5131424..28be2d25e 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -893,7 +893,6 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - ILOG("Erasing flash page at addr: %#x\n", flashaddr); if (sl->chip_id == STM32F4_CHIP_ID) { /* wait for ongoing op to finish */ @@ -1234,8 +1233,11 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned WLOG("Failed to erase_flash_page(%#zx) == -1\n", addr + off); return -1; } + fprintf(stdout,"\rFlash page at addr: 0x%08lx erased", addr + off); + fflush(stdout); page_count++; } + fprintf(stdout,"\n"); ILOG("Finished erasing %d pages of %d (%#x) bytes\n", page_count, sl->flash_pgsz, sl->flash_pgsz); @@ -1321,19 +1323,20 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned /* write a word in program memory */ for (off = 0; off < len; off += sizeof(uint32_t)) { uint32_t data; + write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); + stlink_write_debug32(sl, addr + off, data); + if (sl->verbose >= 1) { if ((off & (sl->flash_pgsz - 1)) == 0) { /* show progress. writing procedure is slow and previous errors are misleading */ const uint32_t pgnum = off / sl->flash_pgsz; const uint32_t pgcount = len / sl->flash_pgsz; - fprintf(stdout, "%u pages written out of %u\n", pgnum, pgcount); + fprintf(stdout, "\r%3u/%u pages written", pgnum, pgcount); + fflush(stdout); } } - write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); - stlink_write_debug32(sl, addr + off, data); - /* wait for sr.busy to be cleared */ while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) { } @@ -1377,6 +1380,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned #endif /* todo: check redo write operation */ } + fprintf(stdout, "\n"); /* reset lock bits */ val = stlink_read_debug32(sl, STM32L_FLASH_PECR) | (1 << 0) | (1 << 1) | (1 << 2); From b50eedcdb46c7baee5479ba20ca7d326702ac5a4 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 17 Jan 2012 15:44:17 +0100 Subject: [PATCH 0102/1435] Some L1 flash address was off by 0x10, but is never used --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 28be2d25e..2d495a852 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -59,7 +59,7 @@ #define STM32L_FLASH_PRGKEYR (STM32L_FLASH_REGS_ADDR + 0x10) #define STM32L_FLASH_OPTKEYR (STM32L_FLASH_REGS_ADDR + 0x14) #define STM32L_FLASH_SR (STM32L_FLASH_REGS_ADDR + 0x18) -#define STM32L_FLASH_OBR (STM32L_FLASH_REGS_ADDR + 0x0c) +#define STM32L_FLASH_OBR (STM32L_FLASH_REGS_ADDR + 0x1c) #define STM32L_FLASH_WRPR (STM32L_FLASH_REGS_ADDR + 0x20) From 72966d19122b54ce39a29c4b8a6f44170cce82c1 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 17 Jan 2012 21:17:02 +0100 Subject: [PATCH 0103/1435] write_mem8 with more than 0x40 bytes gives unexpected results --- src/stlink-common.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index 2d495a852..0c391129c 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -537,6 +537,11 @@ void stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { void stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem8 ***\n"); + if (len > 0x40 ) { // !!! never ever: Writing more then 0x40 bytes gives unexpected behaviour + fprintf(stderr, "Error: Data length > 64: +%d byte.\n", + len); + return; + } sl->backend->write_mem8(sl, addr, len); } From 079148247ce01c8b2ca0f8622e3d754d1f0ed3f3 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 17 Jan 2012 21:24:01 +0100 Subject: [PATCH 0104/1435] In write_buffer_to_sram() write as much as possible with write_mem32 --- src/stlink-common.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 0c391129c..97bc3e140 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -864,8 +864,16 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size) { /* write the buffer right after the loader */ - memcpy(sl->q_buf, buf, size); - stlink_write_mem8(sl, fl->buf_addr, size); + size_t chunk = size & ~0x3; + size_t rem = size & 0x3; + if (chunk) { + memcpy(sl->q_buf, buf, chunk); + stlink_write_mem32(sl, fl->buf_addr, chunk); + } + if (rem) { + memcpy(sl->q_buf, buf+chunk, rem); + stlink_write_mem8(sl, (fl->buf_addr)+chunk, rem); + } return 0; } From 9c2b7dd76b8c5da11f3789c8dc3f5226f6f5f877 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 17 Jan 2012 21:28:36 +0100 Subject: [PATCH 0105/1435] Enable half_page write for STM32L --- src/stlink-common.c | 86 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 15 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 97bc3e140..2ecddea3d 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -61,6 +61,8 @@ #define STM32L_FLASH_SR (STM32L_FLASH_REGS_ADDR + 0x18) #define STM32L_FLASH_OBR (STM32L_FLASH_REGS_ADDR + 0x1c) #define STM32L_FLASH_WRPR (STM32L_FLASH_REGS_ADDR + 0x20) +#define FLASH_L1_FPRG 10 +#define FLASH_L1_PROG 3 //STM32F4 @@ -1212,6 +1214,57 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, } +int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned num_half_pages) +{ + unsigned int count; + uint32_t val; + flash_loader_t fl; + + ILOG("Starting Half page flash write for STM32L core id\n"); + /* flash loader initialization */ + if (init_flash_loader(sl, &fl) == -1) { + WLOG("init_flash_loader() == -1\n"); + return -1; + } + /* Unlock already done */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + val |= (1 << FLASH_L1_FPRG); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + + val |= (1 << FLASH_L1_PROG); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) {} + +#define L1_WRITE_BLOCK_SIZE 0x80 + for (count = 0; count < num_half_pages; count ++) { + if (run_flash_loader(sl, &fl, addr + count * L1_WRITE_BLOCK_SIZE, base + count * L1_WRITE_BLOCK_SIZE, L1_WRITE_BLOCK_SIZE) == -1) { + WLOG("l1_run_flash_loader(%#zx) failed! == -1\n", addr + count * L1_WRITE_BLOCK_SIZE); + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + val &= ~((1 << FLASH_L1_FPRG) |(1 << FLASH_L1_PROG)); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + return -1; + } + /* wait for sr.busy to be cleared */ + if (sl->verbose >= 1) { + /* show progress. writing procedure is slow + and previous errors are misleading */ + fprintf(stdout, "\r%3u/%u halfpages written", count, num_half_pages); + fflush(stdout); + } + while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) { + } + } + fprintf(stdout, "\n"); + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + val &= ~(1 << FLASH_L1_PROG); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + val &= ~(1 << FLASH_L1_FPRG); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + + return 0; +} + int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned len) { size_t off; flash_loader_t fl; @@ -1332,24 +1385,19 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned fprintf(stderr, "pecr.prglock not clear\n"); return -1; } + if (len > L1_WRITE_BLOCK_SIZE) { + if (stm32l1_write_half_pages(sl, addr, base, len/L1_WRITE_BLOCK_SIZE) == -1){ + WLOG("\nwrite_half_pages failed == -1\n"); + return -1; + } + } - /* write a word in program memory */ - for (off = 0; off < len; off += sizeof(uint32_t)) { + /* write remainingword in program memory */ + for (off = (len /L1_WRITE_BLOCK_SIZE)*L1_WRITE_BLOCK_SIZE; off < len; off += sizeof(uint32_t)) { uint32_t data; write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); stlink_write_debug32(sl, addr + off, data); - if (sl->verbose >= 1) { - if ((off & (sl->flash_pgsz - 1)) == 0) { - /* show progress. writing procedure is slow - and previous errors are misleading */ - const uint32_t pgnum = off / sl->flash_pgsz; - const uint32_t pgcount = len / sl->flash_pgsz; - fprintf(stdout, "\r%3u/%u pages written", pgnum, pgcount); - fflush(stdout); - } - } - /* wait for sr.busy to be cleared */ while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) { } @@ -1470,6 +1518,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { reg rr; + int i = 0; DLOG("Running flash loader, write address:%#x, size: %zd\n", target, size); // FIXME This can never return -1 if (write_buffer_to_sram(sl, fl, buf, size) == -1) { @@ -1487,7 +1536,6 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, target, 0); /* target */ stlink_write_reg(sl, fl->buf_addr, 1); /* source */ stlink_write_reg(sl, count, 2); /* count (32 bits words) */ - stlink_write_reg(sl, 0, 3); /* output count */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ } else if (sl->core_id == STM32VL_CORE_ID) { @@ -1511,8 +1559,16 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_run(sl); /* wait until done (reaches breakpoint) */ - while (is_core_halted(sl) == 0) ; + while ((is_core_halted(sl) == 0) && (i <10000)) + { + i++; + } + if ( i > 9999) { + fprintf(stderr, "run error\n"); + return -1; + } + /* check written byte count */ if (sl->core_id == STM32L_CORE_ID) { From 587c65948ae4dcb2c3a93c331c3397f3ab22355d Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 17 Jan 2012 21:43:58 +0100 Subject: [PATCH 0106/1435] As write_buffer_to_sram() can now handles arbitrary size, use flash_pgsz chunks for writing F1 and reduce output --- src/stlink-common.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 2ecddea3d..69a68cef4 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -181,7 +181,7 @@ static int unlock_flash_if(stlink_t *sl) { return -1; } } - ILOG("Successfully unlocked flash\n"); + DLOG("Successfully unlocked flash\n"); return 0; } @@ -1454,15 +1454,11 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned return -1; } - /* write each page. above WRITE_BLOCK_SIZE fails? */ -#define WRITE_BLOCK_SIZE 0x40 int write_block_count = 0; - for (off = 0; off < len; off += WRITE_BLOCK_SIZE) { - ILOG("Writing flash block %d of size %d (%#x)\n", write_block_count, - WRITE_BLOCK_SIZE, WRITE_BLOCK_SIZE); + for (off = 0; off < len; off += sl->flash_pgsz) { /* adjust last write size */ - size_t size = WRITE_BLOCK_SIZE; - if ((off + WRITE_BLOCK_SIZE) > len) size = len - off; + size_t size = sl->flash_pgsz; + if ((off + sl->flash_pgsz) > len) size = len - off; /* unlock and set programming mode */ unlock_flash_if(sl); @@ -1473,8 +1469,14 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned return -1; } lock_flash(sl); - DLOG("Finished writing block %d\n", write_block_count++); + if (sl->verbose >= 1) { + /* show progress. writing procedure is slow + and previous errors are misleading */ + fprintf(stdout, "\r%3u/%lu pages written", write_block_count++, len/sl->flash_pgsz); + fflush(stdout); + } } + fprintf(stdout, "\n"); } else { WLOG("unknown coreid, not sure how to write: %x\n", sl->core_id); return -1; From bcf1030354bef0b28b9876944948cd6a46789b09 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 17 Jan 2012 21:55:10 +0100 Subject: [PATCH 0107/1435] Add dependancy from stlink.a --- gdbserver/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdbserver/Makefile b/gdbserver/Makefile index c81ea52b8..4f5642450 100644 --- a/gdbserver/Makefile +++ b/gdbserver/Makefile @@ -6,7 +6,7 @@ LDFLAGS=-L.. -lstlink -lusb-1.0 all: $(PRG) -$(PRG): $(OBJS) +$(PRG): $(OBJS) ../libstlink.a $(CC) -o $@ $^ $(LDFLAGS) clean: From adaf602a5600ee53836d30f77a636ca380bfddf4 Mon Sep 17 00:00:00 2001 From: le mentec fabien Date: Wed, 18 Jan 2012 09:58:54 -0600 Subject: [PATCH 0108/1435] [fix] format warning on 32 bits --- src/stlink-common.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 69a68cef4..f7f03b918 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1299,7 +1299,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned WLOG("Failed to erase_flash_page(%#zx) == -1\n", addr + off); return -1; } - fprintf(stdout,"\rFlash page at addr: 0x%08lx erased", addr + off); + fprintf(stdout,"\rFlash page at addr: 0x%08lx erased", + (unsigned long)addr + off); fflush(stdout); page_count++; } @@ -1472,7 +1473,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned if (sl->verbose >= 1) { /* show progress. writing procedure is slow and previous errors are misleading */ - fprintf(stdout, "\r%3u/%lu pages written", write_block_count++, len/sl->flash_pgsz); + fprintf(stdout, "\r%3u/%lu pages written", write_block_count++, (unsigned long)len/sl->flash_pgsz); fflush(stdout); } } From 9c41193a169c1078fff70fb356c53c22224e5bb9 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 19 Jan 2012 13:47:23 +0100 Subject: [PATCH 0109/1435] Use stlink_r|w_debug32 for single word access in the gdbserver too --- gdbserver/gdb-server.c | 51 +++++++++++++----------------------------- 1 file changed, 16 insertions(+), 35 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 6033040a3..851c758a9 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -265,15 +265,13 @@ static void init_data_watchpoints(stlink_t *sl) { #endif // set trcena in debug command to turn on dwt unit - stlink_read_mem32(sl, 0xE000EDFC, 4); - sl->q_buf[3] |= 1; - stlink_write_mem32(sl, 0xE000EDFC, 4); + stlink_write_debug32(sl, 0xE000EDFC, + stlink_read_debug32(sl, 0xE000EDFC) | (1<<24)); // make sure all watchpoints are cleared - memset(sl->q_buf, 0, 4); for(int i = 0; i < DATA_WATCH_NUM; i++) { data_watches[i].fun = WATCHDISABLED; - stlink_write_mem32(sl, 0xe0001028 + i * 16, 4); + stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); } } @@ -306,25 +304,16 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr data_watches[i].mask = mask; // insert comparator address - sl->q_buf[0] = (addr & 0xff); - sl->q_buf[1] = ((addr >> 8) & 0xff); - sl->q_buf[2] = ((addr >> 16) & 0xff); - sl->q_buf[3] = ((addr >> 24) & 0xff); - - stlink_write_mem32(sl, 0xE0001020 + i * 16, 4); + stlink_write_debug32(sl, 0xE0001020 + i * 16, addr); // insert mask - memset(sl->q_buf, 0, 4); - sl->q_buf[0] = mask; - stlink_write_mem32(sl, 0xE0001024 + i * 16, 4); + stlink_write_debug32(sl, 0xE0001024 + i * 16, mask); // insert function - memset(sl->q_buf, 0, 4); - sl->q_buf[0] = wf; - stlink_write_mem32(sl, 0xE0001028 + i * 16, 4); + stlink_write_debug32(sl, 0xE0001028 + i * 16, wf); // just to make sure the matched bit is clear ! - stlink_read_mem32(sl, 0xE0001028 + i * 16, 4); + stlink_read_debug32(sl, 0xE0001028 + i * 16); return 0; } } @@ -346,9 +335,8 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) printf("delete watchpoint %d addr %x\n", i, addr); #endif - memset(sl->q_buf, 0, 4); data_watches[i].fun = WATCHDISABLED; - stlink_write_mem32(sl, 0xe0001028 + i * 16, 4); + stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); return 0; } @@ -374,15 +362,13 @@ struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM]; static void init_code_breakpoints(stlink_t *sl) { memset(sl->q_buf, 0, 4); - sl->q_buf[0] = 0x03; // KEY | ENABLE - stlink_write_mem32(sl, CM3_REG_FP_CTRL, 4); + stlink_write_debug32(sl, CM3_REG_FP_CTRL, 0x03 /*KEY | ENABLE4*/); printf("KARL - should read back as 0x03, not 60 02 00 00\n"); - stlink_read_mem32(sl, CM3_REG_FP_CTRL, 4); + stlink_read_debug32(sl, CM3_REG_FP_CTRL); - memset(sl->q_buf, 0, 4); for(int i = 0; i < CODE_BREAK_NUM; i++) { code_breaks[i].type = 0; - stlink_write_mem32(sl, CM3_REG_FP_COMP0 + i * 4, 4); + stlink_write_debug32(sl, CM3_REG_FP_COMP0 + i * 4, 0); } } @@ -416,28 +402,23 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { if(set) brk->type |= type; else brk->type &= ~type; - memset(sl->q_buf, 0, 4); - if(brk->type == 0) { #ifdef DEBUG printf("clearing hw break %d\n", id); #endif - stlink_write_mem32(sl, 0xe0002008 + id * 4, 4); + stlink_write_debug32(sl, 0xe0002008 + id * 4, 0); } else { - sl->q_buf[0] = ( brk->addr & 0xff) | 1; - sl->q_buf[1] = ((brk->addr >> 8) & 0xff); - sl->q_buf[2] = ((brk->addr >> 16) & 0xff); - sl->q_buf[3] = ((brk->addr >> 24) & 0xff) | (brk->type << 6); + uint32_t mask = (brk->addr) | 1 | (brk->type << 30); #ifdef DEBUG printf("setting hw break %d at %08x (%d)\n", id, brk->addr, brk->type); - printf("reg %02x %02x %02x %02x\n", - sl->q_buf[3], sl->q_buf[2], sl->q_buf[1], sl->q_buf[0]); + printf("reg %08x \n", + mask); #endif - stlink_write_mem32(sl, 0xe0002008 + id * 4, 4); + stlink_write_debug32(sl, 0xe0002008 + id * 4, mask); } return 0; From 16756fbe053f3e5efaf2973aebabeec201926f53 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 19 Jan 2012 13:55:00 +0100 Subject: [PATCH 0110/1435] Store the masked chip_id in the stlink structure. Should fix unexpected behaviour with L1 and F2 --- src/stlink-common.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index f7f03b918..626c86d6d 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -405,9 +405,9 @@ int stlink_load_device_params(stlink_t *sl) { chip_id = 0x413; } - sl->chip_id = chip_id; + sl->chip_id = chip_id & 0xfff; for(size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { - if(devices[i].chip_id == (chip_id & 0xFFF)) { + if(devices[i].chip_id == sl->chip_id) { params = &devices[i]; break; } @@ -422,9 +422,9 @@ int stlink_load_device_params(stlink_t *sl) { sl->sram_base = STM32_SRAM_BASE; // read flash size from hardware, if possible... - if ((chip_id & 0xFFF) == STM32_CHIPID_F2) { + if (sl->chip_id == STM32_CHIPID_F2) { sl->flash_size = 0; // FIXME - need to work this out some other way, just set to max possible? - } else if ((chip_id & 0xFFF) == STM32_CHIPID_F4) { + } else if (sl->chip_id == STM32_CHIPID_F4) { sl->flash_size = 0x100000; //todo: RM0090 error; size register same address as unique ID } else { uint32_t flash_size = stlink_read_debug32(sl, params->flash_size_reg) & 0xffff; @@ -1185,7 +1185,7 @@ int stlink_fcheck_flash(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, unsigned length) { size_t off; - if ((sl->chip_id & 0xFFF) == STM32_CHIPID_F4) { + if (sl->chip_id == STM32_CHIPID_F4) { DLOG("(FIXME)Skipping verification for F4, not enough ram (yet)\n"); return 0; } From 4c206c3b7cb14bf29eb8ff23aa3c64e1cdab69db Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 19 Jan 2012 14:07:14 +0100 Subject: [PATCH 0111/1435] Allow to write to sram from the command line --- flash/main.c | 7 ++++++- src/stlink-common.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/flash/main.c b/flash/main.c index d61b22bd0..0f3040d37 100644 --- a/flash/main.c +++ b/flash/main.c @@ -109,7 +109,12 @@ int main(int ac, char** av) if (o.do_read == 0) /* write */ { - err = stlink_fwrite_flash(sl, o.filename, o.addr); + if ((o.addr >= sl->flash_base) && + (o.addr < sl->flash_base + sl->flash_size)) + err = stlink_fwrite_flash(sl, o.filename, o.addr); + else if ((o.addr >= sl->sram_base) && + (o.addr < sl->sram_base + sl->sram_size)) + err = stlink_fwrite_sram(sl, o.filename, o.addr); if (err == -1) { printf("stlink_fwrite_flash() == -1\n"); diff --git a/src/stlink-common.h b/src/stlink-common.h index a1442f366..155c6c003 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -363,6 +363,7 @@ extern "C" { int stlink_erase_flash_mass(stlink_t* sl); int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, unsigned length); 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, unsigned length); // PUBLIC From 41e7c16cf2f9c6db6b4cc4d61af86a359646d6be Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 19 Jan 2012 14:17:22 +0100 Subject: [PATCH 0112/1435] When loading a file to SRAM or Flash, set the Stack pointer with the initial SP value and the Program counter with the reset value from the Vector table. Then run reset function --- src/stlink-common.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index 626c86d6d..87dfc02fb 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -799,6 +799,11 @@ int stlink_fwrite_sram /* success */ error = 0; + /* set stack*/ + stlink_write_reg(sl, stlink_read_debug32(sl, addr ),13); + /* Set PC to the reset routine*/ + stlink_write_reg(sl, stlink_read_debug32(sl, addr + 4),15); + stlink_run(sl); on_error: unmap_file(&mf); @@ -1514,6 +1519,11 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { mf.len -= num_empty; } err = stlink_write_flash(sl, addr, mf.base, mf.len); + /* set stack*/ + stlink_write_reg(sl, stlink_read_debug32(sl, addr ),13); + /* Set PC to the reset routine*/ + stlink_write_reg(sl, stlink_read_debug32(sl, addr + 4),15); + stlink_run(sl); unmap_file(&mf); return err; } From 8c36e07cbefc41751807d9e327c116d3755cc6aa Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 19 Jan 2012 14:59:02 +0100 Subject: [PATCH 0113/1435] Make stlink_erase_flash_mass device dependant and implement mass erase for L1 by consecutive page erase Allow to erase the device with the flash --- flash/main.c | 71 ++++++++++++++++++++++++++++++--------------- src/stlink-common.c | 58 +++++++++++++++++++++++------------- 2 files changed, 86 insertions(+), 43 deletions(-) diff --git a/flash/main.c b/flash/main.c index 0f3040d37..387a335a1 100644 --- a/flash/main.c +++ b/flash/main.c @@ -9,10 +9,10 @@ #include #include "stlink-common.h" - +enum st_cmds {DO_WRITE = 0, DO_READ = 1, DO_ERASE = 2}; struct opts { - unsigned int do_read; + enum st_cmds cmd; const char* devname; const char* filename; stm32_addr_t addr; @@ -22,7 +22,9 @@ struct opts static void usage(void) { puts("stlinkv1 command line: ./flash {read|write} /dev/sgX path addr "); + puts("stlinkv1 command line: ./flash /dev/sgX erase"); puts("stlinkv2 command line: ./flash {read|write} path addr "); + puts("stlinkv2 command line: ./flash erase"); puts(" use hex format for addr and "); } @@ -33,38 +35,52 @@ static int get_opts(struct opts* o, int ac, char** av) unsigned int i = 0; - if (ac < 3) return -1; + if (ac < 1) return -1; /* stlinkv2 */ o->devname = NULL; - if (strcmp(av[0], "read") == 0) + if (strcmp(av[0], "erase") == 0) { - o->do_read = 1; + o->cmd = DO_ERASE; /* stlinkv1 mode */ - if (ac == 5) + if (ac == 2) { o->devname = av[1]; i = 1; } - if (ac > 3) - o->size = strtoul(av[i + 3], NULL, 16); } - else if (strcmp(av[0], "write") == 0) - { - o->do_read = 0; - - /* stlinkv1 mode */ - if (ac == 4) - { - o->devname = av[1]; - i = 1; - } - } - else - { - return -1; + else { + if (ac < 3) return -1; + if (strcmp(av[0], "read") == 0) + { + o->cmd = DO_READ; + + /* stlinkv1 mode */ + if (ac == 5) + { + o->devname = av[1]; + i = 1; + } + if (ac > 3) + o->size = strtoul(av[i + 3], NULL, 16); + } + else if (strcmp(av[0], "write") == 0) + { + o->cmd = DO_WRITE; + + /* stlinkv1 mode */ + if (ac == 4) + { + o->devname = av[1]; + i = 1; + } + } + else + { + return -1; + } } o->filename = av[i + 1]; @@ -107,7 +123,7 @@ int main(int ac, char** av) if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); - if (o.do_read == 0) /* write */ + if (o.cmd == DO_WRITE) /* write */ { if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) @@ -121,6 +137,15 @@ int main(int ac, char** av) goto on_error; } } + else if (o.cmd == DO_ERASE) + { + err = stlink_erase_flash_mass(sl); + if (err == -1) + { + printf("stlink_fwrite_flash() == -1\n"); + goto on_error; + } + } else /* read */ { err = stlink_fread(sl, o.filename, o.addr, o.size); diff --git a/src/stlink-common.c b/src/stlink-common.c index 87dfc02fb..5cbf7febb 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1053,26 +1053,44 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } int stlink_erase_flash_mass(stlink_t *sl) { - /* wait for ongoing op to finish */ - wait_flash_busy(sl); - - /* unlock if locked */ - unlock_flash_if(sl); - - /* set the mass erase bit */ - set_flash_cr_mer(sl); - - /* start erase operation, reset by hw with bsy bit */ - set_flash_cr_strt(sl); - - /* wait for completion */ - wait_flash_busy(sl); - - /* relock the flash */ - lock_flash(sl); - - /* todo: verify the erased memory */ - + if (sl->chip_id == STM32_CHIPID_F4) { + DLOG("(FIXME) Mass erase of STM32F4\n"); + } + else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { + /* erase each page */ + int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; + for (i = 0; i < num_pages; i++) { + /* addr must be an addr inside the page */ + stm32_addr_t addr = sl->flash_base + i * sl->flash_pgsz; + if (stlink_erase_flash_page(sl, addr) == -1) { + WLOG("Failed to erase_flash_page(%#zx) == -1\n", addr); + return -1; + } + fprintf(stdout,"\rFlash page at %5d/%5d erased", i, num_pages); + fflush(stdout); + } + } + else { + /* wait for ongoing op to finish */ + wait_flash_busy(sl); + + /* unlock if locked */ + unlock_flash_if(sl); + + /* set the mass erase bit */ + set_flash_cr_mer(sl); + + /* start erase operation, reset by hw with bsy bit */ + set_flash_cr_strt(sl); + + /* wait for completion */ + wait_flash_busy(sl); + + /* relock the flash */ + lock_flash(sl); + + /* todo: verify the erased memory */ + } return 0; } From 0164043f9229e1c0c99789a7dcebe684a4fb6e1b Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 19 Jan 2012 15:45:51 +0100 Subject: [PATCH 0114/1435] A blank STM32L151 refused half-page writing. Fall back to half-word writing in that case. Report advance in half-word writing. Setting stack and PC give access error so automatic start fails too and hardware needs to be hard-reset to start --- src/stlink-common.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 5cbf7febb..39a714b17 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1069,6 +1069,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { fprintf(stdout,"\rFlash page at %5d/%5d erased", i, num_pages); fflush(stdout); } + fprintf(stdout, "\n"); } else { /* wait for ongoing op to finish */ @@ -1242,7 +1243,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uns unsigned int count; uint32_t val; flash_loader_t fl; - + ILOG("Starting Half page flash write for STM32L core id\n"); /* flash loader initialization */ if (init_flash_loader(sl, &fl) == -1) { @@ -1277,7 +1278,6 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uns while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) { } } - fprintf(stdout, "\n"); val = stlink_read_debug32(sl, STM32L_FLASH_PECR); val &= ~(1 << FLASH_L1_PROG); stlink_write_debug32(sl, STM32L_FLASH_PECR, val); @@ -1409,16 +1409,29 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned fprintf(stderr, "pecr.prglock not clear\n"); return -1; } + off = 0; if (len > L1_WRITE_BLOCK_SIZE) { if (stm32l1_write_half_pages(sl, addr, base, len/L1_WRITE_BLOCK_SIZE) == -1){ + /* This may happen on a blank device! */ WLOG("\nwrite_half_pages failed == -1\n"); - return -1; - } - } + } + else{ + off = (len /L1_WRITE_BLOCK_SIZE)*L1_WRITE_BLOCK_SIZE; + } + } /* write remainingword in program memory */ - for (off = (len /L1_WRITE_BLOCK_SIZE)*L1_WRITE_BLOCK_SIZE; off < len; off += sizeof(uint32_t)) { + for ( ; off < len; off += sizeof(uint32_t)) { uint32_t data; + if (off > 254) + fprintf(stdout, "\r"); + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) { + fprintf(stdout, "\r%3u/%u pages written", + off/sl->flash_pgsz, len/sl->flash_pgsz); + fflush(stdout); + } + write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); stlink_write_debug32(sl, addr + off, data); @@ -1590,12 +1603,12 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_run(sl); /* wait until done (reaches breakpoint) */ - while ((is_core_halted(sl) == 0) && (i <10000)) + while ((is_core_halted(sl) == 0) && (i <1000)) { i++; } - if ( i > 9999) { + if ( i > 999) { fprintf(stderr, "run error\n"); return -1; } From d00a6a30a2e020d629df2eec46840d6af247b607 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 20 Jan 2012 17:25:01 +0100 Subject: [PATCH 0115/1435] F1 set_flash_cr_strt unconditionally set the PER bit and so mass erase didn't work --- src/stlink-common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 39a714b17..b6e4a51a5 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -246,9 +246,9 @@ static void set_flash_cr_strt(stlink_t *sl) { stlink_write_debug32(sl, FLASH_F4_CR, x); } else { - /* assume come on the flash_cr_per path */ - const uint32_t n = (1 << FLASH_CR_PER) | (1 << FLASH_CR_STRT); - stlink_write_debug32(sl, FLASH_CR, n); + stlink_write_debug32( + sl, FLASH_CR, + stlink_read_debug32(sl,FLASH_CR) |(1 << FLASH_CR_STRT) ); } } From ce813d328b6d1105af0254dafc43a1414a0dfed3 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 24 Jan 2012 13:21:47 +0100 Subject: [PATCH 0116/1435] Fix mass erase of F4 --- src/stlink-common.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index b6e4a51a5..e8d324bee 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -229,13 +229,21 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { } static void set_flash_cr_mer(stlink_t *sl) { - const uint32_t n = 1 << FLASH_CR_MER; - stlink_write_debug32(sl, FLASH_CR, n); + if(sl->chip_id == STM32F4_CHIP_ID) + stlink_write_debug32(sl, FLASH_F4_CR, + stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); + else + stlink_write_debug32(sl, FLASH_CR, + stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_MER)); } static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { - const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_MER); - stlink_write_debug32(sl, FLASH_CR, n); + if(sl->chip_id == STM32F4_CHIP_ID) + stlink_write_debug32(sl, FLASH_F4_CR, + stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); + else + stlink_write_debug32(sl, FLASH_CR, + stlink_read_debug32(sl, FLASH_CR) & ~(1 << FLASH_CR_MER)); } static void set_flash_cr_strt(stlink_t *sl) { @@ -279,6 +287,22 @@ static void wait_flash_busy(stlink_t *sl) { ; } +static void wait_flash_busy_progress(stlink_t *sl) { + int i = 0; + fprintf(stdout, "Mass erasing"); + fflush(stdout); + while (is_flash_busy(sl)) + { + usleep(10000); + i++; + if (i % 100 == 0) { + fprintf(stdout, "."); + fflush(stdout); + } + } + fprintf(stdout, "\n"); +} + static inline unsigned int is_flash_eop(stlink_t *sl) { return read_flash_sr(sl) & (1 << FLASH_SR_EOP); } @@ -1053,10 +1077,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } int stlink_erase_flash_mass(stlink_t *sl) { - if (sl->chip_id == STM32_CHIPID_F4) { - DLOG("(FIXME) Mass erase of STM32F4\n"); - } - else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { /* erase each page */ int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -1085,7 +1106,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { set_flash_cr_strt(sl); /* wait for completion */ - wait_flash_busy(sl); + wait_flash_busy_progress(sl); /* relock the flash */ lock_flash(sl); From a85ebd90b21ee37baa6d185dd1b5c676d768ac7c Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 27 Jan 2012 20:26:32 +0100 Subject: [PATCH 0117/1435] Fix writing to SRAM on F1. Blocksize greater 0x1800 stalls STLINKV2. V1 needs to be checked! --- src/stlink-common.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index e8d324bee..8605f8776 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -747,15 +747,21 @@ static void unmap_file(mapped_file_t * mf) { mf->len = 0; } +/* Limit the block size to compare to 0x1800 + Anything larger will stall the STLINK2 + Maybe STLINK V1 needs smaller value!*/ static int check_file(stlink_t* sl, mapped_file_t* mf, stm32_addr_t addr) { size_t off; + size_t n_cmp = sl->flash_pgsz; + if ( n_cmp > 0x1800) + n_cmp = 0x1800; - for (off = 0; off < mf->len; off += sl->flash_pgsz) { + for (off = 0; off < mf->len; off += n_cmp) { size_t aligned_size; /* adjust last page size */ - size_t cmp_size = sl->flash_pgsz; - if ((off + sl->flash_pgsz) > mf->len) + size_t cmp_size = n_cmp; + if ((off + n_cmp) > mf->len) cmp_size = mf->len - off; aligned_size = cmp_size; From b95e4aa8a47c4caef0e525205945bdc61c5ee2c8 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 28 Jan 2012 04:46:22 +0100 Subject: [PATCH 0118/1435] CoreIF for F2/F4 is not different, use CPUID to distinguish. F4 errata seems to give wrong workaround --- src/stlink-common.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 8605f8776..03e1cce52 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -420,22 +420,23 @@ void stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { int stlink_load_device_params(stlink_t *sl) { ILOG("Loading device parameters....\n"); const chip_params_t *params = NULL; - sl->core_id = stlink_core_id(sl); uint32_t chip_id = stlink_chip_id(sl); - /* Fix chip_id for F4 rev A errata */ - if (((chip_id & 0xFFF) == 0x411) && (sl->core_id == CORE_M4_R0)) { - chip_id = 0x413; + sl->chip_id = chip_id & 0xfff; + /* Fix chip_id for F4 rev A errata , Read CPU ID, as CoreID is the same for F2/F4*/ + if (sl->chip_id == 0x411) { + uint32_t cpuid = stlink_read_debug32(sl, 0xE000ED00); + if((cpuid & 0xfff0) == 0xc240) + sl->chip_id = 0x413; } - sl->chip_id = chip_id & 0xfff; - for(size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { - if(devices[i].chip_id == sl->chip_id) { - params = &devices[i]; - break; - } - } + for(size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { + if(devices[i].chip_id == sl->chip_id) { + params = &devices[i]; + break; + } + } if (params == NULL) { WLOG("unknown chip id! %#x\n", chip_id); return -1; From 19b8c645402463b2303200cedda6d84f3c6c6582 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 29 Jan 2012 14:21:26 +0100 Subject: [PATCH 0119/1435] Give a different error when writing to flash or ram --- flash/main.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/flash/main.c b/flash/main.c index 387a335a1..f838d9232 100644 --- a/flash/main.c +++ b/flash/main.c @@ -126,17 +126,23 @@ int main(int ac, char** av) if (o.cmd == DO_WRITE) /* write */ { if ((o.addr >= sl->flash_base) && - (o.addr < sl->flash_base + sl->flash_size)) + (o.addr < sl->flash_base + sl->flash_size)) { err = stlink_fwrite_flash(sl, o.filename, o.addr); - else if ((o.addr >= sl->sram_base) && + if (err == -1) + { + printf("stlink_fwrite_flash() == -1\n"); + goto on_error; + } + } + else if ((o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) err = stlink_fwrite_sram(sl, o.filename, o.addr); - if (err == -1) - { - printf("stlink_fwrite_flash() == -1\n"); - goto on_error; - } - } + if (err == -1) + { + printf("stlink_sram_flash() == -1\n"); + goto on_error; + } + } else if (o.cmd == DO_ERASE) { err = stlink_erase_flash_mass(sl); From a1a949fa5598c3d2e014d276e7e52aeb8d62f3e4 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Mon, 30 Jan 2012 13:32:18 +0100 Subject: [PATCH 0120/1435] Limit reading from RAM to the SRAM Size --- flash/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/flash/main.c b/flash/main.c index 387a335a1..249e5fddc 100644 --- a/flash/main.c +++ b/flash/main.c @@ -148,6 +148,12 @@ int main(int ac, char** av) } else /* read */ { + if ((o.addr >= sl->flash_base) && + (o.addr < sl->flash_base + sl->flash_size)) + o.size = sl->flash_size; + else if ((o.addr >= sl->sram_base) && + (o.addr < sl->sram_base + sl->sram_size)) + o.size = sl->sram_size; err = stlink_fread(sl, o.filename, o.addr, o.size); if (err == -1) { From 5e5d1fa747efd4c913fc9b64414d33a1586c99a3 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 31 Jan 2012 16:49:45 +1030 Subject: [PATCH 0121/1435] Use pkg-config to find libusb CFLAGS and LDFLAGS. --- Makefile | 6 +++++- flash/Makefile | 6 +++++- gdbserver/Makefile | 6 +++++- src/stlink-sg.h | 2 +- src/stlink-usb.c | 2 +- src/stlink-usb.h | 2 +- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 6bf02323d..4bb0608b1 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,11 @@ VPATH=src SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c uglylogging.c OBJS_LIB=$(SOURCES_LIB:.c=.o) TEST_PROGRAMS=test_usb test_sg -LDFLAGS=-L. -lstlink -lusb-1.0 +LDFLAGS=-L. -lstlink + +# libusb location +LDFLAGS+=`pkg-config --libs libusb-1.0` +CFLAGS+=`pkg-config --cflags libusb-1.0` CFLAGS+=-g CFLAGS+=-DDEBUG=1 diff --git a/flash/Makefile b/flash/Makefile index cb7dcd2c2..491458717 100644 --- a/flash/Makefile +++ b/flash/Makefile @@ -4,7 +4,11 @@ CFLAGS+=-std=gnu99 CFLAGS+=-Wall -Wextra CFLAGS+=-I../src -LDFLAGS=-L.. -lstlink -lusb-1.0 +LDFLAGS=-L.. -lstlink + +# libusb location +LDFLAGS+=`pkg-config --libs libusb-1.0` +CFLAGS+=`pkg-config --cflags libusb-1.0` SRCS=main.c OBJS=$(SRCS:.c=.o) diff --git a/gdbserver/Makefile b/gdbserver/Makefile index 8cca5726d..bd5c73dbc 100644 --- a/gdbserver/Makefile +++ b/gdbserver/Makefile @@ -2,7 +2,11 @@ PRG := st-util OBJS = gdb-remote.o gdb-server.o CFLAGS+=-g -Wall -Werror -std=gnu99 -I../src -LDFLAGS=-L.. -lstlink -lusb-1.0 +LDFLAGS=-L.. -lstlink + +# libusb location +LDFLAGS+=`pkg-config --libs libusb-1.0` +CFLAGS+=`pkg-config --cflags libusb-1.0` all: $(PRG) diff --git a/src/stlink-sg.h b/src/stlink-sg.h index d4d7723b8..beecac324 100644 --- a/src/stlink-sg.h +++ b/src/stlink-sg.h @@ -12,7 +12,7 @@ extern "C" { #endif -#include +#include #include "stlink-common.h" // device access diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 65d92ecab..2a82b8837 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include "stlink-common.h" #include "stlink-usb.h" diff --git a/src/stlink-usb.h b/src/stlink-usb.h index 2f3b8cc3e..63b53695e 100644 --- a/src/stlink-usb.h +++ b/src/stlink-usb.h @@ -12,7 +12,7 @@ extern "C" { #endif -#include +#include #include "stlink-common.h" #define STLINK_SG_SIZE 31 From f38ff8f91282113b42ded9b108c05e5e329b6ffc Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 1 Feb 2012 20:55:10 +0000 Subject: [PATCH 0122/1435] Unify chipid naming convention. Flag more duplicate variables that need to be removed/combined --- gdbserver/gdb-server.c | 2 +- src/stlink-common.c | 28 ++++++++++++++-------------- src/stlink-common.h | 21 +++++++++------------ 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 851c758a9..89f862db0 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -219,7 +219,7 @@ char* make_memory_map(stlink_t *sl) { char* map = malloc(4096); map[0] = '\0'; - if(sl->chip_id==STM32F4_CHIP_ID) { + if(sl->chip_id==STM32_CHIPID_F4) { strcpy(map, memory_map_template_F4); } else { snprintf(map, 4096, memory_map_template, diff --git a/src/stlink-common.c b/src/stlink-common.c index 03e1cce52..65d459049 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -136,7 +136,7 @@ static inline uint32_t read_flash_obr(stlink_t *sl) { static inline uint32_t read_flash_cr(stlink_t *sl) { uint32_t res; - if(sl->chip_id==STM32F4_CHIP_ID) + if(sl->chip_id==STM32_CHIPID_F4) res = stlink_read_debug32(sl, FLASH_F4_CR); else res = stlink_read_debug32(sl, FLASH_CR); @@ -148,7 +148,7 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ - if(sl->chip_id==STM32F4_CHIP_ID) + if(sl->chip_id==STM32_CHIPID_F4) return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK); else return read_flash_cr(sl) & (1 << FLASH_CR_LOCK); @@ -160,7 +160,7 @@ static void unlock_flash(stlink_t *sl) { an invalid sequence results in a definitive lock of the FPEC block until next reset. */ - if(sl->chip_id==STM32F4_CHIP_ID) { + if(sl->chip_id==STM32_CHIPID_F4) { stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); } @@ -186,7 +186,7 @@ static int unlock_flash_if(stlink_t *sl) { } static void lock_flash(stlink_t *sl) { - if(sl->chip_id==STM32F4_CHIP_ID) { + if(sl->chip_id==STM32_CHIPID_F4) { const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); stlink_write_debug32(sl, FLASH_F4_CR, n); } @@ -199,7 +199,7 @@ static void lock_flash(stlink_t *sl) { static void set_flash_cr_pg(stlink_t *sl) { - if(sl->chip_id==STM32F4_CHIP_ID) { + if(sl->chip_id==STM32_CHIPID_F4) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_CR_PG); stlink_write_debug32(sl, FLASH_F4_CR, x); @@ -212,7 +212,7 @@ static void set_flash_cr_pg(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); - if(sl->chip_id==STM32F4_CHIP_ID) + if(sl->chip_id==STM32_CHIPID_F4) stlink_write_debug32(sl, FLASH_F4_CR, n); else stlink_write_debug32(sl, FLASH_CR, n); @@ -229,7 +229,7 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { } static void set_flash_cr_mer(stlink_t *sl) { - if(sl->chip_id == STM32F4_CHIP_ID) + if(sl->chip_id == STM32_CHIPID_F4) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); else @@ -238,7 +238,7 @@ static void set_flash_cr_mer(stlink_t *sl) { } static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { - if(sl->chip_id == STM32F4_CHIP_ID) + if(sl->chip_id == STM32_CHIPID_F4) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); else @@ -247,7 +247,7 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { } static void set_flash_cr_strt(stlink_t *sl) { - if(sl->chip_id == STM32F4_CHIP_ID) + if(sl->chip_id == STM32_CHIPID_F4) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_F4_CR_STRT); @@ -266,7 +266,7 @@ static inline uint32_t read_flash_acr(stlink_t *sl) { static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res; - if(sl->chip_id==STM32F4_CHIP_ID) + if(sl->chip_id==STM32_CHIPID_F4) res = stlink_read_debug32(sl, FLASH_F4_SR); else res = stlink_read_debug32(sl, FLASH_SR); @@ -275,7 +275,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { } static inline unsigned int is_flash_busy(stlink_t *sl) { - if(sl->chip_id==STM32F4_CHIP_ID) + if(sl->chip_id==STM32_CHIPID_F4) return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY); else return read_flash_sr(sl) & (1 << FLASH_SR_BSY); @@ -927,7 +927,7 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ - if(sl->chip_id == STM32F4_CHIP_ID) { + if(sl->chip_id == STM32_CHIPID_F4) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector<4) sl->flash_pgsz=0x4000; else if(sector<5) sl->flash_pgsz=0x10000; @@ -944,7 +944,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - if (sl->chip_id == STM32F4_CHIP_ID) + if (sl->chip_id == STM32_CHIPID_F4) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1359,7 +1359,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned ILOG("Finished erasing %d pages of %d (%#x) bytes\n", page_count, sl->flash_pgsz, sl->flash_pgsz); - if (sl->chip_id == STM32F4_CHIP_ID) { + if (sl->chip_id == STM32_CHIPID_F4) { /* todo: check write operation */ /* First unlock the cr */ diff --git a/src/stlink-common.h b/src/stlink-common.h index 155c6c003..6fcb2194e 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -81,10 +81,18 @@ extern "C" { #define CM3_REG_FP_COMP0 0xE0002008 /* cortex core ids */ + // TODO clean this up... #define STM32VL_CORE_ID 0x1ba01477 #define STM32L_CORE_ID 0x2ba01477 #define STM32F4_CORE_ID 0x2ba01477 - +#define CORE_M3_R1 0x1BA00477 +#define CORE_M3_R2 0x4BA00477 +#define CORE_M4_R0 0x2BA01477 + +/* + * Chip IDs are explained in the appropriate programming manual for the + * DBGMCU_IDCODE register (0xE0042000) + */ // stm32 chipids, only lower 12 bits.. #define STM32_CHIPID_F1_MEDIUM 0x410 #define STM32_CHIPID_F2 0x411 @@ -101,17 +109,6 @@ extern "C" { #define STM32_FLASH_BASE 0x08000000 #define STM32_SRAM_BASE 0x20000000 -/* - * 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 - -/* using chip id for F4 ident, since core id is same as F1 */ -#define STM32F4_CHIP_ID 0x413 - /* Cortex™-M3 Technical Reference Manual */ /* Debug Halting Control and Status Register */ #define DHCSR 0xe000edf0 From 7c4d7aa5593be79e6ff54df4ac7d9023ab83d810 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 1 Feb 2012 21:05:06 +0000 Subject: [PATCH 0123/1435] Use proper modifiers for size_t printing. Eliminates build warnings. --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 65d459049..d88b53e02 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1455,7 +1455,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned fprintf(stdout, "\r"); if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) { - fprintf(stdout, "\r%3u/%u pages written", + fprintf(stdout, "\r%3zd/%3zd pages written", off/sl->flash_pgsz, len/sl->flash_pgsz); fflush(stdout); } From 3355fb6a080447dec33c8868ecae1d22bf392fe7 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 15 Nov 2011 01:42:47 +0000 Subject: [PATCH 0124/1435] Remove the "merge in progress" notice --- README | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/README b/README index 1eb6d2617..838484ee4 100644 --- a/README +++ b/README @@ -1,11 +1,3 @@ -IMPORTANT SHORT TERM NOTICE: -If you are targetting F1 devices, with either stlinkv1 or v2 hardware, you -_need_ to use karlp's libwork2 branch. - -If you are targetting F4, you _need_ to use texane's master - -If you are targetting F2 or L1, please let us know how it goes! - HOWTO ===== @@ -136,7 +128,7 @@ STLink v1 (as found on the 32VL Discovery board) Known Working Targets: * STM32F100xx (Medium Density VL) -* STM32F103 (according to jpa- o n##stm32 +* STM32F103 (according to jpa- on ##stm32 No information: * everything else! From ce603be2003ae67a6472b647f62b3ef2f80e0da3 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 16 Nov 2011 02:44:01 +0000 Subject: [PATCH 0125/1435] Update list of known working targets --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index 838484ee4..73686a83d 100644 --- a/README +++ b/README @@ -133,11 +133,11 @@ Known Working Targets: No information: * everything else! - STLink v2 (as found on the 32L and F4 Discovery boards) Known Working Targets: * STM32F100xx (Medium Density VL, as on the 32VL Discovery board) -* ? +* STM32L1xx (STM32L Discovery board) +* STM32F407xx (STM32F4 Discovery board) Please report any and all known working combinations so I can update this! From 13035018f21c0cda27743aa4f26c543767a05cd6 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 1 Feb 2012 21:27:20 +0000 Subject: [PATCH 0126/1435] Add pkg-config to the list of requirements. --- README | 5 +++-- doc/tutorial/tutorial.pdf | Bin 96483 -> 115939 bytes doc/tutorial/tutorial.tex | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README b/README index 73686a83d..022e191c1 100644 --- a/README +++ b/README @@ -14,8 +14,9 @@ called stlink and there are 2 versions: Common requirements ~~~~~~~~~~~~~~~~~~~ -libusb-1.0 (You probably already have this, but you'll need the +. libusb-1.0 (You probably already have this, but you'll need the development version to compile) +. pkg-config IF YOU HAVE AN STLINKv1 ~~~~~~~~~~~~~~~~~~~~~~~ @@ -128,7 +129,7 @@ STLink v1 (as found on the 32VL Discovery board) Known Working Targets: * STM32F100xx (Medium Density VL) -* STM32F103 (according to jpa- on ##stm32 +* STM32F103 (according to jpa- on ##stm32) No information: * everything else! diff --git a/doc/tutorial/tutorial.pdf b/doc/tutorial/tutorial.pdf index d9b9333aef01627c9afecbeff887444662707d95..275e7a8fdd0755096ea549faab603b091439772e 100644 GIT binary patch delta 23385 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 VdDz&}g1nGO7_G3ds-7C{{{UWR?B)Of delta 4037 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 ST+Jp4n9pZhS-E*i*#851%5JFu diff --git a/doc/tutorial/tutorial.tex b/doc/tutorial/tutorial.tex index c3615df78..2045d77da 100644 --- a/doc/tutorial/tutorial.tex +++ b/doc/tutorial/tutorial.tex @@ -60,6 +60,7 @@ \section{Installing STLINK} Before continuing, the following dependencies must be met: \begin{itemize} \item libusb-1.0 +\item pkg-config \end{itemize} \paragraph{} From 18d6fe4893d92b67f1690674a6e7482eef18a31f Mon Sep 17 00:00:00 2001 From: Fabien Le Mentec Date: Wed, 1 Feb 2012 16:05:46 -0600 Subject: [PATCH 0127/1435] Get st-util ack'ing the monitor request. Responds to monitor reset -- reset the core monitor resume -- get the core running but don't stop gdb executing commands monitor halt -- halt the core --- gdbserver/gdb-server.c | 43 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 89f862db0..94784fcdb 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -669,6 +669,49 @@ int serve(stlink_t *sl, int port) { strncpy(&reply[1], data, length); } } + } else if(!strncmp(queryName, "Rcmd,",4)) { + // Rcmd uses the wrong separator + char *separator = strstr(packet, ","), *params = ""; + if(separator == NULL) { + separator = packet + strlen(packet); + } else { + params = separator + 1; + } + + + if (!strncmp(params,"7265",4)) {// resume +#ifdef DEBUG + printf("Rcmd: resume\n"); +#endif + stlink_run(sl); + + reply = strdup("OK"); + } else if (!strncmp(params,"6861",4)) { //half + reply = strdup("OK"); + + stlink_force_debug(sl); + +#ifdef DEBUG + printf("Rcmd: halt\n"); +#endif + } else if (!strncmp(params,"7265",4)) { //reset + reply = strdup("OK"); + + stlink_force_debug(sl); + stlink_reset(sl); + init_code_breakpoints(sl); + init_data_watchpoints(sl); + +#ifdef DEBUG + printf("Rcmd: reset\n"); +#endif + } else { +#ifdef DEBUG + printf("Rcmd: %s\n", params); +#endif + + } + } if(reply == NULL) From 9153dd5c0818997d8b12fd0c12d28f64d477c94e Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 1 Feb 2012 23:54:02 +0000 Subject: [PATCH 0128/1435] Remove all project files from stlink. The project is made with Makefiles, so while the project files provided some convenience to some people, they were not in any way portable or maintained. Removing them also allows other people to keep their own versions without having to deal with shared conflicts. Updated gitignore to reflec this. --- .gitignore | 3 +- .project | 81 ---- nbproject/Package-Default.bash | 75 ---- nbproject/Package-flash.bash | 75 ---- nbproject/configurations.xml | 672 --------------------------------- nbproject/project.xml | 27 -- 6 files changed, 2 insertions(+), 931 deletions(-) delete mode 100644 .project delete mode 100644 nbproject/Package-Default.bash delete mode 100644 nbproject/Package-flash.bash delete mode 100644 nbproject/configurations.xml delete mode 100644 nbproject/project.xml diff --git a/.gitignore b/.gitignore index 8e974b74b..bc2ba52ac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -/nbproject/private/ +nbproject +.project *.o *.elf doc/tutorial/*.log diff --git a/.project b/.project deleted file mode 100644 index 12a2f85eb..000000000 --- a/.project +++ /dev/null @@ -1,81 +0,0 @@ - - - stlink - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - ?children? - ?name?=outputEntries\|?children?=?name?=entry\\\\\\\|\\\|\|| - - - ?name? - - - - org.eclipse.cdt.make.core.append_environment - true - - - org.eclipse.cdt.make.core.autoBuildTarget - all - - - org.eclipse.cdt.make.core.buildArguments - - - - org.eclipse.cdt.make.core.buildCommand - make - - - org.eclipse.cdt.make.core.cleanBuildTarget - clean - - - org.eclipse.cdt.make.core.contents - org.eclipse.cdt.make.core.activeConfigSettings - - - org.eclipse.cdt.make.core.enableAutoBuild - false - - - org.eclipse.cdt.make.core.enableCleanBuild - true - - - org.eclipse.cdt.make.core.enableFullBuild - true - - - org.eclipse.cdt.make.core.fullBuildTarget - all - - - org.eclipse.cdt.make.core.stopOnError - true - - - org.eclipse.cdt.make.core.useDefaultBuildCmd - true - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - - - - - - org.eclipse.cdt.core.cnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - diff --git a/nbproject/Package-Default.bash b/nbproject/Package-Default.bash deleted file mode 100644 index f6abfb43c..000000000 --- a/nbproject/Package-Default.bash +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash -x - -# -# Generated - do not edit! -# - -# Macros -TOP=`pwd` -CND_PLATFORM=GNU-Linux-x86 -CND_CONF=Default -CND_DISTDIR=dist -CND_BUILDDIR=build -NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging -TMPDIRNAME=tmp-packaging -OUTPUT_PATH=gdbserver/st-util -OUTPUT_BASENAME=st-util -PACKAGE_TOP_DIR=stlink/ - -# Functions -function checkReturnCode -{ - rc=$? - if [ $rc != 0 ] - then - exit $rc - fi -} -function makeDirectory -# $1 directory path -# $2 permission (optional) -{ - mkdir -p "$1" - checkReturnCode - if [ "$2" != "" ] - then - chmod $2 "$1" - checkReturnCode - fi -} -function copyFileToTmpDir -# $1 from-file path -# $2 to-file path -# $3 permission -{ - cp "$1" "$2" - checkReturnCode - if [ "$3" != "" ] - then - chmod $3 "$2" - checkReturnCode - fi -} - -# Setup -cd "${TOP}" -mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package -rm -rf ${NBTMPDIR} -mkdir -p ${NBTMPDIR} - -# Copy files and create directories and links -cd "${TOP}" -makeDirectory "${NBTMPDIR}/stlink/bin" -copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 - - -# Generate tar file -cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/stlink.tar -cd ${NBTMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/stlink.tar * -checkReturnCode - -# Cleanup -cd "${TOP}" -rm -rf ${NBTMPDIR} diff --git a/nbproject/Package-flash.bash b/nbproject/Package-flash.bash deleted file mode 100644 index 44fd0fc43..000000000 --- a/nbproject/Package-flash.bash +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash -x - -# -# Generated - do not edit! -# - -# Macros -TOP=`pwd` -CND_PLATFORM=GNU-Linux-x86 -CND_CONF=flash -CND_DISTDIR=dist -CND_BUILDDIR=build -NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging -TMPDIRNAME=tmp-packaging -OUTPUT_PATH=MissingOutputInProject -OUTPUT_BASENAME=MissingOutputInProject -PACKAGE_TOP_DIR=stlink/ - -# Functions -function checkReturnCode -{ - rc=$? - if [ $rc != 0 ] - then - exit $rc - fi -} -function makeDirectory -# $1 directory path -# $2 permission (optional) -{ - mkdir -p "$1" - checkReturnCode - if [ "$2" != "" ] - then - chmod $2 "$1" - checkReturnCode - fi -} -function copyFileToTmpDir -# $1 from-file path -# $2 to-file path -# $3 permission -{ - cp "$1" "$2" - checkReturnCode - if [ "$3" != "" ] - then - chmod $3 "$2" - checkReturnCode - fi -} - -# Setup -cd "${TOP}" -mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package -rm -rf ${NBTMPDIR} -mkdir -p ${NBTMPDIR} - -# Copy files and create directories and links -cd "${TOP}" -makeDirectory "${NBTMPDIR}/stlink" -copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 - - -# Generate tar file -cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/stlink.tar -cd ${NBTMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/stlink.tar * -checkReturnCode - -# Cleanup -cd "${TOP}" -rm -rf ${NBTMPDIR} diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml deleted file mode 100644 index f1fcd48d1..000000000 --- a/nbproject/configurations.xml +++ /dev/null @@ -1,672 +0,0 @@ - - - - - - - - - - - discover_board.h - main.c - startup_stm32l1xx_md.s - system_stm32l1xx.c - - - discover_board.h - main.c - stm32l_discovery_lcd.c - stm32l_discovery_lcd.h - - - main.c - startup_stm32f10x_md_vl.S - stm32f10x_conf.h - stm32f10x_it.c - stm32f10x_it.h - system_stm32f10x.c - - - main.c - - - discover_board.h - main.c - startup_stm32l1xx_md.s - system_stm32l1xx.c - - - - STM32vldiscovery.c - STM32vldiscovery.h - - - - - - - - stdint.h - - - core_cm3.c - core_cm3.h - - - stm32f10x.h - stm32l1xx.h - system_stm32f10x.h - system_stm32l1xx.h - - - misc.h - stm32f10x_adc.h - stm32f10x_bkp.h - stm32f10x_can.h - stm32f10x_cec.h - stm32f10x_crc.h - stm32f10x_dac.h - stm32f10x_dbgmcu.h - stm32f10x_dma.h - stm32f10x_exti.h - stm32f10x_flash.h - stm32f10x_fsmc.h - stm32f10x_gpio.h - stm32f10x_i2c.h - stm32f10x_iwdg.h - stm32f10x_pwr.h - stm32f10x_rcc.h - stm32f10x_rtc.h - stm32f10x_sdio.h - stm32f10x_spi.h - stm32f10x_tim.h - stm32f10x_usart.h - stm32f10x_wwdg.h - - - misc.h - stm32l1xx_adc.h - stm32l1xx_comp.h - stm32l1xx_crc.h - stm32l1xx_dac.h - stm32l1xx_dbgmcu.h - stm32l1xx_dma.h - stm32l1xx_exti.h - stm32l1xx_flash.h - stm32l1xx_gpio.h - stm32l1xx_i2c.h - stm32l1xx_iwdg.h - stm32l1xx_lcd.h - stm32l1xx_pwr.h - stm32l1xx_rcc.h - stm32l1xx_rtc.h - stm32l1xx_spi.h - stm32l1xx_syscfg.h - stm32l1xx_tim.h - stm32l1xx_usart.h - stm32l1xx_wwdg.h - - - - - misc.c - stm32f10x_adc.c - stm32f10x_bkp.c - stm32f10x_can.c - stm32f10x_cec.c - stm32f10x_crc.c - stm32f10x_dac.c - stm32f10x_dbgmcu.c - stm32f10x_dma.c - stm32f10x_exti.c - stm32f10x_flash.c - stm32f10x_fsmc.c - stm32f10x_gpio.c - stm32f10x_i2c.c - stm32f10x_iwdg.c - stm32f10x_pwr.c - stm32f10x_rcc.c - stm32f10x_rtc.c - stm32f10x_sdio.c - stm32f10x_spi.c - stm32f10x_tim.c - stm32f10x_usart.c - stm32f10x_wwdg.c - - - misc.c - stm32l1xx_adc.c - stm32l1xx_comp.c - stm32l1xx_crc.c - stm32l1xx_dac.c - stm32l1xx_dbgmcu.c - stm32l1xx_dma.c - stm32l1xx_exti.c - stm32l1xx_flash.c - stm32l1xx_flash_ramfunc.c - stm32l1xx_gpio.c - stm32l1xx_i2c.c - stm32l1xx_iwdg.c - stm32l1xx_lcd.c - stm32l1xx_pwr.c - stm32l1xx_rcc.c - stm32l1xx_rtc.c - stm32l1xx_spi.c - stm32l1xx_syscfg.c - stm32l1xx_tim.c - stm32l1xx_usart.c - stm32l1xx_wwdg.c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - main.c - - - gdb-remote.c - gdb-remote.h - gdb-server.c - - - stlink-common.c - stlink-common.h - stlink-sg.c - stlink-sg.h - stlink-usb.c - stlink-usb.h - test_sg.c - test_usb.c - uglylogging.c - uglylogging.h - - - - - stlink-hw.h - - - - - - - - Makefile - - - ^(nbproject)$ - - . - - Makefile - - - - LOCAL_SOURCES - default - - - - . - ${MAKE} -f Makefile - ${MAKE} -f Makefile clean - gdbserver/st-util - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . - - - DEBUG=1 - - - - - - - src - - - CONFIG_USE_LIBUSB=1 - DEBUG - - - - - - - src - - - CONFIG_USE_LIBUSB=1 - - - - - - - . - - - DEBUG=1 - - - - - - - - - LOCAL_SOURCES - default - - - - flash - ${MAKE} -f Makefile - ${MAKE} -f Makefile clean - - - - DEBUG - - - - - - - - - - - - - - - - - - src - - - CONFIG_USE_LIBUSB=1 - - - - - - - src - - - CONFIG_USE_LIBSG=1 - CONFIG_USE_LIBUSB=1 - - - - - - - . - - - - - - - - - - - - - - diff --git a/nbproject/project.xml b/nbproject/project.xml deleted file mode 100644 index 7526e4b6b..000000000 --- a/nbproject/project.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - org.netbeans.modules.cnd.makeproject - - - stlink - c - - h - UTF-8 - - - . - - - - Default - 0 - - - flash - 0 - - - - - From edea824055ff395a218a1968c1efefd3dc9d6a37 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 29 Jan 2012 14:21:26 +0100 Subject: [PATCH 0129/1435] Give a different error when writing to flash or ram --- flash/main.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/flash/main.c b/flash/main.c index 249e5fddc..24287456b 100644 --- a/flash/main.c +++ b/flash/main.c @@ -126,17 +126,23 @@ int main(int ac, char** av) if (o.cmd == DO_WRITE) /* write */ { if ((o.addr >= sl->flash_base) && - (o.addr < sl->flash_base + sl->flash_size)) + (o.addr < sl->flash_base + sl->flash_size)) { err = stlink_fwrite_flash(sl, o.filename, o.addr); - else if ((o.addr >= sl->sram_base) && + if (err == -1) + { + printf("stlink_fwrite_flash() == -1\n"); + goto on_error; + } + } + else if ((o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) err = stlink_fwrite_sram(sl, o.filename, o.addr); - if (err == -1) - { - printf("stlink_fwrite_flash() == -1\n"); - goto on_error; - } - } + if (err == -1) + { + printf("stlink_sram_flash() == -1\n"); + goto on_error; + } + } else if (o.cmd == DO_ERASE) { err = stlink_erase_flash_mass(sl); From cc461e9bc984da6a462c931848e535533b9bf461 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 2 Feb 2012 22:10:13 +0100 Subject: [PATCH 0130/1435] For L1/F2/F4 we need the chip-id to distinguish, F1 needs core_id as common deniminator --- src/stlink-common.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 03e1cce52..9f1220898 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -972,7 +972,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); #endif } - else if (sl->core_id == STM32L_CORE_ID) + else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { uint32_t val; @@ -1185,7 +1185,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { const uint8_t* loader_code; size_t loader_size; - if (sl->core_id == STM32L_CORE_ID) /* stm32l */ + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) /* stm32l */ { loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); @@ -1404,7 +1404,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned } //STM32F4END - else if (sl->core_id == STM32L_CORE_ID) { + else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { /* use fast word write. todo: half page. */ uint32_t val; @@ -1599,7 +1599,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - if (sl->core_id == STM32L_CORE_ID) { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1642,7 +1642,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } /* check written byte count */ - if (sl->core_id == STM32L_CORE_ID) { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; From cbd0cf0918d63753e8c35d779b4b04e1d87eb889 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 2 Feb 2012 22:20:44 +0100 Subject: [PATCH 0131/1435] For now, we can treat F2 as F4 for flashing --- src/stlink-common.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 9f1220898..c122518bb 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -136,7 +136,7 @@ static inline uint32_t read_flash_obr(stlink_t *sl) { static inline uint32_t read_flash_cr(stlink_t *sl) { uint32_t res; - if(sl->chip_id==STM32F4_CHIP_ID) + if((sl->chip_id==STM32_CHIPID_F2) ||(sl->chip_id==STM32F4_CHIP_ID)) res = stlink_read_debug32(sl, FLASH_F4_CR); else res = stlink_read_debug32(sl, FLASH_CR); @@ -148,7 +148,7 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ - if(sl->chip_id==STM32F4_CHIP_ID) + if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK); else return read_flash_cr(sl) & (1 << FLASH_CR_LOCK); @@ -160,7 +160,7 @@ static void unlock_flash(stlink_t *sl) { an invalid sequence results in a definitive lock of the FPEC block until next reset. */ - if(sl->chip_id==STM32F4_CHIP_ID) { + if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) { stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); } @@ -186,7 +186,7 @@ static int unlock_flash_if(stlink_t *sl) { } static void lock_flash(stlink_t *sl) { - if(sl->chip_id==STM32F4_CHIP_ID) { + if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) { const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); stlink_write_debug32(sl, FLASH_F4_CR, n); } @@ -199,7 +199,7 @@ static void lock_flash(stlink_t *sl) { static void set_flash_cr_pg(stlink_t *sl) { - if(sl->chip_id==STM32F4_CHIP_ID) { + if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_CR_PG); stlink_write_debug32(sl, FLASH_F4_CR, x); @@ -212,7 +212,7 @@ static void set_flash_cr_pg(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); - if(sl->chip_id==STM32F4_CHIP_ID) + if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) stlink_write_debug32(sl, FLASH_F4_CR, n); else stlink_write_debug32(sl, FLASH_CR, n); @@ -229,7 +229,7 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { } static void set_flash_cr_mer(stlink_t *sl) { - if(sl->chip_id == STM32F4_CHIP_ID) + if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); else @@ -238,7 +238,7 @@ static void set_flash_cr_mer(stlink_t *sl) { } static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { - if(sl->chip_id == STM32F4_CHIP_ID) + if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); else @@ -247,7 +247,7 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { } static void set_flash_cr_strt(stlink_t *sl) { - if(sl->chip_id == STM32F4_CHIP_ID) + if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_F4_CR_STRT); @@ -266,7 +266,7 @@ static inline uint32_t read_flash_acr(stlink_t *sl) { static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res; - if(sl->chip_id==STM32F4_CHIP_ID) + if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) res = stlink_read_debug32(sl, FLASH_F4_SR); else res = stlink_read_debug32(sl, FLASH_SR); @@ -275,7 +275,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { } static inline unsigned int is_flash_busy(stlink_t *sl) { - if(sl->chip_id==STM32F4_CHIP_ID) + if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY); else return read_flash_sr(sl) & (1 << FLASH_SR_BSY); @@ -927,7 +927,7 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ - if(sl->chip_id == STM32F4_CHIP_ID) { + if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector<4) sl->flash_pgsz=0x4000; else if(sector<5) sl->flash_pgsz=0x10000; @@ -944,7 +944,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - if (sl->chip_id == STM32F4_CHIP_ID) + if ((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1359,7 +1359,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned ILOG("Finished erasing %d pages of %d (%#x) bytes\n", page_count, sl->flash_pgsz, sl->flash_pgsz); - if (sl->chip_id == STM32F4_CHIP_ID) { + if ((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) { /* todo: check write operation */ /* First unlock the cr */ From 02357a8b278a55e9428d064dbb57d893095db8b8 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 2 Feb 2012 22:36:13 +0100 Subject: [PATCH 0132/1435] Assume maximum FLASH size for F2 as for F4 (broken Flash size register) Verify F2 and F4 by using a decent block size --- src/stlink-common.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index c122518bb..294f932b2 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -448,7 +448,7 @@ int stlink_load_device_params(stlink_t *sl) { // read flash size from hardware, if possible... if (sl->chip_id == STM32_CHIPID_F2) { - sl->flash_size = 0; // FIXME - need to work this out some other way, just set to max possible? + sl->flash_size = 0x100000; /* Use maximum, User must care!*/ } else if (sl->chip_id == STM32_CHIPID_F4) { sl->flash_size = 0x100000; //todo: RM0090 error; size register same address as unique ID } else { @@ -1237,17 +1237,13 @@ int stlink_fcheck_flash(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, unsigned length) { size_t off; - if (sl->chip_id == STM32_CHIPID_F4) { - DLOG("(FIXME)Skipping verification for F4, not enough ram (yet)\n"); - return 0; - } + size_t cmp_size = (sl->flash_pgsz > 0x1800)? 0x1800:sl->flash_pgsz; ILOG("Starting verification of write complete\n"); - for (off = 0; off < length; off += sl->flash_pgsz) { + for (off = 0; off < length; off += cmp_size) { size_t aligned_size; /* adjust last page size */ - size_t cmp_size = sl->flash_pgsz; - if ((off + sl->flash_pgsz) > length) + if ((off + cmp_size) > length) cmp_size = length - off; aligned_size = cmp_size; From 132491480619da445b03b55fae7eeed0b1044da5 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 2 Feb 2012 22:49:33 +0100 Subject: [PATCH 0133/1435] Fix the progress indicator for F2/F4 flash writing --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 294f932b2..68b7d5049 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1377,7 +1377,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned /* show progress. writing procedure is slow and previous errors are misleading */ const uint32_t pgnum = (off / PROGRESS_CHUNK_SIZE)+1; - const uint32_t pgcount = len / PROGRESS_CHUNK_SIZE; + const uint32_t pgcount = len / PROGRESS_CHUNK_SIZE +1; fprintf(stdout, "Writing %ukB chunk %u out of %u\n", PROGRESS_CHUNK_SIZE/1024, pgnum, pgcount); } } From e919d94870667af422a8116b3f3a0fd0ffe16742 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 4 Feb 2012 15:49:11 +0100 Subject: [PATCH 0134/1435] Report about more Chips tested --- README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README b/README index 022e191c1..bb06f60a9 100644 --- a/README +++ b/README @@ -138,6 +138,8 @@ STLink v2 (as found on the 32L and F4 Discovery boards) Known Working Targets: * STM32F100xx (Medium Density VL, as on the 32VL Discovery board) * STM32L1xx (STM32L Discovery board) +* STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on a custom boards + (https://github.com/UweBonnes/wiki_fuer_alex/layout/usps...) * STM32F407xx (STM32F4 Discovery board) Please report any and all known working combinations so I can update this! From c2d09105f5bc00c5d9896ebf3f2a5595005e6d64 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 7 Feb 2012 21:20:54 +0100 Subject: [PATCH 0135/1435] Remove an outdated FIXME --- src/stlink-usb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 2a82b8837..979ba9731 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -636,7 +636,6 @@ stlink_t* stlink_open_usb(const int verbose) { slu->usb_handle = libusb_open_device_with_vid_pid(slu->libusb_ctx, USB_ST_VID, USB_STLINK_32L_PID); if (slu->usb_handle == NULL) { - // TODO - free usb context too... WLOG("Couldn't find any ST-Link/V2 devices"); goto on_error; } From 957b9c504fa6984314e0dd00958500dcf622ac9e Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 7 Feb 2012 21:43:43 +0100 Subject: [PATCH 0136/1435] Revive the V1 pathes in stlink-usb. Tested with the STM32VL Discovery. --- src/stlink-usb.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 979ba9731..8f5c6c410 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -127,8 +127,6 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, } if ((handle->protocoll == 1) && terminate) { - fprintf(stderr, "This is never used....\n"); - exit(EXIT_FAILURE); /* Read the SG reply */ unsigned char sg_buf[13]; libusb_fill_bulk_transfer @@ -157,7 +155,6 @@ static int fill_command int i = 0; memset(cmd, 0, sizeof (sl->c_buf)); if(slu->protocoll == 1) { - fprintf(stderr, "This is never used....\n"); cmd[i++] = 'U'; cmd[i++] = 'S'; cmd[i++] = 'B'; @@ -636,10 +633,14 @@ stlink_t* stlink_open_usb(const int verbose) { slu->usb_handle = libusb_open_device_with_vid_pid(slu->libusb_ctx, USB_ST_VID, USB_STLINK_32L_PID); if (slu->usb_handle == NULL) { - WLOG("Couldn't find any ST-Link/V2 devices"); - goto on_error; + slu->usb_handle = libusb_open_device_with_vid_pid(slu->libusb_ctx, USB_ST_VID, USB_STLINK_PID); + if (slu->usb_handle == NULL) { + WLOG("Couldn't find any ST-Link/V2 devices"); + goto on_error; + } + slu->protocoll = 1; } - + if (libusb_kernel_driver_active(slu->usb_handle, 0) == 1) { int r; From 41c5ef21ab59dd3d8505c2471e4f1a63611e1f47 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 7 Feb 2012 21:48:46 +0100 Subject: [PATCH 0137/1435] Rename "flash" to "st-flash" --- flash/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flash/Makefile b/flash/Makefile index 491458717..5345dcbfd 100644 --- a/flash/Makefile +++ b/flash/Makefile @@ -13,7 +13,7 @@ CFLAGS+=`pkg-config --cflags libusb-1.0` SRCS=main.c OBJS=$(SRCS:.c=.o) -NAME=flash +NAME=st-flash all: $(NAME) From b014aebd6372039bbb8214ccbc1e76b22ae5a8c2 Mon Sep 17 00:00:00 2001 From: Rob Spanton Date: Mon, 23 Apr 2012 23:19:55 +0100 Subject: [PATCH 0138/1435] Fix an unused parameter warning test_sg.c's main doesn't use its argv parameter, and so the compiler warns us this is the case. This patch stops it from warning us. --- src/test_sg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test_sg.c b/src/test_sg.c index 357f43665..51b0f074c 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -33,6 +33,8 @@ static void __attribute__((unused)) mark_buf(stlink_t *sl) { int main(int argc, char *argv[]) { + /* Avoid unused parameter warning */ + (void)argv; // set scpi lib debug level: 0 for no debug info, 10 for lots switch (argc) { From 087a3596c3f22599867411fafb79fdfb3f48097c Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sat, 28 Apr 2012 02:13:58 +0100 Subject: [PATCH 0139/1435] autoconfiscate --- .gitignore | 39 ++++++++++++++++++++--------------- ChangeLog | 0 Makefile | 58 ---------------------------------------------------- Makefile.am | 20 ++++++++++++++++++ NEWS | 0 autogen.sh | 11 ++++++++++ configure.ac | 29 ++++++++++++++++++++++++++ 7 files changed, 82 insertions(+), 75 deletions(-) create mode 100644 ChangeLog delete mode 100644 Makefile create mode 100644 Makefile.am create mode 100644 NEWS create mode 100755 autogen.sh create mode 100644 configure.ac diff --git a/.gitignore b/.gitignore index bc2ba52ac..c04ecfcdd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,23 @@ -nbproject -.project +COPYING +INSTALL +Makefile.in +aclocal.m4 +autom4te.cache +config.guess +config.sub +configure +depcomp +install-sh +ltmain.sh +missing +*.bz2 +*.lo *.o -*.elf -doc/tutorial/*.log -doc/tutorial/*.aux -libstlink.a -test_usb -test_sg -gdbserver/st-util -flash/flash -*.log -example/*/*.bin -example/*/*.elf -example/*/*/*.bin -example/*/*/*/*.bin -example/*/*/*.a -example/*/*/*/*.a +.libs +libtool +*.la +config.log +config.status +compile +st-flash +st-util diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/Makefile b/Makefile deleted file mode 100644 index 4bb0608b1..000000000 --- a/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -# make ... for both stlink v1 and stlink v2 support -## -VPATH=src - -SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c uglylogging.c -OBJS_LIB=$(SOURCES_LIB:.c=.o) -TEST_PROGRAMS=test_usb test_sg -LDFLAGS=-L. -lstlink - -# libusb location -LDFLAGS+=`pkg-config --libs libusb-1.0` -CFLAGS+=`pkg-config --cflags libusb-1.0` - -CFLAGS+=-g -CFLAGS+=-DDEBUG=1 -CFLAGS+=-std=gnu99 -CFLAGS+=-Wall -Wextra - - -LIBRARY=libstlink.a - -all: $(LIBRARY) flash gdbserver $(TEST_PROGRAMS) - -$(LIBRARY): $(OBJS_LIB) - @echo "objs are $(OBJS_LIB)" - $(AR) -cr $@ $^ - @echo "done making library" - - -test_sg: test_sg.o $(LIBRARY) - @echo "building test_sg" - $(CC) test_sg.o $(LDFLAGS) -o $@ - -test_usb: test_usb.o $(LIBRARY) - @echo "building test_usb" - $(CC) test_usb.o $(LDFLAGS) -o $@ - @echo "done linking" - -%.o: %.c - @echo "building $^ into $@" - $(CC) $(CFLAGS) -c $^ -o $@ - @echo "done compiling" - -clean: - rm -rf $(OBJS_LIB) - rm -rf $(LIBRARY) - rm -rf test_usb* - rm -rf test_sg* - $(MAKE) -C flash clean - $(MAKE) -C gdbserver clean - -flash: - $(MAKE) -C flash - -gdbserver: - $(MAKE) -C gdbserver CONFIG_USE_LIBSG="$(CONFIG_USE_LIBSG)" - -.PHONY: clean all flash gdbserver diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..9aeec4a00 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,20 @@ +# Makefile.am -- Process this file with automake to produce Makefile.in +bin_PROGRAMS = st-flash st-util + +noinst_LTLIBRARIES = libstlink.la + +st_flash_SOURCES = flash/main.c +st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c + +libstlink_la_SOURCES = src/stlink-common.c src/stlink-usb.c src/stlink-sg.c src/uglylogging.c \ + src/stlink-common.h src/stlink-usb.h src/stlink-sg.h src/uglylogging.h + +libstlink_la_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 + +st_flash_LDADD = libstlink.la +st_flash_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src + +st_util_LDADD = libstlink.la +st_util_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src + +EXTRA_DIST = autogen.sh diff --git a/NEWS b/NEWS new file mode 100644 index 000000000..e69de29bb diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 000000000..3a76a1150 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,11 @@ +#!/bin/sh +if test ! "x$(which libtoolize)" = "x"; then + echo "Running libtoolize" + libtoolize --copy --force --automake +else + if test ! "x$(which gintltoolize)" = "x"; then + echo "Running glibtoolize" + glibtoolize --copy --force --automake + fi +fi +autoreconf --install --force --verbose diff --git a/configure.ac b/configure.ac new file mode 100644 index 000000000..fcfb37735 --- /dev/null +++ b/configure.ac @@ -0,0 +1,29 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.61) +AC_INIT([stlink],[0.5.0],[davem@devkitpro.org]) +AC_CONFIG_SRCDIR([src/stlink-common.c]) + +AM_INIT_AUTOMAKE([1.10]) + + +# Checks for programs. +AC_PROG_CC +AC_PROG_INSTALL +AC_CANONICAL_HOST +AC_CANONICAL_BUILD +AC_PROG_LIBTOOL +AM_PROG_CC_C_O + +# Checks for libraries. +PKG_CHECK_MODULES(USB, libusb-1.0 >= 1.0.0,, + AC_MSG_ERROR([*** Required libusb-1.0 >= 1.0.0 not installed ***])) +AC_CHECK_LIB([usbpath],[usb_path2devnum],,,-lusb) + +LIBS="$LIBS $USB_LIBS" +CFLAGS="$CFLAGS $USB_CFLAGS" + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT + From 691e9af28da2e1178353a5c016c478e508a04f19 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sat, 28 Apr 2012 22:55:23 +0100 Subject: [PATCH 0140/1435] Changes for compiling with mingw32 add mmap & pread functions when compiling for systems that don't provide them don't use libtoolize, stick with static libraries --- Makefile.am | 29 +++++++++++++++---- autogen.sh | 9 ------ configure.ac | 11 ++++++-- src/mmap.c | 69 +++++++++++++++++++++++++++++++++++++++++++++ src/mmap.h | 62 ++++++++++++++++++++++++++++++++++++++++ src/pread.c | 42 +++++++++++++++++++++++++++ src/stlink-common.c | 3 +- src/stlink-sg.c | 2 +- src/stlink-usb.c | 12 ++++++++ 9 files changed, 218 insertions(+), 21 deletions(-) create mode 100644 src/mmap.c create mode 100644 src/mmap.h create mode 100644 src/pread.c diff --git a/Makefile.am b/Makefile.am index 9aeec4a00..28e11d5e5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,20 +1,37 @@ # Makefile.am -- Process this file with automake to produce Makefile.in + +AUTOMAKE_OPTIONS = subdir-objects + bin_PROGRAMS = st-flash st-util -noinst_LTLIBRARIES = libstlink.la +noinst_LIBRARIES = libstlink.a st_flash_SOURCES = flash/main.c st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c -libstlink_la_SOURCES = src/stlink-common.c src/stlink-usb.c src/stlink-sg.c src/uglylogging.c \ - src/stlink-common.h src/stlink-usb.h src/stlink-sg.h src/uglylogging.h +CFILES = \ + src/stlink-common.c \ + src/stlink-usb.c \ + src/stlink-sg.c \ + src/uglylogging.c + +HFILES = \ + src/stlink-common.h \ + src/stlink-usb.h \ + src/stlink-sg.h \ + src/uglylogging.h \ + src/mmap.h -libstlink_la_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 +libstlink_a_SOURCES = $(CFILES) $(HFILES) -st_flash_LDADD = libstlink.la +libstlink_a_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 +libstlink_a_LIBADD = $(LIBOBJS) + +st_flash_LDADD = libstlink.a st_flash_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -st_util_LDADD = libstlink.la +st_util_LDADD = libstlink.a st_util_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src EXTRA_DIST = autogen.sh + diff --git a/autogen.sh b/autogen.sh index 3a76a1150..2af5ccdac 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,11 +1,2 @@ #!/bin/sh -if test ! "x$(which libtoolize)" = "x"; then - echo "Running libtoolize" - libtoolize --copy --force --automake -else - if test ! "x$(which gintltoolize)" = "x"; then - echo "Running glibtoolize" - glibtoolize --copy --force --automake - fi -fi autoreconf --install --force --verbose diff --git a/configure.ac b/configure.ac index fcfb37735..a19bba4f1 100644 --- a/configure.ac +++ b/configure.ac @@ -2,9 +2,9 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([stlink],[0.5.0],[davem@devkitpro.org]) +AC_INIT([stlink],[0.5.1],[davem@devkitpro.org]) AC_CONFIG_SRCDIR([src/stlink-common.c]) - +AC_CONFIG_LIBOBJ_DIR([src]) AM_INIT_AUTOMAKE([1.10]) @@ -13,9 +13,14 @@ AC_PROG_CC AC_PROG_INSTALL AC_CANONICAL_HOST AC_CANONICAL_BUILD -AC_PROG_LIBTOOL +AC_PROG_RANLIB +#AC_PROG_LIBTOOL AM_PROG_CC_C_O +AC_CHECK_HEADERS(sys/mman.h) +AC_CHECK_FUNCS(mmap) +AC_REPLACE_FUNCS(mmap pread) + # Checks for libraries. PKG_CHECK_MODULES(USB, libusb-1.0 >= 1.0.0,, AC_MSG_ERROR([*** Required libusb-1.0 >= 1.0.0 not installed ***])) diff --git a/src/mmap.c b/src/mmap.c new file mode 100644 index 000000000..7316389b9 --- /dev/null +++ b/src/mmap.c @@ -0,0 +1,69 @@ +/* mmap.c -- version of mmap for gold. */ + +/* Copyright 2009 Free Software Foundation, Inc. + Written by Vladimir Simonov . + + This file is part of gold. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +//#include "config.h" +//#include "ansidecl.h" + +#include +#include +#ifdef HAVE_STDLIB_H +#include +#endif + +#include "mmap.h" + +extern ssize_t pread (int, void *, size_t, off_t); + +void * +mmap (void *__addr, size_t __len, int __prot, + int __flags, int __fd, long long __offset) +{ + void *ret; + ssize_t count; + + if (__addr || (__fd != -1 && (__prot & PROT_WRITE)) + || (__flags & MAP_SHARED)) + return MAP_FAILED; + + ret = malloc (__len); + if (!ret) + return MAP_FAILED; + + if (__fd == -1) + return ret; + + count = pread (__fd, ret, __len, __offset); + if ((size_t) count != __len) + { + free (ret); + return MAP_FAILED; + } + + return ret; +} + +int +munmap (void *__addr, size_t __len) +{ + free (__addr); + return 0; +} diff --git a/src/mmap.h b/src/mmap.h new file mode 100644 index 000000000..375eafb7b --- /dev/null +++ b/src/mmap.h @@ -0,0 +1,62 @@ +/* mmap.h -- mmap family functions prototypes for gold. */ + +/* Copyright 2009 Free Software Foundation, Inc. + Written by Vladimir Simonov + + This file is part of gold. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#ifndef GOLD_MMAP_H +#define GOLD_MMAP_H + +#ifdef HAVE_SYS_MMAN_H + +#include + +/* Some BSD systems still use MAP_ANON instead of MAP_ANONYMOUS. */ + +#ifndef MAP_ANONYMOUS +# define MAP_ANONYMOUS MAP_ANON +#endif + +#else + +#define PROT_READ 0x1 +#define PROT_WRITE 0x2 + +#define MAP_SHARED 0x01 +#define MAP_PRIVATE 0x02 + +#define MAP_ANONYMOUS 0x20 + +#define MAP_FAILED ((void *) -1) +#endif /* HAVE_SYS_MMAN_H */ + +#ifndef HAVE_MMAP +#ifdef __cplusplus +extern "C" { +#endif +extern void *mmap (void *__addr, size_t __len, int __prot, + int __flags, int __fd, long long __offset); +extern int munmap (void *__addr, size_t __len); +#ifdef __cplusplus +} +#endif + +#endif /* HAVE_MMAP */ + +#endif /* GOLD_MMAP_H */ diff --git a/src/pread.c b/src/pread.c new file mode 100644 index 000000000..4ac61155c --- /dev/null +++ b/src/pread.c @@ -0,0 +1,42 @@ +/* pread.c -- version of pread for gold. */ + +/* Copyright 2006, 2007, 2009 Free Software Foundation, Inc. + Written by Ian Lance Taylor . + + This file is part of gold. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* This file implements pread for systems which don't have it. This + file is only compiled if pread is not present on the system. This + is not an exact version of pread, as it does not preserve the + current file offset. */ + +//#include "config.h" + +#include +#include +#include + +extern ssize_t pread (int, void *, size_t, off_t); + +ssize_t +pread (int fd, void *buf, size_t count, off_t offset) +{ + if (lseek(fd, offset, SEEK_SET) != offset) + return -1; + return read(fd, buf, count); +} diff --git a/src/stlink-common.c b/src/stlink-common.c index 26b36cd24..29640fd70 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -9,8 +9,7 @@ #include #include #include -#include - +#include "mmap.h" #include "stlink-common.h" #include "uglylogging.h" diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 3d4a9b798..4cae3ee11 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -85,7 +85,7 @@ #include #include #include -#include +#include "mmap.h" #include "stlink-common.h" #include "stlink-sg.h" diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 8f5c6c410..d945f66ec 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -16,6 +16,18 @@ #define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args) #define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args) +#ifndef timersub +/* This is a copy from GNU C Library (GNU LGPL 2.1), sys/time.h. */ +# define timersub(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ + } while (0) +#endif enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80}; From 414ca992d70311ac4f47d776d4b0a2fa304317c4 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sun, 29 Apr 2012 14:09:06 +0100 Subject: [PATCH 0141/1435] update ignores for generated files --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index c04ecfcdd..d1d6410ff 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,8 @@ config.status compile st-flash st-util +*.deps* +*.dirstamp +*.a +Makefile +*.exe From 7ed5be296326a770bb8c66eff7f549b8b35327e2 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sun, 29 Apr 2012 14:43:46 +0100 Subject: [PATCH 0142/1435] build with mingw --- Makefile.am | 6 +- configure.ac | 7 +- gdbserver/gdb-remote.c | 6 +- gdbserver/gdb-server.c | 49 ++++---- mingw/mingw.c | 263 +++++++++++++++++++++++++++++++++++++++++ mingw/mingw.h | 61 ++++++++++ 6 files changed, 365 insertions(+), 27 deletions(-) create mode 100644 mingw/mingw.c create mode 100644 mingw/mingw.h diff --git a/Makefile.am b/Makefile.am index 28e11d5e5..a315dd726 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,7 +7,7 @@ bin_PROGRAMS = st-flash st-util noinst_LIBRARIES = libstlink.a st_flash_SOURCES = flash/main.c -st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c +st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c mingw/mingw.c mingw/mingw.h CFILES = \ src/stlink-common.c \ @@ -28,10 +28,10 @@ libstlink_a_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 libstlink_a_LIBADD = $(LIBOBJS) st_flash_LDADD = libstlink.a -st_flash_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src +st_flash_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw st_util_LDADD = libstlink.a -st_util_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src +st_util_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw EXTRA_DIST = autogen.sh diff --git a/configure.ac b/configure.ac index a19bba4f1..7b4d59041 100644 --- a/configure.ac +++ b/configure.ac @@ -14,10 +14,10 @@ AC_PROG_INSTALL AC_CANONICAL_HOST AC_CANONICAL_BUILD AC_PROG_RANLIB -#AC_PROG_LIBTOOL AM_PROG_CC_C_O AC_CHECK_HEADERS(sys/mman.h) +AC_CHECK_HEADERS(sys/poll.h) AC_CHECK_FUNCS(mmap) AC_REPLACE_FUNCS(mmap pread) @@ -29,6 +29,11 @@ AC_CHECK_LIB([usbpath],[usb_path2devnum],,,-lusb) LIBS="$LIBS $USB_LIBS" CFLAGS="$CFLAGS $USB_CFLAGS" +case "${host}" in + *-mingw32*) + LIBS="$LIBS -lws2_32" + ;; +esac AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/gdbserver/gdb-remote.c b/gdbserver/gdb-remote.c index f6bf02d26..1b0488e32 100644 --- a/gdbserver/gdb-remote.c +++ b/gdbserver/gdb-remote.c @@ -11,7 +11,11 @@ #include #include #include +#ifdef __MINGW32__ +#include "mingw.h" +#else #include +#endif static const char hex[] = "0123456789abcdef"; @@ -24,7 +28,7 @@ int gdb_send_packet(int fd, char* data) { packet[0] = '$'; uint8_t cksum = 0; - for(int i = 0; i < strlen(data); i++) { + for(unsigned int i = 0; i < strlen(data); i++) { packet[i + 1] = data[i]; cksum += data[i]; } diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 94784fcdb..b0b43d8e2 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -12,10 +12,14 @@ #include #include #include +#ifdef __MINGW32__ +#include "mingw.h" +#else #include #include #include #include +#endif #include @@ -203,15 +207,15 @@ static const char* const memory_map_template = "" "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram 8k - " " - " 0x%x" + " " // code = sram, bootrom or flash; flash is bigger + " " // sram 8k + " " + " 0x%zx" " " " " // peripheral regs " " // cortex regs - " " // bootrom - " " // option byte area + " " // bootrom + " " // option byte area ""; char* make_memory_map(stlink_t *sl) { @@ -291,7 +295,7 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr mask++; } - if((mask != -1) && (mask < 16)) { + if((mask != (uint32_t)-1) && (mask < 16)) { for(i = 0; i < DATA_WATCH_NUM; i++) { // is this an empty slot ? if(data_watches[i].fun == WATCHDISABLED) { @@ -461,7 +465,7 @@ static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { } static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { - int fit_blocks = 0, fit_length = 0; + unsigned int fit_blocks = 0, fit_length = 0; for(struct flash_block* fb = flash_root; fb; fb = fb->next) { /* Block: ------X------Y-------- @@ -553,7 +557,8 @@ int serve(stlink_t *sl, int port) { unsigned int val = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); - struct sockaddr_in serv_addr = {0}; + struct sockaddr_in serv_addr; + bzero(&serv_addr,sizeof(struct sockaddr_in)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); serv_addr.sin_port = htons(port); @@ -576,7 +581,7 @@ int serve(stlink_t *sl, int port) { printf("Listening at *:%d...\n", port); int client = accept(sock, NULL, NULL); - signal (SIGINT, SIG_DFL); + //signal (SIGINT, SIG_DFL); if(client < 0) { perror("accept"); return 1; @@ -633,17 +638,17 @@ int serve(stlink_t *sl, int port) { if(!strcmp(queryName, "Supported")) { reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); } else if(!strcmp(queryName, "Xfer")) { - char *type, *op, *s_addr, *s_length; + char *type, *op, *__s_addr, *s_length; char *tok = params; char *annex __attribute__((unused)); type = strsep(&tok, ":"); op = strsep(&tok, ":"); annex = strsep(&tok, ":"); - s_addr = strsep(&tok, ","); + __s_addr = strsep(&tok, ","); s_length = tok; - unsigned addr = strtoul(s_addr, NULL, 16), + unsigned addr = strtoul(__s_addr, NULL, 16), length = strtoul(s_length, NULL, 16); #ifdef DEBUG @@ -729,13 +734,13 @@ int serve(stlink_t *sl, int port) { cmdName++; // vCommand -> Command if(!strcmp(cmdName, "FlashErase")) { - char *s_addr, *s_length; + char *__s_addr, *s_length; char *tok = params; - s_addr = strsep(&tok, ","); + __s_addr = strsep(&tok, ","); s_length = tok; - unsigned addr = strtoul(s_addr, NULL, 16), + unsigned addr = strtoul(__s_addr, NULL, 16), length = strtoul(s_length, NULL, 16); #ifdef DEBUG @@ -749,13 +754,13 @@ int serve(stlink_t *sl, int port) { reply = strdup("OK"); } } else if(!strcmp(cmdName, "FlashWrite")) { - char *s_addr, *data; + char *__s_addr, *data; char *tok = params; - s_addr = strsep(&tok, ":"); + __s_addr = strsep(&tok, ":"); data = tok; - unsigned addr = strtoul(s_addr, NULL, 16); + unsigned addr = strtoul(__s_addr, NULL, 16); unsigned data_length = status - (data - packet); // Length of decoded data cannot be more than @@ -763,7 +768,7 @@ int serve(stlink_t *sl, int port) { // Additional byte is reserved for alignment fix. uint8_t *decoded = calloc(data_length + 1, 1); unsigned dec_index = 0; - for(int i = 0; i < data_length; i++) { + for(unsigned int i = 0; i < data_length; i++) { if(data[i] == 0x7d) { i++; decoded[dec_index++] = data[i] ^ 0x20; @@ -919,7 +924,7 @@ int serve(stlink_t *sl, int port) { count : count + 4 - (count % 4)); reply = calloc(count * 2 + 1, 1); - for(int i = 0; i < count; i++) { + for(unsigned int i = 0; i < count; i++) { reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4]; reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf]; } @@ -935,7 +940,7 @@ int serve(stlink_t *sl, int port) { stm32_addr_t start = strtoul(s_start, NULL, 16); unsigned count = strtoul(s_count, NULL, 16); - for(int i = 0; i < count; i ++) { + for(unsigned int i = 0; i < count; i ++) { char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; uint8_t byte = strtoul(hex, NULL, 16); sl->q_buf[i] = byte; diff --git a/mingw/mingw.c b/mingw/mingw.c new file mode 100644 index 000000000..c394a160c --- /dev/null +++ b/mingw/mingw.c @@ -0,0 +1,263 @@ +#ifdef __MINGW32__ + +#include "mingw.h" + +#include +#include +#include + +int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) +{ + struct timeval timeout, *toptr; + fd_set ifds, ofds, efds, *ip, *op; + int i, rc; + + /* Set up the file-descriptor sets in ifds, ofds and efds. */ + FD_ZERO(&ifds); + FD_ZERO(&ofds); + FD_ZERO(&efds); + for (i = 0, op = ip = 0; i < nfds; ++i) { + fds[i].revents = 0; + if(fds[i].events & (POLLIN|POLLPRI)) { + ip = &ifds; + FD_SET(fds[i].fd, ip); + } + if(fds[i].events & POLLOUT) { + op = &ofds; + FD_SET(fds[i].fd, op); + } + FD_SET(fds[i].fd, &efds); + } + + /* Set up the timeval structure for the timeout parameter */ + if(timo < 0) { + toptr = 0; + } else { + toptr = &timeout; + timeout.tv_sec = timo / 1000; + timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000; + } + +#ifdef DEBUG_POLL + printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n", + (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op); +#endif + rc = select(0, ip, op, &efds, toptr); +#ifdef DEBUG_POLL + printf("Exiting select rc=%d\n", rc); +#endif + + if(rc <= 0) + return rc; + + if(rc > 0) { + for (i = 0; i < nfds; ++i) { + int fd = fds[i].fd; + if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) + fds[i].revents |= POLLIN; + if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) + fds[i].revents |= POLLOUT; + if(FD_ISSET(fd, &efds)) + /* Some error was detected ... should be some way to know. */ + fds[i].revents |= POLLHUP; +#ifdef DEBUG_POLL + printf("%d %d %d revent = %x\n", + FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds), + fds[i].revents + ); +#endif + } + } + return rc; +} +static void +set_connect_errno(int winsock_err) +{ + switch(winsock_err) { + case WSAEINVAL: + case WSAEALREADY: + case WSAEWOULDBLOCK: + errno = EINPROGRESS; + break; + default: + errno = winsock_err; + break; + } +} + +static void +set_socket_errno(int winsock_err) +{ + switch(winsock_err) { + case WSAEWOULDBLOCK: + errno = EAGAIN; + break; + default: + errno = winsock_err; + break; + } +} +/* + * A wrapper around the socket() function. The purpose of this wrapper + * is to ensure that the global errno symbol is set if an error occurs, + * even if we are using winsock. + */ +SOCKET +win32_socket(int domain, int type, int protocol) +{ + SOCKET fd = socket(domain, type, protocol); + if(fd == INVALID_SOCKET) { + set_socket_errno(WSAGetLastError()); + } + return fd; +} +/* + * A wrapper around the connect() function. The purpose of this wrapper + * is to ensure that the global errno symbol is set if an error occurs, + * even if we are using winsock. + */ +int +win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len) +{ + int rc = connect(fd, addr, addr_len); + assert(rc == 0 || rc == SOCKET_ERROR); + if(rc == SOCKET_ERROR) { + set_connect_errno(WSAGetLastError()); + } + return rc; +} + +/* + * A wrapper around the accept() function. The purpose of this wrapper + * is to ensure that the global errno symbol is set if an error occurs, + * even if we are using winsock. + */ +SOCKET +win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len) +{ + SOCKET newfd = accept(fd, addr, addr_len); + if(newfd == INVALID_SOCKET) { + set_socket_errno(WSAGetLastError()); + newfd = -1; + } + return newfd; +} + +/* + * A wrapper around the shutdown() function. The purpose of this wrapper + * is to ensure that the global errno symbol is set if an error occurs, + * even if we are using winsock. + */ +int +win32_shutdown(SOCKET fd, int mode) +{ + int rc = shutdown(fd, mode); + assert(rc == 0 || rc == SOCKET_ERROR); + if(rc == SOCKET_ERROR) { + set_socket_errno(WSAGetLastError()); + } + return rc; +} +int win32_close_socket(SOCKET fd) { + int rc; + + rc = closesocket(fd); + return 0; +} + + +int win32_write_socket(SOCKET fd, void *buf, int n) +{ + int rc = send(fd, buf, n, 0); + if(rc == SOCKET_ERROR) { + set_socket_errno(WSAGetLastError()); + } + return rc; +} + +int win32_read_socket(SOCKET fd, void *buf, int n) +{ + int rc = recv(fd, buf, n, 0); + if(rc == SOCKET_ERROR) { + set_socket_errno(WSAGetLastError()); + } + return rc; +} + + +char * win32_strtok_r(char *s, const char *delim, char **lasts) +{ + register char *spanp; + register int c, sc; + char *tok; + + + if (s == NULL && (s = *lasts) == NULL) + return (NULL); + + /* + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). + */ +cont: + c = *s++; + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + if (c == sc) + goto cont; + } + + if (c == 0) { /* no non-delimiter characters */ + *lasts = NULL; + return (NULL); + } + tok = s - 1; + + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *lasts = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +char *win32_strsep (char **stringp, const char *delim) +{ + register char *s; + register const char *spanp; + register int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +#endif + + diff --git a/mingw/mingw.h b/mingw/mingw.h new file mode 100644 index 000000000..93b3702d2 --- /dev/null +++ b/mingw/mingw.h @@ -0,0 +1,61 @@ +#ifdef __MINGW32__ + +#include + +#include + +#define ENOTCONN WSAENOTCONN +#define EWOULDBLOCK WSAEWOULDBLOCK +#define ENOBUFS WSAENOBUFS +#define ECONNRESET WSAECONNRESET +#define ESHUTDOWN WSAESHUTDOWN +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define EPROTONOSUPPORT WSAEPROTONOSUPPORT +#define EINPROGRESS WSAEINPROGRESS +#define EISCONN WSAEISCONN + +/* winsock doesn't feature poll(), so there is a version implemented + * in terms of select() in mingw.c. The following definitions + * are copied from linux man pages. A poll() macro is defined to + * call the version in mingw.c. + */ +#define POLLIN 0x0001 /* There is data to read */ +#define POLLPRI 0x0002 /* There is urgent data to read */ +#define POLLOUT 0x0004 /* Writing now will not block */ +#define POLLERR 0x0008 /* Error condition */ +#define POLLHUP 0x0010 /* Hung up */ +#define POLLNVAL 0x0020 /* Invalid request: fd not open */ +struct pollfd { + SOCKET fd; /* file descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; +#define poll(x, y, z) win32_poll(x, y, z) + +/* These wrappers do nothing special except set the global errno variable if + * an error occurs (winsock doesn't do this by default). They set errno + * to unix-like values (i.e. WSAEWOULDBLOCK is mapped to EAGAIN), so code + * outside of this file "shouldn't" have to worry about winsock specific error + * handling. + */ +#define socket(x, y, z) win32_socket(x, y, z) +#define connect(x, y, z) win32_connect(x, y, z) +#define accept(x, y, z) win32_accept(x, y, z) +#define shutdown(x, y) win32_shutdown(x, y) + +/* Winsock uses int instead of the usual socklen_t */ +typedef int socklen_t; + +int win32_poll(struct pollfd *, unsigned int, int); +SOCKET win32_socket(int, int, int); +int win32_connect(SOCKET, struct sockaddr*, socklen_t); +SOCKET win32_accept(SOCKET, struct sockaddr*, socklen_t *); +int win32_shutdown(SOCKET, int); + +#define strtok_r(x, y, z) win32_strtok_r(x, y, z) +#define strsep(x,y) win32_strsep(x,y) + +char *win32_strtok_r(char *s, const char *delim, char **lasts); +char *win32_strsep(char **stringp, const char *delim); + +#endif From 24171a2fd824408563ee747718066505df95c42a Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sun, 29 Apr 2012 18:45:37 +0100 Subject: [PATCH 0143/1435] use correct headers --- mingw/mingw.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mingw/mingw.h b/mingw/mingw.h index 93b3702d2..a64da570f 100644 --- a/mingw/mingw.h +++ b/mingw/mingw.h @@ -2,7 +2,8 @@ #include -#include +#define _USE_W32_SOCKETS 1 +#include #define ENOTCONN WSAENOTCONN #define EWOULDBLOCK WSAEWOULDBLOCK From 6db2766e3fce0148fa4a5a5dc2a86fbbe5931415 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sun, 29 Apr 2012 18:47:38 +0100 Subject: [PATCH 0144/1435] undefine macros for socket redirection, fix warnings --- mingw/mingw.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mingw/mingw.c b/mingw/mingw.c index c394a160c..0cae043c1 100644 --- a/mingw/mingw.c +++ b/mingw/mingw.c @@ -2,6 +2,11 @@ #include "mingw.h" +#undef socket +#undef connect +#undef accept +#undef shutdown + #include #include #include @@ -10,7 +15,7 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) { struct timeval timeout, *toptr; fd_set ifds, ofds, efds, *ip, *op; - int i, rc; + unsigned int i, rc; /* Set up the file-descriptor sets in ifds, ofds and efds. */ FD_ZERO(&ifds); @@ -51,7 +56,7 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) return rc; if(rc > 0) { - for (i = 0; i < nfds; ++i) { + for ( i = 0; i < nfds; ++i) { int fd = fds[i].fd; if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) fds[i].revents |= POLLIN; @@ -162,7 +167,7 @@ int win32_close_socket(SOCKET fd) { int rc; rc = closesocket(fd); - return 0; + return rc; } From 2559ab0c30b6782e67c9a0a1622c04bde9ee51f5 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sun, 29 Apr 2012 18:48:26 +0100 Subject: [PATCH 0145/1435] use WSAStartup on windows, replace bzero with memset --- gdbserver/gdb-server.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index b0b43d8e2..bd478573f 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -170,8 +170,20 @@ int main(int argc, char** argv) { current_memory_map = make_memory_map(sl); +#ifdef __MINGW32__ + WSADATA wsadata; + if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0 ) { + goto winsock_error; + } +#endif + while(serve(sl, state.listen_port) == 0); +#ifdef __MINGW32__ +winsock_error: + WSACleanup(); +#endif + /* Switch back to mass storage mode before closing. */ stlink_run(sl); stlink_exit_debug_mode(sl); @@ -558,7 +570,7 @@ int serve(stlink_t *sl, int port) { setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); struct sockaddr_in serv_addr; - bzero(&serv_addr,sizeof(struct sockaddr_in)); + memset(&serv_addr,0,sizeof(struct sockaddr_in)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); serv_addr.sin_port = htons(port); From c5b021c6ab9a6a7fef9f3cf0f43ff2c26cd1b9de Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sun, 29 Apr 2012 18:49:08 +0100 Subject: [PATCH 0146/1435] allow use of %zx format specifier om mingw --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 7b4d59041..761591a6b 100644 --- a/configure.ac +++ b/configure.ac @@ -32,6 +32,7 @@ CFLAGS="$CFLAGS $USB_CFLAGS" case "${host}" in *-mingw32*) LIBS="$LIBS -lws2_32" + CPPFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CPPFLAGS" ;; esac AC_CONFIG_FILES([Makefile]) From 49bafd873992d96cd95184d45d5bd24bd657a323 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sun, 29 Apr 2012 19:30:27 +0100 Subject: [PATCH 0147/1435] wrap read/write socket functions on mingw --- mingw/mingw.c | 4 ++-- mingw/mingw.h | 14 ++++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/mingw/mingw.c b/mingw/mingw.c index 0cae043c1..493dcbaa2 100644 --- a/mingw/mingw.c +++ b/mingw/mingw.c @@ -171,7 +171,7 @@ int win32_close_socket(SOCKET fd) { } -int win32_write_socket(SOCKET fd, void *buf, int n) +ssize_t win32_write_socket(SOCKET fd, void *buf, int n) { int rc = send(fd, buf, n, 0); if(rc == SOCKET_ERROR) { @@ -180,7 +180,7 @@ int win32_write_socket(SOCKET fd, void *buf, int n) return rc; } -int win32_read_socket(SOCKET fd, void *buf, int n) +ssize_t win32_read_socket(SOCKET fd, void *buf, int n) { int rc = recv(fd, buf, n, 0); if(rc == SOCKET_ERROR) { diff --git a/mingw/mingw.h b/mingw/mingw.h index a64da570f..28c7a82e0 100644 --- a/mingw/mingw.h +++ b/mingw/mingw.h @@ -39,10 +39,12 @@ struct pollfd { * outside of this file "shouldn't" have to worry about winsock specific error * handling. */ -#define socket(x, y, z) win32_socket(x, y, z) -#define connect(x, y, z) win32_connect(x, y, z) -#define accept(x, y, z) win32_accept(x, y, z) -#define shutdown(x, y) win32_shutdown(x, y) +#define socket(x, y, z) win32_socket(x, y, z) +#define connect(x, y, z) win32_connect(x, y, z) +#define accept(x, y, z) win32_accept(x, y, z) +#define shutdown(x, y) win32_shutdown(x, y) +#define read(x, y, z) win32_read_socket(x, y, z) +#define write(x, y, z) win32_write_socket(x, y, z) /* Winsock uses int instead of the usual socklen_t */ typedef int socklen_t; @@ -59,4 +61,8 @@ int win32_shutdown(SOCKET, int); char *win32_strtok_r(char *s, const char *delim, char **lasts); char *win32_strsep(char **stringp, const char *delim); +ssize_t win32_read_socket(SOCKET fd, void *buf, int n); +ssize_t win32_write_socket(SOCKET fd, void *buf, int n); + + #endif From c6b6f4c51d41451b613c9b1c29d40e39eaa4fce2 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sun, 29 Apr 2012 19:44:51 +0100 Subject: [PATCH 0148/1435] prototype main function properly --- example/blink/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/blink/main.c b/example/blink/main.c index 0a38069be..b70a136a3 100644 --- a/example/blink/main.c +++ b/example/blink/main.c @@ -1,7 +1,7 @@ /* missing type */ typedef unsigned int uint32_t; - +void main(void); /* hardware configuration */ From b61a06a8b71c68a40c9d7185a14c94079711b574 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Fri, 11 May 2012 14:11:12 -0400 Subject: [PATCH 0149/1435] Fixed issue #66 - Fixed the F4 memory map to include CCM RAM. https://github.com/texane/stlink/issues/66 --- gdbserver/gdb-server.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 94784fcdb..f6ec15bf5 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -182,7 +182,8 @@ static const char* const memory_map_template_F4 = " \"http://sourceware.org/gdb/gdb-memory-map.dtd\">" "" " " // code = sram, bootrom or flash; flash is bigger - " " // sram + " " // ccm ram + " " // sram " " //Sectors 0..3 " 0x4000" //16kB " " From d02326726a82f9c65263205f587f13ec11c7e7f0 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sun, 13 May 2012 22:54:26 +0100 Subject: [PATCH 0150/1435] fix signedness warning --- gdbserver/gdb-remote.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdbserver/gdb-remote.c b/gdbserver/gdb-remote.c index 1b0488e32..edf53389b 100644 --- a/gdbserver/gdb-remote.c +++ b/gdbserver/gdb-remote.c @@ -20,7 +20,7 @@ static const char hex[] = "0123456789abcdef"; int gdb_send_packet(int fd, char* data) { - unsigned length = strlen(data) + 5; + int length = strlen(data) + 5; char* packet = malloc(length); /* '$' data (hex) '#' cksum (hex) */ memset(packet, 0, length); From 947c1409e371f5ec0dca8a851f5b681d722d6ab5 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sun, 13 May 2012 22:55:41 +0100 Subject: [PATCH 0151/1435] cast to avoid pointer warning --- gdbserver/gdb-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index bd478573f..0d67abd0f 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -567,7 +567,7 @@ int serve(stlink_t *sl, int port) { } unsigned int val = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); struct sockaddr_in serv_addr; memset(&serv_addr,0,sizeof(struct sockaddr_in)); From 80d603582862ea0332dc301352655e8c086776dd Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sun, 13 May 2012 22:57:27 +0100 Subject: [PATCH 0152/1435] use sys/time.h for mingw compatiblity, use LIBUSB_CALL modifier for callback --- src/stlink-usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index d945f66ec..580722766 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include @@ -57,7 +57,7 @@ struct trans_ctx { volatile unsigned long flags; }; -static void on_trans_done(struct libusb_transfer * trans) { +static void LIBUSB_CALL on_trans_done(struct libusb_transfer * trans) { struct trans_ctx * const ctx = trans->user_data; if (trans->status != LIBUSB_TRANSFER_COMPLETED) From 802049ed7da8ac6074120c127cf2ac096f67316a Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Mon, 14 May 2012 10:55:55 +0100 Subject: [PATCH 0153/1435] bump stlink version --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 761591a6b..866d8bbd5 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([stlink],[0.5.1],[davem@devkitpro.org]) +AC_INIT([stlink],[0.5.2],[davem@devkitpro.org]) AC_CONFIG_SRCDIR([src/stlink-common.c]) AC_CONFIG_LIBOBJ_DIR([src]) AM_INIT_AUTOMAKE([1.10]) From c0eb32267c56b2eb63e6b7ecdf0d2980e158df68 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Mon, 14 May 2012 10:57:41 +0100 Subject: [PATCH 0154/1435] ignore elf files in example --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d1d6410ff..0a705b55b 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ st-util *.a Makefile *.exe +example/blink/*.elf From 8e4efc36028140a7ac7fffd181040654a4931bd1 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Wed, 16 May 2012 22:15:38 +0100 Subject: [PATCH 0155/1435] reimplement mingw mmap --- configure.ac | 3 +-- src/mmap.c | 74 ++++++++++++++-------------------------------------- src/mmap.h | 59 ++++++++++------------------------------- src/pread.c | 42 ----------------------------- 4 files changed, 34 insertions(+), 144 deletions(-) delete mode 100644 src/pread.c diff --git a/configure.ac b/configure.ac index 866d8bbd5..f7feed2cc 100644 --- a/configure.ac +++ b/configure.ac @@ -18,8 +18,7 @@ AM_PROG_CC_C_O AC_CHECK_HEADERS(sys/mman.h) AC_CHECK_HEADERS(sys/poll.h) -AC_CHECK_FUNCS(mmap) -AC_REPLACE_FUNCS(mmap pread) +AC_REPLACE_FUNCS(mmap) # Checks for libraries. PKG_CHECK_MODULES(USB, libusb-1.0 >= 1.0.0,, diff --git a/src/mmap.c b/src/mmap.c index 7316389b9..8a0a2e361 100644 --- a/src/mmap.c +++ b/src/mmap.c @@ -1,69 +1,33 @@ -/* mmap.c -- version of mmap for gold. */ - -/* Copyright 2009 Free Software Foundation, Inc. - Written by Vladimir Simonov . - - This file is part of gold. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -//#include "config.h" -//#include "ansidecl.h" - #include #include -#ifdef HAVE_STDLIB_H #include -#endif +#include #include "mmap.h" -extern ssize_t pread (int, void *, size_t, off_t); - -void * -mmap (void *__addr, size_t __len, int __prot, - int __flags, int __fd, long long __offset) -{ - void *ret; - ssize_t count; +void *mmap (void *addr, size_t len, int prot, int flags, int fd, long long offset) { - if (__addr || (__fd != -1 && (__prot & PROT_WRITE)) - || (__flags & MAP_SHARED)) - return MAP_FAILED; + void *buf; + ssize_t count; - ret = malloc (__len); - if (!ret) - return MAP_FAILED; + if ( addr || fd == -1 || (prot & PROT_WRITE)) return MAP_FAILED; - if (__fd == -1) - return ret; + buf = malloc(len); + if ( NULL == buf ) return MAP_FAILED; - count = pread (__fd, ret, __len, __offset); - if ((size_t) count != __len) - { - free (ret); - return MAP_FAILED; - } + if (lseek(fd,offset,SEEK_SET) != offset) return MAP_FAILED; + + count = read(fd, buf, len); + + if (count != len) { + free (buf); + return MAP_FAILED; + } - return ret; + return buf; } -int -munmap (void *__addr, size_t __len) -{ - free (__addr); - return 0; +int munmap (void *addr, size_t len) { + free (addr); + return 0; } diff --git a/src/mmap.h b/src/mmap.h index 375eafb7b..bff766c4a 100644 --- a/src/mmap.h +++ b/src/mmap.h @@ -1,62 +1,31 @@ -/* mmap.h -- mmap family functions prototypes for gold. */ - -/* Copyright 2009 Free Software Foundation, Inc. - Written by Vladimir Simonov - - This file is part of gold. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#ifndef GOLD_MMAP_H -#define GOLD_MMAP_H +#ifndef STLINK_MMAP_H +#define STLINK_MMAP_H #ifdef HAVE_SYS_MMAN_H - #include - -/* Some BSD systems still use MAP_ANON instead of MAP_ANONYMOUS. */ - -#ifndef MAP_ANONYMOUS -# define MAP_ANONYMOUS MAP_ANON -#endif - #else -#define PROT_READ 0x1 -#define PROT_WRITE 0x2 +#define PROT_READ (1<<0) +#define PROT_WRITE (1<<1) -#define MAP_SHARED 0x01 -#define MAP_PRIVATE 0x02 +#define MAP_SHARED (1<<0) +#define MAP_PRIVATE (1<<1) -#define MAP_ANONYMOUS 0x20 +#define MAP_ANONYMOUS (1<<5) -#define MAP_FAILED ((void *) -1) -#endif /* HAVE_SYS_MMAN_H */ +#define MAP_FAILED ((void *)-1) -#ifndef HAVE_MMAP #ifdef __cplusplus extern "C" { #endif -extern void *mmap (void *__addr, size_t __len, int __prot, - int __flags, int __fd, long long __offset); -extern int munmap (void *__addr, size_t __len); + +void *mmap(void *addr, size_t len, int prot, int flags, int fd, long long offset); +int munmap(void *addr, size_t len); + #ifdef __cplusplus } #endif -#endif /* HAVE_MMAP */ +#endif /* HAVE_SYS_MMAN_H */ -#endif /* GOLD_MMAP_H */ +#endif /* STLINK_MMAP_H */ diff --git a/src/pread.c b/src/pread.c deleted file mode 100644 index 4ac61155c..000000000 --- a/src/pread.c +++ /dev/null @@ -1,42 +0,0 @@ -/* pread.c -- version of pread for gold. */ - -/* Copyright 2006, 2007, 2009 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of gold. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -/* This file implements pread for systems which don't have it. This - file is only compiled if pread is not present on the system. This - is not an exact version of pread, as it does not preserve the - current file offset. */ - -//#include "config.h" - -#include -#include -#include - -extern ssize_t pread (int, void *, size_t, off_t); - -ssize_t -pread (int fd, void *buf, size_t count, off_t offset) -{ - if (lseek(fd, offset, SEEK_SET) != offset) - return -1; - return read(fd, buf, count); -} From 5bbef2f18bd36e510dcff6aab43d65203aeb3e73 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Wed, 16 May 2012 22:22:54 +0100 Subject: [PATCH 0156/1435] fix whitespace --- src/mmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mmap.c b/src/mmap.c index 8a0a2e361..9c631da2d 100644 --- a/src/mmap.c +++ b/src/mmap.c @@ -16,9 +16,9 @@ void *mmap (void *addr, size_t len, int prot, int flags, int fd, long long offs if ( NULL == buf ) return MAP_FAILED; if (lseek(fd,offset,SEEK_SET) != offset) return MAP_FAILED; - + count = read(fd, buf, len); - + if (count != len) { free (buf); return MAP_FAILED; From 89016d1d86de485ecb1f75312f17ee3574d07f0b Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Wed, 16 May 2012 22:44:31 +0100 Subject: [PATCH 0157/1435] add COPYING to repository to avoid license confusion --- .gitignore | 1 - COPYING | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 COPYING diff --git a/.gitignore b/.gitignore index 0a705b55b..cf2f1a448 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -COPYING INSTALL Makefile.in aclocal.m4 diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..37b124eba --- /dev/null +++ b/COPYING @@ -0,0 +1,27 @@ +Copyright (c) 2011 The "Capt'ns Missing Link" Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Martin Capitanio nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From 4080a3ecbb8fcf7ac83cc53903a0b8f379cc3fc0 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Wed, 16 May 2012 23:31:07 +0100 Subject: [PATCH 0158/1435] bump version --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index f7feed2cc..1f00f3a80 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([stlink],[0.5.2],[davem@devkitpro.org]) +AC_INIT([stlink],[0.5.3],[davem@devkitpro.org]) AC_CONFIG_SRCDIR([src/stlink-common.c]) AC_CONFIG_LIBOBJ_DIR([src]) AM_INIT_AUTOMAKE([1.10]) From 299c5d272f58c7cb803d6a61ca16d9551c7697e5 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Wed, 16 May 2012 23:41:42 +0100 Subject: [PATCH 0159/1435] use BSD timersub --- src/stlink-usb.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 580722766..20e5cd22e 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -16,17 +16,18 @@ #define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args) #define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args) -#ifndef timersub -/* This is a copy from GNU C Library (GNU LGPL 2.1), sys/time.h. */ -# define timersub(a, b, result) \ - do { \ - (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((result)->tv_usec < 0) { \ - --(result)->tv_sec; \ - (result)->tv_usec += 1000000; \ - } \ - } while (0) +/* code from bsd timersub.h +http://www.gnu-darwin.org/www001/src/ports/net/libevnet/work/libevnet-0.3.8/libnostd/bsd/sys/time/timersub.h.html +*/ +#if !defined timersub +#define timersub(a, b, r) do { \ + (r)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (r)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((r)->tv_usec < 0) { \ + --(r)->tv_sec; \ + (r)->tv_usec += 1000000; \ + } \ +} while (0) #endif enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80}; From fc85ba71f1bd1eeebbc36e69bc5d667c812784b3 Mon Sep 17 00:00:00 2001 From: Fabien Le Mentec Date: Thu, 17 May 2012 01:39:16 -0500 Subject: [PATCH 0160/1435] [ fix ] missing LIBUSB_CALL definition --- src/stlink-usb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 20e5cd22e..72ffda177 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -58,6 +58,10 @@ struct trans_ctx { volatile unsigned long flags; }; +#ifndef LIBUSB_CALL +# define LIBUSB_CALL +#endif + static void LIBUSB_CALL on_trans_done(struct libusb_transfer * trans) { struct trans_ctx * const ctx = trans->user_data; From 105b293a1501154c69663b4fb29671a8d2cc62ec Mon Sep 17 00:00:00 2001 From: Tectu Date: Fri, 25 May 2012 17:05:44 +0200 Subject: [PATCH 0161/1435] fixed option bytes amount --- gdbserver/gdb-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 91fb8dced..7a525d535 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -228,7 +228,7 @@ static const char* const memory_map_template = " " // peripheral regs " " // cortex regs " " // bootrom - " " // option byte area + " " // option byte area ""; char* make_memory_map(stlink_t *sl) { From a303d9fe7a698d85f87500e0ad7229a1a76d4b21 Mon Sep 17 00:00:00 2001 From: Fabien Le Mentec Date: Sat, 26 May 2012 09:48:48 -0500 Subject: [PATCH 0162/1435] [ fix ] apply jserv@0xlab.org patch, 0001-trivial-documentation-fix-for-st-util-path --- AUTHORS | 1 + README | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index 8153669c7..1096c1735 100644 --- a/AUTHORS +++ b/AUTHORS @@ -14,3 +14,4 @@ bravikov@gmail.com jnosky - codegrinder69@hotmail.com marpe@mimuw.edu.pl marco.cassinerio@gmail.com +jserv@0xlab.org \ No newline at end of file diff --git a/README b/README index bb06f60a9..d99337c2a 100644 --- a/README +++ b/README @@ -37,11 +37,11 @@ You're ready to go :) To run the gdb server, do (you do not need sudo if you have set up permissions correctly): -$ make && [sudo] ./gdbserver/st-util +$ make && [sudo] ./st-util There are a few options: -./gdbserver/st-util - usage: +./st-util - usage: -h, --help Print this help -vXX, --verbose=XX specify a specific verbosity level (0..99) From 14db250dcc263ec5bcc959c31430dbde5caff868 Mon Sep 17 00:00:00 2001 From: Fabien Le Mentec Date: Sun, 3 Jun 2012 01:40:27 -0500 Subject: [PATCH 0163/1435] [ update ] F0 chip id --- src/stlink-common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index 29640fd70..3f8a7f0e5 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -394,6 +394,7 @@ uint32_t stlink_core_id(stlink_t *sl) { uint32_t stlink_chip_id(stlink_t *sl) { uint32_t chip_id = stlink_read_debug32(sl, 0xE0042000); + if (chip_id == 0) chip_id = stlink_read_debug32(sl, 0xE000ED00); return chip_id; } From 9ccb398ab73804d9cd2eba060a7f5a42f7d76aeb Mon Sep 17 00:00:00 2001 From: Mike Szczys Date: Sun, 3 Jun 2012 10:39:34 -0500 Subject: [PATCH 0164/1435] Corrected F0 DBGMCU_IDCODE register address --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 3f8a7f0e5..f0a0c236e 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -394,7 +394,7 @@ uint32_t stlink_core_id(stlink_t *sl) { uint32_t stlink_chip_id(stlink_t *sl) { uint32_t chip_id = stlink_read_debug32(sl, 0xE0042000); - if (chip_id == 0) chip_id = stlink_read_debug32(sl, 0xE000ED00); + if (chip_id == 0) chip_id = stlink_read_debug32(sl, 0x40015800); //Try Corex M0 DBGMCU_IDCODE register address return chip_id; } From 8975f92574d5d6476ef2d86407247a2f3a6d2e13 Mon Sep 17 00:00:00 2001 From: Mike Szczys Date: Sun, 3 Jun 2012 10:44:48 -0500 Subject: [PATCH 0165/1435] Added memory map for STM32F05xxx chips --- src/stlink-common.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/stlink-common.h b/src/stlink-common.h index 6fcb2194e..ee59094b6 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -221,6 +221,17 @@ extern "C" { .sram_size = 0x18000, .bootrom_base = 0x1fffe000, .bootrom_size = 0x1800 + }, + { + //Use this as an example for mapping future chips: + //RM0091 document was used to find these paramaters + .chip_id = 0x440, + .description = "F0 device", + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 } }; From bdb1a498df58f00c84378ff54e9077f1bfb197a7 Mon Sep 17 00:00:00 2001 From: Mike Szczys Date: Sun, 3 Jun 2012 10:47:18 -0500 Subject: [PATCH 0166/1435] Added STM32F0-Discovery board to the blink example code --- example/blink/Makefile | 5 ++++- example/blink/main.c | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/example/blink/Makefile b/example/blink/Makefile index cf7221da8..60fab84c8 100644 --- a/example/blink/Makefile +++ b/example/blink/Makefile @@ -12,8 +12,9 @@ DEF_CFLAGS+=-Wl,-Ttext,0x20000000 -Wl,-e,0x20000000 CFLAGS_VL=$(DEF_CFLAGS) -mcpu=cortex-m3 -DCONFIG_STM32VL_DISCOVERY=1 CFLAGS_L=$(DEF_CFLAGS) -mcpu=cortex-m3 -DCONFIG_STM32L_DISCOVERY CFLAGS_F4=$(DEF_CFLAGS) -mcpu=cortex-m4 -DCONFIG_STM32F4_DISCOVERY=1 +CFLAGS_F0=$(DEF_CFLAGS) -mcpu=cortex-m0 -DCONFIG_STM32F0_DISCOVERY=1 -all: blink_32VL.elf blink_32L.elf blink_F4.elf +all: blink_32VL.elf blink_32L.elf blink_F4.elf blink_F0.elf %.bin: %.elf $(OBJCOPY) -O binary $^ $@ @@ -24,6 +25,8 @@ blink_32L.elf: main.c $(CC) $(CFLAGS_L) $^ -o $@ blink_F4.elf: main.c $(CC) $(CFLAGS_F4) $^ -o $@ +blink_F0.elf: main.c + $(CC) $(CFLAGS_F0) $^ -o $@ clean: rm -rf *.elf diff --git a/example/blink/main.c b/example/blink/main.c index b70a136a3..26fcca029 100644 --- a/example/blink/main.c +++ b/example/blink/main.c @@ -58,6 +58,26 @@ static inline void setup_leds(void) (1 << (13 * 2)) | (1 << (14 * 2)) | (1 << (15 * 2)); } +#elif CONFIG_STM32F0_DISCOVERY + +#define GPIOC 0x48000800 /* port C */ +#define GPIOC_MODER (GPIOC + 0x00) /* port mode register */ +#define LED_PORT_ODR (GPIOC + 0x14) /* port output data register */ + +#define LED_BLUE (1 << 8) /* port C, pin 8 */ +#define LED_GREEN (1 << 9) /* port C, pin 9 */ +#define LED_ORANGE 0 +#define LED_RED 0 + +void _tmain(void) { + main(); +} +static inline void setup_leds(void) +{ + /* configure port 8 and 9 as output */ + *(volatile uint32_t*)GPIOC_MODER |= (1 << (9* 2)) | (1 << (8 * 2)); +} + #else #error "Architecture must be defined!" #endif /* otherwise, error */ From cfb1e862525f95252e367ccc38845da5a9a017af Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 7 Jun 2012 18:03:23 +0200 Subject: [PATCH 0167/1435] st-flash: Honor size, if given --- flash/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flash/main.c b/flash/main.c index 24287456b..4716b66e1 100644 --- a/flash/main.c +++ b/flash/main.c @@ -154,10 +154,10 @@ int main(int ac, char** av) } else /* read */ { - if ((o.addr >= sl->flash_base) && + if ((o.addr >= sl->flash_base) && (o.size == 0) && (o.addr < sl->flash_base + sl->flash_size)) o.size = sl->flash_size; - else if ((o.addr >= sl->sram_base) && + else if ((o.addr >= sl->sram_base) && (o.size == 0) && (o.addr < sl->sram_base + sl->sram_size)) o.size = sl->sram_size; err = stlink_fread(sl, o.filename, o.addr, o.size); From 0e7ee109f6c37dd2f1acfdc861eb12803e96eabb Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 7 Jun 2012 18:13:43 +0200 Subject: [PATCH 0168/1435] Add \n to WLOG when no STLINK found --- src/stlink-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 72ffda177..a25f7ec55 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -652,7 +652,7 @@ stlink_t* stlink_open_usb(const int verbose) { if (slu->usb_handle == NULL) { slu->usb_handle = libusb_open_device_with_vid_pid(slu->libusb_ctx, USB_ST_VID, USB_STLINK_PID); if (slu->usb_handle == NULL) { - WLOG("Couldn't find any ST-Link/V2 devices"); + WLOG("Couldn't find any ST-Link/V2 devices\n"); goto on_error; } slu->protocoll = 1; From 8151bf5c4a443608d4fec15cf7dfe79a02cdd096 Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Thu, 7 Jun 2012 23:16:19 +0200 Subject: [PATCH 0169/1435] Added flash loader stub for F2/F4. --- flashloaders/stm32f4.s | 32 ++++++++++++++++++++ src/stlink-common.c | 68 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 flashloaders/stm32f4.s diff --git a/flashloaders/stm32f4.s b/flashloaders/stm32f4.s new file mode 100644 index 000000000..6cad73042 --- /dev/null +++ b/flashloaders/stm32f4.s @@ -0,0 +1,32 @@ +.global start +.syntax unified + +@ r0 = source +@ r1 = target +@ r2 = wordcount +@ r3 = flash_base +@ r4 = temp + +start: + ldr r3, flash_base +next: + cbz r2, done + ldr r4, [r0] + str r4, [r1] + +wait: + ldrh r4, [r3, #0x0e] + tst.w r4, #1 + bne wait + + add r0, #4 + add r1, #4 + sub r2, #1 + b next +done: + bkpt + +.align 2 + +flash_base: + .word 0x40023c00 diff --git a/src/stlink-common.c b/src/stlink-common.c index f0a0c236e..08bd0bb4d 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1182,6 +1182,28 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0x00, 0xbe }; + static const uint8_t loader_code_stm32f4[] = { + // flashloaders/stm32f4.s + + 0x07, 0x4b, + + 0x62, 0xb1, + 0x04, 0x68, + 0x0c, 0x60, + + 0xdc, 0x89, + 0x14, 0xf0, 0x01, 0x0f, + 0xfb, 0xd1, + 0x00, 0xf1, 0x04, 0x00, + 0x01, 0xf1, 0x04, 0x01, + 0xa2, 0xf1, 0x01, 0x02, + 0xf1, 0xe7, + + 0x00, 0xbe, + + 0x00, 0x3c, 0x02, 0x40, + }; + const uint8_t* loader_code; size_t loader_size; @@ -1195,6 +1217,11 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); } + else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) + { + loader_code = loader_code_stm32f4; + loader_size = sizeof(loader_code_stm32f4); + } else { WLOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); @@ -1358,6 +1385,13 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned if ((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) { /* todo: check write operation */ + ILOG("Starting Flash write for F2/F4\n"); + /* flash loader initialization */ + if (init_flash_loader(sl, &fl) == -1) { + WLOG("init_flash_loader() == -1\n"); + return -1; + } + /* First unlock the cr */ unlock_flash_if(sl); @@ -1368,6 +1402,20 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned /* set programming mode */ set_flash_cr_pg(sl); + for(off = 0; off < len;) { + size_t size = len - off > 0x8000 ? 0x8000 : len - off; + + printf("size: %u\n", size); + + if (run_flash_loader(sl, &fl, addr + off, base + off, size) == -1) { + WLOG("run_flash_loader(%#zx) failed! == -1\n", addr + off); + return -1; + } + + off += size; + } + +#if 0 #define PROGRESS_CHUNK_SIZE 0x1000 /* write a word in program memory */ for (off = 0; off < len; off += sizeof(uint32_t)) { @@ -1389,6 +1437,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned wait_flash_busy(sl); } +#endif /* Relock flash */ lock_flash(sl); @@ -1618,6 +1667,17 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, 0, 3); /* flash bank 0 (input) */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ + } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { + + size_t count = size / sizeof(uint32_t); + if (size % sizeof(uint32_t)) ++count; + + /* setup core */ + stlink_write_reg(sl, fl->buf_addr, 0); /* source */ + stlink_write_reg(sl, target, 1); /* target */ + stlink_write_reg(sl, count, 2); /* count (32 bits words) */ + stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ + } else { fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id); return -1; @@ -1657,6 +1717,14 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } + } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { + + stlink_read_reg(sl, 2, &rr); + if (rr.r[2] != 0) { + fprintf(stderr, "write error, count == %u\n", rr.r[2]); + return -1; + } + } else { fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id); From 75c434ef2d962cf822eaf9850bf2617a20c2c06f Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 20 Jun 2012 19:01:27 +0000 Subject: [PATCH 0170/1435] Examples have no place in stlink codebase. They should be in a standalone repository, that can focus on clean, easy to follow, well documented, well tested examples. If you just want some example binaries that you can use to test your installation is working, the libopencm3 project has various blink projects for all the STM32 Discovery boards. --- example/32l_dac/Makefile | 40 - example/32l_dac/discover_board.h | 61 - example/32l_dac/main.c | 242 - example/32l_dac/startup_stm32l1xx_md.s | 365 - example/32l_dac/stm32_flash.ld | 173 - example/32l_dac/system_stm32l1xx.c | 367 - example/32l_lcd/Makefile | 42 - example/32l_lcd/discover_board.h | 61 - example/32l_lcd/linker_stm32l.lds | 54 - example/32l_lcd/main.c | 351 - example/32l_lcd/stm32l_discovery_lcd.c | 614 -- example/32l_lcd/stm32l_discovery_lcd.h | 127 - example/32vl_factory_demo/Makefile | 53 - example/32vl_factory_demo/README | 5 - example/32vl_factory_demo/main.c | 234 - example/32vl_factory_demo/stm32f10x_conf.h | 76 - example/32vl_factory_demo/stm32f10x_it.c | 160 - example/32vl_factory_demo/stm32f10x_it.h | 46 - example/32vl_factory_demo/system_stm32f10x.c | 1019 -- example/README | 6 - example/blink/Makefile | 35 - example/blink/main.c | 114 - example/blink_flash/Makefile | 48 - example/blink_flash/discover_board.h | 61 - example/blink_flash/main.c | 197 - example/blink_flash/startup_stm32l1xx_md.s | 365 - example/blink_flash/stm32_flash.ld | 173 - example/blink_flash/system_stm32l1xx.c | 367 - example/libs_stm/README | 9 - example/libs_stm/build/Makefile | 10 - example/libs_stm/build/Makefile.common | 34 - example/libs_stm/build/Makefile.f10x | 5 - example/libs_stm/build/Makefile.l1xx | 5 - example/libs_stm/inc/base/stdint.h | 16 - example/libs_stm/inc/core_support/core_cm3.c | 784 -- example/libs_stm/inc/core_support/core_cm3.h | 1818 ---- .../libs_stm/inc/device_support/stm32f10x.h | 8227 ----------------- .../libs_stm/inc/device_support/stm32l1xx.h | 5140 ---------- .../inc/device_support/system_stm32f10x.h | 97 - .../inc/device_support/system_stm32l1xx.h | 98 - example/libs_stm/inc/stm32f10x/misc.h | 219 - .../libs_stm/inc/stm32f10x/stm32f10x_adc.h | 482 - .../libs_stm/inc/stm32f10x/stm32f10x_bkp.h | 194 - .../libs_stm/inc/stm32f10x/stm32f10x_can.h | 535 -- .../libs_stm/inc/stm32f10x/stm32f10x_cec.h | 209 - .../libs_stm/inc/stm32f10x/stm32f10x_crc.h | 93 - .../libs_stm/inc/stm32f10x/stm32f10x_dac.h | 316 - .../libs_stm/inc/stm32f10x/stm32f10x_dbgmcu.h | 118 - .../libs_stm/inc/stm32f10x/stm32f10x_dma.h | 437 - .../libs_stm/inc/stm32f10x/stm32f10x_exti.h | 183 - .../libs_stm/inc/stm32f10x/stm32f10x_flash.h | 425 - .../libs_stm/inc/stm32f10x/stm32f10x_fsmc.h | 716 -- .../libs_stm/inc/stm32f10x/stm32f10x_gpio.h | 379 - .../libs_stm/inc/stm32f10x/stm32f10x_i2c.h | 670 -- .../libs_stm/inc/stm32f10x/stm32f10x_iwdg.h | 139 - .../libs_stm/inc/stm32f10x/stm32f10x_pwr.h | 155 - .../libs_stm/inc/stm32f10x/stm32f10x_rcc.h | 726 -- .../libs_stm/inc/stm32f10x/stm32f10x_rtc.h | 134 - .../libs_stm/inc/stm32f10x/stm32f10x_sdio.h | 530 -- .../libs_stm/inc/stm32f10x/stm32f10x_spi.h | 490 - .../libs_stm/inc/stm32f10x/stm32f10x_tim.h | 1133 --- .../libs_stm/inc/stm32f10x/stm32f10x_usart.h | 411 - .../libs_stm/inc/stm32f10x/stm32f10x_wwdg.h | 114 - example/libs_stm/inc/stm32l1xx/misc.h | 196 - .../libs_stm/inc/stm32l1xx/stm32l1xx_adc.h | 606 -- .../libs_stm/inc/stm32l1xx/stm32l1xx_comp.h | 180 - .../libs_stm/inc/stm32l1xx/stm32l1xx_crc.h | 77 - .../libs_stm/inc/stm32l1xx/stm32l1xx_dac.h | 299 - .../libs_stm/inc/stm32l1xx/stm32l1xx_dbgmcu.h | 98 - .../libs_stm/inc/stm32l1xx/stm32l1xx_dma.h | 363 - .../libs_stm/inc/stm32l1xx/stm32l1xx_exti.h | 190 - .../libs_stm/inc/stm32l1xx/stm32l1xx_flash.h | 354 - .../libs_stm/inc/stm32l1xx/stm32l1xx_gpio.h | 364 - .../libs_stm/inc/stm32l1xx/stm32l1xx_i2c.h | 688 -- .../libs_stm/inc/stm32l1xx/stm32l1xx_iwdg.h | 128 - .../libs_stm/inc/stm32l1xx/stm32l1xx_lcd.h | 446 - .../libs_stm/inc/stm32l1xx/stm32l1xx_pwr.h | 207 - .../libs_stm/inc/stm32l1xx/stm32l1xx_rcc.h | 468 - .../libs_stm/inc/stm32l1xx/stm32l1xx_rtc.h | 611 -- .../libs_stm/inc/stm32l1xx/stm32l1xx_spi.h | 379 - .../libs_stm/inc/stm32l1xx/stm32l1xx_syscfg.h | 387 - .../libs_stm/inc/stm32l1xx/stm32l1xx_tim.h | 907 -- .../libs_stm/inc/stm32l1xx/stm32l1xx_usart.h | 403 - .../libs_stm/inc/stm32l1xx/stm32l1xx_wwdg.h | 104 - ..._Notes_for_STM32F10x_StdPeriph_Driver.html | 203 - example/libs_stm/src/stm32f10x/misc.c | 223 - .../libs_stm/src/stm32f10x/stm32f10x_adc.c | 1306 --- .../libs_stm/src/stm32f10x/stm32f10x_bkp.c | 311 - .../libs_stm/src/stm32f10x/stm32f10x_can.c | 990 -- .../libs_stm/src/stm32f10x/stm32f10x_cec.c | 432 - .../libs_stm/src/stm32f10x/stm32f10x_crc.c | 163 - .../libs_stm/src/stm32f10x/stm32f10x_dac.c | 579 -- .../libs_stm/src/stm32f10x/stm32f10x_dbgmcu.c | 161 - .../libs_stm/src/stm32f10x/stm32f10x_dma.c | 693 -- .../libs_stm/src/stm32f10x/stm32f10x_exti.c | 268 - .../libs_stm/src/stm32f10x/stm32f10x_flash.c | 1735 ---- .../libs_stm/src/stm32f10x/stm32f10x_fsmc.c | 858 -- .../libs_stm/src/stm32f10x/stm32f10x_gpio.c | 642 -- .../libs_stm/src/stm32f10x/stm32f10x_i2c.c | 1285 --- .../libs_stm/src/stm32f10x/stm32f10x_iwdg.c | 189 - .../libs_stm/src/stm32f10x/stm32f10x_pwr.c | 316 - .../libs_stm/src/stm32f10x/stm32f10x_rcc.c | 1477 --- .../libs_stm/src/stm32f10x/stm32f10x_rtc.c | 341 - .../libs_stm/src/stm32f10x/stm32f10x_sdio.c | 798 -- .../libs_stm/src/stm32f10x/stm32f10x_spi.c | 907 -- .../libs_stm/src/stm32f10x/stm32f10x_tim.c | 2834 ------ .../libs_stm/src/stm32f10x/stm32f10x_usart.c | 1054 --- .../libs_stm/src/stm32f10x/stm32f10x_wwdg.c | 223 - example/libs_stm/src/stm32l1xx/misc.c | 249 - .../libs_stm/src/stm32l1xx/stm32l1xx_adc.c | 1803 ---- .../libs_stm/src/stm32l1xx/stm32l1xx_comp.c | 356 - .../libs_stm/src/stm32l1xx/stm32l1xx_crc.c | 127 - .../libs_stm/src/stm32l1xx/stm32l1xx_dac.c | 690 -- .../libs_stm/src/stm32l1xx/stm32l1xx_dbgmcu.c | 170 - .../libs_stm/src/stm32l1xx/stm32l1xx_dma.c | 752 -- .../libs_stm/src/stm32l1xx/stm32l1xx_exti.c | 313 - .../libs_stm/src/stm32l1xx/stm32l1xx_flash.c | 1335 --- .../src/stm32l1xx/stm32l1xx_flash_ramfunc.c | 385 - .../libs_stm/src/stm32l1xx/stm32l1xx_gpio.c | 546 -- .../libs_stm/src/stm32l1xx/stm32l1xx_i2c.c | 1333 --- .../libs_stm/src/stm32l1xx/stm32l1xx_iwdg.c | 263 - .../libs_stm/src/stm32l1xx/stm32l1xx_lcd.c | 637 -- .../libs_stm/src/stm32l1xx/stm32l1xx_pwr.c | 829 -- .../libs_stm/src/stm32l1xx/stm32l1xx_rcc.c | 1575 ---- .../libs_stm/src/stm32l1xx/stm32l1xx_rtc.c | 2138 ----- .../libs_stm/src/stm32l1xx/stm32l1xx_spi.c | 884 -- .../libs_stm/src/stm32l1xx/stm32l1xx_syscfg.c | 561 -- .../libs_stm/src/stm32l1xx/stm32l1xx_tim.c | 2832 ------ .../libs_stm/src/stm32l1xx/stm32l1xx_usart.c | 1432 --- .../libs_stm/src/stm32l1xx/stm32l1xx_wwdg.c | 307 - example/stm32f4/Projects/IO_Toggle/Makefile | 31 - example/stm32f4/Projects/IO_Toggle/main.c | 142 - example/stm32f4/Projects/IO_Toggle/readme.txt | 91 - .../Projects/IO_Toggle/startup_stm32f4xx.s | 509 - .../stm32f4/Projects/IO_Toggle/stm32_flash.ld | 170 - .../Projects/IO_Toggle/stm32f4_discovery.h | 158 - .../Projects/IO_Toggle/stm32f4xx_conf.h | 94 - .../stm32f4/Projects/IO_Toggle/stm32f4xx_it.c | 167 - .../stm32f4/Projects/IO_Toggle/stm32f4xx_it.h | 54 - .../Projects/IO_Toggle/system_stm32f4xx.c | 545 -- .../stm32f4/Projects/discovery_demo/Makefile | 61 - .../discovery_demo/Release_Notes.html | 151 - .../stm32f4/Projects/discovery_demo/main.c | 508 - .../stm32f4/Projects/discovery_demo/main.h | 62 - .../Projects/discovery_demo/selftest.c | 808 -- .../Projects/discovery_demo/selftest.h | 41 - .../discovery_demo/startup_stm32f4xx.s | 509 - .../Projects/discovery_demo/stm32_flash.ld | 170 - .../Projects/discovery_demo/stm32f4xx_conf.h | 94 - .../Projects/discovery_demo/stm32f4xx_it.c | 320 - .../Projects/discovery_demo/stm32f4xx_it.h | 54 - .../discovery_demo/system_stm32f4xx.c | 566 -- .../stm32f4/Projects/discovery_demo/usb_bsp.c | 382 - .../Projects/discovery_demo/usb_conf.h | 252 - .../Projects/discovery_demo/usb_core.c | 2187 ----- .../Projects/discovery_demo/usb_core.h | 408 - .../Projects/discovery_demo/usbd_conf.h | 93 - .../Projects/discovery_demo/usbd_desc.c | 313 - .../Projects/discovery_demo/usbd_desc.h | 114 - .../Projects/discovery_demo/usbd_usr.c | 238 - .../STM32F4xx_StdPeriph_Driver/build/Makefile | 60 - .../inc/core_support/arm_common_tables.h | 35 - .../inc/core_support/arm_math.h | 7051 -------------- .../inc/core_support/core_cm0.h | 665 -- .../inc/core_support/core_cm3.c | 784 -- .../inc/core_support/core_cm3.h | 1236 --- .../inc/core_support/core_cm4.h | 1378 --- .../inc/core_support/core_cm4_simd.h | 701 -- .../inc/core_support/core_cmFunc.h | 609 -- .../inc/core_support/core_cmInstr.h | 585 -- .../inc/device_support/stm32f4_discovery.h | 158 - .../inc/device_support/stm32f4xx.h | 7017 -------------- .../inc/device_support/system_stm32f4xx.h | 100 - .../STM32F4xx_StdPeriph_Driver/inc/misc.h | 172 - .../inc/stm32f4xx_adc.h | 643 -- .../inc/stm32f4xx_can.h | 638 -- .../inc/stm32f4xx_crc.h | 77 - .../inc/stm32f4xx_cryp.h | 338 - .../inc/stm32f4xx_dac.h | 298 - .../inc/stm32f4xx_dbgmcu.h | 103 - .../inc/stm32f4xx_dcmi.h | 306 - .../inc/stm32f4xx_dma.h | 603 -- .../inc/stm32f4xx_exti.h | 177 - .../inc/stm32f4xx_flash.h | 334 - .../inc/stm32f4xx_fsmc.h | 669 -- .../inc/stm32f4xx_gpio.h | 406 - .../inc/stm32f4xx_hash.h | 244 - .../inc/stm32f4xx_i2c.h | 692 -- .../inc/stm32f4xx_iwdg.h | 125 - .../inc/stm32f4xx_pwr.h | 163 - .../inc/stm32f4xx_rcc.h | 509 - .../inc/stm32f4xx_rng.h | 114 - .../inc/stm32f4xx_rtc.h | 875 -- .../inc/stm32f4xx_sdio.h | 530 -- .../inc/stm32f4xx_spi.h | 537 -- .../inc/stm32f4xx_syscfg.h | 173 - .../inc/stm32f4xx_tim.h | 1144 --- .../inc/stm32f4xx_usart.h | 412 - .../inc/stm32f4xx_wwdg.h | 105 - .../STM32F4xx_StdPeriph_Driver/src/misc.c | 243 - .../src/stm32f4xx_adc.c | 1742 ---- .../src/stm32f4xx_can.c | 1698 ---- .../src/stm32f4xx_crc.c | 127 - .../src/stm32f4xx_cryp.c | 850 -- .../src/stm32f4xx_cryp_aes.c | 638 -- .../src/stm32f4xx_cryp_des.c | 291 - .../src/stm32f4xx_cryp_tdes.c | 308 - .../src/stm32f4xx_dac.c | 701 -- .../src/stm32f4xx_dbgmcu.c | 174 - .../src/stm32f4xx_dcmi.c | 534 -- .../src/stm32f4xx_dma.c | 1283 --- .../src/stm32f4xx_exti.c | 306 - .../src/stm32f4xx_flash.c | 1054 --- .../src/stm32f4xx_fsmc.c | 982 -- .../src/stm32f4xx_gpio.c | 561 -- .../src/stm32f4xx_hash.c | 700 -- .../src/stm32f4xx_hash_md5.c | 314 - .../src/stm32f4xx_hash_sha1.c | 317 - .../src/stm32f4xx_i2c.c | 1395 --- .../src/stm32f4xx_iwdg.c | 263 - .../src/stm32f4xx_pwr.c | 638 -- .../src/stm32f4xx_rcc.c | 1811 ---- .../src/stm32f4xx_rng.c | 399 - .../src/stm32f4xx_rtc.c | 2733 ------ .../src/stm32f4xx_sdio.c | 1004 -- .../src/stm32f4xx_spi.c | 1290 --- .../src/stm32f4xx_syscfg.c | 204 - .../src/stm32f4xx_tim.c | 3349 ------- .../src/stm32f4xx_usart.c | 1462 --- .../src/stm32f4xx_wwdg.c | 303 - .../Class/audio/inc/usbd_audio_core.h | 158 - .../Class/audio/inc/usbd_audio_out_if.h | 117 - .../Class/audio/src/usbd_audio_core.c | 665 -- .../Class/audio/src/usbd_audio_out_if.c | 318 - .../Class/cdc/inc/usbd_cdc_core.h | 137 - .../Class/cdc/inc/usbd_cdc_if_template.h | 45 - .../Class/cdc/src/usbd_cdc_core.c | 811 -- .../Class/cdc/src/usbd_cdc_if_template.c | 202 - .../Class/dfu/inc/usbd_dfu_core.h | 187 - .../Class/dfu/inc/usbd_dfu_mal.h | 79 - .../Class/dfu/inc/usbd_flash_if.h | 49 - .../Class/dfu/inc/usbd_mem_if_template.h | 46 - .../Class/dfu/inc/usbd_otp_if.h | 43 - .../Class/dfu/src/usbd_dfu_core.c | 1046 --- .../Class/dfu/src/usbd_dfu_mal.c | 281 - .../Class/dfu/src/usbd_flash_if.c | 221 - .../Class/dfu/src/usbd_mem_if_template.c | 133 - .../Class/dfu/src/usbd_otp_if.c | 120 - .../Class/hid/inc/usbd_hid_core.h | 110 - .../Class/hid/src/usbd_hid_core.c | 460 - .../Class/msc/inc/usbd_msc_bot.h | 147 - .../Class/msc/inc/usbd_msc_core.h | 72 - .../Class/msc/inc/usbd_msc_data.h | 98 - .../Class/msc/inc/usbd_msc_mem.h | 106 - .../Class/msc/inc/usbd_msc_scsi.h | 189 - .../Class/msc/src/usbd_msc_bot.c | 393 - .../Class/msc/src/usbd_msc_core.c | 490 - .../Class/msc/src/usbd_msc_data.c | 128 - .../Class/msc/src/usbd_msc_scsi.c | 722 -- .../Class/msc/src/usbd_storage_template.c | 179 - .../Core/inc/usbd_conf_template.h | 78 - .../Core/inc/usbd_core.h | 114 - .../Core/inc/usbd_def.h | 149 - .../Core/inc/usbd_ioreq.h | 115 - .../Core/inc/usbd_req.h | 102 - .../Core/inc/usbd_usr.h | 135 - .../Core/src/usbd_core.c | 476 - .../Core/src/usbd_ioreq.c | 237 - .../Core/src/usbd_req.c | 868 -- .../Class/HID/inc/usbh_hid_core.h | 195 - .../Class/HID/inc/usbh_hid_keybd.h | 122 - .../Class/HID/inc/usbh_hid_mouse.h | 114 - .../Class/HID/src/usbh_hid_core.c | 640 -- .../Class/HID/src/usbh_hid_keybd.c | 338 - .../Class/HID/src/usbh_hid_mouse.c | 155 - .../Class/MSC/inc/usbh_msc_bot.h | 221 - .../Class/MSC/inc/usbh_msc_core.h | 141 - .../Class/MSC/inc/usbh_msc_scsi.h | 163 - .../Class/MSC/src/usbh_msc_bot.c | 613 -- .../Class/MSC/src/usbh_msc_core.c | 559 -- .../Class/MSC/src/usbh_msc_fatfs.c | 186 - .../Class/MSC/src/usbh_msc_scsi.c | 674 -- .../Core/inc/usbh_conf_template.h | 94 - .../Core/inc/usbh_core.h | 289 - .../Core/inc/usbh_def.h | 280 - .../Core/inc/usbh_hcs.h | 125 - .../Core/inc/usbh_ioreq.h | 140 - .../Core/inc/usbh_stdreq.h | 148 - .../Core/src/usbh_core.c | 842 -- .../Core/src/usbh_hcs.c | 253 - .../Core/src/usbh_ioreq.c | 419 - .../Core/src/usbh_stdreq.c | 551 -- .../STM32_USB_OTG_Driver/Release_Notes.html | 941 -- .../STM32_USB_OTG_Driver/inc/usb_bsp.h | 97 - .../inc/usb_conf_template.h | 287 - .../STM32_USB_OTG_Driver/inc/usb_core.h | 408 - .../STM32_USB_OTG_Driver/inc/usb_dcd.h | 158 - .../STM32_USB_OTG_Driver/inc/usb_dcd_int.h | 121 - .../STM32_USB_OTG_Driver/inc/usb_defines.h | 244 - .../STM32_USB_OTG_Driver/inc/usb_hcd.h | 102 - .../STM32_USB_OTG_Driver/inc/usb_hcd_int.h | 126 - .../STM32_USB_OTG_Driver/inc/usb_otg.h | 94 - .../STM32_USB_OTG_Driver/inc/usb_regs.h | 1206 --- .../src/usb_bsp_template.c | 200 - .../STM32_USB_OTG_Driver/src/usb_core.c | 2187 ----- .../STM32_USB_OTG_Driver/src/usb_dcd.c | 472 - .../STM32_USB_OTG_Driver/src/usb_dcd_int.c | 886 -- .../STM32_USB_OTG_Driver/src/usb_hcd.c | 256 - .../STM32_USB_OTG_Driver/src/usb_hcd_int.c | 832 -- .../STM32_USB_OTG_Driver/src/usb_otg.c | 175 - .../STM32F4-Discovery/Release_Notes.html | 151 - .../STM32F4-Discovery/stm32f4_discovery.c | 257 - .../STM32F4-Discovery/stm32f4_discovery.h | 158 - .../stm32f4_discovery_audio_codec.c | 1651 ---- .../stm32f4_discovery_audio_codec.h | 304 - .../stm32f4_discovery_lis302dl.c | 504 - .../stm32f4_discovery_lis302dl.h | 772 -- 317 files changed, 173076 deletions(-) delete mode 100644 example/32l_dac/Makefile delete mode 100644 example/32l_dac/discover_board.h delete mode 100644 example/32l_dac/main.c delete mode 100644 example/32l_dac/startup_stm32l1xx_md.s delete mode 100644 example/32l_dac/stm32_flash.ld delete mode 100644 example/32l_dac/system_stm32l1xx.c delete mode 100644 example/32l_lcd/Makefile delete mode 100644 example/32l_lcd/discover_board.h delete mode 100644 example/32l_lcd/linker_stm32l.lds delete mode 100644 example/32l_lcd/main.c delete mode 100644 example/32l_lcd/stm32l_discovery_lcd.c delete mode 100644 example/32l_lcd/stm32l_discovery_lcd.h delete mode 100644 example/32vl_factory_demo/Makefile delete mode 100644 example/32vl_factory_demo/README delete mode 100644 example/32vl_factory_demo/main.c delete mode 100644 example/32vl_factory_demo/stm32f10x_conf.h delete mode 100644 example/32vl_factory_demo/stm32f10x_it.c delete mode 100644 example/32vl_factory_demo/stm32f10x_it.h delete mode 100644 example/32vl_factory_demo/system_stm32f10x.c delete mode 100644 example/README delete mode 100644 example/blink/Makefile delete mode 100644 example/blink/main.c delete mode 100644 example/blink_flash/Makefile delete mode 100644 example/blink_flash/discover_board.h delete mode 100644 example/blink_flash/main.c delete mode 100644 example/blink_flash/startup_stm32l1xx_md.s delete mode 100644 example/blink_flash/stm32_flash.ld delete mode 100644 example/blink_flash/system_stm32l1xx.c delete mode 100644 example/libs_stm/README delete mode 100644 example/libs_stm/build/Makefile delete mode 100644 example/libs_stm/build/Makefile.common delete mode 100644 example/libs_stm/build/Makefile.f10x delete mode 100644 example/libs_stm/build/Makefile.l1xx delete mode 100644 example/libs_stm/inc/base/stdint.h delete mode 100644 example/libs_stm/inc/core_support/core_cm3.c delete mode 100644 example/libs_stm/inc/core_support/core_cm3.h delete mode 100644 example/libs_stm/inc/device_support/stm32f10x.h delete mode 100644 example/libs_stm/inc/device_support/stm32l1xx.h delete mode 100644 example/libs_stm/inc/device_support/system_stm32f10x.h delete mode 100644 example/libs_stm/inc/device_support/system_stm32l1xx.h delete mode 100644 example/libs_stm/inc/stm32f10x/misc.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_adc.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_bkp.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_can.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_cec.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_crc.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_dac.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_dbgmcu.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_dma.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_exti.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_flash.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_fsmc.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_gpio.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_i2c.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_iwdg.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_pwr.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_rcc.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_rtc.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_sdio.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_spi.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_tim.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_usart.h delete mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_wwdg.h delete mode 100644 example/libs_stm/inc/stm32l1xx/misc.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_adc.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_comp.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_crc.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_dac.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_dbgmcu.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_dma.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_exti.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_flash.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_gpio.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_i2c.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_iwdg.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_lcd.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_pwr.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_rcc.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_rtc.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_spi.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_syscfg.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_tim.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_usart.h delete mode 100644 example/libs_stm/inc/stm32l1xx/stm32l1xx_wwdg.h delete mode 100644 example/libs_stm/src/stm32f10x/Release_Notes_for_STM32F10x_StdPeriph_Driver.html delete mode 100644 example/libs_stm/src/stm32f10x/misc.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_adc.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_bkp.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_can.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_cec.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_crc.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_dac.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_dbgmcu.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_dma.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_exti.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_flash.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_fsmc.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_gpio.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_i2c.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_iwdg.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_pwr.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_rcc.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_rtc.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_sdio.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_spi.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_tim.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_usart.c delete mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_wwdg.c delete mode 100644 example/libs_stm/src/stm32l1xx/misc.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_adc.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_comp.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_crc.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_dac.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_dbgmcu.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_dma.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_exti.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_flash.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_flash_ramfunc.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_gpio.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_i2c.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_iwdg.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_lcd.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_pwr.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_rcc.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_rtc.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_spi.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_syscfg.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_tim.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_usart.c delete mode 100644 example/libs_stm/src/stm32l1xx/stm32l1xx_wwdg.c delete mode 100644 example/stm32f4/Projects/IO_Toggle/Makefile delete mode 100644 example/stm32f4/Projects/IO_Toggle/main.c delete mode 100644 example/stm32f4/Projects/IO_Toggle/readme.txt delete mode 100644 example/stm32f4/Projects/IO_Toggle/startup_stm32f4xx.s delete mode 100644 example/stm32f4/Projects/IO_Toggle/stm32_flash.ld delete mode 100644 example/stm32f4/Projects/IO_Toggle/stm32f4_discovery.h delete mode 100644 example/stm32f4/Projects/IO_Toggle/stm32f4xx_conf.h delete mode 100644 example/stm32f4/Projects/IO_Toggle/stm32f4xx_it.c delete mode 100644 example/stm32f4/Projects/IO_Toggle/stm32f4xx_it.h delete mode 100644 example/stm32f4/Projects/IO_Toggle/system_stm32f4xx.c delete mode 100644 example/stm32f4/Projects/discovery_demo/Makefile delete mode 100644 example/stm32f4/Projects/discovery_demo/Release_Notes.html delete mode 100644 example/stm32f4/Projects/discovery_demo/main.c delete mode 100644 example/stm32f4/Projects/discovery_demo/main.h delete mode 100644 example/stm32f4/Projects/discovery_demo/selftest.c delete mode 100644 example/stm32f4/Projects/discovery_demo/selftest.h delete mode 100644 example/stm32f4/Projects/discovery_demo/startup_stm32f4xx.s delete mode 100644 example/stm32f4/Projects/discovery_demo/stm32_flash.ld delete mode 100644 example/stm32f4/Projects/discovery_demo/stm32f4xx_conf.h delete mode 100644 example/stm32f4/Projects/discovery_demo/stm32f4xx_it.c delete mode 100644 example/stm32f4/Projects/discovery_demo/stm32f4xx_it.h delete mode 100644 example/stm32f4/Projects/discovery_demo/system_stm32f4xx.c delete mode 100644 example/stm32f4/Projects/discovery_demo/usb_bsp.c delete mode 100644 example/stm32f4/Projects/discovery_demo/usb_conf.h delete mode 100644 example/stm32f4/Projects/discovery_demo/usb_core.c delete mode 100644 example/stm32f4/Projects/discovery_demo/usb_core.h delete mode 100644 example/stm32f4/Projects/discovery_demo/usbd_conf.h delete mode 100644 example/stm32f4/Projects/discovery_demo/usbd_desc.c delete mode 100644 example/stm32f4/Projects/discovery_demo/usbd_desc.h delete mode 100644 example/stm32f4/Projects/discovery_demo/usbd_usr.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/build/Makefile delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/arm_common_tables.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/arm_math.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm0.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm3.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm3.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm4.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm4_simd.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cmFunc.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cmInstr.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/device_support/stm32f4_discovery.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/device_support/stm32f4xx.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/device_support/system_stm32f4xx.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/misc.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_adc.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_can.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_crc.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_cryp.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dac.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dbgmcu.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dcmi.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_exti.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_flash.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_fsmc.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_gpio.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_hash.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_i2c.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_iwdg.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_pwr.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rcc.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rng.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rtc.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_sdio.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_spi.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_syscfg.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_tim.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_usart.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_wwdg.h delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/misc.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_adc.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_can.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_crc.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp_aes.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp_des.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp_tdes.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dac.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dbgmcu.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dcmi.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_flash.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_fsmc.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash_md5.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash_sha1.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_i2c.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_iwdg.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_pwr.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rng.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rtc.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_sdio.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_spi.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c delete mode 100644 example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_wwdg.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_out_if.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_out_if.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_otp_if.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_otp_if.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_core.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_def.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_req.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_usr.h delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Core/src/usbd_core.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Core/src/usbd_ioreq.c delete mode 100644 example/stm32f4/STM32_USB_Device_Library/Core/src/usbd_req.c delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_core.h delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_keybd.h delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_mouse.h delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_core.c delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_keybd.c delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_mouse.c delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_bot.h delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_core.h delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_scsi.h delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_bot.c delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_core.c delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_fatfs.c delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_scsi.c delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_conf_template.h delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_core.h delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_def.h delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_hcs.h delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_ioreq.h delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_stdreq.h delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_core.c delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_hcs.c delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_ioreq.c delete mode 100644 example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_stdreq.c delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/Release_Notes.html delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/inc/usb_bsp.h delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/inc/usb_conf_template.h delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/inc/usb_core.h delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/inc/usb_dcd.h delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/inc/usb_defines.h delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/inc/usb_hcd.h delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/inc/usb_otg.h delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/inc/usb_regs.h delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/src/usb_bsp_template.c delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/src/usb_core.c delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/src/usb_dcd.c delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/src/usb_dcd_int.c delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/src/usb_hcd.c delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/src/usb_hcd_int.c delete mode 100644 example/stm32f4/STM32_USB_OTG_Driver/src/usb_otg.c delete mode 100644 example/stm32f4/Utilities/STM32F4-Discovery/Release_Notes.html delete mode 100644 example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery.c delete mode 100644 example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery.h delete mode 100644 example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_audio_codec.c delete mode 100644 example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_audio_codec.h delete mode 100644 example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_lis302dl.c delete mode 100644 example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_lis302dl.h diff --git a/example/32l_dac/Makefile b/example/32l_dac/Makefile deleted file mode 100644 index 6c1844169..000000000 --- a/example/32l_dac/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -EXECUTABLE=dac.elf -BIN_IMAGE=dac.bin - -CC=arm-none-eabi-gcc -OBJCOPY=arm-none-eabi-objcopy - -CFLAGS=-O3 -mlittle-endian -mthumb -CFLAGS+=-mcpu=cortex-m3 -DCONFIG_STM32L_DISCOVERY=1 -CFLAGS+=-ffreestanding -nostdlib -nostdinc - -# to run from FLASH -CFLAGS+=-Wl,-T,stm32_flash.ld - -PLATFORM=stm32l1xx -LIBS_STM_PATH=../libs_stm - -# stm32l_discovery lib -CFLAGS+=-I$(LIBS_STM_PATH)/inc/base -CFLAGS+=-I$(LIBS_STM_PATH)/inc/core_support -CFLAGS+=-I$(LIBS_STM_PATH)/inc/device_support -CFLAGS+=-I$(LIBS_STM_PATH)/inc/$(PLATFORM) - -LDFLAGS+=-L$(LIBS_STM_PATH)/build -lstm32_stdperiph_l1xx - -all: $(BIN_IMAGE) - -$(BIN_IMAGE): $(EXECUTABLE) - $(OBJCOPY) -O binary $^ $@ - -$(EXECUTABLE): main.c system_stm32l1xx.c startup_stm32l1xx_md.s - $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) - -clean: - rm -rf $(EXECUTABLE) - rm -rf $(BIN_IMAGE) - -write: all - sudo ../../flash/flash write ./dac.bin 0x08000000 - -.PHONY: all clean write diff --git a/example/32l_dac/discover_board.h b/example/32l_dac/discover_board.h deleted file mode 100644 index d93a184aa..000000000 --- a/example/32l_dac/discover_board.h +++ /dev/null @@ -1,61 +0,0 @@ - /** - ****************************************************************************** - * @file discover_board.h - * @author Microcontroller Division - * @version V1.0.2 - * @date September-2011 - * @brief Input/Output defines - ****************************************************************************** - * @copy - * - * 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 2011 STMicroelectronics

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef __DISCOVER_BOARD_H -#define __DISCOVER_BOARD_H - -/* Includes ------------------------------------------------------------------*/ -/* #include "stm32l1xx.h" */ - -#define bool _Bool -#define FALSE 0 -#define TRUE !FALSE - -/* MACROs for SET, RESET or TOGGLE Output port */ - -#define GPIO_HIGH(a,b) a->BSRRL = b -#define GPIO_LOW(a,b) a->BSRRH = b -#define GPIO_TOGGLE(a,b) a->ODR ^= b - -#define USERBUTTON_GPIO_PORT GPIOA -#define USERBUTTON_GPIO_PIN GPIO_Pin_0 -#define USERBUTTON_GPIO_CLK RCC_AHBPeriph_GPIOA - -#define LD_GPIO_PORT GPIOB -#define LD_GREEN_GPIO_PIN GPIO_Pin_7 -#define LD_BLUE_GPIO_PIN GPIO_Pin_6 -#define LD_GPIO_PORT_CLK RCC_AHBPeriph_GPIOB - -#define CTN_GPIO_PORT GPIOC -#define CTN_CNTEN_GPIO_PIN GPIO_Pin_13 -#define CTN_GPIO_CLK RCC_AHBPeriph_GPIOC - -#define WAKEUP_GPIO_PORT GPIOA - -#define IDD_MEASURE_PORT GPIOA -#define IDD_MEASURE GPIO_Pin_4 - - -#endif - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/32l_dac/main.c b/example/32l_dac/main.c deleted file mode 100644 index 1f89d33ac..000000000 --- a/example/32l_dac/main.c +++ /dev/null @@ -1,242 +0,0 @@ -/* base headers */ -#include "stdint.h" - -/* libstm32l_discovery headers */ -#include "stm32l1xx_gpio.h" -#include "stm32l1xx_adc.h" -#include "stm32l1xx_dac.h" -#include "stm32l1xx_lcd.h" -#include "stm32l1xx_rcc.h" -#include "stm32l1xx_rtc.h" -#include "stm32l1xx_exti.h" -#include "stm32l1xx_pwr.h" -#include "stm32l1xx_flash.h" -#include "stm32l1xx_syscfg.h" -#include "stm32l1xx_dbgmcu.h" - -/* board specific macros */ -#include "discover_board.h" - - -/* hardware configuration */ - -#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_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) -{ - GPIO_HIGH(LD_GPIO_PORT, LD_GREEN_GPIO_PIN); - GPIO_HIGH(LD_GPIO_PORT, LD_BLUE_GPIO_PIN); -} - -static inline void switch_leds_off(void) -{ - GPIO_LOW(LD_GPIO_PORT, LD_GREEN_GPIO_PIN); - GPIO_LOW(LD_GPIO_PORT, LD_BLUE_GPIO_PIN); -} - -#endif /* otherwise, error */ - - -#define delay() \ -do { \ - volatile unsigned int i; \ - for (i = 0; i < 1000000; ++i) \ - __asm__ __volatile__ ("nop\n\t":::"memory"); \ -} while (0) - - -static void RCC_Configuration(void) -{ - /* HSI is 16mhz RC clock directly fed to SYSCLK (rm00038, figure 9) */ - - /* enable the HSI clock (high speed internal) */ - RCC_HSICmd(ENABLE); - - /* wail til HSI ready */ - while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET) - {} - - /* at startup, SYSCLK driven by MSI. set to HSI */ - RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI); - - /* set MSI to 4mhz */ - RCC_MSIRangeConfig(RCC_MSIRange_6); - - /* turn HSE off */ - RCC_HSEConfig(RCC_HSE_OFF); - if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET) - { - while (1) ; - } -} - - -static void RTC_Configuration(void) -{ - /* Allow access to the RTC */ - PWR_RTCAccessCmd(ENABLE); - - /* Reset Backup Domain */ - RCC_RTCResetCmd(ENABLE); - RCC_RTCResetCmd(DISABLE); - - /* LSE Enable */ - RCC_LSEConfig(RCC_LSE_ON); - - /* Wait till LSE is ready */ - while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) - {} - - RCC_RTCCLKCmd(ENABLE); - - /* LCD Clock Source Selection */ - RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); - -} - -static void setup_dac1(void) -{ - /* see 10.2 notes */ - - static GPIO_InitTypeDef GPIO_InitStructure; - static DAC_InitTypeDef DAC_InitStructure; - - /* DAC clock path: - HSI (16mhz) -> SYSCLK -> HCLK(/1) -> PCLK1(/1) - */ - - /* set the AHB clock (HCLK) prescaler to 1 */ - RCC_HCLKConfig(RCC_SYSCLK_Div1); - - /* set the low speed APB clock (APB1, ie. PCLK1) prescaler to 1 */ - RCC_PCLK1Config(RCC_HCLK_Div1); - - /* enable DAC APB1 clock */ - /* signal connections: HSI(16mhz) -> SYSCLK -> AHB */ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); - - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; /* GPIO_Pin_5 for channel 2 */ - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - DAC_StructInit(&DAC_InitStructure); - DAC_InitStructure.DAC_Trigger = DAC_Trigger_None; -#if 0 /* triangle waveform generation */ - DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_Triangle; - DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_1; -#else - DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; - DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; -#endif - DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; - DAC_Init(DAC_Channel_1, &DAC_InitStructure); - - /* enable dac channel */ - DAC_Cmd(DAC_Channel_1, ENABLE); -} - -static inline void set_dac1_mv(unsigned int mv) -{ - /* mv the millivolts */ - - /* vref in millivolts */ - /* #define CONFIG_VREF 5000 */ -#define CONFIG_VREF 3000 - - /* resolution in bits */ -#define CONFIG_DAC_RES 12 - - const uint16_t n = (mv * (1 << (CONFIG_DAC_RES - 1))) / CONFIG_VREF; - DAC_SetChannel1Data(DAC_Align_12b_R, n); -} - -void main(void) -{ - static RCC_ClocksTypeDef RCC_Clocks; - static GPIO_InitTypeDef GPIO_InitStructure; - static uint16_t dac_value; - static unsigned int led_state = 0; - - /* Configure Clocks for Application need */ - RCC_Configuration(); - - /* Configure RTC Clocks */ - RTC_Configuration(); - -#if 0 - /* Set internal voltage regulator to 1.8v */ - PWR_VoltageScalingConfig(PWR_VoltageScaling_Range1); - /* Wait Until the Voltage Regulator is ready */ - while (PWR_GetFlagStatus(PWR_FLAG_VOS) != RESET) ; -#endif - - /* configure gpios */ - - /* Enable GPIOs clock */ - RCC_AHBPeriphClockCmd(LD_GPIO_PORT_CLK, ENABLE); - - /* Configure the GPIO_LED pins LD3 & LD4*/ - GPIO_InitStructure.GPIO_Pin = LD_GREEN_GPIO_PIN | LD_BLUE_GPIO_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_Init(LD_GPIO_PORT, &GPIO_InitStructure); - GPIO_LOW(LD_GPIO_PORT, LD_GREEN_GPIO_PIN); - GPIO_LOW(LD_GPIO_PORT, LD_BLUE_GPIO_PIN); - - setup_dac1(); - - dac_value = 0; - - while (1) - { - DAC_SetChannel1Data(DAC_Align_12b_R, dac_value & 0xfff); - dac_value += 0x10; - - if (led_state & 1) switch_leds_on(); - else switch_leds_off(); - led_state ^= 1; - - delay(); - } -} diff --git a/example/32l_dac/startup_stm32l1xx_md.s b/example/32l_dac/startup_stm32l1xx_md.s deleted file mode 100644 index 9a8389c9f..000000000 --- a/example/32l_dac/startup_stm32l1xx_md.s +++ /dev/null @@ -1,365 +0,0 @@ -/** - ****************************************************************************** - * @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/32l_dac/stm32_flash.ld b/example/32l_dac/stm32_flash.ld deleted file mode 100644 index 146b16ecc..000000000 --- a/example/32l_dac/stm32_flash.ld +++ /dev/null @@ -1,173 +0,0 @@ -/* -***************************************************************************** -** -** 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/32l_dac/system_stm32l1xx.c b/example/32l_dac/system_stm32l1xx.c deleted file mode 100644 index 6deab320c..000000000 --- a/example/32l_dac/system_stm32l1xx.c +++ /dev/null @@ -1,367 +0,0 @@ -/** - ****************************************************************************** - * @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/example/32l_lcd/Makefile b/example/32l_lcd/Makefile deleted file mode 100644 index fdb79c304..000000000 --- a/example/32l_lcd/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -ELF=lcd.elf - -CC=arm-none-eabi-gcc - -CFLAGS=-O2 -mlittle-endian -mthumb -g -CFLAGS+=-mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc - -CFLAGS+=-I. - - -PLATFORM=stm32l1xx -LIBS_STM_PATH=../libs_stm - -CFLAGS+=-I$(LIBS_STM_PATH)/inc/base -CFLAGS+=-I$(LIBS_STM_PATH)/inc/core_support -CFLAGS+=-I$(LIBS_STM_PATH)/inc/device_support -CFLAGS+=-I$(LIBS_STM_PATH)/inc/$(PLATFORM) - -# to run from SRAM -CFLAGS+=-Wl,-T,linker_stm32l.lds - -LDFLAGS+=-L$(LIBS_STM_PATH)/build -lstm32_stdperiph_l1xx - -SRCS=\ -main.c\ -stm32l_discovery_lcd.c - -OBJS=$(SRCS:.c=.o) - -all: $(ELF) - -$(ELF): $(OBJS) - $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $^ - -clean: - -rm -f $(OBJS) - -rm -f $(ELF) - -.PHONY: all clean diff --git a/example/32l_lcd/discover_board.h b/example/32l_lcd/discover_board.h deleted file mode 100644 index 91617684a..000000000 --- a/example/32l_lcd/discover_board.h +++ /dev/null @@ -1,61 +0,0 @@ - /** - ****************************************************************************** - * @file discover_board.h - * @author Microcontroller Division - * @version V1.0.2 - * @date September-2011 - * @brief Input/Output defines - ****************************************************************************** - * @copy - * - * 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 2011 STMicroelectronics

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef __DISCOVER_BOARD_H -#define __DISCOVER_BOARD_H - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -#define bool _Bool -#define FALSE 0 -#define TRUE !FALSE - -/* MACROs for SET, RESET or TOGGLE Output port */ - -#define GPIO_HIGH(a,b) a->BSRRL = b -#define GPIO_LOW(a,b) a->BSRRH = b -#define GPIO_TOGGLE(a,b) a->ODR ^= b - -#define USERBUTTON_GPIO_PORT GPIOA -#define USERBUTTON_GPIO_PIN GPIO_Pin_0 -#define USERBUTTON_GPIO_CLK RCC_AHBPeriph_GPIOA - -#define LD_GPIO_PORT GPIOB -#define LD_GREEN_GPIO_PIN GPIO_Pin_7 -#define LD_BLUE_GPIO_PIN GPIO_Pin_6 -#define LD_GPIO_PORT_CLK RCC_AHBPeriph_GPIOB - -#define CTN_GPIO_PORT GPIOC -#define CTN_CNTEN_GPIO_PIN GPIO_Pin_13 -#define CTN_GPIO_CLK RCC_AHBPeriph_GPIOC - -#define WAKEUP_GPIO_PORT GPIOA - -#define IDD_MEASURE_PORT GPIOA -#define IDD_MEASURE GPIO_Pin_4 - - -#endif - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/32l_lcd/linker_stm32l.lds b/example/32l_lcd/linker_stm32l.lds deleted file mode 100644 index 58b894f03..000000000 --- a/example/32l_lcd/linker_stm32l.lds +++ /dev/null @@ -1,54 +0,0 @@ -OUTPUT_FORMAT("elf32-littlearm") -ENTRY(_main) - -MEMORY -{ - sram : ORIGIN = 0x20000000, LENGTH = 0x4000 -} - -SECTIONS -{ - .text(ORIGIN(sram)): - { - _main = .; - _ftext = .; - *(.text .stub .text.* .gnu.linkonce.t.*) - _etext = .; - } > sram - - .rodata : - { - . = ALIGN(4); - _frodata = .; - *(.rodata .rodata.* .gnu.linkonce.r.*) - *(.rodata1) - _erodata = .; - } > sram - - .data : - { - . = ALIGN(4); - _fdata = .; - *(.data .data.* .gnu.linkonce.d.*) - *(.data1) - _gp = ALIGN(16); - *(.sdata .sdata.* .gnu.linkonce.s.*) - _edata = .; - } > sram - - .bss : - { - . = ALIGN(4); - _fbss = .; - *(.dynsbss) - *(.sbss .sbss.* .gnu.linkonce.sb.*) - *(.scommon) - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - _ebss = .; - _end = .; - } > sram -} - -PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 4); diff --git a/example/32l_lcd/main.c b/example/32l_lcd/main.c deleted file mode 100644 index 36d6e52d9..000000000 --- a/example/32l_lcd/main.c +++ /dev/null @@ -1,351 +0,0 @@ -/* this example is only for stm32l discover. - adapted from ST firmwares projects. - */ - -/* base headers */ -#include "stdint.h" - -/* libstm32l_discovery headers */ -#include "stm32l1xx_gpio.h" -#include "stm32l1xx_adc.h" -#include "stm32l1xx_lcd.h" -#include "stm32l1xx_rcc.h" -#include "stm32l1xx_rtc.h" -#include "stm32l1xx_exti.h" -#include "stm32l1xx_pwr.h" -#include "stm32l1xx_syscfg.h" -#include "stm32l1xx_dbgmcu.h" - -/* lcd wrapper routines header */ -#include "stm32l_discovery_lcd.h" - -/* boot mode */ - -#define CONFIG_BOOT_SRAM 1 -#define CONFIG_BOOT_FLASH 0 - - -/* gpios - refer to CD00277537.pdf, APB memory space. - refer to CD00240193.pdf, GPIO. -*/ - -#define GPIOA_MODER (GPIOA_BASE + 0x00) -#define GPIOA_ODR (GPIOA_BASE + 0x14) - -#define GPIOB_MODER (GPIOB_BASE + 0x00) -#define GPIOB_ODR (GPIOB_BASE + 0x14) - -#define GPIOC_MODER (GPIOC_BASE + 0x00) -#define GPIOC_ODR (GPIOC_BASE + 0x14) - - -/* leds */ - -#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; -} - - -#define delay() \ -do { \ - register unsigned int i; \ - for (i = 0; i < 1000000; ++i) \ - __asm__ __volatile__ ("nop\n\t":::"memory"); \ -} while (0) - - -#if CONFIG_BOOT_SRAM - -extern uint32_t _fstack; - -static inline void setup_stack(void) -{ - /* setup the stack to point to _fstack (refer to ld script) */ - - static const uint32_t fstack = (uint32_t)&_fstack; - - __asm__ __volatile__ - ( - "ldr sp, %0\n\t" - : - : "m"(fstack) - : "sp" - ); -} - -#endif /* CONFIG_BOOT_SRAM */ - - -/* application related setup */ - -static void RCC_Configuration(void) -{ - /* Enable HSI Clock */ - RCC_HSICmd(ENABLE); - - /*!< Wait till HSI is ready */ - while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); - - /* Set HSI as sys clock*/ - RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI); - - /* Set MSI clock range to ~4.194MHz*/ - RCC_MSIRangeConfig(RCC_MSIRange_6); - - /* Enable the GPIOs clocks */ - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC| RCC_AHBPeriph_GPIOD| RCC_AHBPeriph_GPIOE| RCC_AHBPeriph_GPIOH, ENABLE); - - /* Enable comparator, LCD and PWR mngt clocks */ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP | RCC_APB1Periph_LCD | RCC_APB1Periph_PWR,ENABLE); - - /* Enable ADC & SYSCFG clocks */ - RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_SYSCFG , ENABLE); - - /* Allow access to the RTC */ - PWR_RTCAccessCmd(ENABLE); - - /* Reset RTC Backup Domain */ - RCC_RTCResetCmd(ENABLE); - RCC_RTCResetCmd(DISABLE); - - /* LSE Enable */ - RCC_LSEConfig(RCC_LSE_ON); - - /* Wait until LSE is ready */ - while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); - - /* RTC Clock Source Selection */ - RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); - - /* Enable the RTC */ - RCC_RTCCLKCmd(ENABLE); - - /*Disable HSE*/ - RCC_HSEConfig(RCC_HSE_OFF); - if(RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET ) - { - /* Stay in infinite loop if HSE is not disabled*/ - while(1); - } -} - -static void Init_GPIOs(void) -{ -#if 0 /* fixme: GPIO_Init raises a bug in some gcc toolchains */ - - /* GPIO, EXTI and NVIC Init structure declaration */ - GPIO_InitTypeDef GPIO_InitStructure; - -#if 0 - EXTI_InitTypeDef EXTI_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; -#endif - -#if 0 - /* Configure User Button pin as input */ - GPIO_InitStructure.GPIO_Pin = USERBUTTON_GPIO_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; - GPIO_Init(USERBUTTON_GPIO_PORT, &GPIO_InitStructure); -#endif - -#if 0 - /* Select User Button pin as input source for EXTI Line */ - SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0); - - /* Configure EXT1 Line 0 in interrupt mode trigged on Rising edge */ - EXTI_InitStructure.EXTI_Line = EXTI_Line0 ; // PA0 for User button AND IDD_WakeUP - EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; - EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; - EXTI_InitStructure.EXTI_LineCmd = ENABLE; - EXTI_Init(&EXTI_InitStructure); - - /* Enable and set EXTI0 Interrupt to the lowest priority */ - NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn ; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); -#endif - -#if 0 - /* Configure the LED_pin as output push-pull for LD3 & LD4 usage*/ - GPIO_InitStructure.GPIO_Pin = LD_GREEN_GPIO_PIN | LD_BLUE_GPIO_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_Init(LD_GPIO_PORT, &GPIO_InitStructure); - - /* Force a low level on LEDs*/ - GPIO_LOW(LD_GPIO_PORT,LD_GREEN_GPIO_PIN); - GPIO_LOW(LD_GPIO_PORT,LD_BLUE_GPIO_PIN); - - /* Counter enable: GPIO set in output for enable the counter */ - GPIO_InitStructure.GPIO_Pin = CTN_CNTEN_GPIO_PIN; - GPIO_Init( CTN_GPIO_PORT, &GPIO_InitStructure); - - /* To prepare to start counter */ - GPIO_HIGH(CTN_GPIO_PORT,CTN_CNTEN_GPIO_PIN); - - /* Configure Port A LCD Output pins as alternate function */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_8 | GPIO_Pin_9 |GPIO_Pin_10 |GPIO_Pin_15; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init( GPIOA, &GPIO_InitStructure); - - /* Select LCD alternate function for Port A LCD Output pins */ - GPIO_PinAFConfig(GPIOA, GPIO_PinSource1,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOA, GPIO_PinSource2,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOA, GPIO_PinSource3,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOA, GPIO_PinSource8,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOA, GPIO_PinSource9,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOA, GPIO_PinSource10,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOA, GPIO_PinSource15,GPIO_AF_LCD) ; - - /* Configure Port B LCD Output pins as alternate function */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9 \ - | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init( GPIOB, &GPIO_InitStructure); - - /* Select LCD alternate function for Port B LCD Output pins */ - GPIO_PinAFConfig(GPIOB, GPIO_PinSource3,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource4,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource5,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource8,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource9,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource10,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource11,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource12,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource13,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource14,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource15,GPIO_AF_LCD) ; -#endif - -#if 0 - /* Configure Port C LCD Output pins as alternate function */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 \ - | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |GPIO_Pin_11 ; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init( GPIOC, &GPIO_InitStructure); - - /* Select LCD alternate function for Port B LCD Output pins */ - GPIO_PinAFConfig(GPIOC, GPIO_PinSource0,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource1,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource2,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource3,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource6,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource7,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource8,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource9,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource10,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource11,GPIO_AF_LCD) ; -#endif - -#if 0 - /* Configure ADC (IDD_MEASURE) pin as Analogue */ - GPIO_InitStructure.GPIO_Pin = IDD_MEASURE ; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; - GPIO_Init( IDD_MEASURE_PORT, &GPIO_InitStructure); -#endif - -#else /* fixme */ - - /* set every port in digital output mode */ - - /* PA[1:3,8:10,15] */ - *(volatile uint32_t*)GPIOA_MODER |= - (GPIO_Mode_AF << (1 * 2)) | - (GPIO_Mode_AF << (2 * 2)) | - (GPIO_Mode_AF << (3 * 2)) | - (GPIO_Mode_AF << (8 * 2)) | - (GPIO_Mode_AF << (9 * 2)) | - (GPIO_Mode_AF << (10 * 2)) | - (GPIO_Mode_AF << (15 * 2)); - - /* PB[3:5,8:15] */ - *(volatile uint32_t*)GPIOB_MODER |= - (GPIO_Mode_AF << (3 * 2)) | - (GPIO_Mode_AF << (4 * 2)) | - (GPIO_Mode_AF << (5 * 2)) | - (GPIO_Mode_AF << (8 * 2)) | - (GPIO_Mode_AF << (9 * 2)) | - (GPIO_Mode_AF << (10 * 2)) | - (GPIO_Mode_AF << (11 * 2)) | - (GPIO_Mode_AF << (12 * 2)) | - (GPIO_Mode_AF << (13 * 2)) | - (GPIO_Mode_AF << (14 * 2)) | - (GPIO_Mode_AF << (15 * 2)); - - /* PC[0:3,6:11] */ - *(volatile uint32_t*)GPIOC_MODER |= - (GPIO_Mode_AF << (0 * 2)) | - (GPIO_Mode_AF << (1 * 2)) | - (GPIO_Mode_AF << (2 * 2)) | - (GPIO_Mode_AF << (3 * 2)) | - (GPIO_Mode_AF << (6 * 2)) | - (GPIO_Mode_AF << (7 * 2)) | - (GPIO_Mode_AF << (8 * 2)) | - (GPIO_Mode_AF << (9 * 2)) | - (GPIO_Mode_AF << (10 * 2)) | - (GPIO_Mode_AF << (11 * 2)); - -#endif /* fixme */ -} - - -/* main */ - -static void __attribute__((naked)) __attribute__((used)) main(void) -{ -#if CONFIG_BOOT_SRAM - /* do not use previsouly setup stack, if any */ - setup_stack(); -#endif /* CONFIG_BOOT_SRAM */ - - RCC_Configuration(); - - Init_GPIOs(); - - LCD_GLASS_Init(); - - setup_leds(); - - while (1) - { - /* switch_leds_on(); */ - GPIO_HIGH(LD_GPIO_PORT, LD_GREEN_GPIO_PIN); - GPIO_HIGH(LD_GPIO_PORT, LD_BLUE_GPIO_PIN); - - LCD_GLASS_Clear(); - LCD_GLASS_DisplayString("ON "); - - delay(); - - /* switch_leds_off(); */ - GPIO_LOW(LD_GPIO_PORT, LD_GREEN_GPIO_PIN); - GPIO_LOW(LD_GPIO_PORT, LD_BLUE_GPIO_PIN); - - LCD_GLASS_Clear(); - LCD_GLASS_DisplayString(" OFF"); - - delay(); - } -} diff --git a/example/32l_lcd/stm32l_discovery_lcd.c b/example/32l_lcd/stm32l_discovery_lcd.c deleted file mode 100644 index 982a5f259..000000000 --- a/example/32l_lcd/stm32l_discovery_lcd.c +++ /dev/null @@ -1,614 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l_discovery_lcd.c - * @author Microcontroller Division - * @version V1.0.0 - * @date Apri-2011 - * @brief This file includes driver for the glass LCD Module mounted on - * STM32l discovery board MB963 - ****************************************************************************** - * @copy - * - * 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 2011 STMicroelectronics

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l_discovery_lcd.h" -#include "discover_board.h" -#include "stm32l1xx_lcd.h" -#include "stm32l1xx_gpio.h" -#include "stm32l1xx_rcc.h" -/* #include "main.h" */ - -/* this variable can be used for accelerate the scrolling exit when push user button */ -volatile bool KeyPressed = FALSE; - -/* LCD BAR status: We don't write directly in LCD RAM for save the bar setting */ -uint8_t t_bar[2]={0x0,0X0}; - -/* ========================================================================= - LCD MAPPING - ========================================================================= - A - _ ---------- -COL |_| |\ |J /| - F| H | K |B - _ | \ | / | -COL |_| --G-- --M-- - | /| \ | - E| Q | N |C - _ | / |P \| -DP |_| ----------- - D - - An LCD character coding is based on the following matrix: - { E , D , P , N } - { M , C , COL , DP} - { B , A , K , J } - { G , F , Q , H } - - The character 'A' for example is: - ------------------------------- -LSB { 1 , 0 , 0 , 0 } - { 1 , 1 , 0 , 0 } - { 1 , 1 , 0 , 0 } -MSB { 1 , 1 , 0 , 0 } - ------------------- - 'A' = F E 0 0 hexa - -*/ - -/* Constant table for cap characters 'A' --> 'Z' */ -const uint16_t CapLetterMap[26]= - { - /* A B C D E F G H I */ - 0xFE00,0x6714,0x1d00,0x4714,0x9d00,0x9c00,0x3f00,0xfa00,0x0014, - /* J K L M N O P Q R */ - 0x5300,0x9841,0x1900,0x5a48,0x5a09,0x5f00,0xFC00,0x5F01,0xFC01, - /* S T U V W X Y Z */ - 0xAF00,0x0414,0x5b00,0x18c0,0x5a81,0x00c9,0x0058,0x05c0 - }; - -/* Constant table for number '0' --> '9' */ -const uint16_t NumberMap[10]= - { - /* 0 1 2 3 4 5 6 7 8 9 */ - 0x5F00,0x4200,0xF500,0x6700,0xEa00,0xAF00,0xBF00,0x04600,0xFF00,0xEF00 - }; - -static void LCD_Conv_Char_Seg(uint8_t* c,bool point,bool column,uint8_t* digit); - -/** - * @brief Configures the LCD GLASS relative GPIO port IOs and LCD peripheral. - * @param None - * @retval None - */ -void LCD_GLASS_Init(void) -{ - LCD_InitTypeDef LCD_InitStruct; - - - LCD_InitStruct.LCD_Prescaler = LCD_Prescaler_1; - LCD_InitStruct.LCD_Divider = LCD_Divider_31; - LCD_InitStruct.LCD_Duty = LCD_Duty_1_4; - LCD_InitStruct.LCD_Bias = LCD_Bias_1_3; - LCD_InitStruct.LCD_VoltageSource = LCD_VoltageSource_Internal; - - - /* Initialize the LCD */ - LCD_Init(&LCD_InitStruct); - - LCD_MuxSegmentCmd(ENABLE); - - /* To set contrast to mean value */ - LCD_ContrastConfig(LCD_Contrast_Level_4); - - LCD_DeadTimeConfig(LCD_DeadTime_0); - LCD_PulseOnDurationConfig(LCD_PulseOnDuration_4); - - /* Wait Until the LCD FCR register is synchronized */ - LCD_WaitForSynchro(); - - /* Enable LCD peripheral */ - LCD_Cmd(ENABLE); - - /* Wait Until the LCD is enabled */ - while(LCD_GetFlagStatus(LCD_FLAG_ENS) == RESET) - { - } - /*!< Wait Until the LCD Booster is ready */ - while(LCD_GetFlagStatus(LCD_FLAG_RDY) == RESET) - { - } - - LCD_BlinkConfig(LCD_BlinkMode_Off,LCD_BlinkFrequency_Div32); - LCD_GLASS_Clear(); -} - -/** - * @brief To initialize the LCD pins - * @caller main - * @param None - * @retval None - */ - -void LCD_GLASS_Configure_GPIO(void) -{ - GPIO_InitTypeDef GPIO_InitStructure; - -/* Enable GPIOs clock */ - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | - RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE | RCC_AHBPeriph_GPIOH, ENABLE); - - -/* Configure Output for LCD */ -/* Port A */ - GPIO_StructInit(&GPIO_InitStructure); - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_8 | GPIO_Pin_9 |GPIO_Pin_10 |GPIO_Pin_15; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init( GPIOA, &GPIO_InitStructure); - - GPIO_PinAFConfig(GPIOA, GPIO_PinSource1,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOA, GPIO_PinSource2,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOA, GPIO_PinSource3,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOA, GPIO_PinSource8,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOA, GPIO_PinSource9,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOA, GPIO_PinSource10,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOA, GPIO_PinSource15,GPIO_AF_LCD) ; - -/* Configure Output for LCD */ -/* Port B */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9 \ - | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init( GPIOB, &GPIO_InitStructure); - - GPIO_PinAFConfig(GPIOB, GPIO_PinSource3,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource4,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource5,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource8,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource9,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource10,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource11,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource12,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource13,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource14,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOB, GPIO_PinSource15,GPIO_AF_LCD) ; - -/* Configure Output for LCD */ -/* Port C*/ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 \ - | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |GPIO_Pin_11 ; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init( GPIOC, &GPIO_InitStructure); - - - GPIO_PinAFConfig(GPIOC, GPIO_PinSource0,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource1,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource2,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource3,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource6,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource7,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource8,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource9,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource10,GPIO_AF_LCD) ; - GPIO_PinAFConfig(GPIOC, GPIO_PinSource11,GPIO_AF_LCD) ; - -/* Disable GPIOs clock */ - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | - RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE | RCC_AHBPeriph_GPIOH, DISABLE); - -} - -/** - * @brief LCD contrast setting min-->max-->min by pressing user button - * @param None - * @retval None - */ - -static void Delay(uint32_t nTime) -{ - while((nTime--) != 0); -} - -void LCD_contrast() -{ - uint32_t contrast ; - - /* To get the actual contrast value in register */ - contrast = LCD->FCR & LCD_Contrast_Level_7; - - while ((GPIOC->IDR & USERBUTTON_GPIO_PIN) == 0x0) - { - contrast += LCD_Contrast_Level_1; - - if (contrast > LCD_Contrast_Level_7) - contrast=LCD_Contrast_Level_0; - - LCD_ContrastConfig(contrast); - Delay(100); - } -} - -/** - * @brief Setting bar on LCD, writes bar value in LCD frame buffer - * @param None - * @retval None - */ -void LCD_bar() -{ - - LCD->RAM[LCD_RAMRegister_4] &= 0xffff5fff; - LCD->RAM[LCD_RAMRegister_6] &= 0xffff5fff; -/* bar1 bar3 */ - LCD->RAM[LCD_RAMRegister_4] |= (uint32_t)(t_bar[0]<<12); - -/*bar0 bar2 */ - LCD->RAM[LCD_RAMRegister_6] |= (uint32_t)(t_bar[1]<<12); - -} - -/** - * @brief Converts an ascii char to the a LCD digit. - * @param c: a char to display. - * @param point: a point to add in front of char - * This parameter can be: POINT_OFF or POINT_ON - * @param column : flag indicating if a column has to be add in front - * of displayed character. - * This parameter can be: COLUMN_OFF or COLUMN_ON. - * @param digit array with segment - * @retval None - */ -static void LCD_Conv_Char_Seg(uint8_t* c,bool point,bool column, uint8_t* digit) -{ - uint16_t ch = 0 ; - uint8_t i,j; - - switch (*c) - { - case ' ' : - ch = 0x00; - break; - - case '*': - ch = star; - break; - - case 'µ' : - ch = C_UMAP; - break; - - case 'm' : - ch = C_mMap; - break; - - case 'n' : - ch = C_nMap; - break; - - case '-' : - ch = C_minus; - break; - - case '/' : - ch = C_slatch; - break; - - case '°' : - ch = C_percent_1; - break; - case '%' : - ch = C_percent_2; - break; - case 255 : - ch = C_full; - break ; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - ch = NumberMap[*c-0x30]; - break; - - default: - /* The character c is one letter in upper case*/ - if ( (*c < 0x5b) && (*c > 0x40) ) - { - ch = CapLetterMap[*c-'A']; - } - /* The character c is one letter in lower case*/ - if ( (*c <0x7b) && ( *c> 0x60) ) - { - ch = CapLetterMap[*c-'a']; - } - break; - } - - /* Set the digital point can be displayed if the point is on */ - if (point) - { - ch |= 0x0002; - } - - /* Set the "COL" segment in the character that can be displayed if the column is on */ - if (column) - { - ch |= 0x0020; - } - - for (i = 12,j=0 ;j<4; i-=4,j++) - { - digit[j] = (ch >> i) & 0x0f; //To isolate the less signifiant dibit - } -} - -/** - * @brief This function writes a char in the LCD frame buffer. - * @param ch: the character to display. - * @param point: a point to add in front of char - * This parameter can be: POINT_OFF or POINT_ON - * @param column: flag indicating if a column has to be add in front - * of displayed character. - * This parameter can be: COLUMN_OFF or COLUMN_ON. - * @param position: position in the LCD of the caracter to write [0:7] - * @retval None - * @par Required preconditions: The LCD should be cleared before to start the - * write operation. - */ -void LCD_GLASS_WriteChar(uint8_t* ch, bool point, bool column, uint8_t position) -{ - uint8_t digit[4]; /* Digit frame buffer */ - -/* To convert displayed character in segment in array digit */ - LCD_Conv_Char_Seg(ch,point,column,digit); - -/* TO wait LCD Ready */ - while( LCD_GetFlagStatus (LCD_FLAG_UDR) != RESET) ; - - switch (position) - { - /* Position 1 on LCD (Digit1)*/ - case 1: - LCD->RAM[LCD_RAMRegister_0] &= 0xcffffffc; - LCD->RAM[LCD_RAMRegister_2] &= 0xcffffffc; - LCD->RAM[LCD_RAMRegister_4] &= 0xcffffffc; - LCD->RAM[LCD_RAMRegister_6] &= 0xcffffffc; - - LCD->RAM[LCD_RAMRegister_0] |= ((digit[0]& 0x0c) << 26 ) | (digit[0]& 0x03) ; // 1G 1B 1M 1E - LCD->RAM[LCD_RAMRegister_2] |= ((digit[1]& 0x0c) << 26 ) | (digit[1]& 0x03) ; // 1F 1A 1C 1D - LCD->RAM[LCD_RAMRegister_4] |= ((digit[2]& 0x0c) << 26 ) | (digit[2]& 0x03) ; // 1Q 1K 1Col 1P - LCD->RAM[LCD_RAMRegister_6] |= ((digit[3]& 0x0c) << 26 ) | (digit[3]& 0x03) ; // 1H 1J 1DP 1N - - break; - - /* Position 2 on LCD (Digit2)*/ - case 2: - LCD->RAM[LCD_RAMRegister_0] &= 0xf3ffff03; - LCD->RAM[LCD_RAMRegister_2] &= 0xf3ffff03; - LCD->RAM[LCD_RAMRegister_4] &= 0xf3ffff03; - LCD->RAM[LCD_RAMRegister_6] &= 0xf3ffff03; - - LCD->RAM[LCD_RAMRegister_0] |= ((digit[0]& 0x0c) << 24 )|((digit[0]& 0x02) << 6 )|((digit[0]& 0x01) << 2 ) ; // 2G 2B 2M 2E - LCD->RAM[LCD_RAMRegister_2] |= ((digit[1]& 0x0c) << 24 )|((digit[1]& 0x02) << 6 )|((digit[1]& 0x01) << 2 ) ; // 2F 2A 2C 2D - LCD->RAM[LCD_RAMRegister_4] |= ((digit[2]& 0x0c) << 24 )|((digit[2]& 0x02) << 6 )|((digit[2]& 0x01) << 2 ) ; // 2Q 2K 2Col 2P - LCD->RAM[LCD_RAMRegister_6] |= ((digit[3]& 0x0c) << 24 )|((digit[3]& 0x02) << 6 )|((digit[3]& 0x01) << 2 ) ; // 2H 2J 2DP 2N - - break; - - /* Position 3 on LCD (Digit3)*/ - case 3: - LCD->RAM[LCD_RAMRegister_0] &= 0xfcfffcff; - LCD->RAM[LCD_RAMRegister_2] &= 0xfcfffcff; - LCD->RAM[LCD_RAMRegister_4] &= 0xfcfffcff; - LCD->RAM[LCD_RAMRegister_6] &= 0xfcfffcff; - - LCD->RAM[LCD_RAMRegister_0] |= ((digit[0]& 0x0c) << 22 ) | ((digit[0]& 0x03) << 8 ) ; // 3G 3B 3M 3E - LCD->RAM[LCD_RAMRegister_2] |= ((digit[1]& 0x0c) << 22 ) | ((digit[1]& 0x03) << 8 ) ; // 3F 3A 3C 3D - LCD->RAM[LCD_RAMRegister_4] |= ((digit[2]& 0x0c) << 22 ) | ((digit[2]& 0x03) << 8 ) ; // 3Q 3K 3Col 3P - LCD->RAM[LCD_RAMRegister_6] |= ((digit[3]& 0x0c) << 22 ) | ((digit[3]& 0x03) << 8 ) ; // 3H 3J 3DP 3N - - break; - - /* Position 4 on LCD (Digit4)*/ - case 4: - LCD->RAM[LCD_RAMRegister_0] &= 0xffcff3ff; - LCD->RAM[LCD_RAMRegister_2] &= 0xffcff3ff; - LCD->RAM[LCD_RAMRegister_4] &= 0xffcff3ff; - LCD->RAM[LCD_RAMRegister_6] &= 0xffcff3ff; - - LCD->RAM[LCD_RAMRegister_0] |= ((digit[0]& 0x0c) << 18 ) | ((digit[0]& 0x03) << 10 ) ; // 4G 4B 4M 4E - LCD->RAM[LCD_RAMRegister_2] |= ((digit[1]& 0x0c) << 18 ) | ((digit[1]& 0x03) << 10 ) ; // 4F 4A 4C 4D - LCD->RAM[LCD_RAMRegister_4] |= ((digit[2]& 0x0c) << 18 ) | ((digit[2]& 0x03) << 10 ) ; // 4Q 4K 4Col 4P - LCD->RAM[LCD_RAMRegister_6] |= ((digit[3]& 0x0c) << 18 ) | ((digit[3]& 0x03) << 10 ) ; // 4H 4J 4DP 4N - - break; - - /* Position 5 on LCD (Digit5)*/ - case 5: - LCD->RAM[LCD_RAMRegister_0] &= 0xfff3cfff; - LCD->RAM[LCD_RAMRegister_2] &= 0xfff3cfff; - LCD->RAM[LCD_RAMRegister_4] &= 0xfff3efff; - LCD->RAM[LCD_RAMRegister_6] &= 0xfff3efff; - - LCD->RAM[LCD_RAMRegister_0] |= ((digit[0]& 0x0c) << 16 ) | ((digit[0]& 0x03) << 12 ) ; // 5G 5B 5M 5E - LCD->RAM[LCD_RAMRegister_2] |= ((digit[1]& 0x0c) << 16 ) | ((digit[1]& 0x03) << 12 ) ; // 5F 5A 5C 5D - LCD->RAM[LCD_RAMRegister_4] |= ((digit[2]& 0x0c) << 16 ) | ((digit[2]& 0x01) << 12 ) ; // 5Q 5K 5P - LCD->RAM[LCD_RAMRegister_6] |= ((digit[3]& 0x0c) << 16 ) | ((digit[3]& 0x01) << 12 ) ; // 5H 5J 5N - - break; - - /* Position 6 on LCD (Digit6)*/ - case 6: - LCD->RAM[LCD_RAMRegister_0] &= 0xfffc3fff; - LCD->RAM[LCD_RAMRegister_2] &= 0xfffc3fff; - LCD->RAM[LCD_RAMRegister_4] &= 0xfffc3fff; - LCD->RAM[LCD_RAMRegister_6] &= 0xfffc3fff; - - LCD->RAM[LCD_RAMRegister_0] |= ((digit[0]& 0x04) << 15 ) | ((digit[0]& 0x08) << 13 ) | ((digit[0]& 0x03) << 14 ) ; // 6B 6G 6M 6E - LCD->RAM[LCD_RAMRegister_2] |= ((digit[1]& 0x04) << 15 ) | ((digit[1]& 0x08) << 13 ) | ((digit[1]& 0x03) << 14 ) ; // 6A 6F 6C 6D - LCD->RAM[LCD_RAMRegister_4] |= ((digit[2]& 0x04) << 15 ) | ((digit[2]& 0x08) << 13 ) | ((digit[2]& 0x01) << 14 ) ; // 6K 6Q 6P - LCD->RAM[LCD_RAMRegister_6] |= ((digit[3]& 0x04) << 15 ) | ((digit[3]& 0x08) << 13 ) | ((digit[3]& 0x01) << 14 ) ; // 6J 6H 6N - - break; - - default: - break; - } - -/* Refresh LCD bar */ - LCD_bar(); - -/* Update the LCD display */ - LCD_UpdateDisplayRequest(); - -} - -/** - * @brief This function writes a char in the LCD RAM. - * @param ptr: Pointer to string to display on the LCD Glass. - * @retval None - */ -void LCD_GLASS_DisplayString(uint8_t* ptr) -{ - uint8_t i = 0x01; - - /* Send the string character by character on lCD */ - while ((*ptr != 0) & (i < 8)) - { - /* Display one character on LCD */ - LCD_GLASS_WriteChar(ptr, FALSE, FALSE, i); - - /* Point on the next character */ - ptr++; - - /* Increment the character counter */ - i++; - } -} - -/** - * @brief This function writes a char in the LCD RAM. - * @param ptr: Pointer to string to display on the LCD Glass. - * @retval None - * @par Required preconditions: Char is ASCCI value "Ored" with decimal point or Column flag - */ -void LCD_GLASS_DisplayStrDeci(uint16_t* ptr) -{ - uint8_t i = 0x01; - uint8_t char_tmp; - -// LCD_GLASS_Clear(); - /* Send the string character by character on lCD */ - while ((*ptr != 0) & (i < 8)) - { - char_tmp = (*ptr) & 0x00ff; - - switch ((*ptr) & 0xf000) - { - case DOT: - /* Display one character on LCD with decimal point */ - LCD_GLASS_WriteChar(&char_tmp, POINT_ON, COLUMN_OFF, i); - break; - case DOUBLE_DOT: - /* Display one character on LCD with decimal point */ - LCD_GLASS_WriteChar(&char_tmp, POINT_OFF, COLUMN_ON, i); - break; - default: - LCD_GLASS_WriteChar(&char_tmp, POINT_OFF, COLUMN_OFF, i); - break; - }/* Point on the next character */ - ptr++; - - /* Increment the character counter */ - i++; - } -} - -/** - * @brief This function Clear the whole LCD RAM. - * @param None - * @retval None - */ -void LCD_GLASS_Clear(void) -{ - uint8_t counter = 0; - - /* TO wait LCD Ready */ - while( LCD_GetFlagStatus (LCD_FLAG_UDR) != RESET) ; - - for (counter = LCD_RAMRegister_0; counter <= LCD_RAMRegister_15; counter++) - { - LCD->RAM[counter] = 0; - } - - /* Update the LCD display */ - LCD_UpdateDisplayRequest(); - -} - -/** - * @brief Display a string in scrolling mode - * @param ptr: Pointer to string to display on the LCD Glass. - * @param nScroll: Specifies how many time the message will be scrolled - * @param ScrollSpeed : Speciifes the speed of the scroll, low value gives - * higher speed - * @retval None - * @par Required preconditions: The LCD should be cleared before to start the - * write operation. - */ -void LCD_GLASS_ScrollSentence(uint8_t* ptr, uint16_t nScroll, uint16_t ScrollSpeed) -{ - uint8_t Repetition; - uint8_t Char_Nb; - uint8_t* ptr1; - uint8_t str[7]=""; - uint8_t Str_size; - - if (ptr == 0) return; - -/* To calculate end of string */ - for (ptr1=ptr,Str_size = 0 ; *ptr1 != 0; Str_size++,ptr1++) ; - - ptr1 = ptr; - - LCD_GLASS_DisplayString(ptr); - Delay(ScrollSpeed); - -/* To shift the string for scrolling display*/ - for (Repetition=0; Repetition
© COPYRIGHT 2011 STMicroelectronics
- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __stm32l_discovery_lcd -#define __stm32l_discovery_lcd - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" -#include "discover_board.h" - -/* Define for scrolling sentences*/ -#define SCROLL_SPEED 300 -#define SCROLL_SPEED_L 600 -#define SCROLL_NUM 1 - -/* Define for character '.' */ -#define POINT_OFF FALSE -#define POINT_ON TRUE - -/* Define for caracter ":" */ -#define COLUMN_OFF FALSE -#define COLUMN_ON TRUE - -#define DOT 0x8000 /* for add decimal point in string */ -#define DOUBLE_DOT 0x4000 /* for add decimal point in string */ - - -/* ========================================================================= - LCD MAPPING - ========================================================================= - A - _ ---------- -COL |_| |\ |J /| - F| H | K |B - _ | \ | / | -COL |_| --G-- --M-- - | /| \ | - E| Q | N |C - _ | / |P \| -DP |_| ----------- - D - - An LCD character coding is based on the following matrix: - { E , D , P , N } - { M , C , COL , DP} - { B , A , K , J } - { G , F , Q , H } - - The character 'A' for example is: - ------------------------------- -LSB { 1 , 0 , 0 , 0 } - { 1 , 1 , 0 , 0 } - { 1 , 1 , 0 , 0 } -MSB { 1 , 1 , 0 , 0 } - ------------------- - 'A' = F E 0 0 hexa - -*/ -/* Macros used for set/reset bar LCD bar */ -#define BAR0_ON t_bar[1] |= 8 -#define BAR0_OFF t_bar[1] &= ~8 -#define BAR1_ON t_bar[0] |= 8 -#define BAR1_OFF t_bar[0] &= ~8 -#define BAR2_ON t_bar[1] |= 2 -#define BAR2_OFF t_bar[1] &= ~2 -#define BAR3_ON t_bar[0] |= 2 -#define BAR3_OFF t_bar[0] &= ~2 - -/* code for 'µ' character */ -#define C_UMAP 0x6084 - -/* code for 'm' character */ -#define C_mMap 0xb210 - -/* code for 'n' character */ -#define C_nMap 0x2210 - -/* constant code for '*' character */ -#define star 0xA0DD - -/* constant code for '-' character */ -#define C_minus 0xA000 - -/* constant code for '/' */ -#define C_slatch 0x00c0 - -/* constant code for ° */ -#define C_percent_1 0xec00 - -/* constant code for small o */ -#define C_percent_2 0xb300 - -#define C_full 0xffdd - -void LCD_bar(void); -void LCD_GLASS_Init(void); -void LCD_GLASS_WriteChar(uint8_t* ch, bool point, bool column,uint8_t position); -void LCD_GLASS_DisplayString(uint8_t* ptr); -void LCD_GLASS_DisplayStrDeci(uint16_t* ptr); -void LCD_GLASS_ClearChar(uint8_t position); -void LCD_GLASS_Clear(void); -void LCD_GLASS_ScrollSentence(uint8_t* ptr, uint16_t nScroll, uint16_t ScrollSpeed); -void LCD_GLASS_WriteTime(char a, uint8_t posi, bool column); -void LCD_GLASS_Configure_GPIO(void); - -#endif /* stm32l_discovery_lcd*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/32vl_factory_demo/Makefile b/example/32vl_factory_demo/Makefile deleted file mode 100644 index 81cdd56ba..000000000 --- a/example/32vl_factory_demo/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# build an elf from the an3268 demonstration code -APP=32vl_factory_demo - -CC=arm-none-eabi-gcc -OBJCOPY=arm-none-eabi-objcopy - -CFLAGS=-O2 -mlittle-endian -mthumb -CFLAGS+=-mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc -ifeq ($(DEBUG),1) - CFLAGS+=-g -endif - -# to run from SRAM -CFLAGS+=-Wl,-Ttext,0x20000000 -Wl,-e,0x20000000 - -# to write to flash then run -# CFLAGS+=-Wl,-Ttext,0x08000000 -Wl,-e,0x08000000 - -PLATFORM=stm32f10x -BOARD_SUPPORT=../board_support/discovery_32vl -LIBS_STM_PATH=../libs_stm - -CFLAGS+=-I. -CFLAGS+=-I$(LIBS_STM_PATH)/inc/base -CFLAGS+=-I$(LIBS_STM_PATH)/inc/core_support -CFLAGS+=-I$(LIBS_STM_PATH)/inc/device_support -CFLAGS+=-I$(LIBS_STM_PATH)/inc/$(PLATFORM) -CFLAGS+=-I$(BOARD_SUPPORT) - -LDFLAGS+=-L$(LIBS_STM_PATH)/build -lstm32_stdperiph_f10x - - -SRCS=$(wildcard *.c) -SRCS+=$(wildcard $(BOARD_SUPPORT)/*.c) - -OBJS=$(SRCS:.c=.o) - -all: $(APP).elf - -%.bin: %.elf - $(OBJCOPY) -O binary $^ $@ - -$(APP).elf: $(OBJS) - $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $^ - -clean: - rm -rf $(OBJS) - rm -rf $(APP).* - -.PHONY: all clean diff --git a/example/32vl_factory_demo/README b/example/32vl_factory_demo/README deleted file mode 100644 index 28c83952d..000000000 --- a/example/32vl_factory_demo/README +++ /dev/null @@ -1,5 +0,0 @@ -This source is copied from AN3268, the STM demo code for the VL discovery board. - -It was modified to add includes and things where needed, but nothing else was touched. - -Eventually, this should be usable to restore a board to virgin state. (but not yet) diff --git a/example/32vl_factory_demo/main.c b/example/32vl_factory_demo/main.c deleted file mode 100644 index 0043b650e..000000000 --- a/example/32vl_factory_demo/main.c +++ /dev/null @@ -1,234 +0,0 @@ -/** - ****************************************************************************** - * @file Demo/src/main.c - * @author MCD Application Team - * @version V1.0.0 - * @date 09/13/2010 - * @brief Main program body - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" -#include "stm32f10x_conf.h" -#include "STM32vldiscovery.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define LSE_FAIL_FLAG 0x80 -#define LSE_PASS_FLAG 0x100 -/* Private macro -------------------------------------------------------------*/ -/* Private consts ------------------------------------------------------------*/ - -/* Private variables ---------------------------------------------------------*/ -u32 LSE_Delay = 0; -u32 count = 0; -u32 BlinkSpeed = 0; -u32 KeyState = 0; -static __IO uint32_t TimingDelay; -/* Private function prototypes -----------------------------------------------*/ -void Delay(uint32_t nTime); -void TimingDelay_Decrement(void); - -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief Main program. - * @param None - * @retval None - */ - -int main(void) -{ - /* Enable GPIOx Clock */ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); - - /* Initialise LEDs LD3&LD4, both off */ - STM32vldiscovery_LEDInit(LED3); - STM32vldiscovery_LEDInit(LED4); - - STM32vldiscovery_LEDOff(LED3); - STM32vldiscovery_LEDOff(LED4); - - /* Initialise USER Button */ - STM32vldiscovery_PBInit(BUTTON_USER, BUTTON_MODE_GPIO); - - /* Setup SysTick Timer for 1 msec interrupts */ - if (SysTick_Config(SystemCoreClock / 1000)) - { - /* Capture error */ - while (1); - } - - /* Enable access to the backup register => LSE can be enabled */ - PWR_BackupAccessCmd(ENABLE); - - /* Enable LSE (Low Speed External Oscillation) */ - RCC_LSEConfig(RCC_LSE_ON); - - /* Check the LSE Status */ - while(1) - { - if(LSE_Delay < LSE_FAIL_FLAG) - { - /* check whether LSE is ready, with 4 seconds timeout */ - Delay (500); - LSE_Delay += 0x10; - if(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != RESET) - { - /* Set flag: LSE PASS */ - LSE_Delay |= LSE_PASS_FLAG; - /* Turn Off Led4 */ - STM32vldiscovery_LEDOff(LED4); - /* Disable LSE */ - RCC_LSEConfig(RCC_LSE_OFF); - break; - } - } - - /* LSE_FAIL_FLAG = 0x80 */ - else if(LSE_Delay >= LSE_FAIL_FLAG) - { - if(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) - { - /* Set flag: LSE FAIL */ - LSE_Delay |= LSE_FAIL_FLAG; - /* Turn On Led4 */ - STM32vldiscovery_LEDOn(LED4); - } - /* Disable LSE */ - RCC_LSEConfig(RCC_LSE_OFF); - break; - } - } - - /* main while */ - while(1) - { - if(0 == STM32vldiscovery_PBGetState(BUTTON_USER)) - { - if(KeyState == 1) - { - if(0 == STM32vldiscovery_PBGetState(BUTTON_USER)) - { - /* USER Button released */ - KeyState = 0; - /* Turn Off LED4 */ - STM32vldiscovery_LEDOff(LED4); - } - } - } - else if(STM32vldiscovery_PBGetState(BUTTON_USER)) - { - if(KeyState == 0) - { - if(STM32vldiscovery_PBGetState(BUTTON_USER)) - { - /* USER Button released */ - KeyState = 1; - /* Turn ON LED4 */ - STM32vldiscovery_LEDOn(LED4); - Delay(1000); - /* Turn OFF LED4 */ - STM32vldiscovery_LEDOff(LED4); - /* BlinkSpeed: 0 -> 1 -> 2, then re-cycle */ - BlinkSpeed ++ ; - } - } - } - count++; - Delay(100); - /* BlinkSpeed: 0 */ - if(BlinkSpeed == 0) - { - if(4 == (count % 8)) - STM32vldiscovery_LEDOn(LED3); - if(0 == (count % 8)) - STM32vldiscovery_LEDOff(LED3); - } - /* BlinkSpeed: 1 */ - if(BlinkSpeed == 1) - { - if(2 == (count % 4)) - STM32vldiscovery_LEDOn(LED3); - if(0 == (count % 4)) - STM32vldiscovery_LEDOff(LED3); - } - /* BlinkSpeed: 2 */ - if(BlinkSpeed == 2) - { - if(0 == (count % 2)) - STM32vldiscovery_LEDOn(LED3); - else - STM32vldiscovery_LEDOff(LED3); - } - /* BlinkSpeed: 3 */ - else if(BlinkSpeed == 3) - BlinkSpeed = 0; - } -} - -/** - * @brief Inserts a delay time. - * @param nTime: specifies the delay time length, in milliseconds. - * @retval None - */ -void Delay(uint32_t nTime) -{ - TimingDelay = nTime; - - while(TimingDelay != 0); -} - -/** - * @brief Decrements the TimingDelay variable. - * @param None - * @retval None - */ -void TimingDelay_Decrement(void) -{ - if (TimingDelay != 0x00) - { - TimingDelay--; - } -} - -#ifdef USE_FULL_ASSERT -/** - * @brief Reports the name of the source file and the source line number - * where the assert_param error has occurred. - * @param file: pointer to the source file name - * @param line: assert_param error line source number - * @retval None - */ -void assert_failed(uint8_t* file, uint32_t line) -{ - /* User can add his own implementation to report the file name and line number, - ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ - - /* Infinite loop */ - while (1) - { - } -} -#endif - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/32vl_factory_demo/stm32f10x_conf.h b/example/32vl_factory_demo/stm32f10x_conf.h deleted file mode 100644 index 706b92ed9..000000000 --- a/example/32vl_factory_demo/stm32f10x_conf.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - ****************************************************************************** - * @file Demo/inc/stm32f10x_conf.h - * @author MCD Application Team - * @version V1.0.0 - * @date 09/13/2010 - * @brief Library configuration file. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_CONF_H -#define __STM32F10x_CONF_H - -/* Includes ------------------------------------------------------------------*/ -/* Uncomment the line below to enable peripheral header file inclusion */ -/* #include "stm32f10x_adc.h" */ -/* #include "stm32f10x_bkp.h" */ -/* #include "stm32f10x_can.h" */ -/* #include "stm32f10x_crc.h" */ -/* #include "stm32f10x_dac.h" */ -/* #include "stm32f10x_dbgmcu.h" */ -/* #include "stm32f10x_dma.h" */ -#include "stm32f10x_exti.h" -#include "stm32f10x_flash.h" -/* #include "stm32f10x_fsmc.h" */ -#include "stm32f10x_gpio.h" -/* #include "stm32f10x_i2c.h" */ -/* #include "stm32f10x_iwdg.h" */ -#include "stm32f10x_pwr.h" -#include "stm32f10x_rcc.h" -/* #include "stm32f10x_rtc.h" */ -/* #include "stm32f10x_sdio.h" */ -/* #include "stm32f10x_spi.h" */ -/* #include "stm32f10x_tim.h" */ -/* #include "stm32f10x_usart.h" */ -/* #include "stm32f10x_wwdg.h" */ -#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Uncomment the line below to expanse the "assert_param" macro in the - Standard Peripheral Library drivers code */ -/* #define USE_FULL_ASSERT 1 */ - -/* Exported macro ------------------------------------------------------------*/ -#ifdef USE_FULL_ASSERT - -/** - * @brief The assert_param macro is used for function's parameters check. - * @param expr: If expr is false, it calls assert_failed function - * which reports the name of the source file and the source - * line number of the call that failed. - * If expr is true, it returns no value. - * @retval None - */ - #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) -/* Exported functions ------------------------------------------------------- */ - void assert_failed(uint8_t* file, uint32_t line); -#else - #define assert_param(expr) ((void)0) -#endif /* USE_FULL_ASSERT */ - -#endif /* __STM32F10x_CONF_H */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/32vl_factory_demo/stm32f10x_it.c b/example/32vl_factory_demo/stm32f10x_it.c deleted file mode 100644 index c1035270e..000000000 --- a/example/32vl_factory_demo/stm32f10x_it.c +++ /dev/null @@ -1,160 +0,0 @@ -/** - ****************************************************************************** - * @file Demo/src/stm32f10x_it.c - * @author MCD Application Team - * @version V1.0.0 - * @date 09/13/2010 - * @brief Main Interrupt Service Routines. - * This file provides template for all exceptions handler and peripherals - * interrupt service routine. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_it.h" -void TimingDelay_Decrement(void); -/** @addtogroup Demo - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************/ -/* Cortex-M3 Processor Exceptions Handlers */ -/******************************************************************************/ - -/** - * @brief This function handles NMI exception. - * @param None - * @retval None - */ -void NMI_Handler(void) -{ -} - -/** - * @brief This function handles Hard Fault exception. - * @param None - * @retval None - */ -void HardFault_Handler(void) -{ - /* Go to infinite loop when Hard Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Memory Manage exception. - * @param None - * @retval None - */ -void MemManage_Handler(void) -{ - /* Go to infinite loop when Memory Manage exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Bus Fault exception. - * @param None - * @retval None - */ -void BusFault_Handler(void) -{ - /* Go to infinite loop when Bus Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Usage Fault exception. - * @param None - * @retval None - */ -void UsageFault_Handler(void) -{ - /* Go to infinite loop when Usage Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles SVCall exception. - * @param None - * @retval None - */ -void SVC_Handler(void) -{ -} - -/** - * @brief This function handles Debug Monitor exception. - * @param None - * @retval None - */ -void DebugMon_Handler(void) -{ -} - -/** - * @brief This function handles PendSV_Handler exception. - * @param None - * @retval None - */ -void PendSV_Handler(void) -{ -} - -/** - * @brief This function handles SysTick Handler. - * @param None - * @retval None - */ -void SysTick_Handler(void) -{ - TimingDelay_Decrement(); -} - -/******************************************************************************/ -/* STM32F10x Peripherals Interrupt Handlers */ -/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ -/* available peripheral interrupt handler's name please refer to the startup */ -/* file (startup_stm32f10x_xx.s). */ -/******************************************************************************/ - -/** - * @brief This function handles PPP interrupt request. - * @param None - * @retval None - */ -/*void PPP_IRQHandler(void) -{ -}*/ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/32vl_factory_demo/stm32f10x_it.h b/example/32vl_factory_demo/stm32f10x_it.h deleted file mode 100644 index e8d2b316e..000000000 --- a/example/32vl_factory_demo/stm32f10x_it.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - ****************************************************************************** - * @file Demo/inc/stm32f10x_it.h - * @author MCD Team - * @version V1.0.0 - * @date 09/13/2010 - * @brief This file contains the headers of the interrupt handlers. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_IT_H -#define __STM32F10x_IT_H - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/* Exported types ------------------------------------------------------------*/ -extern vu32 TickValue; -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -void NMI_Handler(void); -void HardFault_Handler(void); -void MemManage_Handler(void); -void BusFault_Handler(void); -void UsageFault_Handler(void); -void SVC_Handler(void); -void DebugMon_Handler(void); -void PendSV_Handler(void); -void SysTick_Handler(void); - -#endif /* __STM32F10x_IT_H */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/32vl_factory_demo/system_stm32f10x.c b/example/32vl_factory_demo/system_stm32f10x.c deleted file mode 100644 index aed930ec8..000000000 --- a/example/32vl_factory_demo/system_stm32f10x.c +++ /dev/null @@ -1,1019 +0,0 @@ -/** - ****************************************************************************** - * @file system_stm32f10x.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File. - ****************************************************************************** - * - * 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 stm32f10x_system - * @{ - */ - -/** @addtogroup STM32F10x_System_Private_Includes - * @{ - */ - -#include "stm32f10x.h" - -/** - * @} - */ - -/** @addtogroup STM32F10x_System_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32F10x_System_Private_Defines - * @{ - */ - -/*!< Uncomment the line corresponding to the desired System clock (SYSCLK) - frequency (after reset the HSI is used as SYSCLK source) - - IMPORTANT NOTE: - ============== - 1. After each device reset the HSI is used as System clock source. - - 2. Please make sure that the selected System clock doesn't exceed your device's - maximum frequency. - - 3. If none of the define below is enabled, the HSI is used as System clock - source. - - 4. The System clock configuration functions provided within this file assume that: - - For Low and Medium density Value line devices an external 8MHz crystal - is used to drive the System clock. - - For Low, Medium and High density devices an external 8MHz crystal is - used to drive the System clock. - - For Connectivity line devices an external 25MHz crystal is used to drive - the System clock. - If you are using different crystal you have to adapt those functions accordingly. - */ - -#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) -/* #define SYSCLK_FREQ_HSE HSE_Value */ - #define SYSCLK_FREQ_24MHz 24000000 -#else -/* #define SYSCLK_FREQ_HSE HSE_Value */ -/* #define SYSCLK_FREQ_24MHz 24000000 */ -/* #define SYSCLK_FREQ_36MHz 36000000 */ -/* #define SYSCLK_FREQ_48MHz 48000000 */ -/* #define SYSCLK_FREQ_56MHz 56000000 */ -#define SYSCLK_FREQ_72MHz 72000000 -#endif - -/*!< Uncomment the following line if you need to use external SRAM mounted - on STM3210E-EVAL board (STM32 High density and XL-density devices) as data memory */ -#if defined (STM32F10X_HD) || (defined STM32F10X_XL) -/* #define DATA_IN_ExtSRAM */ -#endif - -/** - * @} - */ - -/** @addtogroup STM32F10x_System_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32F10x_System_Private_Variables - * @{ - */ - -/******************************************************************************* -* Clock Definitions -*******************************************************************************/ -#ifdef SYSCLK_FREQ_HSE - uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!< System Clock Frequency (Core Clock) */ -#elif defined SYSCLK_FREQ_24MHz - uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /*!< System Clock Frequency (Core Clock) */ -#elif defined SYSCLK_FREQ_36MHz - uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz; /*!< System Clock Frequency (Core Clock) */ -#elif defined SYSCLK_FREQ_48MHz - uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /*!< System Clock Frequency (Core Clock) */ -#elif defined SYSCLK_FREQ_56MHz - uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /*!< System Clock Frequency (Core Clock) */ -#elif defined SYSCLK_FREQ_72MHz - uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */ -#else /*!< HSI Selected as System Clock source */ - uint32_t SystemCoreClock = HSI_Value; /*!< System Clock Frequency (Core Clock) */ -#endif - -__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; -/** - * @} - */ - -/** @addtogroup STM32F10x_System_Private_FunctionPrototypes - * @{ - */ - -static void SetSysClock(void); - -#ifdef SYSCLK_FREQ_HSE - static void SetSysClockToHSE(void); -#elif defined SYSCLK_FREQ_24MHz - static void SetSysClockTo24(void); -#elif defined SYSCLK_FREQ_36MHz - static void SetSysClockTo36(void); -#elif defined SYSCLK_FREQ_48MHz - static void SetSysClockTo48(void); -#elif defined SYSCLK_FREQ_56MHz - static void SetSysClockTo56(void); -#elif defined SYSCLK_FREQ_72MHz - static void SetSysClockTo72(void); -#endif - -#ifdef DATA_IN_ExtSRAM - static void SystemInit_ExtMemCtl(void); -#endif /* DATA_IN_ExtSRAM */ - -/** - * @} - */ - -/** @addtogroup STM32F10x_System_Private_Functions - * @{ - */ - -/** - * @brief Setup the microcontroller system - * Initialize the Embedded Flash Interface, the PLL and update the - * SystemCoreClock variable. - * @note This function should be used only after reset. - * @param None - * @retval None - */ -void SystemInit (void) -{ - /* Reset the RCC clock configuration to the default reset state(for debug purpose) */ - /* Set HSION bit */ - RCC->CR |= (uint32_t)0x00000001; - - /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ -#ifndef STM32F10X_CL - RCC->CFGR &= (uint32_t)0xF8FF0000; -#else - RCC->CFGR &= (uint32_t)0xF0FF0000; -#endif /* STM32F10X_CL */ - - /* Reset HSEON, CSSON and PLLON bits */ - RCC->CR &= (uint32_t)0xFEF6FFFF; - - /* Reset HSEBYP bit */ - RCC->CR &= (uint32_t)0xFFFBFFFF; - - /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ - RCC->CFGR &= (uint32_t)0xFF80FFFF; - -#ifdef STM32F10X_CL - /* Reset PLL2ON and PLL3ON bits */ - RCC->CR &= (uint32_t)0xEBFFFFFF; - - /* Disable all interrupts and clear pending bits */ - RCC->CIR = 0x00FF0000; - - /* Reset CFGR2 register */ - RCC->CFGR2 = 0x00000000; -#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) - /* Disable all interrupts and clear pending bits */ - RCC->CIR = 0x009F0000; - - /* Reset CFGR2 register */ - RCC->CFGR2 = 0x00000000; -#else - /* Disable all interrupts and clear pending bits */ - RCC->CIR = 0x009F0000; -#endif /* STM32F10X_CL */ - -#if defined (STM32F10X_HD) || (defined STM32F10X_XL) - #ifdef DATA_IN_ExtSRAM - SystemInit_ExtMemCtl(); - #endif /* DATA_IN_ExtSRAM */ -#endif - - /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ - /* Configure the Flash Latency cycles and enable prefetch buffer */ - SetSysClock(); -} - -/** - * @brief Update SystemCoreClock according to Clock Register Values - * @note None - * @param None - * @retval None - */ -void SystemCoreClockUpdate (void) -{ - uint32_t tmp = 0, pllmull = 0, pllsource = 0; - -#ifdef STM32F10X_CL - uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0; -#endif /* STM32F10X_CL */ - -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) - uint32_t prediv1factor = 0; -#endif /* STM32F10X_LD_VL or STM32F10X_MD_VL */ - - /* Get SYSCLK source -------------------------------------------------------*/ - tmp = RCC->CFGR & RCC_CFGR_SWS; - - switch (tmp) - { - case 0x00: /* HSI used as system clock */ - SystemCoreClock = HSI_Value; - break; - case 0x04: /* HSE used as system clock */ - SystemCoreClock = HSE_Value; - break; - case 0x08: /* PLL used as system clock */ - - /* Get PLL clock source and multiplication factor ----------------------*/ - pllmull = RCC->CFGR & RCC_CFGR_PLLMULL; - pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; - -#ifndef STM32F10X_CL - pllmull = ( pllmull >> 18) + 2; - - if (pllsource == 0x00) - { - /* HSI oscillator clock divided by 2 selected as PLL clock entry */ - SystemCoreClock = (HSI_Value >> 1) * pllmull; - } - else - { - #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) - prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; - /* HSE oscillator clock selected as PREDIV1 clock entry */ - SystemCoreClock = (HSE_Value / prediv1factor) * pllmull; - #else - /* HSE selected as PLL clock entry */ - if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET) - {/* HSE oscillator clock divided by 2 */ - SystemCoreClock = (HSE_Value >> 1) * pllmull; - } - else - { - SystemCoreClock = HSE_Value * pllmull; - } - #endif - } -#else - pllmull = pllmull >> 18; - - if (pllmull != 0x0D) - { - pllmull += 2; - } - else - { /* PLL multiplication factor = PLL input clock * 6.5 */ - pllmull = 13 / 2; - } - - if (pllsource == 0x00) - { - /* HSI oscillator clock divided by 2 selected as PLL clock entry */ - SystemCoreClock = (HSI_Value >> 1) * pllmull; - } - else - {/* PREDIV1 selected as PLL clock entry */ - - /* Get PREDIV1 clock source and division factor */ - prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC; - prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; - - if (prediv1source == 0) - { - /* HSE oscillator clock selected as PREDIV1 clock entry */ - SystemCoreClock = (HSE_Value / prediv1factor) * pllmull; - } - else - {/* PLL2 clock selected as PREDIV1 clock entry */ - - /* Get PREDIV2 division factor and PLL2 multiplication factor */ - prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1; - pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2; - SystemCoreClock = (((HSE_Value / prediv2factor) * pll2mull) / prediv1factor) * pllmull; - } - } -#endif /* STM32F10X_CL */ - break; - - default: - SystemCoreClock = HSI_Value; - 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, HCLK, PCLK2 and PCLK1 prescalers. - * @param None - * @retval None - */ -static void SetSysClock(void) -{ -#ifdef SYSCLK_FREQ_HSE - SetSysClockToHSE(); -#elif defined SYSCLK_FREQ_24MHz - SetSysClockTo24(); -#elif defined SYSCLK_FREQ_36MHz - SetSysClockTo36(); -#elif defined SYSCLK_FREQ_48MHz - SetSysClockTo48(); -#elif defined SYSCLK_FREQ_56MHz - SetSysClockTo56(); -#elif defined SYSCLK_FREQ_72MHz - SetSysClockTo72(); -#endif - - /* If none of the define above is enabled, the HSI is used as System clock - source (default after reset) */ -} - -/** - * @brief Setup the external memory controller. Called in startup_stm32f10x.s - * before jump to __main - * @param None - * @retval None - */ -#ifdef DATA_IN_ExtSRAM -/** - * @brief Setup the external memory controller. - * Called in startup_stm32f10x_xx.s/.c before jump to main. - * This function configures the external SRAM mounted on STM3210E-EVAL - * board (STM32 High density devices). This SRAM will be used as program - * data memory (including heap and stack). - * @param None - * @retval None - */ -void SystemInit_ExtMemCtl(void) -{ -/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is - required, then adjust the Register Addresses */ - - /* Enable FSMC clock */ - RCC->AHBENR = 0x00000114; - - /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */ - RCC->APB2ENR = 0x000001E0; - -/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/ -/*---------------- SRAM Address lines configuration -------------------------*/ -/*---------------- NOE and NWE configuration --------------------------------*/ -/*---------------- NE3 configuration ----------------------------------------*/ -/*---------------- NBL0, NBL1 configuration ---------------------------------*/ - - GPIOD->CRL = 0x44BB44BB; - GPIOD->CRH = 0xBBBBBBBB; - - GPIOE->CRL = 0xB44444BB; - GPIOE->CRH = 0xBBBBBBBB; - - GPIOF->CRL = 0x44BBBBBB; - GPIOF->CRH = 0xBBBB4444; - - GPIOG->CRL = 0x44BBBBBB; - GPIOG->CRH = 0x44444B44; - -/*---------------- FSMC Configuration ---------------------------------------*/ -/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/ - - FSMC_Bank1->BTCR[4] = 0x00001011; - FSMC_Bank1->BTCR[5] = 0x00000200; -} -#endif /* DATA_IN_ExtSRAM */ - -#ifdef SYSCLK_FREQ_HSE -/** - * @brief Selects HSE as System clock source and configure HCLK, PCLK2 - * and PCLK1 prescalers. - * @note This function should be used only after reset. - * @param None - * @retval None - */ -static void SetSysClockToHSE(void) -{ - __IO uint32_t StartUpCounter = 0, HSEStatus = 0; - - /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { - -#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL - /* Enable Prefetch Buffer */ - FLASH->ACR |= FLASH_ACR_PRFTBE; - - /* Flash 0 wait state */ - FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); - -#ifndef STM32F10X_CL - FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; -#else - if (HSE_Value <= 24000000) - { - FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; - } - else - { - FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; - } -#endif /* STM32F10X_CL */ -#endif - - /* HCLK = SYSCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; - - /* PCLK1 = HCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; - - /* Select HSE as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSE; - - /* Wait till HSE is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x04) - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } -} -#elif defined SYSCLK_FREQ_24MHz -/** - * @brief Sets System clock frequency to 24MHz and configure HCLK, PCLK2 - * and PCLK1 prescalers. - * @note This function should be used only after reset. - * @param None - * @retval None - */ -static void SetSysClockTo24(void) -{ - __IO uint32_t StartUpCounter = 0, HSEStatus = 0; - - /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { -#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL - /* Enable Prefetch Buffer */ - FLASH->ACR |= FLASH_ACR_PRFTBE; - - /* Flash 0 wait state */ - FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); - FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; -#endif - - /* HCLK = SYSCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; - - /* PCLK1 = HCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; - -#ifdef STM32F10X_CL - /* Configure PLLs ------------------------------------------------------*/ - /* PLL configuration: PLLCLK = PREDIV1 * 6 = 24 MHz */ - RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); - RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | - RCC_CFGR_PLLMULL6); - - /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ - /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */ - RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | - RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); - RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | - RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10); - - /* Enable PLL2 */ - RCC->CR |= RCC_CR_PLL2ON; - /* Wait till PLL2 is ready */ - while((RCC->CR & RCC_CR_PLL2RDY) == 0) - { - } -#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) - /* PLL configuration: = (HSE / 2) * 6 = 24 MHz */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); - RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2 | RCC_CFGR_PLLMULL6); -#else - /* PLL configuration: = (HSE / 2) * 6 = 24 MHz */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); - RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL6); -#endif /* STM32F10X_CL */ - - /* Enable PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Select PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; - - /* Wait till PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } -} -#elif defined SYSCLK_FREQ_36MHz -/** - * @brief Sets System clock frequency to 36MHz and configure HCLK, PCLK2 - * and PCLK1 prescalers. - * @note This function should be used only after reset. - * @param None - * @retval None - */ -static void SetSysClockTo36(void) -{ - __IO uint32_t StartUpCounter = 0, HSEStatus = 0; - - /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { - /* Enable Prefetch Buffer */ - FLASH->ACR |= FLASH_ACR_PRFTBE; - - /* Flash 1 wait state */ - FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); - FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; - - /* HCLK = SYSCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; - - /* PCLK1 = HCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; - -#ifdef STM32F10X_CL - /* Configure PLLs ------------------------------------------------------*/ - - /* PLL configuration: PLLCLK = PREDIV1 * 9 = 36 MHz */ - RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); - RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | - RCC_CFGR_PLLMULL9); - - /*!< PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ - /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */ - - RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | - RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); - RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | - RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10); - - /* Enable PLL2 */ - RCC->CR |= RCC_CR_PLL2ON; - /* Wait till PLL2 is ready */ - while((RCC->CR & RCC_CR_PLL2RDY) == 0) - { - } - -#else - /* PLL configuration: PLLCLK = (HSE / 2) * 9 = 36 MHz */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); - RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL9); -#endif /* STM32F10X_CL */ - - /* Enable PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Select PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; - - /* Wait till PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } -} -#elif defined SYSCLK_FREQ_48MHz -/** - * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 - * and PCLK1 prescalers. - * @note This function should be used only after reset. - * @param None - * @retval None - */ -static void SetSysClockTo48(void) -{ - __IO uint32_t StartUpCounter = 0, HSEStatus = 0; - - /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { - /* Enable Prefetch Buffer */ - FLASH->ACR |= FLASH_ACR_PRFTBE; - - /* Flash 1 wait state */ - FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); - FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; - - /* HCLK = SYSCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; - - /* PCLK1 = HCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; - -#ifdef STM32F10X_CL - /* Configure PLLs ------------------------------------------------------*/ - /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ - /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ - - RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | - RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); - RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | - RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); - - /* Enable PLL2 */ - RCC->CR |= RCC_CR_PLL2ON; - /* Wait till PLL2 is ready */ - while((RCC->CR & RCC_CR_PLL2RDY) == 0) - { - } - - - /* PLL configuration: PLLCLK = PREDIV1 * 6 = 48 MHz */ - RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); - RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | - RCC_CFGR_PLLMULL6); -#else - /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); - RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6); -#endif /* STM32F10X_CL */ - - /* Enable PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Select PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; - - /* Wait till PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } -} - -#elif defined SYSCLK_FREQ_56MHz -/** - * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 - * and PCLK1 prescalers. - * @note This function should be used only after reset. - * @param None - * @retval None - */ -static void SetSysClockTo56(void) -{ - __IO uint32_t StartUpCounter = 0, HSEStatus = 0; - - /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { - /* Enable Prefetch Buffer */ - FLASH->ACR |= FLASH_ACR_PRFTBE; - - /* Flash 2 wait state */ - FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); - FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; - - /* HCLK = SYSCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; - - /* PCLK1 = HCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; - -#ifdef STM32F10X_CL - /* Configure PLLs ------------------------------------------------------*/ - /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ - /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ - - RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | - RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); - RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | - RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); - - /* Enable PLL2 */ - RCC->CR |= RCC_CR_PLL2ON; - /* Wait till PLL2 is ready */ - while((RCC->CR & RCC_CR_PLL2RDY) == 0) - { - } - - - /* PLL configuration: PLLCLK = PREDIV1 * 7 = 56 MHz */ - RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); - RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | - RCC_CFGR_PLLMULL7); -#else - /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); - RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL7); - -#endif /* STM32F10X_CL */ - - /* Enable PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Select PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; - - /* Wait till PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } -} - -#elif defined SYSCLK_FREQ_72MHz -/** - * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 - * and PCLK1 prescalers. - * @note This function should be used only after reset. - * @param None - * @retval None - */ -static void SetSysClockTo72(void) -{ - __IO uint32_t StartUpCounter = 0, HSEStatus = 0; - - /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { - /* Enable Prefetch Buffer */ - FLASH->ACR |= FLASH_ACR_PRFTBE; - - /* Flash 2 wait state */ - FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); - FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; - - - /* HCLK = SYSCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; - - /* PCLK1 = HCLK */ - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; - -#ifdef STM32F10X_CL - /* Configure PLLs ------------------------------------------------------*/ - /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ - /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ - - RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | - RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); - RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | - RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); - - /* Enable PLL2 */ - RCC->CR |= RCC_CR_PLL2ON; - /* Wait till PLL2 is ready */ - while((RCC->CR & RCC_CR_PLL2RDY) == 0) - { - } - - - /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ - RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); - RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | - RCC_CFGR_PLLMULL9); -#else - /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | - RCC_CFGR_PLLMULL)); - RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); -#endif /* STM32F10X_CL */ - - /* Enable PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Select PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; - - /* Wait till PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } -} -#endif - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/README b/example/README deleted file mode 100644 index 5d72e8282..000000000 --- a/example/README +++ /dev/null @@ -1,6 +0,0 @@ -Don't trust many of these examples yet... A lot of them are a work in -progress... - -A good source of examples is in the libopencm3 sources: http://sourceforge.net/projects/libopencm3/ - - diff --git a/example/blink/Makefile b/example/blink/Makefile deleted file mode 100644 index 60fab84c8..000000000 --- a/example/blink/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -CC=arm-none-eabi-gcc -OBJCOPY=arm-none-eabi-objcopy - -DEF_CFLAGS=-g -O2 -mlittle-endian -mthumb -ffreestanding -nostdlib -nostdinc - -# to run from SRAM -DEF_CFLAGS+=-Wl,-Ttext,0x20000000 -Wl,-e,0x20000000 - -# to write to flash then run -# DEF_CFLAGS+=-Wl,-Ttext,0x08000000 -Wl,-e,0x08000000 - -CFLAGS_VL=$(DEF_CFLAGS) -mcpu=cortex-m3 -DCONFIG_STM32VL_DISCOVERY=1 -CFLAGS_L=$(DEF_CFLAGS) -mcpu=cortex-m3 -DCONFIG_STM32L_DISCOVERY -CFLAGS_F4=$(DEF_CFLAGS) -mcpu=cortex-m4 -DCONFIG_STM32F4_DISCOVERY=1 -CFLAGS_F0=$(DEF_CFLAGS) -mcpu=cortex-m0 -DCONFIG_STM32F0_DISCOVERY=1 - -all: blink_32VL.elf blink_32L.elf blink_F4.elf blink_F0.elf - -%.bin: %.elf - $(OBJCOPY) -O binary $^ $@ - -blink_32VL.elf: main.c - $(CC) $(CFLAGS_VL) $^ -o $@ -blink_32L.elf: main.c - $(CC) $(CFLAGS_L) $^ -o $@ -blink_F4.elf: main.c - $(CC) $(CFLAGS_F4) $^ -o $@ -blink_F0.elf: main.c - $(CC) $(CFLAGS_F0) $^ -o $@ - -clean: - rm -rf *.elf - rm -rf *.bin - -.PHONY: all clean diff --git a/example/blink/main.c b/example/blink/main.c deleted file mode 100644 index 26fcca029..000000000 --- a/example/blink/main.c +++ /dev/null @@ -1,114 +0,0 @@ -/* missing type */ - -typedef unsigned int uint32_t; -void main(void); - -/* hardware configuration */ - -#if CONFIG_STM32VL_DISCOVERY - -#define GPIOC 0x40011000 /* port C */ -#define GPIOC_CRH (GPIOC + 0x04) /* port configuration register high */ -#define LED_PORT_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 */ -#define LED_ORANGE 0 -#define LED_RED 0 - -static inline void setup_leds(void) -{ - *(volatile uint32_t*)GPIOC_CRH = 0x44444411; -} - -#elif CONFIG_STM32L_DISCOVERY - -#define GPIOB 0x40020400 /* port B */ -#define GPIOB_MODER (GPIOB + 0x00) /* port mode register */ -#define LED_PORT_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 */ -#define LED_ORANGE 0 -#define LED_RED 0 - -static inline void setup_leds(void) -{ - /* configure port 6 and 7 as output */ - *(volatile uint32_t*)GPIOB_MODER |= (1 << (7 * 2)) | (1 << (6 * 2)); -} - -#elif CONFIG_STM32F4_DISCOVERY - -#define GPIOD 0x40020C00 /* port D */ -#define GPIOD_MODER (GPIOD + 0x00) /* port mode register */ -#define LED_PORT_ODR (GPIOD + 0x14) /* port output data register */ - -#define LED_GREEN (1 << 12) /* port D, pin 12 */ -#define LED_ORANGE (1 << 13) /* port D, pin 13 */ -#define LED_RED (1 << 14) /* port D, pin 14 */ -#define LED_BLUE (1 << 15) /* port D, pin 15 */ - -void _tmain(void) { - main(); -} -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)); -} - -#elif CONFIG_STM32F0_DISCOVERY - -#define GPIOC 0x48000800 /* port C */ -#define GPIOC_MODER (GPIOC + 0x00) /* port mode register */ -#define LED_PORT_ODR (GPIOC + 0x14) /* port output data register */ - -#define LED_BLUE (1 << 8) /* port C, pin 8 */ -#define LED_GREEN (1 << 9) /* port C, pin 9 */ -#define LED_ORANGE 0 -#define LED_RED 0 - -void _tmain(void) { - main(); -} -static inline void setup_leds(void) -{ - /* configure port 8 and 9 as output */ - *(volatile uint32_t*)GPIOC_MODER |= (1 << (9* 2)) | (1 << (8 * 2)); -} - -#else -#error "Architecture must be defined!" -#endif /* otherwise, error */ - -static inline void switch_leds_on(void) -{ - *(volatile uint32_t*)LED_PORT_ODR = LED_BLUE | LED_GREEN | LED_ORANGE | LED_RED; -} - -static inline void switch_leds_off(void) -{ - *(volatile uint32_t*)LED_PORT_ODR = 0; -} - -#define delay() \ -do { \ - register unsigned int i; \ - for (i = 0; i < 1000000; ++i) \ - __asm__ __volatile__ ("nop\n\t":::"memory"); \ -} while (0) - -/* static void __attribute__((naked)) __attribute__((used)) main(void) */ -void main(void) -{ - setup_leds(); - - while (1) - { - switch_leds_on(); - delay(); - switch_leds_off(); - delay(); - } -} diff --git a/example/blink_flash/Makefile b/example/blink_flash/Makefile deleted file mode 100644 index 1696bf5f0..000000000 --- a/example/blink_flash/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -EXECUTABLE=blink.elf -BIN_IMAGE=blink.bin - -CC=arm-none-eabi-gcc -OBJCOPY=arm-none-eabi-objcopy - -CFLAGS=-O3 -mlittle-endian -mthumb -ifeq ($(CONFIG_STM32L_DISCOVERY), 1) - CFLAGS+=-mcpu=cortex-m3 -DCONFIG_STM32L_DISCOVERY=1 -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 - -PLATFORM=stm32l1xx -LIBS_STM_PATH=../libs_stm - -# stm32l_discovery lib -CFLAGS+=-I$(LIBS_STM_PATH)/inc/base -CFLAGS+=-I$(LIBS_STM_PATH)/inc/core_support -CFLAGS+=-I$(LIBS_STM_PATH)/inc/device_support -CFLAGS+=-I$(LIBS_STM_PATH)/inc/$(PLATFORM) - -LDFLAGS+=-L$(LIBS_STM_PATH)/build -lstm32_stdperiph_l1xx - -all: $(BIN_IMAGE) - -$(BIN_IMAGE): $(EXECUTABLE) - $(OBJCOPY) -O binary $^ $@ - -$(EXECUTABLE): main.c system_stm32l1xx.c startup_stm32l1xx_md.s - $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) - -clean: - rm -rf $(EXECUTABLE) - rm -rf $(BIN_IMAGE) - -write: all - sudo ../../flash/flash write ./blink.bin 0x08000000 - -.PHONY: all clean diff --git a/example/blink_flash/discover_board.h b/example/blink_flash/discover_board.h deleted file mode 100644 index d93a184aa..000000000 --- a/example/blink_flash/discover_board.h +++ /dev/null @@ -1,61 +0,0 @@ - /** - ****************************************************************************** - * @file discover_board.h - * @author Microcontroller Division - * @version V1.0.2 - * @date September-2011 - * @brief Input/Output defines - ****************************************************************************** - * @copy - * - * 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 2011 STMicroelectronics

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef __DISCOVER_BOARD_H -#define __DISCOVER_BOARD_H - -/* Includes ------------------------------------------------------------------*/ -/* #include "stm32l1xx.h" */ - -#define bool _Bool -#define FALSE 0 -#define TRUE !FALSE - -/* MACROs for SET, RESET or TOGGLE Output port */ - -#define GPIO_HIGH(a,b) a->BSRRL = b -#define GPIO_LOW(a,b) a->BSRRH = b -#define GPIO_TOGGLE(a,b) a->ODR ^= b - -#define USERBUTTON_GPIO_PORT GPIOA -#define USERBUTTON_GPIO_PIN GPIO_Pin_0 -#define USERBUTTON_GPIO_CLK RCC_AHBPeriph_GPIOA - -#define LD_GPIO_PORT GPIOB -#define LD_GREEN_GPIO_PIN GPIO_Pin_7 -#define LD_BLUE_GPIO_PIN GPIO_Pin_6 -#define LD_GPIO_PORT_CLK RCC_AHBPeriph_GPIOB - -#define CTN_GPIO_PORT GPIOC -#define CTN_CNTEN_GPIO_PIN GPIO_Pin_13 -#define CTN_GPIO_CLK RCC_AHBPeriph_GPIOC - -#define WAKEUP_GPIO_PORT GPIOA - -#define IDD_MEASURE_PORT GPIOA -#define IDD_MEASURE GPIO_Pin_4 - - -#endif - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/blink_flash/main.c b/example/blink_flash/main.c deleted file mode 100644 index 4385b0971..000000000 --- a/example/blink_flash/main.c +++ /dev/null @@ -1,197 +0,0 @@ -/* base headers */ -#include "stdint.h" - -/* libstm32l_discovery headers */ -#include "stm32l1xx_gpio.h" -#include "stm32l1xx_adc.h" -#include "stm32l1xx_lcd.h" -#include "stm32l1xx_rcc.h" -#include "stm32l1xx_rtc.h" -#include "stm32l1xx_exti.h" -#include "stm32l1xx_pwr.h" -#include "stm32l1xx_flash.h" -#include "stm32l1xx_syscfg.h" -#include "stm32l1xx_dbgmcu.h" - -/* board specific macros */ -#include "discover_board.h" - - -/* hardware configuration */ - -#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_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) -{ - GPIO_HIGH(LD_GPIO_PORT, LD_GREEN_GPIO_PIN); - GPIO_HIGH(LD_GPIO_PORT, LD_BLUE_GPIO_PIN); -} - -static inline void switch_leds_off(void) -{ - GPIO_LOW(LD_GPIO_PORT, LD_GREEN_GPIO_PIN); - GPIO_LOW(LD_GPIO_PORT, LD_BLUE_GPIO_PIN); -} - -#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 */ - -void _tmain(void) { - main(); -} -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_RED ; -} - -static inline void switch_leds_off(void) -{ - *(volatile uint32_t*)GPIOD_ODR = 0; -} - -#endif /* otherwise, error */ - - -#define delay() \ -do { \ - volatile unsigned int i; \ - for (i = 0; i < 1000000; ++i) \ - __asm__ __volatile__ ("nop\n\t":::"memory"); \ -} while (0) - - -static void RCC_Configuration(void) -{ - /* Enable HSI Clock */ - RCC_HSICmd(ENABLE); - - /*!< Wait till HSI is ready */ - while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET) - {} - - RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI); - - RCC_MSIRangeConfig(RCC_MSIRange_6); - - RCC_HSEConfig(RCC_HSE_OFF); - if(RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET ) - { - while(1); - } -} - - -static void RTC_Configuration(void) -{ - /* Allow access to the RTC */ - PWR_RTCAccessCmd(ENABLE); - - /* Reset Backup Domain */ - RCC_RTCResetCmd(ENABLE); - RCC_RTCResetCmd(DISABLE); - - /* LSE Enable */ - RCC_LSEConfig(RCC_LSE_ON); - - /* Wait till LSE is ready */ - while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) - {} - - RCC_RTCCLKCmd(ENABLE); - - /* LCD Clock Source Selection */ - RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); - -} - -void main(void) -{ - static RCC_ClocksTypeDef RCC_Clocks; - static GPIO_InitTypeDef GPIO_InitStructure; - - /* Configure Clocks for Application need */ - RCC_Configuration(); - - /* Configure RTC Clocks */ - RTC_Configuration(); - - /* Set internal voltage regulator to 1.8V */ - PWR_VoltageScalingConfig(PWR_VoltageScaling_Range1); - - /* Wait Until the Voltage Regulator is ready */ - while (PWR_GetFlagStatus(PWR_FLAG_VOS) != RESET) ; - - /* configure gpios */ - - /* Enable GPIOs clock */ - RCC_AHBPeriphClockCmd(LD_GPIO_PORT_CLK, ENABLE); - - /* Configure the GPIO_LED pins LD3 & LD4*/ - GPIO_InitStructure.GPIO_Pin = LD_GREEN_GPIO_PIN | LD_BLUE_GPIO_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_Init(LD_GPIO_PORT, &GPIO_InitStructure); - GPIO_LOW(LD_GPIO_PORT, LD_GREEN_GPIO_PIN); - GPIO_LOW(LD_GPIO_PORT, LD_BLUE_GPIO_PIN); - - 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 deleted file mode 100644 index 9a8389c9f..000000000 --- a/example/blink_flash/startup_stm32l1xx_md.s +++ /dev/null @@ -1,365 +0,0 @@ -/** - ****************************************************************************** - * @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 deleted file mode 100644 index 146b16ecc..000000000 --- a/example/blink_flash/stm32_flash.ld +++ /dev/null @@ -1,173 +0,0 @@ -/* -***************************************************************************** -** -** 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 deleted file mode 100644 index 6deab320c..000000000 --- a/example/blink_flash/system_stm32l1xx.c +++ /dev/null @@ -1,367 +0,0 @@ -/** - ****************************************************************************** - * @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/example/libs_stm/README b/example/libs_stm/README deleted file mode 100644 index c3dcc4e4b..000000000 --- a/example/libs_stm/README +++ /dev/null @@ -1,9 +0,0 @@ -This directory contains the StdPeriph libraries from ST, and the CMSIS core and device -support, all from ST. - -Issues: -* No tracking of which version of which library (yet) -* Both of these define assert_param() as empty. That may not be what you - want! - - diff --git a/example/libs_stm/build/Makefile b/example/libs_stm/build/Makefile deleted file mode 100644 index d35e3d69f..000000000 --- a/example/libs_stm/build/Makefile +++ /dev/null @@ -1,10 +0,0 @@ - -all: - make -f Makefile.f10x - make -f Makefile.l1xx - -clean: - make -f Makefile.f10x clean - make -f Makefile.l1xx clean - -.PHONY: all clean diff --git a/example/libs_stm/build/Makefile.common b/example/libs_stm/build/Makefile.common deleted file mode 100644 index 954413e1b..000000000 --- a/example/libs_stm/build/Makefile.common +++ /dev/null @@ -1,34 +0,0 @@ -CC = arm-none-eabi-gcc -AR = arm-none-eabi-ar -RANLIB = arm-none-eabi-ranlib - - -INC_CORE_SUPPORT=../inc/core_support -SRC_CORE_SUPPORT=../inc/core_support -INC_DEVICE_SUPPORT=../inc/device_support -INC_PLATFORM=../inc/$(PLATFORM) -SRC_PLATFORM=../src/$(PLATFORM) - -CFLAGS += -Wall -O2 -mlittle-endian -mthumb -CFLAGS += -mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc -CFLAGS += -I$(INC_PLATFORM) -I$(INC_DEVICE_SUPPORT) -I$(INC_CORE_SUPPORT) -I../inc/base - -SRCS=$(wildcard $(SRC_PLATFORM)/*.c) -SRCS+=$(SRC_CORE_SUPPORT)/core_cm3.c - -OBJS = $(SRCS:.c=.o) - -all: $(LIB) - -$(LIB): $(OBJS) - $(AR) -r $(LIB) $(OBJS) - $(RANLIB) $(LIB) - -%.o : %.c - $(CC) $(CFLAGS) -c -o $@ $^ - -clean: - -rm -f $(OBJS) - -rm -f $(LIB) - -.PHONY: all clean diff --git a/example/libs_stm/build/Makefile.f10x b/example/libs_stm/build/Makefile.f10x deleted file mode 100644 index dfe0376ab..000000000 --- a/example/libs_stm/build/Makefile.f10x +++ /dev/null @@ -1,5 +0,0 @@ -LIB = libstm32_stdperiph_f10x.a -PLATFORM=stm32f10x -CFLAGS+= -mcpu=cortex-m3 - -include Makefile.common diff --git a/example/libs_stm/build/Makefile.l1xx b/example/libs_stm/build/Makefile.l1xx deleted file mode 100644 index 7469ff58f..000000000 --- a/example/libs_stm/build/Makefile.l1xx +++ /dev/null @@ -1,5 +0,0 @@ -LIB = libstm32_stdperiph_l1xx.a -PLATFORM=stm32l1xx -CFLAGS+=-mcpu=cortex-m3 - -include Makefile.common diff --git a/example/libs_stm/inc/base/stdint.h b/example/libs_stm/inc/base/stdint.h deleted file mode 100644 index 00d4aaf82..000000000 --- a/example/libs_stm/inc/base/stdint.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef STDINT_H_INCLUDED -# define STDINT_H_INCLUDED - - -typedef char int8_t; -typedef short int16_t; -typedef int int32_t; -typedef long long int64_t; - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; - - -#endif /* ! STDINT_H_INCLUDED */ diff --git a/example/libs_stm/inc/core_support/core_cm3.c b/example/libs_stm/inc/core_support/core_cm3.c deleted file mode 100644 index 56fddc52b..000000000 --- a/example/libs_stm/inc/core_support/core_cm3.c +++ /dev/null @@ -1,784 +0,0 @@ -/**************************************************************************//** - * @file core_cm3.c - * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File - * @version V1.30 - * @date 30. October 2009 - * - * @note - * Copyright (C) 2009 ARM Limited. All rights reserved. - * - * @par - * ARM Limited (ARM) is supplying this software for use with Cortex-M - * processor based microcontrollers. This file can be freely distributed - * within development tools that are supporting such ARM based processors. - * - * @par - * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED - * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. - * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. - * - ******************************************************************************/ - -#include - -/* define compiler specific symbols */ -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */ - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - -#endif - - -/* ################### Compiler specific Intrinsics ########################### */ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -/** - * @brief Return the Process Stack Pointer - * - * @return ProcessStackPointer - * - * Return the actual process stack pointer - */ -__ASM uint32_t __get_PSP(void) -{ - mrs r0, psp - bx lr -} - -/** - * @brief Set the Process Stack Pointer - * - * @param topOfProcStack Process Stack Pointer - * - * Assign the value ProcessStackPointer to the MSP - * (process stack pointer) Cortex processor register - */ -__ASM void __set_PSP(uint32_t topOfProcStack) -{ - msr psp, r0 - bx lr -} - -/** - * @brief Return the Main Stack Pointer - * - * @return Main Stack Pointer - * - * Return the current value of the MSP (main stack pointer) - * Cortex processor register - */ -__ASM uint32_t __get_MSP(void) -{ - mrs r0, msp - bx lr -} - -/** - * @brief Set the Main Stack Pointer - * - * @param topOfMainStack Main Stack Pointer - * - * Assign the value mainStackPointer to the MSP - * (main stack pointer) Cortex processor register - */ -__ASM void __set_MSP(uint32_t mainStackPointer) -{ - msr msp, r0 - bx lr -} - -/** - * @brief Reverse byte order in unsigned short value - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in unsigned short value - */ -__ASM uint32_t __REV16(uint16_t value) -{ - rev16 r0, r0 - bx lr -} - -/** - * @brief Reverse byte order in signed short value with sign extension to integer - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in signed short value with sign extension to integer - */ -__ASM int32_t __REVSH(int16_t value) -{ - revsh r0, r0 - bx lr -} - - -#if (__ARMCC_VERSION < 400000) - -/** - * @brief Remove the exclusive lock created by ldrex - * - * Removes the exclusive lock which is created by ldrex. - */ -__ASM void __CLREX(void) -{ - clrex -} - -/** - * @brief Return the Base Priority value - * - * @return BasePriority - * - * Return the content of the base priority register - */ -__ASM uint32_t __get_BASEPRI(void) -{ - mrs r0, basepri - bx lr -} - -/** - * @brief Set the Base Priority value - * - * @param basePri BasePriority - * - * Set the base priority register - */ -__ASM void __set_BASEPRI(uint32_t basePri) -{ - msr basepri, r0 - bx lr -} - -/** - * @brief Return the Priority Mask value - * - * @return PriMask - * - * Return state of the priority mask bit from the priority mask register - */ -__ASM uint32_t __get_PRIMASK(void) -{ - mrs r0, primask - bx lr -} - -/** - * @brief Set the Priority Mask value - * - * @param priMask PriMask - * - * Set the priority mask bit in the priority mask register - */ -__ASM void __set_PRIMASK(uint32_t priMask) -{ - msr primask, r0 - bx lr -} - -/** - * @brief Return the Fault Mask value - * - * @return FaultMask - * - * Return the content of the fault mask register - */ -__ASM uint32_t __get_FAULTMASK(void) -{ - mrs r0, faultmask - bx lr -} - -/** - * @brief Set the Fault Mask value - * - * @param faultMask faultMask value - * - * Set the fault mask register - */ -__ASM void __set_FAULTMASK(uint32_t faultMask) -{ - msr faultmask, r0 - bx lr -} - -/** - * @brief Return the Control Register value - * - * @return Control value - * - * Return the content of the control register - */ -__ASM uint32_t __get_CONTROL(void) -{ - mrs r0, control - bx lr -} - -/** - * @brief Set the Control Register value - * - * @param control Control value - * - * Set the control register - */ -__ASM void __set_CONTROL(uint32_t control) -{ - msr control, r0 - bx lr -} - -#endif /* __ARMCC_VERSION */ - - - -#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ -#pragma diag_suppress=Pe940 - -/** - * @brief Return the Process Stack Pointer - * - * @return ProcessStackPointer - * - * Return the actual process stack pointer - */ -uint32_t __get_PSP(void) -{ - __ASM("mrs r0, psp"); - __ASM("bx lr"); -} - -/** - * @brief Set the Process Stack Pointer - * - * @param topOfProcStack Process Stack Pointer - * - * Assign the value ProcessStackPointer to the MSP - * (process stack pointer) Cortex processor register - */ -void __set_PSP(uint32_t topOfProcStack) -{ - __ASM("msr psp, r0"); - __ASM("bx lr"); -} - -/** - * @brief Return the Main Stack Pointer - * - * @return Main Stack Pointer - * - * Return the current value of the MSP (main stack pointer) - * Cortex processor register - */ -uint32_t __get_MSP(void) -{ - __ASM("mrs r0, msp"); - __ASM("bx lr"); -} - -/** - * @brief Set the Main Stack Pointer - * - * @param topOfMainStack Main Stack Pointer - * - * Assign the value mainStackPointer to the MSP - * (main stack pointer) Cortex processor register - */ -void __set_MSP(uint32_t topOfMainStack) -{ - __ASM("msr msp, r0"); - __ASM("bx lr"); -} - -/** - * @brief Reverse byte order in unsigned short value - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in unsigned short value - */ -uint32_t __REV16(uint16_t value) -{ - __ASM("rev16 r0, r0"); - __ASM("bx lr"); -} - -/** - * @brief Reverse bit order of value - * - * @param value value to reverse - * @return reversed value - * - * Reverse bit order of value - */ -uint32_t __RBIT(uint32_t value) -{ - __ASM("rbit r0, r0"); - __ASM("bx lr"); -} - -/** - * @brief LDR Exclusive (8 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 8 bit values) - */ -uint8_t __LDREXB(uint8_t *addr) -{ - __ASM("ldrexb r0, [r0]"); - __ASM("bx lr"); -} - -/** - * @brief LDR Exclusive (16 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 16 bit values - */ -uint16_t __LDREXH(uint16_t *addr) -{ - __ASM("ldrexh r0, [r0]"); - __ASM("bx lr"); -} - -/** - * @brief LDR Exclusive (32 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 32 bit values - */ -uint32_t __LDREXW(uint32_t *addr) -{ - __ASM("ldrex r0, [r0]"); - __ASM("bx lr"); -} - -/** - * @brief STR Exclusive (8 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 8 bit values - */ -uint32_t __STREXB(uint8_t value, uint8_t *addr) -{ - __ASM("strexb r0, r0, [r1]"); - __ASM("bx lr"); -} - -/** - * @brief STR Exclusive (16 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 16 bit values - */ -uint32_t __STREXH(uint16_t value, uint16_t *addr) -{ - __ASM("strexh r0, r0, [r1]"); - __ASM("bx lr"); -} - -/** - * @brief STR Exclusive (32 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 32 bit values - */ -uint32_t __STREXW(uint32_t value, uint32_t *addr) -{ - __ASM("strex r0, r0, [r1]"); - __ASM("bx lr"); -} - -#pragma diag_default=Pe940 - - -#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/** - * @brief Return the Process Stack Pointer - * - * @return ProcessStackPointer - * - * Return the actual process stack pointer - */ -uint32_t __get_PSP(void) __attribute__( ( naked ) ); -uint32_t __get_PSP(void) -{ - uint32_t result=0; - - __ASM volatile ("MRS %0, psp\n\t" - "MOV r0, %0 \n\t" - "BX lr \n\t" : "=r" (result) ); - return(result); -} - -/** - * @brief Set the Process Stack Pointer - * - * @param topOfProcStack Process Stack Pointer - * - * Assign the value ProcessStackPointer to the MSP - * (process stack pointer) Cortex processor register - */ -void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) ); -void __set_PSP(uint32_t topOfProcStack) -{ - __ASM volatile ("MSR psp, %0\n\t" - "BX lr \n\t" : : "r" (topOfProcStack) ); -} - -/** - * @brief Return the Main Stack Pointer - * - * @return Main Stack Pointer - * - * Return the current value of the MSP (main stack pointer) - * Cortex processor register - */ -uint32_t __get_MSP(void) __attribute__( ( naked ) ); -uint32_t __get_MSP(void) -{ - uint32_t result=0; - - __ASM volatile ("MRS %0, msp\n\t" - "MOV r0, %0 \n\t" - "BX lr \n\t" : "=r" (result) ); - return(result); -} - -/** - * @brief Set the Main Stack Pointer - * - * @param topOfMainStack Main Stack Pointer - * - * Assign the value mainStackPointer to the MSP - * (main stack pointer) Cortex processor register - */ -void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) ); -void __set_MSP(uint32_t topOfMainStack) -{ - __ASM volatile ("MSR msp, %0\n\t" - "BX lr \n\t" : : "r" (topOfMainStack) ); -} - -/** - * @brief Return the Base Priority value - * - * @return BasePriority - * - * Return the content of the base priority register - */ -uint32_t __get_BASEPRI(void) -{ - uint32_t result=0; - - __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); - return(result); -} - -/** - * @brief Set the Base Priority value - * - * @param basePri BasePriority - * - * Set the base priority register - */ -void __set_BASEPRI(uint32_t value) -{ - __ASM volatile ("MSR basepri, %0" : : "r" (value) ); -} - -/** - * @brief Return the Priority Mask value - * - * @return PriMask - * - * Return state of the priority mask bit from the priority mask register - */ -uint32_t __get_PRIMASK(void) -{ - uint32_t result=0; - - __ASM volatile ("MRS %0, primask" : "=r" (result) ); - return(result); -} - -/** - * @brief Set the Priority Mask value - * - * @param priMask PriMask - * - * Set the priority mask bit in the priority mask register - */ -void __set_PRIMASK(uint32_t priMask) -{ - __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); -} - -/** - * @brief Return the Fault Mask value - * - * @return FaultMask - * - * Return the content of the fault mask register - */ -uint32_t __get_FAULTMASK(void) -{ - uint32_t result=0; - - __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); - return(result); -} - -/** - * @brief Set the Fault Mask value - * - * @param faultMask faultMask value - * - * Set the fault mask register - */ -void __set_FAULTMASK(uint32_t faultMask) -{ - __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) ); -} - -/** - * @brief Return the Control Register value -* -* @return Control value - * - * Return the content of the control register - */ -uint32_t __get_CONTROL(void) -{ - uint32_t result=0; - - __ASM volatile ("MRS %0, control" : "=r" (result) ); - return(result); -} - -/** - * @brief Set the Control Register value - * - * @param control Control value - * - * Set the control register - */ -void __set_CONTROL(uint32_t control) -{ - __ASM volatile ("MSR control, %0" : : "r" (control) ); -} - - -/** - * @brief Reverse byte order in integer value - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in integer value - */ -uint32_t __REV(uint32_t value) -{ - uint32_t result=0; - - __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - -/** - * @brief Reverse byte order in unsigned short value - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in unsigned short value - */ -uint32_t __REV16(uint16_t value) -{ - uint32_t result=0; - - __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - -/** - * @brief Reverse byte order in signed short value with sign extension to integer - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in signed short value with sign extension to integer - */ -int32_t __REVSH(int16_t value) -{ - uint32_t result=0; - - __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - -/** - * @brief Reverse bit order of value - * - * @param value value to reverse - * @return reversed value - * - * Reverse bit order of value - */ -uint32_t __RBIT(uint32_t value) -{ - uint32_t result=0; - - __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - -/** - * @brief LDR Exclusive (8 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 8 bit value - */ -uint8_t __LDREXB(uint8_t *addr) -{ - uint8_t result=0; - - __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - -/** - * @brief LDR Exclusive (16 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 16 bit values - */ -uint16_t __LDREXH(uint16_t *addr) -{ - uint16_t result=0; - - __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - -/** - * @brief LDR Exclusive (32 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 32 bit values - */ -uint32_t __LDREXW(uint32_t *addr) -{ - uint32_t result=0; - - __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - -/** - * @brief STR Exclusive (8 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 8 bit values - */ -uint32_t __STREXB(uint8_t value, uint8_t *addr) -{ - uint32_t result=0; - - __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); - return(result); -} - -/** - * @brief STR Exclusive (16 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 16 bit values - */ -uint32_t __STREXH(uint16_t value, uint16_t *addr) -{ - uint32_t result=0; - - __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); - return(result); -} - -/** - * @brief STR Exclusive (32 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 32 bit values - */ -uint32_t __STREXW(uint32_t value, uint32_t *addr) -{ - uint32_t result=0; - - __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); - return(result); -} - - -#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/ -/* TASKING carm specific functions */ - -/* - * The CMSIS functions have been implemented as intrinsics in the compiler. - * Please use "carm -?i" to get an up to date list of all instrinsics, - * Including the CMSIS ones. - */ - -#endif diff --git a/example/libs_stm/inc/core_support/core_cm3.h b/example/libs_stm/inc/core_support/core_cm3.h deleted file mode 100644 index 2b6b51a7d..000000000 --- a/example/libs_stm/inc/core_support/core_cm3.h +++ /dev/null @@ -1,1818 +0,0 @@ -/**************************************************************************//** - * @file core_cm3.h - * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File - * @version V1.30 - * @date 30. October 2009 - * - * @note - * Copyright (C) 2009 ARM Limited. All rights reserved. - * - * @par - * ARM Limited (ARM) is supplying this software for use with Cortex-M - * processor based microcontrollers. This file can be freely distributed - * within development tools that are supporting such ARM based processors. - * - * @par - * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED - * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. - * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. - * - ******************************************************************************/ - -#ifndef __CM3_CORE_H__ -#define __CM3_CORE_H__ - -/** @addtogroup CMSIS_CM3_core_LintCinfiguration CMSIS CM3 Core Lint Configuration - * - * List of Lint messages which will be suppressed and not shown: - * - Error 10: \n - * register uint32_t __regBasePri __asm("basepri"); \n - * Error 10: Expecting ';' - * . - * - Error 530: \n - * return(__regBasePri); \n - * Warning 530: Symbol '__regBasePri' (line 264) not initialized - * . - * - Error 550: \n - * __regBasePri = (basePri & 0x1ff); \n - * Warning 550: Symbol '__regBasePri' (line 271) not accessed - * . - * - Error 754: \n - * uint32_t RESERVED0[24]; \n - * Info 754: local structure member '' (line 109, file ./cm3_core.h) not referenced - * . - * - Error 750: \n - * #define __CM3_CORE_H__ \n - * Info 750: local macro '__CM3_CORE_H__' (line 43, file./cm3_core.h) not referenced - * . - * - Error 528: \n - * static __INLINE void NVIC_DisableIRQ(uint32_t IRQn) \n - * Warning 528: Symbol 'NVIC_DisableIRQ(unsigned int)' (line 419, file ./cm3_core.h) not referenced - * . - * - Error 751: \n - * } InterruptType_Type; \n - * Info 751: local typedef 'InterruptType_Type' (line 170, file ./cm3_core.h) not referenced - * . - * Note: To re-enable a Message, insert a space before 'lint' * - * - */ - -/*lint -save */ -/*lint -e10 */ -/*lint -e530 */ -/*lint -e550 */ -/*lint -e754 */ -/*lint -e750 */ -/*lint -e528 */ -/*lint -e751 */ - - -/** @addtogroup CMSIS_CM3_core_definitions CM3 Core Definitions - This file defines all structures and symbols for CMSIS core: - - CMSIS version number - - Cortex-M core registers and bitfields - - Cortex-M core peripheral base address - @{ - */ - -#ifdef __cplusplus - extern "C" { -#endif - -#define __CM3_CMSIS_VERSION_MAIN (0x01) /*!< [31:16] CMSIS HAL main version */ -#define __CM3_CMSIS_VERSION_SUB (0x30) /*!< [15:0] CMSIS HAL sub version */ -#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x03) /*!< Cortex core */ - -#include /* Include standard types */ - -#if defined (__ICCARM__) - #include /* IAR Intrinsics */ -#endif - - -#ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 4 /*!< standard definition for NVIC Priority Bits */ -#endif - - - - -/** - * IO definitions - * - * define access restrictions to peripheral registers - */ - -#ifdef __cplusplus - #define __I volatile /*!< defines 'read only' permissions */ -#else - #define __I volatile const /*!< defines 'read only' permissions */ -#endif -#define __O volatile /*!< defines 'write only' permissions */ -#define __IO volatile /*!< defines 'read / write' permissions */ - - - -/******************************************************************************* - * Register Abstraction - ******************************************************************************/ -/** @addtogroup CMSIS_CM3_core_register CMSIS CM3 Core Register - @{ -*/ - - -/** @addtogroup CMSIS_CM3_NVIC CMSIS CM3 NVIC - memory mapped structure for Nested Vectored Interrupt Controller (NVIC) - @{ - */ -typedef struct -{ - __IO uint32_t ISER[8]; /*!< Offset: 0x000 Interrupt Set Enable Register */ - uint32_t RESERVED0[24]; - __IO uint32_t ICER[8]; /*!< Offset: 0x080 Interrupt Clear Enable Register */ - uint32_t RSERVED1[24]; - __IO uint32_t ISPR[8]; /*!< Offset: 0x100 Interrupt Set Pending Register */ - uint32_t RESERVED2[24]; - __IO uint32_t ICPR[8]; /*!< Offset: 0x180 Interrupt Clear Pending Register */ - uint32_t RESERVED3[24]; - __IO uint32_t IABR[8]; /*!< Offset: 0x200 Interrupt Active bit Register */ - uint32_t RESERVED4[56]; - __IO uint8_t IP[240]; /*!< Offset: 0x300 Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644]; - __O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */ -} NVIC_Type; -/*@}*/ /* end of group CMSIS_CM3_NVIC */ - - -/** @addtogroup CMSIS_CM3_SCB CMSIS CM3 SCB - memory mapped structure for System Control Block (SCB) - @{ - */ -typedef struct -{ - __I uint32_t CPUID; /*!< Offset: 0x00 CPU ID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x04 Interrupt Control State Register */ - __IO uint32_t VTOR; /*!< Offset: 0x08 Vector Table Offset Register */ - __IO uint32_t AIRCR; /*!< Offset: 0x0C Application Interrupt / Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x10 System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x14 Configuration Control Register */ - __IO uint8_t SHP[12]; /*!< Offset: 0x18 System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IO uint32_t SHCSR; /*!< Offset: 0x24 System Handler Control and State Register */ - __IO uint32_t CFSR; /*!< Offset: 0x28 Configurable Fault Status Register */ - __IO uint32_t HFSR; /*!< Offset: 0x2C Hard Fault Status Register */ - __IO uint32_t DFSR; /*!< Offset: 0x30 Debug Fault Status Register */ - __IO uint32_t MMFAR; /*!< Offset: 0x34 Mem Manage Address Register */ - __IO uint32_t BFAR; /*!< Offset: 0x38 Bus Fault Address Register */ - __IO uint32_t AFSR; /*!< Offset: 0x3C Auxiliary Fault Status Register */ - __I uint32_t PFR[2]; /*!< Offset: 0x40 Processor Feature Register */ - __I uint32_t DFR; /*!< Offset: 0x48 Debug Feature Register */ - __I uint32_t ADR; /*!< Offset: 0x4C Auxiliary Feature Register */ - __I uint32_t MMFR[4]; /*!< Offset: 0x50 Memory Model Feature Register */ - __I uint32_t ISAR[5]; /*!< Offset: 0x60 ISA Feature Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFul << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFul << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFul << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ -#define SCB_CPUID_REVISION_Msk (0xFul << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1ul << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1ul << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1ul << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1ul << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1ul << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1ul << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1ul << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFul << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ -#define SCB_ICSR_RETTOBASE_Msk (1ul << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFul << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_VTOR_TBLBASE_Pos 29 /*!< SCB VTOR: TBLBASE Position */ -#define SCB_VTOR_TBLBASE_Msk (0x1FFul << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ - -#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFul << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFul << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFul << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1ul << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ -#define SCB_AIRCR_PRIGROUP_Msk (7ul << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1ul << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1ul << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ -#define SCB_AIRCR_VECTRESET_Msk (1ul << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1ul << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1ul << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1ul << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ - -/* SCB Configuration Control Register Definitions */ -#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1ul << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ -#define SCB_CCR_BFHFNMIGN_Msk (1ul << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ - -#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ -#define SCB_CCR_DIV_0_TRP_Msk (1ul << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1ul << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ -#define SCB_CCR_USERSETMPEND_Msk (1ul << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ - -#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ -#define SCB_CCR_NONBASETHRDENA_Msk (1ul << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ -#define SCB_SHCSR_USGFAULTENA_Msk (1ul << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ - -#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ -#define SCB_SHCSR_BUSFAULTENA_Msk (1ul << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ - -#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ -#define SCB_SHCSR_MEMFAULTENA_Msk (1ul << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ - -#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1ul << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ -#define SCB_SHCSR_BUSFAULTPENDED_Msk (1ul << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ - -#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ -#define SCB_SHCSR_MEMFAULTPENDED_Msk (1ul << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ - -#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ -#define SCB_SHCSR_USGFAULTPENDED_Msk (1ul << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ - -#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ -#define SCB_SHCSR_SYSTICKACT_Msk (1ul << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ - -#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ -#define SCB_SHCSR_PENDSVACT_Msk (1ul << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ - -#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ -#define SCB_SHCSR_MONITORACT_Msk (1ul << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ - -#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ -#define SCB_SHCSR_SVCALLACT_Msk (1ul << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ - -#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ -#define SCB_SHCSR_USGFAULTACT_Msk (1ul << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ - -#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ -#define SCB_SHCSR_BUSFAULTACT_Msk (1ul << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ - -#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ -#define SCB_SHCSR_MEMFAULTACT_Msk (1ul << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ - -/* SCB Configurable Fault Status Registers Definitions */ -#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ -#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFul << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ - -#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ -#define SCB_CFSR_BUSFAULTSR_Msk (0xFFul << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ - -#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ -#define SCB_CFSR_MEMFAULTSR_Msk (0xFFul << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ - -/* SCB Hard Fault Status Registers Definitions */ -#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ -#define SCB_HFSR_DEBUGEVT_Msk (1ul << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ - -#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ -#define SCB_HFSR_FORCED_Msk (1ul << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ - -#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ -#define SCB_HFSR_VECTTBL_Msk (1ul << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ - -/* SCB Debug Fault Status Register Definitions */ -#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ -#define SCB_DFSR_EXTERNAL_Msk (1ul << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ - -#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ -#define SCB_DFSR_VCATCH_Msk (1ul << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ - -#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ -#define SCB_DFSR_DWTTRAP_Msk (1ul << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ - -#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ -#define SCB_DFSR_BKPT_Msk (1ul << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ - -#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ -#define SCB_DFSR_HALTED_Msk (1ul << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ -/*@}*/ /* end of group CMSIS_CM3_SCB */ - - -/** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick - memory mapped structure for SysTick - @{ - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1ul << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1ul << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1ul << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ -/*@}*/ /* end of group CMSIS_CM3_SysTick */ - - -/** @addtogroup CMSIS_CM3_ITM CMSIS CM3 ITM - memory mapped structure for Instrumentation Trace Macrocell (ITM) - @{ - */ -typedef struct -{ - __O union - { - __O uint8_t u8; /*!< Offset: ITM Stimulus Port 8-bit */ - __O uint16_t u16; /*!< Offset: ITM Stimulus Port 16-bit */ - __O uint32_t u32; /*!< Offset: ITM Stimulus Port 32-bit */ - } PORT [32]; /*!< Offset: 0x00 ITM Stimulus Port Registers */ - uint32_t RESERVED0[864]; - __IO uint32_t TER; /*!< Offset: ITM Trace Enable Register */ - uint32_t RESERVED1[15]; - __IO uint32_t TPR; /*!< Offset: ITM Trace Privilege Register */ - uint32_t RESERVED2[15]; - __IO uint32_t TCR; /*!< Offset: ITM Trace Control Register */ - uint32_t RESERVED3[29]; - __IO uint32_t IWR; /*!< Offset: ITM Integration Write Register */ - __IO uint32_t IRR; /*!< Offset: ITM Integration Read Register */ - __IO uint32_t IMCR; /*!< Offset: ITM Integration Mode Control Register */ - uint32_t RESERVED4[43]; - __IO uint32_t LAR; /*!< Offset: ITM Lock Access Register */ - __IO uint32_t LSR; /*!< Offset: ITM Lock Status Register */ - uint32_t RESERVED5[6]; - __I uint32_t PID4; /*!< Offset: ITM Peripheral Identification Register #4 */ - __I uint32_t PID5; /*!< Offset: ITM Peripheral Identification Register #5 */ - __I uint32_t PID6; /*!< Offset: ITM Peripheral Identification Register #6 */ - __I uint32_t PID7; /*!< Offset: ITM Peripheral Identification Register #7 */ - __I uint32_t PID0; /*!< Offset: ITM Peripheral Identification Register #0 */ - __I uint32_t PID1; /*!< Offset: ITM Peripheral Identification Register #1 */ - __I uint32_t PID2; /*!< Offset: ITM Peripheral Identification Register #2 */ - __I uint32_t PID3; /*!< Offset: ITM Peripheral Identification Register #3 */ - __I uint32_t CID0; /*!< Offset: ITM Component Identification Register #0 */ - __I uint32_t CID1; /*!< Offset: ITM Component Identification Register #1 */ - __I uint32_t CID2; /*!< Offset: ITM Component Identification Register #2 */ - __I uint32_t CID3; /*!< Offset: ITM Component Identification Register #3 */ -} ITM_Type; - -/* ITM Trace Privilege Register Definitions */ -#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFul << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ - -/* ITM Trace Control Register Definitions */ -#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ -#define ITM_TCR_BUSY_Msk (1ul << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ - -#define ITM_TCR_ATBID_Pos 16 /*!< ITM TCR: ATBID Position */ -#define ITM_TCR_ATBID_Msk (0x7Ful << ITM_TCR_ATBID_Pos) /*!< ITM TCR: ATBID Mask */ - -#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ -#define ITM_TCR_TSPrescale_Msk (3ul << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ - -#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ -#define ITM_TCR_SWOENA_Msk (1ul << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ - -#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ -#define ITM_TCR_DWTENA_Msk (1ul << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ - -#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ -#define ITM_TCR_SYNCENA_Msk (1ul << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ - -#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ -#define ITM_TCR_TSENA_Msk (1ul << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ - -#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ -#define ITM_TCR_ITMENA_Msk (1ul << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ - -/* ITM Integration Write Register Definitions */ -#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ -#define ITM_IWR_ATVALIDM_Msk (1ul << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ - -/* ITM Integration Read Register Definitions */ -#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ -#define ITM_IRR_ATREADYM_Msk (1ul << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ - -/* ITM Integration Mode Control Register Definitions */ -#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ -#define ITM_IMCR_INTEGRATION_Msk (1ul << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ - -/* ITM Lock Status Register Definitions */ -#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ -#define ITM_LSR_ByteAcc_Msk (1ul << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ - -#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ -#define ITM_LSR_Access_Msk (1ul << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ - -#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ -#define ITM_LSR_Present_Msk (1ul << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ -/*@}*/ /* end of group CMSIS_CM3_ITM */ - - -/** @addtogroup CMSIS_CM3_InterruptType CMSIS CM3 Interrupt Type - memory mapped structure for Interrupt Type - @{ - */ -typedef struct -{ - uint32_t RESERVED0; - __I uint32_t ICTR; /*!< Offset: 0x04 Interrupt Control Type Register */ -#if ((defined __CM3_REV) && (__CM3_REV >= 0x200)) - __IO uint32_t ACTLR; /*!< Offset: 0x08 Auxiliary Control Register */ -#else - uint32_t RESERVED1; -#endif -} InterruptType_Type; - -/* Interrupt Controller Type Register Definitions */ -#define InterruptType_ICTR_INTLINESNUM_Pos 0 /*!< InterruptType ICTR: INTLINESNUM Position */ -#define InterruptType_ICTR_INTLINESNUM_Msk (0x1Ful << InterruptType_ICTR_INTLINESNUM_Pos) /*!< InterruptType ICTR: INTLINESNUM Mask */ - -/* Auxiliary Control Register Definitions */ -#define InterruptType_ACTLR_DISFOLD_Pos 2 /*!< InterruptType ACTLR: DISFOLD Position */ -#define InterruptType_ACTLR_DISFOLD_Msk (1ul << InterruptType_ACTLR_DISFOLD_Pos) /*!< InterruptType ACTLR: DISFOLD Mask */ - -#define InterruptType_ACTLR_DISDEFWBUF_Pos 1 /*!< InterruptType ACTLR: DISDEFWBUF Position */ -#define InterruptType_ACTLR_DISDEFWBUF_Msk (1ul << InterruptType_ACTLR_DISDEFWBUF_Pos) /*!< InterruptType ACTLR: DISDEFWBUF Mask */ - -#define InterruptType_ACTLR_DISMCYCINT_Pos 0 /*!< InterruptType ACTLR: DISMCYCINT Position */ -#define InterruptType_ACTLR_DISMCYCINT_Msk (1ul << InterruptType_ACTLR_DISMCYCINT_Pos) /*!< InterruptType ACTLR: DISMCYCINT Mask */ -/*@}*/ /* end of group CMSIS_CM3_InterruptType */ - - -#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1) -/** @addtogroup CMSIS_CM3_MPU CMSIS CM3 MPU - memory mapped structure for Memory Protection Unit (MPU) - @{ - */ -typedef struct -{ - __I uint32_t TYPE; /*!< Offset: 0x00 MPU Type Register */ - __IO uint32_t CTRL; /*!< Offset: 0x04 MPU Control Register */ - __IO uint32_t RNR; /*!< Offset: 0x08 MPU Region RNRber Register */ - __IO uint32_t RBAR; /*!< Offset: 0x0C MPU Region Base Address Register */ - __IO uint32_t RASR; /*!< Offset: 0x10 MPU Region Attribute and Size Register */ - __IO uint32_t RBAR_A1; /*!< Offset: 0x14 MPU Alias 1 Region Base Address Register */ - __IO uint32_t RASR_A1; /*!< Offset: 0x18 MPU Alias 1 Region Attribute and Size Register */ - __IO uint32_t RBAR_A2; /*!< Offset: 0x1C MPU Alias 2 Region Base Address Register */ - __IO uint32_t RASR_A2; /*!< Offset: 0x20 MPU Alias 2 Region Attribute and Size Register */ - __IO uint32_t RBAR_A3; /*!< Offset: 0x24 MPU Alias 3 Region Base Address Register */ - __IO uint32_t RASR_A3; /*!< Offset: 0x28 MPU Alias 3 Region Attribute and Size Register */ -} MPU_Type; - -/* MPU Type Register */ -#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFul << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ - -#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFul << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ - -#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1ul << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ - -/* MPU Control Register */ -#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1ul << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ - -#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1ul << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ - -#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1ul << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ - -/* MPU Region Number Register */ -#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFul << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ - -/* MPU Region Base Address Register */ -#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFul << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ - -#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1ul << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ - -#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFul << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ - -/* MPU Region Attribute and Size Register */ -#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: XN Position */ -#define MPU_RASR_XN_Msk (1ul << MPU_RASR_XN_Pos) /*!< MPU RASR: XN Mask */ - -#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: AP Position */ -#define MPU_RASR_AP_Msk (7ul << MPU_RASR_AP_Pos) /*!< MPU RASR: AP Mask */ - -#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: TEX Position */ -#define MPU_RASR_TEX_Msk (7ul << MPU_RASR_TEX_Pos) /*!< MPU RASR: TEX Mask */ - -#define MPU_RASR_S_Pos 18 /*!< MPU RASR: Shareable bit Position */ -#define MPU_RASR_S_Msk (1ul << MPU_RASR_S_Pos) /*!< MPU RASR: Shareable bit Mask */ - -#define MPU_RASR_C_Pos 17 /*!< MPU RASR: Cacheable bit Position */ -#define MPU_RASR_C_Msk (1ul << MPU_RASR_C_Pos) /*!< MPU RASR: Cacheable bit Mask */ - -#define MPU_RASR_B_Pos 16 /*!< MPU RASR: Bufferable bit Position */ -#define MPU_RASR_B_Msk (1ul << MPU_RASR_B_Pos) /*!< MPU RASR: Bufferable bit Mask */ - -#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ -#define MPU_RASR_SRD_Msk (0xFFul << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ - -#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ -#define MPU_RASR_SIZE_Msk (0x1Ful << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ - -#define MPU_RASR_ENA_Pos 0 /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENA_Msk (0x1Ful << MPU_RASR_ENA_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@}*/ /* end of group CMSIS_CM3_MPU */ -#endif - - -/** @addtogroup CMSIS_CM3_CoreDebug CMSIS CM3 Core Debug - memory mapped structure for Core Debug Register - @{ - */ -typedef struct -{ - __IO uint32_t DHCSR; /*!< Offset: 0x00 Debug Halting Control and Status Register */ - __O uint32_t DCRSR; /*!< Offset: 0x04 Debug Core Register Selector Register */ - __IO uint32_t DCRDR; /*!< Offset: 0x08 Debug Core Register Data Register */ - __IO uint32_t DEMCR; /*!< Offset: 0x0C Debug Exception and Monitor Control Register */ -} CoreDebug_Type; - -/* Debug Halting Control and Status Register */ -#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ -#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFul << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ - -#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ -#define CoreDebug_DHCSR_S_RESET_ST_Msk (1ul << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ - -#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ -#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1ul << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ - -#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ -#define CoreDebug_DHCSR_S_LOCKUP_Msk (1ul << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ - -#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ -#define CoreDebug_DHCSR_S_SLEEP_Msk (1ul << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ - -#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ -#define CoreDebug_DHCSR_S_HALT_Msk (1ul << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ - -#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ -#define CoreDebug_DHCSR_S_REGRDY_Msk (1ul << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ - -#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ -#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1ul << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ - -#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ -#define CoreDebug_DHCSR_C_MASKINTS_Msk (1ul << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ - -#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ -#define CoreDebug_DHCSR_C_STEP_Msk (1ul << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ - -#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ -#define CoreDebug_DHCSR_C_HALT_Msk (1ul << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ - -#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ -#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1ul << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ - -/* Debug Core Register Selector Register */ -#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ -#define CoreDebug_DCRSR_REGWnR_Msk (1ul << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ - -#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ -#define CoreDebug_DCRSR_REGSEL_Msk (0x1Ful << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ - -/* Debug Exception and Monitor Control Register */ -#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ -#define CoreDebug_DEMCR_TRCENA_Msk (1ul << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ - -#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ -#define CoreDebug_DEMCR_MON_REQ_Msk (1ul << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ - -#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ -#define CoreDebug_DEMCR_MON_STEP_Msk (1ul << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ - -#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ -#define CoreDebug_DEMCR_MON_PEND_Msk (1ul << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ - -#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ -#define CoreDebug_DEMCR_MON_EN_Msk (1ul << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ - -#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ -#define CoreDebug_DEMCR_VC_HARDERR_Msk (1ul << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ - -#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ -#define CoreDebug_DEMCR_VC_INTERR_Msk (1ul << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ - -#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ -#define CoreDebug_DEMCR_VC_BUSERR_Msk (1ul << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ - -#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ -#define CoreDebug_DEMCR_VC_STATERR_Msk (1ul << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ - -#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ -#define CoreDebug_DEMCR_VC_CHKERR_Msk (1ul << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ - -#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ -#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1ul << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ - -#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ -#define CoreDebug_DEMCR_VC_MMERR_Msk (1ul << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ - -#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ -#define CoreDebug_DEMCR_VC_CORERESET_Msk (1ul << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ -/*@}*/ /* end of group CMSIS_CM3_CoreDebug */ - - -/* Memory mapping of Cortex-M3 Hardware */ -#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */ -#define ITM_BASE (0xE0000000) /*!< ITM Base Address */ -#define CoreDebug_BASE (0xE000EDF0) /*!< Core Debug Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */ - -#define InterruptType ((InterruptType_Type *) SCS_BASE) /*!< Interrupt Type Register */ -#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE) /*!< NVIC configuration struct */ -#define ITM ((ITM_Type *) ITM_BASE) /*!< ITM configuration struct */ -#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ - -#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1) - #define MPU_BASE (SCS_BASE + 0x0D90) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type*) MPU_BASE) /*!< Memory Protection Unit */ -#endif - -/*@}*/ /* end of group CMSIS_CM3_core_register */ - - -/******************************************************************************* - * Hardware Abstraction Layer - ******************************************************************************/ - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */ - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - -#endif - - -/* ################### Compiler specific Intrinsics ########################### */ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -#define __enable_fault_irq __enable_fiq -#define __disable_fault_irq __disable_fiq - -#define __NOP __nop -#define __WFI __wfi -#define __WFE __wfe -#define __SEV __sev -#define __ISB() __isb(0) -#define __DSB() __dsb(0) -#define __DMB() __dmb(0) -#define __REV __rev -#define __RBIT __rbit -#define __LDREXB(ptr) ((unsigned char ) __ldrex(ptr)) -#define __LDREXH(ptr) ((unsigned short) __ldrex(ptr)) -#define __LDREXW(ptr) ((unsigned int ) __ldrex(ptr)) -#define __STREXB(value, ptr) __strex(value, ptr) -#define __STREXH(value, ptr) __strex(value, ptr) -#define __STREXW(value, ptr) __strex(value, ptr) - - -/* intrinsic unsigned long long __ldrexd(volatile void *ptr) */ -/* intrinsic int __strexd(unsigned long long val, volatile void *ptr) */ -/* intrinsic void __enable_irq(); */ -/* intrinsic void __disable_irq(); */ - - -/** - * @brief Return the Process Stack Pointer - * - * @return ProcessStackPointer - * - * Return the actual process stack pointer - */ -extern uint32_t __get_PSP(void); - -/** - * @brief Set the Process Stack Pointer - * - * @param topOfProcStack Process Stack Pointer - * - * Assign the value ProcessStackPointer to the MSP - * (process stack pointer) Cortex processor register - */ -extern void __set_PSP(uint32_t topOfProcStack); - -/** - * @brief Return the Main Stack Pointer - * - * @return Main Stack Pointer - * - * Return the current value of the MSP (main stack pointer) - * Cortex processor register - */ -extern uint32_t __get_MSP(void); - -/** - * @brief Set the Main Stack Pointer - * - * @param topOfMainStack Main Stack Pointer - * - * Assign the value mainStackPointer to the MSP - * (main stack pointer) Cortex processor register - */ -extern void __set_MSP(uint32_t topOfMainStack); - -/** - * @brief Reverse byte order in unsigned short value - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in unsigned short value - */ -extern uint32_t __REV16(uint16_t value); - -/** - * @brief Reverse byte order in signed short value with sign extension to integer - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in signed short value with sign extension to integer - */ -extern int32_t __REVSH(int16_t value); - - -#if (__ARMCC_VERSION < 400000) - -/** - * @brief Remove the exclusive lock created by ldrex - * - * Removes the exclusive lock which is created by ldrex. - */ -extern void __CLREX(void); - -/** - * @brief Return the Base Priority value - * - * @return BasePriority - * - * Return the content of the base priority register - */ -extern uint32_t __get_BASEPRI(void); - -/** - * @brief Set the Base Priority value - * - * @param basePri BasePriority - * - * Set the base priority register - */ -extern void __set_BASEPRI(uint32_t basePri); - -/** - * @brief Return the Priority Mask value - * - * @return PriMask - * - * Return state of the priority mask bit from the priority mask register - */ -extern uint32_t __get_PRIMASK(void); - -/** - * @brief Set the Priority Mask value - * - * @param priMask PriMask - * - * Set the priority mask bit in the priority mask register - */ -extern void __set_PRIMASK(uint32_t priMask); - -/** - * @brief Return the Fault Mask value - * - * @return FaultMask - * - * Return the content of the fault mask register - */ -extern uint32_t __get_FAULTMASK(void); - -/** - * @brief Set the Fault Mask value - * - * @param faultMask faultMask value - * - * Set the fault mask register - */ -extern void __set_FAULTMASK(uint32_t faultMask); - -/** - * @brief Return the Control Register value - * - * @return Control value - * - * Return the content of the control register - */ -extern uint32_t __get_CONTROL(void); - -/** - * @brief Set the Control Register value - * - * @param control Control value - * - * Set the control register - */ -extern void __set_CONTROL(uint32_t control); - -#else /* (__ARMCC_VERSION >= 400000) */ - -/** - * @brief Remove the exclusive lock created by ldrex - * - * Removes the exclusive lock which is created by ldrex. - */ -#define __CLREX __clrex - -/** - * @brief Return the Base Priority value - * - * @return BasePriority - * - * Return the content of the base priority register - */ -static __INLINE uint32_t __get_BASEPRI(void) -{ - register uint32_t __regBasePri __ASM("basepri"); - return(__regBasePri); -} - -/** - * @brief Set the Base Priority value - * - * @param basePri BasePriority - * - * Set the base priority register - */ -static __INLINE void __set_BASEPRI(uint32_t basePri) -{ - register uint32_t __regBasePri __ASM("basepri"); - __regBasePri = (basePri & 0xff); -} - -/** - * @brief Return the Priority Mask value - * - * @return PriMask - * - * Return state of the priority mask bit from the priority mask register - */ -static __INLINE uint32_t __get_PRIMASK(void) -{ - register uint32_t __regPriMask __ASM("primask"); - return(__regPriMask); -} - -/** - * @brief Set the Priority Mask value - * - * @param priMask PriMask - * - * Set the priority mask bit in the priority mask register - */ -static __INLINE void __set_PRIMASK(uint32_t priMask) -{ - register uint32_t __regPriMask __ASM("primask"); - __regPriMask = (priMask); -} - -/** - * @brief Return the Fault Mask value - * - * @return FaultMask - * - * Return the content of the fault mask register - */ -static __INLINE uint32_t __get_FAULTMASK(void) -{ - register uint32_t __regFaultMask __ASM("faultmask"); - return(__regFaultMask); -} - -/** - * @brief Set the Fault Mask value - * - * @param faultMask faultMask value - * - * Set the fault mask register - */ -static __INLINE void __set_FAULTMASK(uint32_t faultMask) -{ - register uint32_t __regFaultMask __ASM("faultmask"); - __regFaultMask = (faultMask & 1); -} - -/** - * @brief Return the Control Register value - * - * @return Control value - * - * Return the content of the control register - */ -static __INLINE uint32_t __get_CONTROL(void) -{ - register uint32_t __regControl __ASM("control"); - return(__regControl); -} - -/** - * @brief Set the Control Register value - * - * @param control Control value - * - * Set the control register - */ -static __INLINE void __set_CONTROL(uint32_t control) -{ - register uint32_t __regControl __ASM("control"); - __regControl = control; -} - -#endif /* __ARMCC_VERSION */ - - - -#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ - -#define __enable_irq __enable_interrupt /*!< global Interrupt enable */ -#define __disable_irq __disable_interrupt /*!< global Interrupt disable */ - -static __INLINE void __enable_fault_irq() { __ASM ("cpsie f"); } -static __INLINE void __disable_fault_irq() { __ASM ("cpsid f"); } - -#define __NOP __no_operation /*!< no operation intrinsic in IAR Compiler */ -static __INLINE void __WFI() { __ASM ("wfi"); } -static __INLINE void __WFE() { __ASM ("wfe"); } -static __INLINE void __SEV() { __ASM ("sev"); } -static __INLINE void __CLREX() { __ASM ("clrex"); } - -/* intrinsic void __ISB(void) */ -/* intrinsic void __DSB(void) */ -/* intrinsic void __DMB(void) */ -/* intrinsic void __set_PRIMASK(); */ -/* intrinsic void __get_PRIMASK(); */ -/* intrinsic void __set_FAULTMASK(); */ -/* intrinsic void __get_FAULTMASK(); */ -/* intrinsic uint32_t __REV(uint32_t value); */ -/* intrinsic uint32_t __REVSH(uint32_t value); */ -/* intrinsic unsigned long __STREX(unsigned long, unsigned long); */ -/* intrinsic unsigned long __LDREX(unsigned long *); */ - - -/** - * @brief Return the Process Stack Pointer - * - * @return ProcessStackPointer - * - * Return the actual process stack pointer - */ -extern uint32_t __get_PSP(void); - -/** - * @brief Set the Process Stack Pointer - * - * @param topOfProcStack Process Stack Pointer - * - * Assign the value ProcessStackPointer to the MSP - * (process stack pointer) Cortex processor register - */ -extern void __set_PSP(uint32_t topOfProcStack); - -/** - * @brief Return the Main Stack Pointer - * - * @return Main Stack Pointer - * - * Return the current value of the MSP (main stack pointer) - * Cortex processor register - */ -extern uint32_t __get_MSP(void); - -/** - * @brief Set the Main Stack Pointer - * - * @param topOfMainStack Main Stack Pointer - * - * Assign the value mainStackPointer to the MSP - * (main stack pointer) Cortex processor register - */ -extern void __set_MSP(uint32_t topOfMainStack); - -/** - * @brief Reverse byte order in unsigned short value - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in unsigned short value - */ -extern uint32_t __REV16(uint16_t value); - -/** - * @brief Reverse bit order of value - * - * @param value value to reverse - * @return reversed value - * - * Reverse bit order of value - */ -extern uint32_t __RBIT(uint32_t value); - -/** - * @brief LDR Exclusive (8 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 8 bit values) - */ -extern uint8_t __LDREXB(uint8_t *addr); - -/** - * @brief LDR Exclusive (16 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 16 bit values - */ -extern uint16_t __LDREXH(uint16_t *addr); - -/** - * @brief LDR Exclusive (32 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 32 bit values - */ -extern uint32_t __LDREXW(uint32_t *addr); - -/** - * @brief STR Exclusive (8 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 8 bit values - */ -extern uint32_t __STREXB(uint8_t value, uint8_t *addr); - -/** - * @brief STR Exclusive (16 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 16 bit values - */ -extern uint32_t __STREXH(uint16_t value, uint16_t *addr); - -/** - * @brief STR Exclusive (32 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 32 bit values - */ -extern uint32_t __STREXW(uint32_t value, uint32_t *addr); - - - -#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -static __INLINE void __enable_irq() { __ASM volatile ("cpsie i"); } -static __INLINE void __disable_irq() { __ASM volatile ("cpsid i"); } - -static __INLINE void __enable_fault_irq() { __ASM volatile ("cpsie f"); } -static __INLINE void __disable_fault_irq() { __ASM volatile ("cpsid f"); } - -static __INLINE void __NOP() { __ASM volatile ("nop"); } -static __INLINE void __WFI() { __ASM volatile ("wfi"); } -static __INLINE void __WFE() { __ASM volatile ("wfe"); } -static __INLINE void __SEV() { __ASM volatile ("sev"); } -static __INLINE void __ISB() { __ASM volatile ("isb"); } -static __INLINE void __DSB() { __ASM volatile ("dsb"); } -static __INLINE void __DMB() { __ASM volatile ("dmb"); } -static __INLINE void __CLREX() { __ASM volatile ("clrex"); } - - -/** - * @brief Return the Process Stack Pointer - * - * @return ProcessStackPointer - * - * Return the actual process stack pointer - */ -extern uint32_t __get_PSP(void); - -/** - * @brief Set the Process Stack Pointer - * - * @param topOfProcStack Process Stack Pointer - * - * Assign the value ProcessStackPointer to the MSP - * (process stack pointer) Cortex processor register - */ -extern void __set_PSP(uint32_t topOfProcStack); - -/** - * @brief Return the Main Stack Pointer - * - * @return Main Stack Pointer - * - * Return the current value of the MSP (main stack pointer) - * Cortex processor register - */ -extern uint32_t __get_MSP(void); - -/** - * @brief Set the Main Stack Pointer - * - * @param topOfMainStack Main Stack Pointer - * - * Assign the value mainStackPointer to the MSP - * (main stack pointer) Cortex processor register - */ -extern void __set_MSP(uint32_t topOfMainStack); - -/** - * @brief Return the Base Priority value - * - * @return BasePriority - * - * Return the content of the base priority register - */ -extern uint32_t __get_BASEPRI(void); - -/** - * @brief Set the Base Priority value - * - * @param basePri BasePriority - * - * Set the base priority register - */ -extern void __set_BASEPRI(uint32_t basePri); - -/** - * @brief Return the Priority Mask value - * - * @return PriMask - * - * Return state of the priority mask bit from the priority mask register - */ -extern uint32_t __get_PRIMASK(void); - -/** - * @brief Set the Priority Mask value - * - * @param priMask PriMask - * - * Set the priority mask bit in the priority mask register - */ -extern void __set_PRIMASK(uint32_t priMask); - -/** - * @brief Return the Fault Mask value - * - * @return FaultMask - * - * Return the content of the fault mask register - */ -extern uint32_t __get_FAULTMASK(void); - -/** - * @brief Set the Fault Mask value - * - * @param faultMask faultMask value - * - * Set the fault mask register - */ -extern void __set_FAULTMASK(uint32_t faultMask); - -/** - * @brief Return the Control Register value -* -* @return Control value - * - * Return the content of the control register - */ -extern uint32_t __get_CONTROL(void); - -/** - * @brief Set the Control Register value - * - * @param control Control value - * - * Set the control register - */ -extern void __set_CONTROL(uint32_t control); - -/** - * @brief Reverse byte order in integer value - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in integer value - */ -extern uint32_t __REV(uint32_t value); - -/** - * @brief Reverse byte order in unsigned short value - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in unsigned short value - */ -extern uint32_t __REV16(uint16_t value); - -/** - * @brief Reverse byte order in signed short value with sign extension to integer - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in signed short value with sign extension to integer - */ -extern int32_t __REVSH(int16_t value); - -/** - * @brief Reverse bit order of value - * - * @param value value to reverse - * @return reversed value - * - * Reverse bit order of value - */ -extern uint32_t __RBIT(uint32_t value); - -/** - * @brief LDR Exclusive (8 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 8 bit value - */ -extern uint8_t __LDREXB(uint8_t *addr); - -/** - * @brief LDR Exclusive (16 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 16 bit values - */ -extern uint16_t __LDREXH(uint16_t *addr); - -/** - * @brief LDR Exclusive (32 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 32 bit values - */ -extern uint32_t __LDREXW(uint32_t *addr); - -/** - * @brief STR Exclusive (8 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 8 bit values - */ -extern uint32_t __STREXB(uint8_t value, uint8_t *addr); - -/** - * @brief STR Exclusive (16 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 16 bit values - */ -extern uint32_t __STREXH(uint16_t value, uint16_t *addr); - -/** - * @brief STR Exclusive (32 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 32 bit values - */ -extern uint32_t __STREXW(uint32_t value, uint32_t *addr); - - -#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/ -/* TASKING carm specific functions */ - -/* - * The CMSIS functions have been implemented as intrinsics in the compiler. - * Please use "carm -?i" to get an up to date list of all instrinsics, - * Including the CMSIS ones. - */ - -#endif - - -/** @addtogroup CMSIS_CM3_Core_FunctionInterface CMSIS CM3 Core Function Interface - Core Function Interface containing: - - Core NVIC Functions - - Core SysTick Functions - - Core Reset Functions -*/ -/*@{*/ - -/* ########################## NVIC functions #################################### */ - -/** - * @brief Set the Priority Grouping in NVIC Interrupt Controller - * - * @param PriorityGroup is priority grouping field - * - * Set the priority grouping field using the required unlock sequence. - * The parameter priority_grouping is assigned to the field - * SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used. - * In case of a conflict between priority grouping and available - * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. - */ -static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) -{ - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ - - reg_value = SCB->AIRCR; /* read old register configuration */ - reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ - reg_value = (reg_value | - (0x5FA << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ - SCB->AIRCR = reg_value; -} - -/** - * @brief Get the Priority Grouping from NVIC Interrupt Controller - * - * @return priority grouping field - * - * Get the priority grouping from NVIC Interrupt Controller. - * priority grouping is SCB->AIRCR [10:8] PRIGROUP field. - */ -static __INLINE uint32_t NVIC_GetPriorityGrouping(void) -{ - return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ -} - -/** - * @brief Enable Interrupt in NVIC Interrupt Controller - * - * @param IRQn The positive number of the external interrupt to enable - * - * Enable a device specific interupt in the NVIC interrupt controller. - * The interrupt number cannot be a negative value. - */ -static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ -} - -/** - * @brief Disable the interrupt line for external interrupt specified - * - * @param IRQn The positive number of the external interrupt to disable - * - * Disable a device specific interupt in the NVIC interrupt controller. - * The interrupt number cannot be a negative value. - */ -static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ -} - -/** - * @brief Read the interrupt pending bit for a device specific interrupt source - * - * @param IRQn The number of the device specifc interrupt - * @return 1 = interrupt pending, 0 = interrupt not pending - * - * Read the pending register in NVIC and return 1 if its status is pending, - * otherwise it returns 0 - */ -static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ -} - -/** - * @brief Set the pending bit for an external interrupt - * - * @param IRQn The number of the interrupt for set pending - * - * Set the pending bit for the specified interrupt. - * The interrupt number cannot be a negative value. - */ -static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ -} - -/** - * @brief Clear the pending bit for an external interrupt - * - * @param IRQn The number of the interrupt for clear pending - * - * Clear the pending bit for the specified interrupt. - * The interrupt number cannot be a negative value. - */ -static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ -} - -/** - * @brief Read the active bit for an external interrupt - * - * @param IRQn The number of the interrupt for read active bit - * @return 1 = interrupt active, 0 = interrupt not active - * - * Read the active register in NVIC and returns 1 if its status is active, - * otherwise it returns 0. - */ -static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ -} - -/** - * @brief Set the priority for an interrupt - * - * @param IRQn The number of the interrupt for set priority - * @param priority The priority to set - * - * Set the priority for the specified interrupt. The interrupt - * number can be positive to specify an external (device specific) - * interrupt, or negative to specify an internal (core) interrupt. - * - * Note: The priority cannot be set for every core interrupt. - */ -static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if(IRQn < 0) { - SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */ - else { - NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ -} - -/** - * @brief Read the priority for an interrupt - * - * @param IRQn The number of the interrupt for get priority - * @return The priority for the interrupt - * - * Read the priority for the specified interrupt. The interrupt - * number can be positive to specify an external (device specific) - * interrupt, or negative to specify an internal (core) interrupt. - * - * The returned priority value is automatically aligned to the implemented - * priority bits of the microcontroller. - * - * Note: The priority cannot be set for every core interrupt. - */ -static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) -{ - - if(IRQn < 0) { - return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M3 system interrupts */ - else { - return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ -} - - -/** - * @brief Encode the priority for an interrupt - * - * @param PriorityGroup The used priority group - * @param PreemptPriority The preemptive priority value (starting from 0) - * @param SubPriority The sub priority value (starting from 0) - * @return The encoded priority for the interrupt - * - * Encode the priority for an interrupt with the given priority group, - * preemptive priority value and sub priority value. - * In case of a conflict between priority grouping and available - * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. - * - * The returned priority value can be used for NVIC_SetPriority(...) function - */ -static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; - SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; - - return ( - ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | - ((SubPriority & ((1 << (SubPriorityBits )) - 1))) - ); -} - - -/** - * @brief Decode the priority of an interrupt - * - * @param Priority The priority for the interrupt - * @param PriorityGroup The used priority group - * @param pPreemptPriority The preemptive priority value (starting from 0) - * @param pSubPriority The sub priority value (starting from 0) - * - * Decode an interrupt priority value with the given priority group to - * preemptive priority value and sub priority value. - * In case of a conflict between priority grouping and available - * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. - * - * The priority value can be retrieved with NVIC_GetPriority(...) function - */ -static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; - SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; - - *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); - *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); -} - - - -/* ################################## SysTick function ############################################ */ - -#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0) - -/** - * @brief Initialize and start the SysTick counter and its interrupt. - * - * @param ticks number of ticks between two interrupts - * @return 1 = failed, 0 = successful - * - * Initialise the system tick timer and its interrupt and start the - * system tick timer / counter in free running mode to generate - * periodical interrupts. - */ -static __INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ - - SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ - SysTick->VAL = 0; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0); /* Function successful */ -} - -#endif - - - - -/* ################################## Reset function ############################################ */ - -/** - * @brief Initiate a system reset request. - * - * Initiate a system reset request to reset the MCU - */ -static __INLINE void NVIC_SystemReset(void) -{ - SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | - (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | - SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ - __DSB(); /* Ensure completion of memory access */ - while(1); /* wait until reset */ -} - -/*@}*/ /* end of group CMSIS_CM3_Core_FunctionInterface */ - - - -/* ##################################### Debug In/Output function ########################################### */ - -/** @addtogroup CMSIS_CM3_CoreDebugInterface CMSIS CM3 Core Debug Interface - Core Debug Interface containing: - - Core Debug Receive / Transmit Functions - - Core Debug Defines - - Core Debug Variables -*/ -/*@{*/ - -extern volatile int ITM_RxBuffer; /*!< variable to receive characters */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */ - - -/** - * @brief Outputs a character via the ITM channel 0 - * - * @param ch character to output - * @return character to output - * - * The function outputs a character via the ITM channel 0. - * The function returns when no debugger is connected that has booked the output. - * It is blocking when a debugger is connected, but the previous character send is not transmitted. - */ -static __INLINE uint32_t ITM_SendChar (uint32_t ch) -{ - if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled */ - (ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ - (ITM->TER & (1ul << 0) ) ) /* ITM Port #0 enabled */ - { - while (ITM->PORT[0].u32 == 0); - ITM->PORT[0].u8 = (uint8_t) ch; - } - return (ch); -} - - -/** - * @brief Inputs a character via variable ITM_RxBuffer - * - * @return received character, -1 = no character received - * - * The function inputs a character via variable ITM_RxBuffer. - * The function returns when no debugger is connected that has booked the output. - * It is blocking when a debugger is connected, but the previous character send is not transmitted. - */ -static __INLINE int ITM_ReceiveChar (void) { - int ch = -1; /* no character available */ - - if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { - ch = ITM_RxBuffer; - ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ - } - - return (ch); -} - - -/** - * @brief Check if a character via variable ITM_RxBuffer is available - * - * @return 1 = character available, 0 = no character available - * - * The function checks variable ITM_RxBuffer whether a character is available or not. - * The function returns '1' if a character is available and '0' if no character is available. - */ -static __INLINE int ITM_CheckChar (void) { - - if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { - return (0); /* no character available */ - } else { - return (1); /* character available */ - } -} - -/*@}*/ /* end of group CMSIS_CM3_core_DebugInterface */ - - -#ifdef __cplusplus -} -#endif - -/*@}*/ /* end of group CMSIS_CM3_core_definitions */ - -#endif /* __CM3_CORE_H__ */ - -/*lint -restore */ diff --git a/example/libs_stm/inc/device_support/stm32f10x.h b/example/libs_stm/inc/device_support/stm32f10x.h deleted file mode 100644 index 9d124002e..000000000 --- a/example/libs_stm/inc/device_support/stm32f10x.h +++ /dev/null @@ -1,8227 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File. - * This file contains all the peripheral register's definitions, bits - * definitions and memory mapping for STM32F10x Connectivity line, High - * density, Medium density, Medium density Value line, Low density - * and Low density Value line and XL-density devices. - ****************************************************************************** - * - * 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 stm32f10x - * @{ - */ - -#ifndef __STM32F10x_H -#define __STM32F10x_H - -#ifdef __cplusplus - extern "C" { -#endif - -#define assert_param(__p) - - -/** @addtogroup Library_configuration_section - * @{ - */ - -/* Uncomment the line below according to the target STM32 device used in your - application - */ - -#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL) - /* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */ - /* #define STM32F10X_LD_VL */ /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */ - /* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */ - /* #define STM32F10X_MD_VL */ /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */ - /* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */ - #define STM32F10X_XL /*!< STM32F10X_XL: STM32 XL-density devices */ - /* #define STM32F10X_CL */ /*!< STM32F10X_CL: STM32 Connectivity line devices */ -#endif -/* Tip: To avoid modifying this file each time you need to switch between these - devices, you can define the device in your toolchain compiler preprocessor. - - - Low density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers - where the Flash memory density ranges between 16 and 32 Kbytes. - - Low-density value line devices are STM32F100xx microcontrollers where the Flash - memory density ranges between 16 and 32 Kbytes. - - Medium density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers - where the Flash memory density ranges between 64 and 128 Kbytes. - - Medium-density value line devices are STM32F100xx microcontrollers where the - Flash memory density ranges between 64 and 128 Kbytes. - - High density devices are STM32F101xx and STM32F103xx microcontrollers where - the Flash memory density ranges between 256 and 512 Kbytes. - - XL-density devices are STM32F101xx and STM32F103xx microcontrollers where - the Flash memory density ranges between 512 and 1024 Kbytes. - - Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers. - */ - -#if !defined USE_STDPERIPH_DRIVER -/** - * @brief Comment the line below if you will not use the peripherals drivers. - In this case, these drivers will not be included and the application code will - be based on direct access to peripherals registers - */ - /*#define USE_STDPERIPH_DRIVER*/ -#endif - -/** - * @brief In the following line adjust the value of External High Speed oscillator (HSE) - used in your application - - Tip: To avoid modifying this file each time you need to use different HSE, you - can define the HSE value in your toolchain compiler preprocessor. - */ -#if !defined HSE_VALUE - #ifdef STM32F10X_CL - #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ - #else - #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ - #endif /* STM32F10X_CL */ -#endif /* HSE_VALUE */ - - -/** - * @brief In the following line adjust the External High Speed oscillator (HSE) Startup - Timeout value - */ -#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */ - -#define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/ - -/** - * @brief STM32F10x Standard Peripheral Library version number - */ -#define __STM32F10X_STDPERIPH_VERSION_MAIN (0x03) /*!< [31:16] STM32F10x Standard Peripheral Library main version */ -#define __STM32F10X_STDPERIPH_VERSION_SUB1 (0x03) /*!< [15:8] STM32F10x Standard Peripheral Library sub1 version */ -#define __STM32F10X_STDPERIPH_VERSION_SUB2 (0x00) /*!< [7:0] STM32F10x Standard Peripheral Library sub2 version */ -#define __STM32F10X_STDPERIPH_VERSION ((__STM32F10X_STDPERIPH_VERSION_MAIN << 16)\ - | (__STM32F10X_STDPERIPH_VERSION_SUB1 << 8)\ - | __STM32F10X_STDPERIPH_VERSION_SUB2) - -/** - * @} - */ - -/** @addtogroup Configuration_section_for_CMSIS - * @{ - */ - -/** - * @brief Configuration of the Cortex-M3 Processor and Core Peripherals - */ -#ifdef STM32F10X_XL - #define __MPU_PRESENT 1 /*!< STM32 XL-density devices provide an MPU */ -#else - #define __MPU_PRESENT 0 /*!< Other STM32 devices does not provide an MPU */ -#endif /* STM32F10X_XL */ -#define __NVIC_PRIO_BITS 4 /*!< STM32 uses 4 Bits for the Priority Levels */ -#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ - -/** - * @brief STM32F10x Interrupt Number Definition, according to the selected device - * in @ref Library_configuration_section - */ -typedef enum IRQn -{ -/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/ - NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ - MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */ - BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */ - UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */ - SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */ - DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */ - PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */ - SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */ - -/****** STM32 specific Interrupt Numbers *********************************************************/ - WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ - PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ - TAMPER_IRQn = 2, /*!< Tamper Interrupt */ - RTC_IRQn = 3, /*!< RTC global Interrupt */ - FLASH_IRQn = 4, /*!< FLASH global Interrupt */ - RCC_IRQn = 5, /*!< RCC global Interrupt */ - EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ - EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ - EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ - EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ - EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ - DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */ - DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */ - DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */ - DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */ - DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */ - DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */ - DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */ - -#ifdef STM32F10X_LD - ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */ - USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ - USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ - CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ - CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ - EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ - TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ - TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ - TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ - TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ - TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ - TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ - I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ - I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ - SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ - USART1_IRQn = 37, /*!< USART1 global Interrupt */ - USART2_IRQn = 38, /*!< USART2 global Interrupt */ - EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ -#endif /* STM32F10X_LD */ - -#ifdef STM32F10X_LD_VL - ADC1_IRQn = 18, /*!< ADC1 global Interrupt */ - EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ - TIM1_BRK_TIM15_IRQn = 24, /*!< TIM1 Break and TIM15 Interrupts */ - TIM1_UP_TIM16_IRQn = 25, /*!< TIM1 Update and TIM16 Interrupts */ - TIM1_TRG_COM_TIM17_IRQn = 26, /*!< TIM1 Trigger and Commutation and TIM17 Interrupt */ - TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ - TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ - TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ - I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ - I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ - SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ - USART1_IRQn = 37, /*!< USART1 global Interrupt */ - USART2_IRQn = 38, /*!< USART2 global Interrupt */ - EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */ - TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */ - TIM7_IRQn = 55 /*!< TIM7 Interrupt */ -#endif /* STM32F10X_LD_VL */ - -#ifdef STM32F10X_MD - ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */ - USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ - USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ - CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ - CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ - EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ - TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ - TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ - TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ - TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ - TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ - TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ - TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ - I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ - I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ - I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ - I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ - SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ - SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ - USART1_IRQn = 37, /*!< USART1 global Interrupt */ - USART2_IRQn = 38, /*!< USART2 global Interrupt */ - USART3_IRQn = 39, /*!< USART3 global Interrupt */ - EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - USBWakeUp_IRQn = 42 /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ -#endif /* STM32F10X_MD */ - -#ifdef STM32F10X_MD_VL - ADC1_IRQn = 18, /*!< ADC1 global Interrupt */ - EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ - TIM1_BRK_TIM15_IRQn = 24, /*!< TIM1 Break and TIM15 Interrupts */ - TIM1_UP_TIM16_IRQn = 25, /*!< TIM1 Update and TIM16 Interrupts */ - TIM1_TRG_COM_TIM17_IRQn = 26, /*!< TIM1 Trigger and Commutation and TIM17 Interrupt */ - TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ - TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ - TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ - TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ - I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ - I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ - I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ - I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ - SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ - SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ - USART1_IRQn = 37, /*!< USART1 global Interrupt */ - USART2_IRQn = 38, /*!< USART2 global Interrupt */ - USART3_IRQn = 39, /*!< USART3 global Interrupt */ - EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - CEC_IRQn = 42, /*!< HDMI-CEC Interrupt */ - TIM6_DAC_IRQn = 54, /*!< TIM6 and DAC underrun Interrupt */ - TIM7_IRQn = 55 /*!< TIM7 Interrupt */ -#endif /* STM32F10X_MD_VL */ - -#ifdef STM32F10X_HD - ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */ - USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ - USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ - CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ - CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ - EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ - TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ - TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ - TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ - TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ - TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ - TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ - TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ - I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ - I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ - I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ - I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ - SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ - SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ - USART1_IRQn = 37, /*!< USART1 global Interrupt */ - USART2_IRQn = 38, /*!< USART2 global Interrupt */ - USART3_IRQn = 39, /*!< USART3 global Interrupt */ - EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ - TIM8_BRK_IRQn = 43, /*!< TIM8 Break Interrupt */ - TIM8_UP_IRQn = 44, /*!< TIM8 Update Interrupt */ - TIM8_TRG_COM_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt */ - TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ - ADC3_IRQn = 47, /*!< ADC3 global Interrupt */ - FSMC_IRQn = 48, /*!< FSMC global Interrupt */ - SDIO_IRQn = 49, /*!< SDIO global Interrupt */ - TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ - SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ - UART4_IRQn = 52, /*!< UART4 global Interrupt */ - UART5_IRQn = 53, /*!< UART5 global Interrupt */ - TIM6_IRQn = 54, /*!< TIM6 global Interrupt */ - TIM7_IRQn = 55, /*!< TIM7 global Interrupt */ - DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */ - DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */ - DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */ - DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */ -#endif /* STM32F10X_HD */ - -#ifdef STM32F10X_XL - ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */ - USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ - USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ - CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ - CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ - EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ - TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break Interrupt and TIM9 global Interrupt */ - TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global Interrupt */ - TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */ - TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ - TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ - TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ - TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ - I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ - I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ - I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ - I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ - SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ - SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ - USART1_IRQn = 37, /*!< USART1 global Interrupt */ - USART2_IRQn = 38, /*!< USART2 global Interrupt */ - USART3_IRQn = 39, /*!< USART3 global Interrupt */ - EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */ - TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global Interrupt */ - TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global Interrupt */ - TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ - TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ - ADC3_IRQn = 47, /*!< ADC3 global Interrupt */ - FSMC_IRQn = 48, /*!< FSMC global Interrupt */ - SDIO_IRQn = 49, /*!< SDIO global Interrupt */ - TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ - SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ - UART4_IRQn = 52, /*!< UART4 global Interrupt */ - UART5_IRQn = 53, /*!< UART5 global Interrupt */ - TIM6_IRQn = 54, /*!< TIM6 global Interrupt */ - TIM7_IRQn = 55, /*!< TIM7 global Interrupt */ - DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */ - DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */ - DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */ - DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */ -#endif /* STM32F10X_XL */ - -#ifdef STM32F10X_CL - ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */ - CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */ - CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */ - CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ - CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ - EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ - TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */ - TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */ - TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */ - TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ - TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ - TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ - TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ - I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ - I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ - I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ - I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ - SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ - SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ - USART1_IRQn = 37, /*!< USART1 global Interrupt */ - USART2_IRQn = 38, /*!< USART2 global Interrupt */ - USART3_IRQn = 39, /*!< USART3 global Interrupt */ - EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS WakeUp from suspend through EXTI Line Interrupt */ - TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ - SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ - UART4_IRQn = 52, /*!< UART4 global Interrupt */ - UART5_IRQn = 53, /*!< UART5 global Interrupt */ - TIM6_IRQn = 54, /*!< TIM6 global Interrupt */ - TIM7_IRQn = 55, /*!< TIM7 global Interrupt */ - DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */ - DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */ - DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */ - DMA2_Channel4_IRQn = 59, /*!< DMA2 Channel 4 global Interrupt */ - DMA2_Channel5_IRQn = 60, /*!< DMA2 Channel 5 global Interrupt */ - ETH_IRQn = 61, /*!< Ethernet global Interrupt */ - ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ - CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */ - CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */ - CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */ - CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */ - OTG_FS_IRQn = 67 /*!< USB OTG FS global Interrupt */ -#endif /* STM32F10X_CL */ -} IRQn_Type; - -/** - * @} - */ - -#include "core_cm3.h" -#include "system_stm32f10x.h" -#include - -/** @addtogroup Exported_types - * @{ - */ - -/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */ -typedef int32_t s32; -typedef int16_t s16; -typedef int8_t s8; - -typedef const int32_t sc32; /*!< Read Only */ -typedef const int16_t sc16; /*!< Read Only */ -typedef const int8_t sc8; /*!< Read Only */ - -typedef __IO int32_t vs32; -typedef __IO int16_t vs16; -typedef __IO int8_t vs8; - -typedef __I int32_t vsc32; /*!< Read Only */ -typedef __I int16_t vsc16; /*!< Read Only */ -typedef __I int8_t vsc8; /*!< Read Only */ - -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; - -typedef const uint32_t uc32; /*!< Read Only */ -typedef const uint16_t uc16; /*!< Read Only */ -typedef const uint8_t uc8; /*!< Read Only */ - -typedef __IO uint32_t vu32; -typedef __IO uint16_t vu16; -typedef __IO uint8_t vu8; - -typedef __I uint32_t vuc32; /*!< Read Only */ -typedef __I uint16_t vuc16; /*!< Read Only */ -typedef __I uint8_t vuc8; /*!< Read Only */ - -#ifndef __cplusplus -typedef enum {FALSE = 0, TRUE = !FALSE} bool; -#endif - -typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; - -typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; -#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) - -typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; - -/*!< STM32F10x Standard Peripheral Library old definitions (maintained for legacy purpose) */ -#define HSEStartUp_TimeOut HSE_STARTUP_TIMEOUT -#define HSE_Value HSE_VALUE -#define HSI_Value HSI_VALUE -/** - * @} - */ - -/** @addtogroup Peripheral_registers_structures - * @{ - */ - -/** - * @brief Analog to Digital Converter - */ - -typedef struct -{ - __IO uint32_t SR; - __IO uint32_t CR1; - __IO uint32_t CR2; - __IO uint32_t SMPR1; - __IO uint32_t SMPR2; - __IO uint32_t JOFR1; - __IO uint32_t JOFR2; - __IO uint32_t JOFR3; - __IO uint32_t JOFR4; - __IO uint32_t HTR; - __IO uint32_t LTR; - __IO uint32_t SQR1; - __IO uint32_t SQR2; - __IO uint32_t SQR3; - __IO uint32_t JSQR; - __IO uint32_t JDR1; - __IO uint32_t JDR2; - __IO uint32_t JDR3; - __IO uint32_t JDR4; - __IO uint32_t DR; -} ADC_TypeDef; - -/** - * @brief Backup Registers - */ - -typedef struct -{ - uint32_t RESERVED0; - __IO uint16_t DR1; - uint16_t RESERVED1; - __IO uint16_t DR2; - uint16_t RESERVED2; - __IO uint16_t DR3; - uint16_t RESERVED3; - __IO uint16_t DR4; - uint16_t RESERVED4; - __IO uint16_t DR5; - uint16_t RESERVED5; - __IO uint16_t DR6; - uint16_t RESERVED6; - __IO uint16_t DR7; - uint16_t RESERVED7; - __IO uint16_t DR8; - uint16_t RESERVED8; - __IO uint16_t DR9; - uint16_t RESERVED9; - __IO uint16_t DR10; - uint16_t RESERVED10; - __IO uint16_t RTCCR; - uint16_t RESERVED11; - __IO uint16_t CR; - uint16_t RESERVED12; - __IO uint16_t CSR; - uint16_t RESERVED13[5]; - __IO uint16_t DR11; - uint16_t RESERVED14; - __IO uint16_t DR12; - uint16_t RESERVED15; - __IO uint16_t DR13; - uint16_t RESERVED16; - __IO uint16_t DR14; - uint16_t RESERVED17; - __IO uint16_t DR15; - uint16_t RESERVED18; - __IO uint16_t DR16; - uint16_t RESERVED19; - __IO uint16_t DR17; - uint16_t RESERVED20; - __IO uint16_t DR18; - uint16_t RESERVED21; - __IO uint16_t DR19; - uint16_t RESERVED22; - __IO uint16_t DR20; - uint16_t RESERVED23; - __IO uint16_t DR21; - uint16_t RESERVED24; - __IO uint16_t DR22; - uint16_t RESERVED25; - __IO uint16_t DR23; - uint16_t RESERVED26; - __IO uint16_t DR24; - uint16_t RESERVED27; - __IO uint16_t DR25; - uint16_t RESERVED28; - __IO uint16_t DR26; - uint16_t RESERVED29; - __IO uint16_t DR27; - uint16_t RESERVED30; - __IO uint16_t DR28; - uint16_t RESERVED31; - __IO uint16_t DR29; - uint16_t RESERVED32; - __IO uint16_t DR30; - uint16_t RESERVED33; - __IO uint16_t DR31; - uint16_t RESERVED34; - __IO uint16_t DR32; - uint16_t RESERVED35; - __IO uint16_t DR33; - uint16_t RESERVED36; - __IO uint16_t DR34; - uint16_t RESERVED37; - __IO uint16_t DR35; - uint16_t RESERVED38; - __IO uint16_t DR36; - uint16_t RESERVED39; - __IO uint16_t DR37; - uint16_t RESERVED40; - __IO uint16_t DR38; - uint16_t RESERVED41; - __IO uint16_t DR39; - uint16_t RESERVED42; - __IO uint16_t DR40; - uint16_t RESERVED43; - __IO uint16_t DR41; - uint16_t RESERVED44; - __IO uint16_t DR42; - uint16_t RESERVED45; -} BKP_TypeDef; - -/** - * @brief Controller Area Network TxMailBox - */ - -typedef struct -{ - __IO uint32_t TIR; - __IO uint32_t TDTR; - __IO uint32_t TDLR; - __IO uint32_t TDHR; -} CAN_TxMailBox_TypeDef; - -/** - * @brief Controller Area Network FIFOMailBox - */ - -typedef struct -{ - __IO uint32_t RIR; - __IO uint32_t RDTR; - __IO uint32_t RDLR; - __IO uint32_t RDHR; -} CAN_FIFOMailBox_TypeDef; - -/** - * @brief Controller Area Network FilterRegister - */ - -typedef struct -{ - __IO uint32_t FR1; - __IO uint32_t FR2; -} CAN_FilterRegister_TypeDef; - -/** - * @brief Controller Area Network - */ - -typedef struct -{ - __IO uint32_t MCR; - __IO uint32_t MSR; - __IO uint32_t TSR; - __IO uint32_t RF0R; - __IO uint32_t RF1R; - __IO uint32_t IER; - __IO uint32_t ESR; - __IO uint32_t BTR; - uint32_t RESERVED0[88]; - CAN_TxMailBox_TypeDef sTxMailBox[3]; - CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; - uint32_t RESERVED1[12]; - __IO uint32_t FMR; - __IO uint32_t FM1R; - uint32_t RESERVED2; - __IO uint32_t FS1R; - uint32_t RESERVED3; - __IO uint32_t FFA1R; - uint32_t RESERVED4; - __IO uint32_t FA1R; - uint32_t RESERVED5[8]; -#ifndef STM32F10X_CL - CAN_FilterRegister_TypeDef sFilterRegister[14]; -#else - CAN_FilterRegister_TypeDef sFilterRegister[28]; -#endif /* STM32F10X_CL */ -} CAN_TypeDef; - -/** - * @brief Consumer Electronics Control (CEC) - */ -typedef struct -{ - __IO uint32_t CFGR; - __IO uint32_t OAR; - __IO uint32_t PRES; - __IO uint32_t ESR; - __IO uint32_t CSR; - __IO uint32_t TXD; - __IO uint32_t RXD; -} CEC_TypeDef; - -/** - * @brief CRC calculation unit - */ - -typedef struct -{ - __IO uint32_t DR; - __IO uint8_t IDR; - uint8_t RESERVED0; - uint16_t RESERVED1; - __IO uint32_t CR; -} CRC_TypeDef; - -/** - * @brief Digital to Analog Converter - */ - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t SWTRIGR; - __IO uint32_t DHR12R1; - __IO uint32_t DHR12L1; - __IO uint32_t DHR8R1; - __IO uint32_t DHR12R2; - __IO uint32_t DHR12L2; - __IO uint32_t DHR8R2; - __IO uint32_t DHR12RD; - __IO uint32_t DHR12LD; - __IO uint32_t DHR8RD; - __IO uint32_t DOR1; - __IO uint32_t DOR2; -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) - __IO uint32_t SR; -#endif -} DAC_TypeDef; - -/** - * @brief Debug MCU - */ - -typedef struct -{ - __IO uint32_t IDCODE; - __IO uint32_t CR; -}DBGMCU_TypeDef; - -/** - * @brief DMA Controller - */ - -typedef struct -{ - __IO uint32_t CCR; - __IO uint32_t CNDTR; - __IO uint32_t CPAR; - __IO uint32_t CMAR; -} DMA_Channel_TypeDef; - -typedef struct -{ - __IO uint32_t ISR; - __IO uint32_t IFCR; -} DMA_TypeDef; - -/** - * @brief Ethernet MAC - */ - -typedef struct -{ - __IO uint32_t MACCR; - __IO uint32_t MACFFR; - __IO uint32_t MACHTHR; - __IO uint32_t MACHTLR; - __IO uint32_t MACMIIAR; - __IO uint32_t MACMIIDR; - __IO uint32_t MACFCR; - __IO uint32_t MACVLANTR; /* 8 */ - uint32_t RESERVED0[2]; - __IO uint32_t MACRWUFFR; /* 11 */ - __IO uint32_t MACPMTCSR; - uint32_t RESERVED1[2]; - __IO uint32_t MACSR; /* 15 */ - __IO uint32_t MACIMR; - __IO uint32_t MACA0HR; - __IO uint32_t MACA0LR; - __IO uint32_t MACA1HR; - __IO uint32_t MACA1LR; - __IO uint32_t MACA2HR; - __IO uint32_t MACA2LR; - __IO uint32_t MACA3HR; - __IO uint32_t MACA3LR; /* 24 */ - uint32_t RESERVED2[40]; - __IO uint32_t MMCCR; /* 65 */ - __IO uint32_t MMCRIR; - __IO uint32_t MMCTIR; - __IO uint32_t MMCRIMR; - __IO uint32_t MMCTIMR; /* 69 */ - uint32_t RESERVED3[14]; - __IO uint32_t MMCTGFSCCR; /* 84 */ - __IO uint32_t MMCTGFMSCCR; - uint32_t RESERVED4[5]; - __IO uint32_t MMCTGFCR; - uint32_t RESERVED5[10]; - __IO uint32_t MMCRFCECR; - __IO uint32_t MMCRFAECR; - uint32_t RESERVED6[10]; - __IO uint32_t MMCRGUFCR; - uint32_t RESERVED7[334]; - __IO uint32_t PTPTSCR; - __IO uint32_t PTPSSIR; - __IO uint32_t PTPTSHR; - __IO uint32_t PTPTSLR; - __IO uint32_t PTPTSHUR; - __IO uint32_t PTPTSLUR; - __IO uint32_t PTPTSAR; - __IO uint32_t PTPTTHR; - __IO uint32_t PTPTTLR; - uint32_t RESERVED8[567]; - __IO uint32_t DMABMR; - __IO uint32_t DMATPDR; - __IO uint32_t DMARPDR; - __IO uint32_t DMARDLAR; - __IO uint32_t DMATDLAR; - __IO uint32_t DMASR; - __IO uint32_t DMAOMR; - __IO uint32_t DMAIER; - __IO uint32_t DMAMFBOCR; - uint32_t RESERVED9[9]; - __IO uint32_t DMACHTDR; - __IO uint32_t DMACHRDR; - __IO uint32_t DMACHTBAR; - __IO uint32_t DMACHRBAR; -} ETH_TypeDef; - -/** - * @brief External Interrupt/Event Controller - */ - -typedef struct -{ - __IO uint32_t IMR; - __IO uint32_t EMR; - __IO uint32_t RTSR; - __IO uint32_t FTSR; - __IO uint32_t SWIER; - __IO uint32_t PR; -} EXTI_TypeDef; - -/** - * @brief FLASH Registers - */ - -typedef struct -{ - __IO uint32_t ACR; - __IO uint32_t KEYR; - __IO uint32_t OPTKEYR; - __IO uint32_t SR; - __IO uint32_t CR; - __IO uint32_t AR; - __IO uint32_t RESERVED; - __IO uint32_t OBR; - __IO uint32_t WRPR; -#ifdef STM32F10X_XL - uint32_t RESERVED1[8]; - __IO uint32_t KEYR2; - uint32_t RESERVED2; - __IO uint32_t SR2; - __IO uint32_t CR2; - __IO uint32_t AR2; -#endif /* STM32F10X_XL */ -} FLASH_TypeDef; - -/** - * @brief Option Bytes Registers - */ - -typedef struct -{ - __IO uint16_t RDP; - __IO uint16_t USER; - __IO uint16_t Data0; - __IO uint16_t Data1; - __IO uint16_t WRP0; - __IO uint16_t WRP1; - __IO uint16_t WRP2; - __IO uint16_t WRP3; -} OB_TypeDef; - -/** - * @brief Flexible Static Memory Controller - */ - -typedef struct -{ - __IO uint32_t BTCR[8]; -} FSMC_Bank1_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank1E - */ - -typedef struct -{ - __IO uint32_t BWTR[7]; -} FSMC_Bank1E_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank2 - */ - -typedef struct -{ - __IO uint32_t PCR2; - __IO uint32_t SR2; - __IO uint32_t PMEM2; - __IO uint32_t PATT2; - uint32_t RESERVED0; - __IO uint32_t ECCR2; -} FSMC_Bank2_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank3 - */ - -typedef struct -{ - __IO uint32_t PCR3; - __IO uint32_t SR3; - __IO uint32_t PMEM3; - __IO uint32_t PATT3; - uint32_t RESERVED0; - __IO uint32_t ECCR3; -} FSMC_Bank3_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank4 - */ - -typedef struct -{ - __IO uint32_t PCR4; - __IO uint32_t SR4; - __IO uint32_t PMEM4; - __IO uint32_t PATT4; - __IO uint32_t PIO4; -} FSMC_Bank4_TypeDef; - -/** - * @brief General Purpose I/O - */ - -typedef struct -{ - __IO uint32_t CRL; - __IO uint32_t CRH; - __IO uint32_t IDR; - __IO uint32_t ODR; - __IO uint32_t BSRR; - __IO uint32_t BRR; - __IO uint32_t LCKR; -} GPIO_TypeDef; - -/** - * @brief Alternate Function I/O - */ - -typedef struct -{ - __IO uint32_t EVCR; - __IO uint32_t MAPR; - __IO uint32_t EXTICR[4]; - uint32_t RESERVED0; - __IO uint32_t MAPR2; -} AFIO_TypeDef; -/** - * @brief Inter-integrated Circuit Interface - */ - -typedef struct -{ - __IO uint16_t CR1; - uint16_t RESERVED0; - __IO uint16_t CR2; - uint16_t RESERVED1; - __IO uint16_t OAR1; - uint16_t RESERVED2; - __IO uint16_t OAR2; - uint16_t RESERVED3; - __IO uint16_t DR; - uint16_t RESERVED4; - __IO uint16_t SR1; - uint16_t RESERVED5; - __IO uint16_t SR2; - uint16_t RESERVED6; - __IO uint16_t CCR; - uint16_t RESERVED7; - __IO uint16_t TRISE; - uint16_t RESERVED8; -} I2C_TypeDef; - -/** - * @brief Independent WATCHDOG - */ - -typedef struct -{ - __IO uint32_t KR; - __IO uint32_t PR; - __IO uint32_t RLR; - __IO uint32_t SR; -} IWDG_TypeDef; - -/** - * @brief Power Control - */ - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t CSR; -} PWR_TypeDef; - -/** - * @brief Reset and Clock Control - */ - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t CFGR; - __IO uint32_t CIR; - __IO uint32_t APB2RSTR; - __IO uint32_t APB1RSTR; - __IO uint32_t AHBENR; - __IO uint32_t APB2ENR; - __IO uint32_t APB1ENR; - __IO uint32_t BDCR; - __IO uint32_t CSR; - -#ifdef STM32F10X_CL - __IO uint32_t AHBRSTR; - __IO uint32_t CFGR2; -#endif /* STM32F10X_CL */ - -#if defined STM32F10X_LD_VL || defined STM32F10X_MD_VL - uint32_t RESERVED0; - __IO uint32_t CFGR2; -#endif /* STM32F10X_LD_VL || STM32F10X_MD_VL */ -} RCC_TypeDef; - -/** - * @brief Real-Time Clock - */ - -typedef struct -{ - __IO uint16_t CRH; - uint16_t RESERVED0; - __IO uint16_t CRL; - uint16_t RESERVED1; - __IO uint16_t PRLH; - uint16_t RESERVED2; - __IO uint16_t PRLL; - uint16_t RESERVED3; - __IO uint16_t DIVH; - uint16_t RESERVED4; - __IO uint16_t DIVL; - uint16_t RESERVED5; - __IO uint16_t CNTH; - uint16_t RESERVED6; - __IO uint16_t CNTL; - uint16_t RESERVED7; - __IO uint16_t ALRH; - uint16_t RESERVED8; - __IO uint16_t ALRL; - uint16_t RESERVED9; -} RTC_TypeDef; - -/** - * @brief SD host Interface - */ - -typedef struct -{ - __IO uint32_t POWER; - __IO uint32_t CLKCR; - __IO uint32_t ARG; - __IO uint32_t CMD; - __I uint32_t RESPCMD; - __I uint32_t RESP1; - __I uint32_t RESP2; - __I uint32_t RESP3; - __I uint32_t RESP4; - __IO uint32_t DTIMER; - __IO uint32_t DLEN; - __IO uint32_t DCTRL; - __I uint32_t DCOUNT; - __I uint32_t STA; - __IO uint32_t ICR; - __IO uint32_t MASK; - uint32_t RESERVED0[2]; - __I uint32_t FIFOCNT; - uint32_t RESERVED1[13]; - __IO uint32_t FIFO; -} SDIO_TypeDef; - -/** - * @brief Serial Peripheral Interface - */ - -typedef struct -{ - __IO uint16_t CR1; - uint16_t RESERVED0; - __IO uint16_t CR2; - uint16_t RESERVED1; - __IO uint16_t SR; - uint16_t RESERVED2; - __IO uint16_t DR; - uint16_t RESERVED3; - __IO uint16_t CRCPR; - uint16_t RESERVED4; - __IO uint16_t RXCRCR; - uint16_t RESERVED5; - __IO uint16_t TXCRCR; - uint16_t RESERVED6; - __IO uint16_t I2SCFGR; - uint16_t RESERVED7; - __IO uint16_t I2SPR; - uint16_t RESERVED8; -} SPI_TypeDef; - -/** - * @brief TIM - */ - -typedef struct -{ - __IO uint16_t CR1; - uint16_t RESERVED0; - __IO uint16_t CR2; - uint16_t RESERVED1; - __IO uint16_t SMCR; - uint16_t RESERVED2; - __IO uint16_t DIER; - uint16_t RESERVED3; - __IO uint16_t SR; - uint16_t RESERVED4; - __IO uint16_t EGR; - uint16_t RESERVED5; - __IO uint16_t CCMR1; - uint16_t RESERVED6; - __IO uint16_t CCMR2; - uint16_t RESERVED7; - __IO uint16_t CCER; - uint16_t RESERVED8; - __IO uint16_t CNT; - uint16_t RESERVED9; - __IO uint16_t PSC; - uint16_t RESERVED10; - __IO uint16_t ARR; - uint16_t RESERVED11; - __IO uint16_t RCR; - uint16_t RESERVED12; - __IO uint16_t CCR1; - uint16_t RESERVED13; - __IO uint16_t CCR2; - uint16_t RESERVED14; - __IO uint16_t CCR3; - uint16_t RESERVED15; - __IO uint16_t CCR4; - uint16_t RESERVED16; - __IO uint16_t BDTR; - uint16_t RESERVED17; - __IO uint16_t DCR; - uint16_t RESERVED18; - __IO uint16_t DMAR; - uint16_t RESERVED19; -} TIM_TypeDef; - -/** - * @brief Universal Synchronous Asynchronous Receiver Transmitter - */ - -typedef struct -{ - __IO uint16_t SR; - uint16_t RESERVED0; - __IO uint16_t DR; - uint16_t RESERVED1; - __IO uint16_t BRR; - uint16_t RESERVED2; - __IO uint16_t CR1; - uint16_t RESERVED3; - __IO uint16_t CR2; - uint16_t RESERVED4; - __IO uint16_t CR3; - uint16_t RESERVED5; - __IO uint16_t GTPR; - uint16_t RESERVED6; -} USART_TypeDef; - -/** - * @brief Window WATCHDOG - */ - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t CFR; - __IO uint32_t SR; -} WWDG_TypeDef; - -/** - * @} - */ - -/** @addtogroup Peripheral_memory_map - * @{ - */ - -#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the alias region */ -#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the alias region */ - -#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM base address in the bit-band region */ -#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the bit-band region */ - -#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */ - -/*!< Peripheral memory map */ -#define APB1PERIPH_BASE PERIPH_BASE -#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) -#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) - -#define TIM2_BASE (APB1PERIPH_BASE + 0x0000) -#define TIM3_BASE (APB1PERIPH_BASE + 0x0400) -#define TIM4_BASE (APB1PERIPH_BASE + 0x0800) -#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00) -#define TIM6_BASE (APB1PERIPH_BASE + 0x1000) -#define TIM7_BASE (APB1PERIPH_BASE + 0x1400) -#define TIM12_BASE (APB1PERIPH_BASE + 0x1800) -#define TIM13_BASE (APB1PERIPH_BASE + 0x1C00) -#define TIM14_BASE (APB1PERIPH_BASE + 0x2000) -#define RTC_BASE (APB1PERIPH_BASE + 0x2800) -#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00) -#define IWDG_BASE (APB1PERIPH_BASE + 0x3000) -#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) -#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) -#define USART2_BASE (APB1PERIPH_BASE + 0x4400) -#define USART3_BASE (APB1PERIPH_BASE + 0x4800) -#define UART4_BASE (APB1PERIPH_BASE + 0x4C00) -#define UART5_BASE (APB1PERIPH_BASE + 0x5000) -#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) -#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) -#define CAN1_BASE (APB1PERIPH_BASE + 0x6400) -#define CAN2_BASE (APB1PERIPH_BASE + 0x6800) -#define BKP_BASE (APB1PERIPH_BASE + 0x6C00) -#define PWR_BASE (APB1PERIPH_BASE + 0x7000) -#define DAC_BASE (APB1PERIPH_BASE + 0x7400) -#define CEC_BASE (APB1PERIPH_BASE + 0x7800) - -#define AFIO_BASE (APB2PERIPH_BASE + 0x0000) -#define EXTI_BASE (APB2PERIPH_BASE + 0x0400) -#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) -#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00) -#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000) -#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) -#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800) -#define GPIOF_BASE (APB2PERIPH_BASE + 0x1C00) -#define GPIOG_BASE (APB2PERIPH_BASE + 0x2000) -#define ADC1_BASE (APB2PERIPH_BASE + 0x2400) -#define ADC2_BASE (APB2PERIPH_BASE + 0x2800) -#define TIM1_BASE (APB2PERIPH_BASE + 0x2C00) -#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) -#define TIM8_BASE (APB2PERIPH_BASE + 0x3400) -#define USART1_BASE (APB2PERIPH_BASE + 0x3800) -#define ADC3_BASE (APB2PERIPH_BASE + 0x3C00) -#define TIM15_BASE (APB2PERIPH_BASE + 0x4000) -#define TIM16_BASE (APB2PERIPH_BASE + 0x4400) -#define TIM17_BASE (APB2PERIPH_BASE + 0x4800) -#define TIM9_BASE (APB2PERIPH_BASE + 0x4C00) -#define TIM10_BASE (APB2PERIPH_BASE + 0x5000) -#define TIM11_BASE (APB2PERIPH_BASE + 0x5400) - -#define SDIO_BASE (PERIPH_BASE + 0x18000) - -#define DMA1_BASE (AHBPERIPH_BASE + 0x0000) -#define DMA1_Channel1_BASE (AHBPERIPH_BASE + 0x0008) -#define DMA1_Channel2_BASE (AHBPERIPH_BASE + 0x001C) -#define DMA1_Channel3_BASE (AHBPERIPH_BASE + 0x0030) -#define DMA1_Channel4_BASE (AHBPERIPH_BASE + 0x0044) -#define DMA1_Channel5_BASE (AHBPERIPH_BASE + 0x0058) -#define DMA1_Channel6_BASE (AHBPERIPH_BASE + 0x006C) -#define DMA1_Channel7_BASE (AHBPERIPH_BASE + 0x0080) -#define DMA2_BASE (AHBPERIPH_BASE + 0x0400) -#define DMA2_Channel1_BASE (AHBPERIPH_BASE + 0x0408) -#define DMA2_Channel2_BASE (AHBPERIPH_BASE + 0x041C) -#define DMA2_Channel3_BASE (AHBPERIPH_BASE + 0x0430) -#define DMA2_Channel4_BASE (AHBPERIPH_BASE + 0x0444) -#define DMA2_Channel5_BASE (AHBPERIPH_BASE + 0x0458) -#define RCC_BASE (AHBPERIPH_BASE + 0x1000) -#define CRC_BASE (AHBPERIPH_BASE + 0x3000) - -#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000) /*!< Flash registers base address */ -#define OB_BASE ((uint32_t)0x1FFFF800) /*!< Flash Option Bytes base address */ - -#define ETH_BASE (AHBPERIPH_BASE + 0x8000) -#define ETH_MAC_BASE (ETH_BASE) -#define ETH_MMC_BASE (ETH_BASE + 0x0100) -#define ETH_PTP_BASE (ETH_BASE + 0x0700) -#define ETH_DMA_BASE (ETH_BASE + 0x1000) - -#define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) /*!< FSMC Bank1 registers base address */ -#define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) /*!< FSMC Bank1E registers base address */ -#define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060) /*!< FSMC Bank2 registers base address */ -#define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080) /*!< FSMC Bank3 registers base address */ -#define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0) /*!< FSMC Bank4 registers base address */ - -#define DBGMCU_BASE ((uint32_t)0xE0042000) /*!< Debug MCU registers base address */ - -/** - * @} - */ - -/** @addtogroup Peripheral_declaration - * @{ - */ - -#define TIM2 ((TIM_TypeDef *) TIM2_BASE) -#define TIM3 ((TIM_TypeDef *) TIM3_BASE) -#define TIM4 ((TIM_TypeDef *) TIM4_BASE) -#define TIM5 ((TIM_TypeDef *) TIM5_BASE) -#define TIM6 ((TIM_TypeDef *) TIM6_BASE) -#define TIM7 ((TIM_TypeDef *) TIM7_BASE) -#define TIM12 ((TIM_TypeDef *) TIM12_BASE) -#define TIM13 ((TIM_TypeDef *) TIM13_BASE) -#define TIM14 ((TIM_TypeDef *) TIM14_BASE) -#define RTC ((RTC_TypeDef *) RTC_BASE) -#define WWDG ((WWDG_TypeDef *) WWDG_BASE) -#define IWDG ((IWDG_TypeDef *) IWDG_BASE) -#define SPI2 ((SPI_TypeDef *) SPI2_BASE) -#define SPI3 ((SPI_TypeDef *) SPI3_BASE) -#define USART2 ((USART_TypeDef *) USART2_BASE) -#define USART3 ((USART_TypeDef *) USART3_BASE) -#define UART4 ((USART_TypeDef *) UART4_BASE) -#define UART5 ((USART_TypeDef *) UART5_BASE) -#define I2C1 ((I2C_TypeDef *) I2C1_BASE) -#define I2C2 ((I2C_TypeDef *) I2C2_BASE) -#define CAN1 ((CAN_TypeDef *) CAN1_BASE) -#define CAN2 ((CAN_TypeDef *) CAN2_BASE) -#define BKP ((BKP_TypeDef *) BKP_BASE) -#define PWR ((PWR_TypeDef *) PWR_BASE) -#define DAC ((DAC_TypeDef *) DAC_BASE) -#define CEC ((CEC_TypeDef *) CEC_BASE) -#define AFIO ((AFIO_TypeDef *) AFIO_BASE) -#define EXTI ((EXTI_TypeDef *) EXTI_BASE) -#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) -#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) -#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) -#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) -#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) -#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) -#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE) -#define ADC1 ((ADC_TypeDef *) ADC1_BASE) -#define ADC2 ((ADC_TypeDef *) ADC2_BASE) -#define TIM1 ((TIM_TypeDef *) TIM1_BASE) -#define SPI1 ((SPI_TypeDef *) SPI1_BASE) -#define TIM8 ((TIM_TypeDef *) TIM8_BASE) -#define USART1 ((USART_TypeDef *) USART1_BASE) -#define ADC3 ((ADC_TypeDef *) ADC3_BASE) -#define TIM15 ((TIM_TypeDef *) TIM15_BASE) -#define TIM16 ((TIM_TypeDef *) TIM16_BASE) -#define TIM17 ((TIM_TypeDef *) TIM17_BASE) -#define TIM9 ((TIM_TypeDef *) TIM9_BASE) -#define TIM10 ((TIM_TypeDef *) TIM10_BASE) -#define TIM11 ((TIM_TypeDef *) TIM11_BASE) -#define SDIO ((SDIO_TypeDef *) SDIO_BASE) -#define DMA1 ((DMA_TypeDef *) DMA1_BASE) -#define DMA2 ((DMA_TypeDef *) DMA2_BASE) -#define DMA1_Channel1 ((DMA_Channel_TypeDef *) DMA1_Channel1_BASE) -#define DMA1_Channel2 ((DMA_Channel_TypeDef *) DMA1_Channel2_BASE) -#define DMA1_Channel3 ((DMA_Channel_TypeDef *) DMA1_Channel3_BASE) -#define DMA1_Channel4 ((DMA_Channel_TypeDef *) DMA1_Channel4_BASE) -#define DMA1_Channel5 ((DMA_Channel_TypeDef *) DMA1_Channel5_BASE) -#define DMA1_Channel6 ((DMA_Channel_TypeDef *) DMA1_Channel6_BASE) -#define DMA1_Channel7 ((DMA_Channel_TypeDef *) DMA1_Channel7_BASE) -#define DMA2_Channel1 ((DMA_Channel_TypeDef *) DMA2_Channel1_BASE) -#define DMA2_Channel2 ((DMA_Channel_TypeDef *) DMA2_Channel2_BASE) -#define DMA2_Channel3 ((DMA_Channel_TypeDef *) DMA2_Channel3_BASE) -#define DMA2_Channel4 ((DMA_Channel_TypeDef *) DMA2_Channel4_BASE) -#define DMA2_Channel5 ((DMA_Channel_TypeDef *) DMA2_Channel5_BASE) -#define RCC ((RCC_TypeDef *) RCC_BASE) -#define CRC ((CRC_TypeDef *) CRC_BASE) -#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) -#define OB ((OB_TypeDef *) OB_BASE) -#define ETH ((ETH_TypeDef *) ETH_BASE) -#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE) -#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE) -#define FSMC_Bank2 ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE) -#define FSMC_Bank3 ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE) -#define FSMC_Bank4 ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE) -#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) - -/** - * @} - */ - -/** @addtogroup Exported_constants - * @{ - */ - - /** @addtogroup Peripheral_Registers_Bits_Definition - * @{ - */ - -/******************************************************************************/ -/* Peripheral Registers_Bits_Definition */ -/******************************************************************************/ - -/******************************************************************************/ -/* */ -/* CRC calculation unit */ -/* */ -/******************************************************************************/ - -/******************* Bit definition for CRC_DR register *********************/ -#define CRC_DR_DR ((uint32_t)0xFFFFFFFF) /*!< Data register bits */ - - -/******************* Bit definition for CRC_IDR register ********************/ -#define CRC_IDR_IDR ((uint8_t)0xFF) /*!< General-purpose 8-bit data register bits */ - - -/******************** Bit definition for CRC_CR register ********************/ -#define CRC_CR_RESET ((uint8_t)0x01) /*!< RESET bit */ - -/******************************************************************************/ -/* */ -/* Power Control */ -/* */ -/******************************************************************************/ - -/******************** Bit definition for PWR_CR register ********************/ -#define PWR_CR_LPDS ((uint16_t)0x0001) /*!< Low-Power Deepsleep */ -#define PWR_CR_PDDS ((uint16_t)0x0002) /*!< Power Down Deepsleep */ -#define PWR_CR_CWUF ((uint16_t)0x0004) /*!< Clear Wakeup Flag */ -#define PWR_CR_CSBF ((uint16_t)0x0008) /*!< Clear Standby Flag */ -#define PWR_CR_PVDE ((uint16_t)0x0010) /*!< Power Voltage Detector Enable */ - -#define PWR_CR_PLS ((uint16_t)0x00E0) /*!< PLS[2:0] bits (PVD Level Selection) */ -#define PWR_CR_PLS_0 ((uint16_t)0x0020) /*!< Bit 0 */ -#define PWR_CR_PLS_1 ((uint16_t)0x0040) /*!< Bit 1 */ -#define PWR_CR_PLS_2 ((uint16_t)0x0080) /*!< Bit 2 */ - -/*!< PVD level configuration */ -#define PWR_CR_PLS_2V2 ((uint16_t)0x0000) /*!< PVD level 2.2V */ -#define PWR_CR_PLS_2V3 ((uint16_t)0x0020) /*!< PVD level 2.3V */ -#define PWR_CR_PLS_2V4 ((uint16_t)0x0040) /*!< PVD level 2.4V */ -#define PWR_CR_PLS_2V5 ((uint16_t)0x0060) /*!< PVD level 2.5V */ -#define PWR_CR_PLS_2V6 ((uint16_t)0x0080) /*!< PVD level 2.6V */ -#define PWR_CR_PLS_2V7 ((uint16_t)0x00A0) /*!< PVD level 2.7V */ -#define PWR_CR_PLS_2V8 ((uint16_t)0x00C0) /*!< PVD level 2.8V */ -#define PWR_CR_PLS_2V9 ((uint16_t)0x00E0) /*!< PVD level 2.9V */ - -#define PWR_CR_DBP ((uint16_t)0x0100) /*!< Disable Backup Domain write protection */ - - -/******************* Bit definition for PWR_CSR register ********************/ -#define PWR_CSR_WUF ((uint16_t)0x0001) /*!< Wakeup Flag */ -#define PWR_CSR_SBF ((uint16_t)0x0002) /*!< Standby Flag */ -#define PWR_CSR_PVDO ((uint16_t)0x0004) /*!< PVD Output */ -#define PWR_CSR_EWUP ((uint16_t)0x0100) /*!< Enable WKUP pin */ - -/******************************************************************************/ -/* */ -/* Backup registers */ -/* */ -/******************************************************************************/ - -/******************* Bit definition for BKP_DR1 register ********************/ -#define BKP_DR1_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR2 register ********************/ -#define BKP_DR2_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR3 register ********************/ -#define BKP_DR3_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR4 register ********************/ -#define BKP_DR4_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR5 register ********************/ -#define BKP_DR5_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR6 register ********************/ -#define BKP_DR6_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR7 register ********************/ -#define BKP_DR7_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR8 register ********************/ -#define BKP_DR8_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR9 register ********************/ -#define BKP_DR9_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR10 register *******************/ -#define BKP_DR10_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR11 register *******************/ -#define BKP_DR11_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR12 register *******************/ -#define BKP_DR12_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR13 register *******************/ -#define BKP_DR13_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR14 register *******************/ -#define BKP_DR14_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR15 register *******************/ -#define BKP_DR15_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR16 register *******************/ -#define BKP_DR16_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR17 register *******************/ -#define BKP_DR17_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/****************** Bit definition for BKP_DR18 register ********************/ -#define BKP_DR18_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR19 register *******************/ -#define BKP_DR19_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR20 register *******************/ -#define BKP_DR20_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR21 register *******************/ -#define BKP_DR21_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR22 register *******************/ -#define BKP_DR22_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR23 register *******************/ -#define BKP_DR23_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR24 register *******************/ -#define BKP_DR24_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR25 register *******************/ -#define BKP_DR25_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR26 register *******************/ -#define BKP_DR26_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR27 register *******************/ -#define BKP_DR27_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR28 register *******************/ -#define BKP_DR28_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR29 register *******************/ -#define BKP_DR29_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR30 register *******************/ -#define BKP_DR30_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR31 register *******************/ -#define BKP_DR31_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR32 register *******************/ -#define BKP_DR32_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR33 register *******************/ -#define BKP_DR33_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR34 register *******************/ -#define BKP_DR34_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR35 register *******************/ -#define BKP_DR35_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR36 register *******************/ -#define BKP_DR36_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR37 register *******************/ -#define BKP_DR37_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR38 register *******************/ -#define BKP_DR38_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR39 register *******************/ -#define BKP_DR39_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR40 register *******************/ -#define BKP_DR40_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR41 register *******************/ -#define BKP_DR41_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/******************* Bit definition for BKP_DR42 register *******************/ -#define BKP_DR42_D ((uint16_t)0xFFFF) /*!< Backup data */ - -/****************** Bit definition for BKP_RTCCR register *******************/ -#define BKP_RTCCR_CAL ((uint16_t)0x007F) /*!< Calibration value */ -#define BKP_RTCCR_CCO ((uint16_t)0x0080) /*!< Calibration Clock Output */ -#define BKP_RTCCR_ASOE ((uint16_t)0x0100) /*!< Alarm or Second Output Enable */ -#define BKP_RTCCR_ASOS ((uint16_t)0x0200) /*!< Alarm or Second Output Selection */ - -/******************** Bit definition for BKP_CR register ********************/ -#define BKP_CR_TPE ((uint8_t)0x01) /*!< TAMPER pin enable */ -#define BKP_CR_TPAL ((uint8_t)0x02) /*!< TAMPER pin active level */ - -/******************* Bit definition for BKP_CSR register ********************/ -#define BKP_CSR_CTE ((uint16_t)0x0001) /*!< Clear Tamper event */ -#define BKP_CSR_CTI ((uint16_t)0x0002) /*!< Clear Tamper Interrupt */ -#define BKP_CSR_TPIE ((uint16_t)0x0004) /*!< TAMPER Pin interrupt enable */ -#define BKP_CSR_TEF ((uint16_t)0x0100) /*!< Tamper Event Flag */ -#define BKP_CSR_TIF ((uint16_t)0x0200) /*!< Tamper Interrupt Flag */ - -/******************************************************************************/ -/* */ -/* Reset and Clock Control */ -/* */ -/******************************************************************************/ - -/******************** Bit definition for RCC_CR register ********************/ -#define RCC_CR_HSION ((uint32_t)0x00000001) /*!< Internal High Speed clock enable */ -#define RCC_CR_HSIRDY ((uint32_t)0x00000002) /*!< Internal High Speed clock ready flag */ -#define RCC_CR_HSITRIM ((uint32_t)0x000000F8) /*!< Internal High Speed clock trimming */ -#define RCC_CR_HSICAL ((uint32_t)0x0000FF00) /*!< Internal High Speed clock Calibration */ -#define RCC_CR_HSEON ((uint32_t)0x00010000) /*!< External High Speed clock enable */ -#define RCC_CR_HSERDY ((uint32_t)0x00020000) /*!< External High Speed clock ready flag */ -#define RCC_CR_HSEBYP ((uint32_t)0x00040000) /*!< External High Speed clock Bypass */ -#define RCC_CR_CSSON ((uint32_t)0x00080000) /*!< Clock Security System enable */ -#define RCC_CR_PLLON ((uint32_t)0x01000000) /*!< PLL enable */ -#define RCC_CR_PLLRDY ((uint32_t)0x02000000) /*!< PLL clock ready flag */ - -#ifdef STM32F10X_CL - #define RCC_CR_PLL2ON ((uint32_t)0x04000000) /*!< PLL2 enable */ - #define RCC_CR_PLL2RDY ((uint32_t)0x08000000) /*!< PLL2 clock ready flag */ - #define RCC_CR_PLL3ON ((uint32_t)0x10000000) /*!< PLL3 enable */ - #define RCC_CR_PLL3RDY ((uint32_t)0x20000000) /*!< PLL3 clock ready flag */ -#endif /* STM32F10X_CL */ - -/******************* Bit definition for RCC_CFGR register *******************/ -/*!< SW configuration */ -#define RCC_CFGR_SW ((uint32_t)0x00000003) /*!< SW[1:0] bits (System clock Switch) */ -#define RCC_CFGR_SW_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define RCC_CFGR_SW_1 ((uint32_t)0x00000002) /*!< Bit 1 */ - -#define RCC_CFGR_SW_HSI ((uint32_t)0x00000000) /*!< HSI selected as system clock */ -#define RCC_CFGR_SW_HSE ((uint32_t)0x00000001) /*!< HSE selected as system clock */ -#define RCC_CFGR_SW_PLL ((uint32_t)0x00000002) /*!< PLL selected as system clock */ - -/*!< SWS configuration */ -#define RCC_CFGR_SWS ((uint32_t)0x0000000C) /*!< SWS[1:0] bits (System Clock Switch Status) */ -#define RCC_CFGR_SWS_0 ((uint32_t)0x00000004) /*!< Bit 0 */ -#define RCC_CFGR_SWS_1 ((uint32_t)0x00000008) /*!< Bit 1 */ - -#define RCC_CFGR_SWS_HSI ((uint32_t)0x00000000) /*!< HSI oscillator used as system clock */ -#define RCC_CFGR_SWS_HSE ((uint32_t)0x00000004) /*!< HSE oscillator used as system clock */ -#define RCC_CFGR_SWS_PLL ((uint32_t)0x00000008) /*!< PLL used as system clock */ - -/*!< HPRE configuration */ -#define RCC_CFGR_HPRE ((uint32_t)0x000000F0) /*!< HPRE[3:0] bits (AHB prescaler) */ -#define RCC_CFGR_HPRE_0 ((uint32_t)0x00000010) /*!< Bit 0 */ -#define RCC_CFGR_HPRE_1 ((uint32_t)0x00000020) /*!< Bit 1 */ -#define RCC_CFGR_HPRE_2 ((uint32_t)0x00000040) /*!< Bit 2 */ -#define RCC_CFGR_HPRE_3 ((uint32_t)0x00000080) /*!< Bit 3 */ - -#define RCC_CFGR_HPRE_DIV1 ((uint32_t)0x00000000) /*!< SYSCLK not divided */ -#define RCC_CFGR_HPRE_DIV2 ((uint32_t)0x00000080) /*!< SYSCLK divided by 2 */ -#define RCC_CFGR_HPRE_DIV4 ((uint32_t)0x00000090) /*!< SYSCLK divided by 4 */ -#define RCC_CFGR_HPRE_DIV8 ((uint32_t)0x000000A0) /*!< SYSCLK divided by 8 */ -#define RCC_CFGR_HPRE_DIV16 ((uint32_t)0x000000B0) /*!< SYSCLK divided by 16 */ -#define RCC_CFGR_HPRE_DIV64 ((uint32_t)0x000000C0) /*!< SYSCLK divided by 64 */ -#define RCC_CFGR_HPRE_DIV128 ((uint32_t)0x000000D0) /*!< SYSCLK divided by 128 */ -#define RCC_CFGR_HPRE_DIV256 ((uint32_t)0x000000E0) /*!< SYSCLK divided by 256 */ -#define RCC_CFGR_HPRE_DIV512 ((uint32_t)0x000000F0) /*!< SYSCLK divided by 512 */ - -/*!< PPRE1 configuration */ -#define RCC_CFGR_PPRE1 ((uint32_t)0x00000700) /*!< PRE1[2:0] bits (APB1 prescaler) */ -#define RCC_CFGR_PPRE1_0 ((uint32_t)0x00000100) /*!< Bit 0 */ -#define RCC_CFGR_PPRE1_1 ((uint32_t)0x00000200) /*!< Bit 1 */ -#define RCC_CFGR_PPRE1_2 ((uint32_t)0x00000400) /*!< Bit 2 */ - -#define RCC_CFGR_PPRE1_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */ -#define RCC_CFGR_PPRE1_DIV2 ((uint32_t)0x00000400) /*!< HCLK divided by 2 */ -#define RCC_CFGR_PPRE1_DIV4 ((uint32_t)0x00000500) /*!< HCLK divided by 4 */ -#define RCC_CFGR_PPRE1_DIV8 ((uint32_t)0x00000600) /*!< HCLK divided by 8 */ -#define RCC_CFGR_PPRE1_DIV16 ((uint32_t)0x00000700) /*!< HCLK divided by 16 */ - -/*!< PPRE2 configuration */ -#define RCC_CFGR_PPRE2 ((uint32_t)0x00003800) /*!< PRE2[2:0] bits (APB2 prescaler) */ -#define RCC_CFGR_PPRE2_0 ((uint32_t)0x00000800) /*!< Bit 0 */ -#define RCC_CFGR_PPRE2_1 ((uint32_t)0x00001000) /*!< Bit 1 */ -#define RCC_CFGR_PPRE2_2 ((uint32_t)0x00002000) /*!< Bit 2 */ - -#define RCC_CFGR_PPRE2_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */ -#define RCC_CFGR_PPRE2_DIV2 ((uint32_t)0x00002000) /*!< HCLK divided by 2 */ -#define RCC_CFGR_PPRE2_DIV4 ((uint32_t)0x00002800) /*!< HCLK divided by 4 */ -#define RCC_CFGR_PPRE2_DIV8 ((uint32_t)0x00003000) /*!< HCLK divided by 8 */ -#define RCC_CFGR_PPRE2_DIV16 ((uint32_t)0x00003800) /*!< HCLK divided by 16 */ - -/*!< ADCPPRE configuration */ -#define RCC_CFGR_ADCPRE ((uint32_t)0x0000C000) /*!< ADCPRE[1:0] bits (ADC prescaler) */ -#define RCC_CFGR_ADCPRE_0 ((uint32_t)0x00004000) /*!< Bit 0 */ -#define RCC_CFGR_ADCPRE_1 ((uint32_t)0x00008000) /*!< Bit 1 */ - -#define RCC_CFGR_ADCPRE_DIV2 ((uint32_t)0x00000000) /*!< PCLK2 divided by 2 */ -#define RCC_CFGR_ADCPRE_DIV4 ((uint32_t)0x00004000) /*!< PCLK2 divided by 4 */ -#define RCC_CFGR_ADCPRE_DIV6 ((uint32_t)0x00008000) /*!< PCLK2 divided by 6 */ -#define RCC_CFGR_ADCPRE_DIV8 ((uint32_t)0x0000C000) /*!< PCLK2 divided by 8 */ - -#define RCC_CFGR_PLLSRC ((uint32_t)0x00010000) /*!< PLL entry clock source */ - -#define RCC_CFGR_PLLXTPRE ((uint32_t)0x00020000) /*!< HSE divider for PLL entry */ - -/*!< PLLMUL configuration */ -#define RCC_CFGR_PLLMULL ((uint32_t)0x003C0000) /*!< PLLMUL[3:0] bits (PLL multiplication factor) */ -#define RCC_CFGR_PLLMULL_0 ((uint32_t)0x00040000) /*!< Bit 0 */ -#define RCC_CFGR_PLLMULL_1 ((uint32_t)0x00080000) /*!< Bit 1 */ -#define RCC_CFGR_PLLMULL_2 ((uint32_t)0x00100000) /*!< Bit 2 */ -#define RCC_CFGR_PLLMULL_3 ((uint32_t)0x00200000) /*!< Bit 3 */ - -#ifdef STM32F10X_CL - #define RCC_CFGR_PLLSRC_HSI_Div2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */ - #define RCC_CFGR_PLLSRC_PREDIV1 ((uint32_t)0x00010000) /*!< PREDIV1 clock selected as PLL entry clock source */ - - #define RCC_CFGR_PLLXTPRE_PREDIV1 ((uint32_t)0x00000000) /*!< PREDIV1 clock not divided for PLL entry */ - #define RCC_CFGR_PLLXTPRE_PREDIV1_Div2 ((uint32_t)0x00020000) /*!< PREDIV1 clock divided by 2 for PLL entry */ - - #define RCC_CFGR_PLLMULL4 ((uint32_t)0x00080000) /*!< PLL input clock * 4 */ - #define RCC_CFGR_PLLMULL5 ((uint32_t)0x000C0000) /*!< PLL input clock * 5 */ - #define RCC_CFGR_PLLMULL6 ((uint32_t)0x00100000) /*!< PLL input clock * 6 */ - #define RCC_CFGR_PLLMULL7 ((uint32_t)0x00140000) /*!< PLL input clock * 7 */ - #define RCC_CFGR_PLLMULL8 ((uint32_t)0x00180000) /*!< PLL input clock * 8 */ - #define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock * 9 */ - #define RCC_CFGR_PLLMULL6_5 ((uint32_t)0x00340000) /*!< PLL input clock * 6.5 */ - - #define RCC_CFGR_OTGFSPRE ((uint32_t)0x00400000) /*!< USB OTG FS prescaler */ - -/*!< MCO configuration */ - #define RCC_CFGR_MCO ((uint32_t)0x0F000000) /*!< MCO[3:0] bits (Microcontroller Clock Output) */ - #define RCC_CFGR_MCO_0 ((uint32_t)0x01000000) /*!< Bit 0 */ - #define RCC_CFGR_MCO_1 ((uint32_t)0x02000000) /*!< Bit 1 */ - #define RCC_CFGR_MCO_2 ((uint32_t)0x04000000) /*!< Bit 2 */ - #define RCC_CFGR_MCO_3 ((uint32_t)0x08000000) /*!< Bit 3 */ - - #define RCC_CFGR_MCO_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */ - #define RCC_CFGR_MCO_SYSCLK ((uint32_t)0x04000000) /*!< System clock selected as MCO source */ - #define RCC_CFGR_MCO_HSI ((uint32_t)0x05000000) /*!< HSI clock selected as MCO source */ - #define RCC_CFGR_MCO_HSE ((uint32_t)0x06000000) /*!< HSE clock selected as MCO source */ - #define RCC_CFGR_MCO_PLLCLK_Div2 ((uint32_t)0x07000000) /*!< PLL clock divided by 2 selected as MCO source */ - #define RCC_CFGR_MCO_PLL2CLK ((uint32_t)0x08000000) /*!< PLL2 clock selected as MCO source*/ - #define RCC_CFGR_MCO_PLL3CLK_Div2 ((uint32_t)0x09000000) /*!< PLL3 clock divided by 2 selected as MCO source*/ - #define RCC_CFGR_MCO_Ext_HSE ((uint32_t)0x0A000000) /*!< XT1 external 3-25 MHz oscillator clock selected as MCO source */ - #define RCC_CFGR_MCO_PLL3CLK ((uint32_t)0x0B000000) /*!< PLL3 clock selected as MCO source */ -#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) - #define RCC_CFGR_PLLSRC_HSI_Div2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */ - #define RCC_CFGR_PLLSRC_PREDIV1 ((uint32_t)0x00010000) /*!< PREDIV1 clock selected as PLL entry clock source */ - - #define RCC_CFGR_PLLXTPRE_PREDIV1 ((uint32_t)0x00000000) /*!< PREDIV1 clock not divided for PLL entry */ - #define RCC_CFGR_PLLXTPRE_PREDIV1_Div2 ((uint32_t)0x00020000) /*!< PREDIV1 clock divided by 2 for PLL entry */ - - #define RCC_CFGR_PLLMULL2 ((uint32_t)0x00000000) /*!< PLL input clock*2 */ - #define RCC_CFGR_PLLMULL3 ((uint32_t)0x00040000) /*!< PLL input clock*3 */ - #define RCC_CFGR_PLLMULL4 ((uint32_t)0x00080000) /*!< PLL input clock*4 */ - #define RCC_CFGR_PLLMULL5 ((uint32_t)0x000C0000) /*!< PLL input clock*5 */ - #define RCC_CFGR_PLLMULL6 ((uint32_t)0x00100000) /*!< PLL input clock*6 */ - #define RCC_CFGR_PLLMULL7 ((uint32_t)0x00140000) /*!< PLL input clock*7 */ - #define RCC_CFGR_PLLMULL8 ((uint32_t)0x00180000) /*!< PLL input clock*8 */ - #define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock*9 */ - #define RCC_CFGR_PLLMULL10 ((uint32_t)0x00200000) /*!< PLL input clock10 */ - #define RCC_CFGR_PLLMULL11 ((uint32_t)0x00240000) /*!< PLL input clock*11 */ - #define RCC_CFGR_PLLMULL12 ((uint32_t)0x00280000) /*!< PLL input clock*12 */ - #define RCC_CFGR_PLLMULL13 ((uint32_t)0x002C0000) /*!< PLL input clock*13 */ - #define RCC_CFGR_PLLMULL14 ((uint32_t)0x00300000) /*!< PLL input clock*14 */ - #define RCC_CFGR_PLLMULL15 ((uint32_t)0x00340000) /*!< PLL input clock*15 */ - #define RCC_CFGR_PLLMULL16 ((uint32_t)0x00380000) /*!< PLL input clock*16 */ - -/*!< MCO configuration */ - #define RCC_CFGR_MCO ((uint32_t)0x07000000) /*!< MCO[2:0] bits (Microcontroller Clock Output) */ - #define RCC_CFGR_MCO_0 ((uint32_t)0x01000000) /*!< Bit 0 */ - #define RCC_CFGR_MCO_1 ((uint32_t)0x02000000) /*!< Bit 1 */ - #define RCC_CFGR_MCO_2 ((uint32_t)0x04000000) /*!< Bit 2 */ - - #define RCC_CFGR_MCO_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */ - #define RCC_CFGR_MCO_SYSCLK ((uint32_t)0x04000000) /*!< System clock selected as MCO source */ - #define RCC_CFGR_MCO_HSI ((uint32_t)0x05000000) /*!< HSI clock selected as MCO source */ - #define RCC_CFGR_MCO_HSE ((uint32_t)0x06000000) /*!< HSE clock selected as MCO source */ - #define RCC_CFGR_MCO_PLL ((uint32_t)0x07000000) /*!< PLL clock divided by 2 selected as MCO source */ -#else - #define RCC_CFGR_PLLSRC_HSI_Div2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */ - #define RCC_CFGR_PLLSRC_HSE ((uint32_t)0x00010000) /*!< HSE clock selected as PLL entry clock source */ - - #define RCC_CFGR_PLLXTPRE_HSE ((uint32_t)0x00000000) /*!< HSE clock not divided for PLL entry */ - #define RCC_CFGR_PLLXTPRE_HSE_Div2 ((uint32_t)0x00020000) /*!< HSE clock divided by 2 for PLL entry */ - - #define RCC_CFGR_PLLMULL2 ((uint32_t)0x00000000) /*!< PLL input clock*2 */ - #define RCC_CFGR_PLLMULL3 ((uint32_t)0x00040000) /*!< PLL input clock*3 */ - #define RCC_CFGR_PLLMULL4 ((uint32_t)0x00080000) /*!< PLL input clock*4 */ - #define RCC_CFGR_PLLMULL5 ((uint32_t)0x000C0000) /*!< PLL input clock*5 */ - #define RCC_CFGR_PLLMULL6 ((uint32_t)0x00100000) /*!< PLL input clock*6 */ - #define RCC_CFGR_PLLMULL7 ((uint32_t)0x00140000) /*!< PLL input clock*7 */ - #define RCC_CFGR_PLLMULL8 ((uint32_t)0x00180000) /*!< PLL input clock*8 */ - #define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock*9 */ - #define RCC_CFGR_PLLMULL10 ((uint32_t)0x00200000) /*!< PLL input clock10 */ - #define RCC_CFGR_PLLMULL11 ((uint32_t)0x00240000) /*!< PLL input clock*11 */ - #define RCC_CFGR_PLLMULL12 ((uint32_t)0x00280000) /*!< PLL input clock*12 */ - #define RCC_CFGR_PLLMULL13 ((uint32_t)0x002C0000) /*!< PLL input clock*13 */ - #define RCC_CFGR_PLLMULL14 ((uint32_t)0x00300000) /*!< PLL input clock*14 */ - #define RCC_CFGR_PLLMULL15 ((uint32_t)0x00340000) /*!< PLL input clock*15 */ - #define RCC_CFGR_PLLMULL16 ((uint32_t)0x00380000) /*!< PLL input clock*16 */ - #define RCC_CFGR_USBPRE ((uint32_t)0x00400000) /*!< USB Device prescaler */ - -/*!< MCO configuration */ - #define RCC_CFGR_MCO ((uint32_t)0x07000000) /*!< MCO[2:0] bits (Microcontroller Clock Output) */ - #define RCC_CFGR_MCO_0 ((uint32_t)0x01000000) /*!< Bit 0 */ - #define RCC_CFGR_MCO_1 ((uint32_t)0x02000000) /*!< Bit 1 */ - #define RCC_CFGR_MCO_2 ((uint32_t)0x04000000) /*!< Bit 2 */ - - #define RCC_CFGR_MCO_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */ - #define RCC_CFGR_MCO_SYSCLK ((uint32_t)0x04000000) /*!< System clock selected as MCO source */ - #define RCC_CFGR_MCO_HSI ((uint32_t)0x05000000) /*!< HSI clock selected as MCO source */ - #define RCC_CFGR_MCO_HSE ((uint32_t)0x06000000) /*!< HSE clock selected as MCO source */ - #define RCC_CFGR_MCO_PLL ((uint32_t)0x07000000) /*!< PLL clock divided by 2 selected as MCO source */ -#endif /* STM32F10X_CL */ - -/*!<****************** Bit definition for RCC_CIR register ********************/ -#define RCC_CIR_LSIRDYF ((uint32_t)0x00000001) /*!< LSI Ready Interrupt flag */ -#define RCC_CIR_LSERDYF ((uint32_t)0x00000002) /*!< LSE Ready Interrupt flag */ -#define RCC_CIR_HSIRDYF ((uint32_t)0x00000004) /*!< HSI Ready Interrupt flag */ -#define RCC_CIR_HSERDYF ((uint32_t)0x00000008) /*!< HSE Ready Interrupt flag */ -#define RCC_CIR_PLLRDYF ((uint32_t)0x00000010) /*!< PLL Ready Interrupt flag */ -#define RCC_CIR_CSSF ((uint32_t)0x00000080) /*!< Clock Security System Interrupt flag */ -#define RCC_CIR_LSIRDYIE ((uint32_t)0x00000100) /*!< LSI Ready Interrupt Enable */ -#define RCC_CIR_LSERDYIE ((uint32_t)0x00000200) /*!< LSE Ready Interrupt Enable */ -#define RCC_CIR_HSIRDYIE ((uint32_t)0x00000400) /*!< HSI Ready Interrupt Enable */ -#define RCC_CIR_HSERDYIE ((uint32_t)0x00000800) /*!< HSE Ready Interrupt Enable */ -#define RCC_CIR_PLLRDYIE ((uint32_t)0x00001000) /*!< PLL Ready Interrupt Enable */ -#define RCC_CIR_LSIRDYC ((uint32_t)0x00010000) /*!< LSI Ready Interrupt Clear */ -#define RCC_CIR_LSERDYC ((uint32_t)0x00020000) /*!< LSE Ready Interrupt Clear */ -#define RCC_CIR_HSIRDYC ((uint32_t)0x00040000) /*!< HSI Ready Interrupt Clear */ -#define RCC_CIR_HSERDYC ((uint32_t)0x00080000) /*!< HSE Ready Interrupt Clear */ -#define RCC_CIR_PLLRDYC ((uint32_t)0x00100000) /*!< PLL Ready Interrupt Clear */ -#define RCC_CIR_CSSC ((uint32_t)0x00800000) /*!< Clock Security System Interrupt Clear */ - -#ifdef STM32F10X_CL - #define RCC_CIR_PLL2RDYF ((uint32_t)0x00000020) /*!< PLL2 Ready Interrupt flag */ - #define RCC_CIR_PLL3RDYF ((uint32_t)0x00000040) /*!< PLL3 Ready Interrupt flag */ - #define RCC_CIR_PLL2RDYIE ((uint32_t)0x00002000) /*!< PLL2 Ready Interrupt Enable */ - #define RCC_CIR_PLL3RDYIE ((uint32_t)0x00004000) /*!< PLL3 Ready Interrupt Enable */ - #define RCC_CIR_PLL2RDYC ((uint32_t)0x00200000) /*!< PLL2 Ready Interrupt Clear */ - #define RCC_CIR_PLL3RDYC ((uint32_t)0x00400000) /*!< PLL3 Ready Interrupt Clear */ -#endif /* STM32F10X_CL */ - -/***************** Bit definition for RCC_APB2RSTR register *****************/ -#define RCC_APB2RSTR_AFIORST ((uint32_t)0x00000001) /*!< Alternate Function I/O reset */ -#define RCC_APB2RSTR_IOPARST ((uint32_t)0x00000004) /*!< I/O port A reset */ -#define RCC_APB2RSTR_IOPBRST ((uint32_t)0x00000008) /*!< I/O port B reset */ -#define RCC_APB2RSTR_IOPCRST ((uint32_t)0x00000010) /*!< I/O port C reset */ -#define RCC_APB2RSTR_IOPDRST ((uint32_t)0x00000020) /*!< I/O port D reset */ -#define RCC_APB2RSTR_ADC1RST ((uint32_t)0x00000200) /*!< ADC 1 interface reset */ - -#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) -#define RCC_APB2RSTR_ADC2RST ((uint32_t)0x00000400) /*!< ADC 2 interface reset */ -#endif - -#define RCC_APB2RSTR_TIM1RST ((uint32_t)0x00000800) /*!< TIM1 Timer reset */ -#define RCC_APB2RSTR_SPI1RST ((uint32_t)0x00001000) /*!< SPI 1 reset */ -#define RCC_APB2RSTR_USART1RST ((uint32_t)0x00004000) /*!< USART1 reset */ - -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) -#define RCC_APB2RSTR_TIM15RST ((uint32_t)0x00010000) /*!< TIM15 Timer reset */ -#define RCC_APB2RSTR_TIM16RST ((uint32_t)0x00020000) /*!< TIM16 Timer reset */ -#define RCC_APB2RSTR_TIM17RST ((uint32_t)0x00040000) /*!< TIM17 Timer reset */ -#endif - -#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) - #define RCC_APB2RSTR_IOPERST ((uint32_t)0x00000040) /*!< I/O port E reset */ -#endif /* STM32F10X_LD && STM32F10X_LD_VL */ - -#if defined (STM32F10X_HD) || defined (STM32F10X_XL) - #define RCC_APB2RSTR_IOPFRST ((uint32_t)0x00000080) /*!< I/O port F reset */ - #define RCC_APB2RSTR_IOPGRST ((uint32_t)0x00000100) /*!< I/O port G reset */ - #define RCC_APB2RSTR_TIM8RST ((uint32_t)0x00002000) /*!< TIM8 Timer reset */ - #define RCC_APB2RSTR_ADC3RST ((uint32_t)0x00008000) /*!< ADC3 interface reset */ -#endif - -#ifdef STM32F10X_XL - #define RCC_APB2RSTR_TIM9RST ((uint32_t)0x00080000) /*!< TIM9 Timer reset */ - #define RCC_APB2RSTR_TIM10RST ((uint32_t)0x00100000) /*!< TIM10 Timer reset */ - #define RCC_APB2RSTR_TIM11RST ((uint32_t)0x00200000) /*!< TIM11 Timer reset */ -#endif /* STM32F10X_XL */ - -/***************** Bit definition for RCC_APB1RSTR register *****************/ -#define RCC_APB1RSTR_TIM2RST ((uint32_t)0x00000001) /*!< Timer 2 reset */ -#define RCC_APB1RSTR_TIM3RST ((uint32_t)0x00000002) /*!< Timer 3 reset */ -#define RCC_APB1RSTR_WWDGRST ((uint32_t)0x00000800) /*!< Window Watchdog reset */ -#define RCC_APB1RSTR_USART2RST ((uint32_t)0x00020000) /*!< USART 2 reset */ -#define RCC_APB1RSTR_I2C1RST ((uint32_t)0x00200000) /*!< I2C 1 reset */ - -#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) -#define RCC_APB1RSTR_CAN1RST ((uint32_t)0x02000000) /*!< CAN1 reset */ -#endif - -#define RCC_APB1RSTR_BKPRST ((uint32_t)0x08000000) /*!< Backup interface reset */ -#define RCC_APB1RSTR_PWRRST ((uint32_t)0x10000000) /*!< Power interface reset */ - -#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) - #define RCC_APB1RSTR_TIM4RST ((uint32_t)0x00000004) /*!< Timer 4 reset */ - #define RCC_APB1RSTR_SPI2RST ((uint32_t)0x00004000) /*!< SPI 2 reset */ - #define RCC_APB1RSTR_USART3RST ((uint32_t)0x00040000) /*!< RUSART 3 reset */ - #define RCC_APB1RSTR_I2C2RST ((uint32_t)0x00400000) /*!< I2C 2 reset */ -#endif /* STM32F10X_LD && STM32F10X_LD_VL */ - -#if defined (STM32F10X_HD) || defined (STM32F10X_MD) || defined (STM32F10X_LD) || defined (STM32F10X_XL) - #define RCC_APB1RSTR_USBRST ((uint32_t)0x00800000) /*!< USB Device reset */ -#endif - -#if defined (STM32F10X_HD) || defined (STM32F10X_CL) || defined (STM32F10X_XL) - #define RCC_APB1RSTR_TIM5RST ((uint32_t)0x00000008) /*!< Timer 5 reset */ - #define RCC_APB1RSTR_TIM6RST ((uint32_t)0x00000010) /*!< Timer 6 reset */ - #define RCC_APB1RSTR_TIM7RST ((uint32_t)0x00000020) /*!< Timer 7 reset */ - #define RCC_APB1RSTR_SPI3RST ((uint32_t)0x00008000) /*!< SPI 3 reset */ - #define RCC_APB1RSTR_UART4RST ((uint32_t)0x00080000) /*!< UART 4 reset */ - #define RCC_APB1RSTR_UART5RST ((uint32_t)0x00100000) /*!< UART 5 reset */ - #define RCC_APB1RSTR_DACRST ((uint32_t)0x20000000) /*!< DAC interface reset */ -#endif - -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) - #define RCC_APB1RSTR_TIM6RST ((uint32_t)0x00000010) /*!< Timer 6 reset */ - #define RCC_APB1RSTR_TIM7RST ((uint32_t)0x00000020) /*!< Timer 7 reset */ - #define RCC_APB1RSTR_DACRST ((uint32_t)0x20000000) /*!< DAC interface reset */ - #define RCC_APB1RSTR_CECRST ((uint32_t)0x40000000) /*!< CEC interface reset */ -#endif - -#ifdef STM32F10X_CL - #define RCC_APB1RSTR_CAN2RST ((uint32_t)0x04000000) /*!< CAN2 reset */ -#endif /* STM32F10X_CL */ - -#ifdef STM32F10X_XL - #define RCC_APB1RSTR_TIM12RST ((uint32_t)0x00000040) /*!< TIM12 Timer reset */ - #define RCC_APB1RSTR_TIM13RST ((uint32_t)0x00000080) /*!< TIM13 Timer reset */ - #define RCC_APB1RSTR_TIM14RST ((uint32_t)0x00000100) /*!< TIM14 Timer reset */ -#endif /* STM32F10X_XL */ - -/****************** Bit definition for RCC_AHBENR register ******************/ -#define RCC_AHBENR_DMA1EN ((uint16_t)0x0001) /*!< DMA1 clock enable */ -#define RCC_AHBENR_SRAMEN ((uint16_t)0x0004) /*!< SRAM interface clock enable */ -#define RCC_AHBENR_FLITFEN ((uint16_t)0x0010) /*!< FLITF clock enable */ -#define RCC_AHBENR_CRCEN ((uint16_t)0x0040) /*!< CRC clock enable */ - -#if defined (STM32F10X_HD) || defined (STM32F10X_CL) - #define RCC_AHBENR_DMA2EN ((uint16_t)0x0002) /*!< DMA2 clock enable */ -#endif - -#if defined (STM32F10X_HD) || defined (STM32F10X_XL) - #define RCC_AHBENR_FSMCEN ((uint16_t)0x0100) /*!< FSMC clock enable */ - #define RCC_AHBENR_SDIOEN ((uint16_t)0x0400) /*!< SDIO clock enable */ -#endif - -#ifdef STM32F10X_CL - #define RCC_AHBENR_OTGFSEN ((uint32_t)0x00001000) /*!< USB OTG FS clock enable */ - #define RCC_AHBENR_ETHMACEN ((uint32_t)0x00004000) /*!< ETHERNET MAC clock enable */ - #define RCC_AHBENR_ETHMACTXEN ((uint32_t)0x00008000) /*!< ETHERNET MAC Tx clock enable */ - #define RCC_AHBENR_ETHMACRXEN ((uint32_t)0x00010000) /*!< ETHERNET MAC Rx clock enable */ -#endif /* STM32F10X_CL */ - -/****************** Bit definition for RCC_APB2ENR register *****************/ -#define RCC_APB2ENR_AFIOEN ((uint32_t)0x00000001) /*!< Alternate Function I/O clock enable */ -#define RCC_APB2ENR_IOPAEN ((uint32_t)0x00000004) /*!< I/O port A clock enable */ -#define RCC_APB2ENR_IOPBEN ((uint32_t)0x00000008) /*!< I/O port B clock enable */ -#define RCC_APB2ENR_IOPCEN ((uint32_t)0x00000010) /*!< I/O port C clock enable */ -#define RCC_APB2ENR_IOPDEN ((uint32_t)0x00000020) /*!< I/O port D clock enable */ -#define RCC_APB2ENR_ADC1EN ((uint32_t)0x00000200) /*!< ADC 1 interface clock enable */ - -#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) -#define RCC_APB2ENR_ADC2EN ((uint32_t)0x00000400) /*!< ADC 2 interface clock enable */ -#endif - -#define RCC_APB2ENR_TIM1EN ((uint32_t)0x00000800) /*!< TIM1 Timer clock enable */ -#define RCC_APB2ENR_SPI1EN ((uint32_t)0x00001000) /*!< SPI 1 clock enable */ -#define RCC_APB2ENR_USART1EN ((uint32_t)0x00004000) /*!< USART1 clock enable */ - -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) -#define RCC_APB2ENR_TIM15EN ((uint32_t)0x00010000) /*!< TIM15 Timer clock enable */ -#define RCC_APB2ENR_TIM16EN ((uint32_t)0x00020000) /*!< TIM16 Timer clock enable */ -#define RCC_APB2ENR_TIM17EN ((uint32_t)0x00040000) /*!< TIM17 Timer clock enable */ -#endif - -#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) - #define RCC_APB2ENR_IOPEEN ((uint32_t)0x00000040) /*!< I/O port E clock enable */ -#endif /* STM32F10X_LD && STM32F10X_LD_VL */ - -#if defined (STM32F10X_HD) || defined (STM32F10X_XL) - #define RCC_APB2ENR_IOPFEN ((uint32_t)0x00000080) /*!< I/O port F clock enable */ - #define RCC_APB2ENR_IOPGEN ((uint32_t)0x00000100) /*!< I/O port G clock enable */ - #define RCC_APB2ENR_TIM8EN ((uint32_t)0x00002000) /*!< TIM8 Timer clock enable */ - #define RCC_APB2ENR_ADC3EN ((uint32_t)0x00008000) /*!< DMA1 clock enable */ -#endif - -#ifdef STM32F10X_XL - #define RCC_APB2ENR_TIM9EN ((uint32_t)0x00080000) /*!< TIM9 Timer clock enable */ - #define RCC_APB2ENR_TIM10EN ((uint32_t)0x00100000) /*!< TIM10 Timer clock enable */ - #define RCC_APB2ENR_TIM11EN ((uint32_t)0x00200000) /*!< TIM11 Timer clock enable */ -#endif - -/***************** Bit definition for RCC_APB1ENR register ******************/ -#define RCC_APB1ENR_TIM2EN ((uint32_t)0x00000001) /*!< Timer 2 clock enabled*/ -#define RCC_APB1ENR_TIM3EN ((uint32_t)0x00000002) /*!< Timer 3 clock enable */ -#define RCC_APB1ENR_WWDGEN ((uint32_t)0x00000800) /*!< Window Watchdog clock enable */ -#define RCC_APB1ENR_USART2EN ((uint32_t)0x00020000) /*!< USART 2 clock enable */ -#define RCC_APB1ENR_I2C1EN ((uint32_t)0x00200000) /*!< I2C 1 clock enable */ - -#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) -#define RCC_APB1ENR_CAN1EN ((uint32_t)0x02000000) /*!< CAN1 clock enable */ -#endif - -#define RCC_APB1ENR_BKPEN ((uint32_t)0x08000000) /*!< Backup interface clock enable */ -#define RCC_APB1ENR_PWREN ((uint32_t)0x10000000) /*!< Power interface clock enable */ - -#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) - #define RCC_APB1ENR_TIM4EN ((uint32_t)0x00000004) /*!< Timer 4 clock enable */ - #define RCC_APB1ENR_SPI2EN ((uint32_t)0x00004000) /*!< SPI 2 clock enable */ - #define RCC_APB1ENR_USART3EN ((uint32_t)0x00040000) /*!< USART 3 clock enable */ - #define RCC_APB1ENR_I2C2EN ((uint32_t)0x00400000) /*!< I2C 2 clock enable */ -#endif /* STM32F10X_LD && STM32F10X_LD_VL */ - -#if defined (STM32F10X_HD) || defined (STM32F10X_MD) || defined (STM32F10X_LD) - #define RCC_APB1ENR_USBEN ((uint32_t)0x00800000) /*!< USB Device clock enable */ -#endif - -#if defined (STM32F10X_HD) || defined (STM32F10X_CL) - #define RCC_APB1ENR_TIM5EN ((uint32_t)0x00000008) /*!< Timer 5 clock enable */ - #define RCC_APB1ENR_TIM6EN ((uint32_t)0x00000010) /*!< Timer 6 clock enable */ - #define RCC_APB1ENR_TIM7EN ((uint32_t)0x00000020) /*!< Timer 7 clock enable */ - #define RCC_APB1ENR_SPI3EN ((uint32_t)0x00008000) /*!< SPI 3 clock enable */ - #define RCC_APB1ENR_UART4EN ((uint32_t)0x00080000) /*!< UART 4 clock enable */ - #define RCC_APB1ENR_UART5EN ((uint32_t)0x00100000) /*!< UART 5 clock enable */ - #define RCC_APB1ENR_DACEN ((uint32_t)0x20000000) /*!< DAC interface clock enable */ -#endif - -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) - #define RCC_APB1ENR_TIM6EN ((uint32_t)0x00000010) /*!< Timer 6 clock enable */ - #define RCC_APB1ENR_TIM7EN ((uint32_t)0x00000020) /*!< Timer 7 clock enable */ - #define RCC_APB1ENR_DACEN ((uint32_t)0x20000000) /*!< DAC interface clock enable */ - #define RCC_APB1ENR_CECEN ((uint32_t)0x40000000) /*!< CEC interface clock enable */ -#endif - -#ifdef STM32F10X_CL - #define RCC_APB1ENR_CAN2EN ((uint32_t)0x04000000) /*!< CAN2 clock enable */ -#endif /* STM32F10X_CL */ - -#ifdef STM32F10X_XL - #define RCC_APB1ENR_TIM12EN ((uint32_t)0x00000040) /*!< TIM12 Timer clock enable */ - #define RCC_APB1ENR_TIM13EN ((uint32_t)0x00000080) /*!< TIM13 Timer clock enable */ - #define RCC_APB1ENR_TIM14EN ((uint32_t)0x00000100) /*!< TIM14 Timer clock enable */ -#endif /* STM32F10X_XL */ - -/******************* Bit definition for RCC_BDCR register *******************/ -#define RCC_BDCR_LSEON ((uint32_t)0x00000001) /*!< External Low Speed oscillator enable */ -#define RCC_BDCR_LSERDY ((uint32_t)0x00000002) /*!< External Low Speed oscillator Ready */ -#define RCC_BDCR_LSEBYP ((uint32_t)0x00000004) /*!< External Low Speed oscillator Bypass */ - -#define RCC_BDCR_RTCSEL ((uint32_t)0x00000300) /*!< RTCSEL[1:0] bits (RTC clock source selection) */ -#define RCC_BDCR_RTCSEL_0 ((uint32_t)0x00000100) /*!< Bit 0 */ -#define RCC_BDCR_RTCSEL_1 ((uint32_t)0x00000200) /*!< Bit 1 */ - -/*!< RTC congiguration */ -#define RCC_BDCR_RTCSEL_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */ -#define RCC_BDCR_RTCSEL_LSE ((uint32_t)0x00000100) /*!< LSE oscillator clock used as RTC clock */ -#define RCC_BDCR_RTCSEL_LSI ((uint32_t)0x00000200) /*!< LSI oscillator clock used as RTC clock */ -#define RCC_BDCR_RTCSEL_HSE ((uint32_t)0x00000300) /*!< HSE oscillator clock divided by 128 used as RTC clock */ - -#define RCC_BDCR_RTCEN ((uint32_t)0x00008000) /*!< RTC clock enable */ -#define RCC_BDCR_BDRST ((uint32_t)0x00010000) /*!< Backup domain software reset */ - -/******************* Bit definition for RCC_CSR register ********************/ -#define RCC_CSR_LSION ((uint32_t)0x00000001) /*!< Internal Low Speed oscillator enable */ -#define RCC_CSR_LSIRDY ((uint32_t)0x00000002) /*!< Internal Low Speed oscillator Ready */ -#define RCC_CSR_RMVF ((uint32_t)0x01000000) /*!< Remove reset flag */ -#define RCC_CSR_PINRSTF ((uint32_t)0x04000000) /*!< PIN reset flag */ -#define RCC_CSR_PORRSTF ((uint32_t)0x08000000) /*!< POR/PDR reset flag */ -#define RCC_CSR_SFTRSTF ((uint32_t)0x10000000) /*!< Software Reset flag */ -#define RCC_CSR_IWDGRSTF ((uint32_t)0x20000000) /*!< Independent Watchdog reset flag */ -#define RCC_CSR_WWDGRSTF ((uint32_t)0x40000000) /*!< Window watchdog reset flag */ -#define RCC_CSR_LPWRRSTF ((uint32_t)0x80000000) /*!< Low-Power reset flag */ - -#ifdef STM32F10X_CL -/******************* Bit definition for RCC_AHBRSTR register ****************/ - #define RCC_AHBRSTR_OTGFSRST ((uint32_t)0x00001000) /*!< USB OTG FS reset */ - #define RCC_AHBRSTR_ETHMACRST ((uint32_t)0x00004000) /*!< ETHERNET MAC reset */ - -/******************* Bit definition for RCC_CFGR2 register ******************/ -/*!< PREDIV1 configuration */ - #define RCC_CFGR2_PREDIV1 ((uint32_t)0x0000000F) /*!< PREDIV1[3:0] bits */ - #define RCC_CFGR2_PREDIV1_0 ((uint32_t)0x00000001) /*!< Bit 0 */ - #define RCC_CFGR2_PREDIV1_1 ((uint32_t)0x00000002) /*!< Bit 1 */ - #define RCC_CFGR2_PREDIV1_2 ((uint32_t)0x00000004) /*!< Bit 2 */ - #define RCC_CFGR2_PREDIV1_3 ((uint32_t)0x00000008) /*!< Bit 3 */ - - #define RCC_CFGR2_PREDIV1_DIV1 ((uint32_t)0x00000000) /*!< PREDIV1 input clock not divided */ - #define RCC_CFGR2_PREDIV1_DIV2 ((uint32_t)0x00000001) /*!< PREDIV1 input clock divided by 2 */ - #define RCC_CFGR2_PREDIV1_DIV3 ((uint32_t)0x00000002) /*!< PREDIV1 input clock divided by 3 */ - #define RCC_CFGR2_PREDIV1_DIV4 ((uint32_t)0x00000003) /*!< PREDIV1 input clock divided by 4 */ - #define RCC_CFGR2_PREDIV1_DIV5 ((uint32_t)0x00000004) /*!< PREDIV1 input clock divided by 5 */ - #define RCC_CFGR2_PREDIV1_DIV6 ((uint32_t)0x00000005) /*!< PREDIV1 input clock divided by 6 */ - #define RCC_CFGR2_PREDIV1_DIV7 ((uint32_t)0x00000006) /*!< PREDIV1 input clock divided by 7 */ - #define RCC_CFGR2_PREDIV1_DIV8 ((uint32_t)0x00000007) /*!< PREDIV1 input clock divided by 8 */ - #define RCC_CFGR2_PREDIV1_DIV9 ((uint32_t)0x00000008) /*!< PREDIV1 input clock divided by 9 */ - #define RCC_CFGR2_PREDIV1_DIV10 ((uint32_t)0x00000009) /*!< PREDIV1 input clock divided by 10 */ - #define RCC_CFGR2_PREDIV1_DIV11 ((uint32_t)0x0000000A) /*!< PREDIV1 input clock divided by 11 */ - #define RCC_CFGR2_PREDIV1_DIV12 ((uint32_t)0x0000000B) /*!< PREDIV1 input clock divided by 12 */ - #define RCC_CFGR2_PREDIV1_DIV13 ((uint32_t)0x0000000C) /*!< PREDIV1 input clock divided by 13 */ - #define RCC_CFGR2_PREDIV1_DIV14 ((uint32_t)0x0000000D) /*!< PREDIV1 input clock divided by 14 */ - #define RCC_CFGR2_PREDIV1_DIV15 ((uint32_t)0x0000000E) /*!< PREDIV1 input clock divided by 15 */ - #define RCC_CFGR2_PREDIV1_DIV16 ((uint32_t)0x0000000F) /*!< PREDIV1 input clock divided by 16 */ - -/*!< PREDIV2 configuration */ - #define RCC_CFGR2_PREDIV2 ((uint32_t)0x000000F0) /*!< PREDIV2[3:0] bits */ - #define RCC_CFGR2_PREDIV2_0 ((uint32_t)0x00000010) /*!< Bit 0 */ - #define RCC_CFGR2_PREDIV2_1 ((uint32_t)0x00000020) /*!< Bit 1 */ - #define RCC_CFGR2_PREDIV2_2 ((uint32_t)0x00000040) /*!< Bit 2 */ - #define RCC_CFGR2_PREDIV2_3 ((uint32_t)0x00000080) /*!< Bit 3 */ - - #define RCC_CFGR2_PREDIV2_DIV1 ((uint32_t)0x00000000) /*!< PREDIV2 input clock not divided */ - #define RCC_CFGR2_PREDIV2_DIV2 ((uint32_t)0x00000010) /*!< PREDIV2 input clock divided by 2 */ - #define RCC_CFGR2_PREDIV2_DIV3 ((uint32_t)0x00000020) /*!< PREDIV2 input clock divided by 3 */ - #define RCC_CFGR2_PREDIV2_DIV4 ((uint32_t)0x00000030) /*!< PREDIV2 input clock divided by 4 */ - #define RCC_CFGR2_PREDIV2_DIV5 ((uint32_t)0x00000040) /*!< PREDIV2 input clock divided by 5 */ - #define RCC_CFGR2_PREDIV2_DIV6 ((uint32_t)0x00000050) /*!< PREDIV2 input clock divided by 6 */ - #define RCC_CFGR2_PREDIV2_DIV7 ((uint32_t)0x00000060) /*!< PREDIV2 input clock divided by 7 */ - #define RCC_CFGR2_PREDIV2_DIV8 ((uint32_t)0x00000070) /*!< PREDIV2 input clock divided by 8 */ - #define RCC_CFGR2_PREDIV2_DIV9 ((uint32_t)0x00000080) /*!< PREDIV2 input clock divided by 9 */ - #define RCC_CFGR2_PREDIV2_DIV10 ((uint32_t)0x00000090) /*!< PREDIV2 input clock divided by 10 */ - #define RCC_CFGR2_PREDIV2_DIV11 ((uint32_t)0x000000A0) /*!< PREDIV2 input clock divided by 11 */ - #define RCC_CFGR2_PREDIV2_DIV12 ((uint32_t)0x000000B0) /*!< PREDIV2 input clock divided by 12 */ - #define RCC_CFGR2_PREDIV2_DIV13 ((uint32_t)0x000000C0) /*!< PREDIV2 input clock divided by 13 */ - #define RCC_CFGR2_PREDIV2_DIV14 ((uint32_t)0x000000D0) /*!< PREDIV2 input clock divided by 14 */ - #define RCC_CFGR2_PREDIV2_DIV15 ((uint32_t)0x000000E0) /*!< PREDIV2 input clock divided by 15 */ - #define RCC_CFGR2_PREDIV2_DIV16 ((uint32_t)0x000000F0) /*!< PREDIV2 input clock divided by 16 */ - -/*!< PLL2MUL configuration */ - #define RCC_CFGR2_PLL2MUL ((uint32_t)0x00000F00) /*!< PLL2MUL[3:0] bits */ - #define RCC_CFGR2_PLL2MUL_0 ((uint32_t)0x00000100) /*!< Bit 0 */ - #define RCC_CFGR2_PLL2MUL_1 ((uint32_t)0x00000200) /*!< Bit 1 */ - #define RCC_CFGR2_PLL2MUL_2 ((uint32_t)0x00000400) /*!< Bit 2 */ - #define RCC_CFGR2_PLL2MUL_3 ((uint32_t)0x00000800) /*!< Bit 3 */ - - #define RCC_CFGR2_PLL2MUL8 ((uint32_t)0x00000600) /*!< PLL2 input clock * 8 */ - #define RCC_CFGR2_PLL2MUL9 ((uint32_t)0x00000700) /*!< PLL2 input clock * 9 */ - #define RCC_CFGR2_PLL2MUL10 ((uint32_t)0x00000800) /*!< PLL2 input clock * 10 */ - #define RCC_CFGR2_PLL2MUL11 ((uint32_t)0x00000900) /*!< PLL2 input clock * 11 */ - #define RCC_CFGR2_PLL2MUL12 ((uint32_t)0x00000A00) /*!< PLL2 input clock * 12 */ - #define RCC_CFGR2_PLL2MUL13 ((uint32_t)0x00000B00) /*!< PLL2 input clock * 13 */ - #define RCC_CFGR2_PLL2MUL14 ((uint32_t)0x00000C00) /*!< PLL2 input clock * 14 */ - #define RCC_CFGR2_PLL2MUL16 ((uint32_t)0x00000E00) /*!< PLL2 input clock * 16 */ - #define RCC_CFGR2_PLL2MUL20 ((uint32_t)0x00000F00) /*!< PLL2 input clock * 20 */ - -/*!< PLL3MUL configuration */ - #define RCC_CFGR2_PLL3MUL ((uint32_t)0x0000F000) /*!< PLL3MUL[3:0] bits */ - #define RCC_CFGR2_PLL3MUL_0 ((uint32_t)0x00001000) /*!< Bit 0 */ - #define RCC_CFGR2_PLL3MUL_1 ((uint32_t)0x00002000) /*!< Bit 1 */ - #define RCC_CFGR2_PLL3MUL_2 ((uint32_t)0x00004000) /*!< Bit 2 */ - #define RCC_CFGR2_PLL3MUL_3 ((uint32_t)0x00008000) /*!< Bit 3 */ - - #define RCC_CFGR2_PLL3MUL8 ((uint32_t)0x00006000) /*!< PLL3 input clock * 8 */ - #define RCC_CFGR2_PLL3MUL9 ((uint32_t)0x00007000) /*!< PLL3 input clock * 9 */ - #define RCC_CFGR2_PLL3MUL10 ((uint32_t)0x00008000) /*!< PLL3 input clock * 10 */ - #define RCC_CFGR2_PLL3MUL11 ((uint32_t)0x00009000) /*!< PLL3 input clock * 11 */ - #define RCC_CFGR2_PLL3MUL12 ((uint32_t)0x0000A000) /*!< PLL3 input clock * 12 */ - #define RCC_CFGR2_PLL3MUL13 ((uint32_t)0x0000B000) /*!< PLL3 input clock * 13 */ - #define RCC_CFGR2_PLL3MUL14 ((uint32_t)0x0000C000) /*!< PLL3 input clock * 14 */ - #define RCC_CFGR2_PLL3MUL16 ((uint32_t)0x0000E000) /*!< PLL3 input clock * 16 */ - #define RCC_CFGR2_PLL3MUL20 ((uint32_t)0x0000F000) /*!< PLL3 input clock * 20 */ - - #define RCC_CFGR2_PREDIV1SRC ((uint32_t)0x00010000) /*!< PREDIV1 entry clock source */ - #define RCC_CFGR2_PREDIV1SRC_PLL2 ((uint32_t)0x00010000) /*!< PLL2 selected as PREDIV1 entry clock source */ - #define RCC_CFGR2_PREDIV1SRC_HSE ((uint32_t)0x00000000) /*!< HSE selected as PREDIV1 entry clock source */ - #define RCC_CFGR2_I2S2SRC ((uint32_t)0x00020000) /*!< I2S2 entry clock source */ - #define RCC_CFGR2_I2S3SRC ((uint32_t)0x00040000) /*!< I2S3 clock source */ -#endif /* STM32F10X_CL */ - -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) -/******************* Bit definition for RCC_CFGR2 register ******************/ -/*!< PREDIV1 configuration */ - #define RCC_CFGR2_PREDIV1 ((uint32_t)0x0000000F) /*!< PREDIV1[3:0] bits */ - #define RCC_CFGR2_PREDIV1_0 ((uint32_t)0x00000001) /*!< Bit 0 */ - #define RCC_CFGR2_PREDIV1_1 ((uint32_t)0x00000002) /*!< Bit 1 */ - #define RCC_CFGR2_PREDIV1_2 ((uint32_t)0x00000004) /*!< Bit 2 */ - #define RCC_CFGR2_PREDIV1_3 ((uint32_t)0x00000008) /*!< Bit 3 */ - - #define RCC_CFGR2_PREDIV1_DIV1 ((uint32_t)0x00000000) /*!< PREDIV1 input clock not divided */ - #define RCC_CFGR2_PREDIV1_DIV2 ((uint32_t)0x00000001) /*!< PREDIV1 input clock divided by 2 */ - #define RCC_CFGR2_PREDIV1_DIV3 ((uint32_t)0x00000002) /*!< PREDIV1 input clock divided by 3 */ - #define RCC_CFGR2_PREDIV1_DIV4 ((uint32_t)0x00000003) /*!< PREDIV1 input clock divided by 4 */ - #define RCC_CFGR2_PREDIV1_DIV5 ((uint32_t)0x00000004) /*!< PREDIV1 input clock divided by 5 */ - #define RCC_CFGR2_PREDIV1_DIV6 ((uint32_t)0x00000005) /*!< PREDIV1 input clock divided by 6 */ - #define RCC_CFGR2_PREDIV1_DIV7 ((uint32_t)0x00000006) /*!< PREDIV1 input clock divided by 7 */ - #define RCC_CFGR2_PREDIV1_DIV8 ((uint32_t)0x00000007) /*!< PREDIV1 input clock divided by 8 */ - #define RCC_CFGR2_PREDIV1_DIV9 ((uint32_t)0x00000008) /*!< PREDIV1 input clock divided by 9 */ - #define RCC_CFGR2_PREDIV1_DIV10 ((uint32_t)0x00000009) /*!< PREDIV1 input clock divided by 10 */ - #define RCC_CFGR2_PREDIV1_DIV11 ((uint32_t)0x0000000A) /*!< PREDIV1 input clock divided by 11 */ - #define RCC_CFGR2_PREDIV1_DIV12 ((uint32_t)0x0000000B) /*!< PREDIV1 input clock divided by 12 */ - #define RCC_CFGR2_PREDIV1_DIV13 ((uint32_t)0x0000000C) /*!< PREDIV1 input clock divided by 13 */ - #define RCC_CFGR2_PREDIV1_DIV14 ((uint32_t)0x0000000D) /*!< PREDIV1 input clock divided by 14 */ - #define RCC_CFGR2_PREDIV1_DIV15 ((uint32_t)0x0000000E) /*!< PREDIV1 input clock divided by 15 */ - #define RCC_CFGR2_PREDIV1_DIV16 ((uint32_t)0x0000000F) /*!< PREDIV1 input clock divided by 16 */ -#endif - -/******************************************************************************/ -/* */ -/* General Purpose and Alternate Function I/O */ -/* */ -/******************************************************************************/ - -/******************* Bit definition for GPIO_CRL register *******************/ -#define GPIO_CRL_MODE ((uint32_t)0x33333333) /*!< Port x mode bits */ - -#define GPIO_CRL_MODE0 ((uint32_t)0x00000003) /*!< MODE0[1:0] bits (Port x mode bits, pin 0) */ -#define GPIO_CRL_MODE0_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define GPIO_CRL_MODE0_1 ((uint32_t)0x00000002) /*!< Bit 1 */ - -#define GPIO_CRL_MODE1 ((uint32_t)0x00000030) /*!< MODE1[1:0] bits (Port x mode bits, pin 1) */ -#define GPIO_CRL_MODE1_0 ((uint32_t)0x00000010) /*!< Bit 0 */ -#define GPIO_CRL_MODE1_1 ((uint32_t)0x00000020) /*!< Bit 1 */ - -#define GPIO_CRL_MODE2 ((uint32_t)0x00000300) /*!< MODE2[1:0] bits (Port x mode bits, pin 2) */ -#define GPIO_CRL_MODE2_0 ((uint32_t)0x00000100) /*!< Bit 0 */ -#define GPIO_CRL_MODE2_1 ((uint32_t)0x00000200) /*!< Bit 1 */ - -#define GPIO_CRL_MODE3 ((uint32_t)0x00003000) /*!< MODE3[1:0] bits (Port x mode bits, pin 3) */ -#define GPIO_CRL_MODE3_0 ((uint32_t)0x00001000) /*!< Bit 0 */ -#define GPIO_CRL_MODE3_1 ((uint32_t)0x00002000) /*!< Bit 1 */ - -#define GPIO_CRL_MODE4 ((uint32_t)0x00030000) /*!< MODE4[1:0] bits (Port x mode bits, pin 4) */ -#define GPIO_CRL_MODE4_0 ((uint32_t)0x00010000) /*!< Bit 0 */ -#define GPIO_CRL_MODE4_1 ((uint32_t)0x00020000) /*!< Bit 1 */ - -#define GPIO_CRL_MODE5 ((uint32_t)0x00300000) /*!< MODE5[1:0] bits (Port x mode bits, pin 5) */ -#define GPIO_CRL_MODE5_0 ((uint32_t)0x00100000) /*!< Bit 0 */ -#define GPIO_CRL_MODE5_1 ((uint32_t)0x00200000) /*!< Bit 1 */ - -#define GPIO_CRL_MODE6 ((uint32_t)0x03000000) /*!< MODE6[1:0] bits (Port x mode bits, pin 6) */ -#define GPIO_CRL_MODE6_0 ((uint32_t)0x01000000) /*!< Bit 0 */ -#define GPIO_CRL_MODE6_1 ((uint32_t)0x02000000) /*!< Bit 1 */ - -#define GPIO_CRL_MODE7 ((uint32_t)0x30000000) /*!< MODE7[1:0] bits (Port x mode bits, pin 7) */ -#define GPIO_CRL_MODE7_0 ((uint32_t)0x10000000) /*!< Bit 0 */ -#define GPIO_CRL_MODE7_1 ((uint32_t)0x20000000) /*!< Bit 1 */ - -#define GPIO_CRL_CNF ((uint32_t)0xCCCCCCCC) /*!< Port x configuration bits */ - -#define GPIO_CRL_CNF0 ((uint32_t)0x0000000C) /*!< CNF0[1:0] bits (Port x configuration bits, pin 0) */ -#define GPIO_CRL_CNF0_0 ((uint32_t)0x00000004) /*!< Bit 0 */ -#define GPIO_CRL_CNF0_1 ((uint32_t)0x00000008) /*!< Bit 1 */ - -#define GPIO_CRL_CNF1 ((uint32_t)0x000000C0) /*!< CNF1[1:0] bits (Port x configuration bits, pin 1) */ -#define GPIO_CRL_CNF1_0 ((uint32_t)0x00000040) /*!< Bit 0 */ -#define GPIO_CRL_CNF1_1 ((uint32_t)0x00000080) /*!< Bit 1 */ - -#define GPIO_CRL_CNF2 ((uint32_t)0x00000C00) /*!< CNF2[1:0] bits (Port x configuration bits, pin 2) */ -#define GPIO_CRL_CNF2_0 ((uint32_t)0x00000400) /*!< Bit 0 */ -#define GPIO_CRL_CNF2_1 ((uint32_t)0x00000800) /*!< Bit 1 */ - -#define GPIO_CRL_CNF3 ((uint32_t)0x0000C000) /*!< CNF3[1:0] bits (Port x configuration bits, pin 3) */ -#define GPIO_CRL_CNF3_0 ((uint32_t)0x00004000) /*!< Bit 0 */ -#define GPIO_CRL_CNF3_1 ((uint32_t)0x00008000) /*!< Bit 1 */ - -#define GPIO_CRL_CNF4 ((uint32_t)0x000C0000) /*!< CNF4[1:0] bits (Port x configuration bits, pin 4) */ -#define GPIO_CRL_CNF4_0 ((uint32_t)0x00040000) /*!< Bit 0 */ -#define GPIO_CRL_CNF4_1 ((uint32_t)0x00080000) /*!< Bit 1 */ - -#define GPIO_CRL_CNF5 ((uint32_t)0x00C00000) /*!< CNF5[1:0] bits (Port x configuration bits, pin 5) */ -#define GPIO_CRL_CNF5_0 ((uint32_t)0x00400000) /*!< Bit 0 */ -#define GPIO_CRL_CNF5_1 ((uint32_t)0x00800000) /*!< Bit 1 */ - -#define GPIO_CRL_CNF6 ((uint32_t)0x0C000000) /*!< CNF6[1:0] bits (Port x configuration bits, pin 6) */ -#define GPIO_CRL_CNF6_0 ((uint32_t)0x04000000) /*!< Bit 0 */ -#define GPIO_CRL_CNF6_1 ((uint32_t)0x08000000) /*!< Bit 1 */ - -#define GPIO_CRL_CNF7 ((uint32_t)0xC0000000) /*!< CNF7[1:0] bits (Port x configuration bits, pin 7) */ -#define GPIO_CRL_CNF7_0 ((uint32_t)0x40000000) /*!< Bit 0 */ -#define GPIO_CRL_CNF7_1 ((uint32_t)0x80000000) /*!< Bit 1 */ - -/******************* Bit definition for GPIO_CRH register *******************/ -#define GPIO_CRH_MODE ((uint32_t)0x33333333) /*!< Port x mode bits */ - -#define GPIO_CRH_MODE8 ((uint32_t)0x00000003) /*!< MODE8[1:0] bits (Port x mode bits, pin 8) */ -#define GPIO_CRH_MODE8_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define GPIO_CRH_MODE8_1 ((uint32_t)0x00000002) /*!< Bit 1 */ - -#define GPIO_CRH_MODE9 ((uint32_t)0x00000030) /*!< MODE9[1:0] bits (Port x mode bits, pin 9) */ -#define GPIO_CRH_MODE9_0 ((uint32_t)0x00000010) /*!< Bit 0 */ -#define GPIO_CRH_MODE9_1 ((uint32_t)0x00000020) /*!< Bit 1 */ - -#define GPIO_CRH_MODE10 ((uint32_t)0x00000300) /*!< MODE10[1:0] bits (Port x mode bits, pin 10) */ -#define GPIO_CRH_MODE10_0 ((uint32_t)0x00000100) /*!< Bit 0 */ -#define GPIO_CRH_MODE10_1 ((uint32_t)0x00000200) /*!< Bit 1 */ - -#define GPIO_CRH_MODE11 ((uint32_t)0x00003000) /*!< MODE11[1:0] bits (Port x mode bits, pin 11) */ -#define GPIO_CRH_MODE11_0 ((uint32_t)0x00001000) /*!< Bit 0 */ -#define GPIO_CRH_MODE11_1 ((uint32_t)0x00002000) /*!< Bit 1 */ - -#define GPIO_CRH_MODE12 ((uint32_t)0x00030000) /*!< MODE12[1:0] bits (Port x mode bits, pin 12) */ -#define GPIO_CRH_MODE12_0 ((uint32_t)0x00010000) /*!< Bit 0 */ -#define GPIO_CRH_MODE12_1 ((uint32_t)0x00020000) /*!< Bit 1 */ - -#define GPIO_CRH_MODE13 ((uint32_t)0x00300000) /*!< MODE13[1:0] bits (Port x mode bits, pin 13) */ -#define GPIO_CRH_MODE13_0 ((uint32_t)0x00100000) /*!< Bit 0 */ -#define GPIO_CRH_MODE13_1 ((uint32_t)0x00200000) /*!< Bit 1 */ - -#define GPIO_CRH_MODE14 ((uint32_t)0x03000000) /*!< MODE14[1:0] bits (Port x mode bits, pin 14) */ -#define GPIO_CRH_MODE14_0 ((uint32_t)0x01000000) /*!< Bit 0 */ -#define GPIO_CRH_MODE14_1 ((uint32_t)0x02000000) /*!< Bit 1 */ - -#define GPIO_CRH_MODE15 ((uint32_t)0x30000000) /*!< MODE15[1:0] bits (Port x mode bits, pin 15) */ -#define GPIO_CRH_MODE15_0 ((uint32_t)0x10000000) /*!< Bit 0 */ -#define GPIO_CRH_MODE15_1 ((uint32_t)0x20000000) /*!< Bit 1 */ - -#define GPIO_CRH_CNF ((uint32_t)0xCCCCCCCC) /*!< Port x configuration bits */ - -#define GPIO_CRH_CNF8 ((uint32_t)0x0000000C) /*!< CNF8[1:0] bits (Port x configuration bits, pin 8) */ -#define GPIO_CRH_CNF8_0 ((uint32_t)0x00000004) /*!< Bit 0 */ -#define GPIO_CRH_CNF8_1 ((uint32_t)0x00000008) /*!< Bit 1 */ - -#define GPIO_CRH_CNF9 ((uint32_t)0x000000C0) /*!< CNF9[1:0] bits (Port x configuration bits, pin 9) */ -#define GPIO_CRH_CNF9_0 ((uint32_t)0x00000040) /*!< Bit 0 */ -#define GPIO_CRH_CNF9_1 ((uint32_t)0x00000080) /*!< Bit 1 */ - -#define GPIO_CRH_CNF10 ((uint32_t)0x00000C00) /*!< CNF10[1:0] bits (Port x configuration bits, pin 10) */ -#define GPIO_CRH_CNF10_0 ((uint32_t)0x00000400) /*!< Bit 0 */ -#define GPIO_CRH_CNF10_1 ((uint32_t)0x00000800) /*!< Bit 1 */ - -#define GPIO_CRH_CNF11 ((uint32_t)0x0000C000) /*!< CNF11[1:0] bits (Port x configuration bits, pin 11) */ -#define GPIO_CRH_CNF11_0 ((uint32_t)0x00004000) /*!< Bit 0 */ -#define GPIO_CRH_CNF11_1 ((uint32_t)0x00008000) /*!< Bit 1 */ - -#define GPIO_CRH_CNF12 ((uint32_t)0x000C0000) /*!< CNF12[1:0] bits (Port x configuration bits, pin 12) */ -#define GPIO_CRH_CNF12_0 ((uint32_t)0x00040000) /*!< Bit 0 */ -#define GPIO_CRH_CNF12_1 ((uint32_t)0x00080000) /*!< Bit 1 */ - -#define GPIO_CRH_CNF13 ((uint32_t)0x00C00000) /*!< CNF13[1:0] bits (Port x configuration bits, pin 13) */ -#define GPIO_CRH_CNF13_0 ((uint32_t)0x00400000) /*!< Bit 0 */ -#define GPIO_CRH_CNF13_1 ((uint32_t)0x00800000) /*!< Bit 1 */ - -#define GPIO_CRH_CNF14 ((uint32_t)0x0C000000) /*!< CNF14[1:0] bits (Port x configuration bits, pin 14) */ -#define GPIO_CRH_CNF14_0 ((uint32_t)0x04000000) /*!< Bit 0 */ -#define GPIO_CRH_CNF14_1 ((uint32_t)0x08000000) /*!< Bit 1 */ - -#define GPIO_CRH_CNF15 ((uint32_t)0xC0000000) /*!< CNF15[1:0] bits (Port x configuration bits, pin 15) */ -#define GPIO_CRH_CNF15_0 ((uint32_t)0x40000000) /*!< Bit 0 */ -#define GPIO_CRH_CNF15_1 ((uint32_t)0x80000000) /*!< Bit 1 */ - -/*!<****************** Bit definition for GPIO_IDR register *******************/ -#define GPIO_IDR_IDR0 ((uint16_t)0x0001) /*!< Port input data, bit 0 */ -#define GPIO_IDR_IDR1 ((uint16_t)0x0002) /*!< Port input data, bit 1 */ -#define GPIO_IDR_IDR2 ((uint16_t)0x0004) /*!< Port input data, bit 2 */ -#define GPIO_IDR_IDR3 ((uint16_t)0x0008) /*!< Port input data, bit 3 */ -#define GPIO_IDR_IDR4 ((uint16_t)0x0010) /*!< Port input data, bit 4 */ -#define GPIO_IDR_IDR5 ((uint16_t)0x0020) /*!< Port input data, bit 5 */ -#define GPIO_IDR_IDR6 ((uint16_t)0x0040) /*!< Port input data, bit 6 */ -#define GPIO_IDR_IDR7 ((uint16_t)0x0080) /*!< Port input data, bit 7 */ -#define GPIO_IDR_IDR8 ((uint16_t)0x0100) /*!< Port input data, bit 8 */ -#define GPIO_IDR_IDR9 ((uint16_t)0x0200) /*!< Port input data, bit 9 */ -#define GPIO_IDR_IDR10 ((uint16_t)0x0400) /*!< Port input data, bit 10 */ -#define GPIO_IDR_IDR11 ((uint16_t)0x0800) /*!< Port input data, bit 11 */ -#define GPIO_IDR_IDR12 ((uint16_t)0x1000) /*!< Port input data, bit 12 */ -#define GPIO_IDR_IDR13 ((uint16_t)0x2000) /*!< Port input data, bit 13 */ -#define GPIO_IDR_IDR14 ((uint16_t)0x4000) /*!< Port input data, bit 14 */ -#define GPIO_IDR_IDR15 ((uint16_t)0x8000) /*!< Port input data, bit 15 */ - -/******************* Bit definition for GPIO_ODR register *******************/ -#define GPIO_ODR_ODR0 ((uint16_t)0x0001) /*!< Port output data, bit 0 */ -#define GPIO_ODR_ODR1 ((uint16_t)0x0002) /*!< Port output data, bit 1 */ -#define GPIO_ODR_ODR2 ((uint16_t)0x0004) /*!< Port output data, bit 2 */ -#define GPIO_ODR_ODR3 ((uint16_t)0x0008) /*!< Port output data, bit 3 */ -#define GPIO_ODR_ODR4 ((uint16_t)0x0010) /*!< Port output data, bit 4 */ -#define GPIO_ODR_ODR5 ((uint16_t)0x0020) /*!< Port output data, bit 5 */ -#define GPIO_ODR_ODR6 ((uint16_t)0x0040) /*!< Port output data, bit 6 */ -#define GPIO_ODR_ODR7 ((uint16_t)0x0080) /*!< Port output data, bit 7 */ -#define GPIO_ODR_ODR8 ((uint16_t)0x0100) /*!< Port output data, bit 8 */ -#define GPIO_ODR_ODR9 ((uint16_t)0x0200) /*!< Port output data, bit 9 */ -#define GPIO_ODR_ODR10 ((uint16_t)0x0400) /*!< Port output data, bit 10 */ -#define GPIO_ODR_ODR11 ((uint16_t)0x0800) /*!< Port output data, bit 11 */ -#define GPIO_ODR_ODR12 ((uint16_t)0x1000) /*!< Port output data, bit 12 */ -#define GPIO_ODR_ODR13 ((uint16_t)0x2000) /*!< Port output data, bit 13 */ -#define GPIO_ODR_ODR14 ((uint16_t)0x4000) /*!< Port output data, bit 14 */ -#define GPIO_ODR_ODR15 ((uint16_t)0x8000) /*!< Port output data, bit 15 */ - -/****************** Bit definition for GPIO_BSRR register *******************/ -#define GPIO_BSRR_BS0 ((uint32_t)0x00000001) /*!< Port x Set bit 0 */ -#define GPIO_BSRR_BS1 ((uint32_t)0x00000002) /*!< Port x Set bit 1 */ -#define GPIO_BSRR_BS2 ((uint32_t)0x00000004) /*!< Port x Set bit 2 */ -#define GPIO_BSRR_BS3 ((uint32_t)0x00000008) /*!< Port x Set bit 3 */ -#define GPIO_BSRR_BS4 ((uint32_t)0x00000010) /*!< Port x Set bit 4 */ -#define GPIO_BSRR_BS5 ((uint32_t)0x00000020) /*!< Port x Set bit 5 */ -#define GPIO_BSRR_BS6 ((uint32_t)0x00000040) /*!< Port x Set bit 6 */ -#define GPIO_BSRR_BS7 ((uint32_t)0x00000080) /*!< Port x Set bit 7 */ -#define GPIO_BSRR_BS8 ((uint32_t)0x00000100) /*!< Port x Set bit 8 */ -#define GPIO_BSRR_BS9 ((uint32_t)0x00000200) /*!< Port x Set bit 9 */ -#define GPIO_BSRR_BS10 ((uint32_t)0x00000400) /*!< Port x Set bit 10 */ -#define GPIO_BSRR_BS11 ((uint32_t)0x00000800) /*!< Port x Set bit 11 */ -#define GPIO_BSRR_BS12 ((uint32_t)0x00001000) /*!< Port x Set bit 12 */ -#define GPIO_BSRR_BS13 ((uint32_t)0x00002000) /*!< Port x Set bit 13 */ -#define GPIO_BSRR_BS14 ((uint32_t)0x00004000) /*!< Port x Set bit 14 */ -#define GPIO_BSRR_BS15 ((uint32_t)0x00008000) /*!< Port x Set bit 15 */ - -#define GPIO_BSRR_BR0 ((uint32_t)0x00010000) /*!< Port x Reset bit 0 */ -#define GPIO_BSRR_BR1 ((uint32_t)0x00020000) /*!< Port x Reset bit 1 */ -#define GPIO_BSRR_BR2 ((uint32_t)0x00040000) /*!< Port x Reset bit 2 */ -#define GPIO_BSRR_BR3 ((uint32_t)0x00080000) /*!< Port x Reset bit 3 */ -#define GPIO_BSRR_BR4 ((uint32_t)0x00100000) /*!< Port x Reset bit 4 */ -#define GPIO_BSRR_BR5 ((uint32_t)0x00200000) /*!< Port x Reset bit 5 */ -#define GPIO_BSRR_BR6 ((uint32_t)0x00400000) /*!< Port x Reset bit 6 */ -#define GPIO_BSRR_BR7 ((uint32_t)0x00800000) /*!< Port x Reset bit 7 */ -#define GPIO_BSRR_BR8 ((uint32_t)0x01000000) /*!< Port x Reset bit 8 */ -#define GPIO_BSRR_BR9 ((uint32_t)0x02000000) /*!< Port x Reset bit 9 */ -#define GPIO_BSRR_BR10 ((uint32_t)0x04000000) /*!< Port x Reset bit 10 */ -#define GPIO_BSRR_BR11 ((uint32_t)0x08000000) /*!< Port x Reset bit 11 */ -#define GPIO_BSRR_BR12 ((uint32_t)0x10000000) /*!< Port x Reset bit 12 */ -#define GPIO_BSRR_BR13 ((uint32_t)0x20000000) /*!< Port x Reset bit 13 */ -#define GPIO_BSRR_BR14 ((uint32_t)0x40000000) /*!< Port x Reset bit 14 */ -#define GPIO_BSRR_BR15 ((uint32_t)0x80000000) /*!< Port x Reset bit 15 */ - -/******************* Bit definition for GPIO_BRR register *******************/ -#define GPIO_BRR_BR0 ((uint16_t)0x0001) /*!< Port x Reset bit 0 */ -#define GPIO_BRR_BR1 ((uint16_t)0x0002) /*!< Port x Reset bit 1 */ -#define GPIO_BRR_BR2 ((uint16_t)0x0004) /*!< Port x Reset bit 2 */ -#define GPIO_BRR_BR3 ((uint16_t)0x0008) /*!< Port x Reset bit 3 */ -#define GPIO_BRR_BR4 ((uint16_t)0x0010) /*!< Port x Reset bit 4 */ -#define GPIO_BRR_BR5 ((uint16_t)0x0020) /*!< Port x Reset bit 5 */ -#define GPIO_BRR_BR6 ((uint16_t)0x0040) /*!< Port x Reset bit 6 */ -#define GPIO_BRR_BR7 ((uint16_t)0x0080) /*!< Port x Reset bit 7 */ -#define GPIO_BRR_BR8 ((uint16_t)0x0100) /*!< Port x Reset bit 8 */ -#define GPIO_BRR_BR9 ((uint16_t)0x0200) /*!< Port x Reset bit 9 */ -#define GPIO_BRR_BR10 ((uint16_t)0x0400) /*!< Port x Reset bit 10 */ -#define GPIO_BRR_BR11 ((uint16_t)0x0800) /*!< Port x Reset bit 11 */ -#define GPIO_BRR_BR12 ((uint16_t)0x1000) /*!< Port x Reset bit 12 */ -#define GPIO_BRR_BR13 ((uint16_t)0x2000) /*!< Port x Reset bit 13 */ -#define GPIO_BRR_BR14 ((uint16_t)0x4000) /*!< Port x Reset bit 14 */ -#define GPIO_BRR_BR15 ((uint16_t)0x8000) /*!< Port x Reset bit 15 */ - -/****************** Bit definition for GPIO_LCKR register *******************/ -#define GPIO_LCKR_LCK0 ((uint32_t)0x00000001) /*!< Port x Lock bit 0 */ -#define GPIO_LCKR_LCK1 ((uint32_t)0x00000002) /*!< Port x Lock bit 1 */ -#define GPIO_LCKR_LCK2 ((uint32_t)0x00000004) /*!< Port x Lock bit 2 */ -#define GPIO_LCKR_LCK3 ((uint32_t)0x00000008) /*!< Port x Lock bit 3 */ -#define GPIO_LCKR_LCK4 ((uint32_t)0x00000010) /*!< Port x Lock bit 4 */ -#define GPIO_LCKR_LCK5 ((uint32_t)0x00000020) /*!< Port x Lock bit 5 */ -#define GPIO_LCKR_LCK6 ((uint32_t)0x00000040) /*!< Port x Lock bit 6 */ -#define GPIO_LCKR_LCK7 ((uint32_t)0x00000080) /*!< Port x Lock bit 7 */ -#define GPIO_LCKR_LCK8 ((uint32_t)0x00000100) /*!< Port x Lock bit 8 */ -#define GPIO_LCKR_LCK9 ((uint32_t)0x00000200) /*!< Port x Lock bit 9 */ -#define GPIO_LCKR_LCK10 ((uint32_t)0x00000400) /*!< Port x Lock bit 10 */ -#define GPIO_LCKR_LCK11 ((uint32_t)0x00000800) /*!< Port x Lock bit 11 */ -#define GPIO_LCKR_LCK12 ((uint32_t)0x00001000) /*!< Port x Lock bit 12 */ -#define GPIO_LCKR_LCK13 ((uint32_t)0x00002000) /*!< Port x Lock bit 13 */ -#define GPIO_LCKR_LCK14 ((uint32_t)0x00004000) /*!< Port x Lock bit 14 */ -#define GPIO_LCKR_LCK15 ((uint32_t)0x00008000) /*!< Port x Lock bit 15 */ -#define GPIO_LCKR_LCKK ((uint32_t)0x00010000) /*!< Lock key */ - -/*----------------------------------------------------------------------------*/ - -/****************** Bit definition for AFIO_EVCR register *******************/ -#define AFIO_EVCR_PIN ((uint8_t)0x0F) /*!< PIN[3:0] bits (Pin selection) */ -#define AFIO_EVCR_PIN_0 ((uint8_t)0x01) /*!< Bit 0 */ -#define AFIO_EVCR_PIN_1 ((uint8_t)0x02) /*!< Bit 1 */ -#define AFIO_EVCR_PIN_2 ((uint8_t)0x04) /*!< Bit 2 */ -#define AFIO_EVCR_PIN_3 ((uint8_t)0x08) /*!< Bit 3 */ - -/*!< PIN configuration */ -#define AFIO_EVCR_PIN_PX0 ((uint8_t)0x00) /*!< Pin 0 selected */ -#define AFIO_EVCR_PIN_PX1 ((uint8_t)0x01) /*!< Pin 1 selected */ -#define AFIO_EVCR_PIN_PX2 ((uint8_t)0x02) /*!< Pin 2 selected */ -#define AFIO_EVCR_PIN_PX3 ((uint8_t)0x03) /*!< Pin 3 selected */ -#define AFIO_EVCR_PIN_PX4 ((uint8_t)0x04) /*!< Pin 4 selected */ -#define AFIO_EVCR_PIN_PX5 ((uint8_t)0x05) /*!< Pin 5 selected */ -#define AFIO_EVCR_PIN_PX6 ((uint8_t)0x06) /*!< Pin 6 selected */ -#define AFIO_EVCR_PIN_PX7 ((uint8_t)0x07) /*!< Pin 7 selected */ -#define AFIO_EVCR_PIN_PX8 ((uint8_t)0x08) /*!< Pin 8 selected */ -#define AFIO_EVCR_PIN_PX9 ((uint8_t)0x09) /*!< Pin 9 selected */ -#define AFIO_EVCR_PIN_PX10 ((uint8_t)0x0A) /*!< Pin 10 selected */ -#define AFIO_EVCR_PIN_PX11 ((uint8_t)0x0B) /*!< Pin 11 selected */ -#define AFIO_EVCR_PIN_PX12 ((uint8_t)0x0C) /*!< Pin 12 selected */ -#define AFIO_EVCR_PIN_PX13 ((uint8_t)0x0D) /*!< Pin 13 selected */ -#define AFIO_EVCR_PIN_PX14 ((uint8_t)0x0E) /*!< Pin 14 selected */ -#define AFIO_EVCR_PIN_PX15 ((uint8_t)0x0F) /*!< Pin 15 selected */ - -#define AFIO_EVCR_PORT ((uint8_t)0x70) /*!< PORT[2:0] bits (Port selection) */ -#define AFIO_EVCR_PORT_0 ((uint8_t)0x10) /*!< Bit 0 */ -#define AFIO_EVCR_PORT_1 ((uint8_t)0x20) /*!< Bit 1 */ -#define AFIO_EVCR_PORT_2 ((uint8_t)0x40) /*!< Bit 2 */ - -/*!< PORT configuration */ -#define AFIO_EVCR_PORT_PA ((uint8_t)0x00) /*!< Port A selected */ -#define AFIO_EVCR_PORT_PB ((uint8_t)0x10) /*!< Port B selected */ -#define AFIO_EVCR_PORT_PC ((uint8_t)0x20) /*!< Port C selected */ -#define AFIO_EVCR_PORT_PD ((uint8_t)0x30) /*!< Port D selected */ -#define AFIO_EVCR_PORT_PE ((uint8_t)0x40) /*!< Port E selected */ - -#define AFIO_EVCR_EVOE ((uint8_t)0x80) /*!< Event Output Enable */ - -/****************** Bit definition for AFIO_MAPR register *******************/ -#define AFIO_MAPR_SPI1_REMAP ((uint32_t)0x00000001) /*!< SPI1 remapping */ -#define AFIO_MAPR_I2C1_REMAP ((uint32_t)0x00000002) /*!< I2C1 remapping */ -#define AFIO_MAPR_USART1_REMAP ((uint32_t)0x00000004) /*!< USART1 remapping */ -#define AFIO_MAPR_USART2_REMAP ((uint32_t)0x00000008) /*!< USART2 remapping */ - -#define AFIO_MAPR_USART3_REMAP ((uint32_t)0x00000030) /*!< USART3_REMAP[1:0] bits (USART3 remapping) */ -#define AFIO_MAPR_USART3_REMAP_0 ((uint32_t)0x00000010) /*!< Bit 0 */ -#define AFIO_MAPR_USART3_REMAP_1 ((uint32_t)0x00000020) /*!< Bit 1 */ - -/* USART3_REMAP configuration */ -#define AFIO_MAPR_USART3_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (TX/PB10, RX/PB11, CK/PB12, CTS/PB13, RTS/PB14) */ -#define AFIO_MAPR_USART3_REMAP_PARTIALREMAP ((uint32_t)0x00000010) /*!< Partial remap (TX/PC10, RX/PC11, CK/PC12, CTS/PB13, RTS/PB14) */ -#define AFIO_MAPR_USART3_REMAP_FULLREMAP ((uint32_t)0x00000030) /*!< Full remap (TX/PD8, RX/PD9, CK/PD10, CTS/PD11, RTS/PD12) */ - -#define AFIO_MAPR_TIM1_REMAP ((uint32_t)0x000000C0) /*!< TIM1_REMAP[1:0] bits (TIM1 remapping) */ -#define AFIO_MAPR_TIM1_REMAP_0 ((uint32_t)0x00000040) /*!< Bit 0 */ -#define AFIO_MAPR_TIM1_REMAP_1 ((uint32_t)0x00000080) /*!< Bit 1 */ - -/*!< TIM1_REMAP configuration */ -#define AFIO_MAPR_TIM1_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PB12, CH1N/PB13, CH2N/PB14, CH3N/PB15) */ -#define AFIO_MAPR_TIM1_REMAP_PARTIALREMAP ((uint32_t)0x00000040) /*!< Partial remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PA6, CH1N/PA7, CH2N/PB0, CH3N/PB1) */ -#define AFIO_MAPR_TIM1_REMAP_FULLREMAP ((uint32_t)0x000000C0) /*!< Full remap (ETR/PE7, CH1/PE9, CH2/PE11, CH3/PE13, CH4/PE14, BKIN/PE15, CH1N/PE8, CH2N/PE10, CH3N/PE12) */ - -#define AFIO_MAPR_TIM2_REMAP ((uint32_t)0x00000300) /*!< TIM2_REMAP[1:0] bits (TIM2 remapping) */ -#define AFIO_MAPR_TIM2_REMAP_0 ((uint32_t)0x00000100) /*!< Bit 0 */ -#define AFIO_MAPR_TIM2_REMAP_1 ((uint32_t)0x00000200) /*!< Bit 1 */ - -/*!< TIM2_REMAP configuration */ -#define AFIO_MAPR_TIM2_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (CH1/ETR/PA0, CH2/PA1, CH3/PA2, CH4/PA3) */ -#define AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1 ((uint32_t)0x00000100) /*!< Partial remap (CH1/ETR/PA15, CH2/PB3, CH3/PA2, CH4/PA3) */ -#define AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2 ((uint32_t)0x00000200) /*!< Partial remap (CH1/ETR/PA0, CH2/PA1, CH3/PB10, CH4/PB11) */ -#define AFIO_MAPR_TIM2_REMAP_FULLREMAP ((uint32_t)0x00000300) /*!< Full remap (CH1/ETR/PA15, CH2/PB3, CH3/PB10, CH4/PB11) */ - -#define AFIO_MAPR_TIM3_REMAP ((uint32_t)0x00000C00) /*!< TIM3_REMAP[1:0] bits (TIM3 remapping) */ -#define AFIO_MAPR_TIM3_REMAP_0 ((uint32_t)0x00000400) /*!< Bit 0 */ -#define AFIO_MAPR_TIM3_REMAP_1 ((uint32_t)0x00000800) /*!< Bit 1 */ - -/*!< TIM3_REMAP configuration */ -#define AFIO_MAPR_TIM3_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (CH1/PA6, CH2/PA7, CH3/PB0, CH4/PB1) */ -#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP ((uint32_t)0x00000800) /*!< Partial remap (CH1/PB4, CH2/PB5, CH3/PB0, CH4/PB1) */ -#define AFIO_MAPR_TIM3_REMAP_FULLREMAP ((uint32_t)0x00000C00) /*!< Full remap (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9) */ - -#define AFIO_MAPR_TIM4_REMAP ((uint32_t)0x00001000) /*!< TIM4_REMAP bit (TIM4 remapping) */ - -#define AFIO_MAPR_CAN_REMAP ((uint32_t)0x00006000) /*!< CAN_REMAP[1:0] bits (CAN Alternate function remapping) */ -#define AFIO_MAPR_CAN_REMAP_0 ((uint32_t)0x00002000) /*!< Bit 0 */ -#define AFIO_MAPR_CAN_REMAP_1 ((uint32_t)0x00004000) /*!< Bit 1 */ - -/*!< CAN_REMAP configuration */ -#define AFIO_MAPR_CAN_REMAP_REMAP1 ((uint32_t)0x00000000) /*!< CANRX mapped to PA11, CANTX mapped to PA12 */ -#define AFIO_MAPR_CAN_REMAP_REMAP2 ((uint32_t)0x00004000) /*!< CANRX mapped to PB8, CANTX mapped to PB9 */ -#define AFIO_MAPR_CAN_REMAP_REMAP3 ((uint32_t)0x00006000) /*!< CANRX mapped to PD0, CANTX mapped to PD1 */ - -#define AFIO_MAPR_PD01_REMAP ((uint32_t)0x00008000) /*!< Port D0/Port D1 mapping on OSC_IN/OSC_OUT */ -#define AFIO_MAPR_TIM5CH4_IREMAP ((uint32_t)0x00010000) /*!< TIM5 Channel4 Internal Remap */ -#define AFIO_MAPR_ADC1_ETRGINJ_REMAP ((uint32_t)0x00020000) /*!< ADC 1 External Trigger Injected Conversion remapping */ -#define AFIO_MAPR_ADC1_ETRGREG_REMAP ((uint32_t)0x00040000) /*!< ADC 1 External Trigger Regular Conversion remapping */ -#define AFIO_MAPR_ADC2_ETRGINJ_REMAP ((uint32_t)0x00080000) /*!< ADC 2 External Trigger Injected Conversion remapping */ -#define AFIO_MAPR_ADC2_ETRGREG_REMAP ((uint32_t)0x00100000) /*!< ADC 2 External Trigger Regular Conversion remapping */ - -/*!< SWJ_CFG configuration */ -#define AFIO_MAPR_SWJ_CFG ((uint32_t)0x07000000) /*!< SWJ_CFG[2:0] bits (Serial Wire JTAG configuration) */ -#define AFIO_MAPR_SWJ_CFG_0 ((uint32_t)0x01000000) /*!< Bit 0 */ -#define AFIO_MAPR_SWJ_CFG_1 ((uint32_t)0x02000000) /*!< Bit 1 */ -#define AFIO_MAPR_SWJ_CFG_2 ((uint32_t)0x04000000) /*!< Bit 2 */ - -#define AFIO_MAPR_SWJ_CFG_RESET ((uint32_t)0x00000000) /*!< Full SWJ (JTAG-DP + SW-DP) : Reset State */ -#define AFIO_MAPR_SWJ_CFG_NOJNTRST ((uint32_t)0x01000000) /*!< Full SWJ (JTAG-DP + SW-DP) but without JNTRST */ -#define AFIO_MAPR_SWJ_CFG_JTAGDISABLE ((uint32_t)0x02000000) /*!< JTAG-DP Disabled and SW-DP Enabled */ -#define AFIO_MAPR_SWJ_CFG_DISABLE ((uint32_t)0x04000000) /*!< JTAG-DP Disabled and SW-DP Disabled */ - -#ifdef STM32F10X_CL -/*!< ETH_REMAP configuration */ - #define AFIO_MAPR_ETH_REMAP ((uint32_t)0x00200000) /*!< SPI3_REMAP bit (Ethernet MAC I/O remapping) */ - -/*!< CAN2_REMAP configuration */ - #define AFIO_MAPR_CAN2_REMAP ((uint32_t)0x00400000) /*!< CAN2_REMAP bit (CAN2 I/O remapping) */ - -/*!< MII_RMII_SEL configuration */ - #define AFIO_MAPR_MII_RMII_SEL ((uint32_t)0x00800000) /*!< MII_RMII_SEL bit (Ethernet MII or RMII selection) */ - -/*!< SPI3_REMAP configuration */ - #define AFIO_MAPR_SPI3_REMAP ((uint32_t)0x10000000) /*!< SPI3_REMAP bit (SPI3 remapping) */ - -/*!< TIM2ITR1_IREMAP configuration */ - #define AFIO_MAPR_TIM2ITR1_IREMAP ((uint32_t)0x20000000) /*!< TIM2ITR1_IREMAP bit (TIM2 internal trigger 1 remapping) */ - -/*!< PTP_PPS_REMAP configuration */ - #define AFIO_MAPR_PTP_PPS_REMAP ((uint32_t)0x20000000) /*!< PTP_PPS_REMAP bit (Ethernet PTP PPS remapping) */ -#endif - -/***************** Bit definition for AFIO_EXTICR1 register *****************/ -#define AFIO_EXTICR1_EXTI0 ((uint16_t)0x000F) /*!< EXTI 0 configuration */ -#define AFIO_EXTICR1_EXTI1 ((uint16_t)0x00F0) /*!< EXTI 1 configuration */ -#define AFIO_EXTICR1_EXTI2 ((uint16_t)0x0F00) /*!< EXTI 2 configuration */ -#define AFIO_EXTICR1_EXTI3 ((uint16_t)0xF000) /*!< EXTI 3 configuration */ - -/*!< EXTI0 configuration */ -#define AFIO_EXTICR1_EXTI0_PA ((uint16_t)0x0000) /*!< PA[0] pin */ -#define AFIO_EXTICR1_EXTI0_PB ((uint16_t)0x0001) /*!< PB[0] pin */ -#define AFIO_EXTICR1_EXTI0_PC ((uint16_t)0x0002) /*!< PC[0] pin */ -#define AFIO_EXTICR1_EXTI0_PD ((uint16_t)0x0003) /*!< PD[0] pin */ -#define AFIO_EXTICR1_EXTI0_PE ((uint16_t)0x0004) /*!< PE[0] pin */ -#define AFIO_EXTICR1_EXTI0_PF ((uint16_t)0x0005) /*!< PF[0] pin */ -#define AFIO_EXTICR1_EXTI0_PG ((uint16_t)0x0006) /*!< PG[0] pin */ - -/*!< EXTI1 configuration */ -#define AFIO_EXTICR1_EXTI1_PA ((uint16_t)0x0000) /*!< PA[1] pin */ -#define AFIO_EXTICR1_EXTI1_PB ((uint16_t)0x0010) /*!< PB[1] pin */ -#define AFIO_EXTICR1_EXTI1_PC ((uint16_t)0x0020) /*!< PC[1] pin */ -#define AFIO_EXTICR1_EXTI1_PD ((uint16_t)0x0030) /*!< PD[1] pin */ -#define AFIO_EXTICR1_EXTI1_PE ((uint16_t)0x0040) /*!< PE[1] pin */ -#define AFIO_EXTICR1_EXTI1_PF ((uint16_t)0x0050) /*!< PF[1] pin */ -#define AFIO_EXTICR1_EXTI1_PG ((uint16_t)0x0060) /*!< PG[1] pin */ - -/*!< EXTI2 configuration */ -#define AFIO_EXTICR1_EXTI2_PA ((uint16_t)0x0000) /*!< PA[2] pin */ -#define AFIO_EXTICR1_EXTI2_PB ((uint16_t)0x0100) /*!< PB[2] pin */ -#define AFIO_EXTICR1_EXTI2_PC ((uint16_t)0x0200) /*!< PC[2] pin */ -#define AFIO_EXTICR1_EXTI2_PD ((uint16_t)0x0300) /*!< PD[2] pin */ -#define AFIO_EXTICR1_EXTI2_PE ((uint16_t)0x0400) /*!< PE[2] pin */ -#define AFIO_EXTICR1_EXTI2_PF ((uint16_t)0x0500) /*!< PF[2] pin */ -#define AFIO_EXTICR1_EXTI2_PG ((uint16_t)0x0600) /*!< PG[2] pin */ - -/*!< EXTI3 configuration */ -#define AFIO_EXTICR1_EXTI3_PA ((uint16_t)0x0000) /*!< PA[3] pin */ -#define AFIO_EXTICR1_EXTI3_PB ((uint16_t)0x1000) /*!< PB[3] pin */ -#define AFIO_EXTICR1_EXTI3_PC ((uint16_t)0x2000) /*!< PC[3] pin */ -#define AFIO_EXTICR1_EXTI3_PD ((uint16_t)0x3000) /*!< PD[3] pin */ -#define AFIO_EXTICR1_EXTI3_PE ((uint16_t)0x4000) /*!< PE[3] pin */ -#define AFIO_EXTICR1_EXTI3_PF ((uint16_t)0x5000) /*!< PF[3] pin */ -#define AFIO_EXTICR1_EXTI3_PG ((uint16_t)0x6000) /*!< PG[3] pin */ - -/***************** Bit definition for AFIO_EXTICR2 register *****************/ -#define AFIO_EXTICR2_EXTI4 ((uint16_t)0x000F) /*!< EXTI 4 configuration */ -#define AFIO_EXTICR2_EXTI5 ((uint16_t)0x00F0) /*!< EXTI 5 configuration */ -#define AFIO_EXTICR2_EXTI6 ((uint16_t)0x0F00) /*!< EXTI 6 configuration */ -#define AFIO_EXTICR2_EXTI7 ((uint16_t)0xF000) /*!< EXTI 7 configuration */ - -/*!< EXTI4 configuration */ -#define AFIO_EXTICR2_EXTI4_PA ((uint16_t)0x0000) /*!< PA[4] pin */ -#define AFIO_EXTICR2_EXTI4_PB ((uint16_t)0x0001) /*!< PB[4] pin */ -#define AFIO_EXTICR2_EXTI4_PC ((uint16_t)0x0002) /*!< PC[4] pin */ -#define AFIO_EXTICR2_EXTI4_PD ((uint16_t)0x0003) /*!< PD[4] pin */ -#define AFIO_EXTICR2_EXTI4_PE ((uint16_t)0x0004) /*!< PE[4] pin */ -#define AFIO_EXTICR2_EXTI4_PF ((uint16_t)0x0005) /*!< PF[4] pin */ -#define AFIO_EXTICR2_EXTI4_PG ((uint16_t)0x0006) /*!< PG[4] pin */ - -/* EXTI5 configuration */ -#define AFIO_EXTICR2_EXTI5_PA ((uint16_t)0x0000) /*!< PA[5] pin */ -#define AFIO_EXTICR2_EXTI5_PB ((uint16_t)0x0010) /*!< PB[5] pin */ -#define AFIO_EXTICR2_EXTI5_PC ((uint16_t)0x0020) /*!< PC[5] pin */ -#define AFIO_EXTICR2_EXTI5_PD ((uint16_t)0x0030) /*!< PD[5] pin */ -#define AFIO_EXTICR2_EXTI5_PE ((uint16_t)0x0040) /*!< PE[5] pin */ -#define AFIO_EXTICR2_EXTI5_PF ((uint16_t)0x0050) /*!< PF[5] pin */ -#define AFIO_EXTICR2_EXTI5_PG ((uint16_t)0x0060) /*!< PG[5] pin */ - -/*!< EXTI6 configuration */ -#define AFIO_EXTICR2_EXTI6_PA ((uint16_t)0x0000) /*!< PA[6] pin */ -#define AFIO_EXTICR2_EXTI6_PB ((uint16_t)0x0100) /*!< PB[6] pin */ -#define AFIO_EXTICR2_EXTI6_PC ((uint16_t)0x0200) /*!< PC[6] pin */ -#define AFIO_EXTICR2_EXTI6_PD ((uint16_t)0x0300) /*!< PD[6] pin */ -#define AFIO_EXTICR2_EXTI6_PE ((uint16_t)0x0400) /*!< PE[6] pin */ -#define AFIO_EXTICR2_EXTI6_PF ((uint16_t)0x0500) /*!< PF[6] pin */ -#define AFIO_EXTICR2_EXTI6_PG ((uint16_t)0x0600) /*!< PG[6] pin */ - -/*!< EXTI7 configuration */ -#define AFIO_EXTICR2_EXTI7_PA ((uint16_t)0x0000) /*!< PA[7] pin */ -#define AFIO_EXTICR2_EXTI7_PB ((uint16_t)0x1000) /*!< PB[7] pin */ -#define AFIO_EXTICR2_EXTI7_PC ((uint16_t)0x2000) /*!< PC[7] pin */ -#define AFIO_EXTICR2_EXTI7_PD ((uint16_t)0x3000) /*!< PD[7] pin */ -#define AFIO_EXTICR2_EXTI7_PE ((uint16_t)0x4000) /*!< PE[7] pin */ -#define AFIO_EXTICR2_EXTI7_PF ((uint16_t)0x5000) /*!< PF[7] pin */ -#define AFIO_EXTICR2_EXTI7_PG ((uint16_t)0x6000) /*!< PG[7] pin */ - -/***************** Bit definition for AFIO_EXTICR3 register *****************/ -#define AFIO_EXTICR3_EXTI8 ((uint16_t)0x000F) /*!< EXTI 8 configuration */ -#define AFIO_EXTICR3_EXTI9 ((uint16_t)0x00F0) /*!< EXTI 9 configuration */ -#define AFIO_EXTICR3_EXTI10 ((uint16_t)0x0F00) /*!< EXTI 10 configuration */ -#define AFIO_EXTICR3_EXTI11 ((uint16_t)0xF000) /*!< EXTI 11 configuration */ - -/*!< EXTI8 configuration */ -#define AFIO_EXTICR3_EXTI8_PA ((uint16_t)0x0000) /*!< PA[8] pin */ -#define AFIO_EXTICR3_EXTI8_PB ((uint16_t)0x0001) /*!< PB[8] pin */ -#define AFIO_EXTICR3_EXTI8_PC ((uint16_t)0x0002) /*!< PC[8] pin */ -#define AFIO_EXTICR3_EXTI8_PD ((uint16_t)0x0003) /*!< PD[8] pin */ -#define AFIO_EXTICR3_EXTI8_PE ((uint16_t)0x0004) /*!< PE[8] pin */ -#define AFIO_EXTICR3_EXTI8_PF ((uint16_t)0x0005) /*!< PF[8] pin */ -#define AFIO_EXTICR3_EXTI8_PG ((uint16_t)0x0006) /*!< PG[8] pin */ - -/*!< EXTI9 configuration */ -#define AFIO_EXTICR3_EXTI9_PA ((uint16_t)0x0000) /*!< PA[9] pin */ -#define AFIO_EXTICR3_EXTI9_PB ((uint16_t)0x0010) /*!< PB[9] pin */ -#define AFIO_EXTICR3_EXTI9_PC ((uint16_t)0x0020) /*!< PC[9] pin */ -#define AFIO_EXTICR3_EXTI9_PD ((uint16_t)0x0030) /*!< PD[9] pin */ -#define AFIO_EXTICR3_EXTI9_PE ((uint16_t)0x0040) /*!< PE[9] pin */ -#define AFIO_EXTICR3_EXTI9_PF ((uint16_t)0x0050) /*!< PF[9] pin */ -#define AFIO_EXTICR3_EXTI9_PG ((uint16_t)0x0060) /*!< PG[9] pin */ - -/*!< EXTI10 configuration */ -#define AFIO_EXTICR3_EXTI10_PA ((uint16_t)0x0000) /*!< PA[10] pin */ -#define AFIO_EXTICR3_EXTI10_PB ((uint16_t)0x0100) /*!< PB[10] pin */ -#define AFIO_EXTICR3_EXTI10_PC ((uint16_t)0x0200) /*!< PC[10] pin */ -#define AFIO_EXTICR3_EXTI10_PD ((uint16_t)0x0300) /*!< PD[10] pin */ -#define AFIO_EXTICR3_EXTI10_PE ((uint16_t)0x0400) /*!< PE[10] pin */ -#define AFIO_EXTICR3_EXTI10_PF ((uint16_t)0x0500) /*!< PF[10] pin */ -#define AFIO_EXTICR3_EXTI10_PG ((uint16_t)0x0600) /*!< PG[10] pin */ - -/*!< EXTI11 configuration */ -#define AFIO_EXTICR3_EXTI11_PA ((uint16_t)0x0000) /*!< PA[11] pin */ -#define AFIO_EXTICR3_EXTI11_PB ((uint16_t)0x1000) /*!< PB[11] pin */ -#define AFIO_EXTICR3_EXTI11_PC ((uint16_t)0x2000) /*!< PC[11] pin */ -#define AFIO_EXTICR3_EXTI11_PD ((uint16_t)0x3000) /*!< PD[11] pin */ -#define AFIO_EXTICR3_EXTI11_PE ((uint16_t)0x4000) /*!< PE[11] pin */ -#define AFIO_EXTICR3_EXTI11_PF ((uint16_t)0x5000) /*!< PF[11] pin */ -#define AFIO_EXTICR3_EXTI11_PG ((uint16_t)0x6000) /*!< PG[11] pin */ - -/***************** Bit definition for AFIO_EXTICR4 register *****************/ -#define AFIO_EXTICR4_EXTI12 ((uint16_t)0x000F) /*!< EXTI 12 configuration */ -#define AFIO_EXTICR4_EXTI13 ((uint16_t)0x00F0) /*!< EXTI 13 configuration */ -#define AFIO_EXTICR4_EXTI14 ((uint16_t)0x0F00) /*!< EXTI 14 configuration */ -#define AFIO_EXTICR4_EXTI15 ((uint16_t)0xF000) /*!< EXTI 15 configuration */ - -/* EXTI12 configuration */ -#define AFIO_EXTICR4_EXTI12_PA ((uint16_t)0x0000) /*!< PA[12] pin */ -#define AFIO_EXTICR4_EXTI12_PB ((uint16_t)0x0001) /*!< PB[12] pin */ -#define AFIO_EXTICR4_EXTI12_PC ((uint16_t)0x0002) /*!< PC[12] pin */ -#define AFIO_EXTICR4_EXTI12_PD ((uint16_t)0x0003) /*!< PD[12] pin */ -#define AFIO_EXTICR4_EXTI12_PE ((uint16_t)0x0004) /*!< PE[12] pin */ -#define AFIO_EXTICR4_EXTI12_PF ((uint16_t)0x0005) /*!< PF[12] pin */ -#define AFIO_EXTICR4_EXTI12_PG ((uint16_t)0x0006) /*!< PG[12] pin */ - -/* EXTI13 configuration */ -#define AFIO_EXTICR4_EXTI13_PA ((uint16_t)0x0000) /*!< PA[13] pin */ -#define AFIO_EXTICR4_EXTI13_PB ((uint16_t)0x0010) /*!< PB[13] pin */ -#define AFIO_EXTICR4_EXTI13_PC ((uint16_t)0x0020) /*!< PC[13] pin */ -#define AFIO_EXTICR4_EXTI13_PD ((uint16_t)0x0030) /*!< PD[13] pin */ -#define AFIO_EXTICR4_EXTI13_PE ((uint16_t)0x0040) /*!< PE[13] pin */ -#define AFIO_EXTICR4_EXTI13_PF ((uint16_t)0x0050) /*!< PF[13] pin */ -#define AFIO_EXTICR4_EXTI13_PG ((uint16_t)0x0060) /*!< PG[13] pin */ - -/*!< EXTI14 configuration */ -#define AFIO_EXTICR4_EXTI14_PA ((uint16_t)0x0000) /*!< PA[14] pin */ -#define AFIO_EXTICR4_EXTI14_PB ((uint16_t)0x0100) /*!< PB[14] pin */ -#define AFIO_EXTICR4_EXTI14_PC ((uint16_t)0x0200) /*!< PC[14] pin */ -#define AFIO_EXTICR4_EXTI14_PD ((uint16_t)0x0300) /*!< PD[14] pin */ -#define AFIO_EXTICR4_EXTI14_PE ((uint16_t)0x0400) /*!< PE[14] pin */ -#define AFIO_EXTICR4_EXTI14_PF ((uint16_t)0x0500) /*!< PF[14] pin */ -#define AFIO_EXTICR4_EXTI14_PG ((uint16_t)0x0600) /*!< PG[14] pin */ - -/*!< EXTI15 configuration */ -#define AFIO_EXTICR4_EXTI15_PA ((uint16_t)0x0000) /*!< PA[15] pin */ -#define AFIO_EXTICR4_EXTI15_PB ((uint16_t)0x1000) /*!< PB[15] pin */ -#define AFIO_EXTICR4_EXTI15_PC ((uint16_t)0x2000) /*!< PC[15] pin */ -#define AFIO_EXTICR4_EXTI15_PD ((uint16_t)0x3000) /*!< PD[15] pin */ -#define AFIO_EXTICR4_EXTI15_PE ((uint16_t)0x4000) /*!< PE[15] pin */ -#define AFIO_EXTICR4_EXTI15_PF ((uint16_t)0x5000) /*!< PF[15] pin */ -#define AFIO_EXTICR4_EXTI15_PG ((uint16_t)0x6000) /*!< PG[15] pin */ - -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) -/****************** Bit definition for AFIO_MAPR2 register ******************/ -#define AFIO_MAPR2_TIM15_REMAP ((uint32_t)0x00000001) /*!< TIM15 remapping */ -#define AFIO_MAPR2_TIM16_REMAP ((uint32_t)0x00000002) /*!< TIM16 remapping */ -#define AFIO_MAPR2_TIM17_REMAP ((uint32_t)0x00000004) /*!< TIM17 remapping */ -#define AFIO_MAPR2_CEC_REMAP ((uint32_t)0x00000008) /*!< CEC remapping */ -#define AFIO_MAPR2_TIM1_DMA_REMAP ((uint32_t)0x00000010) /*!< TIM1_DMA remapping */ -#endif - -#ifdef STM32F10X_XL -/****************** Bit definition for AFIO_MAPR2 register ******************/ -#define AFIO_MAPR2_TIM9_REMAP ((uint32_t)0x00000020) /*!< TIM9 remapping */ -#define AFIO_MAPR2_TIM10_REMAP ((uint32_t)0x00000040) /*!< TIM10 remapping */ -#define AFIO_MAPR2_TIM11_REMAP ((uint32_t)0x00000080) /*!< TIM11 remapping */ -#define AFIO_MAPR2_TIM13_REMAP ((uint32_t)0x00000100) /*!< TIM13 remapping */ -#define AFIO_MAPR2_TIM14_REMAP ((uint32_t)0x00000200) /*!< TIM14 remapping */ -#define AFIO_MAPR2_FSMC_NADV_REMAP ((uint32_t)0x00000400) /*!< FSMC NADV remapping */ -#endif - -/******************************************************************************/ -/* */ -/* SystemTick */ -/* */ -/******************************************************************************/ - -/***************** Bit definition for SysTick_CTRL register *****************/ -#define SysTick_CTRL_ENABLE ((uint32_t)0x00000001) /*!< Counter enable */ -#define SysTick_CTRL_TICKINT ((uint32_t)0x00000002) /*!< Counting down to 0 pends the SysTick handler */ -#define SysTick_CTRL_CLKSOURCE ((uint32_t)0x00000004) /*!< Clock source */ -#define SysTick_CTRL_COUNTFLAG ((uint32_t)0x00010000) /*!< Count Flag */ - -/***************** Bit definition for SysTick_LOAD register *****************/ -#define SysTick_LOAD_RELOAD ((uint32_t)0x00FFFFFF) /*!< Value to load into the SysTick Current Value Register when the counter reaches 0 */ - -/***************** Bit definition for SysTick_VAL register ******************/ -#define SysTick_VAL_CURRENT ((uint32_t)0x00FFFFFF) /*!< Current value at the time the register is accessed */ - -/***************** Bit definition for SysTick_CALIB register ****************/ -#define SysTick_CALIB_TENMS ((uint32_t)0x00FFFFFF) /*!< Reload value to use for 10ms timing */ -#define SysTick_CALIB_SKEW ((uint32_t)0x40000000) /*!< Calibration value is not exactly 10 ms */ -#define SysTick_CALIB_NOREF ((uint32_t)0x80000000) /*!< The reference clock is not provided */ - -/******************************************************************************/ -/* */ -/* Nested Vectored Interrupt Controller */ -/* */ -/******************************************************************************/ - -/****************** Bit definition for NVIC_ISER register *******************/ -#define NVIC_ISER_SETENA ((uint32_t)0xFFFFFFFF) /*!< Interrupt set enable bits */ -#define NVIC_ISER_SETENA_0 ((uint32_t)0x00000001) /*!< bit 0 */ -#define NVIC_ISER_SETENA_1 ((uint32_t)0x00000002) /*!< bit 1 */ -#define NVIC_ISER_SETENA_2 ((uint32_t)0x00000004) /*!< bit 2 */ -#define NVIC_ISER_SETENA_3 ((uint32_t)0x00000008) /*!< bit 3 */ -#define NVIC_ISER_SETENA_4 ((uint32_t)0x00000010) /*!< bit 4 */ -#define NVIC_ISER_SETENA_5 ((uint32_t)0x00000020) /*!< bit 5 */ -#define NVIC_ISER_SETENA_6 ((uint32_t)0x00000040) /*!< bit 6 */ -#define NVIC_ISER_SETENA_7 ((uint32_t)0x00000080) /*!< bit 7 */ -#define NVIC_ISER_SETENA_8 ((uint32_t)0x00000100) /*!< bit 8 */ -#define NVIC_ISER_SETENA_9 ((uint32_t)0x00000200) /*!< bit 9 */ -#define NVIC_ISER_SETENA_10 ((uint32_t)0x00000400) /*!< bit 10 */ -#define NVIC_ISER_SETENA_11 ((uint32_t)0x00000800) /*!< bit 11 */ -#define NVIC_ISER_SETENA_12 ((uint32_t)0x00001000) /*!< bit 12 */ -#define NVIC_ISER_SETENA_13 ((uint32_t)0x00002000) /*!< bit 13 */ -#define NVIC_ISER_SETENA_14 ((uint32_t)0x00004000) /*!< bit 14 */ -#define NVIC_ISER_SETENA_15 ((uint32_t)0x00008000) /*!< bit 15 */ -#define NVIC_ISER_SETENA_16 ((uint32_t)0x00010000) /*!< bit 16 */ -#define NVIC_ISER_SETENA_17 ((uint32_t)0x00020000) /*!< bit 17 */ -#define NVIC_ISER_SETENA_18 ((uint32_t)0x00040000) /*!< bit 18 */ -#define NVIC_ISER_SETENA_19 ((uint32_t)0x00080000) /*!< bit 19 */ -#define NVIC_ISER_SETENA_20 ((uint32_t)0x00100000) /*!< bit 20 */ -#define NVIC_ISER_SETENA_21 ((uint32_t)0x00200000) /*!< bit 21 */ -#define NVIC_ISER_SETENA_22 ((uint32_t)0x00400000) /*!< bit 22 */ -#define NVIC_ISER_SETENA_23 ((uint32_t)0x00800000) /*!< bit 23 */ -#define NVIC_ISER_SETENA_24 ((uint32_t)0x01000000) /*!< bit 24 */ -#define NVIC_ISER_SETENA_25 ((uint32_t)0x02000000) /*!< bit 25 */ -#define NVIC_ISER_SETENA_26 ((uint32_t)0x04000000) /*!< bit 26 */ -#define NVIC_ISER_SETENA_27 ((uint32_t)0x08000000) /*!< bit 27 */ -#define NVIC_ISER_SETENA_28 ((uint32_t)0x10000000) /*!< bit 28 */ -#define NVIC_ISER_SETENA_29 ((uint32_t)0x20000000) /*!< bit 29 */ -#define NVIC_ISER_SETENA_30 ((uint32_t)0x40000000) /*!< bit 30 */ -#define NVIC_ISER_SETENA_31 ((uint32_t)0x80000000) /*!< bit 31 */ - -/****************** Bit definition for NVIC_ICER register *******************/ -#define NVIC_ICER_CLRENA ((uint32_t)0xFFFFFFFF) /*!< Interrupt clear-enable bits */ -#define NVIC_ICER_CLRENA_0 ((uint32_t)0x00000001) /*!< bit 0 */ -#define NVIC_ICER_CLRENA_1 ((uint32_t)0x00000002) /*!< bit 1 */ -#define NVIC_ICER_CLRENA_2 ((uint32_t)0x00000004) /*!< bit 2 */ -#define NVIC_ICER_CLRENA_3 ((uint32_t)0x00000008) /*!< bit 3 */ -#define NVIC_ICER_CLRENA_4 ((uint32_t)0x00000010) /*!< bit 4 */ -#define NVIC_ICER_CLRENA_5 ((uint32_t)0x00000020) /*!< bit 5 */ -#define NVIC_ICER_CLRENA_6 ((uint32_t)0x00000040) /*!< bit 6 */ -#define NVIC_ICER_CLRENA_7 ((uint32_t)0x00000080) /*!< bit 7 */ -#define NVIC_ICER_CLRENA_8 ((uint32_t)0x00000100) /*!< bit 8 */ -#define NVIC_ICER_CLRENA_9 ((uint32_t)0x00000200) /*!< bit 9 */ -#define NVIC_ICER_CLRENA_10 ((uint32_t)0x00000400) /*!< bit 10 */ -#define NVIC_ICER_CLRENA_11 ((uint32_t)0x00000800) /*!< bit 11 */ -#define NVIC_ICER_CLRENA_12 ((uint32_t)0x00001000) /*!< bit 12 */ -#define NVIC_ICER_CLRENA_13 ((uint32_t)0x00002000) /*!< bit 13 */ -#define NVIC_ICER_CLRENA_14 ((uint32_t)0x00004000) /*!< bit 14 */ -#define NVIC_ICER_CLRENA_15 ((uint32_t)0x00008000) /*!< bit 15 */ -#define NVIC_ICER_CLRENA_16 ((uint32_t)0x00010000) /*!< bit 16 */ -#define NVIC_ICER_CLRENA_17 ((uint32_t)0x00020000) /*!< bit 17 */ -#define NVIC_ICER_CLRENA_18 ((uint32_t)0x00040000) /*!< bit 18 */ -#define NVIC_ICER_CLRENA_19 ((uint32_t)0x00080000) /*!< bit 19 */ -#define NVIC_ICER_CLRENA_20 ((uint32_t)0x00100000) /*!< bit 20 */ -#define NVIC_ICER_CLRENA_21 ((uint32_t)0x00200000) /*!< bit 21 */ -#define NVIC_ICER_CLRENA_22 ((uint32_t)0x00400000) /*!< bit 22 */ -#define NVIC_ICER_CLRENA_23 ((uint32_t)0x00800000) /*!< bit 23 */ -#define NVIC_ICER_CLRENA_24 ((uint32_t)0x01000000) /*!< bit 24 */ -#define NVIC_ICER_CLRENA_25 ((uint32_t)0x02000000) /*!< bit 25 */ -#define NVIC_ICER_CLRENA_26 ((uint32_t)0x04000000) /*!< bit 26 */ -#define NVIC_ICER_CLRENA_27 ((uint32_t)0x08000000) /*!< bit 27 */ -#define NVIC_ICER_CLRENA_28 ((uint32_t)0x10000000) /*!< bit 28 */ -#define NVIC_ICER_CLRENA_29 ((uint32_t)0x20000000) /*!< bit 29 */ -#define NVIC_ICER_CLRENA_30 ((uint32_t)0x40000000) /*!< bit 30 */ -#define NVIC_ICER_CLRENA_31 ((uint32_t)0x80000000) /*!< bit 31 */ - -/****************** Bit definition for NVIC_ISPR register *******************/ -#define NVIC_ISPR_SETPEND ((uint32_t)0xFFFFFFFF) /*!< Interrupt set-pending bits */ -#define NVIC_ISPR_SETPEND_0 ((uint32_t)0x00000001) /*!< bit 0 */ -#define NVIC_ISPR_SETPEND_1 ((uint32_t)0x00000002) /*!< bit 1 */ -#define NVIC_ISPR_SETPEND_2 ((uint32_t)0x00000004) /*!< bit 2 */ -#define NVIC_ISPR_SETPEND_3 ((uint32_t)0x00000008) /*!< bit 3 */ -#define NVIC_ISPR_SETPEND_4 ((uint32_t)0x00000010) /*!< bit 4 */ -#define NVIC_ISPR_SETPEND_5 ((uint32_t)0x00000020) /*!< bit 5 */ -#define NVIC_ISPR_SETPEND_6 ((uint32_t)0x00000040) /*!< bit 6 */ -#define NVIC_ISPR_SETPEND_7 ((uint32_t)0x00000080) /*!< bit 7 */ -#define NVIC_ISPR_SETPEND_8 ((uint32_t)0x00000100) /*!< bit 8 */ -#define NVIC_ISPR_SETPEND_9 ((uint32_t)0x00000200) /*!< bit 9 */ -#define NVIC_ISPR_SETPEND_10 ((uint32_t)0x00000400) /*!< bit 10 */ -#define NVIC_ISPR_SETPEND_11 ((uint32_t)0x00000800) /*!< bit 11 */ -#define NVIC_ISPR_SETPEND_12 ((uint32_t)0x00001000) /*!< bit 12 */ -#define NVIC_ISPR_SETPEND_13 ((uint32_t)0x00002000) /*!< bit 13 */ -#define NVIC_ISPR_SETPEND_14 ((uint32_t)0x00004000) /*!< bit 14 */ -#define NVIC_ISPR_SETPEND_15 ((uint32_t)0x00008000) /*!< bit 15 */ -#define NVIC_ISPR_SETPEND_16 ((uint32_t)0x00010000) /*!< bit 16 */ -#define NVIC_ISPR_SETPEND_17 ((uint32_t)0x00020000) /*!< bit 17 */ -#define NVIC_ISPR_SETPEND_18 ((uint32_t)0x00040000) /*!< bit 18 */ -#define NVIC_ISPR_SETPEND_19 ((uint32_t)0x00080000) /*!< bit 19 */ -#define NVIC_ISPR_SETPEND_20 ((uint32_t)0x00100000) /*!< bit 20 */ -#define NVIC_ISPR_SETPEND_21 ((uint32_t)0x00200000) /*!< bit 21 */ -#define NVIC_ISPR_SETPEND_22 ((uint32_t)0x00400000) /*!< bit 22 */ -#define NVIC_ISPR_SETPEND_23 ((uint32_t)0x00800000) /*!< bit 23 */ -#define NVIC_ISPR_SETPEND_24 ((uint32_t)0x01000000) /*!< bit 24 */ -#define NVIC_ISPR_SETPEND_25 ((uint32_t)0x02000000) /*!< bit 25 */ -#define NVIC_ISPR_SETPEND_26 ((uint32_t)0x04000000) /*!< bit 26 */ -#define NVIC_ISPR_SETPEND_27 ((uint32_t)0x08000000) /*!< bit 27 */ -#define NVIC_ISPR_SETPEND_28 ((uint32_t)0x10000000) /*!< bit 28 */ -#define NVIC_ISPR_SETPEND_29 ((uint32_t)0x20000000) /*!< bit 29 */ -#define NVIC_ISPR_SETPEND_30 ((uint32_t)0x40000000) /*!< bit 30 */ -#define NVIC_ISPR_SETPEND_31 ((uint32_t)0x80000000) /*!< bit 31 */ - -/****************** Bit definition for NVIC_ICPR register *******************/ -#define NVIC_ICPR_CLRPEND ((uint32_t)0xFFFFFFFF) /*!< Interrupt clear-pending bits */ -#define NVIC_ICPR_CLRPEND_0 ((uint32_t)0x00000001) /*!< bit 0 */ -#define NVIC_ICPR_CLRPEND_1 ((uint32_t)0x00000002) /*!< bit 1 */ -#define NVIC_ICPR_CLRPEND_2 ((uint32_t)0x00000004) /*!< bit 2 */ -#define NVIC_ICPR_CLRPEND_3 ((uint32_t)0x00000008) /*!< bit 3 */ -#define NVIC_ICPR_CLRPEND_4 ((uint32_t)0x00000010) /*!< bit 4 */ -#define NVIC_ICPR_CLRPEND_5 ((uint32_t)0x00000020) /*!< bit 5 */ -#define NVIC_ICPR_CLRPEND_6 ((uint32_t)0x00000040) /*!< bit 6 */ -#define NVIC_ICPR_CLRPEND_7 ((uint32_t)0x00000080) /*!< bit 7 */ -#define NVIC_ICPR_CLRPEND_8 ((uint32_t)0x00000100) /*!< bit 8 */ -#define NVIC_ICPR_CLRPEND_9 ((uint32_t)0x00000200) /*!< bit 9 */ -#define NVIC_ICPR_CLRPEND_10 ((uint32_t)0x00000400) /*!< bit 10 */ -#define NVIC_ICPR_CLRPEND_11 ((uint32_t)0x00000800) /*!< bit 11 */ -#define NVIC_ICPR_CLRPEND_12 ((uint32_t)0x00001000) /*!< bit 12 */ -#define NVIC_ICPR_CLRPEND_13 ((uint32_t)0x00002000) /*!< bit 13 */ -#define NVIC_ICPR_CLRPEND_14 ((uint32_t)0x00004000) /*!< bit 14 */ -#define NVIC_ICPR_CLRPEND_15 ((uint32_t)0x00008000) /*!< bit 15 */ -#define NVIC_ICPR_CLRPEND_16 ((uint32_t)0x00010000) /*!< bit 16 */ -#define NVIC_ICPR_CLRPEND_17 ((uint32_t)0x00020000) /*!< bit 17 */ -#define NVIC_ICPR_CLRPEND_18 ((uint32_t)0x00040000) /*!< bit 18 */ -#define NVIC_ICPR_CLRPEND_19 ((uint32_t)0x00080000) /*!< bit 19 */ -#define NVIC_ICPR_CLRPEND_20 ((uint32_t)0x00100000) /*!< bit 20 */ -#define NVIC_ICPR_CLRPEND_21 ((uint32_t)0x00200000) /*!< bit 21 */ -#define NVIC_ICPR_CLRPEND_22 ((uint32_t)0x00400000) /*!< bit 22 */ -#define NVIC_ICPR_CLRPEND_23 ((uint32_t)0x00800000) /*!< bit 23 */ -#define NVIC_ICPR_CLRPEND_24 ((uint32_t)0x01000000) /*!< bit 24 */ -#define NVIC_ICPR_CLRPEND_25 ((uint32_t)0x02000000) /*!< bit 25 */ -#define NVIC_ICPR_CLRPEND_26 ((uint32_t)0x04000000) /*!< bit 26 */ -#define NVIC_ICPR_CLRPEND_27 ((uint32_t)0x08000000) /*!< bit 27 */ -#define NVIC_ICPR_CLRPEND_28 ((uint32_t)0x10000000) /*!< bit 28 */ -#define NVIC_ICPR_CLRPEND_29 ((uint32_t)0x20000000) /*!< bit 29 */ -#define NVIC_ICPR_CLRPEND_30 ((uint32_t)0x40000000) /*!< bit 30 */ -#define NVIC_ICPR_CLRPEND_31 ((uint32_t)0x80000000) /*!< bit 31 */ - -/****************** Bit definition for NVIC_IABR register *******************/ -#define NVIC_IABR_ACTIVE ((uint32_t)0xFFFFFFFF) /*!< Interrupt active flags */ -#define NVIC_IABR_ACTIVE_0 ((uint32_t)0x00000001) /*!< bit 0 */ -#define NVIC_IABR_ACTIVE_1 ((uint32_t)0x00000002) /*!< bit 1 */ -#define NVIC_IABR_ACTIVE_2 ((uint32_t)0x00000004) /*!< bit 2 */ -#define NVIC_IABR_ACTIVE_3 ((uint32_t)0x00000008) /*!< bit 3 */ -#define NVIC_IABR_ACTIVE_4 ((uint32_t)0x00000010) /*!< bit 4 */ -#define NVIC_IABR_ACTIVE_5 ((uint32_t)0x00000020) /*!< bit 5 */ -#define NVIC_IABR_ACTIVE_6 ((uint32_t)0x00000040) /*!< bit 6 */ -#define NVIC_IABR_ACTIVE_7 ((uint32_t)0x00000080) /*!< bit 7 */ -#define NVIC_IABR_ACTIVE_8 ((uint32_t)0x00000100) /*!< bit 8 */ -#define NVIC_IABR_ACTIVE_9 ((uint32_t)0x00000200) /*!< bit 9 */ -#define NVIC_IABR_ACTIVE_10 ((uint32_t)0x00000400) /*!< bit 10 */ -#define NVIC_IABR_ACTIVE_11 ((uint32_t)0x00000800) /*!< bit 11 */ -#define NVIC_IABR_ACTIVE_12 ((uint32_t)0x00001000) /*!< bit 12 */ -#define NVIC_IABR_ACTIVE_13 ((uint32_t)0x00002000) /*!< bit 13 */ -#define NVIC_IABR_ACTIVE_14 ((uint32_t)0x00004000) /*!< bit 14 */ -#define NVIC_IABR_ACTIVE_15 ((uint32_t)0x00008000) /*!< bit 15 */ -#define NVIC_IABR_ACTIVE_16 ((uint32_t)0x00010000) /*!< bit 16 */ -#define NVIC_IABR_ACTIVE_17 ((uint32_t)0x00020000) /*!< bit 17 */ -#define NVIC_IABR_ACTIVE_18 ((uint32_t)0x00040000) /*!< bit 18 */ -#define NVIC_IABR_ACTIVE_19 ((uint32_t)0x00080000) /*!< bit 19 */ -#define NVIC_IABR_ACTIVE_20 ((uint32_t)0x00100000) /*!< bit 20 */ -#define NVIC_IABR_ACTIVE_21 ((uint32_t)0x00200000) /*!< bit 21 */ -#define NVIC_IABR_ACTIVE_22 ((uint32_t)0x00400000) /*!< bit 22 */ -#define NVIC_IABR_ACTIVE_23 ((uint32_t)0x00800000) /*!< bit 23 */ -#define NVIC_IABR_ACTIVE_24 ((uint32_t)0x01000000) /*!< bit 24 */ -#define NVIC_IABR_ACTIVE_25 ((uint32_t)0x02000000) /*!< bit 25 */ -#define NVIC_IABR_ACTIVE_26 ((uint32_t)0x04000000) /*!< bit 26 */ -#define NVIC_IABR_ACTIVE_27 ((uint32_t)0x08000000) /*!< bit 27 */ -#define NVIC_IABR_ACTIVE_28 ((uint32_t)0x10000000) /*!< bit 28 */ -#define NVIC_IABR_ACTIVE_29 ((uint32_t)0x20000000) /*!< bit 29 */ -#define NVIC_IABR_ACTIVE_30 ((uint32_t)0x40000000) /*!< bit 30 */ -#define NVIC_IABR_ACTIVE_31 ((uint32_t)0x80000000) /*!< bit 31 */ - -/****************** Bit definition for NVIC_PRI0 register *******************/ -#define NVIC_IPR0_PRI_0 ((uint32_t)0x000000FF) /*!< Priority of interrupt 0 */ -#define NVIC_IPR0_PRI_1 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 1 */ -#define NVIC_IPR0_PRI_2 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 2 */ -#define NVIC_IPR0_PRI_3 ((uint32_t)0xFF000000) /*!< Priority of interrupt 3 */ - -/****************** Bit definition for NVIC_PRI1 register *******************/ -#define NVIC_IPR1_PRI_4 ((uint32_t)0x000000FF) /*!< Priority of interrupt 4 */ -#define NVIC_IPR1_PRI_5 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 5 */ -#define NVIC_IPR1_PRI_6 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 6 */ -#define NVIC_IPR1_PRI_7 ((uint32_t)0xFF000000) /*!< Priority of interrupt 7 */ - -/****************** Bit definition for NVIC_PRI2 register *******************/ -#define NVIC_IPR2_PRI_8 ((uint32_t)0x000000FF) /*!< Priority of interrupt 8 */ -#define NVIC_IPR2_PRI_9 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 9 */ -#define NVIC_IPR2_PRI_10 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 10 */ -#define NVIC_IPR2_PRI_11 ((uint32_t)0xFF000000) /*!< Priority of interrupt 11 */ - -/****************** Bit definition for NVIC_PRI3 register *******************/ -#define NVIC_IPR3_PRI_12 ((uint32_t)0x000000FF) /*!< Priority of interrupt 12 */ -#define NVIC_IPR3_PRI_13 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 13 */ -#define NVIC_IPR3_PRI_14 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 14 */ -#define NVIC_IPR3_PRI_15 ((uint32_t)0xFF000000) /*!< Priority of interrupt 15 */ - -/****************** Bit definition for NVIC_PRI4 register *******************/ -#define NVIC_IPR4_PRI_16 ((uint32_t)0x000000FF) /*!< Priority of interrupt 16 */ -#define NVIC_IPR4_PRI_17 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 17 */ -#define NVIC_IPR4_PRI_18 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 18 */ -#define NVIC_IPR4_PRI_19 ((uint32_t)0xFF000000) /*!< Priority of interrupt 19 */ - -/****************** Bit definition for NVIC_PRI5 register *******************/ -#define NVIC_IPR5_PRI_20 ((uint32_t)0x000000FF) /*!< Priority of interrupt 20 */ -#define NVIC_IPR5_PRI_21 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 21 */ -#define NVIC_IPR5_PRI_22 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 22 */ -#define NVIC_IPR5_PRI_23 ((uint32_t)0xFF000000) /*!< Priority of interrupt 23 */ - -/****************** Bit definition for NVIC_PRI6 register *******************/ -#define NVIC_IPR6_PRI_24 ((uint32_t)0x000000FF) /*!< Priority of interrupt 24 */ -#define NVIC_IPR6_PRI_25 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 25 */ -#define NVIC_IPR6_PRI_26 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 26 */ -#define NVIC_IPR6_PRI_27 ((uint32_t)0xFF000000) /*!< Priority of interrupt 27 */ - -/****************** Bit definition for NVIC_PRI7 register *******************/ -#define NVIC_IPR7_PRI_28 ((uint32_t)0x000000FF) /*!< Priority of interrupt 28 */ -#define NVIC_IPR7_PRI_29 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 29 */ -#define NVIC_IPR7_PRI_30 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 30 */ -#define NVIC_IPR7_PRI_31 ((uint32_t)0xFF000000) /*!< Priority of interrupt 31 */ - -/****************** Bit definition for SCB_CPUID register *******************/ -#define SCB_CPUID_REVISION ((uint32_t)0x0000000F) /*!< Implementation defined revision number */ -#define SCB_CPUID_PARTNO ((uint32_t)0x0000FFF0) /*!< Number of processor within family */ -#define SCB_CPUID_Constant ((uint32_t)0x000F0000) /*!< Reads as 0x0F */ -#define SCB_CPUID_VARIANT ((uint32_t)0x00F00000) /*!< Implementation defined variant number */ -#define SCB_CPUID_IMPLEMENTER ((uint32_t)0xFF000000) /*!< Implementer code. ARM is 0x41 */ - -/******************* Bit definition for SCB_ICSR register *******************/ -#define SCB_ICSR_VECTACTIVE ((uint32_t)0x000001FF) /*!< Active ISR number field */ -#define SCB_ICSR_RETTOBASE ((uint32_t)0x00000800) /*!< All active exceptions minus the IPSR_current_exception yields the empty set */ -#define SCB_ICSR_VECTPENDING ((uint32_t)0x003FF000) /*!< Pending ISR number field */ -#define SCB_ICSR_ISRPENDING ((uint32_t)0x00400000) /*!< Interrupt pending flag */ -#define SCB_ICSR_ISRPREEMPT ((uint32_t)0x00800000) /*!< It indicates that a pending interrupt becomes active in the next running cycle */ -#define SCB_ICSR_PENDSTCLR ((uint32_t)0x02000000) /*!< Clear pending SysTick bit */ -#define SCB_ICSR_PENDSTSET ((uint32_t)0x04000000) /*!< Set pending SysTick bit */ -#define SCB_ICSR_PENDSVCLR ((uint32_t)0x08000000) /*!< Clear pending pendSV bit */ -#define SCB_ICSR_PENDSVSET ((uint32_t)0x10000000) /*!< Set pending pendSV bit */ -#define SCB_ICSR_NMIPENDSET ((uint32_t)0x80000000) /*!< Set pending NMI bit */ - -/******************* Bit definition for SCB_VTOR register *******************/ -#define SCB_VTOR_TBLOFF ((uint32_t)0x1FFFFF80) /*!< Vector table base offset field */ -#define SCB_VTOR_TBLBASE ((uint32_t)0x20000000) /*!< Table base in code(0) or RAM(1) */ - -/*!<***************** Bit definition for SCB_AIRCR register *******************/ -#define SCB_AIRCR_VECTRESET ((uint32_t)0x00000001) /*!< System Reset bit */ -#define SCB_AIRCR_VECTCLRACTIVE ((uint32_t)0x00000002) /*!< Clear active vector bit */ -#define SCB_AIRCR_SYSRESETREQ ((uint32_t)0x00000004) /*!< Requests chip control logic to generate a reset */ - -#define SCB_AIRCR_PRIGROUP ((uint32_t)0x00000700) /*!< PRIGROUP[2:0] bits (Priority group) */ -#define SCB_AIRCR_PRIGROUP_0 ((uint32_t)0x00000100) /*!< Bit 0 */ -#define SCB_AIRCR_PRIGROUP_1 ((uint32_t)0x00000200) /*!< Bit 1 */ -#define SCB_AIRCR_PRIGROUP_2 ((uint32_t)0x00000400) /*!< Bit 2 */ - -/* prority group configuration */ -#define SCB_AIRCR_PRIGROUP0 ((uint32_t)0x00000000) /*!< Priority group=0 (7 bits of pre-emption priority, 1 bit of subpriority) */ -#define SCB_AIRCR_PRIGROUP1 ((uint32_t)0x00000100) /*!< Priority group=1 (6 bits of pre-emption priority, 2 bits of subpriority) */ -#define SCB_AIRCR_PRIGROUP2 ((uint32_t)0x00000200) /*!< Priority group=2 (5 bits of pre-emption priority, 3 bits of subpriority) */ -#define SCB_AIRCR_PRIGROUP3 ((uint32_t)0x00000300) /*!< Priority group=3 (4 bits of pre-emption priority, 4 bits of subpriority) */ -#define SCB_AIRCR_PRIGROUP4 ((uint32_t)0x00000400) /*!< Priority group=4 (3 bits of pre-emption priority, 5 bits of subpriority) */ -#define SCB_AIRCR_PRIGROUP5 ((uint32_t)0x00000500) /*!< Priority group=5 (2 bits of pre-emption priority, 6 bits of subpriority) */ -#define SCB_AIRCR_PRIGROUP6 ((uint32_t)0x00000600) /*!< Priority group=6 (1 bit of pre-emption priority, 7 bits of subpriority) */ -#define SCB_AIRCR_PRIGROUP7 ((uint32_t)0x00000700) /*!< Priority group=7 (no pre-emption priority, 8 bits of subpriority) */ - -#define SCB_AIRCR_ENDIANESS ((uint32_t)0x00008000) /*!< Data endianness bit */ -#define SCB_AIRCR_VECTKEY ((uint32_t)0xFFFF0000) /*!< Register key (VECTKEY) - Reads as 0xFA05 (VECTKEYSTAT) */ - -/******************* Bit definition for SCB_SCR register ********************/ -#define SCB_SCR_SLEEPONEXIT ((uint8_t)0x02) /*!< Sleep on exit bit */ -#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04) /*!< Sleep deep bit */ -#define SCB_SCR_SEVONPEND ((uint8_t)0x10) /*!< Wake up from WFE */ - -/******************** Bit definition for SCB_CCR register *******************/ -#define SCB_CCR_NONBASETHRDENA ((uint16_t)0x0001) /*!< Thread mode can be entered from any level in Handler mode by controlled return value */ -#define SCB_CCR_USERSETMPEND ((uint16_t)0x0002) /*!< Enables user code to write the Software Trigger Interrupt register to trigger (pend) a Main exception */ -#define SCB_CCR_UNALIGN_TRP ((uint16_t)0x0008) /*!< Trap for unaligned access */ -#define SCB_CCR_DIV_0_TRP ((uint16_t)0x0010) /*!< Trap on Divide by 0 */ -#define SCB_CCR_BFHFNMIGN ((uint16_t)0x0100) /*!< Handlers running at priority -1 and -2 */ -#define SCB_CCR_STKALIGN ((uint16_t)0x0200) /*!< On exception entry, the SP used prior to the exception is adjusted to be 8-byte aligned */ - -/******************* Bit definition for SCB_SHPR register ********************/ -#define SCB_SHPR_PRI_N ((uint32_t)0x000000FF) /*!< Priority of system handler 4,8, and 12. Mem Manage, reserved and Debug Monitor */ -#define SCB_SHPR_PRI_N1 ((uint32_t)0x0000FF00) /*!< Priority of system handler 5,9, and 13. Bus Fault, reserved and reserved */ -#define SCB_SHPR_PRI_N2 ((uint32_t)0x00FF0000) /*!< Priority of system handler 6,10, and 14. Usage Fault, reserved and PendSV */ -#define SCB_SHPR_PRI_N3 ((uint32_t)0xFF000000) /*!< Priority of system handler 7,11, and 15. Reserved, SVCall and SysTick */ - -/****************** Bit definition for SCB_SHCSR register *******************/ -#define SCB_SHCSR_MEMFAULTACT ((uint32_t)0x00000001) /*!< MemManage is active */ -#define SCB_SHCSR_BUSFAULTACT ((uint32_t)0x00000002) /*!< BusFault is active */ -#define SCB_SHCSR_USGFAULTACT ((uint32_t)0x00000008) /*!< UsageFault is active */ -#define SCB_SHCSR_SVCALLACT ((uint32_t)0x00000080) /*!< SVCall is active */ -#define SCB_SHCSR_MONITORACT ((uint32_t)0x00000100) /*!< Monitor is active */ -#define SCB_SHCSR_PENDSVACT ((uint32_t)0x00000400) /*!< PendSV is active */ -#define SCB_SHCSR_SYSTICKACT ((uint32_t)0x00000800) /*!< SysTick is active */ -#define SCB_SHCSR_USGFAULTPENDED ((uint32_t)0x00001000) /*!< Usage Fault is pended */ -#define SCB_SHCSR_MEMFAULTPENDED ((uint32_t)0x00002000) /*!< MemManage is pended */ -#define SCB_SHCSR_BUSFAULTPENDED ((uint32_t)0x00004000) /*!< Bus Fault is pended */ -#define SCB_SHCSR_SVCALLPENDED ((uint32_t)0x00008000) /*!< SVCall is pended */ -#define SCB_SHCSR_MEMFAULTENA ((uint32_t)0x00010000) /*!< MemManage enable */ -#define SCB_SHCSR_BUSFAULTENA ((uint32_t)0x00020000) /*!< Bus Fault enable */ -#define SCB_SHCSR_USGFAULTENA ((uint32_t)0x00040000) /*!< UsageFault enable */ - -/******************* Bit definition for SCB_CFSR register *******************/ -/*!< MFSR */ -#define SCB_CFSR_IACCVIOL ((uint32_t)0x00000001) /*!< Instruction access violation */ -#define SCB_CFSR_DACCVIOL ((uint32_t)0x00000002) /*!< Data access violation */ -#define SCB_CFSR_MUNSTKERR ((uint32_t)0x00000008) /*!< Unstacking error */ -#define SCB_CFSR_MSTKERR ((uint32_t)0x00000010) /*!< Stacking error */ -#define SCB_CFSR_MMARVALID ((uint32_t)0x00000080) /*!< Memory Manage Address Register address valid flag */ -/*!< BFSR */ -#define SCB_CFSR_IBUSERR ((uint32_t)0x00000100) /*!< Instruction bus error flag */ -#define SCB_CFSR_PRECISERR ((uint32_t)0x00000200) /*!< Precise data bus error */ -#define SCB_CFSR_IMPRECISERR ((uint32_t)0x00000400) /*!< Imprecise data bus error */ -#define SCB_CFSR_UNSTKERR ((uint32_t)0x00000800) /*!< Unstacking error */ -#define SCB_CFSR_STKERR ((uint32_t)0x00001000) /*!< Stacking error */ -#define SCB_CFSR_BFARVALID ((uint32_t)0x00008000) /*!< Bus Fault Address Register address valid flag */ -/*!< UFSR */ -#define SCB_CFSR_UNDEFINSTR ((uint32_t)0x00010000) /*!< The processor attempt to excecute an undefined instruction */ -#define SCB_CFSR_INVSTATE ((uint32_t)0x00020000) /*!< Invalid combination of EPSR and instruction */ -#define SCB_CFSR_INVPC ((uint32_t)0x00040000) /*!< Attempt to load EXC_RETURN into pc illegally */ -#define SCB_CFSR_NOCP ((uint32_t)0x00080000) /*!< Attempt to use a coprocessor instruction */ -#define SCB_CFSR_UNALIGNED ((uint32_t)0x01000000) /*!< Fault occurs when there is an attempt to make an unaligned memory access */ -#define SCB_CFSR_DIVBYZERO ((uint32_t)0x02000000) /*!< Fault occurs when SDIV or DIV instruction is used with a divisor of 0 */ - -/******************* Bit definition for SCB_HFSR register *******************/ -#define SCB_HFSR_VECTTBL ((uint32_t)0x00000002) /*!< Fault occures because of vector table read on exception processing */ -#define SCB_HFSR_FORCED ((uint32_t)0x40000000) /*!< Hard Fault activated when a configurable Fault was received and cannot activate */ -#define SCB_HFSR_DEBUGEVT ((uint32_t)0x80000000) /*!< Fault related to debug */ - -/******************* Bit definition for SCB_DFSR register *******************/ -#define SCB_DFSR_HALTED ((uint8_t)0x01) /*!< Halt request flag */ -#define SCB_DFSR_BKPT ((uint8_t)0x02) /*!< BKPT flag */ -#define SCB_DFSR_DWTTRAP ((uint8_t)0x04) /*!< Data Watchpoint and Trace (DWT) flag */ -#define SCB_DFSR_VCATCH ((uint8_t)0x08) /*!< Vector catch flag */ -#define SCB_DFSR_EXTERNAL ((uint8_t)0x10) /*!< External debug request flag */ - -/******************* Bit definition for SCB_MMFAR register ******************/ -#define SCB_MMFAR_ADDRESS ((uint32_t)0xFFFFFFFF) /*!< Mem Manage fault address field */ - -/******************* Bit definition for SCB_BFAR register *******************/ -#define SCB_BFAR_ADDRESS ((uint32_t)0xFFFFFFFF) /*!< Bus fault address field */ - -/******************* Bit definition for SCB_afsr register *******************/ -#define SCB_AFSR_IMPDEF ((uint32_t)0xFFFFFFFF) /*!< Implementation defined */ - -/******************************************************************************/ -/* */ -/* External Interrupt/Event Controller */ -/* */ -/******************************************************************************/ - -/******************* Bit definition for EXTI_IMR register *******************/ -#define EXTI_IMR_MR0 ((uint32_t)0x00000001) /*!< Interrupt Mask on line 0 */ -#define EXTI_IMR_MR1 ((uint32_t)0x00000002) /*!< Interrupt Mask on line 1 */ -#define EXTI_IMR_MR2 ((uint32_t)0x00000004) /*!< Interrupt Mask on line 2 */ -#define EXTI_IMR_MR3 ((uint32_t)0x00000008) /*!< Interrupt Mask on line 3 */ -#define EXTI_IMR_MR4 ((uint32_t)0x00000010) /*!< Interrupt Mask on line 4 */ -#define EXTI_IMR_MR5 ((uint32_t)0x00000020) /*!< Interrupt Mask on line 5 */ -#define EXTI_IMR_MR6 ((uint32_t)0x00000040) /*!< Interrupt Mask on line 6 */ -#define EXTI_IMR_MR7 ((uint32_t)0x00000080) /*!< Interrupt Mask on line 7 */ -#define EXTI_IMR_MR8 ((uint32_t)0x00000100) /*!< Interrupt Mask on line 8 */ -#define EXTI_IMR_MR9 ((uint32_t)0x00000200) /*!< Interrupt Mask on line 9 */ -#define EXTI_IMR_MR10 ((uint32_t)0x00000400) /*!< Interrupt Mask on line 10 */ -#define EXTI_IMR_MR11 ((uint32_t)0x00000800) /*!< Interrupt Mask on line 11 */ -#define EXTI_IMR_MR12 ((uint32_t)0x00001000) /*!< Interrupt Mask on line 12 */ -#define EXTI_IMR_MR13 ((uint32_t)0x00002000) /*!< Interrupt Mask on line 13 */ -#define EXTI_IMR_MR14 ((uint32_t)0x00004000) /*!< Interrupt Mask on line 14 */ -#define EXTI_IMR_MR15 ((uint32_t)0x00008000) /*!< Interrupt Mask on line 15 */ -#define EXTI_IMR_MR16 ((uint32_t)0x00010000) /*!< Interrupt Mask on line 16 */ -#define EXTI_IMR_MR17 ((uint32_t)0x00020000) /*!< Interrupt Mask on line 17 */ -#define EXTI_IMR_MR18 ((uint32_t)0x00040000) /*!< Interrupt Mask on line 18 */ -#define EXTI_IMR_MR19 ((uint32_t)0x00080000) /*!< Interrupt Mask on line 19 */ - -/******************* Bit definition for EXTI_EMR register *******************/ -#define EXTI_EMR_MR0 ((uint32_t)0x00000001) /*!< Event Mask on line 0 */ -#define EXTI_EMR_MR1 ((uint32_t)0x00000002) /*!< Event Mask on line 1 */ -#define EXTI_EMR_MR2 ((uint32_t)0x00000004) /*!< Event Mask on line 2 */ -#define EXTI_EMR_MR3 ((uint32_t)0x00000008) /*!< Event Mask on line 3 */ -#define EXTI_EMR_MR4 ((uint32_t)0x00000010) /*!< Event Mask on line 4 */ -#define EXTI_EMR_MR5 ((uint32_t)0x00000020) /*!< Event Mask on line 5 */ -#define EXTI_EMR_MR6 ((uint32_t)0x00000040) /*!< Event Mask on line 6 */ -#define EXTI_EMR_MR7 ((uint32_t)0x00000080) /*!< Event Mask on line 7 */ -#define EXTI_EMR_MR8 ((uint32_t)0x00000100) /*!< Event Mask on line 8 */ -#define EXTI_EMR_MR9 ((uint32_t)0x00000200) /*!< Event Mask on line 9 */ -#define EXTI_EMR_MR10 ((uint32_t)0x00000400) /*!< Event Mask on line 10 */ -#define EXTI_EMR_MR11 ((uint32_t)0x00000800) /*!< Event Mask on line 11 */ -#define EXTI_EMR_MR12 ((uint32_t)0x00001000) /*!< Event Mask on line 12 */ -#define EXTI_EMR_MR13 ((uint32_t)0x00002000) /*!< Event Mask on line 13 */ -#define EXTI_EMR_MR14 ((uint32_t)0x00004000) /*!< Event Mask on line 14 */ -#define EXTI_EMR_MR15 ((uint32_t)0x00008000) /*!< Event Mask on line 15 */ -#define EXTI_EMR_MR16 ((uint32_t)0x00010000) /*!< Event Mask on line 16 */ -#define EXTI_EMR_MR17 ((uint32_t)0x00020000) /*!< Event Mask on line 17 */ -#define EXTI_EMR_MR18 ((uint32_t)0x00040000) /*!< Event Mask on line 18 */ -#define EXTI_EMR_MR19 ((uint32_t)0x00080000) /*!< Event Mask on line 19 */ - -/****************** Bit definition for EXTI_RTSR register *******************/ -#define EXTI_RTSR_TR0 ((uint32_t)0x00000001) /*!< Rising trigger event configuration bit of line 0 */ -#define EXTI_RTSR_TR1 ((uint32_t)0x00000002) /*!< Rising trigger event configuration bit of line 1 */ -#define EXTI_RTSR_TR2 ((uint32_t)0x00000004) /*!< Rising trigger event configuration bit of line 2 */ -#define EXTI_RTSR_TR3 ((uint32_t)0x00000008) /*!< Rising trigger event configuration bit of line 3 */ -#define EXTI_RTSR_TR4 ((uint32_t)0x00000010) /*!< Rising trigger event configuration bit of line 4 */ -#define EXTI_RTSR_TR5 ((uint32_t)0x00000020) /*!< Rising trigger event configuration bit of line 5 */ -#define EXTI_RTSR_TR6 ((uint32_t)0x00000040) /*!< Rising trigger event configuration bit of line 6 */ -#define EXTI_RTSR_TR7 ((uint32_t)0x00000080) /*!< Rising trigger event configuration bit of line 7 */ -#define EXTI_RTSR_TR8 ((uint32_t)0x00000100) /*!< Rising trigger event configuration bit of line 8 */ -#define EXTI_RTSR_TR9 ((uint32_t)0x00000200) /*!< Rising trigger event configuration bit of line 9 */ -#define EXTI_RTSR_TR10 ((uint32_t)0x00000400) /*!< Rising trigger event configuration bit of line 10 */ -#define EXTI_RTSR_TR11 ((uint32_t)0x00000800) /*!< Rising trigger event configuration bit of line 11 */ -#define EXTI_RTSR_TR12 ((uint32_t)0x00001000) /*!< Rising trigger event configuration bit of line 12 */ -#define EXTI_RTSR_TR13 ((uint32_t)0x00002000) /*!< Rising trigger event configuration bit of line 13 */ -#define EXTI_RTSR_TR14 ((uint32_t)0x00004000) /*!< Rising trigger event configuration bit of line 14 */ -#define EXTI_RTSR_TR15 ((uint32_t)0x00008000) /*!< Rising trigger event configuration bit of line 15 */ -#define EXTI_RTSR_TR16 ((uint32_t)0x00010000) /*!< Rising trigger event configuration bit of line 16 */ -#define EXTI_RTSR_TR17 ((uint32_t)0x00020000) /*!< Rising trigger event configuration bit of line 17 */ -#define EXTI_RTSR_TR18 ((uint32_t)0x00040000) /*!< Rising trigger event configuration bit of line 18 */ -#define EXTI_RTSR_TR19 ((uint32_t)0x00080000) /*!< Rising trigger event configuration bit of line 19 */ - -/****************** Bit definition for EXTI_FTSR register *******************/ -#define EXTI_FTSR_TR0 ((uint32_t)0x00000001) /*!< Falling trigger event configuration bit of line 0 */ -#define EXTI_FTSR_TR1 ((uint32_t)0x00000002) /*!< Falling trigger event configuration bit of line 1 */ -#define EXTI_FTSR_TR2 ((uint32_t)0x00000004) /*!< Falling trigger event configuration bit of line 2 */ -#define EXTI_FTSR_TR3 ((uint32_t)0x00000008) /*!< Falling trigger event configuration bit of line 3 */ -#define EXTI_FTSR_TR4 ((uint32_t)0x00000010) /*!< Falling trigger event configuration bit of line 4 */ -#define EXTI_FTSR_TR5 ((uint32_t)0x00000020) /*!< Falling trigger event configuration bit of line 5 */ -#define EXTI_FTSR_TR6 ((uint32_t)0x00000040) /*!< Falling trigger event configuration bit of line 6 */ -#define EXTI_FTSR_TR7 ((uint32_t)0x00000080) /*!< Falling trigger event configuration bit of line 7 */ -#define EXTI_FTSR_TR8 ((uint32_t)0x00000100) /*!< Falling trigger event configuration bit of line 8 */ -#define EXTI_FTSR_TR9 ((uint32_t)0x00000200) /*!< Falling trigger event configuration bit of line 9 */ -#define EXTI_FTSR_TR10 ((uint32_t)0x00000400) /*!< Falling trigger event configuration bit of line 10 */ -#define EXTI_FTSR_TR11 ((uint32_t)0x00000800) /*!< Falling trigger event configuration bit of line 11 */ -#define EXTI_FTSR_TR12 ((uint32_t)0x00001000) /*!< Falling trigger event configuration bit of line 12 */ -#define EXTI_FTSR_TR13 ((uint32_t)0x00002000) /*!< Falling trigger event configuration bit of line 13 */ -#define EXTI_FTSR_TR14 ((uint32_t)0x00004000) /*!< Falling trigger event configuration bit of line 14 */ -#define EXTI_FTSR_TR15 ((uint32_t)0x00008000) /*!< Falling trigger event configuration bit of line 15 */ -#define EXTI_FTSR_TR16 ((uint32_t)0x00010000) /*!< Falling trigger event configuration bit of line 16 */ -#define EXTI_FTSR_TR17 ((uint32_t)0x00020000) /*!< Falling trigger event configuration bit of line 17 */ -#define EXTI_FTSR_TR18 ((uint32_t)0x00040000) /*!< Falling trigger event configuration bit of line 18 */ -#define EXTI_FTSR_TR19 ((uint32_t)0x00080000) /*!< Falling trigger event configuration bit of line 19 */ - -/****************** Bit definition for EXTI_SWIER register ******************/ -#define EXTI_SWIER_SWIER0 ((uint32_t)0x00000001) /*!< Software Interrupt on line 0 */ -#define EXTI_SWIER_SWIER1 ((uint32_t)0x00000002) /*!< Software Interrupt on line 1 */ -#define EXTI_SWIER_SWIER2 ((uint32_t)0x00000004) /*!< Software Interrupt on line 2 */ -#define EXTI_SWIER_SWIER3 ((uint32_t)0x00000008) /*!< Software Interrupt on line 3 */ -#define EXTI_SWIER_SWIER4 ((uint32_t)0x00000010) /*!< Software Interrupt on line 4 */ -#define EXTI_SWIER_SWIER5 ((uint32_t)0x00000020) /*!< Software Interrupt on line 5 */ -#define EXTI_SWIER_SWIER6 ((uint32_t)0x00000040) /*!< Software Interrupt on line 6 */ -#define EXTI_SWIER_SWIER7 ((uint32_t)0x00000080) /*!< Software Interrupt on line 7 */ -#define EXTI_SWIER_SWIER8 ((uint32_t)0x00000100) /*!< Software Interrupt on line 8 */ -#define EXTI_SWIER_SWIER9 ((uint32_t)0x00000200) /*!< Software Interrupt on line 9 */ -#define EXTI_SWIER_SWIER10 ((uint32_t)0x00000400) /*!< Software Interrupt on line 10 */ -#define EXTI_SWIER_SWIER11 ((uint32_t)0x00000800) /*!< Software Interrupt on line 11 */ -#define EXTI_SWIER_SWIER12 ((uint32_t)0x00001000) /*!< Software Interrupt on line 12 */ -#define EXTI_SWIER_SWIER13 ((uint32_t)0x00002000) /*!< Software Interrupt on line 13 */ -#define EXTI_SWIER_SWIER14 ((uint32_t)0x00004000) /*!< Software Interrupt on line 14 */ -#define EXTI_SWIER_SWIER15 ((uint32_t)0x00008000) /*!< Software Interrupt on line 15 */ -#define EXTI_SWIER_SWIER16 ((uint32_t)0x00010000) /*!< Software Interrupt on line 16 */ -#define EXTI_SWIER_SWIER17 ((uint32_t)0x00020000) /*!< Software Interrupt on line 17 */ -#define EXTI_SWIER_SWIER18 ((uint32_t)0x00040000) /*!< Software Interrupt on line 18 */ -#define EXTI_SWIER_SWIER19 ((uint32_t)0x00080000) /*!< Software Interrupt on line 19 */ - -/******************* Bit definition for EXTI_PR register ********************/ -#define EXTI_PR_PR0 ((uint32_t)0x00000001) /*!< Pending bit for line 0 */ -#define EXTI_PR_PR1 ((uint32_t)0x00000002) /*!< Pending bit for line 1 */ -#define EXTI_PR_PR2 ((uint32_t)0x00000004) /*!< Pending bit for line 2 */ -#define EXTI_PR_PR3 ((uint32_t)0x00000008) /*!< Pending bit for line 3 */ -#define EXTI_PR_PR4 ((uint32_t)0x00000010) /*!< Pending bit for line 4 */ -#define EXTI_PR_PR5 ((uint32_t)0x00000020) /*!< Pending bit for line 5 */ -#define EXTI_PR_PR6 ((uint32_t)0x00000040) /*!< Pending bit for line 6 */ -#define EXTI_PR_PR7 ((uint32_t)0x00000080) /*!< Pending bit for line 7 */ -#define EXTI_PR_PR8 ((uint32_t)0x00000100) /*!< Pending bit for line 8 */ -#define EXTI_PR_PR9 ((uint32_t)0x00000200) /*!< Pending bit for line 9 */ -#define EXTI_PR_PR10 ((uint32_t)0x00000400) /*!< Pending bit for line 10 */ -#define EXTI_PR_PR11 ((uint32_t)0x00000800) /*!< Pending bit for line 11 */ -#define EXTI_PR_PR12 ((uint32_t)0x00001000) /*!< Pending bit for line 12 */ -#define EXTI_PR_PR13 ((uint32_t)0x00002000) /*!< Pending bit for line 13 */ -#define EXTI_PR_PR14 ((uint32_t)0x00004000) /*!< Pending bit for line 14 */ -#define EXTI_PR_PR15 ((uint32_t)0x00008000) /*!< Pending bit for line 15 */ -#define EXTI_PR_PR16 ((uint32_t)0x00010000) /*!< Pending bit for line 16 */ -#define EXTI_PR_PR17 ((uint32_t)0x00020000) /*!< Pending bit for line 17 */ -#define EXTI_PR_PR18 ((uint32_t)0x00040000) /*!< Pending bit for line 18 */ -#define EXTI_PR_PR19 ((uint32_t)0x00080000) /*!< Pending bit for line 19 */ - -/******************************************************************************/ -/* */ -/* DMA Controller */ -/* */ -/******************************************************************************/ - -/******************* Bit definition for DMA_ISR register ********************/ -#define DMA_ISR_GIF1 ((uint32_t)0x00000001) /*!< Channel 1 Global interrupt flag */ -#define DMA_ISR_TCIF1 ((uint32_t)0x00000002) /*!< Channel 1 Transfer Complete flag */ -#define DMA_ISR_HTIF1 ((uint32_t)0x00000004) /*!< Channel 1 Half Transfer flag */ -#define DMA_ISR_TEIF1 ((uint32_t)0x00000008) /*!< Channel 1 Transfer Error flag */ -#define DMA_ISR_GIF2 ((uint32_t)0x00000010) /*!< Channel 2 Global interrupt flag */ -#define DMA_ISR_TCIF2 ((uint32_t)0x00000020) /*!< Channel 2 Transfer Complete flag */ -#define DMA_ISR_HTIF2 ((uint32_t)0x00000040) /*!< Channel 2 Half Transfer flag */ -#define DMA_ISR_TEIF2 ((uint32_t)0x00000080) /*!< Channel 2 Transfer Error flag */ -#define DMA_ISR_GIF3 ((uint32_t)0x00000100) /*!< Channel 3 Global interrupt flag */ -#define DMA_ISR_TCIF3 ((uint32_t)0x00000200) /*!< Channel 3 Transfer Complete flag */ -#define DMA_ISR_HTIF3 ((uint32_t)0x00000400) /*!< Channel 3 Half Transfer flag */ -#define DMA_ISR_TEIF3 ((uint32_t)0x00000800) /*!< Channel 3 Transfer Error flag */ -#define DMA_ISR_GIF4 ((uint32_t)0x00001000) /*!< Channel 4 Global interrupt flag */ -#define DMA_ISR_TCIF4 ((uint32_t)0x00002000) /*!< Channel 4 Transfer Complete flag */ -#define DMA_ISR_HTIF4 ((uint32_t)0x00004000) /*!< Channel 4 Half Transfer flag */ -#define DMA_ISR_TEIF4 ((uint32_t)0x00008000) /*!< Channel 4 Transfer Error flag */ -#define DMA_ISR_GIF5 ((uint32_t)0x00010000) /*!< Channel 5 Global interrupt flag */ -#define DMA_ISR_TCIF5 ((uint32_t)0x00020000) /*!< Channel 5 Transfer Complete flag */ -#define DMA_ISR_HTIF5 ((uint32_t)0x00040000) /*!< Channel 5 Half Transfer flag */ -#define DMA_ISR_TEIF5 ((uint32_t)0x00080000) /*!< Channel 5 Transfer Error flag */ -#define DMA_ISR_GIF6 ((uint32_t)0x00100000) /*!< Channel 6 Global interrupt flag */ -#define DMA_ISR_TCIF6 ((uint32_t)0x00200000) /*!< Channel 6 Transfer Complete flag */ -#define DMA_ISR_HTIF6 ((uint32_t)0x00400000) /*!< Channel 6 Half Transfer flag */ -#define DMA_ISR_TEIF6 ((uint32_t)0x00800000) /*!< Channel 6 Transfer Error flag */ -#define DMA_ISR_GIF7 ((uint32_t)0x01000000) /*!< Channel 7 Global interrupt flag */ -#define DMA_ISR_TCIF7 ((uint32_t)0x02000000) /*!< Channel 7 Transfer Complete flag */ -#define DMA_ISR_HTIF7 ((uint32_t)0x04000000) /*!< Channel 7 Half Transfer flag */ -#define DMA_ISR_TEIF7 ((uint32_t)0x08000000) /*!< Channel 7 Transfer Error flag */ - -/******************* Bit definition for DMA_IFCR register *******************/ -#define DMA_IFCR_CGIF1 ((uint32_t)0x00000001) /*!< Channel 1 Global interrupt clearr */ -#define DMA_IFCR_CTCIF1 ((uint32_t)0x00000002) /*!< Channel 1 Transfer Complete clear */ -#define DMA_IFCR_CHTIF1 ((uint32_t)0x00000004) /*!< Channel 1 Half Transfer clear */ -#define DMA_IFCR_CTEIF1 ((uint32_t)0x00000008) /*!< Channel 1 Transfer Error clear */ -#define DMA_IFCR_CGIF2 ((uint32_t)0x00000010) /*!< Channel 2 Global interrupt clear */ -#define DMA_IFCR_CTCIF2 ((uint32_t)0x00000020) /*!< Channel 2 Transfer Complete clear */ -#define DMA_IFCR_CHTIF2 ((uint32_t)0x00000040) /*!< Channel 2 Half Transfer clear */ -#define DMA_IFCR_CTEIF2 ((uint32_t)0x00000080) /*!< Channel 2 Transfer Error clear */ -#define DMA_IFCR_CGIF3 ((uint32_t)0x00000100) /*!< Channel 3 Global interrupt clear */ -#define DMA_IFCR_CTCIF3 ((uint32_t)0x00000200) /*!< Channel 3 Transfer Complete clear */ -#define DMA_IFCR_CHTIF3 ((uint32_t)0x00000400) /*!< Channel 3 Half Transfer clear */ -#define DMA_IFCR_CTEIF3 ((uint32_t)0x00000800) /*!< Channel 3 Transfer Error clear */ -#define DMA_IFCR_CGIF4 ((uint32_t)0x00001000) /*!< Channel 4 Global interrupt clear */ -#define DMA_IFCR_CTCIF4 ((uint32_t)0x00002000) /*!< Channel 4 Transfer Complete clear */ -#define DMA_IFCR_CHTIF4 ((uint32_t)0x00004000) /*!< Channel 4 Half Transfer clear */ -#define DMA_IFCR_CTEIF4 ((uint32_t)0x00008000) /*!< Channel 4 Transfer Error clear */ -#define DMA_IFCR_CGIF5 ((uint32_t)0x00010000) /*!< Channel 5 Global interrupt clear */ -#define DMA_IFCR_CTCIF5 ((uint32_t)0x00020000) /*!< Channel 5 Transfer Complete clear */ -#define DMA_IFCR_CHTIF5 ((uint32_t)0x00040000) /*!< Channel 5 Half Transfer clear */ -#define DMA_IFCR_CTEIF5 ((uint32_t)0x00080000) /*!< Channel 5 Transfer Error clear */ -#define DMA_IFCR_CGIF6 ((uint32_t)0x00100000) /*!< Channel 6 Global interrupt clear */ -#define DMA_IFCR_CTCIF6 ((uint32_t)0x00200000) /*!< Channel 6 Transfer Complete clear */ -#define DMA_IFCR_CHTIF6 ((uint32_t)0x00400000) /*!< Channel 6 Half Transfer clear */ -#define DMA_IFCR_CTEIF6 ((uint32_t)0x00800000) /*!< Channel 6 Transfer Error clear */ -#define DMA_IFCR_CGIF7 ((uint32_t)0x01000000) /*!< Channel 7 Global interrupt clear */ -#define DMA_IFCR_CTCIF7 ((uint32_t)0x02000000) /*!< Channel 7 Transfer Complete clear */ -#define DMA_IFCR_CHTIF7 ((uint32_t)0x04000000) /*!< Channel 7 Half Transfer clear */ -#define DMA_IFCR_CTEIF7 ((uint32_t)0x08000000) /*!< Channel 7 Transfer Error clear */ - -/******************* Bit definition for DMA_CCR1 register *******************/ -#define DMA_CCR1_EN ((uint16_t)0x0001) /*!< Channel enable*/ -#define DMA_CCR1_TCIE ((uint16_t)0x0002) /*!< Transfer complete interrupt enable */ -#define DMA_CCR1_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */ -#define DMA_CCR1_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */ -#define DMA_CCR1_DIR ((uint16_t)0x0010) /*!< Data transfer direction */ -#define DMA_CCR1_CIRC ((uint16_t)0x0020) /*!< Circular mode */ -#define DMA_CCR1_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */ -#define DMA_CCR1_MINC ((uint16_t)0x0080) /*!< Memory increment mode */ - -#define DMA_CCR1_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */ -#define DMA_CCR1_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */ -#define DMA_CCR1_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */ - -#define DMA_CCR1_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */ -#define DMA_CCR1_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */ -#define DMA_CCR1_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */ - -#define DMA_CCR1_PL ((uint16_t)0x3000) /*!< PL[1:0] bits(Channel Priority level) */ -#define DMA_CCR1_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */ -#define DMA_CCR1_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */ - -#define DMA_CCR1_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */ - -/******************* Bit definition for DMA_CCR2 register *******************/ -#define DMA_CCR2_EN ((uint16_t)0x0001) /*!< Channel enable */ -#define DMA_CCR2_TCIE ((uint16_t)0x0002) /*!< ransfer complete interrupt enable */ -#define DMA_CCR2_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */ -#define DMA_CCR2_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */ -#define DMA_CCR2_DIR ((uint16_t)0x0010) /*!< Data transfer direction */ -#define DMA_CCR2_CIRC ((uint16_t)0x0020) /*!< Circular mode */ -#define DMA_CCR2_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */ -#define DMA_CCR2_MINC ((uint16_t)0x0080) /*!< Memory increment mode */ - -#define DMA_CCR2_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */ -#define DMA_CCR2_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */ -#define DMA_CCR2_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */ - -#define DMA_CCR2_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */ -#define DMA_CCR2_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */ -#define DMA_CCR2_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */ - -#define DMA_CCR2_PL ((uint16_t)0x3000) /*!< PL[1:0] bits (Channel Priority level) */ -#define DMA_CCR2_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */ -#define DMA_CCR2_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */ - -#define DMA_CCR2_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */ - -/******************* Bit definition for DMA_CCR3 register *******************/ -#define DMA_CCR3_EN ((uint16_t)0x0001) /*!< Channel enable */ -#define DMA_CCR3_TCIE ((uint16_t)0x0002) /*!< Transfer complete interrupt enable */ -#define DMA_CCR3_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */ -#define DMA_CCR3_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */ -#define DMA_CCR3_DIR ((uint16_t)0x0010) /*!< Data transfer direction */ -#define DMA_CCR3_CIRC ((uint16_t)0x0020) /*!< Circular mode */ -#define DMA_CCR3_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */ -#define DMA_CCR3_MINC ((uint16_t)0x0080) /*!< Memory increment mode */ - -#define DMA_CCR3_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */ -#define DMA_CCR3_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */ -#define DMA_CCR3_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */ - -#define DMA_CCR3_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */ -#define DMA_CCR3_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */ -#define DMA_CCR3_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */ - -#define DMA_CCR3_PL ((uint16_t)0x3000) /*!< PL[1:0] bits (Channel Priority level) */ -#define DMA_CCR3_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */ -#define DMA_CCR3_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */ - -#define DMA_CCR3_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */ - -/*!<****************** Bit definition for DMA_CCR4 register *******************/ -#define DMA_CCR4_EN ((uint16_t)0x0001) /*!
© COPYRIGHT 2010 STMicroelectronics
- ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32l1xx - * @{ - */ - -#ifndef __STM32L1XX_H -#define __STM32L1XX_H - -#ifdef __cplusplus - extern "C" { -#endif - -#define assert_param(__p) - -/** @addtogroup Library_configuration_section - * @{ - */ - -/* Uncomment the line below according to the target STM32L device used in your - application - */ - -#if !defined (STM32L1XX_MD) - #define STM32L1XX_MD /*!< STM32L1XX_MD: STM32L Ultra Low Power Medium-density devices */ -#endif -/* Tip: To avoid modifying this file each time you need to switch between these - devices, you can define the device in your toolchain compiler preprocessor. - - - Ultra Low Power Medium-density devices are STM32L151xx and STM32L152xx - microcontrollers where the Flash memory density ranges between 64 and 128 Kbytes. - - */ - -#if !defined (STM32L1XX_MD) - #error "Please select first the target STM32L1xx device used in your application (in stm32l1xx.h file)" -#endif - -#if !defined USE_STDPERIPH_DRIVER -/** - * @brief Comment the line below if you will not use the peripherals drivers. - In this case, these drivers will not be included and the application code will - be based on direct access to peripherals registers - */ - /*#define USE_STDPERIPH_DRIVER*/ -#endif - -/** - * @brief In the following line adjust the value of External High Speed oscillator (HSE) - used in your application - - Tip: To avoid modifying this file each time you need to use different HSE, you - can define the HSE value in your toolchain compiler preprocessor. - */ -#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz*/ - -/** - * @brief In the following line adjust the External High Speed oscillator (HSE) Startup - Timeout value - */ -#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */ - -/** - * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup - Timeout value - */ -#define HSI_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSI start up */ - -#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal High Speed oscillator in Hz. - The real value may vary depending on the variations - in voltage and temperature. */ -#define LSI_VALUE ((uint32_t)37000) /*!< Value of the Internal Low Speed oscillator in Hz - The real value may vary depending on the variations - in voltage and temperature. */ -#define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */ - -/** - * @brief STM32L1xx Standard Peripheral Library version number - */ -#define __STM32L1XX_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ -#define __STM32L1XX_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ -#define __STM32L1XX_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ -#define __STM32L1XX_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ -#define __STM32L1XX_STDPERIPH_VERSION ( (__STM32L1XX_STDPERIPH_VERSION_MAIN << 24)\ - |(__STM32L1XX_STDPERIPH_VERSION_SUB1 << 16)\ - |(__STM32L1XX_STDPERIPH_VERSION_SUB2 << 8)\ - |(__STM32L1XX_STDPERIPH_VERSION_RC)) - -/** - * @} - */ - -/** @addtogroup Configuration_section_for_CMSIS - * @{ - */ - -/** - * @brief STM32L1xx Interrupt Number Definition, according to the selected device - * in @ref Library_configuration_section - */ -#define __MPU_PRESENT 1 /*!< STM32L provides MPU */ -#define __NVIC_PRIO_BITS 4 /*!< STM32 uses 4 Bits for the Priority Levels */ -#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ - -/*!< Interrupt Number Definition */ -typedef enum IRQn -{ -/****** Cortex-M3 Processor Exceptions Numbers ******************************************************/ - NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ - MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */ - BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */ - UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */ - SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */ - DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */ - PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */ - SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */ - -/****** STM32L specific Interrupt Numbers ***********************************************************/ - WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ - PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ - TAMPER_STAMP_IRQn = 2, /*!< Tamper and Time Stamp through EXTI Line Interrupts */ - RTC_WKUP_IRQn = 3, /*!< RTC Wakeup Timer through EXTI Line Interrupt */ - FLASH_IRQn = 4, /*!< FLASH global Interrupt */ - RCC_IRQn = 5, /*!< RCC global Interrupt */ - EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ - EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ - EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ - EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ - EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ - DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */ - DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */ - DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */ - DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */ - DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */ - DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */ - DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */ - ADC1_IRQn = 18, /*!< ADC1 global Interrupt */ - USB_HP_IRQn = 19, /*!< USB High Priority Interrupt */ - USB_LP_IRQn = 20, /*!< USB Low Priority Interrupt */ - DAC_IRQn = 21, /*!< DAC Interrupt */ - COMP_IRQn = 22, /*!< Comparator through EXTI Line Interrupt */ - EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ - LCD_IRQn = 24, /*!< LCD Interrupt */ - TIM9_IRQn = 25, /*!< TIM9 global Interrupt */ - TIM10_IRQn = 26, /*!< TIM10 global Interrupt */ - TIM11_IRQn = 27, /*!< TIM11 global Interrupt */ - TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ - TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ - TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ - I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ - I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ - I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ - I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ - SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ - SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ - USART1_IRQn = 37, /*!< USART1 global Interrupt */ - USART2_IRQn = 38, /*!< USART2 global Interrupt */ - USART3_IRQn = 39, /*!< USART3 global Interrupt */ - EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTC_Alarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */ - USB_FS_WKUP_IRQn = 42, /*!< USB FS WakeUp from suspend through EXTI Line Interrupt */ - TIM6_IRQn = 43, /*!< TIM6 global Interrupt */ - TIM7_IRQn = 44 /*!< TIM7 global Interrupt */ -} IRQn_Type; - -/** - * @} - */ - -#include "core_cm3.h" -#include "system_stm32l1xx.h" -#include - -/** @addtogroup Exported_types - * @{ - */ - -typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; - -typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; -#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) - -typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; - -/** - * @brief __RAM_FUNC definition - */ -#if defined ( __CC_ARM ) -/* ARM Compiler - ------------ - RAM functions are defined using the toolchain options. - Functions that are executed in RAM should reside in a separate source - module. Using the 'Options for File' dialog you can simply change the - 'Code / Const' area of a module to a memory space in physical RAM. - Available memory areas are declared in the 'Target' tab of the - 'Options for Target' dialog. -*/ - #define __RAM_FUNC FLASH_Status - -#elif defined ( __ICCARM__ ) -/* ICCARM Compiler - --------------- - RAM functions are defined using a specific toolchain keyword "__ramfunc". -*/ - #define __RAM_FUNC __ramfunc FLASH_Status - -#elif defined ( __GNUC__ ) -/* GNU Compiler - ------------ - RAM functions are defined using a specific toolchain attribute - "__attribute__((section(".data")))". -*/ - #define __RAM_FUNC FLASH_Status __attribute__((section(".data"))) - -#elif defined ( __TASKING__ ) -/* TASKING Compiler - ---------------- - RAM functions are defined using a specific toolchain pragma. This pragma is - defined in the stm32l1xx_flash_ramfunc.c -*/ - #define __RAM_FUNC FLASH_Status - -#endif - -/** - * @} - */ - -/** @addtogroup Peripheral_registers_structures - * @{ - */ - -/** - * @brief Analog to Digital Converter - */ - -typedef struct -{ - __IO uint32_t SR; - __IO uint32_t CR1; - __IO uint32_t CR2; - __IO uint32_t SMPR1; - __IO uint32_t SMPR2; - __IO uint32_t SMPR3; - __IO uint32_t JOFR1; - __IO uint32_t JOFR2; - __IO uint32_t JOFR3; - __IO uint32_t JOFR4; - __IO uint32_t HTR; - __IO uint32_t LTR; - __IO uint32_t SQR1; - __IO uint32_t SQR2; - __IO uint32_t SQR3; - __IO uint32_t SQR4; - __IO uint32_t SQR5; - __IO uint32_t JSQR; - __IO uint32_t JDR1; - __IO uint32_t JDR2; - __IO uint32_t JDR3; - __IO uint32_t JDR4; - __IO uint32_t DR; -} ADC_TypeDef; - -typedef struct -{ - __IO uint32_t CSR; - __IO uint32_t CCR; -} ADC_Common_TypeDef; - - -/** - * @brief Comparator - */ - -typedef struct -{ - __IO uint32_t CSR; -} COMP_TypeDef; - -/** - * @brief CRC calculation unit - */ - -typedef struct -{ - __IO uint32_t DR; - __IO uint8_t IDR; - uint8_t RESERVED0; - uint16_t RESERVED1; - __IO uint32_t CR; -} CRC_TypeDef; - -/** - * @brief Digital to Analog Converter - */ - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t SWTRIGR; - __IO uint32_t DHR12R1; - __IO uint32_t DHR12L1; - __IO uint32_t DHR8R1; - __IO uint32_t DHR12R2; - __IO uint32_t DHR12L2; - __IO uint32_t DHR8R2; - __IO uint32_t DHR12RD; - __IO uint32_t DHR12LD; - __IO uint32_t DHR8RD; - __IO uint32_t DOR1; - __IO uint32_t DOR2; - __IO uint32_t SR; -} DAC_TypeDef; - -/** - * @brief Debug MCU - */ - -typedef struct -{ - __IO uint32_t IDCODE; - __IO uint32_t CR; - __IO uint32_t APB1FZ; - __IO uint32_t APB2FZ; -}DBGMCU_TypeDef; - -/** - * @brief DMA Controller - */ - -typedef struct -{ - __IO uint32_t CCR; - __IO uint32_t CNDTR; - __IO uint32_t CPAR; - __IO uint32_t CMAR; -} DMA_Channel_TypeDef; - -typedef struct -{ - __IO uint32_t ISR; - __IO uint32_t IFCR; -} DMA_TypeDef; - -/** - * @brief External Interrupt/Event Controller - */ - -typedef struct -{ - __IO uint32_t IMR; - __IO uint32_t EMR; - __IO uint32_t RTSR; - __IO uint32_t FTSR; - __IO uint32_t SWIER; - __IO uint32_t PR; -} EXTI_TypeDef; - -/** - * @brief FLASH Registers - */ - -typedef struct -{ - __IO uint32_t ACR; - __IO uint32_t PECR; - __IO uint32_t PDKEYR; - __IO uint32_t PEKEYR; - __IO uint32_t PRGKEYR; - __IO uint32_t OPTKEYR; - __IO uint32_t SR; - __IO uint32_t OBR; - __IO uint32_t WRPR; -} FLASH_TypeDef; - -/** - * @brief Option Bytes Registers - */ - -typedef struct -{ - __IO uint32_t RDP; - __IO uint32_t USER; - __IO uint32_t WRP01; - __IO uint32_t WRP23; -} OB_TypeDef; - -/** - * @brief General Purpose IO - */ - -typedef struct -{ - __IO uint32_t MODER; - __IO uint16_t OTYPER; - uint16_t RESERVED0; - __IO uint32_t OSPEEDR; - __IO uint32_t PUPDR; - __IO uint16_t IDR; - uint16_t RESERVED1; - __IO uint16_t ODR; - uint16_t RESERVED2; - __IO uint16_t BSRRL; /* BSRR register is split to 2 * 16-bit fields BSRRL */ - __IO uint16_t BSRRH; /* BSRR register is split to 2 * 16-bit fields BSRRH */ - __IO uint32_t LCKR; - __IO uint32_t AFR[2]; -} GPIO_TypeDef; - -/** - * @brief SysTem Configuration - */ - -typedef struct -{ - __IO uint32_t MEMRMP; - __IO uint32_t PMC; - __IO uint32_t EXTICR[4]; -} SYSCFG_TypeDef; - -/** - * @brief Inter-integrated Circuit Interface - */ - -typedef struct -{ - __IO uint16_t CR1; - uint16_t RESERVED0; - __IO uint16_t CR2; - uint16_t RESERVED1; - __IO uint16_t OAR1; - uint16_t RESERVED2; - __IO uint16_t OAR2; - uint16_t RESERVED3; - __IO uint16_t DR; - uint16_t RESERVED4; - __IO uint16_t SR1; - uint16_t RESERVED5; - __IO uint16_t SR2; - uint16_t RESERVED6; - __IO uint16_t CCR; - uint16_t RESERVED7; - __IO uint16_t TRISE; - uint16_t RESERVED8; -} I2C_TypeDef; - -/** - * @brief Independent WATCHDOG - */ - -typedef struct -{ - __IO uint32_t KR; - __IO uint32_t PR; - __IO uint32_t RLR; - __IO uint32_t SR; -} IWDG_TypeDef; - - -/** - * @brief LCD - */ - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t FCR; - __IO uint32_t SR; - __IO uint32_t CLR; - uint32_t RESERVED; - __IO uint32_t RAM[16]; -} LCD_TypeDef; - -/** - * @brief Power Control - */ - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t CSR; -} PWR_TypeDef; - -/** - * @brief Reset and Clock Control - */ - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t ICSCR; - __IO uint32_t CFGR; - __IO uint32_t CIR; - __IO uint32_t AHBRSTR; - __IO uint32_t APB2RSTR; - __IO uint32_t APB1RSTR; - __IO uint32_t AHBENR; - __IO uint32_t APB2ENR; - __IO uint32_t APB1ENR; - __IO uint32_t AHBLPENR; - __IO uint32_t APB2LPENR; - __IO uint32_t APB1LPENR; - __IO uint32_t CSR; -} RCC_TypeDef; - -/** - * @brief Routing Interface - */ - -typedef struct -{ - __IO uint32_t ICR; - __IO uint32_t ASCR1; - __IO uint32_t ASCR2; - __IO uint32_t HYSCR1; - __IO uint32_t HYSCR2; - __IO uint32_t HYSCR3; -} RI_TypeDef; - -/** - * @brief Real-Time Clock - */ - -typedef struct -{ - __IO uint32_t TR; - __IO uint32_t DR; - __IO uint32_t CR; - __IO uint32_t ISR; - __IO uint32_t PRER; - __IO uint32_t WUTR; - __IO uint32_t CALIBR; - __IO uint32_t ALRMAR; - __IO uint32_t ALRMBR; - __IO uint32_t WPR; - uint32_t RESERVED1; - uint32_t RESERVED2; - __IO uint32_t TSTR; - __IO uint32_t TSDR; - uint32_t RESERVED3; - uint32_t RESERVED4; - __IO uint32_t TAFCR; - uint32_t RESERVED5; - uint32_t RESERVED6; - uint32_t RESERVED7; - __IO uint32_t BKP0R; - __IO uint32_t BKP1R; - __IO uint32_t BKP2R; - __IO uint32_t BKP3R; - __IO uint32_t BKP4R; - __IO uint32_t BKP5R; - __IO uint32_t BKP6R; - __IO uint32_t BKP7R; - __IO uint32_t BKP8R; - __IO uint32_t BKP9R; - __IO uint32_t BKP10R; - __IO uint32_t BKP11R; - __IO uint32_t BKP12R; - __IO uint32_t BKP13R; - __IO uint32_t BKP14R; - __IO uint32_t BKP15R; - __IO uint32_t BKP16R; - __IO uint32_t BKP17R; - __IO uint32_t BKP18R; - __IO uint32_t BKP19R; -} RTC_TypeDef; - -/** - * @brief Serial Peripheral Interface - */ - -typedef struct -{ - __IO uint16_t CR1; - uint16_t RESERVED0; - __IO uint16_t CR2; - uint16_t RESERVED1; - __IO uint16_t SR; - uint16_t RESERVED2; - __IO uint16_t DR; - uint16_t RESERVED3; - __IO uint16_t CRCPR; - uint16_t RESERVED4; - __IO uint16_t RXCRCR; - uint16_t RESERVED5; - __IO uint16_t TXCRCR; - uint16_t RESERVED6; -} SPI_TypeDef; - -/** - * @brief TIM - */ - -typedef struct -{ - __IO uint16_t CR1; - uint16_t RESERVED0; - __IO uint16_t CR2; - uint16_t RESERVED1; - __IO uint16_t SMCR; - uint16_t RESERVED2; - __IO uint16_t DIER; - uint16_t RESERVED3; - __IO uint16_t SR; - uint16_t RESERVED4; - __IO uint16_t EGR; - uint16_t RESERVED5; - __IO uint16_t CCMR1; - uint16_t RESERVED6; - __IO uint16_t CCMR2; - uint16_t RESERVED7; - __IO uint16_t CCER; - uint16_t RESERVED8; - __IO uint16_t CNT; - uint16_t RESERVED9; - __IO uint16_t PSC; - uint16_t RESERVED10; - __IO uint16_t ARR; - uint16_t RESERVED11; - uint32_t RESERVED12; - __IO uint16_t CCR1; - uint16_t RESERVED13; - __IO uint16_t CCR2; - uint16_t RESERVED14; - __IO uint16_t CCR3; - uint16_t RESERVED15; - __IO uint16_t CCR4; - uint16_t RESERVED16; - uint32_t RESERVED17; - __IO uint16_t DCR; - uint16_t RESERVED18; - __IO uint16_t DMAR; - uint16_t RESERVED19; - __IO uint16_t OR; - uint16_t RESERVED20; -} TIM_TypeDef; - -/** - * @brief Universal Synchronous Asynchronous Receiver Transmitter - */ - -typedef struct -{ - __IO uint16_t SR; - uint16_t RESERVED0; - __IO uint16_t DR; - uint16_t RESERVED1; - __IO uint16_t BRR; - uint16_t RESERVED2; - __IO uint16_t CR1; - uint16_t RESERVED3; - __IO uint16_t CR2; - uint16_t RESERVED4; - __IO uint16_t CR3; - uint16_t RESERVED5; - __IO uint16_t GTPR; - uint16_t RESERVED6; -} USART_TypeDef; - -/** - * @brief Window WATCHDOG - */ - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t CFR; - __IO uint32_t SR; -} WWDG_TypeDef; - -/** - * @} - */ - -/** @addtogroup Peripheral_memory_map - * @{ - */ - -#define FLASH_BASE ((uint32_t)0x08000000) /*!< FLASH base address in the alias region */ -#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM base address in the alias region */ -#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */ - -#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the bit-band region */ -#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */ - -/*!< Peripheral memory map */ -#define APB1PERIPH_BASE PERIPH_BASE -#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) -#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) - -#define TIM2_BASE (APB1PERIPH_BASE + 0x0000) -#define TIM3_BASE (APB1PERIPH_BASE + 0x0400) -#define TIM4_BASE (APB1PERIPH_BASE + 0x0800) -#define TIM6_BASE (APB1PERIPH_BASE + 0x1000) -#define TIM7_BASE (APB1PERIPH_BASE + 0x1400) -#define LCD_BASE (APB1PERIPH_BASE + 0x2400) -#define RTC_BASE (APB1PERIPH_BASE + 0x2800) -#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00) -#define IWDG_BASE (APB1PERIPH_BASE + 0x3000) -#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) -#define USART2_BASE (APB1PERIPH_BASE + 0x4400) -#define USART3_BASE (APB1PERIPH_BASE + 0x4800) -#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) -#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) -#define PWR_BASE (APB1PERIPH_BASE + 0x7000) -#define DAC_BASE (APB1PERIPH_BASE + 0x7400) -#define COMP_BASE (APB1PERIPH_BASE + 0x7C00) -#define RI_BASE (APB1PERIPH_BASE + 0x7C04) - -#define SYSCFG_BASE (APB2PERIPH_BASE + 0x0000) -#define EXTI_BASE (APB2PERIPH_BASE + 0x0400) -#define TIM9_BASE (APB2PERIPH_BASE + 0x0800) -#define TIM10_BASE (APB2PERIPH_BASE + 0x0C00) -#define TIM11_BASE (APB2PERIPH_BASE + 0x1000) -#define ADC1_BASE (APB2PERIPH_BASE + 0x2400) -#define ADC_BASE (APB2PERIPH_BASE + 0x2700) -#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) -#define USART1_BASE (APB2PERIPH_BASE + 0x3800) - -#define GPIOA_BASE (AHBPERIPH_BASE + 0x0000) -#define GPIOB_BASE (AHBPERIPH_BASE + 0x0400) -#define GPIOC_BASE (AHBPERIPH_BASE + 0x0800) -#define GPIOD_BASE (AHBPERIPH_BASE + 0x0C00) -#define GPIOE_BASE (AHBPERIPH_BASE + 0x1000) -#define GPIOH_BASE (AHBPERIPH_BASE + 0x1400) -#define CRC_BASE (AHBPERIPH_BASE + 0x3000) -#define RCC_BASE (AHBPERIPH_BASE + 0x3800) - - -#define FLASH_R_BASE (AHBPERIPH_BASE + 0x3C00) /*!< FLASH registers base address */ -#define OB_BASE ((uint32_t)0x1FF80000) /*!< FLASH Option Bytes base address */ - -#define DMA1_BASE (AHBPERIPH_BASE + 0x6000) -#define DMA1_Channel1_BASE (DMA1_BASE + 0x0008) -#define DMA1_Channel2_BASE (DMA1_BASE + 0x001C) -#define DMA1_Channel3_BASE (DMA1_BASE + 0x0030) -#define DMA1_Channel4_BASE (DMA1_BASE + 0x0044) -#define DMA1_Channel5_BASE (DMA1_BASE + 0x0058) -#define DMA1_Channel6_BASE (DMA1_BASE + 0x006C) -#define DMA1_Channel7_BASE (DMA1_BASE + 0x0080) - - -#define DBGMCU_BASE ((uint32_t)0xE0042000) /*!< Debug MCU registers base address */ - -/** - * @} - */ - -/** @addtogroup Peripheral_declaration - * @{ - */ - -#define TIM2 ((TIM_TypeDef *) TIM2_BASE) -#define TIM3 ((TIM_TypeDef *) TIM3_BASE) -#define TIM4 ((TIM_TypeDef *) TIM4_BASE) -#define TIM6 ((TIM_TypeDef *) TIM6_BASE) -#define TIM7 ((TIM_TypeDef *) TIM7_BASE) -#define LCD ((LCD_TypeDef *) LCD_BASE) -#define RTC ((RTC_TypeDef *) RTC_BASE) -#define WWDG ((WWDG_TypeDef *) WWDG_BASE) -#define IWDG ((IWDG_TypeDef *) IWDG_BASE) -#define SPI2 ((SPI_TypeDef *) SPI2_BASE) -#define USART2 ((USART_TypeDef *) USART2_BASE) -#define USART3 ((USART_TypeDef *) USART3_BASE) -#define I2C1 ((I2C_TypeDef *) I2C1_BASE) -#define I2C2 ((I2C_TypeDef *) I2C2_BASE) -#define PWR ((PWR_TypeDef *) PWR_BASE) -#define DAC ((DAC_TypeDef *) DAC_BASE) -#define COMP ((COMP_TypeDef *) COMP_BASE) -#define RI ((RI_TypeDef *) RI_BASE) -#define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE) -#define EXTI ((EXTI_TypeDef *) EXTI_BASE) - -#define ADC1 ((ADC_TypeDef *) ADC1_BASE) -#define ADC ((ADC_Common_TypeDef *) ADC_BASE) -#define TIM9 ((TIM_TypeDef *) TIM9_BASE) -#define TIM10 ((TIM_TypeDef *) TIM10_BASE) -#define TIM11 ((TIM_TypeDef *) TIM11_BASE) -#define SPI1 ((SPI_TypeDef *) SPI1_BASE) -#define USART1 ((USART_TypeDef *) USART1_BASE) -#define DMA1 ((DMA_TypeDef *) DMA1_BASE) -#define DMA1_Channel1 ((DMA_Channel_TypeDef *) DMA1_Channel1_BASE) -#define DMA1_Channel2 ((DMA_Channel_TypeDef *) DMA1_Channel2_BASE) -#define DMA1_Channel3 ((DMA_Channel_TypeDef *) DMA1_Channel3_BASE) -#define DMA1_Channel4 ((DMA_Channel_TypeDef *) DMA1_Channel4_BASE) -#define DMA1_Channel5 ((DMA_Channel_TypeDef *) DMA1_Channel5_BASE) -#define DMA1_Channel6 ((DMA_Channel_TypeDef *) DMA1_Channel6_BASE) -#define DMA1_Channel7 ((DMA_Channel_TypeDef *) DMA1_Channel7_BASE) -#define RCC ((RCC_TypeDef *) RCC_BASE) -#define CRC ((CRC_TypeDef *) CRC_BASE) - -#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) -#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) -#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) -#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) -#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) -#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE) - -#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) -#define OB ((OB_TypeDef *) OB_BASE) - -#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) - -/** - * @} - */ - -/** @addtogroup Exported_constants - * @{ - */ - - /** @addtogroup Peripheral_Registers_Bits_Definition - * @{ - */ - -/******************************************************************************/ -/* Peripheral Registers Bits Definition */ -/******************************************************************************/ -/******************************************************************************/ -/* */ -/* Analog to Digital Converter (ADC) */ -/* */ -/******************************************************************************/ - -/******************** Bit definition for ADC_SR register ********************/ -#define ADC_SR_AWD ((uint32_t)0x00000001) /*!< Analog watchdog flag */ -#define ADC_SR_EOC ((uint32_t)0x00000002) /*!< End of conversion */ -#define ADC_SR_JEOC ((uint32_t)0x00000004) /*!< Injected channel end of conversion */ -#define ADC_SR_JSTRT ((uint32_t)0x00000008) /*!< Injected channel Start flag */ -#define ADC_SR_STRT ((uint32_t)0x00000010) /*!< Regular channel Start flag */ -#define ADC_SR_OVR ((uint32_t)0x00000020) /*!< Overrun flag */ -#define ADC_SR_ADONS ((uint32_t)0x00000040) /*!< ADC ON status */ -#define ADC_SR_RCNR ((uint32_t)0x00000100) /*!< Regular channel not ready flag */ -#define ADC_SR_JCNR ((uint32_t)0x00000200) /*!< Injected channel not ready flag */ - -/******************* Bit definition for ADC_CR1 register ********************/ -#define ADC_CR1_AWDCH ((uint32_t)0x0000001F) /*!< AWDCH[4:0] bits (Analog watchdog channel select bits) */ -#define ADC_CR1_AWDCH_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define ADC_CR1_AWDCH_1 ((uint32_t)0x00000002) /*!< Bit 1 */ -#define ADC_CR1_AWDCH_2 ((uint32_t)0x00000004) /*!< Bit 2 */ -#define ADC_CR1_AWDCH_3 ((uint32_t)0x00000008) /*!< Bit 3 */ -#define ADC_CR1_AWDCH_4 ((uint32_t)0x00000010) /*!< Bit 4 */ - -#define ADC_CR1_EOCIE ((uint32_t)0x00000020) /*!< Interrupt enable for EOC */ -#define ADC_CR1_AWDIE ((uint32_t)0x00000040) /*!< Analog Watchdog interrupt enable */ -#define ADC_CR1_JEOCIE ((uint32_t)0x00000080) /*!< Interrupt enable for injected channels */ -#define ADC_CR1_SCAN ((uint32_t)0x00000100) /*!< Scan mode */ -#define ADC_CR1_AWDSGL ((uint32_t)0x00000200) /*!< Enable the watchdog on a single channel in scan mode */ -#define ADC_CR1_JAUTO ((uint32_t)0x00000400) /*!< Automatic injected group conversion */ -#define ADC_CR1_DISCEN ((uint32_t)0x00000800) /*!< Discontinuous mode on regular channels */ -#define ADC_CR1_JDISCEN ((uint32_t)0x00001000) /*!< Discontinuous mode on injected channels */ - -#define ADC_CR1_DISCNUM ((uint32_t)0x0000E000) /*!< DISCNUM[2:0] bits (Discontinuous mode channel count) */ -#define ADC_CR1_DISCNUM_0 ((uint32_t)0x00002000) /*!< Bit 0 */ -#define ADC_CR1_DISCNUM_1 ((uint32_t)0x00004000) /*!< Bit 1 */ -#define ADC_CR1_DISCNUM_2 ((uint32_t)0x00008000) /*!< Bit 2 */ - -#define ADC_CR1_PDD ((uint32_t)0x00010000) /*!< Power Down during Delay phase */ -#define ADC_CR1_PDI ((uint32_t)0x00020000) /*!< Power Down during Idle phase */ - -#define ADC_CR1_JAWDEN ((uint32_t)0x00400000) /*!< Analog watchdog enable on injected channels */ -#define ADC_CR1_AWDEN ((uint32_t)0x00800000) /*!< Analog watchdog enable on regular channels */ - -#define ADC_CR1_RES ((uint32_t)0x03000000) /*!< RES[1:0] bits (Resolution) */ -#define ADC_CR1_RES_0 ((uint32_t)0x01000000) /*!< Bit 0 */ -#define ADC_CR1_RES_1 ((uint32_t)0x02000000) /*!< Bit 1 */ - -#define ADC_CR1_OVRIE ((uint32_t)0x04000000) /*!< Overrun interrupt enable */ - -/******************* Bit definition for ADC_CR2 register ********************/ -#define ADC_CR2_ADON ((uint32_t)0x00000001) /*!< A/D Converter ON / OFF */ -#define ADC_CR2_CONT ((uint32_t)0x00000002) /*!< Continuous Conversion */ - -#define ADC_CR2_DELS ((uint32_t)0x00000070) /*!< DELS[2:0] bits (Delay selection) */ -#define ADC_CR2_DELS_0 ((uint32_t)0x00000010) /*!< Bit 0 */ -#define ADC_CR2_DELS_1 ((uint32_t)0x00000020) /*!< Bit 1 */ -#define ADC_CR2_DELS_2 ((uint32_t)0x00000040) /*!< Bit 2 */ - -#define ADC_CR2_DMA ((uint32_t)0x00000100) /*!< Direct Memory access mode */ -#define ADC_CR2_DDS ((uint32_t)0x00000200) /*!< DMA disable selection (Single ADC) */ -#define ADC_CR2_EOCS ((uint32_t)0x00000400) /*!< End of conversion selection */ -#define ADC_CR2_ALIGN ((uint32_t)0x00000800) /*!< Data Alignment */ - -#define ADC_CR2_JEXTSEL ((uint32_t)0x000F0000) /*!< JEXTSEL[3:0] bits (External event select for injected group) */ -#define ADC_CR2_JEXTSEL_0 ((uint32_t)0x00010000) /*!< Bit 0 */ -#define ADC_CR2_JEXTSEL_1 ((uint32_t)0x00020000) /*!< Bit 1 */ -#define ADC_CR2_JEXTSEL_2 ((uint32_t)0x00040000) /*!< Bit 2 */ -#define ADC_CR2_JEXTSEL_3 ((uint32_t)0x00080000) /*!< Bit 3 */ - -#define ADC_CR2_JEXTEN ((uint32_t)0x00300000) /*!< JEXTEN[1:0] bits (External Trigger Conversion mode for injected channels) */ -#define ADC_CR2_JEXTEN_0 ((uint32_t)0x00100000) /*!< Bit 0 */ -#define ADC_CR2_JEXTEN_1 ((uint32_t)0x00200000) /*!< Bit 1 */ - -#define ADC_CR2_JSWSTART ((uint32_t)0x00400000) /*!< Start Conversion of injected channels */ - -#define ADC_CR2_EXTSEL ((uint32_t)0x0F000000) /*!< EXTSEL[3:0] bits (External Event Select for regular group) */ -#define ADC_CR2_EXTSEL_0 ((uint32_t)0x01000000) /*!< Bit 0 */ -#define ADC_CR2_EXTSEL_1 ((uint32_t)0x02000000) /*!< Bit 1 */ -#define ADC_CR2_EXTSEL_2 ((uint32_t)0x04000000) /*!< Bit 2 */ -#define ADC_CR2_EXTSEL_3 ((uint32_t)0x08000000) /*!< Bit 3 */ - -#define ADC_CR2_EXTEN ((uint32_t)0x30000000) /*!< EXTEN[1:0] bits (External Trigger Conversion mode for regular channels) */ -#define ADC_CR2_EXTEN_0 ((uint32_t)0x10000000) /*!< Bit 0 */ -#define ADC_CR2_EXTEN_1 ((uint32_t)0x20000000) /*!< Bit 1 */ - -#define ADC_CR2_SWSTART ((uint32_t)0x40000000) /*!< Start Conversion of regular channels */ - -/****************** Bit definition for ADC_SMPR1 register *******************/ -#define ADC_SMPR1_SMP20 ((uint32_t)0x00000007) /*!< SMP20[2:0] bits (Channel 20 Sample time selection) */ -#define ADC_SMPR1_SMP20_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define ADC_SMPR1_SMP20_1 ((uint32_t)0x00000002) /*!< Bit 1 */ -#define ADC_SMPR1_SMP20_2 ((uint32_t)0x00000004) /*!< Bit 2 */ - -#define ADC_SMPR1_SMP21 ((uint32_t)0x00000038) /*!< SMP21[2:0] bits (Channel 21 Sample time selection) */ -#define ADC_SMPR1_SMP21_0 ((uint32_t)0x00000008) /*!< Bit 0 */ -#define ADC_SMPR1_SMP21_1 ((uint32_t)0x00000010) /*!< Bit 1 */ -#define ADC_SMPR1_SMP21_2 ((uint32_t)0x00000020) /*!< Bit 2 */ - -#define ADC_SMPR1_SMP22 ((uint32_t)0x000001C0) /*!< SMP22[2:0] bits (Channel 22 Sample time selection) */ -#define ADC_SMPR1_SMP22_0 ((uint32_t)0x00000040) /*!< Bit 0 */ -#define ADC_SMPR1_SMP22_1 ((uint32_t)0x00000080) /*!< Bit 1 */ -#define ADC_SMPR1_SMP22_2 ((uint32_t)0x00000100) /*!< Bit 2 */ - -#define ADC_SMPR1_SMP23 ((uint32_t)0x00000E00) /*!< SMP23[2:0] bits (Channel 23 Sample time selection) */ -#define ADC_SMPR1_SMP23_0 ((uint32_t)0x00000200) /*!< Bit 0 */ -#define ADC_SMPR1_SMP23_1 ((uint32_t)0x00000400) /*!< Bit 1 */ -#define ADC_SMPR1_SMP23_2 ((uint32_t)0x00000800) /*!< Bit 2 */ - -#define ADC_SMPR1_SMP24 ((uint32_t)0x00007000) /*!< SMP24[2:0] bits (Channel 24 Sample time selection) */ -#define ADC_SMPR1_SMP24_0 ((uint32_t)0x00001000) /*!< Bit 0 */ -#define ADC_SMPR1_SMP24_1 ((uint32_t)0x00002000) /*!< Bit 1 */ -#define ADC_SMPR1_SMP24_2 ((uint32_t)0x00004000) /*!< Bit 2 */ - -#define ADC_SMPR1_SMP25 ((uint32_t)0x00038000) /*!< SMP25[2:0] bits (Channel 25 Sample time selection) */ -#define ADC_SMPR1_SMP25_0 ((uint32_t)0x00008000) /*!< Bit 0 */ -#define ADC_SMPR1_SMP25_1 ((uint32_t)0x00010000) /*!< Bit 1 */ -#define ADC_SMPR1_SMP25_2 ((uint32_t)0x00020000) /*!< Bit 2 */ - -/****************** Bit definition for ADC_SMPR2 register *******************/ -#define ADC_SMPR2_SMP10 ((uint32_t)0x00000007) /*!< SMP10[2:0] bits (Channel 10 Sample time selection) */ -#define ADC_SMPR2_SMP10_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define ADC_SMPR2_SMP10_1 ((uint32_t)0x00000002) /*!< Bit 1 */ -#define ADC_SMPR2_SMP10_2 ((uint32_t)0x00000004) /*!< Bit 2 */ - -#define ADC_SMPR2_SMP11 ((uint32_t)0x00000038) /*!< SMP11[2:0] bits (Channel 11 Sample time selection) */ -#define ADC_SMPR2_SMP11_0 ((uint32_t)0x00000008) /*!< Bit 0 */ -#define ADC_SMPR2_SMP11_1 ((uint32_t)0x00000010) /*!< Bit 1 */ -#define ADC_SMPR2_SMP11_2 ((uint32_t)0x00000020) /*!< Bit 2 */ - -#define ADC_SMPR2_SMP12 ((uint32_t)0x000001C0) /*!< SMP12[2:0] bits (Channel 12 Sample time selection) */ -#define ADC_SMPR2_SMP12_0 ((uint32_t)0x00000040) /*!< Bit 0 */ -#define ADC_SMPR2_SMP12_1 ((uint32_t)0x00000080) /*!< Bit 1 */ -#define ADC_SMPR2_SMP12_2 ((uint32_t)0x00000100) /*!< Bit 2 */ - -#define ADC_SMPR2_SMP13 ((uint32_t)0x00000E00) /*!< SMP13[2:0] bits (Channel 13 Sample time selection) */ -#define ADC_SMPR2_SMP13_0 ((uint32_t)0x00000200) /*!< Bit 0 */ -#define ADC_SMPR2_SMP13_1 ((uint32_t)0x00000400) /*!< Bit 1 */ -#define ADC_SMPR2_SMP13_2 ((uint32_t)0x00000800) /*!< Bit 2 */ - -#define ADC_SMPR2_SMP14 ((uint32_t)0x00007000) /*!< SMP14[2:0] bits (Channel 14 Sample time selection) */ -#define ADC_SMPR2_SMP14_0 ((uint32_t)0x00001000) /*!< Bit 0 */ -#define ADC_SMPR2_SMP14_1 ((uint32_t)0x00002000) /*!< Bit 1 */ -#define ADC_SMPR2_SMP14_2 ((uint32_t)0x00004000) /*!< Bit 2 */ - -#define ADC_SMPR2_SMP15 ((uint32_t)0x00038000) /*!< SMP15[2:0] bits (Channel 5 Sample time selection) */ -#define ADC_SMPR2_SMP15_0 ((uint32_t)0x00008000) /*!< Bit 0 */ -#define ADC_SMPR2_SMP15_1 ((uint32_t)0x00010000) /*!< Bit 1 */ -#define ADC_SMPR2_SMP15_2 ((uint32_t)0x00020000) /*!< Bit 2 */ - -#define ADC_SMPR2_SMP16 ((uint32_t)0x001C0000) /*!< SMP16[2:0] bits (Channel 16 Sample time selection) */ -#define ADC_SMPR2_SMP16_0 ((uint32_t)0x00040000) /*!< Bit 0 */ -#define ADC_SMPR2_SMP16_1 ((uint32_t)0x00080000) /*!< Bit 1 */ -#define ADC_SMPR2_SMP16_2 ((uint32_t)0x00100000) /*!< Bit 2 */ - -#define ADC_SMPR2_SMP17 ((uint32_t)0x00E00000) /*!< SMP17[2:0] bits (Channel 17 Sample time selection) */ -#define ADC_SMPR2_SMP17_0 ((uint32_t)0x00200000) /*!< Bit 0 */ -#define ADC_SMPR2_SMP17_1 ((uint32_t)0x00400000) /*!< Bit 1 */ -#define ADC_SMPR2_SMP17_2 ((uint32_t)0x00800000) /*!< Bit 2 */ - -#define ADC_SMPR2_SMP18 ((uint32_t)0x07000000) /*!< SMP18[2:0] bits (Channel 18 Sample time selection) */ -#define ADC_SMPR2_SMP18_0 ((uint32_t)0x01000000) /*!< Bit 0 */ -#define ADC_SMPR2_SMP18_1 ((uint32_t)0x02000000) /*!< Bit 1 */ -#define ADC_SMPR2_SMP18_2 ((uint32_t)0x04000000) /*!< Bit 2 */ - -#define ADC_SMPR2_SMP19 ((uint32_t)0x38000000) /*!< SMP19[2:0] bits (Channel 19 Sample time selection) */ -#define ADC_SMPR2_SMP19_0 ((uint32_t)0x08000000) /*!< Bit 0 */ -#define ADC_SMPR2_SMP19_1 ((uint32_t)0x10000000) /*!< Bit 1 */ -#define ADC_SMPR2_SMP19_2 ((uint32_t)0x20000000) /*!< Bit 2 */ - -/****************** Bit definition for ADC_SMPR3 register *******************/ -#define ADC_SMPR3_SMP0 ((uint32_t)0x00000007) /*!< SMP0[2:0] bits (Channel 0 Sample time selection) */ -#define ADC_SMPR3_SMP0_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define ADC_SMPR3_SMP0_1 ((uint32_t)0x00000002) /*!< Bit 1 */ -#define ADC_SMPR3_SMP0_2 ((uint32_t)0x00000004) /*!< Bit 2 */ - -#define ADC_SMPR3_SMP1 ((uint32_t)0x00000038) /*!< SMP1[2:0] bits (Channel 1 Sample time selection) */ -#define ADC_SMPR3_SMP1_0 ((uint32_t)0x00000008) /*!< Bit 0 */ -#define ADC_SMPR3_SMP1_1 ((uint32_t)0x00000010) /*!< Bit 1 */ -#define ADC_SMPR3_SMP1_2 ((uint32_t)0x00000020) /*!< Bit 2 */ - -#define ADC_SMPR3_SMP2 ((uint32_t)0x000001C0) /*!< SMP2[2:0] bits (Channel 2 Sample time selection) */ -#define ADC_SMPR3_SMP2_0 ((uint32_t)0x00000040) /*!< Bit 0 */ -#define ADC_SMPR3_SMP2_1 ((uint32_t)0x00000080) /*!< Bit 1 */ -#define ADC_SMPR3_SMP2_2 ((uint32_t)0x00000100) /*!< Bit 2 */ - -#define ADC_SMPR3_SMP3 ((uint32_t)0x00000E00) /*!< SMP3[2:0] bits (Channel 3 Sample time selection) */ -#define ADC_SMPR3_SMP3_0 ((uint32_t)0x00000200) /*!< Bit 0 */ -#define ADC_SMPR3_SMP3_1 ((uint32_t)0x00000400) /*!< Bit 1 */ -#define ADC_SMPR3_SMP3_2 ((uint32_t)0x00000800) /*!< Bit 2 */ - -#define ADC_SMPR3_SMP4 ((uint32_t)0x00007000) /*!< SMP4[2:0] bits (Channel 4 Sample time selection) */ -#define ADC_SMPR3_SMP4_0 ((uint32_t)0x00001000) /*!< Bit 0 */ -#define ADC_SMPR3_SMP4_1 ((uint32_t)0x00002000) /*!< Bit 1 */ -#define ADC_SMPR3_SMP4_2 ((uint32_t)0x00004000) /*!< Bit 2 */ - -#define ADC_SMPR3_SMP5 ((uint32_t)0x00038000) /*!< SMP5[2:0] bits (Channel 5 Sample time selection) */ -#define ADC_SMPR3_SMP5_0 ((uint32_t)0x00008000) /*!< Bit 0 */ -#define ADC_SMPR3_SMP5_1 ((uint32_t)0x00010000) /*!< Bit 1 */ -#define ADC_SMPR3_SMP5_2 ((uint32_t)0x00020000) /*!< Bit 2 */ - -#define ADC_SMPR3_SMP6 ((uint32_t)0x001C0000) /*!< SMP6[2:0] bits (Channel 6 Sample time selection) */ -#define ADC_SMPR3_SMP6_0 ((uint32_t)0x00040000) /*!< Bit 0 */ -#define ADC_SMPR3_SMP6_1 ((uint32_t)0x00080000) /*!< Bit 1 */ -#define ADC_SMPR3_SMP6_2 ((uint32_t)0x00100000) /*!< Bit 2 */ - -#define ADC_SMPR3_SMP7 ((uint32_t)0x00E00000) /*!< SMP7[2:0] bits (Channel 7 Sample time selection) */ -#define ADC_SMPR3_SMP7_0 ((uint32_t)0x00200000) /*!< Bit 0 */ -#define ADC_SMPR3_SMP7_1 ((uint32_t)0x00400000) /*!< Bit 1 */ -#define ADC_SMPR3_SMP7_2 ((uint32_t)0x00800000) /*!< Bit 2 */ - -#define ADC_SMPR3_SMP8 ((uint32_t)0x07000000) /*!< SMP8[2:0] bits (Channel 8 Sample time selection) */ -#define ADC_SMPR3_SMP8_0 ((uint32_t)0x01000000) /*!< Bit 0 */ -#define ADC_SMPR3_SMP8_1 ((uint32_t)0x02000000) /*!< Bit 1 */ -#define ADC_SMPR3_SMP8_2 ((uint32_t)0x04000000) /*!< Bit 2 */ - -#define ADC_SMPR3_SMP9 ((uint32_t)0x38000000) /*!< SMP9[2:0] bits (Channel 9 Sample time selection) */ -#define ADC_SMPR3_SMP9_0 ((uint32_t)0x08000000) /*!< Bit 0 */ -#define ADC_SMPR3_SMP9_1 ((uint32_t)0x10000000) /*!< Bit 1 */ -#define ADC_SMPR3_SMP9_2 ((uint32_t)0x20000000) /*!< Bit 2 */ - - -/****************** Bit definition for ADC_JOFR1 register *******************/ -#define ADC_JOFR1_JOFFSET1 ((uint32_t)0x00000FFF) /*!< Data offset for injected channel 1 */ - -/****************** Bit definition for ADC_JOFR2 register *******************/ -#define ADC_JOFR2_JOFFSET2 ((uint32_t)0x00000FFF) /*!< Data offset for injected channel 2 */ - -/****************** Bit definition for ADC_JOFR3 register *******************/ -#define ADC_JOFR3_JOFFSET3 ((uint32_t)0x00000FFF) /*!< Data offset for injected channel 3 */ - -/****************** Bit definition for ADC_JOFR4 register *******************/ -#define ADC_JOFR4_JOFFSET4 ((uint32_t)0x00000FFF) /*!< Data offset for injected channel 4 */ - -/******************* Bit definition for ADC_HTR register ********************/ -#define ADC_HTR_HT ((uint32_t)0x00000FFF) /*!< Analog watchdog high threshold */ - -/******************* Bit definition for ADC_LTR register ********************/ -#define ADC_LTR_LT ((uint32_t)0x00000FFF) /*!< Analog watchdog low threshold */ - -/******************* Bit definition for ADC_SQR1 register *******************/ -#define ADC_SQR1_SQ25 ((uint32_t)0x0000001F) /*!< SQ25[4:0] bits (25th conversion in regular sequence) */ -#define ADC_SQR1_SQ25_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define ADC_SQR1_SQ25_1 ((uint32_t)0x00000002) /*!< Bit 1 */ -#define ADC_SQR1_SQ25_2 ((uint32_t)0x00000004) /*!< Bit 2 */ -#define ADC_SQR1_SQ25_3 ((uint32_t)0x00000008) /*!< Bit 3 */ -#define ADC_SQR1_SQ25_4 ((uint32_t)0x00000010) /*!< Bit 4 */ - -#define ADC_SQR1_SQ26 ((uint32_t)0x000003E0) /*!< SQ26[4:0] bits (26th conversion in regular sequence) */ -#define ADC_SQR1_SQ26_0 ((uint32_t)0x00000020) /*!< Bit 0 */ -#define ADC_SQR1_SQ26_1 ((uint32_t)0x00000040) /*!< Bit 1 */ -#define ADC_SQR1_SQ26_2 ((uint32_t)0x00000080) /*!< Bit 2 */ -#define ADC_SQR1_SQ26_3 ((uint32_t)0x00000100) /*!< Bit 3 */ -#define ADC_SQR1_SQ26_4 ((uint32_t)0x00000200) /*!< Bit 4 */ - -#define ADC_SQR1_SQ27 ((uint32_t)0x00007C00) /*!< SQ27[4:0] bits (27th conversion in regular sequence) */ -#define ADC_SQR1_SQ27_0 ((uint32_t)0x00000400) /*!< Bit 0 */ -#define ADC_SQR1_SQ27_1 ((uint32_t)0x00000800) /*!< Bit 1 */ -#define ADC_SQR1_SQ27_2 ((uint32_t)0x00001000) /*!< Bit 2 */ -#define ADC_SQR1_SQ27_3 ((uint32_t)0x00002000) /*!< Bit 3 */ -#define ADC_SQR1_SQ27_4 ((uint32_t)0x00004000) /*!< Bit 4 */ - -#define ADC_SQR1_L ((uint32_t)0x00F00000) /*!< L[3:0] bits (Regular channel sequence length) */ -#define ADC_SQR1_L_0 ((uint32_t)0x00100000) /*!< Bit 0 */ -#define ADC_SQR1_L_1 ((uint32_t)0x00200000) /*!< Bit 1 */ -#define ADC_SQR1_L_2 ((uint32_t)0x00400000) /*!< Bit 2 */ -#define ADC_SQR1_L_3 ((uint32_t)0x00800000) /*!< Bit 3 */ - -/******************* Bit definition for ADC_SQR2 register *******************/ -#define ADC_SQR2_SQ19 ((uint32_t)0x0000001F) /*!< SQ19[4:0] bits (19th conversion in regular sequence) */ -#define ADC_SQR2_SQ19_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define ADC_SQR2_SQ19_1 ((uint32_t)0x00000002) /*!< Bit 1 */ -#define ADC_SQR2_SQ19_2 ((uint32_t)0x00000004) /*!< Bit 2 */ -#define ADC_SQR2_SQ19_3 ((uint32_t)0x00000008) /*!< Bit 3 */ -#define ADC_SQR2_SQ19_4 ((uint32_t)0x00000010) /*!< Bit 4 */ - -#define ADC_SQR2_SQ20 ((uint32_t)0x000003E0) /*!< SQ20[4:0] bits (20th conversion in regular sequence) */ -#define ADC_SQR2_SQ20_0 ((uint32_t)0x00000020) /*!< Bit 0 */ -#define ADC_SQR2_SQ20_1 ((uint32_t)0x00000040) /*!< Bit 1 */ -#define ADC_SQR2_SQ20_2 ((uint32_t)0x00000080) /*!< Bit 2 */ -#define ADC_SQR2_SQ20_3 ((uint32_t)0x00000100) /*!< Bit 3 */ -#define ADC_SQR2_SQ20_4 ((uint32_t)0x00000200) /*!< Bit 4 */ - -#define ADC_SQR2_SQ21 ((uint32_t)0x00007C00) /*!< SQ21[4:0] bits (21th conversion in regular sequence) */ -#define ADC_SQR2_SQ21_0 ((uint32_t)0x00000400) /*!< Bit 0 */ -#define ADC_SQR2_SQ21_1 ((uint32_t)0x00000800) /*!< Bit 1 */ -#define ADC_SQR2_SQ21_2 ((uint32_t)0x00001000) /*!< Bit 2 */ -#define ADC_SQR2_SQ21_3 ((uint32_t)0x00002000) /*!< Bit 3 */ -#define ADC_SQR2_SQ21_4 ((uint32_t)0x00004000) /*!< Bit 4 */ - -#define ADC_SQR2_SQ22 ((uint32_t)0x000F8000) /*!< SQ22[4:0] bits (22th conversion in regular sequence) */ -#define ADC_SQR2_SQ22_0 ((uint32_t)0x00008000) /*!< Bit 0 */ -#define ADC_SQR2_SQ22_1 ((uint32_t)0x00010000) /*!< Bit 1 */ -#define ADC_SQR2_SQ22_2 ((uint32_t)0x00020000) /*!< Bit 2 */ -#define ADC_SQR2_SQ22_3 ((uint32_t)0x00040000) /*!< Bit 3 */ -#define ADC_SQR2_SQ22_4 ((uint32_t)0x00080000) /*!< Bit 4 */ - -#define ADC_SQR2_SQ23 ((uint32_t)0x01F00000) /*!< SQ23[4:0] bits (23th conversion in regular sequence) */ -#define ADC_SQR2_SQ23_0 ((uint32_t)0x00100000) /*!< Bit 0 */ -#define ADC_SQR2_SQ23_1 ((uint32_t)0x00200000) /*!< Bit 1 */ -#define ADC_SQR2_SQ23_2 ((uint32_t)0x00400000) /*!< Bit 2 */ -#define ADC_SQR2_SQ23_3 ((uint32_t)0x00800000) /*!< Bit 3 */ -#define ADC_SQR2_SQ23_4 ((uint32_t)0x01000000) /*!< Bit 4 */ - -#define ADC_SQR2_SQ24 ((uint32_t)0x3E000000) /*!< SQ24[4:0] bits (24th conversion in regular sequence) */ -#define ADC_SQR2_SQ24_0 ((uint32_t)0x02000000) /*!< Bit 0 */ -#define ADC_SQR2_SQ24_1 ((uint32_t)0x04000000) /*!< Bit 1 */ -#define ADC_SQR2_SQ24_2 ((uint32_t)0x08000000) /*!< Bit 2 */ -#define ADC_SQR2_SQ24_3 ((uint32_t)0x10000000) /*!< Bit 3 */ -#define ADC_SQR2_SQ24_4 ((uint32_t)0x20000000) /*!< Bit 4 */ - -/******************* Bit definition for ADC_SQR3 register *******************/ -#define ADC_SQR3_SQ13 ((uint32_t)0x0000001F) /*!< SQ13[4:0] bits (13th conversion in regular sequence) */ -#define ADC_SQR3_SQ13_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define ADC_SQR3_SQ13_1 ((uint32_t)0x00000002) /*!< Bit 1 */ -#define ADC_SQR3_SQ13_2 ((uint32_t)0x00000004) /*!< Bit 2 */ -#define ADC_SQR3_SQ13_3 ((uint32_t)0x00000008) /*!< Bit 3 */ -#define ADC_SQR3_SQ13_4 ((uint32_t)0x00000010) /*!< Bit 4 */ - -#define ADC_SQR3_SQ14 ((uint32_t)0x000003E0) /*!< SQ14[4:0] bits (14th conversion in regular sequence) */ -#define ADC_SQR3_SQ14_0 ((uint32_t)0x00000020) /*!< Bit 0 */ -#define ADC_SQR3_SQ14_1 ((uint32_t)0x00000040) /*!< Bit 1 */ -#define ADC_SQR3_SQ14_2 ((uint32_t)0x00000080) /*!< Bit 2 */ -#define ADC_SQR3_SQ14_3 ((uint32_t)0x00000100) /*!< Bit 3 */ -#define ADC_SQR3_SQ14_4 ((uint32_t)0x00000200) /*!< Bit 4 */ - -#define ADC_SQR3_SQ15 ((uint32_t)0x00007C00) /*!< SQ15[4:0] bits (15th conversion in regular sequence) */ -#define ADC_SQR3_SQ15_0 ((uint32_t)0x00000400) /*!< Bit 0 */ -#define ADC_SQR3_SQ15_1 ((uint32_t)0x00000800) /*!< Bit 1 */ -#define ADC_SQR3_SQ15_2 ((uint32_t)0x00001000) /*!< Bit 2 */ -#define ADC_SQR3_SQ15_3 ((uint32_t)0x00002000) /*!< Bit 3 */ -#define ADC_SQR3_SQ15_4 ((uint32_t)0x00004000) /*!< Bit 4 */ - -#define ADC_SQR3_SQ16 ((uint32_t)0x000F8000) /*!< SQ16[4:0] bits (16th conversion in regular sequence) */ -#define ADC_SQR3_SQ16_0 ((uint32_t)0x00008000) /*!< Bit 0 */ -#define ADC_SQR3_SQ16_1 ((uint32_t)0x00010000) /*!< Bit 1 */ -#define ADC_SQR3_SQ16_2 ((uint32_t)0x00020000) /*!< Bit 2 */ -#define ADC_SQR3_SQ16_3 ((uint32_t)0x00040000) /*!< Bit 3 */ -#define ADC_SQR3_SQ16_4 ((uint32_t)0x00080000) /*!< Bit 4 */ - -#define ADC_SQR3_SQ17 ((uint32_t)0x01F00000) /*!< SQ17[4:0] bits (17th conversion in regular sequence) */ -#define ADC_SQR3_SQ17_0 ((uint32_t)0x00100000) /*!< Bit 0 */ -#define ADC_SQR3_SQ17_1 ((uint32_t)0x00200000) /*!< Bit 1 */ -#define ADC_SQR3_SQ17_2 ((uint32_t)0x00400000) /*!< Bit 2 */ -#define ADC_SQR3_SQ17_3 ((uint32_t)0x00800000) /*!< Bit 3 */ -#define ADC_SQR3_SQ17_4 ((uint32_t)0x01000000) /*!< Bit 4 */ - -#define ADC_SQR3_SQ18 ((uint32_t)0x3E000000) /*!< SQ18[4:0] bits (18th conversion in regular sequence) */ -#define ADC_SQR3_SQ18_0 ((uint32_t)0x02000000) /*!< Bit 0 */ -#define ADC_SQR3_SQ18_1 ((uint32_t)0x04000000) /*!< Bit 1 */ -#define ADC_SQR3_SQ18_2 ((uint32_t)0x08000000) /*!< Bit 2 */ -#define ADC_SQR3_SQ18_3 ((uint32_t)0x10000000) /*!< Bit 3 */ -#define ADC_SQR3_SQ18_4 ((uint32_t)0x20000000) /*!< Bit 4 */ - -/******************* Bit definition for ADC_SQR4 register *******************/ -#define ADC_SQR4_SQ7 ((uint32_t)0x0000001F) /*!< SQ7[4:0] bits (7th conversion in regular sequence) */ -#define ADC_SQR4_SQ7_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define ADC_SQR4_SQ7_1 ((uint32_t)0x00000002) /*!< Bit 1 */ -#define ADC_SQR4_SQ7_2 ((uint32_t)0x00000004) /*!< Bit 2 */ -#define ADC_SQR4_SQ7_3 ((uint32_t)0x00000008) /*!< Bit 3 */ -#define ADC_SQR4_SQ7_4 ((uint32_t)0x00000010) /*!< Bit 4 */ - -#define ADC_SQR4_SQ8 ((uint32_t)0x000003E0) /*!< SQ8[4:0] bits (8th conversion in regular sequence) */ -#define ADC_SQR4_SQ8_0 ((uint32_t)0x00000020) /*!< Bit 0 */ -#define ADC_SQR4_SQ8_1 ((uint32_t)0x00000040) /*!< Bit 1 */ -#define ADC_SQR4_SQ8_2 ((uint32_t)0x00000080) /*!< Bit 2 */ -#define ADC_SQR4_SQ8_3 ((uint32_t)0x00000100) /*!< Bit 3 */ -#define ADC_SQR4_SQ8_4 ((uint32_t)0x00000200) /*!< Bit 4 */ - -#define ADC_SQR4_SQ9 ((uint32_t)0x00007C00) /*!< SQ9[4:0] bits (9th conversion in regular sequence) */ -#define ADC_SQR4_SQ9_0 ((uint32_t)0x00000400) /*!< Bit 0 */ -#define ADC_SQR4_SQ9_1 ((uint32_t)0x00000800) /*!< Bit 1 */ -#define ADC_SQR4_SQ9_2 ((uint32_t)0x00001000) /*!< Bit 2 */ -#define ADC_SQR4_SQ9_3 ((uint32_t)0x00002000) /*!< Bit 3 */ -#define ADC_SQR4_SQ9_4 ((uint32_t)0x00004000) /*!< Bit 4 */ - -#define ADC_SQR4_SQ10 ((uint32_t)0x000F8000) /*!< SQ10[4:0] bits (10th conversion in regular sequence) */ -#define ADC_SQR4_SQ10_0 ((uint32_t)0x00008000) /*!< Bit 0 */ -#define ADC_SQR4_SQ10_1 ((uint32_t)0x00010000) /*!< Bit 1 */ -#define ADC_SQR4_SQ10_2 ((uint32_t)0x00020000) /*!< Bit 2 */ -#define ADC_SQR4_SQ10_3 ((uint32_t)0x00040000) /*!< Bit 3 */ -#define ADC_SQR4_SQ10_4 ((uint32_t)0x00080000) /*!< Bit 4 */ - -#define ADC_SQR4_SQ11 ((uint32_t)0x01F00000) /*!< SQ11[4:0] bits (11th conversion in regular sequence) */ -#define ADC_SQR4_SQ11_0 ((uint32_t)0x00100000) /*!< Bit 0 */ -#define ADC_SQR4_SQ11_1 ((uint32_t)0x00200000) /*!< Bit 1 */ -#define ADC_SQR4_SQ11_2 ((uint32_t)0x00400000) /*!< Bit 2 */ -#define ADC_SQR4_SQ11_3 ((uint32_t)0x00800000) /*!< Bit 3 */ -#define ADC_SQR4_SQ11_4 ((uint32_t)0x01000000) /*!< Bit 4 */ - -#define ADC_SQR4_SQ12 ((uint32_t)0x3E000000) /*!< SQ12[4:0] bits (12th conversion in regular sequence) */ -#define ADC_SQR4_SQ12_0 ((uint32_t)0x02000000) /*!< Bit 0 */ -#define ADC_SQR4_SQ12_1 ((uint32_t)0x04000000) /*!< Bit 1 */ -#define ADC_SQR4_SQ12_2 ((uint32_t)0x08000000) /*!< Bit 2 */ -#define ADC_SQR4_SQ12_3 ((uint32_t)0x10000000) /*!< Bit 3 */ -#define ADC_SQR4_SQ12_4 ((uint32_t)0x20000000) /*!< Bit 4 */ - -/******************* Bit definition for ADC_SQR5 register *******************/ -#define ADC_SQR5_SQ1 ((uint32_t)0x0000001F) /*!< SQ1[4:0] bits (1st conversion in regular sequence) */ -#define ADC_SQR5_SQ1_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define ADC_SQR5_SQ1_1 ((uint32_t)0x00000002) /*!< Bit 1 */ -#define ADC_SQR5_SQ1_2 ((uint32_t)0x00000004) /*!< Bit 2 */ -#define ADC_SQR5_SQ1_3 ((uint32_t)0x00000008) /*!< Bit 3 */ -#define ADC_SQR5_SQ1_4 ((uint32_t)0x00000010) /*!< Bit 4 */ - -#define ADC_SQR5_SQ2 ((uint32_t)0x000003E0) /*!< SQ2[4:0] bits (2nd conversion in regular sequence) */ -#define ADC_SQR5_SQ2_0 ((uint32_t)0x00000020) /*!< Bit 0 */ -#define ADC_SQR5_SQ2_1 ((uint32_t)0x00000040) /*!< Bit 1 */ -#define ADC_SQR5_SQ2_2 ((uint32_t)0x00000080) /*!< Bit 2 */ -#define ADC_SQR5_SQ2_3 ((uint32_t)0x00000100) /*!< Bit 3 */ -#define ADC_SQR5_SQ2_4 ((uint32_t)0x00000200) /*!< Bit 4 */ - -#define ADC_SQR5_SQ3 ((uint32_t)0x00007C00) /*!< SQ3[4:0] bits (3rd conversion in regular sequence) */ -#define ADC_SQR5_SQ3_0 ((uint32_t)0x00000400) /*!< Bit 0 */ -#define ADC_SQR5_SQ3_1 ((uint32_t)0x00000800) /*!< Bit 1 */ -#define ADC_SQR5_SQ3_2 ((uint32_t)0x00001000) /*!< Bit 2 */ -#define ADC_SQR5_SQ3_3 ((uint32_t)0x00002000) /*!< Bit 3 */ -#define ADC_SQR5_SQ3_4 ((uint32_t)0x00004000) /*!< Bit 4 */ - -#define ADC_SQR5_SQ4 ((uint32_t)0x000F8000) /*!< SQ4[4:0] bits (4th conversion in regular sequence) */ -#define ADC_SQR5_SQ4_0 ((uint32_t)0x00008000) /*!< Bit 0 */ -#define ADC_SQR5_SQ4_1 ((uint32_t)0x00010000) /*!< Bit 1 */ -#define ADC_SQR5_SQ4_2 ((uint32_t)0x00020000) /*!< Bit 2 */ -#define ADC_SQR5_SQ4_3 ((uint32_t)0x00040000) /*!< Bit 3 */ -#define ADC_SQR5_SQ4_4 ((uint32_t)0x00080000) /*!< Bit 4 */ - -#define ADC_SQR5_SQ5 ((uint32_t)0x01F00000) /*!< SQ5[4:0] bits (5th conversion in regular sequence) */ -#define ADC_SQR5_SQ5_0 ((uint32_t)0x00100000) /*!< Bit 0 */ -#define ADC_SQR5_SQ5_1 ((uint32_t)0x00200000) /*!< Bit 1 */ -#define ADC_SQR5_SQ5_2 ((uint32_t)0x00400000) /*!< Bit 2 */ -#define ADC_SQR5_SQ5_3 ((uint32_t)0x00800000) /*!< Bit 3 */ -#define ADC_SQR5_SQ5_4 ((uint32_t)0x01000000) /*!< Bit 4 */ - -#define ADC_SQR5_SQ6 ((uint32_t)0x3E000000) /*!< SQ6[4:0] bits (6th conversion in regular sequence) */ -#define ADC_SQR5_SQ6_0 ((uint32_t)0x02000000) /*!< Bit 0 */ -#define ADC_SQR5_SQ6_1 ((uint32_t)0x04000000) /*!< Bit 1 */ -#define ADC_SQR5_SQ6_2 ((uint32_t)0x08000000) /*!< Bit 2 */ -#define ADC_SQR5_SQ6_3 ((uint32_t)0x10000000) /*!< Bit 3 */ -#define ADC_SQR5_SQ6_4 ((uint32_t)0x20000000) /*!< Bit 4 */ - - -/******************* Bit definition for ADC_JSQR register *******************/ -#define ADC_JSQR_JSQ1 ((uint32_t)0x0000001F) /*!< JSQ1[4:0] bits (1st conversion in injected sequence) */ -#define ADC_JSQR_JSQ1_0 ((uint32_t)0x00000001) /*!< Bit 0 */ -#define ADC_JSQR_JSQ1_1 ((uint32_t)0x00000002) /*!< Bit 1 */ -#define ADC_JSQR_JSQ1_2 ((uint32_t)0x00000004) /*!< Bit 2 */ -#define ADC_JSQR_JSQ1_3 ((uint32_t)0x00000008) /*!< Bit 3 */ -#define ADC_JSQR_JSQ1_4 ((uint32_t)0x00000010) /*!< Bit 4 */ - -#define ADC_JSQR_JSQ2 ((uint32_t)0x000003E0) /*!< JSQ2[4:0] bits (2nd conversion in injected sequence) */ -#define ADC_JSQR_JSQ2_0 ((uint32_t)0x00000020) /*!< Bit 0 */ -#define ADC_JSQR_JSQ2_1 ((uint32_t)0x00000040) /*!< Bit 1 */ -#define ADC_JSQR_JSQ2_2 ((uint32_t)0x00000080) /*!< Bit 2 */ -#define ADC_JSQR_JSQ2_3 ((uint32_t)0x00000100) /*!< Bit 3 */ -#define ADC_JSQR_JSQ2_4 ((uint32_t)0x00000200) /*!< Bit 4 */ - -#define ADC_JSQR_JSQ3 ((uint32_t)0x00007C00) /*!< JSQ3[4:0] bits (3rd conversion in injected sequence) */ -#define ADC_JSQR_JSQ3_0 ((uint32_t)0x00000400) /*!< Bit 0 */ -#define ADC_JSQR_JSQ3_1 ((uint32_t)0x00000800) /*!< Bit 1 */ -#define ADC_JSQR_JSQ3_2 ((uint32_t)0x00001000) /*!< Bit 2 */ -#define ADC_JSQR_JSQ3_3 ((uint32_t)0x00002000) /*!< Bit 3 */ -#define ADC_JSQR_JSQ3_4 ((uint32_t)0x00004000) /*!< Bit 4 */ - -#define ADC_JSQR_JSQ4 ((uint32_t)0x000F8000) /*!< JSQ4[4:0] bits (4th conversion in injected sequence) */ -#define ADC_JSQR_JSQ4_0 ((uint32_t)0x00008000) /*!< Bit 0 */ -#define ADC_JSQR_JSQ4_1 ((uint32_t)0x00010000) /*!< Bit 1 */ -#define ADC_JSQR_JSQ4_2 ((uint32_t)0x00020000) /*!< Bit 2 */ -#define ADC_JSQR_JSQ4_3 ((uint32_t)0x00040000) /*!< Bit 3 */ -#define ADC_JSQR_JSQ4_4 ((uint32_t)0x00080000) /*!< Bit 4 */ - -#define ADC_JSQR_JL ((uint32_t)0x00300000) /*!< JL[1:0] bits (Injected Sequence length) */ -#define ADC_JSQR_JL_0 ((uint32_t)0x00100000) /*!< Bit 0 */ -#define ADC_JSQR_JL_1 ((uint32_t)0x00200000) /*!< Bit 1 */ - -/******************* Bit definition for ADC_JDR1 register *******************/ -#define ADC_JDR1_JDATA ((uint32_t)0x0000FFFF) /*!< Injected data */ - -/******************* Bit definition for ADC_JDR2 register *******************/ -#define ADC_JDR2_JDATA ((uint32_t)0x0000FFFF) /*!< Injected data */ - -/******************* Bit definition for ADC_JDR3 register *******************/ -#define ADC_JDR3_JDATA ((uint32_t)0x0000FFFF) /*!< Injected data */ - -/******************* Bit definition for ADC_JDR4 register *******************/ -#define ADC_JDR4_JDATA ((uint32_t)0x0000FFFF) /*!< Injected data */ - -/******************** Bit definition for ADC_DR register ********************/ -#define ADC_DR_DATA ((uint32_t)0x0000FFFF) /*!< Regular data */ - - -/******************* Bit definition for ADC_CSR register ********************/ -#define ADC_CSR_AWD1 ((uint32_t)0x00000001) /*!< ADC1 Analog watchdog flag */ -#define ADC_CSR_EOC1 ((uint32_t)0x00000002) /*!< ADC1 End of conversion */ -#define ADC_CSR_JEOC1 ((uint32_t)0x00000004) /*!< ADC1 Injected channel end of conversion */ -#define ADC_CSR_JSTRT1 ((uint32_t)0x00000008) /*!< ADC1 Injected channel Start flag */ -#define ADC_CSR_STRT1 ((uint32_t)0x00000010) /*!< ADC1 Regular channel Start flag */ -#define ADC_CSR_OVR1 ((uint32_t)0x00000020) /*!< ADC1 overrun flag */ -#define ADC_CSR_ADONS1 ((uint32_t)0x00000040) /*!< ADON status of ADC1 */ - -/******************* Bit definition for ADC_CCR register ********************/ -#define ADC_CCR_ADCPRE ((uint32_t)0x00030000) /*!< ADC prescaler*/ -#define ADC_CCR_ADCPRE_0 ((uint32_t)0x00010000) /*!< Bit 0 */ -#define ADC_CCR_ADCPRE_1 ((uint32_t)0x00020000) /*!< Bit 1 */ -#define ADC_CCR_TSVREFE ((uint32_t)0x00800000) /*!< Temperature Sensor and VREFINT Enable */ - -/******************************************************************************/ -/* */ -/* Analog Comparators (COMP) */ -/* */ -/******************************************************************************/ - -/****************** Bit definition for COMP_CSR register ********************/ -#define COMP_CSR_10KPU ((uint32_t)0x00000001) /*!< 10K pull-up resistor */ -#define COMP_CSR_400KPU ((uint32_t)0x00000002) /*!< 400K pull-up resistor */ -#define COMP_CSR_10KPD ((uint32_t)0x00000004) /*!< 10K pull-down resistor */ -#define COMP_CSR_400KPD ((uint32_t)0x00000008) /*!< 400K pull-down resistor */ - -#define COMP_CSR_CMP1EN ((uint32_t)0x00000010) /*!< Comparator 1 enable */ -#define COMP_CSR_CMP1OUT ((uint32_t)0x00000080) /*!< Comparator 1 output */ - -#define COMP_CSR_SPEED ((uint32_t)0x00001000) /*!< Comparator 2 speed */ -#define COMP_CSR_CMP2OUT ((uint32_t)0x00002000) /*!< Comparator 2 ouput */ - -#define COMP_CSR_VREFOUTEN ((uint32_t)0x00010000) /*!< Comparator Vref Enable */ -#define COMP_CSR_WNDWE ((uint32_t)0x00020000) /*!< Window mode enable */ - -#define COMP_CSR_INSEL ((uint32_t)0x001C0000) /*!< INSEL[2:0] Inversion input Selection */ -#define COMP_CSR_INSEL_0 ((uint32_t)0x00040000) /*!< Bit 0 */ -#define COMP_CSR_INSEL_1 ((uint32_t)0x00080000) /*!< Bit 1 */ -#define COMP_CSR_INSEL_2 ((uint32_t)0x00100000) /*!< Bit 2 */ - -#define COMP_CSR_OUTSEL ((uint32_t)0x00E00000) /*!< OUTSEL[2:0] comparator 2 output redirection */ -#define COMP_CSR_OUTSEL_0 ((uint32_t)0x00200000) /*!< Bit 0 */ -#define COMP_CSR_OUTSEL_1 ((uint32_t)0x00400000) /*!< Bit 1 */ -#define COMP_CSR_OUTSEL_2 ((uint32_t)0x00800000) /*!< Bit 2 */ - -/******************************************************************************/ -/* */ -/* CRC calculation unit (CRC) */ -/* */ -/******************************************************************************/ - -/******************* Bit definition for CRC_DR register *********************/ -#define CRC_DR_DR ((uint32_t)0xFFFFFFFF) /*!< Data register bits */ - -/******************* Bit definition for CRC_IDR register ********************/ -#define CRC_IDR_IDR ((uint8_t)0xFF) /*!< General-purpose 8-bit data register bits */ - -/******************** Bit definition for CRC_CR register ********************/ -#define CRC_CR_RESET ((uint32_t)0x00000001) /*!< RESET bit */ - -/******************************************************************************/ -/* */ -/* Digital to Analog Converter (DAC) */ -/* */ -/******************************************************************************/ - -/******************** Bit definition for DAC_CR register ********************/ -#define DAC_CR_EN1 ((uint32_t)0x00000001) /*!
© COPYRIGHT 2010 STMicroelectronics
- ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32f10x_system - * @{ - */ - -/** - * @brief Define to prevent recursive inclusion - */ -#ifndef __SYSTEM_STM32F10X_H -#define __SYSTEM_STM32F10X_H - -#ifdef __cplusplus - extern "C" { -#endif - -/** @addtogroup STM32F10x_System_Includes - * @{ - */ - -/** - * @} - */ - - -/** @addtogroup STM32F10x_System_Exported_types - * @{ - */ - -extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ - -/** - * @} - */ - -/** @addtogroup STM32F10x_System_Exported_Constants - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32F10x_System_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32F10x_System_Exported_Functions - * @{ - */ - -extern void SystemInit(void); -extern void SystemCoreClockUpdate(void); -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /*__SYSTEM_STM32F10X_H */ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/device_support/system_stm32l1xx.h b/example/libs_stm/inc/device_support/system_stm32l1xx.h deleted file mode 100644 index 6ad7303cd..000000000 --- a/example/libs_stm/inc/device_support/system_stm32l1xx.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - ****************************************************************************** - * @file system_stm32l1xx.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File. - ****************************************************************************** - * @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 - * @{ - */ - -/** - * @brief Define to prevent recursive inclusion - */ -#ifndef __SYSTEM_STM32L1XX_H -#define __SYSTEM_STM32L1XX_H - -#ifdef __cplusplus - extern "C" { -#endif - -/** @addtogroup STM32L1xx_System_Includes - * @{ - */ - -/** - * @} - */ - - -/** @addtogroup STM32L1xx_System_Exported_types - * @{ - */ - -extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ - -/** - * @} - */ - -/** @addtogroup STM32L1xx_System_Exported_Constants - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32L1xx_System_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32L1xx_System_Exported_Functions - * @{ - */ - -extern void SystemInit(void); -extern void SystemCoreClockUpdate(void); -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /*__SYSTEM_STM32L1XX_H */ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/misc.h b/example/libs_stm/inc/stm32f10x/misc.h deleted file mode 100644 index 95c9541d3..000000000 --- a/example/libs_stm/inc/stm32f10x/misc.h +++ /dev/null @@ -1,219 +0,0 @@ -/** - ****************************************************************************** - * @file misc.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the miscellaneous - * firmware library functions (add-on to CMSIS functions). - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __MISC_H -#define __MISC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup MISC - * @{ - */ - -/** @defgroup MISC_Exported_Types - * @{ - */ - -/** - * @brief NVIC Init Structure definition - */ - -typedef struct -{ - uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled. - This parameter can be a value of @ref IRQn_Type - (For the complete STM32 Devices IRQ Channels list, please - refer to stm32f10x.h file) */ - - uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel - specified in NVIC_IRQChannel. This parameter can be a value - between 0 and 15 as described in the table @ref NVIC_Priority_Table */ - - uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified - in NVIC_IRQChannel. This parameter can be a value - between 0 and 15 as described in the table @ref NVIC_Priority_Table */ - - FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel - will be enabled or disabled. - This parameter can be set either to ENABLE or DISABLE */ -} NVIC_InitTypeDef; - -/** - * @} - */ - -/** @defgroup NVIC_Priority_Table - * @{ - */ - -/** -@code - The table below gives the allowed values of the pre-emption priority and subpriority according - to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function - ============================================================================================================================ - NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description - ============================================================================================================================ - NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority - | | | 4 bits for subpriority - ---------------------------------------------------------------------------------------------------------------------------- - NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority - | | | 3 bits for subpriority - ---------------------------------------------------------------------------------------------------------------------------- - NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority - | | | 2 bits for subpriority - ---------------------------------------------------------------------------------------------------------------------------- - NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority - | | | 1 bits for subpriority - ---------------------------------------------------------------------------------------------------------------------------- - NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority - | | | 0 bits for subpriority - ============================================================================================================================ -@endcode -*/ - -/** - * @} - */ - -/** @defgroup MISC_Exported_Constants - * @{ - */ - -/** @defgroup Vector_Table_Base - * @{ - */ - -#define NVIC_VectTab_RAM ((uint32_t)0x20000000) -#define NVIC_VectTab_FLASH ((uint32_t)0x08000000) -#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \ - ((VECTTAB) == NVIC_VectTab_FLASH)) -/** - * @} - */ - -/** @defgroup System_Low_Power - * @{ - */ - -#define NVIC_LP_SEVONPEND ((uint8_t)0x10) -#define NVIC_LP_SLEEPDEEP ((uint8_t)0x04) -#define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02) -#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \ - ((LP) == NVIC_LP_SLEEPDEEP) || \ - ((LP) == NVIC_LP_SLEEPONEXIT)) -/** - * @} - */ - -/** @defgroup Preemption_Priority_Group - * @{ - */ - -#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority - 4 bits for subpriority */ -#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority - 3 bits for subpriority */ -#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority - 2 bits for subpriority */ -#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority - 1 bits for subpriority */ -#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority - 0 bits for subpriority */ - -#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \ - ((GROUP) == NVIC_PriorityGroup_1) || \ - ((GROUP) == NVIC_PriorityGroup_2) || \ - ((GROUP) == NVIC_PriorityGroup_3) || \ - ((GROUP) == NVIC_PriorityGroup_4)) - -#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) - -#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) - -#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF) - -/** - * @} - */ - -/** @defgroup SysTick_clock_source - * @{ - */ - -#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) -#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004) -#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \ - ((SOURCE) == SysTick_CLKSource_HCLK_Div8)) -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup MISC_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup MISC_Exported_Functions - * @{ - */ - -void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); -void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); -void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset); -void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState); -void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource); - -#ifdef __cplusplus -} -#endif - -#endif /* __MISC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_adc.h b/example/libs_stm/inc/stm32f10x/stm32f10x_adc.h deleted file mode 100644 index 401241c4c..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_adc.h +++ /dev/null @@ -1,482 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_adc.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the ADC firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_ADC_H -#define __STM32F10x_ADC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup ADC - * @{ - */ - -/** @defgroup ADC_Exported_Types - * @{ - */ - -/** - * @brief ADC Init structure definition - */ - -typedef struct -{ - uint32_t ADC_Mode; /*!< Configures the ADC to operate in independent or - dual mode. - This parameter can be a value of @ref ADC_mode */ - - FunctionalState ADC_ScanConvMode; /*!< Specifies whether the conversion is performed in - Scan (multichannels) or Single (one channel) mode. - This parameter can be set to ENABLE or DISABLE */ - - FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion is performed in - Continuous or Single mode. - This parameter can be set to ENABLE or DISABLE. */ - - uint32_t ADC_ExternalTrigConv; /*!< Defines the external trigger used to start the analog - to digital conversion of regular channels. This parameter - can be a value of @ref ADC_external_trigger_sources_for_regular_channels_conversion */ - - uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment is left or right. - This parameter can be a value of @ref ADC_data_align */ - - uint8_t ADC_NbrOfChannel; /*!< Specifies the number of ADC channels that will be converted - using the sequencer for regular channel group. - This parameter must range from 1 to 16. */ -}ADC_InitTypeDef; -/** - * @} - */ - -/** @defgroup ADC_Exported_Constants - * @{ - */ - -#define IS_ADC_ALL_PERIPH(PERIPH) (((PERIPH) == ADC1) || \ - ((PERIPH) == ADC2) || \ - ((PERIPH) == ADC3)) - -#define IS_ADC_DMA_PERIPH(PERIPH) (((PERIPH) == ADC1) || \ - ((PERIPH) == ADC3)) - -/** @defgroup ADC_mode - * @{ - */ - -#define ADC_Mode_Independent ((uint32_t)0x00000000) -#define ADC_Mode_RegInjecSimult ((uint32_t)0x00010000) -#define ADC_Mode_RegSimult_AlterTrig ((uint32_t)0x00020000) -#define ADC_Mode_InjecSimult_FastInterl ((uint32_t)0x00030000) -#define ADC_Mode_InjecSimult_SlowInterl ((uint32_t)0x00040000) -#define ADC_Mode_InjecSimult ((uint32_t)0x00050000) -#define ADC_Mode_RegSimult ((uint32_t)0x00060000) -#define ADC_Mode_FastInterl ((uint32_t)0x00070000) -#define ADC_Mode_SlowInterl ((uint32_t)0x00080000) -#define ADC_Mode_AlterTrig ((uint32_t)0x00090000) - -#define IS_ADC_MODE(MODE) (((MODE) == ADC_Mode_Independent) || \ - ((MODE) == ADC_Mode_RegInjecSimult) || \ - ((MODE) == ADC_Mode_RegSimult_AlterTrig) || \ - ((MODE) == ADC_Mode_InjecSimult_FastInterl) || \ - ((MODE) == ADC_Mode_InjecSimult_SlowInterl) || \ - ((MODE) == ADC_Mode_InjecSimult) || \ - ((MODE) == ADC_Mode_RegSimult) || \ - ((MODE) == ADC_Mode_FastInterl) || \ - ((MODE) == ADC_Mode_SlowInterl) || \ - ((MODE) == ADC_Mode_AlterTrig)) -/** - * @} - */ - -/** @defgroup ADC_external_trigger_sources_for_regular_channels_conversion - * @{ - */ - -#define ADC_ExternalTrigConv_T1_CC1 ((uint32_t)0x00000000) /*!< For ADC1 and ADC2 */ -#define ADC_ExternalTrigConv_T1_CC2 ((uint32_t)0x00020000) /*!< For ADC1 and ADC2 */ -#define ADC_ExternalTrigConv_T2_CC2 ((uint32_t)0x00060000) /*!< For ADC1 and ADC2 */ -#define ADC_ExternalTrigConv_T3_TRGO ((uint32_t)0x00080000) /*!< For ADC1 and ADC2 */ -#define ADC_ExternalTrigConv_T4_CC4 ((uint32_t)0x000A0000) /*!< For ADC1 and ADC2 */ -#define ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO ((uint32_t)0x000C0000) /*!< For ADC1 and ADC2 */ - -#define ADC_ExternalTrigConv_T1_CC3 ((uint32_t)0x00040000) /*!< For ADC1, ADC2 and ADC3 */ -#define ADC_ExternalTrigConv_None ((uint32_t)0x000E0000) /*!< For ADC1, ADC2 and ADC3 */ - -#define ADC_ExternalTrigConv_T3_CC1 ((uint32_t)0x00000000) /*!< For ADC3 only */ -#define ADC_ExternalTrigConv_T2_CC3 ((uint32_t)0x00020000) /*!< For ADC3 only */ -#define ADC_ExternalTrigConv_T8_CC1 ((uint32_t)0x00060000) /*!< For ADC3 only */ -#define ADC_ExternalTrigConv_T8_TRGO ((uint32_t)0x00080000) /*!< For ADC3 only */ -#define ADC_ExternalTrigConv_T5_CC1 ((uint32_t)0x000A0000) /*!< For ADC3 only */ -#define ADC_ExternalTrigConv_T5_CC3 ((uint32_t)0x000C0000) /*!< For ADC3 only */ - -#define IS_ADC_EXT_TRIG(REGTRIG) (((REGTRIG) == ADC_ExternalTrigConv_T1_CC1) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T1_CC2) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T1_CC3) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T2_CC2) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T3_TRGO) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T4_CC4) || \ - ((REGTRIG) == ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO) || \ - ((REGTRIG) == ADC_ExternalTrigConv_None) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T3_CC1) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T2_CC3) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T8_CC1) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T8_TRGO) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T5_CC1) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T5_CC3)) -/** - * @} - */ - -/** @defgroup ADC_data_align - * @{ - */ - -#define ADC_DataAlign_Right ((uint32_t)0x00000000) -#define ADC_DataAlign_Left ((uint32_t)0x00000800) -#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DataAlign_Right) || \ - ((ALIGN) == ADC_DataAlign_Left)) -/** - * @} - */ - -/** @defgroup ADC_channels - * @{ - */ - -#define ADC_Channel_0 ((uint8_t)0x00) -#define ADC_Channel_1 ((uint8_t)0x01) -#define ADC_Channel_2 ((uint8_t)0x02) -#define ADC_Channel_3 ((uint8_t)0x03) -#define ADC_Channel_4 ((uint8_t)0x04) -#define ADC_Channel_5 ((uint8_t)0x05) -#define ADC_Channel_6 ((uint8_t)0x06) -#define ADC_Channel_7 ((uint8_t)0x07) -#define ADC_Channel_8 ((uint8_t)0x08) -#define ADC_Channel_9 ((uint8_t)0x09) -#define ADC_Channel_10 ((uint8_t)0x0A) -#define ADC_Channel_11 ((uint8_t)0x0B) -#define ADC_Channel_12 ((uint8_t)0x0C) -#define ADC_Channel_13 ((uint8_t)0x0D) -#define ADC_Channel_14 ((uint8_t)0x0E) -#define ADC_Channel_15 ((uint8_t)0x0F) -#define ADC_Channel_16 ((uint8_t)0x10) -#define ADC_Channel_17 ((uint8_t)0x11) - -#define ADC_Channel_TempSensor ((uint8_t)ADC_Channel_16) -#define ADC_Channel_Vrefint ((uint8_t)ADC_Channel_17) - -#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_0) || ((CHANNEL) == ADC_Channel_1) || \ - ((CHANNEL) == ADC_Channel_2) || ((CHANNEL) == ADC_Channel_3) || \ - ((CHANNEL) == ADC_Channel_4) || ((CHANNEL) == ADC_Channel_5) || \ - ((CHANNEL) == ADC_Channel_6) || ((CHANNEL) == ADC_Channel_7) || \ - ((CHANNEL) == ADC_Channel_8) || ((CHANNEL) == ADC_Channel_9) || \ - ((CHANNEL) == ADC_Channel_10) || ((CHANNEL) == ADC_Channel_11) || \ - ((CHANNEL) == ADC_Channel_12) || ((CHANNEL) == ADC_Channel_13) || \ - ((CHANNEL) == ADC_Channel_14) || ((CHANNEL) == ADC_Channel_15) || \ - ((CHANNEL) == ADC_Channel_16) || ((CHANNEL) == ADC_Channel_17)) -/** - * @} - */ - -/** @defgroup ADC_sampling_time - * @{ - */ - -#define ADC_SampleTime_1Cycles5 ((uint8_t)0x00) -#define ADC_SampleTime_7Cycles5 ((uint8_t)0x01) -#define ADC_SampleTime_13Cycles5 ((uint8_t)0x02) -#define ADC_SampleTime_28Cycles5 ((uint8_t)0x03) -#define ADC_SampleTime_41Cycles5 ((uint8_t)0x04) -#define ADC_SampleTime_55Cycles5 ((uint8_t)0x05) -#define ADC_SampleTime_71Cycles5 ((uint8_t)0x06) -#define ADC_SampleTime_239Cycles5 ((uint8_t)0x07) -#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_1Cycles5) || \ - ((TIME) == ADC_SampleTime_7Cycles5) || \ - ((TIME) == ADC_SampleTime_13Cycles5) || \ - ((TIME) == ADC_SampleTime_28Cycles5) || \ - ((TIME) == ADC_SampleTime_41Cycles5) || \ - ((TIME) == ADC_SampleTime_55Cycles5) || \ - ((TIME) == ADC_SampleTime_71Cycles5) || \ - ((TIME) == ADC_SampleTime_239Cycles5)) -/** - * @} - */ - -/** @defgroup ADC_external_trigger_sources_for_injected_channels_conversion - * @{ - */ - -#define ADC_ExternalTrigInjecConv_T2_TRGO ((uint32_t)0x00002000) /*!< For ADC1 and ADC2 */ -#define ADC_ExternalTrigInjecConv_T2_CC1 ((uint32_t)0x00003000) /*!< For ADC1 and ADC2 */ -#define ADC_ExternalTrigInjecConv_T3_CC4 ((uint32_t)0x00004000) /*!< For ADC1 and ADC2 */ -#define ADC_ExternalTrigInjecConv_T4_TRGO ((uint32_t)0x00005000) /*!< For ADC1 and ADC2 */ -#define ADC_ExternalTrigInjecConv_Ext_IT15_TIM8_CC4 ((uint32_t)0x00006000) /*!< For ADC1 and ADC2 */ - -#define ADC_ExternalTrigInjecConv_T1_TRGO ((uint32_t)0x00000000) /*!< For ADC1, ADC2 and ADC3 */ -#define ADC_ExternalTrigInjecConv_T1_CC4 ((uint32_t)0x00001000) /*!< For ADC1, ADC2 and ADC3 */ -#define ADC_ExternalTrigInjecConv_None ((uint32_t)0x00007000) /*!< For ADC1, ADC2 and ADC3 */ - -#define ADC_ExternalTrigInjecConv_T4_CC3 ((uint32_t)0x00002000) /*!< For ADC3 only */ -#define ADC_ExternalTrigInjecConv_T8_CC2 ((uint32_t)0x00003000) /*!< For ADC3 only */ -#define ADC_ExternalTrigInjecConv_T8_CC4 ((uint32_t)0x00004000) /*!< For ADC3 only */ -#define ADC_ExternalTrigInjecConv_T5_TRGO ((uint32_t)0x00005000) /*!< For ADC3 only */ -#define ADC_ExternalTrigInjecConv_T5_CC4 ((uint32_t)0x00006000) /*!< For ADC3 only */ - -#define IS_ADC_EXT_INJEC_TRIG(INJTRIG) (((INJTRIG) == ADC_ExternalTrigInjecConv_T1_TRGO) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T1_CC4) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_TRGO) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_CC1) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC4) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_TRGO) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_Ext_IT15_TIM8_CC4) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_None) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC3) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC2) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC4) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T5_TRGO) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T5_CC4)) -/** - * @} - */ - -/** @defgroup ADC_injected_channel_selection - * @{ - */ - -#define ADC_InjectedChannel_1 ((uint8_t)0x14) -#define ADC_InjectedChannel_2 ((uint8_t)0x18) -#define ADC_InjectedChannel_3 ((uint8_t)0x1C) -#define ADC_InjectedChannel_4 ((uint8_t)0x20) -#define IS_ADC_INJECTED_CHANNEL(CHANNEL) (((CHANNEL) == ADC_InjectedChannel_1) || \ - ((CHANNEL) == ADC_InjectedChannel_2) || \ - ((CHANNEL) == ADC_InjectedChannel_3) || \ - ((CHANNEL) == ADC_InjectedChannel_4)) -/** - * @} - */ - -/** @defgroup ADC_analog_watchdog_selection - * @{ - */ - -#define ADC_AnalogWatchdog_SingleRegEnable ((uint32_t)0x00800200) -#define ADC_AnalogWatchdog_SingleInjecEnable ((uint32_t)0x00400200) -#define ADC_AnalogWatchdog_SingleRegOrInjecEnable ((uint32_t)0x00C00200) -#define ADC_AnalogWatchdog_AllRegEnable ((uint32_t)0x00800000) -#define ADC_AnalogWatchdog_AllInjecEnable ((uint32_t)0x00400000) -#define ADC_AnalogWatchdog_AllRegAllInjecEnable ((uint32_t)0x00C00000) -#define ADC_AnalogWatchdog_None ((uint32_t)0x00000000) - -#define IS_ADC_ANALOG_WATCHDOG(WATCHDOG) (((WATCHDOG) == ADC_AnalogWatchdog_SingleRegEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_SingleInjecEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_SingleRegOrInjecEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_AllRegEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_AllInjecEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_AllRegAllInjecEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_None)) -/** - * @} - */ - -/** @defgroup ADC_interrupts_definition - * @{ - */ - -#define ADC_IT_EOC ((uint16_t)0x0220) -#define ADC_IT_AWD ((uint16_t)0x0140) -#define ADC_IT_JEOC ((uint16_t)0x0480) - -#define IS_ADC_IT(IT) ((((IT) & (uint16_t)0xF81F) == 0x00) && ((IT) != 0x00)) - -#define IS_ADC_GET_IT(IT) (((IT) == ADC_IT_EOC) || ((IT) == ADC_IT_AWD) || \ - ((IT) == ADC_IT_JEOC)) -/** - * @} - */ - -/** @defgroup ADC_flags_definition - * @{ - */ - -#define ADC_FLAG_AWD ((uint8_t)0x01) -#define ADC_FLAG_EOC ((uint8_t)0x02) -#define ADC_FLAG_JEOC ((uint8_t)0x04) -#define ADC_FLAG_JSTRT ((uint8_t)0x08) -#define ADC_FLAG_STRT ((uint8_t)0x10) -#define IS_ADC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint8_t)0xE0) == 0x00) && ((FLAG) != 0x00)) -#define IS_ADC_GET_FLAG(FLAG) (((FLAG) == ADC_FLAG_AWD) || ((FLAG) == ADC_FLAG_EOC) || \ - ((FLAG) == ADC_FLAG_JEOC) || ((FLAG)== ADC_FLAG_JSTRT) || \ - ((FLAG) == ADC_FLAG_STRT)) -/** - * @} - */ - -/** @defgroup ADC_thresholds - * @{ - */ - -#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFF) - -/** - * @} - */ - -/** @defgroup ADC_injected_offset - * @{ - */ - -#define IS_ADC_OFFSET(OFFSET) ((OFFSET) <= 0xFFF) - -/** - * @} - */ - -/** @defgroup ADC_injected_length - * @{ - */ - -#define IS_ADC_INJECTED_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x4)) - -/** - * @} - */ - -/** @defgroup ADC_injected_rank - * @{ - */ - -#define IS_ADC_INJECTED_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x4)) - -/** - * @} - */ - - -/** @defgroup ADC_regular_length - * @{ - */ - -#define IS_ADC_REGULAR_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x10)) -/** - * @} - */ - -/** @defgroup ADC_regular_rank - * @{ - */ - -#define IS_ADC_REGULAR_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x10)) - -/** - * @} - */ - -/** @defgroup ADC_regular_discontinuous_mode_number - * @{ - */ - -#define IS_ADC_REGULAR_DISC_NUMBER(NUMBER) (((NUMBER) >= 0x1) && ((NUMBER) <= 0x8)) - -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup ADC_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup ADC_Exported_Functions - * @{ - */ - -void ADC_DeInit(ADC_TypeDef* ADCx); -void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct); -void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct); -void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState); -void ADC_ResetCalibration(ADC_TypeDef* ADCx); -FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx); -void ADC_StartCalibration(ADC_TypeDef* ADCx); -FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx); -void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx); -void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number); -void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); -void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx); -uint32_t ADC_GetDualModeConversionValue(void); -void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv); -void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_SoftwareStartInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx); -void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); -void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length); -void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset); -uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel); -void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog); -void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold); -void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel); -void ADC_TempSensorVrefintCmd(FunctionalState NewState); -FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG); -void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG); -ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT); -void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F10x_ADC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_bkp.h b/example/libs_stm/inc/stm32f10x/stm32f10x_bkp.h deleted file mode 100644 index 45c4e3500..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_bkp.h +++ /dev/null @@ -1,194 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_bkp.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the BKP firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_BKP_H -#define __STM32F10x_BKP_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup BKP - * @{ - */ - -/** @defgroup BKP_Exported_Types - * @{ - */ - -/** - * @} - */ - -/** @defgroup BKP_Exported_Constants - * @{ - */ - -/** @defgroup Tamper_Pin_active_level - * @{ - */ - -#define BKP_TamperPinLevel_High ((uint16_t)0x0000) -#define BKP_TamperPinLevel_Low ((uint16_t)0x0001) -#define IS_BKP_TAMPER_PIN_LEVEL(LEVEL) (((LEVEL) == BKP_TamperPinLevel_High) || \ - ((LEVEL) == BKP_TamperPinLevel_Low)) -/** - * @} - */ - -/** @defgroup RTC_output_source_to_output_on_the_Tamper_pin - * @{ - */ - -#define BKP_RTCOutputSource_None ((uint16_t)0x0000) -#define BKP_RTCOutputSource_CalibClock ((uint16_t)0x0080) -#define BKP_RTCOutputSource_Alarm ((uint16_t)0x0100) -#define BKP_RTCOutputSource_Second ((uint16_t)0x0300) -#define IS_BKP_RTC_OUTPUT_SOURCE(SOURCE) (((SOURCE) == BKP_RTCOutputSource_None) || \ - ((SOURCE) == BKP_RTCOutputSource_CalibClock) || \ - ((SOURCE) == BKP_RTCOutputSource_Alarm) || \ - ((SOURCE) == BKP_RTCOutputSource_Second)) -/** - * @} - */ - -/** @defgroup Data_Backup_Register - * @{ - */ - -#define BKP_DR1 ((uint16_t)0x0004) -#define BKP_DR2 ((uint16_t)0x0008) -#define BKP_DR3 ((uint16_t)0x000C) -#define BKP_DR4 ((uint16_t)0x0010) -#define BKP_DR5 ((uint16_t)0x0014) -#define BKP_DR6 ((uint16_t)0x0018) -#define BKP_DR7 ((uint16_t)0x001C) -#define BKP_DR8 ((uint16_t)0x0020) -#define BKP_DR9 ((uint16_t)0x0024) -#define BKP_DR10 ((uint16_t)0x0028) -#define BKP_DR11 ((uint16_t)0x0040) -#define BKP_DR12 ((uint16_t)0x0044) -#define BKP_DR13 ((uint16_t)0x0048) -#define BKP_DR14 ((uint16_t)0x004C) -#define BKP_DR15 ((uint16_t)0x0050) -#define BKP_DR16 ((uint16_t)0x0054) -#define BKP_DR17 ((uint16_t)0x0058) -#define BKP_DR18 ((uint16_t)0x005C) -#define BKP_DR19 ((uint16_t)0x0060) -#define BKP_DR20 ((uint16_t)0x0064) -#define BKP_DR21 ((uint16_t)0x0068) -#define BKP_DR22 ((uint16_t)0x006C) -#define BKP_DR23 ((uint16_t)0x0070) -#define BKP_DR24 ((uint16_t)0x0074) -#define BKP_DR25 ((uint16_t)0x0078) -#define BKP_DR26 ((uint16_t)0x007C) -#define BKP_DR27 ((uint16_t)0x0080) -#define BKP_DR28 ((uint16_t)0x0084) -#define BKP_DR29 ((uint16_t)0x0088) -#define BKP_DR30 ((uint16_t)0x008C) -#define BKP_DR31 ((uint16_t)0x0090) -#define BKP_DR32 ((uint16_t)0x0094) -#define BKP_DR33 ((uint16_t)0x0098) -#define BKP_DR34 ((uint16_t)0x009C) -#define BKP_DR35 ((uint16_t)0x00A0) -#define BKP_DR36 ((uint16_t)0x00A4) -#define BKP_DR37 ((uint16_t)0x00A8) -#define BKP_DR38 ((uint16_t)0x00AC) -#define BKP_DR39 ((uint16_t)0x00B0) -#define BKP_DR40 ((uint16_t)0x00B4) -#define BKP_DR41 ((uint16_t)0x00B8) -#define BKP_DR42 ((uint16_t)0x00BC) - -#define IS_BKP_DR(DR) (((DR) == BKP_DR1) || ((DR) == BKP_DR2) || ((DR) == BKP_DR3) || \ - ((DR) == BKP_DR4) || ((DR) == BKP_DR5) || ((DR) == BKP_DR6) || \ - ((DR) == BKP_DR7) || ((DR) == BKP_DR8) || ((DR) == BKP_DR9) || \ - ((DR) == BKP_DR10) || ((DR) == BKP_DR11) || ((DR) == BKP_DR12) || \ - ((DR) == BKP_DR13) || ((DR) == BKP_DR14) || ((DR) == BKP_DR15) || \ - ((DR) == BKP_DR16) || ((DR) == BKP_DR17) || ((DR) == BKP_DR18) || \ - ((DR) == BKP_DR19) || ((DR) == BKP_DR20) || ((DR) == BKP_DR21) || \ - ((DR) == BKP_DR22) || ((DR) == BKP_DR23) || ((DR) == BKP_DR24) || \ - ((DR) == BKP_DR25) || ((DR) == BKP_DR26) || ((DR) == BKP_DR27) || \ - ((DR) == BKP_DR28) || ((DR) == BKP_DR29) || ((DR) == BKP_DR30) || \ - ((DR) == BKP_DR31) || ((DR) == BKP_DR32) || ((DR) == BKP_DR33) || \ - ((DR) == BKP_DR34) || ((DR) == BKP_DR35) || ((DR) == BKP_DR36) || \ - ((DR) == BKP_DR37) || ((DR) == BKP_DR38) || ((DR) == BKP_DR39) || \ - ((DR) == BKP_DR40) || ((DR) == BKP_DR41) || ((DR) == BKP_DR42)) - -#define IS_BKP_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x7F) -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup BKP_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup BKP_Exported_Functions - * @{ - */ - -void BKP_DeInit(void); -void BKP_TamperPinLevelConfig(uint16_t BKP_TamperPinLevel); -void BKP_TamperPinCmd(FunctionalState NewState); -void BKP_ITConfig(FunctionalState NewState); -void BKP_RTCOutputConfig(uint16_t BKP_RTCOutputSource); -void BKP_SetRTCCalibrationValue(uint8_t CalibrationValue); -void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data); -uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR); -FlagStatus BKP_GetFlagStatus(void); -void BKP_ClearFlag(void); -ITStatus BKP_GetITStatus(void); -void BKP_ClearITPendingBit(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_BKP_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_can.h b/example/libs_stm/inc/stm32f10x/stm32f10x_can.h deleted file mode 100644 index d9ae0676f..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_can.h +++ /dev/null @@ -1,535 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_can.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the CAN firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_CAN_H -#define __STM32F10x_CAN_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup CAN - * @{ - */ - -/** @defgroup CAN_Exported_Types - * @{ - */ - -#define IS_CAN_ALL_PERIPH(PERIPH) (((PERIPH) == CAN1) || \ - ((PERIPH) == CAN2)) - -/** - * @brief CAN init structure definition - */ - -typedef struct -{ - uint16_t CAN_Prescaler; /*!< Specifies the length of a time quantum. It ranges from 1 to 1024. */ - - uint8_t CAN_Mode; /*!< Specifies the CAN operating mode. - This parameter can be a value of @ref CAN_operating_mode */ - - uint8_t CAN_SJW; /*!< Specifies the maximum number of time quanta the CAN hardware - is allowed to lengthen or shorten a bit to perform resynchronization. - This parameter can be a value of @ref CAN_synchronisation_jump_width */ - - uint8_t CAN_BS1; /*!< Specifies the number of time quanta in Bit Segment 1. - This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_1 */ - - uint8_t CAN_BS2; /*!< Specifies the number of time quanta in Bit Segment 2. - This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */ - - FunctionalState CAN_TTCM; /*!< Enable or disable the time triggered communication mode. - This parameter can be set either to ENABLE or DISABLE. */ - - FunctionalState CAN_ABOM; /*!< Enable or disable the automatic bus-off management. - This parameter can be set either to ENABLE or DISABLE. */ - - FunctionalState CAN_AWUM; /*!< Enable or disable the automatic wake-up mode. - This parameter can be set either to ENABLE or DISABLE. */ - - FunctionalState CAN_NART; /*!< Enable or disable the no-automatic retransmission mode. - This parameter can be set either to ENABLE or DISABLE. */ - - FunctionalState CAN_RFLM; /*!< Enable or disable the Receive FIFO Locked mode. - This parameter can be set either to ENABLE or DISABLE. */ - - FunctionalState CAN_TXFP; /*!< Enable or disable the transmit FIFO priority. - This parameter can be set either to ENABLE or DISABLE. */ -} CAN_InitTypeDef; - -/** - * @brief CAN filter init structure definition - */ - -typedef struct -{ - uint16_t CAN_FilterIdHigh; /*!< Specifies the filter identification number (MSBs for a 32-bit - configuration, first one for a 16-bit configuration). - This parameter can be a value between 0x0000 and 0xFFFF */ - - uint16_t CAN_FilterIdLow; /*!< Specifies the filter identification number (LSBs for a 32-bit - configuration, second one for a 16-bit configuration). - This parameter can be a value between 0x0000 and 0xFFFF */ - - uint16_t CAN_FilterMaskIdHigh; /*!< Specifies the filter mask number or identification number, - according to the mode (MSBs for a 32-bit configuration, - first one for a 16-bit configuration). - This parameter can be a value between 0x0000 and 0xFFFF */ - - uint16_t CAN_FilterMaskIdLow; /*!< Specifies the filter mask number or identification number, - according to the mode (LSBs for a 32-bit configuration, - second one for a 16-bit configuration). - This parameter can be a value between 0x0000 and 0xFFFF */ - - uint16_t CAN_FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1) which will be assigned to the filter. - This parameter can be a value of @ref CAN_filter_FIFO */ - - uint8_t CAN_FilterNumber; /*!< Specifies the filter which will be initialized. It ranges from 0 to 13. */ - - uint8_t CAN_FilterMode; /*!< Specifies the filter mode to be initialized. - This parameter can be a value of @ref CAN_filter_mode */ - - uint8_t CAN_FilterScale; /*!< Specifies the filter scale. - This parameter can be a value of @ref CAN_filter_scale */ - - FunctionalState CAN_FilterActivation; /*!< Enable or disable the filter. - This parameter can be set either to ENABLE or DISABLE. */ -} CAN_FilterInitTypeDef; - -/** - * @brief CAN Tx message structure definition - */ - -typedef struct -{ - uint32_t StdId; /*!< Specifies the standard identifier. - This parameter can be a value between 0 to 0x7FF. */ - - uint32_t ExtId; /*!< Specifies the extended identifier. - This parameter can be a value between 0 to 0x1FFFFFFF. */ - - uint8_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted. - This parameter can be a value of @ref CAN_identifier_type */ - - uint8_t RTR; /*!< Specifies the type of frame for the message that will be transmitted. - This parameter can be a value of @ref CAN_remote_transmission_request */ - - uint8_t DLC; /*!< Specifies the length of the frame that will be transmitted. - This parameter can be a value between 0 to 8 */ - - uint8_t Data[8]; /*!< Contains the data to be transmitted. It ranges from 0 to 0xFF. */ -} CanTxMsg; - -/** - * @brief CAN Rx message structure definition - */ - -typedef struct -{ - uint32_t StdId; /*!< Specifies the standard identifier. - This parameter can be a value between 0 to 0x7FF. */ - - uint32_t ExtId; /*!< Specifies the extended identifier. - This parameter can be a value between 0 to 0x1FFFFFFF. */ - - uint8_t IDE; /*!< Specifies the type of identifier for the message that will be received. - This parameter can be a value of @ref CAN_identifier_type */ - - uint8_t RTR; /*!< Specifies the type of frame for the received message. - This parameter can be a value of @ref CAN_remote_transmission_request */ - - uint8_t DLC; /*!< Specifies the length of the frame that will be received. - This parameter can be a value between 0 to 8 */ - - uint8_t Data[8]; /*!< Contains the data to be received. It ranges from 0 to 0xFF. */ - - uint8_t FMI; /*!< Specifies the index of the filter the message stored in the mailbox passes through. - This parameter can be a value between 0 to 0xFF */ -} CanRxMsg; - -/** - * @} - */ - -/** @defgroup CAN_Exported_Constants - * @{ - */ - -/** @defgroup CAN_sleep_constants - * @{ - */ - -#define CANINITFAILED ((uint8_t)0x00) /*!< CAN initialization failed */ -#define CANINITOK ((uint8_t)0x01) /*!< CAN initialization failed */ - -/** - * @} - */ - -/** @defgroup CAN_operating_mode - * @{ - */ - -#define CAN_Mode_Normal ((uint8_t)0x00) /*!< normal mode */ -#define CAN_Mode_LoopBack ((uint8_t)0x01) /*!< loopback mode */ -#define CAN_Mode_Silent ((uint8_t)0x02) /*!< silent mode */ -#define CAN_Mode_Silent_LoopBack ((uint8_t)0x03) /*!< loopback combined with silent mode */ - -#define IS_CAN_MODE(MODE) (((MODE) == CAN_Mode_Normal) || ((MODE) == CAN_Mode_LoopBack)|| \ - ((MODE) == CAN_Mode_Silent) || ((MODE) == CAN_Mode_Silent_LoopBack)) -/** - * @} - */ - -/** @defgroup CAN_synchronisation_jump_width - * @{ - */ - -#define CAN_SJW_1tq ((uint8_t)0x00) /*!< 1 time quantum */ -#define CAN_SJW_2tq ((uint8_t)0x01) /*!< 2 time quantum */ -#define CAN_SJW_3tq ((uint8_t)0x02) /*!< 3 time quantum */ -#define CAN_SJW_4tq ((uint8_t)0x03) /*!< 4 time quantum */ - -#define IS_CAN_SJW(SJW) (((SJW) == CAN_SJW_1tq) || ((SJW) == CAN_SJW_2tq)|| \ - ((SJW) == CAN_SJW_3tq) || ((SJW) == CAN_SJW_4tq)) -/** - * @} - */ - -/** @defgroup CAN_time_quantum_in_bit_segment_1 - * @{ - */ - -#define CAN_BS1_1tq ((uint8_t)0x00) /*!< 1 time quantum */ -#define CAN_BS1_2tq ((uint8_t)0x01) /*!< 2 time quantum */ -#define CAN_BS1_3tq ((uint8_t)0x02) /*!< 3 time quantum */ -#define CAN_BS1_4tq ((uint8_t)0x03) /*!< 4 time quantum */ -#define CAN_BS1_5tq ((uint8_t)0x04) /*!< 5 time quantum */ -#define CAN_BS1_6tq ((uint8_t)0x05) /*!< 6 time quantum */ -#define CAN_BS1_7tq ((uint8_t)0x06) /*!< 7 time quantum */ -#define CAN_BS1_8tq ((uint8_t)0x07) /*!< 8 time quantum */ -#define CAN_BS1_9tq ((uint8_t)0x08) /*!< 9 time quantum */ -#define CAN_BS1_10tq ((uint8_t)0x09) /*!< 10 time quantum */ -#define CAN_BS1_11tq ((uint8_t)0x0A) /*!< 11 time quantum */ -#define CAN_BS1_12tq ((uint8_t)0x0B) /*!< 12 time quantum */ -#define CAN_BS1_13tq ((uint8_t)0x0C) /*!< 13 time quantum */ -#define CAN_BS1_14tq ((uint8_t)0x0D) /*!< 14 time quantum */ -#define CAN_BS1_15tq ((uint8_t)0x0E) /*!< 15 time quantum */ -#define CAN_BS1_16tq ((uint8_t)0x0F) /*!< 16 time quantum */ - -#define IS_CAN_BS1(BS1) ((BS1) <= CAN_BS1_16tq) -/** - * @} - */ - -/** @defgroup CAN_time_quantum_in_bit_segment_2 - * @{ - */ - -#define CAN_BS2_1tq ((uint8_t)0x00) /*!< 1 time quantum */ -#define CAN_BS2_2tq ((uint8_t)0x01) /*!< 2 time quantum */ -#define CAN_BS2_3tq ((uint8_t)0x02) /*!< 3 time quantum */ -#define CAN_BS2_4tq ((uint8_t)0x03) /*!< 4 time quantum */ -#define CAN_BS2_5tq ((uint8_t)0x04) /*!< 5 time quantum */ -#define CAN_BS2_6tq ((uint8_t)0x05) /*!< 6 time quantum */ -#define CAN_BS2_7tq ((uint8_t)0x06) /*!< 7 time quantum */ -#define CAN_BS2_8tq ((uint8_t)0x07) /*!< 8 time quantum */ - -#define IS_CAN_BS2(BS2) ((BS2) <= CAN_BS2_8tq) - -/** - * @} - */ - -/** @defgroup CAN_clock_prescaler - * @{ - */ - -#define IS_CAN_PRESCALER(PRESCALER) (((PRESCALER) >= 1) && ((PRESCALER) <= 1024)) - -/** - * @} - */ - -/** @defgroup CAN_filter_number - * @{ - */ -#ifndef STM32F10X_CL - #define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 13) -#else - #define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 27) -#endif /* STM32F10X_CL */ -/** - * @} - */ - -/** @defgroup CAN_filter_mode - * @{ - */ - -#define CAN_FilterMode_IdMask ((uint8_t)0x00) /*!< id/mask mode */ -#define CAN_FilterMode_IdList ((uint8_t)0x01) /*!< identifier list mode */ - -#define IS_CAN_FILTER_MODE(MODE) (((MODE) == CAN_FilterMode_IdMask) || \ - ((MODE) == CAN_FilterMode_IdList)) -/** - * @} - */ - -/** @defgroup CAN_filter_scale - * @{ - */ - -#define CAN_FilterScale_16bit ((uint8_t)0x00) /*!< Two 16-bit filters */ -#define CAN_FilterScale_32bit ((uint8_t)0x01) /*!< One 32-bit filter */ - -#define IS_CAN_FILTER_SCALE(SCALE) (((SCALE) == CAN_FilterScale_16bit) || \ - ((SCALE) == CAN_FilterScale_32bit)) - -/** - * @} - */ - -/** @defgroup CAN_filter_FIFO - * @{ - */ - -#define CAN_FilterFIFO0 ((uint8_t)0x00) /*!< Filter FIFO 0 assignment for filter x */ -#define CAN_FilterFIFO1 ((uint8_t)0x01) /*!< Filter FIFO 1 assignment for filter x */ -#define IS_CAN_FILTER_FIFO(FIFO) (((FIFO) == CAN_FilterFIFO0) || \ - ((FIFO) == CAN_FilterFIFO1)) - -/** - * @} - */ - -/** @defgroup Start_bank_filter_for_slave_CAN - * @{ - */ -#define IS_CAN_BANKNUMBER(BANKNUMBER) (((BANKNUMBER) >= 1) && ((BANKNUMBER) <= 27)) -/** - * @} - */ - -/** @defgroup CAN_Tx - * @{ - */ - -#define IS_CAN_TRANSMITMAILBOX(TRANSMITMAILBOX) ((TRANSMITMAILBOX) <= ((uint8_t)0x02)) -#define IS_CAN_STDID(STDID) ((STDID) <= ((uint32_t)0x7FF)) -#define IS_CAN_EXTID(EXTID) ((EXTID) <= ((uint32_t)0x1FFFFFFF)) -#define IS_CAN_DLC(DLC) ((DLC) <= ((uint8_t)0x08)) - -/** - * @} - */ - -/** @defgroup CAN_identifier_type - * @{ - */ - -#define CAN_ID_STD ((uint32_t)0x00000000) /*!< Standard Id */ -#define CAN_ID_EXT ((uint32_t)0x00000004) /*!< Extended Id */ -#define IS_CAN_IDTYPE(IDTYPE) (((IDTYPE) == CAN_ID_STD) || ((IDTYPE) == CAN_ID_EXT)) - -/** - * @} - */ - -/** @defgroup CAN_remote_transmission_request - * @{ - */ - -#define CAN_RTR_DATA ((uint32_t)0x00000000) /*!< Data frame */ -#define CAN_RTR_REMOTE ((uint32_t)0x00000002) /*!< Remote frame */ -#define IS_CAN_RTR(RTR) (((RTR) == CAN_RTR_DATA) || ((RTR) == CAN_RTR_REMOTE)) - -/** - * @} - */ - -/** @defgroup CAN_transmit_constants - * @{ - */ - -#define CANTXFAILED ((uint8_t)0x00) /*!< CAN transmission failed */ -#define CANTXOK ((uint8_t)0x01) /*!< CAN transmission succeeded */ -#define CANTXPENDING ((uint8_t)0x02) /*!< CAN transmission pending */ -#define CAN_NO_MB ((uint8_t)0x04) /*!< CAN cell did not provide an empty mailbox */ - -/** - * @} - */ - -/** @defgroup CAN_receive_FIFO_number_constants - * @{ - */ - -#define CAN_FIFO0 ((uint8_t)0x00) /*!< CAN FIFO0 used to receive */ -#define CAN_FIFO1 ((uint8_t)0x01) /*!< CAN FIFO1 used to receive */ - -#define IS_CAN_FIFO(FIFO) (((FIFO) == CAN_FIFO0) || ((FIFO) == CAN_FIFO1)) - -/** - * @} - */ - -/** @defgroup CAN_sleep_constants - * @{ - */ - -#define CANSLEEPFAILED ((uint8_t)0x00) /*!< CAN did not enter the sleep mode */ -#define CANSLEEPOK ((uint8_t)0x01) /*!< CAN entered the sleep mode */ - -/** - * @} - */ - -/** @defgroup CAN_wake_up_constants - * @{ - */ - -#define CANWAKEUPFAILED ((uint8_t)0x00) /*!< CAN did not leave the sleep mode */ -#define CANWAKEUPOK ((uint8_t)0x01) /*!< CAN leaved the sleep mode */ - -/** - * @} - */ - -/** @defgroup CAN_flags - * @{ - */ - -#define CAN_FLAG_EWG ((uint32_t)0x00000001) /*!< Error Warning Flag */ -#define CAN_FLAG_EPV ((uint32_t)0x00000002) /*!< Error Passive Flag */ -#define CAN_FLAG_BOF ((uint32_t)0x00000004) /*!< Bus-Off Flag */ - -#define IS_CAN_FLAG(FLAG) (((FLAG) == CAN_FLAG_EWG) || ((FLAG) == CAN_FLAG_EPV) ||\ - ((FLAG) == CAN_FLAG_BOF)) - -/** - * @} - */ - -/** @defgroup CAN_interrupts - * @{ - */ - -#define CAN_IT_RQCP0 ((uint32_t)0x00000005) /*!< Request completed mailbox 0 */ -#define CAN_IT_RQCP1 ((uint32_t)0x00000006) /*!< Request completed mailbox 1 */ -#define CAN_IT_RQCP2 ((uint32_t)0x00000007) /*!< Request completed mailbox 2 */ -#define CAN_IT_TME ((uint32_t)0x00000001) /*!< Transmit mailbox empty */ -#define CAN_IT_FMP0 ((uint32_t)0x00000002) /*!< FIFO 0 message pending */ -#define CAN_IT_FF0 ((uint32_t)0x00000004) /*!< FIFO 0 full */ -#define CAN_IT_FOV0 ((uint32_t)0x00000008) /*!< FIFO 0 overrun */ -#define CAN_IT_FMP1 ((uint32_t)0x00000010) /*!< FIFO 1 message pending */ -#define CAN_IT_FF1 ((uint32_t)0x00000020) /*!< FIFO 1 full */ -#define CAN_IT_FOV1 ((uint32_t)0x00000040) /*!< FIFO 1 overrun */ -#define CAN_IT_EWG ((uint32_t)0x00000100) /*!< Error warning */ -#define CAN_IT_EPV ((uint32_t)0x00000200) /*!< Error passive */ -#define CAN_IT_BOF ((uint32_t)0x00000400) /*!< Bus-off */ -#define CAN_IT_LEC ((uint32_t)0x00000800) /*!< Last error code */ -#define CAN_IT_ERR ((uint32_t)0x00008000) /*!< Error */ -#define CAN_IT_WKU ((uint32_t)0x00010000) /*!< Wake-up */ -#define CAN_IT_SLK ((uint32_t)0x00020000) /*!< Sleep */ - -#define IS_CAN_ITConfig(IT) (((IT) == CAN_IT_TME) || ((IT) == CAN_IT_FMP0) ||\ - ((IT) == CAN_IT_FF0) || ((IT) == CAN_IT_FOV0) ||\ - ((IT) == CAN_IT_FMP1) || ((IT) == CAN_IT_FF1) ||\ - ((IT) == CAN_IT_FOV1) || ((IT) == CAN_IT_EWG) ||\ - ((IT) == CAN_IT_EPV) || ((IT) == CAN_IT_BOF) ||\ - ((IT) == CAN_IT_LEC) || ((IT) == CAN_IT_ERR) ||\ - ((IT) == CAN_IT_WKU) || ((IT) == CAN_IT_SLK)) - -#define IS_CAN_ITStatus(IT) (((IT) == CAN_IT_RQCP0) || ((IT) == CAN_IT_RQCP1) ||\ - ((IT) == CAN_IT_RQCP2) || ((IT) == CAN_IT_FF0) ||\ - ((IT) == CAN_IT_FOV0) || ((IT) == CAN_IT_FF1) ||\ - ((IT) == CAN_IT_FOV1) || ((IT) == CAN_IT_EWG) ||\ - ((IT) == CAN_IT_EPV) || ((IT) == CAN_IT_BOF) ||\ - ((IT) == CAN_IT_WKU) || ((IT) == CAN_IT_SLK)) -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup CAN_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup CAN_Exported_Functions - * @{ - */ - -void CAN_DeInit(CAN_TypeDef* CANx); -uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct); -void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct); -void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct); -void CAN_SlaveStartBank(uint8_t CAN_BankNumber); -void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState); -uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage); -uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox); -void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox); -void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber); -uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber); -void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage); -void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState); -uint8_t CAN_Sleep(CAN_TypeDef* CANx); -uint8_t CAN_WakeUp(CAN_TypeDef* CANx); -FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG); -void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG); -ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT); -void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_CAN_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_cec.h b/example/libs_stm/inc/stm32f10x/stm32f10x_cec.h deleted file mode 100644 index 233a0944f..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_cec.h +++ /dev/null @@ -1,209 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_cec.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the CEC firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_CEC_H -#define __STM32F10x_CEC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup CEC - * @{ - */ - - -/** @defgroup CEC_Exported_Types - * @{ - */ - -/** - * @brief CEC Init structure definition - */ -typedef struct -{ - uint16_t CEC_BitTimingMode; /*!< Configures the CEC Bit Timing Error Mode. - This parameter can be a value of @ref CEC_BitTiming_Mode */ - uint16_t CEC_BitPeriodMode; /*!< Configures the CEC Bit Period Error Mode. - This parameter can be a value of @ref CEC_BitPeriod_Mode */ -}CEC_InitTypeDef; - -/** - * @} - */ - -/** @defgroup CEC_Exported_Constants - * @{ - */ - -/** @defgroup CEC_BitTiming_Mode - * @{ - */ -#define CEC_BitTimingStdMode ((uint16_t)0x00) /*!< Bit timing error Standard Mode */ -#define CEC_BitTimingErrFreeMode CEC_CFGR_BTEM /*!< Bit timing error Free Mode */ - -#define IS_CEC_BIT_TIMING_ERROR_MODE(MODE) (((MODE) == CEC_BitTimingStdMode) || \ - ((MODE) == CEC_BitTimingErrFreeMode)) -/** - * @} - */ - -/** @defgroup CEC_BitPeriod_Mode - * @{ - */ -#define CEC_BitPeriodStdMode ((uint16_t)0x00) /*!< Bit period error Standard Mode */ -#define CEC_BitPeriodFlexibleMode CEC_CFGR_BPEM /*!< Bit period error Flexible Mode */ - -#define IS_CEC_BIT_PERIOD_ERROR_MODE(MODE) (((MODE) == CEC_BitPeriodStdMode) || \ - ((MODE) == CEC_BitPeriodFlexibleMode)) -/** - * @} - */ - - -/** @defgroup CEC_interrupts_definition - * @{ - */ -#define CEC_IT_TERR CEC_CSR_TERR -#define CEC_IT_TBTRF CEC_CSR_TBTRF -#define CEC_IT_RERR CEC_CSR_RERR -#define CEC_IT_RBTF CEC_CSR_RBTF -#define IS_CEC_GET_IT(IT) (((IT) == CEC_IT_TERR) || ((IT) == CEC_IT_TBTRF) || \ - ((IT) == CEC_IT_RERR) || ((IT) == CEC_IT_RBTF)) -/** - * @} - */ - - -/** @defgroup CEC_Own_Addres - * @{ - */ -#define IS_CEC_ADDRESS(ADDRESS) ((ADDRESS) < 0x10) -/** - * @} - */ - -/** @defgroup CEC_Prescaler - * @{ - */ -#define IS_CEC_PRESCALER(PRESCALER) ((PRESCALER) <= 0x3FFF) - -/** - * @} - */ - -/** @defgroup CEC_flags_definition - * @{ - */ - -/** - * @brief ESR register flags - */ -#define CEC_FLAG_BTE ((uint32_t)0x10010000) -#define CEC_FLAG_BPE ((uint32_t)0x10020000) -#define CEC_FLAG_RBTFE ((uint32_t)0x10040000) -#define CEC_FLAG_SBE ((uint32_t)0x10080000) -#define CEC_FLAG_ACKE ((uint32_t)0x10100000) -#define CEC_FLAG_LINE ((uint32_t)0x10200000) -#define CEC_FLAG_TBTFE ((uint32_t)0x10400000) - -/** - * @brief CSR register flags - */ -#define CEC_FLAG_TEOM ((uint32_t)0x00000002) -#define CEC_FLAG_TERR ((uint32_t)0x00000004) -#define CEC_FLAG_TBTRF ((uint32_t)0x00000008) -#define CEC_FLAG_RSOM ((uint32_t)0x00000010) -#define CEC_FLAG_REOM ((uint32_t)0x00000020) -#define CEC_FLAG_RERR ((uint32_t)0x00000040) -#define CEC_FLAG_RBTF ((uint32_t)0x00000080) - -#define IS_CEC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFF03) == 0x00) && ((FLAG) != 0x00)) - -#define IS_CEC_GET_FLAG(FLAG) (((FLAG) == CEC_FLAG_BTE) || ((FLAG) == CEC_FLAG_BPE) || \ - ((FLAG) == CEC_FLAG_RBTFE) || ((FLAG)== CEC_FLAG_SBE) || \ - ((FLAG) == CEC_FLAG_ACKE) || ((FLAG) == CEC_FLAG_LINE) || \ - ((FLAG) == CEC_FLAG_TBTFE) || ((FLAG) == CEC_FLAG_TEOM) || \ - ((FLAG) == CEC_FLAG_TERR) || ((FLAG) == CEC_FLAG_TBTRF) || \ - ((FLAG) == CEC_FLAG_RSOM) || ((FLAG) == CEC_FLAG_REOM) || \ - ((FLAG) == CEC_FLAG_RERR) || ((FLAG) == CEC_FLAG_RBTF)) - -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup CEC_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup CEC_Exported_Functions - * @{ - */ -void CEC_DeInit(void); -void CEC_Init(CEC_InitTypeDef* CEC_InitStruct); -void CEC_Cmd(FunctionalState NewState); -void CEC_ITConfig(FunctionalState NewState); -void CEC_OwnAddressConfig(uint8_t CEC_OwnAddress); -void CEC_SetPrescaler(uint16_t CEC_Prescaler); -void CEC_SendDataByte(uint8_t Data); -uint8_t CEC_ReceiveDataByte(void); -void CEC_StartOfMessage(void); -void CEC_EndOfMessageCmd(FunctionalState NewState); -FlagStatus CEC_GetFlagStatus(uint32_t CEC_FLAG); -void CEC_ClearFlag(uint32_t CEC_FLAG); -ITStatus CEC_GetITStatus(uint8_t CEC_IT); -void CEC_ClearITPendingBit(uint16_t CEC_IT); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_CEC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_crc.h b/example/libs_stm/inc/stm32f10x/stm32f10x_crc.h deleted file mode 100644 index f7b2678c3..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_crc.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_crc.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the CRC firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_CRC_H -#define __STM32F10x_CRC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup CRC - * @{ - */ - -/** @defgroup CRC_Exported_Types - * @{ - */ - -/** - * @} - */ - -/** @defgroup CRC_Exported_Constants - * @{ - */ - -/** - * @} - */ - -/** @defgroup CRC_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup CRC_Exported_Functions - * @{ - */ - -void CRC_ResetDR(void); -uint32_t CRC_CalcCRC(uint32_t Data); -uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength); -uint32_t CRC_GetCRC(void); -void CRC_SetIDRegister(uint8_t IDValue); -uint8_t CRC_GetIDRegister(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_CRC_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_dac.h b/example/libs_stm/inc/stm32f10x/stm32f10x_dac.h deleted file mode 100644 index 16afbce49..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_dac.h +++ /dev/null @@ -1,316 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_dac.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the DAC firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_DAC_H -#define __STM32F10x_DAC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup DAC - * @{ - */ - -/** @defgroup DAC_Exported_Types - * @{ - */ - -/** - * @brief DAC Init structure definition - */ - -typedef struct -{ - uint32_t DAC_Trigger; /*!< Specifies the external trigger for the selected DAC channel. - This parameter can be a value of @ref DAC_trigger_selection */ - - uint32_t DAC_WaveGeneration; /*!< Specifies whether DAC channel noise waves or triangle waves - are generated, or whether no wave is generated. - This parameter can be a value of @ref DAC_wave_generation */ - - uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*!< Specifies the LFSR mask for noise wave generation or - the maximum amplitude triangle generation for the DAC channel. - This parameter can be a value of @ref DAC_lfsrunmask_triangleamplitude */ - - uint32_t DAC_OutputBuffer; /*!< Specifies whether the DAC channel output buffer is enabled or disabled. - This parameter can be a value of @ref DAC_output_buffer */ -}DAC_InitTypeDef; - -/** - * @} - */ - -/** @defgroup DAC_Exported_Constants - * @{ - */ - -/** @defgroup DAC_trigger_selection - * @{ - */ - -#define DAC_Trigger_None ((uint32_t)0x00000000) /*!< Conversion is automatic once the DAC1_DHRxxxx register - has been loaded, and not by external trigger */ -#define DAC_Trigger_T6_TRGO ((uint32_t)0x00000004) /*!< TIM6 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_T8_TRGO ((uint32_t)0x0000000C) /*!< TIM8 TRGO selected as external conversion trigger for DAC channel - only in High-density devices*/ -#define DAC_Trigger_T3_TRGO ((uint32_t)0x0000000C) /*!< TIM8 TRGO selected as external conversion trigger for DAC channel - only in Connectivity line, Medium-density and Low-density Value Line devices */ -#define DAC_Trigger_T7_TRGO ((uint32_t)0x00000014) /*!< TIM7 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_T5_TRGO ((uint32_t)0x0000001C) /*!< TIM5 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_T15_TRGO ((uint32_t)0x0000001C) /*!< TIM15 TRGO selected as external conversion trigger for DAC channel - only in Medium-density and Low-density Value Line devices*/ -#define DAC_Trigger_T2_TRGO ((uint32_t)0x00000024) /*!< TIM2 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_T4_TRGO ((uint32_t)0x0000002C) /*!< TIM4 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_Ext_IT9 ((uint32_t)0x00000034) /*!< EXTI Line9 event selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_Software ((uint32_t)0x0000003C) /*!< Conversion started by software trigger for DAC channel */ - -#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_Trigger_None) || \ - ((TRIGGER) == DAC_Trigger_T6_TRGO) || \ - ((TRIGGER) == DAC_Trigger_T8_TRGO) || \ - ((TRIGGER) == DAC_Trigger_T7_TRGO) || \ - ((TRIGGER) == DAC_Trigger_T5_TRGO) || \ - ((TRIGGER) == DAC_Trigger_T2_TRGO) || \ - ((TRIGGER) == DAC_Trigger_T4_TRGO) || \ - ((TRIGGER) == DAC_Trigger_Ext_IT9) || \ - ((TRIGGER) == DAC_Trigger_Software)) - -/** - * @} - */ - -/** @defgroup DAC_wave_generation - * @{ - */ - -#define DAC_WaveGeneration_None ((uint32_t)0x00000000) -#define DAC_WaveGeneration_Noise ((uint32_t)0x00000040) -#define DAC_WaveGeneration_Triangle ((uint32_t)0x00000080) -#define IS_DAC_GENERATE_WAVE(WAVE) (((WAVE) == DAC_WaveGeneration_None) || \ - ((WAVE) == DAC_WaveGeneration_Noise) || \ - ((WAVE) == DAC_WaveGeneration_Triangle)) -/** - * @} - */ - -/** @defgroup DAC_lfsrunmask_triangleamplitude - * @{ - */ - -#define DAC_LFSRUnmask_Bit0 ((uint32_t)0x00000000) /*!< Unmask DAC channel LFSR bit0 for noise wave generation */ -#define DAC_LFSRUnmask_Bits1_0 ((uint32_t)0x00000100) /*!< Unmask DAC channel LFSR bit[1:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits2_0 ((uint32_t)0x00000200) /*!< Unmask DAC channel LFSR bit[2:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits3_0 ((uint32_t)0x00000300) /*!< Unmask DAC channel LFSR bit[3:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits4_0 ((uint32_t)0x00000400) /*!< Unmask DAC channel LFSR bit[4:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits5_0 ((uint32_t)0x00000500) /*!< Unmask DAC channel LFSR bit[5:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits6_0 ((uint32_t)0x00000600) /*!< Unmask DAC channel LFSR bit[6:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits7_0 ((uint32_t)0x00000700) /*!< Unmask DAC channel LFSR bit[7:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits8_0 ((uint32_t)0x00000800) /*!< Unmask DAC channel LFSR bit[8:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits9_0 ((uint32_t)0x00000900) /*!< Unmask DAC channel LFSR bit[9:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits10_0 ((uint32_t)0x00000A00) /*!< Unmask DAC channel LFSR bit[10:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits11_0 ((uint32_t)0x00000B00) /*!< Unmask DAC channel LFSR bit[11:0] for noise wave generation */ -#define DAC_TriangleAmplitude_1 ((uint32_t)0x00000000) /*!< Select max triangle amplitude of 1 */ -#define DAC_TriangleAmplitude_3 ((uint32_t)0x00000100) /*!< Select max triangle amplitude of 3 */ -#define DAC_TriangleAmplitude_7 ((uint32_t)0x00000200) /*!< Select max triangle amplitude of 7 */ -#define DAC_TriangleAmplitude_15 ((uint32_t)0x00000300) /*!< Select max triangle amplitude of 15 */ -#define DAC_TriangleAmplitude_31 ((uint32_t)0x00000400) /*!< Select max triangle amplitude of 31 */ -#define DAC_TriangleAmplitude_63 ((uint32_t)0x00000500) /*!< Select max triangle amplitude of 63 */ -#define DAC_TriangleAmplitude_127 ((uint32_t)0x00000600) /*!< Select max triangle amplitude of 127 */ -#define DAC_TriangleAmplitude_255 ((uint32_t)0x00000700) /*!< Select max triangle amplitude of 255 */ -#define DAC_TriangleAmplitude_511 ((uint32_t)0x00000800) /*!< Select max triangle amplitude of 511 */ -#define DAC_TriangleAmplitude_1023 ((uint32_t)0x00000900) /*!< Select max triangle amplitude of 1023 */ -#define DAC_TriangleAmplitude_2047 ((uint32_t)0x00000A00) /*!< Select max triangle amplitude of 2047 */ -#define DAC_TriangleAmplitude_4095 ((uint32_t)0x00000B00) /*!< Select max triangle amplitude of 4095 */ - -#define IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(VALUE) (((VALUE) == DAC_LFSRUnmask_Bit0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits1_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits2_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits3_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits4_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits5_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits6_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits7_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits8_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits9_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits10_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits11_0) || \ - ((VALUE) == DAC_TriangleAmplitude_1) || \ - ((VALUE) == DAC_TriangleAmplitude_3) || \ - ((VALUE) == DAC_TriangleAmplitude_7) || \ - ((VALUE) == DAC_TriangleAmplitude_15) || \ - ((VALUE) == DAC_TriangleAmplitude_31) || \ - ((VALUE) == DAC_TriangleAmplitude_63) || \ - ((VALUE) == DAC_TriangleAmplitude_127) || \ - ((VALUE) == DAC_TriangleAmplitude_255) || \ - ((VALUE) == DAC_TriangleAmplitude_511) || \ - ((VALUE) == DAC_TriangleAmplitude_1023) || \ - ((VALUE) == DAC_TriangleAmplitude_2047) || \ - ((VALUE) == DAC_TriangleAmplitude_4095)) -/** - * @} - */ - -/** @defgroup DAC_output_buffer - * @{ - */ - -#define DAC_OutputBuffer_Enable ((uint32_t)0x00000000) -#define DAC_OutputBuffer_Disable ((uint32_t)0x00000002) -#define IS_DAC_OUTPUT_BUFFER_STATE(STATE) (((STATE) == DAC_OutputBuffer_Enable) || \ - ((STATE) == DAC_OutputBuffer_Disable)) -/** - * @} - */ - -/** @defgroup DAC_Channel_selection - * @{ - */ - -#define DAC_Channel_1 ((uint32_t)0x00000000) -#define DAC_Channel_2 ((uint32_t)0x00000010) -#define IS_DAC_CHANNEL(CHANNEL) (((CHANNEL) == DAC_Channel_1) || \ - ((CHANNEL) == DAC_Channel_2)) -/** - * @} - */ - -/** @defgroup DAC_data_alignement - * @{ - */ - -#define DAC_Align_12b_R ((uint32_t)0x00000000) -#define DAC_Align_12b_L ((uint32_t)0x00000004) -#define DAC_Align_8b_R ((uint32_t)0x00000008) -#define IS_DAC_ALIGN(ALIGN) (((ALIGN) == DAC_Align_12b_R) || \ - ((ALIGN) == DAC_Align_12b_L) || \ - ((ALIGN) == DAC_Align_8b_R)) -/** - * @} - */ - -/** @defgroup DAC_wave_generation - * @{ - */ - -#define DAC_Wave_Noise ((uint32_t)0x00000040) -#define DAC_Wave_Triangle ((uint32_t)0x00000080) -#define IS_DAC_WAVE(WAVE) (((WAVE) == DAC_Wave_Noise) || \ - ((WAVE) == DAC_Wave_Triangle)) -/** - * @} - */ - -/** @defgroup DAC_data - * @{ - */ - -#define IS_DAC_DATA(DATA) ((DATA) <= 0xFFF0) -/** - * @} - */ -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) -/** @defgroup DAC_interrupts_definition - * @{ - */ - -#define DAC_IT_DMAUDR ((uint32_t)0x00002000) -#define IS_DAC_IT(IT) (((IT) == DAC_IT_DMAUDR)) - -/** - * @} - */ - -/** @defgroup DAC_flags_definition - * @{ - */ - -#define DAC_FLAG_DMAUDR ((uint32_t)0x00002000) -#define IS_DAC_FLAG(FLAG) (((FLAG) == DAC_FLAG_DMAUDR)) - -/** - * @} - */ -#endif - -/** - * @} - */ - -/** @defgroup DAC_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup DAC_Exported_Functions - * @{ - */ - -void DAC_DeInit(void); -void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct); -void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct); -void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState); -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) -void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState); -#endif -void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState); -void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState); -void DAC_DualSoftwareTriggerCmd(FunctionalState NewState); -void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState); -void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data); -void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data); -void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1); -uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel); -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) -FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG); -void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG); -ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT); -void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F10x_DAC_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_dbgmcu.h b/example/libs_stm/inc/stm32f10x/stm32f10x_dbgmcu.h deleted file mode 100644 index 5a78f7355..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_dbgmcu.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_dbgmcu.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the DBGMCU - * firmware library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_DBGMCU_H -#define __STM32F10x_DBGMCU_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup DBGMCU - * @{ - */ - -/** @defgroup DBGMCU_Exported_Types - * @{ - */ - -/** - * @} - */ - -/** @defgroup DBGMCU_Exported_Constants - * @{ - */ - -#define DBGMCU_SLEEP ((uint32_t)0x00000001) -#define DBGMCU_STOP ((uint32_t)0x00000002) -#define DBGMCU_STANDBY ((uint32_t)0x00000004) -#define DBGMCU_IWDG_STOP ((uint32_t)0x00000100) -#define DBGMCU_WWDG_STOP ((uint32_t)0x00000200) -#define DBGMCU_TIM1_STOP ((uint32_t)0x00000400) -#define DBGMCU_TIM2_STOP ((uint32_t)0x00000800) -#define DBGMCU_TIM3_STOP ((uint32_t)0x00001000) -#define DBGMCU_TIM4_STOP ((uint32_t)0x00002000) -#define DBGMCU_CAN1_STOP ((uint32_t)0x00004000) -#define DBGMCU_I2C1_SMBUS_TIMEOUT ((uint32_t)0x00008000) -#define DBGMCU_I2C2_SMBUS_TIMEOUT ((uint32_t)0x00010000) -#define DBGMCU_TIM8_STOP ((uint32_t)0x00020000) -#define DBGMCU_TIM5_STOP ((uint32_t)0x00040000) -#define DBGMCU_TIM6_STOP ((uint32_t)0x00080000) -#define DBGMCU_TIM7_STOP ((uint32_t)0x00100000) -#define DBGMCU_CAN2_STOP ((uint32_t)0x00200000) -#define DBGMCU_TIM15_STOP ((uint32_t)0x00400000) -#define DBGMCU_TIM16_STOP ((uint32_t)0x00800000) -#define DBGMCU_TIM17_STOP ((uint32_t)0x01000000) -#define DBGMCU_TIM12_STOP ((uint32_t)0x02000000) -#define DBGMCU_TIM13_STOP ((uint32_t)0x04000000) -#define DBGMCU_TIM14_STOP ((uint32_t)0x08000000) -#define DBGMCU_TIM9_STOP ((uint32_t)0x10000000) -#define DBGMCU_TIM10_STOP ((uint32_t)0x20000000) -#define DBGMCU_TIM11_STOP ((uint32_t)0x40000000) - -#define IS_DBGMCU_PERIPH(PERIPH) ((((PERIPH) & 0x800000F8) == 0x00) && ((PERIPH) != 0x00)) -/** - * @} - */ - -/** @defgroup DBGMCU_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup DBGMCU_Exported_Functions - * @{ - */ - -uint32_t DBGMCU_GetREVID(void); -uint32_t DBGMCU_GetDEVID(void); -void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_DBGMCU_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_dma.h b/example/libs_stm/inc/stm32f10x/stm32f10x_dma.h deleted file mode 100644 index 35769abc6..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_dma.h +++ /dev/null @@ -1,437 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_dma.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the DMA firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_DMA_H -#define __STM32F10x_DMA_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup DMA - * @{ - */ - -/** @defgroup DMA_Exported_Types - * @{ - */ - -/** - * @brief DMA Init structure definition - */ - -typedef struct -{ - uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Channelx. */ - - uint32_t DMA_MemoryBaseAddr; /*!< Specifies the memory base address for DMAy Channelx. */ - - uint32_t DMA_DIR; /*!< Specifies if the peripheral is the source or destination. - This parameter can be a value of @ref DMA_data_transfer_direction */ - - uint32_t DMA_BufferSize; /*!< Specifies the buffer size, in data unit, of the specified Channel. - The data unit is equal to the configuration set in DMA_PeripheralDataSize - or DMA_MemoryDataSize members depending in the transfer direction. */ - - uint32_t DMA_PeripheralInc; /*!< Specifies whether the Peripheral address register is incremented or not. - This parameter can be a value of @ref DMA_peripheral_incremented_mode */ - - uint32_t DMA_MemoryInc; /*!< Specifies whether the memory address register is incremented or not. - This parameter can be a value of @ref DMA_memory_incremented_mode */ - - uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width. - This parameter can be a value of @ref DMA_peripheral_data_size */ - - uint32_t DMA_MemoryDataSize; /*!< Specifies the Memory data width. - This parameter can be a value of @ref DMA_memory_data_size */ - - uint32_t DMA_Mode; /*!< Specifies the operation mode of the DMAy Channelx. - This parameter can be a value of @ref DMA_circular_normal_mode. - @note: The circular buffer mode cannot be used if the memory-to-memory - data transfer is configured on the selected Channel */ - - uint32_t DMA_Priority; /*!< Specifies the software priority for the DMAy Channelx. - This parameter can be a value of @ref DMA_priority_level */ - - uint32_t DMA_M2M; /*!< Specifies if the DMAy Channelx will be used in memory-to-memory transfer. - This parameter can be a value of @ref DMA_memory_to_memory */ -}DMA_InitTypeDef; - -/** - * @} - */ - -/** @defgroup DMA_Exported_Constants - * @{ - */ - -#define IS_DMA_ALL_PERIPH(PERIPH) (((PERIPH) == DMA1_Channel1) || \ - ((PERIPH) == DMA1_Channel2) || \ - ((PERIPH) == DMA1_Channel3) || \ - ((PERIPH) == DMA1_Channel4) || \ - ((PERIPH) == DMA1_Channel5) || \ - ((PERIPH) == DMA1_Channel6) || \ - ((PERIPH) == DMA1_Channel7) || \ - ((PERIPH) == DMA2_Channel1) || \ - ((PERIPH) == DMA2_Channel2) || \ - ((PERIPH) == DMA2_Channel3) || \ - ((PERIPH) == DMA2_Channel4) || \ - ((PERIPH) == DMA2_Channel5)) - -/** @defgroup DMA_data_transfer_direction - * @{ - */ - -#define DMA_DIR_PeripheralDST ((uint32_t)0x00000010) -#define DMA_DIR_PeripheralSRC ((uint32_t)0x00000000) -#define IS_DMA_DIR(DIR) (((DIR) == DMA_DIR_PeripheralDST) || \ - ((DIR) == DMA_DIR_PeripheralSRC)) -/** - * @} - */ - -/** @defgroup DMA_peripheral_incremented_mode - * @{ - */ - -#define DMA_PeripheralInc_Enable ((uint32_t)0x00000040) -#define DMA_PeripheralInc_Disable ((uint32_t)0x00000000) -#define IS_DMA_PERIPHERAL_INC_STATE(STATE) (((STATE) == DMA_PeripheralInc_Enable) || \ - ((STATE) == DMA_PeripheralInc_Disable)) -/** - * @} - */ - -/** @defgroup DMA_memory_incremented_mode - * @{ - */ - -#define DMA_MemoryInc_Enable ((uint32_t)0x00000080) -#define DMA_MemoryInc_Disable ((uint32_t)0x00000000) -#define IS_DMA_MEMORY_INC_STATE(STATE) (((STATE) == DMA_MemoryInc_Enable) || \ - ((STATE) == DMA_MemoryInc_Disable)) -/** - * @} - */ - -/** @defgroup DMA_peripheral_data_size - * @{ - */ - -#define DMA_PeripheralDataSize_Byte ((uint32_t)0x00000000) -#define DMA_PeripheralDataSize_HalfWord ((uint32_t)0x00000100) -#define DMA_PeripheralDataSize_Word ((uint32_t)0x00000200) -#define IS_DMA_PERIPHERAL_DATA_SIZE(SIZE) (((SIZE) == DMA_PeripheralDataSize_Byte) || \ - ((SIZE) == DMA_PeripheralDataSize_HalfWord) || \ - ((SIZE) == DMA_PeripheralDataSize_Word)) -/** - * @} - */ - -/** @defgroup DMA_memory_data_size - * @{ - */ - -#define DMA_MemoryDataSize_Byte ((uint32_t)0x00000000) -#define DMA_MemoryDataSize_HalfWord ((uint32_t)0x00000400) -#define DMA_MemoryDataSize_Word ((uint32_t)0x00000800) -#define IS_DMA_MEMORY_DATA_SIZE(SIZE) (((SIZE) == DMA_MemoryDataSize_Byte) || \ - ((SIZE) == DMA_MemoryDataSize_HalfWord) || \ - ((SIZE) == DMA_MemoryDataSize_Word)) -/** - * @} - */ - -/** @defgroup DMA_circular_normal_mode - * @{ - */ - -#define DMA_Mode_Circular ((uint32_t)0x00000020) -#define DMA_Mode_Normal ((uint32_t)0x00000000) -#define IS_DMA_MODE(MODE) (((MODE) == DMA_Mode_Circular) || ((MODE) == DMA_Mode_Normal)) -/** - * @} - */ - -/** @defgroup DMA_priority_level - * @{ - */ - -#define DMA_Priority_VeryHigh ((uint32_t)0x00003000) -#define DMA_Priority_High ((uint32_t)0x00002000) -#define DMA_Priority_Medium ((uint32_t)0x00001000) -#define DMA_Priority_Low ((uint32_t)0x00000000) -#define IS_DMA_PRIORITY(PRIORITY) (((PRIORITY) == DMA_Priority_VeryHigh) || \ - ((PRIORITY) == DMA_Priority_High) || \ - ((PRIORITY) == DMA_Priority_Medium) || \ - ((PRIORITY) == DMA_Priority_Low)) -/** - * @} - */ - -/** @defgroup DMA_memory_to_memory - * @{ - */ - -#define DMA_M2M_Enable ((uint32_t)0x00004000) -#define DMA_M2M_Disable ((uint32_t)0x00000000) -#define IS_DMA_M2M_STATE(STATE) (((STATE) == DMA_M2M_Enable) || ((STATE) == DMA_M2M_Disable)) - -/** - * @} - */ - -/** @defgroup DMA_interrupts_definition - * @{ - */ - -#define DMA_IT_TC ((uint32_t)0x00000002) -#define DMA_IT_HT ((uint32_t)0x00000004) -#define DMA_IT_TE ((uint32_t)0x00000008) -#define IS_DMA_CONFIG_IT(IT) ((((IT) & 0xFFFFFFF1) == 0x00) && ((IT) != 0x00)) - -#define DMA1_IT_GL1 ((uint32_t)0x00000001) -#define DMA1_IT_TC1 ((uint32_t)0x00000002) -#define DMA1_IT_HT1 ((uint32_t)0x00000004) -#define DMA1_IT_TE1 ((uint32_t)0x00000008) -#define DMA1_IT_GL2 ((uint32_t)0x00000010) -#define DMA1_IT_TC2 ((uint32_t)0x00000020) -#define DMA1_IT_HT2 ((uint32_t)0x00000040) -#define DMA1_IT_TE2 ((uint32_t)0x00000080) -#define DMA1_IT_GL3 ((uint32_t)0x00000100) -#define DMA1_IT_TC3 ((uint32_t)0x00000200) -#define DMA1_IT_HT3 ((uint32_t)0x00000400) -#define DMA1_IT_TE3 ((uint32_t)0x00000800) -#define DMA1_IT_GL4 ((uint32_t)0x00001000) -#define DMA1_IT_TC4 ((uint32_t)0x00002000) -#define DMA1_IT_HT4 ((uint32_t)0x00004000) -#define DMA1_IT_TE4 ((uint32_t)0x00008000) -#define DMA1_IT_GL5 ((uint32_t)0x00010000) -#define DMA1_IT_TC5 ((uint32_t)0x00020000) -#define DMA1_IT_HT5 ((uint32_t)0x00040000) -#define DMA1_IT_TE5 ((uint32_t)0x00080000) -#define DMA1_IT_GL6 ((uint32_t)0x00100000) -#define DMA1_IT_TC6 ((uint32_t)0x00200000) -#define DMA1_IT_HT6 ((uint32_t)0x00400000) -#define DMA1_IT_TE6 ((uint32_t)0x00800000) -#define DMA1_IT_GL7 ((uint32_t)0x01000000) -#define DMA1_IT_TC7 ((uint32_t)0x02000000) -#define DMA1_IT_HT7 ((uint32_t)0x04000000) -#define DMA1_IT_TE7 ((uint32_t)0x08000000) - -#define DMA2_IT_GL1 ((uint32_t)0x10000001) -#define DMA2_IT_TC1 ((uint32_t)0x10000002) -#define DMA2_IT_HT1 ((uint32_t)0x10000004) -#define DMA2_IT_TE1 ((uint32_t)0x10000008) -#define DMA2_IT_GL2 ((uint32_t)0x10000010) -#define DMA2_IT_TC2 ((uint32_t)0x10000020) -#define DMA2_IT_HT2 ((uint32_t)0x10000040) -#define DMA2_IT_TE2 ((uint32_t)0x10000080) -#define DMA2_IT_GL3 ((uint32_t)0x10000100) -#define DMA2_IT_TC3 ((uint32_t)0x10000200) -#define DMA2_IT_HT3 ((uint32_t)0x10000400) -#define DMA2_IT_TE3 ((uint32_t)0x10000800) -#define DMA2_IT_GL4 ((uint32_t)0x10001000) -#define DMA2_IT_TC4 ((uint32_t)0x10002000) -#define DMA2_IT_HT4 ((uint32_t)0x10004000) -#define DMA2_IT_TE4 ((uint32_t)0x10008000) -#define DMA2_IT_GL5 ((uint32_t)0x10010000) -#define DMA2_IT_TC5 ((uint32_t)0x10020000) -#define DMA2_IT_HT5 ((uint32_t)0x10040000) -#define DMA2_IT_TE5 ((uint32_t)0x10080000) - -#define IS_DMA_CLEAR_IT(IT) (((((IT) & 0xF0000000) == 0x00) || (((IT) & 0xEFF00000) == 0x00)) && ((IT) != 0x00)) - -#define IS_DMA_GET_IT(IT) (((IT) == DMA1_IT_GL1) || ((IT) == DMA1_IT_TC1) || \ - ((IT) == DMA1_IT_HT1) || ((IT) == DMA1_IT_TE1) || \ - ((IT) == DMA1_IT_GL2) || ((IT) == DMA1_IT_TC2) || \ - ((IT) == DMA1_IT_HT2) || ((IT) == DMA1_IT_TE2) || \ - ((IT) == DMA1_IT_GL3) || ((IT) == DMA1_IT_TC3) || \ - ((IT) == DMA1_IT_HT3) || ((IT) == DMA1_IT_TE3) || \ - ((IT) == DMA1_IT_GL4) || ((IT) == DMA1_IT_TC4) || \ - ((IT) == DMA1_IT_HT4) || ((IT) == DMA1_IT_TE4) || \ - ((IT) == DMA1_IT_GL5) || ((IT) == DMA1_IT_TC5) || \ - ((IT) == DMA1_IT_HT5) || ((IT) == DMA1_IT_TE5) || \ - ((IT) == DMA1_IT_GL6) || ((IT) == DMA1_IT_TC6) || \ - ((IT) == DMA1_IT_HT6) || ((IT) == DMA1_IT_TE6) || \ - ((IT) == DMA1_IT_GL7) || ((IT) == DMA1_IT_TC7) || \ - ((IT) == DMA1_IT_HT7) || ((IT) == DMA1_IT_TE7) || \ - ((IT) == DMA2_IT_GL1) || ((IT) == DMA2_IT_TC1) || \ - ((IT) == DMA2_IT_HT1) || ((IT) == DMA2_IT_TE1) || \ - ((IT) == DMA2_IT_GL2) || ((IT) == DMA2_IT_TC2) || \ - ((IT) == DMA2_IT_HT2) || ((IT) == DMA2_IT_TE2) || \ - ((IT) == DMA2_IT_GL3) || ((IT) == DMA2_IT_TC3) || \ - ((IT) == DMA2_IT_HT3) || ((IT) == DMA2_IT_TE3) || \ - ((IT) == DMA2_IT_GL4) || ((IT) == DMA2_IT_TC4) || \ - ((IT) == DMA2_IT_HT4) || ((IT) == DMA2_IT_TE4) || \ - ((IT) == DMA2_IT_GL5) || ((IT) == DMA2_IT_TC5) || \ - ((IT) == DMA2_IT_HT5) || ((IT) == DMA2_IT_TE5)) - -/** - * @} - */ - -/** @defgroup DMA_flags_definition - * @{ - */ -#define DMA1_FLAG_GL1 ((uint32_t)0x00000001) -#define DMA1_FLAG_TC1 ((uint32_t)0x00000002) -#define DMA1_FLAG_HT1 ((uint32_t)0x00000004) -#define DMA1_FLAG_TE1 ((uint32_t)0x00000008) -#define DMA1_FLAG_GL2 ((uint32_t)0x00000010) -#define DMA1_FLAG_TC2 ((uint32_t)0x00000020) -#define DMA1_FLAG_HT2 ((uint32_t)0x00000040) -#define DMA1_FLAG_TE2 ((uint32_t)0x00000080) -#define DMA1_FLAG_GL3 ((uint32_t)0x00000100) -#define DMA1_FLAG_TC3 ((uint32_t)0x00000200) -#define DMA1_FLAG_HT3 ((uint32_t)0x00000400) -#define DMA1_FLAG_TE3 ((uint32_t)0x00000800) -#define DMA1_FLAG_GL4 ((uint32_t)0x00001000) -#define DMA1_FLAG_TC4 ((uint32_t)0x00002000) -#define DMA1_FLAG_HT4 ((uint32_t)0x00004000) -#define DMA1_FLAG_TE4 ((uint32_t)0x00008000) -#define DMA1_FLAG_GL5 ((uint32_t)0x00010000) -#define DMA1_FLAG_TC5 ((uint32_t)0x00020000) -#define DMA1_FLAG_HT5 ((uint32_t)0x00040000) -#define DMA1_FLAG_TE5 ((uint32_t)0x00080000) -#define DMA1_FLAG_GL6 ((uint32_t)0x00100000) -#define DMA1_FLAG_TC6 ((uint32_t)0x00200000) -#define DMA1_FLAG_HT6 ((uint32_t)0x00400000) -#define DMA1_FLAG_TE6 ((uint32_t)0x00800000) -#define DMA1_FLAG_GL7 ((uint32_t)0x01000000) -#define DMA1_FLAG_TC7 ((uint32_t)0x02000000) -#define DMA1_FLAG_HT7 ((uint32_t)0x04000000) -#define DMA1_FLAG_TE7 ((uint32_t)0x08000000) - -#define DMA2_FLAG_GL1 ((uint32_t)0x10000001) -#define DMA2_FLAG_TC1 ((uint32_t)0x10000002) -#define DMA2_FLAG_HT1 ((uint32_t)0x10000004) -#define DMA2_FLAG_TE1 ((uint32_t)0x10000008) -#define DMA2_FLAG_GL2 ((uint32_t)0x10000010) -#define DMA2_FLAG_TC2 ((uint32_t)0x10000020) -#define DMA2_FLAG_HT2 ((uint32_t)0x10000040) -#define DMA2_FLAG_TE2 ((uint32_t)0x10000080) -#define DMA2_FLAG_GL3 ((uint32_t)0x10000100) -#define DMA2_FLAG_TC3 ((uint32_t)0x10000200) -#define DMA2_FLAG_HT3 ((uint32_t)0x10000400) -#define DMA2_FLAG_TE3 ((uint32_t)0x10000800) -#define DMA2_FLAG_GL4 ((uint32_t)0x10001000) -#define DMA2_FLAG_TC4 ((uint32_t)0x10002000) -#define DMA2_FLAG_HT4 ((uint32_t)0x10004000) -#define DMA2_FLAG_TE4 ((uint32_t)0x10008000) -#define DMA2_FLAG_GL5 ((uint32_t)0x10010000) -#define DMA2_FLAG_TC5 ((uint32_t)0x10020000) -#define DMA2_FLAG_HT5 ((uint32_t)0x10040000) -#define DMA2_FLAG_TE5 ((uint32_t)0x10080000) - -#define IS_DMA_CLEAR_FLAG(FLAG) (((((FLAG) & 0xF0000000) == 0x00) || (((FLAG) & 0xEFF00000) == 0x00)) && ((FLAG) != 0x00)) - -#define IS_DMA_GET_FLAG(FLAG) (((FLAG) == DMA1_FLAG_GL1) || ((FLAG) == DMA1_FLAG_TC1) || \ - ((FLAG) == DMA1_FLAG_HT1) || ((FLAG) == DMA1_FLAG_TE1) || \ - ((FLAG) == DMA1_FLAG_GL2) || ((FLAG) == DMA1_FLAG_TC2) || \ - ((FLAG) == DMA1_FLAG_HT2) || ((FLAG) == DMA1_FLAG_TE2) || \ - ((FLAG) == DMA1_FLAG_GL3) || ((FLAG) == DMA1_FLAG_TC3) || \ - ((FLAG) == DMA1_FLAG_HT3) || ((FLAG) == DMA1_FLAG_TE3) || \ - ((FLAG) == DMA1_FLAG_GL4) || ((FLAG) == DMA1_FLAG_TC4) || \ - ((FLAG) == DMA1_FLAG_HT4) || ((FLAG) == DMA1_FLAG_TE4) || \ - ((FLAG) == DMA1_FLAG_GL5) || ((FLAG) == DMA1_FLAG_TC5) || \ - ((FLAG) == DMA1_FLAG_HT5) || ((FLAG) == DMA1_FLAG_TE5) || \ - ((FLAG) == DMA1_FLAG_GL6) || ((FLAG) == DMA1_FLAG_TC6) || \ - ((FLAG) == DMA1_FLAG_HT6) || ((FLAG) == DMA1_FLAG_TE6) || \ - ((FLAG) == DMA1_FLAG_GL7) || ((FLAG) == DMA1_FLAG_TC7) || \ - ((FLAG) == DMA1_FLAG_HT7) || ((FLAG) == DMA1_FLAG_TE7) || \ - ((FLAG) == DMA2_FLAG_GL1) || ((FLAG) == DMA2_FLAG_TC1) || \ - ((FLAG) == DMA2_FLAG_HT1) || ((FLAG) == DMA2_FLAG_TE1) || \ - ((FLAG) == DMA2_FLAG_GL2) || ((FLAG) == DMA2_FLAG_TC2) || \ - ((FLAG) == DMA2_FLAG_HT2) || ((FLAG) == DMA2_FLAG_TE2) || \ - ((FLAG) == DMA2_FLAG_GL3) || ((FLAG) == DMA2_FLAG_TC3) || \ - ((FLAG) == DMA2_FLAG_HT3) || ((FLAG) == DMA2_FLAG_TE3) || \ - ((FLAG) == DMA2_FLAG_GL4) || ((FLAG) == DMA2_FLAG_TC4) || \ - ((FLAG) == DMA2_FLAG_HT4) || ((FLAG) == DMA2_FLAG_TE4) || \ - ((FLAG) == DMA2_FLAG_GL5) || ((FLAG) == DMA2_FLAG_TC5) || \ - ((FLAG) == DMA2_FLAG_HT5) || ((FLAG) == DMA2_FLAG_TE5)) -/** - * @} - */ - -/** @defgroup DMA_Buffer_Size - * @{ - */ - -#define IS_DMA_BUFFER_SIZE(SIZE) (((SIZE) >= 0x1) && ((SIZE) < 0x10000)) - -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup DMA_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup DMA_Exported_Functions - * @{ - */ - -void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx); -void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct); -void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct); -void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState); -void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState); -uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx); -FlagStatus DMA_GetFlagStatus(uint32_t DMA_FLAG); -void DMA_ClearFlag(uint32_t DMA_FLAG); -ITStatus DMA_GetITStatus(uint32_t DMA_IT); -void DMA_ClearITPendingBit(uint32_t DMA_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F10x_DMA_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_exti.h b/example/libs_stm/inc/stm32f10x/stm32f10x_exti.h deleted file mode 100644 index e5f1c5a06..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_exti.h +++ /dev/null @@ -1,183 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_exti.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the EXTI firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_EXTI_H -#define __STM32F10x_EXTI_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup EXTI - * @{ - */ - -/** @defgroup EXTI_Exported_Types - * @{ - */ - -/** - * @brief EXTI mode enumeration - */ - -typedef enum -{ - EXTI_Mode_Interrupt = 0x00, - EXTI_Mode_Event = 0x04 -}EXTIMode_TypeDef; - -#define IS_EXTI_MODE(MODE) (((MODE) == EXTI_Mode_Interrupt) || ((MODE) == EXTI_Mode_Event)) - -/** - * @brief EXTI Trigger enumeration - */ - -typedef enum -{ - EXTI_Trigger_Rising = 0x08, - EXTI_Trigger_Falling = 0x0C, - EXTI_Trigger_Rising_Falling = 0x10 -}EXTITrigger_TypeDef; - -#define IS_EXTI_TRIGGER(TRIGGER) (((TRIGGER) == EXTI_Trigger_Rising) || \ - ((TRIGGER) == EXTI_Trigger_Falling) || \ - ((TRIGGER) == EXTI_Trigger_Rising_Falling)) -/** - * @brief EXTI Init Structure definition - */ - -typedef struct -{ - uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled. - This parameter can be any combination of @ref EXTI_Lines */ - - EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines. - This parameter can be a value of @ref EXTIMode_TypeDef */ - - EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines. - This parameter can be a value of @ref EXTIMode_TypeDef */ - - FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines. - This parameter can be set either to ENABLE or DISABLE */ -}EXTI_InitTypeDef; - -/** - * @} - */ - -/** @defgroup EXTI_Exported_Constants - * @{ - */ - -/** @defgroup EXTI_Lines - * @{ - */ - -#define EXTI_Line0 ((uint32_t)0x00001) /*!< External interrupt line 0 */ -#define EXTI_Line1 ((uint32_t)0x00002) /*!< External interrupt line 1 */ -#define EXTI_Line2 ((uint32_t)0x00004) /*!< External interrupt line 2 */ -#define EXTI_Line3 ((uint32_t)0x00008) /*!< External interrupt line 3 */ -#define EXTI_Line4 ((uint32_t)0x00010) /*!< External interrupt line 4 */ -#define EXTI_Line5 ((uint32_t)0x00020) /*!< External interrupt line 5 */ -#define EXTI_Line6 ((uint32_t)0x00040) /*!< External interrupt line 6 */ -#define EXTI_Line7 ((uint32_t)0x00080) /*!< External interrupt line 7 */ -#define EXTI_Line8 ((uint32_t)0x00100) /*!< External interrupt line 8 */ -#define EXTI_Line9 ((uint32_t)0x00200) /*!< External interrupt line 9 */ -#define EXTI_Line10 ((uint32_t)0x00400) /*!< External interrupt line 10 */ -#define EXTI_Line11 ((uint32_t)0x00800) /*!< External interrupt line 11 */ -#define EXTI_Line12 ((uint32_t)0x01000) /*!< External interrupt line 12 */ -#define EXTI_Line13 ((uint32_t)0x02000) /*!< External interrupt line 13 */ -#define EXTI_Line14 ((uint32_t)0x04000) /*!< External interrupt line 14 */ -#define EXTI_Line15 ((uint32_t)0x08000) /*!< External interrupt line 15 */ -#define EXTI_Line16 ((uint32_t)0x10000) /*!< External interrupt line 16 Connected to the PVD Output */ -#define EXTI_Line17 ((uint32_t)0x20000) /*!< External interrupt line 17 Connected to the RTC Alarm event */ -#define EXTI_Line18 ((uint32_t)0x40000) /*!< External interrupt line 18 Connected to the USB Device/USB OTG FS - Wakeup from suspend event */ -#define EXTI_Line19 ((uint32_t)0x80000) /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */ - -#define IS_EXTI_LINE(LINE) ((((LINE) & (uint32_t)0xFFF00000) == 0x00) && ((LINE) != (uint16_t)0x00)) -#define IS_GET_EXTI_LINE(LINE) (((LINE) == EXTI_Line0) || ((LINE) == EXTI_Line1) || \ - ((LINE) == EXTI_Line2) || ((LINE) == EXTI_Line3) || \ - ((LINE) == EXTI_Line4) || ((LINE) == EXTI_Line5) || \ - ((LINE) == EXTI_Line6) || ((LINE) == EXTI_Line7) || \ - ((LINE) == EXTI_Line8) || ((LINE) == EXTI_Line9) || \ - ((LINE) == EXTI_Line10) || ((LINE) == EXTI_Line11) || \ - ((LINE) == EXTI_Line12) || ((LINE) == EXTI_Line13) || \ - ((LINE) == EXTI_Line14) || ((LINE) == EXTI_Line15) || \ - ((LINE) == EXTI_Line16) || ((LINE) == EXTI_Line17) || \ - ((LINE) == EXTI_Line18) || ((LINE) == EXTI_Line19)) - - -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup EXTI_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup EXTI_Exported_Functions - * @{ - */ - -void EXTI_DeInit(void); -void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct); -void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct); -void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line); -FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line); -void EXTI_ClearFlag(uint32_t EXTI_Line); -ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); -void EXTI_ClearITPendingBit(uint32_t EXTI_Line); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_EXTI_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_flash.h b/example/libs_stm/inc/stm32f10x/stm32f10x_flash.h deleted file mode 100644 index 71943013d..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_flash.h +++ /dev/null @@ -1,425 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_flash.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the FLASH - * firmware library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_FLASH_H -#define __STM32F10x_FLASH_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup FLASH - * @{ - */ - -/** @defgroup FLASH_Exported_Types - * @{ - */ - -/** - * @brief FLASH Status - */ - -typedef enum -{ - FLASH_BUSY = 1, - FLASH_ERROR_PG, - FLASH_ERROR_WRP, - FLASH_COMPLETE, - FLASH_TIMEOUT -}FLASH_Status; - -/** - * @} - */ - -/** @defgroup FLASH_Exported_Constants - * @{ - */ - -/** @defgroup Flash_Latency - * @{ - */ - -#define FLASH_Latency_0 ((uint32_t)0x00000000) /*!< FLASH Zero Latency cycle */ -#define FLASH_Latency_1 ((uint32_t)0x00000001) /*!< FLASH One Latency cycle */ -#define FLASH_Latency_2 ((uint32_t)0x00000002) /*!< FLASH Two Latency cycles */ -#define IS_FLASH_LATENCY(LATENCY) (((LATENCY) == FLASH_Latency_0) || \ - ((LATENCY) == FLASH_Latency_1) || \ - ((LATENCY) == FLASH_Latency_2)) -/** - * @} - */ - -/** @defgroup Half_Cycle_Enable_Disable - * @{ - */ - -#define FLASH_HalfCycleAccess_Enable ((uint32_t)0x00000008) /*!< FLASH Half Cycle Enable */ -#define FLASH_HalfCycleAccess_Disable ((uint32_t)0x00000000) /*!< FLASH Half Cycle Disable */ -#define IS_FLASH_HALFCYCLEACCESS_STATE(STATE) (((STATE) == FLASH_HalfCycleAccess_Enable) || \ - ((STATE) == FLASH_HalfCycleAccess_Disable)) -/** - * @} - */ - -/** @defgroup Prefetch_Buffer_Enable_Disable - * @{ - */ - -#define FLASH_PrefetchBuffer_Enable ((uint32_t)0x00000010) /*!< FLASH Prefetch Buffer Enable */ -#define FLASH_PrefetchBuffer_Disable ((uint32_t)0x00000000) /*!< FLASH Prefetch Buffer Disable */ -#define IS_FLASH_PREFETCHBUFFER_STATE(STATE) (((STATE) == FLASH_PrefetchBuffer_Enable) || \ - ((STATE) == FLASH_PrefetchBuffer_Disable)) -/** - * @} - */ - -/** @defgroup Option_Bytes_Write_Protection - * @{ - */ - -/* Values to be used with STM32 Low and Medium density devices */ -#define FLASH_WRProt_Pages0to3 ((uint32_t)0x00000001) /*!< STM32 Low and Medium density devices: Write protection of page 0 to 3 */ -#define FLASH_WRProt_Pages4to7 ((uint32_t)0x00000002) /*!< STM32 Low and Medium density devices: Write protection of page 4 to 7 */ -#define FLASH_WRProt_Pages8to11 ((uint32_t)0x00000004) /*!< STM32 Low and Medium density devices: Write protection of page 8 to 11 */ -#define FLASH_WRProt_Pages12to15 ((uint32_t)0x00000008) /*!< STM32 Low and Medium density devices: Write protection of page 12 to 15 */ -#define FLASH_WRProt_Pages16to19 ((uint32_t)0x00000010) /*!< STM32 Low and Medium density devices: Write protection of page 16 to 19 */ -#define FLASH_WRProt_Pages20to23 ((uint32_t)0x00000020) /*!< STM32 Low and Medium density devices: Write protection of page 20 to 23 */ -#define FLASH_WRProt_Pages24to27 ((uint32_t)0x00000040) /*!< STM32 Low and Medium density devices: Write protection of page 24 to 27 */ -#define FLASH_WRProt_Pages28to31 ((uint32_t)0x00000080) /*!< STM32 Low and Medium density devices: Write protection of page 28 to 31 */ - -/* Values to be used with STM32 Medium-density devices */ -#define FLASH_WRProt_Pages32to35 ((uint32_t)0x00000100) /*!< STM32 Medium-density devices: Write protection of page 32 to 35 */ -#define FLASH_WRProt_Pages36to39 ((uint32_t)0x00000200) /*!< STM32 Medium-density devices: Write protection of page 36 to 39 */ -#define FLASH_WRProt_Pages40to43 ((uint32_t)0x00000400) /*!< STM32 Medium-density devices: Write protection of page 40 to 43 */ -#define FLASH_WRProt_Pages44to47 ((uint32_t)0x00000800) /*!< STM32 Medium-density devices: Write protection of page 44 to 47 */ -#define FLASH_WRProt_Pages48to51 ((uint32_t)0x00001000) /*!< STM32 Medium-density devices: Write protection of page 48 to 51 */ -#define FLASH_WRProt_Pages52to55 ((uint32_t)0x00002000) /*!< STM32 Medium-density devices: Write protection of page 52 to 55 */ -#define FLASH_WRProt_Pages56to59 ((uint32_t)0x00004000) /*!< STM32 Medium-density devices: Write protection of page 56 to 59 */ -#define FLASH_WRProt_Pages60to63 ((uint32_t)0x00008000) /*!< STM32 Medium-density devices: Write protection of page 60 to 63 */ -#define FLASH_WRProt_Pages64to67 ((uint32_t)0x00010000) /*!< STM32 Medium-density devices: Write protection of page 64 to 67 */ -#define FLASH_WRProt_Pages68to71 ((uint32_t)0x00020000) /*!< STM32 Medium-density devices: Write protection of page 68 to 71 */ -#define FLASH_WRProt_Pages72to75 ((uint32_t)0x00040000) /*!< STM32 Medium-density devices: Write protection of page 72 to 75 */ -#define FLASH_WRProt_Pages76to79 ((uint32_t)0x00080000) /*!< STM32 Medium-density devices: Write protection of page 76 to 79 */ -#define FLASH_WRProt_Pages80to83 ((uint32_t)0x00100000) /*!< STM32 Medium-density devices: Write protection of page 80 to 83 */ -#define FLASH_WRProt_Pages84to87 ((uint32_t)0x00200000) /*!< STM32 Medium-density devices: Write protection of page 84 to 87 */ -#define FLASH_WRProt_Pages88to91 ((uint32_t)0x00400000) /*!< STM32 Medium-density devices: Write protection of page 88 to 91 */ -#define FLASH_WRProt_Pages92to95 ((uint32_t)0x00800000) /*!< STM32 Medium-density devices: Write protection of page 92 to 95 */ -#define FLASH_WRProt_Pages96to99 ((uint32_t)0x01000000) /*!< STM32 Medium-density devices: Write protection of page 96 to 99 */ -#define FLASH_WRProt_Pages100to103 ((uint32_t)0x02000000) /*!< STM32 Medium-density devices: Write protection of page 100 to 103 */ -#define FLASH_WRProt_Pages104to107 ((uint32_t)0x04000000) /*!< STM32 Medium-density devices: Write protection of page 104 to 107 */ -#define FLASH_WRProt_Pages108to111 ((uint32_t)0x08000000) /*!< STM32 Medium-density devices: Write protection of page 108 to 111 */ -#define FLASH_WRProt_Pages112to115 ((uint32_t)0x10000000) /*!< STM32 Medium-density devices: Write protection of page 112 to 115 */ -#define FLASH_WRProt_Pages116to119 ((uint32_t)0x20000000) /*!< STM32 Medium-density devices: Write protection of page 115 to 119 */ -#define FLASH_WRProt_Pages120to123 ((uint32_t)0x40000000) /*!< STM32 Medium-density devices: Write protection of page 120 to 123 */ -#define FLASH_WRProt_Pages124to127 ((uint32_t)0x80000000) /*!< STM32 Medium-density devices: Write protection of page 124 to 127 */ - -/* Values to be used with STM32 High-density and STM32F10X Connectivity line devices */ -#define FLASH_WRProt_Pages0to1 ((uint32_t)0x00000001) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 0 to 1 */ -#define FLASH_WRProt_Pages2to3 ((uint32_t)0x00000002) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 2 to 3 */ -#define FLASH_WRProt_Pages4to5 ((uint32_t)0x00000004) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 4 to 5 */ -#define FLASH_WRProt_Pages6to7 ((uint32_t)0x00000008) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 6 to 7 */ -#define FLASH_WRProt_Pages8to9 ((uint32_t)0x00000010) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 8 to 9 */ -#define FLASH_WRProt_Pages10to11 ((uint32_t)0x00000020) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 10 to 11 */ -#define FLASH_WRProt_Pages12to13 ((uint32_t)0x00000040) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 12 to 13 */ -#define FLASH_WRProt_Pages14to15 ((uint32_t)0x00000080) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 14 to 15 */ -#define FLASH_WRProt_Pages16to17 ((uint32_t)0x00000100) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 16 to 17 */ -#define FLASH_WRProt_Pages18to19 ((uint32_t)0x00000200) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 18 to 19 */ -#define FLASH_WRProt_Pages20to21 ((uint32_t)0x00000400) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 20 to 21 */ -#define FLASH_WRProt_Pages22to23 ((uint32_t)0x00000800) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 22 to 23 */ -#define FLASH_WRProt_Pages24to25 ((uint32_t)0x00001000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 24 to 25 */ -#define FLASH_WRProt_Pages26to27 ((uint32_t)0x00002000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 26 to 27 */ -#define FLASH_WRProt_Pages28to29 ((uint32_t)0x00004000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 28 to 29 */ -#define FLASH_WRProt_Pages30to31 ((uint32_t)0x00008000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 30 to 31 */ -#define FLASH_WRProt_Pages32to33 ((uint32_t)0x00010000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 32 to 33 */ -#define FLASH_WRProt_Pages34to35 ((uint32_t)0x00020000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 34 to 35 */ -#define FLASH_WRProt_Pages36to37 ((uint32_t)0x00040000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 36 to 37 */ -#define FLASH_WRProt_Pages38to39 ((uint32_t)0x00080000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 38 to 39 */ -#define FLASH_WRProt_Pages40to41 ((uint32_t)0x00100000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 40 to 41 */ -#define FLASH_WRProt_Pages42to43 ((uint32_t)0x00200000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 42 to 43 */ -#define FLASH_WRProt_Pages44to45 ((uint32_t)0x00400000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 44 to 45 */ -#define FLASH_WRProt_Pages46to47 ((uint32_t)0x00800000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 46 to 47 */ -#define FLASH_WRProt_Pages48to49 ((uint32_t)0x01000000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 48 to 49 */ -#define FLASH_WRProt_Pages50to51 ((uint32_t)0x02000000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 50 to 51 */ -#define FLASH_WRProt_Pages52to53 ((uint32_t)0x04000000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 52 to 53 */ -#define FLASH_WRProt_Pages54to55 ((uint32_t)0x08000000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 54 to 55 */ -#define FLASH_WRProt_Pages56to57 ((uint32_t)0x10000000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 56 to 57 */ -#define FLASH_WRProt_Pages58to59 ((uint32_t)0x20000000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 58 to 59 */ -#define FLASH_WRProt_Pages60to61 ((uint32_t)0x40000000) /*!< STM32 High-density, XL-density and Connectivity line devices: - Write protection of page 60 to 61 */ -#define FLASH_WRProt_Pages62to127 ((uint32_t)0x80000000) /*!< STM32 Connectivity line devices: Write protection of page 62 to 127 */ -#define FLASH_WRProt_Pages62to255 ((uint32_t)0x80000000) /*!< STM32 Medium-density devices: Write protection of page 62 to 255 */ -#define FLASH_WRProt_Pages62to511 ((uint32_t)0x80000000) /*!< STM32 XL-density devices: Write protection of page 62 to 511 */ - -#define FLASH_WRProt_AllPages ((uint32_t)0xFFFFFFFF) /*!< Write protection of all Pages */ - -#define IS_FLASH_WRPROT_PAGE(PAGE) (((PAGE) != 0x00000000)) - -#define IS_FLASH_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x080FFFFF)) - -#define IS_OB_DATA_ADDRESS(ADDRESS) (((ADDRESS) == 0x1FFFF804) || ((ADDRESS) == 0x1FFFF806)) - -/** - * @} - */ - -/** @defgroup Option_Bytes_IWatchdog - * @{ - */ - -#define OB_IWDG_SW ((uint16_t)0x0001) /*!< Software IWDG selected */ -#define OB_IWDG_HW ((uint16_t)0x0000) /*!< Hardware IWDG selected */ -#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW)) - -/** - * @} - */ - -/** @defgroup Option_Bytes_nRST_STOP - * @{ - */ - -#define OB_STOP_NoRST ((uint16_t)0x0002) /*!< No reset generated when entering in STOP */ -#define OB_STOP_RST ((uint16_t)0x0000) /*!< Reset generated when entering in STOP */ -#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NoRST) || ((SOURCE) == OB_STOP_RST)) - -/** - * @} - */ - -/** @defgroup Option_Bytes_nRST_STDBY - * @{ - */ - -#define OB_STDBY_NoRST ((uint16_t)0x0004) /*!< No reset generated when entering in STANDBY */ -#define OB_STDBY_RST ((uint16_t)0x0000) /*!< Reset generated when entering in STANDBY */ -#define IS_OB_STDBY_SOURCE(SOURCE) (((SOURCE) == OB_STDBY_NoRST) || ((SOURCE) == OB_STDBY_RST)) - -#ifdef STM32F10X_XL -/** - * @} - */ -/** @defgroup FLASH_Boot - * @{ - */ -#define FLASH_BOOT_Bank1 ((uint16_t)0x0000) /*!< At startup, if boot pins are set in boot from user Flash position - and this parameter is selected the device will boot from Bank1(Default) */ -#define FLASH_BOOT_Bank2 ((uint16_t)0x0001) /*!< At startup, if boot pins are set in boot from user Flash position - and this parameter is selected the device will boot from Bank 2 or Bank 1, - depending on the activation of the bank */ -#define IS_FLASH_BOOT(BOOT) (((BOOT) == FLASH_BOOT_Bank1) || ((BOOT) == FLASH_BOOT_Bank2)) -#endif -/** - * @} - */ -/** @defgroup FLASH_Interrupts - * @{ - */ -#ifdef STM32F10X_XL -#define FLASH_IT_BANK2_ERROR ((uint32_t)0x80000400) /*!< FPEC BANK2 error interrupt source */ -#define FLASH_IT_BANK2_EOP ((uint32_t)0x80001000) /*!< End of FLASH BANK2 Operation Interrupt source */ - -#define FLASH_IT_BANK1_ERROR FLASH_IT_ERROR /*!< FPEC BANK1 error interrupt source */ -#define FLASH_IT_BANK1_EOP FLASH_IT_EOP /*!< End of FLASH BANK1 Operation Interrupt source */ - -#define FLASH_IT_ERROR ((uint32_t)0x00000400) /*!< FPEC BANK1 error interrupt source */ -#define FLASH_IT_EOP ((uint32_t)0x00001000) /*!< End of FLASH BANK1 Operation Interrupt source */ -#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0x7FFFEBFF) == 0x00000000) && (((IT) != 0x00000000))) -#else -#define FLASH_IT_ERROR ((uint32_t)0x00000400) /*!< FPEC error interrupt source */ -#define FLASH_IT_EOP ((uint32_t)0x00001000) /*!< End of FLASH Operation Interrupt source */ -#define FLASH_IT_BANK1_ERROR FLASH_IT_ERROR /*!< FPEC BANK1 error interrupt source */ -#define FLASH_IT_BANK1_EOP FLASH_IT_EOP /*!< End of FLASH BANK1 Operation Interrupt source */ - -#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0xFFFFEBFF) == 0x00000000) && (((IT) != 0x00000000))) -#endif - -/** - * @} - */ - -/** @defgroup FLASH_Flags - * @{ - */ -#ifdef STM32F10X_XL -#define FLASH_FLAG_BANK2_BSY ((uint32_t)0x80000001) /*!< FLASH BANK2 Busy flag */ -#define FLASH_FLAG_BANK2_EOP ((uint32_t)0x80000020) /*!< FLASH BANK2 End of Operation flag */ -#define FLASH_FLAG_BANK2_PGERR ((uint32_t)0x80000004) /*!< FLASH BANK2 Program error flag */ -#define FLASH_FLAG_BANK2_WRPRTERR ((uint32_t)0x80000010) /*!< FLASH BANK2 Write protected error flag */ - -#define FLASH_FLAG_BANK1_BSY FLASH_FLAG_BSY /*!< FLASH BANK1 Busy flag*/ -#define FLASH_FLAG_BANK1_EOP FLASH_FLAG_EOP /*!< FLASH BANK1 End of Operation flag */ -#define FLASH_FLAG_BANK1_PGERR FLASH_FLAG_PGERR /*!< FLASH BANK1 Program error flag */ -#define FLASH_FLAG_BANK1_WRPRTERR FLASH_FLAG_WRPRTERR /*!< FLASH BANK1 Write protected error flag */ - -#define FLASH_FLAG_BSY ((uint32_t)0x00000001) /*!< FLASH Busy flag */ -#define FLASH_FLAG_EOP ((uint32_t)0x00000020) /*!< FLASH End of Operation flag */ -#define FLASH_FLAG_PGERR ((uint32_t)0x00000004) /*!< FLASH Program error flag */ -#define FLASH_FLAG_WRPRTERR ((uint32_t)0x00000010) /*!< FLASH Write protected error flag */ -#define FLASH_FLAG_OPTERR ((uint32_t)0x00000001) /*!< FLASH Option Byte error flag */ - -#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0x7FFFFFCA) == 0x00000000) && ((FLAG) != 0x00000000)) -#define IS_FLASH_GET_FLAG(FLAG) (((FLAG) == FLASH_FLAG_BSY) || ((FLAG) == FLASH_FLAG_EOP) || \ - ((FLAG) == FLASH_FLAG_PGERR) || ((FLAG) == FLASH_FLAG_WRPRTERR) || \ - ((FLAG) == FLASH_FLAG_OPTERR)|| \ - ((FLAG) == FLASH_FLAG_BANK1_BSY) || ((FLAG) == FLASH_FLAG_BANK1_EOP) || \ - ((FLAG) == FLASH_FLAG_BANK1_PGERR) || ((FLAG) == FLASH_FLAG_BANK1_WRPRTERR) || \ - ((FLAG) == FLASH_FLAG_BANK2_BSY) || ((FLAG) == FLASH_FLAG_BANK2_EOP) || \ - ((FLAG) == FLASH_FLAG_BANK2_PGERR) || ((FLAG) == FLASH_FLAG_BANK2_WRPRTERR)) -#else -#define FLASH_FLAG_BSY ((uint32_t)0x00000001) /*!< FLASH Busy flag */ -#define FLASH_FLAG_EOP ((uint32_t)0x00000020) /*!< FLASH End of Operation flag */ -#define FLASH_FLAG_PGERR ((uint32_t)0x00000004) /*!< FLASH Program error flag */ -#define FLASH_FLAG_WRPRTERR ((uint32_t)0x00000010) /*!< FLASH Write protected error flag */ -#define FLASH_FLAG_OPTERR ((uint32_t)0x00000001) /*!< FLASH Option Byte error flag */ - -#define FLASH_FLAG_BANK1_BSY FLASH_FLAG_BSY /*!< FLASH BANK1 Busy flag*/ -#define FLASH_FLAG_BANK1_EOP FLASH_FLAG_EOP /*!< FLASH BANK1 End of Operation flag */ -#define FLASH_FLAG_BANK1_PGERR FLASH_FLAG_PGERR /*!< FLASH BANK1 Program error flag */ -#define FLASH_FLAG_BANK1_WRPRTERR FLASH_FLAG_WRPRTERR /*!< FLASH BANK1 Write protected error flag */ - -#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFCA) == 0x00000000) && ((FLAG) != 0x00000000)) -#define IS_FLASH_GET_FLAG(FLAG) (((FLAG) == FLASH_FLAG_BSY) || ((FLAG) == FLASH_FLAG_EOP) || \ - ((FLAG) == FLASH_FLAG_PGERR) || ((FLAG) == FLASH_FLAG_WRPRTERR) || \ - ((FLAG) == FLASH_FLAG_BANK1_BSY) || ((FLAG) == FLASH_FLAG_BANK1_EOP) || \ - ((FLAG) == FLASH_FLAG_BANK1_PGERR) || ((FLAG) == FLASH_FLAG_BANK1_WRPRTERR) || \ - ((FLAG) == FLASH_FLAG_OPTERR)) -#endif - -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup FLASH_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup FLASH_Exported_Functions - * @{ - */ - -/*------------ Functions used for all STM32F10x devices -----*/ -void FLASH_SetLatency(uint32_t FLASH_Latency); -void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess); -void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer); -void FLASH_Unlock(void); -void FLASH_Lock(void); -FLASH_Status FLASH_ErasePage(uint32_t Page_Address); -FLASH_Status FLASH_EraseAllPages(void); -FLASH_Status FLASH_EraseOptionBytes(void); -FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data); -FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data); -FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data); -FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages); -FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState); -FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY); -uint32_t FLASH_GetUserOptionByte(void); -uint32_t FLASH_GetWriteProtectionOptionByte(void); -FlagStatus FLASH_GetReadOutProtectionStatus(void); -FlagStatus FLASH_GetPrefetchBufferStatus(void); -void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState); -FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG); -void FLASH_ClearFlag(uint32_t FLASH_FLAG); -FLASH_Status FLASH_GetStatus(void); -FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout); - -/*------------ New function used for all STM32F10x devices -----*/ -void FLASH_UnlockBank1(void); -void FLASH_LockBank1(void); -FLASH_Status FLASH_EraseAllBank1Pages(void); -FLASH_Status FLASH_GetBank1Status(void); -FLASH_Status FLASH_WaitForLastBank1Operation(uint32_t Timeout); - -#ifdef STM32F10X_XL -/*---- New Functions used only with STM32F10x_XL density devices -----*/ -void FLASH_UnlockBank2(void); -void FLASH_LockBank2(void); -FLASH_Status FLASH_EraseAllBank2Pages(void); -FLASH_Status FLASH_GetBank2Status(void); -FLASH_Status FLASH_WaitForLastBank2Operation(uint32_t Timeout); -FLASH_Status FLASH_BootConfig(uint16_t FLASH_BOOT); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_FLASH_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_fsmc.h b/example/libs_stm/inc/stm32f10x/stm32f10x_fsmc.h deleted file mode 100644 index 944f077ed..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_fsmc.h +++ /dev/null @@ -1,716 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_fsmc.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the FSMC firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_FSMC_H -#define __STM32F10x_FSMC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup FSMC - * @{ - */ - -/** @defgroup FSMC_Exported_Types - * @{ - */ - -/** - * @brief Timing parameters For NOR/SRAM Banks - */ - -typedef struct -{ - uint32_t FSMC_AddressSetupTime; /*!< Defines the number of HCLK cycles to configure - the duration of the address setup time. - This parameter can be a value between 0 and 0xF. - @note: It is not used with synchronous NOR Flash memories. */ - - uint32_t FSMC_AddressHoldTime; /*!< Defines the number of HCLK cycles to configure - the duration of the address hold time. - This parameter can be a value between 0 and 0xF. - @note: It is not used with synchronous NOR Flash memories.*/ - - uint32_t FSMC_DataSetupTime; /*!< Defines the number of HCLK cycles to configure - the duration of the data setup time. - This parameter can be a value between 0 and 0xFF. - @note: It is used for SRAMs, ROMs and asynchronous multiplexed NOR Flash memories. */ - - uint32_t FSMC_BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure - the duration of the bus turnaround. - This parameter can be a value between 0 and 0xF. - @note: It is only used for multiplexed NOR Flash memories. */ - - uint32_t FSMC_CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of HCLK cycles. - This parameter can be a value between 1 and 0xF. - @note: This parameter is not used for asynchronous NOR Flash, SRAM or ROM accesses. */ - - uint32_t FSMC_DataLatency; /*!< Defines the number of memory clock cycles to issue - to the memory before getting the first data. - The value of this parameter depends on the memory type as shown below: - - It must be set to 0 in case of a CRAM - - It is dont care in asynchronous NOR, SRAM or ROM accesses - - It may assume a value between 0 and 0xF in NOR Flash memories - with synchronous burst mode enable */ - - uint32_t FSMC_AccessMode; /*!< Specifies the asynchronous access mode. - This parameter can be a value of @ref FSMC_Access_Mode */ -}FSMC_NORSRAMTimingInitTypeDef; - -/** - * @brief FSMC NOR/SRAM Init structure definition - */ - -typedef struct -{ - uint32_t FSMC_Bank; /*!< Specifies the NOR/SRAM memory bank that will be used. - This parameter can be a value of @ref FSMC_NORSRAM_Bank */ - - uint32_t FSMC_DataAddressMux; /*!< Specifies whether the address and data values are - multiplexed on the databus or not. - This parameter can be a value of @ref FSMC_Data_Address_Bus_Multiplexing */ - - uint32_t FSMC_MemoryType; /*!< Specifies the type of external memory attached to - the corresponding memory bank. - This parameter can be a value of @ref FSMC_Memory_Type */ - - uint32_t FSMC_MemoryDataWidth; /*!< Specifies the external memory device width. - This parameter can be a value of @ref FSMC_Data_Width */ - - uint32_t FSMC_BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory, - valid only with synchronous burst Flash memories. - This parameter can be a value of @ref FSMC_Burst_Access_Mode */ - - uint32_t FSMC_WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing - the Flash memory in burst mode. - This parameter can be a value of @ref FSMC_Wait_Signal_Polarity */ - - uint32_t FSMC_WrapMode; /*!< Enables or disables the Wrapped burst access mode for Flash - memory, valid only when accessing Flash memories in burst mode. - This parameter can be a value of @ref FSMC_Wrap_Mode */ - - uint32_t FSMC_WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one - clock cycle before the wait state or during the wait state, - valid only when accessing memories in burst mode. - This parameter can be a value of @ref FSMC_Wait_Timing */ - - uint32_t FSMC_WriteOperation; /*!< Enables or disables the write operation in the selected bank by the FSMC. - This parameter can be a value of @ref FSMC_Write_Operation */ - - uint32_t FSMC_WaitSignal; /*!< Enables or disables the wait-state insertion via wait - signal, valid for Flash memory access in burst mode. - This parameter can be a value of @ref FSMC_Wait_Signal */ - - uint32_t FSMC_ExtendedMode; /*!< Enables or disables the extended mode. - This parameter can be a value of @ref FSMC_Extended_Mode */ - - uint32_t FSMC_WriteBurst; /*!< Enables or disables the write burst operation. - This parameter can be a value of @ref FSMC_Write_Burst */ - - FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct; /*!< Timing Parameters for write and read access if the ExtendedMode is not used*/ - - FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct; /*!< Timing Parameters for write access if the ExtendedMode is used*/ -}FSMC_NORSRAMInitTypeDef; - -/** - * @brief Timing parameters For FSMC NAND and PCCARD Banks - */ - -typedef struct -{ - uint32_t FSMC_SetupTime; /*!< Defines the number of HCLK cycles to setup address before - the command assertion for NAND-Flash read or write access - to common/Attribute or I/O memory space (depending on - the memory space timing to be configured). - This parameter can be a value between 0 and 0xFF.*/ - - uint32_t FSMC_WaitSetupTime; /*!< Defines the minimum number of HCLK cycles to assert the - command for NAND-Flash read or write access to - common/Attribute or I/O memory space (depending on the - memory space timing to be configured). - This parameter can be a number between 0x00 and 0xFF */ - - uint32_t FSMC_HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address - (and data for write access) after the command deassertion - for NAND-Flash read or write access to common/Attribute - or I/O memory space (depending on the memory space timing - to be configured). - This parameter can be a number between 0x00 and 0xFF */ - - uint32_t FSMC_HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the - databus is kept in HiZ after the start of a NAND-Flash - write access to common/Attribute or I/O memory space (depending - on the memory space timing to be configured). - This parameter can be a number between 0x00 and 0xFF */ -}FSMC_NAND_PCCARDTimingInitTypeDef; - -/** - * @brief FSMC NAND Init structure definition - */ - -typedef struct -{ - uint32_t FSMC_Bank; /*!< Specifies the NAND memory bank that will be used. - This parameter can be a value of @ref FSMC_NAND_Bank */ - - uint32_t FSMC_Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory Bank. - This parameter can be any value of @ref FSMC_Wait_feature */ - - uint32_t FSMC_MemoryDataWidth; /*!< Specifies the external memory device width. - This parameter can be any value of @ref FSMC_Data_Width */ - - uint32_t FSMC_ECC; /*!< Enables or disables the ECC computation. - This parameter can be any value of @ref FSMC_ECC */ - - uint32_t FSMC_ECCPageSize; /*!< Defines the page size for the extended ECC. - This parameter can be any value of @ref FSMC_ECC_Page_Size */ - - uint32_t FSMC_TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the - delay between CLE low and RE low. - This parameter can be a value between 0 and 0xFF. */ - - uint32_t FSMC_TARSetupTime; /*!< Defines the number of HCLK cycles to configure the - delay between ALE low and RE low. - This parameter can be a number between 0x0 and 0xFF */ - - FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_CommonSpaceTimingStruct; /*!< FSMC Common Space Timing */ - - FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_AttributeSpaceTimingStruct; /*!< FSMC Attribute Space Timing */ -}FSMC_NANDInitTypeDef; - -/** - * @brief FSMC PCCARD Init structure definition - */ - -typedef struct -{ - uint32_t FSMC_Waitfeature; /*!< Enables or disables the Wait feature for the Memory Bank. - This parameter can be any value of @ref FSMC_Wait_feature */ - - uint32_t FSMC_TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the - delay between CLE low and RE low. - This parameter can be a value between 0 and 0xFF. */ - - uint32_t FSMC_TARSetupTime; /*!< Defines the number of HCLK cycles to configure the - delay between ALE low and RE low. - This parameter can be a number between 0x0 and 0xFF */ - - - FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_CommonSpaceTimingStruct; /*!< FSMC Common Space Timing */ - - FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_AttributeSpaceTimingStruct; /*!< FSMC Attribute Space Timing */ - - FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_IOSpaceTimingStruct; /*!< FSMC IO Space Timing */ -}FSMC_PCCARDInitTypeDef; - -/** - * @} - */ - -/** @defgroup FSMC_Exported_Constants - * @{ - */ - -/** @defgroup FSMC_NORSRAM_Bank - * @{ - */ -#define FSMC_Bank1_NORSRAM1 ((uint32_t)0x00000000) -#define FSMC_Bank1_NORSRAM2 ((uint32_t)0x00000002) -#define FSMC_Bank1_NORSRAM3 ((uint32_t)0x00000004) -#define FSMC_Bank1_NORSRAM4 ((uint32_t)0x00000006) -/** - * @} - */ - -/** @defgroup FSMC_NAND_Bank - * @{ - */ -#define FSMC_Bank2_NAND ((uint32_t)0x00000010) -#define FSMC_Bank3_NAND ((uint32_t)0x00000100) -/** - * @} - */ - -/** @defgroup FSMC_PCCARD_Bank - * @{ - */ -#define FSMC_Bank4_PCCARD ((uint32_t)0x00001000) -/** - * @} - */ - -#define IS_FSMC_NORSRAM_BANK(BANK) (((BANK) == FSMC_Bank1_NORSRAM1) || \ - ((BANK) == FSMC_Bank1_NORSRAM2) || \ - ((BANK) == FSMC_Bank1_NORSRAM3) || \ - ((BANK) == FSMC_Bank1_NORSRAM4)) - -#define IS_FSMC_NAND_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \ - ((BANK) == FSMC_Bank3_NAND)) - -#define IS_FSMC_GETFLAG_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \ - ((BANK) == FSMC_Bank3_NAND) || \ - ((BANK) == FSMC_Bank4_PCCARD)) - -#define IS_FSMC_IT_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \ - ((BANK) == FSMC_Bank3_NAND) || \ - ((BANK) == FSMC_Bank4_PCCARD)) - -/** @defgroup NOR_SRAM_Controller - * @{ - */ - -/** @defgroup FSMC_Data_Address_Bus_Multiplexing - * @{ - */ - -#define FSMC_DataAddressMux_Disable ((uint32_t)0x00000000) -#define FSMC_DataAddressMux_Enable ((uint32_t)0x00000002) -#define IS_FSMC_MUX(MUX) (((MUX) == FSMC_DataAddressMux_Disable) || \ - ((MUX) == FSMC_DataAddressMux_Enable)) - -/** - * @} - */ - -/** @defgroup FSMC_Memory_Type - * @{ - */ - -#define FSMC_MemoryType_SRAM ((uint32_t)0x00000000) -#define FSMC_MemoryType_PSRAM ((uint32_t)0x00000004) -#define FSMC_MemoryType_NOR ((uint32_t)0x00000008) -#define IS_FSMC_MEMORY(MEMORY) (((MEMORY) == FSMC_MemoryType_SRAM) || \ - ((MEMORY) == FSMC_MemoryType_PSRAM)|| \ - ((MEMORY) == FSMC_MemoryType_NOR)) - -/** - * @} - */ - -/** @defgroup FSMC_Data_Width - * @{ - */ - -#define FSMC_MemoryDataWidth_8b ((uint32_t)0x00000000) -#define FSMC_MemoryDataWidth_16b ((uint32_t)0x00000010) -#define IS_FSMC_MEMORY_WIDTH(WIDTH) (((WIDTH) == FSMC_MemoryDataWidth_8b) || \ - ((WIDTH) == FSMC_MemoryDataWidth_16b)) - -/** - * @} - */ - -/** @defgroup FSMC_Burst_Access_Mode - * @{ - */ - -#define FSMC_BurstAccessMode_Disable ((uint32_t)0x00000000) -#define FSMC_BurstAccessMode_Enable ((uint32_t)0x00000100) -#define IS_FSMC_BURSTMODE(STATE) (((STATE) == FSMC_BurstAccessMode_Disable) || \ - ((STATE) == FSMC_BurstAccessMode_Enable)) -/** - * @} - */ - -/** @defgroup FSMC_Wait_Signal_Polarity - * @{ - */ - -#define FSMC_WaitSignalPolarity_Low ((uint32_t)0x00000000) -#define FSMC_WaitSignalPolarity_High ((uint32_t)0x00000200) -#define IS_FSMC_WAIT_POLARITY(POLARITY) (((POLARITY) == FSMC_WaitSignalPolarity_Low) || \ - ((POLARITY) == FSMC_WaitSignalPolarity_High)) - -/** - * @} - */ - -/** @defgroup FSMC_Wrap_Mode - * @{ - */ - -#define FSMC_WrapMode_Disable ((uint32_t)0x00000000) -#define FSMC_WrapMode_Enable ((uint32_t)0x00000400) -#define IS_FSMC_WRAP_MODE(MODE) (((MODE) == FSMC_WrapMode_Disable) || \ - ((MODE) == FSMC_WrapMode_Enable)) - -/** - * @} - */ - -/** @defgroup FSMC_Wait_Timing - * @{ - */ - -#define FSMC_WaitSignalActive_BeforeWaitState ((uint32_t)0x00000000) -#define FSMC_WaitSignalActive_DuringWaitState ((uint32_t)0x00000800) -#define IS_FSMC_WAIT_SIGNAL_ACTIVE(ACTIVE) (((ACTIVE) == FSMC_WaitSignalActive_BeforeWaitState) || \ - ((ACTIVE) == FSMC_WaitSignalActive_DuringWaitState)) - -/** - * @} - */ - -/** @defgroup FSMC_Write_Operation - * @{ - */ - -#define FSMC_WriteOperation_Disable ((uint32_t)0x00000000) -#define FSMC_WriteOperation_Enable ((uint32_t)0x00001000) -#define IS_FSMC_WRITE_OPERATION(OPERATION) (((OPERATION) == FSMC_WriteOperation_Disable) || \ - ((OPERATION) == FSMC_WriteOperation_Enable)) - -/** - * @} - */ - -/** @defgroup FSMC_Wait_Signal - * @{ - */ - -#define FSMC_WaitSignal_Disable ((uint32_t)0x00000000) -#define FSMC_WaitSignal_Enable ((uint32_t)0x00002000) -#define IS_FSMC_WAITE_SIGNAL(SIGNAL) (((SIGNAL) == FSMC_WaitSignal_Disable) || \ - ((SIGNAL) == FSMC_WaitSignal_Enable)) -/** - * @} - */ - -/** @defgroup FSMC_Extended_Mode - * @{ - */ - -#define FSMC_ExtendedMode_Disable ((uint32_t)0x00000000) -#define FSMC_ExtendedMode_Enable ((uint32_t)0x00004000) - -#define IS_FSMC_EXTENDED_MODE(MODE) (((MODE) == FSMC_ExtendedMode_Disable) || \ - ((MODE) == FSMC_ExtendedMode_Enable)) - -/** - * @} - */ - -/** @defgroup FSMC_Write_Burst - * @{ - */ - -#define FSMC_WriteBurst_Disable ((uint32_t)0x00000000) -#define FSMC_WriteBurst_Enable ((uint32_t)0x00080000) -#define IS_FSMC_WRITE_BURST(BURST) (((BURST) == FSMC_WriteBurst_Disable) || \ - ((BURST) == FSMC_WriteBurst_Enable)) -/** - * @} - */ - -/** @defgroup FSMC_Address_Setup_Time - * @{ - */ - -#define IS_FSMC_ADDRESS_SETUP_TIME(TIME) ((TIME) <= 0xF) - -/** - * @} - */ - -/** @defgroup FSMC_Address_Hold_Time - * @{ - */ - -#define IS_FSMC_ADDRESS_HOLD_TIME(TIME) ((TIME) <= 0xF) - -/** - * @} - */ - -/** @defgroup FSMC_Data_Setup_Time - * @{ - */ - -#define IS_FSMC_DATASETUP_TIME(TIME) (((TIME) > 0) && ((TIME) <= 0xFF)) - -/** - * @} - */ - -/** @defgroup FSMC_Bus_Turn_around_Duration - * @{ - */ - -#define IS_FSMC_TURNAROUND_TIME(TIME) ((TIME) <= 0xF) - -/** - * @} - */ - -/** @defgroup FSMC_CLK_Division - * @{ - */ - -#define IS_FSMC_CLK_DIV(DIV) ((DIV) <= 0xF) - -/** - * @} - */ - -/** @defgroup FSMC_Data_Latency - * @{ - */ - -#define IS_FSMC_DATA_LATENCY(LATENCY) ((LATENCY) <= 0xF) - -/** - * @} - */ - -/** @defgroup FSMC_Access_Mode - * @{ - */ - -#define FSMC_AccessMode_A ((uint32_t)0x00000000) -#define FSMC_AccessMode_B ((uint32_t)0x10000000) -#define FSMC_AccessMode_C ((uint32_t)0x20000000) -#define FSMC_AccessMode_D ((uint32_t)0x30000000) -#define IS_FSMC_ACCESS_MODE(MODE) (((MODE) == FSMC_AccessMode_A) || \ - ((MODE) == FSMC_AccessMode_B) || \ - ((MODE) == FSMC_AccessMode_C) || \ - ((MODE) == FSMC_AccessMode_D)) - -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup NAND_PCCARD_Controller - * @{ - */ - -/** @defgroup FSMC_Wait_feature - * @{ - */ - -#define FSMC_Waitfeature_Disable ((uint32_t)0x00000000) -#define FSMC_Waitfeature_Enable ((uint32_t)0x00000002) -#define IS_FSMC_WAIT_FEATURE(FEATURE) (((FEATURE) == FSMC_Waitfeature_Disable) || \ - ((FEATURE) == FSMC_Waitfeature_Enable)) - -/** - * @} - */ - - -/** @defgroup FSMC_ECC - * @{ - */ - -#define FSMC_ECC_Disable ((uint32_t)0x00000000) -#define FSMC_ECC_Enable ((uint32_t)0x00000040) -#define IS_FSMC_ECC_STATE(STATE) (((STATE) == FSMC_ECC_Disable) || \ - ((STATE) == FSMC_ECC_Enable)) - -/** - * @} - */ - -/** @defgroup FSMC_ECC_Page_Size - * @{ - */ - -#define FSMC_ECCPageSize_256Bytes ((uint32_t)0x00000000) -#define FSMC_ECCPageSize_512Bytes ((uint32_t)0x00020000) -#define FSMC_ECCPageSize_1024Bytes ((uint32_t)0x00040000) -#define FSMC_ECCPageSize_2048Bytes ((uint32_t)0x00060000) -#define FSMC_ECCPageSize_4096Bytes ((uint32_t)0x00080000) -#define FSMC_ECCPageSize_8192Bytes ((uint32_t)0x000A0000) -#define IS_FSMC_ECCPAGE_SIZE(SIZE) (((SIZE) == FSMC_ECCPageSize_256Bytes) || \ - ((SIZE) == FSMC_ECCPageSize_512Bytes) || \ - ((SIZE) == FSMC_ECCPageSize_1024Bytes) || \ - ((SIZE) == FSMC_ECCPageSize_2048Bytes) || \ - ((SIZE) == FSMC_ECCPageSize_4096Bytes) || \ - ((SIZE) == FSMC_ECCPageSize_8192Bytes)) - -/** - * @} - */ - -/** @defgroup FSMC_TCLR_Setup_Time - * @{ - */ - -#define IS_FSMC_TCLR_TIME(TIME) ((TIME) <= 0xFF) - -/** - * @} - */ - -/** @defgroup FSMC_TAR_Setup_Time - * @{ - */ - -#define IS_FSMC_TAR_TIME(TIME) ((TIME) <= 0xFF) - -/** - * @} - */ - -/** @defgroup FSMC_Setup_Time - * @{ - */ - -#define IS_FSMC_SETUP_TIME(TIME) ((TIME) <= 0xFF) - -/** - * @} - */ - -/** @defgroup FSMC_Wait_Setup_Time - * @{ - */ - -#define IS_FSMC_WAIT_TIME(TIME) ((TIME) <= 0xFF) - -/** - * @} - */ - -/** @defgroup FSMC_Hold_Setup_Time - * @{ - */ - -#define IS_FSMC_HOLD_TIME(TIME) ((TIME) <= 0xFF) - -/** - * @} - */ - -/** @defgroup FSMC_HiZ_Setup_Time - * @{ - */ - -#define IS_FSMC_HIZ_TIME(TIME) ((TIME) <= 0xFF) - -/** - * @} - */ - -/** @defgroup FSMC_Interrupt_sources - * @{ - */ - -#define FSMC_IT_RisingEdge ((uint32_t)0x00000008) -#define FSMC_IT_Level ((uint32_t)0x00000010) -#define FSMC_IT_FallingEdge ((uint32_t)0x00000020) -#define IS_FSMC_IT(IT) ((((IT) & (uint32_t)0xFFFFFFC7) == 0x00000000) && ((IT) != 0x00000000)) -#define IS_FSMC_GET_IT(IT) (((IT) == FSMC_IT_RisingEdge) || \ - ((IT) == FSMC_IT_Level) || \ - ((IT) == FSMC_IT_FallingEdge)) -/** - * @} - */ - -/** @defgroup FSMC_Flags - * @{ - */ - -#define FSMC_FLAG_RisingEdge ((uint32_t)0x00000001) -#define FSMC_FLAG_Level ((uint32_t)0x00000002) -#define FSMC_FLAG_FallingEdge ((uint32_t)0x00000004) -#define FSMC_FLAG_FEMPT ((uint32_t)0x00000040) -#define IS_FSMC_GET_FLAG(FLAG) (((FLAG) == FSMC_FLAG_RisingEdge) || \ - ((FLAG) == FSMC_FLAG_Level) || \ - ((FLAG) == FSMC_FLAG_FallingEdge) || \ - ((FLAG) == FSMC_FLAG_FEMPT)) - -#define IS_FSMC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFF8) == 0x00000000) && ((FLAG) != 0x00000000)) - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup FSMC_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup FSMC_Exported_Functions - * @{ - */ - -void FSMC_NORSRAMDeInit(uint32_t FSMC_Bank); -void FSMC_NANDDeInit(uint32_t FSMC_Bank); -void FSMC_PCCARDDeInit(void); -void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct); -void FSMC_NANDInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct); -void FSMC_PCCARDInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct); -void FSMC_NORSRAMStructInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct); -void FSMC_NANDStructInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct); -void FSMC_PCCARDStructInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct); -void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState); -void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState); -void FSMC_PCCARDCmd(FunctionalState NewState); -void FSMC_NANDECCCmd(uint32_t FSMC_Bank, FunctionalState NewState); -uint32_t FSMC_GetECC(uint32_t FSMC_Bank); -void FSMC_ITConfig(uint32_t FSMC_Bank, uint32_t FSMC_IT, FunctionalState NewState); -FlagStatus FSMC_GetFlagStatus(uint32_t FSMC_Bank, uint32_t FSMC_FLAG); -void FSMC_ClearFlag(uint32_t FSMC_Bank, uint32_t FSMC_FLAG); -ITStatus FSMC_GetITStatus(uint32_t FSMC_Bank, uint32_t FSMC_IT); -void FSMC_ClearITPendingBit(uint32_t FSMC_Bank, uint32_t FSMC_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F10x_FSMC_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_gpio.h b/example/libs_stm/inc/stm32f10x/stm32f10x_gpio.h deleted file mode 100644 index aff7a5c1d..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_gpio.h +++ /dev/null @@ -1,379 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_gpio.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the GPIO - * firmware library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_GPIO_H -#define __STM32F10x_GPIO_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup GPIO - * @{ - */ - -/** @defgroup GPIO_Exported_Types - * @{ - */ - -#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ - ((PERIPH) == GPIOB) || \ - ((PERIPH) == GPIOC) || \ - ((PERIPH) == GPIOD) || \ - ((PERIPH) == GPIOE) || \ - ((PERIPH) == GPIOF) || \ - ((PERIPH) == GPIOG)) - -/** - * @brief Output Maximum frequency selection - */ - -typedef enum -{ - GPIO_Speed_10MHz = 1, - GPIO_Speed_2MHz, - GPIO_Speed_50MHz -}GPIOSpeed_TypeDef; -#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_10MHz) || ((SPEED) == GPIO_Speed_2MHz) || \ - ((SPEED) == GPIO_Speed_50MHz)) - -/** - * @brief Configuration Mode enumeration - */ - -typedef enum -{ GPIO_Mode_AIN = 0x0, - GPIO_Mode_IN_FLOATING = 0x04, - GPIO_Mode_IPD = 0x28, - GPIO_Mode_IPU = 0x48, - GPIO_Mode_Out_OD = 0x14, - GPIO_Mode_Out_PP = 0x10, - GPIO_Mode_AF_OD = 0x1C, - GPIO_Mode_AF_PP = 0x18 -}GPIOMode_TypeDef; - -#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_AIN) || ((MODE) == GPIO_Mode_IN_FLOATING) || \ - ((MODE) == GPIO_Mode_IPD) || ((MODE) == GPIO_Mode_IPU) || \ - ((MODE) == GPIO_Mode_Out_OD) || ((MODE) == GPIO_Mode_Out_PP) || \ - ((MODE) == GPIO_Mode_AF_OD) || ((MODE) == GPIO_Mode_AF_PP)) - -/** - * @brief GPIO Init structure definition - */ - -typedef struct -{ - uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. - This parameter can be any value of @ref GPIO_pins_define */ - - GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. - This parameter can be a value of @ref GPIOSpeed_TypeDef */ - - GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. - This parameter can be a value of @ref GPIOMode_TypeDef */ -}GPIO_InitTypeDef; - - -/** - * @brief Bit_SET and Bit_RESET enumeration - */ - -typedef enum -{ Bit_RESET = 0, - Bit_SET -}BitAction; - -#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) - -/** - * @} - */ - -/** @defgroup GPIO_Exported_Constants - * @{ - */ - -/** @defgroup GPIO_pins_define - * @{ - */ - -#define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */ -#define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */ -#define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */ -#define GPIO_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */ -#define GPIO_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */ -#define GPIO_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */ -#define GPIO_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */ -#define GPIO_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */ -#define GPIO_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */ -#define GPIO_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */ -#define GPIO_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */ -#define GPIO_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */ -#define GPIO_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */ -#define GPIO_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */ -#define GPIO_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */ -#define GPIO_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */ -#define GPIO_Pin_All ((uint16_t)0xFFFF) /*!< All pins selected */ - -#define IS_GPIO_PIN(PIN) ((((PIN) & (uint16_t)0x00) == 0x00) && ((PIN) != (uint16_t)0x00)) - -#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \ - ((PIN) == GPIO_Pin_1) || \ - ((PIN) == GPIO_Pin_2) || \ - ((PIN) == GPIO_Pin_3) || \ - ((PIN) == GPIO_Pin_4) || \ - ((PIN) == GPIO_Pin_5) || \ - ((PIN) == GPIO_Pin_6) || \ - ((PIN) == GPIO_Pin_7) || \ - ((PIN) == GPIO_Pin_8) || \ - ((PIN) == GPIO_Pin_9) || \ - ((PIN) == GPIO_Pin_10) || \ - ((PIN) == GPIO_Pin_11) || \ - ((PIN) == GPIO_Pin_12) || \ - ((PIN) == GPIO_Pin_13) || \ - ((PIN) == GPIO_Pin_14) || \ - ((PIN) == GPIO_Pin_15)) - -/** - * @} - */ - -/** @defgroup GPIO_Remap_define - * @{ - */ - -#define GPIO_Remap_SPI1 ((uint32_t)0x00000001) /*!< SPI1 Alternate Function mapping */ -#define GPIO_Remap_I2C1 ((uint32_t)0x00000002) /*!< I2C1 Alternate Function mapping */ -#define GPIO_Remap_USART1 ((uint32_t)0x00000004) /*!< USART1 Alternate Function mapping */ -#define GPIO_Remap_USART2 ((uint32_t)0x00000008) /*!< USART2 Alternate Function mapping */ -#define GPIO_PartialRemap_USART3 ((uint32_t)0x00140010) /*!< USART3 Partial Alternate Function mapping */ -#define GPIO_FullRemap_USART3 ((uint32_t)0x00140030) /*!< USART3 Full Alternate Function mapping */ -#define GPIO_PartialRemap_TIM1 ((uint32_t)0x00160040) /*!< TIM1 Partial Alternate Function mapping */ -#define GPIO_FullRemap_TIM1 ((uint32_t)0x001600C0) /*!< TIM1 Full Alternate Function mapping */ -#define GPIO_PartialRemap1_TIM2 ((uint32_t)0x00180100) /*!< TIM2 Partial1 Alternate Function mapping */ -#define GPIO_PartialRemap2_TIM2 ((uint32_t)0x00180200) /*!< TIM2 Partial2 Alternate Function mapping */ -#define GPIO_FullRemap_TIM2 ((uint32_t)0x00180300) /*!< TIM2 Full Alternate Function mapping */ -#define GPIO_PartialRemap_TIM3 ((uint32_t)0x001A0800) /*!< TIM3 Partial Alternate Function mapping */ -#define GPIO_FullRemap_TIM3 ((uint32_t)0x001A0C00) /*!< TIM3 Full Alternate Function mapping */ -#define GPIO_Remap_TIM4 ((uint32_t)0x00001000) /*!< TIM4 Alternate Function mapping */ -#define GPIO_Remap1_CAN1 ((uint32_t)0x001D4000) /*!< CAN1 Alternate Function mapping */ -#define GPIO_Remap2_CAN1 ((uint32_t)0x001D6000) /*!< CAN1 Alternate Function mapping */ -#define GPIO_Remap_PD01 ((uint32_t)0x00008000) /*!< PD01 Alternate Function mapping */ -#define GPIO_Remap_TIM5CH4_LSI ((uint32_t)0x00200001) /*!< LSI connected to TIM5 Channel4 input capture for calibration */ -#define GPIO_Remap_ADC1_ETRGINJ ((uint32_t)0x00200002) /*!< ADC1 External Trigger Injected Conversion remapping */ -#define GPIO_Remap_ADC1_ETRGREG ((uint32_t)0x00200004) /*!< ADC1 External Trigger Regular Conversion remapping */ -#define GPIO_Remap_ADC2_ETRGINJ ((uint32_t)0x00200008) /*!< ADC2 External Trigger Injected Conversion remapping */ -#define GPIO_Remap_ADC2_ETRGREG ((uint32_t)0x00200010) /*!< ADC2 External Trigger Regular Conversion remapping */ -#define GPIO_Remap_ETH ((uint32_t)0x00200020) /*!< Ethernet remapping (only for Connectivity line devices) */ -#define GPIO_Remap_CAN2 ((uint32_t)0x00200040) /*!< CAN2 remapping (only for Connectivity line devices) */ -#define GPIO_Remap_SWJ_NoJTRST ((uint32_t)0x00300100) /*!< Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST */ -#define GPIO_Remap_SWJ_JTAGDisable ((uint32_t)0x00300200) /*!< JTAG-DP Disabled and SW-DP Enabled */ -#define GPIO_Remap_SWJ_Disable ((uint32_t)0x00300400) /*!< Full SWJ Disabled (JTAG-DP + SW-DP) */ -#define GPIO_Remap_SPI3 ((uint32_t)0x00201000) /*!< SPI3/I2S3 Alternate Function mapping (only for Connectivity line devices) */ -#define GPIO_Remap_TIM2ITR1_PTP_SOF ((uint32_t)0x00202000) /*!< Ethernet PTP output or USB OTG SOF (Start of Frame) connected - to TIM2 Internal Trigger 1 for calibration - (only for Connectivity line devices) */ -#define GPIO_Remap_PTP_PPS ((uint32_t)0x00204000) /*!< Ethernet MAC PPS_PTS output on PB05 (only for Connectivity line devices) */ - -#define GPIO_Remap_TIM15 ((uint32_t)0x80000001) /*!< TIM15 Alternate Function mapping (only for Value line devices) */ -#define GPIO_Remap_TIM16 ((uint32_t)0x80000002) /*!< TIM16 Alternate Function mapping (only for Value line devices) */ -#define GPIO_Remap_TIM17 ((uint32_t)0x80000004) /*!< TIM17 Alternate Function mapping (only for Value line devices) */ -#define GPIO_Remap_CEC ((uint32_t)0x80000008) /*!< CEC Alternate Function mapping (only for Value line devices) */ -#define GPIO_Remap_TIM1_DMA ((uint32_t)0x80000010) /*!< TIM1 DMA requests mapping (only for Value line devices) */ - -#define GPIO_Remap_TIM9 ((uint32_t)0x80000020) /*!< TIM9 Alternate Function mapping (only for XL-density devices) */ -#define GPIO_Remap_TIM10 ((uint32_t)0x80000040) /*!< TIM10 Alternate Function mapping (only for XL-density devices) */ -#define GPIO_Remap_TIM11 ((uint32_t)0x80000080) /*!< TIM11 Alternate Function mapping (only for XL-density devices) */ -#define GPIO_Remap_TIM13 ((uint32_t)0x80000100) /*!< TIM13 Alternate Function mapping (only for XL-density devices) */ -#define GPIO_Remap_TIM14 ((uint32_t)0x80000200) /*!< TIM14 Alternate Function mapping (only for XL-density devices) */ -#define GPIO_Remap_FSMC_NADV ((uint32_t)0x80000400) /*!< FSMC_NADV Alternate Function mapping (only for XL-density devices) */ - - -#define IS_GPIO_REMAP(REMAP) (((REMAP) == GPIO_Remap_SPI1) || ((REMAP) == GPIO_Remap_I2C1) || \ - ((REMAP) == GPIO_Remap_USART1) || ((REMAP) == GPIO_Remap_USART2) || \ - ((REMAP) == GPIO_PartialRemap_USART3) || ((REMAP) == GPIO_FullRemap_USART3) || \ - ((REMAP) == GPIO_PartialRemap_TIM1) || ((REMAP) == GPIO_FullRemap_TIM1) || \ - ((REMAP) == GPIO_PartialRemap1_TIM2) || ((REMAP) == GPIO_PartialRemap2_TIM2) || \ - ((REMAP) == GPIO_FullRemap_TIM2) || ((REMAP) == GPIO_PartialRemap_TIM3) || \ - ((REMAP) == GPIO_FullRemap_TIM3) || ((REMAP) == GPIO_Remap_TIM4) || \ - ((REMAP) == GPIO_Remap1_CAN1) || ((REMAP) == GPIO_Remap2_CAN1) || \ - ((REMAP) == GPIO_Remap_PD01) || ((REMAP) == GPIO_Remap_TIM5CH4_LSI) || \ - ((REMAP) == GPIO_Remap_ADC1_ETRGINJ) ||((REMAP) == GPIO_Remap_ADC1_ETRGREG) || \ - ((REMAP) == GPIO_Remap_ADC2_ETRGINJ) ||((REMAP) == GPIO_Remap_ADC2_ETRGREG) || \ - ((REMAP) == GPIO_Remap_ETH) ||((REMAP) == GPIO_Remap_CAN2) || \ - ((REMAP) == GPIO_Remap_SWJ_NoJTRST) || ((REMAP) == GPIO_Remap_SWJ_JTAGDisable) || \ - ((REMAP) == GPIO_Remap_SWJ_Disable)|| ((REMAP) == GPIO_Remap_SPI3) || \ - ((REMAP) == GPIO_Remap_TIM2ITR1_PTP_SOF) || ((REMAP) == GPIO_Remap_PTP_PPS) || \ - ((REMAP) == GPIO_Remap_TIM15) || ((REMAP) == GPIO_Remap_TIM16) || \ - ((REMAP) == GPIO_Remap_TIM17) || ((REMAP) == GPIO_Remap_CEC) || \ - ((REMAP) == GPIO_Remap_TIM1_DMA) || ((REMAP) == GPIO_Remap_TIM9) || \ - ((REMAP) == GPIO_Remap_TIM10) || ((REMAP) == GPIO_Remap_TIM11) || \ - ((REMAP) == GPIO_Remap_TIM13) || ((REMAP) == GPIO_Remap_TIM14) || \ - ((REMAP) == GPIO_Remap_FSMC_NADV)) - -/** - * @} - */ - -/** @defgroup GPIO_Port_Sources - * @{ - */ - -#define GPIO_PortSourceGPIOA ((uint8_t)0x00) -#define GPIO_PortSourceGPIOB ((uint8_t)0x01) -#define GPIO_PortSourceGPIOC ((uint8_t)0x02) -#define GPIO_PortSourceGPIOD ((uint8_t)0x03) -#define GPIO_PortSourceGPIOE ((uint8_t)0x04) -#define GPIO_PortSourceGPIOF ((uint8_t)0x05) -#define GPIO_PortSourceGPIOG ((uint8_t)0x06) -#define IS_GPIO_EVENTOUT_PORT_SOURCE(PORTSOURCE) (((PORTSOURCE) == GPIO_PortSourceGPIOA) || \ - ((PORTSOURCE) == GPIO_PortSourceGPIOB) || \ - ((PORTSOURCE) == GPIO_PortSourceGPIOC) || \ - ((PORTSOURCE) == GPIO_PortSourceGPIOD) || \ - ((PORTSOURCE) == GPIO_PortSourceGPIOE)) - -#define IS_GPIO_EXTI_PORT_SOURCE(PORTSOURCE) (((PORTSOURCE) == GPIO_PortSourceGPIOA) || \ - ((PORTSOURCE) == GPIO_PortSourceGPIOB) || \ - ((PORTSOURCE) == GPIO_PortSourceGPIOC) || \ - ((PORTSOURCE) == GPIO_PortSourceGPIOD) || \ - ((PORTSOURCE) == GPIO_PortSourceGPIOE) || \ - ((PORTSOURCE) == GPIO_PortSourceGPIOF) || \ - ((PORTSOURCE) == GPIO_PortSourceGPIOG)) - -/** - * @} - */ - -/** @defgroup GPIO_Pin_sources - * @{ - */ - -#define GPIO_PinSource0 ((uint8_t)0x00) -#define GPIO_PinSource1 ((uint8_t)0x01) -#define GPIO_PinSource2 ((uint8_t)0x02) -#define GPIO_PinSource3 ((uint8_t)0x03) -#define GPIO_PinSource4 ((uint8_t)0x04) -#define GPIO_PinSource5 ((uint8_t)0x05) -#define GPIO_PinSource6 ((uint8_t)0x06) -#define GPIO_PinSource7 ((uint8_t)0x07) -#define GPIO_PinSource8 ((uint8_t)0x08) -#define GPIO_PinSource9 ((uint8_t)0x09) -#define GPIO_PinSource10 ((uint8_t)0x0A) -#define GPIO_PinSource11 ((uint8_t)0x0B) -#define GPIO_PinSource12 ((uint8_t)0x0C) -#define GPIO_PinSource13 ((uint8_t)0x0D) -#define GPIO_PinSource14 ((uint8_t)0x0E) -#define GPIO_PinSource15 ((uint8_t)0x0F) - -#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \ - ((PINSOURCE) == GPIO_PinSource1) || \ - ((PINSOURCE) == GPIO_PinSource2) || \ - ((PINSOURCE) == GPIO_PinSource3) || \ - ((PINSOURCE) == GPIO_PinSource4) || \ - ((PINSOURCE) == GPIO_PinSource5) || \ - ((PINSOURCE) == GPIO_PinSource6) || \ - ((PINSOURCE) == GPIO_PinSource7) || \ - ((PINSOURCE) == GPIO_PinSource8) || \ - ((PINSOURCE) == GPIO_PinSource9) || \ - ((PINSOURCE) == GPIO_PinSource10) || \ - ((PINSOURCE) == GPIO_PinSource11) || \ - ((PINSOURCE) == GPIO_PinSource12) || \ - ((PINSOURCE) == GPIO_PinSource13) || \ - ((PINSOURCE) == GPIO_PinSource14) || \ - ((PINSOURCE) == GPIO_PinSource15)) - -/** - * @} - */ - -/** @defgroup Ethernet_Media_Interface - * @{ - */ -#define GPIO_ETH_MediaInterface_MII ((u32)0x00000000) -#define GPIO_ETH_MediaInterface_RMII ((u32)0x00000001) - -#define IS_GPIO_ETH_MEDIA_INTERFACE(INTERFACE) (((INTERFACE) == GPIO_ETH_MediaInterface_MII) || \ - ((INTERFACE) == GPIO_ETH_MediaInterface_RMII)) - -/** - * @} - */ -/** - * @} - */ - -/** @defgroup GPIO_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup GPIO_Exported_Functions - * @{ - */ - -void GPIO_DeInit(GPIO_TypeDef* GPIOx); -void GPIO_AFIODeInit(void); -void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); -void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); -uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); -uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); -void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); -void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); -void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource); -void GPIO_EventOutputCmd(FunctionalState NewState); -void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState); -void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource); -void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_GPIO_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_i2c.h b/example/libs_stm/inc/stm32f10x/stm32f10x_i2c.h deleted file mode 100644 index d9c9346bc..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_i2c.h +++ /dev/null @@ -1,670 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_i2c.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the I2C firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_I2C_H -#define __STM32F10x_I2C_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup I2C - * @{ - */ - -/** @defgroup I2C_Exported_Types - * @{ - */ - -/** - * @brief I2C Init structure definition - */ - -typedef struct -{ - uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency. - This parameter must be set to a value lower than 400kHz */ - - uint16_t I2C_Mode; /*!< Specifies the I2C mode. - This parameter can be a value of @ref I2C_mode */ - - uint16_t I2C_DutyCycle; /*!< Specifies the I2C fast mode duty cycle. - This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */ - - uint16_t I2C_OwnAddress1; /*!< Specifies the first device own address. - This parameter can be a 7-bit or 10-bit address. */ - - uint16_t I2C_Ack; /*!< Enables or disables the acknowledgement. - This parameter can be a value of @ref I2C_acknowledgement */ - - uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged. - This parameter can be a value of @ref I2C_acknowledged_address */ -}I2C_InitTypeDef; - -/** - * @} - */ - - -/** @defgroup I2C_Exported_Constants - * @{ - */ - -#define IS_I2C_ALL_PERIPH(PERIPH) (((PERIPH) == I2C1) || \ - ((PERIPH) == I2C2)) -/** @defgroup I2C_mode - * @{ - */ - -#define I2C_Mode_I2C ((uint16_t)0x0000) -#define I2C_Mode_SMBusDevice ((uint16_t)0x0002) -#define I2C_Mode_SMBusHost ((uint16_t)0x000A) -#define IS_I2C_MODE(MODE) (((MODE) == I2C_Mode_I2C) || \ - ((MODE) == I2C_Mode_SMBusDevice) || \ - ((MODE) == I2C_Mode_SMBusHost)) -/** - * @} - */ - -/** @defgroup I2C_duty_cycle_in_fast_mode - * @{ - */ - -#define I2C_DutyCycle_16_9 ((uint16_t)0x4000) /*!< I2C fast mode Tlow/Thigh = 16/9 */ -#define I2C_DutyCycle_2 ((uint16_t)0xBFFF) /*!< I2C fast mode Tlow/Thigh = 2 */ -#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DutyCycle_16_9) || \ - ((CYCLE) == I2C_DutyCycle_2)) -/** - * @} - */ - -/** @defgroup I2C_acknowledgement - * @{ - */ - -#define I2C_Ack_Enable ((uint16_t)0x0400) -#define I2C_Ack_Disable ((uint16_t)0x0000) -#define IS_I2C_ACK_STATE(STATE) (((STATE) == I2C_Ack_Enable) || \ - ((STATE) == I2C_Ack_Disable)) -/** - * @} - */ - -/** @defgroup I2C_transfer_direction - * @{ - */ - -#define I2C_Direction_Transmitter ((uint8_t)0x00) -#define I2C_Direction_Receiver ((uint8_t)0x01) -#define IS_I2C_DIRECTION(DIRECTION) (((DIRECTION) == I2C_Direction_Transmitter) || \ - ((DIRECTION) == I2C_Direction_Receiver)) -/** - * @} - */ - -/** @defgroup I2C_acknowledged_address - * @{ - */ - -#define I2C_AcknowledgedAddress_7bit ((uint16_t)0x4000) -#define I2C_AcknowledgedAddress_10bit ((uint16_t)0xC000) -#define IS_I2C_ACKNOWLEDGE_ADDRESS(ADDRESS) (((ADDRESS) == I2C_AcknowledgedAddress_7bit) || \ - ((ADDRESS) == I2C_AcknowledgedAddress_10bit)) -/** - * @} - */ - -/** @defgroup I2C_registers - * @{ - */ - -#define I2C_Register_CR1 ((uint8_t)0x00) -#define I2C_Register_CR2 ((uint8_t)0x04) -#define I2C_Register_OAR1 ((uint8_t)0x08) -#define I2C_Register_OAR2 ((uint8_t)0x0C) -#define I2C_Register_DR ((uint8_t)0x10) -#define I2C_Register_SR1 ((uint8_t)0x14) -#define I2C_Register_SR2 ((uint8_t)0x18) -#define I2C_Register_CCR ((uint8_t)0x1C) -#define I2C_Register_TRISE ((uint8_t)0x20) -#define IS_I2C_REGISTER(REGISTER) (((REGISTER) == I2C_Register_CR1) || \ - ((REGISTER) == I2C_Register_CR2) || \ - ((REGISTER) == I2C_Register_OAR1) || \ - ((REGISTER) == I2C_Register_OAR2) || \ - ((REGISTER) == I2C_Register_DR) || \ - ((REGISTER) == I2C_Register_SR1) || \ - ((REGISTER) == I2C_Register_SR2) || \ - ((REGISTER) == I2C_Register_CCR) || \ - ((REGISTER) == I2C_Register_TRISE)) -/** - * @} - */ - -/** @defgroup I2C_SMBus_alert_pin_level - * @{ - */ - -#define I2C_SMBusAlert_Low ((uint16_t)0x2000) -#define I2C_SMBusAlert_High ((uint16_t)0xDFFF) -#define IS_I2C_SMBUS_ALERT(ALERT) (((ALERT) == I2C_SMBusAlert_Low) || \ - ((ALERT) == I2C_SMBusAlert_High)) -/** - * @} - */ - -/** @defgroup I2C_PEC_position - * @{ - */ - -#define I2C_PECPosition_Next ((uint16_t)0x0800) -#define I2C_PECPosition_Current ((uint16_t)0xF7FF) -#define IS_I2C_PEC_POSITION(POSITION) (((POSITION) == I2C_PECPosition_Next) || \ - ((POSITION) == I2C_PECPosition_Current)) -/** - * @} - */ - -/** @defgroup I2C_interrupts_definition - * @{ - */ - -#define I2C_IT_BUF ((uint16_t)0x0400) -#define I2C_IT_EVT ((uint16_t)0x0200) -#define I2C_IT_ERR ((uint16_t)0x0100) -#define IS_I2C_CONFIG_IT(IT) ((((IT) & (uint16_t)0xF8FF) == 0x00) && ((IT) != 0x00)) -/** - * @} - */ - -/** @defgroup I2C_interrupts_definition - * @{ - */ - -#define I2C_IT_SMBALERT ((uint32_t)0x01008000) -#define I2C_IT_TIMEOUT ((uint32_t)0x01004000) -#define I2C_IT_PECERR ((uint32_t)0x01001000) -#define I2C_IT_OVR ((uint32_t)0x01000800) -#define I2C_IT_AF ((uint32_t)0x01000400) -#define I2C_IT_ARLO ((uint32_t)0x01000200) -#define I2C_IT_BERR ((uint32_t)0x01000100) -#define I2C_IT_TXE ((uint32_t)0x06000080) -#define I2C_IT_RXNE ((uint32_t)0x06000040) -#define I2C_IT_STOPF ((uint32_t)0x02000010) -#define I2C_IT_ADD10 ((uint32_t)0x02000008) -#define I2C_IT_BTF ((uint32_t)0x02000004) -#define I2C_IT_ADDR ((uint32_t)0x02000002) -#define I2C_IT_SB ((uint32_t)0x02000001) - -#define IS_I2C_CLEAR_IT(IT) ((((IT) & (uint16_t)0x20FF) == 0x00) && ((IT) != (uint16_t)0x00)) - -#define IS_I2C_GET_IT(IT) (((IT) == I2C_IT_SMBALERT) || ((IT) == I2C_IT_TIMEOUT) || \ - ((IT) == I2C_IT_PECERR) || ((IT) == I2C_IT_OVR) || \ - ((IT) == I2C_IT_AF) || ((IT) == I2C_IT_ARLO) || \ - ((IT) == I2C_IT_BERR) || ((IT) == I2C_IT_TXE) || \ - ((IT) == I2C_IT_RXNE) || ((IT) == I2C_IT_STOPF) || \ - ((IT) == I2C_IT_ADD10) || ((IT) == I2C_IT_BTF) || \ - ((IT) == I2C_IT_ADDR) || ((IT) == I2C_IT_SB)) -/** - * @} - */ - -/** @defgroup I2C_flags_definition - * @{ - */ - -/** - * @brief SR2 register flags - */ - -#define I2C_FLAG_DUALF ((uint32_t)0x00800000) -#define I2C_FLAG_SMBHOST ((uint32_t)0x00400000) -#define I2C_FLAG_SMBDEFAULT ((uint32_t)0x00200000) -#define I2C_FLAG_GENCALL ((uint32_t)0x00100000) -#define I2C_FLAG_TRA ((uint32_t)0x00040000) -#define I2C_FLAG_BUSY ((uint32_t)0x00020000) -#define I2C_FLAG_MSL ((uint32_t)0x00010000) - -/** - * @brief SR1 register flags - */ - -#define I2C_FLAG_SMBALERT ((uint32_t)0x10008000) -#define I2C_FLAG_TIMEOUT ((uint32_t)0x10004000) -#define I2C_FLAG_PECERR ((uint32_t)0x10001000) -#define I2C_FLAG_OVR ((uint32_t)0x10000800) -#define I2C_FLAG_AF ((uint32_t)0x10000400) -#define I2C_FLAG_ARLO ((uint32_t)0x10000200) -#define I2C_FLAG_BERR ((uint32_t)0x10000100) -#define I2C_FLAG_TXE ((uint32_t)0x10000080) -#define I2C_FLAG_RXNE ((uint32_t)0x10000040) -#define I2C_FLAG_STOPF ((uint32_t)0x10000010) -#define I2C_FLAG_ADD10 ((uint32_t)0x10000008) -#define I2C_FLAG_BTF ((uint32_t)0x10000004) -#define I2C_FLAG_ADDR ((uint32_t)0x10000002) -#define I2C_FLAG_SB ((uint32_t)0x10000001) - -#define IS_I2C_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0x20FF) == 0x00) && ((FLAG) != (uint16_t)0x00)) - -#define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_DUALF) || ((FLAG) == I2C_FLAG_SMBHOST) || \ - ((FLAG) == I2C_FLAG_SMBDEFAULT) || ((FLAG) == I2C_FLAG_GENCALL) || \ - ((FLAG) == I2C_FLAG_TRA) || ((FLAG) == I2C_FLAG_BUSY) || \ - ((FLAG) == I2C_FLAG_MSL) || ((FLAG) == I2C_FLAG_SMBALERT) || \ - ((FLAG) == I2C_FLAG_TIMEOUT) || ((FLAG) == I2C_FLAG_PECERR) || \ - ((FLAG) == I2C_FLAG_OVR) || ((FLAG) == I2C_FLAG_AF) || \ - ((FLAG) == I2C_FLAG_ARLO) || ((FLAG) == I2C_FLAG_BERR) || \ - ((FLAG) == I2C_FLAG_TXE) || ((FLAG) == I2C_FLAG_RXNE) || \ - ((FLAG) == I2C_FLAG_STOPF) || ((FLAG) == I2C_FLAG_ADD10) || \ - ((FLAG) == I2C_FLAG_BTF) || ((FLAG) == I2C_FLAG_ADDR) || \ - ((FLAG) == I2C_FLAG_SB)) -/** - * @} - */ - -/** @defgroup I2C_Events - * @{ - */ - -/*======================================== - - I2C Master Events (Events grouped in order of communication) - ==========================================*/ -/** - * @brief Communication start - * - * After sending the START condition (I2C_GenerateSTART() function) the master - * has to wait for this event. It means that the Start condition has been correctly - * released on the I2C bus (the bus is free, no other devices is communicating). - * - */ -/* --EV5 */ -#define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */ - -/** - * @brief Address Acknowledge - * - * After checking on EV5 (start condition correctly released on the bus), the - * master sends the address of the slave(s) with which it will communicate - * (I2C_Send7bitAddress() function, it also determines the direction of the communication: - * Master transmitter or Receiver). Then the master has to wait that a slave acknowledges - * his address. If an acknowledge is sent on the bus, one of the following events will - * be set: - * - * 1) In case of Master Receiver (7-bit addressing): the I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED - * event is set. - * - * 2) In case of Master Transmitter (7-bit addressing): the I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED - * is set - * - * 3) In case of 10-Bit addressing mode, the master (just after generating the START - * and checking on EV5) has to send the header of 10-bit addressing mode (I2C_SendData() - * function). Then master should wait on EV9. It means that the 10-bit addressing - * header has been correctly sent on the bus. Then master should send the second part of - * the 10-bit address (LSB) using the function I2C_Send7bitAddress(). Then master - * should wait for event EV6. - * - */ - -/* --EV6 */ -#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */ -#define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL and ADDR flags */ -/* --EV9 */ -#define I2C_EVENT_MASTER_MODE_ADDRESS10 ((uint32_t)0x00030008) /* BUSY, MSL and ADD10 flags */ - -/** - * @brief Communication events - * - * If a communication is established (START condition generated and slave address - * acknowledged) then the master has to check on one of the following events for - * communication procedures: - * - * 1) Master Receiver mode: The master has to wait on the event EV7 then to read - * the data received from the slave (I2C_ReceiveData() function). - * - * 2) Master Transmitter mode: The master has to send data (I2C_SendData() - * function) then to wait on event EV8 or EV8_2. - * These two events are similar: - * - EV8 means that the data has been written in the data register and is - * being shifted out. - * - EV8_2 means that the data has been physically shifted out and output - * on the bus. - * In most cases, using EV8 is sufficient for the application. - * Using EV8_2 leads to a slower communication but ensure more reliable test. - * EV8_2 is also more suitable than EV8 for testing on the last data transmission - * (before Stop condition generation). - * - * @note In case the user software does not guarantee that this event EV7 is - * managed before the current byte end of transfer, then user may check on EV7 - * and BTF flag at the same time (ie. (I2C_EVENT_MASTER_BYTE_RECEIVED | I2C_FLAG_BTF)). - * In this case the communication may be slower. - * - */ - -/* Master RECEIVER mode -----------------------------*/ -/* --EV7 */ -#define I2C_EVENT_MASTER_BYTE_RECEIVED ((uint32_t)0x00030040) /* BUSY, MSL and RXNE flags */ - -/* Master TRANSMITTER mode --------------------------*/ -/* --EV8 */ -#define I2C_EVENT_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */ -/* --EV8_2 */ -#define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags */ - - -/*======================================== - - I2C Slave Events (Events grouped in order of communication) - ==========================================*/ - -/** - * @brief Communication start events - * - * Wait on one of these events at the start of the communication. It means that - * the I2C peripheral detected a Start condition on the bus (generated by master - * device) followed by the peripheral address. The peripheral generates an ACK - * condition on the bus (if the acknowledge feature is enabled through function - * I2C_AcknowledgeConfig()) and the events listed above are set : - * - * 1) In normal case (only one address managed by the slave), when the address - * sent by the master matches the own address of the peripheral (configured by - * I2C_OwnAddress1 field) the I2C_EVENT_SLAVE_XXX_ADDRESS_MATCHED event is set - * (where XXX could be TRANSMITTER or RECEIVER). - * - * 2) In case the address sent by the master matches the second address of the - * peripheral (configured by the function I2C_OwnAddress2Config() and enabled - * by the function I2C_DualAddressCmd()) the events I2C_EVENT_SLAVE_XXX_SECONDADDRESS_MATCHED - * (where XXX could be TRANSMITTER or RECEIVER) are set. - * - * 3) In case the address sent by the master is General Call (address 0x00) and - * if the General Call is enabled for the peripheral (using function I2C_GeneralCallCmd()) - * the following event is set I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED. - * - */ - -/* --EV1 (all the events below are variants of EV1) */ -/* 1) Case of One Single Address managed by the slave */ -#define I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ((uint32_t)0x00020002) /* BUSY and ADDR flags */ -#define I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED ((uint32_t)0x00060082) /* TRA, BUSY, TXE and ADDR flags */ - -/* 2) Case of Dual address managed by the slave */ -#define I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED ((uint32_t)0x00820000) /* DUALF and BUSY flags */ -#define I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED ((uint32_t)0x00860080) /* DUALF, TRA, BUSY and TXE flags */ - -/* 3) Case of General Call enabled for the slave */ -#define I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED ((uint32_t)0x00120000) /* GENCALL and BUSY flags */ - -/** - * @brief Communication events - * - * Wait on one of these events when EV1 has already been checked and: - * - * - Slave RECEIVER mode: - * - EV2: When the application is expecting a data byte to be received. - * - EV4: When the application is expecting the end of the communication: master - * sends a stop condition and data transmission is stopped. - * - * - Slave Transmitter mode: - * - EV3: When a byte has been transmitted by the slave and the application is expecting - * the end of the byte transmission. The two events I2C_EVENT_SLAVE_BYTE_TRANSMITTED and - * I2C_EVENT_SLAVE_BYTE_TRANSMITTING are similar. The second one can optionally be - * used when the user software doesn't guarantee the EV3 is managed before the - * current byte end of tranfer. - * - EV3_2: When the master sends a NACK in order to tell slave that data transmission - * shall end (before sending the STOP condition). In this case slave has to stop sending - * data bytes and expect a Stop condition on the bus. - * - * @note In case the user software does not guarantee that the event EV2 is - * managed before the current byte end of transfer, then user may check on EV2 - * and BTF flag at the same time (ie. (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_BTF)). - * In this case the communication may be slower. - * - */ - -/* Slave RECEIVER mode --------------------------*/ -/* --EV2 */ -#define I2C_EVENT_SLAVE_BYTE_RECEIVED ((uint32_t)0x00020040) /* BUSY and RXNE flags */ -/* --EV4 */ -#define I2C_EVENT_SLAVE_STOP_DETECTED ((uint32_t)0x00000010) /* STOPF flag */ - -/* Slave TRANSMITTER mode -----------------------*/ -/* --EV3 */ -#define I2C_EVENT_SLAVE_BYTE_TRANSMITTED ((uint32_t)0x00060084) /* TRA, BUSY, TXE and BTF flags */ -#define I2C_EVENT_SLAVE_BYTE_TRANSMITTING ((uint32_t)0x00060080) /* TRA, BUSY and TXE flags */ -/* --EV3_2 */ -#define I2C_EVENT_SLAVE_ACK_FAILURE ((uint32_t)0x00000400) /* AF flag */ - -/*=========================== End of Events Description ==========================================*/ - -#define IS_I2C_EVENT(EVENT) (((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_BYTE_RECEIVED) || \ - ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF)) || \ - ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL)) || \ - ((EVENT) == I2C_EVENT_SLAVE_BYTE_TRANSMITTED) || \ - ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF)) || \ - ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL)) || \ - ((EVENT) == I2C_EVENT_SLAVE_STOP_DETECTED) || \ - ((EVENT) == I2C_EVENT_MASTER_MODE_SELECT) || \ - ((EVENT) == I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) || \ - ((EVENT) == I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) || \ - ((EVENT) == I2C_EVENT_MASTER_BYTE_RECEIVED) || \ - ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTED) || \ - ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTING) || \ - ((EVENT) == I2C_EVENT_MASTER_MODE_ADDRESS10) || \ - ((EVENT) == I2C_EVENT_SLAVE_ACK_FAILURE)) -/** - * @} - */ - -/** @defgroup I2C_own_address1 - * @{ - */ - -#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x3FF) -/** - * @} - */ - -/** @defgroup I2C_clock_speed - * @{ - */ - -#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) >= 0x1) && ((SPEED) <= 400000)) -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup I2C_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup I2C_Exported_Functions - * @{ - */ - -void I2C_DeInit(I2C_TypeDef* I2Cx); -void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct); -void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct); -void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address); -void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState); -void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data); -uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx); -void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction); -uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register); -void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert); -void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition); -void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState); -uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx); -void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle); - -/** - * @brief - **************************************************************************************** - * - * I2C State Monitoring Functions - * - **************************************************************************************** - * This I2C driver provides three different ways for I2C state monitoring - * depending on the application requirements and constraints: - * - * - * 1) Basic state monitoring: - * Using I2C_CheckEvent() function: - * It compares the status registers (SR1 and SR2) content to a given event - * (can be the combination of one or more flags). - * It returns SUCCESS if the current status includes the given flags - * and returns ERROR if one or more flags are missing in the current status. - * - When to use: - * - This function is suitable for most applications as well as for startup - * activity since the events are fully described in the product reference manual - * (RM0008). - * - It is also suitable for users who need to define their own events. - * - Limitations: - * - If an error occurs (ie. error flags are set besides to the monitored flags), - * the I2C_CheckEvent() function may return SUCCESS despite the communication - * hold or corrupted real state. - * In this case, it is advised to use error interrupts to monitor the error - * events and handle them in the interrupt IRQ handler. - * - * @note - * For error management, it is advised to use the following functions: - * - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR). - * - I2Cx_ER_IRQHandler() which is called when the error interurpt occurs. - * Where x is the peripheral instance (I2C1, I2C2 ...) - * - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into I2Cx_ER_IRQHandler() - * in order to determine which error occured. - * - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd() - * and/or I2C_GenerateStop() in order to clear the error flag and source, - * and return to correct communication status. - * - * - * 2) Advanced state monitoring: - * Using the function I2C_GetLastEvent() which returns the image of both status - * registers in a single word (uint32_t) (Status Register 2 value is shifted left - * by 16 bits and concatenated to Status Register 1). - * - When to use: - * - This function is suitable for the same applications above but it allows to - * overcome the limitations of I2C_GetFlagStatus() function (see below). - * The returned value could be compared to events already defined in the - * library (stm32f10x_i2c.h) or to custom values defined by user. - * - This function is suitable when multiple flags are monitored at the same time. - * - At the opposite of I2C_CheckEvent() function, this function allows user to - * choose when an event is accepted (when all events flags are set and no - * other flags are set or just when the needed flags are set like - * I2C_CheckEvent() function). - * - Limitations: - * - User may need to define his own events. - * - Same remark concerning the error management is applicable for this - * function if user decides to check only regular communication flags (and - * ignores error flags). - * - * - * 3) Flag-based state monitoring: - * Using the function I2C_GetFlagStatus() which simply returns the status of - * one single flag (ie. I2C_FLAG_RXNE ...). - * - When to use: - * - This function could be used for specific applications or in debug phase. - * - It is suitable when only one flag checking is needed (most I2C events - * are monitored through multiple flags). - * - Limitations: - * - When calling this function, the Status register is accessed. Some flags are - * cleared when the status register is accessed. So checking the status - * of one Flag, may clear other ones. - * - Function may need to be called twice or more in order to monitor one - * single event. - * - */ - -/** - * - * 1) Basic state monitoring - ******************************************************************************* - */ -ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT); -/** - * - * 2) Advanced state monitoring - ******************************************************************************* - */ -uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx); -/** - * - * 3) Flag-based state monitoring - ******************************************************************************* - */ -FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); -/** - * - ******************************************************************************* - */ - -void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); -ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT); -void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F10x_I2C_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_iwdg.h b/example/libs_stm/inc/stm32f10x/stm32f10x_iwdg.h deleted file mode 100644 index f9a26bf18..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_iwdg.h +++ /dev/null @@ -1,139 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_iwdg.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the IWDG - * firmware library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_IWDG_H -#define __STM32F10x_IWDG_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup IWDG - * @{ - */ - -/** @defgroup IWDG_Exported_Types - * @{ - */ - -/** - * @} - */ - -/** @defgroup IWDG_Exported_Constants - * @{ - */ - -/** @defgroup IWDG_WriteAccess - * @{ - */ - -#define IWDG_WriteAccess_Enable ((uint16_t)0x5555) -#define IWDG_WriteAccess_Disable ((uint16_t)0x0000) -#define IS_IWDG_WRITE_ACCESS(ACCESS) (((ACCESS) == IWDG_WriteAccess_Enable) || \ - ((ACCESS) == IWDG_WriteAccess_Disable)) -/** - * @} - */ - -/** @defgroup IWDG_prescaler - * @{ - */ - -#define IWDG_Prescaler_4 ((uint8_t)0x00) -#define IWDG_Prescaler_8 ((uint8_t)0x01) -#define IWDG_Prescaler_16 ((uint8_t)0x02) -#define IWDG_Prescaler_32 ((uint8_t)0x03) -#define IWDG_Prescaler_64 ((uint8_t)0x04) -#define IWDG_Prescaler_128 ((uint8_t)0x05) -#define IWDG_Prescaler_256 ((uint8_t)0x06) -#define IS_IWDG_PRESCALER(PRESCALER) (((PRESCALER) == IWDG_Prescaler_4) || \ - ((PRESCALER) == IWDG_Prescaler_8) || \ - ((PRESCALER) == IWDG_Prescaler_16) || \ - ((PRESCALER) == IWDG_Prescaler_32) || \ - ((PRESCALER) == IWDG_Prescaler_64) || \ - ((PRESCALER) == IWDG_Prescaler_128)|| \ - ((PRESCALER) == IWDG_Prescaler_256)) -/** - * @} - */ - -/** @defgroup IWDG_Flag - * @{ - */ - -#define IWDG_FLAG_PVU ((uint16_t)0x0001) -#define IWDG_FLAG_RVU ((uint16_t)0x0002) -#define IS_IWDG_FLAG(FLAG) (((FLAG) == IWDG_FLAG_PVU) || ((FLAG) == IWDG_FLAG_RVU)) -#define IS_IWDG_RELOAD(RELOAD) ((RELOAD) <= 0xFFF) -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup IWDG_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup IWDG_Exported_Functions - * @{ - */ - -void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess); -void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); -void IWDG_SetReload(uint16_t Reload); -void IWDG_ReloadCounter(void); -void IWDG_Enable(void); -FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_IWDG_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_pwr.h b/example/libs_stm/inc/stm32f10x/stm32f10x_pwr.h deleted file mode 100644 index ce168da23..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_pwr.h +++ /dev/null @@ -1,155 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_pwr.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the PWR firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_PWR_H -#define __STM32F10x_PWR_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup PWR - * @{ - */ - -/** @defgroup PWR_Exported_Types - * @{ - */ - -/** - * @} - */ - -/** @defgroup PWR_Exported_Constants - * @{ - */ - -/** @defgroup PVD_detection_level - * @{ - */ - -#define PWR_PVDLevel_2V2 ((uint32_t)0x00000000) -#define PWR_PVDLevel_2V3 ((uint32_t)0x00000020) -#define PWR_PVDLevel_2V4 ((uint32_t)0x00000040) -#define PWR_PVDLevel_2V5 ((uint32_t)0x00000060) -#define PWR_PVDLevel_2V6 ((uint32_t)0x00000080) -#define PWR_PVDLevel_2V7 ((uint32_t)0x000000A0) -#define PWR_PVDLevel_2V8 ((uint32_t)0x000000C0) -#define PWR_PVDLevel_2V9 ((uint32_t)0x000000E0) -#define IS_PWR_PVD_LEVEL(LEVEL) (((LEVEL) == PWR_PVDLevel_2V2) || ((LEVEL) == PWR_PVDLevel_2V3)|| \ - ((LEVEL) == PWR_PVDLevel_2V4) || ((LEVEL) == PWR_PVDLevel_2V5)|| \ - ((LEVEL) == PWR_PVDLevel_2V6) || ((LEVEL) == PWR_PVDLevel_2V7)|| \ - ((LEVEL) == PWR_PVDLevel_2V8) || ((LEVEL) == PWR_PVDLevel_2V9)) -/** - * @} - */ - -/** @defgroup Regulator_state_is_STOP_mode - * @{ - */ - -#define PWR_Regulator_ON ((uint32_t)0x00000000) -#define PWR_Regulator_LowPower ((uint32_t)0x00000001) -#define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_Regulator_ON) || \ - ((REGULATOR) == PWR_Regulator_LowPower)) -/** - * @} - */ - -/** @defgroup STOP_mode_entry - * @{ - */ - -#define PWR_STOPEntry_WFI ((uint8_t)0x01) -#define PWR_STOPEntry_WFE ((uint8_t)0x02) -#define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPEntry_WFI) || ((ENTRY) == PWR_STOPEntry_WFE)) - -/** - * @} - */ - -/** @defgroup PWR_Flag - * @{ - */ - -#define PWR_FLAG_WU ((uint32_t)0x00000001) -#define PWR_FLAG_SB ((uint32_t)0x00000002) -#define PWR_FLAG_PVDO ((uint32_t)0x00000004) -#define IS_PWR_GET_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB) || \ - ((FLAG) == PWR_FLAG_PVDO)) - -#define IS_PWR_CLEAR_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB)) -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup PWR_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup PWR_Exported_Functions - * @{ - */ - -void PWR_DeInit(void); -void PWR_BackupAccessCmd(FunctionalState NewState); -void PWR_PVDCmd(FunctionalState NewState); -void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel); -void PWR_WakeUpPinCmd(FunctionalState NewState); -void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry); -void PWR_EnterSTANDBYMode(void); -FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG); -void PWR_ClearFlag(uint32_t PWR_FLAG); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_PWR_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_rcc.h b/example/libs_stm/inc/stm32f10x/stm32f10x_rcc.h deleted file mode 100644 index 19afe3e45..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_rcc.h +++ /dev/null @@ -1,726 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_rcc.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the RCC firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_RCC_H -#define __STM32F10x_RCC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup RCC - * @{ - */ - -/** @defgroup RCC_Exported_Types - * @{ - */ - -typedef struct -{ - uint32_t SYSCLK_Frequency; /*!< returns SYSCLK clock frequency expressed in Hz */ - uint32_t HCLK_Frequency; /*!< returns HCLK clock frequency expressed in Hz */ - uint32_t PCLK1_Frequency; /*!< returns PCLK1 clock frequency expressed in Hz */ - uint32_t PCLK2_Frequency; /*!< returns PCLK2 clock frequency expressed in Hz */ - uint32_t ADCCLK_Frequency; /*!< returns ADCCLK clock frequency expressed in Hz */ -}RCC_ClocksTypeDef; - -/** - * @} - */ - -/** @defgroup RCC_Exported_Constants - * @{ - */ - -/** @defgroup HSE_configuration - * @{ - */ - -#define RCC_HSE_OFF ((uint32_t)0x00000000) -#define RCC_HSE_ON ((uint32_t)0x00010000) -#define RCC_HSE_Bypass ((uint32_t)0x00040000) -#define IS_RCC_HSE(HSE) (((HSE) == RCC_HSE_OFF) || ((HSE) == RCC_HSE_ON) || \ - ((HSE) == RCC_HSE_Bypass)) - -/** - * @} - */ - -/** @defgroup PLL_entry_clock_source - * @{ - */ - -#define RCC_PLLSource_HSI_Div2 ((uint32_t)0x00000000) - -#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_CL) - #define RCC_PLLSource_HSE_Div1 ((uint32_t)0x00010000) - #define RCC_PLLSource_HSE_Div2 ((uint32_t)0x00030000) - #define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI_Div2) || \ - ((SOURCE) == RCC_PLLSource_HSE_Div1) || \ - ((SOURCE) == RCC_PLLSource_HSE_Div2)) -#else - #define RCC_PLLSource_PREDIV1 ((uint32_t)0x00010000) - #define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI_Div2) || \ - ((SOURCE) == RCC_PLLSource_PREDIV1)) -#endif /* STM32F10X_CL */ - -/** - * @} - */ - -/** @defgroup PLL_multiplication_factor - * @{ - */ -#ifndef STM32F10X_CL - #define RCC_PLLMul_2 ((uint32_t)0x00000000) - #define RCC_PLLMul_3 ((uint32_t)0x00040000) - #define RCC_PLLMul_4 ((uint32_t)0x00080000) - #define RCC_PLLMul_5 ((uint32_t)0x000C0000) - #define RCC_PLLMul_6 ((uint32_t)0x00100000) - #define RCC_PLLMul_7 ((uint32_t)0x00140000) - #define RCC_PLLMul_8 ((uint32_t)0x00180000) - #define RCC_PLLMul_9 ((uint32_t)0x001C0000) - #define RCC_PLLMul_10 ((uint32_t)0x00200000) - #define RCC_PLLMul_11 ((uint32_t)0x00240000) - #define RCC_PLLMul_12 ((uint32_t)0x00280000) - #define RCC_PLLMul_13 ((uint32_t)0x002C0000) - #define RCC_PLLMul_14 ((uint32_t)0x00300000) - #define RCC_PLLMul_15 ((uint32_t)0x00340000) - #define RCC_PLLMul_16 ((uint32_t)0x00380000) - #define IS_RCC_PLL_MUL(MUL) (((MUL) == RCC_PLLMul_2) || ((MUL) == RCC_PLLMul_3) || \ - ((MUL) == RCC_PLLMul_4) || ((MUL) == RCC_PLLMul_5) || \ - ((MUL) == RCC_PLLMul_6) || ((MUL) == RCC_PLLMul_7) || \ - ((MUL) == RCC_PLLMul_8) || ((MUL) == RCC_PLLMul_9) || \ - ((MUL) == RCC_PLLMul_10) || ((MUL) == RCC_PLLMul_11) || \ - ((MUL) == RCC_PLLMul_12) || ((MUL) == RCC_PLLMul_13) || \ - ((MUL) == RCC_PLLMul_14) || ((MUL) == RCC_PLLMul_15) || \ - ((MUL) == RCC_PLLMul_16)) - -#else - #define RCC_PLLMul_4 ((uint32_t)0x00080000) - #define RCC_PLLMul_5 ((uint32_t)0x000C0000) - #define RCC_PLLMul_6 ((uint32_t)0x00100000) - #define RCC_PLLMul_7 ((uint32_t)0x00140000) - #define RCC_PLLMul_8 ((uint32_t)0x00180000) - #define RCC_PLLMul_9 ((uint32_t)0x001C0000) - #define RCC_PLLMul_6_5 ((uint32_t)0x00340000) - - #define IS_RCC_PLL_MUL(MUL) (((MUL) == RCC_PLLMul_4) || ((MUL) == RCC_PLLMul_5) || \ - ((MUL) == RCC_PLLMul_6) || ((MUL) == RCC_PLLMul_7) || \ - ((MUL) == RCC_PLLMul_8) || ((MUL) == RCC_PLLMul_9) || \ - ((MUL) == RCC_PLLMul_6_5)) -#endif /* STM32F10X_CL */ -/** - * @} - */ - -/** @defgroup PREDIV1_division_factor - * @{ - */ -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_CL) - #define RCC_PREDIV1_Div1 ((uint32_t)0x00000000) - #define RCC_PREDIV1_Div2 ((uint32_t)0x00000001) - #define RCC_PREDIV1_Div3 ((uint32_t)0x00000002) - #define RCC_PREDIV1_Div4 ((uint32_t)0x00000003) - #define RCC_PREDIV1_Div5 ((uint32_t)0x00000004) - #define RCC_PREDIV1_Div6 ((uint32_t)0x00000005) - #define RCC_PREDIV1_Div7 ((uint32_t)0x00000006) - #define RCC_PREDIV1_Div8 ((uint32_t)0x00000007) - #define RCC_PREDIV1_Div9 ((uint32_t)0x00000008) - #define RCC_PREDIV1_Div10 ((uint32_t)0x00000009) - #define RCC_PREDIV1_Div11 ((uint32_t)0x0000000A) - #define RCC_PREDIV1_Div12 ((uint32_t)0x0000000B) - #define RCC_PREDIV1_Div13 ((uint32_t)0x0000000C) - #define RCC_PREDIV1_Div14 ((uint32_t)0x0000000D) - #define RCC_PREDIV1_Div15 ((uint32_t)0x0000000E) - #define RCC_PREDIV1_Div16 ((uint32_t)0x0000000F) - - #define IS_RCC_PREDIV1(PREDIV1) (((PREDIV1) == RCC_PREDIV1_Div1) || ((PREDIV1) == RCC_PREDIV1_Div2) || \ - ((PREDIV1) == RCC_PREDIV1_Div3) || ((PREDIV1) == RCC_PREDIV1_Div4) || \ - ((PREDIV1) == RCC_PREDIV1_Div5) || ((PREDIV1) == RCC_PREDIV1_Div6) || \ - ((PREDIV1) == RCC_PREDIV1_Div7) || ((PREDIV1) == RCC_PREDIV1_Div8) || \ - ((PREDIV1) == RCC_PREDIV1_Div9) || ((PREDIV1) == RCC_PREDIV1_Div10) || \ - ((PREDIV1) == RCC_PREDIV1_Div11) || ((PREDIV1) == RCC_PREDIV1_Div12) || \ - ((PREDIV1) == RCC_PREDIV1_Div13) || ((PREDIV1) == RCC_PREDIV1_Div14) || \ - ((PREDIV1) == RCC_PREDIV1_Div15) || ((PREDIV1) == RCC_PREDIV1_Div16)) -#endif -/** - * @} - */ - - -/** @defgroup PREDIV1_clock_source - * @{ - */ -#ifdef STM32F10X_CL -/* PREDIV1 clock source (for STM32 connectivity line devices) */ - #define RCC_PREDIV1_Source_HSE ((uint32_t)0x00000000) - #define RCC_PREDIV1_Source_PLL2 ((uint32_t)0x00010000) - - #define IS_RCC_PREDIV1_SOURCE(SOURCE) (((SOURCE) == RCC_PREDIV1_Source_HSE) || \ - ((SOURCE) == RCC_PREDIV1_Source_PLL2)) -#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) -/* PREDIV1 clock source (for STM32 Value line devices) */ - #define RCC_PREDIV1_Source_HSE ((uint32_t)0x00000000) - - #define IS_RCC_PREDIV1_SOURCE(SOURCE) (((SOURCE) == RCC_PREDIV1_Source_HSE)) -#endif -/** - * @} - */ - -#ifdef STM32F10X_CL -/** @defgroup PREDIV2_division_factor - * @{ - */ - - #define RCC_PREDIV2_Div1 ((uint32_t)0x00000000) - #define RCC_PREDIV2_Div2 ((uint32_t)0x00000010) - #define RCC_PREDIV2_Div3 ((uint32_t)0x00000020) - #define RCC_PREDIV2_Div4 ((uint32_t)0x00000030) - #define RCC_PREDIV2_Div5 ((uint32_t)0x00000040) - #define RCC_PREDIV2_Div6 ((uint32_t)0x00000050) - #define RCC_PREDIV2_Div7 ((uint32_t)0x00000060) - #define RCC_PREDIV2_Div8 ((uint32_t)0x00000070) - #define RCC_PREDIV2_Div9 ((uint32_t)0x00000080) - #define RCC_PREDIV2_Div10 ((uint32_t)0x00000090) - #define RCC_PREDIV2_Div11 ((uint32_t)0x000000A0) - #define RCC_PREDIV2_Div12 ((uint32_t)0x000000B0) - #define RCC_PREDIV2_Div13 ((uint32_t)0x000000C0) - #define RCC_PREDIV2_Div14 ((uint32_t)0x000000D0) - #define RCC_PREDIV2_Div15 ((uint32_t)0x000000E0) - #define RCC_PREDIV2_Div16 ((uint32_t)0x000000F0) - - #define IS_RCC_PREDIV2(PREDIV2) (((PREDIV2) == RCC_PREDIV2_Div1) || ((PREDIV2) == RCC_PREDIV2_Div2) || \ - ((PREDIV2) == RCC_PREDIV2_Div3) || ((PREDIV2) == RCC_PREDIV2_Div4) || \ - ((PREDIV2) == RCC_PREDIV2_Div5) || ((PREDIV2) == RCC_PREDIV2_Div6) || \ - ((PREDIV2) == RCC_PREDIV2_Div7) || ((PREDIV2) == RCC_PREDIV2_Div8) || \ - ((PREDIV2) == RCC_PREDIV2_Div9) || ((PREDIV2) == RCC_PREDIV2_Div10) || \ - ((PREDIV2) == RCC_PREDIV2_Div11) || ((PREDIV2) == RCC_PREDIV2_Div12) || \ - ((PREDIV2) == RCC_PREDIV2_Div13) || ((PREDIV2) == RCC_PREDIV2_Div14) || \ - ((PREDIV2) == RCC_PREDIV2_Div15) || ((PREDIV2) == RCC_PREDIV2_Div16)) -/** - * @} - */ - - -/** @defgroup PLL2_multiplication_factor - * @{ - */ - - #define RCC_PLL2Mul_8 ((uint32_t)0x00000600) - #define RCC_PLL2Mul_9 ((uint32_t)0x00000700) - #define RCC_PLL2Mul_10 ((uint32_t)0x00000800) - #define RCC_PLL2Mul_11 ((uint32_t)0x00000900) - #define RCC_PLL2Mul_12 ((uint32_t)0x00000A00) - #define RCC_PLL2Mul_13 ((uint32_t)0x00000B00) - #define RCC_PLL2Mul_14 ((uint32_t)0x00000C00) - #define RCC_PLL2Mul_16 ((uint32_t)0x00000E00) - #define RCC_PLL2Mul_20 ((uint32_t)0x00000F00) - - #define IS_RCC_PLL2_MUL(MUL) (((MUL) == RCC_PLL2Mul_8) || ((MUL) == RCC_PLL2Mul_9) || \ - ((MUL) == RCC_PLL2Mul_10) || ((MUL) == RCC_PLL2Mul_11) || \ - ((MUL) == RCC_PLL2Mul_12) || ((MUL) == RCC_PLL2Mul_13) || \ - ((MUL) == RCC_PLL2Mul_14) || ((MUL) == RCC_PLL2Mul_16) || \ - ((MUL) == RCC_PLL2Mul_20)) -/** - * @} - */ - - -/** @defgroup PLL3_multiplication_factor - * @{ - */ - - #define RCC_PLL3Mul_8 ((uint32_t)0x00006000) - #define RCC_PLL3Mul_9 ((uint32_t)0x00007000) - #define RCC_PLL3Mul_10 ((uint32_t)0x00008000) - #define RCC_PLL3Mul_11 ((uint32_t)0x00009000) - #define RCC_PLL3Mul_12 ((uint32_t)0x0000A000) - #define RCC_PLL3Mul_13 ((uint32_t)0x0000B000) - #define RCC_PLL3Mul_14 ((uint32_t)0x0000C000) - #define RCC_PLL3Mul_16 ((uint32_t)0x0000E000) - #define RCC_PLL3Mul_20 ((uint32_t)0x0000F000) - - #define IS_RCC_PLL3_MUL(MUL) (((MUL) == RCC_PLL3Mul_8) || ((MUL) == RCC_PLL3Mul_9) || \ - ((MUL) == RCC_PLL3Mul_10) || ((MUL) == RCC_PLL3Mul_11) || \ - ((MUL) == RCC_PLL3Mul_12) || ((MUL) == RCC_PLL3Mul_13) || \ - ((MUL) == RCC_PLL3Mul_14) || ((MUL) == RCC_PLL3Mul_16) || \ - ((MUL) == RCC_PLL3Mul_20)) -/** - * @} - */ - -#endif /* STM32F10X_CL */ - - -/** @defgroup System_clock_source - * @{ - */ - -#define RCC_SYSCLKSource_HSI ((uint32_t)0x00000000) -#define RCC_SYSCLKSource_HSE ((uint32_t)0x00000001) -#define RCC_SYSCLKSource_PLLCLK ((uint32_t)0x00000002) -#define IS_RCC_SYSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSource_HSI) || \ - ((SOURCE) == RCC_SYSCLKSource_HSE) || \ - ((SOURCE) == RCC_SYSCLKSource_PLLCLK)) -/** - * @} - */ - -/** @defgroup AHB_clock_source - * @{ - */ - -#define RCC_SYSCLK_Div1 ((uint32_t)0x00000000) -#define RCC_SYSCLK_Div2 ((uint32_t)0x00000080) -#define RCC_SYSCLK_Div4 ((uint32_t)0x00000090) -#define RCC_SYSCLK_Div8 ((uint32_t)0x000000A0) -#define RCC_SYSCLK_Div16 ((uint32_t)0x000000B0) -#define RCC_SYSCLK_Div64 ((uint32_t)0x000000C0) -#define RCC_SYSCLK_Div128 ((uint32_t)0x000000D0) -#define RCC_SYSCLK_Div256 ((uint32_t)0x000000E0) -#define RCC_SYSCLK_Div512 ((uint32_t)0x000000F0) -#define IS_RCC_HCLK(HCLK) (((HCLK) == RCC_SYSCLK_Div1) || ((HCLK) == RCC_SYSCLK_Div2) || \ - ((HCLK) == RCC_SYSCLK_Div4) || ((HCLK) == RCC_SYSCLK_Div8) || \ - ((HCLK) == RCC_SYSCLK_Div16) || ((HCLK) == RCC_SYSCLK_Div64) || \ - ((HCLK) == RCC_SYSCLK_Div128) || ((HCLK) == RCC_SYSCLK_Div256) || \ - ((HCLK) == RCC_SYSCLK_Div512)) -/** - * @} - */ - -/** @defgroup APB1_APB2_clock_source - * @{ - */ - -#define RCC_HCLK_Div1 ((uint32_t)0x00000000) -#define RCC_HCLK_Div2 ((uint32_t)0x00000400) -#define RCC_HCLK_Div4 ((uint32_t)0x00000500) -#define RCC_HCLK_Div8 ((uint32_t)0x00000600) -#define RCC_HCLK_Div16 ((uint32_t)0x00000700) -#define IS_RCC_PCLK(PCLK) (((PCLK) == RCC_HCLK_Div1) || ((PCLK) == RCC_HCLK_Div2) || \ - ((PCLK) == RCC_HCLK_Div4) || ((PCLK) == RCC_HCLK_Div8) || \ - ((PCLK) == RCC_HCLK_Div16)) -/** - * @} - */ - -/** @defgroup RCC_Interrupt_source - * @{ - */ - -#define RCC_IT_LSIRDY ((uint8_t)0x01) -#define RCC_IT_LSERDY ((uint8_t)0x02) -#define RCC_IT_HSIRDY ((uint8_t)0x04) -#define RCC_IT_HSERDY ((uint8_t)0x08) -#define RCC_IT_PLLRDY ((uint8_t)0x10) -#define RCC_IT_CSS ((uint8_t)0x80) - -#ifndef STM32F10X_CL - #define IS_RCC_IT(IT) ((((IT) & (uint8_t)0xE0) == 0x00) && ((IT) != 0x00)) - #define IS_RCC_GET_IT(IT) (((IT) == RCC_IT_LSIRDY) || ((IT) == RCC_IT_LSERDY) || \ - ((IT) == RCC_IT_HSIRDY) || ((IT) == RCC_IT_HSERDY) || \ - ((IT) == RCC_IT_PLLRDY) || ((IT) == RCC_IT_CSS)) - #define IS_RCC_CLEAR_IT(IT) ((((IT) & (uint8_t)0x60) == 0x00) && ((IT) != 0x00)) -#else - #define RCC_IT_PLL2RDY ((uint8_t)0x20) - #define RCC_IT_PLL3RDY ((uint8_t)0x40) - #define IS_RCC_IT(IT) ((((IT) & (uint8_t)0x80) == 0x00) && ((IT) != 0x00)) - #define IS_RCC_GET_IT(IT) (((IT) == RCC_IT_LSIRDY) || ((IT) == RCC_IT_LSERDY) || \ - ((IT) == RCC_IT_HSIRDY) || ((IT) == RCC_IT_HSERDY) || \ - ((IT) == RCC_IT_PLLRDY) || ((IT) == RCC_IT_CSS) || \ - ((IT) == RCC_IT_PLL2RDY) || ((IT) == RCC_IT_PLL3RDY)) - #define IS_RCC_CLEAR_IT(IT) ((IT) != 0x00) -#endif /* STM32F10X_CL */ - - -/** - * @} - */ - -#ifndef STM32F10X_CL -/** @defgroup USB_Device_clock_source - * @{ - */ - - #define RCC_USBCLKSource_PLLCLK_1Div5 ((uint8_t)0x00) - #define RCC_USBCLKSource_PLLCLK_Div1 ((uint8_t)0x01) - - #define IS_RCC_USBCLK_SOURCE(SOURCE) (((SOURCE) == RCC_USBCLKSource_PLLCLK_1Div5) || \ - ((SOURCE) == RCC_USBCLKSource_PLLCLK_Div1)) -/** - * @} - */ -#else -/** @defgroup USB_OTG_FS_clock_source - * @{ - */ - #define RCC_OTGFSCLKSource_PLLVCO_Div3 ((uint8_t)0x00) - #define RCC_OTGFSCLKSource_PLLVCO_Div2 ((uint8_t)0x01) - - #define IS_RCC_OTGFSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_OTGFSCLKSource_PLLVCO_Div3) || \ - ((SOURCE) == RCC_OTGFSCLKSource_PLLVCO_Div2)) -/** - * @} - */ -#endif /* STM32F10X_CL */ - - -#ifdef STM32F10X_CL -/** @defgroup I2S2_clock_source - * @{ - */ - #define RCC_I2S2CLKSource_SYSCLK ((uint8_t)0x00) - #define RCC_I2S2CLKSource_PLL3_VCO ((uint8_t)0x01) - - #define IS_RCC_I2S2CLK_SOURCE(SOURCE) (((SOURCE) == RCC_I2S2CLKSource_SYSCLK) || \ - ((SOURCE) == RCC_I2S2CLKSource_PLL3_VCO)) -/** - * @} - */ - -/** @defgroup I2S3_clock_source - * @{ - */ - #define RCC_I2S3CLKSource_SYSCLK ((uint8_t)0x00) - #define RCC_I2S3CLKSource_PLL3_VCO ((uint8_t)0x01) - - #define IS_RCC_I2S3CLK_SOURCE(SOURCE) (((SOURCE) == RCC_I2S3CLKSource_SYSCLK) || \ - ((SOURCE) == RCC_I2S3CLKSource_PLL3_VCO)) -/** - * @} - */ -#endif /* STM32F10X_CL */ - - -/** @defgroup ADC_clock_source - * @{ - */ - -#define RCC_PCLK2_Div2 ((uint32_t)0x00000000) -#define RCC_PCLK2_Div4 ((uint32_t)0x00004000) -#define RCC_PCLK2_Div6 ((uint32_t)0x00008000) -#define RCC_PCLK2_Div8 ((uint32_t)0x0000C000) -#define IS_RCC_ADCCLK(ADCCLK) (((ADCCLK) == RCC_PCLK2_Div2) || ((ADCCLK) == RCC_PCLK2_Div4) || \ - ((ADCCLK) == RCC_PCLK2_Div6) || ((ADCCLK) == RCC_PCLK2_Div8)) -/** - * @} - */ - -/** @defgroup LSE_configuration - * @{ - */ - -#define RCC_LSE_OFF ((uint8_t)0x00) -#define RCC_LSE_ON ((uint8_t)0x01) -#define RCC_LSE_Bypass ((uint8_t)0x04) -#define IS_RCC_LSE(LSE) (((LSE) == RCC_LSE_OFF) || ((LSE) == RCC_LSE_ON) || \ - ((LSE) == RCC_LSE_Bypass)) -/** - * @} - */ - -/** @defgroup RTC_clock_source - * @{ - */ - -#define RCC_RTCCLKSource_LSE ((uint32_t)0x00000100) -#define RCC_RTCCLKSource_LSI ((uint32_t)0x00000200) -#define RCC_RTCCLKSource_HSE_Div128 ((uint32_t)0x00000300) -#define IS_RCC_RTCCLK_SOURCE(SOURCE) (((SOURCE) == RCC_RTCCLKSource_LSE) || \ - ((SOURCE) == RCC_RTCCLKSource_LSI) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div128)) -/** - * @} - */ - -/** @defgroup AHB_peripheral - * @{ - */ - -#define RCC_AHBPeriph_DMA1 ((uint32_t)0x00000001) -#define RCC_AHBPeriph_DMA2 ((uint32_t)0x00000002) -#define RCC_AHBPeriph_SRAM ((uint32_t)0x00000004) -#define RCC_AHBPeriph_FLITF ((uint32_t)0x00000010) -#define RCC_AHBPeriph_CRC ((uint32_t)0x00000040) - -#ifndef STM32F10X_CL - #define RCC_AHBPeriph_FSMC ((uint32_t)0x00000100) - #define RCC_AHBPeriph_SDIO ((uint32_t)0x00000400) - #define IS_RCC_AHB_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFAA8) == 0x00) && ((PERIPH) != 0x00)) -#else - #define RCC_AHBPeriph_OTG_FS ((uint32_t)0x00001000) - #define RCC_AHBPeriph_ETH_MAC ((uint32_t)0x00004000) - #define RCC_AHBPeriph_ETH_MAC_Tx ((uint32_t)0x00008000) - #define RCC_AHBPeriph_ETH_MAC_Rx ((uint32_t)0x00010000) - - #define IS_RCC_AHB_PERIPH(PERIPH) ((((PERIPH) & 0xFFFE2FA8) == 0x00) && ((PERIPH) != 0x00)) - #define IS_RCC_AHB_PERIPH_RESET(PERIPH) ((((PERIPH) & 0xFFFFAFFF) == 0x00) && ((PERIPH) != 0x00)) -#endif /* STM32F10X_CL */ -/** - * @} - */ - -/** @defgroup APB2_peripheral - * @{ - */ - -#define RCC_APB2Periph_AFIO ((uint32_t)0x00000001) -#define RCC_APB2Periph_GPIOA ((uint32_t)0x00000004) -#define RCC_APB2Periph_GPIOB ((uint32_t)0x00000008) -#define RCC_APB2Periph_GPIOC ((uint32_t)0x00000010) -#define RCC_APB2Periph_GPIOD ((uint32_t)0x00000020) -#define RCC_APB2Periph_GPIOE ((uint32_t)0x00000040) -#define RCC_APB2Periph_GPIOF ((uint32_t)0x00000080) -#define RCC_APB2Periph_GPIOG ((uint32_t)0x00000100) -#define RCC_APB2Periph_ADC1 ((uint32_t)0x00000200) -#define RCC_APB2Periph_ADC2 ((uint32_t)0x00000400) -#define RCC_APB2Periph_TIM1 ((uint32_t)0x00000800) -#define RCC_APB2Periph_SPI1 ((uint32_t)0x00001000) -#define RCC_APB2Periph_TIM8 ((uint32_t)0x00002000) -#define RCC_APB2Periph_USART1 ((uint32_t)0x00004000) -#define RCC_APB2Periph_ADC3 ((uint32_t)0x00008000) -#define RCC_APB2Periph_TIM15 ((uint32_t)0x00010000) -#define RCC_APB2Periph_TIM16 ((uint32_t)0x00020000) -#define RCC_APB2Periph_TIM17 ((uint32_t)0x00040000) -#define RCC_APB2Periph_TIM9 ((uint32_t)0x00080000) -#define RCC_APB2Periph_TIM10 ((uint32_t)0x00100000) -#define RCC_APB2Periph_TIM11 ((uint32_t)0x00200000) - -#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFC00002) == 0x00) && ((PERIPH) != 0x00)) -/** - * @} - */ - -/** @defgroup APB1_peripheral - * @{ - */ - -#define RCC_APB1Periph_TIM2 ((uint32_t)0x00000001) -#define RCC_APB1Periph_TIM3 ((uint32_t)0x00000002) -#define RCC_APB1Periph_TIM4 ((uint32_t)0x00000004) -#define RCC_APB1Periph_TIM5 ((uint32_t)0x00000008) -#define RCC_APB1Periph_TIM6 ((uint32_t)0x00000010) -#define RCC_APB1Periph_TIM7 ((uint32_t)0x00000020) -#define RCC_APB1Periph_TIM12 ((uint32_t)0x00000040) -#define RCC_APB1Periph_TIM13 ((uint32_t)0x00000080) -#define RCC_APB1Periph_TIM14 ((uint32_t)0x00000100) -#define RCC_APB1Periph_WWDG ((uint32_t)0x00000800) -#define RCC_APB1Periph_SPI2 ((uint32_t)0x00004000) -#define RCC_APB1Periph_SPI3 ((uint32_t)0x00008000) -#define RCC_APB1Periph_USART2 ((uint32_t)0x00020000) -#define RCC_APB1Periph_USART3 ((uint32_t)0x00040000) -#define RCC_APB1Periph_UART4 ((uint32_t)0x00080000) -#define RCC_APB1Periph_UART5 ((uint32_t)0x00100000) -#define RCC_APB1Periph_I2C1 ((uint32_t)0x00200000) -#define RCC_APB1Periph_I2C2 ((uint32_t)0x00400000) -#define RCC_APB1Periph_USB ((uint32_t)0x00800000) -#define RCC_APB1Periph_CAN1 ((uint32_t)0x02000000) -#define RCC_APB1Periph_CAN2 ((uint32_t)0x04000000) -#define RCC_APB1Periph_BKP ((uint32_t)0x08000000) -#define RCC_APB1Periph_PWR ((uint32_t)0x10000000) -#define RCC_APB1Periph_DAC ((uint32_t)0x20000000) -#define RCC_APB1Periph_CEC ((uint32_t)0x40000000) - -#define IS_RCC_APB1_PERIPH(PERIPH) ((((PERIPH) & 0x81013600) == 0x00) && ((PERIPH) != 0x00)) - -/** - * @} - */ - -/** @defgroup Clock_source_to_output_on_MCO_pin - * @{ - */ - -#define RCC_MCO_NoClock ((uint8_t)0x00) -#define RCC_MCO_SYSCLK ((uint8_t)0x04) -#define RCC_MCO_HSI ((uint8_t)0x05) -#define RCC_MCO_HSE ((uint8_t)0x06) -#define RCC_MCO_PLLCLK_Div2 ((uint8_t)0x07) - -#ifndef STM32F10X_CL - #define IS_RCC_MCO(MCO) (((MCO) == RCC_MCO_NoClock) || ((MCO) == RCC_MCO_HSI) || \ - ((MCO) == RCC_MCO_SYSCLK) || ((MCO) == RCC_MCO_HSE) || \ - ((MCO) == RCC_MCO_PLLCLK_Div2)) -#else - #define RCC_MCO_PLL2CLK ((uint8_t)0x08) - #define RCC_MCO_PLL3CLK_Div2 ((uint8_t)0x09) - #define RCC_MCO_XT1 ((uint8_t)0x0A) - #define RCC_MCO_PLL3CLK ((uint8_t)0x0B) - - #define IS_RCC_MCO(MCO) (((MCO) == RCC_MCO_NoClock) || ((MCO) == RCC_MCO_HSI) || \ - ((MCO) == RCC_MCO_SYSCLK) || ((MCO) == RCC_MCO_HSE) || \ - ((MCO) == RCC_MCO_PLLCLK_Div2) || ((MCO) == RCC_MCO_PLL2CLK) || \ - ((MCO) == RCC_MCO_PLL3CLK_Div2) || ((MCO) == RCC_MCO_XT1) || \ - ((MCO) == RCC_MCO_PLL3CLK)) -#endif /* STM32F10X_CL */ - -/** - * @} - */ - -/** @defgroup RCC_Flag - * @{ - */ - -#define RCC_FLAG_HSIRDY ((uint8_t)0x21) -#define RCC_FLAG_HSERDY ((uint8_t)0x31) -#define RCC_FLAG_PLLRDY ((uint8_t)0x39) -#define RCC_FLAG_LSERDY ((uint8_t)0x41) -#define RCC_FLAG_LSIRDY ((uint8_t)0x61) -#define RCC_FLAG_PINRST ((uint8_t)0x7A) -#define RCC_FLAG_PORRST ((uint8_t)0x7B) -#define RCC_FLAG_SFTRST ((uint8_t)0x7C) -#define RCC_FLAG_IWDGRST ((uint8_t)0x7D) -#define RCC_FLAG_WWDGRST ((uint8_t)0x7E) -#define RCC_FLAG_LPWRRST ((uint8_t)0x7F) - -#ifndef STM32F10X_CL - #define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_HSIRDY) || ((FLAG) == RCC_FLAG_HSERDY) || \ - ((FLAG) == RCC_FLAG_PLLRDY) || ((FLAG) == RCC_FLAG_LSERDY) || \ - ((FLAG) == RCC_FLAG_LSIRDY) || ((FLAG) == RCC_FLAG_PINRST) || \ - ((FLAG) == RCC_FLAG_PORRST) || ((FLAG) == RCC_FLAG_SFTRST) || \ - ((FLAG) == RCC_FLAG_IWDGRST)|| ((FLAG) == RCC_FLAG_WWDGRST)|| \ - ((FLAG) == RCC_FLAG_LPWRRST)) -#else - #define RCC_FLAG_PLL2RDY ((uint8_t)0x3B) - #define RCC_FLAG_PLL3RDY ((uint8_t)0x3D) - #define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_HSIRDY) || ((FLAG) == RCC_FLAG_HSERDY) || \ - ((FLAG) == RCC_FLAG_PLLRDY) || ((FLAG) == RCC_FLAG_LSERDY) || \ - ((FLAG) == RCC_FLAG_PLL2RDY) || ((FLAG) == RCC_FLAG_PLL3RDY) || \ - ((FLAG) == RCC_FLAG_LSIRDY) || ((FLAG) == RCC_FLAG_PINRST) || \ - ((FLAG) == RCC_FLAG_PORRST) || ((FLAG) == RCC_FLAG_SFTRST) || \ - ((FLAG) == RCC_FLAG_IWDGRST)|| ((FLAG) == RCC_FLAG_WWDGRST)|| \ - ((FLAG) == RCC_FLAG_LPWRRST)) -#endif /* STM32F10X_CL */ - -#define IS_RCC_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x1F) -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup RCC_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup RCC_Exported_Functions - * @{ - */ - -void RCC_DeInit(void); -void RCC_HSEConfig(uint32_t RCC_HSE); -ErrorStatus RCC_WaitForHSEStartUp(void); -void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue); -void RCC_HSICmd(FunctionalState NewState); -void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul); -void RCC_PLLCmd(FunctionalState NewState); - -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_CL) - void RCC_PREDIV1Config(uint32_t RCC_PREDIV1_Source, uint32_t RCC_PREDIV1_Div); -#endif - -#ifdef STM32F10X_CL - void RCC_PREDIV2Config(uint32_t RCC_PREDIV2_Div); - void RCC_PLL2Config(uint32_t RCC_PLL2Mul); - void RCC_PLL2Cmd(FunctionalState NewState); - void RCC_PLL3Config(uint32_t RCC_PLL3Mul); - void RCC_PLL3Cmd(FunctionalState NewState); -#endif /* STM32F10X_CL */ - -void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource); -uint8_t RCC_GetSYSCLKSource(void); -void RCC_HCLKConfig(uint32_t RCC_SYSCLK); -void RCC_PCLK1Config(uint32_t RCC_HCLK); -void RCC_PCLK2Config(uint32_t RCC_HCLK); -void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState); - -#ifndef STM32F10X_CL - void RCC_USBCLKConfig(uint32_t RCC_USBCLKSource); -#else - void RCC_OTGFSCLKConfig(uint32_t RCC_OTGFSCLKSource); -#endif /* STM32F10X_CL */ - -void RCC_ADCCLKConfig(uint32_t RCC_PCLK2); - -#ifdef STM32F10X_CL - void RCC_I2S2CLKConfig(uint32_t RCC_I2S2CLKSource); - void RCC_I2S3CLKConfig(uint32_t RCC_I2S3CLKSource); -#endif /* STM32F10X_CL */ - -void RCC_LSEConfig(uint8_t RCC_LSE); -void RCC_LSICmd(FunctionalState NewState); -void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource); -void RCC_RTCCLKCmd(FunctionalState NewState); -void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks); -void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); -void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); -void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); - -#ifdef STM32F10X_CL -void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); -#endif /* STM32F10X_CL */ - -void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); -void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); -void RCC_BackupResetCmd(FunctionalState NewState); -void RCC_ClockSecuritySystemCmd(FunctionalState NewState); -void RCC_MCOConfig(uint8_t RCC_MCO); -FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG); -void RCC_ClearFlag(void); -ITStatus RCC_GetITStatus(uint8_t RCC_IT); -void RCC_ClearITPendingBit(uint8_t RCC_IT); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_RCC_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_rtc.h b/example/libs_stm/inc/stm32f10x/stm32f10x_rtc.h deleted file mode 100644 index 833f2fea1..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_rtc.h +++ /dev/null @@ -1,134 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_rtc.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the RTC firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_RTC_H -#define __STM32F10x_RTC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup RTC - * @{ - */ - -/** @defgroup RTC_Exported_Types - * @{ - */ - -/** - * @} - */ - -/** @defgroup RTC_Exported_Constants - * @{ - */ - -/** @defgroup RTC_interrupts_define - * @{ - */ - -#define RTC_IT_OW ((uint16_t)0x0004) /*!< Overflow interrupt */ -#define RTC_IT_ALR ((uint16_t)0x0002) /*!< Alarm interrupt */ -#define RTC_IT_SEC ((uint16_t)0x0001) /*!< Second interrupt */ -#define IS_RTC_IT(IT) ((((IT) & (uint16_t)0xFFF8) == 0x00) && ((IT) != 0x00)) -#define IS_RTC_GET_IT(IT) (((IT) == RTC_IT_OW) || ((IT) == RTC_IT_ALR) || \ - ((IT) == RTC_IT_SEC)) -/** - * @} - */ - -/** @defgroup RTC_interrupts_flags - * @{ - */ - -#define RTC_FLAG_RTOFF ((uint16_t)0x0020) /*!< RTC Operation OFF flag */ -#define RTC_FLAG_RSF ((uint16_t)0x0008) /*!< Registers Synchronized flag */ -#define RTC_FLAG_OW ((uint16_t)0x0004) /*!< Overflow flag */ -#define RTC_FLAG_ALR ((uint16_t)0x0002) /*!< Alarm flag */ -#define RTC_FLAG_SEC ((uint16_t)0x0001) /*!< Second flag */ -#define IS_RTC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFFF0) == 0x00) && ((FLAG) != 0x00)) -#define IS_RTC_GET_FLAG(FLAG) (((FLAG) == RTC_FLAG_RTOFF) || ((FLAG) == RTC_FLAG_RSF) || \ - ((FLAG) == RTC_FLAG_OW) || ((FLAG) == RTC_FLAG_ALR) || \ - ((FLAG) == RTC_FLAG_SEC)) -#define IS_RTC_PRESCALER(PRESCALER) ((PRESCALER) <= 0xFFFFF) - -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup RTC_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup RTC_Exported_Functions - * @{ - */ - -void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState); -void RTC_EnterConfigMode(void); -void RTC_ExitConfigMode(void); -uint32_t RTC_GetCounter(void); -void RTC_SetCounter(uint32_t CounterValue); -void RTC_SetPrescaler(uint32_t PrescalerValue); -void RTC_SetAlarm(uint32_t AlarmValue); -uint32_t RTC_GetDivider(void); -void RTC_WaitForLastTask(void); -void RTC_WaitForSynchro(void); -FlagStatus RTC_GetFlagStatus(uint16_t RTC_FLAG); -void RTC_ClearFlag(uint16_t RTC_FLAG); -ITStatus RTC_GetITStatus(uint16_t RTC_IT); -void RTC_ClearITPendingBit(uint16_t RTC_IT); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_RTC_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_sdio.h b/example/libs_stm/inc/stm32f10x/stm32f10x_sdio.h deleted file mode 100644 index a6c62cd8b..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_sdio.h +++ /dev/null @@ -1,530 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_sdio.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the SDIO firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_SDIO_H -#define __STM32F10x_SDIO_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup SDIO - * @{ - */ - -/** @defgroup SDIO_Exported_Types - * @{ - */ - -typedef struct -{ - uint32_t SDIO_ClockEdge; /*!< Specifies the clock transition on which the bit capture is made. - This parameter can be a value of @ref SDIO_Clock_Edge */ - - uint32_t SDIO_ClockBypass; /*!< Specifies whether the SDIO Clock divider bypass is - enabled or disabled. - This parameter can be a value of @ref SDIO_Clock_Bypass */ - - uint32_t SDIO_ClockPowerSave; /*!< Specifies whether SDIO Clock output is enabled or - disabled when the bus is idle. - This parameter can be a value of @ref SDIO_Clock_Power_Save */ - - uint32_t SDIO_BusWide; /*!< Specifies the SDIO bus width. - This parameter can be a value of @ref SDIO_Bus_Wide */ - - uint32_t SDIO_HardwareFlowControl; /*!< Specifies whether the SDIO hardware flow control is enabled or disabled. - This parameter can be a value of @ref SDIO_Hardware_Flow_Control */ - - uint8_t SDIO_ClockDiv; /*!< Specifies the clock frequency of the SDIO controller. - This parameter can be a value between 0x00 and 0xFF. */ - -} SDIO_InitTypeDef; - -typedef struct -{ - uint32_t SDIO_Argument; /*!< Specifies the SDIO command argument which is sent - to a card as part of a command message. If a command - contains an argument, it must be loaded into this register - before writing the command to the command register */ - - uint32_t SDIO_CmdIndex; /*!< Specifies the SDIO command index. It must be lower than 0x40. */ - - uint32_t SDIO_Response; /*!< Specifies the SDIO response type. - This parameter can be a value of @ref SDIO_Response_Type */ - - uint32_t SDIO_Wait; /*!< Specifies whether SDIO wait-for-interrupt request is enabled or disabled. - This parameter can be a value of @ref SDIO_Wait_Interrupt_State */ - - uint32_t SDIO_CPSM; /*!< Specifies whether SDIO Command path state machine (CPSM) - is enabled or disabled. - This parameter can be a value of @ref SDIO_CPSM_State */ -} SDIO_CmdInitTypeDef; - -typedef struct -{ - uint32_t SDIO_DataTimeOut; /*!< Specifies the data timeout period in card bus clock periods. */ - - uint32_t SDIO_DataLength; /*!< Specifies the number of data bytes to be transferred. */ - - uint32_t SDIO_DataBlockSize; /*!< Specifies the data block size for block transfer. - This parameter can be a value of @ref SDIO_Data_Block_Size */ - - uint32_t SDIO_TransferDir; /*!< Specifies the data transfer direction, whether the transfer - is a read or write. - This parameter can be a value of @ref SDIO_Transfer_Direction */ - - uint32_t SDIO_TransferMode; /*!< Specifies whether data transfer is in stream or block mode. - This parameter can be a value of @ref SDIO_Transfer_Type */ - - uint32_t SDIO_DPSM; /*!< Specifies whether SDIO Data path state machine (DPSM) - is enabled or disabled. - This parameter can be a value of @ref SDIO_DPSM_State */ -} SDIO_DataInitTypeDef; - -/** - * @} - */ - -/** @defgroup SDIO_Exported_Constants - * @{ - */ - -/** @defgroup SDIO_Clock_Edge - * @{ - */ - -#define SDIO_ClockEdge_Rising ((uint32_t)0x00000000) -#define SDIO_ClockEdge_Falling ((uint32_t)0x00002000) -#define IS_SDIO_CLOCK_EDGE(EDGE) (((EDGE) == SDIO_ClockEdge_Rising) || \ - ((EDGE) == SDIO_ClockEdge_Falling)) -/** - * @} - */ - -/** @defgroup SDIO_Clock_Bypass - * @{ - */ - -#define SDIO_ClockBypass_Disable ((uint32_t)0x00000000) -#define SDIO_ClockBypass_Enable ((uint32_t)0x00000400) -#define IS_SDIO_CLOCK_BYPASS(BYPASS) (((BYPASS) == SDIO_ClockBypass_Disable) || \ - ((BYPASS) == SDIO_ClockBypass_Enable)) -/** - * @} - */ - -/** @defgroup SDIO_Clock_Power_Save - * @{ - */ - -#define SDIO_ClockPowerSave_Disable ((uint32_t)0x00000000) -#define SDIO_ClockPowerSave_Enable ((uint32_t)0x00000200) -#define IS_SDIO_CLOCK_POWER_SAVE(SAVE) (((SAVE) == SDIO_ClockPowerSave_Disable) || \ - ((SAVE) == SDIO_ClockPowerSave_Enable)) -/** - * @} - */ - -/** @defgroup SDIO_Bus_Wide - * @{ - */ - -#define SDIO_BusWide_1b ((uint32_t)0x00000000) -#define SDIO_BusWide_4b ((uint32_t)0x00000800) -#define SDIO_BusWide_8b ((uint32_t)0x00001000) -#define IS_SDIO_BUS_WIDE(WIDE) (((WIDE) == SDIO_BusWide_1b) || ((WIDE) == SDIO_BusWide_4b) || \ - ((WIDE) == SDIO_BusWide_8b)) - -/** - * @} - */ - -/** @defgroup SDIO_Hardware_Flow_Control - * @{ - */ - -#define SDIO_HardwareFlowControl_Disable ((uint32_t)0x00000000) -#define SDIO_HardwareFlowControl_Enable ((uint32_t)0x00004000) -#define IS_SDIO_HARDWARE_FLOW_CONTROL(CONTROL) (((CONTROL) == SDIO_HardwareFlowControl_Disable) || \ - ((CONTROL) == SDIO_HardwareFlowControl_Enable)) -/** - * @} - */ - -/** @defgroup SDIO_Power_State - * @{ - */ - -#define SDIO_PowerState_OFF ((uint32_t)0x00000000) -#define SDIO_PowerState_ON ((uint32_t)0x00000003) -#define IS_SDIO_POWER_STATE(STATE) (((STATE) == SDIO_PowerState_OFF) || ((STATE) == SDIO_PowerState_ON)) -/** - * @} - */ - - -/** @defgroup SDIO_Interrupt_soucres - * @{ - */ - -#define SDIO_IT_CCRCFAIL ((uint32_t)0x00000001) -#define SDIO_IT_DCRCFAIL ((uint32_t)0x00000002) -#define SDIO_IT_CTIMEOUT ((uint32_t)0x00000004) -#define SDIO_IT_DTIMEOUT ((uint32_t)0x00000008) -#define SDIO_IT_TXUNDERR ((uint32_t)0x00000010) -#define SDIO_IT_RXOVERR ((uint32_t)0x00000020) -#define SDIO_IT_CMDREND ((uint32_t)0x00000040) -#define SDIO_IT_CMDSENT ((uint32_t)0x00000080) -#define SDIO_IT_DATAEND ((uint32_t)0x00000100) -#define SDIO_IT_STBITERR ((uint32_t)0x00000200) -#define SDIO_IT_DBCKEND ((uint32_t)0x00000400) -#define SDIO_IT_CMDACT ((uint32_t)0x00000800) -#define SDIO_IT_TXACT ((uint32_t)0x00001000) -#define SDIO_IT_RXACT ((uint32_t)0x00002000) -#define SDIO_IT_TXFIFOHE ((uint32_t)0x00004000) -#define SDIO_IT_RXFIFOHF ((uint32_t)0x00008000) -#define SDIO_IT_TXFIFOF ((uint32_t)0x00010000) -#define SDIO_IT_RXFIFOF ((uint32_t)0x00020000) -#define SDIO_IT_TXFIFOE ((uint32_t)0x00040000) -#define SDIO_IT_RXFIFOE ((uint32_t)0x00080000) -#define SDIO_IT_TXDAVL ((uint32_t)0x00100000) -#define SDIO_IT_RXDAVL ((uint32_t)0x00200000) -#define SDIO_IT_SDIOIT ((uint32_t)0x00400000) -#define SDIO_IT_CEATAEND ((uint32_t)0x00800000) -#define IS_SDIO_IT(IT) ((((IT) & (uint32_t)0xFF000000) == 0x00) && ((IT) != (uint32_t)0x00)) -/** - * @} - */ - -/** @defgroup SDIO_Command_Index - * @{ - */ - -#define IS_SDIO_CMD_INDEX(INDEX) ((INDEX) < 0x40) -/** - * @} - */ - -/** @defgroup SDIO_Response_Type - * @{ - */ - -#define SDIO_Response_No ((uint32_t)0x00000000) -#define SDIO_Response_Short ((uint32_t)0x00000040) -#define SDIO_Response_Long ((uint32_t)0x000000C0) -#define IS_SDIO_RESPONSE(RESPONSE) (((RESPONSE) == SDIO_Response_No) || \ - ((RESPONSE) == SDIO_Response_Short) || \ - ((RESPONSE) == SDIO_Response_Long)) -/** - * @} - */ - -/** @defgroup SDIO_Wait_Interrupt_State - * @{ - */ - -#define SDIO_Wait_No ((uint32_t)0x00000000) /*!< SDIO No Wait, TimeOut is enabled */ -#define SDIO_Wait_IT ((uint32_t)0x00000100) /*!< SDIO Wait Interrupt Request */ -#define SDIO_Wait_Pend ((uint32_t)0x00000200) /*!< SDIO Wait End of transfer */ -#define IS_SDIO_WAIT(WAIT) (((WAIT) == SDIO_Wait_No) || ((WAIT) == SDIO_Wait_IT) || \ - ((WAIT) == SDIO_Wait_Pend)) -/** - * @} - */ - -/** @defgroup SDIO_CPSM_State - * @{ - */ - -#define SDIO_CPSM_Disable ((uint32_t)0x00000000) -#define SDIO_CPSM_Enable ((uint32_t)0x00000400) -#define IS_SDIO_CPSM(CPSM) (((CPSM) == SDIO_CPSM_Enable) || ((CPSM) == SDIO_CPSM_Disable)) -/** - * @} - */ - -/** @defgroup SDIO_Response_Registers - * @{ - */ - -#define SDIO_RESP1 ((uint32_t)0x00000000) -#define SDIO_RESP2 ((uint32_t)0x00000004) -#define SDIO_RESP3 ((uint32_t)0x00000008) -#define SDIO_RESP4 ((uint32_t)0x0000000C) -#define IS_SDIO_RESP(RESP) (((RESP) == SDIO_RESP1) || ((RESP) == SDIO_RESP2) || \ - ((RESP) == SDIO_RESP3) || ((RESP) == SDIO_RESP4)) -/** - * @} - */ - -/** @defgroup SDIO_Data_Length - * @{ - */ - -#define IS_SDIO_DATA_LENGTH(LENGTH) ((LENGTH) <= 0x01FFFFFF) -/** - * @} - */ - -/** @defgroup SDIO_Data_Block_Size - * @{ - */ - -#define SDIO_DataBlockSize_1b ((uint32_t)0x00000000) -#define SDIO_DataBlockSize_2b ((uint32_t)0x00000010) -#define SDIO_DataBlockSize_4b ((uint32_t)0x00000020) -#define SDIO_DataBlockSize_8b ((uint32_t)0x00000030) -#define SDIO_DataBlockSize_16b ((uint32_t)0x00000040) -#define SDIO_DataBlockSize_32b ((uint32_t)0x00000050) -#define SDIO_DataBlockSize_64b ((uint32_t)0x00000060) -#define SDIO_DataBlockSize_128b ((uint32_t)0x00000070) -#define SDIO_DataBlockSize_256b ((uint32_t)0x00000080) -#define SDIO_DataBlockSize_512b ((uint32_t)0x00000090) -#define SDIO_DataBlockSize_1024b ((uint32_t)0x000000A0) -#define SDIO_DataBlockSize_2048b ((uint32_t)0x000000B0) -#define SDIO_DataBlockSize_4096b ((uint32_t)0x000000C0) -#define SDIO_DataBlockSize_8192b ((uint32_t)0x000000D0) -#define SDIO_DataBlockSize_16384b ((uint32_t)0x000000E0) -#define IS_SDIO_BLOCK_SIZE(SIZE) (((SIZE) == SDIO_DataBlockSize_1b) || \ - ((SIZE) == SDIO_DataBlockSize_2b) || \ - ((SIZE) == SDIO_DataBlockSize_4b) || \ - ((SIZE) == SDIO_DataBlockSize_8b) || \ - ((SIZE) == SDIO_DataBlockSize_16b) || \ - ((SIZE) == SDIO_DataBlockSize_32b) || \ - ((SIZE) == SDIO_DataBlockSize_64b) || \ - ((SIZE) == SDIO_DataBlockSize_128b) || \ - ((SIZE) == SDIO_DataBlockSize_256b) || \ - ((SIZE) == SDIO_DataBlockSize_512b) || \ - ((SIZE) == SDIO_DataBlockSize_1024b) || \ - ((SIZE) == SDIO_DataBlockSize_2048b) || \ - ((SIZE) == SDIO_DataBlockSize_4096b) || \ - ((SIZE) == SDIO_DataBlockSize_8192b) || \ - ((SIZE) == SDIO_DataBlockSize_16384b)) -/** - * @} - */ - -/** @defgroup SDIO_Transfer_Direction - * @{ - */ - -#define SDIO_TransferDir_ToCard ((uint32_t)0x00000000) -#define SDIO_TransferDir_ToSDIO ((uint32_t)0x00000002) -#define IS_SDIO_TRANSFER_DIR(DIR) (((DIR) == SDIO_TransferDir_ToCard) || \ - ((DIR) == SDIO_TransferDir_ToSDIO)) -/** - * @} - */ - -/** @defgroup SDIO_Transfer_Type - * @{ - */ - -#define SDIO_TransferMode_Block ((uint32_t)0x00000000) -#define SDIO_TransferMode_Stream ((uint32_t)0x00000004) -#define IS_SDIO_TRANSFER_MODE(MODE) (((MODE) == SDIO_TransferMode_Stream) || \ - ((MODE) == SDIO_TransferMode_Block)) -/** - * @} - */ - -/** @defgroup SDIO_DPSM_State - * @{ - */ - -#define SDIO_DPSM_Disable ((uint32_t)0x00000000) -#define SDIO_DPSM_Enable ((uint32_t)0x00000001) -#define IS_SDIO_DPSM(DPSM) (((DPSM) == SDIO_DPSM_Enable) || ((DPSM) == SDIO_DPSM_Disable)) -/** - * @} - */ - -/** @defgroup SDIO_Flags - * @{ - */ - -#define SDIO_FLAG_CCRCFAIL ((uint32_t)0x00000001) -#define SDIO_FLAG_DCRCFAIL ((uint32_t)0x00000002) -#define SDIO_FLAG_CTIMEOUT ((uint32_t)0x00000004) -#define SDIO_FLAG_DTIMEOUT ((uint32_t)0x00000008) -#define SDIO_FLAG_TXUNDERR ((uint32_t)0x00000010) -#define SDIO_FLAG_RXOVERR ((uint32_t)0x00000020) -#define SDIO_FLAG_CMDREND ((uint32_t)0x00000040) -#define SDIO_FLAG_CMDSENT ((uint32_t)0x00000080) -#define SDIO_FLAG_DATAEND ((uint32_t)0x00000100) -#define SDIO_FLAG_STBITERR ((uint32_t)0x00000200) -#define SDIO_FLAG_DBCKEND ((uint32_t)0x00000400) -#define SDIO_FLAG_CMDACT ((uint32_t)0x00000800) -#define SDIO_FLAG_TXACT ((uint32_t)0x00001000) -#define SDIO_FLAG_RXACT ((uint32_t)0x00002000) -#define SDIO_FLAG_TXFIFOHE ((uint32_t)0x00004000) -#define SDIO_FLAG_RXFIFOHF ((uint32_t)0x00008000) -#define SDIO_FLAG_TXFIFOF ((uint32_t)0x00010000) -#define SDIO_FLAG_RXFIFOF ((uint32_t)0x00020000) -#define SDIO_FLAG_TXFIFOE ((uint32_t)0x00040000) -#define SDIO_FLAG_RXFIFOE ((uint32_t)0x00080000) -#define SDIO_FLAG_TXDAVL ((uint32_t)0x00100000) -#define SDIO_FLAG_RXDAVL ((uint32_t)0x00200000) -#define SDIO_FLAG_SDIOIT ((uint32_t)0x00400000) -#define SDIO_FLAG_CEATAEND ((uint32_t)0x00800000) -#define IS_SDIO_FLAG(FLAG) (((FLAG) == SDIO_FLAG_CCRCFAIL) || \ - ((FLAG) == SDIO_FLAG_DCRCFAIL) || \ - ((FLAG) == SDIO_FLAG_CTIMEOUT) || \ - ((FLAG) == SDIO_FLAG_DTIMEOUT) || \ - ((FLAG) == SDIO_FLAG_TXUNDERR) || \ - ((FLAG) == SDIO_FLAG_RXOVERR) || \ - ((FLAG) == SDIO_FLAG_CMDREND) || \ - ((FLAG) == SDIO_FLAG_CMDSENT) || \ - ((FLAG) == SDIO_FLAG_DATAEND) || \ - ((FLAG) == SDIO_FLAG_STBITERR) || \ - ((FLAG) == SDIO_FLAG_DBCKEND) || \ - ((FLAG) == SDIO_FLAG_CMDACT) || \ - ((FLAG) == SDIO_FLAG_TXACT) || \ - ((FLAG) == SDIO_FLAG_RXACT) || \ - ((FLAG) == SDIO_FLAG_TXFIFOHE) || \ - ((FLAG) == SDIO_FLAG_RXFIFOHF) || \ - ((FLAG) == SDIO_FLAG_TXFIFOF) || \ - ((FLAG) == SDIO_FLAG_RXFIFOF) || \ - ((FLAG) == SDIO_FLAG_TXFIFOE) || \ - ((FLAG) == SDIO_FLAG_RXFIFOE) || \ - ((FLAG) == SDIO_FLAG_TXDAVL) || \ - ((FLAG) == SDIO_FLAG_RXDAVL) || \ - ((FLAG) == SDIO_FLAG_SDIOIT) || \ - ((FLAG) == SDIO_FLAG_CEATAEND)) - -#define IS_SDIO_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFF3FF800) == 0x00) && ((FLAG) != (uint32_t)0x00)) - -#define IS_SDIO_GET_IT(IT) (((IT) == SDIO_IT_CCRCFAIL) || \ - ((IT) == SDIO_IT_DCRCFAIL) || \ - ((IT) == SDIO_IT_CTIMEOUT) || \ - ((IT) == SDIO_IT_DTIMEOUT) || \ - ((IT) == SDIO_IT_TXUNDERR) || \ - ((IT) == SDIO_IT_RXOVERR) || \ - ((IT) == SDIO_IT_CMDREND) || \ - ((IT) == SDIO_IT_CMDSENT) || \ - ((IT) == SDIO_IT_DATAEND) || \ - ((IT) == SDIO_IT_STBITERR) || \ - ((IT) == SDIO_IT_DBCKEND) || \ - ((IT) == SDIO_IT_CMDACT) || \ - ((IT) == SDIO_IT_TXACT) || \ - ((IT) == SDIO_IT_RXACT) || \ - ((IT) == SDIO_IT_TXFIFOHE) || \ - ((IT) == SDIO_IT_RXFIFOHF) || \ - ((IT) == SDIO_IT_TXFIFOF) || \ - ((IT) == SDIO_IT_RXFIFOF) || \ - ((IT) == SDIO_IT_TXFIFOE) || \ - ((IT) == SDIO_IT_RXFIFOE) || \ - ((IT) == SDIO_IT_TXDAVL) || \ - ((IT) == SDIO_IT_RXDAVL) || \ - ((IT) == SDIO_IT_SDIOIT) || \ - ((IT) == SDIO_IT_CEATAEND)) - -#define IS_SDIO_CLEAR_IT(IT) ((((IT) & (uint32_t)0xFF3FF800) == 0x00) && ((IT) != (uint32_t)0x00)) - -/** - * @} - */ - -/** @defgroup SDIO_Read_Wait_Mode - * @{ - */ - -#define SDIO_ReadWaitMode_CLK ((uint32_t)0x00000001) -#define SDIO_ReadWaitMode_DATA2 ((uint32_t)0x00000000) -#define IS_SDIO_READWAIT_MODE(MODE) (((MODE) == SDIO_ReadWaitMode_CLK) || \ - ((MODE) == SDIO_ReadWaitMode_DATA2)) -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup SDIO_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup SDIO_Exported_Functions - * @{ - */ - -void SDIO_DeInit(void); -void SDIO_Init(SDIO_InitTypeDef* SDIO_InitStruct); -void SDIO_StructInit(SDIO_InitTypeDef* SDIO_InitStruct); -void SDIO_ClockCmd(FunctionalState NewState); -void SDIO_SetPowerState(uint32_t SDIO_PowerState); -uint32_t SDIO_GetPowerState(void); -void SDIO_ITConfig(uint32_t SDIO_IT, FunctionalState NewState); -void SDIO_DMACmd(FunctionalState NewState); -void SDIO_SendCommand(SDIO_CmdInitTypeDef *SDIO_CmdInitStruct); -void SDIO_CmdStructInit(SDIO_CmdInitTypeDef* SDIO_CmdInitStruct); -uint8_t SDIO_GetCommandResponse(void); -uint32_t SDIO_GetResponse(uint32_t SDIO_RESP); -void SDIO_DataConfig(SDIO_DataInitTypeDef* SDIO_DataInitStruct); -void SDIO_DataStructInit(SDIO_DataInitTypeDef* SDIO_DataInitStruct); -uint32_t SDIO_GetDataCounter(void); -uint32_t SDIO_ReadData(void); -void SDIO_WriteData(uint32_t Data); -uint32_t SDIO_GetFIFOCount(void); -void SDIO_StartSDIOReadWait(FunctionalState NewState); -void SDIO_StopSDIOReadWait(FunctionalState NewState); -void SDIO_SetSDIOReadWaitMode(uint32_t SDIO_ReadWaitMode); -void SDIO_SetSDIOOperation(FunctionalState NewState); -void SDIO_SendSDIOSuspendCmd(FunctionalState NewState); -void SDIO_CommandCompletionCmd(FunctionalState NewState); -void SDIO_CEATAITCmd(FunctionalState NewState); -void SDIO_SendCEATACmd(FunctionalState NewState); -FlagStatus SDIO_GetFlagStatus(uint32_t SDIO_FLAG); -void SDIO_ClearFlag(uint32_t SDIO_FLAG); -ITStatus SDIO_GetITStatus(uint32_t SDIO_IT); -void SDIO_ClearITPendingBit(uint32_t SDIO_IT); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_SDIO_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_spi.h b/example/libs_stm/inc/stm32f10x/stm32f10x_spi.h deleted file mode 100644 index 920c82697..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_spi.h +++ /dev/null @@ -1,490 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_spi.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the SPI firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_SPI_H -#define __STM32F10x_SPI_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup SPI - * @{ - */ - -/** @defgroup SPI_Exported_Types - * @{ - */ - -/** - * @brief SPI Init structure definition - */ - -typedef struct -{ - uint16_t SPI_Direction; /*!< Specifies the SPI unidirectional or bidirectional data mode. - This parameter can be a value of @ref SPI_data_direction */ - - uint16_t SPI_Mode; /*!< Specifies the SPI operating mode. - This parameter can be a value of @ref SPI_mode */ - - uint16_t SPI_DataSize; /*!< Specifies the SPI data size. - This parameter can be a value of @ref SPI_data_size */ - - uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state. - This parameter can be a value of @ref SPI_Clock_Polarity */ - - uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture. - This parameter can be a value of @ref SPI_Clock_Phase */ - - uint16_t SPI_NSS; /*!< Specifies whether the NSS signal is managed by - hardware (NSS pin) or by software using the SSI bit. - This parameter can be a value of @ref SPI_Slave_Select_management */ - - uint16_t SPI_BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be - used to configure the transmit and receive SCK clock. - This parameter can be a value of @ref SPI_BaudRate_Prescaler. - @note The communication clock is derived from the master - clock. The slave clock does not need to be set. */ - - uint16_t SPI_FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit. - This parameter can be a value of @ref SPI_MSB_LSB_transmission */ - - uint16_t SPI_CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. */ -}SPI_InitTypeDef; - -/** - * @brief I2S Init structure definition - */ - -typedef struct -{ - - uint16_t I2S_Mode; /*!< Specifies the I2S operating mode. - This parameter can be a value of @ref I2S_Mode */ - - uint16_t I2S_Standard; /*!< Specifies the standard used for the I2S communication. - This parameter can be a value of @ref I2S_Standard */ - - uint16_t I2S_DataFormat; /*!< Specifies the data format for the I2S communication. - This parameter can be a value of @ref I2S_Data_Format */ - - uint16_t I2S_MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not. - This parameter can be a value of @ref I2S_MCLK_Output */ - - uint32_t I2S_AudioFreq; /*!< Specifies the frequency selected for the I2S communication. - This parameter can be a value of @ref I2S_Audio_Frequency */ - - uint16_t I2S_CPOL; /*!< Specifies the idle state of the I2S clock. - This parameter can be a value of @ref I2S_Clock_Polarity */ -}I2S_InitTypeDef; - -/** - * @} - */ - -/** @defgroup SPI_Exported_Constants - * @{ - */ - -#define IS_SPI_ALL_PERIPH(PERIPH) (((PERIPH) == SPI1) || \ - ((PERIPH) == SPI2) || \ - ((PERIPH) == SPI3)) - -#define IS_SPI_23_PERIPH(PERIPH) (((PERIPH) == SPI2) || \ - ((PERIPH) == SPI3)) - -/** @defgroup SPI_data_direction - * @{ - */ - -#define SPI_Direction_2Lines_FullDuplex ((uint16_t)0x0000) -#define SPI_Direction_2Lines_RxOnly ((uint16_t)0x0400) -#define SPI_Direction_1Line_Rx ((uint16_t)0x8000) -#define SPI_Direction_1Line_Tx ((uint16_t)0xC000) -#define IS_SPI_DIRECTION_MODE(MODE) (((MODE) == SPI_Direction_2Lines_FullDuplex) || \ - ((MODE) == SPI_Direction_2Lines_RxOnly) || \ - ((MODE) == SPI_Direction_1Line_Rx) || \ - ((MODE) == SPI_Direction_1Line_Tx)) -/** - * @} - */ - -/** @defgroup SPI_mode - * @{ - */ - -#define SPI_Mode_Master ((uint16_t)0x0104) -#define SPI_Mode_Slave ((uint16_t)0x0000) -#define IS_SPI_MODE(MODE) (((MODE) == SPI_Mode_Master) || \ - ((MODE) == SPI_Mode_Slave)) -/** - * @} - */ - -/** @defgroup SPI_data_size - * @{ - */ - -#define SPI_DataSize_16b ((uint16_t)0x0800) -#define SPI_DataSize_8b ((uint16_t)0x0000) -#define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DataSize_16b) || \ - ((DATASIZE) == SPI_DataSize_8b)) -/** - * @} - */ - -/** @defgroup SPI_Clock_Polarity - * @{ - */ - -#define SPI_CPOL_Low ((uint16_t)0x0000) -#define SPI_CPOL_High ((uint16_t)0x0002) -#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_CPOL_Low) || \ - ((CPOL) == SPI_CPOL_High)) -/** - * @} - */ - -/** @defgroup SPI_Clock_Phase - * @{ - */ - -#define SPI_CPHA_1Edge ((uint16_t)0x0000) -#define SPI_CPHA_2Edge ((uint16_t)0x0001) -#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_CPHA_1Edge) || \ - ((CPHA) == SPI_CPHA_2Edge)) -/** - * @} - */ - -/** @defgroup SPI_Slave_Select_management - * @{ - */ - -#define SPI_NSS_Soft ((uint16_t)0x0200) -#define SPI_NSS_Hard ((uint16_t)0x0000) -#define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_Soft) || \ - ((NSS) == SPI_NSS_Hard)) -/** - * @} - */ - -/** @defgroup SPI_BaudRate_Prescaler - * @{ - */ - -#define SPI_BaudRatePrescaler_2 ((uint16_t)0x0000) -#define SPI_BaudRatePrescaler_4 ((uint16_t)0x0008) -#define SPI_BaudRatePrescaler_8 ((uint16_t)0x0010) -#define SPI_BaudRatePrescaler_16 ((uint16_t)0x0018) -#define SPI_BaudRatePrescaler_32 ((uint16_t)0x0020) -#define SPI_BaudRatePrescaler_64 ((uint16_t)0x0028) -#define SPI_BaudRatePrescaler_128 ((uint16_t)0x0030) -#define SPI_BaudRatePrescaler_256 ((uint16_t)0x0038) -#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BaudRatePrescaler_2) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_4) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_8) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_16) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_32) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_64) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_128) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_256)) -/** - * @} - */ - -/** @defgroup SPI_MSB_LSB_transmission - * @{ - */ - -#define SPI_FirstBit_MSB ((uint16_t)0x0000) -#define SPI_FirstBit_LSB ((uint16_t)0x0080) -#define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FirstBit_MSB) || \ - ((BIT) == SPI_FirstBit_LSB)) -/** - * @} - */ - -/** @defgroup I2S_Mode - * @{ - */ - -#define I2S_Mode_SlaveTx ((uint16_t)0x0000) -#define I2S_Mode_SlaveRx ((uint16_t)0x0100) -#define I2S_Mode_MasterTx ((uint16_t)0x0200) -#define I2S_Mode_MasterRx ((uint16_t)0x0300) -#define IS_I2S_MODE(MODE) (((MODE) == I2S_Mode_SlaveTx) || \ - ((MODE) == I2S_Mode_SlaveRx) || \ - ((MODE) == I2S_Mode_MasterTx) || \ - ((MODE) == I2S_Mode_MasterRx) ) -/** - * @} - */ - -/** @defgroup I2S_Standard - * @{ - */ - -#define I2S_Standard_Phillips ((uint16_t)0x0000) -#define I2S_Standard_MSB ((uint16_t)0x0010) -#define I2S_Standard_LSB ((uint16_t)0x0020) -#define I2S_Standard_PCMShort ((uint16_t)0x0030) -#define I2S_Standard_PCMLong ((uint16_t)0x00B0) -#define IS_I2S_STANDARD(STANDARD) (((STANDARD) == I2S_Standard_Phillips) || \ - ((STANDARD) == I2S_Standard_MSB) || \ - ((STANDARD) == I2S_Standard_LSB) || \ - ((STANDARD) == I2S_Standard_PCMShort) || \ - ((STANDARD) == I2S_Standard_PCMLong)) -/** - * @} - */ - -/** @defgroup I2S_Data_Format - * @{ - */ - -#define I2S_DataFormat_16b ((uint16_t)0x0000) -#define I2S_DataFormat_16bextended ((uint16_t)0x0001) -#define I2S_DataFormat_24b ((uint16_t)0x0003) -#define I2S_DataFormat_32b ((uint16_t)0x0005) -#define IS_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == I2S_DataFormat_16b) || \ - ((FORMAT) == I2S_DataFormat_16bextended) || \ - ((FORMAT) == I2S_DataFormat_24b) || \ - ((FORMAT) == I2S_DataFormat_32b)) -/** - * @} - */ - -/** @defgroup I2S_MCLK_Output - * @{ - */ - -#define I2S_MCLKOutput_Enable ((uint16_t)0x0200) -#define I2S_MCLKOutput_Disable ((uint16_t)0x0000) -#define IS_I2S_MCLK_OUTPUT(OUTPUT) (((OUTPUT) == I2S_MCLKOutput_Enable) || \ - ((OUTPUT) == I2S_MCLKOutput_Disable)) -/** - * @} - */ - -/** @defgroup I2S_Audio_Frequency - * @{ - */ - -#define I2S_AudioFreq_96k ((uint32_t)96000) -#define I2S_AudioFreq_48k ((uint32_t)48000) -#define I2S_AudioFreq_44k ((uint32_t)44100) -#define I2S_AudioFreq_32k ((uint32_t)32000) -#define I2S_AudioFreq_22k ((uint32_t)22050) -#define I2S_AudioFreq_16k ((uint32_t)16000) -#define I2S_AudioFreq_11k ((uint32_t)11025) -#define I2S_AudioFreq_8k ((uint32_t)8000) -#define I2S_AudioFreq_Default ((uint32_t)2) -#define IS_I2S_AUDIO_FREQ(FREQ) (((FREQ) == I2S_AudioFreq_96k) || \ - ((FREQ) == I2S_AudioFreq_48k) || \ - ((FREQ) == I2S_AudioFreq_44k) || \ - ((FREQ) == I2S_AudioFreq_32k) || \ - ((FREQ) == I2S_AudioFreq_22k) || \ - ((FREQ) == I2S_AudioFreq_16k) || \ - ((FREQ) == I2S_AudioFreq_11k) || \ - ((FREQ) == I2S_AudioFreq_8k) || \ - ((FREQ) == I2S_AudioFreq_Default)) -/** - * @} - */ - -/** @defgroup I2S_Clock_Polarity - * @{ - */ - -#define I2S_CPOL_Low ((uint16_t)0x0000) -#define I2S_CPOL_High ((uint16_t)0x0008) -#define IS_I2S_CPOL(CPOL) (((CPOL) == I2S_CPOL_Low) || \ - ((CPOL) == I2S_CPOL_High)) -/** - * @} - */ - -/** @defgroup SPI_I2S_DMA_transfer_requests - * @{ - */ - -#define SPI_I2S_DMAReq_Tx ((uint16_t)0x0002) -#define SPI_I2S_DMAReq_Rx ((uint16_t)0x0001) -#define IS_SPI_I2S_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFFFC) == 0x00) && ((DMAREQ) != 0x00)) -/** - * @} - */ - -/** @defgroup SPI_NSS_internal_software_mangement - * @{ - */ - -#define SPI_NSSInternalSoft_Set ((uint16_t)0x0100) -#define SPI_NSSInternalSoft_Reset ((uint16_t)0xFEFF) -#define IS_SPI_NSS_INTERNAL(INTERNAL) (((INTERNAL) == SPI_NSSInternalSoft_Set) || \ - ((INTERNAL) == SPI_NSSInternalSoft_Reset)) -/** - * @} - */ - -/** @defgroup SPI_CRC_Transmit_Receive - * @{ - */ - -#define SPI_CRC_Tx ((uint8_t)0x00) -#define SPI_CRC_Rx ((uint8_t)0x01) -#define IS_SPI_CRC(CRC) (((CRC) == SPI_CRC_Tx) || ((CRC) == SPI_CRC_Rx)) -/** - * @} - */ - -/** @defgroup SPI_direction_transmit_receive - * @{ - */ - -#define SPI_Direction_Rx ((uint16_t)0xBFFF) -#define SPI_Direction_Tx ((uint16_t)0x4000) -#define IS_SPI_DIRECTION(DIRECTION) (((DIRECTION) == SPI_Direction_Rx) || \ - ((DIRECTION) == SPI_Direction_Tx)) -/** - * @} - */ - -/** @defgroup SPI_I2S_interrupts_definition - * @{ - */ - -#define SPI_I2S_IT_TXE ((uint8_t)0x71) -#define SPI_I2S_IT_RXNE ((uint8_t)0x60) -#define SPI_I2S_IT_ERR ((uint8_t)0x50) -#define IS_SPI_I2S_CONFIG_IT(IT) (((IT) == SPI_I2S_IT_TXE) || \ - ((IT) == SPI_I2S_IT_RXNE) || \ - ((IT) == SPI_I2S_IT_ERR)) -#define SPI_I2S_IT_OVR ((uint8_t)0x56) -#define SPI_IT_MODF ((uint8_t)0x55) -#define SPI_IT_CRCERR ((uint8_t)0x54) -#define I2S_IT_UDR ((uint8_t)0x53) -#define IS_SPI_I2S_CLEAR_IT(IT) (((IT) == SPI_IT_CRCERR)) -#define IS_SPI_I2S_GET_IT(IT) (((IT) == SPI_I2S_IT_RXNE) || ((IT) == SPI_I2S_IT_TXE) || \ - ((IT) == I2S_IT_UDR) || ((IT) == SPI_IT_CRCERR) || \ - ((IT) == SPI_IT_MODF) || ((IT) == SPI_I2S_IT_OVR)) -/** - * @} - */ - -/** @defgroup SPI_I2S_flags_definition - * @{ - */ - -#define SPI_I2S_FLAG_RXNE ((uint16_t)0x0001) -#define SPI_I2S_FLAG_TXE ((uint16_t)0x0002) -#define I2S_FLAG_CHSIDE ((uint16_t)0x0004) -#define I2S_FLAG_UDR ((uint16_t)0x0008) -#define SPI_FLAG_CRCERR ((uint16_t)0x0010) -#define SPI_FLAG_MODF ((uint16_t)0x0020) -#define SPI_I2S_FLAG_OVR ((uint16_t)0x0040) -#define SPI_I2S_FLAG_BSY ((uint16_t)0x0080) -#define IS_SPI_I2S_CLEAR_FLAG(FLAG) (((FLAG) == SPI_FLAG_CRCERR)) -#define IS_SPI_I2S_GET_FLAG(FLAG) (((FLAG) == SPI_I2S_FLAG_BSY) || ((FLAG) == SPI_I2S_FLAG_OVR) || \ - ((FLAG) == SPI_FLAG_MODF) || ((FLAG) == SPI_FLAG_CRCERR) || \ - ((FLAG) == I2S_FLAG_UDR) || ((FLAG) == I2S_FLAG_CHSIDE) || \ - ((FLAG) == SPI_I2S_FLAG_TXE) || ((FLAG) == SPI_I2S_FLAG_RXNE)) -/** - * @} - */ - -/** @defgroup SPI_CRC_polynomial - * @{ - */ - -#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) ((POLYNOMIAL) >= 0x1) -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup SPI_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup SPI_Exported_Functions - * @{ - */ - -void SPI_I2S_DeInit(SPI_TypeDef* SPIx); -void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct); -void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct); -void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct); -void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct); -void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); -void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); -void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState); -void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState); -void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data); -uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx); -void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft); -void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState); -void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize); -void SPI_TransmitCRC(SPI_TypeDef* SPIx); -void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState); -uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC); -uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx); -void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction); -FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); -void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); -ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); -void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F10x_SPI_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_tim.h b/example/libs_stm/inc/stm32f10x/stm32f10x_tim.h deleted file mode 100644 index 500c195d2..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_tim.h +++ /dev/null @@ -1,1133 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_tim.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the TIM firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_TIM_H -#define __STM32F10x_TIM_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup TIM - * @{ - */ - -/** @defgroup TIM_Exported_Types - * @{ - */ - -/** - * @brief TIM Time Base Init structure definition - * @note This sturcture is used with all TIMx except for TIM6 and TIM7. - */ - -typedef struct -{ - uint16_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. - This parameter can be a number between 0x0000 and 0xFFFF */ - - uint16_t TIM_CounterMode; /*!< Specifies the counter mode. - This parameter can be a value of @ref TIM_Counter_Mode */ - - uint16_t TIM_Period; /*!< Specifies the period value to be loaded into the active - Auto-Reload Register at the next update event. - This parameter must be a number between 0x0000 and 0xFFFF. */ - - uint16_t TIM_ClockDivision; /*!< Specifies the clock division. - This parameter can be a value of @ref TIM_Clock_Division_CKD */ - - uint8_t TIM_RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter - reaches zero, an update event is generated and counting restarts - from the RCR value (N). - This means in PWM mode that (N+1) corresponds to: - - the number of PWM periods in edge-aligned mode - - the number of half PWM period in center-aligned mode - This parameter must be a number between 0x00 and 0xFF. - @note This parameter is valid only for TIM1 and TIM8. */ -} TIM_TimeBaseInitTypeDef; - -/** - * @brief TIM Output Compare Init structure definition - */ - -typedef struct -{ - uint16_t TIM_OCMode; /*!< Specifies the TIM mode. - This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ - - uint16_t TIM_OutputState; /*!< Specifies the TIM Output Compare state. - This parameter can be a value of @ref TIM_Output_Compare_state */ - - uint16_t TIM_OutputNState; /*!< Specifies the TIM complementary Output Compare state. - This parameter can be a value of @ref TIM_Output_Compare_N_state - @note This parameter is valid only for TIM1 and TIM8. */ - - uint16_t TIM_Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. - This parameter can be a number between 0x0000 and 0xFFFF */ - - uint16_t TIM_OCPolarity; /*!< Specifies the output polarity. - This parameter can be a value of @ref TIM_Output_Compare_Polarity */ - - uint16_t TIM_OCNPolarity; /*!< Specifies the complementary output polarity. - This parameter can be a value of @ref TIM_Output_Compare_N_Polarity - @note This parameter is valid only for TIM1 and TIM8. */ - - uint16_t TIM_OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. - This parameter can be a value of @ref TIM_Output_Compare_Idle_State - @note This parameter is valid only for TIM1 and TIM8. */ - - uint16_t TIM_OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. - This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State - @note This parameter is valid only for TIM1 and TIM8. */ -} TIM_OCInitTypeDef; - -/** - * @brief TIM Input Capture Init structure definition - */ - -typedef struct -{ - - uint16_t TIM_Channel; /*!< Specifies the TIM channel. - This parameter can be a value of @ref TIM_Channel */ - - uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal. - This parameter can be a value of @ref TIM_Input_Capture_Polarity */ - - uint16_t TIM_ICSelection; /*!< Specifies the input. - This parameter can be a value of @ref TIM_Input_Capture_Selection */ - - uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler. - This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ - - uint16_t TIM_ICFilter; /*!< Specifies the input capture filter. - This parameter can be a number between 0x0 and 0xF */ -} TIM_ICInitTypeDef; - -/** - * @brief BDTR structure definition - * @note This sturcture is used only with TIM1 and TIM8. - */ - -typedef struct -{ - - uint16_t TIM_OSSRState; /*!< Specifies the Off-State selection used in Run mode. - This parameter can be a value of @ref OSSR_Off_State_Selection_for_Run_mode_state */ - - uint16_t TIM_OSSIState; /*!< Specifies the Off-State used in Idle state. - This parameter can be a value of @ref OSSI_Off_State_Selection_for_Idle_mode_state */ - - uint16_t TIM_LOCKLevel; /*!< Specifies the LOCK level parameters. - This parameter can be a value of @ref Lock_level */ - - uint16_t TIM_DeadTime; /*!< Specifies the delay time between the switching-off and the - switching-on of the outputs. - This parameter can be a number between 0x00 and 0xFF */ - - uint16_t TIM_Break; /*!< Specifies whether the TIM Break input is enabled or not. - This parameter can be a value of @ref Break_Input_enable_disable */ - - uint16_t TIM_BreakPolarity; /*!< Specifies the TIM Break Input pin polarity. - This parameter can be a value of @ref Break_Polarity */ - - uint16_t TIM_AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature is enabled or not. - This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */ -} TIM_BDTRInitTypeDef; - -/** @defgroup TIM_Exported_constants - * @{ - */ - -#define IS_TIM_ALL_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM5) || \ - ((PERIPH) == TIM6) || \ - ((PERIPH) == TIM7) || \ - ((PERIPH) == TIM8) || \ - ((PERIPH) == TIM9) || \ - ((PERIPH) == TIM10)|| \ - ((PERIPH) == TIM11)|| \ - ((PERIPH) == TIM12)|| \ - ((PERIPH) == TIM13)|| \ - ((PERIPH) == TIM14)|| \ - ((PERIPH) == TIM15)|| \ - ((PERIPH) == TIM16)|| \ - ((PERIPH) == TIM17)) - -/* LIST1: TIM 1 and 8 */ -#define IS_TIM_LIST1_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM8)) - -/* LIST2: TIM 1, 8, 15 16 and 17 */ -#define IS_TIM_LIST2_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM8) || \ - ((PERIPH) == TIM15)|| \ - ((PERIPH) == TIM16)|| \ - ((PERIPH) == TIM17)) - -/* LIST3: TIM 1, 2, 3, 4, 5 and 8 */ -#define IS_TIM_LIST3_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM5) || \ - ((PERIPH) == TIM8)) - -/* LIST4: TIM 1, 2, 3, 4, 5, 8, 15, 16 and 17 */ -#define IS_TIM_LIST4_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM5) || \ - ((PERIPH) == TIM8) || \ - ((PERIPH) == TIM15)|| \ - ((PERIPH) == TIM16)|| \ - ((PERIPH) == TIM17)) - -/* LIST5: TIM 1, 2, 3, 4, 5, 8 and 15 */ -#define IS_TIM_LIST5_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM5) || \ - ((PERIPH) == TIM8) || \ - ((PERIPH) == TIM15)) - -/* LIST6: TIM 1, 2, 3, 4, 5, 8, 9, 12 and 15 */ -#define IS_TIM_LIST6_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM5) || \ - ((PERIPH) == TIM8) || \ - ((PERIPH) == TIM9) || \ - ((PERIPH) == TIM12)|| \ - ((PERIPH) == TIM15)) - -/* LIST7: TIM 1, 2, 3, 4, 5, 6, 7, 8, 9, 12 and 15 */ -#define IS_TIM_LIST7_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM5) || \ - ((PERIPH) == TIM6) || \ - ((PERIPH) == TIM7) || \ - ((PERIPH) == TIM8) || \ - ((PERIPH) == TIM9) || \ - ((PERIPH) == TIM12)|| \ - ((PERIPH) == TIM15)) - -/* LIST8: TIM 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16 and 17 */ -#define IS_TIM_LIST8_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM5) || \ - ((PERIPH) == TIM8) || \ - ((PERIPH) == TIM9) || \ - ((PERIPH) == TIM10)|| \ - ((PERIPH) == TIM11)|| \ - ((PERIPH) == TIM12)|| \ - ((PERIPH) == TIM13)|| \ - ((PERIPH) == TIM14)|| \ - ((PERIPH) == TIM15)|| \ - ((PERIPH) == TIM16)|| \ - ((PERIPH) == TIM17)) - -/* LIST9: TIM 1, 2, 3, 4, 5, 6, 7, 8, 15, 16, and 17 */ -#define IS_TIM_LIST9_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM5) || \ - ((PERIPH) == TIM6) || \ - ((PERIPH) == TIM7) || \ - ((PERIPH) == TIM8) || \ - ((PERIPH) == TIM15)|| \ - ((PERIPH) == TIM16)|| \ - ((PERIPH) == TIM17)) - -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_and_PWM_modes - * @{ - */ - -#define TIM_OCMode_Timing ((uint16_t)0x0000) -#define TIM_OCMode_Active ((uint16_t)0x0010) -#define TIM_OCMode_Inactive ((uint16_t)0x0020) -#define TIM_OCMode_Toggle ((uint16_t)0x0030) -#define TIM_OCMode_PWM1 ((uint16_t)0x0060) -#define TIM_OCMode_PWM2 ((uint16_t)0x0070) -#define IS_TIM_OC_MODE(MODE) (((MODE) == TIM_OCMode_Timing) || \ - ((MODE) == TIM_OCMode_Active) || \ - ((MODE) == TIM_OCMode_Inactive) || \ - ((MODE) == TIM_OCMode_Toggle)|| \ - ((MODE) == TIM_OCMode_PWM1) || \ - ((MODE) == TIM_OCMode_PWM2)) -#define IS_TIM_OCM(MODE) (((MODE) == TIM_OCMode_Timing) || \ - ((MODE) == TIM_OCMode_Active) || \ - ((MODE) == TIM_OCMode_Inactive) || \ - ((MODE) == TIM_OCMode_Toggle)|| \ - ((MODE) == TIM_OCMode_PWM1) || \ - ((MODE) == TIM_OCMode_PWM2) || \ - ((MODE) == TIM_ForcedAction_Active) || \ - ((MODE) == TIM_ForcedAction_InActive)) -/** - * @} - */ - -/** @defgroup TIM_One_Pulse_Mode - * @{ - */ - -#define TIM_OPMode_Single ((uint16_t)0x0008) -#define TIM_OPMode_Repetitive ((uint16_t)0x0000) -#define IS_TIM_OPM_MODE(MODE) (((MODE) == TIM_OPMode_Single) || \ - ((MODE) == TIM_OPMode_Repetitive)) -/** - * @} - */ - -/** @defgroup TIM_Channel - * @{ - */ - -#define TIM_Channel_1 ((uint16_t)0x0000) -#define TIM_Channel_2 ((uint16_t)0x0004) -#define TIM_Channel_3 ((uint16_t)0x0008) -#define TIM_Channel_4 ((uint16_t)0x000C) -#define IS_TIM_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ - ((CHANNEL) == TIM_Channel_2) || \ - ((CHANNEL) == TIM_Channel_3) || \ - ((CHANNEL) == TIM_Channel_4)) -#define IS_TIM_PWMI_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ - ((CHANNEL) == TIM_Channel_2)) -#define IS_TIM_COMPLEMENTARY_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ - ((CHANNEL) == TIM_Channel_2) || \ - ((CHANNEL) == TIM_Channel_3)) -/** - * @} - */ - -/** @defgroup TIM_Clock_Division_CKD - * @{ - */ - -#define TIM_CKD_DIV1 ((uint16_t)0x0000) -#define TIM_CKD_DIV2 ((uint16_t)0x0100) -#define TIM_CKD_DIV4 ((uint16_t)0x0200) -#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \ - ((DIV) == TIM_CKD_DIV2) || \ - ((DIV) == TIM_CKD_DIV4)) -/** - * @} - */ - -/** @defgroup TIM_Counter_Mode - * @{ - */ - -#define TIM_CounterMode_Up ((uint16_t)0x0000) -#define TIM_CounterMode_Down ((uint16_t)0x0010) -#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020) -#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040) -#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060) -#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) || \ - ((MODE) == TIM_CounterMode_Down) || \ - ((MODE) == TIM_CounterMode_CenterAligned1) || \ - ((MODE) == TIM_CounterMode_CenterAligned2) || \ - ((MODE) == TIM_CounterMode_CenterAligned3)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_Polarity - * @{ - */ - -#define TIM_OCPolarity_High ((uint16_t)0x0000) -#define TIM_OCPolarity_Low ((uint16_t)0x0002) -#define IS_TIM_OC_POLARITY(POLARITY) (((POLARITY) == TIM_OCPolarity_High) || \ - ((POLARITY) == TIM_OCPolarity_Low)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_N_Polarity - * @{ - */ - -#define TIM_OCNPolarity_High ((uint16_t)0x0000) -#define TIM_OCNPolarity_Low ((uint16_t)0x0008) -#define IS_TIM_OCN_POLARITY(POLARITY) (((POLARITY) == TIM_OCNPolarity_High) || \ - ((POLARITY) == TIM_OCNPolarity_Low)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_state - * @{ - */ - -#define TIM_OutputState_Disable ((uint16_t)0x0000) -#define TIM_OutputState_Enable ((uint16_t)0x0001) -#define IS_TIM_OUTPUT_STATE(STATE) (((STATE) == TIM_OutputState_Disable) || \ - ((STATE) == TIM_OutputState_Enable)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_N_state - * @{ - */ - -#define TIM_OutputNState_Disable ((uint16_t)0x0000) -#define TIM_OutputNState_Enable ((uint16_t)0x0004) -#define IS_TIM_OUTPUTN_STATE(STATE) (((STATE) == TIM_OutputNState_Disable) || \ - ((STATE) == TIM_OutputNState_Enable)) -/** - * @} - */ - -/** @defgroup TIM_Capture_Compare_state - * @{ - */ - -#define TIM_CCx_Enable ((uint16_t)0x0001) -#define TIM_CCx_Disable ((uint16_t)0x0000) -#define IS_TIM_CCX(CCX) (((CCX) == TIM_CCx_Enable) || \ - ((CCX) == TIM_CCx_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Capture_Compare_N_state - * @{ - */ - -#define TIM_CCxN_Enable ((uint16_t)0x0004) -#define TIM_CCxN_Disable ((uint16_t)0x0000) -#define IS_TIM_CCXN(CCXN) (((CCXN) == TIM_CCxN_Enable) || \ - ((CCXN) == TIM_CCxN_Disable)) -/** - * @} - */ - -/** @defgroup Break_Input_enable_disable - * @{ - */ - -#define TIM_Break_Enable ((uint16_t)0x1000) -#define TIM_Break_Disable ((uint16_t)0x0000) -#define IS_TIM_BREAK_STATE(STATE) (((STATE) == TIM_Break_Enable) || \ - ((STATE) == TIM_Break_Disable)) -/** - * @} - */ - -/** @defgroup Break_Polarity - * @{ - */ - -#define TIM_BreakPolarity_Low ((uint16_t)0x0000) -#define TIM_BreakPolarity_High ((uint16_t)0x2000) -#define IS_TIM_BREAK_POLARITY(POLARITY) (((POLARITY) == TIM_BreakPolarity_Low) || \ - ((POLARITY) == TIM_BreakPolarity_High)) -/** - * @} - */ - -/** @defgroup TIM_AOE_Bit_Set_Reset - * @{ - */ - -#define TIM_AutomaticOutput_Enable ((uint16_t)0x4000) -#define TIM_AutomaticOutput_Disable ((uint16_t)0x0000) -#define IS_TIM_AUTOMATIC_OUTPUT_STATE(STATE) (((STATE) == TIM_AutomaticOutput_Enable) || \ - ((STATE) == TIM_AutomaticOutput_Disable)) -/** - * @} - */ - -/** @defgroup Lock_level - * @{ - */ - -#define TIM_LOCKLevel_OFF ((uint16_t)0x0000) -#define TIM_LOCKLevel_1 ((uint16_t)0x0100) -#define TIM_LOCKLevel_2 ((uint16_t)0x0200) -#define TIM_LOCKLevel_3 ((uint16_t)0x0300) -#define IS_TIM_LOCK_LEVEL(LEVEL) (((LEVEL) == TIM_LOCKLevel_OFF) || \ - ((LEVEL) == TIM_LOCKLevel_1) || \ - ((LEVEL) == TIM_LOCKLevel_2) || \ - ((LEVEL) == TIM_LOCKLevel_3)) -/** - * @} - */ - -/** @defgroup OSSI_Off_State_Selection_for_Idle_mode_state - * @{ - */ - -#define TIM_OSSIState_Enable ((uint16_t)0x0400) -#define TIM_OSSIState_Disable ((uint16_t)0x0000) -#define IS_TIM_OSSI_STATE(STATE) (((STATE) == TIM_OSSIState_Enable) || \ - ((STATE) == TIM_OSSIState_Disable)) -/** - * @} - */ - -/** @defgroup OSSR_Off_State_Selection_for_Run_mode_state - * @{ - */ - -#define TIM_OSSRState_Enable ((uint16_t)0x0800) -#define TIM_OSSRState_Disable ((uint16_t)0x0000) -#define IS_TIM_OSSR_STATE(STATE) (((STATE) == TIM_OSSRState_Enable) || \ - ((STATE) == TIM_OSSRState_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_Idle_State - * @{ - */ - -#define TIM_OCIdleState_Set ((uint16_t)0x0100) -#define TIM_OCIdleState_Reset ((uint16_t)0x0000) -#define IS_TIM_OCIDLE_STATE(STATE) (((STATE) == TIM_OCIdleState_Set) || \ - ((STATE) == TIM_OCIdleState_Reset)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_N_Idle_State - * @{ - */ - -#define TIM_OCNIdleState_Set ((uint16_t)0x0200) -#define TIM_OCNIdleState_Reset ((uint16_t)0x0000) -#define IS_TIM_OCNIDLE_STATE(STATE) (((STATE) == TIM_OCNIdleState_Set) || \ - ((STATE) == TIM_OCNIdleState_Reset)) -/** - * @} - */ - -/** @defgroup TIM_Input_Capture_Polarity - * @{ - */ - -#define TIM_ICPolarity_Rising ((uint16_t)0x0000) -#define TIM_ICPolarity_Falling ((uint16_t)0x0002) -#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \ - ((POLARITY) == TIM_ICPolarity_Falling)) -/** - * @} - */ - -/** @defgroup TIM_Input_Capture_Selection - * @{ - */ - -#define TIM_ICSelection_DirectTI ((uint16_t)0x0001) /*!< TIM Input 1, 2, 3 or 4 is selected to be - connected to IC1, IC2, IC3 or IC4, respectively */ -#define TIM_ICSelection_IndirectTI ((uint16_t)0x0002) /*!< TIM Input 1, 2, 3 or 4 is selected to be - connected to IC2, IC1, IC4 or IC3, respectively. */ -#define TIM_ICSelection_TRC ((uint16_t)0x0003) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC. */ -#define IS_TIM_IC_SELECTION(SELECTION) (((SELECTION) == TIM_ICSelection_DirectTI) || \ - ((SELECTION) == TIM_ICSelection_IndirectTI) || \ - ((SELECTION) == TIM_ICSelection_TRC)) -/** - * @} - */ - -/** @defgroup TIM_Input_Capture_Prescaler - * @{ - */ - -#define TIM_ICPSC_DIV1 ((uint16_t)0x0000) /*!< Capture performed each time an edge is detected on the capture input. */ -#define TIM_ICPSC_DIV2 ((uint16_t)0x0004) /*!< Capture performed once every 2 events. */ -#define TIM_ICPSC_DIV4 ((uint16_t)0x0008) /*!< Capture performed once every 4 events. */ -#define TIM_ICPSC_DIV8 ((uint16_t)0x000C) /*!< Capture performed once every 8 events. */ -#define IS_TIM_IC_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ICPSC_DIV1) || \ - ((PRESCALER) == TIM_ICPSC_DIV2) || \ - ((PRESCALER) == TIM_ICPSC_DIV4) || \ - ((PRESCALER) == TIM_ICPSC_DIV8)) -/** - * @} - */ - -/** @defgroup TIM_interrupt_sources - * @{ - */ - -#define TIM_IT_Update ((uint16_t)0x0001) -#define TIM_IT_CC1 ((uint16_t)0x0002) -#define TIM_IT_CC2 ((uint16_t)0x0004) -#define TIM_IT_CC3 ((uint16_t)0x0008) -#define TIM_IT_CC4 ((uint16_t)0x0010) -#define TIM_IT_COM ((uint16_t)0x0020) -#define TIM_IT_Trigger ((uint16_t)0x0040) -#define TIM_IT_Break ((uint16_t)0x0080) -#define IS_TIM_IT(IT) ((((IT) & (uint16_t)0xFF00) == 0x0000) && ((IT) != 0x0000)) - -#define IS_TIM_GET_IT(IT) (((IT) == TIM_IT_Update) || \ - ((IT) == TIM_IT_CC1) || \ - ((IT) == TIM_IT_CC2) || \ - ((IT) == TIM_IT_CC3) || \ - ((IT) == TIM_IT_CC4) || \ - ((IT) == TIM_IT_COM) || \ - ((IT) == TIM_IT_Trigger) || \ - ((IT) == TIM_IT_Break)) -/** - * @} - */ - -/** @defgroup TIM_DMA_Base_address - * @{ - */ - -#define TIM_DMABase_CR1 ((uint16_t)0x0000) -#define TIM_DMABase_CR2 ((uint16_t)0x0001) -#define TIM_DMABase_SMCR ((uint16_t)0x0002) -#define TIM_DMABase_DIER ((uint16_t)0x0003) -#define TIM_DMABase_SR ((uint16_t)0x0004) -#define TIM_DMABase_EGR ((uint16_t)0x0005) -#define TIM_DMABase_CCMR1 ((uint16_t)0x0006) -#define TIM_DMABase_CCMR2 ((uint16_t)0x0007) -#define TIM_DMABase_CCER ((uint16_t)0x0008) -#define TIM_DMABase_CNT ((uint16_t)0x0009) -#define TIM_DMABase_PSC ((uint16_t)0x000A) -#define TIM_DMABase_ARR ((uint16_t)0x000B) -#define TIM_DMABase_RCR ((uint16_t)0x000C) -#define TIM_DMABase_CCR1 ((uint16_t)0x000D) -#define TIM_DMABase_CCR2 ((uint16_t)0x000E) -#define TIM_DMABase_CCR3 ((uint16_t)0x000F) -#define TIM_DMABase_CCR4 ((uint16_t)0x0010) -#define TIM_DMABase_BDTR ((uint16_t)0x0011) -#define TIM_DMABase_DCR ((uint16_t)0x0012) -#define IS_TIM_DMA_BASE(BASE) (((BASE) == TIM_DMABase_CR1) || \ - ((BASE) == TIM_DMABase_CR2) || \ - ((BASE) == TIM_DMABase_SMCR) || \ - ((BASE) == TIM_DMABase_DIER) || \ - ((BASE) == TIM_DMABase_SR) || \ - ((BASE) == TIM_DMABase_EGR) || \ - ((BASE) == TIM_DMABase_CCMR1) || \ - ((BASE) == TIM_DMABase_CCMR2) || \ - ((BASE) == TIM_DMABase_CCER) || \ - ((BASE) == TIM_DMABase_CNT) || \ - ((BASE) == TIM_DMABase_PSC) || \ - ((BASE) == TIM_DMABase_ARR) || \ - ((BASE) == TIM_DMABase_RCR) || \ - ((BASE) == TIM_DMABase_CCR1) || \ - ((BASE) == TIM_DMABase_CCR2) || \ - ((BASE) == TIM_DMABase_CCR3) || \ - ((BASE) == TIM_DMABase_CCR4) || \ - ((BASE) == TIM_DMABase_BDTR) || \ - ((BASE) == TIM_DMABase_DCR)) -/** - * @} - */ - -/** @defgroup TIM_DMA_Burst_Length - * @{ - */ - -#define TIM_DMABurstLength_1Byte ((uint16_t)0x0000) -#define TIM_DMABurstLength_2Bytes ((uint16_t)0x0100) -#define TIM_DMABurstLength_3Bytes ((uint16_t)0x0200) -#define TIM_DMABurstLength_4Bytes ((uint16_t)0x0300) -#define TIM_DMABurstLength_5Bytes ((uint16_t)0x0400) -#define TIM_DMABurstLength_6Bytes ((uint16_t)0x0500) -#define TIM_DMABurstLength_7Bytes ((uint16_t)0x0600) -#define TIM_DMABurstLength_8Bytes ((uint16_t)0x0700) -#define TIM_DMABurstLength_9Bytes ((uint16_t)0x0800) -#define TIM_DMABurstLength_10Bytes ((uint16_t)0x0900) -#define TIM_DMABurstLength_11Bytes ((uint16_t)0x0A00) -#define TIM_DMABurstLength_12Bytes ((uint16_t)0x0B00) -#define TIM_DMABurstLength_13Bytes ((uint16_t)0x0C00) -#define TIM_DMABurstLength_14Bytes ((uint16_t)0x0D00) -#define TIM_DMABurstLength_15Bytes ((uint16_t)0x0E00) -#define TIM_DMABurstLength_16Bytes ((uint16_t)0x0F00) -#define TIM_DMABurstLength_17Bytes ((uint16_t)0x1000) -#define TIM_DMABurstLength_18Bytes ((uint16_t)0x1100) -#define IS_TIM_DMA_LENGTH(LENGTH) (((LENGTH) == TIM_DMABurstLength_1Byte) || \ - ((LENGTH) == TIM_DMABurstLength_2Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_3Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_4Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_5Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_6Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_7Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_8Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_9Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_10Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_11Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_12Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_13Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_14Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_15Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_16Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_17Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_18Bytes)) -/** - * @} - */ - -/** @defgroup TIM_DMA_sources - * @{ - */ - -#define TIM_DMA_Update ((uint16_t)0x0100) -#define TIM_DMA_CC1 ((uint16_t)0x0200) -#define TIM_DMA_CC2 ((uint16_t)0x0400) -#define TIM_DMA_CC3 ((uint16_t)0x0800) -#define TIM_DMA_CC4 ((uint16_t)0x1000) -#define TIM_DMA_COM ((uint16_t)0x2000) -#define TIM_DMA_Trigger ((uint16_t)0x4000) -#define IS_TIM_DMA_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0x80FF) == 0x0000) && ((SOURCE) != 0x0000)) - -/** - * @} - */ - -/** @defgroup TIM_External_Trigger_Prescaler - * @{ - */ - -#define TIM_ExtTRGPSC_OFF ((uint16_t)0x0000) -#define TIM_ExtTRGPSC_DIV2 ((uint16_t)0x1000) -#define TIM_ExtTRGPSC_DIV4 ((uint16_t)0x2000) -#define TIM_ExtTRGPSC_DIV8 ((uint16_t)0x3000) -#define IS_TIM_EXT_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ExtTRGPSC_OFF) || \ - ((PRESCALER) == TIM_ExtTRGPSC_DIV2) || \ - ((PRESCALER) == TIM_ExtTRGPSC_DIV4) || \ - ((PRESCALER) == TIM_ExtTRGPSC_DIV8)) -/** - * @} - */ - -/** @defgroup TIM_Internal_Trigger_Selection - * @{ - */ - -#define TIM_TS_ITR0 ((uint16_t)0x0000) -#define TIM_TS_ITR1 ((uint16_t)0x0010) -#define TIM_TS_ITR2 ((uint16_t)0x0020) -#define TIM_TS_ITR3 ((uint16_t)0x0030) -#define TIM_TS_TI1F_ED ((uint16_t)0x0040) -#define TIM_TS_TI1FP1 ((uint16_t)0x0050) -#define TIM_TS_TI2FP2 ((uint16_t)0x0060) -#define TIM_TS_ETRF ((uint16_t)0x0070) -#define IS_TIM_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ - ((SELECTION) == TIM_TS_ITR1) || \ - ((SELECTION) == TIM_TS_ITR2) || \ - ((SELECTION) == TIM_TS_ITR3) || \ - ((SELECTION) == TIM_TS_TI1F_ED) || \ - ((SELECTION) == TIM_TS_TI1FP1) || \ - ((SELECTION) == TIM_TS_TI2FP2) || \ - ((SELECTION) == TIM_TS_ETRF)) -#define IS_TIM_INTERNAL_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ - ((SELECTION) == TIM_TS_ITR1) || \ - ((SELECTION) == TIM_TS_ITR2) || \ - ((SELECTION) == TIM_TS_ITR3)) -/** - * @} - */ - -/** @defgroup TIM_TIx_External_Clock_Source - * @{ - */ - -#define TIM_TIxExternalCLK1Source_TI1 ((uint16_t)0x0050) -#define TIM_TIxExternalCLK1Source_TI2 ((uint16_t)0x0060) -#define TIM_TIxExternalCLK1Source_TI1ED ((uint16_t)0x0040) -#define IS_TIM_TIXCLK_SOURCE(SOURCE) (((SOURCE) == TIM_TIxExternalCLK1Source_TI1) || \ - ((SOURCE) == TIM_TIxExternalCLK1Source_TI2) || \ - ((SOURCE) == TIM_TIxExternalCLK1Source_TI1ED)) -/** - * @} - */ - -/** @defgroup TIM_External_Trigger_Polarity - * @{ - */ -#define TIM_ExtTRGPolarity_Inverted ((uint16_t)0x8000) -#define TIM_ExtTRGPolarity_NonInverted ((uint16_t)0x0000) -#define IS_TIM_EXT_POLARITY(POLARITY) (((POLARITY) == TIM_ExtTRGPolarity_Inverted) || \ - ((POLARITY) == TIM_ExtTRGPolarity_NonInverted)) -/** - * @} - */ - -/** @defgroup TIM_Prescaler_Reload_Mode - * @{ - */ - -#define TIM_PSCReloadMode_Update ((uint16_t)0x0000) -#define TIM_PSCReloadMode_Immediate ((uint16_t)0x0001) -#define IS_TIM_PRESCALER_RELOAD(RELOAD) (((RELOAD) == TIM_PSCReloadMode_Update) || \ - ((RELOAD) == TIM_PSCReloadMode_Immediate)) -/** - * @} - */ - -/** @defgroup TIM_Forced_Action - * @{ - */ - -#define TIM_ForcedAction_Active ((uint16_t)0x0050) -#define TIM_ForcedAction_InActive ((uint16_t)0x0040) -#define IS_TIM_FORCED_ACTION(ACTION) (((ACTION) == TIM_ForcedAction_Active) || \ - ((ACTION) == TIM_ForcedAction_InActive)) -/** - * @} - */ - -/** @defgroup TIM_Encoder_Mode - * @{ - */ - -#define TIM_EncoderMode_TI1 ((uint16_t)0x0001) -#define TIM_EncoderMode_TI2 ((uint16_t)0x0002) -#define TIM_EncoderMode_TI12 ((uint16_t)0x0003) -#define IS_TIM_ENCODER_MODE(MODE) (((MODE) == TIM_EncoderMode_TI1) || \ - ((MODE) == TIM_EncoderMode_TI2) || \ - ((MODE) == TIM_EncoderMode_TI12)) -/** - * @} - */ - - -/** @defgroup TIM_Event_Source - * @{ - */ - -#define TIM_EventSource_Update ((uint16_t)0x0001) -#define TIM_EventSource_CC1 ((uint16_t)0x0002) -#define TIM_EventSource_CC2 ((uint16_t)0x0004) -#define TIM_EventSource_CC3 ((uint16_t)0x0008) -#define TIM_EventSource_CC4 ((uint16_t)0x0010) -#define TIM_EventSource_COM ((uint16_t)0x0020) -#define TIM_EventSource_Trigger ((uint16_t)0x0040) -#define TIM_EventSource_Break ((uint16_t)0x0080) -#define IS_TIM_EVENT_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0xFF00) == 0x0000) && ((SOURCE) != 0x0000)) - -/** - * @} - */ - -/** @defgroup TIM_Update_Source - * @{ - */ - -#define TIM_UpdateSource_Global ((uint16_t)0x0000) /*!< Source of update is the counter overflow/underflow - or the setting of UG bit, or an update generation - through the slave mode controller. */ -#define TIM_UpdateSource_Regular ((uint16_t)0x0001) /*!< Source of update is counter overflow/underflow. */ -#define IS_TIM_UPDATE_SOURCE(SOURCE) (((SOURCE) == TIM_UpdateSource_Global) || \ - ((SOURCE) == TIM_UpdateSource_Regular)) -/** - * @} - */ - -/** @defgroup TIM_Ouput_Compare_Preload_State - * @{ - */ - -#define TIM_OCPreload_Enable ((uint16_t)0x0008) -#define TIM_OCPreload_Disable ((uint16_t)0x0000) -#define IS_TIM_OCPRELOAD_STATE(STATE) (((STATE) == TIM_OCPreload_Enable) || \ - ((STATE) == TIM_OCPreload_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Ouput_Compare_Fast_State - * @{ - */ - -#define TIM_OCFast_Enable ((uint16_t)0x0004) -#define TIM_OCFast_Disable ((uint16_t)0x0000) -#define IS_TIM_OCFAST_STATE(STATE) (((STATE) == TIM_OCFast_Enable) || \ - ((STATE) == TIM_OCFast_Disable)) - -/** - * @} - */ - -/** @defgroup TIM_Ouput_Compare_Clear_State - * @{ - */ - -#define TIM_OCClear_Enable ((uint16_t)0x0080) -#define TIM_OCClear_Disable ((uint16_t)0x0000) -#define IS_TIM_OCCLEAR_STATE(STATE) (((STATE) == TIM_OCClear_Enable) || \ - ((STATE) == TIM_OCClear_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Trigger_Output_Source - * @{ - */ - -#define TIM_TRGOSource_Reset ((uint16_t)0x0000) -#define TIM_TRGOSource_Enable ((uint16_t)0x0010) -#define TIM_TRGOSource_Update ((uint16_t)0x0020) -#define TIM_TRGOSource_OC1 ((uint16_t)0x0030) -#define TIM_TRGOSource_OC1Ref ((uint16_t)0x0040) -#define TIM_TRGOSource_OC2Ref ((uint16_t)0x0050) -#define TIM_TRGOSource_OC3Ref ((uint16_t)0x0060) -#define TIM_TRGOSource_OC4Ref ((uint16_t)0x0070) -#define IS_TIM_TRGO_SOURCE(SOURCE) (((SOURCE) == TIM_TRGOSource_Reset) || \ - ((SOURCE) == TIM_TRGOSource_Enable) || \ - ((SOURCE) == TIM_TRGOSource_Update) || \ - ((SOURCE) == TIM_TRGOSource_OC1) || \ - ((SOURCE) == TIM_TRGOSource_OC1Ref) || \ - ((SOURCE) == TIM_TRGOSource_OC2Ref) || \ - ((SOURCE) == TIM_TRGOSource_OC3Ref) || \ - ((SOURCE) == TIM_TRGOSource_OC4Ref)) -/** - * @} - */ - -/** @defgroup TIM_Slave_Mode - * @{ - */ - -#define TIM_SlaveMode_Reset ((uint16_t)0x0004) -#define TIM_SlaveMode_Gated ((uint16_t)0x0005) -#define TIM_SlaveMode_Trigger ((uint16_t)0x0006) -#define TIM_SlaveMode_External1 ((uint16_t)0x0007) -#define IS_TIM_SLAVE_MODE(MODE) (((MODE) == TIM_SlaveMode_Reset) || \ - ((MODE) == TIM_SlaveMode_Gated) || \ - ((MODE) == TIM_SlaveMode_Trigger) || \ - ((MODE) == TIM_SlaveMode_External1)) -/** - * @} - */ - -/** @defgroup TIM_Master_Slave_Mode - * @{ - */ - -#define TIM_MasterSlaveMode_Enable ((uint16_t)0x0080) -#define TIM_MasterSlaveMode_Disable ((uint16_t)0x0000) -#define IS_TIM_MSM_STATE(STATE) (((STATE) == TIM_MasterSlaveMode_Enable) || \ - ((STATE) == TIM_MasterSlaveMode_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Flags - * @{ - */ - -#define TIM_FLAG_Update ((uint16_t)0x0001) -#define TIM_FLAG_CC1 ((uint16_t)0x0002) -#define TIM_FLAG_CC2 ((uint16_t)0x0004) -#define TIM_FLAG_CC3 ((uint16_t)0x0008) -#define TIM_FLAG_CC4 ((uint16_t)0x0010) -#define TIM_FLAG_COM ((uint16_t)0x0020) -#define TIM_FLAG_Trigger ((uint16_t)0x0040) -#define TIM_FLAG_Break ((uint16_t)0x0080) -#define TIM_FLAG_CC1OF ((uint16_t)0x0200) -#define TIM_FLAG_CC2OF ((uint16_t)0x0400) -#define TIM_FLAG_CC3OF ((uint16_t)0x0800) -#define TIM_FLAG_CC4OF ((uint16_t)0x1000) -#define IS_TIM_GET_FLAG(FLAG) (((FLAG) == TIM_FLAG_Update) || \ - ((FLAG) == TIM_FLAG_CC1) || \ - ((FLAG) == TIM_FLAG_CC2) || \ - ((FLAG) == TIM_FLAG_CC3) || \ - ((FLAG) == TIM_FLAG_CC4) || \ - ((FLAG) == TIM_FLAG_COM) || \ - ((FLAG) == TIM_FLAG_Trigger) || \ - ((FLAG) == TIM_FLAG_Break) || \ - ((FLAG) == TIM_FLAG_CC1OF) || \ - ((FLAG) == TIM_FLAG_CC2OF) || \ - ((FLAG) == TIM_FLAG_CC3OF) || \ - ((FLAG) == TIM_FLAG_CC4OF)) - - -#define IS_TIM_CLEAR_FLAG(TIM_FLAG) ((((TIM_FLAG) & (uint16_t)0xE100) == 0x0000) && ((TIM_FLAG) != 0x0000)) -/** - * @} - */ - -/** @defgroup TIM_Input_Capture_Filer_Value - * @{ - */ - -#define IS_TIM_IC_FILTER(ICFILTER) ((ICFILTER) <= 0xF) -/** - * @} - */ - -/** @defgroup TIM_External_Trigger_Filter - * @{ - */ - -#define IS_TIM_EXT_FILTER(EXTFILTER) ((EXTFILTER) <= 0xF) -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup TIM_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup TIM_Exported_Functions - * @{ - */ - -void TIM_DeInit(TIM_TypeDef* TIMx); -void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); -void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); -void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); -void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct); -void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); -void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct); -void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct); -void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); -void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState); -void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState); -void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource); -void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength); -void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState); -void TIM_InternalClockConfig(TIM_TypeDef* TIMx); -void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); -void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, - uint16_t TIM_ICPolarity, uint16_t ICFilter); -void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, - uint16_t ExtTRGFilter); -void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, - uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); -void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, - uint16_t ExtTRGFilter); -void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode); -void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode); -void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); -void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, - uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity); -void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); -void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); -void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); -void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); -void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState); -void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState); -void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState); -void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState); -void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); -void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); -void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); -void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); -void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); -void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); -void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); -void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); -void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); -void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); -void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); -void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); -void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); -void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); -void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); -void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); -void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); -void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); -void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); -void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx); -void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN); -void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode); -void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState); -void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource); -void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState); -void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode); -void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource); -void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); -void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode); -void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter); -void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload); -void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1); -void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2); -void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3); -void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4); -void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); -void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); -void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); -void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); -void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD); -uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx); -uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx); -uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx); -uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx); -uint16_t TIM_GetCounter(TIM_TypeDef* TIMx); -uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx); -FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); -void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); -ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT); -void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F10x_TIM_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_usart.h b/example/libs_stm/inc/stm32f10x/stm32f10x_usart.h deleted file mode 100644 index b79855a1d..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_usart.h +++ /dev/null @@ -1,411 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_usart.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the USART - * firmware library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_USART_H -#define __STM32F10x_USART_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup USART - * @{ - */ - -/** @defgroup USART_Exported_Types - * @{ - */ - -/** - * @brief USART Init Structure definition - */ - -typedef struct -{ - uint32_t USART_BaudRate; /*!< This member configures the USART communication baud rate. - The baud rate is computed using the following formula: - - IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate))) - - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */ - - uint16_t USART_WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. - This parameter can be a value of @ref USART_Word_Length */ - - uint16_t USART_StopBits; /*!< Specifies the number of stop bits transmitted. - This parameter can be a value of @ref USART_Stop_Bits */ - - uint16_t USART_Parity; /*!< Specifies the parity mode. - This parameter can be a value of @ref USART_Parity - @note When parity is enabled, the computed parity is inserted - at the MSB position of the transmitted data (9th bit when - the word length is set to 9 data bits; 8th bit when the - word length is set to 8 data bits). */ - - uint16_t USART_Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled. - This parameter can be a value of @ref USART_Mode */ - - uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled - or disabled. - This parameter can be a value of @ref USART_Hardware_Flow_Control */ -} USART_InitTypeDef; - -/** - * @brief USART Clock Init Structure definition - */ - -typedef struct -{ - - uint16_t USART_Clock; /*!< Specifies whether the USART clock is enabled or disabled. - This parameter can be a value of @ref USART_Clock */ - - uint16_t USART_CPOL; /*!< Specifies the steady state value of the serial clock. - This parameter can be a value of @ref USART_Clock_Polarity */ - - uint16_t USART_CPHA; /*!< Specifies the clock transition on which the bit capture is made. - This parameter can be a value of @ref USART_Clock_Phase */ - - uint16_t USART_LastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted - data bit (MSB) has to be output on the SCLK pin in synchronous mode. - This parameter can be a value of @ref USART_Last_Bit */ -} USART_ClockInitTypeDef; - -/** - * @} - */ - -/** @defgroup USART_Exported_Constants - * @{ - */ - -#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \ - ((PERIPH) == USART2) || \ - ((PERIPH) == USART3) || \ - ((PERIPH) == UART4) || \ - ((PERIPH) == UART5)) - -#define IS_USART_123_PERIPH(PERIPH) (((PERIPH) == USART1) || \ - ((PERIPH) == USART2) || \ - ((PERIPH) == USART3)) - -#define IS_USART_1234_PERIPH(PERIPH) (((PERIPH) == USART1) || \ - ((PERIPH) == USART2) || \ - ((PERIPH) == USART3) || \ - ((PERIPH) == UART4)) -/** @defgroup USART_Word_Length - * @{ - */ - -#define USART_WordLength_8b ((uint16_t)0x0000) -#define USART_WordLength_9b ((uint16_t)0x1000) - -#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WordLength_8b) || \ - ((LENGTH) == USART_WordLength_9b)) -/** - * @} - */ - -/** @defgroup USART_Stop_Bits - * @{ - */ - -#define USART_StopBits_1 ((uint16_t)0x0000) -#define USART_StopBits_0_5 ((uint16_t)0x1000) -#define USART_StopBits_2 ((uint16_t)0x2000) -#define USART_StopBits_1_5 ((uint16_t)0x3000) -#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_StopBits_1) || \ - ((STOPBITS) == USART_StopBits_0_5) || \ - ((STOPBITS) == USART_StopBits_2) || \ - ((STOPBITS) == USART_StopBits_1_5)) -/** - * @} - */ - -/** @defgroup USART_Parity - * @{ - */ - -#define USART_Parity_No ((uint16_t)0x0000) -#define USART_Parity_Even ((uint16_t)0x0400) -#define USART_Parity_Odd ((uint16_t)0x0600) -#define IS_USART_PARITY(PARITY) (((PARITY) == USART_Parity_No) || \ - ((PARITY) == USART_Parity_Even) || \ - ((PARITY) == USART_Parity_Odd)) -/** - * @} - */ - -/** @defgroup USART_Mode - * @{ - */ - -#define USART_Mode_Rx ((uint16_t)0x0004) -#define USART_Mode_Tx ((uint16_t)0x0008) -#define IS_USART_MODE(MODE) ((((MODE) & (uint16_t)0xFFF3) == 0x00) && ((MODE) != (uint16_t)0x00)) -/** - * @} - */ - -/** @defgroup USART_Hardware_Flow_Control - * @{ - */ -#define USART_HardwareFlowControl_None ((uint16_t)0x0000) -#define USART_HardwareFlowControl_RTS ((uint16_t)0x0100) -#define USART_HardwareFlowControl_CTS ((uint16_t)0x0200) -#define USART_HardwareFlowControl_RTS_CTS ((uint16_t)0x0300) -#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)\ - (((CONTROL) == USART_HardwareFlowControl_None) || \ - ((CONTROL) == USART_HardwareFlowControl_RTS) || \ - ((CONTROL) == USART_HardwareFlowControl_CTS) || \ - ((CONTROL) == USART_HardwareFlowControl_RTS_CTS)) -/** - * @} - */ - -/** @defgroup USART_Clock - * @{ - */ -#define USART_Clock_Disable ((uint16_t)0x0000) -#define USART_Clock_Enable ((uint16_t)0x0800) -#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_Clock_Disable) || \ - ((CLOCK) == USART_Clock_Enable)) -/** - * @} - */ - -/** @defgroup USART_Clock_Polarity - * @{ - */ - -#define USART_CPOL_Low ((uint16_t)0x0000) -#define USART_CPOL_High ((uint16_t)0x0400) -#define IS_USART_CPOL(CPOL) (((CPOL) == USART_CPOL_Low) || ((CPOL) == USART_CPOL_High)) - -/** - * @} - */ - -/** @defgroup USART_Clock_Phase - * @{ - */ - -#define USART_CPHA_1Edge ((uint16_t)0x0000) -#define USART_CPHA_2Edge ((uint16_t)0x0200) -#define IS_USART_CPHA(CPHA) (((CPHA) == USART_CPHA_1Edge) || ((CPHA) == USART_CPHA_2Edge)) - -/** - * @} - */ - -/** @defgroup USART_Last_Bit - * @{ - */ - -#define USART_LastBit_Disable ((uint16_t)0x0000) -#define USART_LastBit_Enable ((uint16_t)0x0100) -#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LastBit_Disable) || \ - ((LASTBIT) == USART_LastBit_Enable)) -/** - * @} - */ - -/** @defgroup USART_Interrupt_definition - * @{ - */ - -#define USART_IT_PE ((uint16_t)0x0028) -#define USART_IT_TXE ((uint16_t)0x0727) -#define USART_IT_TC ((uint16_t)0x0626) -#define USART_IT_RXNE ((uint16_t)0x0525) -#define USART_IT_IDLE ((uint16_t)0x0424) -#define USART_IT_LBD ((uint16_t)0x0846) -#define USART_IT_CTS ((uint16_t)0x096A) -#define USART_IT_ERR ((uint16_t)0x0060) -#define USART_IT_ORE ((uint16_t)0x0360) -#define USART_IT_NE ((uint16_t)0x0260) -#define USART_IT_FE ((uint16_t)0x0160) -#define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ - ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ - ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ - ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR)) -#define IS_USART_GET_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ - ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ - ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ - ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ORE) || \ - ((IT) == USART_IT_NE) || ((IT) == USART_IT_FE)) -#define IS_USART_CLEAR_IT(IT) (((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ - ((IT) == USART_IT_LBD) || ((IT) == USART_IT_CTS)) -/** - * @} - */ - -/** @defgroup USART_DMA_Requests - * @{ - */ - -#define USART_DMAReq_Tx ((uint16_t)0x0080) -#define USART_DMAReq_Rx ((uint16_t)0x0040) -#define IS_USART_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFF3F) == 0x00) && ((DMAREQ) != (uint16_t)0x00)) - -/** - * @} - */ - -/** @defgroup USART_WakeUp_methods - * @{ - */ - -#define USART_WakeUp_IdleLine ((uint16_t)0x0000) -#define USART_WakeUp_AddressMark ((uint16_t)0x0800) -#define IS_USART_WAKEUP(WAKEUP) (((WAKEUP) == USART_WakeUp_IdleLine) || \ - ((WAKEUP) == USART_WakeUp_AddressMark)) -/** - * @} - */ - -/** @defgroup USART_LIN_Break_Detection_Length - * @{ - */ - -#define USART_LINBreakDetectLength_10b ((uint16_t)0x0000) -#define USART_LINBreakDetectLength_11b ((uint16_t)0x0020) -#define IS_USART_LIN_BREAK_DETECT_LENGTH(LENGTH) \ - (((LENGTH) == USART_LINBreakDetectLength_10b) || \ - ((LENGTH) == USART_LINBreakDetectLength_11b)) -/** - * @} - */ - -/** @defgroup USART_IrDA_Low_Power - * @{ - */ - -#define USART_IrDAMode_LowPower ((uint16_t)0x0004) -#define USART_IrDAMode_Normal ((uint16_t)0x0000) -#define IS_USART_IRDA_MODE(MODE) (((MODE) == USART_IrDAMode_LowPower) || \ - ((MODE) == USART_IrDAMode_Normal)) -/** - * @} - */ - -/** @defgroup USART_Flags - * @{ - */ - -#define USART_FLAG_CTS ((uint16_t)0x0200) -#define USART_FLAG_LBD ((uint16_t)0x0100) -#define USART_FLAG_TXE ((uint16_t)0x0080) -#define USART_FLAG_TC ((uint16_t)0x0040) -#define USART_FLAG_RXNE ((uint16_t)0x0020) -#define USART_FLAG_IDLE ((uint16_t)0x0010) -#define USART_FLAG_ORE ((uint16_t)0x0008) -#define USART_FLAG_NE ((uint16_t)0x0004) -#define USART_FLAG_FE ((uint16_t)0x0002) -#define USART_FLAG_PE ((uint16_t)0x0001) -#define IS_USART_FLAG(FLAG) (((FLAG) == USART_FLAG_PE) || ((FLAG) == USART_FLAG_TXE) || \ - ((FLAG) == USART_FLAG_TC) || ((FLAG) == USART_FLAG_RXNE) || \ - ((FLAG) == USART_FLAG_IDLE) || ((FLAG) == USART_FLAG_LBD) || \ - ((FLAG) == USART_FLAG_CTS) || ((FLAG) == USART_FLAG_ORE) || \ - ((FLAG) == USART_FLAG_NE) || ((FLAG) == USART_FLAG_FE)) - -#define IS_USART_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFC9F) == 0x00) && ((FLAG) != (uint16_t)0x00)) -#define IS_USART_PERIPH_FLAG(PERIPH, USART_FLAG) ((((*(uint32_t*)&(PERIPH)) != UART4_BASE) &&\ - ((*(uint32_t*)&(PERIPH)) != UART5_BASE)) \ - || ((USART_FLAG) != USART_FLAG_CTS)) -#define IS_USART_BAUDRATE(BAUDRATE) (((BAUDRATE) > 0) && ((BAUDRATE) < 0x0044AA21)) -#define IS_USART_ADDRESS(ADDRESS) ((ADDRESS) <= 0xF) -#define IS_USART_DATA(DATA) ((DATA) <= 0x1FF) - -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup USART_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USART_Exported_Functions - * @{ - */ - -void USART_DeInit(USART_TypeDef* USARTx); -void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct); -void USART_StructInit(USART_InitTypeDef* USART_InitStruct); -void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct); -void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct); -void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState); -void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState); -void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address); -void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp); -void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength); -void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_SendData(USART_TypeDef* USARTx, uint16_t Data); -uint16_t USART_ReceiveData(USART_TypeDef* USARTx); -void USART_SendBreak(USART_TypeDef* USARTx); -void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime); -void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler); -void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode); -void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState); -FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); -void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG); -ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT); -void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_USART_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32f10x/stm32f10x_wwdg.h b/example/libs_stm/inc/stm32f10x/stm32f10x_wwdg.h deleted file mode 100644 index fe238cdb9..000000000 --- a/example/libs_stm/inc/stm32f10x/stm32f10x_wwdg.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_wwdg.h - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file contains all the functions prototypes for the WWDG firmware - * library. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F10x_WWDG_H -#define __STM32F10x_WWDG_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @addtogroup WWDG - * @{ - */ - -/** @defgroup WWDG_Exported_Types - * @{ - */ - -/** - * @} - */ - -/** @defgroup WWDG_Exported_Constants - * @{ - */ - -/** @defgroup WWDG_Prescaler - * @{ - */ - -#define WWDG_Prescaler_1 ((uint32_t)0x00000000) -#define WWDG_Prescaler_2 ((uint32_t)0x00000080) -#define WWDG_Prescaler_4 ((uint32_t)0x00000100) -#define WWDG_Prescaler_8 ((uint32_t)0x00000180) -#define IS_WWDG_PRESCALER(PRESCALER) (((PRESCALER) == WWDG_Prescaler_1) || \ - ((PRESCALER) == WWDG_Prescaler_2) || \ - ((PRESCALER) == WWDG_Prescaler_4) || \ - ((PRESCALER) == WWDG_Prescaler_8)) -#define IS_WWDG_WINDOW_VALUE(VALUE) ((VALUE) <= 0x7F) -#define IS_WWDG_COUNTER(COUNTER) (((COUNTER) >= 0x40) && ((COUNTER) <= 0x7F)) - -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup WWDG_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup WWDG_Exported_Functions - * @{ - */ - -void WWDG_DeInit(void); -void WWDG_SetPrescaler(uint32_t WWDG_Prescaler); -void WWDG_SetWindowValue(uint8_t WindowValue); -void WWDG_EnableIT(void); -void WWDG_SetCounter(uint8_t Counter); -void WWDG_Enable(uint8_t Counter); -FlagStatus WWDG_GetFlagStatus(void); -void WWDG_ClearFlag(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F10x_WWDG_H */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/misc.h b/example/libs_stm/inc/stm32l1xx/misc.h deleted file mode 100644 index cc551902f..000000000 --- a/example/libs_stm/inc/stm32l1xx/misc.h +++ /dev/null @@ -1,196 +0,0 @@ -/** - ****************************************************************************** - * @file misc.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the miscellaneous - * firmware library functions (add-on to CMSIS functions). - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __MISC_H -#define __MISC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup MISC - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief NVIC Init Structure definition - */ - -typedef struct -{ - uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled. - This parameter can be a value of @ref IRQn_Type - (For the complete STM32 Devices IRQ Channels list, please - refer to stm32l1xx.h file) */ - - uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel - specified in NVIC_IRQChannel. This parameter can be a value - between 0 and 15 as described in the table @ref NVIC_Priority_Table */ - - uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified - in NVIC_IRQChannel. This parameter can be a value - between 0 and 15 as described in the table @ref NVIC_Priority_Table */ - - FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel - will be enabled or disabled. - This parameter can be set either to ENABLE or DISABLE */ -} NVIC_InitTypeDef; - -/** - * -@verbatim - The table below gives the allowed values of the pre-emption priority and subpriority according - to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function - ============================================================================================================================ - NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description - ============================================================================================================================ - NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority - | | | 4 bits for subpriority - ---------------------------------------------------------------------------------------------------------------------------- - NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority - | | | 3 bits for subpriority - ---------------------------------------------------------------------------------------------------------------------------- - NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority - | | | 2 bits for subpriority - ---------------------------------------------------------------------------------------------------------------------------- - NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority - | | | 1 bits for subpriority - ---------------------------------------------------------------------------------------------------------------------------- - NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority - | | | 0 bits for subpriority - ============================================================================================================================ -@endverbatim -*/ - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup MISC_Exported_Constants - * @{ - */ - -/** @defgroup Vector_Table_Base - * @{ - */ - -#define NVIC_VectTab_RAM ((uint32_t)0x20000000) -#define NVIC_VectTab_FLASH ((uint32_t)0x08000000) -#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \ - ((VECTTAB) == NVIC_VectTab_FLASH)) -/** - * @} - */ - -/** @defgroup System_Low_Power - * @{ - */ - -#define NVIC_LP_SEVONPEND ((uint8_t)0x10) -#define NVIC_LP_SLEEPDEEP ((uint8_t)0x04) -#define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02) -#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \ - ((LP) == NVIC_LP_SLEEPDEEP) || \ - ((LP) == NVIC_LP_SLEEPONEXIT)) -/** - * @} - */ - -/** @defgroup Preemption_Priority_Group - * @{ - */ - -#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority - 4 bits for subpriority */ -#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority - 3 bits for subpriority */ -#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority - 2 bits for subpriority */ -#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority - 1 bits for subpriority */ -#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority - 0 bits for subpriority */ - -#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \ - ((GROUP) == NVIC_PriorityGroup_1) || \ - ((GROUP) == NVIC_PriorityGroup_2) || \ - ((GROUP) == NVIC_PriorityGroup_3) || \ - ((GROUP) == NVIC_PriorityGroup_4)) - -#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) - -#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) - -#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x0001FFFF) - -/** - * @} - */ - -/** @defgroup SysTick_clock_source - * @{ - */ - -#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) -#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004) -#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \ - ((SOURCE) == SysTick_CLKSource_HCLK_Div8)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); -void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); -void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset); -void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState); -void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource); - -#ifdef __cplusplus -} -#endif - -#endif /* __MISC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_adc.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_adc.h deleted file mode 100644 index a7b882d01..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_adc.h +++ /dev/null @@ -1,606 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_adc.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the ADC firmware - * library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_ADC_H -#define __STM32L1xx_ADC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup ADC - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief ADC Init structure definition - */ - -typedef struct -{ - uint32_t ADC_Resolution; /*!< Selects the resolution of the conversion. - This parameter can be a value of @ref ADC_Resolution */ - - FunctionalState ADC_ScanConvMode; /*!< Specifies whether the conversion is performed in - Scan (multichannel) or Single (one channel) mode. - This parameter can be set to ENABLE or DISABLE */ - - FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion is performed in - Continuous or Single mode. - This parameter can be set to ENABLE or DISABLE. */ - - uint32_t ADC_ExternalTrigConvEdge; /*!< Selects the external trigger Edge and enables the - trigger of a regular group. This parameter can be a value - of @ref ADC_external_trigger_edge_for_regular_channels_conversion */ - - uint32_t ADC_ExternalTrigConv; /*!< Defines the external trigger used to start the analog - to digital conversion of regular channels. This parameter - can be a value of @ref ADC_external_trigger_sources_for_regular_channels_conversion */ - - uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment is left or right. - This parameter can be a value of @ref ADC_data_align */ - - uint8_t ADC_NbrOfConversion; /*!< Specifies the number of ADC conversions that will be done - using the sequencer for regular channel group. - This parameter must range from 1 to 27. */ -}ADC_InitTypeDef; - -typedef struct -{ - uint32_t ADC_Prescaler; /*!< Selects the ADC prescaler. - This parameter can be a value - of @ref ADC_Prescaler */ -}ADC_CommonInitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup ADC_Exported_Constants - * @{ - */ -#define IS_ADC_ALL_PERIPH(PERIPH) ((PERIPH) == ADC1) -#define IS_ADC_DMA_PERIPH(PERIPH) ((PERIPH) == ADC1) - -/** @defgroup ADC_Power_down_during_Idle_and_or_Delay_phase - * @{ - */ -#define ADC_PowerDown_Delay ((uint32_t)0x00010000) -#define ADC_PowerDown_Idle ((uint32_t)0x00020000) -#define ADC_PowerDown_Idle_Delay ((uint32_t)0x00030000) - -#define IS_ADC_POWER_DOWN(DWON) (((DWON) == ADC_PowerDown_Delay) || \ - ((DWON) == ADC_PowerDown_Idle) || \ - ((DWON) == ADC_PowerDown_Idle_Delay)) -/** - * @} - */ - - -/** @defgroup ADC_Prescaler - * @{ - */ -#define ADC_Prescaler_Div1 ((uint32_t)0x00000000) -#define ADC_Prescaler_Div2 ((uint32_t)0x00010000) -#define ADC_Prescaler_Div4 ((uint32_t)0x00020000) - -#define IS_ADC_PRESCALER(PRESCALER) (((PRESCALER) == ADC_Prescaler_Div1) || \ - ((PRESCALER) == ADC_Prescaler_Div2) || \ - ((PRESCALER) == ADC_Prescaler_Div4)) -/** - * @} - */ - - - -/** @defgroup ADC_resolution - * @{ - */ -#define ADC_Resolution_12b ((uint32_t)0x00000000) -#define ADC_Resolution_10b ((uint32_t)0x01000000) -#define ADC_Resolution_8b ((uint32_t)0x02000000) -#define ADC_Resolution_6b ((uint32_t)0x03000000) - -#define IS_ADC_RESOLUTION(RESOLUTION) (((RESOLUTION) == ADC_Resolution_12b) || \ - ((RESOLUTION) == ADC_Resolution_10b) || \ - ((RESOLUTION) == ADC_Resolution_8b) || \ - ((RESOLUTION) == ADC_Resolution_6b)) - -/** - * @} - */ - -/** @defgroup ADC_external_trigger_edge_for_regular_channels_conversion - * @{ - */ -#define ADC_ExternalTrigConvEdge_None ((uint32_t)0x00000000) -#define ADC_ExternalTrigConvEdge_Rising ((uint32_t)0x10000000) -#define ADC_ExternalTrigConvEdge_Falling ((uint32_t)0x20000000) -#define ADC_ExternalTrigConvEdge_RisingFalling ((uint32_t)0x30000000) - -#define IS_ADC_EXT_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigConvEdge_None) || \ - ((EDGE) == ADC_ExternalTrigConvEdge_Rising) || \ - ((EDGE) == ADC_ExternalTrigConvEdge_Falling) || \ - ((EDGE) == ADC_ExternalTrigConvEdge_RisingFalling)) -/** - * @} - */ - -/** @defgroup ADC_external_trigger_sources_for_regular_channels_conversion - * @{ - */ - -/* TIM2 */ -#define ADC_ExternalTrigConv_T2_CC3 ((uint32_t)0x02000000) -#define ADC_ExternalTrigConv_T2_CC2 ((uint32_t)0x03000000) -#define ADC_ExternalTrigConv_T2_TRGO ((uint32_t)0x06000000) - -/* TIM3 */ -#define ADC_ExternalTrigConv_T3_CC1 ((uint32_t)0x07000000) -#define ADC_ExternalTrigConv_T3_CC3 ((uint32_t)0x08000000) -#define ADC_ExternalTrigConv_T3_TRGO ((uint32_t)0x04000000) - -/* TIM4 */ -#define ADC_ExternalTrigConv_T4_CC4 ((uint32_t)0x05000000) -#define ADC_ExternalTrigConv_T4_TRGO ((uint32_t)0x09000000) - -/* TIM6 */ -#define ADC_ExternalTrigConv_T6_TRGO ((uint32_t)0x0A000000) - -/* TIM9 */ -#define ADC_ExternalTrigConv_T9_CC2 ((uint32_t)0x00000000) -#define ADC_ExternalTrigConv_T9_TRGO ((uint32_t)0x01000000) - -/* EXTI */ -#define ADC_ExternalTrigConv_Ext_IT11 ((uint32_t)0x0F000000) - -#define IS_ADC_EXT_TRIG(REGTRIG) (((REGTRIG) == ADC_ExternalTrigConv_T9_CC2) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T9_TRGO) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T2_CC3) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T2_CC2) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T3_TRGO) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T4_CC4) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T2_TRGO) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T3_CC1) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T3_CC3) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T4_TRGO) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T6_TRGO) || \ - ((REGTRIG) == ADC_ExternalTrigConv_Ext_IT11)) -/** - * @} - */ - -/** @defgroup ADC_data_align - * @{ - */ - -#define ADC_DataAlign_Right ((uint32_t)0x00000000) -#define ADC_DataAlign_Left ((uint32_t)0x00000800) - -#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DataAlign_Right) || \ - ((ALIGN) == ADC_DataAlign_Left)) -/** - * @} - */ - -/** @defgroup ADC_channels - * @{ - */ - -#define ADC_Channel_0 ((uint8_t)0x00) -#define ADC_Channel_1 ((uint8_t)0x01) -#define ADC_Channel_2 ((uint8_t)0x02) -#define ADC_Channel_3 ((uint8_t)0x03) -#define ADC_Channel_4 ((uint8_t)0x04) -#define ADC_Channel_5 ((uint8_t)0x05) -#define ADC_Channel_6 ((uint8_t)0x06) -#define ADC_Channel_7 ((uint8_t)0x07) -#define ADC_Channel_8 ((uint8_t)0x08) -#define ADC_Channel_9 ((uint8_t)0x09) -#define ADC_Channel_10 ((uint8_t)0x0A) -#define ADC_Channel_11 ((uint8_t)0x0B) -#define ADC_Channel_12 ((uint8_t)0x0C) -#define ADC_Channel_13 ((uint8_t)0x0D) -#define ADC_Channel_14 ((uint8_t)0x0E) -#define ADC_Channel_15 ((uint8_t)0x0F) -#define ADC_Channel_16 ((uint8_t)0x10) -#define ADC_Channel_17 ((uint8_t)0x11) -#define ADC_Channel_18 ((uint8_t)0x12) -#define ADC_Channel_19 ((uint8_t)0x13) -#define ADC_Channel_20 ((uint8_t)0x14) -#define ADC_Channel_21 ((uint8_t)0x15) -#define ADC_Channel_22 ((uint8_t)0x16) -#define ADC_Channel_23 ((uint8_t)0x17) -#define ADC_Channel_24 ((uint8_t)0x18) -#define ADC_Channel_25 ((uint8_t)0x19) - -#define ADC_Channel_TempSensor ((uint8_t)ADC_Channel_16) -#define ADC_Channel_Vrefint ((uint8_t)ADC_Channel_17) - - - -#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_0) || ((CHANNEL) == ADC_Channel_1) || \ - ((CHANNEL) == ADC_Channel_2) || ((CHANNEL) == ADC_Channel_3) || \ - ((CHANNEL) == ADC_Channel_4) || ((CHANNEL) == ADC_Channel_5) || \ - ((CHANNEL) == ADC_Channel_6) || ((CHANNEL) == ADC_Channel_7) || \ - ((CHANNEL) == ADC_Channel_8) || ((CHANNEL) == ADC_Channel_9) || \ - ((CHANNEL) == ADC_Channel_10) || ((CHANNEL) == ADC_Channel_11) || \ - ((CHANNEL) == ADC_Channel_12) || ((CHANNEL) == ADC_Channel_13) || \ - ((CHANNEL) == ADC_Channel_14) || ((CHANNEL) == ADC_Channel_15) || \ - ((CHANNEL) == ADC_Channel_16) || ((CHANNEL) == ADC_Channel_17) || \ - ((CHANNEL) == ADC_Channel_18) || ((CHANNEL) == ADC_Channel_19) || \ - ((CHANNEL) == ADC_Channel_20) || ((CHANNEL) == ADC_Channel_21) || \ - ((CHANNEL) == ADC_Channel_22) || ((CHANNEL) == ADC_Channel_23) || \ - ((CHANNEL) == ADC_Channel_24) || ((CHANNEL) == ADC_Channel_25) ) -/** - * @} - */ - -/** @defgroup ADC_sampling_times - * @{ - */ - -#define ADC_SampleTime_4Cycles ((uint8_t)0x00) -#define ADC_SampleTime_9Cycles ((uint8_t)0x01) -#define ADC_SampleTime_16Cycles ((uint8_t)0x02) -#define ADC_SampleTime_24Cycles ((uint8_t)0x03) -#define ADC_SampleTime_48Cycles ((uint8_t)0x04) -#define ADC_SampleTime_96Cycles ((uint8_t)0x05) -#define ADC_SampleTime_192Cycles ((uint8_t)0x06) -#define ADC_SampleTime_384Cycles ((uint8_t)0x07) - -#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_4Cycles) || \ - ((TIME) == ADC_SampleTime_9Cycles) || \ - ((TIME) == ADC_SampleTime_16Cycles) || \ - ((TIME) == ADC_SampleTime_24Cycles) || \ - ((TIME) == ADC_SampleTime_48Cycles) || \ - ((TIME) == ADC_SampleTime_96Cycles) || \ - ((TIME) == ADC_SampleTime_192Cycles) || \ - ((TIME) == ADC_SampleTime_384Cycles)) -/** - * @} - */ - -/** @defgroup ADC_Delay_length - * @{ - */ - -#define ADC_DelayLength_None ((uint8_t)0x00) -#define ADC_DelayLength_Freeze ((uint8_t)0x10) -#define ADC_DelayLength_7Cycles ((uint8_t)0x20) -#define ADC_DelayLength_15Cycles ((uint8_t)0x30) -#define ADC_DelayLength_31Cycles ((uint8_t)0x40) -#define ADC_DelayLength_63Cycles ((uint8_t)0x50) -#define ADC_DelayLength_127Cycles ((uint8_t)0x60) -#define ADC_DelayLength_255Cycles ((uint8_t)0x70) - -#define IS_ADC_DELAY_LENGTH(LENGTH) (((LENGTH) == ADC_DelayLength_None) || \ - ((LENGTH) == ADC_DelayLength_Freeze) || \ - ((LENGTH) == ADC_DelayLength_7Cycles) || \ - ((LENGTH) == ADC_DelayLength_15Cycles) || \ - ((LENGTH) == ADC_DelayLength_31Cycles) || \ - ((LENGTH) == ADC_DelayLength_63Cycles) || \ - ((LENGTH) == ADC_DelayLength_127Cycles) || \ - ((LENGTH) == ADC_DelayLength_255Cycles)) - -/** - * @} - */ - -/** @defgroup ADC_external_trigger_edge_for_injected_channels_conversion - * @{ - */ -#define ADC_ExternalTrigInjecConvEdge_None ((uint32_t)0x00000000) -#define ADC_ExternalTrigInjecConvEdge_Rising ((uint32_t)0x00100000) -#define ADC_ExternalTrigInjecConvEdge_Falling ((uint32_t)0x00200000) -#define ADC_ExternalTrigInjecConvEdge_RisingFalling ((uint32_t)0x00300000) - -#define IS_ADC_EXT_INJEC_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigInjecConvEdge_None) || \ - ((EDGE) == ADC_ExternalTrigInjecConvEdge_Rising) || \ - ((EDGE) == ADC_ExternalTrigInjecConvEdge_Falling) || \ - ((EDGE) == ADC_ExternalTrigInjecConvEdge_RisingFalling)) -/** - * @} - */ - - -/** @defgroup ADC_external_trigger_sources_for_injected_channels_conversion - * @{ - */ - - -/* TIM2 */ -#define ADC_ExternalTrigInjecConv_T2_TRGO ((uint32_t)0x00020000) -#define ADC_ExternalTrigInjecConv_T2_CC1 ((uint32_t)0x00030000) - -/* TIM3 */ -#define ADC_ExternalTrigInjecConv_T3_CC4 ((uint32_t)0x00040000) - -/* TIM4 */ -#define ADC_ExternalTrigInjecConv_T4_TRGO ((uint32_t)0x00050000) -#define ADC_ExternalTrigInjecConv_T4_CC1 ((uint32_t)0x00060000) -#define ADC_ExternalTrigInjecConv_T4_CC2 ((uint32_t)0x00070000) -#define ADC_ExternalTrigInjecConv_T4_CC3 ((uint32_t)0x00080000) - -/* TIM7 */ -#define ADC_ExternalTrigInjecConv_T7_TRGO ((uint32_t)0x000A0000) - -/* TIM9 */ -#define ADC_ExternalTrigInjecConv_T9_CC1 ((uint32_t)0x00000000) -#define ADC_ExternalTrigInjecConv_T9_TRGO ((uint32_t)0x00010000) - -/* TIM10 */ -#define ADC_ExternalTrigInjecConv_T10_CC1 ((uint32_t)0x00090000) - -/* EXTI */ -#define ADC_ExternalTrigInjecConv_Ext_IT15 ((uint32_t)0x000F0000) - -#define IS_ADC_EXT_INJEC_TRIG(INJTRIG) (((INJTRIG) == ADC_ExternalTrigInjecConv_T9_CC1) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T9_TRGO) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_TRGO) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_CC1) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC4) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_TRGO) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC1) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC2) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC3) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T10_CC1) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T7_TRGO) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_Ext_IT15)) -/** - * @} - */ - -/** @defgroup ADC_injected_channel_selection - * @{ - */ -#define ADC_InjectedChannel_1 ((uint8_t)0x18) -#define ADC_InjectedChannel_2 ((uint8_t)0x1C) -#define ADC_InjectedChannel_3 ((uint8_t)0x20) -#define ADC_InjectedChannel_4 ((uint8_t)0x24) - -#define IS_ADC_INJECTED_CHANNEL(CHANNEL) (((CHANNEL) == ADC_InjectedChannel_1) || \ - ((CHANNEL) == ADC_InjectedChannel_2) || \ - ((CHANNEL) == ADC_InjectedChannel_3) || \ - ((CHANNEL) == ADC_InjectedChannel_4)) -/** - * @} - */ - -/** @defgroup ADC_analog_watchdog_selection - * @{ - */ - -#define ADC_AnalogWatchdog_SingleRegEnable ((uint32_t)0x00800200) -#define ADC_AnalogWatchdog_SingleInjecEnable ((uint32_t)0x00400200) -#define ADC_AnalogWatchdog_SingleRegOrInjecEnable ((uint32_t)0x00C00200) -#define ADC_AnalogWatchdog_AllRegEnable ((uint32_t)0x00800000) -#define ADC_AnalogWatchdog_AllInjecEnable ((uint32_t)0x00400000) -#define ADC_AnalogWatchdog_AllRegAllInjecEnable ((uint32_t)0x00C00000) -#define ADC_AnalogWatchdog_None ((uint32_t)0x00000000) - -#define IS_ADC_ANALOG_WATCHDOG(WATCHDOG) (((WATCHDOG) == ADC_AnalogWatchdog_SingleRegEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_SingleInjecEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_SingleRegOrInjecEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_AllRegEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_AllInjecEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_AllRegAllInjecEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_None)) -/** - * @} - */ - -/** @defgroup ADC_interrupts_definition - * @{ - */ - -#define ADC_IT_AWD ((uint16_t)0x0106) -#define ADC_IT_EOC ((uint16_t)0x0205) -#define ADC_IT_JEOC ((uint16_t)0x0407) -#define ADC_IT_OVR ((uint16_t)0x201A) - -#define IS_ADC_IT(IT) (((IT) == ADC_IT_AWD) || ((IT) == ADC_IT_EOC) || \ - ((IT) == ADC_IT_JEOC)|| ((IT) == ADC_IT_OVR)) -/** - * @} - */ - -/** @defgroup ADC_flags_definition - * @{ - */ - -#define ADC_FLAG_AWD ((uint16_t)0x0001) -#define ADC_FLAG_EOC ((uint16_t)0x0002) -#define ADC_FLAG_JEOC ((uint16_t)0x0004) -#define ADC_FLAG_JSTRT ((uint16_t)0x0008) -#define ADC_FLAG_STRT ((uint16_t)0x0010) -#define ADC_FLAG_OVR ((uint16_t)0x0020) -#define ADC_FLAG_ADONS ((uint16_t)0x0040) -#define ADC_FLAG_RCNR ((uint16_t)0x0100) -#define ADC_FLAG_JCNR ((uint16_t)0x0200) - -#define IS_ADC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFFC0) == 0x00) && ((FLAG) != 0x00)) - -#define IS_ADC_GET_FLAG(FLAG) (((FLAG) == ADC_FLAG_AWD) || ((FLAG) == ADC_FLAG_EOC) || \ - ((FLAG) == ADC_FLAG_JEOC) || ((FLAG)== ADC_FLAG_JSTRT) || \ - ((FLAG) == ADC_FLAG_STRT) || ((FLAG)== ADC_FLAG_OVR) || \ - ((FLAG) == ADC_FLAG_ADONS) || ((FLAG)== ADC_FLAG_RCNR) || \ - ((FLAG) == ADC_FLAG_JCNR)) -/** - * @} - */ - -/** @defgroup ADC_thresholds - * @{ - */ - -#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFF) - -/** - * @} - */ - -/** @defgroup ADC_injected_offset - * @{ - */ - -#define IS_ADC_OFFSET(OFFSET) ((OFFSET) <= 0xFFF) - -/** - * @} - */ - -/** @defgroup ADC_injected_length - * @{ - */ - -#define IS_ADC_INJECTED_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x4)) - -/** - * @} - */ - -/** @defgroup ADC_injected_rank - * @{ - */ - -#define IS_ADC_INJECTED_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x4)) - -/** - * @} - */ - -/** @defgroup ADC_regular_length - * @{ - */ - -#define IS_ADC_REGULAR_LENGTH(LENGTH) (((LENGTH) >= 1) && ((LENGTH) <= 27)) - -/** - * @} - */ - -/** @defgroup ADC_regular_rank - * @{ - */ - -#define IS_ADC_REGULAR_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x1B)) - -/** - * @} - */ - -/** @defgroup ADC_regular_discontinuous_mode_number - * @{ - */ - -#define IS_ADC_REGULAR_DISC_NUMBER(NUMBER) (((NUMBER) >= 0x1) && ((NUMBER) <= 0x8)) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* Function used to set the ADC configuration to the default reset state *****/ -void ADC_DeInit(ADC_TypeDef* ADCx); - -/* Initialization and Configuration functions *********************************/ -void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct); -void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct); -void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct); -void ADC_CommonStructInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct); -void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState); - -/* Power saving functions *****************************************************/ -void ADC_PowerDownCmd(ADC_TypeDef* ADCx, uint32_t ADC_PowerDown, FunctionalState NewState); -void ADC_DelaySelectionConfig(ADC_TypeDef* ADCx, uint8_t ADC_DelayLength); - -/* Analog Watchdog configuration functions ************************************/ -void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog); -void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold,uint16_t LowThreshold); -void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel); - -/* Temperature Sensor & Vrefint (Voltage Reference internal) management function */ -void ADC_TempSensorVrefintCmd(FunctionalState NewState); - -/* Regular Channels Configuration functions ***********************************/ -void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); -void ADC_SoftwareStartConv(ADC_TypeDef* ADCx); -FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx); -void ADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number); -void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx); - -/* Regular Channels DMA Configuration functions *******************************/ -void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState); - -/* Injected channels Configuration functions **********************************/ -void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); -void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length); -void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset); -void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv); -void ADC_ExternalTrigInjectedConvEdgeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConvEdge); -void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx); -FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx); -void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel); - -/* Interrupts and flags management functions **********************************/ -void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState); -FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint16_t ADC_FLAG); -void ADC_ClearFlag(ADC_TypeDef* ADCx, uint16_t ADC_FLAG); -ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT); -void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32L1xx_ADC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_comp.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_comp.h deleted file mode 100644 index 1fcc9f923..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_comp.h +++ /dev/null @@ -1,180 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_comp.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the COMP firmware - * library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_COMP_H -#define __STM32L1xx_COMP_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup COMP - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief COMP Init structure definition - */ - -typedef struct -{ - uint32_t COMP_Speed; /*!< Defines the speed of comparator 2. - This parameter can be a value of @ref COMP_Speed */ - uint32_t COMP_InvertingInput; /*!< Selects the inverting input of the comparator 2. - This parameter can be a value of @ref COMP_InvertingInput */ - uint32_t COMP_OutputSelect; /*!< Selects the output redirection of the comparator 2. - This parameter can be a value of @ref COMP_OutputSelect */ - -}COMP_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup COMP_Exported_Constants - * @{ - */ - -#define COMP_OutputLevel_High ((uint32_t)0x00000001) -#define COMP_OutputLevel_Low ((uint32_t)0x00000000) - -/** @defgroup COMP_Selection - * @{ - */ - -#define COMP_Selection_COMP1 ((uint32_t)0x00000001) -#define COMP_Selection_COMP2 ((uint32_t)0x00000002) - -#define IS_COMP_ALL_PERIPH(PERIPH) (((PERIPH) == COMP_Selection_COMP1) || \ - ((PERIPH) == COMP_Selection_COMP2)) - -/** - * @} - */ - -/** @defgroup COMP_InvertingInput - * @{ - */ - -#define COMP_InvertingInput_None ((uint32_t)0x00000000) /* COMP2 is disabled when this parameter is selected */ -#define COMP_InvertingInput_IO ((uint32_t)0x00040000) -#define COMP_InvertingInput_VREFINT ((uint32_t)0x00080000) -#define COMP_InvertingInput_3_4VREFINT ((uint32_t)0x000C0000) -#define COMP_InvertingInput_1_2VREFINT ((uint32_t)0x00100000) -#define COMP_InvertingInput_1_4VREFINT ((uint32_t)0x00140000) -#define COMP_InvertingInput_DAC1 ((uint32_t)0x00180000) -#define COMP_InvertingInput_DAC2 ((uint32_t)0x001C0000) - -#define IS_COMP_INVERTING_INPUT(INPUT) (((INPUT) == COMP_InvertingInput_None) || \ - ((INPUT) == COMP_InvertingInput_IO) || \ - ((INPUT) == COMP_InvertingInput_VREFINT) || \ - ((INPUT) == COMP_InvertingInput_3_4VREFINT) || \ - ((INPUT) == COMP_InvertingInput_1_2VREFINT) || \ - ((INPUT) == COMP_InvertingInput_1_4VREFINT) || \ - ((INPUT) == COMP_InvertingInput_DAC1) || \ - ((INPUT) == COMP_InvertingInput_DAC2)) -/** - * @} - */ - -/** @defgroup COMP_OutputSelect - * @{ - */ - -#define COMP_OutputSelect_TIM2IC4 ((uint32_t)0x00000000) -#define COMP_OutputSelect_TIM2OCREFCLR ((uint32_t)0x00200000) -#define COMP_OutputSelect_TIM3IC4 ((uint32_t)0x00400000) -#define COMP_OutputSelect_TIM3OCREFCLR ((uint32_t)0x00600000) -#define COMP_OutputSelect_TIM4IC4 ((uint32_t)0x00800000) -#define COMP_OutputSelect_TIM4OCREFCLR ((uint32_t)0x00A00000) -#define COMP_OutputSelect_TIM10IC1 ((uint32_t)0x00C00000) -#define COMP_OutputSelect_None ((uint32_t)0x00E00000) - -#define IS_COMP_OUTPUT(OUTPUT) (((OUTPUT) == COMP_OutputSelect_TIM2IC4) || \ - ((OUTPUT) == COMP_OutputSelect_TIM2OCREFCLR) || \ - ((OUTPUT) == COMP_OutputSelect_TIM3IC4) || \ - ((OUTPUT) == COMP_OutputSelect_TIM3OCREFCLR) || \ - ((OUTPUT) == COMP_OutputSelect_TIM4IC4) || \ - ((OUTPUT) == COMP_OutputSelect_TIM4OCREFCLR) || \ - ((OUTPUT) == COMP_OutputSelect_TIM10IC1) || \ - ((OUTPUT) == COMP_OutputSelect_None)) -/** - * @} - */ - -/** @defgroup COMP_Speed - * @{ - */ - -#define COMP_Speed_Slow ((uint32_t)0x00000000) -#define COMP_Speed_Fast ((uint32_t)0x00001000) - -#define IS_COMP_SPEED(SPEED) (((SPEED) == COMP_Speed_Slow) || \ - ((SPEED) == COMP_Speed_Fast)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* Function used to set the COMP configuration to the default reset state ****/ -void COMP_DeInit(void); - -/* Initialization and Configuration functions *********************************/ -void COMP_Init(COMP_InitTypeDef* COMP_InitStruct); -void COMP_Cmd(FunctionalState NewState); -uint8_t COMP_GetOutputLevel(uint32_t COMP_Selection); - -/* Window mode control function ***********************************************/ -void COMP_WindowCmd(FunctionalState NewState); - -/* Internal Reference Voltage (VREFINT) output function ***********************/ -void COMP_VrefintOutputCmd(FunctionalState NewState); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32L1xx_COMP_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_crc.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_crc.h deleted file mode 100644 index 6c999fabd..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_crc.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_crc.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the CRC firmware - * library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_CRC_H -#define __STM32L1xx_CRC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup CRC - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup CRC_Exported_Constants - * @{ - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -void CRC_ResetDR(void); -uint32_t CRC_CalcCRC(uint32_t Data); -uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength); -uint32_t CRC_GetCRC(void); -void CRC_SetIDRegister(uint8_t IDValue); -uint8_t CRC_GetIDRegister(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32L1xx_CRC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_dac.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_dac.h deleted file mode 100644 index 2ebe5e104..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_dac.h +++ /dev/null @@ -1,299 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_dac.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the DAC firmware - * library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_DAC_H -#define __STM32L1xx_DAC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup DAC - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief DAC Init structure definition - */ - -typedef struct -{ - uint32_t DAC_Trigger; /*!< Specifies the external trigger for the selected DAC channel. - This parameter can be a value of @ref DAC_trigger_selection */ - - uint32_t DAC_WaveGeneration; /*!< Specifies whether DAC channel noise waves or triangle waves - are generated, or whether no wave is generated. - This parameter can be a value of @ref DAC_wave_generation */ - - uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*!< Specifies the LFSR mask for noise wave generation or - the maximum amplitude triangle generation for the DAC channel. - This parameter can be a value of @ref DAC_lfsrunmask_triangleamplitude */ - - uint32_t DAC_OutputBuffer; /*!< Specifies whether the DAC channel output buffer is enabled or disabled. - This parameter can be a value of @ref DAC_output_buffer */ -}DAC_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup DAC_Exported_Constants - * @{ - */ - -/** @defgroup DAC_trigger_selection - * @{ - */ - -#define DAC_Trigger_None ((uint32_t)0x00000000) /*!< Conversion is automatic once the DAC1_DHRxxxx register - has been loaded, and not by external trigger */ -#define DAC_Trigger_T6_TRGO ((uint32_t)0x00000004) /*!< TIM6 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_T7_TRGO ((uint32_t)0x00000014) /*!< TIM7 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_T9_TRGO ((uint32_t)0x0000001C) /*!< TIM9 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_T2_TRGO ((uint32_t)0x00000024) /*!< TIM2 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_T4_TRGO ((uint32_t)0x0000002C) /*!< TIM4 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_Ext_IT9 ((uint32_t)0x00000034) /*!< EXTI Line9 event selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_Software ((uint32_t)0x0000003C) /*!< Conversion started by software trigger for DAC channel */ - -#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_Trigger_None) || \ - ((TRIGGER) == DAC_Trigger_T6_TRGO) || \ - ((TRIGGER) == DAC_Trigger_T7_TRGO) || \ - ((TRIGGER) == DAC_Trigger_T9_TRGO) || \ - ((TRIGGER) == DAC_Trigger_T2_TRGO) || \ - ((TRIGGER) == DAC_Trigger_T4_TRGO) || \ - ((TRIGGER) == DAC_Trigger_Ext_IT9) || \ - ((TRIGGER) == DAC_Trigger_Software)) - -/** - * @} - */ - -/** @defgroup DAC_wave_generation - * @{ - */ - -#define DAC_WaveGeneration_None ((uint32_t)0x00000000) -#define DAC_WaveGeneration_Noise ((uint32_t)0x00000040) -#define DAC_WaveGeneration_Triangle ((uint32_t)0x00000080) -#define IS_DAC_GENERATE_WAVE(WAVE) (((WAVE) == DAC_WaveGeneration_None) || \ - ((WAVE) == DAC_WaveGeneration_Noise) || \ - ((WAVE) == DAC_WaveGeneration_Triangle)) -/** - * @} - */ - -/** @defgroup DAC_lfsrunmask_triangleamplitude - * @{ - */ - -#define DAC_LFSRUnmask_Bit0 ((uint32_t)0x00000000) /*!< Unmask DAC channel LFSR bit0 for noise wave generation */ -#define DAC_LFSRUnmask_Bits1_0 ((uint32_t)0x00000100) /*!< Unmask DAC channel LFSR bit[1:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits2_0 ((uint32_t)0x00000200) /*!< Unmask DAC channel LFSR bit[2:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits3_0 ((uint32_t)0x00000300) /*!< Unmask DAC channel LFSR bit[3:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits4_0 ((uint32_t)0x00000400) /*!< Unmask DAC channel LFSR bit[4:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits5_0 ((uint32_t)0x00000500) /*!< Unmask DAC channel LFSR bit[5:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits6_0 ((uint32_t)0x00000600) /*!< Unmask DAC channel LFSR bit[6:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits7_0 ((uint32_t)0x00000700) /*!< Unmask DAC channel LFSR bit[7:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits8_0 ((uint32_t)0x00000800) /*!< Unmask DAC channel LFSR bit[8:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits9_0 ((uint32_t)0x00000900) /*!< Unmask DAC channel LFSR bit[9:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits10_0 ((uint32_t)0x00000A00) /*!< Unmask DAC channel LFSR bit[10:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits11_0 ((uint32_t)0x00000B00) /*!< Unmask DAC channel LFSR bit[11:0] for noise wave generation */ -#define DAC_TriangleAmplitude_1 ((uint32_t)0x00000000) /*!< Select max triangle amplitude of 1 */ -#define DAC_TriangleAmplitude_3 ((uint32_t)0x00000100) /*!< Select max triangle amplitude of 3 */ -#define DAC_TriangleAmplitude_7 ((uint32_t)0x00000200) /*!< Select max triangle amplitude of 7 */ -#define DAC_TriangleAmplitude_15 ((uint32_t)0x00000300) /*!< Select max triangle amplitude of 15 */ -#define DAC_TriangleAmplitude_31 ((uint32_t)0x00000400) /*!< Select max triangle amplitude of 31 */ -#define DAC_TriangleAmplitude_63 ((uint32_t)0x00000500) /*!< Select max triangle amplitude of 63 */ -#define DAC_TriangleAmplitude_127 ((uint32_t)0x00000600) /*!< Select max triangle amplitude of 127 */ -#define DAC_TriangleAmplitude_255 ((uint32_t)0x00000700) /*!< Select max triangle amplitude of 255 */ -#define DAC_TriangleAmplitude_511 ((uint32_t)0x00000800) /*!< Select max triangle amplitude of 511 */ -#define DAC_TriangleAmplitude_1023 ((uint32_t)0x00000900) /*!< Select max triangle amplitude of 1023 */ -#define DAC_TriangleAmplitude_2047 ((uint32_t)0x00000A00) /*!< Select max triangle amplitude of 2047 */ -#define DAC_TriangleAmplitude_4095 ((uint32_t)0x00000B00) /*!< Select max triangle amplitude of 4095 */ - -#define IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(VALUE) (((VALUE) == DAC_LFSRUnmask_Bit0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits1_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits2_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits3_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits4_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits5_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits6_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits7_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits8_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits9_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits10_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits11_0) || \ - ((VALUE) == DAC_TriangleAmplitude_1) || \ - ((VALUE) == DAC_TriangleAmplitude_3) || \ - ((VALUE) == DAC_TriangleAmplitude_7) || \ - ((VALUE) == DAC_TriangleAmplitude_15) || \ - ((VALUE) == DAC_TriangleAmplitude_31) || \ - ((VALUE) == DAC_TriangleAmplitude_63) || \ - ((VALUE) == DAC_TriangleAmplitude_127) || \ - ((VALUE) == DAC_TriangleAmplitude_255) || \ - ((VALUE) == DAC_TriangleAmplitude_511) || \ - ((VALUE) == DAC_TriangleAmplitude_1023) || \ - ((VALUE) == DAC_TriangleAmplitude_2047) || \ - ((VALUE) == DAC_TriangleAmplitude_4095)) -/** - * @} - */ - -/** @defgroup DAC_output_buffer - * @{ - */ - -#define DAC_OutputBuffer_Enable ((uint32_t)0x00000000) -#define DAC_OutputBuffer_Disable ((uint32_t)0x00000002) -#define IS_DAC_OUTPUT_BUFFER_STATE(STATE) (((STATE) == DAC_OutputBuffer_Enable) || \ - ((STATE) == DAC_OutputBuffer_Disable)) -/** - * @} - */ - -/** @defgroup DAC_Channel_selection - * @{ - */ - -#define DAC_Channel_1 ((uint32_t)0x00000000) -#define DAC_Channel_2 ((uint32_t)0x00000010) -#define IS_DAC_CHANNEL(CHANNEL) (((CHANNEL) == DAC_Channel_1) || \ - ((CHANNEL) == DAC_Channel_2)) -/** - * @} - */ - -/** @defgroup DAC_data_alignment - * @{ - */ - -#define DAC_Align_12b_R ((uint32_t)0x00000000) -#define DAC_Align_12b_L ((uint32_t)0x00000004) -#define DAC_Align_8b_R ((uint32_t)0x00000008) -#define IS_DAC_ALIGN(ALIGN) (((ALIGN) == DAC_Align_12b_R) || \ - ((ALIGN) == DAC_Align_12b_L) || \ - ((ALIGN) == DAC_Align_8b_R)) -/** - * @} - */ - -/** @defgroup DAC_wave_generation - * @{ - */ - -#define DAC_Wave_Noise ((uint32_t)0x00000040) -#define DAC_Wave_Triangle ((uint32_t)0x00000080) -#define IS_DAC_WAVE(WAVE) (((WAVE) == DAC_Wave_Noise) || \ - ((WAVE) == DAC_Wave_Triangle)) -/** - * @} - */ - -/** @defgroup DAC_data - * @{ - */ - -#define IS_DAC_DATA(DATA) ((DATA) <= 0xFFF0) - -/** - * @} - */ - -/** @defgroup DAC_interrupts_definition - * @{ - */ - -#define DAC_IT_DMAUDR ((uint32_t)0x00002000) -#define IS_DAC_IT(IT) (((IT) == DAC_IT_DMAUDR)) - -/** - * @} - */ - - -/** @defgroup DAC_flags_definition - * @{ - */ - -#define DAC_FLAG_DMAUDR ((uint32_t)0x00002000) - -#define IS_DAC_FLAG(FLAG) (((FLAG) == DAC_FLAG_DMAUDR)) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* Function used to set the DAC configuration to the default reset state *****/ -void DAC_DeInit(void); - -/* DAC channels configuration: trigger, output buffer, data format functions */ -void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct); -void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct); -void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState); -void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState); -void DAC_DualSoftwareTriggerCmd(FunctionalState NewState); -void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState); -void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data); -void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data); -void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1); -uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel); - -/* DMA management functions ***************************************************/ -void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState); - -/* Interrupts and flags management functions **********************************/ -void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState); -FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG); -void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG); -ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT); -void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32L1xx_DAC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_dbgmcu.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_dbgmcu.h deleted file mode 100644 index 8b8aed1d2..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_dbgmcu.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_dbgmcu.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the DBGMCU - * firmware library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_DBGMCU_H -#define __STM32L1xx_DBGMCU_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup DBGMCU - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup DBGMCU_Exported_Constants - * @{ - */ - -#define DBGMCU_SLEEP ((uint32_t)0x00000001) -#define DBGMCU_STOP ((uint32_t)0x00000002) -#define DBGMCU_STANDBY ((uint32_t)0x00000004) -#define IS_DBGMCU_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFF8) == 0x00) && ((PERIPH) != 0x00)) - -#define DBGMCU_TIM2_STOP ((uint32_t)0x00000001) -#define DBGMCU_TIM3_STOP ((uint32_t)0x00000002) -#define DBGMCU_TIM4_STOP ((uint32_t)0x00000004) -#define DBGMCU_TIM6_STOP ((uint32_t)0x00000010) -#define DBGMCU_TIM7_STOP ((uint32_t)0x00000020) -#define DBGMCU_RTC_STOP ((uint32_t)0x00000400) -#define DBGMCU_WWDG_STOP ((uint32_t)0x00000800) -#define DBGMCU_IWDG_STOP ((uint32_t)0x00001000) -#define DBGMCU_I2C1_SMBUS_TIMEOUT ((uint32_t)0x00200000) -#define DBGMCU_I2C2_SMBUS_TIMEOUT ((uint32_t)0x00400000) -#define IS_DBGMCU_APB1PERIPH(PERIPH) ((((PERIPH) & 0xFF9FE3C8) == 0x00) && ((PERIPH) != 0x00)) - -#define DBGMCU_TIM9_STOP ((uint32_t)0x00000004) -#define DBGMCU_TIM10_STOP ((uint32_t)0x00000008) -#define DBGMCU_TIM11_STOP ((uint32_t)0x00000010) -#define IS_DBGMCU_APB2PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFE3) == 0x00) && ((PERIPH) != 0x00)) - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -uint32_t DBGMCU_GetREVID(void); -uint32_t DBGMCU_GetDEVID(void); -void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState); -void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState); -void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32L1xx_DBGMCU_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_dma.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_dma.h deleted file mode 100644 index 4925c929a..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_dma.h +++ /dev/null @@ -1,363 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_dma.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the DMA firmware - * library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_DMA_H -#define __STM32L1xx_DMA_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup DMA - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief DMA Init structure definition - */ - -typedef struct -{ - uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Channelx. */ - - uint32_t DMA_MemoryBaseAddr; /*!< Specifies the memory base address for DMAy Channelx. */ - - uint32_t DMA_DIR; /*!< Specifies if the peripheral is the source or destination. - This parameter can be a value of @ref DMA_data_transfer_direction */ - - uint32_t DMA_BufferSize; /*!< Specifies the buffer size, in data unit, of the specified Channel. - The data unit is equal to the configuration set in DMA_PeripheralDataSize - or DMA_MemoryDataSize members depending in the transfer direction. */ - - uint32_t DMA_PeripheralInc; /*!< Specifies whether the Peripheral address register is incremented or not. - This parameter can be a value of @ref DMA_peripheral_incremented_mode */ - - uint32_t DMA_MemoryInc; /*!< Specifies whether the memory address register is incremented or not. - This parameter can be a value of @ref DMA_memory_incremented_mode */ - - uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width. - This parameter can be a value of @ref DMA_peripheral_data_size */ - - uint32_t DMA_MemoryDataSize; /*!< Specifies the Memory data width. - This parameter can be a value of @ref DMA_memory_data_size */ - - uint32_t DMA_Mode; /*!< Specifies the operation mode of the DMAy Channelx. - This parameter can be a value of @ref DMA_circular_normal_mode. - @note: The circular buffer mode cannot be used if the memory-to-memory - data transfer is configured on the selected Channel */ - - uint32_t DMA_Priority; /*!< Specifies the software priority for the DMAy Channelx. - This parameter can be a value of @ref DMA_priority_level */ - - uint32_t DMA_M2M; /*!< Specifies if the DMAy Channelx will be used in memory-to-memory transfer. - This parameter can be a value of @ref DMA_memory_to_memory */ -}DMA_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup DMA_Exported_Constants - * @{ - */ - -#define IS_DMA_ALL_PERIPH(PERIPH) (((PERIPH) == DMA1_Channel1) || \ - ((PERIPH) == DMA1_Channel2) || \ - ((PERIPH) == DMA1_Channel3) || \ - ((PERIPH) == DMA1_Channel4) || \ - ((PERIPH) == DMA1_Channel5) || \ - ((PERIPH) == DMA1_Channel6) || \ - ((PERIPH) == DMA1_Channel7)) - -/** @defgroup DMA_data_transfer_direction - * @{ - */ - -#define DMA_DIR_PeripheralDST ((uint32_t)0x00000010) -#define DMA_DIR_PeripheralSRC ((uint32_t)0x00000000) -#define IS_DMA_DIR(DIR) (((DIR) == DMA_DIR_PeripheralDST) || \ - ((DIR) == DMA_DIR_PeripheralSRC)) -/** - * @} - */ - -/** @defgroup DMA_peripheral_incremented_mode - * @{ - */ - -#define DMA_PeripheralInc_Enable ((uint32_t)0x00000040) -#define DMA_PeripheralInc_Disable ((uint32_t)0x00000000) -#define IS_DMA_PERIPHERAL_INC_STATE(STATE) (((STATE) == DMA_PeripheralInc_Enable) || \ - ((STATE) == DMA_PeripheralInc_Disable)) -/** - * @} - */ - -/** @defgroup DMA_memory_incremented_mode - * @{ - */ - -#define DMA_MemoryInc_Enable ((uint32_t)0x00000080) -#define DMA_MemoryInc_Disable ((uint32_t)0x00000000) -#define IS_DMA_MEMORY_INC_STATE(STATE) (((STATE) == DMA_MemoryInc_Enable) || \ - ((STATE) == DMA_MemoryInc_Disable)) -/** - * @} - */ - -/** @defgroup DMA_peripheral_data_size - * @{ - */ - -#define DMA_PeripheralDataSize_Byte ((uint32_t)0x00000000) -#define DMA_PeripheralDataSize_HalfWord ((uint32_t)0x00000100) -#define DMA_PeripheralDataSize_Word ((uint32_t)0x00000200) -#define IS_DMA_PERIPHERAL_DATA_SIZE(SIZE) (((SIZE) == DMA_PeripheralDataSize_Byte) || \ - ((SIZE) == DMA_PeripheralDataSize_HalfWord) || \ - ((SIZE) == DMA_PeripheralDataSize_Word)) -/** - * @} - */ - -/** @defgroup DMA_memory_data_size - * @{ - */ - -#define DMA_MemoryDataSize_Byte ((uint32_t)0x00000000) -#define DMA_MemoryDataSize_HalfWord ((uint32_t)0x00000400) -#define DMA_MemoryDataSize_Word ((uint32_t)0x00000800) -#define IS_DMA_MEMORY_DATA_SIZE(SIZE) (((SIZE) == DMA_MemoryDataSize_Byte) || \ - ((SIZE) == DMA_MemoryDataSize_HalfWord) || \ - ((SIZE) == DMA_MemoryDataSize_Word)) -/** - * @} - */ - -/** @defgroup DMA_circular_normal_mode - * @{ - */ - -#define DMA_Mode_Circular ((uint32_t)0x00000020) -#define DMA_Mode_Normal ((uint32_t)0x00000000) -#define IS_DMA_MODE(MODE) (((MODE) == DMA_Mode_Circular) || ((MODE) == DMA_Mode_Normal)) -/** - * @} - */ - -/** @defgroup DMA_priority_level - * @{ - */ - -#define DMA_Priority_VeryHigh ((uint32_t)0x00003000) -#define DMA_Priority_High ((uint32_t)0x00002000) -#define DMA_Priority_Medium ((uint32_t)0x00001000) -#define DMA_Priority_Low ((uint32_t)0x00000000) -#define IS_DMA_PRIORITY(PRIORITY) (((PRIORITY) == DMA_Priority_VeryHigh) || \ - ((PRIORITY) == DMA_Priority_High) || \ - ((PRIORITY) == DMA_Priority_Medium) || \ - ((PRIORITY) == DMA_Priority_Low)) -/** - * @} - */ - -/** @defgroup DMA_memory_to_memory - * @{ - */ - -#define DMA_M2M_Enable ((uint32_t)0x00004000) -#define DMA_M2M_Disable ((uint32_t)0x00000000) -#define IS_DMA_M2M_STATE(STATE) (((STATE) == DMA_M2M_Enable) || ((STATE) == DMA_M2M_Disable)) - -/** - * @} - */ - -/** @defgroup DMA_interrupts_definition - * @{ - */ - -#define DMA_IT_TC ((uint32_t)0x00000002) -#define DMA_IT_HT ((uint32_t)0x00000004) -#define DMA_IT_TE ((uint32_t)0x00000008) -#define IS_DMA_CONFIG_IT(IT) ((((IT) & 0xFFFFFFF1) == 0x00) && ((IT) != 0x00)) - -#define DMA1_IT_GL1 ((uint32_t)0x00000001) -#define DMA1_IT_TC1 ((uint32_t)0x00000002) -#define DMA1_IT_HT1 ((uint32_t)0x00000004) -#define DMA1_IT_TE1 ((uint32_t)0x00000008) -#define DMA1_IT_GL2 ((uint32_t)0x00000010) -#define DMA1_IT_TC2 ((uint32_t)0x00000020) -#define DMA1_IT_HT2 ((uint32_t)0x00000040) -#define DMA1_IT_TE2 ((uint32_t)0x00000080) -#define DMA1_IT_GL3 ((uint32_t)0x00000100) -#define DMA1_IT_TC3 ((uint32_t)0x00000200) -#define DMA1_IT_HT3 ((uint32_t)0x00000400) -#define DMA1_IT_TE3 ((uint32_t)0x00000800) -#define DMA1_IT_GL4 ((uint32_t)0x00001000) -#define DMA1_IT_TC4 ((uint32_t)0x00002000) -#define DMA1_IT_HT4 ((uint32_t)0x00004000) -#define DMA1_IT_TE4 ((uint32_t)0x00008000) -#define DMA1_IT_GL5 ((uint32_t)0x00010000) -#define DMA1_IT_TC5 ((uint32_t)0x00020000) -#define DMA1_IT_HT5 ((uint32_t)0x00040000) -#define DMA1_IT_TE5 ((uint32_t)0x00080000) -#define DMA1_IT_GL6 ((uint32_t)0x00100000) -#define DMA1_IT_TC6 ((uint32_t)0x00200000) -#define DMA1_IT_HT6 ((uint32_t)0x00400000) -#define DMA1_IT_TE6 ((uint32_t)0x00800000) -#define DMA1_IT_GL7 ((uint32_t)0x01000000) -#define DMA1_IT_TC7 ((uint32_t)0x02000000) -#define DMA1_IT_HT7 ((uint32_t)0x04000000) -#define DMA1_IT_TE7 ((uint32_t)0x08000000) - -#define IS_DMA_CLEAR_IT(IT) ((((IT) & 0xF0000000) == 0x00) && ((IT) != 0x00)) - -#define IS_DMA_GET_IT(IT) (((IT) == DMA1_IT_GL1) || ((IT) == DMA1_IT_TC1) || \ - ((IT) == DMA1_IT_HT1) || ((IT) == DMA1_IT_TE1) || \ - ((IT) == DMA1_IT_GL2) || ((IT) == DMA1_IT_TC2) || \ - ((IT) == DMA1_IT_HT2) || ((IT) == DMA1_IT_TE2) || \ - ((IT) == DMA1_IT_GL3) || ((IT) == DMA1_IT_TC3) || \ - ((IT) == DMA1_IT_HT3) || ((IT) == DMA1_IT_TE3) || \ - ((IT) == DMA1_IT_GL4) || ((IT) == DMA1_IT_TC4) || \ - ((IT) == DMA1_IT_HT4) || ((IT) == DMA1_IT_TE4) || \ - ((IT) == DMA1_IT_GL5) || ((IT) == DMA1_IT_TC5) || \ - ((IT) == DMA1_IT_HT5) || ((IT) == DMA1_IT_TE5) || \ - ((IT) == DMA1_IT_GL6) || ((IT) == DMA1_IT_TC6) || \ - ((IT) == DMA1_IT_HT6) || ((IT) == DMA1_IT_TE6) || \ - ((IT) == DMA1_IT_GL7) || ((IT) == DMA1_IT_TC7) || \ - ((IT) == DMA1_IT_HT7) || ((IT) == DMA1_IT_TE7)) - -/** - * @} - */ - -/** @defgroup DMA_flags_definition - * @{ - */ -#define DMA1_FLAG_GL1 ((uint32_t)0x00000001) -#define DMA1_FLAG_TC1 ((uint32_t)0x00000002) -#define DMA1_FLAG_HT1 ((uint32_t)0x00000004) -#define DMA1_FLAG_TE1 ((uint32_t)0x00000008) -#define DMA1_FLAG_GL2 ((uint32_t)0x00000010) -#define DMA1_FLAG_TC2 ((uint32_t)0x00000020) -#define DMA1_FLAG_HT2 ((uint32_t)0x00000040) -#define DMA1_FLAG_TE2 ((uint32_t)0x00000080) -#define DMA1_FLAG_GL3 ((uint32_t)0x00000100) -#define DMA1_FLAG_TC3 ((uint32_t)0x00000200) -#define DMA1_FLAG_HT3 ((uint32_t)0x00000400) -#define DMA1_FLAG_TE3 ((uint32_t)0x00000800) -#define DMA1_FLAG_GL4 ((uint32_t)0x00001000) -#define DMA1_FLAG_TC4 ((uint32_t)0x00002000) -#define DMA1_FLAG_HT4 ((uint32_t)0x00004000) -#define DMA1_FLAG_TE4 ((uint32_t)0x00008000) -#define DMA1_FLAG_GL5 ((uint32_t)0x00010000) -#define DMA1_FLAG_TC5 ((uint32_t)0x00020000) -#define DMA1_FLAG_HT5 ((uint32_t)0x00040000) -#define DMA1_FLAG_TE5 ((uint32_t)0x00080000) -#define DMA1_FLAG_GL6 ((uint32_t)0x00100000) -#define DMA1_FLAG_TC6 ((uint32_t)0x00200000) -#define DMA1_FLAG_HT6 ((uint32_t)0x00400000) -#define DMA1_FLAG_TE6 ((uint32_t)0x00800000) -#define DMA1_FLAG_GL7 ((uint32_t)0x01000000) -#define DMA1_FLAG_TC7 ((uint32_t)0x02000000) -#define DMA1_FLAG_HT7 ((uint32_t)0x04000000) -#define DMA1_FLAG_TE7 ((uint32_t)0x08000000) - -#define IS_DMA_CLEAR_FLAG(FLAG) ((((FLAG) & 0xF0000000) == 0x00) && ((FLAG) != 0x00)) - -#define IS_DMA_GET_FLAG(FLAG) (((FLAG) == DMA1_FLAG_GL1) || ((FLAG) == DMA1_FLAG_TC1) || \ - ((FLAG) == DMA1_FLAG_HT1) || ((FLAG) == DMA1_FLAG_TE1) || \ - ((FLAG) == DMA1_FLAG_GL2) || ((FLAG) == DMA1_FLAG_TC2) || \ - ((FLAG) == DMA1_FLAG_HT2) || ((FLAG) == DMA1_FLAG_TE2) || \ - ((FLAG) == DMA1_FLAG_GL3) || ((FLAG) == DMA1_FLAG_TC3) || \ - ((FLAG) == DMA1_FLAG_HT3) || ((FLAG) == DMA1_FLAG_TE3) || \ - ((FLAG) == DMA1_FLAG_GL4) || ((FLAG) == DMA1_FLAG_TC4) || \ - ((FLAG) == DMA1_FLAG_HT4) || ((FLAG) == DMA1_FLAG_TE4) || \ - ((FLAG) == DMA1_FLAG_GL5) || ((FLAG) == DMA1_FLAG_TC5) || \ - ((FLAG) == DMA1_FLAG_HT5) || ((FLAG) == DMA1_FLAG_TE5) || \ - ((FLAG) == DMA1_FLAG_GL6) || ((FLAG) == DMA1_FLAG_TC6) || \ - ((FLAG) == DMA1_FLAG_HT6) || ((FLAG) == DMA1_FLAG_TE6) || \ - ((FLAG) == DMA1_FLAG_GL7) || ((FLAG) == DMA1_FLAG_TC7) || \ - ((FLAG) == DMA1_FLAG_HT7) || ((FLAG) == DMA1_FLAG_TE7)) -/** - * @} - */ - -/** @defgroup DMA_Buffer_Size - * @{ - */ - -#define IS_DMA_BUFFER_SIZE(SIZE) (((SIZE) >= 0x1) && ((SIZE) < 0x10000)) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* Function used to set the DMA configuration to the default reset state *****/ -void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx); - -/* Initialization and Configuration functions *********************************/ -void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct); -void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct); -void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState); - -/* Data Counter functions *****************************************************/ -void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber); -uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx); - -/* Interrupts and flags management functions **********************************/ -void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState); -FlagStatus DMA_GetFlagStatus(uint32_t DMA_FLAG); -void DMA_ClearFlag(uint32_t DMA_FLAG); -ITStatus DMA_GetITStatus(uint32_t DMA_IT); -void DMA_ClearITPendingBit(uint32_t DMA_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32L1xx_DMA_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_exti.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_exti.h deleted file mode 100644 index 1c2b6f2bd..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_exti.h +++ /dev/null @@ -1,190 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_exti.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the EXTI firmware - * library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_EXTI_H -#define __STM32L1xx_EXTI_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup EXTI - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief EXTI mode enumeration - */ - -typedef enum -{ - EXTI_Mode_Interrupt = 0x00, - EXTI_Mode_Event = 0x04 -}EXTIMode_TypeDef; - -#define IS_EXTI_MODE(MODE) (((MODE) == EXTI_Mode_Interrupt) || ((MODE) == EXTI_Mode_Event)) - -/** - * @brief EXTI Trigger enumeration - */ - -typedef enum -{ - EXTI_Trigger_Rising = 0x08, - EXTI_Trigger_Falling = 0x0C, - EXTI_Trigger_Rising_Falling = 0x10 -}EXTITrigger_TypeDef; - -#define IS_EXTI_TRIGGER(TRIGGER) (((TRIGGER) == EXTI_Trigger_Rising) || \ - ((TRIGGER) == EXTI_Trigger_Falling) || \ - ((TRIGGER) == EXTI_Trigger_Rising_Falling)) -/** - * @brief EXTI Init Structure definition - */ - -typedef struct -{ - uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled. - This parameter can be any combination of @ref EXTI_Lines */ - - EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines. - This parameter can be a value of @ref EXTIMode_TypeDef */ - - EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines. - This parameter can be a value of @ref EXTIMode_TypeDef */ - - FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines. - This parameter can be set either to ENABLE or DISABLE */ -}EXTI_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup EXTI_Exported_Constants - * @{ - */ - -/** @defgroup EXTI_Lines - * @{ - */ - -#define EXTI_Line0 ((uint32_t)0x00000001) /*!< External interrupt line 0 */ -#define EXTI_Line1 ((uint32_t)0x00000002) /*!< External interrupt line 1 */ -#define EXTI_Line2 ((uint32_t)0x00000004) /*!< External interrupt line 2 */ -#define EXTI_Line3 ((uint32_t)0x00000008) /*!< External interrupt line 3 */ -#define EXTI_Line4 ((uint32_t)0x00000010) /*!< External interrupt line 4 */ -#define EXTI_Line5 ((uint32_t)0x00000020) /*!< External interrupt line 5 */ -#define EXTI_Line6 ((uint32_t)0x00000040) /*!< External interrupt line 6 */ -#define EXTI_Line7 ((uint32_t)0x00000080) /*!< External interrupt line 7 */ -#define EXTI_Line8 ((uint32_t)0x00000100) /*!< External interrupt line 8 */ -#define EXTI_Line9 ((uint32_t)0x00000200) /*!< External interrupt line 9 */ -#define EXTI_Line10 ((uint32_t)0x00000400) /*!< External interrupt line 10 */ -#define EXTI_Line11 ((uint32_t)0x00000800) /*!< External interrupt line 11 */ -#define EXTI_Line12 ((uint32_t)0x00001000) /*!< External interrupt line 12 */ -#define EXTI_Line13 ((uint32_t)0x00002000) /*!< External interrupt line 13 */ -#define EXTI_Line14 ((uint32_t)0x00004000) /*!< External interrupt line 14 */ -#define EXTI_Line15 ((uint32_t)0x00008000) /*!< External interrupt line 15 */ -#define EXTI_Line16 ((uint32_t)0x00010000) /*!< External interrupt line 16 - Connected to the PVD Output */ -#define EXTI_Line17 ((uint32_t)0x00020000) /*!< External interrupt line 17 - Connected to the RTC Alarm - event */ -#define EXTI_Line18 ((uint32_t)0x00040000) /*!< External interrupt line 18 - Connected to the USB Device - FS Wakeup from suspend event */ -#define EXTI_Line19 ((uint32_t)0x00080000) /*!< External interrupt line 19 - Connected to the RTC Tamper - and Time Stamp events */ -#define EXTI_Line20 ((uint32_t)0x00100000) /*!< External interrupt line 20 - Connected to the RTC Wakeup - event */ -#define EXTI_Line21 ((uint32_t)0x00200000) /*!< External interrupt line 21 - Connected to the Comparator 1 - event */ - -#define EXTI_Line22 ((uint32_t)0x00400000) /*!< External interrupt line 22 - Connected to the Comparator 2 - event */ - -#define IS_EXTI_LINE(LINE) ((((LINE) & (uint32_t)0xFF800000) == 0x00) && ((LINE) != (uint16_t)0x00)) - -#define IS_GET_EXTI_LINE(LINE) (((LINE) == EXTI_Line0) || ((LINE) == EXTI_Line1) || \ - ((LINE) == EXTI_Line2) || ((LINE) == EXTI_Line3) || \ - ((LINE) == EXTI_Line4) || ((LINE) == EXTI_Line5) || \ - ((LINE) == EXTI_Line6) || ((LINE) == EXTI_Line7) || \ - ((LINE) == EXTI_Line8) || ((LINE) == EXTI_Line9) || \ - ((LINE) == EXTI_Line10) || ((LINE) == EXTI_Line11) || \ - ((LINE) == EXTI_Line12) || ((LINE) == EXTI_Line13) || \ - ((LINE) == EXTI_Line14) || ((LINE) == EXTI_Line15) || \ - ((LINE) == EXTI_Line16) || ((LINE) == EXTI_Line17) || \ - ((LINE) == EXTI_Line18) || ((LINE) == EXTI_Line19) || \ - ((LINE) == EXTI_Line20) || ((LINE) == EXTI_Line21) || \ - ((LINE) == EXTI_Line22)) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -/* Function used to set the EXTI configuration to the default reset state *****/ -void EXTI_DeInit(void); - -/* Initialization and Configuration functions *********************************/ -void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct); -void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct); -void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line); - -/* Interrupts and flags management functions **********************************/ -FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line); -void EXTI_ClearFlag(uint32_t EXTI_Line); -ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); -void EXTI_ClearITPendingBit(uint32_t EXTI_Line); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32L1xx_EXTI_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_flash.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_flash.h deleted file mode 100644 index 0e0a6c63a..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_flash.h +++ /dev/null @@ -1,354 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_flash.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the FLASH - * firmware library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_FLASH_H -#define __STM32L1xx_FLASH_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup FLASH - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief FLASH Status - */ -typedef enum -{ - FLASH_BUSY = 1, - FLASH_ERROR_WRP, - FLASH_ERROR_PROGRAM, - FLASH_COMPLETE, - FLASH_TIMEOUT -}FLASH_Status; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup FLASH_Exported_Constants - * @{ - */ - -/** @defgroup FLASH_Latency - * @{ - */ -#define FLASH_Latency_0 ((uint8_t)0x00) /*!< FLASH Zero Latency cycle */ -#define FLASH_Latency_1 ((uint8_t)0x01) /*!< FLASH One Latency cycle */ - -#define IS_FLASH_LATENCY(LATENCY) (((LATENCY) == FLASH_Latency_0) || \ - ((LATENCY) == FLASH_Latency_1)) -/** - * @} - */ - -/** @defgroup FLASH_Interrupts - * @{ - */ - -#define FLASH_IT_EOP FLASH_PECR_EOPIE /*!< End of programming interrupt source */ -#define FLASH_IT_ERR FLASH_PECR_ERRIE /*!< Error interrupt source */ -#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0xFFFCFFFF) == 0x00000000) && (((IT) != 0x00000000))) -/** - * @} - */ - -/** @defgroup FLASH_Address - * @{ - */ - -#define IS_FLASH_DATA_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08080000) && ((ADDRESS) <= 0x08080FFF)) -#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) <= 0x0801FFFF)) - -/** - * @} - */ - -/** @defgroup Option_Bytes_Write_Protection - * @{ - */ - - -#define OB_WRP_Pages0to15 ((uint32_t)0x00000001) /* Write protection of Sector0 */ -#define OB_WRP_Pages16to31 ((uint32_t)0x00000002) /* Write protection of Sector1 */ -#define OB_WRP_Pages32to47 ((uint32_t)0x00000004) /* Write protection of Sector2 */ -#define OB_WRP_Pages48to63 ((uint32_t)0x00000008) /* Write protection of Sector3 */ -#define OB_WRP_Pages64to79 ((uint32_t)0x00000010) /* Write protection of Sector4 */ -#define OB_WRP_Pages80to95 ((uint32_t)0x00000020) /* Write protection of Sector5 */ -#define OB_WRP_Pages96to111 ((uint32_t)0x00000040) /* Write protection of Sector6 */ -#define OB_WRP_Pages112to127 ((uint32_t)0x00000080) /* Write protection of Sector7 */ -#define OB_WRP_Pages128to143 ((uint32_t)0x00000100) /* Write protection of Sector8 */ -#define OB_WRP_Pages144to159 ((uint32_t)0x00000200) /* Write protection of Sector9 */ -#define OB_WRP_Pages160to175 ((uint32_t)0x00000400) /* Write protection of Sector10 */ -#define OB_WRP_Pages176to191 ((uint32_t)0x00000800) /* Write protection of Sector11 */ -#define OB_WRP_Pages192to207 ((uint32_t)0x00001000) /* Write protection of Sector12 */ -#define OB_WRP_Pages208to223 ((uint32_t)0x00002000) /* Write protection of Sector13 */ -#define OB_WRP_Pages224to239 ((uint32_t)0x00004000) /* Write protection of Sector14 */ -#define OB_WRP_Pages240to255 ((uint32_t)0x00008000) /* Write protection of Sector15 */ -#define OB_WRP_Pages256to271 ((uint32_t)0x00010000) /* Write protection of Sector16 */ -#define OB_WRP_Pages272to287 ((uint32_t)0x00020000) /* Write protection of Sector17 */ -#define OB_WRP_Pages288to303 ((uint32_t)0x00040000) /* Write protection of Sector18 */ -#define OB_WRP_Pages304to319 ((uint32_t)0x00080000) /* Write protection of Sector19 */ -#define OB_WRP_Pages320to335 ((uint32_t)0x00100000) /* Write protection of Sector20 */ -#define OB_WRP_Pages336to351 ((uint32_t)0x00200000) /* Write protection of Sector21 */ -#define OB_WRP_Pages352to367 ((uint32_t)0x00400000) /* Write protection of Sector22 */ -#define OB_WRP_Pages368to383 ((uint32_t)0x00800000) /* Write protection of Sector23 */ -#define OB_WRP_Pages384to399 ((uint32_t)0x01000000) /* Write protection of Sector24 */ -#define OB_WRP_Pages400to415 ((uint32_t)0x02000000) /* Write protection of Sector25 */ -#define OB_WRP_Pages416to431 ((uint32_t)0x04000000) /* Write protection of Sector26 */ -#define OB_WRP_Pages432to447 ((uint32_t)0x08000000) /* Write protection of Sector27 */ -#define OB_WRP_Pages448to463 ((uint32_t)0x10000000) /* Write protection of Sector28 */ -#define OB_WRP_Pages464to479 ((uint32_t)0x20000000) /* Write protection of Sector29 */ -#define OB_WRP_Pages480to495 ((uint32_t)0x40000000) /* Write protection of Sector30 */ -#define OB_WRP_Pages496to511 ((uint32_t)0x80000000) /* Write protection of Sector31 */ - -#define OB_WRP_AllPages ((uint32_t)0xFFFFFFFF) /*!< Write protection of all Sectors */ - -#define IS_OB_WRP(PAGE) (((PAGE) != 0x0000000)) - -/** - * @} - */ - -/** @defgroup Option_Bytes_Read_Protection - * @{ - */ - -/** - * @brief Read Protection Level - */ -#define OB_RDP_Level_0 ((uint8_t)0xAA) -#define OB_RDP_Level_1 ((uint8_t)0xBB) -/*#define OB_RDP_Level_2 ((uint8_t)0xCC)*/ /* Warning: When enabling read protection level 2 - it's no more possible to go back to level 1 or 0 */ - -#define IS_OB_RDP(LEVEL) (((LEVEL) == OB_RDP_Level_0)||\ - ((LEVEL) == OB_RDP_Level_1))/*||\ - ((LEVEL) == OB_RDP_Level_2))*/ -/** - * @} - */ - -/** @defgroup Option_Bytes_IWatchdog - * @{ - */ - -#define OB_IWDG_SW ((uint8_t)0x10) /*!< Software WDG selected */ -#define OB_IWDG_HW ((uint8_t)0x00) /*!< Hardware WDG selected */ -#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW)) - -/** - * @} - */ - -/** @defgroup Option_Bytes_nRST_STOP - * @{ - */ - -#define OB_STOP_NoRST ((uint8_t)0x20) /*!< No reset generated when entering in STOP */ -#define OB_STOP_RST ((uint8_t)0x00) /*!< Reset generated when entering in STOP */ -#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NoRST) || ((SOURCE) == OB_STOP_RST)) - -/** - * @} - */ - -/** @defgroup Option_Bytes_nRST_STDBY - * @{ - */ - -#define OB_STDBY_NoRST ((uint8_t)0x40) /*!< No reset generated when entering in STANDBY */ -#define OB_STDBY_RST ((uint8_t)0x00) /*!< Reset generated when entering in STANDBY */ -#define IS_OB_STDBY_SOURCE(SOURCE) (((SOURCE) == OB_STDBY_NoRST) || ((SOURCE) == OB_STDBY_RST)) - -/** - * @} - */ - -/** @defgroup Option_Bytes_BOR_Level - * @{ - */ - -#define OB_BOR_OFF ((uint8_t)0x00) /*!< BOR is disabled at power down, the reset is asserted when the VDD - power supply reaches the PDR(Power Down Reset) threshold (1.5V) */ -#define OB_BOR_LEVEL1 ((uint8_t)0x08) /*!< BOR Reset threshold levels for 1.7V - 1.8V VDD power supply */ -#define OB_BOR_LEVEL2 ((uint8_t)0x09) /*!< BOR Reset threshold levels for 1.9V - 2.0V VDD power supply */ -#define OB_BOR_LEVEL3 ((uint8_t)0x0A) /*!< BOR Reset threshold levels for 2.3V - 2.4V VDD power supply */ -#define OB_BOR_LEVEL4 ((uint8_t)0x0B) /*!< BOR Reset threshold levels for 2.55V - 2.65V VDD power supply */ -#define OB_BOR_LEVEL5 ((uint8_t)0x0C) /*!< BOR Reset threshold levels for 2.8V - 2.9V VDD power supply */ - -#define IS_OB_BOR_LEVEL(LEVEL) (((LEVEL) == OB_BOR_OFF) || \ - ((LEVEL) == OB_BOR_LEVEL1) || \ - ((LEVEL) == OB_BOR_LEVEL2) || \ - ((LEVEL) == OB_BOR_LEVEL3) || \ - ((LEVEL) == OB_BOR_LEVEL4) || \ - ((LEVEL) == OB_BOR_LEVEL5)) - -/** - * @} - */ - -/** @defgroup FLASH_Flags - * @{ - */ - -#define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */ -#define FLASH_FLAG_EOP FLASH_SR_EOP /*!< FLASH End of Programming flag */ -#define FLASH_FLAG_ENDHV FLASH_SR_ENHV /*!< FLASH End of High Voltage flag */ -#define FLASH_FLAG_READY FLASH_SR_READY /*!< FLASH Ready flag after low power mode */ -#define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< FLASH Write protected error flag */ -#define FLASH_FLAG_PGAERR FLASH_SR_PGAERR /*!< FLASH Programming Alignment error flag */ -#define FLASH_FLAG_SIZERR FLASH_SR_SIZERR /*!< FLASH Size error flag */ -#define FLASH_FLAG_OPTVERR FLASH_SR_OPTVERR /*!< FLASH Option Validity error flag */ - -#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFF0FD) == 0x00000000) && ((FLAG) != 0x00000000)) - -#define IS_FLASH_GET_FLAG(FLAG) (((FLAG) == FLASH_FLAG_BSY) || ((FLAG) == FLASH_FLAG_EOP) || \ - ((FLAG) == FLASH_FLAG_ENDHV) || ((FLAG) == FLASH_FLAG_READY ) || \ - ((FLAG) == FLASH_FLAG_WRPERR) || ((FLAG) == FLASH_FLAG_PGAERR ) || \ - ((FLAG) == FLASH_FLAG_SIZERR) || ((FLAG) == FLASH_FLAG_OPTVERR)) -/** - * @} - */ - -/** @defgroup FLASH_Keys - * @{ - */ - -#define FLASH_PDKEY1 ((uint32_t)0x04152637) /*!< Flash power down key1 */ -#define FLASH_PDKEY2 ((uint32_t)0xFAFBFCFD) /*!< Flash power down key2: used with FLASH_PDKEY1 - to unlock the RUN_PD bit in FLASH_ACR */ - -#define FLASH_PEKEY1 ((uint32_t)0x89ABCDEF) /*!< Flash program erase key1 */ -#define FLASH_PEKEY2 ((uint32_t)0x02030405) /*!< Flash program erase key: used with FLASH_PEKEY2 - to unlock the write access to the FLASH_PECR register and - data EEPROM */ - -#define FLASH_PRGKEY1 ((uint32_t)0x8C9DAEBF) /*!< Flash program memory key1 */ -#define FLASH_PRGKEY2 ((uint32_t)0x13141516) /*!< Flash program memory key2: used with FLASH_PRGKEY2 - to unlock the program memory */ - -#define FLASH_OPTKEY1 ((uint32_t)0xFBEAD9C8) /*!< Flash option key1 */ -#define FLASH_OPTKEY2 ((uint32_t)0x24252627) /*!< Flash option key2: used with FLASH_OPTKEY1 to - unlock the write access to the option byte block */ -/** - * @} - */ - -/** @defgroup Timeout_definition - * @{ - */ -#define FLASH_ER_PRG_TIMEOUT ((uint32_t)0x8000) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/** - * @brief FLASH memory functions that can be executed from FLASH. - */ -/* FLASH Interface configuration functions ************************************/ -void FLASH_SetLatency(uint32_t FLASH_Latency); -void FLASH_PrefetchBufferCmd(FunctionalState NewState); -void FLASH_ReadAccess64Cmd(FunctionalState NewState); -void FLASH_SLEEPPowerDownCmd(FunctionalState NewState); - -/* FLASH Memory Programming functions *****************************************/ -void FLASH_Unlock(void); -void FLASH_Lock(void); -FLASH_Status FLASH_ErasePage(uint32_t Page_Address); -FLASH_Status FLASH_FastProgramWord(uint32_t Address, uint32_t Data); - -/* DATA EEPROM Programming functions ******************************************/ -void DATA_EEPROM_Unlock(void); -void DATA_EEPROM_Lock(void); -void DATA_EEPROM_FixedTimeProgramCmd(FunctionalState NewState); -FLASH_Status DATA_EEPROM_EraseWord(uint32_t Address); -FLASH_Status DATA_EEPROM_FastProgramByte(uint32_t Address, uint8_t Data); -FLASH_Status DATA_EEPROM_FastProgramHalfWord(uint32_t Address, uint16_t Data); -FLASH_Status DATA_EEPROM_FastProgramWord(uint32_t Address, uint32_t Data); -FLASH_Status DATA_EEPROM_ProgramByte(uint32_t Address, uint8_t Data); -FLASH_Status DATA_EEPROM_ProgramHalfWord(uint32_t Address, uint16_t Data); -FLASH_Status DATA_EEPROM_ProgramWord(uint32_t Address, uint32_t Data); - -/* Option Bytes Programming functions *****************************************/ -void FLASH_OB_Unlock(void); -void FLASH_OB_Lock(void); -void FLASH_OB_Launch(void); -FLASH_Status FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState); -FLASH_Status FLASH_OB_RDPConfig(uint8_t OB_RDP); -FLASH_Status FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY); -FLASH_Status FLASH_OB_BORConfig(uint8_t OB_BOR); -uint8_t FLASH_OB_GetUser(void); -uint32_t FLASH_OB_GetWRP(void); -FlagStatus FLASH_OB_GetRDP(void); -uint8_t FLASH_OB_GetBOR(void); - -/* Interrupts and flags management functions **********************************/ -void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState); -FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG); -void FLASH_ClearFlag(uint32_t FLASH_FLAG); -FLASH_Status FLASH_GetStatus(void); -FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout); - -/** - * @brief FLASH memory functions that should be executed from internal SRAM. - * These functions are defined inside the "stm32l1xx_flash_ramfunc.c" - * file. - */ -FLASH_Status FLASH_RUNPowerDownCmd(FunctionalState NewState); -FLASH_Status FLASH_ProgramHalfPage(uint32_t Address, uint32_t* pBuffer); -FLASH_Status DATA_EEPROM_EraseDoubleWord(uint32_t Address); -FLASH_Status DATA_EEPROM_ProgramDoubleWord(uint32_t Address, uint64_t Data); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32L1xx_FLASH_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_gpio.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_gpio.h deleted file mode 100644 index 6e1a1dd1d..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_gpio.h +++ /dev/null @@ -1,364 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_gpio.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the GPIO - * firmware library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_GPIO_H -#define __STM32L1xx_GPIO_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup GPIO - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ - ((PERIPH) == GPIOB) || \ - ((PERIPH) == GPIOC) || \ - ((PERIPH) == GPIOD) || \ - ((PERIPH) == GPIOE) || \ - ((PERIPH) == GPIOH)) - -/** @defgroup Configuration_Mode_enumeration - * @{ - */ -typedef enum -{ - GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ - GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ - GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ - GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */ -}GPIOMode_TypeDef; -#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN) || ((MODE) == GPIO_Mode_OUT) || \ - ((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN)) -/** - * @} - */ - -/** @defgroup Output_type_enumeration - * @{ - */ -typedef enum -{ GPIO_OType_PP = 0x00, - GPIO_OType_OD = 0x01 -}GPIOOType_TypeDef; -#define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD)) - -/** - * @} - */ - -/** @defgroup Output_Maximum_frequency_enumeration - * @{ - */ -typedef enum -{ - GPIO_Speed_400KHz = 0x00, /*!< Very Low Speed */ - GPIO_Speed_2MHz = 0x01, /*!< Low Speed */ - GPIO_Speed_10MHz = 0x02, /*!< Medium Speed */ - GPIO_Speed_40MHz = 0x03 /*!< High Speed */ -}GPIOSpeed_TypeDef; -#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_400KHz) || ((SPEED) == GPIO_Speed_2MHz) || \ - ((SPEED) == GPIO_Speed_10MHz)|| ((SPEED) == GPIO_Speed_40MHz)) -/** - * @} - */ - -/** @defgroup Configuration_Pull-Up_Pull-Down_enumeration - * @{ - */ -typedef enum -{ GPIO_PuPd_NOPULL = 0x00, - GPIO_PuPd_UP = 0x01, - GPIO_PuPd_DOWN = 0x02 -}GPIOPuPd_TypeDef; -#define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \ - ((PUPD) == GPIO_PuPd_DOWN)) -/** - * @} - */ - -/** @defgroup Bit_SET_and_Bit_RESET_enumeration - * @{ - */ -typedef enum -{ Bit_RESET = 0, - Bit_SET -}BitAction; -#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) - -/** - * @} - */ - -/** - * @brief GPIO Init structure definition - */ -typedef struct -{ - uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. - This parameter can be any value of @ref GPIO_pins_define */ - - GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. - This parameter can be a value of @ref GPIOMode_TypeDef */ - - GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. - This parameter can be a value of @ref GPIOSpeed_TypeDef */ - - GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins. - This parameter can be a value of @ref GPIOOType_TypeDef */ - - GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. - This parameter can be a value of @ref GPIOPuPd_TypeDef */ -}GPIO_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup GPIO_Exported_Constants - * @{ - */ - -/** @defgroup GPIO_pins_define - * @{ - */ -#define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */ -#define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */ -#define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */ -#define GPIO_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */ -#define GPIO_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */ -#define GPIO_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */ -#define GPIO_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */ -#define GPIO_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */ -#define GPIO_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */ -#define GPIO_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */ -#define GPIO_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */ -#define GPIO_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */ -#define GPIO_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */ -#define GPIO_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */ -#define GPIO_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */ -#define GPIO_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */ -#define GPIO_Pin_All ((uint16_t)0xFFFF) /*!< All pins selected */ - -#define IS_GPIO_PIN(PIN) ((PIN) != (uint16_t)0x00) -#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \ - ((PIN) == GPIO_Pin_1) || \ - ((PIN) == GPIO_Pin_2) || \ - ((PIN) == GPIO_Pin_3) || \ - ((PIN) == GPIO_Pin_4) || \ - ((PIN) == GPIO_Pin_5) || \ - ((PIN) == GPIO_Pin_6) || \ - ((PIN) == GPIO_Pin_7) || \ - ((PIN) == GPIO_Pin_8) || \ - ((PIN) == GPIO_Pin_9) || \ - ((PIN) == GPIO_Pin_10) || \ - ((PIN) == GPIO_Pin_11) || \ - ((PIN) == GPIO_Pin_12) || \ - ((PIN) == GPIO_Pin_13) || \ - ((PIN) == GPIO_Pin_14) || \ - ((PIN) == GPIO_Pin_15)) -/** - * @} - */ - -/** @defgroup GPIO_Pin_sources - * @{ - */ -#define GPIO_PinSource0 ((uint8_t)0x00) -#define GPIO_PinSource1 ((uint8_t)0x01) -#define GPIO_PinSource2 ((uint8_t)0x02) -#define GPIO_PinSource3 ((uint8_t)0x03) -#define GPIO_PinSource4 ((uint8_t)0x04) -#define GPIO_PinSource5 ((uint8_t)0x05) -#define GPIO_PinSource6 ((uint8_t)0x06) -#define GPIO_PinSource7 ((uint8_t)0x07) -#define GPIO_PinSource8 ((uint8_t)0x08) -#define GPIO_PinSource9 ((uint8_t)0x09) -#define GPIO_PinSource10 ((uint8_t)0x0A) -#define GPIO_PinSource11 ((uint8_t)0x0B) -#define GPIO_PinSource12 ((uint8_t)0x0C) -#define GPIO_PinSource13 ((uint8_t)0x0D) -#define GPIO_PinSource14 ((uint8_t)0x0E) -#define GPIO_PinSource15 ((uint8_t)0x0F) - -#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \ - ((PINSOURCE) == GPIO_PinSource1) || \ - ((PINSOURCE) == GPIO_PinSource2) || \ - ((PINSOURCE) == GPIO_PinSource3) || \ - ((PINSOURCE) == GPIO_PinSource4) || \ - ((PINSOURCE) == GPIO_PinSource5) || \ - ((PINSOURCE) == GPIO_PinSource6) || \ - ((PINSOURCE) == GPIO_PinSource7) || \ - ((PINSOURCE) == GPIO_PinSource8) || \ - ((PINSOURCE) == GPIO_PinSource9) || \ - ((PINSOURCE) == GPIO_PinSource10) || \ - ((PINSOURCE) == GPIO_PinSource11) || \ - ((PINSOURCE) == GPIO_PinSource12) || \ - ((PINSOURCE) == GPIO_PinSource13) || \ - ((PINSOURCE) == GPIO_PinSource14) || \ - ((PINSOURCE) == GPIO_PinSource15)) -/** - * @} - */ - -/** @defgroup GPIO_Alternat_function_selection_define - * @{ - */ - -/** - * @brief AF 0 selection - */ -#define GPIO_AF_RTC_50Hz ((uint8_t)0x00) /*!< RTC 50/60 Hz Alternate Function mapping */ -#define GPIO_AF_MCO ((uint8_t)0x00) /*!< MCO Alternate Function mapping */ -#define GPIO_AF_RTC_AF1 ((uint8_t)0x00) /*!< RTC_AF1 Alternate Function mapping */ -#define GPIO_AF_WKUP ((uint8_t)0x00) /*!< Wakeup (WKUP1, WKUP2 and WKUP3) Alternate Function mapping */ -#define GPIO_AF_SWJ ((uint8_t)0x00) /*!< SWJ (SW and JTAG) Alternate Function mapping */ -#define GPIO_AF_TRACE ((uint8_t)0x00) /*!< TRACE Alternate Function mapping */ - -/** - * @brief AF 1 selection - */ -#define GPIO_AF_TIM2 ((uint8_t)0x01) /*!< TIM2 Alternate Function mapping */ -/** - * @brief AF 2 selection - */ -#define GPIO_AF_TIM3 ((uint8_t)0x02) /*!< TIM3 Alternate Function mapping */ -#define GPIO_AF_TIM4 ((uint8_t)0x02) /*!< TIM4 Alternate Function mapping */ -/** - * @brief AF 3 selection - */ -#define GPIO_AF_TIM9 ((uint8_t)0x03) /*!< TIM9 Alternate Function mapping */ -#define GPIO_AF_TIM10 ((uint8_t)0x03) /*!< TIM10 Alternate Function mapping */ -#define GPIO_AF_TIM11 ((uint8_t)0x03) /*!< TIM11 Alternate Function mapping */ -/** - * @brief AF 4 selection - */ -#define GPIO_AF_I2C1 ((uint8_t)0x04) /*!< I2C1 Alternate Function mapping */ -#define GPIO_AF_I2C2 ((uint8_t)0x04) /*!< I2C2 Alternate Function mapping */ -/** - * @brief AF 5 selection - */ -#define GPIO_AF_SPI1 ((uint8_t)0x05) /*!< SPI1 Alternate Function mapping */ -#define GPIO_AF_SPI2 ((uint8_t)0x05) /*!< SPI2 Alternate Function mapping */ -/** - * @brief AF 7 selection - */ -#define GPIO_AF_USART1 ((uint8_t)0x07) /*!< USART1 Alternate Function mapping */ -#define GPIO_AF_USART2 ((uint8_t)0x07) /*!< USART2 Alternate Function mapping */ -#define GPIO_AF_USART3 ((uint8_t)0x07) /*!< USART3 Alternate Function mapping */ -/** - * @brief AF 10 selection - */ -#define GPIO_AF_USB ((uint8_t)0xA) /*!< USB Full speed device Alternate Function mapping */ -/** - * @brief AF 11 selection - */ -#define GPIO_AF_LCD ((uint8_t)0x0B) /*!< LCD Alternate Function mapping */ -/** - * @brief AF 14 selection - */ -#define GPIO_AF_RI ((uint8_t)0x0E) /*!< RI Alternate Function mapping */ - -/** - * @brief AF 15 selection - */ -#define GPIO_AF_EVENTOUT ((uint8_t)0x0F) /*!< EVENTOUT Alternate Function mapping */ - -#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_MCO) || \ - ((AF) == GPIO_AF_RTC_AF1) || ((AF) == GPIO_AF_WKUP) || \ - ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ - ((AF) == GPIO_AF_TIM2) || ((AF)== GPIO_AF_TIM3) || \ - ((AF) == GPIO_AF_TIM4) || ((AF)== GPIO_AF_TIM9) || \ - ((AF) == GPIO_AF_TIM10) || ((AF)== GPIO_AF_TIM11) || \ - ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ - ((AF) == GPIO_AF_SPI1) || ((AF) == GPIO_AF_SPI2) || \ - ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ - ((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_USB) || \ - ((AF) == GPIO_AF_LCD) || ((AF) == GPIO_AF_RI) || \ - ((AF) == GPIO_AF_EVENTOUT)) - -/** - * @} - */ - -/** @defgroup GPIO_Legacy - * @{ - */ - -#define GPIO_Mode_AIN GPIO_Mode_AN - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* Function used to set the GPIO configuration to the default reset state ****/ -void GPIO_DeInit(GPIO_TypeDef* GPIOx); - -/* Initialization and Configuration functions *********************************/ -void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); -void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); -void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); - -/* GPIO Read and Write functions **********************************************/ -uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); -uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); -void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); -void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); - -/* GPIO Alternate functions configuration functions ***************************/ -void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32L1xx_GPIO_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_i2c.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_i2c.h deleted file mode 100644 index 15b5c5464..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_i2c.h +++ /dev/null @@ -1,688 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_i2c.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the I2C firmware - * library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_I2C_H -#define __STM32L1xx_I2C_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup I2C - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief I2C Init structure definition - */ - -typedef struct -{ - uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency. - This parameter must be set to a value lower than 400kHz */ - - uint16_t I2C_Mode; /*!< Specifies the I2C mode. - This parameter can be a value of @ref I2C_mode */ - - uint16_t I2C_DutyCycle; /*!< Specifies the I2C fast mode duty cycle. - This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */ - - uint16_t I2C_OwnAddress1; /*!< Specifies the first device own address. - This parameter can be a 7-bit or 10-bit address. */ - - uint16_t I2C_Ack; /*!< Enables or disables the acknowledgement. - This parameter can be a value of @ref I2C_acknowledgement */ - - uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged. - This parameter can be a value of @ref I2C_acknowledged_address */ -}I2C_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - - -/** @defgroup I2C_Exported_Constants - * @{ - */ - -#define IS_I2C_ALL_PERIPH(PERIPH) (((PERIPH) == I2C1) || \ - ((PERIPH) == I2C2)) -/** @defgroup I2C_mode - * @{ - */ - -#define I2C_Mode_I2C ((uint16_t)0x0000) -#define I2C_Mode_SMBusDevice ((uint16_t)0x0002) -#define I2C_Mode_SMBusHost ((uint16_t)0x000A) -#define IS_I2C_MODE(MODE) (((MODE) == I2C_Mode_I2C) || \ - ((MODE) == I2C_Mode_SMBusDevice) || \ - ((MODE) == I2C_Mode_SMBusHost)) -/** - * @} - */ - -/** @defgroup I2C_duty_cycle_in_fast_mode - * @{ - */ - -#define I2C_DutyCycle_16_9 ((uint16_t)0x4000) /*!< I2C fast mode Tlow/Thigh = 16/9 */ -#define I2C_DutyCycle_2 ((uint16_t)0xBFFF) /*!< I2C fast mode Tlow/Thigh = 2 */ -#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DutyCycle_16_9) || \ - ((CYCLE) == I2C_DutyCycle_2)) -/** - * @} - */ - -/** @defgroup I2C_acknowledgement - * @{ - */ - -#define I2C_Ack_Enable ((uint16_t)0x0400) -#define I2C_Ack_Disable ((uint16_t)0x0000) -#define IS_I2C_ACK_STATE(STATE) (((STATE) == I2C_Ack_Enable) || \ - ((STATE) == I2C_Ack_Disable)) -/** - * @} - */ - -/** @defgroup I2C_transfer_direction - * @{ - */ - -#define I2C_Direction_Transmitter ((uint8_t)0x00) -#define I2C_Direction_Receiver ((uint8_t)0x01) -#define IS_I2C_DIRECTION(DIRECTION) (((DIRECTION) == I2C_Direction_Transmitter) || \ - ((DIRECTION) == I2C_Direction_Receiver)) -/** - * @} - */ - -/** @defgroup I2C_acknowledged_address - * @{ - */ - -#define I2C_AcknowledgedAddress_7bit ((uint16_t)0x4000) -#define I2C_AcknowledgedAddress_10bit ((uint16_t)0xC000) -#define IS_I2C_ACKNOWLEDGE_ADDRESS(ADDRESS) (((ADDRESS) == I2C_AcknowledgedAddress_7bit) || \ - ((ADDRESS) == I2C_AcknowledgedAddress_10bit)) -/** - * @} - */ - -/** @defgroup I2C_registers - * @{ - */ - -#define I2C_Register_CR1 ((uint8_t)0x00) -#define I2C_Register_CR2 ((uint8_t)0x04) -#define I2C_Register_OAR1 ((uint8_t)0x08) -#define I2C_Register_OAR2 ((uint8_t)0x0C) -#define I2C_Register_DR ((uint8_t)0x10) -#define I2C_Register_SR1 ((uint8_t)0x14) -#define I2C_Register_SR2 ((uint8_t)0x18) -#define I2C_Register_CCR ((uint8_t)0x1C) -#define I2C_Register_TRISE ((uint8_t)0x20) -#define IS_I2C_REGISTER(REGISTER) (((REGISTER) == I2C_Register_CR1) || \ - ((REGISTER) == I2C_Register_CR2) || \ - ((REGISTER) == I2C_Register_OAR1) || \ - ((REGISTER) == I2C_Register_OAR2) || \ - ((REGISTER) == I2C_Register_DR) || \ - ((REGISTER) == I2C_Register_SR1) || \ - ((REGISTER) == I2C_Register_SR2) || \ - ((REGISTER) == I2C_Register_CCR) || \ - ((REGISTER) == I2C_Register_TRISE)) -/** - * @} - */ - -/** @defgroup I2C_SMBus_alert_pin_level - * @{ - */ - -#define I2C_SMBusAlert_Low ((uint16_t)0x2000) -#define I2C_SMBusAlert_High ((uint16_t)0xDFFF) -#define IS_I2C_SMBUS_ALERT(ALERT) (((ALERT) == I2C_SMBusAlert_Low) || \ - ((ALERT) == I2C_SMBusAlert_High)) -/** - * @} - */ - -/** @defgroup I2C_PEC_position - * @{ - */ - -#define I2C_PECPosition_Next ((uint16_t)0x0800) -#define I2C_PECPosition_Current ((uint16_t)0xF7FF) -#define IS_I2C_PEC_POSITION(POSITION) (((POSITION) == I2C_PECPosition_Next) || \ - ((POSITION) == I2C_PECPosition_Current)) -/** - * @} - */ - -/** @defgroup I2C_interrupts_definition - * @{ - */ - -#define I2C_IT_BUF ((uint16_t)0x0400) -#define I2C_IT_EVT ((uint16_t)0x0200) -#define I2C_IT_ERR ((uint16_t)0x0100) -#define IS_I2C_CONFIG_IT(IT) ((((IT) & (uint16_t)0xF8FF) == 0x00) && ((IT) != 0x00)) -/** - * @} - */ - -/** @defgroup I2C_interrupts_definition - * @{ - */ - -#define I2C_IT_SMBALERT ((uint32_t)0x01008000) -#define I2C_IT_TIMEOUT ((uint32_t)0x01004000) -#define I2C_IT_PECERR ((uint32_t)0x01001000) -#define I2C_IT_OVR ((uint32_t)0x01000800) -#define I2C_IT_AF ((uint32_t)0x01000400) -#define I2C_IT_ARLO ((uint32_t)0x01000200) -#define I2C_IT_BERR ((uint32_t)0x01000100) -#define I2C_IT_TXE ((uint32_t)0x06000080) -#define I2C_IT_RXNE ((uint32_t)0x06000040) -#define I2C_IT_STOPF ((uint32_t)0x02000010) -#define I2C_IT_ADD10 ((uint32_t)0x02000008) -#define I2C_IT_BTF ((uint32_t)0x02000004) -#define I2C_IT_ADDR ((uint32_t)0x02000002) -#define I2C_IT_SB ((uint32_t)0x02000001) - -#define IS_I2C_CLEAR_IT(IT) ((((IT) & (uint16_t)0x20FF) == 0x00) && ((IT) != (uint16_t)0x00)) - -#define IS_I2C_GET_IT(IT) (((IT) == I2C_IT_SMBALERT) || ((IT) == I2C_IT_TIMEOUT) || \ - ((IT) == I2C_IT_PECERR) || ((IT) == I2C_IT_OVR) || \ - ((IT) == I2C_IT_AF) || ((IT) == I2C_IT_ARLO) || \ - ((IT) == I2C_IT_BERR) || ((IT) == I2C_IT_TXE) || \ - ((IT) == I2C_IT_RXNE) || ((IT) == I2C_IT_STOPF) || \ - ((IT) == I2C_IT_ADD10) || ((IT) == I2C_IT_BTF) || \ - ((IT) == I2C_IT_ADDR) || ((IT) == I2C_IT_SB)) -/** - * @} - */ - -/** @defgroup I2C_flags_definition - * @{ - */ - -/** - * @brief SR2 register flags - */ - -#define I2C_FLAG_DUALF ((uint32_t)0x00800000) -#define I2C_FLAG_SMBHOST ((uint32_t)0x00400000) -#define I2C_FLAG_SMBDEFAULT ((uint32_t)0x00200000) -#define I2C_FLAG_GENCALL ((uint32_t)0x00100000) -#define I2C_FLAG_TRA ((uint32_t)0x00040000) -#define I2C_FLAG_BUSY ((uint32_t)0x00020000) -#define I2C_FLAG_MSL ((uint32_t)0x00010000) - -/** - * @brief SR1 register flags - */ - -#define I2C_FLAG_SMBALERT ((uint32_t)0x10008000) -#define I2C_FLAG_TIMEOUT ((uint32_t)0x10004000) -#define I2C_FLAG_PECERR ((uint32_t)0x10001000) -#define I2C_FLAG_OVR ((uint32_t)0x10000800) -#define I2C_FLAG_AF ((uint32_t)0x10000400) -#define I2C_FLAG_ARLO ((uint32_t)0x10000200) -#define I2C_FLAG_BERR ((uint32_t)0x10000100) -#define I2C_FLAG_TXE ((uint32_t)0x10000080) -#define I2C_FLAG_RXNE ((uint32_t)0x10000040) -#define I2C_FLAG_STOPF ((uint32_t)0x10000010) -#define I2C_FLAG_ADD10 ((uint32_t)0x10000008) -#define I2C_FLAG_BTF ((uint32_t)0x10000004) -#define I2C_FLAG_ADDR ((uint32_t)0x10000002) -#define I2C_FLAG_SB ((uint32_t)0x10000001) - -#define IS_I2C_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0x20FF) == 0x00) && ((FLAG) != (uint16_t)0x00)) - -#define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_DUALF) || ((FLAG) == I2C_FLAG_SMBHOST) || \ - ((FLAG) == I2C_FLAG_SMBDEFAULT) || ((FLAG) == I2C_FLAG_GENCALL) || \ - ((FLAG) == I2C_FLAG_TRA) || ((FLAG) == I2C_FLAG_BUSY) || \ - ((FLAG) == I2C_FLAG_MSL) || ((FLAG) == I2C_FLAG_SMBALERT) || \ - ((FLAG) == I2C_FLAG_TIMEOUT) || ((FLAG) == I2C_FLAG_PECERR) || \ - ((FLAG) == I2C_FLAG_OVR) || ((FLAG) == I2C_FLAG_AF) || \ - ((FLAG) == I2C_FLAG_ARLO) || ((FLAG) == I2C_FLAG_BERR) || \ - ((FLAG) == I2C_FLAG_TXE) || ((FLAG) == I2C_FLAG_RXNE) || \ - ((FLAG) == I2C_FLAG_STOPF) || ((FLAG) == I2C_FLAG_ADD10) || \ - ((FLAG) == I2C_FLAG_BTF) || ((FLAG) == I2C_FLAG_ADDR) || \ - ((FLAG) == I2C_FLAG_SB)) -/** - * @} - */ - -/** @defgroup I2C_Events - * @{ - */ - -/** - =============================================================================== - I2C Master Events (Events grouped in order of communication) - =============================================================================== - */ - -/** - * @brief Communication start - * - * After sending the START condition (I2C_GenerateSTART() function) the master - * has to wait for this event. It means that the Start condition has been correctly - * released on the I2C bus (the bus is free, no other devices is communicating). - * - */ -/* --EV5 */ -#define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */ - -/** - * @brief Address Acknowledge - * - * After checking on EV5 (start condition correctly released on the bus), the - * master sends the address of the slave(s) with which it will communicate - * (I2C_Send7bitAddress() function, it also determines the direction of the communication: - * Master transmitter or Receiver). Then the master has to wait that a slave acknowledges - * his address. If an acknowledge is sent on the bus, one of the following events will - * be set: - * - * 1) In case of Master Receiver (7-bit addressing): the I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED - * event is set. - * - * 2) In case of Master Transmitter (7-bit addressing): the I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED - * is set - * - * 3) In case of 10-Bit addressing mode, the master (just after generating the START - * and checking on EV5) has to send the header of 10-bit addressing mode (I2C_SendData() - * function). Then master should wait on EV9. It means that the 10-bit addressing - * header has been correctly sent on the bus. Then master should send the second part of - * the 10-bit address (LSB) using the function I2C_Send7bitAddress(). Then master - * should wait for event EV6. - * - */ - -/* --EV6 */ -#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */ -#define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL and ADDR flags */ -/* --EV9 */ -#define I2C_EVENT_MASTER_MODE_ADDRESS10 ((uint32_t)0x00030008) /* BUSY, MSL and ADD10 flags */ - -/** - * @brief Communication events - * - * If a communication is established (START condition generated and slave address - * acknowledged) then the master has to check on one of the following events for - * communication procedures: - * - * 1) Master Receiver mode: The master has to wait on the event EV7 then to read - * the data received from the slave (I2C_ReceiveData() function). - * - * 2) Master Transmitter mode: The master has to send data (I2C_SendData() - * function) then to wait on event EV8 or EV8_2. - * These two events are similar: - * - EV8 means that the data has been written in the data register and is - * being shifted out. - * - EV8_2 means that the data has been physically shifted out and output - * on the bus. - * In most cases, using EV8 is sufficient for the application. - * Using EV8_2 leads to a slower communication but ensure more reliable test. - * EV8_2 is also more suitable than EV8 for testing on the last data transmission - * (before Stop condition generation). - * - * @note In case the user software does not guarantee that this event EV7 is - * managed before the current byte end of transfer, then user may check on EV7 - * and BTF flag at the same time (ie. (I2C_EVENT_MASTER_BYTE_RECEIVED | I2C_FLAG_BTF)). - * In this case the communication may be slower. - * - */ - -/* Master RECEIVER mode -----------------------------*/ -/* --EV7 */ -#define I2C_EVENT_MASTER_BYTE_RECEIVED ((uint32_t)0x00030040) /* BUSY, MSL and RXNE flags */ - -/* Master TRANSMITTER mode --------------------------*/ -/* --EV8 */ -#define I2C_EVENT_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */ -/* --EV8_2 */ -#define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags */ - - -/** - =============================================================================== - I2C Slave Events (Events grouped in order of communication) - =============================================================================== - */ - - -/** - * @brief Communication start events - * - * Wait on one of these events at the start of the communication. It means that - * the I2C peripheral detected a Start condition on the bus (generated by master - * device) followed by the peripheral address. The peripheral generates an ACK - * condition on the bus (if the acknowledge feature is enabled through function - * I2C_AcknowledgeConfig()) and the events listed above are set : - * - * 1) In normal case (only one address managed by the slave), when the address - * sent by the master matches the own address of the peripheral (configured by - * I2C_OwnAddress1 field) the I2C_EVENT_SLAVE_XXX_ADDRESS_MATCHED event is set - * (where XXX could be TRANSMITTER or RECEIVER). - * - * 2) In case the address sent by the master matches the second address of the - * peripheral (configured by the function I2C_OwnAddress2Config() and enabled - * by the function I2C_DualAddressCmd()) the events I2C_EVENT_SLAVE_XXX_SECONDADDRESS_MATCHED - * (where XXX could be TRANSMITTER or RECEIVER) are set. - * - * 3) In case the address sent by the master is General Call (address 0x00) and - * if the General Call is enabled for the peripheral (using function I2C_GeneralCallCmd()) - * the following event is set I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED. - * - */ - -/* --EV1 (all the events below are variants of EV1) */ -/* 1) Case of One Single Address managed by the slave */ -#define I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ((uint32_t)0x00020002) /* BUSY and ADDR flags */ -#define I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED ((uint32_t)0x00060082) /* TRA, BUSY, TXE and ADDR flags */ - -/* 2) Case of Dual address managed by the slave */ -#define I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED ((uint32_t)0x00820000) /* DUALF and BUSY flags */ -#define I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED ((uint32_t)0x00860080) /* DUALF, TRA, BUSY and TXE flags */ - -/* 3) Case of General Call enabled for the slave */ -#define I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED ((uint32_t)0x00120000) /* GENCALL and BUSY flags */ - -/** - * @brief Communication events - * - * Wait on one of these events when EV1 has already been checked and: - * - * - Slave RECEIVER mode: - * - EV2: When the application is expecting a data byte to be received. - * - EV4: When the application is expecting the end of the communication: master - * sends a stop condition and data transmission is stopped. - * - * - Slave Transmitter mode: - * - EV3: When a byte has been transmitted by the slave and the application is expecting - * the end of the byte transmission. The two events I2C_EVENT_SLAVE_BYTE_TRANSMITTED and - * I2C_EVENT_SLAVE_BYTE_TRANSMITTING are similar. The second one can optionally be - * used when the user software doesn't guarantee the EV3 is managed before the - * current byte end of transfer. - * - EV3_2: When the master sends a NACK in order to tell slave that data transmission - * shall end (before sending the STOP condition). In this case slave has to stop sending - * data bytes and expect a Stop condition on the bus. - * - * @note In case the user software does not guarantee that the event EV2 is - * managed before the current byte end of transfer, then user may check on EV2 - * and BTF flag at the same time (ie. (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_BTF)). - * In this case the communication may be slower. - * - */ - -/* Slave RECEIVER mode --------------------------*/ -/* --EV2 */ -#define I2C_EVENT_SLAVE_BYTE_RECEIVED ((uint32_t)0x00020040) /* BUSY and RXNE flags */ -/* --EV4 */ -#define I2C_EVENT_SLAVE_STOP_DETECTED ((uint32_t)0x00000010) /* STOPF flag */ - -/* Slave TRANSMITTER mode -----------------------*/ -/* --EV3 */ -#define I2C_EVENT_SLAVE_BYTE_TRANSMITTED ((uint32_t)0x00060084) /* TRA, BUSY, TXE and BTF flags */ -#define I2C_EVENT_SLAVE_BYTE_TRANSMITTING ((uint32_t)0x00060080) /* TRA, BUSY and TXE flags */ -/* --EV3_2 */ -#define I2C_EVENT_SLAVE_ACK_FAILURE ((uint32_t)0x00000400) /* AF flag */ - -/** - =============================================================================== - End of Events Description - =============================================================================== - */ - -#define IS_I2C_EVENT(EVENT) (((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_BYTE_RECEIVED) || \ - ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF)) || \ - ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL)) || \ - ((EVENT) == I2C_EVENT_SLAVE_BYTE_TRANSMITTED) || \ - ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF)) || \ - ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL)) || \ - ((EVENT) == I2C_EVENT_SLAVE_STOP_DETECTED) || \ - ((EVENT) == I2C_EVENT_MASTER_MODE_SELECT) || \ - ((EVENT) == I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) || \ - ((EVENT) == I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) || \ - ((EVENT) == I2C_EVENT_MASTER_BYTE_RECEIVED) || \ - ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTED) || \ - ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTING) || \ - ((EVENT) == I2C_EVENT_MASTER_MODE_ADDRESS10) || \ - ((EVENT) == I2C_EVENT_SLAVE_ACK_FAILURE)) -/** - * @} - */ - -/** @defgroup I2C_own_address1 - * @{ - */ - -#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x3FF) -/** - * @} - */ - -/** @defgroup I2C_clock_speed - * @{ - */ - -#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) >= 0x1) && ((SPEED) <= 400000)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* Function used to set the I2C configuration to the default reset state *****/ -void I2C_DeInit(I2C_TypeDef* I2Cx); - -/* Initialization and Configuration functions *********************************/ -void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct); -void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct); -void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address); -void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert); -void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle); -void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction); - -/* Data transfers functions ***************************************************/ -void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data); -uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx); - -/* PEC management functions ***************************************************/ -void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition); -void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState); -uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx); - -/* DMA transfers management functions *****************************************/ -void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); - - -/* Interrupts, events and flags management functions **************************/ -uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register); -void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState); - -/** - * @brief - * -@verbatim - =============================================================================== - I2C State Monitoring Functions - =============================================================================== - This I2C driver provides three different ways for I2C state monitoring - depending on the application requirements and constraints: - - - 1. Basic state monitoring (Using I2C_CheckEvent() function) - ----------------------------------------------------------- - It compares the status registers (SR1 and SR2) content to a given event - (can be the combination of one or more flags). - It returns SUCCESS if the current status includes the given flags - and returns ERROR if one or more flags are missing in the current status. - - - When to use - - This function is suitable for most applications as well as for startup - activity since the events are fully described in the product reference - manual (RM0038). - - It is also suitable for users who need to define their own events. - - - Limitations - - If an error occurs (ie. error flags are set besides to the monitored - flags), the I2C_CheckEvent() function may return SUCCESS despite - the communication hold or corrupted real state. - In this case, it is advised to use error interrupts to monitor - the error events and handle them in the interrupt IRQ handler. - - @note - For error management, it is advised to use the following functions: - - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR). - - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs. - Where x is the peripheral instance (I2C1, I2C2 ...) - - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into the - I2Cx_ER_IRQHandler() function in order to determine which error occurred. - - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd() - and/or I2C_GenerateStop() in order to clear the error flag and source - and return to correct communciation status. - - - 2. Advanced state monitoring (Using the function I2C_GetLastEvent()) - -------------------------------------------------------------------- - Using the function I2C_GetLastEvent() which returns the image of both status - registers in a single word (uint32_t) (Status Register 2 value is shifted left - by 16 bits and concatenated to Status Register 1). - - - When to use - - This function is suitable for the same applications above but it - allows to overcome the mentioned limitation of I2C_GetFlagStatus() - function. - - The returned value could be compared to events already defined in - the library (stm32l1xx_i2c.h) or to custom values defined by user. - This function is suitable when multiple flags are monitored at the - same time. - - At the opposite of I2C_CheckEvent() function, this function allows - user to choose when an event is accepted (when all events flags are - set and no other flags are set or just when the needed flags are set - like I2C_CheckEvent() function. - - - Limitations - - User may need to define his own events. - - Same remark concerning the error management is applicable for this - function if user decides to check only regular communication flags - (and ignores error flags). - - - 3. Flag-based state monitoring (Using the function I2C_GetFlagStatus()) - ----------------------------------------------------------------------- - - Using the function I2C_GetFlagStatus() which simply returns the status of - one single flag (ie. I2C_FLAG_RXNE ...). - - - When to use - - This function could be used for specific applications or in debug - phase. - - It is suitable when only one flag checking is needed (most I2C - events are monitored through multiple flags). - - Limitations: - - When calling this function, the Status register is accessed. - Some flags are cleared when the status register is accessed. - So checking the status of one Flag, may clear other ones. - - Function may need to be called twice or more in order to monitor - one single event. - - For detailed description of Events, please refer to section I2C_Events in - stm32l1xx_i2c.h file. - -@endverbatim - * - */ - -/** - =============================================================================== - 1. Basic state monitoring - =============================================================================== - */ -ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT); -/** - =============================================================================== - 2. Advanced state monitoring - =============================================================================== - */ -uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx); -/** - =============================================================================== - 3. Flag-based state monitoring - =============================================================================== - */ -FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); - - -void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); -ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT); -void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32L1xx_I2C_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_iwdg.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_iwdg.h deleted file mode 100644 index 00b768e3f..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_iwdg.h +++ /dev/null @@ -1,128 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_iwdg.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the IWDG - * firmware library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_IWDG_H -#define __STM32L1xx_IWDG_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup IWDG - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup IWDG_Exported_Constants - * @{ - */ - -/** @defgroup IWDG_WriteAccess - * @{ - */ - -#define IWDG_WriteAccess_Enable ((uint16_t)0x5555) -#define IWDG_WriteAccess_Disable ((uint16_t)0x0000) -#define IS_IWDG_WRITE_ACCESS(ACCESS) (((ACCESS) == IWDG_WriteAccess_Enable) || \ - ((ACCESS) == IWDG_WriteAccess_Disable)) -/** - * @} - */ - -/** @defgroup IWDG_prescaler - * @{ - */ - -#define IWDG_Prescaler_4 ((uint8_t)0x00) -#define IWDG_Prescaler_8 ((uint8_t)0x01) -#define IWDG_Prescaler_16 ((uint8_t)0x02) -#define IWDG_Prescaler_32 ((uint8_t)0x03) -#define IWDG_Prescaler_64 ((uint8_t)0x04) -#define IWDG_Prescaler_128 ((uint8_t)0x05) -#define IWDG_Prescaler_256 ((uint8_t)0x06) -#define IS_IWDG_PRESCALER(PRESCALER) (((PRESCALER) == IWDG_Prescaler_4) || \ - ((PRESCALER) == IWDG_Prescaler_8) || \ - ((PRESCALER) == IWDG_Prescaler_16) || \ - ((PRESCALER) == IWDG_Prescaler_32) || \ - ((PRESCALER) == IWDG_Prescaler_64) || \ - ((PRESCALER) == IWDG_Prescaler_128)|| \ - ((PRESCALER) == IWDG_Prescaler_256)) -/** - * @} - */ - -/** @defgroup IWDG_Flag - * @{ - */ - -#define IWDG_FLAG_PVU ((uint16_t)0x0001) -#define IWDG_FLAG_RVU ((uint16_t)0x0002) -#define IS_IWDG_FLAG(FLAG) (((FLAG) == IWDG_FLAG_PVU) || ((FLAG) == IWDG_FLAG_RVU)) -#define IS_IWDG_RELOAD(RELOAD) ((RELOAD) <= 0xFFF) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* Prescaler and Counter configuration functions ******************************/ -void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess); -void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); -void IWDG_SetReload(uint16_t Reload); -void IWDG_ReloadCounter(void); - -/* IWDG activation function ***************************************************/ -void IWDG_Enable(void); - -/* Flag management function ***************************************************/ -FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32L1xx_IWDG_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_lcd.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_lcd.h deleted file mode 100644 index 4944c8361..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_lcd.h +++ /dev/null @@ -1,446 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_lcd.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the LCD firmware - * library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_LCD_H -#define __STM32L1xx_LCD_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup LCD - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief LCD Init structure definition - */ - -typedef struct -{ - uint32_t LCD_Prescaler; /*!< Configures the LCD Prescaler. - This parameter can be one value of @ref LCD_Prescaler */ - uint32_t LCD_Divider; /*!< Configures the LCD Divider. - This parameter can be one value of @ref LCD_Divider */ - uint32_t LCD_Duty; /*!< Configures the LCD Duty. - This parameter can be one value of @ref LCD_Duty */ - uint32_t LCD_Bias; /*!< Configures the LCD Bias. - This parameter can be one value of @ref LCD_Bias */ - uint32_t LCD_VoltageSource; /*!< Selects the LCD Voltage source. - This parameter can be one value of @ref LCD_Voltage_Source */ -}LCD_InitTypeDef; - - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup LCD_Exported_Constants - * @{ - */ - -/** @defgroup LCD_Prescaler - * @{ - */ - -#define LCD_Prescaler_1 ((uint32_t)0x00000000) /*!< CLKPS = LCDCLK */ -#define LCD_Prescaler_2 ((uint32_t)0x00400000) /*!< CLKPS = LCDCLK/2 */ -#define LCD_Prescaler_4 ((uint32_t)0x00800000) /*!< CLKPS = LCDCLK/4 */ -#define LCD_Prescaler_8 ((uint32_t)0x00C00000) /*!< CLKPS = LCDCLK/8 */ -#define LCD_Prescaler_16 ((uint32_t)0x01000000) /*!< CLKPS = LCDCLK/16 */ -#define LCD_Prescaler_32 ((uint32_t)0x01400000) /*!< CLKPS = LCDCLK/32 */ -#define LCD_Prescaler_64 ((uint32_t)0x01800000) /*!< CLKPS = LCDCLK/64 */ -#define LCD_Prescaler_128 ((uint32_t)0x01C00000) /*!< CLKPS = LCDCLK/128 */ -#define LCD_Prescaler_256 ((uint32_t)0x02000000) /*!< CLKPS = LCDCLK/256 */ -#define LCD_Prescaler_512 ((uint32_t)0x02400000) /*!< CLKPS = LCDCLK/512 */ -#define LCD_Prescaler_1024 ((uint32_t)0x02800000) /*!< CLKPS = LCDCLK/1024 */ -#define LCD_Prescaler_2048 ((uint32_t)0x02C00000) /*!< CLKPS = LCDCLK/2048 */ -#define LCD_Prescaler_4096 ((uint32_t)0x03000000) /*!< CLKPS = LCDCLK/4096 */ -#define LCD_Prescaler_8192 ((uint32_t)0x03400000) /*!< CLKPS = LCDCLK/8192 */ -#define LCD_Prescaler_16384 ((uint32_t)0x03800000) /*!< CLKPS = LCDCLK/16384 */ -#define LCD_Prescaler_32768 ((uint32_t)0x03C00000) /*!< CLKPS = LCDCLK/32768 */ - -#define IS_LCD_PRESCALER(PRESCALER) (((PRESCALER) == LCD_Prescaler_1) || \ - ((PRESCALER) == LCD_Prescaler_2) || \ - ((PRESCALER) == LCD_Prescaler_4) || \ - ((PRESCALER) == LCD_Prescaler_8) || \ - ((PRESCALER) == LCD_Prescaler_16) || \ - ((PRESCALER) == LCD_Prescaler_32) || \ - ((PRESCALER) == LCD_Prescaler_64) || \ - ((PRESCALER) == LCD_Prescaler_128) || \ - ((PRESCALER) == LCD_Prescaler_256) || \ - ((PRESCALER) == LCD_Prescaler_512) || \ - ((PRESCALER) == LCD_Prescaler_1024) || \ - ((PRESCALER) == LCD_Prescaler_2048) || \ - ((PRESCALER) == LCD_Prescaler_4096) || \ - ((PRESCALER) == LCD_Prescaler_8192) || \ - ((PRESCALER) == LCD_Prescaler_16384) || \ - ((PRESCALER) == LCD_Prescaler_32768)) - -/** - * @} - */ - -/** @defgroup LCD_Divider - * @{ - */ - -#define LCD_Divider_16 ((uint32_t)0x00000000) /*!< LCD frequency = CLKPS/16 */ -#define LCD_Divider_17 ((uint32_t)0x00040000) /*!< LCD frequency = CLKPS/17 */ -#define LCD_Divider_18 ((uint32_t)0x00080000) /*!< LCD frequency = CLKPS/18 */ -#define LCD_Divider_19 ((uint32_t)0x000C0000) /*!< LCD frequency = CLKPS/19 */ -#define LCD_Divider_20 ((uint32_t)0x00100000) /*!< LCD frequency = CLKPS/20 */ -#define LCD_Divider_21 ((uint32_t)0x00140000) /*!< LCD frequency = CLKPS/21 */ -#define LCD_Divider_22 ((uint32_t)0x00180000) /*!< LCD frequency = CLKPS/22 */ -#define LCD_Divider_23 ((uint32_t)0x001C0000) /*!< LCD frequency = CLKPS/23 */ -#define LCD_Divider_24 ((uint32_t)0x00200000) /*!< LCD frequency = CLKPS/24 */ -#define LCD_Divider_25 ((uint32_t)0x00240000) /*!< LCD frequency = CLKPS/25 */ -#define LCD_Divider_26 ((uint32_t)0x00280000) /*!< LCD frequency = CLKPS/26 */ -#define LCD_Divider_27 ((uint32_t)0x002C0000) /*!< LCD frequency = CLKPS/27 */ -#define LCD_Divider_28 ((uint32_t)0x00300000) /*!< LCD frequency = CLKPS/28 */ -#define LCD_Divider_29 ((uint32_t)0x00340000) /*!< LCD frequency = CLKPS/29 */ -#define LCD_Divider_30 ((uint32_t)0x00380000) /*!< LCD frequency = CLKPS/30 */ -#define LCD_Divider_31 ((uint32_t)0x003C0000) /*!< LCD frequency = CLKPS/31 */ - -#define IS_LCD_DIVIDER(DIVIDER) (((DIVIDER) == LCD_Divider_16) || \ - ((DIVIDER) == LCD_Divider_17) || \ - ((DIVIDER) == LCD_Divider_18) || \ - ((DIVIDER) == LCD_Divider_19) || \ - ((DIVIDER) == LCD_Divider_20) || \ - ((DIVIDER) == LCD_Divider_21) || \ - ((DIVIDER) == LCD_Divider_22) || \ - ((DIVIDER) == LCD_Divider_23) || \ - ((DIVIDER) == LCD_Divider_24) || \ - ((DIVIDER) == LCD_Divider_25) || \ - ((DIVIDER) == LCD_Divider_26) || \ - ((DIVIDER) == LCD_Divider_27) || \ - ((DIVIDER) == LCD_Divider_28) || \ - ((DIVIDER) == LCD_Divider_29) || \ - ((DIVIDER) == LCD_Divider_30) || \ - ((DIVIDER) == LCD_Divider_31)) - -/** - * @} - */ - - -/** @defgroup LCD_Duty - * @{ - */ - -#define LCD_Duty_Static ((uint32_t)0x00000000) /*!< Static duty */ -#define LCD_Duty_1_2 ((uint32_t)0x00000004) /*!< 1/2 duty */ -#define LCD_Duty_1_3 ((uint32_t)0x00000008) /*!< 1/3 duty */ -#define LCD_Duty_1_4 ((uint32_t)0x0000000C) /*!< 1/4 duty */ -#define LCD_Duty_1_8 ((uint32_t)0x00000010) /*!< 1/4 duty */ - -#define IS_LCD_DUTY(DUTY) (((DUTY) == LCD_Duty_Static) || \ - ((DUTY) == LCD_Duty_1_2) || \ - ((DUTY) == LCD_Duty_1_3) || \ - ((DUTY) == LCD_Duty_1_4) || \ - ((DUTY) == LCD_Duty_1_8)) - -/** - * @} - */ - - -/** @defgroup LCD_Bias - * @{ - */ - -#define LCD_Bias_1_4 ((uint32_t)0x00000000) /*!< 1/4 Bias */ -#define LCD_Bias_1_2 LCD_CR_BIAS_0 /*!< 1/2 Bias */ -#define LCD_Bias_1_3 LCD_CR_BIAS_1 /*!< 1/3 Bias */ - -#define IS_LCD_BIAS(BIAS) (((BIAS) == LCD_Bias_1_4) || \ - ((BIAS) == LCD_Bias_1_2) || \ - ((BIAS) == LCD_Bias_1_3)) -/** - * @} - */ - -/** @defgroup LCD_Voltage_Source - * @{ - */ - -#define LCD_VoltageSource_Internal ((uint32_t)0x00000000) /*!< Internal voltage source for the LCD */ -#define LCD_VoltageSource_External LCD_CR_VSEL /*!< External voltage source for the LCD */ - -#define IS_LCD_VOLTAGE_SOURCE(SOURCE) (((SOURCE) == LCD_VoltageSource_Internal) || \ - ((SOURCE) == LCD_VoltageSource_External)) - -/** - * @} - */ - -/** @defgroup LCD_Interrupts - * @{ - */ -#define LCD_IT_SOF LCD_FCR_SOFIE -#define LCD_IT_UDD LCD_FCR_UDDIE - -#define IS_LCD_IT(IT) ((((IT) & (uint32_t)0xFFFFFFF5) == 0x00) && ((IT) != 0x00)) - -#define IS_LCD_GET_IT(IT) (((IT) == LCD_IT_SOF) || ((IT) == LCD_IT_UDD)) - -/** - * @} - */ - -/** @defgroup LCD_PulseOnDuration - * @{ - */ - -#define LCD_PulseOnDuration_0 ((uint32_t)0x00000000) /*!< Pulse ON duration = 0 pulse */ -#define LCD_PulseOnDuration_1 ((uint32_t)0x00000010) /*!< Pulse ON duration = 1/CK_PS */ -#define LCD_PulseOnDuration_2 ((uint32_t)0x00000020) /*!< Pulse ON duration = 2/CK_PS */ -#define LCD_PulseOnDuration_3 ((uint32_t)0x00000030) /*!< Pulse ON duration = 3/CK_PS */ -#define LCD_PulseOnDuration_4 ((uint32_t)0x00000040) /*!< Pulse ON duration = 4/CK_PS */ -#define LCD_PulseOnDuration_5 ((uint32_t)0x00000050) /*!< Pulse ON duration = 5/CK_PS */ -#define LCD_PulseOnDuration_6 ((uint32_t)0x00000060) /*!< Pulse ON duration = 6/CK_PS */ -#define LCD_PulseOnDuration_7 ((uint32_t)0x00000070) /*!< Pulse ON duration = 7/CK_PS */ - -#define IS_LCD_PULSE_ON_DURATION(DURATION) (((DURATION) == LCD_PulseOnDuration_0) || \ - ((DURATION) == LCD_PulseOnDuration_1) || \ - ((DURATION) == LCD_PulseOnDuration_2) || \ - ((DURATION) == LCD_PulseOnDuration_3) || \ - ((DURATION) == LCD_PulseOnDuration_4) || \ - ((DURATION) == LCD_PulseOnDuration_5) || \ - ((DURATION) == LCD_PulseOnDuration_6) || \ - ((DURATION) == LCD_PulseOnDuration_7)) -/** - * @} - */ - - -/** @defgroup LCD_DeadTime - * @{ - */ - -#define LCD_DeadTime_0 ((uint32_t)0x00000000) /*!< No dead Time */ -#define LCD_DeadTime_1 ((uint32_t)0x00000080) /*!< One Phase between different couple of Frame */ -#define LCD_DeadTime_2 ((uint32_t)0x00000100) /*!< Two Phase between different couple of Frame */ -#define LCD_DeadTime_3 ((uint32_t)0x00000180) /*!< Three Phase between different couple of Frame */ -#define LCD_DeadTime_4 ((uint32_t)0x00000200) /*!< Four Phase between different couple of Frame */ -#define LCD_DeadTime_5 ((uint32_t)0x00000280) /*!< Five Phase between different couple of Frame */ -#define LCD_DeadTime_6 ((uint32_t)0x00000300) /*!< Six Phase between different couple of Frame */ -#define LCD_DeadTime_7 ((uint32_t)0x00000380) /*!< Seven Phase between different couple of Frame */ - -#define IS_LCD_DEAD_TIME(TIME) (((TIME) == LCD_DeadTime_0) || \ - ((TIME) == LCD_DeadTime_1) || \ - ((TIME) == LCD_DeadTime_2) || \ - ((TIME) == LCD_DeadTime_3) || \ - ((TIME) == LCD_DeadTime_4) || \ - ((TIME) == LCD_DeadTime_5) || \ - ((TIME) == LCD_DeadTime_6) || \ - ((TIME) == LCD_DeadTime_7)) -/** - * @} - */ - -/** @defgroup LCD_BlinkMode - * @{ - */ - -#define LCD_BlinkMode_Off ((uint32_t)0x00000000) /*!< Blink disabled */ -#define LCD_BlinkMode_SEG0_COM0 ((uint32_t)0x00010000) /*!< Blink enabled on SEG[0], COM[0] (1 pixel) */ -#define LCD_BlinkMode_SEG0_AllCOM ((uint32_t)0x00020000) /*!< Blink enabled on SEG[0], all COM (up to - 8 pixels according to the programmed duty) */ -#define LCD_BlinkMode_AllSEG_AllCOM ((uint32_t)0x00030000) /*!< Blink enabled on all SEG and all COM (all pixels) */ - -#define IS_LCD_BLINK_MODE(MODE) (((MODE) == LCD_BlinkMode_Off) || \ - ((MODE) == LCD_BlinkMode_SEG0_COM0) || \ - ((MODE) == LCD_BlinkMode_SEG0_AllCOM) || \ - ((MODE) == LCD_BlinkMode_AllSEG_AllCOM)) -/** - * @} - */ - -/** @defgroup LCD_BlinkFrequency - * @{ - */ - -#define LCD_BlinkFrequency_Div8 ((uint32_t)0x00000000) /*!< The Blink frequency = fLCD/8 */ -#define LCD_BlinkFrequency_Div16 ((uint32_t)0x00002000) /*!< The Blink frequency = fLCD/16 */ -#define LCD_BlinkFrequency_Div32 ((uint32_t)0x00004000) /*!< The Blink frequency = fLCD/32 */ -#define LCD_BlinkFrequency_Div64 ((uint32_t)0x00006000) /*!< The Blink frequency = fLCD/64 */ -#define LCD_BlinkFrequency_Div128 ((uint32_t)0x00008000) /*!< The Blink frequency = fLCD/128 */ -#define LCD_BlinkFrequency_Div256 ((uint32_t)0x0000A000) /*!< The Blink frequency = fLCD/256 */ -#define LCD_BlinkFrequency_Div512 ((uint32_t)0x0000C000) /*!< The Blink frequency = fLCD/512 */ -#define LCD_BlinkFrequency_Div1024 ((uint32_t)0x0000E000) /*!< The Blink frequency = fLCD/1024 */ - -#define IS_LCD_BLINK_FREQUENCY(FREQUENCY) (((FREQUENCY) == LCD_BlinkFrequency_Div8) || \ - ((FREQUENCY) == LCD_BlinkFrequency_Div16) || \ - ((FREQUENCY) == LCD_BlinkFrequency_Div32) || \ - ((FREQUENCY) == LCD_BlinkFrequency_Div64) || \ - ((FREQUENCY) == LCD_BlinkFrequency_Div128) || \ - ((FREQUENCY) == LCD_BlinkFrequency_Div256) || \ - ((FREQUENCY) == LCD_BlinkFrequency_Div512) || \ - ((FREQUENCY) == LCD_BlinkFrequency_Div1024)) -/** - * @} - */ - -/** @defgroup LCD_Contrast - * @{ - */ - -#define LCD_Contrast_Level_0 ((uint32_t)0x00000000) /*!< Maximum Voltage = 2.60V */ -#define LCD_Contrast_Level_1 ((uint32_t)0x00000400) /*!< Maximum Voltage = 2.73V */ -#define LCD_Contrast_Level_2 ((uint32_t)0x00000800) /*!< Maximum Voltage = 2.86V */ -#define LCD_Contrast_Level_3 ((uint32_t)0x00000C00) /*!< Maximum Voltage = 2.99V */ -#define LCD_Contrast_Level_4 ((uint32_t)0x00001000) /*!< Maximum Voltage = 3.12V */ -#define LCD_Contrast_Level_5 ((uint32_t)0x00001400) /*!< Maximum Voltage = 3.25V */ -#define LCD_Contrast_Level_6 ((uint32_t)0x00001800) /*!< Maximum Voltage = 3.38V */ -#define LCD_Contrast_Level_7 ((uint32_t)0x00001C00) /*!< Maximum Voltage = 3.51V */ - -#define IS_LCD_CONTRAST(CONTRAST) (((CONTRAST) == LCD_Contrast_Level_0) || \ - ((CONTRAST) == LCD_Contrast_Level_1) || \ - ((CONTRAST) == LCD_Contrast_Level_2) || \ - ((CONTRAST) == LCD_Contrast_Level_3) || \ - ((CONTRAST) == LCD_Contrast_Level_4) || \ - ((CONTRAST) == LCD_Contrast_Level_5) || \ - ((CONTRAST) == LCD_Contrast_Level_6) || \ - ((CONTRAST) == LCD_Contrast_Level_7)) -/** - * @} - */ - -/** @defgroup LCD_Flag - * @{ - */ - -#define LCD_FLAG_ENS LCD_SR_ENS -#define LCD_FLAG_SOF LCD_SR_SOF -#define LCD_FLAG_UDR LCD_SR_UDR -#define LCD_FLAG_UDD LCD_SR_UDD -#define LCD_FLAG_RDY LCD_SR_RDY -#define LCD_FLAG_FCRSF LCD_SR_FCRSR - -#define IS_LCD_GET_FLAG(FLAG) (((FLAG) == LCD_FLAG_ENS) || ((FLAG) == LCD_FLAG_SOF) || \ - ((FLAG) == LCD_FLAG_UDR) || ((FLAG) == LCD_FLAG_UDD) || \ - ((FLAG) == LCD_FLAG_RDY) || ((FLAG) == LCD_FLAG_FCRSF)) - -#define IS_LCD_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFF5) == 0x00) && ((FLAG) != 0x00)) -/** - * @} - */ - -/** @defgroup LCD_RAMRegister - * @{ - */ - -#define LCD_RAMRegister_0 ((uint32_t)0x00000000) /*!< LCD RAM Register 0 */ -#define LCD_RAMRegister_1 ((uint32_t)0x00000001) /*!< LCD RAM Register 1 */ -#define LCD_RAMRegister_2 ((uint32_t)0x00000002) /*!< LCD RAM Register 2 */ -#define LCD_RAMRegister_3 ((uint32_t)0x00000003) /*!< LCD RAM Register 3 */ -#define LCD_RAMRegister_4 ((uint32_t)0x00000004) /*!< LCD RAM Register 4 */ -#define LCD_RAMRegister_5 ((uint32_t)0x00000005) /*!< LCD RAM Register 5 */ -#define LCD_RAMRegister_6 ((uint32_t)0x00000006) /*!< LCD RAM Register 6 */ -#define LCD_RAMRegister_7 ((uint32_t)0x00000007) /*!< LCD RAM Register 7 */ -#define LCD_RAMRegister_8 ((uint32_t)0x00000008) /*!< LCD RAM Register 8 */ -#define LCD_RAMRegister_9 ((uint32_t)0x00000009) /*!< LCD RAM Register 9 */ -#define LCD_RAMRegister_10 ((uint32_t)0x0000000A) /*!< LCD RAM Register 10 */ -#define LCD_RAMRegister_11 ((uint32_t)0x0000000B) /*!< LCD RAM Register 11 */ -#define LCD_RAMRegister_12 ((uint32_t)0x0000000C) /*!< LCD RAM Register 12 */ -#define LCD_RAMRegister_13 ((uint32_t)0x0000000D) /*!< LCD RAM Register 13 */ -#define LCD_RAMRegister_14 ((uint32_t)0x0000000E) /*!< LCD RAM Register 14 */ -#define LCD_RAMRegister_15 ((uint32_t)0x0000000F) /*!< LCD RAM Register 15 */ - -#define IS_LCD_RAM_REGISTER(REGISTER) (((REGISTER) == LCD_RAMRegister_0) || \ - ((REGISTER) == LCD_RAMRegister_1) || \ - ((REGISTER) == LCD_RAMRegister_2) || \ - ((REGISTER) == LCD_RAMRegister_3) || \ - ((REGISTER) == LCD_RAMRegister_4) || \ - ((REGISTER) == LCD_RAMRegister_5) || \ - ((REGISTER) == LCD_RAMRegister_6) || \ - ((REGISTER) == LCD_RAMRegister_7) || \ - ((REGISTER) == LCD_RAMRegister_8) || \ - ((REGISTER) == LCD_RAMRegister_9) || \ - ((REGISTER) == LCD_RAMRegister_10) || \ - ((REGISTER) == LCD_RAMRegister_11) || \ - ((REGISTER) == LCD_RAMRegister_12) || \ - ((REGISTER) == LCD_RAMRegister_13) || \ - ((REGISTER) == LCD_RAMRegister_14) || \ - ((REGISTER) == LCD_RAMRegister_15)) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* Function used to set the LCD configuration to the default reset state *****/ -void LCD_DeInit(void); - -/* Initialization and Configuration functions *********************************/ -void LCD_Init(LCD_InitTypeDef* LCD_InitStruct); -void LCD_StructInit(LCD_InitTypeDef* LCD_InitStruct); -void LCD_Cmd(FunctionalState NewState); -void LCD_WaitForSynchro(void); -void LCD_HighDriveCmd(FunctionalState NewState); -void LCD_MuxSegmentCmd(FunctionalState NewState); -void LCD_PulseOnDurationConfig(uint32_t LCD_PulseOnDuration); -void LCD_DeadTimeConfig(uint32_t LCD_DeadTime); -void LCD_BlinkConfig(uint32_t LCD_BlinkMode, uint32_t LCD_BlinkFrequency); -void LCD_ContrastConfig(uint32_t LCD_Contrast); - -/* LCD RAM memory write functions *********************************************/ -void LCD_Write(uint32_t LCD_RAMRegister, uint32_t LCD_Data); -void LCD_UpdateDisplayRequest(void); - -/* Interrupts and flags management functions **********************************/ -void LCD_ITConfig(uint32_t LCD_IT, FunctionalState NewState); -FlagStatus LCD_GetFlagStatus(uint32_t LCD_FLAG); -void LCD_ClearFlag(uint32_t LCD_FLAG); -ITStatus LCD_GetITStatus(uint32_t LCD_IT); -void LCD_ClearITPendingBit(uint32_t LCD_IT); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32L1xx_LCD_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_pwr.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_pwr.h deleted file mode 100644 index ae2adb74a..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_pwr.h +++ /dev/null @@ -1,207 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_pwr.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the PWR firmware - * library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_PWR_H -#define __STM32L1xx_PWR_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup PWR - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup PWR_Exported_Constants - * @{ - */ - -/** @defgroup PVD_detection_level - * @{ - */ - -#define PWR_PVDLevel_0 PWR_CR_PLS_LEV0 -#define PWR_PVDLevel_1 PWR_CR_PLS_LEV1 -#define PWR_PVDLevel_2 PWR_CR_PLS_LEV2 -#define PWR_PVDLevel_3 PWR_CR_PLS_LEV3 -#define PWR_PVDLevel_4 PWR_CR_PLS_LEV4 -#define PWR_PVDLevel_5 PWR_CR_PLS_LEV5 -#define PWR_PVDLevel_6 PWR_CR_PLS_LEV6 -#define PWR_PVDLevel_7 PWR_CR_PLS_LEV7 /* External input analog voltage - (Compare internally to VREFINT) */ -#define IS_PWR_PVD_LEVEL(LEVEL) (((LEVEL) == PWR_PVDLevel_0) || ((LEVEL) == PWR_PVDLevel_1)|| \ - ((LEVEL) == PWR_PVDLevel_2) || ((LEVEL) == PWR_PVDLevel_3)|| \ - ((LEVEL) == PWR_PVDLevel_4) || ((LEVEL) == PWR_PVDLevel_5)|| \ - ((LEVEL) == PWR_PVDLevel_6) || ((LEVEL) == PWR_PVDLevel_7)) -/** - * @} - */ - -/** @defgroup WakeUp_Pins - * @{ - */ - -#define PWR_WakeUpPin_1 ((uint32_t)0x00000000) -#define PWR_WakeUpPin_2 ((uint32_t)0x00000004) -#define PWR_WakeUpPin_3 ((uint32_t)0x00000008) -#define IS_PWR_WAKEUP_PIN(PIN) (((PIN) == PWR_WakeUpPin_1) || \ - ((PIN) == PWR_WakeUpPin_2) || \ - ((PIN) == PWR_WakeUpPin_3)) -/** - * @} - */ - - -/** @defgroup Voltage_Scaling_Ranges - * @{ - */ - -#define PWR_VoltageScaling_Range1 PWR_CR_VOS_0 -#define PWR_VoltageScaling_Range2 PWR_CR_VOS_1 -#define PWR_VoltageScaling_Range3 PWR_CR_VOS - -#define IS_PWR_VOLTAGE_SCALING_RANGE(RANGE) (((RANGE) == PWR_VoltageScaling_Range1) || \ - ((RANGE) == PWR_VoltageScaling_Range2) || \ - ((RANGE) == PWR_VoltageScaling_Range3)) -/** - * @} - */ - -/** @defgroup Regulator_state_is_Sleep_STOP_mode - * @{ - */ - -#define PWR_Regulator_ON ((uint32_t)0x00000000) -#define PWR_Regulator_LowPower PWR_CR_LPSDSR -#define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_Regulator_ON) || \ - ((REGULATOR) == PWR_Regulator_LowPower)) -/** - * @} - */ - -/** @defgroup SLEEP_mode_entry - * @{ - */ - -#define PWR_SLEEPEntry_WFI ((uint8_t)0x01) -#define PWR_SLEEPEntry_WFE ((uint8_t)0x02) -#define IS_PWR_SLEEP_ENTRY(ENTRY) (((ENTRY) == PWR_SLEEPEntry_WFI) || ((ENTRY) == PWR_SLEEPEntry_WFE)) - -/** - * @} - */ - -/** @defgroup STOP_mode_entry - * @{ - */ - -#define PWR_STOPEntry_WFI ((uint8_t)0x01) -#define PWR_STOPEntry_WFE ((uint8_t)0x02) -#define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPEntry_WFI) || ((ENTRY) == PWR_STOPEntry_WFE)) - -/** - * @} - */ - -/** @defgroup PWR_Flag - * @{ - */ - -#define PWR_FLAG_WU PWR_CSR_WUF -#define PWR_FLAG_SB PWR_CSR_SBF -#define PWR_FLAG_PVDO PWR_CSR_PVDO -#define PWR_FLAG_VREFINTRDY PWR_CSR_VREFINTRDYF -#define PWR_FLAG_VOS PWR_CSR_VOSF -#define PWR_FLAG_REGLP PWR_CSR_REGLPF - -#define IS_PWR_GET_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB) || \ - ((FLAG) == PWR_FLAG_PVDO) || ((FLAG) == PWR_FLAG_VREFINTRDY) || \ - ((FLAG) == PWR_FLAG_VOS) || ((FLAG) == PWR_FLAG_REGLP)) - -#define IS_PWR_CLEAR_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* Function used to set the PWR configuration to the default reset state ******/ -void PWR_DeInit(void); - -/* RTC Domain Access function *************************************************/ -void PWR_RTCAccessCmd(FunctionalState NewState); - -/* PVD configuration functions ************************************************/ -void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel); -void PWR_PVDCmd(FunctionalState NewState); - -/* WakeUp pins configuration functions ****************************************/ -void PWR_WakeUpPinCmd(uint32_t PWR_WakeUpPin, FunctionalState NewState); - -/* Ultra Low Power mode configuration functions *******************************/ -void PWR_FastWakeUpCmd(FunctionalState NewState); -void PWR_UltraLowPowerCmd(FunctionalState NewState); - -/* Voltage Scaling configuration functions ************************************/ -void PWR_VoltageScalingConfig(uint32_t PWR_VoltageScaling); - -/* Low Power modes configuration functions ************************************/ -void PWR_EnterLowPowerRunMode(FunctionalState NewState); -void PWR_EnterSleepMode(uint32_t PWR_Regulator, uint8_t PWR_SLEEPEntry); -void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry); -void PWR_EnterSTANDBYMode(void); - -/* Flags management functions *************************************************/ -FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG); -void PWR_ClearFlag(uint32_t PWR_FLAG); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32L1xx_PWR_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_rcc.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_rcc.h deleted file mode 100644 index d73c2aa1d..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_rcc.h +++ /dev/null @@ -1,468 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_rcc.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the RCC - * firmware library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_RCC_H -#define __STM32L1xx_RCC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup RCC - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -typedef struct -{ - uint32_t SYSCLK_Frequency; - uint32_t HCLK_Frequency; - uint32_t PCLK1_Frequency; - uint32_t PCLK2_Frequency; -}RCC_ClocksTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup RCC_Exported_Constants - * @{ - */ - -/** @defgroup HSE_configuration - * @{ - */ - -#define RCC_HSE_OFF ((uint8_t)0x00) -#define RCC_HSE_ON ((uint8_t)0x01) -#define RCC_HSE_Bypass ((uint8_t)0x05) -#define IS_RCC_HSE(HSE) (((HSE) == RCC_HSE_OFF) || ((HSE) == RCC_HSE_ON) || \ - ((HSE) == RCC_HSE_Bypass)) - -/** - * @} - */ - -/** @defgroup MSI_Clock_Range - * @{ - */ - -#define RCC_MSIRange_0 RCC_ICSCR_MSIRANGE_0 /*!< MSI = 65.536 KHz */ -#define RCC_MSIRange_1 RCC_ICSCR_MSIRANGE_1 /*!< MSI = 131.072 KHz */ -#define RCC_MSIRange_2 RCC_ICSCR_MSIRANGE_2 /*!< MSI = 262.144 KHz */ -#define RCC_MSIRange_3 RCC_ICSCR_MSIRANGE_3 /*!< MSI = 524.288 KHz */ -#define RCC_MSIRange_4 RCC_ICSCR_MSIRANGE_4 /*!< MSI = 1.048 MHz */ -#define RCC_MSIRange_5 RCC_ICSCR_MSIRANGE_5 /*!< MSI = 2.097 MHz */ -#define RCC_MSIRange_6 RCC_ICSCR_MSIRANGE_6 /*!< MSI = 4.194 MHz */ - -#define IS_RCC_MSI_CLOCK_RANGE(RANGE) (((RANGE) == RCC_MSIRange_0) || \ - ((RANGE) == RCC_MSIRange_1) || \ - ((RANGE) == RCC_MSIRange_2) || \ - ((RANGE) == RCC_MSIRange_3) || \ - ((RANGE) == RCC_MSIRange_4) || \ - ((RANGE) == RCC_MSIRange_5) || \ - ((RANGE) == RCC_MSIRange_6)) - -/** - * @} - */ - -/** @defgroup PLL_Clock_Source - * @{ - */ - -#define RCC_PLLSource_HSI ((uint8_t)0x00) -#define RCC_PLLSource_HSE ((uint8_t)0x01) - -#define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI) || \ - ((SOURCE) == RCC_PLLSource_HSE)) -/** - * @} - */ - -/** @defgroup PLL_Multiplication_Factor - * @{ - */ - -#define RCC_PLLMul_3 ((uint8_t)0x00) -#define RCC_PLLMul_4 ((uint8_t)0x04) -#define RCC_PLLMul_6 ((uint8_t)0x08) -#define RCC_PLLMul_8 ((uint8_t)0x0C) -#define RCC_PLLMul_12 ((uint8_t)0x10) -#define RCC_PLLMul_16 ((uint8_t)0x14) -#define RCC_PLLMul_24 ((uint8_t)0x18) -#define RCC_PLLMul_32 ((uint8_t)0x1C) -#define RCC_PLLMul_48 ((uint8_t)0x20) - - -#define IS_RCC_PLL_MUL(MUL) (((MUL) == RCC_PLLMul_3) || ((MUL) == RCC_PLLMul_4) || \ - ((MUL) == RCC_PLLMul_6) || ((MUL) == RCC_PLLMul_8) || \ - ((MUL) == RCC_PLLMul_12) || ((MUL) == RCC_PLLMul_16) || \ - ((MUL) == RCC_PLLMul_24) || ((MUL) == RCC_PLLMul_32) || \ - ((MUL) == RCC_PLLMul_48)) -/** - * @} - */ - -/** @defgroup PLL_Divider_Factor - * @{ - */ - -#define RCC_PLLDiv_2 ((uint8_t)0x40) -#define RCC_PLLDiv_3 ((uint8_t)0x80) -#define RCC_PLLDiv_4 ((uint8_t)0xC0) - - -#define IS_RCC_PLL_DIV(DIV) (((DIV) == RCC_PLLDiv_2) || ((DIV) == RCC_PLLDiv_3) || \ - ((DIV) == RCC_PLLDiv_4)) -/** - * @} - */ - -/** @defgroup System_Clock_Source - * @{ - */ - -#define RCC_SYSCLKSource_MSI RCC_CFGR_SW_MSI -#define RCC_SYSCLKSource_HSI RCC_CFGR_SW_HSI -#define RCC_SYSCLKSource_HSE RCC_CFGR_SW_HSE -#define RCC_SYSCLKSource_PLLCLK RCC_CFGR_SW_PLL -#define IS_RCC_SYSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSource_MSI) || \ - ((SOURCE) == RCC_SYSCLKSource_HSI) || \ - ((SOURCE) == RCC_SYSCLKSource_HSE) || \ - ((SOURCE) == RCC_SYSCLKSource_PLLCLK)) -/** - * @} - */ - -/** @defgroup AHB_Clock_Source - * @{ - */ - -#define RCC_SYSCLK_Div1 RCC_CFGR_HPRE_DIV1 -#define RCC_SYSCLK_Div2 RCC_CFGR_HPRE_DIV2 -#define RCC_SYSCLK_Div4 RCC_CFGR_HPRE_DIV4 -#define RCC_SYSCLK_Div8 RCC_CFGR_HPRE_DIV8 -#define RCC_SYSCLK_Div16 RCC_CFGR_HPRE_DIV16 -#define RCC_SYSCLK_Div64 RCC_CFGR_HPRE_DIV64 -#define RCC_SYSCLK_Div128 RCC_CFGR_HPRE_DIV128 -#define RCC_SYSCLK_Div256 RCC_CFGR_HPRE_DIV256 -#define RCC_SYSCLK_Div512 RCC_CFGR_HPRE_DIV512 -#define IS_RCC_HCLK(HCLK) (((HCLK) == RCC_SYSCLK_Div1) || ((HCLK) == RCC_SYSCLK_Div2) || \ - ((HCLK) == RCC_SYSCLK_Div4) || ((HCLK) == RCC_SYSCLK_Div8) || \ - ((HCLK) == RCC_SYSCLK_Div16) || ((HCLK) == RCC_SYSCLK_Div64) || \ - ((HCLK) == RCC_SYSCLK_Div128) || ((HCLK) == RCC_SYSCLK_Div256) || \ - ((HCLK) == RCC_SYSCLK_Div512)) -/** - * @} - */ - -/** @defgroup APB1_APB2_Clock_Source - * @{ - */ - -#define RCC_HCLK_Div1 RCC_CFGR_PPRE1_DIV1 -#define RCC_HCLK_Div2 RCC_CFGR_PPRE1_DIV2 -#define RCC_HCLK_Div4 RCC_CFGR_PPRE1_DIV4 -#define RCC_HCLK_Div8 RCC_CFGR_PPRE1_DIV8 -#define RCC_HCLK_Div16 RCC_CFGR_PPRE1_DIV16 -#define IS_RCC_PCLK(PCLK) (((PCLK) == RCC_HCLK_Div1) || ((PCLK) == RCC_HCLK_Div2) || \ - ((PCLK) == RCC_HCLK_Div4) || ((PCLK) == RCC_HCLK_Div8) || \ - ((PCLK) == RCC_HCLK_Div16)) -/** - * @} - */ - - -/** @defgroup RCC_Interrupt_Source - * @{ - */ - -#define RCC_IT_LSIRDY ((uint8_t)0x01) -#define RCC_IT_LSERDY ((uint8_t)0x02) -#define RCC_IT_HSIRDY ((uint8_t)0x04) -#define RCC_IT_HSERDY ((uint8_t)0x08) -#define RCC_IT_PLLRDY ((uint8_t)0x10) -#define RCC_IT_MSIRDY ((uint8_t)0x20) -#define RCC_IT_CSS ((uint8_t)0x80) - -#define IS_RCC_IT(IT) ((((IT) & (uint8_t)0xC0) == 0x00) && ((IT) != 0x00)) - -#define IS_RCC_GET_IT(IT) (((IT) == RCC_IT_LSIRDY) || ((IT) == RCC_IT_LSERDY) || \ - ((IT) == RCC_IT_HSIRDY) || ((IT) == RCC_IT_HSERDY) || \ - ((IT) == RCC_IT_PLLRDY) || ((IT) == RCC_IT_MSIRDY) || \ - ((IT) == RCC_IT_CSS)) - -#define IS_RCC_CLEAR_IT(IT) ((((IT) & (uint8_t)0x40) == 0x00) && ((IT) != 0x00)) - -/** - * @} - */ - -/** @defgroup LSE_Configuration - * @{ - */ - -#define RCC_LSE_OFF ((uint8_t)0x00) -#define RCC_LSE_ON ((uint8_t)0x01) -#define RCC_LSE_Bypass ((uint8_t)0x05) -#define IS_RCC_LSE(LSE) (((LSE) == RCC_LSE_OFF) || ((LSE) == RCC_LSE_ON) || \ - ((LSE) == RCC_LSE_Bypass)) -/** - * @} - */ - -/** @defgroup RTC_Clock_Source - * @{ - */ - -#define RCC_RTCCLKSource_LSE RCC_CSR_RTCSEL_LSE -#define RCC_RTCCLKSource_LSI RCC_CSR_RTCSEL_LSI -#define RCC_RTCCLKSource_HSE_Div2 RCC_CSR_RTCSEL_HSE -#define RCC_RTCCLKSource_HSE_Div4 ((uint32_t)RCC_CSR_RTCSEL_HSE | RCC_CR_RTCPRE_0) -#define RCC_RTCCLKSource_HSE_Div8 ((uint32_t)RCC_CSR_RTCSEL_HSE | RCC_CR_RTCPRE_1) -#define RCC_RTCCLKSource_HSE_Div16 ((uint32_t)RCC_CSR_RTCSEL_HSE | RCC_CR_RTCPRE) -#define IS_RCC_RTCCLK_SOURCE(SOURCE) (((SOURCE) == RCC_RTCCLKSource_LSE) || \ - ((SOURCE) == RCC_RTCCLKSource_LSI) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div2) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div4) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div8) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div16)) -/** - * @} - */ - -/** @defgroup AHB_Peripherals - * @{ - */ - -#define RCC_AHBPeriph_GPIOA RCC_AHBENR_GPIOAEN -#define RCC_AHBPeriph_GPIOB RCC_AHBENR_GPIOBEN -#define RCC_AHBPeriph_GPIOC RCC_AHBENR_GPIOCEN -#define RCC_AHBPeriph_GPIOD RCC_AHBENR_GPIODEN -#define RCC_AHBPeriph_GPIOE RCC_AHBENR_GPIOEEN -#define RCC_AHBPeriph_GPIOH RCC_AHBENR_GPIOHEN -#define RCC_AHBPeriph_CRC RCC_AHBENR_CRCEN -#define RCC_AHBPeriph_FLITF RCC_AHBENR_FLITFEN -#define RCC_AHBPeriph_SRAM RCC_AHBLPENR_SRAMLPEN -#define RCC_AHBPeriph_DMA1 RCC_AHBENR_DMA1EN - -#define IS_RCC_AHB_PERIPH(PERIPH) ((((PERIPH) & 0xFEFF6FC0) == 0x00) && ((PERIPH) != 0x00)) -#define IS_RCC_AHB_LPMODE_PERIPH(PERIPH) ((((PERIPH) & 0xFEFE6FC0) == 0x00) && ((PERIPH) != 0x00)) - -/** - * @} - */ - -/** @defgroup APB2_Peripherals - * @{ - */ - -#define RCC_APB2Periph_SYSCFG RCC_APB2ENR_SYSCFGEN -#define RCC_APB2Periph_TIM9 RCC_APB2ENR_TIM9EN -#define RCC_APB2Periph_TIM10 RCC_APB2ENR_TIM10EN -#define RCC_APB2Periph_TIM11 RCC_APB2ENR_TIM11EN -#define RCC_APB2Periph_ADC1 RCC_APB2ENR_ADC1EN -#define RCC_APB2Periph_SPI1 RCC_APB2ENR_SPI1EN -#define RCC_APB2Periph_USART1 RCC_APB2ENR_USART1EN - -#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFADE2) == 0x00) && ((PERIPH) != 0x00)) -/** - * @} - */ - -/** @defgroup APB1_Peripherals - * @{ - */ - -#define RCC_APB1Periph_TIM2 RCC_APB1ENR_TIM2EN -#define RCC_APB1Periph_TIM3 RCC_APB1ENR_TIM3EN -#define RCC_APB1Periph_TIM4 RCC_APB1ENR_TIM4EN -#define RCC_APB1Periph_TIM6 RCC_APB1ENR_TIM6EN -#define RCC_APB1Periph_TIM7 RCC_APB1ENR_TIM7EN -#define RCC_APB1Periph_LCD RCC_APB1ENR_LCDEN -#define RCC_APB1Periph_WWDG RCC_APB1ENR_WWDGEN -#define RCC_APB1Periph_SPI2 RCC_APB1ENR_SPI2EN -#define RCC_APB1Periph_USART2 RCC_APB1ENR_USART2EN -#define RCC_APB1Periph_USART3 RCC_APB1ENR_USART3EN -#define RCC_APB1Periph_I2C1 RCC_APB1ENR_I2C1EN -#define RCC_APB1Periph_I2C2 RCC_APB1ENR_I2C2EN -#define RCC_APB1Periph_USB RCC_APB1ENR_USBEN -#define RCC_APB1Periph_PWR RCC_APB1ENR_PWREN -#define RCC_APB1Periph_DAC RCC_APB1ENR_DACEN -#define RCC_APB1Periph_COMP RCC_APB1ENR_COMPEN - -#define IS_RCC_APB1_PERIPH(PERIPH) ((((PERIPH) & 0x4F19B5C8) == 0x00) && ((PERIPH) != 0x00)) -/** - * @} - */ - -/** @defgroup MCO_Clock_Source - * @{ - */ - -#define RCC_MCOSource_NoClock ((uint8_t)0x00) -#define RCC_MCOSource_SYSCLK ((uint8_t)0x01) -#define RCC_MCOSource_HSI ((uint8_t)0x02) -#define RCC_MCOSource_MSI ((uint8_t)0x03) -#define RCC_MCOSource_HSE ((uint8_t)0x04) -#define RCC_MCOSource_PLLCLK ((uint8_t)0x05) -#define RCC_MCOSource_LSI ((uint8_t)0x06) -#define RCC_MCOSource_LSE ((uint8_t)0x07) - -#define IS_RCC_MCO_SOURCE(SOURCE) (((SOURCE) == RCC_MCOSource_NoClock) || ((SOURCE) == RCC_MCOSource_SYSCLK) || \ - ((SOURCE) == RCC_MCOSource_HSI) || ((SOURCE) == RCC_MCOSource_MSI) || \ - ((SOURCE) == RCC_MCOSource_HSE) || ((SOURCE) == RCC_MCOSource_PLLCLK) || \ - ((SOURCE) == RCC_MCOSource_LSI) || ((SOURCE) == RCC_MCOSource_LSE)) -/** - * @} - */ - -/** @defgroup MCO_Output_Divider - * @{ - */ - -#define RCC_MCODiv_1 ((uint8_t)0x00) -#define RCC_MCODiv_2 ((uint8_t)0x10) -#define RCC_MCODiv_4 ((uint8_t)0x20) -#define RCC_MCODiv_8 ((uint8_t)0x30) -#define RCC_MCODiv_16 ((uint8_t)0x40) - -#define IS_RCC_MCO_DIV(DIV) (((DIV) == RCC_MCODiv_1) || ((DIV) == RCC_MCODiv_2) || \ - ((DIV) == RCC_MCODiv_4) || ((DIV) == RCC_MCODiv_8) || \ - ((DIV) == RCC_MCODiv_16)) -/** - * @} - */ - -/** @defgroup RCC_Flag - * @{ - */ - -#define RCC_FLAG_HSIRDY ((uint8_t)0x21) -#define RCC_FLAG_MSIRDY ((uint8_t)0x29) -#define RCC_FLAG_HSERDY ((uint8_t)0x31) -#define RCC_FLAG_PLLRDY ((uint8_t)0x39) -#define RCC_FLAG_LSERDY ((uint8_t)0x49) -#define RCC_FLAG_LSIRDY ((uint8_t)0x41) -#define RCC_FLAG_OBLRST ((uint8_t)0x59) -#define RCC_FLAG_PINRST ((uint8_t)0x5A) -#define RCC_FLAG_PORRST ((uint8_t)0x5B) -#define RCC_FLAG_SFTRST ((uint8_t)0x5C) -#define RCC_FLAG_IWDGRST ((uint8_t)0x5D) -#define RCC_FLAG_WWDGRST ((uint8_t)0x5E) -#define RCC_FLAG_LPWRRST ((uint8_t)0x5F) - -#define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_HSIRDY) || ((FLAG) == RCC_FLAG_HSERDY) || \ - ((FLAG) == RCC_FLAG_MSIRDY) || ((FLAG) == RCC_FLAG_PLLRDY) || \ - ((FLAG) == RCC_FLAG_LSERDY) || ((FLAG) == RCC_FLAG_LSIRDY) || \ - ((FLAG) == RCC_FLAG_PINRST) || ((FLAG) == RCC_FLAG_PORRST) || \ - ((FLAG) == RCC_FLAG_SFTRST) || ((FLAG) == RCC_FLAG_IWDGRST)|| \ - ((FLAG) == RCC_FLAG_WWDGRST)|| ((FLAG) == RCC_FLAG_LPWRRST)|| \ - ((FLAG) == RCC_FLAG_WWDGRST)) - -#define IS_RCC_HSI_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x1F) -#define IS_RCC_MSI_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x3F) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* Function used to set the RCC clock configuration to the default reset state */ -void RCC_DeInit(void); - -/* Internal/external clocks, PLL, CSS and MCO configuration functions *********/ -void RCC_HSEConfig(uint8_t RCC_HSE); -ErrorStatus RCC_WaitForHSEStartUp(void); -void RCC_MSIRangeConfig(uint32_t RCC_MSIRange); -void RCC_AdjustMSICalibrationValue(uint8_t MSICalibrationValue); -void RCC_MSICmd(FunctionalState NewState); -void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue); -void RCC_HSICmd(FunctionalState NewState); -void RCC_LSEConfig(uint8_t RCC_LSE); -void RCC_LSICmd(FunctionalState NewState); -void RCC_PLLConfig(uint8_t RCC_PLLSource, uint8_t RCC_PLLMul, uint8_t RCC_PLLDiv); -void RCC_PLLCmd(FunctionalState NewState); -void RCC_ClockSecuritySystemCmd(FunctionalState NewState); -void RCC_MCOConfig(uint8_t RCC_MCOSource, uint8_t RCC_MCODiv); - -/* System, AHB and APB busses clocks configuration functions ******************/ -void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource); -uint8_t RCC_GetSYSCLKSource(void); -void RCC_HCLKConfig(uint32_t RCC_SYSCLK); -void RCC_PCLK1Config(uint32_t RCC_HCLK); -void RCC_PCLK2Config(uint32_t RCC_HCLK); -void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks); - -/* Peripheral clocks configuration functions **********************************/ -void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource); -void RCC_RTCCLKCmd(FunctionalState NewState); -void RCC_RTCResetCmd(FunctionalState NewState); - -void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); -void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); -void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); - -void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); -void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); -void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); - -void RCC_AHBPeriphClockLPModeCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); -void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); -void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); - -/* Interrupts and flags management functions **********************************/ -void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState); -FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG); -void RCC_ClearFlag(void); -ITStatus RCC_GetITStatus(uint8_t RCC_IT); -void RCC_ClearITPendingBit(uint8_t RCC_IT); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32L1xx_RCC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_rtc.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_rtc.h deleted file mode 100644 index 65979deda..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_rtc.h +++ /dev/null @@ -1,611 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_rtc.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the RTC firmware - * library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_RTC_H -#define __STM32L1xx_RTC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup RTC - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief RTC Init structures definition - */ -typedef struct -{ - uint32_t RTC_HourFormat; /*!< Specifies the RTC Hour Format. - This parameter can be a value of @ref RTC_Hour_Formats */ - - uint32_t RTC_AsynchPrediv; /*!< Specifies the RTC Asynchronous Predivider value. - This parameter must be set to a value lower than 0x7F */ - - uint32_t RTC_SynchPrediv; /*!< Specifies the RTC Synchronous Predivider value. - This parameter must be set to a value lower than 0x1FFF */ -}RTC_InitTypeDef; - -/** - * @brief RTC Time structure definition - */ -typedef struct -{ - uint8_t RTC_Hours; /*!< Specifies the RTC Time Hour. - This parameter must be set to a value in the 0-12 range - if the RTC_HourFormat_12 is selected or 0-23 range if - the RTC_HourFormat_24 is selected. */ - - uint8_t RTC_Minutes; /*!< Specifies the RTC Time Minutes. - This parameter must be set to a value in the 0-59 range. */ - - uint8_t RTC_Seconds; /*!< Specifies the RTC Time Seconds. - This parameter must be set to a value in the 0-59 range. */ - - uint8_t RTC_H12; /*!< Specifies the RTC AM/PM Time. - This parameter can be a value of @ref RTC_AM_PM_Definitions */ -}RTC_TimeTypeDef; - -/** - * @brief RTC Date structure definition - */ -typedef struct -{ - uint32_t RTC_WeekDay; /*!< Specifies the RTC Date WeekDay. - This parameter can be a value of @ref RTC_WeekDay_Definitions */ - - uint32_t RTC_Month; /*!< Specifies the RTC Date Month. - This parameter can be a value of @ref RTC_Month_Date_Definitions */ - - uint8_t RTC_Date; /*!< Specifies the RTC Date. - This parameter must be set to a value in the 1-31 range. */ - - uint8_t RTC_Year; /*!< Specifies the RTC Date Year. - This parameter must be set to a value in the 0-99 range. */ -}RTC_DateTypeDef; - -/** - * @brief RTC Alarm structure definition - */ -typedef struct -{ - RTC_TimeTypeDef RTC_AlarmTime; /*!< Specifies the RTC Alarm Time members. */ - - uint32_t RTC_AlarmMask; /*!< Specifies the RTC Alarm Masks. - This parameter can be a value of @ref RTC_AlarmMask_Definitions */ - - uint32_t RTC_AlarmDateWeekDaySel; /*!< Specifies the RTC Alarm is on Date or WeekDay. - This parameter can be a value of @ref RTC_AlarmDateWeekDay_Definitions */ - - uint8_t RTC_AlarmDateWeekDay; /*!< Specifies the RTC Alarm Date/WeekDay. - This parameter must be set to a value in the 1-31 range - if the Alarm Date is selected. - This parameter can be a value of @ref RTC_WeekDay_Definitions - if the Alarm WeekDay is selected. */ -}RTC_AlarmTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup RTC_Exported_Constants - * @{ - */ - - -/** @defgroup RTC_Hour_Formats - * @{ - */ -#define RTC_HourFormat_24 ((uint32_t)0x00000000) -#define RTC_HourFormat_12 ((uint32_t)0x00000040) -#define IS_RTC_HOUR_FORMAT(FORMAT) (((FORMAT) == RTC_HourFormat_12) || \ - ((FORMAT) == RTC_HourFormat_24)) -/** - * @} - */ - -/** @defgroup RTC_Asynchronous_Predivider - * @{ - */ -#define IS_RTC_ASYNCH_PREDIV(PREDIV) ((PREDIV) <= 0x7F) - -/** - * @} - */ - - -/** @defgroup RTC_Synchronous_Predivider - * @{ - */ -#define IS_RTC_SYNCH_PREDIV(PREDIV) ((PREDIV) <= 0x1FFF) - -/** - * @} - */ - -/** @defgroup RTC_Time_Definitions - * @{ - */ -#define IS_RTC_HOUR12(HOUR) (((HOUR) > 0) && ((HOUR) <= 12)) -#define IS_RTC_HOUR24(HOUR) ((HOUR) <= 23) -#define IS_RTC_MINUTES(MINUTES) ((MINUTES) <= 59) -#define IS_RTC_SECONDS(SECONDS) ((SECONDS) <= 59) - -/** - * @} - */ - -/** @defgroup RTC_AM_PM_Definitions - * @{ - */ -#define RTC_H12_AM ((uint8_t)0x00) -#define RTC_H12_PM ((uint8_t)0x40) -#define IS_RTC_H12(PM) (((PM) == RTC_H12_AM) || ((PM) == RTC_H12_PM)) - -/** - * @} - */ - -/** @defgroup RTC_Year_Date_Definitions - * @{ - */ -#define IS_RTC_YEAR(YEAR) ((YEAR) <= 99) - -/** - * @} - */ - -/** @defgroup RTC_Month_Date_Definitions - * @{ - */ -#define RTC_Month_January ((uint32_t)0x00000001) -#define RTC_Month_February ((uint32_t)0x00000002) -#define RTC_Month_March ((uint32_t)0x00000003) -#define RTC_Month_April ((uint32_t)0x00000004) -#define RTC_Month_May ((uint32_t)0x00000005) -#define RTC_Month_June ((uint32_t)0x00000006) -#define RTC_Month_July ((uint32_t)0x00000007) -#define RTC_Month_August ((uint32_t)0x00000008) -#define RTC_Month_September ((uint32_t)0x00000009) -#define RTC_Month_October ((uint32_t)0x00000010) -#define RTC_Month_November ((uint32_t)0x00000011) -#define RTC_Month_December ((uint32_t)0x00000012) -#define IS_RTC_MONTH(MONTH) (((MONTH) >= 1) && ((MONTH) <= 12)) -#define IS_RTC_DATE(DATE) (((DATE) >= 1) && ((DATE) <= 31)) - -/** - * @} - */ - -/** @defgroup RTC_WeekDay_Definitions - * @{ - */ - -#define RTC_Weekday_Monday ((uint32_t)0x00000001) -#define RTC_Weekday_Tuesday ((uint32_t)0x00000002) -#define RTC_Weekday_Wednesday ((uint32_t)0x00000003) -#define RTC_Weekday_Thursday ((uint32_t)0x00000004) -#define RTC_Weekday_Friday ((uint32_t)0x00000005) -#define RTC_Weekday_Saturday ((uint32_t)0x00000006) -#define RTC_Weekday_Sunday ((uint32_t)0x00000007) -#define IS_RTC_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_Weekday_Monday) || \ - ((WEEKDAY) == RTC_Weekday_Tuesday) || \ - ((WEEKDAY) == RTC_Weekday_Wednesday) || \ - ((WEEKDAY) == RTC_Weekday_Thursday) || \ - ((WEEKDAY) == RTC_Weekday_Friday) || \ - ((WEEKDAY) == RTC_Weekday_Saturday) || \ - ((WEEKDAY) == RTC_Weekday_Sunday)) -/** - * @} - */ - - -/** @defgroup RTC_Alarm_Definitions - * @{ - */ -#define IS_RTC_ALARM_DATE_WEEKDAY_DATE(DATE) (((DATE) > 0) && ((DATE) <= 31)) -#define IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_Weekday_Monday) || \ - ((WEEKDAY) == RTC_Weekday_Tuesday) || \ - ((WEEKDAY) == RTC_Weekday_Wednesday) || \ - ((WEEKDAY) == RTC_Weekday_Thursday) || \ - ((WEEKDAY) == RTC_Weekday_Friday) || \ - ((WEEKDAY) == RTC_Weekday_Saturday) || \ - ((WEEKDAY) == RTC_Weekday_Sunday)) - -/** - * @} - */ - - -/** @defgroup RTC_AlarmDateWeekDay_Definitions - * @{ - */ -#define RTC_AlarmDateWeekDaySel_Date ((uint32_t)0x00000000) -#define RTC_AlarmDateWeekDaySel_WeekDay ((uint32_t)0x40000000) - -#define IS_RTC_ALARM_DATE_WEEKDAY_SEL(SEL) (((SEL) == RTC_AlarmDateWeekDaySel_Date) || \ - ((SEL) == RTC_AlarmDateWeekDaySel_WeekDay)) - -/** - * @} - */ - - -/** @defgroup RTC_AlarmMask_Definitions - * @{ - */ -#define RTC_AlarmMask_None ((uint32_t)0x00000000) -#define RTC_AlarmMask_DateWeekDay ((uint32_t)0x80000000) -#define RTC_AlarmMask_Hours ((uint32_t)0x00800000) -#define RTC_AlarmMask_Minutes ((uint32_t)0x00008000) -#define RTC_AlarmMask_Seconds ((uint32_t)0x00000080) -#define RTC_AlarmMask_All ((uint32_t)0x80808080) -#define IS_ALARM_MASK(MASK) (((MASK) & 0x7F7F7F7F) == (uint32_t)RESET) - -/** - * @} - */ - -/** @defgroup RTC_Alarms_Definitions - * @{ - */ -#define RTC_Alarm_A ((uint32_t)0x00000100) -#define RTC_Alarm_B ((uint32_t)0x00000200) -#define IS_RTC_ALARM(ALARM) (((ALARM) == RTC_Alarm_A) || ((ALARM) == RTC_Alarm_B)) -#define IS_RTC_CMD_ALARM(ALARM) (((ALARM) & (RTC_Alarm_A | RTC_Alarm_B)) != (uint32_t)RESET) - -/** - * @} - */ - -/** @defgroup RTC_Wakeup_Timer_Definitions - * @{ - */ -#define RTC_WakeUpClock_RTCCLK_Div16 ((uint32_t)0x00000000) -#define RTC_WakeUpClock_RTCCLK_Div8 ((uint32_t)0x00000001) -#define RTC_WakeUpClock_RTCCLK_Div4 ((uint32_t)0x00000002) -#define RTC_WakeUpClock_RTCCLK_Div2 ((uint32_t)0x00000003) -#define RTC_WakeUpClock_CK_SPRE_16bits ((uint32_t)0x00000004) -#define RTC_WakeUpClock_CK_SPRE_17bits ((uint32_t)0x00000006) -#define IS_RTC_WAKEUP_CLOCK(CLOCK) (((CLOCK) == RTC_WakeUpClock_RTCCLK_Div16) || \ - ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div8) || \ - ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div4) || \ - ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div2) || \ - ((CLOCK) == RTC_WakeUpClock_CK_SPRE_16bits) || \ - ((CLOCK) == RTC_WakeUpClock_CK_SPRE_17bits)) -#define IS_RTC_WAKEUP_COUNTER(COUNTER) ((COUNTER) <= 0xFFFF) -/** - * @} - */ - -/** @defgroup RTC_Time_Stamp_Edges_definitions - * @{ - */ -#define RTC_TimeStampEdge_Rising ((uint32_t)0x00000000) -#define RTC_TimeStampEdge_Falling ((uint32_t)0x00000008) -#define IS_RTC_TIMESTAMP_EDGE(EDGE) (((EDGE) == RTC_TimeStampEdge_Rising) || \ - ((EDGE) == RTC_TimeStampEdge_Falling)) -/** - * @} - */ - -/** @defgroup RTC_Output_selection_Definitions - * @{ - */ -#define RTC_Output_Disable ((uint32_t)0x00000000) -#define RTC_Output_AlarmA ((uint32_t)0x00200000) -#define RTC_Output_AlarmB ((uint32_t)0x00400000) -#define RTC_Output_WakeUp ((uint32_t)0x00600000) - -#define IS_RTC_OUTPUT(OUTPUT) (((OUTPUT) == RTC_Output_Disable) || \ - ((OUTPUT) == RTC_Output_AlarmA) || \ - ((OUTPUT) == RTC_Output_AlarmB) || \ - ((OUTPUT) == RTC_Output_WakeUp)) - -/** - * @} - */ - -/** @defgroup RTC_Output_Polarity_Definitions - * @{ - */ -#define RTC_OutputPolarity_High ((uint32_t)0x00000000) -#define RTC_OutputPolarity_Low ((uint32_t)0x00100000) -#define IS_RTC_OUTPUT_POL(POL) (((POL) == RTC_OutputPolarity_High) || \ - ((POL) == RTC_OutputPolarity_Low)) -/** - * @} - */ - - -/** @defgroup RTC_Digital_Calibration_Definitions - * @{ - */ -#define RTC_CalibSign_Positive ((uint32_t)0x00000000) -#define RTC_CalibSign_Negative ((uint32_t)0x00000080) -#define IS_RTC_CALIB_SIGN(SIGN) (((SIGN) == RTC_CalibSign_Positive) || \ - ((SIGN) == RTC_CalibSign_Negative)) -#define IS_RTC_CALIB_VALUE(VALUE) ((VALUE) < 0x20) - -/** - * @} - */ - - -/** @defgroup RTC_DayLightSaving_Definitions - * @{ - */ -#define RTC_DayLightSaving_SUB1H ((uint32_t)0x00020000) -#define RTC_DayLightSaving_ADD1H ((uint32_t)0x00010000) -#define IS_RTC_DAYLIGHT_SAVING(SAVE) (((SAVE) == RTC_DayLightSaving_SUB1H) || \ - ((SAVE) == RTC_DayLightSaving_ADD1H)) - -#define RTC_StoreOperation_Reset ((uint32_t)0x00000000) -#define RTC_StoreOperation_Set ((uint32_t)0x00040000) -#define IS_RTC_STORE_OPERATION(OPERATION) (((OPERATION) == RTC_StoreOperation_Reset) || \ - ((OPERATION) == RTC_StoreOperation_Set)) -/** - * @} - */ - -/** @defgroup RTC_Tamper_Trigger_Definitions - * @{ - */ -#define RTC_TamperTrigger_RisingEdge ((uint32_t)0x00000000) -#define RTC_TamperTrigger_FallingEdge ((uint32_t)0x00000001) -#define IS_RTC_TAMPER_TRIGGER(TRIGGER) (((TRIGGER) == RTC_TamperTrigger_RisingEdge) || \ - ((TRIGGER) == RTC_TamperTrigger_FallingEdge)) - -/** - * @} - */ - -/** @defgroup RTC_Tamper_Pins_Definitions - * @{ - */ -#define RTC_Tamper_1 RTC_TAFCR_TAMP1E -#define IS_RTC_TAMPER(TAMPER) (((TAMPER) == RTC_Tamper_1)) - -/** - * @} - */ - -/** @defgroup RTC_Output_Type_ALARM_OUT - * @{ - */ -#define RTC_OutputType_OpenDrain ((uint32_t)0x00000000) -#define RTC_OutputType_PushPull ((uint32_t)0x00040000) -#define IS_RTC_OUTPUT_TYPE(TYPE) (((TYPE) == RTC_OutputType_OpenDrain) || \ - ((TYPE) == RTC_OutputType_PushPull)) - -/** - * @} - */ - -/** @defgroup RTC_Backup_Registers_Definitions - * @{ - */ - -#define RTC_BKP_DR0 ((uint32_t)0x00000000) -#define RTC_BKP_DR1 ((uint32_t)0x00000001) -#define RTC_BKP_DR2 ((uint32_t)0x00000002) -#define RTC_BKP_DR3 ((uint32_t)0x00000003) -#define RTC_BKP_DR4 ((uint32_t)0x00000004) -#define RTC_BKP_DR5 ((uint32_t)0x00000005) -#define RTC_BKP_DR6 ((uint32_t)0x00000006) -#define RTC_BKP_DR7 ((uint32_t)0x00000007) -#define RTC_BKP_DR8 ((uint32_t)0x00000008) -#define RTC_BKP_DR9 ((uint32_t)0x00000009) -#define RTC_BKP_DR10 ((uint32_t)0x0000000A) -#define RTC_BKP_DR11 ((uint32_t)0x0000000B) -#define RTC_BKP_DR12 ((uint32_t)0x0000000C) -#define RTC_BKP_DR13 ((uint32_t)0x0000000D) -#define RTC_BKP_DR14 ((uint32_t)0x0000000E) -#define RTC_BKP_DR15 ((uint32_t)0x0000000F) -#define RTC_BKP_DR16 ((uint32_t)0x00000010) -#define RTC_BKP_DR17 ((uint32_t)0x00000011) -#define RTC_BKP_DR18 ((uint32_t)0x00000012) -#define RTC_BKP_DR19 ((uint32_t)0x00000013) -#define IS_RTC_BKP(BKP) (((BKP) == RTC_BKP_DR0) || \ - ((BKP) == RTC_BKP_DR1) || \ - ((BKP) == RTC_BKP_DR2) || \ - ((BKP) == RTC_BKP_DR3) || \ - ((BKP) == RTC_BKP_DR4) || \ - ((BKP) == RTC_BKP_DR5) || \ - ((BKP) == RTC_BKP_DR6) || \ - ((BKP) == RTC_BKP_DR7) || \ - ((BKP) == RTC_BKP_DR8) || \ - ((BKP) == RTC_BKP_DR9) || \ - ((BKP) == RTC_BKP_DR10) || \ - ((BKP) == RTC_BKP_DR11) || \ - ((BKP) == RTC_BKP_DR12) || \ - ((BKP) == RTC_BKP_DR13) || \ - ((BKP) == RTC_BKP_DR14) || \ - ((BKP) == RTC_BKP_DR15) || \ - ((BKP) == RTC_BKP_DR16) || \ - ((BKP) == RTC_BKP_DR17) || \ - ((BKP) == RTC_BKP_DR18) || \ - ((BKP) == RTC_BKP_DR19)) -/** - * @} - */ - -/** @defgroup RTC_Input_parameter_format_definitions - * @{ - */ -#define RTC_Format_BIN ((uint32_t)0x000000000) -#define RTC_Format_BCD ((uint32_t)0x000000001) -#define IS_RTC_FORMAT(FORMAT) (((FORMAT) == RTC_Format_BIN) || ((FORMAT) == RTC_Format_BCD)) - -/** - * @} - */ - -/** @defgroup RTC_Flags_Definitions - * @{ - */ -#define RTC_FLAG_TAMP1F ((uint32_t)0x00002000) -#define RTC_FLAG_TSOVF ((uint32_t)0x00001000) -#define RTC_FLAG_TSF ((uint32_t)0x00000800) -#define RTC_FLAG_WUTF ((uint32_t)0x00000400) -#define RTC_FLAG_ALRBF ((uint32_t)0x00000200) -#define RTC_FLAG_ALRAF ((uint32_t)0x00000100) -#define RTC_FLAG_INITF ((uint32_t)0x00000040) -#define RTC_FLAG_RSF ((uint32_t)0x00000020) -#define RTC_FLAG_INITS ((uint32_t)0x00000010) -#define RTC_FLAG_WUTWF ((uint32_t)0x00000004) -#define RTC_FLAG_ALRBWF ((uint32_t)0x00000002) -#define RTC_FLAG_ALRAWF ((uint32_t)0x00000001) -#define IS_RTC_GET_FLAG(FLAG) (((FLAG) == RTC_FLAG_TSOVF) || ((FLAG) == RTC_FLAG_TSF) || \ - ((FLAG) == RTC_FLAG_WUTF) || ((FLAG) == RTC_FLAG_ALRBF) || \ - ((FLAG) == RTC_FLAG_ALRAF) || ((FLAG) == RTC_FLAG_INITF) || \ - ((FLAG) == RTC_FLAG_RSF) || ((FLAG) == RTC_FLAG_WUTWF) || \ - ((FLAG) == RTC_FLAG_ALRBWF) || ((FLAG) == RTC_FLAG_ALRAWF) || \ - ((FLAG) == RTC_FLAG_TAMP1F)) -#define IS_RTC_CLEAR_FLAG(FLAG) (((FLAG) != (uint32_t)RESET) && (((FLAG) & 0xFFFFC0DF) == (uint32_t)RESET)) - -/** - * @} - */ - -/** @defgroup RTC_Interrupts_Definitions - * @{ - */ -#define RTC_IT_TS ((uint32_t)0x00008000) -#define RTC_IT_WUT ((uint32_t)0x00004000) -#define RTC_IT_ALRB ((uint32_t)0x00002000) -#define RTC_IT_ALRA ((uint32_t)0x00001000) -#define RTC_IT_TAMP ((uint32_t)0x00000004) /* Used only to Enable the Tamper Interrupt */ -#define RTC_IT_TAMP1 ((uint32_t)0x00020000) - -#define IS_RTC_CONFIG_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFF0FFB) == (uint32_t)RESET)) -#define IS_RTC_GET_IT(IT) (((IT) == RTC_IT_TS) || ((IT) == RTC_IT_WUT) || \ - ((IT) == RTC_IT_ALRB) || ((IT) == RTC_IT_ALRA) || \ - ((IT) == RTC_IT_TAMP1)) -#define IS_RTC_CLEAR_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFD0FFF) == (uint32_t)RESET)) - -/** - * @} - */ - -/** - * @} - */ - - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* Function used to set the RTC configuration to the default reset state *****/ -ErrorStatus RTC_DeInit(void); - - -/* Initialization and Configuration functions *********************************/ -ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct); -void RTC_StructInit(RTC_InitTypeDef* RTC_InitStruct); -void RTC_WriteProtectionCmd(FunctionalState NewState); -ErrorStatus RTC_EnterInitMode(void); -void RTC_ExitInitMode(void); -ErrorStatus RTC_WaitForSynchro(void); -ErrorStatus RTC_RefClockCmd(FunctionalState NewState); - -/* Time and Date configuration functions **************************************/ -ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct); -void RTC_TimeStructInit(RTC_TimeTypeDef* RTC_TimeStruct); -void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct); -ErrorStatus RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct); -void RTC_DateStructInit(RTC_DateTypeDef* RTC_DateStruct); -void RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct); - -/* Alarms (Alarm A and Alarm B) configuration functions **********************/ -void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct); -void RTC_AlarmStructInit(RTC_AlarmTypeDef* RTC_AlarmStruct); -void RTC_GetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct); -ErrorStatus RTC_AlarmCmd(uint32_t RTC_Alarm, FunctionalState NewState); - -/* WakeUp Timer configuration functions ***************************************/ -void RTC_WakeUpClockConfig(uint32_t RTC_WakeUpClock); -void RTC_SetWakeUpCounter(uint32_t RTC_WakeUpCounter); -uint32_t RTC_GetWakeUpCounter(void); -ErrorStatus RTC_WakeUpCmd(FunctionalState NewState); - -/* Daylight Saving configuration functions ************************************/ -void RTC_DayLightSavingConfig(uint32_t RTC_DayLightSaving, uint32_t RTC_StoreOperation); -uint32_t RTC_GetStoreOperation(void); - -/* Output pin Configuration function ******************************************/ -void RTC_OutputConfig(uint32_t RTC_Output, uint32_t RTC_OutputPolarity); - -/* Digital Calibration configuration functions ********************************/ -ErrorStatus RTC_DigitalCalibConfig(uint32_t RTC_CalibSign, uint32_t Value); -ErrorStatus RTC_DigitalCalibCmd(FunctionalState NewState); -void RTC_CalibOutputCmd(FunctionalState NewState); - -/* TimeStamp configuration functions ******************************************/ -void RTC_TimeStampCmd(uint32_t RTC_TimeStampEdge, FunctionalState NewState); -void RTC_GetTimeStamp(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_StampTimeStruct, - RTC_DateTypeDef* RTC_StampDateStruct); - - -/* Tampers configuration functions ********************************************/ -void RTC_TamperTriggerConfig(uint32_t RTC_Tamper, uint32_t RTC_TamperTrigger); -void RTC_TamperCmd(uint32_t RTC_Tamper, FunctionalState NewState); - -/* Backup Data Registers configuration functions ******************************/ -void RTC_WriteBackupRegister(uint32_t RTC_BKP_DR, uint32_t Data); -uint32_t RTC_ReadBackupRegister(uint32_t RTC_BKP_DR); - -/* Output Type Config configuration functions *********************************/ -void RTC_OutputTypeConfig(uint32_t RTC_OutputType); - - -/* Interrupts and flags management functions **********************************/ -void RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState); -FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG); -void RTC_ClearFlag(uint32_t RTC_FLAG); -ITStatus RTC_GetITStatus(uint32_t RTC_IT); -void RTC_ClearITPendingBit(uint32_t RTC_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32L1xx_RTC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_spi.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_spi.h deleted file mode 100644 index 335bec493..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_spi.h +++ /dev/null @@ -1,379 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_spi.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the SPI - * firmware library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_SPI_H -#define __STM32L1xx_SPI_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup SPI - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief SPI Init structure definition - */ - -typedef struct -{ - uint16_t SPI_Direction; /*!< Specifies the SPI unidirectional or bidirectional data mode. - This parameter can be any combination of @ref SPI_data_direction */ - - uint16_t SPI_Mode; /*!< Specifies the SPI operating mode. - This parameter can be any combination of @ref SPI_mode */ - - uint16_t SPI_DataSize; /*!< Specifies the SPI data size. - This parameter can be any combination of @ref SPI_data_size */ - - uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state. - This parameter can be any combination of @ref SPI_Clock_Polarity */ - - uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture. - This parameter can be any combination of @ref SPI_Clock_Phase */ - - uint16_t SPI_NSS; /*!< Specifies whether the NSS signal is managed by - hardware (NSS pin) or by software using the SSI bit. - This parameter can be any combination of @ref SPI_Slave_Select_management */ - - uint16_t SPI_BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be - used to configure the transmit and receive SCK clock. - This parameter can be any combination of @ref SPI_BaudRate_Prescaler. - @note The communication clock is derived from the master - clock. The slave clock does not need to be set. */ - - uint16_t SPI_FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit. - This parameter can be any combination of @ref SPI_MSB_LSB_transmission */ - - uint16_t SPI_CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. */ -}SPI_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup SPI_Exported_Constants - * @{ - */ - -#define IS_SPI_ALL_PERIPH(PERIPH) (((PERIPH) == SPI1) || \ - ((PERIPH) == SPI2)) - -/** @defgroup SPI_data_direction - * @{ - */ - -#define SPI_Direction_2Lines_FullDuplex ((uint16_t)0x0000) -#define SPI_Direction_2Lines_RxOnly ((uint16_t)0x0400) -#define SPI_Direction_1Line_Rx ((uint16_t)0x8000) -#define SPI_Direction_1Line_Tx ((uint16_t)0xC000) -#define IS_SPI_DIRECTION_MODE(MODE) (((MODE) == SPI_Direction_2Lines_FullDuplex) || \ - ((MODE) == SPI_Direction_2Lines_RxOnly) || \ - ((MODE) == SPI_Direction_1Line_Rx) || \ - ((MODE) == SPI_Direction_1Line_Tx)) -/** - * @} - */ - -/** @defgroup SPI_mode - * @{ - */ - -#define SPI_Mode_Master ((uint16_t)0x0104) -#define SPI_Mode_Slave ((uint16_t)0x0000) -#define IS_SPI_MODE(MODE) (((MODE) == SPI_Mode_Master) || \ - ((MODE) == SPI_Mode_Slave)) -/** - * @} - */ - -/** @defgroup SPI_data_size - * @{ - */ - -#define SPI_DataSize_16b ((uint16_t)0x0800) -#define SPI_DataSize_8b ((uint16_t)0x0000) -#define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DataSize_16b) || \ - ((DATASIZE) == SPI_DataSize_8b)) -/** - * @} - */ - -/** @defgroup SPI_Clock_Polarity - * @{ - */ - -#define SPI_CPOL_Low ((uint16_t)0x0000) -#define SPI_CPOL_High ((uint16_t)0x0002) -#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_CPOL_Low) || \ - ((CPOL) == SPI_CPOL_High)) -/** - * @} - */ - -/** @defgroup SPI_Clock_Phase - * @{ - */ - -#define SPI_CPHA_1Edge ((uint16_t)0x0000) -#define SPI_CPHA_2Edge ((uint16_t)0x0001) -#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_CPHA_1Edge) || \ - ((CPHA) == SPI_CPHA_2Edge)) -/** - * @} - */ - -/** @defgroup SPI_Slave_Select_management - * @{ - */ - -#define SPI_NSS_Soft ((uint16_t)0x0200) -#define SPI_NSS_Hard ((uint16_t)0x0000) -#define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_Soft) || \ - ((NSS) == SPI_NSS_Hard)) -/** - * @} - */ - -/** @defgroup SPI_BaudRate_Prescaler - * @{ - */ - -#define SPI_BaudRatePrescaler_2 ((uint16_t)0x0000) -#define SPI_BaudRatePrescaler_4 ((uint16_t)0x0008) -#define SPI_BaudRatePrescaler_8 ((uint16_t)0x0010) -#define SPI_BaudRatePrescaler_16 ((uint16_t)0x0018) -#define SPI_BaudRatePrescaler_32 ((uint16_t)0x0020) -#define SPI_BaudRatePrescaler_64 ((uint16_t)0x0028) -#define SPI_BaudRatePrescaler_128 ((uint16_t)0x0030) -#define SPI_BaudRatePrescaler_256 ((uint16_t)0x0038) -#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BaudRatePrescaler_2) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_4) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_8) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_16) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_32) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_64) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_128) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_256)) -/** - * @} - */ - -/** @defgroup SPI_MSB_LSB_transmission - * @{ - */ - -#define SPI_FirstBit_MSB ((uint16_t)0x0000) -#define SPI_FirstBit_LSB ((uint16_t)0x0080) -#define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FirstBit_MSB) || \ - ((BIT) == SPI_FirstBit_LSB)) -/** - * @} - */ - -/** @defgroup SPI_I2S_DMA_transfer_requests - * @{ - */ - -#define SPI_I2S_DMAReq_Tx ((uint16_t)0x0002) -#define SPI_I2S_DMAReq_Rx ((uint16_t)0x0001) -#define IS_SPI_I2S_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFFFC) == 0x00) && ((DMAREQ) != 0x00)) -/** - * @} - */ - -/** @defgroup SPI_NSS_internal_software_management - * @{ - */ - -#define SPI_NSSInternalSoft_Set ((uint16_t)0x0100) -#define SPI_NSSInternalSoft_Reset ((uint16_t)0xFEFF) -#define IS_SPI_NSS_INTERNAL(INTERNAL) (((INTERNAL) == SPI_NSSInternalSoft_Set) || \ - ((INTERNAL) == SPI_NSSInternalSoft_Reset)) -/** - * @} - */ - -/** @defgroup SPI_CRC_Transmit_Receive - * @{ - */ - -#define SPI_CRC_Tx ((uint8_t)0x00) -#define SPI_CRC_Rx ((uint8_t)0x01) -#define IS_SPI_CRC(CRC) (((CRC) == SPI_CRC_Tx) || ((CRC) == SPI_CRC_Rx)) -/** - * @} - */ - -/** @defgroup SPI_direction_transmit_receive - * @{ - */ - -#define SPI_Direction_Rx ((uint16_t)0xBFFF) -#define SPI_Direction_Tx ((uint16_t)0x4000) -#define IS_SPI_DIRECTION(DIRECTION) (((DIRECTION) == SPI_Direction_Rx) || \ - ((DIRECTION) == SPI_Direction_Tx)) -/** - * @} - */ - -/** @defgroup SPI_I2S_interrupts_definition - * @{ - */ - -#define SPI_I2S_IT_TXE ((uint8_t)0x71) -#define SPI_I2S_IT_RXNE ((uint8_t)0x60) -#define SPI_I2S_IT_ERR ((uint8_t)0x50) -#define IS_SPI_I2S_CONFIG_IT(IT) (((IT) == SPI_I2S_IT_TXE) || \ - ((IT) == SPI_I2S_IT_RXNE) || \ - ((IT) == SPI_I2S_IT_ERR)) - -#define SPI_I2S_IT_OVR ((uint8_t)0x56) -#define SPI_IT_MODF ((uint8_t)0x55) -#define SPI_IT_CRCERR ((uint8_t)0x54) - -#define IS_SPI_I2S_CLEAR_IT(IT) (((IT) == SPI_IT_CRCERR)) - -#define IS_SPI_I2S_GET_IT(IT) (((IT) == SPI_I2S_IT_RXNE) || ((IT) == SPI_I2S_IT_TXE) || \ - ((IT) == SPI_IT_CRCERR) || ((IT) == SPI_IT_MODF) || \ - ((IT) == SPI_I2S_IT_OVR)) -/** - * @} - */ - -/** @defgroup SPI_I2S_flags_definition - * @{ - */ - -#define SPI_I2S_FLAG_RXNE ((uint16_t)0x0001) -#define SPI_I2S_FLAG_TXE ((uint16_t)0x0002) -#define SPI_FLAG_CRCERR ((uint16_t)0x0010) -#define SPI_FLAG_MODF ((uint16_t)0x0020) -#define SPI_I2S_FLAG_OVR ((uint16_t)0x0040) -#define SPI_I2S_FLAG_BSY ((uint16_t)0x0080) -#define IS_SPI_I2S_CLEAR_FLAG(FLAG) (((FLAG) == SPI_FLAG_CRCERR)) -#define IS_SPI_I2S_GET_FLAG(FLAG) (((FLAG) == SPI_I2S_FLAG_BSY) || ((FLAG) == SPI_I2S_FLAG_OVR) || \ - ((FLAG) == SPI_FLAG_MODF) || ((FLAG) == SPI_FLAG_CRCERR) || \ - ((FLAG) == SPI_I2S_FLAG_TXE) || ((FLAG) == SPI_I2S_FLAG_RXNE)) -/** - * @} - */ - -/** @defgroup SPI_CRC_polynomial - * @{ - */ - -#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) ((POLYNOMIAL) >= 0x1) -/** - * @} - */ - -/** @defgroup SPI_I2S_Legacy - * @{ - */ - -#define SPI_DMAReq_Tx SPI_I2S_DMAReq_Tx -#define SPI_DMAReq_Rx SPI_I2S_DMAReq_Rx -#define SPI_IT_TXE SPI_I2S_IT_TXE -#define SPI_IT_RXNE SPI_I2S_IT_RXNE -#define SPI_IT_ERR SPI_I2S_IT_ERR -#define SPI_IT_OVR SPI_I2S_IT_OVR -#define SPI_FLAG_RXNE SPI_I2S_FLAG_RXNE -#define SPI_FLAG_TXE SPI_I2S_FLAG_TXE -#define SPI_FLAG_OVR SPI_I2S_FLAG_OVR -#define SPI_FLAG_BSY SPI_I2S_FLAG_BSY -#define SPI_DeInit SPI_I2S_DeInit -#define SPI_ITConfig SPI_I2S_ITConfig -#define SPI_DMACmd SPI_I2S_DMACmd -#define SPI_SendData SPI_I2S_SendData -#define SPI_ReceiveData SPI_I2S_ReceiveData -#define SPI_GetFlagStatus SPI_I2S_GetFlagStatus -#define SPI_ClearFlag SPI_I2S_ClearFlag -#define SPI_GetITStatus SPI_I2S_GetITStatus -#define SPI_ClearITPendingBit SPI_I2S_ClearITPendingBit -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* Function used to set the SPI configuration to the default reset state *****/ -void SPI_I2S_DeInit(SPI_TypeDef* SPIx); - -/* Initialization and Configuration functions *********************************/ -void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct); -void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct); -void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); -void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize); -void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction); -void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft); -void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState); - -/* Data transfers functions ***************************************************/ -void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data); -uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx); - -/* Hardware CRC Calculation functions *****************************************/ -void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState); -void SPI_TransmitCRC(SPI_TypeDef* SPIx); -uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC); -uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx); - -/* DMA transfers management functions *****************************************/ -void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState); - -/* Interrupts and flags management functions **********************************/ -void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState); -FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); -void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); -ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); -void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32L1xx_SPI_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_syscfg.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_syscfg.h deleted file mode 100644 index 4b9229665..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_syscfg.h +++ /dev/null @@ -1,387 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_syscfg.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the SYSCFG - * firmware library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/*!< Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_SYSCFG_H -#define __STM32L1xx_SYSCFG_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*!< Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup SYSCFG - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup SYSCFG_Exported_Constants - * @{ - */ - -/** @defgroup EXTI_Port_Sources - * @{ - */ -#define EXTI_PortSourceGPIOA ((uint8_t)0x00) -#define EXTI_PortSourceGPIOB ((uint8_t)0x01) -#define EXTI_PortSourceGPIOC ((uint8_t)0x02) -#define EXTI_PortSourceGPIOD ((uint8_t)0x03) -#define EXTI_PortSourceGPIOE ((uint8_t)0x04) -#define EXTI_PortSourceGPIOH ((uint8_t)0x05) - -#define IS_EXTI_PORT_SOURCE(PORTSOURCE) (((PORTSOURCE) == EXTI_PortSourceGPIOA) || \ - ((PORTSOURCE) == EXTI_PortSourceGPIOB) || \ - ((PORTSOURCE) == EXTI_PortSourceGPIOC) || \ - ((PORTSOURCE) == EXTI_PortSourceGPIOD) || \ - ((PORTSOURCE) == EXTI_PortSourceGPIOE) || \ - ((PORTSOURCE) == EXTI_PortSourceGPIOH)) -/** - * @} - */ - -/** @defgroup EXTI_Pin_sources - * @{ - */ -#define EXTI_PinSource0 ((uint8_t)0x00) -#define EXTI_PinSource1 ((uint8_t)0x01) -#define EXTI_PinSource2 ((uint8_t)0x02) -#define EXTI_PinSource3 ((uint8_t)0x03) -#define EXTI_PinSource4 ((uint8_t)0x04) -#define EXTI_PinSource5 ((uint8_t)0x05) -#define EXTI_PinSource6 ((uint8_t)0x06) -#define EXTI_PinSource7 ((uint8_t)0x07) -#define EXTI_PinSource8 ((uint8_t)0x08) -#define EXTI_PinSource9 ((uint8_t)0x09) -#define EXTI_PinSource10 ((uint8_t)0x0A) -#define EXTI_PinSource11 ((uint8_t)0x0B) -#define EXTI_PinSource12 ((uint8_t)0x0C) -#define EXTI_PinSource13 ((uint8_t)0x0D) -#define EXTI_PinSource14 ((uint8_t)0x0E) -#define EXTI_PinSource15 ((uint8_t)0x0F) -#define IS_EXTI_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == EXTI_PinSource0) || \ - ((PINSOURCE) == EXTI_PinSource1) || \ - ((PINSOURCE) == EXTI_PinSource2) || \ - ((PINSOURCE) == EXTI_PinSource3) || \ - ((PINSOURCE) == EXTI_PinSource4) || \ - ((PINSOURCE) == EXTI_PinSource5) || \ - ((PINSOURCE) == EXTI_PinSource6) || \ - ((PINSOURCE) == EXTI_PinSource7) || \ - ((PINSOURCE) == EXTI_PinSource8) || \ - ((PINSOURCE) == EXTI_PinSource9) || \ - ((PINSOURCE) == EXTI_PinSource10) || \ - ((PINSOURCE) == EXTI_PinSource11) || \ - ((PINSOURCE) == EXTI_PinSource12) || \ - ((PINSOURCE) == EXTI_PinSource13) || \ - ((PINSOURCE) == EXTI_PinSource14) || \ - ((PINSOURCE) == EXTI_PinSource15)) -/** - * @} - */ - -/** @defgroup SYSCFG_Memory_Remap_Config - * @{ - */ -#define SYSCFG_MemoryRemap_Flash ((uint8_t)0x00) -#define SYSCFG_MemoryRemap_SystemFlash ((uint8_t)0x01) -#define SYSCFG_MemoryRemap_SRAM ((uint8_t)0x03) - -#define IS_SYSCFG_MEMORY_REMAP_CONFING(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \ - ((REMAP) == SYSCFG_MemoryRemap_SystemFlash) || \ - ((REMAP) == SYSCFG_MemoryRemap_SRAM)) - -/** - * @} - */ - -/** @defgroup RI_Resistor - * @{ - */ - -#define RI_Resistor_10KPU COMP_CSR_10KPU -#define RI_Resistor_400KPU COMP_CSR_400KPU -#define RI_Resistor_10KPD COMP_CSR_10KPD -#define RI_Resistor_400KPD COMP_CSR_400KPD - -#define IS_RI_RESISTOR(RESISTOR) (((RESISTOR) == COMP_CSR_10KPU) || \ - ((RESISTOR) == COMP_CSR_400KPU) || \ - ((RESISTOR) == COMP_CSR_10KPD) || \ - ((RESISTOR) == COMP_CSR_400KPD)) - -/** - * @} - */ - -/** @defgroup RI_InputCapture - * @{ - */ - -#define RI_InputCapture_IC1 RI_ICR_IC1 /*!< Input Capture 1 */ -#define RI_InputCapture_IC2 RI_ICR_IC2 /*!< Input Capture 2 */ -#define RI_InputCapture_IC3 RI_ICR_IC3 /*!< Input Capture 3 */ -#define RI_InputCapture_IC4 RI_ICR_IC4 /*!< Input Capture 4 */ - -#define IS_RI_INPUTCAPTURE(INPUTCAPTURE) ((((INPUTCAPTURE) & (uint32_t)0xFFC2FFFF) == 0x00) && ((INPUTCAPTURE) != (uint32_t)0x00)) -/** - * @} - */ - -/** @defgroup TIM_Select - * @{ - */ - -#define TIM_Select_None ((uint32_t)0x00000000) /*!< None selected */ -#define TIM_Select_TIM2 ((uint32_t)0x00010000) /*!< Timer 2 selected */ -#define TIM_Select_TIM3 ((uint32_t)0x00020000) /*!< Timer 3 selected */ -#define TIM_Select_TIM4 ((uint32_t)0x00030000) /*!< Timer 4 selected */ - -#define IS_RI_TIM(TIM) (((TIM) == TIM_Select_None) || \ - ((TIM) == TIM_Select_TIM2) || \ - ((TIM) == TIM_Select_TIM3) || \ - ((TIM) == TIM_Select_TIM4)) - -/** - * @} - */ - -/** @defgroup RI_InputCaptureRouting - * @{ - */ - /* TIMx_IC1 TIMx_IC2 TIMx_IC3 TIMx_IC4 */ -#define RI_InputCaptureRouting_0 ((uint32_t)0x00000000) /* PA0 PA1 PA2 PA3 */ -#define RI_InputCaptureRouting_1 ((uint32_t)0x00000001) /* PA4 PA5 PA6 PA7 */ -#define RI_InputCaptureRouting_2 ((uint32_t)0x00000002) /* PA8 PA9 PA10 PA11 */ -#define RI_InputCaptureRouting_3 ((uint32_t)0x00000003) /* PA12 PA13 PA14 PA15 */ -#define RI_InputCaptureRouting_4 ((uint32_t)0x00000004) /* PC0 PC1 PC2 PC3 */ -#define RI_InputCaptureRouting_5 ((uint32_t)0x00000005) /* PC4 PC5 PC6 PC7 */ -#define RI_InputCaptureRouting_6 ((uint32_t)0x00000006) /* PC8 PC9 PC10 PC11 */ -#define RI_InputCaptureRouting_7 ((uint32_t)0x00000007) /* PC12 PC13 PC14 PC15 */ -#define RI_InputCaptureRouting_8 ((uint32_t)0x00000008) /* PD0 PD1 PD2 PD3 */ -#define RI_InputCaptureRouting_9 ((uint32_t)0x00000009) /* PD4 PD5 PD6 PD7 */ -#define RI_InputCaptureRouting_10 ((uint32_t)0x0000000A) /* PD8 PD9 PD10 PD11 */ -#define RI_InputCaptureRouting_11 ((uint32_t)0x0000000B) /* PD12 PD13 PD14 PD15 */ -#define RI_InputCaptureRouting_12 ((uint32_t)0x0000000C) /* PE0 PE1 PE2 PE3 */ -#define RI_InputCaptureRouting_13 ((uint32_t)0x0000000D) /* PE4 PE5 PE6 PE7 */ -#define RI_InputCaptureRouting_14 ((uint32_t)0x0000000E) /* PE8 PE9 PE10 PE11 */ -#define RI_InputCaptureRouting_15 ((uint32_t)0x0000000F) /* PE12 PE13 PE14 PE15 */ - -#define IS_RI_INPUTCAPTURE_ROUTING(ROUTING) (((ROUTING) == RI_InputCaptureRouting_0) || \ - ((ROUTING) == RI_InputCaptureRouting_1) || \ - ((ROUTING) == RI_InputCaptureRouting_2) || \ - ((ROUTING) == RI_InputCaptureRouting_3) || \ - ((ROUTING) == RI_InputCaptureRouting_4) || \ - ((ROUTING) == RI_InputCaptureRouting_5) || \ - ((ROUTING) == RI_InputCaptureRouting_6) || \ - ((ROUTING) == RI_InputCaptureRouting_7) || \ - ((ROUTING) == RI_InputCaptureRouting_8) || \ - ((ROUTING) == RI_InputCaptureRouting_9) || \ - ((ROUTING) == RI_InputCaptureRouting_10) || \ - ((ROUTING) == RI_InputCaptureRouting_11) || \ - ((ROUTING) == RI_InputCaptureRouting_12) || \ - ((ROUTING) == RI_InputCaptureRouting_13) || \ - ((ROUTING) == RI_InputCaptureRouting_14) || \ - ((ROUTING) == RI_InputCaptureRouting_15)) - -/** - * @} - */ - -/** @defgroup RI_IOSwitch - * @{ - */ - -/* ASCR1 I/O switch: bit 31 is set to '1' to indicate that the mask is in ASCR1 register */ -#define RI_IOSwitch_CH0 ((uint32_t)0x80000001) -#define RI_IOSwitch_CH1 ((uint32_t)0x80000002) -#define RI_IOSwitch_CH2 ((uint32_t)0x80000004) -#define RI_IOSwitch_CH3 ((uint32_t)0x80000008) -#define RI_IOSwitch_CH4 ((uint32_t)0x80000010) -#define RI_IOSwitch_CH5 ((uint32_t)0x80000020) -#define RI_IOSwitch_CH6 ((uint32_t)0x80000040) -#define RI_IOSwitch_CH7 ((uint32_t)0x80000080) -#define RI_IOSwitch_CH8 ((uint32_t)0x80000100) -#define RI_IOSwitch_CH9 ((uint32_t)0x80000200) -#define RI_IOSwitch_CH10 ((uint32_t)0x80000400) -#define RI_IOSwitch_CH11 ((uint32_t)0x80000800) -#define RI_IOSwitch_CH12 ((uint32_t)0x80001000) -#define RI_IOSwitch_CH13 ((uint32_t)0x80002000) -#define RI_IOSwitch_CH14 ((uint32_t)0x80004000) -#define RI_IOSwitch_CH15 ((uint32_t)0x80008000) -#define RI_IOSwitch_CH18 ((uint32_t)0x80040000) -#define RI_IOSwitch_CH19 ((uint32_t)0x80080000) -#define RI_IOSwitch_CH20 ((uint32_t)0x80100000) -#define RI_IOSwitch_CH21 ((uint32_t)0x80200000) -#define RI_IOSwitch_CH22 ((uint32_t)0x80400000) -#define RI_IOSwitch_CH23 ((uint32_t)0x80800000) -#define RI_IOSwitch_CH24 ((uint32_t)0x81000000) -#define RI_IOSwitch_CH25 ((uint32_t)0x82000000) -#define RI_IOSwitch_VCOMP ((uint32_t)0x84000000) /* VCOMP is an internal switch used to connect - selected channel to COMP1 non inverting input */ - -/* ASCR2 IO switch: bit 31 is set to '0' to indicate that the mask is in ASCR2 register */ -#define RI_IOSwitch_GR10_1 ((uint32_t)0x00000001) -#define RI_IOSwitch_GR10_2 ((uint32_t)0x00000002) -#define RI_IOSwitch_GR10_3 ((uint32_t)0x00000004) -#define RI_IOSwitch_GR10_4 ((uint32_t)0x00000008) -#define RI_IOSwitch_GR6_1 ((uint32_t)0x00000010) -#define RI_IOSwitch_GR6_2 ((uint32_t)0x00000020) -#define RI_IOSwitch_GR5_1 ((uint32_t)0x00000040) -#define RI_IOSwitch_GR5_2 ((uint32_t)0x00000080) -#define RI_IOSwitch_GR5_3 ((uint32_t)0x00000100) -#define RI_IOSwitch_GR4_1 ((uint32_t)0x00000200) -#define RI_IOSwitch_GR4_2 ((uint32_t)0x00000400) -#define RI_IOSwitch_GR4_3 ((uint32_t)0x00000800) - -#define IS_RI_IOSWITCH(IOSWITCH) (((IOSWITCH) == RI_IOSwitch_CH0) || \ - ((IOSWITCH) == RI_IOSwitch_CH1) || \ - ((IOSWITCH) == RI_IOSwitch_CH2) || \ - ((IOSWITCH) == RI_IOSwitch_CH3) || \ - ((IOSWITCH) == RI_IOSwitch_CH4) || \ - ((IOSWITCH) == RI_IOSwitch_CH5) || \ - ((IOSWITCH) == RI_IOSwitch_CH6) || \ - ((IOSWITCH) == RI_IOSwitch_CH7) || \ - ((IOSWITCH) == RI_IOSwitch_CH8) || \ - ((IOSWITCH) == RI_IOSwitch_CH9) || \ - ((IOSWITCH) == RI_IOSwitch_CH10) || \ - ((IOSWITCH) == RI_IOSwitch_CH11) || \ - ((IOSWITCH) == RI_IOSwitch_CH12) || \ - ((IOSWITCH) == RI_IOSwitch_CH13) || \ - ((IOSWITCH) == RI_IOSwitch_CH14) || \ - ((IOSWITCH) == RI_IOSwitch_CH15) || \ - ((IOSWITCH) == RI_IOSwitch_CH18) || \ - ((IOSWITCH) == RI_IOSwitch_CH19) || \ - ((IOSWITCH) == RI_IOSwitch_CH20) || \ - ((IOSWITCH) == RI_IOSwitch_CH21) || \ - ((IOSWITCH) == RI_IOSwitch_CH22) || \ - ((IOSWITCH) == RI_IOSwitch_CH23) || \ - ((IOSWITCH) == RI_IOSwitch_CH24) || \ - ((IOSWITCH) == RI_IOSwitch_CH25) || \ - ((IOSWITCH) == RI_IOSwitch_VCOMP) || \ - ((IOSWITCH) == RI_IOSwitch_GR10_1) || \ - ((IOSWITCH) == RI_IOSwitch_GR10_2) || \ - ((IOSWITCH) == RI_IOSwitch_GR10_3) || \ - ((IOSWITCH) == RI_IOSwitch_GR10_4) || \ - ((IOSWITCH) == RI_IOSwitch_GR6_1) || \ - ((IOSWITCH) == RI_IOSwitch_GR6_2) || \ - ((IOSWITCH) == RI_IOSwitch_GR5_1) || \ - ((IOSWITCH) == RI_IOSwitch_GR5_2) || \ - ((IOSWITCH) == RI_IOSwitch_GR5_3) || \ - ((IOSWITCH) == RI_IOSwitch_GR4_1) || \ - ((IOSWITCH) == RI_IOSwitch_GR4_2) || \ - ((IOSWITCH) == RI_IOSwitch_GR4_3)) - -/** - * @} - */ - -/** @defgroup RI_Port - * @{ - */ - -#define RI_PortA ((uint8_t)0x01) /*!< GPIOA selected */ -#define RI_PortB ((uint8_t)0x02) /*!< GPIOB selected */ -#define RI_PortC ((uint8_t)0x03) /*!< GPIOC selected */ -#define RI_PortD ((uint8_t)0x04) /*!< GPIOD selected */ -#define RI_PortE ((uint8_t)0x05) /*!< GPIOE selected */ - -#define IS_RI_PORT(PORT) (((PORT) == RI_PortA) || \ - ((PORT) == RI_PortB) || \ - ((PORT) == RI_PortC) || \ - ((PORT) == RI_PortD) || \ - ((PORT) == RI_PortE)) -/** - * @} - */ - -/** @defgroup RI_Pin define - * @{ - */ -#define RI_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */ -#define RI_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */ -#define RI_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */ -#define RI_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */ -#define RI_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */ -#define RI_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */ -#define RI_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */ -#define RI_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */ -#define RI_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */ -#define RI_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */ -#define RI_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */ -#define RI_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */ -#define RI_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */ -#define RI_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */ -#define RI_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */ -#define RI_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */ -#define RI_Pin_All ((uint16_t)0xFFFF) /*!< All pins selected */ - -#define IS_RI_PIN(PIN) ((PIN) != (uint16_t)0x00) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* Function used to set the RTC configuration to the default reset state *****/ -void SYSCFG_DeInit(void); -void SYSCFG_RIDeInit(void); - -/* SYSCFG Initialization and Configuration functions **************************/ -void SYSCFG_MemoryRemapConfig(uint8_t SYSCFG_MemoryRemap); -void SYSCFG_USBPuCmd(FunctionalState NewState); -void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex); - -/* RI Initialization and Configuration functions ******************************/ -void SYSCFG_RITIMSelect(uint32_t TIM_Select); -void SYSCFG_RITIMInputCaptureConfig(uint32_t RI_InputCapture, uint32_t RI_InputCaptureRouting); -void SYSCFG_RIResistorConfig(uint32_t RI_Resistor, FunctionalState NewState); -void SYSCFG_RISwitchControlModeCmd(FunctionalState NewState); -void SYSCFG_RIIOSwitchConfig(uint32_t RI_IOSwitch, FunctionalState NewState); -void SYSCFG_RIHysteresisConfig(uint8_t RI_Port, uint16_t RI_Pin, - FunctionalState NewState); -#ifdef __cplusplus -} -#endif - -#endif /*__STM32L1xx_SYSCFG_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_tim.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_tim.h deleted file mode 100644 index a67ef9ac1..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_tim.h +++ /dev/null @@ -1,907 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_tim.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the TIM firmware - * library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_TIM_H -#define __STM32L1xx_TIM_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup TIM - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief TIM Time Base Init structure definition - * @note This structure is used with all TIMx except for TIM6 and TIM7. - */ - -typedef struct -{ - uint16_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. - This parameter can be a number between 0x0000 and 0xFFFF */ - - uint16_t TIM_CounterMode; /*!< Specifies the counter mode. - This parameter can be a value of @ref TIM_Counter_Mode */ - - uint16_t TIM_Period; /*!< Specifies the period value to be loaded into the active - Auto-Reload Register at the next update event. - This parameter must be a number between 0x0000 and 0xFFFF. */ - - uint16_t TIM_ClockDivision; /*!< Specifies the clock division. - This parameter can be a value of @ref TIM_Clock_Division_CKD */ - -} TIM_TimeBaseInitTypeDef; - -/** - * @brief TIM Output Compare Init structure definition - */ - -typedef struct -{ - uint16_t TIM_OCMode; /*!< Specifies the TIM mode. - This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ - - uint16_t TIM_OutputState; /*!< Specifies the TIM Output Compare state. - This parameter can be a value of @ref TIM_Output_Compare_state */ - - uint16_t TIM_Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. - This parameter can be a number between 0x0000 and 0xFFFF */ - - uint16_t TIM_OCPolarity; /*!< Specifies the output polarity. - This parameter can be a value of @ref TIM_Output_Compare_Polarity */ - -} TIM_OCInitTypeDef; - -/** - * @brief TIM Input Capture Init structure definition - */ - -typedef struct -{ - - uint16_t TIM_Channel; /*!< Specifies the TIM channel. - This parameter can be a value of @ref TIM_Channel */ - - uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal. - This parameter can be a value of @ref TIM_Input_Capture_Polarity */ - - uint16_t TIM_ICSelection; /*!< Specifies the input. - This parameter can be a value of @ref TIM_Input_Capture_Selection */ - - uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler. - This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ - - uint16_t TIM_ICFilter; /*!< Specifies the input capture filter. - This parameter can be a number between 0x0 and 0xF */ -} TIM_ICInitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - - -/** @defgroup TIM_Exported_constants - * @{ - */ - -#define IS_TIM_ALL_PERIPH(PERIPH) (((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM6) || \ - ((PERIPH) == TIM7) || \ - ((PERIPH) == TIM9) || \ - ((PERIPH) == TIM10) || \ - ((PERIPH) == TIM11)) - -/* LIST1: TIM2, TIM3, TIM4, TIM9, TIM10 and TIM11 */ -#define IS_TIM_LIST1_PERIPH(PERIPH) (((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM9) || \ - ((PERIPH) == TIM10) || \ - ((PERIPH) == TIM11)) - -/* LIST3: TIM2, TIM3 and TIM4 */ -#define IS_TIM_LIST3_PERIPH(PERIPH) (((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4)) - -/* LIST2: TIM2, TIM3, TIM4 and TIM9 */ -#define IS_TIM_LIST2_PERIPH(PERIPH) (((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) ||\ - ((PERIPH) == TIM9)) - -/* LIST5: TIM2, TIM3, TIM4, TIM6, TIM7 and TIM9 */ -#define IS_TIM_LIST5_PERIPH(PERIPH) (((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) ||\ - ((PERIPH) == TIM6) || \ - ((PERIPH) == TIM7) ||\ - ((PERIPH) == TIM9)) - -/* LIST4: TIM2, TIM3, TIM4, TIM6 and TIM7 */ -#define IS_TIM_LIST4_PERIPH(PERIPH) (((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) ||\ - ((PERIPH) == TIM6) || \ - ((PERIPH) == TIM7)) - -/* LIST6: TIM9, TIM10 and TIM11 */ -#define IS_TIM_LIST6_PERIPH(PERIPH) (((PERIPH) == TIM9) || \ - ((PERIPH) == TIM10) ||\ - ((PERIPH) == TIM11)) - - - -/** @defgroup TIM_Output_Compare_and_PWM_modes - * @{ - */ - -#define TIM_OCMode_Timing ((uint16_t)0x0000) -#define TIM_OCMode_Active ((uint16_t)0x0010) -#define TIM_OCMode_Inactive ((uint16_t)0x0020) -#define TIM_OCMode_Toggle ((uint16_t)0x0030) -#define TIM_OCMode_PWM1 ((uint16_t)0x0060) -#define TIM_OCMode_PWM2 ((uint16_t)0x0070) -#define IS_TIM_OC_MODE(MODE) (((MODE) == TIM_OCMode_Timing) || \ - ((MODE) == TIM_OCMode_Active) || \ - ((MODE) == TIM_OCMode_Inactive) || \ - ((MODE) == TIM_OCMode_Toggle)|| \ - ((MODE) == TIM_OCMode_PWM1) || \ - ((MODE) == TIM_OCMode_PWM2)) -#define IS_TIM_OCM(MODE) (((MODE) == TIM_OCMode_Timing) || \ - ((MODE) == TIM_OCMode_Active) || \ - ((MODE) == TIM_OCMode_Inactive) || \ - ((MODE) == TIM_OCMode_Toggle)|| \ - ((MODE) == TIM_OCMode_PWM1) || \ - ((MODE) == TIM_OCMode_PWM2) || \ - ((MODE) == TIM_ForcedAction_Active) || \ - ((MODE) == TIM_ForcedAction_InActive)) -/** - * @} - */ - -/** @defgroup TIM_One_Pulse_Mode - * @{ - */ - -#define TIM_OPMode_Single ((uint16_t)0x0008) -#define TIM_OPMode_Repetitive ((uint16_t)0x0000) -#define IS_TIM_OPM_MODE(MODE) (((MODE) == TIM_OPMode_Single) || \ - ((MODE) == TIM_OPMode_Repetitive)) -/** - * @} - */ - -/** @defgroup TIM_Channel - * @{ - */ - -#define TIM_Channel_1 ((uint16_t)0x0000) -#define TIM_Channel_2 ((uint16_t)0x0004) -#define TIM_Channel_3 ((uint16_t)0x0008) -#define TIM_Channel_4 ((uint16_t)0x000C) - -#define IS_TIM_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ - ((CHANNEL) == TIM_Channel_2) || \ - ((CHANNEL) == TIM_Channel_3) || \ - ((CHANNEL) == TIM_Channel_4)) - -#define IS_TIM_PWMI_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ - ((CHANNEL) == TIM_Channel_2)) - -/** - * @} - */ - -/** @defgroup TIM_Clock_Division_CKD - * @{ - */ - -#define TIM_CKD_DIV1 ((uint16_t)0x0000) -#define TIM_CKD_DIV2 ((uint16_t)0x0100) -#define TIM_CKD_DIV4 ((uint16_t)0x0200) -#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \ - ((DIV) == TIM_CKD_DIV2) || \ - ((DIV) == TIM_CKD_DIV4)) -/** - * @} - */ - -/** @defgroup TIM_Counter_Mode - * @{ - */ - -#define TIM_CounterMode_Up ((uint16_t)0x0000) -#define TIM_CounterMode_Down ((uint16_t)0x0010) -#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020) -#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040) -#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060) -#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) || \ - ((MODE) == TIM_CounterMode_Down) || \ - ((MODE) == TIM_CounterMode_CenterAligned1) || \ - ((MODE) == TIM_CounterMode_CenterAligned2) || \ - ((MODE) == TIM_CounterMode_CenterAligned3)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_Polarity - * @{ - */ - -#define TIM_OCPolarity_High ((uint16_t)0x0000) -#define TIM_OCPolarity_Low ((uint16_t)0x0002) -#define IS_TIM_OC_POLARITY(POLARITY) (((POLARITY) == TIM_OCPolarity_High) || \ - ((POLARITY) == TIM_OCPolarity_Low)) -/** - * @} - */ - - -/** @defgroup TIM_Output_Compare_state - * @{ - */ - -#define TIM_OutputState_Disable ((uint16_t)0x0000) -#define TIM_OutputState_Enable ((uint16_t)0x0001) -#define IS_TIM_OUTPUT_STATE(STATE) (((STATE) == TIM_OutputState_Disable) || \ - ((STATE) == TIM_OutputState_Enable)) -/** - * @} - */ - - -/** @defgroup TIM_Capture_Compare_state - * @{ - */ - -#define TIM_CCx_Enable ((uint16_t)0x0001) -#define TIM_CCx_Disable ((uint16_t)0x0000) -#define IS_TIM_CCX(CCX) (((CCX) == TIM_CCx_Enable) || \ - ((CCX) == TIM_CCx_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Input_Capture_Polarity - * @{ - */ - -#define TIM_ICPolarity_Rising ((uint16_t)0x0000) -#define TIM_ICPolarity_Falling ((uint16_t)0x0002) -#define TIM_ICPolarity_BothEdge ((uint16_t)0x000A) -#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \ - ((POLARITY) == TIM_ICPolarity_Falling)|| \ - ((POLARITY) == TIM_ICPolarity_BothEdge)) -/** - * @} - */ - -/** @defgroup TIM_Input_Capture_Selection - * @{ - */ - -#define TIM_ICSelection_DirectTI ((uint16_t)0x0001) /*!< TIM Input 1, 2, 3 or 4 is selected to be - connected to IC1, IC2, IC3 or IC4, respectively */ -#define TIM_ICSelection_IndirectTI ((uint16_t)0x0002) /*!< TIM Input 1, 2, 3 or 4 is selected to be - connected to IC2, IC1, IC4 or IC3, respectively. */ -#define TIM_ICSelection_TRC ((uint16_t)0x0003) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC. */ -#define IS_TIM_IC_SELECTION(SELECTION) (((SELECTION) == TIM_ICSelection_DirectTI) || \ - ((SELECTION) == TIM_ICSelection_IndirectTI) || \ - ((SELECTION) == TIM_ICSelection_TRC)) -/** - * @} - */ - -/** @defgroup TIM_Input_Capture_Prescaler - * @{ - */ - -#define TIM_ICPSC_DIV1 ((uint16_t)0x0000) /*!< Capture performed each time an edge is detected on the capture input. */ -#define TIM_ICPSC_DIV2 ((uint16_t)0x0004) /*!< Capture performed once every 2 events. */ -#define TIM_ICPSC_DIV4 ((uint16_t)0x0008) /*!< Capture performed once every 4 events. */ -#define TIM_ICPSC_DIV8 ((uint16_t)0x000C) /*!< Capture performed once every 8 events. */ -#define IS_TIM_IC_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ICPSC_DIV1) || \ - ((PRESCALER) == TIM_ICPSC_DIV2) || \ - ((PRESCALER) == TIM_ICPSC_DIV4) || \ - ((PRESCALER) == TIM_ICPSC_DIV8)) -/** - * @} - */ - -/** @defgroup TIM_interrupt_sources - * @{ - */ - -#define TIM_IT_Update ((uint16_t)0x0001) -#define TIM_IT_CC1 ((uint16_t)0x0002) -#define TIM_IT_CC2 ((uint16_t)0x0004) -#define TIM_IT_CC3 ((uint16_t)0x0008) -#define TIM_IT_CC4 ((uint16_t)0x0010) -#define TIM_IT_Trigger ((uint16_t)0x0040) -#define IS_TIM_IT(IT) ((((IT) & (uint16_t)0xFFA0) == 0x0000) && ((IT) != 0x0000)) - -#define IS_TIM_GET_IT(IT) (((IT) == TIM_IT_Update) || \ - ((IT) == TIM_IT_CC1) || \ - ((IT) == TIM_IT_CC2) || \ - ((IT) == TIM_IT_CC3) || \ - ((IT) == TIM_IT_CC4) || \ - ((IT) == TIM_IT_Trigger)) -/** - * @} - */ - -/** @defgroup TIM_DMA_Base_address - * @{ - */ - -#define TIM_DMABase_CR1 ((uint16_t)0x0000) -#define TIM_DMABase_CR2 ((uint16_t)0x0001) -#define TIM_DMABase_SMCR ((uint16_t)0x0002) -#define TIM_DMABase_DIER ((uint16_t)0x0003) -#define TIM_DMABase_SR ((uint16_t)0x0004) -#define TIM_DMABase_EGR ((uint16_t)0x0005) -#define TIM_DMABase_CCMR1 ((uint16_t)0x0006) -#define TIM_DMABase_CCMR2 ((uint16_t)0x0007) -#define TIM_DMABase_CCER ((uint16_t)0x0008) -#define TIM_DMABase_CNT ((uint16_t)0x0009) -#define TIM_DMABase_PSC ((uint16_t)0x000A) -#define TIM_DMABase_ARR ((uint16_t)0x000B) -#define TIM_DMABase_RCR ((uint16_t)0x000C) -#define TIM_DMABase_CCR1 ((uint16_t)0x000D) -#define TIM_DMABase_CCR2 ((uint16_t)0x000E) -#define TIM_DMABase_CCR3 ((uint16_t)0x000F) -#define TIM_DMABase_CCR4 ((uint16_t)0x0010) -#define TIM_DMABase_DCR ((uint16_t)0x0012) -#define IS_TIM_DMA_BASE(BASE) (((BASE) == TIM_DMABase_CR1) || \ - ((BASE) == TIM_DMABase_CR2) || \ - ((BASE) == TIM_DMABase_SMCR) || \ - ((BASE) == TIM_DMABase_DIER) || \ - ((BASE) == TIM_DMABase_SR) || \ - ((BASE) == TIM_DMABase_EGR) || \ - ((BASE) == TIM_DMABase_CCMR1) || \ - ((BASE) == TIM_DMABase_CCMR2) || \ - ((BASE) == TIM_DMABase_CCER) || \ - ((BASE) == TIM_DMABase_CNT) || \ - ((BASE) == TIM_DMABase_PSC) || \ - ((BASE) == TIM_DMABase_ARR) || \ - ((BASE) == TIM_DMABase_CCR1) || \ - ((BASE) == TIM_DMABase_CCR2) || \ - ((BASE) == TIM_DMABase_CCR3) || \ - ((BASE) == TIM_DMABase_CCR4) || \ - ((BASE) == TIM_DMABase_DCR)) -/** - * @} - */ - -/** @defgroup TIM_DMA_Burst_Length - * @{ - */ - -#define TIM_DMABurstLength_1Byte ((uint16_t)0x0000) -#define TIM_DMABurstLength_2Bytes ((uint16_t)0x0100) -#define TIM_DMABurstLength_3Bytes ((uint16_t)0x0200) -#define TIM_DMABurstLength_4Bytes ((uint16_t)0x0300) -#define TIM_DMABurstLength_5Bytes ((uint16_t)0x0400) -#define TIM_DMABurstLength_6Bytes ((uint16_t)0x0500) -#define TIM_DMABurstLength_7Bytes ((uint16_t)0x0600) -#define TIM_DMABurstLength_8Bytes ((uint16_t)0x0700) -#define TIM_DMABurstLength_9Bytes ((uint16_t)0x0800) -#define TIM_DMABurstLength_10Bytes ((uint16_t)0x0900) -#define TIM_DMABurstLength_11Bytes ((uint16_t)0x0A00) -#define TIM_DMABurstLength_12Bytes ((uint16_t)0x0B00) -#define TIM_DMABurstLength_13Bytes ((uint16_t)0x0C00) -#define TIM_DMABurstLength_14Bytes ((uint16_t)0x0D00) -#define TIM_DMABurstLength_15Bytes ((uint16_t)0x0E00) -#define TIM_DMABurstLength_16Bytes ((uint16_t)0x0F00) -#define TIM_DMABurstLength_17Bytes ((uint16_t)0x1000) -#define TIM_DMABurstLength_18Bytes ((uint16_t)0x1100) -#define IS_TIM_DMA_LENGTH(LENGTH) (((LENGTH) == TIM_DMABurstLength_1Byte) || \ - ((LENGTH) == TIM_DMABurstLength_2Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_3Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_4Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_5Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_6Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_7Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_8Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_9Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_10Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_11Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_12Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_13Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_14Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_15Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_16Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_17Bytes) || \ - ((LENGTH) == TIM_DMABurstLength_18Bytes)) -/** - * @} - */ - -/** @defgroup TIM_DMA_sources - * @{ - */ - -#define TIM_DMA_Update ((uint16_t)0x0100) -#define TIM_DMA_CC1 ((uint16_t)0x0200) -#define TIM_DMA_CC2 ((uint16_t)0x0400) -#define TIM_DMA_CC3 ((uint16_t)0x0800) -#define TIM_DMA_CC4 ((uint16_t)0x1000) -#define TIM_DMA_Trigger ((uint16_t)0x4000) -#define IS_TIM_DMA_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0xA0FF) == 0x0000) && ((SOURCE) != 0x0000)) - -/** - * @} - */ - -/** @defgroup TIM_External_Trigger_Prescaler - * @{ - */ - -#define TIM_ExtTRGPSC_OFF ((uint16_t)0x0000) -#define TIM_ExtTRGPSC_DIV2 ((uint16_t)0x1000) -#define TIM_ExtTRGPSC_DIV4 ((uint16_t)0x2000) -#define TIM_ExtTRGPSC_DIV8 ((uint16_t)0x3000) -#define IS_TIM_EXT_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ExtTRGPSC_OFF) || \ - ((PRESCALER) == TIM_ExtTRGPSC_DIV2) || \ - ((PRESCALER) == TIM_ExtTRGPSC_DIV4) || \ - ((PRESCALER) == TIM_ExtTRGPSC_DIV8)) -/** - * @} - */ - -/** @defgroup TIM_Internal_Trigger_Selection - * @{ - */ - -#define TIM_TS_ITR0 ((uint16_t)0x0000) -#define TIM_TS_ITR1 ((uint16_t)0x0010) -#define TIM_TS_ITR2 ((uint16_t)0x0020) -#define TIM_TS_ITR3 ((uint16_t)0x0030) -#define TIM_TS_TI1F_ED ((uint16_t)0x0040) -#define TIM_TS_TI1FP1 ((uint16_t)0x0050) -#define TIM_TS_TI2FP2 ((uint16_t)0x0060) -#define TIM_TS_ETRF ((uint16_t)0x0070) -#define IS_TIM_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ - ((SELECTION) == TIM_TS_ITR1) || \ - ((SELECTION) == TIM_TS_ITR2) || \ - ((SELECTION) == TIM_TS_ITR3) || \ - ((SELECTION) == TIM_TS_TI1F_ED) || \ - ((SELECTION) == TIM_TS_TI1FP1) || \ - ((SELECTION) == TIM_TS_TI2FP2) || \ - ((SELECTION) == TIM_TS_ETRF)) -#define IS_TIM_INTERNAL_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ - ((SELECTION) == TIM_TS_ITR1) || \ - ((SELECTION) == TIM_TS_ITR2) || \ - ((SELECTION) == TIM_TS_ITR3)) -/** - * @} - */ - -/** @defgroup TIM_TIx_External_Clock_Source - * @{ - */ - -#define TIM_TIxExternalCLK1Source_TI1 ((uint16_t)0x0050) -#define TIM_TIxExternalCLK1Source_TI2 ((uint16_t)0x0060) -#define TIM_TIxExternalCLK1Source_TI1ED ((uint16_t)0x0040) - -/** - * @} - */ - -/** @defgroup TIM_External_Trigger_Polarity - * @{ - */ -#define TIM_ExtTRGPolarity_Inverted ((uint16_t)0x8000) -#define TIM_ExtTRGPolarity_NonInverted ((uint16_t)0x0000) -#define IS_TIM_EXT_POLARITY(POLARITY) (((POLARITY) == TIM_ExtTRGPolarity_Inverted) || \ - ((POLARITY) == TIM_ExtTRGPolarity_NonInverted)) -/** - * @} - */ - -/** @defgroup TIM_Prescaler_Reload_Mode - * @{ - */ - -#define TIM_PSCReloadMode_Update ((uint16_t)0x0000) -#define TIM_PSCReloadMode_Immediate ((uint16_t)0x0001) -#define IS_TIM_PRESCALER_RELOAD(RELOAD) (((RELOAD) == TIM_PSCReloadMode_Update) || \ - ((RELOAD) == TIM_PSCReloadMode_Immediate)) -/** - * @} - */ - -/** @defgroup TIM_Forced_Action - * @{ - */ - -#define TIM_ForcedAction_Active ((uint16_t)0x0050) -#define TIM_ForcedAction_InActive ((uint16_t)0x0040) -#define IS_TIM_FORCED_ACTION(ACTION) (((ACTION) == TIM_ForcedAction_Active) || \ - ((ACTION) == TIM_ForcedAction_InActive)) -/** - * @} - */ - -/** @defgroup TIM_Encoder_Mode - * @{ - */ - -#define TIM_EncoderMode_TI1 ((uint16_t)0x0001) -#define TIM_EncoderMode_TI2 ((uint16_t)0x0002) -#define TIM_EncoderMode_TI12 ((uint16_t)0x0003) -#define IS_TIM_ENCODER_MODE(MODE) (((MODE) == TIM_EncoderMode_TI1) || \ - ((MODE) == TIM_EncoderMode_TI2) || \ - ((MODE) == TIM_EncoderMode_TI12)) -/** - * @} - */ - - -/** @defgroup TIM_Event_Source - * @{ - */ - -#define TIM_EventSource_Update ((uint16_t)0x0001) -#define TIM_EventSource_CC1 ((uint16_t)0x0002) -#define TIM_EventSource_CC2 ((uint16_t)0x0004) -#define TIM_EventSource_CC3 ((uint16_t)0x0008) -#define TIM_EventSource_CC4 ((uint16_t)0x0010) -#define TIM_EventSource_Trigger ((uint16_t)0x0040) -#define IS_TIM_EVENT_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0xFFA0) == 0x0000) && ((SOURCE) != 0x0000)) - -/** - * @} - */ - -/** @defgroup TIM_Update_Source - * @{ - */ - -#define TIM_UpdateSource_Global ((uint16_t)0x0000) /*!< Source of update is the counter overflow/underflow - or the setting of UG bit, or an update generation - through the slave mode controller. */ -#define TIM_UpdateSource_Regular ((uint16_t)0x0001) /*!< Source of update is counter overflow/underflow. */ -#define IS_TIM_UPDATE_SOURCE(SOURCE) (((SOURCE) == TIM_UpdateSource_Global) || \ - ((SOURCE) == TIM_UpdateSource_Regular)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_Preload_State - * @{ - */ - -#define TIM_OCPreload_Enable ((uint16_t)0x0008) -#define TIM_OCPreload_Disable ((uint16_t)0x0000) -#define IS_TIM_OCPRELOAD_STATE(STATE) (((STATE) == TIM_OCPreload_Enable) || \ - ((STATE) == TIM_OCPreload_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_Fast_State - * @{ - */ - -#define TIM_OCFast_Enable ((uint16_t)0x0004) -#define TIM_OCFast_Disable ((uint16_t)0x0000) -#define IS_TIM_OCFAST_STATE(STATE) (((STATE) == TIM_OCFast_Enable) || \ - ((STATE) == TIM_OCFast_Disable)) - -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_Clear_State - * @{ - */ - -#define TIM_OCClear_Enable ((uint16_t)0x0080) -#define TIM_OCClear_Disable ((uint16_t)0x0000) -#define IS_TIM_OCCLEAR_STATE(STATE) (((STATE) == TIM_OCClear_Enable) || \ - ((STATE) == TIM_OCClear_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Trigger_Output_Source - * @{ - */ - -#define TIM_TRGOSource_Reset ((uint16_t)0x0000) -#define TIM_TRGOSource_Enable ((uint16_t)0x0010) -#define TIM_TRGOSource_Update ((uint16_t)0x0020) -#define TIM_TRGOSource_OC1 ((uint16_t)0x0030) -#define TIM_TRGOSource_OC1Ref ((uint16_t)0x0040) -#define TIM_TRGOSource_OC2Ref ((uint16_t)0x0050) -#define TIM_TRGOSource_OC3Ref ((uint16_t)0x0060) -#define TIM_TRGOSource_OC4Ref ((uint16_t)0x0070) -#define IS_TIM_TRGO_SOURCE(SOURCE) (((SOURCE) == TIM_TRGOSource_Reset) || \ - ((SOURCE) == TIM_TRGOSource_Enable) || \ - ((SOURCE) == TIM_TRGOSource_Update) || \ - ((SOURCE) == TIM_TRGOSource_OC1) || \ - ((SOURCE) == TIM_TRGOSource_OC1Ref) || \ - ((SOURCE) == TIM_TRGOSource_OC2Ref) || \ - ((SOURCE) == TIM_TRGOSource_OC3Ref) || \ - ((SOURCE) == TIM_TRGOSource_OC4Ref)) -/** - * @} - */ - -/** @defgroup TIM_Slave_Mode - * @{ - */ - -#define TIM_SlaveMode_Reset ((uint16_t)0x0004) -#define TIM_SlaveMode_Gated ((uint16_t)0x0005) -#define TIM_SlaveMode_Trigger ((uint16_t)0x0006) -#define TIM_SlaveMode_External1 ((uint16_t)0x0007) -#define IS_TIM_SLAVE_MODE(MODE) (((MODE) == TIM_SlaveMode_Reset) || \ - ((MODE) == TIM_SlaveMode_Gated) || \ - ((MODE) == TIM_SlaveMode_Trigger) || \ - ((MODE) == TIM_SlaveMode_External1)) -/** - * @} - */ - -/** @defgroup TIM_Master_Slave_Mode - * @{ - */ - -#define TIM_MasterSlaveMode_Enable ((uint16_t)0x0080) -#define TIM_MasterSlaveMode_Disable ((uint16_t)0x0000) -#define IS_TIM_MSM_STATE(STATE) (((STATE) == TIM_MasterSlaveMode_Enable) || \ - ((STATE) == TIM_MasterSlaveMode_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Flags - * @{ - */ - -#define TIM_FLAG_Update ((uint16_t)0x0001) -#define TIM_FLAG_CC1 ((uint16_t)0x0002) -#define TIM_FLAG_CC2 ((uint16_t)0x0004) -#define TIM_FLAG_CC3 ((uint16_t)0x0008) -#define TIM_FLAG_CC4 ((uint16_t)0x0010) -#define TIM_FLAG_Trigger ((uint16_t)0x0040) -#define TIM_FLAG_CC1OF ((uint16_t)0x0200) -#define TIM_FLAG_CC2OF ((uint16_t)0x0400) -#define TIM_FLAG_CC3OF ((uint16_t)0x0800) -#define TIM_FLAG_CC4OF ((uint16_t)0x1000) -#define IS_TIM_GET_FLAG(FLAG) (((FLAG) == TIM_FLAG_Update) || \ - ((FLAG) == TIM_FLAG_CC1) || \ - ((FLAG) == TIM_FLAG_CC2) || \ - ((FLAG) == TIM_FLAG_CC3) || \ - ((FLAG) == TIM_FLAG_CC4) || \ - ((FLAG) == TIM_FLAG_Trigger) || \ - ((FLAG) == TIM_FLAG_CC1OF) || \ - ((FLAG) == TIM_FLAG_CC2OF) || \ - ((FLAG) == TIM_FLAG_CC3OF) || \ - ((FLAG) == TIM_FLAG_CC4OF)) -#define IS_TIM_CLEAR_FLAG(TIM_FLAG) ((((TIM_FLAG) & (uint16_t)0xE1A0) == 0x0000) && ((TIM_FLAG) != 0x0000)) - -/** - * @} - */ - -/** @defgroup TIM_Input_Capture_Filer_Value - * @{ - */ - -#define IS_TIM_IC_FILTER(ICFILTER) ((ICFILTER) <= 0xF) -/** - * @} - */ - -/** @defgroup TIM_External_Trigger_Filter - * @{ - */ - -#define IS_TIM_EXT_FILTER(EXTFILTER) ((EXTFILTER) <= 0xF) -/** - * @} - */ - -/** @defgroup TIM_OCReferenceClear - * @{ - */ -#define TIM_OCReferenceClear_ETRF ((uint16_t)0x0008) -#define TIM_OCReferenceClear_OCREFCLR ((uint16_t)0x0000) -#define TIM_OCREFERENCECECLEAR_SOURCE(SOURCE) (((SOURCE) == TIM_OCReferenceClear_ETRF) || \ - ((SOURCE) == TIM_OCReferenceClear_OCREFCLR)) - -/** - * @} - */ - -/** @defgroup TIM_Remap - * @{ - */ - -#define TIM9_GPIO ((uint16_t)0x0000) -#define TIM9_LSE ((uint16_t)0x0001) - -#define TIM10_GPIO ((uint16_t)0x0000) -#define TIM10_LSI ((uint16_t)0x0001) -#define TIM10_LSE ((uint16_t)0x0002) -#define TIM10_RTC ((uint16_t)0x0003) - -#define TIM11_GPIO ((uint16_t)0x0000) -#define TIM11_MSI ((uint16_t)0x0001) -#define TIM11_HSE_RTC ((uint16_t)0x0002) - -#define IS_TIM_REMAP(TIM_REMAP) (((TIM_REMAP) == TIM9_GPIO)||\ - ((TIM_REMAP) == TIM9_LSE)||\ - ((TIM_REMAP) == TIM10_GPIO)||\ - ((TIM_REMAP) == TIM10_LSI)||\ - ((TIM_REMAP) == TIM10_LSE)||\ - ((TIM_REMAP) == TIM10_RTC)||\ - ((TIM_REMAP) == TIM11_GPIO)||\ - ((TIM_REMAP) == TIM11_MSI)||\ - ((TIM_REMAP) == TIM11_HSE_RTC)) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* TimeBase management ********************************************************/ -void TIM_DeInit(TIM_TypeDef* TIMx); -void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); -void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); -void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode); -void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode); -void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter); -void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload); -uint32_t TIM_GetCounter(TIM_TypeDef* TIMx); -uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx); -void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState); -void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource); -void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState); -void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode); -void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD); -void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); - -/* Output Compare management **************************************************/ -void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode); -void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1); -void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2); -void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3); -void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4); -void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); -void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); -void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); -void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); -void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); -void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); -void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); -void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); -void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); -void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); -void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); -void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); -void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); -void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); -void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); -void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); -void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); -void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); -void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); -void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); -void TIM_SelectOCREFClear(TIM_TypeDef* TIMx, uint16_t TIM_OCReferenceClear); -void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx); - -/* Input Capture management ***************************************************/ -void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); -void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct); -void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); -uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx); -uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx); -uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx); -uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx); -void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); -void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); -void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); -void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); - -/* Interrupts, DMA and flags management ***************************************/ -void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState); -void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource); -FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); -void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); -ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT); -void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT); -void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength); -void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState); -void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState); - -/* Clocks management **********************************************************/ -void TIM_InternalClockConfig(TIM_TypeDef* TIMx); -void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); -void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, - uint16_t TIM_ICPolarity, uint16_t ICFilter); -void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, - uint16_t ExtTRGFilter); -void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, - uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); - - -/* Synchronization management *************************************************/ -void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); -void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource); -void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); -void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode); -void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, - uint16_t ExtTRGFilter); - -/* Specific interface management **********************************************/ -void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, - uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity); -void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState); - -/* Specific remapping management **********************************************/ -void TIM_RemapConfig(TIM_TypeDef* TIMx, uint16_t TIM_Remap); - - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32L1xx_TIM_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_usart.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_usart.h deleted file mode 100644 index a5bc386d6..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_usart.h +++ /dev/null @@ -1,403 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_usart.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the USART - * firmware library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_USART_H -#define __STM32L1xx_USART_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup USART - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief USART Init Structure definition - */ - -typedef struct -{ - uint32_t USART_BaudRate; /*!< This member configures the USART communication baud rate. - The baud rate is computed using the following formula: - - IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate))) - - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */ - - uint16_t USART_WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. - This parameter can be a value of @ref USART_Word_Length */ - - uint16_t USART_StopBits; /*!< Specifies the number of stop bits transmitted. - This parameter can be a value of @ref USART_Stop_Bits */ - - uint16_t USART_Parity; /*!< Specifies the parity mode. - This parameter can be a value of @ref USART_Parity - @note When parity is enabled, the computed parity is inserted - at the MSB position of the transmitted data (9th bit when - the word length is set to 9 data bits; 8th bit when the - word length is set to 8 data bits). */ - - uint16_t USART_Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled. - This parameter can be a value of @ref USART_Mode */ - - uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled - or disabled. - This parameter can be a value of @ref USART_Hardware_Flow_Control */ -} USART_InitTypeDef; - -/** - * @brief USART Clock Init Structure definition - */ - -typedef struct -{ - - uint16_t USART_Clock; /*!< Specifies whether the USART clock is enabled or disabled. - This parameter can be a value of @ref USART_Clock */ - - uint16_t USART_CPOL; /*!< Specifies the steady state value of the serial clock. - This parameter can be a value of @ref USART_Clock_Polarity */ - - uint16_t USART_CPHA; /*!< Specifies the clock transition on which the bit capture is made. - This parameter can be a value of @ref USART_Clock_Phase */ - - uint16_t USART_LastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted - data bit (MSB) has to be output on the SCLK pin in synchronous mode. - This parameter can be a value of @ref USART_Last_Bit */ -} USART_ClockInitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup USART_Exported_Constants - * @{ - */ - -#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \ - ((PERIPH) == USART2) || \ - ((PERIPH) == USART3)) - -/** @defgroup USART_Word_Length - * @{ - */ - -#define USART_WordLength_8b ((uint16_t)0x0000) -#define USART_WordLength_9b ((uint16_t)0x1000) - -#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WordLength_8b) || \ - ((LENGTH) == USART_WordLength_9b)) -/** - * @} - */ - -/** @defgroup USART_Stop_Bits - * @{ - */ - -#define USART_StopBits_1 ((uint16_t)0x0000) -#define USART_StopBits_0_5 ((uint16_t)0x1000) -#define USART_StopBits_2 ((uint16_t)0x2000) -#define USART_StopBits_1_5 ((uint16_t)0x3000) -#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_StopBits_1) || \ - ((STOPBITS) == USART_StopBits_0_5) || \ - ((STOPBITS) == USART_StopBits_2) || \ - ((STOPBITS) == USART_StopBits_1_5)) -/** - * @} - */ - -/** @defgroup USART_Parity - * @{ - */ - -#define USART_Parity_No ((uint16_t)0x0000) -#define USART_Parity_Even ((uint16_t)0x0400) -#define USART_Parity_Odd ((uint16_t)0x0600) -#define IS_USART_PARITY(PARITY) (((PARITY) == USART_Parity_No) || \ - ((PARITY) == USART_Parity_Even) || \ - ((PARITY) == USART_Parity_Odd)) -/** - * @} - */ - -/** @defgroup USART_Mode - * @{ - */ - -#define USART_Mode_Rx ((uint16_t)0x0004) -#define USART_Mode_Tx ((uint16_t)0x0008) -#define IS_USART_MODE(MODE) ((((MODE) & (uint16_t)0xFFF3) == 0x00) && ((MODE) != (uint16_t)0x00)) -/** - * @} - */ - -/** @defgroup USART_Hardware_Flow_Control - * @{ - */ -#define USART_HardwareFlowControl_None ((uint16_t)0x0000) -#define USART_HardwareFlowControl_RTS ((uint16_t)0x0100) -#define USART_HardwareFlowControl_CTS ((uint16_t)0x0200) -#define USART_HardwareFlowControl_RTS_CTS ((uint16_t)0x0300) -#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)\ - (((CONTROL) == USART_HardwareFlowControl_None) || \ - ((CONTROL) == USART_HardwareFlowControl_RTS) || \ - ((CONTROL) == USART_HardwareFlowControl_CTS) || \ - ((CONTROL) == USART_HardwareFlowControl_RTS_CTS)) -/** - * @} - */ - -/** @defgroup USART_Clock - * @{ - */ -#define USART_Clock_Disable ((uint16_t)0x0000) -#define USART_Clock_Enable ((uint16_t)0x0800) -#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_Clock_Disable) || \ - ((CLOCK) == USART_Clock_Enable)) -/** - * @} - */ - -/** @defgroup USART_Clock_Polarity - * @{ - */ - -#define USART_CPOL_Low ((uint16_t)0x0000) -#define USART_CPOL_High ((uint16_t)0x0400) -#define IS_USART_CPOL(CPOL) (((CPOL) == USART_CPOL_Low) || ((CPOL) == USART_CPOL_High)) - -/** - * @} - */ - -/** @defgroup USART_Clock_Phase - * @{ - */ - -#define USART_CPHA_1Edge ((uint16_t)0x0000) -#define USART_CPHA_2Edge ((uint16_t)0x0200) -#define IS_USART_CPHA(CPHA) (((CPHA) == USART_CPHA_1Edge) || ((CPHA) == USART_CPHA_2Edge)) - -/** - * @} - */ - -/** @defgroup USART_Last_Bit - * @{ - */ - -#define USART_LastBit_Disable ((uint16_t)0x0000) -#define USART_LastBit_Enable ((uint16_t)0x0100) -#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LastBit_Disable) || \ - ((LASTBIT) == USART_LastBit_Enable)) -/** - * @} - */ - -/** @defgroup USART_Interrupt_definition - * @{ - */ - -#define USART_IT_PE ((uint16_t)0x0028) -#define USART_IT_TXE ((uint16_t)0x0727) -#define USART_IT_TC ((uint16_t)0x0626) -#define USART_IT_RXNE ((uint16_t)0x0525) -#define USART_IT_IDLE ((uint16_t)0x0424) -#define USART_IT_LBD ((uint16_t)0x0846) -#define USART_IT_CTS ((uint16_t)0x096A) -#define USART_IT_ERR ((uint16_t)0x0060) -#define USART_IT_ORE ((uint16_t)0x0360) -#define USART_IT_NE ((uint16_t)0x0260) -#define USART_IT_FE ((uint16_t)0x0160) -#define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ - ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ - ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ - ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR)) -#define IS_USART_GET_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ - ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ - ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ - ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ORE) || \ - ((IT) == USART_IT_NE) || ((IT) == USART_IT_FE)) -#define IS_USART_CLEAR_IT(IT) (((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ - ((IT) == USART_IT_LBD) || ((IT) == USART_IT_CTS)) -/** - * @} - */ - -/** @defgroup USART_DMA_Requests - * @{ - */ - -#define USART_DMAReq_Tx ((uint16_t)0x0080) -#define USART_DMAReq_Rx ((uint16_t)0x0040) -#define IS_USART_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFF3F) == 0x00) && ((DMAREQ) != (uint16_t)0x00)) - -/** - * @} - */ - -/** @defgroup USART_WakeUp_methods - * @{ - */ - -#define USART_WakeUp_IdleLine ((uint16_t)0x0000) -#define USART_WakeUp_AddressMark ((uint16_t)0x0800) -#define IS_USART_WAKEUP(WAKEUP) (((WAKEUP) == USART_WakeUp_IdleLine) || \ - ((WAKEUP) == USART_WakeUp_AddressMark)) -/** - * @} - */ - -/** @defgroup USART_LIN_Break_Detection_Length - * @{ - */ - -#define USART_LINBreakDetectLength_10b ((uint16_t)0x0000) -#define USART_LINBreakDetectLength_11b ((uint16_t)0x0020) -#define IS_USART_LIN_BREAK_DETECT_LENGTH(LENGTH) \ - (((LENGTH) == USART_LINBreakDetectLength_10b) || \ - ((LENGTH) == USART_LINBreakDetectLength_11b)) -/** - * @} - */ - -/** @defgroup USART_IrDA_Low_Power - * @{ - */ - -#define USART_IrDAMode_LowPower ((uint16_t)0x0004) -#define USART_IrDAMode_Normal ((uint16_t)0x0000) -#define IS_USART_IRDA_MODE(MODE) (((MODE) == USART_IrDAMode_LowPower) || \ - ((MODE) == USART_IrDAMode_Normal)) -/** - * @} - */ - -/** @defgroup USART_Flags - * @{ - */ - -#define USART_FLAG_CTS ((uint16_t)0x0200) -#define USART_FLAG_LBD ((uint16_t)0x0100) -#define USART_FLAG_TXE ((uint16_t)0x0080) -#define USART_FLAG_TC ((uint16_t)0x0040) -#define USART_FLAG_RXNE ((uint16_t)0x0020) -#define USART_FLAG_IDLE ((uint16_t)0x0010) -#define USART_FLAG_ORE ((uint16_t)0x0008) -#define USART_FLAG_NE ((uint16_t)0x0004) -#define USART_FLAG_FE ((uint16_t)0x0002) -#define USART_FLAG_PE ((uint16_t)0x0001) -#define IS_USART_FLAG(FLAG) (((FLAG) == USART_FLAG_PE) || ((FLAG) == USART_FLAG_TXE) || \ - ((FLAG) == USART_FLAG_TC) || ((FLAG) == USART_FLAG_RXNE) || \ - ((FLAG) == USART_FLAG_IDLE) || ((FLAG) == USART_FLAG_LBD) || \ - ((FLAG) == USART_FLAG_CTS) || ((FLAG) == USART_FLAG_ORE) || \ - ((FLAG) == USART_FLAG_NE) || ((FLAG) == USART_FLAG_FE)) - -#define IS_USART_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFC9F) == 0x00) && ((FLAG) != (uint16_t)0x00)) - -#define IS_USART_BAUDRATE(BAUDRATE) (((BAUDRATE) > 0) && ((BAUDRATE) < 0x003D0901)) -#define IS_USART_ADDRESS(ADDRESS) ((ADDRESS) <= 0xF) -#define IS_USART_DATA(DATA) ((DATA) <= 0x1FF) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -/* Function used to set the USART configuration to the default reset state ***/ -void USART_DeInit(USART_TypeDef* USARTx); - -/* Initialization and Configuration functions *********************************/ -void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct); -void USART_StructInit(USART_InitTypeDef* USART_InitStruct); -void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct); -void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct); -void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler); -void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState); - -/* Data transfers functions ***************************************************/ -void USART_SendData(USART_TypeDef* USARTx, uint16_t Data); -uint16_t USART_ReceiveData(USART_TypeDef* USARTx); - -/* Multi-Processor Communication functions ************************************/ -void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address); -void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp); -void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState); - -/* LIN mode functions *********************************************************/ -void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength); -void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_SendBreak(USART_TypeDef* USARTx); - -/* Half-duplex mode function **************************************************/ -void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState); - -/* Smartcard mode functions ***************************************************/ -void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime); - -/* IrDA mode functions ********************************************************/ -void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode); -void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState); - -/* DMA transfers management functions *****************************************/ -void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState); - -/* Interrupts and flags management functions **********************************/ -void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState); -FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); -void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG); -ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT); -void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32L1xx_USART_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/inc/stm32l1xx/stm32l1xx_wwdg.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_wwdg.h deleted file mode 100644 index d00e42ac1..000000000 --- a/example/libs_stm/inc/stm32l1xx/stm32l1xx_wwdg.h +++ /dev/null @@ -1,104 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_wwdg.h - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file contains all the functions prototypes for the WWDG - * firmware library. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32L1xx_WWDG_H -#define __STM32L1xx_WWDG_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup WWDG - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup WWDG_Exported_Constants - * @{ - */ - -/** @defgroup WWDG_Prescaler - * @{ - */ - -#define WWDG_Prescaler_1 ((uint32_t)0x00000000) -#define WWDG_Prescaler_2 ((uint32_t)0x00000080) -#define WWDG_Prescaler_4 ((uint32_t)0x00000100) -#define WWDG_Prescaler_8 ((uint32_t)0x00000180) -#define IS_WWDG_PRESCALER(PRESCALER) (((PRESCALER) == WWDG_Prescaler_1) || \ - ((PRESCALER) == WWDG_Prescaler_2) || \ - ((PRESCALER) == WWDG_Prescaler_4) || \ - ((PRESCALER) == WWDG_Prescaler_8)) -#define IS_WWDG_WINDOW_VALUE(VALUE) ((VALUE) <= 0x7F) -#define IS_WWDG_COUNTER(COUNTER) (((COUNTER) >= 0x40) && ((COUNTER) <= 0x7F)) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -/* Function used to set the WWDG configuration to the default reset state ****/ -void WWDG_DeInit(void); - -/* Prescaler, Refresh window and Counter configuration functions **************/ -void WWDG_SetPrescaler(uint32_t WWDG_Prescaler); -void WWDG_SetWindowValue(uint8_t WindowValue); -void WWDG_EnableIT(void); -void WWDG_SetCounter(uint8_t Counter); - -/* WWDG activation functions **************************************************/ -void WWDG_Enable(uint8_t Counter); - -/* Interrupts and flags management functions **********************************/ -FlagStatus WWDG_GetFlagStatus(void); -void WWDG_ClearFlag(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32L1xx_WWDG_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/Release_Notes_for_STM32F10x_StdPeriph_Driver.html b/example/libs_stm/src/stm32f10x/Release_Notes_for_STM32F10x_StdPeriph_Driver.html deleted file mode 100644 index 018141b98..000000000 --- a/example/libs_stm/src/stm32f10x/Release_Notes_for_STM32F10x_StdPeriph_Driver.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - - -Release Notes for STM32F10x Standard Peripherals Library Drivers - - - - - -
-


-

-
- - - - - - -
- - - - - - - - - -
Back to Release page
-

Release -Notes for STM32F10x Standard Peripherals Library Drivers -(StdPeriph_Driver)

-

Copyright 2010 STMicroelectronics

-

-
-

 

- - - - - - -
-

Contents

-
    -
  1. STM32F10x Standard Peripherals Library -Drivers update History
  2. -
  3. License
  4. -
- - -

STM32F10x Standard -Peripherals Library Drivers  update History

3.3.0 -- 04/16/2010

-
  1. General
-
  • Add support for STM32F10x XL-density devices.
  • I2C driver: events description and management enhancement.
-
  1. STM32F10x_StdPeriph_Driver
-
  • stm32f10x_dbgmcu.h/.c
    • DBGMCU_Config() function: add new values DBGMCU_TIMx_STOP (x: 9..14) for DBGMCU_Periph parameter.
  • stm32f10x_flash.h/.c: -updated to support Bank2 of XL-density devices (up to 1MByte of Flash -memory). For more details, refer to the description provided within -stm32f10x_flash.c file.
  • stm32f10x_gpio.h/.c
    • GPIO_PinRemapConfig() function: add new values for GPIO_Remap parameter, to support new remap for FSMC_NADV pin and TIM9..11,13,14.
  • stm32f10x_i2c.h/.c: I2C events description and management enhancement.
    • I2C_CheckEvent() -function: updated to check whether the last event contains the -I2C_EVENT  (instead of check whether the last event is equal to -I2C_EVENT)
    • Add -detailed description of I2C events and how to manage them using the -functions provided by this driver. For more information, refer to -stm32f10x_i2c.h and stm32f10x_i2c.c files.
  • stm32f10x_rcc.h/.c: updated to support TIM9..TIM14 APB clock and reset configuration
  • stm32f10x_tim.h/.c: updated to support new Timers TIM9..TIM14.
  • stm32f10x_sdio.h: 
    • SDIO_SetSDIOReadWaitMode() function: correct values of SDIO_ReadWaitMode parameter
      change
        -#define -SDIO_ReadWaitMode_CLK               -  ((uint32_t)0x00000000)
        #define -SDIO_ReadWaitMode_DATA2             -((uint32_t)0x00000001)
      by
        #define -SDIO_ReadWaitMode_CLK               -  ((uint32_t)0x00000001)
        #define -SDIO_ReadWaitMode_DATA2             -((uint32_t)0x00000000)
-

3.2.0 -- 03/01/2010

-
    -
  1. General
  2. -
-
    - -
  • Add support -for STM32 Low-density Value line (STM32F100x4/6) and -Medium-density Value line (STM32F100x8/B) devices.
  • -
  • Almost -peripherals drivers were updated to support Value -line devices features
  • -
  • Drivers limitations fix and enhancements.
  • - -
-
    -
  1. STM32F10x_StdPeriph_Driver
  2. -
-
    -
  • Add new -firmware driver for CEC peripheral: stm32f10x_cec.h and stm32f10x_cec.c
  • -
  • Timers drivers stm32f10x_tim.h/.c: add support for new General Purpose Timers: TIM15, TIM16 and TIM17.
  • -
  • RCC driver: add support for new Value peripherals: HDMI-CEC, TIM15, TIM16 and TIM17.
  • -
  • GPIO driver: add new remap parameters for TIM1, TIM15, TIM16, TIM17 and HDMI-CEC: GPIO_Remap_TIM1_DMA, GPIO_Remap_TIM15, GPIO_Remap_TIM16, GPIO_Remap_TIM17, GPIO_Remap_CEC.
  • -
  • USART -driver: add support for Oversampling by 8 mode and onebit method. 2 -functions has been added: USART_OverSampling8Cmd() and -USART_OneBitMethodCmd().
    -
  • -
  • DAC -driver: add new functions handling the DAC under run feature: -DAC_ITConfig(), DAC_GetFlagStatus(), DAC_ClearFlag(), DAC_GetITStatus() -and DAC_ClearITPendingBit().
  • -
  • DBGMCU driver: add new parameters for TIM15, TIM16 and TIM17: DBGMCU_TIM15_STOP, DBGMCU_TIM16_STOP, DBGMCU_TIM17_STOP.
    -
  • -
  • FLASH -driver: the FLASH_EraseOptionBytes() function updated. This is now just -erasing the option bytes without modifying the RDP status either -enabled or disabled.
  • -
  • PWR -driver: the PWR_EnterSTOPMode() function updated. When woken up from -STOP mode, this function resets again the SLEEPDEEP bit in the -Cortex-M3 System Control register to allow Sleep mode entering.
  • - - -
-

License

-

The -enclosed firmware and all the related documentation are not covered by -a License Agreement, if you need such License you can contact your -local STMicroelectronics office.

-

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.

-

 

-
-
-

For -complete documentation on STM32(CORTEX M3) 32-Bit Microcontrollers -visit www.st.com/STM32

-
-

-
-
-

 

-
- \ No newline at end of file diff --git a/example/libs_stm/src/stm32f10x/misc.c b/example/libs_stm/src/stm32f10x/misc.c deleted file mode 100644 index b8349fab9..000000000 --- a/example/libs_stm/src/stm32f10x/misc.c +++ /dev/null @@ -1,223 +0,0 @@ -/** - ****************************************************************************** - * @file misc.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the miscellaneous firmware functions (add-on - * to CMSIS functions). - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "misc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup MISC - * @brief MISC driver modules - * @{ - */ - -/** @defgroup MISC_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup MISC_Private_Defines - * @{ - */ - -#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) -/** - * @} - */ - -/** @defgroup MISC_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup MISC_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup MISC_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup MISC_Private_Functions - * @{ - */ - -/** - * @brief Configures the priority grouping: pre-emption priority and subpriority. - * @param NVIC_PriorityGroup: specifies the priority grouping bits length. - * This parameter can be one of the following values: - * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority - * 4 bits for subpriority - * @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority - * 3 bits for subpriority - * @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority - * 2 bits for subpriority - * @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority - * 1 bits for subpriority - * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority - * 0 bits for subpriority - * @retval None - */ -void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) -{ - /* Check the parameters */ - assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); - - /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */ - SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; -} - -/** - * @brief Initializes the NVIC peripheral according to the specified - * parameters in the NVIC_InitStruct. - * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains - * the configuration information for the specified NVIC peripheral. - * @retval None - */ -void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) -{ - uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F; - - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd)); - assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority)); - assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority)); - - if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE) - { - /* Compute the Corresponding IRQ Priority --------------------------------*/ - tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08; - tmppre = (0x4 - tmppriority); - tmpsub = tmpsub >> tmppriority; - - tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; - tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub; - tmppriority = tmppriority << 0x04; - - NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority; - - /* Enable the Selected IRQ Channels --------------------------------------*/ - NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = - (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); - } - else - { - /* Disable the Selected IRQ Channels -------------------------------------*/ - NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = - (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); - } -} - -/** - * @brief Sets the vector table location and Offset. - * @param NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory. - * This parameter can be one of the following values: - * @arg NVIC_VectTab_RAM - * @arg NVIC_VectTab_FLASH - * @param Offset: Vector Table base offset field. This value must be a multiple of 0x100. - * @retval None - */ -void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) -{ - /* Check the parameters */ - assert_param(IS_NVIC_VECTTAB(NVIC_VectTab)); - assert_param(IS_NVIC_OFFSET(Offset)); - - SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80); -} - -/** - * @brief Selects the condition for the system to enter low power mode. - * @param LowPowerMode: Specifies the new mode for the system to enter low power mode. - * This parameter can be one of the following values: - * @arg NVIC_LP_SEVONPEND - * @arg NVIC_LP_SLEEPDEEP - * @arg NVIC_LP_SLEEPONEXIT - * @param NewState: new state of LP condition. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_NVIC_LP(LowPowerMode)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - SCB->SCR |= LowPowerMode; - } - else - { - SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode); - } -} - -/** - * @brief Configures the SysTick clock source. - * @param SysTick_CLKSource: specifies the SysTick clock source. - * This parameter can be one of the following values: - * @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source. - * @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source. - * @retval None - */ -void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) -{ - /* Check the parameters */ - assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); - if (SysTick_CLKSource == SysTick_CLKSource_HCLK) - { - SysTick->CTRL |= SysTick_CLKSource_HCLK; - } - else - { - SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_adc.c b/example/libs_stm/src/stm32f10x/stm32f10x_adc.c deleted file mode 100644 index a027f3304..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_adc.c +++ /dev/null @@ -1,1306 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_adc.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the ADC firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_adc.h" -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup ADC - * @brief ADC driver modules - * @{ - */ - -/** @defgroup ADC_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup ADC_Private_Defines - * @{ - */ - -/* ADC DISCNUM mask */ -#define CR1_DISCNUM_Reset ((uint32_t)0xFFFF1FFF) - -/* ADC DISCEN mask */ -#define CR1_DISCEN_Set ((uint32_t)0x00000800) -#define CR1_DISCEN_Reset ((uint32_t)0xFFFFF7FF) - -/* ADC JAUTO mask */ -#define CR1_JAUTO_Set ((uint32_t)0x00000400) -#define CR1_JAUTO_Reset ((uint32_t)0xFFFFFBFF) - -/* ADC JDISCEN mask */ -#define CR1_JDISCEN_Set ((uint32_t)0x00001000) -#define CR1_JDISCEN_Reset ((uint32_t)0xFFFFEFFF) - -/* ADC AWDCH mask */ -#define CR1_AWDCH_Reset ((uint32_t)0xFFFFFFE0) - -/* ADC Analog watchdog enable mode mask */ -#define CR1_AWDMode_Reset ((uint32_t)0xFF3FFDFF) - -/* CR1 register Mask */ -#define CR1_CLEAR_Mask ((uint32_t)0xFFF0FEFF) - -/* ADC ADON mask */ -#define CR2_ADON_Set ((uint32_t)0x00000001) -#define CR2_ADON_Reset ((uint32_t)0xFFFFFFFE) - -/* ADC DMA mask */ -#define CR2_DMA_Set ((uint32_t)0x00000100) -#define CR2_DMA_Reset ((uint32_t)0xFFFFFEFF) - -/* ADC RSTCAL mask */ -#define CR2_RSTCAL_Set ((uint32_t)0x00000008) - -/* ADC CAL mask */ -#define CR2_CAL_Set ((uint32_t)0x00000004) - -/* ADC SWSTART mask */ -#define CR2_SWSTART_Set ((uint32_t)0x00400000) - -/* ADC EXTTRIG mask */ -#define CR2_EXTTRIG_Set ((uint32_t)0x00100000) -#define CR2_EXTTRIG_Reset ((uint32_t)0xFFEFFFFF) - -/* ADC Software start mask */ -#define CR2_EXTTRIG_SWSTART_Set ((uint32_t)0x00500000) -#define CR2_EXTTRIG_SWSTART_Reset ((uint32_t)0xFFAFFFFF) - -/* ADC JEXTSEL mask */ -#define CR2_JEXTSEL_Reset ((uint32_t)0xFFFF8FFF) - -/* ADC JEXTTRIG mask */ -#define CR2_JEXTTRIG_Set ((uint32_t)0x00008000) -#define CR2_JEXTTRIG_Reset ((uint32_t)0xFFFF7FFF) - -/* ADC JSWSTART mask */ -#define CR2_JSWSTART_Set ((uint32_t)0x00200000) - -/* ADC injected software start mask */ -#define CR2_JEXTTRIG_JSWSTART_Set ((uint32_t)0x00208000) -#define CR2_JEXTTRIG_JSWSTART_Reset ((uint32_t)0xFFDF7FFF) - -/* ADC TSPD mask */ -#define CR2_TSVREFE_Set ((uint32_t)0x00800000) -#define CR2_TSVREFE_Reset ((uint32_t)0xFF7FFFFF) - -/* CR2 register Mask */ -#define CR2_CLEAR_Mask ((uint32_t)0xFFF1F7FD) - -/* ADC SQx mask */ -#define SQR3_SQ_Set ((uint32_t)0x0000001F) -#define SQR2_SQ_Set ((uint32_t)0x0000001F) -#define SQR1_SQ_Set ((uint32_t)0x0000001F) - -/* SQR1 register Mask */ -#define SQR1_CLEAR_Mask ((uint32_t)0xFF0FFFFF) - -/* ADC JSQx mask */ -#define JSQR_JSQ_Set ((uint32_t)0x0000001F) - -/* ADC JL mask */ -#define JSQR_JL_Set ((uint32_t)0x00300000) -#define JSQR_JL_Reset ((uint32_t)0xFFCFFFFF) - -/* ADC SMPx mask */ -#define SMPR1_SMP_Set ((uint32_t)0x00000007) -#define SMPR2_SMP_Set ((uint32_t)0x00000007) - -/* ADC JDRx registers offset */ -#define JDR_Offset ((uint8_t)0x28) - -/* ADC1 DR register base address */ -#define DR_ADDRESS ((uint32_t)0x4001244C) - -/** - * @} - */ - -/** @defgroup ADC_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup ADC_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup ADC_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup ADC_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the ADCx peripheral registers to their default reset values. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @retval None - */ -void ADC_DeInit(ADC_TypeDef* ADCx) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - - if (ADCx == ADC1) - { - /* Enable ADC1 reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, ENABLE); - /* Release ADC1 from reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, DISABLE); - } - else if (ADCx == ADC2) - { - /* Enable ADC2 reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2, ENABLE); - /* Release ADC2 from reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2, DISABLE); - } - else - { - if (ADCx == ADC3) - { - /* Enable ADC3 reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3, ENABLE); - /* Release ADC3 from reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3, DISABLE); - } - } -} - -/** - * @brief Initializes the ADCx peripheral according to the specified parameters - * in the ADC_InitStruct. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains - * the configuration information for the specified ADC peripheral. - * @retval None - */ -void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) -{ - uint32_t tmpreg1 = 0; - uint8_t tmpreg2 = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_MODE(ADC_InitStruct->ADC_Mode)); - assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ScanConvMode)); - assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ContinuousConvMode)); - assert_param(IS_ADC_EXT_TRIG(ADC_InitStruct->ADC_ExternalTrigConv)); - assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign)); - assert_param(IS_ADC_REGULAR_LENGTH(ADC_InitStruct->ADC_NbrOfChannel)); - - /*---------------------------- ADCx CR1 Configuration -----------------*/ - /* Get the ADCx CR1 value */ - tmpreg1 = ADCx->CR1; - /* Clear DUALMOD and SCAN bits */ - tmpreg1 &= CR1_CLEAR_Mask; - /* Configure ADCx: Dual mode and scan conversion mode */ - /* Set DUALMOD bits according to ADC_Mode value */ - /* Set SCAN bit according to ADC_ScanConvMode value */ - tmpreg1 |= (uint32_t)(ADC_InitStruct->ADC_Mode | ((uint32_t)ADC_InitStruct->ADC_ScanConvMode << 8)); - /* Write to ADCx CR1 */ - ADCx->CR1 = tmpreg1; - - /*---------------------------- ADCx CR2 Configuration -----------------*/ - /* Get the ADCx CR2 value */ - tmpreg1 = ADCx->CR2; - /* Clear CONT, ALIGN and EXTSEL bits */ - tmpreg1 &= CR2_CLEAR_Mask; - /* Configure ADCx: external trigger event and continuous conversion mode */ - /* Set ALIGN bit according to ADC_DataAlign value */ - /* Set EXTSEL bits according to ADC_ExternalTrigConv value */ - /* Set CONT bit according to ADC_ContinuousConvMode value */ - tmpreg1 |= (uint32_t)(ADC_InitStruct->ADC_DataAlign | ADC_InitStruct->ADC_ExternalTrigConv | - ((uint32_t)ADC_InitStruct->ADC_ContinuousConvMode << 1)); - /* Write to ADCx CR2 */ - ADCx->CR2 = tmpreg1; - - /*---------------------------- ADCx SQR1 Configuration -----------------*/ - /* Get the ADCx SQR1 value */ - tmpreg1 = ADCx->SQR1; - /* Clear L bits */ - tmpreg1 &= SQR1_CLEAR_Mask; - /* Configure ADCx: regular channel sequence length */ - /* Set L bits according to ADC_NbrOfChannel value */ - tmpreg2 |= (uint8_t) (ADC_InitStruct->ADC_NbrOfChannel - (uint8_t)1); - tmpreg1 |= (uint32_t)tmpreg2 << 20; - /* Write to ADCx SQR1 */ - ADCx->SQR1 = tmpreg1; -} - -/** - * @brief Fills each ADC_InitStruct member with its default value. - * @param ADC_InitStruct : pointer to an ADC_InitTypeDef structure which will be initialized. - * @retval None - */ -void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct) -{ - /* Reset ADC init structure parameters values */ - /* Initialize the ADC_Mode member */ - ADC_InitStruct->ADC_Mode = ADC_Mode_Independent; - /* initialize the ADC_ScanConvMode member */ - ADC_InitStruct->ADC_ScanConvMode = DISABLE; - /* Initialize the ADC_ContinuousConvMode member */ - ADC_InitStruct->ADC_ContinuousConvMode = DISABLE; - /* Initialize the ADC_ExternalTrigConv member */ - ADC_InitStruct->ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; - /* Initialize the ADC_DataAlign member */ - ADC_InitStruct->ADC_DataAlign = ADC_DataAlign_Right; - /* Initialize the ADC_NbrOfChannel member */ - ADC_InitStruct->ADC_NbrOfChannel = 1; -} - -/** - * @brief Enables or disables the specified ADC peripheral. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the ADCx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Set the ADON bit to wake up the ADC from power down mode */ - ADCx->CR2 |= CR2_ADON_Set; - } - else - { - /* Disable the selected ADC peripheral */ - ADCx->CR2 &= CR2_ADON_Reset; - } -} - -/** - * @brief Enables or disables the specified ADC DMA request. - * @param ADCx: where x can be 1 or 3 to select the ADC peripheral. - * Note: ADC2 hasn't a DMA capability. - * @param NewState: new state of the selected ADC DMA transfer. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_DMA_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected ADC DMA request */ - ADCx->CR2 |= CR2_DMA_Set; - } - else - { - /* Disable the selected ADC DMA request */ - ADCx->CR2 &= CR2_DMA_Reset; - } -} - -/** - * @brief Enables or disables the specified ADC interrupts. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_IT: specifies the ADC interrupt sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg ADC_IT_EOC: End of conversion interrupt mask - * @arg ADC_IT_AWD: Analog watchdog interrupt mask - * @arg ADC_IT_JEOC: End of injected conversion interrupt mask - * @param NewState: new state of the specified ADC interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState) -{ - uint8_t itmask = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_ADC_IT(ADC_IT)); - /* Get the ADC IT index */ - itmask = (uint8_t)ADC_IT; - if (NewState != DISABLE) - { - /* Enable the selected ADC interrupts */ - ADCx->CR1 |= itmask; - } - else - { - /* Disable the selected ADC interrupts */ - ADCx->CR1 &= (~(uint32_t)itmask); - } -} - -/** - * @brief Resets the selected ADC calibration registers. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @retval None - */ -void ADC_ResetCalibration(ADC_TypeDef* ADCx) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - /* Resets the selected ADC calibartion registers */ - ADCx->CR2 |= CR2_RSTCAL_Set; -} - -/** - * @brief Gets the selected ADC reset calibration registers status. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @retval The new state of ADC reset calibration registers (SET or RESET). - */ -FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - /* Check the status of RSTCAL bit */ - if ((ADCx->CR2 & CR2_RSTCAL_Set) != (uint32_t)RESET) - { - /* RSTCAL bit is set */ - bitstatus = SET; - } - else - { - /* RSTCAL bit is reset */ - bitstatus = RESET; - } - /* Return the RSTCAL bit status */ - return bitstatus; -} - -/** - * @brief Starts the selected ADC calibration process. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @retval None - */ -void ADC_StartCalibration(ADC_TypeDef* ADCx) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - /* Enable the selected ADC calibration process */ - ADCx->CR2 |= CR2_CAL_Set; -} - -/** - * @brief Gets the selected ADC calibration status. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @retval The new state of ADC calibration (SET or RESET). - */ -FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - /* Check the status of CAL bit */ - if ((ADCx->CR2 & CR2_CAL_Set) != (uint32_t)RESET) - { - /* CAL bit is set: calibration on going */ - bitstatus = SET; - } - else - { - /* CAL bit is reset: end of calibration */ - bitstatus = RESET; - } - /* Return the CAL bit status */ - return bitstatus; -} - -/** - * @brief Enables or disables the selected ADC software start conversion . - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the selected ADC software start conversion. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected ADC conversion on external event and start the selected - ADC conversion */ - ADCx->CR2 |= CR2_EXTTRIG_SWSTART_Set; - } - else - { - /* Disable the selected ADC conversion on external event and stop the selected - ADC conversion */ - ADCx->CR2 &= CR2_EXTTRIG_SWSTART_Reset; - } -} - -/** - * @brief Gets the selected ADC Software start conversion Status. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @retval The new state of ADC software start conversion (SET or RESET). - */ -FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - /* Check the status of SWSTART bit */ - if ((ADCx->CR2 & CR2_SWSTART_Set) != (uint32_t)RESET) - { - /* SWSTART bit is set */ - bitstatus = SET; - } - else - { - /* SWSTART bit is reset */ - bitstatus = RESET; - } - /* Return the SWSTART bit status */ - return bitstatus; -} - -/** - * @brief Configures the discontinuous mode for the selected ADC regular - * group channel. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param Number: specifies the discontinuous mode regular channel - * count value. This number must be between 1 and 8. - * @retval None - */ -void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number) -{ - uint32_t tmpreg1 = 0; - uint32_t tmpreg2 = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_REGULAR_DISC_NUMBER(Number)); - /* Get the old register value */ - tmpreg1 = ADCx->CR1; - /* Clear the old discontinuous mode channel count */ - tmpreg1 &= CR1_DISCNUM_Reset; - /* Set the discontinuous mode channel count */ - tmpreg2 = Number - 1; - tmpreg1 |= tmpreg2 << 13; - /* Store the new register value */ - ADCx->CR1 = tmpreg1; -} - -/** - * @brief Enables or disables the discontinuous mode on regular group - * channel for the specified ADC - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the selected ADC discontinuous mode - * on regular group channel. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected ADC regular discontinuous mode */ - ADCx->CR1 |= CR1_DISCEN_Set; - } - else - { - /* Disable the selected ADC regular discontinuous mode */ - ADCx->CR1 &= CR1_DISCEN_Reset; - } -} - -/** - * @brief Configures for the selected ADC regular channel its corresponding - * rank in the sequencer and its sample time. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_Channel: the ADC channel to configure. - * This parameter can be one of the following values: - * @arg ADC_Channel_0: ADC Channel0 selected - * @arg ADC_Channel_1: ADC Channel1 selected - * @arg ADC_Channel_2: ADC Channel2 selected - * @arg ADC_Channel_3: ADC Channel3 selected - * @arg ADC_Channel_4: ADC Channel4 selected - * @arg ADC_Channel_5: ADC Channel5 selected - * @arg ADC_Channel_6: ADC Channel6 selected - * @arg ADC_Channel_7: ADC Channel7 selected - * @arg ADC_Channel_8: ADC Channel8 selected - * @arg ADC_Channel_9: ADC Channel9 selected - * @arg ADC_Channel_10: ADC Channel10 selected - * @arg ADC_Channel_11: ADC Channel11 selected - * @arg ADC_Channel_12: ADC Channel12 selected - * @arg ADC_Channel_13: ADC Channel13 selected - * @arg ADC_Channel_14: ADC Channel14 selected - * @arg ADC_Channel_15: ADC Channel15 selected - * @arg ADC_Channel_16: ADC Channel16 selected - * @arg ADC_Channel_17: ADC Channel17 selected - * @param Rank: The rank in the regular group sequencer. This parameter must be between 1 to 16. - * @param ADC_SampleTime: The sample time value to be set for the selected channel. - * This parameter can be one of the following values: - * @arg ADC_SampleTime_1Cycles5: Sample time equal to 1.5 cycles - * @arg ADC_SampleTime_7Cycles5: Sample time equal to 7.5 cycles - * @arg ADC_SampleTime_13Cycles5: Sample time equal to 13.5 cycles - * @arg ADC_SampleTime_28Cycles5: Sample time equal to 28.5 cycles - * @arg ADC_SampleTime_41Cycles5: Sample time equal to 41.5 cycles - * @arg ADC_SampleTime_55Cycles5: Sample time equal to 55.5 cycles - * @arg ADC_SampleTime_71Cycles5: Sample time equal to 71.5 cycles - * @arg ADC_SampleTime_239Cycles5: Sample time equal to 239.5 cycles - * @retval None - */ -void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) -{ - uint32_t tmpreg1 = 0, tmpreg2 = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_CHANNEL(ADC_Channel)); - assert_param(IS_ADC_REGULAR_RANK(Rank)); - assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); - /* if ADC_Channel_10 ... ADC_Channel_17 is selected */ - if (ADC_Channel > ADC_Channel_9) - { - /* Get the old register value */ - tmpreg1 = ADCx->SMPR1; - /* Calculate the mask to clear */ - tmpreg2 = SMPR1_SMP_Set << (3 * (ADC_Channel - 10)); - /* Clear the old channel sample time */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 10)); - /* Set the new channel sample time */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SMPR1 = tmpreg1; - } - else /* ADC_Channel include in ADC_Channel_[0..9] */ - { - /* Get the old register value */ - tmpreg1 = ADCx->SMPR2; - /* Calculate the mask to clear */ - tmpreg2 = SMPR2_SMP_Set << (3 * ADC_Channel); - /* Clear the old channel sample time */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); - /* Set the new channel sample time */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SMPR2 = tmpreg1; - } - /* For Rank 1 to 6 */ - if (Rank < 7) - { - /* Get the old register value */ - tmpreg1 = ADCx->SQR3; - /* Calculate the mask to clear */ - tmpreg2 = SQR3_SQ_Set << (5 * (Rank - 1)); - /* Clear the old SQx bits for the selected rank */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 1)); - /* Set the SQx bits for the selected rank */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SQR3 = tmpreg1; - } - /* For Rank 7 to 12 */ - else if (Rank < 13) - { - /* Get the old register value */ - tmpreg1 = ADCx->SQR2; - /* Calculate the mask to clear */ - tmpreg2 = SQR2_SQ_Set << (5 * (Rank - 7)); - /* Clear the old SQx bits for the selected rank */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 7)); - /* Set the SQx bits for the selected rank */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SQR2 = tmpreg1; - } - /* For Rank 13 to 16 */ - else - { - /* Get the old register value */ - tmpreg1 = ADCx->SQR1; - /* Calculate the mask to clear */ - tmpreg2 = SQR1_SQ_Set << (5 * (Rank - 13)); - /* Clear the old SQx bits for the selected rank */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 13)); - /* Set the SQx bits for the selected rank */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SQR1 = tmpreg1; - } -} - -/** - * @brief Enables or disables the ADCx conversion through external trigger. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the selected ADC external trigger start of conversion. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected ADC conversion on external event */ - ADCx->CR2 |= CR2_EXTTRIG_Set; - } - else - { - /* Disable the selected ADC conversion on external event */ - ADCx->CR2 &= CR2_EXTTRIG_Reset; - } -} - -/** - * @brief Returns the last ADCx conversion result data for regular channel. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @retval The Data conversion value. - */ -uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - /* Return the selected ADC conversion value */ - return (uint16_t) ADCx->DR; -} - -/** - * @brief Returns the last ADC1 and ADC2 conversion result data in dual mode. - * @retval The Data conversion value. - */ -uint32_t ADC_GetDualModeConversionValue(void) -{ - /* Return the dual mode conversion value */ - return (*(__IO uint32_t *) DR_ADDRESS); -} - -/** - * @brief Enables or disables the selected ADC automatic injected group - * conversion after regular one. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the selected ADC auto injected conversion - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected ADC automatic injected group conversion */ - ADCx->CR1 |= CR1_JAUTO_Set; - } - else - { - /* Disable the selected ADC automatic injected group conversion */ - ADCx->CR1 &= CR1_JAUTO_Reset; - } -} - -/** - * @brief Enables or disables the discontinuous mode for injected group - * channel for the specified ADC - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the selected ADC discontinuous mode - * on injected group channel. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected ADC injected discontinuous mode */ - ADCx->CR1 |= CR1_JDISCEN_Set; - } - else - { - /* Disable the selected ADC injected discontinuous mode */ - ADCx->CR1 &= CR1_JDISCEN_Reset; - } -} - -/** - * @brief Configures the ADCx external trigger for injected channels conversion. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_ExternalTrigInjecConv: specifies the ADC trigger to start injected conversion. - * This parameter can be one of the following values: - * @arg ADC_ExternalTrigInjecConv_T1_TRGO: Timer1 TRGO event selected (for ADC1, ADC2 and ADC3) - * @arg ADC_ExternalTrigInjecConv_T1_CC4: Timer1 capture compare4 selected (for ADC1, ADC2 and ADC3) - * @arg ADC_ExternalTrigInjecConv_T2_TRGO: Timer2 TRGO event selected (for ADC1 and ADC2) - * @arg ADC_ExternalTrigInjecConv_T2_CC1: Timer2 capture compare1 selected (for ADC1 and ADC2) - * @arg ADC_ExternalTrigInjecConv_T3_CC4: Timer3 capture compare4 selected (for ADC1 and ADC2) - * @arg ADC_ExternalTrigInjecConv_T4_TRGO: Timer4 TRGO event selected (for ADC1 and ADC2) - * @arg ADC_ExternalTrigInjecConv_Ext_IT15_TIM8_CC4: External interrupt line 15 or Timer8 - * capture compare4 event selected (for ADC1 and ADC2) - * @arg ADC_ExternalTrigInjecConv_T4_CC3: Timer4 capture compare3 selected (for ADC3 only) - * @arg ADC_ExternalTrigInjecConv_T8_CC2: Timer8 capture compare2 selected (for ADC3 only) - * @arg ADC_ExternalTrigInjecConv_T8_CC4: Timer8 capture compare4 selected (for ADC3 only) - * @arg ADC_ExternalTrigInjecConv_T5_TRGO: Timer5 TRGO event selected (for ADC3 only) - * @arg ADC_ExternalTrigInjecConv_T5_CC4: Timer5 capture compare4 selected (for ADC3 only) - * @arg ADC_ExternalTrigInjecConv_None: Injected conversion started by software and not - * by external trigger (for ADC1, ADC2 and ADC3) - * @retval None - */ -void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_EXT_INJEC_TRIG(ADC_ExternalTrigInjecConv)); - /* Get the old register value */ - tmpreg = ADCx->CR2; - /* Clear the old external event selection for injected group */ - tmpreg &= CR2_JEXTSEL_Reset; - /* Set the external event selection for injected group */ - tmpreg |= ADC_ExternalTrigInjecConv; - /* Store the new register value */ - ADCx->CR2 = tmpreg; -} - -/** - * @brief Enables or disables the ADCx injected channels conversion through - * external trigger - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the selected ADC external trigger start of - * injected conversion. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected ADC external event selection for injected group */ - ADCx->CR2 |= CR2_JEXTTRIG_Set; - } - else - { - /* Disable the selected ADC external event selection for injected group */ - ADCx->CR2 &= CR2_JEXTTRIG_Reset; - } -} - -/** - * @brief Enables or disables the selected ADC start of the injected - * channels conversion. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the selected ADC software start injected conversion. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_SoftwareStartInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected ADC conversion for injected group on external event and start the selected - ADC injected conversion */ - ADCx->CR2 |= CR2_JEXTTRIG_JSWSTART_Set; - } - else - { - /* Disable the selected ADC conversion on external event for injected group and stop the selected - ADC injected conversion */ - ADCx->CR2 &= CR2_JEXTTRIG_JSWSTART_Reset; - } -} - -/** - * @brief Gets the selected ADC Software start injected conversion Status. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @retval The new state of ADC software start injected conversion (SET or RESET). - */ -FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - /* Check the status of JSWSTART bit */ - if ((ADCx->CR2 & CR2_JSWSTART_Set) != (uint32_t)RESET) - { - /* JSWSTART bit is set */ - bitstatus = SET; - } - else - { - /* JSWSTART bit is reset */ - bitstatus = RESET; - } - /* Return the JSWSTART bit status */ - return bitstatus; -} - -/** - * @brief Configures for the selected ADC injected channel its corresponding - * rank in the sequencer and its sample time. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_Channel: the ADC channel to configure. - * This parameter can be one of the following values: - * @arg ADC_Channel_0: ADC Channel0 selected - * @arg ADC_Channel_1: ADC Channel1 selected - * @arg ADC_Channel_2: ADC Channel2 selected - * @arg ADC_Channel_3: ADC Channel3 selected - * @arg ADC_Channel_4: ADC Channel4 selected - * @arg ADC_Channel_5: ADC Channel5 selected - * @arg ADC_Channel_6: ADC Channel6 selected - * @arg ADC_Channel_7: ADC Channel7 selected - * @arg ADC_Channel_8: ADC Channel8 selected - * @arg ADC_Channel_9: ADC Channel9 selected - * @arg ADC_Channel_10: ADC Channel10 selected - * @arg ADC_Channel_11: ADC Channel11 selected - * @arg ADC_Channel_12: ADC Channel12 selected - * @arg ADC_Channel_13: ADC Channel13 selected - * @arg ADC_Channel_14: ADC Channel14 selected - * @arg ADC_Channel_15: ADC Channel15 selected - * @arg ADC_Channel_16: ADC Channel16 selected - * @arg ADC_Channel_17: ADC Channel17 selected - * @param Rank: The rank in the injected group sequencer. This parameter must be between 1 and 4. - * @param ADC_SampleTime: The sample time value to be set for the selected channel. - * This parameter can be one of the following values: - * @arg ADC_SampleTime_1Cycles5: Sample time equal to 1.5 cycles - * @arg ADC_SampleTime_7Cycles5: Sample time equal to 7.5 cycles - * @arg ADC_SampleTime_13Cycles5: Sample time equal to 13.5 cycles - * @arg ADC_SampleTime_28Cycles5: Sample time equal to 28.5 cycles - * @arg ADC_SampleTime_41Cycles5: Sample time equal to 41.5 cycles - * @arg ADC_SampleTime_55Cycles5: Sample time equal to 55.5 cycles - * @arg ADC_SampleTime_71Cycles5: Sample time equal to 71.5 cycles - * @arg ADC_SampleTime_239Cycles5: Sample time equal to 239.5 cycles - * @retval None - */ -void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) -{ - uint32_t tmpreg1 = 0, tmpreg2 = 0, tmpreg3 = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_CHANNEL(ADC_Channel)); - assert_param(IS_ADC_INJECTED_RANK(Rank)); - assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); - /* if ADC_Channel_10 ... ADC_Channel_17 is selected */ - if (ADC_Channel > ADC_Channel_9) - { - /* Get the old register value */ - tmpreg1 = ADCx->SMPR1; - /* Calculate the mask to clear */ - tmpreg2 = SMPR1_SMP_Set << (3*(ADC_Channel - 10)); - /* Clear the old channel sample time */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_SampleTime << (3*(ADC_Channel - 10)); - /* Set the new channel sample time */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SMPR1 = tmpreg1; - } - else /* ADC_Channel include in ADC_Channel_[0..9] */ - { - /* Get the old register value */ - tmpreg1 = ADCx->SMPR2; - /* Calculate the mask to clear */ - tmpreg2 = SMPR2_SMP_Set << (3 * ADC_Channel); - /* Clear the old channel sample time */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); - /* Set the new channel sample time */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SMPR2 = tmpreg1; - } - /* Rank configuration */ - /* Get the old register value */ - tmpreg1 = ADCx->JSQR; - /* Get JL value: Number = JL+1 */ - tmpreg3 = (tmpreg1 & JSQR_JL_Set)>> 20; - /* Calculate the mask to clear: ((Rank-1)+(4-JL-1)) */ - tmpreg2 = JSQR_JSQ_Set << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1))); - /* Clear the old JSQx bits for the selected rank */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set: ((Rank-1)+(4-JL-1)) */ - tmpreg2 = (uint32_t)ADC_Channel << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1))); - /* Set the JSQx bits for the selected rank */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->JSQR = tmpreg1; -} - -/** - * @brief Configures the sequencer length for injected channels - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param Length: The sequencer length. - * This parameter must be a number between 1 to 4. - * @retval None - */ -void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length) -{ - uint32_t tmpreg1 = 0; - uint32_t tmpreg2 = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_INJECTED_LENGTH(Length)); - - /* Get the old register value */ - tmpreg1 = ADCx->JSQR; - /* Clear the old injected sequnence lenght JL bits */ - tmpreg1 &= JSQR_JL_Reset; - /* Set the injected sequnence lenght JL bits */ - tmpreg2 = Length - 1; - tmpreg1 |= tmpreg2 << 20; - /* Store the new register value */ - ADCx->JSQR = tmpreg1; -} - -/** - * @brief Set the injected channels conversion value offset - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_InjectedChannel: the ADC injected channel to set its offset. - * This parameter can be one of the following values: - * @arg ADC_InjectedChannel_1: Injected Channel1 selected - * @arg ADC_InjectedChannel_2: Injected Channel2 selected - * @arg ADC_InjectedChannel_3: Injected Channel3 selected - * @arg ADC_InjectedChannel_4: Injected Channel4 selected - * @param Offset: the offset value for the selected ADC injected channel - * This parameter must be a 12bit value. - * @retval None - */ -void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel)); - assert_param(IS_ADC_OFFSET(Offset)); - - tmp = (uint32_t)ADCx; - tmp += ADC_InjectedChannel; - - /* Set the selected injected channel data offset */ - *(__IO uint32_t *) tmp = (uint32_t)Offset; -} - -/** - * @brief Returns the ADC injected channel conversion result - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_InjectedChannel: the converted ADC injected channel. - * This parameter can be one of the following values: - * @arg ADC_InjectedChannel_1: Injected Channel1 selected - * @arg ADC_InjectedChannel_2: Injected Channel2 selected - * @arg ADC_InjectedChannel_3: Injected Channel3 selected - * @arg ADC_InjectedChannel_4: Injected Channel4 selected - * @retval The Data conversion value. - */ -uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel)); - - tmp = (uint32_t)ADCx; - tmp += ADC_InjectedChannel + JDR_Offset; - - /* Returns the selected injected channel conversion data value */ - return (uint16_t) (*(__IO uint32_t*) tmp); -} - -/** - * @brief Enables or disables the analog watchdog on single/all regular - * or injected channels - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_AnalogWatchdog: the ADC analog watchdog configuration. - * This parameter can be one of the following values: - * @arg ADC_AnalogWatchdog_SingleRegEnable: Analog watchdog on a single regular channel - * @arg ADC_AnalogWatchdog_SingleInjecEnable: Analog watchdog on a single injected channel - * @arg ADC_AnalogWatchdog_SingleRegOrInjecEnable: Analog watchdog on a single regular or injected channel - * @arg ADC_AnalogWatchdog_AllRegEnable: Analog watchdog on all regular channel - * @arg ADC_AnalogWatchdog_AllInjecEnable: Analog watchdog on all injected channel - * @arg ADC_AnalogWatchdog_AllRegAllInjecEnable: Analog watchdog on all regular and injected channels - * @arg ADC_AnalogWatchdog_None: No channel guarded by the analog watchdog - * @retval None - */ -void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_ANALOG_WATCHDOG(ADC_AnalogWatchdog)); - /* Get the old register value */ - tmpreg = ADCx->CR1; - /* Clear AWDEN, AWDENJ and AWDSGL bits */ - tmpreg &= CR1_AWDMode_Reset; - /* Set the analog watchdog enable mode */ - tmpreg |= ADC_AnalogWatchdog; - /* Store the new register value */ - ADCx->CR1 = tmpreg; -} - -/** - * @brief Configures the high and low thresholds of the analog watchdog. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param HighThreshold: the ADC analog watchdog High threshold value. - * This parameter must be a 12bit value. - * @param LowThreshold: the ADC analog watchdog Low threshold value. - * This parameter must be a 12bit value. - * @retval None - */ -void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, - uint16_t LowThreshold) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_THRESHOLD(HighThreshold)); - assert_param(IS_ADC_THRESHOLD(LowThreshold)); - /* Set the ADCx high threshold */ - ADCx->HTR = HighThreshold; - /* Set the ADCx low threshold */ - ADCx->LTR = LowThreshold; -} - -/** - * @brief Configures the analog watchdog guarded single channel - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_Channel: the ADC channel to configure for the analog watchdog. - * This parameter can be one of the following values: - * @arg ADC_Channel_0: ADC Channel0 selected - * @arg ADC_Channel_1: ADC Channel1 selected - * @arg ADC_Channel_2: ADC Channel2 selected - * @arg ADC_Channel_3: ADC Channel3 selected - * @arg ADC_Channel_4: ADC Channel4 selected - * @arg ADC_Channel_5: ADC Channel5 selected - * @arg ADC_Channel_6: ADC Channel6 selected - * @arg ADC_Channel_7: ADC Channel7 selected - * @arg ADC_Channel_8: ADC Channel8 selected - * @arg ADC_Channel_9: ADC Channel9 selected - * @arg ADC_Channel_10: ADC Channel10 selected - * @arg ADC_Channel_11: ADC Channel11 selected - * @arg ADC_Channel_12: ADC Channel12 selected - * @arg ADC_Channel_13: ADC Channel13 selected - * @arg ADC_Channel_14: ADC Channel14 selected - * @arg ADC_Channel_15: ADC Channel15 selected - * @arg ADC_Channel_16: ADC Channel16 selected - * @arg ADC_Channel_17: ADC Channel17 selected - * @retval None - */ -void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_CHANNEL(ADC_Channel)); - /* Get the old register value */ - tmpreg = ADCx->CR1; - /* Clear the Analog watchdog channel select bits */ - tmpreg &= CR1_AWDCH_Reset; - /* Set the Analog watchdog channel */ - tmpreg |= ADC_Channel; - /* Store the new register value */ - ADCx->CR1 = tmpreg; -} - -/** - * @brief Enables or disables the temperature sensor and Vrefint channel. - * @param NewState: new state of the temperature sensor. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_TempSensorVrefintCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the temperature sensor and Vrefint channel*/ - ADC1->CR2 |= CR2_TSVREFE_Set; - } - else - { - /* Disable the temperature sensor and Vrefint channel*/ - ADC1->CR2 &= CR2_TSVREFE_Reset; - } -} - -/** - * @brief Checks whether the specified ADC flag is set or not. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg ADC_FLAG_AWD: Analog watchdog flag - * @arg ADC_FLAG_EOC: End of conversion flag - * @arg ADC_FLAG_JEOC: End of injected group conversion flag - * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag - * @arg ADC_FLAG_STRT: Start of regular group conversion flag - * @retval The new state of ADC_FLAG (SET or RESET). - */ -FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_GET_FLAG(ADC_FLAG)); - /* Check the status of the specified ADC flag */ - if ((ADCx->SR & ADC_FLAG) != (uint8_t)RESET) - { - /* ADC_FLAG is set */ - bitstatus = SET; - } - else - { - /* ADC_FLAG is reset */ - bitstatus = RESET; - } - /* Return the ADC_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the ADCx's pending flags. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg ADC_FLAG_AWD: Analog watchdog flag - * @arg ADC_FLAG_EOC: End of conversion flag - * @arg ADC_FLAG_JEOC: End of injected group conversion flag - * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag - * @arg ADC_FLAG_STRT: Start of regular group conversion flag - * @retval None - */ -void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_CLEAR_FLAG(ADC_FLAG)); - /* Clear the selected ADC flags */ - ADCx->SR = ~(uint32_t)ADC_FLAG; -} - -/** - * @brief Checks whether the specified ADC interrupt has occurred or not. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_IT: specifies the ADC interrupt source to check. - * This parameter can be one of the following values: - * @arg ADC_IT_EOC: End of conversion interrupt mask - * @arg ADC_IT_AWD: Analog watchdog interrupt mask - * @arg ADC_IT_JEOC: End of injected conversion interrupt mask - * @retval The new state of ADC_IT (SET or RESET). - */ -ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT) -{ - ITStatus bitstatus = RESET; - uint32_t itmask = 0, enablestatus = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_GET_IT(ADC_IT)); - /* Get the ADC IT index */ - itmask = ADC_IT >> 8; - /* Get the ADC_IT enable bit status */ - enablestatus = (ADCx->CR1 & (uint8_t)ADC_IT) ; - /* Check the status of the specified ADC interrupt */ - if (((ADCx->SR & itmask) != (uint32_t)RESET) && enablestatus) - { - /* ADC_IT is set */ - bitstatus = SET; - } - else - { - /* ADC_IT is reset */ - bitstatus = RESET; - } - /* Return the ADC_IT status */ - return bitstatus; -} - -/** - * @brief Clears the ADCxs interrupt pending bits. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_IT: specifies the ADC interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg ADC_IT_EOC: End of conversion interrupt mask - * @arg ADC_IT_AWD: Analog watchdog interrupt mask - * @arg ADC_IT_JEOC: End of injected conversion interrupt mask - * @retval None - */ -void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT) -{ - uint8_t itmask = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_IT(ADC_IT)); - /* Get the ADC IT index */ - itmask = (uint8_t)(ADC_IT >> 8); - /* Clear the selected ADC interrupt pending bits */ - ADCx->SR = ~(uint32_t)itmask; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_bkp.c b/example/libs_stm/src/stm32f10x/stm32f10x_bkp.c deleted file mode 100644 index de065648f..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_bkp.c +++ /dev/null @@ -1,311 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_bkp.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the BKP firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_bkp.h" -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup BKP - * @brief BKP driver modules - * @{ - */ - -/** @defgroup BKP_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup BKP_Private_Defines - * @{ - */ - -/* ------------ BKP registers bit address in the alias region --------------- */ -#define BKP_OFFSET (BKP_BASE - PERIPH_BASE) - -/* --- CR Register ----*/ - -/* Alias word address of TPAL bit */ -#define CR_OFFSET (BKP_OFFSET + 0x30) -#define TPAL_BitNumber 0x01 -#define CR_TPAL_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (TPAL_BitNumber * 4)) - -/* Alias word address of TPE bit */ -#define TPE_BitNumber 0x00 -#define CR_TPE_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (TPE_BitNumber * 4)) - -/* --- CSR Register ---*/ - -/* Alias word address of TPIE bit */ -#define CSR_OFFSET (BKP_OFFSET + 0x34) -#define TPIE_BitNumber 0x02 -#define CSR_TPIE_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (TPIE_BitNumber * 4)) - -/* Alias word address of TIF bit */ -#define TIF_BitNumber 0x09 -#define CSR_TIF_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (TIF_BitNumber * 4)) - -/* Alias word address of TEF bit */ -#define TEF_BitNumber 0x08 -#define CSR_TEF_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (TEF_BitNumber * 4)) - -/* ---------------------- BKP registers bit mask ------------------------ */ - -/* RTCCR register bit mask */ -#define RTCCR_CAL_Mask ((uint16_t)0xFF80) -#define RTCCR_Mask ((uint16_t)0xFC7F) - -/* CSR register bit mask */ -#define CSR_CTE_Set ((uint16_t)0x0001) -#define CSR_CTI_Set ((uint16_t)0x0002) - -/** - * @} - */ - - -/** @defgroup BKP_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup BKP_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup BKP_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup BKP_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the BKP peripheral registers to their default reset values. - * @param None - * @retval None - */ -void BKP_DeInit(void) -{ - RCC_BackupResetCmd(ENABLE); - RCC_BackupResetCmd(DISABLE); -} - -/** - * @brief Configures the Tamper Pin active level. - * @param BKP_TamperPinLevel: specifies the Tamper Pin active level. - * This parameter can be one of the following values: - * @arg BKP_TamperPinLevel_High: Tamper pin active on high level - * @arg BKP_TamperPinLevel_Low: Tamper pin active on low level - * @retval None - */ -void BKP_TamperPinLevelConfig(uint16_t BKP_TamperPinLevel) -{ - /* Check the parameters */ - assert_param(IS_BKP_TAMPER_PIN_LEVEL(BKP_TamperPinLevel)); - *(__IO uint32_t *) CR_TPAL_BB = BKP_TamperPinLevel; -} - -/** - * @brief Enables or disables the Tamper Pin activation. - * @param NewState: new state of the Tamper Pin activation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void BKP_TamperPinCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) CR_TPE_BB = (uint32_t)NewState; -} - -/** - * @brief Enables or disables the Tamper Pin Interrupt. - * @param NewState: new state of the Tamper Pin Interrupt. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void BKP_ITConfig(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) CSR_TPIE_BB = (uint32_t)NewState; -} - -/** - * @brief Select the RTC output source to output on the Tamper pin. - * @param BKP_RTCOutputSource: specifies the RTC output source. - * This parameter can be one of the following values: - * @arg BKP_RTCOutputSource_None: no RTC output on the Tamper pin. - * @arg BKP_RTCOutputSource_CalibClock: output the RTC clock with frequency - * divided by 64 on the Tamper pin. - * @arg BKP_RTCOutputSource_Alarm: output the RTC Alarm pulse signal on - * the Tamper pin. - * @arg BKP_RTCOutputSource_Second: output the RTC Second pulse signal on - * the Tamper pin. - * @retval None - */ -void BKP_RTCOutputConfig(uint16_t BKP_RTCOutputSource) -{ - uint16_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_BKP_RTC_OUTPUT_SOURCE(BKP_RTCOutputSource)); - tmpreg = BKP->RTCCR; - /* Clear CCO, ASOE and ASOS bits */ - tmpreg &= RTCCR_Mask; - - /* Set CCO, ASOE and ASOS bits according to BKP_RTCOutputSource value */ - tmpreg |= BKP_RTCOutputSource; - /* Store the new value */ - BKP->RTCCR = tmpreg; -} - -/** - * @brief Sets RTC Clock Calibration value. - * @param CalibrationValue: specifies the RTC Clock Calibration value. - * This parameter must be a number between 0 and 0x7F. - * @retval None - */ -void BKP_SetRTCCalibrationValue(uint8_t CalibrationValue) -{ - uint16_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_BKP_CALIBRATION_VALUE(CalibrationValue)); - tmpreg = BKP->RTCCR; - /* Clear CAL[6:0] bits */ - tmpreg &= RTCCR_CAL_Mask; - /* Set CAL[6:0] bits according to CalibrationValue value */ - tmpreg |= CalibrationValue; - /* Store the new value */ - BKP->RTCCR = tmpreg; -} - -/** - * @brief Writes user data to the specified Data Backup Register. - * @param BKP_DR: specifies the Data Backup Register. - * This parameter can be BKP_DRx where x:[1, 42] - * @param Data: data to write - * @retval None - */ -void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_BKP_DR(BKP_DR)); - - tmp = (uint32_t)BKP_BASE; - tmp += BKP_DR; - - *(__IO uint32_t *) tmp = Data; -} - -/** - * @brief Reads data from the specified Data Backup Register. - * @param BKP_DR: specifies the Data Backup Register. - * This parameter can be BKP_DRx where x:[1, 42] - * @retval The content of the specified Data Backup Register - */ -uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_BKP_DR(BKP_DR)); - - tmp = (uint32_t)BKP_BASE; - tmp += BKP_DR; - - return (*(__IO uint16_t *) tmp); -} - -/** - * @brief Checks whether the Tamper Pin Event flag is set or not. - * @param None - * @retval The new state of the Tamper Pin Event flag (SET or RESET). - */ -FlagStatus BKP_GetFlagStatus(void) -{ - return (FlagStatus)(*(__IO uint32_t *) CSR_TEF_BB); -} - -/** - * @brief Clears Tamper Pin Event pending flag. - * @param None - * @retval None - */ -void BKP_ClearFlag(void) -{ - /* Set CTE bit to clear Tamper Pin Event flag */ - BKP->CSR |= CSR_CTE_Set; -} - -/** - * @brief Checks whether the Tamper Pin Interrupt has occurred or not. - * @param None - * @retval The new state of the Tamper Pin Interrupt (SET or RESET). - */ -ITStatus BKP_GetITStatus(void) -{ - return (ITStatus)(*(__IO uint32_t *) CSR_TIF_BB); -} - -/** - * @brief Clears Tamper Pin Interrupt pending bit. - * @param None - * @retval None - */ -void BKP_ClearITPendingBit(void) -{ - /* Set CTI bit to clear Tamper Pin Interrupt pending bit */ - BKP->CSR |= CSR_CTI_Set; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_can.c b/example/libs_stm/src/stm32f10x/stm32f10x_can.c deleted file mode 100644 index 537f333ba..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_can.c +++ /dev/null @@ -1,990 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_can.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the CAN firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_can.h" -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup CAN - * @brief CAN driver modules - * @{ - */ - -/** @defgroup CAN_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup CAN_Private_Defines - * @{ - */ - -/* CAN Master Control Register bits */ -#define MCR_INRQ ((uint32_t)0x00000001) /* Initialization request */ -#define MCR_SLEEP ((uint32_t)0x00000002) /* Sleep mode request */ -#define MCR_TXFP ((uint32_t)0x00000004) /* Transmit FIFO priority */ -#define MCR_RFLM ((uint32_t)0x00000008) /* Receive FIFO locked mode */ -#define MCR_NART ((uint32_t)0x00000010) /* No automatic retransmission */ -#define MCR_AWUM ((uint32_t)0x00000020) /* Automatic wake up mode */ -#define MCR_ABOM ((uint32_t)0x00000040) /* Automatic bus-off management */ -#define MCR_TTCM ((uint32_t)0x00000080) /* time triggered communication */ -#define MCR_RESET ((uint32_t)0x00008000) /* time triggered communication */ -#define MCR_DBF ((uint32_t)0x00010000) /* software master reset */ - -/* CAN Master Status Register bits */ -#define MSR_INAK ((uint32_t)0x00000001) /* Initialization acknowledge */ -#define MSR_WKUI ((uint32_t)0x00000008) /* Wake-up interrupt */ -#define MSR_SLAKI ((uint32_t)0x00000010) /* Sleep acknowledge interrupt */ - -/* CAN Transmit Status Register bits */ -#define TSR_RQCP0 ((uint32_t)0x00000001) /* Request completed mailbox0 */ -#define TSR_TXOK0 ((uint32_t)0x00000002) /* Transmission OK of mailbox0 */ -#define TSR_ABRQ0 ((uint32_t)0x00000080) /* Abort request for mailbox0 */ -#define TSR_RQCP1 ((uint32_t)0x00000100) /* Request completed mailbox1 */ -#define TSR_TXOK1 ((uint32_t)0x00000200) /* Transmission OK of mailbox1 */ -#define TSR_ABRQ1 ((uint32_t)0x00008000) /* Abort request for mailbox1 */ -#define TSR_RQCP2 ((uint32_t)0x00010000) /* Request completed mailbox2 */ -#define TSR_TXOK2 ((uint32_t)0x00020000) /* Transmission OK of mailbox2 */ -#define TSR_ABRQ2 ((uint32_t)0x00800000) /* Abort request for mailbox2 */ -#define TSR_TME0 ((uint32_t)0x04000000) /* Transmit mailbox 0 empty */ -#define TSR_TME1 ((uint32_t)0x08000000) /* Transmit mailbox 1 empty */ -#define TSR_TME2 ((uint32_t)0x10000000) /* Transmit mailbox 2 empty */ - -/* CAN Receive FIFO 0 Register bits */ -#define RF0R_FULL0 ((uint32_t)0x00000008) /* FIFO 0 full */ -#define RF0R_FOVR0 ((uint32_t)0x00000010) /* FIFO 0 overrun */ -#define RF0R_RFOM0 ((uint32_t)0x00000020) /* Release FIFO 0 output mailbox */ - -/* CAN Receive FIFO 1 Register bits */ -#define RF1R_FULL1 ((uint32_t)0x00000008) /* FIFO 1 full */ -#define RF1R_FOVR1 ((uint32_t)0x00000010) /* FIFO 1 overrun */ -#define RF1R_RFOM1 ((uint32_t)0x00000020) /* Release FIFO 1 output mailbox */ - -/* CAN Error Status Register bits */ -#define ESR_EWGF ((uint32_t)0x00000001) /* Error warning flag */ -#define ESR_EPVF ((uint32_t)0x00000002) /* Error passive flag */ -#define ESR_BOFF ((uint32_t)0x00000004) /* Bus-off flag */ - -/* CAN Mailbox Transmit Request */ -#define TMIDxR_TXRQ ((uint32_t)0x00000001) /* Transmit mailbox request */ - -/* CAN Filter Master Register bits */ -#define FMR_FINIT ((uint32_t)0x00000001) /* Filter init mode */ - -/* Time out for INAK bit */ -#define INAK_TimeOut ((uint32_t)0x0000FFFF) - -/* Time out for SLAK bit */ -#define SLAK_TimeOut ((uint32_t)0x0000FFFF) - -/** - * @} - */ - -/** @defgroup CAN_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup CAN_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup CAN_Private_FunctionPrototypes - * @{ - */ - -static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit); - -/** - * @} - */ - -/** @defgroup CAN_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the CAN peripheral registers to their default reset values. - * @param CANx: where x can be 1 or 2 to select the CAN peripheral. - * @retval None. - */ -void CAN_DeInit(CAN_TypeDef* CANx) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - - if (CANx == CAN1) - { - /* Enable CAN1 reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, ENABLE); - /* Release CAN1 from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, DISABLE); - } - else - { - /* Enable CAN2 reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, ENABLE); - /* Release CAN2 from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, DISABLE); - } -} - -/** - * @brief Initializes the CAN peripheral according to the specified - * parameters in the CAN_InitStruct. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param CAN_InitStruct: pointer to a CAN_InitTypeDef structure that - * contains the configuration information for the CAN peripheral. - * @retval Constant indicates initialization succeed which will be - * CANINITFAILED or CANINITOK. - */ -uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct) -{ - uint8_t InitStatus = CANINITFAILED; - uint32_t wait_ack = 0x00000000; - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_TTCM)); - assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_ABOM)); - assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_AWUM)); - assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_NART)); - assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_RFLM)); - assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_TXFP)); - assert_param(IS_CAN_MODE(CAN_InitStruct->CAN_Mode)); - assert_param(IS_CAN_SJW(CAN_InitStruct->CAN_SJW)); - assert_param(IS_CAN_BS1(CAN_InitStruct->CAN_BS1)); - assert_param(IS_CAN_BS2(CAN_InitStruct->CAN_BS2)); - assert_param(IS_CAN_PRESCALER(CAN_InitStruct->CAN_Prescaler)); - - /* exit from sleep mode */ - CANx->MCR &= ~MCR_SLEEP; - - /* Request initialisation */ - CANx->MCR |= MCR_INRQ ; - - /* Wait the acknowledge */ - while (((CANx->MSR & MSR_INAK) != MSR_INAK) && (wait_ack != INAK_TimeOut)) - { - wait_ack++; - } - - /* ...and check acknowledged */ - if ((CANx->MSR & MSR_INAK) != MSR_INAK) - { - InitStatus = CANINITFAILED; - } - else - { - /* Set the time triggered communication mode */ - if (CAN_InitStruct->CAN_TTCM == ENABLE) - { - CANx->MCR |= MCR_TTCM; - } - else - { - CANx->MCR &= ~MCR_TTCM; - } - - /* Set the automatic bus-off management */ - if (CAN_InitStruct->CAN_ABOM == ENABLE) - { - CANx->MCR |= MCR_ABOM; - } - else - { - CANx->MCR &= ~MCR_ABOM; - } - - /* Set the automatic wake-up mode */ - if (CAN_InitStruct->CAN_AWUM == ENABLE) - { - CANx->MCR |= MCR_AWUM; - } - else - { - CANx->MCR &= ~MCR_AWUM; - } - - /* Set the no automatic retransmission */ - if (CAN_InitStruct->CAN_NART == ENABLE) - { - CANx->MCR |= MCR_NART; - } - else - { - CANx->MCR &= ~MCR_NART; - } - - /* Set the receive FIFO locked mode */ - if (CAN_InitStruct->CAN_RFLM == ENABLE) - { - CANx->MCR |= MCR_RFLM; - } - else - { - CANx->MCR &= ~MCR_RFLM; - } - - /* Set the transmit FIFO priority */ - if (CAN_InitStruct->CAN_TXFP == ENABLE) - { - CANx->MCR |= MCR_TXFP; - } - else - { - CANx->MCR &= ~MCR_TXFP; - } - - /* Set the bit timing register */ - CANx->BTR = (uint32_t)((uint32_t)CAN_InitStruct->CAN_Mode << 30) | ((uint32_t)CAN_InitStruct->CAN_SJW << 24) | - ((uint32_t)CAN_InitStruct->CAN_BS1 << 16) | ((uint32_t)CAN_InitStruct->CAN_BS2 << 20) | - ((uint32_t)CAN_InitStruct->CAN_Prescaler - 1); - - /* Request leave initialisation */ - CANx->MCR &= ~MCR_INRQ; - - /* Wait the acknowledge */ - wait_ack = 0x00; - - while (((CANx->MSR & MSR_INAK) == MSR_INAK) && (wait_ack != INAK_TimeOut)) - { - wait_ack++; - } - - /* ...and check acknowledged */ - if ((CANx->MSR & MSR_INAK) == MSR_INAK) - { - InitStatus = CANINITFAILED; - } - else - { - InitStatus = CANINITOK ; - } - } - - /* At this step, return the status of initialization */ - return InitStatus; -} - -/** - * @brief Initializes the CAN peripheral according to the specified - * parameters in the CAN_FilterInitStruct. - * @param CAN_FilterInitStruct: pointer to a CAN_FilterInitTypeDef - * structure that contains the configuration information. - * @retval None. - */ -void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct) -{ - uint32_t filter_number_bit_pos = 0; - /* Check the parameters */ - assert_param(IS_CAN_FILTER_NUMBER(CAN_FilterInitStruct->CAN_FilterNumber)); - assert_param(IS_CAN_FILTER_MODE(CAN_FilterInitStruct->CAN_FilterMode)); - assert_param(IS_CAN_FILTER_SCALE(CAN_FilterInitStruct->CAN_FilterScale)); - assert_param(IS_CAN_FILTER_FIFO(CAN_FilterInitStruct->CAN_FilterFIFOAssignment)); - assert_param(IS_FUNCTIONAL_STATE(CAN_FilterInitStruct->CAN_FilterActivation)); - - filter_number_bit_pos = ((uint32_t)0x00000001) << CAN_FilterInitStruct->CAN_FilterNumber; - - /* Initialisation mode for the filter */ - CAN1->FMR |= FMR_FINIT; - - /* Filter Deactivation */ - CAN1->FA1R &= ~(uint32_t)filter_number_bit_pos; - - /* Filter Scale */ - if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_16bit) - { - /* 16-bit scale for the filter */ - CAN1->FS1R &= ~(uint32_t)filter_number_bit_pos; - - /* First 16-bit identifier and First 16-bit mask */ - /* Or First 16-bit identifier and Second 16-bit identifier */ - CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 = - ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow) << 16) | - (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow); - - /* Second 16-bit identifier and Second 16-bit mask */ - /* Or Third 16-bit identifier and Fourth 16-bit identifier */ - CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 = - ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) | - (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh); - } - - if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_32bit) - { - /* 32-bit scale for the filter */ - CAN1->FS1R |= filter_number_bit_pos; - /* 32-bit identifier or First 32-bit identifier */ - CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 = - ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh) << 16) | - (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow); - /* 32-bit mask or Second 32-bit identifier */ - CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 = - ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) | - (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow); - } - - /* Filter Mode */ - if (CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdMask) - { - /*Id/Mask mode for the filter*/ - CAN1->FM1R &= ~(uint32_t)filter_number_bit_pos; - } - else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */ - { - /*Identifier list mode for the filter*/ - CAN1->FM1R |= (uint32_t)filter_number_bit_pos; - } - - /* Filter FIFO assignment */ - if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_FilterFIFO0) - { - /* FIFO 0 assignation for the filter */ - CAN1->FFA1R &= ~(uint32_t)filter_number_bit_pos; - } - - if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_FilterFIFO1) - { - /* FIFO 1 assignation for the filter */ - CAN1->FFA1R |= (uint32_t)filter_number_bit_pos; - } - - /* Filter activation */ - if (CAN_FilterInitStruct->CAN_FilterActivation == ENABLE) - { - CAN1->FA1R |= filter_number_bit_pos; - } - - /* Leave the initialisation mode for the filter */ - CAN1->FMR &= ~FMR_FINIT; -} - -/** - * @brief Fills each CAN_InitStruct member with its default value. - * @param CAN_InitStruct: pointer to a CAN_InitTypeDef structure which - * will be initialized. - * @retval None. - */ -void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct) -{ - /* Reset CAN init structure parameters values */ - /* Initialize the time triggered communication mode */ - CAN_InitStruct->CAN_TTCM = DISABLE; - /* Initialize the automatic bus-off management */ - CAN_InitStruct->CAN_ABOM = DISABLE; - /* Initialize the automatic wake-up mode */ - CAN_InitStruct->CAN_AWUM = DISABLE; - /* Initialize the no automatic retransmission */ - CAN_InitStruct->CAN_NART = DISABLE; - /* Initialize the receive FIFO locked mode */ - CAN_InitStruct->CAN_RFLM = DISABLE; - /* Initialize the transmit FIFO priority */ - CAN_InitStruct->CAN_TXFP = DISABLE; - /* Initialize the CAN_Mode member */ - CAN_InitStruct->CAN_Mode = CAN_Mode_Normal; - /* Initialize the CAN_SJW member */ - CAN_InitStruct->CAN_SJW = CAN_SJW_1tq; - /* Initialize the CAN_BS1 member */ - CAN_InitStruct->CAN_BS1 = CAN_BS1_4tq; - /* Initialize the CAN_BS2 member */ - CAN_InitStruct->CAN_BS2 = CAN_BS2_3tq; - /* Initialize the CAN_Prescaler member */ - CAN_InitStruct->CAN_Prescaler = 1; -} - -/** - * @brief Select the start bank filter for slave CAN. - * @note This function applies only to STM32 Connectivity line devices. - * @param CAN_BankNumber: Select the start slave bank filter from 1..27. - * @retval None. - */ -void CAN_SlaveStartBank(uint8_t CAN_BankNumber) -{ - /* Check the parameters */ - assert_param(IS_CAN_BANKNUMBER(CAN_BankNumber)); - /* enter Initialisation mode for the filter */ - CAN1->FMR |= FMR_FINIT; - /* Select the start slave bank */ - CAN1->FMR &= (uint32_t)0xFFFFC0F1 ; - CAN1->FMR |= (uint32_t)(CAN_BankNumber)<<8; - /* Leave Initialisation mode for the filter */ - CAN1->FMR &= ~FMR_FINIT; -} - -/** - * @brief Enables or disables the specified CAN interrupts. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param CAN_IT: specifies the CAN interrupt sources to be enabled or disabled. - * This parameter can be: CAN_IT_TME, CAN_IT_FMP0, CAN_IT_FF0, - * CAN_IT_FOV0, CAN_IT_FMP1, CAN_IT_FF1, - * CAN_IT_FOV1, CAN_IT_EWG, CAN_IT_EPV, - * CAN_IT_LEC, CAN_IT_ERR, CAN_IT_WKU or - * CAN_IT_SLK. - * @param NewState: new state of the CAN interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None. - */ -void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_ITConfig(CAN_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected CAN interrupt */ - CANx->IER |= CAN_IT; - } - else - { - /* Disable the selected CAN interrupt */ - CANx->IER &= ~CAN_IT; - } -} - -/** - * @brief Initiates the transmission of a message. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param TxMessage: pointer to a structure which contains CAN Id, CAN - * DLC and CAN datas. - * @retval The number of the mailbox that is used for transmission - * or CAN_NO_MB if there is no empty mailbox. - */ -uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage) -{ - uint8_t transmit_mailbox = 0; - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_IDTYPE(TxMessage->IDE)); - assert_param(IS_CAN_RTR(TxMessage->RTR)); - assert_param(IS_CAN_DLC(TxMessage->DLC)); - - /* Select one empty transmit mailbox */ - if ((CANx->TSR&TSR_TME0) == TSR_TME0) - { - transmit_mailbox = 0; - } - else if ((CANx->TSR&TSR_TME1) == TSR_TME1) - { - transmit_mailbox = 1; - } - else if ((CANx->TSR&TSR_TME2) == TSR_TME2) - { - transmit_mailbox = 2; - } - else - { - transmit_mailbox = CAN_NO_MB; - } - - if (transmit_mailbox != CAN_NO_MB) - { - /* Set up the Id */ - CANx->sTxMailBox[transmit_mailbox].TIR &= TMIDxR_TXRQ; - if (TxMessage->IDE == CAN_ID_STD) - { - assert_param(IS_CAN_STDID(TxMessage->StdId)); - CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->StdId << 21) | TxMessage->RTR); - } - else - { - assert_param(IS_CAN_EXTID(TxMessage->ExtId)); - CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->ExtId<<3) | TxMessage->IDE | - TxMessage->RTR); - } - - - /* Set up the DLC */ - TxMessage->DLC &= (uint8_t)0x0000000F; - CANx->sTxMailBox[transmit_mailbox].TDTR &= (uint32_t)0xFFFFFFF0; - CANx->sTxMailBox[transmit_mailbox].TDTR |= TxMessage->DLC; - - /* Set up the data field */ - CANx->sTxMailBox[transmit_mailbox].TDLR = (((uint32_t)TxMessage->Data[3] << 24) | - ((uint32_t)TxMessage->Data[2] << 16) | - ((uint32_t)TxMessage->Data[1] << 8) | - ((uint32_t)TxMessage->Data[0])); - CANx->sTxMailBox[transmit_mailbox].TDHR = (((uint32_t)TxMessage->Data[7] << 24) | - ((uint32_t)TxMessage->Data[6] << 16) | - ((uint32_t)TxMessage->Data[5] << 8) | - ((uint32_t)TxMessage->Data[4])); - /* Request transmission */ - CANx->sTxMailBox[transmit_mailbox].TIR |= TMIDxR_TXRQ; - } - return transmit_mailbox; -} - -/** - * @brief Checks the transmission of a message. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param TransmitMailbox: the number of the mailbox that is used for transmission. - * @retval CANTXOK if the CAN driver transmits the message, CANTXFAILED in an other case. - */ -uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox) -{ - /* RQCP, TXOK and TME bits */ - uint8_t state = 0; - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_TRANSMITMAILBOX(TransmitMailbox)); - switch (TransmitMailbox) - { - case (0): state |= (uint8_t)((CANx->TSR & TSR_RQCP0) << 2); - state |= (uint8_t)((CANx->TSR & TSR_TXOK0) >> 0); - state |= (uint8_t)((CANx->TSR & TSR_TME0) >> 26); - break; - case (1): state |= (uint8_t)((CANx->TSR & TSR_RQCP1) >> 6); - state |= (uint8_t)((CANx->TSR & TSR_TXOK1) >> 8); - state |= (uint8_t)((CANx->TSR & TSR_TME1) >> 27); - break; - case (2): state |= (uint8_t)((CANx->TSR & TSR_RQCP2) >> 14); - state |= (uint8_t)((CANx->TSR & TSR_TXOK2) >> 16); - state |= (uint8_t)((CANx->TSR & TSR_TME2) >> 28); - break; - default: - state = CANTXFAILED; - break; - } - switch (state) - { - /* transmit pending */ - case (0x0): state = CANTXPENDING; - break; - /* transmit failed */ - case (0x5): state = CANTXFAILED; - break; - /* transmit succedeed */ - case (0x7): state = CANTXOK; - break; - default: - state = CANTXFAILED; - break; - } - return state; -} - -/** - * @brief Cancels a transmit request. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param Mailbox: Mailbox number. - * @retval None. - */ -void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_TRANSMITMAILBOX(Mailbox)); - /* abort transmission */ - switch (Mailbox) - { - case (0): CANx->TSR |= TSR_ABRQ0; - break; - case (1): CANx->TSR |= TSR_ABRQ1; - break; - case (2): CANx->TSR |= TSR_ABRQ2; - break; - default: - break; - } -} - -/** - * @brief Releases a FIFO. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param FIFONumber: FIFO to release, CAN_FIFO0 or CAN_FIFO1. - * @retval None. - */ -void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_FIFO(FIFONumber)); - /* Release FIFO0 */ - if (FIFONumber == CAN_FIFO0) - { - CANx->RF0R = RF0R_RFOM0; - } - /* Release FIFO1 */ - else /* FIFONumber == CAN_FIFO1 */ - { - CANx->RF1R = RF1R_RFOM1; - } -} - -/** - * @brief Returns the number of pending messages. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1. - * @retval NbMessage which is the number of pending message. - */ -uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber) -{ - uint8_t message_pending=0; - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_FIFO(FIFONumber)); - if (FIFONumber == CAN_FIFO0) - { - message_pending = (uint8_t)(CANx->RF0R&(uint32_t)0x03); - } - else if (FIFONumber == CAN_FIFO1) - { - message_pending = (uint8_t)(CANx->RF1R&(uint32_t)0x03); - } - else - { - message_pending = 0; - } - return message_pending; -} - -/** - * @brief Receives a message. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1. - * @param RxMessage: pointer to a structure receive message which - * contains CAN Id, CAN DLC, CAN datas and FMI number. - * @retval None. - */ -void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_FIFO(FIFONumber)); - /* Get the Id */ - RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONumber].RIR; - if (RxMessage->IDE == CAN_ID_STD) - { - RxMessage->StdId = (uint32_t)0x000007FF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 21); - } - else - { - RxMessage->ExtId = (uint32_t)0x1FFFFFFF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 3); - } - - RxMessage->RTR = (uint8_t)0x02 & CANx->sFIFOMailBox[FIFONumber].RIR; - /* Get the DLC */ - RxMessage->DLC = (uint8_t)0x0F & CANx->sFIFOMailBox[FIFONumber].RDTR; - /* Get the FMI */ - RxMessage->FMI = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDTR >> 8); - /* Get the data field */ - RxMessage->Data[0] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDLR; - RxMessage->Data[1] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 8); - RxMessage->Data[2] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 16); - RxMessage->Data[3] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 24); - RxMessage->Data[4] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDHR; - RxMessage->Data[5] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 8); - RxMessage->Data[6] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 16); - RxMessage->Data[7] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 24); - /* Release the FIFO */ - CAN_FIFORelease(CANx, FIFONumber); -} - -/** - * @brief Enables or disables the DBG Freeze for CAN. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param NewState: new state of the CAN peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None. - */ -void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable Debug Freeze */ - CANx->MCR |= MCR_DBF; - } - else - { - /* Disable Debug Freeze */ - CANx->MCR &= ~MCR_DBF; - } -} - -/** - * @brief Enters the low power mode. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @retval CANSLEEPOK if sleep entered, CANSLEEPFAILED in an other case. - */ -uint8_t CAN_Sleep(CAN_TypeDef* CANx) -{ - uint8_t sleepstatus = CANSLEEPFAILED; - - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - - /* Request Sleep mode */ - CANx->MCR = (((CANx->MCR) & (uint32_t)(~MCR_INRQ)) | MCR_SLEEP); - - /* Sleep mode status */ - if ((CANx->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) == CAN_MSR_SLAK) - { - /* Sleep mode not entered */ - sleepstatus = CANSLEEPOK; - } - /* At this step, sleep mode status */ - return (uint8_t)sleepstatus; -} - -/** - * @brief Wakes the CAN up. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @retval CANWAKEUPOK if sleep mode left, CANWAKEUPFAILED in an other case. - */ -uint8_t CAN_WakeUp(CAN_TypeDef* CANx) -{ - uint32_t wait_slak = SLAK_TimeOut ; - uint8_t wakeupstatus = CANWAKEUPFAILED; - - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - - /* Wake up request */ - CANx->MCR &= ~MCR_SLEEP; - - /* Sleep mode status */ - while(((CANx->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)&&(wait_slak!=0x00)) - { - wait_slak--; - } - if((CANx->MSR & CAN_MSR_SLAK) != CAN_MSR_SLAK) - { - /* Sleep mode exited */ - wakeupstatus = CANWAKEUPOK; - } - /* At this step, sleep mode status */ - return (uint8_t)wakeupstatus; -} - -/** - * @brief Checks whether the specified CAN flag is set or not. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param CAN_FLAG: specifies the flag to check. - * This parameter can be: CAN_FLAG_EWG, CAN_FLAG_EPV or CAN_FLAG_BOF. - * @retval The new state of CAN_FLAG (SET or RESET). - */ -FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_FLAG(CAN_FLAG)); - /* Check the status of the specified CAN flag */ - if ((CANx->ESR & CAN_FLAG) != (uint32_t)RESET) - { - /* CAN_FLAG is set */ - bitstatus = SET; - } - else - { - /* CAN_FLAG is reset */ - bitstatus = RESET; - } - /* Return the CAN_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the CAN's pending flags. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param CAN_FLAG: specifies the flag to clear. - * @retval None. - */ -void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_FLAG(CAN_FLAG)); - /* Clear the selected CAN flags */ - CANx->ESR &= ~CAN_FLAG; -} - -/** - * @brief Checks whether the specified CAN interrupt has occurred or not. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param CAN_IT: specifies the CAN interrupt source to check. - * This parameter can be: CAN_IT_RQCP0, CAN_IT_RQCP1, CAN_IT_RQCP2, - * CAN_IT_FF0, CAN_IT_FOV0, CAN_IT_FF1, - * CAN_IT_FOV1, CAN_IT_EWG, CAN_IT_EPV, - * CAN_IT_BOF, CAN_IT_WKU or CAN_IT_SLK. - * @retval The new state of CAN_IT (SET or RESET). - */ -ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT) -{ - ITStatus pendingbitstatus = RESET; - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_ITStatus(CAN_IT)); - switch (CAN_IT) - { - case CAN_IT_RQCP0: - pendingbitstatus = CheckITStatus(CANx->TSR, TSR_RQCP0); - break; - case CAN_IT_RQCP1: - pendingbitstatus = CheckITStatus(CANx->TSR, TSR_RQCP1); - break; - case CAN_IT_RQCP2: - pendingbitstatus = CheckITStatus(CANx->TSR, TSR_RQCP2); - break; - case CAN_IT_FF0: - pendingbitstatus = CheckITStatus(CANx->RF0R, RF0R_FULL0); - break; - case CAN_IT_FOV0: - pendingbitstatus = CheckITStatus(CANx->RF0R, RF0R_FOVR0); - break; - case CAN_IT_FF1: - pendingbitstatus = CheckITStatus(CANx->RF1R, RF1R_FULL1); - break; - case CAN_IT_FOV1: - pendingbitstatus = CheckITStatus(CANx->RF1R, RF1R_FOVR1); - break; - case CAN_IT_EWG: - pendingbitstatus = CheckITStatus(CANx->ESR, ESR_EWGF); - break; - case CAN_IT_EPV: - pendingbitstatus = CheckITStatus(CANx->ESR, ESR_EPVF); - break; - case CAN_IT_BOF: - pendingbitstatus = CheckITStatus(CANx->ESR, ESR_BOFF); - break; - case CAN_IT_SLK: - pendingbitstatus = CheckITStatus(CANx->MSR, MSR_SLAKI); - break; - case CAN_IT_WKU: - pendingbitstatus = CheckITStatus(CANx->MSR, MSR_WKUI); - break; - default : - pendingbitstatus = RESET; - break; - } - /* Return the CAN_IT status */ - return pendingbitstatus; -} - -/** - * @brief Clears the CANs interrupt pending bits. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param CAN_IT: specifies the interrupt pending bit to clear. - * @retval None. - */ -void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_ITStatus(CAN_IT)); - switch (CAN_IT) - { - case CAN_IT_RQCP0: - CANx->TSR = TSR_RQCP0; /* rc_w1*/ - break; - case CAN_IT_RQCP1: - CANx->TSR = TSR_RQCP1; /* rc_w1*/ - break; - case CAN_IT_RQCP2: - CANx->TSR = TSR_RQCP2; /* rc_w1*/ - break; - case CAN_IT_FF0: - CANx->RF0R = RF0R_FULL0; /* rc_w1*/ - break; - case CAN_IT_FOV0: - CANx->RF0R = RF0R_FOVR0; /* rc_w1*/ - break; - case CAN_IT_FF1: - CANx->RF1R = RF1R_FULL1; /* rc_w1*/ - break; - case CAN_IT_FOV1: - CANx->RF1R = RF1R_FOVR1; /* rc_w1*/ - break; - case CAN_IT_EWG: - CANx->ESR &= ~ ESR_EWGF; /* rw */ - break; - case CAN_IT_EPV: - CANx->ESR &= ~ ESR_EPVF; /* rw */ - break; - case CAN_IT_BOF: - CANx->ESR &= ~ ESR_BOFF; /* rw */ - break; - case CAN_IT_WKU: - CANx->MSR = MSR_WKUI; /* rc_w1*/ - break; - case CAN_IT_SLK: - CANx->MSR = MSR_SLAKI; /* rc_w1*/ - break; - default : - break; - } -} - -/** - * @brief Checks whether the CAN interrupt has occurred or not. - * @param CAN_Reg: specifies the CAN interrupt register to check. - * @param It_Bit: specifies the interrupt source bit to check. - * @retval The new state of the CAN Interrupt (SET or RESET). - */ -static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit) -{ - ITStatus pendingbitstatus = RESET; - - if ((CAN_Reg & It_Bit) != (uint32_t)RESET) - { - /* CAN_IT is set */ - pendingbitstatus = SET; - } - else - { - /* CAN_IT is reset */ - pendingbitstatus = RESET; - } - return pendingbitstatus; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_cec.c b/example/libs_stm/src/stm32f10x/stm32f10x_cec.c deleted file mode 100644 index 4ae244569..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_cec.c +++ /dev/null @@ -1,432 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_cec.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the CEC firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_cec.h" -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup CEC - * @brief CEC driver modules - * @{ - */ - -/** @defgroup CEC_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - - -/** @defgroup CEC_Private_Defines - * @{ - */ - -/* ------------ CEC registers bit address in the alias region ----------- */ -#define CEC_OFFSET (CEC_BASE - PERIPH_BASE) - -/* --- CFGR Register ---*/ - -/* Alias word address of PE bit */ -#define CFGR_OFFSET (CEC_OFFSET + 0x00) -#define PE_BitNumber 0x00 -#define CFGR_PE_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (PE_BitNumber * 4)) - -/* Alias word address of IE bit */ -#define IE_BitNumber 0x01 -#define CFGR_IE_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (IE_BitNumber * 4)) - -/* --- CSR Register ---*/ - -/* Alias word address of TSOM bit */ -#define CSR_OFFSET (CEC_OFFSET + 0x10) -#define TSOM_BitNumber 0x00 -#define CSR_TSOM_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (TSOM_BitNumber * 4)) - -/* Alias word address of TEOM bit */ -#define TEOM_BitNumber 0x01 -#define CSR_TEOM_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (TEOM_BitNumber * 4)) - -#define CFGR_CLEAR_Mask (uint8_t)(0xF3) /* CFGR register Mask */ -#define FLAG_Mask ((uint32_t)0x00FFFFFF) /* CEC FLAG mask */ - -/** - * @} - */ - - -/** @defgroup CEC_Private_Macros - * @{ - */ - -/** - * @} - */ - - -/** @defgroup CEC_Private_Variables - * @{ - */ - -/** - * @} - */ - - -/** @defgroup CEC_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - - -/** @defgroup CEC_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the CEC peripheral registers to their default reset - * values. - * @param None - * @retval None - */ -void CEC_DeInit(void) -{ - /* Enable CEC reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_CEC, ENABLE); - /* Release CEC from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_CEC, DISABLE); -} - - -/** - * @brief Initializes the CEC peripheral according to the specified - * parameters in the CEC_InitStruct. - * @param CEC_InitStruct: pointer to an CEC_InitTypeDef structure that - * contains the configuration information for the specified - * CEC peripheral. - * @retval None - */ -void CEC_Init(CEC_InitTypeDef* CEC_InitStruct) -{ - uint16_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_CEC_BIT_TIMING_ERROR_MODE(CEC_InitStruct->CEC_BitTimingMode)); - assert_param(IS_CEC_BIT_PERIOD_ERROR_MODE(CEC_InitStruct->CEC_BitPeriodMode)); - - /*---------------------------- CEC CFGR Configuration -----------------*/ - /* Get the CEC CFGR value */ - tmpreg = CEC->CFGR; - - /* Clear BTEM and BPEM bits */ - tmpreg &= CFGR_CLEAR_Mask; - - /* Configure CEC: Bit Timing Error and Bit Period Error */ - tmpreg |= (uint16_t)(CEC_InitStruct->CEC_BitTimingMode | CEC_InitStruct->CEC_BitPeriodMode); - - /* Write to CEC CFGR register*/ - CEC->CFGR = tmpreg; - -} - -/** - * @brief Enables or disables the specified CEC peripheral. - * @param NewState: new state of the CEC peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void CEC_Cmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CFGR_PE_BB = (uint32_t)NewState; - - if(NewState == DISABLE) - { - /* Wait until the PE bit is cleared by hardware (Idle Line detected) */ - while((CEC->CFGR & CEC_CFGR_PE) != (uint32_t)RESET) - { - } - } -} - -/** - * @brief Enables or disables the CEC interrupt. - * @param NewState: new state of the CEC interrupt. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void CEC_ITConfig(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CFGR_IE_BB = (uint32_t)NewState; -} - -/** - * @brief Defines the Own Address of the CEC device. - * @param CEC_OwnAddress: The CEC own address - * @retval None - */ -void CEC_OwnAddressConfig(uint8_t CEC_OwnAddress) -{ - /* Check the parameters */ - assert_param(IS_CEC_ADDRESS(CEC_OwnAddress)); - - /* Set the CEC own address */ - CEC->OAR = CEC_OwnAddress; -} - -/** - * @brief Sets the CEC prescaler value. - * @param CEC_Prescaler: CEC prescaler new value - * @retval None - */ -void CEC_SetPrescaler(uint16_t CEC_Prescaler) -{ - /* Check the parameters */ - assert_param(IS_CEC_PRESCALER(CEC_Prescaler)); - - /* Set the Prescaler value*/ - CEC->PRES = CEC_Prescaler; -} - -/** - * @brief Transmits single data through the CEC peripheral. - * @param Data: the data to transmit. - * @retval None - */ -void CEC_SendDataByte(uint8_t Data) -{ - /* Transmit Data */ - CEC->TXD = Data ; -} - - -/** - * @brief Returns the most recent received data by the CEC peripheral. - * @param None - * @retval The received data. - */ -uint8_t CEC_ReceiveDataByte(void) -{ - /* Receive Data */ - return (uint8_t)(CEC->RXD); -} - -/** - * @brief Starts a new message. - * @param None - * @retval None - */ -void CEC_StartOfMessage(void) -{ - /* Starts of new message */ - *(__IO uint32_t *) CSR_TSOM_BB = (uint32_t)0x1; -} - -/** - * @brief Transmits message with or without an EOM bit. - * @param NewState: new state of the CEC Tx End Of Message. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void CEC_EndOfMessageCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* The data byte will be transmitted with or without an EOM bit*/ - *(__IO uint32_t *) CSR_TEOM_BB = (uint32_t)NewState; -} - -/** - * @brief Gets the CEC flag status - * @param CEC_FLAG: specifies the CEC flag to check. - * This parameter can be one of the following values: - * @arg CEC_FLAG_BTE: Bit Timing Error - * @arg CEC_FLAG_BPE: Bit Period Error - * @arg CEC_FLAG_RBTFE: Rx Block Transfer Finished Error - * @arg CEC_FLAG_SBE: Start Bit Error - * @arg CEC_FLAG_ACKE: Block Acknowledge Error - * @arg CEC_FLAG_LINE: Line Error - * @arg CEC_FLAG_TBTFE: Tx Block Transfer Finsihed Error - * @arg CEC_FLAG_TEOM: Tx End Of Message - * @arg CEC_FLAG_TERR: Tx Error - * @arg CEC_FLAG_TBTRF: Tx Byte Transfer Request or Block Transfer Finished - * @arg CEC_FLAG_RSOM: Rx Start Of Message - * @arg CEC_FLAG_REOM: Rx End Of Message - * @arg CEC_FLAG_RERR: Rx Error - * @arg CEC_FLAG_RBTF: Rx Byte/Block Transfer Finished - * @retval The new state of CEC_FLAG (SET or RESET) - */ -FlagStatus CEC_GetFlagStatus(uint32_t CEC_FLAG) -{ - FlagStatus bitstatus = RESET; - uint32_t cecreg = 0, cecbase = 0; - - /* Check the parameters */ - assert_param(IS_CEC_GET_FLAG(CEC_FLAG)); - - /* Get the CEC peripheral base address */ - cecbase = (uint32_t)(CEC_BASE); - - /* Read flag register index */ - cecreg = CEC_FLAG >> 28; - - /* Get bit[23:0] of the flag */ - CEC_FLAG &= FLAG_Mask; - - if(cecreg != 0) - { - /* Flag in CEC ESR Register */ - CEC_FLAG = (uint32_t)(CEC_FLAG >> 16); - - /* Get the CEC ESR register address */ - cecbase += 0xC; - } - else - { - /* Get the CEC CSR register address */ - cecbase += 0x10; - } - - if(((*(__IO uint32_t *)cecbase) & CEC_FLAG) != (uint32_t)RESET) - { - /* CEC_FLAG is set */ - bitstatus = SET; - } - else - { - /* CEC_FLAG is reset */ - bitstatus = RESET; - } - - /* Return the CEC_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the CEC's pending flags. - * @param CEC_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg CEC_FLAG_TERR: Tx Error - * @arg CEC_FLAG_TBTRF: Tx Byte Transfer Request or Block Transfer Finished - * @arg CEC_FLAG_RSOM: Rx Start Of Message - * @arg CEC_FLAG_REOM: Rx End Of Message - * @arg CEC_FLAG_RERR: Rx Error - * @arg CEC_FLAG_RBTF: Rx Byte/Block Transfer Finished - * @retval None - */ -void CEC_ClearFlag(uint32_t CEC_FLAG) -{ - uint32_t tmp = 0x0; - - /* Check the parameters */ - assert_param(IS_CEC_CLEAR_FLAG(CEC_FLAG)); - - tmp = CEC->CSR & 0x2; - - /* Clear the selected CEC flags */ - CEC->CSR &= (uint32_t)(((~(uint32_t)CEC_FLAG) & 0xFFFFFFFC) | tmp); -} - -/** - * @brief Checks whether the specified CEC interrupt has occurred or not. - * @param CEC_IT: specifies the CEC interrupt source to check. - * This parameter can be one of the following values: - * @arg CEC_IT_TERR: Tx Error - * @arg CEC_IT_TBTF: Tx Block Transfer Finished - * @arg CEC_IT_RERR: Rx Error - * @arg CEC_IT_RBTF: Rx Block Transfer Finished - * @retval The new state of CEC_IT (SET or RESET). - */ -ITStatus CEC_GetITStatus(uint8_t CEC_IT) -{ - ITStatus bitstatus = RESET; - uint32_t enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_CEC_GET_IT(CEC_IT)); - - /* Get the CEC IT enable bit status */ - enablestatus = (CEC->CFGR & (uint8_t)CEC_CFGR_IE) ; - - /* Check the status of the specified CEC interrupt */ - if (((CEC->CSR & CEC_IT) != (uint32_t)RESET) && enablestatus) - { - /* CEC_IT is set */ - bitstatus = SET; - } - else - { - /* CEC_IT is reset */ - bitstatus = RESET; - } - /* Return the CEC_IT status */ - return bitstatus; -} - -/** - * @brief Clears the CEC's interrupt pending bits. - * @param CEC_IT: specifies the CEC interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg CEC_IT_TERR: Tx Error - * @arg CEC_IT_TBTF: Tx Block Transfer Finished - * @arg CEC_IT_RERR: Rx Error - * @arg CEC_IT_RBTF: Rx Block Transfer Finished - * @retval None - */ -void CEC_ClearITPendingBit(uint16_t CEC_IT) -{ - uint32_t tmp = 0x0; - - /* Check the parameters */ - assert_param(IS_CEC_GET_IT(CEC_IT)); - - tmp = CEC->CSR & 0x2; - - /* Clear the selected CEC interrupt pending bits */ - CEC->CSR &= (uint32_t)(((~(uint32_t)CEC_IT) & 0xFFFFFFFC) | tmp); -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_crc.c b/example/libs_stm/src/stm32f10x/stm32f10x_crc.c deleted file mode 100644 index c9291f4c4..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_crc.c +++ /dev/null @@ -1,163 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_crc.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the CRC firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_crc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup CRC - * @brief CRC driver modules - * @{ - */ - -/** @defgroup CRC_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup CRC_Private_Defines - * @{ - */ - -/* CR register bit mask */ - -#define CR_RESET_Set ((uint32_t)0x00000001) - -/** - * @} - */ - -/** @defgroup CRC_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup CRC_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup CRC_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup CRC_Private_Functions - * @{ - */ - -/** - * @brief Resets the CRC Data register (DR). - * @param None - * @retval None - */ -void CRC_ResetDR(void) -{ - /* Reset CRC generator */ - CRC->CR = CR_RESET_Set; -} - -/** - * @brief Computes the 32-bit CRC of a given data word(32-bit). - * @param Data: data word(32-bit) to compute its CRC - * @retval 32-bit CRC - */ -uint32_t CRC_CalcCRC(uint32_t Data) -{ - CRC->DR = Data; - - return (CRC->DR); -} - -/** - * @brief Computes the 32-bit CRC of a given buffer of data word(32-bit). - * @param pBuffer: pointer to the buffer containing the data to be computed - * @param BufferLength: length of the buffer to be computed - * @retval 32-bit CRC - */ -uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength) -{ - uint32_t index = 0; - - for(index = 0; index < BufferLength; index++) - { - CRC->DR = pBuffer[index]; - } - return (CRC->DR); -} - -/** - * @brief Returns the current CRC value. - * @param None - * @retval 32-bit CRC - */ -uint32_t CRC_GetCRC(void) -{ - return (CRC->DR); -} - -/** - * @brief Stores a 8-bit data in the Independent Data(ID) register. - * @param IDValue: 8-bit value to be stored in the ID register - * @retval None - */ -void CRC_SetIDRegister(uint8_t IDValue) -{ - CRC->IDR = IDValue; -} - -/** - * @brief Returns the 8-bit data stored in the Independent Data(ID) register - * @param None - * @retval 8-bit value of the ID register - */ -uint8_t CRC_GetIDRegister(void) -{ - return (CRC->IDR); -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_dac.c b/example/libs_stm/src/stm32f10x/stm32f10x_dac.c deleted file mode 100644 index e20b4a933..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_dac.c +++ /dev/null @@ -1,579 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_dac.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the DAC firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_dac.h" -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup DAC - * @brief DAC driver modules - * @{ - */ - -/** @defgroup DAC_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup DAC_Private_Defines - * @{ - */ - -/* DAC EN mask */ -#define CR_EN_Set ((uint32_t)0x00000001) - -/* DAC DMAEN mask */ -#define CR_DMAEN_Set ((uint32_t)0x00001000) - -/* CR register Mask */ -#define CR_CLEAR_Mask ((uint32_t)0x00000FFE) - -/* DAC SWTRIG mask */ -#define SWTRIGR_SWTRIG_Set ((uint32_t)0x00000001) - -/* DAC Dual Channels SWTRIG masks */ -#define DUAL_SWTRIG_Set ((uint32_t)0x00000003) -#define DUAL_SWTRIG_Reset ((uint32_t)0xFFFFFFFC) - -/* DHR registers offsets */ -#define DHR12R1_Offset ((uint32_t)0x00000008) -#define DHR12R2_Offset ((uint32_t)0x00000014) -#define DHR12RD_Offset ((uint32_t)0x00000020) - -/* DOR register offset */ -#define DOR_Offset ((uint32_t)0x0000002C) -/** - * @} - */ - -/** @defgroup DAC_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup DAC_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup DAC_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup DAC_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the DAC peripheral registers to their default reset values. - * @param None - * @retval None - */ -void DAC_DeInit(void) -{ - /* Enable DAC reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, ENABLE); - /* Release DAC from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, DISABLE); -} - -/** - * @brief Initializes the DAC peripheral according to the specified - * parameters in the DAC_InitStruct. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure that - * contains the configuration information for the specified DAC channel. - * @retval None - */ -void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct) -{ - uint32_t tmpreg1 = 0, tmpreg2 = 0; - /* Check the DAC parameters */ - assert_param(IS_DAC_TRIGGER(DAC_InitStruct->DAC_Trigger)); - assert_param(IS_DAC_GENERATE_WAVE(DAC_InitStruct->DAC_WaveGeneration)); - assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude)); - assert_param(IS_DAC_OUTPUT_BUFFER_STATE(DAC_InitStruct->DAC_OutputBuffer)); -/*---------------------------- DAC CR Configuration --------------------------*/ - /* Get the DAC CR value */ - tmpreg1 = DAC->CR; - /* Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits */ - tmpreg1 &= ~(CR_CLEAR_Mask << DAC_Channel); - /* Configure for the selected DAC channel: buffer output, trigger, wave genration, - mask/amplitude for wave genration */ - /* Set TSELx and TENx bits according to DAC_Trigger value */ - /* Set WAVEx bits according to DAC_WaveGeneration value */ - /* Set MAMPx bits according to DAC_LFSRUnmask_TriangleAmplitude value */ - /* Set BOFFx bit according to DAC_OutputBuffer value */ - tmpreg2 = (DAC_InitStruct->DAC_Trigger | DAC_InitStruct->DAC_WaveGeneration | - DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude | DAC_InitStruct->DAC_OutputBuffer); - /* Calculate CR register value depending on DAC_Channel */ - tmpreg1 |= tmpreg2 << DAC_Channel; - /* Write to DAC CR */ - DAC->CR = tmpreg1; -} - -/** - * @brief Fills each DAC_InitStruct member with its default value. - * @param DAC_InitStruct : pointer to a DAC_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct) -{ -/*--------------- Reset DAC init structure parameters values -----------------*/ - /* Initialize the DAC_Trigger member */ - DAC_InitStruct->DAC_Trigger = DAC_Trigger_None; - /* Initialize the DAC_WaveGeneration member */ - DAC_InitStruct->DAC_WaveGeneration = DAC_WaveGeneration_None; - /* Initialize the DAC_LFSRUnmask_TriangleAmplitude member */ - DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; - /* Initialize the DAC_OutputBuffer member */ - DAC_InitStruct->DAC_OutputBuffer = DAC_OutputBuffer_Enable; -} - -/** - * @brief Enables or disables the specified DAC channel. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param NewState: new state of the DAC channel. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected DAC channel */ - DAC->CR |= CR_EN_Set << DAC_Channel; - } - else - { - /* Disable the selected DAC channel */ - DAC->CR &= ~(CR_EN_Set << DAC_Channel); - } -} -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) -/** - * @brief Enables or disables the specified DAC interrupts. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_IT: specifies the DAC interrupt sources to be enabled or disabled. - * This parameter can be the following values: - * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask - * @param NewState: new state of the specified DAC interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_DAC_IT(DAC_IT)); - - if (NewState != DISABLE) - { - /* Enable the selected DAC interrupts */ - DAC->CR |= (DAC_IT << DAC_Channel); - } - else - { - /* Disable the selected DAC interrupts */ - DAC->CR &= (~(uint32_t)(DAC_IT << DAC_Channel)); - } -} -#endif - -/** - * @brief Enables or disables the specified DAC channel DMA request. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param NewState: new state of the selected DAC channel DMA request. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected DAC channel DMA request */ - DAC->CR |= CR_DMAEN_Set << DAC_Channel; - } - else - { - /* Disable the selected DAC channel DMA request */ - DAC->CR &= ~(CR_DMAEN_Set << DAC_Channel); - } -} - -/** - * @brief Enables or disables the selected DAC channel software trigger. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param NewState: new state of the selected DAC channel software trigger. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable software trigger for the selected DAC channel */ - DAC->SWTRIGR |= SWTRIGR_SWTRIG_Set << (DAC_Channel >> 4); - } - else - { - /* Disable software trigger for the selected DAC channel */ - DAC->SWTRIGR &= ~(SWTRIGR_SWTRIG_Set << (DAC_Channel >> 4)); - } -} - -/** - * @brief Enables or disables simultaneously the two DAC channels software - * triggers. - * @param NewState: new state of the DAC channels software triggers. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DAC_DualSoftwareTriggerCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable software trigger for both DAC channels */ - DAC->SWTRIGR |= DUAL_SWTRIG_Set ; - } - else - { - /* Disable software trigger for both DAC channels */ - DAC->SWTRIGR &= DUAL_SWTRIG_Reset; - } -} - -/** - * @brief Enables or disables the selected DAC channel wave generation. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_Wave: Specifies the wave type to enable or disable. - * This parameter can be one of the following values: - * @arg DAC_Wave_Noise: noise wave generation - * @arg DAC_Wave_Triangle: triangle wave generation - * @param NewState: new state of the selected DAC channel wave generation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_WAVE(DAC_Wave)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected wave generation for the selected DAC channel */ - DAC->CR |= DAC_Wave << DAC_Channel; - } - else - { - /* Disable the selected wave generation for the selected DAC channel */ - DAC->CR &= ~(DAC_Wave << DAC_Channel); - } -} - -/** - * @brief Set the specified data holding register value for DAC channel1. - * @param DAC_Align: Specifies the data alignement for DAC channel1. - * This parameter can be one of the following values: - * @arg DAC_Align_8b_R: 8bit right data alignement selected - * @arg DAC_Align_12b_L: 12bit left data alignement selected - * @arg DAC_Align_12b_R: 12bit right data alignement selected - * @param Data : Data to be loaded in the selected data holding register. - * @retval None - */ -void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_DAC_ALIGN(DAC_Align)); - assert_param(IS_DAC_DATA(Data)); - - tmp = (uint32_t)DAC_BASE; - tmp += DHR12R1_Offset + DAC_Align; - - /* Set the DAC channel1 selected data holding register */ - *(__IO uint32_t *) tmp = Data; -} - -/** - * @brief Set the specified data holding register value for DAC channel2. - * @param DAC_Align: Specifies the data alignement for DAC channel2. - * This parameter can be one of the following values: - * @arg DAC_Align_8b_R: 8bit right data alignement selected - * @arg DAC_Align_12b_L: 12bit left data alignement selected - * @arg DAC_Align_12b_R: 12bit right data alignement selected - * @param Data : Data to be loaded in the selected data holding register. - * @retval None - */ -void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_DAC_ALIGN(DAC_Align)); - assert_param(IS_DAC_DATA(Data)); - - tmp = (uint32_t)DAC_BASE; - tmp += DHR12R2_Offset + DAC_Align; - - /* Set the DAC channel2 selected data holding register */ - *(__IO uint32_t *)tmp = Data; -} - -/** - * @brief Set the specified data holding register value for dual channel - * DAC. - * @param DAC_Align: Specifies the data alignement for dual channel DAC. - * This parameter can be one of the following values: - * @arg DAC_Align_8b_R: 8bit right data alignement selected - * @arg DAC_Align_12b_L: 12bit left data alignement selected - * @arg DAC_Align_12b_R: 12bit right data alignement selected - * @param Data2: Data for DAC Channel2 to be loaded in the selected data - * holding register. - * @param Data1: Data for DAC Channel1 to be loaded in the selected data - * holding register. - * @retval None - */ -void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1) -{ - uint32_t data = 0, tmp = 0; - - /* Check the parameters */ - assert_param(IS_DAC_ALIGN(DAC_Align)); - assert_param(IS_DAC_DATA(Data1)); - assert_param(IS_DAC_DATA(Data2)); - - /* Calculate and set dual DAC data holding register value */ - if (DAC_Align == DAC_Align_8b_R) - { - data = ((uint32_t)Data2 << 8) | Data1; - } - else - { - data = ((uint32_t)Data2 << 16) | Data1; - } - - tmp = (uint32_t)DAC_BASE; - tmp += DHR12RD_Offset + DAC_Align; - - /* Set the dual DAC selected data holding register */ - *(__IO uint32_t *)tmp = data; -} - -/** - * @brief Returns the last data output value of the selected DAC cahnnel. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @retval The selected DAC channel data output value. - */ -uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - - tmp = (uint32_t) DAC_BASE ; - tmp += DOR_Offset + ((uint32_t)DAC_Channel >> 2); - - /* Returns the DAC channel data output register value */ - return (uint16_t) (*(__IO uint32_t*) tmp); -} - -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) -/** - * @brief Checks whether the specified DAC flag is set or not. - * @param DAC_Channel: thee selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_FLAG: specifies the flag to check. - * This parameter can be only of the following value: - * @arg DAC_FLAG_DMAUDR: DMA underrun flag - * @retval The new state of DAC_FLAG (SET or RESET). - */ -FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_FLAG(DAC_FLAG)); - - /* Check the status of the specified DAC flag */ - if ((DAC->SR & (DAC_FLAG << DAC_Channel)) != (uint8_t)RESET) - { - /* DAC_FLAG is set */ - bitstatus = SET; - } - else - { - /* DAC_FLAG is reset */ - bitstatus = RESET; - } - /* Return the DAC_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the DAC channelx's pending flags. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_FLAG: specifies the flag to clear. - * This parameter can be of the following value: - * @arg DAC_FLAG_DMAUDR: DMA underrun flag - * @retval None - */ -void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_FLAG(DAC_FLAG)); - - /* Clear the selected DAC flags */ - DAC->SR = (DAC_FLAG << DAC_Channel); -} - -/** - * @brief Checks whether the specified DAC interrupt has occurred or not. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_IT: specifies the DAC interrupt source to check. - * This parameter can be the following values: - * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask - * @retval The new state of DAC_IT (SET or RESET). - */ -ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT) -{ - ITStatus bitstatus = RESET; - uint32_t enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_IT(DAC_IT)); - - /* Get the DAC_IT enable bit status */ - enablestatus = (DAC->CR & (DAC_IT << DAC_Channel)) ; - - /* Check the status of the specified DAC interrupt */ - if (((DAC->SR & (DAC_IT << DAC_Channel)) != (uint32_t)RESET) && enablestatus) - { - /* DAC_IT is set */ - bitstatus = SET; - } - else - { - /* DAC_IT is reset */ - bitstatus = RESET; - } - /* Return the DAC_IT status */ - return bitstatus; -} - -/** - * @brief Clears the DAC channelxs interrupt pending bits. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_IT: specifies the DAC interrupt pending bit to clear. - * This parameter can be the following values: - * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask - * @retval None - */ -void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_IT(DAC_IT)); - - /* Clear the selected DAC interrupt pending bits */ - DAC->SR = (DAC_IT << DAC_Channel); -} -#endif - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_dbgmcu.c b/example/libs_stm/src/stm32f10x/stm32f10x_dbgmcu.c deleted file mode 100644 index 6cfceba07..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_dbgmcu.c +++ /dev/null @@ -1,161 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_dbgmcu.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the DBGMCU firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_dbgmcu.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup DBGMCU - * @brief DBGMCU driver modules - * @{ - */ - -/** @defgroup DBGMCU_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup DBGMCU_Private_Defines - * @{ - */ - -#define IDCODE_DEVID_Mask ((uint32_t)0x00000FFF) -/** - * @} - */ - -/** @defgroup DBGMCU_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup DBGMCU_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup DBGMCU_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup DBGMCU_Private_Functions - * @{ - */ - -/** - * @brief Returns the device revision identifier. - * @param None - * @retval Device revision identifier - */ -uint32_t DBGMCU_GetREVID(void) -{ - return(DBGMCU->IDCODE >> 16); -} - -/** - * @brief Returns the device identifier. - * @param None - * @retval Device identifier - */ -uint32_t DBGMCU_GetDEVID(void) -{ - return(DBGMCU->IDCODE & IDCODE_DEVID_Mask); -} - -/** - * @brief Configures the specified peripheral and low power mode behavior - * when the MCU under Debug mode. - * @param DBGMCU_Periph: specifies the peripheral and low power mode. - * This parameter can be any combination of the following values: - * @arg DBGMCU_SLEEP: Keep debugger connection during SLEEP mode - * @arg DBGMCU_STOP: Keep debugger connection during STOP mode - * @arg DBGMCU_STANDBY: Keep debugger connection during STANDBY mode - * @arg DBGMCU_IWDG_STOP: Debug IWDG stopped when Core is halted - * @arg DBGMCU_WWDG_STOP: Debug WWDG stopped when Core is halted - * @arg DBGMCU_TIM1_STOP: TIM1 counter stopped when Core is halted - * @arg DBGMCU_TIM2_STOP: TIM2 counter stopped when Core is halted - * @arg DBGMCU_TIM3_STOP: TIM3 counter stopped when Core is halted - * @arg DBGMCU_TIM4_STOP: TIM4 counter stopped when Core is halted - * @arg DBGMCU_CAN1_STOP: Debug CAN2 stopped when Core is halted - * @arg DBGMCU_I2C1_SMBUS_TIMEOUT: I2C1 SMBUS timeout mode stopped when Core is halted - * @arg DBGMCU_I2C2_SMBUS_TIMEOUT: I2C2 SMBUS timeout mode stopped when Core is halted - * @arg DBGMCU_TIM5_STOP: TIM5 counter stopped when Core is halted - * @arg DBGMCU_TIM6_STOP: TIM6 counter stopped when Core is halted - * @arg DBGMCU_TIM7_STOP: TIM7 counter stopped when Core is halted - * @arg DBGMCU_TIM8_STOP: TIM8 counter stopped when Core is halted - * @arg DBGMCU_CAN2_STOP: Debug CAN2 stopped when Core is halted - * @arg DBGMCU_TIM15_STOP: TIM15 counter stopped when Core is halted - * @arg DBGMCU_TIM16_STOP: TIM16 counter stopped when Core is halted - * @arg DBGMCU_TIM17_STOP: TIM17 counter stopped when Core is halted - * @arg DBGMCU_TIM9_STOP: TIM9 counter stopped when Core is halted - * @arg DBGMCU_TIM10_STOP: TIM10 counter stopped when Core is halted - * @arg DBGMCU_TIM11_STOP: TIM11 counter stopped when Core is halted - * @arg DBGMCU_TIM12_STOP: TIM12 counter stopped when Core is halted - * @arg DBGMCU_TIM13_STOP: TIM13 counter stopped when Core is halted - * @arg DBGMCU_TIM14_STOP: TIM14 counter stopped when Core is halted - * @param NewState: new state of the specified peripheral in Debug mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DBGMCU_PERIPH(DBGMCU_Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - DBGMCU->CR |= DBGMCU_Periph; - } - else - { - DBGMCU->CR &= ~DBGMCU_Periph; - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_dma.c b/example/libs_stm/src/stm32f10x/stm32f10x_dma.c deleted file mode 100644 index aa890c6a6..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_dma.c +++ /dev/null @@ -1,693 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_dma.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the DMA firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_dma.h" -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup DMA - * @brief DMA driver modules - * @{ - */ - -/** @defgroup DMA_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - -/** @defgroup DMA_Private_Defines - * @{ - */ - -/* DMA ENABLE mask */ -#define CCR_ENABLE_Set ((uint32_t)0x00000001) -#define CCR_ENABLE_Reset ((uint32_t)0xFFFFFFFE) - -/* DMA1 Channelx interrupt pending bit masks */ -#define DMA1_Channel1_IT_Mask ((uint32_t)0x0000000F) -#define DMA1_Channel2_IT_Mask ((uint32_t)0x000000F0) -#define DMA1_Channel3_IT_Mask ((uint32_t)0x00000F00) -#define DMA1_Channel4_IT_Mask ((uint32_t)0x0000F000) -#define DMA1_Channel5_IT_Mask ((uint32_t)0x000F0000) -#define DMA1_Channel6_IT_Mask ((uint32_t)0x00F00000) -#define DMA1_Channel7_IT_Mask ((uint32_t)0x0F000000) - -/* DMA2 Channelx interrupt pending bit masks */ -#define DMA2_Channel1_IT_Mask ((uint32_t)0x0000000F) -#define DMA2_Channel2_IT_Mask ((uint32_t)0x000000F0) -#define DMA2_Channel3_IT_Mask ((uint32_t)0x00000F00) -#define DMA2_Channel4_IT_Mask ((uint32_t)0x0000F000) -#define DMA2_Channel5_IT_Mask ((uint32_t)0x000F0000) - -/* DMA2 FLAG mask */ -#define FLAG_Mask ((uint32_t)0x10000000) - -/* DMA registers Masks */ -#define CCR_CLEAR_Mask ((uint32_t)0xFFFF800F) - -/** - * @} - */ - -/** @defgroup DMA_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup DMA_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup DMA_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup DMA_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the DMAy Channelx registers to their default reset - * values. - * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and - * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. - * @retval None - */ -void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); - /* Disable the selected DMAy Channelx */ - DMAy_Channelx->CCR &= CCR_ENABLE_Reset; - /* Reset DMAy Channelx control register */ - DMAy_Channelx->CCR = 0; - - /* Reset DMAy Channelx remaining bytes register */ - DMAy_Channelx->CNDTR = 0; - - /* Reset DMAy Channelx peripheral address register */ - DMAy_Channelx->CPAR = 0; - - /* Reset DMAy Channelx memory address register */ - DMAy_Channelx->CMAR = 0; - - if (DMAy_Channelx == DMA1_Channel1) - { - /* Reset interrupt pending bits for DMA1 Channel1 */ - DMA1->IFCR |= DMA1_Channel1_IT_Mask; - } - else if (DMAy_Channelx == DMA1_Channel2) - { - /* Reset interrupt pending bits for DMA1 Channel2 */ - DMA1->IFCR |= DMA1_Channel2_IT_Mask; - } - else if (DMAy_Channelx == DMA1_Channel3) - { - /* Reset interrupt pending bits for DMA1 Channel3 */ - DMA1->IFCR |= DMA1_Channel3_IT_Mask; - } - else if (DMAy_Channelx == DMA1_Channel4) - { - /* Reset interrupt pending bits for DMA1 Channel4 */ - DMA1->IFCR |= DMA1_Channel4_IT_Mask; - } - else if (DMAy_Channelx == DMA1_Channel5) - { - /* Reset interrupt pending bits for DMA1 Channel5 */ - DMA1->IFCR |= DMA1_Channel5_IT_Mask; - } - else if (DMAy_Channelx == DMA1_Channel6) - { - /* Reset interrupt pending bits for DMA1 Channel6 */ - DMA1->IFCR |= DMA1_Channel6_IT_Mask; - } - else if (DMAy_Channelx == DMA1_Channel7) - { - /* Reset interrupt pending bits for DMA1 Channel7 */ - DMA1->IFCR |= DMA1_Channel7_IT_Mask; - } - else if (DMAy_Channelx == DMA2_Channel1) - { - /* Reset interrupt pending bits for DMA2 Channel1 */ - DMA2->IFCR |= DMA2_Channel1_IT_Mask; - } - else if (DMAy_Channelx == DMA2_Channel2) - { - /* Reset interrupt pending bits for DMA2 Channel2 */ - DMA2->IFCR |= DMA2_Channel2_IT_Mask; - } - else if (DMAy_Channelx == DMA2_Channel3) - { - /* Reset interrupt pending bits for DMA2 Channel3 */ - DMA2->IFCR |= DMA2_Channel3_IT_Mask; - } - else if (DMAy_Channelx == DMA2_Channel4) - { - /* Reset interrupt pending bits for DMA2 Channel4 */ - DMA2->IFCR |= DMA2_Channel4_IT_Mask; - } - else - { - if (DMAy_Channelx == DMA2_Channel5) - { - /* Reset interrupt pending bits for DMA2 Channel5 */ - DMA2->IFCR |= DMA2_Channel5_IT_Mask; - } - } -} - -/** - * @brief Initializes the DMAy Channelx according to the specified - * parameters in the DMA_InitStruct. - * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and - * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. - * @param DMA_InitStruct: pointer to a DMA_InitTypeDef structure that - * contains the configuration information for the specified DMA Channel. - * @retval None - */ -void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); - assert_param(IS_DMA_DIR(DMA_InitStruct->DMA_DIR)); - assert_param(IS_DMA_BUFFER_SIZE(DMA_InitStruct->DMA_BufferSize)); - assert_param(IS_DMA_PERIPHERAL_INC_STATE(DMA_InitStruct->DMA_PeripheralInc)); - assert_param(IS_DMA_MEMORY_INC_STATE(DMA_InitStruct->DMA_MemoryInc)); - assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(DMA_InitStruct->DMA_PeripheralDataSize)); - assert_param(IS_DMA_MEMORY_DATA_SIZE(DMA_InitStruct->DMA_MemoryDataSize)); - assert_param(IS_DMA_MODE(DMA_InitStruct->DMA_Mode)); - assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority)); - assert_param(IS_DMA_M2M_STATE(DMA_InitStruct->DMA_M2M)); - -/*--------------------------- DMAy Channelx CCR Configuration -----------------*/ - /* Get the DMAy_Channelx CCR value */ - tmpreg = DMAy_Channelx->CCR; - /* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */ - tmpreg &= CCR_CLEAR_Mask; - /* Configure DMAy Channelx: data transfer, data size, priority level and mode */ - /* Set DIR bit according to DMA_DIR value */ - /* Set CIRC bit according to DMA_Mode value */ - /* Set PINC bit according to DMA_PeripheralInc value */ - /* Set MINC bit according to DMA_MemoryInc value */ - /* Set PSIZE bits according to DMA_PeripheralDataSize value */ - /* Set MSIZE bits according to DMA_MemoryDataSize value */ - /* Set PL bits according to DMA_Priority value */ - /* Set the MEM2MEM bit according to DMA_M2M value */ - tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode | - DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc | - DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize | - DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M; - - /* Write to DMAy Channelx CCR */ - DMAy_Channelx->CCR = tmpreg; - -/*--------------------------- DMAy Channelx CNDTR Configuration ---------------*/ - /* Write to DMAy Channelx CNDTR */ - DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize; - -/*--------------------------- DMAy Channelx CPAR Configuration ----------------*/ - /* Write to DMAy Channelx CPAR */ - DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr; - -/*--------------------------- DMAy Channelx CMAR Configuration ----------------*/ - /* Write to DMAy Channelx CMAR */ - DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr; -} - -/** - * @brief Fills each DMA_InitStruct member with its default value. - * @param DMA_InitStruct : pointer to a DMA_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct) -{ -/*-------------- Reset DMA init structure parameters values ------------------*/ - /* Initialize the DMA_PeripheralBaseAddr member */ - DMA_InitStruct->DMA_PeripheralBaseAddr = 0; - /* Initialize the DMA_MemoryBaseAddr member */ - DMA_InitStruct->DMA_MemoryBaseAddr = 0; - /* Initialize the DMA_DIR member */ - DMA_InitStruct->DMA_DIR = DMA_DIR_PeripheralSRC; - /* Initialize the DMA_BufferSize member */ - DMA_InitStruct->DMA_BufferSize = 0; - /* Initialize the DMA_PeripheralInc member */ - DMA_InitStruct->DMA_PeripheralInc = DMA_PeripheralInc_Disable; - /* Initialize the DMA_MemoryInc member */ - DMA_InitStruct->DMA_MemoryInc = DMA_MemoryInc_Disable; - /* Initialize the DMA_PeripheralDataSize member */ - DMA_InitStruct->DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; - /* Initialize the DMA_MemoryDataSize member */ - DMA_InitStruct->DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; - /* Initialize the DMA_Mode member */ - DMA_InitStruct->DMA_Mode = DMA_Mode_Normal; - /* Initialize the DMA_Priority member */ - DMA_InitStruct->DMA_Priority = DMA_Priority_Low; - /* Initialize the DMA_M2M member */ - DMA_InitStruct->DMA_M2M = DMA_M2M_Disable; -} - -/** - * @brief Enables or disables the specified DMAy Channelx. - * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and - * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. - * @param NewState: new state of the DMAy Channelx. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected DMAy Channelx */ - DMAy_Channelx->CCR |= CCR_ENABLE_Set; - } - else - { - /* Disable the selected DMAy Channelx */ - DMAy_Channelx->CCR &= CCR_ENABLE_Reset; - } -} - -/** - * @brief Enables or disables the specified DMAy Channelx interrupts. - * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and - * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. - * @param DMA_IT: specifies the DMA interrupts sources to be enabled - * or disabled. - * This parameter can be any combination of the following values: - * @arg DMA_IT_TC: Transfer complete interrupt mask - * @arg DMA_IT_HT: Half transfer interrupt mask - * @arg DMA_IT_TE: Transfer error interrupt mask - * @param NewState: new state of the specified DMA interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); - assert_param(IS_DMA_CONFIG_IT(DMA_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected DMA interrupts */ - DMAy_Channelx->CCR |= DMA_IT; - } - else - { - /* Disable the selected DMA interrupts */ - DMAy_Channelx->CCR &= ~DMA_IT; - } -} - -/** - * @brief Returns the number of remaining data units in the current - * DMAy Channelx transfer. - * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and - * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. - * @retval The number of remaining data units in the current DMAy Channelx - * transfer. - */ -uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); - /* Return the number of remaining data units for DMAy Channelx */ - return ((uint16_t)(DMAy_Channelx->CNDTR)); -} - -/** - * @brief Checks whether the specified DMAy Channelx flag is set or not. - * @param DMA_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg DMA1_FLAG_GL1: DMA1 Channel1 global flag. - * @arg DMA1_FLAG_TC1: DMA1 Channel1 transfer complete flag. - * @arg DMA1_FLAG_HT1: DMA1 Channel1 half transfer flag. - * @arg DMA1_FLAG_TE1: DMA1 Channel1 transfer error flag. - * @arg DMA1_FLAG_GL2: DMA1 Channel2 global flag. - * @arg DMA1_FLAG_TC2: DMA1 Channel2 transfer complete flag. - * @arg DMA1_FLAG_HT2: DMA1 Channel2 half transfer flag. - * @arg DMA1_FLAG_TE2: DMA1 Channel2 transfer error flag. - * @arg DMA1_FLAG_GL3: DMA1 Channel3 global flag. - * @arg DMA1_FLAG_TC3: DMA1 Channel3 transfer complete flag. - * @arg DMA1_FLAG_HT3: DMA1 Channel3 half transfer flag. - * @arg DMA1_FLAG_TE3: DMA1 Channel3 transfer error flag. - * @arg DMA1_FLAG_GL4: DMA1 Channel4 global flag. - * @arg DMA1_FLAG_TC4: DMA1 Channel4 transfer complete flag. - * @arg DMA1_FLAG_HT4: DMA1 Channel4 half transfer flag. - * @arg DMA1_FLAG_TE4: DMA1 Channel4 transfer error flag. - * @arg DMA1_FLAG_GL5: DMA1 Channel5 global flag. - * @arg DMA1_FLAG_TC5: DMA1 Channel5 transfer complete flag. - * @arg DMA1_FLAG_HT5: DMA1 Channel5 half transfer flag. - * @arg DMA1_FLAG_TE5: DMA1 Channel5 transfer error flag. - * @arg DMA1_FLAG_GL6: DMA1 Channel6 global flag. - * @arg DMA1_FLAG_TC6: DMA1 Channel6 transfer complete flag. - * @arg DMA1_FLAG_HT6: DMA1 Channel6 half transfer flag. - * @arg DMA1_FLAG_TE6: DMA1 Channel6 transfer error flag. - * @arg DMA1_FLAG_GL7: DMA1 Channel7 global flag. - * @arg DMA1_FLAG_TC7: DMA1 Channel7 transfer complete flag. - * @arg DMA1_FLAG_HT7: DMA1 Channel7 half transfer flag. - * @arg DMA1_FLAG_TE7: DMA1 Channel7 transfer error flag. - * @arg DMA2_FLAG_GL1: DMA2 Channel1 global flag. - * @arg DMA2_FLAG_TC1: DMA2 Channel1 transfer complete flag. - * @arg DMA2_FLAG_HT1: DMA2 Channel1 half transfer flag. - * @arg DMA2_FLAG_TE1: DMA2 Channel1 transfer error flag. - * @arg DMA2_FLAG_GL2: DMA2 Channel2 global flag. - * @arg DMA2_FLAG_TC2: DMA2 Channel2 transfer complete flag. - * @arg DMA2_FLAG_HT2: DMA2 Channel2 half transfer flag. - * @arg DMA2_FLAG_TE2: DMA2 Channel2 transfer error flag. - * @arg DMA2_FLAG_GL3: DMA2 Channel3 global flag. - * @arg DMA2_FLAG_TC3: DMA2 Channel3 transfer complete flag. - * @arg DMA2_FLAG_HT3: DMA2 Channel3 half transfer flag. - * @arg DMA2_FLAG_TE3: DMA2 Channel3 transfer error flag. - * @arg DMA2_FLAG_GL4: DMA2 Channel4 global flag. - * @arg DMA2_FLAG_TC4: DMA2 Channel4 transfer complete flag. - * @arg DMA2_FLAG_HT4: DMA2 Channel4 half transfer flag. - * @arg DMA2_FLAG_TE4: DMA2 Channel4 transfer error flag. - * @arg DMA2_FLAG_GL5: DMA2 Channel5 global flag. - * @arg DMA2_FLAG_TC5: DMA2 Channel5 transfer complete flag. - * @arg DMA2_FLAG_HT5: DMA2 Channel5 half transfer flag. - * @arg DMA2_FLAG_TE5: DMA2 Channel5 transfer error flag. - * @retval The new state of DMA_FLAG (SET or RESET). - */ -FlagStatus DMA_GetFlagStatus(uint32_t DMA_FLAG) -{ - FlagStatus bitstatus = RESET; - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_DMA_GET_FLAG(DMA_FLAG)); - - /* Calculate the used DMA */ - if ((DMA_FLAG & FLAG_Mask) != (uint32_t)RESET) - { - /* Get DMA2 ISR register value */ - tmpreg = DMA2->ISR ; - } - else - { - /* Get DMA1 ISR register value */ - tmpreg = DMA1->ISR ; - } - - /* Check the status of the specified DMA flag */ - if ((tmpreg & DMA_FLAG) != (uint32_t)RESET) - { - /* DMA_FLAG is set */ - bitstatus = SET; - } - else - { - /* DMA_FLAG is reset */ - bitstatus = RESET; - } - - /* Return the DMA_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the DMAy Channelx's pending flags. - * @param DMA_FLAG: specifies the flag to clear. - * This parameter can be any combination (for the same DMA) of the following values: - * @arg DMA1_FLAG_GL1: DMA1 Channel1 global flag. - * @arg DMA1_FLAG_TC1: DMA1 Channel1 transfer complete flag. - * @arg DMA1_FLAG_HT1: DMA1 Channel1 half transfer flag. - * @arg DMA1_FLAG_TE1: DMA1 Channel1 transfer error flag. - * @arg DMA1_FLAG_GL2: DMA1 Channel2 global flag. - * @arg DMA1_FLAG_TC2: DMA1 Channel2 transfer complete flag. - * @arg DMA1_FLAG_HT2: DMA1 Channel2 half transfer flag. - * @arg DMA1_FLAG_TE2: DMA1 Channel2 transfer error flag. - * @arg DMA1_FLAG_GL3: DMA1 Channel3 global flag. - * @arg DMA1_FLAG_TC3: DMA1 Channel3 transfer complete flag. - * @arg DMA1_FLAG_HT3: DMA1 Channel3 half transfer flag. - * @arg DMA1_FLAG_TE3: DMA1 Channel3 transfer error flag. - * @arg DMA1_FLAG_GL4: DMA1 Channel4 global flag. - * @arg DMA1_FLAG_TC4: DMA1 Channel4 transfer complete flag. - * @arg DMA1_FLAG_HT4: DMA1 Channel4 half transfer flag. - * @arg DMA1_FLAG_TE4: DMA1 Channel4 transfer error flag. - * @arg DMA1_FLAG_GL5: DMA1 Channel5 global flag. - * @arg DMA1_FLAG_TC5: DMA1 Channel5 transfer complete flag. - * @arg DMA1_FLAG_HT5: DMA1 Channel5 half transfer flag. - * @arg DMA1_FLAG_TE5: DMA1 Channel5 transfer error flag. - * @arg DMA1_FLAG_GL6: DMA1 Channel6 global flag. - * @arg DMA1_FLAG_TC6: DMA1 Channel6 transfer complete flag. - * @arg DMA1_FLAG_HT6: DMA1 Channel6 half transfer flag. - * @arg DMA1_FLAG_TE6: DMA1 Channel6 transfer error flag. - * @arg DMA1_FLAG_GL7: DMA1 Channel7 global flag. - * @arg DMA1_FLAG_TC7: DMA1 Channel7 transfer complete flag. - * @arg DMA1_FLAG_HT7: DMA1 Channel7 half transfer flag. - * @arg DMA1_FLAG_TE7: DMA1 Channel7 transfer error flag. - * @arg DMA2_FLAG_GL1: DMA2 Channel1 global flag. - * @arg DMA2_FLAG_TC1: DMA2 Channel1 transfer complete flag. - * @arg DMA2_FLAG_HT1: DMA2 Channel1 half transfer flag. - * @arg DMA2_FLAG_TE1: DMA2 Channel1 transfer error flag. - * @arg DMA2_FLAG_GL2: DMA2 Channel2 global flag. - * @arg DMA2_FLAG_TC2: DMA2 Channel2 transfer complete flag. - * @arg DMA2_FLAG_HT2: DMA2 Channel2 half transfer flag. - * @arg DMA2_FLAG_TE2: DMA2 Channel2 transfer error flag. - * @arg DMA2_FLAG_GL3: DMA2 Channel3 global flag. - * @arg DMA2_FLAG_TC3: DMA2 Channel3 transfer complete flag. - * @arg DMA2_FLAG_HT3: DMA2 Channel3 half transfer flag. - * @arg DMA2_FLAG_TE3: DMA2 Channel3 transfer error flag. - * @arg DMA2_FLAG_GL4: DMA2 Channel4 global flag. - * @arg DMA2_FLAG_TC4: DMA2 Channel4 transfer complete flag. - * @arg DMA2_FLAG_HT4: DMA2 Channel4 half transfer flag. - * @arg DMA2_FLAG_TE4: DMA2 Channel4 transfer error flag. - * @arg DMA2_FLAG_GL5: DMA2 Channel5 global flag. - * @arg DMA2_FLAG_TC5: DMA2 Channel5 transfer complete flag. - * @arg DMA2_FLAG_HT5: DMA2 Channel5 half transfer flag. - * @arg DMA2_FLAG_TE5: DMA2 Channel5 transfer error flag. - * @retval None - */ -void DMA_ClearFlag(uint32_t DMA_FLAG) -{ - /* Check the parameters */ - assert_param(IS_DMA_CLEAR_FLAG(DMA_FLAG)); - /* Calculate the used DMA */ - - if ((DMA_FLAG & FLAG_Mask) != (uint32_t)RESET) - { - /* Clear the selected DMA flags */ - DMA2->IFCR = DMA_FLAG; - } - else - { - /* Clear the selected DMA flags */ - DMA1->IFCR = DMA_FLAG; - } -} - -/** - * @brief Checks whether the specified DMAy Channelx interrupt has occurred or not. - * @param DMA_IT: specifies the DMA interrupt source to check. - * This parameter can be one of the following values: - * @arg DMA1_IT_GL1: DMA1 Channel1 global interrupt. - * @arg DMA1_IT_TC1: DMA1 Channel1 transfer complete interrupt. - * @arg DMA1_IT_HT1: DMA1 Channel1 half transfer interrupt. - * @arg DMA1_IT_TE1: DMA1 Channel1 transfer error interrupt. - * @arg DMA1_IT_GL2: DMA1 Channel2 global interrupt. - * @arg DMA1_IT_TC2: DMA1 Channel2 transfer complete interrupt. - * @arg DMA1_IT_HT2: DMA1 Channel2 half transfer interrupt. - * @arg DMA1_IT_TE2: DMA1 Channel2 transfer error interrupt. - * @arg DMA1_IT_GL3: DMA1 Channel3 global interrupt. - * @arg DMA1_IT_TC3: DMA1 Channel3 transfer complete interrupt. - * @arg DMA1_IT_HT3: DMA1 Channel3 half transfer interrupt. - * @arg DMA1_IT_TE3: DMA1 Channel3 transfer error interrupt. - * @arg DMA1_IT_GL4: DMA1 Channel4 global interrupt. - * @arg DMA1_IT_TC4: DMA1 Channel4 transfer complete interrupt. - * @arg DMA1_IT_HT4: DMA1 Channel4 half transfer interrupt. - * @arg DMA1_IT_TE4: DMA1 Channel4 transfer error interrupt. - * @arg DMA1_IT_GL5: DMA1 Channel5 global interrupt. - * @arg DMA1_IT_TC5: DMA1 Channel5 transfer complete interrupt. - * @arg DMA1_IT_HT5: DMA1 Channel5 half transfer interrupt. - * @arg DMA1_IT_TE5: DMA1 Channel5 transfer error interrupt. - * @arg DMA1_IT_GL6: DMA1 Channel6 global interrupt. - * @arg DMA1_IT_TC6: DMA1 Channel6 transfer complete interrupt. - * @arg DMA1_IT_HT6: DMA1 Channel6 half transfer interrupt. - * @arg DMA1_IT_TE6: DMA1 Channel6 transfer error interrupt. - * @arg DMA1_IT_GL7: DMA1 Channel7 global interrupt. - * @arg DMA1_IT_TC7: DMA1 Channel7 transfer complete interrupt. - * @arg DMA1_IT_HT7: DMA1 Channel7 half transfer interrupt. - * @arg DMA1_IT_TE7: DMA1 Channel7 transfer error interrupt. - * @arg DMA2_IT_GL1: DMA2 Channel1 global interrupt. - * @arg DMA2_IT_TC1: DMA2 Channel1 transfer complete interrupt. - * @arg DMA2_IT_HT1: DMA2 Channel1 half transfer interrupt. - * @arg DMA2_IT_TE1: DMA2 Channel1 transfer error interrupt. - * @arg DMA2_IT_GL2: DMA2 Channel2 global interrupt. - * @arg DMA2_IT_TC2: DMA2 Channel2 transfer complete interrupt. - * @arg DMA2_IT_HT2: DMA2 Channel2 half transfer interrupt. - * @arg DMA2_IT_TE2: DMA2 Channel2 transfer error interrupt. - * @arg DMA2_IT_GL3: DMA2 Channel3 global interrupt. - * @arg DMA2_IT_TC3: DMA2 Channel3 transfer complete interrupt. - * @arg DMA2_IT_HT3: DMA2 Channel3 half transfer interrupt. - * @arg DMA2_IT_TE3: DMA2 Channel3 transfer error interrupt. - * @arg DMA2_IT_GL4: DMA2 Channel4 global interrupt. - * @arg DMA2_IT_TC4: DMA2 Channel4 transfer complete interrupt. - * @arg DMA2_IT_HT4: DMA2 Channel4 half transfer interrupt. - * @arg DMA2_IT_TE4: DMA2 Channel4 transfer error interrupt. - * @arg DMA2_IT_GL5: DMA2 Channel5 global interrupt. - * @arg DMA2_IT_TC5: DMA2 Channel5 transfer complete interrupt. - * @arg DMA2_IT_HT5: DMA2 Channel5 half transfer interrupt. - * @arg DMA2_IT_TE5: DMA2 Channel5 transfer error interrupt. - * @retval The new state of DMA_IT (SET or RESET). - */ -ITStatus DMA_GetITStatus(uint32_t DMA_IT) -{ - ITStatus bitstatus = RESET; - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_DMA_GET_IT(DMA_IT)); - - /* Calculate the used DMA */ - if ((DMA_IT & FLAG_Mask) != (uint32_t)RESET) - { - /* Get DMA2 ISR register value */ - tmpreg = DMA2->ISR ; - } - else - { - /* Get DMA1 ISR register value */ - tmpreg = DMA1->ISR ; - } - - /* Check the status of the specified DMA interrupt */ - if ((tmpreg & DMA_IT) != (uint32_t)RESET) - { - /* DMA_IT is set */ - bitstatus = SET; - } - else - { - /* DMA_IT is reset */ - bitstatus = RESET; - } - /* Return the DMA_IT status */ - return bitstatus; -} - -/** - * @brief Clears the DMAy Channelxs interrupt pending bits. - * @param DMA_IT: specifies the DMA interrupt pending bit to clear. - * This parameter can be any combination (for the same DMA) of the following values: - * @arg DMA1_IT_GL1: DMA1 Channel1 global interrupt. - * @arg DMA1_IT_TC1: DMA1 Channel1 transfer complete interrupt. - * @arg DMA1_IT_HT1: DMA1 Channel1 half transfer interrupt. - * @arg DMA1_IT_TE1: DMA1 Channel1 transfer error interrupt. - * @arg DMA1_IT_GL2: DMA1 Channel2 global interrupt. - * @arg DMA1_IT_TC2: DMA1 Channel2 transfer complete interrupt. - * @arg DMA1_IT_HT2: DMA1 Channel2 half transfer interrupt. - * @arg DMA1_IT_TE2: DMA1 Channel2 transfer error interrupt. - * @arg DMA1_IT_GL3: DMA1 Channel3 global interrupt. - * @arg DMA1_IT_TC3: DMA1 Channel3 transfer complete interrupt. - * @arg DMA1_IT_HT3: DMA1 Channel3 half transfer interrupt. - * @arg DMA1_IT_TE3: DMA1 Channel3 transfer error interrupt. - * @arg DMA1_IT_GL4: DMA1 Channel4 global interrupt. - * @arg DMA1_IT_TC4: DMA1 Channel4 transfer complete interrupt. - * @arg DMA1_IT_HT4: DMA1 Channel4 half transfer interrupt. - * @arg DMA1_IT_TE4: DMA1 Channel4 transfer error interrupt. - * @arg DMA1_IT_GL5: DMA1 Channel5 global interrupt. - * @arg DMA1_IT_TC5: DMA1 Channel5 transfer complete interrupt. - * @arg DMA1_IT_HT5: DMA1 Channel5 half transfer interrupt. - * @arg DMA1_IT_TE5: DMA1 Channel5 transfer error interrupt. - * @arg DMA1_IT_GL6: DMA1 Channel6 global interrupt. - * @arg DMA1_IT_TC6: DMA1 Channel6 transfer complete interrupt. - * @arg DMA1_IT_HT6: DMA1 Channel6 half transfer interrupt. - * @arg DMA1_IT_TE6: DMA1 Channel6 transfer error interrupt. - * @arg DMA1_IT_GL7: DMA1 Channel7 global interrupt. - * @arg DMA1_IT_TC7: DMA1 Channel7 transfer complete interrupt. - * @arg DMA1_IT_HT7: DMA1 Channel7 half transfer interrupt. - * @arg DMA1_IT_TE7: DMA1 Channel7 transfer error interrupt. - * @arg DMA2_IT_GL1: DMA2 Channel1 global interrupt. - * @arg DMA2_IT_TC1: DMA2 Channel1 transfer complete interrupt. - * @arg DMA2_IT_HT1: DMA2 Channel1 half transfer interrupt. - * @arg DMA2_IT_TE1: DMA2 Channel1 transfer error interrupt. - * @arg DMA2_IT_GL2: DMA2 Channel2 global interrupt. - * @arg DMA2_IT_TC2: DMA2 Channel2 transfer complete interrupt. - * @arg DMA2_IT_HT2: DMA2 Channel2 half transfer interrupt. - * @arg DMA2_IT_TE2: DMA2 Channel2 transfer error interrupt. - * @arg DMA2_IT_GL3: DMA2 Channel3 global interrupt. - * @arg DMA2_IT_TC3: DMA2 Channel3 transfer complete interrupt. - * @arg DMA2_IT_HT3: DMA2 Channel3 half transfer interrupt. - * @arg DMA2_IT_TE3: DMA2 Channel3 transfer error interrupt. - * @arg DMA2_IT_GL4: DMA2 Channel4 global interrupt. - * @arg DMA2_IT_TC4: DMA2 Channel4 transfer complete interrupt. - * @arg DMA2_IT_HT4: DMA2 Channel4 half transfer interrupt. - * @arg DMA2_IT_TE4: DMA2 Channel4 transfer error interrupt. - * @arg DMA2_IT_GL5: DMA2 Channel5 global interrupt. - * @arg DMA2_IT_TC5: DMA2 Channel5 transfer complete interrupt. - * @arg DMA2_IT_HT5: DMA2 Channel5 half transfer interrupt. - * @arg DMA2_IT_TE5: DMA2 Channel5 transfer error interrupt. - * @retval None - */ -void DMA_ClearITPendingBit(uint32_t DMA_IT) -{ - /* Check the parameters */ - assert_param(IS_DMA_CLEAR_IT(DMA_IT)); - - /* Calculate the used DMA */ - if ((DMA_IT & FLAG_Mask) != (uint32_t)RESET) - { - /* Clear the selected DMA interrupt pending bits */ - DMA2->IFCR = DMA_IT; - } - else - { - /* Clear the selected DMA interrupt pending bits */ - DMA1->IFCR = DMA_IT; - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_exti.c b/example/libs_stm/src/stm32f10x/stm32f10x_exti.c deleted file mode 100644 index eae3253ea..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_exti.c +++ /dev/null @@ -1,268 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_exti.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the EXTI firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_exti.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup EXTI - * @brief EXTI driver modules - * @{ - */ - -/** @defgroup EXTI_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup EXTI_Private_Defines - * @{ - */ - -#define EXTI_LineNone ((uint32_t)0x00000) /* No interrupt selected */ - -/** - * @} - */ - -/** @defgroup EXTI_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup EXTI_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup EXTI_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup EXTI_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the EXTI peripheral registers to their default reset values. - * @param None - * @retval None - */ -void EXTI_DeInit(void) -{ - EXTI->IMR = 0x00000000; - EXTI->EMR = 0x00000000; - EXTI->RTSR = 0x00000000; - EXTI->FTSR = 0x00000000; - EXTI->PR = 0x000FFFFF; -} - -/** - * @brief Initializes the EXTI peripheral according to the specified - * parameters in the EXTI_InitStruct. - * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure - * that contains the configuration information for the EXTI peripheral. - * @retval None - */ -void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct) -{ - uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode)); - assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger)); - assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line)); - assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd)); - - tmp = (uint32_t)EXTI_BASE; - - if (EXTI_InitStruct->EXTI_LineCmd != DISABLE) - { - /* Clear EXTI line configuration */ - EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line; - EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line; - - tmp += EXTI_InitStruct->EXTI_Mode; - - *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; - - /* Clear Rising Falling edge configuration */ - EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line; - EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line; - - /* Select the trigger for the selected external interrupts */ - if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling) - { - /* Rising Falling edge */ - EXTI->RTSR |= EXTI_InitStruct->EXTI_Line; - EXTI->FTSR |= EXTI_InitStruct->EXTI_Line; - } - else - { - tmp = (uint32_t)EXTI_BASE; - tmp += EXTI_InitStruct->EXTI_Trigger; - - *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; - } - } - else - { - tmp += EXTI_InitStruct->EXTI_Mode; - - /* Disable the selected external lines */ - *(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line; - } -} - -/** - * @brief Fills each EXTI_InitStruct member with its reset value. - * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct) -{ - EXTI_InitStruct->EXTI_Line = EXTI_LineNone; - EXTI_InitStruct->EXTI_Mode = EXTI_Mode_Interrupt; - EXTI_InitStruct->EXTI_Trigger = EXTI_Trigger_Falling; - EXTI_InitStruct->EXTI_LineCmd = DISABLE; -} - -/** - * @brief Generates a Software interrupt. - * @param EXTI_Line: specifies the EXTI lines to be enabled or disabled. - * This parameter can be any combination of EXTI_Linex where x can be (0..19). - * @retval None - */ -void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line) -{ - /* Check the parameters */ - assert_param(IS_EXTI_LINE(EXTI_Line)); - - EXTI->SWIER |= EXTI_Line; -} - -/** - * @brief Checks whether the specified EXTI line flag is set or not. - * @param EXTI_Line: specifies the EXTI line flag to check. - * This parameter can be: - * @arg EXTI_Linex: External interrupt line x where x(0..19) - * @retval The new state of EXTI_Line (SET or RESET). - */ -FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_GET_EXTI_LINE(EXTI_Line)); - - if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the EXTIs line pending flags. - * @param EXTI_Line: specifies the EXTI lines flags to clear. - * This parameter can be any combination of EXTI_Linex where x can be (0..19). - * @retval None - */ -void EXTI_ClearFlag(uint32_t EXTI_Line) -{ - /* Check the parameters */ - assert_param(IS_EXTI_LINE(EXTI_Line)); - - EXTI->PR = EXTI_Line; -} - -/** - * @brief Checks whether the specified EXTI line is asserted or not. - * @param EXTI_Line: specifies the EXTI line to check. - * This parameter can be: - * @arg EXTI_Linex: External interrupt line x where x(0..19) - * @retval The new state of EXTI_Line (SET or RESET). - */ -ITStatus EXTI_GetITStatus(uint32_t EXTI_Line) -{ - ITStatus bitstatus = RESET; - uint32_t enablestatus = 0; - /* Check the parameters */ - assert_param(IS_GET_EXTI_LINE(EXTI_Line)); - - enablestatus = EXTI->IMR & EXTI_Line; - if (((EXTI->PR & EXTI_Line) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the EXTIs line pending bits. - * @param EXTI_Line: specifies the EXTI lines to clear. - * This parameter can be any combination of EXTI_Linex where x can be (0..19). - * @retval None - */ -void EXTI_ClearITPendingBit(uint32_t EXTI_Line) -{ - /* Check the parameters */ - assert_param(IS_EXTI_LINE(EXTI_Line)); - - EXTI->PR = EXTI_Line; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_flash.c b/example/libs_stm/src/stm32f10x/stm32f10x_flash.c deleted file mode 100644 index 3475e6a37..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_flash.c +++ /dev/null @@ -1,1735 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_flash.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the FLASH firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_flash.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup FLASH - * @brief FLASH driver modules - * @{ - */ - -/** @defgroup FLASH_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup FLASH_Private_Defines - * @{ - */ - -/* Flash Access Control Register bits */ -#define ACR_LATENCY_Mask ((uint32_t)0x00000038) -#define ACR_HLFCYA_Mask ((uint32_t)0xFFFFFFF7) -#define ACR_PRFTBE_Mask ((uint32_t)0xFFFFFFEF) - -/* Flash Access Control Register bits */ -#define ACR_PRFTBS_Mask ((uint32_t)0x00000020) - -/* Flash Control Register bits */ -#define CR_PG_Set ((uint32_t)0x00000001) -#define CR_PG_Reset ((uint32_t)0x00001FFE) -#define CR_PER_Set ((uint32_t)0x00000002) -#define CR_PER_Reset ((uint32_t)0x00001FFD) -#define CR_MER_Set ((uint32_t)0x00000004) -#define CR_MER_Reset ((uint32_t)0x00001FFB) -#define CR_OPTPG_Set ((uint32_t)0x00000010) -#define CR_OPTPG_Reset ((uint32_t)0x00001FEF) -#define CR_OPTER_Set ((uint32_t)0x00000020) -#define CR_OPTER_Reset ((uint32_t)0x00001FDF) -#define CR_STRT_Set ((uint32_t)0x00000040) -#define CR_LOCK_Set ((uint32_t)0x00000080) - -/* FLASH Mask */ -#define RDPRT_Mask ((uint32_t)0x00000002) -#define WRP0_Mask ((uint32_t)0x000000FF) -#define WRP1_Mask ((uint32_t)0x0000FF00) -#define WRP2_Mask ((uint32_t)0x00FF0000) -#define WRP3_Mask ((uint32_t)0xFF000000) -#define OB_USER_BFB2 ((uint16_t)0x0008) - -/* FLASH Keys */ -#define RDP_Key ((uint16_t)0x00A5) -#define FLASH_KEY1 ((uint32_t)0x45670123) -#define FLASH_KEY2 ((uint32_t)0xCDEF89AB) - -/* FLASH BANK address */ -#define FLASH_BANK1_END_ADDRESS ((uint32_t)0x807FFFF) - -/* Delay definition */ -#define EraseTimeout ((uint32_t)0x000B0000) -#define ProgramTimeout ((uint32_t)0x00002000) -/** - * @} - */ - -/** @defgroup FLASH_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup FLASH_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup FLASH_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup FLASH_Private_Functions - * @{ - */ - -/** -@code - - This driver provides functions to configure and program the Flash memory of all STM32F10x devices, - including the latest STM32F10x_XL density devices. - - STM32F10x_XL devices feature up to 1 Mbyte with dual bank architecture for read-while-write (RWW) capability: - - bank1: fixed size of 512 Kbytes (256 pages of 2Kbytes each) - - bank2: up to 512 Kbytes (up to 256 pages of 2Kbytes each) - While other STM32F10x devices features only one bank with memory up to 512 Kbytes. - - In version V3.3.0, some functions were updated and new ones were added to support - STM32F10x_XL devices. Thus some functions manages all devices, while other are - dedicated for XL devices only. - - The table below presents the list of available functions depending on the used STM32F10x devices. - - *************************************************** - * Legacy functions used for all STM32F10x devices * - *************************************************** - +----------------------------------------------------------------------------------------------------------------------------------+ - | Functions prototypes |STM32F10x_XL|Other STM32F10x| Comments | - | | devices | devices | | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_SetLatency | Yes | Yes | No change | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_HalfCycleAccessCmd | Yes | Yes | No change | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_PrefetchBufferCmd | Yes | Yes | No change | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_Unlock | Yes | Yes | - For STM32F10X_XL devices: unlock Bank1 and Bank2. | - | | | | - For other devices: unlock Bank1 and it is equivalent | - | | | | to FLASH_UnlockBank1 function. | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_Lock | Yes | Yes | - For STM32F10X_XL devices: lock Bank1 and Bank2. | - | | | | - For other devices: lock Bank1 and it is equivalent | - | | | | to FLASH_LockBank1 function. | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_ErasePage | Yes | Yes | - For STM32F10x_XL devices: erase a page in Bank1 and Bank2 | - | | | | - For other devices: erase a page in Bank1 | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_EraseAllPages | Yes | Yes | - For STM32F10x_XL devices: erase all pages in Bank1 and Bank2 | - | | | | - For other devices: erase all pages in Bank1 | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_EraseOptionBytes | Yes | Yes | No change | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_ProgramWord | Yes | Yes | Updated to program up to 1MByte (depending on the used device) | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_ProgramHalfWord | Yes | Yes | Updated to program up to 1MByte (depending on the used device) | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_ProgramOptionByteData | Yes | Yes | No change | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_EnableWriteProtection | Yes | Yes | No change | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_ReadOutProtection | Yes | Yes | No change | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_UserOptionByteConfig | Yes | Yes | No change | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_GetUserOptionByte | Yes | Yes | No change | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_GetWriteProtectionOptionByte | Yes | Yes | No change | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_GetReadOutProtectionStatus | Yes | Yes | No change | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_GetPrefetchBufferStatus | Yes | Yes | No change | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_ITConfig | Yes | Yes | - For STM32F10x_XL devices: enable Bank1 and Bank2's interrupts| - | | | | - For other devices: enable Bank1's interrupts | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_GetFlagStatus | Yes | Yes | - For STM32F10x_XL devices: return Bank1 and Bank2's flag status| - | | | | - For other devices: return Bank1's flag status | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_ClearFlag | Yes | Yes | - For STM32F10x_XL devices: clear Bank1 and Bank2's flag | - | | | | - For other devices: clear Bank1's flag | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_GetStatus | Yes | Yes | - Return the status of Bank1 (for all devices) | - | | | | equivalent to FLASH_GetBank1Status function | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_WaitForLastOperation | Yes | Yes | - Wait for Bank1 last operation (for all devices) | - | | | | equivalent to: FLASH_WaitForLastBank1Operation function | - +----------------------------------------------------------------------------------------------------------------------------------+ - - ************************************************************************************************************************ - * New functions used for all STM32F10x devices to manage Bank1: * - * - These functions are mainly useful for STM32F10x_XL density devices, to have separate control for Bank1 and bank2 * - * - For other devices, these functions are optional (covered by functions listed above) * - ************************************************************************************************************************ - +----------------------------------------------------------------------------------------------------------------------------------+ - | Functions prototypes |STM32F10x_XL|Other STM32F10x| Comments | - | | devices | devices | | - |----------------------------------------------------------------------------------------------------------------------------------| - | FLASH_UnlockBank1 | Yes | Yes | - Unlock Bank1 | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_LockBank1 | Yes | Yes | - Lock Bank1 | - |----------------------------------------------------------------------------------------------------------------------------------| - | FLASH_EraseAllBank1Pages | Yes | Yes | - Erase all pages in Bank1 | - |----------------------------------------------------------------------------------------------------------------------------------| - | FLASH_GetBank1Status | Yes | Yes | - Return the status of Bank1 | - |----------------------------------------------------------------------------------------------------------------------------------| - | FLASH_WaitForLastBank1Operation | Yes | Yes | - Wait for Bank1 last operation | - +----------------------------------------------------------------------------------------------------------------------------------+ - - ***************************************************************************** - * New Functions used only with STM32F10x_XL density devices to manage Bank2 * - ***************************************************************************** - +----------------------------------------------------------------------------------------------------------------------------------+ - | Functions prototypes |STM32F10x_XL|Other STM32F10x| Comments | - | | devices | devices | | - |----------------------------------------------------------------------------------------------------------------------------------| - | FLASH_UnlockBank2 | Yes | No | - Unlock Bank2 | - |----------------------------------------------------------------------------------------------------------------------------------| - |FLASH_LockBank2 | Yes | No | - Lock Bank2 | - |----------------------------------------------------------------------------------------------------------------------------------| - | FLASH_EraseAllBank2Pages | Yes | No | - Erase all pages in Bank2 | - |----------------------------------------------------------------------------------------------------------------------------------| - | FLASH_GetBank2Status | Yes | No | - Return the status of Bank2 | - |----------------------------------------------------------------------------------------------------------------------------------| - | FLASH_WaitForLastBank2Operation | Yes | No | - Wait for Bank2 last operation | - |----------------------------------------------------------------------------------------------------------------------------------| - | FLASH_BootConfig | Yes | No | - Configure to boot from Bank1 or Bank2 | - +----------------------------------------------------------------------------------------------------------------------------------+ -@endcode -*/ - - -/** - * @brief Sets the code latency value. - * @note This function can be used for all STM32F10x devices. - * @param FLASH_Latency: specifies the FLASH Latency value. - * This parameter can be one of the following values: - * @arg FLASH_Latency_0: FLASH Zero Latency cycle - * @arg FLASH_Latency_1: FLASH One Latency cycle - * @arg FLASH_Latency_2: FLASH Two Latency cycles - * @retval None - */ -void FLASH_SetLatency(uint32_t FLASH_Latency) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_FLASH_LATENCY(FLASH_Latency)); - - /* Read the ACR register */ - tmpreg = FLASH->ACR; - - /* Sets the Latency value */ - tmpreg &= ACR_LATENCY_Mask; - tmpreg |= FLASH_Latency; - - /* Write the ACR register */ - FLASH->ACR = tmpreg; -} - -/** - * @brief Enables or disables the Half cycle flash access. - * @note This function can be used for all STM32F10x devices. - * @param FLASH_HalfCycleAccess: specifies the FLASH Half cycle Access mode. - * This parameter can be one of the following values: - * @arg FLASH_HalfCycleAccess_Enable: FLASH Half Cycle Enable - * @arg FLASH_HalfCycleAccess_Disable: FLASH Half Cycle Disable - * @retval None - */ -void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess) -{ - /* Check the parameters */ - assert_param(IS_FLASH_HALFCYCLEACCESS_STATE(FLASH_HalfCycleAccess)); - - /* Enable or disable the Half cycle access */ - FLASH->ACR &= ACR_HLFCYA_Mask; - FLASH->ACR |= FLASH_HalfCycleAccess; -} - -/** - * @brief Enables or disables the Prefetch Buffer. - * @note This function can be used for all STM32F10x devices. - * @param FLASH_PrefetchBuffer: specifies the Prefetch buffer status. - * This parameter can be one of the following values: - * @arg FLASH_PrefetchBuffer_Enable: FLASH Prefetch Buffer Enable - * @arg FLASH_PrefetchBuffer_Disable: FLASH Prefetch Buffer Disable - * @retval None - */ -void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer) -{ - /* Check the parameters */ - assert_param(IS_FLASH_PREFETCHBUFFER_STATE(FLASH_PrefetchBuffer)); - - /* Enable or disable the Prefetch Buffer */ - FLASH->ACR &= ACR_PRFTBE_Mask; - FLASH->ACR |= FLASH_PrefetchBuffer; -} - -/** - * @brief Unlocks the FLASH Program Erase Controller. - * @note This function can be used for all STM32F10x devices. - * - For STM32F10X_XL devices this function unlocks Bank1 and Bank2. - * - For all other devices it unlocks Bank1 and it is equivalent - * to FLASH_UnlockBank1 function.. - * @param None - * @retval None - */ -void FLASH_Unlock(void) -{ - /* Authorize the FPEC of Bank1 Access */ - FLASH->KEYR = FLASH_KEY1; - FLASH->KEYR = FLASH_KEY2; - -#ifdef STM32F10X_XL - /* Authorize the FPEC of Bank2 Access */ - FLASH->KEYR2 = FLASH_KEY1; - FLASH->KEYR2 = FLASH_KEY2; -#endif /* STM32F10X_XL */ -} -/** - * @brief Unlocks the FLASH Bank1 Program Erase Controller. - * @note This function can be used for all STM32F10x devices. - * - For STM32F10X_XL devices this function unlocks Bank1. - * - For all other devices it unlocks Bank1 and it is - * equivalent to FLASH_Unlock function. - * @param None - * @retval None - */ -void FLASH_UnlockBank1(void) -{ - /* Authorize the FPEC of Bank1 Access */ - FLASH->KEYR = FLASH_KEY1; - FLASH->KEYR = FLASH_KEY2; -} - -#ifdef STM32F10X_XL -/** - * @brief Unlocks the FLASH Bank2 Program Erase Controller. - * @note This function can be used only for STM32F10X_XL density devices. - * @param None - * @retval None - */ -void FLASH_UnlockBank2(void) -{ - /* Authorize the FPEC of Bank2 Access */ - FLASH->KEYR2 = FLASH_KEY1; - FLASH->KEYR2 = FLASH_KEY2; - -} -#endif /* STM32F10X_XL */ - -/** - * @brief Locks the FLASH Program Erase Controller. - * @note This function can be used for all STM32F10x devices. - * - For STM32F10X_XL devices this function Locks Bank1 and Bank2. - * - For all other devices it Locks Bank1 and it is equivalent - * to FLASH_LockBank1 function. - * @param None - * @retval None - */ -void FLASH_Lock(void) -{ - /* Set the Lock Bit to lock the FPEC and the CR of Bank1 */ - FLASH->CR |= CR_LOCK_Set; - -#ifdef STM32F10X_XL - /* Set the Lock Bit to lock the FPEC and the CR of Bank2 */ - FLASH->CR2 |= CR_LOCK_Set; -#endif /* STM32F10X_XL */ -} - -/** - * @brief Locks the FLASH Bank1 Program Erase Controller. - * @note this function can be used for all STM32F10x devices. - * - For STM32F10X_XL devices this function Locks Bank1. - * - For all other devices it Locks Bank1 and it is equivalent - * to FLASH_Lock function. - * @param None - * @retval None - */ -void FLASH_LockBank1(void) -{ - /* Set the Lock Bit to lock the FPEC and the CR of Bank1 */ - FLASH->CR |= CR_LOCK_Set; -} - -#ifdef STM32F10X_XL -/** - * @brief Locks the FLASH Bank2 Program Erase Controller. - * @note This function can be used only for STM32F10X_XL density devices. - * @param None - * @retval None - */ -void FLASH_LockBank2(void) -{ - /* Set the Lock Bit to lock the FPEC and the CR of Bank2 */ - FLASH->CR2 |= CR_LOCK_Set; -} -#endif /* STM32F10X_XL */ - -/** - * @brief Erases a specified FLASH page. - * @note This function can be used for all STM32F10x devices. - * @param Page_Address: The page address to be erased. - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_ErasePage(uint32_t Page_Address) -{ - FLASH_Status status = FLASH_COMPLETE; - /* Check the parameters */ - assert_param(IS_FLASH_ADDRESS(Page_Address)); - -#ifdef STM32F10X_XL - if(Page_Address < FLASH_BANK1_END_ADDRESS) - { - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank1Operation(EraseTimeout); - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to erase the page */ - FLASH->CR|= CR_PER_Set; - FLASH->AR = Page_Address; - FLASH->CR|= CR_STRT_Set; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank1Operation(EraseTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the erase operation is completed, disable the PER Bit */ - FLASH->CR &= CR_PER_Reset; - } - } - } - else - { - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank2Operation(EraseTimeout); - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to erase the page */ - FLASH->CR2|= CR_PER_Set; - FLASH->AR2 = Page_Address; - FLASH->CR2|= CR_STRT_Set; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank2Operation(EraseTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the erase operation is completed, disable the PER Bit */ - FLASH->CR2 &= CR_PER_Reset; - } - } - } -#else - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(EraseTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to erase the page */ - FLASH->CR|= CR_PER_Set; - FLASH->AR = Page_Address; - FLASH->CR|= CR_STRT_Set; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(EraseTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the erase operation is completed, disable the PER Bit */ - FLASH->CR &= CR_PER_Reset; - } - } -#endif /* STM32F10X_XL */ - - /* Return the Erase Status */ - return status; -} - -/** - * @brief Erases all FLASH pages. - * @note This function can be used for all STM32F10x devices. - * @param None - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_EraseAllPages(void) -{ - FLASH_Status status = FLASH_COMPLETE; - -#ifdef STM32F10X_XL - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank1Operation(EraseTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to erase all pages */ - FLASH->CR |= CR_MER_Set; - FLASH->CR |= CR_STRT_Set; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank1Operation(EraseTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the erase operation is completed, disable the MER Bit */ - FLASH->CR &= CR_MER_Reset; - } - } - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to erase all pages */ - FLASH->CR2 |= CR_MER_Set; - FLASH->CR2 |= CR_STRT_Set; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank2Operation(EraseTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the erase operation is completed, disable the MER Bit */ - FLASH->CR2 &= CR_MER_Reset; - } - } -#else - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(EraseTimeout); - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to erase all pages */ - FLASH->CR |= CR_MER_Set; - FLASH->CR |= CR_STRT_Set; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(EraseTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the erase operation is completed, disable the MER Bit */ - FLASH->CR &= CR_MER_Reset; - } - } -#endif /* STM32F10X_XL */ - - /* Return the Erase Status */ - return status; -} - -/** - * @brief Erases all Bank1 FLASH pages. - * @note This function can be used for all STM32F10x devices. - * - For STM32F10X_XL devices this function erases all Bank1 pages. - * - For all other devices it erases all Bank1 pages and it is equivalent - * to FLASH_EraseAllPages function. - * @param None - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_EraseAllBank1Pages(void) -{ - FLASH_Status status = FLASH_COMPLETE; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank1Operation(EraseTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to erase all pages */ - FLASH->CR |= CR_MER_Set; - FLASH->CR |= CR_STRT_Set; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank1Operation(EraseTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the erase operation is completed, disable the MER Bit */ - FLASH->CR &= CR_MER_Reset; - } - } - /* Return the Erase Status */ - return status; -} - -#ifdef STM32F10X_XL -/** - * @brief Erases all Bank2 FLASH pages. - * @note This function can be used only for STM32F10x_XL density devices. - * @param None - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_EraseAllBank2Pages(void) -{ - FLASH_Status status = FLASH_COMPLETE; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank2Operation(EraseTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to erase all pages */ - FLASH->CR2 |= CR_MER_Set; - FLASH->CR2 |= CR_STRT_Set; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank2Operation(EraseTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the erase operation is completed, disable the MER Bit */ - FLASH->CR2 &= CR_MER_Reset; - } - } - /* Return the Erase Status */ - return status; -} -#endif /* STM32F10X_XL */ - -/** - * @brief Erases the FLASH option bytes. - * @note This functions erases all option bytes except the Read protection (RDP). - * @note This function can be used for all STM32F10x devices. - * @param None - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_EraseOptionBytes(void) -{ - uint16_t rdptmp = RDP_Key; - - FLASH_Status status = FLASH_COMPLETE; - - /* Get the actual read protection Option Byte value */ - if(FLASH_GetReadOutProtectionStatus() != RESET) - { - rdptmp = 0x00; - } - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(EraseTimeout); - if(status == FLASH_COMPLETE) - { - /* Authorize the small information block programming */ - FLASH->OPTKEYR = FLASH_KEY1; - FLASH->OPTKEYR = FLASH_KEY2; - - /* if the previous operation is completed, proceed to erase the option bytes */ - FLASH->CR |= CR_OPTER_Set; - FLASH->CR |= CR_STRT_Set; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(EraseTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the erase operation is completed, disable the OPTER Bit */ - FLASH->CR &= CR_OPTER_Reset; - - /* Enable the Option Bytes Programming operation */ - FLASH->CR |= CR_OPTPG_Set; - /* Restore the last read protection Option Byte value */ - OB->RDP = (uint16_t)rdptmp; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - - if(status != FLASH_TIMEOUT) - { - /* if the program operation is completed, disable the OPTPG Bit */ - FLASH->CR &= CR_OPTPG_Reset; - } - } - else - { - if (status != FLASH_TIMEOUT) - { - /* Disable the OPTPG Bit */ - FLASH->CR &= CR_OPTPG_Reset; - } - } - } - /* Return the erase status */ - return status; -} - -/** - * @brief Programs a word at a specified address. - * @note This function can be used for all STM32F10x devices. - * @param Address: specifies the address to be programmed. - * @param Data: specifies the data to be programmed. - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_FLASH_ADDRESS(Address)); - -#ifdef STM32F10X_XL - if(Address < FLASH_BANK1_END_ADDRESS - 2) - { - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank1Operation(ProgramTimeout); - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new first - half word */ - FLASH->CR |= CR_PG_Set; - - *(__IO uint16_t*)Address = (uint16_t)Data; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new second - half word */ - tmp = Address + 2; - - *(__IO uint16_t*) tmp = Data >> 16; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - - if(status != FLASH_TIMEOUT) - { - /* Disable the PG Bit */ - FLASH->CR &= CR_PG_Reset; - } - } - else - { - if (status != FLASH_TIMEOUT) - { - /* Disable the PG Bit */ - FLASH->CR &= CR_PG_Reset; - } - } - } - } - else if(Address == (FLASH_BANK1_END_ADDRESS - 1)) - { - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank1Operation(ProgramTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new first - half word */ - FLASH->CR |= CR_PG_Set; - - *(__IO uint16_t*)Address = (uint16_t)Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank1Operation(ProgramTimeout); - - if(status != FLASH_TIMEOUT) - { - /* Disable the PG Bit */ - FLASH->CR &= CR_PG_Reset; - } - } - else - { - if (status != FLASH_TIMEOUT) - { - /* Disable the PG Bit */ - FLASH->CR &= CR_PG_Reset; - } - } - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank2Operation(ProgramTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new second - half word */ - FLASH->CR2 |= CR_PG_Set; - tmp = Address + 2; - - *(__IO uint16_t*) tmp = Data >> 16; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank2Operation(ProgramTimeout); - - if(status != FLASH_TIMEOUT) - { - /* Disable the PG Bit */ - FLASH->CR2 &= CR_PG_Reset; - } - } - else - { - if (status != FLASH_TIMEOUT) - { - /* Disable the PG Bit */ - FLASH->CR2 &= CR_PG_Reset; - } - } - } - else - { - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank2Operation(ProgramTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new first - half word */ - FLASH->CR2 |= CR_PG_Set; - - *(__IO uint16_t*)Address = (uint16_t)Data; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank2Operation(ProgramTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new second - half word */ - tmp = Address + 2; - - *(__IO uint16_t*) tmp = Data >> 16; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank2Operation(ProgramTimeout); - - if(status != FLASH_TIMEOUT) - { - /* Disable the PG Bit */ - FLASH->CR2 &= CR_PG_Reset; - } - } - else - { - if (status != FLASH_TIMEOUT) - { - /* Disable the PG Bit */ - FLASH->CR2 &= CR_PG_Reset; - } - } - } - } -#else - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new first - half word */ - FLASH->CR |= CR_PG_Set; - - *(__IO uint16_t*)Address = (uint16_t)Data; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new second - half word */ - tmp = Address + 2; - - *(__IO uint16_t*) tmp = Data >> 16; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - - if(status != FLASH_TIMEOUT) - { - /* Disable the PG Bit */ - FLASH->CR &= CR_PG_Reset; - } - } - else - { - if (status != FLASH_TIMEOUT) - { - /* Disable the PG Bit */ - FLASH->CR &= CR_PG_Reset; - } - } - } -#endif /* STM32F10X_XL */ - - /* Return the Program Status */ - return status; -} - -/** - * @brief Programs a half word at a specified address. - * @note This function can be used for all STM32F10x devices. - * @param Address: specifies the address to be programmed. - * @param Data: specifies the data to be programmed. - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - /* Check the parameters */ - assert_param(IS_FLASH_ADDRESS(Address)); - -#ifdef STM32F10X_XL - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - - if(Address < FLASH_BANK1_END_ADDRESS) - { - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new data */ - FLASH->CR |= CR_PG_Set; - - *(__IO uint16_t*)Address = Data; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank1Operation(ProgramTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the program operation is completed, disable the PG Bit */ - FLASH->CR &= CR_PG_Reset; - } - } - } - else - { - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new data */ - FLASH->CR2 |= CR_PG_Set; - - *(__IO uint16_t*)Address = Data; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastBank2Operation(ProgramTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the program operation is completed, disable the PG Bit */ - FLASH->CR2 &= CR_PG_Reset; - } - } - } -#else - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new data */ - FLASH->CR |= CR_PG_Set; - - *(__IO uint16_t*)Address = Data; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the program operation is completed, disable the PG Bit */ - FLASH->CR &= CR_PG_Reset; - } - } -#endif /* STM32F10X_XL */ - - /* Return the Program Status */ - return status; -} - -/** - * @brief Programs a half word at a specified Option Byte Data address. - * @note This function can be used for all STM32F10x devices. - * @param Address: specifies the address to be programmed. - * This parameter can be 0x1FFFF804 or 0x1FFFF806. - * @param Data: specifies the data to be programmed. - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - /* Check the parameters */ - assert_param(IS_OB_DATA_ADDRESS(Address)); - status = FLASH_WaitForLastOperation(ProgramTimeout); - - if(status == FLASH_COMPLETE) - { - /* Authorize the small information block programming */ - FLASH->OPTKEYR = FLASH_KEY1; - FLASH->OPTKEYR = FLASH_KEY2; - /* Enables the Option Bytes Programming operation */ - FLASH->CR |= CR_OPTPG_Set; - *(__IO uint16_t*)Address = Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the program operation is completed, disable the OPTPG Bit */ - FLASH->CR &= CR_OPTPG_Reset; - } - } - /* Return the Option Byte Data Program Status */ - return status; -} - -/** - * @brief Write protects the desired pages - * @note This function can be used for all STM32F10x devices. - * @param FLASH_Pages: specifies the address of the pages to be write protected. - * This parameter can be: - * @arg For @b STM32_Low-density_devices: value between FLASH_WRProt_Pages0to3 and FLASH_WRProt_Pages28to31 - * @arg For @b STM32_Medium-density_devices: value between FLASH_WRProt_Pages0to3 - * and FLASH_WRProt_Pages124to127 - * @arg For @b STM32_High-density_devices: value between FLASH_WRProt_Pages0to1 and - * FLASH_WRProt_Pages60to61 or FLASH_WRProt_Pages62to255 - * @arg For @b STM32_Connectivity_line_devices: value between FLASH_WRProt_Pages0to1 and - * FLASH_WRProt_Pages60to61 or FLASH_WRProt_Pages62to127 - * @arg For @b STM32_XL-density_devices: value between FLASH_WRProt_Pages0to1 and - * FLASH_WRProt_Pages60to61 or FLASH_WRProt_Pages62to511 - * @arg FLASH_WRProt_AllPages - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages) -{ - uint16_t WRP0_Data = 0xFFFF, WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF; - - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_FLASH_WRPROT_PAGE(FLASH_Pages)); - - FLASH_Pages = (uint32_t)(~FLASH_Pages); - WRP0_Data = (uint16_t)(FLASH_Pages & WRP0_Mask); - WRP1_Data = (uint16_t)((FLASH_Pages & WRP1_Mask) >> 8); - WRP2_Data = (uint16_t)((FLASH_Pages & WRP2_Mask) >> 16); - WRP3_Data = (uint16_t)((FLASH_Pages & WRP3_Mask) >> 24); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - - if(status == FLASH_COMPLETE) - { - /* Authorizes the small information block programming */ - FLASH->OPTKEYR = FLASH_KEY1; - FLASH->OPTKEYR = FLASH_KEY2; - FLASH->CR |= CR_OPTPG_Set; - if(WRP0_Data != 0xFF) - { - OB->WRP0 = WRP0_Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - } - if((status == FLASH_COMPLETE) && (WRP1_Data != 0xFF)) - { - OB->WRP1 = WRP1_Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - } - if((status == FLASH_COMPLETE) && (WRP2_Data != 0xFF)) - { - OB->WRP2 = WRP2_Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - } - - if((status == FLASH_COMPLETE)&& (WRP3_Data != 0xFF)) - { - OB->WRP3 = WRP3_Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - } - - if(status != FLASH_TIMEOUT) - { - /* if the program operation is completed, disable the OPTPG Bit */ - FLASH->CR &= CR_OPTPG_Reset; - } - } - /* Return the write protection operation Status */ - return status; -} - -/** - * @brief Enables or disables the read out protection. - * @note If the user has already programmed the other option bytes before calling - * this function, he must re-program them since this function erases all option bytes. - * @note This function can be used for all STM32F10x devices. - * @param Newstate: new state of the ReadOut Protection. - * This parameter can be: ENABLE or DISABLE. - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState) -{ - FLASH_Status status = FLASH_COMPLETE; - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - status = FLASH_WaitForLastOperation(EraseTimeout); - if(status == FLASH_COMPLETE) - { - /* Authorizes the small information block programming */ - FLASH->OPTKEYR = FLASH_KEY1; - FLASH->OPTKEYR = FLASH_KEY2; - FLASH->CR |= CR_OPTER_Set; - FLASH->CR |= CR_STRT_Set; - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(EraseTimeout); - if(status == FLASH_COMPLETE) - { - /* if the erase operation is completed, disable the OPTER Bit */ - FLASH->CR &= CR_OPTER_Reset; - /* Enable the Option Bytes Programming operation */ - FLASH->CR |= CR_OPTPG_Set; - if(NewState != DISABLE) - { - OB->RDP = 0x00; - } - else - { - OB->RDP = RDP_Key; - } - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(EraseTimeout); - - if(status != FLASH_TIMEOUT) - { - /* if the program operation is completed, disable the OPTPG Bit */ - FLASH->CR &= CR_OPTPG_Reset; - } - } - else - { - if(status != FLASH_TIMEOUT) - { - /* Disable the OPTER Bit */ - FLASH->CR &= CR_OPTER_Reset; - } - } - } - /* Return the protection operation Status */ - return status; -} - -/** - * @brief Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY. - * @note This function can be used for all STM32F10x devices. - * @param OB_IWDG: Selects the IWDG mode - * This parameter can be one of the following values: - * @arg OB_IWDG_SW: Software IWDG selected - * @arg OB_IWDG_HW: Hardware IWDG selected - * @param OB_STOP: Reset event when entering STOP mode. - * This parameter can be one of the following values: - * @arg OB_STOP_NoRST: No reset generated when entering in STOP - * @arg OB_STOP_RST: Reset generated when entering in STOP - * @param OB_STDBY: Reset event when entering Standby mode. - * This parameter can be one of the following values: - * @arg OB_STDBY_NoRST: No reset generated when entering in STANDBY - * @arg OB_STDBY_RST: Reset generated when entering in STANDBY - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_OB_IWDG_SOURCE(OB_IWDG)); - assert_param(IS_OB_STOP_SOURCE(OB_STOP)); - assert_param(IS_OB_STDBY_SOURCE(OB_STDBY)); - - /* Authorize the small information block programming */ - FLASH->OPTKEYR = FLASH_KEY1; - FLASH->OPTKEYR = FLASH_KEY2; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - - if(status == FLASH_COMPLETE) - { - /* Enable the Option Bytes Programming operation */ - FLASH->CR |= CR_OPTPG_Set; - - OB->USER = OB_IWDG | (uint16_t)(OB_STOP | (uint16_t)(OB_STDBY | ((uint16_t)0xF8))); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the program operation is completed, disable the OPTPG Bit */ - FLASH->CR &= CR_OPTPG_Reset; - } - } - /* Return the Option Byte program Status */ - return status; -} - -#ifdef STM32F10X_XL -/** - * @brief Configures to boot from Bank1 or Bank2. - * @note This function can be used only for STM32F10x_XL density devices. - * @param FLASH_BOOT: select the FLASH Bank to boot from. - * This parameter can be one of the following values: - * @arg FLASH_BOOT_Bank1: At startup, if boot pins are set in boot from user Flash - * position and this parameter is selected the device will boot from Bank1(Default). - * @arg FLASH_BOOT_Bank2: At startup, if boot pins are set in boot from user Flash - * position and this parameter is selected the device will boot from Bank2 or Bank1, - * depending on the activation of the bank. The active banks are checked in - * the following order: Bank2, followed by Bank1. - * The active bank is recognized by the value programmed at the base address - * of the respective bank (corresponding to the initial stack pointer value - * in the interrupt vector table). - * For more information, please refer to AN2606 from www.st.com. - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_BootConfig(uint16_t FLASH_BOOT) -{ - FLASH_Status status = FLASH_COMPLETE; - assert_param(IS_FLASH_BOOT(FLASH_BOOT)); - /* Authorize the small information block programming */ - FLASH->OPTKEYR = FLASH_KEY1; - FLASH->OPTKEYR = FLASH_KEY2; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - - if(status == FLASH_COMPLETE) - { - /* Enable the Option Bytes Programming operation */ - FLASH->CR |= CR_OPTPG_Set; - - if(FLASH_BOOT == FLASH_BOOT_Bank1) - { - OB->USER |= OB_USER_BFB2; - } - else - { - OB->USER &= (uint16_t)(~(uint16_t)(OB_USER_BFB2)); - } - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(ProgramTimeout); - if(status != FLASH_TIMEOUT) - { - /* if the program operation is completed, disable the OPTPG Bit */ - FLASH->CR &= CR_OPTPG_Reset; - } - } - /* Return the Option Byte program Status */ - return status; -} -#endif /* STM32F10X_XL */ - -/** - * @brief Returns the FLASH User Option Bytes values. - * @note This function can be used for all STM32F10x devices. - * @param None - * @retval The FLASH User Option Bytes values:IWDG_SW(Bit0), RST_STOP(Bit1) - * and RST_STDBY(Bit2). - */ -uint32_t FLASH_GetUserOptionByte(void) -{ - /* Return the User Option Byte */ - return (uint32_t)(FLASH->OBR >> 2); -} - -/** - * @brief Returns the FLASH Write Protection Option Bytes Register value. - * @note This function can be used for all STM32F10x devices. - * @param None - * @retval The FLASH Write Protection Option Bytes Register value - */ -uint32_t FLASH_GetWriteProtectionOptionByte(void) -{ - /* Return the Falsh write protection Register value */ - return (uint32_t)(FLASH->WRPR); -} - -/** - * @brief Checks whether the FLASH Read Out Protection Status is set or not. - * @note This function can be used for all STM32F10x devices. - * @param None - * @retval FLASH ReadOut Protection Status(SET or RESET) - */ -FlagStatus FLASH_GetReadOutProtectionStatus(void) -{ - FlagStatus readoutstatus = RESET; - if ((FLASH->OBR & RDPRT_Mask) != (uint32_t)RESET) - { - readoutstatus = SET; - } - else - { - readoutstatus = RESET; - } - return readoutstatus; -} - -/** - * @brief Checks whether the FLASH Prefetch Buffer status is set or not. - * @note This function can be used for all STM32F10x devices. - * @param None - * @retval FLASH Prefetch Buffer Status (SET or RESET). - */ -FlagStatus FLASH_GetPrefetchBufferStatus(void) -{ - FlagStatus bitstatus = RESET; - - if ((FLASH->ACR & ACR_PRFTBS_Mask) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the new state of FLASH Prefetch Buffer Status (SET or RESET) */ - return bitstatus; -} - -/** - * @brief Enables or disables the specified FLASH interrupts. - * @note This function can be used for all STM32F10x devices. - * - For STM32F10X_XL devices, enables or disables the specified FLASH interrupts - for Bank1 and Bank2. - * - For other devices it enables or disables the specified FLASH interrupts for Bank1. - * @param FLASH_IT: specifies the FLASH interrupt sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg FLASH_IT_ERROR: FLASH Error Interrupt - * @arg FLASH_IT_EOP: FLASH end of operation Interrupt - * @param NewState: new state of the specified Flash interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState) -{ -#ifdef STM32F10X_XL - /* Check the parameters */ - assert_param(IS_FLASH_IT(FLASH_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if((FLASH_IT & 0x80000000) != 0x0) - { - if(NewState != DISABLE) - { - /* Enable the interrupt sources */ - FLASH->CR2 |= (FLASH_IT & 0x7FFFFFFF); - } - else - { - /* Disable the interrupt sources */ - FLASH->CR2 &= ~(uint32_t)(FLASH_IT & 0x7FFFFFFF); - } - } - else - { - if(NewState != DISABLE) - { - /* Enable the interrupt sources */ - FLASH->CR |= FLASH_IT; - } - else - { - /* Disable the interrupt sources */ - FLASH->CR &= ~(uint32_t)FLASH_IT; - } - } -#else - /* Check the parameters */ - assert_param(IS_FLASH_IT(FLASH_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if(NewState != DISABLE) - { - /* Enable the interrupt sources */ - FLASH->CR |= FLASH_IT; - } - else - { - /* Disable the interrupt sources */ - FLASH->CR &= ~(uint32_t)FLASH_IT; - } -#endif /* STM32F10X_XL */ -} - -/** - * @brief Checks whether the specified FLASH flag is set or not. - * @note This function can be used for all STM32F10x devices. - * - For STM32F10X_XL devices, this function checks whether the specified - * Bank1 or Bank2 flag is set or not. - * - For other devices, it checks whether the specified Bank1 flag is - * set or not. - * @param FLASH_FLAG: specifies the FLASH flag to check. - * This parameter can be one of the following values: - * @arg FLASH_FLAG_BSY: FLASH Busy flag - * @arg FLASH_FLAG_PGERR: FLASH Program error flag - * @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag - * @arg FLASH_FLAG_EOP: FLASH End of Operation flag - * @arg FLASH_FLAG_OPTERR: FLASH Option Byte error flag - * @retval The new state of FLASH_FLAG (SET or RESET). - */ -FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG) -{ - FlagStatus bitstatus = RESET; - -#ifdef STM32F10X_XL - /* Check the parameters */ - assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)) ; - if(FLASH_FLAG == FLASH_FLAG_OPTERR) - { - if((FLASH->OBR & FLASH_FLAG_OPTERR) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - } - else - { - if((FLASH_FLAG & 0x80000000) != 0x0) - { - if((FLASH->SR2 & FLASH_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - } - else - { - if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - } - } -#else - /* Check the parameters */ - assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)) ; - if(FLASH_FLAG == FLASH_FLAG_OPTERR) - { - if((FLASH->OBR & FLASH_FLAG_OPTERR) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - } - else - { - if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - } -#endif /* STM32F10X_XL */ - - /* Return the new state of FLASH_FLAG (SET or RESET) */ - return bitstatus; -} - -/** - * @brief Clears the FLASHs pending flags. - * @note This function can be used for all STM32F10x devices. - * - For STM32F10X_XL devices, this function clears Bank1 or Bank2s pending flags - * - For other devices, it clears Bank1s pending flags. - * @param FLASH_FLAG: specifies the FLASH flags to clear. - * This parameter can be any combination of the following values: - * @arg FLASH_FLAG_PGERR: FLASH Program error flag - * @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag - * @arg FLASH_FLAG_EOP: FLASH End of Operation flag - * @retval None - */ -void FLASH_ClearFlag(uint32_t FLASH_FLAG) -{ -#ifdef STM32F10X_XL - /* Check the parameters */ - assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)) ; - - if((FLASH_FLAG & 0x80000000) != 0x0) - { - /* Clear the flags */ - FLASH->SR2 = FLASH_FLAG; - } - else - { - /* Clear the flags */ - FLASH->SR = FLASH_FLAG; - } - -#else - /* Check the parameters */ - assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)) ; - - /* Clear the flags */ - FLASH->SR = FLASH_FLAG; -#endif /* STM32F10X_XL */ -} - -/** - * @brief Returns the FLASH Status. - * @note This function can be used for all STM32F10x devices, it is equivalent - * to FLASH_GetBank1Status function. - * @param None - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, - * FLASH_ERROR_WRP or FLASH_COMPLETE - */ -FLASH_Status FLASH_GetStatus(void) -{ - FLASH_Status flashstatus = FLASH_COMPLETE; - - if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY) - { - flashstatus = FLASH_BUSY; - } - else - { - if((FLASH->SR & FLASH_FLAG_PGERR) != 0) - { - flashstatus = FLASH_ERROR_PG; - } - else - { - if((FLASH->SR & FLASH_FLAG_WRPRTERR) != 0 ) - { - flashstatus = FLASH_ERROR_WRP; - } - else - { - flashstatus = FLASH_COMPLETE; - } - } - } - /* Return the Flash Status */ - return flashstatus; -} - -/** - * @brief Returns the FLASH Bank1 Status. - * @note This function can be used for all STM32F10x devices, it is equivalent - * to FLASH_GetStatus function. - * @param None - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, - * FLASH_ERROR_WRP or FLASH_COMPLETE - */ -FLASH_Status FLASH_GetBank1Status(void) -{ - FLASH_Status flashstatus = FLASH_COMPLETE; - - if((FLASH->SR & FLASH_FLAG_BANK1_BSY) == FLASH_FLAG_BSY) - { - flashstatus = FLASH_BUSY; - } - else - { - if((FLASH->SR & FLASH_FLAG_BANK1_PGERR) != 0) - { - flashstatus = FLASH_ERROR_PG; - } - else - { - if((FLASH->SR & FLASH_FLAG_BANK1_WRPRTERR) != 0 ) - { - flashstatus = FLASH_ERROR_WRP; - } - else - { - flashstatus = FLASH_COMPLETE; - } - } - } - /* Return the Flash Status */ - return flashstatus; -} - -#ifdef STM32F10X_XL -/** - * @brief Returns the FLASH Bank2 Status. - * @note This function can be used for STM32F10x_XL density devices. - * @param None - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, - * FLASH_ERROR_WRP or FLASH_COMPLETE - */ -FLASH_Status FLASH_GetBank2Status(void) -{ - FLASH_Status flashstatus = FLASH_COMPLETE; - - if((FLASH->SR2 & (FLASH_FLAG_BANK2_BSY & 0x7FFFFFFF)) == (FLASH_FLAG_BANK2_BSY & 0x7FFFFFFF)) - { - flashstatus = FLASH_BUSY; - } - else - { - if((FLASH->SR2 & (FLASH_FLAG_BANK2_PGERR & 0x7FFFFFFF)) != 0) - { - flashstatus = FLASH_ERROR_PG; - } - else - { - if((FLASH->SR2 & (FLASH_FLAG_BANK2_WRPRTERR & 0x7FFFFFFF)) != 0 ) - { - flashstatus = FLASH_ERROR_WRP; - } - else - { - flashstatus = FLASH_COMPLETE; - } - } - } - /* Return the Flash Status */ - return flashstatus; -} -#endif /* STM32F10X_XL */ -/** - * @brief Waits for a Flash operation to complete or a TIMEOUT to occur. - * @note This function can be used for all STM32F10x devices, - * it is equivalent to FLASH_WaitForLastBank1Operation. - * - For STM32F10X_XL devices this function waits for a Bank1 Flash operation - * to complete or a TIMEOUT to occur. - * - For all other devices it waits for a Flash operation to complete - * or a TIMEOUT to occur. - * @param Timeout: FLASH progamming Timeout - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check for the Flash Status */ - status = FLASH_GetBank1Status(); - /* Wait for a Flash operation to complete or a TIMEOUT to occur */ - while((status == FLASH_BUSY) && (Timeout != 0x00)) - { - status = FLASH_GetBank1Status(); - Timeout--; - } - if(Timeout == 0x00 ) - { - status = FLASH_TIMEOUT; - } - /* Return the operation status */ - return status; -} - -/** - * @brief Waits for a Flash operation on Bank1 to complete or a TIMEOUT to occur. - * @note This function can be used for all STM32F10x devices, - * it is equivalent to FLASH_WaitForLastOperation. - * @param Timeout: FLASH progamming Timeout - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_WaitForLastBank1Operation(uint32_t Timeout) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check for the Flash Status */ - status = FLASH_GetBank1Status(); - /* Wait for a Flash operation to complete or a TIMEOUT to occur */ - while((status == FLASH_FLAG_BANK1_BSY) && (Timeout != 0x00)) - { - status = FLASH_GetBank1Status(); - Timeout--; - } - if(Timeout == 0x00 ) - { - status = FLASH_TIMEOUT; - } - /* Return the operation status */ - return status; -} - -#ifdef STM32F10X_XL -/** - * @brief Waits for a Flash operation on Bank2 to complete or a TIMEOUT to occur. - * @note This function can be used only for STM32F10x_XL density devices. - * @param Timeout: FLASH progamming Timeout - * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, - * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_WaitForLastBank2Operation(uint32_t Timeout) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check for the Flash Status */ - status = FLASH_GetBank2Status(); - /* Wait for a Flash operation to complete or a TIMEOUT to occur */ - while((status == (FLASH_FLAG_BANK2_BSY & 0x7FFFFFFF)) && (Timeout != 0x00)) - { - status = FLASH_GetBank2Status(); - Timeout--; - } - if(Timeout == 0x00 ) - { - status = FLASH_TIMEOUT; - } - /* Return the operation status */ - return status; -} -#endif /* STM32F10X_XL */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_fsmc.c b/example/libs_stm/src/stm32f10x/stm32f10x_fsmc.c deleted file mode 100644 index d04221942..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_fsmc.c +++ /dev/null @@ -1,858 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_fsmc.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the FSMC firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_fsmc.h" -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup FSMC - * @brief FSMC driver modules - * @{ - */ - -/** @defgroup FSMC_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - -/** @defgroup FSMC_Private_Defines - * @{ - */ - -/* --------------------- FSMC registers bit mask ---------------------------- */ - -/* FSMC BCRx Mask */ -#define BCR_MBKEN_Set ((uint32_t)0x00000001) -#define BCR_MBKEN_Reset ((uint32_t)0x000FFFFE) -#define BCR_FACCEN_Set ((uint32_t)0x00000040) - -/* FSMC PCRx Mask */ -#define PCR_PBKEN_Set ((uint32_t)0x00000004) -#define PCR_PBKEN_Reset ((uint32_t)0x000FFFFB) -#define PCR_ECCEN_Set ((uint32_t)0x00000040) -#define PCR_ECCEN_Reset ((uint32_t)0x000FFFBF) -#define PCR_MemoryType_NAND ((uint32_t)0x00000008) -/** - * @} - */ - -/** @defgroup FSMC_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup FSMC_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup FSMC_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup FSMC_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the FSMC NOR/SRAM Banks registers to their default - * reset values. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank1_NORSRAM1: FSMC Bank1 NOR/SRAM1 - * @arg FSMC_Bank1_NORSRAM2: FSMC Bank1 NOR/SRAM2 - * @arg FSMC_Bank1_NORSRAM3: FSMC Bank1 NOR/SRAM3 - * @arg FSMC_Bank1_NORSRAM4: FSMC Bank1 NOR/SRAM4 - * @retval None - */ -void FSMC_NORSRAMDeInit(uint32_t FSMC_Bank) -{ - /* Check the parameter */ - assert_param(IS_FSMC_NORSRAM_BANK(FSMC_Bank)); - - /* FSMC_Bank1_NORSRAM1 */ - if(FSMC_Bank == FSMC_Bank1_NORSRAM1) - { - FSMC_Bank1->BTCR[FSMC_Bank] = 0x000030DB; - } - /* FSMC_Bank1_NORSRAM2, FSMC_Bank1_NORSRAM3 or FSMC_Bank1_NORSRAM4 */ - else - { - FSMC_Bank1->BTCR[FSMC_Bank] = 0x000030D2; - } - FSMC_Bank1->BTCR[FSMC_Bank + 1] = 0x0FFFFFFF; - FSMC_Bank1E->BWTR[FSMC_Bank] = 0x0FFFFFFF; -} - -/** - * @brief Deinitializes the FSMC NAND Banks registers to their default reset values. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @retval None - */ -void FSMC_NANDDeInit(uint32_t FSMC_Bank) -{ - /* Check the parameter */ - assert_param(IS_FSMC_NAND_BANK(FSMC_Bank)); - - if(FSMC_Bank == FSMC_Bank2_NAND) - { - /* Set the FSMC_Bank2 registers to their reset values */ - FSMC_Bank2->PCR2 = 0x00000018; - FSMC_Bank2->SR2 = 0x00000040; - FSMC_Bank2->PMEM2 = 0xFCFCFCFC; - FSMC_Bank2->PATT2 = 0xFCFCFCFC; - } - /* FSMC_Bank3_NAND */ - else - { - /* Set the FSMC_Bank3 registers to their reset values */ - FSMC_Bank3->PCR3 = 0x00000018; - FSMC_Bank3->SR3 = 0x00000040; - FSMC_Bank3->PMEM3 = 0xFCFCFCFC; - FSMC_Bank3->PATT3 = 0xFCFCFCFC; - } -} - -/** - * @brief Deinitializes the FSMC PCCARD Bank registers to their default reset values. - * @param None - * @retval None - */ -void FSMC_PCCARDDeInit(void) -{ - /* Set the FSMC_Bank4 registers to their reset values */ - FSMC_Bank4->PCR4 = 0x00000018; - FSMC_Bank4->SR4 = 0x00000000; - FSMC_Bank4->PMEM4 = 0xFCFCFCFC; - FSMC_Bank4->PATT4 = 0xFCFCFCFC; - FSMC_Bank4->PIO4 = 0xFCFCFCFC; -} - -/** - * @brief Initializes the FSMC NOR/SRAM Banks according to the specified - * parameters in the FSMC_NORSRAMInitStruct. - * @param FSMC_NORSRAMInitStruct : pointer to a FSMC_NORSRAMInitTypeDef - * structure that contains the configuration information for - * the FSMC NOR/SRAM specified Banks. - * @retval None - */ -void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct) -{ - /* Check the parameters */ - assert_param(IS_FSMC_NORSRAM_BANK(FSMC_NORSRAMInitStruct->FSMC_Bank)); - assert_param(IS_FSMC_MUX(FSMC_NORSRAMInitStruct->FSMC_DataAddressMux)); - assert_param(IS_FSMC_MEMORY(FSMC_NORSRAMInitStruct->FSMC_MemoryType)); - assert_param(IS_FSMC_MEMORY_WIDTH(FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth)); - assert_param(IS_FSMC_BURSTMODE(FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode)); - assert_param(IS_FSMC_WAIT_POLARITY(FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity)); - assert_param(IS_FSMC_WRAP_MODE(FSMC_NORSRAMInitStruct->FSMC_WrapMode)); - assert_param(IS_FSMC_WAIT_SIGNAL_ACTIVE(FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive)); - assert_param(IS_FSMC_WRITE_OPERATION(FSMC_NORSRAMInitStruct->FSMC_WriteOperation)); - assert_param(IS_FSMC_WAITE_SIGNAL(FSMC_NORSRAMInitStruct->FSMC_WaitSignal)); - assert_param(IS_FSMC_EXTENDED_MODE(FSMC_NORSRAMInitStruct->FSMC_ExtendedMode)); - assert_param(IS_FSMC_WRITE_BURST(FSMC_NORSRAMInitStruct->FSMC_WriteBurst)); - assert_param(IS_FSMC_ADDRESS_SETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime)); - assert_param(IS_FSMC_ADDRESS_HOLD_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime)); - assert_param(IS_FSMC_DATASETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime)); - assert_param(IS_FSMC_TURNAROUND_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration)); - assert_param(IS_FSMC_CLK_DIV(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision)); - assert_param(IS_FSMC_DATA_LATENCY(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency)); - assert_param(IS_FSMC_ACCESS_MODE(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode)); - - /* Bank1 NOR/SRAM control register configuration */ - FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank] = - (uint32_t)FSMC_NORSRAMInitStruct->FSMC_DataAddressMux | - FSMC_NORSRAMInitStruct->FSMC_MemoryType | - FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth | - FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode | - FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity | - FSMC_NORSRAMInitStruct->FSMC_WrapMode | - FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive | - FSMC_NORSRAMInitStruct->FSMC_WriteOperation | - FSMC_NORSRAMInitStruct->FSMC_WaitSignal | - FSMC_NORSRAMInitStruct->FSMC_ExtendedMode | - FSMC_NORSRAMInitStruct->FSMC_WriteBurst; - if(FSMC_NORSRAMInitStruct->FSMC_MemoryType == FSMC_MemoryType_NOR) - { - FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank] |= (uint32_t)BCR_FACCEN_Set; - } - /* Bank1 NOR/SRAM timing register configuration */ - FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank+1] = - (uint32_t)FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime | - (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime << 4) | - (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime << 8) | - (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration << 16) | - (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision << 20) | - (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency << 24) | - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode; - - - /* Bank1 NOR/SRAM timing register for write configuration, if extended mode is used */ - if(FSMC_NORSRAMInitStruct->FSMC_ExtendedMode == FSMC_ExtendedMode_Enable) - { - assert_param(IS_FSMC_ADDRESS_SETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime)); - assert_param(IS_FSMC_ADDRESS_HOLD_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime)); - assert_param(IS_FSMC_DATASETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime)); - assert_param(IS_FSMC_CLK_DIV(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision)); - assert_param(IS_FSMC_DATA_LATENCY(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency)); - assert_param(IS_FSMC_ACCESS_MODE(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode)); - FSMC_Bank1E->BWTR[FSMC_NORSRAMInitStruct->FSMC_Bank] = - (uint32_t)FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime | - (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime << 4 )| - (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime << 8) | - (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision << 20) | - (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency << 24) | - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode; - } - else - { - FSMC_Bank1E->BWTR[FSMC_NORSRAMInitStruct->FSMC_Bank] = 0x0FFFFFFF; - } -} - -/** - * @brief Initializes the FSMC NAND Banks according to the specified - * parameters in the FSMC_NANDInitStruct. - * @param FSMC_NANDInitStruct : pointer to a FSMC_NANDInitTypeDef - * structure that contains the configuration information for the FSMC NAND specified Banks. - * @retval None - */ -void FSMC_NANDInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct) -{ - uint32_t tmppcr = 0x00000000, tmppmem = 0x00000000, tmppatt = 0x00000000; - - /* Check the parameters */ - assert_param( IS_FSMC_NAND_BANK(FSMC_NANDInitStruct->FSMC_Bank)); - assert_param( IS_FSMC_WAIT_FEATURE(FSMC_NANDInitStruct->FSMC_Waitfeature)); - assert_param( IS_FSMC_MEMORY_WIDTH(FSMC_NANDInitStruct->FSMC_MemoryDataWidth)); - assert_param( IS_FSMC_ECC_STATE(FSMC_NANDInitStruct->FSMC_ECC)); - assert_param( IS_FSMC_ECCPAGE_SIZE(FSMC_NANDInitStruct->FSMC_ECCPageSize)); - assert_param( IS_FSMC_TCLR_TIME(FSMC_NANDInitStruct->FSMC_TCLRSetupTime)); - assert_param( IS_FSMC_TAR_TIME(FSMC_NANDInitStruct->FSMC_TARSetupTime)); - assert_param(IS_FSMC_SETUP_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime)); - assert_param(IS_FSMC_WAIT_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime)); - assert_param(IS_FSMC_HOLD_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime)); - assert_param(IS_FSMC_HIZ_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime)); - assert_param(IS_FSMC_SETUP_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime)); - assert_param(IS_FSMC_WAIT_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime)); - assert_param(IS_FSMC_HOLD_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime)); - assert_param(IS_FSMC_HIZ_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime)); - - /* Set the tmppcr value according to FSMC_NANDInitStruct parameters */ - tmppcr = (uint32_t)FSMC_NANDInitStruct->FSMC_Waitfeature | - PCR_MemoryType_NAND | - FSMC_NANDInitStruct->FSMC_MemoryDataWidth | - FSMC_NANDInitStruct->FSMC_ECC | - FSMC_NANDInitStruct->FSMC_ECCPageSize | - (FSMC_NANDInitStruct->FSMC_TCLRSetupTime << 9 )| - (FSMC_NANDInitStruct->FSMC_TARSetupTime << 13); - - /* Set tmppmem value according to FSMC_CommonSpaceTimingStructure parameters */ - tmppmem = (uint32_t)FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime | - (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime << 8) | - (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime << 16)| - (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime << 24); - - /* Set tmppatt value according to FSMC_AttributeSpaceTimingStructure parameters */ - tmppatt = (uint32_t)FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime | - (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime << 8) | - (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime << 16)| - (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime << 24); - - if(FSMC_NANDInitStruct->FSMC_Bank == FSMC_Bank2_NAND) - { - /* FSMC_Bank2_NAND registers configuration */ - FSMC_Bank2->PCR2 = tmppcr; - FSMC_Bank2->PMEM2 = tmppmem; - FSMC_Bank2->PATT2 = tmppatt; - } - else - { - /* FSMC_Bank3_NAND registers configuration */ - FSMC_Bank3->PCR3 = tmppcr; - FSMC_Bank3->PMEM3 = tmppmem; - FSMC_Bank3->PATT3 = tmppatt; - } -} - -/** - * @brief Initializes the FSMC PCCARD Bank according to the specified - * parameters in the FSMC_PCCARDInitStruct. - * @param FSMC_PCCARDInitStruct : pointer to a FSMC_PCCARDInitTypeDef - * structure that contains the configuration information for the FSMC PCCARD Bank. - * @retval None - */ -void FSMC_PCCARDInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct) -{ - /* Check the parameters */ - assert_param(IS_FSMC_WAIT_FEATURE(FSMC_PCCARDInitStruct->FSMC_Waitfeature)); - assert_param(IS_FSMC_TCLR_TIME(FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime)); - assert_param(IS_FSMC_TAR_TIME(FSMC_PCCARDInitStruct->FSMC_TARSetupTime)); - - assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime)); - assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime)); - assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime)); - assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime)); - - assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime)); - assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime)); - assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime)); - assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime)); - assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime)); - assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime)); - assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime)); - assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime)); - - /* Set the PCR4 register value according to FSMC_PCCARDInitStruct parameters */ - FSMC_Bank4->PCR4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_Waitfeature | - FSMC_MemoryDataWidth_16b | - (FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime << 9) | - (FSMC_PCCARDInitStruct->FSMC_TARSetupTime << 13); - - /* Set PMEM4 register value according to FSMC_CommonSpaceTimingStructure parameters */ - FSMC_Bank4->PMEM4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime | - (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime << 8) | - (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime << 16)| - (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime << 24); - - /* Set PATT4 register value according to FSMC_AttributeSpaceTimingStructure parameters */ - FSMC_Bank4->PATT4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime | - (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime << 8) | - (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime << 16)| - (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime << 24); - - /* Set PIO4 register value according to FSMC_IOSpaceTimingStructure parameters */ - FSMC_Bank4->PIO4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime | - (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime << 8) | - (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime << 16)| - (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime << 24); -} - -/** - * @brief Fills each FSMC_NORSRAMInitStruct member with its default value. - * @param FSMC_NORSRAMInitStruct: pointer to a FSMC_NORSRAMInitTypeDef - * structure which will be initialized. - * @retval None - */ -void FSMC_NORSRAMStructInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct) -{ - /* Reset NOR/SRAM Init structure parameters values */ - FSMC_NORSRAMInitStruct->FSMC_Bank = FSMC_Bank1_NORSRAM1; - FSMC_NORSRAMInitStruct->FSMC_DataAddressMux = FSMC_DataAddressMux_Enable; - FSMC_NORSRAMInitStruct->FSMC_MemoryType = FSMC_MemoryType_SRAM; - FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; - FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; - FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; - FSMC_NORSRAMInitStruct->FSMC_WrapMode = FSMC_WrapMode_Disable; - FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; - FSMC_NORSRAMInitStruct->FSMC_WriteOperation = FSMC_WriteOperation_Enable; - FSMC_NORSRAMInitStruct->FSMC_WaitSignal = FSMC_WaitSignal_Enable; - FSMC_NORSRAMInitStruct->FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; - FSMC_NORSRAMInitStruct->FSMC_WriteBurst = FSMC_WriteBurst_Disable; - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime = 0xF; - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime = 0xF; - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime = 0xFF; - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration = 0xF; - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision = 0xF; - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency = 0xF; - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode = FSMC_AccessMode_A; - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime = 0xF; - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime = 0xF; - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime = 0xFF; - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_BusTurnAroundDuration = 0xF; - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision = 0xF; - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency = 0xF; - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode = FSMC_AccessMode_A; -} - -/** - * @brief Fills each FSMC_NANDInitStruct member with its default value. - * @param FSMC_NANDInitStruct: pointer to a FSMC_NANDInitTypeDef - * structure which will be initialized. - * @retval None - */ -void FSMC_NANDStructInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct) -{ - /* Reset NAND Init structure parameters values */ - FSMC_NANDInitStruct->FSMC_Bank = FSMC_Bank2_NAND; - FSMC_NANDInitStruct->FSMC_Waitfeature = FSMC_Waitfeature_Disable; - FSMC_NANDInitStruct->FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; - FSMC_NANDInitStruct->FSMC_ECC = FSMC_ECC_Disable; - FSMC_NANDInitStruct->FSMC_ECCPageSize = FSMC_ECCPageSize_256Bytes; - FSMC_NANDInitStruct->FSMC_TCLRSetupTime = 0x0; - FSMC_NANDInitStruct->FSMC_TARSetupTime = 0x0; - FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime = 0xFC; - FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; - FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; - FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; - FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime = 0xFC; - FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; - FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; - FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; -} - -/** - * @brief Fills each FSMC_PCCARDInitStruct member with its default value. - * @param FSMC_PCCARDInitStruct: pointer to a FSMC_PCCARDInitTypeDef - * structure which will be initialized. - * @retval None - */ -void FSMC_PCCARDStructInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct) -{ - /* Reset PCCARD Init structure parameters values */ - FSMC_PCCARDInitStruct->FSMC_Waitfeature = FSMC_Waitfeature_Disable; - FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime = 0x0; - FSMC_PCCARDInitStruct->FSMC_TARSetupTime = 0x0; - FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; -} - -/** - * @brief Enables or disables the specified NOR/SRAM Memory Bank. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank1_NORSRAM1: FSMC Bank1 NOR/SRAM1 - * @arg FSMC_Bank1_NORSRAM2: FSMC Bank1 NOR/SRAM2 - * @arg FSMC_Bank1_NORSRAM3: FSMC Bank1 NOR/SRAM3 - * @arg FSMC_Bank1_NORSRAM4: FSMC Bank1 NOR/SRAM4 - * @param NewState: new state of the FSMC_Bank. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState) -{ - assert_param(IS_FSMC_NORSRAM_BANK(FSMC_Bank)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected NOR/SRAM Bank by setting the PBKEN bit in the BCRx register */ - FSMC_Bank1->BTCR[FSMC_Bank] |= BCR_MBKEN_Set; - } - else - { - /* Disable the selected NOR/SRAM Bank by clearing the PBKEN bit in the BCRx register */ - FSMC_Bank1->BTCR[FSMC_Bank] &= BCR_MBKEN_Reset; - } -} - -/** - * @brief Enables or disables the specified NAND Memory Bank. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @param NewState: new state of the FSMC_Bank. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState) -{ - assert_param(IS_FSMC_NAND_BANK(FSMC_Bank)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected NAND Bank by setting the PBKEN bit in the PCRx register */ - if(FSMC_Bank == FSMC_Bank2_NAND) - { - FSMC_Bank2->PCR2 |= PCR_PBKEN_Set; - } - else - { - FSMC_Bank3->PCR3 |= PCR_PBKEN_Set; - } - } - else - { - /* Disable the selected NAND Bank by clearing the PBKEN bit in the PCRx register */ - if(FSMC_Bank == FSMC_Bank2_NAND) - { - FSMC_Bank2->PCR2 &= PCR_PBKEN_Reset; - } - else - { - FSMC_Bank3->PCR3 &= PCR_PBKEN_Reset; - } - } -} - -/** - * @brief Enables or disables the PCCARD Memory Bank. - * @param NewState: new state of the PCCARD Memory Bank. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FSMC_PCCARDCmd(FunctionalState NewState) -{ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the PCCARD Bank by setting the PBKEN bit in the PCR4 register */ - FSMC_Bank4->PCR4 |= PCR_PBKEN_Set; - } - else - { - /* Disable the PCCARD Bank by clearing the PBKEN bit in the PCR4 register */ - FSMC_Bank4->PCR4 &= PCR_PBKEN_Reset; - } -} - -/** - * @brief Enables or disables the FSMC NAND ECC feature. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @param NewState: new state of the FSMC NAND ECC feature. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FSMC_NANDECCCmd(uint32_t FSMC_Bank, FunctionalState NewState) -{ - assert_param(IS_FSMC_NAND_BANK(FSMC_Bank)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected NAND Bank ECC function by setting the ECCEN bit in the PCRx register */ - if(FSMC_Bank == FSMC_Bank2_NAND) - { - FSMC_Bank2->PCR2 |= PCR_ECCEN_Set; - } - else - { - FSMC_Bank3->PCR3 |= PCR_ECCEN_Set; - } - } - else - { - /* Disable the selected NAND Bank ECC function by clearing the ECCEN bit in the PCRx register */ - if(FSMC_Bank == FSMC_Bank2_NAND) - { - FSMC_Bank2->PCR2 &= PCR_ECCEN_Reset; - } - else - { - FSMC_Bank3->PCR3 &= PCR_ECCEN_Reset; - } - } -} - -/** - * @brief Returns the error correction code register value. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @retval The Error Correction Code (ECC) value. - */ -uint32_t FSMC_GetECC(uint32_t FSMC_Bank) -{ - uint32_t eccval = 0x00000000; - - if(FSMC_Bank == FSMC_Bank2_NAND) - { - /* Get the ECCR2 register value */ - eccval = FSMC_Bank2->ECCR2; - } - else - { - /* Get the ECCR3 register value */ - eccval = FSMC_Bank3->ECCR3; - } - /* Return the error correction code value */ - return(eccval); -} - -/** - * @brief Enables or disables the specified FSMC interrupts. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD - * @param FSMC_IT: specifies the FSMC interrupt sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt. - * @arg FSMC_IT_Level: Level edge detection interrupt. - * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt. - * @param NewState: new state of the specified FSMC interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FSMC_ITConfig(uint32_t FSMC_Bank, uint32_t FSMC_IT, FunctionalState NewState) -{ - assert_param(IS_FSMC_IT_BANK(FSMC_Bank)); - assert_param(IS_FSMC_IT(FSMC_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected FSMC_Bank2 interrupts */ - if(FSMC_Bank == FSMC_Bank2_NAND) - { - FSMC_Bank2->SR2 |= FSMC_IT; - } - /* Enable the selected FSMC_Bank3 interrupts */ - else if (FSMC_Bank == FSMC_Bank3_NAND) - { - FSMC_Bank3->SR3 |= FSMC_IT; - } - /* Enable the selected FSMC_Bank4 interrupts */ - else - { - FSMC_Bank4->SR4 |= FSMC_IT; - } - } - else - { - /* Disable the selected FSMC_Bank2 interrupts */ - if(FSMC_Bank == FSMC_Bank2_NAND) - { - - FSMC_Bank2->SR2 &= (uint32_t)~FSMC_IT; - } - /* Disable the selected FSMC_Bank3 interrupts */ - else if (FSMC_Bank == FSMC_Bank3_NAND) - { - FSMC_Bank3->SR3 &= (uint32_t)~FSMC_IT; - } - /* Disable the selected FSMC_Bank4 interrupts */ - else - { - FSMC_Bank4->SR4 &= (uint32_t)~FSMC_IT; - } - } -} - -/** - * @brief Checks whether the specified FSMC flag is set or not. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD - * @param FSMC_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg FSMC_FLAG_RisingEdge: Rising egde detection Flag. - * @arg FSMC_FLAG_Level: Level detection Flag. - * @arg FSMC_FLAG_FallingEdge: Falling egde detection Flag. - * @arg FSMC_FLAG_FEMPT: Fifo empty Flag. - * @retval The new state of FSMC_FLAG (SET or RESET). - */ -FlagStatus FSMC_GetFlagStatus(uint32_t FSMC_Bank, uint32_t FSMC_FLAG) -{ - FlagStatus bitstatus = RESET; - uint32_t tmpsr = 0x00000000; - - /* Check the parameters */ - assert_param(IS_FSMC_GETFLAG_BANK(FSMC_Bank)); - assert_param(IS_FSMC_GET_FLAG(FSMC_FLAG)); - - if(FSMC_Bank == FSMC_Bank2_NAND) - { - tmpsr = FSMC_Bank2->SR2; - } - else if(FSMC_Bank == FSMC_Bank3_NAND) - { - tmpsr = FSMC_Bank3->SR3; - } - /* FSMC_Bank4_PCCARD*/ - else - { - tmpsr = FSMC_Bank4->SR4; - } - - /* Get the flag status */ - if ((tmpsr & FSMC_FLAG) != (uint16_t)RESET ) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the flag status */ - return bitstatus; -} - -/** - * @brief Clears the FSMCs pending flags. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD - * @param FSMC_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg FSMC_FLAG_RisingEdge: Rising egde detection Flag. - * @arg FSMC_FLAG_Level: Level detection Flag. - * @arg FSMC_FLAG_FallingEdge: Falling egde detection Flag. - * @retval None - */ -void FSMC_ClearFlag(uint32_t FSMC_Bank, uint32_t FSMC_FLAG) -{ - /* Check the parameters */ - assert_param(IS_FSMC_GETFLAG_BANK(FSMC_Bank)); - assert_param(IS_FSMC_CLEAR_FLAG(FSMC_FLAG)) ; - - if(FSMC_Bank == FSMC_Bank2_NAND) - { - FSMC_Bank2->SR2 &= ~FSMC_FLAG; - } - else if(FSMC_Bank == FSMC_Bank3_NAND) - { - FSMC_Bank3->SR3 &= ~FSMC_FLAG; - } - /* FSMC_Bank4_PCCARD*/ - else - { - FSMC_Bank4->SR4 &= ~FSMC_FLAG; - } -} - -/** - * @brief Checks whether the specified FSMC interrupt has occurred or not. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD - * @param FSMC_IT: specifies the FSMC interrupt source to check. - * This parameter can be one of the following values: - * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt. - * @arg FSMC_IT_Level: Level edge detection interrupt. - * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt. - * @retval The new state of FSMC_IT (SET or RESET). - */ -ITStatus FSMC_GetITStatus(uint32_t FSMC_Bank, uint32_t FSMC_IT) -{ - ITStatus bitstatus = RESET; - uint32_t tmpsr = 0x0, itstatus = 0x0, itenable = 0x0; - - /* Check the parameters */ - assert_param(IS_FSMC_IT_BANK(FSMC_Bank)); - assert_param(IS_FSMC_GET_IT(FSMC_IT)); - - if(FSMC_Bank == FSMC_Bank2_NAND) - { - tmpsr = FSMC_Bank2->SR2; - } - else if(FSMC_Bank == FSMC_Bank3_NAND) - { - tmpsr = FSMC_Bank3->SR3; - } - /* FSMC_Bank4_PCCARD*/ - else - { - tmpsr = FSMC_Bank4->SR4; - } - - itstatus = tmpsr & FSMC_IT; - - itenable = tmpsr & (FSMC_IT >> 3); - if ((itstatus != (uint32_t)RESET) && (itenable != (uint32_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the FSMCs interrupt pending bits. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD - * @param FSMC_IT: specifies the interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt. - * @arg FSMC_IT_Level: Level edge detection interrupt. - * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt. - * @retval None - */ -void FSMC_ClearITPendingBit(uint32_t FSMC_Bank, uint32_t FSMC_IT) -{ - /* Check the parameters */ - assert_param(IS_FSMC_IT_BANK(FSMC_Bank)); - assert_param(IS_FSMC_IT(FSMC_IT)); - - if(FSMC_Bank == FSMC_Bank2_NAND) - { - FSMC_Bank2->SR2 &= ~(FSMC_IT >> 3); - } - else if(FSMC_Bank == FSMC_Bank3_NAND) - { - FSMC_Bank3->SR3 &= ~(FSMC_IT >> 3); - } - /* FSMC_Bank4_PCCARD*/ - else - { - FSMC_Bank4->SR4 &= ~(FSMC_IT >> 3); - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_gpio.c b/example/libs_stm/src/stm32f10x/stm32f10x_gpio.c deleted file mode 100644 index 0978e986e..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_gpio.c +++ /dev/null @@ -1,642 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_gpio.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the GPIO firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_gpio.h" -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup GPIO - * @brief GPIO driver modules - * @{ - */ - -/** @defgroup GPIO_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup GPIO_Private_Defines - * @{ - */ - -/* ------------ RCC registers bit address in the alias region ----------------*/ -#define AFIO_OFFSET (AFIO_BASE - PERIPH_BASE) - -/* --- EVENTCR Register -----*/ - -/* Alias word address of EVOE bit */ -#define EVCR_OFFSET (AFIO_OFFSET + 0x00) -#define EVOE_BitNumber ((uint8_t)0x07) -#define EVCR_EVOE_BB (PERIPH_BB_BASE + (EVCR_OFFSET * 32) + (EVOE_BitNumber * 4)) - - -/* --- MAPR Register ---*/ -/* Alias word address of MII_RMII_SEL bit */ -#define MAPR_OFFSET (AFIO_OFFSET + 0x04) -#define MII_RMII_SEL_BitNumber ((u8)0x17) -#define MAPR_MII_RMII_SEL_BB (PERIPH_BB_BASE + (MAPR_OFFSET * 32) + (MII_RMII_SEL_BitNumber * 4)) - - -#define EVCR_PORTPINCONFIG_MASK ((uint16_t)0xFF80) -#define LSB_MASK ((uint16_t)0xFFFF) -#define DBGAFR_POSITION_MASK ((uint32_t)0x000F0000) -#define DBGAFR_SWJCFG_MASK ((uint32_t)0xF0FFFFFF) -#define DBGAFR_LOCATION_MASK ((uint32_t)0x00200000) -#define DBGAFR_NUMBITS_MASK ((uint32_t)0x00100000) -/** - * @} - */ - -/** @defgroup GPIO_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup GPIO_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup GPIO_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup GPIO_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the GPIOx peripheral registers to their default reset values. - * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. - * @retval None - */ -void GPIO_DeInit(GPIO_TypeDef* GPIOx) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - - if (GPIOx == GPIOA) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE); - } - else if (GPIOx == GPIOB) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE); - } - else if (GPIOx == GPIOC) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, DISABLE); - } - else if (GPIOx == GPIOD) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOD, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOD, DISABLE); - } - else if (GPIOx == GPIOE) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOE, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOE, DISABLE); - } - else if (GPIOx == GPIOF) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOF, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOF, DISABLE); - } - else - { - if (GPIOx == GPIOG) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOG, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOG, DISABLE); - } - } -} - -/** - * @brief Deinitializes the Alternate Functions (remap, event control - * and EXTI configuration) registers to their default reset values. - * @param None - * @retval None - */ -void GPIO_AFIODeInit(void) -{ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, DISABLE); -} - -/** - * @brief Initializes the GPIOx peripheral according to the specified - * parameters in the GPIO_InitStruct. - * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. - * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that - * contains the configuration information for the specified GPIO peripheral. - * @retval None - */ -void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) -{ - uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00; - uint32_t tmpreg = 0x00, pinmask = 0x00; - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); - assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); - -/*---------------------------- GPIO Mode Configuration -----------------------*/ - currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F); - if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00) - { - /* Check the parameters */ - assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed)); - /* Output mode */ - currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed; - } -/*---------------------------- GPIO CRL Configuration ------------------------*/ - /* Configure the eight low port pins */ - if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00) - { - tmpreg = GPIOx->CRL; - for (pinpos = 0x00; pinpos < 0x08; pinpos++) - { - pos = ((uint32_t)0x01) << pinpos; - /* Get the port pins position */ - currentpin = (GPIO_InitStruct->GPIO_Pin) & pos; - if (currentpin == pos) - { - pos = pinpos << 2; - /* Clear the corresponding low control register bits */ - pinmask = ((uint32_t)0x0F) << pos; - tmpreg &= ~pinmask; - /* Write the mode configuration in the corresponding bits */ - tmpreg |= (currentmode << pos); - /* Reset the corresponding ODR bit */ - if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD) - { - GPIOx->BRR = (((uint32_t)0x01) << pinpos); - } - else - { - /* Set the corresponding ODR bit */ - if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU) - { - GPIOx->BSRR = (((uint32_t)0x01) << pinpos); - } - } - } - } - GPIOx->CRL = tmpreg; - } -/*---------------------------- GPIO CRH Configuration ------------------------*/ - /* Configure the eight high port pins */ - if (GPIO_InitStruct->GPIO_Pin > 0x00FF) - { - tmpreg = GPIOx->CRH; - for (pinpos = 0x00; pinpos < 0x08; pinpos++) - { - pos = (((uint32_t)0x01) << (pinpos + 0x08)); - /* Get the port pins position */ - currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos); - if (currentpin == pos) - { - pos = pinpos << 2; - /* Clear the corresponding high control register bits */ - pinmask = ((uint32_t)0x0F) << pos; - tmpreg &= ~pinmask; - /* Write the mode configuration in the corresponding bits */ - tmpreg |= (currentmode << pos); - /* Reset the corresponding ODR bit */ - if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD) - { - GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08)); - } - /* Set the corresponding ODR bit */ - if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU) - { - GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08)); - } - } - } - GPIOx->CRH = tmpreg; - } -} - -/** - * @brief Fills each GPIO_InitStruct member with its default value. - * @param GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct) -{ - /* Reset GPIO init structure parameters values */ - GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All; - GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN_FLOATING; -} - -/** - * @brief Reads the specified input port pin. - * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bit to read. - * This parameter can be GPIO_Pin_x where x can be (0..15). - * @retval The input port pin value. - */ -uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - uint8_t bitstatus = 0x00; - - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); - - if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET) - { - bitstatus = (uint8_t)Bit_SET; - } - else - { - bitstatus = (uint8_t)Bit_RESET; - } - return bitstatus; -} - -/** - * @brief Reads the specified GPIO input data port. - * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. - * @retval GPIO input data port value. - */ -uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - - return ((uint16_t)GPIOx->IDR); -} - -/** - * @brief Reads the specified output data port bit. - * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bit to read. - * This parameter can be GPIO_Pin_x where x can be (0..15). - * @retval The output port pin value. - */ -uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - uint8_t bitstatus = 0x00; - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); - - if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET) - { - bitstatus = (uint8_t)Bit_SET; - } - else - { - bitstatus = (uint8_t)Bit_RESET; - } - return bitstatus; -} - -/** - * @brief Reads the specified GPIO output data port. - * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. - * @retval GPIO output data port value. - */ -uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - - return ((uint16_t)GPIOx->ODR); -} - -/** - * @brief Sets the selected data port bits. - * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bits to be written. - * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). - * @retval None - */ -void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GPIO_PIN(GPIO_Pin)); - - GPIOx->BSRR = GPIO_Pin; -} - -/** - * @brief Clears the selected data port bits. - * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bits to be written. - * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). - * @retval None - */ -void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GPIO_PIN(GPIO_Pin)); - - GPIOx->BRR = GPIO_Pin; -} - -/** - * @brief Sets or clears the selected data port bit. - * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bit to be written. - * This parameter can be one of GPIO_Pin_x where x can be (0..15). - * @param BitVal: specifies the value to be written to the selected bit. - * This parameter can be one of the BitAction enum values: - * @arg Bit_RESET: to clear the port pin - * @arg Bit_SET: to set the port pin - * @retval None - */ -void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); - assert_param(IS_GPIO_BIT_ACTION(BitVal)); - - if (BitVal != Bit_RESET) - { - GPIOx->BSRR = GPIO_Pin; - } - else - { - GPIOx->BRR = GPIO_Pin; - } -} - -/** - * @brief Writes data to the specified GPIO data port. - * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. - * @param PortVal: specifies the value to be written to the port output data register. - * @retval None - */ -void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - - GPIOx->ODR = PortVal; -} - -/** - * @brief Locks GPIO Pins configuration registers. - * @param GPIOx: where x can be (A..G) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bit to be written. - * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). - * @retval None - */ -void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - uint32_t tmp = 0x00010000; - - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GPIO_PIN(GPIO_Pin)); - - tmp |= GPIO_Pin; - /* Set LCKK bit */ - GPIOx->LCKR = tmp; - /* Reset LCKK bit */ - GPIOx->LCKR = GPIO_Pin; - /* Set LCKK bit */ - GPIOx->LCKR = tmp; - /* Read LCKK bit*/ - tmp = GPIOx->LCKR; - /* Read LCKK bit*/ - tmp = GPIOx->LCKR; -} - -/** - * @brief Selects the GPIO pin used as Event output. - * @param GPIO_PortSource: selects the GPIO port to be used as source - * for Event output. - * This parameter can be GPIO_PortSourceGPIOx where x can be (A..E). - * @param GPIO_PinSource: specifies the pin for the Event output. - * This parameter can be GPIO_PinSourcex where x can be (0..15). - * @retval None - */ -void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource) -{ - uint32_t tmpreg = 0x00; - /* Check the parameters */ - assert_param(IS_GPIO_EVENTOUT_PORT_SOURCE(GPIO_PortSource)); - assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource)); - - tmpreg = AFIO->EVCR; - /* Clear the PORT[6:4] and PIN[3:0] bits */ - tmpreg &= EVCR_PORTPINCONFIG_MASK; - tmpreg |= (uint32_t)GPIO_PortSource << 0x04; - tmpreg |= GPIO_PinSource; - AFIO->EVCR = tmpreg; -} - -/** - * @brief Enables or disables the Event Output. - * @param NewState: new state of the Event output. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void GPIO_EventOutputCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) EVCR_EVOE_BB = (uint32_t)NewState; -} - -/** - * @brief Changes the mapping of the specified pin. - * @param GPIO_Remap: selects the pin to remap. - * This parameter can be one of the following values: - * @arg GPIO_Remap_SPI1 - * @arg GPIO_Remap_I2C1 - * @arg GPIO_Remap_USART1 - * @arg GPIO_Remap_USART2 - * @arg GPIO_PartialRemap_USART3 - * @arg GPIO_FullRemap_USART3 - * @arg GPIO_PartialRemap_TIM1 - * @arg GPIO_FullRemap_TIM1 - * @arg GPIO_PartialRemap1_TIM2 - * @arg GPIO_PartialRemap2_TIM2 - * @arg GPIO_FullRemap_TIM2 - * @arg GPIO_PartialRemap_TIM3 - * @arg GPIO_FullRemap_TIM3 - * @arg GPIO_Remap_TIM4 - * @arg GPIO_Remap1_CAN1 - * @arg GPIO_Remap2_CAN1 - * @arg GPIO_Remap_PD01 - * @arg GPIO_Remap_TIM5CH4_LSI - * @arg GPIO_Remap_ADC1_ETRGINJ - * @arg GPIO_Remap_ADC1_ETRGREG - * @arg GPIO_Remap_ADC2_ETRGINJ - * @arg GPIO_Remap_ADC2_ETRGREG - * @arg GPIO_Remap_ETH - * @arg GPIO_Remap_CAN2 - * @arg GPIO_Remap_SWJ_NoJTRST - * @arg GPIO_Remap_SWJ_JTAGDisable - * @arg GPIO_Remap_SWJ_Disable - * @arg GPIO_Remap_SPI3 - * @arg GPIO_Remap_TIM2ITR1_PTP_SOF - * @arg GPIO_Remap_PTP_PPS - * @arg GPIO_Remap_TIM15 - * @arg GPIO_Remap_TIM16 - * @arg GPIO_Remap_TIM17 - * @arg GPIO_Remap_CEC - * @arg GPIO_Remap_TIM1_DMA - * @arg GPIO_Remap_TIM9 - * @arg GPIO_Remap_TIM10 - * @arg GPIO_Remap_TIM11 - * @arg GPIO_Remap_TIM13 - * @arg GPIO_Remap_TIM14 - * @arg GPIO_Remap_FSMC_NADV - * @note If the GPIO_Remap_TIM2ITR1_PTP_SOF is enabled the TIM2 ITR1 is connected - * to Ethernet PTP output. When Reset TIM2 ITR1 is connected to USB OTG SOF output. - * @param NewState: new state of the port pin remapping. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState) -{ - uint32_t tmp = 0x00, tmp1 = 0x00, tmpreg = 0x00, tmpmask = 0x00; - - /* Check the parameters */ - assert_param(IS_GPIO_REMAP(GPIO_Remap)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if((GPIO_Remap & 0x80000000) == 0x80000000) - { - tmpreg = AFIO->MAPR2; - } - else - { - tmpreg = AFIO->MAPR; - } - - tmpmask = (GPIO_Remap & DBGAFR_POSITION_MASK) >> 0x10; - tmp = GPIO_Remap & LSB_MASK; - - if ((GPIO_Remap & (DBGAFR_LOCATION_MASK | DBGAFR_NUMBITS_MASK)) == (DBGAFR_LOCATION_MASK | DBGAFR_NUMBITS_MASK)) - { - tmpreg &= DBGAFR_SWJCFG_MASK; - AFIO->MAPR &= DBGAFR_SWJCFG_MASK; - } - else if ((GPIO_Remap & DBGAFR_NUMBITS_MASK) == DBGAFR_NUMBITS_MASK) - { - tmp1 = ((uint32_t)0x03) << tmpmask; - tmpreg &= ~tmp1; - tmpreg |= ~DBGAFR_SWJCFG_MASK; - } - else - { - tmpreg &= ~(tmp << ((GPIO_Remap >> 0x15)*0x10)); - tmpreg |= ~DBGAFR_SWJCFG_MASK; - } - - if (NewState != DISABLE) - { - tmpreg |= (tmp << ((GPIO_Remap >> 0x15)*0x10)); - } - - if((GPIO_Remap & 0x80000000) == 0x80000000) - { - AFIO->MAPR2 = tmpreg; - } - else - { - AFIO->MAPR = tmpreg; - } -} - -/** - * @brief Selects the GPIO pin used as EXTI Line. - * @param GPIO_PortSource: selects the GPIO port to be used as source for EXTI lines. - * This parameter can be GPIO_PortSourceGPIOx where x can be (A..G). - * @param GPIO_PinSource: specifies the EXTI line to be configured. - * This parameter can be GPIO_PinSourcex where x can be (0..15). - * @retval None - */ -void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource) -{ - uint32_t tmp = 0x00; - /* Check the parameters */ - assert_param(IS_GPIO_EXTI_PORT_SOURCE(GPIO_PortSource)); - assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource)); - - tmp = ((uint32_t)0x0F) << (0x04 * (GPIO_PinSource & (uint8_t)0x03)); - AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp; - AFIO->EXTICR[GPIO_PinSource >> 0x02] |= (((uint32_t)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (uint8_t)0x03))); -} - -/** - * @brief Selects the Ethernet media interface. - * @note This function applies only to STM32 Connectivity line devices. - * @param GPIO_ETH_MediaInterface: specifies the Media Interface mode. - * This parameter can be one of the following values: - * @arg GPIO_ETH_MediaInterface_MII: MII mode - * @arg GPIO_ETH_MediaInterface_RMII: RMII mode - * @retval None - */ -void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface) -{ - assert_param(IS_GPIO_ETH_MEDIA_INTERFACE(GPIO_ETH_MediaInterface)); - - /* Configure MII_RMII selection bit */ - *(__IO uint32_t *) MAPR_MII_RMII_SEL_BB = GPIO_ETH_MediaInterface; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_i2c.c b/example/libs_stm/src/stm32f10x/stm32f10x_i2c.c deleted file mode 100644 index 32545f5ed..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_i2c.c +++ /dev/null @@ -1,1285 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_i2c.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the I2C firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_i2c.h" -#include "stm32f10x_rcc.h" - - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup I2C - * @brief I2C driver modules - * @{ - */ - -/** @defgroup I2C_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup I2C_Private_Defines - * @{ - */ - -/* I2C SPE mask */ -#define CR1_PE_Set ((uint16_t)0x0001) -#define CR1_PE_Reset ((uint16_t)0xFFFE) - -/* I2C START mask */ -#define CR1_START_Set ((uint16_t)0x0100) -#define CR1_START_Reset ((uint16_t)0xFEFF) - -/* I2C STOP mask */ -#define CR1_STOP_Set ((uint16_t)0x0200) -#define CR1_STOP_Reset ((uint16_t)0xFDFF) - -/* I2C ACK mask */ -#define CR1_ACK_Set ((uint16_t)0x0400) -#define CR1_ACK_Reset ((uint16_t)0xFBFF) - -/* I2C ENGC mask */ -#define CR1_ENGC_Set ((uint16_t)0x0040) -#define CR1_ENGC_Reset ((uint16_t)0xFFBF) - -/* I2C SWRST mask */ -#define CR1_SWRST_Set ((uint16_t)0x8000) -#define CR1_SWRST_Reset ((uint16_t)0x7FFF) - -/* I2C PEC mask */ -#define CR1_PEC_Set ((uint16_t)0x1000) -#define CR1_PEC_Reset ((uint16_t)0xEFFF) - -/* I2C ENPEC mask */ -#define CR1_ENPEC_Set ((uint16_t)0x0020) -#define CR1_ENPEC_Reset ((uint16_t)0xFFDF) - -/* I2C ENARP mask */ -#define CR1_ENARP_Set ((uint16_t)0x0010) -#define CR1_ENARP_Reset ((uint16_t)0xFFEF) - -/* I2C NOSTRETCH mask */ -#define CR1_NOSTRETCH_Set ((uint16_t)0x0080) -#define CR1_NOSTRETCH_Reset ((uint16_t)0xFF7F) - -/* I2C registers Masks */ -#define CR1_CLEAR_Mask ((uint16_t)0xFBF5) - -/* I2C DMAEN mask */ -#define CR2_DMAEN_Set ((uint16_t)0x0800) -#define CR2_DMAEN_Reset ((uint16_t)0xF7FF) - -/* I2C LAST mask */ -#define CR2_LAST_Set ((uint16_t)0x1000) -#define CR2_LAST_Reset ((uint16_t)0xEFFF) - -/* I2C FREQ mask */ -#define CR2_FREQ_Reset ((uint16_t)0xFFC0) - -/* I2C ADD0 mask */ -#define OAR1_ADD0_Set ((uint16_t)0x0001) -#define OAR1_ADD0_Reset ((uint16_t)0xFFFE) - -/* I2C ENDUAL mask */ -#define OAR2_ENDUAL_Set ((uint16_t)0x0001) -#define OAR2_ENDUAL_Reset ((uint16_t)0xFFFE) - -/* I2C ADD2 mask */ -#define OAR2_ADD2_Reset ((uint16_t)0xFF01) - -/* I2C F/S mask */ -#define CCR_FS_Set ((uint16_t)0x8000) - -/* I2C CCR mask */ -#define CCR_CCR_Set ((uint16_t)0x0FFF) - -/* I2C FLAG mask */ -#define FLAG_Mask ((uint32_t)0x00FFFFFF) - -/* I2C Interrupt Enable mask */ -#define ITEN_Mask ((uint32_t)0x07000000) - -/** - * @} - */ - -/** @defgroup I2C_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup I2C_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup I2C_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup I2C_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the I2Cx peripheral registers to their default reset values. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @retval None - */ -void I2C_DeInit(I2C_TypeDef* I2Cx) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - - if (I2Cx == I2C1) - { - /* Enable I2C1 reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); - /* Release I2C1 from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); - } - else - { - /* Enable I2C2 reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE); - /* Release I2C2 from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE); - } -} - -/** - * @brief Initializes the I2Cx peripheral according to the specified - * parameters in the I2C_InitStruct. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_InitStruct: pointer to a I2C_InitTypeDef structure that - * contains the configuration information for the specified I2C peripheral. - * @retval None - */ -void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct) -{ - uint16_t tmpreg = 0, freqrange = 0; - uint16_t result = 0x04; - uint32_t pclk1 = 8000000; - RCC_ClocksTypeDef rcc_clocks; - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_CLOCK_SPEED(I2C_InitStruct->I2C_ClockSpeed)); - assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode)); - assert_param(IS_I2C_DUTY_CYCLE(I2C_InitStruct->I2C_DutyCycle)); - assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1)); - assert_param(IS_I2C_ACK_STATE(I2C_InitStruct->I2C_Ack)); - assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress)); - -/*---------------------------- I2Cx CR2 Configuration ------------------------*/ - /* Get the I2Cx CR2 value */ - tmpreg = I2Cx->CR2; - /* Clear frequency FREQ[5:0] bits */ - tmpreg &= CR2_FREQ_Reset; - /* Get pclk1 frequency value */ - RCC_GetClocksFreq(&rcc_clocks); - pclk1 = rcc_clocks.PCLK1_Frequency; - /* Set frequency bits depending on pclk1 value */ - freqrange = (uint16_t)(pclk1 / 1000000); - tmpreg |= freqrange; - /* Write to I2Cx CR2 */ - I2Cx->CR2 = tmpreg; - -/*---------------------------- I2Cx CCR Configuration ------------------------*/ - /* Disable the selected I2C peripheral to configure TRISE */ - I2Cx->CR1 &= CR1_PE_Reset; - /* Reset tmpreg value */ - /* Clear F/S, DUTY and CCR[11:0] bits */ - tmpreg = 0; - - /* Configure speed in standard mode */ - if (I2C_InitStruct->I2C_ClockSpeed <= 100000) - { - /* Standard mode speed calculate */ - result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed << 1)); - /* Test if CCR value is under 0x4*/ - if (result < 0x04) - { - /* Set minimum allowed value */ - result = 0x04; - } - /* Set speed value for standard mode */ - tmpreg |= result; - /* Set Maximum Rise Time for standard mode */ - I2Cx->TRISE = freqrange + 1; - } - /* Configure speed in fast mode */ - else /*(I2C_InitStruct->I2C_ClockSpeed <= 400000)*/ - { - if (I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_2) - { - /* Fast mode speed calculate: Tlow/Thigh = 2 */ - result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 3)); - } - else /*I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_16_9*/ - { - /* Fast mode speed calculate: Tlow/Thigh = 16/9 */ - result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 25)); - /* Set DUTY bit */ - result |= I2C_DutyCycle_16_9; - } - - /* Test if CCR value is under 0x1*/ - if ((result & CCR_CCR_Set) == 0) - { - /* Set minimum allowed value */ - result |= (uint16_t)0x0001; - } - /* Set speed value and set F/S bit for fast mode */ - tmpreg |= (uint16_t)(result | CCR_FS_Set); - /* Set Maximum Rise Time for fast mode */ - I2Cx->TRISE = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1); - } - - /* Write to I2Cx CCR */ - I2Cx->CCR = tmpreg; - /* Enable the selected I2C peripheral */ - I2Cx->CR1 |= CR1_PE_Set; - -/*---------------------------- I2Cx CR1 Configuration ------------------------*/ - /* Get the I2Cx CR1 value */ - tmpreg = I2Cx->CR1; - /* Clear ACK, SMBTYPE and SMBUS bits */ - tmpreg &= CR1_CLEAR_Mask; - /* Configure I2Cx: mode and acknowledgement */ - /* Set SMBTYPE and SMBUS bits according to I2C_Mode value */ - /* Set ACK bit according to I2C_Ack value */ - tmpreg |= (uint16_t)((uint32_t)I2C_InitStruct->I2C_Mode | I2C_InitStruct->I2C_Ack); - /* Write to I2Cx CR1 */ - I2Cx->CR1 = tmpreg; - -/*---------------------------- I2Cx OAR1 Configuration -----------------------*/ - /* Set I2Cx Own Address1 and acknowledged address */ - I2Cx->OAR1 = (I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1); -} - -/** - * @brief Fills each I2C_InitStruct member with its default value. - * @param I2C_InitStruct: pointer to an I2C_InitTypeDef structure which will be initialized. - * @retval None - */ -void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct) -{ -/*---------------- Reset I2C init structure parameters values ----------------*/ - /* initialize the I2C_ClockSpeed member */ - I2C_InitStruct->I2C_ClockSpeed = 5000; - /* Initialize the I2C_Mode member */ - I2C_InitStruct->I2C_Mode = I2C_Mode_I2C; - /* Initialize the I2C_DutyCycle member */ - I2C_InitStruct->I2C_DutyCycle = I2C_DutyCycle_2; - /* Initialize the I2C_OwnAddress1 member */ - I2C_InitStruct->I2C_OwnAddress1 = 0; - /* Initialize the I2C_Ack member */ - I2C_InitStruct->I2C_Ack = I2C_Ack_Disable; - /* Initialize the I2C_AcknowledgedAddress member */ - I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; -} - -/** - * @brief Enables or disables the specified I2C peripheral. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2Cx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C peripheral */ - I2Cx->CR1 |= CR1_PE_Set; - } - else - { - /* Disable the selected I2C peripheral */ - I2Cx->CR1 &= CR1_PE_Reset; - } -} - -/** - * @brief Enables or disables the specified I2C DMA requests. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C DMA transfer. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C DMA requests */ - I2Cx->CR2 |= CR2_DMAEN_Set; - } - else - { - /* Disable the selected I2C DMA requests */ - I2Cx->CR2 &= CR2_DMAEN_Reset; - } -} - -/** - * @brief Specifies if the next DMA transfer will be the last one. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C DMA last transfer. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Next DMA transfer is the last transfer */ - I2Cx->CR2 |= CR2_LAST_Set; - } - else - { - /* Next DMA transfer is not the last transfer */ - I2Cx->CR2 &= CR2_LAST_Reset; - } -} - -/** - * @brief Generates I2Cx communication START condition. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C START condition generation. - * This parameter can be: ENABLE or DISABLE. - * @retval None. - */ -void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Generate a START condition */ - I2Cx->CR1 |= CR1_START_Set; - } - else - { - /* Disable the START condition generation */ - I2Cx->CR1 &= CR1_START_Reset; - } -} - -/** - * @brief Generates I2Cx communication STOP condition. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C STOP condition generation. - * This parameter can be: ENABLE or DISABLE. - * @retval None. - */ -void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Generate a STOP condition */ - I2Cx->CR1 |= CR1_STOP_Set; - } - else - { - /* Disable the STOP condition generation */ - I2Cx->CR1 &= CR1_STOP_Reset; - } -} - -/** - * @brief Enables or disables the specified I2C acknowledge feature. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C Acknowledgement. - * This parameter can be: ENABLE or DISABLE. - * @retval None. - */ -void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the acknowledgement */ - I2Cx->CR1 |= CR1_ACK_Set; - } - else - { - /* Disable the acknowledgement */ - I2Cx->CR1 &= CR1_ACK_Reset; - } -} - -/** - * @brief Configures the specified I2C own address2. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param Address: specifies the 7bit I2C own address2. - * @retval None. - */ -void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address) -{ - uint16_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - - /* Get the old register value */ - tmpreg = I2Cx->OAR2; - - /* Reset I2Cx Own address2 bit [7:1] */ - tmpreg &= OAR2_ADD2_Reset; - - /* Set I2Cx Own address2 */ - tmpreg |= (uint16_t)((uint16_t)Address & (uint16_t)0x00FE); - - /* Store the new register value */ - I2Cx->OAR2 = tmpreg; -} - -/** - * @brief Enables or disables the specified I2C dual addressing mode. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C dual addressing mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable dual addressing mode */ - I2Cx->OAR2 |= OAR2_ENDUAL_Set; - } - else - { - /* Disable dual addressing mode */ - I2Cx->OAR2 &= OAR2_ENDUAL_Reset; - } -} - -/** - * @brief Enables or disables the specified I2C general call feature. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C General call. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable generall call */ - I2Cx->CR1 |= CR1_ENGC_Set; - } - else - { - /* Disable generall call */ - I2Cx->CR1 &= CR1_ENGC_Reset; - } -} - -/** - * @brief Enables or disables the specified I2C interrupts. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_IT: specifies the I2C interrupts sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg I2C_IT_BUF: Buffer interrupt mask - * @arg I2C_IT_EVT: Event interrupt mask - * @arg I2C_IT_ERR: Error interrupt mask - * @param NewState: new state of the specified I2C interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_I2C_CONFIG_IT(I2C_IT)); - - if (NewState != DISABLE) - { - /* Enable the selected I2C interrupts */ - I2Cx->CR2 |= I2C_IT; - } - else - { - /* Disable the selected I2C interrupts */ - I2Cx->CR2 &= (uint16_t)~I2C_IT; - } -} - -/** - * @brief Sends a data byte through the I2Cx peripheral. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param Data: Byte to be transmitted.. - * @retval None - */ -void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - /* Write in the DR register the data to be sent */ - I2Cx->DR = Data; -} - -/** - * @brief Returns the most recent received data by the I2Cx peripheral. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @retval The value of the received data. - */ -uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - /* Return the data in the DR register */ - return (uint8_t)I2Cx->DR; -} - -/** - * @brief Transmits the address byte to select the slave device. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param Address: specifies the slave address which will be transmitted - * @param I2C_Direction: specifies whether the I2C device will be a - * Transmitter or a Receiver. This parameter can be one of the following values - * @arg I2C_Direction_Transmitter: Transmitter mode - * @arg I2C_Direction_Receiver: Receiver mode - * @retval None. - */ -void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_DIRECTION(I2C_Direction)); - /* Test on the direction to set/reset the read/write bit */ - if (I2C_Direction != I2C_Direction_Transmitter) - { - /* Set the address bit0 for read */ - Address |= OAR1_ADD0_Set; - } - else - { - /* Reset the address bit0 for write */ - Address &= OAR1_ADD0_Reset; - } - /* Send the address */ - I2Cx->DR = Address; -} - -/** - * @brief Reads the specified I2C register and returns its value. - * @param I2C_Register: specifies the register to read. - * This parameter can be one of the following values: - * @arg I2C_Register_CR1: CR1 register. - * @arg I2C_Register_CR2: CR2 register. - * @arg I2C_Register_OAR1: OAR1 register. - * @arg I2C_Register_OAR2: OAR2 register. - * @arg I2C_Register_DR: DR register. - * @arg I2C_Register_SR1: SR1 register. - * @arg I2C_Register_SR2: SR2 register. - * @arg I2C_Register_CCR: CCR register. - * @arg I2C_Register_TRISE: TRISE register. - * @retval The value of the read register. - */ -uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_REGISTER(I2C_Register)); - - tmp = (uint32_t) I2Cx; - tmp += I2C_Register; - - /* Return the selected register value */ - return (*(__IO uint16_t *) tmp); -} - -/** - * @brief Enables or disables the specified I2C software reset. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C software reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Peripheral under reset */ - I2Cx->CR1 |= CR1_SWRST_Set; - } - else - { - /* Peripheral not under reset */ - I2Cx->CR1 &= CR1_SWRST_Reset; - } -} - -/** - * @brief Drives the SMBusAlert pin high or low for the specified I2C. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_SMBusAlert: specifies SMBAlert pin level. - * This parameter can be one of the following values: - * @arg I2C_SMBusAlert_Low: SMBAlert pin driven low - * @arg I2C_SMBusAlert_High: SMBAlert pin driven high - * @retval None - */ -void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_SMBUS_ALERT(I2C_SMBusAlert)); - if (I2C_SMBusAlert == I2C_SMBusAlert_Low) - { - /* Drive the SMBusAlert pin Low */ - I2Cx->CR1 |= I2C_SMBusAlert_Low; - } - else - { - /* Drive the SMBusAlert pin High */ - I2Cx->CR1 &= I2C_SMBusAlert_High; - } -} - -/** - * @brief Enables or disables the specified I2C PEC transfer. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C PEC transmission. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C PEC transmission */ - I2Cx->CR1 |= CR1_PEC_Set; - } - else - { - /* Disable the selected I2C PEC transmission */ - I2Cx->CR1 &= CR1_PEC_Reset; - } -} - -/** - * @brief Selects the specified I2C PEC position. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_PECPosition: specifies the PEC position. - * This parameter can be one of the following values: - * @arg I2C_PECPosition_Next: indicates that the next byte is PEC - * @arg I2C_PECPosition_Current: indicates that current byte is PEC - * @retval None - */ -void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_PEC_POSITION(I2C_PECPosition)); - if (I2C_PECPosition == I2C_PECPosition_Next) - { - /* Next byte in shift register is PEC */ - I2Cx->CR1 |= I2C_PECPosition_Next; - } - else - { - /* Current byte in shift register is PEC */ - I2Cx->CR1 &= I2C_PECPosition_Current; - } -} - -/** - * @brief Enables or disables the PEC value calculation of the transfered bytes. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2Cx PEC value calculation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C PEC calculation */ - I2Cx->CR1 |= CR1_ENPEC_Set; - } - else - { - /* Disable the selected I2C PEC calculation */ - I2Cx->CR1 &= CR1_ENPEC_Reset; - } -} - -/** - * @brief Returns the PEC value for the specified I2C. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @retval The PEC value. - */ -uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - /* Return the selected I2C PEC value */ - return ((I2Cx->SR2) >> 8); -} - -/** - * @brief Enables or disables the specified I2C ARP. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2Cx ARP. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C ARP */ - I2Cx->CR1 |= CR1_ENARP_Set; - } - else - { - /* Disable the selected I2C ARP */ - I2Cx->CR1 &= CR1_ENARP_Reset; - } -} - -/** - * @brief Enables or disables the specified I2C Clock stretching. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2Cx Clock stretching. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState == DISABLE) - { - /* Enable the selected I2C Clock stretching */ - I2Cx->CR1 |= CR1_NOSTRETCH_Set; - } - else - { - /* Disable the selected I2C Clock stretching */ - I2Cx->CR1 &= CR1_NOSTRETCH_Reset; - } -} - -/** - * @brief Selects the specified I2C fast mode duty cycle. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_DutyCycle: specifies the fast mode duty cycle. - * This parameter can be one of the following values: - * @arg I2C_DutyCycle_2: I2C fast mode Tlow/Thigh = 2 - * @arg I2C_DutyCycle_16_9: I2C fast mode Tlow/Thigh = 16/9 - * @retval None - */ -void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_DUTY_CYCLE(I2C_DutyCycle)); - if (I2C_DutyCycle != I2C_DutyCycle_16_9) - { - /* I2C fast mode Tlow/Thigh=2 */ - I2Cx->CCR &= I2C_DutyCycle_2; - } - else - { - /* I2C fast mode Tlow/Thigh=16/9 */ - I2Cx->CCR |= I2C_DutyCycle_16_9; - } -} - - - -/** - * @brief - **************************************************************************************** - * - * I2C State Monitoring Functions - * - **************************************************************************************** - * This I2C driver provides three different ways for I2C state monitoring - * depending on the application requirements and constraints: - * - * - * 1) Basic state monitoring: - * Using I2C_CheckEvent() function: - * It compares the status registers (SR1 and SR2) content to a given event - * (can be the combination of one or more flags). - * It returns SUCCESS if the current status includes the given flags - * and returns ERROR if one or more flags are missing in the current status. - * - When to use: - * - This function is suitable for most applciations as well as for startup - * activity since the events are fully described in the product reference manual - * (RM0008). - * - It is also suitable for users who need to define their own events. - * - Limitations: - * - If an error occurs (ie. error flags are set besides to the monitored flags), - * the I2C_CheckEvent() function may return SUCCESS despite the communication - * hold or corrupted real state. - * In this case, it is advised to use error interrupts to monitor the error - * events and handle them in the interrupt IRQ handler. - * - * @note - * For error management, it is advised to use the following functions: - * - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR). - * - I2Cx_ER_IRQHandler() which is called when the error interurpt occurs. - * Where x is the peripheral instance (I2C1, I2C2 ...) - * - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into I2Cx_ER_IRQHandler() - * in order to determine which error occured. - * - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd() - * and/or I2C_GenerateStop() in order to clear the error flag and source, - * and return to correct communication status. - * - * - * 2) Advanced state monitoring: - * Using the function I2C_GetLastEvent() which returns the image of both status - * registers in a single word (uint32_t) (Status Register 2 value is shifted left - * by 16 bits and concatenated to Status Register 1). - * - When to use: - * - This function is suitable for the same applications above but it allows to - * overcome the mentionned limitation of I2C_GetFlagStatus() function. - * The returned value could be compared to events already defined in the - * library (stm32f10x_i2c.h) or to custom values defiend by user. - * - This function is suitable when multiple flags are monitored at the same time. - * - At the opposite of I2C_CheckEvent() function, this function allows user to - * choose when an event is accepted (when all events flags are set and no - * other flags are set or just when the needed flags are set like - * I2C_CheckEvent() function). - * - Limitations: - * - User may need to define his own events. - * - Same remark concerning the error management is applicable for this - * function if user decides to check only regular communication flags (and - * ignores error flags). - * - * - * 3) Flag-based state monitoring: - * Using the function I2C_GetFlagStatus() which simply returns the status of - * one single flag (ie. I2C_FLAG_RXNE ...). - * - When to use: - * - This function could be used for specific applications or in debug phase. - * - It is suitable when only one flag checking is needed (most I2C events - * are monitored through multiple flags). - * - Limitations: - * - When calling this function, the Status register is accessed. Some flags are - * cleared when the status register is accessed. So checking the status - * of one Flag, may clear other ones. - * - Function may need to be called twice or more in order to monitor one - * single event. - * - * For detailed description of Events, please refer to section I2C_Events in - * stm32f10x_i2c.h file. - * - */ - -/** - * - * 1) Basic state monitoring - ******************************************************************************* - */ - -/** - * @brief Checks whether the last I2Cx Event is equal to the one passed - * as parameter. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_EVENT: specifies the event to be checked. - * This parameter can be one of the following values: - * @arg I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED : EV1 - * @arg I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED : EV1 - * @arg I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED : EV1 - * @arg I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED : EV1 - * @arg I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED : EV1 - * @arg I2C_EVENT_SLAVE_BYTE_RECEIVED : EV2 - * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF) : EV2 - * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL) : EV2 - * @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED : EV3 - * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF) : EV3 - * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL) : EV3 - * @arg I2C_EVENT_SLAVE_ACK_FAILURE : EV3_2 - * @arg I2C_EVENT_SLAVE_STOP_DETECTED : EV4 - * @arg I2C_EVENT_MASTER_MODE_SELECT : EV5 - * @arg I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED : EV6 - * @arg I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED : EV6 - * @arg I2C_EVENT_MASTER_BYTE_RECEIVED : EV7 - * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTING : EV8 - * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTED : EV8_2 - * @arg I2C_EVENT_MASTER_MODE_ADDRESS10 : EV9 - * - * @note: For detailed description of Events, please refer to section - * I2C_Events in stm32f10x_i2c.h file. - * - * @retval An ErrorStatus enumuration value: - * - SUCCESS: Last event is equal to the I2C_EVENT - * - ERROR: Last event is different from the I2C_EVENT - */ -ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) -{ - uint32_t lastevent = 0; - uint32_t flag1 = 0, flag2 = 0; - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_EVENT(I2C_EVENT)); - - /* Read the I2Cx status register */ - flag1 = I2Cx->SR1; - flag2 = I2Cx->SR2; - flag2 = flag2 << 16; - - /* Get the last event value from I2C status register */ - lastevent = (flag1 | flag2) & FLAG_Mask; - - /* Check whether the last event contains the I2C_EVENT */ - if ((lastevent & I2C_EVENT) == I2C_EVENT) - { - /* SUCCESS: last event is equal to I2C_EVENT */ - status = SUCCESS; - } - else - { - /* ERROR: last event is different from I2C_EVENT */ - status = ERROR; - } - /* Return status */ - return status; -} - -/** - * - * 2) Advanced state monitoring - ******************************************************************************* - */ - -/** - * @brief Returns the last I2Cx Event. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * - * @note: For detailed description of Events, please refer to section - * I2C_Events in stm32f10x_i2c.h file. - * - * @retval The last event - */ -uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx) -{ - uint32_t lastevent = 0; - uint32_t flag1 = 0, flag2 = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - - /* Read the I2Cx status register */ - flag1 = I2Cx->SR1; - flag2 = I2Cx->SR2; - flag2 = flag2 << 16; - - /* Get the last event value from I2C status register */ - lastevent = (flag1 | flag2) & FLAG_Mask; - - /* Return status */ - return lastevent; -} - -/** - * - * 3) Flag-based state monitoring - ******************************************************************************* - */ - -/** - * @brief Checks whether the specified I2C flag is set or not. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg I2C_FLAG_DUALF: Dual flag (Slave mode) - * @arg I2C_FLAG_SMBHOST: SMBus host header (Slave mode) - * @arg I2C_FLAG_SMBDEFAULT: SMBus default header (Slave mode) - * @arg I2C_FLAG_GENCALL: General call header flag (Slave mode) - * @arg I2C_FLAG_TRA: Transmitter/Receiver flag - * @arg I2C_FLAG_BUSY: Bus busy flag - * @arg I2C_FLAG_MSL: Master/Slave flag - * @arg I2C_FLAG_SMBALERT: SMBus Alert flag - * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag - * @arg I2C_FLAG_PECERR: PEC error in reception flag - * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) - * @arg I2C_FLAG_AF: Acknowledge failure flag - * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) - * @arg I2C_FLAG_BERR: Bus error flag - * @arg I2C_FLAG_TXE: Data register empty flag (Transmitter) - * @arg I2C_FLAG_RXNE: Data register not empty (Receiver) flag - * @arg I2C_FLAG_STOPF: Stop detection flag (Slave mode) - * @arg I2C_FLAG_ADD10: 10-bit header sent flag (Master mode) - * @arg I2C_FLAG_BTF: Byte transfer finished flag - * @arg I2C_FLAG_ADDR: Address sent flag (Master mode) ADSL - * Address matched flag (Slave mode)ENDAD - * @arg I2C_FLAG_SB: Start bit flag (Master mode) - * @retval The new state of I2C_FLAG (SET or RESET). - */ -FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) -{ - FlagStatus bitstatus = RESET; - __IO uint32_t i2creg = 0, i2cxbase = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_GET_FLAG(I2C_FLAG)); - - /* Get the I2Cx peripheral base address */ - i2cxbase = (uint32_t)I2Cx; - - /* Read flag register index */ - i2creg = I2C_FLAG >> 28; - - /* Get bit[23:0] of the flag */ - I2C_FLAG &= FLAG_Mask; - - if(i2creg != 0) - { - /* Get the I2Cx SR1 register address */ - i2cxbase += 0x14; - } - else - { - /* Flag in I2Cx SR2 Register */ - I2C_FLAG = (uint32_t)(I2C_FLAG >> 16); - /* Get the I2Cx SR2 register address */ - i2cxbase += 0x18; - } - - if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET) - { - /* I2C_FLAG is set */ - bitstatus = SET; - } - else - { - /* I2C_FLAG is reset */ - bitstatus = RESET; - } - - /* Return the I2C_FLAG status */ - return bitstatus; -} - - - -/** - * @brief Clears the I2Cx's pending flags. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg I2C_FLAG_SMBALERT: SMBus Alert flag - * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag - * @arg I2C_FLAG_PECERR: PEC error in reception flag - * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) - * @arg I2C_FLAG_AF: Acknowledge failure flag - * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) - * @arg I2C_FLAG_BERR: Bus error flag - * - * @note - * - STOPF (STOP detection) is cleared by software sequence: a read operation - * to I2C_SR1 register (I2C_GetFlagStatus()) followed by a write operation - * to I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral). - * - ADD10 (10-bit header sent) is cleared by software sequence: a read - * operation to I2C_SR1 (I2C_GetFlagStatus()) followed by writing the - * second byte of the address in DR register. - * - BTF (Byte Transfer Finished) is cleared by software sequence: a read - * operation to I2C_SR1 register (I2C_GetFlagStatus()) followed by a - * read/write to I2C_DR register (I2C_SendData()). - * - ADDR (Address sent) is cleared by software sequence: a read operation to - * I2C_SR1 register (I2C_GetFlagStatus()) followed by a read operation to - * I2C_SR2 register ((void)(I2Cx->SR2)). - * - SB (Start Bit) is cleared software sequence: a read operation to I2C_SR1 - * register (I2C_GetFlagStatus()) followed by a write operation to I2C_DR - * register (I2C_SendData()). - * @retval None - */ -void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) -{ - uint32_t flagpos = 0; - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_CLEAR_FLAG(I2C_FLAG)); - /* Get the I2C flag position */ - flagpos = I2C_FLAG & FLAG_Mask; - /* Clear the selected I2C flag */ - I2Cx->SR1 = (uint16_t)~flagpos; -} - -/** - * @brief Checks whether the specified I2C interrupt has occurred or not. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_IT: specifies the interrupt source to check. - * This parameter can be one of the following values: - * @arg I2C_IT_SMBALERT: SMBus Alert flag - * @arg I2C_IT_TIMEOUT: Timeout or Tlow error flag - * @arg I2C_IT_PECERR: PEC error in reception flag - * @arg I2C_IT_OVR: Overrun/Underrun flag (Slave mode) - * @arg I2C_IT_AF: Acknowledge failure flag - * @arg I2C_IT_ARLO: Arbitration lost flag (Master mode) - * @arg I2C_IT_BERR: Bus error flag - * @arg I2C_IT_TXE: Data register empty flag (Transmitter) - * @arg I2C_IT_RXNE: Data register not empty (Receiver) flag - * @arg I2C_IT_STOPF: Stop detection flag (Slave mode) - * @arg I2C_IT_ADD10: 10-bit header sent flag (Master mode) - * @arg I2C_IT_BTF: Byte transfer finished flag - * @arg I2C_IT_ADDR: Address sent flag (Master mode) ADSL - * Address matched flag (Slave mode)ENDAD - * @arg I2C_IT_SB: Start bit flag (Master mode) - * @retval The new state of I2C_IT (SET or RESET). - */ -ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT) -{ - ITStatus bitstatus = RESET; - uint32_t enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_GET_IT(I2C_IT)); - - /* Check if the interrupt source is enabled or not */ - enablestatus = (uint32_t)(((I2C_IT & ITEN_Mask) >> 16) & (I2Cx->CR2)) ; - - /* Get bit[23:0] of the flag */ - I2C_IT &= FLAG_Mask; - - /* Check the status of the specified I2C flag */ - if (((I2Cx->SR1 & I2C_IT) != (uint32_t)RESET) && enablestatus) - { - /* I2C_IT is set */ - bitstatus = SET; - } - else - { - /* I2C_IT is reset */ - bitstatus = RESET; - } - /* Return the I2C_IT status */ - return bitstatus; -} - -/** - * @brief Clears the I2Cxs interrupt pending bits. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_IT: specifies the interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg I2C_IT_SMBALERT: SMBus Alert interrupt - * @arg I2C_IT_TIMEOUT: Timeout or Tlow error interrupt - * @arg I2C_IT_PECERR: PEC error in reception interrupt - * @arg I2C_IT_OVR: Overrun/Underrun interrupt (Slave mode) - * @arg I2C_IT_AF: Acknowledge failure interrupt - * @arg I2C_IT_ARLO: Arbitration lost interrupt (Master mode) - * @arg I2C_IT_BERR: Bus error interrupt - * - * @note - * - STOPF (STOP detection) is cleared by software sequence: a read operation - * to I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to - * I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral). - * - ADD10 (10-bit header sent) is cleared by software sequence: a read - * operation to I2C_SR1 (I2C_GetITStatus()) followed by writing the second - * byte of the address in I2C_DR register. - * - BTF (Byte Transfer Finished) is cleared by software sequence: a read - * operation to I2C_SR1 register (I2C_GetITStatus()) followed by a - * read/write to I2C_DR register (I2C_SendData()). - * - ADDR (Address sent) is cleared by software sequence: a read operation to - * I2C_SR1 register (I2C_GetITStatus()) followed by a read operation to - * I2C_SR2 register ((void)(I2Cx->SR2)). - * - SB (Start Bit) is cleared by software sequence: a read operation to - * I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to - * I2C_DR register (I2C_SendData()). - * @retval None - */ -void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT) -{ - uint32_t flagpos = 0; - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_CLEAR_IT(I2C_IT)); - /* Get the I2C flag position */ - flagpos = I2C_IT & FLAG_Mask; - /* Clear the selected I2C flag */ - I2Cx->SR1 = (uint16_t)~flagpos; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_iwdg.c b/example/libs_stm/src/stm32f10x/stm32f10x_iwdg.c deleted file mode 100644 index 58ab061c3..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_iwdg.c +++ /dev/null @@ -1,189 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_iwdg.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the IWDG firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_iwdg.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup IWDG - * @brief IWDG driver modules - * @{ - */ - -/** @defgroup IWDG_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup IWDG_Private_Defines - * @{ - */ - -/* ---------------------- IWDG registers bit mask ----------------------------*/ - -/* KR register bit mask */ -#define KR_KEY_Reload ((uint16_t)0xAAAA) -#define KR_KEY_Enable ((uint16_t)0xCCCC) - -/** - * @} - */ - -/** @defgroup IWDG_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup IWDG_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup IWDG_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup IWDG_Private_Functions - * @{ - */ - -/** - * @brief Enables or disables write access to IWDG_PR and IWDG_RLR registers. - * @param IWDG_WriteAccess: new state of write access to IWDG_PR and IWDG_RLR registers. - * This parameter can be one of the following values: - * @arg IWDG_WriteAccess_Enable: Enable write access to IWDG_PR and IWDG_RLR registers - * @arg IWDG_WriteAccess_Disable: Disable write access to IWDG_PR and IWDG_RLR registers - * @retval None - */ -void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess) -{ - /* Check the parameters */ - assert_param(IS_IWDG_WRITE_ACCESS(IWDG_WriteAccess)); - IWDG->KR = IWDG_WriteAccess; -} - -/** - * @brief Sets IWDG Prescaler value. - * @param IWDG_Prescaler: specifies the IWDG Prescaler value. - * This parameter can be one of the following values: - * @arg IWDG_Prescaler_4: IWDG prescaler set to 4 - * @arg IWDG_Prescaler_8: IWDG prescaler set to 8 - * @arg IWDG_Prescaler_16: IWDG prescaler set to 16 - * @arg IWDG_Prescaler_32: IWDG prescaler set to 32 - * @arg IWDG_Prescaler_64: IWDG prescaler set to 64 - * @arg IWDG_Prescaler_128: IWDG prescaler set to 128 - * @arg IWDG_Prescaler_256: IWDG prescaler set to 256 - * @retval None - */ -void IWDG_SetPrescaler(uint8_t IWDG_Prescaler) -{ - /* Check the parameters */ - assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler)); - IWDG->PR = IWDG_Prescaler; -} - -/** - * @brief Sets IWDG Reload value. - * @param Reload: specifies the IWDG Reload value. - * This parameter must be a number between 0 and 0x0FFF. - * @retval None - */ -void IWDG_SetReload(uint16_t Reload) -{ - /* Check the parameters */ - assert_param(IS_IWDG_RELOAD(Reload)); - IWDG->RLR = Reload; -} - -/** - * @brief Reloads IWDG counter with value defined in the reload register - * (write access to IWDG_PR and IWDG_RLR registers disabled). - * @param None - * @retval None - */ -void IWDG_ReloadCounter(void) -{ - IWDG->KR = KR_KEY_Reload; -} - -/** - * @brief Enables IWDG (write access to IWDG_PR and IWDG_RLR registers disabled). - * @param None - * @retval None - */ -void IWDG_Enable(void) -{ - IWDG->KR = KR_KEY_Enable; -} - -/** - * @brief Checks whether the specified IWDG flag is set or not. - * @param IWDG_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg IWDG_FLAG_PVU: Prescaler Value Update on going - * @arg IWDG_FLAG_RVU: Reload Value Update on going - * @retval The new state of IWDG_FLAG (SET or RESET). - */ -FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_IWDG_FLAG(IWDG_FLAG)); - if ((IWDG->SR & IWDG_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the flag status */ - return bitstatus; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_pwr.c b/example/libs_stm/src/stm32f10x/stm32f10x_pwr.c deleted file mode 100644 index a017ac681..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_pwr.c +++ /dev/null @@ -1,316 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_pwr.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the PWR firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_pwr.h" -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup PWR - * @brief PWR driver modules - * @{ - */ - -/** @defgroup PWR_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup PWR_Private_Defines - * @{ - */ - -/* --------- PWR registers bit address in the alias region ---------- */ -#define PWR_OFFSET (PWR_BASE - PERIPH_BASE) - -/* --- CR Register ---*/ - -/* Alias word address of DBP bit */ -#define CR_OFFSET (PWR_OFFSET + 0x00) -#define DBP_BitNumber 0x08 -#define CR_DBP_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (DBP_BitNumber * 4)) - -/* Alias word address of PVDE bit */ -#define PVDE_BitNumber 0x04 -#define CR_PVDE_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PVDE_BitNumber * 4)) - -/* --- CSR Register ---*/ - -/* Alias word address of EWUP bit */ -#define CSR_OFFSET (PWR_OFFSET + 0x04) -#define EWUP_BitNumber 0x08 -#define CSR_EWUP_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (EWUP_BitNumber * 4)) - -/* ------------------ PWR registers bit mask ------------------------ */ - -/* CR register bit mask */ -#define CR_PDDS_Set ((uint32_t)0x00000002) -#define CR_DS_Mask ((uint32_t)0xFFFFFFFC) -#define CR_CWUF_Set ((uint32_t)0x00000004) -#define CR_PLS_Mask ((uint32_t)0xFFFFFF1F) - -/* --------- Cortex System Control register bit mask ---------------- */ - -/* Cortex System Control register address */ -#define SCB_SysCtrl ((uint32_t)0xE000ED10) - -/* SLEEPDEEP bit mask */ -#define SysCtrl_SLEEPDEEP_Set ((uint32_t)0x00000004) -#define SysCtrl_SLEEPDEEP_Reset ((uint32_t)0xFFFFFFFB) - -/** - * @} - */ - -/** @defgroup PWR_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup PWR_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup PWR_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup PWR_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the PWR peripheral registers to their default reset values. - * @param None - * @retval None - */ -void PWR_DeInit(void) -{ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, DISABLE); -} - -/** - * @brief Enables or disables access to the RTC and backup registers. - * @param NewState: new state of the access to the RTC and backup registers. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_BackupAccessCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) CR_DBP_BB = (uint32_t)NewState; -} - -/** - * @brief Enables or disables the Power Voltage Detector(PVD). - * @param NewState: new state of the PVD. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_PVDCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)NewState; -} - -/** - * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD). - * @param PWR_PVDLevel: specifies the PVD detection level - * This parameter can be one of the following values: - * @arg PWR_PVDLevel_2V2: PVD detection level set to 2.2V - * @arg PWR_PVDLevel_2V3: PVD detection level set to 2.3V - * @arg PWR_PVDLevel_2V4: PVD detection level set to 2.4V - * @arg PWR_PVDLevel_2V5: PVD detection level set to 2.5V - * @arg PWR_PVDLevel_2V6: PVD detection level set to 2.6V - * @arg PWR_PVDLevel_2V7: PVD detection level set to 2.7V - * @arg PWR_PVDLevel_2V8: PVD detection level set to 2.8V - * @arg PWR_PVDLevel_2V9: PVD detection level set to 2.9V - * @retval None - */ -void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_PWR_PVD_LEVEL(PWR_PVDLevel)); - tmpreg = PWR->CR; - /* Clear PLS[7:5] bits */ - tmpreg &= CR_PLS_Mask; - /* Set PLS[7:5] bits according to PWR_PVDLevel value */ - tmpreg |= PWR_PVDLevel; - /* Store the new value */ - PWR->CR = tmpreg; -} - -/** - * @brief Enables or disables the WakeUp Pin functionality. - * @param NewState: new state of the WakeUp Pin functionality. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_WakeUpPinCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) CSR_EWUP_BB = (uint32_t)NewState; -} - -/** - * @brief Enters STOP mode. - * @param PWR_Regulator: specifies the regulator state in STOP mode. - * This parameter can be one of the following values: - * @arg PWR_Regulator_ON: STOP mode with regulator ON - * @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode - * @param PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction. - * This parameter can be one of the following values: - * @arg PWR_STOPEntry_WFI: enter STOP mode with WFI instruction - * @arg PWR_STOPEntry_WFE: enter STOP mode with WFE instruction - * @retval None - */ -void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_PWR_REGULATOR(PWR_Regulator)); - assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry)); - - /* Select the regulator state in STOP mode ---------------------------------*/ - tmpreg = PWR->CR; - /* Clear PDDS and LPDS bits */ - tmpreg &= CR_DS_Mask; - /* Set LPDS bit according to PWR_Regulator value */ - tmpreg |= PWR_Regulator; - /* Store the new value */ - PWR->CR = tmpreg; - /* Set SLEEPDEEP bit of Cortex System Control Register */ - *(__IO uint32_t *) SCB_SysCtrl |= SysCtrl_SLEEPDEEP_Set; - - /* Select STOP mode entry --------------------------------------------------*/ - if(PWR_STOPEntry == PWR_STOPEntry_WFI) - { - /* Request Wait For Interrupt */ - __WFI(); - } - else - { - /* Request Wait For Event */ - __WFE(); - } - - /* Reset SLEEPDEEP bit of Cortex System Control Register */ - *(__IO uint32_t *) SCB_SysCtrl &= SysCtrl_SLEEPDEEP_Reset; -} - -/** - * @brief Enters STANDBY mode. - * @param None - * @retval None - */ -void PWR_EnterSTANDBYMode(void) -{ - /* Clear Wake-up flag */ - PWR->CR |= CR_CWUF_Set; - /* Select STANDBY mode */ - PWR->CR |= CR_PDDS_Set; - /* Set SLEEPDEEP bit of Cortex System Control Register */ - *(__IO uint32_t *) SCB_SysCtrl |= SysCtrl_SLEEPDEEP_Set; -/* This option is used to ensure that store operations are completed */ -#if defined ( __CC_ARM ) - __force_stores(); -#endif - /* Request Wait For Interrupt */ - __WFI(); -} - -/** - * @brief Checks whether the specified PWR flag is set or not. - * @param PWR_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg PWR_FLAG_WU: Wake Up flag - * @arg PWR_FLAG_SB: StandBy flag - * @arg PWR_FLAG_PVDO: PVD Output - * @retval The new state of PWR_FLAG (SET or RESET). - */ -FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_PWR_GET_FLAG(PWR_FLAG)); - - if ((PWR->CSR & PWR_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the flag status */ - return bitstatus; -} - -/** - * @brief Clears the PWR's pending flags. - * @param PWR_FLAG: specifies the flag to clear. - * This parameter can be one of the following values: - * @arg PWR_FLAG_WU: Wake Up flag - * @arg PWR_FLAG_SB: StandBy flag - * @retval None - */ -void PWR_ClearFlag(uint32_t PWR_FLAG) -{ - /* Check the parameters */ - assert_param(IS_PWR_CLEAR_FLAG(PWR_FLAG)); - - PWR->CR |= PWR_FLAG << 2; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_rcc.c b/example/libs_stm/src/stm32f10x/stm32f10x_rcc.c deleted file mode 100644 index 0fb0d58a0..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_rcc.c +++ /dev/null @@ -1,1477 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_rcc.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the RCC firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup RCC - * @brief RCC driver modules - * @{ - */ - -/** @defgroup RCC_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup RCC_Private_Defines - * @{ - */ - -/* ------------ RCC registers bit address in the alias region ----------- */ -#define RCC_OFFSET (RCC_BASE - PERIPH_BASE) - -/* --- CR Register ---*/ - -/* Alias word address of HSION bit */ -#define CR_OFFSET (RCC_OFFSET + 0x00) -#define HSION_BitNumber 0x00 -#define CR_HSION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (HSION_BitNumber * 4)) - -/* Alias word address of PLLON bit */ -#define PLLON_BitNumber 0x18 -#define CR_PLLON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLON_BitNumber * 4)) - -#ifdef STM32F10X_CL - /* Alias word address of PLL2ON bit */ - #define PLL2ON_BitNumber 0x1A - #define CR_PLL2ON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLL2ON_BitNumber * 4)) - - /* Alias word address of PLL3ON bit */ - #define PLL3ON_BitNumber 0x1C - #define CR_PLL3ON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLL3ON_BitNumber * 4)) -#endif /* STM32F10X_CL */ - -/* Alias word address of CSSON bit */ -#define CSSON_BitNumber 0x13 -#define CR_CSSON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (CSSON_BitNumber * 4)) - -/* --- CFGR Register ---*/ - -/* Alias word address of USBPRE bit */ -#define CFGR_OFFSET (RCC_OFFSET + 0x04) - -#ifndef STM32F10X_CL - #define USBPRE_BitNumber 0x16 - #define CFGR_USBPRE_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (USBPRE_BitNumber * 4)) -#else - #define OTGFSPRE_BitNumber 0x16 - #define CFGR_OTGFSPRE_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (OTGFSPRE_BitNumber * 4)) -#endif /* STM32F10X_CL */ - -/* --- BDCR Register ---*/ - -/* Alias word address of RTCEN bit */ -#define BDCR_OFFSET (RCC_OFFSET + 0x20) -#define RTCEN_BitNumber 0x0F -#define BDCR_RTCEN_BB (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (RTCEN_BitNumber * 4)) - -/* Alias word address of BDRST bit */ -#define BDRST_BitNumber 0x10 -#define BDCR_BDRST_BB (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (BDRST_BitNumber * 4)) - -/* --- CSR Register ---*/ - -/* Alias word address of LSION bit */ -#define CSR_OFFSET (RCC_OFFSET + 0x24) -#define LSION_BitNumber 0x00 -#define CSR_LSION_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (LSION_BitNumber * 4)) - -#ifdef STM32F10X_CL -/* --- CFGR2 Register ---*/ - - /* Alias word address of I2S2SRC bit */ - #define CFGR2_OFFSET (RCC_OFFSET + 0x2C) - #define I2S2SRC_BitNumber 0x11 - #define CFGR2_I2S2SRC_BB (PERIPH_BB_BASE + (CFGR2_OFFSET * 32) + (I2S2SRC_BitNumber * 4)) - - /* Alias word address of I2S3SRC bit */ - #define I2S3SRC_BitNumber 0x12 - #define CFGR2_I2S3SRC_BB (PERIPH_BB_BASE + (CFGR2_OFFSET * 32) + (I2S3SRC_BitNumber * 4)) -#endif /* STM32F10X_CL */ - -/* ---------------------- RCC registers bit mask ------------------------ */ - -/* CR register bit mask */ -#define CR_HSEBYP_Reset ((uint32_t)0xFFFBFFFF) -#define CR_HSEBYP_Set ((uint32_t)0x00040000) -#define CR_HSEON_Reset ((uint32_t)0xFFFEFFFF) -#define CR_HSEON_Set ((uint32_t)0x00010000) -#define CR_HSITRIM_Mask ((uint32_t)0xFFFFFF07) - -/* CFGR register bit mask */ -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_CL) - #define CFGR_PLL_Mask ((uint32_t)0xFFC2FFFF) -#else - #define CFGR_PLL_Mask ((uint32_t)0xFFC0FFFF) -#endif /* STM32F10X_CL */ - -#define CFGR_PLLMull_Mask ((uint32_t)0x003C0000) -#define CFGR_PLLSRC_Mask ((uint32_t)0x00010000) -#define CFGR_PLLXTPRE_Mask ((uint32_t)0x00020000) -#define CFGR_SWS_Mask ((uint32_t)0x0000000C) -#define CFGR_SW_Mask ((uint32_t)0xFFFFFFFC) -#define CFGR_HPRE_Reset_Mask ((uint32_t)0xFFFFFF0F) -#define CFGR_HPRE_Set_Mask ((uint32_t)0x000000F0) -#define CFGR_PPRE1_Reset_Mask ((uint32_t)0xFFFFF8FF) -#define CFGR_PPRE1_Set_Mask ((uint32_t)0x00000700) -#define CFGR_PPRE2_Reset_Mask ((uint32_t)0xFFFFC7FF) -#define CFGR_PPRE2_Set_Mask ((uint32_t)0x00003800) -#define CFGR_ADCPRE_Reset_Mask ((uint32_t)0xFFFF3FFF) -#define CFGR_ADCPRE_Set_Mask ((uint32_t)0x0000C000) - -/* CSR register bit mask */ -#define CSR_RMVF_Set ((uint32_t)0x01000000) - -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_CL) -/* CFGR2 register bit mask */ - #define CFGR2_PREDIV1SRC ((uint32_t)0x00010000) - #define CFGR2_PREDIV1 ((uint32_t)0x0000000F) -#endif -#ifdef STM32F10X_CL - #define CFGR2_PREDIV2 ((uint32_t)0x000000F0) - #define CFGR2_PLL2MUL ((uint32_t)0x00000F00) - #define CFGR2_PLL3MUL ((uint32_t)0x0000F000) -#endif /* STM32F10X_CL */ - -/* RCC Flag Mask */ -#define FLAG_Mask ((uint8_t)0x1F) - -#ifndef HSI_Value -/* Typical Value of the HSI in Hz */ - #define HSI_Value ((uint32_t)8000000) -#endif /* HSI_Value */ - -/* CIR register byte 2 (Bits[15:8]) base address */ -#define CIR_BYTE2_ADDRESS ((uint32_t)0x40021009) - -/* CIR register byte 3 (Bits[23:16]) base address */ -#define CIR_BYTE3_ADDRESS ((uint32_t)0x4002100A) - -/* CFGR register byte 4 (Bits[31:24]) base address */ -#define CFGR_BYTE4_ADDRESS ((uint32_t)0x40021007) - -/* BDCR register base address */ -#define BDCR_ADDRESS (PERIPH_BASE + BDCR_OFFSET) - -#ifndef HSEStartUp_TimeOut -/* Time out for HSE start up */ - #define HSEStartUp_TimeOut ((uint16_t)0x0500) -#endif /* HSEStartUp_TimeOut */ - -/** - * @} - */ - -/** @defgroup RCC_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup RCC_Private_Variables - * @{ - */ - -static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; -static __I uint8_t ADCPrescTable[4] = {2, 4, 6, 8}; - -/** - * @} - */ - -/** @defgroup RCC_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup RCC_Private_Functions - * @{ - */ - -/** - * @brief Resets the RCC clock configuration to the default reset state. - * @param None - * @retval None - */ -void RCC_DeInit(void) -{ - /* Set HSION bit */ - RCC->CR |= (uint32_t)0x00000001; - - /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ -#ifndef STM32F10X_CL - RCC->CFGR &= (uint32_t)0xF8FF0000; -#else - RCC->CFGR &= (uint32_t)0xF0FF0000; -#endif /* STM32F10X_CL */ - - /* Reset HSEON, CSSON and PLLON bits */ - RCC->CR &= (uint32_t)0xFEF6FFFF; - - /* Reset HSEBYP bit */ - RCC->CR &= (uint32_t)0xFFFBFFFF; - - /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ - RCC->CFGR &= (uint32_t)0xFF80FFFF; - -#ifdef STM32F10X_CL - /* Reset PLL2ON and PLL3ON bits */ - RCC->CR &= (uint32_t)0xEBFFFFFF; - - /* Disable all interrupts and clear pending bits */ - RCC->CIR = 0x00FF0000; - - /* Reset CFGR2 register */ - RCC->CFGR2 = 0x00000000; -#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) - /* Disable all interrupts and clear pending bits */ - RCC->CIR = 0x009F0000; - - /* Reset CFGR2 register */ - RCC->CFGR2 = 0x00000000; -#else - /* Disable all interrupts and clear pending bits */ - RCC->CIR = 0x009F0000; -#endif /* STM32F10X_CL */ - -} - -/** - * @brief Configures the External High Speed oscillator (HSE). - * @note HSE can not be stopped if it is used directly or through the PLL as system clock. - * @param RCC_HSE: specifies the new state of the HSE. - * This parameter can be one of the following values: - * @arg RCC_HSE_OFF: HSE oscillator OFF - * @arg RCC_HSE_ON: HSE oscillator ON - * @arg RCC_HSE_Bypass: HSE oscillator bypassed with external clock - * @retval None - */ -void RCC_HSEConfig(uint32_t RCC_HSE) -{ - /* Check the parameters */ - assert_param(IS_RCC_HSE(RCC_HSE)); - /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/ - /* Reset HSEON bit */ - RCC->CR &= CR_HSEON_Reset; - /* Reset HSEBYP bit */ - RCC->CR &= CR_HSEBYP_Reset; - /* Configure HSE (RCC_HSE_OFF is already covered by the code section above) */ - switch(RCC_HSE) - { - case RCC_HSE_ON: - /* Set HSEON bit */ - RCC->CR |= CR_HSEON_Set; - break; - - case RCC_HSE_Bypass: - /* Set HSEBYP and HSEON bits */ - RCC->CR |= CR_HSEBYP_Set | CR_HSEON_Set; - break; - - default: - break; - } -} - -/** - * @brief Waits for HSE start-up. - * @param None - * @retval An ErrorStatus enumuration value: - * - SUCCESS: HSE oscillator is stable and ready to use - * - ERROR: HSE oscillator not yet ready - */ -ErrorStatus RCC_WaitForHSEStartUp(void) -{ - __IO uint32_t StartUpCounter = 0; - ErrorStatus status = ERROR; - FlagStatus HSEStatus = RESET; - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY); - StartUpCounter++; - } while((StartUpCounter != HSEStartUp_TimeOut) && (HSEStatus == RESET)); - - if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET) - { - status = SUCCESS; - } - else - { - status = ERROR; - } - return (status); -} - -/** - * @brief Adjusts the Internal High Speed oscillator (HSI) calibration value. - * @param HSICalibrationValue: specifies the calibration trimming value. - * This parameter must be a number between 0 and 0x1F. - * @retval None - */ -void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_RCC_CALIBRATION_VALUE(HSICalibrationValue)); - tmpreg = RCC->CR; - /* Clear HSITRIM[4:0] bits */ - tmpreg &= CR_HSITRIM_Mask; - /* Set the HSITRIM[4:0] bits according to HSICalibrationValue value */ - tmpreg |= (uint32_t)HSICalibrationValue << 3; - /* Store the new value */ - RCC->CR = tmpreg; -} - -/** - * @brief Enables or disables the Internal High Speed oscillator (HSI). - * @note HSI can not be stopped if it is used directly or through the PLL as system clock. - * @param NewState: new state of the HSI. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_HSICmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) CR_HSION_BB = (uint32_t)NewState; -} - -/** - * @brief Configures the PLL clock source and multiplication factor. - * @note This function must be used only when the PLL is disabled. - * @param RCC_PLLSource: specifies the PLL entry clock source. - * For @b STM32_Connectivity_line_devices or @b STM32_Value_line_devices, - * this parameter can be one of the following values: - * @arg RCC_PLLSource_HSI_Div2: HSI oscillator clock divided by 2 selected as PLL clock entry - * @arg RCC_PLLSource_PREDIV1: PREDIV1 clock selected as PLL clock entry - * For @b other_STM32_devices, this parameter can be one of the following values: - * @arg RCC_PLLSource_HSI_Div2: HSI oscillator clock divided by 2 selected as PLL clock entry - * @arg RCC_PLLSource_HSE_Div1: HSE oscillator clock selected as PLL clock entry - * @arg RCC_PLLSource_HSE_Div2: HSE oscillator clock divided by 2 selected as PLL clock entry - * @param RCC_PLLMul: specifies the PLL multiplication factor. - * For @b STM32_Connectivity_line_devices, this parameter can be RCC_PLLMul_x where x:{[4,9], 6_5} - * For @b other_STM32_devices, this parameter can be RCC_PLLMul_x where x:[2,16] - * @retval None - */ -void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource)); - assert_param(IS_RCC_PLL_MUL(RCC_PLLMul)); - - tmpreg = RCC->CFGR; - /* Clear PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */ - tmpreg &= CFGR_PLL_Mask; - /* Set the PLL configuration bits */ - tmpreg |= RCC_PLLSource | RCC_PLLMul; - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -/** - * @brief Enables or disables the PLL. - * @note The PLL can not be disabled if it is used as system clock. - * @param NewState: new state of the PLL. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_PLLCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_PLLON_BB = (uint32_t)NewState; -} - -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_CL) -/** - * @brief Configures the PREDIV1 division factor. - * @note - * - This function must be used only when the PLL is disabled. - * - This function applies only to STM32 Connectivity line and Value line - * devices. - * @param RCC_PREDIV1_Source: specifies the PREDIV1 clock source. - * This parameter can be one of the following values: - * @arg RCC_PREDIV1_Source_HSE: HSE selected as PREDIV1 clock - * @arg RCC_PREDIV1_Source_PLL2: PLL2 selected as PREDIV1 clock - * @note - * For @b STM32_Value_line_devices this parameter is always RCC_PREDIV1_Source_HSE - * @param RCC_PREDIV1_Div: specifies the PREDIV1 clock division factor. - * This parameter can be RCC_PREDIV1_Divx where x:[1,16] - * @retval None - */ -void RCC_PREDIV1Config(uint32_t RCC_PREDIV1_Source, uint32_t RCC_PREDIV1_Div) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_PREDIV1_SOURCE(RCC_PREDIV1_Source)); - assert_param(IS_RCC_PREDIV1(RCC_PREDIV1_Div)); - - tmpreg = RCC->CFGR2; - /* Clear PREDIV1[3:0] and PREDIV1SRC bits */ - tmpreg &= ~(CFGR2_PREDIV1 | CFGR2_PREDIV1SRC); - /* Set the PREDIV1 clock source and division factor */ - tmpreg |= RCC_PREDIV1_Source | RCC_PREDIV1_Div ; - /* Store the new value */ - RCC->CFGR2 = tmpreg; -} -#endif - -#ifdef STM32F10X_CL -/** - * @brief Configures the PREDIV2 division factor. - * @note - * - This function must be used only when both PLL2 and PLL3 are disabled. - * - This function applies only to STM32 Connectivity line devices. - * @param RCC_PREDIV2_Div: specifies the PREDIV2 clock division factor. - * This parameter can be RCC_PREDIV2_Divx where x:[1,16] - * @retval None - */ -void RCC_PREDIV2Config(uint32_t RCC_PREDIV2_Div) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_PREDIV2(RCC_PREDIV2_Div)); - - tmpreg = RCC->CFGR2; - /* Clear PREDIV2[3:0] bits */ - tmpreg &= ~CFGR2_PREDIV2; - /* Set the PREDIV2 division factor */ - tmpreg |= RCC_PREDIV2_Div; - /* Store the new value */ - RCC->CFGR2 = tmpreg; -} - -/** - * @brief Configures the PLL2 multiplication factor. - * @note - * - This function must be used only when the PLL2 is disabled. - * - This function applies only to STM32 Connectivity line devices. - * @param RCC_PLL2Mul: specifies the PLL2 multiplication factor. - * This parameter can be RCC_PLL2Mul_x where x:{[8,14], 16, 20} - * @retval None - */ -void RCC_PLL2Config(uint32_t RCC_PLL2Mul) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_PLL2_MUL(RCC_PLL2Mul)); - - tmpreg = RCC->CFGR2; - /* Clear PLL2Mul[3:0] bits */ - tmpreg &= ~CFGR2_PLL2MUL; - /* Set the PLL2 configuration bits */ - tmpreg |= RCC_PLL2Mul; - /* Store the new value */ - RCC->CFGR2 = tmpreg; -} - - -/** - * @brief Enables or disables the PLL2. - * @note - * - The PLL2 can not be disabled if it is used indirectly as system clock - * (i.e. it is used as PLL clock entry that is used as System clock). - * - This function applies only to STM32 Connectivity line devices. - * @param NewState: new state of the PLL2. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_PLL2Cmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_PLL2ON_BB = (uint32_t)NewState; -} - - -/** - * @brief Configures the PLL3 multiplication factor. - * @note - * - This function must be used only when the PLL3 is disabled. - * - This function applies only to STM32 Connectivity line devices. - * @param RCC_PLL3Mul: specifies the PLL3 multiplication factor. - * This parameter can be RCC_PLL3Mul_x where x:{[8,14], 16, 20} - * @retval None - */ -void RCC_PLL3Config(uint32_t RCC_PLL3Mul) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_PLL3_MUL(RCC_PLL3Mul)); - - tmpreg = RCC->CFGR2; - /* Clear PLL3Mul[3:0] bits */ - tmpreg &= ~CFGR2_PLL3MUL; - /* Set the PLL3 configuration bits */ - tmpreg |= RCC_PLL3Mul; - /* Store the new value */ - RCC->CFGR2 = tmpreg; -} - - -/** - * @brief Enables or disables the PLL3. - * @note This function applies only to STM32 Connectivity line devices. - * @param NewState: new state of the PLL3. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_PLL3Cmd(FunctionalState NewState) -{ - /* Check the parameters */ - - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) CR_PLL3ON_BB = (uint32_t)NewState; -} -#endif /* STM32F10X_CL */ - -/** - * @brief Configures the system clock (SYSCLK). - * @param RCC_SYSCLKSource: specifies the clock source used as system clock. - * This parameter can be one of the following values: - * @arg RCC_SYSCLKSource_HSI: HSI selected as system clock - * @arg RCC_SYSCLKSource_HSE: HSE selected as system clock - * @arg RCC_SYSCLKSource_PLLCLK: PLL selected as system clock - * @retval None - */ -void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_RCC_SYSCLK_SOURCE(RCC_SYSCLKSource)); - tmpreg = RCC->CFGR; - /* Clear SW[1:0] bits */ - tmpreg &= CFGR_SW_Mask; - /* Set SW[1:0] bits according to RCC_SYSCLKSource value */ - tmpreg |= RCC_SYSCLKSource; - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -/** - * @brief Returns the clock source used as system clock. - * @param None - * @retval The clock source used as system clock. The returned value can - * be one of the following: - * - 0x00: HSI used as system clock - * - 0x04: HSE used as system clock - * - 0x08: PLL used as system clock - */ -uint8_t RCC_GetSYSCLKSource(void) -{ - return ((uint8_t)(RCC->CFGR & CFGR_SWS_Mask)); -} - -/** - * @brief Configures the AHB clock (HCLK). - * @param RCC_SYSCLK: defines the AHB clock divider. This clock is derived from - * the system clock (SYSCLK). - * This parameter can be one of the following values: - * @arg RCC_SYSCLK_Div1: AHB clock = SYSCLK - * @arg RCC_SYSCLK_Div2: AHB clock = SYSCLK/2 - * @arg RCC_SYSCLK_Div4: AHB clock = SYSCLK/4 - * @arg RCC_SYSCLK_Div8: AHB clock = SYSCLK/8 - * @arg RCC_SYSCLK_Div16: AHB clock = SYSCLK/16 - * @arg RCC_SYSCLK_Div64: AHB clock = SYSCLK/64 - * @arg RCC_SYSCLK_Div128: AHB clock = SYSCLK/128 - * @arg RCC_SYSCLK_Div256: AHB clock = SYSCLK/256 - * @arg RCC_SYSCLK_Div512: AHB clock = SYSCLK/512 - * @retval None - */ -void RCC_HCLKConfig(uint32_t RCC_SYSCLK) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_RCC_HCLK(RCC_SYSCLK)); - tmpreg = RCC->CFGR; - /* Clear HPRE[3:0] bits */ - tmpreg &= CFGR_HPRE_Reset_Mask; - /* Set HPRE[3:0] bits according to RCC_SYSCLK value */ - tmpreg |= RCC_SYSCLK; - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -/** - * @brief Configures the Low Speed APB clock (PCLK1). - * @param RCC_HCLK: defines the APB1 clock divider. This clock is derived from - * the AHB clock (HCLK). - * This parameter can be one of the following values: - * @arg RCC_HCLK_Div1: APB1 clock = HCLK - * @arg RCC_HCLK_Div2: APB1 clock = HCLK/2 - * @arg RCC_HCLK_Div4: APB1 clock = HCLK/4 - * @arg RCC_HCLK_Div8: APB1 clock = HCLK/8 - * @arg RCC_HCLK_Div16: APB1 clock = HCLK/16 - * @retval None - */ -void RCC_PCLK1Config(uint32_t RCC_HCLK) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_RCC_PCLK(RCC_HCLK)); - tmpreg = RCC->CFGR; - /* Clear PPRE1[2:0] bits */ - tmpreg &= CFGR_PPRE1_Reset_Mask; - /* Set PPRE1[2:0] bits according to RCC_HCLK value */ - tmpreg |= RCC_HCLK; - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -/** - * @brief Configures the High Speed APB clock (PCLK2). - * @param RCC_HCLK: defines the APB2 clock divider. This clock is derived from - * the AHB clock (HCLK). - * This parameter can be one of the following values: - * @arg RCC_HCLK_Div1: APB2 clock = HCLK - * @arg RCC_HCLK_Div2: APB2 clock = HCLK/2 - * @arg RCC_HCLK_Div4: APB2 clock = HCLK/4 - * @arg RCC_HCLK_Div8: APB2 clock = HCLK/8 - * @arg RCC_HCLK_Div16: APB2 clock = HCLK/16 - * @retval None - */ -void RCC_PCLK2Config(uint32_t RCC_HCLK) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_RCC_PCLK(RCC_HCLK)); - tmpreg = RCC->CFGR; - /* Clear PPRE2[2:0] bits */ - tmpreg &= CFGR_PPRE2_Reset_Mask; - /* Set PPRE2[2:0] bits according to RCC_HCLK value */ - tmpreg |= RCC_HCLK << 3; - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -/** - * @brief Enables or disables the specified RCC interrupts. - * @param RCC_IT: specifies the RCC interrupt sources to be enabled or disabled. - * - * For @b STM32_Connectivity_line_devices, this parameter can be any combination - * of the following values - * @arg RCC_IT_LSIRDY: LSI ready interrupt - * @arg RCC_IT_LSERDY: LSE ready interrupt - * @arg RCC_IT_HSIRDY: HSI ready interrupt - * @arg RCC_IT_HSERDY: HSE ready interrupt - * @arg RCC_IT_PLLRDY: PLL ready interrupt - * @arg RCC_IT_PLL2RDY: PLL2 ready interrupt - * @arg RCC_IT_PLL3RDY: PLL3 ready interrupt - * - * For @b other_STM32_devices, this parameter can be any combination of the - * following values - * @arg RCC_IT_LSIRDY: LSI ready interrupt - * @arg RCC_IT_LSERDY: LSE ready interrupt - * @arg RCC_IT_HSIRDY: HSI ready interrupt - * @arg RCC_IT_HSERDY: HSE ready interrupt - * @arg RCC_IT_PLLRDY: PLL ready interrupt - * - * @param NewState: new state of the specified RCC interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_IT(RCC_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Perform Byte access to RCC_CIR bits to enable the selected interrupts */ - *(__IO uint8_t *) CIR_BYTE2_ADDRESS |= RCC_IT; - } - else - { - /* Perform Byte access to RCC_CIR bits to disable the selected interrupts */ - *(__IO uint8_t *) CIR_BYTE2_ADDRESS &= (uint8_t)~RCC_IT; - } -} - -#ifndef STM32F10X_CL -/** - * @brief Configures the USB clock (USBCLK). - * @param RCC_USBCLKSource: specifies the USB clock source. This clock is - * derived from the PLL output. - * This parameter can be one of the following values: - * @arg RCC_USBCLKSource_PLLCLK_1Div5: PLL clock divided by 1,5 selected as USB - * clock source - * @arg RCC_USBCLKSource_PLLCLK_Div1: PLL clock selected as USB clock source - * @retval None - */ -void RCC_USBCLKConfig(uint32_t RCC_USBCLKSource) -{ - /* Check the parameters */ - assert_param(IS_RCC_USBCLK_SOURCE(RCC_USBCLKSource)); - - *(__IO uint32_t *) CFGR_USBPRE_BB = RCC_USBCLKSource; -} -#else -/** - * @brief Configures the USB OTG FS clock (OTGFSCLK). - * This function applies only to STM32 Connectivity line devices. - * @param RCC_OTGFSCLKSource: specifies the USB OTG FS clock source. - * This clock is derived from the PLL output. - * This parameter can be one of the following values: - * @arg RCC_OTGFSCLKSource_PLLVCO_Div3: PLL VCO clock divided by 2 selected as USB OTG FS clock source - * @arg RCC_OTGFSCLKSource_PLLVCO_Div2: PLL VCO clock divided by 2 selected as USB OTG FS clock source - * @retval None - */ -void RCC_OTGFSCLKConfig(uint32_t RCC_OTGFSCLKSource) -{ - /* Check the parameters */ - assert_param(IS_RCC_OTGFSCLK_SOURCE(RCC_OTGFSCLKSource)); - - *(__IO uint32_t *) CFGR_OTGFSPRE_BB = RCC_OTGFSCLKSource; -} -#endif /* STM32F10X_CL */ - -/** - * @brief Configures the ADC clock (ADCCLK). - * @param RCC_PCLK2: defines the ADC clock divider. This clock is derived from - * the APB2 clock (PCLK2). - * This parameter can be one of the following values: - * @arg RCC_PCLK2_Div2: ADC clock = PCLK2/2 - * @arg RCC_PCLK2_Div4: ADC clock = PCLK2/4 - * @arg RCC_PCLK2_Div6: ADC clock = PCLK2/6 - * @arg RCC_PCLK2_Div8: ADC clock = PCLK2/8 - * @retval None - */ -void RCC_ADCCLKConfig(uint32_t RCC_PCLK2) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_RCC_ADCCLK(RCC_PCLK2)); - tmpreg = RCC->CFGR; - /* Clear ADCPRE[1:0] bits */ - tmpreg &= CFGR_ADCPRE_Reset_Mask; - /* Set ADCPRE[1:0] bits according to RCC_PCLK2 value */ - tmpreg |= RCC_PCLK2; - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -#ifdef STM32F10X_CL -/** - * @brief Configures the I2S2 clock source(I2S2CLK). - * @note - * - This function must be called before enabling I2S2 APB clock. - * - This function applies only to STM32 Connectivity line devices. - * @param RCC_I2S2CLKSource: specifies the I2S2 clock source. - * This parameter can be one of the following values: - * @arg RCC_I2S2CLKSource_SYSCLK: system clock selected as I2S2 clock entry - * @arg RCC_I2S2CLKSource_PLL3_VCO: PLL3 VCO clock selected as I2S2 clock entry - * @retval None - */ -void RCC_I2S2CLKConfig(uint32_t RCC_I2S2CLKSource) -{ - /* Check the parameters */ - assert_param(IS_RCC_I2S2CLK_SOURCE(RCC_I2S2CLKSource)); - - *(__IO uint32_t *) CFGR2_I2S2SRC_BB = RCC_I2S2CLKSource; -} - -/** - * @brief Configures the I2S3 clock source(I2S2CLK). - * @note - * - This function must be called before enabling I2S3 APB clock. - * - This function applies only to STM32 Connectivity line devices. - * @param RCC_I2S3CLKSource: specifies the I2S3 clock source. - * This parameter can be one of the following values: - * @arg RCC_I2S3CLKSource_SYSCLK: system clock selected as I2S3 clock entry - * @arg RCC_I2S3CLKSource_PLL3_VCO: PLL3 VCO clock selected as I2S3 clock entry - * @retval None - */ -void RCC_I2S3CLKConfig(uint32_t RCC_I2S3CLKSource) -{ - /* Check the parameters */ - assert_param(IS_RCC_I2S3CLK_SOURCE(RCC_I2S3CLKSource)); - - *(__IO uint32_t *) CFGR2_I2S3SRC_BB = RCC_I2S3CLKSource; -} -#endif /* STM32F10X_CL */ - -/** - * @brief Configures the External Low Speed oscillator (LSE). - * @param RCC_LSE: specifies the new state of the LSE. - * This parameter can be one of the following values: - * @arg RCC_LSE_OFF: LSE oscillator OFF - * @arg RCC_LSE_ON: LSE oscillator ON - * @arg RCC_LSE_Bypass: LSE oscillator bypassed with external clock - * @retval None - */ -void RCC_LSEConfig(uint8_t RCC_LSE) -{ - /* Check the parameters */ - assert_param(IS_RCC_LSE(RCC_LSE)); - /* Reset LSEON and LSEBYP bits before configuring the LSE ------------------*/ - /* Reset LSEON bit */ - *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF; - /* Reset LSEBYP bit */ - *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF; - /* Configure LSE (RCC_LSE_OFF is already covered by the code section above) */ - switch(RCC_LSE) - { - case RCC_LSE_ON: - /* Set LSEON bit */ - *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_ON; - break; - - case RCC_LSE_Bypass: - /* Set LSEBYP and LSEON bits */ - *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_Bypass | RCC_LSE_ON; - break; - - default: - break; - } -} - -/** - * @brief Enables or disables the Internal Low Speed oscillator (LSI). - * @note LSI can not be disabled if the IWDG is running. - * @param NewState: new state of the LSI. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_LSICmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) CSR_LSION_BB = (uint32_t)NewState; -} - -/** - * @brief Configures the RTC clock (RTCCLK). - * @note Once the RTC clock is selected it cant be changed unless the Backup domain is reset. - * @param RCC_RTCCLKSource: specifies the RTC clock source. - * This parameter can be one of the following values: - * @arg RCC_RTCCLKSource_LSE: LSE selected as RTC clock - * @arg RCC_RTCCLKSource_LSI: LSI selected as RTC clock - * @arg RCC_RTCCLKSource_HSE_Div128: HSE clock divided by 128 selected as RTC clock - * @retval None - */ -void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource) -{ - /* Check the parameters */ - assert_param(IS_RCC_RTCCLK_SOURCE(RCC_RTCCLKSource)); - /* Select the RTC clock source */ - RCC->BDCR |= RCC_RTCCLKSource; -} - -/** - * @brief Enables or disables the RTC clock. - * @note This function must be used only after the RTC clock was selected using the RCC_RTCCLKConfig function. - * @param NewState: new state of the RTC clock. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_RTCCLKCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) BDCR_RTCEN_BB = (uint32_t)NewState; -} - -/** - * @brief Returns the frequencies of different on chip clocks. - * @param RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold - * the clocks frequencies. - * @retval None - */ -void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks) -{ - uint32_t tmp = 0, pllmull = 0, pllsource = 0, presc = 0; - -#ifdef STM32F10X_CL - uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0; -#endif /* STM32F10X_CL */ - -#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) - uint32_t prediv1factor = 0; -#endif - - /* Get SYSCLK source -------------------------------------------------------*/ - tmp = RCC->CFGR & CFGR_SWS_Mask; - - switch (tmp) - { - case 0x00: /* HSI used as system clock */ - RCC_Clocks->SYSCLK_Frequency = HSI_Value; - break; - case 0x04: /* HSE used as system clock */ - RCC_Clocks->SYSCLK_Frequency = HSE_Value; - break; - case 0x08: /* PLL used as system clock */ - - /* Get PLL clock source and multiplication factor ----------------------*/ - pllmull = RCC->CFGR & CFGR_PLLMull_Mask; - pllsource = RCC->CFGR & CFGR_PLLSRC_Mask; - -#ifndef STM32F10X_CL - pllmull = ( pllmull >> 18) + 2; - - if (pllsource == 0x00) - {/* HSI oscillator clock divided by 2 selected as PLL clock entry */ - RCC_Clocks->SYSCLK_Frequency = (HSI_Value >> 1) * pllmull; - } - else - { - #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) - prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1; - /* HSE oscillator clock selected as PREDIV1 clock entry */ - RCC_Clocks->SYSCLK_Frequency = (HSE_Value / prediv1factor) * pllmull; - #else - /* HSE selected as PLL clock entry */ - if ((RCC->CFGR & CFGR_PLLXTPRE_Mask) != (uint32_t)RESET) - {/* HSE oscillator clock divided by 2 */ - RCC_Clocks->SYSCLK_Frequency = (HSE_Value >> 1) * pllmull; - } - else - { - RCC_Clocks->SYSCLK_Frequency = HSE_Value * pllmull; - } - #endif - } -#else - pllmull = pllmull >> 18; - - if (pllmull != 0x0D) - { - pllmull += 2; - } - else - { /* PLL multiplication factor = PLL input clock * 6.5 */ - pllmull = 13 / 2; - } - - if (pllsource == 0x00) - {/* HSI oscillator clock divided by 2 selected as PLL clock entry */ - RCC_Clocks->SYSCLK_Frequency = (HSI_Value >> 1) * pllmull; - } - else - {/* PREDIV1 selected as PLL clock entry */ - - /* Get PREDIV1 clock source and division factor */ - prediv1source = RCC->CFGR2 & CFGR2_PREDIV1SRC; - prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1; - - if (prediv1source == 0) - { /* HSE oscillator clock selected as PREDIV1 clock entry */ - RCC_Clocks->SYSCLK_Frequency = (HSE_Value / prediv1factor) * pllmull; - } - else - {/* PLL2 clock selected as PREDIV1 clock entry */ - - /* Get PREDIV2 division factor and PLL2 multiplication factor */ - prediv2factor = ((RCC->CFGR2 & CFGR2_PREDIV2) >> 4) + 1; - pll2mull = ((RCC->CFGR2 & CFGR2_PLL2MUL) >> 8 ) + 2; - RCC_Clocks->SYSCLK_Frequency = (((HSE_Value / prediv2factor) * pll2mull) / prediv1factor) * pllmull; - } - } -#endif /* STM32F10X_CL */ - break; - - default: - RCC_Clocks->SYSCLK_Frequency = HSI_Value; - break; - } - - /* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*/ - /* Get HCLK prescaler */ - tmp = RCC->CFGR & CFGR_HPRE_Set_Mask; - tmp = tmp >> 4; - presc = APBAHBPrescTable[tmp]; - /* HCLK clock frequency */ - RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc; - /* Get PCLK1 prescaler */ - tmp = RCC->CFGR & CFGR_PPRE1_Set_Mask; - tmp = tmp >> 8; - presc = APBAHBPrescTable[tmp]; - /* PCLK1 clock frequency */ - RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc; - /* Get PCLK2 prescaler */ - tmp = RCC->CFGR & CFGR_PPRE2_Set_Mask; - tmp = tmp >> 11; - presc = APBAHBPrescTable[tmp]; - /* PCLK2 clock frequency */ - RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc; - /* Get ADCCLK prescaler */ - tmp = RCC->CFGR & CFGR_ADCPRE_Set_Mask; - tmp = tmp >> 14; - presc = ADCPrescTable[tmp]; - /* ADCCLK clock frequency */ - RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK2_Frequency / presc; -} - -/** - * @brief Enables or disables the AHB peripheral clock. - * @param RCC_AHBPeriph: specifies the AHB peripheral to gates its clock. - * - * For @b STM32_Connectivity_line_devices, this parameter can be any combination - * of the following values: - * @arg RCC_AHBPeriph_DMA1 - * @arg RCC_AHBPeriph_DMA2 - * @arg RCC_AHBPeriph_SRAM - * @arg RCC_AHBPeriph_FLITF - * @arg RCC_AHBPeriph_CRC - * @arg RCC_AHBPeriph_OTG_FS - * @arg RCC_AHBPeriph_ETH_MAC - * @arg RCC_AHBPeriph_ETH_MAC_Tx - * @arg RCC_AHBPeriph_ETH_MAC_Rx - * - * For @b other_STM32_devices, this parameter can be any combination of the - * following values: - * @arg RCC_AHBPeriph_DMA1 - * @arg RCC_AHBPeriph_DMA2 - * @arg RCC_AHBPeriph_SRAM - * @arg RCC_AHBPeriph_FLITF - * @arg RCC_AHBPeriph_CRC - * @arg RCC_AHBPeriph_FSMC - * @arg RCC_AHBPeriph_SDIO - * - * @note SRAM and FLITF clock can be disabled only during sleep mode. - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->AHBENR |= RCC_AHBPeriph; - } - else - { - RCC->AHBENR &= ~RCC_AHBPeriph; - } -} - -/** - * @brief Enables or disables the High Speed APB (APB2) peripheral clock. - * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB, - * RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE, - * RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1, - * RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1, - * RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3, - * RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17, - * RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11 - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - RCC->APB2ENR |= RCC_APB2Periph; - } - else - { - RCC->APB2ENR &= ~RCC_APB2Periph; - } -} - -/** - * @brief Enables or disables the Low Speed APB (APB1) peripheral clock. - * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3, RCC_APB1Periph_TIM4, - * RCC_APB1Periph_TIM5, RCC_APB1Periph_TIM6, RCC_APB1Periph_TIM7, - * RCC_APB1Periph_WWDG, RCC_APB1Periph_SPI2, RCC_APB1Periph_SPI3, - * RCC_APB1Periph_USART2, RCC_APB1Periph_USART3, RCC_APB1Periph_USART4, - * RCC_APB1Periph_USART5, RCC_APB1Periph_I2C1, RCC_APB1Periph_I2C2, - * RCC_APB1Periph_USB, RCC_APB1Periph_CAN1, RCC_APB1Periph_BKP, - * RCC_APB1Periph_PWR, RCC_APB1Periph_DAC, RCC_APB1Periph_CEC, - * RCC_APB1Periph_TIM12, RCC_APB1Periph_TIM13, RCC_APB1Periph_TIM14 - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - RCC->APB1ENR |= RCC_APB1Periph; - } - else - { - RCC->APB1ENR &= ~RCC_APB1Periph; - } -} - -#ifdef STM32F10X_CL -/** - * @brief Forces or releases AHB peripheral reset. - * @note This function applies only to STM32 Connectivity line devices. - * @param RCC_AHBPeriph: specifies the AHB peripheral to reset. - * This parameter can be any combination of the following values: - * @arg RCC_AHBPeriph_OTG_FS - * @arg RCC_AHBPeriph_ETH_MAC - * @param NewState: new state of the specified peripheral reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_AHB_PERIPH_RESET(RCC_AHBPeriph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->AHBRSTR |= RCC_AHBPeriph; - } - else - { - RCC->AHBRSTR &= ~RCC_AHBPeriph; - } -} -#endif /* STM32F10X_CL */ - -/** - * @brief Forces or releases High Speed APB (APB2) peripheral reset. - * @param RCC_APB2Periph: specifies the APB2 peripheral to reset. - * This parameter can be any combination of the following values: - * @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB, - * RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE, - * RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1, - * RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1, - * RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3, - * RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17, - * RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11 - * @param NewState: new state of the specified peripheral reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - RCC->APB2RSTR |= RCC_APB2Periph; - } - else - { - RCC->APB2RSTR &= ~RCC_APB2Periph; - } -} - -/** - * @brief Forces or releases Low Speed APB (APB1) peripheral reset. - * @param RCC_APB1Periph: specifies the APB1 peripheral to reset. - * This parameter can be any combination of the following values: - * @arg RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3, RCC_APB1Periph_TIM4, - * RCC_APB1Periph_TIM5, RCC_APB1Periph_TIM6, RCC_APB1Periph_TIM7, - * RCC_APB1Periph_WWDG, RCC_APB1Periph_SPI2, RCC_APB1Periph_SPI3, - * RCC_APB1Periph_USART2, RCC_APB1Periph_USART3, RCC_APB1Periph_USART4, - * RCC_APB1Periph_USART5, RCC_APB1Periph_I2C1, RCC_APB1Periph_I2C2, - * RCC_APB1Periph_USB, RCC_APB1Periph_CAN1, RCC_APB1Periph_BKP, - * RCC_APB1Periph_PWR, RCC_APB1Periph_DAC, RCC_APB1Periph_CEC, - * RCC_APB1Periph_TIM12, RCC_APB1Periph_TIM13, RCC_APB1Periph_TIM14 - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - RCC->APB1RSTR |= RCC_APB1Periph; - } - else - { - RCC->APB1RSTR &= ~RCC_APB1Periph; - } -} - -/** - * @brief Forces or releases the Backup domain reset. - * @param NewState: new state of the Backup domain reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_BackupResetCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) BDCR_BDRST_BB = (uint32_t)NewState; -} - -/** - * @brief Enables or disables the Clock Security System. - * @param NewState: new state of the Clock Security System.. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_ClockSecuritySystemCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) CR_CSSON_BB = (uint32_t)NewState; -} - -/** - * @brief Selects the clock source to output on MCO pin. - * @param RCC_MCO: specifies the clock source to output. - * - * For @b STM32_Connectivity_line_devices, this parameter can be one of the - * following values: - * @arg RCC_MCO_NoClock: No clock selected - * @arg RCC_MCO_SYSCLK: System clock selected - * @arg RCC_MCO_HSI: HSI oscillator clock selected - * @arg RCC_MCO_HSE: HSE oscillator clock selected - * @arg RCC_MCO_PLLCLK_Div2: PLL clock divided by 2 selected - * @arg RCC_MCO_PLL2CLK: PLL2 clock selected - * @arg RCC_MCO_PLL3CLK_Div2: PLL3 clock divided by 2 selected - * @arg RCC_MCO_XT1: External 3-25 MHz oscillator clock selected - * @arg RCC_MCO_PLL3CLK: PLL3 clock selected - * - * For @b other_STM32_devices, this parameter can be one of the following values: - * @arg RCC_MCO_NoClock: No clock selected - * @arg RCC_MCO_SYSCLK: System clock selected - * @arg RCC_MCO_HSI: HSI oscillator clock selected - * @arg RCC_MCO_HSE: HSE oscillator clock selected - * @arg RCC_MCO_PLLCLK_Div2: PLL clock divided by 2 selected - * - * @retval None - */ -void RCC_MCOConfig(uint8_t RCC_MCO) -{ - /* Check the parameters */ - assert_param(IS_RCC_MCO(RCC_MCO)); - - /* Perform Byte access to MCO bits to select the MCO source */ - *(__IO uint8_t *) CFGR_BYTE4_ADDRESS = RCC_MCO; -} - -/** - * @brief Checks whether the specified RCC flag is set or not. - * @param RCC_FLAG: specifies the flag to check. - * - * For @b STM32_Connectivity_line_devices, this parameter can be one of the - * following values: - * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready - * @arg RCC_FLAG_HSERDY: HSE oscillator clock ready - * @arg RCC_FLAG_PLLRDY: PLL clock ready - * @arg RCC_FLAG_PLL2RDY: PLL2 clock ready - * @arg RCC_FLAG_PLL3RDY: PLL3 clock ready - * @arg RCC_FLAG_LSERDY: LSE oscillator clock ready - * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready - * @arg RCC_FLAG_PINRST: Pin reset - * @arg RCC_FLAG_PORRST: POR/PDR reset - * @arg RCC_FLAG_SFTRST: Software reset - * @arg RCC_FLAG_IWDGRST: Independent Watchdog reset - * @arg RCC_FLAG_WWDGRST: Window Watchdog reset - * @arg RCC_FLAG_LPWRRST: Low Power reset - * - * For @b other_STM32_devices, this parameter can be one of the following values: - * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready - * @arg RCC_FLAG_HSERDY: HSE oscillator clock ready - * @arg RCC_FLAG_PLLRDY: PLL clock ready - * @arg RCC_FLAG_LSERDY: LSE oscillator clock ready - * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready - * @arg RCC_FLAG_PINRST: Pin reset - * @arg RCC_FLAG_PORRST: POR/PDR reset - * @arg RCC_FLAG_SFTRST: Software reset - * @arg RCC_FLAG_IWDGRST: Independent Watchdog reset - * @arg RCC_FLAG_WWDGRST: Window Watchdog reset - * @arg RCC_FLAG_LPWRRST: Low Power reset - * - * @retval The new state of RCC_FLAG (SET or RESET). - */ -FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG) -{ - uint32_t tmp = 0; - uint32_t statusreg = 0; - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_RCC_FLAG(RCC_FLAG)); - - /* Get the RCC register index */ - tmp = RCC_FLAG >> 5; - if (tmp == 1) /* The flag to check is in CR register */ - { - statusreg = RCC->CR; - } - else if (tmp == 2) /* The flag to check is in BDCR register */ - { - statusreg = RCC->BDCR; - } - else /* The flag to check is in CSR register */ - { - statusreg = RCC->CSR; - } - - /* Get the flag position */ - tmp = RCC_FLAG & FLAG_Mask; - if ((statusreg & ((uint32_t)1 << tmp)) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - - /* Return the flag status */ - return bitstatus; -} - -/** - * @brief Clears the RCC reset flags. - * @note The reset flags are: RCC_FLAG_PINRST, RCC_FLAG_PORRST, RCC_FLAG_SFTRST, - * RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST - * @param None - * @retval None - */ -void RCC_ClearFlag(void) -{ - /* Set RMVF bit to clear the reset flags */ - RCC->CSR |= CSR_RMVF_Set; -} - -/** - * @brief Checks whether the specified RCC interrupt has occurred or not. - * @param RCC_IT: specifies the RCC interrupt source to check. - * - * For @b STM32_Connectivity_line_devices, this parameter can be one of the - * following values: - * @arg RCC_IT_LSIRDY: LSI ready interrupt - * @arg RCC_IT_LSERDY: LSE ready interrupt - * @arg RCC_IT_HSIRDY: HSI ready interrupt - * @arg RCC_IT_HSERDY: HSE ready interrupt - * @arg RCC_IT_PLLRDY: PLL ready interrupt - * @arg RCC_IT_PLL2RDY: PLL2 ready interrupt - * @arg RCC_IT_PLL3RDY: PLL3 ready interrupt - * @arg RCC_IT_CSS: Clock Security System interrupt - * - * For @b other_STM32_devices, this parameter can be one of the following values: - * @arg RCC_IT_LSIRDY: LSI ready interrupt - * @arg RCC_IT_LSERDY: LSE ready interrupt - * @arg RCC_IT_HSIRDY: HSI ready interrupt - * @arg RCC_IT_HSERDY: HSE ready interrupt - * @arg RCC_IT_PLLRDY: PLL ready interrupt - * @arg RCC_IT_CSS: Clock Security System interrupt - * - * @retval The new state of RCC_IT (SET or RESET). - */ -ITStatus RCC_GetITStatus(uint8_t RCC_IT) -{ - ITStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_RCC_GET_IT(RCC_IT)); - - /* Check the status of the specified RCC interrupt */ - if ((RCC->CIR & RCC_IT) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - - /* Return the RCC_IT status */ - return bitstatus; -} - -/** - * @brief Clears the RCCs interrupt pending bits. - * @param RCC_IT: specifies the interrupt pending bit to clear. - * - * For @b STM32_Connectivity_line_devices, this parameter can be any combination - * of the following values: - * @arg RCC_IT_LSIRDY: LSI ready interrupt - * @arg RCC_IT_LSERDY: LSE ready interrupt - * @arg RCC_IT_HSIRDY: HSI ready interrupt - * @arg RCC_IT_HSERDY: HSE ready interrupt - * @arg RCC_IT_PLLRDY: PLL ready interrupt - * @arg RCC_IT_PLL2RDY: PLL2 ready interrupt - * @arg RCC_IT_PLL3RDY: PLL3 ready interrupt - * @arg RCC_IT_CSS: Clock Security System interrupt - * - * For @b other_STM32_devices, this parameter can be any combination of the - * following values: - * @arg RCC_IT_LSIRDY: LSI ready interrupt - * @arg RCC_IT_LSERDY: LSE ready interrupt - * @arg RCC_IT_HSIRDY: HSI ready interrupt - * @arg RCC_IT_HSERDY: HSE ready interrupt - * @arg RCC_IT_PLLRDY: PLL ready interrupt - * - * @arg RCC_IT_CSS: Clock Security System interrupt - * @retval None - */ -void RCC_ClearITPendingBit(uint8_t RCC_IT) -{ - /* Check the parameters */ - assert_param(IS_RCC_CLEAR_IT(RCC_IT)); - - /* Perform Byte access to RCC_CIR[23:16] bits to clear the selected interrupt - pending bits */ - *(__IO uint8_t *) CIR_BYTE3_ADDRESS = RCC_IT; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_rtc.c b/example/libs_stm/src/stm32f10x/stm32f10x_rtc.c deleted file mode 100644 index 2720124bd..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_rtc.c +++ /dev/null @@ -1,341 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_rtc.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the RTC firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_rtc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup RTC - * @brief RTC driver modules - * @{ - */ - -/** @defgroup RTC_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - -/** @defgroup RTC_Private_Defines - * @{ - */ - -#define CRL_CNF_Set ((uint16_t)0x0010) /*!< Configuration Flag Enable Mask */ -#define CRL_CNF_Reset ((uint16_t)0xFFEF) /*!< Configuration Flag Disable Mask */ -#define RTC_LSB_Mask ((uint32_t)0x0000FFFF) /*!< RTC LSB Mask */ -#define PRLH_MSB_Mask ((uint32_t)0x000F0000) /*!< RTC Prescaler MSB Mask */ - -/** - * @} - */ - -/** @defgroup RTC_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup RTC_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup RTC_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup RTC_Private_Functions - * @{ - */ - -/** - * @brief Enables or disables the specified RTC interrupts. - * @param RTC_IT: specifies the RTC interrupts sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg RTC_IT_OW: Overflow interrupt - * @arg RTC_IT_ALR: Alarm interrupt - * @arg RTC_IT_SEC: Second interrupt - * @param NewState: new state of the specified RTC interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RTC_IT(RTC_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RTC->CRH |= RTC_IT; - } - else - { - RTC->CRH &= (uint16_t)~RTC_IT; - } -} - -/** - * @brief Enters the RTC configuration mode. - * @param None - * @retval None - */ -void RTC_EnterConfigMode(void) -{ - /* Set the CNF flag to enter in the Configuration Mode */ - RTC->CRL |= CRL_CNF_Set; -} - -/** - * @brief Exits from the RTC configuration mode. - * @param None - * @retval None - */ -void RTC_ExitConfigMode(void) -{ - /* Reset the CNF flag to exit from the Configuration Mode */ - RTC->CRL &= CRL_CNF_Reset; -} - -/** - * @brief Gets the RTC counter value. - * @param None - * @retval RTC counter value. - */ -uint32_t RTC_GetCounter(void) -{ - uint16_t tmp = 0; - tmp = RTC->CNTL; - return (((uint32_t)RTC->CNTH << 16 ) | tmp) ; -} - -/** - * @brief Sets the RTC counter value. - * @param CounterValue: RTC counter new value. - * @retval None - */ -void RTC_SetCounter(uint32_t CounterValue) -{ - RTC_EnterConfigMode(); - /* Set RTC COUNTER MSB word */ - RTC->CNTH = CounterValue >> 16; - /* Set RTC COUNTER LSB word */ - RTC->CNTL = (CounterValue & RTC_LSB_Mask); - RTC_ExitConfigMode(); -} - -/** - * @brief Sets the RTC prescaler value. - * @param PrescalerValue: RTC prescaler new value. - * @retval None - */ -void RTC_SetPrescaler(uint32_t PrescalerValue) -{ - /* Check the parameters */ - assert_param(IS_RTC_PRESCALER(PrescalerValue)); - - RTC_EnterConfigMode(); - /* Set RTC PRESCALER MSB word */ - RTC->PRLH = (PrescalerValue & PRLH_MSB_Mask) >> 16; - /* Set RTC PRESCALER LSB word */ - RTC->PRLL = (PrescalerValue & RTC_LSB_Mask); - RTC_ExitConfigMode(); -} - -/** - * @brief Sets the RTC alarm value. - * @param AlarmValue: RTC alarm new value. - * @retval None - */ -void RTC_SetAlarm(uint32_t AlarmValue) -{ - RTC_EnterConfigMode(); - /* Set the ALARM MSB word */ - RTC->ALRH = AlarmValue >> 16; - /* Set the ALARM LSB word */ - RTC->ALRL = (AlarmValue & RTC_LSB_Mask); - RTC_ExitConfigMode(); -} - -/** - * @brief Gets the RTC divider value. - * @param None - * @retval RTC Divider value. - */ -uint32_t RTC_GetDivider(void) -{ - uint32_t tmp = 0x00; - tmp = ((uint32_t)RTC->DIVH & (uint32_t)0x000F) << 16; - tmp |= RTC->DIVL; - return tmp; -} - -/** - * @brief Waits until last write operation on RTC registers has finished. - * @note This function must be called before any write to RTC registers. - * @param None - * @retval None - */ -void RTC_WaitForLastTask(void) -{ - /* Loop until RTOFF flag is set */ - while ((RTC->CRL & RTC_FLAG_RTOFF) == (uint16_t)RESET) - { - } -} - -/** - * @brief Waits until the RTC registers (RTC_CNT, RTC_ALR and RTC_PRL) - * are synchronized with RTC APB clock. - * @note This function must be called before any read operation after an APB reset - * or an APB clock stop. - * @param None - * @retval None - */ -void RTC_WaitForSynchro(void) -{ - /* Clear RSF flag */ - RTC->CRL &= (uint16_t)~RTC_FLAG_RSF; - /* Loop until RSF flag is set */ - while ((RTC->CRL & RTC_FLAG_RSF) == (uint16_t)RESET) - { - } -} - -/** - * @brief Checks whether the specified RTC flag is set or not. - * @param RTC_FLAG: specifies the flag to check. - * This parameter can be one the following values: - * @arg RTC_FLAG_RTOFF: RTC Operation OFF flag - * @arg RTC_FLAG_RSF: Registers Synchronized flag - * @arg RTC_FLAG_OW: Overflow flag - * @arg RTC_FLAG_ALR: Alarm flag - * @arg RTC_FLAG_SEC: Second flag - * @retval The new state of RTC_FLAG (SET or RESET). - */ -FlagStatus RTC_GetFlagStatus(uint16_t RTC_FLAG) -{ - FlagStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_RTC_GET_FLAG(RTC_FLAG)); - - if ((RTC->CRL & RTC_FLAG) != (uint16_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the RTCs pending flags. - * @param RTC_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg RTC_FLAG_RSF: Registers Synchronized flag. This flag is cleared only after - * an APB reset or an APB Clock stop. - * @arg RTC_FLAG_OW: Overflow flag - * @arg RTC_FLAG_ALR: Alarm flag - * @arg RTC_FLAG_SEC: Second flag - * @retval None - */ -void RTC_ClearFlag(uint16_t RTC_FLAG) -{ - /* Check the parameters */ - assert_param(IS_RTC_CLEAR_FLAG(RTC_FLAG)); - - /* Clear the coressponding RTC flag */ - RTC->CRL &= (uint16_t)~RTC_FLAG; -} - -/** - * @brief Checks whether the specified RTC interrupt has occured or not. - * @param RTC_IT: specifies the RTC interrupts sources to check. - * This parameter can be one of the following values: - * @arg RTC_IT_OW: Overflow interrupt - * @arg RTC_IT_ALR: Alarm interrupt - * @arg RTC_IT_SEC: Second interrupt - * @retval The new state of the RTC_IT (SET or RESET). - */ -ITStatus RTC_GetITStatus(uint16_t RTC_IT) -{ - ITStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_RTC_GET_IT(RTC_IT)); - - bitstatus = (ITStatus)(RTC->CRL & RTC_IT); - if (((RTC->CRH & RTC_IT) != (uint16_t)RESET) && (bitstatus != (uint16_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the RTCs interrupt pending bits. - * @param RTC_IT: specifies the interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg RTC_IT_OW: Overflow interrupt - * @arg RTC_IT_ALR: Alarm interrupt - * @arg RTC_IT_SEC: Second interrupt - * @retval None - */ -void RTC_ClearITPendingBit(uint16_t RTC_IT) -{ - /* Check the parameters */ - assert_param(IS_RTC_IT(RTC_IT)); - - /* Clear the coressponding RTC pending bit */ - RTC->CRL &= (uint16_t)~RTC_IT; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_sdio.c b/example/libs_stm/src/stm32f10x/stm32f10x_sdio.c deleted file mode 100644 index 9d4a3763d..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_sdio.c +++ /dev/null @@ -1,798 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_sdio.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the SDIO firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_sdio.h" -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup SDIO - * @brief SDIO driver modules - * @{ - */ - -/** @defgroup SDIO_Private_TypesDefinitions - * @{ - */ - -/* ------------ SDIO registers bit address in the alias region ----------- */ -#define SDIO_OFFSET (SDIO_BASE - PERIPH_BASE) - -/* --- CLKCR Register ---*/ - -/* Alias word address of CLKEN bit */ -#define CLKCR_OFFSET (SDIO_OFFSET + 0x04) -#define CLKEN_BitNumber 0x08 -#define CLKCR_CLKEN_BB (PERIPH_BB_BASE + (CLKCR_OFFSET * 32) + (CLKEN_BitNumber * 4)) - -/* --- CMD Register ---*/ - -/* Alias word address of SDIOSUSPEND bit */ -#define CMD_OFFSET (SDIO_OFFSET + 0x0C) -#define SDIOSUSPEND_BitNumber 0x0B -#define CMD_SDIOSUSPEND_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (SDIOSUSPEND_BitNumber * 4)) - -/* Alias word address of ENCMDCOMPL bit */ -#define ENCMDCOMPL_BitNumber 0x0C -#define CMD_ENCMDCOMPL_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ENCMDCOMPL_BitNumber * 4)) - -/* Alias word address of NIEN bit */ -#define NIEN_BitNumber 0x0D -#define CMD_NIEN_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (NIEN_BitNumber * 4)) - -/* Alias word address of ATACMD bit */ -#define ATACMD_BitNumber 0x0E -#define CMD_ATACMD_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ATACMD_BitNumber * 4)) - -/* --- DCTRL Register ---*/ - -/* Alias word address of DMAEN bit */ -#define DCTRL_OFFSET (SDIO_OFFSET + 0x2C) -#define DMAEN_BitNumber 0x03 -#define DCTRL_DMAEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (DMAEN_BitNumber * 4)) - -/* Alias word address of RWSTART bit */ -#define RWSTART_BitNumber 0x08 -#define DCTRL_RWSTART_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTART_BitNumber * 4)) - -/* Alias word address of RWSTOP bit */ -#define RWSTOP_BitNumber 0x09 -#define DCTRL_RWSTOP_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTOP_BitNumber * 4)) - -/* Alias word address of RWMOD bit */ -#define RWMOD_BitNumber 0x0A -#define DCTRL_RWMOD_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWMOD_BitNumber * 4)) - -/* Alias word address of SDIOEN bit */ -#define SDIOEN_BitNumber 0x0B -#define DCTRL_SDIOEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (SDIOEN_BitNumber * 4)) - -/* ---------------------- SDIO registers bit mask ------------------------ */ - -/* --- CLKCR Register ---*/ - -/* CLKCR register clear mask */ -#define CLKCR_CLEAR_MASK ((uint32_t)0xFFFF8100) - -/* --- PWRCTRL Register ---*/ - -/* SDIO PWRCTRL Mask */ -#define PWR_PWRCTRL_MASK ((uint32_t)0xFFFFFFFC) - -/* --- DCTRL Register ---*/ - -/* SDIO DCTRL Clear Mask */ -#define DCTRL_CLEAR_MASK ((uint32_t)0xFFFFFF08) - -/* --- CMD Register ---*/ - -/* CMD Register clear mask */ -#define CMD_CLEAR_MASK ((uint32_t)0xFFFFF800) - -/* SDIO RESP Registers Address */ -#define SDIO_RESP_ADDR ((uint32_t)(SDIO_BASE + 0x14)) - -/** - * @} - */ - -/** @defgroup SDIO_Private_Defines - * @{ - */ - -/** - * @} - */ - -/** @defgroup SDIO_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup SDIO_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup SDIO_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup SDIO_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the SDIO peripheral registers to their default reset values. - * @param None - * @retval None - */ -void SDIO_DeInit(void) -{ - SDIO->POWER = 0x00000000; - SDIO->CLKCR = 0x00000000; - SDIO->ARG = 0x00000000; - SDIO->CMD = 0x00000000; - SDIO->DTIMER = 0x00000000; - SDIO->DLEN = 0x00000000; - SDIO->DCTRL = 0x00000000; - SDIO->ICR = 0x00C007FF; - SDIO->MASK = 0x00000000; -} - -/** - * @brief Initializes the SDIO peripheral according to the specified - * parameters in the SDIO_InitStruct. - * @param SDIO_InitStruct : pointer to a SDIO_InitTypeDef structure - * that contains the configuration information for the SDIO peripheral. - * @retval None - */ -void SDIO_Init(SDIO_InitTypeDef* SDIO_InitStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_SDIO_CLOCK_EDGE(SDIO_InitStruct->SDIO_ClockEdge)); - assert_param(IS_SDIO_CLOCK_BYPASS(SDIO_InitStruct->SDIO_ClockBypass)); - assert_param(IS_SDIO_CLOCK_POWER_SAVE(SDIO_InitStruct->SDIO_ClockPowerSave)); - assert_param(IS_SDIO_BUS_WIDE(SDIO_InitStruct->SDIO_BusWide)); - assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(SDIO_InitStruct->SDIO_HardwareFlowControl)); - -/*---------------------------- SDIO CLKCR Configuration ------------------------*/ - /* Get the SDIO CLKCR value */ - tmpreg = SDIO->CLKCR; - - /* Clear CLKDIV, PWRSAV, BYPASS, WIDBUS, NEGEDGE, HWFC_EN bits */ - tmpreg &= CLKCR_CLEAR_MASK; - - /* Set CLKDIV bits according to SDIO_ClockDiv value */ - /* Set PWRSAV bit according to SDIO_ClockPowerSave value */ - /* Set BYPASS bit according to SDIO_ClockBypass value */ - /* Set WIDBUS bits according to SDIO_BusWide value */ - /* Set NEGEDGE bits according to SDIO_ClockEdge value */ - /* Set HWFC_EN bits according to SDIO_HardwareFlowControl value */ - tmpreg |= (SDIO_InitStruct->SDIO_ClockDiv | SDIO_InitStruct->SDIO_ClockPowerSave | - SDIO_InitStruct->SDIO_ClockBypass | SDIO_InitStruct->SDIO_BusWide | - SDIO_InitStruct->SDIO_ClockEdge | SDIO_InitStruct->SDIO_HardwareFlowControl); - - /* Write to SDIO CLKCR */ - SDIO->CLKCR = tmpreg; -} - -/** - * @brief Fills each SDIO_InitStruct member with its default value. - * @param SDIO_InitStruct: pointer to an SDIO_InitTypeDef structure which - * will be initialized. - * @retval None - */ -void SDIO_StructInit(SDIO_InitTypeDef* SDIO_InitStruct) -{ - /* SDIO_InitStruct members default value */ - SDIO_InitStruct->SDIO_ClockDiv = 0x00; - SDIO_InitStruct->SDIO_ClockEdge = SDIO_ClockEdge_Rising; - SDIO_InitStruct->SDIO_ClockBypass = SDIO_ClockBypass_Disable; - SDIO_InitStruct->SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; - SDIO_InitStruct->SDIO_BusWide = SDIO_BusWide_1b; - SDIO_InitStruct->SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; -} - -/** - * @brief Enables or disables the SDIO Clock. - * @param NewState: new state of the SDIO Clock. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_ClockCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CLKCR_CLKEN_BB = (uint32_t)NewState; -} - -/** - * @brief Sets the power status of the controller. - * @param SDIO_PowerState: new state of the Power state. - * This parameter can be one of the following values: - * @arg SDIO_PowerState_OFF - * @arg SDIO_PowerState_ON - * @retval None - */ -void SDIO_SetPowerState(uint32_t SDIO_PowerState) -{ - /* Check the parameters */ - assert_param(IS_SDIO_POWER_STATE(SDIO_PowerState)); - - SDIO->POWER &= PWR_PWRCTRL_MASK; - SDIO->POWER |= SDIO_PowerState; -} - -/** - * @brief Gets the power status of the controller. - * @param None - * @retval Power status of the controller. The returned value can - * be one of the following: - * - 0x00: Power OFF - * - 0x02: Power UP - * - 0x03: Power ON - */ -uint32_t SDIO_GetPowerState(void) -{ - return (SDIO->POWER & (~PWR_PWRCTRL_MASK)); -} - -/** - * @brief Enables or disables the SDIO interrupts. - * @param SDIO_IT: specifies the SDIO interrupt sources to be enabled or disabled. - * This parameter can be one or a combination of the following values: - * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt - * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt - * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt - * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt - * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt - * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt - * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt - * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt - * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt - * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide - * bus mode interrupt - * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt - * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt - * @arg SDIO_IT_TXACT: Data transmit in progress interrupt - * @arg SDIO_IT_RXACT: Data receive in progress interrupt - * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt - * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt - * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt - * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt - * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt - * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt - * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt - * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt - * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt - * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt - * @param NewState: new state of the specified SDIO interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_ITConfig(uint32_t SDIO_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SDIO_IT(SDIO_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the SDIO interrupts */ - SDIO->MASK |= SDIO_IT; - } - else - { - /* Disable the SDIO interrupts */ - SDIO->MASK &= ~SDIO_IT; - } -} - -/** - * @brief Enables or disables the SDIO DMA request. - * @param NewState: new state of the selected SDIO DMA request. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_DMACmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) DCTRL_DMAEN_BB = (uint32_t)NewState; -} - -/** - * @brief Initializes the SDIO Command according to the specified - * parameters in the SDIO_CmdInitStruct and send the command. - * @param SDIO_CmdInitStruct : pointer to a SDIO_CmdInitTypeDef - * structure that contains the configuration information for the SDIO command. - * @retval None - */ -void SDIO_SendCommand(SDIO_CmdInitTypeDef *SDIO_CmdInitStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_SDIO_CMD_INDEX(SDIO_CmdInitStruct->SDIO_CmdIndex)); - assert_param(IS_SDIO_RESPONSE(SDIO_CmdInitStruct->SDIO_Response)); - assert_param(IS_SDIO_WAIT(SDIO_CmdInitStruct->SDIO_Wait)); - assert_param(IS_SDIO_CPSM(SDIO_CmdInitStruct->SDIO_CPSM)); - -/*---------------------------- SDIO ARG Configuration ------------------------*/ - /* Set the SDIO Argument value */ - SDIO->ARG = SDIO_CmdInitStruct->SDIO_Argument; - -/*---------------------------- SDIO CMD Configuration ------------------------*/ - /* Get the SDIO CMD value */ - tmpreg = SDIO->CMD; - /* Clear CMDINDEX, WAITRESP, WAITINT, WAITPEND, CPSMEN bits */ - tmpreg &= CMD_CLEAR_MASK; - /* Set CMDINDEX bits according to SDIO_CmdIndex value */ - /* Set WAITRESP bits according to SDIO_Response value */ - /* Set WAITINT and WAITPEND bits according to SDIO_Wait value */ - /* Set CPSMEN bits according to SDIO_CPSM value */ - tmpreg |= (uint32_t)SDIO_CmdInitStruct->SDIO_CmdIndex | SDIO_CmdInitStruct->SDIO_Response - | SDIO_CmdInitStruct->SDIO_Wait | SDIO_CmdInitStruct->SDIO_CPSM; - - /* Write to SDIO CMD */ - SDIO->CMD = tmpreg; -} - -/** - * @brief Fills each SDIO_CmdInitStruct member with its default value. - * @param SDIO_CmdInitStruct: pointer to an SDIO_CmdInitTypeDef - * structure which will be initialized. - * @retval None - */ -void SDIO_CmdStructInit(SDIO_CmdInitTypeDef* SDIO_CmdInitStruct) -{ - /* SDIO_CmdInitStruct members default value */ - SDIO_CmdInitStruct->SDIO_Argument = 0x00; - SDIO_CmdInitStruct->SDIO_CmdIndex = 0x00; - SDIO_CmdInitStruct->SDIO_Response = SDIO_Response_No; - SDIO_CmdInitStruct->SDIO_Wait = SDIO_Wait_No; - SDIO_CmdInitStruct->SDIO_CPSM = SDIO_CPSM_Disable; -} - -/** - * @brief Returns command index of last command for which response received. - * @param None - * @retval Returns the command index of the last command response received. - */ -uint8_t SDIO_GetCommandResponse(void) -{ - return (uint8_t)(SDIO->RESPCMD); -} - -/** - * @brief Returns response received from the card for the last command. - * @param SDIO_RESP: Specifies the SDIO response register. - * This parameter can be one of the following values: - * @arg SDIO_RESP1: Response Register 1 - * @arg SDIO_RESP2: Response Register 2 - * @arg SDIO_RESP3: Response Register 3 - * @arg SDIO_RESP4: Response Register 4 - * @retval The Corresponding response register value. - */ -uint32_t SDIO_GetResponse(uint32_t SDIO_RESP) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_SDIO_RESP(SDIO_RESP)); - - tmp = SDIO_RESP_ADDR + SDIO_RESP; - - return (*(__IO uint32_t *) tmp); -} - -/** - * @brief Initializes the SDIO data path according to the specified - * parameters in the SDIO_DataInitStruct. - * @param SDIO_DataInitStruct : pointer to a SDIO_DataInitTypeDef structure that - * contains the configuration information for the SDIO command. - * @retval None - */ -void SDIO_DataConfig(SDIO_DataInitTypeDef* SDIO_DataInitStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_SDIO_DATA_LENGTH(SDIO_DataInitStruct->SDIO_DataLength)); - assert_param(IS_SDIO_BLOCK_SIZE(SDIO_DataInitStruct->SDIO_DataBlockSize)); - assert_param(IS_SDIO_TRANSFER_DIR(SDIO_DataInitStruct->SDIO_TransferDir)); - assert_param(IS_SDIO_TRANSFER_MODE(SDIO_DataInitStruct->SDIO_TransferMode)); - assert_param(IS_SDIO_DPSM(SDIO_DataInitStruct->SDIO_DPSM)); - -/*---------------------------- SDIO DTIMER Configuration ---------------------*/ - /* Set the SDIO Data TimeOut value */ - SDIO->DTIMER = SDIO_DataInitStruct->SDIO_DataTimeOut; - -/*---------------------------- SDIO DLEN Configuration -----------------------*/ - /* Set the SDIO DataLength value */ - SDIO->DLEN = SDIO_DataInitStruct->SDIO_DataLength; - -/*---------------------------- SDIO DCTRL Configuration ----------------------*/ - /* Get the SDIO DCTRL value */ - tmpreg = SDIO->DCTRL; - /* Clear DEN, DTMODE, DTDIR and DBCKSIZE bits */ - tmpreg &= DCTRL_CLEAR_MASK; - /* Set DEN bit according to SDIO_DPSM value */ - /* Set DTMODE bit according to SDIO_TransferMode value */ - /* Set DTDIR bit according to SDIO_TransferDir value */ - /* Set DBCKSIZE bits according to SDIO_DataBlockSize value */ - tmpreg |= (uint32_t)SDIO_DataInitStruct->SDIO_DataBlockSize | SDIO_DataInitStruct->SDIO_TransferDir - | SDIO_DataInitStruct->SDIO_TransferMode | SDIO_DataInitStruct->SDIO_DPSM; - - /* Write to SDIO DCTRL */ - SDIO->DCTRL = tmpreg; -} - -/** - * @brief Fills each SDIO_DataInitStruct member with its default value. - * @param SDIO_DataInitStruct: pointer to an SDIO_DataInitTypeDef structure which - * will be initialized. - * @retval None - */ -void SDIO_DataStructInit(SDIO_DataInitTypeDef* SDIO_DataInitStruct) -{ - /* SDIO_DataInitStruct members default value */ - SDIO_DataInitStruct->SDIO_DataTimeOut = 0xFFFFFFFF; - SDIO_DataInitStruct->SDIO_DataLength = 0x00; - SDIO_DataInitStruct->SDIO_DataBlockSize = SDIO_DataBlockSize_1b; - SDIO_DataInitStruct->SDIO_TransferDir = SDIO_TransferDir_ToCard; - SDIO_DataInitStruct->SDIO_TransferMode = SDIO_TransferMode_Block; - SDIO_DataInitStruct->SDIO_DPSM = SDIO_DPSM_Disable; -} - -/** - * @brief Returns number of remaining data bytes to be transferred. - * @param None - * @retval Number of remaining data bytes to be transferred - */ -uint32_t SDIO_GetDataCounter(void) -{ - return SDIO->DCOUNT; -} - -/** - * @brief Read one data word from Rx FIFO. - * @param None - * @retval Data received - */ -uint32_t SDIO_ReadData(void) -{ - return SDIO->FIFO; -} - -/** - * @brief Write one data word to Tx FIFO. - * @param Data: 32-bit data word to write. - * @retval None - */ -void SDIO_WriteData(uint32_t Data) -{ - SDIO->FIFO = Data; -} - -/** - * @brief Returns the number of words left to be written to or read from FIFO. - * @param None - * @retval Remaining number of words. - */ -uint32_t SDIO_GetFIFOCount(void) -{ - return SDIO->FIFOCNT; -} - -/** - * @brief Starts the SD I/O Read Wait operation. - * @param NewState: new state of the Start SDIO Read Wait operation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_StartSDIOReadWait(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) DCTRL_RWSTART_BB = (uint32_t) NewState; -} - -/** - * @brief Stops the SD I/O Read Wait operation. - * @param NewState: new state of the Stop SDIO Read Wait operation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_StopSDIOReadWait(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) DCTRL_RWSTOP_BB = (uint32_t) NewState; -} - -/** - * @brief Sets one of the two options of inserting read wait interval. - * @param SDIO_ReadWaitMode: SD I/O Read Wait operation mode. - * This parametre can be: - * @arg SDIO_ReadWaitMode_CLK: Read Wait control by stopping SDIOCLK - * @arg SDIO_ReadWaitMode_DATA2: Read Wait control using SDIO_DATA2 - * @retval None - */ -void SDIO_SetSDIOReadWaitMode(uint32_t SDIO_ReadWaitMode) -{ - /* Check the parameters */ - assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode)); - - *(__IO uint32_t *) DCTRL_RWMOD_BB = SDIO_ReadWaitMode; -} - -/** - * @brief Enables or disables the SD I/O Mode Operation. - * @param NewState: new state of SDIO specific operation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_SetSDIOOperation(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) DCTRL_SDIOEN_BB = (uint32_t)NewState; -} - -/** - * @brief Enables or disables the SD I/O Mode suspend command sending. - * @param NewState: new state of the SD I/O Mode suspend command. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_SendSDIOSuspendCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CMD_SDIOSUSPEND_BB = (uint32_t)NewState; -} - -/** - * @brief Enables or disables the command completion signal. - * @param NewState: new state of command completion signal. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_CommandCompletionCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CMD_ENCMDCOMPL_BB = (uint32_t)NewState; -} - -/** - * @brief Enables or disables the CE-ATA interrupt. - * @param NewState: new state of CE-ATA interrupt. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_CEATAITCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CMD_NIEN_BB = (uint32_t)((~((uint32_t)NewState)) & ((uint32_t)0x1)); -} - -/** - * @brief Sends CE-ATA command (CMD61). - * @param NewState: new state of CE-ATA command. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_SendCEATACmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CMD_ATACMD_BB = (uint32_t)NewState; -} - -/** - * @brief Checks whether the specified SDIO flag is set or not. - * @param SDIO_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed) - * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) - * @arg SDIO_FLAG_CTIMEOUT: Command response timeout - * @arg SDIO_FLAG_DTIMEOUT: Data timeout - * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error - * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error - * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed) - * @arg SDIO_FLAG_CMDSENT: Command sent (no response required) - * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero) - * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide - * bus mode. - * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed) - * @arg SDIO_FLAG_CMDACT: Command transfer in progress - * @arg SDIO_FLAG_TXACT: Data transmit in progress - * @arg SDIO_FLAG_RXACT: Data receive in progress - * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty - * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full - * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full - * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full - * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty - * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty - * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO - * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO - * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received - * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61 - * @retval The new state of SDIO_FLAG (SET or RESET). - */ -FlagStatus SDIO_GetFlagStatus(uint32_t SDIO_FLAG) -{ - FlagStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_SDIO_FLAG(SDIO_FLAG)); - - if ((SDIO->STA & SDIO_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the SDIO's pending flags. - * @param SDIO_FLAG: specifies the flag to clear. - * This parameter can be one or a combination of the following values: - * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed) - * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) - * @arg SDIO_FLAG_CTIMEOUT: Command response timeout - * @arg SDIO_FLAG_DTIMEOUT: Data timeout - * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error - * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error - * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed) - * @arg SDIO_FLAG_CMDSENT: Command sent (no response required) - * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero) - * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide - * bus mode - * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed) - * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received - * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61 - * @retval None - */ -void SDIO_ClearFlag(uint32_t SDIO_FLAG) -{ - /* Check the parameters */ - assert_param(IS_SDIO_CLEAR_FLAG(SDIO_FLAG)); - - SDIO->ICR = SDIO_FLAG; -} - -/** - * @brief Checks whether the specified SDIO interrupt has occurred or not. - * @param SDIO_IT: specifies the SDIO interrupt source to check. - * This parameter can be one of the following values: - * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt - * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt - * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt - * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt - * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt - * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt - * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt - * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt - * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt - * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide - * bus mode interrupt - * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt - * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt - * @arg SDIO_IT_TXACT: Data transmit in progress interrupt - * @arg SDIO_IT_RXACT: Data receive in progress interrupt - * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt - * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt - * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt - * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt - * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt - * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt - * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt - * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt - * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt - * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt - * @retval The new state of SDIO_IT (SET or RESET). - */ -ITStatus SDIO_GetITStatus(uint32_t SDIO_IT) -{ - ITStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_SDIO_GET_IT(SDIO_IT)); - if ((SDIO->STA & SDIO_IT) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the SDIOs interrupt pending bits. - * @param SDIO_IT: specifies the interrupt pending bit to clear. - * This parameter can be one or a combination of the following values: - * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt - * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt - * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt - * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt - * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt - * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt - * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt - * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt - * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt - * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide - * bus mode interrupt - * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt - * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 - * @retval None - */ -void SDIO_ClearITPendingBit(uint32_t SDIO_IT) -{ - /* Check the parameters */ - assert_param(IS_SDIO_CLEAR_IT(SDIO_IT)); - - SDIO->ICR = SDIO_IT; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_spi.c b/example/libs_stm/src/stm32f10x/stm32f10x_spi.c deleted file mode 100644 index b1ff419d9..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_spi.c +++ /dev/null @@ -1,907 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_spi.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the SPI firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_spi.h" -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup SPI - * @brief SPI driver modules - * @{ - */ - -/** @defgroup SPI_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - - -/** @defgroup SPI_Private_Defines - * @{ - */ - -/* SPI SPE mask */ -#define CR1_SPE_Set ((uint16_t)0x0040) -#define CR1_SPE_Reset ((uint16_t)0xFFBF) - -/* I2S I2SE mask */ -#define I2SCFGR_I2SE_Set ((uint16_t)0x0400) -#define I2SCFGR_I2SE_Reset ((uint16_t)0xFBFF) - -/* SPI CRCNext mask */ -#define CR1_CRCNext_Set ((uint16_t)0x1000) - -/* SPI CRCEN mask */ -#define CR1_CRCEN_Set ((uint16_t)0x2000) -#define CR1_CRCEN_Reset ((uint16_t)0xDFFF) - -/* SPI SSOE mask */ -#define CR2_SSOE_Set ((uint16_t)0x0004) -#define CR2_SSOE_Reset ((uint16_t)0xFFFB) - -/* SPI registers Masks */ -#define CR1_CLEAR_Mask ((uint16_t)0x3040) -#define I2SCFGR_CLEAR_Mask ((uint16_t)0xF040) - -/* SPI or I2S mode selection masks */ -#define SPI_Mode_Select ((uint16_t)0xF7FF) -#define I2S_Mode_Select ((uint16_t)0x0800) - -/* I2S clock source selection masks */ -#define I2S2_CLOCK_SRC ((uint32_t)(0x00020000)) -#define I2S3_CLOCK_SRC ((uint32_t)(0x00040000)) -#define I2S_MUL_MASK ((uint32_t)(0x0000F000)) -#define I2S_DIV_MASK ((uint32_t)(0x000000F0)) - -/** - * @} - */ - -/** @defgroup SPI_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup SPI_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup SPI_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup SPI_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the SPIx peripheral registers to their default - * reset values (Affects also the I2Ss). - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @retval None - */ -void SPI_I2S_DeInit(SPI_TypeDef* SPIx) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - if (SPIx == SPI1) - { - /* Enable SPI1 reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE); - /* Release SPI1 from reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE); - } - else if (SPIx == SPI2) - { - /* Enable SPI2 reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE); - /* Release SPI2 from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE); - } - else - { - if (SPIx == SPI3) - { - /* Enable SPI3 reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE); - /* Release SPI3 from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE); - } - } -} - -/** - * @brief Initializes the SPIx peripheral according to the specified - * parameters in the SPI_InitStruct. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure that - * contains the configuration information for the specified SPI peripheral. - * @retval None - */ -void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct) -{ - uint16_t tmpreg = 0; - - /* check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - /* Check the SPI parameters */ - assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction)); - assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode)); - assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize)); - assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL)); - assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA)); - assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS)); - assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler)); - assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit)); - assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial)); - -/*---------------------------- SPIx CR1 Configuration ------------------------*/ - /* Get the SPIx CR1 value */ - tmpreg = SPIx->CR1; - /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */ - tmpreg &= CR1_CLEAR_Mask; - /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler - master/salve mode, CPOL and CPHA */ - /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */ - /* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */ - /* Set LSBFirst bit according to SPI_FirstBit value */ - /* Set BR bits according to SPI_BaudRatePrescaler value */ - /* Set CPOL bit according to SPI_CPOL value */ - /* Set CPHA bit according to SPI_CPHA value */ - tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode | - SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL | - SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS | - SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit); - /* Write to SPIx CR1 */ - SPIx->CR1 = tmpreg; - - /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */ - SPIx->I2SCFGR &= SPI_Mode_Select; - -/*---------------------------- SPIx CRCPOLY Configuration --------------------*/ - /* Write to SPIx CRCPOLY */ - SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial; -} - -/** - * @brief Initializes the SPIx peripheral according to the specified - * parameters in the I2S_InitStruct. - * @param SPIx: where x can be 2 or 3 to select the SPI peripheral - * (configured in I2S mode). - * @param I2S_InitStruct: pointer to an I2S_InitTypeDef structure that - * contains the configuration information for the specified SPI peripheral - * configured in I2S mode. - * @note - * The function calculates the optimal prescaler needed to obtain the most - * accurate audio frequency (depending on the I2S clock source, the PLL values - * and the product configuration). But in case the prescaler value is greater - * than 511, the default value (0x02) will be configured instead. * - * @retval None - */ -void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct) -{ - uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1; - uint32_t tmp = 0; - RCC_ClocksTypeDef RCC_Clocks; - uint32_t sourceclock = 0; - - /* Check the I2S parameters */ - assert_param(IS_SPI_23_PERIPH(SPIx)); - assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode)); - assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard)); - assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat)); - assert_param(IS_I2S_MCLK_OUTPUT(I2S_InitStruct->I2S_MCLKOutput)); - assert_param(IS_I2S_AUDIO_FREQ(I2S_InitStruct->I2S_AudioFreq)); - assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL)); - -/*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/ - /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */ - SPIx->I2SCFGR &= I2SCFGR_CLEAR_Mask; - SPIx->I2SPR = 0x0002; - - /* Get the I2SCFGR register value */ - tmpreg = SPIx->I2SCFGR; - - /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/ - if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default) - { - i2sodd = (uint16_t)0; - i2sdiv = (uint16_t)2; - } - /* If the requested audio frequency is not the default, compute the prescaler */ - else - { - /* Check the frame length (For the Prescaler computing) */ - if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b) - { - /* Packet length is 16 bits */ - packetlength = 1; - } - else - { - /* Packet length is 32 bits */ - packetlength = 2; - } - - /* Get the I2S clock source mask depending on the peripheral number */ - if(((uint32_t)SPIx) == SPI2_BASE) - { - /* The mask is relative to I2S2 */ - tmp = I2S2_CLOCK_SRC; - } - else - { - /* The mask is relative to I2S3 */ - tmp = I2S3_CLOCK_SRC; - } - - /* Check the I2S clock source configuration depending on the Device: - Only Connectivity line devices have the PLL3 VCO clock */ -#ifdef STM32F10X_CL - if((RCC->CFGR2 & tmp) != 0) - { - /* Get the configuration bits of RCC PLL3 multiplier */ - tmp = (uint32_t)((RCC->CFGR2 & I2S_MUL_MASK) >> 12); - - /* Get the value of the PLL3 multiplier */ - if((tmp > 5) && (tmp < 15)) - { - /* Multplier is between 8 and 14 (value 15 is forbidden) */ - tmp += 2; - } - else - { - if (tmp == 15) - { - /* Multiplier is 20 */ - tmp = 20; - } - } - /* Get the PREDIV2 value */ - sourceclock = (uint32_t)(((RCC->CFGR2 & I2S_DIV_MASK) >> 4) + 1); - - /* Calculate the Source Clock frequency based on PLL3 and PREDIV2 values */ - sourceclock = (uint32_t) ((HSE_Value / sourceclock) * tmp * 2); - } - else - { - /* I2S Clock source is System clock: Get System Clock frequency */ - RCC_GetClocksFreq(&RCC_Clocks); - - /* Get the source clock value: based on System Clock value */ - sourceclock = RCC_Clocks.SYSCLK_Frequency; - } -#else /* STM32F10X_HD */ - /* I2S Clock source is System clock: Get System Clock frequency */ - RCC_GetClocksFreq(&RCC_Clocks); - - /* Get the source clock value: based on System Clock value */ - sourceclock = RCC_Clocks.SYSCLK_Frequency; -#endif /* STM32F10X_CL */ - - /* Compute the Real divider depending on the MCLK output state with a flaoting point */ - if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable) - { - /* MCLK output is enabled */ - tmp = (uint16_t)(((((sourceclock / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5); - } - else - { - /* MCLK output is disabled */ - tmp = (uint16_t)(((((sourceclock / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5); - } - - /* Remove the flaoting point */ - tmp = tmp / 10; - - /* Check the parity of the divider */ - i2sodd = (uint16_t)(tmp & (uint16_t)0x0001); - - /* Compute the i2sdiv prescaler */ - i2sdiv = (uint16_t)((tmp - i2sodd) / 2); - - /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */ - i2sodd = (uint16_t) (i2sodd << 8); - } - - /* Test if the divider is 1 or 0 or greater than 0xFF */ - if ((i2sdiv < 2) || (i2sdiv > 0xFF)) - { - /* Set the default values */ - i2sdiv = 2; - i2sodd = 0; - } - - /* Write to SPIx I2SPR register the computed value */ - SPIx->I2SPR = (uint16_t)(i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput)); - - /* Configure the I2S with the SPI_InitStruct values */ - tmpreg |= (uint16_t)(I2S_Mode_Select | (uint16_t)(I2S_InitStruct->I2S_Mode | \ - (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \ - (uint16_t)I2S_InitStruct->I2S_CPOL)))); - - /* Write to SPIx I2SCFGR */ - SPIx->I2SCFGR = tmpreg; -} - -/** - * @brief Fills each SPI_InitStruct member with its default value. - * @param SPI_InitStruct : pointer to a SPI_InitTypeDef structure which will be initialized. - * @retval None - */ -void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct) -{ -/*--------------- Reset SPI init structure parameters values -----------------*/ - /* Initialize the SPI_Direction member */ - SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex; - /* initialize the SPI_Mode member */ - SPI_InitStruct->SPI_Mode = SPI_Mode_Slave; - /* initialize the SPI_DataSize member */ - SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b; - /* Initialize the SPI_CPOL member */ - SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low; - /* Initialize the SPI_CPHA member */ - SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge; - /* Initialize the SPI_NSS member */ - SPI_InitStruct->SPI_NSS = SPI_NSS_Hard; - /* Initialize the SPI_BaudRatePrescaler member */ - SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; - /* Initialize the SPI_FirstBit member */ - SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB; - /* Initialize the SPI_CRCPolynomial member */ - SPI_InitStruct->SPI_CRCPolynomial = 7; -} - -/** - * @brief Fills each I2S_InitStruct member with its default value. - * @param I2S_InitStruct : pointer to a I2S_InitTypeDef structure which will be initialized. - * @retval None - */ -void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct) -{ -/*--------------- Reset I2S init structure parameters values -----------------*/ - /* Initialize the I2S_Mode member */ - I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx; - - /* Initialize the I2S_Standard member */ - I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips; - - /* Initialize the I2S_DataFormat member */ - I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b; - - /* Initialize the I2S_MCLKOutput member */ - I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable; - - /* Initialize the I2S_AudioFreq member */ - I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default; - - /* Initialize the I2S_CPOL member */ - I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low; -} - -/** - * @brief Enables or disables the specified SPI peripheral. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param NewState: new state of the SPIx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected SPI peripheral */ - SPIx->CR1 |= CR1_SPE_Set; - } - else - { - /* Disable the selected SPI peripheral */ - SPIx->CR1 &= CR1_SPE_Reset; - } -} - -/** - * @brief Enables or disables the specified SPI peripheral (in I2S mode). - * @param SPIx: where x can be 2 or 3 to select the SPI peripheral. - * @param NewState: new state of the SPIx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_23_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected SPI peripheral (in I2S mode) */ - SPIx->I2SCFGR |= I2SCFGR_I2SE_Set; - } - else - { - /* Disable the selected SPI peripheral (in I2S mode) */ - SPIx->I2SCFGR &= I2SCFGR_I2SE_Reset; - } -} - -/** - * @brief Enables or disables the specified SPI/I2S interrupts. - * @param SPIx: where x can be - * - 1, 2 or 3 in SPI mode - * - 2 or 3 in I2S mode - * @param SPI_I2S_IT: specifies the SPI/I2S interrupt source to be enabled or disabled. - * This parameter can be one of the following values: - * @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask - * @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask - * @arg SPI_I2S_IT_ERR: Error interrupt mask - * @param NewState: new state of the specified SPI/I2S interrupt. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState) -{ - uint16_t itpos = 0, itmask = 0 ; - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT)); - - /* Get the SPI/I2S IT index */ - itpos = SPI_I2S_IT >> 4; - - /* Set the IT mask */ - itmask = (uint16_t)1 << (uint16_t)itpos; - - if (NewState != DISABLE) - { - /* Enable the selected SPI/I2S interrupt */ - SPIx->CR2 |= itmask; - } - else - { - /* Disable the selected SPI/I2S interrupt */ - SPIx->CR2 &= (uint16_t)~itmask; - } -} - -/** - * @brief Enables or disables the SPIx/I2Sx DMA interface. - * @param SPIx: where x can be - * - 1, 2 or 3 in SPI mode - * - 2 or 3 in I2S mode - * @param SPI_I2S_DMAReq: specifies the SPI/I2S DMA transfer request to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request - * @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request - * @param NewState: new state of the selected SPI/I2S DMA transfer request. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_SPI_I2S_DMAREQ(SPI_I2S_DMAReq)); - if (NewState != DISABLE) - { - /* Enable the selected SPI/I2S DMA requests */ - SPIx->CR2 |= SPI_I2S_DMAReq; - } - else - { - /* Disable the selected SPI/I2S DMA requests */ - SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq; - } -} - -/** - * @brief Transmits a Data through the SPIx/I2Sx peripheral. - * @param SPIx: where x can be - * - 1, 2 or 3 in SPI mode - * - 2 or 3 in I2S mode - * @param Data : Data to be transmitted. - * @retval None - */ -void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - /* Write in the DR register the data to be sent */ - SPIx->DR = Data; -} - -/** - * @brief Returns the most recent received data by the SPIx/I2Sx peripheral. - * @param SPIx: where x can be - * - 1, 2 or 3 in SPI mode - * - 2 or 3 in I2S mode - * @retval The value of the received data. - */ -uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - /* Return the data in the DR register */ - return SPIx->DR; -} - -/** - * @brief Configures internally by software the NSS pin for the selected SPI. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param SPI_NSSInternalSoft: specifies the SPI NSS internal state. - * This parameter can be one of the following values: - * @arg SPI_NSSInternalSoft_Set: Set NSS pin internally - * @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally - * @retval None - */ -void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft)); - if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset) - { - /* Set NSS pin internally by software */ - SPIx->CR1 |= SPI_NSSInternalSoft_Set; - } - else - { - /* Reset NSS pin internally by software */ - SPIx->CR1 &= SPI_NSSInternalSoft_Reset; - } -} - -/** - * @brief Enables or disables the SS output for the selected SPI. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param NewState: new state of the SPIx SS output. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected SPI SS output */ - SPIx->CR2 |= CR2_SSOE_Set; - } - else - { - /* Disable the selected SPI SS output */ - SPIx->CR2 &= CR2_SSOE_Reset; - } -} - -/** - * @brief Configures the data size for the selected SPI. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param SPI_DataSize: specifies the SPI data size. - * This parameter can be one of the following values: - * @arg SPI_DataSize_16b: Set data frame format to 16bit - * @arg SPI_DataSize_8b: Set data frame format to 8bit - * @retval None - */ -void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_DATASIZE(SPI_DataSize)); - /* Clear DFF bit */ - SPIx->CR1 &= (uint16_t)~SPI_DataSize_16b; - /* Set new DFF bit value */ - SPIx->CR1 |= SPI_DataSize; -} - -/** - * @brief Transmit the SPIx CRC value. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @retval None - */ -void SPI_TransmitCRC(SPI_TypeDef* SPIx) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - /* Enable the selected SPI CRC transmission */ - SPIx->CR1 |= CR1_CRCNext_Set; -} - -/** - * @brief Enables or disables the CRC value calculation of the transfered bytes. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param NewState: new state of the SPIx CRC value calculation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected SPI CRC calculation */ - SPIx->CR1 |= CR1_CRCEN_Set; - } - else - { - /* Disable the selected SPI CRC calculation */ - SPIx->CR1 &= CR1_CRCEN_Reset; - } -} - -/** - * @brief Returns the transmit or the receive CRC register value for the specified SPI. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param SPI_CRC: specifies the CRC register to be read. - * This parameter can be one of the following values: - * @arg SPI_CRC_Tx: Selects Tx CRC register - * @arg SPI_CRC_Rx: Selects Rx CRC register - * @retval The selected CRC register value.. - */ -uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC) -{ - uint16_t crcreg = 0; - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_CRC(SPI_CRC)); - if (SPI_CRC != SPI_CRC_Rx) - { - /* Get the Tx CRC register */ - crcreg = SPIx->TXCRCR; - } - else - { - /* Get the Rx CRC register */ - crcreg = SPIx->RXCRCR; - } - /* Return the selected CRC register */ - return crcreg; -} - -/** - * @brief Returns the CRC Polynomial register value for the specified SPI. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @retval The CRC Polynomial register value. - */ -uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - /* Return the CRC polynomial register */ - return SPIx->CRCPR; -} - -/** - * @brief Selects the data transfer direction in bi-directional mode for the specified SPI. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param SPI_Direction: specifies the data transfer direction in bi-directional mode. - * This parameter can be one of the following values: - * @arg SPI_Direction_Tx: Selects Tx transmission direction - * @arg SPI_Direction_Rx: Selects Rx receive direction - * @retval None - */ -void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_DIRECTION(SPI_Direction)); - if (SPI_Direction == SPI_Direction_Tx) - { - /* Set the Tx only mode */ - SPIx->CR1 |= SPI_Direction_Tx; - } - else - { - /* Set the Rx only mode */ - SPIx->CR1 &= SPI_Direction_Rx; - } -} - -/** - * @brief Checks whether the specified SPI/I2S flag is set or not. - * @param SPIx: where x can be - * - 1, 2 or 3 in SPI mode - * - 2 or 3 in I2S mode - * @param SPI_I2S_FLAG: specifies the SPI/I2S flag to check. - * This parameter can be one of the following values: - * @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag. - * @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag. - * @arg SPI_I2S_FLAG_BSY: Busy flag. - * @arg SPI_I2S_FLAG_OVR: Overrun flag. - * @arg SPI_FLAG_MODF: Mode Fault flag. - * @arg SPI_FLAG_CRCERR: CRC Error flag. - * @arg I2S_FLAG_UDR: Underrun Error flag. - * @arg I2S_FLAG_CHSIDE: Channel Side flag. - * @retval The new state of SPI_I2S_FLAG (SET or RESET). - */ -FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG)); - /* Check the status of the specified SPI/I2S flag */ - if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET) - { - /* SPI_I2S_FLAG is set */ - bitstatus = SET; - } - else - { - /* SPI_I2S_FLAG is reset */ - bitstatus = RESET; - } - /* Return the SPI_I2S_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the SPIx CRC Error (CRCERR) flag. - * @param SPIx: where x can be - * - 1, 2 or 3 in SPI mode - * @param SPI_I2S_FLAG: specifies the SPI flag to clear. - * This function clears only CRCERR flag. - * @note - * - OVR (OverRun error) flag is cleared by software sequence: a read - * operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by a read - * operation to SPI_SR register (SPI_I2S_GetFlagStatus()). - * - UDR (UnderRun error) flag is cleared by a read operation to - * SPI_SR register (SPI_I2S_GetFlagStatus()). - * - MODF (Mode Fault) flag is cleared by software sequence: a read/write - * operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by a - * write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI). - * @retval None - */ -void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_I2S_CLEAR_FLAG(SPI_I2S_FLAG)); - - /* Clear the selected SPI CRC Error (CRCERR) flag */ - SPIx->SR = (uint16_t)~SPI_I2S_FLAG; -} - -/** - * @brief Checks whether the specified SPI/I2S interrupt has occurred or not. - * @param SPIx: where x can be - * - 1, 2 or 3 in SPI mode - * - 2 or 3 in I2S mode - * @param SPI_I2S_IT: specifies the SPI/I2S interrupt source to check. - * This parameter can be one of the following values: - * @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt. - * @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt. - * @arg SPI_I2S_IT_OVR: Overrun interrupt. - * @arg SPI_IT_MODF: Mode Fault interrupt. - * @arg SPI_IT_CRCERR: CRC Error interrupt. - * @arg I2S_IT_UDR: Underrun Error interrupt. - * @retval The new state of SPI_I2S_IT (SET or RESET). - */ -ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT) -{ - ITStatus bitstatus = RESET; - uint16_t itpos = 0, itmask = 0, enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT)); - - /* Get the SPI/I2S IT index */ - itpos = 0x01 << (SPI_I2S_IT & 0x0F); - - /* Get the SPI/I2S IT mask */ - itmask = SPI_I2S_IT >> 4; - - /* Set the IT mask */ - itmask = 0x01 << itmask; - - /* Get the SPI_I2S_IT enable bit status */ - enablestatus = (SPIx->CR2 & itmask) ; - - /* Check the status of the specified SPI/I2S interrupt */ - if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus) - { - /* SPI_I2S_IT is set */ - bitstatus = SET; - } - else - { - /* SPI_I2S_IT is reset */ - bitstatus = RESET; - } - /* Return the SPI_I2S_IT status */ - return bitstatus; -} - -/** - * @brief Clears the SPIx CRC Error (CRCERR) interrupt pending bit. - * @param SPIx: where x can be - * - 1, 2 or 3 in SPI mode - * @param SPI_I2S_IT: specifies the SPI interrupt pending bit to clear. - * This function clears only CRCERR intetrrupt pending bit. - * @note - * - OVR (OverRun Error) interrupt pending bit is cleared by software - * sequence: a read operation to SPI_DR register (SPI_I2S_ReceiveData()) - * followed by a read operation to SPI_SR register (SPI_I2S_GetITStatus()). - * - UDR (UnderRun Error) interrupt pending bit is cleared by a read - * operation to SPI_SR register (SPI_I2S_GetITStatus()). - * - MODF (Mode Fault) interrupt pending bit is cleared by software sequence: - * a read/write operation to SPI_SR register (SPI_I2S_GetITStatus()) - * followed by a write operation to SPI_CR1 register (SPI_Cmd() to enable - * the SPI). - * @retval None - */ -void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT) -{ - uint16_t itpos = 0; - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_I2S_CLEAR_IT(SPI_I2S_IT)); - - /* Get the SPI IT index */ - itpos = 0x01 << (SPI_I2S_IT & 0x0F); - - /* Clear the selected SPI CRC Error (CRCERR) interrupt pending bit */ - SPIx->SR = (uint16_t)~itpos; -} -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_tim.c b/example/libs_stm/src/stm32f10x/stm32f10x_tim.c deleted file mode 100644 index c626dca35..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_tim.c +++ /dev/null @@ -1,2834 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_tim.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the TIM firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_tim.h" -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup TIM - * @brief TIM driver modules - * @{ - */ - -/** @defgroup TIM_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup TIM_Private_Defines - * @{ - */ - -/* ---------------------- TIM registers bit mask ------------------------ */ -#define SMCR_ETR_Mask ((uint16_t)0x00FF) -#define CCMR_Offset ((uint16_t)0x0018) -#define CCER_CCE_Set ((uint16_t)0x0001) -#define CCER_CCNE_Set ((uint16_t)0x0004) - -/** - * @} - */ - -/** @defgroup TIM_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup TIM_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup TIM_Private_FunctionPrototypes - * @{ - */ - -static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter); -static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter); -static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter); -static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter); -/** - * @} - */ - -/** @defgroup TIM_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup TIM_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup TIM_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup TIM_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the TIMx peripheral registers to their default reset values. - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @retval None - */ -void TIM_DeInit(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - - if (TIMx == TIM1) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, DISABLE); - } - else if (TIMx == TIM2) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, DISABLE); - } - else if (TIMx == TIM3) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, DISABLE); - } - else if (TIMx == TIM4) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, DISABLE); - } - else if (TIMx == TIM5) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, DISABLE); - } - else if (TIMx == TIM6) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, DISABLE); - } - else if (TIMx == TIM7) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, DISABLE); - } - else if (TIMx == TIM8) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, DISABLE); - } - else if (TIMx == TIM9) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, DISABLE); - } - else if (TIMx == TIM10) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, DISABLE); - } - else if (TIMx == TIM11) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, DISABLE); - } - else if (TIMx == TIM12) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, DISABLE); - } - else if (TIMx == TIM13) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, DISABLE); - } - else if (TIMx == TIM14) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, DISABLE); - } - else if (TIMx == TIM15) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM15, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM15, DISABLE); - } - else if (TIMx == TIM16) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM16, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM16, DISABLE); - } - else - { - if (TIMx == TIM17) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM17, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM17, DISABLE); - } - } -} - -/** - * @brief Initializes the TIMx Time Base Unit peripheral according to - * the specified parameters in the TIM_TimeBaseInitStruct. - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef - * structure that contains the configuration information for the specified TIM peripheral. - * @retval None - */ -void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) -{ - uint16_t tmpcr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode)); - assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision)); - - tmpcr1 = TIMx->CR1; - - if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM2) || (TIMx == TIM3)|| - (TIMx == TIM4) || (TIMx == TIM5)) - { - /* Select the Counter Mode */ - tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS))); - tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode; - } - - if((TIMx != TIM6) && (TIMx != TIM7)) - { - /* Set the clock division */ - tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD)); - tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision; - } - - TIMx->CR1 = tmpcr1; - - /* Set the Autoreload value */ - TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ; - - /* Set the Prescaler value */ - TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler; - - if ((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM15)|| (TIMx == TIM16) || (TIMx == TIM17)) - { - /* Set the Repetition Counter value */ - TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter; - } - - /* Generate an update event to reload the Prescaler and the Repetition counter - values immediately */ - TIMx->EGR = TIM_PSCReloadMode_Immediate; -} - -/** - * @brief Initializes the TIMx Channel1 according to the specified - * parameters in the TIM_OCInitStruct. - * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. - * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure - * that contains the configuration information for the specified TIM peripheral. - * @retval None - */ -void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST8_PERIPH(TIMx)); - assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); - assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); - /* Disable the Channel 1: Reset the CC1E Bit */ - TIMx->CCER &= (uint16_t)(~(uint16_t)TIM_CCER_CC1E); - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - /* Get the TIMx CR2 register value */ - tmpcr2 = TIMx->CR2; - - /* Get the TIMx CCMR1 register value */ - tmpccmrx = TIMx->CCMR1; - - /* Reset the Output Compare Mode Bits */ - tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_OC1M)); - tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_CC1S)); - - /* Select the Output Compare Mode */ - tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; - - /* Reset the Output Polarity level */ - tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1P)); - /* Set the Output Compare Polarity */ - tmpccer |= TIM_OCInitStruct->TIM_OCPolarity; - - /* Set the Output State */ - tmpccer |= TIM_OCInitStruct->TIM_OutputState; - - if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM15)|| - (TIMx == TIM16)|| (TIMx == TIM17)) - { - assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); - assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); - assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); - assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); - - /* Reset the Output N Polarity level */ - tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1NP)); - /* Set the Output N Polarity */ - tmpccer |= TIM_OCInitStruct->TIM_OCNPolarity; - - /* Reset the Output N State */ - tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1NE)); - /* Set the Output N State */ - tmpccer |= TIM_OCInitStruct->TIM_OutputNState; - - /* Reset the Ouput Compare and Output Compare N IDLE State */ - tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS1)); - tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS1N)); - - /* Set the Output Idle state */ - tmpcr2 |= TIM_OCInitStruct->TIM_OCIdleState; - /* Set the Output N Idle state */ - tmpcr2 |= TIM_OCInitStruct->TIM_OCNIdleState; - } - /* Write to TIMx CR2 */ - TIMx->CR2 = tmpcr2; - - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmrx; - - /* Set the Capture Compare Register value */ - TIMx->CCR1 = TIM_OCInitStruct->TIM_Pulse; - - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Initializes the TIMx Channel2 according to the specified - * parameters in the TIM_OCInitStruct. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select - * the TIM peripheral. - * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure - * that contains the configuration information for the specified TIM peripheral. - * @retval None - */ -void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); - assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); - /* Disable the Channel 2: Reset the CC2E Bit */ - TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC2E)); - - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - /* Get the TIMx CR2 register value */ - tmpcr2 = TIMx->CR2; - - /* Get the TIMx CCMR1 register value */ - tmpccmrx = TIMx->CCMR1; - - /* Reset the Output Compare mode and Capture/Compare selection Bits */ - tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_OC2M)); - tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S)); - - /* Select the Output Compare Mode */ - tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8); - - /* Reset the Output Polarity level */ - tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2P)); - /* Set the Output Compare Polarity */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 4); - - /* Set the Output State */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 4); - - if((TIMx == TIM1) || (TIMx == TIM8)) - { - assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); - assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); - assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); - assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); - - /* Reset the Output N Polarity level */ - tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2NP)); - /* Set the Output N Polarity */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 4); - - /* Reset the Output N State */ - tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2NE)); - /* Set the Output N State */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 4); - - /* Reset the Ouput Compare and Output Compare N IDLE State */ - tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS2)); - tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS2N)); - - /* Set the Output Idle state */ - tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 2); - /* Set the Output N Idle state */ - tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 2); - } - /* Write to TIMx CR2 */ - TIMx->CR2 = tmpcr2; - - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmrx; - - /* Set the Capture Compare Register value */ - TIMx->CCR2 = TIM_OCInitStruct->TIM_Pulse; - - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Initializes the TIMx Channel3 according to the specified - * parameters in the TIM_OCInitStruct. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure - * that contains the configuration information for the specified TIM peripheral. - * @retval None - */ -void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); - assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); - /* Disable the Channel 2: Reset the CC2E Bit */ - TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC3E)); - - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - /* Get the TIMx CR2 register value */ - tmpcr2 = TIMx->CR2; - - /* Get the TIMx CCMR2 register value */ - tmpccmrx = TIMx->CCMR2; - - /* Reset the Output Compare mode and Capture/Compare selection Bits */ - tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_OC3M)); - tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_CC3S)); - /* Select the Output Compare Mode */ - tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; - - /* Reset the Output Polarity level */ - tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3P)); - /* Set the Output Compare Polarity */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 8); - - /* Set the Output State */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 8); - - if((TIMx == TIM1) || (TIMx == TIM8)) - { - assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); - assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); - assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); - assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); - - /* Reset the Output N Polarity level */ - tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3NP)); - /* Set the Output N Polarity */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 8); - /* Reset the Output N State */ - tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3NE)); - - /* Set the Output N State */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 8); - /* Reset the Ouput Compare and Output Compare N IDLE State */ - tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS3)); - tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS3N)); - /* Set the Output Idle state */ - tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 4); - /* Set the Output N Idle state */ - tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 4); - } - /* Write to TIMx CR2 */ - TIMx->CR2 = tmpcr2; - - /* Write to TIMx CCMR2 */ - TIMx->CCMR2 = tmpccmrx; - - /* Set the Capture Compare Register value */ - TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse; - - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Initializes the TIMx Channel4 according to the specified - * parameters in the TIM_OCInitStruct. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure - * that contains the configuration information for the specified TIM peripheral. - * @retval None - */ -void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); - assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); - /* Disable the Channel 2: Reset the CC4E Bit */ - TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC4E)); - - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - /* Get the TIMx CR2 register value */ - tmpcr2 = TIMx->CR2; - - /* Get the TIMx CCMR2 register value */ - tmpccmrx = TIMx->CCMR2; - - /* Reset the Output Compare mode and Capture/Compare selection Bits */ - tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_OC4M)); - tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_CC4S)); - - /* Select the Output Compare Mode */ - tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8); - - /* Reset the Output Polarity level */ - tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC4P)); - /* Set the Output Compare Polarity */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 12); - - /* Set the Output State */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 12); - - if((TIMx == TIM1) || (TIMx == TIM8)) - { - assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); - /* Reset the Ouput Compare IDLE State */ - tmpcr2 &= (uint16_t)(~((uint16_t)TIM_CR2_OIS4)); - /* Set the Output Idle state */ - tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 6); - } - /* Write to TIMx CR2 */ - TIMx->CR2 = tmpcr2; - - /* Write to TIMx CCMR2 */ - TIMx->CCMR2 = tmpccmrx; - - /* Set the Capture Compare Register value */ - TIMx->CCR4 = TIM_OCInitStruct->TIM_Pulse; - - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Initializes the TIM peripheral according to the specified - * parameters in the TIM_ICInitStruct. - * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. - * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure - * that contains the configuration information for the specified TIM peripheral. - * @retval None - */ -void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) -{ - /* Check the parameters */ - assert_param(IS_TIM_CHANNEL(TIM_ICInitStruct->TIM_Channel)); - assert_param(IS_TIM_IC_POLARITY(TIM_ICInitStruct->TIM_ICPolarity)); - assert_param(IS_TIM_IC_SELECTION(TIM_ICInitStruct->TIM_ICSelection)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICInitStruct->TIM_ICPrescaler)); - assert_param(IS_TIM_IC_FILTER(TIM_ICInitStruct->TIM_ICFilter)); - - if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) - { - assert_param(IS_TIM_LIST8_PERIPH(TIMx)); - /* TI1 Configuration */ - TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, - TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } - else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_2) - { - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - /* TI2 Configuration */ - TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, - TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } - else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_3) - { - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - /* TI3 Configuration */ - TI3_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, - TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC3Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } - else - { - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - /* TI4 Configuration */ - TI4_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, - TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC4Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } -} - -/** - * @brief Configures the TIM peripheral according to the specified - * parameters in the TIM_ICInitStruct to measure an external PWM signal. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. - * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure - * that contains the configuration information for the specified TIM peripheral. - * @retval None - */ -void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) -{ - uint16_t icoppositepolarity = TIM_ICPolarity_Rising; - uint16_t icoppositeselection = TIM_ICSelection_DirectTI; - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - /* Select the Opposite Input Polarity */ - if (TIM_ICInitStruct->TIM_ICPolarity == TIM_ICPolarity_Rising) - { - icoppositepolarity = TIM_ICPolarity_Falling; - } - else - { - icoppositepolarity = TIM_ICPolarity_Rising; - } - /* Select the Opposite Input */ - if (TIM_ICInitStruct->TIM_ICSelection == TIM_ICSelection_DirectTI) - { - icoppositeselection = TIM_ICSelection_IndirectTI; - } - else - { - icoppositeselection = TIM_ICSelection_DirectTI; - } - if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) - { - /* TI1 Configuration */ - TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - /* TI2 Configuration */ - TI2_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } - else - { - /* TI2 Configuration */ - TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - /* TI1 Configuration */ - TI1_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } -} - -/** - * @brief Configures the: Break feature, dead time, Lock level, the OSSI, - * the OSSR State and the AOE(automatic output enable). - * @param TIMx: where x can be 1 or 8 to select the TIM - * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure that - * contains the BDTR Register configuration information for the TIM peripheral. - * @retval None - */ -void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_OSSR_STATE(TIM_BDTRInitStruct->TIM_OSSRState)); - assert_param(IS_TIM_OSSI_STATE(TIM_BDTRInitStruct->TIM_OSSIState)); - assert_param(IS_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->TIM_LOCKLevel)); - assert_param(IS_TIM_BREAK_STATE(TIM_BDTRInitStruct->TIM_Break)); - assert_param(IS_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->TIM_BreakPolarity)); - assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->TIM_AutomaticOutput)); - /* Set the Lock level, the Break enable Bit and the Ploarity, the OSSR State, - the OSSI State, the dead time value and the Automatic Output Enable Bit */ - TIMx->BDTR = (uint32_t)TIM_BDTRInitStruct->TIM_OSSRState | TIM_BDTRInitStruct->TIM_OSSIState | - TIM_BDTRInitStruct->TIM_LOCKLevel | TIM_BDTRInitStruct->TIM_DeadTime | - TIM_BDTRInitStruct->TIM_Break | TIM_BDTRInitStruct->TIM_BreakPolarity | - TIM_BDTRInitStruct->TIM_AutomaticOutput; -} - -/** - * @brief Fills each TIM_TimeBaseInitStruct member with its default value. - * @param TIM_TimeBaseInitStruct : pointer to a TIM_TimeBaseInitTypeDef - * structure which will be initialized. - * @retval None - */ -void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) -{ - /* Set the default configuration */ - TIM_TimeBaseInitStruct->TIM_Period = 0xFFFF; - TIM_TimeBaseInitStruct->TIM_Prescaler = 0x0000; - TIM_TimeBaseInitStruct->TIM_ClockDivision = TIM_CKD_DIV1; - TIM_TimeBaseInitStruct->TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseInitStruct->TIM_RepetitionCounter = 0x0000; -} - -/** - * @brief Fills each TIM_OCInitStruct member with its default value. - * @param TIM_OCInitStruct : pointer to a TIM_OCInitTypeDef structure which will - * be initialized. - * @retval None - */ -void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - /* Set the default configuration */ - TIM_OCInitStruct->TIM_OCMode = TIM_OCMode_Timing; - TIM_OCInitStruct->TIM_OutputState = TIM_OutputState_Disable; - TIM_OCInitStruct->TIM_OutputNState = TIM_OutputNState_Disable; - TIM_OCInitStruct->TIM_Pulse = 0x0000; - TIM_OCInitStruct->TIM_OCPolarity = TIM_OCPolarity_High; - TIM_OCInitStruct->TIM_OCNPolarity = TIM_OCPolarity_High; - TIM_OCInitStruct->TIM_OCIdleState = TIM_OCIdleState_Reset; - TIM_OCInitStruct->TIM_OCNIdleState = TIM_OCNIdleState_Reset; -} - -/** - * @brief Fills each TIM_ICInitStruct member with its default value. - * @param TIM_ICInitStruct : pointer to a TIM_ICInitTypeDef structure which will - * be initialized. - * @retval None - */ -void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct) -{ - /* Set the default configuration */ - TIM_ICInitStruct->TIM_Channel = TIM_Channel_1; - TIM_ICInitStruct->TIM_ICPolarity = TIM_ICPolarity_Rising; - TIM_ICInitStruct->TIM_ICSelection = TIM_ICSelection_DirectTI; - TIM_ICInitStruct->TIM_ICPrescaler = TIM_ICPSC_DIV1; - TIM_ICInitStruct->TIM_ICFilter = 0x00; -} - -/** - * @brief Fills each TIM_BDTRInitStruct member with its default value. - * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure which - * will be initialized. - * @retval None - */ -void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct) -{ - /* Set the default configuration */ - TIM_BDTRInitStruct->TIM_OSSRState = TIM_OSSRState_Disable; - TIM_BDTRInitStruct->TIM_OSSIState = TIM_OSSIState_Disable; - TIM_BDTRInitStruct->TIM_LOCKLevel = TIM_LOCKLevel_OFF; - TIM_BDTRInitStruct->TIM_DeadTime = 0x00; - TIM_BDTRInitStruct->TIM_Break = TIM_Break_Disable; - TIM_BDTRInitStruct->TIM_BreakPolarity = TIM_BreakPolarity_Low; - TIM_BDTRInitStruct->TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; -} - -/** - * @brief Enables or disables the specified TIM peripheral. - * @param TIMx: where x can be 1 to 17 to select the TIMx peripheral. - * @param NewState: new state of the TIMx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the TIM Counter */ - TIMx->CR1 |= TIM_CR1_CEN; - } - else - { - /* Disable the TIM Counter */ - TIMx->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN)); - } -} - -/** - * @brief Enables or disables the TIM peripheral Main Outputs. - * @param TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIMx peripheral. - * @param NewState: new state of the TIM peripheral Main Outputs. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the TIM Main Output */ - TIMx->BDTR |= TIM_BDTR_MOE; - } - else - { - /* Disable the TIM Main Output */ - TIMx->BDTR &= (uint16_t)(~((uint16_t)TIM_BDTR_MOE)); - } -} - -/** - * @brief Enables or disables the specified TIM interrupts. - * @param TIMx: where x can be 1 to 17 to select the TIMx peripheral. - * @param TIM_IT: specifies the TIM interrupts sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg TIM_IT_Update: TIM update Interrupt source - * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source - * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source - * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source - * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source - * @arg TIM_IT_COM: TIM Commutation Interrupt source - * @arg TIM_IT_Trigger: TIM Trigger Interrupt source - * @arg TIM_IT_Break: TIM Break Interrupt source - * @note - * - TIM6 and TIM7 can only generate an update interrupt. - * - TIM9, TIM12 and TIM15 can have only TIM_IT_Update, TIM_IT_CC1, - * TIM_IT_CC2 or TIM_IT_Trigger. - * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1. - * - TIM_IT_Break is used only with TIM1, TIM8 and TIM15. - * - TIM_IT_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17. - * @param NewState: new state of the TIM interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_IT(TIM_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the Interrupt sources */ - TIMx->DIER |= TIM_IT; - } - else - { - /* Disable the Interrupt sources */ - TIMx->DIER &= (uint16_t)~TIM_IT; - } -} - -/** - * @brief Configures the TIMx event to be generate by software. - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @param TIM_EventSource: specifies the event source. - * This parameter can be one or more of the following values: - * @arg TIM_EventSource_Update: Timer update Event source - * @arg TIM_EventSource_CC1: Timer Capture Compare 1 Event source - * @arg TIM_EventSource_CC2: Timer Capture Compare 2 Event source - * @arg TIM_EventSource_CC3: Timer Capture Compare 3 Event source - * @arg TIM_EventSource_CC4: Timer Capture Compare 4 Event source - * @arg TIM_EventSource_COM: Timer COM event source - * @arg TIM_EventSource_Trigger: Timer Trigger Event source - * @arg TIM_EventSource_Break: Timer Break event source - * @note - * - TIM6 and TIM7 can only generate an update event. - * - TIM_EventSource_COM and TIM_EventSource_Break are used only with TIM1 and TIM8. - * @retval None - */ -void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_EVENT_SOURCE(TIM_EventSource)); - - /* Set the event sources */ - TIMx->EGR = TIM_EventSource; -} - -/** - * @brief Configures the TIMxs DMA interface. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 15, 16 or 17 to select - * the TIM peripheral. - * @param TIM_DMABase: DMA Base address. - * This parameter can be one of the following values: - * @arg TIM_DMABase_CR, TIM_DMABase_CR2, TIM_DMABase_SMCR, - * TIM_DMABase_DIER, TIM1_DMABase_SR, TIM_DMABase_EGR, - * TIM_DMABase_CCMR1, TIM_DMABase_CCMR2, TIM_DMABase_CCER, - * TIM_DMABase_CNT, TIM_DMABase_PSC, TIM_DMABase_ARR, - * TIM_DMABase_RCR, TIM_DMABase_CCR1, TIM_DMABase_CCR2, - * TIM_DMABase_CCR3, TIM_DMABase_CCR4, TIM_DMABase_BDTR, - * TIM_DMABase_DCR. - * @param TIM_DMABurstLength: DMA Burst length. - * This parameter can be one value between: - * TIM_DMABurstLength_1Byte and TIM_DMABurstLength_18Bytes. - * @retval None - */ -void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST4_PERIPH(TIMx)); - assert_param(IS_TIM_DMA_BASE(TIM_DMABase)); - assert_param(IS_TIM_DMA_LENGTH(TIM_DMABurstLength)); - /* Set the DMA Base and the DMA Burst Length */ - TIMx->DCR = TIM_DMABase | TIM_DMABurstLength; -} - -/** - * @brief Enables or disables the TIMxs DMA Requests. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 15, 16 or 17 - * to select the TIM peripheral. - * @param TIM_DMASource: specifies the DMA Request sources. - * This parameter can be any combination of the following values: - * @arg TIM_DMA_Update: TIM update Interrupt source - * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source - * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source - * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source - * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source - * @arg TIM_DMA_COM: TIM Commutation DMA source - * @arg TIM_DMA_Trigger: TIM Trigger DMA source - * @param NewState: new state of the DMA Request sources. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST9_PERIPH(TIMx)); - assert_param(IS_TIM_DMA_SOURCE(TIM_DMASource)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the DMA sources */ - TIMx->DIER |= TIM_DMASource; - } - else - { - /* Disable the DMA sources */ - TIMx->DIER &= (uint16_t)~TIM_DMASource; - } -} - -/** - * @brief Configures the TIMx interrnal Clock - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 - * to select the TIM peripheral. - * @retval None - */ -void TIM_InternalClockConfig(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - /* Disable slave mode to clock the prescaler directly with the internal clock */ - TIMx->SMCR &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS)); -} - -/** - * @brief Configures the TIMx Internal Trigger as External Clock - * @param TIMx: where x can be 1, 2, 3, 4, 5, 9, 12 or 15 to select the TIM peripheral. - * @param TIM_ITRSource: Trigger source. - * This parameter can be one of the following values: - * @param TIM_TS_ITR0: Internal Trigger 0 - * @param TIM_TS_ITR1: Internal Trigger 1 - * @param TIM_TS_ITR2: Internal Trigger 2 - * @param TIM_TS_ITR3: Internal Trigger 3 - * @retval None - */ -void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - assert_param(IS_TIM_INTERNAL_TRIGGER_SELECTION(TIM_InputTriggerSource)); - /* Select the Internal Trigger */ - TIM_SelectInputTrigger(TIMx, TIM_InputTriggerSource); - /* Select the External clock mode1 */ - TIMx->SMCR |= TIM_SlaveMode_External1; -} - -/** - * @brief Configures the TIMx Trigger as External Clock - * @param TIMx: where x can be 1, 2, 3, 4, 5, 9, 12 or 15 to select the TIM peripheral. - * @param TIM_TIxExternalCLKSource: Trigger source. - * This parameter can be one of the following values: - * @arg TIM_TIxExternalCLK1Source_TI1ED: TI1 Edge Detector - * @arg TIM_TIxExternalCLK1Source_TI1: Filtered Timer Input 1 - * @arg TIM_TIxExternalCLK1Source_TI2: Filtered Timer Input 2 - * @param TIM_ICPolarity: specifies the TIx Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @param ICFilter : specifies the filter value. - * This parameter must be a value between 0x0 and 0xF. - * @retval None - */ -void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, - uint16_t TIM_ICPolarity, uint16_t ICFilter) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - assert_param(IS_TIM_TIXCLK_SOURCE(TIM_TIxExternalCLKSource)); - assert_param(IS_TIM_IC_POLARITY(TIM_ICPolarity)); - assert_param(IS_TIM_IC_FILTER(ICFilter)); - /* Configure the Timer Input Clock Source */ - if (TIM_TIxExternalCLKSource == TIM_TIxExternalCLK1Source_TI2) - { - TI2_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); - } - else - { - TI1_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); - } - /* Select the Trigger source */ - TIM_SelectInputTrigger(TIMx, TIM_TIxExternalCLKSource); - /* Select the External clock mode1 */ - TIMx->SMCR |= TIM_SlaveMode_External1; -} - -/** - * @brief Configures the External clock Mode1 - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. - * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. - * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. - * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. - * @param TIM_ExtTRGPolarity: The external Trigger Polarity. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. - * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. - * @param ExtTRGFilter: External Trigger Filter. - * This parameter must be a value between 0x00 and 0x0F - * @retval None - */ -void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, - uint16_t ExtTRGFilter) -{ - uint16_t tmpsmcr = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); - assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); - assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); - /* Configure the ETR Clock source */ - TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); - - /* Get the TIMx SMCR register value */ - tmpsmcr = TIMx->SMCR; - /* Reset the SMS Bits */ - tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS)); - /* Select the External clock mode1 */ - tmpsmcr |= TIM_SlaveMode_External1; - /* Select the Trigger selection : ETRF */ - tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS)); - tmpsmcr |= TIM_TS_ETRF; - /* Write to TIMx SMCR */ - TIMx->SMCR = tmpsmcr; -} - -/** - * @brief Configures the External clock Mode2 - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. - * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. - * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. - * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. - * @param TIM_ExtTRGPolarity: The external Trigger Polarity. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. - * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. - * @param ExtTRGFilter: External Trigger Filter. - * This parameter must be a value between 0x00 and 0x0F - * @retval None - */ -void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, - uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); - assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); - assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); - /* Configure the ETR Clock source */ - TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); - /* Enable the External clock mode2 */ - TIMx->SMCR |= TIM_SMCR_ECE; -} - -/** - * @brief Configures the TIMx External Trigger (ETR). - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. - * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. - * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. - * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. - * @param TIM_ExtTRGPolarity: The external Trigger Polarity. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. - * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. - * @param ExtTRGFilter: External Trigger Filter. - * This parameter must be a value between 0x00 and 0x0F - * @retval None - */ -void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, - uint16_t ExtTRGFilter) -{ - uint16_t tmpsmcr = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); - assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); - assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); - tmpsmcr = TIMx->SMCR; - /* Reset the ETR Bits */ - tmpsmcr &= SMCR_ETR_Mask; - /* Set the Prescaler, the Filter value and the Polarity */ - tmpsmcr |= (uint16_t)(TIM_ExtTRGPrescaler | (uint16_t)(TIM_ExtTRGPolarity | (uint16_t)(ExtTRGFilter << (uint16_t)8))); - /* Write to TIMx SMCR */ - TIMx->SMCR = tmpsmcr; -} - -/** - * @brief Configures the TIMx Prescaler. - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @param Prescaler: specifies the Prescaler Register value - * @param TIM_PSCReloadMode: specifies the TIM Prescaler Reload mode - * This parameter can be one of the following values: - * @arg TIM_PSCReloadMode_Update: The Prescaler is loaded at the update event. - * @arg TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediately. - * @retval None - */ -void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_PRESCALER_RELOAD(TIM_PSCReloadMode)); - /* Set the Prescaler value */ - TIMx->PSC = Prescaler; - /* Set or reset the UG Bit */ - TIMx->EGR = TIM_PSCReloadMode; -} - -/** - * @brief Specifies the TIMx Counter Mode to be used. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_CounterMode: specifies the Counter Mode to be used - * This parameter can be one of the following values: - * @arg TIM_CounterMode_Up: TIM Up Counting Mode - * @arg TIM_CounterMode_Down: TIM Down Counting Mode - * @arg TIM_CounterMode_CenterAligned1: TIM Center Aligned Mode1 - * @arg TIM_CounterMode_CenterAligned2: TIM Center Aligned Mode2 - * @arg TIM_CounterMode_CenterAligned3: TIM Center Aligned Mode3 - * @retval None - */ -void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode) -{ - uint16_t tmpcr1 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_COUNTER_MODE(TIM_CounterMode)); - tmpcr1 = TIMx->CR1; - /* Reset the CMS and DIR Bits */ - tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS))); - /* Set the Counter Mode */ - tmpcr1 |= TIM_CounterMode; - /* Write to TIMx CR1 register */ - TIMx->CR1 = tmpcr1; -} - -/** - * @brief Selects the Input Trigger source - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. - * @param TIM_InputTriggerSource: The Input Trigger source. - * This parameter can be one of the following values: - * @arg TIM_TS_ITR0: Internal Trigger 0 - * @arg TIM_TS_ITR1: Internal Trigger 1 - * @arg TIM_TS_ITR2: Internal Trigger 2 - * @arg TIM_TS_ITR3: Internal Trigger 3 - * @arg TIM_TS_TI1F_ED: TI1 Edge Detector - * @arg TIM_TS_TI1FP1: Filtered Timer Input 1 - * @arg TIM_TS_TI2FP2: Filtered Timer Input 2 - * @arg TIM_TS_ETRF: External Trigger input - * @retval None - */ -void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource) -{ - uint16_t tmpsmcr = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - assert_param(IS_TIM_TRIGGER_SELECTION(TIM_InputTriggerSource)); - /* Get the TIMx SMCR register value */ - tmpsmcr = TIMx->SMCR; - /* Reset the TS Bits */ - tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS)); - /* Set the Input Trigger source */ - tmpsmcr |= TIM_InputTriggerSource; - /* Write to TIMx SMCR */ - TIMx->SMCR = tmpsmcr; -} - -/** - * @brief Configures the TIMx Encoder Interface. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_EncoderMode: specifies the TIMx Encoder Mode. - * This parameter can be one of the following values: - * @arg TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level. - * @arg TIM_EncoderMode_TI2: Counter counts on TI2FP2 edge depending on TI1FP1 level. - * @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending - * on the level of the other input. - * @param TIM_IC1Polarity: specifies the IC1 Polarity - * This parmeter can be one of the following values: - * @arg TIM_ICPolarity_Falling: IC Falling edge. - * @arg TIM_ICPolarity_Rising: IC Rising edge. - * @param TIM_IC2Polarity: specifies the IC2 Polarity - * This parmeter can be one of the following values: - * @arg TIM_ICPolarity_Falling: IC Falling edge. - * @arg TIM_ICPolarity_Rising: IC Rising edge. - * @retval None - */ -void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, - uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity) -{ - uint16_t tmpsmcr = 0; - uint16_t tmpccmr1 = 0; - uint16_t tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST5_PERIPH(TIMx)); - assert_param(IS_TIM_ENCODER_MODE(TIM_EncoderMode)); - assert_param(IS_TIM_IC_POLARITY(TIM_IC1Polarity)); - assert_param(IS_TIM_IC_POLARITY(TIM_IC2Polarity)); - - /* Get the TIMx SMCR register value */ - tmpsmcr = TIMx->SMCR; - - /* Get the TIMx CCMR1 register value */ - tmpccmr1 = TIMx->CCMR1; - - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - - /* Set the encoder Mode */ - tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS)); - tmpsmcr |= TIM_EncoderMode; - - /* Select the Capture Compare 1 and the Capture Compare 2 as input */ - tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S))); - tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0; - - /* Set the TI1 and the TI2 Polarities */ - tmpccer &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCER_CC1P)) & ((uint16_t)~((uint16_t)TIM_CCER_CC2P))); - tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4)); - - /* Write to TIMx SMCR */ - TIMx->SMCR = tmpsmcr; - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmr1; - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Forces the TIMx output 1 waveform to active or inactive level. - * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. - * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. - * This parameter can be one of the following values: - * @arg TIM_ForcedAction_Active: Force active level on OC1REF - * @arg TIM_ForcedAction_InActive: Force inactive level on OC1REF. - * @retval None - */ -void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) -{ - uint16_t tmpccmr1 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST8_PERIPH(TIMx)); - assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC1M Bits */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1M); - /* Configure The Forced output Mode */ - tmpccmr1 |= TIM_ForcedAction; - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Forces the TIMx output 2 waveform to active or inactive level. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. - * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. - * This parameter can be one of the following values: - * @arg TIM_ForcedAction_Active: Force active level on OC2REF - * @arg TIM_ForcedAction_InActive: Force inactive level on OC2REF. - * @retval None - */ -void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) -{ - uint16_t tmpccmr1 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC2M Bits */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2M); - /* Configure The Forced output Mode */ - tmpccmr1 |= (uint16_t)(TIM_ForcedAction << 8); - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Forces the TIMx output 3 waveform to active or inactive level. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. - * This parameter can be one of the following values: - * @arg TIM_ForcedAction_Active: Force active level on OC3REF - * @arg TIM_ForcedAction_InActive: Force inactive level on OC3REF. - * @retval None - */ -void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) -{ - uint16_t tmpccmr2 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC1M Bits */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3M); - /* Configure The Forced output Mode */ - tmpccmr2 |= TIM_ForcedAction; - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Forces the TIMx output 4 waveform to active or inactive level. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. - * This parameter can be one of the following values: - * @arg TIM_ForcedAction_Active: Force active level on OC4REF - * @arg TIM_ForcedAction_InActive: Force inactive level on OC4REF. - * @retval None - */ -void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) -{ - uint16_t tmpccmr2 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC2M Bits */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4M); - /* Configure The Forced output Mode */ - tmpccmr2 |= (uint16_t)(TIM_ForcedAction << 8); - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Enables or disables TIMx peripheral Preload register on ARR. - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @param NewState: new state of the TIMx peripheral Preload register - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Set the ARR Preload Bit */ - TIMx->CR1 |= TIM_CR1_ARPE; - } - else - { - /* Reset the ARR Preload Bit */ - TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_ARPE); - } -} - -/** - * @brief Selects the TIM peripheral Commutation event. - * @param TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIMx peripheral - * @param NewState: new state of the Commutation event. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Set the COM Bit */ - TIMx->CR2 |= TIM_CR2_CCUS; - } - else - { - /* Reset the COM Bit */ - TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCUS); - } -} - -/** - * @brief Selects the TIMx peripheral Capture Compare DMA source. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 15, 16 or 17 to select - * the TIM peripheral. - * @param NewState: new state of the Capture Compare DMA source - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST4_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Set the CCDS Bit */ - TIMx->CR2 |= TIM_CR2_CCDS; - } - else - { - /* Reset the CCDS Bit */ - TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCDS); - } -} - -/** - * @brief Sets or Resets the TIM peripheral Capture Compare Preload Control bit. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8 or 15 - * to select the TIMx peripheral - * @param NewState: new state of the Capture Compare Preload Control bit - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST5_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Set the CCPC Bit */ - TIMx->CR2 |= TIM_CR2_CCPC; - } - else - { - /* Reset the CCPC Bit */ - TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCPC); - } -} - -/** - * @brief Enables or disables the TIMx peripheral Preload register on CCR1. - * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. - * @param TIM_OCPreload: new state of the TIMx peripheral Preload register - * This parameter can be one of the following values: - * @arg TIM_OCPreload_Enable - * @arg TIM_OCPreload_Disable - * @retval None - */ -void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) -{ - uint16_t tmpccmr1 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST8_PERIPH(TIMx)); - assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC1PE Bit */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1PE); - /* Enable or Disable the Output Compare Preload feature */ - tmpccmr1 |= TIM_OCPreload; - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Enables or disables the TIMx peripheral Preload register on CCR2. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select - * the TIM peripheral. - * @param TIM_OCPreload: new state of the TIMx peripheral Preload register - * This parameter can be one of the following values: - * @arg TIM_OCPreload_Enable - * @arg TIM_OCPreload_Disable - * @retval None - */ -void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) -{ - uint16_t tmpccmr1 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC2PE Bit */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2PE); - /* Enable or Disable the Output Compare Preload feature */ - tmpccmr1 |= (uint16_t)(TIM_OCPreload << 8); - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Enables or disables the TIMx peripheral Preload register on CCR3. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCPreload: new state of the TIMx peripheral Preload register - * This parameter can be one of the following values: - * @arg TIM_OCPreload_Enable - * @arg TIM_OCPreload_Disable - * @retval None - */ -void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) -{ - uint16_t tmpccmr2 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC3PE Bit */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3PE); - /* Enable or Disable the Output Compare Preload feature */ - tmpccmr2 |= TIM_OCPreload; - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Enables or disables the TIMx peripheral Preload register on CCR4. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCPreload: new state of the TIMx peripheral Preload register - * This parameter can be one of the following values: - * @arg TIM_OCPreload_Enable - * @arg TIM_OCPreload_Disable - * @retval None - */ -void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) -{ - uint16_t tmpccmr2 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC4PE Bit */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4PE); - /* Enable or Disable the Output Compare Preload feature */ - tmpccmr2 |= (uint16_t)(TIM_OCPreload << 8); - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Configures the TIMx Output Compare 1 Fast feature. - * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. - * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCFast_Enable: TIM output compare fast enable - * @arg TIM_OCFast_Disable: TIM output compare fast disable - * @retval None - */ -void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) -{ - uint16_t tmpccmr1 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST8_PERIPH(TIMx)); - assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); - /* Get the TIMx CCMR1 register value */ - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC1FE Bit */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1FE); - /* Enable or Disable the Output Compare Fast Bit */ - tmpccmr1 |= TIM_OCFast; - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Configures the TIMx Output Compare 2 Fast feature. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select - * the TIM peripheral. - * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCFast_Enable: TIM output compare fast enable - * @arg TIM_OCFast_Disable: TIM output compare fast disable - * @retval None - */ -void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) -{ - uint16_t tmpccmr1 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); - /* Get the TIMx CCMR1 register value */ - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC2FE Bit */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2FE); - /* Enable or Disable the Output Compare Fast Bit */ - tmpccmr1 |= (uint16_t)(TIM_OCFast << 8); - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Configures the TIMx Output Compare 3 Fast feature. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCFast_Enable: TIM output compare fast enable - * @arg TIM_OCFast_Disable: TIM output compare fast disable - * @retval None - */ -void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) -{ - uint16_t tmpccmr2 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); - /* Get the TIMx CCMR2 register value */ - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC3FE Bit */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3FE); - /* Enable or Disable the Output Compare Fast Bit */ - tmpccmr2 |= TIM_OCFast; - /* Write to TIMx CCMR2 */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Configures the TIMx Output Compare 4 Fast feature. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCFast_Enable: TIM output compare fast enable - * @arg TIM_OCFast_Disable: TIM output compare fast disable - * @retval None - */ -void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) -{ - uint16_t tmpccmr2 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); - /* Get the TIMx CCMR2 register value */ - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC4FE Bit */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4FE); - /* Enable or Disable the Output Compare Fast Bit */ - tmpccmr2 |= (uint16_t)(TIM_OCFast << 8); - /* Write to TIMx CCMR2 */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Clears or safeguards the OCREF1 signal on an external event - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCClear_Enable: TIM Output clear enable - * @arg TIM_OCClear_Disable: TIM Output clear disable - * @retval None - */ -void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) -{ - uint16_t tmpccmr1 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); - - tmpccmr1 = TIMx->CCMR1; - - /* Reset the OC1CE Bit */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1CE); - /* Enable or Disable the Output Compare Clear Bit */ - tmpccmr1 |= TIM_OCClear; - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Clears or safeguards the OCREF2 signal on an external event - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCClear_Enable: TIM Output clear enable - * @arg TIM_OCClear_Disable: TIM Output clear disable - * @retval None - */ -void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) -{ - uint16_t tmpccmr1 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC2CE Bit */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2CE); - /* Enable or Disable the Output Compare Clear Bit */ - tmpccmr1 |= (uint16_t)(TIM_OCClear << 8); - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Clears or safeguards the OCREF3 signal on an external event - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCClear_Enable: TIM Output clear enable - * @arg TIM_OCClear_Disable: TIM Output clear disable - * @retval None - */ -void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) -{ - uint16_t tmpccmr2 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC3CE Bit */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3CE); - /* Enable or Disable the Output Compare Clear Bit */ - tmpccmr2 |= TIM_OCClear; - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Clears or safeguards the OCREF4 signal on an external event - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCClear_Enable: TIM Output clear enable - * @arg TIM_OCClear_Disable: TIM Output clear disable - * @retval None - */ -void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) -{ - uint16_t tmpccmr2 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC4CE Bit */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4CE); - /* Enable or Disable the Output Compare Clear Bit */ - tmpccmr2 |= (uint16_t)(TIM_OCClear << 8); - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Configures the TIMx channel 1 polarity. - * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. - * @param TIM_OCPolarity: specifies the OC1 Polarity - * This parmeter can be one of the following values: - * @arg TIM_OCPolarity_High: Output Compare active high - * @arg TIM_OCPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) -{ - uint16_t tmpccer = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST8_PERIPH(TIMx)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); - tmpccer = TIMx->CCER; - /* Set or Reset the CC1P Bit */ - tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC1P); - tmpccer |= TIM_OCPolarity; - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx Channel 1N polarity. - * @param TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIM peripheral. - * @param TIM_OCNPolarity: specifies the OC1N Polarity - * This parmeter can be one of the following values: - * @arg TIM_OCNPolarity_High: Output Compare active high - * @arg TIM_OCNPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) -{ - uint16_t tmpccer = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); - - tmpccer = TIMx->CCER; - /* Set or Reset the CC1NP Bit */ - tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC1NP); - tmpccer |= TIM_OCNPolarity; - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx channel 2 polarity. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. - * @param TIM_OCPolarity: specifies the OC2 Polarity - * This parmeter can be one of the following values: - * @arg TIM_OCPolarity_High: Output Compare active high - * @arg TIM_OCPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) -{ - uint16_t tmpccer = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); - tmpccer = TIMx->CCER; - /* Set or Reset the CC2P Bit */ - tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC2P); - tmpccer |= (uint16_t)(TIM_OCPolarity << 4); - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx Channel 2N polarity. - * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. - * @param TIM_OCNPolarity: specifies the OC2N Polarity - * This parmeter can be one of the following values: - * @arg TIM_OCNPolarity_High: Output Compare active high - * @arg TIM_OCNPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) -{ - uint16_t tmpccer = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); - - tmpccer = TIMx->CCER; - /* Set or Reset the CC2NP Bit */ - tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC2NP); - tmpccer |= (uint16_t)(TIM_OCNPolarity << 4); - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx channel 3 polarity. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCPolarity: specifies the OC3 Polarity - * This parmeter can be one of the following values: - * @arg TIM_OCPolarity_High: Output Compare active high - * @arg TIM_OCPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) -{ - uint16_t tmpccer = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); - tmpccer = TIMx->CCER; - /* Set or Reset the CC3P Bit */ - tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC3P); - tmpccer |= (uint16_t)(TIM_OCPolarity << 8); - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx Channel 3N polarity. - * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. - * @param TIM_OCNPolarity: specifies the OC3N Polarity - * This parmeter can be one of the following values: - * @arg TIM_OCNPolarity_High: Output Compare active high - * @arg TIM_OCNPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) -{ - uint16_t tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); - - tmpccer = TIMx->CCER; - /* Set or Reset the CC3NP Bit */ - tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC3NP); - tmpccer |= (uint16_t)(TIM_OCNPolarity << 8); - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx channel 4 polarity. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCPolarity: specifies the OC4 Polarity - * This parmeter can be one of the following values: - * @arg TIM_OCPolarity_High: Output Compare active high - * @arg TIM_OCPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) -{ - uint16_t tmpccer = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); - tmpccer = TIMx->CCER; - /* Set or Reset the CC4P Bit */ - tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC4P); - tmpccer |= (uint16_t)(TIM_OCPolarity << 12); - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Enables or disables the TIM Capture Compare Channel x. - * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. - * @param TIM_Channel: specifies the TIM Channel - * This parmeter can be one of the following values: - * @arg TIM_Channel_1: TIM Channel 1 - * @arg TIM_Channel_2: TIM Channel 2 - * @arg TIM_Channel_3: TIM Channel 3 - * @arg TIM_Channel_4: TIM Channel 4 - * @param TIM_CCx: specifies the TIM Channel CCxE bit new state. - * This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable. - * @retval None - */ -void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx) -{ - uint16_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST8_PERIPH(TIMx)); - assert_param(IS_TIM_CHANNEL(TIM_Channel)); - assert_param(IS_TIM_CCX(TIM_CCx)); - - tmp = CCER_CCE_Set << TIM_Channel; - - /* Reset the CCxE Bit */ - TIMx->CCER &= (uint16_t)~ tmp; - - /* Set or reset the CCxE Bit */ - TIMx->CCER |= (uint16_t)(TIM_CCx << TIM_Channel); -} - -/** - * @brief Enables or disables the TIM Capture Compare Channel xN. - * @param TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIM peripheral. - * @param TIM_Channel: specifies the TIM Channel - * This parmeter can be one of the following values: - * @arg TIM_Channel_1: TIM Channel 1 - * @arg TIM_Channel_2: TIM Channel 2 - * @arg TIM_Channel_3: TIM Channel 3 - * @param TIM_CCxN: specifies the TIM Channel CCxNE bit new state. - * This parameter can be: TIM_CCxN_Enable or TIM_CCxN_Disable. - * @retval None - */ -void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN) -{ - uint16_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_COMPLEMENTARY_CHANNEL(TIM_Channel)); - assert_param(IS_TIM_CCXN(TIM_CCxN)); - - tmp = CCER_CCNE_Set << TIM_Channel; - - /* Reset the CCxNE Bit */ - TIMx->CCER &= (uint16_t) ~tmp; - - /* Set or reset the CCxNE Bit */ - TIMx->CCER |= (uint16_t)(TIM_CCxN << TIM_Channel); -} - -/** - * @brief Selects the TIM Ouput Compare Mode. - * @note This function disables the selected channel before changing the Ouput - * Compare Mode. - * User has to enable this channel using TIM_CCxCmd and TIM_CCxNCmd functions. - * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. - * @param TIM_Channel: specifies the TIM Channel - * This parmeter can be one of the following values: - * @arg TIM_Channel_1: TIM Channel 1 - * @arg TIM_Channel_2: TIM Channel 2 - * @arg TIM_Channel_3: TIM Channel 3 - * @arg TIM_Channel_4: TIM Channel 4 - * @param TIM_OCMode: specifies the TIM Output Compare Mode. - * This paramter can be one of the following values: - * @arg TIM_OCMode_Timing - * @arg TIM_OCMode_Active - * @arg TIM_OCMode_Toggle - * @arg TIM_OCMode_PWM1 - * @arg TIM_OCMode_PWM2 - * @arg TIM_ForcedAction_Active - * @arg TIM_ForcedAction_InActive - * @retval None - */ -void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode) -{ - uint32_t tmp = 0; - uint16_t tmp1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST8_PERIPH(TIMx)); - assert_param(IS_TIM_CHANNEL(TIM_Channel)); - assert_param(IS_TIM_OCM(TIM_OCMode)); - - tmp = (uint32_t) TIMx; - tmp += CCMR_Offset; - - tmp1 = CCER_CCE_Set << (uint16_t)TIM_Channel; - - /* Disable the Channel: Reset the CCxE Bit */ - TIMx->CCER &= (uint16_t) ~tmp1; - - if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3)) - { - tmp += (TIM_Channel>>1); - - /* Reset the OCxM bits in the CCMRx register */ - *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC1M); - - /* Configure the OCxM bits in the CCMRx register */ - *(__IO uint32_t *) tmp |= TIM_OCMode; - } - else - { - tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1; - - /* Reset the OCxM bits in the CCMRx register */ - *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2M); - - /* Configure the OCxM bits in the CCMRx register */ - *(__IO uint32_t *) tmp |= (uint16_t)(TIM_OCMode << 8); - } -} - -/** - * @brief Enables or Disables the TIMx Update event. - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @param NewState: new state of the TIMx UDIS bit - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Set the Update Disable Bit */ - TIMx->CR1 |= TIM_CR1_UDIS; - } - else - { - /* Reset the Update Disable Bit */ - TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_UDIS); - } -} - -/** - * @brief Configures the TIMx Update Request Interrupt source. - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @param TIM_UpdateSource: specifies the Update source. - * This parameter can be one of the following values: - * @arg TIM_UpdateSource_Regular: Source of update is the counter overflow/underflow - or the setting of UG bit, or an update generation - through the slave mode controller. - * @arg TIM_UpdateSource_Global: Source of update is counter overflow/underflow. - * @retval None - */ -void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_UPDATE_SOURCE(TIM_UpdateSource)); - if (TIM_UpdateSource != TIM_UpdateSource_Global) - { - /* Set the URS Bit */ - TIMx->CR1 |= TIM_CR1_URS; - } - else - { - /* Reset the URS Bit */ - TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_URS); - } -} - -/** - * @brief Enables or disables the TIMxs Hall sensor interface. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param NewState: new state of the TIMx Hall sensor interface. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Set the TI1S Bit */ - TIMx->CR2 |= TIM_CR2_TI1S; - } - else - { - /* Reset the TI1S Bit */ - TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_TI1S); - } -} - -/** - * @brief Selects the TIMxs One Pulse Mode. - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @param TIM_OPMode: specifies the OPM Mode to be used. - * This parameter can be one of the following values: - * @arg TIM_OPMode_Single - * @arg TIM_OPMode_Repetitive - * @retval None - */ -void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_OPM_MODE(TIM_OPMode)); - /* Reset the OPM Bit */ - TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_OPM); - /* Configure the OPM Mode */ - TIMx->CR1 |= TIM_OPMode; -} - -/** - * @brief Selects the TIMx Trigger Output Mode. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7, 8, 9, 12 or 15 to select the TIM peripheral. - * @param TIM_TRGOSource: specifies the Trigger Output source. - * This paramter can be one of the following values: - * - * - For all TIMx - * @arg TIM_TRGOSource_Reset: The UG bit in the TIM_EGR register is used as the trigger output (TRGO). - * @arg TIM_TRGOSource_Enable: The Counter Enable CEN is used as the trigger output (TRGO). - * @arg TIM_TRGOSource_Update: The update event is selected as the trigger output (TRGO). - * - * - For all TIMx except TIM6 and TIM7 - * @arg TIM_TRGOSource_OC1: The trigger output sends a positive pulse when the CC1IF flag - * is to be set, as soon as a capture or compare match occurs (TRGO). - * @arg TIM_TRGOSource_OC1Ref: OC1REF signal is used as the trigger output (TRGO). - * @arg TIM_TRGOSource_OC2Ref: OC2REF signal is used as the trigger output (TRGO). - * @arg TIM_TRGOSource_OC3Ref: OC3REF signal is used as the trigger output (TRGO). - * @arg TIM_TRGOSource_OC4Ref: OC4REF signal is used as the trigger output (TRGO). - * - * @retval None - */ -void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST7_PERIPH(TIMx)); - assert_param(IS_TIM_TRGO_SOURCE(TIM_TRGOSource)); - /* Reset the MMS Bits */ - TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_MMS); - /* Select the TRGO source */ - TIMx->CR2 |= TIM_TRGOSource; -} - -/** - * @brief Selects the TIMx Slave Mode. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. - * @param TIM_SlaveMode: specifies the Timer Slave Mode. - * This paramter can be one of the following values: - * @arg TIM_SlaveMode_Reset: Rising edge of the selected trigger signal (TRGI) re-initializes - * the counter and triggers an update of the registers. - * @arg TIM_SlaveMode_Gated: The counter clock is enabled when the trigger signal (TRGI) is high. - * @arg TIM_SlaveMode_Trigger: The counter starts at a rising edge of the trigger TRGI. - * @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter. - * @retval None - */ -void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - assert_param(IS_TIM_SLAVE_MODE(TIM_SlaveMode)); - /* Reset the SMS Bits */ - TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_SMS); - /* Select the Slave Mode */ - TIMx->SMCR |= TIM_SlaveMode; -} - -/** - * @brief Sets or Resets the TIMx Master/Slave Mode. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. - * @param TIM_MasterSlaveMode: specifies the Timer Master Slave Mode. - * This paramter can be one of the following values: - * @arg TIM_MasterSlaveMode_Enable: synchronization between the current timer - * and its slaves (through TRGO). - * @arg TIM_MasterSlaveMode_Disable: No action - * @retval None - */ -void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - assert_param(IS_TIM_MSM_STATE(TIM_MasterSlaveMode)); - /* Reset the MSM Bit */ - TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_MSM); - - /* Set or Reset the MSM Bit */ - TIMx->SMCR |= TIM_MasterSlaveMode; -} - -/** - * @brief Sets the TIMx Counter Register value - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @param Counter: specifies the Counter register new value. - * @retval None - */ -void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - /* Set the Counter Register value */ - TIMx->CNT = Counter; -} - -/** - * @brief Sets the TIMx Autoreload Register value - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @param Autoreload: specifies the Autoreload register new value. - * @retval None - */ -void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - /* Set the Autoreload Register value */ - TIMx->ARR = Autoreload; -} - -/** - * @brief Sets the TIMx Capture Compare1 Register value - * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. - * @param Compare1: specifies the Capture Compare1 register new value. - * @retval None - */ -void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST8_PERIPH(TIMx)); - /* Set the Capture Compare1 Register value */ - TIMx->CCR1 = Compare1; -} - -/** - * @brief Sets the TIMx Capture Compare2 Register value - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. - * @param Compare2: specifies the Capture Compare2 register new value. - * @retval None - */ -void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - /* Set the Capture Compare2 Register value */ - TIMx->CCR2 = Compare2; -} - -/** - * @brief Sets the TIMx Capture Compare3 Register value - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param Compare3: specifies the Capture Compare3 register new value. - * @retval None - */ -void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - /* Set the Capture Compare3 Register value */ - TIMx->CCR3 = Compare3; -} - -/** - * @brief Sets the TIMx Capture Compare4 Register value - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param Compare4: specifies the Capture Compare4 register new value. - * @retval None - */ -void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - /* Set the Capture Compare4 Register value */ - TIMx->CCR4 = Compare4; -} - -/** - * @brief Sets the TIMx Input Capture 1 prescaler. - * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. - * @param TIM_ICPSC: specifies the Input Capture1 prescaler new value. - * This parameter can be one of the following values: - * @arg TIM_ICPSC_DIV1: no prescaler - * @arg TIM_ICPSC_DIV2: capture is done once every 2 events - * @arg TIM_ICPSC_DIV4: capture is done once every 4 events - * @arg TIM_ICPSC_DIV8: capture is done once every 8 events - * @retval None - */ -void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST8_PERIPH(TIMx)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); - /* Reset the IC1PSC Bits */ - TIMx->CCMR1 &= (uint16_t)~((uint16_t)TIM_CCMR1_IC1PSC); - /* Set the IC1PSC value */ - TIMx->CCMR1 |= TIM_ICPSC; -} - -/** - * @brief Sets the TIMx Input Capture 2 prescaler. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. - * @param TIM_ICPSC: specifies the Input Capture2 prescaler new value. - * This parameter can be one of the following values: - * @arg TIM_ICPSC_DIV1: no prescaler - * @arg TIM_ICPSC_DIV2: capture is done once every 2 events - * @arg TIM_ICPSC_DIV4: capture is done once every 4 events - * @arg TIM_ICPSC_DIV8: capture is done once every 8 events - * @retval None - */ -void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); - /* Reset the IC2PSC Bits */ - TIMx->CCMR1 &= (uint16_t)~((uint16_t)TIM_CCMR1_IC2PSC); - /* Set the IC2PSC value */ - TIMx->CCMR1 |= (uint16_t)(TIM_ICPSC << 8); -} - -/** - * @brief Sets the TIMx Input Capture 3 prescaler. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ICPSC: specifies the Input Capture3 prescaler new value. - * This parameter can be one of the following values: - * @arg TIM_ICPSC_DIV1: no prescaler - * @arg TIM_ICPSC_DIV2: capture is done once every 2 events - * @arg TIM_ICPSC_DIV4: capture is done once every 4 events - * @arg TIM_ICPSC_DIV8: capture is done once every 8 events - * @retval None - */ -void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); - /* Reset the IC3PSC Bits */ - TIMx->CCMR2 &= (uint16_t)~((uint16_t)TIM_CCMR2_IC3PSC); - /* Set the IC3PSC value */ - TIMx->CCMR2 |= TIM_ICPSC; -} - -/** - * @brief Sets the TIMx Input Capture 4 prescaler. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ICPSC: specifies the Input Capture4 prescaler new value. - * This parameter can be one of the following values: - * @arg TIM_ICPSC_DIV1: no prescaler - * @arg TIM_ICPSC_DIV2: capture is done once every 2 events - * @arg TIM_ICPSC_DIV4: capture is done once every 4 events - * @arg TIM_ICPSC_DIV8: capture is done once every 8 events - * @retval None - */ -void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); - /* Reset the IC4PSC Bits */ - TIMx->CCMR2 &= (uint16_t)~((uint16_t)TIM_CCMR2_IC4PSC); - /* Set the IC4PSC value */ - TIMx->CCMR2 |= (uint16_t)(TIM_ICPSC << 8); -} - -/** - * @brief Sets the TIMx Clock Division value. - * @param TIMx: where x can be 1 to 17 except 6 and 7 to select - * the TIM peripheral. - * @param TIM_CKD: specifies the clock division value. - * This parameter can be one of the following value: - * @arg TIM_CKD_DIV1: TDTS = Tck_tim - * @arg TIM_CKD_DIV2: TDTS = 2*Tck_tim - * @arg TIM_CKD_DIV4: TDTS = 4*Tck_tim - * @retval None - */ -void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST8_PERIPH(TIMx)); - assert_param(IS_TIM_CKD_DIV(TIM_CKD)); - /* Reset the CKD Bits */ - TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_CKD); - /* Set the CKD value */ - TIMx->CR1 |= TIM_CKD; -} - -/** - * @brief Gets the TIMx Input Capture 1 value. - * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. - * @retval Capture Compare 1 Register value. - */ -uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST8_PERIPH(TIMx)); - /* Get the Capture 1 Register value */ - return TIMx->CCR1; -} - -/** - * @brief Gets the TIMx Input Capture 2 value. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. - * @retval Capture Compare 2 Register value. - */ -uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - /* Get the Capture 2 Register value */ - return TIMx->CCR2; -} - -/** - * @brief Gets the TIMx Input Capture 3 value. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @retval Capture Compare 3 Register value. - */ -uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - /* Get the Capture 3 Register value */ - return TIMx->CCR3; -} - -/** - * @brief Gets the TIMx Input Capture 4 value. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @retval Capture Compare 4 Register value. - */ -uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - /* Get the Capture 4 Register value */ - return TIMx->CCR4; -} - -/** - * @brief Gets the TIMx Counter value. - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @retval Counter Register value. - */ -uint16_t TIM_GetCounter(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - /* Get the Counter Register value */ - return TIMx->CNT; -} - -/** - * @brief Gets the TIMx Prescaler value. - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @retval Prescaler Register value. - */ -uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - /* Get the Prescaler Register value */ - return TIMx->PSC; -} - -/** - * @brief Checks whether the specified TIM flag is set or not. - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @param TIM_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg TIM_FLAG_Update: TIM update Flag - * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag - * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag - * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag - * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag - * @arg TIM_FLAG_COM: TIM Commutation Flag - * @arg TIM_FLAG_Trigger: TIM Trigger Flag - * @arg TIM_FLAG_Break: TIM Break Flag - * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag - * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag - * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag - * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag - * @note - * - TIM6 and TIM7 can have only one update flag. - * - TIM9, TIM12 and TIM15 can have only TIM_FLAG_Update, TIM_FLAG_CC1, - * TIM_FLAG_CC2 or TIM_FLAG_Trigger. - * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_FLAG_Update or TIM_FLAG_CC1. - * - TIM_FLAG_Break is used only with TIM1, TIM8 and TIM15. - * - TIM_FLAG_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17. - * @retval The new state of TIM_FLAG (SET or RESET). - */ -FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) -{ - ITStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_GET_FLAG(TIM_FLAG)); - - if ((TIMx->SR & TIM_FLAG) != (uint16_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the TIMx's pending flags. - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @param TIM_FLAG: specifies the flag bit to clear. - * This parameter can be any combination of the following values: - * @arg TIM_FLAG_Update: TIM update Flag - * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag - * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag - * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag - * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag - * @arg TIM_FLAG_COM: TIM Commutation Flag - * @arg TIM_FLAG_Trigger: TIM Trigger Flag - * @arg TIM_FLAG_Break: TIM Break Flag - * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag - * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag - * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag - * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag - * @note - * - TIM6 and TIM7 can have only one update flag. - * - TIM9, TIM12 and TIM15 can have only TIM_FLAG_Update, TIM_FLAG_CC1, - * TIM_FLAG_CC2 or TIM_FLAG_Trigger. - * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_FLAG_Update or TIM_FLAG_CC1. - * - TIM_FLAG_Break is used only with TIM1, TIM8 and TIM15. - * - TIM_FLAG_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17. - * @retval None - */ -void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_CLEAR_FLAG(TIM_FLAG)); - - /* Clear the flags */ - TIMx->SR = (uint16_t)~TIM_FLAG; -} - -/** - * @brief Checks whether the TIM interrupt has occurred or not. - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @param TIM_IT: specifies the TIM interrupt source to check. - * This parameter can be one of the following values: - * @arg TIM_IT_Update: TIM update Interrupt source - * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source - * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source - * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source - * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source - * @arg TIM_IT_COM: TIM Commutation Interrupt source - * @arg TIM_IT_Trigger: TIM Trigger Interrupt source - * @arg TIM_IT_Break: TIM Break Interrupt source - * @note - * - TIM6 and TIM7 can generate only an update interrupt. - * - TIM9, TIM12 and TIM15 can have only TIM_IT_Update, TIM_IT_CC1, - * TIM_IT_CC2 or TIM_IT_Trigger. - * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1. - * - TIM_IT_Break is used only with TIM1, TIM8 and TIM15. - * - TIM_IT_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17. - * @retval The new state of the TIM_IT(SET or RESET). - */ -ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT) -{ - ITStatus bitstatus = RESET; - uint16_t itstatus = 0x0, itenable = 0x0; - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_GET_IT(TIM_IT)); - - itstatus = TIMx->SR & TIM_IT; - - itenable = TIMx->DIER & TIM_IT; - if ((itstatus != (uint16_t)RESET) && (itenable != (uint16_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the TIMx's interrupt pending bits. - * @param TIMx: where x can be 1 to 17 to select the TIM peripheral. - * @param TIM_IT: specifies the pending bit to clear. - * This parameter can be any combination of the following values: - * @arg TIM_IT_Update: TIM1 update Interrupt source - * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source - * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source - * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source - * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source - * @arg TIM_IT_COM: TIM Commutation Interrupt source - * @arg TIM_IT_Trigger: TIM Trigger Interrupt source - * @arg TIM_IT_Break: TIM Break Interrupt source - * @note - * - TIM6 and TIM7 can generate only an update interrupt. - * - TIM9, TIM12 and TIM15 can have only TIM_IT_Update, TIM_IT_CC1, - * TIM_IT_CC2 or TIM_IT_Trigger. - * - TIM10, TIM11, TIM13, TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1. - * - TIM_IT_Break is used only with TIM1, TIM8 and TIM15. - * - TIM_IT_COM is used only with TIM1, TIM8, TIM15, TIM16 and TIM17. - * @retval None - */ -void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_IT(TIM_IT)); - /* Clear the IT pending Bit */ - TIMx->SR = (uint16_t)~TIM_IT; -} - -/** - * @brief Configure the TI1 as Input. - * @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. - * @param TIM_ICPolarity : The Input Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @param TIM_ICSelection: specifies the input to be used. - * This parameter can be one of the following values: - * @arg TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1. - * @arg TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2. - * @arg TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC. - * @param TIM_ICFilter: Specifies the Input Capture Filter. - * This parameter must be a value between 0x00 and 0x0F. - * @retval None - */ -static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter) -{ - uint16_t tmpccmr1 = 0, tmpccer = 0; - /* Disable the Channel 1: Reset the CC1E Bit */ - TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC1E); - tmpccmr1 = TIMx->CCMR1; - tmpccer = TIMx->CCER; - /* Select the Input and set the filter */ - tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & ((uint16_t)~((uint16_t)TIM_CCMR1_IC1F))); - tmpccmr1 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4)); - /* Select the Polarity and set the CC1E Bit */ - tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC1P)); - tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC1E); - /* Write to TIMx CCMR1 and CCER registers */ - TIMx->CCMR1 = tmpccmr1; - TIMx->CCER = tmpccer; -} - -/** - * @brief Configure the TI2 as Input. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral. - * @param TIM_ICPolarity : The Input Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @param TIM_ICSelection: specifies the input to be used. - * This parameter can be one of the following values: - * @arg TIM_ICSelection_DirectTI: TIM Input 2 is selected to be connected to IC2. - * @arg TIM_ICSelection_IndirectTI: TIM Input 2 is selected to be connected to IC1. - * @arg TIM_ICSelection_TRC: TIM Input 2 is selected to be connected to TRC. - * @param TIM_ICFilter: Specifies the Input Capture Filter. - * This parameter must be a value between 0x00 and 0x0F. - * @retval None - */ -static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter) -{ - uint16_t tmpccmr1 = 0, tmpccer = 0, tmp = 0; - /* Disable the Channel 2: Reset the CC2E Bit */ - TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC2E); - tmpccmr1 = TIMx->CCMR1; - tmpccer = TIMx->CCER; - tmp = (uint16_t)(TIM_ICPolarity << 4); - /* Select the Input and set the filter */ - tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC2S)) & ((uint16_t)~((uint16_t)TIM_CCMR1_IC2F))); - tmpccmr1 |= (uint16_t)(TIM_ICFilter << 12); - tmpccmr1 |= (uint16_t)(TIM_ICSelection << 8); - /* Select the Polarity and set the CC2E Bit */ - tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC2P)); - tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC2E); - /* Write to TIMx CCMR1 and CCER registers */ - TIMx->CCMR1 = tmpccmr1 ; - TIMx->CCER = tmpccer; -} - -/** - * @brief Configure the TI3 as Input. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ICPolarity : The Input Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @param TIM_ICSelection: specifies the input to be used. - * This parameter can be one of the following values: - * @arg TIM_ICSelection_DirectTI: TIM Input 3 is selected to be connected to IC3. - * @arg TIM_ICSelection_IndirectTI: TIM Input 3 is selected to be connected to IC4. - * @arg TIM_ICSelection_TRC: TIM Input 3 is selected to be connected to TRC. - * @param TIM_ICFilter: Specifies the Input Capture Filter. - * This parameter must be a value between 0x00 and 0x0F. - * @retval None - */ -static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter) -{ - uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; - /* Disable the Channel 3: Reset the CC3E Bit */ - TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC3E); - tmpccmr2 = TIMx->CCMR2; - tmpccer = TIMx->CCER; - tmp = (uint16_t)(TIM_ICPolarity << 8); - /* Select the Input and set the filter */ - tmpccmr2 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR2_CC3S)) & ((uint16_t)~((uint16_t)TIM_CCMR2_IC3F))); - tmpccmr2 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4)); - /* Select the Polarity and set the CC3E Bit */ - tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC3P)); - tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC3E); - /* Write to TIMx CCMR2 and CCER registers */ - TIMx->CCMR2 = tmpccmr2; - TIMx->CCER = tmpccer; -} - -/** - * @brief Configure the TI1 as Input. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ICPolarity : The Input Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @param TIM_ICSelection: specifies the input to be used. - * This parameter can be one of the following values: - * @arg TIM_ICSelection_DirectTI: TIM Input 4 is selected to be connected to IC4. - * @arg TIM_ICSelection_IndirectTI: TIM Input 4 is selected to be connected to IC3. - * @arg TIM_ICSelection_TRC: TIM Input 4 is selected to be connected to TRC. - * @param TIM_ICFilter: Specifies the Input Capture Filter. - * This parameter must be a value between 0x00 and 0x0F. - * @retval None - */ -static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter) -{ - uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; - - /* Disable the Channel 4: Reset the CC4E Bit */ - TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC4E); - tmpccmr2 = TIMx->CCMR2; - tmpccer = TIMx->CCER; - tmp = (uint16_t)(TIM_ICPolarity << 12); - /* Select the Input and set the filter */ - tmpccmr2 &= (uint16_t)((uint16_t)(~(uint16_t)TIM_CCMR2_CC4S) & ((uint16_t)~((uint16_t)TIM_CCMR2_IC4F))); - tmpccmr2 |= (uint16_t)(TIM_ICSelection << 8); - tmpccmr2 |= (uint16_t)(TIM_ICFilter << 12); - - /* Select the Polarity and set the CC4E Bit */ - tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC4P)); - tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC4E); - /* Write to TIMx CCMR2 and CCER registers */ - TIMx->CCMR2 = tmpccmr2; - TIMx->CCER = tmpccer; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_usart.c b/example/libs_stm/src/stm32f10x/stm32f10x_usart.c deleted file mode 100644 index fa0733e89..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_usart.c +++ /dev/null @@ -1,1054 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_usart.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the USART firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_usart.h" -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup USART - * @brief USART driver modules - * @{ - */ - -/** @defgroup USART_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup USART_Private_Defines - * @{ - */ - -#define CR1_UE_Set ((uint16_t)0x2000) /*!< USART Enable Mask */ -#define CR1_UE_Reset ((uint16_t)0xDFFF) /*!< USART Disable Mask */ - -#define CR1_WAKE_Mask ((uint16_t)0xF7FF) /*!< USART WakeUp Method Mask */ - -#define CR1_RWU_Set ((uint16_t)0x0002) /*!< USART mute mode Enable Mask */ -#define CR1_RWU_Reset ((uint16_t)0xFFFD) /*!< USART mute mode Enable Mask */ -#define CR1_SBK_Set ((uint16_t)0x0001) /*!< USART Break Character send Mask */ -#define CR1_CLEAR_Mask ((uint16_t)0xE9F3) /*!< USART CR1 Mask */ -#define CR2_Address_Mask ((uint16_t)0xFFF0) /*!< USART address Mask */ - -#define CR2_LINEN_Set ((uint16_t)0x4000) /*!< USART LIN Enable Mask */ -#define CR2_LINEN_Reset ((uint16_t)0xBFFF) /*!< USART LIN Disable Mask */ - -#define CR2_LBDL_Mask ((uint16_t)0xFFDF) /*!< USART LIN Break detection Mask */ -#define CR2_STOP_CLEAR_Mask ((uint16_t)0xCFFF) /*!< USART CR2 STOP Bits Mask */ -#define CR2_CLOCK_CLEAR_Mask ((uint16_t)0xF0FF) /*!< USART CR2 Clock Mask */ - -#define CR3_SCEN_Set ((uint16_t)0x0020) /*!< USART SC Enable Mask */ -#define CR3_SCEN_Reset ((uint16_t)0xFFDF) /*!< USART SC Disable Mask */ - -#define CR3_NACK_Set ((uint16_t)0x0010) /*!< USART SC NACK Enable Mask */ -#define CR3_NACK_Reset ((uint16_t)0xFFEF) /*!< USART SC NACK Disable Mask */ - -#define CR3_HDSEL_Set ((uint16_t)0x0008) /*!< USART Half-Duplex Enable Mask */ -#define CR3_HDSEL_Reset ((uint16_t)0xFFF7) /*!< USART Half-Duplex Disable Mask */ - -#define CR3_IRLP_Mask ((uint16_t)0xFFFB) /*!< USART IrDA LowPower mode Mask */ -#define CR3_CLEAR_Mask ((uint16_t)0xFCFF) /*!< USART CR3 Mask */ - -#define CR3_IREN_Set ((uint16_t)0x0002) /*!< USART IrDA Enable Mask */ -#define CR3_IREN_Reset ((uint16_t)0xFFFD) /*!< USART IrDA Disable Mask */ -#define GTPR_LSB_Mask ((uint16_t)0x00FF) /*!< Guard Time Register LSB Mask */ -#define GTPR_MSB_Mask ((uint16_t)0xFF00) /*!< Guard Time Register MSB Mask */ -#define IT_Mask ((uint16_t)0x001F) /*!< USART Interrupt Mask */ - -/* USART OverSampling-8 Mask */ -#define CR1_OVER8_Set ((u16)0x8000) /* USART OVER8 mode Enable Mask */ -#define CR1_OVER8_Reset ((u16)0x7FFF) /* USART OVER8 mode Disable Mask */ - -/* USART One Bit Sampling Mask */ -#define CR3_ONEBITE_Set ((u16)0x0800) /* USART ONEBITE mode Enable Mask */ -#define CR3_ONEBITE_Reset ((u16)0xF7FF) /* USART ONEBITE mode Disable Mask */ - -/** - * @} - */ - -/** @defgroup USART_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USART_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup USART_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup USART_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the USARTx peripheral registers to their default reset values. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: USART1, USART2, USART3, UART4 or UART5. - * @retval None - */ -void USART_DeInit(USART_TypeDef* USARTx) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - - if (USARTx == USART1) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); - } - else if (USARTx == USART2) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE); - } - else if (USARTx == USART3) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE); - } - else if (USARTx == UART4) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, DISABLE); - } - else - { - if (USARTx == UART5) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, DISABLE); - } - } -} - -/** - * @brief Initializes the USARTx peripheral according to the specified - * parameters in the USART_InitStruct . - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param USART_InitStruct: pointer to a USART_InitTypeDef structure - * that contains the configuration information for the specified USART peripheral. - * @retval None - */ -void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct) -{ - uint32_t tmpreg = 0x00, apbclock = 0x00; - uint32_t integerdivider = 0x00; - uint32_t fractionaldivider = 0x00; - uint32_t usartxbase = 0; - RCC_ClocksTypeDef RCC_ClocksStatus; - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_BAUDRATE(USART_InitStruct->USART_BaudRate)); - assert_param(IS_USART_WORD_LENGTH(USART_InitStruct->USART_WordLength)); - assert_param(IS_USART_STOPBITS(USART_InitStruct->USART_StopBits)); - assert_param(IS_USART_PARITY(USART_InitStruct->USART_Parity)); - assert_param(IS_USART_MODE(USART_InitStruct->USART_Mode)); - assert_param(IS_USART_HARDWARE_FLOW_CONTROL(USART_InitStruct->USART_HardwareFlowControl)); - /* The hardware flow control is available only for USART1, USART2 and USART3 */ - if (USART_InitStruct->USART_HardwareFlowControl != USART_HardwareFlowControl_None) - { - assert_param(IS_USART_123_PERIPH(USARTx)); - } - - usartxbase = (uint32_t)USARTx; - -/*---------------------------- USART CR2 Configuration -----------------------*/ - tmpreg = USARTx->CR2; - /* Clear STOP[13:12] bits */ - tmpreg &= CR2_STOP_CLEAR_Mask; - /* Configure the USART Stop Bits, Clock, CPOL, CPHA and LastBit ------------*/ - /* Set STOP[13:12] bits according to USART_StopBits value */ - tmpreg |= (uint32_t)USART_InitStruct->USART_StopBits; - - /* Write to USART CR2 */ - USARTx->CR2 = (uint16_t)tmpreg; - -/*---------------------------- USART CR1 Configuration -----------------------*/ - tmpreg = USARTx->CR1; - /* Clear M, PCE, PS, TE and RE bits */ - tmpreg &= CR1_CLEAR_Mask; - /* Configure the USART Word Length, Parity and mode ----------------------- */ - /* Set the M bits according to USART_WordLength value */ - /* Set PCE and PS bits according to USART_Parity value */ - /* Set TE and RE bits according to USART_Mode value */ - tmpreg |= (uint32_t)USART_InitStruct->USART_WordLength | USART_InitStruct->USART_Parity | - USART_InitStruct->USART_Mode; - /* Write to USART CR1 */ - USARTx->CR1 = (uint16_t)tmpreg; - -/*---------------------------- USART CR3 Configuration -----------------------*/ - tmpreg = USARTx->CR3; - /* Clear CTSE and RTSE bits */ - tmpreg &= CR3_CLEAR_Mask; - /* Configure the USART HFC -------------------------------------------------*/ - /* Set CTSE and RTSE bits according to USART_HardwareFlowControl value */ - tmpreg |= USART_InitStruct->USART_HardwareFlowControl; - /* Write to USART CR3 */ - USARTx->CR3 = (uint16_t)tmpreg; - -/*---------------------------- USART BRR Configuration -----------------------*/ - /* Configure the USART Baud Rate -------------------------------------------*/ - RCC_GetClocksFreq(&RCC_ClocksStatus); - if (usartxbase == USART1_BASE) - { - apbclock = RCC_ClocksStatus.PCLK2_Frequency; - } - else - { - apbclock = RCC_ClocksStatus.PCLK1_Frequency; - } - - /* Determine the integer part */ - if ((USARTx->CR1 & CR1_OVER8_Set) != 0) - { - /* Integer part computing in case Oversampling mode is 8 Samples */ - integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate))); - } - else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */ - { - /* Integer part computing in case Oversampling mode is 16 Samples */ - integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate))); - } - tmpreg = (integerdivider / 100) << 4; - - /* Determine the fractional part */ - fractionaldivider = integerdivider - (100 * (tmpreg >> 4)); - - /* Implement the fractional part in the register */ - if ((USARTx->CR1 & CR1_OVER8_Set) != 0) - { - tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07); - } - else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */ - { - tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F); - } - - /* Write to USART BRR */ - USARTx->BRR = (uint16_t)tmpreg; -} - -/** - * @brief Fills each USART_InitStruct member with its default value. - * @param USART_InitStruct: pointer to a USART_InitTypeDef structure - * which will be initialized. - * @retval None - */ -void USART_StructInit(USART_InitTypeDef* USART_InitStruct) -{ - /* USART_InitStruct members default value */ - USART_InitStruct->USART_BaudRate = 9600; - USART_InitStruct->USART_WordLength = USART_WordLength_8b; - USART_InitStruct->USART_StopBits = USART_StopBits_1; - USART_InitStruct->USART_Parity = USART_Parity_No ; - USART_InitStruct->USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - USART_InitStruct->USART_HardwareFlowControl = USART_HardwareFlowControl_None; -} - -/** - * @brief Initializes the USARTx peripheral Clock according to the - * specified parameters in the USART_ClockInitStruct . - * @param USARTx: where x can be 1, 2, 3 to select the USART peripheral. - * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef - * structure that contains the configuration information for the specified - * USART peripheral. - * @note The Smart Card mode is not available for UART4 and UART5. - * @retval None - */ -void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct) -{ - uint32_t tmpreg = 0x00; - /* Check the parameters */ - assert_param(IS_USART_123_PERIPH(USARTx)); - assert_param(IS_USART_CLOCK(USART_ClockInitStruct->USART_Clock)); - assert_param(IS_USART_CPOL(USART_ClockInitStruct->USART_CPOL)); - assert_param(IS_USART_CPHA(USART_ClockInitStruct->USART_CPHA)); - assert_param(IS_USART_LASTBIT(USART_ClockInitStruct->USART_LastBit)); - -/*---------------------------- USART CR2 Configuration -----------------------*/ - tmpreg = USARTx->CR2; - /* Clear CLKEN, CPOL, CPHA and LBCL bits */ - tmpreg &= CR2_CLOCK_CLEAR_Mask; - /* Configure the USART Clock, CPOL, CPHA and LastBit ------------*/ - /* Set CLKEN bit according to USART_Clock value */ - /* Set CPOL bit according to USART_CPOL value */ - /* Set CPHA bit according to USART_CPHA value */ - /* Set LBCL bit according to USART_LastBit value */ - tmpreg |= (uint32_t)USART_ClockInitStruct->USART_Clock | USART_ClockInitStruct->USART_CPOL | - USART_ClockInitStruct->USART_CPHA | USART_ClockInitStruct->USART_LastBit; - /* Write to USART CR2 */ - USARTx->CR2 = (uint16_t)tmpreg; -} - -/** - * @brief Fills each USART_ClockInitStruct member with its default value. - * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef - * structure which will be initialized. - * @retval None - */ -void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct) -{ - /* USART_ClockInitStruct members default value */ - USART_ClockInitStruct->USART_Clock = USART_Clock_Disable; - USART_ClockInitStruct->USART_CPOL = USART_CPOL_Low; - USART_ClockInitStruct->USART_CPHA = USART_CPHA_1Edge; - USART_ClockInitStruct->USART_LastBit = USART_LastBit_Disable; -} - -/** - * @brief Enables or disables the specified USART peripheral. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param NewState: new state of the USARTx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected USART by setting the UE bit in the CR1 register */ - USARTx->CR1 |= CR1_UE_Set; - } - else - { - /* Disable the selected USART by clearing the UE bit in the CR1 register */ - USARTx->CR1 &= CR1_UE_Reset; - } -} - -/** - * @brief Enables or disables the specified USART interrupts. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param USART_IT: specifies the USART interrupt sources to be enabled or disabled. - * This parameter can be one of the following values: - * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) - * @arg USART_IT_LBD: LIN Break detection interrupt - * @arg USART_IT_TXE: Tansmit Data Register empty interrupt - * @arg USART_IT_TC: Transmission complete interrupt - * @arg USART_IT_RXNE: Receive Data register not empty interrupt - * @arg USART_IT_IDLE: Idle line detection interrupt - * @arg USART_IT_PE: Parity Error interrupt - * @arg USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error) - * @param NewState: new state of the specified USARTx interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState) -{ - uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00; - uint32_t usartxbase = 0x00; - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_CONFIG_IT(USART_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - /* The CTS interrupt is not available for UART4 and UART5 */ - if (USART_IT == USART_IT_CTS) - { - assert_param(IS_USART_123_PERIPH(USARTx)); - } - - usartxbase = (uint32_t)USARTx; - - /* Get the USART register index */ - usartreg = (((uint8_t)USART_IT) >> 0x05); - - /* Get the interrupt position */ - itpos = USART_IT & IT_Mask; - itmask = (((uint32_t)0x01) << itpos); - - if (usartreg == 0x01) /* The IT is in CR1 register */ - { - usartxbase += 0x0C; - } - else if (usartreg == 0x02) /* The IT is in CR2 register */ - { - usartxbase += 0x10; - } - else /* The IT is in CR3 register */ - { - usartxbase += 0x14; - } - if (NewState != DISABLE) - { - *(__IO uint32_t*)usartxbase |= itmask; - } - else - { - *(__IO uint32_t*)usartxbase &= ~itmask; - } -} - -/** - * @brief Enables or disables the USARTs DMA interface. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3 or UART4. - * @param USART_DMAReq: specifies the DMA request. - * This parameter can be any combination of the following values: - * @arg USART_DMAReq_Tx: USART DMA transmit request - * @arg USART_DMAReq_Rx: USART DMA receive request - * @param NewState: new state of the DMA Request sources. - * This parameter can be: ENABLE or DISABLE. - * @note The DMA mode is not available for UART5. - * @retval None - */ -void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_1234_PERIPH(USARTx)); - assert_param(IS_USART_DMAREQ(USART_DMAReq)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the DMA transfer for selected requests by setting the DMAT and/or - DMAR bits in the USART CR3 register */ - USARTx->CR3 |= USART_DMAReq; - } - else - { - /* Disable the DMA transfer for selected requests by clearing the DMAT and/or - DMAR bits in the USART CR3 register */ - USARTx->CR3 &= (uint16_t)~USART_DMAReq; - } -} - -/** - * @brief Sets the address of the USART node. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param USART_Address: Indicates the address of the USART node. - * @retval None - */ -void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_ADDRESS(USART_Address)); - - /* Clear the USART address */ - USARTx->CR2 &= CR2_Address_Mask; - /* Set the USART address node */ - USARTx->CR2 |= USART_Address; -} - -/** - * @brief Selects the USART WakeUp method. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param USART_WakeUp: specifies the USART wakeup method. - * This parameter can be one of the following values: - * @arg USART_WakeUp_IdleLine: WakeUp by an idle line detection - * @arg USART_WakeUp_AddressMark: WakeUp by an address mark - * @retval None - */ -void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_WAKEUP(USART_WakeUp)); - - USARTx->CR1 &= CR1_WAKE_Mask; - USARTx->CR1 |= USART_WakeUp; -} - -/** - * @brief Determines if the USART is in mute mode or not. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param NewState: new state of the USART mute mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the USART mute mode by setting the RWU bit in the CR1 register */ - USARTx->CR1 |= CR1_RWU_Set; - } - else - { - /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */ - USARTx->CR1 &= CR1_RWU_Reset; - } -} - -/** - * @brief Sets the USART LIN Break detection length. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param USART_LINBreakDetectLength: specifies the LIN break detection length. - * This parameter can be one of the following values: - * @arg USART_LINBreakDetectLength_10b: 10-bit break detection - * @arg USART_LINBreakDetectLength_11b: 11-bit break detection - * @retval None - */ -void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_LIN_BREAK_DETECT_LENGTH(USART_LINBreakDetectLength)); - - USARTx->CR2 &= CR2_LBDL_Mask; - USARTx->CR2 |= USART_LINBreakDetectLength; -} - -/** - * @brief Enables or disables the USARTs LIN mode. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param NewState: new state of the USART LIN mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the LIN mode by setting the LINEN bit in the CR2 register */ - USARTx->CR2 |= CR2_LINEN_Set; - } - else - { - /* Disable the LIN mode by clearing the LINEN bit in the CR2 register */ - USARTx->CR2 &= CR2_LINEN_Reset; - } -} - -/** - * @brief Transmits single data through the USARTx peripheral. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param Data: the data to transmit. - * @retval None - */ -void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_DATA(Data)); - - /* Transmit Data */ - USARTx->DR = (Data & (uint16_t)0x01FF); -} - -/** - * @brief Returns the most recent received data by the USARTx peripheral. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @retval The received data. - */ -uint16_t USART_ReceiveData(USART_TypeDef* USARTx) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - - /* Receive Data */ - return (uint16_t)(USARTx->DR & (uint16_t)0x01FF); -} - -/** - * @brief Transmits break characters. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @retval None - */ -void USART_SendBreak(USART_TypeDef* USARTx) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - - /* Send break characters */ - USARTx->CR1 |= CR1_SBK_Set; -} - -/** - * @brief Sets the specified USART guard time. - * @param USARTx: where x can be 1, 2 or 3 to select the USART peripheral. - * @param USART_GuardTime: specifies the guard time. - * @note The guard time bits are not available for UART4 and UART5. - * @retval None - */ -void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime) -{ - /* Check the parameters */ - assert_param(IS_USART_123_PERIPH(USARTx)); - - /* Clear the USART Guard time */ - USARTx->GTPR &= GTPR_LSB_Mask; - /* Set the USART guard time */ - USARTx->GTPR |= (uint16_t)((uint16_t)USART_GuardTime << 0x08); -} - -/** - * @brief Sets the system clock prescaler. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param USART_Prescaler: specifies the prescaler clock. - * @note The function is used for IrDA mode with UART4 and UART5. - * @retval None - */ -void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - - /* Clear the USART prescaler */ - USARTx->GTPR &= GTPR_MSB_Mask; - /* Set the USART prescaler */ - USARTx->GTPR |= USART_Prescaler; -} - -/** - * @brief Enables or disables the USARTs Smart Card mode. - * @param USARTx: where x can be 1, 2 or 3 to select the USART peripheral. - * @param NewState: new state of the Smart Card mode. - * This parameter can be: ENABLE or DISABLE. - * @note The Smart Card mode is not available for UART4 and UART5. - * @retval None - */ -void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_123_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the SC mode by setting the SCEN bit in the CR3 register */ - USARTx->CR3 |= CR3_SCEN_Set; - } - else - { - /* Disable the SC mode by clearing the SCEN bit in the CR3 register */ - USARTx->CR3 &= CR3_SCEN_Reset; - } -} - -/** - * @brief Enables or disables NACK transmission. - * @param USARTx: where x can be 1, 2 or 3 to select the USART peripheral. - * @param NewState: new state of the NACK transmission. - * This parameter can be: ENABLE or DISABLE. - * @note The Smart Card mode is not available for UART4 and UART5. - * @retval None - */ -void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_123_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the NACK transmission by setting the NACK bit in the CR3 register */ - USARTx->CR3 |= CR3_NACK_Set; - } - else - { - /* Disable the NACK transmission by clearing the NACK bit in the CR3 register */ - USARTx->CR3 &= CR3_NACK_Reset; - } -} - -/** - * @brief Enables or disables the USARTs Half Duplex communication. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param NewState: new state of the USART Communication. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ - USARTx->CR3 |= CR3_HDSEL_Set; - } - else - { - /* Disable the Half-Duplex mode by clearing the HDSEL bit in the CR3 register */ - USARTx->CR3 &= CR3_HDSEL_Reset; - } -} - - -/** - * @brief Enables or disables the USART's 8x oversampling mode. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param NewState: new state of the USART one bit sampling methode. - * This parameter can be: ENABLE or DISABLE. - * @note - * This function has to be called before calling USART_Init() - * function in order to have correct baudrate Divider value. - * @retval None - */ -void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the 8x Oversampling mode by setting the OVER8 bit in the CR1 register */ - USARTx->CR1 |= CR1_OVER8_Set; - } - else - { - /* Disable the 8x Oversampling mode by clearing the OVER8 bit in the CR1 register */ - USARTx->CR1 &= CR1_OVER8_Reset; - } -} - -/** - * @brief Enables or disables the USART's one bit sampling methode. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param NewState: new state of the USART one bit sampling methode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the one bit method by setting the ONEBITE bit in the CR3 register */ - USARTx->CR3 |= CR3_ONEBITE_Set; - } - else - { - /* Disable tthe one bit method by clearing the ONEBITE bit in the CR3 register */ - USARTx->CR3 &= CR3_ONEBITE_Reset; - } -} - -/** - * @brief Configures the USARTs IrDA interface. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param USART_IrDAMode: specifies the IrDA mode. - * This parameter can be one of the following values: - * @arg USART_IrDAMode_LowPower - * @arg USART_IrDAMode_Normal - * @retval None - */ -void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_IRDA_MODE(USART_IrDAMode)); - - USARTx->CR3 &= CR3_IRLP_Mask; - USARTx->CR3 |= USART_IrDAMode; -} - -/** - * @brief Enables or disables the USARTs IrDA interface. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param NewState: new state of the IrDA mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the IrDA mode by setting the IREN bit in the CR3 register */ - USARTx->CR3 |= CR3_IREN_Set; - } - else - { - /* Disable the IrDA mode by clearing the IREN bit in the CR3 register */ - USARTx->CR3 &= CR3_IREN_Reset; - } -} - -/** - * @brief Checks whether the specified USART flag is set or not. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param USART_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5) - * @arg USART_FLAG_LBD: LIN Break detection flag - * @arg USART_FLAG_TXE: Transmit data register empty flag - * @arg USART_FLAG_TC: Transmission Complete flag - * @arg USART_FLAG_RXNE: Receive data register not empty flag - * @arg USART_FLAG_IDLE: Idle Line detection flag - * @arg USART_FLAG_ORE: OverRun Error flag - * @arg USART_FLAG_NE: Noise Error flag - * @arg USART_FLAG_FE: Framing Error flag - * @arg USART_FLAG_PE: Parity Error flag - * @retval The new state of USART_FLAG (SET or RESET). - */ -FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_FLAG(USART_FLAG)); - /* The CTS flag is not available for UART4 and UART5 */ - if (USART_FLAG == USART_FLAG_CTS) - { - assert_param(IS_USART_123_PERIPH(USARTx)); - } - - if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the USARTx's pending flags. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param USART_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5). - * @arg USART_FLAG_LBD: LIN Break detection flag. - * @arg USART_FLAG_TC: Transmission Complete flag. - * @arg USART_FLAG_RXNE: Receive data register not empty flag. - * - * @note - * - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun - * error) and IDLE (Idle line detected) flags are cleared by software - * sequence: a read operation to USART_SR register (USART_GetFlagStatus()) - * followed by a read operation to USART_DR register (USART_ReceiveData()). - * - RXNE flag can be also cleared by a read to the USART_DR register - * (USART_ReceiveData()). - * - TC flag can be also cleared by software sequence: a read operation to - * USART_SR register (USART_GetFlagStatus()) followed by a write operation - * to USART_DR register (USART_SendData()). - * - TXE flag is cleared only by a write to the USART_DR register - * (USART_SendData()). - * @retval None - */ -void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_CLEAR_FLAG(USART_FLAG)); - /* The CTS flag is not available for UART4 and UART5 */ - if ((USART_FLAG & USART_FLAG_CTS) == USART_FLAG_CTS) - { - assert_param(IS_USART_123_PERIPH(USARTx)); - } - - USARTx->SR = (uint16_t)~USART_FLAG; -} - -/** - * @brief Checks whether the specified USART interrupt has occurred or not. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param USART_IT: specifies the USART interrupt source to check. - * This parameter can be one of the following values: - * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) - * @arg USART_IT_LBD: LIN Break detection interrupt - * @arg USART_IT_TXE: Tansmit Data Register empty interrupt - * @arg USART_IT_TC: Transmission complete interrupt - * @arg USART_IT_RXNE: Receive Data register not empty interrupt - * @arg USART_IT_IDLE: Idle line detection interrupt - * @arg USART_IT_ORE: OverRun Error interrupt - * @arg USART_IT_NE: Noise Error interrupt - * @arg USART_IT_FE: Framing Error interrupt - * @arg USART_IT_PE: Parity Error interrupt - * @retval The new state of USART_IT (SET or RESET). - */ -ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT) -{ - uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00; - ITStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_GET_IT(USART_IT)); - /* The CTS interrupt is not available for UART4 and UART5 */ - if (USART_IT == USART_IT_CTS) - { - assert_param(IS_USART_123_PERIPH(USARTx)); - } - - /* Get the USART register index */ - usartreg = (((uint8_t)USART_IT) >> 0x05); - /* Get the interrupt position */ - itmask = USART_IT & IT_Mask; - itmask = (uint32_t)0x01 << itmask; - - if (usartreg == 0x01) /* The IT is in CR1 register */ - { - itmask &= USARTx->CR1; - } - else if (usartreg == 0x02) /* The IT is in CR2 register */ - { - itmask &= USARTx->CR2; - } - else /* The IT is in CR3 register */ - { - itmask &= USARTx->CR3; - } - - bitpos = USART_IT >> 0x08; - bitpos = (uint32_t)0x01 << bitpos; - bitpos &= USARTx->SR; - if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - - return bitstatus; -} - -/** - * @brief Clears the USARTxs interrupt pending bits. - * @param USARTx: Select the USART or the UART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3, UART4 or UART5. - * @param USART_IT: specifies the interrupt pending bit to clear. - * This parameter can be one of the following values: - * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) - * @arg USART_IT_LBD: LIN Break detection interrupt - * @arg USART_IT_TC: Transmission complete interrupt. - * @arg USART_IT_RXNE: Receive Data register not empty interrupt. - * - * @note - * - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun - * error) and IDLE (Idle line detected) pending bits are cleared by - * software sequence: a read operation to USART_SR register - * (USART_GetITStatus()) followed by a read operation to USART_DR register - * (USART_ReceiveData()). - * - RXNE pending bit can be also cleared by a read to the USART_DR register - * (USART_ReceiveData()). - * - TC pending bit can be also cleared by software sequence: a read - * operation to USART_SR register (USART_GetITStatus()) followed by a write - * operation to USART_DR register (USART_SendData()). - * - TXE pending bit is cleared only by a write to the USART_DR register - * (USART_SendData()). - * @retval None - */ -void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT) -{ - uint16_t bitpos = 0x00, itmask = 0x00; - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_CLEAR_IT(USART_IT)); - /* The CTS interrupt is not available for UART4 and UART5 */ - if (USART_IT == USART_IT_CTS) - { - assert_param(IS_USART_123_PERIPH(USARTx)); - } - - bitpos = USART_IT >> 0x08; - itmask = ((uint16_t)0x01 << (uint16_t)bitpos); - USARTx->SR = (uint16_t)~itmask; -} -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32f10x/stm32f10x_wwdg.c b/example/libs_stm/src/stm32f10x/stm32f10x_wwdg.c deleted file mode 100644 index cd4978bbe..000000000 --- a/example/libs_stm/src/stm32f10x/stm32f10x_wwdg.c +++ /dev/null @@ -1,223 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f10x_wwdg.c - * @author MCD Application Team - * @version V3.3.0 - * @date 04/16/2010 - * @brief This file provides all the WWDG firmware functions. - ****************************************************************************** - * @copy - * - * 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

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f10x_wwdg.h" -#include "stm32f10x_rcc.h" - -/** @addtogroup STM32F10x_StdPeriph_Driver - * @{ - */ - -/** @defgroup WWDG - * @brief WWDG driver modules - * @{ - */ - -/** @defgroup WWDG_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup WWDG_Private_Defines - * @{ - */ - -/* ----------- WWDG registers bit address in the alias region ----------- */ -#define WWDG_OFFSET (WWDG_BASE - PERIPH_BASE) - -/* Alias word address of EWI bit */ -#define CFR_OFFSET (WWDG_OFFSET + 0x04) -#define EWI_BitNumber 0x09 -#define CFR_EWI_BB (PERIPH_BB_BASE + (CFR_OFFSET * 32) + (EWI_BitNumber * 4)) - -/* --------------------- WWDG registers bit mask ------------------------ */ - -/* CR register bit mask */ -#define CR_WDGA_Set ((uint32_t)0x00000080) - -/* CFR register bit mask */ -#define CFR_WDGTB_Mask ((uint32_t)0xFFFFFE7F) -#define CFR_W_Mask ((uint32_t)0xFFFFFF80) -#define BIT_Mask ((uint8_t)0x7F) - -/** - * @} - */ - -/** @defgroup WWDG_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup WWDG_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup WWDG_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup WWDG_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the WWDG peripheral registers to their default reset values. - * @param None - * @retval None - */ -void WWDG_DeInit(void) -{ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, DISABLE); -} - -/** - * @brief Sets the WWDG Prescaler. - * @param WWDG_Prescaler: specifies the WWDG Prescaler. - * This parameter can be one of the following values: - * @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1 - * @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2 - * @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4 - * @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8 - * @retval None - */ -void WWDG_SetPrescaler(uint32_t WWDG_Prescaler) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_WWDG_PRESCALER(WWDG_Prescaler)); - /* Clear WDGTB[1:0] bits */ - tmpreg = WWDG->CFR & CFR_WDGTB_Mask; - /* Set WDGTB[1:0] bits according to WWDG_Prescaler value */ - tmpreg |= WWDG_Prescaler; - /* Store the new value */ - WWDG->CFR = tmpreg; -} - -/** - * @brief Sets the WWDG window value. - * @param WindowValue: specifies the window value to be compared to the downcounter. - * This parameter value must be lower than 0x80. - * @retval None - */ -void WWDG_SetWindowValue(uint8_t WindowValue) -{ - __IO uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_WWDG_WINDOW_VALUE(WindowValue)); - /* Clear W[6:0] bits */ - - tmpreg = WWDG->CFR & CFR_W_Mask; - - /* Set W[6:0] bits according to WindowValue value */ - tmpreg |= WindowValue & (uint32_t) BIT_Mask; - - /* Store the new value */ - WWDG->CFR = tmpreg; -} - -/** - * @brief Enables the WWDG Early Wakeup interrupt(EWI). - * @param None - * @retval None - */ -void WWDG_EnableIT(void) -{ - *(__IO uint32_t *) CFR_EWI_BB = (uint32_t)ENABLE; -} - -/** - * @brief Sets the WWDG counter value. - * @param Counter: specifies the watchdog counter value. - * This parameter must be a number between 0x40 and 0x7F. - * @retval None - */ -void WWDG_SetCounter(uint8_t Counter) -{ - /* Check the parameters */ - assert_param(IS_WWDG_COUNTER(Counter)); - /* Write to T[6:0] bits to configure the counter value, no need to do - a read-modify-write; writing a 0 to WDGA bit does nothing */ - WWDG->CR = Counter & BIT_Mask; -} - -/** - * @brief Enables WWDG and load the counter value. - * @param Counter: specifies the watchdog counter value. - * This parameter must be a number between 0x40 and 0x7F. - * @retval None - */ -void WWDG_Enable(uint8_t Counter) -{ - /* Check the parameters */ - assert_param(IS_WWDG_COUNTER(Counter)); - WWDG->CR = CR_WDGA_Set | Counter; -} - -/** - * @brief Checks whether the Early Wakeup interrupt flag is set or not. - * @param None - * @retval The new state of the Early Wakeup interrupt flag (SET or RESET) - */ -FlagStatus WWDG_GetFlagStatus(void) -{ - return (FlagStatus)(WWDG->SR); -} - -/** - * @brief Clears Early Wakeup interrupt flag. - * @param None - * @retval None - */ -void WWDG_ClearFlag(void) -{ - WWDG->SR = (uint32_t)RESET; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/misc.c b/example/libs_stm/src/stm32l1xx/misc.c deleted file mode 100644 index 3b7a0009e..000000000 --- a/example/libs_stm/src/stm32l1xx/misc.c +++ /dev/null @@ -1,249 +0,0 @@ -/** - ****************************************************************************** - * @file misc.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides all the miscellaneous firmware functions (add-on - * to CMSIS functions). - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "misc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup MISC - * @brief MISC driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup MISC_Private_Functions - * @{ - */ -/** - * -@verbatim - ******************************************************************************* - Interrupts configuration functions - ******************************************************************************* - - This section provide functions allowing to configure the NVIC interrupts (IRQ). - The Cortex-M3 exceptions are managed by CMSIS functions. - - 1. Configure the NVIC Priority Grouping using NVIC_PriorityGroupConfig() function - according to the following table. - - The table below gives the allowed values of the pre-emption priority and subpriority according - to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function - ============================================================================================================================ - NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description - ============================================================================================================================ - NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority - | | | 4 bits for subpriority - ---------------------------------------------------------------------------------------------------------------------------- - NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority - | | | 3 bits for subpriority - ---------------------------------------------------------------------------------------------------------------------------- - NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority - | | | 2 bits for subpriority - ---------------------------------------------------------------------------------------------------------------------------- - NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority - | | | 1 bits for subpriority - ---------------------------------------------------------------------------------------------------------------------------- - NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority - | | | 0 bits for subpriority - ============================================================================================================================ - - - 2. Enable and Configure the priority of the selected IRQ Channels. - -@note When the NVIC_PriorityGroup_0 is selected, it will no any nested interrupt, - the IRQ priority will be managed only by subpriority. - The sub-priority is only used to sort pending exception priorities, - and does not affect active exceptions. - -@note Lower priority values gives higher priority. - -@note Priority Order: - 1. Lowest Preemption priority - 2. Lowest Subpriority - 3. Lowest hardware priority (IRQn position) - -@endverbatim -*/ - -/** - * @brief Configures the priority grouping: pre-emption priority and subpriority. - * @param NVIC_PriorityGroup: specifies the priority grouping bits length. - * This parameter can be one of the following values: - * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority - * 4 bits for subpriority - * @note When NVIC_PriorityGroup_0 is selected, it will no be any nested - * interrupt. This interrupts priority is managed only with subpriority. - * @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority - * 3 bits for subpriority - * @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority - * 2 bits for subpriority - * @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority - * 1 bits for subpriority - * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority - * 0 bits for subpriority - * @retval None - */ -void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) -{ - /* Check the parameters */ - assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); - - /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */ - SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; -} - -/** - * @brief Initializes the NVIC peripheral according to the specified - * parameters in the NVIC_InitStruct. - * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() - * function should be called before. - * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains - * the configuration information for the specified NVIC peripheral. - * @retval None - */ -void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) -{ - uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F; - - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd)); - assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority)); - assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority)); - - if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE) - { - /* Compute the Corresponding IRQ Priority --------------------------------*/ - tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08; - tmppre = (0x4 - tmppriority); - tmpsub = tmpsub >> tmppriority; - - tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; - tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub; - tmppriority = tmppriority << 0x04; - - NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority; - - /* Enable the Selected IRQ Channels --------------------------------------*/ - NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = - (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); - } - else - { - /* Disable the Selected IRQ Channels -------------------------------------*/ - NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = - (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); - } -} - -/** - * @brief Sets the vector table location and Offset. - * @param NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory. - * This parameter can be one of the following values: - * @arg NVIC_VectTab_RAM - * @arg NVIC_VectTab_FLASH - * @param Offset: Vector Table base offset field. This value must be a multiple of 0x200. - * @retval None - */ -void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) -{ - /* Check the parameters */ - assert_param(IS_NVIC_VECTTAB(NVIC_VectTab)); - assert_param(IS_NVIC_OFFSET(Offset)); - - SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80); -} - -/** - * @brief Selects the condition for the system to enter low power mode. - * @param LowPowerMode: Specifies the new mode for the system to enter low power mode. - * This parameter can be one of the following values: - * @arg NVIC_LP_SEVONPEND - * @arg NVIC_LP_SLEEPDEEP - * @arg NVIC_LP_SLEEPONEXIT - * @param NewState: new state of LP condition. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_NVIC_LP(LowPowerMode)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - SCB->SCR |= LowPowerMode; - } - else - { - SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode); - } -} - -/** - * @brief Configures the SysTick clock source. - * @param SysTick_CLKSource: specifies the SysTick clock source. - * This parameter can be one of the following values: - * @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source. - * @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source. - * @retval None - */ -void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) -{ - /* Check the parameters */ - assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); - - if (SysTick_CLKSource == SysTick_CLKSource_HCLK) - { - SysTick->CTRL |= SysTick_CLKSource_HCLK; - } - else - { - SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_adc.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_adc.c deleted file mode 100644 index fec303234..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_adc.c +++ /dev/null @@ -1,1803 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_adc.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the Analog to Digital Convertor (ADC) peripheral: - * - Initialization and Configuration - * - Power saving - * - Analog Watchdog configuration - * - Temperature Sensor & Vrefint (Voltage Reference internal) management - * - Regular Channels Configuration - * - Regular Channels DMA Configuration - * - Injected channels Configuration - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * - Configure the ADC Prescaler, conversion resolution and data - * alignment using the ADC_Init() function. - * - Activate the ADC peripheral using ADC_Cmd() function. - * - * Regular channels group configuration - * ==================================== - * - To configure the ADC regular channels group features, use - * ADC_Init() and ADC_RegularChannelConfig() functions. - * - To activate the continuous mode, use the ADC_continuousModeCmd() - * function. - * - To configurate and activate the Discontinuous mode, use the - * ADC_DiscModeChannelCountConfig() and ADC_DiscModeCmd() functions. - * - To read the ADC converted values, use the ADC_GetConversionValue() - * function. - * - * DMA for Regular channels group features configuration - * ====================================================== - * - To enable the DMA mode for regular channels group, use the - * ADC_DMACmd() function. - * - To enable the generation of DMA requests continuously at the end - * of the last DMA transfer, use the ADC_DMARequestAfterLastTransferCmd() - * function. - - * Injected channels group configuration - * ===================================== - * - To configure the ADC Injected channels group features, use - * ADC_InjectedChannelConfig() and ADC_InjectedSequencerLengthConfig() - * functions. - * - To activate the continuous mode, use the ADC_continuousModeCmd() - * function. - * - To activate the Injected Discontinuous mode, use the - * ADC_InjectedDiscModeCmd() function. - * - To activate the AutoInjected mode, use the ADC_AutoInjectedConvCmd() - * function. - * - To read the ADC converted values, use the ADC_GetInjectedConversionValue() - * function. - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_adc.h" -#include "stm32l1xx_rcc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup ADC - * @brief ADC driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* ADC DISCNUM mask */ -#define CR1_DISCNUM_RESET ((uint32_t)0xFFFF1FFF) - -/* ADC AWDCH mask */ -#define CR1_AWDCH_RESET ((uint32_t)0xFFFFFFE0) - -/* ADC Analog watchdog enable mode mask */ -#define CR1_AWDMODE_RESET ((uint32_t)0xFF3FFDFF) - -/* CR1 register Mask */ -#define CR1_CLEAR_MASK ((uint32_t)0xFCFFFEFF) - -/* ADC DELAY mask */ -#define CR2_DELS_RESET ((uint32_t)0xFFFFFF0F) - -/* ADC JEXTEN mask */ -#define CR2_JEXTEN_RESET ((uint32_t)0xFFCFFFFF) - -/* ADC JEXTSEL mask */ -#define CR2_JEXTSEL_RESET ((uint32_t)0xFFF0FFFF) - -/* CR2 register Mask */ -#define CR2_CLEAR_MASK ((uint32_t)0xC0FFF7FD) - -/* ADC SQx mask */ -#define SQR5_SQ_SET ((uint32_t)0x0000001F) -#define SQR4_SQ_SET ((uint32_t)0x0000001F) -#define SQR3_SQ_SET ((uint32_t)0x0000001F) -#define SQR2_SQ_SET ((uint32_t)0x0000001F) -#define SQR1_SQ_SET ((uint32_t)0x0000001F) - -/* ADC L Mask */ -#define SQR1_L_RESET ((uint32_t)0xFE0FFFFF) - -/* ADC JSQx mask */ -#define JSQR_JSQ_SET ((uint32_t)0x0000001F) - -/* ADC JL mask */ -#define JSQR_JL_SET ((uint32_t)0x00300000) -#define JSQR_JL_RESET ((uint32_t)0xFFCFFFFF) - -/* ADC SMPx mask */ -#define SMPR1_SMP_SET ((uint32_t)0x00000007) -#define SMPR2_SMP_SET ((uint32_t)0x00000007) -#define SMPR3_SMP_SET ((uint32_t)0x00000007) - -/* ADC JDRx registers offset */ -#define JDR_OFFSET ((uint8_t)0x30) - -/* ADC CCR register Mask */ -#define CR_CLEAR_MASK ((uint32_t)0xFFFCFFFF) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup ADC_Private_Functions - * @{ - */ - -/** @defgroup ADC_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - This section provides functions allowing to: - - Initialize and configure the ADC Prescaler - - ADC Conversion Resolution (12bit..6bit) - - Scan Conversion Mode (multichannels or one channel) for regular group - - ADC Continuous Conversion Mode (Continuous or Single conversion) for regular group - - External trigger Edge and source of regular group, - - Converted data alignment (left or right) - - The number of ADC conversions that will be done using the sequencer for regular channel group - - Enable or disable the ADC peripheral - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes ADC1 peripheral registers to their default reset values. - * @param None - * @retval None - */ -void ADC_DeInit(ADC_TypeDef* ADCx) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - - /* Enable ADC1 reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, ENABLE); - /* Release ADC1 from reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, DISABLE); -} - -/** - * @brief Initializes the ADCx peripheral according to the specified parameters - * in the ADC_InitStruct. - * @note This function is used to configure the global features of the ADC ( - * Resolution and Data Alignment), however, the rest of the configuration - * parameters are specific to the regular channels group (scan mode - * activation, continuous mode activation, External trigger source and - * edge, number of conversion in the regular channels group sequencer). - * @param ADCx: where x can be 1 to select the ADC peripheral. - * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains - * the configuration information for the specified ADC peripheral. - * @retval None - */ -void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) -{ - uint32_t tmpreg1 = 0; - uint8_t tmpreg2 = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_RESOLUTION(ADC_InitStruct->ADC_Resolution)); - assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ScanConvMode)); - assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ContinuousConvMode)); - assert_param(IS_ADC_EXT_TRIG_EDGE(ADC_InitStruct->ADC_ExternalTrigConvEdge)); - assert_param(IS_ADC_EXT_TRIG(ADC_InitStruct->ADC_ExternalTrigConv)); - assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign)); - assert_param(IS_ADC_REGULAR_LENGTH(ADC_InitStruct->ADC_NbrOfConversion)); - - /*---------------------------- ADCx CR1 Configuration -----------------*/ - /* Get the ADCx CR1 value */ - tmpreg1 = ADCx->CR1; - /* Clear RES and SCAN bits */ - tmpreg1 &= CR1_CLEAR_MASK; - /* Configure ADCx: scan conversion mode and resolution */ - /* Set SCAN bit according to ADC_ScanConvMode value */ - /* Set RES bit according to ADC_Resolution value */ - tmpreg1 |= (uint32_t)(((uint32_t)ADC_InitStruct->ADC_ScanConvMode << 8) | ADC_InitStruct->ADC_Resolution); - /* Write to ADCx CR1 */ - ADCx->CR1 = tmpreg1; - - /*---------------------------- ADCx CR2 Configuration -----------------*/ - /* Get the ADCx CR2 value */ - tmpreg1 = ADCx->CR2; - /* Clear CONT, ALIGN, EXTEN and EXTSEL bits */ - tmpreg1 &= CR2_CLEAR_MASK; - /* Configure ADCx: external trigger event and edge, data alignment and continuous conversion mode */ - /* Set ALIGN bit according to ADC_DataAlign value */ - /* Set EXTEN bits according to ADC_ExternalTrigConvEdge value */ - /* Set EXTSEL bits according to ADC_ExternalTrigConv value */ - /* Set CONT bit according to ADC_ContinuousConvMode value */ - tmpreg1 |= (uint32_t)(ADC_InitStruct->ADC_DataAlign | ADC_InitStruct->ADC_ExternalTrigConv | - ADC_InitStruct->ADC_ExternalTrigConvEdge | ((uint32_t)ADC_InitStruct->ADC_ContinuousConvMode << 1)); - /* Write to ADCx CR2 */ - ADCx->CR2 = tmpreg1; - - /*---------------------------- ADCx SQR1 Configuration -----------------*/ - /* Get the ADCx SQR1 value */ - tmpreg1 = ADCx->SQR1; - /* Clear L bits */ - tmpreg1 &= SQR1_L_RESET; - /* Configure ADCx: regular channel sequence length */ - /* Set L bits according to ADC_NbrOfConversion value */ - tmpreg2 |= (uint8_t)(ADC_InitStruct->ADC_NbrOfConversion - (uint8_t)1); - tmpreg1 |= ((uint32_t)tmpreg2 << 20); - /* Write to ADCx SQR1 */ - ADCx->SQR1 = tmpreg1; -} - -/** - * @brief Fills each ADC_InitStruct member with its default value. - * @note This function is used to initialize the global features of the ADC ( - * Resolution and Data Alignment), however, the rest of the configuration - * parameters are specific to the regular channels group (scan mode - * activation, continuous mode activation, External trigger source and - * edge, number of conversion in the regular channels group sequencer). - * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct) -{ - /* Reset ADC init structure parameters values */ - /* Initialize the ADC_Resolution member */ - ADC_InitStruct->ADC_Resolution = ADC_Resolution_12b; - - /* Initialize the ADC_ScanConvMode member */ - ADC_InitStruct->ADC_ScanConvMode = DISABLE; - - /* Initialize the ADC_ContinuousConvMode member */ - ADC_InitStruct->ADC_ContinuousConvMode = DISABLE; - - /* Initialize the ADC_ExternalTrigConvEdge member */ - ADC_InitStruct->ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; - - /* Initialize the ADC_ExternalTrigConv member */ - ADC_InitStruct->ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; - - /* Initialize the ADC_DataAlign member */ - ADC_InitStruct->ADC_DataAlign = ADC_DataAlign_Right; - - /* Initialize the ADC_NbrOfConversion member */ - ADC_InitStruct->ADC_NbrOfConversion = 1; -} - -/** - * @brief Initializes the ADCs peripherals according to the specified parameters - * in the ADC_CommonInitStruct. - * @param ADC_CommonInitStruct: pointer to an ADC_CommonInitTypeDef structure - * that contains the configuration information (Prescaler) for ADC1 peripheral. - * @retval None - */ -void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_ADC_PRESCALER(ADC_CommonInitStruct->ADC_Prescaler)); - - /*---------------------------- ADC CCR Configuration -----------------*/ - /* Get the ADC CCR value */ - tmpreg = ADC->CCR; - - /* Clear ADCPRE bit */ - tmpreg &= CR_CLEAR_MASK; - - /* Configure ADCx: ADC prescaler according to ADC_Prescaler */ - tmpreg |= (uint32_t)(ADC_CommonInitStruct->ADC_Prescaler); - - /* Write to ADC CCR */ - ADC->CCR = tmpreg; -} - -/** - * @brief Fills each ADC_CommonInitStruct member with its default value. - * @param ADC_CommonInitStruct: pointer to an ADC_CommonInitTypeDef structure - * which will be initialized. - * @retval None - */ -void ADC_CommonStructInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct) -{ - /* Reset ADC init structure parameters values */ - /* Initialize the ADC_Prescaler member */ - ADC_CommonInitStruct->ADC_Prescaler = ADC_Prescaler_Div1; - -} - -/** - * @brief Enables or disables the specified ADC peripheral. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param NewState: new state of the ADCx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Set the ADON bit to wake up the ADC from power down mode */ - ADCx->CR2 |= (uint32_t)ADC_CR2_ADON; - } - else - { - /* Disable the selected ADC peripheral */ - ADCx->CR2 &= (uint32_t)(~ADC_CR2_ADON); - } -} - -/** - * @} - */ - -/** @defgroup ADC_Group2 Power saving functions - * @brief Power saving functions - * -@verbatim - =============================================================================== - Power saving functions - =============================================================================== - - This section provides functions allowing to reduce power consumption. - The two function must be combined to get the maximal benefits: - When the ADC frequency is higher than the CPU one, it is recommended to - 1. Insert a freeze delay : - ==> using ADC_DelaySelectionConfig(ADC1, ADC_DelayLength_Freeze); - 2. Enable the power down in Idle and Delay phases : - ==> using ADC_PowerDownCmd(ADC1, ADC_PowerDown_Idle_Delay, ENABLE); - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the ADC Power Down during Delay and/or Idle phase. - * @note ADC power-on and power-off can be managed by hardware to cut the - * consumption when the ADC is not converting. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param ADC_PowerDown: The ADC power down configuration. - * This parameter can be one of the following values: - * @arg ADC_PowerDown_Delay: ADC is powered down during delay phase - * @arg ADC_PowerDown_Idle: ADC is powered down during Idle phase - * @arg ADC_PowerDown_Idle_Delay: ADC is powered down during Delay and Idle phases - * @note The ADC can be powered down: - * - During the hardware delay insertion (using the ADC_PowerDown_Delay - * parameter) - * => The ADC is powered up again at the end of the delay. - * - During the ADC is waiting for a trigger event ( using the - * ADC_PowerDown_Idle parameter) - * => The ADC is powered up at the next trigger event. - * - During the hardware delay insertion or the ADC is waiting for a - * trigger event (using the ADC_PowerDown_Idle_Delay parameter) - * => The ADC is powered up only at the end of the delay and at the - * next trigger event. - * @param NewState: new state of the ADCx power down. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_PowerDownCmd(ADC_TypeDef* ADCx, uint32_t ADC_PowerDown, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_ADC_POWER_DOWN(ADC_PowerDown)); - - if (NewState != DISABLE) - { - /* Enable the ADC power-down during Delay and/or Idle phase */ - ADCx->CR1 |= ADC_PowerDown; - } - else - { - /* Disable The ADC power-down during Delay and/or Idle phase */ - ADCx->CR1 &= (uint32_t)~ADC_PowerDown; - } -} - -/** - * @brief Defines the length of the delay which is applied after a conversion - * or a sequence of conversion. - * @note When the CPU clock is not fast enough to manage the data rate, a - * Hardware delay can be introduced between ADC conversions to reduce - * this data rate. - * @note The Hardware delay is inserted after : - * - each regular conversion - * - after each sequence of injected conversions - * @note No Hardware delay is inserted between conversions of different groups. - * @note When the hardware delay is not enough, the Freeze Delay Mode can be - * selected and a new conversion can start only if all the previous data - * of the same group have been treated: - * - for a regular conversion: once the ADC conversion data register has - * been read (using ADC_GetConversionValue() function) or if the EOC - * Flag has been cleared (using ADC_ClearFlag() function). - * - for an injected conversion: when the JEOC bit has been cleared - * (using ADC_ClearFlag() function). - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param ADC_DelayLength: The length of delay which is applied after a - * conversion or a sequence of conversion. - * This parameter can be one of the following values: - * @arg ADC_DelayLength_None: No delay - * @arg ADC_DelayLength_Freeze: Delay until the converted data has been read. - * @arg ADC_DelayLength_7Cycles: Delay length equal to 7 APB clock cycles - * @arg ADC_DelayLength_15Cycles: Delay length equal to 15 APB clock cycles - * @arg ADC_DelayLength_31Cycles: Delay length equal to 31 APB clock cycles - * @arg ADC_DelayLength_63Cycles: Delay length equal to 63 APB clock cycles - * @arg ADC_DelayLength_127Cycles: Delay length equal to 127 APB clock cycles - * @arg ADC_DelayLength_255Cycles: Delay length equal to 255 APB clock cycles - * @retval None - */ -void ADC_DelaySelectionConfig(ADC_TypeDef* ADCx, uint8_t ADC_DelayLength) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_DELAY_LENGTH(ADC_DelayLength)); - - /* Get the old register value */ - tmpreg = ADCx->CR2; - /* Clear the old delay length */ - tmpreg &= CR2_DELS_RESET; - /* Set the delay length */ - tmpreg |= ADC_DelayLength; - /* Store the new register value */ - ADCx->CR2 = tmpreg; - -} - -/** - * @} - */ - -/** @defgroup ADC_Group3 Analog Watchdog configuration functions - * @brief Analog Watchdog configuration functions - * -@verbatim - =============================================================================== - Analog Watchdog configuration functions - =============================================================================== - - This section provides functions allowing to configure the Analog Watchdog - (AWD) feature in the ADC. - - A typical configuration Analog Watchdog is done following these steps : - 1. the ADC guarded channel(s) is (are) selected using the - ADC_AnalogWatchdogSingleChannelConfig() function. - 2. The Analog watchdog lower and higher threshold are configured using the - ADC_AnalogWatchdogThresholdsConfig() function. - 3. The Analog watchdog is enabled and configured to enable the check, on one - or more channels, using the ADC_AnalogWatchdogCmd() function. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the analog watchdog on single/all regular - * or injected channels - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param ADC_AnalogWatchdog: the ADC analog watchdog configuration. - * This parameter can be one of the following values: - * @arg ADC_AnalogWatchdog_SingleRegEnable: Analog watchdog on a single - * regular channel - * @arg ADC_AnalogWatchdog_SingleInjecEnable: Analog watchdog on a single - * injected channel - * @arg ADC_AnalogWatchdog_SingleRegOrInjecEnable: Analog watchdog on a - * single regular or injected channel - * @arg ADC_AnalogWatchdog_AllRegEnable: Analog watchdog on all regular - * channel - * @arg ADC_AnalogWatchdog_AllInjecEnable: Analog watchdog on all injected - * channel - * @arg ADC_AnalogWatchdog_AllRegAllInjecEnable: Analog watchdog on all - * regular and injected channels - * @arg ADC_AnalogWatchdog_None: No channel guarded by the analog watchdog - * @retval None - */ -void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_ANALOG_WATCHDOG(ADC_AnalogWatchdog)); - - /* Get the old register value */ - tmpreg = ADCx->CR1; - /* Clear AWDEN, JAWDEN and AWDSGL bits */ - tmpreg &= CR1_AWDMODE_RESET; - /* Set the analog watchdog enable mode */ - tmpreg |= ADC_AnalogWatchdog; - /* Store the new register value */ - ADCx->CR1 = tmpreg; -} - -/** - * @brief Configures the high and low thresholds of the analog watchdog. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param HighThreshold: the ADC analog watchdog High threshold value. - * This parameter must be a 12bit value. - * @param LowThreshold: the ADC analog watchdog Low threshold value. - * This parameter must be a 12bit value. - * @retval None - */ -void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, - uint16_t LowThreshold) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_THRESHOLD(HighThreshold)); - assert_param(IS_ADC_THRESHOLD(LowThreshold)); - - /* Set the ADCx high threshold */ - ADCx->HTR = HighThreshold; - /* Set the ADCx low threshold */ - ADCx->LTR = LowThreshold; -} - -/** - * @brief Configures the analog watchdog guarded single channel - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param ADC_Channel: the ADC channel to configure for the analog watchdog. - * This parameter can be one of the following values: - * @arg ADC_Channel_0: ADC Channel0 selected - * @arg ADC_Channel_1: ADC Channel1 selected - * @arg ADC_Channel_2: ADC Channel2 selected - * @arg ADC_Channel_3: ADC Channel3 selected - * @arg ADC_Channel_4: ADC Channel4 selected - * @arg ADC_Channel_5: ADC Channel5 selected - * @arg ADC_Channel_6: ADC Channel6 selected - * @arg ADC_Channel_7: ADC Channel7 selected - * @arg ADC_Channel_8: ADC Channel8 selected - * @arg ADC_Channel_9: ADC Channel9 selected - * @arg ADC_Channel_10: ADC Channel10 selected - * @arg ADC_Channel_11: ADC Channel11 selected - * @arg ADC_Channel_12: ADC Channel12 selected - * @arg ADC_Channel_13: ADC Channel13 selected - * @arg ADC_Channel_14: ADC Channel14 selected - * @arg ADC_Channel_15: ADC Channel15 selected - * @arg ADC_Channel_16: ADC Channel16 selected - * @arg ADC_Channel_17: ADC Channel17 selected - * @arg ADC_Channel_18: ADC Channel18 selected - * @arg ADC_Channel_19: ADC Channel19 selected - * @arg ADC_Channel_20: ADC Channel20 selected - * @arg ADC_Channel_21: ADC Channel21 selected - * @arg ADC_Channel_22: ADC Channel22 selected - * @arg ADC_Channel_23: ADC Channel23 selected - * @arg ADC_Channel_24: ADC Channel24 selected - * @arg ADC_Channel_25: ADC Channel25 selected - * @retval None - */ -void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_CHANNEL(ADC_Channel)); - - /* Get the old register value */ - tmpreg = ADCx->CR1; - /* Clear the Analog watchdog channel select bits */ - tmpreg &= CR1_AWDCH_RESET; - /* Set the Analog watchdog channel */ - tmpreg |= ADC_Channel; - /* Store the new register value */ - ADCx->CR1 = tmpreg; -} - -/** - * @} - */ - -/** @defgroup ADC_Group4 Temperature Sensor & Vrefint (Voltage Reference internal) management function - * @brief Temperature Sensor & Vrefint (Voltage Reference internal) management function - * -@verbatim - =============================================================================== - Temperature Sensor & Vrefint (Voltage Reference internal) management function - =============================================================================== - - This section provides a function allowing to enable/ disable the internal - connections between the ADC and the Temperature Sensor and the Vrefint source. - - A typical configuration to get the Temperature sensor and Vrefint channels - voltages or is done following these steps : - 1. Enable the internal connection of Temperature sensor and Vrefint sources - with the ADC channels using ADC_TempSensorVrefintCmd() function. - 2. select the ADC_Channel_TempSensor and/or ADC_Channel_Vrefint using - ADC_RegularChannelConfig() or ADC_InjectedChannelConfig() functions - 3. Get the voltage values, using ADC_GetConversionValue() or - ADC_GetInjectedConversionValue(). - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the temperature sensor and Vrefint channel. - * @param NewState: new state of the temperature sensor and Vref int channels. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_TempSensorVrefintCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the temperature sensor and Vrefint channel*/ - ADC->CCR |= (uint32_t)ADC_CCR_TSVREFE; - } - else - { - /* Disable the temperature sensor and Vrefint channel*/ - ADC->CCR &= (uint32_t)(~ADC_CCR_TSVREFE); - } -} - -/** - * @} - */ - -/** @defgroup ADC_Group5 Regular Channels Configuration functions - * @brief Regular Channels Configuration functions - * -@verbatim - =============================================================================== - Regular Channels Configuration functions - =============================================================================== - - This section provides functions allowing to manage the ADC regular channels, - it is composed of 2 sub sections : - - 1. Configuration and management functions for regular channels: This subsection - provides functions allowing to configure the ADC regular channels : - - Configure the rank in the regular group sequencer for each channel - - Configure the sampling time for each channel - - select the conversion Trigger for regular channels - - select the desired EOC event behavior configuration - - Activate the continuous Mode (*) - - Activate the Discontinuous Mode - Please Note that the following features for regular channels are configurated - using the ADC_Init() function : - - scan mode activation - - continuous mode activation (**) - - External trigger source - - External trigger edge - - number of conversion in the regular channels group sequencer. - - @note : (*) and (**) are performing the same configuration - - 2. Get the conversion data: This subsection provides an important function in - the ADC peripheral since it returns the converted data of the current - regular channel. When the Conversion value is read, the EOC Flag is - automatically cleared. - -@endverbatim - * @{ - */ - -/** - * @brief Configures for the selected ADC regular channel its corresponding - * rank in the sequencer and its sampling time. - * @param ADCx: where x can be 1 to select the ADC peripheral. - * @param ADC_Channel: the ADC channel to configure. - * This parameter can be one of the following values: - * @arg ADC_Channel_0: ADC Channel0 selected - * @arg ADC_Channel_1: ADC Channel1 selected - * @arg ADC_Channel_2: ADC Channel2 selected - * @arg ADC_Channel_3: ADC Channel3 selected - * @arg ADC_Channel_4: ADC Channel4 selected - * @arg ADC_Channel_5: ADC Channel5 selected - * @arg ADC_Channel_6: ADC Channel6 selected - * @arg ADC_Channel_7: ADC Channel7 selected - * @arg ADC_Channel_8: ADC Channel8 selected - * @arg ADC_Channel_9: ADC Channel9 selected - * @arg ADC_Channel_10: ADC Channel10 selected - * @arg ADC_Channel_11: ADC Channel11 selected - * @arg ADC_Channel_12: ADC Channel12 selected - * @arg ADC_Channel_13: ADC Channel13 selected - * @arg ADC_Channel_14: ADC Channel14 selected - * @arg ADC_Channel_15: ADC Channel15 selected - * @arg ADC_Channel_16: ADC Channel16 selected - * @arg ADC_Channel_17: ADC Channel17 selected - * @arg ADC_Channel_18: ADC Channel18 selected - * @arg ADC_Channel_19: ADC Channel19 selected - * @arg ADC_Channel_20: ADC Channel20 selected - * @arg ADC_Channel_21: ADC Channel21 selected - * @arg ADC_Channel_22: ADC Channel22 selected - * @arg ADC_Channel_23: ADC Channel23 selected - * @arg ADC_Channel_24: ADC Channel24 selected - * @arg ADC_Channel_25: ADC Channel25 selected - * @param Rank: The rank in the regular group sequencer. This parameter - * must be between 1 to 26. - * @param ADC_SampleTime: The sample time value to be set for the selected - * channel. - * This parameter can be one of the following values: - * @arg ADC_SampleTime_4Cycles: Sample time equal to 4 cycles - * @arg ADC_SampleTime_9Cycles: Sample time equal to 9 cycles - * @arg ADC_SampleTime_16Cycles: Sample time equal to 16 cycles - * @arg ADC_SampleTime_24Cycles: Sample time equal to 24 cycles - * @arg ADC_SampleTime_48Cycles: Sample time equal to 48 cycles - * @arg ADC_SampleTime_96Cycles: Sample time equal to 96 cycles - * @arg ADC_SampleTime_192Cycles: Sample time equal to 192 cycles - * @arg ADC_SampleTime_384Cycles: Sample time equal to 384 cycles - * @retval None - */ -void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) -{ - uint32_t tmpreg1 = 0, tmpreg2 = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_CHANNEL(ADC_Channel)); - assert_param(IS_ADC_REGULAR_RANK(Rank)); - assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); - - /* if ADC_Channel_20 ... ADC_Channel_25 is selected */ - if (ADC_Channel > ADC_Channel_19) - { - /* Get the old register value */ - tmpreg1 = ADCx->SMPR1; - /* Calculate the mask to clear */ - tmpreg2 = SMPR1_SMP_SET << (3 * (ADC_Channel - 20)); - /* Clear the old sample time */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 20)); - /* Set the new sample time */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SMPR1 = tmpreg1; - } - - /* if ADC_Channel_10 ... ADC_Channel_19 is selected */ - else if (ADC_Channel > ADC_Channel_9) - { - /* Get the old register value */ - tmpreg1 = ADCx->SMPR2; - /* Calculate the mask to clear */ - tmpreg2 = SMPR2_SMP_SET << (3 * (ADC_Channel - 10)); - /* Clear the old sample time */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 10)); - /* Set the new sample time */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SMPR2 = tmpreg1; - } - - else /* ADC_Channel include in ADC_Channel_[0..9] */ - { - /* Get the old register value */ - tmpreg1 = ADCx->SMPR3; - /* Calculate the mask to clear */ - tmpreg2 = SMPR3_SMP_SET << (3 * ADC_Channel); - /* Clear the old sample time */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); - /* Set the new sample time */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SMPR3 = tmpreg1; - } - /* For Rank 1 to 6 */ - if (Rank < 7) - { - /* Get the old register value */ - tmpreg1 = ADCx->SQR5; - /* Calculate the mask to clear */ - tmpreg2 = SQR5_SQ_SET << (5 * (Rank - 1)); - /* Clear the old SQx bits for the selected rank */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 1)); - /* Set the SQx bits for the selected rank */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SQR5 = tmpreg1; - } - /* For Rank 7 to 12 */ - else if (Rank < 13) - { - /* Get the old register value */ - tmpreg1 = ADCx->SQR4; - /* Calculate the mask to clear */ - tmpreg2 = SQR4_SQ_SET << (5 * (Rank - 7)); - /* Clear the old SQx bits for the selected rank */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 7)); - /* Set the SQx bits for the selected rank */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SQR4 = tmpreg1; - } - /* For Rank 13 to 18 */ - else if (Rank < 19) - { - /* Get the old register value */ - tmpreg1 = ADCx->SQR3; - /* Calculate the mask to clear */ - tmpreg2 = SQR3_SQ_SET << (5 * (Rank - 13)); - /* Clear the old SQx bits for the selected rank */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 13)); - /* Set the SQx bits for the selected rank */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SQR3 = tmpreg1; - } - - /* For Rank 19 to 24 */ - else if (Rank < 25) - { - /* Get the old register value */ - tmpreg1 = ADCx->SQR2; - /* Calculate the mask to clear */ - tmpreg2 = SQR2_SQ_SET << (5 * (Rank - 19)); - /* Clear the old SQx bits for the selected rank */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 19)); - /* Set the SQx bits for the selected rank */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SQR2 = tmpreg1; - } - - /* For Rank 25 to 27 */ - else - { - /* Get the old register value */ - tmpreg1 = ADCx->SQR1; - /* Calculate the mask to clear */ - tmpreg2 = SQR1_SQ_SET << (5 * (Rank - 25)); - /* Clear the old SQx bits for the selected rank */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 25)); - /* Set the SQx bits for the selected rank */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SQR1 = tmpreg1; - } -} - -/** - * @brief Enables the selected ADC software start conversion of the regular channels. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @retval None - */ -void ADC_SoftwareStartConv(ADC_TypeDef* ADCx) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - - /* Enable the selected ADC conversion for regular group */ - ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART; -} - -/** - * @brief Gets the selected ADC Software start regular conversion Status. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @retval The new state of ADC software start conversion (SET or RESET). - */ -FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx) -{ - FlagStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - - /* Check the status of SWSTART bit */ - if ((ADCx->CR2 & ADC_CR2_SWSTART) != (uint32_t)RESET) - { - /* SWSTART bit is set */ - bitstatus = SET; - } - else - { - /* SWSTART bit is reset */ - bitstatus = RESET; - } - /* Return the SWSTART bit status */ - return bitstatus; -} - -/** - * @brief Enables or disables the EOC on each regular channel conversion - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param NewState: new state of the selected ADC EOC flag rising - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected ADC EOC rising on each regular channel conversion */ - ADCx->CR2 |= ADC_CR2_EOCS; - } - else - { - /* Disable the selected ADC EOC rising on each regular channel conversion */ - ADCx->CR2 &= (uint32_t)~ADC_CR2_EOCS; - } -} - -/** - * @brief Enables or disables the ADC continuous conversion mode - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param NewState: new state of the selected ADC continuous conversion mode - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected ADC continuous conversion mode */ - ADCx->CR2 |= (uint32_t)ADC_CR2_CONT; - } - else - { - /* Disable the selected ADC continuous conversion mode */ - ADCx->CR2 &= (uint32_t)(~ADC_CR2_CONT); - } -} - -/** - * @brief Configures the discontinuous mode for the selected ADC regular - * group channel. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param Number: specifies the discontinuous mode regular channel count value. - * This number must be between 1 and 8. - * @retval None - */ -void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number) -{ - uint32_t tmpreg1 = 0; - uint32_t tmpreg2 = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_REGULAR_DISC_NUMBER(Number)); - - /* Get the old register value */ - tmpreg1 = ADCx->CR1; - /* Clear the old discontinuous mode channel count */ - tmpreg1 &= CR1_DISCNUM_RESET; - /* Set the discontinuous mode channel count */ - tmpreg2 = Number - 1; - tmpreg1 |= tmpreg2 << 13; - /* Store the new register value */ - ADCx->CR1 = tmpreg1; -} - -/** - * @brief Enables or disables the discontinuous mode on regular group - * channel for the specified ADC - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param NewState: new state of the selected ADC discontinuous mode on regular - * group channel. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected ADC regular discontinuous mode */ - ADCx->CR1 |= (uint32_t)ADC_CR1_DISCEN; - } - else - { - /* Disable the selected ADC regular discontinuous mode */ - ADCx->CR1 &= (uint32_t)(~ADC_CR1_DISCEN); - } -} - -/** - * @brief Returns the last ADCx conversion result data for regular channel. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @retval The Data conversion value. - */ -uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - - /* Return the selected ADC conversion value */ - return (uint16_t) ADCx->DR; -} - -/** - * @} - */ - -/** @defgroup ADC_Group6 Regular Channels DMA Configuration functions - * @brief Regular Channels DMA Configuration functions - * -@verbatim - =============================================================================== - Regular Channels DMA Configuration functions - =============================================================================== - - This section provides functions allowing to configure the DMA for ADC regular - channels. - Since converted regular channel values are stored into a unique data register, - it is useful to use DMA for conversion of more than one regular channel. This - avoids the loss of the data already stored in the ADC Data register. - - When the DMA mode is enabled (using the ADC_DMACmd() function), after each - conversion of a regular channel, a DMA request is generated. - - Depending on the "DMA disable selection" configuration (using the - ADC_DMARequestAfterLastTransferCmd() function), at the end of the last DMA - transfer, two possibilities are allowed: - - No new DMA request is issued to the DMA controller (feature DISABLED) - - Requests can continue to be generated (feature ENABLED). - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified ADC DMA request. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param NewState: new state of the selected ADC DMA transfer. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_DMA_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected ADC DMA request */ - ADCx->CR2 |= (uint32_t)ADC_CR2_DMA; - } - else - { - /* Disable the selected ADC DMA request */ - ADCx->CR2 &= (uint32_t)(~ADC_CR2_DMA); - } -} - - -/** - * @brief Enables or disables the ADC DMA request after last transfer (Single-ADC mode) - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param NewState: new state of the selected ADC EOC flag rising - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected ADC DMA request after last transfer */ - ADCx->CR2 |= ADC_CR2_DDS; - } - else - { - /* Disable the selected ADC DMA request after last transfer */ - ADCx->CR2 &= (uint32_t)~ADC_CR2_DDS; - } -} - -/** - * @} - */ - -/** @defgroup ADC_Group7 Injected channels Configuration functions - * @brief Injected channels Configuration functions - * -@verbatim - =============================================================================== - Injected channels Configuration functions - =============================================================================== - - This section provide functions allowing to configure the ADC Injected channels, - it is composed of 2 sub sections : - - 1. Configuration functions for Injected channels: This subsection provides - functions allowing to configure the ADC injected channels : - - Configure the rank in the injected group sequencer for each channel - - Configure the sampling time for each channel - - Activate the Auto injected Mode - - Activate the Discontinuous Mode - - scan mode activation - - External/software trigger source - - External trigger edge - - injected channels sequencer. - - 2. Get the Specified Injected channel conversion data: This subsection - provides an important function in the ADC peripheral since it returns the - converted data of the specific injected channel. - -@endverbatim - * @{ - */ - -/** - * @brief Configures for the selected ADC injected channel its corresponding - * rank in the sequencer and its sample time. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param ADC_Channel: the ADC channel to configure. - * This parameter can be one of the following values: - * @arg ADC_Channel_0: ADC Channel0 selected - * @arg ADC_Channel_1: ADC Channel1 selected - * @arg ADC_Channel_2: ADC Channel2 selected - * @arg ADC_Channel_3: ADC Channel3 selected - * @arg ADC_Channel_4: ADC Channel4 selected - * @arg ADC_Channel_5: ADC Channel5 selected - * @arg ADC_Channel_6: ADC Channel6 selected - * @arg ADC_Channel_7: ADC Channel7 selected - * @arg ADC_Channel_8: ADC Channel8 selected - * @arg ADC_Channel_9: ADC Channel9 selected - * @arg ADC_Channel_10: ADC Channel10 selected - * @arg ADC_Channel_11: ADC Channel11 selected - * @arg ADC_Channel_12: ADC Channel12 selected - * @arg ADC_Channel_13: ADC Channel13 selected - * @arg ADC_Channel_14: ADC Channel14 selected - * @arg ADC_Channel_15: ADC Channel15 selected - * @arg ADC_Channel_16: ADC Channel16 selected - * @arg ADC_Channel_17: ADC Channel17 selected - * @arg ADC_Channel_18: ADC Channel18 selected - * @arg ADC_Channel_19: ADC Channel19 selected - * @arg ADC_Channel_20: ADC Channel20 selected - * @arg ADC_Channel_21: ADC Channel21 selected - * @arg ADC_Channel_22: ADC Channel22 selected - * @arg ADC_Channel_23: ADC Channel23 selected - * @arg ADC_Channel_24: ADC Channel24 selected - * @arg ADC_Channel_25: ADC Channel25 selected - * @param Rank: The rank in the injected group sequencer. This parameter - * must be between 1 to 4. - * @param ADC_SampleTime: The sample time value to be set for the selected - * channel. This parameter can be one of the following values: - * @arg ADC_SampleTime_4Cycles: Sample time equal to 4 cycles - * @arg ADC_SampleTime_9Cycles: Sample time equal to 9 cycles - * @arg ADC_SampleTime_16Cycles: Sample time equal to 16 cycles - * @arg ADC_SampleTime_24Cycles: Sample time equal to 24 cycles - * @arg ADC_SampleTime_48Cycles: Sample time equal to 48 cycles - * @arg ADC_SampleTime_96Cycles: Sample time equal to 96 cycles - * @arg ADC_SampleTime_192Cycles: Sample time equal to 192 cycles - * @arg ADC_SampleTime_384Cycles: Sample time equal to 384 cycles - * @retval None - */ -void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) -{ - uint32_t tmpreg1 = 0, tmpreg2 = 0, tmpreg3 = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_CHANNEL(ADC_Channel)); - assert_param(IS_ADC_INJECTED_RANK(Rank)); - assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); - - /* if ADC_Channel_20 ... ADC_Channel_25 is selected */ - if (ADC_Channel > ADC_Channel_19) - { - /* Get the old register value */ - tmpreg1 = ADCx->SMPR1; - /* Calculate the mask to clear */ - tmpreg2 = SMPR1_SMP_SET << (3 * (ADC_Channel - 20)); - /* Clear the old sample time */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 20)); - /* Set the new sample time */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SMPR1 = tmpreg1; - } - - /* if ADC_Channel_10 ... ADC_Channel_19 is selected */ - else if (ADC_Channel > ADC_Channel_9) - { - /* Get the old register value */ - tmpreg1 = ADCx->SMPR2; - /* Calculate the mask to clear */ - tmpreg2 = SMPR2_SMP_SET << (3 * (ADC_Channel - 10)); - /* Clear the old sample time */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 10)); - /* Set the new sample time */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SMPR2 = tmpreg1; - } - - else /* ADC_Channel include in ADC_Channel_[0..9] */ - { - /* Get the old register value */ - tmpreg1 = ADCx->SMPR3; - /* Calculate the mask to clear */ - tmpreg2 = SMPR3_SMP_SET << (3 * ADC_Channel); - /* Clear the old sample time */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); - /* Set the new sample time */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SMPR3 = tmpreg1; - } - - /* Rank configuration */ - /* Get the old register value */ - tmpreg1 = ADCx->JSQR; - /* Get JL value: Number = JL+1 */ - tmpreg3 = (tmpreg1 & JSQR_JL_SET)>> 20; - /* Calculate the mask to clear: ((Rank-1)+(4- (JL+1))) */ - tmpreg2 = JSQR_JSQ_SET << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1))); - /* Clear the old JSQx bits for the selected rank */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set: ((Rank-1)+(4- (JL+1))) */ - tmpreg2 = (uint32_t)ADC_Channel << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1))); - /* Set the JSQx bits for the selected rank */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->JSQR = tmpreg1; -} - -/** - * @brief Configures the sequencer length for injected channels - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param Length: The sequencer length. - * This parameter must be a number between 1 to 4. - * @retval None - */ -void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length) -{ - uint32_t tmpreg1 = 0; - uint32_t tmpreg2 = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_INJECTED_LENGTH(Length)); - - /* Get the old register value */ - tmpreg1 = ADCx->JSQR; - /* Clear the old injected sequence length JL bits */ - tmpreg1 &= JSQR_JL_RESET; - /* Set the injected sequence length JL bits */ - tmpreg2 = Length - 1; - tmpreg1 |= tmpreg2 << 20; - /* Store the new register value */ - ADCx->JSQR = tmpreg1; -} - -/** - * @brief Set the injected channels conversion value offset - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param ADC_InjectedChannel: the ADC injected channel to set its offset. - * This parameter can be one of the following values: - * @arg ADC_InjectedChannel_1: Injected Channel1 selected - * @arg ADC_InjectedChannel_2: Injected Channel2 selected - * @arg ADC_InjectedChannel_3: Injected Channel3 selected - * @arg ADC_InjectedChannel_4: Injected Channel4 selected - * @param Offset: the offset value for the selected ADC injected channel - * This parameter must be a 12bit value. - * @retval None - */ -void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel)); - assert_param(IS_ADC_OFFSET(Offset)); - - tmp = (uint32_t)ADCx; - tmp += ADC_InjectedChannel; - - /* Set the selected injected channel data offset */ - *(__IO uint32_t *) tmp = (uint32_t)Offset; -} - -/** - * @brief Configures the ADCx external trigger for injected channels conversion. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param ADC_ExternalTrigInjecConv: specifies the ADC trigger to start injected - * conversion. This parameter can be one of the following values: - * @arg ADC_ExternalTrigInjecConv_T9_CC1: Timer9 capture compare1 selected - * @arg ADC_ExternalTrigInjecConv_T9_TRGO: Timer9 TRGO event selected - * @arg ADC_ExternalTrigInjecConv_T2_TRGO: Timer2 TRGO event selected - * @arg ADC_ExternalTrigInjecConv_T2_CC1: Timer2 capture compare1 selected - * @arg ADC_ExternalTrigInjecConv_T3_CC4: Timer3 capture compare4 selected - * @arg ADC_ExternalTrigInjecConv_T4_TRGO: Timer4 TRGO event selected - * @arg ADC_ExternalTrigInjecConv_T4_CC1: Timer4 capture compare1 selected - * @arg ADC_ExternalTrigInjecConv_T4_CC2: Timer4 capture compare2 selected - * @arg ADC_ExternalTrigInjecConv_T4_CC3: Timer4 capture compare3 selected - * @arg ADC_ExternalTrigInjecConv_T10_CC1: Timer10 capture compare1 selected - * @arg ADC_ExternalTrigInjecConv_T7_TRGO: Timer7 TRGO event selected - * @arg ADC_ExternalTrigInjecConv_Ext_IT15: External interrupt line 15 event selected - * @retval None - */ -void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_EXT_INJEC_TRIG(ADC_ExternalTrigInjecConv)); - - /* Get the old register value */ - tmpreg = ADCx->CR2; - /* Clear the old external event selection for injected group */ - tmpreg &= CR2_JEXTSEL_RESET; - /* Set the external event selection for injected group */ - tmpreg |= ADC_ExternalTrigInjecConv; - /* Store the new register value */ - ADCx->CR2 = tmpreg; -} - -/** - * @brief Configures the ADCx external trigger edge for injected channels conversion. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param ADC_ExternalTrigInjecConvEdge: specifies the ADC external trigger - * edge to start injected conversion. - * This parameter can be one of the following values: - * @arg ADC_ExternalTrigConvEdge_None: external trigger disabled for - * injected conversion - * @arg ADC_ExternalTrigConvEdge_Rising: detection on rising edge - * @arg ADC_ExternalTrigConvEdge_Falling: detection on falling edge - * @arg ADC_External ADC_ExternalTrigConvEdge_RisingFalling: detection on - * both rising and falling edge - * @retval None - */ -void ADC_ExternalTrigInjectedConvEdgeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConvEdge) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(ADC_ExternalTrigInjecConvEdge)); - - /* Get the old register value */ - tmpreg = ADCx->CR2; - /* Clear the old external trigger edge for injected group */ - tmpreg &= CR2_JEXTEN_RESET; - /* Set the new external trigger edge for injected group */ - tmpreg |= ADC_ExternalTrigInjecConvEdge; - /* Store the new register value */ - ADCx->CR2 = tmpreg; -} - -/** - * @brief Enables the selected ADC software start conversion of the injected - * channels. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @retval None - */ -void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - /* Enable the selected ADC conversion for injected group */ - ADCx->CR2 |= (uint32_t)ADC_CR2_JSWSTART; -} - -/** - * @brief Gets the selected ADC Software start injected conversion Status. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @retval The new state of ADC software start injected conversion (SET or RESET). - */ -FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx) -{ - FlagStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - - /* Check the status of JSWSTART bit */ - if ((ADCx->CR2 & ADC_CR2_JSWSTART) != (uint32_t)RESET) - { - /* JSWSTART bit is set */ - bitstatus = SET; - } - else - { - /* JSWSTART bit is reset */ - bitstatus = RESET; - } - /* Return the JSWSTART bit status */ - return bitstatus; -} - -/** - * @brief Enables or disables the selected ADC automatic injected group - * conversion after regular one. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param NewState: new state of the selected ADC auto injected - * conversion. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected ADC automatic injected group conversion */ - ADCx->CR1 |= (uint32_t)ADC_CR1_JAUTO; - } - else - { - /* Disable the selected ADC automatic injected group conversion */ - ADCx->CR1 &= (uint32_t)(~ADC_CR1_JAUTO); - } -} - -/** - * @brief Enables or disables the discontinuous mode for injected group - * channel for the specified ADC - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param NewState: new state of the selected ADC discontinuous mode - * on injected group channel. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected ADC injected discontinuous mode */ - ADCx->CR1 |= (uint32_t)ADC_CR1_JDISCEN; - } - else - { - /* Disable the selected ADC injected discontinuous mode */ - ADCx->CR1 &= (uint32_t)(~ADC_CR1_JDISCEN); - } -} - -/** - * @brief Returns the ADC injected channel conversion result - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param ADC_InjectedChannel: the converted ADC injected channel. - * This parameter can be one of the following values: - * @arg ADC_InjectedChannel_1: Injected Channel1 selected - * @arg ADC_InjectedChannel_2: Injected Channel2 selected - * @arg ADC_InjectedChannel_3: Injected Channel3 selected - * @arg ADC_InjectedChannel_4: Injected Channel4 selected - * @retval The Data conversion value. - */ -uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel)); - - tmp = (uint32_t)ADCx; - tmp += ADC_InjectedChannel + JDR_OFFSET; - - /* Returns the selected injected channel conversion data value */ - return (uint16_t) (*(__IO uint32_t*) tmp); -} - -/** - * @} - */ - -/** @defgroup ADC_Group8 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - - This section provides functions allowing to configure the ADC Interrupts and get - the status and clear flags and Interrupts pending bits. - - The ADC provide 4 Interrupts sources and 9 Flags which can be divided into 3 groups: - - I. Flags and Interrupts for ADC regular channels - ================================================= - Flags : - ---------- - 1. ADC_FLAG_OVR : Overrun detection when regular converted data are lost - - 2. ADC_FLAG_EOC : Regular channel end of conversion+ to indicate (depending - on EOCS bit, managed by ADC_EOCOnEachRegularChannelCmd() ) the end of : - ==> a regular CHANNEL conversion - ==> sequence of regular GROUP conversions . - - 3. ADC_FLAG_STRT: Regular channel start+ to indicate when regular CHANNEL - conversion starts. - - 4. ADC_FLAG_RCNR: Regular channel not ready+ to indicate if a new regular - conversion can be launched - - Interrupts : - ------------ - 1. ADC_IT_OVR - 2. ADC_IT_EOC - - - II. Flags and Interrupts for ADC Injected channels - ================================================= - Flags : - ---------- - 1. ADC_FLAG_JEOC : Injected channel end of conversion+ to indicate at - the end of injected GROUP conversion - - 2. ADC_FLAG_JSTRT: Injected channel start+ to indicate hardware when - injected GROUP conversion starts. - - 3. ADC_FLAG_JCNR: Injected channel not ready+ to indicate if a new - injected conversion can be launched. - - Interrupts : - ------------ - 1. ADC_IT_JEOC - - III. General Flags and Interrupts for the ADC - ================================================= - Flags : - ---------- - 1. ADC_FLAG_AWD: Analog watchdog+ to indicate if the converted voltage - crosses the programmed thresholds values. - - 2. ADC_FLAG_ADONS: ADC ON status+ to indicate if the ADC is ready to convert. - - Interrupts : - ------------ - 1. ADC_IT_AWD - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified ADC interrupts. - * @param ADCx: where x can be 1 to select the ADC peripheral. - * @param ADC_IT: specifies the ADC interrupt sources to be enabled or disabled. - * This parameter can be one of the following values: - * @arg ADC_IT_EOC: End of conversion interrupt - * @arg ADC_IT_AWD: Analog watchdog interrupt - * @arg ADC_IT_JEOC: End of injected conversion interrupt - * @arg ADC_IT_OVR: overrun interrupt - * @param NewState: new state of the specified ADC interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState) -{ - uint32_t itmask = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_ADC_IT(ADC_IT)); - - /* Get the ADC IT index */ - itmask = (uint8_t)ADC_IT; - itmask = (uint32_t)0x01 << itmask; - - if (NewState != DISABLE) - { - /* Enable the selected ADC interrupts */ - ADCx->CR1 |= itmask; - } - else - { - /* Disable the selected ADC interrupts */ - ADCx->CR1 &= (~(uint32_t)itmask); - } -} - -/** - * @brief Checks whether the specified ADC flag is set or not. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param ADC_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg ADC_FLAG_AWD: Analog watchdog flag - * @arg ADC_FLAG_EOC: End of conversion flag - * @arg ADC_FLAG_JEOC: End of injected group conversion flag - * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag - * @arg ADC_FLAG_STRT: Start of regular group conversion flag - * @arg ADC_FLAG_OVR: Overrun flag - * @arg ADC_FLAG_ADONS: ADC ON status - * @arg ADC_FLAG_RCNR: Regular channel not ready - * @arg ADC_FLAG_JCNR: Injected channel not ready - * @retval The new state of ADC_FLAG (SET or RESET). - */ -FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint16_t ADC_FLAG) -{ - FlagStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_GET_FLAG(ADC_FLAG)); - - /* Check the status of the specified ADC flag */ - if ((ADCx->SR & ADC_FLAG) != (uint8_t)RESET) - { - /* ADC_FLAG is set */ - bitstatus = SET; - } - else - { - /* ADC_FLAG is reset */ - bitstatus = RESET; - } - /* Return the ADC_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the ADCx's pending flags. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param ADC_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg ADC_FLAG_AWD: Analog watchdog flag - * @arg ADC_FLAG_EOC: End of conversion flag - * @arg ADC_FLAG_JEOC: End of injected group conversion flag - * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag - * @arg ADC_FLAG_STRT: Start of regular group conversion flag - * @arg ADC_FLAG_OVR: overrun flag - * @retval None - */ -void ADC_ClearFlag(ADC_TypeDef* ADCx, uint16_t ADC_FLAG) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_CLEAR_FLAG(ADC_FLAG)); - - /* Clear the selected ADC flags */ - ADCx->SR = ~(uint32_t)ADC_FLAG; -} - -/** - * @brief Checks whether the specified ADC interrupt has occurred or not. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param ADC_IT: specifies the ADC interrupt source to check. - * This parameter can be one of the following values: - * @arg ADC_IT_EOC: End of conversion interrupt - * @arg ADC_IT_AWD: Analog watchdog interrupt - * @arg ADC_IT_JEOC: End of injected conversion interrupt - * @arg ADC_IT_OVR: Overrun interrupt - * @retval The new state of ADC_IT (SET or RESET). - */ -ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT) -{ - ITStatus bitstatus = RESET; - uint32_t itmask = 0, enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_IT(ADC_IT)); - - /* Get the ADC IT index */ - itmask = (uint32_t)((uint32_t)ADC_IT >> 8); - - /* Get the ADC_IT enable bit status */ - enablestatus = (ADCx->CR1 & ((uint32_t)0x01 << (uint8_t)ADC_IT)); - - /* Check the status of the specified ADC interrupt */ - if (((uint32_t)(ADCx->SR & (uint32_t)itmask) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET)) - { - /* ADC_IT is set */ - bitstatus = SET; - } - else - { - /* ADC_IT is reset */ - bitstatus = RESET; - } - /* Return the ADC_IT status */ - return bitstatus; -} - -/** - * @brief Clears the ADCxs interrupt pending bits. - * @param ADCx: where x can be 1 to select the ADC1 peripheral. - * @param ADC_IT: specifies the ADC interrupt pending bit to clear. - * This parameter can be one of the following values: - * @arg ADC_IT_EOC: End of conversion interrupt - * @arg ADC_IT_AWD: Analog watchdog interrupt - * @arg ADC_IT_JEOC: End of injected conversion interrupt - * @arg ADC_IT_OVR: Overrun interrupt - * @retval None - */ -void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT) -{ - uint8_t itmask = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_IT(ADC_IT)); - - /* Get the ADC IT index */ - itmask = (uint8_t)(ADC_IT >> 8); - - /* Clear the selected ADC interrupt pending bits */ - ADCx->SR = ~(uint32_t)itmask; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_comp.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_comp.c deleted file mode 100644 index 289a536aa..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_comp.c +++ /dev/null @@ -1,356 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_comp.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the comparators (COMP1 and COMP2) peripheral: - * - Comparators configuration - * - Window mode control - * - Internal Reference Voltage (VREFINT) output - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * - * The device integrates two analog comparators COMP1 and COMP2: - * - COMP1 is a fixed threshold (VREFINT) that shares the non inverting - * input with the ADC channels. - * - * - COMP2 is a rail-to-rail comparator whose the inverting input - * can be selected among: DAC_OUT1, DAC_OUT2, 1/4 VREFINT, - * 1/2 VERFINT, 3/4 VREFINT, VREFINT, PB3 and whose the output - * can be redirected to embedded timers: TIM2, TIM3, TIM4, TIM10 - * - * - The two comparators COMP1 and COMP2 can be combined in window - * mode. - * - * @note - * 1- Comparator APB clock must be enabled to get write access - * to comparator register using - * RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP, ENABLE); - * - * 2- COMP1 comparator and ADC can't be used at the same time since - * they share the same ADC switch matrix (analog switches). - * - * 3- When an I/O is used as comparator input, the corresponding GPIO - * registers should be configured in analog mode. - * - * 4- Comparators outputs (CMP1OUT and CMP2OUT) are not mapped on - * GPIO pin. They are only internal. - * To get the comparator output level, use COMP_GetOutputLevel() - * - * 5- COMP1 and COMP2 outputs are internally connected to EXTI Line 21 - * and EXTI Line 22 respectively. - * Interrupts can be used by configuring the EXTI Line using the - * EXTI peripheral driver. - * - * 6- After enabling the comparator (COMP1 or COMP2), user should wait - * for start-up time (tSTART) to get right output levels. - * Please refer to product datasheet for more information on tSTART. - * - * 7- Comparators cannot be used to exit the device from Sleep or Stop - * mode when the internal reference voltage is switched off using - * the PWR_UltraLowPowerCmd() function (ULP bit in the PWR_CR register). - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_comp.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup COMP - * @brief COMP driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup COMP_Private_Functions - * @{ - */ - -/** @defgroup COMP_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes COMP peripheral registers to their default reset values. - * @param None - * @retval None - */ -void COMP_DeInit(void) -{ - COMP->CSR = ((uint32_t)0x00000000); /*!< Set COMP->CSR to reset value */ -} - -/** - * @brief Initializes the COMP2 peripheral according to the specified parameters - * in the COMP_InitStruct: - * - COMP_InvertingInput specify the inverting input of COMP2 - * - COMP_OutputSelect connect the output of COMP2 to selected timer - * input (Input capture / Output Compare Reference Clear) - * - COMP_Speed configures COMP2 speed for optimum speed/consumption ratio - * @note This function configures only COMP2. - * @note COMP2 comparator is enabled as soon as the INSEL[2:0] bits are - * different from "000". - * @param COMP_InitStruct: pointer to an COMP_InitTypeDef structure that contains - * the configuration information for the specified COMP peripheral. - * @retval None - */ -void COMP_Init(COMP_InitTypeDef* COMP_InitStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_COMP_INVERTING_INPUT(COMP_InitStruct->COMP_InvertingInput)); - assert_param(IS_COMP_OUTPUT(COMP_InitStruct->COMP_OutputSelect)); - assert_param(IS_COMP_SPEED(COMP_InitStruct->COMP_Speed)); - - /*!< Get the COMP CSR value */ - tmpreg = COMP->CSR; - - /*!< Clear the INSEL[2:0], OUTSEL[1:0] and SPEED bits */ - tmpreg &= (uint32_t) (~(uint32_t) (COMP_CSR_OUTSEL | COMP_CSR_INSEL | COMP_CSR_SPEED)); - - /*!< Configure COMP: speed, inversion input selection and output redirection */ - /*!< Set SPEED bit according to COMP_InitStruct->COMP_Speed value */ - /*!< Set INSEL bits according to COMP_InitStruct->COMP_InvertingInput value */ - /*!< Set OUTSEL bits according to COMP_InitStruct->COMP_OutputSelect value */ - tmpreg |= (uint32_t)((COMP_InitStruct->COMP_Speed | COMP_InitStruct->COMP_InvertingInput - | COMP_InitStruct->COMP_OutputSelect)); - - /*!< The COMP2 comparator is enabled as soon as the INSEL[2:0] bits value are - different from "000" */ - /*!< Write to COMP_CSR register */ - COMP->CSR = tmpreg; -} - -/** - * @brief Enable or disable the COMP1 peripheral. - * After enabling COMP1, the following functions should be called to - * connect the selected GPIO input to COMP1 non inverting input: - * - Enable switch control mode using SYSCFG_RISwitchControlModeCmd() - * - Close VCOMP switch using SYSCFG_RIIOSwitchConfig() - * - Close the I/O switch number n corresponding to the I/O - * using SYSCFG_RIIOSwitchConfig() - * @param NewState: new state of the COMP1 peripheral. - * This parameter can be: ENABLE or DISABLE. - * @note This function enables/disables only the COMP1. - * @retval None - */ -void COMP_Cmd(FunctionalState NewState) -{ - /* Check the parameter */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the COMP1 */ - COMP->CSR |= (uint32_t) COMP_CSR_CMP1EN; - } - else - { - /* Disable the COMP1 */ - COMP->CSR &= (uint32_t)(~COMP_CSR_CMP1EN); - } -} - -/** - * @brief Return the output level (high or low) of the selected comparator: - * - Comparator output is low when the non-inverting input is at a lower - * voltage than the inverting input - * - Comparator output is high when the non-inverting input is at a higher - * voltage than the inverting input - * @note Comparators outputs aren't available on GPIO (outputs levels are - * only internal). The COMP1 and COMP2 outputs are connected internally - * to the EXTI Line 21 and Line 22 respectively. - * @param COMP_Selection: the selected comparator. - * This parameter can be one of the following values: - * @arg COMP_Selection_COMP1: COMP1 selected - * @arg COMP_Selection_COMP2: COMP2 selected - * @retval Returns the selected comparator output level. - */ -uint8_t COMP_GetOutputLevel(uint32_t COMP_Selection) -{ - uint8_t compout = 0x0; - - /* Check the parameters */ - assert_param(IS_COMP_ALL_PERIPH(COMP_Selection)); - - /* Check if Comparator 1 is selected */ - if(COMP_Selection == COMP_Selection_COMP1) - { - /* Check if comparator 1 output level is high */ - if((COMP->CSR & COMP_CSR_CMP1OUT) != (uint8_t) RESET) - { - /* Get Comparator 1 output level */ - compout = (uint8_t) COMP_OutputLevel_High; - } - /* comparator 1 output level is low */ - else - { - /* Get Comparator 1 output level */ - compout = (uint8_t) COMP_OutputLevel_Low; - } - } - /* Comparator 2 is selected */ - else - { - /* Check if comparator 2 output level is high */ - if((COMP->CSR & COMP_CSR_CMP2OUT) != (uint8_t) RESET) - { - /* Get Comparator output level */ - compout = (uint8_t) COMP_OutputLevel_High; - } - /* comparator 2 output level is low */ - else - { - /* Get Comparator 2 output level */ - compout = (uint8_t) COMP_OutputLevel_Low; - } - } - /* Return the comparator output level */ - return (uint8_t)(compout); -} - -/** - * @} - */ - -/** @defgroup COMP_Group2 Window mode control function - * @brief Window mode control function - * -@verbatim - =============================================================================== - Window mode control function - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the window mode. - * In window mode: - * - COMP1 inverting input is fixed to VREFINT defining the first - * threshold - * - COMP2 inverting input is configurable (DAC_OUT1, DAC_OUT2, VREFINT - * sub-multiples, PB3) defining the second threshold - * - COMP1 and COMP2 non inverting inputs are connected together. - * @note In window mode, only the Group 6 (PB4 or PB5) can be used as - * non-inverting inputs. - * param NewState: new state of the window mode. - * This parameter can be ENABLE or DISABLE. - * @retval None - */ -void COMP_WindowCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the window mode */ - COMP->CSR |= (uint32_t) COMP_CSR_WNDWE; - } - else - { - /* Disable the window mode */ - COMP->CSR &= (uint32_t)(~COMP_CSR_WNDWE); - } -} - -/** - * @} - */ - -/** @defgroup COMP_Group3 Internal Reference Voltage output function - * @brief Internal Reference Voltage (VREFINT) output function - * -@verbatim - =============================================================================== - Internal Reference Voltage (VREFINT) output function - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the output of internal reference voltage (VREFINT). - * The VREFINT output can be routed to any I/O in group 3: CH8 (PB0) or - * CH9 (PB1). - * To correctly use this function, the SYSCFG_RIIOSwitchConfig() function - * should be called after. - * @param NewState: new state of the Vrefint output. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void COMP_VrefintOutputCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the output of internal reference voltage */ - COMP->CSR |= (uint32_t) COMP_CSR_VREFOUTEN; - } - else - { - /* Disable the output of internal reference voltage */ - COMP->CSR &= (uint32_t) (~COMP_CSR_VREFOUTEN); - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_crc.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_crc.c deleted file mode 100644 index 0a8836824..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_crc.c +++ /dev/null @@ -1,127 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_crc.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides all the CRC firmware functions. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_crc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup CRC - * @brief CRC driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup CRC_Private_Functions - * @{ - */ - -/** - * @brief Resets the CRC Data register (DR). - * @param None - * @retval None - */ -void CRC_ResetDR(void) -{ - /* Reset CRC generator */ - CRC->CR = CRC_CR_RESET; -} - -/** - * @brief Computes the 32-bit CRC of a given data word(32-bit). - * @param Data: data word(32-bit) to compute its CRC - * @retval 32-bit CRC - */ -uint32_t CRC_CalcCRC(uint32_t Data) -{ - CRC->DR = Data; - - return (CRC->DR); -} - -/** - * @brief Computes the 32-bit CRC of a given buffer of data word(32-bit). - * @param pBuffer: pointer to the buffer containing the data to be computed - * @param BufferLength: length of the buffer to be computed - * @retval 32-bit CRC - */ -uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength) -{ - uint32_t index = 0; - - for(index = 0; index < BufferLength; index++) - { - CRC->DR = pBuffer[index]; - } - return (CRC->DR); -} - -/** - * @brief Returns the current CRC value. - * @param None - * @retval 32-bit CRC - */ -uint32_t CRC_GetCRC(void) -{ - return (CRC->DR); -} - -/** - * @brief Stores a 8-bit data in the Independent Data(ID) register. - * @param IDValue: 8-bit value to be stored in the ID register - * @retval None - */ -void CRC_SetIDRegister(uint8_t IDValue) -{ - CRC->IDR = IDValue; -} - -/** - * @brief Returns the 8-bit data stored in the Independent Data(ID) register - * @param None - * @retval 8-bit value of the ID register - */ -uint8_t CRC_GetIDRegister(void) -{ - return (CRC->IDR); -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_dac.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_dac.c deleted file mode 100644 index dcc59c9b0..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_dac.c +++ /dev/null @@ -1,690 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_dac.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the Digital-to-Analog Converter (DAC) peripheral: - * - DAC channels configuration: trigger, output buffer, data format - * - DMA management - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * DAC Peripheral features - * =================================================================== - * The device integrates two 12-bit Digital Analog Converters that can - * be used independently or simultaneously (dual mode): - * 1- DAC channel1 with DAC_OUT1 (PA4) as output - * 1- DAC channel2 with DAC_OUT2 (PA5) as output - * - * Digital to Analog conversion can be non-triggered using DAC_Trigger_None - * and DAC_OUT1/DAC_OUT2 is available once writing to DHRx register using - * DAC_SetChannel1Data()/DAC_SetChannel2Data. - * - * Digital to Analog conversion can be triggered by: - * 1- External event: EXTI Line 9 (any GPIOx_Pin9) using DAC_Trigger_Ext_IT9. - * The used pin (GPIOx_Pin9) must be configured in input mode. - * - * 2- Timers TRGO: TIM2, TIM4, TIM6, TIM7 and TIM9 - * (DAC_Trigger_T2_TRGO, DAC_Trigger_T4_TRGO...) - * The timer TRGO event should be selected using TIM_SelectOutputTrigger() - * - * 3- Software using DAC_Trigger_Software - * - * Each DAC channel integrates an output buffer that can be used to - * reduce the output impedance, and to drive external loads directly - * without having to add an external operational amplifier. - * To enable, the output buffer use - * DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; - * - * Refer to the device datasheet for more details about output impedance - * value with and without output buffer. - * - * Both DAC channels can be used to generate - * 1- Noise wave using DAC_WaveGeneration_Noise - * 2- Triangle wave using DAC_WaveGeneration_Triangle - * - * Wave generation can be disabled using DAC_WaveGeneration_None - * - * The DAC data format can be: - * 1- 8-bit right alignment using DAC_Align_8b_R - * 2- 12-bit left alignment using DAC_Align_12b_L - * 3- 12-bit right alignment using DAC_Align_12b_R - * - * The analog output voltage on each DAC channel pin is determined - * by the following equation: DAC_OUTx = VREF+ * DOR / 4095 - * with DOR is the Data Output Register - * VEF+ is the input voltage reference (refer to the device datasheet) - * e.g. To set DAC_OUT1 to 0.7V, use - * DAC_SetChannel1Data(DAC_Align_12b_R, 868); - * Assuming that VREF+ = 3.3, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V - * - * A DMA1 request can be generated when an external trigger (but not - * a software trigger) occurs if DMA1 requests are enabled using - * DAC_DMACmd() - * DMA1 requests are mapped as following: - * 1- DAC channel1 is mapped on DMA1 channel3 which must be already - * configured - * 2- DAC channel2 is mapped on DMA1 channel4 which must be already - * configured - * - * =================================================================== - * How to use this driver - * =================================================================== - * - DAC APB clock must be enabled to get write access to DAC - * registers using - * RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE) - * - Configure DAC_OUTx (DAC_OUT1: PA4, DAC_OUT2: PA5) in analog mode. - * - Configure the DAC channel using DAC_Init() - * - Enable the DAC channel using DAC_Cmd() - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_dac.h" -#include "stm32l1xx_rcc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup DAC - * @brief DAC driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* CR register Mask */ -#define CR_CLEAR_MASK ((uint32_t)0x00000FFE) - -/* DAC Dual Channels SWTRIG masks */ -#define DUAL_SWTRIG_SET ((uint32_t)0x00000003) -#define DUAL_SWTRIG_RESET ((uint32_t)0xFFFFFFFC) - -/* DHR registers offsets */ -#define DHR12R1_OFFSET ((uint32_t)0x00000008) -#define DHR12R2_OFFSET ((uint32_t)0x00000014) -#define DHR12RD_OFFSET ((uint32_t)0x00000020) - -/* DOR register offset */ -#define DOR_OFFSET ((uint32_t)0x0000002C) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup DAC_Private_Functions - * @{ - */ - -/** @defgroup DAC_Group1 DAC channels configuration - * @brief DAC channels configuration: trigger, output buffer, data format - * -@verbatim - =============================================================================== - DAC channels configuration: trigger, output buffer, data format - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the DAC peripheral registers to their default reset values. - * @param None - * @retval None - */ -void DAC_DeInit(void) -{ - /* Enable DAC reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, ENABLE); - /* Release DAC from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, DISABLE); -} - -/** - * @brief Initializes the DAC peripheral according to the specified - * parameters in the DAC_InitStruct. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure that - * contains the configuration information for the specified DAC channel. - * DAC_Trigger selects the trigger source: EXTI Line 9, TIM2, TIM4.... - * DAC_WaveGeneration selects the waveform to be generated: noise, triangle - * DAC_LFSRUnmask_TriangleAmplitude - * defines the LFSR when noise waveform is selected by DAC_WaveGeneration - * or defines the amplitude of the triangle waveform when it is - * selected by DAC_WaveGeneration - * DAC_OutputBuffer enables/disables the output buffer on DAC_OUTx - * @retval None - */ -void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct) -{ - uint32_t tmpreg1 = 0, tmpreg2 = 0; - - /* Check the DAC parameters */ - assert_param(IS_DAC_TRIGGER(DAC_InitStruct->DAC_Trigger)); - assert_param(IS_DAC_GENERATE_WAVE(DAC_InitStruct->DAC_WaveGeneration)); - assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude)); - assert_param(IS_DAC_OUTPUT_BUFFER_STATE(DAC_InitStruct->DAC_OutputBuffer)); - -/*---------------------------- DAC CR Configuration --------------------------*/ - /* Get the DAC CR value */ - tmpreg1 = DAC->CR; - /* Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits */ - tmpreg1 &= ~(CR_CLEAR_MASK << DAC_Channel); - /* Configure for the selected DAC channel: buffer output, trigger, wave generation, - mask/amplitude for wave generation */ - /* Set TSELx and TENx bits according to DAC_Trigger value */ - /* Set WAVEx bits according to DAC_WaveGeneration value */ - /* Set MAMPx bits according to DAC_LFSRUnmask_TriangleAmplitude value */ - /* Set BOFFx bit according to DAC_OutputBuffer value */ - tmpreg2 = (DAC_InitStruct->DAC_Trigger | DAC_InitStruct->DAC_WaveGeneration | - DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude | DAC_InitStruct->DAC_OutputBuffer); - /* Calculate CR register value depending on DAC_Channel */ - tmpreg1 |= tmpreg2 << DAC_Channel; - /* Write to DAC CR */ - DAC->CR = tmpreg1; -} - -/** - * @brief Fills each DAC_InitStruct member with its default value. - * @param DAC_InitStruct : pointer to a DAC_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct) -{ -/*--------------- Reset DAC init structure parameters values -----------------*/ - /* Initialize the DAC_Trigger member */ - DAC_InitStruct->DAC_Trigger = DAC_Trigger_None; - /* Initialize the DAC_WaveGeneration member */ - DAC_InitStruct->DAC_WaveGeneration = DAC_WaveGeneration_None; - /* Initialize the DAC_LFSRUnmask_TriangleAmplitude member */ - DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; - /* Initialize the DAC_OutputBuffer member */ - DAC_InitStruct->DAC_OutputBuffer = DAC_OutputBuffer_Enable; -} - -/** - * @brief Enables or disables the specified DAC channel. - * @param DAC_Channel: The selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param NewState: new state of the DAC channel. - * This parameter can be: ENABLE or DISABLE. - * @note When the DAC channel is enabled the trigger source can no more - * be modified. - * @retval None - */ -void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected DAC channel */ - DAC->CR |= (DAC_CR_EN1 << DAC_Channel); - } - else - { - /* Disable the selected DAC channel */ - DAC->CR &= (~(DAC_CR_EN1 << DAC_Channel)); - } -} - -/** - * @brief Enables or disables the selected DAC channel software trigger. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param NewState: new state of the selected DAC channel software trigger. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable software trigger for the selected DAC channel */ - DAC->SWTRIGR |= (uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4); - } - else - { - /* Disable software trigger for the selected DAC channel */ - DAC->SWTRIGR &= ~((uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4)); - } -} - -/** - * @brief Enables or disables simultaneously the two DAC channels software - * triggers. - * @param NewState: new state of the DAC channels software triggers. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DAC_DualSoftwareTriggerCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable software trigger for both DAC channels */ - DAC->SWTRIGR |= DUAL_SWTRIG_SET; - } - else - { - /* Disable software trigger for both DAC channels */ - DAC->SWTRIGR &= DUAL_SWTRIG_RESET; - } -} - -/** - * @brief Enables or disables the selected DAC channel wave generation. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_Wave: Specifies the wave type to enable or disable. - * This parameter can be one of the following values: - * @arg DAC_Wave_Noise: noise wave generation - * @arg DAC_Wave_Triangle: triangle wave generation - * @param NewState: new state of the selected DAC channel wave generation. - * This parameter can be: ENABLE or DISABLE. - * @note - * @retval None - */ -void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_WAVE(DAC_Wave)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected wave generation for the selected DAC channel */ - DAC->CR |= DAC_Wave << DAC_Channel; - } - else - { - /* Disable the selected wave generation for the selected DAC channel */ - DAC->CR &= ~(DAC_Wave << DAC_Channel); - } -} - -/** - * @brief Set the specified data holding register value for DAC channel1. - * @param DAC_Align: Specifies the data alignment for DAC channel1. - * This parameter can be one of the following values: - * @arg DAC_Align_8b_R: 8bit right data alignment selected - * @arg DAC_Align_12b_L: 12bit left data alignment selected - * @arg DAC_Align_12b_R: 12bit right data alignment selected - * @param Data : Data to be loaded in the selected data holding register. - * @retval None - */ -void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_DAC_ALIGN(DAC_Align)); - assert_param(IS_DAC_DATA(Data)); - - tmp = (uint32_t)DAC_BASE; - tmp += DHR12R1_OFFSET + DAC_Align; - - /* Set the DAC channel1 selected data holding register */ - *(__IO uint32_t *) tmp = Data; -} - -/** - * @brief Set the specified data holding register value for DAC channel2. - * @param DAC_Align: Specifies the data alignment for DAC channel2. - * This parameter can be one of the following values: - * @arg DAC_Align_8b_R: 8bit right data alignment selected - * @arg DAC_Align_12b_L: 12bit left data alignment selected - * @arg DAC_Align_12b_R: 12bit right data alignment selected - * @param Data : Data to be loaded in the selected data holding register. - * @retval None - */ -void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_DAC_ALIGN(DAC_Align)); - assert_param(IS_DAC_DATA(Data)); - - tmp = (uint32_t)DAC_BASE; - tmp += DHR12R2_OFFSET + DAC_Align; - - /* Set the DAC channel2 selected data holding register */ - *(__IO uint32_t *)tmp = Data; -} - -/** - * @brief Set the specified data holding register value for dual channel DAC. - * @param DAC_Align: Specifies the data alignment for dual channel DAC. - * This parameter can be one of the following values: - * @arg DAC_Align_8b_R: 8bit right data alignment selected - * @arg DAC_Align_12b_L: 12bit left data alignment selected - * @arg DAC_Align_12b_R: 12bit right data alignment selected - * @param Data2: Data for DAC Channel2 to be loaded in the selected data - * holding register. - * @param Data1: Data for DAC Channel1 to be loaded in the selected data - * holding register. - * @note In dual mode, a unique register access is required to write in both - * DAC channels at the same time. - * @retval None - */ -void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1) -{ - uint32_t data = 0, tmp = 0; - - /* Check the parameters */ - assert_param(IS_DAC_ALIGN(DAC_Align)); - assert_param(IS_DAC_DATA(Data1)); - assert_param(IS_DAC_DATA(Data2)); - - /* Calculate and set dual DAC data holding register value */ - if (DAC_Align == DAC_Align_8b_R) - { - data = ((uint32_t)Data2 << 8) | Data1; - } - else - { - data = ((uint32_t)Data2 << 16) | Data1; - } - - tmp = (uint32_t)DAC_BASE; - tmp += DHR12RD_OFFSET + DAC_Align; - - /* Set the dual DAC selected data holding register */ - *(__IO uint32_t *)tmp = data; -} - -/** - * @brief Returns the last data output value of the selected DAC channel. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @retval The selected DAC channel data output value. - */ -uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - - tmp = (uint32_t) DAC_BASE ; - tmp += DOR_OFFSET + ((uint32_t)DAC_Channel >> 2); - - /* Returns the DAC channel data output register value */ - return (uint16_t) (*(__IO uint32_t*) tmp); -} - -/** - * @} - */ - -/** @defgroup DAC_Group2 DMA management functions - * @brief DMA management functions - * -@verbatim - =============================================================================== - DMA management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified DAC channel DMA request. - * When enabled DMA1 is generated when an external trigger (EXTI Line9, - * TIM2, TIM4, TIM6, TIM7 or TIM9 but not a software trigger) occurs - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param NewState: new state of the selected DAC channel DMA request. - * This parameter can be: ENABLE or DISABLE. - * The DAC channel1 (channel2) is mapped on DMA1 channel3 (channel4) which - * must be already configured. - * @retval None - */ -void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected DAC channel DMA request */ - DAC->CR |= (DAC_CR_DMAEN1 << DAC_Channel); - } - else - { - /* Disable the selected DAC channel DMA request */ - DAC->CR &= (~(DAC_CR_DMAEN1 << DAC_Channel)); - } -} - -/** - * @} - */ - -/** @defgroup DAC_Group3 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified DAC interrupts. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_IT: specifies the DAC interrupt sources to be enabled or disabled. - * This parameter can be the following values: - * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask - * @note The DMA underrun occurs when a second external trigger arrives before - * the acknowledgement for the first external trigger is received (first request). - * @param NewState: new state of the specified DAC interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_DAC_IT(DAC_IT)); - - if (NewState != DISABLE) - { - /* Enable the selected DAC interrupts */ - DAC->CR |= (DAC_IT << DAC_Channel); - } - else - { - /* Disable the selected DAC interrupts */ - DAC->CR &= (~(uint32_t)(DAC_IT << DAC_Channel)); - } -} - -/** - * @brief Checks whether the specified DAC flag is set or not. - * @param DAC_Channel: thee selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_FLAG: specifies the flag to check. - * This parameter can be only of the following value: - * @arg DAC_FLAG_DMAUDR: DMA underrun flag - * @note The DMA underrun occurs when a second external trigger arrives before - * the acknowledgement for the first external trigger is received (first request). - * @retval The new state of DAC_FLAG (SET or RESET). - */ -FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_FLAG(DAC_FLAG)); - - /* Check the status of the specified DAC flag */ - if ((DAC->SR & (DAC_FLAG << DAC_Channel)) != (uint8_t)RESET) - { - /* DAC_FLAG is set */ - bitstatus = SET; - } - else - { - /* DAC_FLAG is reset */ - bitstatus = RESET; - } - /* Return the DAC_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the DAC channel's pending flags. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_FLAG: specifies the flag to clear. - * This parameter can be of the following value: - * @arg DAC_FLAG_DMAUDR: DMA underrun flag - * @retval None - */ -void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_FLAG(DAC_FLAG)); - - /* Clear the selected DAC flags */ - DAC->SR = (DAC_FLAG << DAC_Channel); -} - -/** - * @brief Checks whether the specified DAC interrupt has occurred or not. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_IT: specifies the DAC interrupt source to check. - * This parameter can be the following values: - * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask - * @note The DMA underrun occurs when a second external trigger arrives before - * the acknowledgement for the first external trigger is received (first request). - * @retval The new state of DAC_IT (SET or RESET). - */ -ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT) -{ - ITStatus bitstatus = RESET; - uint32_t enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_IT(DAC_IT)); - - /* Get the DAC_IT enable bit status */ - enablestatus = (DAC->CR & (DAC_IT << DAC_Channel)) ; - - /* Check the status of the specified DAC interrupt */ - if (((DAC->SR & (DAC_IT << DAC_Channel)) != (uint32_t)RESET) && enablestatus) - { - /* DAC_IT is set */ - bitstatus = SET; - } - else - { - /* DAC_IT is reset */ - bitstatus = RESET; - } - /* Return the DAC_IT status */ - return bitstatus; -} - -/** - * @brief Clears the DAC channels interrupt pending bits. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_IT: specifies the DAC interrupt pending bit to clear. - * This parameter can be the following values: - * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask - * @retval None - */ -void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_IT(DAC_IT)); - - /* Clear the selected DAC interrupt pending bits */ - DAC->SR = (DAC_IT << DAC_Channel); -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_dbgmcu.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_dbgmcu.c deleted file mode 100644 index f6b5712b0..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_dbgmcu.c +++ /dev/null @@ -1,170 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_dbgmcu.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides all the DBGMCU firmware functions. - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_dbgmcu.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup DBGMCU - * @brief DBGMCU driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup DBGMCU_Private_Functions - * @{ - */ - -/** - * @brief Returns the device revision identifier. - * @param None - * @retval Device revision identifier - */ -uint32_t DBGMCU_GetREVID(void) -{ - return(DBGMCU->IDCODE >> 16); -} - -/** - * @brief Returns the device identifier. - * @param None - * @retval Device identifier - */ -uint32_t DBGMCU_GetDEVID(void) -{ - return(DBGMCU->IDCODE & IDCODE_DEVID_MASK); -} - -/** - * @brief Configures low power mode behavior when the MCU is in Debug mode. - * @param DBGMCU_Periph: specifies the low power mode. - * This parameter can be any combination of the following values: - * @arg DBGMCU_SLEEP: Keep debugger connection during SLEEP mode - * @arg DBGMCU_STOP: Keep debugger connection during STOP mode - * @arg DBGMCU_STANDBY: Keep debugger connection during STANDBY mode - * @param NewState: new state of the specified low power mode in Debug mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DBGMCU_PERIPH(DBGMCU_Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - DBGMCU->CR |= DBGMCU_Periph; - } - else - { - DBGMCU->CR &= ~DBGMCU_Periph; - } -} - - -/** - * @brief Configures APB1 peripheral behavior when the MCU is in Debug mode. - * @param DBGMCU_Periph: specifies the APB1 peripheral. - * This parameter can be any combination of the following values: - * @arg DBGMCU_TIM2_STOP: TIM2 counter stopped when Core is halted - * @arg DBGMCU_TIM3_STOP: TIM3 counter stopped when Core is halted - * @arg DBGMCU_TIM4_STOP: TIM4 counter stopped when Core is halted - * @arg DBGMCU_TIM6_STOP: TIM6 counter stopped when Core is halted - * @arg DBGMCU_TIM7_STOP: TIM7 counter stopped when Core is halted - * @arg DBGMCU_RTC_STOP: RTC Wakeup counter stopped when Core is halted - * @arg DBGMCU_WWDG_STOP: Debug WWDG stopped when Core is halted - * @arg DBGMCU_IWDG_STOP: Debug IWDG stopped when Core is halted - * @arg DBGMCU_I2C1_SMBUS_TIMEOUT: I2C1 SMBUS timeout mode stopped when Core is - * halted - * @arg DBGMCU_I2C2_SMBUS_TIMEOUT: I2C2 SMBUS timeout mode stopped when Core is - * halted - * @param NewState: new state of the specified APB1 peripheral in Debug mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DBGMCU_APB1PERIPH(DBGMCU_Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - DBGMCU->APB1FZ |= DBGMCU_Periph; - } - else - { - DBGMCU->APB1FZ &= ~DBGMCU_Periph; - } -} - -/** - * @brief Configures APB2 peripheral behavior when the MCU is in Debug mode. - * @param DBGMCU_Periph: specifies the APB2 peripheral. - * This parameter can be any combination of the following values: - * @arg DBGMCU_TIM9_STOP: TIM9 counter stopped when Core is halted - * @arg DBGMCU_TIM10_STOP: TIM10 counter stopped when Core is halted - * @arg DBGMCU_TIM11_STOP: TIM11 counter stopped when Core is halted - * @param NewState: new state of the specified APB2 peripheral in Debug mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DBGMCU_APB2PERIPH(DBGMCU_Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - DBGMCU->APB2FZ |= DBGMCU_Periph; - } - else - { - DBGMCU->APB2FZ &= ~DBGMCU_Periph; - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_dma.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_dma.c deleted file mode 100644 index 749f6db49..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_dma.c +++ /dev/null @@ -1,752 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_dma.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the Direct Memory Access controller (DMA): - * - Initialization and Configuration - * - Data Counter - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable The DMA controller clock using RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE) - * function for DMA1 or using RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE) - * function for DMA2. - * - * 2. Enable and configure the peripheral to be connected to the DMA channel - * (except for internal SRAM / FLASH memories: no initialization is - * necessary). - * - * 3. For a given Channel, program the Source and Destination addresses, - * the transfer Direction, the Buffer Size, the Peripheral and Memory - * Incrementation mode and Data Size, the Circular or Normal mode, - * the channel transfer Priority and the Memory-to-Memory transfer - * mode (if needed) using the DMA_Init() function. - * - * 4. Enable the NVIC and the corresponding interrupt(s) using the function - * DMA_ITConfig() if you need to use DMA interrupts. - * - * 5. Enable the DMA channel using the DMA_Cmd() function. - * - * 6. Activate the needed channel Request using PPP_DMACmd() function for - * any PPP peripheral except internal SRAM and FLASH (ie. SPI, USART ...) - * The function allowing this operation is provided in each PPP peripheral - * driver (ie. SPI_DMACmd for SPI peripheral). - * - * 7. Optionally, you can configure the number of data to be transferred - * when the channel is disabled (ie. after each Transfer Complete event - * or when a Transfer Error occurs) using the function DMA_SetCurrDataCounter(). - * And you can get the number of remaining data to be transferred using - * the function DMA_GetCurrDataCounter() at run time (when the DMA channel is - * enabled and running). - * - * 8. To control DMA events you can use one of the following - * two methods: - * a- Check on DMA channel flags using the function DMA_GetFlagStatus(). - * b- Use DMA interrupts through the function DMA_ITConfig() at initialization - * phase and DMA_GetITStatus() function into interrupt routines in - * communication phase. - * After checking on a flag you should clear it using DMA_ClearFlag() - * function. And after checking on an interrupt event you should - * clear it using DMA_ClearITPendingBit() function. - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_dma.h" -#include "stm32l1xx_rcc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup DMA - * @brief DMA driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* DMA1 Channelx interrupt pending bit masks */ -#define DMA1_CHANNEL1_IT_MASK ((uint32_t)(DMA_ISR_GIF1 | DMA_ISR_TCIF1 | DMA_ISR_HTIF1 | DMA_ISR_TEIF1)) -#define DMA1_CHANNEL2_IT_MASK ((uint32_t)(DMA_ISR_GIF2 | DMA_ISR_TCIF2 | DMA_ISR_HTIF2 | DMA_ISR_TEIF2)) -#define DMA1_CHANNEL3_IT_MASK ((uint32_t)(DMA_ISR_GIF3 | DMA_ISR_TCIF3 | DMA_ISR_HTIF3 | DMA_ISR_TEIF3)) -#define DMA1_CHANNEL4_IT_MASK ((uint32_t)(DMA_ISR_GIF4 | DMA_ISR_TCIF4 | DMA_ISR_HTIF4 | DMA_ISR_TEIF4)) -#define DMA1_CHANNEL5_IT_MASK ((uint32_t)(DMA_ISR_GIF5 | DMA_ISR_TCIF5 | DMA_ISR_HTIF5 | DMA_ISR_TEIF5)) -#define DMA1_CHANNEL6_IT_MASK ((uint32_t)(DMA_ISR_GIF6 | DMA_ISR_TCIF6 | DMA_ISR_HTIF6 | DMA_ISR_TEIF6)) -#define DMA1_CHANNEL7_IT_MASK ((uint32_t)(DMA_ISR_GIF7 | DMA_ISR_TCIF7 | DMA_ISR_HTIF7 | DMA_ISR_TEIF7)) - -/* DMA FLAG mask */ -#define FLAG_MASK ((uint32_t)0x10000000) - -/* DMA registers Masks */ -#define CCR_CLEAR_MASK ((uint32_t)0xFFFF800F) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - - -/** @defgroup DMA_Private_Functions - * @{ - */ - -/** @defgroup DMA_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - - This subsection provides functions allowing to initialize the DMA channel source - and destination addresses, incrementation and data sizes, transfer direction, - buffer size, circular/normal mode selection, memory-to-memory mode selection - and channel priority value. - - The DMA_Init() function follows the DMA configuration procedures as described in - reference manual (RM0038). - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the DMAy Channelx registers to their default reset - * values. - * @param DMAy_Channelx: where y can be 1 to select the DMA and - * x can be 1 to 7 for DMA1 to select the DMA Channel. - * @retval None - */ -void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); - - /* Disable the selected DMAy Channelx */ - DMAy_Channelx->CCR &= (uint16_t)(~DMA_CCR1_EN); - - /* Reset DMAy Channelx control register */ - DMAy_Channelx->CCR = 0; - - /* Reset DMAy Channelx remaining bytes register */ - DMAy_Channelx->CNDTR = 0; - - /* Reset DMAy Channelx peripheral address register */ - DMAy_Channelx->CPAR = 0; - - /* Reset DMAy Channelx memory address register */ - DMAy_Channelx->CMAR = 0; - - if (DMAy_Channelx == DMA1_Channel1) - { - /* Reset interrupt pending bits for DMA1 Channel1 */ - DMA1->IFCR |= DMA1_CHANNEL1_IT_MASK; - } - else if (DMAy_Channelx == DMA1_Channel2) - { - /* Reset interrupt pending bits for DMA1 Channel2 */ - DMA1->IFCR |= DMA1_CHANNEL2_IT_MASK; - } - else if (DMAy_Channelx == DMA1_Channel3) - { - /* Reset interrupt pending bits for DMA1 Channel3 */ - DMA1->IFCR |= DMA1_CHANNEL3_IT_MASK; - } - else if (DMAy_Channelx == DMA1_Channel4) - { - /* Reset interrupt pending bits for DMA1 Channel4 */ - DMA1->IFCR |= DMA1_CHANNEL4_IT_MASK; - } - else if (DMAy_Channelx == DMA1_Channel5) - { - /* Reset interrupt pending bits for DMA1 Channel5 */ - DMA1->IFCR |= DMA1_CHANNEL5_IT_MASK; - } - else if (DMAy_Channelx == DMA1_Channel6) - { - /* Reset interrupt pending bits for DMA1 Channel6 */ - DMA1->IFCR |= DMA1_CHANNEL6_IT_MASK; - } - else - { - if (DMAy_Channelx == DMA1_Channel7) - { - /* Reset interrupt pending bits for DMA1 Channel7 */ - DMA1->IFCR |= DMA1_CHANNEL7_IT_MASK; - } - } -} - -/** - * @brief Initializes the DMAy Channelx according to the specified - * parameters in the DMA_InitStruct. - * @param DMAy_Channelx: where y can be 1 to select the DMA and - * x can be 1 to 7 for DMA1 to select the DMA Channel. - * @param DMA_InitStruct: pointer to a DMA_InitTypeDef structure that - * contains the configuration information for the specified DMA Channel. - * @retval None - */ -void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); - assert_param(IS_DMA_DIR(DMA_InitStruct->DMA_DIR)); - assert_param(IS_DMA_BUFFER_SIZE(DMA_InitStruct->DMA_BufferSize)); - assert_param(IS_DMA_PERIPHERAL_INC_STATE(DMA_InitStruct->DMA_PeripheralInc)); - assert_param(IS_DMA_MEMORY_INC_STATE(DMA_InitStruct->DMA_MemoryInc)); - assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(DMA_InitStruct->DMA_PeripheralDataSize)); - assert_param(IS_DMA_MEMORY_DATA_SIZE(DMA_InitStruct->DMA_MemoryDataSize)); - assert_param(IS_DMA_MODE(DMA_InitStruct->DMA_Mode)); - assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority)); - assert_param(IS_DMA_M2M_STATE(DMA_InitStruct->DMA_M2M)); - -/*--------------------------- DMAy Channelx CCR Configuration -----------------*/ - /* Get the DMAy_Channelx CCR value */ - tmpreg = DMAy_Channelx->CCR; - /* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */ - tmpreg &= CCR_CLEAR_MASK; - /* Configure DMAy Channelx: data transfer, data size, priority level and mode */ - /* Set DIR bit according to DMA_DIR value */ - /* Set CIRC bit according to DMA_Mode value */ - /* Set PINC bit according to DMA_PeripheralInc value */ - /* Set MINC bit according to DMA_MemoryInc value */ - /* Set PSIZE bits according to DMA_PeripheralDataSize value */ - /* Set MSIZE bits according to DMA_MemoryDataSize value */ - /* Set PL bits according to DMA_Priority value */ - /* Set the MEM2MEM bit according to DMA_M2M value */ - tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode | - DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc | - DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize | - DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M; - - /* Write to DMAy Channelx CCR */ - DMAy_Channelx->CCR = tmpreg; - -/*--------------------------- DMAy Channelx CNDTR Configuration ---------------*/ - /* Write to DMAy Channelx CNDTR */ - DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize; - -/*--------------------------- DMAy Channelx CPAR Configuration ----------------*/ - /* Write to DMAy Channelx CPAR */ - DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr; - -/*--------------------------- DMAy Channelx CMAR Configuration ----------------*/ - /* Write to DMAy Channelx CMAR */ - DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr; -} - -/** - * @brief Fills each DMA_InitStruct member with its default value. - * @param DMA_InitStruct: pointer to a DMA_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct) -{ -/*-------------- Reset DMA init structure parameters values ------------------*/ - /* Initialize the DMA_PeripheralBaseAddr member */ - DMA_InitStruct->DMA_PeripheralBaseAddr = 0; - /* Initialize the DMA_MemoryBaseAddr member */ - DMA_InitStruct->DMA_MemoryBaseAddr = 0; - /* Initialize the DMA_DIR member */ - DMA_InitStruct->DMA_DIR = DMA_DIR_PeripheralSRC; - /* Initialize the DMA_BufferSize member */ - DMA_InitStruct->DMA_BufferSize = 0; - /* Initialize the DMA_PeripheralInc member */ - DMA_InitStruct->DMA_PeripheralInc = DMA_PeripheralInc_Disable; - /* Initialize the DMA_MemoryInc member */ - DMA_InitStruct->DMA_MemoryInc = DMA_MemoryInc_Disable; - /* Initialize the DMA_PeripheralDataSize member */ - DMA_InitStruct->DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; - /* Initialize the DMA_MemoryDataSize member */ - DMA_InitStruct->DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; - /* Initialize the DMA_Mode member */ - DMA_InitStruct->DMA_Mode = DMA_Mode_Normal; - /* Initialize the DMA_Priority member */ - DMA_InitStruct->DMA_Priority = DMA_Priority_Low; - /* Initialize the DMA_M2M member */ - DMA_InitStruct->DMA_M2M = DMA_M2M_Disable; -} - -/** - * @brief Enables or disables the specified DMAy Channelx. - * @param DMAy_Channelx: where y can be 1 to select the DMA and - * x can be 1 to 7 for DMA1 to select the DMA Channel. - * @param NewState: new state of the DMAy Channelx. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected DMAy Channelx */ - DMAy_Channelx->CCR |= DMA_CCR1_EN; - } - else - { - /* Disable the selected DMAy Channelx */ - DMAy_Channelx->CCR &= (uint16_t)(~DMA_CCR1_EN); - } -} - -/** - * @} - */ - -/** @defgroup DMA_Group2 Data Counter functions - * @brief Data Counter functions - * -@verbatim - =============================================================================== - Data Counter functions - =============================================================================== - - This subsection provides function allowing to configure and read the buffer size - (number of data to be transferred). - - The DMA data counter can be written only when the DMA channel is disabled - (ie. after transfer complete event). - - The following function can be used to write the Channel data counter value: - - void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber); - -@note It is advised to use this function rather than DMA_Init() in situations where - only the Data buffer needs to be reloaded. - - The DMA data counter can be read to indicate the number of remaining transfers for - the relative DMA channel. This counter is decremented at the end of each data - transfer and when the transfer is complete: - - If Normal mode is selected: the counter is set to 0. - - If Circular mode is selected: the counter is reloaded with the initial value - (configured before enabling the DMA channel) - - The following function can be used to read the Channel data counter value: - - uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx); - -@endverbatim - * @{ - */ - -/** - * @brief Sets the number of data units in the current DMAy Channelx transfer. - * @param DMAy_Channelx: where y can be 1 to select the DMA and - * x can be 1 to 7 for DMA1 to select the DMA Channel. - * @param DataNumber: The number of data units in the current DMAy Channelx - * transfer. - * @note This function can only be used when the DMAy_Channelx is disabled. - * @retval None. - */ -void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); - -/*--------------------------- DMAy Channelx CNDTR Configuration ---------------*/ - /* Write to DMAy Channelx CNDTR */ - DMAy_Channelx->CNDTR = DataNumber; -} - -/** - * @brief Returns the number of remaining data units in the current - * DMAy Channelx transfer. - * @param DMAy_Channelx: where y can be 1 to select the DMA and - * x can be 1 to 7 for DMA1 to select the DMA Channel. - * @retval The number of remaining data units in the current DMAy Channelx - * transfer. - */ -uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); - /* Return the number of remaining data units for DMAy Channelx */ - return ((uint16_t)(DMAy_Channelx->CNDTR)); -} - -/** - * @} - */ - -/** @defgroup DMA_Group3 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - - This subsection provides functions allowing to configure the DMA Interrupts - sources and check or clear the flags or pending bits status. - The user should identify which mode will be used in his application to manage the - DMA controller events: Polling mode or Interrupt mode. - - Polling Mode - ============= - Each DMA channel can be managed through 4 event Flags: - (y : DMA Controller number - x : DMA channel number ) - 1. DMAy_FLAG_TCx : to indicate that a Transfer Complete event occurred - 2. DMAy_FLAG_HTx : to indicate that a Half-Transfer Complete event occured - 3. DMAy_FLAG_TEx : to indicate that a Transfer Error occured. - 4. DMAy_FLAG_GLx : to indicate that at least one of the events described - above occured. - -@note Clearing DMAy_FLAG_GLx results in clearing all other pending flags of the - same channel (DMAy_FLAG_TCx, DMAy_FLAG_HTx and DMAy_FLAG_TEx). - - In this Mode it is advised to use the following functions: - - FlagStatus DMA_GetFlagStatus(uint32_t DMA_FLAG); - - void DMA_ClearFlag(uint32_t DMA_FLAG); - - Interrupt Mode - =============== - Each DMA channel can be managed through 4 Interrupts: - - Interrupt Source - ---------------- - 1. DMA_IT_TC: specifies the interrupt source for the Transfer Complete event. - 2. DMA_IT_HT : specifies the interrupt source for the Half-transfer Complete event. - 3. DMA_IT_TE : specifies the interrupt source for the transfer errors event. - 4. DMA_IT_GL : to indicate that at least one of the interrupts described - above occurred. - -@note Clearing DMA_IT_GL interrupt results in clearing all other interrupts of the - same channel (DMA_IT_TCx, DMA_IT_HT and DMA_IT_TE). - - In this Mode it is advised to use the following functions: - - void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState); - - ITStatus DMA_GetITStatus(uint32_t DMA_IT); - - void DMA_ClearITPendingBit(uint32_t DMA_IT); - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified DMAy Channelx interrupts. - * @param DMAy_Channelx: where y can be 1 to select the DMA and - * x can be 1 to 7 for DMA1 to select the DMA Channel. - * @param DMA_IT: specifies the DMA interrupts sources to be enabled - * or disabled. - * This parameter can be any combination of the following values: - * @arg DMA_IT_TC: Transfer complete interrupt mask - * @arg DMA_IT_HT: Half transfer interrupt mask - * @arg DMA_IT_TE: Transfer error interrupt mask - * @param NewState: new state of the specified DMA interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); - assert_param(IS_DMA_CONFIG_IT(DMA_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected DMA interrupts */ - DMAy_Channelx->CCR |= DMA_IT; - } - else - { - /* Disable the selected DMA interrupts */ - DMAy_Channelx->CCR &= ~DMA_IT; - } -} - -/** - * @brief Checks whether the specified DMAy Channelx flag is set or not. - * @param DMA_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg DMA1_FLAG_GL1: DMA1 Channel1 global flag. - * @arg DMA1_FLAG_TC1: DMA1 Channel1 transfer complete flag. - * @arg DMA1_FLAG_HT1: DMA1 Channel1 half transfer flag. - * @arg DMA1_FLAG_TE1: DMA1 Channel1 transfer error flag. - * @arg DMA1_FLAG_GL2: DMA1 Channel2 global flag. - * @arg DMA1_FLAG_TC2: DMA1 Channel2 transfer complete flag. - * @arg DMA1_FLAG_HT2: DMA1 Channel2 half transfer flag. - * @arg DMA1_FLAG_TE2: DMA1 Channel2 transfer error flag. - * @arg DMA1_FLAG_GL3: DMA1 Channel3 global flag. - * @arg DMA1_FLAG_TC3: DMA1 Channel3 transfer complete flag. - * @arg DMA1_FLAG_HT3: DMA1 Channel3 half transfer flag. - * @arg DMA1_FLAG_TE3: DMA1 Channel3 transfer error flag. - * @arg DMA1_FLAG_GL4: DMA1 Channel4 global flag. - * @arg DMA1_FLAG_TC4: DMA1 Channel4 transfer complete flag. - * @arg DMA1_FLAG_HT4: DMA1 Channel4 half transfer flag. - * @arg DMA1_FLAG_TE4: DMA1 Channel4 transfer error flag. - * @arg DMA1_FLAG_GL5: DMA1 Channel5 global flag. - * @arg DMA1_FLAG_TC5: DMA1 Channel5 transfer complete flag. - * @arg DMA1_FLAG_HT5: DMA1 Channel5 half transfer flag. - * @arg DMA1_FLAG_TE5: DMA1 Channel5 transfer error flag. - * @arg DMA1_FLAG_GL6: DMA1 Channel6 global flag. - * @arg DMA1_FLAG_TC6: DMA1 Channel6 transfer complete flag. - * @arg DMA1_FLAG_HT6: DMA1 Channel6 half transfer flag. - * @arg DMA1_FLAG_TE6: DMA1 Channel6 transfer error flag. - * @arg DMA1_FLAG_GL7: DMA1 Channel7 global flag. - * @arg DMA1_FLAG_TC7: DMA1 Channel7 transfer complete flag. - * @arg DMA1_FLAG_HT7: DMA1 Channel7 half transfer flag. - * @arg DMA1_FLAG_TE7: DMA1 Channel7 transfer error flag. - * - * @note - * The Global flag (DMAy_FLAG_GLx) is set whenever any of the other flags - * relative to the same channel is set (Transfer Complete, Half-transfer - * Complete or Transfer Error flags: DMAy_FLAG_TCx, DMAy_FLAG_HTx or - * DMAy_FLAG_TEx). - * - * @retval The new state of DMA_FLAG (SET or RESET). - */ -FlagStatus DMA_GetFlagStatus(uint32_t DMA_FLAG) -{ - FlagStatus bitstatus = RESET; - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_DMA_GET_FLAG(DMA_FLAG)); - - /* Calculate the used DMA */ - if ((DMA_FLAG & FLAG_MASK) == (uint32_t)RESET) - { - /* Get DMA1 ISR register value */ - tmpreg = DMA1->ISR ; - } - - /* Check the status of the specified DMA flag */ - if ((tmpreg & DMA_FLAG) != (uint32_t)RESET) - { - /* DMA_FLAG is set */ - bitstatus = SET; - } - else - { - /* DMA_FLAG is reset */ - bitstatus = RESET; - } - - /* Return the DMA_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the DMAy Channelx's pending flags. - * @param DMA_FLAG: specifies the flag to clear. - * This parameter can be any combination (for the same DMA) of the following values: - * @arg DMA1_FLAG_GL1: DMA1 Channel1 global flag. - * @arg DMA1_FLAG_TC1: DMA1 Channel1 transfer complete flag. - * @arg DMA1_FLAG_HT1: DMA1 Channel1 half transfer flag. - * @arg DMA1_FLAG_TE1: DMA1 Channel1 transfer error flag. - * @arg DMA1_FLAG_GL2: DMA1 Channel2 global flag. - * @arg DMA1_FLAG_TC2: DMA1 Channel2 transfer complete flag. - * @arg DMA1_FLAG_HT2: DMA1 Channel2 half transfer flag. - * @arg DMA1_FLAG_TE2: DMA1 Channel2 transfer error flag. - * @arg DMA1_FLAG_GL3: DMA1 Channel3 global flag. - * @arg DMA1_FLAG_TC3: DMA1 Channel3 transfer complete flag. - * @arg DMA1_FLAG_HT3: DMA1 Channel3 half transfer flag. - * @arg DMA1_FLAG_TE3: DMA1 Channel3 transfer error flag. - * @arg DMA1_FLAG_GL4: DMA1 Channel4 global flag. - * @arg DMA1_FLAG_TC4: DMA1 Channel4 transfer complete flag. - * @arg DMA1_FLAG_HT4: DMA1 Channel4 half transfer flag. - * @arg DMA1_FLAG_TE4: DMA1 Channel4 transfer error flag. - * @arg DMA1_FLAG_GL5: DMA1 Channel5 global flag. - * @arg DMA1_FLAG_TC5: DMA1 Channel5 transfer complete flag. - * @arg DMA1_FLAG_HT5: DMA1 Channel5 half transfer flag. - * @arg DMA1_FLAG_TE5: DMA1 Channel5 transfer error flag. - * @arg DMA1_FLAG_GL6: DMA1 Channel6 global flag. - * @arg DMA1_FLAG_TC6: DMA1 Channel6 transfer complete flag. - * @arg DMA1_FLAG_HT6: DMA1 Channel6 half transfer flag. - * @arg DMA1_FLAG_TE6: DMA1 Channel6 transfer error flag. - * @arg DMA1_FLAG_GL7: DMA1 Channel7 global flag. - * @arg DMA1_FLAG_TC7: DMA1 Channel7 transfer complete flag. - * @arg DMA1_FLAG_HT7: DMA1 Channel7 half transfer flag. - * @arg DMA1_FLAG_TE7: DMA1 Channel7 transfer error flag. - * - * @note - * Clearing the Global flag (DMAy_FLAG_GLx) results in clearing all other flags - * relative to the same channel (Transfer Complete, Half-transfer Complete and - * Transfer Error flags: DMAy_FLAG_TCx, DMAy_FLAG_HTx and DMAy_FLAG_TEx). - * - * @retval None - */ -void DMA_ClearFlag(uint32_t DMA_FLAG) -{ - /* Check the parameters */ - assert_param(IS_DMA_CLEAR_FLAG(DMA_FLAG)); - - if ((DMA_FLAG & FLAG_MASK) == (uint32_t)RESET) - { - /* Clear the selected DMA flags */ - DMA1->IFCR = DMA_FLAG; - } -} - -/** - * @brief Checks whether the specified DMAy Channelx interrupt has occurred or not. - * @param DMA_IT: specifies the DMA interrupt source to check. - * This parameter can be one of the following values: - * @arg DMA1_IT_GL1: DMA1 Channel1 global interrupt. - * @arg DMA1_IT_TC1: DMA1 Channel1 transfer complete interrupt. - * @arg DMA1_IT_HT1: DMA1 Channel1 half transfer interrupt. - * @arg DMA1_IT_TE1: DMA1 Channel1 transfer error interrupt. - * @arg DMA1_IT_GL2: DMA1 Channel2 global interrupt. - * @arg DMA1_IT_TC2: DMA1 Channel2 transfer complete interrupt. - * @arg DMA1_IT_HT2: DMA1 Channel2 half transfer interrupt. - * @arg DMA1_IT_TE2: DMA1 Channel2 transfer error interrupt. - * @arg DMA1_IT_GL3: DMA1 Channel3 global interrupt. - * @arg DMA1_IT_TC3: DMA1 Channel3 transfer complete interrupt. - * @arg DMA1_IT_HT3: DMA1 Channel3 half transfer interrupt. - * @arg DMA1_IT_TE3: DMA1 Channel3 transfer error interrupt. - * @arg DMA1_IT_GL4: DMA1 Channel4 global interrupt. - * @arg DMA1_IT_TC4: DMA1 Channel4 transfer complete interrupt. - * @arg DMA1_IT_HT4: DMA1 Channel4 half transfer interrupt. - * @arg DMA1_IT_TE4: DMA1 Channel4 transfer error interrupt. - * @arg DMA1_IT_GL5: DMA1 Channel5 global interrupt. - * @arg DMA1_IT_TC5: DMA1 Channel5 transfer complete interrupt. - * @arg DMA1_IT_HT5: DMA1 Channel5 half transfer interrupt. - * @arg DMA1_IT_TE5: DMA1 Channel5 transfer error interrupt. - * @arg DMA1_IT_GL6: DMA1 Channel6 global interrupt. - * @arg DMA1_IT_TC6: DMA1 Channel6 transfer complete interrupt. - * @arg DMA1_IT_HT6: DMA1 Channel6 half transfer interrupt. - * @arg DMA1_IT_TE6: DMA1 Channel6 transfer error interrupt. - * @arg DMA1_IT_GL7: DMA1 Channel7 global interrupt. - * @arg DMA1_IT_TC7: DMA1 Channel7 transfer complete interrupt. - * @arg DMA1_IT_HT7: DMA1 Channel7 half transfer interrupt. - * @arg DMA1_IT_TE7: DMA1 Channel7 transfer error interrupt. - * - * @note - * The Global interrupt (DMAy_FLAG_GLx) is set whenever any of the other - * interrupts relative to the same channel is set (Transfer Complete, - * Half-transfer Complete or Transfer Error interrupts: DMAy_IT_TCx, - * DMAy_IT_HTx or DMAy_IT_TEx). - * - * @retval The new state of DMA_IT (SET or RESET). - */ -ITStatus DMA_GetITStatus(uint32_t DMA_IT) -{ - ITStatus bitstatus = RESET; - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_DMA_GET_IT(DMA_IT)); - - /* Calculate the used DMA */ - if ((DMA_IT & FLAG_MASK) == (uint32_t)RESET) - { - /* Get DMA1 ISR register value */ - tmpreg = DMA1->ISR ; - } - - /* Check the status of the specified DMA interrupt */ - if ((tmpreg & DMA_IT) != (uint32_t)RESET) - { - /* DMA_IT is set */ - bitstatus = SET; - } - else - { - /* DMA_IT is reset */ - bitstatus = RESET; - } - /* Return the DMA_IT status */ - return bitstatus; -} - -/** - * @brief Clears the DMAy Channelxs interrupt pending bits. - * @param DMA_IT: specifies the DMA interrupt pending bit to clear. - * This parameter can be any combination (for the same DMA) of the following values: - * @arg DMA1_IT_GL1: DMA1 Channel1 global interrupt. - * @arg DMA1_IT_TC1: DMA1 Channel1 transfer complete interrupt. - * @arg DMA1_IT_HT1: DMA1 Channel1 half transfer interrupt. - * @arg DMA1_IT_TE1: DMA1 Channel1 transfer error interrupt. - * @arg DMA1_IT_GL2: DMA1 Channel2 global interrupt. - * @arg DMA1_IT_TC2: DMA1 Channel2 transfer complete interrupt. - * @arg DMA1_IT_HT2: DMA1 Channel2 half transfer interrupt. - * @arg DMA1_IT_TE2: DMA1 Channel2 transfer error interrupt. - * @arg DMA1_IT_GL3: DMA1 Channel3 global interrupt. - * @arg DMA1_IT_TC3: DMA1 Channel3 transfer complete interrupt. - * @arg DMA1_IT_HT3: DMA1 Channel3 half transfer interrupt. - * @arg DMA1_IT_TE3: DMA1 Channel3 transfer error interrupt. - * @arg DMA1_IT_GL4: DMA1 Channel4 global interrupt. - * @arg DMA1_IT_TC4: DMA1 Channel4 transfer complete interrupt. - * @arg DMA1_IT_HT4: DMA1 Channel4 half transfer interrupt. - * @arg DMA1_IT_TE4: DMA1 Channel4 transfer error interrupt. - * @arg DMA1_IT_GL5: DMA1 Channel5 global interrupt. - * @arg DMA1_IT_TC5: DMA1 Channel5 transfer complete interrupt. - * @arg DMA1_IT_HT5: DMA1 Channel5 half transfer interrupt. - * @arg DMA1_IT_TE5: DMA1 Channel5 transfer error interrupt. - * @arg DMA1_IT_GL6: DMA1 Channel6 global interrupt. - * @arg DMA1_IT_TC6: DMA1 Channel6 transfer complete interrupt. - * @arg DMA1_IT_HT6: DMA1 Channel6 half transfer interrupt. - * @arg DMA1_IT_TE6: DMA1 Channel6 transfer error interrupt. - * @arg DMA1_IT_GL7: DMA1 Channel7 global interrupt. - * @arg DMA1_IT_TC7: DMA1 Channel7 transfer complete interrupt. - * @arg DMA1_IT_HT7: DMA1 Channel7 half transfer interrupt. - * @arg DMA1_IT_TE7: DMA1 Channel7 transfer error interrupt. - * - * @note - * Clearing the Global interrupt (DMAy_IT_GLx) results in clearing all other - * interrupts relative to the same channel (Transfer Complete, Half-transfer - * Complete and Transfer Error interrupts: DMAy_IT_TCx, DMAy_IT_HTx and - * DMAy_IT_TEx). - * - * @retval None - */ -void DMA_ClearITPendingBit(uint32_t DMA_IT) -{ - /* Check the parameters */ - assert_param(IS_DMA_CLEAR_IT(DMA_IT)); - - /* Calculate the used DMA */ - if ((DMA_IT & FLAG_MASK) == (uint32_t)RESET) - { - /* Clear the selected DMA interrupt pending bits */ - DMA1->IFCR = DMA_IT; - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_exti.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_exti.c deleted file mode 100644 index 008f62e8f..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_exti.c +++ /dev/null @@ -1,313 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_exti.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the EXTI peripheral: - * - Initialization and Configuration - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * EXTI features - * =================================================================== - * - * External interrupt/event lines are mapped as following: - * 1- All available GPIO pins are connected to the 16 external - * interrupt/event lines from EXTI0 to EXTI15. - * 2- EXTI line 16 is connected to the PVD output - * 3- EXTI line 17 is connected to the RTC Alarm event - * 4- EXTI line 18 is connected to the USB Device FS wakeup event - * 5- EXTI line 19 is connected to the RTC Tamper and TimeStamp events - * 6- EXTI line 20 is connected to the RTC Wakeup event - * 7- EXTI line 21 is connected to the Comparator 1 wakeup event - * 8- EXTI line 22 is connected to the Comparator 2 wakeup event - * - * =================================================================== - * How to use this driver - * =================================================================== - * - * In order to use an I/O pin as an external interrupt source, follow - * steps below: - * 1- Configure the I/O in input mode using GPIO_Init() - * 2- Select the input source pin for the EXTI line using - * SYSCFG_EXTILineConfig() - * 3- Select the mode(interrupt, event) and configure the trigger - * selection (Rising, falling or both) using EXTI_Init() - * 4- Configure NVIC IRQ channel mapped to the EXTI line using NVIC_Init() - * - *@note SYSCFG APB clock must be enabled to get write access to SYSCFG_EXTICRx - * registers using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_exti.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup EXTI - * @brief EXTI driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define EXTI_LINENONE ((uint32_t)0x00000) /* No interrupt selected */ - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup EXTI_Private_Functions - * @{ - */ - -/** @defgroup EXTI_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the EXTI peripheral registers to their default reset values. - * @param None - * @retval None - */ -void EXTI_DeInit(void) -{ - EXTI->IMR = 0x00000000; - EXTI->EMR = 0x00000000; - EXTI->RTSR = 0x00000000; - EXTI->FTSR = 0x00000000; - EXTI->PR = 0x007FFFFF; -} - -/** - * @brief Initializes the EXTI peripheral according to the specified - * parameters in the EXTI_InitStruct. - * EXTI_Line specifies the EXTI line (EXTI0....EXTI22) - * EXTI_Mode specifies which EXTI line is used as interrupt or an event - * EXTI_Trigger selects the trigger. When the trigger occurs, interrupt - * pending bit will be set - * EXTI_LineCmd controls (Enable/Disable) the EXTI line - * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure - * that contains the configuration information for the EXTI peripheral. - * @retval None - */ -void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct) -{ - uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode)); - assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger)); - assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line)); - assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd)); - - tmp = (uint32_t)EXTI_BASE; - - if (EXTI_InitStruct->EXTI_LineCmd != DISABLE) - { - /* Clear EXTI line configuration */ - EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line; - EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line; - - tmp += EXTI_InitStruct->EXTI_Mode; - - *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; - - /* Clear Rising Falling edge configuration */ - EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line; - EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line; - - /* Select the trigger for the selected external interrupts */ - if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling) - { - /* Rising Falling edge */ - EXTI->RTSR |= EXTI_InitStruct->EXTI_Line; - EXTI->FTSR |= EXTI_InitStruct->EXTI_Line; - } - else - { - tmp = (uint32_t)EXTI_BASE; - tmp += EXTI_InitStruct->EXTI_Trigger; - - *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; - } - } - else - { - tmp += EXTI_InitStruct->EXTI_Mode; - - /* Disable the selected external lines */ - *(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line; - } -} - -/** - * @brief Fills each EXTI_InitStruct member with its reset value. - * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct) -{ - EXTI_InitStruct->EXTI_Line = EXTI_LINENONE; - EXTI_InitStruct->EXTI_Mode = EXTI_Mode_Interrupt; - EXTI_InitStruct->EXTI_Trigger = EXTI_Trigger_Falling; - EXTI_InitStruct->EXTI_LineCmd = DISABLE; -} - -/** - * @brief Generates a Software interrupt on selected EXTI line. - * @param EXTI_Line: specifies the EXTI line on which the software interrupt - * will be generated. - * This parameter can be any combination of EXTI_Linex where x can be (0..22). - * @retval None - */ -void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line) -{ - /* Check the parameters */ - assert_param(IS_EXTI_LINE(EXTI_Line)); - - EXTI->SWIER |= EXTI_Line; -} - -/** - * @} - */ - -/** @defgroup EXTI_Group2 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Checks whether the specified EXTI line flag is set or not. - * @param EXTI_Line: specifies the EXTI line flag to check. - * This parameter can be: - * @arg EXTI_Linex: External interrupt line x where x(0..22) - * @retval The new state of EXTI_Line (SET or RESET). - */ -FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_GET_EXTI_LINE(EXTI_Line)); - - if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the EXTIs line pending flags. - * @param EXTI_Line: specifies the EXTI lines flags to clear. - * This parameter can be any combination of EXTI_Linex where x can be (0..22). - * @retval None - */ -void EXTI_ClearFlag(uint32_t EXTI_Line) -{ - /* Check the parameters */ - assert_param(IS_EXTI_LINE(EXTI_Line)); - - EXTI->PR = EXTI_Line; -} - -/** - * @brief Checks whether the specified EXTI line is asserted or not. - * @param EXTI_Line: specifies the EXTI line to check. - * This parameter can be: - * @arg EXTI_Linex: External interrupt line x where x(0..22) - * @retval The new state of EXTI_Line (SET or RESET). - */ -ITStatus EXTI_GetITStatus(uint32_t EXTI_Line) -{ - ITStatus bitstatus = RESET; - uint32_t enablestatus = 0; - /* Check the parameters */ - assert_param(IS_GET_EXTI_LINE(EXTI_Line)); - - enablestatus = EXTI->IMR & EXTI_Line; - if (((EXTI->PR & EXTI_Line) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the EXTIs line pending bits. - * @param EXTI_Line: specifies the EXTI lines to clear. - * This parameter can be any combination of EXTI_Linex where x can be (0..22). - * @retval None - */ -void EXTI_ClearITPendingBit(uint32_t EXTI_Line) -{ - /* Check the parameters */ - assert_param(IS_EXTI_LINE(EXTI_Line)); - - EXTI->PR = EXTI_Line; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_flash.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_flash.c deleted file mode 100644 index 2fa60a7bc..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_flash.c +++ /dev/null @@ -1,1335 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_flash.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides all the Flash firmware functions. These functions - * can be executed from Internal FLASH or Internal SRAM memories. - * The functions that should be called from SRAM are defined inside - * the "stm32l1xx_flash_ramfunc.c" file. - * This file provides firmware functions to manage the following - * functionalities of the FLASH peripheral: - * - FLASH Interface configuration - * - FLASH Memory Programming - * - DATA EEPROM Programming - * - Option Bytes Programming - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * - * This driver provides functions to configure and program the Flash - * memory of all STM32L1xx devices - * These functions are split in 5 groups - * - * 1. FLASH Interface configuration functions: this group includes - * the management of following features: - * - Set the latency - * - Enable/Disable the prefetch buffer - * - Enable/Disable the 64 bit Read Access - * - Enable/Disable the RUN PowerDown mode - * - Enable/Disable the SLEEP PowerDown mode - * - * 2. FLASH Memory Programming functions: this group includes all - * needed functions to erase and program the main memory: - * - Lock and Unlock the Flash interface. - * - Erase function: Erase Page. - * - Program functions: Fast Word and Half Page(should be - * executed from internal SRAM). - * - * 3. DATA EEPROM Programming functions: this group includes all - * needed functions to erase and program the DATA EEPROM memory: - * - Lock and Unlock the DATA EEPROM interface. - * - Erase function: Erase Word, erase Double Word (should be - * executed from internal SRAM). - * - Program functions: Fast Program Byte, Fast Program Half-Word, - * FastProgramWord, Program Byte, Program Half-Word, - * Program Word and Program Double-Word (should be executed - * from internal SRAM). - * - * 4. FLASH Option Bytes Programming functions: this group includes - * all needed functions to: - * - Lock and Unlock the Flash Option bytes. - * - Set/Reset the write protection - * - Set the Read protection Level - * - Set the BOR level - * - Program the user option Bytes - * - Launch the Option Bytes loader - * - Get the Write protection - * - Get the read protection status - * - Get the BOR level - * - Get the user option bytes - * - * 5. FLASH Interrupts and flag management functions: this group - * includes all needed functions to: - * - Enable/Disable the flash interrupt sources - * - Get flags status - * - Clear flags - * - Get Flash operation status - * - Wait for last flash operation - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_flash.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup FLASH - * @brief FLASH driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* FLASH Mask */ -#define RDPRT_MASK ((uint32_t)0x00000002) -#define WRP01_MASK ((uint32_t)0x0000FFFF) -#define WRP23_MASK ((uint32_t)0xFFFF0000) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup FLASH_Private_Functions - * @{ - */ - -/** @defgroup FLASH_Group1 FLASH Interface configuration functions - * @brief FLASH Interface configuration functions - * -@verbatim - =============================================================================== - FLASH Interface configuration functions - =============================================================================== - - FLASH_Interface configuration_Functions, includes the following functions: - - void FLASH_SetLatency(uint32_t FLASH_Latency): - To correctly read data from Flash memory, the number of wait states (LATENCY) - must be correctly programmed according to the frequency of the CPU clock - (HCLK) and the supply voltage of the device. - ---------------------------------------------------------------- - | Wait states | HCLK clock frequency (MHz) | - | |------------------------------------------------| - | (Latency) | voltage range | voltage range | - | | 1.65 V - 3.6 V | 2.0 V - 3.6 V | - | |----------------|---------------|---------------| - | | VCORE = 1.2 V | VCORE = 1.5 V | VCORE = 1.8 V | - |-------------- |----------------|---------------|---------------| - |0WS(1CPU cycle)|0 < HCLK <= 2 |0 < HCLK <= 8 |0 < HCLK <= 16 | - |---------------|----------------|---------------|---------------| - |1WS(2CPU cycle)|2 < HCLK <= 4 |8 < HCLK <= 16 |16 < HCLK <= 32| - ---------------------------------------------------------------- - - - void FLASH_PrefetchBufferCmd(FunctionalState NewState); - - void FLASH_ReadAccess64Cmd(FunctionalState NewState); - - void FLASH_RUNPowerDownCmd(FunctionalState NewState); - - void FLASH_SLEEPPowerDownCmd(FunctionalState NewState); - - void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState); - - Here below the allowed configuration of Latency, 64Bit access and prefetch buffer - -------------------------------------------------------------------------------- - | | ACC64 = 0 | ACC64 = 1 | - | Latency |----------------|---------------|---------------|---------------| - | | PRFTEN = 0 | PRFTEN = 1 | PRFTEN = 0 | PRFTEN = 1 | - |---------------|----------------|---------------|---------------|---------------| - |0WS(1CPU cycle)| YES | NO | YES | YES | - |---------------|----------------|---------------|---------------|---------------| - |1WS(2CPU cycle)| NO | NO | YES | YES | - -------------------------------------------------------------------------------- - All these functions don't need the unlock sequence. - -@endverbatim - * @{ - */ - -/** - * @brief Sets the code latency value. - * @param FLASH_Latency: specifies the FLASH Latency value. - * This parameter can be one of the following values: - * @arg FLASH_Latency_0: FLASH Zero Latency cycle - * @arg FLASH_Latency_1: FLASH One Latency cycle - * @retval None - */ -void FLASH_SetLatency(uint32_t FLASH_Latency) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_FLASH_LATENCY(FLASH_Latency)); - - /* Read the ACR register */ - tmpreg = FLASH->ACR; - - /* Sets the Latency value */ - tmpreg &= (uint32_t) (~((uint32_t)FLASH_ACR_LATENCY)); - tmpreg |= FLASH_Latency; - - /* Write the ACR register */ - FLASH->ACR = tmpreg; -} - -/** - * @brief Enables or disables the Prefetch Buffer. - * @param NewState: new state of the FLASH prefetch buffer. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FLASH_PrefetchBufferCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if(NewState != DISABLE) - { - FLASH->ACR |= FLASH_ACR_PRFTEN; - } - else - { - FLASH->ACR &= (uint32_t)(~((uint32_t)FLASH_ACR_PRFTEN)); - } -} - -/** - * @brief Enables or disables read access to flash by 64 bits. - * @param NewState: new state of the FLASH read access mode. - * This parameter can be: ENABLE or DISABLE. - * @note - If this bit is set, the Read access 64 bit is used. - * - If this bit is reset, the Read access 32 bit is used. - * @note - This bit cannot be written at the same time as the LATENCY and - * PRFTEN bits. - * - To reset this bit, the LATENCY should be zero wait state and the - * prefetch off. - * @retval None - */ -void FLASH_ReadAccess64Cmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if(NewState != DISABLE) - { - FLASH->ACR |= FLASH_ACR_ACC64; - } - else - { - FLASH->ACR &= (uint32_t)(~((uint32_t)FLASH_ACR_ACC64)); - } -} - -/** - * @brief Enable or disable the power down mode during Sleep mode. - * @note This function is used to power down the FLASH when the system is in SLEEP LP mode. - * @param NewState: new state of the power down mode during sleep mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FLASH_SLEEPPowerDownCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Set the SLEEP_PD bit to put Flash in power down mode during sleep mode */ - FLASH->ACR |= FLASH_ACR_SLEEP_PD; - } - else - { - /* Clear the SLEEP_PD bit in to put Flash in idle mode during sleep mode */ - FLASH->ACR &= (uint32_t)(~((uint32_t)FLASH_ACR_SLEEP_PD)); - } -} - -/** - * @} - */ - -/** @defgroup FLASH_Group2 FLASH Memory Programming functions - * @brief FLASH Memory Programming functions - * -@verbatim - =============================================================================== - FLASH Memory Programming functions - =============================================================================== - - The FLASH Memory Programming functions, includes the following functions: - - void FLASH_Unlock(void); - - void FLASH_Lock(void); - - FLASH_Status FLASH_ErasePage(uint32_t Page_Address); - - FLASH_Status FLASH_FastProgramWord(uint32_t Address, uint32_t Data); - - Any operation of erase or program should follow these steps: - - 1. Call the FLASH_Unlock() function to enable the flash control register and - program memory access - - 2. Call the desired function to erase page or program data - - 3. Call the FLASH_Lock() to disable the flash program memory access - (recommended to protect the FLASH memory against possible unwanted operation) - -@endverbatim - * @{ - */ - -/** - * @brief Unlocks the FLASH control register and program memory access. - * @param None - * @retval None - */ -void FLASH_Unlock(void) -{ - if((FLASH->PECR & FLASH_PECR_PRGLOCK) != RESET) - { - /* Unlocking the data memory and FLASH_PECR register access */ - DATA_EEPROM_Unlock(); - - /* Unlocking the program memory access */ - FLASH->PRGKEYR = FLASH_PRGKEY1; - FLASH->PRGKEYR = FLASH_PRGKEY2; - } -} - -/** - * @brief Locks the Program memory access. - * @param None - * @retval None - */ -void FLASH_Lock(void) -{ - /* Set the PRGLOCK Bit to lock the program memory access */ - FLASH->PECR |= FLASH_PECR_PRGLOCK; -} - -/** - * @brief Erases a specified page in program memory. - * @note - To correctly run this function, the FLASH_Unlock() function - * must be called before. - * - Call the FLASH_Lock() to disable the flash memory access - * (recommended to protect the FLASH memory against possible unwanted operation) - * @param Page_Address: The page address in program memory to be erased. - * @note A Page is erased in the Program memory only if the address to load - * is the start address of a page (multiple of 256 bytes). - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_ErasePage(uint32_t Page_Address) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_FLASH_PROGRAM_ADDRESS(Page_Address)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - /* If the previous operation is completed, proceed to erase the page */ - - /* Set the ERASE bit */ - FLASH->PECR |= FLASH_PECR_ERASE; - - /* Set PROG bit */ - FLASH->PECR |= FLASH_PECR_PROG; - - /* Write 00000000h to the first word of the program page to erase */ - *(__IO uint32_t *)Page_Address = 0x00000000; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - /* If the erase operation is completed, disable the ERASE and PROG bits */ - FLASH->PECR &= (uint32_t)(~FLASH_PECR_PROG); - FLASH->PECR &= (uint32_t)(~FLASH_PECR_ERASE); - } - /* Return the Erase Status */ - return status; -} - -/** - * @brief Programs a word at a specified address in program memory. - * @note - To correctly run this function, the FLASH_Unlock() function - * must be called before. - * - Call the FLASH_Lock() to disable the flash memory access - * (recommended to protect the FLASH memory against possible unwanted operation) - * @param Address: specifies the address to be written. - * @param Data: specifies the data to be written. - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_FastProgramWord(uint32_t Address, uint32_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - /* If the previous operation is completed, proceed to program the new word */ - *(__IO uint32_t *)Address = Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - } - /* Return the Write Status */ - return status; -} - -/** - * @} - */ - -/** @defgroup FLASH_Group3 DATA EEPROM Programming functions - * @brief DATA EEPROM Programming functions - * -@verbatim - =============================================================================== - DATA EEPROM Programming functions - =============================================================================== - - The DATA_EEPROM Programming_Functions, includes the following functions: - - void DATA_EEPROM_Unlock(void); - - void DATA_EEPROM_Lock(void); - - FLASH_Status DATA_EEPROM_EraseWord(uint32_t Address); - - FLASH_Status DATA_EEPROM_FastProgramByte(uint32_t Address, uint8_t Data); - - FLASH_Status DATA_EEPROM_FastProgramHalfWord(uint32_t Address, uint16_t Data); - - FLASH_Status DATA_EEPROM_FastProgramWord(uint32_t Address, uint32_t Data); - - FLASH_Status DATA_EEPROM_ProgramByte(uint32_t Address, uint8_t Data); - - FLASH_Status DATA_EEPROM_ProgramHalfWord(uint32_t Address, uint16_t Data); - - FLASH_Status DATA_EEPROM_ProgramWord(uint32_t Address, uint32_t Data); - - Any operation of erase or program should follow these steps: - - 1. Call the DATA_EEPROM_Unlock() function to enable the data EEPROM access - and Flash program erase control register access. - - 2. Call the desired function to erase or program data - - 3. Call the DATA_EEPROM_Lock() to disable the data EEPROM access - and Flash program erase control register access(recommended - to protect the DATA_EEPROM against possible unwanted operation) - -@endverbatim - * @{ - */ - -/** - * @brief Unlocks the data memory and FLASH_PECR register access. - * @param None - * @retval None - */ -void DATA_EEPROM_Unlock(void) -{ - if((FLASH->PECR & FLASH_PECR_PELOCK) != RESET) - { - /* Unlocking the Data memory and FLASH_PECR register access*/ - FLASH->PEKEYR = FLASH_PEKEY1; - FLASH->PEKEYR = FLASH_PEKEY2; - } -} - -/** - * @brief Locks the Data memory and FLASH_PECR register access. - * @param None - * @retval None - */ -void DATA_EEPROM_Lock(void) -{ - /* Set the PELOCK Bit to lock the data memory and FLASH_PECR register access */ - FLASH->PECR |= FLASH_PECR_PELOCK; -} - -/** - * @brief Enables or disables DATA EEPROM fixed Time programming (2*Tprog). - * @param NewState: new state of the DATA EEPROM fixed Time programming mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DATA_EEPROM_FixedTimeProgramCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if(NewState != DISABLE) - { - FLASH->PECR |= (uint32_t)FLASH_PECR_FTDW; - } - else - { - FLASH->PECR &= (uint32_t)(~((uint32_t)FLASH_PECR_FTDW)); - } -} - -/** - * @brief Erase a word in data memory. - * @param Address: specifies the address to be erased - * @note1 - A data memory word is erased in the data memory only if the address - * to load is the start address of a word (multiple of a word). - * @note2 - To correctly run this function, the DATA_EEPROM_Unlock() function - * must be called before. - * - Call the DATA_EEPROM_Lock() to he data EEPROM access - * and Flash program erase control register access(recommended to protect - * the DATA_EEPROM against possible unwanted operation) - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status DATA_EEPROM_EraseWord(uint32_t Address) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_FLASH_DATA_ADDRESS(Address)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - /* Write "00000000h" to valid address in the data memory" */ - *(__IO uint32_t *) Address = 0x00000000; - } - - /* Return the erase status */ - return status; -} - -/** - * @brief Write a Byte at a specified address in data memory. - * @note - To correctly run this function, the DATA_EEPROM_Unlock() function - * must be called before. - * - Call the DATA_EEPROM_Lock() to he data EEPROM access - * and Flash program erase control register access(recommended to protect - * the DATA_EEPROM against possible unwanted operation) - * @param Address: specifies the address to be written. - * @param Data: specifies the data to be written. - * @note This function assumes that the is data word is already erased. - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status DATA_EEPROM_FastProgramByte(uint32_t Address, uint8_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - uint32_t tmp = 0, tmpaddr = 0; - - /* Check the parameters */ - assert_param(IS_FLASH_DATA_ADDRESS(Address)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - /* Clear the FTDW bit */ - FLASH->PECR &= (uint32_t)(~((uint32_t)FLASH_PECR_FTDW)); - - if(Data != (uint8_t)0x00) - { - /* If the previous operation is completed, proceed to write the new Data */ - *(__IO uint8_t *)Address = Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - } - else - { - tmpaddr = Address & 0xFFFFFFFC; - tmp = * (__IO uint32_t *) tmpaddr; - tmpaddr = 0xFF << ((uint32_t) (0x8 * (Address & 0x3))); - tmp &= ~tmpaddr; - status = DATA_EEPROM_EraseWord(Address & 0xFFFFFFFC); - status = DATA_EEPROM_FastProgramWord((Address & 0xFFFFFFFC), tmp); - } - } - /* Return the Write Status */ - return status; -} - -/** - * @brief Writes a half word at a specified address in data memory. - * @note - To correctly run this function, the DATA_EEPROM_Unlock() function - * must be called before. - * - Call the DATA_EEPROM_Lock() to he data EEPROM access - * and Flash program erase control register access(recommended to protect - * the DATA_EEPROM against possible unwanted operation) - * @param Address: specifies the address to be written. - * @param Data: specifies the data to be written. - * @note This function assumes that the is data word is already erased. - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status DATA_EEPROM_FastProgramHalfWord(uint32_t Address, uint16_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - uint32_t tmp = 0, tmpaddr = 0; - - /* Check the parameters */ - assert_param(IS_FLASH_DATA_ADDRESS(Address)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - /* Clear the FTDW bit */ - FLASH->PECR &= (uint32_t)(~((uint32_t)FLASH_PECR_FTDW)); - - if(Data != (uint16_t)0x0000) - { - /* If the previous operation is completed, proceed to write the new data */ - *(__IO uint16_t *)Address = Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - } - else - { - if((Address & 0x3) != 0x3) - { - tmpaddr = Address & 0xFFFFFFFC; - tmp = * (__IO uint32_t *) tmpaddr; - tmpaddr = 0xFFFF << ((uint32_t) (0x8 * (Address & 0x3))); - tmp &= ~tmpaddr; - status = DATA_EEPROM_EraseWord(Address & 0xFFFFFFFC); - status = DATA_EEPROM_FastProgramWord((Address & 0xFFFFFFFC), tmp); - } - else - { - DATA_EEPROM_FastProgramByte(Address, 0x00); - DATA_EEPROM_FastProgramByte(Address + 1, 0x00); - } - } - } - /* Return the Write Status */ - return status; -} - -/** - * @brief Programs a word at a specified address in data memory. - * @note - To correctly run this function, the DATA_EEPROM_Unlock() function - * must be called before. - * - Call the DATA_EEPROM_Lock() to the data EEPROM access - * and Flash program erase control register access(recommended to protect - * the DATA_EEPROM against possible unwanted operation) - * @param Address: specifies the address to be written. - * @param Data: specifies the data to be written. - * @note This function assumes that the is data word is already erased. - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status DATA_EEPROM_FastProgramWord(uint32_t Address, uint32_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_FLASH_DATA_ADDRESS(Address)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - /* Clear the FTDW bit */ - FLASH->PECR &= (uint32_t)(~((uint32_t)FLASH_PECR_FTDW)); - - /* If the previous operation is completed, proceed to program the new data */ - *(__IO uint32_t *)Address = Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - } - /* Return the Write Status */ - return status; -} - -/** - * @brief Write a Byte at a specified address in data memory without erase. - * @note - To correctly run this function, the DATA_EEPROM_Unlock() function - * must be called before. - * - Call the DATA_EEPROM_Lock() to he data EEPROM access - * and Flash program erase control register access(recommended to protect - * the DATA_EEPROM against possible unwanted operation) - * @note The function DATA_EEPROM_FixedTimeProgramCmd() can be called before - * this function to configure the Fixed Time Programming. - * @param Address: specifies the address to be written. - * @param Data: specifies the data to be written. - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status DATA_EEPROM_ProgramByte(uint32_t Address, uint8_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - uint32_t tmp = 0, tmpaddr = 0; - - /* Check the parameters */ - assert_param(IS_FLASH_DATA_ADDRESS(Address)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - if(Data != (uint8_t) 0x00) - { - *(__IO uint8_t *)Address = Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - } - else - { - tmpaddr = Address & 0xFFFFFFFC; - tmp = * (__IO uint32_t *) tmpaddr; - tmpaddr = 0xFF << ((uint32_t) (0x8 * (Address & 0x3))); - tmp &= ~tmpaddr; - status = DATA_EEPROM_EraseWord(Address & 0xFFFFFFFC); - status = DATA_EEPROM_FastProgramWord((Address & 0xFFFFFFFC), tmp); - } - } - /* Return the Write Status */ - return status; -} - -/** - * @brief Writes a half word at a specified address in data memory without erase. - * @note - To correctly run this function, the DATA_EEPROM_Unlock() function - * must be called before. - * - Call the DATA_EEPROM_Lock() to he data EEPROM access - * and Flash program erase control register access(recommended to protect - * the DATA_EEPROM against possible unwanted operation) - * @note The function DATA_EEPROM_FixedTimeProgramCmd() can be called before - * this function to configure the Fixed Time Programming - * @param Address: specifies the address to be written. - * @param Data: specifies the data to be written. - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status DATA_EEPROM_ProgramHalfWord(uint32_t Address, uint16_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - uint32_t tmp = 0, tmpaddr = 0; - - /* Check the parameters */ - assert_param(IS_FLASH_DATA_ADDRESS(Address)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - if(Data != (uint16_t)0x0000) - { - *(__IO uint16_t *)Address = Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - } - else - { - if((Address & 0x3) != 0x3) - { - tmpaddr = Address & 0xFFFFFFFC; - tmp = * (__IO uint32_t *) tmpaddr; - tmpaddr = 0xFFFF << ((uint32_t) (0x8 * (Address & 0x3))); - tmp &= ~tmpaddr; - status = DATA_EEPROM_EraseWord(Address & 0xFFFFFFFC); - status = DATA_EEPROM_FastProgramWord((Address & 0xFFFFFFFC), tmp); - } - else - { - DATA_EEPROM_FastProgramByte(Address, 0x00); - DATA_EEPROM_FastProgramByte(Address + 1, 0x00); - } - } - } - /* Return the Write Status */ - return status; -} - -/** - * @brief Programs a word at a specified address in data memory without erase. - * @note - To correctly run this function, the DATA_EEPROM_Unlock() function - * must be called before. - * - Call the DATA_EEPROM_Lock() to he data EEPROM access - * and Flash program erase control register access(recommended to protect - * the DATA_EEPROM against possible unwanted operation) - * @note The function DATA_EEPROM_FixedTimeProgramCmd() can be called before - * this function to configure the Fixed Time Programming. - * @param Address: specifies the address to be written. - * @param Data: specifies the data to be written. - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status DATA_EEPROM_ProgramWord(uint32_t Address, uint32_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_FLASH_DATA_ADDRESS(Address)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - *(__IO uint32_t *)Address = Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - } - /* Return the Write Status */ - return status; -} - -/** - * @} - */ - -/** @defgroup FLASH_Group4 Option Bytes Programming functions - * @brief Option Bytes Programming functions - * -@verbatim - =============================================================================== - Option Bytes Programming functions - =============================================================================== - - The FLASH_Option Bytes Programming_functions, includes the following functions: - - void FLASH_OB_Unlock(void); - - void FLASH_OB_Lock(void); - - void FLASH_OB_Launch(void); - - FLASH_Status FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState); - - FLASH_Status FLASH_OB_RDPConfig(uint8_t OB_RDP); - - FLASH_Status FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY); - - FLASH_Status FLASH_OB_BORConfig(uint8_t OB_BOR); - - uint8_t FLASH_OB_GetUser(void); - - uint32_t FLASH_OB_GetWRP(void); - - FlagStatus FLASH_OB_GetRDP(void); - - uint8_t FLASH_OB_GetBOR(void); - - Any operation of erase or program should follow these steps: - - 1. Call the FLASH_OB_Unlock() function to enable the Flash option control register access - - 2. Call one or several functions to program the desired option bytes - - void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) => to Enable/Disable - the desired sector write protection - - void FLASH_OB_RDPConfig(uint8_t OB_RDP) => to set the desired read Protection Level - - void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) => to configure - the user option Bytes: IWDG, STOP and the Standby. - - void FLASH_OB_BORConfig(uint8_t OB_BOR) => to Set the BOR level - - FLASH_Status FLASH_ProgramOTP(uint32_t Address, uint32_t Data) => to program the OTP bytes - - 3. Once all needed option bytes to be programmed are correctly written, call the - FLASH_OB_Launch(void) function to launch the Option Bytes programming process. - - 4. Call the FLASH_OB_Lock() to disable the Flash option control register access (recommended - to protect the option Bytes against possible unwanted operations) - -@endverbatim - * @{ - */ - -/** - * @brief Unlocks the option bytes block access. - * @param None - * @retval None - */ -void FLASH_OB_Unlock(void) -{ - if((FLASH->PECR & FLASH_PECR_OPTLOCK) != RESET) - { - /* Unlocking the data memory and FLASH_PECR register access */ - DATA_EEPROM_Unlock(); - - /* Unlocking the option bytes block access */ - FLASH->OPTKEYR = FLASH_OPTKEY1; - FLASH->OPTKEYR = FLASH_OPTKEY2; - } -} - -/** - * @brief Locks the option bytes block access. - * @param None - * @retval None - */ -void FLASH_OB_Lock(void) -{ - /* Set the OPTLOCK Bit to lock the option bytes block access */ - FLASH->PECR |= FLASH_PECR_OPTLOCK; -} - -/** - * @brief Launch the option byte loading. - * @param None - * @retval None - */ -void FLASH_OB_Launch(void) -{ - /* Set the OBL_Launch bit to lauch the option byte loading */ - FLASH->PECR |= FLASH_PECR_OBL_LAUNCH; -} - -/** - * @brief Write protects the desired pages - * @note - To correctly run this function, the FLASH_OB_Unlock() function - * must be called before. - * - Call the FLASH_OB_Lock() to disable the flash control register access and the option bytes - * (recommended to protect the FLASH memory against possible unwanted operation) - * @param OB_WRP: specifies the address of the pages to be write protected. - * This parameter can be: - * @arg value between OB_WRP_Pages0to15 and OB_WRP_Pages496to511 - * @arg OB_WRP_AllPages - * @param NewState: new state of the specified FLASH Pages Wtite protection. - * This parameter can be: ENABLE or DISABLE. - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) -{ - uint32_t WRP01_Data = 0, WRP23_Data = 0; - - FLASH_Status status = FLASH_COMPLETE; - uint32_t tmp1 = 0, tmp2 = 0; - - /* Check the parameters */ - assert_param(IS_OB_WRP(OB_WRP)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - if (NewState != DISABLE) - { - WRP01_Data = (uint16_t)(((OB_WRP & WRP01_MASK) | OB->WRP01)); - WRP23_Data = (uint16_t)((((OB_WRP & WRP23_MASK)>>16 | OB->WRP23))); - tmp1 = (uint32_t)(~(WRP01_Data) << 16)|(WRP01_Data); - OB->WRP01 = tmp1; - - tmp2 = (uint32_t)(~(WRP23_Data) << 16)|(WRP23_Data); - OB->WRP23 = tmp2; - } - - else - { - WRP01_Data = (uint16_t)(~OB_WRP & (WRP01_MASK & OB->WRP01)); - WRP23_Data = (uint16_t)((((~OB_WRP & WRP23_MASK)>>16 & OB->WRP23))); - - tmp1 = (uint32_t)((~WRP01_Data) << 16)|(WRP01_Data); - OB->WRP01 = tmp1; - - tmp2 = (uint32_t)((~WRP23_Data) << 16)|(WRP23_Data); - OB->WRP23 = tmp2; - } - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - } - - /* Return the write protection operation Status */ - return status; -} - -/** - * @brief Enables or disables the read out protection. - * @note - To correctly run this function, the FLASH_OB_Unlock() function - * must be called before. - * - Call the FLASH_OB_Lock() to disable the flash control register access and the option bytes - * (recommended to protect the FLASH memory against possible unwanted operation) - * @param FLASH_ReadProtection_Level: specifies the read protection level. - * This parameter can be: - * @arg OB_RDP_Level_0: No protection - * @arg OB_RDP_Level_1: Read protection of the memory - * @arg OB_RDP_Level_2: Chip protection - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_OB_RDPConfig(uint8_t OB_RDP) -{ - FLASH_Status status = FLASH_COMPLETE; - uint8_t tmp1 = 0; - uint32_t tmp2 = 0; - - /* Check the parameters */ - assert_param(IS_OB_RDP(OB_RDP)); - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - /* calculate the option byte to write */ - tmp1 = (uint8_t)(~(OB_RDP )); - tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16)) | ((uint32_t)OB_RDP)); - - if(status == FLASH_COMPLETE) - { - /* program read protection level */ - OB->RDP = tmp2; - } - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - /* Return the Read protection operation Status */ - return status; -} - -/** - * @brief Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY. - * @note - To correctly run this function, the FLASH_OB_Unlock() function - * must be called before. - * - Call the FLASH_OB_Lock() to disable the flash control register access and the option bytes - * (recommended to protect the FLASH memory against possible unwanted operation) - * @param OB_IWDG: Selects the WDG mode - * This parameter can be one of the following values: - * @arg OB_IWDG_SW: Software WDG selected - * @arg OB_IWDG_HW: Hardware WDG selected - * @param OB_STOP: Reset event when entering STOP mode. - * This parameter can be one of the following values: - * @arg OB_STOP_NoRST: No reset generated when entering in STOP - * @arg OB_STOP_RST: Reset generated when entering in STOP - * @param OB_STDBY: Reset event when entering Standby mode. - * This parameter can be one of the following values: - * @arg OB_STDBY_NoRST: No reset generated when entering in STANDBY - * @arg OB_STDBY_RST: Reset generated when entering in STANDBY - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) -{ - FLASH_Status status = FLASH_COMPLETE; - uint32_t tmp = 0, tmp1 = 0; - - /* Check the parameters */ - assert_param(IS_OB_IWDG_SOURCE(OB_IWDG)); - assert_param(IS_OB_STOP_SOURCE(OB_STOP)); - assert_param(IS_OB_STDBY_SOURCE(OB_STDBY)); - - /* Get the User Option byte register */ - tmp1 = (FLASH->OBR & 0x000F0000) >> 16; - - /* Calculate the user option byte to write */ - tmp = (uint32_t)(((uint32_t)~((uint32_t)((uint32_t)(OB_IWDG) | (uint32_t)(OB_STOP) | (uint32_t)(OB_STDBY) | tmp1))) << ((uint32_t)0x10)); - tmp |= ((uint32_t)(OB_IWDG) | ((uint32_t)OB_STOP) | (uint32_t)(OB_STDBY) | tmp1); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - /* Write the User Option Byte */ - OB->USER = tmp; - } - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - /* Return the Option Byte program Status */ - return status; -} - -/** - * @brief Programs the FLASH brownout reset threshold level Option Byte. - * @note - To correctly run this function, the FLASH_OB_Unlock() function - * must be called before. - * - Call the FLASH_OB_Lock() to disable the flash control register access and the option bytes - * (recommended to protect the FLASH memory against possible unwanted operation) - * @param OB_BOR: Selects the brownout reset threshold level - * This parameter can be one of the following values: - * @arg OB_BOR_OFF: BOR is disabled at power down, the reset is asserted when the VDD - * power supply reaches the PDR(Power Down Reset) threshold (1.5V) - * @arg OB_BOR_LEVEL1: BOR Reset threshold levels for 1.7V - 1.8V VDD power supply - * @arg OB_BOR_LEVEL2: BOR Reset threshold levels for 1.9V - 2.0V VDD power supply - * @arg OB_BOR_LEVEL3: BOR Reset threshold levels for 2.3V - 2.4V VDD power supply - * @arg OB_BOR_LEVEL4: BOR Reset threshold levels for 2.55V - 2.65V VDD power supply - * @arg OB_BOR_LEVEL5: BOR Reset threshold levels for 2.8V - 2.9V VDD power supply - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_OB_BORConfig(uint8_t OB_BOR) -{ - FLASH_Status status = FLASH_COMPLETE; - uint32_t tmp = 0, tmp1 = 0; - - /* Check the parameters */ - assert_param(IS_OB_BOR_LEVEL(OB_BOR)); - - /* Get the User Option byte register */ - tmp1 = (FLASH->OBR & 0x00700000) >> 16; - - /* Calculate the option byte to write */ - tmp = (uint32_t)~(OB_BOR | tmp1)<<16; - tmp |= (OB_BOR | tmp1); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - /* Write the BOR Option Byte */ - OB->USER = tmp; - } - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - /* Return the Option Byte program Status */ - return status; -} - -/** - * @brief Returns the FLASH User Option Bytes values. - * @param None - * @retval The FLASH User Option Bytes . - */ -uint8_t FLASH_OB_GetUser(void) -{ - /* Return the User Option Byte */ - return (uint8_t)(FLASH->OBR >> 20); -} - -/** - * @brief Returns the FLASH Write Protection Option Bytes value. - * @param None - * @retval The FLASH Write Protection Option Bytes value - */ -uint32_t FLASH_OB_GetWRP(void) -{ - /* Return the FLASH write protection Register value */ - return (uint32_t)(FLASH->WRPR); -} - -/** - * @brief Checks whether the FLASH Read out Protection Status is set or not. - * @param None - * @retval FLASH ReadOut Protection Status(SET or RESET) - */ -FlagStatus FLASH_OB_GetRDP(void) -{ - FlagStatus readstatus = RESET; - - if ((uint8_t)(FLASH->OBR) != (uint8_t)OB_RDP_Level_0) - { - readstatus = SET; - } - else - { - readstatus = RESET; - } - return readstatus; -} - -/** - * @brief Returns the FLASH BOR level. - * @param None - * @retval The FLASH User Option Bytes . - */ -uint8_t FLASH_OB_GetBOR(void) -{ - /* Return the BOR level */ - return (uint8_t)((FLASH->OBR & (uint32_t)0x000F0000) >> 16); -} - -/** - * @} - */ - -/** @defgroup FLASH_Group5 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified FLASH interrupts. - * @param FLASH_IT: specifies the FLASH interrupt sources to be enabled or - * disabled. - * This parameter can be any combination of the following values: - * @arg FLASH_IT_EOP: FLASH end of programming Interrupt - * @arg FLASH_IT_ERR: FLASH Error Interrupt - * @retval None - */ -void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FLASH_IT(FLASH_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if(NewState != DISABLE) - { - /* Enable the interrupt sources */ - FLASH->PECR |= FLASH_IT; - } - else - { - /* Disable the interrupt sources */ - FLASH->PECR &= ~(uint32_t)FLASH_IT; - } -} - -/** - * @brief Checks whether the specified FLASH flag is set or not. - * @param FLASH_FLAG: specifies the FLASH flag to check. - * This parameter can be one of the following values: - * @arg FLASH_FLAG_BSY: FLASH write/erase operations in progress flag - * @arg FLASH_FLAG_EOP: FLASH End of Operation flag - * @arg FLASH_FLAG_READY: FLASH Ready flag after low power mode - * @arg FLASH_FLAG_ENDHV: FLASH End of high voltage flag - * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag - * @arg FLASH_FLAG_PGAERR: FLASH Programming Alignment error flag - * @arg FLASH_FLAG_SIZERR: FLASH size error flag - * @arg FLASH_FLAG_OPTVERR: FLASH Option validity error flag - * @retval The new state of FLASH_FLAG (SET or RESET). - */ -FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG) -{ - FlagStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)); - - if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the new state of FLASH_FLAG (SET or RESET) */ - return bitstatus; -} - -/** - * @brief Clears the FLASHs pending flags. - * @param FLASH_FLAG: specifies the FLASH flags to clear. - * This parameter can be any combination of the following values: - * @arg FLASH_FLAG_EOP: FLASH End of Operation flag - * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag - * @arg FLASH_FLAG_PGAERR: FLASH Programming Alignment error flag - * @arg FLASH_FLAG_SIZERR: FLASH size error flag - * @arg FLASH_FLAG_OPTVERR: FLASH Option validity error flag - * @retval None - */ -void FLASH_ClearFlag(uint32_t FLASH_FLAG) -{ - /* Check the parameters */ - assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)); - - /* Clear the flags */ - FLASH->SR = FLASH_FLAG; -} - -/** - * @brief Returns the FLASH Status. - * @param None - * @retval FLASH Status: The returned value can be: - * FLASH_BUSY, FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP or FLASH_COMPLETE. - */ -FLASH_Status FLASH_GetStatus(void) -{ - FLASH_Status FLASHstatus = FLASH_COMPLETE; - - if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY) - { - FLASHstatus = FLASH_BUSY; - } - else - { - if((FLASH->SR & (uint32_t)FLASH_FLAG_WRPERR)!= (uint32_t)0x00) - { - FLASHstatus = FLASH_ERROR_WRP; - } - else - { - if((FLASH->SR & (uint32_t)0xFEF0) != (uint32_t)0x00) - { - FLASHstatus = FLASH_ERROR_PROGRAM; - } - else - { - FLASHstatus = FLASH_COMPLETE; - } - } - } - /* Return the FLASH Status */ - return FLASHstatus; -} - - -/** - * @brief Waits for a FLASH operation to complete or a TIMEOUT to occur. - * @param Timeout: FLASH programming Timeout - * @retval FLASH Status: The returned value can be: FLASH_BUSY, - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check for the FLASH Status */ - status = FLASH_GetStatus(); - - /* Wait for a FLASH operation to complete or a TIMEOUT to occur */ - while((status == FLASH_BUSY) && (Timeout != 0x00)) - { - status = FLASH_GetStatus(); - Timeout--; - } - - if(Timeout == 0x00 ) - { - status = FLASH_TIMEOUT; - } - /* Return the operation status */ - return status; -} - -/** - * @} - */ - -/** - * @} - */ - - /** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_flash_ramfunc.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_flash_ramfunc.c deleted file mode 100644 index aefaf96c4..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_flash_ramfunc.c +++ /dev/null @@ -1,385 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_flash_ramfunc.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides all the Flash firmware functions which should be - * executed from the internal SRAM. This file should be placed in - * internal SRAM. - * Other FLASH memory functions that can be used from the FLASH are - * defined in the "stm32l1xx_flash.c" file. - * @verbatim - * - * ARM Compiler - * ------------ - * RAM functions are defined using the toolchain options. - * Functions that are be executed in RAM should reside in a separate - * source module. Using the 'Options for File' dialog you can simply change - * the 'Code / Const' area of a module to a memory space in physical RAM. - * Available memory areas are declared in the 'Target' tab of the - * 'Options for Target' dialog. - * - * ICCARM Compiler - * --------------- - * RAM functions are defined using a specific toolchain keyword "__ramfunc". - * - * GNU Compiler - * ------------ - * RAM functions are defined using a specific toolchain attribute - * "__attribute__((section(".data")))". - * - * TASKING Compiler - * ---------------- - * RAM functions are defined using a specific toolchain pragma. This - * pragma is defined inside this file. - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_flash.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup FLASH - * @brief FLASH driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -static __RAM_FUNC GetStatus(void); -static __RAM_FUNC WaitForLastOperation(uint32_t Timeout); - -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup FLASH_Private_Functions - * @{ - */ - -/** @addtogroup FLASH_Group1 - * -@verbatim -@endverbatim - * @{ - */ -#if defined ( __TASKING__ ) -#pragma section_code_init on -#endif - -/** - * @brief Enable or disable the power down mode during RUN mode. - * @note: This function can be used only when the user code is running from Internal SRAM - * @param NewState: new state of the power down mode during RUN mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -__RAM_FUNC FLASH_RUNPowerDownCmd(FunctionalState NewState) -{ - FLASH_Status status = FLASH_COMPLETE; - - if (NewState != DISABLE) - { - /* Unlock the RUN_PD bit */ - FLASH->PDKEYR = FLASH_PDKEY1; - FLASH->PDKEYR = FLASH_PDKEY2; - - /* Set the RUN_PD bit in FLASH_ACR register to put Flash in power down mode */ - FLASH->ACR |= (uint32_t)FLASH_ACR_RUN_PD; - - if((FLASH->ACR & FLASH_ACR_RUN_PD) != FLASH_ACR_RUN_PD) - { - status = FLASH_ERROR_PROGRAM; - } - } - else - { - /* Clear the RUN_PD bit in FLASH_ACR register to put Flash in idle mode */ - FLASH->ACR &= (uint32_t)(~(uint32_t)FLASH_ACR_RUN_PD); - } - - /* Return the Write Status */ - return status; -} - -/** - * @} - */ - -/** @addtogroup FLASH_Group2 - * -@verbatim -@endverbatim - * @{ - */ - -/** - * @brief Programs a half page in program memory. - * @param Address: specifies the address to be written. - * @param pBuffer: pointer to the buffer containing the data to be written to - * the half page. - * @note - To correctly run this function, the FLASH_Unlock() function - * must be called before. - * - Call the FLASH_Lock() to disable the flash memory access - * (recommended to protect the FLASH memory against possible unwanted operation) - * @note Half page write is possible only from SRAM. - * @note If there are more than 32 words to write, after 32 words another - * Half Page programming operation starts and has to be finished. - * @note A half page is written to the program memory only if the first - * address to load is the start address of a half page (multiple of 128 - * bytes) and the 31 remaining words to load are in the same half page. - * @note During the Program memory half page write all read operations are - * forbidden (this includes DMA read operations and debugger read - * operations such as breakpoints, periodic updates, etc.) - * @note If a PGAERR is set during a Program memory half page write, the - * complete write operation is aborted. Software should then reset the - * FPRG and PROG/DATA bits and restart the write operation from the - * beginning. - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -__RAM_FUNC FLASH_ProgramHalfPage(uint32_t Address, uint32_t* pBuffer) -{ - uint32_t count = 0; - - FLASH_Status status = FLASH_COMPLETE; - - /* Wait for last operation to be completed */ - status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new - half page */ - FLASH->PECR |= FLASH_PECR_FPRG; - FLASH->PECR |= FLASH_PECR_PROG; - - /* Write one half page directly with 32 different words */ - while(count < 32) - { - *(__IO uint32_t*) (Address + (4 * count)) = *(pBuffer++); - count ++; - } - /* Wait for last operation to be completed */ - status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - /* if the write operation is completed, disable the PROG and FPRG bits */ - FLASH->PECR &= (uint32_t)(~FLASH_PECR_PROG); - FLASH->PECR &= (uint32_t)(~FLASH_PECR_FPRG); - } - /* Return the Write Status */ - return status; -} - -/** - * @} - */ - -/** @addtogroup FLASH_Group3 - * -@verbatim -@endverbatim - * @{ - */ - -/** - * @brief Erase a double word in data memory. - * @param Address: specifies the address to be erased - * @note - To correctly run this function, the DATA_EEPROM_Unlock() function - * must be called before. - * - Call the DATA_EEPROM_Lock() to he data EEPROM access - * and Flash program erase control register access(recommended to protect - * the DATA_EEPROM against possible unwanted operation) - * @note Data memory double word erase is possible only from SRAM. - * @note A double word is erased to the data memory only if the first address - * to load is the start address of a double word (multiple of 8 bytes) - * @note During the Data memory double word erase, all read operations are - * forbidden (this includes DMA read operations and debugger read - * operations such as breakpoints, periodic updates, etc.) - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ - -__RAM_FUNC DATA_EEPROM_EraseDoubleWord(uint32_t Address) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Wait for last operation to be completed */ - status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - /* If the previous operation is completed, proceed to erase the next double word */ - /* Set the ERASE bit */ - FLASH->PECR |= FLASH_PECR_ERASE; - - /* Set DATA bit */ - FLASH->PECR |= FLASH_PECR_DATA; - - /* Write 00000000h to the 2 words to erase */ - *(__IO uint64_t *)Address = 0x00000000; - - /* Wait for last operation to be completed */ - status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - /* If the erase operation is completed, disable the ERASE and DATA bits */ - FLASH->PECR &= (uint32_t)(~FLASH_PECR_ERASE); - FLASH->PECR &= (uint32_t)(~FLASH_PECR_DATA); - } - /* Return the erase status */ - return status; -} - -/** - * @brief Write a double word in data memory without erase. - * @param Address: specifies the address to be written. - * @param Data: specifies the data to be written. - * @note - To correctly run this function, the DATA_EEPROM_Unlock() function - * must be called before. - * - Call the DATA_EEPROM_Lock() to he data EEPROM access - * and Flash program erase control register access(recommended to protect - * the DATA_EEPROM against possible unwanted operation) - * @note Data memory double word write is possible only from SRAM. - * @note A data memory double word is written to the data memory only if the - * first address to load is the start address of a double word (multiple - * of double word). - * @note During the Data memory double word write, all read operations are - * forbidden (this includes DMA read operations and debugger read - * operations such as breakpoints, periodic updates, etc.) - * @retval FLASH Status: The returned value can be: - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. - */ -__RAM_FUNC DATA_EEPROM_ProgramDoubleWord(uint32_t Address, uint64_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Wait for last operation to be completed */ - status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - if(status == FLASH_COMPLETE) - { - /* If the previous operation is completed, proceed to program the new data*/ - FLASH->PECR |= FLASH_PECR_FPRG; - FLASH->PECR |= FLASH_PECR_DATA; - - /* Write the 2 words */ - *(__IO uint32_t *)Address = (uint32_t) Data; - Address += 4; - *(__IO uint32_t *)Address = (uint32_t) (Data >> 32); - - /* Wait for last operation to be completed */ - status = WaitForLastOperation(FLASH_ER_PRG_TIMEOUT); - - /* If the write operation is completed, disable the FPRG and DATA bits */ - FLASH->PECR &= (uint32_t)(~FLASH_PECR_FPRG); - FLASH->PECR &= (uint32_t)(~FLASH_PECR_DATA); - } - /* Return the Write Status */ - return status; -} - -/** - * @} - */ - -/** - * @brief Returns the FLASH Status. - * @param None - * @retval FLASH Status: The returned value can be: FLASH_BUSY, - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP or FLASH_COMPLETE - */ -static __RAM_FUNC GetStatus(void) -{ - FLASH_Status FLASHstatus = FLASH_COMPLETE; - - if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY) - { - FLASHstatus = FLASH_BUSY; - } - else - { - if((FLASH->SR & (uint32_t)FLASH_FLAG_WRPERR)!= (uint32_t)0x00) - { - FLASHstatus = FLASH_ERROR_WRP; - } - else - { - if((FLASH->SR & (uint32_t)0xFEF0) != (uint32_t)0x00) - { - FLASHstatus = FLASH_ERROR_PROGRAM; - } - else - { - FLASHstatus = FLASH_COMPLETE; - } - } - } - /* Return the FLASH Status */ - return FLASHstatus; -} - -/** - * @brief Waits for a FLASH operation to complete or a TIMEOUT to occur. - * @param Timeout: FLASH programming Timeout - * @retval FLASH Status: The returned value can be: FLASH_BUSY, - * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or - * FLASH_TIMEOUT. - */ -static __RAM_FUNC WaitForLastOperation(uint32_t Timeout) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check for the FLASH Status */ - status = GetStatus(); - - /* Wait for a FLASH operation to complete or a TIMEOUT to occur */ - while((status == FLASH_BUSY) && (Timeout != 0x00)) - { - status = GetStatus(); - Timeout--; - } - - if(Timeout == 0x00 ) - { - status = FLASH_TIMEOUT; - } - /* Return the operation status */ - return status; -} - -#if defined ( __TASKING__ ) -#pragma section_code_init restore -#endif - -/** - * @} - */ - - /** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_gpio.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_gpio.c deleted file mode 100644 index ad2db4fe0..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_gpio.c +++ /dev/null @@ -1,546 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_gpio.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the GPIO peripheral: - * - Initialization and Configuration - * - GPIO Read and Write - * - GPIO Alternate functions configuration - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable the GPIO AHB clock using RCC_AHBPeriphClockCmd() - * - * 2. Configure the GPIO pin(s) using GPIO_Init() - * Four possible configuration are available for each pin: - * - Input: Floating, Pull-up, Pull-down. - * - Output: Push-Pull (Pull-up, Pull-down or no Pull) - * Open Drain (Pull-up, Pull-down or no Pull). - * In output mode, the speed is configurable: Very Low, Low, - * Medium or High. - * - Alternate Function: Push-Pull (Pull-up, Pull-down or no Pull) - * Open Drain (Pull-up, Pull-down or no Pull). - * - Analog: required mode when a pin is to be used as ADC channel, - * DAC output or comparator input. - * - * 3- Peripherals alternate function: - * - For ADC, DAC and comparators, configure the desired pin in - * analog mode using GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AN - * - For other peripherals (TIM, USART...): - * - Connect the pin to the desired peripherals' Alternate - * Function (AF) using GPIO_PinAFConfig() function - * - Configure the desired pin in alternate function mode using - * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF - * - Select the type, pull-up/pull-down and output speed via - * GPIO_PuPd, GPIO_OType and GPIO_Speed members - * - Call GPIO_Init() function - * - * 4. To get the level of a pin configured in input mode use GPIO_ReadInputDataBit() - * - * 5. To set/reset the level of a pin configured in output mode use - * GPIO_SetBits()/GPIO_ResetBits() - * - * 6. During and just after reset, the alternate functions are not - * active and the GPIO pins are configured in input floating mode - * (except JTAG pins). - * - * 7. The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as - * general-purpose (PC14 and PC15, respectively) when the LSE - * oscillator is off. The LSE has priority over the GPIO function. - * - * 8. The HSE oscillator pins OSC_IN/OSC_OUT can be used as - * general-purpose PH0 and PH1, respectively, when the HSE - * oscillator is off. The HSE has priority over the GPIO function. - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_gpio.h" -#include "stm32l1xx_rcc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup GPIO - * @brief GPIO driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup GPIO_Private_Functions - * @{ - */ - -/** @defgroup GPIO_Group1 Initialization and Configuration - * @brief Initialization and Configuration - * -@verbatim - =============================================================================== - Initialization and Configuration - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the GPIOx peripheral registers to their default reset - * values. - * By default, The GPIO pins are configured in input floating mode - * (except JTAG pins). - * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. - * @retval None - */ -void GPIO_DeInit(GPIO_TypeDef* GPIOx) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - - if(GPIOx == GPIOA) - { - RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOA, ENABLE); - RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOA, DISABLE); - } - else if(GPIOx == GPIOB) - { - RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOB, ENABLE); - RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOB, DISABLE); - } - else if(GPIOx == GPIOC) - { - RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOC, ENABLE); - RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOC, DISABLE); - } - else if(GPIOx == GPIOD) - { - RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOD, ENABLE); - RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOD, DISABLE); - } - else if(GPIOx == GPIOE) - { - RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOE, ENABLE); - RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOE, DISABLE); - } - else - { - if(GPIOx == GPIOH) - { - RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOH, ENABLE); - RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOH, DISABLE); - } - } -} - -/** - * @brief Initializes the GPIOx peripheral according to the specified - * parameters in the GPIO_InitStruct. - * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. - * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that - * contains the configuration information for the specified GPIO - * peripheral. - * GPIO_Pin: selects the pin to be configured: GPIO_Pin_0 -> GPIO_Pin_15 - * GPIO_Mode: selects the mode of the pin: - * - Input mode: GPIO_Mode_IN - * - Output mode: GPIO_Mode_OUT - * - Alternate Function mode: GPIO_Mode_AF - * - Analog mode: GPIO_Mode_AN - * GPIO_Speed: selects the speed of the pin if configured in Output: - * - Very Low: GPIO_Speed_400KHz - * - Low: GPIO_Speed_2MHz - * - Medium: GPIO_Speed_10MHz - * - High: GPIO_Speed_40MHz - * GPIO_OType: selects the Output type (if the selected mode is output): - * - Push-pull: GPIO_OType_PP - * - Open Drain: GPIO_OType_OD - * GPIO_PuPd: configures the Pull-up/Pull-down resistor on the pin: - * - pull-up: GPIO_PuPd_UP - * - pull-down: GPIO_PuPd_DOWN - * - Neither pull-up nor Pull-down: GPIO_PuPd_NOPULL - * @retval None - */ -void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) -{ - uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00; - - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); - assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); - assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd)); - - /* -------------------------Configure the port pins---------------- */ - /*-- GPIO Mode Configuration --*/ - for (pinpos = 0x00; pinpos < 0x10; pinpos++) - { - pos = ((uint32_t)0x01) << pinpos; - - /* Get the port pins position */ - currentpin = (GPIO_InitStruct->GPIO_Pin) & pos; - - if (currentpin == pos) - { - GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2)); - - GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2)); - - if ((GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) || (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_AF)) - { - /* Check Speed mode parameters */ - assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed)); - - /* Speed mode configuration */ - GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2)); - GPIOx->OSPEEDR |= ((uint32_t)(GPIO_InitStruct->GPIO_Speed) << (pinpos * 2)); - - /*Check Output mode parameters */ - assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType)); - - /* Output mode configuration */ - GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos)) ; - GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << ((uint16_t)pinpos)); - } - - /* Pull-up Pull down resistor configuration */ - GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2)); - GPIOx->PUPDR |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) << (pinpos * 2)); - } - } -} - -/** - * @brief Fills each GPIO_InitStruct member with its default value. - * @param GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct) -{ - /* Reset GPIO init structure parameters values */ - GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All; - GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStruct->GPIO_Speed = GPIO_Speed_400KHz; - GPIO_InitStruct->GPIO_OType = GPIO_OType_PP; - GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_NOPULL; -} - -/** - * @brief Locks GPIO Pins configuration registers. - * The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, - * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH. - * The configuration of the locked GPIO pins can no longer be modified - * until the next reset. - * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bit to be written. - * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). - * @retval None - */ -void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - uint32_t tmp = 0x00010000; - - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GPIO_PIN(GPIO_Pin)); - - tmp |= GPIO_Pin; - /* Set LCKK bit */ - GPIOx->LCKR = tmp; - /* Reset LCKK bit */ - GPIOx->LCKR = GPIO_Pin; - /* Set LCKK bit */ - GPIOx->LCKR = tmp; - /* Read LCKK bit*/ - tmp = GPIOx->LCKR; - /* Read LCKK bit*/ - tmp = GPIOx->LCKR; -} - -/** - * @} - */ - -/** @defgroup GPIO_Group2 GPIO Read and Write - * @brief GPIO Read and Write - * -@verbatim - =============================================================================== - GPIO Read and Write - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Reads the specified input port pin. - * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bit to read. - * This parameter can be GPIO_Pin_x where x can be (0..15). - * @retval The input port pin value. - */ -uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - uint8_t bitstatus = 0x00; - - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); - - if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET) - { - bitstatus = (uint8_t)Bit_SET; - } - else - { - bitstatus = (uint8_t)Bit_RESET; - } - return bitstatus; -} - -/** - * @brief Reads the specified GPIO input data port. - * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. - * @retval GPIO input data port value. - */ -uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - - return ((uint16_t)GPIOx->IDR); -} - -/** - * @brief Reads the specified output data port bit. - * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. - * @param GPIO_Pin: Specifies the port bit to read. - * This parameter can be GPIO_Pin_x where x can be (0..15). - * @retval The output port pin value. - */ -uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - uint8_t bitstatus = 0x00; - - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); - - if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET) - { - bitstatus = (uint8_t)Bit_SET; - } - else - { - bitstatus = (uint8_t)Bit_RESET; - } - return bitstatus; -} - -/** - * @brief Reads the specified GPIO output data port. - * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. - * @retval GPIO output data port value. - */ -uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - - return ((uint16_t)GPIOx->ODR); -} - -/** - * @brief Sets the selected data port bits. - * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bits to be written. - * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). - * @note This functions uses GPIOx_BSRR register to allow atomic read/modify - * accesses. In this way, there is no risk of an IRQ occurring between - * the read and the modify access. - * @retval None - */ -void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GPIO_PIN(GPIO_Pin)); - - GPIOx->BSRRL = GPIO_Pin; -} - -/** - * @brief Clears the selected data port bits. - * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bits to be written. - * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). - * @note This functions uses GPIOx_BSRR register to allow atomic read/modify - * accesses. In this way, there is no risk of an IRQ occurring between - * the read and the modify access. - * @retval None - */ -void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GPIO_PIN(GPIO_Pin)); - - GPIOx->BSRRH = GPIO_Pin; -} - -/** - * @brief Sets or clears the selected data port bit. - * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bit to be written. - * This parameter can be one of GPIO_Pin_x where x can be (0..15). - * @param BitVal: specifies the value to be written to the selected bit. - * This parameter can be one of the BitAction enum values: - * @arg Bit_RESET: to clear the port pin - * @arg Bit_SET: to set the port pin - * @retval None - */ -void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); - assert_param(IS_GPIO_BIT_ACTION(BitVal)); - - if (BitVal != Bit_RESET) - { - GPIOx->BSRRL = GPIO_Pin; - } - else - { - GPIOx->BSRRH = GPIO_Pin ; - } -} - -/** - * @brief Writes data to the specified GPIO data port. - * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. - * @param PortVal: specifies the value to be written to the port output data - * register. - * @retval None - */ -void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - - GPIOx->ODR = PortVal; -} - -/** - * @} - */ - -/** @defgroup GPIO_Group3 GPIO Alternate functions configuration functions - * @brief GPIO Alternate functions configuration functions - * -@verbatim - =============================================================================== - GPIO Alternate functions configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Changes the mapping of the specified pin. - * @param GPIOx: where x can be (A, B, C, D, E or H) to select the GPIO peripheral. - * @param GPIO_PinSource: specifies the pin for the Alternate function. - * This parameter can be GPIO_PinSourcex where x can be (0..15). - * @param GPIO_AFSelection: selects the pin to used as Alternat function. - * This parameter can be one of the following values: - * @arg GPIO_AF_RTC_50Hz: RTC 50/60 Hz synchronization - * @arg GPIO_AF_MCO: Microcontroller clock output - * @arg GPIO_AF_RTC_AF1: Time stamp, Tamper, Alarm A out, Alarm B out, - * 512 Hz clock output (with an LSE oscillator of 32.768 kHz) - * @arg GPIO_AF_WKUP: wakeup - * @arg GPIO_AF_SWJ: SWJ (SW and JTAG) - * @arg GPIO_AF_TRACE - * @arg GPIO_AF_TIM2 - * @arg GPIO_AF_TIM3 - * @arg GPIO_AF_TIM4 - * @arg GPIO_AF_TIM9 - * @arg GPIO_AF_TIM10 - * @arg GPIO_AF_TIM11 - * @arg GPIO_AF_I2C1 - * @arg GPIO_AF_I2C2 - * @arg GPIO_AF_SPI1 - * @arg GPIO_AF_SPI2 - * @arg GPIO_AF_USART1 - * @arg GPIO_AF_USART2 - * @arg GPIO_AF_USART3 - * @arg GPIO_AF_USB - * @arg GPIO_AF_LCD - * @arg GPIO_AF_RI - * @arg GPIO_AF_EVENTOUT: Cortex-M3 EVENTOUT signal - * @note: The pin should already been configured in Alternate Function mode(AF) - * using GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF - * @note: Please refer to the Alternate function mapping table in the device - * datasheet for the detailed mapping of the system and peripherals - * alternate function I/O pins. - * @note: EVENTOUT is not mapped on PH0, PH1 and PH2. - * @retval None - */ -void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF) -{ - uint32_t temp = 0x00; - uint32_t temp_2 = 0x00; - - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource)); - assert_param(IS_GPIO_AF(GPIO_AF)); - - temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ; - GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ; - temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp; - GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_i2c.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_i2c.c deleted file mode 100644 index 763fe88b7..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_i2c.c +++ /dev/null @@ -1,1333 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_i2c.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the Inter-integrated circuit (I2C) - * - Initialization and Configuration - * - Data transfers - * - PEC management - * - DMA transfers management - * - Interrupts, events and flags management - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable peripheral clock using RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2Cx, ENABLE) - * function for I2C1 or I2C2. - * - * 2. Enable SDA, SCL and SMBA (when used) GPIO clocks using - * RCC_AHBPeriphClockCmd() function. - * - * 3. Peripherals alternate function: - * - Connect the pin to the desired peripherals' Alternate - * Function (AF) using GPIO_PinAFConfig() function - * - Configure the desired pin in alternate function by: - * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF - * - Select the type, pull-up/pull-down and output speed via - * GPIO_PuPd, GPIO_OType and GPIO_Speed members - * - Call GPIO_Init() function - * - * 4. Program the Mode, duty cycle , Own address, Ack, Speed and Acknowledged - * Address using the I2C_Init() function. - * - * 5. Optionally you can enable/configure the following parameters without - * re-initialization (i.e there is no need to call again I2C_Init() function): - * - Enable the acknowledge feature using I2C_AcknowledgeConfig() function - * - Enable the dual addressing mode using I2C_DualAddressCmd() function - * - Enable the general call using the I2C_GeneralCallCmd() function - * - Enable the clock stretching using I2C_StretchClockCmd() function - * - Enable the fast mode duty cycle using the I2C_FastModeDutyCycleConfig() - * function - * - Enable the PEC Calculation using I2C_CalculatePEC() function - * - For SMBus Mode: - * - Enable the Address Resolution Protocol (ARP) using I2C_ARPCmd() function - * - Configure the SMBusAlert pin using I2C_SMBusAlertConfig() function - * - * 6. Enable the NVIC and the corresponding interrupt using the function - * I2C_ITConfig() if you need to use interrupt mode. - * - * 7. When using the DMA mode - * - Configure the DMA using DMA_Init() function - * - Active the needed channel Request using I2C_DMACmd() or - I2C_DMALastTransferCmd() function - * - * 8. Enable the I2C using the I2C_Cmd() function. - * - * 9. Enable the DMA using the DMA_Cmd() function when using DMA mode in the - * transfers. - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_i2c.h" -#include "stm32l1xx_rcc.h" - - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup I2C - * @brief I2C driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -#define CR1_CLEAR_MASK ((uint16_t)0xFBF5) /*I2C_ClockSpeed)); - assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode)); - assert_param(IS_I2C_DUTY_CYCLE(I2C_InitStruct->I2C_DutyCycle)); - assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1)); - assert_param(IS_I2C_ACK_STATE(I2C_InitStruct->I2C_Ack)); - assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress)); - -/*---------------------------- I2Cx CR2 Configuration ------------------------*/ - /* Get the I2Cx CR2 value */ - tmpreg = I2Cx->CR2; - /* Clear frequency FREQ[5:0] bits */ - tmpreg &= (uint16_t)~((uint16_t)I2C_CR2_FREQ); - /* Get pclk1 frequency value */ - RCC_GetClocksFreq(&rcc_clocks); - pclk1 = rcc_clocks.PCLK1_Frequency; - /* Set frequency bits depending on pclk1 value */ - freqrange = (uint16_t)(pclk1 / 1000000); - tmpreg |= freqrange; - /* Write to I2Cx CR2 */ - I2Cx->CR2 = tmpreg; - -/*---------------------------- I2Cx CCR Configuration ------------------------*/ - /* Disable the selected I2C peripheral to configure TRISE */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PE); - /* Reset tmpreg value */ - /* Clear F/S, DUTY and CCR[11:0] bits */ - tmpreg = 0; - - /* Configure speed in standard mode */ - if (I2C_InitStruct->I2C_ClockSpeed <= 100000) - { - /* Standard mode speed calculate */ - result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed << 1)); - /* Test if CCR value is under 0x4*/ - if (result < 0x04) - { - /* Set minimum allowed value */ - result = 0x04; - } - /* Set speed value for standard mode */ - tmpreg |= result; - /* Set Maximum Rise Time for standard mode */ - I2Cx->TRISE = freqrange + 1; - } - /* Configure speed in fast mode */ - /* To use the I2C at 400 KHz (in fast mode), the PCLK1 frequency (I2C peripheral - input clock) must be a multiple of 10 MHz */ - else /*(I2C_InitStruct->I2C_ClockSpeed <= 400000)*/ - { - if (I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_2) - { - /* Fast mode speed calculate: Tlow/Thigh = 2 */ - result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 3)); - } - else /*I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_16_9*/ - { - /* Fast mode speed calculate: Tlow/Thigh = 16/9 */ - result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 25)); - /* Set DUTY bit */ - result |= I2C_DutyCycle_16_9; - } - - /* Test if CCR value is under 0x1*/ - if ((result & I2C_CCR_CCR) == 0) - { - /* Set minimum allowed value */ - result |= (uint16_t)0x0001; - } - /* Set speed value and set F/S bit for fast mode */ - tmpreg |= (uint16_t)(result | I2C_CCR_FS); - /* Set Maximum Rise Time for fast mode */ - I2Cx->TRISE = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1); - } - - /* Write to I2Cx CCR */ - I2Cx->CCR = tmpreg; - /* Enable the selected I2C peripheral */ - I2Cx->CR1 |= I2C_CR1_PE; - -/*---------------------------- I2Cx CR1 Configuration ------------------------*/ - /* Get the I2Cx CR1 value */ - tmpreg = I2Cx->CR1; - /* Clear ACK, SMBTYPE and SMBUS bits */ - tmpreg &= CR1_CLEAR_MASK; - /* Configure I2Cx: mode and acknowledgement */ - /* Set SMBTYPE and SMBUS bits according to I2C_Mode value */ - /* Set ACK bit according to I2C_Ack value */ - tmpreg |= (uint16_t)((uint32_t)I2C_InitStruct->I2C_Mode | I2C_InitStruct->I2C_Ack); - /* Write to I2Cx CR1 */ - I2Cx->CR1 = tmpreg; - -/*---------------------------- I2Cx OAR1 Configuration -----------------------*/ - /* Set I2Cx Own Address1 and acknowledged address */ - I2Cx->OAR1 = (I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1); -} - -/** - * @brief Fills each I2C_InitStruct member with its default value. - * @param I2C_InitStruct: pointer to an I2C_InitTypeDef structure which will be initialized. - * @retval None - */ -void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct) -{ -/*---------------- Reset I2C init structure parameters values ----------------*/ - /* initialize the I2C_ClockSpeed member */ - I2C_InitStruct->I2C_ClockSpeed = 5000; - /* Initialize the I2C_Mode member */ - I2C_InitStruct->I2C_Mode = I2C_Mode_I2C; - /* Initialize the I2C_DutyCycle member */ - I2C_InitStruct->I2C_DutyCycle = I2C_DutyCycle_2; - /* Initialize the I2C_OwnAddress1 member */ - I2C_InitStruct->I2C_OwnAddress1 = 0; - /* Initialize the I2C_Ack member */ - I2C_InitStruct->I2C_Ack = I2C_Ack_Disable; - /* Initialize the I2C_AcknowledgedAddress member */ - I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; -} - -/** - * @brief Enables or disables the specified I2C peripheral. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2Cx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C peripheral */ - I2Cx->CR1 |= I2C_CR1_PE; - } - else - { - /* Disable the selected I2C peripheral */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PE); - } -} - -/** - * @brief Generates I2Cx communication START condition. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C START condition generation. - * This parameter can be: ENABLE or DISABLE. - * @retval None. - */ -void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Generate a START condition */ - I2Cx->CR1 |= I2C_CR1_START; - } - else - { - /* Disable the START condition generation */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_START); - } -} - -/** - * @brief Generates I2Cx communication STOP condition. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C STOP condition generation. - * This parameter can be: ENABLE or DISABLE. - * @retval None. - */ -void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Generate a STOP condition */ - I2Cx->CR1 |= I2C_CR1_STOP; - } - else - { - /* Disable the STOP condition generation */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_STOP); - } -} - -/** - * @brief Enables or disables the specified I2C acknowledge feature. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C Acknowledgement. - * This parameter can be: ENABLE or DISABLE. - * @retval None. - */ -void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the acknowledgement */ - I2Cx->CR1 |= I2C_CR1_ACK; - } - else - { - /* Disable the acknowledgement */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ACK); - } -} - -/** - * @brief Configures the specified I2C own address2. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param Address: specifies the 7bit I2C own address2. - * @retval None. - */ -void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address) -{ - uint16_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - - /* Get the old register value */ - tmpreg = I2Cx->OAR2; - - /* Reset I2Cx Own address2 bit [7:1] */ - tmpreg &= (uint16_t)~((uint16_t)I2C_OAR2_ADD2); - - /* Set I2Cx Own address2 */ - tmpreg |= (uint16_t)((uint16_t)Address & (uint16_t)0x00FE); - - /* Store the new register value */ - I2Cx->OAR2 = tmpreg; -} - -/** - * @brief Enables or disables the specified I2C dual addressing mode. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C dual addressing mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable dual addressing mode */ - I2Cx->OAR2 |= I2C_OAR2_ENDUAL; - } - else - { - /* Disable dual addressing mode */ - I2Cx->OAR2 &= (uint16_t)~((uint16_t)I2C_OAR2_ENDUAL); - } -} - -/** - * @brief Enables or disables the specified I2C general call feature. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C General call. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable generall call */ - I2Cx->CR1 |= I2C_CR1_ENGC; - } - else - { - /* Disable generall call */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENGC); - } -} - -/** - * @brief Enables or disables the specified I2C software reset. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C software reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Peripheral under reset */ - I2Cx->CR1 |= I2C_CR1_SWRST; - } - else - { - /* Peripheral not under reset */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_SWRST); - } -} - -/** - * @brief Drives the SMBusAlert pin high or low for the specified I2C. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_SMBusAlert: specifies SMBAlert pin level. - * This parameter can be one of the following values: - * @arg I2C_SMBusAlert_Low: SMBAlert pin driven low - * @arg I2C_SMBusAlert_High: SMBAlert pin driven high - * @retval None - */ -void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_SMBUS_ALERT(I2C_SMBusAlert)); - if (I2C_SMBusAlert == I2C_SMBusAlert_Low) - { - /* Drive the SMBusAlert pin Low */ - I2Cx->CR1 |= I2C_SMBusAlert_Low; - } - else - { - /* Drive the SMBusAlert pin High */ - I2Cx->CR1 &= I2C_SMBusAlert_High; - } -} - -/** - * @brief Enables or disables the specified I2C ARP. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2Cx ARP. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C ARP */ - I2Cx->CR1 |= I2C_CR1_ENARP; - } - else - { - /* Disable the selected I2C ARP */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENARP); - } -} - -/** - * @brief Enables or disables the specified I2C Clock stretching. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2Cx Clock stretching. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState == DISABLE) - { - /* Enable the selected I2C Clock stretching */ - I2Cx->CR1 |= I2C_CR1_NOSTRETCH; - } - else - { - /* Disable the selected I2C Clock stretching */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_NOSTRETCH); - } -} - -/** - * @brief Selects the specified I2C fast mode duty cycle. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_DutyCycle: specifies the fast mode duty cycle. - * This parameter can be one of the following values: - * @arg I2C_DutyCycle_2: I2C fast mode Tlow/Thigh = 2 - * @arg I2C_DutyCycle_16_9: I2C fast mode Tlow/Thigh = 16/9 - * @retval None - */ -void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_DUTY_CYCLE(I2C_DutyCycle)); - if (I2C_DutyCycle != I2C_DutyCycle_16_9) - { - /* I2C fast mode Tlow/Thigh=2 */ - I2Cx->CCR &= I2C_DutyCycle_2; - } - else - { - /* I2C fast mode Tlow/Thigh=16/9 */ - I2Cx->CCR |= I2C_DutyCycle_16_9; - } -} - -/** - * @brief Transmits the address byte to select the slave device. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param Address: specifies the slave address which will be transmitted - * @param I2C_Direction: specifies whether the I2C device will be a - * Transmitter or a Receiver. This parameter can be one of the following values - * @arg I2C_Direction_Transmitter: Transmitter mode - * @arg I2C_Direction_Receiver: Receiver mode - * @retval None. - */ -void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_DIRECTION(I2C_Direction)); - /* Test on the direction to set/reset the read/write bit */ - if (I2C_Direction != I2C_Direction_Transmitter) - { - /* Set the address bit0 for read */ - Address |= I2C_OAR1_ADD0; - } - else - { - /* Reset the address bit0 for write */ - Address &= (uint8_t)~((uint8_t)I2C_OAR1_ADD0); - } - /* Send the address */ - I2Cx->DR = Address; -} - -/** - * @} - */ - -/** @defgroup I2C_Group2 Data transfers functions - * @brief Data transfers functions - * -@verbatim - =============================================================================== - Data transfers functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Sends a data byte through the I2Cx peripheral. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param Data: Byte to be transmitted.. - * @retval None - */ -void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - /* Write in the DR register the data to be sent */ - I2Cx->DR = Data; -} - -/** - * @brief Returns the most recent received data by the I2Cx peripheral. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @retval The value of the received data. - */ -uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - /* Return the data in the DR register */ - return (uint8_t)I2Cx->DR; -} - -/** - * @} - */ - -/** @defgroup I2C_Group3 PEC management functions - * @brief PEC management functions - * -@verbatim - =============================================================================== - PEC management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified I2C PEC transfer. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C PEC transmission. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C PEC transmission */ - I2Cx->CR1 |= I2C_CR1_PEC; - } - else - { - /* Disable the selected I2C PEC transmission */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PEC); - } -} - -/** - * @brief Selects the specified I2C PEC position. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_PECPosition: specifies the PEC position. - * This parameter can be one of the following values: - * @arg I2C_PECPosition_Next: indicates that the next byte is PEC - * @arg I2C_PECPosition_Current: indicates that current byte is PEC - * @retval None - */ -void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_PEC_POSITION(I2C_PECPosition)); - if (I2C_PECPosition == I2C_PECPosition_Next) - { - /* Next byte in shift register is PEC */ - I2Cx->CR1 |= I2C_PECPosition_Next; - } - else - { - /* Current byte in shift register is PEC */ - I2Cx->CR1 &= I2C_PECPosition_Current; - } -} - -/** - * @brief Enables or disables the PEC value calculation of the transferred bytes. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2Cx PEC value calculation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C PEC calculation */ - I2Cx->CR1 |= I2C_CR1_ENPEC; - } - else - { - /* Disable the selected I2C PEC calculation */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENPEC); - } -} - -/** - * @brief Returns the PEC value for the specified I2C. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @retval The PEC value. - */ -uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - /* Return the selected I2C PEC value */ - return ((I2Cx->SR2) >> 8); -} - -/** - * @} - */ - -/** @defgroup I2C_Group4 DMA transfers management functions - * @brief DMA transfers management functions - * -@verbatim - =============================================================================== - DMA transfers management functions - =============================================================================== - This section provides functions allowing to configure the I2C DMA channels - requests. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified I2C DMA requests. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C DMA transfer. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C DMA requests */ - I2Cx->CR2 |= I2C_CR2_DMAEN; - } - else - { - /* Disable the selected I2C DMA requests */ - I2Cx->CR2 &= (uint16_t)~((uint16_t)I2C_CR2_DMAEN); - } -} - -/** - * @brief Specifies that the next DMA transfer is the last one. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param NewState: new state of the I2C DMA last transfer. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Next DMA transfer is the last transfer */ - I2Cx->CR2 |= I2C_CR2_LAST; - } - else - { - /* Next DMA transfer is not the last transfer */ - I2Cx->CR2 &= (uint16_t)~((uint16_t)I2C_CR2_LAST); - } -} - -/** - * @} - */ - -/** @defgroup I2C_Group5 Interrupts events and flags management functions - * @brief Interrupts, events and flags management functions - * -@verbatim - =============================================================================== - Interrupts, events and flags management functions - =============================================================================== - This section provides functions allowing to configure the I2C Interrupts - sources and check or clear the flags or pending bits status. - The user should identify which mode will be used in his application to manage - the communication: Polling mode, Interrupt mode or DMA mode. - - =============================================================================== - I2C State Monitoring Functions - =============================================================================== - This I2C driver provides three different ways for I2C state monitoring - depending on the application requirements and constraints: - - - 1. Basic state monitoring (Using I2C_CheckEvent() function) - ----------------------------------------------------------- - It compares the status registers (SR1 and SR2) content to a given event - (can be the combination of one or more flags). - It returns SUCCESS if the current status includes the given flags - and returns ERROR if one or more flags are missing in the current status. - - - When to use - - This function is suitable for most applications as well as for startup - activity since the events are fully described in the product reference - manual (RM0038). - - It is also suitable for users who need to define their own events. - - - Limitations - - If an error occurs (ie. error flags are set besides to the monitored - flags), the I2C_CheckEvent() function may return SUCCESS despite - the communication hold or corrupted real state. - In this case, it is advised to use error interrupts to monitor - the error events and handle them in the interrupt IRQ handler. - - @note - For error management, it is advised to use the following functions: - - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR). - - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs. - Where x is the peripheral instance (I2C1, I2C2 ...) - - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into the - I2Cx_ER_IRQHandler() function in order to determine which error occurred. - - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd() - and/or I2C_GenerateStop() in order to clear the error flag and source - and return to correct communication status. - - - 2. Advanced state monitoring (Using the function I2C_GetLastEvent()) - -------------------------------------------------------------------- - Using the function I2C_GetLastEvent() which returns the image of both status - registers in a single word (uint32_t) (Status Register 2 value is shifted left - by 16 bits and concatenated to Status Register 1). - - - When to use - - This function is suitable for the same applications above but it - allows to overcome the mentioned limitation of I2C_GetFlagStatus() - function. - - The returned value could be compared to events already defined in - the library (stm32l1xx_i2c.h) or to custom values defined by user. - This function is suitable when multiple flags are monitored at the - same time. - - At the opposite of I2C_CheckEvent() function, this function allows - user to choose when an event is accepted (when all events flags are - set and no other flags are set or just when the needed flags are set - like I2C_CheckEvent() function. - - - Limitations - - User may need to define his own events. - - Same remark concerning the error management is applicable for this - function if user decides to check only regular communication flags - (and ignores error flags). - - - 3. Flag-based state monitoring (Using the function I2C_GetFlagStatus()) - ----------------------------------------------------------------------- - - Using the function I2C_GetFlagStatus() which simply returns the status of - one single flag (ie. I2C_FLAG_RXNE ...). - - - When to use - - This function could be used for specific applications or in debug - phase. - - It is suitable when only one flag checking is needed (most I2C - events are monitored through multiple flags). - - Limitations: - - When calling this function, the Status register is accessed. - Some flags are cleared when the status register is accessed. - So checking the status of one Flag, may clear other ones. - - Function may need to be called twice or more in order to monitor - one single event. - - For detailed description of Events, please refer to section I2C_Events in - stm32l1xx_i2c.h file. - -@endverbatim - * @{ - */ - -/** - * @brief Reads the specified I2C register and returns its value. - * @param I2C_Register: specifies the register to read. - * This parameter can be one of the following values: - * @arg I2C_Register_CR1: CR1 register. - * @arg I2C_Register_CR2: CR2 register. - * @arg I2C_Register_OAR1: OAR1 register. - * @arg I2C_Register_OAR2: OAR2 register. - * @arg I2C_Register_DR: DR register. - * @arg I2C_Register_SR1: SR1 register. - * @arg I2C_Register_SR2: SR2 register. - * @arg I2C_Register_CCR: CCR register. - * @arg I2C_Register_TRISE: TRISE register. - * @retval The value of the read register. - */ -uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_REGISTER(I2C_Register)); - - tmp = (uint32_t) I2Cx; - tmp += I2C_Register; - - /* Return the selected register value */ - return (*(__IO uint16_t *) tmp); -} - -/** - * @brief Enables or disables the specified I2C interrupts. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_IT: specifies the I2C interrupts sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg I2C_IT_BUF: Buffer interrupt mask - * @arg I2C_IT_EVT: Event interrupt mask - * @arg I2C_IT_ERR: Error interrupt mask - * @param NewState: new state of the specified I2C interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_I2C_CONFIG_IT(I2C_IT)); - - if (NewState != DISABLE) - { - /* Enable the selected I2C interrupts */ - I2Cx->CR2 |= I2C_IT; - } - else - { - /* Disable the selected I2C interrupts */ - I2Cx->CR2 &= (uint16_t)~I2C_IT; - } -} - -/** - =============================================================================== - 1. Basic state monitoring - =============================================================================== - */ - -/** - * @brief Checks whether the last I2Cx Event is equal to the one passed - * as parameter. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_EVENT: specifies the event to be checked. - * This parameter can be one of the following values: - * @arg I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED : EV1 - * @arg I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED : EV1 - * @arg I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED : EV1 - * @arg I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED : EV1 - * @arg I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED : EV1 - * @arg I2C_EVENT_SLAVE_BYTE_RECEIVED : EV2 - * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF) : EV2 - * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL) : EV2 - * @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED : EV3 - * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF) : EV3 - * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL) : EV3 - * @arg I2C_EVENT_SLAVE_ACK_FAILURE : EV3_2 - * @arg I2C_EVENT_SLAVE_STOP_DETECTED : EV4 - * @arg I2C_EVENT_MASTER_MODE_SELECT : EV5 - * @arg I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED : EV6 - * @arg I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED : EV6 - * @arg I2C_EVENT_MASTER_BYTE_RECEIVED : EV7 - * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTING : EV8 - * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTED : EV8_2 - * @arg I2C_EVENT_MASTER_MODE_ADDRESS10 : EV9 - * - * @note: For detailed description of Events, please refer to section - * I2C_Events in stm32l1xx_i2c.h file. - * - * @retval An ErrorStatus enumeration value: - * - SUCCESS: Last event is equal to the I2C_EVENT - * - ERROR: Last event is different from the I2C_EVENT - */ -ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) -{ - uint32_t lastevent = 0; - uint32_t flag1 = 0, flag2 = 0; - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_EVENT(I2C_EVENT)); - - /* Read the I2Cx status register */ - flag1 = I2Cx->SR1; - flag2 = I2Cx->SR2; - flag2 = flag2 << 16; - - /* Get the last event value from I2C status register */ - lastevent = (flag1 | flag2) & FLAG_MASK; - - /* Check whether the last event contains the I2C_EVENT */ - if ((lastevent & I2C_EVENT) == I2C_EVENT) - { - /* SUCCESS: last event is equal to I2C_EVENT */ - status = SUCCESS; - } - else - { - /* ERROR: last event is different from I2C_EVENT */ - status = ERROR; - } - /* Return status */ - return status; -} - -/** - =============================================================================== - 2. Advanced state monitoring - =============================================================================== - */ - -/** - * @brief Returns the last I2Cx Event. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * - * @note: For detailed description of Events, please refer to section - * I2C_Events in stm32l1xx_i2c.h file. - * - * @retval The last event - */ -uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx) -{ - uint32_t lastevent = 0; - uint32_t flag1 = 0, flag2 = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - - /* Read the I2Cx status register */ - flag1 = I2Cx->SR1; - flag2 = I2Cx->SR2; - flag2 = flag2 << 16; - - /* Get the last event value from I2C status register */ - lastevent = (flag1 | flag2) & FLAG_MASK; - - /* Return status */ - return lastevent; -} - -/** - =============================================================================== - 3. Flag-based state monitoring - =============================================================================== - */ - -/** - * @brief Checks whether the specified I2C flag is set or not. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg I2C_FLAG_DUALF: Dual flag (Slave mode) - * @arg I2C_FLAG_SMBHOST: SMBus host header (Slave mode) - * @arg I2C_FLAG_SMBDEFAULT: SMBus default header (Slave mode) - * @arg I2C_FLAG_GENCALL: General call header flag (Slave mode) - * @arg I2C_FLAG_TRA: Transmitter/Receiver flag - * @arg I2C_FLAG_BUSY: Bus busy flag - * @arg I2C_FLAG_MSL: Master/Slave flag - * @arg I2C_FLAG_SMBALERT: SMBus Alert flag - * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag - * @arg I2C_FLAG_PECERR: PEC error in reception flag - * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) - * @arg I2C_FLAG_AF: Acknowledge failure flag - * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) - * @arg I2C_FLAG_BERR: Bus error flag - * @arg I2C_FLAG_TXE: Data register empty flag (Transmitter) - * @arg I2C_FLAG_RXNE: Data register not empty (Receiver) flag - * @arg I2C_FLAG_STOPF: Stop detection flag (Slave mode) - * @arg I2C_FLAG_ADD10: 10-bit header sent flag (Master mode) - * @arg I2C_FLAG_BTF: Byte transfer finished flag - * @arg I2C_FLAG_ADDR: Address sent flag (Master mode) ADSL - * Address matched flag (Slave mode)ENDAD - * @arg I2C_FLAG_SB: Start bit flag (Master mode) - * @retval The new state of I2C_FLAG (SET or RESET). - */ -FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) -{ - FlagStatus bitstatus = RESET; - __IO uint32_t i2creg = 0, i2cxbase = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_GET_FLAG(I2C_FLAG)); - - /* Get the I2Cx peripheral base address */ - i2cxbase = (uint32_t)I2Cx; - - /* Read flag register index */ - i2creg = I2C_FLAG >> 28; - - /* Get bit[23:0] of the flag */ - I2C_FLAG &= FLAG_MASK; - - if(i2creg != 0) - { - /* Get the I2Cx SR1 register address */ - i2cxbase += 0x14; - } - else - { - /* Flag in I2Cx SR2 Register */ - I2C_FLAG = (uint32_t)(I2C_FLAG >> 16); - /* Get the I2Cx SR2 register address */ - i2cxbase += 0x18; - } - - if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET) - { - /* I2C_FLAG is set */ - bitstatus = SET; - } - else - { - /* I2C_FLAG is reset */ - bitstatus = RESET; - } - - /* Return the I2C_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the I2Cx's pending flags. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg I2C_FLAG_SMBALERT: SMBus Alert flag - * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag - * @arg I2C_FLAG_PECERR: PEC error in reception flag - * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) - * @arg I2C_FLAG_AF: Acknowledge failure flag - * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) - * @arg I2C_FLAG_BERR: Bus error flag - * - * @note - * - STOPF (STOP detection) is cleared by software sequence: a read operation - * to I2C_SR1 register (I2C_GetFlagStatus()) followed by a write operation - * to I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral). - * - ADD10 (10-bit header sent) is cleared by software sequence: a read - * operation to I2C_SR1 (I2C_GetFlagStatus()) followed by writing the - * second byte of the address in DR register. - * - BTF (Byte Transfer Finished) is cleared by software sequence: a read - * operation to I2C_SR1 register (I2C_GetFlagStatus()) followed by a - * read/write to I2C_DR register (I2C_SendData()). - * - ADDR (Address sent) is cleared by software sequence: a read operation to - * I2C_SR1 register (I2C_GetFlagStatus()) followed by a read operation to - * I2C_SR2 register ((void)(I2Cx->SR2)). - * - SB (Start Bit) is cleared software sequence: a read operation to I2C_SR1 - * register (I2C_GetFlagStatus()) followed by a write operation to I2C_DR - * register (I2C_SendData()). - * @retval None - */ -void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) -{ - uint32_t flagpos = 0; - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_CLEAR_FLAG(I2C_FLAG)); - /* Get the I2C flag position */ - flagpos = I2C_FLAG & FLAG_MASK; - /* Clear the selected I2C flag */ - I2Cx->SR1 = (uint16_t)~flagpos; -} - -/** - * @brief Checks whether the specified I2C interrupt has occurred or not. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_IT: specifies the interrupt source to check. - * This parameter can be one of the following values: - * @arg I2C_IT_SMBALERT: SMBus Alert flag - * @arg I2C_IT_TIMEOUT: Timeout or Tlow error flag - * @arg I2C_IT_PECERR: PEC error in reception flag - * @arg I2C_IT_OVR: Overrun/Underrun flag (Slave mode) - * @arg I2C_IT_AF: Acknowledge failure flag - * @arg I2C_IT_ARLO: Arbitration lost flag (Master mode) - * @arg I2C_IT_BERR: Bus error flag - * @arg I2C_IT_TXE: Data register empty flag (Transmitter) - * @arg I2C_IT_RXNE: Data register not empty (Receiver) flag - * @arg I2C_IT_STOPF: Stop detection flag (Slave mode) - * @arg I2C_IT_ADD10: 10-bit header sent flag (Master mode) - * @arg I2C_IT_BTF: Byte transfer finished flag - * @arg I2C_IT_ADDR: Address sent flag (Master mode) ADSL - * Address matched flag (Slave mode)ENDAD - * @arg I2C_IT_SB: Start bit flag (Master mode) - * @retval The new state of I2C_IT (SET or RESET). - */ -ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT) -{ - ITStatus bitstatus = RESET; - uint32_t enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_GET_IT(I2C_IT)); - - /* Check if the interrupt source is enabled or not */ - enablestatus = (uint32_t)(((I2C_IT & ITEN_MASK) >> 16) & (I2Cx->CR2)) ; - - /* Get bit[23:0] of the flag */ - I2C_IT &= FLAG_MASK; - - /* Check the status of the specified I2C flag */ - if (((I2Cx->SR1 & I2C_IT) != (uint32_t)RESET) && enablestatus) - { - /* I2C_IT is set */ - bitstatus = SET; - } - else - { - /* I2C_IT is reset */ - bitstatus = RESET; - } - /* Return the I2C_IT status */ - return bitstatus; -} - -/** - * @brief Clears the I2Cxs interrupt pending bits. - * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. - * @param I2C_IT: specifies the interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg I2C_IT_SMBALERT: SMBus Alert interrupt - * @arg I2C_IT_TIMEOUT: Timeout or Tlow error interrupt - * @arg I2C_IT_PECERR: PEC error in reception interrupt - * @arg I2C_IT_OVR: Overrun/Underrun interrupt (Slave mode) - * @arg I2C_IT_AF: Acknowledge failure interrupt - * @arg I2C_IT_ARLO: Arbitration lost interrupt (Master mode) - * @arg I2C_IT_BERR: Bus error interrupt - * - * @note - * - STOPF (STOP detection) is cleared by software sequence: a read operation - * to I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to - * I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral). - * - ADD10 (10-bit header sent) is cleared by software sequence: a read - * operation to I2C_SR1 (I2C_GetITStatus()) followed by writing the second - * byte of the address in I2C_DR register. - * - BTF (Byte Transfer Finished) is cleared by software sequence: a read - * operation to I2C_SR1 register (I2C_GetITStatus()) followed by a - * read/write to I2C_DR register (I2C_SendData()). - * - ADDR (Address sent) is cleared by software sequence: a read operation to - * I2C_SR1 register (I2C_GetITStatus()) followed by a read operation to - * I2C_SR2 register ((void)(I2Cx->SR2)). - * - SB (Start Bit) is cleared by software sequence: a read operation to - * I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to - * I2C_DR register (I2C_SendData()). - * @retval None - */ -void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT) -{ - uint32_t flagpos = 0; - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_CLEAR_IT(I2C_IT)); - /* Get the I2C flag position */ - flagpos = I2C_IT & FLAG_MASK; - /* Clear the selected I2C flag */ - I2Cx->SR1 = (uint16_t)~flagpos; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ - - - diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_iwdg.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_iwdg.c deleted file mode 100644 index d9e1028c3..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_iwdg.c +++ /dev/null @@ -1,263 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_iwdg.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the Independent watchdog (IWDG) peripheral: - * - Prescaler and Counter configuration - * - IWDG activation - * - Flag management - * - * @verbatim - * - * =================================================================== - * IWDG features - * =================================================================== - * - * The IWDG can be started by either software or hardware (configurable - * through option byte). - * - * The IWDG is clocked by its own dedicated low-speed clock (LSI) and - * thus stays active even if the main clock fails. - * Once the IWDG is started, the LSI is forced ON and cannot be disabled - * (LSI cannot be disabled too), and the counter starts counting down from - * the reset value of 0xFFF. When it reaches the end of count value (0x000) - * a system reset is generated. - * The IWDG counter should be reloaded at regular intervals to prevent - * an MCU reset. - * - * The IWDG is implemented in the VDD voltage domain that is still functional - * in STOP and STANDBY mode (IWDG reset can wake-up from STANDBY) - * - * IWDGRST flag in RCC_CSR register can be used to inform when a IWDG - * reset occurs - * - * Min-max timeout value @37KHz (LSI): ~108us / ~28.3s - * The IWDG timeout may vary due to LSI frequency dispersion. STM32L1xx - * devices provide the capability to measure the LSI frequency (LSI clock - * connected internally to TIM10 CH1 input capture). The measured value - * can be used to have an IWDG timeout with an acceptable accuracy. - * For more information, please refer to the STM32L1xx Reference manual - * - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable write access to IWDG_PR and IWDG_RLR registers using - * IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable) function - * - * 2. Configure the IWDG prescaler using IWDG_SetPrescaler() function - * - * 3. Configure the IWDG counter value using IWDG_SetReload() function. - * This value will be loaded in the IWDG counter each time the counter - * is reloaded, then the IWDG will start counting down from this value. - * - * 4. Start the IWDG using IWDG_Enable() function, when the IWDG is used - * in software mode (no need to enable the LSI, it will be enabled - * by hardware) - * - * 5. Then the application program must reload the IWDG counter at regular - * intervals during normal operation to prevent an MCU reset, using - * IWDG_ReloadCounter() function. - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_iwdg.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup IWDG - * @brief IWDG driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* ---------------------- IWDG registers bit mask ----------------------------*/ -/* KR register bit mask */ -#define KR_KEY_RELOAD ((uint16_t)0xAAAA) -#define KR_KEY_ENABLE ((uint16_t)0xCCCC) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup IWDG_Private_Functions - * @{ - */ - -/** @defgroup IWDG_Group1 Prescaler and Counter configuration functions - * @brief Prescaler and Counter configuration functions - * -@verbatim - =============================================================================== - Prescaler and Counter configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables write access to IWDG_PR and IWDG_RLR registers. - * @param IWDG_WriteAccess: new state of write access to IWDG_PR and IWDG_RLR registers. - * This parameter can be one of the following values: - * @arg IWDG_WriteAccess_Enable: Enable write access to IWDG_PR and IWDG_RLR registers - * @arg IWDG_WriteAccess_Disable: Disable write access to IWDG_PR and IWDG_RLR registers - * @retval None - */ -void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess) -{ - /* Check the parameters */ - assert_param(IS_IWDG_WRITE_ACCESS(IWDG_WriteAccess)); - IWDG->KR = IWDG_WriteAccess; -} - -/** - * @brief Sets IWDG Prescaler value. - * @param IWDG_Prescaler: specifies the IWDG Prescaler value. - * This parameter can be one of the following values: - * @arg IWDG_Prescaler_4: IWDG prescaler set to 4 - * @arg IWDG_Prescaler_8: IWDG prescaler set to 8 - * @arg IWDG_Prescaler_16: IWDG prescaler set to 16 - * @arg IWDG_Prescaler_32: IWDG prescaler set to 32 - * @arg IWDG_Prescaler_64: IWDG prescaler set to 64 - * @arg IWDG_Prescaler_128: IWDG prescaler set to 128 - * @arg IWDG_Prescaler_256: IWDG prescaler set to 256 - * @retval None - */ -void IWDG_SetPrescaler(uint8_t IWDG_Prescaler) -{ - /* Check the parameters */ - assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler)); - IWDG->PR = IWDG_Prescaler; -} - -/** - * @brief Sets IWDG Reload value. - * @param Reload: specifies the IWDG Reload value. - * This parameter must be a number between 0 and 0x0FFF. - * @retval None - */ -void IWDG_SetReload(uint16_t Reload) -{ - /* Check the parameters */ - assert_param(IS_IWDG_RELOAD(Reload)); - IWDG->RLR = Reload; -} - -/** - * @brief Reloads IWDG counter with value defined in the reload register - * (write access to IWDG_PR and IWDG_RLR registers disabled). - * @param None - * @retval None - */ -void IWDG_ReloadCounter(void) -{ - IWDG->KR = KR_KEY_RELOAD; -} - -/** - * @} - */ - -/** @defgroup IWDG_Group2 IWDG activation function - * @brief IWDG activation function - * -@verbatim - =============================================================================== - IWDG activation function - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables IWDG (write access to IWDG_PR and IWDG_RLR registers disabled). - * @param None - * @retval None - */ -void IWDG_Enable(void) -{ - IWDG->KR = KR_KEY_ENABLE; -} - -/** - * @} - */ - -/** @defgroup IWDG_Group3 Flag management function - * @brief Flag management function - * -@verbatim - =============================================================================== - Flag management function - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Checks whether the specified IWDG flag is set or not. - * @param IWDG_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg IWDG_FLAG_PVU: Prescaler Value Update on going - * @arg IWDG_FLAG_RVU: Reload Value Update on going - * @retval The new state of IWDG_FLAG (SET or RESET). - */ -FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_IWDG_FLAG(IWDG_FLAG)); - if ((IWDG->SR & IWDG_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the flag status */ - return bitstatus; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_lcd.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_lcd.c deleted file mode 100644 index 9116b6881..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_lcd.c +++ /dev/null @@ -1,637 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_lcd.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the LCD controller (LCD) peripheral: - * - Initialization and configuration - * - LCD RAM memory write - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * LCD Clock - * =================================================================== - * LCDCLK is the same as RTCCLK. - * To configure the RTCCLK/LCDCLK, proceed as follows: - * - Enable the Power Controller (PWR) APB1 interface clock using the - * RCC_APB1PeriphClockCmd() function. - * - Enable access to RTC domain using the PWR_RTCAccessCmd() function. - * - Select the RTC clock source using the RCC_RTCCLKConfig() function. - * - * The frequency generator allows you to achieve various LCD frame rates - * starting from an LCD input clock frequency (LCDCLK) which can vary - * from 32 kHz up to 1 MHz. - * - * =================================================================== - * LCD and low power modes - * =================================================================== - * The LCD still active during STOP mode. - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable LCD clock using RCC_APB1PeriphClockCmd(RCC_APB1Periph_LCD, ENABLE) function - * - * 2. Configure the LCD prescaler, divider, duty, bias and voltage source - * using LCD_Init() function - * - * 3. Optionally you can enable/configure: - * - LCD High Drive using the LCD_HighDriveCmd() function - * - LCD High Drive using the LCD_MuxSegmentCmd() function - * - LCD Pulse ON Duration using the LCD_PulseOnDurationConfig() function - * - LCD Dead Time using the LCD_DeadTimeConfig() function - * - The LCD Blink mode and frequency using the LCD_BlinkConfig() function - * - The LCD Contrast using the LCD_ContrastConfig() function - * - * 4. Call the LCD_WaitForSynchro() function to wait for LCD_FCR register - * synchronization. - * - * 5. Call the LCD_Cmd() to enable the LCD controller - * - * 6. Wait until the LCD Controller status is enabled and the step-up - * converter is ready using the LCD_GetFlagStatus() and - * LCD_FLAG_ENS and LCD_FLAG_RDY flags. - * - * 7. Write to the LCD RAM memory using the LCD_Write() function. - * - * 8. Request an update display using the LCD_UpdateDisplayRequest() - * function. - * - * 9. Wait until the update display is finished by checking the UDD - * flag status using the LCD_GetFlagStatus(LCD_FLAG_UDD) - * - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_lcd.h" -#include "stm32l1xx_rcc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup LCD - * @brief LCD driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* ------------ LCD registers bit address in the alias region --------------- */ -#define LCD_OFFSET (LCD_BASE - PERIPH_BASE) - -/* --- CR Register ---*/ - -/* Alias word address of LCDEN bit */ -#define CR_OFFSET (LCD_OFFSET + 0x00) -#define LCDEN_BitNumber 0x00 -#define CR_LCDEN_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (LCDEN_BitNumber * 4)) - -/* Alias word address of MUX_SEG bit */ -#define MUX_SEG_BitNumber 0x07 -#define CR_MUX_SEG_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (MUX_SEG_BitNumber * 4)) - - -/* --- FCR Register ---*/ - -/* Alias word address of HD bit */ -#define FCR_OFFSET (LCD_OFFSET + 0x04) -#define HD_BitNumber 0x00 -#define FCR_HD_BB (PERIPH_BB_BASE + (FCR_OFFSET * 32) + (HD_BitNumber * 4)) - -/* --- SR Register ---*/ - -/* Alias word address of UDR bit */ -#define SR_OFFSET (LCD_OFFSET + 0x08) -#define UDR_BitNumber 0x02 -#define SR_UDR_BB (PERIPH_BB_BASE + (SR_OFFSET * 32) + (UDR_BitNumber * 4)) - -#define FCR_MASK ((uint32_t)0xFC03FFFF) /* LCD FCR Mask */ -#define CR_MASK ((uint32_t)0xFFFFFF81) /* LCD CR Mask */ -#define PON_MASK ((uint32_t)0xFFFFFF8F) /* LCD PON Mask */ -#define DEAD_MASK ((uint32_t)0xFFFFFC7F) /* LCD DEAD Mask */ -#define BLINK_MASK ((uint32_t)0xFFFC1FFF) /* LCD BLINK Mask */ -#define CONTRAST_MASK ((uint32_t)0xFFFFE3FF) /* LCD CONTRAST Mask */ - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup LCD_Private_Functions - * @{ - */ - -/** @defgroup LCD_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the LCD peripheral registers to their default reset - * values. - * @param None - * @retval None - */ -void LCD_DeInit(void) -{ - /* Enable LCD reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_LCD, ENABLE); - /* Release LCD from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_LCD, DISABLE); -} - -/** - * @brief Initializes the LCD peripheral according to the specified parameters - * in the LCD_InitStruct. - * @note This function can be used only when the LCD is disabled. - * @param LCD_InitStruct: pointer to a LCD_InitTypeDef structure that contains - * the configuration information for the specified LCD peripheral. - * @retval None - */ -void LCD_Init(LCD_InitTypeDef* LCD_InitStruct) -{ - /* Check function parameters */ - assert_param(IS_LCD_PRESCALER(LCD_InitStruct->LCD_Prescaler)); - assert_param(IS_LCD_DIVIDER(LCD_InitStruct->LCD_Divider)); - assert_param(IS_LCD_DUTY(LCD_InitStruct->LCD_Duty)); - assert_param(IS_LCD_BIAS(LCD_InitStruct->LCD_Bias)); - assert_param(IS_LCD_VOLTAGE_SOURCE(LCD_InitStruct->LCD_VoltageSource)); - - LCD->FCR &= (uint32_t)FCR_MASK; - LCD->FCR |= (uint32_t)(LCD_InitStruct->LCD_Prescaler | LCD_InitStruct->LCD_Divider); - - LCD_WaitForSynchro(); - - LCD->CR &= (uint32_t)CR_MASK; - LCD->CR |= (uint32_t)(LCD_InitStruct->LCD_Duty | LCD_InitStruct->LCD_Bias | \ - LCD_InitStruct->LCD_VoltageSource); - -} - -/** - * @brief Fills each LCD_InitStruct member with its default value. - * @param LCD_InitStruct: pointer to a LCD_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void LCD_StructInit(LCD_InitTypeDef* LCD_InitStruct) -{ -/*--------------- Reset LCD init structure parameters values -----------------*/ - LCD_InitStruct->LCD_Prescaler = LCD_Prescaler_1; /*!< Initialize the LCD_Prescaler member */ - - LCD_InitStruct->LCD_Divider = LCD_Divider_16; /*!< Initialize the LCD_Divider member */ - - LCD_InitStruct->LCD_Duty = LCD_Duty_Static; /*!< Initialize the LCD_Duty member */ - - LCD_InitStruct->LCD_Bias = LCD_Bias_1_4; /*!< Initialize the LCD_Bias member */ - - LCD_InitStruct->LCD_VoltageSource = LCD_VoltageSource_Internal; /*!< Initialize the LCD_VoltageSource member */ -} - -/** - * @brief Enables or disables the LCD Controller. - * @param NewState: new state of the LCD peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void LCD_Cmd(FunctionalState NewState) -{ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_LCDEN_BB = (uint32_t)NewState; -} - -/** - * @brief Waits until the LCD FCR register is synchronized in the LCDCLK domain. - * This function must be called after any write operation to LCD_FCR register. - * @param None - * @retval None - */ -void LCD_WaitForSynchro(void) -{ - /* Loop until FCRSF flag is set */ - while ((LCD->SR & LCD_FLAG_FCRSF) == (uint32_t)RESET) - { - } -} - -/** - * @brief Enables or disables the low resistance divider. Displays with high - * internal resistance may need a longer drive time to achieve - * satisfactory contrast. This function is useful in this case if some - * additional power consumption can be tolerated. - * @note When this mode is enabled, the PulseOn Duration (PON) have to be - * programmed to 1/CK_PS (LCD_PulseOnDuration_1). - * @param NewState: new state of the low resistance divider. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void LCD_HighDriveCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) FCR_HD_BB = (uint32_t)NewState; -} - -/** - * @brief Enables or disables the Mux Segment. - * @note This function can be used only when the LCD is disabled. - * @param NewState: new state of the Mux Segment. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void LCD_MuxSegmentCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_MUX_SEG_BB = (uint32_t)NewState; -} - -/** - * @brief Configures the LCD pulses on duration. - * @param LCD_PulseOnDuration: specifies the LCD pulse on duration in terms of - * CK_PS (prescaled LCD clock period) pulses. - * This parameter can be one of the following values: - * @arg LCD_PulseOnDuration_0: 0 pulse - * @arg LCD_PulseOnDuration_1: Pulse ON duration = 1/CK_PS - * @arg LCD_PulseOnDuration_2: Pulse ON duration = 2/CK_PS - * @arg LCD_PulseOnDuration_3: Pulse ON duration = 3/CK_PS - * @arg LCD_PulseOnDuration_4: Pulse ON duration = 4/CK_PS - * @arg LCD_PulseOnDuration_5: Pulse ON duration = 5/CK_PS - * @arg LCD_PulseOnDuration_6: Pulse ON duration = 6/CK_PS - * @arg LCD_PulseOnDuration_7: Pulse ON duration = 7/CK_PS - * @retval None - */ -void LCD_PulseOnDurationConfig(uint32_t LCD_PulseOnDuration) -{ - /* Check the parameters */ - assert_param(IS_LCD_PULSE_ON_DURATION(LCD_PulseOnDuration)); - - LCD->FCR &= (uint32_t)PON_MASK; - LCD->FCR |= (uint32_t)(LCD_PulseOnDuration); -} - -/** - * @brief Configures the LCD dead time. - * @param LCD_DeadTime: specifies the LCD dead time. - * This parameter can be one of the following values: - * @arg LCD_DeadTime_0: No dead Time - * @arg LCD_DeadTime_1: One Phase between different couple of Frame - * @arg LCD_DeadTime_2: Two Phase between different couple of Frame - * @arg LCD_DeadTime_3: Three Phase between different couple of Frame - * @arg LCD_DeadTime_4: Four Phase between different couple of Frame - * @arg LCD_DeadTime_5: Five Phase between different couple of Frame - * @arg LCD_DeadTime_6: Six Phase between different couple of Frame - * @arg LCD_DeadTime_7: Seven Phase between different couple of Frame - * @retval None - */ -void LCD_DeadTimeConfig(uint32_t LCD_DeadTime) -{ - /* Check the parameters */ - assert_param(IS_LCD_DEAD_TIME(LCD_DeadTime)); - - LCD->FCR &= (uint32_t)DEAD_MASK; - LCD->FCR |= (uint32_t)(LCD_DeadTime); -} - -/** - * @brief Configures the LCD Blink mode and Blink frequency. - * @param LCD_BlinkMode: specifies the LCD blink mode. - * This parameter can be one of the following values: - * @arg LCD_BlinkMode_Off: Blink disabled - * @arg LCD_BlinkMode_SEG0_COM0: Blink enabled on SEG[0], COM[0] (1 pixel) - * @arg LCD_BlinkMode_SEG0_AllCOM: Blink enabled on SEG[0], all COM (up to 8 - * pixels according to the programmed duty) - * @arg LCD_BlinkMode_AllSEG_AllCOM: Blink enabled on all SEG and all COM - * (all pixels) - * @param LCD_BlinkFrequency: specifies the LCD blink frequency. - * This parameter can be one of the following values: - * @arg LCD_BlinkFrequency_Div8: The Blink frequency = fLcd/8 - * @arg LCD_BlinkFrequency_Div16: The Blink frequency = fLcd/16 - * @arg LCD_BlinkFrequency_Div32: The Blink frequency = fLcd/32 - * @arg LCD_BlinkFrequency_Div64: The Blink frequency = fLcd/64 - * @arg LCD_BlinkFrequency_Div128: The Blink frequency = fLcd/128 - * @arg LCD_BlinkFrequency_Div256: The Blink frequency = fLcd/256 - * @arg LCD_BlinkFrequency_Div512: The Blink frequency = fLcd/512 - * @arg LCD_BlinkFrequency_Div1024: The Blink frequency = fLcd/1024 - * @retval None - */ -void LCD_BlinkConfig(uint32_t LCD_BlinkMode, uint32_t LCD_BlinkFrequency) -{ - /* Check the parameters */ - assert_param(IS_LCD_BLINK_MODE(LCD_BlinkMode)); - assert_param(IS_LCD_BLINK_FREQUENCY(LCD_BlinkFrequency)); - - LCD->FCR &= (uint32_t)BLINK_MASK; - LCD->FCR |= (uint32_t)(LCD_BlinkMode | LCD_BlinkFrequency); -} - -/** - * @brief Configures the LCD Contrast. - * @param LCD_Contrast: specifies the LCD Contrast. - * This parameter can be one of the following values: - * @arg LCD_Contrast_Level_0: Maximum Voltage = 2.60V - * @arg LCD_Contrast_Level_1: Maximum Voltage = 2.73V - * @arg LCD_Contrast_Level_2: Maximum Voltage = 2.86V - * @arg LCD_Contrast_Level_3: Maximum Voltage = 2.99V - * @arg LCD_Contrast_Level_4: Maximum Voltage = 3.12V - * @arg LCD_Contrast_Level_5: Maximum Voltage = 3.25V - * @arg LCD_Contrast_Level_6: Maximum Voltage = 3.38V - * @arg LCD_Contrast_Level_7: Maximum Voltage = 3.51V - * @retval None - */ -void LCD_ContrastConfig(uint32_t LCD_Contrast) -{ - /* Check the parameters */ - assert_param(IS_LCD_CONTRAST(LCD_Contrast)); - - LCD->FCR &= (uint32_t)CONTRAST_MASK; - LCD->FCR |= (uint32_t)(LCD_Contrast); -} - -/** - * @} - */ - -/** @defgroup LCD_Group2 LCD RAM memory write functions - * @brief LCD RAM memory write functions - * -@verbatim - =============================================================================== - LCD RAM memory write functions - =============================================================================== - - Using its double buffer memory the LCD controller ensures the coherency of the - displayed information without having to use interrupts to control LCD_RAM - modification. - The application software can access the first buffer level (LCD_RAM) through - the APB interface. Once it has modified the LCD_RAM, it sets the UDR flag in - the LCD_SR register using the LCD_UpdateDisplayRequest() function. - This UDR flag (update display request) requests the updated information to be - moved into the second buffer level (LCD_DISPLAY). - This operation is done synchronously with the frame (at the beginning of the - next frame), until the update is completed, the LCD_RAM is write protected and - the UDR flag stays high. - Once the update is completed another flag (UDD - Update Display Done) is set and - generates an interrupt if the UDDIE bit in the LCD_FCR register is set. - The time it takes to update LCD_DISPLAY is, in the worst case, one odd and one - even frame. - The update will not occur (UDR = 1 and UDD = 0) until the display is - enabled (LCDEN = 1). - -@endverbatim - * @{ - */ - -/** - * @brief Writes a word in the specific LCD RAM. - * @param LCD_RAMRegister: specifies the LCD Contrast. - * This parameter can be one of the following values: - * @arg LCD_RAMRegister_0: LCD RAM Register 0 - * @arg LCD_RAMRegister_1: LCD RAM Register 1 - * @arg LCD_RAMRegister_2: LCD RAM Register 2 - * @arg LCD_RAMRegister_3: LCD RAM Register 3 - * @arg LCD_RAMRegister_4: LCD RAM Register 4 - * @arg LCD_RAMRegister_5: LCD RAM Register 5 - * @arg LCD_RAMRegister_6: LCD RAM Register 6 - * @arg LCD_RAMRegister_7: LCD RAM Register 7 - * @arg LCD_RAMRegister_8: LCD RAM Register 8 - * @arg LCD_RAMRegister_9: LCD RAM Register 9 - * @arg LCD_RAMRegister_10: LCD RAM Register 10 - * @arg LCD_RAMRegister_11: LCD RAM Register 11 - * @arg LCD_RAMRegister_12: LCD RAM Register 12 - * @arg LCD_RAMRegister_13: LCD RAM Register 13 - * @arg LCD_RAMRegister_14: LCD RAM Register 14 - * @arg LCD_RAMRegister_15: LCD RAM Register 15 - * @param LCD_Data: specifies LCD Data Value to be written. - * @retval None - */ -void LCD_Write(uint32_t LCD_RAMRegister, uint32_t LCD_Data) -{ - /* Check the parameters */ - assert_param(IS_LCD_RAM_REGISTER(LCD_RAMRegister)); - - /* Copy data bytes to RAM register */ - LCD->RAM[LCD_RAMRegister] = (uint32_t)LCD_Data; -} - -/** - * @brief Enables the Update Display Request. - * @note Each time software modifies the LCD_RAM it must set the UDR bit to - * transfer the updated data to the second level buffer. - * The UDR bit stays set until the end of the update and during this - * time the LCD_RAM is write protected. - * @note When the display is disabled, the update is performed for all - * LCD_DISPLAY locations. - * When the display is enabled, the update is performed only for locations - * for which commons are active (depending on DUTY). For example if - * DUTY = 1/2, only the LCD_DISPLAY of COM0 and COM1 will be updated. - * @param None - * @retval None - */ -void LCD_UpdateDisplayRequest(void) -{ - *(__IO uint32_t *) SR_UDR_BB = (uint32_t)0x01; -} - -/** - * @} - */ - -/** @defgroup LCD_Group3 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified LCD interrupts. - * @param LCD_IT: specifies the LCD interrupts sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg LCD_IT_SOF: Start of Frame Interrupt - * @arg LCD_IT_UDD: Update Display Done Interrupt - * @param NewState: new state of the specified LCD interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void LCD_ITConfig(uint32_t LCD_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_LCD_IT(LCD_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - LCD->FCR |= LCD_IT; - } - else - { - LCD->FCR &= (uint32_t)~LCD_IT; - } -} - -/** - * @brief Checks whether the specified LCD flag is set or not. - * @param LCD_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg LCD_FLAG_ENS: LCD Enabled flag. It indicates the LCD controller status. - * @note The ENS bit is set immediately when the LCDEN bit in the LCD_CR - * goes from 0 to 1. On deactivation it reflects the real status of - * LCD so it becomes 0 at the end of the last displayed frame. - * @arg LCD_FLAG_SOF: Start of Frame flag. This flag is set by hardware at - * the beginning of a new frame, at the same time as the display data is - * updated. - * @arg LCD_FLAG_UDR: Update Display Request flag. - * @arg LCD_FLAG_UDD: Update Display Done flag. - * @arg LCD_FLAG_RDY: Step_up converter Ready flag. It indicates the status - * of the step-up converter. - * @arg LCD_FLAG_FCRSF: LCD Frame Control Register Synchronization Flag. - * This flag is set by hardware each time the LCD_FCR register is updated - * in the LCDCLK domain. - * @retval The new state of LCD_FLAG (SET or RESET). - */ -FlagStatus LCD_GetFlagStatus(uint32_t LCD_FLAG) -{ - FlagStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_LCD_GET_FLAG(LCD_FLAG)); - - if ((LCD->SR & LCD_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the LCD's pending flags. - * @param LCD_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg LCD_FLAG_SOF: Start of Frame Interrupt - * @arg LCD_FLAG_UDD: Update Display Done Interrupt - * @retval None - */ -void LCD_ClearFlag(uint32_t LCD_FLAG) -{ - /* Check the parameters */ - assert_param(IS_LCD_CLEAR_FLAG(LCD_FLAG)); - - /* Clear the corresponding LCD flag */ - LCD->CLR = (uint32_t)LCD_FLAG; -} - -/** - * @brief Checks whether the specified RTC interrupt has occurred or not. - * @param RTC_IT: specifies the RTC interrupts sources to check. - * This parameter can be one of the following values: - * @arg LCD_IT_SOF: Start of Frame Interrupt - * @arg LCD_IT_UDD: Update Display Done Interrupt. - * @note If the device is in STOP mode (PCLK not provided) UDD will not - * generate an interrupt even if UDDIE = 1. - * If the display is not enabled the UDD interrupt will never occur. - * @retval The new state of the LCD_IT (SET or RESET). - */ -ITStatus LCD_GetITStatus(uint32_t LCD_IT) -{ - ITStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_LCD_GET_IT(LCD_IT)); - - if ((LCD->SR & LCD_IT) != (uint16_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - - if (((LCD->FCR & LCD_IT) != (uint16_t)RESET) && (bitstatus != (uint32_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the LCD's interrupt pending bits. - * @param LCD_IT: specifies the interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg LCD_IT_SOF: Start of Frame Interrupt - * @arg LCD_IT_UDD: Update Display Done Interrupt - * @retval None - */ -void LCD_ClearITPendingBit(uint32_t LCD_IT) -{ - /* Check the parameters */ - assert_param(IS_LCD_IT(LCD_IT)); - - /* Clear the corresponding LCD pending bit */ - LCD->CLR = (uint32_t)LCD_IT; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_pwr.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_pwr.c deleted file mode 100644 index 09e7cc351..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_pwr.c +++ /dev/null @@ -1,829 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_pwr.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the Power Controller (PWR) peripheral: - * - RTC Domain Access - * - PVD configuration - * - WakeUp pins configuration - * - Ultra Low Power mode configuration - * - Voltage Scaling configuration - * - Low Power modes configuration - * - Flags management - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_pwr.h" -#include "stm32l1xx_rcc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup PWR - * @brief PWR driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* --------- PWR registers bit address in the alias region ---------- */ -#define PWR_OFFSET (PWR_BASE - PERIPH_BASE) - -/* --- CR Register ---*/ - -/* Alias word address of DBP bit */ -#define CR_OFFSET (PWR_OFFSET + 0x00) -#define DBP_BitNumber 0x08 -#define CR_DBP_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (DBP_BitNumber * 4)) - -/* Alias word address of PVDE bit */ -#define PVDE_BitNumber 0x04 -#define CR_PVDE_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PVDE_BitNumber * 4)) - -/* Alias word address of ULP bit */ -#define ULP_BitNumber 0x09 -#define CR_ULP_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (ULP_BitNumber * 4)) - -/* Alias word address of FWU bit */ -#define FWU_BitNumber 0x0A -#define CR_FWU_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (FWU_BitNumber * 4)) - -/* --- CSR Register ---*/ - -/* Alias word address of EWUP bit */ -#define CSR_OFFSET (PWR_OFFSET + 0x04) -#define EWUP_BitNumber 0x08 -#define CSR_EWUP_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (EWUP_BitNumber * 4)) - -/* ------------------ PWR registers bit mask ------------------------ */ - -/* CR register bit mask */ -#define CR_DS_MASK ((uint32_t)0xFFFFFFFC) -#define CR_PLS_MASK ((uint32_t)0xFFFFFF1F) -#define CR_VOS_MASK ((uint32_t)0xFFFFE7FF) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup PWR_Private_Functions - * @{ - */ - -/** @defgroup PWR_Group1 RTC Domain Access function - * @brief RTC Domain Access function - * -@verbatim - =============================================================================== - RTC Domain Access function - =============================================================================== - - After reset, the RTC Registers (RCC CSR Register, RTC registers and RTC backup - registers) are protected against possible stray write accesses. - To enable access to RTC domain use the PWR_RTCAccessCmd(ENABLE) function. - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the PWR peripheral registers to their default reset values. - * @note Before calling this function, the VOS[1:0] bits should be configured - * to "10" and the system frequency has to be configured accordingly. - * To configure the VOS[1:0] bits, use the PWR_VoltageScalingConfig() - * function. - * @note ULP and FWU bits are not reset by this function. - * @param None - * @retval None - */ -void PWR_DeInit(void) -{ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, DISABLE); -} - -/** - * @brief Enables or disables access to the RTC and backup registers. - * @note If the HSE divided by 2, 4, 8 or 16 is used as the RTC clock, the - * RTC Domain Access should be kept enabled. - * @param NewState: new state of the access to the RTC and backup registers. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_RTCAccessCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_DBP_BB = (uint32_t)NewState; -} - -/** - * @} - */ - -/** @defgroup PWR_Group2 PVD configuration functions - * @brief PVD configuration functions - * -@verbatim - =============================================================================== - PVD configuration functions - =============================================================================== - - - The PVD is used to monitor the VDD power supply by comparing it to a threshold - selected by the PVD Level (PLS[2:0] bits in the PWR_CR). - - The PVD can use an external input analog voltage (PVD_IN) which is compared - internally to VREFINT. The PVD_IN (PB7) has to be configured in Analog mode - when PWR_PVDLevel_7 is selected (PLS[2:0] = 111). - - A PVDO flag is available to indicate if VDD/VDDA is higher or lower than the - PVD threshold. This event is internally connected to the EXTI line16 - and can generate an interrupt if enabled through the EXTI registers. - - The PVD is stopped in Standby mode. - -@endverbatim - * @{ - */ - -/** - * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD). - * @param PWR_PVDLevel: specifies the PVD detection level - * This parameter can be one of the following values: - * @arg PWR_PVDLevel_0: PVD detection level set to 1.9V - * @arg PWR_PVDLevel_1: PVD detection level set to 2.1V - * @arg PWR_PVDLevel_2: PVD detection level set to 2.3V - * @arg PWR_PVDLevel_3: PVD detection level set to 2.5V - * @arg PWR_PVDLevel_4: PVD detection level set to 2.7V - * @arg PWR_PVDLevel_5: PVD detection level set to 2.9V - * @arg PWR_PVDLevel_6: PVD detection level set to 3.1V - * @arg PWR_PVDLevel_7: External input analog voltage (Compare internally to VREFINT) - * @retval None - */ -void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_PWR_PVD_LEVEL(PWR_PVDLevel)); - - tmpreg = PWR->CR; - - /* Clear PLS[7:5] bits */ - tmpreg &= CR_PLS_MASK; - - /* Set PLS[7:5] bits according to PWR_PVDLevel value */ - tmpreg |= PWR_PVDLevel; - - /* Store the new value */ - PWR->CR = tmpreg; -} - -/** - * @brief Enables or disables the Power Voltage Detector(PVD). - * @param NewState: new state of the PVD. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_PVDCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)NewState; -} - -/** - * @} - */ - -/** @defgroup PWR_Group3 WakeUp pins configuration functions - * @brief WakeUp pins configuration functions - * -@verbatim - =============================================================================== - WakeUp pins configuration functions - =============================================================================== - - - WakeUp pins are used to wakeup the system from Standby mode. These pins are - forced in input pull down configuration and are active on rising edges. - - There are three WakeUp pins: WakeUp Pin 1 on PA.00, WakeUp Pin 2 on PC.13 and - WakeUp Pin 3 on PE.06. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the WakeUp Pin functionality. - * @param PWR_WakeUpPin: specifies the WakeUpPin. - * This parameter can be: PWR_WakeUpPin_1, PWR_WakeUpPin_2 or PWR_WakeUpPin_3. - * @param NewState: new state of the WakeUp Pin functionality. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_WakeUpPinCmd(uint32_t PWR_WakeUpPin, FunctionalState NewState) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_PWR_WAKEUP_PIN(PWR_WakeUpPin)); - - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - tmp = CSR_EWUP_BB + PWR_WakeUpPin; - - *(__IO uint32_t *) (tmp) = (uint32_t)NewState; -} - -/** - * @} - */ - -/** @defgroup PWR_Group4 Ultra Low Power mode configuration functions - * @brief Ultra Low Power mode configuration functions - * -@verbatim - =============================================================================== - Ultra Low Power mode configuration functions - =============================================================================== - - - The internal voltage reference consumption is not negligible, in particular - in Stop and Standby mode. To reduce power consumption, use the PWR_UltraLowPowerCmd() - function (ULP bit (Ultra low power) in the PWR_CR register) to disable the - internal voltage reference. However, in this case, when exiting from the - Stop/Standby mode, the functions managed through the internal voltage reference - are not reliable during the internal voltage reference startup time (up to 3 ms). - To reduce the wakeup time, the device can exit from Stop/Standby mode without - waiting for the internal voltage reference startup time. This is performed - by using the PWR_FastWakeUpCmd() function (setting the FWU bit (Fast - wakeup) in the PWR_CR register) before entering Stop/Standby mode. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the Fast WakeUp from Ultra Low Power mode. - * @param NewState: new state of the Fast WakeUp functionality. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_FastWakeUpCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_FWU_BB = (uint32_t)NewState; -} - -/** - * @brief Enables or disables the Ultra Low Power mode. - * @param NewState: new state of the Ultra Low Power mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_UltraLowPowerCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_ULP_BB = (uint32_t)NewState; -} - -/** - * @} - */ - -/** @defgroup PWR_Group5 Voltage Scaling configuration functions - * @brief Voltage Scaling configuration functions - * -@verbatim - =============================================================================== - Voltage Scaling configuration functions - =============================================================================== - - - The dynamic voltage scaling is a power management technique which consists in - increasing or decreasing the voltage used for the digital peripherals (VCORE), - according to the circumstances. - - Depending on the device voltage range, the maximum frequency and FLASH wait - state should be adapted accordingly: - - +------------------------------------------------------------------+ - | Wait states | HCLK clock frequency (MHz) | - | |------------------------------------------------| - | (Latency) | voltage range | voltage range | - | | 1.65 V - 3.6 V | 2.0 V - 3.6 V | - | |----------------|---------------|---------------| - | | Range 3 | Range 2 | Range 1 | - | | VCORE = 1.2 V | VCORE = 1.5 V | VCORE = 1.8 V | - |---------------- |----------------|---------------|---------------| - | 0WS(1CPU cycle) |0 < HCLK <= 2 |0 < HCLK <= 8 |0 < HCLK <= 16 | - |-----------------|----------------|---------------|---------------| - | 1WS(2CPU cycle) |2 < HCLK <= 4 |8 < HCLK <= 16 |16 < HCLK <= 32| - |-----------------|----------------|---------------|---------------| - | CPU Performance | Low | Medium | High | - |-----__----------|----------------|---------------|---------------| - |Power Performance| High | Medium | Low | - +------------------------------------------------------------------+ - - - To modify the Product voltage range, user application has to: - - Check VDD to identify which ranges are allowed (see table above) - - Check the PWR_FLAG_VOSF (Voltage Scaling update ongoing) using the PWR_GetFlagStatus() - function and wait until it is reset. - - Configure the Voltage range using the PWR_VoltageScalingConfig() function. - - - When VCORE range 1 is selected and VDD drops below 2.0 V, the application must - reconfigure the system: - - Detect that VDD drops below 2.0 V using the PVD Level 1 - - Adapt the clock frequency to the voltage range that will be selected at next step - - Select the required voltage range - - When VCORE range 2 or range 3 is selected and VDD drops below 2.0 V, no system - reconfiguration is required. - - - When VDD is above 2.0 V, any of the 3 voltage ranges can be selected - - When the voltage range is above the targeted voltage range (e.g. from range - 1 to 2): - - Adapt the clock frequency to the lower voltage range that will be selected - at next step. - - Select the required voltage range. - - When the voltage range is below the targeted voltage range (e.g. from range - 3 to 1): - - Select the required voltage range. - - Tune the clock frequency if needed. - - - When VDD is below 2.0 V, only range 2 and 3 can be selected: - - From range 2 to range 3 - - Adapt the clock frequency to voltage range 3. - - Select voltage range 3. - - From range 3 to range 2 - - Select the voltage range 2. - - Tune the clock frequency if needed. - -@endverbatim - * @{ - */ - -/** - * @brief Configures the voltage scaling range. - * @note During voltage scaling configuration, the system clock is stopped - * until the regulator is stabilized (VOSF = 0). This must be taken - * into account during application developement, in case a critical - * reaction time to interrupt is needed, and depending on peripheral - * used (timer, communication,...). - * - * @param PWR_VoltageScaling: specifies the voltage scaling range. - * This parameter can be: - * @arg PWR_VoltageScaling_Range1: Voltage Scaling Range 1 (VCORE = 1.8V) - * @arg PWR_VoltageScaling_Range2: Voltage Scaling Range 2 (VCORE = 1.5V) - * @arg PWR_VoltageScaling_Range3: Voltage Scaling Range 3 (VCORE = 1.2V) - * @retval None - */ -void PWR_VoltageScalingConfig(uint32_t PWR_VoltageScaling) -{ - uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_PWR_VOLTAGE_SCALING_RANGE(PWR_VoltageScaling)); - - tmp = PWR->CR; - - tmp &= CR_VOS_MASK; - tmp |= PWR_VoltageScaling; - - PWR->CR = tmp & 0xFFFFFFF3; - -} - -/** - * @} - */ - -/** @defgroup PWR_Group6 Low Power modes configuration functions - * @brief Low Power modes configuration functions - * -@verbatim - =============================================================================== - Low Power modes configuration functions - =============================================================================== - - The devices feature five low-power modes: - - Low power run mode: regulator in low power mode, limited clock frequency, - limited number of peripherals running. - - Sleep mode: Cortex-M3 core stopped, peripherals kept running. - - Low power sleep mode: Cortex-M3 core stopped, limited clock frequency, - limited number of peripherals running, regulator in low power mode. - - Stop mode: all clocks are stopped, regulator running, regulator in low power mode - - Standby mode: VCORE domain powered off - - Low power run mode (LP run) - =========================== - - Entry: - - Decrease the system frequency. - - The regulator is forced in low power mode using the PWR_EnterLowPowerRunMode() - function. - - Exit: - - The regulator is forced in Main regulator mode sing the PWR_EnterLowPowerRunMode() - function. - - Increase the system frequency if needed. - - Sleep mode - =========== - - Entry: - - The Sleep mode is entered by using the PWR_EnterSleepMode(PWR_Regulator_ON,) - function with regulator ON. - - Exit: - - Any peripheral interrupt acknowledged by the nested vectored interrupt - controller (NVIC) can wake up the device from Sleep mode. - - Low power sleep mode (LP sleep) - =============================== - - Entry: - - The Flash memory must be switched off by using the FLASH_SLEEPPowerDownCmd() - function. - - Decrease the system frequency. - - The regulator is forced in low power mode and the WFI or WFE instructions - are executed using the PWR_EnterSleepMode(PWR_Regulator_LowPower,) function - with regulator in LowPower. - - Exit: - - Any peripheral interrupt acknowledged by the nested vectored interrupt - controller (NVIC) can wake up the device from Sleep LP mode. - - Stop mode - ========== - In Stop mode, all clocks in the VCORE domain are stopped, the PLL, the MSI, - the HSI and the HSE RC oscillators are disabled. Internal SRAM and register - contents are preserved. - The voltage regulator can be configured either in normal or low-power mode. - To minimize the consumption In Stop mode, VREFINT, the BOR, PVD, and temperature - sensor can be switched off before entering the Stop mode. They can be switched - on again by software after exiting the Stop mode using the PWR_UltraLowPowerCmd() - function. - - - Entry: - - The Stop mode is entered using the PWR_EnterSTOPMode(PWR_Regulator_LowPower,) - function with regulator in LowPower or with Regulator ON. - - Exit: - - Any EXTI Line (Internal or External) configured in Interrupt/Event mode. - - Standby mode - ============ - The Standby mode allows to achieve the lowest power consumption. It is based - on the Cortex-M3 deepsleep mode, with the voltage regulator disabled. - The VCORE domain is consequently powered off. The PLL, the MSI, the HSI - oscillator and the HSE oscillator are also switched off. SRAM and register - contents are lost except for the RTC registers, RTC backup registers and - Standby circuitry. - - The voltage regulator is OFF. - - To minimize the consumption In Standby mode, VREFINT, the BOR, PVD, and temperature - sensor can be switched off before entering the Standby mode. They can be switched - on again by software after exiting the Standby mode using the PWR_UltraLowPowerCmd() - function. - - - Entry: - - The Standby mode is entered using the PWR_EnterSTANDBYMode() function. - - Exit: - - WKUP pin rising edge, RTC alarm (Alarm A and Alarm B), RTC wakeup, - tamper event, time-stamp event, external reset in NRST pin, IWDG reset. - - Auto-wakeup (AWU) from low-power mode - ===================================== - The MCU can be woken up from low-power mode by an RTC Alarm event, an RTC - Wakeup event, a tamper event, a time-stamp event, or a comparator event, - without depending on an external interrupt (Auto-wakeup mode). - - - RTC auto-wakeup (AWU) from the Stop mode - ---------------------------------------- - - - To wake up from the Stop mode with an RTC alarm event, it is necessary to: - - Configure the EXTI Line 17 to be sensitive to rising edges (Interrupt - or Event modes) using the EXTI_Init() function. - - Enable the RTC Alarm Interrupt using the RTC_ITConfig() function - - Configure the RTC to generate the RTC alarm using the RTC_SetAlarm() - and RTC_AlarmCmd() functions. - - To wake up from the Stop mode with an RTC Tamper or time stamp event, it - is necessary to: - - Configure the EXTI Line 19 to be sensitive to rising edges (Interrupt - or Event modes) using the EXTI_Init() function. - - Enable the RTC Tamper or time stamp Interrupt using the RTC_ITConfig() - function - - Configure the RTC to detect the tamper or time stamp event using the - RTC_TimeStampConfig(), RTC_TamperTriggerConfig() and RTC_TamperCmd() - functions. - - To wake up from the Stop mode with an RTC WakeUp event, it is necessary to: - - Configure the EXTI Line 20 to be sensitive to rising edges (Interrupt - or Event modes) using the EXTI_Init() function. - - Enable the RTC WakeUp Interrupt using the RTC_ITConfig() function - - Configure the RTC to generate the RTC WakeUp event using the RTC_WakeUpClockConfig(), - RTC_SetWakeUpCounter() and RTC_WakeUpCmd() functions. - - - RTC auto-wakeup (AWU) from the Standby mode - ------------------------------------------- - - To wake up from the Standby mode with an RTC alarm event, it is necessary to: - - Enable the RTC Alarm Interrupt using the RTC_ITConfig() function - - Configure the RTC to generate the RTC alarm using the RTC_SetAlarm() - and RTC_AlarmCmd() functions. - - To wake up from the Standby mode with an RTC Tamper or time stamp event, it - is necessary to: - - Enable the RTC Tamper or time stamp Interrupt using the RTC_ITConfig() - function - - Configure the RTC to detect the tamper or time stamp event using the - RTC_TimeStampConfig(), RTC_TamperTriggerConfig() and RTC_TamperCmd() - functions. - - To wake up from the Standby mode with an RTC WakeUp event, it is necessary to: - - Enable the RTC WakeUp Interrupt using the RTC_ITConfig() function - - Configure the RTC to generate the RTC WakeUp event using the RTC_WakeUpClockConfig(), - RTC_SetWakeUpCounter() and RTC_WakeUpCmd() functions. - - - Comparator auto-wakeup (AWU) from the Stop mode - ----------------------------------------------- - - To wake up from the Stop mode with an comparator 1 or comparator 2 wakeup - event, it is necessary to: - - Configure the EXTI Line 21 for comparator 1 or EXTI Line 22 for comparator 2 - to be sensitive to to the selected edges (falling, rising or falling - and rising) (Interrupt or Event modes) using the EXTI_Init() function. - - Configure the comparator to generate the event. - -@endverbatim - * @{ - */ - -/** - * @brief Enters/Exits the Low Power Run mode. - * @note Low power run mode can only be entered when VCORE is in range 2. - * In addition, the dynamic voltage scaling must not be used when Low - * power run mode is selected. Only Stop and Sleep modes with regulator - * configured in Low power mode is allowed when Low power run mode is - * selected. - * @note In Low power run mode, all I/O pins keep the same state as in Run mode. - * @param NewState: new state of the Low Power Run mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_EnterLowPowerRunMode(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - PWR->CR |= PWR_CR_LPSDSR; - PWR->CR |= PWR_CR_LPRUN; - } - else - { - PWR->CR &= (uint32_t)~((uint32_t)PWR_CR_LPRUN); - PWR->CR &= (uint32_t)~((uint32_t)PWR_CR_LPSDSR); - } -} - -/** - * @brief Enters Sleep mode. - * @note In Sleep mode, all I/O pins keep the same state as in Run mode. - * @param PWR_Regulator: specifies the regulator state in Sleep mode. - * This parameter can be one of the following values: - * @arg PWR_Regulator_ON: Sleep mode with regulator ON - * @arg PWR_Regulator_LowPower: Sleep mode with regulator in low power mode - * @note Low power sleep mode can only be entered when VCORE is in range 2. - * @note When the voltage regulator operates in low power mode, an additional - * startup delay is incurred when waking up from Low power sleep mode. - * - * @param PWR_SLEEPEntry: specifies if SLEEP mode in entered with WFI or WFE instruction. - * This parameter can be one of the following values: - * @arg PWR_SLEEPEntry_WFI: enter SLEEP mode with WFI instruction - * @arg PWR_SLEEPEntry_WFE: enter SLEEP mode with WFE instruction - * @retval None - */ -void PWR_EnterSleepMode(uint32_t PWR_Regulator, uint8_t PWR_SLEEPEntry) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_PWR_REGULATOR(PWR_Regulator)); - - assert_param(IS_PWR_SLEEP_ENTRY(PWR_SLEEPEntry)); - - /* Select the regulator state in Sleep mode ---------------------------------*/ - tmpreg = PWR->CR; - - /* Clear PDDS and LPDSR bits */ - tmpreg &= CR_DS_MASK; - - /* Set LPDSR bit according to PWR_Regulator value */ - tmpreg |= PWR_Regulator; - - /* Store the new value */ - PWR->CR = tmpreg; - - /* Clear SLEEPDEEP bit of Cortex System Control Register */ - SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP); - - /* Select SLEEP mode entry -------------------------------------------------*/ - if(PWR_SLEEPEntry == PWR_SLEEPEntry_WFI) - { - /* Request Wait For Interrupt */ - __WFI(); - } - else - { - /* Request Wait For Event */ - __WFE(); - } -} - -/** - * @brief Enters STOP mode. - * @note In Stop mode, all I/O pins keep the same state as in Run mode. - * @note When exiting Stop mode by issuing an interrupt or a wakeup event, - * the MSI RC oscillator is selected as system clock. - * @note When the voltage regulator operates in low power mode, an additional - * startup delay is incurred when waking up from Stop mode. - * By keeping the internal regulator ON during Stop mode, the consumption - * is higher although the startup time is reduced. - * @param PWR_Regulator: specifies the regulator state in STOP mode. - * This parameter can be one of the following values: - * @arg PWR_Regulator_ON: STOP mode with regulator ON - * @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode - * @param PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction. - * This parameter can be one of the following values: - * @arg PWR_STOPEntry_WFI: enter STOP mode with WFI instruction - * @arg PWR_STOPEntry_WFE: enter STOP mode with WFE instruction - * @retval None - */ -void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_PWR_REGULATOR(PWR_Regulator)); - assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry)); - - /* Select the regulator state in STOP mode ---------------------------------*/ - tmpreg = PWR->CR; - /* Clear PDDS and LPDSR bits */ - tmpreg &= CR_DS_MASK; - - /* Set LPDSR bit according to PWR_Regulator value */ - tmpreg |= PWR_Regulator; - - /* Store the new value */ - PWR->CR = tmpreg; - - /* Set SLEEPDEEP bit of Cortex System Control Register */ - SCB->SCR |= SCB_SCR_SLEEPDEEP; - - /* Select STOP mode entry --------------------------------------------------*/ - if(PWR_STOPEntry == PWR_STOPEntry_WFI) - { - /* Request Wait For Interrupt */ - __WFI(); - } - else - { - /* Request Wait For Event */ - __WFE(); - } - /* Reset SLEEPDEEP bit of Cortex System Control Register */ - SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP); -} - -/** - * @brief Enters STANDBY mode. - * @note In Standby mode, all I/O pins are high impedance except for: - * - Reset pad (still available) - * - RTC_AF1 pin (PC13) if configured for Wakeup pin 2 (WKUP2), tamper, - * time-stamp, RTC Alarm out, or RTC clock calibration out. - * - WKUP pin 1 (PA0) and WKUP pin 3 (PE6), if enabled. - * @param None - * @retval None - */ -void PWR_EnterSTANDBYMode(void) -{ - /* Clear Wakeup flag */ - PWR->CR |= PWR_CR_CWUF; - - /* Select STANDBY mode */ - PWR->CR |= PWR_CR_PDDS; - - /* Set SLEEPDEEP bit of Cortex System Control Register */ - SCB->SCR |= SCB_SCR_SLEEPDEEP; - -/* This option is used to ensure that store operations are completed */ -#if defined ( __CC_ARM ) - __force_stores(); -#endif - /* Request Wait For Interrupt */ - __WFI(); -} - -/** - * @} - */ - -/** @defgroup PWR_Group7 Flags management functions - * @brief Flags management functions - * -@verbatim - =============================================================================== - Flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Checks whether the specified PWR flag is set or not. - * @param PWR_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg PWR_FLAG_WU: Wake Up flag. This flag indicates that a wakeup event - * was received from the WKUP pin or from the RTC alarm (Alarm A or Alarm B), - * RTC Tamper event, RTC TimeStamp event or RTC Wakeup. - * @arg PWR_FLAG_SB: StandBy flag. This flag indicates that the system was - * resumed from StandBy mode. - * @arg PWR_FLAG_PVDO: PVD Output. This flag is valid only if PVD is enabled - * by the PWR_PVDCmd() function. - * @arg PWR_FLAG_VREFINTRDY: Internal Voltage Reference Ready flag. This - * flag indicates the state of the internal voltage reference, VREFINT. - * @arg PWR_FLAG_VOS: Voltage Scaling select flag. A delay is required for - * the internal regulator to be ready after the voltage range is changed. - * The VOSF flag indicates that the regulator has reached the voltage level - * defined with bits VOS[1:0] of PWR_CR register. - * @arg PWR_FLAG_REGLP: Regulator LP flag. This flag is set by hardware - * when the MCU is in Low power run mode. - * When the MCU exits from Low power run mode, this flag stays SET until - * the regulator is ready in main mode. A polling on this flag is - * recommended to wait for the regulator main mode. - * This flag is RESET by hardware when the regulator is ready. - * @retval The new state of PWR_FLAG (SET or RESET). - */ -FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_PWR_GET_FLAG(PWR_FLAG)); - - if ((PWR->CSR & PWR_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the flag status */ - return bitstatus; -} - -/** - * @brief Clears the PWR's pending flags. - * @param PWR_FLAG: specifies the flag to clear. - * This parameter can be one of the following values: - * @arg PWR_FLAG_WU: Wake Up flag - * @arg PWR_FLAG_SB: StandBy flag - * @retval None - */ -void PWR_ClearFlag(uint32_t PWR_FLAG) -{ - /* Check the parameters */ - assert_param(IS_PWR_CLEAR_FLAG(PWR_FLAG)); - - PWR->CR |= PWR_FLAG << 2; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_rcc.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_rcc.c deleted file mode 100644 index dbce5fa2f..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_rcc.c +++ /dev/null @@ -1,1575 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_rcc.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the Reset and clock control (RCC) peripheral: - * - Internal/external clocks, PLL, CSS and MCO configuration - * - System, AHB and APB busses clocks configuration - * - Peripheral clocks configuration - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * RCC specific features - * =================================================================== - * - * After reset the device is running from MSI (2 MHz) with Flash 0 WS, - * all peripherals are off except internal SRAM, Flash and JTAG. - * - There is no prescaler on High speed (AHB) and Low speed (APB) busses; - * all peripherals mapped on these busses are running at MSI speed. - * - The clock for all peripherals is switched off, except the SRAM and FLASH. - * - All GPIOs are in input floating state, except the JTAG pins which - * are assigned to be used for debug purpose. - * - * Once the device started from reset, the user application has to: - * - Configure the clock source to be used to drive the System clock - * (if the application needs higher frequency/performance) - * - Configure the System clock frequency and Flash settings - * - Configure the AHB and APB busses prescalers - * - Enable the clock for the peripheral(s) to be used - * - Configure the clock source(s) for peripherals whose clocks are not - * derived from the System clock (ADC, RTC/LCD and IWDG) - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_rcc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup RCC - * @brief RCC driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* ------------ RCC registers bit address in the alias region ----------- */ -#define RCC_OFFSET (RCC_BASE - PERIPH_BASE) - -/* --- CR Register ---*/ - -/* Alias word address of HSION bit */ -#define CR_OFFSET (RCC_OFFSET + 0x00) -#define HSION_BitNumber 0x00 -#define CR_HSION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (HSION_BitNumber * 4)) - -/* Alias word address of MSION bit */ -#define MSION_BitNumber 0x08 -#define CR_MSION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (MSION_BitNumber * 4)) - -/* Alias word address of PLLON bit */ -#define PLLON_BitNumber 0x18 -#define CR_PLLON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLON_BitNumber * 4)) - -/* Alias word address of CSSON bit */ -#define CSSON_BitNumber 0x1C -#define CR_CSSON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (CSSON_BitNumber * 4)) - -/* --- CSR Register ---*/ - -/* Alias word address of LSION bit */ -#define CSR_OFFSET (RCC_OFFSET + 0x34) -#define LSION_BitNumber 0x00 -#define CSR_LSION_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (LSION_BitNumber * 4)) - -/* Alias word address of RTCEN bit */ -#define RTCEN_BitNumber 0x16 -#define CSR_RTCEN_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (RTCEN_BitNumber * 4)) - -/* Alias word address of RTCRST bit */ -#define RTCRST_BitNumber 0x17 -#define CSR_RTCRST_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (RTCRST_BitNumber * 4)) - - -/* ---------------------- RCC registers mask -------------------------------- */ -/* RCC Flag Mask */ -#define FLAG_MASK ((uint8_t)0x1F) - -/* CR register byte 3 (Bits[23:16]) base address */ -#define CR_BYTE3_ADDRESS ((uint32_t)0x40023802) - -/* ICSCR register byte 4 (Bits[31:24]) base address */ -#define ICSCR_BYTE4_ADDRESS ((uint32_t)0x40023807) - -/* CFGR register byte 3 (Bits[23:16]) base address */ -#define CFGR_BYTE3_ADDRESS ((uint32_t)0x4002380A) - -/* CFGR register byte 4 (Bits[31:24]) base address */ -#define CFGR_BYTE4_ADDRESS ((uint32_t)0x4002380B) - -/* CIR register byte 2 (Bits[15:8]) base address */ -#define CIR_BYTE2_ADDRESS ((uint32_t)0x4002380D) - -/* CIR register byte 3 (Bits[23:16]) base address */ -#define CIR_BYTE3_ADDRESS ((uint32_t)0x4002380E) - -/* CSR register byte 2 (Bits[15:8]) base address */ -#define CSR_BYTE2_ADDRESS ((uint32_t)0x40023835) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ - -static __I uint8_t PLLMulTable[9] = {3, 4, 6, 8, 12, 16, 24, 32, 48}; -static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; - -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup RCC_Private_Functions - * @{ - */ - -/** @defgroup RCC_Group1 Internal and external clocks, PLL, CSS and MCO configuration functions - * @brief Internal and external clocks, PLL, CSS and MCO configuration functions - * -@verbatim - =============================================================================== - Internal/external clocks, PLL, CSS and MCO configuration functions - =============================================================================== - - This section provide functions allowing to configure the internal/external clocks, - PLL, CSS and MCO. - - 1. HSI (high-speed internal), 16 MHz factory-trimmed RC used directly or through - the PLL as System clock source. - - 2. MSI (multi-speed internal), multispeed low power RC (65.536 KHz to 4.194 MHz) - MHz used as System clock source. - - 3. LSI (low-speed internal), 37 KHz low consumption RC used as IWDG and/or RTC - clock source. - - 4. HSE (high-speed external), 1 to 24 MHz crystal oscillator used directly or - through the PLL as System clock source. Can be used also as RTC clock source. - - 5. LSE (low-speed external), 32 KHz oscillator used as RTC clock source. - - 6. PLL (clocked by HSI or HSE), for System clock and USB (48 MHz). - - 7. CSS (Clock security system), once enable and if a HSE clock failure occurs - (HSE used directly or through PLL as System clock source), the System clock - is automatically switched to MSI and an interrupt is generated if enabled. - The interrupt is linked to the Cortex-M3 NMI (Non-Maskable Interrupt) - exception vector. - - 8. MCO (microcontroller clock output), used to output SYSCLK, HSI, MSI, HSE, PLL, - LSI or LSE clock (through a configurable prescaler) on PA8 pin. - -@endverbatim - * @{ - */ - -/** - * @brief Resets the RCC clock configuration to the default reset state. - * @note - The default reset state of the clock configuration is given below: - * - MSI ON and used as system clock source (MSI range is not modified - * by this function, it keep the value configured by user application) - * - HSI, HSE and PLL OFF - * - AHB, APB1 and APB2 prescaler set to 1. - * - CSS and MCO OFF - * - All interrupts disabled - * - However, this function doesn't modify the configuration of the - * - Peripheral clocks - * - LSI, LSE and RTC clocks - * @param None - * @retval None - */ -void RCC_DeInit(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; -} - -/** - * @brief Configures the External High Speed oscillator (HSE). - * @note - After enabling the HSE (RCC_HSE_ON or RCC_HSE_Bypass), the application - * software should wait on HSERDY flag to be set indicating that HSE clock - * is stable and can be used to clock the PLL and/or system clock. - * - HSE state can not be changed if it is used directly or through the - * PLL as system clock. In this case, you have to select another source - * of the system clock then change the HSE state (ex. disable it). - * - The HSE is stopped by hardware when entering STOP and STANDBY modes. - * @note This function reset the CSSON bit, so if the Clock security system(CSS) - * was previously enabled you have to enable it again after calling this - * function. - * @param RCC_HSE: specifies the new state of the HSE. - * This parameter can be one of the following values: - * @arg RCC_HSE_OFF: turn OFF the HSE oscillator, HSERDY flag goes low after - * 6 HSE oscillator clock cycles. - * @arg RCC_HSE_ON: turn ON the HSE oscillator - * @arg RCC_HSE_Bypass: HSE oscillator bypassed with external clock - * @retval None - */ -void RCC_HSEConfig(uint8_t RCC_HSE) -{ - /* Check the parameters */ - assert_param(IS_RCC_HSE(RCC_HSE)); - - /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/ - *(__IO uint8_t *) CR_BYTE3_ADDRESS = RCC_HSE_OFF; - - /* Set the new HSE configuration -------------------------------------------*/ - *(__IO uint8_t *) CR_BYTE3_ADDRESS = RCC_HSE; - -} - -/** - * @brief Waits for HSE start-up. - * @note This functions waits on HSERDY flag to be set and return SUCCESS if - * this flag is set, otherwise returns ERROR if the timeout is reached - * and this flag is not set. The timeout value is defined by the constant - * HSE_STARTUP_TIMEOUT in stm32l1xx.h file. You can tailor it depending - * on the HSE crystal used in your application. - * @param None - * @retval An ErrorStatus enumeration value: - * - SUCCESS: HSE oscillator is stable and ready to use - * - ERROR: HSE oscillator not yet ready - */ -ErrorStatus RCC_WaitForHSEStartUp(void) -{ - __IO uint32_t StartUpCounter = 0; - ErrorStatus status = ERROR; - FlagStatus HSEStatus = RESET; - - /* Wait till HSE is ready and if timeout is reached exit */ - do - { - HSEStatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY); - StartUpCounter++; - } while((StartUpCounter != HSE_STARTUP_TIMEOUT) && (HSEStatus == RESET)); - - if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET) - { - status = SUCCESS; - } - else - { - status = ERROR; - } - return (status); -} - -/** - * @brief Adjusts the Internal Multi Speed oscillator (MSI) calibration value. - * @note The calibration is used to compensate for the variations in voltage - * and temperature that influence the frequency of the internal MSI RC. - * Refer to the Application Note AN3300 for more details on how to - * calibrate the MSI. - * @param MSICalibrationValue: specifies the MSI calibration trimming value. - * This parameter must be a number between 0 and 0xFF. - * @retval None - */ -void RCC_AdjustMSICalibrationValue(uint8_t MSICalibrationValue) -{ - - /* Check the parameters */ - assert_param(IS_RCC_MSI_CALIBRATION_VALUE(MSICalibrationValue)); - - *(__IO uint8_t *) ICSCR_BYTE4_ADDRESS = MSICalibrationValue; -} - -/** - * @brief Configures the Internal Multi Speed oscillator (MSI) clock range. - * @note - After restart from Reset or wakeup from STANDBY, the MSI clock is - * around 2.097 MHz. The MSI clock does not change after wake-up from - * STOP mode. - * - The MSI clock range can be modified on the fly. - * @param RCC_MSIRange: specifies the MSI Clock range. - * This parameter must be one of the following values: - * @arg RCC_MSIRange_0: MSI clock is around 65.536 KHz - * @arg RCC_MSIRange_1: MSI clock is around 131.072 KHz - * @arg RCC_MSIRange_2: MSI clock is around 262.144 KHz - * @arg RCC_MSIRange_3: MSI clock is around 524.288 KHz - * @arg RCC_MSIRange_4: MSI clock is around 1.048 MHz - * @arg RCC_MSIRange_5: MSI clock is around 2.097 MHz (default after Reset or wake-up from STANDBY) - * @arg RCC_MSIRange_6: MSI clock is around - * - * @retval None - */ -void RCC_MSIRangeConfig(uint32_t RCC_MSIRange) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_MSIRange)); - - tmpreg = RCC->ICSCR; - - /* Clear MSIRANGE[2:0] bits */ - tmpreg &= ~RCC_ICSCR_MSIRANGE; - - /* Set the MSIRANGE[2:0] bits according to RCC_MSIRange value */ - tmpreg |= (uint32_t)RCC_MSIRange; - - /* Store the new value */ - RCC->ICSCR = tmpreg; -} - -/** - * @brief Enables or disables the Internal Multi Speed oscillator (MSI). - * @note - The MSI is stopped by hardware when entering STOP and STANDBY modes. - * It is used (enabled by hardware) as system clock source after - * startup from Reset, wakeup from STOP and STANDBY mode, or in case - * of failure of the HSE used directly or indirectly as system clock - * (if the Clock Security System CSS is enabled). - * - MSI can not be stopped if it is used as system clock source. - * In this case, you have to select another source of the system - * clock then stop the MSI. - * - After enabling the MSI, the application software should wait on - * MSIRDY flag to be set indicating that MSI clock is stable and can - * be used as system clock source. - * @param NewState: new state of the MSI. - * This parameter can be: ENABLE or DISABLE. - * @note When the MSI is stopped, MSIRDY flag goes low after 6 MSI oscillator - * clock cycles. - * @retval None - */ -void RCC_MSICmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_MSION_BB = (uint32_t)NewState; -} - -/** - * @brief Adjusts the Internal High Speed oscillator (HSI) calibration value. - * @note The calibration is used to compensate for the variations in voltage - * and temperature that influence the frequency of the internal HSI RC. - * Refer to the Application Note AN3300 for more details on how to - * calibrate the HSI. - * @param HSICalibrationValue: specifies the HSI calibration trimming value. - * This parameter must be a number between 0 and 0x1F. - * @retval None - */ -void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_HSI_CALIBRATION_VALUE(HSICalibrationValue)); - - tmpreg = RCC->ICSCR; - - /* Clear HSITRIM[4:0] bits */ - tmpreg &= ~RCC_ICSCR_HSITRIM; - - /* Set the HSITRIM[4:0] bits according to HSICalibrationValue value */ - tmpreg |= (uint32_t)HSICalibrationValue << 8; - - /* Store the new value */ - RCC->ICSCR = tmpreg; -} - -/** - * @brief Enables or disables the Internal High Speed oscillator (HSI). - * @note - After enabling the HSI, the application software should wait on - * HSIRDY flag to be set indicating that HSI clock is stable and can - * be used to clock the PLL and/or system clock. - * - HSI can not be stopped if it is used directly or through the PLL - * as system clock. In this case, you have to select another source - * of the system clock then stop the HSI. - * - The HSI is stopped by hardware when entering STOP and STANDBY modes. - * @param NewState: new state of the HSI. - * This parameter can be: ENABLE or DISABLE. - * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator - * clock cycles. - * @retval None - */ -void RCC_HSICmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_HSION_BB = (uint32_t)NewState; -} - -/** - * @brief Configures the External Low Speed oscillator (LSE). - * @note - As the LSE is in the RTC domain and write access is denied to this - * domain after reset, you have to enable write access using - * PWR_RTCAccessCmd(ENABLE) function before to configure the LSE - * (to be done once after reset). - * - After enabling the LSE (RCC_LSE_ON or RCC_LSE_Bypass), the application - * software should wait on LSERDY flag to be set indicating that LSE clock - * is stable and can be used to clock the RTC. - * @param RCC_LSE: specifies the new state of the LSE. - * This parameter can be one of the following values: - * @arg RCC_LSE_OFF: turn OFF the LSE oscillator, LSERDY flag goes low after - * 6 LSE oscillator clock cycles. - * @arg RCC_LSE_ON: turn ON the LSE oscillator - * @arg RCC_LSE_Bypass: LSE oscillator bypassed with external clock - * @retval None - */ -void RCC_LSEConfig(uint8_t RCC_LSE) -{ - /* Check the parameters */ - assert_param(IS_RCC_LSE(RCC_LSE)); - - /* Reset LSEON and LSEBYP bits before configuring the LSE ------------------*/ - *(__IO uint8_t *) CSR_BYTE2_ADDRESS = RCC_LSE_OFF; - - /* Set the new LSE configuration -------------------------------------------*/ - *(__IO uint8_t *) CSR_BYTE2_ADDRESS = RCC_LSE; -} - -/** - * @brief Enables or disables the Internal Low Speed oscillator (LSI). - * @note - After enabling the LSI, the application software should wait on - * LSIRDY flag to be set indicating that LSI clock is stable and can - * be used to clock the IWDG and/or the RTC. - * - LSI can not be disabled if the IWDG is running. - * @param NewState: new state of the LSI. - * This parameter can be: ENABLE or DISABLE. - * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator - * clock cycles. - * @retval None - */ -void RCC_LSICmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CSR_LSION_BB = (uint32_t)NewState; -} - -/** - * @brief Configures the PLL clock source and multiplication factor. - * @note This function must be used only when the PLL is disabled. - * - * @param RCC_PLLSource: specifies the PLL entry clock source. - * This parameter can be one of the following values: - * @arg RCC_PLLSource_HSI: HSI oscillator clock selected as PLL clock source - * @arg RCC_PLLSource_HSE: HSE oscillator clock selected as PLL clock source - * @note The minimum input clock frequency for PLL is 2 MHz (when using HSE as - * PLL source). - * - * @param RCC_PLLMul: specifies the PLL multiplication factor, which drive the PLLVCO clock - * This parameter can be: - * @arg RCC_PLLMul_3: PLL clock source multiplied by 3 - * @arg RCC_PLLMul_4: PLL clock source multiplied by 4 - * @arg RCC_PLLMul_6: PLL clock source multiplied by 6 - * @arg RCC_PLLMul_8: PLL clock source multiplied by 8 - * @arg RCC_PLLMul_12: PLL clock source multiplied by 12 - * @arg RCC_PLLMul_16: PLL clock source multiplied by 16 - * @arg RCC_PLLMul_24: PLL clock source multiplied by 24 - * @arg RCC_PLLMul_32: PLL clock source multiplied by 32 - * @arg RCC_PLLMul_48: PLL clock source multiplied by 48 - * @note The application software must set correctly the PLL multiplication - * factor to avoid exceeding - * - 96 MHz as PLLVCO when the product is in range 1 - * - 48 MHz as PLLVCO when the product is in range 2 - * - 24 MHz when the product is in range 3 - * @note When using the USB the PLLVCO should be 96MHz - * - * @param RCC_PLLDiv: specifies the PLL division factor. - * This parameter can be: - * @arg RCC_PLLDiv_2: PLL Clock output divided by 2 - * @arg RCC_PLLDiv_3: PLL Clock output divided by 3 - * @arg RCC_PLLDiv_4: PLL Clock output divided by 4 - * @note The application software must set correctly the output division to avoid - * exceeding 32 MHz as SYSCLK. - * - * @retval None - */ -void RCC_PLLConfig(uint8_t RCC_PLLSource, uint8_t RCC_PLLMul, uint8_t RCC_PLLDiv) -{ - /* Check the parameters */ - assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource)); - assert_param(IS_RCC_PLL_MUL(RCC_PLLMul)); - assert_param(IS_RCC_PLL_DIV(RCC_PLLDiv)); - - *(__IO uint8_t *) CFGR_BYTE3_ADDRESS = (uint8_t)(RCC_PLLSource | ((uint8_t)(RCC_PLLMul | (uint8_t)(RCC_PLLDiv)))); -} - -/** - * @brief Enables or disables the PLL. - * @note - After enabling the PLL, the application software should wait on - * PLLRDY flag to be set indicating that PLL clock is stable and can - * be used as system clock source. - * - The PLL can not be disabled if it is used as system clock source - * - The PLL is disabled by hardware when entering STOP and STANDBY modes. - * @param NewState: new state of the PLL. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_PLLCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_PLLON_BB = (uint32_t)NewState; -} - -/** - * @brief Enables or disables the Clock Security System. - * @note If a failure is detected on the HSE oscillator clock, this oscillator - * is automatically disabled and an interrupt is generated to inform the - * software about the failure (Clock Security System Interrupt, CSSI), - * allowing the MCU to perform rescue operations. The CSSI is linked to - * the Cortex-M3 NMI (Non-Maskable Interrupt) exception vector. - * @param NewState: new state of the Clock Security System. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_ClockSecuritySystemCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_CSSON_BB = (uint32_t)NewState; -} - -/** - * @brief Selects the clock source to output on MCO pin (PA8). - * @note PA8 should be configured in alternate function mode. - * @param RCC_MCOSource: specifies the clock source to output. - * This parameter can be one of the following values: - * @arg RCC_MCOSource_NoClock: No clock selected - * @arg RCC_MCOSource_SYSCLK: System clock selected - * @arg RCC_MCOSource_HSI: HSI oscillator clock selected - * @arg RCC_MCOSource_MSI: MSI oscillator clock selected - * @arg RCC_MCOSource_HSE: HSE oscillator clock selected - * @arg RCC_MCOSource_PLLCLK: PLL clock selected - * @arg RCC_MCOSource_LSI: LSI clock selected - * @arg RCC_MCOSource_LSE: LSE clock selected - * @param RCC_MCODiv: specifies the MCO prescaler. - * This parameter can be one of the following values: - * @arg RCC_MCODiv_1: no division applied to MCO clock - * @arg RCC_MCODiv_2: division by 2 applied to MCO clock - * @arg RCC_MCODiv_4: division by 4 applied to MCO clock - * @arg RCC_MCODiv_8: division by 8 applied to MCO clock - * @arg RCC_MCODiv_16: division by 16 applied to MCO clock - * @retval None - */ -void RCC_MCOConfig(uint8_t RCC_MCOSource, uint8_t RCC_MCODiv) -{ - /* Check the parameters */ - assert_param(IS_RCC_MCO_SOURCE(RCC_MCOSource)); - assert_param(IS_RCC_MCO_DIV(RCC_MCODiv)); - - /* Select MCO clock source and prescaler */ - *(__IO uint8_t *) CFGR_BYTE4_ADDRESS = RCC_MCOSource | RCC_MCODiv; -} - -/** - * @} - */ - -/** @defgroup RCC_Group2 System AHB and APB busses clocks configuration functions - * @brief System, AHB and APB busses clocks configuration functions - * -@verbatim - =============================================================================== - System, AHB and APB busses clocks configuration functions - =============================================================================== - - This section provide functions allowing to configure the System, AHB, APB1 and - APB2 busses clocks. - - 1. Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI, - HSE and PLL. - The AHB clock (HCLK) is derived from System clock through configurable prescaler - and used to clock the CPU, memory and peripherals mapped on AHB bus (DMA and GPIO). - APB1 (PCLK1) and APB2 (PCLK2) clocks are derived from AHB clock through - configurable prescalers and used to clock the peripherals mapped on these busses. - You can use "RCC_GetClocksFreq()" function to retrieve the frequencies of these clocks. - -Note: All the peripheral clocks are derived from the System clock (SYSCLK) except: -==== - The USB 48 MHz clock which is derived from the PLL VCO clock. - - The ADC clock which is always the HSI clock. A divider by 1, 2 or 4 allows - to adapt the clock frequency to the device operating conditions. - - The RTC/LCD clock which is derived from the LSE, LSI or 1 MHz HSE_RTC (HSE - divided by a programmable prescaler). - The System clock (SYSCLK) frequency must be higher or equal to the RTC/LCD - clock frequency. - - IWDG clock which is always the LSI clock. - - 2. The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 32 MHz. - Depending on the device voltage range, the maximum frequency should be - adapted accordingly: - +----------------------------------------------------------------+ - | Wait states | HCLK clock frequency (MHz) | - | |------------------------------------------------| - | (Latency) | voltage range | voltage range | - | | 1.65 V - 3.6 V | 2.0 V - 3.6 V | - | |----------------|---------------|---------------| - | | VCORE = 1.2 V | VCORE = 1.5 V | VCORE = 1.8 V | - |-------------- |----------------|---------------|---------------| - |0WS(1CPU cycle)|0 < HCLK <= 2 |0 < HCLK <= 8 |0 < HCLK <= 16 | - |---------------|----------------|---------------|---------------| - |1WS(2CPU cycle)|2 < HCLK <= 4 |8 < HCLK <= 16 |16 < HCLK <= 32| - +----------------------------------------------------------------+ - - 3. After reset, the System clock source is the MSI (2 MHz) with 0 WS, Flash - 32-bit access is enabled and prefetch is disabled. - - It is recommended to use the following software sequences to tune the number - of wait states needed to access the Flash memory with the CPU frequency (HCLK). - - Increasing the CPU frequency (in the same voltage range) - - Program the Flash 64-bit access, using "FLASH_ReadAccess64Cmd(ENABLE)" function - - Check that 64-bit access is taken into account by reading FLASH_ACR - - Program Flash WS to 1, using "FLASH_SetLatency(FLASH_Latency_1)" function - - Check that the new number of WS is taken into account by reading FLASH_ACR - - Modify the CPU clock source, using "RCC_SYSCLKConfig()" function - - If needed, modify the CPU clock prescaler by using "RCC_HCLKConfig()" function - - Check that the new CPU clock source is taken into account by reading - the clock source status, using "RCC_GetSYSCLKSource()" function - - Decreasing the CPU frequency (in the same voltage range) - - Modify the CPU clock source, using "RCC_SYSCLKConfig()" function - - If needed, modify the CPU clock prescaler by using "RCC_HCLKConfig()" function - - Check that the new CPU clock source is taken into account by reading - the clock source status, using "RCC_GetSYSCLKSource()" function - - Program the new number of WS, using "FLASH_SetLatency()" function - - Check that the new number of WS is taken into account by reading FLASH_ACR - - Enable the Flash 32-bit access, using "FLASH_ReadAccess64Cmd(DISABLE)" function - - Check that 32-bit access is taken into account by reading FLASH_ACR - -@endverbatim - * @{ - */ - -/** - * @brief Configures the system clock (SYSCLK). - * @note - The MSI is used (enabled by hardware) as system clock source after - * startup from Reset, wake-up from STOP and STANDBY mode, or in case - * of failure of the HSE used directly or indirectly as system clock - * (if the Clock Security System CSS is enabled). - * - A switch from one clock source to another occurs only if the target - * clock source is ready (clock stable after startup delay or PLL locked). - * If a clock source which is not yet ready is selected, the switch will - * occur when the clock source will be ready. - * You can use RCC_GetSYSCLKSource() function to know which clock is - * currently used as system clock source. - * @param RCC_SYSCLKSource: specifies the clock source used as system clock source - * This parameter can be one of the following values: - * @arg RCC_SYSCLKSource_MSI: MSI selected as system clock source - * @arg RCC_SYSCLKSource_HSI: HSI selected as system clock source - * @arg RCC_SYSCLKSource_HSE: HSE selected as system clock source - * @arg RCC_SYSCLKSource_PLLCLK: PLL selected as system clock source - * @retval None - */ -void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_SYSCLK_SOURCE(RCC_SYSCLKSource)); - - tmpreg = RCC->CFGR; - - /* Clear SW[1:0] bits */ - tmpreg &= ~RCC_CFGR_SW; - - /* Set SW[1:0] bits according to RCC_SYSCLKSource value */ - tmpreg |= RCC_SYSCLKSource; - - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -/** - * @brief Returns the clock source used as system clock. - * @param None - * @retval The clock source used as system clock. The returned value can be one - * of the following values: - * - 0x00: MSI used as system clock - * - 0x04: HSI used as system clock - * - 0x08: HSE used as system clock - * - 0x0C: PLL used as system clock - */ -uint8_t RCC_GetSYSCLKSource(void) -{ - return ((uint8_t)(RCC->CFGR & RCC_CFGR_SWS)); -} - -/** - * @brief Configures the AHB clock (HCLK). - * @note Depending on the device voltage range, the software has to set correctly - * these bits to ensure that the system frequency does not exceed the - * maximum allowed frequency (for more details refer to section above - * "CPU, AHB and APB busses clocks configuration functions") - * @param RCC_SYSCLK: defines the AHB clock divider. This clock is derived from - * the system clock (SYSCLK). - * This parameter can be one of the following values: - * @arg RCC_SYSCLK_Div1: AHB clock = SYSCLK - * @arg RCC_SYSCLK_Div2: AHB clock = SYSCLK/2 - * @arg RCC_SYSCLK_Div4: AHB clock = SYSCLK/4 - * @arg RCC_SYSCLK_Div8: AHB clock = SYSCLK/8 - * @arg RCC_SYSCLK_Div16: AHB clock = SYSCLK/16 - * @arg RCC_SYSCLK_Div64: AHB clock = SYSCLK/64 - * @arg RCC_SYSCLK_Div128: AHB clock = SYSCLK/128 - * @arg RCC_SYSCLK_Div256: AHB clock = SYSCLK/256 - * @arg RCC_SYSCLK_Div512: AHB clock = SYSCLK/512 - * @retval None - */ -void RCC_HCLKConfig(uint32_t RCC_SYSCLK) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_HCLK(RCC_SYSCLK)); - - tmpreg = RCC->CFGR; - - /* Clear HPRE[3:0] bits */ - tmpreg &= ~RCC_CFGR_HPRE; - - /* Set HPRE[3:0] bits according to RCC_SYSCLK value */ - tmpreg |= RCC_SYSCLK; - - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -/** - * @brief Configures the Low Speed APB clock (PCLK1). - * @param RCC_HCLK: defines the APB1 clock divider. This clock is derived from - * the AHB clock (HCLK). - * This parameter can be one of the following values: - * @arg RCC_HCLK_Div1: APB1 clock = HCLK - * @arg RCC_HCLK_Div2: APB1 clock = HCLK/2 - * @arg RCC_HCLK_Div4: APB1 clock = HCLK/4 - * @arg RCC_HCLK_Div8: APB1 clock = HCLK/8 - * @arg RCC_HCLK_Div16: APB1 clock = HCLK/16 - * @retval None - */ -void RCC_PCLK1Config(uint32_t RCC_HCLK) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_PCLK(RCC_HCLK)); - - tmpreg = RCC->CFGR; - - /* Clear PPRE1[2:0] bits */ - tmpreg &= ~RCC_CFGR_PPRE1; - - /* Set PPRE1[2:0] bits according to RCC_HCLK value */ - tmpreg |= RCC_HCLK; - - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -/** - * @brief Configures the High Speed APB clock (PCLK2). - * @param RCC_HCLK: defines the APB2 clock divider. This clock is derived from - * the AHB clock (HCLK). - * This parameter can be one of the following values: - * @arg RCC_HCLK_Div1: APB2 clock = HCLK - * @arg RCC_HCLK_Div2: APB2 clock = HCLK/2 - * @arg RCC_HCLK_Div4: APB2 clock = HCLK/4 - * @arg RCC_HCLK_Div8: APB2 clock = HCLK/8 - * @arg RCC_HCLK_Div16: APB2 clock = HCLK/16 - * @retval None - */ -void RCC_PCLK2Config(uint32_t RCC_HCLK) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_PCLK(RCC_HCLK)); - - tmpreg = RCC->CFGR; - - /* Clear PPRE2[2:0] bits */ - tmpreg &= ~RCC_CFGR_PPRE2; - - /* Set PPRE2[2:0] bits according to RCC_HCLK value */ - tmpreg |= RCC_HCLK << 3; - - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -/** - * @brief Returns the frequencies of the System, AHB and APB busses clocks. - * @note - The frequency returned by this function is not the real frequency - * in the chip. It is calculated based on the predefined constant and - * the source selected by RCC_SYSCLKConfig(): - * - * - If SYSCLK source is MSI, function returns constant the MSI value - * as defined by the MSI range, refer to RCC_MSIRangeConfig() - * - * - If SYSCLK source is HSI, function returns constant HSI_VALUE(*) - * - * - If SYSCLK source is HSE, function returns constant HSE_VALUE(**) - * - * - If SYSCLK source is PLL, function returns constant 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, refer to RCC_AdjustHSICalibrationValue(). - * - * (**) 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 - * return wrong result. - * - * - The result of this function could be not correct when using fractional - * value for HSE crystal. - * - * @param RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold - * the clocks frequencies. - * @retval None - */ -void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks) -{ - uint32_t tmp = 0, pllmul = 0, plldiv = 0, pllsource = 0, presc = 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; - RCC_Clocks->SYSCLK_Frequency = (32768 * (1 << (msirange + 1))); - break; - case 0x04: /* HSI used as system clock */ - RCC_Clocks->SYSCLK_Frequency = HSI_VALUE; - break; - case 0x08: /* HSE used as system clock */ - RCC_Clocks->SYSCLK_Frequency = 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 source */ - RCC_Clocks->SYSCLK_Frequency = (((HSI_VALUE) * pllmul) / plldiv); - } - else - { - /* HSE selected as PLL clock source */ - RCC_Clocks->SYSCLK_Frequency = (((HSE_VALUE) * pllmul) / plldiv); - } - break; - default: /* MSI used as system clock */ - msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE ) >> 13; - RCC_Clocks->SYSCLK_Frequency = (32768 * (1 << (msirange + 1))); - break; - } - /* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*/ - /* Get HCLK prescaler */ - tmp = RCC->CFGR & RCC_CFGR_HPRE; - tmp = tmp >> 4; - presc = APBAHBPrescTable[tmp]; - /* HCLK clock frequency */ - RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc; - - /* Get PCLK1 prescaler */ - tmp = RCC->CFGR & RCC_CFGR_PPRE1; - tmp = tmp >> 8; - presc = APBAHBPrescTable[tmp]; - /* PCLK1 clock frequency */ - RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc; - - /* Get PCLK2 prescaler */ - tmp = RCC->CFGR & RCC_CFGR_PPRE2; - tmp = tmp >> 11; - presc = APBAHBPrescTable[tmp]; - /* PCLK2 clock frequency */ - RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc; -} - -/** - * @} - */ - -/** @defgroup RCC_Group3 Peripheral clocks configuration functions - * @brief Peripheral clocks configuration functions - * -@verbatim - =============================================================================== - Peripheral clocks configuration functions - =============================================================================== - - This section provide functions allowing to configure the Peripheral clocks. - - 1. The RTC/LCD clock which is derived from the LSE, LSI or 1 MHz HSE_RTC (HSE - divided by a programmable prescaler). - - 2. After restart from Reset or wakeup from STANDBY, all peripherals are off - except internal SRAM, Flash and JTAG. Before to start using a peripheral you - have to enable its interface clock. You can do this using RCC_AHBPeriphClockCmd() - , RCC_APB2PeriphClockCmd() and RCC_APB1PeriphClockCmd() functions. - - 3. To reset the peripherals configuration (to the default state after device reset) - you can use RCC_AHBPeriphResetCmd(), RCC_APB2PeriphResetCmd() and - RCC_APB1PeriphResetCmd() functions. - - 4. To further reduce power consumption in SLEEP mode the peripheral clocks can - be disabled prior to executing the WFI or WFE instructions. You can do this - using RCC_AHBPeriphClockLPModeCmd(), RCC_APB2PeriphClockLPModeCmd() and - RCC_APB1PeriphClockLPModeCmd() functions. - -@endverbatim - * @{ - */ - -/** - * @brief Configures the RTC and LCD clock (RTCCLK / LCDCLK). - * @note - As the RTC clock configuration bits are in the RTC domain and write - * access is denied to this domain after reset, you have to enable write - * access using PWR_RTCAccessCmd(ENABLE) function before to configure - * the RTC clock source (to be done once after reset). - * - Once the RTC clock is configured it can't be changed unless the RTC - * is reset using RCC_RTCResetCmd function, or by a Power On Reset (POR) - * - The RTC clock (RTCCLK) is used also to clock the LCD (LCDCLK). - * - * @param RCC_RTCCLKSource: specifies the RTC clock source. - * This parameter can be one of the following values: - * @arg RCC_RTCCLKSource_LSE: LSE selected as RTC clock - * @arg RCC_RTCCLKSource_LSI: LSI selected as RTC clock - * @arg RCC_RTCCLKSource_HSE_Div2: HSE divided by 2 selected as RTC clock - * @arg RCC_RTCCLKSource_HSE_Div4: HSE divided by 4 selected as RTC clock - * @arg RCC_RTCCLKSource_HSE_Div8: HSE divided by 8 selected as RTC clock - * @arg RCC_RTCCLKSource_HSE_Div16: HSE divided by 16 selected as RTC clock - * - * @note - If the LSE or LSI is used as RTC clock source, the RTC continues to - * work in STOP and STANDBY modes, and can be used as wakeup source. - * However, when the HSE clock is used as RTC clock source, the RTC - * cannot be used in STOP and STANDBY modes. - * - * - The maximum input clock frequency for RTC is 1MHz (when using HSE as - * RTC clock source). - * - * @retval None - */ -void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_RTCCLK_SOURCE(RCC_RTCCLKSource)); - - if ((RCC_RTCCLKSource & RCC_CSR_RTCSEL_HSE) == RCC_CSR_RTCSEL_HSE) - { - /* If HSE is selected as RTC clock source, configure HSE division factor for RTC clock */ - tmpreg = RCC->CR; - - /* Clear RTCPRE[1:0] bits */ - tmpreg &= ~RCC_CR_RTCPRE; - - /* Configure HSE division factor for RTC clock */ - tmpreg |= (RCC_RTCCLKSource & RCC_CR_RTCPRE); - - /* Store the new value */ - RCC->CR = tmpreg; - } - - RCC->CSR &= ~RCC_CSR_RTCSEL; - - /* Select the RTC clock source */ - RCC->CSR |= (RCC_RTCCLKSource & RCC_CSR_RTCSEL); -} - -/** - * @brief Enables or disables the RTC clock. - * @note This function must be used only after the RTC clock source was selected - * using the RCC_RTCCLKConfig function. - * @param NewState: new state of the RTC clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_RTCCLKCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CSR_RTCEN_BB = (uint32_t)NewState; -} - -/** - * @brief Forces or releases the RTC peripheral and associated resources reset. - * @note This function resets the RTC peripheral, RTC clock source selection - * (in RCC_CSR) and the backup registers. - * @param NewState: new state of the RTC reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_RTCResetCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CSR_RTCRST_BB = (uint32_t)NewState; -} - -/** - * @brief Enables or disables the AHB peripheral clock. - * @note After reset, the peripheral clock (used for registers read/write access) - * is disabled and the application software has to enable this clock before - * using it. - * @param RCC_AHBPeriph: specifies the AHB peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_AHBPeriph_GPIOA - * @arg RCC_AHBPeriph_GPIOB - * @arg RCC_AHBPeriph_GPIOC - * @arg RCC_AHBPeriph_GPIOD - * @arg RCC_AHBPeriph_GPIOE - * @arg RCC_AHBPeriph_GPIOH - * @arg RCC_AHBPeriph_CRC - * @arg RCC_AHBPeriph_FLITF (has effect only when the Flash memory is in power down mode) - * @arg RCC_AHBPeriph_DMA1 - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->AHBENR |= RCC_AHBPeriph; - } - else - { - RCC->AHBENR &= ~RCC_AHBPeriph; - } -} - -/** - * @brief Enables or disables the High Speed APB (APB2) peripheral clock. - * @note After reset, the peripheral clock (used for registers read/write access) - * is disabled and the application software has to enable this clock before - * using it. - * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_APB2Periph_SYSCFG - * @arg RCC_APB2Periph_TIM9 - * @arg RCC_APB2Periph_TIM10 - * @arg RCC_APB2Periph_TIM11 - * @arg RCC_APB2Periph_ADC1 - * @arg RCC_APB2Periph_SPI1 - * @arg RCC_APB2Periph_USART1 - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->APB2ENR |= RCC_APB2Periph; - } - else - { - RCC->APB2ENR &= ~RCC_APB2Periph; - } -} - -/** - * @brief Enables or disables the Low Speed APB (APB1) peripheral clock. - * @note After reset, the peripheral clock (used for registers read/write access) - * is disabled and the application software has to enable this clock before - * using it. - * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_APB1Periph_TIM2 - * @arg RCC_APB1Periph_TIM3 - * @arg RCC_APB1Periph_TIM4 - * @arg RCC_APB1Periph_TIM6 - * @arg RCC_APB1Periph_TIM7 - * @arg RCC_APB1Periph_LCD - * @arg RCC_APB1Periph_WWDG - * @arg RCC_APB1Periph_SPI2 - * @arg RCC_APB1Periph_USART2 - * @arg RCC_APB1Periph_USART3 - * @arg RCC_APB1Periph_I2C1 - * @arg RCC_APB1Periph_I2C2 - * @arg RCC_APB1Periph_USB - * @arg RCC_APB1Periph_PWR - * @arg RCC_APB1Periph_DAC - * @arg RCC_APB1Periph_COMP - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->APB1ENR |= RCC_APB1Periph; - } - else - { - RCC->APB1ENR &= ~RCC_APB1Periph; - } -} - -/** - * @brief Forces or releases AHB peripheral reset. - * @param RCC_AHBPeriph: specifies the AHB peripheral to reset. - * This parameter can be any combination of the following values: - * @arg RCC_AHBPeriph_GPIOA - * @arg RCC_AHBPeriph_GPIOB - * @arg RCC_AHBPeriph_GPIOC - * @arg RCC_AHBPeriph_GPIOD - * @arg RCC_AHBPeriph_GPIOE - * @arg RCC_AHBPeriph_GPIOH - * @arg RCC_AHBPeriph_CRC - * @arg RCC_AHBPeriph_FLITF (has effect only when the Flash memory is in power down mode) - * @arg RCC_AHBPeriph_DMA1 - * @param NewState: new state of the specified peripheral reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->AHBRSTR |= RCC_AHBPeriph; - } - else - { - RCC->AHBRSTR &= ~RCC_AHBPeriph; - } -} - -/** - * @brief Forces or releases High Speed APB (APB2) peripheral reset. - * @param RCC_APB2Periph: specifies the APB2 peripheral to reset. - * This parameter can be any combination of the following values: - * @arg RCC_APB2Periph_SYSCFG - * @arg RCC_APB2Periph_TIM9 - * @arg RCC_APB2Periph_TIM10 - * @arg RCC_APB2Periph_TIM11 - * @arg RCC_APB2Periph_ADC1 - * @arg RCC_APB2Periph_SPI1 - * @arg RCC_APB2Periph_USART1 - * @param NewState: new state of the specified peripheral reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->APB2RSTR |= RCC_APB2Periph; - } - else - { - RCC->APB2RSTR &= ~RCC_APB2Periph; - } -} - -/** - * @brief Forces or releases Low Speed APB (APB1) peripheral reset. - * @param RCC_APB1Periph: specifies the APB1 peripheral to reset. - * This parameter can be any combination of the following values: - * @arg RCC_APB1Periph_TIM2 - * @arg RCC_APB1Periph_TIM3 - * @arg RCC_APB1Periph_TIM4 - * @arg RCC_APB1Periph_TIM6 - * @arg RCC_APB1Periph_TIM7 - * @arg RCC_APB1Periph_LCD - * @arg RCC_APB1Periph_WWDG - * @arg RCC_APB1Periph_SPI2 - * @arg RCC_APB1Periph_USART2 - * @arg RCC_APB1Periph_USART3 - * @arg RCC_APB1Periph_I2C1 - * @arg RCC_APB1Periph_I2C2 - * @arg RCC_APB1Periph_USB - * @arg RCC_APB1Periph_PWR - * @arg RCC_APB1Periph_DAC - * @arg RCC_APB1Periph_COMP - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->APB1RSTR |= RCC_APB1Periph; - } - else - { - RCC->APB1RSTR &= ~RCC_APB1Periph; - } -} - -/** - * @brief Enables or disables the AHB peripheral clock during SLEEP mode. - * @note - Peripheral clock gating in SLEEP mode can be used to further reduce - * power consumption. - * - After wakeup from SLEEP mode, the peripheral clock is enabled again. - * - By default, all peripheral clocks are enabled during SLEEP mode. - * @param RCC_AHBPeriph: specifies the AHB peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_AHBPeriph_GPIOA - * @arg RCC_AHBPeriph_GPIOB - * @arg RCC_AHBPeriph_GPIOC - * @arg RCC_AHBPeriph_GPIOD - * @arg RCC_AHBPeriph_GPIOE - * @arg RCC_AHBPeriph_GPIOH - * @arg RCC_AHBPeriph_CRC - * @arg RCC_AHBPeriph_FLITF (has effect only when the Flash memory is in power down mode) - * @arg RCC_AHBPeriph_SRAM - * @arg RCC_AHBPeriph_DMA1 - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_AHBPeriphClockLPModeCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_AHB_LPMODE_PERIPH(RCC_AHBPeriph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->AHBLPENR |= RCC_AHBPeriph; - } - else - { - RCC->AHBLPENR &= ~RCC_AHBPeriph; - } -} - -/** - * @brief Enables or disables the APB2 peripheral clock during SLEEP mode. - * @note - Peripheral clock gating in SLEEP mode can be used to further reduce - * power consumption. - * - After wakeup from SLEEP mode, the peripheral clock is enabled again. - * - By default, all peripheral clocks are enabled during SLEEP mode. - * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_APB2Periph_SYSCFG - * @arg RCC_APB2Periph_TIM9 - * @arg RCC_APB2Periph_TIM10 - * @arg RCC_APB2Periph_TIM11 - * @arg RCC_APB2Periph_ADC1 - * @arg RCC_APB2Periph_SPI1 - * @arg RCC_APB2Periph_USART1 - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->APB2LPENR |= RCC_APB2Periph; - } - else - { - RCC->APB2LPENR &= ~RCC_APB2Periph; - } -} - -/** - * @brief Enables or disables the APB1 peripheral clock during SLEEP mode. - * @note - Peripheral clock gating in SLEEP mode can be used to further reduce - * power consumption. - * - After wakeup from SLEEP mode, the peripheral clock is enabled again. - * - By default, all peripheral clocks are enabled during SLEEP mode. - * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_APB1Periph_TIM2 - * @arg RCC_APB1Periph_TIM3 - * @arg RCC_APB1Periph_TIM4 - * @arg RCC_APB1Periph_TIM6 - * @arg RCC_APB1Periph_TIM7 - * @arg RCC_APB1Periph_LCD - * @arg RCC_APB1Periph_WWDG - * @arg RCC_APB1Periph_SPI2 - * @arg RCC_APB1Periph_USART2 - * @arg RCC_APB1Periph_USART3 - * @arg RCC_APB1Periph_I2C1 - * @arg RCC_APB1Periph_I2C2 - * @arg RCC_APB1Periph_USB - * @arg RCC_APB1Periph_PWR - * @arg RCC_APB1Periph_DAC - * @arg RCC_APB1Periph_COMP - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->APB1LPENR |= RCC_APB1Periph; - } - else - { - RCC->APB1LPENR &= ~RCC_APB1Periph; - } -} - -/** - * @} - */ - -/** @defgroup RCC_Group4 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified RCC interrupts. - * @note The CSS interrupt doesn't have an enable bit; once the CSS is enabled - * and if the HSE clock fails, the CSS interrupt occurs and an NMI is - * automatically generated. The NMI will be executed indefinitely, and - * since NMI has higher priority than any other IRQ (and main program) - * the application will be stacked in the NMI ISR unless the CSS interrupt - * pending bit is cleared. - * @param RCC_IT: specifies the RCC interrupt sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg RCC_IT_LSIRDY: LSI ready interrupt - * @arg RCC_IT_LSERDY: LSE ready interrupt - * @arg RCC_IT_HSIRDY: HSI ready interrupt - * @arg RCC_IT_HSERDY: HSE ready interrupt - * @arg RCC_IT_PLLRDY: PLL ready interrupt - * @arg RCC_IT_MSIRDY: MSI ready interrupt - * @param NewState: new state of the specified RCC interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_IT(RCC_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Perform Byte access to RCC_CIR[12:8] bits to enable the selected interrupts */ - *(__IO uint8_t *) CIR_BYTE2_ADDRESS |= RCC_IT; - } - else - { - /* Perform Byte access to RCC_CIR[12:8] bits to disable the selected interrupts */ - *(__IO uint8_t *) CIR_BYTE2_ADDRESS &= (uint8_t)~RCC_IT; - } -} - -/** - * @brief Checks whether the specified RCC flag is set or not. - * @param RCC_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready - * @arg RCC_FLAG_MSIRDY: MSI oscillator clock ready - * @arg RCC_FLAG_HSERDY: HSE oscillator clock ready - * @arg RCC_FLAG_PLLRDY: PLL clock ready - * @arg RCC_FLAG_LSERDY: LSE oscillator clock ready - * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready - * @arg RCC_FLAG_OBLRST: Option Byte Loader (OBL) reset - * @arg RCC_FLAG_PINRST: Pin reset - * @arg RCC_FLAG_PORRST: POR/PDR reset - * @arg RCC_FLAG_SFTRST: Software reset - * @arg RCC_FLAG_IWDGRST: Independent Watchdog reset - * @arg RCC_FLAG_WWDGRST: Window Watchdog reset - * @arg RCC_FLAG_LPWRRST: Low Power reset - * @retval The new state of RCC_FLAG (SET or RESET). - */ -FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG) -{ - uint32_t tmp = 0; - uint32_t statusreg = 0; - FlagStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_RCC_FLAG(RCC_FLAG)); - - /* Get the RCC register index */ - tmp = RCC_FLAG >> 5; - - if (tmp == 1) /* The flag to check is in CR register */ - { - statusreg = RCC->CR; - } - else /* The flag to check is in CSR register (tmp == 2) */ - { - statusreg = RCC->CSR; - } - - /* Get the flag position */ - tmp = RCC_FLAG & FLAG_MASK; - - if ((statusreg & ((uint32_t)1 << tmp)) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the flag status */ - return bitstatus; -} - -/** - * @brief Clears the RCC reset flags. - * The reset flags are: RCC_FLAG_OBLRST, RCC_FLAG_PINRST, RCC_FLAG_PORRST, - * RCC_FLAG_SFTRST, RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST. - * @param None - * @retval None - */ -void RCC_ClearFlag(void) -{ - /* Set RMVF bit to clear the reset flags */ - RCC->CSR |= RCC_CSR_RMVF; -} - -/** - * @brief Checks whether the specified RCC interrupt has occurred or not. - * @param RCC_IT: specifies the RCC interrupt source to check. - * This parameter can be one of the following values: - * @arg RCC_IT_LSIRDY: LSI ready interrupt - * @arg RCC_IT_LSERDY: LSE ready interrupt - * @arg RCC_IT_HSIRDY: HSI ready interrupt - * @arg RCC_IT_HSERDY: HSE ready interrupt - * @arg RCC_IT_PLLRDY: PLL ready interrupt - * @arg RCC_IT_MSIRDY: MSI ready interrupt - * @arg RCC_IT_CSS: Clock Security System interrupt - * @retval The new state of RCC_IT (SET or RESET). - */ -ITStatus RCC_GetITStatus(uint8_t RCC_IT) -{ - ITStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_RCC_GET_IT(RCC_IT)); - - /* Check the status of the specified RCC interrupt */ - if ((RCC->CIR & RCC_IT) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the RCC_IT status */ - return bitstatus; -} - -/** - * @brief Clears the RCC's interrupt pending bits. - * @param RCC_IT: specifies the interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg RCC_IT_LSIRDY: LSI ready interrupt - * @arg RCC_IT_LSERDY: LSE ready interrupt - * @arg RCC_IT_HSIRDY: HSI ready interrupt - * @arg RCC_IT_HSERDY: HSE ready interrupt - * @arg RCC_IT_PLLRDY: PLL ready interrupt - * @arg RCC_IT_MSIRDY: MSI ready interrupt - * @arg RCC_IT_CSS: Clock Security System interrupt - * @retval None - */ -void RCC_ClearITPendingBit(uint8_t RCC_IT) -{ - /* Check the parameters */ - assert_param(IS_RCC_CLEAR_IT(RCC_IT)); - - /* Perform Byte access to RCC_CIR[23:16] bits to clear the selected interrupt - pending bits */ - *(__IO uint8_t *) CIR_BYTE3_ADDRESS = RCC_IT; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_rtc.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_rtc.c deleted file mode 100644 index fbcf67997..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_rtc.c +++ /dev/null @@ -1,2138 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_rtc.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the Real-Time Clock (RTC) peripheral: - * - Initialization - * - Calendar (Time and Date) configuration - * - Alarms (Alarm A and Alarm B) configuration - * - WakeUp Timer configuration - * - Daylight Saving configuration - * - Output pin Configuration - * - Digital Calibration configuration - * - TimeStamp configuration - * - Tampers configuration - * - Backup Data Registers configuration - * - Output Type Config configuration - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * RTC Domain Reset - * =================================================================== - * After power-on reset, the RTC domain (RTC clock source configuration, - * RTC registers and RTC Backup data registers) is reset. You can also - * reset this domain by software using the RCC_RTCResetCmd() function. - * - * =================================================================== - * RTC Operating Condition - * =================================================================== - * As long as the supply voltage remains in the operating range, - * the RTC never stops, regardless of the device status (Run mode, - * low power modes or under reset). - * - * =================================================================== - * RTC Domain Access - * =================================================================== - * After reset, the RTC domain (RTC clock source configuration, - * RTC registers and RTC Backup data registers) are protected against - * possible stray write accesses. - * To enable access to the RTC Domain and RTC registers, proceed as follows: - * - Enable the Power Controller (PWR) APB1 interface clock using the - * RCC_APB1PeriphClockCmd() function. - * - Enable access to RTC domain using the PWR_RTCAccessCmd() function. - * - Select the RTC clock source using the RCC_RTCCLKConfig() function. - * - Enable RTC Clock using the RCC_RTCCLKCmd() function. - * - * =================================================================== - * RTC Driver: how to use it - * =================================================================== - * - Enable the RTC domain access (see description in the section above) - * - Configure the RTC Prescaler (Asynchronous and Synchronous) and - * RTC hour format using the RTC_Init() function. - * - * Time and Date configuration - * =========================== - * - To configure the RTC Calendar (Time and Date) use the RTC_SetTime() - * and RTC_SetDate() functions. - * - To read the RTC Calendar, use the RTC_GetTime() and RTC_GetDate() - * functions. - * - Use the RTC_DayLightSavingConfig() function to add or sub one - * hour to the RTC Calendar. - * - * Alarm configuration - * =================== - * - To configure the RTC Alarm use the RTC_SetAlarm() function. - * - Enable the selected RTC Alarm using the RTC_AlarmCmd() function - * - To read the RTC Alarm, use the RTC_GetAlarm() function. - * - * RTC Wakeup configuration - * ======================== - * - Configure the RTC Wakeup Clock source use the RTC_WakeUpClockConfig() - * function. - * - Configure the RTC WakeUp Counter using the RTC_SetWakeUpCounter() - * function - * - Enable the RTC WakeUp using the RTC_WakeUpCmd() function - * - To read the RTC WakeUp Counter register, use the RTC_GetWakeUpCounter() - * function. - * - * Outputs configuration - * ===================== - * The RTC has 2 different outputs: - * - AFO_ALARM: this output is used to manage the RTC Alarm A, Alarm B - * and WaKeUp signals. - * To output the selected RTC signal on RTC_AF1 pin, use the - * RTC_OutputConfig() function. - * - AFO_CALIB: this output is used to manage the RTC Clock divided - * by 64 (512Hz) signal. - * To output the RTC Clock on RTC_AF1 pin, use the RTC_CalibOutputCmd() - * function. - * - * Digital Calibration configuration - * ================================= - * - Configure the RTC Digital Calibration Value and the corresponding - * sign using the RTC_DigitalCalibConfig() function. - * - Enable the RTC Digital Calibration using the RTC_DigitalCalibCmd() - * function - * - * TimeStamp configuration - * ======================= - * - Configure the RTC_AF1 trigger and enables the RTC TimeStamp - * using the RTC_TimeStampCmd() function. - * - To read the RTC TimeStamp Time and Date register, use the - * RTC_GetTimeStamp() function. - * - * Tamper configuration - * ==================== - * - Configure the RTC Tamper trigger using the RTC_TamperConfig() - * function. - * - Enable the RTC Tamper using the RTC_TamperCmd() function. - * - * Backup Data Registers configuration - * =================================== - * - To write to the RTC Backup Data registers, use the RTC_WriteBackupRegister() - * function. - * - To read the RTC Backup Data registers, use the RTC_ReadBackupRegister() - * function. - * - * =================================================================== - * RTC and low power modes - * =================================================================== - * The MCU can be woken up from a low power mode by an RTC alternate - * function. - * The RTC alternate functions are the RTC alarms (Alarm A and Alarm B), - * RTC wakeup, RTC tamper event detection and RTC time stamp event detection. - * These RTC alternate functions can wake up the system from the Stop - * and Standby lowpower modes. - * The system can also wake up from low power modes without depending - * on an external interrupt (Auto-wakeup mode), by using the RTC alarm - * or the RTC wakeup events. - * The RTC provides a programmable time base for waking up from the - * Stop or Standby mode at regular intervals. - * Wakeup from STOP and Standby modes is possible only when the RTC - * clock source is LSE or LSI. - * - * =================================================================== - * Selection of RTC_AF1 alternate functions - * =================================================================== - * The RTC_AF1 pin (PC13) can be used for the following purposes: - * - Wakeup pin 2 (WKUP2) using the PWR_WakeUpPinCmd() function. - * - AFO_ALARM output - * - AFO_CALIB output - * - AFI_TAMPER - * - AFI_TIMESTAMP - * - * +------------------------------------------------------------------------------------------+ - * | Pin |AFO_ALARM |AFO_CALIB |AFI_TAMPER |AFI_TIMESTAMP | WKUP2 |ALARMOUTTYPE | - * | configuration | ENABLED | ENABLED | ENABLED | ENABLED |ENABLED | AFO_ALARM | - * | and function | | | | | |Configuration | - * |-----------------|----------|----------|-----------|--------------|--------|--------------| - * | Alarm out | | | | | Don't | | - * | output OD | 1 | 0 |Don't care | Don't care | care | 0 | - * |-----------------|----------|----------|-----------|--------------|--------|--------------| - * | Alarm out | | | | | Don't | | - * | output PP | 1 | 0 |Don't care | Don't care | care | 1 | - * |-----------------|----------|----------|-----------|--------------|--------|--------------| - * | Calibration out | | | | | Don't | | - * | output PP | 0 | 1 |Don't care | Don't care | care | Don't care | - * |-----------------|----------|----------|-----------|--------------|--------|--------------| - * | TAMPER input | | | | | Don't | | - * | floating | 0 | 0 | 1 | 0 | care | Don't care | - * |-----------------|----------|----------|-----------|--------------|--------|--------------| - * | TIMESTAMP and | | | | | Don't | | - * | TAMPER input | 0 | 0 | 1 | 1 | care | Don't care | - * | floating | | | | | | | - * |-----------------|----------|----------|-----------|--------------|--------|--------------| - * | TIMESTAMP input | | | | | Don't | | - * | floating | 0 | 0 | 0 | 1 | care | Don't care | - * |-----------------|----------|----------|-----------|--------------|--------|--------------| - * | Wakeup Pin 2 | 0 | 0 | 0 | 0 | 1 | Don't care | - * |-----------------|----------|----------|-----------|--------------|--------|--------------| - * | Standard GPIO | 0 | 0 | 0 | 0 | 0 | Don't care | - * +------------------------------------------------------------------------------------------+ - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_rtc.h" -#include "stm32l1xx_rcc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup RTC - * @brief RTC driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* Masks Definition */ -#define RTC_TR_RESERVED_MASK ((uint32_t)0x007F7F7F) -#define RTC_DR_RESERVED_MASK ((uint32_t)0x00FFFF3F) -#define RTC_INIT_MASK ((uint32_t)0xFFFFFFFF) -#define RTC_RSF_MASK ((uint32_t)0xFFFFFF5F) -#define RTC_FLAGS_MASK ((uint32_t)(RTC_FLAG_TSOVF | RTC_FLAG_TSF | RTC_FLAG_WUTF | \ - RTC_FLAG_ALRBF | RTC_FLAG_ALRAF | RTC_FLAG_INITF | \ - RTC_FLAG_RSF | RTC_FLAG_INITS | RTC_FLAG_WUTWF | \ - RTC_FLAG_ALRBWF | RTC_FLAG_ALRAWF | RTC_FLAG_TAMP1F )) - -#define INITMODE_TIMEOUT ((uint32_t) 0x00002000) -#define SYNCHRO_TIMEOUT ((uint32_t) 0x00001000) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -static uint8_t RTC_ByteToBcd2(uint8_t Value); -static uint8_t RTC_Bcd2ToByte(uint8_t Value); - -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup RTC_Private_Functions - * @{ - */ - -/** @defgroup RTC_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - - This section provide functions allowing to initialize and configure the RTC - Prescaler (Synchronous and Asynchronous), RTC Hour format, disable RTC registers - Write protection, enter and exit the RTC initialization mode, RTC registers - synchronization check and reference clock detection enable. - - 1. The RTC Prescaler is programmed to generate the RTC 1Hz time base. It is - split into 2 programmable prescalers to minimize power consumption. - - A 7-bit asynchronous prescaler and A 13-bit synchronous prescaler. - - When both prescalers are used, it is recommended to configure the asynchronous - prescaler to a high value to minimize consumption. - - 2. All RTC registers are Write protected. Writing to the RTC registers - is enabled by writing a key into the Write Protection register, RTC_WPR. - - 3. To Configure the RTC Calendar, user application should enter initialization - mode. In this mode, the calendar counter is stopped and its value can be - updated. When the initialization sequence is complete, the calendar restarts - counting after 4 RTCCLK cycles. - - 4. To read the calendar through the shadow registers after Calendar initialization, - calendar update or after wakeup from low power modes the software must first - clear the RSF flag. The software must then wait until it is set again before - reading the calendar, which means that the calendar registers have been - correctly copied into the RTC_TR and RTC_DR shadow registers. - The RTC_WaitForSynchro() function implements the above software sequence - (RSF clear and RSF check). - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the RTC registers to their default reset values. - * @note This function doesn't reset the RTC Clock source and RTC Backup Data - * registers. - * @param None - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC registers are deinitialized - * - ERROR: RTC registers are not deinitialized - */ -ErrorStatus RTC_DeInit(void) -{ - __IO uint32_t wutcounter = 0x00; - uint32_t wutwfstatus = 0x00; - ErrorStatus status = ERROR; - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Set Initialization mode */ - if (RTC_EnterInitMode() == ERROR) - { - status = ERROR; - } - else - { - /* Reset TR, DR and CR registers */ - RTC->TR = (uint32_t)0x00000000; - RTC->DR = (uint32_t)0x00002101; - /* Reset All CR bits except CR[2:0] */ - RTC->CR &= (uint32_t)0x00000007; - - /* Wait till RTC WUTWF flag is set and if Time out is reached exit */ - do - { - wutwfstatus = RTC->ISR & RTC_ISR_WUTWF; - wutcounter++; - } while((wutcounter != INITMODE_TIMEOUT) && (wutwfstatus == 0x00)); - - if ((RTC->ISR & RTC_ISR_WUTWF) == RESET) - { - status = ERROR; - } - else - { - /* Reset all RTC CR register bits */ - RTC->CR &= (uint32_t)0x00000000; - RTC->WUTR = (uint32_t)0x0000FFFF; - RTC->PRER = (uint32_t)0x007F00FF; - RTC->CALIBR = (uint32_t)0x00000000; - RTC->ALRMAR = (uint32_t)0x00000000; - RTC->ALRMBR = (uint32_t)0x00000000; - - /* Reset ISR register and exit initialization mode */ - RTC->ISR = (uint32_t)0x00000000; - - /* Reset Tamper and alternate functions configuration register */ - RTC->TAFCR = 0x00000000; - - if(RTC_WaitForSynchro() == ERROR) - { - status = ERROR; - } - else - { - status = SUCCESS; - } - } - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @brief Initializes the RTC registers according to the specified parameters - * in RTC_InitStruct. - * @param RTC_InitStruct: pointer to a RTC_InitTypeDef structure that contains - * the configuration information for the RTC peripheral. - * @note The RTC Prescaler register is write protected and can be written in - * initialization mode only. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC registers are initialized - * - ERROR: RTC registers are not initialized - */ -ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct) -{ - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_RTC_HOUR_FORMAT(RTC_InitStruct->RTC_HourFormat)); - assert_param(IS_RTC_ASYNCH_PREDIV(RTC_InitStruct->RTC_AsynchPrediv)); - assert_param(IS_RTC_SYNCH_PREDIV(RTC_InitStruct->RTC_SynchPrediv)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Set Initialization mode */ - if (RTC_EnterInitMode() == ERROR) - { - status = ERROR; - } - else - { - /* Clear RTC CR FMT Bit */ - RTC->CR &= ((uint32_t)~(RTC_CR_FMT)); - /* Set RTC_CR register */ - RTC->CR |= ((uint32_t)(RTC_InitStruct->RTC_HourFormat)); - - /* Configure the RTC PRER */ - RTC->PRER = (uint32_t)(RTC_InitStruct->RTC_SynchPrediv); - RTC->PRER |= (uint32_t)(RTC_InitStruct->RTC_AsynchPrediv << 16); - - /* Exit Initialization mode */ - RTC_ExitInitMode(); - - status = SUCCESS; - } - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @brief Fills each RTC_InitStruct member with its default value. - * @param RTC_InitStruct: pointer to a RTC_InitTypeDef structure which will be - * initialized. - * @retval None - */ -void RTC_StructInit(RTC_InitTypeDef* RTC_InitStruct) -{ - /* Initialize the RTC_HourFormat member */ - RTC_InitStruct->RTC_HourFormat = RTC_HourFormat_24; - - /* Initialize the RTC_AsynchPrediv member */ - RTC_InitStruct->RTC_AsynchPrediv = (uint32_t)0x7F; - - /* Initialize the RTC_SynchPrediv member */ - RTC_InitStruct->RTC_SynchPrediv = (uint32_t)0xFF; -} - -/** - * @brief Enables or disables the RTC registers write protection. - * @note All the RTC registers are write protected except for RTC_ISR[13:8], - * RTC_TAFCR and RTC_BKPxR. - * @note Writing a wrong key reactivates the write protection. - * @note The protection mechanism is not affected by system reset. - * @param NewState: new state of the write protection. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RTC_WriteProtectionCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - } - else - { - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - } -} - -/** - * @brief Enters the RTC Initialization mode. - * @note The RTC Initialization mode is write protected, use the - * RTC_WriteProtectionCmd(DISABLE) before calling this function. - * @param None - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC is in Init mode - * - ERROR: RTC is not in Init mode - */ -ErrorStatus RTC_EnterInitMode(void) -{ - __IO uint32_t initcounter = 0x00; - ErrorStatus status = ERROR; - uint32_t initstatus = 0x00; - - /* Check if the Initialization mode is set */ - if ((RTC->ISR & RTC_ISR_INITF) == (uint32_t)RESET) - { - /* Set the Initialization mode */ - RTC->ISR = (uint32_t)RTC_INIT_MASK; - - /* Wait till RTC is in INIT state and if Time out is reached exit */ - do - { - initstatus = RTC->ISR & RTC_ISR_INITF; - initcounter++; - } while((initcounter != INITMODE_TIMEOUT) && (initstatus == 0x00)); - - if ((RTC->ISR & RTC_ISR_INITF) != RESET) - { - status = SUCCESS; - } - else - { - status = ERROR; - } - } - else - { - status = SUCCESS; - } - - return (status); -} - -/** - * @brief Exits the RTC Initialization mode. - * @note When the initialization sequence is complete, the calendar restarts - * counting after 4 RTCCLK cycles. - * @note The RTC Initialization mode is write protected, use the - * RTC_WriteProtectionCmd(DISABLE) before calling this function. - * @param None - * @retval None - */ -void RTC_ExitInitMode(void) -{ - /* Exit Initialization mode */ - RTC->ISR &= (uint32_t)~RTC_ISR_INIT; -} - -/** - * @brief Waits until the RTC Time and Date registers (RTC_TR and RTC_DR) are - * synchronized with RTC APB clock. - * @note The RTC Resynchronization mode is write protected, use the - * RTC_WriteProtectionCmd(DISABLE) before calling this function. - * @note To read the calendar through the shadow registers after Calendar - * initialization, calendar update or after wakeup from low power modes - * the software must first clear the RSF flag. - * The software must then wait until it is set again before reading - * the calendar, which means that the calendar registers have been - * correctly copied into the RTC_TR and RTC_DR shadow registers. - * @param None - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC registers are synchronised - * - ERROR: RTC registers are not synchronised - */ -ErrorStatus RTC_WaitForSynchro(void) -{ - __IO uint32_t synchrocounter = 0; - ErrorStatus status = ERROR; - uint32_t synchrostatus = 0x00; - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Clear RSF flag */ - RTC->ISR &= (uint32_t)RTC_RSF_MASK; - - /* Wait the registers to be synchronised */ - do - { - synchrostatus = RTC->ISR & RTC_ISR_RSF; - synchrocounter++; - } while((synchrocounter != SYNCHRO_TIMEOUT) && (synchrostatus == 0x00)); - - if ((RTC->ISR & RTC_ISR_RSF) != RESET) - { - status = SUCCESS; - } - else - { - status = ERROR; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return (status); -} - -/** - * @brief Enables or disables the RTC reference clock detection. - * @param NewState: new state of the RTC reference clock. - * This parameter can be: ENABLE or DISABLE. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC reference clock detection is enabled - * - ERROR: RTC reference clock detection is disabled - */ -ErrorStatus RTC_RefClockCmd(FunctionalState NewState) -{ - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Set Initialization mode */ - if (RTC_EnterInitMode() == ERROR) - { - status = ERROR; - } - else - { - if (NewState != DISABLE) - { - /* Enable the RTC reference clock detection */ - RTC->CR |= RTC_CR_REFCKON; - } - else - { - /* Disable the RTC reference clock detection */ - RTC->CR &= ~RTC_CR_REFCKON; - } - /* Exit Initialization mode */ - RTC_ExitInitMode(); - - status = SUCCESS; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @} - */ - -/** @defgroup RTC_Group2 Time and Date configuration functions - * @brief Time and Date configuration functions - * -@verbatim - =============================================================================== - Time and Date configuration functions - =============================================================================== - - This section provide functions allowing to program and read the RTC Calendar - (Time and Date). - -@endverbatim - * @{ - */ - -/** - * @brief Set the RTC current time. - * @param RTC_Format: specifies the format of the entered parameters. - * This parameter can be one of the following values: - * @arg RTC_Format_BIN: Binary data format - * @arg RTC_Format_BCD: BCD data format - * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure that contains - * the time configuration information for the RTC. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC Time register is configured - * - ERROR: RTC Time register is not configured - */ -ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct) -{ - uint32_t tmpreg = 0; - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_RTC_FORMAT(RTC_Format)); - - if (RTC_Format == RTC_Format_BIN) - { - if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) - { - assert_param(IS_RTC_HOUR12(RTC_TimeStruct->RTC_Hours)); - assert_param(IS_RTC_H12(RTC_TimeStruct->RTC_H12)); - } - else - { - RTC_TimeStruct->RTC_H12 = 0x00; - assert_param(IS_RTC_HOUR24(RTC_TimeStruct->RTC_Hours)); - } - assert_param(IS_RTC_MINUTES(RTC_TimeStruct->RTC_Minutes)); - assert_param(IS_RTC_SECONDS(RTC_TimeStruct->RTC_Seconds)); - } - else - { - if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) - { - tmpreg = RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours); - assert_param(IS_RTC_HOUR12(tmpreg)); - assert_param(IS_RTC_H12(RTC_TimeStruct->RTC_H12)); - } - else - { - RTC_TimeStruct->RTC_H12 = 0x00; - assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours))); - } - assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes))); - assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds))); - } - - /* Check the input parameters format */ - if (RTC_Format != RTC_Format_BIN) - { - tmpreg = (((uint32_t)(RTC_TimeStruct->RTC_Hours) << 16) | \ - ((uint32_t)(RTC_TimeStruct->RTC_Minutes) << 8) | \ - ((uint32_t)RTC_TimeStruct->RTC_Seconds) | \ - ((uint32_t)(RTC_TimeStruct->RTC_H12) << 16)); - } - else - { - tmpreg = (uint32_t)(((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Hours) << 16) | \ - ((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Minutes) << 8) | \ - ((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Seconds)) | \ - (((uint32_t)RTC_TimeStruct->RTC_H12) << 16)); - } - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Set Initialization mode */ - if (RTC_EnterInitMode() == ERROR) - { - status = ERROR; - } - else - { - /* Set the RTC_TR register */ - RTC->TR = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK); - - /* Exit Initialization mode */ - RTC_ExitInitMode(); - - if(RTC_WaitForSynchro() == ERROR) - { - status = ERROR; - } - else - { - status = SUCCESS; - } - - } - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @brief Fills each RTC_TimeStruct member with its default value - * (Time = 00h:00min:00sec). - * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure which will be - * initialized. - * @retval None - */ -void RTC_TimeStructInit(RTC_TimeTypeDef* RTC_TimeStruct) -{ - /* Time = 00h:00min:00sec */ - RTC_TimeStruct->RTC_H12 = RTC_H12_AM; - RTC_TimeStruct->RTC_Hours = 0; - RTC_TimeStruct->RTC_Minutes = 0; - RTC_TimeStruct->RTC_Seconds = 0; -} - -/** - * @brief Get the RTC current Time. - * @param RTC_Format: specifies the format of the returned parameters. - * This parameter can be one of the following values: - * @arg RTC_Format_BIN: Binary data format - * @arg RTC_Format_BCD: BCD data format - * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure that will - * contain the returned current time configuration. - * @retval None - */ -void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_FORMAT(RTC_Format)); - - /* Get the RTC_TR register */ - tmpreg = (uint32_t)(RTC->TR & RTC_TR_RESERVED_MASK); - - /* Fill the structure fields with the read parameters */ - RTC_TimeStruct->RTC_Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16); - RTC_TimeStruct->RTC_Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8); - RTC_TimeStruct->RTC_Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU)); - RTC_TimeStruct->RTC_H12 = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 16); - - /* Check the input parameters format */ - if (RTC_Format == RTC_Format_BIN) - { - /* Convert the structure parameters to Binary format */ - RTC_TimeStruct->RTC_Hours = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours); - RTC_TimeStruct->RTC_Minutes = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes); - RTC_TimeStruct->RTC_Seconds = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds); - } -} - -/** - * @brief Set the RTC current date. - * @param RTC_Format: specifies the format of the entered parameters. - * This parameter can be one of the following values: - * @arg RTC_Format_BIN: Binary data format - * @arg RTC_Format_BCD: BCD data format - * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure that contains - * the date configuration information for the RTC. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC Date register is configured - * - ERROR: RTC Date register is not configured - */ -ErrorStatus RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct) -{ - uint32_t tmpreg = 0; - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_RTC_FORMAT(RTC_Format)); - - if ((RTC_Format == RTC_Format_BIN) && ((RTC_DateStruct->RTC_Month & 0x10) == 0x10)) - { - RTC_DateStruct->RTC_Month = (RTC_DateStruct->RTC_Month & (uint32_t)~(0x10)) + 0x0A; - } - if (RTC_Format == RTC_Format_BIN) - { - assert_param(IS_RTC_YEAR(RTC_DateStruct->RTC_Year)); - assert_param(IS_RTC_MONTH(RTC_DateStruct->RTC_Month)); - assert_param(IS_RTC_DATE(RTC_DateStruct->RTC_Date)); - } - else - { - assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(RTC_DateStruct->RTC_Year))); - tmpreg = RTC_Bcd2ToByte(RTC_DateStruct->RTC_Month); - assert_param(IS_RTC_MONTH(tmpreg)); - tmpreg = RTC_Bcd2ToByte(RTC_DateStruct->RTC_Date); - assert_param(IS_RTC_DATE(tmpreg)); - } - assert_param(IS_RTC_WEEKDAY(RTC_DateStruct->RTC_WeekDay)); - - /* Check the input parameters format */ - if (RTC_Format != RTC_Format_BIN) - { - tmpreg = ((((uint32_t)RTC_DateStruct->RTC_Year) << 16) | \ - (((uint32_t)RTC_DateStruct->RTC_Month) << 8) | \ - ((uint32_t)RTC_DateStruct->RTC_Date) | \ - (((uint32_t)RTC_DateStruct->RTC_WeekDay) << 13)); - } - else - { - tmpreg = (((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Year) << 16) | \ - ((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Month) << 8) | \ - ((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Date)) | \ - ((uint32_t)RTC_DateStruct->RTC_WeekDay << 13)); - } - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Set Initialization mode */ - if (RTC_EnterInitMode() == ERROR) - { - status = ERROR; - } - else - { - /* Set the RTC_DR register */ - RTC->DR = (uint32_t)(tmpreg & RTC_DR_RESERVED_MASK); - - /* Exit Initialization mode */ - RTC_ExitInitMode(); - - if(RTC_WaitForSynchro() == ERROR) - { - status = ERROR; - } - else - { - status = SUCCESS; - } - } - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @brief Fills each RTC_DateStruct member with its default value - * (Monday, January 01 xx00). - * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure which will be - * initialized. - * @retval None - */ -void RTC_DateStructInit(RTC_DateTypeDef* RTC_DateStruct) -{ - /* Monday, January 01 xx00 */ - RTC_DateStruct->RTC_WeekDay = RTC_Weekday_Monday; - RTC_DateStruct->RTC_Date = 1; - RTC_DateStruct->RTC_Month = RTC_Month_January; - RTC_DateStruct->RTC_Year = 0; -} - -/** - * @brief Get the RTC current date. - * @param RTC_Format: specifies the format of the returned parameters. - * This parameter can be one of the following values: - * @arg RTC_Format_BIN: Binary data format - * @arg RTC_Format_BCD: BCD data format - * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure that will - * contain the returned current date configuration. - * @retval None - */ -void RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_FORMAT(RTC_Format)); - - /* Get the RTC_TR register */ - tmpreg = (uint32_t)(RTC->DR & RTC_DR_RESERVED_MASK); - - /* Fill the structure fields with the read parameters */ - RTC_DateStruct->RTC_Year = (uint8_t)((tmpreg & (RTC_DR_YT | RTC_DR_YU)) >> 16); - RTC_DateStruct->RTC_Month = (uint8_t)((tmpreg & (RTC_DR_MT | RTC_DR_MU)) >> 8); - RTC_DateStruct->RTC_Date = (uint8_t)(tmpreg & (RTC_DR_DT | RTC_DR_DU)); - RTC_DateStruct->RTC_WeekDay = (uint8_t)((tmpreg & (RTC_DR_WDU)) >> 13); - - /* Check the input parameters format */ - if (RTC_Format == RTC_Format_BIN) - { - /* Convert the structure parameters to Binary format */ - RTC_DateStruct->RTC_Year = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Year); - RTC_DateStruct->RTC_Month = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Month); - RTC_DateStruct->RTC_Date = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Date); - RTC_DateStruct->RTC_WeekDay = (uint8_t)(RTC_DateStruct->RTC_WeekDay); - } -} - -/** - * @} - */ - -/** @defgroup RTC_Group3 Alarms configuration functions - * @brief Alarms (Alarm A and Alarm B) configuration functions - * -@verbatim - =============================================================================== - Alarms (Alarm A and Alarm B) configuration functions - =============================================================================== - - This section provide functions allowing to program and read the RTC Alarms. - -@endverbatim - * @{ - */ - -/** - * @brief Set the specified RTC Alarm. - * @note The Alarm register can only be written when the corresponding Alarm - * is disabled (Use the RTC_AlarmCmd(DISABLE)). - * @param RTC_Format: specifies the format of the returned parameters. - * This parameter can be one of the following values: - * @arg RTC_Format_BIN: Binary data format - * @arg RTC_Format_BCD: BCD data format - * @param RTC_Alarm: specifies the alarm to be configured. - * This parameter can be one of the following values: - * @arg RTC_Alarm_A: to select Alarm A - * @arg RTC_Alarm_B: to select Alarm B - * @param RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that - * contains the alarm configuration parameters. - * @retval None - */ -void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_FORMAT(RTC_Format)); - assert_param(IS_RTC_ALARM(RTC_Alarm)); - assert_param(IS_ALARM_MASK(RTC_AlarmStruct->RTC_AlarmMask)); - assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel)); - - if (RTC_Format == RTC_Format_BIN) - { - if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) - { - assert_param(IS_RTC_HOUR12(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours)); - assert_param(IS_RTC_H12(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12)); - } - else - { - RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = 0x00; - assert_param(IS_RTC_HOUR24(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours)); - } - assert_param(IS_RTC_MINUTES(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes)); - assert_param(IS_RTC_SECONDS(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds)); - - if(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel == RTC_AlarmDateWeekDaySel_Date) - { - assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(RTC_AlarmStruct->RTC_AlarmDateWeekDay)); - } - else - { - assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(RTC_AlarmStruct->RTC_AlarmDateWeekDay)); - } - } - else - { - if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) - { - tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours); - assert_param(IS_RTC_HOUR12(tmpreg)); - assert_param(IS_RTC_H12(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12)); - } - else - { - RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = 0x00; - assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours))); - } - - assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes))); - assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds))); - - if(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel == RTC_AlarmDateWeekDaySel_Date) - { - tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay); - assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(tmpreg)); - } - else - { - tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay); - assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(tmpreg)); - } - } - - /* Check the input parameters format */ - if (RTC_Format != RTC_Format_BIN) - { - tmpreg = (((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours) << 16) | \ - ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes) << 8) | \ - ((uint32_t)RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds) | \ - ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12) << 16) | \ - ((uint32_t)(RTC_AlarmStruct->RTC_AlarmDateWeekDay) << 24) | \ - ((uint32_t)RTC_AlarmStruct->RTC_AlarmDateWeekDaySel) | \ - ((uint32_t)RTC_AlarmStruct->RTC_AlarmMask)); - } - else - { - tmpreg = (((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours) << 16) | \ - ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes) << 8) | \ - ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds)) | \ - ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12) << 16) | \ - ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmDateWeekDay) << 24) | \ - ((uint32_t)RTC_AlarmStruct->RTC_AlarmDateWeekDaySel) | \ - ((uint32_t)RTC_AlarmStruct->RTC_AlarmMask)); - } - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Configure the Alarm register */ - if (RTC_Alarm == RTC_Alarm_A) - { - RTC->ALRMAR = (uint32_t)tmpreg; - } - else - { - RTC->ALRMBR = (uint32_t)tmpreg; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @brief Fills each RTC_AlarmStruct member with its default value - * (Time = 00h:00mn:00sec / Date = 1st day of the month/Mask = - * all fields are masked). - * @param RTC_AlarmStruct: pointer to a @ref RTC_AlarmTypeDef structure which - * will be initialized. - * @retval None - */ -void RTC_AlarmStructInit(RTC_AlarmTypeDef* RTC_AlarmStruct) -{ - /* Alarm Time Settings : Time = 00h:00mn:00sec */ - RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = RTC_H12_AM; - RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = 0; - RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = 0; - RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = 0; - - /* Alarm Date Settings : Date = 1st day of the month */ - RTC_AlarmStruct->RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date; - RTC_AlarmStruct->RTC_AlarmDateWeekDay = 1; - - /* Alarm Masks Settings : Mask = all fields are not masked */ - RTC_AlarmStruct->RTC_AlarmMask = RTC_AlarmMask_None; -} - -/** - * @brief Get the RTC Alarm value and masks. - * @param RTC_Format: specifies the format of the output parameters. - * This parameter can be one of the following values: - * @arg RTC_Format_BIN: Binary data format - * @arg RTC_Format_BCD: BCD data format - * @param RTC_Alarm: specifies the alarm to be read. - * This parameter can be one of the following values: - * @arg RTC_Alarm_A: to select Alarm A - * @arg RTC_Alarm_B: to select Alarm B - * @param RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that will - * contains the output alarm configuration values. - * @retval None - */ -void RTC_GetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_FORMAT(RTC_Format)); - assert_param(IS_RTC_ALARM(RTC_Alarm)); - - /* Get the RTC_ALRMxR register */ - if (RTC_Alarm == RTC_Alarm_A) - { - tmpreg = (uint32_t)(RTC->ALRMAR); - } - else - { - tmpreg = (uint32_t)(RTC->ALRMBR); - } - - /* Fill the structure with the read parameters */ - RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = (uint32_t)((tmpreg & (RTC_ALRMAR_HT | \ - RTC_ALRMAR_HU)) >> 16); - RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = (uint32_t)((tmpreg & (RTC_ALRMAR_MNT | \ - RTC_ALRMAR_MNU)) >> 8); - RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = (uint32_t)(tmpreg & (RTC_ALRMAR_ST | \ - RTC_ALRMAR_SU)); - RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = (uint32_t)((tmpreg & RTC_ALRMAR_PM) >> 16); - RTC_AlarmStruct->RTC_AlarmDateWeekDay = (uint32_t)((tmpreg & (RTC_ALRMAR_DT | RTC_ALRMAR_DU)) >> 24); - RTC_AlarmStruct->RTC_AlarmDateWeekDaySel = (uint32_t)(tmpreg & RTC_ALRMAR_WDSEL); - RTC_AlarmStruct->RTC_AlarmMask = (uint32_t)(tmpreg & RTC_AlarmMask_All); - - if (RTC_Format == RTC_Format_BIN) - { - RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = RTC_Bcd2ToByte(RTC_AlarmStruct-> \ - RTC_AlarmTime.RTC_Hours); - RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = RTC_Bcd2ToByte(RTC_AlarmStruct-> \ - RTC_AlarmTime.RTC_Minutes); - RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = RTC_Bcd2ToByte(RTC_AlarmStruct-> \ - RTC_AlarmTime.RTC_Seconds); - RTC_AlarmStruct->RTC_AlarmDateWeekDay = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay); - } -} - -/** - * @brief Enables or disables the specified RTC Alarm. - * @param RTC_Alarm: specifies the alarm to be configured. - * This parameter can be any combination of the following values: - * @arg RTC_Alarm_A: to select Alarm A - * @arg RTC_Alarm_B: to select Alarm B - * @param NewState: new state of the specified alarm. - * This parameter can be: ENABLE or DISABLE. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC Alarm is enabled/disabled - * - ERROR: RTC Alarm is not enabled/disabled - */ -ErrorStatus RTC_AlarmCmd(uint32_t RTC_Alarm, FunctionalState NewState) -{ - __IO uint32_t alarmcounter = 0x00; - uint32_t alarmstatus = 0x00; - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_RTC_CMD_ALARM(RTC_Alarm)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Configure the Alarm state */ - if (NewState != DISABLE) - { - RTC->CR |= (uint32_t)RTC_Alarm; - - status = SUCCESS; - } - else - { - /* Disable the Alarm in RTC_CR register */ - RTC->CR &= (uint32_t)~RTC_Alarm; - - /* Wait till RTC ALRxWF flag is set and if Time out is reached exit */ - do - { - alarmstatus = RTC->ISR & (RTC_Alarm >> 8); - alarmcounter++; - } while((alarmcounter != INITMODE_TIMEOUT) && (alarmstatus == 0x00)); - - if ((RTC->ISR & (RTC_Alarm >> 8)) == RESET) - { - status = ERROR; - } - else - { - status = SUCCESS; - } - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @} - */ - -/** @defgroup RTC_Group4 WakeUp Timer configuration functions - * @brief WakeUp Timer configuration functions - * -@verbatim - =============================================================================== - WakeUp Timer configuration functions - =============================================================================== - - This section provide functions allowing to program and read the RTC WakeUp. - -@endverbatim - * @{ - */ - -/** - * @brief Configures the RTC Wakeup clock source. - * @note The WakeUp Clock source can only be changed when the RTC WakeUp - * is disabled (Use the RTC_WakeUpCmd(DISABLE)). - * @param RTC_WakeUpClock: Wakeup Clock source. - * This parameter can be one of the following values: - * @arg RTC_WakeUpClock_RTCCLK_Div16 - * @arg RTC_WakeUpClock_RTCCLK_Div8 - * @arg RTC_WakeUpClock_RTCCLK_Div4 - * @arg RTC_WakeUpClock_RTCCLK_Div2 - * @arg RTC_WakeUpClock_CK_SPRE_16bits - * @arg RTC_WakeUpClock_CK_SPRE_17bits - * @retval None - */ -void RTC_WakeUpClockConfig(uint32_t RTC_WakeUpClock) -{ - /* Check the parameters */ - assert_param(IS_RTC_WAKEUP_CLOCK(RTC_WakeUpClock)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Clear the Wakeup Timer clock source bits in CR register */ - RTC->CR &= (uint32_t)~RTC_CR_WUCKSEL; - - /* Configure the clock source */ - RTC->CR |= (uint32_t)RTC_WakeUpClock; - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @brief Configures the RTC Wakeup counter. - * @note The RTC WakeUp counter can only be written when the RTC WakeUp - * is disabled (Use the RTC_WakeUpCmd(DISABLE)). - * @param RTC_WakeUpCounter: specifies the WakeUp counter. - * This parameter can be a value from 0x0000 to 0xFFFF. - * @retval None - */ -void RTC_SetWakeUpCounter(uint32_t RTC_WakeUpCounter) -{ - /* Check the parameters */ - assert_param(IS_RTC_WAKEUP_COUNTER(RTC_WakeUpCounter)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Configure the Wakeup Timer counter */ - RTC->WUTR = (uint32_t)RTC_WakeUpCounter; - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @brief Returns the RTC WakeUp timer counter value. - * @param None - * @retval The RTC WakeUp Counter value. - */ -uint32_t RTC_GetWakeUpCounter(void) -{ - /* Get the counter value */ - return ((uint32_t)(RTC->WUTR & RTC_WUTR_WUT)); -} - -/** - * @brief Enables or Disables the RTC WakeUp timer. - * @param NewState: new state of the WakeUp timer. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -ErrorStatus RTC_WakeUpCmd(FunctionalState NewState) -{ - __IO uint32_t wutcounter = 0x00; - uint32_t wutwfstatus = 0x00; - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - if (NewState != DISABLE) - { - /* Enable the Wakeup Timer */ - RTC->CR |= (uint32_t)RTC_CR_WUTE; - status = SUCCESS; - } - else - { - /* Disable the Wakeup Timer */ - RTC->CR &= (uint32_t)~RTC_CR_WUTE; - /* Wait till RTC WUTWF flag is set and if Time out is reached exit */ - do - { - wutwfstatus = RTC->ISR & RTC_ISR_WUTWF; - wutcounter++; - } while((wutcounter != INITMODE_TIMEOUT) && (wutwfstatus == 0x00)); - - if ((RTC->ISR & RTC_ISR_WUTWF) == RESET) - { - status = ERROR; - } - else - { - status = SUCCESS; - } - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @} - */ - -/** @defgroup RTC_Group5 Daylight Saving configuration functions - * @brief Daylight Saving configuration functions - * -@verbatim - =============================================================================== - Daylight Saving configuration functions - =============================================================================== - - This section provide functions allowing to configure the RTC DayLight Saving. - -@endverbatim - * @{ - */ - -/** - * @brief Adds or substract one hour from the current time. - * @param RTC_DayLightSaveOperation: the value of hour adjustment. - * This parameter can be one of the following values: - * @arg RTC_DayLightSaving_SUB1H: Substract one hour (winter time) - * @arg RTC_DayLightSaving_ADD1H: Add one hour (summer time) - * @param RTC_StoreOperation: Specifies the value to be written in the BCK bit - * in CR register to store the operation. - * This parameter can be one of the following values: - * @arg RTC_StoreOperation_Reset - * @arg RTC_StoreOperation_Set - * @retval None - */ -void RTC_DayLightSavingConfig(uint32_t RTC_DayLightSaving, uint32_t RTC_StoreOperation) -{ - /* Check the parameters */ - assert_param(IS_RTC_DAYLIGHT_SAVING(RTC_DayLightSaving)); - assert_param(IS_RTC_STORE_OPERATION(RTC_StoreOperation)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Clear the bits to be configured */ - RTC->CR &= (uint32_t)~(RTC_CR_BCK); - - /* Configure the RTC_CR register */ - RTC->CR |= (uint32_t)(RTC_DayLightSaving | RTC_StoreOperation); - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @brief Returns the RTC Day Light Saving stored operation. - * @param None - * @retval RTC Day Light Saving stored operation. - * - RTC_StoreOperation_Reset - * - RTC_StoreOperation_Set - */ -uint32_t RTC_GetStoreOperation(void) -{ - return (RTC->CR & RTC_CR_BCK); -} - -/** - * @} - */ - -/** @defgroup RTC_Group6 Output pin Configuration function - * @brief Output pin Configuration function - * -@verbatim - =============================================================================== - Output pin Configuration function - =============================================================================== - - This section provide functions allowing to configure the RTC Output source. - -@endverbatim - * @{ - */ - -/** - * @brief Configures the RTC output source (AFO_ALARM). - * @param RTC_Output: Specifies which signal will be routed to the RTC output. - * This parameter can be one of the following values: - * @arg RTC_Output_Disable: No output selected - * @arg RTC_Output_AlarmA: signal of AlarmA mapped to output - * @arg RTC_Output_AlarmB: signal of AlarmB mapped to output - * @arg RTC_Output_WakeUp: signal of WakeUp mapped to output - * @param RTC_OutputPolarity: Specifies the polarity of the output signal. - * This parameter can be one of the following: - * @arg RTC_OutputPolarity_High: The output pin is high when the - * ALRAF/ALRBF/WUTF is high (depending on OSEL) - * @arg RTC_OutputPolarity_Low: The output pin is low when the - * ALRAF/ALRBF/WUTF is high (depending on OSEL) - * @retval None - */ -void RTC_OutputConfig(uint32_t RTC_Output, uint32_t RTC_OutputPolarity) -{ - /* Check the parameters */ - assert_param(IS_RTC_OUTPUT(RTC_Output)); - assert_param(IS_RTC_OUTPUT_POL(RTC_OutputPolarity)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Clear the bits to be configured */ - RTC->CR &= (uint32_t)~(RTC_CR_OSEL | RTC_CR_POL); - - /* Configure the output selection and polarity */ - RTC->CR |= (uint32_t)(RTC_Output | RTC_OutputPolarity); - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @} - */ - -/** @defgroup RTC_Group7 Digital Calibration configuration functions - * @brief Digital Calibration configuration functions - * -@verbatim - =============================================================================== - Digital Calibration configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Configures the digital calibration parameters. - * @param RTC_CalibSign: specifies the sign of the calibration value. - * This parameter can be one of the following values: - * @arg RTC_CalibSign_Positive: The value sign is positive - * @arg RTC_CalibSign_Negative: The value sign is negative - * @param Value: value of calibration expressed in ppm (coded on 5 bits) - * - This value should be between 0 and 63 when using negative sign - * with a 2-ppm step. - * - This value should be between 0 and 126 when using positive sign - * with a 4-ppm step. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC digital calibration are initialized - * - ERROR: RTC digital calibration are not initialized - */ -ErrorStatus RTC_DigitalCalibConfig(uint32_t RTC_CalibSign, uint32_t Value) -{ - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_RTC_CALIB_SIGN(RTC_CalibSign)); - assert_param(IS_RTC_CALIB_VALUE(Value)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Set Initialization mode */ - if (RTC_EnterInitMode() == ERROR) - { - status = ERROR; - } - else - { - /* Set the calibration value */ - RTC->CALIBR = (uint32_t)(RTC_CalibSign | Value); - /* Exit Initialization mode */ - RTC_ExitInitMode(); - - status = SUCCESS; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @brief Enables or disables the digital calibration process. - * @param NewState: new state of the digital calibration. - * This parameter can be: ENABLE or DISABLE. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC digital calibration are enabled/disabled - * - ERROR: RTC digital calibration are not enabled/disabled - */ -ErrorStatus RTC_DigitalCalibCmd(FunctionalState NewState) -{ - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Set Initialization mode */ - if (RTC_EnterInitMode() == ERROR) - { - status = ERROR; - } - else - { - if (NewState != DISABLE) - { - /* Enable the Digital Calibration */ - RTC->CR |= (uint32_t)RTC_CR_DCE; - } - else - { - /* Disable the Digital Calibration */ - RTC->CR &= (uint32_t)~RTC_CR_DCE; - } - /* Exit Initialization mode */ - RTC_ExitInitMode(); - - status = SUCCESS; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @brief Enables or disables the RTC clock to be output through the relative - * pin. - * @param NewState: new state of the digital calibration Output. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RTC_CalibOutputCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - if (NewState != DISABLE) - { - /* Enable the RTC clock output */ - RTC->CR |= (uint32_t)RTC_CR_COE; - } - else - { - /* Disable the RTC clock output */ - RTC->CR &= (uint32_t)~RTC_CR_COE; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @} - */ - - -/** @defgroup RTC_Group8 TimeStamp configuration functions - * @brief TimeStamp configuration functions - * -@verbatim - =============================================================================== - TimeStamp configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or Disables the RTC TimeStamp functionality with the - * specified time stamp pin stimulating edge. - * @param RTC_TimeStampEdge: Specifies the pin edge on which the TimeStamp is - * activated. - * This parameter can be one of the following: - * @arg RTC_TimeStampEdge_Rising: the Time stamp event occurs on the rising - * edge of the related pin. - * @arg RTC_TimeStampEdge_Falling: the Time stamp event occurs on the - * falling edge of the related pin. - * @param NewState: new state of the TimeStamp. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RTC_TimeStampCmd(uint32_t RTC_TimeStampEdge, FunctionalState NewState) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_TIMESTAMP_EDGE(RTC_TimeStampEdge)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Get the RTC_CR register and clear the bits to be configured */ - tmpreg = (uint32_t)(RTC->CR & (uint32_t)~(RTC_CR_TSEDGE | RTC_CR_TSE)); - - /* Get the new configuration */ - if (NewState != DISABLE) - { - tmpreg |= (uint32_t)(RTC_TimeStampEdge | RTC_CR_TSE); - } - else - { - tmpreg |= (uint32_t)(RTC_TimeStampEdge); - } - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Configure the Time Stamp TSEDGE and Enable bits */ - RTC->CR = (uint32_t)tmpreg; - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @brief Get the RTC TimeStamp value and masks. - * @param RTC_Format: specifies the format of the output parameters. - * This parameter can be one of the following values: - * @arg RTC_Format_BIN: Binary data format - * @arg RTC_Format_BCD: BCD data format - * @param RTC_StampTimeStruct: pointer to a RTC_TimeTypeDef structure that will - * contains the TimeStamp time values. - * @param RTC_StampDateStruct: pointer to a RTC_DateTypeDef structure that will - * contains the TimeStamp date values. - * @retval None - */ -void RTC_GetTimeStamp(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_StampTimeStruct, - RTC_DateTypeDef* RTC_StampDateStruct) -{ - uint32_t tmptime = 0, tmpdate = 0; - - /* Check the parameters */ - assert_param(IS_RTC_FORMAT(RTC_Format)); - - /* Get the TimeStamp time and date registers values */ - tmptime = (uint32_t)(RTC->TSTR & RTC_TR_RESERVED_MASK); - tmpdate = (uint32_t)(RTC->TSDR & RTC_DR_RESERVED_MASK); - - /* Fill the Time structure fields with the read parameters */ - RTC_StampTimeStruct->RTC_Hours = (uint8_t)((tmptime & (RTC_TR_HT | RTC_TR_HU)) >> 16); - RTC_StampTimeStruct->RTC_Minutes = (uint8_t)((tmptime & (RTC_TR_MNT | RTC_TR_MNU)) >> 8); - RTC_StampTimeStruct->RTC_Seconds = (uint8_t)(tmptime & (RTC_TR_ST | RTC_TR_SU)); - RTC_StampTimeStruct->RTC_H12 = (uint8_t)((tmptime & (RTC_TR_PM)) >> 16); - - /* Fill the Date structure fields with the read parameters */ - RTC_StampDateStruct->RTC_Year = 0; - RTC_StampDateStruct->RTC_Month = (uint8_t)((tmpdate & (RTC_DR_MT | RTC_DR_MU)) >> 8); - RTC_StampDateStruct->RTC_Date = (uint8_t)(tmpdate & (RTC_DR_DT | RTC_DR_DU)); - RTC_StampDateStruct->RTC_WeekDay = (uint8_t)((tmpdate & (RTC_DR_WDU)) >> 13); - - /* Check the input parameters format */ - if (RTC_Format == RTC_Format_BIN) - { - /* Convert the Time structure parameters to Binary format */ - RTC_StampTimeStruct->RTC_Hours = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Hours); - RTC_StampTimeStruct->RTC_Minutes = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Minutes); - RTC_StampTimeStruct->RTC_Seconds = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Seconds); - - /* Convert the Date structure parameters to Binary format */ - RTC_StampDateStruct->RTC_Month = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_Month); - RTC_StampDateStruct->RTC_Date = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_Date); - RTC_StampDateStruct->RTC_WeekDay = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_WeekDay); - } -} - -/** - * @} - */ - -/** @defgroup RTC_Group9 Tampers configuration functions - * @brief Tampers configuration functions - * -@verbatim - =============================================================================== - Tampers configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Configures the select Tamper pin edge. - * @param RTC_Tamper: Selected tamper pin. - * This parameter can be RTC_Tamper_1. - * @param RTC_TamperTrigger: Specifies the trigger on the tamper pin that - * stimulates tamper event. - * This parameter can be one of the following values: - * @arg RTC_TamperTrigger_RisingEdge: Rising Edge of the tamper pin causes tamper event. - * @arg RTC_TamperTrigger_FallingEdge: Falling Edge of the tamper pin causes tamper event. - * @retval None - */ -void RTC_TamperTriggerConfig(uint32_t RTC_Tamper, uint32_t RTC_TamperTrigger) -{ - /* Check the parameters */ - assert_param(IS_RTC_TAMPER(RTC_Tamper)); - assert_param(IS_RTC_TAMPER_TRIGGER(RTC_TamperTrigger)); - - if (RTC_TamperTrigger == RTC_TamperTrigger_RisingEdge) - { - /* Configure the RTC_TAFCR register */ - RTC->TAFCR &= (uint32_t)((uint32_t)~(RTC_Tamper << 1)); - } - else - { - /* Configure the RTC_TAFCR register */ - RTC->TAFCR |= (uint32_t)(RTC_Tamper << 1); - } -} - -/** - * @brief Enables or Disables the Tamper detection. - * @param RTC_Tamper: Selected tamper pin. - * This parameter can be RTC_Tamper_1. - * @param NewState: new state of the tamper pin. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RTC_TamperCmd(uint32_t RTC_Tamper, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RTC_TAMPER(RTC_Tamper)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected Tamper pin */ - RTC->TAFCR |= (uint32_t)RTC_Tamper; - } - else - { - /* Disable the selected Tamper pin */ - RTC->TAFCR &= (uint32_t)~RTC_Tamper; - } -} - -/** - * @} - */ - -/** @defgroup RTC_Group10 Backup Data Registers configuration functions - * @brief Backup Data Registers configuration functions - * -@verbatim - =============================================================================== - Backup Data Registers configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Writes a data in a specified RTC Backup data register. - * @param RTC_BKP_DR: RTC Backup data Register number. - * This parameter can be: RTC_BKP_DRx where x can be from 0 to 19 to - * specify the register. - * @param Data: Data to be written in the specified RTC Backup data register. - * @retval None - */ -void RTC_WriteBackupRegister(uint32_t RTC_BKP_DR, uint32_t Data) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_RTC_BKP(RTC_BKP_DR)); - - tmp = RTC_BASE + 0x50; - tmp += (RTC_BKP_DR * 4); - - /* Write the specified register */ - *(__IO uint32_t *)tmp = (uint32_t)Data; -} - -/** - * @brief Reads data from the specified RTC Backup data Register. - * @param RTC_BKP_DR: RTC Backup data Register number. - * This parameter can be: RTC_BKP_DRx where x can be from 0 to 19 to - * specify the register. - * @retval None - */ -uint32_t RTC_ReadBackupRegister(uint32_t RTC_BKP_DR) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_RTC_BKP(RTC_BKP_DR)); - - tmp = RTC_BASE + 0x50; - tmp += (RTC_BKP_DR * 4); - - /* Read the specified register */ - return (*(__IO uint32_t *)tmp); -} - -/** - * @} - */ - -/** @defgroup RTC_Group11 Output Type Config configuration functions - * @brief Output Type Config configuration functions - * -@verbatim - =============================================================================== - Output Type Config configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Configures the RTC Output Pin mode. - * @param RTC_OutputType: specifies the RTC Output (PC13) pin mode. - * This parameter can be one of the following values: - * @arg RTC_OutputType_OpenDrain: RTC Output (PC13) is configured in - * Open Drain mode. - * @arg RTC_OutputType_PushPull: RTC Output (PC13) is configured in - * Push Pull mode. - * @retval None - */ -void RTC_OutputTypeConfig(uint32_t RTC_OutputType) -{ - /* Check the parameters */ - assert_param(IS_RTC_OUTPUT_TYPE(RTC_OutputType)); - - RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_ALARMOUTTYPE); - RTC->TAFCR |= (uint32_t)(RTC_OutputType); -} - -/** - * @} - */ - -/** @defgroup RTC_Group12 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - All RTC interrupts are connected to the EXTI controller. - - - To enable the RTC Alarm interrupt, the following sequence is required: - - Configure and enable the EXTI Line 17 in interrupt mode and select the rising - edge sensitivity using the EXTI_Init() function. - - Configure and enable the RTC_Alarm IRQ channel in the NVIC using the NVIC_Init() - function. - - Configure the RTC to generate RTC alarms (Alarm A and/or Alarm B) using - the RTC_SetAlarm() and RTC_AlarmCmd() functions. - - - To enable the RTC Wakeup interrupt, the following sequence is required: - - Configure and enable the EXTI Line 20 in interrupt mode and select the rising - edge sensitivity using the EXTI_Init() function. - - Configure and enable the RTC_WKUP IRQ channel in the NVIC using the NVIC_Init() - function. - - Configure the RTC to generate the RTC wakeup timer event using the - RTC_WakeUpClockConfig(), RTC_SetWakeUpCounter() and RTC_WakeUpCmd() functions. - - - To enable the RTC Tamper interrupt, the following sequence is required: - - Configure and enable the EXTI Line 19 in interrupt mode and select the rising - edge sensitivity using the EXTI_Init() function. - - Configure and enable the TAMP_STAMP IRQ channel in the NVIC using the NVIC_Init() - function. - - Configure the RTC to detect the RTC tamper event using the - RTC_TamperTriggerConfig() and RTC_TamperCmd() functions. - - - To enable the RTC TimeStamp interrupt, the following sequence is required: - - Configure and enable the EXTI Line 19 in interrupt mode and select the rising - edge sensitivity using the EXTI_Init() function. - - Configure and enable the TAMP_STAMP IRQ channel in the NVIC using the NVIC_Init() - function. - - Configure the RTC to detect the RTC time-stamp event using the - RTC_TimeStampCmd() functions. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified RTC interrupts. - * @param RTC_IT: specifies the RTC interrupt sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg RTC_IT_TS: Time Stamp interrupt mask - * @arg RTC_IT_WUT: WakeUp Timer interrupt mask - * @arg RTC_IT_ALRB: Alarm B interrupt mask - * @arg RTC_IT_ALRA: Alarm A interrupt mask - * @arg RTC_IT_TAMP: Tamper event interrupt mask - * @param NewState: new state of the specified RTC interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RTC_CONFIG_IT(RTC_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - if (NewState != DISABLE) - { - /* Configure the Interrupts in the RTC_CR register */ - RTC->CR |= (uint32_t)(RTC_IT & ~RTC_TAFCR_TAMPIE); - /* Configure the Tamper Interrupt in the RTC_TAFCR */ - RTC->TAFCR |= (uint32_t)(RTC_IT & RTC_TAFCR_TAMPIE); - } - else - { - /* Configure the Interrupts in the RTC_CR register */ - RTC->CR &= (uint32_t)~(RTC_IT & (uint32_t)~RTC_TAFCR_TAMPIE); - /* Configure the Tamper Interrupt in the RTC_TAFCR */ - RTC->TAFCR &= (uint32_t)~(RTC_IT & RTC_TAFCR_TAMPIE); - } - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @brief Checks whether the specified RTC flag is set or not. - * @param RTC_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg RTC_FLAG_TAMP1F: Tamper 1 event flag - * @arg RTC_FLAG_TSOVF: Time Stamp OverFlow flag - * @arg RTC_FLAG_TSF: Time Stamp event flag - * @arg RTC_FLAG_WUTF: WakeUp Timer flag - * @arg RTC_FLAG_ALRBF: Alarm B flag - * @arg RTC_FLAG_ALRAF: Alarm A flag - * @arg RTC_FLAG_INITF: Initialization mode flag - * @arg RTC_FLAG_RSF: Registers Synchronized flag - * @arg RTC_FLAG_INITS: Registers Configured flag - * @arg RTC_FLAG_WUTWF: WakeUp Timer Write flag - * @arg RTC_FLAG_ALRBWF: Alarm B Write flag - * @arg RTC_FLAG_ALRAWF: Alarm A write flag - * @retval The new state of RTC_FLAG (SET or RESET). - */ -FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG) -{ - FlagStatus bitstatus = RESET; - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_GET_FLAG(RTC_FLAG)); - - /* Get all the flags */ - tmpreg = (uint32_t)(RTC->ISR & RTC_FLAGS_MASK); - - /* Return the status of the flag */ - if ((tmpreg & RTC_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the RTC's pending flags. - * @param RTC_FLAG: specifies the RTC flag to clear. - * This parameter can be any combination of the following values: - * @arg RTC_FLAG_TAMP1F: Tamper 1 event flag - * @arg RTC_FLAG_TSOVF: Time Stamp Overflow flag - * @arg RTC_FLAG_TSF: Time Stamp event flag - * @arg RTC_FLAG_WUTF: WakeUp Timer flag - * @arg RTC_FLAG_ALRBF: Alarm B flag - * @arg RTC_FLAG_ALRAF: Alarm A flag - * @arg RTC_FLAG_RSF: Registers Synchronized flag - * @retval None - */ -void RTC_ClearFlag(uint32_t RTC_FLAG) -{ - /* Check the parameters */ - assert_param(IS_RTC_CLEAR_FLAG(RTC_FLAG)); - - /* Clear the Flags in the RTC_ISR register */ - RTC->ISR = (uint32_t)((uint32_t)(~((RTC_FLAG | RTC_ISR_INIT)& 0x0000FFFF) | (uint32_t)(RTC->ISR & RTC_ISR_INIT))); -} - -/** - * @brief Checks whether the specified RTC interrupt has occurred or not. - * @param RTC_IT: specifies the RTC interrupt source to check. - * This parameter can be one of the following values: - * @arg RTC_IT_TS: Time Stamp interrupt - * @arg RTC_IT_WUT: WakeUp Timer interrupt - * @arg RTC_IT_ALRB: Alarm B interrupt - * @arg RTC_IT_ALRA: Alarm A interrupt - * @arg RTC_IT_TAMP1: Tamper 1 event interrupt - * @retval The new state of RTC_IT (SET or RESET). - */ -ITStatus RTC_GetITStatus(uint32_t RTC_IT) -{ - ITStatus bitstatus = RESET; - uint32_t tmpreg = 0, enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_RTC_GET_IT(RTC_IT)); - - /* Get the TAMPER Interrupt enable bit and pending bit */ - tmpreg = (uint32_t)(RTC->TAFCR & (RTC_TAFCR_TAMPIE)); - - /* Get the Interrupt enable Status */ - enablestatus = (uint32_t)((RTC->CR & RTC_IT) | (tmpreg & (RTC_IT >> 15))); - - /* Get the Interrupt pending bit */ - tmpreg = (uint32_t)((RTC->ISR & (uint32_t)(RTC_IT >> 4))); - - /* Get the status of the Interrupt */ - if ((enablestatus != (uint32_t)RESET) && ((tmpreg & 0x0000FFFF) != (uint32_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the RTC's interrupt pending bits. - * @param RTC_IT: specifies the RTC interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg RTC_IT_TS: Time Stamp interrupt - * @arg RTC_IT_WUT: WakeUp Timer interrupt - * @arg RTC_IT_ALRB: Alarm B interrupt - * @arg RTC_IT_ALRA: Alarm A interrupt - * @arg RTC_IT_TAMP1: Tamper 1 event interrupt - * @retval None - */ -void RTC_ClearITPendingBit(uint32_t RTC_IT) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_CLEAR_IT(RTC_IT)); - - /* Get the RTC_ISR Interrupt pending bits mask */ - tmpreg = (uint32_t)(RTC_IT >> 4); - - /* Clear the interrupt pending bits in the RTC_ISR register */ - RTC->ISR = (uint32_t)((uint32_t)(~((tmpreg | RTC_ISR_INIT)& 0x0000FFFF) | (uint32_t)(RTC->ISR & RTC_ISR_INIT))); -} - -/** - * @} - */ - -/** - * @brief Converts a 2 digit decimal to BCD format. - * @param Value: Byte to be converted. - * @retval Converted byte - */ -static uint8_t RTC_ByteToBcd2(uint8_t Value) -{ - uint8_t bcdhigh = 0; - - while (Value >= 10) - { - bcdhigh++; - Value -= 10; - } - - return ((uint8_t)(bcdhigh << 4) | Value); -} - -/** - * @brief Convert from 2 digit BCD to Binary. - * @param Value: BCD value to be converted. - * @retval Converted word - */ -static uint8_t RTC_Bcd2ToByte(uint8_t Value) -{ - uint8_t tmp = 0; - tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10; - return (tmp + (Value & (uint8_t)0x0F)); -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_spi.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_spi.c deleted file mode 100644 index bf8ce5fba..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_spi.c +++ /dev/null @@ -1,884 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_spi.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the Serial peripheral interface (SPI): - * - Initialization and Configuration - * - Data transfers functions - * - Hardware CRC Calculation - * - DMA transfers management - * - Interrupts and flags management - * - * @verbatim - * - * The I2S feature is not implemented in STM32L1xx Ultra Low Power - * Medium-density devices and will be supported in future products. - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable peripheral clock using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE) - * function for SPI1 or using RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE) - * function for SPI2. - * - * 2. Enable SCK, MOSI, MISO and NSS GPIO clocks using RCC_AHBPeriphClockCmd() - * function. - * - * 3. Peripherals alternate function: - * - Connect the pin to the desired peripherals' Alternate - * Function (AF) using GPIO_PinAFConfig() function - * - Configure the desired pin in alternate function by: - * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF - * - Select the type, pull-up/pull-down and output speed via - * GPIO_PuPd, GPIO_OType and GPIO_Speed members - * - Call GPIO_Init() function - * - * 4. Program the Polarity, Phase, First Data, Baud Rate Prescaler, Slave - * Management, Peripheral Mode and CRC Polynomial values using the SPI_Init() - * function. - * - * 5. Enable the NVIC and the corresponding interrupt using the function - * SPI_ITConfig() if you need to use interrupt mode. - * - * 6. When using the DMA mode - * - Configure the DMA using DMA_Init() function - * - Active the needed channel Request using SPI_I2S_DMACmd() function - * - * 7. Enable the SPI using the SPI_Cmd() function. - * - * 8. Enable the DMA using the DMA_Cmd() function when using DMA mode. - * - * 9. Optionally you can enable/configure the following parameters without - * re-initialization (i.e there is no need to call again SPI_Init() function): - * - When bidirectional mode (SPI_Direction_1Line_Rx or SPI_Direction_1Line_Tx) - * is programmed as Data direction parameter using the SPI_Init() function - * it can be possible to switch between SPI_Direction_Tx or SPI_Direction_Rx - * using the SPI_BiDirectionalLineConfig() function. - * - When SPI_NSS_Soft is selected as Slave Select Management parameter - * using the SPI_Init() function it can be possible to manage the - * NSS internal signal using the SPI_NSSInternalSoftwareConfig() function. - * - Reconfigure the data size using the SPI_DataSizeConfig() function - * - Enable or disable the SS output using the SPI_SSOutputCmd() function - * - * 10. To use the CRC Hardware calculation feature refer to the Peripheral - * CRC hardware Calculation subsection. - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_spi.h" -#include "stm32l1xx_rcc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup SPI - * @brief SPI driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* SPI registers Masks */ -#define CR1_CLEAR_MASK ((uint16_t)0x3040) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup SPI_Private_Functions - * @{ - */ - -/** @defgroup SPI_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - - This section provides a set of functions allowing to initialize the SPI Direction, - SPI Mode, SPI Data Size, SPI Polarity, SPI Phase, SPI NSS Management, SPI Baud - Rate Prescaler, SPI First Bit and SPI CRC Polynomial. - - The SPI_Init() function follows the SPI configuration procedures for Master mode - and Slave mode (details for these procedures are available in reference manual - (RM0038)). - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the SPIx peripheral registers to their default - * reset values. - * @param SPIx: where x can be 1 or 2 to select the SPI peripheral. - * @retval None - */ -void SPI_I2S_DeInit(SPI_TypeDef* SPIx) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - if (SPIx == SPI1) - { - /* Enable SPI1 reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE); - /* Release SPI1 from reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE); - } - else - { - if (SPIx == SPI2) - { - /* Enable SPI2 reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE); - /* Release SPI2 from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE); - } - } -} - -/** - * @brief Initializes the SPIx peripheral according to the specified - * parameters in the SPI_InitStruct. - * @param SPIx: where x can be 1 or 2 to select the SPI peripheral. - * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure that - * contains the configuration information for the specified SPI peripheral. - * @retval None - */ -void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct) -{ - uint16_t tmpreg = 0; - - /* check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - /* Check the SPI parameters */ - assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction)); - assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode)); - assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize)); - assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL)); - assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA)); - assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS)); - assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler)); - assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit)); - assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial)); - -/*---------------------------- SPIx CR1 Configuration ------------------------*/ - /* Get the SPIx CR1 value */ - tmpreg = SPIx->CR1; - /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */ - tmpreg &= CR1_CLEAR_MASK; - /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler - master/salve mode, CPOL and CPHA */ - /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */ - /* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */ - /* Set LSBFirst bit according to SPI_FirstBit value */ - /* Set BR bits according to SPI_BaudRatePrescaler value */ - /* Set CPOL bit according to SPI_CPOL value */ - /* Set CPHA bit according to SPI_CPHA value */ - tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode | - SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL | - SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS | - SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit); - /* Write to SPIx CR1 */ - SPIx->CR1 = tmpreg; - -/*---------------------------- SPIx CRCPOLY Configuration --------------------*/ - /* Write to SPIx CRCPOLY */ - SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial; -} - -/** - * @brief Fills each SPI_InitStruct member with its default value. - * @param SPI_InitStruct : pointer to a SPI_InitTypeDef structure which will be initialized. - * @retval None - */ -void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct) -{ -/*--------------- Reset SPI init structure parameters values -----------------*/ - /* Initialize the SPI_Direction member */ - SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex; - /* initialize the SPI_Mode member */ - SPI_InitStruct->SPI_Mode = SPI_Mode_Slave; - /* initialize the SPI_DataSize member */ - SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b; - /* Initialize the SPI_CPOL member */ - SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low; - /* Initialize the SPI_CPHA member */ - SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge; - /* Initialize the SPI_NSS member */ - SPI_InitStruct->SPI_NSS = SPI_NSS_Hard; - /* Initialize the SPI_BaudRatePrescaler member */ - SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; - /* Initialize the SPI_FirstBit member */ - SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB; - /* Initialize the SPI_CRCPolynomial member */ - SPI_InitStruct->SPI_CRCPolynomial = 7; -} - -/** - * @brief Enables or disables the specified SPI peripheral. - * @param SPIx: where x can be 1 or 2 to select the SPI peripheral. - * @param NewState: new state of the SPIx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected SPI peripheral */ - SPIx->CR1 |= SPI_CR1_SPE; - } - else - { - /* Disable the selected SPI peripheral */ - SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE); - } -} - -/** - * @brief Configures the data size for the selected SPI. - * @param SPIx: where x can be 1 or 2 to select the SPI peripheral. - * @param SPI_DataSize: specifies the SPI data size. - * This parameter can be one of the following values: - * @arg SPI_DataSize_16b: Set data frame format to 16bit - * @arg SPI_DataSize_8b: Set data frame format to 8bit - * @retval None - */ -void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_DATASIZE(SPI_DataSize)); - /* Clear DFF bit */ - SPIx->CR1 &= (uint16_t)~SPI_DataSize_16b; - /* Set new DFF bit value */ - SPIx->CR1 |= SPI_DataSize; -} - -/** - * @brief Selects the data transfer direction in bidirectional mode for the specified SPI. - * @param SPIx: where x can be 1 or 2 to select the SPI peripheral. - * @param SPI_Direction: specifies the data transfer direction in bidirectional mode. - * This parameter can be one of the following values: - * @arg SPI_Direction_Tx: Selects Tx transmission direction - * @arg SPI_Direction_Rx: Selects Rx receive direction - * @retval None - */ -void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_DIRECTION(SPI_Direction)); - if (SPI_Direction == SPI_Direction_Tx) - { - /* Set the Tx only mode */ - SPIx->CR1 |= SPI_Direction_Tx; - } - else - { - /* Set the Rx only mode */ - SPIx->CR1 &= SPI_Direction_Rx; - } -} - -/** - * @brief Configures internally by software the NSS pin for the selected SPI. - * @param SPIx: where x can be 1 or 2 to select the SPI peripheral. - * @param SPI_NSSInternalSoft: specifies the SPI NSS internal state. - * This parameter can be one of the following values: - * @arg SPI_NSSInternalSoft_Set: Set NSS pin internally - * @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally - * @retval None - */ -void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft)); - if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset) - { - /* Set NSS pin internally by software */ - SPIx->CR1 |= SPI_NSSInternalSoft_Set; - } - else - { - /* Reset NSS pin internally by software */ - SPIx->CR1 &= SPI_NSSInternalSoft_Reset; - } -} - -/** - * @brief Enables or disables the SS output for the selected SPI. - * @param SPIx: where x can be 1 or 2 to select the SPI peripheral. - * @param NewState: new state of the SPIx SS output. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected SPI SS output */ - SPIx->CR2 |= (uint16_t)SPI_CR2_SSOE; - } - else - { - /* Disable the selected SPI SS output */ - SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE); - } -} - -/** - * @} - */ - -/** @defgroup SPI_Group2 Data transfers functions - * @brief Data transfers functions - * -@verbatim - =============================================================================== - Data transfers functions - =============================================================================== - - This section provides a set of functions allowing to manage the SPI data transfers - - In reception, data are received and then stored into an internal Rx buffer while - In transmission, data are first stored into an internal Tx buffer before being - transmitted. - - The read access of the SPI_DR register can be done using the SPI_I2S_ReceiveData() - function and returns the Rx buffered value. Whereas a write access to the SPI_DR - can be done using SPI_I2S_SendData() function and stores the written data into - Tx buffer. - -@endverbatim - * @{ - */ - -/** - * @brief Returns the most recent received data by the SPIx peripheral. - * @param SPIx: where x can be 1 or 2 in SPI mode. - * @retval The value of the received data. - */ -uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - /* Return the data in the DR register */ - return SPIx->DR; -} - -/** - * @brief Transmits a Data through the SPIx peripheral. - * @param SPIx: where x can be 1 or 2 in SPI mode. - * @param Data: Data to be transmitted. - * @retval None - */ -void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - /* Write in the DR register the data to be sent */ - SPIx->DR = Data; -} - -/** - * @} - */ - -/** @defgroup SPI_Group3 Hardware CRC Calculation functions - * @brief Hardware CRC Calculation functions - * -@verbatim - =============================================================================== - Hardware CRC Calculation functions - =============================================================================== - - This section provides a set of functions allowing to manage the SPI CRC hardware - calculation - - SPI communication using CRC is possible through the following procedure: - 1. Program the Data direction, Polarity, Phase, First Data, Baud Rate Prescaler, - Slave Management, Peripheral Mode and CRC Polynomial values using the SPI_Init() - function. - 2. Enable the CRC calculation using the SPI_CalculateCRC() function. - 3. Enable the SPI using the SPI_Cmd() function - 4. Before writing the last data to the TX buffer, set the CRCNext bit using the - SPI_TransmitCRC() function to indicate that after transmission of the last - data, the CRC should be transmitted. - 5. After transmitting the last data, the SPI transmits the CRC. The SPI_CR1_CRCNEXT - bit is reset. The CRC is also received and compared against the SPI_RXCRCR - value. - If the value does not match, the SPI_FLAG_CRCERR flag is set and an interrupt - can be generated when the SPI_I2S_IT_ERR interrupt is enabled. - -Note: ------ - - It is advised to don't read the calculate CRC values during the communication. - - - When the SPI is in slave mode, be careful to enable CRC calculation only - when the clock is stable, that is, when the clock is in the steady state. - If not, a wrong CRC calculation may be done. In fact, the CRC is sensitive - to the SCK slave input clock as soon as CRCEN is set, and this, whatever - the value of the SPE bit. - - - With high bitrate frequencies, be careful when transmitting the CRC. - As the number of used CPU cycles has to be as low as possible in the CRC - transfer phase, it is forbidden to call software functions in the CRC - transmission sequence to avoid errors in the last data and CRC reception. - In fact, CRCNEXT bit has to be written before the end of the transmission/reception - of the last data. - - - For high bit rate frequencies, it is advised to use the DMA mode to avoid the - degradation of the SPI speed performance due to CPU accesses impacting the - SPI bandwidth. - - - When the STM32L15xxx are configured as slaves and the NSS hardware mode is - used, the NSS pin needs to be kept low between the data phase and the CRC - phase. - - - When the SPI is configured in slave mode with the CRC feature enabled, CRC - calculation takes place even if a high level is applied on the NSS pin. - This may happen for example in case of a multislave environment where the - communication master addresses slaves alternately. - - - Between a slave deselection (high level on NSS) and a new slave selection - (low level on NSS), the CRC value should be cleared on both master and slave - sides in order to resynchronize the master and slave for their respective - CRC calculation. - - To clear the CRC, follow the procedure below: - 1. Disable SPI using the SPI_Cmd() function - 2. Disable the CRC calculation using the SPI_CalculateCRC() function. - 3. Enable the CRC calculation using the SPI_CalculateCRC() function. - 4. Enable SPI using the SPI_Cmd() function. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the CRC value calculation of the transferred bytes. - * @param SPIx: where x can be 1 or 2 to select the SPI peripheral. - * @param NewState: new state of the SPIx CRC value calculation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected SPI CRC calculation */ - SPIx->CR1 |= SPI_CR1_CRCEN; - } - else - { - /* Disable the selected SPI CRC calculation */ - SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCEN); - } -} - -/** - * @brief Transmit the SPIx CRC value. - * @param SPIx: where x can be 1 or 2 to select the SPI peripheral. - * @retval None - */ -void SPI_TransmitCRC(SPI_TypeDef* SPIx) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - /* Enable the selected SPI CRC transmission */ - SPIx->CR1 |= SPI_CR1_CRCNEXT; -} - -/** - * @brief Returns the transmit or the receive CRC register value for the specified SPI. - * @param SPIx: where x can be 1 or 2 to select the SPI peripheral. - * @param SPI_CRC: specifies the CRC register to be read. - * This parameter can be one of the following values: - * @arg SPI_CRC_Tx: Selects Tx CRC register - * @arg SPI_CRC_Rx: Selects Rx CRC register - * @retval The selected CRC register value.. - */ -uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC) -{ - uint16_t crcreg = 0; - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_CRC(SPI_CRC)); - if (SPI_CRC != SPI_CRC_Rx) - { - /* Get the Tx CRC register */ - crcreg = SPIx->TXCRCR; - } - else - { - /* Get the Rx CRC register */ - crcreg = SPIx->RXCRCR; - } - /* Return the selected CRC register */ - return crcreg; -} - -/** - * @brief Returns the CRC Polynomial register value for the specified SPI. - * @param SPIx: where x can be 1 or 2 to select the SPI peripheral. - * @retval The CRC Polynomial register value. - */ -uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - /* Return the CRC polynomial register */ - return SPIx->CRCPR; -} - -/** - * @} - */ - -/** @defgroup SPI_Group4 DMA transfers management functions - * @brief DMA transfers management functions - * -@verbatim - =============================================================================== - DMA transfers management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the SPIx DMA interface. - * @param SPIx: where x can be 1 or 2 in SPI mode - * @param SPI_I2S_DMAReq: specifies the SPI DMA transfer request to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request - * @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request - * @param NewState: new state of the selected SPI DMA transfer request. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_SPI_I2S_DMAREQ(SPI_I2S_DMAReq)); - - if (NewState != DISABLE) - { - /* Enable the selected SPI DMA requests */ - SPIx->CR2 |= SPI_I2S_DMAReq; - } - else - { - /* Disable the selected SPI DMA requests */ - SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq; - } -} - -/** - * @} - */ - -/** @defgroup SPI_Group5 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - - This section provides a set of functions allowing to configure the SPI Interrupts - sources and check or clear the flags or pending bits status. - The user should identify which mode will be used in his application to manage - the communication: Polling mode, Interrupt mode or DMA mode. - - Polling Mode - ============= - In Polling Mode, the SPI communication can be managed by 6 flags: - 1. SPI_I2S_FLAG_TXE : to indicate the status of the transmit buffer register - 2. SPI_I2S_FLAG_RXNE : to indicate the status of the receive buffer register - 3. SPI_I2S_FLAG_BSY : to indicate the state of the communication layer of the SPI. - 4. SPI_FLAG_CRCERR : to indicate if a CRC Calculation error occur - 5. SPI_FLAG_MODF : to indicate if a Mode Fault error occur - 6. SPI_I2S_FLAG_OVR : to indicate if an Overrun error occur - -Note: Do not use the BSY flag to handle each data transmission or reception. ------ It is better to use the TXE and RXNE flags instead. - - In this Mode it is advised to use the following functions: - - FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); - - void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); - - Interrupt Mode - =============== - In Interrupt Mode, the SPI communication can be managed by 3 interrupt sources - and 5 pending bits: - Pending Bits: - ------------- - 1. SPI_I2S_IT_TXE : to indicate the status of the transmit buffer register - 2. SPI_I2S_IT_RXNE : to indicate the status of the receive buffer register - 3. SPI_IT_CRCERR : to indicate if a CRC Calculation error occur - 4. SPI_IT_MODF : to indicate if a Mode Fault error occur - 5. SPI_I2S_IT_OVR : to indicate if an Overrun error occur - - Interrupt Source: - ----------------- - 1. SPI_I2S_IT_TXE: specifies the interrupt source for the Tx buffer empty - interrupt. - 2. SPI_I2S_IT_RXNE : specifies the interrupt source for the Rx buffer not - empty interrupt. - 3. SPI_I2S_IT_ERR : specifies the interrupt source for the errors interrupt. - - In this Mode it is advised to use the following functions: - - void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState); - - ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); - - void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); - - DMA Mode - ======== - In DMA Mode, the SPI communication can be managed by 2 DMA Channel requests: - 1. SPI_I2S_DMAReq_Tx: specifies the Tx buffer DMA transfer request - 2. SPI_I2S_DMAReq_Rx: specifies the Rx buffer DMA transfer request - - In this Mode it is advised to use the following function: - - void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState); - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified SPI interrupts. - * @param SPIx: where x can be 1 or 2 in SPI mode - * @param SPI_I2S_IT: specifies the SPI interrupt source to be enabled or disabled. - * This parameter can be one of the following values: - * @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask - * @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask - * @arg SPI_I2S_IT_ERR: Error interrupt mask - * @param NewState: new state of the specified SPI interrupt. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState) -{ - uint16_t itpos = 0, itmask = 0 ; - - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT)); - - /* Get the SPI IT index */ - itpos = SPI_I2S_IT >> 4; - - /* Set the IT mask */ - itmask = (uint16_t)1 << (uint16_t)itpos; - - if (NewState != DISABLE) - { - /* Enable the selected SPI interrupt */ - SPIx->CR2 |= itmask; - } - else - { - /* Disable the selected SPI interrupt */ - SPIx->CR2 &= (uint16_t)~itmask; - } -} - -/** - * @brief Checks whether the specified SPI flag is set or not. - * @param SPIx: where x can be 1 or 2 in SPI mode - * @param SPI_I2S_FLAG: specifies the SPI flag to check. - * This parameter can be one of the following values: - * @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag. - * @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag. - * @arg SPI_I2S_FLAG_BSY: Busy flag. - * @arg SPI_I2S_FLAG_OVR: Overrun flag. - * @arg SPI_I2S_FLAG_MODF: Mode Fault flag. - * @arg SPI_I2S_FLAG_CRCERR: CRC Error flag. - * @retval The new state of SPI_I2S_FLAG (SET or RESET). - */ -FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG)); - - /* Check the status of the specified SPI flag */ - if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET) - { - /* SPI_I2S_FLAG is set */ - bitstatus = SET; - } - else - { - /* SPI_I2S_FLAG is reset */ - bitstatus = RESET; - } - /* Return the SPI_I2S_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the SPIx CRC Error (CRCERR) flag. - * @param SPIx: where x can be 1 or 2 in SPI mode - * @param SPI_I2S_FLAG: specifies the SPI flag to clear. - * This function clears only CRCERR flag. - * @note - * - OVR (OverRun error) flag is cleared by software sequence: a read - * operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by a read - * operation to SPI_SR register (SPI_I2S_GetFlagStatus()). - * - MODF (Mode Fault) flag is cleared by software sequence: a read/write - * operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by a - * write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI). - * @retval None - */ -void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_I2S_CLEAR_FLAG(SPI_I2S_FLAG)); - - /* Clear the selected SPI CRC Error (CRCERR) flag */ - SPIx->SR = (uint16_t)~SPI_I2S_FLAG; -} - -/** - * @brief Checks whether the specified SPI interrupt has occurred or not. - * @param SPIx: where x can be - * - 1 or 2 in SPI mode - * @param SPI_I2S_IT: specifies the SPI interrupt source to check. - * This parameter can be one of the following values: - * @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt. - * @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt. - * @arg SPI_I2S_IT_OVR: Overrun interrupt. - * @arg SPI_I2S_IT_MODF: Mode Fault interrupt. - * @arg SPI_I2S_IT_CRCERR: CRC Error interrupt. - * @retval The new state of SPI_I2S_IT (SET or RESET). - */ -ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT) -{ - ITStatus bitstatus = RESET; - uint16_t itpos = 0, itmask = 0, enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT)); - - /* Get the SPI_I2S_IT index */ - itpos = 0x01 << (SPI_I2S_IT & 0x0F); - - /* Get the SPI_I2S_IT IT mask */ - itmask = SPI_I2S_IT >> 4; - - /* Set the IT mask */ - itmask = 0x01 << itmask; - - /* Get the SPI_I2S_IT enable bit status */ - enablestatus = (SPIx->CR2 & itmask) ; - - /* Check the status of the specified SPI interrupt */ - if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus) - { - /* SPI_I2S_IT is set */ - bitstatus = SET; - } - else - { - /* SPI_I2S_IT is reset */ - bitstatus = RESET; - } - /* Return the SPI_I2S_IT status */ - return bitstatus; -} - -/** - * @brief Clears the SPIx CRC Error (CRCERR) interrupt pending bit. - * @param SPIx: where x can be - * - 1 or 2 in SPI mode - * @param SPI_I2S_IT: specifies the SPI interrupt pending bit to clear. - * This function clears only CRCERR interrupt pending bit. - * @note - * - OVR (OverRun Error) interrupt pending bit is cleared by software - * sequence: a read operation to SPI_DR register (SPI_I2S_ReceiveData()) - * followed by a read operation to SPI_SR register (SPI_I2S_GetITStatus()). - * - MODF (Mode Fault) interrupt pending bit is cleared by software sequence: - * a read/write operation to SPI_SR register (SPI_I2S_GetITStatus()) - * followed by a write operation to SPI_CR1 register (SPI_Cmd() to enable - * the SPI). - * @retval None - */ -void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT) -{ - uint16_t itpos = 0; - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_I2S_CLEAR_IT(SPI_I2S_IT)); - - /* Get the SPI_I2S IT index */ - itpos = 0x01 << (SPI_I2S_IT & 0x0F); - - /* Clear the selected SPI CRC Error (CRCERR) interrupt pending bit */ - SPIx->SR = (uint16_t)~itpos; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_syscfg.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_syscfg.c deleted file mode 100644 index b59f8e86e..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_syscfg.c +++ /dev/null @@ -1,561 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_syscfg.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the SYSCFG and RI peripherals: - * - SYSCFG Initialization and Configuration - * - RI Initialization and Configuration - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * - * This driver provides functions for: - * - * 1. Remapping the memory accessible in the code area using - * SYSCFG_MemoryRemapConfig() - * 2. Manage the EXTI lines connection to the GPIOs using - * SYSCFG_EXTILineConfig(). - * 3. Routing of I/Os toward the input captures of timers (TIM2, TIM3 and TIM4). - * 4. Input routing of COMP1 and COMP2 - * 5. Routing of internal reference voltage VREFINT to PB0 and PB1. - * - * 6. The RI registers can be accessed only when the comparator - * APB interface clock is enabled. - * To enable comparator clock use: - * RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP, ENABLE); - * - * Following functions uses RI registers: - * - SYSCFG_RIDeInit() - * - SYSCFG_RITIMSelect() - * - SYSCFG_RITIMInputCaptureConfig() - * - SYSCFG_RIResistorConfig() - * - SYSCFG_RIIOSwitchConfig() - * - SYSCFG_RISwitchControlModeCmd() - * - SYSCFG_RIHysteresisConfig() - * - * 7- The SYSCFG registers can be accessed only when the SYSCFG - * interface APB clock is enabled. - * To enable SYSCFG APB clock use: - * RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); - * - * Following functions uses SYSCFG registers: - * - SYSCFG_MemoryRemapConfig() - * - SYSCFG_USBPuCmd() - * - SYSCFG_EXTILineConfig() - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_syscfg.h" -#include "stm32l1xx_rcc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup SYSCFG - * @brief SYSCFG driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define TIM_SELECT_MASK ((uint32_t)0xFFFCFFFF) /*!< TIM select mask */ -#define IC_ROUTING_MASK ((uint32_t)0x0000000F) /*!< Input Capture routing mask */ - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup SYSCFG_Private_Functions - * @{ - */ - -/** @defgroup SYSCFG_Group1 SYSCFG Initialization and Configuration functions - * @brief SYSCFG Initialization and Configuration functions - * -@verbatim - =============================================================================== - SYSCFG Initialization and Configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the SYSCFG registers to their default reset values. - * @param None - * @retval None - * @ Note: MEMRMP bits are not reset by APB2 reset. - */ -void SYSCFG_DeInit(void) -{ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, DISABLE); -} - -/** - * @brief Deinitializes the RI registers to their default reset values. - * @param None - * @retval None - */ -void SYSCFG_RIDeInit(void) -{ - RI->ICR = ((uint32_t)0x00000000); /*!< Set RI->ICR to reset value */ - RI->ASCR1 = ((uint32_t)0x00000000); /*!< Set RI->ASCR1 to reset value */ - RI->ASCR2 = ((uint32_t)0x00000000); /*!< Set RI->ASCR2 to reset value */ - RI->HYSCR1 = ((uint32_t)0x00000000); /*!< Set RI->HYSCR1 to reset value */ - RI->HYSCR2 = ((uint32_t)0x00000000); /*!< Set RI->HYSCR2 to reset value */ - RI->HYSCR3 = ((uint32_t)0x00000000); /*!< Set RI->HYSCR3 to reset value */ -} - -/** - * @brief Changes the mapping of the specified memory. - * @param SYSCFG_Memory: selects the memory remapping. - * This parameter can be one of the following values: - * @arg SYSCFG_MemoryRemap_Flash: Main Flash memory mapped at 0x00000000 - * @arg SYSCFG_MemoryRemap_SystemFlash: System Flash memory mapped at 0x00000000 - * @arg SYSCFG_MemoryRemap_SRAM: Embedded SRAM mapped at 0x00000000 - * @retval None - */ -void SYSCFG_MemoryRemapConfig(uint8_t SYSCFG_MemoryRemap) -{ - /* Check the parameters */ - assert_param(IS_SYSCFG_MEMORY_REMAP_CONFING(SYSCFG_MemoryRemap)); - SYSCFG->MEMRMP = SYSCFG_MemoryRemap; -} - -/** - * @brief Control the internal pull-up on USB DP line. - * @param NewState: New state of the internal pull-up on USB DP line. - * This parameter can be ENABLE: Connect internal pull-up on USB DP line. - * or DISABLE: Disconnect internal pull-up on USB DP line. - * @retval None - */ -void SYSCFG_USBPuCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Connect internal pull-up on USB DP line */ - SYSCFG->PMC |= (uint32_t) SYSCFG_PMC_USB_PU; - } - else - { - /* Disconnect internal pull-up on USB DP line */ - SYSCFG->PMC &= (uint32_t)(~SYSCFG_PMC_USB_PU); - } -} - -/** - * @brief Selects the GPIO pin used as EXTI Line. - * @param EXTI_PortSourceGPIOx : selects the GPIO port to be used as source - * for EXTI lines where x can be (A, B, C, D, E or H). - * @param EXTI_PinSourcex: specifies the EXTI line to be configured. - * This parameter can be EXTI_PinSourcex where x can be (0..15) - * @retval None - */ -void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex) -{ - uint32_t tmp = 0x00; - - /* Check the parameters */ - assert_param(IS_EXTI_PORT_SOURCE(EXTI_PortSourceGPIOx)); - assert_param(IS_EXTI_PIN_SOURCE(EXTI_PinSourcex)); - - tmp = ((uint32_t)0x0F) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03)); - SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] &= ~tmp; - SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] |= (((uint32_t)EXTI_PortSourceGPIOx) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03))); -} - -/** - * @} - */ - -/** @defgroup SYSCFG_Group2 RI Initialization and Configuration functions - * @brief RI Initialization and Configuration functions - * -@verbatim - =============================================================================== - RI Initialization and Configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Configures the routing interface to select which Timer to be routed. - * @note Routing capability can be applied only on one of the three timers - * (TIM2, TIM3 or TIM4) at a time. - * @param TIM_Select: Timer select. - * This parameter can be one of the following values: - * @arg TIM_Select_None: No timer selected and default Timer mapping is enabled. - * @arg TIM_Select_TIM2: Timer 2 Input Captures to be routed. - * @arg TIM_Select_TIM3: Timer 3 Input Captures to be routed. - * @arg TIM_Select_TIM4: Timer 4 Input Captures to be routed. - * @retval None. - */ -void SYSCFG_RITIMSelect(uint32_t TIM_Select) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RI_TIM(TIM_Select)); - - /* Get the old register value */ - tmpreg = RI->ICR; - - /* Clear the TIMx select bits */ - tmpreg &= TIM_SELECT_MASK; - - /* Select the Timer */ - tmpreg |= (TIM_Select); - - /* Write to RI->ICR register */ - RI->ICR = tmpreg; -} - -/** - * @brief Configures the routing interface to map Input Capture 1, 2, 3 or 4 - * to a selected I/O pin. - * @param RI_InputCapture selects which input capture to be routed. - * This parameter can be one (or combination) of the following parameters: - * @arg RI_InputCapture_IC1: Input capture 1 is selected. - * @arg RI_InputCapture_IC2: Input capture 2 is selected. - * @arg RI_InputCapture_IC3: Input capture 3 is selected. - * @arg RI_InputCapture_IC4: Input capture 4 is selected. - * @param RI_InputCaptureRouting: selects which pin to be routed to Input Capture. - * This parameter can be one of the following values: - * @arg RI_InputCaptureRouting_0 to RI_InputCaptureRouting_15 - * e.g. - * SYSCFG_RITIMSelect(TIM_Select_TIM2) - * SYSCFG_RITIMInputCaptureConfig(RI_InputCapture_IC1, RI_InputCaptureRouting_1) - * allows routing of Input capture IC1 of TIM2 to PA4. - * For details about correspondence between RI_InputCaptureRouting_x - * and I/O pins refer to the parameters' description in the header file - * or refer to the product reference manual. - * @note Input capture selection bits are not reset by this function. - * To reset input capture selection bits, use SYSCFG_RIDeInit() function. - * @note The I/O should be configured in alternate function mode (AF14) using - * GPIO_PinAFConfig() function. - * @retval None. - */ -void SYSCFG_RITIMInputCaptureConfig(uint32_t RI_InputCapture, uint32_t RI_InputCaptureRouting) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RI_INPUTCAPTURE(RI_InputCapture)); - assert_param(IS_RI_INPUTCAPTURE_ROUTING(RI_InputCaptureRouting)); - - /* Get the old register value */ - tmpreg = RI->ICR; - - /* Select input captures to be routed */ - tmpreg |= (RI_InputCapture); - - if((RI_InputCapture & RI_InputCapture_IC1) == RI_InputCapture_IC1) - { - /* Clear the input capture select bits */ - tmpreg &= (uint32_t)(~IC_ROUTING_MASK); - - /* Set RI_InputCaptureRouting bits */ - tmpreg |= (uint32_t)( RI_InputCaptureRouting); - } - - if((RI_InputCapture & RI_InputCapture_IC2) == RI_InputCapture_IC2) - { - /* Clear the input capture select bits */ - tmpreg &= (uint32_t)(~(IC_ROUTING_MASK << 4)); - - /* Set RI_InputCaptureRouting bits */ - tmpreg |= (uint32_t)( (RI_InputCaptureRouting << 4)); - } - - if((RI_InputCapture & RI_InputCapture_IC3) == RI_InputCapture_IC3) - { - /* Clear the input capture select bits */ - tmpreg &= (uint32_t)(~(IC_ROUTING_MASK << 8)); - - /* Set RI_InputCaptureRouting bits */ - tmpreg |= (uint32_t)( (RI_InputCaptureRouting << 8)); - } - - if((RI_InputCapture & RI_InputCapture_IC4) == RI_InputCapture_IC4) - { - /* Clear the input capture select bits */ - tmpreg &= (uint32_t)(~(IC_ROUTING_MASK << 12)); - - /* Set RI_InputCaptureRouting bits */ - tmpreg |= (uint32_t)( (RI_InputCaptureRouting << 12)); - } - - /* Write to RI->ICR register */ - RI->ICR = tmpreg; -} -/** - * @brief Configures the Pull-up and Pull-down Resistors - * @param RI_Resistor selects the resistor to connect. - * This parameter can be one of the following values: - * @arg RI_Resistor_10KPU: 10K pull-up resistor - * @arg RI_Resistor_400KPU: 400K pull-up resistor - * @arg RI_Resistor_10KPD: 10K pull-down resistor - * @arg RI_Resistor_400KPD: 400K pull-down resistor - * @param NewState: New state of the analog switch associated to the selected - * resistor. - * This parameter can be: - * ENABLE so the selected resistor is connected - * or DISABLE so the selected resistor is disconnected - * @note To avoid extra power consumption, only one resistor should be enabled - * at a time. - * @retval None - */ -void SYSCFG_RIResistorConfig(uint32_t RI_Resistor, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RI_RESISTOR(RI_Resistor)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the resistor */ - COMP->CSR |= (uint32_t) RI_Resistor; - } - else - { - /* Disable the Resistor */ - COMP->CSR &= (uint32_t) (~RI_Resistor); - } -} - -/** - * @brief Close or Open the routing interface Input Output switches. - * @param RI_IOSwitch: selects the I/O analog switch number. - * This parameter can be one of the following values: - * @arg RI_IOSwitch_CH0 --> RI_IOSwitch_CH15 - * @arg RI_IOSwitch_CH18 --> RI_IOSwitch_CH25 - * @arg RI_IOSwitch_GR10_1 --> RI_IOSwitch_GR10_4 - * @arg RI_IOSwitch_GR6_1 --> RI_IOSwitch_GR6_2 - * @arg RI_IOSwitch_GR5_1 --> RI_IOSwitch_GR5_3 - * @arg RI_IOSwitch_GR4_1 --> RI_IOSwitch_GR4_3 - * @arg RI_IOSwitch_VCOMP - * @param NewState: New state of the analog switch. - * This parameter can be - * ENABLE so the Input Output switch is closed - * or DISABLE so the Input Output switch is open - * @retval None - */ -void SYSCFG_RIIOSwitchConfig(uint32_t RI_IOSwitch, FunctionalState NewState) -{ - uint32_t ioswitchmask = 0; - - /* Check the parameters */ - assert_param(IS_RI_IOSWITCH(RI_IOSwitch)); - - /* Read Analog switch register index */ - ioswitchmask = RI_IOSwitch >> 31; - - /* Get Bits[30:0] of the IO switch */ - RI_IOSwitch &= 0x7FFFFFFF; - - - if (NewState != DISABLE) - { - if (ioswitchmask != 0) - { - /* Close the analog switches */ - RI->ASCR1 |= RI_IOSwitch; - } - else - { - /* Open the analog switches */ - RI->ASCR2 |= RI_IOSwitch; - } - } - else - { - if (ioswitchmask != 0) - { - /* Close the analog switches */ - RI->ASCR1 &= (~ (uint32_t)RI_IOSwitch); - } - else - { - /* Open the analog switches */ - RI->ASCR2 &= (~ (uint32_t)RI_IOSwitch); - } - } -} - -/** - * @brief Enable or disable the switch control mode. - * @param NewState: New state of the switch control mode. This parameter can - * be ENABLE: ADC analog switches closed if the corresponding - * I/O switch is also closed. - * When using COMP1 switch control mode must be enabled. - * or DISABLE: ADC analog switches open or controlled by the ADC interface. - * When using the ADC for acquisition switch control mode - * must be disabled. - * @note COMP1 comparator and ADC cannot be used at the same time since - * they share the ADC switch matrix. - * @retval None - */ -void SYSCFG_RISwitchControlModeCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the Switch control mode */ - RI->ASCR1 |= (uint32_t) RI_ASCR1_SCM; - } - else - { - /* Disable the Switch control mode */ - RI->ASCR1 &= (uint32_t)(~RI_ASCR1_SCM); - } -} - -/** - * @brief Enable or disable Hysteresis of the input schmitt triger of Ports A..E - * When the I/Os are programmed in input mode by standard I/O port - * registers, the Schmitt trigger and the hysteresis are enabled by default. - * When hysteresis is disabled, it is possible to read the - * corresponding port with a trigger level of VDDIO/2. - * @param RI_Port: selects the GPIO Port. - * This parameter can be one of the following values: - * @arg RI_PortA : Port A is selected - * @arg RI_PortB : Port B is selected - * @arg RI_PortC : Port C is selected - * @arg RI_PortD : Port D is selected - * @arg RI_PortE : Port E is selected - * @param RI_Pin : Selects the pin(s) on which to enable or disable hysteresis. - * This parameter can any value from RI_Pin_x where x can be (0..15) or RI_Pin_All. - * @param NewState new state of the Hysteresis. - * This parameter can be: - * ENABLE so the Hysteresis is on - * or DISABLE so the Hysteresis is off - * @retval None - */ -void SYSCFG_RIHysteresisConfig(uint8_t RI_Port, uint16_t RI_Pin, - FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RI_PORT(RI_Port)); - assert_param(IS_RI_PIN(RI_Pin)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if(RI_Port == RI_PortA) - { - if (NewState != DISABLE) - { - /* Hysteresis on */ - RI->HYSCR1 &= (uint32_t)~((uint32_t)RI_Pin); - } - else - { - /* Hysteresis off */ - RI->HYSCR1 |= (uint32_t) RI_Pin; - } - } - - else if(RI_Port == RI_PortB) - { - - if (NewState != DISABLE) - { - /* Hysteresis on */ - RI->HYSCR1 &= (uint32_t) (~((uint32_t)RI_Pin) << 16); - } - else - { - /* Hysteresis off */ - RI->HYSCR1 |= (uint32_t) ((uint32_t)(RI_Pin) << 16); - } - } - - else if(RI_Port == RI_PortC) - { - - if (NewState != DISABLE) - { - /* Hysteresis on */ - RI->HYSCR2 &= (uint32_t) (~((uint32_t)RI_Pin)); - } - else - { - /* Hysteresis off */ - RI->HYSCR2 |= (uint32_t) (RI_Pin ); - } - } - else if(RI_Port == RI_PortD) - { - if (NewState != DISABLE) - { - /* Hysteresis on */ - RI->HYSCR2 &= (uint32_t) (~((uint32_t)RI_Pin) << 16); - } - else - { - /* Hysteresis off */ - RI->HYSCR2 |= (uint32_t) ((uint32_t)(RI_Pin) << 16); - - } - } - else /* RI_Port == RI_PortE */ - { - if (NewState != DISABLE) - { - /* Hysteresis on */ - RI->HYSCR3 &= (uint32_t) (~((uint32_t)RI_Pin)); - } - else - { - /* Hysteresis off */ - RI->HYSCR3 |= (uint32_t) (RI_Pin ); - } - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_tim.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_tim.c deleted file mode 100644 index d7ed2308b..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_tim.c +++ /dev/null @@ -1,2832 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_tim.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the TIM peripheral: - * - TimeBase management - * - Output Compare management - * - Input Capture management - * - Interrupts, DMA and flags management - * - Clocks management - * - Synchronization management - * - Specific interface management - * - Specific remapping management - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * This driver provides functions to configure and program the TIM - * of all STM32L1xx devices - * These functions are split in 8 groups: - * - * 1. TIM TimeBase management: this group includes all needed functions - * to configure the TM Timebase unit: - * - Set/Get Prescaler - * - Set/Get Autoreload - * - Counter modes configuration - * - Set Clock division - * - Select the One Pulse mode - * - Update Request Configuration - * - Update Disable Configuration - * - Auto-Preload Configuration - * - Enable/Disable the counter - * - * 2. TIM Output Compare management: this group includes all needed - * functions to configure the Capture/Compare unit used in Output - * compare mode: - * - Configure each channel, independently, in Output Compare mode - * - Select the output compare modes - * - Select the Polarities of each channel - * - Set/Get the Capture/Compare register values - * - Select the Output Compare Fast mode - * - Select the Output Compare Forced mode - * - Output Compare-Preload Configuration - * - Clear Output Compare Reference - * - Select the OCREF Clear signal - * - Enable/Disable the Capture/Compare Channels - * - * 3. TIM Input Capture management: this group includes all needed - * functions to configure the Capture/Compare unit used in - * Input Capture mode: - * - Configure each channel in input capture mode - * - Configure Channel1/2 in PWM Input mode - * - Set the Input Capture Prescaler - * - Get the Capture/Compare values - * - * 4. TIM interrupts, DMA and flags management - * - Enable/Disable interrupt sources - * - Get flags status - * - Clear flags/ Pending bits - * - Enable/Disable DMA requests - * - Configure DMA burst mode - * - Select CaptureCompare DMA request - * - * 5. TIM clocks management: this group includes all needed functions - * to configure the clock controller unit: - * - Select internal/External clock - * - Select the external clock mode: ETR(Mode1/Mode2), TIx or ITRx - * - * 6. TIM synchronization management: this group includes all needed - * functions to configure the Synchronization unit: - * - Select Input Trigger - * - Select Output Trigger - * - Select Master Slave Mode - * - ETR Configuration when used as external trigger - * - * 7. TIM specific interface management, this group includes all - * needed functions to use the specific TIM interface: - * - Encoder Interface Configuration - * - Select Hall Sensor - * - * 8. TIM specific remapping management includes the Remapping - * configuration of specific timers - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_tim.h" -#include "stm32l1xx_rcc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup TIM - * @brief TIM driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* ---------------------- TIM registers bit mask ------------------------ */ -#define SMCR_ETR_MASK ((uint16_t)0x00FF) -#define CCMR_OFFSET ((uint16_t)0x0018) -#define CCER_CCE_SET ((uint16_t)0x0001) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ - -static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter); -static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter); -static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter); -static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter); -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup TIM_Private_Functions - * @{ - */ - -/** @defgroup TIM_Group1 TimeBase management functions - * @brief TimeBase management functions - * -@verbatim - =============================================================================== - TimeBase management functions - =============================================================================== - - =================================================================== - TIM Driver: how to use it in Timing(Time base) Mode - =================================================================== - To use the Timer in Timing(Time base) mode, the following steps are mandatory: - - 1. Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function - - 2. Fill the TIM_TimeBaseInitStruct with the desired parameters. - - 3. Call TIM_TimeBaseInit(TIMx, &TIM_TimeBaseInitStruct) to configure the Time Base unit - with the corresponding configuration - - 4. Enable the NVIC if you need to generate the update interrupt. - - 5. Enable the corresponding interrupt using the function TIM_ITConfig(TIMx, TIM_IT_Update) - - 6. Call the TIM_Cmd(ENABLE) function to enable the TIM counter. - - Note1: All other functions can be used seperatly to modify, if needed, - a specific feature of the Timer. - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the TIMx peripheral registers to their default reset values. - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @retval None - * - */ -void TIM_DeInit(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - - if (TIMx == TIM2) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, DISABLE); - } - else if (TIMx == TIM3) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, DISABLE); - } - else if (TIMx == TIM4) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, DISABLE); - } - - else if (TIMx == TIM6) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, DISABLE); - } - else if (TIMx == TIM7) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, DISABLE); - } - - else if (TIMx == TIM9) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, DISABLE); - } - else if (TIMx == TIM10) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, DISABLE); - } - else - { - if (TIMx == TIM11) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, DISABLE); - } - } - -} - -/** - * @brief Initializes the TIMx Time Base Unit peripheral according to - * the specified parameters in the TIM_TimeBaseInitStruct. - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef - * structure that contains the configuration information for - * the specified TIM peripheral. - * @retval None - */ -void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) -{ - uint16_t tmpcr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode)); - assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision)); - - tmpcr1 = TIMx->CR1; - - if(((TIMx) == TIM2) || ((TIMx) == TIM3) || ((TIMx) == TIM4)) - { - /* Select the Counter Mode */ - tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS))); - tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode; - } - - if(((TIMx) != TIM6) && ((TIMx) != TIM7)) - { - /* Set the clock division */ - tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD)); - tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision; - } - - TIMx->CR1 = tmpcr1; - - /* Set the Autoreload value */ - TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ; - - /* Set the Prescaler value */ - TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler; - - /* Generate an update event to reload the Prescaler value immediatly */ - TIMx->EGR = TIM_PSCReloadMode_Immediate; -} - -/** - * @brief Fills each TIM_TimeBaseInitStruct member with its default value. - * @param TIM_TimeBaseInitStruct : pointer to a TIM_TimeBaseInitTypeDef - * structure which will be initialized. - * @retval None - */ -void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) -{ - /* Set the default configuration */ - TIM_TimeBaseInitStruct->TIM_Period = 0xFFFF; - TIM_TimeBaseInitStruct->TIM_Prescaler = 0x0000; - TIM_TimeBaseInitStruct->TIM_ClockDivision = TIM_CKD_DIV1; - TIM_TimeBaseInitStruct->TIM_CounterMode = TIM_CounterMode_Up; -} - -/** - * @brief Configures the TIMx Prescaler. - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @param Prescaler: specifies the Prescaler Register value - * @param TIM_PSCReloadMode: specifies the TIM Prescaler Reload mode - * This parameter can be one of the following values: - * @arg TIM_PSCReloadMode_Update: The Prescaler is loaded at the update event. - * @arg TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediatly. - * @retval None - */ -void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_PRESCALER_RELOAD(TIM_PSCReloadMode)); - - /* Set the Prescaler value */ - TIMx->PSC = Prescaler; - /* Set or reset the UG Bit */ - TIMx->EGR = TIM_PSCReloadMode; -} - -/** - * @brief Specifies the TIMx Counter Mode to be used. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_CounterMode: specifies the Counter Mode to be used - * This parameter can be one of the following values: - * @arg TIM_CounterMode_Up: TIM Up Counting Mode - * @arg TIM_CounterMode_Down: TIM Down Counting Mode - * @arg TIM_CounterMode_CenterAligned1: TIM Center Aligned Mode1 - * @arg TIM_CounterMode_CenterAligned2: TIM Center Aligned Mode2 - * @arg TIM_CounterMode_CenterAligned3: TIM Center Aligned Mode3 - * @retval None - */ -void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode) -{ - uint16_t tmpcr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_COUNTER_MODE(TIM_CounterMode)); - - tmpcr1 = TIMx->CR1; - /* Reset the CMS and DIR Bits */ - tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS))); - /* Set the Counter Mode */ - tmpcr1 |= TIM_CounterMode; - /* Write to TIMx CR1 register */ - TIMx->CR1 = tmpcr1; -} - -/** - * @brief Sets the TIMx Counter Register value - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @param Counter: specifies the Counter register new value. - * @retval None - */ -void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - - /* Set the Counter Register value */ - TIMx->CNT = Counter; -} - -/** - * @brief Sets the TIMx Autoreload Register value - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @param Autoreload: specifies the Autoreload register new value. - * @retval None - */ -void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - - /* Set the Autoreload Register value */ - TIMx->ARR = Autoreload; -} - -/** - * @brief Gets the TIMx Counter value. - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @retval Counter Register value. - */ -uint32_t TIM_GetCounter(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - - /* Get the Counter Register value */ - return TIMx->CNT; -} - -/** - * @brief Gets the TIMx Prescaler value. - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @retval Prescaler Register value. - */ -uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - - /* Get the Prescaler Register value */ - return TIMx->PSC; -} - -/** - * @brief Enables or Disables the TIMx Update event. - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @param NewState: new state of the TIMx UDIS bit - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Set the Update Disable Bit */ - TIMx->CR1 |= TIM_CR1_UDIS; - } - else - { - /* Reset the Update Disable Bit */ - TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_UDIS); - } -} - -/** - * @brief Configures the TIMx Update Request Interrupt source. - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @param TIM_UpdateSource: specifies the Update source. - * This parameter can be one of the following values: - * @arg TIM_UpdateSource_Regular: Source of update is the counter overflow/underflow - or the setting of UG bit, or an update generation - through the slave mode controller. - * @arg TIM_UpdateSource_Global: Source of update is counter overflow/underflow. - * @retval None - */ -void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_UPDATE_SOURCE(TIM_UpdateSource)); - - if (TIM_UpdateSource != TIM_UpdateSource_Global) - { - /* Set the URS Bit */ - TIMx->CR1 |= TIM_CR1_URS; - } - else - { - /* Reset the URS Bit */ - TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_URS); - } -} - -/** - * @brief Enables or disables TIMx peripheral Preload register on ARR. - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @param NewState: new state of the TIMx peripheral Preload register - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Set the ARR Preload Bit */ - TIMx->CR1 |= TIM_CR1_ARPE; - } - else - { - /* Reset the ARR Preload Bit */ - TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_ARPE); - } -} - -/** - * @brief Selects the TIMxs One Pulse Mode. - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @param TIM_OPMode: specifies the OPM Mode to be used. - * This parameter can be one of the following values: - * @arg TIM_OPMode_Single - * @arg TIM_OPMode_Repetitive - * @retval None - */ -void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_OPM_MODE(TIM_OPMode)); - - /* Reset the OPM Bit */ - TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_OPM); - /* Configure the OPM Mode */ - TIMx->CR1 |= TIM_OPMode; -} - -/** - * @brief Sets the TIMx Clock Division value. - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param TIM_CKD: specifies the clock division value. - * This parameter can be one of the following value: - * @arg TIM_CKD_DIV1: TDTS = Tck_tim - * @arg TIM_CKD_DIV2: TDTS = 2*Tck_tim - * @arg TIM_CKD_DIV4: TDTS = 4*Tck_tim - * @retval None - */ -void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_CKD_DIV(TIM_CKD)); - - /* Reset the CKD Bits */ - TIMx->CR1 &= (uint16_t)~((uint16_t)TIM_CR1_CKD); - /* Set the CKD value */ - TIMx->CR1 |= TIM_CKD; -} - -/** - * @brief Enables or disables the specified TIM peripheral. - * @param TIMx: where x can be 2 to 11 to select the TIMx peripheral. - * @param NewState: new state of the TIMx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the TIM Counter */ - TIMx->CR1 |= TIM_CR1_CEN; - } - else - { - /* Disable the TIM Counter */ - TIMx->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN)); - } -} - -/** - * @} - */ - -/** @defgroup TIM_Group2 Output Compare management functions - * @brief Output Compare management functions - * -@verbatim - =============================================================================== - Output Compare management functions - =============================================================================== - - =================================================================== - TIM Driver: how to use it in Output Compare Mode - =================================================================== - To use the Timer in Output Compare mode, the following steps are mandatory: - - 1. Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function - - 2. Configure the TIM pins by configuring the corresponding GPIO pins - - 2. Configure the Time base unit as described in the first part of this driver, if needed, - else the Timer will run with the default configuration: - - Autoreload value = 0xFFFF - - Prescaler value = 0x0000 - - Counter mode = Up counting - - Clock Division = TIM_CKD_DIV1 - - 3. Fill the TIM_OCInitStruct with the desired parameters including: - - The TIM Output Compare mode: TIM_OCMode - - TIM Output State: TIM_OutputState - - TIM Pulse value: TIM_Pulse - - TIM Output Compare Polarity : TIM_OCPolarity - - 4. Call TIM_OCxInit(TIMx, &TIM_OCInitStruct) to configure the desired channel with the - corresponding configuration - - 5. Call the TIM_Cmd(ENABLE) function to enable the TIM counter. - - Note1: All other functions can be used separately to modify, if needed, - a specific feature of the Timer. - - Note2: In case of PWM mode, this function is mandatory: - TIM_OCxPreloadConfig(TIMx, TIM_OCPreload_ENABLE); - - Note3: If the corresponding interrupt or DMA request are needed, the user should: - 1. Enable the NVIC (or the DMA) to use the TIM interrupts (or DMA requests). - 2. Enable the corresponding interrupt (or DMA request) using the function - TIM_ITConfig(TIMx, TIM_IT_CCx) (or TIM_DMA_Cmd(TIMx, TIM_DMA_CCx)) - -@endverbatim - * @{ - */ - -/** - * @brief Initializes the TIMx Channel1 according to the specified - * parameters in the TIM_OCInitStruct. - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure - * that contains the configuration information for the specified TIM - * peripheral. - * @retval None - */ -void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - uint16_t tmpccmrx = 0, tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); - assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); - /* Disable the Channel 1: Reset the CC1E Bit */ - TIMx->CCER &= (uint16_t)(~(uint16_t)TIM_CCER_CC1E); - - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - - /* Get the TIMx CCMR1 register value */ - tmpccmrx = TIMx->CCMR1; - - /* Reset the Output Compare Mode Bits */ - tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_OC1M)); - tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_CC1S)); - - /* Select the Output Compare Mode */ - tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; - - /* Reset the Output Polarity level */ - tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC1P)); - /* Set the Output Compare Polarity */ - tmpccer |= TIM_OCInitStruct->TIM_OCPolarity; - - /* Set the Output State */ - tmpccer |= TIM_OCInitStruct->TIM_OutputState; - - /* Set the Capture Compare Register value */ - TIMx->CCR1 = TIM_OCInitStruct->TIM_Pulse; - - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmrx; - - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Initializes the TIMx Channel2 according to the specified - * parameters in the TIM_OCInitStruct. - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure - * that contains the configuration information for the specified TIM - * peripheral. - * @retval None - */ -void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - uint16_t tmpccmrx = 0, tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); - assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); - /* Disable the Channel 2: Reset the CC2E Bit */ - TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC2E)); - - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - - /* Get the TIMx CCMR1 register value */ - tmpccmrx = TIMx->CCMR1; - - /* Reset the Output Compare Mode Bits */ - tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR1_OC2M)); - - /* Select the Output Compare Mode */ - tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8); - - /* Reset the Output Polarity level */ - tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC2P)); - /* Set the Output Compare Polarity */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 4); - - /* Set the Output State */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 4); - - /* Set the Capture Compare Register value */ - TIMx->CCR2 = TIM_OCInitStruct->TIM_Pulse; - - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmrx; - - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Initializes the TIMx Channel3 according to the specified - * parameters in the TIM_OCInitStruct. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure - * that contains the configuration information for the specified TIM - * peripheral. - * @retval None - */ -void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - uint16_t tmpccmrx = 0, tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); - assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); - - /* Disable the Channel 2: Reset the CC2E Bit */ - TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC3E)); - - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - - /* Get the TIMx CCMR2 register value */ - tmpccmrx = TIMx->CCMR2; - - /* Reset the Output Compare Mode Bits */ - tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_OC3M)); - - /* Select the Output Compare Mode */ - tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; - - /* Reset the Output Polarity level */ - tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC3P)); - /* Set the Output Compare Polarity */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 8); - - /* Set the Output State */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 8); - - /* Set the Capture Compare Register value */ - TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse; - - /* Write to TIMx CCMR2 */ - TIMx->CCMR2 = tmpccmrx; - - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Initializes the TIMx Channel4 according to the specified - * parameters in the TIM_OCInitStruct. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure - * that contains the configuration information for the specified TIM - * peripheral. - * @retval None - */ -void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - uint16_t tmpccmrx = 0, tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); - assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); - - /* Disable the Channel 2: Reset the CC4E Bit */ - TIMx->CCER &= (uint16_t)(~((uint16_t)TIM_CCER_CC4E)); - - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - - /* Get the TIMx CCMR2 register value */ - tmpccmrx = TIMx->CCMR2; - - /* Reset the Output Compare Mode Bits */ - tmpccmrx &= (uint16_t)(~((uint16_t)TIM_CCMR2_OC4M)); - - /* Select the Output Compare Mode */ - tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8); - - /* Reset the Output Polarity level */ - tmpccer &= (uint16_t)(~((uint16_t)TIM_CCER_CC4P)); - /* Set the Output Compare Polarity */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 12); - - /* Set the Output State */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 12); - - /* Set the Capture Compare Register value */ - TIMx->CCR4 = TIM_OCInitStruct->TIM_Pulse; - - /* Write to TIMx CCMR2 */ - TIMx->CCMR2 = tmpccmrx; - - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Fills each TIM_OCInitStruct member with its default value. - * @param TIM_OCInitStruct : pointer to a TIM_OCInitTypeDef structure which will - * be initialized. - * @retval None - */ -void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - /* Set the default configuration */ - TIM_OCInitStruct->TIM_OCMode = TIM_OCMode_Timing; - TIM_OCInitStruct->TIM_OutputState = TIM_OutputState_Disable; - TIM_OCInitStruct->TIM_Pulse = 0x0000; - TIM_OCInitStruct->TIM_OCPolarity = TIM_OCPolarity_High; -} - -/** - * @brief Selects the TIM Output Compare Mode. - * @note This function disables the selected channel before changing the Output - * Compare Mode. - * User has to enable this channel using TIM_CCxCmd and TIM_CCxNCmd functions. - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param TIM_Channel: specifies the TIM Channel - * This parameter can be one of the following values: - * @arg TIM_Channel_1: TIM Channel 1 - * @arg TIM_Channel_2: TIM Channel 2 - * @arg TIM_Channel_3: TIM Channel 3 - * @arg TIM_Channel_4: TIM Channel 4 - * @param TIM_OCMode: specifies the TIM Output Compare Mode. - * This parameter can be one of the following values: - * @arg TIM_OCMode_Timing - * @arg TIM_OCMode_Active - * @arg TIM_OCMode_Toggle - * @arg TIM_OCMode_PWM1 - * @arg TIM_OCMode_PWM2 - * @arg TIM_ForcedAction_Active - * @arg TIM_ForcedAction_InActive - * @retval None - */ -void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode) -{ - uint32_t tmp = 0; - uint16_t tmp1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_OCM(TIM_OCMode)); - - tmp = (uint32_t) TIMx; - tmp += CCMR_OFFSET; - - tmp1 = CCER_CCE_SET << (uint16_t)TIM_Channel; - - /* Disable the Channel: Reset the CCxE Bit */ - TIMx->CCER &= (uint16_t) ~tmp1; - - if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3)) - { - tmp += (TIM_Channel>>1); - - /* Reset the OCxM bits in the CCMRx register */ - *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC1M); - - /* Configure the OCxM bits in the CCMRx register */ - *(__IO uint32_t *) tmp |= TIM_OCMode; - } - else - { - tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1; - - /* Reset the OCxM bits in the CCMRx register */ - *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2M); - - /* Configure the OCxM bits in the CCMRx register */ - *(__IO uint32_t *) tmp |= (uint16_t)(TIM_OCMode << 8); - } -} - -/** - * @brief Sets the TIMx Capture Compare1 Register value - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param Compare1: specifies the Capture Compare1 register new value. - * @retval None - - */ -void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - - /* Set the Capture Compare1 Register value */ - TIMx->CCR1 = Compare1; -} - -/** - * @brief Sets the TIMx Capture Compare2 Register value - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param Compare2: specifies the Capture Compare2 register new value. - * @retval None - - */ -void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - - /* Set the Capture Compare2 Register value */ - TIMx->CCR2 = Compare2; -} - -/** - * @brief Sets the TIMx Capture Compare3 Register value - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param Compare3: specifies the Capture Compare3 register new value. - * @retval None - - */ -void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - - /* Set the Capture Compare3 Register value */ - TIMx->CCR3 = Compare3; -} - -/** - * @brief Sets the TIMx Capture Compare4 Register value - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param Compare4: specifies the Capture Compare4 register new value. - * @retval None - - */ -void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - - /* Set the Capture Compare4 Register value */ - TIMx->CCR4 = Compare4; -} - -/** - * @brief Forces the TIMx output 1 waveform to active or inactive level. - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. - * This parameter can be one of the following values: - * @arg TIM_ForcedAction_Active: Force active level on OC1REF - * @arg TIM_ForcedAction_InActive: Force inactive level on OC1REF. - * @retval None - */ -void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) -{ - uint16_t tmpccmr1 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC1M Bits */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1M); - /* Configure The Forced output Mode */ - tmpccmr1 |= TIM_ForcedAction; - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Forces the TIMx output 2 waveform to active or inactive level. - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM - * peripheral. - * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. - * This parameter can be one of the following values: - * @arg TIM_ForcedAction_Active: Force active level on OC2REF - * @arg TIM_ForcedAction_InActive: Force inactive level on OC2REF. - * @retval None - */ -void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) -{ - uint16_t tmpccmr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); - - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC2M Bits */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2M); - /* Configure The Forced output Mode */ - tmpccmr1 |= (uint16_t)(TIM_ForcedAction << 8); - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Forces the TIMx output 3 waveform to active or inactive level. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. - * This parameter can be one of the following values: - * @arg TIM_ForcedAction_Active: Force active level on OC3REF - * @arg TIM_ForcedAction_InActive: Force inactive level on OC3REF. - * @retval None - */ -void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); - - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC1M Bits */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3M); - /* Configure The Forced output Mode */ - tmpccmr2 |= TIM_ForcedAction; - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Forces the TIMx output 4 waveform to active or inactive level. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. - * This parameter can be one of the following values: - * @arg TIM_ForcedAction_Active: Force active level on OC4REF - * @arg TIM_ForcedAction_InActive: Force inactive level on OC4REF. - * @retval None - */ -void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) -{ - uint16_t tmpccmr2 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); - - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC2M Bits */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4M); - /* Configure The Forced output Mode */ - tmpccmr2 |= (uint16_t)(TIM_ForcedAction << 8); - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Enables or disables the TIMx peripheral Preload register on CCR1. - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param TIM_OCPreload: new state of the TIMx peripheral Preload register - * This parameter can be one of the following values: - * @arg TIM_OCPreload_Enable - * @arg TIM_OCPreload_Disable - * @retval None - */ -void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) -{ - uint16_t tmpccmr1 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); - - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC1PE Bit */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1PE); - /* Enable or Disable the Output Compare Preload feature */ - tmpccmr1 |= TIM_OCPreload; - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Enables or disables the TIMx peripheral Preload register on CCR2. - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param TIM_OCPreload: new state of the TIMx peripheral Preload register - * This parameter can be one of the following values: - * @arg TIM_OCPreload_Enable - * @arg TIM_OCPreload_Disable - * @retval None - */ -void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) -{ - uint16_t tmpccmr1 = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); - - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC2PE Bit */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2PE); - /* Enable or Disable the Output Compare Preload feature */ - tmpccmr1 |= (uint16_t)(TIM_OCPreload << 8); - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Enables or disables the TIMx peripheral Preload register on CCR3. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_OCPreload: new state of the TIMx peripheral Preload register - * This parameter can be one of the following values: - * @arg TIM_OCPreload_Enable - * @arg TIM_OCPreload_Disable - * @retval None - */ -void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); - - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC3PE Bit */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3PE); - /* Enable or Disable the Output Compare Preload feature */ - tmpccmr2 |= TIM_OCPreload; - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Enables or disables the TIMx peripheral Preload register on CCR4. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_OCPreload: new state of the TIMx peripheral Preload register - * This parameter can be one of the following values: - * @arg TIM_OCPreload_Enable - * @arg TIM_OCPreload_Disable - * @retval None - */ -void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); - - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC4PE Bit */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4PE); - /* Enable or Disable the Output Compare Preload feature */ - tmpccmr2 |= (uint16_t)(TIM_OCPreload << 8); - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Configures the TIMx Output Compare 1 Fast feature. - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCFast_Enable: TIM output compare fast enable - * @arg TIM_OCFast_Disable: TIM output compare fast disable - * @retval None - */ -void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) -{ - uint16_t tmpccmr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); - - /* Get the TIMx CCMR1 register value */ - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC1FE Bit */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1FE); - /* Enable or Disable the Output Compare Fast Bit */ - tmpccmr1 |= TIM_OCFast; - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Configures the TIMx Output Compare 2 Fast feature. - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCFast_Enable: TIM output compare fast enable - * @arg TIM_OCFast_Disable: TIM output compare fast disable - * @retval None - */ -void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) -{ - uint16_t tmpccmr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); - - /* Get the TIMx CCMR1 register value */ - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC2FE Bit */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2FE); - /* Enable or Disable the Output Compare Fast Bit */ - tmpccmr1 |= (uint16_t)(TIM_OCFast << 8); - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Configures the TIMx Output Compare 3 Fast feature. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCFast_Enable: TIM output compare fast enable - * @arg TIM_OCFast_Disable: TIM output compare fast disable - * @retval None - */ -void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); - - /* Get the TIMx CCMR2 register value */ - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC3FE Bit */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3FE); - /* Enable or Disable the Output Compare Fast Bit */ - tmpccmr2 |= TIM_OCFast; - /* Write to TIMx CCMR2 */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Configures the TIMx Output Compare 4 Fast feature. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCFast_Enable: TIM output compare fast enable - * @arg TIM_OCFast_Disable: TIM output compare fast disable - * @retval None - */ -void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); - - /* Get the TIMx CCMR2 register value */ - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC4FE Bit */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4FE); - /* Enable or Disable the Output Compare Fast Bit */ - tmpccmr2 |= (uint16_t)(TIM_OCFast << 8); - /* Write to TIMx CCMR2 */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Clears or safeguards the OCREF1 signal on an external event - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCClear_Enable: TIM Output clear enable - * @arg TIM_OCClear_Disable: TIM Output clear disable - * @retval None - */ -void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) -{ - uint16_t tmpccmr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); - - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC1CE Bit */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC1CE); - /* Enable or Disable the Output Compare Clear Bit */ - tmpccmr1 |= TIM_OCClear; - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Clears or safeguards the OCREF2 signal on an external event - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. - - * This parameter can be one of the following values: - * @arg TIM_OCClear_Enable: TIM Output clear enable - * @arg TIM_OCClear_Disable: TIM Output clear disable - * @retval None - */ -void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) -{ - uint16_t tmpccmr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); - - tmpccmr1 = TIMx->CCMR1; - /* Reset the OC2CE Bit */ - tmpccmr1 &= (uint16_t)~((uint16_t)TIM_CCMR1_OC2CE); - /* Enable or Disable the Output Compare Clear Bit */ - tmpccmr1 |= (uint16_t)(TIM_OCClear << 8); - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Clears or safeguards the OCREF3 signal on an external event - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCClear_Enable: TIM Output clear enable - * @arg TIM_OCClear_Disable: TIM Output clear disable - * @retval None - */ -void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); - - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC3CE Bit */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3CE); - /* Enable or Disable the Output Compare Clear Bit */ - tmpccmr2 |= TIM_OCClear; - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Clears or safeguards the OCREF4 signal on an external event - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCClear_Enable: TIM Output clear enable - * @arg TIM_OCClear_Disable: TIM Output clear disable - * @retval None - */ -void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); - - tmpccmr2 = TIMx->CCMR2; - /* Reset the OC4CE Bit */ - tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC4CE); - /* Enable or Disable the Output Compare Clear Bit */ - tmpccmr2 |= (uint16_t)(TIM_OCClear << 8); - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Configures the TIMx channel 1 polarity. - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param TIM_OCPolarity: specifies the OC1 Polarity - * This parmeter can be one of the following values: - * @arg TIM_OCPolarity_High: Output Compare active high - * @arg TIM_OCPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) -{ - uint16_t tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); - - tmpccer = TIMx->CCER; - /* Set or Reset the CC1P Bit */ - tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC1P); - tmpccer |= TIM_OCPolarity; - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx channel 2 polarity. - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param TIM_OCPolarity: specifies the OC2 Polarity - * This parmeter can be one of the following values: - * @arg TIM_OCPolarity_High: Output Compare active high - * @arg TIM_OCPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) -{ - uint16_t tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); - - tmpccer = TIMx->CCER; - /* Set or Reset the CC2P Bit */ - tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC2P); - tmpccer |= (uint16_t)(TIM_OCPolarity << 4); - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx channel 3 polarity. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_OCPolarity: specifies the OC3 Polarity - * This parmeter can be one of the following values: - * @arg TIM_OCPolarity_High: Output Compare active high - * @arg TIM_OCPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) -{ - uint16_t tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); - - tmpccer = TIMx->CCER; - /* Set or Reset the CC3P Bit */ - tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC3P); - tmpccer |= (uint16_t)(TIM_OCPolarity << 8); - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx channel 4 polarity. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_OCPolarity: specifies the OC4 Polarity - * This parmeter can be one of the following values: - * @arg TIM_OCPolarity_High: Output Compare active high - * @arg TIM_OCPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) -{ - uint16_t tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); - - tmpccer = TIMx->CCER; - /* Set or Reset the CC4P Bit */ - tmpccer &= (uint16_t)~((uint16_t)TIM_CCER_CC4P); - tmpccer |= (uint16_t)(TIM_OCPolarity << 12); - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Selects the OCReference Clear source. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_OCReferenceClear: specifies the OCReference Clear source. - * This parameter can be one of the following values: - * @arg TIM_OCReferenceClear_ETRF: The internal OCreference clear input is connected to ETRF. - * @arg TIM_OCReferenceClear_OCREFCLR: The internal OCreference clear input is connected to OCREF_CLR input. - * @retval None - */ -void TIM_SelectOCREFClear(TIM_TypeDef* TIMx, uint16_t TIM_OCReferenceClear) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(TIM_OCREFERENCECECLEAR_SOURCE(TIM_OCReferenceClear)); - - /* Set the TIM_OCReferenceClear source */ - TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_OCCS); - TIMx->SMCR |= TIM_OCReferenceClear; -} - -/** - * @brief Enables or disables the TIM Capture Compare Channel x. - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param TIM_Channel: specifies the TIM Channel - * This parameter can be one of the following values: - * @arg TIM_Channel_1: TIM Channel 1 - * @arg TIM_Channel_2: TIM Channel 2 - * @arg TIM_Channel_3: TIM Channel 3 - * @arg TIM_Channel_4: TIM Channel 4 - * @param TIM_CCx: specifies the TIM Channel CCxE bit new state. - * This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable. - * @retval None - */ -void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx) -{ - uint16_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_CCX(TIM_CCx)); - - tmp = CCER_CCE_SET << TIM_Channel; - - /* Reset the CCxE Bit */ - TIMx->CCER &= (uint16_t)~ tmp; - - /* Set or reset the CCxE Bit */ - TIMx->CCER |= (uint16_t)(TIM_CCx << TIM_Channel); -} - -/** - * @} - */ - -/** @defgroup TIM_Group3 Input Capture management functions - * @brief Input Capture management functions - * -@verbatim - =============================================================================== - Input Capture management functions - =============================================================================== - - =================================================================== - TIM Driver: how to use it in Input Capture Mode - =================================================================== - To use the Timer in Input Capture mode, the following steps are mandatory: - - 1. Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function - - 2. Configure the TIM pins by configuring the corresponding GPIO pins - - 2. Configure the Time base unit as described in the first part of this driver, if needed, - else the Timer will run with the default configuration: - - Autoreload value = 0xFFFF - - Prescaler value = 0x0000 - - Counter mode = Up counting - - Clock Division = TIM_CKD_DIV1 - - 3. Fill the TIM_ICInitStruct with the desired parameters including: - - TIM Channel: TIM_Channel - - TIM Input Capture polarity: TIM_ICPolarity - - TIM Input Capture selection: TIM_ICSelection - - TIM Input Capture Prescaler: TIM_ICPrescaler - - TIM Input CApture filter value: TIM_ICFilter - - 4. Call TIM_ICInit(TIMx, &TIM_ICInitStruct) to configure the desired channel with the - corresponding configuration and to measure only frequency or duty cycle of the input signal, - or, - Call TIM_PWMIConfig(TIMx, &TIM_ICInitStruct) to configure the desired channels with the - corresponding configuration and to measure the frequency and the duty cycle of the input signal - - 5. Enable the NVIC or the DMA to read the measured frequency. - - 6. Enable the corresponding interrupt (or DMA request) to read the Captured value, - using the function TIM_ITConfig(TIMx, TIM_IT_CCx) (or TIM_DMA_Cmd(TIMx, TIM_DMA_CCx)) - - 7. Call the TIM_Cmd(ENABLE) function to enable the TIM counter. - - 8. Use TIM_GetCapturex(TIMx); to read the captured value. - - Note1: All other functions can be used seperatly to modify, if needed, - a specific feature of the Timer. - -@endverbatim - * @{ - */ - -/** - * @brief Initializes the TIM peripheral according to the specified - * parameters in the TIM_ICInitStruct. - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure - * that contains the configuration information for the specified TIM - * peripheral. - * @retval None - */ -void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_IC_POLARITY(TIM_ICInitStruct->TIM_ICPolarity)); - assert_param(IS_TIM_IC_SELECTION(TIM_ICInitStruct->TIM_ICSelection)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICInitStruct->TIM_ICPrescaler)); - assert_param(IS_TIM_IC_FILTER(TIM_ICInitStruct->TIM_ICFilter)); - - if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) - { - /* TI1 Configuration */ - TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, - TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } - else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_2) - { - /* TI2 Configuration */ - TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, - TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } - else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_3) - { - /* TI3 Configuration */ - TI3_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, - TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC3Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } - else - { - /* TI4 Configuration */ - TI4_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, - TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC4Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } -} - -/** - * @brief Fills each TIM_ICInitStruct member with its default value. - * @param TIM_ICInitStruct : pointer to a TIM_ICInitTypeDef structure which will - * be initialized. - * @retval None - */ -void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct) -{ - /* Set the default configuration */ - TIM_ICInitStruct->TIM_Channel = TIM_Channel_1; - TIM_ICInitStruct->TIM_ICPolarity = TIM_ICPolarity_Rising; - TIM_ICInitStruct->TIM_ICSelection = TIM_ICSelection_DirectTI; - TIM_ICInitStruct->TIM_ICPrescaler = TIM_ICPSC_DIV1; - TIM_ICInitStruct->TIM_ICFilter = 0x00; -} - -/** - * @brief Configures the TIM peripheral according to the specified - * parameters in the TIM_ICInitStruct to measure an external PWM signal. - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure - * that contains the configuration information for the specified TIM - * peripheral. - * @retval None - */ -void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) -{ - uint16_t icoppositepolarity = TIM_ICPolarity_Rising; - uint16_t icoppositeselection = TIM_ICSelection_DirectTI; - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - /* Select the Opposite Input Polarity */ - if (TIM_ICInitStruct->TIM_ICPolarity == TIM_ICPolarity_Rising) - { - icoppositepolarity = TIM_ICPolarity_Falling; - } - else - { - icoppositepolarity = TIM_ICPolarity_Rising; - } - /* Select the Opposite Input */ - if (TIM_ICInitStruct->TIM_ICSelection == TIM_ICSelection_DirectTI) - { - icoppositeselection = TIM_ICSelection_IndirectTI; - } - else - { - icoppositeselection = TIM_ICSelection_DirectTI; - } - if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) - { - /* TI1 Configuration */ - TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - /* TI2 Configuration */ - TI2_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } - else - { - /* TI2 Configuration */ - TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - /* TI1 Configuration */ - TI1_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } -} - -/** - * @brief Gets the TIMx Input Capture 1 value. - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @retval Capture Compare 1 Register value. - - */ -uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - - /* Get the Capture 1 Register value */ - return TIMx->CCR1; -} - -/** - * @brief Gets the TIMx Input Capture 2 value. - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @retval Capture Compare 2 Register value. - - */ -uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - - /* Get the Capture 2 Register value */ - return TIMx->CCR2; -} - -/** - * @brief Gets the TIMx Input Capture 3 value. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @retval Capture Compare 3 Register value. - */ -uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - - /* Get the Capture 3 Register value */ - return TIMx->CCR3; -} - -/** - * @brief Gets the TIMx Input Capture 4 value. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @retval Capture Compare 4 Register value. - */ -uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - - /* Get the Capture 4 Register value */ - return TIMx->CCR4; -} - -/** - * @brief Sets the TIMx Input Capture 1 prescaler. - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param TIM_ICPSC: specifies the Input Capture1 prescaler new value. - * This parameter can be one of the following values: - * @arg TIM_ICPSC_DIV1: no prescaler - * @arg TIM_ICPSC_DIV2: capture is done once every 2 events - * @arg TIM_ICPSC_DIV4: capture is done once every 4 events - * @arg TIM_ICPSC_DIV8: capture is done once every 8 events - * @retval None - */ -void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); - - /* Reset the IC1PSC Bits */ - TIMx->CCMR1 &= (uint16_t)~((uint16_t)TIM_CCMR1_IC1PSC); - /* Set the IC1PSC value */ - TIMx->CCMR1 |= TIM_ICPSC; -} - -/** - * @brief Sets the TIMx Input Capture 2 prescaler. - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param TIM_ICPSC: specifies the Input Capture2 prescaler new value. - * This parameter can be one of the following values: - * @arg TIM_ICPSC_DIV1: no prescaler - * @arg TIM_ICPSC_DIV2: capture is done once every 2 events - * @arg TIM_ICPSC_DIV4: capture is done once every 4 events - * @arg TIM_ICPSC_DIV8: capture is done once every 8 events - * @retval None - */ -void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); - - /* Reset the IC2PSC Bits */ - TIMx->CCMR1 &= (uint16_t)~((uint16_t)TIM_CCMR1_IC2PSC); - /* Set the IC2PSC value */ - TIMx->CCMR1 |= (uint16_t)(TIM_ICPSC << 8); -} - -/** - * @brief Sets the TIMx Input Capture 3 prescaler. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_ICPSC: specifies the Input Capture3 prescaler new value. - * This parameter can be one of the following values: - * @arg TIM_ICPSC_DIV1: no prescaler - * @arg TIM_ICPSC_DIV2: capture is done once every 2 events - * @arg TIM_ICPSC_DIV4: capture is done once every 4 events - * @arg TIM_ICPSC_DIV8: capture is done once every 8 events - * @retval None - */ -void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); - - /* Reset the IC3PSC Bits */ - TIMx->CCMR2 &= (uint16_t)~((uint16_t)TIM_CCMR2_IC3PSC); - /* Set the IC3PSC value */ - TIMx->CCMR2 |= TIM_ICPSC; -} - -/** - * @brief Sets the TIMx Input Capture 4 prescaler. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_ICPSC: specifies the Input Capture4 prescaler new value. - * This parameter can be one of the following values: - * @arg TIM_ICPSC_DIV1: no prescaler - * @arg TIM_ICPSC_DIV2: capture is done once every 2 events - * @arg TIM_ICPSC_DIV4: capture is done once every 4 events - * @arg TIM_ICPSC_DIV8: capture is done once every 8 events - * @retval None - */ -void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); - - /* Reset the IC4PSC Bits */ - TIMx->CCMR2 &= (uint16_t)~((uint16_t)TIM_CCMR2_IC4PSC); - /* Set the IC4PSC value */ - TIMx->CCMR2 |= (uint16_t)(TIM_ICPSC << 8); -} - -/** - * @} - */ - -/** @defgroup TIM_Group4 Interrupts DMA and flags management functions - * @brief Interrupts, DMA and flags management functions - * -@verbatim - =============================================================================== - Interrupts, DMA and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified TIM interrupts. - * @param TIMx: where x can be 2 to 11 to select the TIMx peripheral. - * @param TIM_IT: specifies the TIM interrupts sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg TIM_IT_Update: TIM update Interrupt source - * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source - * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source - * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source - * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source - * @arg TIM_IT_Trigger: TIM Trigger Interrupt source - * @note - * - TIM6 and TIM7 can only generate an update interrupt. - * - TIM_IT_CC2, TIM_IT_CC3, TIM_IT_CC4 and TIM_IT_Trigger can not be used with TIM10 and TIM11 - * - TIM_IT_CC3, TIM_IT_CC4 can not be used with TIM9. - * @param NewState: new state of the TIM interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_IT(TIM_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the Interrupt sources */ - TIMx->DIER |= TIM_IT; - } - else - { - /* Disable the Interrupt sources */ - TIMx->DIER &= (uint16_t)~TIM_IT; - } -} - -/** - * @brief Configures the TIMx event to be generate by software. - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @param TIM_EventSource: specifies the event source. - * This parameter can be one or more of the following values: - * @arg TIM_EventSource_Update: Timer update Event source - * @arg TIM_EventSource_CC1: Timer Capture Compare 1 Event source - * @arg TIM_EventSource_CC2: Timer Capture Compare 2 Event source - * @arg TIM_EventSource_CC3: Timer Capture Compare 3 Event source - * @arg TIM_EventSource_CC4: Timer Capture Compare 4 Event source - * @arg TIM_EventSource_Trigger: Timer Trigger Event source - * @note - * - TIM6 and TIM7 can only generate an update event. - * - TIM9 can only generate an update event, Capture Compare 1 event, - * Capture Compare 2 event and TIM_EventSource_Trigger. - * - TIM10 and TIM11 can only generate an update event and Capture Compare 1 event. - * @retval None - */ -void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_EVENT_SOURCE(TIM_EventSource)); - /* Set the event sources */ - TIMx->EGR = TIM_EventSource; -} - -/** - * @brief Checks whether the specified TIM flag is set or not. - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @param TIM_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg TIM_FLAG_Update: TIM update Flag - * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag - * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag - * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag - * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag - * @arg TIM_FLAG_Trigger: TIM Trigger Flag - * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag - * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag - * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag - * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag - * @note - * - TIM6 and TIM7 can have only one update flag. - * - TIM9 can have only update flag, TIM_FLAG_CC1, TIM_FLAG_CC2 and TIM_FLAG_Trigger, - * TIM_FLAG_CC1OF or TIM_FLAG_CC2OF flags - * - TIM10 and TIM11 can have only update flag, TIM_FLAG_CC1 or TIM_FLAG_CC1OF flags - * @retval The new state of TIM_FLAG (SET or RESET). - */ -FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) -{ - ITStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_GET_FLAG(TIM_FLAG)); - - if ((TIMx->SR & TIM_FLAG) != (uint16_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the TIMx's pending flags. - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @param TIM_FLAG: specifies the flag bit to clear. - * This parameter can be any combination of the following values: - * @arg TIM_FLAG_Update: TIM update Flag - * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag - * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag - * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag - * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag - * @arg TIM_FLAG_Trigger: TIM Trigger Flag - * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag - * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag - * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag - * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag - * @note - * - TIM6 and TIM7 can have only one update flag. - * - TIM9 can have only update flag, TIM_FLAG_CC1, TIM_FLAG_CC2 and TIM_FLAG_Trigger flags - * TIM_FLAG_CC1OF or TIM_FLAG_CC2OF flags - * - TIM10 and TIM11 can have only update flag, TIM_FLAG_CC1 - * or TIM_FLAG_CC1OF flags - * @retval None - */ -void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_CLEAR_FLAG(TIM_FLAG)); - - /* Clear the flags */ - TIMx->SR = (uint16_t)~TIM_FLAG; -} - -/** - * @brief Checks whether the TIM interrupt has occurred or not. - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @param TIM_IT: specifies the TIM interrupt source to check. - * This parameter can be one of the following values: - * @arg TIM_IT_Update: TIM update Interrupt source - * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source - * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source - * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source - * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source - * @arg TIM_IT_Trigger: TIM Trigger Interrupt source - * @note - * - TIM6 and TIM7 can generate only an update interrupt. - * - TIM9 can have only update interrupt, TIM_FLAG_CC1 or TIM_FLAG_CC2, - * interrupt and TIM_IT_Trigger interrupt. - * - TIM10 and TIM11 can have only update interrupt or TIM_FLAG_CC1 - * interrupt - * @retval The new state of the TIM_IT(SET or RESET). - */ -ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT) -{ - ITStatus bitstatus = RESET; - uint16_t itstatus = 0x0, itenable = 0x0; - - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_GET_IT(TIM_IT)); - - itstatus = TIMx->SR & TIM_IT; - - itenable = TIMx->DIER & TIM_IT; - if ((itstatus != (uint16_t)RESET) && (itenable != (uint16_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the TIMx's interrupt pending bits. - * @param TIMx: where x can be 2 to 11 to select the TIM peripheral. - * @param TIM_IT: specifies the pending bit to clear. - * This parameter can be any combination of the following values: - * @arg TIM_IT_Update: TIM update Interrupt source - * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source - * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source - * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source - * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source - * @arg TIM_IT_Trigger: TIM Trigger Interrupt source - * @note - * - TIM6 and TIM7 can generate only an update interrupt. - * - TIM9 can have only update interrupt, TIM_IT_CC1 or TIM_IT_CC2, - * and TIM_IT_Trigger interrupt. - * - TIM10 and TIM11 can have only update interrupt or TIM_IT_CC1 - * interrupt - * @retval None - */ -void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_IT(TIM_IT)); - - /* Clear the IT pending Bit */ - TIMx->SR = (uint16_t)~TIM_IT; -} - -/** - * @brief Configures the TIMxs DMA interface. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_DMABase: DMA Base address. - * This parameter can be one of the following values: - * @arg TIM_DMABase_CR, TIM_DMABase_CR2, TIM_DMABase_SMCR, - * TIM_DMABase_DIER, TIM_DMABase_SR, TIM_DMABase_EGR, - * TIM_DMABase_CCMR1, TIM_DMABase_CCMR2, TIM_DMABase_CCER, - * TIM_DMABase_CNT, TIM_DMABase_PSC, TIM_DMABase_ARR, - * TIM_DMABase_CCR1, TIM_DMABase_CCR2, TIM_DMABase_CCR3, - * TIM_DMABase_CCR4, TIM_DMABase_DCR. - * @param TIM_DMABurstLength: DMA Burst length. - * This parameter can be one value between: - * TIM_DMABurstLength_1Byte and TIM_DMABurstLength_18Bytes. - * @retval None - */ -void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_DMA_BASE(TIM_DMABase)); - assert_param(IS_TIM_DMA_LENGTH(TIM_DMABurstLength)); - /* Set the DMA Base and the DMA Burst Length */ - TIMx->DCR = TIM_DMABase | TIM_DMABurstLength; -} - -/** - * @brief Enables or disables the TIMxs DMA Requests. - * @param TIMx: where x can be 2, 3, 4, 6 or 7 to select the TIM peripheral. - * @param TIM_DMASource: specifies the DMA Request sources. - * This parameter can be any combination of the following values: - * @arg TIM_DMA_Update: TIM update Interrupt source - * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source - * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source - * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source - * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source - * @arg TIM_DMA_Trigger: TIM Trigger DMA source - * @param NewState: new state of the DMA Request sources. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST4_PERIPH(TIMx)); - assert_param(IS_TIM_DMA_SOURCE(TIM_DMASource)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the DMA sources */ - TIMx->DIER |= TIM_DMASource; - } - else - { - /* Disable the DMA sources */ - TIMx->DIER &= (uint16_t)~TIM_DMASource; - } -} - -/** - * @brief Selects the TIMx peripheral Capture Compare DMA source. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param NewState: new state of the Capture Compare DMA source - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Set the CCDS Bit */ - TIMx->CR2 |= TIM_CR2_CCDS; - } - else - { - /* Reset the CCDS Bit */ - TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_CCDS); - } -} - -/** - * @} - */ - -/** @defgroup TIM_Group5 Clocks management functions - * @brief Clocks management functions - * -@verbatim - =============================================================================== - Clocks management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Configures the TIMx internal Clock - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @retval None - */ -void TIM_InternalClockConfig(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - /* Disable slave mode to clock the prescaler directly with the internal clock */ - TIMx->SMCR &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS)); -} - -/** - * @brief Configures the TIMx Internal Trigger as External Clock - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param TIM_ITRSource: Trigger source. - * This parameter can be one of the following values: - * @param TIM_TS_ITR0: Internal Trigger 0 - * @param TIM_TS_ITR1: Internal Trigger 1 - * @param TIM_TS_ITR2: Internal Trigger 2 - * @param TIM_TS_ITR3: Internal Trigger 3 - * @retval None - */ -void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_INTERNAL_TRIGGER_SELECTION(TIM_InputTriggerSource)); - /* Select the Internal Trigger */ - TIM_SelectInputTrigger(TIMx, TIM_InputTriggerSource); - /* Select the External clock mode1 */ - TIMx->SMCR |= TIM_SlaveMode_External1; -} - -/** - * @brief Configures the TIMx Trigger as External Clock - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param TIM_TIxExternalCLKSource: Trigger source. - * This parameter can be one of the following values: - * @arg TIM_TIxExternalCLK1Source_TI1ED: TI1 Edge Detector - * @arg TIM_TIxExternalCLK1Source_TI1: Filtered Timer Input 1 - * @arg TIM_TIxExternalCLK1Source_TI2: Filtered Timer Input 2 - * @param TIM_ICPolarity: specifies the TIx Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @param ICFilter : specifies the filter value. - * This parameter must be a value between 0x0 and 0xF. - * @retval None - */ -void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, - uint16_t TIM_ICPolarity, uint16_t ICFilter) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_IC_POLARITY(TIM_ICPolarity)); - assert_param(IS_TIM_IC_FILTER(ICFilter)); - - /* Configure the Timer Input Clock Source */ - if (TIM_TIxExternalCLKSource == TIM_TIxExternalCLK1Source_TI2) - { - TI2_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); - } - else - { - TI1_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); - } - /* Select the Trigger source */ - TIM_SelectInputTrigger(TIMx, TIM_TIxExternalCLKSource); - /* Select the External clock mode1 */ - TIMx->SMCR |= TIM_SlaveMode_External1; -} - -/** - * @brief Configures the External clock Mode1 - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. - * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. - * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. - * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. - * @param TIM_ExtTRGPolarity: The external Trigger Polarity. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. - * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. - * @param ExtTRGFilter: External Trigger Filter. - * This parameter must be a value between 0x00 and 0x0F - * @retval None - */ -void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, - uint16_t ExtTRGFilter) -{ - uint16_t tmpsmcr = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); - assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); - assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); - - /* Configure the ETR Clock source */ - TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); - - /* Get the TIMx SMCR register value */ - tmpsmcr = TIMx->SMCR; - /* Reset the SMS Bits */ - tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS)); - /* Select the External clock mode1 */ - tmpsmcr |= TIM_SlaveMode_External1; - /* Select the Trigger selection : ETRF */ - tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS)); - tmpsmcr |= TIM_TS_ETRF; - /* Write to TIMx SMCR */ - TIMx->SMCR = tmpsmcr; -} - -/** - * @brief Configures the External clock Mode2 - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. - * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. - * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. - * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. - * @param TIM_ExtTRGPolarity: The external Trigger Polarity. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. - * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. - * @param ExtTRGFilter: External Trigger Filter. - * This parameter must be a value between 0x00 and 0x0F - * @retval None - */ -void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, - uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); - assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); - assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); - - /* Configure the ETR Clock source */ - TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); - /* Enable the External clock mode2 */ - TIMx->SMCR |= TIM_SMCR_ECE; -} - -/** - * @} - */ - -/** @defgroup TIM_Group6 Synchronization management functions - * @brief Synchronization management functions - * -@verbatim - =============================================================================== - Synchronization management functions - =============================================================================== - - =================================================================== - TIM Driver: how to use it in synchronization Mode - =================================================================== - Case of two/several Timers - ************************** - 1. Configure the Master Timers using the following functions: - - void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource); - - void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode); - 2. Configure the Slave Timers using the following functions: - - void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); - - void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); - - Case of Timers and external trigger(ETR pin) - ******************************************** - 1. Configure the Etrenal trigger using this function: - - void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, - uint16_t ExtTRGFilter); - 2. Configure the Slave Timers using the following functions: - - void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); - - void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); - -@endverbatim - * @{ - */ - -/** - * @brief Selects the Input Trigger source - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param TIM_InputTriggerSource: The Input Trigger source. - * This parameter can be one of the following values: - * @arg TIM_TS_ITR0: Internal Trigger 0 - * @arg TIM_TS_ITR1: Internal Trigger 1 - * @arg TIM_TS_ITR2: Internal Trigger 2 - * @arg TIM_TS_ITR3: Internal Trigger 3 - * @arg TIM_TS_TI1F_ED: TI1 Edge Detector - * @arg TIM_TS_TI1FP1: Filtered Timer Input 1 - * @arg TIM_TS_TI2FP2: Filtered Timer Input 2 - * @arg TIM_TS_ETRF: External Trigger input - * @retval None - */ -void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource) -{ - uint16_t tmpsmcr = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_TRIGGER_SELECTION(TIM_InputTriggerSource)); - - /* Get the TIMx SMCR register value */ - tmpsmcr = TIMx->SMCR; - /* Reset the TS Bits */ - tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_TS)); - /* Set the Input Trigger source */ - tmpsmcr |= TIM_InputTriggerSource; - /* Write to TIMx SMCR */ - TIMx->SMCR = tmpsmcr; -} - -/** - * @brief Selects the TIMx Trigger Output Mode. - * @param TIMx: where x can be 2, 3, 4, 6, 7 or 9 to select the TIM peripheral. - * @param TIM_TRGOSource: specifies the Trigger Output source. - * This paramter can be one of the following values: - * - * - For all TIMx - * @arg TIM_TRGOSource_Reset: The UG bit in the TIM_EGR register is used as the trigger output (TRGO). - * @arg TIM_TRGOSource_Enable: The Counter Enable CEN is used as the trigger output (TRGO). - * @arg TIM_TRGOSource_Update: The update event is selected as the trigger output (TRGO). - * - * - For all TIMx except TIM6 and TIM7 - * @arg TIM_TRGOSource_OC1: The trigger output sends a positive pulse when the CC1IF flag - * is to be set, as soon as a capture or compare match occurs (TRGO). - * @arg TIM_TRGOSource_OC1Ref: OC1REF signal is used as the trigger output (TRGO). - - * - For all TIMx except TIM6, TIM7, TIM10 and TIM11 - * @arg TIM_TRGOSource_OC2Ref: OC2REF signal is used as the trigger output (TRGO). - - * - For TIM2, TIM3 and TIM4 - * @arg TIM_TRGOSource_OC3Ref: OC3REF signal is used as the trigger output (TRGO). - * @arg TIM_TRGOSource_OC4Ref: OC4REF signal is used as the trigger output (TRGO). - * - * @retval None - */ -void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST5_PERIPH(TIMx)); - assert_param(IS_TIM_TRGO_SOURCE(TIM_TRGOSource)); - - /* Reset the MMS Bits */ - TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_MMS); - /* Select the TRGO source */ - TIMx->CR2 |= TIM_TRGOSource; -} - -/** - * @brief Selects the TIMx Slave Mode. - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param TIM_SlaveMode: specifies the Timer Slave Mode. - * This paramter can be one of the following values: - * @arg TIM_SlaveMode_Reset: Rising edge of the selected trigger signal (TRGI) re-initializes - * the counter and triggers an update of the registers. - * @arg TIM_SlaveMode_Gated: The counter clock is enabled when the trigger signal (TRGI) is high. - * @arg TIM_SlaveMode_Trigger: The counter starts at a rising edge of the trigger TRGI. - * @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter. - * @retval None - */ -void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_SLAVE_MODE(TIM_SlaveMode)); - - /* Reset the SMS Bits */ - TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_SMS); - /* Select the Slave Mode */ - TIMx->SMCR |= TIM_SlaveMode; -} - -/** - * @brief Sets or Resets the TIMx Master/Slave Mode. - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param TIM_MasterSlaveMode: specifies the Timer Master Slave Mode. - * This paramter can be one of the following values: - * @arg TIM_MasterSlaveMode_Enable: synchronization between the current timer - * and its slaves (through TRGO). - * @arg TIM_MasterSlaveMode_Disable: No action - * @retval None - */ -void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_MSM_STATE(TIM_MasterSlaveMode)); - - /* Reset the MSM Bit */ - TIMx->SMCR &= (uint16_t)~((uint16_t)TIM_SMCR_MSM); - - /* Set or Reset the MSM Bit */ - TIMx->SMCR |= TIM_MasterSlaveMode; -} - -/** - * @brief Configures the TIMx External Trigger (ETR). - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. - * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. - * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. - * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. - * @param TIM_ExtTRGPolarity: The external Trigger Polarity. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. - * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. - * @param ExtTRGFilter: External Trigger Filter. - * This parameter must be a value between 0x00 and 0x0F - * @retval None - */ -void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, - uint16_t ExtTRGFilter) -{ - uint16_t tmpsmcr = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); - assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); - assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); - - tmpsmcr = TIMx->SMCR; - /* Reset the ETR Bits */ - tmpsmcr &= SMCR_ETR_MASK; - /* Set the Prescaler, the Filter value and the Polarity */ - tmpsmcr |= (uint16_t)(TIM_ExtTRGPrescaler | (uint16_t)(TIM_ExtTRGPolarity | (uint16_t)(ExtTRGFilter << (uint16_t)8))); - /* Write to TIMx SMCR */ - TIMx->SMCR = tmpsmcr; -} - -/** - * @} - */ - -/** @defgroup TIM_Group7 Specific interface management functions - * @brief Specific interface management functions - * -@verbatim - =============================================================================== - Specific interface management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Configures the TIMx Encoder Interface. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_EncoderMode: specifies the TIMx Encoder Mode. - * This parameter can be one of the following values: - * @arg TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level. - * @arg TIM_EncoderMode_TI2: Counter counts on TI2FP2 edge depending on TI1FP1 level. - * @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending - * on the level of the other input. - * @param TIM_IC1Polarity: specifies the IC1 Polarity - * This parmeter can be one of the following values: - * @arg TIM_ICPolarity_Falling: IC Falling edge. - * @arg TIM_ICPolarity_Rising: IC Rising edge. - * @param TIM_IC2Polarity: specifies the IC2 Polarity - * This parmeter can be one of the following values: - * @arg TIM_ICPolarity_Falling: IC Falling edge. - * @arg TIM_ICPolarity_Rising: IC Rising edge. - * @retval None - */ -void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, - uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity) -{ - uint16_t tmpsmcr = 0; - uint16_t tmpccmr1 = 0; - uint16_t tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_ENCODER_MODE(TIM_EncoderMode)); - assert_param(IS_TIM_IC_POLARITY(TIM_IC1Polarity)); - assert_param(IS_TIM_IC_POLARITY(TIM_IC2Polarity)); - - /* Get the TIMx SMCR register value */ - tmpsmcr = TIMx->SMCR; - /* Get the TIMx CCMR1 register value */ - tmpccmr1 = TIMx->CCMR1; - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - /* Set the encoder Mode */ - tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS)); - tmpsmcr |= TIM_EncoderMode; - /* Select the Capture Compare 1 and the Capture Compare 2 as input */ - tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S))); - tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0; - /* Set the TI1 and the TI2 Polarities */ - tmpccer &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCER_CC1P)) & ((uint16_t)~((uint16_t)TIM_CCER_CC2P))); - tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4)); - /* Write to TIMx SMCR */ - TIMx->SMCR = tmpsmcr; - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmr1; - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Enables or disables the TIMxs Hall sensor interface. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param NewState: new state of the TIMx Hall sensor interface. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Set the TI1S Bit */ - TIMx->CR2 |= TIM_CR2_TI1S; - } - else - { - /* Reset the TI1S Bit */ - TIMx->CR2 &= (uint16_t)~((uint16_t)TIM_CR2_TI1S); - } -} - -/** - * @} - */ - -/** @defgroup TIM_Group8 Specific remapping management function - * @brief Specific remapping management function - * -@verbatim - =============================================================================== - Specific remapping management function - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Configures the TIM9, TIM10 and TIM11 Remapping input Capabilities. - * @param TIMx: where x can be 9, 10 or 11 to select the TIM peripheral. - * @param TIM_Remap: specifies the TIM input remapping source. - * This parameter can be one of the following values: - * @arg TIM9_GPIO: TIM9 Channel 1 is connected to dedicated Timer pin(default) - * @arg TIM9_LSE: TIM9 Channel 1 is connected to LSE clock. - * @arg TIM10_GPIO: TIM10 Channel 1 is connected to dedicated Timer pin(default) - * @arg TIM10_LSI: TIM10 Channel 1 is connected to LSI clock. - * @arg TIM10_LSE: TIM10 Channel 1 is connected to LSE clock. - * @arg TIM10_RTC: TIM10 Channel 1 is connected to RTC Output event. - * @arg TIM11_GPIO: TIM11 Channel 1 is connected to dedicated Timer pin(default) - * @arg TIM11_MSI: TIM11 Channel 1 is connected to MSI clock. - * @arg TIM11_HSE_RTC: TIM11 Channel 1 is connected to HSE_RTC clock. - * @retval None - */ -void TIM_RemapConfig(TIM_TypeDef* TIMx, uint16_t TIM_Remap) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - assert_param(IS_TIM_REMAP(TIM_Remap)); - - /* Set the Timer remapping configuration */ - TIMx->OR = TIM_Remap; -} - -/** - * @} - */ - -/** - * @brief Configure the TI1 as Input. - * @param TIMx: where x can be 2, 3, 4, 9, 10 or 11 to select the TIM peripheral. - * @param TIM_ICPolarity : The Input Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @param TIM_ICSelection: specifies the input to be used. - * This parameter can be one of the following values: - * @arg TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1. - * @arg TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2. - * @arg TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC. - * @param TIM_ICFilter: Specifies the Input Capture Filter. - * This parameter must be a value between 0x00 and 0x0F. - * @retval None - */ -static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter) -{ - uint16_t tmpccmr1 = 0, tmpccer = 0; - - /* Disable the Channel 1: Reset the CC1E Bit */ - TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC1E); - tmpccmr1 = TIMx->CCMR1; - tmpccer = TIMx->CCER; - /* Select the Input and set the filter */ - tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & ((uint16_t)~((uint16_t)TIM_CCMR1_IC1F))); - tmpccmr1 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4)); - /* Select the Polarity and set the CC1E Bit */ - tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC1P | TIM_CCER_CC1NP)); - tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC1E); - /* Write to TIMx CCMR1 and CCER registers */ - TIMx->CCMR1 = tmpccmr1; - TIMx->CCER = tmpccer; -} - -/** - * @brief Configure the TI2 as Input. - * @param TIMx: where x can be 2, 3, 4 or 9 to select the TIM peripheral. - * @param TIM_ICPolarity : The Input Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @param TIM_ICSelection: specifies the input to be used. - * This parameter can be one of the following values: - * @arg TIM_ICSelection_DirectTI: TIM Input 2 is selected to be connected to IC2. - * @arg TIM_ICSelection_IndirectTI: TIM Input 2 is selected to be connected to IC1. - * @arg TIM_ICSelection_TRC: TIM Input 2 is selected to be connected to TRC. - * @param TIM_ICFilter: Specifies the Input Capture Filter. - * This parameter must be a value between 0x00 and 0x0F. - * @retval None - */ -static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter) -{ - uint16_t tmpccmr1 = 0, tmpccer = 0, tmp = 0; - - /* Disable the Channel 2: Reset the CC2E Bit */ - TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC2E); - tmpccmr1 = TIMx->CCMR1; - tmpccer = TIMx->CCER; - tmp = (uint16_t)(TIM_ICPolarity << 4); - /* Select the Input and set the filter */ - tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC2S)) & ((uint16_t)~((uint16_t)TIM_CCMR1_IC2F))); - tmpccmr1 |= (uint16_t)(TIM_ICFilter << 12); - tmpccmr1 |= (uint16_t)(TIM_ICSelection << 8); - /* Select the Polarity and set the CC2E Bit */ - tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC2P | TIM_CCER_CC2NP)); - tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC2E); - /* Write to TIMx CCMR1 and CCER registers */ - TIMx->CCMR1 = tmpccmr1 ; - TIMx->CCER = tmpccer; -} - -/** - * @brief Configure the TI3 as Input. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_ICPolarity : The Input Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @param TIM_ICSelection: specifies the input to be used. - * This parameter can be one of the following values: - * @arg TIM_ICSelection_DirectTI: TIM Input 3 is selected to be connected to IC3. - * @arg TIM_ICSelection_IndirectTI: TIM Input 3 is selected to be connected to IC4. - * @arg TIM_ICSelection_TRC: TIM Input 3 is selected to be connected to TRC. - * @param TIM_ICFilter: Specifies the Input Capture Filter. - * This parameter must be a value between 0x00 and 0x0F. - * @retval None - */ -static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter) -{ - uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; - - /* Disable the Channel 3: Reset the CC3E Bit */ - TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC3E); - tmpccmr2 = TIMx->CCMR2; - tmpccer = TIMx->CCER; - tmp = (uint16_t)(TIM_ICPolarity << 8); - /* Select the Input and set the filter */ - tmpccmr2 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR2_CC3S)) & ((uint16_t)~((uint16_t)TIM_CCMR2_IC3F))); - tmpccmr2 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4)); - /* Select the Polarity and set the CC3E Bit */ - tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC3P | TIM_CCER_CC3NP)); - tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC3E); - /* Write to TIMx CCMR2 and CCER registers */ - TIMx->CCMR2 = tmpccmr2; - TIMx->CCER = tmpccer; -} - -/** - * @brief Configure the TI4 as Input. - * @param TIMx: where x can be 2, 3 or 4 to select the TIM peripheral. - * @param TIM_ICPolarity : The Input Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @param TIM_ICSelection: specifies the input to be used. - * This parameter can be one of the following values: - * @arg TIM_ICSelection_DirectTI: TIM Input 4 is selected to be connected to IC4. - * @arg TIM_ICSelection_IndirectTI: TIM Input 4 is selected to be connected to IC3. - * @arg TIM_ICSelection_TRC: TIM Input 4 is selected to be connected to TRC. - * @param TIM_ICFilter: Specifies the Input Capture Filter. - * This parameter must be a value between 0x00 and 0x0F. - * @retval None - */ -static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter) -{ - uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; - - /* Disable the Channel 4: Reset the CC4E Bit */ - TIMx->CCER &= (uint16_t)~((uint16_t)TIM_CCER_CC4E); - tmpccmr2 = TIMx->CCMR2; - tmpccer = TIMx->CCER; - tmp = (uint16_t)(TIM_ICPolarity << 12); - /* Select the Input and set the filter */ - tmpccmr2 &= (uint16_t)((uint16_t)(~(uint16_t)TIM_CCMR2_CC4S) & ((uint16_t)~((uint16_t)TIM_CCMR2_IC4F))); - tmpccmr2 |= (uint16_t)(TIM_ICSelection << 8); - tmpccmr2 |= (uint16_t)(TIM_ICFilter << 12); - - /* Select the Polarity and set the CC4E Bit */ - tmpccer &= (uint16_t)~((uint16_t)(TIM_CCER_CC4P | TIM_CCER_CC4NP)); - tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC4E); - /* Write to TIMx CCMR2 and CCER registers */ - TIMx->CCMR2 = tmpccmr2; - TIMx->CCER = tmpccer ; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_usart.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_usart.c deleted file mode 100644 index 3da7fe801..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_usart.c +++ /dev/null @@ -1,1432 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_usart.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the Universal synchronous asynchronous receiver - * transmitter (USART): - * - Initialization and Configuration - * - Data transfers - * - Multi-Processor Communication - * - LIN mode - * - Half-duplex mode - * - Smartcard mode - * - IrDA mode - * - DMA transfers management - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable peripheral clock using RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE) - * function for USART1 or using RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE) - * function for USART2 and USART3. - * - * 2. According to the USART mode, enable the GPIO clocks using - * RCC_AHBPeriphClockCmd() function. (The I/O can be TX, RX, CTS, - * or and SCLK). - * - * 3. Peripherals alternate function: - * - Connect the pin to the desired peripherals' Alternate - * Function (AF) using GPIO_PinAFConfig() function - * - Configure the desired pin in alternate function by: - * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF - * - Select the type, pull-up/pull-down and output speed via - * GPIO_PuPd, GPIO_OType and GPIO_Speed members - * - Call GPIO_Init() function - * - * 4. Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware - * flow control and Mode(Receiver/Transmitter) using the SPI_Init() - * function. - * - * 5. For synchronous mode, enable the clock and program the polarity, - * phase and last bit using the USART_ClockInit() function. - * - * 5. Enable the NVIC and the corresponding interrupt using the function - * USART_ITConfig() if you need to use interrupt mode. - * - * 6. When using the DMA mode - * - Configure the DMA using DMA_Init() function - * - Active the needed channel Request using USART_DMACmd() function - * - * 7. Enable the USART using the USART_Cmd() function. - * - * 8. Enable the DMA using the DMA_Cmd() function, when using DMA mode. - * - * Refer to Multi-Processor, LIN, half-duplex, Smartcard, IrDA sub-sections - * for more details - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_usart.h" -#include "stm32l1xx_rcc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup USART - * @brief USART driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/*!< USART CR1 register clear Mask ((~(uint16_t)0xE9F3)) */ -#define CR1_CLEAR_MASK ((uint16_t)(USART_CR1_M | USART_CR1_PCE | \ - USART_CR1_PS | USART_CR1_TE | \ - USART_CR1_RE)) - -/*!< USART CR2 register clock bits clear Mask ((~(uint16_t)0xF0FF)) */ -#define CR2_CLOCK_CLEAR_MASK ((uint16_t)(USART_CR2_CLKEN | USART_CR2_CPOL | \ - USART_CR2_CPHA | USART_CR2_LBCL)) - -/*!< USART CR3 register clear Mask ((~(uint16_t)0xFCFF)) */ -#define CR3_CLEAR_MASK ((uint16_t)(USART_CR3_RTSE | USART_CR3_CTSE)) - -/*!< USART Interrupts mask */ -#define IT_MASK ((uint16_t)0x001F) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup USART_Private_Functions - * @{ - */ - -/** @defgroup USART_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - - This subsection provides a set of functions allowing to initialize the USART - in asynchronous and in synchronous modes. - - For the asynchronous mode only these parameters can be configured: - - Baud Rate - - Word Length - - Stop Bit - - Parity: If the parity is enabled, then the MSB bit of the data written - in the data register is transmitted but is changed by the parity bit. - Depending on the frame length defined by the M bit (8-bits or 9-bits), - the possible USART frame formats are as listed in the following table: - +-------------------------------------------------------------+ - | M bit | PCE bit | USART frame | - |---------------------|---------------------------------------| - | 0 | 0 | | SB | 8 bit data | STB | | - |---------|-----------|---------------------------------------| - | 0 | 1 | | SB | 7 bit data | PB | STB | | - |---------|-----------|---------------------------------------| - | 1 | 0 | | SB | 9 bit data | STB | | - |---------|-----------|---------------------------------------| - | 1 | 1 | | SB | 8 bit data | PB | STB | | - +-------------------------------------------------------------+ - - Hardware flow control - - Receiver/transmitter modes - - The USART_Init() function follows the USART asynchronous configuration procedure - (details for the procedure are available in reference manual (RM0038)). - - - For the synchronous mode in addition to the asynchronous mode parameters these - parameters should be also configured: - - USART Clock Enabled - - USART polarity - - USART phase - - USART LastBit - - These parameters can be configured using the USART_ClockInit() function. - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the USARTx peripheral registers to their default reset values. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: USART1, USART2 or USART3. - * @retval None - */ -void USART_DeInit(USART_TypeDef* USARTx) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - - if (USARTx == USART1) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); - } - else if (USARTx == USART2) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE); - } - else - { - if (USARTx == USART3) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE); - } - } -} - -/** - * @brief Initializes the USARTx peripheral according to the specified - * parameters in the USART_InitStruct . - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param USART_InitStruct: pointer to a USART_InitTypeDef structure - * that contains the configuration information for the specified USART peripheral. - * @retval None - */ -void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct) -{ - uint32_t tmpreg = 0x00, apbclock = 0x00; - uint32_t integerdivider = 0x00; - uint32_t fractionaldivider = 0x00; - RCC_ClocksTypeDef RCC_ClocksStatus; - - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_BAUDRATE(USART_InitStruct->USART_BaudRate)); - assert_param(IS_USART_WORD_LENGTH(USART_InitStruct->USART_WordLength)); - assert_param(IS_USART_STOPBITS(USART_InitStruct->USART_StopBits)); - assert_param(IS_USART_PARITY(USART_InitStruct->USART_Parity)); - assert_param(IS_USART_MODE(USART_InitStruct->USART_Mode)); - assert_param(IS_USART_HARDWARE_FLOW_CONTROL(USART_InitStruct->USART_HardwareFlowControl)); - -/*---------------------------- USART CR2 Configuration -----------------------*/ - tmpreg = USARTx->CR2; - /* Clear STOP[13:12] bits */ - tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP); - - /* Configure the USART Stop Bits, Clock, CPOL, CPHA and LastBit ------------*/ - /* Set STOP[13:12] bits according to USART_StopBits value */ - tmpreg |= (uint32_t)USART_InitStruct->USART_StopBits; - - /* Write to USART CR2 */ - USARTx->CR2 = (uint16_t)tmpreg; - -/*---------------------------- USART CR1 Configuration -----------------------*/ - tmpreg = USARTx->CR1; - /* Clear M, PCE, PS, TE and RE bits */ - tmpreg &= (uint32_t)~((uint32_t)CR1_CLEAR_MASK); - - /* Configure the USART Word Length, Parity and mode ----------------------- */ - /* Set the M bits according to USART_WordLength value */ - /* Set PCE and PS bits according to USART_Parity value */ - /* Set TE and RE bits according to USART_Mode value */ - tmpreg |= (uint32_t)USART_InitStruct->USART_WordLength | USART_InitStruct->USART_Parity | - USART_InitStruct->USART_Mode; - - /* Write to USART CR1 */ - USARTx->CR1 = (uint16_t)tmpreg; - -/*---------------------------- USART CR3 Configuration -----------------------*/ - tmpreg = USARTx->CR3; - /* Clear CTSE and RTSE bits */ - tmpreg &= (uint32_t)~((uint32_t)CR3_CLEAR_MASK); - - /* Configure the USART HFC -------------------------------------------------*/ - /* Set CTSE and RTSE bits according to USART_HardwareFlowControl value */ - tmpreg |= USART_InitStruct->USART_HardwareFlowControl; - - /* Write to USART CR3 */ - USARTx->CR3 = (uint16_t)tmpreg; - -/*---------------------------- USART BRR Configuration -----------------------*/ - /* Configure the USART Baud Rate -------------------------------------------*/ - RCC_GetClocksFreq(&RCC_ClocksStatus); - if (USARTx == USART1) - { - apbclock = RCC_ClocksStatus.PCLK2_Frequency; - } - else - { - apbclock = RCC_ClocksStatus.PCLK1_Frequency; - } - - /* Determine the integer part */ - if ((USARTx->CR1 & USART_CR1_OVER8) != 0) - { - /* Integer part computing in case Oversampling mode is 8 Samples */ - integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate))); - } - else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */ - { - /* Integer part computing in case Oversampling mode is 16 Samples */ - integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate))); - } - tmpreg = (integerdivider / 100) << 4; - - /* Determine the fractional part */ - fractionaldivider = integerdivider - (100 * (tmpreg >> 4)); - - /* Implement the fractional part in the register */ - if ((USARTx->CR1 & USART_CR1_OVER8) != 0) - { - tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07); - } - else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */ - { - tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F); - } - - /* Write to USART BRR */ - USARTx->BRR = (uint16_t)tmpreg; -} - -/** - * @brief Fills each USART_InitStruct member with its default value. - * @param USART_InitStruct: pointer to a USART_InitTypeDef structure - * which will be initialized. - * @retval None - */ -void USART_StructInit(USART_InitTypeDef* USART_InitStruct) -{ - /* USART_InitStruct members default value */ - USART_InitStruct->USART_BaudRate = 9600; - USART_InitStruct->USART_WordLength = USART_WordLength_8b; - USART_InitStruct->USART_StopBits = USART_StopBits_1; - USART_InitStruct->USART_Parity = USART_Parity_No ; - USART_InitStruct->USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - USART_InitStruct->USART_HardwareFlowControl = USART_HardwareFlowControl_None; -} - -/** - * @brief Initializes the USARTx peripheral Clock according to the - * specified parameters in the USART_ClockInitStruct . - * @param USARTx: where x can be 1, 2, 3 to select the USART peripheral. - * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef - * structure that contains the configuration information for the specified - * USART peripheral. - * @retval None - */ -void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct) -{ - uint32_t tmpreg = 0x00; - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_CLOCK(USART_ClockInitStruct->USART_Clock)); - assert_param(IS_USART_CPOL(USART_ClockInitStruct->USART_CPOL)); - assert_param(IS_USART_CPHA(USART_ClockInitStruct->USART_CPHA)); - assert_param(IS_USART_LASTBIT(USART_ClockInitStruct->USART_LastBit)); - -/*---------------------------- USART CR2 Configuration -----------------------*/ - tmpreg = USARTx->CR2; - /* Clear CLKEN, CPOL, CPHA and LBCL bits */ - tmpreg &= (uint32_t)~((uint32_t)CR2_CLOCK_CLEAR_MASK); - /* Configure the USART Clock, CPOL, CPHA and LastBit ------------*/ - /* Set CLKEN bit according to USART_Clock value */ - /* Set CPOL bit according to USART_CPOL value */ - /* Set CPHA bit according to USART_CPHA value */ - /* Set LBCL bit according to USART_LastBit value */ - tmpreg |= (uint32_t)USART_ClockInitStruct->USART_Clock | USART_ClockInitStruct->USART_CPOL | - USART_ClockInitStruct->USART_CPHA | USART_ClockInitStruct->USART_LastBit; - /* Write to USART CR2 */ - USARTx->CR2 = (uint16_t)tmpreg; -} - -/** - * @brief Fills each USART_ClockInitStruct member with its default value. - * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef - * structure which will be initialized. - * @retval None - */ -void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct) -{ - /* USART_ClockInitStruct members default value */ - USART_ClockInitStruct->USART_Clock = USART_Clock_Disable; - USART_ClockInitStruct->USART_CPOL = USART_CPOL_Low; - USART_ClockInitStruct->USART_CPHA = USART_CPHA_1Edge; - USART_ClockInitStruct->USART_LastBit = USART_LastBit_Disable; -} - -/** - * @brief Enables or disables the specified USART peripheral. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param NewState: new state of the USARTx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected USART by setting the UE bit in the CR1 register */ - USARTx->CR1 |= USART_CR1_UE; - } - else - { - /* Disable the selected USART by clearing the UE bit in the CR1 register */ - USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_UE); - } -} - -/** - * @brief Sets the system clock prescaler. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param USART_Prescaler: specifies the prescaler clock. - * @retval None - */ -void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - - /* Clear the USART prescaler */ - USARTx->GTPR &= USART_GTPR_GT; - /* Set the USART prescaler */ - USARTx->GTPR |= USART_Prescaler; -} - -/** - * @brief Enables or disables the USART's 8x oversampling mode. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3. - * @param NewState: new state of the USART 8x oversampling mode. - * This parameter can be: ENABLE or DISABLE. - * - * @note - * This function has to be called before calling USART_Init() - * function in order to have correct baudrate Divider value. - * @retval : None - */ -void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the 8x Oversampling mode by setting the OVER8 bit in the CR1 register */ - USARTx->CR1 |= USART_CR1_OVER8; - } - else - { - /* Disable the 8x Oversampling mode by clearing the OVER8 bit in the CR1 register */ - USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_OVER8); - } -} - -/** - * @brief Enables or disables the USART's one bit sampling method. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2, USART3. - * @param NewState: new state of the USART one bit sampling method. - * This parameter can be: ENABLE or DISABLE. - * @retval : None - */ -void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the one bit method by setting the ONEBITE bit in the CR3 register */ - USARTx->CR3 |= USART_CR3_ONEBIT; - } - else - { - /* Disable the one bit method by clearing the ONEBITE bit in the CR3 register */ - USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_ONEBIT); - } -} - -/** - * @} - */ - -/** @defgroup USART_Group2 Data transfers functions - * @brief Data transfers functions - * -@verbatim - =============================================================================== - Data transfers functions - =============================================================================== - - This subsection provides a set of functions allowing to manage the USART data - transfers. - - During an USART reception, data shifts in least significant bit first through - the RX pin. In this mode, the USART_DR register consists of a buffer (RDR) - between the internal bus and the received shift register. - - When a transmission is taking place, a write instruction to the USART_DR register - stores the data in the TDR register and which is copied in the shift register - at the end of the current transmission. - - The read access of the USART_DR register can be done using the USART_ReceiveData() - function and returns the RDR buffered value. Whereas a write access to the USART_DR - can be done using USART_SendData() function and stores the written data into - TDR buffer. - -@endverbatim - * @{ - */ - -/** - * @brief Transmits single data through the USARTx peripheral. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param Data: the data to transmit. - * @retval None - */ -void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_DATA(Data)); - - /* Transmit Data */ - USARTx->DR = (Data & (uint16_t)0x01FF); -} - -/** - * @brief Returns the most recent received data by the USARTx peripheral. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @retval The received data. - */ -uint16_t USART_ReceiveData(USART_TypeDef* USARTx) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - - /* Receive Data */ - return (uint16_t)(USARTx->DR & (uint16_t)0x01FF); -} - -/** - * @} - */ - -/** @defgroup USART_Group3 MultiProcessor Communication functions - * @brief Multi-Processor Communication functions - * -@verbatim - =============================================================================== - Multi-Processor Communication functions - =============================================================================== - - This subsection provides a set of functions allowing to manage the USART - multiprocessor communication. - - For instance one of the USARTs can be the master, its TX output is connected to - the RX input of the other USART. The others are slaves, their respective TX outputs - are logically ANDed together and connected to the RX input of the master. - - USART multiprocessor communication is possible through the following procedure: - 1. Program the Baud rate, Word length = 9 bits, Stop bits, Parity, Mode transmitter - or Mode receiver and hardware flow control values using the USART_Init() - function. - 2. Configures the USART address using the USART_SetAddress() function. - 3. Configures the wake up methode (USART_WakeUp_IdleLine or USART_WakeUp_AddressMark) - using USART_WakeUpConfig() function only for the slaves. - 4. Enable the USART using the USART_Cmd() function. - 5. Enter the USART slaves in mute mode using USART_ReceiverWakeUpCmd() function. - - The USART Slave exit from mute mode when receive the wake up condition. - -@endverbatim - * @{ - */ - -/** - * @brief Sets the address of the USART node. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param USART_Address: Indicates the address of the USART node. - * @retval None - */ -void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_ADDRESS(USART_Address)); - - /* Clear the USART address */ - USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_ADD); - /* Set the USART address node */ - USARTx->CR2 |= USART_Address; -} - -/** - * @brief Determines if the USART is in mute mode or not. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param NewState: new state of the USART mute mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the USART mute mode by setting the RWU bit in the CR1 register */ - USARTx->CR1 |= USART_CR1_RWU; - } - else - { - /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */ - USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_RWU); - } -} -/** - * @brief Selects the USART WakeUp method. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param USART_WakeUp: specifies the USART wakeup method. - * This parameter can be one of the following values: - * @arg USART_WakeUp_IdleLine: WakeUp by an idle line detection - * @arg USART_WakeUp_AddressMark: WakeUp by an address mark - * @retval None - */ -void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_WAKEUP(USART_WakeUp)); - - USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_WAKE); - USARTx->CR1 |= USART_WakeUp; -} - -/** - * @} - */ - -/** @defgroup USART_Group4 LIN mode functions - * @brief LIN mode functions - * -@verbatim - =============================================================================== - LIN mode functions - =============================================================================== - - This subsection provides a set of functions allowing to manage the USART LIN - Mode communication. - - In LIN mode, 8-bit data format with 1 stop bit is required in accordance with - the LIN standard. - - Only this LIN Feature is supported by the USART IP: - - LIN Master Synchronous Break send capability and LIN slave break detection - capability : 13-bit break generation and 10/11 bit break detection - - - USART LIN Master transmitter communication is possible through the following procedure: - 1. Program the Baud rate, Word length = 8bits, Stop bits = 1bit, Parity, - Mode transmitter or Mode receiver and hardware flow control values using - the USART_Init() function. - 2. Enable the USART using the USART_Cmd() function. - 3. Enable the LIN mode using the USART_LINCmd() function. - 4. Send the break character using USART_SendBreak() function. - - USART LIN Master receiver communication is possible through the following procedure: - 1. Program the Baud rate, Word length = 8bits, Stop bits = 1bit, Parity, - Mode transmitter or Mode receiver and hardware flow control values using - the USART_Init() function. - 2. Enable the USART using the USART_Cmd() function. - 3. Configures the break detection length using the USART_LINBreakDetectLengthConfig() - function. - 4. Enable the LIN mode using the USART_LINCmd() function. - -Note: ----- - 1. In LIN mode, the following bits must be kept cleared: - - CLKEN in the USART_CR2 register, - - STOP[1:0], SCEN, HDSEL and IREN in the USART_CR3 register. - -@endverbatim - * @{ - */ - -/** - * @brief Sets the USART LIN Break detection length. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param USART_LINBreakDetectLength: specifies the LIN break detection length. - * This parameter can be one of the following values: - * @arg USART_LINBreakDetectLength_10b: 10-bit break detection - * @arg USART_LINBreakDetectLength_11b: 11-bit break detection - * @retval None - */ -void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_LIN_BREAK_DETECT_LENGTH(USART_LINBreakDetectLength)); - - USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_LBDL); - USARTx->CR2 |= USART_LINBreakDetectLength; -} - -/** - * @brief Enables or disables the USARTs LIN mode. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param NewState: new state of the USART LIN mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the LIN mode by setting the LINEN bit in the CR2 register */ - USARTx->CR2 |= USART_CR2_LINEN; - } - else - { - /* Disable the LIN mode by clearing the LINEN bit in the CR2 register */ - USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_LINEN); - } -} - -/** - * @brief Transmits break characters. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @retval None - */ -void USART_SendBreak(USART_TypeDef* USARTx) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - - /* Send break characters */ - USARTx->CR1 |= USART_CR1_SBK; -} - -/** - * @} - */ - -/** @defgroup USART_Group5 Halfduplex mode function - * @brief Half-duplex mode function - * -@verbatim - =============================================================================== - Half-duplex mode function - =============================================================================== - - This subsection provides a set of functions allowing to manage the USART - Half-duplex communication. - - The USART can be configured to follow a single-wire half-duplex protocol where - the TX and RX lines are internally connected. - - USART Half duplex communication is possible through the following procedure: - 1. Program the Baud rate, Word length, Stop bits, Parity, Mode transmitter - or Mode receiver and hardware flow control values using the USART_Init() - function. - 2. Configures the USART address using the USART_SetAddress() function. - 3. Enable the USART using the USART_Cmd() function. - 4. Enable the half duplex mode using USART_HalfDuplexCmd() function. - -Note: ----- - 1. The RX pin is no longer used - 2. In Half-duplex mode the following bits must be kept cleared: - - LINEN and CLKEN bits in the USART_CR2 register. - - SCEN and IREN bits in the USART_CR3 register. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the USARTs Half Duplex communication. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param NewState: new state of the USART Communication. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ - USARTx->CR3 |= USART_CR3_HDSEL; - } - else - { - /* Disable the Half-Duplex mode by clearing the HDSEL bit in the CR3 register */ - USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_HDSEL); - } -} - -/** - * @} - */ - - -/** @defgroup USART_Group6 Smartcard mode functions - * @brief Smartcard mode functions - * -@verbatim - =============================================================================== - Smartcard mode functions - =============================================================================== - - This subsection provides a set of functions allowing to manage the USART - Smartcard communication. - - The Smartcard interface is designed to support asynchronous protocol Smartcards as - defined in the ISO 7816-3 standard. - - The USART can provide a clock to the smartcard through the SCLK output. - In smartcard mode, SCLK is not associated to the communication but is simply derived - from the internal peripheral input clock through a 5-bit prescaler. - - Smartcard communication is possible through the following procedure: - 1. Configures the Smartcard Prsecaler using the USART_SetPrescaler() function. - 2. Configures the Smartcard Guard Time using the USART_SetGuardTime() function. - 3. Program the USART clock using the USART_ClockInit() function as following: - - USART Clock enabled - - USART CPOL Low - - USART CPHA on first edge - - USART Last Bit Clock Enabled - 4. Program the Smartcard interface using the USART_Init() function as following: - - Word Length = 9 Bits - - 1.5 Stop Bit - - Even parity - - BaudRate = 12096 baud - - Hardware flow control disabled (RTS and CTS signals) - - Tx and Rx enabled - 5. Optionally you can enable the parity error interrupt using the USART_ITConfig() - function - 6. Enable the USART using the USART_Cmd() function. - 7. Enable the Smartcard NACK using the USART_SmartCardNACKCmd() function. - 8. Enable the Smartcard interface using the USART_SmartCardCmd() function. - - Please refer to the ISO 7816-3 specification for more details. - -Note: ------ - 1. It is also possible to choose 0.5 stop bit for receiving but it is recommended - to use 1.5 stop bits for both transmitting and receiving to avoid switching - between the two configurations. - 2. In smartcard mode, the following bits must be kept cleared: - - LINEN bit in the USART_CR2 register. - - HDSEL and IREN bits in the USART_CR3 register. - -@endverbatim - * @{ - */ - -/** - * @brief Sets the specified USART guard time. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param USART_GuardTime: specifies the guard time. - * @retval None - */ -void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - - /* Clear the USART Guard time */ - USARTx->GTPR &= USART_GTPR_PSC; - /* Set the USART guard time */ - USARTx->GTPR |= (uint16_t)((uint16_t)USART_GuardTime << 0x08); -} - -/** - * @brief Enables or disables the USARTs Smart Card mode. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param NewState: new state of the Smart Card mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the SC mode by setting the SCEN bit in the CR3 register */ - USARTx->CR3 |= USART_CR3_SCEN; - } - else - { - /* Disable the SC mode by clearing the SCEN bit in the CR3 register */ - USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_SCEN); - } -} - -/** - * @brief Enables or disables NACK transmission. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param NewState: new state of the NACK transmission. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the NACK transmission by setting the NACK bit in the CR3 register */ - USARTx->CR3 |= USART_CR3_NACK; - } - else - { - /* Disable the NACK transmission by clearing the NACK bit in the CR3 register */ - USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_NACK); - } -} - -/** - * @} - */ - -/** @defgroup USART_Group7 IrDA mode functions - * @brief IrDA mode functions - * -@verbatim - =============================================================================== - IrDA mode functions - =============================================================================== - - This subsection provides a set of functions allowing to manage the USART - IrDA communication. - - IrDA is a half duplex communication protocol. If the Transmitter is busy, any data - on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver - is busy, data on the TX from the USART to IrDA will not be encoded by IrDA. - While receiving data, transmission should be avoided as the data to be transmitted - could be corrupted. - - IrDA communication is possible through the following procedure: - 1. Program the Baud rate, Word length = 8 bits, Stop bits, Parity, Transmitter/Receiver - modes and hardware flow control values using the USART_Init() function. - 2. Enable the USART using the USART_Cmd() function. - 3. Configures the IrDA pulse width by configuring the prescaler using - the USART_SetPrescaler() function. - 4. Configures the IrDA USART_IrDAMode_LowPower or USART_IrDAMode_Normal mode - using the USART_IrDAConfig() function. - 5. Enable the IrDA using the USART_IrDACmd() function. - -Note: ------ - 1. A pulse of width less than two and greater than one PSC period(s) may or may - not be rejected. - 2. The receiver set up time should be managed by software. The IrDA physical layer - specification specifies a minimum of 10 ms delay between transmission and - reception (IrDA is a half duplex protocol). - 3. In IrDA mode, the following bits must be kept cleared: - - LINEN, STOP and CLKEN bits in the USART_CR2 register. - - SCEN and HDSEL bits in the USART_CR3 register. - -@endverbatim - * @{ - */ - -/** - * @brief Configures the USARTs IrDA interface. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param USART_IrDAMode: specifies the IrDA mode. - * This parameter can be one of the following values: - * @arg USART_IrDAMode_LowPower - * @arg USART_IrDAMode_Normal - * @retval None - */ -void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_IRDA_MODE(USART_IrDAMode)); - - USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_IRLP); - USARTx->CR3 |= USART_IrDAMode; -} - -/** - * @brief Enables or disables the USARTs IrDA interface. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param NewState: new state of the IrDA mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the IrDA mode by setting the IREN bit in the CR3 register */ - USARTx->CR3 |= USART_CR3_IREN; - } - else - { - /* Disable the IrDA mode by clearing the IREN bit in the CR3 register */ - USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_IREN); - } -} - -/** - * @} - */ - -/** @defgroup USART_Group8 DMA transfers management functions - * @brief DMA transfers management functions - * -@verbatim - =============================================================================== - DMA transfers management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the USARTs DMA interface. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param USART_DMAReq: specifies the DMA request. - * This parameter can be any combination of the following values: - * @arg USART_DMAReq_Tx: USART DMA transmit request - * @arg USART_DMAReq_Rx: USART DMA receive request - * @param NewState: new state of the DMA Request sources. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_DMAREQ(USART_DMAReq)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the DMA transfer for selected requests by setting the DMAT and/or - DMAR bits in the USART CR3 register */ - USARTx->CR3 |= USART_DMAReq; - } - else - { - /* Disable the DMA transfer for selected requests by clearing the DMAT and/or - DMAR bits in the USART CR3 register */ - USARTx->CR3 &= (uint16_t)~USART_DMAReq; - } -} - -/** - * @} - */ - -/** @defgroup USART_Group9 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - - This subsection provides a set of functions allowing to configure the USART - Interrupts sources, DMA channels requests and check or clear the flags or - pending bits status. - The user should identify which mode will be used in his application to manage - the communication: Polling mode, Interrupt mode or DMA mode. - - Polling Mode - ============= - In Polling Mode, the SPI communication can be managed by 10 flags: - 1. USART_FLAG_TXE : to indicate the status of the transmit buffer register - 2. USART_FLAG_RXNE : to indicate the status of the receive buffer register - 3. USART_FLAG_TC : to indicate the status of the transmit operation - 4. USART_FLAG_IDLE : to indicate the status of the Idle Line - 5. USART_FLAG_CTS : to indicate the status of the nCTS input - 6. USART_FLAG_LBD : to indicate the status of the LIN break detection - 7. USART_FLAG_NE : to indicate if a noise error occur - 8. USART_FLAG_FE : to indicate if a frame error occur - 9. USART_FLAG_PE : to indicate if a parity error occur - 10. USART_FLAG_ORE : to indicate if an Overrun error occur - - In this Mode it is advised to use the following functions: - - FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); - - void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG); - - Interrupt Mode - =============== - In Interrupt Mode, the USART communication can be managed by 8 interrupt sources - and 10 pending bits: - - Pending Bits: - ------------- - 1. USART_IT_TXE : to indicate the status of the transmit buffer register - 2. USART_IT_RXNE : to indicate the status of the receive buffer register - 3. USART_IT_TC : to indicate the status of the transmit operation - 4. USART_IT_IDLE : to indicate the status of the Idle Line - 5. USART_IT_CTS : to indicate the status of the nCTS input - 6. USART_IT_LBD : to indicate the status of the LIN break detection - 7. USART_IT_NE : to indicate if a noise error occur - 8. USART_IT_FE : to indicate if a frame error occur - 9. USART_IT_PE : to indicate if a parity error occur - 10. USART_IT_ORE : to indicate if an Overrun error occur - - Interrupt Source: - ----------------- - 1. USART_IT_TXE : specifies the interrupt source for the Tx buffer empty - interrupt. - 2. USART_IT_RXNE : specifies the interrupt source for the Rx buffer not - empty interrupt. - 3. USART_IT_TC : specifies the interrupt source for the Transmit complete - interrupt. - 4. USART_IT_IDLE : specifies the interrupt source for the Idle Line interrupt. - 5. USART_IT_CTS : specifies the interrupt source for the CTS interrupt. - 6. USART_IT_LBD : specifies the interrupt source for the LIN break detection - interrupt. - 7. USART_IT_PE : specifies the interrupt source for theparity error interrupt. - 8. USART_IT_ERR : specifies the interrupt source for the errors interrupt. - - Note: Some parameters are coded in order to use them as interrupt source or - ---- as pending bits. - - In this Mode it is advised to use the following functions: - - void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState); - - ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT); - - void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT); - - DMA Mode - ======== - In DMA Mode, the USART communication can be managed by 2 DMA Channel requests: - 1. USART_DMAReq_Tx: specifies the Tx buffer DMA transfer request - 2. USART_DMAReq_Rx: specifies the Rx buffer DMA transfer request - - In this Mode it is advised to use the following function: - - void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState); - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified USART interrupts. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param USART_IT: specifies the USART interrupt sources to be enabled or disabled. - * This parameter can be one of the following values: - * @arg USART_IT_CTS: CTS change interrupt - * @arg USART_IT_LBD: LIN Break detection interrupt - * @arg USART_IT_TXE: Tansmit Data Register empty interrupt - * @arg USART_IT_TC: Transmission complete interrupt - * @arg USART_IT_RXNE: Receive Data register not empty interrupt - * @arg USART_IT_IDLE: Idle line detection interrupt - * @arg USART_IT_PE: Parity Error interrupt - * @arg USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error) - * @param NewState: new state of the specified USARTx interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState) -{ - uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00; - uint32_t usartxbase = 0x00; - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_CONFIG_IT(USART_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - usartxbase = (uint32_t)USARTx; - - /* Get the USART register index */ - usartreg = (((uint8_t)USART_IT) >> 0x05); - - /* Get the interrupt position */ - itpos = USART_IT & IT_MASK; - itmask = (((uint32_t)0x01) << itpos); - - if (usartreg == 0x01) /* The IT is in CR1 register */ - { - usartxbase += 0x0C; - } - else if (usartreg == 0x02) /* The IT is in CR2 register */ - { - usartxbase += 0x10; - } - else /* The IT is in CR3 register */ - { - usartxbase += 0x14; - } - if (NewState != DISABLE) - { - *(__IO uint32_t*)usartxbase |= itmask; - } - else - { - *(__IO uint32_t*)usartxbase &= ~itmask; - } -} - -/** - * @brief Checks whether the specified USART flag is set or not. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param USART_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg USART_FLAG_CTS: CTS Change flag - * @arg USART_FLAG_LBD: LIN Break detection flag - * @arg USART_FLAG_TXE: Transmit data register empty flag - * @arg USART_FLAG_TC: Transmission Complete flag - * @arg USART_FLAG_RXNE: Receive data register not empty flag - * @arg USART_FLAG_IDLE: Idle Line detection flag - * @arg USART_FLAG_ORE: OverRun Error flag - * @arg USART_FLAG_NE: Noise Error flag - * @arg USART_FLAG_FE: Framing Error flag - * @arg USART_FLAG_PE: Parity Error flag - * @retval The new state of USART_FLAG (SET or RESET). - */ -FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_FLAG(USART_FLAG)); - - if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the USARTx's pending flags. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param USART_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg USART_FLAG_CTS: CTS Change flag. - * @arg USART_FLAG_LBD: LIN Break detection flag. - * @arg USART_FLAG_TC: Transmission Complete flag. - * @arg USART_FLAG_RXNE: Receive data register not empty flag. - * - * @note - * - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun - * error) and IDLE (Idle line detected) flags are cleared by software - * sequence: a read operation to USART_SR register (USART_GetFlagStatus()) - * followed by a read operation to USART_DR register (USART_ReceiveData()). - * - RXNE flag can be also cleared by a read to the USART_DR register - * (USART_ReceiveData()). - * - TC flag can be also cleared by software sequence: a read operation to - * USART_SR register (USART_GetFlagStatus()) followed by a write operation - * to USART_DR register (USART_SendData()). - * - TXE flag is cleared only by a write to the USART_DR register - * (USART_SendData()). - * @retval None - */ -void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_CLEAR_FLAG(USART_FLAG)); - - USARTx->SR = (uint16_t)~USART_FLAG; -} - -/** - * @brief Checks whether the specified USART interrupt has occurred or not. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param USART_IT: specifies the USART interrupt source to check. - * This parameter can be one of the following values: - * @arg USART_IT_CTS: CTS change interrupt - * @arg USART_IT_LBD: LIN Break detection interrupt - * @arg USART_IT_TXE: Tansmit Data Register empty interrupt - * @arg USART_IT_TC: Transmission complete interrupt - * @arg USART_IT_RXNE: Receive Data register not empty interrupt - * @arg USART_IT_IDLE: Idle line detection interrupt - * @arg USART_IT_ORE: OverRun Error interrupt - * @arg USART_IT_NE: Noise Error interrupt - * @arg USART_IT_FE: Framing Error interrupt - * @arg USART_IT_PE: Parity Error interrupt - * @retval The new state of USART_IT (SET or RESET). - */ -ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT) -{ - uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00; - ITStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_GET_IT(USART_IT)); - - /* Get the USART register index */ - usartreg = (((uint8_t)USART_IT) >> 0x05); - /* Get the interrupt position */ - itmask = USART_IT & IT_MASK; - itmask = (uint32_t)0x01 << itmask; - - if (usartreg == 0x01) /* The IT is in CR1 register */ - { - itmask &= USARTx->CR1; - } - else if (usartreg == 0x02) /* The IT is in CR2 register */ - { - itmask &= USARTx->CR2; - } - else /* The IT is in CR3 register */ - { - itmask &= USARTx->CR3; - } - - bitpos = USART_IT >> 0x08; - bitpos = (uint32_t)0x01 << bitpos; - bitpos &= USARTx->SR; - if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - - return bitstatus; -} - -/** - * @brief Clears the USARTxs interrupt pending bits. - * @param USARTx: Select the USART peripheral. - * This parameter can be one of the following values: - * USART1, USART2 or USART3. - * @param USART_IT: specifies the interrupt pending bit to clear. - * This parameter can be one of the following values: - * @arg USART_IT_CTS: CTS change interrupt - * @arg USART_IT_LBD: LIN Break detection interrupt - * @arg USART_IT_TC: Transmission complete interrupt. - * @arg USART_IT_RXNE: Receive Data register not empty interrupt. - * - * @note - * - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun - * error) and IDLE (Idle line detected) pending bits are cleared by - * software sequence: a read operation to USART_SR register - * (USART_GetITStatus()) followed by a read operation to USART_DR register - * (USART_ReceiveData()). - * - RXNE pending bit can be also cleared by a read to the USART_DR register - * (USART_ReceiveData()). - * - TC pending bit can be also cleared by software sequence: a read - * operation to USART_SR register (USART_GetITStatus()) followed by a write - * operation to USART_DR register (USART_SendData()). - * - TXE pending bit is cleared only by a write to the USART_DR register - * (USART_SendData()). - * @retval None - */ -void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT) -{ - uint16_t bitpos = 0x00, itmask = 0x00; - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_CLEAR_IT(USART_IT)); - - bitpos = USART_IT >> 0x08; - itmask = ((uint16_t)0x01 << (uint16_t)bitpos); - USARTx->SR = (uint16_t)~itmask; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/libs_stm/src/stm32l1xx/stm32l1xx_wwdg.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_wwdg.c deleted file mode 100644 index 9a815d440..000000000 --- a/example/libs_stm/src/stm32l1xx/stm32l1xx_wwdg.c +++ /dev/null @@ -1,307 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l1xx_wwdg.c - * @author MCD Application Team - * @version V1.0.0 - * @date 31-December-2010 - * @brief This file provides firmware functions to manage the following - * functionalities of the Window watchdog (WWDG) peripheral: - * - Prescaler, Refresh window and Counter configuration - * - WWDG activation - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * WWDG features - * =================================================================== - * - * Once enabled the WWDG generates a system reset on expiry of a programmed - * time period, unless the program refreshes the counter (downcounter) - * before to reach 0x3F value (i.e. a reset is generated when the counter - * value rolls over from 0x40 to 0x3F). - * An MCU reset is also generated if the counter value is refreshed - * before the counter has reached the refresh window value. This - * implies that the counter must be refreshed in a limited window. - * - * Once enabled the WWDG cannot be disabled except by a system reset. - * - * WWDGRST flag in RCC_CSR register can be used to inform when a WWDG - * reset occurs. - * - * The WWDG counter input clock is derived from the APB clock divided - * by a programmable prescaler. - * - * WWDG counter clock = PCLK1 / Prescaler - * WWDG timeout = (WWDG counter clock) * (counter value) - * - * Min-max timeout value @32MHz (PCLK1): ~128us / ~65.6ms - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable WWDG clock using RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE) function - * - * 2. Configure the WWDG prescaler using WWDG_SetPrescaler() function - * - * 3. Configure the WWDG refresh window using WWDG_SetWindowValue() function - * - * 4. Set the WWDG counter value and start it using WWDG_Enable() function. - * When the WWDG is enabled the counter value should be configured to - * a value greater than 0x40 to prevent generating an immediate reset. - * - * 5. Optionally you can enable the Early wakeup interrupt which is - * generated when the counter reach 0x40. - * Once enabled this interrupt cannot be disabled except by a system reset. - * - * 6. Then the application program must refresh the WWDG counter at regular - * intervals during normal operation to prevent an MCU reset, using - * WWDG_SetCounter() function. This operation must occur only when - * the counter value is lower than the refresh window value, - * programmed using WWDG_SetWindowValue(). - * - * @endverbatim - * - ****************************************************************************** - * @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

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l1xx_wwdg.h" -#include "stm32l1xx_rcc.h" - -/** @addtogroup STM32L1xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup WWDG - * @brief WWDG driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* ----------- WWDG registers bit address in the alias region ----------- */ -#define WWDG_OFFSET (WWDG_BASE - PERIPH_BASE) - -/* Alias word address of EWI bit */ -#define CFR_OFFSET (WWDG_OFFSET + 0x04) -#define EWI_BitNumber 0x09 -#define CFR_EWI_BB (PERIPH_BB_BASE + (CFR_OFFSET * 32) + (EWI_BitNumber * 4)) - -/* --------------------- WWDG registers bit mask ------------------------ */ - -/* CFR register bit mask */ -#define CFR_WDGTB_MASK ((uint32_t)0xFFFFFE7F) -#define CFR_W_MASK ((uint32_t)0xFFFFFF80) -#define BIT_MASK ((uint8_t)0x7F) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup WWDG_Private_Functions - * @{ - */ - -/** @defgroup WWDG_Group1 Prescaler, Refresh window and Counter configuration functions - * @brief Prescaler, Refresh window and Counter configuration functions - * -@verbatim - =============================================================================== - Prescaler, Refresh window and Counter configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the WWDG peripheral registers to their default reset values. - * @param None - * @retval None - */ -void WWDG_DeInit(void) -{ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, DISABLE); -} - -/** - * @brief Sets the WWDG Prescaler. - * @param WWDG_Prescaler: specifies the WWDG Prescaler. - * This parameter can be one of the following values: - * @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1 - * @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2 - * @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4 - * @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8 - * @retval None - */ -void WWDG_SetPrescaler(uint32_t WWDG_Prescaler) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_WWDG_PRESCALER(WWDG_Prescaler)); - /* Clear WDGTB[1:0] bits */ - tmpreg = WWDG->CFR & CFR_WDGTB_MASK; - /* Set WDGTB[1:0] bits according to WWDG_Prescaler value */ - tmpreg |= WWDG_Prescaler; - /* Store the new value */ - WWDG->CFR = tmpreg; -} - -/** - * @brief Sets the WWDG window value. - * @param WindowValue: specifies the window value to be compared to the downcounter. - * This parameter value must be lower than 0x80. - * @retval None - */ -void WWDG_SetWindowValue(uint8_t WindowValue) -{ - __IO uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_WWDG_WINDOW_VALUE(WindowValue)); - /* Clear W[6:0] bits */ - - tmpreg = WWDG->CFR & CFR_W_MASK; - - /* Set W[6:0] bits according to WindowValue value */ - tmpreg |= WindowValue & (uint32_t) BIT_MASK; - - /* Store the new value */ - WWDG->CFR = tmpreg; -} - -/** - * @brief Enables the WWDG Early Wakeup interrupt(EWI). - * @note Once enabled this interrupt cannot be disabled except by a system reset. - * @param None - * @retval None - */ -void WWDG_EnableIT(void) -{ - *(__IO uint32_t *) CFR_EWI_BB = (uint32_t)ENABLE; -} - -/** - * @brief Sets the WWDG counter value. - * @param Counter: specifies the watchdog counter value. - * This parameter must be a number between 0x40 and 0x7F (to prevent generating - * an immediate reset) - * @retval None - */ -void WWDG_SetCounter(uint8_t Counter) -{ - /* Check the parameters */ - assert_param(IS_WWDG_COUNTER(Counter)); - /* Write to T[6:0] bits to configure the counter value, no need to do - a read-modify-write; writing a 0 to WDGA bit does nothing */ - WWDG->CR = Counter & BIT_MASK; -} - -/** - * @} - */ - -/** @defgroup WWDG_Group2 WWDG activation functions - * @brief WWDG activation functions - * -@verbatim - =============================================================================== - WWDG activation functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables WWDG and load the counter value. - * @param Counter: specifies the watchdog counter value. - * This parameter must be a number between 0x40 and 0x7F (to prevent generating - * an immediate reset) - * @retval None - */ -void WWDG_Enable(uint8_t Counter) -{ - /* Check the parameters */ - assert_param(IS_WWDG_COUNTER(Counter)); - WWDG->CR = WWDG_CR_WDGA | Counter; -} - -/** - * @} - */ - -/** @defgroup WWDG_Group3 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Checks whether the Early Wakeup interrupt flag is set or not. - * @param None - * @retval The new state of the Early Wakeup interrupt flag (SET or RESET) - */ -FlagStatus WWDG_GetFlagStatus(void) -{ - FlagStatus bitstatus = RESET; - - if ((WWDG->SR) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears Early Wakeup interrupt flag. - * @param None - * @retval None - */ -void WWDG_ClearFlag(void) -{ - WWDG->SR = (uint32_t)RESET; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/IO_Toggle/Makefile b/example/stm32f4/Projects/IO_Toggle/Makefile deleted file mode 100644 index ef8860af4..000000000 --- a/example/stm32f4/Projects/IO_Toggle/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -EXECUTABLE=IO_Toggle.elf -BIN_IMAGE=IO_Toggle.bin - -CC=arm-none-eabi-gcc -OBJCOPY=arm-none-eabi-objcopy - -CFLAGS=-g -O2 -mlittle-endian -mthumb -CFLAGS+=-mcpu=cortex-m4 -CFLAGS+=-ffreestanding -nostdlib - -# to run from FLASH -CFLAGS+=-Wl,-T,stm32_flash.ld - -# stm32f4_discovery lib -CFLAGS+=-I../../STM32F4xx_StdPeriph_Driver/inc -CFLAGS+=-I../../STM32F4xx_StdPeriph_Driver/inc/device_support -CFLAGS+=-I../../STM32F4xx_StdPeriph_Driver/inc/core_support - -all: $(BIN_IMAGE) - -$(BIN_IMAGE): $(EXECUTABLE) - $(OBJCOPY) -O binary $^ $@ - -$(EXECUTABLE): main.c system_stm32f4xx.c startup_stm32f4xx.s stm32f4xx_it.c - $(CC) $(CFLAGS) $^ -o $@ -L../../STM32F4xx_StdPeriph_Driver/build -lSTM32F4xx_StdPeriph_Driver - -clean: - rm -rf $(EXECUTABLE) - rm -rf $(BIN_IMAGE) - -.PHONY: all clean diff --git a/example/stm32f4/Projects/IO_Toggle/main.c b/example/stm32f4/Projects/IO_Toggle/main.c deleted file mode 100644 index 152c64b9c..000000000 --- a/example/stm32f4/Projects/IO_Toggle/main.c +++ /dev/null @@ -1,142 +0,0 @@ -/** - ****************************************************************************** - * @file IO_Toggle/main.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief Main program body - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4_discovery.h" -#include "stm32f4xx_conf.h" - -/** @addtogroup STM32F4_Discovery_Peripheral_Examples - * @{ - */ - -/** @addtogroup IO_Toggle - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -GPIO_InitTypeDef GPIO_InitStructure; - -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -void Delay(__IO uint32_t nCount); -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief Main program - * @param None - * @retval None - */ -int main(void) -{ - /*!< At this stage the microcontroller clock setting is already configured, - this is done through SystemInit() function which is called from startup - file (startup_stm32f4xx.s) before to branch to application main. - To reconfigure the default setting of SystemInit() function, refer to - system_stm32f4xx.c file - */ - - /* GPIOD Periph clock enable */ - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); - - /* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOD, &GPIO_InitStructure); - - while (1) - { - /* PD12 to be toggled */ - GPIO_SetBits(GPIOD, GPIO_Pin_12); - - /* Insert delay */ - Delay(0x3FFFFF); - - /* PD13 to be toggled */ - GPIO_SetBits(GPIOD, GPIO_Pin_13); - - /* Insert delay */ - Delay(0x3FFFFF); - - /* PD14 to be toggled */ - GPIO_SetBits(GPIOD, GPIO_Pin_14); - - /* Insert delay */ - Delay(0x3FFFFF); - - /* PD15 to be toggled */ - GPIO_SetBits(GPIOD, GPIO_Pin_15); - - /* Insert delay */ - Delay(0x7FFFFF); - - GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); - - /* Insert delay */ - Delay(0xFFFFFF); - } -} - -/** - * @brief Delay Function. - * @param nCount:specifies the Delay time length. - * @retval None - */ -void Delay(__IO uint32_t nCount) -{ - while(nCount--) - { - } -} - -#ifdef USE_FULL_ASSERT - -/** - * @brief Reports the name of the source file and the source line number - * where the assert_param error has occurred. - * @param file: pointer to the source file name - * @param line: assert_param error line source number - * @retval None - */ -void assert_failed(uint8_t* file, uint32_t line) -{ - /* User can add his own implementation to report the file name and line number, - ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ - - /* Infinite loop */ - while (1) - { - } -} -#endif - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/IO_Toggle/readme.txt b/example/stm32f4/Projects/IO_Toggle/readme.txt deleted file mode 100644 index fda5b2ef2..000000000 --- a/example/stm32f4/Projects/IO_Toggle/readme.txt +++ /dev/null @@ -1,91 +0,0 @@ -/** - @page GPIO_IOToggle GPIO IO Toggle example - - @verbatim - ******************** (C) COPYRIGHT 2011 STMicroelectronics ******************* - * @file IO_Toggle/readme.txt - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief Description of the GPIO IO Toggle example. - ****************************************************************************** - * 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. - ****************************************************************************** - @endverbatim - -@par Example Description - -This example describes how to toggle the GPIO pins connected on AHB bus. - -PD12, PD13, PD14 and PD15 (configured in output pushpull mode) toggles in a forever loop. - - Set PD12, PD13, PD14 and PD15 by setting corresponding bits in BSRRL register - - Reset PD12, PD13, PD14 and PD15 by setting corresponding bits in BSRRH register - -In this example, HCLK is configured at 168 MHz. - -@par Directory contents - - - IO_Toggle/stm32f4xx_conf.h Library Configuration file - - IO_Toggle/stm32f4xx_it.c Interrupt handlers - - IO_Toggle/stm32f4xx_it.h Interrupt handlers header file - - IO_Toggle/main.c Main program - - IO_Toggle/system_stm32f4xx.c STM32F4xx system source file - -@par Hardware and Software environment - - - This example runs on STM32F4xx Devices Revision A. - - - This example has been tested with STM32F4-Discovery (MB997) RevA and can be - easily tailored to any other development board - - - STM32F4-Discovery - - LED4, LED3, LED5 and LED6 are connected respectively to PD.12, PD.13, PD.14 and PD.15. - - -@par How to use it ? - -In order to make the program work, you must do the following : - - + EWARM - - Open the IO_Toggle.eww workspace - - Rebuild all files: Project->Rebuild all - - Load project image: Project->Debug - - Run program: Debug->Go(F5) - - + MDK-ARM - - Open the IO_Toggle.uvproj project - - Rebuild all files: Project->Rebuild all target files - - Load project image: Debug->Start/Stop Debug Session - - Run program: Debug->Run (F5) - - + TASKING - - Open TASKING toolchain. - - Click on File->Import, select General->'Existing Projects into Workspace' - and then click "Next". - - Browse to TASKING workspace directory and select the project "IO_Toggle" - - Rebuild all project files: Select the project in the "Project explorer" - window then click on Project->build project menu. - - Run program: Select the project in the "Project explorer" window then click - Run->Debug (F11) - - + TrueSTUDIO - - Open the TrueSTUDIO toolchain. - - Click on File->Switch Workspace->Other and browse to TrueSTUDIO workspace - directory. - - Click on File->Import, select General->'Existing Projects into Workspace' - and then click "Next". - - Browse to the TrueSTUDIO workspace directory and select the project "IO_Toggle" - - Rebuild all project files: Select the project in the "Project explorer" - window then click on Project->build project menu. - - Run program: Select the project in the "Project explorer" window then click - Run->Debug (F11) - - - - *

© COPYRIGHT 2011 STMicroelectronics

- */ diff --git a/example/stm32f4/Projects/IO_Toggle/startup_stm32f4xx.s b/example/stm32f4/Projects/IO_Toggle/startup_stm32f4xx.s deleted file mode 100644 index ce5360f3c..000000000 --- a/example/stm32f4/Projects/IO_Toggle/startup_stm32f4xx.s +++ /dev/null @@ -1,509 +0,0 @@ -/** - ****************************************************************************** - * @file startup_stm32f4xx.s - * @author MCD Application Team - * @version V1.0.0 - * @date 30-September-2011 - * @brief STM32F4xx 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 - * - Configure the clock system and the external SRAM mounted on - * STM324xG-EVAL board to be used as data memory (optional, - * to be enabled by user) - * - Branches to main in the C library (which eventually - * calls main()). - * After Reset the Cortex-M4 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 2011 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 -/* stack used for SystemInit_ExtMemCtl; always internal RAM used */ - -/** - * @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.*/ - 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 - - /* External Interrupts */ - .word WWDG_IRQHandler /* Window WatchDog */ - .word PVD_IRQHandler /* PVD through EXTI Line detection */ - .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */ - .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */ - .word FLASH_IRQHandler /* FLASH */ - .word RCC_IRQHandler /* RCC */ - .word EXTI0_IRQHandler /* EXTI Line0 */ - .word EXTI1_IRQHandler /* EXTI Line1 */ - .word EXTI2_IRQHandler /* EXTI Line2 */ - .word EXTI3_IRQHandler /* EXTI Line3 */ - .word EXTI4_IRQHandler /* EXTI Line4 */ - .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */ - .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */ - .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */ - .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */ - .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */ - .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */ - .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */ - .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */ - .word CAN1_TX_IRQHandler /* CAN1 TX */ - .word CAN1_RX0_IRQHandler /* CAN1 RX0 */ - .word CAN1_RX1_IRQHandler /* CAN1 RX1 */ - .word CAN1_SCE_IRQHandler /* CAN1 SCE */ - .word EXTI9_5_IRQHandler /* External Line[9:5]s */ - .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */ - .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */ - .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */ - .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ - .word TIM2_IRQHandler /* TIM2 */ - .word TIM3_IRQHandler /* TIM3 */ - .word TIM4_IRQHandler /* TIM4 */ - .word I2C1_EV_IRQHandler /* I2C1 Event */ - .word I2C1_ER_IRQHandler /* I2C1 Error */ - .word I2C2_EV_IRQHandler /* I2C2 Event */ - .word I2C2_ER_IRQHandler /* I2C2 Error */ - .word SPI1_IRQHandler /* SPI1 */ - .word SPI2_IRQHandler /* SPI2 */ - .word USART1_IRQHandler /* USART1 */ - .word USART2_IRQHandler /* USART2 */ - .word USART3_IRQHandler /* USART3 */ - .word EXTI15_10_IRQHandler /* External Line[15:10]s */ - .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */ - .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */ - .word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */ - .word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */ - .word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */ - .word TIM8_CC_IRQHandler /* TIM8 Capture Compare */ - .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */ - .word FSMC_IRQHandler /* FSMC */ - .word SDIO_IRQHandler /* SDIO */ - .word TIM5_IRQHandler /* TIM5 */ - .word SPI3_IRQHandler /* SPI3 */ - .word UART4_IRQHandler /* UART4 */ - .word UART5_IRQHandler /* UART5 */ - .word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */ - .word TIM7_IRQHandler /* TIM7 */ - .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */ - .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */ - .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */ - .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */ - .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */ - .word ETH_IRQHandler /* Ethernet */ - .word ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */ - .word CAN2_TX_IRQHandler /* CAN2 TX */ - .word CAN2_RX0_IRQHandler /* CAN2 RX0 */ - .word CAN2_RX1_IRQHandler /* CAN2 RX1 */ - .word CAN2_SCE_IRQHandler /* CAN2 SCE */ - .word OTG_FS_IRQHandler /* USB OTG FS */ - .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */ - .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */ - .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */ - .word USART6_IRQHandler /* USART6 */ - .word I2C3_EV_IRQHandler /* I2C3 event */ - .word I2C3_ER_IRQHandler /* I2C3 error */ - .word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */ - .word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */ - .word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */ - .word OTG_HS_IRQHandler /* USB OTG HS */ - .word DCMI_IRQHandler /* DCMI */ - .word CRYP_IRQHandler /* CRYP crypto */ - .word HASH_RNG_IRQHandler /* Hash and Rng */ - .word FPU_IRQHandler /* FPU */ - -/******************************************************************************* -* -* 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 TAMP_STAMP_IRQHandler - .thumb_set TAMP_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_Stream0_IRQHandler - .thumb_set DMA1_Stream0_IRQHandler,Default_Handler - - .weak DMA1_Stream1_IRQHandler - .thumb_set DMA1_Stream1_IRQHandler,Default_Handler - - .weak DMA1_Stream2_IRQHandler - .thumb_set DMA1_Stream2_IRQHandler,Default_Handler - - .weak DMA1_Stream3_IRQHandler - .thumb_set DMA1_Stream3_IRQHandler,Default_Handler - - .weak DMA1_Stream4_IRQHandler - .thumb_set DMA1_Stream4_IRQHandler,Default_Handler - - .weak DMA1_Stream5_IRQHandler - .thumb_set DMA1_Stream5_IRQHandler,Default_Handler - - .weak DMA1_Stream6_IRQHandler - .thumb_set DMA1_Stream6_IRQHandler,Default_Handler - - .weak ADC_IRQHandler - .thumb_set ADC_IRQHandler,Default_Handler - - .weak CAN1_TX_IRQHandler - .thumb_set CAN1_TX_IRQHandler,Default_Handler - - .weak CAN1_RX0_IRQHandler - .thumb_set CAN1_RX0_IRQHandler,Default_Handler - - .weak CAN1_RX1_IRQHandler - .thumb_set CAN1_RX1_IRQHandler,Default_Handler - - .weak CAN1_SCE_IRQHandler - .thumb_set CAN1_SCE_IRQHandler,Default_Handler - - .weak EXTI9_5_IRQHandler - .thumb_set EXTI9_5_IRQHandler,Default_Handler - - .weak TIM1_BRK_TIM9_IRQHandler - .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler - - .weak TIM1_UP_TIM10_IRQHandler - .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler - - .weak TIM1_TRG_COM_TIM11_IRQHandler - .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler - - .weak TIM1_CC_IRQHandler - .thumb_set TIM1_CC_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 OTG_FS_WKUP_IRQHandler - .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler - - .weak TIM8_BRK_TIM12_IRQHandler - .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler - - .weak TIM8_UP_TIM13_IRQHandler - .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler - - .weak TIM8_TRG_COM_TIM14_IRQHandler - .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler - - .weak TIM8_CC_IRQHandler - .thumb_set TIM8_CC_IRQHandler,Default_Handler - - .weak DMA1_Stream7_IRQHandler - .thumb_set DMA1_Stream7_IRQHandler,Default_Handler - - .weak FSMC_IRQHandler - .thumb_set FSMC_IRQHandler,Default_Handler - - .weak SDIO_IRQHandler - .thumb_set SDIO_IRQHandler,Default_Handler - - .weak TIM5_IRQHandler - .thumb_set TIM5_IRQHandler,Default_Handler - - .weak SPI3_IRQHandler - .thumb_set SPI3_IRQHandler,Default_Handler - - .weak UART4_IRQHandler - .thumb_set UART4_IRQHandler,Default_Handler - - .weak UART5_IRQHandler - .thumb_set UART5_IRQHandler,Default_Handler - - .weak TIM6_DAC_IRQHandler - .thumb_set TIM6_DAC_IRQHandler,Default_Handler - - .weak TIM7_IRQHandler - .thumb_set TIM7_IRQHandler,Default_Handler - - .weak DMA2_Stream0_IRQHandler - .thumb_set DMA2_Stream0_IRQHandler,Default_Handler - - .weak DMA2_Stream1_IRQHandler - .thumb_set DMA2_Stream1_IRQHandler,Default_Handler - - .weak DMA2_Stream2_IRQHandler - .thumb_set DMA2_Stream2_IRQHandler,Default_Handler - - .weak DMA2_Stream3_IRQHandler - .thumb_set DMA2_Stream3_IRQHandler,Default_Handler - - .weak DMA2_Stream4_IRQHandler - .thumb_set DMA2_Stream4_IRQHandler,Default_Handler - - .weak ETH_IRQHandler - .thumb_set ETH_IRQHandler,Default_Handler - - .weak ETH_WKUP_IRQHandler - .thumb_set ETH_WKUP_IRQHandler,Default_Handler - - .weak CAN2_TX_IRQHandler - .thumb_set CAN2_TX_IRQHandler,Default_Handler - - .weak CAN2_RX0_IRQHandler - .thumb_set CAN2_RX0_IRQHandler,Default_Handler - - .weak CAN2_RX1_IRQHandler - .thumb_set CAN2_RX1_IRQHandler,Default_Handler - - .weak CAN2_SCE_IRQHandler - .thumb_set CAN2_SCE_IRQHandler,Default_Handler - - .weak OTG_FS_IRQHandler - .thumb_set OTG_FS_IRQHandler,Default_Handler - - .weak DMA2_Stream5_IRQHandler - .thumb_set DMA2_Stream5_IRQHandler,Default_Handler - - .weak DMA2_Stream6_IRQHandler - .thumb_set DMA2_Stream6_IRQHandler,Default_Handler - - .weak DMA2_Stream7_IRQHandler - .thumb_set DMA2_Stream7_IRQHandler,Default_Handler - - .weak USART6_IRQHandler - .thumb_set USART6_IRQHandler,Default_Handler - - .weak I2C3_EV_IRQHandler - .thumb_set I2C3_EV_IRQHandler,Default_Handler - - .weak I2C3_ER_IRQHandler - .thumb_set I2C3_ER_IRQHandler,Default_Handler - - .weak OTG_HS_EP1_OUT_IRQHandler - .thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler - - .weak OTG_HS_EP1_IN_IRQHandler - .thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler - - .weak OTG_HS_WKUP_IRQHandler - .thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler - - .weak OTG_HS_IRQHandler - .thumb_set OTG_HS_IRQHandler,Default_Handler - - .weak DCMI_IRQHandler - .thumb_set DCMI_IRQHandler,Default_Handler - - .weak CRYP_IRQHandler - .thumb_set CRYP_IRQHandler,Default_Handler - - .weak HASH_RNG_IRQHandler - .thumb_set HASH_RNG_IRQHandler,Default_Handler - - .weak FPU_IRQHandler - .thumb_set FPU_IRQHandler,Default_Handler - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/IO_Toggle/stm32_flash.ld b/example/stm32f4/Projects/IO_Toggle/stm32_flash.ld deleted file mode 100644 index 1a0b4b860..000000000 --- a/example/stm32f4/Projects/IO_Toggle/stm32_flash.ld +++ /dev/null @@ -1,170 +0,0 @@ -/* -***************************************************************************** -** -** File : stm32_flash.ld -** -** Abstract : Linker script for STM32F407VG Device with -** 1024KByte FLASH, 192KByte 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 = 0x20020000; /* end of 128K RAM on AHB bus*/ - -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0; /* required amount of heap */ -_Min_Stack_Size = 0x400; /* required amount of stack */ - -/* Specify the memory areas */ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K - MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K -} - -/* 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) } -} diff --git a/example/stm32f4/Projects/IO_Toggle/stm32f4_discovery.h b/example/stm32f4/Projects/IO_Toggle/stm32f4_discovery.h deleted file mode 100644 index c6fec4221..000000000 --- a/example/stm32f4/Projects/IO_Toggle/stm32f4_discovery.h +++ /dev/null @@ -1,158 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4_discovery.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file contains definitions for STM32F4-Discovery Kit's Leds and - * push-button hardware resources. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4_DISCOVERY_H -#define __STM32F4_DISCOVERY_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ - #include "stm32f4xx.h" - -/** @addtogroup Utilities - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY_LOW_LEVEL - * @{ - */ - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Exported_Types - * @{ - */ -typedef enum -{ - LED4 = 0, - LED3 = 1, - LED5 = 2, - LED6 = 3 -} Led_TypeDef; - -typedef enum -{ - BUTTON_USER = 0, -} Button_TypeDef; - -typedef enum -{ - BUTTON_MODE_GPIO = 0, - BUTTON_MODE_EXTI = 1 -} ButtonMode_TypeDef; -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Exported_Constants - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY_LOW_LEVEL_LED - * @{ - */ -#define LEDn 4 - -#define LED4_PIN GPIO_Pin_12 -#define LED4_GPIO_PORT GPIOD -#define LED4_GPIO_CLK RCC_AHB1Periph_GPIOD - -#define LED3_PIN GPIO_Pin_13 -#define LED3_GPIO_PORT GPIOD -#define LED3_GPIO_CLK RCC_AHB1Periph_GPIOD - -#define LED5_PIN GPIO_Pin_14 -#define LED5_GPIO_PORT GPIOD -#define LED5_GPIO_CLK RCC_AHB1Periph_GPIOD - -#define LED6_PIN GPIO_Pin_15 -#define LED6_GPIO_PORT GPIOD -#define LED6_GPIO_CLK RCC_AHB1Periph_GPIOD -/** - * @} - */ - -/** @addtogroup STM32F4_DISCOVERY_LOW_LEVEL_BUTTON - * @{ - */ -#define BUTTONn 1 - -/** - * @brief Wakeup push-button - */ -#define USER_BUTTON_PIN GPIO_Pin_0 -#define USER_BUTTON_GPIO_PORT GPIOA -#define USER_BUTTON_GPIO_CLK RCC_AHB1Periph_GPIOA -#define USER_BUTTON_EXTI_LINE EXTI_Line0 -#define USER_BUTTON_EXTI_PORT_SOURCE EXTI_PortSourceGPIOA -#define USER_BUTTON_EXTI_PIN_SOURCE EXTI_PinSource0 -#define USER_BUTTON_EXTI_IRQn EXTI0_IRQn -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Exported_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Exported_Functions - * @{ - */ -void STM_EVAL_LEDInit(Led_TypeDef Led); -void STM_EVAL_LEDOn(Led_TypeDef Led); -void STM_EVAL_LEDOff(Led_TypeDef Led); -void STM_EVAL_LEDToggle(Led_TypeDef Led); -void STM_EVAL_PBInit(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode); -uint32_t STM_EVAL_PBGetState(Button_TypeDef Button); -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4_DISCOVERY_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/IO_Toggle/stm32f4xx_conf.h b/example/stm32f4/Projects/IO_Toggle/stm32f4xx_conf.h deleted file mode 100644 index abd159f6b..000000000 --- a/example/stm32f4/Projects/IO_Toggle/stm32f4xx_conf.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - ****************************************************************************** - * @file IO_Toggle/stm32f4xx_conf.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief Library configuration file. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_CONF_H -#define __STM32F4xx_CONF_H - -#if defined (HSE_VALUE) -/* Redefine the HSE value; it's equal to 8 MHz on the STM32F4-DISCOVERY Kit */ - #undef HSE_VALUE - #define HSE_VALUE ((uint32_t)8000000) -#endif /* HSE_VALUE */ - -/* Includes ------------------------------------------------------------------*/ -/* Uncomment the line below to enable peripheral header file inclusion */ -#include "stm32f4xx_adc.h" -#include "stm32f4xx_can.h" -#include "stm32f4xx_crc.h" -#include "stm32f4xx_cryp.h" -#include "stm32f4xx_dac.h" -#include "stm32f4xx_dbgmcu.h" -#include "stm32f4xx_dcmi.h" -#include "stm32f4xx_dma.h" -#include "stm32f4xx_exti.h" -#include "stm32f4xx_flash.h" -#include "stm32f4xx_fsmc.h" -#include "stm32f4xx_hash.h" -#include "stm32f4xx_gpio.h" -#include "stm32f4xx_i2c.h" -#include "stm32f4xx_iwdg.h" -#include "stm32f4xx_pwr.h" -#include "stm32f4xx_rcc.h" -#include "stm32f4xx_rng.h" -#include "stm32f4xx_rtc.h" -#include "stm32f4xx_sdio.h" -#include "stm32f4xx_spi.h" -#include "stm32f4xx_syscfg.h" -#include "stm32f4xx_tim.h" -#include "stm32f4xx_usart.h" -#include "stm32f4xx_wwdg.h" -#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/* If an external clock source is used, then the value of the following define - should be set to the value of the external clock source, else, if no external - clock is used, keep this define commented */ -/*#define I2S_EXTERNAL_CLOCK_VAL 12288000 */ /* Value of the external clock in Hz */ - - -/* Uncomment the line below to expanse the "assert_param" macro in the - Standard Peripheral Library drivers code */ -/* #define USE_FULL_ASSERT 1 */ - -/* Exported macro ------------------------------------------------------------*/ -#ifdef USE_FULL_ASSERT - -/** - * @brief The assert_param macro is used for function's parameters check. - * @param expr: If expr is false, it calls assert_failed function - * which reports the name of the source file and the source - * line number of the call that failed. - * If expr is true, it returns no value. - * @retval None - */ - #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) -/* Exported functions ------------------------------------------------------- */ - void assert_failed(uint8_t* file, uint32_t line); -#else - #define assert_param(expr) ((void)0) -#endif /* USE_FULL_ASSERT */ - -#endif /* __STM32F4xx_CONF_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/IO_Toggle/stm32f4xx_it.c b/example/stm32f4/Projects/IO_Toggle/stm32f4xx_it.c deleted file mode 100644 index ceac51ac4..000000000 --- a/example/stm32f4/Projects/IO_Toggle/stm32f4xx_it.c +++ /dev/null @@ -1,167 +0,0 @@ -/** - ****************************************************************************** - * @file IO_Toggle/stm32f4xx_it.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief Main Interrupt Service Routines. - * This file provides template for all exceptions handler and - * peripherals interrupt service routine. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_it.h" - -/** @addtogroup STM32F4_Discovery_Peripheral_Examples - * @{ - */ - -/** @addtogroup IO_Toggle - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************/ -/* Cortex-M4 Processor Exceptions Handlers */ -/******************************************************************************/ - -/** - * @brief This function handles NMI exception. - * @param None - * @retval None - */ -void NMI_Handler(void) -{ -} - -/** - * @brief This function handles Hard Fault exception. - * @param None - * @retval None - */ -void HardFault_Handler(void) -{ - /* Go to infinite loop when Hard Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Memory Manage exception. - * @param None - * @retval None - */ -void MemManage_Handler(void) -{ - /* Go to infinite loop when Memory Manage exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Bus Fault exception. - * @param None - * @retval None - */ -void BusFault_Handler(void) -{ - /* Go to infinite loop when Bus Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Usage Fault exception. - * @param None - * @retval None - */ -void UsageFault_Handler(void) -{ - /* Go to infinite loop when Usage Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles SVCall exception. - * @param None - * @retval None - */ -void SVC_Handler(void) -{ -} - -/** - * @brief This function handles Debug Monitor exception. - * @param None - * @retval None - */ -void DebugMon_Handler(void) -{ -} - -/** - * @brief This function handles PendSVC exception. - * @param None - * @retval None - */ -void PendSV_Handler(void) -{ -} - -/** - * @brief This function handles SysTick Handler. - * @param None - * @retval None - */ -void SysTick_Handler(void) -{ -} - -/******************************************************************************/ -/* STM32F4xx Peripherals Interrupt Handlers */ -/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ -/* available peripheral interrupt handler's name please refer to the startup */ -/* file (startup_stm32f4xx.s). */ -/******************************************************************************/ - -/** - * @brief This function handles PPP interrupt request. - * @param None - * @retval None - */ -/*void PPP_IRQHandler(void) -{ -}*/ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/IO_Toggle/stm32f4xx_it.h b/example/stm32f4/Projects/IO_Toggle/stm32f4xx_it.h deleted file mode 100644 index 74f17c9cc..000000000 --- a/example/stm32f4/Projects/IO_Toggle/stm32f4xx_it.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - ****************************************************************************** - * @file GPIO/IOToggle/stm32f4xx_it.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file contains the headers of the interrupt handlers. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_IT_H -#define __STM32F4xx_IT_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -void NMI_Handler(void); -void HardFault_Handler(void); -void MemManage_Handler(void); -void BusFault_Handler(void); -void UsageFault_Handler(void); -void SVC_Handler(void); -void DebugMon_Handler(void); -void PendSV_Handler(void); -void SysTick_Handler(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_IT_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/IO_Toggle/system_stm32f4xx.c b/example/stm32f4/Projects/IO_Toggle/system_stm32f4xx.c deleted file mode 100644 index b058084b6..000000000 --- a/example/stm32f4/Projects/IO_Toggle/system_stm32f4xx.c +++ /dev/null @@ -1,545 +0,0 @@ -/** - ****************************************************************************** - * @file system_stm32f4xx.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. - * This file contains the system clock configuration for STM32F4xx devices, - * and is generated by the clock configuration tool - * stm32f4xx_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_stm32f4xx.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 HSI (16 MHz) is used as system clock source. - * Then SystemInit() function is called, in "startup_stm32f4xx.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 HSI 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 8 MHz, refer to "HSE_VALUE" define - * in "stm32f4xx.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: - *============================================================================= - *============================================================================= - * Supported STM32F4xx device revision | Rev A - *----------------------------------------------------------------------------- - * System Clock source | PLL (HSE) - *----------------------------------------------------------------------------- - * SYSCLK(Hz) | 168000000 - *----------------------------------------------------------------------------- - * HCLK(Hz) | 168000000 - *----------------------------------------------------------------------------- - * AHB Prescaler | 1 - *----------------------------------------------------------------------------- - * APB1 Prescaler | 4 - *----------------------------------------------------------------------------- - * APB2 Prescaler | 2 - *----------------------------------------------------------------------------- - * HSE Frequency(Hz) | 8000000 - *----------------------------------------------------------------------------- - * PLL_M | 8 - *----------------------------------------------------------------------------- - * PLL_N | 336 - *----------------------------------------------------------------------------- - * PLL_P | 2 - *----------------------------------------------------------------------------- - * PLL_Q | 7 - *----------------------------------------------------------------------------- - * PLLI2S_N | NA - *----------------------------------------------------------------------------- - * PLLI2S_R | NA - *----------------------------------------------------------------------------- - * I2S input clock | NA - *----------------------------------------------------------------------------- - * VDD(V) | 3.3 - *----------------------------------------------------------------------------- - * High Performance mode | Enabled - *----------------------------------------------------------------------------- - * Flash Latency(WS) | 5 - *----------------------------------------------------------------------------- - * Prefetch Buffer | OFF - *----------------------------------------------------------------------------- - * Instruction cache | ON - *----------------------------------------------------------------------------- - * Data cache | ON - *----------------------------------------------------------------------------- - * Require 48MHz for USB OTG FS, | Enabled - * SDIO and RNG clock | - *----------------------------------------------------------------------------- - *============================================================================= - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32f4xx_system - * @{ - */ - -/** @addtogroup STM32F4xx_System_Private_Includes - * @{ - */ - -#include "stm32f4xx.h" - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_Defines - * @{ - */ - -/*!< Uncomment the following line if you need to use external SRAM mounted - on STM324xG_EVAL board as data memory */ -/* #define DATA_IN_ExtSRAM */ - -/*!< Uncomment the following line if you need to relocate your vector Table in - Internal SRAM. */ -/* #define VECT_TAB_SRAM */ -#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. - This value must be a multiple of 0x200. */ - - -/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ -#define PLL_M 8 -#define PLL_N 336 - -/* SYSCLK = PLL_VCO / PLL_P */ -#define PLL_P 2 - -/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ -#define PLL_Q 7 - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_Variables - * @{ - */ - - uint32_t SystemCoreClock = 168000000; - - __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes - * @{ - */ - -static void SetSysClock(void); -#ifdef DATA_IN_ExtSRAM - static void SystemInit_ExtMemCtl(void); -#endif /* DATA_IN_ExtSRAM */ - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_Functions - * @{ - */ - -/** - * @brief Setup the microcontroller system - * Initialize the Embedded Flash Interface, the PLL and update the - * SystemFrequency variable. - * @param None - * @retval None - */ -void SystemInit(void) -{ - /* Reset the RCC clock configuration to the default reset state ------------*/ - /* Set HSION bit */ - RCC->CR |= (uint32_t)0x00000001; - - /* Reset CFGR register */ - RCC->CFGR = 0x00000000; - - /* Reset HSEON, CSSON and PLLON bits */ - RCC->CR &= (uint32_t)0xFEF6FFFF; - - /* Reset PLLCFGR register */ - RCC->PLLCFGR = 0x24003010; - - /* Reset HSEBYP bit */ - RCC->CR &= (uint32_t)0xFFFBFFFF; - - /* Disable all interrupts */ - RCC->CIR = 0x00000000; - -#ifdef DATA_IN_ExtSRAM - SystemInit_ExtMemCtl(); -#endif /* DATA_IN_ExtSRAM */ - - /* Configure the System clock source, PLL Multiplier and Divider factors, - AHB/APBx prescalers and Flash settings ----------------------------------*/ - SetSysClock(); - - /* Configure the Vector Table location add offset address ------------------*/ -#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 variable according to Clock Register Values. - * The SystemCoreClock variable contains the core clock (HCLK), it can - * be used by the user application to setup the SysTick timer or configure - * other parameters. - * - * @note Each time the core clock (HCLK) changes, this function must be called - * to update SystemCoreClock variable value. Otherwise, any configuration - * based on this variable will be incorrect. - * - * @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 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 stm32f4xx.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 stm32f4xx.h file (default value - * 25 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, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; - - /* Get SYSCLK source -------------------------------------------------------*/ - tmp = RCC->CFGR & RCC_CFGR_SWS; - - switch (tmp) - { - case 0x00: /* HSI used as system clock source */ - SystemCoreClock = HSI_VALUE; - break; - case 0x04: /* HSE used as system clock source */ - SystemCoreClock = HSE_VALUE; - break; - case 0x08: /* PLL used as system clock source */ - - /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N - SYSCLK = PLL_VCO / PLL_P - */ - pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; - pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; - - if (pllsource != 0) - { - /* HSE used as PLL clock source */ - pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); - } - else - { - /* HSI used as PLL clock source */ - pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); - } - - pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; - SystemCoreClock = pllvco/pllp; - break; - default: - SystemCoreClock = HSI_VALUE; - break; - } - /* Compute HCLK frequency --------------------------------------------------*/ - /* Get HCLK prescaler */ - tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; - /* HCLK frequency */ - SystemCoreClock >>= tmp; -} - -/** - * @brief Configures the System clock source, PLL Multiplier and Divider factors, - * 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) -{ -/******************************************************************************/ -/* PLL (clocked by HSE) used as System clock source */ -/******************************************************************************/ - __IO uint32_t StartUpCounter = 0, HSEStatus = 0; - - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { - /* Enable high performance mode, System frequency up to 168 MHz */ - RCC->APB1ENR |= RCC_APB1ENR_PWREN; - PWR->CR |= PWR_CR_PMODE; - - /* HCLK = SYSCLK / 1*/ - RCC->CFGR |= RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK / 2*/ - RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; - - /* PCLK1 = HCLK / 4*/ - RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; - - /* Configure the main PLL */ - RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); - - /* Enable the main PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till the main PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; - - /* Select the main PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= RCC_CFGR_SW_PLL; - - /* Wait till the main PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } - -} - -/** - * @brief Setup the external memory controller. Called in startup_stm32f4xx.s - * before jump to __main - * @param None - * @retval None - */ -#ifdef DATA_IN_ExtSRAM -/** - * @brief Setup the external memory controller. - * Called in startup_stm32f4xx.s before jump to main. - * This function configures the external SRAM mounted on STM324xG_EVAL board - * This SRAM will be used as program data memory (including heap and stack). - * @param None - * @retval None - */ -void SystemInit_ExtMemCtl(void) -{ -/*-- GPIOs Configuration -----------------------------------------------------*/ -/* - +-------------------+--------------------+------------------+------------------+ - + SRAM pins assignment + - +-------------------+--------------------+------------------+------------------+ - | PD0 <-> FSMC_D2 | PE0 <-> FSMC_NBL0 | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 | - | PD1 <-> FSMC_D3 | PE1 <-> FSMC_NBL1 | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 | - | PD4 <-> FSMC_NOE | PE3 <-> FSMC_A19 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 | - | PD5 <-> FSMC_NWE | PE4 <-> FSMC_A20 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 | - | PD8 <-> FSMC_D13 | PE7 <-> FSMC_D4 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 | - | PD9 <-> FSMC_D14 | PE8 <-> FSMC_D5 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 | - | PD10 <-> FSMC_D15 | PE9 <-> FSMC_D6 | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 | - | PD11 <-> FSMC_A16 | PE10 <-> FSMC_D7 | PF13 <-> FSMC_A7 |------------------+ - | PD12 <-> FSMC_A17 | PE11 <-> FSMC_D8 | PF14 <-> FSMC_A8 | - | PD13 <-> FSMC_A18 | PE12 <-> FSMC_D9 | PF15 <-> FSMC_A9 | - | PD14 <-> FSMC_D0 | PE13 <-> FSMC_D10 |------------------+ - | PD15 <-> FSMC_D1 | PE14 <-> FSMC_D11 | - | | PE15 <-> FSMC_D12 | - +-------------------+--------------------+ -*/ - /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ - RCC->AHB1ENR = 0x00000078; - - /* Connect PDx pins to FSMC Alternate function */ - GPIOD->AFR[0] = 0x00cc00cc; - GPIOD->AFR[1] = 0xcc0ccccc; - /* Configure PDx pins in Alternate function mode */ - GPIOD->MODER = 0xaaaa0a0a; - /* Configure PDx pins speed to 100 MHz */ - GPIOD->OSPEEDR = 0xffff0f0f; - /* Configure PDx pins Output type to push-pull */ - GPIOD->OTYPER = 0x00000000; - /* No pull-up, pull-down for PDx pins */ - GPIOD->PUPDR = 0x00000000; - - /* Connect PEx pins to FSMC Alternate function */ - GPIOE->AFR[0] = 0xc00cc0cc; - GPIOE->AFR[1] = 0xcccccccc; - /* Configure PEx pins in Alternate function mode */ - GPIOE->MODER = 0xaaaa828a; - /* Configure PEx pins speed to 100 MHz */ - GPIOE->OSPEEDR = 0xffffc3cf; - /* Configure PEx pins Output type to push-pull */ - GPIOE->OTYPER = 0x00000000; - /* No pull-up, pull-down for PEx pins */ - GPIOE->PUPDR = 0x00000000; - - /* Connect PFx pins to FSMC Alternate function */ - GPIOF->AFR[0] = 0x00cccccc; - GPIOF->AFR[1] = 0xcccc0000; - /* Configure PFx pins in Alternate function mode */ - GPIOF->MODER = 0xaa000aaa; - /* Configure PFx pins speed to 100 MHz */ - GPIOF->OSPEEDR = 0xff000fff; - /* Configure PFx pins Output type to push-pull */ - GPIOF->OTYPER = 0x00000000; - /* No pull-up, pull-down for PFx pins */ - GPIOF->PUPDR = 0x00000000; - - /* Connect PGx pins to FSMC Alternate function */ - GPIOG->AFR[0] = 0x00cccccc; - GPIOG->AFR[1] = 0x000000c0; - /* Configure PGx pins in Alternate function mode */ - GPIOG->MODER = 0x00080aaa; - /* Configure PGx pins speed to 100 MHz */ - GPIOG->OSPEEDR = 0x000c0fff; - /* Configure PGx pins Output type to push-pull */ - GPIOG->OTYPER = 0x00000000; - /* No pull-up, pull-down for PGx pins */ - GPIOG->PUPDR = 0x00000000; - -/*-- FSMC Configuration ------------------------------------------------------*/ - /* Enable the FSMC interface clock */ - RCC->AHB3ENR = 0x00000001; - - /* Configure and enable Bank1_SRAM2 */ - FSMC_Bank1->BTCR[2] = 0x00001015; - FSMC_Bank1->BTCR[3] = 0x00010603;//0x00010400; - FSMC_Bank1E->BWTR[2] = 0x0fffffff; -/* - Bank1_SRAM2 is configured as follow: - - p.FSMC_AddressSetupTime = 3;//0; - p.FSMC_AddressHoldTime = 0; - p.FSMC_DataSetupTime = 6;//4; - p.FSMC_BusTurnAroundDuration = 1; - p.FSMC_CLKDivision = 0; - p.FSMC_DataLatency = 0; - p.FSMC_AccessMode = FSMC_AccessMode_A; - - FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2; - FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; - FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM; - FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; - FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; - FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; - FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; - FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; - FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; - FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; -*/ - -} -#endif /* DATA_IN_ExtSRAM */ - - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/Projects/discovery_demo/Makefile b/example/stm32f4/Projects/discovery_demo/Makefile deleted file mode 100644 index 01a2d860e..000000000 --- a/example/stm32f4/Projects/discovery_demo/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -EXECUTABLE=STM32F4-Discovery_Demo.elf -BIN_IMAGE=STM32F4-Discovery_Demo.bin - -CC=arm-none-eabi-gcc -OBJCOPY=arm-none-eabi-objcopy - -CFLAGS=-g -O2 -mlittle-endian -mthumb -CFLAGS+=-mcpu=cortex-m4 -CFLAGS+=-ffreestanding -nostdlib - -#usb_conf.h -CFLAGS+=-DUSE_USB_OTG_FS=1 - -# to run from FLASH -CFLAGS+=-Wl,-T,stm32_flash.ld - -CFLAGS+=-I./ - -# stm32f4_discovery lib -CFLAGS+=-I../../STM32F4xx_StdPeriph_Driver/inc -CFLAGS+=-I../../STM32F4xx_StdPeriph_Driver/inc/device_support -CFLAGS+=-I../../STM32F4xx_StdPeriph_Driver/inc/core_support - -#STM32_USB_Device_Library -CFLAGS+=-I../../STM32_USB_Device_Library/Class/hid/inc -CFLAGS+=-I../../STM32_USB_Device_Library/Core/inc - -#STM32_USB_OTG_Driver -CFLAGS+=-I../../STM32_USB_OTG_Driver/inc - -#STM32F4xx_StdPeriph_Driver\inc -CFLAGS+=-I../../STM32F4xx_StdPeriph_Driver/inc - -#Utilities -CFLAGS+=-I../../Utilities/STM32F4-Discovery - -all: $(BIN_IMAGE) - -$(BIN_IMAGE): $(EXECUTABLE) - $(OBJCOPY) -O binary $^ $@ - -$(EXECUTABLE): main.c selftest.c system_stm32f4xx.c startup_stm32f4xx.s stm32f4xx_it.c \ - usb_bsp.c usbd_desc.c usbd_usr.c usb_core.c \ - ../../Utilities/STM32F4-Discovery/stm32f4_discovery.c \ - ../../Utilities/STM32F4-Discovery/stm32f4_discovery_audio_codec.c \ - ../../Utilities/STM32F4-Discovery/stm32f4_discovery_lis302dl.c \ - ../../STM32_USB_OTG_Driver/src/usb_dcd_int.c \ - ../../STM32_USB_OTG_Driver/src/usb_dcd.c \ - ../../STM32_USB_Device_Library/Core/src/usbd_core.c \ - ../../STM32_USB_Device_Library/Core/src/usbd_req.c \ - ../../STM32_USB_Device_Library/Core/src/usbd_ioreq.c \ - ../../STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c \ - - - $(CC) $(CFLAGS) $^ -o $@ -L../../STM32F4xx_StdPeriph_Driver/build -lSTM32F4xx_StdPeriph_Driver -L../../STM32F_USB_OTG_Driver/build - -clean: - rm -rf $(EXECUTABLE) - rm -rf $(BIN_IMAGE) - -.PHONY: all clean diff --git a/example/stm32f4/Projects/discovery_demo/Release_Notes.html b/example/stm32f4/Projects/discovery_demo/Release_Notes.html deleted file mode 100644 index 304ad5d9f..000000000 --- a/example/stm32f4/Projects/discovery_demo/Release_Notes.html +++ /dev/null @@ -1,151 +0,0 @@ - - - - - - - - - - - - - - - - Release Notes for STM32F4-Discovery Board Demonstration firmware - - - - - - - - - - -
-


-

-
- - - - - - -
- - - - - - - - - -
-

Back to Release page

-
-

Release -Notes for STM32F4-Discovery Board Demonstration firmware

-

Copyright -2011 STMicroelectronics

-

-
-

 

- - - - - - -
-

Contents

-
    -
  1. STM32F4-Discovery Board Demonstration firmware update History
  2. -
  3. License
  4. -
- - -

STM32F4-Discovery Board Demonstration firmware update History

For more information on the STM32F4-Discovery board visit www.st.com/stm32f4-discovery.

V1.0.0 / 19-September-2011

-

Main -Changes

- -
  • First official version of the STM32F4-Discovery Board Demonstration firmware

License

-

The -enclosed firmware and all the related documentation are not covered by -a License Agreement, if you need such License you can contact your -local STMicroelectronics office.

- - 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. - -
-
-

For -complete documentation on STMicroelectronics Microcontrollers visit www.st.com

-
-

-
-
-

 

-
- - \ No newline at end of file diff --git a/example/stm32f4/Projects/discovery_demo/main.c b/example/stm32f4/Projects/discovery_demo/main.c deleted file mode 100644 index 761e761a3..000000000 --- a/example/stm32f4/Projects/discovery_demo/main.c +++ /dev/null @@ -1,508 +0,0 @@ -/** - ****************************************************************************** - * @file main.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief Main program body - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "usbd_hid_core.h" -#include "usbd_usr.h" -#include "usbd_desc.h" - -//Library config for this project!!!!!!!!!!! -#include "stm32f4xx_conf.h" - -/** @addtogroup STM32F4-Discovery_Demo - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -#define TESTRESULT_ADDRESS 0x080FFFFC -#define ALLTEST_PASS 0x00000000 -#define ALLTEST_FAIL 0x55555555 - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment = 4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN USB_OTG_CORE_HANDLE USB_OTG_dev __ALIGN_END; - -uint16_t PrescalerValue = 0; - -__IO uint32_t TimingDelay; -__IO uint8_t DemoEnterCondition = 0x00; -__IO uint8_t UserButtonPressed = 0x00; -LIS302DL_InitTypeDef LIS302DL_InitStruct; -LIS302DL_FilterConfigTypeDef LIS302DL_FilterStruct; -__IO int8_t X_Offset, Y_Offset, Z_Offset = 0x00; -uint8_t Buffer[6]; - -/* Private function prototypes -----------------------------------------------*/ -static uint32_t Demo_USBConfig(void); -static void TIM4_Config(void); -static void Demo_Exec(void); - -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief Main program. - * @param None - * @retval None - */ -int main(void) -{ - RCC_ClocksTypeDef RCC_Clocks; - - /* Initialize LEDs and User_Button on STM32F4-Discovery --------------------*/ - STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI); - - STM_EVAL_LEDInit(LED4); - STM_EVAL_LEDInit(LED3); - STM_EVAL_LEDInit(LED5); - STM_EVAL_LEDInit(LED6); - - /* SysTick end of count event each 10ms */ - RCC_GetClocksFreq(&RCC_Clocks); - SysTick_Config(RCC_Clocks.HCLK_Frequency / 100); - - if (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET) - { - /* Turn on LEDs available on STM32F4-Discovery ---------------------------*/ - STM_EVAL_LEDOn(LED4); - STM_EVAL_LEDOn(LED3); - STM_EVAL_LEDOn(LED5); - STM_EVAL_LEDOn(LED6); - - if ((*(__IO uint32_t*) TESTRESULT_ADDRESS) == ALLTEST_PASS) - { - TimingDelay = 300; - /* Waiting User Button is pressed or Test Program condition verified */ - while ((STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)&&(TimingDelay != 0x00)) - {} - } - else - { - /* Waiting User Button is Released or TimeOut*/ - TimingDelay = 300; - while ((STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)&&(TimingDelay != 0x00)) - {} - if (STM_EVAL_PBGetState(BUTTON_USER) == Bit_RESET) - { - TimingDelay = 0x00; - } - } - if (TimingDelay == 0x00) - { - /* Turn off LEDs available on STM32F4-Discovery ------------------------*/ - STM_EVAL_LEDOff(LED4); - STM_EVAL_LEDOff(LED3); - STM_EVAL_LEDOff(LED5); - STM_EVAL_LEDOff(LED6); - - /* Waiting User Button is released */ - while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET) - {} - - /* Unlocks the FLASH control register access */ - FLASH_Unlock(); - - /* Move discovery kit to detect negative and positive acceleration values - on X, Y and Z axis */ - Accelerometer_MEMS_Test(); - - /* USB Hardware connection */ - USB_Test(); - - /* Audio Hardware connection */ - Audio_Test(); - - /* Microphone MEMS Hardware connection */ - Microphone_MEMS_Test(); - - /* Write PASS code at last word in the flash memory */ - FLASH_ProgramWord(TESTRESULT_ADDRESS, ALLTEST_PASS); - - while(1) - { - /* Toggle Green LED: signaling the End of the Test program */ - STM_EVAL_LEDToggle(LED4); - Delay(10); - } - } - else - { - Demo_Exec(); - } - } - else - { - Demo_Exec(); - } -} - -/** - * @brief Execute the demo application. - * @param None - * @retval None - */ -static void Demo_Exec(void) -{ - RCC_ClocksTypeDef RCC_Clocks; - uint8_t togglecounter = 0x00; - - while(1) - { - DemoEnterCondition = 0x00; - - /* Reset UserButton_Pressed variable */ - UserButtonPressed = 0x00; - - /* Initialize LEDs to be managed by GPIO */ - STM_EVAL_LEDInit(LED4); - STM_EVAL_LEDInit(LED3); - STM_EVAL_LEDInit(LED5); - STM_EVAL_LEDInit(LED6); - - /* SysTick end of count event each 10ms */ - RCC_GetClocksFreq(&RCC_Clocks); - SysTick_Config(RCC_Clocks.HCLK_Frequency / 100); - - /* Turn OFF all LEDs */ - STM_EVAL_LEDOff(LED4); - STM_EVAL_LEDOff(LED3); - STM_EVAL_LEDOff(LED5); - STM_EVAL_LEDOff(LED6); - - /* Waiting User Button is pressed */ - while (UserButtonPressed == 0x00) - { - /* Toggle LED4 */ - STM_EVAL_LEDToggle(LED4); - Delay(10); - /* Toggle LED4 */ - STM_EVAL_LEDToggle(LED3); - Delay(10); - /* Toggle LED4 */ - STM_EVAL_LEDToggle(LED5); - Delay(10); - /* Toggle LED4 */ - STM_EVAL_LEDToggle(LED6); - Delay(10); - togglecounter ++; - if (togglecounter == 0x10) - { - togglecounter = 0x00; - while (togglecounter < 0x10) - { - STM_EVAL_LEDToggle(LED4); - STM_EVAL_LEDToggle(LED3); - STM_EVAL_LEDToggle(LED5); - STM_EVAL_LEDToggle(LED6); - Delay(10); - togglecounter ++; - } - togglecounter = 0x00; - } - } - - /* Waiting User Button is Released */ - while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET) - {} - UserButtonPressed = 0x00; - - /* TIM4 channels configuration */ - TIM4_Config(); - - /* Disable all Timer4 channels */ - TIM_CCxCmd(TIM4, TIM_Channel_1, DISABLE); - TIM_CCxCmd(TIM4, TIM_Channel_2, DISABLE); - TIM_CCxCmd(TIM4, TIM_Channel_3, DISABLE); - TIM_CCxCmd(TIM4, TIM_Channel_4, DISABLE); - - /* MEMS configuration */ - LIS302DL_InitStruct.Power_Mode = LIS302DL_LOWPOWERMODE_ACTIVE; - LIS302DL_InitStruct.Output_DataRate = LIS302DL_DATARATE_100; - LIS302DL_InitStruct.Axes_Enable = LIS302DL_XYZ_ENABLE; - LIS302DL_InitStruct.Full_Scale = LIS302DL_FULLSCALE_2_3; - LIS302DL_InitStruct.Self_Test = LIS302DL_SELFTEST_NORMAL; - LIS302DL_Init(&LIS302DL_InitStruct); - - /* Required delay for the MEMS Accelerometre: Turn-on time = 3/Output data Rate - = 3/100 = 30ms */ - Delay(30); - - DemoEnterCondition = 0x01; - /* MEMS High Pass Filter configuration */ - LIS302DL_FilterStruct.HighPassFilter_Data_Selection = LIS302DL_FILTEREDDATASELECTION_OUTPUTREGISTER; - LIS302DL_FilterStruct.HighPassFilter_CutOff_Frequency = LIS302DL_HIGHPASSFILTER_LEVEL_1; - LIS302DL_FilterStruct.HighPassFilter_Interrupt = LIS302DL_HIGHPASSFILTERINTERRUPT_1_2; - LIS302DL_FilterConfig(&LIS302DL_FilterStruct); - - LIS302DL_Read(Buffer, LIS302DL_OUT_X_ADDR, 6); - X_Offset = Buffer[0]; - Y_Offset = Buffer[2]; - Z_Offset = Buffer[4]; - - /* USB configuration */ - Demo_USBConfig(); - - /* Waiting User Button is pressed */ - while (UserButtonPressed == 0x00) - {} - - /* Waiting User Button is Released */ - while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET) - {} - - /* Disable SPI1 used to drive the MEMS accelerometre */ - SPI_Cmd(LIS302DL_SPI, DISABLE); - - /* Disconnect the USB device */ - DCD_DevDisconnect(&USB_OTG_dev); - USB_OTG_StopDevice(&USB_OTG_dev); - } -} - -/** - * @brief Initializes the USB for the demonstration application. - * @param None - * @retval None - */ -static uint32_t Demo_USBConfig(void) -{ - USBD_Init(&USB_OTG_dev, - USB_OTG_FS_CORE_ID, - &USR_desc, - &USBD_HID_cb, - &USR_cb); - - return 0; -} - -/** - * @brief Configures the TIM Peripheral. - * @param None - * @retval None - */ -static void TIM4_Config(void) -{ - GPIO_InitTypeDef GPIO_InitStructure; - TIM_OCInitTypeDef TIM_OCInitStructure; - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - - /* --------------------------- System Clocks Configuration -----------------*/ - /* TIM4 clock enable */ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); - - /* GPIOD clock enable */ - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); - - /*-------------------------- GPIO Configuration ----------------------------*/ - /* GPIOD Configuration: Pins 12, 13, 14 and 15 in output push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_Init(GPIOD, &GPIO_InitStructure); - - /* Connect TIM4 pins to AF2 */ - GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4); - GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4); - GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4); - GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4); - - /* ----------------------------------------------------------------------- - TIM4 Configuration: Output Compare Timing Mode: - - In this example TIM4 input clock (TIM4CLK) is set to 2 * APB1 clock (PCLK1), - since APB1 prescaler is different from 1 (APB1 Prescaler = 4, see system_stm32f4xx.c file). - TIM4CLK = 2 * PCLK1 - PCLK1 = HCLK / 4 - => TIM4CLK = 2*(HCLK / 4) = HCLK/2 = SystemCoreClock/2 - - To get TIM4 counter clock at 2 KHz, the prescaler is computed as follows: - Prescaler = (TIM4CLK / TIM1 counter clock) - 1 - Prescaler = (168 MHz/(2 * 2 KHz)) - 1 = 41999 - - To get TIM4 output clock at 1 Hz, the period (ARR)) is computed as follows: - ARR = (TIM4 counter clock / TIM4 output clock) - 1 - = 1999 - - TIM4 Channel1 duty cycle = (TIM4_CCR1/ TIM4_ARR)* 100 = 50% - TIM4 Channel2 duty cycle = (TIM4_CCR2/ TIM4_ARR)* 100 = 50% - TIM4 Channel3 duty cycle = (TIM4_CCR3/ TIM4_ARR)* 100 = 50% - TIM4 Channel4 duty cycle = (TIM4_CCR4/ TIM4_ARR)* 100 = 50% - - ==> TIM4_CCRx = TIM4_ARR/2 = 1000 (where x = 1, 2, 3 and 4). - - Note: - SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. - Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() - function to update SystemCoreClock variable value. Otherwise, any configuration - based on this variable will be incorrect. - ----------------------------------------------------------------------- */ - - - /* Compute the prescaler value */ - PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 2000) - 1; - - /* Time base configuration */ - TIM_TimeBaseStructure.TIM_Period = TIM_ARR; - TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; - TIM_TimeBaseStructure.TIM_ClockDivision = 0; - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); - - /* Enable TIM4 Preload register on ARR */ - TIM_ARRPreloadConfig(TIM4, ENABLE); - - /* TIM PWM1 Mode configuration: Channel */ - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; - TIM_OCInitStructure.TIM_Pulse = TIM_CCR; - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; - - /* Output Compare PWM1 Mode configuration: Channel1 */ - TIM_OC1Init(TIM4, &TIM_OCInitStructure); - TIM_CCxCmd(TIM4, TIM_Channel_1, DISABLE); - - TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); - - /* Output Compare PWM1 Mode configuration: Channel2 */ - TIM_OC2Init(TIM4, &TIM_OCInitStructure); - TIM_CCxCmd(TIM4, TIM_Channel_2, DISABLE); - - TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); - - /* Output Compare PWM1 Mode configuration: Channel3 */ - TIM_OC3Init(TIM4, &TIM_OCInitStructure); - TIM_CCxCmd(TIM4, TIM_Channel_3, DISABLE); - - TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); - - /* Output Compare PWM1 Mode configuration: Channel4 */ - TIM_OC4Init(TIM4, &TIM_OCInitStructure); - TIM_CCxCmd(TIM4, TIM_Channel_4, DISABLE); - - TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); - - /* TIM4 enable counter */ - TIM_Cmd(TIM4, ENABLE); -} - -/** - * @brief Inserts a delay time. - * @param nTime: specifies the delay time length, in 10 ms. - * @retval None - */ -void Delay(__IO uint32_t nTime) -{ - TimingDelay = nTime; - - while(TimingDelay != 0); -} - -/** - * @brief Decrements the TimingDelay variable. - * @param None - * @retval None - */ -void TimingDelay_Decrement(void) -{ - if (TimingDelay != 0x00) - { - TimingDelay--; - } -} - -/** - * @brief This function handles the test program fail. - * @param None - * @retval None - */ -void Fail_Handler(void) -{ - /* Erase last sector */ - FLASH_EraseSector(FLASH_Sector_11, VoltageRange_3); - /* Write FAIL code at last word in the flash memory */ - FLASH_ProgramWord(TESTRESULT_ADDRESS, ALLTEST_FAIL); - - while(1) - { - /* Toggle Red LED */ - STM_EVAL_LEDToggle(LED5); - Delay(5); - } -} - -/** - * @brief MEMS accelerometre management of the timeout situation. - * @param None. - * @retval None. - */ -uint32_t LIS302DL_TIMEOUT_UserCallback(void) -{ - /* MEMS Accelerometer Timeout error occured during Test program execution */ - if (DemoEnterCondition == 0x00) - { - /* Timeout error occured for SPI TXE/RXNE flags waiting loops.*/ - Fail_Handler(); - } - /* MEMS Accelerometer Timeout error occured during Demo execution */ - else - { - while (1) - { - } - } - return 0; -} - -#ifdef USE_FULL_ASSERT - -/** - * @brief Reports the name of the source file and the source line number - * where the assert_param error has occurred. - * @param file: pointer to the source file name - * @param line: assert_param error line source number - * @retval None - */ -void assert_failed(uint8_t* file, uint32_t line) -{ - /* User can add his own implementation to report the file name and line number, - ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ - - /* Infinite loop */ - while (1) - { - } -} -#endif - -/** - * @} - */ - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/discovery_demo/main.h b/example/stm32f4/Projects/discovery_demo/main.h deleted file mode 100644 index cc19bb4d0..000000000 --- a/example/stm32f4/Projects/discovery_demo/main.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - ****************************************************************************** - * @file main.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief Header for main.c module - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4_DISCOVERY_DEMO_H -#define __STM32F4_DISCOVERY_DEMO_H - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4_discovery.h" -#include "stm32f4_discovery_audio_codec.h" -#include "stm32f4_discovery_lis302dl.h" -#include "selftest.h" -#include - - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* TIM2 Autoreload and Capture Compare register values */ -#define TIM_ARR (uint16_t)1999 -#define TIM_CCR (uint16_t)1000 - -/* MEMS Microphone SPI Interface */ -#define SPI_SCK_PIN GPIO_Pin_10 -#define SPI_SCK_GPIO_PORT GPIOB -#define SPI_SCK_GPIO_CLK RCC_AHB1Periph_GPIOB -#define SPI_SCK_SOURCE GPIO_PinSource10 -#define SPI_SCK_AF GPIO_AF_SPI2 - -#define SPI_MOSI_PIN GPIO_Pin_3 -#define SPI_MOSI_GPIO_PORT GPIOC -#define SPI_MOSI_GPIO_CLK RCC_AHB1Periph_GPIOC -#define SPI_MOSI_SOURCE GPIO_PinSource3 -#define SPI_MOSI_AF GPIO_AF_SPI2 - -/* Exported macro ------------------------------------------------------------*/ -#define ABS(x) (x < 0) ? (-x) : x -#define MAX(a,b) (a < b) ? (b) : a -/* Exported functions ------------------------------------------------------- */ -void TimingDelay_Decrement(void); -void Delay(__IO uint32_t nTime); -void Fail_Handler(void); -#endif /* __STM32F4_DISCOVERY_DEMO_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/discovery_demo/selftest.c b/example/stm32f4/Projects/discovery_demo/selftest.c deleted file mode 100644 index 7183ffa2c..000000000 --- a/example/stm32f4/Projects/discovery_demo/selftest.c +++ /dev/null @@ -1,808 +0,0 @@ -/** - ****************************************************************************** - * @file selftest.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file provides the hardware tests - ****************************************************************************** - * @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 2011 STMicroelectronics

- */ - -/* Includes ------------------------------------------------------------------*/ -#include "selftest.h" - -//Library config for this project!!!!!!!!!!! -#include "stm32f4xx_conf.h" - - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define MEMS_PASSCONDITION 15 -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Init Structure definition */ -RCC_ClocksTypeDef RCC_Clocks; -ADC_InitTypeDef ADC_InitStructure; -ADC_CommonInitTypeDef ADC_CommonInitStructure; - -__IO uint16_t ConvData1, ConvData2; -__IO uint16_t counter0 = 0, counter1 = 0, Idx = 0; -uint8_t ADC_Channel[2] = {ADC_Channel_2, ADC_Channel_3}; -uint8_t DACTest = 0; -uint8_t GPIO_Pin [2] = {GPIO_Pin_2, GPIO_Pin_3}; - -uint16_t count = 0, count1 = 24, Left_Right = 0; -const int16_t sinebuf[48] = {0, 4276, 8480, 12539, 16383, 19947, 23169, 25995, - 28377, 30272, 31650, 32486, 32767, 32486, 31650, 30272, - 28377, 25995, 23169, 19947, 16383, 12539, 8480, 4276, - 0, -4276, -8480, -12539, -16383, -19947, -23169, -25995, - -28377, -30272, -31650, -32486, -32767, -32486, -31650, -30272, - -28377, -25995, -23169, -19947, -16383, -12539, -8480, -4276 - }; -extern __IO uint32_t TimingDelay; - -extern LIS302DL_InitTypeDef LIS302DL_InitStruct; -extern LIS302DL_FilterConfigTypeDef LIS302DL_FilterStruct; - -extern __IO int8_t X_Offset, Y_Offset, Z_Offset; -extern uint8_t Buffer[6]; -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ -/** - * @brief Test MEMS Hardware. - * The main objectif of this test is to check the hardware connection of the - * MEMS peripheral. - * @param None - * @retval None - */ -void Accelerometer_MEMS_Test(void) -{ - uint8_t temp, memsteststatus = 0x00; - uint8_t xdata, ydata = 0; - - /* MEMS configuration ------------------------------------------------------*/ - /* Set configuration of LIS302DL*/ - LIS302DL_InitStruct.Power_Mode = LIS302DL_LOWPOWERMODE_ACTIVE; - LIS302DL_InitStruct.Output_DataRate = LIS302DL_DATARATE_100; - LIS302DL_InitStruct.Axes_Enable = LIS302DL_X_ENABLE | LIS302DL_Y_ENABLE; - LIS302DL_InitStruct.Full_Scale = LIS302DL_FULLSCALE_2_3; - LIS302DL_InitStruct.Self_Test = LIS302DL_SELFTEST_NORMAL; - LIS302DL_Init(&LIS302DL_InitStruct); - - /* Set configuration of Internal High Pass Filter of LIS302DL*/ - LIS302DL_FilterStruct.HighPassFilter_Data_Selection = LIS302DL_FILTEREDDATASELECTION_OUTPUTREGISTER; - LIS302DL_FilterStruct.HighPassFilter_CutOff_Frequency = LIS302DL_HIGHPASSFILTER_LEVEL_1; - LIS302DL_FilterStruct.HighPassFilter_Interrupt = LIS302DL_HIGHPASSFILTERINTERRUPT_1_2; - LIS302DL_FilterConfig(&LIS302DL_FilterStruct); - - /* Required delay for the MEMS Accelerometre: Turn-on time = 3/Output data Rate - = 3/100 = 30ms */ - Delay(30); - - /* Read WHO_AM_I register */ - LIS302DL_Read(&temp, LIS302DL_WHO_AM_I_ADDR, 1); - - /* Check device identification register, this register should contains - the device identifier that for LIS302DL is set to 0x3B */ - if (temp != 0x3B) - { - Fail_Handler(); - } - - TimingDelay = 500; - /* Wait until detecting all MEMS direction or timeout */ - while((memsteststatus == 0x00)&&(TimingDelay != 0x00)) - { - LIS302DL_Read(Buffer, LIS302DL_OUT_X_ADDR, 4); - xdata = ABS((int8_t)(Buffer[0])); - ydata = ABS((int8_t)(Buffer[2])); - /* Check test PASS condition */ - if ((xdata > MEMS_PASSCONDITION) || (ydata > MEMS_PASSCONDITION)) - { - /* MEMS Test PASS */ - memsteststatus = 0x01; - } - } - - /* MEMS test status: PASS */ - if(memsteststatus != 0x00) - { - /* Turn Green LED ON: signaling MEMS Test PASS */ - STM_EVAL_LEDOn(LED4); - - /* Waiting User Button is pressed */ - while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_RESET) - {} - - /* Waiting User Button is Released */ - while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET) - {} - - /* Turn Green LED OFF: signaling the end of MEMS Test and switching to - the next Sub Test */ - STM_EVAL_LEDOff(LED4); - } - /* MEMS test status: Timeout occurs */ - else - { - Fail_Handler(); - } -} - -/** - * @brief Test USB Hardware. - * The main objectif of this test is to check the hardware connection of the - * Audio and USB peripheral. - * @param None - * @retval None - */ -void USB_Test(void) -{ - GPIO_InitTypeDef GPIO_InitStructure; - - /******************************** USB Test **********************************/ - - /*----------------- Part1: without cables connected ------------------------*/ - - /* GPIOA, GPIOC and GPIOD clock enable */ - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | \ - RCC_AHB1Periph_GPIOD, ENABLE); - - /* GPIOD Configuration: Pins 5 in output push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOD, &GPIO_InitStructure); - - /* Turn LED8 ON using PD5 */ - GPIO_ResetBits(GPIOD, GPIO_Pin_5); - - /* GPIOC Configuration: Pin 0 in output push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOC, &GPIO_InitStructure); - - /* GPIOA Configuration: Pin 9 in input pull-up */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* Turn LED7 ON using PC0 (5v) */ - GPIO_ResetBits(GPIOC, GPIO_Pin_0); - - /* Waiting delay 10ms */ - Delay(1); - - if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9) == Bit_RESET) - { - Fail_Handler(); - } - - /* GPIOA Configuration: Pins 10 in output push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* Waiting delay 10ms */ - Delay(1); - - /* Check the ID level without cable connected */ - if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10) == Bit_RESET) - { - Fail_Handler(); - } - - /* Turn LED7 OFF using PC0 */ - GPIO_SetBits(GPIOC, GPIO_Pin_0); - - /* GPIOA Configuration: Pins 11, 12 in input pull-up */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* GPIOA Configuration: Pin 9 in output push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - GPIO_ResetBits(GPIOA, GPIO_Pin_9); - - /* Waiting delay 10ms */ - Delay(1); - - /* Check PA11 and PA12 level without cable connected */ - if ((GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11) == Bit_RESET) || \ - (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12) == Bit_RESET)) - { - Fail_Handler(); - } - - /* GPIOA Configuration: Pins 12 in input pull-up */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* GPIOA Configuration: Pin 11 in output push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - GPIO_ResetBits(GPIOA, GPIO_Pin_11); - - /* Waiting delay 10ms */ - Delay(1); - - /* Check PA12 level without cable connected */ - if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12) == Bit_RESET) - { - Fail_Handler(); - } - - /* GPIOA Configuration: Pins 11 in input pull-up */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* GPIOA Configuration: Pin 12 in output push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - GPIO_ResetBits(GPIOA, GPIO_Pin_12); - - /* Waiting delay 10ms */ - Delay(1); - - /* Check PA12 level without cable connected */ - if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11) == Bit_RESET) - { - Fail_Handler(); - } - - /* GPIOA Configuration: Pins 9 in output push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* Turn LED7 ON using PA9 */ - GPIO_SetBits(GPIOA, GPIO_Pin_9); - - /* Turn Green LED ON: signaling Audio USB Test part1 PASS */ - STM_EVAL_LEDOn(LED4); - - /* Waiting User Button is pressed */ - while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_RESET) - {} - - /* Waiting User Button is Released */ - while (STM_EVAL_PBGetState(BUTTON_USER) != Bit_RESET) - {} - - /* Turn Green LED OFF: signaling the end of Audio USB Test part1 and switching to - the part2 */ - STM_EVAL_LEDOff(LED4); - - /* Turn LED7 OFF using PA9 */ - GPIO_ResetBits(GPIOA, GPIO_Pin_9); - - /* Turn LED8 OFF using PD5 */ - GPIO_SetBits(GPIOD, GPIO_Pin_5); - - /*--------------- Part2: with Audio USB cables connected ------------------*/ - - /*********************************** USB Test *******************************/ - /* Check the ID level with cable connected */ - if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10) != Bit_RESET) - { - Fail_Handler(); - } - - /* GPIOA Configuration: Pins 11, 12 in input pull-down */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* GPIOA Configuration: Pin 9 in output push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - GPIO_SetBits(GPIOA, GPIO_Pin_9); - - /* Waiting delay 10ms */ - Delay(1); - - /* Check PA11 and PA12 level with cable connected */ - if ((GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11) == Bit_RESET) || \ - (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12) == Bit_RESET)) - { - Fail_Handler(); - } - - /* GPIOA Configuration: Pins 9, 12 in input pull-down */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_12; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* GPIOA Configuration: Pin 11 in output push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - GPIO_SetBits(GPIOA, GPIO_Pin_11); - - /* Waiting delay 10ms */ - Delay(1); - - /* Check PA9 and PA12 level with cable connected */ - if ((GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9) == Bit_RESET)|| \ - (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12) == Bit_RESET)) - { - Fail_Handler(); - } - - /* GPIOA Configuration: Pins 9, 11 in input pull-down */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_11; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* GPIOA Configuration: Pin 12 in output push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - GPIO_SetBits(GPIOA, GPIO_Pin_12); - - /* Waiting delay 10ms */ - Delay(1); - - /* Check PA9 and PA12 level with cable connected */ - if ((GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9) == Bit_RESET)|| \ - (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11) == Bit_RESET)) - { - Fail_Handler(); - } - - /* GPIOA Configuration: Pins 11, 12 in input pull-down */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* GPIOA Configuration: Pin 9 in output push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* Turn LED7 OFF using PA9 */ - GPIO_ResetBits(GPIOA, GPIO_Pin_9); -} - -/** - * @brief Test Audio Hardware. - * The main objectif of this test is to check the hardware connection of the - * Audio peripheral. - * @param None - * @retval None - */ -void Audio_Test(void) -{ - GPIO_InitTypeDef GPIO_InitStructure; - uint8_t audioteststatus = 0x00; - - RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); - RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); - - /* Set the current audio interface: I2S or DAC */ - EVAL_AUDIO_SetAudioInterface(AUDIO_INTERFACE_I2S); - - /* Initialize the Audio codec and all related peripherals (I2S, I2C, IOs...) */ - if (EVAL_AUDIO_Init(OUTPUT_DEVICE_HEADPHONE, 87, I2S_AudioFreq_48k) !=0) - { - Fail_Handler(); - } - /* I2S code to be exectued under the I2S interrupt */ - DACTest = 0; - - /* ADC Common Init */ - ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; - ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8; - ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; - ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles; - ADC_CommonInit(&ADC_CommonInitStructure); - - /* ADC peripherals Init */ - ADC_StructInit(&ADC_InitStructure); - ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b; - ADC_InitStructure.ADC_ScanConvMode = DISABLE; - ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; - ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; - ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; - ADC_InitStructure.ADC_NbrOfConversion = 1; - ADC_Init(ADC1, &ADC_InitStructure); - - ADC_Init(ADC2, &ADC_InitStructure); - - /* Configure ADC Channels pin as analog input */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 ; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - counter1 = 0; - counter0 = 0; - audioteststatus = 0; - /* ADCperipheral[PerIdx] Regular Channel Config */ - ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_56Cycles); - /* ADCperipheral[PerIdx] Regular Channel Config */ - ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 1, ADC_SampleTime_56Cycles); - /* Enable ADC1 */ - ADC_Cmd(ADC1, ENABLE); - ADC_Cmd(ADC2, ENABLE); - - TimingDelay = 500; - /* Wait until detecting 500 data*/ - while((audioteststatus == 0)&&(TimingDelay != 0)) - { - ADC_SoftwareStartConv(ADC1); - while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); - ConvData1 = ADC_GetConversionValue(ADC1); - - ADC_SoftwareStartConv(ADC2); - while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET); - ConvData2 = ADC_GetConversionValue(ADC2); - - /* 1.75V equals to 150 */ - if ((ConvData1 > 150) && (ConvData2 < 10) && (counter1 != 500)) - { - counter1 ++; - } - if ((ConvData1 < 10) && (ConvData2 > 150) && (counter0 != 500)) - { - counter0 ++; - } - if((counter1 == 500) && (counter0 == 500)) - { - audioteststatus = 1; - } - } - - /* Disable ADC Peripherals */ - ADC_Cmd(ADC1, DISABLE); - ADC_Cmd(ADC2, DISABLE); - - /* Audio test status: FAIL */ - if(audioteststatus == 0) - { - Fail_Handler(); - } - - EVAL_AUDIO_DeInit(); - EVAL_AUDIO_SetAudioInterface(AUDIO_INTERFACE_DAC); - /* Initialize the Audio codec and all related peripherals (I2S, I2C, IOs...) */ - if (EVAL_AUDIO_Init(OUTPUT_DEVICE_HEADPHONE, 100, I2S_AudioFreq_48k) !=0) - { - Fail_Handler(); - } - - /* DAC code to be exectued under the I2S interrupt */ - DACTest = 1; - counter1 = 0; - counter0 = 0; - audioteststatus = 0; - - /* Enable ADC1 */ - ADC_Cmd(ADC1, ENABLE); - ADC_Cmd(ADC2, ENABLE); - - TimingDelay = 500; - /* Wait until detecting 50 data*/ - while((audioteststatus == 0)&&(TimingDelay != 0)) - { - - ADC_SoftwareStartConv(ADC1); - while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); - - ConvData1 = ADC_GetConversionValue(ADC1); - - ADC_SoftwareStartConv(ADC2); - while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET); - - ConvData2 = ADC_GetConversionValue(ADC2); - - /* 2.0V equals to 170 */ - if ((ConvData1 > 170) && (ConvData2 > 170) &&(counter1 != 500)) - { - counter1 ++; - } - if ((ConvData1 < 10) && (ConvData2 < 10) && (counter0 != 500)) - { - counter0 ++; - } - if((counter1 == 500) && (counter0 == 500)) - { - audioteststatus = 1; - } - } - - /* Audio test status: FAIL */ - if(audioteststatus == 0x00) - { - Fail_Handler(); - } - - /* Turn Green LED ON: signaling Audio USB Test part2 PASS */ - STM_EVAL_LEDOn(LED4); - - /* Waiting User_Button pressed */ - while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_RESET) - {} - - /* Turn Green LED OFF: signaling the end of Audio USB Test part2 */ - STM_EVAL_LEDOff(LED4); -} - -/** - * @brief Test Micophone MEMS Hardware. - * The main objectif of this test is to check the hardware connection of the - * Microphone MEMS peripheral. - * @param None - * @retval None - */ -void Microphone_MEMS_Test(void) -{ - uint16_t data = 0x00; - uint8_t index = 0x00; - I2S_InitTypeDef I2S_InitStructure; - GPIO_InitTypeDef GPIO_InitStructure; - - /* Enable the SPI clock */ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); - - /* Enable GPIO clocks */ - RCC_AHB1PeriphClockCmd(SPI_SCK_GPIO_CLK | SPI_MOSI_GPIO_CLK, ENABLE); - - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; - - /* SPI SCK pin configuration */ - GPIO_InitStructure.GPIO_Pin = SPI_SCK_PIN; - GPIO_Init(SPI_SCK_GPIO_PORT, &GPIO_InitStructure); - - /* Connect SPI pins to AF5 */ - GPIO_PinAFConfig(SPI_SCK_GPIO_PORT, SPI_SCK_SOURCE, SPI_SCK_AF); - - /* SPI MOSI pin configuration */ - GPIO_InitStructure.GPIO_Pin = SPI_MOSI_PIN; - GPIO_Init(SPI_MOSI_GPIO_PORT, &GPIO_InitStructure); - - GPIO_PinAFConfig(SPI_MOSI_GPIO_PORT, SPI_MOSI_SOURCE, SPI_MOSI_AF); - - /* I2S configuration -------------------------------------------------------*/ - SPI_I2S_DeInit(SPI2); - I2S_InitStructure.I2S_AudioFreq = 64000; - I2S_InitStructure.I2S_Standard = I2S_Standard_MSB; - I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b; - I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low; - I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx; - I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable; - /* Initialize the I2S peripheral with the structure above */ - I2S_Init(SPI2, &I2S_InitStructure); - - /* Enable the I2S peripheral */ - I2S_Cmd(SPI2, ENABLE); - - /* Waiting until MEMS microphone ready : Wake-up Time */ - Delay(10); - - TimingDelay = 500; - /* Wait until detect the click on the MEMS microphone or TimeOut delay*/ - while((index < 30) && (TimingDelay != 0x00)) - { - /* Waiting RXNE Flag or TimeOut delay */ - while((SPI_I2S_GetFlagStatus(SPI2, SPI_FLAG_RXNE) == RESET)&& (TimingDelay != 0x00)) - {} - data = SPI_I2S_ReceiveData(SPI2); - if (data == 0xFFFF) - { - index++; - } - } - - /* MEMS microphone test status: Timeout occurs */ - if(index != 30) - { - Fail_Handler(); - } -} - -/*-------------------------------- - Callbacks implementation: - the callbacks prototypes are defined in the stm324xg_eval_audio_codec.h file - and their implementation should be done in the user code if they are needed. - Below some examples of callback implementations. - --------------------------------------------------------*/ -/** - * @brief Calculates the remaining file size and new position of the pointer. - * @param None - * @retval None - */ -void EVAL_AUDIO_TransferComplete_CallBack(uint32_t pBuffer, uint32_t Size) -{ - /* Calculate the remaining audio data in the file and the new size - for the DMA transfer. If the Audio files size is less than the DMA max - data transfer size, so there is no calculation to be done, just restart - from the beginning of the file ... */ - /* Check if the end of file has been reached */ - -} - -/** - * @brief Manages the DMA Half Transfer complete interrupt. - * @param None - * @retval None - */ -void EVAL_AUDIO_HalfTransfer_CallBack(uint32_t pBuffer, uint32_t Size) -{ -#ifdef AUDIO_MAL_MODE_CIRCULAR - - /* Display message on the LCD screen */ - LCD_DisplayStringLine(Line8, " 1/2 Buffer Reached "); - -#endif /* AUDIO_MAL_MODE_CIRCULAR */ - - /* Generally this interrupt routine is used to load the buffer when - a streaming scheme is used: When first Half buffer is already transferred load - the new data to the first half of buffer while DMA is transferring data from - the second half. And when Transfer complete occurs, load the second half of - the buffer while the DMA is transferring from the first half ... */ - /* - ........... - */ -} -/** - * @brief Get next data sample callback - * @param None - * @retval Next data sample to be sent - */ -uint16_t EVAL_AUDIO_GetSampleCallBack(void) -{ - uint16_t data = 0; - - if (DACTest == 0) - { - if (Left_Right==0) - { - /* Get the next sample to be sent */ - data = sinebuf[count++]; - - if (count == 48) - { - count = 0x00; - } - Left_Right = 1; - } - else - { - /* Get the next sample to be sent */ - data = sinebuf[count1++]; - - if (count1 == 48) - { - count1 = 0x00; - } - Left_Right = 0; - } - } - else - { - /* Get the next sample to be sent */ - data = 32768 + sinebuf[count++]; - - if (count == 48) - { - count = 0x00; - } - } - return data; -} - - -/** - * @brief Manages the DMA FIFO error interrupt. - * @param None - * @retval None - */ -void EVAL_AUDIO_Error_CallBack(void* pData) -{ - /* Stop the program with an infinite loop */ - while (1) - {} - - /* could also generate a system reset to recover from the error */ - /* .... */ -} - -#ifndef USE_DEFAULT_TIMEOUT_CALLBACK -/** - * @brief Basic management of the timeout situation. - * @param None. - * @retval None. - */ -uint32_t Codec_TIMEOUT_UserCallback(void) -{ - /* Block communication and all processes */ - while (1) - { - } -} -#endif /* USE_DEFAULT_TIMEOUT_CALLBACK */ -/*----------------------------------------------------------------------------*/ - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/discovery_demo/selftest.h b/example/stm32f4/Projects/discovery_demo/selftest.h deleted file mode 100644 index feef3de5c..000000000 --- a/example/stm32f4/Projects/discovery_demo/selftest.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - ****************************************************************************** - * @file selftest.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief Header for selftest.c module - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __SELFTEST_H -#define __SELFTEST_H - -/* Includes ------------------------------------------------------------------*/ -#include -#include "main.h" -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -void Audio_Test(void); -void Accelerometer_MEMS_Test(void); -void USB_Test(void); -void Microphone_MEMS_Test(void); - -#endif /* __SELFTEST_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/discovery_demo/startup_stm32f4xx.s b/example/stm32f4/Projects/discovery_demo/startup_stm32f4xx.s deleted file mode 100644 index ce5360f3c..000000000 --- a/example/stm32f4/Projects/discovery_demo/startup_stm32f4xx.s +++ /dev/null @@ -1,509 +0,0 @@ -/** - ****************************************************************************** - * @file startup_stm32f4xx.s - * @author MCD Application Team - * @version V1.0.0 - * @date 30-September-2011 - * @brief STM32F4xx 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 - * - Configure the clock system and the external SRAM mounted on - * STM324xG-EVAL board to be used as data memory (optional, - * to be enabled by user) - * - Branches to main in the C library (which eventually - * calls main()). - * After Reset the Cortex-M4 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 2011 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 -/* stack used for SystemInit_ExtMemCtl; always internal RAM used */ - -/** - * @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.*/ - 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 - - /* External Interrupts */ - .word WWDG_IRQHandler /* Window WatchDog */ - .word PVD_IRQHandler /* PVD through EXTI Line detection */ - .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */ - .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */ - .word FLASH_IRQHandler /* FLASH */ - .word RCC_IRQHandler /* RCC */ - .word EXTI0_IRQHandler /* EXTI Line0 */ - .word EXTI1_IRQHandler /* EXTI Line1 */ - .word EXTI2_IRQHandler /* EXTI Line2 */ - .word EXTI3_IRQHandler /* EXTI Line3 */ - .word EXTI4_IRQHandler /* EXTI Line4 */ - .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */ - .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */ - .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */ - .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */ - .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */ - .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */ - .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */ - .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */ - .word CAN1_TX_IRQHandler /* CAN1 TX */ - .word CAN1_RX0_IRQHandler /* CAN1 RX0 */ - .word CAN1_RX1_IRQHandler /* CAN1 RX1 */ - .word CAN1_SCE_IRQHandler /* CAN1 SCE */ - .word EXTI9_5_IRQHandler /* External Line[9:5]s */ - .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */ - .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */ - .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */ - .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ - .word TIM2_IRQHandler /* TIM2 */ - .word TIM3_IRQHandler /* TIM3 */ - .word TIM4_IRQHandler /* TIM4 */ - .word I2C1_EV_IRQHandler /* I2C1 Event */ - .word I2C1_ER_IRQHandler /* I2C1 Error */ - .word I2C2_EV_IRQHandler /* I2C2 Event */ - .word I2C2_ER_IRQHandler /* I2C2 Error */ - .word SPI1_IRQHandler /* SPI1 */ - .word SPI2_IRQHandler /* SPI2 */ - .word USART1_IRQHandler /* USART1 */ - .word USART2_IRQHandler /* USART2 */ - .word USART3_IRQHandler /* USART3 */ - .word EXTI15_10_IRQHandler /* External Line[15:10]s */ - .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */ - .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */ - .word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */ - .word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */ - .word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */ - .word TIM8_CC_IRQHandler /* TIM8 Capture Compare */ - .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */ - .word FSMC_IRQHandler /* FSMC */ - .word SDIO_IRQHandler /* SDIO */ - .word TIM5_IRQHandler /* TIM5 */ - .word SPI3_IRQHandler /* SPI3 */ - .word UART4_IRQHandler /* UART4 */ - .word UART5_IRQHandler /* UART5 */ - .word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */ - .word TIM7_IRQHandler /* TIM7 */ - .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */ - .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */ - .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */ - .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */ - .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */ - .word ETH_IRQHandler /* Ethernet */ - .word ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */ - .word CAN2_TX_IRQHandler /* CAN2 TX */ - .word CAN2_RX0_IRQHandler /* CAN2 RX0 */ - .word CAN2_RX1_IRQHandler /* CAN2 RX1 */ - .word CAN2_SCE_IRQHandler /* CAN2 SCE */ - .word OTG_FS_IRQHandler /* USB OTG FS */ - .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */ - .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */ - .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */ - .word USART6_IRQHandler /* USART6 */ - .word I2C3_EV_IRQHandler /* I2C3 event */ - .word I2C3_ER_IRQHandler /* I2C3 error */ - .word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */ - .word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */ - .word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */ - .word OTG_HS_IRQHandler /* USB OTG HS */ - .word DCMI_IRQHandler /* DCMI */ - .word CRYP_IRQHandler /* CRYP crypto */ - .word HASH_RNG_IRQHandler /* Hash and Rng */ - .word FPU_IRQHandler /* FPU */ - -/******************************************************************************* -* -* 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 TAMP_STAMP_IRQHandler - .thumb_set TAMP_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_Stream0_IRQHandler - .thumb_set DMA1_Stream0_IRQHandler,Default_Handler - - .weak DMA1_Stream1_IRQHandler - .thumb_set DMA1_Stream1_IRQHandler,Default_Handler - - .weak DMA1_Stream2_IRQHandler - .thumb_set DMA1_Stream2_IRQHandler,Default_Handler - - .weak DMA1_Stream3_IRQHandler - .thumb_set DMA1_Stream3_IRQHandler,Default_Handler - - .weak DMA1_Stream4_IRQHandler - .thumb_set DMA1_Stream4_IRQHandler,Default_Handler - - .weak DMA1_Stream5_IRQHandler - .thumb_set DMA1_Stream5_IRQHandler,Default_Handler - - .weak DMA1_Stream6_IRQHandler - .thumb_set DMA1_Stream6_IRQHandler,Default_Handler - - .weak ADC_IRQHandler - .thumb_set ADC_IRQHandler,Default_Handler - - .weak CAN1_TX_IRQHandler - .thumb_set CAN1_TX_IRQHandler,Default_Handler - - .weak CAN1_RX0_IRQHandler - .thumb_set CAN1_RX0_IRQHandler,Default_Handler - - .weak CAN1_RX1_IRQHandler - .thumb_set CAN1_RX1_IRQHandler,Default_Handler - - .weak CAN1_SCE_IRQHandler - .thumb_set CAN1_SCE_IRQHandler,Default_Handler - - .weak EXTI9_5_IRQHandler - .thumb_set EXTI9_5_IRQHandler,Default_Handler - - .weak TIM1_BRK_TIM9_IRQHandler - .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler - - .weak TIM1_UP_TIM10_IRQHandler - .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler - - .weak TIM1_TRG_COM_TIM11_IRQHandler - .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler - - .weak TIM1_CC_IRQHandler - .thumb_set TIM1_CC_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 OTG_FS_WKUP_IRQHandler - .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler - - .weak TIM8_BRK_TIM12_IRQHandler - .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler - - .weak TIM8_UP_TIM13_IRQHandler - .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler - - .weak TIM8_TRG_COM_TIM14_IRQHandler - .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler - - .weak TIM8_CC_IRQHandler - .thumb_set TIM8_CC_IRQHandler,Default_Handler - - .weak DMA1_Stream7_IRQHandler - .thumb_set DMA1_Stream7_IRQHandler,Default_Handler - - .weak FSMC_IRQHandler - .thumb_set FSMC_IRQHandler,Default_Handler - - .weak SDIO_IRQHandler - .thumb_set SDIO_IRQHandler,Default_Handler - - .weak TIM5_IRQHandler - .thumb_set TIM5_IRQHandler,Default_Handler - - .weak SPI3_IRQHandler - .thumb_set SPI3_IRQHandler,Default_Handler - - .weak UART4_IRQHandler - .thumb_set UART4_IRQHandler,Default_Handler - - .weak UART5_IRQHandler - .thumb_set UART5_IRQHandler,Default_Handler - - .weak TIM6_DAC_IRQHandler - .thumb_set TIM6_DAC_IRQHandler,Default_Handler - - .weak TIM7_IRQHandler - .thumb_set TIM7_IRQHandler,Default_Handler - - .weak DMA2_Stream0_IRQHandler - .thumb_set DMA2_Stream0_IRQHandler,Default_Handler - - .weak DMA2_Stream1_IRQHandler - .thumb_set DMA2_Stream1_IRQHandler,Default_Handler - - .weak DMA2_Stream2_IRQHandler - .thumb_set DMA2_Stream2_IRQHandler,Default_Handler - - .weak DMA2_Stream3_IRQHandler - .thumb_set DMA2_Stream3_IRQHandler,Default_Handler - - .weak DMA2_Stream4_IRQHandler - .thumb_set DMA2_Stream4_IRQHandler,Default_Handler - - .weak ETH_IRQHandler - .thumb_set ETH_IRQHandler,Default_Handler - - .weak ETH_WKUP_IRQHandler - .thumb_set ETH_WKUP_IRQHandler,Default_Handler - - .weak CAN2_TX_IRQHandler - .thumb_set CAN2_TX_IRQHandler,Default_Handler - - .weak CAN2_RX0_IRQHandler - .thumb_set CAN2_RX0_IRQHandler,Default_Handler - - .weak CAN2_RX1_IRQHandler - .thumb_set CAN2_RX1_IRQHandler,Default_Handler - - .weak CAN2_SCE_IRQHandler - .thumb_set CAN2_SCE_IRQHandler,Default_Handler - - .weak OTG_FS_IRQHandler - .thumb_set OTG_FS_IRQHandler,Default_Handler - - .weak DMA2_Stream5_IRQHandler - .thumb_set DMA2_Stream5_IRQHandler,Default_Handler - - .weak DMA2_Stream6_IRQHandler - .thumb_set DMA2_Stream6_IRQHandler,Default_Handler - - .weak DMA2_Stream7_IRQHandler - .thumb_set DMA2_Stream7_IRQHandler,Default_Handler - - .weak USART6_IRQHandler - .thumb_set USART6_IRQHandler,Default_Handler - - .weak I2C3_EV_IRQHandler - .thumb_set I2C3_EV_IRQHandler,Default_Handler - - .weak I2C3_ER_IRQHandler - .thumb_set I2C3_ER_IRQHandler,Default_Handler - - .weak OTG_HS_EP1_OUT_IRQHandler - .thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler - - .weak OTG_HS_EP1_IN_IRQHandler - .thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler - - .weak OTG_HS_WKUP_IRQHandler - .thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler - - .weak OTG_HS_IRQHandler - .thumb_set OTG_HS_IRQHandler,Default_Handler - - .weak DCMI_IRQHandler - .thumb_set DCMI_IRQHandler,Default_Handler - - .weak CRYP_IRQHandler - .thumb_set CRYP_IRQHandler,Default_Handler - - .weak HASH_RNG_IRQHandler - .thumb_set HASH_RNG_IRQHandler,Default_Handler - - .weak FPU_IRQHandler - .thumb_set FPU_IRQHandler,Default_Handler - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/discovery_demo/stm32_flash.ld b/example/stm32f4/Projects/discovery_demo/stm32_flash.ld deleted file mode 100644 index ee842a775..000000000 --- a/example/stm32f4/Projects/discovery_demo/stm32_flash.ld +++ /dev/null @@ -1,170 +0,0 @@ -/* -***************************************************************************** -** -** File : stm32_flash.ld -** -** Abstract : Linker script for STM32F207IG Device with -** 1024KByte FLASH, 112KByte 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 = 0x2001c000; /* end of 112K 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 = 0x400; /* required amount of stack */ - -/* Specify the memory areas */ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 112K - MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K -} - -/* 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) } -} diff --git a/example/stm32f4/Projects/discovery_demo/stm32f4xx_conf.h b/example/stm32f4/Projects/discovery_demo/stm32f4xx_conf.h deleted file mode 100644 index 74447a8f8..000000000 --- a/example/stm32f4/Projects/discovery_demo/stm32f4xx_conf.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_conf.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief Library configuration file. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_CONF_H -#define __STM32F4xx_CONF_H - -#if defined (HSE_VALUE) -/* Redefine the HSE value; it's equal to 8 MHz on the STM32F4-DISCOVERY Kit */ - #undef HSE_VALUE - #define HSE_VALUE ((uint32_t)8000000) -#endif /* HSE_VALUE */ - -/* Includes ------------------------------------------------------------------*/ -/* Uncomment the line below to enable peripheral header file inclusion */ -#include "stm32f4xx_adc.h" -#include "stm32f4xx_can.h" -#include "stm32f4xx_crc.h" -#include "stm32f4xx_cryp.h" -#include "stm32f4xx_dac.h" -#include "stm32f4xx_dbgmcu.h" -#include "stm32f4xx_dcmi.h" -#include "stm32f4xx_dma.h" -#include "stm32f4xx_exti.h" -#include "stm32f4xx_flash.h" -#include "stm32f4xx_fsmc.h" -#include "stm32f4xx_hash.h" -#include "stm32f4xx_gpio.h" -#include "stm32f4xx_i2c.h" -#include "stm32f4xx_iwdg.h" -#include "stm32f4xx_pwr.h" -#include "stm32f4xx_rcc.h" -#include "stm32f4xx_rng.h" -#include "stm32f4xx_rtc.h" -#include "stm32f4xx_sdio.h" -#include "stm32f4xx_spi.h" -#include "stm32f4xx_syscfg.h" -#include "stm32f4xx_tim.h" -#include "stm32f4xx_usart.h" -#include "stm32f4xx_wwdg.h" -#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/* If an external clock source is used, then the value of the following define - should be set to the value of the external clock source, else, if no external - clock is used, keep this define commented */ -/*#define I2S_EXTERNAL_CLOCK_VAL 12288000 */ /* Value of the external clock in Hz */ - - -/* Uncomment the line below to expanse the "assert_param" macro in the - Standard Peripheral Library drivers code */ -/* #define USE_FULL_ASSERT 1 */ - -/* Exported macro ------------------------------------------------------------*/ -#ifdef USE_FULL_ASSERT - -/** - * @brief The assert_param macro is used for function's parameters check. - * @param expr: If expr is false, it calls assert_failed function - * which reports the name of the source file and the source - * line number of the call that failed. - * If expr is true, it returns no value. - * @retval None - */ - #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) -/* Exported functions ------------------------------------------------------- */ - void assert_failed(uint8_t* file, uint32_t line); -#else - #define assert_param(expr) ((void)0) -#endif /* USE_FULL_ASSERT */ - -#endif /* __STM32F4xx_CONF_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/discovery_demo/stm32f4xx_it.c b/example/stm32f4/Projects/discovery_demo/stm32f4xx_it.c deleted file mode 100644 index cee2c2492..000000000 --- a/example/stm32f4/Projects/discovery_demo/stm32f4xx_it.c +++ /dev/null @@ -1,320 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_it.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief Main Interrupt Service Routines. - * This file provides all exceptions handler and peripherals interrupt - * service routine. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_it.h" -#include "main.h" -#include "usb_core.h" -#include "usbd_core.h" -#include "stm32f4_discovery.h" -#include "usbd_hid_core.h" - -//Library config for this project!!!!!!!!!!! -#include "stm32f4xx_conf.h" - - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define CURSOR_STEP 7 - -extern uint8_t Buffer[6]; -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -extern __IO uint8_t DemoEnterCondition; -uint8_t Counter = 0x00; -extern int8_t X_Offset; -extern int8_t Y_Offset; -extern __IO uint8_t UserButtonPressed; -__IO uint8_t TempAcceleration = 0; -/* Private function prototypes -----------------------------------------------*/ -extern USB_OTG_CORE_HANDLE USB_OTG_dev; -static uint8_t *USBD_HID_GetPos (void); -extern uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev); - -/******************************************************************************/ -/* Cortex-M3 Processor Exceptions Handlers */ -/******************************************************************************/ - -/** - * @brief This function handles NMI exception. - * @param None - * @retval None - */ -void NMI_Handler(void) -{ -} - -/** - * @brief This function handles Hard Fault exception. - * @param None - * @retval None - */ -void HardFault_Handler(void) -{ - /* Go to infinite loop when Hard Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Memory Manage exception. - * @param None - * @retval None - */ -void MemManage_Handler(void) -{ - /* Go to infinite loop when Memory Manage exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Bus Fault exception. - * @param None - * @retval None - */ -void BusFault_Handler(void) -{ - /* Go to infinite loop when Bus Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Usage Fault exception. - * @param None - * @retval None - */ -void UsageFault_Handler(void) -{ - /* Go to infinite loop when Usage Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles SVCall exception. - * @param None - * @retval None - */ -void SVC_Handler(void) -{ -} - -/** - * @brief This function handles Debug Monitor exception. - * @param None - * @retval None - */ -void DebugMon_Handler(void) -{ -} - -/** - * @brief This function handles PendSVC exception. - * @param None - * @retval None - */ -void PendSV_Handler(void) -{ -} - -/** - * @brief This function handles SysTick Handler. - * @param None - * @retval None - */ -void SysTick_Handler(void) -{ - uint8_t *buf; - uint8_t temp1, temp2 = 0x00; - - if (DemoEnterCondition == 0x00) - { - TimingDelay_Decrement(); - } - else - { - buf = USBD_HID_GetPos(); - if((buf[1] != 0) ||(buf[2] != 0)) - { - USBD_HID_SendReport (&USB_OTG_dev, - buf, - 4); - } - Counter ++; - if (Counter == 10) - { - Buffer[0] = 0; - Buffer[2] = 0; - /* Disable All TIM4 Capture Compare Channels */ - TIM_CCxCmd(TIM4, TIM_Channel_1, DISABLE); - TIM_CCxCmd(TIM4, TIM_Channel_2, DISABLE); - TIM_CCxCmd(TIM4, TIM_Channel_3, DISABLE); - TIM_CCxCmd(TIM4, TIM_Channel_4, DISABLE); - - LIS302DL_Read(Buffer, LIS302DL_OUT_X_ADDR, 6); - /* Remove the offsets values from data */ - Buffer[0] -= X_Offset; - Buffer[2] -= Y_Offset; - /* Update autoreload and capture compare registers value*/ - temp1 = ABS((int8_t)(Buffer[0])); - temp2 = ABS((int8_t)(Buffer[2])); - TempAcceleration = MAX(temp1, temp2); - - if(TempAcceleration != 0) - { - if ((int8_t)Buffer[0] < -2) - { - /* Enable TIM4 Capture Compare Channel 4 */ - TIM_CCxCmd(TIM4, TIM_Channel_4, ENABLE); - /* Sets the TIM4 Capture Compare4 Register value */ - TIM_SetCompare4(TIM4, TIM_CCR/TempAcceleration); - } - if ((int8_t)Buffer[0] > 2) - { - /* Enable TIM4 Capture Compare Channel 2 */ - TIM_CCxCmd(TIM4, TIM_Channel_2, ENABLE); - /* Sets the TIM4 Capture Compare2 Register value */ - TIM_SetCompare2(TIM4, TIM_CCR/TempAcceleration); - } - if ((int8_t)Buffer[2] > 2) - { - /* Enable TIM4 Capture Compare Channel 1 */ - TIM_CCxCmd(TIM4, TIM_Channel_1, ENABLE); - /* Sets the TIM4 Capture Compare1 Register value */ - TIM_SetCompare1(TIM4, TIM_CCR/TempAcceleration); - } - if ((int8_t)Buffer[2] < -2) - { - /* Enable TIM4 Capture Compare Channel 3 */ - TIM_CCxCmd(TIM4, TIM_Channel_3, ENABLE); - /* Sets the TIM4 Capture Compare3 Register value */ - TIM_SetCompare3(TIM4, TIM_CCR/TempAcceleration); - } - /* Time base configuration */ - TIM_SetAutoreload(TIM4, TIM_ARR/TempAcceleration); - } - Counter = 0x00; - } - } - -} - -/******************************************************************************/ -/* STM32Fxxx Peripherals Interrupt Handlers */ -/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ -/* available peripheral interrupt handler's name please refer to the startup */ -/* file (startup_stm32fxxx.s). */ -/******************************************************************************/ - -/** - * @brief This function handles PPP interrupt request. - * @param None - * @retval None - */ -/*void PPP_IRQHandler(void) -{ -}*/ - -/** - * @brief This function handles EXTI0_IRQ Handler. - * @param None - * @retval None - */ -void EXTI0_IRQHandler(void) -{ - UserButtonPressed = 0x01; - - /* Clear the EXTI line pending bit */ - EXTI_ClearITPendingBit(USER_BUTTON_EXTI_LINE); -} - -/** - * @brief This function handles EXTI15_10_IRQ Handler. - * @param None - * @retval None - */ -void OTG_FS_WKUP_IRQHandler(void) -{ - if(USB_OTG_dev.cfg.low_power) - { - /* Reset SLEEPDEEP and SLEEPONEXIT bits */ - SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); - - /* After wake-up from sleep mode, reconfigure the system clock */ - SystemInit(); - USB_OTG_UngateClock(&USB_OTG_dev); - } - EXTI_ClearITPendingBit(EXTI_Line18); -} - -/** - * @brief This function handles OTG_HS Handler. - * @param None - * @retval None - */ -void OTG_FS_IRQHandler(void) -{ - USBD_OTG_ISR_Handler (&USB_OTG_dev); -} - -/** -* @brief USBD_HID_GetPos -* @param None -* @retval Pointer to report -*/ -static uint8_t *USBD_HID_GetPos (void) -{ - static uint8_t HID_Buffer[4] = {0}; - - HID_Buffer[1] = 0; - HID_Buffer[2] = 0; - /* LEFT Direction */ - if(((int8_t)Buffer[2]) < -2) - { - HID_Buffer[1] += CURSOR_STEP; - } - /* RIGHT Direction */ - if(((int8_t)Buffer[2]) > 2) - { - HID_Buffer[1] -= CURSOR_STEP; - } - /* UP Direction */ - if(((int8_t)Buffer[0]) < -2) - { - HID_Buffer[2] += CURSOR_STEP; - } - /* DOWN Direction */ - if(((int8_t)Buffer[0]) > 2) - { - HID_Buffer[2] -= CURSOR_STEP; - } - - return HID_Buffer; -} -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/discovery_demo/stm32f4xx_it.h b/example/stm32f4/Projects/discovery_demo/stm32f4xx_it.h deleted file mode 100644 index 4ae766cf4..000000000 --- a/example/stm32f4/Projects/discovery_demo/stm32f4xx_it.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_it.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file contains the headers of the interrupt handlers. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_IT_H -#define __STM32F4xx_IT_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "usb_conf.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -void NMI_Handler(void); -void HardFault_Handler(void); -void MemManage_Handler(void); -void BusFault_Handler(void); -void UsageFault_Handler(void); -void SVC_Handler(void); -void DebugMon_Handler(void); -void PendSV_Handler(void); -void SysTick_Handler(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_IT_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/discovery_demo/system_stm32f4xx.c b/example/stm32f4/Projects/discovery_demo/system_stm32f4xx.c deleted file mode 100644 index fbb195cc4..000000000 --- a/example/stm32f4/Projects/discovery_demo/system_stm32f4xx.c +++ /dev/null @@ -1,566 +0,0 @@ -/** - ****************************************************************************** - * @file system_stm32f4xx.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. - * This file contains the system clock configuration for STM32F4xx devices, - * and is generated by the clock configuration tool - * stm32f4xx_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_stm32f4xx.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 HSI (16 MHz) is used as system clock source. - * Then SystemInit() function is called, in "startup_stm32f4xx.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 HSI 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 8 MHz, refer to "HSE_VALUE" define - * in "stm32f4xx.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: - *============================================================================= - *============================================================================= - * Supported STM32F4xx device revision | Rev A - *----------------------------------------------------------------------------- - * System Clock source | PLL (HSE) - *----------------------------------------------------------------------------- - * SYSCLK(Hz) | 168000000 - *----------------------------------------------------------------------------- - * HCLK(Hz) | 168000000 - *----------------------------------------------------------------------------- - * AHB Prescaler | 1 - *----------------------------------------------------------------------------- - * APB1 Prescaler | 4 - *----------------------------------------------------------------------------- - * APB2 Prescaler | 2 - *----------------------------------------------------------------------------- - * HSE Frequency(Hz) | 8000000 - *----------------------------------------------------------------------------- - * PLL_M | 8 - *----------------------------------------------------------------------------- - * PLL_N | 336 - *----------------------------------------------------------------------------- - * PLL_P | 2 - *----------------------------------------------------------------------------- - * PLL_Q | 7 - *----------------------------------------------------------------------------- - * PLLI2S_N | 192 - *----------------------------------------------------------------------------- - * PLLI2S_R | 5 - *----------------------------------------------------------------------------- - * I2S input clock(Hz) | 38400000 - *----------------------------------------------------------------------------- - * VDD(V) | 3.3 - *----------------------------------------------------------------------------- - * High Performance mode | Enabled - *----------------------------------------------------------------------------- - * Flash Latency(WS) | 5 - *----------------------------------------------------------------------------- - * Prefetch Buffer | OFF - *----------------------------------------------------------------------------- - * Instruction cache | ON - *----------------------------------------------------------------------------- - * Data cache | ON - *----------------------------------------------------------------------------- - * Require 48MHz for USB OTG FS, | Enabled - * SDIO and RNG clock | - *----------------------------------------------------------------------------- - *============================================================================= - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32f4xx_system - * @{ - */ - -/** @addtogroup STM32F4xx_System_Private_Includes - * @{ - */ - -#include "stm32f4xx.h" - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_Defines - * @{ - */ - -/*!< Uncomment the following line if you need to use external SRAM mounted - on STM324xG_EVAL board as data memory */ -/* #define DATA_IN_ExtSRAM */ - -/*!< Uncomment the following line if you need to relocate your vector Table in - Internal SRAM. */ -/* #define VECT_TAB_SRAM */ -#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. - This value must be a multiple of 0x200. */ - - -/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ -#define PLL_M 8 -#define PLL_N 336 - -/* SYSCLK = PLL_VCO / PLL_P */ -#define PLL_P 2 - -/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ -#define PLL_Q 7 - -/* PLLI2S_VCO = (HSE_VALUE Or HSI_VALUE / PLL_M) * PLLI2S_N - I2SCLK = PLLI2S_VCO / PLLI2S_R */ -#define PLLI2S_N 192 -#define PLLI2S_R 5 - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_Variables - * @{ - */ - - uint32_t SystemCoreClock = 168000000; - - __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes - * @{ - */ - -static void SetSysClock(void); -#ifdef DATA_IN_ExtSRAM - static void SystemInit_ExtMemCtl(void); -#endif /* DATA_IN_ExtSRAM */ - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_Functions - * @{ - */ - -/** - * @brief Setup the microcontroller system - * Initialize the Embedded Flash Interface, the PLL and update the - * SystemFrequency variable. - * @param None - * @retval None - */ -void SystemInit(void) -{ - /* Reset the RCC clock configuration to the default reset state ------------*/ - /* Set HSION bit */ - RCC->CR |= (uint32_t)0x00000001; - - /* Reset CFGR register */ - RCC->CFGR = 0x00000000; - - /* Reset HSEON, CSSON and PLLON bits */ - RCC->CR &= (uint32_t)0xFEF6FFFF; - - /* Reset PLLCFGR register */ - RCC->PLLCFGR = 0x24003010; - - /* Reset HSEBYP bit */ - RCC->CR &= (uint32_t)0xFFFBFFFF; - - /* Disable all interrupts */ - RCC->CIR = 0x00000000; - -#ifdef DATA_IN_ExtSRAM - SystemInit_ExtMemCtl(); -#endif /* DATA_IN_ExtSRAM */ - - /* Configure the System clock source, PLL Multiplier and Divider factors, - AHB/APBx prescalers and Flash settings ----------------------------------*/ - SetSysClock(); - - /* Configure the Vector Table location add offset address ------------------*/ -#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 variable according to Clock Register Values. - * The SystemCoreClock variable contains the core clock (HCLK), it can - * be used by the user application to setup the SysTick timer or configure - * other parameters. - * - * @note Each time the core clock (HCLK) changes, this function must be called - * to update SystemCoreClock variable value. Otherwise, any configuration - * based on this variable will be incorrect. - * - * @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 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 stm32f4xx.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 stm32f4xx.h file (default value - * 25 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, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; - - /* Get SYSCLK source -------------------------------------------------------*/ - tmp = RCC->CFGR & RCC_CFGR_SWS; - - switch (tmp) - { - case 0x00: /* HSI used as system clock source */ - SystemCoreClock = HSI_VALUE; - break; - case 0x04: /* HSE used as system clock source */ - SystemCoreClock = HSE_VALUE; - break; - case 0x08: /* PLL used as system clock source */ - - /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N - SYSCLK = PLL_VCO / PLL_P - */ - pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; - pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; - - if (pllsource != 0) - { - /* HSE used as PLL clock source */ - pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); - } - else - { - /* HSI used as PLL clock source */ - pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); - } - - pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; - SystemCoreClock = pllvco/pllp; - break; - default: - SystemCoreClock = HSI_VALUE; - break; - } - /* Compute HCLK frequency --------------------------------------------------*/ - /* Get HCLK prescaler */ - tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; - /* HCLK frequency */ - SystemCoreClock >>= tmp; -} - -/** - * @brief Configures the System clock source, PLL Multiplier and Divider factors, - * 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) -{ -/******************************************************************************/ -/* PLL (clocked by HSE) used as System clock source */ -/******************************************************************************/ - __IO uint32_t StartUpCounter = 0, HSEStatus = 0; - - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { - /* Enable high performance mode, System frequency up to 168 MHz */ - RCC->APB1ENR |= RCC_APB1ENR_PWREN; - PWR->CR |= PWR_CR_PMODE; - - /* HCLK = SYSCLK / 1*/ - RCC->CFGR |= RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK / 2*/ - RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; - - /* PCLK1 = HCLK / 4*/ - RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; - - /* Configure the main PLL */ - RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); - - /* Enable the main PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till the main PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; - - /* Select the main PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= RCC_CFGR_SW_PLL; - - /* Wait till the main PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); - { - } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } - -/******************************************************************************/ -/* I2S clock configuration */ -/******************************************************************************/ - /* PLLI2S clock used as I2S clock source */ - RCC->CFGR &= ~RCC_CFGR_I2SSRC; - - /* Configure PLLI2S */ - RCC->PLLI2SCFGR = (PLLI2S_N << 6) | (PLLI2S_R << 28); - - /* Enable PLLI2S */ - RCC->CR |= ((uint32_t)RCC_CR_PLLI2SON); - - /* Wait till PLLI2S is ready */ - while((RCC->CR & RCC_CR_PLLI2SRDY) == 0) - { - } -} - -/** - * @brief Setup the external memory controller. Called in startup_stm32f4xx.s - * before jump to __main - * @param None - * @retval None - */ -#ifdef DATA_IN_ExtSRAM -/** - * @brief Setup the external memory controller. - * Called in startup_stm32f4xx.s before jump to main. - * This function configures the external SRAM mounted on STM324xG_EVAL board - * This SRAM will be used as program data memory (including heap and stack). - * @param None - * @retval None - */ -void SystemInit_ExtMemCtl(void) -{ -/*-- GPIOs Configuration -----------------------------------------------------*/ -/* - +-------------------+--------------------+------------------+------------------+ - + SRAM pins assignment + - +-------------------+--------------------+------------------+------------------+ - | PD0 <-> FSMC_D2 | PE0 <-> FSMC_NBL0 | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 | - | PD1 <-> FSMC_D3 | PE1 <-> FSMC_NBL1 | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 | - | PD4 <-> FSMC_NOE | PE3 <-> FSMC_A19 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 | - | PD5 <-> FSMC_NWE | PE4 <-> FSMC_A20 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 | - | PD8 <-> FSMC_D13 | PE7 <-> FSMC_D4 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 | - | PD9 <-> FSMC_D14 | PE8 <-> FSMC_D5 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 | - | PD10 <-> FSMC_D15 | PE9 <-> FSMC_D6 | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 | - | PD11 <-> FSMC_A16 | PE10 <-> FSMC_D7 | PF13 <-> FSMC_A7 |------------------+ - | PD12 <-> FSMC_A17 | PE11 <-> FSMC_D8 | PF14 <-> FSMC_A8 | - | PD13 <-> FSMC_A18 | PE12 <-> FSMC_D9 | PF15 <-> FSMC_A9 | - | PD14 <-> FSMC_D0 | PE13 <-> FSMC_D10 |------------------+ - | PD15 <-> FSMC_D1 | PE14 <-> FSMC_D11 | - | | PE15 <-> FSMC_D12 | - +-------------------+--------------------+ -*/ - /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ - RCC->AHB1ENR = 0x00000078; - - /* Connect PDx pins to FSMC Alternate function */ - GPIOD->AFR[0] = 0x00cc00cc; - GPIOD->AFR[1] = 0xcc0ccccc; - /* Configure PDx pins in Alternate function mode */ - GPIOD->MODER = 0xaaaa0a0a; - /* Configure PDx pins speed to 100 MHz */ - GPIOD->OSPEEDR = 0xffff0f0f; - /* Configure PDx pins Output type to push-pull */ - GPIOD->OTYPER = 0x00000000; - /* No pull-up, pull-down for PDx pins */ - GPIOD->PUPDR = 0x00000000; - - /* Connect PEx pins to FSMC Alternate function */ - GPIOE->AFR[0] = 0xc00cc0cc; - GPIOE->AFR[1] = 0xcccccccc; - /* Configure PEx pins in Alternate function mode */ - GPIOE->MODER = 0xaaaa828a; - /* Configure PEx pins speed to 100 MHz */ - GPIOE->OSPEEDR = 0xffffc3cf; - /* Configure PEx pins Output type to push-pull */ - GPIOE->OTYPER = 0x00000000; - /* No pull-up, pull-down for PEx pins */ - GPIOE->PUPDR = 0x00000000; - - /* Connect PFx pins to FSMC Alternate function */ - GPIOF->AFR[0] = 0x00cccccc; - GPIOF->AFR[1] = 0xcccc0000; - /* Configure PFx pins in Alternate function mode */ - GPIOF->MODER = 0xaa000aaa; - /* Configure PFx pins speed to 100 MHz */ - GPIOF->OSPEEDR = 0xff000fff; - /* Configure PFx pins Output type to push-pull */ - GPIOF->OTYPER = 0x00000000; - /* No pull-up, pull-down for PFx pins */ - GPIOF->PUPDR = 0x00000000; - - /* Connect PGx pins to FSMC Alternate function */ - GPIOG->AFR[0] = 0x00cccccc; - GPIOG->AFR[1] = 0x000000c0; - /* Configure PGx pins in Alternate function mode */ - GPIOG->MODER = 0x00080aaa; - /* Configure PGx pins speed to 100 MHz */ - GPIOG->OSPEEDR = 0x000c0fff; - /* Configure PGx pins Output type to push-pull */ - GPIOG->OTYPER = 0x00000000; - /* No pull-up, pull-down for PGx pins */ - GPIOG->PUPDR = 0x00000000; - -/*-- FSMC Configuration ------------------------------------------------------*/ - /* Enable the FSMC interface clock */ - RCC->AHB3ENR = 0x00000001; - - /* Configure and enable Bank1_SRAM2 */ - FSMC_Bank1->BTCR[2] = 0x00001015; - FSMC_Bank1->BTCR[3] = 0x00010603;//0x00010400; - FSMC_Bank1E->BWTR[2] = 0x0fffffff; -/* - Bank1_SRAM2 is configured as follow: - - p.FSMC_AddressSetupTime = 3;//0; - p.FSMC_AddressHoldTime = 0; - p.FSMC_DataSetupTime = 6;//4; - p.FSMC_BusTurnAroundDuration = 1; - p.FSMC_CLKDivision = 0; - p.FSMC_DataLatency = 0; - p.FSMC_AccessMode = FSMC_AccessMode_A; - - FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2; - FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; - FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM; - FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; - FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; - FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; - FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; - FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; - FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; - FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; -*/ - -} -#endif /* DATA_IN_ExtSRAM */ - - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/Projects/discovery_demo/usb_bsp.c b/example/stm32f4/Projects/discovery_demo/usb_bsp.c deleted file mode 100644 index 6861d65b4..000000000 --- a/example/stm32f4/Projects/discovery_demo/usb_bsp.c +++ /dev/null @@ -1,382 +0,0 @@ -/** - ****************************************************************************** - * @file usb_bsp.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file is responsible to offer board support package and is - * configurable by user. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_bsp.h" -#include "usbd_conf.h" -#include "stm32f4_discovery.h" - -//Library config for this project!!!!!!!!!!! -#include "stm32f4xx_conf.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY -* @{ -*/ - -/** @defgroup USB_BSP -* @brief This file is responsible to offer board support package -* @{ -*/ - -/** @defgroup USB_BSP_Private_Defines -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_BSP_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - - - - -/** @defgroup USB_BSP_Private_Macros -* @{ -*/ -/** -* @} -*/ - -/** @defgroup USBH_BSP_Private_Variables -* @{ -*/ - -/** -* @} -*/ - -/** @defgroup USBH_BSP_Private_FunctionPrototypes -* @{ -*/ -/** -* @} -*/ - -/** @defgroup USB_BSP_Private_Functions -* @{ -*/ - - -/** -* @brief USB_OTG_BSP_Init -* Initilizes BSP configurations -* @param None -* @retval None -*/ - -void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev) -{ - GPIO_InitTypeDef GPIO_InitStructure; - -#ifndef USE_ULPI_PHY -#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT - EXTI_InitTypeDef EXTI_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; -#endif -#endif - - - #ifdef USE_USB_OTG_FS - - RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA , ENABLE); - - /* Configure SOF VBUS ID DM DP Pins */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | - GPIO_Pin_9 | - GPIO_Pin_11 | - GPIO_Pin_12; - - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_OTG1_FS) ; - GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_OTG1_FS) ; - GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_OTG1_FS) ; - GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_OTG1_FS) ; - - /* this for ID line debug */ - - - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; - GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_Init(GPIOA, &GPIO_InitStructure); - GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_OTG1_FS) ; - - RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); - RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, ENABLE) ; - #else // USE_USB_OTG_HS - - #ifdef USE_ULPI_PHY // ULPI - RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | - RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOH | - RCC_AHB1Periph_GPIOI, ENABLE); - - - GPIO_PinAFConfig(GPIOA,GPIO_PinSource3, GPIO_AF_OTG2_HS) ; // D0 - GPIO_PinAFConfig(GPIOA,GPIO_PinSource5, GPIO_AF_OTG2_HS) ; // CLK - GPIO_PinAFConfig(GPIOB,GPIO_PinSource0, GPIO_AF_OTG2_HS) ; // D1 - GPIO_PinAFConfig(GPIOB,GPIO_PinSource1, GPIO_AF_OTG2_HS) ; // D2 - GPIO_PinAFConfig(GPIOB,GPIO_PinSource5, GPIO_AF_OTG2_HS) ; // D7 - GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_OTG2_HS) ; // D3 - GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_OTG2_HS) ; // D4 - GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_OTG2_HS) ; // D5 - GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_OTG2_HS) ; // D6 - GPIO_PinAFConfig(GPIOH,GPIO_PinSource4, GPIO_AF_OTG2_HS) ; // NXT - GPIO_PinAFConfig(GPIOI,GPIO_PinSource11,GPIO_AF_OTG2_HS) ; // DIR - GPIO_PinAFConfig(GPIOC,GPIO_PinSource0, GPIO_AF_OTG2_HS) ; // STP - - // CLK - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - // D0 - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 ; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - - - // D1 D2 D3 D4 D5 D6 D7 - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | - GPIO_Pin_5 | GPIO_Pin_10 | - GPIO_Pin_11| GPIO_Pin_12 | - GPIO_Pin_13 ; - - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - - // STP - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init(GPIOC, &GPIO_InitStructure); - - //NXT - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init(GPIOH, &GPIO_InitStructure); - - - //DIR - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init(GPIOI, &GPIO_InitStructure); - - - RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS | - RCC_AHB1Periph_OTG_HS_ULPI, ENABLE) ; - - #else - #ifdef USE_I2C_PHY - RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB , ENABLE); - /* Configure RESET INTN SCL SDA (Phy/I2C) Pins */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | - GPIO_Pin_1 | - GPIO_Pin_10 | - GPIO_Pin_11; - - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - GPIO_PinAFConfig(GPIOB,GPIO_PinSource0,GPIO_AF_OTG2_FS) ; - GPIO_PinAFConfig(GPIOB,GPIO_PinSource1,GPIO_AF_OTG2_FS) ; - GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_OTG2_FS) ; - GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_OTG2_FS); - RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS, ENABLE) ; - - #else - - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB , ENABLE); - - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | - GPIO_Pin_13 | - GPIO_Pin_14 | - GPIO_Pin_15; - - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - GPIO_PinAFConfig(GPIOB,GPIO_PinSource12, GPIO_AF_OTG2_FS) ; - GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_OTG2_FS) ; - GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_OTG2_FS) ; - GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_OTG2_FS) ; - RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS, ENABLE) ; - #endif - #endif // USE_ULPI_PHY - - #endif //USB_OTG_HS - - - /* enable the PWR clock */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE); - - /* Configure the Key button in EXTI mode */ - STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI); - -#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT - EXTI_ClearITPendingBit(EXTI_Line18); - - EXTI_InitStructure.EXTI_Line = EXTI_Line18; - EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; - EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; - EXTI_InitStructure.EXTI_LineCmd = ENABLE; - EXTI_Init(&EXTI_InitStructure); - - EXTI_ClearITPendingBit(EXTI_Line18); - - NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_WKUP_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - - EXTI_ClearITPendingBit(EXTI_Line18); -#endif - -#ifdef USB_OTG_HS_LOW_PWR_MGMT_SUPPORT - EXTI_ClearITPendingBit(EXTI_Line20); - - EXTI_InitStructure.EXTI_Line = EXTI_Line20; - EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; - EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; - EXTI_InitStructure.EXTI_LineCmd = ENABLE; - EXTI_Init(&EXTI_InitStructure); - - EXTI_ClearITPendingBit(EXTI_Line20); - - NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_WKUP_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - - EXTI_ClearITPendingBit(EXTI_Line20); -#endif - - EXTI_ClearITPendingBit(USER_BUTTON_EXTI_LINE); -} -/** -* @brief USB_OTG_BSP_EnableInterrupt -* Enabele USB Global interrupt -* @param None -* @retval None -*/ -void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE *pdev) -{ - NVIC_InitTypeDef NVIC_InitStructure; - - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); -#ifdef USE_USB_OTG_HS - NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_IRQn; -#else - NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn; -#endif - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); - NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_EP1_OUT_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); - NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_EP1_IN_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); -#endif -} -/** -* @brief USB_OTG_BSP_uDelay -* This function provides delay time in micro sec -* @param usec : Value of delay required in micro sec -* @retval None -*/ -void USB_OTG_BSP_uDelay (const uint32_t usec) -{ - uint32_t count = 0; - const uint32_t utime = (120 * usec / 7); - do - { - if ( ++count > utime ) - { - return ; - } - } - while (1); -} - - -/** -* @brief USB_OTG_BSP_mDelay -* This function provides delay time in milli sec -* @param msec : Value of delay required in milli sec -* @retval None -*/ -void USB_OTG_BSP_mDelay (const uint32_t msec) -{ - USB_OTG_BSP_uDelay(msec * 1000); -} -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/discovery_demo/usb_conf.h b/example/stm32f4/Projects/discovery_demo/usb_conf.h deleted file mode 100644 index eeb2f79de..000000000 --- a/example/stm32f4/Projects/discovery_demo/usb_conf.h +++ /dev/null @@ -1,252 +0,0 @@ -/** - ****************************************************************************** - * @file usb_conf.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief General low level driver configuration - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_CONF__H__ -#define __USB_CONF__H__ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_CONF - * @brief USB low level driver configuration file - * @{ - */ - -/** @defgroup USB_CONF_Exported_Defines - * @{ - */ - -/* USB Core and PHY interface configuration. - Tip: To avoid modifying these defines each time you need to change the USB - configuration, you can declare the needed define in your toolchain - compiler preprocessor. - */ -#ifndef USE_USB_OTG_FS - //#define USE_USB_OTG_FS -#endif /* USE_USB_OTG_FS */ - -#ifdef USE_USB_OTG_FS - #define USB_OTG_FS_CORE -#endif - -/******************************************************************************* -* FIFO Size Configuration in Device mode -* -* (i) Receive data FIFO size = RAM for setup packets + -* OUT endpoint control information + -* data OUT packets + miscellaneous -* Space = ONE 32-bits words -* --> RAM for setup packets = 10 spaces -* (n is the nbr of CTRL EPs the device core supports) -* --> OUT EP CTRL info = 1 space -* (one space for status information written to the FIFO along with each -* received packet) -* --> data OUT packets = (Largest Packet Size / 4) + 1 spaces -* (MINIMUM to receive packets) -* --> OR data OUT packets = at least 2*(Largest Packet Size / 4) + 1 spaces -* (if high-bandwidth EP is enabled or multiple isochronous EPs) -* --> miscellaneous = 1 space per OUT EP -* (one space for transfer complete status information also pushed to the -* FIFO with each endpoint's last packet) -* -* (ii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for -* that particular IN EP. More space allocated in the IN EP Tx FIFO results -* in a better performance on the USB and can hide latencies on the AHB. -* -* (iii) TXn min size = 16 words. (n : Transmit FIFO index) -* (iv) When a TxFIFO is not used, the Configuration should be as follows: -* case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes) -* --> Txm can use the space allocated for Txn. -* case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes) -* --> Txn should be configured with the minimum space of 16 words -* (v) The FIFO is used optimally when used TxFIFOs are allocated in the top -* of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones. -*******************************************************************************/ - - - -/****************** USB OTG FS CONFIGURATION **********************************/ -#ifdef USB_OTG_FS_CORE - #define RX_FIFO_FS_SIZE 128 - #define TX0_FIFO_FS_SIZE 64 - #define TX1_FIFO_FS_SIZE 128 - #define TX2_FIFO_FS_SIZE 0 - #define TX3_FIFO_FS_SIZE 0 - - //#define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT - //#define USB_OTG_FS_SOF_OUTPUT_ENABLED -#endif - -/****************** USB OTG MODE CONFIGURATION ********************************/ - -//#define USE_HOST_MODE -#define USE_DEVICE_MODE -//#define USE_OTG_MODE - - -#ifndef USB_OTG_FS_CORE - #ifndef USB_OTG_HS_CORE - #error "USB_OTG_HS_CORE or USB_OTG_FS_CORE should be defined" - #endif -#endif - - -#ifndef USE_DEVICE_MODE - #ifndef USE_HOST_MODE - #error "USE_DEVICE_MODE or USE_HOST_MODE should be defined" - #endif -#endif - -#ifndef USE_USB_OTG_HS - #ifndef USE_USB_OTG_FS - #error "USE_USB_OTG_HS or USE_USB_OTG_FS should be defined" - #endif -#else //USE_USB_OTG_HS - #ifndef USE_ULPI_PHY - #ifndef USE_EMBEDDED_PHY - #ifndef USE_I2C_PHY - #error "USE_ULPI_PHY or USE_EMBEDDED_PHY or USE_I2C_PHY should be defined" - #endif - #endif - #endif -#endif - -/****************** C Compilers dependant keywords ****************************/ -/* In HS mode and when the DMA is used, all variables and data structures dealing - with the DMA during the transaction process should be 4-bytes aligned */ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined (__GNUC__) /* GNU Compiler */ - #define __ALIGN_END __attribute__ ((aligned (4))) - #define __ALIGN_BEGIN - #else - #define __ALIGN_END - #if defined (__CC_ARM) /* ARM Compiler */ - #define __ALIGN_BEGIN __align(4) - #elif defined (__ICCARM__) /* IAR Compiler */ - #define __ALIGN_BEGIN - #elif defined (__TASKING__) /* TASKING Compiler */ - #define __ALIGN_BEGIN __align(4) - #endif /* __CC_ARM */ - #endif /* __GNUC__ */ -#else - #define __ALIGN_BEGIN - #define __ALIGN_END -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -/* __packed keyword used to decrease the data type alignment to 1-byte */ -#if defined (__CC_ARM) /* ARM Compiler */ - #define __packed __packed -#elif defined (__ICCARM__) /* IAR Compiler */ - #define __packed __packed -#elif defined ( __GNUC__ ) /* GNU Compiler */ - #define __packed __attribute__ ((__packed__)) -#elif defined (__TASKING__) /* TASKING Compiler */ - #define __packed __unaligned -#endif /* __CC_ARM */ - -/****************** C Compilers dependant keywords ****************************/ -/* In HS mode and when the DMA is used, all variables and data structures dealing - with the DMA during the transaction process should be 4-bytes aligned */ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined (__GNUC__) /* GNU Compiler */ - #define __ALIGN_END __attribute__ ((aligned (4))) - #define __ALIGN_BEGIN - #else - #define __ALIGN_END - #if defined (__CC_ARM) /* ARM Compiler */ - #define __ALIGN_BEGIN __align(4) - #elif defined (__ICCARM__) /* IAR Compiler */ - #define __ALIGN_BEGIN - #elif defined (__TASKING__) /* TASKING Compiler */ - #define __ALIGN_BEGIN __align(4) - #endif /* __CC_ARM */ - #endif /* __GNUC__ */ -#else - #define __ALIGN_BEGIN - #define __ALIGN_END -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -/* __packed keyword used to decrease the data type alignment to 1-byte */ -#if defined (__CC_ARM) /* ARM Compiler */ - #define __packed __packed -#elif defined (__ICCARM__) /* IAR Compiler */ - #define __packed __packed -#elif defined ( __GNUC__ ) /* GNU Compiler */ - #define __packed __attribute__ ((__packed__)) -#elif defined (__TASKING__) /* TASKING Compiler */ - #define __packed __unaligned -#endif /* __CC_ARM */ - - -/** - * @} - */ - - -/** @defgroup USB_CONF_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_CONF_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -#endif //__USB_CONF__H__ - - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/Projects/discovery_demo/usb_core.c b/example/stm32f4/Projects/discovery_demo/usb_core.c deleted file mode 100644 index 74e432ac2..000000000 --- a/example/stm32f4/Projects/discovery_demo/usb_core.c +++ /dev/null @@ -1,2187 +0,0 @@ -/** - ****************************************************************************** - * @file usb_core.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief USB-OTG Core Layer - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_core.h" -#include "usb_bsp.h" - - -/** @addtogroup USB_OTG_DRIVER -* @{ -*/ - -/** @defgroup USB_CORE -* @brief This file includes the USB-OTG Core Layer -* @{ -*/ - - -/** @defgroup USB_CORE_Private_Defines -* @{ -*/ - -/** -* @} -*/ - - -/** @defgroup USB_CORE_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - - -/** @defgroup USB_CORE_Private_Macros -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_CORE_Private_Variables -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_CORE_Private_FunctionPrototypes -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_CORE_Private_Functions -* @{ -*/ - -/** -* @brief USB_OTG_EnableCommonInt -* Initializes the commmon interrupts, used in both device and modes -* @param pdev : Selected device -* @retval None -*/ -static void USB_OTG_EnableCommonInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTMSK_TypeDef int_mask; - - int_mask.d32 = 0; - /* Clear any pending USB_OTG Interrupts */ -#ifndef USE_OTG_MODE - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GOTGINT, 0xFFFFFFFF); -#endif - /* Clear any pending interrupts */ - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF); - /* Enable the interrupts in the INTMSK */ - int_mask.b.wkupintr = 1; - int_mask.b.usbsuspend = 1; - -#ifdef USE_OTG_MODE - int_mask.b.otgintr = 1; - int_mask.b.sessreqintr = 1; - int_mask.b.conidstschng = 1; -#endif - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32); -} - -/** -* @brief USB_OTG_CoreReset : Soft reset of the core -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -static USB_OTG_STS USB_OTG_CoreReset(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - __IO USB_OTG_GRSTCTL_TypeDef greset; - uint32_t count = 0; - - greset.d32 = 0; - /* Wait for AHB master IDLE state. */ - do - { - USB_OTG_BSP_uDelay(3); - greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL); - if (++count > 200000) - { - return USB_OTG_OK; - } - } - while (greset.b.ahbidle == 0); - /* Core Soft Reset */ - count = 0; - greset.b.csftrst = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRSTCTL, greset.d32 ); - do - { - greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL); - if (++count > 200000) - { - break; - } - } - while (greset.b.csftrst == 1); - /* Wait for 3 PHY Clocks*/ - USB_OTG_BSP_uDelay(3); - return status; -} - -/** -* @brief USB_OTG_WritePacket : Writes a packet into the Tx FIFO associated -* with the EP -* @param pdev : Selected device -* @param src : source pointer -* @param ch_ep_num : end point number -* @param bytes : No. of bytes -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_WritePacket(USB_OTG_CORE_HANDLE *pdev, - uint8_t *src, - uint8_t ch_ep_num, - uint16_t len) -{ - USB_OTG_STS status = USB_OTG_OK; - if (pdev->cfg.dma_enable == 0) - { - uint32_t count32b= 0 , i= 0; - __IO uint32_t *fifo; - - count32b = (len + 3) / 4; - fifo = pdev->regs.DFIFO[ch_ep_num]; - for (i = 0; i < count32b; i++, src+=4) - { - USB_OTG_WRITE_REG32( fifo, *((__packed uint32_t *)src) ); - } - } - return status; -} - - -/** -* @brief USB_OTG_ReadPacket : Reads a packet from the Rx FIFO -* @param pdev : Selected device -* @param dest : Destination Pointer -* @param bytes : No. of bytes -* @retval None -*/ -void *USB_OTG_ReadPacket(USB_OTG_CORE_HANDLE *pdev, - uint8_t *dest, - uint16_t len) -{ - uint32_t i=0; - uint32_t count32b = (len + 3) / 4; - - __IO uint32_t *fifo = pdev->regs.DFIFO[0]; - - for ( i = 0; i < count32b; i++, dest += 4 ) - { - *(__packed uint32_t *)dest = USB_OTG_READ_REG32(fifo); - - } - return ((void *)dest); -} - -/** -* @brief USB_OTG_SelectCore -* Initialize core registers address. -* @param pdev : Selected device -* @param coreID : USB OTG Core ID -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_SelectCore(USB_OTG_CORE_HANDLE *pdev, - USB_OTG_CORE_ID_TypeDef coreID) -{ - uint32_t i , baseAddress = 0; - USB_OTG_STS status = USB_OTG_OK; - - pdev->cfg.dma_enable = 0; - - /* at startup the core is in FS mode */ - pdev->cfg.speed = USB_OTG_SPEED_FULL; - pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ; - - /* initialize device cfg following its address */ - if (coreID == USB_OTG_FS_CORE_ID) - { - baseAddress = USB_OTG_FS_BASE_ADDR; - pdev->cfg.coreID = USB_OTG_FS_CORE_ID; - pdev->cfg.host_channels = 8 ; - pdev->cfg.dev_endpoints = 4 ; - pdev->cfg.TotalFifoSize = 320; /* in 32-bits */ - pdev->cfg.phy_itface = USB_OTG_EMBEDDED_PHY; - -#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED - pdev->cfg.Sof_output = 1; -#endif - -#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT - pdev->cfg.low_power = 1; -#endif - } - else if (coreID == USB_OTG_HS_CORE_ID) - { - baseAddress = USB_OTG_HS_BASE_ADDR; - pdev->cfg.coreID = USB_OTG_HS_CORE_ID; - pdev->cfg.host_channels = 12 ; - pdev->cfg.dev_endpoints = 6 ; - pdev->cfg.TotalFifoSize = 1280;/* in 32-bits */ - -#ifdef USB_OTG_ULPI_PHY_ENABLED - pdev->cfg.phy_itface = USB_OTG_ULPI_PHY; -#else - #ifdef USB_OTG_EMBEDDED_PHY_ENABLED - pdev->cfg.phy_itface = USB_OTG_EMBEDDED_PHY; - #else - #ifdef USB_OTG_I2C_PHY_ENABLED - pdev->cfg.phy_itface = USB_OTG_I2C_PHY; - #endif - #endif -#endif - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - pdev->cfg.dma_enable = 1; -#endif - -#ifdef USB_OTG_HS_SOF_OUTPUT_ENABLED - pdev->cfg.Sof_output = 1; -#endif - -#ifdef USB_OTG_HS_LOW_PWR_MGMT_SUPPORT - pdev->cfg.low_power = 1; -#endif - - } - - pdev->regs.GREGS = (USB_OTG_GREGS *)(baseAddress + \ - USB_OTG_CORE_GLOBAL_REGS_OFFSET); - pdev->regs.DREGS = (USB_OTG_DREGS *) (baseAddress + \ - USB_OTG_DEV_GLOBAL_REG_OFFSET); - - for (i = 0; i < pdev->cfg.dev_endpoints; i++) - { - pdev->regs.INEP_REGS[i] = (USB_OTG_INEPREGS *) \ - (baseAddress + USB_OTG_DEV_IN_EP_REG_OFFSET + \ - (i * USB_OTG_EP_REG_OFFSET)); - pdev->regs.OUTEP_REGS[i] = (USB_OTG_OUTEPREGS *) \ - (baseAddress + USB_OTG_DEV_OUT_EP_REG_OFFSET + \ - (i * USB_OTG_EP_REG_OFFSET)); - } - pdev->regs.HREGS = (USB_OTG_HREGS *)(baseAddress + \ - USB_OTG_HOST_GLOBAL_REG_OFFSET); - pdev->regs.HPRT0 = (uint32_t *)(baseAddress + USB_OTG_HOST_PORT_REGS_OFFSET); - - for (i = 0; i < pdev->cfg.host_channels; i++) - { - pdev->regs.HC_REGS[i] = (USB_OTG_HC_REGS *)(baseAddress + \ - USB_OTG_HOST_CHAN_REGS_OFFSET + \ - (i * USB_OTG_CHAN_REGS_OFFSET)); - } - for (i = 0; i < pdev->cfg.host_channels; i++) - { - pdev->regs.DFIFO[i] = (uint32_t *)(baseAddress + USB_OTG_DATA_FIFO_OFFSET +\ - (i * USB_OTG_DATA_FIFO_SIZE)); - } - pdev->regs.PCGCCTL = (uint32_t *)(baseAddress + USB_OTG_PCGCCTL_OFFSET); - - return status; -} - - -/** -* @brief USB_OTG_CoreInit -* Initializes the USB_OTG controller registers and prepares the core -* device mode or host mode operation. -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_CoreInit(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GUSBCFG_TypeDef usbcfg; - USB_OTG_GCCFG_TypeDef gccfg; - USB_OTG_GI2CCTL_TypeDef i2cctl; - USB_OTG_GAHBCFG_TypeDef ahbcfg; - - usbcfg.d32 = 0; - gccfg.d32 = 0; - ahbcfg.d32 = 0; - - - - if (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY) - { - gccfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GCCFG); - gccfg.b.pwdn = 0; - - if (pdev->cfg.Sof_output) - { - gccfg.b.sofouten = 1; - } - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32); - - /* Init The ULPI Interface */ - usbcfg.d32 = 0; - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - - usbcfg.b.physel = 0; /* HS Interface */ -#ifdef USB_OTG_INTERNAL_VBUS_ENABLED - usbcfg.b.ulpi_ext_vbus_drv = 0; /* Use internal VBUS */ -#else - #ifdef USB_OTG_EXTERNAL_VBUS_ENABLED - usbcfg.b.ulpi_ext_vbus_drv = 1; /* Use external VBUS */ - #endif -#endif - usbcfg.b.term_sel_dl_pulse = 0; /* Data line pulsing using utmi_txvalid */ - usbcfg.b.ulpi_utmi_sel = 1; /* ULPI seleInterfacect */ - - usbcfg.b.phyif = 0; /* 8 bits */ - usbcfg.b.ddrsel = 0; /* single data rate */ - - usbcfg.b.ulpi_fsls = 0; - usbcfg.b.ulpi_clk_sus_m = 0; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - - /* Reset after a PHY select */ - USB_OTG_CoreReset(pdev); - - if(pdev->cfg.dma_enable == 1) - { - - ahbcfg.b.hburstlen = 5; /* 64 x 32-bits*/ - ahbcfg.b.dmaenable = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32); - - } - } - else /* FS interface (embedded Phy or I2C Phy) */ - { - - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);; - usbcfg.b.physel = 1; /* FS Interface */ - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - /* Reset after a PHY select and set Host mode */ - USB_OTG_CoreReset(pdev); - /* Enable the I2C interface and deactivate the power down*/ - gccfg.d32 = 0; - gccfg.b.pwdn = 1; - - if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) - { - gccfg.b.i2cifen = 1; - } - gccfg.b.vbussensingA = 1 ; - gccfg.b.vbussensingB = 1 ; -#ifndef VBUS_SENSING_ENABLED - gccfg.b.disablevbussensing = 1; -#endif - - if(pdev->cfg.Sof_output) - { - gccfg.b.sofouten = 1; - } - - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32); - USB_OTG_BSP_mDelay(20); - /* Program GUSBCFG.OtgUtmifsSel to I2C*/ - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - - if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) - { - usbcfg.b.otgutmifssel = 1; - } - - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - - if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) - { - /*Program GI2CCTL.I2CEn*/ - i2cctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GI2CCTL); - i2cctl.b.i2cdevaddr = 1; - i2cctl.b.i2cen = 0; - i2cctl.b.dat_se0 = 1; - i2cctl.b.addr = 0x2D; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GI2CCTL, i2cctl.d32); - - USB_OTG_BSP_mDelay(200); - - i2cctl.b.i2cen = 1; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GI2CCTL, i2cctl.d32); - USB_OTG_BSP_mDelay(200); - } - } - /* case the HS core is working in FS mode */ - if(pdev->cfg.dma_enable == 1) - { - - ahbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GAHBCFG); - ahbcfg.b.hburstlen = 5; /* 64 x 32-bits*/ - ahbcfg.b.dmaenable = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32); - - } - /* initialize OTG features */ -#ifdef USE_OTG_MODE - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - usbcfg.b.hnpcap = 1; - usbcfg.b.srpcap = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - USB_OTG_EnableCommonInt(pdev); -#endif - return status; -} -/** -* @brief USB_OTG_EnableGlobalInt -* Enables the controller's Global Int in the AHB Config reg -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EnableGlobalInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GAHBCFG_TypeDef ahbcfg; - - ahbcfg.d32 = 0; - ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ - USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GAHBCFG, 0, ahbcfg.d32); - return status; -} - - -/** -* @brief USB_OTG_DisableGlobalInt -* Enables the controller's Global Int in the AHB Config reg -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GAHBCFG_TypeDef ahbcfg; - ahbcfg.d32 = 0; - ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ - USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32, 0); - return status; -} - - -/** -* @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO -* @param pdev : Selected device -* @param num : FO num -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_FlushTxFifo (USB_OTG_CORE_HANDLE *pdev , uint32_t num ) -{ - USB_OTG_STS status = USB_OTG_OK; - __IO USB_OTG_GRSTCTL_TypeDef greset; - - uint32_t count = 0; - greset.d32 = 0; - greset.b.txfflsh = 1; - greset.b.txfnum = num; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GRSTCTL, greset.d32 ); - do - { - greset.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRSTCTL); - if (++count > 200000) - { - break; - } - } - while (greset.b.txfflsh == 1); - /* Wait for 3 PHY Clocks*/ - USB_OTG_BSP_uDelay(3); - return status; -} - - -/** -* @brief USB_OTG_FlushRxFifo : Flush a Rx FIFO -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_FlushRxFifo( USB_OTG_CORE_HANDLE *pdev ) -{ - USB_OTG_STS status = USB_OTG_OK; - __IO USB_OTG_GRSTCTL_TypeDef greset; - uint32_t count = 0; - - greset.d32 = 0; - greset.b.rxfflsh = 1; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GRSTCTL, greset.d32 ); - do - { - greset.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRSTCTL); - if (++count > 200000) - { - break; - } - } - while (greset.b.rxfflsh == 1); - /* Wait for 3 PHY Clocks*/ - USB_OTG_BSP_uDelay(3); - return status; -} - - -/** -* @brief USB_OTG_SetCurrentMode : Set ID line -* @param pdev : Selected device -* @param mode : (Host/device) -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_SetCurrentMode(USB_OTG_CORE_HANDLE *pdev , uint8_t mode) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GUSBCFG_TypeDef usbcfg; - - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - - usbcfg.b.force_host = 0; - usbcfg.b.force_dev = 0; - - if ( mode == HOST_MODE) - { - usbcfg.b.force_host = 1; - } - else if ( mode == DEVICE_MODE) - { - usbcfg.b.force_dev = 1; - } - - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - USB_OTG_BSP_mDelay(50); - return status; -} - - -/** -* @brief USB_OTG_GetMode : Get current mode -* @param pdev : Selected device -* @retval current mode -*/ -uint32_t USB_OTG_GetMode(USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS ) & 0x1); -} - - -/** -* @brief USB_OTG_IsDeviceMode : Check if it is device mode -* @param pdev : Selected device -* @retval num_in_ep -*/ -uint8_t USB_OTG_IsDeviceMode(USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_GetMode(pdev) != HOST_MODE); -} - - -/** -* @brief USB_OTG_IsHostMode : Check if it is host mode -* @param pdev : Selected device -* @retval num_in_ep -*/ -uint8_t USB_OTG_IsHostMode(USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_GetMode(pdev) == HOST_MODE); -} - - -/** -* @brief USB_OTG_ReadCoreItr : returns the Core Interrupt register -* @param pdev : Selected device -* @retval Status -*/ -uint32_t USB_OTG_ReadCoreItr(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t v = 0; - v = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS); - v &= USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTMSK); - return v; -} - - -/** -* @brief USB_OTG_ReadOtgItr : returns the USB_OTG Interrupt register -* @param pdev : Selected device -* @retval Status -*/ -uint32_t USB_OTG_ReadOtgItr (USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_READ_REG32 (&pdev->regs.GREGS->GOTGINT)); -} - -#ifdef USE_HOST_MODE -/** -* @brief USB_OTG_CoreInitHost : Initializes USB_OTG controller for host mode -* @param pdev : Selected device -* @retval status -*/ -USB_OTG_STS USB_OTG_CoreInitHost(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_FSIZ_TypeDef nptxfifosize; - USB_OTG_FSIZ_TypeDef ptxfifosize; - USB_OTG_HCFG_TypeDef hcfg; - -#ifdef USE_OTG_MODE - USB_OTG_OTGCTL_TypeDef gotgctl; -#endif - - uint32_t i = 0; - - nptxfifosize.d32 = 0; - ptxfifosize.d32 = 0; -#ifdef USE_OTG_MODE - gotgctl.d32 = 0; -#endif - hcfg.d32 = 0; - - - /* configure charge pump IO */ - USB_OTG_BSP_ConfigVBUS(pdev); - - /* Restart the Phy Clock */ - USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0); - - /* Initialize Host Configuration Register */ - USB_OTG_InitFSLSPClkSel(pdev , HCFG_48_MHZ); /* in init phase */ - - hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG); - hcfg.b.fslssupp = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32); - - /* Configure data FIFO sizes */ - /* Rx FIFO */ -#ifdef USB_OTG_FS_CORE - if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID) - { - /* set Rx FIFO size */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE); - nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE; - nptxfifosize.b.depth = TXH_NP_FS_FIFOSIZ; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32); - - ptxfifosize.b.startaddr = RX_FIFO_FS_SIZE + TXH_NP_FS_FIFOSIZ; - ptxfifosize.b.depth = TXH_P_FS_FIFOSIZ; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32); - } -#endif -#ifdef USB_OTG_HS_CORE - if (pdev->cfg.coreID == USB_OTG_HS_CORE_ID) - { - /* set Rx FIFO size */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE); - nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE; - nptxfifosize.b.depth = TXH_NP_HS_FIFOSIZ; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32); - - ptxfifosize.b.startaddr = RX_FIFO_HS_SIZE + TXH_NP_HS_FIFOSIZ; - ptxfifosize.b.depth = TXH_P_HS_FIFOSIZ; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32); - } -#endif - -#ifdef USE_OTG_MODE - /* Clear Host Set HNP Enable in the USB_OTG Control Register */ - gotgctl.b.hstsethnpen = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GOTGCTL, gotgctl.d32, 0); -#endif - - /* Make sure the FIFOs are flushed. */ - USB_OTG_FlushTxFifo(pdev, 0x10 ); /* all Tx FIFOs */ - USB_OTG_FlushRxFifo(pdev); - - - /* Clear all pending HC Interrupts */ - for (i = 0; i < pdev->cfg.host_channels; i++) - { - USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCINT, 0xFFFFFFFF ); - USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCGINTMSK, 0 ); - } -#ifndef USE_OTG_MODE - USB_OTG_DriveVbus(pdev, 1); -#endif - - USB_OTG_EnableHostInt(pdev); - return status; -} - -/** -* @brief USB_OTG_IsEvenFrame -* This function returns the frame number for sof packet -* @param pdev : Selected device -* @retval Frame number -*/ -uint8_t USB_OTG_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev) -{ - return !(USB_OTG_READ_REG32(&pdev->regs.HREGS->HFNUM) & 0x1); -} - -/** -* @brief USB_OTG_DriveVbus : set/reset vbus -* @param pdev : Selected device -* @param state : VBUS state -* @retval None -*/ -void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state) -{ - USB_OTG_HPRT0_TypeDef hprt0; - - hprt0.d32 = 0; - - /* enable disable the external charge pump */ - USB_OTG_BSP_DriveVBUS(pdev, state); - - /* Turn on the Host port power. */ - hprt0.d32 = USB_OTG_ReadHPRT0(pdev); - if ((hprt0.b.prtpwr == 0 ) && (state == 1 )) - { - hprt0.b.prtpwr = 1; - USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); - } - if ((hprt0.b.prtpwr == 1 ) && (state == 0 )) - { - hprt0.b.prtpwr = 0; - USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); - } - - USB_OTG_BSP_mDelay(200); -} -/** -* @brief USB_OTG_EnableHostInt: Enables the Host mode interrupts -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EnableHostInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GINTMSK_TypeDef intmsk; - intmsk.d32 = 0; - /* Disable all interrupts. */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTMSK, 0); - - /* Clear any pending interrupts. */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF); - - /* Enable the common interrupts */ - USB_OTG_EnableCommonInt(pdev); - - if (pdev->cfg.dma_enable == 0) - { - intmsk.b.rxstsqlvl = 1; - } - intmsk.b.portintr = 1; - intmsk.b.hcintr = 1; - intmsk.b.disconnect = 1; - intmsk.b.sofintr = 1; - intmsk.b.incomplisoout = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32); - return status; -} - -/** -* @brief USB_OTG_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the -* HCFG register on the PHY type -* @param pdev : Selected device -* @param freq : clock frequency -* @retval None -*/ -void USB_OTG_InitFSLSPClkSel(USB_OTG_CORE_HANDLE *pdev , uint8_t freq) -{ - USB_OTG_HCFG_TypeDef hcfg; - - hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG); - hcfg.b.fslspclksel = freq; - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32); -} - - -/** -* @brief USB_OTG_ReadHPRT0 : Reads HPRT0 to modify later -* @param pdev : Selected device -* @retval HPRT0 value -*/ -uint32_t USB_OTG_ReadHPRT0(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HPRT0_TypeDef hprt0; - - hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0); - hprt0.b.prtena = 0; - hprt0.b.prtconndet = 0; - hprt0.b.prtenchng = 0; - hprt0.b.prtovrcurrchng = 0; - return hprt0.d32; -} - - -/** -* @brief USB_OTG_ReadHostAllChannels_intr : Register PCD Callbacks -* @param pdev : Selected device -* @retval Status -*/ -uint32_t USB_OTG_ReadHostAllChannels_intr (USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_READ_REG32 (&pdev->regs.HREGS->HAINT)); -} - - -/** -* @brief USB_OTG_ResetPort : Reset Host Port -* @param pdev : Selected device -* @retval status -* @note : (1)The application must wait at least 10 ms (+ 10 ms security) -* before clearing the reset bit. -*/ -uint32_t USB_OTG_ResetPort(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HPRT0_TypeDef hprt0; - - hprt0.d32 = USB_OTG_ReadHPRT0(pdev); - hprt0.b.prtrst = 1; - USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); - USB_OTG_BSP_mDelay (10); /* See Note #1 */ - hprt0.b.prtrst = 0; - USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); - USB_OTG_BSP_mDelay (20); - return 1; -} - - -/** -* @brief USB_OTG_HC_Init : Prepares a host channel for transferring packets -* @param pdev : Selected device -* @param hc_num : channel number -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_HC_Init(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - USB_OTG_STS status = USB_OTG_OK; - uint32_t intr_enable = 0; - USB_OTG_HCGINTMSK_TypeDef hcintmsk; - USB_OTG_GINTMSK_TypeDef gintmsk; - USB_OTG_HCCHAR_TypeDef hcchar; - USB_OTG_HCINTn_TypeDef hcint; - - - gintmsk.d32 = 0; - hcintmsk.d32 = 0; - hcchar.d32 = 0; - - /* Clear old interrupt conditions for this host channel. */ - hcint.d32 = 0xFFFFFFFF; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINT, hcint.d32); - - /* Enable channel interrupts required for this transfer. */ - hcintmsk.d32 = 0; - - if (pdev->cfg.dma_enable == 1) - { - hcintmsk.b.ahberr = 1; - } - - switch (pdev->host.hc[hc_num].ep_type) - { - case EP_TYPE_CTRL: - case EP_TYPE_BULK: - hcintmsk.b.xfercompl = 1; - hcintmsk.b.stall = 1; - hcintmsk.b.xacterr = 1; - hcintmsk.b.datatglerr = 1; - hcintmsk.b.nak = 1; - if (pdev->host.hc[hc_num].ep_is_in) - { - hcintmsk.b.bblerr = 1; - } - else - { - hcintmsk.b.nyet = 1; - if (pdev->host.hc[hc_num].do_ping) - { - hcintmsk.b.ack = 1; - } - } - break; - case EP_TYPE_INTR: - hcintmsk.b.xfercompl = 1; - hcintmsk.b.nak = 1; - hcintmsk.b.stall = 1; - hcintmsk.b.xacterr = 1; - hcintmsk.b.datatglerr = 1; - hcintmsk.b.frmovrun = 1; - - if (pdev->host.hc[hc_num].ep_is_in) - { - hcintmsk.b.bblerr = 1; - } - - break; - case EP_TYPE_ISOC: - hcintmsk.b.xfercompl = 1; - hcintmsk.b.frmovrun = 1; - hcintmsk.b.ack = 1; - - if (pdev->host.hc[hc_num].ep_is_in) - { - hcintmsk.b.xacterr = 1; - hcintmsk.b.bblerr = 1; - } - break; - } - - - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, hcintmsk.d32); - - - /* Enable the top level host channel interrupt. */ - intr_enable = (1 << hc_num); - USB_OTG_MODIFY_REG32(&pdev->regs.HREGS->HAINTMSK, 0, intr_enable); - - /* Make sure host channel interrupts are enabled. */ - gintmsk.b.hcintr = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, 0, gintmsk.d32); - - /* Program the HCCHAR register */ - hcchar.d32 = 0; - hcchar.b.devaddr = pdev->host.hc[hc_num].dev_addr; - hcchar.b.epnum = pdev->host.hc[hc_num].ep_num; - hcchar.b.epdir = pdev->host.hc[hc_num].ep_is_in; - hcchar.b.lspddev = (pdev->host.hc[hc_num].speed == HPRT0_PRTSPD_LOW_SPEED); - hcchar.b.eptype = pdev->host.hc[hc_num].ep_type; - hcchar.b.mps = pdev->host.hc[hc_num].max_packet; - if (pdev->host.hc[hc_num].ep_type == HCCHAR_INTR) - { - hcchar.b.oddfrm = 1; - } - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); - return status; -} - - -/** -* @brief USB_OTG_HC_StartXfer : Start transfer -* @param pdev : Selected device -* @param hc_num : channel number -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_HC_StartXfer(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_HCCHAR_TypeDef hcchar; - USB_OTG_HCTSIZn_TypeDef hctsiz; - USB_OTG_HNPTXSTS_TypeDef hnptxsts; - USB_OTG_HPTXSTS_TypeDef hptxsts; - USB_OTG_GINTMSK_TypeDef intmsk; - uint16_t len_words = 0; - - uint16_t num_packets; - uint16_t max_hc_pkt_count; - - max_hc_pkt_count = 256; - hctsiz.d32 = 0; - hcchar.d32 = 0; - intmsk.d32 = 0; - - /* Compute the expected number of packets associated to the transfer */ - if (pdev->host.hc[hc_num].xfer_len > 0) - { - num_packets = (pdev->host.hc[hc_num].xfer_len + \ - pdev->host.hc[hc_num].max_packet - 1) / pdev->host.hc[hc_num].max_packet; - - if (num_packets > max_hc_pkt_count) - { - num_packets = max_hc_pkt_count; - pdev->host.hc[hc_num].xfer_len = num_packets * \ - pdev->host.hc[hc_num].max_packet; - } - } - else - { - num_packets = 1; - } - if (pdev->host.hc[hc_num].ep_is_in) - { - pdev->host.hc[hc_num].xfer_len = num_packets * \ - pdev->host.hc[hc_num].max_packet; - } - /* Initialize the HCTSIZn register */ - hctsiz.b.xfersize = pdev->host.hc[hc_num].xfer_len; - hctsiz.b.pktcnt = num_packets; - hctsiz.b.pid = pdev->host.hc[hc_num].data_pid; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCDMA, (unsigned int)pdev->host.hc[hc_num].xfer_buff); - } - - - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR); - hcchar.b.oddfrm = USB_OTG_IsEvenFrame(pdev); - - /* Set host channel enable */ - hcchar.b.chen = 1; - hcchar.b.chdis = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); - - if (pdev->cfg.dma_enable == 0) /* Slave mode */ - { - if((pdev->host.hc[hc_num].ep_is_in == 0) && - (pdev->host.hc[hc_num].xfer_len > 0)) - { - switch(pdev->host.hc[hc_num].ep_type) - { - /* Non periodic transfer */ - case EP_TYPE_CTRL: - case EP_TYPE_BULK: - - hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS); - len_words = (pdev->host.hc[hc_num].xfer_len + 3) / 4; - - /* check if there is enough space in FIFO space */ - if(len_words > hnptxsts.b.nptxfspcavail) - { - /* need to process data in nptxfempty interrupt */ - intmsk.b.nptxfempty = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32); - } - - break; - /* Periodic transfer */ - case EP_TYPE_INTR: - case EP_TYPE_ISOC: - hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS); - len_words = (pdev->host.hc[hc_num].xfer_len + 3) / 4; - /* check if there is enough space in FIFO space */ - if(len_words > hptxsts.b.ptxfspcavail) /* split the transfer */ - { - /* need to process data in ptxfempty interrupt */ - intmsk.b.ptxfempty = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32); - } - break; - - default: - break; - } - - /* Write packet into the Tx FIFO. */ - USB_OTG_WritePacket(pdev, - pdev->host.hc[hc_num].xfer_buff , - hc_num, pdev->host.hc[hc_num].xfer_len); - } - } - return status; -} - - -/** -* @brief USB_OTG_HC_Halt : Halt channel -* @param pdev : Selected device -* @param hc_num : channel number -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_HC_Halt(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_HNPTXSTS_TypeDef nptxsts; - USB_OTG_HPTXSTS_TypeDef hptxsts; - USB_OTG_HCCHAR_TypeDef hcchar; - - nptxsts.d32 = 0; - hptxsts.d32 = 0; - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR); - hcchar.b.chen = 1; - hcchar.b.chdis = 1; - - /* Check for space in the request queue to issue the halt. */ - if (hcchar.b.eptype == HCCHAR_CTRL || hcchar.b.eptype == HCCHAR_BULK) - { - nptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS); - if (nptxsts.b.nptxqspcavail == 0) - { - hcchar.b.chen = 0; - } - } - else - { - hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS); - if (hptxsts.b.ptxqspcavail == 0) - { - hcchar.b.chen = 0; - } - } - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); - return status; -} - -/** -* @brief Issue a ping token -* @param None -* @retval : None -*/ -USB_OTG_STS USB_OTG_HC_DoPing(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_HCCHAR_TypeDef hcchar; - USB_OTG_HCTSIZn_TypeDef hctsiz; - - hctsiz.d32 = 0; - hctsiz.b.dopng = 1; - hctsiz.b.pktcnt = 1; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32); - - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR); - hcchar.b.chen = 1; - hcchar.b.chdis = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); - return status; -} - -/** -* @brief Stop the device and clean up fifo's -* @param None -* @retval : None -*/ -void USB_OTG_StopHost(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HCCHAR_TypeDef hcchar; - uint32_t i; - - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HAINTMSK , 0); - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HAINT, 0xFFFFFFFF); - /* Flush out any leftover queued requests. */ - - for (i = 0; i < pdev->cfg.host_channels; i++) - { - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[i]->HCCHAR); - hcchar.b.chen = 0; - hcchar.b.chdis = 1; - hcchar.b.epdir = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[i]->HCCHAR, hcchar.d32); - } - - /* Flush the FIFO */ - USB_OTG_FlushRxFifo(pdev); - USB_OTG_FlushTxFifo(pdev , 0x10 ); -} -#endif -#ifdef USE_DEVICE_MODE -/* PCD Core Layer */ - -/** -* @brief USB_OTG_InitDevSpeed :Initializes the DevSpd field of DCFG register -* depending the PHY type and the enumeration speed of the device. -* @param pdev : Selected device -* @retval : None -*/ -void USB_OTG_InitDevSpeed(USB_OTG_CORE_HANDLE *pdev , uint8_t speed) -{ - USB_OTG_DCFG_TypeDef dcfg; - - dcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCFG); - dcfg.b.devspd = speed; - USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCFG, dcfg.d32); -} - - -/** -* @brief USB_OTG_CoreInitDev : Initializes the USB_OTG controller registers -* for device mode -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - uint32_t i; - USB_OTG_DCFG_TypeDef dcfg; - USB_OTG_FSIZ_TypeDef nptxfifosize; - USB_OTG_FSIZ_TypeDef txfifosize; - USB_OTG_DIEPMSK_TypeDef msk; - USB_OTG_DTHRCTL_TypeDef dthrctl; - - depctl.d32 = 0; - dcfg.d32 = 0; - nptxfifosize.d32 = 0; - txfifosize.d32 = 0; - msk.d32 = 0; - - /* Restart the Phy Clock */ - USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0); - /* Device configuration register */ - dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG); - dcfg.b.perfrint = DCFG_FRAME_INTERVAL_80; - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32 ); - -#ifdef USB_OTG_FS_CORE - if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID ) - { - - /* Set Full speed phy */ - USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_FULL); - - /* set Rx FIFO size */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE); - - /* EP0 TX*/ - nptxfifosize.b.depth = TX0_FIFO_FS_SIZE; - nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 ); - - - /* EP1 TX*/ - txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth; - txfifosize.b.depth = TX1_FIFO_FS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 ); - - - /* EP2 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX2_FIFO_FS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 ); - - - /* EP3 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX3_FIFO_FS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 ); - } -#endif -#ifdef USB_OTG_HS_CORE - if(pdev->cfg.coreID == USB_OTG_HS_CORE_ID ) - { - - /* Set High speed phy */ - - if(pdev->cfg.phy_itface == USB_OTG_ULPI_PHY) - { - USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH); - } - else /* set High speed phy in Full speed mode */ - { - USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH_IN_FULL); - } - - /* set Rx FIFO size */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE); - - /* EP0 TX*/ - nptxfifosize.b.depth = TX0_FIFO_HS_SIZE; - nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 ); - - - /* EP1 TX*/ - txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth; - txfifosize.b.depth = TX1_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 ); - - - /* EP2 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX2_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 ); - - - /* EP3 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX3_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 ); - - /* EP4 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX4_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[3], txfifosize.d32 ); - - - /* EP5 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX5_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[4], txfifosize.d32 ); - } -#endif - /* Flush the FIFOs */ - USB_OTG_FlushTxFifo(pdev , 0x10); /* all Tx FIFOs */ - USB_OTG_FlushRxFifo(pdev); - /* Clear all pending Device Interrupts */ - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 ); - - for (i = 0; i < pdev->cfg.dev_endpoints; i++) - { - depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[i]->DIEPCTL); - if (depctl.b.epena) - { - depctl.d32 = 0; - depctl.b.epdis = 1; - depctl.b.snak = 1; - } - else - { - depctl.d32 = 0; - } - USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPCTL, depctl.d32); - USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPTSIZ, 0); - USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF); - } - for (i = 0; i < pdev->cfg.dev_endpoints; i++) - { - USB_OTG_DEPCTL_TypeDef depctl; - depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[i]->DOEPCTL); - if (depctl.b.epena) - { - depctl.d32 = 0; - depctl.b.epdis = 1; - depctl.b.snak = 1; - } - else - { - depctl.d32 = 0; - } - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPCTL, depctl.d32); - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPTSIZ, 0); - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF); - } - msk.d32 = 0; - msk.b.txfifoundrn = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPMSK, msk.d32, msk.d32); - - if (pdev->cfg.dma_enable == 1) - { - dthrctl.d32 = 0; - dthrctl.b.non_iso_thr_en = 1; - dthrctl.b.iso_thr_en = 1; - dthrctl.b.tx_thr_len = 64; - dthrctl.b.rx_thr_en = 1; - dthrctl.b.rx_thr_len = 64; - USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DTHRCTL, dthrctl.d32); - } - USB_OTG_EnableDevInt(pdev); - return status; -} - - -/** -* @brief USB_OTG_EnableDevInt : Enables the Device mode interrupts -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EnableDevInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GINTMSK_TypeDef intmsk; - - intmsk.d32 = 0; - - /* Disable all interrupts. */ - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, 0); - /* Clear any pending interrupts */ - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF); - /* Enable the common interrupts */ - USB_OTG_EnableCommonInt(pdev); - - if (pdev->cfg.dma_enable == 0) - { - intmsk.b.rxstsqlvl = 1; - } - - /* Enable interrupts matching to the Device mode ONLY */ - intmsk.b.usbsuspend = 1; - intmsk.b.usbreset = 1; - intmsk.b.enumdone = 1; - intmsk.b.inepintr = 1; - intmsk.b.outepintr = 1; - intmsk.b.sofintr = 1; - - intmsk.b.incomplisoin = 1; - intmsk.b.incomplisoout = 1; -#ifdef VBUS_SENSING_ENABLED - intmsk.b.sessreqintr = 1; - intmsk.b.otgintr = 1; -#endif - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32); - return status; -} - - -/** -* @brief USB_OTG_GetDeviceSpeed -* Get the device speed from the device status register -* @param None -* @retval status -*/ -enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_DSTS_TypeDef dsts; - enum USB_OTG_SPEED speed = USB_SPEED_UNKNOWN; - - - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - - switch (dsts.b.enumspd) - { - case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ: - speed = USB_SPEED_HIGH; - break; - case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ: - case DSTS_ENUMSPD_FS_PHY_48MHZ: - speed = USB_SPEED_FULL; - break; - - case DSTS_ENUMSPD_LS_PHY_6MHZ: - speed = USB_SPEED_LOW; - break; - } - - return speed; -} -/** -* @brief enables EP0 OUT to receive SETUP packets and configures EP0 -* for transmitting packets -* @param None -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EP0Activate(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DSTS_TypeDef dsts; - USB_OTG_DEPCTL_TypeDef diepctl; - USB_OTG_DCTL_TypeDef dctl; - - dctl.d32 = 0; - /* Read the Device Status and Endpoint 0 Control registers */ - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - diepctl.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL); - /* Set the MPS of the IN EP based on the enumeration speed */ - switch (dsts.b.enumspd) - { - case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ: - case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ: - case DSTS_ENUMSPD_FS_PHY_48MHZ: - diepctl.b.mps = DEP0CTL_MPS_64; - break; - case DSTS_ENUMSPD_LS_PHY_6MHZ: - diepctl.b.mps = DEP0CTL_MPS_8; - break; - } - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL, diepctl.d32); - dctl.b.cgnpinnak = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, dctl.d32); - return status; -} - - -/** -* @brief USB_OTG_EPActivate : Activates an EP -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPActivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - USB_OTG_DAINT_TypeDef daintmsk; - __IO uint32_t *addr; - - - depctl.d32 = 0; - daintmsk.d32 = 0; - /* Read DEPCTLn register */ - if (ep->is_in == 1) - { - addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL; - daintmsk.ep.in = 1 << ep->num; - } - else - { - addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL; - daintmsk.ep.out = 1 << ep->num; - } - /* If the EP is already active don't change the EP Control - * register. */ - depctl.d32 = USB_OTG_READ_REG32(addr); - if (!depctl.b.usbactep) - { - depctl.b.mps = ep->maxpacket; - depctl.b.eptype = ep->type; - depctl.b.txfnum = ep->tx_fifo_num; - depctl.b.setd0pid = 1; - depctl.b.usbactep = 1; - USB_OTG_WRITE_REG32(addr, depctl.d32); - } - /* Enable the Interrupt for this EP */ -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED - if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID)) - { - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, 0, daintmsk.d32); - } - else -#endif - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, 0, daintmsk.d32); - return status; -} - - -/** -* @brief USB_OTG_EPDeactivate : Deactivates an EP -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - USB_OTG_DAINT_TypeDef daintmsk; - __IO uint32_t *addr; - - depctl.d32 = 0; - daintmsk.d32 = 0; - /* Read DEPCTLn register */ - if (ep->is_in == 1) - { - addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL; - daintmsk.ep.in = 1 << ep->num; - } - else - { - addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL; - daintmsk.ep.out = 1 << ep->num; - } - depctl.b.usbactep = 0; - USB_OTG_WRITE_REG32(addr, depctl.d32); - /* Disable the Interrupt for this EP */ - -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED - if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID)) - { - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, daintmsk.d32, 0); - } - else -#endif - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, daintmsk.d32, 0); - return status; -} - - -/** -* @brief USB_OTG_EPStartXfer : Handle the setup for data xfer for an EP and -* starts the xfer -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPStartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - USB_OTG_DEPXFRSIZ_TypeDef deptsiz; - USB_OTG_DSTS_TypeDef dsts; - uint32_t fifoemptymsk = 0; - - depctl.d32 = 0; - deptsiz.d32 = 0; - /* IN endpoint */ - if (ep->is_in == 1) - { - depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPCTL)); - deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ)); - /* Zero Length Packet? */ - if (ep->xfer_len == 0) - { - deptsiz.b.xfersize = 0; - deptsiz.b.pktcnt = 1; - } - else - { - /* Program the transfer size and packet count - * as follows: xfersize = N * maxpacket + - * short_packet pktcnt = N + (short_packet - * exist ? 1 : 0) - */ - deptsiz.b.xfersize = ep->xfer_len; - deptsiz.b.pktcnt = (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket; - - if (ep->type == EP_TYPE_ISOC) - { - deptsiz.b.mc = 1; - } - } - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ, deptsiz.d32); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr); - } - else - { - if (ep->type != EP_TYPE_ISOC) - { - /* Enable the Tx FIFO Empty Interrupt for this EP */ - if (ep->xfer_len > 0) - { - fifoemptymsk = 1 << ep->num; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk); - } - } - } - - - if (ep->type == EP_TYPE_ISOC) - { - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - - if (((dsts.b.soffn)&0x1) == 0) - { - depctl.b.setd1pid = 1; - } - else - { - depctl.b.setd0pid = 1; - } - } - - /* EP enable, IN data in FIFO */ - depctl.b.cnak = 1; - depctl.b.epena = 1; - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPCTL, depctl.d32); - - if (ep->type == EP_TYPE_ISOC) - { - USB_OTG_WritePacket(pdev, ep->xfer_buff, ep->num, ep->xfer_len); - } - } - else - { - /* OUT endpoint */ - depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL)); - deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ)); - /* Program the transfer size and packet count as follows: - * pktcnt = N - * xfersize = N * maxpacket - */ - if (ep->xfer_len == 0) - { - deptsiz.b.xfersize = ep->maxpacket; - deptsiz.b.pktcnt = 1; - } - else - { - deptsiz.b.pktcnt = (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket; - deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket; - } - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr); - } - - if (ep->type == EP_TYPE_ISOC) - { - if (ep->even_odd_frame) - { - depctl.b.setd1pid = 1; - } - else - { - depctl.b.setd0pid = 1; - } - } - /* EP enable */ - depctl.b.cnak = 1; - depctl.b.epena = 1; - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL, depctl.d32); - } - return status; -} - - -/** -* @brief USB_OTG_EP0StartXfer : Handle the setup for a data xfer for EP0 and -* starts the xfer -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - USB_OTG_DEP0XFRSIZ_TypeDef deptsiz; - USB_OTG_INEPREGS *in_regs; - uint32_t fifoemptymsk = 0; - - depctl.d32 = 0; - deptsiz.d32 = 0; - /* IN endpoint */ - if (ep->is_in == 1) - { - in_regs = pdev->regs.INEP_REGS[0]; - depctl.d32 = USB_OTG_READ_REG32(&in_regs->DIEPCTL); - deptsiz.d32 = USB_OTG_READ_REG32(&in_regs->DIEPTSIZ); - /* Zero Length Packet? */ - if (ep->xfer_len == 0) - { - deptsiz.b.xfersize = 0; - deptsiz.b.pktcnt = 1; - - } - else - { - if (ep->xfer_len > ep->maxpacket) - { - ep->xfer_len = ep->maxpacket; - deptsiz.b.xfersize = ep->maxpacket; - } - else - { - deptsiz.b.xfersize = ep->xfer_len; - } - deptsiz.b.pktcnt = 1; - } - USB_OTG_WRITE_REG32(&in_regs->DIEPTSIZ, deptsiz.d32); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr); - } - - /* EP enable, IN data in FIFO */ - depctl.b.cnak = 1; - depctl.b.epena = 1; - USB_OTG_WRITE_REG32(&in_regs->DIEPCTL, depctl.d32); - - - - if (pdev->cfg.dma_enable == 0) - { - /* Enable the Tx FIFO Empty Interrupt for this EP */ - if (ep->xfer_len > 0) - { - { - fifoemptymsk |= 1 << ep->num; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk); - } - } - } - } - else - { - /* OUT endpoint */ - depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - deptsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ); - /* Program the transfer size and packet count as follows: - * xfersize = N * (maxpacket + 4 - (maxpacket % 4)) - * pktcnt = N */ - if (ep->xfer_len == 0) - { - deptsiz.b.xfersize = ep->maxpacket; - deptsiz.b.pktcnt = 1; - } - else - { - ep->xfer_len = ep->maxpacket; - deptsiz.b.xfersize = ep->maxpacket; - deptsiz.b.pktcnt = 1; - } - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32); - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr); - } - /* EP enable */ - depctl.b.cnak = 1; - depctl.b.epena = 1; - USB_OTG_WRITE_REG32 (&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL), depctl.d32); - - } - return status; -} - - -/** -* @brief USB_OTG_EPSetStall : Set the EP STALL -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPSetStall(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - __IO uint32_t *depctl_addr; - - depctl.d32 = 0; - if (ep->is_in == 1) - { - depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - /* set the disable and stall bits */ - if (depctl.b.epena) - { - depctl.b.epdis = 1; - } - depctl.b.stall = 1; - USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); - } - else - { - depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - /* set the stall bit */ - depctl.b.stall = 1; - USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); - } - return status; -} - - -/** -* @brief Clear the EP STALL -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPClearStall(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - __IO uint32_t *depctl_addr; - - depctl.d32 = 0; - - if (ep->is_in == 1) - { - depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); - } - else - { - depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - } - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - /* clear the stall bits */ - depctl.b.stall = 0; - if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK) - { - depctl.b.setd0pid = 1; /* DATA0 */ - } - USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); - return status; -} - - -/** -* @brief USB_OTG_ReadDevAllOutEp_itr : returns OUT endpoint interrupt bits -* @param pdev : Selected device -* @retval OUT endpoint interrupt bits -*/ -uint32_t USB_OTG_ReadDevAllOutEp_itr(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t v; - v = USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINT); - v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINTMSK); - return ((v & 0xffff0000) >> 16); -} - - -/** -* @brief USB_OTG_ReadDevOutEP_itr : returns Device OUT EP Interrupt register -* @param pdev : Selected device -* @param ep : end point number -* @retval Device OUT EP Interrupt register -*/ -uint32_t USB_OTG_ReadDevOutEP_itr(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) -{ - uint32_t v; - v = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT); - v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOEPMSK); - return v; -} - - -/** -* @brief USB_OTG_ReadDevAllInEPItr : Get int status register -* @param pdev : Selected device -* @retval int status register -*/ -uint32_t USB_OTG_ReadDevAllInEPItr(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t v; - v = USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINT); - v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINTMSK); - return (v & 0xffff); -} - -/** -* @brief configures EPO to receive SETUP packets -* @param None -* @retval : None -*/ -void USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_DEP0XFRSIZ_TypeDef doeptsize0; - doeptsize0.d32 = 0; - doeptsize0.b.supcnt = 3; - doeptsize0.b.pktcnt = 1; - doeptsize0.b.xfersize = 8 * 3; - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPTSIZ, doeptsize0.d32 ); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_DEPCTL_TypeDef doepctl; - doepctl.d32 = 0; - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPDMA, - (uint32_t)&pdev->dev.setup_packet); - - /* EP enable */ - doepctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[0]->DOEPCTL); - doepctl.b.epena = 1; - doepctl.d32 = 0x80008000; - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPCTL, doepctl.d32); - } -} - -/** -* @brief USB_OTG_RemoteWakeup : active remote wakeup signalling -* @param None -* @retval : None -*/ -void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev) -{ - - USB_OTG_DCTL_TypeDef dctl; - USB_OTG_DSTS_TypeDef dsts; - USB_OTG_PCGCCTL_TypeDef power; - - if (pdev->dev.DevRemoteWakeup) - { - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - if(dsts.b.suspsts == 1) - { - if(pdev->cfg.low_power) - { - /* un-gate USB Core clock */ - power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL); - power.b.gatehclk = 0; - power.b.stoppclk = 0; - USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); - } - /* active Remote wakeup signaling */ - dctl.d32 = 0; - dctl.b.rmtwkupsig = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, 0, dctl.d32); - USB_OTG_BSP_mDelay(5); - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 ); - } - } -} - - -/** -* @brief USB_OTG_UngateClock : active USB Core clock -* @param None -* @retval : None -*/ -void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev) -{ - if(pdev->cfg.low_power) - { - - USB_OTG_DSTS_TypeDef dsts; - USB_OTG_PCGCCTL_TypeDef power; - - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - - if(dsts.b.suspsts == 1) - { - /* un-gate USB Core clock */ - power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL); - power.b.gatehclk = 0; - power.b.stoppclk = 0; - USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); - - } - } -} - -/** -* @brief Stop the device and clean up fifo's -* @param None -* @retval : None -*/ -void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t i; - - pdev->dev.device_status = 1; - - for (i = 0; i < pdev->cfg.dev_endpoints ; i++) - { - USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF); - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF); - } - - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF ); - - /* Flush the FIFO */ - USB_OTG_FlushRxFifo(pdev); - USB_OTG_FlushTxFifo(pdev , 0x10 ); -} - -/** -* @brief returns the EP Status -* @param pdev : Selected device -* ep : endpoint structure -* @retval : EP status -*/ - -uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep) -{ - USB_OTG_DEPCTL_TypeDef depctl; - __IO uint32_t *depctl_addr; - uint32_t Status = 0; - - depctl.d32 = 0; - if (ep->is_in == 1) - { - depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - - if (depctl.b.stall == 1) - Status = USB_OTG_EP_TX_STALL; - else if (depctl.b.naksts == 1) - Status = USB_OTG_EP_TX_NAK; - else - Status = USB_OTG_EP_TX_VALID; - - } - else - { - depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - if (depctl.b.stall == 1) - Status = USB_OTG_EP_RX_STALL; - else if (depctl.b.naksts == 1) - Status = USB_OTG_EP_RX_NAK; - else - Status = USB_OTG_EP_RX_VALID; - } - - /* Return the current status */ - return Status; -} - -/** -* @brief Set the EP Status -* @param pdev : Selected device -* Status : new Status -* ep : EP structure -* @retval : None -*/ -void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status) -{ - USB_OTG_DEPCTL_TypeDef depctl; - __IO uint32_t *depctl_addr; - - depctl.d32 = 0; - - /* Process for IN endpoint */ - if (ep->is_in == 1) - { - depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - - if (Status == USB_OTG_EP_TX_STALL) - { - USB_OTG_EPSetStall(pdev, ep); return; - } - else if (Status == USB_OTG_EP_TX_NAK) - depctl.b.snak = 1; - else if (Status == USB_OTG_EP_TX_VALID) - { - if (depctl.b.stall == 1) - { - ep->even_odd_frame = 0; - USB_OTG_EPClearStall(pdev, ep); - return; - } - depctl.b.cnak = 1; - depctl.b.usbactep = 1; - depctl.b.epena = 1; - } - else if (Status == USB_OTG_EP_TX_DIS) - depctl.b.usbactep = 0; - } - else /* Process for OUT endpoint */ - { - depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - - if (Status == USB_OTG_EP_RX_STALL) { - depctl.b.stall = 1; - } - else if (Status == USB_OTG_EP_RX_NAK) - depctl.b.snak = 1; - else if (Status == USB_OTG_EP_RX_VALID) - { - if (depctl.b.stall == 1) - { - ep->even_odd_frame = 0; - USB_OTG_EPClearStall(pdev, ep); - return; - } - depctl.b.cnak = 1; - depctl.b.usbactep = 1; - depctl.b.epena = 1; - } - else if (Status == USB_OTG_EP_RX_DIS) - { - depctl.b.usbactep = 0; - } - } - - USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); -} - -#endif -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/discovery_demo/usb_core.h b/example/stm32f4/Projects/discovery_demo/usb_core.h deleted file mode 100644 index 82a09e15c..000000000 --- a/example/stm32f4/Projects/discovery_demo/usb_core.h +++ /dev/null @@ -1,408 +0,0 @@ -/** - ****************************************************************************** - * @file usb_core.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Header of the Core Layer - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_CORE_H__ -#define __USB_CORE_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_conf.h" -#include "usb_regs.h" -#include "usb_defines.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_CORE - * @brief usb otg driver core layer - * @{ - */ - - -/** @defgroup USB_CORE_Exported_Defines - * @{ - */ - -#define USB_OTG_EP0_IDLE 0 -#define USB_OTG_EP0_SETUP 1 -#define USB_OTG_EP0_DATA_IN 2 -#define USB_OTG_EP0_DATA_OUT 3 -#define USB_OTG_EP0_STATUS_IN 4 -#define USB_OTG_EP0_STATUS_OUT 5 -#define USB_OTG_EP0_STALL 6 - -#define USB_OTG_EP_TX_DIS 0x0000 -#define USB_OTG_EP_TX_STALL 0x0010 -#define USB_OTG_EP_TX_NAK 0x0020 -#define USB_OTG_EP_TX_VALID 0x0030 - -#define USB_OTG_EP_RX_DIS 0x0000 -#define USB_OTG_EP_RX_STALL 0x1000 -#define USB_OTG_EP_RX_NAK 0x2000 -#define USB_OTG_EP_RX_VALID 0x3000 -/** - * @} - */ -#define MAX_DATA_LENGTH 0xFF - -/** @defgroup USB_CORE_Exported_Types - * @{ - */ - - -typedef enum { - USB_OTG_OK = 0, - USB_OTG_FAIL -}USB_OTG_STS; - -typedef enum { - HC_IDLE = 0, - HC_XFRC, - HC_HALTED, - HC_NAK, - HC_NYET, - HC_STALL, - HC_XACTERR, - HC_BBLERR, - HC_DATATGLERR, -}HC_STATUS; - -typedef enum { - URB_IDLE = 0, - URB_DONE, - URB_NOTREADY, - URB_ERROR, - URB_STALL -}URB_STATE; - -typedef enum { - CTRL_START = 0, - CTRL_XFRC, - CTRL_HALTED, - CTRL_NAK, - CTRL_STALL, - CTRL_XACTERR, - CTRL_BBLERR, - CTRL_DATATGLERR, - CTRL_FAIL -}CTRL_STATUS; - - -typedef struct USB_OTG_hc -{ - uint8_t dev_addr ; - uint8_t ep_num; - uint8_t ep_is_in; - uint8_t speed; - uint8_t do_ping; - uint8_t ep_type; - uint16_t max_packet; - uint8_t data_pid; - uint8_t *xfer_buff; - uint32_t xfer_len; - uint32_t xfer_count; - uint8_t toggle_in; - uint8_t toggle_out; - uint32_t dma_addr; -} -USB_OTG_HC , *PUSB_OTG_HC; - -typedef struct USB_OTG_ep -{ - uint8_t num; - uint8_t is_in; - uint8_t is_stall; - uint8_t type; - uint8_t data_pid_start; - uint8_t even_odd_frame; - uint16_t tx_fifo_num; - uint32_t maxpacket; - /* transaction level variables*/ - uint8_t *xfer_buff; - uint32_t dma_addr; - uint32_t xfer_len; - uint32_t xfer_count; - /* Transfer level variables*/ - uint32_t rem_data_len; - uint32_t total_data_len; - uint32_t ctl_data_len; - -} - -USB_OTG_EP , *PUSB_OTG_EP; - - - -typedef struct USB_OTG_core_cfg -{ - uint8_t host_channels; - uint8_t dev_endpoints; - uint8_t speed; - uint8_t dma_enable; - uint16_t mps; - uint16_t TotalFifoSize; - uint8_t phy_itface; - uint8_t Sof_output; - uint8_t low_power; - uint8_t coreID; - -} -USB_OTG_CORE_CFGS, *PUSB_OTG_CORE_CFGS; - - - -typedef struct usb_setup_req { - - uint8_t bmRequest; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -} USB_SETUP_REQ; - -typedef struct _Device_TypeDef -{ - uint8_t *(*GetDeviceDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetLangIDStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetManufacturerStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetProductStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetSerialStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetConfigurationStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetInterfaceStrDescriptor)( uint8_t speed , uint16_t *length); -} USBD_DEVICE, *pUSBD_DEVICE; - -typedef struct USB_OTG_hPort -{ - void (*Disconnect) (void *phost); - void (*Connect) (void *phost); - uint8_t ConnStatus; - uint8_t DisconnStatus; - uint8_t ConnHandled; - uint8_t DisconnHandled; -} USB_OTG_hPort_TypeDef; - -typedef struct _Device_cb -{ - uint8_t (*Init) (void *pdev , uint8_t cfgidx); - uint8_t (*DeInit) (void *pdev , uint8_t cfgidx); - /* Control Endpoints*/ - uint8_t (*Setup) (void *pdev , USB_SETUP_REQ *req); - uint8_t (*EP0_TxSent) (void *pdev ); - uint8_t (*EP0_RxReady) (void *pdev ); - /* Class Specific Endpoints*/ - uint8_t (*DataIn) (void *pdev , uint8_t epnum); - uint8_t (*DataOut) (void *pdev , uint8_t epnum); - uint8_t (*SOF) (void *pdev); - uint8_t (*IsoINIncomplete) (void *pdev); - uint8_t (*IsoOUTIncomplete) (void *pdev); - - uint8_t *(*GetConfigDescriptor)( uint8_t speed , uint16_t *length); -#ifdef USB_OTG_HS_CORE - uint8_t *(*GetOtherConfigDescriptor)( uint8_t speed , uint16_t *length); -#endif - -#ifdef USB_SUPPORT_USER_STRING_DESC - uint8_t *(*GetUsrStrDescriptor)( uint8_t speed ,uint8_t index, uint16_t *length); -#endif - -} USBD_Class_cb_TypeDef; - - - -typedef struct _USBD_USR_PROP -{ - void (*Init)(void); - void (*DeviceReset)(uint8_t speed); - void (*DeviceConfigured)(void); - void (*DeviceSuspended)(void); - void (*DeviceResumed)(void); - - void (*DeviceConnected)(void); - void (*DeviceDisconnected)(void); - -} -USBD_Usr_cb_TypeDef; - -typedef struct _DCD -{ - uint8_t device_config; - uint8_t device_state; - uint8_t device_status; - uint8_t device_address; - uint32_t DevRemoteWakeup; - USB_OTG_EP in_ep [USB_OTG_MAX_TX_FIFOS]; - USB_OTG_EP out_ep [USB_OTG_MAX_TX_FIFOS]; - uint8_t setup_packet [8*3]; - USBD_Class_cb_TypeDef *class_cb; - USBD_Usr_cb_TypeDef *usr_cb; - USBD_DEVICE *usr_device; - uint8_t *pConfig_descriptor; - } -DCD_DEV , *DCD_PDEV; - - -typedef struct _HCD -{ - uint8_t Rx_Buffer [MAX_DATA_LENGTH]; - __IO uint32_t ConnSts; - __IO uint32_t ErrCnt[USB_OTG_MAX_TX_FIFOS]; - __IO uint32_t XferCnt[USB_OTG_MAX_TX_FIFOS]; - __IO HC_STATUS HC_Status[USB_OTG_MAX_TX_FIFOS]; - __IO URB_STATE URB_State[USB_OTG_MAX_TX_FIFOS]; - USB_OTG_HC hc [USB_OTG_MAX_TX_FIFOS]; - uint16_t channel [USB_OTG_MAX_TX_FIFOS]; - USB_OTG_hPort_TypeDef *port_cb; -} -HCD_DEV , *USB_OTG_USBH_PDEV; - - -typedef struct _OTG -{ - uint8_t OTG_State; - uint8_t OTG_PrevState; - uint8_t OTG_Mode; -} -OTG_DEV , *USB_OTG_USBO_PDEV; - -typedef struct USB_OTG_handle -{ - USB_OTG_CORE_CFGS cfg; - USB_OTG_CORE_REGS regs; -#ifdef USE_DEVICE_MODE - DCD_DEV dev; -#endif -#ifdef USE_HOST_MODE - HCD_DEV host; -#endif -#ifdef USE_OTG_MODE - OTG_DEV otg; -#endif -} -USB_OTG_CORE_HANDLE , *PUSB_OTG_CORE_HANDLE; - -/** - * @} - */ - - -/** @defgroup USB_CORE_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_FunctionsPrototype - * @{ - */ - - -USB_OTG_STS USB_OTG_CoreInit (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_SelectCore (USB_OTG_CORE_HANDLE *pdev, - USB_OTG_CORE_ID_TypeDef coreID); -USB_OTG_STS USB_OTG_EnableGlobalInt (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev); -void* USB_OTG_ReadPacket (USB_OTG_CORE_HANDLE *pdev , - uint8_t *dest, - uint16_t len); -USB_OTG_STS USB_OTG_WritePacket (USB_OTG_CORE_HANDLE *pdev , - uint8_t *src, - uint8_t ch_ep_num, - uint16_t len); -USB_OTG_STS USB_OTG_FlushTxFifo (USB_OTG_CORE_HANDLE *pdev , uint32_t num); -USB_OTG_STS USB_OTG_FlushRxFifo (USB_OTG_CORE_HANDLE *pdev); - -uint32_t USB_OTG_ReadCoreItr (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ReadOtgItr (USB_OTG_CORE_HANDLE *pdev); -uint8_t USB_OTG_IsHostMode (USB_OTG_CORE_HANDLE *pdev); -uint8_t USB_OTG_IsDeviceMode (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_GetMode (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_PhyInit (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_SetCurrentMode (USB_OTG_CORE_HANDLE *pdev, - uint8_t mode); - -/*********************** HOST APIs ********************************************/ -#ifdef USE_HOST_MODE -USB_OTG_STS USB_OTG_CoreInitHost (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_EnableHostInt (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_HC_Init (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num); -USB_OTG_STS USB_OTG_HC_Halt (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num); -USB_OTG_STS USB_OTG_HC_StartXfer (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num); -USB_OTG_STS USB_OTG_HC_DoPing (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num); -uint32_t USB_OTG_ReadHostAllChannels_intr (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ResetPort (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ReadHPRT0 (USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state); -void USB_OTG_InitFSLSPClkSel (USB_OTG_CORE_HANDLE *pdev ,uint8_t freq); -uint8_t USB_OTG_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev) ; -void USB_OTG_StopHost (USB_OTG_CORE_HANDLE *pdev); -#endif -/********************* DEVICE APIs ********************************************/ -#ifdef USE_DEVICE_MODE -USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_EnableDevInt (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ReadDevAllInEPItr (USB_OTG_CORE_HANDLE *pdev); -enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_EP0Activate (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_EPActivate (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EPStartXfer (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EPSetStall (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EPClearStall (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -uint32_t USB_OTG_ReadDevAllOutEp_itr (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ReadDevOutEP_itr (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); -uint32_t USB_OTG_ReadDevAllInEPItr (USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_InitDevSpeed (USB_OTG_CORE_HANDLE *pdev , uint8_t speed); -uint8_t USBH_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status); -uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep); -#endif -/** - * @} - */ - -#endif /* __USB_CORE_H__ */ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/Projects/discovery_demo/usbd_conf.h b/example/stm32f4/Projects/discovery_demo/usbd_conf.h deleted file mode 100644 index 3ff02b665..000000000 --- a/example/stm32f4/Projects/discovery_demo/usbd_conf.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_conf.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief USB Device configuration file - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CONF__H__ -#define __USBD_CONF__H__ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4_discovery.h" - -/** @defgroup USB_CONF_Exported_Defines - * @{ - */ - - -#define USBD_CFG_MAX_NUM 1 -#define USBD_ITF_MAX_NUM 1 - -#define USB_MAX_STR_DESC_SIZ 64 - - - -#define USBD_DYNAMIC_DESCRIPTOR_CHANGE_ENABLED - -/** @defgroup USB_String_Descriptors - * @{ - */ - - -/** @defgroup USB_HID_Class_Layer_Parameter - * @{ - */ -#define HID_IN_EP 0x81 -#define HID_OUT_EP 0x01 - -#define HID_IN_PACKET 4 -#define HID_OUT_PACKET 4 - -/** - * @} - */ -/** @defgroup USB_CONF_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_CONF_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -#endif //__USBD_CONF__H__ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/Projects/discovery_demo/usbd_desc.c b/example/stm32f4/Projects/discovery_demo/usbd_desc.c deleted file mode 100644 index ff9b6701b..000000000 --- a/example/stm32f4/Projects/discovery_demo/usbd_desc.c +++ /dev/null @@ -1,313 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_desc.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file provides the USBD descriptors and string formating method. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_core.h" -#include "usbd_desc.h" -#include "usbd_req.h" -#include "usbd_conf.h" -#include "usb_regs.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup USBD_DESC - * @brief USBD descriptors module - * @{ - */ - -/** @defgroup USBD_DESC_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_DESC_Private_Defines - * @{ - */ - -#define USBD_VID 0x0483 -#define USBD_PID 0x5710 - -#define USBD_LANGID_STRING 0x409 -#define USBD_MANUFACTURER_STRING "STMicroelectronics" - -#define USBD_PRODUCT_HS_STRING "Joystick in HS mode" -#define USBD_SERIALNUMBER_HS_STRING "00000000011B" - -#define USBD_PRODUCT_FS_STRING "Joystick in FS Mode" -#define USBD_SERIALNUMBER_FS_STRING "00000000011C" - -#define USBD_CONFIGURATION_HS_STRING "HID Config" -#define USBD_INTERFACE_HS_STRING "HID Interface" - -#define USBD_CONFIGURATION_FS_STRING "HID Config" -#define USBD_INTERFACE_FS_STRING "HID Interface" -/** - * @} - */ - - -/** @defgroup USBD_DESC_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_DESC_Private_Variables - * @{ - */ - -USBD_DEVICE USR_desc = -{ - USBD_USR_DeviceDescriptor, - USBD_USR_LangIDStrDescriptor, - USBD_USR_ManufacturerStrDescriptor, - USBD_USR_ProductStrDescriptor, - USBD_USR_SerialStrDescriptor, - USBD_USR_ConfigStrDescriptor, - USBD_USR_InterfaceStrDescriptor, - -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* USB Standard Device Descriptor */ -__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_SIZ_DEVICE_DESC] __ALIGN_END = - { - 0x12, /*bLength */ - USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/ - 0x00, /*bcdUSB */ - 0x02, - 0x00, /*bDeviceClass*/ - 0x00, /*bDeviceSubClass*/ - 0x00, /*bDeviceProtocol*/ - USB_OTG_MAX_EP0_SIZE, /*bMaxPacketSize*/ - LOBYTE(USBD_VID), /*idVendor*/ - HIBYTE(USBD_VID), /*idVendor*/ - LOBYTE(USBD_PID), /*idVendor*/ - HIBYTE(USBD_PID), /*idVendor*/ - 0x00, /*bcdDevice rel. 2.00*/ - 0x02, - USBD_IDX_MFC_STR, /*Index of manufacturer string*/ - USBD_IDX_PRODUCT_STR, /*Index of product string*/ - USBD_IDX_SERIAL_STR, /*Index of serial number string*/ - USBD_CFG_MAX_NUM /*bNumConfigurations*/ - } ; /* USB_DeviceDescriptor */ - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* USB Standard Device Descriptor */ -__ALIGN_BEGIN uint8_t USBD_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = -{ - USB_LEN_DEV_QUALIFIER_DESC, - USB_DESC_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x01, - 0x00, -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* USB Standard Device Descriptor */ -__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID] __ALIGN_END = -{ - USB_SIZ_STRING_LANGID, - USB_DESC_TYPE_STRING, - LOBYTE(USBD_LANGID_STRING), - HIBYTE(USBD_LANGID_STRING), -}; -/** - * @} - */ - - -/** @defgroup USBD_DESC_Private_FunctionPrototypes - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_DESC_Private_Functions - * @{ - */ - -/** -* @brief USBD_USR_DeviceDescriptor -* return the device descriptor -* @param speed : current device speed -* @param length : pointer to data length variable -* @retval pointer to descriptor buffer -*/ -uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length) -{ - *length = sizeof(USBD_DeviceDesc); - return USBD_DeviceDesc; -} - -/** -* @brief USBD_USR_LangIDStrDescriptor -* return the LangID string descriptor -* @param speed : current device speed -* @param length : pointer to data length variable -* @retval pointer to descriptor buffer -*/ -uint8_t * USBD_USR_LangIDStrDescriptor( uint8_t speed , uint16_t *length) -{ - *length = sizeof(USBD_LangIDDesc); - return USBD_LangIDDesc; -} - - -/** -* @brief USBD_USR_ProductStrDescriptor -* return the product string descriptor -* @param speed : current device speed -* @param length : pointer to data length variable -* @retval pointer to descriptor buffer -*/ -uint8_t * USBD_USR_ProductStrDescriptor( uint8_t speed , uint16_t *length) -{ - - - if(speed == 0) - { - USBD_GetString (USBD_PRODUCT_HS_STRING, USBD_StrDesc, length); - } - else - { - USBD_GetString (USBD_PRODUCT_FS_STRING, USBD_StrDesc, length); - } - return USBD_StrDesc; -} - -/** -* @brief USBD_USR_ManufacturerStrDescriptor -* return the manufacturer string descriptor -* @param speed : current device speed -* @param length : pointer to data length variable -* @retval pointer to descriptor buffer -*/ -uint8_t * USBD_USR_ManufacturerStrDescriptor( uint8_t speed , uint16_t *length) -{ - USBD_GetString (USBD_MANUFACTURER_STRING, USBD_StrDesc, length); - return USBD_StrDesc; -} - -/** -* @brief USBD_USR_SerialStrDescriptor -* return the serial number string descriptor -* @param speed : current device speed -* @param length : pointer to data length variable -* @retval pointer to descriptor buffer -*/ -uint8_t * USBD_USR_SerialStrDescriptor( uint8_t speed , uint16_t *length) -{ - if(speed == USB_OTG_SPEED_HIGH) - { - USBD_GetString (USBD_SERIALNUMBER_HS_STRING, USBD_StrDesc, length); - } - else - { - USBD_GetString (USBD_SERIALNUMBER_FS_STRING, USBD_StrDesc, length); - } - return USBD_StrDesc; -} - -/** -* @brief USBD_USR_ConfigStrDescriptor -* return the configuration string descriptor -* @param speed : current device speed -* @param length : pointer to data length variable -* @retval pointer to descriptor buffer -*/ -uint8_t * USBD_USR_ConfigStrDescriptor( uint8_t speed , uint16_t *length) -{ - if(speed == USB_OTG_SPEED_HIGH) - { - USBD_GetString (USBD_CONFIGURATION_HS_STRING, USBD_StrDesc, length); - } - else - { - USBD_GetString (USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length); - } - return USBD_StrDesc; -} - - -/** -* @brief USBD_USR_InterfaceStrDescriptor -* return the interface string descriptor -* @param speed : current device speed -* @param length : pointer to data length variable -* @retval pointer to descriptor buffer -*/ -uint8_t * USBD_USR_InterfaceStrDescriptor( uint8_t speed , uint16_t *length) -{ - if(speed == 0) - { - USBD_GetString (USBD_INTERFACE_HS_STRING, USBD_StrDesc, length); - } - else - { - USBD_GetString (USBD_INTERFACE_FS_STRING, USBD_StrDesc, length); - } - return USBD_StrDesc; -} - -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/Projects/discovery_demo/usbd_desc.h b/example/stm32f4/Projects/discovery_demo/usbd_desc.h deleted file mode 100644 index ed999dc62..000000000 --- a/example/stm32f4/Projects/discovery_demo/usbd_desc.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_desc.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief header file for the usbd_desc.c file - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef __USB_DESC_H -#define __USB_DESC_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USB_DESC - * @brief general defines for the usb device library file - * @{ - */ - -/** @defgroup USB_DESC_Exported_Defines - * @{ - */ -#define USB_DEVICE_DESCRIPTOR_TYPE 0x01 -#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02 -#define USB_STRING_DESCRIPTOR_TYPE 0x03 -#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04 -#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05 -#define USB_SIZ_DEVICE_DESC 18 -#define USB_SIZ_STRING_LANGID 4 - -/** - * @} - */ - - -/** @defgroup USBD_DESC_Exported_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USBD_DESC_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_DESC_Exported_Variables - * @{ - */ -extern uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC]; -extern uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ]; -extern uint8_t USBD_OtherSpeedCfgDesc[USB_LEN_CFG_DESC]; -extern uint8_t USBD_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC]; -extern uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID]; -extern USBD_DEVICE USR_desc; -/** - * @} - */ - -/** @defgroup USBD_DESC_Exported_FunctionsPrototype - * @{ - */ - - -uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length); -uint8_t * USBD_USR_LangIDStrDescriptor( uint8_t speed , uint16_t *length); -uint8_t * USBD_USR_ManufacturerStrDescriptor ( uint8_t speed , uint16_t *length); -uint8_t * USBD_USR_ProductStrDescriptor ( uint8_t speed , uint16_t *length); -uint8_t * USBD_USR_SerialStrDescriptor( uint8_t speed , uint16_t *length); -uint8_t * USBD_USR_ConfigStrDescriptor( uint8_t speed , uint16_t *length); -uint8_t * USBD_USR_InterfaceStrDescriptor( uint8_t speed , uint16_t *length); - -#ifdef USB_SUPPORT_USER_STRING_DESC -uint8_t * USBD_USR_USRStringDesc (uint8_t speed, uint8_t idx , uint16_t *length); -#endif /* USB_SUPPORT_USER_STRING_DESC */ - -/** - * @} - */ - -#endif /* __USBD_DESC_H */ - -/** - * @} - */ - -/** -* @} -*/ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Projects/discovery_demo/usbd_usr.c b/example/stm32f4/Projects/discovery_demo/usbd_usr.c deleted file mode 100644 index 6ebd1579d..000000000 --- a/example/stm32f4/Projects/discovery_demo/usbd_usr.c +++ /dev/null @@ -1,238 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_usr.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file includes the user application layer - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_usr.h" -#include "usbd_ioreq.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY -* @{ -*/ - -/** @defgroup USBD_USR -* @brief This file includes the user application layer -* @{ -*/ - -/** @defgroup USBD_USR_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBD_USR_Private_Defines -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBD_USR_Private_Macros -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBD_USR_Private_Variables -* @{ -*/ - -USBD_Usr_cb_TypeDef USR_cb = -{ - USBD_USR_Init, - USBD_USR_DeviceReset, - USBD_USR_DeviceConfigured, - USBD_USR_DeviceSuspended, - USBD_USR_DeviceResumed, - - USBD_USR_DeviceConnected, - USBD_USR_DeviceDisconnected, - - -}; - - - -/** -* @} -*/ - -/** @defgroup USBD_USR_Private_Constants -* @{ -*/ - -/** -* @} -*/ - - - -/** @defgroup USBD_USR_Private_FunctionPrototypes -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBD_USR_Private_Functions -* @{ -*/ - -/** -* @brief USBD_USR_Init -* Displays the message on LCD for host lib initialization -* @param None -* @retval None -*/ -void USBD_USR_Init(void) -{ - /* Setup SysTick Timer for 40 msec interrupts - This interrupt is used to probe the joystick */ - if (SysTick_Config(SystemCoreClock / 24)) - { - /* Capture error */ - while (1); - } -} - -/** -* @brief USBD_USR_DeviceReset -* Displays the message on LCD on device Reset Event -* @param speed : device speed -* @retval None -*/ -void USBD_USR_DeviceReset(uint8_t speed ) -{ - switch (speed) - { - case USB_OTG_SPEED_HIGH: - break; - - case USB_OTG_SPEED_FULL: - break; - default: - break; - - } -} - - -/** -* @brief USBD_USR_DeviceConfigured -* Displays the message on LCD on device configuration Event -* @param None -* @retval Staus -*/ -void USBD_USR_DeviceConfigured (void) -{ -} - - -/** -* @brief USBD_USR_DeviceConnected -* Displays the message on LCD on device connection Event -* @param None -* @retval Staus -*/ -void USBD_USR_DeviceConnected (void) -{ -} - - -/** -* @brief USBD_USR_DeviceDisonnected -* Displays the message on LCD on device disconnection Event -* @param None -* @retval Staus -*/ -void USBD_USR_DeviceDisconnected (void) -{ -} - -/** -* @brief USBD_USR_DeviceSuspended -* Displays the message on LCD on device suspend Event -* @param None -* @retval None -*/ -void USBD_USR_DeviceSuspended(void) -{ - /* Users can do their application actions here for the USB-Reset */ -} - - -/** -* @brief USBD_USR_DeviceResumed -* Displays the message on LCD on device resume Event -* @param None -* @retval None -*/ -void USBD_USR_DeviceResumed(void) -{ - /* Users can do their application actions here for the USB-Reset */ -} - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/build/Makefile b/example/stm32f4/STM32F4xx_StdPeriph_Driver/build/Makefile deleted file mode 100644 index 1506b0ed3..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/build/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -LIB = libSTM32F4xx_StdPeriph_Driver.a - -CC = arm-none-eabi-gcc -AR = arm-none-eabi-ar -RANLIB = arm-none-eabi-ranlib - -CFLAGS = -Wall -O2 -mlittle-endian -mthumb -CFLAGS += -mcpu=cortex-m4 -ffreestanding -nostdlib -CFLAGS += -I../inc -I../inc/device_support -I../inc/core_support - -SRCS = \ -../src/misc.c \ -../src/stm32f4xx_adc.c \ -../src/stm32f4xx_can.c \ -../src/stm32f4xx_crc.c \ -../src/stm32f4xx_cryp_aes.c \ -../src/stm32f4xx_cryp_des.c \ -../src/stm32f4xx_cryp_tdes.c \ -../src/stm32f4xx_cryp_des.c \ -../src/stm32f4xx_dac.c \ -../src/stm32f4xx_dbgmcu.c \ -../src/stm32f4xx_dcmi.c \ -../src/stm32f4xx_dma.c \ -../src/stm32f4xx_exti.c \ -../src/stm32f4xx_flash.c \ -../src/stm32f4xx_fsmc.c \ -../src/stm32f4xx_gpio.c \ -../src/stm32f4xx_hash_md5.c \ -../src/stm32f4xx_hash_sha1.c \ -../src/stm32f4xx_hash.c \ -../src/stm32f4xx_i2c.c \ -../src/stm32f4xx_iwdg.c \ -../src/stm32f4xx_pwr.c \ -../src/stm32f4xx_rcc.c \ -../src/stm32f4xx_rng.c \ -../src/stm32f4xx_rtc.c \ -../src/stm32f4xx_sdio.c \ -../src/stm32f4xx_spi.c \ -../src/stm32f4xx_syscfg.c \ -../src/stm32f4xx_tim.c \ -../src/stm32f4xx_usart.c \ -../src/stm32f4xx_wwdg.c \ -#../inc/core_support/core_cm4.c - -OBJS = $(SRCS:.c=.o) - -all: $(LIB) - -$(LIB): $(OBJS) - $(AR) -r $(LIB) $(OBJS) - $(RANLIB) $(LIB) - -%.o : %.c - $(CC) $(CFLAGS) -c -o $@ $^ - -clean: - -rm -f $(OBJS) - -rm -f $(LIB) - -.PHONY: all clean diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/arm_common_tables.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/arm_common_tables.h deleted file mode 100644 index 7245c4f12..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/arm_common_tables.h +++ /dev/null @@ -1,35 +0,0 @@ -/* ---------------------------------------------------------------------- -* Copyright (C) 2010 ARM Limited. All rights reserved. -* -* $Date: 11. November 2010 -* $Revision: V1.0.2 -* -* Project: CMSIS DSP Library -* Title: arm_common_tables.h -* -* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions -* -* Target Processor: Cortex-M4/Cortex-M3 -* -* Version 1.0.2 2010/11/11 -* Documentation updated. -* -* Version 1.0.1 2010/10/05 -* Production release and review comments incorporated. -* -* Version 1.0.0 2010/09/20 -* Production release and review comments incorporated. -* -------------------------------------------------------------------- */ - -#ifndef _ARM_COMMON_TABLES_H -#define _ARM_COMMON_TABLES_H - -#include "arm_math.h" - -extern uint16_t armBitRevTable[256]; -extern q15_t armRecipTableQ15[64]; -extern q31_t armRecipTableQ31[64]; -extern const q31_t realCoefAQ31[1024]; -extern const q31_t realCoefBQ31[1024]; - -#endif /* ARM_COMMON_TABLES_H */ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/arm_math.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/arm_math.h deleted file mode 100644 index ffa03b6fd..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/arm_math.h +++ /dev/null @@ -1,7051 +0,0 @@ -/* ---------------------------------------------------------------------- - * Copyright (C) 2010 ARM Limited. All rights reserved. - * - * $Date: 15. July 2011 - * $Revision: V1.0.10 - * - * Project: CMSIS DSP Library - * Title: arm_math.h - * - * Description: Public header file for CMSIS DSP Library - * - * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0 - * - * Version 1.0.10 2011/7/15 - * Big Endian support added and Merged M0 and M3/M4 Source code. - * - * Version 1.0.3 2010/11/29 - * Re-organized the CMSIS folders and updated documentation. - * - * Version 1.0.2 2010/11/11 - * Documentation updated. - * - * Version 1.0.1 2010/10/05 - * Production release and review comments incorporated. - * - * Version 1.0.0 2010/09/20 - * Production release and review comments incorporated. - * -------------------------------------------------------------------- */ - -/** - \mainpage CMSIS DSP Software Library - * - * Introduction - * - * This user manual describes the CMSIS DSP software library, - * a suite of common signal processing functions for use on Cortex-M processor based devices. - * - * The library is divided into a number of modules each covering a specific category: - * - Basic math functions - * - Fast math functions - * - Complex math functions - * - Filters - * - Matrix functions - * - Transforms - * - Motor control functions - * - Statistical functions - * - Support functions - * - Interpolation functions - * - * The library has separate functions for operating on 8-bit integers, 16-bit integers, - * 32-bit integer and 32-bit floating-point values. - * - * Processor Support - * - * The library is completely written in C and is fully CMSIS compliant. - * High performance is achieved through maximum use of Cortex-M4 intrinsics. - * - * The supplied library source code also builds and runs on the Cortex-M3 and Cortex-M0 processor, - * with the DSP intrinsics being emulated through software. - * - * - * Toolchain Support - * - * The library has been developed and tested with MDK-ARM version 4.21. - * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. - * - * Using the Library - * - * The library installer contains prebuilt versions of the libraries in the Lib folder. - * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4) - * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4) - * - arm_cortexM4l_math.lib (Little endian on Cortex-M4) - * - arm_cortexM4b_math.lib (Big endian on Cortex-M4) - * - arm_cortexM3l_math.lib (Little endian on Cortex-M3) - * - arm_cortexM3b_math.lib (Big endian on Cortex-M3) - * - arm_cortexM0l_math.lib (Little endian on Cortex-M0) - * - arm_cortexM0b_math.lib (Big endian on Cortex-M3) - * - * The library functions are declared in the public file arm_math.h which is placed in the Include folder. - * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single - * public header file arm_math.h for Cortex-M4/M3/M0 with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. - * Define the appropriate pre processor MACRO ARM_MATH_CM4 or ARM_MATH_CM3 or - * ARM_MATH_CM0 depending on the target processor in the application. - * - * Examples - * - * The library ships with a number of examples which demonstrate how to use the library functions. - * - * Building the Library - * - * The library installer contains project files to re build libraries on MDK Tool chain in the CMSIS\DSP_Lib\Source\ARM folder. - * - arm_cortexM0b_math.uvproj - * - arm_cortexM0l_math.uvproj - * - arm_cortexM3b_math.uvproj - * - arm_cortexM3l_math.uvproj - * - arm_cortexM4b_math.uvproj - * - arm_cortexM4l_math.uvproj - * - arm_cortexM4bf_math.uvproj - * - arm_cortexM4lf_math.uvproj - * - * Each library project have differant pre-processor macros. - * - * ARM_MATH_CMx: - * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target - * and ARM_MATH_CM0 for building library on cortex-M0 target. - * - * ARM_MATH_BIG_ENDIAN: - * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. - * - * ARM_MATH_MATRIX_CHECK: - * Define macro for checking on the input and output sizes of matrices - * - * ARM_MATH_ROUNDING: - * Define macro for rounding on support functions - * - * __FPU_PRESENT: - * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries - * - * - * The project can be built by opening the appropriate project in MDK-ARM 4.21 chain and defining the optional pre processor MACROs detailed above. - * - * Copyright Notice - * - * Copyright (C) 2010 ARM Limited. All rights reserved. - */ - - -/** - * @defgroup groupMath Basic Math Functions - */ - -/** - * @defgroup groupFastMath Fast Math Functions - * This set of functions provides a fast approximation to sine, cosine, and square root. - * As compared to most of the other functions in the CMSIS math library, the fast math functions - * operate on individual values and not arrays. - * There are separate functions for Q15, Q31, and floating-point data. - * - */ - -/** - * @defgroup groupCmplxMath Complex Math Functions - * This set of functions operates on complex data vectors. - * The data in the complex arrays is stored in an interleaved fashion - * (real, imag, real, imag, ...). - * In the API functions, the number of samples in a complex array refers - * to the number of complex values; the array contains twice this number of - * real values. - */ - -/** - * @defgroup groupFilters Filtering Functions - */ - -/** - * @defgroup groupMatrix Matrix Functions - * - * This set of functions provides basic matrix math operations. - * The functions operate on matrix data structures. For example, - * the type - * definition for the floating-point matrix structure is shown - * below: - *
- *     typedef struct
- *     {
- *       uint16_t numRows;     // number of rows of the matrix.
- *       uint16_t numCols;     // number of columns of the matrix.
- *       float32_t *pData;     // points to the data of the matrix.
- *     } arm_matrix_instance_f32;
- * 
- * There are similar definitions for Q15 and Q31 data types. - * - * The structure specifies the size of the matrix and then points to - * an array of data. The array is of size numRows X numCols - * and the values are arranged in row order. That is, the - * matrix element (i, j) is stored at: - *
- *     pData[i*numCols + j]
- * 
- * - * \par Init Functions - * There is an associated initialization function for each type of matrix - * data structure. - * The initialization function sets the values of the internal structure fields. - * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() - * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. - * - * \par - * Use of the initialization function is optional. However, if initialization function is used - * then the instance structure cannot be placed into a const data section. - * To place the instance structure in a const data - * section, manually initialize the data structure. For example: - *
- * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
- * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
- * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
- * 
- * where nRows specifies the number of rows, nColumns - * specifies the number of columns, and pData points to the - * data array. - * - * \par Size Checking - * By default all of the matrix functions perform size checking on the input and - * output matrices. For example, the matrix addition function verifies that the - * two input matrices and the output matrix all have the same number of rows and - * columns. If the size check fails the functions return: - *
- *     ARM_MATH_SIZE_MISMATCH
- * 
- * Otherwise the functions return - *
- *     ARM_MATH_SUCCESS
- * 
- * There is some overhead associated with this matrix size checking. - * The matrix size checking is enabled via the #define - *
- *     ARM_MATH_MATRIX_CHECK
- * 
- * within the library project settings. By default this macro is defined - * and size checking is enabled. By changing the project settings and - * undefining this macro size checking is eliminated and the functions - * run a bit faster. With size checking disabled the functions always - * return ARM_MATH_SUCCESS. - */ - -/** - * @defgroup groupTransforms Transform Functions - */ - -/** - * @defgroup groupController Controller Functions - */ - -/** - * @defgroup groupStats Statistics Functions - */ -/** - * @defgroup groupSupport Support Functions - */ - -/** - * @defgroup groupInterpolation Interpolation Functions - * These functions perform 1- and 2-dimensional interpolation of data. - * Linear interpolation is used for 1-dimensional data and - * bilinear interpolation is used for 2-dimensional data. - */ - -/** - * @defgroup groupExamples Examples - */ -#ifndef _ARM_MATH_H -#define _ARM_MATH_H - -#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ - -#if defined (ARM_MATH_CM4) - #include "core_cm4.h" -#elif defined (ARM_MATH_CM3) - #include "core_cm3.h" -#elif defined (ARM_MATH_CM0) - #include "core_cm0.h" -#else -#include "ARMCM4.h" -#warning "Define either ARM_MATH_CM4 OR ARM_MATH_CM3...By Default building on ARM_MATH_CM4....." -#endif - -#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ -#include "string.h" - #include "math.h" -#ifdef __cplusplus -extern "C" -{ -#endif - - - /** - * @brief Macros required for reciprocal calculation in Normalized LMS - */ - -#define DELTA_Q31 (0x100) -#define DELTA_Q15 0x5 -#define INDEX_MASK 0x0000003F -#define PI 3.14159265358979f - - /** - * @brief Macros required for SINE and COSINE Fast math approximations - */ - -#define TABLE_SIZE 256 -#define TABLE_SPACING_Q31 0x800000 -#define TABLE_SPACING_Q15 0x80 - - /** - * @brief Macros required for SINE and COSINE Controller functions - */ - /* 1.31(q31) Fixed value of 2/360 */ - /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ -#define INPUT_SPACING 0xB60B61 - - - /** - * @brief Error status returned by some functions in the library. - */ - - typedef enum - { - ARM_MATH_SUCCESS = 0, /**< No error */ - ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ - ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ - ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ - ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ - ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ - ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ - } arm_status; - - /** - * @brief 8-bit fractional data type in 1.7 format. - */ - typedef int8_t q7_t; - - /** - * @brief 16-bit fractional data type in 1.15 format. - */ - typedef int16_t q15_t; - - /** - * @brief 32-bit fractional data type in 1.31 format. - */ - typedef int32_t q31_t; - - /** - * @brief 64-bit fractional data type in 1.63 format. - */ - typedef int64_t q63_t; - - /** - * @brief 32-bit floating-point type definition. - */ - typedef float float32_t; - - /** - * @brief 64-bit floating-point type definition. - */ - typedef double float64_t; - - /** - * @brief definition to read/write two 16 bit values. - */ -#define __SIMD32(addr) (*(int32_t **) & (addr)) - -#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0) - /** - * @brief definition to pack two 16 bit values. - */ -#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ - (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) - -#endif - - - /** - * @brief definition to pack four 8 bit values. - */ -#ifndef ARM_MATH_BIG_ENDIAN - -#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ - (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ - (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ - (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) -#else - -#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ - (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ - (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ - (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) - -#endif - - - /** - * @brief Clips Q63 to Q31 values. - */ - static __INLINE q31_t clip_q63_to_q31( - q63_t x) - { - return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? - ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; - } - - /** - * @brief Clips Q63 to Q15 values. - */ - static __INLINE q15_t clip_q63_to_q15( - q63_t x) - { - return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? - ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); - } - - /** - * @brief Clips Q31 to Q7 values. - */ - static __INLINE q7_t clip_q31_to_q7( - q31_t x) - { - return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? - ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; - } - - /** - * @brief Clips Q31 to Q15 values. - */ - static __INLINE q15_t clip_q31_to_q15( - q31_t x) - { - return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? - ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; - } - - /** - * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. - */ - - static __INLINE q63_t mult32x64( - q63_t x, - q31_t y) - { - return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + - (((q63_t) (x >> 32) * y))); - } - - -#if defined (ARM_MATH_CM0) && defined ( __CC_ARM ) -#define __CLZ __clz -#endif - -#if defined (ARM_MATH_CM0) && ((defined (__ICCARM__)) ||(defined (__GNUC__)) || defined (__TASKING__) ) - - static __INLINE uint32_t __CLZ(q31_t data); - - - static __INLINE uint32_t __CLZ(q31_t data) - { - uint32_t count = 0; - uint32_t mask = 0x80000000; - - while((data & mask) == 0) - { - count += 1u; - mask = mask >> 1u; - } - - return(count); - - } - -#endif - - /** - * @brief Function to Calculates 1/in(reciprocal) value of Q31 Data type. - */ - - static __INLINE uint32_t arm_recip_q31( - q31_t in, - q31_t * dst, - q31_t * pRecipTable) - { - - uint32_t out, tempVal; - uint32_t index, i; - uint32_t signBits; - - if(in > 0) - { - signBits = __CLZ(in) - 1; - } - else - { - signBits = __CLZ(-in) - 1; - } - - /* Convert input sample to 1.31 format */ - in = in << signBits; - - /* calculation of index for initial approximated Val */ - index = (uint32_t) (in >> 24u); - index = (index & INDEX_MASK); - - /* 1.31 with exp 1 */ - out = pRecipTable[index]; - - /* calculation of reciprocal value */ - /* running approximation for two iterations */ - for (i = 0u; i < 2u; i++) - { - tempVal = (q31_t) (((q63_t) in * out) >> 31u); - tempVal = 0x7FFFFFFF - tempVal; - /* 1.31 with exp 1 */ - //out = (q31_t) (((q63_t) out * tempVal) >> 30u); - out = (q31_t) clip_q63_to_q31(((q63_t) out * tempVal) >> 30u); - } - - /* write output */ - *dst = out; - - /* return num of signbits of out = 1/in value */ - return (signBits + 1u); - - } - - /** - * @brief Function to Calculates 1/in(reciprocal) value of Q15 Data type. - */ - static __INLINE uint32_t arm_recip_q15( - q15_t in, - q15_t * dst, - q15_t * pRecipTable) - { - - uint32_t out = 0, tempVal = 0; - uint32_t index = 0, i = 0; - uint32_t signBits = 0; - - if(in > 0) - { - signBits = __CLZ(in) - 17; - } - else - { - signBits = __CLZ(-in) - 17; - } - - /* Convert input sample to 1.15 format */ - in = in << signBits; - - /* calculation of index for initial approximated Val */ - index = in >> 8; - index = (index & INDEX_MASK); - - /* 1.15 with exp 1 */ - out = pRecipTable[index]; - - /* calculation of reciprocal value */ - /* running approximation for two iterations */ - for (i = 0; i < 2; i++) - { - tempVal = (q15_t) (((q31_t) in * out) >> 15); - tempVal = 0x7FFF - tempVal; - /* 1.15 with exp 1 */ - out = (q15_t) (((q31_t) out * tempVal) >> 14); - } - - /* write output */ - *dst = out; - - /* return num of signbits of out = 1/in value */ - return (signBits + 1); - - } - - - /* - * @brief C custom defined intrinisic function for only M0 processors - */ -#if defined(ARM_MATH_CM0) - - static __INLINE q31_t __SSAT( - q31_t x, - uint32_t y) - { - int32_t posMax, negMin; - uint32_t i; - - posMax = 1; - for (i = 0; i < (y - 1); i++) - { - posMax = posMax * 2; - } - - if(x > 0) - { - posMax = (posMax - 1); - - if(x > posMax) - { - x = posMax; - } - } - else - { - negMin = -posMax; - - if(x < negMin) - { - x = negMin; - } - } - return (x); - - - } - -#endif /* end of ARM_MATH_CM0 */ - - - - /* - * @brief C custom defined intrinsic function for M3 and M0 processors - */ -#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0) - - /* - * @brief C custom defined QADD8 for M3 and M0 processors - */ - static __INLINE q31_t __QADD8( - q31_t x, - q31_t y) - { - - q31_t sum; - q7_t r, s, t, u; - - r = (char) x; - s = (char) y; - - r = __SSAT((q31_t) (r + s), 8); - s = __SSAT(((q31_t) (((x << 16) >> 24) + ((y << 16) >> 24))), 8); - t = __SSAT(((q31_t) (((x << 8) >> 24) + ((y << 8) >> 24))), 8); - u = __SSAT(((q31_t) ((x >> 24) + (y >> 24))), 8); - - sum = (((q31_t) u << 24) & 0xFF000000) | (((q31_t) t << 16) & 0x00FF0000) | - (((q31_t) s << 8) & 0x0000FF00) | (r & 0x000000FF); - - return sum; - - } - - /* - * @brief C custom defined QSUB8 for M3 and M0 processors - */ - static __INLINE q31_t __QSUB8( - q31_t x, - q31_t y) - { - - q31_t sum; - q31_t r, s, t, u; - - r = (char) x; - s = (char) y; - - r = __SSAT((r - s), 8); - s = __SSAT(((q31_t) (((x << 16) >> 24) - ((y << 16) >> 24))), 8) << 8; - t = __SSAT(((q31_t) (((x << 8) >> 24) - ((y << 8) >> 24))), 8) << 16; - u = __SSAT(((q31_t) ((x >> 24) - (y >> 24))), 8) << 24; - - sum = - (u & 0xFF000000) | (t & 0x00FF0000) | (s & 0x0000FF00) | (r & 0x000000FF); - - return sum; - } - - /* - * @brief C custom defined QADD16 for M3 and M0 processors - */ - - /* - * @brief C custom defined QADD16 for M3 and M0 processors - */ - static __INLINE q31_t __QADD16( - q31_t x, - q31_t y) - { - - q31_t sum; - q31_t r, s; - - r = (short) x; - s = (short) y; - - r = __SSAT(r + s, 16); - s = __SSAT(((q31_t) ((x >> 16) + (y >> 16))), 16) << 16; - - sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); - - return sum; - - } - - /* - * @brief C custom defined SHADD16 for M3 and M0 processors - */ - static __INLINE q31_t __SHADD16( - q31_t x, - q31_t y) - { - - q31_t sum; - q31_t r, s; - - r = (short) x; - s = (short) y; - - r = ((r >> 1) + (s >> 1)); - s = ((q31_t) ((x >> 17) + (y >> 17))) << 16; - - sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); - - return sum; - - } - - /* - * @brief C custom defined QSUB16 for M3 and M0 processors - */ - static __INLINE q31_t __QSUB16( - q31_t x, - q31_t y) - { - - q31_t sum; - q31_t r, s; - - r = (short) x; - s = (short) y; - - r = __SSAT(r - s, 16); - s = __SSAT(((q31_t) ((x >> 16) - (y >> 16))), 16) << 16; - - sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); - - return sum; - } - - /* - * @brief C custom defined SHSUB16 for M3 and M0 processors - */ - static __INLINE q31_t __SHSUB16( - q31_t x, - q31_t y) - { - - q31_t diff; - q31_t r, s; - - r = (short) x; - s = (short) y; - - r = ((r >> 1) - (s >> 1)); - s = (((x >> 17) - (y >> 17)) << 16); - - diff = (s & 0xFFFF0000) | (r & 0x0000FFFF); - - return diff; - } - - /* - * @brief C custom defined QASX for M3 and M0 processors - */ - static __INLINE q31_t __QASX( - q31_t x, - q31_t y) - { - - q31_t sum = 0; - - sum = ((sum + clip_q31_to_q15((q31_t) ((short) (x >> 16) + (short) y))) << 16) + - clip_q31_to_q15((q31_t) ((short) x - (short) (y >> 16))); - - return sum; - } - - /* - * @brief C custom defined SHASX for M3 and M0 processors - */ - static __INLINE q31_t __SHASX( - q31_t x, - q31_t y) - { - - q31_t sum; - q31_t r, s; - - r = (short) x; - s = (short) y; - - r = ((r >> 1) - (y >> 17)); - s = (((x >> 17) + (s >> 1)) << 16); - - sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); - - return sum; - } - - - /* - * @brief C custom defined QSAX for M3 and M0 processors - */ - static __INLINE q31_t __QSAX( - q31_t x, - q31_t y) - { - - q31_t sum = 0; - - sum = ((sum + clip_q31_to_q15((q31_t) ((short) (x >> 16) - (short) y))) << 16) + - clip_q31_to_q15((q31_t) ((short) x + (short) (y >> 16))); - - return sum; - } - - /* - * @brief C custom defined SHSAX for M3 and M0 processors - */ - static __INLINE q31_t __SHSAX( - q31_t x, - q31_t y) - { - - q31_t sum; - q31_t r, s; - - r = (short) x; - s = (short) y; - - r = ((r >> 1) + (y >> 17)); - s = (((x >> 17) - (s >> 1)) << 16); - - sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); - - return sum; - } - - /* - * @brief C custom defined SMUSDX for M3 and M0 processors - */ - static __INLINE q31_t __SMUSDX( - q31_t x, - q31_t y) - { - - return ((q31_t)(((short) x * (short) (y >> 16)) - - ((short) (x >> 16) * (short) y))); - } - - /* - * @brief C custom defined SMUADX for M3 and M0 processors - */ - static __INLINE q31_t __SMUADX( - q31_t x, - q31_t y) - { - - return ((q31_t)(((short) x * (short) (y >> 16)) + - ((short) (x >> 16) * (short) y))); - } - - /* - * @brief C custom defined QADD for M3 and M0 processors - */ - static __INLINE q31_t __QADD( - q31_t x, - q31_t y) - { - return clip_q63_to_q31((q63_t) x + y); - } - - /* - * @brief C custom defined QSUB for M3 and M0 processors - */ - static __INLINE q31_t __QSUB( - q31_t x, - q31_t y) - { - return clip_q63_to_q31((q63_t) x - y); - } - - /* - * @brief C custom defined SMLAD for M3 and M0 processors - */ - static __INLINE q31_t __SMLAD( - q31_t x, - q31_t y, - q31_t sum) - { - - return (sum + ((short) (x >> 16) * (short) (y >> 16)) + - ((short) x * (short) y)); - } - - /* - * @brief C custom defined SMLADX for M3 and M0 processors - */ - static __INLINE q31_t __SMLADX( - q31_t x, - q31_t y, - q31_t sum) - { - - return (sum + ((short) (x >> 16) * (short) (y)) + - ((short) x * (short) (y >> 16))); - } - - /* - * @brief C custom defined SMLSDX for M3 and M0 processors - */ - static __INLINE q31_t __SMLSDX( - q31_t x, - q31_t y, - q31_t sum) - { - - return (sum - ((short) (x >> 16) * (short) (y)) + - ((short) x * (short) (y >> 16))); - } - - /* - * @brief C custom defined SMLALD for M3 and M0 processors - */ - static __INLINE q63_t __SMLALD( - q31_t x, - q31_t y, - q63_t sum) - { - - return (sum + ((short) (x >> 16) * (short) (y >> 16)) + - ((short) x * (short) y)); - } - - /* - * @brief C custom defined SMLALDX for M3 and M0 processors - */ - static __INLINE q63_t __SMLALDX( - q31_t x, - q31_t y, - q63_t sum) - { - - return (sum + ((short) (x >> 16) * (short) y)) + - ((short) x * (short) (y >> 16)); - } - - /* - * @brief C custom defined SMUAD for M3 and M0 processors - */ - static __INLINE q31_t __SMUAD( - q31_t x, - q31_t y) - { - - return (((x >> 16) * (y >> 16)) + - (((x << 16) >> 16) * ((y << 16) >> 16))); - } - - /* - * @brief C custom defined SMUSD for M3 and M0 processors - */ - static __INLINE q31_t __SMUSD( - q31_t x, - q31_t y) - { - - return (-((x >> 16) * (y >> 16)) + - (((x << 16) >> 16) * ((y << 16) >> 16))); - } - - - - -#endif /* (ARM_MATH_CM3) || defined (ARM_MATH_CM0) */ - - - /** - * @brief Instance structure for the Q7 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - } arm_fir_instance_q7; - - /** - * @brief Instance structure for the Q15 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - } arm_fir_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - } arm_fir_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - } arm_fir_instance_f32; - - - /** - * @brief Processing function for the Q7 FIR filter. - * @param[in] *S points to an instance of the Q7 FIR filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_q7( - const arm_fir_instance_q7 * S, - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q7 FIR filter. - * @param[in,out] *S points to an instance of the Q7 FIR structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of samples that are processed. - * @return none - */ - void arm_fir_init_q7( - arm_fir_instance_q7 * S, - uint16_t numTaps, - q7_t * pCoeffs, - q7_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 FIR filter. - * @param[in] *S points to an instance of the Q15 FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_q15( - const arm_fir_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q15 FIR filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_fast_q15( - const arm_fir_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q15 FIR filter. - * @param[in,out] *S points to an instance of the Q15 FIR filter structure. - * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if - * numTaps is not a supported value. - */ - - arm_status arm_fir_init_q15( - arm_fir_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 FIR filter. - * @param[in] *S points to an instance of the Q31 FIR filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_q31( - const arm_fir_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q31 FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_fast_q31( - const arm_fir_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 FIR filter. - * @param[in,out] *S points to an instance of the Q31 FIR structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - * @return none. - */ - void arm_fir_init_q31( - arm_fir_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the floating-point FIR filter. - * @param[in] *S points to an instance of the floating-point FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_f32( - const arm_fir_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point FIR filter. - * @param[in,out] *S points to an instance of the floating-point FIR filter structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - * @return none. - */ - void arm_fir_init_f32( - arm_fir_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q15 Biquad cascade filter. - */ - typedef struct - { - int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ - - } arm_biquad_casd_df1_inst_q15; - - - /** - * @brief Instance structure for the Q31 Biquad cascade filter. - */ - typedef struct - { - uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ - - } arm_biquad_casd_df1_inst_q31; - - /** - * @brief Instance structure for the floating-point Biquad cascade filter. - */ - typedef struct - { - uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - - - } arm_biquad_casd_df1_inst_f32; - - - - /** - * @brief Processing function for the Q15 Biquad cascade filter. - * @param[in] *S points to an instance of the Q15 Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_q15( - const arm_biquad_casd_df1_inst_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q15 Biquad cascade filter. - * @param[in,out] *S points to an instance of the Q15 Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format - * @return none - */ - - void arm_biquad_cascade_df1_init_q15( - arm_biquad_casd_df1_inst_q15 * S, - uint8_t numStages, - q15_t * pCoeffs, - q15_t * pState, - int8_t postShift); - - - /** - * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q15 Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_fast_q15( - const arm_biquad_casd_df1_inst_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 Biquad cascade filter - * @param[in] *S points to an instance of the Q31 Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_q31( - const arm_biquad_casd_df1_inst_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q31 Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_fast_q31( - const arm_biquad_casd_df1_inst_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 Biquad cascade filter. - * @param[in,out] *S points to an instance of the Q31 Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format - * @return none - */ - - void arm_biquad_cascade_df1_init_q31( - arm_biquad_casd_df1_inst_q31 * S, - uint8_t numStages, - q31_t * pCoeffs, - q31_t * pState, - int8_t postShift); - - /** - * @brief Processing function for the floating-point Biquad cascade filter. - * @param[in] *S points to an instance of the floating-point Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_f32( - const arm_biquad_casd_df1_inst_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point Biquad cascade filter. - * @param[in,out] *S points to an instance of the floating-point Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @return none - */ - - void arm_biquad_cascade_df1_init_f32( - arm_biquad_casd_df1_inst_f32 * S, - uint8_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - /** - * @brief Instance structure for the floating-point matrix structure. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - float32_t *pData; /**< points to the data of the matrix. */ - } arm_matrix_instance_f32; - - /** - * @brief Instance structure for the Q15 matrix structure. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - q15_t *pData; /**< points to the data of the matrix. */ - - } arm_matrix_instance_q15; - - /** - * @brief Instance structure for the Q31 matrix structure. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - q31_t *pData; /**< points to the data of the matrix. */ - - } arm_matrix_instance_q31; - - - - /** - * @brief Floating-point matrix addition. - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_add_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - /** - * @brief Q15 matrix addition. - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_add_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst); - - /** - * @brief Q31 matrix addition. - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_add_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix transpose. - * @param[in] *pSrc points to the input matrix - * @param[out] *pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_trans_f32( - const arm_matrix_instance_f32 * pSrc, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15 matrix transpose. - * @param[in] *pSrc points to the input matrix - * @param[out] *pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_trans_q15( - const arm_matrix_instance_q15 * pSrc, - arm_matrix_instance_q15 * pDst); - - /** - * @brief Q31 matrix transpose. - * @param[in] *pSrc points to the input matrix - * @param[out] *pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_trans_q31( - const arm_matrix_instance_q31 * pSrc, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix multiplication - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - /** - * @brief Q15 matrix multiplication - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst, - q15_t * pState); - - /** - * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @param[in] *pState points to the array for storing intermediate results - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_fast_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst, - q15_t * pState); - - /** - * @brief Q31 matrix multiplication - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - /** - * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_fast_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix subtraction - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_sub_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - /** - * @brief Q15 matrix subtraction - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_sub_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst); - - /** - * @brief Q31 matrix subtraction - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_sub_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - /** - * @brief Floating-point matrix scaling. - * @param[in] *pSrc points to the input matrix - * @param[in] scale scale factor - * @param[out] *pDst points to the output matrix - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_scale_f32( - const arm_matrix_instance_f32 * pSrc, - float32_t scale, - arm_matrix_instance_f32 * pDst); - - /** - * @brief Q15 matrix scaling. - * @param[in] *pSrc points to input matrix - * @param[in] scaleFract fractional portion of the scale factor - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to output matrix - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_scale_q15( - const arm_matrix_instance_q15 * pSrc, - q15_t scaleFract, - int32_t shift, - arm_matrix_instance_q15 * pDst); - - /** - * @brief Q31 matrix scaling. - * @param[in] *pSrc points to input matrix - * @param[in] scaleFract fractional portion of the scale factor - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_scale_q31( - const arm_matrix_instance_q31 * pSrc, - q31_t scaleFract, - int32_t shift, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Q31 matrix initialization. - * @param[in,out] *S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] *pData points to the matrix data array. - * @return none - */ - - void arm_mat_init_q31( - arm_matrix_instance_q31 * S, - uint16_t nRows, - uint16_t nColumns, - q31_t *pData); - - /** - * @brief Q15 matrix initialization. - * @param[in,out] *S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] *pData points to the matrix data array. - * @return none - */ - - void arm_mat_init_q15( - arm_matrix_instance_q15 * S, - uint16_t nRows, - uint16_t nColumns, - q15_t *pData); - - /** - * @brief Floating-point matrix initialization. - * @param[in,out] *S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] *pData points to the matrix data array. - * @return none - */ - - void arm_mat_init_f32( - arm_matrix_instance_f32 * S, - uint16_t nRows, - uint16_t nColumns, - float32_t *pData); - - - - /** - * @brief Instance structure for the Q15 PID Control. - */ - typedef struct - { - q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ - #ifdef ARM_MATH_CM0 - q15_t A1; - q15_t A2; - #else - q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ - #endif - q15_t state[3]; /**< The state array of length 3. */ - q15_t Kp; /**< The proportional gain. */ - q15_t Ki; /**< The integral gain. */ - q15_t Kd; /**< The derivative gain. */ - } arm_pid_instance_q15; - - /** - * @brief Instance structure for the Q31 PID Control. - */ - typedef struct - { - q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ - q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ - q31_t A2; /**< The derived gain, A2 = Kd . */ - q31_t state[3]; /**< The state array of length 3. */ - q31_t Kp; /**< The proportional gain. */ - q31_t Ki; /**< The integral gain. */ - q31_t Kd; /**< The derivative gain. */ - - } arm_pid_instance_q31; - - /** - * @brief Instance structure for the floating-point PID Control. - */ - typedef struct - { - float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ - float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ - float32_t A2; /**< The derived gain, A2 = Kd . */ - float32_t state[3]; /**< The state array of length 3. */ - float32_t Kp; /**< The proportional gain. */ - float32_t Ki; /**< The integral gain. */ - float32_t Kd; /**< The derivative gain. */ - } arm_pid_instance_f32; - - - - /** - * @brief Initialization function for the floating-point PID Control. - * @param[in,out] *S points to an instance of the PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - * @return none. - */ - void arm_pid_init_f32( - arm_pid_instance_f32 * S, - int32_t resetStateFlag); - - /** - * @brief Reset function for the floating-point PID Control. - * @param[in,out] *S is an instance of the floating-point PID Control structure - * @return none - */ - void arm_pid_reset_f32( - arm_pid_instance_f32 * S); - - - /** - * @brief Initialization function for the Q31 PID Control. - * @param[in,out] *S points to an instance of the Q15 PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - * @return none. - */ - void arm_pid_init_q31( - arm_pid_instance_q31 * S, - int32_t resetStateFlag); - - - /** - * @brief Reset function for the Q31 PID Control. - * @param[in,out] *S points to an instance of the Q31 PID Control structure - * @return none - */ - - void arm_pid_reset_q31( - arm_pid_instance_q31 * S); - - /** - * @brief Initialization function for the Q15 PID Control. - * @param[in,out] *S points to an instance of the Q15 PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - * @return none. - */ - void arm_pid_init_q15( - arm_pid_instance_q15 * S, - int32_t resetStateFlag); - - /** - * @brief Reset function for the Q15 PID Control. - * @param[in,out] *S points to an instance of the q15 PID Control structure - * @return none - */ - void arm_pid_reset_q15( - arm_pid_instance_q15 * S); - - - /** - * @brief Instance structure for the floating-point Linear Interpolate function. - */ - typedef struct - { - uint32_t nValues; - float32_t x1; - float32_t xSpacing; - float32_t *pYData; /**< pointer to the table of Y values */ - } arm_linear_interp_instance_f32; - - /** - * @brief Instance structure for the floating-point bilinear interpolation function. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - float32_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_f32; - - /** - * @brief Instance structure for the Q31 bilinear interpolation function. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q31_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q31; - - /** - * @brief Instance structure for the Q15 bilinear interpolation function. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q15_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q15; - - /** - * @brief Instance structure for the Q15 bilinear interpolation function. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q7_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q7; - - - /** - * @brief Q7 vector multiplication. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_mult_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Q15 vector multiplication. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_mult_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Q31 vector multiplication. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_mult_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Floating-point vector multiplication. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_mult_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q15 CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q15_t *pTwiddle; /**< points to the twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix4_instance_q15; - - /** - * @brief Instance structure for the Q31 CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q31_t *pTwiddle; /**< points to the twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix4_instance_q31; - - /** - * @brief Instance structure for the floating-point CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - float32_t *pTwiddle; /**< points to the twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - float32_t onebyfftLen; /**< value of 1/fftLen. */ - } arm_cfft_radix4_instance_f32; - - /** - * @brief Processing function for the Q15 CFFT/CIFFT. - * @param[in] *S points to an instance of the Q15 CFFT/CIFFT structure. - * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. - * @return none. - */ - - void arm_cfft_radix4_q15( - const arm_cfft_radix4_instance_q15 * S, - q15_t * pSrc); - - /** - * @brief Initialization function for the Q15 CFFT/CIFFT. - * @param[in,out] *S points to an instance of the Q15 CFFT/CIFFT structure. - * @param[in] fftLen length of the FFT. - * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. - * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value. - */ - - arm_status arm_cfft_radix4_init_q15( - arm_cfft_radix4_instance_q15 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Processing function for the Q31 CFFT/CIFFT. - * @param[in] *S points to an instance of the Q31 CFFT/CIFFT structure. - * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. - * @return none. - */ - - void arm_cfft_radix4_q31( - const arm_cfft_radix4_instance_q31 * S, - q31_t * pSrc); - - /** - * @brief Initialization function for the Q31 CFFT/CIFFT. - * @param[in,out] *S points to an instance of the Q31 CFFT/CIFFT structure. - * @param[in] fftLen length of the FFT. - * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. - * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value. - */ - - arm_status arm_cfft_radix4_init_q31( - arm_cfft_radix4_instance_q31 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Processing function for the floating-point CFFT/CIFFT. - * @param[in] *S points to an instance of the floating-point CFFT/CIFFT structure. - * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. - * @return none. - */ - - void arm_cfft_radix4_f32( - const arm_cfft_radix4_instance_f32 * S, - float32_t * pSrc); - - /** - * @brief Initialization function for the floating-point CFFT/CIFFT. - * @param[in,out] *S points to an instance of the floating-point CFFT/CIFFT structure. - * @param[in] fftLen length of the FFT. - * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. - * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value. - */ - - arm_status arm_cfft_radix4_init_f32( - arm_cfft_radix4_instance_f32 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - - - /*---------------------------------------------------------------------- - * Internal functions prototypes FFT function - ----------------------------------------------------------------------*/ - - /** - * @brief Core function for the floating-point CFFT butterfly process. - * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. - * @param[in] fftLen length of the FFT. - * @param[in] *pCoef points to the twiddle coefficient buffer. - * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. - * @return none. - */ - - void arm_radix4_butterfly_f32( - float32_t * pSrc, - uint16_t fftLen, - float32_t * pCoef, - uint16_t twidCoefModifier); - - /** - * @brief Core function for the floating-point CIFFT butterfly process. - * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. - * @param[in] fftLen length of the FFT. - * @param[in] *pCoef points to twiddle coefficient buffer. - * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. - * @param[in] onebyfftLen value of 1/fftLen. - * @return none. - */ - - void arm_radix4_butterfly_inverse_f32( - float32_t * pSrc, - uint16_t fftLen, - float32_t * pCoef, - uint16_t twidCoefModifier, - float32_t onebyfftLen); - - /** - * @brief In-place bit reversal function. - * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. - * @param[in] fftSize length of the FFT. - * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table. - * @param[in] *pBitRevTab points to the bit reversal table. - * @return none. - */ - - void arm_bitreversal_f32( - float32_t *pSrc, - uint16_t fftSize, - uint16_t bitRevFactor, - uint16_t *pBitRevTab); - - /** - * @brief Core function for the Q31 CFFT butterfly process. - * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. - * @param[in] fftLen length of the FFT. - * @param[in] *pCoef points to twiddle coefficient buffer. - * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. - * @return none. - */ - - void arm_radix4_butterfly_q31( - q31_t *pSrc, - uint32_t fftLen, - q31_t *pCoef, - uint32_t twidCoefModifier); - - /** - * @brief Core function for the Q31 CIFFT butterfly process. - * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. - * @param[in] fftLen length of the FFT. - * @param[in] *pCoef points to twiddle coefficient buffer. - * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. - * @return none. - */ - - void arm_radix4_butterfly_inverse_q31( - q31_t * pSrc, - uint32_t fftLen, - q31_t * pCoef, - uint32_t twidCoefModifier); - - /** - * @brief In-place bit reversal function. - * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. - * @param[in] fftLen length of the FFT. - * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table - * @param[in] *pBitRevTab points to bit reversal table. - * @return none. - */ - - void arm_bitreversal_q31( - q31_t * pSrc, - uint32_t fftLen, - uint16_t bitRevFactor, - uint16_t *pBitRevTab); - - /** - * @brief Core function for the Q15 CFFT butterfly process. - * @param[in, out] *pSrc16 points to the in-place buffer of Q15 data type. - * @param[in] fftLen length of the FFT. - * @param[in] *pCoef16 points to twiddle coefficient buffer. - * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. - * @return none. - */ - - void arm_radix4_butterfly_q15( - q15_t *pSrc16, - uint32_t fftLen, - q15_t *pCoef16, - uint32_t twidCoefModifier); - - /** - * @brief Core function for the Q15 CIFFT butterfly process. - * @param[in, out] *pSrc16 points to the in-place buffer of Q15 data type. - * @param[in] fftLen length of the FFT. - * @param[in] *pCoef16 points to twiddle coefficient buffer. - * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. - * @return none. - */ - - void arm_radix4_butterfly_inverse_q15( - q15_t *pSrc16, - uint32_t fftLen, - q15_t *pCoef16, - uint32_t twidCoefModifier); - - /** - * @brief In-place bit reversal function. - * @param[in, out] *pSrc points to the in-place buffer of Q15 data type. - * @param[in] fftLen length of the FFT. - * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table - * @param[in] *pBitRevTab points to bit reversal table. - * @return none. - */ - - void arm_bitreversal_q15( - q15_t * pSrc, - uint32_t fftLen, - uint16_t bitRevFactor, - uint16_t *pBitRevTab); - - /** - * @brief Instance structure for the Q15 RFFT/RIFFT function. - */ - - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - uint32_t fftLenBy2; /**< length of the complex FFT. */ - uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ - uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ - uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ - q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ - arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_q15; - - /** - * @brief Instance structure for the Q31 RFFT/RIFFT function. - */ - - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - uint32_t fftLenBy2; /**< length of the complex FFT. */ - uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ - uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ - uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ - q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ - arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_q31; - - /** - * @brief Instance structure for the floating-point RFFT/RIFFT function. - */ - - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - uint16_t fftLenBy2; /**< length of the complex FFT. */ - uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ - uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ - uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ - float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ - arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_f32; - - /** - * @brief Processing function for the Q15 RFFT/RIFFT. - * @param[in] *S points to an instance of the Q15 RFFT/RIFFT structure. - * @param[in] *pSrc points to the input buffer. - * @param[out] *pDst points to the output buffer. - * @return none. - */ - - void arm_rfft_q15( - const arm_rfft_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst); - - /** - * @brief Initialization function for the Q15 RFFT/RIFFT. - * @param[in, out] *S points to an instance of the Q15 RFFT/RIFFT structure. - * @param[in] *S_CFFT points to an instance of the Q15 CFFT/CIFFT structure. - * @param[in] fftLenReal length of the FFT. - * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. - * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value. - */ - - arm_status arm_rfft_init_q15( - arm_rfft_instance_q15 * S, - arm_cfft_radix4_instance_q15 * S_CFFT, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - /** - * @brief Processing function for the Q31 RFFT/RIFFT. - * @param[in] *S points to an instance of the Q31 RFFT/RIFFT structure. - * @param[in] *pSrc points to the input buffer. - * @param[out] *pDst points to the output buffer. - * @return none. - */ - - void arm_rfft_q31( - const arm_rfft_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst); - - /** - * @brief Initialization function for the Q31 RFFT/RIFFT. - * @param[in, out] *S points to an instance of the Q31 RFFT/RIFFT structure. - * @param[in, out] *S_CFFT points to an instance of the Q31 CFFT/CIFFT structure. - * @param[in] fftLenReal length of the FFT. - * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. - * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value. - */ - - arm_status arm_rfft_init_q31( - arm_rfft_instance_q31 * S, - arm_cfft_radix4_instance_q31 * S_CFFT, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - /** - * @brief Initialization function for the floating-point RFFT/RIFFT. - * @param[in,out] *S points to an instance of the floating-point RFFT/RIFFT structure. - * @param[in,out] *S_CFFT points to an instance of the floating-point CFFT/CIFFT structure. - * @param[in] fftLenReal length of the FFT. - * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. - * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value. - */ - - arm_status arm_rfft_init_f32( - arm_rfft_instance_f32 * S, - arm_cfft_radix4_instance_f32 * S_CFFT, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - /** - * @brief Processing function for the floating-point RFFT/RIFFT. - * @param[in] *S points to an instance of the floating-point RFFT/RIFFT structure. - * @param[in] *pSrc points to the input buffer. - * @param[out] *pDst points to the output buffer. - * @return none. - */ - - void arm_rfft_f32( - const arm_rfft_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst); - - /** - * @brief Instance structure for the floating-point DCT4/IDCT4 function. - */ - - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - float32_t normalize; /**< normalizing factor. */ - float32_t *pTwiddle; /**< points to the twiddle factor table. */ - float32_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_f32; - - /** - * @brief Initialization function for the floating-point DCT4/IDCT4. - * @param[in,out] *S points to an instance of floating-point DCT4/IDCT4 structure. - * @param[in] *S_RFFT points to an instance of floating-point RFFT/RIFFT structure. - * @param[in] *S_CFFT points to an instance of floating-point CFFT/CIFFT structure. - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. - */ - - arm_status arm_dct4_init_f32( - arm_dct4_instance_f32 * S, - arm_rfft_instance_f32 * S_RFFT, - arm_cfft_radix4_instance_f32 * S_CFFT, - uint16_t N, - uint16_t Nby2, - float32_t normalize); - - /** - * @brief Processing function for the floating-point DCT4/IDCT4. - * @param[in] *S points to an instance of the floating-point DCT4/IDCT4 structure. - * @param[in] *pState points to state buffer. - * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. - * @return none. - */ - - void arm_dct4_f32( - const arm_dct4_instance_f32 * S, - float32_t * pState, - float32_t * pInlineBuffer); - - /** - * @brief Instance structure for the Q31 DCT4/IDCT4 function. - */ - - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - q31_t normalize; /**< normalizing factor. */ - q31_t *pTwiddle; /**< points to the twiddle factor table. */ - q31_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_q31; - - /** - * @brief Initialization function for the Q31 DCT4/IDCT4. - * @param[in,out] *S points to an instance of Q31 DCT4/IDCT4 structure. - * @param[in] *S_RFFT points to an instance of Q31 RFFT/RIFFT structure - * @param[in] *S_CFFT points to an instance of Q31 CFFT/CIFFT structure - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. - */ - - arm_status arm_dct4_init_q31( - arm_dct4_instance_q31 * S, - arm_rfft_instance_q31 * S_RFFT, - arm_cfft_radix4_instance_q31 * S_CFFT, - uint16_t N, - uint16_t Nby2, - q31_t normalize); - - /** - * @brief Processing function for the Q31 DCT4/IDCT4. - * @param[in] *S points to an instance of the Q31 DCT4 structure. - * @param[in] *pState points to state buffer. - * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. - * @return none. - */ - - void arm_dct4_q31( - const arm_dct4_instance_q31 * S, - q31_t * pState, - q31_t * pInlineBuffer); - - /** - * @brief Instance structure for the Q15 DCT4/IDCT4 function. - */ - - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - q15_t normalize; /**< normalizing factor. */ - q15_t *pTwiddle; /**< points to the twiddle factor table. */ - q15_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_q15; - - /** - * @brief Initialization function for the Q15 DCT4/IDCT4. - * @param[in,out] *S points to an instance of Q15 DCT4/IDCT4 structure. - * @param[in] *S_RFFT points to an instance of Q15 RFFT/RIFFT structure. - * @param[in] *S_CFFT points to an instance of Q15 CFFT/CIFFT structure. - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. - */ - - arm_status arm_dct4_init_q15( - arm_dct4_instance_q15 * S, - arm_rfft_instance_q15 * S_RFFT, - arm_cfft_radix4_instance_q15 * S_CFFT, - uint16_t N, - uint16_t Nby2, - q15_t normalize); - - /** - * @brief Processing function for the Q15 DCT4/IDCT4. - * @param[in] *S points to an instance of the Q15 DCT4 structure. - * @param[in] *pState points to state buffer. - * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. - * @return none. - */ - - void arm_dct4_q15( - const arm_dct4_instance_q15 * S, - q15_t * pState, - q15_t * pInlineBuffer); - - /** - * @brief Floating-point vector addition. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_add_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Q7 vector addition. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_add_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Q15 vector addition. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_add_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Q31 vector addition. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_add_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Floating-point vector subtraction. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_sub_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Q7 vector subtraction. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_sub_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Q15 vector subtraction. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_sub_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Q31 vector subtraction. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_sub_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Multiplies a floating-point vector by a scalar. - * @param[in] *pSrc points to the input vector - * @param[in] scale scale factor to be applied - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_scale_f32( - float32_t * pSrc, - float32_t scale, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Multiplies a Q7 vector by a scalar. - * @param[in] *pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_scale_q7( - q7_t * pSrc, - q7_t scaleFract, - int8_t shift, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Multiplies a Q15 vector by a scalar. - * @param[in] *pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_scale_q15( - q15_t * pSrc, - q15_t scaleFract, - int8_t shift, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Multiplies a Q31 vector by a scalar. - * @param[in] *pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_scale_q31( - q31_t * pSrc, - q31_t scaleFract, - int8_t shift, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Q7 vector absolute value. - * @param[in] *pSrc points to the input buffer - * @param[out] *pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_abs_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Floating-point vector absolute value. - * @param[in] *pSrc points to the input buffer - * @param[out] *pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_abs_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Q15 vector absolute value. - * @param[in] *pSrc points to the input buffer - * @param[out] *pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_abs_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Q31 vector absolute value. - * @param[in] *pSrc points to the input buffer - * @param[out] *pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_abs_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Dot product of floating-point vectors. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] *result output result returned here - * @return none. - */ - - void arm_dot_prod_f32( - float32_t * pSrcA, - float32_t * pSrcB, - uint32_t blockSize, - float32_t * result); - - /** - * @brief Dot product of Q7 vectors. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] *result output result returned here - * @return none. - */ - - void arm_dot_prod_q7( - q7_t * pSrcA, - q7_t * pSrcB, - uint32_t blockSize, - q31_t * result); - - /** - * @brief Dot product of Q15 vectors. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] *result output result returned here - * @return none. - */ - - void arm_dot_prod_q15( - q15_t * pSrcA, - q15_t * pSrcB, - uint32_t blockSize, - q63_t * result); - - /** - * @brief Dot product of Q31 vectors. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] *result output result returned here - * @return none. - */ - - void arm_dot_prod_q31( - q31_t * pSrcA, - q31_t * pSrcB, - uint32_t blockSize, - q63_t * result); - - /** - * @brief Shifts the elements of a Q7 vector a specified number of bits. - * @param[in] *pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_shift_q7( - q7_t * pSrc, - int8_t shiftBits, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Shifts the elements of a Q15 vector a specified number of bits. - * @param[in] *pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_shift_q15( - q15_t * pSrc, - int8_t shiftBits, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Shifts the elements of a Q31 vector a specified number of bits. - * @param[in] *pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_shift_q31( - q31_t * pSrc, - int8_t shiftBits, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Adds a constant offset to a floating-point vector. - * @param[in] *pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_offset_f32( - float32_t * pSrc, - float32_t offset, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Adds a constant offset to a Q7 vector. - * @param[in] *pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_offset_q7( - q7_t * pSrc, - q7_t offset, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Adds a constant offset to a Q15 vector. - * @param[in] *pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_offset_q15( - q15_t * pSrc, - q15_t offset, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Adds a constant offset to a Q31 vector. - * @param[in] *pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_offset_q31( - q31_t * pSrc, - q31_t offset, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Negates the elements of a floating-point vector. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_negate_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Negates the elements of a Q7 vector. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_negate_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Negates the elements of a Q15 vector. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_negate_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Negates the elements of a Q31 vector. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_negate_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - /** - * @brief Copies the elements of a floating-point vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_copy_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Copies the elements of a Q7 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_copy_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Copies the elements of a Q15 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_copy_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Copies the elements of a Q31 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_copy_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - /** - * @brief Fills a constant value into a floating-point vector. - * @param[in] value input value to be filled - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_fill_f32( - float32_t value, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Fills a constant value into a Q7 vector. - * @param[in] value input value to be filled - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_fill_q7( - q7_t value, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Fills a constant value into a Q15 vector. - * @param[in] value input value to be filled - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_fill_q15( - q15_t value, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Fills a constant value into a Q31 vector. - * @param[in] value input value to be filled - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_fill_q31( - q31_t value, - q31_t * pDst, - uint32_t blockSize); - -/** - * @brief Convolution of floating-point sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst); - -/** - * @brief Convolution of Q15 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - /** - * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - /** - * @brief Convolution of Q31 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - /** - * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - /** - * @brief Convolution of Q7 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst); - - /** - * @brief Partial convolution of floating-point sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - /** - * @brief Partial convolution of Q15 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - /** - * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - /** - * @brief Partial convolution of Q31 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - /** - * @brief Partial convolution of Q7 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Instance structure for the Q15 FIR decimator. - */ - - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - } arm_fir_decimate_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR decimator. - */ - - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - - } arm_fir_decimate_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR decimator. - */ - - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - - } arm_fir_decimate_instance_f32; - - - - /** - * @brief Processing function for the floating-point FIR decimator. - * @param[in] *S points to an instance of the floating-point FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_f32( - const arm_fir_decimate_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point FIR decimator. - * @param[in,out] *S points to an instance of the floating-point FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - - arm_status arm_fir_decimate_init_f32( - arm_fir_decimate_instance_f32 * S, - uint16_t numTaps, - uint8_t M, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the Q15 FIR decimator. - * @param[in] *S points to an instance of the Q15 FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_q15( - const arm_fir_decimate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q15 FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_fast_q15( - const arm_fir_decimate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - - /** - * @brief Initialization function for the Q15 FIR decimator. - * @param[in,out] *S points to an instance of the Q15 FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - - arm_status arm_fir_decimate_init_q15( - arm_fir_decimate_instance_q15 * S, - uint16_t numTaps, - uint8_t M, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 FIR decimator. - * @param[in] *S points to an instance of the Q31 FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_q31( - const arm_fir_decimate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q31 FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_fast_q31( - arm_fir_decimate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 FIR decimator. - * @param[in,out] *S points to an instance of the Q31 FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - - arm_status arm_fir_decimate_init_q31( - arm_fir_decimate_instance_q31 * S, - uint16_t numTaps, - uint8_t M, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - - - /** - * @brief Instance structure for the Q15 FIR interpolator. - */ - - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ - } arm_fir_interpolate_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR interpolator. - */ - - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ - } arm_fir_interpolate_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR interpolator. - */ - - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ - } arm_fir_interpolate_instance_f32; - - - /** - * @brief Processing function for the Q15 FIR interpolator. - * @param[in] *S points to an instance of the Q15 FIR interpolator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_interpolate_q15( - const arm_fir_interpolate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 FIR interpolator. - * @param[in,out] *S points to an instance of the Q15 FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficient buffer. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - - arm_status arm_fir_interpolate_init_q15( - arm_fir_interpolate_instance_q15 * S, - uint8_t L, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 FIR interpolator. - * @param[in] *S points to an instance of the Q15 FIR interpolator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_interpolate_q31( - const arm_fir_interpolate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 FIR interpolator. - * @param[in,out] *S points to an instance of the Q31 FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficient buffer. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - - arm_status arm_fir_interpolate_init_q31( - arm_fir_interpolate_instance_q31 * S, - uint8_t L, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the floating-point FIR interpolator. - * @param[in] *S points to an instance of the floating-point FIR interpolator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_interpolate_f32( - const arm_fir_interpolate_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point FIR interpolator. - * @param[in,out] *S points to an instance of the floating-point FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficient buffer. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - - arm_status arm_fir_interpolate_init_f32( - arm_fir_interpolate_instance_f32 * S, - uint8_t L, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - /** - * @brief Instance structure for the high precision Q31 Biquad cascade filter. - */ - - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ - q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ - - } arm_biquad_cas_df1_32x64_ins_q31; - - - /** - * @param[in] *S points to an instance of the high precision Q31 Biquad cascade filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cas_df1_32x64_q31( - const arm_biquad_cas_df1_32x64_ins_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @param[in,out] *S points to an instance of the high precision Q31 Biquad cascade filter structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format - * @return none - */ - - void arm_biquad_cas_df1_32x64_init_q31( - arm_biquad_cas_df1_32x64_ins_q31 * S, - uint8_t numStages, - q31_t * pCoeffs, - q63_t * pState, - uint8_t postShift); - - - - /** - * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. - */ - - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ - float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_cascade_df2T_instance_f32; - - - /** - * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in] *S points to an instance of the filter data structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df2T_f32( - const arm_biquad_cascade_df2T_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in,out] *S points to an instance of the filter data structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @return none - */ - - void arm_biquad_cascade_df2T_init_f32( - arm_biquad_cascade_df2T_instance_f32 * S, - uint8_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - - /** - * @brief Instance structure for the Q15 FIR lattice filter. - */ - - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR lattice filter. - */ - - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR lattice filter. - */ - - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_f32; - - /** - * @brief Initialization function for the Q15 FIR lattice filter. - * @param[in] *S points to an instance of the Q15 FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] *pState points to the state buffer. The array is of length numStages. - * @return none. - */ - - void arm_fir_lattice_init_q15( - arm_fir_lattice_instance_q15 * S, - uint16_t numStages, - q15_t * pCoeffs, - q15_t * pState); - - - /** - * @brief Processing function for the Q15 FIR lattice filter. - * @param[in] *S points to an instance of the Q15 FIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_lattice_q15( - const arm_fir_lattice_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 FIR lattice filter. - * @param[in] *S points to an instance of the Q31 FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] *pState points to the state buffer. The array is of length numStages. - * @return none. - */ - - void arm_fir_lattice_init_q31( - arm_fir_lattice_instance_q31 * S, - uint16_t numStages, - q31_t * pCoeffs, - q31_t * pState); - - - /** - * @brief Processing function for the Q31 FIR lattice filter. - * @param[in] *S points to an instance of the Q31 FIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_fir_lattice_q31( - const arm_fir_lattice_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - -/** - * @brief Initialization function for the floating-point FIR lattice filter. - * @param[in] *S points to an instance of the floating-point FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] *pState points to the state buffer. The array is of length numStages. - * @return none. - */ - - void arm_fir_lattice_init_f32( - arm_fir_lattice_instance_f32 * S, - uint16_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - /** - * @brief Processing function for the floating-point FIR lattice filter. - * @param[in] *S points to an instance of the floating-point FIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_fir_lattice_f32( - const arm_fir_lattice_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Instance structure for the Q15 IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_q15; - - /** - * @brief Instance structure for the Q31 IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_q31; - - /** - * @brief Instance structure for the floating-point IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_f32; - - /** - * @brief Processing function for the floating-point IIR lattice filter. - * @param[in] *S points to an instance of the floating-point IIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_f32( - const arm_iir_lattice_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point IIR lattice filter. - * @param[in] *S points to an instance of the floating-point IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. - * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. - * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize-1. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_init_f32( - arm_iir_lattice_instance_f32 * S, - uint16_t numStages, - float32_t *pkCoeffs, - float32_t *pvCoeffs, - float32_t *pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 IIR lattice filter. - * @param[in] *S points to an instance of the Q31 IIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_q31( - const arm_iir_lattice_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 IIR lattice filter. - * @param[in] *S points to an instance of the Q31 IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. - * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. - * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_init_q31( - arm_iir_lattice_instance_q31 * S, - uint16_t numStages, - q31_t *pkCoeffs, - q31_t *pvCoeffs, - q31_t *pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 IIR lattice filter. - * @param[in] *S points to an instance of the Q15 IIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_q15( - const arm_iir_lattice_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - -/** - * @brief Initialization function for the Q15 IIR lattice filter. - * @param[in] *S points to an instance of the fixed-point Q15 IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] *pkCoeffs points to reflection coefficient buffer. The array is of length numStages. - * @param[in] *pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. - * @param[in] *pState points to state buffer. The array is of length numStages+blockSize. - * @param[in] blockSize number of samples to process per call. - * @return none. - */ - - void arm_iir_lattice_init_q15( - arm_iir_lattice_instance_q15 * S, - uint16_t numStages, - q15_t *pkCoeffs, - q15_t *pvCoeffs, - q15_t *pState, - uint32_t blockSize); - - /** - * @brief Instance structure for the floating-point LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - float32_t mu; /**< step size that controls filter coefficient updates. */ - } arm_lms_instance_f32; - - /** - * @brief Processing function for floating-point LMS filter. - * @param[in] *S points to an instance of the floating-point LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_f32( - const arm_lms_instance_f32 * S, - float32_t * pSrc, - float32_t * pRef, - float32_t * pOut, - float32_t * pErr, - uint32_t blockSize); - - /** - * @brief Initialization function for floating-point LMS filter. - * @param[in] *S points to an instance of the floating-point LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to the coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_init_f32( - arm_lms_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - float32_t mu, - uint32_t blockSize); - - /** - * @brief Instance structure for the Q15 LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q15_t mu; /**< step size that controls filter coefficient updates. */ - uint32_t postShift; /**< bit shift applied to coefficients. */ - } arm_lms_instance_q15; - - - /** - * @brief Initialization function for the Q15 LMS filter. - * @param[in] *S points to an instance of the Q15 LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to the coefficient buffer. - * @param[in] *pState points to the state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - * @return none. - */ - - void arm_lms_init_q15( - arm_lms_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - q15_t mu, - uint32_t blockSize, - uint32_t postShift); - - /** - * @brief Processing function for Q15 LMS filter. - * @param[in] *S points to an instance of the Q15 LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_q15( - const arm_lms_instance_q15 * S, - q15_t * pSrc, - q15_t * pRef, - q15_t * pOut, - q15_t * pErr, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q31 LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q31_t mu; /**< step size that controls filter coefficient updates. */ - uint32_t postShift; /**< bit shift applied to coefficients. */ - - } arm_lms_instance_q31; - - /** - * @brief Processing function for Q31 LMS filter. - * @param[in] *S points to an instance of the Q15 LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_q31( - const arm_lms_instance_q31 * S, - q31_t * pSrc, - q31_t * pRef, - q31_t * pOut, - q31_t * pErr, - uint32_t blockSize); - - /** - * @brief Initialization function for Q31 LMS filter. - * @param[in] *S points to an instance of the Q31 LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - * @return none. - */ - - void arm_lms_init_q31( - arm_lms_instance_q31 * S, - uint16_t numTaps, - q31_t *pCoeffs, - q31_t *pState, - q31_t mu, - uint32_t blockSize, - uint32_t postShift); - - /** - * @brief Instance structure for the floating-point normalized LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - float32_t mu; /**< step size that control filter coefficient updates. */ - float32_t energy; /**< saves previous frame energy. */ - float32_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_f32; - - /** - * @brief Processing function for floating-point normalized LMS filter. - * @param[in] *S points to an instance of the floating-point normalized LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_norm_f32( - arm_lms_norm_instance_f32 * S, - float32_t * pSrc, - float32_t * pRef, - float32_t * pOut, - float32_t * pErr, - uint32_t blockSize); - - /** - * @brief Initialization function for floating-point normalized LMS filter. - * @param[in] *S points to an instance of the floating-point LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_norm_init_f32( - arm_lms_norm_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - float32_t mu, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q31 normalized LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q31_t mu; /**< step size that controls filter coefficient updates. */ - uint8_t postShift; /**< bit shift applied to coefficients. */ - q31_t *recipTable; /**< points to the reciprocal initial value table. */ - q31_t energy; /**< saves previous frame energy. */ - q31_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_q31; - - /** - * @brief Processing function for Q31 normalized LMS filter. - * @param[in] *S points to an instance of the Q31 normalized LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_norm_q31( - arm_lms_norm_instance_q31 * S, - q31_t * pSrc, - q31_t * pRef, - q31_t * pOut, - q31_t * pErr, - uint32_t blockSize); - - /** - * @brief Initialization function for Q31 normalized LMS filter. - * @param[in] *S points to an instance of the Q31 normalized LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - * @return none. - */ - - void arm_lms_norm_init_q31( - arm_lms_norm_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - q31_t mu, - uint32_t blockSize, - uint8_t postShift); - - /** - * @brief Instance structure for the Q15 normalized LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< Number of coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q15_t mu; /**< step size that controls filter coefficient updates. */ - uint8_t postShift; /**< bit shift applied to coefficients. */ - q15_t *recipTable; /**< Points to the reciprocal initial value table. */ - q15_t energy; /**< saves previous frame energy. */ - q15_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_q15; - - /** - * @brief Processing function for Q15 normalized LMS filter. - * @param[in] *S points to an instance of the Q15 normalized LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_norm_q15( - arm_lms_norm_instance_q15 * S, - q15_t * pSrc, - q15_t * pRef, - q15_t * pOut, - q15_t * pErr, - uint32_t blockSize); - - - /** - * @brief Initialization function for Q15 normalized LMS filter. - * @param[in] *S points to an instance of the Q15 normalized LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - * @return none. - */ - - void arm_lms_norm_init_q15( - arm_lms_norm_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - q15_t mu, - uint32_t blockSize, - uint8_t postShift); - - /** - * @brief Correlation of floating-point sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst); - - /** - * @brief Correlation of Q15 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - /** - * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - /** - * @brief Correlation of Q31 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - /** - * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - /** - * @brief Correlation of Q7 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst); - - /** - * @brief Instance structure for the floating-point sparse FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_f32; - - /** - * @brief Instance structure for the Q31 sparse FIR filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q31; - - /** - * @brief Instance structure for the Q15 sparse FIR filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q15; - - /** - * @brief Instance structure for the Q7 sparse FIR filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q7; - - /** - * @brief Processing function for the floating-point sparse FIR filter. - * @param[in] *S points to an instance of the floating-point sparse FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] *pScratchIn points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_sparse_f32( - arm_fir_sparse_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - float32_t * pScratchIn, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point sparse FIR filter. - * @param[in,out] *S points to an instance of the floating-point sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] *pCoeffs points to the array of filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] *pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - * @return none - */ - - void arm_fir_sparse_init_f32( - arm_fir_sparse_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 sparse FIR filter. - * @param[in] *S points to an instance of the Q31 sparse FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] *pScratchIn points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_sparse_q31( - arm_fir_sparse_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - q31_t * pScratchIn, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 sparse FIR filter. - * @param[in,out] *S points to an instance of the Q31 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] *pCoeffs points to the array of filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] *pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - * @return none - */ - - void arm_fir_sparse_init_q31( - arm_fir_sparse_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - /** - * @brief Processing function for the Q15 sparse FIR filter. - * @param[in] *S points to an instance of the Q15 sparse FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] *pScratchIn points to a temporary buffer of size blockSize. - * @param[in] *pScratchOut points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_sparse_q15( - arm_fir_sparse_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - q15_t * pScratchIn, - q31_t * pScratchOut, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 sparse FIR filter. - * @param[in,out] *S points to an instance of the Q15 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] *pCoeffs points to the array of filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] *pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - * @return none - */ - - void arm_fir_sparse_init_q15( - arm_fir_sparse_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - /** - * @brief Processing function for the Q7 sparse FIR filter. - * @param[in] *S points to an instance of the Q7 sparse FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] *pScratchIn points to a temporary buffer of size blockSize. - * @param[in] *pScratchOut points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_sparse_q7( - arm_fir_sparse_instance_q7 * S, - q7_t * pSrc, - q7_t * pDst, - q7_t * pScratchIn, - q31_t * pScratchOut, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q7 sparse FIR filter. - * @param[in,out] *S points to an instance of the Q7 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] *pCoeffs points to the array of filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] *pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - * @return none - */ - - void arm_fir_sparse_init_q7( - arm_fir_sparse_instance_q7 * S, - uint16_t numTaps, - q7_t * pCoeffs, - q7_t * pState, - int32_t *pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - - /* - * @brief Floating-point sin_cos function. - * @param[in] theta input value in degrees - * @param[out] *pSinVal points to the processed sine output. - * @param[out] *pCosVal points to the processed cos output. - * @return none. - */ - - void arm_sin_cos_f32( - float32_t theta, - float32_t *pSinVal, - float32_t *pCcosVal); - - /* - * @brief Q31 sin_cos function. - * @param[in] theta scaled input value in degrees - * @param[out] *pSinVal points to the processed sine output. - * @param[out] *pCosVal points to the processed cosine output. - * @return none. - */ - - void arm_sin_cos_q31( - q31_t theta, - q31_t *pSinVal, - q31_t *pCosVal); - - - /** - * @brief Floating-point complex conjugate. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_conj_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t numSamples); - - /** - * @brief Q31 complex conjugate. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_conj_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t numSamples); - - /** - * @brief Q15 complex conjugate. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_conj_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t numSamples); - - - - /** - * @brief Floating-point complex magnitude squared - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_squared_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t numSamples); - - /** - * @brief Q31 complex magnitude squared - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_squared_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t numSamples); - - /** - * @brief Q15 complex magnitude squared - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_squared_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t numSamples); - - - /** - * @ingroup groupController - */ - - /** - * @defgroup PID PID Motor Control - * - * A Proportional Integral Derivative (PID) controller is a generic feedback control - * loop mechanism widely used in industrial control systems. - * A PID controller is the most commonly used type of feedback controller. - * - * This set of functions implements (PID) controllers - * for Q15, Q31, and floating-point data types. The functions operate on a single sample - * of data and each call to the function returns a single processed value. - * S points to an instance of the PID control data structure. in - * is the input sample value. The functions return the output value. - * - * \par Algorithm: - *
-   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
-   *    A0 = Kp + Ki + Kd
-   *    A1 = (-Kp ) - (2 * Kd )
-   *    A2 = Kd  
- * - * \par - * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant - * - * \par - * \image html PID.gif "Proportional Integral Derivative Controller" - * - * \par - * The PID controller calculates an "error" value as the difference between - * the measured output and the reference input. - * The controller attempts to minimize the error by adjusting the process control inputs. - * The proportional value determines the reaction to the current error, - * the integral value determines the reaction based on the sum of recent errors, - * and the derivative value determines the reaction based on the rate at which the error has been changing. - * - * \par Instance Structure - * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. - * A separate instance structure must be defined for each PID Controller. - * There are separate instance structure declarations for each of the 3 supported data types. - * - * \par Reset Functions - * There is also an associated reset function for each data type which clears the state array. - * - * \par Initialization Functions - * There is also an associated initialization function for each data type. - * The initialization function performs the following operations: - * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. - * - Zeros out the values in the state buffer. - * - * \par - * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. - * - * \par Fixed-Point Behavior - * Care must be taken when using the fixed-point versions of the PID Controller functions. - * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup PID - * @{ - */ - - /** - * @brief Process function for the floating-point PID Control. - * @param[in,out] *S is an instance of the floating-point PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - */ - - - static __INLINE float32_t arm_pid_f32( - arm_pid_instance_f32 * S, - float32_t in) - { - float32_t out; - - /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ - out = (S->A0 * in) + - (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - - } - - /** - * @brief Process function for the Q31 PID Control. - * @param[in,out] *S points to an instance of the Q31 PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 64-bit accumulator. - * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. - * Thus, if the accumulator result overflows it wraps around rather than clip. - * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. - * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. - */ - - static __INLINE q31_t arm_pid_q31( - arm_pid_instance_q31 * S, - q31_t in) - { - q63_t acc; - q31_t out; - - /* acc = A0 * x[n] */ - acc = (q63_t) S->A0 * in; - - /* acc += A1 * x[n-1] */ - acc += (q63_t) S->A1 * S->state[0]; - - /* acc += A2 * x[n-2] */ - acc += (q63_t) S->A2 * S->state[1]; - - /* convert output to 1.31 format to add y[n-1] */ - out = (q31_t) (acc >> 31u); - - /* out += y[n-1] */ - out += S->state[2]; - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - - } - - /** - * @brief Process function for the Q15 PID Control. - * @param[in,out] *S points to an instance of the Q15 PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using a 64-bit internal accumulator. - * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. - * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. - * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. - * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. - * Lastly, the accumulator is saturated to yield a result in 1.15 format. - */ - - static __INLINE q15_t arm_pid_q15( - arm_pid_instance_q15 * S, - q15_t in) - { - q63_t acc; - q15_t out; - - /* Implementation of PID controller */ - - #ifdef ARM_MATH_CM0 - - /* acc = A0 * x[n] */ - acc = ((q31_t) S->A0 )* in ; - - #else - - /* acc = A0 * x[n] */ - acc = (q31_t) __SMUAD(S->A0, in); - - #endif - - #ifdef ARM_MATH_CM0 - - /* acc += A1 * x[n-1] + A2 * x[n-2] */ - acc += (q31_t) S->A1 * S->state[0] ; - acc += (q31_t) S->A2 * S->state[1] ; - - #else - - /* acc += A1 * x[n-1] + A2 * x[n-2] */ - acc = __SMLALD(S->A1, (q31_t)__SIMD32(S->state), acc); - - #endif - - /* acc += y[n-1] */ - acc += (q31_t) S->state[2] << 15; - - /* saturate the output */ - out = (q15_t) (__SSAT((acc >> 15), 16)); - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - - } - - /** - * @} end of PID group - */ - - - /** - * @brief Floating-point matrix inverse. - * @param[in] *src points to the instance of the input floating-point matrix structure. - * @param[out] *dst points to the instance of the output floating-point matrix structure. - * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. - * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. - */ - - arm_status arm_mat_inverse_f32( - const arm_matrix_instance_f32 * src, - arm_matrix_instance_f32 * dst); - - - - /** - * @ingroup groupController - */ - - - /** - * @defgroup clarke Vector Clarke Transform - * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. - * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents - * in the two-phase orthogonal stator axis Ialpha and Ibeta. - * When Ialpha is superposed with Ia as shown in the figure below - * \image html clarke.gif Stator current space vector and its components in (a,b). - * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta - * can be calculated using only Ia and Ib. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html clarkeFormula.gif - * where Ia and Ib are the instantaneous stator phases and - * pIalpha and pIbeta are the two coordinates of time invariant vector. - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Clarke transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup clarke - * @{ - */ - - /** - * - * @brief Floating-point Clarke transform - * @param[in] Ia input three-phase coordinate a - * @param[in] Ib input three-phase coordinate b - * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta - * @return none. - */ - - static __INLINE void arm_clarke_f32( - float32_t Ia, - float32_t Ib, - float32_t * pIalpha, - float32_t * pIbeta) - { - /* Calculate pIalpha using the equation, pIalpha = Ia */ - *pIalpha = Ia; - - /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ - *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); - - } - - /** - * @brief Clarke transform for Q31 version - * @param[in] Ia input three-phase coordinate a - * @param[in] Ib input three-phase coordinate b - * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta - * @return none. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition, hence there is no risk of overflow. - */ - - static __INLINE void arm_clarke_q31( - q31_t Ia, - q31_t Ib, - q31_t * pIalpha, - q31_t * pIbeta) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - - /* Calculating pIalpha from Ia by equation pIalpha = Ia */ - *pIalpha = Ia; - - /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ - product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); - - /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ - product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); - - /* pIbeta is calculated by adding the intermediate products */ - *pIbeta = __QADD(product1, product2); - } - - /** - * @} end of clarke group - */ - - /** - * @brief Converts the elements of the Q7 vector to Q31 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_q7_to_q31( - q7_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - - - /** - * @ingroup groupController - */ - - /** - * @defgroup inv_clarke Vector Inverse Clarke Transform - * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html clarkeInvFormula.gif - * where pIa and pIb are the instantaneous stator phases and - * Ialpha and Ibeta are the two coordinates of time invariant vector. - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Clarke transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup inv_clarke - * @{ - */ - - /** - * @brief Floating-point Inverse Clarke transform - * @param[in] Ialpha input two-phase orthogonal vector axis alpha - * @param[in] Ibeta input two-phase orthogonal vector axis beta - * @param[out] *pIa points to output three-phase coordinate a - * @param[out] *pIb points to output three-phase coordinate b - * @return none. - */ - - - static __INLINE void arm_inv_clarke_f32( - float32_t Ialpha, - float32_t Ibeta, - float32_t * pIa, - float32_t * pIb) - { - /* Calculating pIa from Ialpha by equation pIa = Ialpha */ - *pIa = Ialpha; - - /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ - *pIb = -0.5 * Ialpha + (float32_t) 0.8660254039 *Ibeta; - - } - - /** - * @brief Inverse Clarke transform for Q31 version - * @param[in] Ialpha input two-phase orthogonal vector axis alpha - * @param[in] Ibeta input two-phase orthogonal vector axis beta - * @param[out] *pIa points to output three-phase coordinate a - * @param[out] *pIb points to output three-phase coordinate b - * @return none. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the subtraction, hence there is no risk of overflow. - */ - - static __INLINE void arm_inv_clarke_q31( - q31_t Ialpha, - q31_t Ibeta, - q31_t * pIa, - q31_t * pIb) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - - /* Calculating pIa from Ialpha by equation pIa = Ialpha */ - *pIa = Ialpha; - - /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ - product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); - - /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ - product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); - - /* pIb is calculated by subtracting the products */ - *pIb = __QSUB(product2, product1); - - } - - /** - * @} end of inv_clarke group - */ - - /** - * @brief Converts the elements of the Q7 vector to Q15 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_q7_to_q15( - q7_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - - /** - * @ingroup groupController - */ - - /** - * @defgroup park Vector Park Transform - * - * Forward Park transform converts the input two-coordinate vector to flux and torque components. - * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents - * from the stationary to the moving reference frame and control the spatial relationship between - * the stator vector current and rotor flux vector. - * If we consider the d axis aligned with the rotor flux, the diagram below shows the - * current vector and the relationship from the two reference frames: - * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html parkFormula.gif - * where Ialpha and Ibeta are the stator vector components, - * pId and pIq are rotor vector components and cosVal and sinVal are the - * cosine and sine values of theta (rotor flux position). - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Park transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup park - * @{ - */ - - /** - * @brief Floating-point Park transform - * @param[in] Ialpha input two-phase vector coordinate alpha - * @param[in] Ibeta input two-phase vector coordinate beta - * @param[out] *pId points to output rotor reference frame d - * @param[out] *pIq points to output rotor reference frame q - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * @return none. - * - * The function implements the forward Park transform. - * - */ - - static __INLINE void arm_park_f32( - float32_t Ialpha, - float32_t Ibeta, - float32_t * pId, - float32_t * pIq, - float32_t sinVal, - float32_t cosVal) - { - /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ - *pId = Ialpha * cosVal + Ibeta * sinVal; - - /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ - *pIq = -Ialpha * sinVal + Ibeta * cosVal; - - } - - /** - * @brief Park transform for Q31 version - * @param[in] Ialpha input two-phase vector coordinate alpha - * @param[in] Ibeta input two-phase vector coordinate beta - * @param[out] *pId points to output rotor reference frame d - * @param[out] *pIq points to output rotor reference frame q - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * @return none. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition and subtraction, hence there is no risk of overflow. - */ - - - static __INLINE void arm_park_q31( - q31_t Ialpha, - q31_t Ibeta, - q31_t * pId, - q31_t * pIq, - q31_t sinVal, - q31_t cosVal) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - q31_t product3, product4; /* Temporary variables used to store intermediate results */ - - /* Intermediate product is calculated by (Ialpha * cosVal) */ - product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); - - /* Intermediate product is calculated by (Ibeta * sinVal) */ - product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); - - - /* Intermediate product is calculated by (Ialpha * sinVal) */ - product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); - - /* Intermediate product is calculated by (Ibeta * cosVal) */ - product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); - - /* Calculate pId by adding the two intermediate products 1 and 2 */ - *pId = __QADD(product1, product2); - - /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ - *pIq = __QSUB(product4, product3); - } - - /** - * @} end of park group - */ - - /** - * @brief Converts the elements of the Q7 vector to floating-point vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q7_to_float( - q7_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @ingroup groupController - */ - - /** - * @defgroup inv_park Vector Inverse Park transform - * Inverse Park transform converts the input flux and torque components to two-coordinate vector. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html parkInvFormula.gif - * where pIalpha and pIbeta are the stator vector components, - * Id and Iq are rotor vector components and cosVal and sinVal are the - * cosine and sine values of theta (rotor flux position). - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Park transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup inv_park - * @{ - */ - - /** - * @brief Floating-point Inverse Park transform - * @param[in] Id input coordinate of rotor reference frame d - * @param[in] Iq input coordinate of rotor reference frame q - * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * @return none. - */ - - static __INLINE void arm_inv_park_f32( - float32_t Id, - float32_t Iq, - float32_t * pIalpha, - float32_t * pIbeta, - float32_t sinVal, - float32_t cosVal) - { - /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ - *pIalpha = Id * cosVal - Iq * sinVal; - - /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ - *pIbeta = Id * sinVal + Iq * cosVal; - - } - - - /** - * @brief Inverse Park transform for Q31 version - * @param[in] Id input coordinate of rotor reference frame d - * @param[in] Iq input coordinate of rotor reference frame q - * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * @return none. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition, hence there is no risk of overflow. - */ - - - static __INLINE void arm_inv_park_q31( - q31_t Id, - q31_t Iq, - q31_t * pIalpha, - q31_t * pIbeta, - q31_t sinVal, - q31_t cosVal) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - q31_t product3, product4; /* Temporary variables used to store intermediate results */ - - /* Intermediate product is calculated by (Id * cosVal) */ - product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); - - /* Intermediate product is calculated by (Iq * sinVal) */ - product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); - - - /* Intermediate product is calculated by (Id * sinVal) */ - product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); - - /* Intermediate product is calculated by (Iq * cosVal) */ - product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); - - /* Calculate pIalpha by using the two intermediate products 1 and 2 */ - *pIalpha = __QSUB(product1, product2); - - /* Calculate pIbeta by using the two intermediate products 3 and 4 */ - *pIbeta = __QADD(product4, product3); - - } - - /** - * @} end of Inverse park group - */ - - - /** - * @brief Converts the elements of the Q31 vector to floating-point vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q31_to_float( - q31_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @ingroup groupInterpolation - */ - - /** - * @defgroup LinearInterpolate Linear Interpolation - * - * Linear interpolation is a method of curve fitting using linear polynomials. - * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line - * - * \par - * \image html LinearInterp.gif "Linear interpolation" - * - * \par - * A Linear Interpolate function calculates an output value(y), for the input(x) - * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) - * - * \par Algorithm: - *
-   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
-   *       where x0, x1 are nearest values of input x
-   *             y0, y1 are nearest values to output y
-   * 
- * - * \par - * This set of functions implements Linear interpolation process - * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single - * sample of data and each call to the function returns a single processed value. - * S points to an instance of the Linear Interpolate function data structure. - * x is the input sample value. The functions returns the output value. - * - * \par - * if x is outside of the table boundary, Linear interpolation returns first value of the table - * if x is below input range and returns last value of table if x is above range. - */ - - /** - * @addtogroup LinearInterpolate - * @{ - */ - - /** - * @brief Process function for the floating-point Linear Interpolation Function. - * @param[in,out] *S is an instance of the floating-point Linear Interpolation structure - * @param[in] x input sample to process - * @return y processed output sample. - * - */ - - static __INLINE float32_t arm_linear_interp_f32( - arm_linear_interp_instance_f32 * S, - float32_t x) - { - - float32_t y; - float32_t x0, x1; /* Nearest input values */ - float32_t y0, y1; /* Nearest output values */ - float32_t xSpacing = S->xSpacing; /* spacing between input values */ - int32_t i; /* Index variable */ - float32_t *pYData = S->pYData; /* pointer to output table */ - - /* Calculation of index */ - i = (x - S->x1) / xSpacing; - - if(i < 0) - { - /* Iniatilize output for below specified range as least output value of table */ - y = pYData[0]; - } - else if(i >= S->nValues) - { - /* Iniatilize output for above specified range as last output value of table */ - y = pYData[S->nValues-1]; - } - else - { - /* Calculation of nearest input values */ - x0 = S->x1 + i * xSpacing; - x1 = S->x1 + (i +1) * xSpacing; - - /* Read of nearest output values */ - y0 = pYData[i]; - y1 = pYData[i + 1]; - - /* Calculation of output */ - y = y0 + (x - x0) * ((y1 - y0)/(x1-x0)); - - } - - /* returns output value */ - return (y); - } - - /** - * - * @brief Process function for the Q31 Linear Interpolation Function. - * @param[in] *pYData pointer to Q31 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - * - */ - - - static __INLINE q31_t arm_linear_interp_q31(q31_t *pYData, - q31_t x, uint32_t nValues) - { - q31_t y; /* output */ - q31_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - int32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - index = ((x & 0xFFF00000) >> 20); - - if(index >= (nValues - 1)) - { - return(pYData[nValues - 1]); - } - else if(index < 0) - { - return(pYData[0]); - } - else - { - - /* 20 bits for the fractional part */ - /* shift left by 11 to keep fract in 1.31 format */ - fract = (x & 0x000FFFFF) << 11; - - /* Read two nearest output values from the index in 1.31(q31) format */ - y0 = pYData[index]; - y1 = pYData[index + 1u]; - - /* Calculation of y0 * (1-fract) and y is in 2.30 format */ - y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); - - /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ - y += ((q31_t) (((q63_t) y1 * fract) >> 32)); - - /* Convert y to 1.31 format */ - return (y << 1u); - - } - - } - - /** - * - * @brief Process function for the Q15 Linear Interpolation Function. - * @param[in] *pYData pointer to Q15 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - * - */ - - - static __INLINE q15_t arm_linear_interp_q15(q15_t *pYData, q31_t x, uint32_t nValues) - { - q63_t y; /* output */ - q15_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - int32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - index = ((x & 0xFFF00000) >> 20u); - - if(index >= (nValues - 1)) - { - return(pYData[nValues - 1]); - } - else if(index < 0) - { - return(pYData[0]); - } - else - { - /* 20 bits for the fractional part */ - /* fract is in 12.20 format */ - fract = (x & 0x000FFFFF); - - /* Read two nearest output values from the index */ - y0 = pYData[index]; - y1 = pYData[index + 1u]; - - /* Calculation of y0 * (1-fract) and y is in 13.35 format */ - y = ((q63_t) y0 * (0xFFFFF - fract)); - - /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ - y += ((q63_t) y1 * (fract)); - - /* convert y to 1.15 format */ - return (y >> 20); - } - - - } - - /** - * - * @brief Process function for the Q7 Linear Interpolation Function. - * @param[in] *pYData pointer to Q7 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - */ - - - static __INLINE q7_t arm_linear_interp_q7(q7_t *pYData, q31_t x, uint32_t nValues) - { - q31_t y; /* output */ - q7_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - int32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - index = ((x & 0xFFF00000) >> 20u); - - - if(index >= (nValues - 1)) - { - return(pYData[nValues - 1]); - } - else if(index < 0) - { - return(pYData[0]); - } - else - { - - /* 20 bits for the fractional part */ - /* fract is in 12.20 format */ - fract = (x & 0x000FFFFF); - - /* Read two nearest output values from the index and are in 1.7(q7) format */ - y0 = pYData[index]; - y1 = pYData[index + 1u]; - - /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ - y = ((y0 * (0xFFFFF - fract))); - - /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ - y += (y1 * fract); - - /* convert y to 1.7(q7) format */ - return (y >> 20u); - - } - - } - /** - * @} end of LinearInterpolate group - */ - - /** - * @brief Fast approximation to the trigonometric sine function for floating-point data. - * @param[in] x input value in radians. - * @return sin(x). - */ - - float32_t arm_sin_f32( - float32_t x); - - /** - * @brief Fast approximation to the trigonometric sine function for Q31 data. - * @param[in] x Scaled input value in radians. - * @return sin(x). - */ - - q31_t arm_sin_q31( - q31_t x); - - /** - * @brief Fast approximation to the trigonometric sine function for Q15 data. - * @param[in] x Scaled input value in radians. - * @return sin(x). - */ - - q15_t arm_sin_q15( - q15_t x); - - /** - * @brief Fast approximation to the trigonometric cosine function for floating-point data. - * @param[in] x input value in radians. - * @return cos(x). - */ - - float32_t arm_cos_f32( - float32_t x); - - /** - * @brief Fast approximation to the trigonometric cosine function for Q31 data. - * @param[in] x Scaled input value in radians. - * @return cos(x). - */ - - q31_t arm_cos_q31( - q31_t x); - - /** - * @brief Fast approximation to the trigonometric cosine function for Q15 data. - * @param[in] x Scaled input value in radians. - * @return cos(x). - */ - - q15_t arm_cos_q15( - q15_t x); - - - /** - * @ingroup groupFastMath - */ - - - /** - * @defgroup SQRT Square Root - * - * Computes the square root of a number. - * There are separate functions for Q15, Q31, and floating-point data types. - * The square root function is computed using the Newton-Raphson algorithm. - * This is an iterative algorithm of the form: - *
-   *      x1 = x0 - f(x0)/f'(x0)
-   * 
- * where x1 is the current estimate, - * x0 is the previous estimate and - * f'(x0) is the derivative of f() evaluated at x0. - * For the square root function, the algorithm reduces to: - *
-   *     x0 = in/2                         [initial guess]
-   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
-   * 
- */ - - - /** - * @addtogroup SQRT - * @{ - */ - - /** - * @brief Floating-point square root function. - * @param[in] in input value. - * @param[out] *pOut square root of input value. - * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if - * in is negative value and returns zero output for negative values. - */ - - static __INLINE arm_status arm_sqrt_f32( - float32_t in, float32_t *pOut) - { - if(in > 0) - { - -// #if __FPU_USED - #if (__FPU_USED == 1) && defined ( __CC_ARM ) - *pOut = __sqrtf(in); - #else - *pOut = sqrtf(in); - #endif - - return (ARM_MATH_SUCCESS); - } - else - { - *pOut = 0.0f; - return (ARM_MATH_ARGUMENT_ERROR); - } - - } - - - /** - * @brief Q31 square root function. - * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. - * @param[out] *pOut square root of input value. - * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if - * in is negative value and returns zero output for negative values. - */ - arm_status arm_sqrt_q31( - q31_t in, q31_t *pOut); - - /** - * @brief Q15 square root function. - * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. - * @param[out] *pOut square root of input value. - * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if - * in is negative value and returns zero output for negative values. - */ - arm_status arm_sqrt_q15( - q15_t in, q15_t *pOut); - - /** - * @} end of SQRT group - */ - - - - - - - /** - * @brief floating-point Circular write function. - */ - - static __INLINE void arm_circularWrite_f32( - int32_t * circBuffer, - int32_t L, - uint16_t * writeOffset, - int32_t bufferInc, - const int32_t * src, - int32_t srcInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t wOffset; - - /* Copy the value of Index pointer that points - * to the current location where the input samples to be copied */ - wOffset = *writeOffset; - - /* Loop over the blockSize */ - i = blockSize; - - while(i > 0u) - { - /* copy the input sample to the circular buffer */ - circBuffer[wOffset] = *src; - - /* Update the input pointer */ - src += srcInc; - - /* Circularly update wOffset. Watch out for positive and negative value */ - wOffset += bufferInc; - if(wOffset >= L) - wOffset -= L; - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *writeOffset = wOffset; - } - - - - /** - * @brief floating-point Circular Read function. - */ - static __INLINE void arm_circularRead_f32( - int32_t * circBuffer, - int32_t L, - int32_t * readOffset, - int32_t bufferInc, - int32_t * dst, - int32_t * dst_base, - int32_t dst_length, - int32_t dstInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t rOffset, dst_end; - - /* Copy the value of Index pointer that points - * to the current location from where the input samples to be read */ - rOffset = *readOffset; - dst_end = (int32_t) (dst_base + dst_length); - - /* Loop over the blockSize */ - i = blockSize; - - while(i > 0u) - { - /* copy the sample from the circular buffer to the destination buffer */ - *dst = circBuffer[rOffset]; - - /* Update the input pointer */ - dst += dstInc; - - if(dst == (int32_t *) dst_end) - { - dst = dst_base; - } - - /* Circularly update rOffset. Watch out for positive and negative value */ - rOffset += bufferInc; - - if(rOffset >= L) - { - rOffset -= L; - } - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *readOffset = rOffset; - } - - /** - * @brief Q15 Circular write function. - */ - - static __INLINE void arm_circularWrite_q15( - q15_t * circBuffer, - int32_t L, - uint16_t * writeOffset, - int32_t bufferInc, - const q15_t * src, - int32_t srcInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t wOffset; - - /* Copy the value of Index pointer that points - * to the current location where the input samples to be copied */ - wOffset = *writeOffset; - - /* Loop over the blockSize */ - i = blockSize; - - while(i > 0u) - { - /* copy the input sample to the circular buffer */ - circBuffer[wOffset] = *src; - - /* Update the input pointer */ - src += srcInc; - - /* Circularly update wOffset. Watch out for positive and negative value */ - wOffset += bufferInc; - if(wOffset >= L) - wOffset -= L; - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *writeOffset = wOffset; - } - - - - /** - * @brief Q15 Circular Read function. - */ - static __INLINE void arm_circularRead_q15( - q15_t * circBuffer, - int32_t L, - int32_t * readOffset, - int32_t bufferInc, - q15_t * dst, - q15_t * dst_base, - int32_t dst_length, - int32_t dstInc, - uint32_t blockSize) - { - uint32_t i = 0; - int32_t rOffset, dst_end; - - /* Copy the value of Index pointer that points - * to the current location from where the input samples to be read */ - rOffset = *readOffset; - - dst_end = (int32_t) (dst_base + dst_length); - - /* Loop over the blockSize */ - i = blockSize; - - while(i > 0u) - { - /* copy the sample from the circular buffer to the destination buffer */ - *dst = circBuffer[rOffset]; - - /* Update the input pointer */ - dst += dstInc; - - if(dst == (q15_t *) dst_end) - { - dst = dst_base; - } - - /* Circularly update wOffset. Watch out for positive and negative value */ - rOffset += bufferInc; - - if(rOffset >= L) - { - rOffset -= L; - } - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *readOffset = rOffset; - } - - - /** - * @brief Q7 Circular write function. - */ - - static __INLINE void arm_circularWrite_q7( - q7_t * circBuffer, - int32_t L, - uint16_t * writeOffset, - int32_t bufferInc, - const q7_t * src, - int32_t srcInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t wOffset; - - /* Copy the value of Index pointer that points - * to the current location where the input samples to be copied */ - wOffset = *writeOffset; - - /* Loop over the blockSize */ - i = blockSize; - - while(i > 0u) - { - /* copy the input sample to the circular buffer */ - circBuffer[wOffset] = *src; - - /* Update the input pointer */ - src += srcInc; - - /* Circularly update wOffset. Watch out for positive and negative value */ - wOffset += bufferInc; - if(wOffset >= L) - wOffset -= L; - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *writeOffset = wOffset; - } - - - - /** - * @brief Q7 Circular Read function. - */ - static __INLINE void arm_circularRead_q7( - q7_t * circBuffer, - int32_t L, - int32_t * readOffset, - int32_t bufferInc, - q7_t * dst, - q7_t * dst_base, - int32_t dst_length, - int32_t dstInc, - uint32_t blockSize) - { - uint32_t i = 0; - int32_t rOffset, dst_end; - - /* Copy the value of Index pointer that points - * to the current location from where the input samples to be read */ - rOffset = *readOffset; - - dst_end = (int32_t) (dst_base + dst_length); - - /* Loop over the blockSize */ - i = blockSize; - - while(i > 0u) - { - /* copy the sample from the circular buffer to the destination buffer */ - *dst = circBuffer[rOffset]; - - /* Update the input pointer */ - dst += dstInc; - - if(dst == (q7_t *) dst_end) - { - dst = dst_base; - } - - /* Circularly update rOffset. Watch out for positive and negative value */ - rOffset += bufferInc; - - if(rOffset >= L) - { - rOffset -= L; - } - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *readOffset = rOffset; - } - - - /** - * @brief Sum of the squares of the elements of a Q31 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_power_q31( - q31_t * pSrc, - uint32_t blockSize, - q63_t * pResult); - - /** - * @brief Sum of the squares of the elements of a floating-point vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_power_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - /** - * @brief Sum of the squares of the elements of a Q15 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_power_q15( - q15_t * pSrc, - uint32_t blockSize, - q63_t * pResult); - - /** - * @brief Sum of the squares of the elements of a Q7 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_power_q7( - q7_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - /** - * @brief Mean value of a Q7 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_mean_q7( - q7_t * pSrc, - uint32_t blockSize, - q7_t * pResult); - - /** - * @brief Mean value of a Q15 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - void arm_mean_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - /** - * @brief Mean value of a Q31 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - void arm_mean_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - /** - * @brief Mean value of a floating-point vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - void arm_mean_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - /** - * @brief Variance of the elements of a floating-point vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_var_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - /** - * @brief Variance of the elements of a Q31 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_var_q31( - q31_t * pSrc, - uint32_t blockSize, - q63_t * pResult); - - /** - * @brief Variance of the elements of a Q15 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_var_q15( - q15_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - /** - * @brief Root Mean Square of the elements of a floating-point vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_rms_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - /** - * @brief Root Mean Square of the elements of a Q31 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_rms_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - /** - * @brief Root Mean Square of the elements of a Q15 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_rms_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - /** - * @brief Standard deviation of the elements of a floating-point vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_std_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - /** - * @brief Standard deviation of the elements of a Q31 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_std_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - /** - * @brief Standard deviation of the elements of a Q15 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_std_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - /** - * @brief Floating-point complex magnitude - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t numSamples); - - /** - * @brief Q31 complex magnitude - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t numSamples); - - /** - * @brief Q15 complex magnitude - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t numSamples); - - /** - * @brief Q15 complex dot product - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] numSamples number of complex samples in each vector - * @param[out] *realResult real part of the result returned here - * @param[out] *imagResult imaginary part of the result returned here - * @return none. - */ - - void arm_cmplx_dot_prod_q15( - q15_t * pSrcA, - q15_t * pSrcB, - uint32_t numSamples, - q31_t * realResult, - q31_t * imagResult); - - /** - * @brief Q31 complex dot product - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] numSamples number of complex samples in each vector - * @param[out] *realResult real part of the result returned here - * @param[out] *imagResult imaginary part of the result returned here - * @return none. - */ - - void arm_cmplx_dot_prod_q31( - q31_t * pSrcA, - q31_t * pSrcB, - uint32_t numSamples, - q63_t * realResult, - q63_t * imagResult); - - /** - * @brief Floating-point complex dot product - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] numSamples number of complex samples in each vector - * @param[out] *realResult real part of the result returned here - * @param[out] *imagResult imaginary part of the result returned here - * @return none. - */ - - void arm_cmplx_dot_prod_f32( - float32_t * pSrcA, - float32_t * pSrcB, - uint32_t numSamples, - float32_t * realResult, - float32_t * imagResult); - - /** - * @brief Q15 complex-by-real multiplication - * @param[in] *pSrcCmplx points to the complex input vector - * @param[in] *pSrcReal points to the real input vector - * @param[out] *pCmplxDst points to the complex output vector - * @param[in] numSamples number of samples in each vector - * @return none. - */ - - void arm_cmplx_mult_real_q15( - q15_t * pSrcCmplx, - q15_t * pSrcReal, - q15_t * pCmplxDst, - uint32_t numSamples); - - /** - * @brief Q31 complex-by-real multiplication - * @param[in] *pSrcCmplx points to the complex input vector - * @param[in] *pSrcReal points to the real input vector - * @param[out] *pCmplxDst points to the complex output vector - * @param[in] numSamples number of samples in each vector - * @return none. - */ - - void arm_cmplx_mult_real_q31( - q31_t * pSrcCmplx, - q31_t * pSrcReal, - q31_t * pCmplxDst, - uint32_t numSamples); - - /** - * @brief Floating-point complex-by-real multiplication - * @param[in] *pSrcCmplx points to the complex input vector - * @param[in] *pSrcReal points to the real input vector - * @param[out] *pCmplxDst points to the complex output vector - * @param[in] numSamples number of samples in each vector - * @return none. - */ - - void arm_cmplx_mult_real_f32( - float32_t * pSrcCmplx, - float32_t * pSrcReal, - float32_t * pCmplxDst, - uint32_t numSamples); - - /** - * @brief Minimum value of a Q7 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *result is output pointer - * @param[in] index is the array index of the minimum value in the input buffer. - * @return none. - */ - - void arm_min_q7( - q7_t * pSrc, - uint32_t blockSize, - q7_t * result, - uint32_t * index); - - /** - * @brief Minimum value of a Q15 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output pointer - * @param[in] *pIndex is the array index of the minimum value in the input buffer. - * @return none. - */ - - void arm_min_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult, - uint32_t * pIndex); - - /** - * @brief Minimum value of a Q31 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output pointer - * @param[out] *pIndex is the array index of the minimum value in the input buffer. - * @return none. - */ - void arm_min_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult, - uint32_t * pIndex); - - /** - * @brief Minimum value of a floating-point vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output pointer - * @param[out] *pIndex is the array index of the minimum value in the input buffer. - * @return none. - */ - - void arm_min_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult, - uint32_t * pIndex); - -/** - * @brief Maximum value of a Q7 vector. - * @param[in] *pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] *pResult maximum value returned here - * @param[out] *pIndex index of maximum value returned here - * @return none. - */ - - void arm_max_q7( - q7_t * pSrc, - uint32_t blockSize, - q7_t * pResult, - uint32_t * pIndex); - -/** - * @brief Maximum value of a Q15 vector. - * @param[in] *pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] *pResult maximum value returned here - * @param[out] *pIndex index of maximum value returned here - * @return none. - */ - - void arm_max_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult, - uint32_t * pIndex); - -/** - * @brief Maximum value of a Q31 vector. - * @param[in] *pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] *pResult maximum value returned here - * @param[out] *pIndex index of maximum value returned here - * @return none. - */ - - void arm_max_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult, - uint32_t * pIndex); - -/** - * @brief Maximum value of a floating-point vector. - * @param[in] *pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] *pResult maximum value returned here - * @param[out] *pIndex index of maximum value returned here - * @return none. - */ - - void arm_max_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult, - uint32_t * pIndex); - - /** - * @brief Q15 complex-by-complex multiplication - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_mult_cmplx_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t numSamples); - - /** - * @brief Q31 complex-by-complex multiplication - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_mult_cmplx_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t numSamples); - - /** - * @brief Floating-point complex-by-complex multiplication - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_mult_cmplx_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t numSamples); - - /** - * @brief Converts the elements of the floating-point vector to Q31 vector. - * @param[in] *pSrc points to the floating-point input vector - * @param[out] *pDst points to the Q31 output vector - * @param[in] blockSize length of the input vector - * @return none. - */ - void arm_float_to_q31( - float32_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Converts the elements of the floating-point vector to Q15 vector. - * @param[in] *pSrc points to the floating-point input vector - * @param[out] *pDst points to the Q15 output vector - * @param[in] blockSize length of the input vector - * @return none - */ - void arm_float_to_q15( - float32_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Converts the elements of the floating-point vector to Q7 vector. - * @param[in] *pSrc points to the floating-point input vector - * @param[out] *pDst points to the Q7 output vector - * @param[in] blockSize length of the input vector - * @return none - */ - void arm_float_to_q7( - float32_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q31 vector to Q15 vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q31_to_q15( - q31_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Converts the elements of the Q31 vector to Q7 vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q31_to_q7( - q31_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Converts the elements of the Q15 vector to floating-point vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q15_to_float( - q15_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q15 vector to Q31 vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q15_to_q31( - q15_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q15 vector to Q7 vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q15_to_q7( - q15_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @ingroup groupInterpolation - */ - - /** - * @defgroup BilinearInterpolate Bilinear Interpolation - * - * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. - * The underlying function f(x, y) is sampled on a regular grid and the interpolation process - * determines values between the grid points. - * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. - * Bilinear interpolation is often used in image processing to rescale images. - * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. - * - * Algorithm - * \par - * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. - * For floating-point, the instance structure is defined as: - *
-   *   typedef struct
-   *   {
-   *     uint16_t numRows;
-   *     uint16_t numCols;
-   *     float32_t *pData;
-   * } arm_bilinear_interp_instance_f32;
-   * 
- * - * \par - * where numRows specifies the number of rows in the table; - * numCols specifies the number of columns in the table; - * and pData points to an array of size numRows*numCols values. - * The data table pTable is organized in row order and the supplied data values fall on integer indexes. - * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. - * - * \par - * Let (x, y) specify the desired interpolation point. Then define: - *
-   *     XF = floor(x)
-   *     YF = floor(y)
-   * 
- * \par - * The interpolated output point is computed as: - *
-   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
-   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
-   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
-   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
-   * 
- * Note that the coordinates (x, y) contain integer and fractional components. - * The integer components specify which portion of the table to use while the - * fractional components control the interpolation processor. - * - * \par - * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. - */ - - /** - * @addtogroup BilinearInterpolate - * @{ - */ - - /** - * - * @brief Floating-point bilinear interpolation. - * @param[in,out] *S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate. - * @param[in] Y interpolation coordinate. - * @return out interpolated value. - */ - - - static __INLINE float32_t arm_bilinear_interp_f32( - const arm_bilinear_interp_instance_f32 * S, - float32_t X, - float32_t Y) - { - float32_t out; - float32_t f00, f01, f10, f11; - float32_t *pData = S->pData; - int32_t xIndex, yIndex, index; - float32_t xdiff, ydiff; - float32_t b1, b2, b3, b4; - - xIndex = (int32_t) X; - yIndex = (int32_t) Y; - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if(xIndex < 0 || xIndex > (S->numRows-1) || yIndex < 0 || yIndex > ( S->numCols-1)) - { - return(0); - } - - /* Calculation of index for two nearest points in X-direction */ - index = (xIndex - 1) + (yIndex-1) * S->numCols ; - - - /* Read two nearest points in X-direction */ - f00 = pData[index]; - f01 = pData[index + 1]; - - /* Calculation of index for two nearest points in Y-direction */ - index = (xIndex-1) + (yIndex) * S->numCols; - - - /* Read two nearest points in Y-direction */ - f10 = pData[index]; - f11 = pData[index + 1]; - - /* Calculation of intermediate values */ - b1 = f00; - b2 = f01 - f00; - b3 = f10 - f00; - b4 = f00 - f01 - f10 + f11; - - /* Calculation of fractional part in X */ - xdiff = X - xIndex; - - /* Calculation of fractional part in Y */ - ydiff = Y - yIndex; - - /* Calculation of bi-linear interpolated output */ - out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; - - /* return to application */ - return (out); - - } - - /** - * - * @brief Q31 bilinear interpolation. - * @param[in,out] *S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate in 12.20 format. - * @param[in] Y interpolation coordinate in 12.20 format. - * @return out interpolated value. - */ - - static __INLINE q31_t arm_bilinear_interp_q31( - arm_bilinear_interp_instance_q31 * S, - q31_t X, - q31_t Y) - { - q31_t out; /* Temporary output */ - q31_t acc = 0; /* output */ - q31_t xfract, yfract; /* X, Y fractional parts */ - q31_t x1, x2, y1, y2; /* Nearest output values */ - int32_t rI, cI; /* Row and column indices */ - q31_t *pYData = S->pData; /* pointer to output table values */ - uint32_t nCols = S->numCols; /* num of rows */ - - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - rI = ((X & 0xFFF00000) >> 20u); - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - cI = ((Y & 0xFFF00000) >> 20u); - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if(rI < 0 || rI > (S->numRows-1) || cI < 0 || cI > ( S->numCols-1)) - { - return(0); - } - - /* 20 bits for the fractional part */ - /* shift left xfract by 11 to keep 1.31 format */ - xfract = (X & 0x000FFFFF) << 11u; - - /* Read two nearest output values from the index */ - x1 = pYData[(rI) + nCols * (cI)]; - x2 = pYData[(rI) + nCols * (cI) + 1u]; - - /* 20 bits for the fractional part */ - /* shift left yfract by 11 to keep 1.31 format */ - yfract = (Y & 0x000FFFFF) << 11u; - - /* Read two nearest output values from the index */ - y1 = pYData[(rI) + nCols * (cI + 1)]; - y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; - - /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ - out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); - acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); - - /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ - out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); - acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); - - /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ - out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); - acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); - - /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ - out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); - acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); - - /* Convert acc to 1.31(q31) format */ - return (acc << 2u); - - } - - /** - * @brief Q15 bilinear interpolation. - * @param[in,out] *S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate in 12.20 format. - * @param[in] Y interpolation coordinate in 12.20 format. - * @return out interpolated value. - */ - - static __INLINE q15_t arm_bilinear_interp_q15( - arm_bilinear_interp_instance_q15 * S, - q31_t X, - q31_t Y) - { - q63_t acc = 0; /* output */ - q31_t out; /* Temporary output */ - q15_t x1, x2, y1, y2; /* Nearest output values */ - q31_t xfract, yfract; /* X, Y fractional parts */ - int32_t rI, cI; /* Row and column indices */ - q15_t *pYData = S->pData; /* pointer to output table values */ - uint32_t nCols = S->numCols; /* num of rows */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - rI = ((X & 0xFFF00000) >> 20); - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - cI = ((Y & 0xFFF00000) >> 20); - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if(rI < 0 || rI > (S->numRows-1) || cI < 0 || cI > ( S->numCols-1)) - { - return(0); - } - - /* 20 bits for the fractional part */ - /* xfract should be in 12.20 format */ - xfract = (X & 0x000FFFFF); - - /* Read two nearest output values from the index */ - x1 = pYData[(rI) + nCols * (cI)]; - x2 = pYData[(rI) + nCols * (cI) + 1u]; - - - /* 20 bits for the fractional part */ - /* yfract should be in 12.20 format */ - yfract = (Y & 0x000FFFFF); - - /* Read two nearest output values from the index */ - y1 = pYData[(rI) + nCols * (cI + 1)]; - y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; - - /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ - - /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ - /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ - out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u); - acc = ((q63_t) out * (0xFFFFF - yfract)); - - /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ - out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u); - acc += ((q63_t) out * (xfract)); - - /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ - out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u); - acc += ((q63_t) out * (yfract)); - - /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ - out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u); - acc += ((q63_t) out * (yfract)); - - /* acc is in 13.51 format and down shift acc by 36 times */ - /* Convert out to 1.15 format */ - return (acc >> 36); - - } - - /** - * @brief Q7 bilinear interpolation. - * @param[in,out] *S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate in 12.20 format. - * @param[in] Y interpolation coordinate in 12.20 format. - * @return out interpolated value. - */ - - static __INLINE q7_t arm_bilinear_interp_q7( - arm_bilinear_interp_instance_q7 * S, - q31_t X, - q31_t Y) - { - q63_t acc = 0; /* output */ - q31_t out; /* Temporary output */ - q31_t xfract, yfract; /* X, Y fractional parts */ - q7_t x1, x2, y1, y2; /* Nearest output values */ - int32_t rI, cI; /* Row and column indices */ - q7_t *pYData = S->pData; /* pointer to output table values */ - uint32_t nCols = S->numCols; /* num of rows */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - rI = ((X & 0xFFF00000) >> 20); - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - cI = ((Y & 0xFFF00000) >> 20); - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if(rI < 0 || rI > (S->numRows-1) || cI < 0 || cI > ( S->numCols-1)) - { - return(0); - } - - /* 20 bits for the fractional part */ - /* xfract should be in 12.20 format */ - xfract = (X & 0x000FFFFF); - - /* Read two nearest output values from the index */ - x1 = pYData[(rI) + nCols * (cI)]; - x2 = pYData[(rI) + nCols * (cI) + 1u]; - - - /* 20 bits for the fractional part */ - /* yfract should be in 12.20 format */ - yfract = (Y & 0x000FFFFF); - - /* Read two nearest output values from the index */ - y1 = pYData[(rI) + nCols * (cI + 1)]; - y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; - - /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ - out = ((x1 * (0xFFFFF - xfract))); - acc = (((q63_t) out * (0xFFFFF - yfract))); - - /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ - out = ((x2 * (0xFFFFF - yfract))); - acc += (((q63_t) out * (xfract))); - - /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ - out = ((y1 * (0xFFFFF - xfract))); - acc += (((q63_t) out * (yfract))); - - /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ - out = ((y2 * (yfract))); - acc += (((q63_t) out * (xfract))); - - /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ - return (acc >> 40); - - } - - /** - * @} end of BilinearInterpolate group - */ - - - - - - -#ifdef __cplusplus -} -#endif - - -#endif /* _ARM_MATH_H */ - - -/** - * - * End of file. - */ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm0.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm0.h deleted file mode 100644 index 9d7a19f9a..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm0.h +++ /dev/null @@ -1,665 +0,0 @@ -/**************************************************************************//** - * @file core_cm0.h - * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File - * @version V2.10 - * @date 19. July 2011 - * - * @note - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * @par - * ARM Limited (ARM) is supplying this software for use with Cortex-M - * processor based microcontrollers. This file can be freely distributed - * within development tools that are supporting such ARM based processors. - * - * @par - * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED - * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. - * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. - * - ******************************************************************************/ -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifdef __cplusplus - extern "C" { -#endif - -#ifndef __CORE_CM0_H_GENERIC -#define __CORE_CM0_H_GENERIC - - -/** \mainpage CMSIS Cortex-M0 - - This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer. - It consists of: - - - Cortex-M Core Register Definitions - - Cortex-M functions - - Cortex-M instructions - - The CMSIS Cortex-M0 Core Peripheral Access Layer contains C and assembly functions that ease - access to the Cortex-M Core - */ - -/** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions - CMSIS violates following MISRA-C2004 Rules: - - - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'. - - - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \defgroup CMSIS_core_definitions CMSIS Core Definitions - This file defines all structures and symbols for CMSIS core: - - CMSIS version number - - Cortex-M core - - Cortex-M core Revision Number - @{ - */ - -/* CMSIS CM0 definitions */ -#define __CM0_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */ -#define __CM0_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */ -#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | __CM0_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x00) /*!< Cortex core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - -#endif - -/*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */ -#define __FPU_USED 0 - -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TASKING__ ) - /* add preprocessor checks */ -#endif - -#include /*!< standard types definitions */ -#include "core_cmInstr.h" /*!< Core Instruction Access */ -#include "core_cmFunc.h" /*!< Core Function Access */ - -#endif /* __CORE_CM0_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM0_H_DEPENDANT -#define __CORE_CM0_H_DEPENDANT - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM0_REV - #define __CM0_REV 0x0000 - #warning "__CM0_REV not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 2 - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0 - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -#ifdef __cplusplus - #define __I volatile /*!< defines 'read only' permissions */ -#else - #define __I volatile const /*!< defines 'read only' permissions */ -#endif -#define __O volatile /*!< defines 'write only' permissions */ -#define __IO volatile /*!< defines 'read / write' permissions */ - -/*@} end of group CMSIS_core_definitions */ - - - -/******************************************************************************* - * Register Abstraction - ******************************************************************************/ -/** \defgroup CMSIS_core_register CMSIS Core Register - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register -*/ - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CORE CMSIS Core - Type definitions for the Cortex-M Core Registers - @{ - */ - -/** \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { -#if (__CORTEX_M != 0x04) - uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ -#else - uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ -#endif - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} APSR_Type; - - -/** \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - - -/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ -#if (__CORTEX_M != 0x04) - uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ -#else - uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ -#endif - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} xPSR_Type; - - -/** \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ - uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/*@} end of group CMSIS_CORE */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC CMSIS NVIC - Type definitions for the Cortex-M NVIC Registers - @{ - */ - -/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[31]; - __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[31]; - __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[31]; - __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[31]; - uint32_t RESERVED4[64]; - __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ -} NVIC_Type; - -/*@} end of group CMSIS_NVIC */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCB CMSIS SCB - Type definitions for the Cortex-M System Control Block Registers - @{ - */ - -/** \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - uint32_t RESERVED0; - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - uint32_t RESERVED1; - __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ - -#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ -#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ - -/* SCB Configuration Control Register Definitions */ -#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick CMSIS SysTick - Type definitions for the Cortex-M System Timer Registers - @{ - */ - -/** \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug CMSIS Core Debug - Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP - and not via processor. Therefore they are not covered by the Cortex-M0 header file. - @{ - */ -/*@} end of group CMSIS_CoreDebug */ - - -/** \ingroup CMSIS_core_register - @{ - */ - -/* Memory mapping of Cortex-M0 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ - - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - ******************************************************************************/ -/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Register Access Functions -*/ - - - -/* ########################## NVIC functions #################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions - @{ - */ - -/* Interrupt Priorities are WORD accessible only under ARMv6M */ -/* The following MACROS handle generation of the register offset and byte masks */ -#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 ) -#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) ) -#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) - - -/** \brief Enable External Interrupt - - This function enables a device specific interrupt in the NVIC interrupt controller. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the external interrupt to enable - */ -static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - - -/** \brief Disable External Interrupt - - This function disables a device specific interrupt in the NVIC interrupt controller. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the external interrupt to disable - */ -static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - - -/** \brief Get Pending Interrupt - - This function reads the pending register in the NVIC and returns the pending bit - for the specified interrupt. - - \param [in] IRQn Number of the interrupt for get pending - \return 0 Interrupt status is not pending - \return 1 Interrupt status is pending - */ -static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - - -/** \brief Set Pending Interrupt - - This function sets the pending bit for the specified interrupt. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the interrupt for set pending - */ -static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - - -/** \brief Clear Pending Interrupt - - This function clears the pending bit for the specified interrupt. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the interrupt for clear pending - */ -static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ -} - - -/** \brief Set Interrupt Priority - - This function sets the priority for the specified interrupt. The interrupt - number can be positive to specify an external (device specific) - interrupt, or negative to specify an internal (core) interrupt. - - Note: The priority cannot be set for every core interrupt. - - \param [in] IRQn Number of the interrupt for set priority - \param [in] priority Priority to set - */ -static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if(IRQn < 0) { - SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | - (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } - else { - NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | - (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } -} - - -/** \brief Get Interrupt Priority - - This function reads the priority for the specified interrupt. The interrupt - number can be positive to specify an external (device specific) - interrupt, or negative to specify an internal (core) interrupt. - - The returned priority value is automatically aligned to the implemented - priority bits of the microcontroller. - - \param [in] IRQn Number of the interrupt for get priority - \return Interrupt Priority - */ -static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) -{ - - if(IRQn < 0) { - return((uint32_t)((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */ - else { - return((uint32_t)((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ -} - - -/** \brief System Reset - - This function initiate a system reset request to reset the MCU. - */ -static __INLINE void NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | - SCB_AIRCR_SYSRESETREQ_Msk); - __DSB(); /* Ensure completion of memory access */ - while(1); /* wait until reset */ -} - -/*@} end of CMSIS_Core_NVICFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions CMSIS Core SysTick Functions - @{ - */ - -#if (__Vendor_SysTickConfig == 0) - -/** \brief System Tick Configuration - - This function initialises the system tick timer and its interrupt and start the system tick timer. - Counter is in free running mode to generate periodical interrupts. - - \param [in] ticks Number of ticks between two interrupts - \return 0 Function succeeded - \return 1 Function failed - */ -static __INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ - - SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ - SysTick->VAL = 0; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - - -#endif /* __CORE_CM0_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ - -#ifdef __cplusplus -} -#endif diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm3.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm3.c deleted file mode 100644 index fcff0d133..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm3.c +++ /dev/null @@ -1,784 +0,0 @@ -/**************************************************************************//** - * @file core_cm3.c - * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File - * @version V1.30 - * @date 30. October 2009 - * - * @note - * Copyright (C) 2009 ARM Limited. All rights reserved. - * - * @par - * ARM Limited (ARM) is supplying this software for use with Cortex-M - * processor based microcontrollers. This file can be freely distributed - * within development tools that are supporting such ARM based processors. - * - * @par - * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED - * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. - * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. - * - ******************************************************************************/ - -#include - -/* define compiler specific symbols */ -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */ - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - -#endif - - -/* ################### Compiler specific Intrinsics ########################### */ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -/** - * @brief Return the Process Stack Pointer - * - * @return ProcessStackPointer - * - * Return the actual process stack pointer - */ -__ASM uint32_t __get_PSP(void) -{ - mrs r0, psp - bx lr -} - -/** - * @brief Set the Process Stack Pointer - * - * @param topOfProcStack Process Stack Pointer - * - * Assign the value ProcessStackPointer to the MSP - * (process stack pointer) Cortex processor register - */ -__ASM void __set_PSP(uint32_t topOfProcStack) -{ - msr psp, r0 - bx lr -} - -/** - * @brief Return the Main Stack Pointer - * - * @return Main Stack Pointer - * - * Return the current value of the MSP (main stack pointer) - * Cortex processor register - */ -__ASM uint32_t __get_MSP(void) -{ - mrs r0, msp - bx lr -} - -/** - * @brief Set the Main Stack Pointer - * - * @param topOfMainStack Main Stack Pointer - * - * Assign the value mainStackPointer to the MSP - * (main stack pointer) Cortex processor register - */ -__ASM void __set_MSP(uint32_t mainStackPointer) -{ - msr msp, r0 - bx lr -} - -/** - * @brief Reverse byte order in unsigned short value - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in unsigned short value - */ -__ASM uint32_t __REV16(uint16_t value) -{ - rev16 r0, r0 - bx lr -} - -/** - * @brief Reverse byte order in signed short value with sign extension to integer - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in signed short value with sign extension to integer - */ -__ASM int32_t __REVSH(int16_t value) -{ - revsh r0, r0 - bx lr -} - - -#if (__ARMCC_VERSION < 400000) - -/** - * @brief Remove the exclusive lock created by ldrex - * - * Removes the exclusive lock which is created by ldrex. - */ -__ASM void __CLREX(void) -{ - clrex -} - -/** - * @brief Return the Base Priority value - * - * @return BasePriority - * - * Return the content of the base priority register - */ -__ASM uint32_t __get_BASEPRI(void) -{ - mrs r0, basepri - bx lr -} - -/** - * @brief Set the Base Priority value - * - * @param basePri BasePriority - * - * Set the base priority register - */ -__ASM void __set_BASEPRI(uint32_t basePri) -{ - msr basepri, r0 - bx lr -} - -/** - * @brief Return the Priority Mask value - * - * @return PriMask - * - * Return state of the priority mask bit from the priority mask register - */ -__ASM uint32_t __get_PRIMASK(void) -{ - mrs r0, primask - bx lr -} - -/** - * @brief Set the Priority Mask value - * - * @param priMask PriMask - * - * Set the priority mask bit in the priority mask register - */ -__ASM void __set_PRIMASK(uint32_t priMask) -{ - msr primask, r0 - bx lr -} - -/** - * @brief Return the Fault Mask value - * - * @return FaultMask - * - * Return the content of the fault mask register - */ -__ASM uint32_t __get_FAULTMASK(void) -{ - mrs r0, faultmask - bx lr -} - -/** - * @brief Set the Fault Mask value - * - * @param faultMask faultMask value - * - * Set the fault mask register - */ -__ASM void __set_FAULTMASK(uint32_t faultMask) -{ - msr faultmask, r0 - bx lr -} - -/** - * @brief Return the Control Register value - * - * @return Control value - * - * Return the content of the control register - */ -__ASM uint32_t __get_CONTROL(void) -{ - mrs r0, control - bx lr -} - -/** - * @brief Set the Control Register value - * - * @param control Control value - * - * Set the control register - */ -__ASM void __set_CONTROL(uint32_t control) -{ - msr control, r0 - bx lr -} - -#endif /* __ARMCC_VERSION */ - - - -#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ -#pragma diag_suppress=Pe940 - -/** - * @brief Return the Process Stack Pointer - * - * @return ProcessStackPointer - * - * Return the actual process stack pointer - */ -uint32_t __get_PSP(void) -{ - __ASM("mrs r0, psp"); - __ASM("bx lr"); -} - -/** - * @brief Set the Process Stack Pointer - * - * @param topOfProcStack Process Stack Pointer - * - * Assign the value ProcessStackPointer to the MSP - * (process stack pointer) Cortex processor register - */ -void __set_PSP(uint32_t topOfProcStack) -{ - __ASM("msr psp, r0"); - __ASM("bx lr"); -} - -/** - * @brief Return the Main Stack Pointer - * - * @return Main Stack Pointer - * - * Return the current value of the MSP (main stack pointer) - * Cortex processor register - */ -uint32_t __get_MSP(void) -{ - __ASM("mrs r0, msp"); - __ASM("bx lr"); -} - -/** - * @brief Set the Main Stack Pointer - * - * @param topOfMainStack Main Stack Pointer - * - * Assign the value mainStackPointer to the MSP - * (main stack pointer) Cortex processor register - */ -void __set_MSP(uint32_t topOfMainStack) -{ - __ASM("msr msp, r0"); - __ASM("bx lr"); -} - -/** - * @brief Reverse byte order in unsigned short value - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in unsigned short value - */ -uint32_t __REV16(uint16_t value) -{ - __ASM("rev16 r0, r0"); - __ASM("bx lr"); -} - -/** - * @brief Reverse bit order of value - * - * @param value value to reverse - * @return reversed value - * - * Reverse bit order of value - */ -uint32_t __RBIT(uint32_t value) -{ - __ASM("rbit r0, r0"); - __ASM("bx lr"); -} - -/** - * @brief LDR Exclusive (8 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 8 bit values) - */ -uint8_t __LDREXB(uint8_t *addr) -{ - __ASM("ldrexb r0, [r0]"); - __ASM("bx lr"); -} - -/** - * @brief LDR Exclusive (16 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 16 bit values - */ -uint16_t __LDREXH(uint16_t *addr) -{ - __ASM("ldrexh r0, [r0]"); - __ASM("bx lr"); -} - -/** - * @brief LDR Exclusive (32 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 32 bit values - */ -uint32_t __LDREXW(uint32_t *addr) -{ - __ASM("ldrex r0, [r0]"); - __ASM("bx lr"); -} - -/** - * @brief STR Exclusive (8 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 8 bit values - */ -uint32_t __STREXB(uint8_t value, uint8_t *addr) -{ - __ASM("strexb r0, r0, [r1]"); - __ASM("bx lr"); -} - -/** - * @brief STR Exclusive (16 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 16 bit values - */ -uint32_t __STREXH(uint16_t value, uint16_t *addr) -{ - __ASM("strexh r0, r0, [r1]"); - __ASM("bx lr"); -} - -/** - * @brief STR Exclusive (32 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 32 bit values - */ -uint32_t __STREXW(uint32_t value, uint32_t *addr) -{ - __ASM("strex r0, r0, [r1]"); - __ASM("bx lr"); -} - -#pragma diag_default=Pe940 - - -#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/** - * @brief Return the Process Stack Pointer - * - * @return ProcessStackPointer - * - * Return the actual process stack pointer - */ -uint32_t __get_PSP(void) __attribute__( ( naked ) ); -uint32_t __get_PSP(void) -{ - uint32_t result=0; - - __ASM volatile ("MRS %0, psp\n\t" - "MOV r0, %0 \n\t" - "BX lr \n\t" : "=r" (result) ); - return(result); -} - -/** - * @brief Set the Process Stack Pointer - * - * @param topOfProcStack Process Stack Pointer - * - * Assign the value ProcessStackPointer to the MSP - * (process stack pointer) Cortex processor register - */ -void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) ); -void __set_PSP(uint32_t topOfProcStack) -{ - __ASM volatile ("MSR psp, %0\n\t" - "BX lr \n\t" : : "r" (topOfProcStack) ); -} - -/** - * @brief Return the Main Stack Pointer - * - * @return Main Stack Pointer - * - * Return the current value of the MSP (main stack pointer) - * Cortex processor register - */ -uint32_t __get_MSP(void) __attribute__( ( naked ) ); -uint32_t __get_MSP(void) -{ - uint32_t result=0; - - __ASM volatile ("MRS %0, msp\n\t" - "MOV r0, %0 \n\t" - "BX lr \n\t" : "=r" (result) ); - return(result); -} - -/** - * @brief Set the Main Stack Pointer - * - * @param topOfMainStack Main Stack Pointer - * - * Assign the value mainStackPointer to the MSP - * (main stack pointer) Cortex processor register - */ -void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) ); -void __set_MSP(uint32_t topOfMainStack) -{ - __ASM volatile ("MSR msp, %0\n\t" - "BX lr \n\t" : : "r" (topOfMainStack) ); -} - -/** - * @brief Return the Base Priority value - * - * @return BasePriority - * - * Return the content of the base priority register - */ -uint32_t __get_BASEPRI(void) -{ - uint32_t result=0; - - __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); - return(result); -} - -/** - * @brief Set the Base Priority value - * - * @param basePri BasePriority - * - * Set the base priority register - */ -void __set_BASEPRI(uint32_t value) -{ - __ASM volatile ("MSR basepri, %0" : : "r" (value) ); -} - -/** - * @brief Return the Priority Mask value - * - * @return PriMask - * - * Return state of the priority mask bit from the priority mask register - */ -uint32_t __get_PRIMASK(void) -{ - uint32_t result=0; - - __ASM volatile ("MRS %0, primask" : "=r" (result) ); - return(result); -} - -/** - * @brief Set the Priority Mask value - * - * @param priMask PriMask - * - * Set the priority mask bit in the priority mask register - */ -void __set_PRIMASK(uint32_t priMask) -{ - __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); -} - -/** - * @brief Return the Fault Mask value - * - * @return FaultMask - * - * Return the content of the fault mask register - */ -uint32_t __get_FAULTMASK(void) -{ - uint32_t result=0; - - __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); - return(result); -} - -/** - * @brief Set the Fault Mask value - * - * @param faultMask faultMask value - * - * Set the fault mask register - */ -void __set_FAULTMASK(uint32_t faultMask) -{ - __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) ); -} - -/** - * @brief Return the Control Register value -* -* @return Control value - * - * Return the content of the control register - */ -uint32_t __get_CONTROL(void) -{ - uint32_t result=0; - - __ASM volatile ("MRS %0, control" : "=r" (result) ); - return(result); -} - -/** - * @brief Set the Control Register value - * - * @param control Control value - * - * Set the control register - */ -void __set_CONTROL(uint32_t control) -{ - __ASM volatile ("MSR control, %0" : : "r" (control) ); -} - - -/** - * @brief Reverse byte order in integer value - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in integer value - */ -uint32_t __REV(uint32_t value) -{ - uint32_t result=0; - - __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - -/** - * @brief Reverse byte order in unsigned short value - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in unsigned short value - */ -uint32_t __REV16(uint16_t value) -{ - uint32_t result=0; - - __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - -/** - * @brief Reverse byte order in signed short value with sign extension to integer - * - * @param value value to reverse - * @return reversed value - * - * Reverse byte order in signed short value with sign extension to integer - */ -int32_t __REVSH(int16_t value) -{ - uint32_t result=0; - - __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - -/** - * @brief Reverse bit order of value - * - * @param value value to reverse - * @return reversed value - * - * Reverse bit order of value - */ -uint32_t __RBIT(uint32_t value) -{ - uint32_t result=0; - - __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - -/** - * @brief LDR Exclusive (8 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 8 bit value - */ -uint8_t __LDREXB(uint8_t *addr) -{ - uint8_t result=0; - - __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - -/** - * @brief LDR Exclusive (16 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 16 bit values - */ -uint16_t __LDREXH(uint16_t *addr) -{ - uint16_t result=0; - - __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - -/** - * @brief LDR Exclusive (32 bit) - * - * @param *addr address pointer - * @return value of (*address) - * - * Exclusive LDR command for 32 bit values - */ -uint32_t __LDREXW(uint32_t *addr) -{ - uint32_t result=0; - - __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - -/** - * @brief STR Exclusive (8 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 8 bit values - */ -uint32_t __STREXB(uint8_t value, uint8_t *addr) -{ - uint32_t result=0; - - __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); - return(result); -} - -/** - * @brief STR Exclusive (16 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 16 bit values - */ -uint32_t __STREXH(uint16_t value, uint16_t *addr) -{ - uint32_t result=0; - - __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); - return(result); -} - -/** - * @brief STR Exclusive (32 bit) - * - * @param value value to store - * @param *addr address pointer - * @return successful / failed - * - * Exclusive STR command for 32 bit values - */ -uint32_t __STREXW(uint32_t value, uint32_t *addr) -{ - uint32_t result=0; - - __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); - return(result); -} - - -#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/ -/* TASKING carm specific functions */ - -/* - * The CMSIS functions have been implemented as intrinsics in the compiler. - * Please use "carm -?i" to get an up to date list of all instrinsics, - * Including the CMSIS ones. - */ - -#endif diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm3.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm3.h deleted file mode 100644 index 1c688181a..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm3.h +++ /dev/null @@ -1,1236 +0,0 @@ -/**************************************************************************//** - * @file core_cm3.h - * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File - * @version V2.10 - * @date 19. July 2011 - * - * @note - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * @par - * ARM Limited (ARM) is supplying this software for use with Cortex-M - * processor based microcontrollers. This file can be freely distributed - * within development tools that are supporting such ARM based processors. - * - * @par - * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED - * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. - * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. - * - ******************************************************************************/ -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifdef __cplusplus - extern "C" { -#endif - -#ifndef __CORE_CM3_H_GENERIC -#define __CORE_CM3_H_GENERIC - - -/** \mainpage CMSIS Cortex-M3 - - This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer. - It consists of: - - - Cortex-M Core Register Definitions - - Cortex-M functions - - Cortex-M instructions - - The CMSIS Cortex-M3 Core Peripheral Access Layer contains C and assembly functions that ease - access to the Cortex-M Core - */ - -/** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions - CMSIS violates following MISRA-C2004 Rules: - - - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'. - - - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \defgroup CMSIS_core_definitions CMSIS Core Definitions - This file defines all structures and symbols for CMSIS core: - - CMSIS version number - - Cortex-M core - - Cortex-M core Revision Number - @{ - */ - -/* CMSIS CM3 definitions */ -#define __CM3_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */ -#define __CM3_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */ -#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x03) /*!< Cortex core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - -#endif - -/*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */ -#define __FPU_USED 0 - -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TASKING__ ) - /* add preprocessor checks */ -#endif - -#include /*!< standard types definitions */ -#include "core_cmInstr.h" /*!< Core Instruction Access */ -#include "core_cmFunc.h" /*!< Core Function Access */ - -#endif /* __CORE_CM3_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM3_H_DEPENDANT -#define __CORE_CM3_H_DEPENDANT - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM3_REV - #define __CM3_REV 0x0200 - #warning "__CM3_REV not defined in device header file; using default!" - #endif - - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0 - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 4 - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0 - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -#ifdef __cplusplus - #define __I volatile /*!< defines 'read only' permissions */ -#else - #define __I volatile const /*!< defines 'read only' permissions */ -#endif -#define __O volatile /*!< defines 'write only' permissions */ -#define __IO volatile /*!< defines 'read / write' permissions */ - -/*@} end of group CMSIS_core_definitions */ - - - -/******************************************************************************* - * Register Abstraction - ******************************************************************************/ -/** \defgroup CMSIS_core_register CMSIS Core Register - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core Debug Register - - Core MPU Register -*/ - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CORE CMSIS Core - Type definitions for the Cortex-M Core Registers - @{ - */ - -/** \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { -#if (__CORTEX_M != 0x04) - uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ -#else - uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ -#endif - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} APSR_Type; - - -/** \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - - -/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ -#if (__CORTEX_M != 0x04) - uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ -#else - uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ -#endif - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} xPSR_Type; - - -/** \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ - uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/*@} end of group CMSIS_CORE */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC CMSIS NVIC - Type definitions for the Cortex-M NVIC Registers - @{ - */ - -/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[24]; - __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[24]; - __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[24]; - __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[24]; - __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ - uint32_t RESERVED4[56]; - __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644]; - __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ -} NVIC_Type; - -/* Software Triggered Interrupt Register Definitions */ -#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ -#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ - -/*@} end of group CMSIS_NVIC */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCB CMSIS SCB - Type definitions for the Cortex-M System Control Block Registers - @{ - */ - -/** \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ - __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ - __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ - __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ - __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ - __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ - __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[5]; - __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ - -#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ -#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ -#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Vector Table Offset Register Definitions */ -#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ -#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ -#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ - -/* SCB Configuration Control Register Definitions */ -#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ -#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ - -#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ -#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ -#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ - -#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ -#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ -#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ - -#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ -#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ - -#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ -#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ - -#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ -#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ - -#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ -#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ - -#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ -#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ - -#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ -#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ - -#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ -#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ - -#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ -#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ - -#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ -#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ - -#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ -#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ - -#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ -#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ - -#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ -#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ - -/* SCB Configurable Fault Status Registers Definitions */ -#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ -#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ - -#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ -#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ - -#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ -#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ - -/* SCB Hard Fault Status Registers Definitions */ -#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ -#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ - -#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ -#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ - -#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ -#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ - -/* SCB Debug Fault Status Register Definitions */ -#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ -#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ - -#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ -#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ - -#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ -#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ - -#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ -#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ - -#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ -#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCnSCB CMSIS System Control and ID Register not in the SCB - Type definitions for the Cortex-M System Control and ID Register not in the SCB - @{ - */ - -/** \brief Structure type to access the System Control and ID Register not in the SCB. - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ -#if ((defined __CM3_REV) && (__CM3_REV >= 0x200)) - __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ -#else - uint32_t RESERVED1[1]; -#endif -} SCnSCB_Type; - -/* Interrupt Controller Type Register Definitions */ -#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ -#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ - -/* Auxiliary Control Register Definitions */ - -#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ -#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ - -#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ -#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ - -#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ -#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ - -/*@} end of group CMSIS_SCnotSCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick CMSIS SysTick - Type definitions for the Cortex-M System Timer Registers - @{ - */ - -/** \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_ITM CMSIS ITM - Type definitions for the Cortex-M Instrumentation Trace Macrocell (ITM) - @{ - */ - -/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). - */ -typedef struct -{ - __O union - { - __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ - __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ - __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ - } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ - uint32_t RESERVED0[864]; - __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ - uint32_t RESERVED1[15]; - __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ - uint32_t RESERVED2[15]; - __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ -} ITM_Type; - -/* ITM Trace Privilege Register Definitions */ -#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ - -/* ITM Trace Control Register Definitions */ -#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ -#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ - -#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ -#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ - -#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ -#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ - -#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ -#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ - -#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ -#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ - -#define ITM_TCR_TXENA_Pos 3 /*!< ITM TCR: TXENA Position */ -#define ITM_TCR_TXENA_Msk (1UL << ITM_TCR_TXENA_Pos) /*!< ITM TCR: TXENA Mask */ - -#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ -#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ - -#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ -#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ - -#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ -#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ - -/*@}*/ /* end of group CMSIS_ITM */ - - -#if (__MPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_MPU CMSIS MPU - Type definitions for the Cortex-M Memory Protection Unit (MPU) - @{ - */ - -/** \brief Structure type to access the Memory Protection Unit (MPU). - */ -typedef struct -{ - __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ - __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ - __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ - __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ - __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ - __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ - __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ -} MPU_Type; - -/* MPU Type Register */ -#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ - -#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ - -#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ - -/* MPU Control Register */ -#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ - -#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ - -#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ - -/* MPU Region Number Register */ -#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ - -/* MPU Region Base Address Register */ -#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ - -#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ - -#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ - -/* MPU Region Attribute and Size Register */ -#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ -#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ - -#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ -#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ - -#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ -#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ - -#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@} end of group CMSIS_MPU */ -#endif - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug CMSIS Core Debug - Type definitions for the Cortex-M Core Debug Registers - @{ - */ - -/** \brief Structure type to access the Core Debug Register (CoreDebug). - */ -typedef struct -{ - __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ - __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ - __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ - __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ -} CoreDebug_Type; - -/* Debug Halting Control and Status Register */ -#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ -#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ - -#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ -#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ - -#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ -#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ - -#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ -#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ - -#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ -#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ - -#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ -#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ - -#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ -#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ - -#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ -#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ - -#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ -#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ - -#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ -#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ - -#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ -#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ - -#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ -#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ - -/* Debug Core Register Selector Register */ -#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ -#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ - -#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ -#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ - -/* Debug Exception and Monitor Control Register */ -#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ -#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ - -#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ -#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ - -#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ -#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ - -#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ -#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ - -#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ -#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ - -#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ -#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ - -#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ -#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ - -#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ -#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ - -#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ -#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ - -#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ -#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ - -#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ -#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ - -#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ -#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ - -#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ -#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ - -/*@} end of group CMSIS_CoreDebug */ - - -/** \ingroup CMSIS_core_register - @{ - */ - -/* Memory mapping of Cortex-M3 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ -#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ -#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ - -#if (__MPU_PRESENT == 1) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - ******************************************************************************/ -/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Debug Functions - - Core Register Access Functions -*/ - - - -/* ########################## NVIC functions #################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions - @{ - */ - -/** \brief Set Priority Grouping - - This function sets the priority grouping field using the required unlock sequence. - The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. - Only values from 0..7 are used. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. - - \param [in] PriorityGroup Priority grouping field - */ -static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) -{ - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ - - reg_value = SCB->AIRCR; /* read old register configuration */ - reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ - reg_value = (reg_value | - ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ - SCB->AIRCR = reg_value; -} - - -/** \brief Get Priority Grouping - - This function gets the priority grouping from NVIC Interrupt Controller. - Priority grouping is SCB->AIRCR [10:8] PRIGROUP field. - - \return Priority grouping field - */ -static __INLINE uint32_t NVIC_GetPriorityGrouping(void) -{ - return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ -} - - -/** \brief Enable External Interrupt - - This function enables a device specific interrupt in the NVIC interrupt controller. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the external interrupt to enable - */ -static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ -} - - -/** \brief Disable External Interrupt - - This function disables a device specific interrupt in the NVIC interrupt controller. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the external interrupt to disable - */ -static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ -} - - -/** \brief Get Pending Interrupt - - This function reads the pending register in the NVIC and returns the pending bit - for the specified interrupt. - - \param [in] IRQn Number of the interrupt for get pending - \return 0 Interrupt status is not pending - \return 1 Interrupt status is pending - */ -static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ -} - - -/** \brief Set Pending Interrupt - - This function sets the pending bit for the specified interrupt. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the interrupt for set pending - */ -static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ -} - - -/** \brief Clear Pending Interrupt - - This function clears the pending bit for the specified interrupt. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the interrupt for clear pending - */ -static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ -} - - -/** \brief Get Active Interrupt - - This function reads the active register in NVIC and returns the active bit. - \param [in] IRQn Number of the interrupt for get active - \return 0 Interrupt status is not active - \return 1 Interrupt status is active - */ -static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ -} - - -/** \brief Set Interrupt Priority - - This function sets the priority for the specified interrupt. The interrupt - number can be positive to specify an external (device specific) - interrupt, or negative to specify an internal (core) interrupt. - - Note: The priority cannot be set for every core interrupt. - - \param [in] IRQn Number of the interrupt for set priority - \param [in] priority Priority to set - */ -static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if(IRQn < 0) { - SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ - else { - NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ -} - - -/** \brief Get Interrupt Priority - - This function reads the priority for the specified interrupt. The interrupt - number can be positive to specify an external (device specific) - interrupt, or negative to specify an internal (core) interrupt. - - The returned priority value is automatically aligned to the implemented - priority bits of the microcontroller. - - \param [in] IRQn Number of the interrupt for get priority - \return Interrupt Priority - */ -static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) -{ - - if(IRQn < 0) { - return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ - else { - return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ -} - - -/** \brief Encode Priority - - This function encodes the priority for an interrupt with the given priority group, - preemptive priority value and sub priority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. - - The returned priority value can be used for NVIC_SetPriority(...) function - - \param [in] PriorityGroup Used priority group - \param [in] PreemptPriority Preemptive priority value (starting from 0) - \param [in] SubPriority Sub priority value (starting from 0) - \return Encoded priority for the interrupt - */ -static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; - SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; - - return ( - ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | - ((SubPriority & ((1 << (SubPriorityBits )) - 1))) - ); -} - - -/** \brief Decode Priority - - This function decodes an interrupt priority value with the given priority group to - preemptive priority value and sub priority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. - - The priority value can be retrieved with NVIC_GetPriority(...) function - - \param [in] Priority Priority value - \param [in] PriorityGroup Used priority group - \param [out] pPreemptPriority Preemptive priority value (starting from 0) - \param [out] pSubPriority Sub priority value (starting from 0) - */ -static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; - SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; - - *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); - *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); -} - - -/** \brief System Reset - - This function initiate a system reset request to reset the MCU. - */ -static __INLINE void NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | - (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | - SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ - __DSB(); /* Ensure completion of memory access */ - while(1); /* wait until reset */ -} - -/*@} end of CMSIS_Core_NVICFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions CMSIS Core SysTick Functions - @{ - */ - -#if (__Vendor_SysTickConfig == 0) - -/** \brief System Tick Configuration - - This function initialises the system tick timer and its interrupt and start the system tick timer. - Counter is in free running mode to generate periodical interrupts. - - \param [in] ticks Number of ticks between two interrupts - \return 0 Function succeeded - \return 1 Function failed - */ -static __INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ - - SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ - SysTick->VAL = 0; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - -/* ##################################### Debug In/Output function ########################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_core_DebugFunctions CMSIS Core Debug Functions - @{ - */ - -extern volatile int32_t ITM_RxBuffer; /*!< external variable to receive characters */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */ - - -/** \brief ITM Send Character - - This function transmits a character via the ITM channel 0. - It just returns when no debugger is connected that has booked the output. - It is blocking when a debugger is connected, but the previous character send is not transmitted. - - \param [in] ch Character to transmit - \return Character to transmit - */ -static __INLINE uint32_t ITM_SendChar (uint32_t ch) -{ - if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled */ - (ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ - (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ - { - while (ITM->PORT[0].u32 == 0); - ITM->PORT[0].u8 = (uint8_t) ch; - } - return (ch); -} - - -/** \brief ITM Receive Character - - This function inputs a character via external variable ITM_RxBuffer. - It just returns when no debugger is connected that has booked the output. - It is blocking when a debugger is connected, but the previous character send is not transmitted. - - \return Received character - \return -1 No character received - */ -static __INLINE int32_t ITM_ReceiveChar (void) { - int32_t ch = -1; /* no character available */ - - if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { - ch = ITM_RxBuffer; - ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ - } - - return (ch); -} - - -/** \brief ITM Check Character - - This function checks external variable ITM_RxBuffer whether a character is available or not. - It returns '1' if a character is available and '0' if no character is available. - - \return 0 No character available - \return 1 Character available - */ -static __INLINE int32_t ITM_CheckChar (void) { - - if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { - return (0); /* no character available */ - } else { - return (1); /* character available */ - } -} - -/*@} end of CMSIS_core_DebugFunctions */ - -#endif /* __CORE_CM3_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ - -#ifdef __cplusplus -} -#endif diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm4.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm4.h deleted file mode 100644 index bf022ba67..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm4.h +++ /dev/null @@ -1,1378 +0,0 @@ -/**************************************************************************//** - * @file core_cm4.h - * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File - * @version V2.10 - * @date 19. July 2011 - * - * @note - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * @par - * ARM Limited (ARM) is supplying this software for use with Cortex-M - * processor based microcontrollers. This file can be freely distributed - * within development tools that are supporting such ARM based processors. - * - * @par - * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED - * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. - * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. - * - ******************************************************************************/ -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifdef __cplusplus - extern "C" { -#endif - -#ifndef __CORE_CM4_H_GENERIC -#define __CORE_CM4_H_GENERIC - - -/** \mainpage CMSIS Cortex-M4 - - This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer. - It consists of: - - - Cortex-M Core Register Definitions - - Cortex-M functions - - Cortex-M instructions - - Cortex-M SIMD instructions - - The CMSIS Cortex-M4 Core Peripheral Access Layer contains C and assembly functions that ease - access to the Cortex-M Core - */ - -/** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions - CMSIS violates following MISRA-C2004 Rules: - - - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'. - - - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \defgroup CMSIS_core_definitions CMSIS Core Definitions - This file defines all structures and symbols for CMSIS core: - - CMSIS version number - - Cortex-M core - - Cortex-M core Revision Number - @{ - */ - -/* CMSIS CM4 definitions */ -#define __CM4_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */ -#define __CM4_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */ -#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | __CM4_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x04) /*!< Cortex core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - -#endif - -/*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */ -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __TASKING__ ) - /* add preprocessor checks to define __FPU_USED */ - #define __FPU_USED 0 -#endif - -#include /*!< standard types definitions */ -#include /*!< Core Instruction Access */ -#include /*!< Core Function Access */ -#include /*!< Compiler specific SIMD Intrinsics */ - -#endif /* __CORE_CM4_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM4_H_DEPENDANT -#define __CORE_CM4_H_DEPENDANT - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM4_REV - #define __CM4_REV 0x0000 - #warning "__CM4_REV not defined in device header file; using default!" - #endif - - #ifndef __FPU_PRESENT - #define __FPU_PRESENT 0 - #warning "__FPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0 - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 4 - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0 - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -#ifdef __cplusplus - #define __I volatile /*!< defines 'read only' permissions */ -#else - #define __I volatile const /*!< defines 'read only' permissions */ -#endif -#define __O volatile /*!< defines 'write only' permissions */ -#define __IO volatile /*!< defines 'read / write' permissions */ - -/*@} end of group CMSIS_core_definitions */ - - - -/******************************************************************************* - * Register Abstraction - ******************************************************************************/ -/** \defgroup CMSIS_core_register CMSIS Core Register - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core Debug Register - - Core MPU Register - - Core FPU Register -*/ - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CORE CMSIS Core - Type definitions for the Cortex-M Core Registers - @{ - */ - -/** \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { -#if (__CORTEX_M != 0x04) - uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ -#else - uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ -#endif - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} APSR_Type; - - -/** \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - - -/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ -#if (__CORTEX_M != 0x04) - uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ -#else - uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ -#endif - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} xPSR_Type; - - -/** \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ - uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/*@} end of group CMSIS_CORE */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC CMSIS NVIC - Type definitions for the Cortex-M NVIC Registers - @{ - */ - -/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[24]; - __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[24]; - __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[24]; - __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[24]; - __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ - uint32_t RESERVED4[56]; - __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644]; - __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ -} NVIC_Type; - -/* Software Triggered Interrupt Register Definitions */ -#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ -#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ - -/*@} end of group CMSIS_NVIC */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCB CMSIS SCB - Type definitions for the Cortex-M System Control Block Registers - @{ - */ - -/** \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ - __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ - __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ - __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ - __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ - __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ - __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[5]; - __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ - -#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ -#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ -#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Vector Table Offset Register Definitions */ -#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ -#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ -#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ - -/* SCB Configuration Control Register Definitions */ -#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ -#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ - -#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ -#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ -#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ - -#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ -#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ -#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ - -#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ -#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ - -#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ -#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ - -#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ -#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ - -#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ -#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ - -#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ -#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ - -#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ -#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ - -#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ -#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ - -#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ -#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ - -#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ -#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ - -#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ -#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ - -#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ -#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ - -#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ -#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ - -/* SCB Configurable Fault Status Registers Definitions */ -#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ -#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ - -#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ -#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ - -#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ -#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ - -/* SCB Hard Fault Status Registers Definitions */ -#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ -#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ - -#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ -#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ - -#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ -#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ - -/* SCB Debug Fault Status Register Definitions */ -#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ -#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ - -#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ -#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ - -#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ -#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ - -#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ -#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ - -#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ -#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCnSCB CMSIS System Control and ID Register not in the SCB - Type definitions for the Cortex-M System Control and ID Register not in the SCB - @{ - */ - -/** \brief Structure type to access the System Control and ID Register not in the SCB. - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ - __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ -} SCnSCB_Type; - -/* Interrupt Controller Type Register Definitions */ -#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ -#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ - -/* Auxiliary Control Register Definitions */ -#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ -#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ - -#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ -#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ - -#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ -#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ - -#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ -#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ - -#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ -#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ - -/*@} end of group CMSIS_SCnotSCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick CMSIS SysTick - Type definitions for the Cortex-M System Timer Registers - @{ - */ - -/** \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_ITM CMSIS ITM - Type definitions for the Cortex-M Instrumentation Trace Macrocell (ITM) - @{ - */ - -/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). - */ -typedef struct -{ - __O union - { - __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ - __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ - __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ - } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ - uint32_t RESERVED0[864]; - __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ - uint32_t RESERVED1[15]; - __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ - uint32_t RESERVED2[15]; - __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ -} ITM_Type; - -/* ITM Trace Privilege Register Definitions */ -#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ - -/* ITM Trace Control Register Definitions */ -#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ -#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ - -#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ -#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ - -#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ -#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ - -#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ -#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ - -#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ -#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ - -#define ITM_TCR_TXENA_Pos 3 /*!< ITM TCR: TXENA Position */ -#define ITM_TCR_TXENA_Msk (1UL << ITM_TCR_TXENA_Pos) /*!< ITM TCR: TXENA Mask */ - -#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ -#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ - -#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ -#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ - -#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ -#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ - -/*@}*/ /* end of group CMSIS_ITM */ - - -#if (__MPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_MPU CMSIS MPU - Type definitions for the Cortex-M Memory Protection Unit (MPU) - @{ - */ - -/** \brief Structure type to access the Memory Protection Unit (MPU). - */ -typedef struct -{ - __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ - __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ - __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ - __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ - __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ - __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ - __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ -} MPU_Type; - -/* MPU Type Register */ -#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ - -#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ - -#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ - -/* MPU Control Register */ -#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ - -#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ - -#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ - -/* MPU Region Number Register */ -#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ - -/* MPU Region Base Address Register */ -#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ - -#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ - -#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ - -/* MPU Region Attribute and Size Register */ -#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ -#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ - -#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ -#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ - -#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ -#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ - -#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@} end of group CMSIS_MPU */ -#endif - - -#if (__FPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_FPU CMSIS FPU - Type definitions for the Cortex-M Floating Point Unit (FPU) - @{ - */ - -/** \brief Structure type to access the Floating Point Unit (FPU). - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ - __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ - __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ - __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ - __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ -} FPU_Type; - -/* Floating-Point Context Control Register */ -#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ -#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ - -#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ -#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ - -#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ -#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ - -#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ -#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ - -#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ -#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ - -#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ -#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ - -#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */ -#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ - -#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */ -#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ - -#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */ -#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */ - -/* Floating-Point Context Address Register */ -#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ -#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ - -/* Floating-Point Default Status Control Register */ -#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ -#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ - -#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ -#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ - -#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ -#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ - -#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ -#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ - -/* Media and FP Feature Register 0 */ -#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */ -#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ - -#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */ -#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ - -#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */ -#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ - -#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */ -#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ - -#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */ -#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ - -#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */ -#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ - -#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */ -#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ - -#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */ -#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */ - -/* Media and FP Feature Register 1 */ -#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */ -#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ - -#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */ -#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ - -#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */ -#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ - -#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */ -#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */ - -/*@} end of group CMSIS_FPU */ -#endif - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug CMSIS Core Debug - Type definitions for the Cortex-M Core Debug Registers - @{ - */ - -/** \brief Structure type to access the Core Debug Register (CoreDebug). - */ -typedef struct -{ - __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ - __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ - __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ - __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ -} CoreDebug_Type; - -/* Debug Halting Control and Status Register */ -#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ -#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ - -#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ -#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ - -#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ -#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ - -#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ -#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ - -#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ -#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ - -#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ -#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ - -#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ -#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ - -#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ -#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ - -#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ -#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ - -#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ -#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ - -#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ -#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ - -#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ -#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ - -/* Debug Core Register Selector Register */ -#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ -#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ - -#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ -#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ - -/* Debug Exception and Monitor Control Register */ -#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ -#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ - -#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ -#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ - -#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ -#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ - -#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ -#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ - -#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ -#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ - -#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ -#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ - -#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ -#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ - -#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ -#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ - -#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ -#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ - -#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ -#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ - -#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ -#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ - -#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ -#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ - -#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ -#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ - -/*@} end of group CMSIS_CoreDebug */ - - -/** \ingroup CMSIS_core_register - @{ - */ - -/* Memory mapping of Cortex-M4 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ -#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ -#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ - -#if (__MPU_PRESENT == 1) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif - -#if (__FPU_PRESENT == 1) - #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ - #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ -#endif - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - ******************************************************************************/ -/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Debug Functions - - Core Register Access Functions -*/ - - - -/* ########################## NVIC functions #################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions - @{ - */ - -/** \brief Set Priority Grouping - - This function sets the priority grouping field using the required unlock sequence. - The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. - Only values from 0..7 are used. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. - - \param [in] PriorityGroup Priority grouping field - */ -static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) -{ - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ - - reg_value = SCB->AIRCR; /* read old register configuration */ - reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ - reg_value = (reg_value | - ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ - SCB->AIRCR = reg_value; -} - - -/** \brief Get Priority Grouping - - This function gets the priority grouping from NVIC Interrupt Controller. - Priority grouping is SCB->AIRCR [10:8] PRIGROUP field. - - \return Priority grouping field - */ -static __INLINE uint32_t NVIC_GetPriorityGrouping(void) -{ - return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ -} - - -/** \brief Enable External Interrupt - - This function enables a device specific interrupt in the NVIC interrupt controller. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the external interrupt to enable - */ -static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ -/* NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */ - NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ -} - - -/** \brief Disable External Interrupt - - This function disables a device specific interrupt in the NVIC interrupt controller. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the external interrupt to disable - */ -static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ -} - - -/** \brief Get Pending Interrupt - - This function reads the pending register in the NVIC and returns the pending bit - for the specified interrupt. - - \param [in] IRQn Number of the interrupt for get pending - \return 0 Interrupt status is not pending - \return 1 Interrupt status is pending - */ -static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ -} - - -/** \brief Set Pending Interrupt - - This function sets the pending bit for the specified interrupt. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the interrupt for set pending - */ -static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ -} - - -/** \brief Clear Pending Interrupt - - This function clears the pending bit for the specified interrupt. - The interrupt number cannot be a negative value. - - \param [in] IRQn Number of the interrupt for clear pending - */ -static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ -} - - -/** \brief Get Active Interrupt - - This function reads the active register in NVIC and returns the active bit. - \param [in] IRQn Number of the interrupt for get active - \return 0 Interrupt status is not active - \return 1 Interrupt status is active - */ -static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ -} - - -/** \brief Set Interrupt Priority - - This function sets the priority for the specified interrupt. The interrupt - number can be positive to specify an external (device specific) - interrupt, or negative to specify an internal (core) interrupt. - - Note: The priority cannot be set for every core interrupt. - - \param [in] IRQn Number of the interrupt for set priority - \param [in] priority Priority to set - */ -static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if(IRQn < 0) { - SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ - else { - NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ -} - - -/** \brief Get Interrupt Priority - - This function reads the priority for the specified interrupt. The interrupt - number can be positive to specify an external (device specific) - interrupt, or negative to specify an internal (core) interrupt. - - The returned priority value is automatically aligned to the implemented - priority bits of the microcontroller. - - \param [in] IRQn Number of the interrupt for get priority - \return Interrupt Priority - */ -static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) -{ - - if(IRQn < 0) { - return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ - else { - return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ -} - - -/** \brief Encode Priority - - This function encodes the priority for an interrupt with the given priority group, - preemptive priority value and sub priority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. - - The returned priority value can be used for NVIC_SetPriority(...) function - - \param [in] PriorityGroup Used priority group - \param [in] PreemptPriority Preemptive priority value (starting from 0) - \param [in] SubPriority Sub priority value (starting from 0) - \return Encoded priority for the interrupt - */ -static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; - SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; - - return ( - ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | - ((SubPriority & ((1 << (SubPriorityBits )) - 1))) - ); -} - - -/** \brief Decode Priority - - This function decodes an interrupt priority value with the given priority group to - preemptive priority value and sub priority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. - - The priority value can be retrieved with NVIC_GetPriority(...) function - - \param [in] Priority Priority value - \param [in] PriorityGroup Used priority group - \param [out] pPreemptPriority Preemptive priority value (starting from 0) - \param [out] pSubPriority Sub priority value (starting from 0) - */ -static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; - SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; - - *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); - *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); -} - - -/** \brief System Reset - - This function initiate a system reset request to reset the MCU. - */ -static __INLINE void NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | - (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | - SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ - __DSB(); /* Ensure completion of memory access */ - while(1); /* wait until reset */ -} - -/*@} end of CMSIS_Core_NVICFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions CMSIS Core SysTick Functions - @{ - */ - -#if (__Vendor_SysTickConfig == 0) - -/** \brief System Tick Configuration - - This function initialises the system tick timer and its interrupt and start the system tick timer. - Counter is in free running mode to generate periodical interrupts. - - \param [in] ticks Number of ticks between two interrupts - \return 0 Function succeeded - \return 1 Function failed - */ -static __INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ - - SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ - SysTick->VAL = 0; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - -/* ##################################### Debug In/Output function ########################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_core_DebugFunctions CMSIS Core Debug Functions - @{ - */ - -extern volatile int32_t ITM_RxBuffer; /*!< external variable to receive characters */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */ - - -/** \brief ITM Send Character - - This function transmits a character via the ITM channel 0. - It just returns when no debugger is connected that has booked the output. - It is blocking when a debugger is connected, but the previous character send is not transmitted. - - \param [in] ch Character to transmit - \return Character to transmit - */ -static __INLINE uint32_t ITM_SendChar (uint32_t ch) -{ - if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled */ - (ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ - (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ - { - while (ITM->PORT[0].u32 == 0); - ITM->PORT[0].u8 = (uint8_t) ch; - } - return (ch); -} - - -/** \brief ITM Receive Character - - This function inputs a character via external variable ITM_RxBuffer. - It just returns when no debugger is connected that has booked the output. - It is blocking when a debugger is connected, but the previous character send is not transmitted. - - \return Received character - \return -1 No character received - */ -static __INLINE int32_t ITM_ReceiveChar (void) { - int32_t ch = -1; /* no character available */ - - if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { - ch = ITM_RxBuffer; - ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ - } - - return (ch); -} - - -/** \brief ITM Check Character - - This function checks external variable ITM_RxBuffer whether a character is available or not. - It returns '1' if a character is available and '0' if no character is available. - - \return 0 No character available - \return 1 Character available - */ -static __INLINE int32_t ITM_CheckChar (void) { - - if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { - return (0); /* no character available */ - } else { - return (1); /* character available */ - } -} - -/*@} end of CMSIS_core_DebugFunctions */ - -#endif /* __CORE_CM4_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ - -#ifdef __cplusplus -} -#endif diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm4_simd.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm4_simd.h deleted file mode 100644 index e7b676522..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cm4_simd.h +++ /dev/null @@ -1,701 +0,0 @@ -/**************************************************************************//** - * @file core_cm4_simd.h - * @brief CMSIS Cortex-M4 SIMD Header File - * @version V2.10 - * @date 19. July 2011 - * - * @note - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * @par - * ARM Limited (ARM) is supplying this software for use with Cortex-M - * processor based microcontrollers. This file can be freely distributed - * within development tools that are supporting such ARM based processors. - * - * @par - * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED - * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. - * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. - * - ******************************************************************************/ - -#ifdef __cplusplus - extern "C" { -#endif - -#ifndef __CORE_CM4_SIMD_H -#define __CORE_CM4_SIMD_H - - -/******************************************************************************* - * Hardware Abstraction Layer - ******************************************************************************/ - - -/* ################### Compiler specific Intrinsics ########################### */ -/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics - Access to dedicated SIMD instructions - @{ -*/ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -/*------ CM4 SOMD Intrinsics -----------------------------------------------------*/ -#define __SADD8 __sadd8 -#define __QADD8 __qadd8 -#define __SHADD8 __shadd8 -#define __UADD8 __uadd8 -#define __UQADD8 __uqadd8 -#define __UHADD8 __uhadd8 -#define __SSUB8 __ssub8 -#define __QSUB8 __qsub8 -#define __SHSUB8 __shsub8 -#define __USUB8 __usub8 -#define __UQSUB8 __uqsub8 -#define __UHSUB8 __uhsub8 -#define __SADD16 __sadd16 -#define __QADD16 __qadd16 -#define __SHADD16 __shadd16 -#define __UADD16 __uadd16 -#define __UQADD16 __uqadd16 -#define __UHADD16 __uhadd16 -#define __SSUB16 __ssub16 -#define __QSUB16 __qsub16 -#define __SHSUB16 __shsub16 -#define __USUB16 __usub16 -#define __UQSUB16 __uqsub16 -#define __UHSUB16 __uhsub16 -#define __SASX __sasx -#define __QASX __qasx -#define __SHASX __shasx -#define __UASX __uasx -#define __UQASX __uqasx -#define __UHASX __uhasx -#define __SSAX __ssax -#define __QSAX __qsax -#define __SHSAX __shsax -#define __USAX __usax -#define __UQSAX __uqsax -#define __UHSAX __uhsax -#define __USAD8 __usad8 -#define __USADA8 __usada8 -#define __SSAT16 __ssat16 -#define __USAT16 __usat16 -#define __UXTB16 __uxtb16 -#define __UXTAB16 __uxtab16 -#define __SXTB16 __sxtb16 -#define __SXTAB16 __sxtab16 -#define __SMUAD __smuad -#define __SMUADX __smuadx -#define __SMLAD __smlad -#define __SMLADX __smladx -#define __SMLALD __smlald -#define __SMLALDX __smlaldx -#define __SMUSD __smusd -#define __SMUSDX __smusdx -#define __SMLSD __smlsd -#define __SMLSDX __smlsdx -#define __SMLSLD __smlsld -#define __SMLSLDX __smlsldx -#define __SEL __sel -#define __QADD __qadd -#define __QSUB __qsub - -#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ - ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) - -#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ - ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) - - -/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ - - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ - -#include - -/*------ CM4 SIMDDSP Intrinsics -----------------------------------------------------*/ -/* intrinsic __SADD8 see intrinsics.h */ -/* intrinsic __QADD8 see intrinsics.h */ -/* intrinsic __SHADD8 see intrinsics.h */ -/* intrinsic __UADD8 see intrinsics.h */ -/* intrinsic __UQADD8 see intrinsics.h */ -/* intrinsic __UHADD8 see intrinsics.h */ -/* intrinsic __SSUB8 see intrinsics.h */ -/* intrinsic __QSUB8 see intrinsics.h */ -/* intrinsic __SHSUB8 see intrinsics.h */ -/* intrinsic __USUB8 see intrinsics.h */ -/* intrinsic __UQSUB8 see intrinsics.h */ -/* intrinsic __UHSUB8 see intrinsics.h */ -/* intrinsic __SADD16 see intrinsics.h */ -/* intrinsic __QADD16 see intrinsics.h */ -/* intrinsic __SHADD16 see intrinsics.h */ -/* intrinsic __UADD16 see intrinsics.h */ -/* intrinsic __UQADD16 see intrinsics.h */ -/* intrinsic __UHADD16 see intrinsics.h */ -/* intrinsic __SSUB16 see intrinsics.h */ -/* intrinsic __QSUB16 see intrinsics.h */ -/* intrinsic __SHSUB16 see intrinsics.h */ -/* intrinsic __USUB16 see intrinsics.h */ -/* intrinsic __UQSUB16 see intrinsics.h */ -/* intrinsic __UHSUB16 see intrinsics.h */ -/* intrinsic __SASX see intrinsics.h */ -/* intrinsic __QASX see intrinsics.h */ -/* intrinsic __SHASX see intrinsics.h */ -/* intrinsic __UASX see intrinsics.h */ -/* intrinsic __UQASX see intrinsics.h */ -/* intrinsic __UHASX see intrinsics.h */ -/* intrinsic __SSAX see intrinsics.h */ -/* intrinsic __QSAX see intrinsics.h */ -/* intrinsic __SHSAX see intrinsics.h */ -/* intrinsic __USAX see intrinsics.h */ -/* intrinsic __UQSAX see intrinsics.h */ -/* intrinsic __UHSAX see intrinsics.h */ -/* intrinsic __USAD8 see intrinsics.h */ -/* intrinsic __USADA8 see intrinsics.h */ -/* intrinsic __SSAT16 see intrinsics.h */ -/* intrinsic __USAT16 see intrinsics.h */ -/* intrinsic __UXTB16 see intrinsics.h */ -/* intrinsic __SXTB16 see intrinsics.h */ -/* intrinsic __UXTAB16 see intrinsics.h */ -/* intrinsic __SXTAB16 see intrinsics.h */ -/* intrinsic __SMUAD see intrinsics.h */ -/* intrinsic __SMUADX see intrinsics.h */ -/* intrinsic __SMLAD see intrinsics.h */ -/* intrinsic __SMLADX see intrinsics.h */ -/* intrinsic __SMLALD see intrinsics.h */ -/* intrinsic __SMLALDX see intrinsics.h */ -/* intrinsic __SMUSD see intrinsics.h */ -/* intrinsic __SMUSDX see intrinsics.h */ -/* intrinsic __SMLSD see intrinsics.h */ -/* intrinsic __SMLSDX see intrinsics.h */ -/* intrinsic __SMLSLD see intrinsics.h */ -/* intrinsic __SMLSLDX see intrinsics.h */ -/* intrinsic __SEL see intrinsics.h */ -/* intrinsic __QADD see intrinsics.h */ -/* intrinsic __QSUB see intrinsics.h */ -/* intrinsic __PKHBT see intrinsics.h */ -/* intrinsic __PKHTB see intrinsics.h */ - -/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ - - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -#define __SSAT16(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - -#define __USAT16(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UXTB16(uint32_t op1) -{ - uint32_t result; - - __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SXTB16(uint32_t op1) -{ - uint32_t result; - - __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -#define __SMLALD(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ - __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ - (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ - }) - -#define __SMLALDX(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ - __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ - (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ - }) - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -#define __SMLSLD(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ - __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ - (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ - }) - -#define __SMLSLDX(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ - __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ - (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ - }) - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) static __INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -#define __PKHBT(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ - __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ - __RES; \ - }) - -#define __PKHTB(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ - if (ARG3 == 0) \ - __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ - else \ - __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ - __RES; \ - }) - -/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ - - - -#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ -/* TASKING carm specific functions */ - - -/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ -/* not yet supported */ -/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ - - -#endif - -/*@} end of group CMSIS_SIMD_intrinsics */ - - -#endif /* __CORE_CM4_SIMD_H */ - -#ifdef __cplusplus -} -#endif diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cmFunc.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cmFunc.h deleted file mode 100644 index 88819f9dd..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cmFunc.h +++ /dev/null @@ -1,609 +0,0 @@ -/**************************************************************************//** - * @file core_cmFunc.h - * @brief CMSIS Cortex-M Core Function Access Header File - * @version V2.10 - * @date 26. July 2011 - * - * @note - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * @par - * ARM Limited (ARM) is supplying this software for use with Cortex-M - * processor based microcontrollers. This file can be freely distributed - * within development tools that are supporting such ARM based processors. - * - * @par - * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED - * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. - * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. - * - ******************************************************************************/ - -#ifndef __CORE_CMFUNC_H -#define __CORE_CMFUNC_H - - -/* ########################### Core Function Access ########################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions - @{ - */ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -#if (__ARMCC_VERSION < 400677) - #error "Please use ARM Compiler Toolchain V4.0.677 or later!" -#endif - -/* intrinsic void __enable_irq(); */ -/* intrinsic void __disable_irq(); */ - -/** \brief Get Control Register - - This function returns the content of the Control Register. - - \return Control Register value - */ -static __INLINE uint32_t __get_CONTROL(void) -{ - register uint32_t __regControl __ASM("control"); - return(__regControl); -} - - -/** \brief Set Control Register - - This function writes the given value to the Control Register. - - \param [in] control Control Register value to set - */ -static __INLINE void __set_CONTROL(uint32_t control) -{ - register uint32_t __regControl __ASM("control"); - __regControl = control; -} - - -/** \brief Get ISPR Register - - This function returns the content of the ISPR Register. - - \return ISPR Register value - */ -static __INLINE uint32_t __get_IPSR(void) -{ - register uint32_t __regIPSR __ASM("ipsr"); - return(__regIPSR); -} - - -/** \brief Get APSR Register - - This function returns the content of the APSR Register. - - \return APSR Register value - */ -static __INLINE uint32_t __get_APSR(void) -{ - register uint32_t __regAPSR __ASM("apsr"); - return(__regAPSR); -} - - -/** \brief Get xPSR Register - - This function returns the content of the xPSR Register. - - \return xPSR Register value - */ -static __INLINE uint32_t __get_xPSR(void) -{ - register uint32_t __regXPSR __ASM("xpsr"); - return(__regXPSR); -} - - -/** \brief Get Process Stack Pointer - - This function returns the current value of the Process Stack Pointer (PSP). - - \return PSP Register value - */ -static __INLINE uint32_t __get_PSP(void) -{ - register uint32_t __regProcessStackPointer __ASM("psp"); - return(__regProcessStackPointer); -} - - -/** \brief Set Process Stack Pointer - - This function assigns the given value to the Process Stack Pointer (PSP). - - \param [in] topOfProcStack Process Stack Pointer value to set - */ -static __INLINE void __set_PSP(uint32_t topOfProcStack) -{ - register uint32_t __regProcessStackPointer __ASM("psp"); - __regProcessStackPointer = topOfProcStack; -} - - -/** \brief Get Main Stack Pointer - - This function returns the current value of the Main Stack Pointer (MSP). - - \return MSP Register value - */ -static __INLINE uint32_t __get_MSP(void) -{ - register uint32_t __regMainStackPointer __ASM("msp"); - return(__regMainStackPointer); -} - - -/** \brief Set Main Stack Pointer - - This function assigns the given value to the Main Stack Pointer (MSP). - - \param [in] topOfMainStack Main Stack Pointer value to set - */ -static __INLINE void __set_MSP(uint32_t topOfMainStack) -{ - register uint32_t __regMainStackPointer __ASM("msp"); - __regMainStackPointer = topOfMainStack; -} - - -/** \brief Get Priority Mask - - This function returns the current state of the priority mask bit from the Priority Mask Register. - - \return Priority Mask value - */ -static __INLINE uint32_t __get_PRIMASK(void) -{ - register uint32_t __regPriMask __ASM("primask"); - return(__regPriMask); -} - - -/** \brief Set Priority Mask - - This function assigns the given value to the Priority Mask Register. - - \param [in] priMask Priority Mask - */ -static __INLINE void __set_PRIMASK(uint32_t priMask) -{ - register uint32_t __regPriMask __ASM("primask"); - __regPriMask = (priMask); -} - - -#if (__CORTEX_M >= 0x03) - -/** \brief Enable FIQ - - This function enables FIQ interrupts by clearing the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -#define __enable_fault_irq __enable_fiq - - -/** \brief Disable FIQ - - This function disables FIQ interrupts by setting the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -#define __disable_fault_irq __disable_fiq - - -/** \brief Get Base Priority - - This function returns the current value of the Base Priority register. - - \return Base Priority register value - */ -static __INLINE uint32_t __get_BASEPRI(void) -{ - register uint32_t __regBasePri __ASM("basepri"); - return(__regBasePri); -} - - -/** \brief Set Base Priority - - This function assigns the given value to the Base Priority register. - - \param [in] basePri Base Priority value to set - */ -static __INLINE void __set_BASEPRI(uint32_t basePri) -{ - register uint32_t __regBasePri __ASM("basepri"); - __regBasePri = (basePri & 0xff); -} - - -/** \brief Get Fault Mask - - This function returns the current value of the Fault Mask register. - - \return Fault Mask register value - */ -static __INLINE uint32_t __get_FAULTMASK(void) -{ - register uint32_t __regFaultMask __ASM("faultmask"); - return(__regFaultMask); -} - - -/** \brief Set Fault Mask - - This function assigns the given value to the Fault Mask register. - - \param [in] faultMask Fault Mask value to set - */ -static __INLINE void __set_FAULTMASK(uint32_t faultMask) -{ - register uint32_t __regFaultMask __ASM("faultmask"); - __regFaultMask = (faultMask & (uint32_t)1); -} - -#endif /* (__CORTEX_M >= 0x03) */ - - -#if (__CORTEX_M == 0x04) - -/** \brief Get FPSCR - - This function returns the current value of the Floating Point Status/Control register. - - \return Floating Point Status/Control register value - */ -static __INLINE uint32_t __get_FPSCR(void) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - register uint32_t __regfpscr __ASM("fpscr"); - return(__regfpscr); -#else - return(0); -#endif -} - - -/** \brief Set FPSCR - - This function assigns the given value to the Floating Point Status/Control register. - - \param [in] fpscr Floating Point Status/Control value to set - */ -static __INLINE void __set_FPSCR(uint32_t fpscr) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - register uint32_t __regfpscr __ASM("fpscr"); - __regfpscr = (fpscr); -#endif -} - -#endif /* (__CORTEX_M == 0x04) */ - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ - -#include - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/** \brief Enable IRQ Interrupts - - This function enables IRQ interrupts by clearing the I-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) static __INLINE void __enable_irq(void) -{ - __ASM volatile ("cpsie i"); -} - - -/** \brief Disable IRQ Interrupts - - This function disables IRQ interrupts by setting the I-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) static __INLINE void __disable_irq(void) -{ - __ASM volatile ("cpsid i"); -} - - -/** \brief Get Control Register - - This function returns the content of the Control Register. - - \return Control Register value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_CONTROL(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, control" : "=r" (result) ); - return(result); -} - - -/** \brief Set Control Register - - This function writes the given value to the Control Register. - - \param [in] control Control Register value to set - */ -__attribute__( ( always_inline ) ) static __INLINE void __set_CONTROL(uint32_t control) -{ - __ASM volatile ("MSR control, %0" : : "r" (control) ); -} - - -/** \brief Get ISPR Register - - This function returns the content of the ISPR Register. - - \return ISPR Register value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_IPSR(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); - return(result); -} - - -/** \brief Get APSR Register - - This function returns the content of the APSR Register. - - \return APSR Register value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_APSR(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, apsr" : "=r" (result) ); - return(result); -} - - -/** \brief Get xPSR Register - - This function returns the content of the xPSR Register. - - \return xPSR Register value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_xPSR(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); - return(result); -} - - -/** \brief Get Process Stack Pointer - - This function returns the current value of the Process Stack Pointer (PSP). - - \return PSP Register value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PSP(void) -{ - register uint32_t result; - - __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); - return(result); -} - - -/** \brief Set Process Stack Pointer - - This function assigns the given value to the Process Stack Pointer (PSP). - - \param [in] topOfProcStack Process Stack Pointer value to set - */ -__attribute__( ( always_inline ) ) static __INLINE void __set_PSP(uint32_t topOfProcStack) -{ - __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) ); -} - - -/** \brief Get Main Stack Pointer - - This function returns the current value of the Main Stack Pointer (MSP). - - \return MSP Register value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_MSP(void) -{ - register uint32_t result; - - __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); - return(result); -} - - -/** \brief Set Main Stack Pointer - - This function assigns the given value to the Main Stack Pointer (MSP). - - \param [in] topOfMainStack Main Stack Pointer value to set - */ -__attribute__( ( always_inline ) ) static __INLINE void __set_MSP(uint32_t topOfMainStack) -{ - __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) ); -} - - -/** \brief Get Priority Mask - - This function returns the current state of the priority mask bit from the Priority Mask Register. - - \return Priority Mask value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PRIMASK(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, primask" : "=r" (result) ); - return(result); -} - - -/** \brief Set Priority Mask - - This function assigns the given value to the Priority Mask Register. - - \param [in] priMask Priority Mask - */ -__attribute__( ( always_inline ) ) static __INLINE void __set_PRIMASK(uint32_t priMask) -{ - __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); -} - - -#if (__CORTEX_M >= 0x03) - -/** \brief Enable FIQ - - This function enables FIQ interrupts by clearing the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) static __INLINE void __enable_fault_irq(void) -{ - __ASM volatile ("cpsie f"); -} - - -/** \brief Disable FIQ - - This function disables FIQ interrupts by setting the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) static __INLINE void __disable_fault_irq(void) -{ - __ASM volatile ("cpsid f"); -} - - -/** \brief Get Base Priority - - This function returns the current value of the Base Priority register. - - \return Base Priority register value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_BASEPRI(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); - return(result); -} - - -/** \brief Set Base Priority - - This function assigns the given value to the Base Priority register. - - \param [in] basePri Base Priority value to set - */ -__attribute__( ( always_inline ) ) static __INLINE void __set_BASEPRI(uint32_t value) -{ - __ASM volatile ("MSR basepri, %0" : : "r" (value) ); -} - - -/** \brief Get Fault Mask - - This function returns the current value of the Fault Mask register. - - \return Fault Mask register value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FAULTMASK(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); - return(result); -} - - -/** \brief Set Fault Mask - - This function assigns the given value to the Fault Mask register. - - \param [in] faultMask Fault Mask value to set - */ -__attribute__( ( always_inline ) ) static __INLINE void __set_FAULTMASK(uint32_t faultMask) -{ - __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) ); -} - -#endif /* (__CORTEX_M >= 0x03) */ - - -#if (__CORTEX_M == 0x04) - -/** \brief Get FPSCR - - This function returns the current value of the Floating Point Status/Control register. - - \return Floating Point Status/Control register value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FPSCR(void) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - uint32_t result; - - __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); - return(result); -#else - return(0); -#endif -} - - -/** \brief Set FPSCR - - This function assigns the given value to the Floating Point Status/Control register. - - \param [in] fpscr Floating Point Status/Control value to set - */ -__attribute__( ( always_inline ) ) static __INLINE void __set_FPSCR(uint32_t fpscr) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) ); -#endif -} - -#endif /* (__CORTEX_M == 0x04) */ - - -#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ -/* TASKING carm specific functions */ - -/* - * The CMSIS functions have been implemented as intrinsics in the compiler. - * Please use "carm -?i" to get an up to date list of all instrinsics, - * Including the CMSIS ones. - */ - -#endif - -/*@} end of CMSIS_Core_RegAccFunctions */ - - -#endif /* __CORE_CMFUNC_H */ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cmInstr.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cmInstr.h deleted file mode 100644 index 78d2ef80b..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/core_support/core_cmInstr.h +++ /dev/null @@ -1,585 +0,0 @@ -/**************************************************************************//** - * @file core_cmInstr.h - * @brief CMSIS Cortex-M Core Instruction Access Header File - * @version V2.10 - * @date 19. July 2011 - * - * @note - * Copyright (C) 2009-2011 ARM Limited. All rights reserved. - * - * @par - * ARM Limited (ARM) is supplying this software for use with Cortex-M - * processor based microcontrollers. This file can be freely distributed - * within development tools that are supporting such ARM based processors. - * - * @par - * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED - * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. - * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. - * - ******************************************************************************/ - -#ifndef __CORE_CMINSTR_H -#define __CORE_CMINSTR_H - - -/* ########################## Core Instruction Access ######################### */ -/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface - Access to dedicated instructions - @{ -*/ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -#if (__ARMCC_VERSION < 400677) - #error "Please use ARM Compiler Toolchain V4.0.677 or later!" -#endif - - -/** \brief No Operation - - No Operation does nothing. This instruction can be used for code alignment purposes. - */ -#define __NOP __nop - - -/** \brief Wait For Interrupt - - Wait For Interrupt is a hint instruction that suspends execution - until one of a number of events occurs. - */ -#define __WFI __wfi - - -/** \brief Wait For Event - - Wait For Event is a hint instruction that permits the processor to enter - a low-power state until one of a number of events occurs. - */ -#define __WFE __wfe - - -/** \brief Send Event - - Send Event is a hint instruction. It causes an event to be signaled to the CPU. - */ -#define __SEV __sev - - -/** \brief Instruction Synchronization Barrier - - Instruction Synchronization Barrier flushes the pipeline in the processor, - so that all instructions following the ISB are fetched from cache or - memory, after the instruction has been completed. - */ -#define __ISB() __isb(0xF) - - -/** \brief Data Synchronization Barrier - - This function acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. - */ -#define __DSB() __dsb(0xF) - - -/** \brief Data Memory Barrier - - This function ensures the apparent order of the explicit memory operations before - and after the instruction, without ensuring their completion. - */ -#define __DMB() __dmb(0xF) - - -/** \brief Reverse byte order (32 bit) - - This function reverses the byte order in integer value. - - \param [in] value Value to reverse - \return Reversed value - */ -#define __REV __rev - - -/** \brief Reverse byte order (16 bit) - - This function reverses the byte order in two unsigned short values. - - \param [in] value Value to reverse - \return Reversed value - */ -static __INLINE __ASM uint32_t __REV16(uint32_t value) -{ - rev16 r0, r0 - bx lr -} - - -/** \brief Reverse byte order in signed short value - - This function reverses the byte order in a signed short value with sign extension to integer. - - \param [in] value Value to reverse - \return Reversed value - */ -static __INLINE __ASM int32_t __REVSH(int32_t value) -{ - revsh r0, r0 - bx lr -} - - -#if (__CORTEX_M >= 0x03) - -/** \brief Reverse bit order of value - - This function reverses the bit order of the given value. - - \param [in] value Value to reverse - \return Reversed value - */ -#define __RBIT __rbit - - -/** \brief LDR Exclusive (8 bit) - - This function performs a exclusive LDR command for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) - - -/** \brief LDR Exclusive (16 bit) - - This function performs a exclusive LDR command for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) - - -/** \brief LDR Exclusive (32 bit) - - This function performs a exclusive LDR command for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) - - -/** \brief STR Exclusive (8 bit) - - This function performs a exclusive STR command for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#define __STREXB(value, ptr) __strex(value, ptr) - - -/** \brief STR Exclusive (16 bit) - - This function performs a exclusive STR command for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#define __STREXH(value, ptr) __strex(value, ptr) - - -/** \brief STR Exclusive (32 bit) - - This function performs a exclusive STR command for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#define __STREXW(value, ptr) __strex(value, ptr) - - -/** \brief Remove the exclusive lock - - This function removes the exclusive lock which is created by LDREX. - - */ -#define __CLREX __clrex - - -/** \brief Signed Saturate - - This function saturates a signed value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (1..32) - \return Saturated value - */ -#define __SSAT __ssat - - -/** \brief Unsigned Saturate - - This function saturates an unsigned value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (0..31) - \return Saturated value - */ -#define __USAT __usat - - -/** \brief Count leading zeros - - This function counts the number of leading zeros of a data value. - - \param [in] value Value to count the leading zeros - \return number of leading zeros in value - */ -#define __CLZ __clz - -#endif /* (__CORTEX_M >= 0x03) */ - - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ - -#include - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/** \brief No Operation - - No Operation does nothing. This instruction can be used for code alignment purposes. - */ -__attribute__( ( always_inline ) ) static __INLINE void __NOP(void) -{ - __ASM volatile ("nop"); -} - - -/** \brief Wait For Interrupt - - Wait For Interrupt is a hint instruction that suspends execution - until one of a number of events occurs. - */ -__attribute__( ( always_inline ) ) static __INLINE void __WFI(void) -{ - __ASM volatile ("wfi"); -} - - -/** \brief Wait For Event - - Wait For Event is a hint instruction that permits the processor to enter - a low-power state until one of a number of events occurs. - */ -__attribute__( ( always_inline ) ) static __INLINE void __WFE(void) -{ - __ASM volatile ("wfe"); -} - - -/** \brief Send Event - - Send Event is a hint instruction. It causes an event to be signaled to the CPU. - */ -__attribute__( ( always_inline ) ) static __INLINE void __SEV(void) -{ - __ASM volatile ("sev"); -} - - -/** \brief Instruction Synchronization Barrier - - Instruction Synchronization Barrier flushes the pipeline in the processor, - so that all instructions following the ISB are fetched from cache or - memory, after the instruction has been completed. - */ -__attribute__( ( always_inline ) ) static __INLINE void __ISB(void) -{ - __ASM volatile ("isb"); -} - - -/** \brief Data Synchronization Barrier - - This function acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. - */ -__attribute__( ( always_inline ) ) static __INLINE void __DSB(void) -{ - __ASM volatile ("dsb"); -} - - -/** \brief Data Memory Barrier - - This function ensures the apparent order of the explicit memory operations before - and after the instruction, without ensuring their completion. - */ -__attribute__( ( always_inline ) ) static __INLINE void __DMB(void) -{ - __ASM volatile ("dmb"); -} - - -/** \brief Reverse byte order (32 bit) - - This function reverses the byte order in integer value. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - - -/** \brief Reverse byte order (16 bit) - - This function reverses the byte order in two unsigned short values. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV16(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - - -/** \brief Reverse byte order in signed short value - - This function reverses the byte order in a signed short value with sign extension to integer. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) static __INLINE int32_t __REVSH(int32_t value) -{ - uint32_t result; - - __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - - -#if (__CORTEX_M >= 0x03) - -/** \brief Reverse bit order of value - - This function reverses the bit order of the given value. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __RBIT(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - - -/** \brief LDR Exclusive (8 bit) - - This function performs a exclusive LDR command for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -__attribute__( ( always_inline ) ) static __INLINE uint8_t __LDREXB(volatile uint8_t *addr) -{ - uint8_t result; - - __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - - -/** \brief LDR Exclusive (16 bit) - - This function performs a exclusive LDR command for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -__attribute__( ( always_inline ) ) static __INLINE uint16_t __LDREXH(volatile uint16_t *addr) -{ - uint16_t result; - - __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - - -/** \brief LDR Exclusive (32 bit) - - This function performs a exclusive LDR command for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __LDREXW(volatile uint32_t *addr) -{ - uint32_t result; - - __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - - -/** \brief STR Exclusive (8 bit) - - This function performs a exclusive STR command for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) -{ - uint32_t result; - - __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); - return(result); -} - - -/** \brief STR Exclusive (16 bit) - - This function performs a exclusive STR command for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) -{ - uint32_t result; - - __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); - return(result); -} - - -/** \brief STR Exclusive (32 bit) - - This function performs a exclusive STR command for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) -{ - uint32_t result; - - __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); - return(result); -} - - -/** \brief Remove the exclusive lock - - This function removes the exclusive lock which is created by LDREX. - - */ -__attribute__( ( always_inline ) ) static __INLINE void __CLREX(void) -{ - __ASM volatile ("clrex"); -} - - -/** \brief Signed Saturate - - This function saturates a signed value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (1..32) - \return Saturated value - */ -#define __SSAT(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - - -/** \brief Unsigned Saturate - - This function saturates an unsigned value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (0..31) - \return Saturated value - */ -#define __USAT(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - - -/** \brief Count leading zeros - - This function counts the number of leading zeros of a data value. - - \param [in] value Value to count the leading zeros - \return number of leading zeros in value - */ -__attribute__( ( always_inline ) ) static __INLINE uint8_t __CLZ(uint32_t value) -{ - uint8_t result; - - __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - -#endif /* (__CORTEX_M >= 0x03) */ - - - - -#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ -/* TASKING carm specific functions */ - -/* - * The CMSIS functions have been implemented as intrinsics in the compiler. - * Please use "carm -?i" to get an up to date list of all intrinsics, - * Including the CMSIS ones. - */ - -#endif - -/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ - -#endif /* __CORE_CMINSTR_H */ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/device_support/stm32f4_discovery.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/device_support/stm32f4_discovery.h deleted file mode 100644 index c6fec4221..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/device_support/stm32f4_discovery.h +++ /dev/null @@ -1,158 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4_discovery.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file contains definitions for STM32F4-Discovery Kit's Leds and - * push-button hardware resources. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4_DISCOVERY_H -#define __STM32F4_DISCOVERY_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ - #include "stm32f4xx.h" - -/** @addtogroup Utilities - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY_LOW_LEVEL - * @{ - */ - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Exported_Types - * @{ - */ -typedef enum -{ - LED4 = 0, - LED3 = 1, - LED5 = 2, - LED6 = 3 -} Led_TypeDef; - -typedef enum -{ - BUTTON_USER = 0, -} Button_TypeDef; - -typedef enum -{ - BUTTON_MODE_GPIO = 0, - BUTTON_MODE_EXTI = 1 -} ButtonMode_TypeDef; -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Exported_Constants - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY_LOW_LEVEL_LED - * @{ - */ -#define LEDn 4 - -#define LED4_PIN GPIO_Pin_12 -#define LED4_GPIO_PORT GPIOD -#define LED4_GPIO_CLK RCC_AHB1Periph_GPIOD - -#define LED3_PIN GPIO_Pin_13 -#define LED3_GPIO_PORT GPIOD -#define LED3_GPIO_CLK RCC_AHB1Periph_GPIOD - -#define LED5_PIN GPIO_Pin_14 -#define LED5_GPIO_PORT GPIOD -#define LED5_GPIO_CLK RCC_AHB1Periph_GPIOD - -#define LED6_PIN GPIO_Pin_15 -#define LED6_GPIO_PORT GPIOD -#define LED6_GPIO_CLK RCC_AHB1Periph_GPIOD -/** - * @} - */ - -/** @addtogroup STM32F4_DISCOVERY_LOW_LEVEL_BUTTON - * @{ - */ -#define BUTTONn 1 - -/** - * @brief Wakeup push-button - */ -#define USER_BUTTON_PIN GPIO_Pin_0 -#define USER_BUTTON_GPIO_PORT GPIOA -#define USER_BUTTON_GPIO_CLK RCC_AHB1Periph_GPIOA -#define USER_BUTTON_EXTI_LINE EXTI_Line0 -#define USER_BUTTON_EXTI_PORT_SOURCE EXTI_PortSourceGPIOA -#define USER_BUTTON_EXTI_PIN_SOURCE EXTI_PinSource0 -#define USER_BUTTON_EXTI_IRQn EXTI0_IRQn -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Exported_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Exported_Functions - * @{ - */ -void STM_EVAL_LEDInit(Led_TypeDef Led); -void STM_EVAL_LEDOn(Led_TypeDef Led); -void STM_EVAL_LEDOff(Led_TypeDef Led); -void STM_EVAL_LEDToggle(Led_TypeDef Led); -void STM_EVAL_PBInit(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode); -uint32_t STM_EVAL_PBGetState(Button_TypeDef Button); -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4_DISCOVERY_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/device_support/stm32f4xx.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/device_support/stm32f4xx.h deleted file mode 100644 index db5d1e470..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/device_support/stm32f4xx.h +++ /dev/null @@ -1,7017 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx.h - * @author MCD Application Team - * @version V1.0.0 - * @date 30-September-2011 - * @brief CMSIS Cortex-M4 Device Peripheral Access Layer Header File. - * This file contains all the peripheral register's definitions, bits - * definitions and memory mapping for STM32F4xx devices. - * - * The file is the unique include file that the application programmer - * is using in the C source code, usually in main.c. This file contains: - * - Configuration section that allows to select: - * - The device used in the target application - * - To use or not the peripherals drivers in application code(i.e. - * code will be based on direct access to peripherals registers - * rather than drivers API), this option is controlled by - * "#define USE_STDPERIPH_DRIVER" - * - To change few application-specific parameters such as the HSE - * crystal frequency - * - Data structures and the address mapping for all peripherals - * - Peripheral's registers declarations and bits definition - * - Macros to access peripherals registers hardware - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32f4xx - * @{ - */ - -#ifndef __STM32F4xx_H -#define __STM32F4xx_H - -#ifdef __cplusplus - extern "C" { -#endif /* __cplusplus */ - -#ifdef USE_FULL_ASSERT - -/** - * @brief The assert_param macro is used for function's parameters check. - * @param expr: If expr is false, it calls assert_failed function - * which reports the name of the source file and the source - * line number of the call that failed. - * If expr is true, it returns no value. - * @retval None - */ - #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) -/* Exported functions ------------------------------------------------------- */ - void assert_failed(uint8_t* file, uint32_t line); -#else - #define assert_param(expr) ((void)0) -#endif /* USE_FULL_ASSERT */ - - -/** @addtogroup Library_configuration_section - * @{ - */ - -/* Uncomment the line below according to the target STM32 device used in your - application - */ - -#if !defined (STM32F4XX) - #define STM32F4XX -#endif - -/* Tip: To avoid modifying this file each time you need to switch between these - devices, you can define the device in your toolchain compiler preprocessor. - */ - -#if !defined (STM32F4XX) - #error "Please select first the target STM32F4XX device used in your application (in stm32f4xx.h file)" -#endif - -#if !defined (USE_STDPERIPH_DRIVER) -/** - * @brief Comment the line below if you will not use the peripherals drivers. - In this case, these drivers will not be included and the application code will - be based on direct access to peripherals registers - */ - /*#define USE_STDPERIPH_DRIVER*/ -#endif /* USE_STDPERIPH_DRIVER */ - -/** - * @brief In the following line adjust the value of External High Speed oscillator (HSE) - used in your application - - Tip: To avoid modifying this file each time you need to use different HSE, you - can define the HSE value in your toolchain compiler preprocessor. - */ - -#if !defined (HSE_VALUE) - #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ -#endif /* HSE_VALUE */ - -/** - * @brief In the following line adjust the External High Speed oscillator (HSE) Startup - Timeout value - */ -#if !defined (HSE_STARTUP_TIMEOUT) - #define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */ -#endif /* HSE_STARTUP_TIMEOUT */ - -#if !defined (HSI_VALUE) - #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ -#endif /* HSI_VALUE */ - -/** - * @brief STM32F4XX Standard Peripherals Library version number V1.0.0 - */ -#define __STM32F4XX_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ -#define __STM32F4XX_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ -#define __STM32F4XX_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ -#define __STM32F4XX_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ -#define __STM32F4XX_STDPERIPH_VERSION ((__STM32F4XX_STDPERIPH_VERSION_MAIN << 24)\ - |(__STM32F4XX_STDPERIPH_VERSION_SUB1 << 16)\ - |(__STM32F4XX_STDPERIPH_VERSION_SUB2 << 8)\ - |(__STM32F4XX_STDPERIPH_VERSION_RC)) - -/** - * @} - */ - -/** @addtogroup Configuration_section_for_CMSIS - * @{ - */ - -/** - * @brief Configuration of the Cortex-M4 Processor and Core Peripherals - */ -#define __CM4_REV 0x0001 /*!< Core revision r0p1 */ -#define __MPU_PRESENT 1 /*!< STM32F4XX provides an MPU */ -#define __NVIC_PRIO_BITS 4 /*!< STM32F4XX uses 4 Bits for the Priority Levels */ -#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ -#define __FPU_PRESENT 1 /*!< FPU present */ - -/** - * @brief STM32F4XX Interrupt Number Definition, according to the selected device - * in @ref Library_configuration_section - */ -typedef enum IRQn -{ -/****** Cortex-M4 Processor Exceptions Numbers ****************************************************************/ - NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ - MemoryManagement_IRQn = -12, /*!< 4 Cortex-M4 Memory Management Interrupt */ - BusFault_IRQn = -11, /*!< 5 Cortex-M4 Bus Fault Interrupt */ - UsageFault_IRQn = -10, /*!< 6 Cortex-M4 Usage Fault Interrupt */ - SVCall_IRQn = -5, /*!< 11 Cortex-M4 SV Call Interrupt */ - DebugMonitor_IRQn = -4, /*!< 12 Cortex-M4 Debug Monitor Interrupt */ - PendSV_IRQn = -2, /*!< 14 Cortex-M4 Pend SV Interrupt */ - SysTick_IRQn = -1, /*!< 15 Cortex-M4 System Tick Interrupt */ -/****** STM32 specific Interrupt Numbers **********************************************************************/ - WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ - PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ - TAMP_STAMP_IRQn = 2, /*!< Tamper and TimeStamp interrupts through the EXTI line */ - RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt through the EXTI line */ - FLASH_IRQn = 4, /*!< FLASH global Interrupt */ - RCC_IRQn = 5, /*!< RCC global Interrupt */ - EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ - EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ - EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ - EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ - EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ - DMA1_Stream0_IRQn = 11, /*!< DMA1 Stream 0 global Interrupt */ - DMA1_Stream1_IRQn = 12, /*!< DMA1 Stream 1 global Interrupt */ - DMA1_Stream2_IRQn = 13, /*!< DMA1 Stream 2 global Interrupt */ - DMA1_Stream3_IRQn = 14, /*!< DMA1 Stream 3 global Interrupt */ - DMA1_Stream4_IRQn = 15, /*!< DMA1 Stream 4 global Interrupt */ - DMA1_Stream5_IRQn = 16, /*!< DMA1 Stream 5 global Interrupt */ - DMA1_Stream6_IRQn = 17, /*!< DMA1 Stream 6 global Interrupt */ - ADC_IRQn = 18, /*!< ADC1, ADC2 and ADC3 global Interrupts */ - CAN1_TX_IRQn = 19, /*!< CAN1 TX Interrupt */ - CAN1_RX0_IRQn = 20, /*!< CAN1 RX0 Interrupt */ - CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ - CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ - EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ - TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break interrupt and TIM9 global interrupt */ - TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global interrupt */ - TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */ - TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ - TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ - TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ - TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ - I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ - I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ - I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ - I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ - SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ - SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ - USART1_IRQn = 37, /*!< USART1 global Interrupt */ - USART2_IRQn = 38, /*!< USART2 global Interrupt */ - USART3_IRQn = 39, /*!< USART3 global Interrupt */ - EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ - RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */ - OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */ - TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global interrupt */ - TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global interrupt */ - TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ - TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ - DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */ - FSMC_IRQn = 48, /*!< FSMC global Interrupt */ - SDIO_IRQn = 49, /*!< SDIO global Interrupt */ - TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ - SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ - UART4_IRQn = 52, /*!< UART4 global Interrupt */ - UART5_IRQn = 53, /*!< UART5 global Interrupt */ - TIM6_DAC_IRQn = 54, /*!< TIM6 global and DAC1&2 underrun error interrupts */ - TIM7_IRQn = 55, /*!< TIM7 global interrupt */ - DMA2_Stream0_IRQn = 56, /*!< DMA2 Stream 0 global Interrupt */ - DMA2_Stream1_IRQn = 57, /*!< DMA2 Stream 1 global Interrupt */ - DMA2_Stream2_IRQn = 58, /*!< DMA2 Stream 2 global Interrupt */ - DMA2_Stream3_IRQn = 59, /*!< DMA2 Stream 3 global Interrupt */ - DMA2_Stream4_IRQn = 60, /*!< DMA2 Stream 4 global Interrupt */ - ETH_IRQn = 61, /*!< Ethernet global Interrupt */ - ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ - CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */ - CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */ - CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */ - CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */ - OTG_FS_IRQn = 67, /*!< USB OTG FS global Interrupt */ - DMA2_Stream5_IRQn = 68, /*!< DMA2 Stream 5 global interrupt */ - DMA2_Stream6_IRQn = 69, /*!< DMA2 Stream 6 global interrupt */ - DMA2_Stream7_IRQn = 70, /*!< DMA2 Stream 7 global interrupt */ - USART6_IRQn = 71, /*!< USART6 global interrupt */ - I2C3_EV_IRQn = 72, /*!< I2C3 event interrupt */ - I2C3_ER_IRQn = 73, /*!< I2C3 error interrupt */ - OTG_HS_EP1_OUT_IRQn = 74, /*!< USB OTG HS End Point 1 Out global interrupt */ - OTG_HS_EP1_IN_IRQn = 75, /*!< USB OTG HS End Point 1 In global interrupt */ - OTG_HS_WKUP_IRQn = 76, /*!< USB OTG HS Wakeup through EXTI interrupt */ - OTG_HS_IRQn = 77, /*!< USB OTG HS global interrupt */ - DCMI_IRQn = 78, /*!< DCMI global interrupt */ - CRYP_IRQn = 79, /*!< CRYP crypto global interrupt */ - HASH_RNG_IRQn = 80, /*!< Hash and Rng global interrupt */ - FPU_IRQn = 81 /*!< FPU global interrupt */ -} IRQn_Type; - -/** - * @} - */ - -#include "core_cm4.h" /* Cortex-M4 processor and core peripherals */ -#include "system_stm32f4xx.h" -#include - -/** @addtogroup Exported_types - * @{ - */ -/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */ -typedef int32_t s32; -typedef int16_t s16; -typedef int8_t s8; - -typedef const int32_t sc32; /*!< Read Only */ -typedef const int16_t sc16; /*!< Read Only */ -typedef const int8_t sc8; /*!< Read Only */ - -typedef __IO int32_t vs32; -typedef __IO int16_t vs16; -typedef __IO int8_t vs8; - -typedef __I int32_t vsc32; /*!< Read Only */ -typedef __I int16_t vsc16; /*!< Read Only */ -typedef __I int8_t vsc8; /*!< Read Only */ - -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; - -typedef const uint32_t uc32; /*!< Read Only */ -typedef const uint16_t uc16; /*!< Read Only */ -typedef const uint8_t uc8; /*!< Read Only */ - -typedef __IO uint32_t vu32; -typedef __IO uint16_t vu16; -typedef __IO uint8_t vu8; - -typedef __I uint32_t vuc32; /*!< Read Only */ -typedef __I uint16_t vuc16; /*!< Read Only */ -typedef __I uint8_t vuc8; /*!< Read Only */ - -typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; - -typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; -#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) - -typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; - -/** - * @} - */ - -/** @addtogroup Peripheral_registers_structures - * @{ - */ - -/** - * @brief Analog to Digital Converter - */ - -typedef struct -{ - __IO uint32_t SR; /*!< ADC status register, Address offset: 0x00 */ - __IO uint32_t CR1; /*!< ADC control register 1, Address offset: 0x04 */ - __IO uint32_t CR2; /*!< ADC control register 2, Address offset: 0x08 */ - __IO uint32_t SMPR1; /*!< ADC sample time register 1, Address offset: 0x0C */ - __IO uint32_t SMPR2; /*!< ADC sample time register 2, Address offset: 0x10 */ - __IO uint32_t JOFR1; /*!< ADC injected channel data offset register 1, Address offset: 0x14 */ - __IO uint32_t JOFR2; /*!< ADC injected channel data offset register 2, Address offset: 0x18 */ - __IO uint32_t JOFR3; /*!< ADC injected channel data offset register 3, Address offset: 0x1C */ - __IO uint32_t JOFR4; /*!< ADC injected channel data offset register 4, Address offset: 0x20 */ - __IO uint32_t HTR; /*!< ADC watchdog higher threshold register, Address offset: 0x24 */ - __IO uint32_t LTR; /*!< ADC watchdog lower threshold register, Address offset: 0x28 */ - __IO uint32_t SQR1; /*!< ADC regular sequence register 1, Address offset: 0x2C */ - __IO uint32_t SQR2; /*!< ADC regular sequence register 2, Address offset: 0x30 */ - __IO uint32_t SQR3; /*!< ADC regular sequence register 3, Address offset: 0x34 */ - __IO uint32_t JSQR; /*!< ADC injected sequence register, Address offset: 0x38*/ - __IO uint32_t JDR1; /*!< ADC injected data register 1, Address offset: 0x3C */ - __IO uint32_t JDR2; /*!< ADC injected data register 2, Address offset: 0x40 */ - __IO uint32_t JDR3; /*!< ADC injected data register 3, Address offset: 0x44 */ - __IO uint32_t JDR4; /*!< ADC injected data register 4, Address offset: 0x48 */ - __IO uint32_t DR; /*!< ADC regular data register, Address offset: 0x4C */ -} ADC_TypeDef; - -typedef struct -{ - __IO uint32_t CSR; /*!< ADC Common status register, Address offset: ADC1 base address + 0x300 */ - __IO uint32_t CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */ - __IO uint32_t CDR; /*!< ADC common regular data register for dual - AND triple modes, Address offset: ADC1 base address + 0x308 */ -} ADC_Common_TypeDef; - - -/** - * @brief Controller Area Network TxMailBox - */ - -typedef struct -{ - __IO uint32_t TIR; /*!< CAN TX mailbox identifier register */ - __IO uint32_t TDTR; /*!< CAN mailbox data length control and time stamp register */ - __IO uint32_t TDLR; /*!< CAN mailbox data low register */ - __IO uint32_t TDHR; /*!< CAN mailbox data high register */ -} CAN_TxMailBox_TypeDef; - -/** - * @brief Controller Area Network FIFOMailBox - */ - -typedef struct -{ - __IO uint32_t RIR; /*!< CAN receive FIFO mailbox identifier register */ - __IO uint32_t RDTR; /*!< CAN receive FIFO mailbox data length control and time stamp register */ - __IO uint32_t RDLR; /*!< CAN receive FIFO mailbox data low register */ - __IO uint32_t RDHR; /*!< CAN receive FIFO mailbox data high register */ -} CAN_FIFOMailBox_TypeDef; - -/** - * @brief Controller Area Network FilterRegister - */ - -typedef struct -{ - __IO uint32_t FR1; /*!< CAN Filter bank register 1 */ - __IO uint32_t FR2; /*!< CAN Filter bank register 1 */ -} CAN_FilterRegister_TypeDef; - -/** - * @brief Controller Area Network - */ - -typedef struct -{ - __IO uint32_t MCR; /*!< CAN master control register, Address offset: 0x00 */ - __IO uint32_t MSR; /*!< CAN master status register, Address offset: 0x04 */ - __IO uint32_t TSR; /*!< CAN transmit status register, Address offset: 0x08 */ - __IO uint32_t RF0R; /*!< CAN receive FIFO 0 register, Address offset: 0x0C */ - __IO uint32_t RF1R; /*!< CAN receive FIFO 1 register, Address offset: 0x10 */ - __IO uint32_t IER; /*!< CAN interrupt enable register, Address offset: 0x14 */ - __IO uint32_t ESR; /*!< CAN error status register, Address offset: 0x18 */ - __IO uint32_t BTR; /*!< CAN bit timing register, Address offset: 0x1C */ - uint32_t RESERVED0[88]; /*!< Reserved, 0x020 - 0x17F */ - CAN_TxMailBox_TypeDef sTxMailBox[3]; /*!< CAN Tx MailBox, Address offset: 0x180 - 0x1AC */ - CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; /*!< CAN FIFO MailBox, Address offset: 0x1B0 - 0x1CC */ - uint32_t RESERVED1[12]; /*!< Reserved, 0x1D0 - 0x1FF */ - __IO uint32_t FMR; /*!< CAN filter master register, Address offset: 0x200 */ - __IO uint32_t FM1R; /*!< CAN filter mode register, Address offset: 0x204 */ - uint32_t RESERVED2; /*!< Reserved, 0x208 */ - __IO uint32_t FS1R; /*!< CAN filter scale register, Address offset: 0x20C */ - uint32_t RESERVED3; /*!< Reserved, 0x210 */ - __IO uint32_t FFA1R; /*!< CAN filter FIFO assignment register, Address offset: 0x214 */ - uint32_t RESERVED4; /*!< Reserved, 0x218 */ - __IO uint32_t FA1R; /*!< CAN filter activation register, Address offset: 0x21C */ - uint32_t RESERVED5[8]; /*!< Reserved, 0x220-0x23F */ - CAN_FilterRegister_TypeDef sFilterRegister[28]; /*!< CAN Filter Register, Address offset: 0x240-0x31C */ -} CAN_TypeDef; - -/** - * @brief CRC calculation unit - */ - -typedef struct -{ - __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ - __IO uint8_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ - uint8_t RESERVED0; /*!< Reserved, 0x05 */ - uint16_t RESERVED1; /*!< Reserved, 0x06 */ - __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ -} CRC_TypeDef; - -/** - * @brief Digital to Analog Converter - */ - -typedef struct -{ - __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ - __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ - __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ - __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ - __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ - __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */ - __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */ - __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */ - __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */ - __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */ - __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */ - __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ - __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */ - __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ -} DAC_TypeDef; - -/** - * @brief Debug MCU - */ - -typedef struct -{ - __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ - __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ - __IO uint32_t APB1FZ; /*!< Debug MCU APB1 freeze register, Address offset: 0x08 */ - __IO uint32_t APB2FZ; /*!< Debug MCU APB2 freeze register, Address offset: 0x0C */ -}DBGMCU_TypeDef; - -/** - * @brief DCMI - */ - -typedef struct -{ - __IO uint32_t CR; /*!< DCMI control register 1, Address offset: 0x00 */ - __IO uint32_t SR; /*!< DCMI status register, Address offset: 0x04 */ - __IO uint32_t RISR; /*!< DCMI raw interrupt status register, Address offset: 0x08 */ - __IO uint32_t IER; /*!< DCMI interrupt enable register, Address offset: 0x0C */ - __IO uint32_t MISR; /*!< DCMI masked interrupt status register, Address offset: 0x10 */ - __IO uint32_t ICR; /*!< DCMI interrupt clear register, Address offset: 0x14 */ - __IO uint32_t ESCR; /*!< DCMI embedded synchronization code register, Address offset: 0x18 */ - __IO uint32_t ESUR; /*!< DCMI embedded synchronization unmask register, Address offset: 0x1C */ - __IO uint32_t CWSTRTR; /*!< DCMI crop window start, Address offset: 0x20 */ - __IO uint32_t CWSIZER; /*!< DCMI crop window size, Address offset: 0x24 */ - __IO uint32_t DR; /*!< DCMI data register, Address offset: 0x28 */ -} DCMI_TypeDef; - -/** - * @brief DMA Controller - */ - -typedef struct -{ - __IO uint32_t CR; /*!< DMA stream x configuration register */ - __IO uint32_t NDTR; /*!< DMA stream x number of data register */ - __IO uint32_t PAR; /*!< DMA stream x peripheral address register */ - __IO uint32_t M0AR; /*!< DMA stream x memory 0 address register */ - __IO uint32_t M1AR; /*!< DMA stream x memory 1 address register */ - __IO uint32_t FCR; /*!< DMA stream x FIFO control register */ -} DMA_Stream_TypeDef; - -typedef struct -{ - __IO uint32_t LISR; /*!< DMA low interrupt status register, Address offset: 0x00 */ - __IO uint32_t HISR; /*!< DMA high interrupt status register, Address offset: 0x04 */ - __IO uint32_t LIFCR; /*!< DMA low interrupt flag clear register, Address offset: 0x08 */ - __IO uint32_t HIFCR; /*!< DMA high interrupt flag clear register, Address offset: 0x0C */ -} DMA_TypeDef; - -/** - * @brief Ethernet MAC - */ - -typedef struct -{ - __IO uint32_t MACCR; - __IO uint32_t MACFFR; - __IO uint32_t MACHTHR; - __IO uint32_t MACHTLR; - __IO uint32_t MACMIIAR; - __IO uint32_t MACMIIDR; - __IO uint32_t MACFCR; - __IO uint32_t MACVLANTR; /* 8 */ - uint32_t RESERVED0[2]; - __IO uint32_t MACRWUFFR; /* 11 */ - __IO uint32_t MACPMTCSR; - uint32_t RESERVED1[2]; - __IO uint32_t MACSR; /* 15 */ - __IO uint32_t MACIMR; - __IO uint32_t MACA0HR; - __IO uint32_t MACA0LR; - __IO uint32_t MACA1HR; - __IO uint32_t MACA1LR; - __IO uint32_t MACA2HR; - __IO uint32_t MACA2LR; - __IO uint32_t MACA3HR; - __IO uint32_t MACA3LR; /* 24 */ - uint32_t RESERVED2[40]; - __IO uint32_t MMCCR; /* 65 */ - __IO uint32_t MMCRIR; - __IO uint32_t MMCTIR; - __IO uint32_t MMCRIMR; - __IO uint32_t MMCTIMR; /* 69 */ - uint32_t RESERVED3[14]; - __IO uint32_t MMCTGFSCCR; /* 84 */ - __IO uint32_t MMCTGFMSCCR; - uint32_t RESERVED4[5]; - __IO uint32_t MMCTGFCR; - uint32_t RESERVED5[10]; - __IO uint32_t MMCRFCECR; - __IO uint32_t MMCRFAECR; - uint32_t RESERVED6[10]; - __IO uint32_t MMCRGUFCR; - uint32_t RESERVED7[334]; - __IO uint32_t PTPTSCR; - __IO uint32_t PTPSSIR; - __IO uint32_t PTPTSHR; - __IO uint32_t PTPTSLR; - __IO uint32_t PTPTSHUR; - __IO uint32_t PTPTSLUR; - __IO uint32_t PTPTSAR; - __IO uint32_t PTPTTHR; - __IO uint32_t PTPTTLR; - __IO uint32_t RESERVED8; - __IO uint32_t PTPTSSR; - uint32_t RESERVED9[565]; - __IO uint32_t DMABMR; - __IO uint32_t DMATPDR; - __IO uint32_t DMARPDR; - __IO uint32_t DMARDLAR; - __IO uint32_t DMATDLAR; - __IO uint32_t DMASR; - __IO uint32_t DMAOMR; - __IO uint32_t DMAIER; - __IO uint32_t DMAMFBOCR; - __IO uint32_t DMARSWTR; - uint32_t RESERVED10[8]; - __IO uint32_t DMACHTDR; - __IO uint32_t DMACHRDR; - __IO uint32_t DMACHTBAR; - __IO uint32_t DMACHRBAR; -} ETH_TypeDef; - -/** - * @brief External Interrupt/Event Controller - */ - -typedef struct -{ - __IO uint32_t IMR; /*!< EXTI Interrupt mask register, Address offset: 0x00 */ - __IO uint32_t EMR; /*!< EXTI Event mask register, Address offset: 0x04 */ - __IO uint32_t RTSR; /*!< EXTI Rising trigger selection register, Address offset: 0x08 */ - __IO uint32_t FTSR; /*!< EXTI Falling trigger selection register, Address offset: 0x0C */ - __IO uint32_t SWIER; /*!< EXTI Software interrupt event register, Address offset: 0x10 */ - __IO uint32_t PR; /*!< EXTI Pending register, Address offset: 0x14 */ -} EXTI_TypeDef; - -/** - * @brief FLASH Registers - */ - -typedef struct -{ - __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */ - __IO uint32_t KEYR; /*!< FLASH key register, Address offset: 0x04 */ - __IO uint32_t OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */ - __IO uint32_t SR; /*!< FLASH status register, Address offset: 0x0C */ - __IO uint32_t CR; /*!< FLASH control register, Address offset: 0x10 */ - __IO uint32_t OPTCR; /*!< FLASH option control register, Address offset: 0x14 */ -} FLASH_TypeDef; - -/** - * @brief Flexible Static Memory Controller - */ - -typedef struct -{ - __IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */ -} FSMC_Bank1_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank1E - */ - -typedef struct -{ - __IO uint32_t BWTR[7]; /*!< NOR/PSRAM write timing registers, Address offset: 0x104-0x11C */ -} FSMC_Bank1E_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank2 - */ - -typedef struct -{ - __IO uint32_t PCR2; /*!< NAND Flash control register 2, Address offset: 0x60 */ - __IO uint32_t SR2; /*!< NAND Flash FIFO status and interrupt register 2, Address offset: 0x64 */ - __IO uint32_t PMEM2; /*!< NAND Flash Common memory space timing register 2, Address offset: 0x68 */ - __IO uint32_t PATT2; /*!< NAND Flash Attribute memory space timing register 2, Address offset: 0x6C */ - uint32_t RESERVED0; /*!< Reserved, 0x70 */ - __IO uint32_t ECCR2; /*!< NAND Flash ECC result registers 2, Address offset: 0x74 */ -} FSMC_Bank2_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank3 - */ - -typedef struct -{ - __IO uint32_t PCR3; /*!< NAND Flash control register 3, Address offset: 0x80 */ - __IO uint32_t SR3; /*!< NAND Flash FIFO status and interrupt register 3, Address offset: 0x84 */ - __IO uint32_t PMEM3; /*!< NAND Flash Common memory space timing register 3, Address offset: 0x88 */ - __IO uint32_t PATT3; /*!< NAND Flash Attribute memory space timing register 3, Address offset: 0x8C */ - uint32_t RESERVED0; /*!< Reserved, 0x90 */ - __IO uint32_t ECCR3; /*!< NAND Flash ECC result registers 3, Address offset: 0x94 */ -} FSMC_Bank3_TypeDef; - -/** - * @brief Flexible Static Memory Controller Bank4 - */ - -typedef struct -{ - __IO uint32_t PCR4; /*!< PC Card control register 4, Address offset: 0xA0 */ - __IO uint32_t SR4; /*!< PC Card FIFO status and interrupt register 4, Address offset: 0xA4 */ - __IO uint32_t PMEM4; /*!< PC Card Common memory space timing register 4, Address offset: 0xA8 */ - __IO uint32_t PATT4; /*!< PC Card Attribute memory space timing register 4, Address offset: 0xAC */ - __IO uint32_t PIO4; /*!< PC Card I/O space timing register 4, Address offset: 0xB0 */ -} FSMC_Bank4_TypeDef; - -/** - * @brief General Purpose I/O - */ - -typedef struct -{ - __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ - __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ - __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ - __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ - __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ - __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ - __IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */ - __IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */ - __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ - __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ -} GPIO_TypeDef; - -/** - * @brief System configuration controller - */ - -typedef struct -{ - __IO uint32_t MEMRMP; /*!< SYSCFG memory remap register, Address offset: 0x00 */ - __IO uint32_t PMC; /*!< SYSCFG peripheral mode configuration register, Address offset: 0x04 */ - __IO uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */ - uint32_t RESERVED[2]; /*!< Reserved, 0x18-0x1C */ - __IO uint32_t CMPCR; /*!< SYSCFG Compensation cell control register, Address offset: 0x20 */ -} SYSCFG_TypeDef; - -/** - * @brief Inter-integrated Circuit Interface - */ - -typedef struct -{ - __IO uint16_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ - uint16_t RESERVED0; /*!< Reserved, 0x02 */ - __IO uint16_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ - uint16_t RESERVED1; /*!< Reserved, 0x06 */ - __IO uint16_t OAR1; /*!< I2C Own address register 1, Address offset: 0x08 */ - uint16_t RESERVED2; /*!< Reserved, 0x0A */ - __IO uint16_t OAR2; /*!< I2C Own address register 2, Address offset: 0x0C */ - uint16_t RESERVED3; /*!< Reserved, 0x0E */ - __IO uint16_t DR; /*!< I2C Data register, Address offset: 0x10 */ - uint16_t RESERVED4; /*!< Reserved, 0x12 */ - __IO uint16_t SR1; /*!< I2C Status register 1, Address offset: 0x14 */ - uint16_t RESERVED5; /*!< Reserved, 0x16 */ - __IO uint16_t SR2; /*!< I2C Status register 2, Address offset: 0x18 */ - uint16_t RESERVED6; /*!< Reserved, 0x1A */ - __IO uint16_t CCR; /*!< I2C Clock control register, Address offset: 0x1C */ - uint16_t RESERVED7; /*!< Reserved, 0x1E */ - __IO uint16_t TRISE; /*!< I2C TRISE register, Address offset: 0x20 */ - uint16_t RESERVED8; /*!< Reserved, 0x22 */ -} I2C_TypeDef; - -/** - * @brief Independent WATCHDOG - */ - -typedef struct -{ - __IO uint32_t KR; /*!< IWDG Key register, Address offset: 0x00 */ - __IO uint32_t PR; /*!< IWDG Prescaler register, Address offset: 0x04 */ - __IO uint32_t RLR; /*!< IWDG Reload register, Address offset: 0x08 */ - __IO uint32_t SR; /*!< IWDG Status register, Address offset: 0x0C */ -} IWDG_TypeDef; - -/** - * @brief Power Control - */ - -typedef struct -{ - __IO uint32_t CR; /*!< PWR power control register, Address offset: 0x00 */ - __IO uint32_t CSR; /*!< PWR power control/status register, Address offset: 0x04 */ -} PWR_TypeDef; - -/** - * @brief Reset and Clock Control - */ - -typedef struct -{ - __IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */ - __IO uint32_t PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */ - __IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */ - __IO uint32_t CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */ - __IO uint32_t AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */ - __IO uint32_t AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */ - __IO uint32_t AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */ - uint32_t RESERVED0; /*!< Reserved, 0x1C */ - __IO uint32_t APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */ - __IO uint32_t APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */ - uint32_t RESERVED1[2]; /*!< Reserved, 0x28-0x2C */ - __IO uint32_t AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */ - __IO uint32_t AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */ - __IO uint32_t AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */ - uint32_t RESERVED2; /*!< Reserved, 0x3C */ - __IO uint32_t APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */ - __IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */ - uint32_t RESERVED3[2]; /*!< Reserved, 0x48-0x4C */ - __IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */ - __IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */ - __IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */ - uint32_t RESERVED4; /*!< Reserved, 0x5C */ - __IO uint32_t APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */ - __IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */ - uint32_t RESERVED5[2]; /*!< Reserved, 0x68-0x6C */ - __IO uint32_t BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */ - __IO uint32_t CSR; /*!< RCC clock control & status register, Address offset: 0x74 */ - uint32_t RESERVED6[2]; /*!< Reserved, 0x78-0x7C */ - __IO uint32_t SSCGR; /*!< RCC spread spectrum clock generation register, Address offset: 0x80 */ - __IO uint32_t PLLI2SCFGR; /*!< RCC PLLI2S configuration register, Address offset: 0x84 */ -} RCC_TypeDef; - -/** - * @brief Real-Time Clock - */ - -typedef struct -{ - __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ - __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ - __IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */ - __IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */ - __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ - __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ - __IO uint32_t CALIBR; /*!< RTC calibration register, Address offset: 0x18 */ - __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */ - __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x20 */ - __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ - __IO uint32_t SSR; /*!< RTC sub second register, Address offset: 0x28 */ - __IO uint32_t SHIFTR; /*!< RTC shift control register, Address offset: 0x2C */ - __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ - __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ - __IO uint32_t TSSSR; /*!< RTC time-stamp sub second register, Address offset: 0x38 */ - __IO uint32_t CALR; /*!< RTC calibration register, Address offset: 0x3C */ - __IO uint32_t TAFCR; /*!< RTC tamper and alternate function configuration register, Address offset: 0x40 */ - __IO uint32_t ALRMASSR;/*!< RTC alarm A sub second register, Address offset: 0x44 */ - __IO uint32_t ALRMBSSR;/*!< RTC alarm B sub second register, Address offset: 0x48 */ - uint32_t RESERVED7; /*!< Reserved, 0x4C */ - __IO uint32_t BKP0R; /*!< RTC backup register 1, Address offset: 0x50 */ - __IO uint32_t BKP1R; /*!< RTC backup register 1, Address offset: 0x54 */ - __IO uint32_t BKP2R; /*!< RTC backup register 2, Address offset: 0x58 */ - __IO uint32_t BKP3R; /*!< RTC backup register 3, Address offset: 0x5C */ - __IO uint32_t BKP4R; /*!< RTC backup register 4, Address offset: 0x60 */ - __IO uint32_t BKP5R; /*!< RTC backup register 5, Address offset: 0x64 */ - __IO uint32_t BKP6R; /*!< RTC backup register 6, Address offset: 0x68 */ - __IO uint32_t BKP7R; /*!< RTC backup register 7, Address offset: 0x6C */ - __IO uint32_t BKP8R; /*!< RTC backup register 8, Address offset: 0x70 */ - __IO uint32_t BKP9R; /*!< RTC backup register 9, Address offset: 0x74 */ - __IO uint32_t BKP10R; /*!< RTC backup register 10, Address offset: 0x78 */ - __IO uint32_t BKP11R; /*!< RTC backup register 11, Address offset: 0x7C */ - __IO uint32_t BKP12R; /*!< RTC backup register 12, Address offset: 0x80 */ - __IO uint32_t BKP13R; /*!< RTC backup register 13, Address offset: 0x84 */ - __IO uint32_t BKP14R; /*!< RTC backup register 14, Address offset: 0x88 */ - __IO uint32_t BKP15R; /*!< RTC backup register 15, Address offset: 0x8C */ - __IO uint32_t BKP16R; /*!< RTC backup register 16, Address offset: 0x90 */ - __IO uint32_t BKP17R; /*!< RTC backup register 17, Address offset: 0x94 */ - __IO uint32_t BKP18R; /*!< RTC backup register 18, Address offset: 0x98 */ - __IO uint32_t BKP19R; /*!< RTC backup register 19, Address offset: 0x9C */ -} RTC_TypeDef; - -/** - * @brief SD host Interface - */ - -typedef struct -{ - __IO uint32_t POWER; /*!< SDIO power control register, Address offset: 0x00 */ - __IO uint32_t CLKCR; /*!< SDI clock control register, Address offset: 0x04 */ - __IO uint32_t ARG; /*!< SDIO argument register, Address offset: 0x08 */ - __IO uint32_t CMD; /*!< SDIO command register, Address offset: 0x0C */ - __I uint32_t RESPCMD; /*!< SDIO command response register, Address offset: 0x10 */ - __I uint32_t RESP1; /*!< SDIO response 1 register, Address offset: 0x14 */ - __I uint32_t RESP2; /*!< SDIO response 2 register, Address offset: 0x18 */ - __I uint32_t RESP3; /*!< SDIO response 3 register, Address offset: 0x1C */ - __I uint32_t RESP4; /*!< SDIO response 4 register, Address offset: 0x20 */ - __IO uint32_t DTIMER; /*!< SDIO data timer register, Address offset: 0x24 */ - __IO uint32_t DLEN; /*!< SDIO data length register, Address offset: 0x28 */ - __IO uint32_t DCTRL; /*!< SDIO data control register, Address offset: 0x2C */ - __I uint32_t DCOUNT; /*!< SDIO data counter register, Address offset: 0x30 */ - __I uint32_t STA; /*!< SDIO status register, Address offset: 0x34 */ - __IO uint32_t ICR; /*!< SDIO interrupt clear register, Address offset: 0x38 */ - __IO uint32_t MASK; /*!< SDIO mask register, Address offset: 0x3C */ - uint32_t RESERVED0[2]; /*!< Reserved, 0x40-0x44 */ - __I uint32_t FIFOCNT; /*!< SDIO FIFO counter register, Address offset: 0x48 */ - uint32_t RESERVED1[13]; /*!< Reserved, 0x4C-0x7C */ - __IO uint32_t FIFO; /*!< SDIO data FIFO register, Address offset: 0x80 */ -} SDIO_TypeDef; - -/** - * @brief Serial Peripheral Interface - */ - -typedef struct -{ - __IO uint16_t CR1; /*!< SPI control register 1 (not used in I2S mode), Address offset: 0x00 */ - uint16_t RESERVED0; /*!< Reserved, 0x02 */ - __IO uint16_t CR2; /*!< SPI control register 2, Address offset: 0x04 */ - uint16_t RESERVED1; /*!< Reserved, 0x06 */ - __IO uint16_t SR; /*!< SPI status register, Address offset: 0x08 */ - uint16_t RESERVED2; /*!< Reserved, 0x0A */ - __IO uint16_t DR; /*!< SPI data register, Address offset: 0x0C */ - uint16_t RESERVED3; /*!< Reserved, 0x0E */ - __IO uint16_t CRCPR; /*!< SPI CRC polynomial register (not used in I2S mode), Address offset: 0x10 */ - uint16_t RESERVED4; /*!< Reserved, 0x12 */ - __IO uint16_t RXCRCR; /*!< SPI RX CRC register (not used in I2S mode), Address offset: 0x14 */ - uint16_t RESERVED5; /*!< Reserved, 0x16 */ - __IO uint16_t TXCRCR; /*!< SPI TX CRC register (not used in I2S mode), Address offset: 0x18 */ - uint16_t RESERVED6; /*!< Reserved, 0x1A */ - __IO uint16_t I2SCFGR; /*!< SPI_I2S configuration register, Address offset: 0x1C */ - uint16_t RESERVED7; /*!< Reserved, 0x1E */ - __IO uint16_t I2SPR; /*!< SPI_I2S prescaler register, Address offset: 0x20 */ - uint16_t RESERVED8; /*!< Reserved, 0x22 */ -} SPI_TypeDef; - -/** - * @brief TIM - */ - -typedef struct -{ - __IO uint16_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ - uint16_t RESERVED0; /*!< Reserved, 0x02 */ - __IO uint16_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ - uint16_t RESERVED1; /*!< Reserved, 0x06 */ - __IO uint16_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ - uint16_t RESERVED2; /*!< Reserved, 0x0A */ - __IO uint16_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ - uint16_t RESERVED3; /*!< Reserved, 0x0E */ - __IO uint16_t SR; /*!< TIM status register, Address offset: 0x10 */ - uint16_t RESERVED4; /*!< Reserved, 0x12 */ - __IO uint16_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ - uint16_t RESERVED5; /*!< Reserved, 0x16 */ - __IO uint16_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ - uint16_t RESERVED6; /*!< Reserved, 0x1A */ - __IO uint16_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ - uint16_t RESERVED7; /*!< Reserved, 0x1E */ - __IO uint16_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ - uint16_t RESERVED8; /*!< Reserved, 0x22 */ - __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ - __IO uint16_t PSC; /*!< TIM prescaler, Address offset: 0x28 */ - uint16_t RESERVED9; /*!< Reserved, 0x2A */ - __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ - __IO uint16_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */ - uint16_t RESERVED10; /*!< Reserved, 0x32 */ - __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ - __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ - __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ - __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ - __IO uint16_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */ - uint16_t RESERVED11; /*!< Reserved, 0x46 */ - __IO uint16_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */ - uint16_t RESERVED12; /*!< Reserved, 0x4A */ - __IO uint16_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */ - uint16_t RESERVED13; /*!< Reserved, 0x4E */ - __IO uint16_t OR; /*!< TIM option register, Address offset: 0x50 */ - uint16_t RESERVED14; /*!< Reserved, 0x52 */ -} TIM_TypeDef; - -/** - * @brief Universal Synchronous Asynchronous Receiver Transmitter - */ - -typedef struct -{ - __IO uint16_t SR; /*!< USART Status register, Address offset: 0x00 */ - uint16_t RESERVED0; /*!< Reserved, 0x02 */ - __IO uint16_t DR; /*!< USART Data register, Address offset: 0x04 */ - uint16_t RESERVED1; /*!< Reserved, 0x06 */ - __IO uint16_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */ - uint16_t RESERVED2; /*!< Reserved, 0x0A */ - __IO uint16_t CR1; /*!< USART Control register 1, Address offset: 0x0C */ - uint16_t RESERVED3; /*!< Reserved, 0x0E */ - __IO uint16_t CR2; /*!< USART Control register 2, Address offset: 0x10 */ - uint16_t RESERVED4; /*!< Reserved, 0x12 */ - __IO uint16_t CR3; /*!< USART Control register 3, Address offset: 0x14 */ - uint16_t RESERVED5; /*!< Reserved, 0x16 */ - __IO uint16_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */ - uint16_t RESERVED6; /*!< Reserved, 0x1A */ -} USART_TypeDef; - -/** - * @brief Window WATCHDOG - */ - -typedef struct -{ - __IO uint32_t CR; /*!< WWDG Control register, Address offset: 0x00 */ - __IO uint32_t CFR; /*!< WWDG Configuration register, Address offset: 0x04 */ - __IO uint32_t SR; /*!< WWDG Status register, Address offset: 0x08 */ -} WWDG_TypeDef; - -/** - * @brief Crypto Processor - */ - -typedef struct -{ - __IO uint32_t CR; /*!< CRYP control register, Address offset: 0x00 */ - __IO uint32_t SR; /*!< CRYP status register, Address offset: 0x04 */ - __IO uint32_t DR; /*!< CRYP data input register, Address offset: 0x08 */ - __IO uint32_t DOUT; /*!< CRYP data output register, Address offset: 0x0C */ - __IO uint32_t DMACR; /*!< CRYP DMA control register, Address offset: 0x10 */ - __IO uint32_t IMSCR; /*!< CRYP interrupt mask set/clear register, Address offset: 0x14 */ - __IO uint32_t RISR; /*!< CRYP raw interrupt status register, Address offset: 0x18 */ - __IO uint32_t MISR; /*!< CRYP masked interrupt status register, Address offset: 0x1C */ - __IO uint32_t K0LR; /*!< CRYP key left register 0, Address offset: 0x20 */ - __IO uint32_t K0RR; /*!< CRYP key right register 0, Address offset: 0x24 */ - __IO uint32_t K1LR; /*!< CRYP key left register 1, Address offset: 0x28 */ - __IO uint32_t K1RR; /*!< CRYP key right register 1, Address offset: 0x2C */ - __IO uint32_t K2LR; /*!< CRYP key left register 2, Address offset: 0x30 */ - __IO uint32_t K2RR; /*!< CRYP key right register 2, Address offset: 0x34 */ - __IO uint32_t K3LR; /*!< CRYP key left register 3, Address offset: 0x38 */ - __IO uint32_t K3RR; /*!< CRYP key right register 3, Address offset: 0x3C */ - __IO uint32_t IV0LR; /*!< CRYP initialization vector left-word register 0, Address offset: 0x40 */ - __IO uint32_t IV0RR; /*!< CRYP initialization vector right-word register 0, Address offset: 0x44 */ - __IO uint32_t IV1LR; /*!< CRYP initialization vector left-word register 1, Address offset: 0x48 */ - __IO uint32_t IV1RR; /*!< CRYP initialization vector right-word register 1, Address offset: 0x4C */ -} CRYP_TypeDef; - -/** - * @brief HASH - */ - -typedef struct -{ - __IO uint32_t CR; /*!< HASH control register, Address offset: 0x00 */ - __IO uint32_t DIN; /*!< HASH data input register, Address offset: 0x04 */ - __IO uint32_t STR; /*!< HASH start register, Address offset: 0x08 */ - __IO uint32_t HR[5]; /*!< HASH digest registers, Address offset: 0x0C-0x1C */ - __IO uint32_t IMR; /*!< HASH interrupt enable register, Address offset: 0x20 */ - __IO uint32_t SR; /*!< HASH status register, Address offset: 0x24 */ - uint32_t RESERVED[52]; /*!< Reserved, 0x28-0xF4 */ - __IO uint32_t CSR[51]; /*!< HASH context swap registers, Address offset: 0x0F8-0x1C0 */ -} HASH_TypeDef; - -/** - * @brief HASH - */ - -typedef struct -{ - __IO uint32_t CR; /*!< RNG control register, Address offset: 0x00 */ - __IO uint32_t SR; /*!< RNG status register, Address offset: 0x04 */ - __IO uint32_t DR; /*!< RNG data register, Address offset: 0x08 */ -} RNG_TypeDef; - -/** - * @} - */ - -/** @addtogroup Peripheral_memory_map - * @{ - */ -#define FLASH_BASE ((uint32_t)0x08000000) /*!< FLASH(up to 1 MB) base address in the alias region */ -#define CCMDATARAM_BASE ((uint32_t)0x10000000) /*!< CCM(core coupled memory) data RAM(64 KB) base address in the alias region */ -#define SRAM1_BASE ((uint32_t)0x20000000) /*!< SRAM1(112 KB) base address in the alias region */ -#define SRAM2_BASE ((uint32_t)0x2001C000) /*!< SRAM2(16 KB) base address in the alias region */ -#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */ -#define BKPSRAM_BASE ((uint32_t)0x40024000) /*!< Backup SRAM(4 KB) base address in the alias region */ -#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */ - -#define CCMDATARAM_BB_BASE ((uint32_t)0x12000000) /*!< CCM(core coupled memory) data RAM(64 KB) base address in the bit-band region */ -#define SRAM1_BB_BASE ((uint32_t)0x22000000) /*!< SRAM1(112 KB) base address in the bit-band region */ -#define SRAM2_BB_BASE ((uint32_t)0x2201C000) /*!< SRAM2(16 KB) base address in the bit-band region */ -#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */ -#define BKPSRAM_BB_BASE ((uint32_t)0x42024000) /*!< Backup SRAM(4 KB) base address in the bit-band region */ - -/* Legacy defines */ -#define SRAM_BASE SRAM1_BASE -#define SRAM_BB_BASE SRAM1_BB_BASE - - -/*!< Peripheral memory map */ -#define APB1PERIPH_BASE PERIPH_BASE -#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000) -#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000) -#define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000) - -/*!< APB1 peripherals */ -#define TIM2_BASE (APB1PERIPH_BASE + 0x0000) -#define TIM3_BASE (APB1PERIPH_BASE + 0x0400) -#define TIM4_BASE (APB1PERIPH_BASE + 0x0800) -#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00) -#define TIM6_BASE (APB1PERIPH_BASE + 0x1000) -#define TIM7_BASE (APB1PERIPH_BASE + 0x1400) -#define TIM12_BASE (APB1PERIPH_BASE + 0x1800) -#define TIM13_BASE (APB1PERIPH_BASE + 0x1C00) -#define TIM14_BASE (APB1PERIPH_BASE + 0x2000) -#define RTC_BASE (APB1PERIPH_BASE + 0x2800) -#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00) -#define IWDG_BASE (APB1PERIPH_BASE + 0x3000) -#define I2S2ext_BASE (APB1PERIPH_BASE + 0x3400) -#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) -#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) -#define I2S3ext_BASE (APB1PERIPH_BASE + 0x4000) -#define USART2_BASE (APB1PERIPH_BASE + 0x4400) -#define USART3_BASE (APB1PERIPH_BASE + 0x4800) -#define UART4_BASE (APB1PERIPH_BASE + 0x4C00) -#define UART5_BASE (APB1PERIPH_BASE + 0x5000) -#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) -#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) -#define I2C3_BASE (APB1PERIPH_BASE + 0x5C00) -#define CAN1_BASE (APB1PERIPH_BASE + 0x6400) -#define CAN2_BASE (APB1PERIPH_BASE + 0x6800) -#define PWR_BASE (APB1PERIPH_BASE + 0x7000) -#define DAC_BASE (APB1PERIPH_BASE + 0x7400) - -/*!< APB2 peripherals */ -#define TIM1_BASE (APB2PERIPH_BASE + 0x0000) -#define TIM8_BASE (APB2PERIPH_BASE + 0x0400) -#define USART1_BASE (APB2PERIPH_BASE + 0x1000) -#define USART6_BASE (APB2PERIPH_BASE + 0x1400) -#define ADC1_BASE (APB2PERIPH_BASE + 0x2000) -#define ADC2_BASE (APB2PERIPH_BASE + 0x2100) -#define ADC3_BASE (APB2PERIPH_BASE + 0x2200) -#define ADC_BASE (APB2PERIPH_BASE + 0x2300) -#define SDIO_BASE (APB2PERIPH_BASE + 0x2C00) -#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) -#define SYSCFG_BASE (APB2PERIPH_BASE + 0x3800) -#define EXTI_BASE (APB2PERIPH_BASE + 0x3C00) -#define TIM9_BASE (APB2PERIPH_BASE + 0x4000) -#define TIM10_BASE (APB2PERIPH_BASE + 0x4400) -#define TIM11_BASE (APB2PERIPH_BASE + 0x4800) - -/*!< AHB1 peripherals */ -#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) -#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400) -#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800) -#define GPIOD_BASE (AHB1PERIPH_BASE + 0x0C00) -#define GPIOE_BASE (AHB1PERIPH_BASE + 0x1000) -#define GPIOF_BASE (AHB1PERIPH_BASE + 0x1400) -#define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800) -#define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00) -#define GPIOI_BASE (AHB1PERIPH_BASE + 0x2000) -#define CRC_BASE (AHB1PERIPH_BASE + 0x3000) -#define RCC_BASE (AHB1PERIPH_BASE + 0x3800) -#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x3C00) -#define DMA1_BASE (AHB1PERIPH_BASE + 0x6000) -#define DMA1_Stream0_BASE (DMA1_BASE + 0x010) -#define DMA1_Stream1_BASE (DMA1_BASE + 0x028) -#define DMA1_Stream2_BASE (DMA1_BASE + 0x040) -#define DMA1_Stream3_BASE (DMA1_BASE + 0x058) -#define DMA1_Stream4_BASE (DMA1_BASE + 0x070) -#define DMA1_Stream5_BASE (DMA1_BASE + 0x088) -#define DMA1_Stream6_BASE (DMA1_BASE + 0x0A0) -#define DMA1_Stream7_BASE (DMA1_BASE + 0x0B8) -#define DMA2_BASE (AHB1PERIPH_BASE + 0x6400) -#define DMA2_Stream0_BASE (DMA2_BASE + 0x010) -#define DMA2_Stream1_BASE (DMA2_BASE + 0x028) -#define DMA2_Stream2_BASE (DMA2_BASE + 0x040) -#define DMA2_Stream3_BASE (DMA2_BASE + 0x058) -#define DMA2_Stream4_BASE (DMA2_BASE + 0x070) -#define DMA2_Stream5_BASE (DMA2_BASE + 0x088) -#define DMA2_Stream6_BASE (DMA2_BASE + 0x0A0) -#define DMA2_Stream7_BASE (DMA2_BASE + 0x0B8) -#define ETH_BASE (AHB1PERIPH_BASE + 0x8000) -#define ETH_MAC_BASE (ETH_BASE) -#define ETH_MMC_BASE (ETH_BASE + 0x0100) -#define ETH_PTP_BASE (ETH_BASE + 0x0700) -#define ETH_DMA_BASE (ETH_BASE + 0x1000) - -/*!< AHB2 peripherals */ -#define DCMI_BASE (AHB2PERIPH_BASE + 0x50000) -#define CRYP_BASE (AHB2PERIPH_BASE + 0x60000) -#define HASH_BASE (AHB2PERIPH_BASE + 0x60400) -#define RNG_BASE (AHB2PERIPH_BASE + 0x60800) - -/*!< FSMC Bankx registers base address */ -#define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) -#define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) -#define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060) -#define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080) -#define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0) - -/* Debug MCU registers base address */ -#define DBGMCU_BASE ((uint32_t )0xE0042000) - -/** - * @} - */ - -/** @addtogroup Peripheral_declaration - * @{ - */ -#define TIM2 ((TIM_TypeDef *) TIM2_BASE) -#define TIM3 ((TIM_TypeDef *) TIM3_BASE) -#define TIM4 ((TIM_TypeDef *) TIM4_BASE) -#define TIM5 ((TIM_TypeDef *) TIM5_BASE) -#define TIM6 ((TIM_TypeDef *) TIM6_BASE) -#define TIM7 ((TIM_TypeDef *) TIM7_BASE) -#define TIM12 ((TIM_TypeDef *) TIM12_BASE) -#define TIM13 ((TIM_TypeDef *) TIM13_BASE) -#define TIM14 ((TIM_TypeDef *) TIM14_BASE) -#define RTC ((RTC_TypeDef *) RTC_BASE) -#define WWDG ((WWDG_TypeDef *) WWDG_BASE) -#define IWDG ((IWDG_TypeDef *) IWDG_BASE) -#define I2S2ext ((SPI_TypeDef *) I2S2ext_BASE) -#define SPI2 ((SPI_TypeDef *) SPI2_BASE) -#define SPI3 ((SPI_TypeDef *) SPI3_BASE) -#define I2S3ext ((SPI_TypeDef *) I2S3ext_BASE) -#define USART2 ((USART_TypeDef *) USART2_BASE) -#define USART3 ((USART_TypeDef *) USART3_BASE) -#define UART4 ((USART_TypeDef *) UART4_BASE) -#define UART5 ((USART_TypeDef *) UART5_BASE) -#define I2C1 ((I2C_TypeDef *) I2C1_BASE) -#define I2C2 ((I2C_TypeDef *) I2C2_BASE) -#define I2C3 ((I2C_TypeDef *) I2C3_BASE) -#define CAN1 ((CAN_TypeDef *) CAN1_BASE) -#define CAN2 ((CAN_TypeDef *) CAN2_BASE) -#define PWR ((PWR_TypeDef *) PWR_BASE) -#define DAC ((DAC_TypeDef *) DAC_BASE) -#define TIM1 ((TIM_TypeDef *) TIM1_BASE) -#define TIM8 ((TIM_TypeDef *) TIM8_BASE) -#define USART1 ((USART_TypeDef *) USART1_BASE) -#define USART6 ((USART_TypeDef *) USART6_BASE) -#define ADC ((ADC_Common_TypeDef *) ADC_BASE) -#define ADC1 ((ADC_TypeDef *) ADC1_BASE) -#define ADC2 ((ADC_TypeDef *) ADC2_BASE) -#define ADC3 ((ADC_TypeDef *) ADC3_BASE) -#define SDIO ((SDIO_TypeDef *) SDIO_BASE) -#define SPI1 ((SPI_TypeDef *) SPI1_BASE) -#define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE) -#define EXTI ((EXTI_TypeDef *) EXTI_BASE) -#define TIM9 ((TIM_TypeDef *) TIM9_BASE) -#define TIM10 ((TIM_TypeDef *) TIM10_BASE) -#define TIM11 ((TIM_TypeDef *) TIM11_BASE) -#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) -#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) -#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) -#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) -#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) -#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) -#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE) -#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE) -#define GPIOI ((GPIO_TypeDef *) GPIOI_BASE) -#define CRC ((CRC_TypeDef *) CRC_BASE) -#define RCC ((RCC_TypeDef *) RCC_BASE) -#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) -#define DMA1 ((DMA_TypeDef *) DMA1_BASE) -#define DMA1_Stream0 ((DMA_Stream_TypeDef *) DMA1_Stream0_BASE) -#define DMA1_Stream1 ((DMA_Stream_TypeDef *) DMA1_Stream1_BASE) -#define DMA1_Stream2 ((DMA_Stream_TypeDef *) DMA1_Stream2_BASE) -#define DMA1_Stream3 ((DMA_Stream_TypeDef *) DMA1_Stream3_BASE) -#define DMA1_Stream4 ((DMA_Stream_TypeDef *) DMA1_Stream4_BASE) -#define DMA1_Stream5 ((DMA_Stream_TypeDef *) DMA1_Stream5_BASE) -#define DMA1_Stream6 ((DMA_Stream_TypeDef *) DMA1_Stream6_BASE) -#define DMA1_Stream7 ((DMA_Stream_TypeDef *) DMA1_Stream7_BASE) -#define DMA2 ((DMA_TypeDef *) DMA2_BASE) -#define DMA2_Stream0 ((DMA_Stream_TypeDef *) DMA2_Stream0_BASE) -#define DMA2_Stream1 ((DMA_Stream_TypeDef *) DMA2_Stream1_BASE) -#define DMA2_Stream2 ((DMA_Stream_TypeDef *) DMA2_Stream2_BASE) -#define DMA2_Stream3 ((DMA_Stream_TypeDef *) DMA2_Stream3_BASE) -#define DMA2_Stream4 ((DMA_Stream_TypeDef *) DMA2_Stream4_BASE) -#define DMA2_Stream5 ((DMA_Stream_TypeDef *) DMA2_Stream5_BASE) -#define DMA2_Stream6 ((DMA_Stream_TypeDef *) DMA2_Stream6_BASE) -#define DMA2_Stream7 ((DMA_Stream_TypeDef *) DMA2_Stream7_BASE) -#define ETH ((ETH_TypeDef *) ETH_BASE) -#define DCMI ((DCMI_TypeDef *) DCMI_BASE) -#define CRYP ((CRYP_TypeDef *) CRYP_BASE) -#define HASH ((HASH_TypeDef *) HASH_BASE) -#define RNG ((RNG_TypeDef *) RNG_BASE) -#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE) -#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE) -#define FSMC_Bank2 ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE) -#define FSMC_Bank3 ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE) -#define FSMC_Bank4 ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE) -#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) - -/** - * @} - */ - -/** @addtogroup Exported_constants - * @{ - */ - - /** @addtogroup Peripheral_Registers_Bits_Definition - * @{ - */ - -/******************************************************************************/ -/* Peripheral Registers_Bits_Definition */ -/******************************************************************************/ - -/******************************************************************************/ -/* */ -/* Analog to Digital Converter */ -/* */ -/******************************************************************************/ -/******************** Bit definition for ADC_SR register ********************/ -#define ADC_SR_AWD ((uint8_t)0x01) /*!
© COPYRIGHT 2011 STMicroelectronics
- ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32f4xx_system - * @{ - */ - -/** - * @brief Define to prevent recursive inclusion - */ -#ifndef __SYSTEM_STM32F4XX_H -#define __SYSTEM_STM32F4XX_H - -#ifdef __cplusplus - extern "C" { -#endif - -/** @addtogroup STM32F4xx_System_Includes - * @{ - */ - -/** - * @} - */ - - -/** @addtogroup STM32F4xx_System_Exported_types - * @{ - */ - -extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ - - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Exported_Constants - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Exported_Functions - * @{ - */ - -extern void SystemInit(void); -extern void SystemCoreClockUpdate(void); -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /*__SYSTEM_STM32F4XX_H */ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/misc.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/misc.h deleted file mode 100644 index 8030e67dd..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/misc.h +++ /dev/null @@ -1,172 +0,0 @@ -/** - ****************************************************************************** - * @file misc.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the miscellaneous - * firmware library functions (add-on to CMSIS functions). - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __MISC_H -#define __MISC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup MISC - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief NVIC Init Structure definition - */ - -typedef struct -{ - uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled. - This parameter can be an enumerator of @ref IRQn_Type - enumeration (For the complete STM32 Devices IRQ Channels - list, please refer to stm32f4xx.h file) */ - - uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel - specified in NVIC_IRQChannel. This parameter can be a value - between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table - A lower priority value indicates a higher priority */ - - uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified - in NVIC_IRQChannel. This parameter can be a value - between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table - A lower priority value indicates a higher priority */ - - FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel - will be enabled or disabled. - This parameter can be set either to ENABLE or DISABLE */ -} NVIC_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup MISC_Exported_Constants - * @{ - */ - -/** @defgroup MISC_Vector_Table_Base - * @{ - */ - -#define NVIC_VectTab_RAM ((uint32_t)0x20000000) -#define NVIC_VectTab_FLASH ((uint32_t)0x08000000) -#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \ - ((VECTTAB) == NVIC_VectTab_FLASH)) -/** - * @} - */ - -/** @defgroup MISC_System_Low_Power - * @{ - */ - -#define NVIC_LP_SEVONPEND ((uint8_t)0x10) -#define NVIC_LP_SLEEPDEEP ((uint8_t)0x04) -#define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02) -#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \ - ((LP) == NVIC_LP_SLEEPDEEP) || \ - ((LP) == NVIC_LP_SLEEPONEXIT)) -/** - * @} - */ - -/** @defgroup MISC_Preemption_Priority_Group - * @{ - */ - -#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority - 4 bits for subpriority */ -#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority - 3 bits for subpriority */ -#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority - 2 bits for subpriority */ -#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority - 1 bits for subpriority */ -#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority - 0 bits for subpriority */ - -#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \ - ((GROUP) == NVIC_PriorityGroup_1) || \ - ((GROUP) == NVIC_PriorityGroup_2) || \ - ((GROUP) == NVIC_PriorityGroup_3) || \ - ((GROUP) == NVIC_PriorityGroup_4)) - -#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) - -#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) - -#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF) - -/** - * @} - */ - -/** @defgroup MISC_SysTick_clock_source - * @{ - */ - -#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) -#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004) -#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \ - ((SOURCE) == SysTick_CLKSource_HCLK_Div8)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); -void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); -void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset); -void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState); -void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource); - -#ifdef __cplusplus -} -#endif - -#endif /* __MISC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_adc.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_adc.h deleted file mode 100644 index a4a0986da..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_adc.h +++ /dev/null @@ -1,643 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_adc.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the ADC firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_ADC_H -#define __STM32F4xx_ADC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup ADC - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief ADC Init structure definition - */ -typedef struct -{ - uint32_t ADC_Resolution; /*!< Configures the ADC resolution dual mode. - This parameter can be a value of @ref ADC_resolution */ - FunctionalState ADC_ScanConvMode; /*!< Specifies whether the conversion - is performed in Scan (multichannels) - or Single (one channel) mode. - This parameter can be set to ENABLE or DISABLE */ - FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion - is performed in Continuous or Single mode. - This parameter can be set to ENABLE or DISABLE. */ - uint32_t ADC_ExternalTrigConvEdge; /*!< Select the external trigger edge and - enable the trigger of a regular group. - This parameter can be a value of - @ref ADC_external_trigger_edge_for_regular_channels_conversion */ - uint32_t ADC_ExternalTrigConv; /*!< Select the external event used to trigger - the start of conversion of a regular group. - This parameter can be a value of - @ref ADC_extrenal_trigger_sources_for_regular_channels_conversion */ - uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment - is left or right. This parameter can be - a value of @ref ADC_data_align */ - uint8_t ADC_NbrOfConversion; /*!< Specifies the number of ADC conversions - that will be done using the sequencer for - regular channel group. - This parameter must range from 1 to 16. */ -}ADC_InitTypeDef; - -/** - * @brief ADC Common Init structure definition - */ -typedef struct -{ - uint32_t ADC_Mode; /*!< Configures the ADC to operate in - independent or multi mode. - This parameter can be a value of @ref ADC_Common_mode */ - uint32_t ADC_Prescaler; /*!< Select the frequency of the clock - to the ADC. The clock is common for all the ADCs. - This parameter can be a value of @ref ADC_Prescaler */ - uint32_t ADC_DMAAccessMode; /*!< Configures the Direct memory access - mode for multi ADC mode. - This parameter can be a value of - @ref ADC_Direct_memory_access_mode_for_multi_mode */ - uint32_t ADC_TwoSamplingDelay; /*!< Configures the Delay between 2 sampling phases. - This parameter can be a value of - @ref ADC_delay_between_2_sampling_phases */ - -}ADC_CommonInitTypeDef; - - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup ADC_Exported_Constants - * @{ - */ -#define IS_ADC_ALL_PERIPH(PERIPH) (((PERIPH) == ADC1) || \ - ((PERIPH) == ADC2) || \ - ((PERIPH) == ADC3)) - -/** @defgroup ADC_Common_mode - * @{ - */ -#define ADC_Mode_Independent ((uint32_t)0x00000000) -#define ADC_DualMode_RegSimult_InjecSimult ((uint32_t)0x00000001) -#define ADC_DualMode_RegSimult_AlterTrig ((uint32_t)0x00000002) -#define ADC_DualMode_InjecSimult ((uint32_t)0x00000005) -#define ADC_DualMode_RegSimult ((uint32_t)0x00000006) -#define ADC_DualMode_Interl ((uint32_t)0x00000007) -#define ADC_DualMode_AlterTrig ((uint32_t)0x00000009) -#define ADC_TripleMode_RegSimult_InjecSimult ((uint32_t)0x00000011) -#define ADC_TripleMode_RegSimult_AlterTrig ((uint32_t)0x00000012) -#define ADC_TripleMode_InjecSimult ((uint32_t)0x00000015) -#define ADC_TripleMode_RegSimult ((uint32_t)0x00000016) -#define ADC_TripleMode_Interl ((uint32_t)0x00000017) -#define ADC_TripleMode_AlterTrig ((uint32_t)0x00000019) -#define IS_ADC_MODE(MODE) (((MODE) == ADC_Mode_Independent) || \ - ((MODE) == ADC_DualMode_RegSimult_InjecSimult) || \ - ((MODE) == ADC_DualMode_RegSimult_AlterTrig) || \ - ((MODE) == ADC_DualMode_InjecSimult) || \ - ((MODE) == ADC_DualMode_RegSimult) || \ - ((MODE) == ADC_DualMode_Interl) || \ - ((MODE) == ADC_DualMode_AlterTrig) || \ - ((MODE) == ADC_TripleMode_RegSimult_InjecSimult) || \ - ((MODE) == ADC_TripleMode_RegSimult_AlterTrig) || \ - ((MODE) == ADC_TripleMode_InjecSimult) || \ - ((MODE) == ADC_TripleMode_RegSimult) || \ - ((MODE) == ADC_TripleMode_Interl) || \ - ((MODE) == ADC_TripleMode_AlterTrig)) -/** - * @} - */ - - -/** @defgroup ADC_Prescaler - * @{ - */ -#define ADC_Prescaler_Div2 ((uint32_t)0x00000000) -#define ADC_Prescaler_Div4 ((uint32_t)0x00010000) -#define ADC_Prescaler_Div6 ((uint32_t)0x00020000) -#define ADC_Prescaler_Div8 ((uint32_t)0x00030000) -#define IS_ADC_PRESCALER(PRESCALER) (((PRESCALER) == ADC_Prescaler_Div2) || \ - ((PRESCALER) == ADC_Prescaler_Div4) || \ - ((PRESCALER) == ADC_Prescaler_Div6) || \ - ((PRESCALER) == ADC_Prescaler_Div8)) -/** - * @} - */ - - -/** @defgroup ADC_Direct_memory_access_mode_for_multi_mode - * @{ - */ -#define ADC_DMAAccessMode_Disabled ((uint32_t)0x00000000) /* DMA mode disabled */ -#define ADC_DMAAccessMode_1 ((uint32_t)0x00004000) /* DMA mode 1 enabled (2 / 3 half-words one by one - 1 then 2 then 3)*/ -#define ADC_DMAAccessMode_2 ((uint32_t)0x00008000) /* DMA mode 2 enabled (2 / 3 half-words by pairs - 2&1 then 1&3 then 3&2)*/ -#define ADC_DMAAccessMode_3 ((uint32_t)0x0000C000) /* DMA mode 3 enabled (2 / 3 bytes by pairs - 2&1 then 1&3 then 3&2) */ -#define IS_ADC_DMA_ACCESS_MODE(MODE) (((MODE) == ADC_DMAAccessMode_Disabled) || \ - ((MODE) == ADC_DMAAccessMode_1) || \ - ((MODE) == ADC_DMAAccessMode_2) || \ - ((MODE) == ADC_DMAAccessMode_3)) - -/** - * @} - */ - - -/** @defgroup ADC_delay_between_2_sampling_phases - * @{ - */ -#define ADC_TwoSamplingDelay_5Cycles ((uint32_t)0x00000000) -#define ADC_TwoSamplingDelay_6Cycles ((uint32_t)0x00000100) -#define ADC_TwoSamplingDelay_7Cycles ((uint32_t)0x00000200) -#define ADC_TwoSamplingDelay_8Cycles ((uint32_t)0x00000300) -#define ADC_TwoSamplingDelay_9Cycles ((uint32_t)0x00000400) -#define ADC_TwoSamplingDelay_10Cycles ((uint32_t)0x00000500) -#define ADC_TwoSamplingDelay_11Cycles ((uint32_t)0x00000600) -#define ADC_TwoSamplingDelay_12Cycles ((uint32_t)0x00000700) -#define ADC_TwoSamplingDelay_13Cycles ((uint32_t)0x00000800) -#define ADC_TwoSamplingDelay_14Cycles ((uint32_t)0x00000900) -#define ADC_TwoSamplingDelay_15Cycles ((uint32_t)0x00000A00) -#define ADC_TwoSamplingDelay_16Cycles ((uint32_t)0x00000B00) -#define ADC_TwoSamplingDelay_17Cycles ((uint32_t)0x00000C00) -#define ADC_TwoSamplingDelay_18Cycles ((uint32_t)0x00000D00) -#define ADC_TwoSamplingDelay_19Cycles ((uint32_t)0x00000E00) -#define ADC_TwoSamplingDelay_20Cycles ((uint32_t)0x00000F00) -#define IS_ADC_SAMPLING_DELAY(DELAY) (((DELAY) == ADC_TwoSamplingDelay_5Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_6Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_7Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_8Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_9Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_10Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_11Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_12Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_13Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_14Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_15Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_16Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_17Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_18Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_19Cycles) || \ - ((DELAY) == ADC_TwoSamplingDelay_20Cycles)) - -/** - * @} - */ - - -/** @defgroup ADC_resolution - * @{ - */ -#define ADC_Resolution_12b ((uint32_t)0x00000000) -#define ADC_Resolution_10b ((uint32_t)0x01000000) -#define ADC_Resolution_8b ((uint32_t)0x02000000) -#define ADC_Resolution_6b ((uint32_t)0x03000000) -#define IS_ADC_RESOLUTION(RESOLUTION) (((RESOLUTION) == ADC_Resolution_12b) || \ - ((RESOLUTION) == ADC_Resolution_10b) || \ - ((RESOLUTION) == ADC_Resolution_8b) || \ - ((RESOLUTION) == ADC_Resolution_6b)) - -/** - * @} - */ - - -/** @defgroup ADC_external_trigger_edge_for_regular_channels_conversion - * @{ - */ -#define ADC_ExternalTrigConvEdge_None ((uint32_t)0x00000000) -#define ADC_ExternalTrigConvEdge_Rising ((uint32_t)0x10000000) -#define ADC_ExternalTrigConvEdge_Falling ((uint32_t)0x20000000) -#define ADC_ExternalTrigConvEdge_RisingFalling ((uint32_t)0x30000000) -#define IS_ADC_EXT_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigConvEdge_None) || \ - ((EDGE) == ADC_ExternalTrigConvEdge_Rising) || \ - ((EDGE) == ADC_ExternalTrigConvEdge_Falling) || \ - ((EDGE) == ADC_ExternalTrigConvEdge_RisingFalling)) -/** - * @} - */ - - -/** @defgroup ADC_extrenal_trigger_sources_for_regular_channels_conversion - * @{ - */ -#define ADC_ExternalTrigConv_T1_CC1 ((uint32_t)0x00000000) -#define ADC_ExternalTrigConv_T1_CC2 ((uint32_t)0x01000000) -#define ADC_ExternalTrigConv_T1_CC3 ((uint32_t)0x02000000) -#define ADC_ExternalTrigConv_T2_CC2 ((uint32_t)0x03000000) -#define ADC_ExternalTrigConv_T2_CC3 ((uint32_t)0x04000000) -#define ADC_ExternalTrigConv_T2_CC4 ((uint32_t)0x05000000) -#define ADC_ExternalTrigConv_T2_TRGO ((uint32_t)0x06000000) -#define ADC_ExternalTrigConv_T3_CC1 ((uint32_t)0x07000000) -#define ADC_ExternalTrigConv_T3_TRGO ((uint32_t)0x08000000) -#define ADC_ExternalTrigConv_T4_CC4 ((uint32_t)0x09000000) -#define ADC_ExternalTrigConv_T5_CC1 ((uint32_t)0x0A000000) -#define ADC_ExternalTrigConv_T5_CC2 ((uint32_t)0x0B000000) -#define ADC_ExternalTrigConv_T5_CC3 ((uint32_t)0x0C000000) -#define ADC_ExternalTrigConv_T8_CC1 ((uint32_t)0x0D000000) -#define ADC_ExternalTrigConv_T8_TRGO ((uint32_t)0x0E000000) -#define ADC_ExternalTrigConv_Ext_IT11 ((uint32_t)0x0F000000) -#define IS_ADC_EXT_TRIG(REGTRIG) (((REGTRIG) == ADC_ExternalTrigConv_T1_CC1) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T1_CC2) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T1_CC3) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T2_CC2) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T2_CC3) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T2_CC4) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T2_TRGO) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T3_CC1) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T3_TRGO) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T4_CC4) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T5_CC1) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T5_CC2) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T5_CC3) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T8_CC1) || \ - ((REGTRIG) == ADC_ExternalTrigConv_T8_TRGO) || \ - ((REGTRIG) == ADC_ExternalTrigConv_Ext_IT11)) -/** - * @} - */ - - -/** @defgroup ADC_data_align - * @{ - */ -#define ADC_DataAlign_Right ((uint32_t)0x00000000) -#define ADC_DataAlign_Left ((uint32_t)0x00000800) -#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DataAlign_Right) || \ - ((ALIGN) == ADC_DataAlign_Left)) -/** - * @} - */ - - -/** @defgroup ADC_channels - * @{ - */ -#define ADC_Channel_0 ((uint8_t)0x00) -#define ADC_Channel_1 ((uint8_t)0x01) -#define ADC_Channel_2 ((uint8_t)0x02) -#define ADC_Channel_3 ((uint8_t)0x03) -#define ADC_Channel_4 ((uint8_t)0x04) -#define ADC_Channel_5 ((uint8_t)0x05) -#define ADC_Channel_6 ((uint8_t)0x06) -#define ADC_Channel_7 ((uint8_t)0x07) -#define ADC_Channel_8 ((uint8_t)0x08) -#define ADC_Channel_9 ((uint8_t)0x09) -#define ADC_Channel_10 ((uint8_t)0x0A) -#define ADC_Channel_11 ((uint8_t)0x0B) -#define ADC_Channel_12 ((uint8_t)0x0C) -#define ADC_Channel_13 ((uint8_t)0x0D) -#define ADC_Channel_14 ((uint8_t)0x0E) -#define ADC_Channel_15 ((uint8_t)0x0F) -#define ADC_Channel_16 ((uint8_t)0x10) -#define ADC_Channel_17 ((uint8_t)0x11) -#define ADC_Channel_18 ((uint8_t)0x12) - -#define ADC_Channel_TempSensor ((uint8_t)ADC_Channel_16) -#define ADC_Channel_Vrefint ((uint8_t)ADC_Channel_17) -#define ADC_Channel_Vbat ((uint8_t)ADC_Channel_18) - -#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_0) || \ - ((CHANNEL) == ADC_Channel_1) || \ - ((CHANNEL) == ADC_Channel_2) || \ - ((CHANNEL) == ADC_Channel_3) || \ - ((CHANNEL) == ADC_Channel_4) || \ - ((CHANNEL) == ADC_Channel_5) || \ - ((CHANNEL) == ADC_Channel_6) || \ - ((CHANNEL) == ADC_Channel_7) || \ - ((CHANNEL) == ADC_Channel_8) || \ - ((CHANNEL) == ADC_Channel_9) || \ - ((CHANNEL) == ADC_Channel_10) || \ - ((CHANNEL) == ADC_Channel_11) || \ - ((CHANNEL) == ADC_Channel_12) || \ - ((CHANNEL) == ADC_Channel_13) || \ - ((CHANNEL) == ADC_Channel_14) || \ - ((CHANNEL) == ADC_Channel_15) || \ - ((CHANNEL) == ADC_Channel_16) || \ - ((CHANNEL) == ADC_Channel_17) || \ - ((CHANNEL) == ADC_Channel_18)) -/** - * @} - */ - - -/** @defgroup ADC_sampling_times - * @{ - */ -#define ADC_SampleTime_3Cycles ((uint8_t)0x00) -#define ADC_SampleTime_15Cycles ((uint8_t)0x01) -#define ADC_SampleTime_28Cycles ((uint8_t)0x02) -#define ADC_SampleTime_56Cycles ((uint8_t)0x03) -#define ADC_SampleTime_84Cycles ((uint8_t)0x04) -#define ADC_SampleTime_112Cycles ((uint8_t)0x05) -#define ADC_SampleTime_144Cycles ((uint8_t)0x06) -#define ADC_SampleTime_480Cycles ((uint8_t)0x07) -#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_3Cycles) || \ - ((TIME) == ADC_SampleTime_15Cycles) || \ - ((TIME) == ADC_SampleTime_28Cycles) || \ - ((TIME) == ADC_SampleTime_56Cycles) || \ - ((TIME) == ADC_SampleTime_84Cycles) || \ - ((TIME) == ADC_SampleTime_112Cycles) || \ - ((TIME) == ADC_SampleTime_144Cycles) || \ - ((TIME) == ADC_SampleTime_480Cycles)) -/** - * @} - */ - - -/** @defgroup ADC_external_trigger_edge_for_injected_channels_conversion - * @{ - */ -#define ADC_ExternalTrigInjecConvEdge_None ((uint32_t)0x00000000) -#define ADC_ExternalTrigInjecConvEdge_Rising ((uint32_t)0x00100000) -#define ADC_ExternalTrigInjecConvEdge_Falling ((uint32_t)0x00200000) -#define ADC_ExternalTrigInjecConvEdge_RisingFalling ((uint32_t)0x00300000) -#define IS_ADC_EXT_INJEC_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigInjecConvEdge_None) || \ - ((EDGE) == ADC_ExternalTrigInjecConvEdge_Rising) || \ - ((EDGE) == ADC_ExternalTrigInjecConvEdge_Falling) || \ - ((EDGE) == ADC_ExternalTrigInjecConvEdge_RisingFalling)) - -/** - * @} - */ - - -/** @defgroup ADC_extrenal_trigger_sources_for_injected_channels_conversion - * @{ - */ -#define ADC_ExternalTrigInjecConv_T1_CC4 ((uint32_t)0x00000000) -#define ADC_ExternalTrigInjecConv_T1_TRGO ((uint32_t)0x00010000) -#define ADC_ExternalTrigInjecConv_T2_CC1 ((uint32_t)0x00020000) -#define ADC_ExternalTrigInjecConv_T2_TRGO ((uint32_t)0x00030000) -#define ADC_ExternalTrigInjecConv_T3_CC2 ((uint32_t)0x00040000) -#define ADC_ExternalTrigInjecConv_T3_CC4 ((uint32_t)0x00050000) -#define ADC_ExternalTrigInjecConv_T4_CC1 ((uint32_t)0x00060000) -#define ADC_ExternalTrigInjecConv_T4_CC2 ((uint32_t)0x00070000) -#define ADC_ExternalTrigInjecConv_T4_CC3 ((uint32_t)0x00080000) -#define ADC_ExternalTrigInjecConv_T4_TRGO ((uint32_t)0x00090000) -#define ADC_ExternalTrigInjecConv_T5_CC4 ((uint32_t)0x000A0000) -#define ADC_ExternalTrigInjecConv_T5_TRGO ((uint32_t)0x000B0000) -#define ADC_ExternalTrigInjecConv_T8_CC2 ((uint32_t)0x000C0000) -#define ADC_ExternalTrigInjecConv_T8_CC3 ((uint32_t)0x000D0000) -#define ADC_ExternalTrigInjecConv_T8_CC4 ((uint32_t)0x000E0000) -#define ADC_ExternalTrigInjecConv_Ext_IT15 ((uint32_t)0x000F0000) -#define IS_ADC_EXT_INJEC_TRIG(INJTRIG) (((INJTRIG) == ADC_ExternalTrigInjecConv_T1_CC4) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T1_TRGO) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_CC1) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_TRGO) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC2) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC4) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC1) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC2) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC3) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_TRGO) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T5_CC4) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T5_TRGO) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC2) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC3) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC4) || \ - ((INJTRIG) == ADC_ExternalTrigInjecConv_Ext_IT15)) -/** - * @} - */ - - -/** @defgroup ADC_injected_channel_selection - * @{ - */ -#define ADC_InjectedChannel_1 ((uint8_t)0x14) -#define ADC_InjectedChannel_2 ((uint8_t)0x18) -#define ADC_InjectedChannel_3 ((uint8_t)0x1C) -#define ADC_InjectedChannel_4 ((uint8_t)0x20) -#define IS_ADC_INJECTED_CHANNEL(CHANNEL) (((CHANNEL) == ADC_InjectedChannel_1) || \ - ((CHANNEL) == ADC_InjectedChannel_2) || \ - ((CHANNEL) == ADC_InjectedChannel_3) || \ - ((CHANNEL) == ADC_InjectedChannel_4)) -/** - * @} - */ - - -/** @defgroup ADC_analog_watchdog_selection - * @{ - */ -#define ADC_AnalogWatchdog_SingleRegEnable ((uint32_t)0x00800200) -#define ADC_AnalogWatchdog_SingleInjecEnable ((uint32_t)0x00400200) -#define ADC_AnalogWatchdog_SingleRegOrInjecEnable ((uint32_t)0x00C00200) -#define ADC_AnalogWatchdog_AllRegEnable ((uint32_t)0x00800000) -#define ADC_AnalogWatchdog_AllInjecEnable ((uint32_t)0x00400000) -#define ADC_AnalogWatchdog_AllRegAllInjecEnable ((uint32_t)0x00C00000) -#define ADC_AnalogWatchdog_None ((uint32_t)0x00000000) -#define IS_ADC_ANALOG_WATCHDOG(WATCHDOG) (((WATCHDOG) == ADC_AnalogWatchdog_SingleRegEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_SingleInjecEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_SingleRegOrInjecEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_AllRegEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_AllInjecEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_AllRegAllInjecEnable) || \ - ((WATCHDOG) == ADC_AnalogWatchdog_None)) -/** - * @} - */ - - -/** @defgroup ADC_interrupts_definition - * @{ - */ -#define ADC_IT_EOC ((uint16_t)0x0205) -#define ADC_IT_AWD ((uint16_t)0x0106) -#define ADC_IT_JEOC ((uint16_t)0x0407) -#define ADC_IT_OVR ((uint16_t)0x201A) -#define IS_ADC_IT(IT) (((IT) == ADC_IT_EOC) || ((IT) == ADC_IT_AWD) || \ - ((IT) == ADC_IT_JEOC)|| ((IT) == ADC_IT_OVR)) -/** - * @} - */ - - -/** @defgroup ADC_flags_definition - * @{ - */ -#define ADC_FLAG_AWD ((uint8_t)0x01) -#define ADC_FLAG_EOC ((uint8_t)0x02) -#define ADC_FLAG_JEOC ((uint8_t)0x04) -#define ADC_FLAG_JSTRT ((uint8_t)0x08) -#define ADC_FLAG_STRT ((uint8_t)0x10) -#define ADC_FLAG_OVR ((uint8_t)0x20) - -#define IS_ADC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint8_t)0xC0) == 0x00) && ((FLAG) != 0x00)) -#define IS_ADC_GET_FLAG(FLAG) (((FLAG) == ADC_FLAG_AWD) || \ - ((FLAG) == ADC_FLAG_EOC) || \ - ((FLAG) == ADC_FLAG_JEOC) || \ - ((FLAG)== ADC_FLAG_JSTRT) || \ - ((FLAG) == ADC_FLAG_STRT) || \ - ((FLAG)== ADC_FLAG_OVR)) -/** - * @} - */ - - -/** @defgroup ADC_thresholds - * @{ - */ -#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFF) -/** - * @} - */ - - -/** @defgroup ADC_injected_offset - * @{ - */ -#define IS_ADC_OFFSET(OFFSET) ((OFFSET) <= 0xFFF) -/** - * @} - */ - - -/** @defgroup ADC_injected_length - * @{ - */ -#define IS_ADC_INJECTED_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x4)) -/** - * @} - */ - - -/** @defgroup ADC_injected_rank - * @{ - */ -#define IS_ADC_INJECTED_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x4)) -/** - * @} - */ - - -/** @defgroup ADC_regular_length - * @{ - */ -#define IS_ADC_REGULAR_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x10)) -/** - * @} - */ - - -/** @defgroup ADC_regular_rank - * @{ - */ -#define IS_ADC_REGULAR_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x10)) -/** - * @} - */ - - -/** @defgroup ADC_regular_discontinuous_mode_number - * @{ - */ -#define IS_ADC_REGULAR_DISC_NUMBER(NUMBER) (((NUMBER) >= 0x1) && ((NUMBER) <= 0x8)) -/** - * @} - */ - - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the ADC configuration to the default reset state *****/ -void ADC_DeInit(void); - -/* Initialization and Configuration functions *********************************/ -void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct); -void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct); -void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct); -void ADC_CommonStructInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct); -void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState); - -/* Analog Watchdog configuration functions ************************************/ -void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog); -void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold,uint16_t LowThreshold); -void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel); - -/* Temperature Sensor, Vrefint and VBAT management functions ******************/ -void ADC_TempSensorVrefintCmd(FunctionalState NewState); -void ADC_VBATCmd(FunctionalState NewState); - -/* Regular Channels Configuration functions ***********************************/ -void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); -void ADC_SoftwareStartConv(ADC_TypeDef* ADCx); -FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx); -void ADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number); -void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx); -uint32_t ADC_GetMultiModeConversionValue(void); - -/* Regular Channels DMA Configuration functions *******************************/ -void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_MultiModeDMARequestAfterLastTransferCmd(FunctionalState NewState); - -/* Injected channels Configuration functions **********************************/ -void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); -void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length); -void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset); -void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv); -void ADC_ExternalTrigInjectedConvEdgeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConvEdge); -void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx); -FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx); -void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); -uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel); - -/* Interrupts and flags management functions **********************************/ -void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState); -FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG); -void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG); -ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT); -void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F4xx_ADC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_can.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_can.h deleted file mode 100644 index 3cb8da0d5..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_can.h +++ /dev/null @@ -1,638 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_can.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the CAN firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_CAN_H -#define __STM32F4xx_CAN_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup CAN - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -#define IS_CAN_ALL_PERIPH(PERIPH) (((PERIPH) == CAN1) || \ - ((PERIPH) == CAN2)) - -/** - * @brief CAN init structure definition - */ -typedef struct -{ - uint16_t CAN_Prescaler; /*!< Specifies the length of a time quantum. - It ranges from 1 to 1024. */ - - uint8_t CAN_Mode; /*!< Specifies the CAN operating mode. - This parameter can be a value of @ref CAN_operating_mode */ - - uint8_t CAN_SJW; /*!< Specifies the maximum number of time quanta - the CAN hardware is allowed to lengthen or - shorten a bit to perform resynchronization. - This parameter can be a value of @ref CAN_synchronisation_jump_width */ - - uint8_t CAN_BS1; /*!< Specifies the number of time quanta in Bit - Segment 1. This parameter can be a value of - @ref CAN_time_quantum_in_bit_segment_1 */ - - uint8_t CAN_BS2; /*!< Specifies the number of time quanta in Bit Segment 2. - This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */ - - FunctionalState CAN_TTCM; /*!< Enable or disable the time triggered communication mode. - This parameter can be set either to ENABLE or DISABLE. */ - - FunctionalState CAN_ABOM; /*!< Enable or disable the automatic bus-off management. - This parameter can be set either to ENABLE or DISABLE. */ - - FunctionalState CAN_AWUM; /*!< Enable or disable the automatic wake-up mode. - This parameter can be set either to ENABLE or DISABLE. */ - - FunctionalState CAN_NART; /*!< Enable or disable the non-automatic retransmission mode. - This parameter can be set either to ENABLE or DISABLE. */ - - FunctionalState CAN_RFLM; /*!< Enable or disable the Receive FIFO Locked mode. - This parameter can be set either to ENABLE or DISABLE. */ - - FunctionalState CAN_TXFP; /*!< Enable or disable the transmit FIFO priority. - This parameter can be set either to ENABLE or DISABLE. */ -} CAN_InitTypeDef; - -/** - * @brief CAN filter init structure definition - */ -typedef struct -{ - uint16_t CAN_FilterIdHigh; /*!< Specifies the filter identification number (MSBs for a 32-bit - configuration, first one for a 16-bit configuration). - This parameter can be a value between 0x0000 and 0xFFFF */ - - uint16_t CAN_FilterIdLow; /*!< Specifies the filter identification number (LSBs for a 32-bit - configuration, second one for a 16-bit configuration). - This parameter can be a value between 0x0000 and 0xFFFF */ - - uint16_t CAN_FilterMaskIdHigh; /*!< Specifies the filter mask number or identification number, - according to the mode (MSBs for a 32-bit configuration, - first one for a 16-bit configuration). - This parameter can be a value between 0x0000 and 0xFFFF */ - - uint16_t CAN_FilterMaskIdLow; /*!< Specifies the filter mask number or identification number, - according to the mode (LSBs for a 32-bit configuration, - second one for a 16-bit configuration). - This parameter can be a value between 0x0000 and 0xFFFF */ - - uint16_t CAN_FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1) which will be assigned to the filter. - This parameter can be a value of @ref CAN_filter_FIFO */ - - uint8_t CAN_FilterNumber; /*!< Specifies the filter which will be initialized. It ranges from 0 to 13. */ - - uint8_t CAN_FilterMode; /*!< Specifies the filter mode to be initialized. - This parameter can be a value of @ref CAN_filter_mode */ - - uint8_t CAN_FilterScale; /*!< Specifies the filter scale. - This parameter can be a value of @ref CAN_filter_scale */ - - FunctionalState CAN_FilterActivation; /*!< Enable or disable the filter. - This parameter can be set either to ENABLE or DISABLE. */ -} CAN_FilterInitTypeDef; - -/** - * @brief CAN Tx message structure definition - */ -typedef struct -{ - uint32_t StdId; /*!< Specifies the standard identifier. - This parameter can be a value between 0 to 0x7FF. */ - - uint32_t ExtId; /*!< Specifies the extended identifier. - This parameter can be a value between 0 to 0x1FFFFFFF. */ - - uint8_t IDE; /*!< Specifies the type of identifier for the message that - will be transmitted. This parameter can be a value - of @ref CAN_identifier_type */ - - uint8_t RTR; /*!< Specifies the type of frame for the message that will - be transmitted. This parameter can be a value of - @ref CAN_remote_transmission_request */ - - uint8_t DLC; /*!< Specifies the length of the frame that will be - transmitted. This parameter can be a value between - 0 to 8 */ - - uint8_t Data[8]; /*!< Contains the data to be transmitted. It ranges from 0 - to 0xFF. */ -} CanTxMsg; - -/** - * @brief CAN Rx message structure definition - */ -typedef struct -{ - uint32_t StdId; /*!< Specifies the standard identifier. - This parameter can be a value between 0 to 0x7FF. */ - - uint32_t ExtId; /*!< Specifies the extended identifier. - This parameter can be a value between 0 to 0x1FFFFFFF. */ - - uint8_t IDE; /*!< Specifies the type of identifier for the message that - will be received. This parameter can be a value of - @ref CAN_identifier_type */ - - uint8_t RTR; /*!< Specifies the type of frame for the received message. - This parameter can be a value of - @ref CAN_remote_transmission_request */ - - uint8_t DLC; /*!< Specifies the length of the frame that will be received. - This parameter can be a value between 0 to 8 */ - - uint8_t Data[8]; /*!< Contains the data to be received. It ranges from 0 to - 0xFF. */ - - uint8_t FMI; /*!< Specifies the index of the filter the message stored in - the mailbox passes through. This parameter can be a - value between 0 to 0xFF */ -} CanRxMsg; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup CAN_Exported_Constants - * @{ - */ - -/** @defgroup CAN_InitStatus - * @{ - */ - -#define CAN_InitStatus_Failed ((uint8_t)0x00) /*!< CAN initialization failed */ -#define CAN_InitStatus_Success ((uint8_t)0x01) /*!< CAN initialization OK */ - - -/* Legacy defines */ -#define CANINITFAILED CAN_InitStatus_Failed -#define CANINITOK CAN_InitStatus_Success -/** - * @} - */ - -/** @defgroup CAN_operating_mode - * @{ - */ - -#define CAN_Mode_Normal ((uint8_t)0x00) /*!< normal mode */ -#define CAN_Mode_LoopBack ((uint8_t)0x01) /*!< loopback mode */ -#define CAN_Mode_Silent ((uint8_t)0x02) /*!< silent mode */ -#define CAN_Mode_Silent_LoopBack ((uint8_t)0x03) /*!< loopback combined with silent mode */ - -#define IS_CAN_MODE(MODE) (((MODE) == CAN_Mode_Normal) || \ - ((MODE) == CAN_Mode_LoopBack)|| \ - ((MODE) == CAN_Mode_Silent) || \ - ((MODE) == CAN_Mode_Silent_LoopBack)) -/** - * @} - */ - - - /** - * @defgroup CAN_operating_mode - * @{ - */ -#define CAN_OperatingMode_Initialization ((uint8_t)0x00) /*!< Initialization mode */ -#define CAN_OperatingMode_Normal ((uint8_t)0x01) /*!< Normal mode */ -#define CAN_OperatingMode_Sleep ((uint8_t)0x02) /*!< sleep mode */ - - -#define IS_CAN_OPERATING_MODE(MODE) (((MODE) == CAN_OperatingMode_Initialization) ||\ - ((MODE) == CAN_OperatingMode_Normal)|| \ - ((MODE) == CAN_OperatingMode_Sleep)) -/** - * @} - */ - -/** - * @defgroup CAN_operating_mode_status - * @{ - */ - -#define CAN_ModeStatus_Failed ((uint8_t)0x00) /*!< CAN entering the specific mode failed */ -#define CAN_ModeStatus_Success ((uint8_t)!CAN_ModeStatus_Failed) /*!< CAN entering the specific mode Succeed */ -/** - * @} - */ - -/** @defgroup CAN_synchronisation_jump_width - * @{ - */ -#define CAN_SJW_1tq ((uint8_t)0x00) /*!< 1 time quantum */ -#define CAN_SJW_2tq ((uint8_t)0x01) /*!< 2 time quantum */ -#define CAN_SJW_3tq ((uint8_t)0x02) /*!< 3 time quantum */ -#define CAN_SJW_4tq ((uint8_t)0x03) /*!< 4 time quantum */ - -#define IS_CAN_SJW(SJW) (((SJW) == CAN_SJW_1tq) || ((SJW) == CAN_SJW_2tq)|| \ - ((SJW) == CAN_SJW_3tq) || ((SJW) == CAN_SJW_4tq)) -/** - * @} - */ - -/** @defgroup CAN_time_quantum_in_bit_segment_1 - * @{ - */ -#define CAN_BS1_1tq ((uint8_t)0x00) /*!< 1 time quantum */ -#define CAN_BS1_2tq ((uint8_t)0x01) /*!< 2 time quantum */ -#define CAN_BS1_3tq ((uint8_t)0x02) /*!< 3 time quantum */ -#define CAN_BS1_4tq ((uint8_t)0x03) /*!< 4 time quantum */ -#define CAN_BS1_5tq ((uint8_t)0x04) /*!< 5 time quantum */ -#define CAN_BS1_6tq ((uint8_t)0x05) /*!< 6 time quantum */ -#define CAN_BS1_7tq ((uint8_t)0x06) /*!< 7 time quantum */ -#define CAN_BS1_8tq ((uint8_t)0x07) /*!< 8 time quantum */ -#define CAN_BS1_9tq ((uint8_t)0x08) /*!< 9 time quantum */ -#define CAN_BS1_10tq ((uint8_t)0x09) /*!< 10 time quantum */ -#define CAN_BS1_11tq ((uint8_t)0x0A) /*!< 11 time quantum */ -#define CAN_BS1_12tq ((uint8_t)0x0B) /*!< 12 time quantum */ -#define CAN_BS1_13tq ((uint8_t)0x0C) /*!< 13 time quantum */ -#define CAN_BS1_14tq ((uint8_t)0x0D) /*!< 14 time quantum */ -#define CAN_BS1_15tq ((uint8_t)0x0E) /*!< 15 time quantum */ -#define CAN_BS1_16tq ((uint8_t)0x0F) /*!< 16 time quantum */ - -#define IS_CAN_BS1(BS1) ((BS1) <= CAN_BS1_16tq) -/** - * @} - */ - -/** @defgroup CAN_time_quantum_in_bit_segment_2 - * @{ - */ -#define CAN_BS2_1tq ((uint8_t)0x00) /*!< 1 time quantum */ -#define CAN_BS2_2tq ((uint8_t)0x01) /*!< 2 time quantum */ -#define CAN_BS2_3tq ((uint8_t)0x02) /*!< 3 time quantum */ -#define CAN_BS2_4tq ((uint8_t)0x03) /*!< 4 time quantum */ -#define CAN_BS2_5tq ((uint8_t)0x04) /*!< 5 time quantum */ -#define CAN_BS2_6tq ((uint8_t)0x05) /*!< 6 time quantum */ -#define CAN_BS2_7tq ((uint8_t)0x06) /*!< 7 time quantum */ -#define CAN_BS2_8tq ((uint8_t)0x07) /*!< 8 time quantum */ - -#define IS_CAN_BS2(BS2) ((BS2) <= CAN_BS2_8tq) -/** - * @} - */ - -/** @defgroup CAN_clock_prescaler - * @{ - */ -#define IS_CAN_PRESCALER(PRESCALER) (((PRESCALER) >= 1) && ((PRESCALER) <= 1024)) -/** - * @} - */ - -/** @defgroup CAN_filter_number - * @{ - */ -#define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 27) -/** - * @} - */ - -/** @defgroup CAN_filter_mode - * @{ - */ -#define CAN_FilterMode_IdMask ((uint8_t)0x00) /*!< identifier/mask mode */ -#define CAN_FilterMode_IdList ((uint8_t)0x01) /*!< identifier list mode */ - -#define IS_CAN_FILTER_MODE(MODE) (((MODE) == CAN_FilterMode_IdMask) || \ - ((MODE) == CAN_FilterMode_IdList)) -/** - * @} - */ - -/** @defgroup CAN_filter_scale - * @{ - */ -#define CAN_FilterScale_16bit ((uint8_t)0x00) /*!< Two 16-bit filters */ -#define CAN_FilterScale_32bit ((uint8_t)0x01) /*!< One 32-bit filter */ - -#define IS_CAN_FILTER_SCALE(SCALE) (((SCALE) == CAN_FilterScale_16bit) || \ - ((SCALE) == CAN_FilterScale_32bit)) -/** - * @} - */ - -/** @defgroup CAN_filter_FIFO - * @{ - */ -#define CAN_Filter_FIFO0 ((uint8_t)0x00) /*!< Filter FIFO 0 assignment for filter x */ -#define CAN_Filter_FIFO1 ((uint8_t)0x01) /*!< Filter FIFO 1 assignment for filter x */ -#define IS_CAN_FILTER_FIFO(FIFO) (((FIFO) == CAN_FilterFIFO0) || \ - ((FIFO) == CAN_FilterFIFO1)) - -/* Legacy defines */ -#define CAN_FilterFIFO0 CAN_Filter_FIFO0 -#define CAN_FilterFIFO1 CAN_Filter_FIFO1 -/** - * @} - */ - -/** @defgroup CAN_Start_bank_filter_for_slave_CAN - * @{ - */ -#define IS_CAN_BANKNUMBER(BANKNUMBER) (((BANKNUMBER) >= 1) && ((BANKNUMBER) <= 27)) -/** - * @} - */ - -/** @defgroup CAN_Tx - * @{ - */ -#define IS_CAN_TRANSMITMAILBOX(TRANSMITMAILBOX) ((TRANSMITMAILBOX) <= ((uint8_t)0x02)) -#define IS_CAN_STDID(STDID) ((STDID) <= ((uint32_t)0x7FF)) -#define IS_CAN_EXTID(EXTID) ((EXTID) <= ((uint32_t)0x1FFFFFFF)) -#define IS_CAN_DLC(DLC) ((DLC) <= ((uint8_t)0x08)) -/** - * @} - */ - -/** @defgroup CAN_identifier_type - * @{ - */ -#define CAN_Id_Standard ((uint32_t)0x00000000) /*!< Standard Id */ -#define CAN_Id_Extended ((uint32_t)0x00000004) /*!< Extended Id */ -#define IS_CAN_IDTYPE(IDTYPE) (((IDTYPE) == CAN_Id_Standard) || \ - ((IDTYPE) == CAN_Id_Extended)) - -/* Legacy defines */ -#define CAN_ID_STD CAN_Id_Standard -#define CAN_ID_EXT CAN_Id_Extended -/** - * @} - */ - -/** @defgroup CAN_remote_transmission_request - * @{ - */ -#define CAN_RTR_Data ((uint32_t)0x00000000) /*!< Data frame */ -#define CAN_RTR_Remote ((uint32_t)0x00000002) /*!< Remote frame */ -#define IS_CAN_RTR(RTR) (((RTR) == CAN_RTR_Data) || ((RTR) == CAN_RTR_Remote)) - -/* Legacy defines */ -#define CAN_RTR_DATA CAN_RTR_Data -#define CAN_RTR_REMOTE CAN_RTR_Remote -/** - * @} - */ - -/** @defgroup CAN_transmit_constants - * @{ - */ -#define CAN_TxStatus_Failed ((uint8_t)0x00)/*!< CAN transmission failed */ -#define CAN_TxStatus_Ok ((uint8_t)0x01) /*!< CAN transmission succeeded */ -#define CAN_TxStatus_Pending ((uint8_t)0x02) /*!< CAN transmission pending */ -#define CAN_TxStatus_NoMailBox ((uint8_t)0x04) /*!< CAN cell did not provide - an empty mailbox */ -/* Legacy defines */ -#define CANTXFAILED CAN_TxStatus_Failed -#define CANTXOK CAN_TxStatus_Ok -#define CANTXPENDING CAN_TxStatus_Pending -#define CAN_NO_MB CAN_TxStatus_NoMailBox -/** - * @} - */ - -/** @defgroup CAN_receive_FIFO_number_constants - * @{ - */ -#define CAN_FIFO0 ((uint8_t)0x00) /*!< CAN FIFO 0 used to receive */ -#define CAN_FIFO1 ((uint8_t)0x01) /*!< CAN FIFO 1 used to receive */ - -#define IS_CAN_FIFO(FIFO) (((FIFO) == CAN_FIFO0) || ((FIFO) == CAN_FIFO1)) -/** - * @} - */ - -/** @defgroup CAN_sleep_constants - * @{ - */ -#define CAN_Sleep_Failed ((uint8_t)0x00) /*!< CAN did not enter the sleep mode */ -#define CAN_Sleep_Ok ((uint8_t)0x01) /*!< CAN entered the sleep mode */ - -/* Legacy defines */ -#define CANSLEEPFAILED CAN_Sleep_Failed -#define CANSLEEPOK CAN_Sleep_Ok -/** - * @} - */ - -/** @defgroup CAN_wake_up_constants - * @{ - */ -#define CAN_WakeUp_Failed ((uint8_t)0x00) /*!< CAN did not leave the sleep mode */ -#define CAN_WakeUp_Ok ((uint8_t)0x01) /*!< CAN leaved the sleep mode */ - -/* Legacy defines */ -#define CANWAKEUPFAILED CAN_WakeUp_Failed -#define CANWAKEUPOK CAN_WakeUp_Ok -/** - * @} - */ - -/** - * @defgroup CAN_Error_Code_constants - * @{ - */ -#define CAN_ErrorCode_NoErr ((uint8_t)0x00) /*!< No Error */ -#define CAN_ErrorCode_StuffErr ((uint8_t)0x10) /*!< Stuff Error */ -#define CAN_ErrorCode_FormErr ((uint8_t)0x20) /*!< Form Error */ -#define CAN_ErrorCode_ACKErr ((uint8_t)0x30) /*!< Acknowledgment Error */ -#define CAN_ErrorCode_BitRecessiveErr ((uint8_t)0x40) /*!< Bit Recessive Error */ -#define CAN_ErrorCode_BitDominantErr ((uint8_t)0x50) /*!< Bit Dominant Error */ -#define CAN_ErrorCode_CRCErr ((uint8_t)0x60) /*!< CRC Error */ -#define CAN_ErrorCode_SoftwareSetErr ((uint8_t)0x70) /*!< Software Set Error */ -/** - * @} - */ - -/** @defgroup CAN_flags - * @{ - */ -/* If the flag is 0x3XXXXXXX, it means that it can be used with CAN_GetFlagStatus() - and CAN_ClearFlag() functions. */ -/* If the flag is 0x1XXXXXXX, it means that it can only be used with - CAN_GetFlagStatus() function. */ - -/* Transmit Flags */ -#define CAN_FLAG_RQCP0 ((uint32_t)0x38000001) /*!< Request MailBox0 Flag */ -#define CAN_FLAG_RQCP1 ((uint32_t)0x38000100) /*!< Request MailBox1 Flag */ -#define CAN_FLAG_RQCP2 ((uint32_t)0x38010000) /*!< Request MailBox2 Flag */ - -/* Receive Flags */ -#define CAN_FLAG_FMP0 ((uint32_t)0x12000003) /*!< FIFO 0 Message Pending Flag */ -#define CAN_FLAG_FF0 ((uint32_t)0x32000008) /*!< FIFO 0 Full Flag */ -#define CAN_FLAG_FOV0 ((uint32_t)0x32000010) /*!< FIFO 0 Overrun Flag */ -#define CAN_FLAG_FMP1 ((uint32_t)0x14000003) /*!< FIFO 1 Message Pending Flag */ -#define CAN_FLAG_FF1 ((uint32_t)0x34000008) /*!< FIFO 1 Full Flag */ -#define CAN_FLAG_FOV1 ((uint32_t)0x34000010) /*!< FIFO 1 Overrun Flag */ - -/* Operating Mode Flags */ -#define CAN_FLAG_WKU ((uint32_t)0x31000008) /*!< Wake up Flag */ -#define CAN_FLAG_SLAK ((uint32_t)0x31000012) /*!< Sleep acknowledge Flag */ -/* @note When SLAK interrupt is disabled (SLKIE=0), no polling on SLAKI is possible. - In this case the SLAK bit can be polled.*/ - -/* Error Flags */ -#define CAN_FLAG_EWG ((uint32_t)0x10F00001) /*!< Error Warning Flag */ -#define CAN_FLAG_EPV ((uint32_t)0x10F00002) /*!< Error Passive Flag */ -#define CAN_FLAG_BOF ((uint32_t)0x10F00004) /*!< Bus-Off Flag */ -#define CAN_FLAG_LEC ((uint32_t)0x30F00070) /*!< Last error code Flag */ - -#define IS_CAN_GET_FLAG(FLAG) (((FLAG) == CAN_FLAG_LEC) || ((FLAG) == CAN_FLAG_BOF) || \ - ((FLAG) == CAN_FLAG_EPV) || ((FLAG) == CAN_FLAG_EWG) || \ - ((FLAG) == CAN_FLAG_WKU) || ((FLAG) == CAN_FLAG_FOV0) || \ - ((FLAG) == CAN_FLAG_FF0) || ((FLAG) == CAN_FLAG_FMP0) || \ - ((FLAG) == CAN_FLAG_FOV1) || ((FLAG) == CAN_FLAG_FF1) || \ - ((FLAG) == CAN_FLAG_FMP1) || ((FLAG) == CAN_FLAG_RQCP2) || \ - ((FLAG) == CAN_FLAG_RQCP1)|| ((FLAG) == CAN_FLAG_RQCP0) || \ - ((FLAG) == CAN_FLAG_SLAK )) - -#define IS_CAN_CLEAR_FLAG(FLAG)(((FLAG) == CAN_FLAG_LEC) || ((FLAG) == CAN_FLAG_RQCP2) || \ - ((FLAG) == CAN_FLAG_RQCP1) || ((FLAG) == CAN_FLAG_RQCP0) || \ - ((FLAG) == CAN_FLAG_FF0) || ((FLAG) == CAN_FLAG_FOV0) ||\ - ((FLAG) == CAN_FLAG_FF1) || ((FLAG) == CAN_FLAG_FOV1) || \ - ((FLAG) == CAN_FLAG_WKU) || ((FLAG) == CAN_FLAG_SLAK)) -/** - * @} - */ - - -/** @defgroup CAN_interrupts - * @{ - */ -#define CAN_IT_TME ((uint32_t)0x00000001) /*!< Transmit mailbox empty Interrupt*/ - -/* Receive Interrupts */ -#define CAN_IT_FMP0 ((uint32_t)0x00000002) /*!< FIFO 0 message pending Interrupt*/ -#define CAN_IT_FF0 ((uint32_t)0x00000004) /*!< FIFO 0 full Interrupt*/ -#define CAN_IT_FOV0 ((uint32_t)0x00000008) /*!< FIFO 0 overrun Interrupt*/ -#define CAN_IT_FMP1 ((uint32_t)0x00000010) /*!< FIFO 1 message pending Interrupt*/ -#define CAN_IT_FF1 ((uint32_t)0x00000020) /*!< FIFO 1 full Interrupt*/ -#define CAN_IT_FOV1 ((uint32_t)0x00000040) /*!< FIFO 1 overrun Interrupt*/ - -/* Operating Mode Interrupts */ -#define CAN_IT_WKU ((uint32_t)0x00010000) /*!< Wake-up Interrupt*/ -#define CAN_IT_SLK ((uint32_t)0x00020000) /*!< Sleep acknowledge Interrupt*/ - -/* Error Interrupts */ -#define CAN_IT_EWG ((uint32_t)0x00000100) /*!< Error warning Interrupt*/ -#define CAN_IT_EPV ((uint32_t)0x00000200) /*!< Error passive Interrupt*/ -#define CAN_IT_BOF ((uint32_t)0x00000400) /*!< Bus-off Interrupt*/ -#define CAN_IT_LEC ((uint32_t)0x00000800) /*!< Last error code Interrupt*/ -#define CAN_IT_ERR ((uint32_t)0x00008000) /*!< Error Interrupt*/ - -/* Flags named as Interrupts : kept only for FW compatibility */ -#define CAN_IT_RQCP0 CAN_IT_TME -#define CAN_IT_RQCP1 CAN_IT_TME -#define CAN_IT_RQCP2 CAN_IT_TME - - -#define IS_CAN_IT(IT) (((IT) == CAN_IT_TME) || ((IT) == CAN_IT_FMP0) ||\ - ((IT) == CAN_IT_FF0) || ((IT) == CAN_IT_FOV0) ||\ - ((IT) == CAN_IT_FMP1) || ((IT) == CAN_IT_FF1) ||\ - ((IT) == CAN_IT_FOV1) || ((IT) == CAN_IT_EWG) ||\ - ((IT) == CAN_IT_EPV) || ((IT) == CAN_IT_BOF) ||\ - ((IT) == CAN_IT_LEC) || ((IT) == CAN_IT_ERR) ||\ - ((IT) == CAN_IT_WKU) || ((IT) == CAN_IT_SLK)) - -#define IS_CAN_CLEAR_IT(IT) (((IT) == CAN_IT_TME) || ((IT) == CAN_IT_FF0) ||\ - ((IT) == CAN_IT_FOV0)|| ((IT) == CAN_IT_FF1) ||\ - ((IT) == CAN_IT_FOV1)|| ((IT) == CAN_IT_EWG) ||\ - ((IT) == CAN_IT_EPV) || ((IT) == CAN_IT_BOF) ||\ - ((IT) == CAN_IT_LEC) || ((IT) == CAN_IT_ERR) ||\ - ((IT) == CAN_IT_WKU) || ((IT) == CAN_IT_SLK)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the CAN configuration to the default reset state *****/ -void CAN_DeInit(CAN_TypeDef* CANx); - -/* Initialization and Configuration functions *********************************/ -uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct); -void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct); -void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct); -void CAN_SlaveStartBank(uint8_t CAN_BankNumber); -void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState); -void CAN_TTComModeCmd(CAN_TypeDef* CANx, FunctionalState NewState); - -/* CAN Frames Transmission functions ******************************************/ -uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage); -uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox); -void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox); - -/* CAN Frames Reception functions *********************************************/ -void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage); -void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber); -uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber); - -/* Operation modes functions **************************************************/ -uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode); -uint8_t CAN_Sleep(CAN_TypeDef* CANx); -uint8_t CAN_WakeUp(CAN_TypeDef* CANx); - -/* CAN Bus Error management functions *****************************************/ -uint8_t CAN_GetLastErrorCode(CAN_TypeDef* CANx); -uint8_t CAN_GetReceiveErrorCounter(CAN_TypeDef* CANx); -uint8_t CAN_GetLSBTransmitErrorCounter(CAN_TypeDef* CANx); - -/* Interrupts and flags management functions **********************************/ -void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState); -FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG); -void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG); -ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT); -void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_CAN_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_crc.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_crc.h deleted file mode 100644 index 56b2bb26a..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_crc.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_crc.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the CRC firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_CRC_H -#define __STM32F4xx_CRC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup CRC - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup CRC_Exported_Constants - * @{ - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -void CRC_ResetDR(void); -uint32_t CRC_CalcCRC(uint32_t Data); -uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength); -uint32_t CRC_GetCRC(void); -void CRC_SetIDRegister(uint8_t IDValue); -uint8_t CRC_GetIDRegister(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_CRC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_cryp.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_cryp.h deleted file mode 100644 index ebcc8fbab..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_cryp.h +++ /dev/null @@ -1,338 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_cryp.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the Cryptographic - * processor(CRYP) firmware library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_CRYP_H -#define __STM32F4xx_CRYP_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup CRYP - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief CRYP Init structure definition - */ -typedef struct -{ - uint16_t CRYP_AlgoDir; /*!< Encrypt or Decrypt. This parameter can be a - value of @ref CRYP_Algorithm_Direction */ - uint16_t CRYP_AlgoMode; /*!< TDES-ECB, TDES-CBC, DES-ECB, DES-CBC, AES-ECB, - AES-CBC, AES-CTR, AES-Key. This parameter can be - a value of @ref CRYP_Algorithm_Mode */ - uint16_t CRYP_DataType; /*!< 32-bit data, 16-bit data, bit data or bit-string. - This parameter can be a value of @ref CRYP_Data_Type */ - uint16_t CRYP_KeySize; /*!< Used only in AES mode only : 128, 192 or 256 bit - key length. This parameter can be a value of - @ref CRYP_Key_Size_for_AES_only */ -}CRYP_InitTypeDef; - -/** - * @brief CRYP Key(s) structure definition - */ -typedef struct -{ - uint32_t CRYP_Key0Left; /*!< Key 0 Left */ - uint32_t CRYP_Key0Right; /*!< Key 0 Right */ - uint32_t CRYP_Key1Left; /*!< Key 1 left */ - uint32_t CRYP_Key1Right; /*!< Key 1 Right */ - uint32_t CRYP_Key2Left; /*!< Key 2 left */ - uint32_t CRYP_Key2Right; /*!< Key 2 Right */ - uint32_t CRYP_Key3Left; /*!< Key 3 left */ - uint32_t CRYP_Key3Right; /*!< Key 3 Right */ -}CRYP_KeyInitTypeDef; -/** - * @brief CRYP Initialization Vectors (IV) structure definition - */ -typedef struct -{ - uint32_t CRYP_IV0Left; /*!< Init Vector 0 Left */ - uint32_t CRYP_IV0Right; /*!< Init Vector 0 Right */ - uint32_t CRYP_IV1Left; /*!< Init Vector 1 left */ - uint32_t CRYP_IV1Right; /*!< Init Vector 1 Right */ -}CRYP_IVInitTypeDef; - -/** - * @brief CRYP context swapping structure definition - */ -typedef struct -{ - /*!< Configuration */ - uint32_t CR_bits9to2; - /*!< KEY */ - uint32_t CRYP_IV0LR; - uint32_t CRYP_IV0RR; - uint32_t CRYP_IV1LR; - uint32_t CRYP_IV1RR; - /*!< IV */ - uint32_t CRYP_K0LR; - uint32_t CRYP_K0RR; - uint32_t CRYP_K1LR; - uint32_t CRYP_K1RR; - uint32_t CRYP_K2LR; - uint32_t CRYP_K2RR; - uint32_t CRYP_K3LR; - uint32_t CRYP_K3RR; -}CRYP_Context; - - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup CRYP_Exported_Constants - * @{ - */ - -/** @defgroup CRYP_Algorithm_Direction - * @{ - */ -#define CRYP_AlgoDir_Encrypt ((uint16_t)0x0000) -#define CRYP_AlgoDir_Decrypt ((uint16_t)0x0004) -#define IS_CRYP_ALGODIR(ALGODIR) (((ALGODIR) == CRYP_AlgoDir_Encrypt) || \ - ((ALGODIR) == CRYP_AlgoDir_Decrypt)) - -/** - * @} - */ - -/** @defgroup CRYP_Algorithm_Mode - * @{ - */ - -/*!< TDES Modes */ -#define CRYP_AlgoMode_TDES_ECB ((uint16_t)0x0000) -#define CRYP_AlgoMode_TDES_CBC ((uint16_t)0x0008) - -/*!< DES Modes */ -#define CRYP_AlgoMode_DES_ECB ((uint16_t)0x0010) -#define CRYP_AlgoMode_DES_CBC ((uint16_t)0x0018) - -/*!< AES Modes */ -#define CRYP_AlgoMode_AES_ECB ((uint16_t)0x0020) -#define CRYP_AlgoMode_AES_CBC ((uint16_t)0x0028) -#define CRYP_AlgoMode_AES_CTR ((uint16_t)0x0030) -#define CRYP_AlgoMode_AES_Key ((uint16_t)0x0038) - -#define IS_CRYP_ALGOMODE(ALGOMODE) (((ALGOMODE) == CRYP_AlgoMode_TDES_ECB) || \ - ((ALGOMODE) == CRYP_AlgoMode_TDES_CBC)|| \ - ((ALGOMODE) == CRYP_AlgoMode_DES_ECB)|| \ - ((ALGOMODE) == CRYP_AlgoMode_DES_CBC) || \ - ((ALGOMODE) == CRYP_AlgoMode_AES_ECB) || \ - ((ALGOMODE) == CRYP_AlgoMode_AES_CBC) || \ - ((ALGOMODE) == CRYP_AlgoMode_AES_CTR) || \ - ((ALGOMODE) == CRYP_AlgoMode_AES_Key)) -/** - * @} - */ - -/** @defgroup CRYP_Data_Type - * @{ - */ -#define CRYP_DataType_32b ((uint16_t)0x0000) -#define CRYP_DataType_16b ((uint16_t)0x0040) -#define CRYP_DataType_8b ((uint16_t)0x0080) -#define CRYP_DataType_1b ((uint16_t)0x00C0) -#define IS_CRYP_DATATYPE(DATATYPE) (((DATATYPE) == CRYP_DataType_32b) || \ - ((DATATYPE) == CRYP_DataType_16b)|| \ - ((DATATYPE) == CRYP_DataType_8b)|| \ - ((DATATYPE) == CRYP_DataType_1b)) -/** - * @} - */ - -/** @defgroup CRYP_Key_Size_for_AES_only - * @{ - */ -#define CRYP_KeySize_128b ((uint16_t)0x0000) -#define CRYP_KeySize_192b ((uint16_t)0x0100) -#define CRYP_KeySize_256b ((uint16_t)0x0200) -#define IS_CRYP_KEYSIZE(KEYSIZE) (((KEYSIZE) == CRYP_KeySize_128b)|| \ - ((KEYSIZE) == CRYP_KeySize_192b)|| \ - ((KEYSIZE) == CRYP_KeySize_256b)) -/** - * @} - */ - -/** @defgroup CRYP_flags_definition - * @{ - */ -#define CRYP_FLAG_BUSY ((uint8_t)0x10) /*!< The CRYP core is currently - processing a block of data - or a key preparation (for - AES decryption). */ -#define CRYP_FLAG_IFEM ((uint8_t)0x01) /*!< Input Fifo Empty */ -#define CRYP_FLAG_IFNF ((uint8_t)0x02) /*!< Input Fifo is Not Full */ -#define CRYP_FLAG_INRIS ((uint8_t)0x22) /*!< Raw interrupt pending */ -#define CRYP_FLAG_OFNE ((uint8_t)0x04) /*!< Input Fifo service raw - interrupt status */ -#define CRYP_FLAG_OFFU ((uint8_t)0x08) /*!< Output Fifo is Full */ -#define CRYP_FLAG_OUTRIS ((uint8_t)0x21) /*!< Output Fifo service raw - interrupt status */ - -#define IS_CRYP_GET_FLAG(FLAG) (((FLAG) == CRYP_FLAG_IFEM) || \ - ((FLAG) == CRYP_FLAG_IFNF) || \ - ((FLAG) == CRYP_FLAG_OFNE) || \ - ((FLAG) == CRYP_FLAG_OFFU) || \ - ((FLAG) == CRYP_FLAG_BUSY) || \ - ((FLAG) == CRYP_FLAG_OUTRIS)|| \ - ((FLAG) == CRYP_FLAG_INRIS)) -/** - * @} - */ - -/** @defgroup CRYP_interrupts_definition - * @{ - */ -#define CRYP_IT_INI ((uint8_t)0x01) /*!< IN Fifo Interrupt */ -#define CRYP_IT_OUTI ((uint8_t)0x02) /*!< OUT Fifo Interrupt */ -#define IS_CRYP_CONFIG_IT(IT) ((((IT) & (uint8_t)0xFC) == 0x00) && ((IT) != 0x00)) -#define IS_CRYP_GET_IT(IT) (((IT) == CRYP_IT_INI) || ((IT) == CRYP_IT_OUTI)) - -/** - * @} - */ - -/** @defgroup CRYP_Encryption_Decryption_modes_definition - * @{ - */ -#define MODE_ENCRYPT ((uint8_t)0x01) -#define MODE_DECRYPT ((uint8_t)0x00) - -/** - * @} - */ - -/** @defgroup CRYP_DMA_transfer_requests - * @{ - */ -#define CRYP_DMAReq_DataIN ((uint8_t)0x01) -#define CRYP_DMAReq_DataOUT ((uint8_t)0x02) -#define IS_CRYP_DMAREQ(DMAREQ) ((((DMAREQ) & (uint8_t)0xFC) == 0x00) && ((DMAREQ) != 0x00)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the CRYP configuration to the default reset state ****/ -void CRYP_DeInit(void); - -/* CRYP Initialization and Configuration functions ****************************/ -void CRYP_Init(CRYP_InitTypeDef* CRYP_InitStruct); -void CRYP_StructInit(CRYP_InitTypeDef* CRYP_InitStruct); -void CRYP_KeyInit(CRYP_KeyInitTypeDef* CRYP_KeyInitStruct); -void CRYP_KeyStructInit(CRYP_KeyInitTypeDef* CRYP_KeyInitStruct); -void CRYP_IVInit(CRYP_IVInitTypeDef* CRYP_IVInitStruct); -void CRYP_IVStructInit(CRYP_IVInitTypeDef* CRYP_IVInitStruct); -void CRYP_Cmd(FunctionalState NewState); - -/* CRYP Data processing functions *********************************************/ -void CRYP_DataIn(uint32_t Data); -uint32_t CRYP_DataOut(void); -void CRYP_FIFOFlush(void); - -/* CRYP Context swapping functions ********************************************/ -ErrorStatus CRYP_SaveContext(CRYP_Context* CRYP_ContextSave, - CRYP_KeyInitTypeDef* CRYP_KeyInitStruct); -void CRYP_RestoreContext(CRYP_Context* CRYP_ContextRestore); - -/* CRYP's DMA interface function **********************************************/ -void CRYP_DMACmd(uint8_t CRYP_DMAReq, FunctionalState NewState); - -/* Interrupts and flags management functions **********************************/ -void CRYP_ITConfig(uint8_t CRYP_IT, FunctionalState NewState); -ITStatus CRYP_GetITStatus(uint8_t CRYP_IT); -FlagStatus CRYP_GetFlagStatus(uint8_t CRYP_FLAG); - -/* High Level AES functions **************************************************/ -ErrorStatus CRYP_AES_ECB(uint8_t Mode, - uint8_t *Key, uint16_t Keysize, - uint8_t *Input, uint32_t Ilength, - uint8_t *Output); - -ErrorStatus CRYP_AES_CBC(uint8_t Mode, - uint8_t InitVectors[16], - uint8_t *Key, uint16_t Keysize, - uint8_t *Input, uint32_t Ilength, - uint8_t *Output); - -ErrorStatus CRYP_AES_CTR(uint8_t Mode, - uint8_t InitVectors[16], - uint8_t *Key, uint16_t Keysize, - uint8_t *Input, uint32_t Ilength, - uint8_t *Output); - -/* High Level TDES functions **************************************************/ -ErrorStatus CRYP_TDES_ECB(uint8_t Mode, - uint8_t Key[24], - uint8_t *Input, uint32_t Ilength, - uint8_t *Output); - -ErrorStatus CRYP_TDES_CBC(uint8_t Mode, - uint8_t Key[24], - uint8_t InitVectors[8], - uint8_t *Input, uint32_t Ilength, - uint8_t *Output); - -/* High Level DES functions **************************************************/ -ErrorStatus CRYP_DES_ECB(uint8_t Mode, - uint8_t Key[8], - uint8_t *Input, uint32_t Ilength, - uint8_t *Output); - -ErrorStatus CRYP_DES_CBC(uint8_t Mode, - uint8_t Key[8], - uint8_t InitVectors[8], - uint8_t *Input,uint32_t Ilength, - uint8_t *Output); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F4xx_CRYP_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dac.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dac.h deleted file mode 100644 index 0f706e905..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dac.h +++ /dev/null @@ -1,298 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_dac.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the DAC firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_DAC_H -#define __STM32F4xx_DAC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup DAC - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief DAC Init structure definition - */ - -typedef struct -{ - uint32_t DAC_Trigger; /*!< Specifies the external trigger for the selected DAC channel. - This parameter can be a value of @ref DAC_trigger_selection */ - - uint32_t DAC_WaveGeneration; /*!< Specifies whether DAC channel noise waves or triangle waves - are generated, or whether no wave is generated. - This parameter can be a value of @ref DAC_wave_generation */ - - uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*!< Specifies the LFSR mask for noise wave generation or - the maximum amplitude triangle generation for the DAC channel. - This parameter can be a value of @ref DAC_lfsrunmask_triangleamplitude */ - - uint32_t DAC_OutputBuffer; /*!< Specifies whether the DAC channel output buffer is enabled or disabled. - This parameter can be a value of @ref DAC_output_buffer */ -}DAC_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup DAC_Exported_Constants - * @{ - */ - -/** @defgroup DAC_trigger_selection - * @{ - */ - -#define DAC_Trigger_None ((uint32_t)0x00000000) /*!< Conversion is automatic once the DAC1_DHRxxxx register - has been loaded, and not by external trigger */ -#define DAC_Trigger_T2_TRGO ((uint32_t)0x00000024) /*!< TIM2 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_T4_TRGO ((uint32_t)0x0000002C) /*!< TIM4 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_T5_TRGO ((uint32_t)0x0000001C) /*!< TIM5 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_T6_TRGO ((uint32_t)0x00000004) /*!< TIM6 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_T7_TRGO ((uint32_t)0x00000014) /*!< TIM7 TRGO selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_T8_TRGO ((uint32_t)0x0000000C) /*!< TIM8 TRGO selected as external conversion trigger for DAC channel */ - -#define DAC_Trigger_Ext_IT9 ((uint32_t)0x00000034) /*!< EXTI Line9 event selected as external conversion trigger for DAC channel */ -#define DAC_Trigger_Software ((uint32_t)0x0000003C) /*!< Conversion started by software trigger for DAC channel */ - -#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_Trigger_None) || \ - ((TRIGGER) == DAC_Trigger_T6_TRGO) || \ - ((TRIGGER) == DAC_Trigger_T8_TRGO) || \ - ((TRIGGER) == DAC_Trigger_T7_TRGO) || \ - ((TRIGGER) == DAC_Trigger_T5_TRGO) || \ - ((TRIGGER) == DAC_Trigger_T2_TRGO) || \ - ((TRIGGER) == DAC_Trigger_T4_TRGO) || \ - ((TRIGGER) == DAC_Trigger_Ext_IT9) || \ - ((TRIGGER) == DAC_Trigger_Software)) - -/** - * @} - */ - -/** @defgroup DAC_wave_generation - * @{ - */ - -#define DAC_WaveGeneration_None ((uint32_t)0x00000000) -#define DAC_WaveGeneration_Noise ((uint32_t)0x00000040) -#define DAC_WaveGeneration_Triangle ((uint32_t)0x00000080) -#define IS_DAC_GENERATE_WAVE(WAVE) (((WAVE) == DAC_WaveGeneration_None) || \ - ((WAVE) == DAC_WaveGeneration_Noise) || \ - ((WAVE) == DAC_WaveGeneration_Triangle)) -/** - * @} - */ - -/** @defgroup DAC_lfsrunmask_triangleamplitude - * @{ - */ - -#define DAC_LFSRUnmask_Bit0 ((uint32_t)0x00000000) /*!< Unmask DAC channel LFSR bit0 for noise wave generation */ -#define DAC_LFSRUnmask_Bits1_0 ((uint32_t)0x00000100) /*!< Unmask DAC channel LFSR bit[1:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits2_0 ((uint32_t)0x00000200) /*!< Unmask DAC channel LFSR bit[2:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits3_0 ((uint32_t)0x00000300) /*!< Unmask DAC channel LFSR bit[3:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits4_0 ((uint32_t)0x00000400) /*!< Unmask DAC channel LFSR bit[4:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits5_0 ((uint32_t)0x00000500) /*!< Unmask DAC channel LFSR bit[5:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits6_0 ((uint32_t)0x00000600) /*!< Unmask DAC channel LFSR bit[6:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits7_0 ((uint32_t)0x00000700) /*!< Unmask DAC channel LFSR bit[7:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits8_0 ((uint32_t)0x00000800) /*!< Unmask DAC channel LFSR bit[8:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits9_0 ((uint32_t)0x00000900) /*!< Unmask DAC channel LFSR bit[9:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits10_0 ((uint32_t)0x00000A00) /*!< Unmask DAC channel LFSR bit[10:0] for noise wave generation */ -#define DAC_LFSRUnmask_Bits11_0 ((uint32_t)0x00000B00) /*!< Unmask DAC channel LFSR bit[11:0] for noise wave generation */ -#define DAC_TriangleAmplitude_1 ((uint32_t)0x00000000) /*!< Select max triangle amplitude of 1 */ -#define DAC_TriangleAmplitude_3 ((uint32_t)0x00000100) /*!< Select max triangle amplitude of 3 */ -#define DAC_TriangleAmplitude_7 ((uint32_t)0x00000200) /*!< Select max triangle amplitude of 7 */ -#define DAC_TriangleAmplitude_15 ((uint32_t)0x00000300) /*!< Select max triangle amplitude of 15 */ -#define DAC_TriangleAmplitude_31 ((uint32_t)0x00000400) /*!< Select max triangle amplitude of 31 */ -#define DAC_TriangleAmplitude_63 ((uint32_t)0x00000500) /*!< Select max triangle amplitude of 63 */ -#define DAC_TriangleAmplitude_127 ((uint32_t)0x00000600) /*!< Select max triangle amplitude of 127 */ -#define DAC_TriangleAmplitude_255 ((uint32_t)0x00000700) /*!< Select max triangle amplitude of 255 */ -#define DAC_TriangleAmplitude_511 ((uint32_t)0x00000800) /*!< Select max triangle amplitude of 511 */ -#define DAC_TriangleAmplitude_1023 ((uint32_t)0x00000900) /*!< Select max triangle amplitude of 1023 */ -#define DAC_TriangleAmplitude_2047 ((uint32_t)0x00000A00) /*!< Select max triangle amplitude of 2047 */ -#define DAC_TriangleAmplitude_4095 ((uint32_t)0x00000B00) /*!< Select max triangle amplitude of 4095 */ - -#define IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(VALUE) (((VALUE) == DAC_LFSRUnmask_Bit0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits1_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits2_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits3_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits4_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits5_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits6_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits7_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits8_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits9_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits10_0) || \ - ((VALUE) == DAC_LFSRUnmask_Bits11_0) || \ - ((VALUE) == DAC_TriangleAmplitude_1) || \ - ((VALUE) == DAC_TriangleAmplitude_3) || \ - ((VALUE) == DAC_TriangleAmplitude_7) || \ - ((VALUE) == DAC_TriangleAmplitude_15) || \ - ((VALUE) == DAC_TriangleAmplitude_31) || \ - ((VALUE) == DAC_TriangleAmplitude_63) || \ - ((VALUE) == DAC_TriangleAmplitude_127) || \ - ((VALUE) == DAC_TriangleAmplitude_255) || \ - ((VALUE) == DAC_TriangleAmplitude_511) || \ - ((VALUE) == DAC_TriangleAmplitude_1023) || \ - ((VALUE) == DAC_TriangleAmplitude_2047) || \ - ((VALUE) == DAC_TriangleAmplitude_4095)) -/** - * @} - */ - -/** @defgroup DAC_output_buffer - * @{ - */ - -#define DAC_OutputBuffer_Enable ((uint32_t)0x00000000) -#define DAC_OutputBuffer_Disable ((uint32_t)0x00000002) -#define IS_DAC_OUTPUT_BUFFER_STATE(STATE) (((STATE) == DAC_OutputBuffer_Enable) || \ - ((STATE) == DAC_OutputBuffer_Disable)) -/** - * @} - */ - -/** @defgroup DAC_Channel_selection - * @{ - */ - -#define DAC_Channel_1 ((uint32_t)0x00000000) -#define DAC_Channel_2 ((uint32_t)0x00000010) -#define IS_DAC_CHANNEL(CHANNEL) (((CHANNEL) == DAC_Channel_1) || \ - ((CHANNEL) == DAC_Channel_2)) -/** - * @} - */ - -/** @defgroup DAC_data_alignement - * @{ - */ - -#define DAC_Align_12b_R ((uint32_t)0x00000000) -#define DAC_Align_12b_L ((uint32_t)0x00000004) -#define DAC_Align_8b_R ((uint32_t)0x00000008) -#define IS_DAC_ALIGN(ALIGN) (((ALIGN) == DAC_Align_12b_R) || \ - ((ALIGN) == DAC_Align_12b_L) || \ - ((ALIGN) == DAC_Align_8b_R)) -/** - * @} - */ - -/** @defgroup DAC_wave_generation - * @{ - */ - -#define DAC_Wave_Noise ((uint32_t)0x00000040) -#define DAC_Wave_Triangle ((uint32_t)0x00000080) -#define IS_DAC_WAVE(WAVE) (((WAVE) == DAC_Wave_Noise) || \ - ((WAVE) == DAC_Wave_Triangle)) -/** - * @} - */ - -/** @defgroup DAC_data - * @{ - */ - -#define IS_DAC_DATA(DATA) ((DATA) <= 0xFFF0) -/** - * @} - */ - -/** @defgroup DAC_interrupts_definition - * @{ - */ -#define DAC_IT_DMAUDR ((uint32_t)0x00002000) -#define IS_DAC_IT(IT) (((IT) == DAC_IT_DMAUDR)) - -/** - * @} - */ - -/** @defgroup DAC_flags_definition - * @{ - */ - -#define DAC_FLAG_DMAUDR ((uint32_t)0x00002000) -#define IS_DAC_FLAG(FLAG) (((FLAG) == DAC_FLAG_DMAUDR)) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the DAC configuration to the default reset state *****/ -void DAC_DeInit(void); - -/* DAC channels configuration: trigger, output buffer, data format functions */ -void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct); -void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct); -void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState); -void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState); -void DAC_DualSoftwareTriggerCmd(FunctionalState NewState); -void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState); -void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data); -void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data); -void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1); -uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel); - -/* DMA management functions ***************************************************/ -void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState); - -/* Interrupts and flags management functions **********************************/ -void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState); -FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG); -void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG); -ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT); -void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F4xx_DAC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dbgmcu.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dbgmcu.h deleted file mode 100644 index 4a64d8850..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dbgmcu.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_dbgmcu.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the DBGMCU firmware library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_DBGMCU_H -#define __STM32F4xx_DBGMCU_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup DBGMCU - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup DBGMCU_Exported_Constants - * @{ - */ -#define DBGMCU_SLEEP ((uint32_t)0x00000001) -#define DBGMCU_STOP ((uint32_t)0x00000002) -#define DBGMCU_STANDBY ((uint32_t)0x00000004) -#define IS_DBGMCU_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFF8) == 0x00) && ((PERIPH) != 0x00)) - -#define DBGMCU_TIM2_STOP ((uint32_t)0x00000001) -#define DBGMCU_TIM3_STOP ((uint32_t)0x00000002) -#define DBGMCU_TIM4_STOP ((uint32_t)0x00000004) -#define DBGMCU_TIM5_STOP ((uint32_t)0x00000008) -#define DBGMCU_TIM6_STOP ((uint32_t)0x00000010) -#define DBGMCU_TIM7_STOP ((uint32_t)0x00000020) -#define DBGMCU_TIM12_STOP ((uint32_t)0x00000040) -#define DBGMCU_TIM13_STOP ((uint32_t)0x00000080) -#define DBGMCU_TIM14_STOP ((uint32_t)0x00000100) -#define DBGMCU_RTC_STOP ((uint32_t)0x00000400) -#define DBGMCU_WWDG_STOP ((uint32_t)0x00000800) -#define DBGMCU_IWDG_STOP ((uint32_t)0x00001000) -#define DBGMCU_I2C1_SMBUS_TIMEOUT ((uint32_t)0x00200000) -#define DBGMCU_I2C2_SMBUS_TIMEOUT ((uint32_t)0x00400000) -#define DBGMCU_I2C3_SMBUS_TIMEOUT ((uint32_t)0x00800000) -#define DBGMCU_CAN1_STOP ((uint32_t)0x02000000) -#define DBGMCU_CAN2_STOP ((uint32_t)0x04000000) -#define IS_DBGMCU_APB1PERIPH(PERIPH) ((((PERIPH) & 0xF91FE200) == 0x00) && ((PERIPH) != 0x00)) - -#define DBGMCU_TIM1_STOP ((uint32_t)0x00000001) -#define DBGMCU_TIM8_STOP ((uint32_t)0x00000002) -#define DBGMCU_TIM9_STOP ((uint32_t)0x00010000) -#define DBGMCU_TIM10_STOP ((uint32_t)0x00020000) -#define DBGMCU_TIM11_STOP ((uint32_t)0x00040000) -#define IS_DBGMCU_APB2PERIPH(PERIPH) ((((PERIPH) & 0xFFF8FFFC) == 0x00) && ((PERIPH) != 0x00)) -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ -uint32_t DBGMCU_GetREVID(void); -uint32_t DBGMCU_GetDEVID(void); -void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState); -void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState); -void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_DBGMCU_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dcmi.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dcmi.h deleted file mode 100644 index d78e66751..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dcmi.h +++ /dev/null @@ -1,306 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_dcmi.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the DCMI firmware library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_DCMI_H -#define __STM32F4xx_DCMI_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup DCMI - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/** - * @brief DCMI Init structure definition - */ -typedef struct -{ - uint16_t DCMI_CaptureMode; /*!< Specifies the Capture Mode: Continuous or Snapshot. - This parameter can be a value of @ref DCMI_Capture_Mode */ - - uint16_t DCMI_SynchroMode; /*!< Specifies the Synchronization Mode: Hardware or Embedded. - This parameter can be a value of @ref DCMI_Synchronization_Mode */ - - uint16_t DCMI_PCKPolarity; /*!< Specifies the Pixel clock polarity: Falling or Rising. - This parameter can be a value of @ref DCMI_PIXCK_Polarity */ - - uint16_t DCMI_VSPolarity; /*!< Specifies the Vertical synchronization polarity: High or Low. - This parameter can be a value of @ref DCMI_VSYNC_Polarity */ - - uint16_t DCMI_HSPolarity; /*!< Specifies the Horizontal synchronization polarity: High or Low. - This parameter can be a value of @ref DCMI_HSYNC_Polarity */ - - uint16_t DCMI_CaptureRate; /*!< Specifies the frequency of frame capture: All, 1/2 or 1/4. - This parameter can be a value of @ref DCMI_Capture_Rate */ - - uint16_t DCMI_ExtendedDataMode; /*!< Specifies the data width: 8-bit, 10-bit, 12-bit or 14-bit. - This parameter can be a value of @ref DCMI_Extended_Data_Mode */ -} DCMI_InitTypeDef; - -/** - * @brief DCMI CROP Init structure definition - */ -typedef struct -{ - uint16_t DCMI_VerticalStartLine; /*!< Specifies the Vertical start line count from which the image capture - will start. This parameter can be a value between 0x00 and 0x1FFF */ - - uint16_t DCMI_HorizontalOffsetCount; /*!< Specifies the number of pixel clocks to count before starting a capture. - This parameter can be a value between 0x00 and 0x3FFF */ - - uint16_t DCMI_VerticalLineCount; /*!< Specifies the number of lines to be captured from the starting point. - This parameter can be a value between 0x00 and 0x3FFF */ - - uint16_t DCMI_CaptureCount; /*!< Specifies the number of pixel clocks to be captured from the starting - point on the same line. - This parameter can be a value between 0x00 and 0x3FFF */ -} DCMI_CROPInitTypeDef; - -/** - * @brief DCMI Embedded Synchronisation CODE Init structure definition - */ -typedef struct -{ - uint8_t DCMI_FrameStartCode; /*!< Specifies the code of the frame start delimiter. */ - uint8_t DCMI_LineStartCode; /*!< Specifies the code of the line start delimiter. */ - uint8_t DCMI_LineEndCode; /*!< Specifies the code of the line end delimiter. */ - uint8_t DCMI_FrameEndCode; /*!< Specifies the code of the frame end delimiter. */ -} DCMI_CodesInitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup DCMI_Exported_Constants - * @{ - */ - -/** @defgroup DCMI_Capture_Mode - * @{ - */ -#define DCMI_CaptureMode_Continuous ((uint16_t)0x0000) /*!< The received data are transferred continuously - into the destination memory through the DMA */ -#define DCMI_CaptureMode_SnapShot ((uint16_t)0x0002) /*!< Once activated, the interface waits for the start of - frame and then transfers a single frame through the DMA */ -#define IS_DCMI_CAPTURE_MODE(MODE)(((MODE) == DCMI_CaptureMode_Continuous) || \ - ((MODE) == DCMI_CaptureMode_SnapShot)) -/** - * @} - */ - - -/** @defgroup DCMI_Synchronization_Mode - * @{ - */ -#define DCMI_SynchroMode_Hardware ((uint16_t)0x0000) /*!< Hardware synchronization data capture (frame/line start/stop) - is synchronized with the HSYNC/VSYNC signals */ -#define DCMI_SynchroMode_Embedded ((uint16_t)0x0010) /*!< Embedded synchronization data capture is synchronized with - synchronization codes embedded in the data flow */ -#define IS_DCMI_SYNCHRO(MODE)(((MODE) == DCMI_SynchroMode_Hardware) || \ - ((MODE) == DCMI_SynchroMode_Embedded)) -/** - * @} - */ - - -/** @defgroup DCMI_PIXCK_Polarity - * @{ - */ -#define DCMI_PCKPolarity_Falling ((uint16_t)0x0000) /*!< Pixel clock active on Falling edge */ -#define DCMI_PCKPolarity_Rising ((uint16_t)0x0020) /*!< Pixel clock active on Rising edge */ -#define IS_DCMI_PCKPOLARITY(POLARITY)(((POLARITY) == DCMI_PCKPolarity_Falling) || \ - ((POLARITY) == DCMI_PCKPolarity_Rising)) -/** - * @} - */ - - -/** @defgroup DCMI_VSYNC_Polarity - * @{ - */ -#define DCMI_VSPolarity_Low ((uint16_t)0x0000) /*!< Vertical synchronization active Low */ -#define DCMI_VSPolarity_High ((uint16_t)0x0080) /*!< Vertical synchronization active High */ -#define IS_DCMI_VSPOLARITY(POLARITY)(((POLARITY) == DCMI_VSPolarity_Low) || \ - ((POLARITY) == DCMI_VSPolarity_High)) -/** - * @} - */ - - -/** @defgroup DCMI_HSYNC_Polarity - * @{ - */ -#define DCMI_HSPolarity_Low ((uint16_t)0x0000) /*!< Horizontal synchronization active Low */ -#define DCMI_HSPolarity_High ((uint16_t)0x0040) /*!< Horizontal synchronization active High */ -#define IS_DCMI_HSPOLARITY(POLARITY)(((POLARITY) == DCMI_HSPolarity_Low) || \ - ((POLARITY) == DCMI_HSPolarity_High)) -/** - * @} - */ - - -/** @defgroup DCMI_Capture_Rate - * @{ - */ -#define DCMI_CaptureRate_All_Frame ((uint16_t)0x0000) /*!< All frames are captured */ -#define DCMI_CaptureRate_1of2_Frame ((uint16_t)0x0100) /*!< Every alternate frame captured */ -#define DCMI_CaptureRate_1of4_Frame ((uint16_t)0x0200) /*!< One frame in 4 frames captured */ -#define IS_DCMI_CAPTURE_RATE(RATE) (((RATE) == DCMI_CaptureRate_All_Frame) || \ - ((RATE) == DCMI_CaptureRate_1of2_Frame) ||\ - ((RATE) == DCMI_CaptureRate_1of4_Frame)) -/** - * @} - */ - - -/** @defgroup DCMI_Extended_Data_Mode - * @{ - */ -#define DCMI_ExtendedDataMode_8b ((uint16_t)0x0000) /*!< Interface captures 8-bit data on every pixel clock */ -#define DCMI_ExtendedDataMode_10b ((uint16_t)0x0400) /*!< Interface captures 10-bit data on every pixel clock */ -#define DCMI_ExtendedDataMode_12b ((uint16_t)0x0800) /*!< Interface captures 12-bit data on every pixel clock */ -#define DCMI_ExtendedDataMode_14b ((uint16_t)0x0C00) /*!< Interface captures 14-bit data on every pixel clock */ -#define IS_DCMI_EXTENDED_DATA(DATA)(((DATA) == DCMI_ExtendedDataMode_8b) || \ - ((DATA) == DCMI_ExtendedDataMode_10b) ||\ - ((DATA) == DCMI_ExtendedDataMode_12b) ||\ - ((DATA) == DCMI_ExtendedDataMode_14b)) -/** - * @} - */ - - -/** @defgroup DCMI_interrupt_sources - * @{ - */ -#define DCMI_IT_FRAME ((uint16_t)0x0001) -#define DCMI_IT_OVF ((uint16_t)0x0002) -#define DCMI_IT_ERR ((uint16_t)0x0004) -#define DCMI_IT_VSYNC ((uint16_t)0x0008) -#define DCMI_IT_LINE ((uint16_t)0x0010) -#define IS_DCMI_CONFIG_IT(IT) ((((IT) & (uint16_t)0xFFE0) == 0x0000) && ((IT) != 0x0000)) -#define IS_DCMI_GET_IT(IT) (((IT) == DCMI_IT_FRAME) || \ - ((IT) == DCMI_IT_OVF) || \ - ((IT) == DCMI_IT_ERR) || \ - ((IT) == DCMI_IT_VSYNC) || \ - ((IT) == DCMI_IT_LINE)) -/** - * @} - */ - - -/** @defgroup DCMI_Flags - * @{ - */ -/** - * @brief DCMI SR register - */ -#define DCMI_FLAG_HSYNC ((uint16_t)0x2001) -#define DCMI_FLAG_VSYNC ((uint16_t)0x2002) -#define DCMI_FLAG_FNE ((uint16_t)0x2004) -/** - * @brief DCMI RISR register - */ -#define DCMI_FLAG_FRAMERI ((uint16_t)0x0001) -#define DCMI_FLAG_OVFRI ((uint16_t)0x0002) -#define DCMI_FLAG_ERRRI ((uint16_t)0x0004) -#define DCMI_FLAG_VSYNCRI ((uint16_t)0x0008) -#define DCMI_FLAG_LINERI ((uint16_t)0x0010) -/** - * @brief DCMI MISR register - */ -#define DCMI_FLAG_FRAMEMI ((uint16_t)0x1001) -#define DCMI_FLAG_OVFMI ((uint16_t)0x1002) -#define DCMI_FLAG_ERRMI ((uint16_t)0x1004) -#define DCMI_FLAG_VSYNCMI ((uint16_t)0x1008) -#define DCMI_FLAG_LINEMI ((uint16_t)0x1010) -#define IS_DCMI_GET_FLAG(FLAG) (((FLAG) == DCMI_FLAG_HSYNC) || \ - ((FLAG) == DCMI_FLAG_VSYNC) || \ - ((FLAG) == DCMI_FLAG_FNE) || \ - ((FLAG) == DCMI_FLAG_FRAMERI) || \ - ((FLAG) == DCMI_FLAG_OVFRI) || \ - ((FLAG) == DCMI_FLAG_ERRRI) || \ - ((FLAG) == DCMI_FLAG_VSYNCRI) || \ - ((FLAG) == DCMI_FLAG_LINERI) || \ - ((FLAG) == DCMI_FLAG_FRAMEMI) || \ - ((FLAG) == DCMI_FLAG_OVFMI) || \ - ((FLAG) == DCMI_FLAG_ERRMI) || \ - ((FLAG) == DCMI_FLAG_VSYNCMI) || \ - ((FLAG) == DCMI_FLAG_LINEMI)) - -#define IS_DCMI_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFFE0) == 0x0000) && ((FLAG) != 0x0000)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the DCMI configuration to the default reset state ****/ -void DCMI_DeInit(void); - -/* Initialization and Configuration functions *********************************/ -void DCMI_Init(DCMI_InitTypeDef* DCMI_InitStruct); -void DCMI_StructInit(DCMI_InitTypeDef* DCMI_InitStruct); -void DCMI_CROPConfig(DCMI_CROPInitTypeDef* DCMI_CROPInitStruct); -void DCMI_CROPCmd(FunctionalState NewState); -void DCMI_SetEmbeddedSynchroCodes(DCMI_CodesInitTypeDef* DCMI_CodesInitStruct); -void DCMI_JPEGCmd(FunctionalState NewState); - -/* Image capture functions ****************************************************/ -void DCMI_Cmd(FunctionalState NewState); -void DCMI_CaptureCmd(FunctionalState NewState); -uint32_t DCMI_ReadData(void); - -/* Interrupts and flags management functions **********************************/ -void DCMI_ITConfig(uint16_t DCMI_IT, FunctionalState NewState); -FlagStatus DCMI_GetFlagStatus(uint16_t DCMI_FLAG); -void DCMI_ClearFlag(uint16_t DCMI_FLAG); -ITStatus DCMI_GetITStatus(uint16_t DCMI_IT); -void DCMI_ClearITPendingBit(uint16_t DCMI_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F4xx_DCMI_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma.h deleted file mode 100644 index 9d5d68bfb..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma.h +++ /dev/null @@ -1,603 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_dma.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the DMA firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_DMA_H -#define __STM32F4xx_DMA_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup DMA - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief DMA Init structure definition - */ - -typedef struct -{ - uint32_t DMA_Channel; /*!< Specifies the channel used for the specified stream. - This parameter can be a value of @ref DMA_channel */ - - uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Streamx. */ - - uint32_t DMA_Memory0BaseAddr; /*!< Specifies the memory 0 base address for DMAy Streamx. - This memory is the default memory used when double buffer mode is - not enabled. */ - - uint32_t DMA_DIR; /*!< Specifies if the data will be transferred from memory to peripheral, - from memory to memory or from peripheral to memory. - This parameter can be a value of @ref DMA_data_transfer_direction */ - - uint32_t DMA_BufferSize; /*!< Specifies the buffer size, in data unit, of the specified Stream. - The data unit is equal to the configuration set in DMA_PeripheralDataSize - or DMA_MemoryDataSize members depending in the transfer direction. */ - - uint32_t DMA_PeripheralInc; /*!< Specifies whether the Peripheral address register should be incremented or not. - This parameter can be a value of @ref DMA_peripheral_incremented_mode */ - - uint32_t DMA_MemoryInc; /*!< Specifies whether the memory address register should be incremented or not. - This parameter can be a value of @ref DMA_memory_incremented_mode */ - - uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width. - This parameter can be a value of @ref DMA_peripheral_data_size */ - - uint32_t DMA_MemoryDataSize; /*!< Specifies the Memory data width. - This parameter can be a value of @ref DMA_memory_data_size */ - - uint32_t DMA_Mode; /*!< Specifies the operation mode of the DMAy Streamx. - This parameter can be a value of @ref DMA_circular_normal_mode - @note The circular buffer mode cannot be used if the memory-to-memory - data transfer is configured on the selected Stream */ - - uint32_t DMA_Priority; /*!< Specifies the software priority for the DMAy Streamx. - This parameter can be a value of @ref DMA_priority_level */ - - uint32_t DMA_FIFOMode; /*!< Specifies if the FIFO mode or Direct mode will be used for the specified Stream. - This parameter can be a value of @ref DMA_fifo_direct_mode - @note The Direct mode (FIFO mode disabled) cannot be used if the - memory-to-memory data transfer is configured on the selected Stream */ - - uint32_t DMA_FIFOThreshold; /*!< Specifies the FIFO threshold level. - This parameter can be a value of @ref DMA_fifo_threshold_level */ - - uint32_t DMA_MemoryBurst; /*!< Specifies the Burst transfer configuration for the memory transfers. - It specifies the amount of data to be transferred in a single non interruptable - transaction. This parameter can be a value of @ref DMA_memory_burst - @note The burst mode is possible only if the address Increment mode is enabled. */ - - uint32_t DMA_PeripheralBurst; /*!< Specifies the Burst transfer configuration for the peripheral transfers. - It specifies the amount of data to be transferred in a single non interruptable - transaction. This parameter can be a value of @ref DMA_peripheral_burst - @note The burst mode is possible only if the address Increment mode is enabled. */ -}DMA_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup DMA_Exported_Constants - * @{ - */ - -#define IS_DMA_ALL_PERIPH(PERIPH) (((PERIPH) == DMA1_Stream0) || \ - ((PERIPH) == DMA1_Stream1) || \ - ((PERIPH) == DMA1_Stream2) || \ - ((PERIPH) == DMA1_Stream3) || \ - ((PERIPH) == DMA1_Stream4) || \ - ((PERIPH) == DMA1_Stream5) || \ - ((PERIPH) == DMA1_Stream6) || \ - ((PERIPH) == DMA1_Stream7) || \ - ((PERIPH) == DMA2_Stream0) || \ - ((PERIPH) == DMA2_Stream1) || \ - ((PERIPH) == DMA2_Stream2) || \ - ((PERIPH) == DMA2_Stream3) || \ - ((PERIPH) == DMA2_Stream4) || \ - ((PERIPH) == DMA2_Stream5) || \ - ((PERIPH) == DMA2_Stream6) || \ - ((PERIPH) == DMA2_Stream7)) - -#define IS_DMA_ALL_CONTROLLER(CONTROLLER) (((CONTROLLER) == DMA1) || \ - ((CONTROLLER) == DMA2)) - -/** @defgroup DMA_channel - * @{ - */ -#define DMA_Channel_0 ((uint32_t)0x00000000) -#define DMA_Channel_1 ((uint32_t)0x02000000) -#define DMA_Channel_2 ((uint32_t)0x04000000) -#define DMA_Channel_3 ((uint32_t)0x06000000) -#define DMA_Channel_4 ((uint32_t)0x08000000) -#define DMA_Channel_5 ((uint32_t)0x0A000000) -#define DMA_Channel_6 ((uint32_t)0x0C000000) -#define DMA_Channel_7 ((uint32_t)0x0E000000) - -#define IS_DMA_CHANNEL(CHANNEL) (((CHANNEL) == DMA_Channel_0) || \ - ((CHANNEL) == DMA_Channel_1) || \ - ((CHANNEL) == DMA_Channel_2) || \ - ((CHANNEL) == DMA_Channel_3) || \ - ((CHANNEL) == DMA_Channel_4) || \ - ((CHANNEL) == DMA_Channel_5) || \ - ((CHANNEL) == DMA_Channel_6) || \ - ((CHANNEL) == DMA_Channel_7)) -/** - * @} - */ - - -/** @defgroup DMA_data_transfer_direction - * @{ - */ -#define DMA_DIR_PeripheralToMemory ((uint32_t)0x00000000) -#define DMA_DIR_MemoryToPeripheral ((uint32_t)0x00000040) -#define DMA_DIR_MemoryToMemory ((uint32_t)0x00000080) - -#define IS_DMA_DIRECTION(DIRECTION) (((DIRECTION) == DMA_DIR_PeripheralToMemory ) || \ - ((DIRECTION) == DMA_DIR_MemoryToPeripheral) || \ - ((DIRECTION) == DMA_DIR_MemoryToMemory)) -/** - * @} - */ - - -/** @defgroup DMA_data_buffer_size - * @{ - */ -#define IS_DMA_BUFFER_SIZE(SIZE) (((SIZE) >= 0x1) && ((SIZE) < 0x10000)) -/** - * @} - */ - - -/** @defgroup DMA_peripheral_incremented_mode - * @{ - */ -#define DMA_PeripheralInc_Enable ((uint32_t)0x00000200) -#define DMA_PeripheralInc_Disable ((uint32_t)0x00000000) - -#define IS_DMA_PERIPHERAL_INC_STATE(STATE) (((STATE) == DMA_PeripheralInc_Enable) || \ - ((STATE) == DMA_PeripheralInc_Disable)) -/** - * @} - */ - - -/** @defgroup DMA_memory_incremented_mode - * @{ - */ -#define DMA_MemoryInc_Enable ((uint32_t)0x00000400) -#define DMA_MemoryInc_Disable ((uint32_t)0x00000000) - -#define IS_DMA_MEMORY_INC_STATE(STATE) (((STATE) == DMA_MemoryInc_Enable) || \ - ((STATE) == DMA_MemoryInc_Disable)) -/** - * @} - */ - - -/** @defgroup DMA_peripheral_data_size - * @{ - */ -#define DMA_PeripheralDataSize_Byte ((uint32_t)0x00000000) -#define DMA_PeripheralDataSize_HalfWord ((uint32_t)0x00000800) -#define DMA_PeripheralDataSize_Word ((uint32_t)0x00001000) - -#define IS_DMA_PERIPHERAL_DATA_SIZE(SIZE) (((SIZE) == DMA_PeripheralDataSize_Byte) || \ - ((SIZE) == DMA_PeripheralDataSize_HalfWord) || \ - ((SIZE) == DMA_PeripheralDataSize_Word)) -/** - * @} - */ - - -/** @defgroup DMA_memory_data_size - * @{ - */ -#define DMA_MemoryDataSize_Byte ((uint32_t)0x00000000) -#define DMA_MemoryDataSize_HalfWord ((uint32_t)0x00002000) -#define DMA_MemoryDataSize_Word ((uint32_t)0x00004000) - -#define IS_DMA_MEMORY_DATA_SIZE(SIZE) (((SIZE) == DMA_MemoryDataSize_Byte) || \ - ((SIZE) == DMA_MemoryDataSize_HalfWord) || \ - ((SIZE) == DMA_MemoryDataSize_Word )) -/** - * @} - */ - - -/** @defgroup DMA_circular_normal_mode - * @{ - */ -#define DMA_Mode_Normal ((uint32_t)0x00000000) -#define DMA_Mode_Circular ((uint32_t)0x00000100) - -#define IS_DMA_MODE(MODE) (((MODE) == DMA_Mode_Normal ) || \ - ((MODE) == DMA_Mode_Circular)) -/** - * @} - */ - - -/** @defgroup DMA_priority_level - * @{ - */ -#define DMA_Priority_Low ((uint32_t)0x00000000) -#define DMA_Priority_Medium ((uint32_t)0x00010000) -#define DMA_Priority_High ((uint32_t)0x00020000) -#define DMA_Priority_VeryHigh ((uint32_t)0x00030000) - -#define IS_DMA_PRIORITY(PRIORITY) (((PRIORITY) == DMA_Priority_Low ) || \ - ((PRIORITY) == DMA_Priority_Medium) || \ - ((PRIORITY) == DMA_Priority_High) || \ - ((PRIORITY) == DMA_Priority_VeryHigh)) -/** - * @} - */ - - -/** @defgroup DMA_fifo_direct_mode - * @{ - */ -#define DMA_FIFOMode_Disable ((uint32_t)0x00000000) -#define DMA_FIFOMode_Enable ((uint32_t)0x00000004) - -#define IS_DMA_FIFO_MODE_STATE(STATE) (((STATE) == DMA_FIFOMode_Disable ) || \ - ((STATE) == DMA_FIFOMode_Enable)) -/** - * @} - */ - - -/** @defgroup DMA_fifo_threshold_level - * @{ - */ -#define DMA_FIFOThreshold_1QuarterFull ((uint32_t)0x00000000) -#define DMA_FIFOThreshold_HalfFull ((uint32_t)0x00000001) -#define DMA_FIFOThreshold_3QuartersFull ((uint32_t)0x00000002) -#define DMA_FIFOThreshold_Full ((uint32_t)0x00000003) - -#define IS_DMA_FIFO_THRESHOLD(THRESHOLD) (((THRESHOLD) == DMA_FIFOThreshold_1QuarterFull ) || \ - ((THRESHOLD) == DMA_FIFOThreshold_HalfFull) || \ - ((THRESHOLD) == DMA_FIFOThreshold_3QuartersFull) || \ - ((THRESHOLD) == DMA_FIFOThreshold_Full)) -/** - * @} - */ - - -/** @defgroup DMA_memory_burst - * @{ - */ -#define DMA_MemoryBurst_Single ((uint32_t)0x00000000) -#define DMA_MemoryBurst_INC4 ((uint32_t)0x00800000) -#define DMA_MemoryBurst_INC8 ((uint32_t)0x01000000) -#define DMA_MemoryBurst_INC16 ((uint32_t)0x01800000) - -#define IS_DMA_MEMORY_BURST(BURST) (((BURST) == DMA_MemoryBurst_Single) || \ - ((BURST) == DMA_MemoryBurst_INC4) || \ - ((BURST) == DMA_MemoryBurst_INC8) || \ - ((BURST) == DMA_MemoryBurst_INC16)) -/** - * @} - */ - - -/** @defgroup DMA_peripheral_burst - * @{ - */ -#define DMA_PeripheralBurst_Single ((uint32_t)0x00000000) -#define DMA_PeripheralBurst_INC4 ((uint32_t)0x00200000) -#define DMA_PeripheralBurst_INC8 ((uint32_t)0x00400000) -#define DMA_PeripheralBurst_INC16 ((uint32_t)0x00600000) - -#define IS_DMA_PERIPHERAL_BURST(BURST) (((BURST) == DMA_PeripheralBurst_Single) || \ - ((BURST) == DMA_PeripheralBurst_INC4) || \ - ((BURST) == DMA_PeripheralBurst_INC8) || \ - ((BURST) == DMA_PeripheralBurst_INC16)) -/** - * @} - */ - - -/** @defgroup DMA_fifo_status_level - * @{ - */ -#define DMA_FIFOStatus_Less1QuarterFull ((uint32_t)0x00000000 << 3) -#define DMA_FIFOStatus_1QuarterFull ((uint32_t)0x00000001 << 3) -#define DMA_FIFOStatus_HalfFull ((uint32_t)0x00000002 << 3) -#define DMA_FIFOStatus_3QuartersFull ((uint32_t)0x00000003 << 3) -#define DMA_FIFOStatus_Empty ((uint32_t)0x00000004 << 3) -#define DMA_FIFOStatus_Full ((uint32_t)0x00000005 << 3) - -#define IS_DMA_FIFO_STATUS(STATUS) (((STATUS) == DMA_FIFOStatus_Less1QuarterFull ) || \ - ((STATUS) == DMA_FIFOStatus_HalfFull) || \ - ((STATUS) == DMA_FIFOStatus_1QuarterFull) || \ - ((STATUS) == DMA_FIFOStatus_3QuartersFull) || \ - ((STATUS) == DMA_FIFOStatus_Full) || \ - ((STATUS) == DMA_FIFOStatus_Empty)) -/** - * @} - */ - -/** @defgroup DMA_flags_definition - * @{ - */ -#define DMA_FLAG_FEIF0 ((uint32_t)0x10800001) -#define DMA_FLAG_DMEIF0 ((uint32_t)0x10800004) -#define DMA_FLAG_TEIF0 ((uint32_t)0x10000008) -#define DMA_FLAG_HTIF0 ((uint32_t)0x10000010) -#define DMA_FLAG_TCIF0 ((uint32_t)0x10000020) -#define DMA_FLAG_FEIF1 ((uint32_t)0x10000040) -#define DMA_FLAG_DMEIF1 ((uint32_t)0x10000100) -#define DMA_FLAG_TEIF1 ((uint32_t)0x10000200) -#define DMA_FLAG_HTIF1 ((uint32_t)0x10000400) -#define DMA_FLAG_TCIF1 ((uint32_t)0x10000800) -#define DMA_FLAG_FEIF2 ((uint32_t)0x10010000) -#define DMA_FLAG_DMEIF2 ((uint32_t)0x10040000) -#define DMA_FLAG_TEIF2 ((uint32_t)0x10080000) -#define DMA_FLAG_HTIF2 ((uint32_t)0x10100000) -#define DMA_FLAG_TCIF2 ((uint32_t)0x10200000) -#define DMA_FLAG_FEIF3 ((uint32_t)0x10400000) -#define DMA_FLAG_DMEIF3 ((uint32_t)0x11000000) -#define DMA_FLAG_TEIF3 ((uint32_t)0x12000000) -#define DMA_FLAG_HTIF3 ((uint32_t)0x14000000) -#define DMA_FLAG_TCIF3 ((uint32_t)0x18000000) -#define DMA_FLAG_FEIF4 ((uint32_t)0x20000001) -#define DMA_FLAG_DMEIF4 ((uint32_t)0x20000004) -#define DMA_FLAG_TEIF4 ((uint32_t)0x20000008) -#define DMA_FLAG_HTIF4 ((uint32_t)0x20000010) -#define DMA_FLAG_TCIF4 ((uint32_t)0x20000020) -#define DMA_FLAG_FEIF5 ((uint32_t)0x20000040) -#define DMA_FLAG_DMEIF5 ((uint32_t)0x20000100) -#define DMA_FLAG_TEIF5 ((uint32_t)0x20000200) -#define DMA_FLAG_HTIF5 ((uint32_t)0x20000400) -#define DMA_FLAG_TCIF5 ((uint32_t)0x20000800) -#define DMA_FLAG_FEIF6 ((uint32_t)0x20010000) -#define DMA_FLAG_DMEIF6 ((uint32_t)0x20040000) -#define DMA_FLAG_TEIF6 ((uint32_t)0x20080000) -#define DMA_FLAG_HTIF6 ((uint32_t)0x20100000) -#define DMA_FLAG_TCIF6 ((uint32_t)0x20200000) -#define DMA_FLAG_FEIF7 ((uint32_t)0x20400000) -#define DMA_FLAG_DMEIF7 ((uint32_t)0x21000000) -#define DMA_FLAG_TEIF7 ((uint32_t)0x22000000) -#define DMA_FLAG_HTIF7 ((uint32_t)0x24000000) -#define DMA_FLAG_TCIF7 ((uint32_t)0x28000000) - -#define IS_DMA_CLEAR_FLAG(FLAG) ((((FLAG) & 0x30000000) != 0x30000000) && (((FLAG) & 0x30000000) != 0) && \ - (((FLAG) & 0xC082F082) == 0x00) && ((FLAG) != 0x00)) - -#define IS_DMA_GET_FLAG(FLAG) (((FLAG) == DMA_FLAG_TCIF0) || ((FLAG) == DMA_FLAG_HTIF0) || \ - ((FLAG) == DMA_FLAG_TEIF0) || ((FLAG) == DMA_FLAG_DMEIF0) || \ - ((FLAG) == DMA_FLAG_FEIF0) || ((FLAG) == DMA_FLAG_TCIF1) || \ - ((FLAG) == DMA_FLAG_HTIF1) || ((FLAG) == DMA_FLAG_TEIF1) || \ - ((FLAG) == DMA_FLAG_DMEIF1) || ((FLAG) == DMA_FLAG_FEIF1) || \ - ((FLAG) == DMA_FLAG_TCIF2) || ((FLAG) == DMA_FLAG_HTIF2) || \ - ((FLAG) == DMA_FLAG_TEIF2) || ((FLAG) == DMA_FLAG_DMEIF2) || \ - ((FLAG) == DMA_FLAG_FEIF2) || ((FLAG) == DMA_FLAG_TCIF3) || \ - ((FLAG) == DMA_FLAG_HTIF3) || ((FLAG) == DMA_FLAG_TEIF3) || \ - ((FLAG) == DMA_FLAG_DMEIF3) || ((FLAG) == DMA_FLAG_FEIF3) || \ - ((FLAG) == DMA_FLAG_TCIF4) || ((FLAG) == DMA_FLAG_HTIF4) || \ - ((FLAG) == DMA_FLAG_TEIF4) || ((FLAG) == DMA_FLAG_DMEIF4) || \ - ((FLAG) == DMA_FLAG_FEIF4) || ((FLAG) == DMA_FLAG_TCIF5) || \ - ((FLAG) == DMA_FLAG_HTIF5) || ((FLAG) == DMA_FLAG_TEIF5) || \ - ((FLAG) == DMA_FLAG_DMEIF5) || ((FLAG) == DMA_FLAG_FEIF5) || \ - ((FLAG) == DMA_FLAG_TCIF6) || ((FLAG) == DMA_FLAG_HTIF6) || \ - ((FLAG) == DMA_FLAG_TEIF6) || ((FLAG) == DMA_FLAG_DMEIF6) || \ - ((FLAG) == DMA_FLAG_FEIF6) || ((FLAG) == DMA_FLAG_TCIF7) || \ - ((FLAG) == DMA_FLAG_HTIF7) || ((FLAG) == DMA_FLAG_TEIF7) || \ - ((FLAG) == DMA_FLAG_DMEIF7) || ((FLAG) == DMA_FLAG_FEIF7)) -/** - * @} - */ - - -/** @defgroup DMA_interrupt_enable_definitions - * @{ - */ -#define DMA_IT_TC ((uint32_t)0x00000010) -#define DMA_IT_HT ((uint32_t)0x00000008) -#define DMA_IT_TE ((uint32_t)0x00000004) -#define DMA_IT_DME ((uint32_t)0x00000002) -#define DMA_IT_FE ((uint32_t)0x00000080) - -#define IS_DMA_CONFIG_IT(IT) ((((IT) & 0xFFFFFF61) == 0x00) && ((IT) != 0x00)) -/** - * @} - */ - - -/** @defgroup DMA_interrupts_definitions - * @{ - */ -#define DMA_IT_FEIF0 ((uint32_t)0x90000001) -#define DMA_IT_DMEIF0 ((uint32_t)0x10001004) -#define DMA_IT_TEIF0 ((uint32_t)0x10002008) -#define DMA_IT_HTIF0 ((uint32_t)0x10004010) -#define DMA_IT_TCIF0 ((uint32_t)0x10008020) -#define DMA_IT_FEIF1 ((uint32_t)0x90000040) -#define DMA_IT_DMEIF1 ((uint32_t)0x10001100) -#define DMA_IT_TEIF1 ((uint32_t)0x10002200) -#define DMA_IT_HTIF1 ((uint32_t)0x10004400) -#define DMA_IT_TCIF1 ((uint32_t)0x10008800) -#define DMA_IT_FEIF2 ((uint32_t)0x90010000) -#define DMA_IT_DMEIF2 ((uint32_t)0x10041000) -#define DMA_IT_TEIF2 ((uint32_t)0x10082000) -#define DMA_IT_HTIF2 ((uint32_t)0x10104000) -#define DMA_IT_TCIF2 ((uint32_t)0x10208000) -#define DMA_IT_FEIF3 ((uint32_t)0x90400000) -#define DMA_IT_DMEIF3 ((uint32_t)0x11001000) -#define DMA_IT_TEIF3 ((uint32_t)0x12002000) -#define DMA_IT_HTIF3 ((uint32_t)0x14004000) -#define DMA_IT_TCIF3 ((uint32_t)0x18008000) -#define DMA_IT_FEIF4 ((uint32_t)0xA0000001) -#define DMA_IT_DMEIF4 ((uint32_t)0x20001004) -#define DMA_IT_TEIF4 ((uint32_t)0x20002008) -#define DMA_IT_HTIF4 ((uint32_t)0x20004010) -#define DMA_IT_TCIF4 ((uint32_t)0x20008020) -#define DMA_IT_FEIF5 ((uint32_t)0xA0000040) -#define DMA_IT_DMEIF5 ((uint32_t)0x20001100) -#define DMA_IT_TEIF5 ((uint32_t)0x20002200) -#define DMA_IT_HTIF5 ((uint32_t)0x20004400) -#define DMA_IT_TCIF5 ((uint32_t)0x20008800) -#define DMA_IT_FEIF6 ((uint32_t)0xA0010000) -#define DMA_IT_DMEIF6 ((uint32_t)0x20041000) -#define DMA_IT_TEIF6 ((uint32_t)0x20082000) -#define DMA_IT_HTIF6 ((uint32_t)0x20104000) -#define DMA_IT_TCIF6 ((uint32_t)0x20208000) -#define DMA_IT_FEIF7 ((uint32_t)0xA0400000) -#define DMA_IT_DMEIF7 ((uint32_t)0x21001000) -#define DMA_IT_TEIF7 ((uint32_t)0x22002000) -#define DMA_IT_HTIF7 ((uint32_t)0x24004000) -#define DMA_IT_TCIF7 ((uint32_t)0x28008000) - -#define IS_DMA_CLEAR_IT(IT) ((((IT) & 0x30000000) != 0x30000000) && \ - (((IT) & 0x30000000) != 0) && ((IT) != 0x00) && \ - (((IT) & 0x40820082) == 0x00)) - -#define IS_DMA_GET_IT(IT) (((IT) == DMA_IT_TCIF0) || ((IT) == DMA_IT_HTIF0) || \ - ((IT) == DMA_IT_TEIF0) || ((IT) == DMA_IT_DMEIF0) || \ - ((IT) == DMA_IT_FEIF0) || ((IT) == DMA_IT_TCIF1) || \ - ((IT) == DMA_IT_HTIF1) || ((IT) == DMA_IT_TEIF1) || \ - ((IT) == DMA_IT_DMEIF1)|| ((IT) == DMA_IT_FEIF1) || \ - ((IT) == DMA_IT_TCIF2) || ((IT) == DMA_IT_HTIF2) || \ - ((IT) == DMA_IT_TEIF2) || ((IT) == DMA_IT_DMEIF2) || \ - ((IT) == DMA_IT_FEIF2) || ((IT) == DMA_IT_TCIF3) || \ - ((IT) == DMA_IT_HTIF3) || ((IT) == DMA_IT_TEIF3) || \ - ((IT) == DMA_IT_DMEIF3)|| ((IT) == DMA_IT_FEIF3) || \ - ((IT) == DMA_IT_TCIF4) || ((IT) == DMA_IT_HTIF4) || \ - ((IT) == DMA_IT_TEIF4) || ((IT) == DMA_IT_DMEIF4) || \ - ((IT) == DMA_IT_FEIF4) || ((IT) == DMA_IT_TCIF5) || \ - ((IT) == DMA_IT_HTIF5) || ((IT) == DMA_IT_TEIF5) || \ - ((IT) == DMA_IT_DMEIF5)|| ((IT) == DMA_IT_FEIF5) || \ - ((IT) == DMA_IT_TCIF6) || ((IT) == DMA_IT_HTIF6) || \ - ((IT) == DMA_IT_TEIF6) || ((IT) == DMA_IT_DMEIF6) || \ - ((IT) == DMA_IT_FEIF6) || ((IT) == DMA_IT_TCIF7) || \ - ((IT) == DMA_IT_HTIF7) || ((IT) == DMA_IT_TEIF7) || \ - ((IT) == DMA_IT_DMEIF7)|| ((IT) == DMA_IT_FEIF7)) -/** - * @} - */ - - -/** @defgroup DMA_peripheral_increment_offset - * @{ - */ -#define DMA_PINCOS_Psize ((uint32_t)0x00000000) -#define DMA_PINCOS_WordAligned ((uint32_t)0x00008000) - -#define IS_DMA_PINCOS_SIZE(SIZE) (((SIZE) == DMA_PINCOS_Psize) || \ - ((SIZE) == DMA_PINCOS_WordAligned)) -/** - * @} - */ - - -/** @defgroup DMA_flow_controller_definitions - * @{ - */ -#define DMA_FlowCtrl_Memory ((uint32_t)0x00000000) -#define DMA_FlowCtrl_Peripheral ((uint32_t)0x00000020) - -#define IS_DMA_FLOW_CTRL(CTRL) (((CTRL) == DMA_FlowCtrl_Memory) || \ - ((CTRL) == DMA_FlowCtrl_Peripheral)) -/** - * @} - */ - - -/** @defgroup DMA_memory_targets_definitions - * @{ - */ -#define DMA_Memory_0 ((uint32_t)0x00000000) -#define DMA_Memory_1 ((uint32_t)0x00080000) - -#define IS_DMA_CURRENT_MEM(MEM) (((MEM) == DMA_Memory_0) || ((MEM) == DMA_Memory_1)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the DMA configuration to the default reset state *****/ -void DMA_DeInit(DMA_Stream_TypeDef* DMAy_Streamx); - -/* Initialization and Configuration functions *********************************/ -void DMA_Init(DMA_Stream_TypeDef* DMAy_Streamx, DMA_InitTypeDef* DMA_InitStruct); -void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct); -void DMA_Cmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState); - -/* Optional Configuration functions *******************************************/ -void DMA_PeriphIncOffsetSizeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_Pincos); -void DMA_FlowControllerConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FlowCtrl); - -/* Data Counter functions *****************************************************/ -void DMA_SetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx, uint16_t Counter); -uint16_t DMA_GetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx); - -/* Double Buffer mode functions ***********************************************/ -void DMA_DoubleBufferModeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t Memory1BaseAddr, - uint32_t DMA_CurrentMemory); -void DMA_DoubleBufferModeCmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState); -void DMA_MemoryTargetConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t MemoryBaseAddr, - uint32_t DMA_MemoryTarget); -uint32_t DMA_GetCurrentMemoryTarget(DMA_Stream_TypeDef* DMAy_Streamx); - -/* Interrupts and flags management functions **********************************/ -FunctionalState DMA_GetCmdStatus(DMA_Stream_TypeDef* DMAy_Streamx); -uint32_t DMA_GetFIFOStatus(DMA_Stream_TypeDef* DMAy_Streamx); -FlagStatus DMA_GetFlagStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG); -void DMA_ClearFlag(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG); -void DMA_ITConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT, FunctionalState NewState); -ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT); -void DMA_ClearITPendingBit(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F4xx_DMA_H */ - -/** - * @} - */ - -/** - * @} - */ - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_exti.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_exti.h deleted file mode 100644 index e35a1c065..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_exti.h +++ /dev/null @@ -1,177 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_exti.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the EXTI firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_EXTI_H -#define __STM32F4xx_EXTI_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup EXTI - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief EXTI mode enumeration - */ - -typedef enum -{ - EXTI_Mode_Interrupt = 0x00, - EXTI_Mode_Event = 0x04 -}EXTIMode_TypeDef; - -#define IS_EXTI_MODE(MODE) (((MODE) == EXTI_Mode_Interrupt) || ((MODE) == EXTI_Mode_Event)) - -/** - * @brief EXTI Trigger enumeration - */ - -typedef enum -{ - EXTI_Trigger_Rising = 0x08, - EXTI_Trigger_Falling = 0x0C, - EXTI_Trigger_Rising_Falling = 0x10 -}EXTITrigger_TypeDef; - -#define IS_EXTI_TRIGGER(TRIGGER) (((TRIGGER) == EXTI_Trigger_Rising) || \ - ((TRIGGER) == EXTI_Trigger_Falling) || \ - ((TRIGGER) == EXTI_Trigger_Rising_Falling)) -/** - * @brief EXTI Init Structure definition - */ - -typedef struct -{ - uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled. - This parameter can be any combination value of @ref EXTI_Lines */ - - EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines. - This parameter can be a value of @ref EXTIMode_TypeDef */ - - EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines. - This parameter can be a value of @ref EXTITrigger_TypeDef */ - - FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines. - This parameter can be set either to ENABLE or DISABLE */ -}EXTI_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup EXTI_Exported_Constants - * @{ - */ - -/** @defgroup EXTI_Lines - * @{ - */ - -#define EXTI_Line0 ((uint32_t)0x00001) /*!< External interrupt line 0 */ -#define EXTI_Line1 ((uint32_t)0x00002) /*!< External interrupt line 1 */ -#define EXTI_Line2 ((uint32_t)0x00004) /*!< External interrupt line 2 */ -#define EXTI_Line3 ((uint32_t)0x00008) /*!< External interrupt line 3 */ -#define EXTI_Line4 ((uint32_t)0x00010) /*!< External interrupt line 4 */ -#define EXTI_Line5 ((uint32_t)0x00020) /*!< External interrupt line 5 */ -#define EXTI_Line6 ((uint32_t)0x00040) /*!< External interrupt line 6 */ -#define EXTI_Line7 ((uint32_t)0x00080) /*!< External interrupt line 7 */ -#define EXTI_Line8 ((uint32_t)0x00100) /*!< External interrupt line 8 */ -#define EXTI_Line9 ((uint32_t)0x00200) /*!< External interrupt line 9 */ -#define EXTI_Line10 ((uint32_t)0x00400) /*!< External interrupt line 10 */ -#define EXTI_Line11 ((uint32_t)0x00800) /*!< External interrupt line 11 */ -#define EXTI_Line12 ((uint32_t)0x01000) /*!< External interrupt line 12 */ -#define EXTI_Line13 ((uint32_t)0x02000) /*!< External interrupt line 13 */ -#define EXTI_Line14 ((uint32_t)0x04000) /*!< External interrupt line 14 */ -#define EXTI_Line15 ((uint32_t)0x08000) /*!< External interrupt line 15 */ -#define EXTI_Line16 ((uint32_t)0x10000) /*!< External interrupt line 16 Connected to the PVD Output */ -#define EXTI_Line17 ((uint32_t)0x20000) /*!< External interrupt line 17 Connected to the RTC Alarm event */ -#define EXTI_Line18 ((uint32_t)0x40000) /*!< External interrupt line 18 Connected to the USB OTG FS Wakeup from suspend event */ -#define EXTI_Line19 ((uint32_t)0x80000) /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */ -#define EXTI_Line20 ((uint32_t)0x00100000) /*!< External interrupt line 20 Connected to the USB OTG HS (configured in FS) Wakeup event */ -#define EXTI_Line21 ((uint32_t)0x00200000) /*!< External interrupt line 21 Connected to the RTC Tamper and Time Stamp events */ -#define EXTI_Line22 ((uint32_t)0x00400000) /*!< External interrupt line 22 Connected to the RTC Wakeup event */ - -#define IS_EXTI_LINE(LINE) ((((LINE) & (uint32_t)0xFF800000) == 0x00) && ((LINE) != (uint16_t)0x00)) - -#define IS_GET_EXTI_LINE(LINE) (((LINE) == EXTI_Line0) || ((LINE) == EXTI_Line1) || \ - ((LINE) == EXTI_Line2) || ((LINE) == EXTI_Line3) || \ - ((LINE) == EXTI_Line4) || ((LINE) == EXTI_Line5) || \ - ((LINE) == EXTI_Line6) || ((LINE) == EXTI_Line7) || \ - ((LINE) == EXTI_Line8) || ((LINE) == EXTI_Line9) || \ - ((LINE) == EXTI_Line10) || ((LINE) == EXTI_Line11) || \ - ((LINE) == EXTI_Line12) || ((LINE) == EXTI_Line13) || \ - ((LINE) == EXTI_Line14) || ((LINE) == EXTI_Line15) || \ - ((LINE) == EXTI_Line16) || ((LINE) == EXTI_Line17) || \ - ((LINE) == EXTI_Line18) || ((LINE) == EXTI_Line19) || \ - ((LINE) == EXTI_Line20) || ((LINE) == EXTI_Line21) ||\ - ((LINE) == EXTI_Line22)) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the EXTI configuration to the default reset state *****/ -void EXTI_DeInit(void); - -/* Initialization and Configuration functions *********************************/ -void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct); -void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct); -void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line); - -/* Interrupts and flags management functions **********************************/ -FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line); -void EXTI_ClearFlag(uint32_t EXTI_Line); -ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); -void EXTI_ClearITPendingBit(uint32_t EXTI_Line); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_EXTI_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_flash.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_flash.h deleted file mode 100644 index 63b9a17ed..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_flash.h +++ /dev/null @@ -1,334 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_flash.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the FLASH - * firmware library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_FLASH_H -#define __STM32F4xx_FLASH_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup FLASH - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/** - * @brief FLASH Status - */ -typedef enum -{ - FLASH_BUSY = 1, - FLASH_ERROR_PGS, - FLASH_ERROR_PGP, - FLASH_ERROR_PGA, - FLASH_ERROR_WRP, - FLASH_ERROR_PROGRAM, - FLASH_ERROR_OPERATION, - FLASH_COMPLETE -}FLASH_Status; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup FLASH_Exported_Constants - * @{ - */ - -/** @defgroup Flash_Latency - * @{ - */ -#define FLASH_Latency_0 ((uint8_t)0x0000) /*!< FLASH Zero Latency cycle */ -#define FLASH_Latency_1 ((uint8_t)0x0001) /*!< FLASH One Latency cycle */ -#define FLASH_Latency_2 ((uint8_t)0x0002) /*!< FLASH Two Latency cycles */ -#define FLASH_Latency_3 ((uint8_t)0x0003) /*!< FLASH Three Latency cycles */ -#define FLASH_Latency_4 ((uint8_t)0x0004) /*!< FLASH Four Latency cycles */ -#define FLASH_Latency_5 ((uint8_t)0x0005) /*!< FLASH Five Latency cycles */ -#define FLASH_Latency_6 ((uint8_t)0x0006) /*!< FLASH Six Latency cycles */ -#define FLASH_Latency_7 ((uint8_t)0x0007) /*!< FLASH Seven Latency cycles */ - -#define IS_FLASH_LATENCY(LATENCY) (((LATENCY) == FLASH_Latency_0) || \ - ((LATENCY) == FLASH_Latency_1) || \ - ((LATENCY) == FLASH_Latency_2) || \ - ((LATENCY) == FLASH_Latency_3) || \ - ((LATENCY) == FLASH_Latency_4) || \ - ((LATENCY) == FLASH_Latency_5) || \ - ((LATENCY) == FLASH_Latency_6) || \ - ((LATENCY) == FLASH_Latency_7)) -/** - * @} - */ - -/** @defgroup FLASH_Voltage_Range - * @{ - */ -#define VoltageRange_1 ((uint8_t)0x00) /*!< Device operating range: 1.8V to 2.1V */ -#define VoltageRange_2 ((uint8_t)0x01) /*!= 0x08000000) && ((ADDRESS) < 0x080FFFFF)) ||\ - (((ADDRESS) >= 0x1FFF7800) && ((ADDRESS) < 0x1FFF7A0F))) -/** - * @} - */ - -/** @defgroup Option_Bytes_Write_Protection - * @{ - */ -#define OB_WRP_Sector_0 ((uint32_t)0x00000001) /*!< Write protection of Sector0 */ -#define OB_WRP_Sector_1 ((uint32_t)0x00000002) /*!< Write protection of Sector1 */ -#define OB_WRP_Sector_2 ((uint32_t)0x00000004) /*!< Write protection of Sector2 */ -#define OB_WRP_Sector_3 ((uint32_t)0x00000008) /*!< Write protection of Sector3 */ -#define OB_WRP_Sector_4 ((uint32_t)0x00000010) /*!< Write protection of Sector4 */ -#define OB_WRP_Sector_5 ((uint32_t)0x00000020) /*!< Write protection of Sector5 */ -#define OB_WRP_Sector_6 ((uint32_t)0x00000040) /*!< Write protection of Sector6 */ -#define OB_WRP_Sector_7 ((uint32_t)0x00000080) /*!< Write protection of Sector7 */ -#define OB_WRP_Sector_8 ((uint32_t)0x00000100) /*!< Write protection of Sector8 */ -#define OB_WRP_Sector_9 ((uint32_t)0x00000200) /*!< Write protection of Sector9 */ -#define OB_WRP_Sector_10 ((uint32_t)0x00000400) /*!< Write protection of Sector10 */ -#define OB_WRP_Sector_11 ((uint32_t)0x00000800) /*!< Write protection of Sector11 */ -#define OB_WRP_Sector_All ((uint32_t)0x00000FFF) /*!< Write protection of all Sectors */ - -#define IS_OB_WRP(SECTOR)((((SECTOR) & (uint32_t)0xFFFFF000) == 0x00000000) && ((SECTOR) != 0x00000000)) -/** - * @} - */ - -/** @defgroup FLASH_Option_Bytes_Read_Protection - * @{ - */ -#define OB_RDP_Level_0 ((uint8_t)0xAA) -#define OB_RDP_Level_1 ((uint8_t)0x55) -/*#define OB_RDP_Level_2 ((uint8_t)0xCC)*/ /*!< Warning: When enabling read protection level 2 - it's no more possible to go back to level 1 or 0 */ -#define IS_OB_RDP(LEVEL) (((LEVEL) == OB_RDP_Level_0)||\ - ((LEVEL) == OB_RDP_Level_1))/*||\ - ((LEVEL) == OB_RDP_Level_2))*/ -/** - * @} - */ - -/** @defgroup FLASH_Option_Bytes_IWatchdog - * @{ - */ -#define OB_IWDG_SW ((uint8_t)0x20) /*!< Software IWDG selected */ -#define OB_IWDG_HW ((uint8_t)0x00) /*!< Hardware IWDG selected */ -#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW)) -/** - * @} - */ - -/** @defgroup FLASH_Option_Bytes_nRST_STOP - * @{ - */ -#define OB_STOP_NoRST ((uint8_t)0x40) /*!< No reset generated when entering in STOP */ -#define OB_STOP_RST ((uint8_t)0x00) /*!< Reset generated when entering in STOP */ -#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NoRST) || ((SOURCE) == OB_STOP_RST)) -/** - * @} - */ - - -/** @defgroup FLASH_Option_Bytes_nRST_STDBY - * @{ - */ -#define OB_STDBY_NoRST ((uint8_t)0x80) /*!< No reset generated when entering in STANDBY */ -#define OB_STDBY_RST ((uint8_t)0x00) /*!< Reset generated when entering in STANDBY */ -#define IS_OB_STDBY_SOURCE(SOURCE) (((SOURCE) == OB_STDBY_NoRST) || ((SOURCE) == OB_STDBY_RST)) -/** - * @} - */ - -/** @defgroup FLASH_BOR_Reset_Level - * @{ - */ -#define OB_BOR_LEVEL3 ((uint8_t)0x00) /*!< Supply voltage ranges from 2.70 to 3.60 V */ -#define OB_BOR_LEVEL2 ((uint8_t)0x04) /*!< Supply voltage ranges from 2.40 to 2.70 V */ -#define OB_BOR_LEVEL1 ((uint8_t)0x08) /*!< Supply voltage ranges from 2.10 to 2.40 V */ -#define OB_BOR_OFF ((uint8_t)0x0C) /*!< Supply voltage ranges from 1.62 to 2.10 V */ -#define IS_OB_BOR(LEVEL) (((LEVEL) == OB_BOR_LEVEL1) || ((LEVEL) == OB_BOR_LEVEL2) ||\ - ((LEVEL) == OB_BOR_LEVEL3) || ((LEVEL) == OB_BOR_OFF)) -/** - * @} - */ - -/** @defgroup FLASH_Interrupts - * @{ - */ -#define FLASH_IT_EOP ((uint32_t)0x01000000) /*!< End of FLASH Operation Interrupt source */ -#define FLASH_IT_ERR ((uint32_t)0x02000000) /*!< Error Interrupt source */ -#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0xFCFFFFFF) == 0x00000000) && ((IT) != 0x00000000)) -/** - * @} - */ - -/** @defgroup FLASH_Flags - * @{ - */ -#define FLASH_FLAG_EOP ((uint32_t)0x00000001) /*!< FLASH End of Operation flag */ -#define FLASH_FLAG_OPERR ((uint32_t)0x00000002) /*!< FLASH operation Error flag */ -#define FLASH_FLAG_WRPERR ((uint32_t)0x00000010) /*!< FLASH Write protected error flag */ -#define FLASH_FLAG_PGAERR ((uint32_t)0x00000020) /*!< FLASH Programming Alignment error flag */ -#define FLASH_FLAG_PGPERR ((uint32_t)0x00000040) /*!< FLASH Programming Parallelism error flag */ -#define FLASH_FLAG_PGSERR ((uint32_t)0x00000080) /*!< FLASH Programming Sequence error flag */ -#define FLASH_FLAG_BSY ((uint32_t)0x00010000) /*!< FLASH Busy flag */ -#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFF0C) == 0x00000000) && ((FLAG) != 0x00000000)) -#define IS_FLASH_GET_FLAG(FLAG) (((FLAG) == FLASH_FLAG_EOP) || ((FLAG) == FLASH_FLAG_OPERR) || \ - ((FLAG) == FLASH_FLAG_WRPERR) || ((FLAG) == FLASH_FLAG_PGAERR) || \ - ((FLAG) == FLASH_FLAG_PGPERR) || ((FLAG) == FLASH_FLAG_PGSERR) || \ - ((FLAG) == FLASH_FLAG_BSY)) -/** - * @} - */ - -/** @defgroup FLASH_Program_Parallelism - * @{ - */ -#define FLASH_PSIZE_BYTE ((uint32_t)0x00000000) -#define FLASH_PSIZE_HALF_WORD ((uint32_t)0x00000100) -#define FLASH_PSIZE_WORD ((uint32_t)0x00000200) -#define FLASH_PSIZE_DOUBLE_WORD ((uint32_t)0x00000300) -#define CR_PSIZE_MASK ((uint32_t)0xFFFFFCFF) -/** - * @} - */ - -/** @defgroup FLASH_Keys - * @{ - */ -#define RDP_KEY ((uint16_t)0x00A5) -#define FLASH_KEY1 ((uint32_t)0x45670123) -#define FLASH_KEY2 ((uint32_t)0xCDEF89AB) -#define FLASH_OPT_KEY1 ((uint32_t)0x08192A3B) -#define FLASH_OPT_KEY2 ((uint32_t)0x4C5D6E7F) -/** - * @} - */ - -/** - * @brief ACR register byte 0 (Bits[8:0]) base address - */ -#define ACR_BYTE0_ADDRESS ((uint32_t)0x40023C00) -/** - * @brief OPTCR register byte 3 (Bits[24:16]) base address - */ -#define OPTCR_BYTE0_ADDRESS ((uint32_t)0x40023C14) -#define OPTCR_BYTE1_ADDRESS ((uint32_t)0x40023C15) -#define OPTCR_BYTE2_ADDRESS ((uint32_t)0x40023C16) - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* FLASH Interface configuration functions ************************************/ -void FLASH_SetLatency(uint32_t FLASH_Latency); -void FLASH_PrefetchBufferCmd(FunctionalState NewState); -void FLASH_InstructionCacheCmd(FunctionalState NewState); -void FLASH_DataCacheCmd(FunctionalState NewState); -void FLASH_InstructionCacheReset(void); -void FLASH_DataCacheReset(void); - -/* FLASH Memory Programming functions *****************************************/ -void FLASH_Unlock(void); -void FLASH_Lock(void); -FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange); -FLASH_Status FLASH_EraseAllSectors(uint8_t VoltageRange); -FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data); -FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data); -FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data); -FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data); - -/* Option Bytes Programming functions *****************************************/ -void FLASH_OB_Unlock(void); -void FLASH_OB_Lock(void); -void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState); -void FLASH_OB_RDPConfig(uint8_t OB_RDP); -void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY); -void FLASH_OB_BORConfig(uint8_t OB_BOR); -FLASH_Status FLASH_OB_Launch(void); -uint8_t FLASH_OB_GetUser(void); -uint16_t FLASH_OB_GetWRP(void); -FlagStatus FLASH_OB_GetRDP(void); -uint8_t FLASH_OB_GetBOR(void); - -/* Interrupts and flags management functions **********************************/ -void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState); -FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG); -void FLASH_ClearFlag(uint32_t FLASH_FLAG); -FLASH_Status FLASH_GetStatus(void); -FLASH_Status FLASH_WaitForLastOperation(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_FLASH_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_fsmc.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_fsmc.h deleted file mode 100644 index 839f8dedd..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_fsmc.h +++ /dev/null @@ -1,669 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_fsmc.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the FSMC firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_FSMC_H -#define __STM32F4xx_FSMC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup FSMC - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief Timing parameters For NOR/SRAM Banks - */ -typedef struct -{ - uint32_t FSMC_AddressSetupTime; /*!< Defines the number of HCLK cycles to configure - the duration of the address setup time. - This parameter can be a value between 0 and 0xF. - @note This parameter is not used with synchronous NOR Flash memories. */ - - uint32_t FSMC_AddressHoldTime; /*!< Defines the number of HCLK cycles to configure - the duration of the address hold time. - This parameter can be a value between 0 and 0xF. - @note This parameter is not used with synchronous NOR Flash memories.*/ - - uint32_t FSMC_DataSetupTime; /*!< Defines the number of HCLK cycles to configure - the duration of the data setup time. - This parameter can be a value between 0 and 0xFF. - @note This parameter is used for SRAMs, ROMs and asynchronous multiplexed NOR Flash memories. */ - - uint32_t FSMC_BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure - the duration of the bus turnaround. - This parameter can be a value between 0 and 0xF. - @note This parameter is only used for multiplexed NOR Flash memories. */ - - uint32_t FSMC_CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of HCLK cycles. - This parameter can be a value between 1 and 0xF. - @note This parameter is not used for asynchronous NOR Flash, SRAM or ROM accesses. */ - - uint32_t FSMC_DataLatency; /*!< Defines the number of memory clock cycles to issue - to the memory before getting the first data. - The parameter value depends on the memory type as shown below: - - It must be set to 0 in case of a CRAM - - It is don't care in asynchronous NOR, SRAM or ROM accesses - - It may assume a value between 0 and 0xF in NOR Flash memories - with synchronous burst mode enable */ - - uint32_t FSMC_AccessMode; /*!< Specifies the asynchronous access mode. - This parameter can be a value of @ref FSMC_Access_Mode */ -}FSMC_NORSRAMTimingInitTypeDef; - -/** - * @brief FSMC NOR/SRAM Init structure definition - */ -typedef struct -{ - uint32_t FSMC_Bank; /*!< Specifies the NOR/SRAM memory bank that will be used. - This parameter can be a value of @ref FSMC_NORSRAM_Bank */ - - uint32_t FSMC_DataAddressMux; /*!< Specifies whether the address and data values are - multiplexed on the databus or not. - This parameter can be a value of @ref FSMC_Data_Address_Bus_Multiplexing */ - - uint32_t FSMC_MemoryType; /*!< Specifies the type of external memory attached to - the corresponding memory bank. - This parameter can be a value of @ref FSMC_Memory_Type */ - - uint32_t FSMC_MemoryDataWidth; /*!< Specifies the external memory device width. - This parameter can be a value of @ref FSMC_Data_Width */ - - uint32_t FSMC_BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory, - valid only with synchronous burst Flash memories. - This parameter can be a value of @ref FSMC_Burst_Access_Mode */ - - uint32_t FSMC_AsynchronousWait; /*!< Enables or disables wait signal during asynchronous transfers, - valid only with asynchronous Flash memories. - This parameter can be a value of @ref FSMC_AsynchronousWait */ - - uint32_t FSMC_WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing - the Flash memory in burst mode. - This parameter can be a value of @ref FSMC_Wait_Signal_Polarity */ - - uint32_t FSMC_WrapMode; /*!< Enables or disables the Wrapped burst access mode for Flash - memory, valid only when accessing Flash memories in burst mode. - This parameter can be a value of @ref FSMC_Wrap_Mode */ - - uint32_t FSMC_WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one - clock cycle before the wait state or during the wait state, - valid only when accessing memories in burst mode. - This parameter can be a value of @ref FSMC_Wait_Timing */ - - uint32_t FSMC_WriteOperation; /*!< Enables or disables the write operation in the selected bank by the FSMC. - This parameter can be a value of @ref FSMC_Write_Operation */ - - uint32_t FSMC_WaitSignal; /*!< Enables or disables the wait-state insertion via wait - signal, valid for Flash memory access in burst mode. - This parameter can be a value of @ref FSMC_Wait_Signal */ - - uint32_t FSMC_ExtendedMode; /*!< Enables or disables the extended mode. - This parameter can be a value of @ref FSMC_Extended_Mode */ - - uint32_t FSMC_WriteBurst; /*!< Enables or disables the write burst operation. - This parameter can be a value of @ref FSMC_Write_Burst */ - - FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct; /*!< Timing Parameters for write and read access if the ExtendedMode is not used*/ - - FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct; /*!< Timing Parameters for write access if the ExtendedMode is used*/ -}FSMC_NORSRAMInitTypeDef; - -/** - * @brief Timing parameters For FSMC NAND and PCCARD Banks - */ -typedef struct -{ - uint32_t FSMC_SetupTime; /*!< Defines the number of HCLK cycles to setup address before - the command assertion for NAND-Flash read or write access - to common/Attribute or I/O memory space (depending on - the memory space timing to be configured). - This parameter can be a value between 0 and 0xFF.*/ - - uint32_t FSMC_WaitSetupTime; /*!< Defines the minimum number of HCLK cycles to assert the - command for NAND-Flash read or write access to - common/Attribute or I/O memory space (depending on the - memory space timing to be configured). - This parameter can be a number between 0x00 and 0xFF */ - - uint32_t FSMC_HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address - (and data for write access) after the command deassertion - for NAND-Flash read or write access to common/Attribute - or I/O memory space (depending on the memory space timing - to be configured). - This parameter can be a number between 0x00 and 0xFF */ - - uint32_t FSMC_HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the - databus is kept in HiZ after the start of a NAND-Flash - write access to common/Attribute or I/O memory space (depending - on the memory space timing to be configured). - This parameter can be a number between 0x00 and 0xFF */ -}FSMC_NAND_PCCARDTimingInitTypeDef; - -/** - * @brief FSMC NAND Init structure definition - */ -typedef struct -{ - uint32_t FSMC_Bank; /*!< Specifies the NAND memory bank that will be used. - This parameter can be a value of @ref FSMC_NAND_Bank */ - - uint32_t FSMC_Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory Bank. - This parameter can be any value of @ref FSMC_Wait_feature */ - - uint32_t FSMC_MemoryDataWidth; /*!< Specifies the external memory device width. - This parameter can be any value of @ref FSMC_Data_Width */ - - uint32_t FSMC_ECC; /*!< Enables or disables the ECC computation. - This parameter can be any value of @ref FSMC_ECC */ - - uint32_t FSMC_ECCPageSize; /*!< Defines the page size for the extended ECC. - This parameter can be any value of @ref FSMC_ECC_Page_Size */ - - uint32_t FSMC_TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the - delay between CLE low and RE low. - This parameter can be a value between 0 and 0xFF. */ - - uint32_t FSMC_TARSetupTime; /*!< Defines the number of HCLK cycles to configure the - delay between ALE low and RE low. - This parameter can be a number between 0x0 and 0xFF */ - - FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_CommonSpaceTimingStruct; /*!< FSMC Common Space Timing */ - - FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_AttributeSpaceTimingStruct; /*!< FSMC Attribute Space Timing */ -}FSMC_NANDInitTypeDef; - -/** - * @brief FSMC PCCARD Init structure definition - */ - -typedef struct -{ - uint32_t FSMC_Waitfeature; /*!< Enables or disables the Wait feature for the Memory Bank. - This parameter can be any value of @ref FSMC_Wait_feature */ - - uint32_t FSMC_TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the - delay between CLE low and RE low. - This parameter can be a value between 0 and 0xFF. */ - - uint32_t FSMC_TARSetupTime; /*!< Defines the number of HCLK cycles to configure the - delay between ALE low and RE low. - This parameter can be a number between 0x0 and 0xFF */ - - - FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_CommonSpaceTimingStruct; /*!< FSMC Common Space Timing */ - - FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_AttributeSpaceTimingStruct; /*!< FSMC Attribute Space Timing */ - - FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_IOSpaceTimingStruct; /*!< FSMC IO Space Timing */ -}FSMC_PCCARDInitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup FSMC_Exported_Constants - * @{ - */ - -/** @defgroup FSMC_NORSRAM_Bank - * @{ - */ -#define FSMC_Bank1_NORSRAM1 ((uint32_t)0x00000000) -#define FSMC_Bank1_NORSRAM2 ((uint32_t)0x00000002) -#define FSMC_Bank1_NORSRAM3 ((uint32_t)0x00000004) -#define FSMC_Bank1_NORSRAM4 ((uint32_t)0x00000006) -/** - * @} - */ - -/** @defgroup FSMC_NAND_Bank - * @{ - */ -#define FSMC_Bank2_NAND ((uint32_t)0x00000010) -#define FSMC_Bank3_NAND ((uint32_t)0x00000100) -/** - * @} - */ - -/** @defgroup FSMC_PCCARD_Bank - * @{ - */ -#define FSMC_Bank4_PCCARD ((uint32_t)0x00001000) -/** - * @} - */ - -#define IS_FSMC_NORSRAM_BANK(BANK) (((BANK) == FSMC_Bank1_NORSRAM1) || \ - ((BANK) == FSMC_Bank1_NORSRAM2) || \ - ((BANK) == FSMC_Bank1_NORSRAM3) || \ - ((BANK) == FSMC_Bank1_NORSRAM4)) - -#define IS_FSMC_NAND_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \ - ((BANK) == FSMC_Bank3_NAND)) - -#define IS_FSMC_GETFLAG_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \ - ((BANK) == FSMC_Bank3_NAND) || \ - ((BANK) == FSMC_Bank4_PCCARD)) - -#define IS_FSMC_IT_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \ - ((BANK) == FSMC_Bank3_NAND) || \ - ((BANK) == FSMC_Bank4_PCCARD)) - -/** @defgroup FSMC_NOR_SRAM_Controller - * @{ - */ - -/** @defgroup FSMC_Data_Address_Bus_Multiplexing - * @{ - */ - -#define FSMC_DataAddressMux_Disable ((uint32_t)0x00000000) -#define FSMC_DataAddressMux_Enable ((uint32_t)0x00000002) -#define IS_FSMC_MUX(MUX) (((MUX) == FSMC_DataAddressMux_Disable) || \ - ((MUX) == FSMC_DataAddressMux_Enable)) -/** - * @} - */ - -/** @defgroup FSMC_Memory_Type - * @{ - */ - -#define FSMC_MemoryType_SRAM ((uint32_t)0x00000000) -#define FSMC_MemoryType_PSRAM ((uint32_t)0x00000004) -#define FSMC_MemoryType_NOR ((uint32_t)0x00000008) -#define IS_FSMC_MEMORY(MEMORY) (((MEMORY) == FSMC_MemoryType_SRAM) || \ - ((MEMORY) == FSMC_MemoryType_PSRAM)|| \ - ((MEMORY) == FSMC_MemoryType_NOR)) -/** - * @} - */ - -/** @defgroup FSMC_Data_Width - * @{ - */ - -#define FSMC_MemoryDataWidth_8b ((uint32_t)0x00000000) -#define FSMC_MemoryDataWidth_16b ((uint32_t)0x00000010) -#define IS_FSMC_MEMORY_WIDTH(WIDTH) (((WIDTH) == FSMC_MemoryDataWidth_8b) || \ - ((WIDTH) == FSMC_MemoryDataWidth_16b)) -/** - * @} - */ - -/** @defgroup FSMC_Burst_Access_Mode - * @{ - */ - -#define FSMC_BurstAccessMode_Disable ((uint32_t)0x00000000) -#define FSMC_BurstAccessMode_Enable ((uint32_t)0x00000100) -#define IS_FSMC_BURSTMODE(STATE) (((STATE) == FSMC_BurstAccessMode_Disable) || \ - ((STATE) == FSMC_BurstAccessMode_Enable)) -/** - * @} - */ - -/** @defgroup FSMC_AsynchronousWait - * @{ - */ -#define FSMC_AsynchronousWait_Disable ((uint32_t)0x00000000) -#define FSMC_AsynchronousWait_Enable ((uint32_t)0x00008000) -#define IS_FSMC_ASYNWAIT(STATE) (((STATE) == FSMC_AsynchronousWait_Disable) || \ - ((STATE) == FSMC_AsynchronousWait_Enable)) -/** - * @} - */ - -/** @defgroup FSMC_Wait_Signal_Polarity - * @{ - */ -#define FSMC_WaitSignalPolarity_Low ((uint32_t)0x00000000) -#define FSMC_WaitSignalPolarity_High ((uint32_t)0x00000200) -#define IS_FSMC_WAIT_POLARITY(POLARITY) (((POLARITY) == FSMC_WaitSignalPolarity_Low) || \ - ((POLARITY) == FSMC_WaitSignalPolarity_High)) -/** - * @} - */ - -/** @defgroup FSMC_Wrap_Mode - * @{ - */ -#define FSMC_WrapMode_Disable ((uint32_t)0x00000000) -#define FSMC_WrapMode_Enable ((uint32_t)0x00000400) -#define IS_FSMC_WRAP_MODE(MODE) (((MODE) == FSMC_WrapMode_Disable) || \ - ((MODE) == FSMC_WrapMode_Enable)) -/** - * @} - */ - -/** @defgroup FSMC_Wait_Timing - * @{ - */ -#define FSMC_WaitSignalActive_BeforeWaitState ((uint32_t)0x00000000) -#define FSMC_WaitSignalActive_DuringWaitState ((uint32_t)0x00000800) -#define IS_FSMC_WAIT_SIGNAL_ACTIVE(ACTIVE) (((ACTIVE) == FSMC_WaitSignalActive_BeforeWaitState) || \ - ((ACTIVE) == FSMC_WaitSignalActive_DuringWaitState)) -/** - * @} - */ - -/** @defgroup FSMC_Write_Operation - * @{ - */ -#define FSMC_WriteOperation_Disable ((uint32_t)0x00000000) -#define FSMC_WriteOperation_Enable ((uint32_t)0x00001000) -#define IS_FSMC_WRITE_OPERATION(OPERATION) (((OPERATION) == FSMC_WriteOperation_Disable) || \ - ((OPERATION) == FSMC_WriteOperation_Enable)) -/** - * @} - */ - -/** @defgroup FSMC_Wait_Signal - * @{ - */ -#define FSMC_WaitSignal_Disable ((uint32_t)0x00000000) -#define FSMC_WaitSignal_Enable ((uint32_t)0x00002000) -#define IS_FSMC_WAITE_SIGNAL(SIGNAL) (((SIGNAL) == FSMC_WaitSignal_Disable) || \ - ((SIGNAL) == FSMC_WaitSignal_Enable)) -/** - * @} - */ - -/** @defgroup FSMC_Extended_Mode - * @{ - */ -#define FSMC_ExtendedMode_Disable ((uint32_t)0x00000000) -#define FSMC_ExtendedMode_Enable ((uint32_t)0x00004000) - -#define IS_FSMC_EXTENDED_MODE(MODE) (((MODE) == FSMC_ExtendedMode_Disable) || \ - ((MODE) == FSMC_ExtendedMode_Enable)) -/** - * @} - */ - -/** @defgroup FSMC_Write_Burst - * @{ - */ - -#define FSMC_WriteBurst_Disable ((uint32_t)0x00000000) -#define FSMC_WriteBurst_Enable ((uint32_t)0x00080000) -#define IS_FSMC_WRITE_BURST(BURST) (((BURST) == FSMC_WriteBurst_Disable) || \ - ((BURST) == FSMC_WriteBurst_Enable)) -/** - * @} - */ - -/** @defgroup FSMC_Address_Setup_Time - * @{ - */ -#define IS_FSMC_ADDRESS_SETUP_TIME(TIME) ((TIME) <= 0xF) -/** - * @} - */ - -/** @defgroup FSMC_Address_Hold_Time - * @{ - */ -#define IS_FSMC_ADDRESS_HOLD_TIME(TIME) ((TIME) <= 0xF) -/** - * @} - */ - -/** @defgroup FSMC_Data_Setup_Time - * @{ - */ -#define IS_FSMC_DATASETUP_TIME(TIME) (((TIME) > 0) && ((TIME) <= 0xFF)) -/** - * @} - */ - -/** @defgroup FSMC_Bus_Turn_around_Duration - * @{ - */ -#define IS_FSMC_TURNAROUND_TIME(TIME) ((TIME) <= 0xF) -/** - * @} - */ - -/** @defgroup FSMC_CLK_Division - * @{ - */ -#define IS_FSMC_CLK_DIV(DIV) ((DIV) <= 0xF) -/** - * @} - */ - -/** @defgroup FSMC_Data_Latency - * @{ - */ -#define IS_FSMC_DATA_LATENCY(LATENCY) ((LATENCY) <= 0xF) -/** - * @} - */ - -/** @defgroup FSMC_Access_Mode - * @{ - */ -#define FSMC_AccessMode_A ((uint32_t)0x00000000) -#define FSMC_AccessMode_B ((uint32_t)0x10000000) -#define FSMC_AccessMode_C ((uint32_t)0x20000000) -#define FSMC_AccessMode_D ((uint32_t)0x30000000) -#define IS_FSMC_ACCESS_MODE(MODE) (((MODE) == FSMC_AccessMode_A) || \ - ((MODE) == FSMC_AccessMode_B) || \ - ((MODE) == FSMC_AccessMode_C) || \ - ((MODE) == FSMC_AccessMode_D)) -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup FSMC_NAND_PCCARD_Controller - * @{ - */ - -/** @defgroup FSMC_Wait_feature - * @{ - */ -#define FSMC_Waitfeature_Disable ((uint32_t)0x00000000) -#define FSMC_Waitfeature_Enable ((uint32_t)0x00000002) -#define IS_FSMC_WAIT_FEATURE(FEATURE) (((FEATURE) == FSMC_Waitfeature_Disable) || \ - ((FEATURE) == FSMC_Waitfeature_Enable)) -/** - * @} - */ - - -/** @defgroup FSMC_ECC - * @{ - */ -#define FSMC_ECC_Disable ((uint32_t)0x00000000) -#define FSMC_ECC_Enable ((uint32_t)0x00000040) -#define IS_FSMC_ECC_STATE(STATE) (((STATE) == FSMC_ECC_Disable) || \ - ((STATE) == FSMC_ECC_Enable)) -/** - * @} - */ - -/** @defgroup FSMC_ECC_Page_Size - * @{ - */ -#define FSMC_ECCPageSize_256Bytes ((uint32_t)0x00000000) -#define FSMC_ECCPageSize_512Bytes ((uint32_t)0x00020000) -#define FSMC_ECCPageSize_1024Bytes ((uint32_t)0x00040000) -#define FSMC_ECCPageSize_2048Bytes ((uint32_t)0x00060000) -#define FSMC_ECCPageSize_4096Bytes ((uint32_t)0x00080000) -#define FSMC_ECCPageSize_8192Bytes ((uint32_t)0x000A0000) -#define IS_FSMC_ECCPAGE_SIZE(SIZE) (((SIZE) == FSMC_ECCPageSize_256Bytes) || \ - ((SIZE) == FSMC_ECCPageSize_512Bytes) || \ - ((SIZE) == FSMC_ECCPageSize_1024Bytes) || \ - ((SIZE) == FSMC_ECCPageSize_2048Bytes) || \ - ((SIZE) == FSMC_ECCPageSize_4096Bytes) || \ - ((SIZE) == FSMC_ECCPageSize_8192Bytes)) -/** - * @} - */ - -/** @defgroup FSMC_TCLR_Setup_Time - * @{ - */ -#define IS_FSMC_TCLR_TIME(TIME) ((TIME) <= 0xFF) -/** - * @} - */ - -/** @defgroup FSMC_TAR_Setup_Time - * @{ - */ -#define IS_FSMC_TAR_TIME(TIME) ((TIME) <= 0xFF) -/** - * @} - */ - -/** @defgroup FSMC_Setup_Time - * @{ - */ -#define IS_FSMC_SETUP_TIME(TIME) ((TIME) <= 0xFF) -/** - * @} - */ - -/** @defgroup FSMC_Wait_Setup_Time - * @{ - */ -#define IS_FSMC_WAIT_TIME(TIME) ((TIME) <= 0xFF) -/** - * @} - */ - -/** @defgroup FSMC_Hold_Setup_Time - * @{ - */ -#define IS_FSMC_HOLD_TIME(TIME) ((TIME) <= 0xFF) -/** - * @} - */ - -/** @defgroup FSMC_HiZ_Setup_Time - * @{ - */ -#define IS_FSMC_HIZ_TIME(TIME) ((TIME) <= 0xFF) -/** - * @} - */ - -/** @defgroup FSMC_Interrupt_sources - * @{ - */ -#define FSMC_IT_RisingEdge ((uint32_t)0x00000008) -#define FSMC_IT_Level ((uint32_t)0x00000010) -#define FSMC_IT_FallingEdge ((uint32_t)0x00000020) -#define IS_FSMC_IT(IT) ((((IT) & (uint32_t)0xFFFFFFC7) == 0x00000000) && ((IT) != 0x00000000)) -#define IS_FSMC_GET_IT(IT) (((IT) == FSMC_IT_RisingEdge) || \ - ((IT) == FSMC_IT_Level) || \ - ((IT) == FSMC_IT_FallingEdge)) -/** - * @} - */ - -/** @defgroup FSMC_Flags - * @{ - */ -#define FSMC_FLAG_RisingEdge ((uint32_t)0x00000001) -#define FSMC_FLAG_Level ((uint32_t)0x00000002) -#define FSMC_FLAG_FallingEdge ((uint32_t)0x00000004) -#define FSMC_FLAG_FEMPT ((uint32_t)0x00000040) -#define IS_FSMC_GET_FLAG(FLAG) (((FLAG) == FSMC_FLAG_RisingEdge) || \ - ((FLAG) == FSMC_FLAG_Level) || \ - ((FLAG) == FSMC_FLAG_FallingEdge) || \ - ((FLAG) == FSMC_FLAG_FEMPT)) - -#define IS_FSMC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFF8) == 0x00000000) && ((FLAG) != 0x00000000)) -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* NOR/SRAM Controller functions **********************************************/ -void FSMC_NORSRAMDeInit(uint32_t FSMC_Bank); -void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct); -void FSMC_NORSRAMStructInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct); -void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState); - -/* NAND Controller functions **************************************************/ -void FSMC_NANDDeInit(uint32_t FSMC_Bank); -void FSMC_NANDInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct); -void FSMC_NANDStructInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct); -void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState); -void FSMC_NANDECCCmd(uint32_t FSMC_Bank, FunctionalState NewState); -uint32_t FSMC_GetECC(uint32_t FSMC_Bank); - -/* PCCARD Controller functions ************************************************/ -void FSMC_PCCARDDeInit(void); -void FSMC_PCCARDInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct); -void FSMC_PCCARDStructInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct); -void FSMC_PCCARDCmd(FunctionalState NewState); - -/* Interrupts and flags management functions **********************************/ -void FSMC_ITConfig(uint32_t FSMC_Bank, uint32_t FSMC_IT, FunctionalState NewState); -FlagStatus FSMC_GetFlagStatus(uint32_t FSMC_Bank, uint32_t FSMC_FLAG); -void FSMC_ClearFlag(uint32_t FSMC_Bank, uint32_t FSMC_FLAG); -ITStatus FSMC_GetITStatus(uint32_t FSMC_Bank, uint32_t FSMC_IT); -void FSMC_ClearITPendingBit(uint32_t FSMC_Bank, uint32_t FSMC_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F4xx_FSMC_H */ -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_gpio.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_gpio.h deleted file mode 100644 index 05b90744f..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_gpio.h +++ /dev/null @@ -1,406 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_gpio.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the GPIO firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_GPIO_H -#define __STM32F4xx_GPIO_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup GPIO - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ - ((PERIPH) == GPIOB) || \ - ((PERIPH) == GPIOC) || \ - ((PERIPH) == GPIOD) || \ - ((PERIPH) == GPIOE) || \ - ((PERIPH) == GPIOF) || \ - ((PERIPH) == GPIOG) || \ - ((PERIPH) == GPIOH) || \ - ((PERIPH) == GPIOI)) - -/** - * @brief GPIO Configuration Mode enumeration - */ -typedef enum -{ - GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ - GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ - GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ - GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */ -}GPIOMode_TypeDef; -#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN) || ((MODE) == GPIO_Mode_OUT) || \ - ((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN)) - -/** - * @brief GPIO Output type enumeration - */ -typedef enum -{ - GPIO_OType_PP = 0x00, - GPIO_OType_OD = 0x01 -}GPIOOType_TypeDef; -#define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD)) - - -/** - * @brief GPIO Output Maximum frequency enumeration - */ -typedef enum -{ - GPIO_Speed_2MHz = 0x00, /*!< Low speed */ - GPIO_Speed_25MHz = 0x01, /*!< Medium speed */ - GPIO_Speed_50MHz = 0x02, /*!< Fast speed */ - GPIO_Speed_100MHz = 0x03 /*!< High speed on 30 pF (80 MHz Output max speed on 15 pF) */ -}GPIOSpeed_TypeDef; -#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_2MHz) || ((SPEED) == GPIO_Speed_25MHz) || \ - ((SPEED) == GPIO_Speed_50MHz)|| ((SPEED) == GPIO_Speed_100MHz)) - -/** - * @brief GPIO Configuration PullUp PullDown enumeration - */ -typedef enum -{ - GPIO_PuPd_NOPULL = 0x00, - GPIO_PuPd_UP = 0x01, - GPIO_PuPd_DOWN = 0x02 -}GPIOPuPd_TypeDef; -#define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \ - ((PUPD) == GPIO_PuPd_DOWN)) - -/** - * @brief GPIO Bit SET and Bit RESET enumeration - */ -typedef enum -{ - Bit_RESET = 0, - Bit_SET -}BitAction; -#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) - - -/** - * @brief GPIO Init structure definition - */ -typedef struct -{ - uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. - This parameter can be any value of @ref GPIO_pins_define */ - - GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. - This parameter can be a value of @ref GPIOMode_TypeDef */ - - GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. - This parameter can be a value of @ref GPIOSpeed_TypeDef */ - - GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins. - This parameter can be a value of @ref GPIOOType_TypeDef */ - - GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. - This parameter can be a value of @ref GPIOPuPd_TypeDef */ -}GPIO_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup GPIO_Exported_Constants - * @{ - */ - -/** @defgroup GPIO_pins_define - * @{ - */ -#define GPIO_Pin_0 ((uint16_t)0x0001) /* Pin 0 selected */ -#define GPIO_Pin_1 ((uint16_t)0x0002) /* Pin 1 selected */ -#define GPIO_Pin_2 ((uint16_t)0x0004) /* Pin 2 selected */ -#define GPIO_Pin_3 ((uint16_t)0x0008) /* Pin 3 selected */ -#define GPIO_Pin_4 ((uint16_t)0x0010) /* Pin 4 selected */ -#define GPIO_Pin_5 ((uint16_t)0x0020) /* Pin 5 selected */ -#define GPIO_Pin_6 ((uint16_t)0x0040) /* Pin 6 selected */ -#define GPIO_Pin_7 ((uint16_t)0x0080) /* Pin 7 selected */ -#define GPIO_Pin_8 ((uint16_t)0x0100) /* Pin 8 selected */ -#define GPIO_Pin_9 ((uint16_t)0x0200) /* Pin 9 selected */ -#define GPIO_Pin_10 ((uint16_t)0x0400) /* Pin 10 selected */ -#define GPIO_Pin_11 ((uint16_t)0x0800) /* Pin 11 selected */ -#define GPIO_Pin_12 ((uint16_t)0x1000) /* Pin 12 selected */ -#define GPIO_Pin_13 ((uint16_t)0x2000) /* Pin 13 selected */ -#define GPIO_Pin_14 ((uint16_t)0x4000) /* Pin 14 selected */ -#define GPIO_Pin_15 ((uint16_t)0x8000) /* Pin 15 selected */ -#define GPIO_Pin_All ((uint16_t)0xFFFF) /* All pins selected */ - -#define IS_GPIO_PIN(PIN) ((((PIN) & (uint16_t)0x00) == 0x00) && ((PIN) != (uint16_t)0x00)) -#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \ - ((PIN) == GPIO_Pin_1) || \ - ((PIN) == GPIO_Pin_2) || \ - ((PIN) == GPIO_Pin_3) || \ - ((PIN) == GPIO_Pin_4) || \ - ((PIN) == GPIO_Pin_5) || \ - ((PIN) == GPIO_Pin_6) || \ - ((PIN) == GPIO_Pin_7) || \ - ((PIN) == GPIO_Pin_8) || \ - ((PIN) == GPIO_Pin_9) || \ - ((PIN) == GPIO_Pin_10) || \ - ((PIN) == GPIO_Pin_11) || \ - ((PIN) == GPIO_Pin_12) || \ - ((PIN) == GPIO_Pin_13) || \ - ((PIN) == GPIO_Pin_14) || \ - ((PIN) == GPIO_Pin_15)) -/** - * @} - */ - - -/** @defgroup GPIO_Pin_sources - * @{ - */ -#define GPIO_PinSource0 ((uint8_t)0x00) -#define GPIO_PinSource1 ((uint8_t)0x01) -#define GPIO_PinSource2 ((uint8_t)0x02) -#define GPIO_PinSource3 ((uint8_t)0x03) -#define GPIO_PinSource4 ((uint8_t)0x04) -#define GPIO_PinSource5 ((uint8_t)0x05) -#define GPIO_PinSource6 ((uint8_t)0x06) -#define GPIO_PinSource7 ((uint8_t)0x07) -#define GPIO_PinSource8 ((uint8_t)0x08) -#define GPIO_PinSource9 ((uint8_t)0x09) -#define GPIO_PinSource10 ((uint8_t)0x0A) -#define GPIO_PinSource11 ((uint8_t)0x0B) -#define GPIO_PinSource12 ((uint8_t)0x0C) -#define GPIO_PinSource13 ((uint8_t)0x0D) -#define GPIO_PinSource14 ((uint8_t)0x0E) -#define GPIO_PinSource15 ((uint8_t)0x0F) - -#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \ - ((PINSOURCE) == GPIO_PinSource1) || \ - ((PINSOURCE) == GPIO_PinSource2) || \ - ((PINSOURCE) == GPIO_PinSource3) || \ - ((PINSOURCE) == GPIO_PinSource4) || \ - ((PINSOURCE) == GPIO_PinSource5) || \ - ((PINSOURCE) == GPIO_PinSource6) || \ - ((PINSOURCE) == GPIO_PinSource7) || \ - ((PINSOURCE) == GPIO_PinSource8) || \ - ((PINSOURCE) == GPIO_PinSource9) || \ - ((PINSOURCE) == GPIO_PinSource10) || \ - ((PINSOURCE) == GPIO_PinSource11) || \ - ((PINSOURCE) == GPIO_PinSource12) || \ - ((PINSOURCE) == GPIO_PinSource13) || \ - ((PINSOURCE) == GPIO_PinSource14) || \ - ((PINSOURCE) == GPIO_PinSource15)) -/** - * @} - */ - -/** @defgroup GPIO_Alternat_function_selection_define - * @{ - */ -/** - * @brief AF 0 selection - */ -#define GPIO_AF_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ -#define GPIO_AF_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ -#define GPIO_AF_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ -#define GPIO_AF_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ -#define GPIO_AF_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ - -/** - * @brief AF 1 selection - */ -#define GPIO_AF_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ -#define GPIO_AF_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ - -/** - * @brief AF 2 selection - */ -#define GPIO_AF_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ -#define GPIO_AF_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ -#define GPIO_AF_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ - -/** - * @brief AF 3 selection - */ -#define GPIO_AF_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */ -#define GPIO_AF_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */ -#define GPIO_AF_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */ -#define GPIO_AF_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */ - -/** - * @brief AF 4 selection - */ -#define GPIO_AF_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ -#define GPIO_AF_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ -#define GPIO_AF_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ - -/** - * @brief AF 5 selection - */ -#define GPIO_AF_SPI1 ((uint8_t)0x05) /* SPI1 Alternate Function mapping */ -#define GPIO_AF_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */ - -/** - * @brief AF 6 selection - */ -#define GPIO_AF_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */ - -/** - * @brief AF 7 selection - */ -#define GPIO_AF_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ -#define GPIO_AF_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ -#define GPIO_AF_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */ -#define GPIO_AF_I2S3ext ((uint8_t)0x07) /* I2S3ext Alternate Function mapping */ - -/** - * @brief AF 8 selection - */ -#define GPIO_AF_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */ -#define GPIO_AF_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */ -#define GPIO_AF_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */ - -/** - * @brief AF 9 selection - */ -#define GPIO_AF_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */ -#define GPIO_AF_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */ -#define GPIO_AF_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */ -#define GPIO_AF_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */ -#define GPIO_AF_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ - -/** - * @brief AF 10 selection - */ -#define GPIO_AF_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ -#define GPIO_AF_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */ - -/** - * @brief AF 11 selection - */ -#define GPIO_AF_ETH ((uint8_t)0x0B) /* ETHERNET Alternate Function mapping */ - -/** - * @brief AF 12 selection - */ -#define GPIO_AF_FSMC ((uint8_t)0xC) /* FSMC Alternate Function mapping */ -#define GPIO_AF_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */ -#define GPIO_AF_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */ - -/** - * @brief AF 13 selection - */ -#define GPIO_AF_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */ - -/** - * @brief AF 15 selection - */ -#define GPIO_AF_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ - -#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ - ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ - ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ - ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ - ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ - ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ - ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ - ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ - ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ - ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ - ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ - ((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \ - ((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \ - ((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \ - ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ - ((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_FSMC) || \ - ((AF) == GPIO_AF_OTG_HS_FS) || ((AF) == GPIO_AF_SDIO) || \ - ((AF) == GPIO_AF_DCMI) || ((AF) == GPIO_AF_EVENTOUT)) -/** - * @} - */ - -/** @defgroup GPIO_Legacy - * @{ - */ - -#define GPIO_Mode_AIN GPIO_Mode_AN - -#define GPIO_AF_OTG1_FS GPIO_AF_OTG_FS -#define GPIO_AF_OTG2_HS GPIO_AF_OTG_HS -#define GPIO_AF_OTG2_FS GPIO_AF_OTG_HS_FS - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the GPIO configuration to the default reset state ****/ -void GPIO_DeInit(GPIO_TypeDef* GPIOx); - -/* Initialization and Configuration functions *********************************/ -void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); -void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); -void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); - -/* GPIO Read and Write functions **********************************************/ -uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); -uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); -void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); -void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); -void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); - -/* GPIO Alternate functions configuration function ****************************/ -void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F4xx_GPIO_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_hash.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_hash.h deleted file mode 100644 index 7cf571753..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_hash.h +++ /dev/null @@ -1,244 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_hash.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the HASH - * firmware library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_HASH_H -#define __STM32F4xx_HASH_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup HASH - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief HASH Init structure definition - */ -typedef struct -{ - uint32_t HASH_AlgoSelection; /*!< SHA-1 or MD5. This parameter can be a value - of @ref HASH_Algo_Selection */ - uint32_t HASH_AlgoMode; /*!< HASH or HMAC. This parameter can be a value - of @ref HASH_processor_Algorithm_Mode */ - uint32_t HASH_DataType; /*!< 32-bit data, 16-bit data, 8-bit data or - bit-string. This parameter can be a value of - @ref HASH_Data_Type */ - uint32_t HASH_HMACKeyType; /*!< HMAC Short key or HMAC Long Key. This parameter - can be a value of @ref HASH_HMAC_Long_key_only_for_HMAC_mode */ -}HASH_InitTypeDef; - -/** - * @brief HASH message digest result structure definition - */ -typedef struct -{ - uint32_t Data[5]; /*!< Message digest result : 5x 32bit words for SHA1 or - 4x 32bit words for MD5 */ -} HASH_MsgDigest; - -/** - * @brief HASH context swapping structure definition - */ -typedef struct -{ - uint32_t HASH_IMR; - uint32_t HASH_STR; - uint32_t HASH_CR; - uint32_t HASH_CSR[51]; -}HASH_Context; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup HASH_Exported_Constants - * @{ - */ - -/** @defgroup HASH_Algo_Selection - * @{ - */ -#define HASH_AlgoSelection_SHA1 ((uint16_t)0x0000) /*!< HASH function is SHA1 */ -#define HASH_AlgoSelection_MD5 ((uint16_t)0x0080) /*!< HASH function is MD5 */ - -#define IS_HASH_ALGOSELECTION(ALGOSELECTION) (((ALGOSELECTION) == HASH_AlgoSelection_SHA1) || \ - ((ALGOSELECTION) == HASH_AlgoSelection_MD5)) -/** - * @} - */ - -/** @defgroup HASH_processor_Algorithm_Mode - * @{ - */ -#define HASH_AlgoMode_HASH ((uint16_t)0x0000) /*!< Algorithm is HASH */ -#define HASH_AlgoMode_HMAC ((uint16_t)0x0040) /*!< Algorithm is HMAC */ - -#define IS_HASH_ALGOMODE(ALGOMODE) (((ALGOMODE) == HASH_AlgoMode_HASH) || \ - ((ALGOMODE) == HASH_AlgoMode_HMAC)) -/** - * @} - */ - -/** @defgroup HASH_Data_Type - * @{ - */ -#define HASH_DataType_32b ((uint16_t)0x0000) -#define HASH_DataType_16b ((uint16_t)0x0010) -#define HASH_DataType_8b ((uint16_t)0x0020) -#define HASH_DataType_1b ((uint16_t)0x0030) - -#define IS_HASH_DATATYPE(DATATYPE) (((DATATYPE) == HASH_DataType_32b)|| \ - ((DATATYPE) == HASH_DataType_16b)|| \ - ((DATATYPE) == HASH_DataType_8b)|| \ - ((DATATYPE) == HASH_DataType_1b)) -/** - * @} - */ - -/** @defgroup HASH_HMAC_Long_key_only_for_HMAC_mode - * @{ - */ -#define HASH_HMACKeyType_ShortKey ((uint32_t)0x00000000) /*!< HMAC Key is <= 64 bytes */ -#define HASH_HMACKeyType_LongKey ((uint32_t)0x00010000) /*!< HMAC Key is > 64 bytes */ - -#define IS_HASH_HMAC_KEYTYPE(KEYTYPE) (((KEYTYPE) == HASH_HMACKeyType_ShortKey) || \ - ((KEYTYPE) == HASH_HMACKeyType_LongKey)) -/** - * @} - */ - -/** @defgroup Number_of_valid_bits_in_last_word_of_the_message - * @{ - */ -#define IS_HASH_VALIDBITSNUMBER(VALIDBITS) ((VALIDBITS) <= 0x1F) - -/** - * @} - */ - -/** @defgroup HASH_interrupts_definition - * @{ - */ -#define HASH_IT_DINI ((uint8_t)0x01) /*!< A new block can be entered into the input buffer (DIN)*/ -#define HASH_IT_DCI ((uint8_t)0x02) /*!< Digest calculation complete */ - -#define IS_HASH_IT(IT) ((((IT) & (uint8_t)0xFC) == 0x00) && ((IT) != 0x00)) -#define IS_HASH_GET_IT(IT) (((IT) == HASH_IT_DINI) || ((IT) == HASH_IT_DCI)) - -/** - * @} - */ - -/** @defgroup HASH_flags_definition - * @{ - */ -#define HASH_FLAG_DINIS ((uint16_t)0x0001) /*!< 16 locations are free in the DIN : A new block can be entered into the input buffer.*/ -#define HASH_FLAG_DCIS ((uint16_t)0x0002) /*!< Digest calculation complete */ -#define HASH_FLAG_DMAS ((uint16_t)0x0004) /*!< DMA interface is enabled (DMAE=1) or a transfer is ongoing */ -#define HASH_FLAG_BUSY ((uint16_t)0x0008) /*!< The hash core is Busy : processing a block of data */ -#define HASH_FLAG_DINNE ((uint16_t)0x1000) /*!< DIN not empty : The input buffer contains at least one word of data */ - -#define IS_HASH_GET_FLAG(FLAG) (((FLAG) == HASH_FLAG_DINIS) || \ - ((FLAG) == HASH_FLAG_DCIS) || \ - ((FLAG) == HASH_FLAG_DMAS) || \ - ((FLAG) == HASH_FLAG_BUSY) || \ - ((FLAG) == HASH_FLAG_DINNE)) - -#define IS_HASH_CLEAR_FLAG(FLAG)(((FLAG) == HASH_FLAG_DINIS) || \ - ((FLAG) == HASH_FLAG_DCIS)) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the HASH configuration to the default reset state ****/ -void HASH_DeInit(void); - -/* HASH Configuration function ************************************************/ -void HASH_Init(HASH_InitTypeDef* HASH_InitStruct); -void HASH_StructInit(HASH_InitTypeDef* HASH_InitStruct); -void HASH_Reset(void); - -/* HASH Message Digest generation functions ***********************************/ -void HASH_DataIn(uint32_t Data); -uint8_t HASH_GetInFIFOWordsNbr(void); -void HASH_SetLastWordValidBitsNbr(uint16_t ValidNumber); -void HASH_StartDigest(void); -void HASH_GetDigest(HASH_MsgDigest* HASH_MessageDigest); - -/* HASH Context swapping functions ********************************************/ -void HASH_SaveContext(HASH_Context* HASH_ContextSave); -void HASH_RestoreContext(HASH_Context* HASH_ContextRestore); - -/* HASH's DMA interface function **********************************************/ -void HASH_DMACmd(FunctionalState NewState); - -/* HASH Interrupts and flags management functions *****************************/ -void HASH_ITConfig(uint8_t HASH_IT, FunctionalState NewState); -FlagStatus HASH_GetFlagStatus(uint16_t HASH_FLAG); -void HASH_ClearFlag(uint16_t HASH_FLAG); -ITStatus HASH_GetITStatus(uint8_t HASH_IT); -void HASH_ClearITPendingBit(uint8_t HASH_IT); - -/* High Level SHA1 functions **************************************************/ -ErrorStatus HASH_SHA1(uint8_t *Input, uint32_t Ilen, uint8_t Output[20]); -ErrorStatus HMAC_SHA1(uint8_t *Key, uint32_t Keylen, - uint8_t *Input, uint32_t Ilen, - uint8_t Output[20]); - -/* High Level MD5 functions ***************************************************/ -ErrorStatus HASH_MD5(uint8_t *Input, uint32_t Ilen, uint8_t Output[16]); -ErrorStatus HMAC_MD5(uint8_t *Key, uint32_t Keylen, - uint8_t *Input, uint32_t Ilen, - uint8_t Output[16]); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F4xx_HASH_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_i2c.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_i2c.h deleted file mode 100644 index ffba64cd5..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_i2c.h +++ /dev/null @@ -1,692 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_i2c.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the I2C firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_I2C_H -#define __STM32F4xx_I2C_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup I2C - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief I2C Init structure definition - */ - -typedef struct -{ - uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency. - This parameter must be set to a value lower than 400kHz */ - - uint16_t I2C_Mode; /*!< Specifies the I2C mode. - This parameter can be a value of @ref I2C_mode */ - - uint16_t I2C_DutyCycle; /*!< Specifies the I2C fast mode duty cycle. - This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */ - - uint16_t I2C_OwnAddress1; /*!< Specifies the first device own address. - This parameter can be a 7-bit or 10-bit address. */ - - uint16_t I2C_Ack; /*!< Enables or disables the acknowledgement. - This parameter can be a value of @ref I2C_acknowledgement */ - - uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged. - This parameter can be a value of @ref I2C_acknowledged_address */ -}I2C_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - - -/** @defgroup I2C_Exported_Constants - * @{ - */ - -#define IS_I2C_ALL_PERIPH(PERIPH) (((PERIPH) == I2C1) || \ - ((PERIPH) == I2C2) || \ - ((PERIPH) == I2C3)) -/** @defgroup I2C_mode - * @{ - */ - -#define I2C_Mode_I2C ((uint16_t)0x0000) -#define I2C_Mode_SMBusDevice ((uint16_t)0x0002) -#define I2C_Mode_SMBusHost ((uint16_t)0x000A) -#define IS_I2C_MODE(MODE) (((MODE) == I2C_Mode_I2C) || \ - ((MODE) == I2C_Mode_SMBusDevice) || \ - ((MODE) == I2C_Mode_SMBusHost)) -/** - * @} - */ - -/** @defgroup I2C_duty_cycle_in_fast_mode - * @{ - */ - -#define I2C_DutyCycle_16_9 ((uint16_t)0x4000) /*!< I2C fast mode Tlow/Thigh = 16/9 */ -#define I2C_DutyCycle_2 ((uint16_t)0xBFFF) /*!< I2C fast mode Tlow/Thigh = 2 */ -#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DutyCycle_16_9) || \ - ((CYCLE) == I2C_DutyCycle_2)) -/** - * @} - */ - -/** @defgroup I2C_acknowledgement - * @{ - */ - -#define I2C_Ack_Enable ((uint16_t)0x0400) -#define I2C_Ack_Disable ((uint16_t)0x0000) -#define IS_I2C_ACK_STATE(STATE) (((STATE) == I2C_Ack_Enable) || \ - ((STATE) == I2C_Ack_Disable)) -/** - * @} - */ - -/** @defgroup I2C_transfer_direction - * @{ - */ - -#define I2C_Direction_Transmitter ((uint8_t)0x00) -#define I2C_Direction_Receiver ((uint8_t)0x01) -#define IS_I2C_DIRECTION(DIRECTION) (((DIRECTION) == I2C_Direction_Transmitter) || \ - ((DIRECTION) == I2C_Direction_Receiver)) -/** - * @} - */ - -/** @defgroup I2C_acknowledged_address - * @{ - */ - -#define I2C_AcknowledgedAddress_7bit ((uint16_t)0x4000) -#define I2C_AcknowledgedAddress_10bit ((uint16_t)0xC000) -#define IS_I2C_ACKNOWLEDGE_ADDRESS(ADDRESS) (((ADDRESS) == I2C_AcknowledgedAddress_7bit) || \ - ((ADDRESS) == I2C_AcknowledgedAddress_10bit)) -/** - * @} - */ - -/** @defgroup I2C_registers - * @{ - */ - -#define I2C_Register_CR1 ((uint8_t)0x00) -#define I2C_Register_CR2 ((uint8_t)0x04) -#define I2C_Register_OAR1 ((uint8_t)0x08) -#define I2C_Register_OAR2 ((uint8_t)0x0C) -#define I2C_Register_DR ((uint8_t)0x10) -#define I2C_Register_SR1 ((uint8_t)0x14) -#define I2C_Register_SR2 ((uint8_t)0x18) -#define I2C_Register_CCR ((uint8_t)0x1C) -#define I2C_Register_TRISE ((uint8_t)0x20) -#define IS_I2C_REGISTER(REGISTER) (((REGISTER) == I2C_Register_CR1) || \ - ((REGISTER) == I2C_Register_CR2) || \ - ((REGISTER) == I2C_Register_OAR1) || \ - ((REGISTER) == I2C_Register_OAR2) || \ - ((REGISTER) == I2C_Register_DR) || \ - ((REGISTER) == I2C_Register_SR1) || \ - ((REGISTER) == I2C_Register_SR2) || \ - ((REGISTER) == I2C_Register_CCR) || \ - ((REGISTER) == I2C_Register_TRISE)) -/** - * @} - */ - -/** @defgroup I2C_NACK_position - * @{ - */ - -#define I2C_NACKPosition_Next ((uint16_t)0x0800) -#define I2C_NACKPosition_Current ((uint16_t)0xF7FF) -#define IS_I2C_NACK_POSITION(POSITION) (((POSITION) == I2C_NACKPosition_Next) || \ - ((POSITION) == I2C_NACKPosition_Current)) -/** - * @} - */ - -/** @defgroup I2C_SMBus_alert_pin_level - * @{ - */ - -#define I2C_SMBusAlert_Low ((uint16_t)0x2000) -#define I2C_SMBusAlert_High ((uint16_t)0xDFFF) -#define IS_I2C_SMBUS_ALERT(ALERT) (((ALERT) == I2C_SMBusAlert_Low) || \ - ((ALERT) == I2C_SMBusAlert_High)) -/** - * @} - */ - -/** @defgroup I2C_PEC_position - * @{ - */ - -#define I2C_PECPosition_Next ((uint16_t)0x0800) -#define I2C_PECPosition_Current ((uint16_t)0xF7FF) -#define IS_I2C_PEC_POSITION(POSITION) (((POSITION) == I2C_PECPosition_Next) || \ - ((POSITION) == I2C_PECPosition_Current)) -/** - * @} - */ - -/** @defgroup I2C_interrupts_definition - * @{ - */ - -#define I2C_IT_BUF ((uint16_t)0x0400) -#define I2C_IT_EVT ((uint16_t)0x0200) -#define I2C_IT_ERR ((uint16_t)0x0100) -#define IS_I2C_CONFIG_IT(IT) ((((IT) & (uint16_t)0xF8FF) == 0x00) && ((IT) != 0x00)) -/** - * @} - */ - -/** @defgroup I2C_interrupts_definition - * @{ - */ - -#define I2C_IT_SMBALERT ((uint32_t)0x01008000) -#define I2C_IT_TIMEOUT ((uint32_t)0x01004000) -#define I2C_IT_PECERR ((uint32_t)0x01001000) -#define I2C_IT_OVR ((uint32_t)0x01000800) -#define I2C_IT_AF ((uint32_t)0x01000400) -#define I2C_IT_ARLO ((uint32_t)0x01000200) -#define I2C_IT_BERR ((uint32_t)0x01000100) -#define I2C_IT_TXE ((uint32_t)0x06000080) -#define I2C_IT_RXNE ((uint32_t)0x06000040) -#define I2C_IT_STOPF ((uint32_t)0x02000010) -#define I2C_IT_ADD10 ((uint32_t)0x02000008) -#define I2C_IT_BTF ((uint32_t)0x02000004) -#define I2C_IT_ADDR ((uint32_t)0x02000002) -#define I2C_IT_SB ((uint32_t)0x02000001) - -#define IS_I2C_CLEAR_IT(IT) ((((IT) & (uint16_t)0x20FF) == 0x00) && ((IT) != (uint16_t)0x00)) - -#define IS_I2C_GET_IT(IT) (((IT) == I2C_IT_SMBALERT) || ((IT) == I2C_IT_TIMEOUT) || \ - ((IT) == I2C_IT_PECERR) || ((IT) == I2C_IT_OVR) || \ - ((IT) == I2C_IT_AF) || ((IT) == I2C_IT_ARLO) || \ - ((IT) == I2C_IT_BERR) || ((IT) == I2C_IT_TXE) || \ - ((IT) == I2C_IT_RXNE) || ((IT) == I2C_IT_STOPF) || \ - ((IT) == I2C_IT_ADD10) || ((IT) == I2C_IT_BTF) || \ - ((IT) == I2C_IT_ADDR) || ((IT) == I2C_IT_SB)) -/** - * @} - */ - -/** @defgroup I2C_flags_definition - * @{ - */ - -/** - * @brief SR2 register flags - */ - -#define I2C_FLAG_DUALF ((uint32_t)0x00800000) -#define I2C_FLAG_SMBHOST ((uint32_t)0x00400000) -#define I2C_FLAG_SMBDEFAULT ((uint32_t)0x00200000) -#define I2C_FLAG_GENCALL ((uint32_t)0x00100000) -#define I2C_FLAG_TRA ((uint32_t)0x00040000) -#define I2C_FLAG_BUSY ((uint32_t)0x00020000) -#define I2C_FLAG_MSL ((uint32_t)0x00010000) - -/** - * @brief SR1 register flags - */ - -#define I2C_FLAG_SMBALERT ((uint32_t)0x10008000) -#define I2C_FLAG_TIMEOUT ((uint32_t)0x10004000) -#define I2C_FLAG_PECERR ((uint32_t)0x10001000) -#define I2C_FLAG_OVR ((uint32_t)0x10000800) -#define I2C_FLAG_AF ((uint32_t)0x10000400) -#define I2C_FLAG_ARLO ((uint32_t)0x10000200) -#define I2C_FLAG_BERR ((uint32_t)0x10000100) -#define I2C_FLAG_TXE ((uint32_t)0x10000080) -#define I2C_FLAG_RXNE ((uint32_t)0x10000040) -#define I2C_FLAG_STOPF ((uint32_t)0x10000010) -#define I2C_FLAG_ADD10 ((uint32_t)0x10000008) -#define I2C_FLAG_BTF ((uint32_t)0x10000004) -#define I2C_FLAG_ADDR ((uint32_t)0x10000002) -#define I2C_FLAG_SB ((uint32_t)0x10000001) - -#define IS_I2C_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0x20FF) == 0x00) && ((FLAG) != (uint16_t)0x00)) - -#define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_DUALF) || ((FLAG) == I2C_FLAG_SMBHOST) || \ - ((FLAG) == I2C_FLAG_SMBDEFAULT) || ((FLAG) == I2C_FLAG_GENCALL) || \ - ((FLAG) == I2C_FLAG_TRA) || ((FLAG) == I2C_FLAG_BUSY) || \ - ((FLAG) == I2C_FLAG_MSL) || ((FLAG) == I2C_FLAG_SMBALERT) || \ - ((FLAG) == I2C_FLAG_TIMEOUT) || ((FLAG) == I2C_FLAG_PECERR) || \ - ((FLAG) == I2C_FLAG_OVR) || ((FLAG) == I2C_FLAG_AF) || \ - ((FLAG) == I2C_FLAG_ARLO) || ((FLAG) == I2C_FLAG_BERR) || \ - ((FLAG) == I2C_FLAG_TXE) || ((FLAG) == I2C_FLAG_RXNE) || \ - ((FLAG) == I2C_FLAG_STOPF) || ((FLAG) == I2C_FLAG_ADD10) || \ - ((FLAG) == I2C_FLAG_BTF) || ((FLAG) == I2C_FLAG_ADDR) || \ - ((FLAG) == I2C_FLAG_SB)) -/** - * @} - */ - -/** @defgroup I2C_Events - * @{ - */ - -/** - =============================================================================== - I2C Master Events (Events grouped in order of communication) - =============================================================================== - */ - -/** - * @brief Communication start - * - * After sending the START condition (I2C_GenerateSTART() function) the master - * has to wait for this event. It means that the Start condition has been correctly - * released on the I2C bus (the bus is free, no other devices is communicating). - * - */ -/* --EV5 */ -#define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */ - -/** - * @brief Address Acknowledge - * - * After checking on EV5 (start condition correctly released on the bus), the - * master sends the address of the slave(s) with which it will communicate - * (I2C_Send7bitAddress() function, it also determines the direction of the communication: - * Master transmitter or Receiver). Then the master has to wait that a slave acknowledges - * his address. If an acknowledge is sent on the bus, one of the following events will - * be set: - * - * 1) In case of Master Receiver (7-bit addressing): the I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED - * event is set. - * - * 2) In case of Master Transmitter (7-bit addressing): the I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED - * is set - * - * 3) In case of 10-Bit addressing mode, the master (just after generating the START - * and checking on EV5) has to send the header of 10-bit addressing mode (I2C_SendData() - * function). Then master should wait on EV9. It means that the 10-bit addressing - * header has been correctly sent on the bus. Then master should send the second part of - * the 10-bit address (LSB) using the function I2C_Send7bitAddress(). Then master - * should wait for event EV6. - * - */ - -/* --EV6 */ -#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */ -#define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL and ADDR flags */ -/* --EV9 */ -#define I2C_EVENT_MASTER_MODE_ADDRESS10 ((uint32_t)0x00030008) /* BUSY, MSL and ADD10 flags */ - -/** - * @brief Communication events - * - * If a communication is established (START condition generated and slave address - * acknowledged) then the master has to check on one of the following events for - * communication procedures: - * - * 1) Master Receiver mode: The master has to wait on the event EV7 then to read - * the data received from the slave (I2C_ReceiveData() function). - * - * 2) Master Transmitter mode: The master has to send data (I2C_SendData() - * function) then to wait on event EV8 or EV8_2. - * These two events are similar: - * - EV8 means that the data has been written in the data register and is - * being shifted out. - * - EV8_2 means that the data has been physically shifted out and output - * on the bus. - * In most cases, using EV8 is sufficient for the application. - * Using EV8_2 leads to a slower communication but ensure more reliable test. - * EV8_2 is also more suitable than EV8 for testing on the last data transmission - * (before Stop condition generation). - * - * @note In case the user software does not guarantee that this event EV7 is - * managed before the current byte end of transfer, then user may check on EV7 - * and BTF flag at the same time (ie. (I2C_EVENT_MASTER_BYTE_RECEIVED | I2C_FLAG_BTF)). - * In this case the communication may be slower. - * - */ - -/* Master RECEIVER mode -----------------------------*/ -/* --EV7 */ -#define I2C_EVENT_MASTER_BYTE_RECEIVED ((uint32_t)0x00030040) /* BUSY, MSL and RXNE flags */ - -/* Master TRANSMITTER mode --------------------------*/ -/* --EV8 */ -#define I2C_EVENT_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */ -/* --EV8_2 */ -#define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags */ - - -/** - =============================================================================== - I2C Slave Events (Events grouped in order of communication) - =============================================================================== - */ - - -/** - * @brief Communication start events - * - * Wait on one of these events at the start of the communication. It means that - * the I2C peripheral detected a Start condition on the bus (generated by master - * device) followed by the peripheral address. The peripheral generates an ACK - * condition on the bus (if the acknowledge feature is enabled through function - * I2C_AcknowledgeConfig()) and the events listed above are set : - * - * 1) In normal case (only one address managed by the slave), when the address - * sent by the master matches the own address of the peripheral (configured by - * I2C_OwnAddress1 field) the I2C_EVENT_SLAVE_XXX_ADDRESS_MATCHED event is set - * (where XXX could be TRANSMITTER or RECEIVER). - * - * 2) In case the address sent by the master matches the second address of the - * peripheral (configured by the function I2C_OwnAddress2Config() and enabled - * by the function I2C_DualAddressCmd()) the events I2C_EVENT_SLAVE_XXX_SECONDADDRESS_MATCHED - * (where XXX could be TRANSMITTER or RECEIVER) are set. - * - * 3) In case the address sent by the master is General Call (address 0x00) and - * if the General Call is enabled for the peripheral (using function I2C_GeneralCallCmd()) - * the following event is set I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED. - * - */ - -/* --EV1 (all the events below are variants of EV1) */ -/* 1) Case of One Single Address managed by the slave */ -#define I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ((uint32_t)0x00020002) /* BUSY and ADDR flags */ -#define I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED ((uint32_t)0x00060082) /* TRA, BUSY, TXE and ADDR flags */ - -/* 2) Case of Dual address managed by the slave */ -#define I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED ((uint32_t)0x00820000) /* DUALF and BUSY flags */ -#define I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED ((uint32_t)0x00860080) /* DUALF, TRA, BUSY and TXE flags */ - -/* 3) Case of General Call enabled for the slave */ -#define I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED ((uint32_t)0x00120000) /* GENCALL and BUSY flags */ - -/** - * @brief Communication events - * - * Wait on one of these events when EV1 has already been checked and: - * - * - Slave RECEIVER mode: - * - EV2: When the application is expecting a data byte to be received. - * - EV4: When the application is expecting the end of the communication: master - * sends a stop condition and data transmission is stopped. - * - * - Slave Transmitter mode: - * - EV3: When a byte has been transmitted by the slave and the application is expecting - * the end of the byte transmission. The two events I2C_EVENT_SLAVE_BYTE_TRANSMITTED and - * I2C_EVENT_SLAVE_BYTE_TRANSMITTING are similar. The second one can optionally be - * used when the user software doesn't guarantee the EV3 is managed before the - * current byte end of transfer. - * - EV3_2: When the master sends a NACK in order to tell slave that data transmission - * shall end (before sending the STOP condition). In this case slave has to stop sending - * data bytes and expect a Stop condition on the bus. - * - * @note In case the user software does not guarantee that the event EV2 is - * managed before the current byte end of transfer, then user may check on EV2 - * and BTF flag at the same time (ie. (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_BTF)). - * In this case the communication may be slower. - * - */ - -/* Slave RECEIVER mode --------------------------*/ -/* --EV2 */ -#define I2C_EVENT_SLAVE_BYTE_RECEIVED ((uint32_t)0x00020040) /* BUSY and RXNE flags */ -/* --EV4 */ -#define I2C_EVENT_SLAVE_STOP_DETECTED ((uint32_t)0x00000010) /* STOPF flag */ - -/* Slave TRANSMITTER mode -----------------------*/ -/* --EV3 */ -#define I2C_EVENT_SLAVE_BYTE_TRANSMITTED ((uint32_t)0x00060084) /* TRA, BUSY, TXE and BTF flags */ -#define I2C_EVENT_SLAVE_BYTE_TRANSMITTING ((uint32_t)0x00060080) /* TRA, BUSY and TXE flags */ -/* --EV3_2 */ -#define I2C_EVENT_SLAVE_ACK_FAILURE ((uint32_t)0x00000400) /* AF flag */ - -/* - =============================================================================== - End of Events Description - =============================================================================== - */ - -#define IS_I2C_EVENT(EVENT) (((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED) || \ - ((EVENT) == I2C_EVENT_SLAVE_BYTE_RECEIVED) || \ - ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF)) || \ - ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL)) || \ - ((EVENT) == I2C_EVENT_SLAVE_BYTE_TRANSMITTED) || \ - ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF)) || \ - ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL)) || \ - ((EVENT) == I2C_EVENT_SLAVE_STOP_DETECTED) || \ - ((EVENT) == I2C_EVENT_MASTER_MODE_SELECT) || \ - ((EVENT) == I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) || \ - ((EVENT) == I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) || \ - ((EVENT) == I2C_EVENT_MASTER_BYTE_RECEIVED) || \ - ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTED) || \ - ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTING) || \ - ((EVENT) == I2C_EVENT_MASTER_MODE_ADDRESS10) || \ - ((EVENT) == I2C_EVENT_SLAVE_ACK_FAILURE)) -/** - * @} - */ - -/** @defgroup I2C_own_address1 - * @{ - */ - -#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x3FF) -/** - * @} - */ - -/** @defgroup I2C_clock_speed - * @{ - */ - -#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) >= 0x1) && ((SPEED) <= 400000)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the I2C configuration to the default reset state *****/ -void I2C_DeInit(I2C_TypeDef* I2Cx); - -/* Initialization and Configuration functions *********************************/ -void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct); -void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct); -void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction); -void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address); -void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle); -void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition); -void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert); -void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); - -/* Data transfers functions ***************************************************/ -void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data); -uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx); - -/* PEC management functions ***************************************************/ -void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition); -void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState); -uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx); - -/* DMA transfers management functions *****************************************/ -void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState); -void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState); - -/* Interrupts, events and flags management functions **************************/ -uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register); -void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState); - -/* - =============================================================================== - I2C State Monitoring Functions - =============================================================================== - This I2C driver provides three different ways for I2C state monitoring - depending on the application requirements and constraints: - - - 1. Basic state monitoring (Using I2C_CheckEvent() function) - ----------------------------------------------------------- - It compares the status registers (SR1 and SR2) content to a given event - (can be the combination of one or more flags). - It returns SUCCESS if the current status includes the given flags - and returns ERROR if one or more flags are missing in the current status. - - - When to use - - This function is suitable for most applications as well as for startup - activity since the events are fully described in the product reference - manual (RM0090). - - It is also suitable for users who need to define their own events. - - - Limitations - - If an error occurs (ie. error flags are set besides to the monitored - flags), the I2C_CheckEvent() function may return SUCCESS despite - the communication hold or corrupted real state. - In this case, it is advised to use error interrupts to monitor - the error events and handle them in the interrupt IRQ handler. - - Note - For error management, it is advised to use the following functions: - - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR). - - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs. - Where x is the peripheral instance (I2C1, I2C2 ...) - - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into the - I2Cx_ER_IRQHandler() function in order to determine which error occurred. - - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd() - and/or I2C_GenerateStop() in order to clear the error flag and source - and return to correct communication status. - - - 2. Advanced state monitoring (Using the function I2C_GetLastEvent()) - -------------------------------------------------------------------- - Using the function I2C_GetLastEvent() which returns the image of both status - registers in a single word (uint32_t) (Status Register 2 value is shifted left - by 16 bits and concatenated to Status Register 1). - - - When to use - - This function is suitable for the same applications above but it - allows to overcome the mentioned limitation of I2C_GetFlagStatus() - function. - - The returned value could be compared to events already defined in - this file or to custom values defined by user. - This function is suitable when multiple flags are monitored at the - same time. - - At the opposite of I2C_CheckEvent() function, this function allows - user to choose when an event is accepted (when all events flags are - set and no other flags are set or just when the needed flags are set - like I2C_CheckEvent() function. - - - Limitations - - User may need to define his own events. - - Same remark concerning the error management is applicable for this - function if user decides to check only regular communication flags - (and ignores error flags). - - - 3. Flag-based state monitoring (Using the function I2C_GetFlagStatus()) - ----------------------------------------------------------------------- - - Using the function I2C_GetFlagStatus() which simply returns the status of - one single flag (ie. I2C_FLAG_RXNE ...). - - - When to use - - This function could be used for specific applications or in debug - phase. - - It is suitable when only one flag checking is needed (most I2C - events are monitored through multiple flags). - - Limitations: - - When calling this function, the Status register is accessed. - Some flags are cleared when the status register is accessed. - So checking the status of one Flag, may clear other ones. - - Function may need to be called twice or more in order to monitor - one single event. - */ - -/* - =============================================================================== - 1. Basic state monitoring - =============================================================================== - */ -ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT); -/* - =============================================================================== - 2. Advanced state monitoring - =============================================================================== - */ -uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx); -/* - =============================================================================== - 3. Flag-based state monitoring - =============================================================================== - */ -FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); - - -void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG); -ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT); -void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F4xx_I2C_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_iwdg.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_iwdg.h deleted file mode 100644 index 3b034304f..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_iwdg.h +++ /dev/null @@ -1,125 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_iwdg.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the IWDG - * firmware library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_IWDG_H -#define __STM32F4xx_IWDG_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup IWDG - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup IWDG_Exported_Constants - * @{ - */ - -/** @defgroup IWDG_WriteAccess - * @{ - */ -#define IWDG_WriteAccess_Enable ((uint16_t)0x5555) -#define IWDG_WriteAccess_Disable ((uint16_t)0x0000) -#define IS_IWDG_WRITE_ACCESS(ACCESS) (((ACCESS) == IWDG_WriteAccess_Enable) || \ - ((ACCESS) == IWDG_WriteAccess_Disable)) -/** - * @} - */ - -/** @defgroup IWDG_prescaler - * @{ - */ -#define IWDG_Prescaler_4 ((uint8_t)0x00) -#define IWDG_Prescaler_8 ((uint8_t)0x01) -#define IWDG_Prescaler_16 ((uint8_t)0x02) -#define IWDG_Prescaler_32 ((uint8_t)0x03) -#define IWDG_Prescaler_64 ((uint8_t)0x04) -#define IWDG_Prescaler_128 ((uint8_t)0x05) -#define IWDG_Prescaler_256 ((uint8_t)0x06) -#define IS_IWDG_PRESCALER(PRESCALER) (((PRESCALER) == IWDG_Prescaler_4) || \ - ((PRESCALER) == IWDG_Prescaler_8) || \ - ((PRESCALER) == IWDG_Prescaler_16) || \ - ((PRESCALER) == IWDG_Prescaler_32) || \ - ((PRESCALER) == IWDG_Prescaler_64) || \ - ((PRESCALER) == IWDG_Prescaler_128)|| \ - ((PRESCALER) == IWDG_Prescaler_256)) -/** - * @} - */ - -/** @defgroup IWDG_Flag - * @{ - */ -#define IWDG_FLAG_PVU ((uint16_t)0x0001) -#define IWDG_FLAG_RVU ((uint16_t)0x0002) -#define IS_IWDG_FLAG(FLAG) (((FLAG) == IWDG_FLAG_PVU) || ((FLAG) == IWDG_FLAG_RVU)) -#define IS_IWDG_RELOAD(RELOAD) ((RELOAD) <= 0xFFF) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Prescaler and Counter configuration functions ******************************/ -void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess); -void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); -void IWDG_SetReload(uint16_t Reload); -void IWDG_ReloadCounter(void); - -/* IWDG activation function ***************************************************/ -void IWDG_Enable(void); - -/* Flag management function ***************************************************/ -FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_IWDG_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_pwr.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_pwr.h deleted file mode 100644 index bf25ef2e5..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_pwr.h +++ /dev/null @@ -1,163 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_pwr.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the PWR firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_PWR_H -#define __STM32F4xx_PWR_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup PWR - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup PWR_Exported_Constants - * @{ - */ - -/** @defgroup PWR_PVD_detection_level - * @{ - */ - -#define PWR_PVDLevel_0 PWR_CR_PLS_LEV0 -#define PWR_PVDLevel_1 PWR_CR_PLS_LEV1 -#define PWR_PVDLevel_2 PWR_CR_PLS_LEV2 -#define PWR_PVDLevel_3 PWR_CR_PLS_LEV3 -#define PWR_PVDLevel_4 PWR_CR_PLS_LEV4 -#define PWR_PVDLevel_5 PWR_CR_PLS_LEV5 -#define PWR_PVDLevel_6 PWR_CR_PLS_LEV6 -#define PWR_PVDLevel_7 PWR_CR_PLS_LEV7 - -#define IS_PWR_PVD_LEVEL(LEVEL) (((LEVEL) == PWR_PVDLevel_0) || ((LEVEL) == PWR_PVDLevel_1)|| \ - ((LEVEL) == PWR_PVDLevel_2) || ((LEVEL) == PWR_PVDLevel_3)|| \ - ((LEVEL) == PWR_PVDLevel_4) || ((LEVEL) == PWR_PVDLevel_5)|| \ - ((LEVEL) == PWR_PVDLevel_6) || ((LEVEL) == PWR_PVDLevel_7)) -/** - * @} - */ - - -/** @defgroup PWR_Regulator_state_in_STOP_mode - * @{ - */ - -#define PWR_Regulator_ON ((uint32_t)0x00000000) -#define PWR_Regulator_LowPower PWR_CR_LPDS -#define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_Regulator_ON) || \ - ((REGULATOR) == PWR_Regulator_LowPower)) -/** - * @} - */ - -/** @defgroup PWR_STOP_mode_entry - * @{ - */ - -#define PWR_STOPEntry_WFI ((uint8_t)0x01) -#define PWR_STOPEntry_WFE ((uint8_t)0x02) -#define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPEntry_WFI) || ((ENTRY) == PWR_STOPEntry_WFE)) - -/** - * @} - */ - -/** @defgroup PWR_Flag - * @{ - */ - -#define PWR_FLAG_WU PWR_CSR_WUF -#define PWR_FLAG_SB PWR_CSR_SBF -#define PWR_FLAG_PVDO PWR_CSR_PVDO -#define PWR_FLAG_BRR PWR_CSR_BRR -#define PWR_FLAG_REGRDY PWR_CSR_REGRDY - -#define IS_PWR_GET_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB) || \ - ((FLAG) == PWR_FLAG_PVDO) || ((FLAG) == PWR_FLAG_BRR) || \ - ((FLAG) == PWR_FLAG_REGRDY)) - -#define IS_PWR_CLEAR_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the PWR configuration to the default reset state ******/ -void PWR_DeInit(void); - -/* Backup Domain Access function **********************************************/ -void PWR_BackupAccessCmd(FunctionalState NewState); - -/* PVD configuration functions ************************************************/ -void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel); -void PWR_PVDCmd(FunctionalState NewState); - -/* WakeUp pins configuration functions ****************************************/ -void PWR_WakeUpPinCmd(FunctionalState NewState); - -/* Backup Regulator configuration functions ***********************************/ -void PWR_BackupRegulatorCmd(FunctionalState NewState); - -/* Performance Mode and FLASH Power Down configuration functions **************/ -void PWR_HighPerformanceModeCmd(FunctionalState NewState); -void PWR_FlashPowerDownCmd(FunctionalState NewState); - -/* Low Power modes configuration functions ************************************/ -void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry); -void PWR_EnterSTANDBYMode(void); - -/* Flags management functions *************************************************/ -FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG); -void PWR_ClearFlag(uint32_t PWR_FLAG); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_PWR_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rcc.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rcc.h deleted file mode 100644 index 914408afb..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rcc.h +++ /dev/null @@ -1,509 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_rcc.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the RCC firmware library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_RCC_H -#define __STM32F4xx_RCC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup RCC - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -typedef struct -{ - uint32_t SYSCLK_Frequency; /*!< SYSCLK clock frequency expressed in Hz */ - uint32_t HCLK_Frequency; /*!< HCLK clock frequency expressed in Hz */ - uint32_t PCLK1_Frequency; /*!< PCLK1 clock frequency expressed in Hz */ - uint32_t PCLK2_Frequency; /*!< PCLK2 clock frequency expressed in Hz */ -}RCC_ClocksTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup RCC_Exported_Constants - * @{ - */ - -/** @defgroup RCC_HSE_configuration - * @{ - */ -#define RCC_HSE_OFF ((uint8_t)0x00) -#define RCC_HSE_ON ((uint8_t)0x01) -#define RCC_HSE_Bypass ((uint8_t)0x05) -#define IS_RCC_HSE(HSE) (((HSE) == RCC_HSE_OFF) || ((HSE) == RCC_HSE_ON) || \ - ((HSE) == RCC_HSE_Bypass)) -/** - * @} - */ - -/** @defgroup RCC_PLL_Clock_Source - * @{ - */ -#define RCC_PLLSource_HSI ((uint32_t)0x00000000) -#define RCC_PLLSource_HSE ((uint32_t)0x00400000) -#define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI) || \ - ((SOURCE) == RCC_PLLSource_HSE)) -#define IS_RCC_PLLM_VALUE(VALUE) ((VALUE) <= 63) -#define IS_RCC_PLLN_VALUE(VALUE) ((192 <= (VALUE)) && ((VALUE) <= 432)) -#define IS_RCC_PLLP_VALUE(VALUE) (((VALUE) == 2) || ((VALUE) == 4) || ((VALUE) == 6) || ((VALUE) == 8)) -#define IS_RCC_PLLQ_VALUE(VALUE) ((4 <= (VALUE)) && ((VALUE) <= 15)) - -#define IS_RCC_PLLI2SN_VALUE(VALUE) ((192 <= (VALUE)) && ((VALUE) <= 432)) -#define IS_RCC_PLLI2SR_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 7)) -/** - * @} - */ - -/** @defgroup RCC_System_Clock_Source - * @{ - */ -#define RCC_SYSCLKSource_HSI ((uint32_t)0x00000000) -#define RCC_SYSCLKSource_HSE ((uint32_t)0x00000001) -#define RCC_SYSCLKSource_PLLCLK ((uint32_t)0x00000002) -#define IS_RCC_SYSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSource_HSI) || \ - ((SOURCE) == RCC_SYSCLKSource_HSE) || \ - ((SOURCE) == RCC_SYSCLKSource_PLLCLK)) -/** - * @} - */ - -/** @defgroup RCC_AHB_Clock_Source - * @{ - */ -#define RCC_SYSCLK_Div1 ((uint32_t)0x00000000) -#define RCC_SYSCLK_Div2 ((uint32_t)0x00000080) -#define RCC_SYSCLK_Div4 ((uint32_t)0x00000090) -#define RCC_SYSCLK_Div8 ((uint32_t)0x000000A0) -#define RCC_SYSCLK_Div16 ((uint32_t)0x000000B0) -#define RCC_SYSCLK_Div64 ((uint32_t)0x000000C0) -#define RCC_SYSCLK_Div128 ((uint32_t)0x000000D0) -#define RCC_SYSCLK_Div256 ((uint32_t)0x000000E0) -#define RCC_SYSCLK_Div512 ((uint32_t)0x000000F0) -#define IS_RCC_HCLK(HCLK) (((HCLK) == RCC_SYSCLK_Div1) || ((HCLK) == RCC_SYSCLK_Div2) || \ - ((HCLK) == RCC_SYSCLK_Div4) || ((HCLK) == RCC_SYSCLK_Div8) || \ - ((HCLK) == RCC_SYSCLK_Div16) || ((HCLK) == RCC_SYSCLK_Div64) || \ - ((HCLK) == RCC_SYSCLK_Div128) || ((HCLK) == RCC_SYSCLK_Div256) || \ - ((HCLK) == RCC_SYSCLK_Div512)) -/** - * @} - */ - -/** @defgroup RCC_APB1_APB2_Clock_Source - * @{ - */ -#define RCC_HCLK_Div1 ((uint32_t)0x00000000) -#define RCC_HCLK_Div2 ((uint32_t)0x00001000) -#define RCC_HCLK_Div4 ((uint32_t)0x00001400) -#define RCC_HCLK_Div8 ((uint32_t)0x00001800) -#define RCC_HCLK_Div16 ((uint32_t)0x00001C00) -#define IS_RCC_PCLK(PCLK) (((PCLK) == RCC_HCLK_Div1) || ((PCLK) == RCC_HCLK_Div2) || \ - ((PCLK) == RCC_HCLK_Div4) || ((PCLK) == RCC_HCLK_Div8) || \ - ((PCLK) == RCC_HCLK_Div16)) -/** - * @} - */ - -/** @defgroup RCC_Interrupt_Source - * @{ - */ -#define RCC_IT_LSIRDY ((uint8_t)0x01) -#define RCC_IT_LSERDY ((uint8_t)0x02) -#define RCC_IT_HSIRDY ((uint8_t)0x04) -#define RCC_IT_HSERDY ((uint8_t)0x08) -#define RCC_IT_PLLRDY ((uint8_t)0x10) -#define RCC_IT_PLLI2SRDY ((uint8_t)0x20) -#define RCC_IT_CSS ((uint8_t)0x80) -#define IS_RCC_IT(IT) ((((IT) & (uint8_t)0xC0) == 0x00) && ((IT) != 0x00)) -#define IS_RCC_GET_IT(IT) (((IT) == RCC_IT_LSIRDY) || ((IT) == RCC_IT_LSERDY) || \ - ((IT) == RCC_IT_HSIRDY) || ((IT) == RCC_IT_HSERDY) || \ - ((IT) == RCC_IT_PLLRDY) || ((IT) == RCC_IT_CSS) || \ - ((IT) == RCC_IT_PLLI2SRDY)) -#define IS_RCC_CLEAR_IT(IT) ((((IT) & (uint8_t)0x40) == 0x00) && ((IT) != 0x00)) -/** - * @} - */ - -/** @defgroup RCC_LSE_Configuration - * @{ - */ -#define RCC_LSE_OFF ((uint8_t)0x00) -#define RCC_LSE_ON ((uint8_t)0x01) -#define RCC_LSE_Bypass ((uint8_t)0x04) -#define IS_RCC_LSE(LSE) (((LSE) == RCC_LSE_OFF) || ((LSE) == RCC_LSE_ON) || \ - ((LSE) == RCC_LSE_Bypass)) -/** - * @} - */ - -/** @defgroup RCC_RTC_Clock_Source - * @{ - */ -#define RCC_RTCCLKSource_LSE ((uint32_t)0x00000100) -#define RCC_RTCCLKSource_LSI ((uint32_t)0x00000200) -#define RCC_RTCCLKSource_HSE_Div2 ((uint32_t)0x00020300) -#define RCC_RTCCLKSource_HSE_Div3 ((uint32_t)0x00030300) -#define RCC_RTCCLKSource_HSE_Div4 ((uint32_t)0x00040300) -#define RCC_RTCCLKSource_HSE_Div5 ((uint32_t)0x00050300) -#define RCC_RTCCLKSource_HSE_Div6 ((uint32_t)0x00060300) -#define RCC_RTCCLKSource_HSE_Div7 ((uint32_t)0x00070300) -#define RCC_RTCCLKSource_HSE_Div8 ((uint32_t)0x00080300) -#define RCC_RTCCLKSource_HSE_Div9 ((uint32_t)0x00090300) -#define RCC_RTCCLKSource_HSE_Div10 ((uint32_t)0x000A0300) -#define RCC_RTCCLKSource_HSE_Div11 ((uint32_t)0x000B0300) -#define RCC_RTCCLKSource_HSE_Div12 ((uint32_t)0x000C0300) -#define RCC_RTCCLKSource_HSE_Div13 ((uint32_t)0x000D0300) -#define RCC_RTCCLKSource_HSE_Div14 ((uint32_t)0x000E0300) -#define RCC_RTCCLKSource_HSE_Div15 ((uint32_t)0x000F0300) -#define RCC_RTCCLKSource_HSE_Div16 ((uint32_t)0x00100300) -#define RCC_RTCCLKSource_HSE_Div17 ((uint32_t)0x00110300) -#define RCC_RTCCLKSource_HSE_Div18 ((uint32_t)0x00120300) -#define RCC_RTCCLKSource_HSE_Div19 ((uint32_t)0x00130300) -#define RCC_RTCCLKSource_HSE_Div20 ((uint32_t)0x00140300) -#define RCC_RTCCLKSource_HSE_Div21 ((uint32_t)0x00150300) -#define RCC_RTCCLKSource_HSE_Div22 ((uint32_t)0x00160300) -#define RCC_RTCCLKSource_HSE_Div23 ((uint32_t)0x00170300) -#define RCC_RTCCLKSource_HSE_Div24 ((uint32_t)0x00180300) -#define RCC_RTCCLKSource_HSE_Div25 ((uint32_t)0x00190300) -#define RCC_RTCCLKSource_HSE_Div26 ((uint32_t)0x001A0300) -#define RCC_RTCCLKSource_HSE_Div27 ((uint32_t)0x001B0300) -#define RCC_RTCCLKSource_HSE_Div28 ((uint32_t)0x001C0300) -#define RCC_RTCCLKSource_HSE_Div29 ((uint32_t)0x001D0300) -#define RCC_RTCCLKSource_HSE_Div30 ((uint32_t)0x001E0300) -#define RCC_RTCCLKSource_HSE_Div31 ((uint32_t)0x001F0300) -#define IS_RCC_RTCCLK_SOURCE(SOURCE) (((SOURCE) == RCC_RTCCLKSource_LSE) || \ - ((SOURCE) == RCC_RTCCLKSource_LSI) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div2) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div3) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div4) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div5) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div6) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div7) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div8) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div9) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div10) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div11) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div12) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div13) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div14) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div15) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div16) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div17) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div18) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div19) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div20) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div21) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div22) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div23) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div24) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div25) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div26) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div27) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div28) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div29) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div30) || \ - ((SOURCE) == RCC_RTCCLKSource_HSE_Div31)) -/** - * @} - */ - -/** @defgroup RCC_I2S_Clock_Source - * @{ - */ -#define RCC_I2S2CLKSource_PLLI2S ((uint8_t)0x00) -#define RCC_I2S2CLKSource_Ext ((uint8_t)0x01) - -#define IS_RCC_I2SCLK_SOURCE(SOURCE) (((SOURCE) == RCC_I2S2CLKSource_PLLI2S) || ((SOURCE) == RCC_I2S2CLKSource_Ext)) -/** - * @} - */ - -/** @defgroup RCC_AHB1_Peripherals - * @{ - */ -#define RCC_AHB1Periph_GPIOA ((uint32_t)0x00000001) -#define RCC_AHB1Periph_GPIOB ((uint32_t)0x00000002) -#define RCC_AHB1Periph_GPIOC ((uint32_t)0x00000004) -#define RCC_AHB1Periph_GPIOD ((uint32_t)0x00000008) -#define RCC_AHB1Periph_GPIOE ((uint32_t)0x00000010) -#define RCC_AHB1Periph_GPIOF ((uint32_t)0x00000020) -#define RCC_AHB1Periph_GPIOG ((uint32_t)0x00000040) -#define RCC_AHB1Periph_GPIOH ((uint32_t)0x00000080) -#define RCC_AHB1Periph_GPIOI ((uint32_t)0x00000100) -#define RCC_AHB1Periph_CRC ((uint32_t)0x00001000) -#define RCC_AHB1Periph_FLITF ((uint32_t)0x00008000) -#define RCC_AHB1Periph_SRAM1 ((uint32_t)0x00010000) -#define RCC_AHB1Periph_SRAM2 ((uint32_t)0x00020000) -#define RCC_AHB1Periph_BKPSRAM ((uint32_t)0x00040000) -#define RCC_AHB1Periph_DMA1 ((uint32_t)0x00200000) -#define RCC_AHB1Periph_DMA2 ((uint32_t)0x00400000) -#define RCC_AHB1Periph_ETH_MAC ((uint32_t)0x02000000) -#define RCC_AHB1Periph_ETH_MAC_Tx ((uint32_t)0x04000000) -#define RCC_AHB1Periph_ETH_MAC_Rx ((uint32_t)0x08000000) -#define RCC_AHB1Periph_ETH_MAC_PTP ((uint32_t)0x10000000) -#define RCC_AHB1Periph_OTG_HS ((uint32_t)0x20000000) -#define RCC_AHB1Periph_OTG_HS_ULPI ((uint32_t)0x40000000) -#define IS_RCC_AHB1_CLOCK_PERIPH(PERIPH) ((((PERIPH) & 0x819BEE00) == 0x00) && ((PERIPH) != 0x00)) -#define IS_RCC_AHB1_RESET_PERIPH(PERIPH) ((((PERIPH) & 0xDD9FEE00) == 0x00) && ((PERIPH) != 0x00)) -#define IS_RCC_AHB1_LPMODE_PERIPH(PERIPH) ((((PERIPH) & 0x81986E00) == 0x00) && ((PERIPH) != 0x00)) -/** - * @} - */ - -/** @defgroup RCC_AHB2_Peripherals - * @{ - */ -#define RCC_AHB2Periph_DCMI ((uint32_t)0x00000001) -#define RCC_AHB2Periph_CRYP ((uint32_t)0x00000010) -#define RCC_AHB2Periph_HASH ((uint32_t)0x00000020) -#define RCC_AHB2Periph_RNG ((uint32_t)0x00000040) -#define RCC_AHB2Periph_OTG_FS ((uint32_t)0x00000080) -#define IS_RCC_AHB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFF0E) == 0x00) && ((PERIPH) != 0x00)) -/** - * @} - */ - -/** @defgroup RCC_AHB3_Peripherals - * @{ - */ -#define RCC_AHB3Periph_FSMC ((uint32_t)0x00000001) -#define IS_RCC_AHB3_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFFE) == 0x00) && ((PERIPH) != 0x00)) -/** - * @} - */ - -/** @defgroup RCC_APB1_Peripherals - * @{ - */ -#define RCC_APB1Periph_TIM2 ((uint32_t)0x00000001) -#define RCC_APB1Periph_TIM3 ((uint32_t)0x00000002) -#define RCC_APB1Periph_TIM4 ((uint32_t)0x00000004) -#define RCC_APB1Periph_TIM5 ((uint32_t)0x00000008) -#define RCC_APB1Periph_TIM6 ((uint32_t)0x00000010) -#define RCC_APB1Periph_TIM7 ((uint32_t)0x00000020) -#define RCC_APB1Periph_TIM12 ((uint32_t)0x00000040) -#define RCC_APB1Periph_TIM13 ((uint32_t)0x00000080) -#define RCC_APB1Periph_TIM14 ((uint32_t)0x00000100) -#define RCC_APB1Periph_WWDG ((uint32_t)0x00000800) -#define RCC_APB1Periph_SPI2 ((uint32_t)0x00004000) -#define RCC_APB1Periph_SPI3 ((uint32_t)0x00008000) -#define RCC_APB1Periph_USART2 ((uint32_t)0x00020000) -#define RCC_APB1Periph_USART3 ((uint32_t)0x00040000) -#define RCC_APB1Periph_UART4 ((uint32_t)0x00080000) -#define RCC_APB1Periph_UART5 ((uint32_t)0x00100000) -#define RCC_APB1Periph_I2C1 ((uint32_t)0x00200000) -#define RCC_APB1Periph_I2C2 ((uint32_t)0x00400000) -#define RCC_APB1Periph_I2C3 ((uint32_t)0x00800000) -#define RCC_APB1Periph_CAN1 ((uint32_t)0x02000000) -#define RCC_APB1Periph_CAN2 ((uint32_t)0x04000000) -#define RCC_APB1Periph_PWR ((uint32_t)0x10000000) -#define RCC_APB1Periph_DAC ((uint32_t)0x20000000) -#define IS_RCC_APB1_PERIPH(PERIPH) ((((PERIPH) & 0xC9013600) == 0x00) && ((PERIPH) != 0x00)) -/** - * @} - */ - -/** @defgroup RCC_APB2_Peripherals - * @{ - */ -#define RCC_APB2Periph_TIM1 ((uint32_t)0x00000001) -#define RCC_APB2Periph_TIM8 ((uint32_t)0x00000002) -#define RCC_APB2Periph_USART1 ((uint32_t)0x00000010) -#define RCC_APB2Periph_USART6 ((uint32_t)0x00000020) -#define RCC_APB2Periph_ADC ((uint32_t)0x00000100) -#define RCC_APB2Periph_ADC1 ((uint32_t)0x00000100) -#define RCC_APB2Periph_ADC2 ((uint32_t)0x00000200) -#define RCC_APB2Periph_ADC3 ((uint32_t)0x00000400) -#define RCC_APB2Periph_SDIO ((uint32_t)0x00000800) -#define RCC_APB2Periph_SPI1 ((uint32_t)0x00001000) -#define RCC_APB2Periph_SYSCFG ((uint32_t)0x00004000) -#define RCC_APB2Periph_TIM9 ((uint32_t)0x00010000) -#define RCC_APB2Periph_TIM10 ((uint32_t)0x00020000) -#define RCC_APB2Periph_TIM11 ((uint32_t)0x00040000) -#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFF8A0CC) == 0x00) && ((PERIPH) != 0x00)) -#define IS_RCC_APB2_RESET_PERIPH(PERIPH) ((((PERIPH) & 0xFFF8A6CC) == 0x00) && ((PERIPH) != 0x00)) -/** - * @} - */ - -/** @defgroup RCC_MCO1_Clock_Source_Prescaler - * @{ - */ -#define RCC_MCO1Source_HSI ((uint32_t)0x00000000) -#define RCC_MCO1Source_LSE ((uint32_t)0x00200000) -#define RCC_MCO1Source_HSE ((uint32_t)0x00400000) -#define RCC_MCO1Source_PLLCLK ((uint32_t)0x00600000) -#define RCC_MCO1Div_1 ((uint32_t)0x00000000) -#define RCC_MCO1Div_2 ((uint32_t)0x04000000) -#define RCC_MCO1Div_3 ((uint32_t)0x05000000) -#define RCC_MCO1Div_4 ((uint32_t)0x06000000) -#define RCC_MCO1Div_5 ((uint32_t)0x07000000) -#define IS_RCC_MCO1SOURCE(SOURCE) (((SOURCE) == RCC_MCO1Source_HSI) || ((SOURCE) == RCC_MCO1Source_LSE) || \ - ((SOURCE) == RCC_MCO1Source_HSE) || ((SOURCE) == RCC_MCO1Source_PLLCLK)) - -#define IS_RCC_MCO1DIV(DIV) (((DIV) == RCC_MCO1Div_1) || ((DIV) == RCC_MCO1Div_2) || \ - ((DIV) == RCC_MCO1Div_3) || ((DIV) == RCC_MCO1Div_4) || \ - ((DIV) == RCC_MCO1Div_5)) -/** - * @} - */ - -/** @defgroup RCC_MCO2_Clock_Source_Prescaler - * @{ - */ -#define RCC_MCO2Source_SYSCLK ((uint32_t)0x00000000) -#define RCC_MCO2Source_PLLI2SCLK ((uint32_t)0x40000000) -#define RCC_MCO2Source_HSE ((uint32_t)0x80000000) -#define RCC_MCO2Source_PLLCLK ((uint32_t)0xC0000000) -#define RCC_MCO2Div_1 ((uint32_t)0x00000000) -#define RCC_MCO2Div_2 ((uint32_t)0x20000000) -#define RCC_MCO2Div_3 ((uint32_t)0x28000000) -#define RCC_MCO2Div_4 ((uint32_t)0x30000000) -#define RCC_MCO2Div_5 ((uint32_t)0x38000000) -#define IS_RCC_MCO2SOURCE(SOURCE) (((SOURCE) == RCC_MCO2Source_SYSCLK) || ((SOURCE) == RCC_MCO2Source_PLLI2SCLK)|| \ - ((SOURCE) == RCC_MCO2Source_HSE) || ((SOURCE) == RCC_MCO2Source_PLLCLK)) - -#define IS_RCC_MCO2DIV(DIV) (((DIV) == RCC_MCO2Div_1) || ((DIV) == RCC_MCO2Div_2) || \ - ((DIV) == RCC_MCO2Div_3) || ((DIV) == RCC_MCO2Div_4) || \ - ((DIV) == RCC_MCO2Div_5)) -/** - * @} - */ - -/** @defgroup RCC_Flag - * @{ - */ -#define RCC_FLAG_HSIRDY ((uint8_t)0x21) -#define RCC_FLAG_HSERDY ((uint8_t)0x31) -#define RCC_FLAG_PLLRDY ((uint8_t)0x39) -#define RCC_FLAG_PLLI2SRDY ((uint8_t)0x3B) -#define RCC_FLAG_LSERDY ((uint8_t)0x41) -#define RCC_FLAG_LSIRDY ((uint8_t)0x61) -#define RCC_FLAG_BORRST ((uint8_t)0x79) -#define RCC_FLAG_PINRST ((uint8_t)0x7A) -#define RCC_FLAG_PORRST ((uint8_t)0x7B) -#define RCC_FLAG_SFTRST ((uint8_t)0x7C) -#define RCC_FLAG_IWDGRST ((uint8_t)0x7D) -#define RCC_FLAG_WWDGRST ((uint8_t)0x7E) -#define RCC_FLAG_LPWRRST ((uint8_t)0x7F) -#define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_HSIRDY) || ((FLAG) == RCC_FLAG_HSERDY) || \ - ((FLAG) == RCC_FLAG_PLLRDY) || ((FLAG) == RCC_FLAG_LSERDY) || \ - ((FLAG) == RCC_FLAG_LSIRDY) || ((FLAG) == RCC_FLAG_BORRST) || \ - ((FLAG) == RCC_FLAG_PINRST) || ((FLAG) == RCC_FLAG_PORRST) || \ - ((FLAG) == RCC_FLAG_SFTRST) || ((FLAG) == RCC_FLAG_IWDGRST)|| \ - ((FLAG) == RCC_FLAG_WWDGRST)|| ((FLAG) == RCC_FLAG_LPWRRST)|| \ - ((FLAG) == RCC_FLAG_PLLI2SRDY)) -#define IS_RCC_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x1F) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the RCC clock configuration to the default reset state */ -void RCC_DeInit(void); - -/* Internal/external clocks, PLL, CSS and MCO configuration functions *********/ -void RCC_HSEConfig(uint8_t RCC_HSE); -ErrorStatus RCC_WaitForHSEStartUp(void); -void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue); -void RCC_HSICmd(FunctionalState NewState); -void RCC_LSEConfig(uint8_t RCC_LSE); -void RCC_LSICmd(FunctionalState NewState); - -void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ); -void RCC_PLLCmd(FunctionalState NewState); -void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR); -void RCC_PLLI2SCmd(FunctionalState NewState); - -void RCC_ClockSecuritySystemCmd(FunctionalState NewState); -void RCC_MCO1Config(uint32_t RCC_MCO1Source, uint32_t RCC_MCO1Div); -void RCC_MCO2Config(uint32_t RCC_MCO2Source, uint32_t RCC_MCO2Div); - -/* System, AHB and APB busses clocks configuration functions ******************/ -void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource); -uint8_t RCC_GetSYSCLKSource(void); -void RCC_HCLKConfig(uint32_t RCC_SYSCLK); -void RCC_PCLK1Config(uint32_t RCC_HCLK); -void RCC_PCLK2Config(uint32_t RCC_HCLK); -void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks); - -/* Peripheral clocks configuration functions **********************************/ -void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource); -void RCC_RTCCLKCmd(FunctionalState NewState); -void RCC_BackupResetCmd(FunctionalState NewState); -void RCC_I2SCLKConfig(uint32_t RCC_I2SCLKSource); - -void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); -void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); -void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); -void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); -void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); - -void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); -void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); -void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); -void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); -void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); - -void RCC_AHB1PeriphClockLPModeCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); -void RCC_AHB2PeriphClockLPModeCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); -void RCC_AHB3PeriphClockLPModeCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); -void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); -void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); - -/* Interrupts and flags management functions **********************************/ -void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState); -FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG); -void RCC_ClearFlag(void); -ITStatus RCC_GetITStatus(uint8_t RCC_IT); -void RCC_ClearITPendingBit(uint8_t RCC_IT); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_RCC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rng.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rng.h deleted file mode 100644 index 63f9185fc..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rng.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_rng.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the Random - * Number Generator(RNG) firmware library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_RNG_H -#define __STM32F4xx_RNG_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup RNG - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup RNG_Exported_Constants - * @{ - */ - -/** @defgroup RNG_flags_definition - * @{ - */ -#define RNG_FLAG_DRDY ((uint8_t)0x0001) /*!< Data ready */ -#define RNG_FLAG_CECS ((uint8_t)0x0002) /*!< Clock error current status */ -#define RNG_FLAG_SECS ((uint8_t)0x0004) /*!< Seed error current status */ - -#define IS_RNG_GET_FLAG(RNG_FLAG) (((RNG_FLAG) == RNG_FLAG_DRDY) || \ - ((RNG_FLAG) == RNG_FLAG_CECS) || \ - ((RNG_FLAG) == RNG_FLAG_SECS)) -#define IS_RNG_CLEAR_FLAG(RNG_FLAG) (((RNG_FLAG) == RNG_FLAG_CECS) || \ - ((RNG_FLAG) == RNG_FLAG_SECS)) -/** - * @} - */ - -/** @defgroup RNG_interrupts_definition - * @{ - */ -#define RNG_IT_CEI ((uint8_t)0x20) /*!< Clock error interrupt */ -#define RNG_IT_SEI ((uint8_t)0x40) /*!< Seed error interrupt */ - -#define IS_RNG_IT(IT) ((((IT) & (uint8_t)0x9F) == 0x00) && ((IT) != 0x00)) -#define IS_RNG_GET_IT(RNG_IT) (((RNG_IT) == RNG_IT_CEI) || ((RNG_IT) == RNG_IT_SEI)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the RNG configuration to the default reset state *****/ -void RNG_DeInit(void); - -/* Configuration function *****************************************************/ -void RNG_Cmd(FunctionalState NewState); - -/* Get 32 bit Random number function ******************************************/ -uint32_t RNG_GetRandomNumber(void); - -/* Interrupts and flags management functions **********************************/ -void RNG_ITConfig(FunctionalState NewState); -FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG); -void RNG_ClearFlag(uint8_t RNG_FLAG); -ITStatus RNG_GetITStatus(uint8_t RNG_IT); -void RNG_ClearITPendingBit(uint8_t RNG_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F4xx_RNG_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rtc.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rtc.h deleted file mode 100644 index 9daafc7bd..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rtc.h +++ /dev/null @@ -1,875 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_rtc.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the RTC firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_RTC_H -#define __STM32F4xx_RTC_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup RTC - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief RTC Init structures definition - */ -typedef struct -{ - uint32_t RTC_HourFormat; /*!< Specifies the RTC Hour Format. - This parameter can be a value of @ref RTC_Hour_Formats */ - - uint32_t RTC_AsynchPrediv; /*!< Specifies the RTC Asynchronous Predivider value. - This parameter must be set to a value lower than 0x7F */ - - uint32_t RTC_SynchPrediv; /*!< Specifies the RTC Synchronous Predivider value. - This parameter must be set to a value lower than 0x7FFF */ -}RTC_InitTypeDef; - -/** - * @brief RTC Time structure definition - */ -typedef struct -{ - uint8_t RTC_Hours; /*!< Specifies the RTC Time Hour. - This parameter must be set to a value in the 0-12 range - if the RTC_HourFormat_12 is selected or 0-23 range if - the RTC_HourFormat_24 is selected. */ - - uint8_t RTC_Minutes; /*!< Specifies the RTC Time Minutes. - This parameter must be set to a value in the 0-59 range. */ - - uint8_t RTC_Seconds; /*!< Specifies the RTC Time Seconds. - This parameter must be set to a value in the 0-59 range. */ - - uint8_t RTC_H12; /*!< Specifies the RTC AM/PM Time. - This parameter can be a value of @ref RTC_AM_PM_Definitions */ -}RTC_TimeTypeDef; - -/** - * @brief RTC Date structure definition - */ -typedef struct -{ - uint8_t RTC_WeekDay; /*!< Specifies the RTC Date WeekDay. - This parameter can be a value of @ref RTC_WeekDay_Definitions */ - - uint8_t RTC_Month; /*!< Specifies the RTC Date Month (in BCD format). - This parameter can be a value of @ref RTC_Month_Date_Definitions */ - - uint8_t RTC_Date; /*!< Specifies the RTC Date. - This parameter must be set to a value in the 1-31 range. */ - - uint8_t RTC_Year; /*!< Specifies the RTC Date Year. - This parameter must be set to a value in the 0-99 range. */ -}RTC_DateTypeDef; - -/** - * @brief RTC Alarm structure definition - */ -typedef struct -{ - RTC_TimeTypeDef RTC_AlarmTime; /*!< Specifies the RTC Alarm Time members. */ - - uint32_t RTC_AlarmMask; /*!< Specifies the RTC Alarm Masks. - This parameter can be a value of @ref RTC_AlarmMask_Definitions */ - - uint32_t RTC_AlarmDateWeekDaySel; /*!< Specifies the RTC Alarm is on Date or WeekDay. - This parameter can be a value of @ref RTC_AlarmDateWeekDay_Definitions */ - - uint8_t RTC_AlarmDateWeekDay; /*!< Specifies the RTC Alarm Date/WeekDay. - If the Alarm Date is selected, this parameter - must be set to a value in the 1-31 range. - If the Alarm WeekDay is selected, this - parameter can be a value of @ref RTC_WeekDay_Definitions */ -}RTC_AlarmTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup RTC_Exported_Constants - * @{ - */ - - -/** @defgroup RTC_Hour_Formats - * @{ - */ -#define RTC_HourFormat_24 ((uint32_t)0x00000000) -#define RTC_HourFormat_12 ((uint32_t)0x00000040) -#define IS_RTC_HOUR_FORMAT(FORMAT) (((FORMAT) == RTC_HourFormat_12) || \ - ((FORMAT) == RTC_HourFormat_24)) -/** - * @} - */ - -/** @defgroup RTC_Asynchronous_Predivider - * @{ - */ -#define IS_RTC_ASYNCH_PREDIV(PREDIV) ((PREDIV) <= 0x7F) - -/** - * @} - */ - - -/** @defgroup RTC_Synchronous_Predivider - * @{ - */ -#define IS_RTC_SYNCH_PREDIV(PREDIV) ((PREDIV) <= 0x7FFF) - -/** - * @} - */ - -/** @defgroup RTC_Time_Definitions - * @{ - */ -#define IS_RTC_HOUR12(HOUR) (((HOUR) > 0) && ((HOUR) <= 12)) -#define IS_RTC_HOUR24(HOUR) ((HOUR) <= 23) -#define IS_RTC_MINUTES(MINUTES) ((MINUTES) <= 59) -#define IS_RTC_SECONDS(SECONDS) ((SECONDS) <= 59) - -/** - * @} - */ - -/** @defgroup RTC_AM_PM_Definitions - * @{ - */ -#define RTC_H12_AM ((uint8_t)0x00) -#define RTC_H12_PM ((uint8_t)0x40) -#define IS_RTC_H12(PM) (((PM) == RTC_H12_AM) || ((PM) == RTC_H12_PM)) - -/** - * @} - */ - -/** @defgroup RTC_Year_Date_Definitions - * @{ - */ -#define IS_RTC_YEAR(YEAR) ((YEAR) <= 99) - -/** - * @} - */ - -/** @defgroup RTC_Month_Date_Definitions - * @{ - */ - -/* Coded in BCD format */ -#define RTC_Month_January ((uint8_t)0x01) -#define RTC_Month_February ((uint8_t)0x02) -#define RTC_Month_March ((uint8_t)0x03) -#define RTC_Month_April ((uint8_t)0x04) -#define RTC_Month_May ((uint8_t)0x05) -#define RTC_Month_June ((uint8_t)0x06) -#define RTC_Month_July ((uint8_t)0x07) -#define RTC_Month_August ((uint8_t)0x08) -#define RTC_Month_September ((uint8_t)0x09) -#define RTC_Month_October ((uint8_t)0x10) -#define RTC_Month_November ((uint8_t)0x11) -#define RTC_Month_December ((uint8_t)0x12) -#define IS_RTC_MONTH(MONTH) (((MONTH) >= 1) && ((MONTH) <= 12)) -#define IS_RTC_DATE(DATE) (((DATE) >= 1) && ((DATE) <= 31)) - -/** - * @} - */ - -/** @defgroup RTC_WeekDay_Definitions - * @{ - */ - -#define RTC_Weekday_Monday ((uint8_t)0x01) -#define RTC_Weekday_Tuesday ((uint8_t)0x02) -#define RTC_Weekday_Wednesday ((uint8_t)0x03) -#define RTC_Weekday_Thursday ((uint8_t)0x04) -#define RTC_Weekday_Friday ((uint8_t)0x05) -#define RTC_Weekday_Saturday ((uint8_t)0x06) -#define RTC_Weekday_Sunday ((uint8_t)0x07) -#define IS_RTC_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_Weekday_Monday) || \ - ((WEEKDAY) == RTC_Weekday_Tuesday) || \ - ((WEEKDAY) == RTC_Weekday_Wednesday) || \ - ((WEEKDAY) == RTC_Weekday_Thursday) || \ - ((WEEKDAY) == RTC_Weekday_Friday) || \ - ((WEEKDAY) == RTC_Weekday_Saturday) || \ - ((WEEKDAY) == RTC_Weekday_Sunday)) -/** - * @} - */ - - -/** @defgroup RTC_Alarm_Definitions - * @{ - */ -#define IS_RTC_ALARM_DATE_WEEKDAY_DATE(DATE) (((DATE) > 0) && ((DATE) <= 31)) -#define IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_Weekday_Monday) || \ - ((WEEKDAY) == RTC_Weekday_Tuesday) || \ - ((WEEKDAY) == RTC_Weekday_Wednesday) || \ - ((WEEKDAY) == RTC_Weekday_Thursday) || \ - ((WEEKDAY) == RTC_Weekday_Friday) || \ - ((WEEKDAY) == RTC_Weekday_Saturday) || \ - ((WEEKDAY) == RTC_Weekday_Sunday)) - -/** - * @} - */ - - -/** @defgroup RTC_AlarmDateWeekDay_Definitions - * @{ - */ -#define RTC_AlarmDateWeekDaySel_Date ((uint32_t)0x00000000) -#define RTC_AlarmDateWeekDaySel_WeekDay ((uint32_t)0x40000000) - -#define IS_RTC_ALARM_DATE_WEEKDAY_SEL(SEL) (((SEL) == RTC_AlarmDateWeekDaySel_Date) || \ - ((SEL) == RTC_AlarmDateWeekDaySel_WeekDay)) - -/** - * @} - */ - - -/** @defgroup RTC_AlarmMask_Definitions - * @{ - */ -#define RTC_AlarmMask_None ((uint32_t)0x00000000) -#define RTC_AlarmMask_DateWeekDay ((uint32_t)0x80000000) -#define RTC_AlarmMask_Hours ((uint32_t)0x00800000) -#define RTC_AlarmMask_Minutes ((uint32_t)0x00008000) -#define RTC_AlarmMask_Seconds ((uint32_t)0x00000080) -#define RTC_AlarmMask_All ((uint32_t)0x80808080) -#define IS_ALARM_MASK(MASK) (((MASK) & 0x7F7F7F7F) == (uint32_t)RESET) - -/** - * @} - */ - -/** @defgroup RTC_Alarms_Definitions - * @{ - */ -#define RTC_Alarm_A ((uint32_t)0x00000100) -#define RTC_Alarm_B ((uint32_t)0x00000200) -#define IS_RTC_ALARM(ALARM) (((ALARM) == RTC_Alarm_A) || ((ALARM) == RTC_Alarm_B)) -#define IS_RTC_CMD_ALARM(ALARM) (((ALARM) & (RTC_Alarm_A | RTC_Alarm_B)) != (uint32_t)RESET) - -/** - * @} - */ - - /** @defgroup RTC_Alarm_Sub_Seconds_Masks_Definitions - * @{ - */ -#define RTC_AlarmSubSecondMask_All ((uint32_t)0x00000000) /*!< All Alarm SS fields are masked. - There is no comparison on sub seconds - for Alarm */ -#define RTC_AlarmSubSecondMask_SS14_1 ((uint32_t)0x01000000) /*!< SS[14:1] are don't care in Alarm - comparison. Only SS[0] is compared. */ -#define RTC_AlarmSubSecondMask_SS14_2 ((uint32_t)0x02000000) /*!< SS[14:2] are don't care in Alarm - comparison. Only SS[1:0] are compared */ -#define RTC_AlarmSubSecondMask_SS14_3 ((uint32_t)0x03000000) /*!< SS[14:3] are don't care in Alarm - comparison. Only SS[2:0] are compared */ -#define RTC_AlarmSubSecondMask_SS14_4 ((uint32_t)0x04000000) /*!< SS[14:4] are don't care in Alarm - comparison. Only SS[3:0] are compared */ -#define RTC_AlarmSubSecondMask_SS14_5 ((uint32_t)0x05000000) /*!< SS[14:5] are don't care in Alarm - comparison. Only SS[4:0] are compared */ -#define RTC_AlarmSubSecondMask_SS14_6 ((uint32_t)0x06000000) /*!< SS[14:6] are don't care in Alarm - comparison. Only SS[5:0] are compared */ -#define RTC_AlarmSubSecondMask_SS14_7 ((uint32_t)0x07000000) /*!< SS[14:7] are don't care in Alarm - comparison. Only SS[6:0] are compared */ -#define RTC_AlarmSubSecondMask_SS14_8 ((uint32_t)0x08000000) /*!< SS[14:8] are don't care in Alarm - comparison. Only SS[7:0] are compared */ -#define RTC_AlarmSubSecondMask_SS14_9 ((uint32_t)0x09000000) /*!< SS[14:9] are don't care in Alarm - comparison. Only SS[8:0] are compared */ -#define RTC_AlarmSubSecondMask_SS14_10 ((uint32_t)0x0A000000) /*!< SS[14:10] are don't care in Alarm - comparison. Only SS[9:0] are compared */ -#define RTC_AlarmSubSecondMask_SS14_11 ((uint32_t)0x0B000000) /*!< SS[14:11] are don't care in Alarm - comparison. Only SS[10:0] are compared */ -#define RTC_AlarmSubSecondMask_SS14_12 ((uint32_t)0x0C000000) /*!< SS[14:12] are don't care in Alarm - comparison.Only SS[11:0] are compared */ -#define RTC_AlarmSubSecondMask_SS14_13 ((uint32_t)0x0D000000) /*!< SS[14:13] are don't care in Alarm - comparison. Only SS[12:0] are compared */ -#define RTC_AlarmSubSecondMask_SS14 ((uint32_t)0x0E000000) /*!< SS[14] is don't care in Alarm - comparison.Only SS[13:0] are compared */ -#define RTC_AlarmSubSecondMask_None ((uint32_t)0x0F000000) /*!< SS[14:0] are compared and must match - to activate alarm. */ -#define IS_RTC_ALARM_SUB_SECOND_MASK(MASK) (((MASK) == RTC_AlarmSubSecondMask_All) || \ - ((MASK) == RTC_AlarmSubSecondMask_SS14_1) || \ - ((MASK) == RTC_AlarmSubSecondMask_SS14_2) || \ - ((MASK) == RTC_AlarmSubSecondMask_SS14_3) || \ - ((MASK) == RTC_AlarmSubSecondMask_SS14_4) || \ - ((MASK) == RTC_AlarmSubSecondMask_SS14_5) || \ - ((MASK) == RTC_AlarmSubSecondMask_SS14_6) || \ - ((MASK) == RTC_AlarmSubSecondMask_SS14_7) || \ - ((MASK) == RTC_AlarmSubSecondMask_SS14_8) || \ - ((MASK) == RTC_AlarmSubSecondMask_SS14_9) || \ - ((MASK) == RTC_AlarmSubSecondMask_SS14_10) || \ - ((MASK) == RTC_AlarmSubSecondMask_SS14_11) || \ - ((MASK) == RTC_AlarmSubSecondMask_SS14_12) || \ - ((MASK) == RTC_AlarmSubSecondMask_SS14_13) || \ - ((MASK) == RTC_AlarmSubSecondMask_SS14) || \ - ((MASK) == RTC_AlarmSubSecondMask_None)) -/** - * @} - */ - -/** @defgroup RTC_Alarm_Sub_Seconds_Value - * @{ - */ - -#define IS_RTC_ALARM_SUB_SECOND_VALUE(VALUE) ((VALUE) <= 0x00007FFF) - -/** - * @} - */ - -/** @defgroup RTC_Wakeup_Timer_Definitions - * @{ - */ -#define RTC_WakeUpClock_RTCCLK_Div16 ((uint32_t)0x00000000) -#define RTC_WakeUpClock_RTCCLK_Div8 ((uint32_t)0x00000001) -#define RTC_WakeUpClock_RTCCLK_Div4 ((uint32_t)0x00000002) -#define RTC_WakeUpClock_RTCCLK_Div2 ((uint32_t)0x00000003) -#define RTC_WakeUpClock_CK_SPRE_16bits ((uint32_t)0x00000004) -#define RTC_WakeUpClock_CK_SPRE_17bits ((uint32_t)0x00000006) -#define IS_RTC_WAKEUP_CLOCK(CLOCK) (((CLOCK) == RTC_WakeUpClock_RTCCLK_Div16) || \ - ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div8) || \ - ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div4) || \ - ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div2) || \ - ((CLOCK) == RTC_WakeUpClock_CK_SPRE_16bits) || \ - ((CLOCK) == RTC_WakeUpClock_CK_SPRE_17bits)) -#define IS_RTC_WAKEUP_COUNTER(COUNTER) ((COUNTER) <= 0xFFFF) -/** - * @} - */ - -/** @defgroup RTC_Time_Stamp_Edges_definitions - * @{ - */ -#define RTC_TimeStampEdge_Rising ((uint32_t)0x00000000) -#define RTC_TimeStampEdge_Falling ((uint32_t)0x00000008) -#define IS_RTC_TIMESTAMP_EDGE(EDGE) (((EDGE) == RTC_TimeStampEdge_Rising) || \ - ((EDGE) == RTC_TimeStampEdge_Falling)) -/** - * @} - */ - -/** @defgroup RTC_Output_selection_Definitions - * @{ - */ -#define RTC_Output_Disable ((uint32_t)0x00000000) -#define RTC_Output_AlarmA ((uint32_t)0x00200000) -#define RTC_Output_AlarmB ((uint32_t)0x00400000) -#define RTC_Output_WakeUp ((uint32_t)0x00600000) - -#define IS_RTC_OUTPUT(OUTPUT) (((OUTPUT) == RTC_Output_Disable) || \ - ((OUTPUT) == RTC_Output_AlarmA) || \ - ((OUTPUT) == RTC_Output_AlarmB) || \ - ((OUTPUT) == RTC_Output_WakeUp)) - -/** - * @} - */ - -/** @defgroup RTC_Output_Polarity_Definitions - * @{ - */ -#define RTC_OutputPolarity_High ((uint32_t)0x00000000) -#define RTC_OutputPolarity_Low ((uint32_t)0x00100000) -#define IS_RTC_OUTPUT_POL(POL) (((POL) == RTC_OutputPolarity_High) || \ - ((POL) == RTC_OutputPolarity_Low)) -/** - * @} - */ - - -/** @defgroup RTC_Digital_Calibration_Definitions - * @{ - */ -#define RTC_CalibSign_Positive ((uint32_t)0x00000000) -#define RTC_CalibSign_Negative ((uint32_t)0x00000080) -#define IS_RTC_CALIB_SIGN(SIGN) (((SIGN) == RTC_CalibSign_Positive) || \ - ((SIGN) == RTC_CalibSign_Negative)) -#define IS_RTC_CALIB_VALUE(VALUE) ((VALUE) < 0x20) - -/** - * @} - */ - - /** @defgroup RTC_Calib_Output_selection_Definitions - * @{ - */ -#define RTC_CalibOutput_512Hz ((uint32_t)0x00000000) -#define RTC_CalibOutput_1Hz ((uint32_t)0x00080000) -#define IS_RTC_CALIB_OUTPUT(OUTPUT) (((OUTPUT) == RTC_CalibOutput_512Hz) || \ - ((OUTPUT) == RTC_CalibOutput_1Hz)) -/** - * @} - */ - -/** @defgroup RTC_Smooth_calib_period_Definitions - * @{ - */ -#define RTC_SmoothCalibPeriod_32sec ((uint32_t)0x00000000) /*!< if RTCCLK = 32768 Hz, Smooth calibation - period is 32s, else 2exp20 RTCCLK seconds */ -#define RTC_SmoothCalibPeriod_16sec ((uint32_t)0x00002000) /*!< if RTCCLK = 32768 Hz, Smooth calibation - period is 16s, else 2exp19 RTCCLK seconds */ -#define RTC_SmoothCalibPeriod_8sec ((uint32_t)0x00004000) /*!< if RTCCLK = 32768 Hz, Smooth calibation - period is 8s, else 2exp18 RTCCLK seconds */ -#define IS_RTC_SMOOTH_CALIB_PERIOD(PERIOD) (((PERIOD) == RTC_SmoothCalibPeriod_32sec) || \ - ((PERIOD) == RTC_SmoothCalibPeriod_16sec) || \ - ((PERIOD) == RTC_SmoothCalibPeriod_8sec)) - -/** - * @} - */ - -/** @defgroup RTC_Smooth_calib_Plus_pulses_Definitions - * @{ - */ -#define RTC_SmoothCalibPlusPulses_Set ((uint32_t)0x00008000) /*!< The number of RTCCLK pulses added - during a X -second window = Y - CALM[8:0]. - with Y = 512, 256, 128 when X = 32, 16, 8 */ -#define RTC_SmoothCalibPlusPulses_Reset ((uint32_t)0x00000000) /*!< The number of RTCCLK pulses subbstited - during a 32-second window = CALM[8:0]. */ -#define IS_RTC_SMOOTH_CALIB_PLUS(PLUS) (((PLUS) == RTC_SmoothCalibPlusPulses_Set) || \ - ((PLUS) == RTC_SmoothCalibPlusPulses_Reset)) - -/** - * @} - */ - -/** @defgroup RTC_Smooth_calib_Minus_pulses_Definitions - * @{ - */ -#define IS_RTC_SMOOTH_CALIB_MINUS(VALUE) ((VALUE) <= 0x000001FF) - -/** - * @} - */ - -/** @defgroup RTC_DayLightSaving_Definitions - * @{ - */ -#define RTC_DayLightSaving_SUB1H ((uint32_t)0x00020000) -#define RTC_DayLightSaving_ADD1H ((uint32_t)0x00010000) -#define IS_RTC_DAYLIGHT_SAVING(SAVE) (((SAVE) == RTC_DayLightSaving_SUB1H) || \ - ((SAVE) == RTC_DayLightSaving_ADD1H)) - -#define RTC_StoreOperation_Reset ((uint32_t)0x00000000) -#define RTC_StoreOperation_Set ((uint32_t)0x00040000) -#define IS_RTC_STORE_OPERATION(OPERATION) (((OPERATION) == RTC_StoreOperation_Reset) || \ - ((OPERATION) == RTC_StoreOperation_Set)) -/** - * @} - */ - -/** @defgroup RTC_Tamper_Trigger_Definitions - * @{ - */ -#define RTC_TamperTrigger_RisingEdge ((uint32_t)0x00000000) -#define RTC_TamperTrigger_FallingEdge ((uint32_t)0x00000001) -#define RTC_TamperTrigger_LowLevel ((uint32_t)0x00000000) -#define RTC_TamperTrigger_HighLevel ((uint32_t)0x00000001) -#define IS_RTC_TAMPER_TRIGGER(TRIGGER) (((TRIGGER) == RTC_TamperTrigger_RisingEdge) || \ - ((TRIGGER) == RTC_TamperTrigger_FallingEdge) || \ - ((TRIGGER) == RTC_TamperTrigger_LowLevel) || \ - ((TRIGGER) == RTC_TamperTrigger_HighLevel)) - -/** - * @} - */ - -/** @defgroup RTC_Tamper_Filter_Definitions - * @{ - */ -#define RTC_TamperFilter_Disable ((uint32_t)0x00000000) /*!< Tamper filter is disabled */ - -#define RTC_TamperFilter_2Sample ((uint32_t)0x00000800) /*!< Tamper is activated after 2 - consecutive samples at the active level */ -#define RTC_TamperFilter_4Sample ((uint32_t)0x00001000) /*!< Tamper is activated after 4 - consecutive samples at the active level */ -#define RTC_TamperFilter_8Sample ((uint32_t)0x00001800) /*!< Tamper is activated after 8 - consecutive samples at the active leve. */ -#define IS_RTC_TAMPER_FILTER(FILTER) (((FILTER) == RTC_TamperFilter_Disable) || \ - ((FILTER) == RTC_TamperFilter_2Sample) || \ - ((FILTER) == RTC_TamperFilter_4Sample) || \ - ((FILTER) == RTC_TamperFilter_8Sample)) -/** - * @} - */ - -/** @defgroup RTC_Tamper_Sampling_Frequencies_Definitions - * @{ - */ -#define RTC_TamperSamplingFreq_RTCCLK_Div32768 ((uint32_t)0x00000000) /*!< Each of the tamper inputs are sampled - with a frequency = RTCCLK / 32768 */ -#define RTC_TamperSamplingFreq_RTCCLK_Div16384 ((uint32_t)0x000000100) /*!< Each of the tamper inputs are sampled - with a frequency = RTCCLK / 16384 */ -#define RTC_TamperSamplingFreq_RTCCLK_Div8192 ((uint32_t)0x00000200) /*!< Each of the tamper inputs are sampled - with a frequency = RTCCLK / 8192 */ -#define RTC_TamperSamplingFreq_RTCCLK_Div4096 ((uint32_t)0x00000300) /*!< Each of the tamper inputs are sampled - with a frequency = RTCCLK / 4096 */ -#define RTC_TamperSamplingFreq_RTCCLK_Div2048 ((uint32_t)0x00000400) /*!< Each of the tamper inputs are sampled - with a frequency = RTCCLK / 2048 */ -#define RTC_TamperSamplingFreq_RTCCLK_Div1024 ((uint32_t)0x00000500) /*!< Each of the tamper inputs are sampled - with a frequency = RTCCLK / 1024 */ -#define RTC_TamperSamplingFreq_RTCCLK_Div512 ((uint32_t)0x00000600) /*!< Each of the tamper inputs are sampled - with a frequency = RTCCLK / 512 */ -#define RTC_TamperSamplingFreq_RTCCLK_Div256 ((uint32_t)0x00000700) /*!< Each of the tamper inputs are sampled - with a frequency = RTCCLK / 256 */ -#define IS_RTC_TAMPER_SAMPLING_FREQ(FREQ) (((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div32768) || \ - ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div16384) || \ - ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div8192) || \ - ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div4096) || \ - ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div2048) || \ - ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div1024) || \ - ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div512) || \ - ((FREQ) ==RTC_TamperSamplingFreq_RTCCLK_Div256)) - -/** - * @} - */ - - /** @defgroup RTC_Tamper_Pin_Precharge_Duration_Definitions - * @{ - */ -#define RTC_TamperPrechargeDuration_1RTCCLK ((uint32_t)0x00000000) /*!< Tamper pins are pre-charged before - sampling during 1 RTCCLK cycle */ -#define RTC_TamperPrechargeDuration_2RTCCLK ((uint32_t)0x00002000) /*!< Tamper pins are pre-charged before - sampling during 2 RTCCLK cycles */ -#define RTC_TamperPrechargeDuration_4RTCCLK ((uint32_t)0x00004000) /*!< Tamper pins are pre-charged before - sampling during 4 RTCCLK cycles */ -#define RTC_TamperPrechargeDuration_8RTCCLK ((uint32_t)0x00006000) /*!< Tamper pins are pre-charged before - sampling during 8 RTCCLK cycles */ - -#define IS_RTC_TAMPER_PRECHARGE_DURATION(DURATION) (((DURATION) == RTC_TamperPrechargeDuration_1RTCCLK) || \ - ((DURATION) == RTC_TamperPrechargeDuration_2RTCCLK) || \ - ((DURATION) == RTC_TamperPrechargeDuration_4RTCCLK) || \ - ((DURATION) == RTC_TamperPrechargeDuration_8RTCCLK)) -/** - * @} - */ - -/** @defgroup RTC_Tamper_Pins_Definitions - * @{ - */ -#define RTC_Tamper_1 RTC_TAFCR_TAMP1E -#define IS_RTC_TAMPER(TAMPER) (((TAMPER) == RTC_Tamper_1)) - -/** - * @} - */ - -/** @defgroup RTC_Tamper_Pin_Selection - * @{ - */ -#define RTC_TamperPin_PC13 ((uint32_t)0x00000000) -#define RTC_TamperPin_PI8 ((uint32_t)0x00010000) -#define IS_RTC_TAMPER_PIN(PIN) (((PIN) == RTC_TamperPin_PC13) || \ - ((PIN) == RTC_TamperPin_PI8)) -/** - * @} - */ - -/** @defgroup RTC_TimeStamp_Pin_Selection - * @{ - */ -#define RTC_TimeStampPin_PC13 ((uint32_t)0x00000000) -#define RTC_TimeStampPin_PI8 ((uint32_t)0x00020000) -#define IS_RTC_TIMESTAMP_PIN(PIN) (((PIN) == RTC_TimeStampPin_PC13) || \ - ((PIN) == RTC_TimeStampPin_PI8)) -/** - * @} - */ - -/** @defgroup RTC_Output_Type_ALARM_OUT - * @{ - */ -#define RTC_OutputType_OpenDrain ((uint32_t)0x00000000) -#define RTC_OutputType_PushPull ((uint32_t)0x00040000) -#define IS_RTC_OUTPUT_TYPE(TYPE) (((TYPE) == RTC_OutputType_OpenDrain) || \ - ((TYPE) == RTC_OutputType_PushPull)) - -/** - * @} - */ - -/** @defgroup RTC_Add_1_Second_Parameter_Definitions - * @{ - */ -#define RTC_ShiftAdd1S_Reset ((uint32_t)0x00000000) -#define RTC_ShiftAdd1S_Set ((uint32_t)0x80000000) -#define IS_RTC_SHIFT_ADD1S(SEL) (((SEL) == RTC_ShiftAdd1S_Reset) || \ - ((SEL) == RTC_ShiftAdd1S_Set)) -/** - * @} - */ - -/** @defgroup RTC_Substract_Fraction_Of_Second_Value - * @{ - */ -#define IS_RTC_SHIFT_SUBFS(FS) ((FS) <= 0x00007FFF) - -/** - * @} - */ - -/** @defgroup RTC_Backup_Registers_Definitions - * @{ - */ - -#define RTC_BKP_DR0 ((uint32_t)0x00000000) -#define RTC_BKP_DR1 ((uint32_t)0x00000001) -#define RTC_BKP_DR2 ((uint32_t)0x00000002) -#define RTC_BKP_DR3 ((uint32_t)0x00000003) -#define RTC_BKP_DR4 ((uint32_t)0x00000004) -#define RTC_BKP_DR5 ((uint32_t)0x00000005) -#define RTC_BKP_DR6 ((uint32_t)0x00000006) -#define RTC_BKP_DR7 ((uint32_t)0x00000007) -#define RTC_BKP_DR8 ((uint32_t)0x00000008) -#define RTC_BKP_DR9 ((uint32_t)0x00000009) -#define RTC_BKP_DR10 ((uint32_t)0x0000000A) -#define RTC_BKP_DR11 ((uint32_t)0x0000000B) -#define RTC_BKP_DR12 ((uint32_t)0x0000000C) -#define RTC_BKP_DR13 ((uint32_t)0x0000000D) -#define RTC_BKP_DR14 ((uint32_t)0x0000000E) -#define RTC_BKP_DR15 ((uint32_t)0x0000000F) -#define RTC_BKP_DR16 ((uint32_t)0x00000010) -#define RTC_BKP_DR17 ((uint32_t)0x00000011) -#define RTC_BKP_DR18 ((uint32_t)0x00000012) -#define RTC_BKP_DR19 ((uint32_t)0x00000013) -#define IS_RTC_BKP(BKP) (((BKP) == RTC_BKP_DR0) || \ - ((BKP) == RTC_BKP_DR1) || \ - ((BKP) == RTC_BKP_DR2) || \ - ((BKP) == RTC_BKP_DR3) || \ - ((BKP) == RTC_BKP_DR4) || \ - ((BKP) == RTC_BKP_DR5) || \ - ((BKP) == RTC_BKP_DR6) || \ - ((BKP) == RTC_BKP_DR7) || \ - ((BKP) == RTC_BKP_DR8) || \ - ((BKP) == RTC_BKP_DR9) || \ - ((BKP) == RTC_BKP_DR10) || \ - ((BKP) == RTC_BKP_DR11) || \ - ((BKP) == RTC_BKP_DR12) || \ - ((BKP) == RTC_BKP_DR13) || \ - ((BKP) == RTC_BKP_DR14) || \ - ((BKP) == RTC_BKP_DR15) || \ - ((BKP) == RTC_BKP_DR16) || \ - ((BKP) == RTC_BKP_DR17) || \ - ((BKP) == RTC_BKP_DR18) || \ - ((BKP) == RTC_BKP_DR19)) -/** - * @} - */ - -/** @defgroup RTC_Input_parameter_format_definitions - * @{ - */ -#define RTC_Format_BIN ((uint32_t)0x000000000) -#define RTC_Format_BCD ((uint32_t)0x000000001) -#define IS_RTC_FORMAT(FORMAT) (((FORMAT) == RTC_Format_BIN) || ((FORMAT) == RTC_Format_BCD)) - -/** - * @} - */ - -/** @defgroup RTC_Flags_Definitions - * @{ - */ -#define RTC_FLAG_RECALPF ((uint32_t)0x00010000) -#define RTC_FLAG_TAMP1F ((uint32_t)0x00002000) -#define RTC_FLAG_TSOVF ((uint32_t)0x00001000) -#define RTC_FLAG_TSF ((uint32_t)0x00000800) -#define RTC_FLAG_WUTF ((uint32_t)0x00000400) -#define RTC_FLAG_ALRBF ((uint32_t)0x00000200) -#define RTC_FLAG_ALRAF ((uint32_t)0x00000100) -#define RTC_FLAG_INITF ((uint32_t)0x00000040) -#define RTC_FLAG_RSF ((uint32_t)0x00000020) -#define RTC_FLAG_INITS ((uint32_t)0x00000010) -#define RTC_FLAG_SHPF ((uint32_t)0x00000008) -#define RTC_FLAG_WUTWF ((uint32_t)0x00000004) -#define RTC_FLAG_ALRBWF ((uint32_t)0x00000002) -#define RTC_FLAG_ALRAWF ((uint32_t)0x00000001) -#define IS_RTC_GET_FLAG(FLAG) (((FLAG) == RTC_FLAG_TSOVF) || ((FLAG) == RTC_FLAG_TSF) || \ - ((FLAG) == RTC_FLAG_WUTF) || ((FLAG) == RTC_FLAG_ALRBF) || \ - ((FLAG) == RTC_FLAG_ALRAF) || ((FLAG) == RTC_FLAG_INITF) || \ - ((FLAG) == RTC_FLAG_RSF) || ((FLAG) == RTC_FLAG_WUTWF) || \ - ((FLAG) == RTC_FLAG_ALRBWF) || ((FLAG) == RTC_FLAG_ALRAWF) || \ - ((FLAG) == RTC_FLAG_TAMP1F) || ((FLAG) == RTC_FLAG_RECALPF) || \ - ((FLAG) == RTC_FLAG_SHPF)) -#define IS_RTC_CLEAR_FLAG(FLAG) (((FLAG) != (uint32_t)RESET) && (((FLAG) & 0xFFFF00DF) == (uint32_t)RESET)) -/** - * @} - */ - -/** @defgroup RTC_Interrupts_Definitions - * @{ - */ -#define RTC_IT_TS ((uint32_t)0x00008000) -#define RTC_IT_WUT ((uint32_t)0x00004000) -#define RTC_IT_ALRB ((uint32_t)0x00002000) -#define RTC_IT_ALRA ((uint32_t)0x00001000) -#define RTC_IT_TAMP ((uint32_t)0x00000004) /* Used only to Enable the Tamper Interrupt */ -#define RTC_IT_TAMP1 ((uint32_t)0x00020000) - -#define IS_RTC_CONFIG_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFF0FFB) == (uint32_t)RESET)) -#define IS_RTC_GET_IT(IT) (((IT) == RTC_IT_TS) || ((IT) == RTC_IT_WUT) || \ - ((IT) == RTC_IT_ALRB) || ((IT) == RTC_IT_ALRA) || \ - ((IT) == RTC_IT_TAMP1)) -#define IS_RTC_CLEAR_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFD0FFF) == (uint32_t)RESET)) - -/** - * @} - */ - -/** @defgroup RTC_Legacy - * @{ - */ -#define RTC_DigitalCalibConfig RTC_CoarseCalibConfig -#define RTC_DigitalCalibCmd RTC_CoarseCalibCmd - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the RTC configuration to the default reset state *****/ -ErrorStatus RTC_DeInit(void); - -/* Initialization and Configuration functions *********************************/ -ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct); -void RTC_StructInit(RTC_InitTypeDef* RTC_InitStruct); -void RTC_WriteProtectionCmd(FunctionalState NewState); -ErrorStatus RTC_EnterInitMode(void); -void RTC_ExitInitMode(void); -ErrorStatus RTC_WaitForSynchro(void); -ErrorStatus RTC_RefClockCmd(FunctionalState NewState); -void RTC_BypassShadowCmd(FunctionalState NewState); - -/* Time and Date configuration functions **************************************/ -ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct); -void RTC_TimeStructInit(RTC_TimeTypeDef* RTC_TimeStruct); -void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct); -uint32_t RTC_GetSubSecond(void); -ErrorStatus RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct); -void RTC_DateStructInit(RTC_DateTypeDef* RTC_DateStruct); -void RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct); - -/* Alarms (Alarm A and Alarm B) configuration functions **********************/ -void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct); -void RTC_AlarmStructInit(RTC_AlarmTypeDef* RTC_AlarmStruct); -void RTC_GetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct); -ErrorStatus RTC_AlarmCmd(uint32_t RTC_Alarm, FunctionalState NewState); -void RTC_AlarmSubSecondConfig(uint32_t RTC_Alarm, uint32_t RTC_AlarmSubSecondValue, uint32_t RTC_AlarmSubSecondMask); -uint32_t RTC_GetAlarmSubSecond(uint32_t RTC_Alarm); - -/* WakeUp Timer configuration functions ***************************************/ -void RTC_WakeUpClockConfig(uint32_t RTC_WakeUpClock); -void RTC_SetWakeUpCounter(uint32_t RTC_WakeUpCounter); -uint32_t RTC_GetWakeUpCounter(void); -ErrorStatus RTC_WakeUpCmd(FunctionalState NewState); - -/* Daylight Saving configuration functions ************************************/ -void RTC_DayLightSavingConfig(uint32_t RTC_DayLightSaving, uint32_t RTC_StoreOperation); -uint32_t RTC_GetStoreOperation(void); - -/* Output pin Configuration function ******************************************/ -void RTC_OutputConfig(uint32_t RTC_Output, uint32_t RTC_OutputPolarity); - -/* Digital Calibration configuration functions *********************************/ -ErrorStatus RTC_CoarseCalibConfig(uint32_t RTC_CalibSign, uint32_t Value); -ErrorStatus RTC_CoarseCalibCmd(FunctionalState NewState); -void RTC_CalibOutputCmd(FunctionalState NewState); -void RTC_CalibOutputConfig(uint32_t RTC_CalibOutput); -ErrorStatus RTC_SmoothCalibConfig(uint32_t RTC_SmoothCalibPeriod, - uint32_t RTC_SmoothCalibPlusPulses, - uint32_t RTC_SmouthCalibMinusPulsesValue); - -/* TimeStamp configuration functions ******************************************/ -void RTC_TimeStampCmd(uint32_t RTC_TimeStampEdge, FunctionalState NewState); -void RTC_GetTimeStamp(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_StampTimeStruct, - RTC_DateTypeDef* RTC_StampDateStruct); -uint32_t RTC_GetTimeStampSubSecond(void); - -/* Tampers configuration functions ********************************************/ -void RTC_TamperTriggerConfig(uint32_t RTC_Tamper, uint32_t RTC_TamperTrigger); -void RTC_TamperCmd(uint32_t RTC_Tamper, FunctionalState NewState); -void RTC_TamperFilterConfig(uint32_t RTC_TamperFilter); -void RTC_TamperSamplingFreqConfig(uint32_t RTC_TamperSamplingFreq); -void RTC_TamperPinsPrechargeDuration(uint32_t RTC_TamperPrechargeDuration); -void RTC_TimeStampOnTamperDetectionCmd(FunctionalState NewState); -void RTC_TamperPullUpCmd(FunctionalState NewState); - -/* Backup Data Registers configuration functions ******************************/ -void RTC_WriteBackupRegister(uint32_t RTC_BKP_DR, uint32_t Data); -uint32_t RTC_ReadBackupRegister(uint32_t RTC_BKP_DR); - -/* RTC Tamper and TimeStamp Pins Selection and Output Type Config configuration - functions ******************************************************************/ -void RTC_TamperPinSelection(uint32_t RTC_TamperPin); -void RTC_TimeStampPinSelection(uint32_t RTC_TimeStampPin); -void RTC_OutputTypeConfig(uint32_t RTC_OutputType); - -/* RTC_Shift_control_synchonisation_functions *********************************/ -ErrorStatus RTC_SynchroShiftConfig(uint32_t RTC_ShiftAdd1S, uint32_t RTC_ShiftSubFS); - -/* Interrupts and flags management functions **********************************/ -void RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState); -FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG); -void RTC_ClearFlag(uint32_t RTC_FLAG); -ITStatus RTC_GetITStatus(uint32_t RTC_IT); -void RTC_ClearITPendingBit(uint32_t RTC_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F4xx_RTC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_sdio.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_sdio.h deleted file mode 100644 index aa1bff688..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_sdio.h +++ /dev/null @@ -1,530 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_sdio.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the SDIO firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_SDIO_H -#define __STM32F4xx_SDIO_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup SDIO - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -typedef struct -{ - uint32_t SDIO_ClockEdge; /*!< Specifies the clock transition on which the bit capture is made. - This parameter can be a value of @ref SDIO_Clock_Edge */ - - uint32_t SDIO_ClockBypass; /*!< Specifies whether the SDIO Clock divider bypass is - enabled or disabled. - This parameter can be a value of @ref SDIO_Clock_Bypass */ - - uint32_t SDIO_ClockPowerSave; /*!< Specifies whether SDIO Clock output is enabled or - disabled when the bus is idle. - This parameter can be a value of @ref SDIO_Clock_Power_Save */ - - uint32_t SDIO_BusWide; /*!< Specifies the SDIO bus width. - This parameter can be a value of @ref SDIO_Bus_Wide */ - - uint32_t SDIO_HardwareFlowControl; /*!< Specifies whether the SDIO hardware flow control is enabled or disabled. - This parameter can be a value of @ref SDIO_Hardware_Flow_Control */ - - uint8_t SDIO_ClockDiv; /*!< Specifies the clock frequency of the SDIO controller. - This parameter can be a value between 0x00 and 0xFF. */ - -} SDIO_InitTypeDef; - -typedef struct -{ - uint32_t SDIO_Argument; /*!< Specifies the SDIO command argument which is sent - to a card as part of a command message. If a command - contains an argument, it must be loaded into this register - before writing the command to the command register */ - - uint32_t SDIO_CmdIndex; /*!< Specifies the SDIO command index. It must be lower than 0x40. */ - - uint32_t SDIO_Response; /*!< Specifies the SDIO response type. - This parameter can be a value of @ref SDIO_Response_Type */ - - uint32_t SDIO_Wait; /*!< Specifies whether SDIO wait-for-interrupt request is enabled or disabled. - This parameter can be a value of @ref SDIO_Wait_Interrupt_State */ - - uint32_t SDIO_CPSM; /*!< Specifies whether SDIO Command path state machine (CPSM) - is enabled or disabled. - This parameter can be a value of @ref SDIO_CPSM_State */ -} SDIO_CmdInitTypeDef; - -typedef struct -{ - uint32_t SDIO_DataTimeOut; /*!< Specifies the data timeout period in card bus clock periods. */ - - uint32_t SDIO_DataLength; /*!< Specifies the number of data bytes to be transferred. */ - - uint32_t SDIO_DataBlockSize; /*!< Specifies the data block size for block transfer. - This parameter can be a value of @ref SDIO_Data_Block_Size */ - - uint32_t SDIO_TransferDir; /*!< Specifies the data transfer direction, whether the transfer - is a read or write. - This parameter can be a value of @ref SDIO_Transfer_Direction */ - - uint32_t SDIO_TransferMode; /*!< Specifies whether data transfer is in stream or block mode. - This parameter can be a value of @ref SDIO_Transfer_Type */ - - uint32_t SDIO_DPSM; /*!< Specifies whether SDIO Data path state machine (DPSM) - is enabled or disabled. - This parameter can be a value of @ref SDIO_DPSM_State */ -} SDIO_DataInitTypeDef; - - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup SDIO_Exported_Constants - * @{ - */ - -/** @defgroup SDIO_Clock_Edge - * @{ - */ - -#define SDIO_ClockEdge_Rising ((uint32_t)0x00000000) -#define SDIO_ClockEdge_Falling ((uint32_t)0x00002000) -#define IS_SDIO_CLOCK_EDGE(EDGE) (((EDGE) == SDIO_ClockEdge_Rising) || \ - ((EDGE) == SDIO_ClockEdge_Falling)) -/** - * @} - */ - -/** @defgroup SDIO_Clock_Bypass - * @{ - */ - -#define SDIO_ClockBypass_Disable ((uint32_t)0x00000000) -#define SDIO_ClockBypass_Enable ((uint32_t)0x00000400) -#define IS_SDIO_CLOCK_BYPASS(BYPASS) (((BYPASS) == SDIO_ClockBypass_Disable) || \ - ((BYPASS) == SDIO_ClockBypass_Enable)) -/** - * @} - */ - -/** @defgroup SDIO_Clock_Power_Save - * @{ - */ - -#define SDIO_ClockPowerSave_Disable ((uint32_t)0x00000000) -#define SDIO_ClockPowerSave_Enable ((uint32_t)0x00000200) -#define IS_SDIO_CLOCK_POWER_SAVE(SAVE) (((SAVE) == SDIO_ClockPowerSave_Disable) || \ - ((SAVE) == SDIO_ClockPowerSave_Enable)) -/** - * @} - */ - -/** @defgroup SDIO_Bus_Wide - * @{ - */ - -#define SDIO_BusWide_1b ((uint32_t)0x00000000) -#define SDIO_BusWide_4b ((uint32_t)0x00000800) -#define SDIO_BusWide_8b ((uint32_t)0x00001000) -#define IS_SDIO_BUS_WIDE(WIDE) (((WIDE) == SDIO_BusWide_1b) || ((WIDE) == SDIO_BusWide_4b) || \ - ((WIDE) == SDIO_BusWide_8b)) - -/** - * @} - */ - -/** @defgroup SDIO_Hardware_Flow_Control - * @{ - */ - -#define SDIO_HardwareFlowControl_Disable ((uint32_t)0x00000000) -#define SDIO_HardwareFlowControl_Enable ((uint32_t)0x00004000) -#define IS_SDIO_HARDWARE_FLOW_CONTROL(CONTROL) (((CONTROL) == SDIO_HardwareFlowControl_Disable) || \ - ((CONTROL) == SDIO_HardwareFlowControl_Enable)) -/** - * @} - */ - -/** @defgroup SDIO_Power_State - * @{ - */ - -#define SDIO_PowerState_OFF ((uint32_t)0x00000000) -#define SDIO_PowerState_ON ((uint32_t)0x00000003) -#define IS_SDIO_POWER_STATE(STATE) (((STATE) == SDIO_PowerState_OFF) || ((STATE) == SDIO_PowerState_ON)) -/** - * @} - */ - - -/** @defgroup SDIO_Interrupt_sources - * @{ - */ - -#define SDIO_IT_CCRCFAIL ((uint32_t)0x00000001) -#define SDIO_IT_DCRCFAIL ((uint32_t)0x00000002) -#define SDIO_IT_CTIMEOUT ((uint32_t)0x00000004) -#define SDIO_IT_DTIMEOUT ((uint32_t)0x00000008) -#define SDIO_IT_TXUNDERR ((uint32_t)0x00000010) -#define SDIO_IT_RXOVERR ((uint32_t)0x00000020) -#define SDIO_IT_CMDREND ((uint32_t)0x00000040) -#define SDIO_IT_CMDSENT ((uint32_t)0x00000080) -#define SDIO_IT_DATAEND ((uint32_t)0x00000100) -#define SDIO_IT_STBITERR ((uint32_t)0x00000200) -#define SDIO_IT_DBCKEND ((uint32_t)0x00000400) -#define SDIO_IT_CMDACT ((uint32_t)0x00000800) -#define SDIO_IT_TXACT ((uint32_t)0x00001000) -#define SDIO_IT_RXACT ((uint32_t)0x00002000) -#define SDIO_IT_TXFIFOHE ((uint32_t)0x00004000) -#define SDIO_IT_RXFIFOHF ((uint32_t)0x00008000) -#define SDIO_IT_TXFIFOF ((uint32_t)0x00010000) -#define SDIO_IT_RXFIFOF ((uint32_t)0x00020000) -#define SDIO_IT_TXFIFOE ((uint32_t)0x00040000) -#define SDIO_IT_RXFIFOE ((uint32_t)0x00080000) -#define SDIO_IT_TXDAVL ((uint32_t)0x00100000) -#define SDIO_IT_RXDAVL ((uint32_t)0x00200000) -#define SDIO_IT_SDIOIT ((uint32_t)0x00400000) -#define SDIO_IT_CEATAEND ((uint32_t)0x00800000) -#define IS_SDIO_IT(IT) ((((IT) & (uint32_t)0xFF000000) == 0x00) && ((IT) != (uint32_t)0x00)) -/** - * @} - */ - -/** @defgroup SDIO_Command_Index - * @{ - */ - -#define IS_SDIO_CMD_INDEX(INDEX) ((INDEX) < 0x40) -/** - * @} - */ - -/** @defgroup SDIO_Response_Type - * @{ - */ - -#define SDIO_Response_No ((uint32_t)0x00000000) -#define SDIO_Response_Short ((uint32_t)0x00000040) -#define SDIO_Response_Long ((uint32_t)0x000000C0) -#define IS_SDIO_RESPONSE(RESPONSE) (((RESPONSE) == SDIO_Response_No) || \ - ((RESPONSE) == SDIO_Response_Short) || \ - ((RESPONSE) == SDIO_Response_Long)) -/** - * @} - */ - -/** @defgroup SDIO_Wait_Interrupt_State - * @{ - */ - -#define SDIO_Wait_No ((uint32_t)0x00000000) /*!< SDIO No Wait, TimeOut is enabled */ -#define SDIO_Wait_IT ((uint32_t)0x00000100) /*!< SDIO Wait Interrupt Request */ -#define SDIO_Wait_Pend ((uint32_t)0x00000200) /*!< SDIO Wait End of transfer */ -#define IS_SDIO_WAIT(WAIT) (((WAIT) == SDIO_Wait_No) || ((WAIT) == SDIO_Wait_IT) || \ - ((WAIT) == SDIO_Wait_Pend)) -/** - * @} - */ - -/** @defgroup SDIO_CPSM_State - * @{ - */ - -#define SDIO_CPSM_Disable ((uint32_t)0x00000000) -#define SDIO_CPSM_Enable ((uint32_t)0x00000400) -#define IS_SDIO_CPSM(CPSM) (((CPSM) == SDIO_CPSM_Enable) || ((CPSM) == SDIO_CPSM_Disable)) -/** - * @} - */ - -/** @defgroup SDIO_Response_Registers - * @{ - */ - -#define SDIO_RESP1 ((uint32_t)0x00000000) -#define SDIO_RESP2 ((uint32_t)0x00000004) -#define SDIO_RESP3 ((uint32_t)0x00000008) -#define SDIO_RESP4 ((uint32_t)0x0000000C) -#define IS_SDIO_RESP(RESP) (((RESP) == SDIO_RESP1) || ((RESP) == SDIO_RESP2) || \ - ((RESP) == SDIO_RESP3) || ((RESP) == SDIO_RESP4)) -/** - * @} - */ - -/** @defgroup SDIO_Data_Length - * @{ - */ - -#define IS_SDIO_DATA_LENGTH(LENGTH) ((LENGTH) <= 0x01FFFFFF) -/** - * @} - */ - -/** @defgroup SDIO_Data_Block_Size - * @{ - */ - -#define SDIO_DataBlockSize_1b ((uint32_t)0x00000000) -#define SDIO_DataBlockSize_2b ((uint32_t)0x00000010) -#define SDIO_DataBlockSize_4b ((uint32_t)0x00000020) -#define SDIO_DataBlockSize_8b ((uint32_t)0x00000030) -#define SDIO_DataBlockSize_16b ((uint32_t)0x00000040) -#define SDIO_DataBlockSize_32b ((uint32_t)0x00000050) -#define SDIO_DataBlockSize_64b ((uint32_t)0x00000060) -#define SDIO_DataBlockSize_128b ((uint32_t)0x00000070) -#define SDIO_DataBlockSize_256b ((uint32_t)0x00000080) -#define SDIO_DataBlockSize_512b ((uint32_t)0x00000090) -#define SDIO_DataBlockSize_1024b ((uint32_t)0x000000A0) -#define SDIO_DataBlockSize_2048b ((uint32_t)0x000000B0) -#define SDIO_DataBlockSize_4096b ((uint32_t)0x000000C0) -#define SDIO_DataBlockSize_8192b ((uint32_t)0x000000D0) -#define SDIO_DataBlockSize_16384b ((uint32_t)0x000000E0) -#define IS_SDIO_BLOCK_SIZE(SIZE) (((SIZE) == SDIO_DataBlockSize_1b) || \ - ((SIZE) == SDIO_DataBlockSize_2b) || \ - ((SIZE) == SDIO_DataBlockSize_4b) || \ - ((SIZE) == SDIO_DataBlockSize_8b) || \ - ((SIZE) == SDIO_DataBlockSize_16b) || \ - ((SIZE) == SDIO_DataBlockSize_32b) || \ - ((SIZE) == SDIO_DataBlockSize_64b) || \ - ((SIZE) == SDIO_DataBlockSize_128b) || \ - ((SIZE) == SDIO_DataBlockSize_256b) || \ - ((SIZE) == SDIO_DataBlockSize_512b) || \ - ((SIZE) == SDIO_DataBlockSize_1024b) || \ - ((SIZE) == SDIO_DataBlockSize_2048b) || \ - ((SIZE) == SDIO_DataBlockSize_4096b) || \ - ((SIZE) == SDIO_DataBlockSize_8192b) || \ - ((SIZE) == SDIO_DataBlockSize_16384b)) -/** - * @} - */ - -/** @defgroup SDIO_Transfer_Direction - * @{ - */ - -#define SDIO_TransferDir_ToCard ((uint32_t)0x00000000) -#define SDIO_TransferDir_ToSDIO ((uint32_t)0x00000002) -#define IS_SDIO_TRANSFER_DIR(DIR) (((DIR) == SDIO_TransferDir_ToCard) || \ - ((DIR) == SDIO_TransferDir_ToSDIO)) -/** - * @} - */ - -/** @defgroup SDIO_Transfer_Type - * @{ - */ - -#define SDIO_TransferMode_Block ((uint32_t)0x00000000) -#define SDIO_TransferMode_Stream ((uint32_t)0x00000004) -#define IS_SDIO_TRANSFER_MODE(MODE) (((MODE) == SDIO_TransferMode_Stream) || \ - ((MODE) == SDIO_TransferMode_Block)) -/** - * @} - */ - -/** @defgroup SDIO_DPSM_State - * @{ - */ - -#define SDIO_DPSM_Disable ((uint32_t)0x00000000) -#define SDIO_DPSM_Enable ((uint32_t)0x00000001) -#define IS_SDIO_DPSM(DPSM) (((DPSM) == SDIO_DPSM_Enable) || ((DPSM) == SDIO_DPSM_Disable)) -/** - * @} - */ - -/** @defgroup SDIO_Flags - * @{ - */ - -#define SDIO_FLAG_CCRCFAIL ((uint32_t)0x00000001) -#define SDIO_FLAG_DCRCFAIL ((uint32_t)0x00000002) -#define SDIO_FLAG_CTIMEOUT ((uint32_t)0x00000004) -#define SDIO_FLAG_DTIMEOUT ((uint32_t)0x00000008) -#define SDIO_FLAG_TXUNDERR ((uint32_t)0x00000010) -#define SDIO_FLAG_RXOVERR ((uint32_t)0x00000020) -#define SDIO_FLAG_CMDREND ((uint32_t)0x00000040) -#define SDIO_FLAG_CMDSENT ((uint32_t)0x00000080) -#define SDIO_FLAG_DATAEND ((uint32_t)0x00000100) -#define SDIO_FLAG_STBITERR ((uint32_t)0x00000200) -#define SDIO_FLAG_DBCKEND ((uint32_t)0x00000400) -#define SDIO_FLAG_CMDACT ((uint32_t)0x00000800) -#define SDIO_FLAG_TXACT ((uint32_t)0x00001000) -#define SDIO_FLAG_RXACT ((uint32_t)0x00002000) -#define SDIO_FLAG_TXFIFOHE ((uint32_t)0x00004000) -#define SDIO_FLAG_RXFIFOHF ((uint32_t)0x00008000) -#define SDIO_FLAG_TXFIFOF ((uint32_t)0x00010000) -#define SDIO_FLAG_RXFIFOF ((uint32_t)0x00020000) -#define SDIO_FLAG_TXFIFOE ((uint32_t)0x00040000) -#define SDIO_FLAG_RXFIFOE ((uint32_t)0x00080000) -#define SDIO_FLAG_TXDAVL ((uint32_t)0x00100000) -#define SDIO_FLAG_RXDAVL ((uint32_t)0x00200000) -#define SDIO_FLAG_SDIOIT ((uint32_t)0x00400000) -#define SDIO_FLAG_CEATAEND ((uint32_t)0x00800000) -#define IS_SDIO_FLAG(FLAG) (((FLAG) == SDIO_FLAG_CCRCFAIL) || \ - ((FLAG) == SDIO_FLAG_DCRCFAIL) || \ - ((FLAG) == SDIO_FLAG_CTIMEOUT) || \ - ((FLAG) == SDIO_FLAG_DTIMEOUT) || \ - ((FLAG) == SDIO_FLAG_TXUNDERR) || \ - ((FLAG) == SDIO_FLAG_RXOVERR) || \ - ((FLAG) == SDIO_FLAG_CMDREND) || \ - ((FLAG) == SDIO_FLAG_CMDSENT) || \ - ((FLAG) == SDIO_FLAG_DATAEND) || \ - ((FLAG) == SDIO_FLAG_STBITERR) || \ - ((FLAG) == SDIO_FLAG_DBCKEND) || \ - ((FLAG) == SDIO_FLAG_CMDACT) || \ - ((FLAG) == SDIO_FLAG_TXACT) || \ - ((FLAG) == SDIO_FLAG_RXACT) || \ - ((FLAG) == SDIO_FLAG_TXFIFOHE) || \ - ((FLAG) == SDIO_FLAG_RXFIFOHF) || \ - ((FLAG) == SDIO_FLAG_TXFIFOF) || \ - ((FLAG) == SDIO_FLAG_RXFIFOF) || \ - ((FLAG) == SDIO_FLAG_TXFIFOE) || \ - ((FLAG) == SDIO_FLAG_RXFIFOE) || \ - ((FLAG) == SDIO_FLAG_TXDAVL) || \ - ((FLAG) == SDIO_FLAG_RXDAVL) || \ - ((FLAG) == SDIO_FLAG_SDIOIT) || \ - ((FLAG) == SDIO_FLAG_CEATAEND)) - -#define IS_SDIO_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFF3FF800) == 0x00) && ((FLAG) != (uint32_t)0x00)) - -#define IS_SDIO_GET_IT(IT) (((IT) == SDIO_IT_CCRCFAIL) || \ - ((IT) == SDIO_IT_DCRCFAIL) || \ - ((IT) == SDIO_IT_CTIMEOUT) || \ - ((IT) == SDIO_IT_DTIMEOUT) || \ - ((IT) == SDIO_IT_TXUNDERR) || \ - ((IT) == SDIO_IT_RXOVERR) || \ - ((IT) == SDIO_IT_CMDREND) || \ - ((IT) == SDIO_IT_CMDSENT) || \ - ((IT) == SDIO_IT_DATAEND) || \ - ((IT) == SDIO_IT_STBITERR) || \ - ((IT) == SDIO_IT_DBCKEND) || \ - ((IT) == SDIO_IT_CMDACT) || \ - ((IT) == SDIO_IT_TXACT) || \ - ((IT) == SDIO_IT_RXACT) || \ - ((IT) == SDIO_IT_TXFIFOHE) || \ - ((IT) == SDIO_IT_RXFIFOHF) || \ - ((IT) == SDIO_IT_TXFIFOF) || \ - ((IT) == SDIO_IT_RXFIFOF) || \ - ((IT) == SDIO_IT_TXFIFOE) || \ - ((IT) == SDIO_IT_RXFIFOE) || \ - ((IT) == SDIO_IT_TXDAVL) || \ - ((IT) == SDIO_IT_RXDAVL) || \ - ((IT) == SDIO_IT_SDIOIT) || \ - ((IT) == SDIO_IT_CEATAEND)) - -#define IS_SDIO_CLEAR_IT(IT) ((((IT) & (uint32_t)0xFF3FF800) == 0x00) && ((IT) != (uint32_t)0x00)) - -/** - * @} - */ - -/** @defgroup SDIO_Read_Wait_Mode - * @{ - */ - -#define SDIO_ReadWaitMode_CLK ((uint32_t)0x00000000) -#define SDIO_ReadWaitMode_DATA2 ((uint32_t)0x00000001) -#define IS_SDIO_READWAIT_MODE(MODE) (((MODE) == SDIO_ReadWaitMode_CLK) || \ - ((MODE) == SDIO_ReadWaitMode_DATA2)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ -/* Function used to set the SDIO configuration to the default reset state ****/ -void SDIO_DeInit(void); - -/* Initialization and Configuration functions *********************************/ -void SDIO_Init(SDIO_InitTypeDef* SDIO_InitStruct); -void SDIO_StructInit(SDIO_InitTypeDef* SDIO_InitStruct); -void SDIO_ClockCmd(FunctionalState NewState); -void SDIO_SetPowerState(uint32_t SDIO_PowerState); -uint32_t SDIO_GetPowerState(void); - -/* Command path state machine (CPSM) management functions *********************/ -void SDIO_SendCommand(SDIO_CmdInitTypeDef *SDIO_CmdInitStruct); -void SDIO_CmdStructInit(SDIO_CmdInitTypeDef* SDIO_CmdInitStruct); -uint8_t SDIO_GetCommandResponse(void); -uint32_t SDIO_GetResponse(uint32_t SDIO_RESP); - -/* Data path state machine (DPSM) management functions ************************/ -void SDIO_DataConfig(SDIO_DataInitTypeDef* SDIO_DataInitStruct); -void SDIO_DataStructInit(SDIO_DataInitTypeDef* SDIO_DataInitStruct); -uint32_t SDIO_GetDataCounter(void); -uint32_t SDIO_ReadData(void); -void SDIO_WriteData(uint32_t Data); -uint32_t SDIO_GetFIFOCount(void); - -/* SDIO IO Cards mode management functions ************************************/ -void SDIO_StartSDIOReadWait(FunctionalState NewState); -void SDIO_StopSDIOReadWait(FunctionalState NewState); -void SDIO_SetSDIOReadWaitMode(uint32_t SDIO_ReadWaitMode); -void SDIO_SetSDIOOperation(FunctionalState NewState); -void SDIO_SendSDIOSuspendCmd(FunctionalState NewState); - -/* CE-ATA mode management functions *******************************************/ -void SDIO_CommandCompletionCmd(FunctionalState NewState); -void SDIO_CEATAITCmd(FunctionalState NewState); -void SDIO_SendCEATACmd(FunctionalState NewState); - -/* DMA transfers management functions *****************************************/ -void SDIO_DMACmd(FunctionalState NewState); - -/* Interrupts and flags management functions **********************************/ -void SDIO_ITConfig(uint32_t SDIO_IT, FunctionalState NewState); -FlagStatus SDIO_GetFlagStatus(uint32_t SDIO_FLAG); -void SDIO_ClearFlag(uint32_t SDIO_FLAG); -ITStatus SDIO_GetITStatus(uint32_t SDIO_IT); -void SDIO_ClearITPendingBit(uint32_t SDIO_IT); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_SDIO_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_spi.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_spi.h deleted file mode 100644 index db43fb3f3..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_spi.h +++ /dev/null @@ -1,537 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_spi.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the SPI - * firmware library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_SPI_H -#define __STM32F4xx_SPI_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup SPI - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief SPI Init structure definition - */ - -typedef struct -{ - uint16_t SPI_Direction; /*!< Specifies the SPI unidirectional or bidirectional data mode. - This parameter can be a value of @ref SPI_data_direction */ - - uint16_t SPI_Mode; /*!< Specifies the SPI operating mode. - This parameter can be a value of @ref SPI_mode */ - - uint16_t SPI_DataSize; /*!< Specifies the SPI data size. - This parameter can be a value of @ref SPI_data_size */ - - uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state. - This parameter can be a value of @ref SPI_Clock_Polarity */ - - uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture. - This parameter can be a value of @ref SPI_Clock_Phase */ - - uint16_t SPI_NSS; /*!< Specifies whether the NSS signal is managed by - hardware (NSS pin) or by software using the SSI bit. - This parameter can be a value of @ref SPI_Slave_Select_management */ - - uint16_t SPI_BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be - used to configure the transmit and receive SCK clock. - This parameter can be a value of @ref SPI_BaudRate_Prescaler - @note The communication clock is derived from the master - clock. The slave clock does not need to be set. */ - - uint16_t SPI_FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit. - This parameter can be a value of @ref SPI_MSB_LSB_transmission */ - - uint16_t SPI_CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. */ -}SPI_InitTypeDef; - -/** - * @brief I2S Init structure definition - */ - -typedef struct -{ - - uint16_t I2S_Mode; /*!< Specifies the I2S operating mode. - This parameter can be a value of @ref I2S_Mode */ - - uint16_t I2S_Standard; /*!< Specifies the standard used for the I2S communication. - This parameter can be a value of @ref I2S_Standard */ - - uint16_t I2S_DataFormat; /*!< Specifies the data format for the I2S communication. - This parameter can be a value of @ref I2S_Data_Format */ - - uint16_t I2S_MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not. - This parameter can be a value of @ref I2S_MCLK_Output */ - - uint32_t I2S_AudioFreq; /*!< Specifies the frequency selected for the I2S communication. - This parameter can be a value of @ref I2S_Audio_Frequency */ - - uint16_t I2S_CPOL; /*!< Specifies the idle state of the I2S clock. - This parameter can be a value of @ref I2S_Clock_Polarity */ -}I2S_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup SPI_Exported_Constants - * @{ - */ - -#define IS_SPI_ALL_PERIPH(PERIPH) (((PERIPH) == SPI1) || \ - ((PERIPH) == SPI2) || \ - ((PERIPH) == SPI3)) - -#define IS_SPI_ALL_PERIPH_EXT(PERIPH) (((PERIPH) == SPI1) || \ - ((PERIPH) == SPI2) || \ - ((PERIPH) == SPI3) || \ - ((PERIPH) == I2S2ext) || \ - ((PERIPH) == I2S3ext)) - -#define IS_SPI_23_PERIPH(PERIPH) (((PERIPH) == SPI2) || \ - ((PERIPH) == SPI3)) - -#define IS_SPI_23_PERIPH_EXT(PERIPH) (((PERIPH) == SPI2) || \ - ((PERIPH) == SPI3) || \ - ((PERIPH) == I2S2ext) || \ - ((PERIPH) == I2S3ext)) - -#define IS_I2S_EXT_PERIPH(PERIPH) (((PERIPH) == I2S2ext) || \ - ((PERIPH) == I2S2ext)) - - -/** @defgroup SPI_data_direction - * @{ - */ - -#define SPI_Direction_2Lines_FullDuplex ((uint16_t)0x0000) -#define SPI_Direction_2Lines_RxOnly ((uint16_t)0x0400) -#define SPI_Direction_1Line_Rx ((uint16_t)0x8000) -#define SPI_Direction_1Line_Tx ((uint16_t)0xC000) -#define IS_SPI_DIRECTION_MODE(MODE) (((MODE) == SPI_Direction_2Lines_FullDuplex) || \ - ((MODE) == SPI_Direction_2Lines_RxOnly) || \ - ((MODE) == SPI_Direction_1Line_Rx) || \ - ((MODE) == SPI_Direction_1Line_Tx)) -/** - * @} - */ - -/** @defgroup SPI_mode - * @{ - */ - -#define SPI_Mode_Master ((uint16_t)0x0104) -#define SPI_Mode_Slave ((uint16_t)0x0000) -#define IS_SPI_MODE(MODE) (((MODE) == SPI_Mode_Master) || \ - ((MODE) == SPI_Mode_Slave)) -/** - * @} - */ - -/** @defgroup SPI_data_size - * @{ - */ - -#define SPI_DataSize_16b ((uint16_t)0x0800) -#define SPI_DataSize_8b ((uint16_t)0x0000) -#define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DataSize_16b) || \ - ((DATASIZE) == SPI_DataSize_8b)) -/** - * @} - */ - -/** @defgroup SPI_Clock_Polarity - * @{ - */ - -#define SPI_CPOL_Low ((uint16_t)0x0000) -#define SPI_CPOL_High ((uint16_t)0x0002) -#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_CPOL_Low) || \ - ((CPOL) == SPI_CPOL_High)) -/** - * @} - */ - -/** @defgroup SPI_Clock_Phase - * @{ - */ - -#define SPI_CPHA_1Edge ((uint16_t)0x0000) -#define SPI_CPHA_2Edge ((uint16_t)0x0001) -#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_CPHA_1Edge) || \ - ((CPHA) == SPI_CPHA_2Edge)) -/** - * @} - */ - -/** @defgroup SPI_Slave_Select_management - * @{ - */ - -#define SPI_NSS_Soft ((uint16_t)0x0200) -#define SPI_NSS_Hard ((uint16_t)0x0000) -#define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_Soft) || \ - ((NSS) == SPI_NSS_Hard)) -/** - * @} - */ - -/** @defgroup SPI_BaudRate_Prescaler - * @{ - */ - -#define SPI_BaudRatePrescaler_2 ((uint16_t)0x0000) -#define SPI_BaudRatePrescaler_4 ((uint16_t)0x0008) -#define SPI_BaudRatePrescaler_8 ((uint16_t)0x0010) -#define SPI_BaudRatePrescaler_16 ((uint16_t)0x0018) -#define SPI_BaudRatePrescaler_32 ((uint16_t)0x0020) -#define SPI_BaudRatePrescaler_64 ((uint16_t)0x0028) -#define SPI_BaudRatePrescaler_128 ((uint16_t)0x0030) -#define SPI_BaudRatePrescaler_256 ((uint16_t)0x0038) -#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BaudRatePrescaler_2) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_4) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_8) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_16) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_32) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_64) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_128) || \ - ((PRESCALER) == SPI_BaudRatePrescaler_256)) -/** - * @} - */ - -/** @defgroup SPI_MSB_LSB_transmission - * @{ - */ - -#define SPI_FirstBit_MSB ((uint16_t)0x0000) -#define SPI_FirstBit_LSB ((uint16_t)0x0080) -#define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FirstBit_MSB) || \ - ((BIT) == SPI_FirstBit_LSB)) -/** - * @} - */ - -/** @defgroup SPI_I2S_Mode - * @{ - */ - -#define I2S_Mode_SlaveTx ((uint16_t)0x0000) -#define I2S_Mode_SlaveRx ((uint16_t)0x0100) -#define I2S_Mode_MasterTx ((uint16_t)0x0200) -#define I2S_Mode_MasterRx ((uint16_t)0x0300) -#define IS_I2S_MODE(MODE) (((MODE) == I2S_Mode_SlaveTx) || \ - ((MODE) == I2S_Mode_SlaveRx) || \ - ((MODE) == I2S_Mode_MasterTx)|| \ - ((MODE) == I2S_Mode_MasterRx)) -/** - * @} - */ - - -/** @defgroup SPI_I2S_Standard - * @{ - */ - -#define I2S_Standard_Phillips ((uint16_t)0x0000) -#define I2S_Standard_MSB ((uint16_t)0x0010) -#define I2S_Standard_LSB ((uint16_t)0x0020) -#define I2S_Standard_PCMShort ((uint16_t)0x0030) -#define I2S_Standard_PCMLong ((uint16_t)0x00B0) -#define IS_I2S_STANDARD(STANDARD) (((STANDARD) == I2S_Standard_Phillips) || \ - ((STANDARD) == I2S_Standard_MSB) || \ - ((STANDARD) == I2S_Standard_LSB) || \ - ((STANDARD) == I2S_Standard_PCMShort) || \ - ((STANDARD) == I2S_Standard_PCMLong)) -/** - * @} - */ - -/** @defgroup SPI_I2S_Data_Format - * @{ - */ - -#define I2S_DataFormat_16b ((uint16_t)0x0000) -#define I2S_DataFormat_16bextended ((uint16_t)0x0001) -#define I2S_DataFormat_24b ((uint16_t)0x0003) -#define I2S_DataFormat_32b ((uint16_t)0x0005) -#define IS_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == I2S_DataFormat_16b) || \ - ((FORMAT) == I2S_DataFormat_16bextended) || \ - ((FORMAT) == I2S_DataFormat_24b) || \ - ((FORMAT) == I2S_DataFormat_32b)) -/** - * @} - */ - -/** @defgroup SPI_I2S_MCLK_Output - * @{ - */ - -#define I2S_MCLKOutput_Enable ((uint16_t)0x0200) -#define I2S_MCLKOutput_Disable ((uint16_t)0x0000) -#define IS_I2S_MCLK_OUTPUT(OUTPUT) (((OUTPUT) == I2S_MCLKOutput_Enable) || \ - ((OUTPUT) == I2S_MCLKOutput_Disable)) -/** - * @} - */ - -/** @defgroup SPI_I2S_Audio_Frequency - * @{ - */ - -#define I2S_AudioFreq_192k ((uint32_t)192000) -#define I2S_AudioFreq_96k ((uint32_t)96000) -#define I2S_AudioFreq_48k ((uint32_t)48000) -#define I2S_AudioFreq_44k ((uint32_t)44100) -#define I2S_AudioFreq_32k ((uint32_t)32000) -#define I2S_AudioFreq_22k ((uint32_t)22050) -#define I2S_AudioFreq_16k ((uint32_t)16000) -#define I2S_AudioFreq_11k ((uint32_t)11025) -#define I2S_AudioFreq_8k ((uint32_t)8000) -#define I2S_AudioFreq_Default ((uint32_t)2) - -#define IS_I2S_AUDIO_FREQ(FREQ) ((((FREQ) >= I2S_AudioFreq_8k) && \ - ((FREQ) <= I2S_AudioFreq_192k)) || \ - ((FREQ) == I2S_AudioFreq_Default)) -/** - * @} - */ - -/** @defgroup SPI_I2S_Clock_Polarity - * @{ - */ - -#define I2S_CPOL_Low ((uint16_t)0x0000) -#define I2S_CPOL_High ((uint16_t)0x0008) -#define IS_I2S_CPOL(CPOL) (((CPOL) == I2S_CPOL_Low) || \ - ((CPOL) == I2S_CPOL_High)) -/** - * @} - */ - -/** @defgroup SPI_I2S_DMA_transfer_requests - * @{ - */ - -#define SPI_I2S_DMAReq_Tx ((uint16_t)0x0002) -#define SPI_I2S_DMAReq_Rx ((uint16_t)0x0001) -#define IS_SPI_I2S_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFFFC) == 0x00) && ((DMAREQ) != 0x00)) -/** - * @} - */ - -/** @defgroup SPI_NSS_internal_software_management - * @{ - */ - -#define SPI_NSSInternalSoft_Set ((uint16_t)0x0100) -#define SPI_NSSInternalSoft_Reset ((uint16_t)0xFEFF) -#define IS_SPI_NSS_INTERNAL(INTERNAL) (((INTERNAL) == SPI_NSSInternalSoft_Set) || \ - ((INTERNAL) == SPI_NSSInternalSoft_Reset)) -/** - * @} - */ - -/** @defgroup SPI_CRC_Transmit_Receive - * @{ - */ - -#define SPI_CRC_Tx ((uint8_t)0x00) -#define SPI_CRC_Rx ((uint8_t)0x01) -#define IS_SPI_CRC(CRC) (((CRC) == SPI_CRC_Tx) || ((CRC) == SPI_CRC_Rx)) -/** - * @} - */ - -/** @defgroup SPI_direction_transmit_receive - * @{ - */ - -#define SPI_Direction_Rx ((uint16_t)0xBFFF) -#define SPI_Direction_Tx ((uint16_t)0x4000) -#define IS_SPI_DIRECTION(DIRECTION) (((DIRECTION) == SPI_Direction_Rx) || \ - ((DIRECTION) == SPI_Direction_Tx)) -/** - * @} - */ - -/** @defgroup SPI_I2S_interrupts_definition - * @{ - */ - -#define SPI_I2S_IT_TXE ((uint8_t)0x71) -#define SPI_I2S_IT_RXNE ((uint8_t)0x60) -#define SPI_I2S_IT_ERR ((uint8_t)0x50) -#define I2S_IT_UDR ((uint8_t)0x53) -#define SPI_I2S_IT_TIFRFE ((uint8_t)0x58) - -#define IS_SPI_I2S_CONFIG_IT(IT) (((IT) == SPI_I2S_IT_TXE) || \ - ((IT) == SPI_I2S_IT_RXNE) || \ - ((IT) == SPI_I2S_IT_ERR)) - -#define SPI_I2S_IT_OVR ((uint8_t)0x56) -#define SPI_IT_MODF ((uint8_t)0x55) -#define SPI_IT_CRCERR ((uint8_t)0x54) - -#define IS_SPI_I2S_CLEAR_IT(IT) (((IT) == SPI_IT_CRCERR)) - -#define IS_SPI_I2S_GET_IT(IT) (((IT) == SPI_I2S_IT_RXNE)|| ((IT) == SPI_I2S_IT_TXE) || \ - ((IT) == SPI_IT_CRCERR) || ((IT) == SPI_IT_MODF) || \ - ((IT) == SPI_I2S_IT_OVR) || ((IT) == I2S_IT_UDR) ||\ - ((IT) == SPI_I2S_IT_TIFRFE)) -/** - * @} - */ - -/** @defgroup SPI_I2S_flags_definition - * @{ - */ - -#define SPI_I2S_FLAG_RXNE ((uint16_t)0x0001) -#define SPI_I2S_FLAG_TXE ((uint16_t)0x0002) -#define I2S_FLAG_CHSIDE ((uint16_t)0x0004) -#define I2S_FLAG_UDR ((uint16_t)0x0008) -#define SPI_FLAG_CRCERR ((uint16_t)0x0010) -#define SPI_FLAG_MODF ((uint16_t)0x0020) -#define SPI_I2S_FLAG_OVR ((uint16_t)0x0040) -#define SPI_I2S_FLAG_BSY ((uint16_t)0x0080) -#define SPI_I2S_FLAG_TIFRFE ((uint16_t)0x0100) - -#define IS_SPI_I2S_CLEAR_FLAG(FLAG) (((FLAG) == SPI_FLAG_CRCERR)) -#define IS_SPI_I2S_GET_FLAG(FLAG) (((FLAG) == SPI_I2S_FLAG_BSY) || ((FLAG) == SPI_I2S_FLAG_OVR) || \ - ((FLAG) == SPI_FLAG_MODF) || ((FLAG) == SPI_FLAG_CRCERR) || \ - ((FLAG) == I2S_FLAG_UDR) || ((FLAG) == I2S_FLAG_CHSIDE) || \ - ((FLAG) == SPI_I2S_FLAG_TXE) || ((FLAG) == SPI_I2S_FLAG_RXNE)|| \ - ((FLAG) == SPI_I2S_FLAG_TIFRFE)) -/** - * @} - */ - -/** @defgroup SPI_CRC_polynomial - * @{ - */ - -#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) ((POLYNOMIAL) >= 0x1) -/** - * @} - */ - -/** @defgroup SPI_I2S_Legacy - * @{ - */ - -#define SPI_DMAReq_Tx SPI_I2S_DMAReq_Tx -#define SPI_DMAReq_Rx SPI_I2S_DMAReq_Rx -#define SPI_IT_TXE SPI_I2S_IT_TXE -#define SPI_IT_RXNE SPI_I2S_IT_RXNE -#define SPI_IT_ERR SPI_I2S_IT_ERR -#define SPI_IT_OVR SPI_I2S_IT_OVR -#define SPI_FLAG_RXNE SPI_I2S_FLAG_RXNE -#define SPI_FLAG_TXE SPI_I2S_FLAG_TXE -#define SPI_FLAG_OVR SPI_I2S_FLAG_OVR -#define SPI_FLAG_BSY SPI_I2S_FLAG_BSY -#define SPI_DeInit SPI_I2S_DeInit -#define SPI_ITConfig SPI_I2S_ITConfig -#define SPI_DMACmd SPI_I2S_DMACmd -#define SPI_SendData SPI_I2S_SendData -#define SPI_ReceiveData SPI_I2S_ReceiveData -#define SPI_GetFlagStatus SPI_I2S_GetFlagStatus -#define SPI_ClearFlag SPI_I2S_ClearFlag -#define SPI_GetITStatus SPI_I2S_GetITStatus -#define SPI_ClearITPendingBit SPI_I2S_ClearITPendingBit -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the SPI configuration to the default reset state *****/ -void SPI_I2S_DeInit(SPI_TypeDef* SPIx); - -/* Initialization and Configuration functions *********************************/ -void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct); -void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct); -void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct); -void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct); -void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); -void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); -void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize); -void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction); -void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft); -void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState); -void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState); - -void I2S_FullDuplexConfig(SPI_TypeDef* I2Sxext, I2S_InitTypeDef* I2S_InitStruct); - -/* Data transfers functions ***************************************************/ -void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data); -uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx); - -/* Hardware CRC Calculation functions *****************************************/ -void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState); -void SPI_TransmitCRC(SPI_TypeDef* SPIx); -uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC); -uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx); - -/* DMA transfers management functions *****************************************/ -void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState); - -/* Interrupts and flags management functions **********************************/ -void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState); -FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); -void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); -ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); -void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F4xx_SPI_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_syscfg.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_syscfg.h deleted file mode 100644 index 80b66ff84..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_syscfg.h +++ /dev/null @@ -1,173 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_syscfg.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the SYSCFG firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_SYSCFG_H -#define __STM32F4xx_SYSCFG_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup SYSCFG - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup SYSCFG_Exported_Constants - * @{ - */ - -/** @defgroup SYSCFG_EXTI_Port_Sources - * @{ - */ -#define EXTI_PortSourceGPIOA ((uint8_t)0x00) -#define EXTI_PortSourceGPIOB ((uint8_t)0x01) -#define EXTI_PortSourceGPIOC ((uint8_t)0x02) -#define EXTI_PortSourceGPIOD ((uint8_t)0x03) -#define EXTI_PortSourceGPIOE ((uint8_t)0x04) -#define EXTI_PortSourceGPIOF ((uint8_t)0x05) -#define EXTI_PortSourceGPIOG ((uint8_t)0x06) -#define EXTI_PortSourceGPIOH ((uint8_t)0x07) -#define EXTI_PortSourceGPIOI ((uint8_t)0x08) - -#define IS_EXTI_PORT_SOURCE(PORTSOURCE) (((PORTSOURCE) == EXTI_PortSourceGPIOA) || \ - ((PORTSOURCE) == EXTI_PortSourceGPIOB) || \ - ((PORTSOURCE) == EXTI_PortSourceGPIOC) || \ - ((PORTSOURCE) == EXTI_PortSourceGPIOD) || \ - ((PORTSOURCE) == EXTI_PortSourceGPIOE) || \ - ((PORTSOURCE) == EXTI_PortSourceGPIOF) || \ - ((PORTSOURCE) == EXTI_PortSourceGPIOG) || \ - ((PORTSOURCE) == EXTI_PortSourceGPIOH) || \ - ((PORTSOURCE) == EXTI_PortSourceGPIOI)) -/** - * @} - */ - - -/** @defgroup SYSCFG_EXTI_Pin_Sources - * @{ - */ -#define EXTI_PinSource0 ((uint8_t)0x00) -#define EXTI_PinSource1 ((uint8_t)0x01) -#define EXTI_PinSource2 ((uint8_t)0x02) -#define EXTI_PinSource3 ((uint8_t)0x03) -#define EXTI_PinSource4 ((uint8_t)0x04) -#define EXTI_PinSource5 ((uint8_t)0x05) -#define EXTI_PinSource6 ((uint8_t)0x06) -#define EXTI_PinSource7 ((uint8_t)0x07) -#define EXTI_PinSource8 ((uint8_t)0x08) -#define EXTI_PinSource9 ((uint8_t)0x09) -#define EXTI_PinSource10 ((uint8_t)0x0A) -#define EXTI_PinSource11 ((uint8_t)0x0B) -#define EXTI_PinSource12 ((uint8_t)0x0C) -#define EXTI_PinSource13 ((uint8_t)0x0D) -#define EXTI_PinSource14 ((uint8_t)0x0E) -#define EXTI_PinSource15 ((uint8_t)0x0F) -#define IS_EXTI_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == EXTI_PinSource0) || \ - ((PINSOURCE) == EXTI_PinSource1) || \ - ((PINSOURCE) == EXTI_PinSource2) || \ - ((PINSOURCE) == EXTI_PinSource3) || \ - ((PINSOURCE) == EXTI_PinSource4) || \ - ((PINSOURCE) == EXTI_PinSource5) || \ - ((PINSOURCE) == EXTI_PinSource6) || \ - ((PINSOURCE) == EXTI_PinSource7) || \ - ((PINSOURCE) == EXTI_PinSource8) || \ - ((PINSOURCE) == EXTI_PinSource9) || \ - ((PINSOURCE) == EXTI_PinSource10) || \ - ((PINSOURCE) == EXTI_PinSource11) || \ - ((PINSOURCE) == EXTI_PinSource12) || \ - ((PINSOURCE) == EXTI_PinSource13) || \ - ((PINSOURCE) == EXTI_PinSource14) || \ - ((PINSOURCE) == EXTI_PinSource15)) -/** - * @} - */ - - -/** @defgroup SYSCFG_Memory_Remap_Config - * @{ - */ -#define SYSCFG_MemoryRemap_Flash ((uint8_t)0x00) -#define SYSCFG_MemoryRemap_SystemFlash ((uint8_t)0x01) -#define SYSCFG_MemoryRemap_FSMC ((uint8_t)0x02) -#define SYSCFG_MemoryRemap_SRAM ((uint8_t)0x03) - -#define IS_SYSCFG_MEMORY_REMAP_CONFING(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \ - ((REMAP) == SYSCFG_MemoryRemap_SystemFlash) || \ - ((REMAP) == SYSCFG_MemoryRemap_SRAM) || \ - ((REMAP) == SYSCFG_MemoryRemap_FSMC)) -/** - * @} - */ - - -/** @defgroup SYSCFG_ETHERNET_Media_Interface - * @{ - */ -#define SYSCFG_ETH_MediaInterface_MII ((uint32_t)0x00000000) -#define SYSCFG_ETH_MediaInterface_RMII ((uint32_t)0x00000001) - -#define IS_SYSCFG_ETH_MEDIA_INTERFACE(INTERFACE) (((INTERFACE) == SYSCFG_ETH_MediaInterface_MII) || \ - ((INTERFACE) == SYSCFG_ETH_MediaInterface_RMII)) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -void SYSCFG_DeInit(void); -void SYSCFG_MemoryRemapConfig(uint8_t SYSCFG_MemoryRemap); -void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex); -void SYSCFG_ETH_MediaInterfaceConfig(uint32_t SYSCFG_ETH_MediaInterface); -void SYSCFG_CompensationCellCmd(FunctionalState NewState); -FlagStatus SYSCFG_GetCompensationCellStatus(void); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F4xx_SYSCFG_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_tim.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_tim.h deleted file mode 100644 index 9bc8b698a..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_tim.h +++ /dev/null @@ -1,1144 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_tim.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the TIM firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_TIM_H -#define __STM32F4xx_TIM_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup TIM - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief TIM Time Base Init structure definition - * @note This structure is used with all TIMx except for TIM6 and TIM7. - */ - -typedef struct -{ - uint16_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. - This parameter can be a number between 0x0000 and 0xFFFF */ - - uint16_t TIM_CounterMode; /*!< Specifies the counter mode. - This parameter can be a value of @ref TIM_Counter_Mode */ - - uint32_t TIM_Period; /*!< Specifies the period value to be loaded into the active - Auto-Reload Register at the next update event. - This parameter must be a number between 0x0000 and 0xFFFF. */ - - uint16_t TIM_ClockDivision; /*!< Specifies the clock division. - This parameter can be a value of @ref TIM_Clock_Division_CKD */ - - uint8_t TIM_RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter - reaches zero, an update event is generated and counting restarts - from the RCR value (N). - This means in PWM mode that (N+1) corresponds to: - - the number of PWM periods in edge-aligned mode - - the number of half PWM period in center-aligned mode - This parameter must be a number between 0x00 and 0xFF. - @note This parameter is valid only for TIM1 and TIM8. */ -} TIM_TimeBaseInitTypeDef; - -/** - * @brief TIM Output Compare Init structure definition - */ - -typedef struct -{ - uint16_t TIM_OCMode; /*!< Specifies the TIM mode. - This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ - - uint16_t TIM_OutputState; /*!< Specifies the TIM Output Compare state. - This parameter can be a value of @ref TIM_Output_Compare_State */ - - uint16_t TIM_OutputNState; /*!< Specifies the TIM complementary Output Compare state. - This parameter can be a value of @ref TIM_Output_Compare_N_State - @note This parameter is valid only for TIM1 and TIM8. */ - - uint32_t TIM_Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. - This parameter can be a number between 0x0000 and 0xFFFF */ - - uint16_t TIM_OCPolarity; /*!< Specifies the output polarity. - This parameter can be a value of @ref TIM_Output_Compare_Polarity */ - - uint16_t TIM_OCNPolarity; /*!< Specifies the complementary output polarity. - This parameter can be a value of @ref TIM_Output_Compare_N_Polarity - @note This parameter is valid only for TIM1 and TIM8. */ - - uint16_t TIM_OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. - This parameter can be a value of @ref TIM_Output_Compare_Idle_State - @note This parameter is valid only for TIM1 and TIM8. */ - - uint16_t TIM_OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. - This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State - @note This parameter is valid only for TIM1 and TIM8. */ -} TIM_OCInitTypeDef; - -/** - * @brief TIM Input Capture Init structure definition - */ - -typedef struct -{ - - uint16_t TIM_Channel; /*!< Specifies the TIM channel. - This parameter can be a value of @ref TIM_Channel */ - - uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal. - This parameter can be a value of @ref TIM_Input_Capture_Polarity */ - - uint16_t TIM_ICSelection; /*!< Specifies the input. - This parameter can be a value of @ref TIM_Input_Capture_Selection */ - - uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler. - This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ - - uint16_t TIM_ICFilter; /*!< Specifies the input capture filter. - This parameter can be a number between 0x0 and 0xF */ -} TIM_ICInitTypeDef; - -/** - * @brief BDTR structure definition - * @note This structure is used only with TIM1 and TIM8. - */ - -typedef struct -{ - - uint16_t TIM_OSSRState; /*!< Specifies the Off-State selection used in Run mode. - This parameter can be a value of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */ - - uint16_t TIM_OSSIState; /*!< Specifies the Off-State used in Idle state. - This parameter can be a value of @ref TIM_OSSI_Off_State_Selection_for_Idle_mode_state */ - - uint16_t TIM_LOCKLevel; /*!< Specifies the LOCK level parameters. - This parameter can be a value of @ref TIM_Lock_level */ - - uint16_t TIM_DeadTime; /*!< Specifies the delay time between the switching-off and the - switching-on of the outputs. - This parameter can be a number between 0x00 and 0xFF */ - - uint16_t TIM_Break; /*!< Specifies whether the TIM Break input is enabled or not. - This parameter can be a value of @ref TIM_Break_Input_enable_disable */ - - uint16_t TIM_BreakPolarity; /*!< Specifies the TIM Break Input pin polarity. - This parameter can be a value of @ref TIM_Break_Polarity */ - - uint16_t TIM_AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature is enabled or not. - This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */ -} TIM_BDTRInitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup TIM_Exported_constants - * @{ - */ - -#define IS_TIM_ALL_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM5) || \ - ((PERIPH) == TIM6) || \ - ((PERIPH) == TIM7) || \ - ((PERIPH) == TIM8) || \ - ((PERIPH) == TIM9) || \ - ((PERIPH) == TIM10) || \ - ((PERIPH) == TIM11) || \ - ((PERIPH) == TIM12) || \ - (((PERIPH) == TIM13) || \ - ((PERIPH) == TIM14))) -/* LIST1: TIM1, TIM2, TIM3, TIM4, TIM5, TIM8, TIM9, TIM10, TIM11, TIM12, TIM13 and TIM14 */ -#define IS_TIM_LIST1_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM5) || \ - ((PERIPH) == TIM8) || \ - ((PERIPH) == TIM9) || \ - ((PERIPH) == TIM10) || \ - ((PERIPH) == TIM11) || \ - ((PERIPH) == TIM12) || \ - ((PERIPH) == TIM13) || \ - ((PERIPH) == TIM14)) - -/* LIST2: TIM1, TIM2, TIM3, TIM4, TIM5, TIM8, TIM9 and TIM12 */ -#define IS_TIM_LIST2_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM5) || \ - ((PERIPH) == TIM8) || \ - ((PERIPH) == TIM9) || \ - ((PERIPH) == TIM12)) -/* LIST3: TIM1, TIM2, TIM3, TIM4, TIM5 and TIM8 */ -#define IS_TIM_LIST3_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM5) || \ - ((PERIPH) == TIM8)) -/* LIST4: TIM1 and TIM8 */ -#define IS_TIM_LIST4_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM8)) -/* LIST5: TIM1, TIM2, TIM3, TIM4, TIM5, TIM6, TIM7 and TIM8 */ -#define IS_TIM_LIST5_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ - ((PERIPH) == TIM2) || \ - ((PERIPH) == TIM3) || \ - ((PERIPH) == TIM4) || \ - ((PERIPH) == TIM5) || \ - ((PERIPH) == TIM6) || \ - ((PERIPH) == TIM7) || \ - ((PERIPH) == TIM8)) -/* LIST6: TIM2, TIM5 and TIM11 */ -#define IS_TIM_LIST6_PERIPH(TIMx)(((TIMx) == TIM2) || \ - ((TIMx) == TIM5) || \ - ((TIMx) == TIM11)) - -/** @defgroup TIM_Output_Compare_and_PWM_modes - * @{ - */ - -#define TIM_OCMode_Timing ((uint16_t)0x0000) -#define TIM_OCMode_Active ((uint16_t)0x0010) -#define TIM_OCMode_Inactive ((uint16_t)0x0020) -#define TIM_OCMode_Toggle ((uint16_t)0x0030) -#define TIM_OCMode_PWM1 ((uint16_t)0x0060) -#define TIM_OCMode_PWM2 ((uint16_t)0x0070) -#define IS_TIM_OC_MODE(MODE) (((MODE) == TIM_OCMode_Timing) || \ - ((MODE) == TIM_OCMode_Active) || \ - ((MODE) == TIM_OCMode_Inactive) || \ - ((MODE) == TIM_OCMode_Toggle)|| \ - ((MODE) == TIM_OCMode_PWM1) || \ - ((MODE) == TIM_OCMode_PWM2)) -#define IS_TIM_OCM(MODE) (((MODE) == TIM_OCMode_Timing) || \ - ((MODE) == TIM_OCMode_Active) || \ - ((MODE) == TIM_OCMode_Inactive) || \ - ((MODE) == TIM_OCMode_Toggle)|| \ - ((MODE) == TIM_OCMode_PWM1) || \ - ((MODE) == TIM_OCMode_PWM2) || \ - ((MODE) == TIM_ForcedAction_Active) || \ - ((MODE) == TIM_ForcedAction_InActive)) -/** - * @} - */ - -/** @defgroup TIM_One_Pulse_Mode - * @{ - */ - -#define TIM_OPMode_Single ((uint16_t)0x0008) -#define TIM_OPMode_Repetitive ((uint16_t)0x0000) -#define IS_TIM_OPM_MODE(MODE) (((MODE) == TIM_OPMode_Single) || \ - ((MODE) == TIM_OPMode_Repetitive)) -/** - * @} - */ - -/** @defgroup TIM_Channel - * @{ - */ - -#define TIM_Channel_1 ((uint16_t)0x0000) -#define TIM_Channel_2 ((uint16_t)0x0004) -#define TIM_Channel_3 ((uint16_t)0x0008) -#define TIM_Channel_4 ((uint16_t)0x000C) - -#define IS_TIM_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ - ((CHANNEL) == TIM_Channel_2) || \ - ((CHANNEL) == TIM_Channel_3) || \ - ((CHANNEL) == TIM_Channel_4)) - -#define IS_TIM_PWMI_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ - ((CHANNEL) == TIM_Channel_2)) -#define IS_TIM_COMPLEMENTARY_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ - ((CHANNEL) == TIM_Channel_2) || \ - ((CHANNEL) == TIM_Channel_3)) -/** - * @} - */ - -/** @defgroup TIM_Clock_Division_CKD - * @{ - */ - -#define TIM_CKD_DIV1 ((uint16_t)0x0000) -#define TIM_CKD_DIV2 ((uint16_t)0x0100) -#define TIM_CKD_DIV4 ((uint16_t)0x0200) -#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \ - ((DIV) == TIM_CKD_DIV2) || \ - ((DIV) == TIM_CKD_DIV4)) -/** - * @} - */ - -/** @defgroup TIM_Counter_Mode - * @{ - */ - -#define TIM_CounterMode_Up ((uint16_t)0x0000) -#define TIM_CounterMode_Down ((uint16_t)0x0010) -#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020) -#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040) -#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060) -#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) || \ - ((MODE) == TIM_CounterMode_Down) || \ - ((MODE) == TIM_CounterMode_CenterAligned1) || \ - ((MODE) == TIM_CounterMode_CenterAligned2) || \ - ((MODE) == TIM_CounterMode_CenterAligned3)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_Polarity - * @{ - */ - -#define TIM_OCPolarity_High ((uint16_t)0x0000) -#define TIM_OCPolarity_Low ((uint16_t)0x0002) -#define IS_TIM_OC_POLARITY(POLARITY) (((POLARITY) == TIM_OCPolarity_High) || \ - ((POLARITY) == TIM_OCPolarity_Low)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_N_Polarity - * @{ - */ - -#define TIM_OCNPolarity_High ((uint16_t)0x0000) -#define TIM_OCNPolarity_Low ((uint16_t)0x0008) -#define IS_TIM_OCN_POLARITY(POLARITY) (((POLARITY) == TIM_OCNPolarity_High) || \ - ((POLARITY) == TIM_OCNPolarity_Low)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_State - * @{ - */ - -#define TIM_OutputState_Disable ((uint16_t)0x0000) -#define TIM_OutputState_Enable ((uint16_t)0x0001) -#define IS_TIM_OUTPUT_STATE(STATE) (((STATE) == TIM_OutputState_Disable) || \ - ((STATE) == TIM_OutputState_Enable)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_N_State - * @{ - */ - -#define TIM_OutputNState_Disable ((uint16_t)0x0000) -#define TIM_OutputNState_Enable ((uint16_t)0x0004) -#define IS_TIM_OUTPUTN_STATE(STATE) (((STATE) == TIM_OutputNState_Disable) || \ - ((STATE) == TIM_OutputNState_Enable)) -/** - * @} - */ - -/** @defgroup TIM_Capture_Compare_State - * @{ - */ - -#define TIM_CCx_Enable ((uint16_t)0x0001) -#define TIM_CCx_Disable ((uint16_t)0x0000) -#define IS_TIM_CCX(CCX) (((CCX) == TIM_CCx_Enable) || \ - ((CCX) == TIM_CCx_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Capture_Compare_N_State - * @{ - */ - -#define TIM_CCxN_Enable ((uint16_t)0x0004) -#define TIM_CCxN_Disable ((uint16_t)0x0000) -#define IS_TIM_CCXN(CCXN) (((CCXN) == TIM_CCxN_Enable) || \ - ((CCXN) == TIM_CCxN_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Break_Input_enable_disable - * @{ - */ - -#define TIM_Break_Enable ((uint16_t)0x1000) -#define TIM_Break_Disable ((uint16_t)0x0000) -#define IS_TIM_BREAK_STATE(STATE) (((STATE) == TIM_Break_Enable) || \ - ((STATE) == TIM_Break_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Break_Polarity - * @{ - */ - -#define TIM_BreakPolarity_Low ((uint16_t)0x0000) -#define TIM_BreakPolarity_High ((uint16_t)0x2000) -#define IS_TIM_BREAK_POLARITY(POLARITY) (((POLARITY) == TIM_BreakPolarity_Low) || \ - ((POLARITY) == TIM_BreakPolarity_High)) -/** - * @} - */ - -/** @defgroup TIM_AOE_Bit_Set_Reset - * @{ - */ - -#define TIM_AutomaticOutput_Enable ((uint16_t)0x4000) -#define TIM_AutomaticOutput_Disable ((uint16_t)0x0000) -#define IS_TIM_AUTOMATIC_OUTPUT_STATE(STATE) (((STATE) == TIM_AutomaticOutput_Enable) || \ - ((STATE) == TIM_AutomaticOutput_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Lock_level - * @{ - */ - -#define TIM_LOCKLevel_OFF ((uint16_t)0x0000) -#define TIM_LOCKLevel_1 ((uint16_t)0x0100) -#define TIM_LOCKLevel_2 ((uint16_t)0x0200) -#define TIM_LOCKLevel_3 ((uint16_t)0x0300) -#define IS_TIM_LOCK_LEVEL(LEVEL) (((LEVEL) == TIM_LOCKLevel_OFF) || \ - ((LEVEL) == TIM_LOCKLevel_1) || \ - ((LEVEL) == TIM_LOCKLevel_2) || \ - ((LEVEL) == TIM_LOCKLevel_3)) -/** - * @} - */ - -/** @defgroup TIM_OSSI_Off_State_Selection_for_Idle_mode_state - * @{ - */ - -#define TIM_OSSIState_Enable ((uint16_t)0x0400) -#define TIM_OSSIState_Disable ((uint16_t)0x0000) -#define IS_TIM_OSSI_STATE(STATE) (((STATE) == TIM_OSSIState_Enable) || \ - ((STATE) == TIM_OSSIState_Disable)) -/** - * @} - */ - -/** @defgroup TIM_OSSR_Off_State_Selection_for_Run_mode_state - * @{ - */ - -#define TIM_OSSRState_Enable ((uint16_t)0x0800) -#define TIM_OSSRState_Disable ((uint16_t)0x0000) -#define IS_TIM_OSSR_STATE(STATE) (((STATE) == TIM_OSSRState_Enable) || \ - ((STATE) == TIM_OSSRState_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_Idle_State - * @{ - */ - -#define TIM_OCIdleState_Set ((uint16_t)0x0100) -#define TIM_OCIdleState_Reset ((uint16_t)0x0000) -#define IS_TIM_OCIDLE_STATE(STATE) (((STATE) == TIM_OCIdleState_Set) || \ - ((STATE) == TIM_OCIdleState_Reset)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_N_Idle_State - * @{ - */ - -#define TIM_OCNIdleState_Set ((uint16_t)0x0200) -#define TIM_OCNIdleState_Reset ((uint16_t)0x0000) -#define IS_TIM_OCNIDLE_STATE(STATE) (((STATE) == TIM_OCNIdleState_Set) || \ - ((STATE) == TIM_OCNIdleState_Reset)) -/** - * @} - */ - -/** @defgroup TIM_Input_Capture_Polarity - * @{ - */ - -#define TIM_ICPolarity_Rising ((uint16_t)0x0000) -#define TIM_ICPolarity_Falling ((uint16_t)0x0002) -#define TIM_ICPolarity_BothEdge ((uint16_t)0x000A) -#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \ - ((POLARITY) == TIM_ICPolarity_Falling)|| \ - ((POLARITY) == TIM_ICPolarity_BothEdge)) -/** - * @} - */ - -/** @defgroup TIM_Input_Capture_Selection - * @{ - */ - -#define TIM_ICSelection_DirectTI ((uint16_t)0x0001) /*!< TIM Input 1, 2, 3 or 4 is selected to be - connected to IC1, IC2, IC3 or IC4, respectively */ -#define TIM_ICSelection_IndirectTI ((uint16_t)0x0002) /*!< TIM Input 1, 2, 3 or 4 is selected to be - connected to IC2, IC1, IC4 or IC3, respectively. */ -#define TIM_ICSelection_TRC ((uint16_t)0x0003) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC. */ -#define IS_TIM_IC_SELECTION(SELECTION) (((SELECTION) == TIM_ICSelection_DirectTI) || \ - ((SELECTION) == TIM_ICSelection_IndirectTI) || \ - ((SELECTION) == TIM_ICSelection_TRC)) -/** - * @} - */ - -/** @defgroup TIM_Input_Capture_Prescaler - * @{ - */ - -#define TIM_ICPSC_DIV1 ((uint16_t)0x0000) /*!< Capture performed each time an edge is detected on the capture input. */ -#define TIM_ICPSC_DIV2 ((uint16_t)0x0004) /*!< Capture performed once every 2 events. */ -#define TIM_ICPSC_DIV4 ((uint16_t)0x0008) /*!< Capture performed once every 4 events. */ -#define TIM_ICPSC_DIV8 ((uint16_t)0x000C) /*!< Capture performed once every 8 events. */ -#define IS_TIM_IC_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ICPSC_DIV1) || \ - ((PRESCALER) == TIM_ICPSC_DIV2) || \ - ((PRESCALER) == TIM_ICPSC_DIV4) || \ - ((PRESCALER) == TIM_ICPSC_DIV8)) -/** - * @} - */ - -/** @defgroup TIM_interrupt_sources - * @{ - */ - -#define TIM_IT_Update ((uint16_t)0x0001) -#define TIM_IT_CC1 ((uint16_t)0x0002) -#define TIM_IT_CC2 ((uint16_t)0x0004) -#define TIM_IT_CC3 ((uint16_t)0x0008) -#define TIM_IT_CC4 ((uint16_t)0x0010) -#define TIM_IT_COM ((uint16_t)0x0020) -#define TIM_IT_Trigger ((uint16_t)0x0040) -#define TIM_IT_Break ((uint16_t)0x0080) -#define IS_TIM_IT(IT) ((((IT) & (uint16_t)0xFF00) == 0x0000) && ((IT) != 0x0000)) - -#define IS_TIM_GET_IT(IT) (((IT) == TIM_IT_Update) || \ - ((IT) == TIM_IT_CC1) || \ - ((IT) == TIM_IT_CC2) || \ - ((IT) == TIM_IT_CC3) || \ - ((IT) == TIM_IT_CC4) || \ - ((IT) == TIM_IT_COM) || \ - ((IT) == TIM_IT_Trigger) || \ - ((IT) == TIM_IT_Break)) -/** - * @} - */ - -/** @defgroup TIM_DMA_Base_address - * @{ - */ - -#define TIM_DMABase_CR1 ((uint16_t)0x0000) -#define TIM_DMABase_CR2 ((uint16_t)0x0001) -#define TIM_DMABase_SMCR ((uint16_t)0x0002) -#define TIM_DMABase_DIER ((uint16_t)0x0003) -#define TIM_DMABase_SR ((uint16_t)0x0004) -#define TIM_DMABase_EGR ((uint16_t)0x0005) -#define TIM_DMABase_CCMR1 ((uint16_t)0x0006) -#define TIM_DMABase_CCMR2 ((uint16_t)0x0007) -#define TIM_DMABase_CCER ((uint16_t)0x0008) -#define TIM_DMABase_CNT ((uint16_t)0x0009) -#define TIM_DMABase_PSC ((uint16_t)0x000A) -#define TIM_DMABase_ARR ((uint16_t)0x000B) -#define TIM_DMABase_RCR ((uint16_t)0x000C) -#define TIM_DMABase_CCR1 ((uint16_t)0x000D) -#define TIM_DMABase_CCR2 ((uint16_t)0x000E) -#define TIM_DMABase_CCR3 ((uint16_t)0x000F) -#define TIM_DMABase_CCR4 ((uint16_t)0x0010) -#define TIM_DMABase_BDTR ((uint16_t)0x0011) -#define TIM_DMABase_DCR ((uint16_t)0x0012) -#define TIM_DMABase_OR ((uint16_t)0x0013) -#define IS_TIM_DMA_BASE(BASE) (((BASE) == TIM_DMABase_CR1) || \ - ((BASE) == TIM_DMABase_CR2) || \ - ((BASE) == TIM_DMABase_SMCR) || \ - ((BASE) == TIM_DMABase_DIER) || \ - ((BASE) == TIM_DMABase_SR) || \ - ((BASE) == TIM_DMABase_EGR) || \ - ((BASE) == TIM_DMABase_CCMR1) || \ - ((BASE) == TIM_DMABase_CCMR2) || \ - ((BASE) == TIM_DMABase_CCER) || \ - ((BASE) == TIM_DMABase_CNT) || \ - ((BASE) == TIM_DMABase_PSC) || \ - ((BASE) == TIM_DMABase_ARR) || \ - ((BASE) == TIM_DMABase_RCR) || \ - ((BASE) == TIM_DMABase_CCR1) || \ - ((BASE) == TIM_DMABase_CCR2) || \ - ((BASE) == TIM_DMABase_CCR3) || \ - ((BASE) == TIM_DMABase_CCR4) || \ - ((BASE) == TIM_DMABase_BDTR) || \ - ((BASE) == TIM_DMABase_DCR) || \ - ((BASE) == TIM_DMABase_OR)) -/** - * @} - */ - -/** @defgroup TIM_DMA_Burst_Length - * @{ - */ - -#define TIM_DMABurstLength_1Transfer ((uint16_t)0x0000) -#define TIM_DMABurstLength_2Transfers ((uint16_t)0x0100) -#define TIM_DMABurstLength_3Transfers ((uint16_t)0x0200) -#define TIM_DMABurstLength_4Transfers ((uint16_t)0x0300) -#define TIM_DMABurstLength_5Transfers ((uint16_t)0x0400) -#define TIM_DMABurstLength_6Transfers ((uint16_t)0x0500) -#define TIM_DMABurstLength_7Transfers ((uint16_t)0x0600) -#define TIM_DMABurstLength_8Transfers ((uint16_t)0x0700) -#define TIM_DMABurstLength_9Transfers ((uint16_t)0x0800) -#define TIM_DMABurstLength_10Transfers ((uint16_t)0x0900) -#define TIM_DMABurstLength_11Transfers ((uint16_t)0x0A00) -#define TIM_DMABurstLength_12Transfers ((uint16_t)0x0B00) -#define TIM_DMABurstLength_13Transfers ((uint16_t)0x0C00) -#define TIM_DMABurstLength_14Transfers ((uint16_t)0x0D00) -#define TIM_DMABurstLength_15Transfers ((uint16_t)0x0E00) -#define TIM_DMABurstLength_16Transfers ((uint16_t)0x0F00) -#define TIM_DMABurstLength_17Transfers ((uint16_t)0x1000) -#define TIM_DMABurstLength_18Transfers ((uint16_t)0x1100) -#define IS_TIM_DMA_LENGTH(LENGTH) (((LENGTH) == TIM_DMABurstLength_1Transfer) || \ - ((LENGTH) == TIM_DMABurstLength_2Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_3Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_4Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_5Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_6Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_7Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_8Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_9Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_10Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_11Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_12Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_13Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_14Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_15Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_16Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_17Transfers) || \ - ((LENGTH) == TIM_DMABurstLength_18Transfers)) -/** - * @} - */ - -/** @defgroup TIM_DMA_sources - * @{ - */ - -#define TIM_DMA_Update ((uint16_t)0x0100) -#define TIM_DMA_CC1 ((uint16_t)0x0200) -#define TIM_DMA_CC2 ((uint16_t)0x0400) -#define TIM_DMA_CC3 ((uint16_t)0x0800) -#define TIM_DMA_CC4 ((uint16_t)0x1000) -#define TIM_DMA_COM ((uint16_t)0x2000) -#define TIM_DMA_Trigger ((uint16_t)0x4000) -#define IS_TIM_DMA_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0x80FF) == 0x0000) && ((SOURCE) != 0x0000)) - -/** - * @} - */ - -/** @defgroup TIM_External_Trigger_Prescaler - * @{ - */ - -#define TIM_ExtTRGPSC_OFF ((uint16_t)0x0000) -#define TIM_ExtTRGPSC_DIV2 ((uint16_t)0x1000) -#define TIM_ExtTRGPSC_DIV4 ((uint16_t)0x2000) -#define TIM_ExtTRGPSC_DIV8 ((uint16_t)0x3000) -#define IS_TIM_EXT_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ExtTRGPSC_OFF) || \ - ((PRESCALER) == TIM_ExtTRGPSC_DIV2) || \ - ((PRESCALER) == TIM_ExtTRGPSC_DIV4) || \ - ((PRESCALER) == TIM_ExtTRGPSC_DIV8)) -/** - * @} - */ - -/** @defgroup TIM_Internal_Trigger_Selection - * @{ - */ - -#define TIM_TS_ITR0 ((uint16_t)0x0000) -#define TIM_TS_ITR1 ((uint16_t)0x0010) -#define TIM_TS_ITR2 ((uint16_t)0x0020) -#define TIM_TS_ITR3 ((uint16_t)0x0030) -#define TIM_TS_TI1F_ED ((uint16_t)0x0040) -#define TIM_TS_TI1FP1 ((uint16_t)0x0050) -#define TIM_TS_TI2FP2 ((uint16_t)0x0060) -#define TIM_TS_ETRF ((uint16_t)0x0070) -#define IS_TIM_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ - ((SELECTION) == TIM_TS_ITR1) || \ - ((SELECTION) == TIM_TS_ITR2) || \ - ((SELECTION) == TIM_TS_ITR3) || \ - ((SELECTION) == TIM_TS_TI1F_ED) || \ - ((SELECTION) == TIM_TS_TI1FP1) || \ - ((SELECTION) == TIM_TS_TI2FP2) || \ - ((SELECTION) == TIM_TS_ETRF)) -#define IS_TIM_INTERNAL_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ - ((SELECTION) == TIM_TS_ITR1) || \ - ((SELECTION) == TIM_TS_ITR2) || \ - ((SELECTION) == TIM_TS_ITR3)) -/** - * @} - */ - -/** @defgroup TIM_TIx_External_Clock_Source - * @{ - */ - -#define TIM_TIxExternalCLK1Source_TI1 ((uint16_t)0x0050) -#define TIM_TIxExternalCLK1Source_TI2 ((uint16_t)0x0060) -#define TIM_TIxExternalCLK1Source_TI1ED ((uint16_t)0x0040) - -/** - * @} - */ - -/** @defgroup TIM_External_Trigger_Polarity - * @{ - */ -#define TIM_ExtTRGPolarity_Inverted ((uint16_t)0x8000) -#define TIM_ExtTRGPolarity_NonInverted ((uint16_t)0x0000) -#define IS_TIM_EXT_POLARITY(POLARITY) (((POLARITY) == TIM_ExtTRGPolarity_Inverted) || \ - ((POLARITY) == TIM_ExtTRGPolarity_NonInverted)) -/** - * @} - */ - -/** @defgroup TIM_Prescaler_Reload_Mode - * @{ - */ - -#define TIM_PSCReloadMode_Update ((uint16_t)0x0000) -#define TIM_PSCReloadMode_Immediate ((uint16_t)0x0001) -#define IS_TIM_PRESCALER_RELOAD(RELOAD) (((RELOAD) == TIM_PSCReloadMode_Update) || \ - ((RELOAD) == TIM_PSCReloadMode_Immediate)) -/** - * @} - */ - -/** @defgroup TIM_Forced_Action - * @{ - */ - -#define TIM_ForcedAction_Active ((uint16_t)0x0050) -#define TIM_ForcedAction_InActive ((uint16_t)0x0040) -#define IS_TIM_FORCED_ACTION(ACTION) (((ACTION) == TIM_ForcedAction_Active) || \ - ((ACTION) == TIM_ForcedAction_InActive)) -/** - * @} - */ - -/** @defgroup TIM_Encoder_Mode - * @{ - */ - -#define TIM_EncoderMode_TI1 ((uint16_t)0x0001) -#define TIM_EncoderMode_TI2 ((uint16_t)0x0002) -#define TIM_EncoderMode_TI12 ((uint16_t)0x0003) -#define IS_TIM_ENCODER_MODE(MODE) (((MODE) == TIM_EncoderMode_TI1) || \ - ((MODE) == TIM_EncoderMode_TI2) || \ - ((MODE) == TIM_EncoderMode_TI12)) -/** - * @} - */ - - -/** @defgroup TIM_Event_Source - * @{ - */ - -#define TIM_EventSource_Update ((uint16_t)0x0001) -#define TIM_EventSource_CC1 ((uint16_t)0x0002) -#define TIM_EventSource_CC2 ((uint16_t)0x0004) -#define TIM_EventSource_CC3 ((uint16_t)0x0008) -#define TIM_EventSource_CC4 ((uint16_t)0x0010) -#define TIM_EventSource_COM ((uint16_t)0x0020) -#define TIM_EventSource_Trigger ((uint16_t)0x0040) -#define TIM_EventSource_Break ((uint16_t)0x0080) -#define IS_TIM_EVENT_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0xFF00) == 0x0000) && ((SOURCE) != 0x0000)) - -/** - * @} - */ - -/** @defgroup TIM_Update_Source - * @{ - */ - -#define TIM_UpdateSource_Global ((uint16_t)0x0000) /*!< Source of update is the counter overflow/underflow - or the setting of UG bit, or an update generation - through the slave mode controller. */ -#define TIM_UpdateSource_Regular ((uint16_t)0x0001) /*!< Source of update is counter overflow/underflow. */ -#define IS_TIM_UPDATE_SOURCE(SOURCE) (((SOURCE) == TIM_UpdateSource_Global) || \ - ((SOURCE) == TIM_UpdateSource_Regular)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_Preload_State - * @{ - */ - -#define TIM_OCPreload_Enable ((uint16_t)0x0008) -#define TIM_OCPreload_Disable ((uint16_t)0x0000) -#define IS_TIM_OCPRELOAD_STATE(STATE) (((STATE) == TIM_OCPreload_Enable) || \ - ((STATE) == TIM_OCPreload_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_Fast_State - * @{ - */ - -#define TIM_OCFast_Enable ((uint16_t)0x0004) -#define TIM_OCFast_Disable ((uint16_t)0x0000) -#define IS_TIM_OCFAST_STATE(STATE) (((STATE) == TIM_OCFast_Enable) || \ - ((STATE) == TIM_OCFast_Disable)) - -/** - * @} - */ - -/** @defgroup TIM_Output_Compare_Clear_State - * @{ - */ - -#define TIM_OCClear_Enable ((uint16_t)0x0080) -#define TIM_OCClear_Disable ((uint16_t)0x0000) -#define IS_TIM_OCCLEAR_STATE(STATE) (((STATE) == TIM_OCClear_Enable) || \ - ((STATE) == TIM_OCClear_Disable)) -/** - * @} - */ - -/** @defgroup TIM_Trigger_Output_Source - * @{ - */ - -#define TIM_TRGOSource_Reset ((uint16_t)0x0000) -#define TIM_TRGOSource_Enable ((uint16_t)0x0010) -#define TIM_TRGOSource_Update ((uint16_t)0x0020) -#define TIM_TRGOSource_OC1 ((uint16_t)0x0030) -#define TIM_TRGOSource_OC1Ref ((uint16_t)0x0040) -#define TIM_TRGOSource_OC2Ref ((uint16_t)0x0050) -#define TIM_TRGOSource_OC3Ref ((uint16_t)0x0060) -#define TIM_TRGOSource_OC4Ref ((uint16_t)0x0070) -#define IS_TIM_TRGO_SOURCE(SOURCE) (((SOURCE) == TIM_TRGOSource_Reset) || \ - ((SOURCE) == TIM_TRGOSource_Enable) || \ - ((SOURCE) == TIM_TRGOSource_Update) || \ - ((SOURCE) == TIM_TRGOSource_OC1) || \ - ((SOURCE) == TIM_TRGOSource_OC1Ref) || \ - ((SOURCE) == TIM_TRGOSource_OC2Ref) || \ - ((SOURCE) == TIM_TRGOSource_OC3Ref) || \ - ((SOURCE) == TIM_TRGOSource_OC4Ref)) -/** - * @} - */ - -/** @defgroup TIM_Slave_Mode - * @{ - */ - -#define TIM_SlaveMode_Reset ((uint16_t)0x0004) -#define TIM_SlaveMode_Gated ((uint16_t)0x0005) -#define TIM_SlaveMode_Trigger ((uint16_t)0x0006) -#define TIM_SlaveMode_External1 ((uint16_t)0x0007) -#define IS_TIM_SLAVE_MODE(MODE) (((MODE) == TIM_SlaveMode_Reset) || \ - ((MODE) == TIM_SlaveMode_Gated) || \ - ((MODE) == TIM_SlaveMode_Trigger) || \ - ((MODE) == TIM_SlaveMode_External1)) -/** - * @} - */ - -/** @defgroup TIM_Master_Slave_Mode - * @{ - */ - -#define TIM_MasterSlaveMode_Enable ((uint16_t)0x0080) -#define TIM_MasterSlaveMode_Disable ((uint16_t)0x0000) -#define IS_TIM_MSM_STATE(STATE) (((STATE) == TIM_MasterSlaveMode_Enable) || \ - ((STATE) == TIM_MasterSlaveMode_Disable)) -/** - * @} - */ -/** @defgroup TIM_Remap - * @{ - */ - -#define TIM2_TIM8_TRGO ((uint16_t)0x0000) -#define TIM2_ETH_PTP ((uint16_t)0x0400) -#define TIM2_USBFS_SOF ((uint16_t)0x0800) -#define TIM2_USBHS_SOF ((uint16_t)0x0C00) - -#define TIM5_GPIO ((uint16_t)0x0000) -#define TIM5_LSI ((uint16_t)0x0040) -#define TIM5_LSE ((uint16_t)0x0080) -#define TIM5_RTC ((uint16_t)0x00C0) - -#define TIM11_GPIO ((uint16_t)0x0000) -#define TIM11_HSE ((uint16_t)0x0002) - -#define IS_TIM_REMAP(TIM_REMAP) (((TIM_REMAP) == TIM2_TIM8_TRGO)||\ - ((TIM_REMAP) == TIM2_ETH_PTP)||\ - ((TIM_REMAP) == TIM2_USBFS_SOF)||\ - ((TIM_REMAP) == TIM2_USBHS_SOF)||\ - ((TIM_REMAP) == TIM5_GPIO)||\ - ((TIM_REMAP) == TIM5_LSI)||\ - ((TIM_REMAP) == TIM5_LSE)||\ - ((TIM_REMAP) == TIM5_RTC)||\ - ((TIM_REMAP) == TIM11_GPIO)||\ - ((TIM_REMAP) == TIM11_HSE)) - -/** - * @} - */ -/** @defgroup TIM_Flags - * @{ - */ - -#define TIM_FLAG_Update ((uint16_t)0x0001) -#define TIM_FLAG_CC1 ((uint16_t)0x0002) -#define TIM_FLAG_CC2 ((uint16_t)0x0004) -#define TIM_FLAG_CC3 ((uint16_t)0x0008) -#define TIM_FLAG_CC4 ((uint16_t)0x0010) -#define TIM_FLAG_COM ((uint16_t)0x0020) -#define TIM_FLAG_Trigger ((uint16_t)0x0040) -#define TIM_FLAG_Break ((uint16_t)0x0080) -#define TIM_FLAG_CC1OF ((uint16_t)0x0200) -#define TIM_FLAG_CC2OF ((uint16_t)0x0400) -#define TIM_FLAG_CC3OF ((uint16_t)0x0800) -#define TIM_FLAG_CC4OF ((uint16_t)0x1000) -#define IS_TIM_GET_FLAG(FLAG) (((FLAG) == TIM_FLAG_Update) || \ - ((FLAG) == TIM_FLAG_CC1) || \ - ((FLAG) == TIM_FLAG_CC2) || \ - ((FLAG) == TIM_FLAG_CC3) || \ - ((FLAG) == TIM_FLAG_CC4) || \ - ((FLAG) == TIM_FLAG_COM) || \ - ((FLAG) == TIM_FLAG_Trigger) || \ - ((FLAG) == TIM_FLAG_Break) || \ - ((FLAG) == TIM_FLAG_CC1OF) || \ - ((FLAG) == TIM_FLAG_CC2OF) || \ - ((FLAG) == TIM_FLAG_CC3OF) || \ - ((FLAG) == TIM_FLAG_CC4OF)) - -/** - * @} - */ - -/** @defgroup TIM_Input_Capture_Filer_Value - * @{ - */ - -#define IS_TIM_IC_FILTER(ICFILTER) ((ICFILTER) <= 0xF) -/** - * @} - */ - -/** @defgroup TIM_External_Trigger_Filter - * @{ - */ - -#define IS_TIM_EXT_FILTER(EXTFILTER) ((EXTFILTER) <= 0xF) -/** - * @} - */ - -/** @defgroup TIM_Legacy - * @{ - */ - -#define TIM_DMABurstLength_1Byte TIM_DMABurstLength_1Transfer -#define TIM_DMABurstLength_2Bytes TIM_DMABurstLength_2Transfers -#define TIM_DMABurstLength_3Bytes TIM_DMABurstLength_3Transfers -#define TIM_DMABurstLength_4Bytes TIM_DMABurstLength_4Transfers -#define TIM_DMABurstLength_5Bytes TIM_DMABurstLength_5Transfers -#define TIM_DMABurstLength_6Bytes TIM_DMABurstLength_6Transfers -#define TIM_DMABurstLength_7Bytes TIM_DMABurstLength_7Transfers -#define TIM_DMABurstLength_8Bytes TIM_DMABurstLength_8Transfers -#define TIM_DMABurstLength_9Bytes TIM_DMABurstLength_9Transfers -#define TIM_DMABurstLength_10Bytes TIM_DMABurstLength_10Transfers -#define TIM_DMABurstLength_11Bytes TIM_DMABurstLength_11Transfers -#define TIM_DMABurstLength_12Bytes TIM_DMABurstLength_12Transfers -#define TIM_DMABurstLength_13Bytes TIM_DMABurstLength_13Transfers -#define TIM_DMABurstLength_14Bytes TIM_DMABurstLength_14Transfers -#define TIM_DMABurstLength_15Bytes TIM_DMABurstLength_15Transfers -#define TIM_DMABurstLength_16Bytes TIM_DMABurstLength_16Transfers -#define TIM_DMABurstLength_17Bytes TIM_DMABurstLength_17Transfers -#define TIM_DMABurstLength_18Bytes TIM_DMABurstLength_18Transfers -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* TimeBase management ********************************************************/ -void TIM_DeInit(TIM_TypeDef* TIMx); -void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); -void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); -void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode); -void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode); -void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter); -void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload); -uint32_t TIM_GetCounter(TIM_TypeDef* TIMx); -uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx); -void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState); -void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource); -void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState); -void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode); -void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD); -void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); - -/* Output Compare management **************************************************/ -void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct); -void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode); -void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1); -void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2); -void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3); -void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4); -void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); -void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); -void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); -void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); -void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); -void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); -void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); -void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); -void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); -void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); -void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); -void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); -void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); -void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); -void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); -void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); -void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); -void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); -void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); -void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); -void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); -void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); -void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); -void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx); -void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN); - -/* Input Capture management ***************************************************/ -void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); -void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct); -void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); -uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx); -uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx); -uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx); -uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx); -void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); -void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); -void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); -void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); - -/* Advanced-control timers (TIM1 and TIM8) specific features ******************/ -void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct); -void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct); -void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState); -void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState); -void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState); - -/* Interrupts, DMA and flags management ***************************************/ -void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState); -void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource); -FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); -void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); -ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT); -void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT); -void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength); -void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState); -void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState); - -/* Clocks management **********************************************************/ -void TIM_InternalClockConfig(TIM_TypeDef* TIMx); -void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); -void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, - uint16_t TIM_ICPolarity, uint16_t ICFilter); -void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, - uint16_t ExtTRGFilter); -void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, - uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); - -/* Synchronization management *************************************************/ -void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); -void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource); -void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); -void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode); -void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, - uint16_t ExtTRGFilter); - -/* Specific interface management **********************************************/ -void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, - uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity); -void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState); - -/* Specific remapping management **********************************************/ -void TIM_RemapConfig(TIM_TypeDef* TIMx, uint16_t TIM_Remap); - -#ifdef __cplusplus -} -#endif - -#endif /*__STM32F4xx_TIM_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_usart.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_usart.h deleted file mode 100644 index b7d84071e..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_usart.h +++ /dev/null @@ -1,412 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_usart.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the USART - * firmware library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_USART_H -#define __STM32F4xx_USART_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup USART - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -/** - * @brief USART Init Structure definition - */ - -typedef struct -{ - uint32_t USART_BaudRate; /*!< This member configures the USART communication baud rate. - The baud rate is computed using the following formula: - - IntegerDivider = ((PCLKx) / (8 * (OVR8+1) * (USART_InitStruct->USART_BaudRate))) - - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 8 * (OVR8+1)) + 0.5 - Where OVR8 is the "oversampling by 8 mode" configuration bit in the CR1 register. */ - - uint16_t USART_WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. - This parameter can be a value of @ref USART_Word_Length */ - - uint16_t USART_StopBits; /*!< Specifies the number of stop bits transmitted. - This parameter can be a value of @ref USART_Stop_Bits */ - - uint16_t USART_Parity; /*!< Specifies the parity mode. - This parameter can be a value of @ref USART_Parity - @note When parity is enabled, the computed parity is inserted - at the MSB position of the transmitted data (9th bit when - the word length is set to 9 data bits; 8th bit when the - word length is set to 8 data bits). */ - - uint16_t USART_Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled. - This parameter can be a value of @ref USART_Mode */ - - uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled - or disabled. - This parameter can be a value of @ref USART_Hardware_Flow_Control */ -} USART_InitTypeDef; - -/** - * @brief USART Clock Init Structure definition - */ - -typedef struct -{ - - uint16_t USART_Clock; /*!< Specifies whether the USART clock is enabled or disabled. - This parameter can be a value of @ref USART_Clock */ - - uint16_t USART_CPOL; /*!< Specifies the steady state of the serial clock. - This parameter can be a value of @ref USART_Clock_Polarity */ - - uint16_t USART_CPHA; /*!< Specifies the clock transition on which the bit capture is made. - This parameter can be a value of @ref USART_Clock_Phase */ - - uint16_t USART_LastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted - data bit (MSB) has to be output on the SCLK pin in synchronous mode. - This parameter can be a value of @ref USART_Last_Bit */ -} USART_ClockInitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup USART_Exported_Constants - * @{ - */ - -#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \ - ((PERIPH) == USART2) || \ - ((PERIPH) == USART3) || \ - ((PERIPH) == UART4) || \ - ((PERIPH) == UART5) || \ - ((PERIPH) == USART6)) - -#define IS_USART_1236_PERIPH(PERIPH) (((PERIPH) == USART1) || \ - ((PERIPH) == USART2) || \ - ((PERIPH) == USART3) || \ - ((PERIPH) == USART6)) - -/** @defgroup USART_Word_Length - * @{ - */ - -#define USART_WordLength_8b ((uint16_t)0x0000) -#define USART_WordLength_9b ((uint16_t)0x1000) - -#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WordLength_8b) || \ - ((LENGTH) == USART_WordLength_9b)) -/** - * @} - */ - -/** @defgroup USART_Stop_Bits - * @{ - */ - -#define USART_StopBits_1 ((uint16_t)0x0000) -#define USART_StopBits_0_5 ((uint16_t)0x1000) -#define USART_StopBits_2 ((uint16_t)0x2000) -#define USART_StopBits_1_5 ((uint16_t)0x3000) -#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_StopBits_1) || \ - ((STOPBITS) == USART_StopBits_0_5) || \ - ((STOPBITS) == USART_StopBits_2) || \ - ((STOPBITS) == USART_StopBits_1_5)) -/** - * @} - */ - -/** @defgroup USART_Parity - * @{ - */ - -#define USART_Parity_No ((uint16_t)0x0000) -#define USART_Parity_Even ((uint16_t)0x0400) -#define USART_Parity_Odd ((uint16_t)0x0600) -#define IS_USART_PARITY(PARITY) (((PARITY) == USART_Parity_No) || \ - ((PARITY) == USART_Parity_Even) || \ - ((PARITY) == USART_Parity_Odd)) -/** - * @} - */ - -/** @defgroup USART_Mode - * @{ - */ - -#define USART_Mode_Rx ((uint16_t)0x0004) -#define USART_Mode_Tx ((uint16_t)0x0008) -#define IS_USART_MODE(MODE) ((((MODE) & (uint16_t)0xFFF3) == 0x00) && ((MODE) != (uint16_t)0x00)) -/** - * @} - */ - -/** @defgroup USART_Hardware_Flow_Control - * @{ - */ -#define USART_HardwareFlowControl_None ((uint16_t)0x0000) -#define USART_HardwareFlowControl_RTS ((uint16_t)0x0100) -#define USART_HardwareFlowControl_CTS ((uint16_t)0x0200) -#define USART_HardwareFlowControl_RTS_CTS ((uint16_t)0x0300) -#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)\ - (((CONTROL) == USART_HardwareFlowControl_None) || \ - ((CONTROL) == USART_HardwareFlowControl_RTS) || \ - ((CONTROL) == USART_HardwareFlowControl_CTS) || \ - ((CONTROL) == USART_HardwareFlowControl_RTS_CTS)) -/** - * @} - */ - -/** @defgroup USART_Clock - * @{ - */ -#define USART_Clock_Disable ((uint16_t)0x0000) -#define USART_Clock_Enable ((uint16_t)0x0800) -#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_Clock_Disable) || \ - ((CLOCK) == USART_Clock_Enable)) -/** - * @} - */ - -/** @defgroup USART_Clock_Polarity - * @{ - */ - -#define USART_CPOL_Low ((uint16_t)0x0000) -#define USART_CPOL_High ((uint16_t)0x0400) -#define IS_USART_CPOL(CPOL) (((CPOL) == USART_CPOL_Low) || ((CPOL) == USART_CPOL_High)) - -/** - * @} - */ - -/** @defgroup USART_Clock_Phase - * @{ - */ - -#define USART_CPHA_1Edge ((uint16_t)0x0000) -#define USART_CPHA_2Edge ((uint16_t)0x0200) -#define IS_USART_CPHA(CPHA) (((CPHA) == USART_CPHA_1Edge) || ((CPHA) == USART_CPHA_2Edge)) - -/** - * @} - */ - -/** @defgroup USART_Last_Bit - * @{ - */ - -#define USART_LastBit_Disable ((uint16_t)0x0000) -#define USART_LastBit_Enable ((uint16_t)0x0100) -#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LastBit_Disable) || \ - ((LASTBIT) == USART_LastBit_Enable)) -/** - * @} - */ - -/** @defgroup USART_Interrupt_definition - * @{ - */ - -#define USART_IT_PE ((uint16_t)0x0028) -#define USART_IT_TXE ((uint16_t)0x0727) -#define USART_IT_TC ((uint16_t)0x0626) -#define USART_IT_RXNE ((uint16_t)0x0525) -#define USART_IT_IDLE ((uint16_t)0x0424) -#define USART_IT_LBD ((uint16_t)0x0846) -#define USART_IT_CTS ((uint16_t)0x096A) -#define USART_IT_ERR ((uint16_t)0x0060) -#define USART_IT_ORE ((uint16_t)0x0360) -#define USART_IT_NE ((uint16_t)0x0260) -#define USART_IT_FE ((uint16_t)0x0160) -#define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ - ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ - ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ - ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR)) -#define IS_USART_GET_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ - ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ - ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ - ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ORE) || \ - ((IT) == USART_IT_NE) || ((IT) == USART_IT_FE)) -#define IS_USART_CLEAR_IT(IT) (((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ - ((IT) == USART_IT_LBD) || ((IT) == USART_IT_CTS)) -/** - * @} - */ - -/** @defgroup USART_DMA_Requests - * @{ - */ - -#define USART_DMAReq_Tx ((uint16_t)0x0080) -#define USART_DMAReq_Rx ((uint16_t)0x0040) -#define IS_USART_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFF3F) == 0x00) && ((DMAREQ) != (uint16_t)0x00)) - -/** - * @} - */ - -/** @defgroup USART_WakeUp_methods - * @{ - */ - -#define USART_WakeUp_IdleLine ((uint16_t)0x0000) -#define USART_WakeUp_AddressMark ((uint16_t)0x0800) -#define IS_USART_WAKEUP(WAKEUP) (((WAKEUP) == USART_WakeUp_IdleLine) || \ - ((WAKEUP) == USART_WakeUp_AddressMark)) -/** - * @} - */ - -/** @defgroup USART_LIN_Break_Detection_Length - * @{ - */ - -#define USART_LINBreakDetectLength_10b ((uint16_t)0x0000) -#define USART_LINBreakDetectLength_11b ((uint16_t)0x0020) -#define IS_USART_LIN_BREAK_DETECT_LENGTH(LENGTH) \ - (((LENGTH) == USART_LINBreakDetectLength_10b) || \ - ((LENGTH) == USART_LINBreakDetectLength_11b)) -/** - * @} - */ - -/** @defgroup USART_IrDA_Low_Power - * @{ - */ - -#define USART_IrDAMode_LowPower ((uint16_t)0x0004) -#define USART_IrDAMode_Normal ((uint16_t)0x0000) -#define IS_USART_IRDA_MODE(MODE) (((MODE) == USART_IrDAMode_LowPower) || \ - ((MODE) == USART_IrDAMode_Normal)) -/** - * @} - */ - -/** @defgroup USART_Flags - * @{ - */ - -#define USART_FLAG_CTS ((uint16_t)0x0200) -#define USART_FLAG_LBD ((uint16_t)0x0100) -#define USART_FLAG_TXE ((uint16_t)0x0080) -#define USART_FLAG_TC ((uint16_t)0x0040) -#define USART_FLAG_RXNE ((uint16_t)0x0020) -#define USART_FLAG_IDLE ((uint16_t)0x0010) -#define USART_FLAG_ORE ((uint16_t)0x0008) -#define USART_FLAG_NE ((uint16_t)0x0004) -#define USART_FLAG_FE ((uint16_t)0x0002) -#define USART_FLAG_PE ((uint16_t)0x0001) -#define IS_USART_FLAG(FLAG) (((FLAG) == USART_FLAG_PE) || ((FLAG) == USART_FLAG_TXE) || \ - ((FLAG) == USART_FLAG_TC) || ((FLAG) == USART_FLAG_RXNE) || \ - ((FLAG) == USART_FLAG_IDLE) || ((FLAG) == USART_FLAG_LBD) || \ - ((FLAG) == USART_FLAG_CTS) || ((FLAG) == USART_FLAG_ORE) || \ - ((FLAG) == USART_FLAG_NE) || ((FLAG) == USART_FLAG_FE)) - -#define IS_USART_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFC9F) == 0x00) && ((FLAG) != (uint16_t)0x00)) - -#define IS_USART_BAUDRATE(BAUDRATE) (((BAUDRATE) > 0) && ((BAUDRATE) < 7500001)) -#define IS_USART_ADDRESS(ADDRESS) ((ADDRESS) <= 0xF) -#define IS_USART_DATA(DATA) ((DATA) <= 0x1FF) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the USART configuration to the default reset state ***/ -void USART_DeInit(USART_TypeDef* USARTx); - -/* Initialization and Configuration functions *********************************/ -void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct); -void USART_StructInit(USART_InitTypeDef* USART_InitStruct); -void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct); -void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct); -void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler); -void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState); - -/* Data transfers functions ***************************************************/ -void USART_SendData(USART_TypeDef* USARTx, uint16_t Data); -uint16_t USART_ReceiveData(USART_TypeDef* USARTx); - -/* Multi-Processor Communication functions ************************************/ -void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address); -void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp); -void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState); - -/* LIN mode functions *********************************************************/ -void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength); -void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_SendBreak(USART_TypeDef* USARTx); - -/* Half-duplex mode function **************************************************/ -void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState); - -/* Smartcard mode functions ***************************************************/ -void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState); -void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime); - -/* IrDA mode functions ********************************************************/ -void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode); -void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState); - -/* DMA transfers management functions *****************************************/ -void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState); - -/* Interrupts and flags management functions **********************************/ -void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState); -FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); -void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG); -ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT); -void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_USART_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_wwdg.h b/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_wwdg.h deleted file mode 100644 index 22b3e0de8..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_wwdg.h +++ /dev/null @@ -1,105 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_wwdg.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file contains all the functions prototypes for the WWDG firmware - * library. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_WWDG_H -#define __STM32F4xx_WWDG_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup WWDG - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup WWDG_Exported_Constants - * @{ - */ - -/** @defgroup WWDG_Prescaler - * @{ - */ - -#define WWDG_Prescaler_1 ((uint32_t)0x00000000) -#define WWDG_Prescaler_2 ((uint32_t)0x00000080) -#define WWDG_Prescaler_4 ((uint32_t)0x00000100) -#define WWDG_Prescaler_8 ((uint32_t)0x00000180) -#define IS_WWDG_PRESCALER(PRESCALER) (((PRESCALER) == WWDG_Prescaler_1) || \ - ((PRESCALER) == WWDG_Prescaler_2) || \ - ((PRESCALER) == WWDG_Prescaler_4) || \ - ((PRESCALER) == WWDG_Prescaler_8)) -#define IS_WWDG_WINDOW_VALUE(VALUE) ((VALUE) <= 0x7F) -#define IS_WWDG_COUNTER(COUNTER) (((COUNTER) >= 0x40) && ((COUNTER) <= 0x7F)) - -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/* Function used to set the WWDG configuration to the default reset state ****/ -void WWDG_DeInit(void); - -/* Prescaler, Refresh window and Counter configuration functions **************/ -void WWDG_SetPrescaler(uint32_t WWDG_Prescaler); -void WWDG_SetWindowValue(uint8_t WindowValue); -void WWDG_EnableIT(void); -void WWDG_SetCounter(uint8_t Counter); - -/* WWDG activation function ***************************************************/ -void WWDG_Enable(uint8_t Counter); - -/* Interrupts and flags management functions **********************************/ -FlagStatus WWDG_GetFlagStatus(void); -void WWDG_ClearFlag(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_WWDG_H */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/misc.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/misc.c deleted file mode 100644 index 4df41bfe8..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/misc.c +++ /dev/null @@ -1,243 +0,0 @@ -/** - ****************************************************************************** - * @file misc.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides all the miscellaneous firmware functions (add-on - * to CMSIS functions). - * - * @verbatim - * - * =================================================================== - * How to configure Interrupts using driver - * =================================================================== - * - * This section provide functions allowing to configure the NVIC interrupts (IRQ). - * The Cortex-M4 exceptions are managed by CMSIS functions. - * - * 1. Configure the NVIC Priority Grouping using NVIC_PriorityGroupConfig() - * function according to the following table. - - * The table below gives the allowed values of the pre-emption priority and subpriority according - * to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function - * ========================================================================================================================== - * NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description - * ========================================================================================================================== - * NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority - * | | | 4 bits for subpriority - * -------------------------------------------------------------------------------------------------------------------------- - * NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority - * | | | 3 bits for subpriority - * -------------------------------------------------------------------------------------------------------------------------- - * NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority - * | | | 2 bits for subpriority - * -------------------------------------------------------------------------------------------------------------------------- - * NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority - * | | | 1 bits for subpriority - * -------------------------------------------------------------------------------------------------------------------------- - * NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority - * | | | 0 bits for subpriority - * ========================================================================================================================== - * - * 2. Enable and Configure the priority of the selected IRQ Channels using NVIC_Init() - * - * @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. - * The pending IRQ priority will be managed only by the subpriority. - * - * @note IRQ priority order (sorted by highest to lowest priority): - * - Lowest pre-emption priority - * - Lowest subpriority - * - Lowest hardware priority (IRQ number) - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "misc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup MISC - * @brief MISC driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup MISC_Private_Functions - * @{ - */ - -/** - * @brief Configures the priority grouping: pre-emption priority and subpriority. - * @param NVIC_PriorityGroup: specifies the priority grouping bits length. - * This parameter can be one of the following values: - * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority - * 4 bits for subpriority - * @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority - * 3 bits for subpriority - * @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority - * 2 bits for subpriority - * @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority - * 1 bits for subpriority - * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority - * 0 bits for subpriority - * @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. - * The pending IRQ priority will be managed only by the subpriority. - * @retval None - */ -void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) -{ - /* Check the parameters */ - assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); - - /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */ - SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; -} - -/** - * @brief Initializes the NVIC peripheral according to the specified - * parameters in the NVIC_InitStruct. - * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() - * function should be called before. - * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains - * the configuration information for the specified NVIC peripheral. - * @retval None - */ -void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) -{ - uint8_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F; - - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd)); - assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority)); - assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority)); - - if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE) - { - /* Compute the Corresponding IRQ Priority --------------------------------*/ - tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08; - tmppre = (0x4 - tmppriority); - tmpsub = tmpsub >> tmppriority; - - tmppriority = NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; - tmppriority |= (uint8_t)(NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub); - - tmppriority = tmppriority << 0x04; - - NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority; - - /* Enable the Selected IRQ Channels --------------------------------------*/ - NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = - (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); - } - else - { - /* Disable the Selected IRQ Channels -------------------------------------*/ - NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = - (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); - } -} - -/** - * @brief Sets the vector table location and Offset. - * @param NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory. - * This parameter can be one of the following values: - * @arg NVIC_VectTab_RAM: Vector Table in internal SRAM. - * @arg NVIC_VectTab_FLASH: Vector Table in internal FLASH. - * @param Offset: Vector Table base offset field. This value must be a multiple of 0x200. - * @retval None - */ -void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) -{ - /* Check the parameters */ - assert_param(IS_NVIC_VECTTAB(NVIC_VectTab)); - assert_param(IS_NVIC_OFFSET(Offset)); - - SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80); -} - -/** - * @brief Selects the condition for the system to enter low power mode. - * @param LowPowerMode: Specifies the new mode for the system to enter low power mode. - * This parameter can be one of the following values: - * @arg NVIC_LP_SEVONPEND: Low Power SEV on Pend. - * @arg NVIC_LP_SLEEPDEEP: Low Power DEEPSLEEP request. - * @arg NVIC_LP_SLEEPONEXIT: Low Power Sleep on Exit. - * @param NewState: new state of LP condition. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_NVIC_LP(LowPowerMode)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - SCB->SCR |= LowPowerMode; - } - else - { - SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode); - } -} - -/** - * @brief Configures the SysTick clock source. - * @param SysTick_CLKSource: specifies the SysTick clock source. - * This parameter can be one of the following values: - * @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source. - * @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source. - * @retval None - */ -void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) -{ - /* Check the parameters */ - assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); - if (SysTick_CLKSource == SysTick_CLKSource_HCLK) - { - SysTick->CTRL |= SysTick_CLKSource_HCLK; - } - else - { - SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_adc.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_adc.c deleted file mode 100644 index 96e13d5d4..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_adc.c +++ /dev/null @@ -1,1742 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_adc.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the Analog to Digital Convertor (ADC) peripheral: - * - Initialization and Configuration (in addition to ADC multi mode - * selection) - * - Analog Watchdog configuration - * - Temperature Sensor & Vrefint (Voltage Reference internal) & VBAT - * management - * - Regular Channels Configuration - * - Regular Channels DMA Configuration - * - Injected channels Configuration - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - - * 1. Enable the ADC interface clock using - * RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADCx, ENABLE); - * - * 2. ADC pins configuration - * - Enable the clock for the ADC GPIOs using the following function: - * RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); - * - Configure these ADC pins in analog mode using GPIO_Init(); - * - * 3. Configure the ADC Prescaler, conversion resolution and data - * alignment using the ADC_Init() function. - * 4. Activate the ADC peripheral using ADC_Cmd() function. - * - * Regular channels group configuration - * ==================================== - * - To configure the ADC regular channels group features, use - * ADC_Init() and ADC_RegularChannelConfig() functions. - * - To activate the continuous mode, use the ADC_continuousModeCmd() - * function. - * - To configurate and activate the Discontinuous mode, use the - * ADC_DiscModeChannelCountConfig() and ADC_DiscModeCmd() functions. - * - To read the ADC converted values, use the ADC_GetConversionValue() - * function. - * - * Multi mode ADCs Regular channels configuration - * =============================================== - * - Refer to "Regular channels group configuration" description to - * configure the ADC1, ADC2 and ADC3 regular channels. - * - Select the Multi mode ADC regular channels features (dual or - * triple mode) using ADC_CommonInit() function and configure - * the DMA mode using ADC_MultiModeDMARequestAfterLastTransferCmd() - * functions. - * - Read the ADCs converted values using the - * ADC_GetMultiModeConversionValue() function. - * - * DMA for Regular channels group features configuration - * ====================================================== - * - To enable the DMA mode for regular channels group, use the - * ADC_DMACmd() function. - * - To enable the generation of DMA requests continuously at the end - * of the last DMA transfer, use the ADC_DMARequestAfterLastTransferCmd() - * function. - * - * Injected channels group configuration - * ===================================== - * - To configure the ADC Injected channels group features, use - * ADC_InjectedChannelConfig() and ADC_InjectedSequencerLengthConfig() - * functions. - * - To activate the continuous mode, use the ADC_continuousModeCmd() - * function. - * - To activate the Injected Discontinuous mode, use the - * ADC_InjectedDiscModeCmd() function. - * - To activate the AutoInjected mode, use the ADC_AutoInjectedConvCmd() - * function. - * - To read the ADC converted values, use the ADC_GetInjectedConversionValue() - * function. - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_adc.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup ADC - * @brief ADC driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* ADC DISCNUM mask */ -#define CR1_DISCNUM_RESET ((uint32_t)0xFFFF1FFF) - -/* ADC AWDCH mask */ -#define CR1_AWDCH_RESET ((uint32_t)0xFFFFFFE0) - -/* ADC Analog watchdog enable mode mask */ -#define CR1_AWDMode_RESET ((uint32_t)0xFF3FFDFF) - -/* CR1 register Mask */ -#define CR1_CLEAR_MASK ((uint32_t)0xFCFFFEFF) - -/* ADC EXTEN mask */ -#define CR2_EXTEN_RESET ((uint32_t)0xCFFFFFFF) - -/* ADC JEXTEN mask */ -#define CR2_JEXTEN_RESET ((uint32_t)0xFFCFFFFF) - -/* ADC JEXTSEL mask */ -#define CR2_JEXTSEL_RESET ((uint32_t)0xFFF0FFFF) - -/* CR2 register Mask */ -#define CR2_CLEAR_MASK ((uint32_t)0xC0FFF7FD) - -/* ADC SQx mask */ -#define SQR3_SQ_SET ((uint32_t)0x0000001F) -#define SQR2_SQ_SET ((uint32_t)0x0000001F) -#define SQR1_SQ_SET ((uint32_t)0x0000001F) - -/* ADC L Mask */ -#define SQR1_L_RESET ((uint32_t)0xFF0FFFFF) - -/* ADC JSQx mask */ -#define JSQR_JSQ_SET ((uint32_t)0x0000001F) - -/* ADC JL mask */ -#define JSQR_JL_SET ((uint32_t)0x00300000) -#define JSQR_JL_RESET ((uint32_t)0xFFCFFFFF) - -/* ADC SMPx mask */ -#define SMPR1_SMP_SET ((uint32_t)0x00000007) -#define SMPR2_SMP_SET ((uint32_t)0x00000007) - -/* ADC JDRx registers offset */ -#define JDR_OFFSET ((uint8_t)0x28) - -/* ADC CDR register base address */ -#define CDR_ADDRESS ((uint32_t)0x40012308) - -/* ADC CCR register Mask */ -#define CR_CLEAR_MASK ((uint32_t)0xFFFC30E0) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup ADC_Private_Functions - * @{ - */ - -/** @defgroup ADC_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - This section provides functions allowing to: - - Initialize and configure the ADC Prescaler - - ADC Conversion Resolution (12bit..6bit) - - Scan Conversion Mode (multichannels or one channel) for regular group - - ADC Continuous Conversion Mode (Continuous or Single conversion) for - regular group - - External trigger Edge and source of regular group, - - Converted data alignment (left or right) - - The number of ADC conversions that will be done using the sequencer for - regular channel group - - Multi ADC mode selection - - Direct memory access mode selection for multi ADC mode - - Delay between 2 sampling phases (used in dual or triple interleaved modes) - - Enable or disable the ADC peripheral - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes all ADCs peripherals registers to their default reset - * values. - * @param None - * @retval None - */ -void ADC_DeInit(void) -{ - /* Enable all ADCs reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC, ENABLE); - - /* Release all ADCs from reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC, DISABLE); -} - -/** - * @brief Initializes the ADCx peripheral according to the specified parameters - * in the ADC_InitStruct. - * @note This function is used to configure the global features of the ADC ( - * Resolution and Data Alignment), however, the rest of the configuration - * parameters are specific to the regular channels group (scan mode - * activation, continuous mode activation, External trigger source and - * edge, number of conversion in the regular channels group sequencer). - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains - * the configuration information for the specified ADC peripheral. - * @retval None - */ -void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) -{ - uint32_t tmpreg1 = 0; - uint8_t tmpreg2 = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_RESOLUTION(ADC_InitStruct->ADC_Resolution)); - assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ScanConvMode)); - assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ContinuousConvMode)); - assert_param(IS_ADC_EXT_TRIG_EDGE(ADC_InitStruct->ADC_ExternalTrigConvEdge)); - assert_param(IS_ADC_EXT_TRIG(ADC_InitStruct->ADC_ExternalTrigConv)); - assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign)); - assert_param(IS_ADC_REGULAR_LENGTH(ADC_InitStruct->ADC_NbrOfConversion)); - - /*---------------------------- ADCx CR1 Configuration -----------------*/ - /* Get the ADCx CR1 value */ - tmpreg1 = ADCx->CR1; - - /* Clear RES and SCAN bits */ - tmpreg1 &= CR1_CLEAR_MASK; - - /* Configure ADCx: scan conversion mode and resolution */ - /* Set SCAN bit according to ADC_ScanConvMode value */ - /* Set RES bit according to ADC_Resolution value */ - tmpreg1 |= (uint32_t)(((uint32_t)ADC_InitStruct->ADC_ScanConvMode << 8) | \ - ADC_InitStruct->ADC_Resolution); - /* Write to ADCx CR1 */ - ADCx->CR1 = tmpreg1; - /*---------------------------- ADCx CR2 Configuration -----------------*/ - /* Get the ADCx CR2 value */ - tmpreg1 = ADCx->CR2; - - /* Clear CONT, ALIGN, EXTEN and EXTSEL bits */ - tmpreg1 &= CR2_CLEAR_MASK; - - /* Configure ADCx: external trigger event and edge, data alignment and - continuous conversion mode */ - /* Set ALIGN bit according to ADC_DataAlign value */ - /* Set EXTEN bits according to ADC_ExternalTrigConvEdge value */ - /* Set EXTSEL bits according to ADC_ExternalTrigConv value */ - /* Set CONT bit according to ADC_ContinuousConvMode value */ - tmpreg1 |= (uint32_t)(ADC_InitStruct->ADC_DataAlign | \ - ADC_InitStruct->ADC_ExternalTrigConv | - ADC_InitStruct->ADC_ExternalTrigConvEdge | \ - ((uint32_t)ADC_InitStruct->ADC_ContinuousConvMode << 1)); - - /* Write to ADCx CR2 */ - ADCx->CR2 = tmpreg1; - /*---------------------------- ADCx SQR1 Configuration -----------------*/ - /* Get the ADCx SQR1 value */ - tmpreg1 = ADCx->SQR1; - - /* Clear L bits */ - tmpreg1 &= SQR1_L_RESET; - - /* Configure ADCx: regular channel sequence length */ - /* Set L bits according to ADC_NbrOfConversion value */ - tmpreg2 |= (uint8_t)(ADC_InitStruct->ADC_NbrOfConversion - (uint8_t)1); - tmpreg1 |= ((uint32_t)tmpreg2 << 20); - - /* Write to ADCx SQR1 */ - ADCx->SQR1 = tmpreg1; -} - -/** - * @brief Fills each ADC_InitStruct member with its default value. - * @note This function is used to initialize the global features of the ADC ( - * Resolution and Data Alignment), however, the rest of the configuration - * parameters are specific to the regular channels group (scan mode - * activation, continuous mode activation, External trigger source and - * edge, number of conversion in the regular channels group sequencer). - * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct) -{ - /* Initialize the ADC_Mode member */ - ADC_InitStruct->ADC_Resolution = ADC_Resolution_12b; - - /* initialize the ADC_ScanConvMode member */ - ADC_InitStruct->ADC_ScanConvMode = DISABLE; - - /* Initialize the ADC_ContinuousConvMode member */ - ADC_InitStruct->ADC_ContinuousConvMode = DISABLE; - - /* Initialize the ADC_ExternalTrigConvEdge member */ - ADC_InitStruct->ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; - - /* Initialize the ADC_ExternalTrigConv member */ - ADC_InitStruct->ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; - - /* Initialize the ADC_DataAlign member */ - ADC_InitStruct->ADC_DataAlign = ADC_DataAlign_Right; - - /* Initialize the ADC_NbrOfConversion member */ - ADC_InitStruct->ADC_NbrOfConversion = 1; -} - -/** - * @brief Initializes the ADCs peripherals according to the specified parameters - * in the ADC_CommonInitStruct. - * @param ADC_CommonInitStruct: pointer to an ADC_CommonInitTypeDef structure - * that contains the configuration information for All ADCs peripherals. - * @retval None - */ -void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct) -{ - uint32_t tmpreg1 = 0; - /* Check the parameters */ - assert_param(IS_ADC_MODE(ADC_CommonInitStruct->ADC_Mode)); - assert_param(IS_ADC_PRESCALER(ADC_CommonInitStruct->ADC_Prescaler)); - assert_param(IS_ADC_DMA_ACCESS_MODE(ADC_CommonInitStruct->ADC_DMAAccessMode)); - assert_param(IS_ADC_SAMPLING_DELAY(ADC_CommonInitStruct->ADC_TwoSamplingDelay)); - /*---------------------------- ADC CCR Configuration -----------------*/ - /* Get the ADC CCR value */ - tmpreg1 = ADC->CCR; - - /* Clear MULTI, DELAY, DMA and ADCPRE bits */ - tmpreg1 &= CR_CLEAR_MASK; - - /* Configure ADCx: Multi mode, Delay between two sampling time, ADC prescaler, - and DMA access mode for multimode */ - /* Set MULTI bits according to ADC_Mode value */ - /* Set ADCPRE bits according to ADC_Prescaler value */ - /* Set DMA bits according to ADC_DMAAccessMode value */ - /* Set DELAY bits according to ADC_TwoSamplingDelay value */ - tmpreg1 |= (uint32_t)(ADC_CommonInitStruct->ADC_Mode | - ADC_CommonInitStruct->ADC_Prescaler | - ADC_CommonInitStruct->ADC_DMAAccessMode | - ADC_CommonInitStruct->ADC_TwoSamplingDelay); - - /* Write to ADC CCR */ - ADC->CCR = tmpreg1; -} - -/** - * @brief Fills each ADC_CommonInitStruct member with its default value. - * @param ADC_CommonInitStruct: pointer to an ADC_CommonInitTypeDef structure - * which will be initialized. - * @retval None - */ -void ADC_CommonStructInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct) -{ - /* Initialize the ADC_Mode member */ - ADC_CommonInitStruct->ADC_Mode = ADC_Mode_Independent; - - /* initialize the ADC_Prescaler member */ - ADC_CommonInitStruct->ADC_Prescaler = ADC_Prescaler_Div2; - - /* Initialize the ADC_DMAAccessMode member */ - ADC_CommonInitStruct->ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; - - /* Initialize the ADC_TwoSamplingDelay member */ - ADC_CommonInitStruct->ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; -} - -/** - * @brief Enables or disables the specified ADC peripheral. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the ADCx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Set the ADON bit to wake up the ADC from power down mode */ - ADCx->CR2 |= (uint32_t)ADC_CR2_ADON; - } - else - { - /* Disable the selected ADC peripheral */ - ADCx->CR2 &= (uint32_t)(~ADC_CR2_ADON); - } -} -/** - * @} - */ - -/** @defgroup ADC_Group2 Analog Watchdog configuration functions - * @brief Analog Watchdog configuration functions - * -@verbatim - =============================================================================== - Analog Watchdog configuration functions - =============================================================================== - - This section provides functions allowing to configure the Analog Watchdog - (AWD) feature in the ADC. - - A typical configuration Analog Watchdog is done following these steps : - 1. the ADC guarded channel(s) is (are) selected using the - ADC_AnalogWatchdogSingleChannelConfig() function. - 2. The Analog watchdog lower and higher threshold are configured using the - ADC_AnalogWatchdogThresholdsConfig() function. - 3. The Analog watchdog is enabled and configured to enable the check, on one - or more channels, using the ADC_AnalogWatchdogCmd() function. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the analog watchdog on single/all regular or - * injected channels - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_AnalogWatchdog: the ADC analog watchdog configuration. - * This parameter can be one of the following values: - * @arg ADC_AnalogWatchdog_SingleRegEnable: Analog watchdog on a single regular channel - * @arg ADC_AnalogWatchdog_SingleInjecEnable: Analog watchdog on a single injected channel - * @arg ADC_AnalogWatchdog_SingleRegOrInjecEnable: Analog watchdog on a single regular or injected channel - * @arg ADC_AnalogWatchdog_AllRegEnable: Analog watchdog on all regular channel - * @arg ADC_AnalogWatchdog_AllInjecEnable: Analog watchdog on all injected channel - * @arg ADC_AnalogWatchdog_AllRegAllInjecEnable: Analog watchdog on all regular and injected channels - * @arg ADC_AnalogWatchdog_None: No channel guarded by the analog watchdog - * @retval None - */ -void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_ANALOG_WATCHDOG(ADC_AnalogWatchdog)); - - /* Get the old register value */ - tmpreg = ADCx->CR1; - - /* Clear AWDEN, JAWDEN and AWDSGL bits */ - tmpreg &= CR1_AWDMode_RESET; - - /* Set the analog watchdog enable mode */ - tmpreg |= ADC_AnalogWatchdog; - - /* Store the new register value */ - ADCx->CR1 = tmpreg; -} - -/** - * @brief Configures the high and low thresholds of the analog watchdog. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param HighThreshold: the ADC analog watchdog High threshold value. - * This parameter must be a 12-bit value. - * @param LowThreshold: the ADC analog watchdog Low threshold value. - * This parameter must be a 12-bit value. - * @retval None - */ -void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, - uint16_t LowThreshold) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_THRESHOLD(HighThreshold)); - assert_param(IS_ADC_THRESHOLD(LowThreshold)); - - /* Set the ADCx high threshold */ - ADCx->HTR = HighThreshold; - - /* Set the ADCx low threshold */ - ADCx->LTR = LowThreshold; -} - -/** - * @brief Configures the analog watchdog guarded single channel - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_Channel: the ADC channel to configure for the analog watchdog. - * This parameter can be one of the following values: - * @arg ADC_Channel_0: ADC Channel0 selected - * @arg ADC_Channel_1: ADC Channel1 selected - * @arg ADC_Channel_2: ADC Channel2 selected - * @arg ADC_Channel_3: ADC Channel3 selected - * @arg ADC_Channel_4: ADC Channel4 selected - * @arg ADC_Channel_5: ADC Channel5 selected - * @arg ADC_Channel_6: ADC Channel6 selected - * @arg ADC_Channel_7: ADC Channel7 selected - * @arg ADC_Channel_8: ADC Channel8 selected - * @arg ADC_Channel_9: ADC Channel9 selected - * @arg ADC_Channel_10: ADC Channel10 selected - * @arg ADC_Channel_11: ADC Channel11 selected - * @arg ADC_Channel_12: ADC Channel12 selected - * @arg ADC_Channel_13: ADC Channel13 selected - * @arg ADC_Channel_14: ADC Channel14 selected - * @arg ADC_Channel_15: ADC Channel15 selected - * @arg ADC_Channel_16: ADC Channel16 selected - * @arg ADC_Channel_17: ADC Channel17 selected - * @arg ADC_Channel_18: ADC Channel18 selected - * @retval None - */ -void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_CHANNEL(ADC_Channel)); - - /* Get the old register value */ - tmpreg = ADCx->CR1; - - /* Clear the Analog watchdog channel select bits */ - tmpreg &= CR1_AWDCH_RESET; - - /* Set the Analog watchdog channel */ - tmpreg |= ADC_Channel; - - /* Store the new register value */ - ADCx->CR1 = tmpreg; -} -/** - * @} - */ - -/** @defgroup ADC_Group3 Temperature Sensor, Vrefint (Voltage Reference internal) - * and VBAT (Voltage BATtery) management functions - * @brief Temperature Sensor, Vrefint and VBAT management functions - * -@verbatim - =============================================================================== - Temperature Sensor, Vrefint and VBAT management functions - =============================================================================== - - This section provides functions allowing to enable/ disable the internal - connections between the ADC and the Temperature Sensor, the Vrefint and the - Vbat sources. - - A typical configuration to get the Temperature sensor and Vrefint channels - voltages is done following these steps : - 1. Enable the internal connection of Temperature sensor and Vrefint sources - with the ADC channels using ADC_TempSensorVrefintCmd() function. - 2. Select the ADC_Channel_TempSensor and/or ADC_Channel_Vrefint using - ADC_RegularChannelConfig() or ADC_InjectedChannelConfig() functions - 3. Get the voltage values, using ADC_GetConversionValue() or - ADC_GetInjectedConversionValue(). - - A typical configuration to get the VBAT channel voltage is done following - these steps : - 1. Enable the internal connection of VBAT source with the ADC channel using - ADC_VBATCmd() function. - 2. Select the ADC_Channel_Vbat using ADC_RegularChannelConfig() or - ADC_InjectedChannelConfig() functions - 3. Get the voltage value, using ADC_GetConversionValue() or - ADC_GetInjectedConversionValue(). - -@endverbatim - * @{ - */ - - -/** - * @brief Enables or disables the temperature sensor and Vrefint channels. - * @param NewState: new state of the temperature sensor and Vrefint channels. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_TempSensorVrefintCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the temperature sensor and Vrefint channel*/ - ADC->CCR |= (uint32_t)ADC_CCR_TSVREFE; - } - else - { - /* Disable the temperature sensor and Vrefint channel*/ - ADC->CCR &= (uint32_t)(~ADC_CCR_TSVREFE); - } -} - -/** - * @brief Enables or disables the VBAT (Voltage Battery) channel. - * @param NewState: new state of the VBAT channel. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_VBATCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the VBAT channel*/ - ADC->CCR |= (uint32_t)ADC_CCR_VBATE; - } - else - { - /* Disable the VBAT channel*/ - ADC->CCR &= (uint32_t)(~ADC_CCR_VBATE); - } -} - -/** - * @} - */ - -/** @defgroup ADC_Group4 Regular Channels Configuration functions - * @brief Regular Channels Configuration functions - * -@verbatim - =============================================================================== - Regular Channels Configuration functions - =============================================================================== - - This section provides functions allowing to manage the ADC's regular channels, - it is composed of 2 sub sections : - - 1. Configuration and management functions for regular channels: This subsection - provides functions allowing to configure the ADC regular channels : - - Configure the rank in the regular group sequencer for each channel - - Configure the sampling time for each channel - - select the conversion Trigger for regular channels - - select the desired EOC event behavior configuration - - Activate the continuous Mode (*) - - Activate the Discontinuous Mode - Please Note that the following features for regular channels are configurated - using the ADC_Init() function : - - scan mode activation - - continuous mode activation (**) - - External trigger source - - External trigger edge - - number of conversion in the regular channels group sequencer. - - @note (*) and (**) are performing the same configuration - - 2. Get the conversion data: This subsection provides an important function in - the ADC peripheral since it returns the converted data of the current - regular channel. When the Conversion value is read, the EOC Flag is - automatically cleared. - - @note For multi ADC mode, the last ADC1, ADC2 and ADC3 regular conversions - results data (in the selected multi mode) can be returned in the same - time using ADC_GetMultiModeConversionValue() function. - - -@endverbatim - * @{ - */ -/** - * @brief Configures for the selected ADC regular channel its corresponding - * rank in the sequencer and its sample time. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_Channel: the ADC channel to configure. - * This parameter can be one of the following values: - * @arg ADC_Channel_0: ADC Channel0 selected - * @arg ADC_Channel_1: ADC Channel1 selected - * @arg ADC_Channel_2: ADC Channel2 selected - * @arg ADC_Channel_3: ADC Channel3 selected - * @arg ADC_Channel_4: ADC Channel4 selected - * @arg ADC_Channel_5: ADC Channel5 selected - * @arg ADC_Channel_6: ADC Channel6 selected - * @arg ADC_Channel_7: ADC Channel7 selected - * @arg ADC_Channel_8: ADC Channel8 selected - * @arg ADC_Channel_9: ADC Channel9 selected - * @arg ADC_Channel_10: ADC Channel10 selected - * @arg ADC_Channel_11: ADC Channel11 selected - * @arg ADC_Channel_12: ADC Channel12 selected - * @arg ADC_Channel_13: ADC Channel13 selected - * @arg ADC_Channel_14: ADC Channel14 selected - * @arg ADC_Channel_15: ADC Channel15 selected - * @arg ADC_Channel_16: ADC Channel16 selected - * @arg ADC_Channel_17: ADC Channel17 selected - * @arg ADC_Channel_18: ADC Channel18 selected - * @param Rank: The rank in the regular group sequencer. - * This parameter must be between 1 to 16. - * @param ADC_SampleTime: The sample time value to be set for the selected channel. - * This parameter can be one of the following values: - * @arg ADC_SampleTime_3Cycles: Sample time equal to 3 cycles - * @arg ADC_SampleTime_15Cycles: Sample time equal to 15 cycles - * @arg ADC_SampleTime_28Cycles: Sample time equal to 28 cycles - * @arg ADC_SampleTime_56Cycles: Sample time equal to 56 cycles - * @arg ADC_SampleTime_84Cycles: Sample time equal to 84 cycles - * @arg ADC_SampleTime_112Cycles: Sample time equal to 112 cycles - * @arg ADC_SampleTime_144Cycles: Sample time equal to 144 cycles - * @arg ADC_SampleTime_480Cycles: Sample time equal to 480 cycles - * @retval None - */ -void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) -{ - uint32_t tmpreg1 = 0, tmpreg2 = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_CHANNEL(ADC_Channel)); - assert_param(IS_ADC_REGULAR_RANK(Rank)); - assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); - - /* if ADC_Channel_10 ... ADC_Channel_18 is selected */ - if (ADC_Channel > ADC_Channel_9) - { - /* Get the old register value */ - tmpreg1 = ADCx->SMPR1; - - /* Calculate the mask to clear */ - tmpreg2 = SMPR1_SMP_SET << (3 * (ADC_Channel - 10)); - - /* Clear the old sample time */ - tmpreg1 &= ~tmpreg2; - - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 10)); - - /* Set the new sample time */ - tmpreg1 |= tmpreg2; - - /* Store the new register value */ - ADCx->SMPR1 = tmpreg1; - } - else /* ADC_Channel include in ADC_Channel_[0..9] */ - { - /* Get the old register value */ - tmpreg1 = ADCx->SMPR2; - - /* Calculate the mask to clear */ - tmpreg2 = SMPR2_SMP_SET << (3 * ADC_Channel); - - /* Clear the old sample time */ - tmpreg1 &= ~tmpreg2; - - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); - - /* Set the new sample time */ - tmpreg1 |= tmpreg2; - - /* Store the new register value */ - ADCx->SMPR2 = tmpreg1; - } - /* For Rank 1 to 6 */ - if (Rank < 7) - { - /* Get the old register value */ - tmpreg1 = ADCx->SQR3; - - /* Calculate the mask to clear */ - tmpreg2 = SQR3_SQ_SET << (5 * (Rank - 1)); - - /* Clear the old SQx bits for the selected rank */ - tmpreg1 &= ~tmpreg2; - - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 1)); - - /* Set the SQx bits for the selected rank */ - tmpreg1 |= tmpreg2; - - /* Store the new register value */ - ADCx->SQR3 = tmpreg1; - } - /* For Rank 7 to 12 */ - else if (Rank < 13) - { - /* Get the old register value */ - tmpreg1 = ADCx->SQR2; - - /* Calculate the mask to clear */ - tmpreg2 = SQR2_SQ_SET << (5 * (Rank - 7)); - - /* Clear the old SQx bits for the selected rank */ - tmpreg1 &= ~tmpreg2; - - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 7)); - - /* Set the SQx bits for the selected rank */ - tmpreg1 |= tmpreg2; - - /* Store the new register value */ - ADCx->SQR2 = tmpreg1; - } - /* For Rank 13 to 16 */ - else - { - /* Get the old register value */ - tmpreg1 = ADCx->SQR1; - - /* Calculate the mask to clear */ - tmpreg2 = SQR1_SQ_SET << (5 * (Rank - 13)); - - /* Clear the old SQx bits for the selected rank */ - tmpreg1 &= ~tmpreg2; - - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 13)); - - /* Set the SQx bits for the selected rank */ - tmpreg1 |= tmpreg2; - - /* Store the new register value */ - ADCx->SQR1 = tmpreg1; - } -} - -/** - * @brief Enables the selected ADC software start conversion of the regular channels. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @retval None - */ -void ADC_SoftwareStartConv(ADC_TypeDef* ADCx) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - - /* Enable the selected ADC conversion for regular group */ - ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART; -} - -/** - * @brief Gets the selected ADC Software start regular conversion Status. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @retval The new state of ADC software start conversion (SET or RESET). - */ -FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - - /* Check the status of SWSTART bit */ - if ((ADCx->CR2 & ADC_CR2_JSWSTART) != (uint32_t)RESET) - { - /* SWSTART bit is set */ - bitstatus = SET; - } - else - { - /* SWSTART bit is reset */ - bitstatus = RESET; - } - - /* Return the SWSTART bit status */ - return bitstatus; -} - - -/** - * @brief Enables or disables the EOC on each regular channel conversion - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the selected ADC EOC flag rising - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected ADC EOC rising on each regular channel conversion */ - ADCx->CR2 |= (uint32_t)ADC_CR2_EOCS; - } - else - { - /* Disable the selected ADC EOC rising on each regular channel conversion */ - ADCx->CR2 &= (uint32_t)(~ADC_CR2_EOCS); - } -} - -/** - * @brief Enables or disables the ADC continuous conversion mode - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the selected ADC continuous conversion mode - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected ADC continuous conversion mode */ - ADCx->CR2 |= (uint32_t)ADC_CR2_CONT; - } - else - { - /* Disable the selected ADC continuous conversion mode */ - ADCx->CR2 &= (uint32_t)(~ADC_CR2_CONT); - } -} - -/** - * @brief Configures the discontinuous mode for the selected ADC regular group - * channel. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param Number: specifies the discontinuous mode regular channel count value. - * This number must be between 1 and 8. - * @retval None - */ -void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number) -{ - uint32_t tmpreg1 = 0; - uint32_t tmpreg2 = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_REGULAR_DISC_NUMBER(Number)); - - /* Get the old register value */ - tmpreg1 = ADCx->CR1; - - /* Clear the old discontinuous mode channel count */ - tmpreg1 &= CR1_DISCNUM_RESET; - - /* Set the discontinuous mode channel count */ - tmpreg2 = Number - 1; - tmpreg1 |= tmpreg2 << 13; - - /* Store the new register value */ - ADCx->CR1 = tmpreg1; -} - -/** - * @brief Enables or disables the discontinuous mode on regular group channel - * for the specified ADC - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the selected ADC discontinuous mode on - * regular group channel. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected ADC regular discontinuous mode */ - ADCx->CR1 |= (uint32_t)ADC_CR1_DISCEN; - } - else - { - /* Disable the selected ADC regular discontinuous mode */ - ADCx->CR1 &= (uint32_t)(~ADC_CR1_DISCEN); - } -} - -/** - * @brief Returns the last ADCx conversion result data for regular channel. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @retval The Data conversion value. - */ -uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - - /* Return the selected ADC conversion value */ - return (uint16_t) ADCx->DR; -} - -/** - * @brief Returns the last ADC1, ADC2 and ADC3 regular conversions results - * data in the selected multi mode. - * @param None - * @retval The Data conversion value. - * @note In dual mode, the value returned by this function is as following - * Data[15:0] : these bits contain the regular data of ADC1. - * Data[31:16]: these bits contain the regular data of ADC2. - * @note In triple mode, the value returned by this function is as following - * Data[15:0] : these bits contain alternatively the regular data of ADC1, ADC3 and ADC2. - * Data[31:16]: these bits contain alternatively the regular data of ADC2, ADC1 and ADC3. - */ -uint32_t ADC_GetMultiModeConversionValue(void) -{ - /* Return the multi mode conversion value */ - return (*(__IO uint32_t *) CDR_ADDRESS); -} -/** - * @} - */ - -/** @defgroup ADC_Group5 Regular Channels DMA Configuration functions - * @brief Regular Channels DMA Configuration functions - * -@verbatim - =============================================================================== - Regular Channels DMA Configuration functions - =============================================================================== - - This section provides functions allowing to configure the DMA for ADC regular - channels. - Since converted regular channel values are stored into a unique data register, - it is useful to use DMA for conversion of more than one regular channel. This - avoids the loss of the data already stored in the ADC Data register. - - When the DMA mode is enabled (using the ADC_DMACmd() function), after each - conversion of a regular channel, a DMA request is generated. - - Depending on the "DMA disable selection for Independent ADC mode" - configuration (using the ADC_DMARequestAfterLastTransferCmd() function), - at the end of the last DMA transfer, two possibilities are allowed: - - No new DMA request is issued to the DMA controller (feature DISABLED) - - Requests can continue to be generated (feature ENABLED). - - Depending on the "DMA disable selection for multi ADC mode" configuration - (using the void ADC_MultiModeDMARequestAfterLastTransferCmd() function), - at the end of the last DMA transfer, two possibilities are allowed: - - No new DMA request is issued to the DMA controller (feature DISABLED) - - Requests can continue to be generated (feature ENABLED). - -@endverbatim - * @{ - */ - - /** - * @brief Enables or disables the specified ADC DMA request. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the selected ADC DMA transfer. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected ADC DMA request */ - ADCx->CR2 |= (uint32_t)ADC_CR2_DMA; - } - else - { - /* Disable the selected ADC DMA request */ - ADCx->CR2 &= (uint32_t)(~ADC_CR2_DMA); - } -} - -/** - * @brief Enables or disables the ADC DMA request after last transfer (Single-ADC mode) - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the selected ADC DMA request after last transfer. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected ADC DMA request after last transfer */ - ADCx->CR2 |= (uint32_t)ADC_CR2_DDS; - } - else - { - /* Disable the selected ADC DMA request after last transfer */ - ADCx->CR2 &= (uint32_t)(~ADC_CR2_DDS); - } -} - -/** - * @brief Enables or disables the ADC DMA request after last transfer in multi ADC mode - * @param NewState: new state of the selected ADC DMA request after last transfer. - * This parameter can be: ENABLE or DISABLE. - * @note if Enabled, DMA requests are issued as long as data are converted and - * DMA mode for multi ADC mode (selected using ADC_CommonInit() function - * by ADC_CommonInitStruct.ADC_DMAAccessMode structure member) is - * ADC_DMAAccessMode_1, ADC_DMAAccessMode_2 or ADC_DMAAccessMode_3. - * @retval None - */ -void ADC_MultiModeDMARequestAfterLastTransferCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected ADC DMA request after last transfer */ - ADC->CCR |= (uint32_t)ADC_CCR_DDS; - } - else - { - /* Disable the selected ADC DMA request after last transfer */ - ADC->CCR &= (uint32_t)(~ADC_CCR_DDS); - } -} -/** - * @} - */ - -/** @defgroup ADC_Group6 Injected channels Configuration functions - * @brief Injected channels Configuration functions - * -@verbatim - =============================================================================== - Injected channels Configuration functions - =============================================================================== - - This section provide functions allowing to configure the ADC Injected channels, - it is composed of 2 sub sections : - - 1. Configuration functions for Injected channels: This subsection provides - functions allowing to configure the ADC injected channels : - - Configure the rank in the injected group sequencer for each channel - - Configure the sampling time for each channel - - Activate the Auto injected Mode - - Activate the Discontinuous Mode - - scan mode activation - - External/software trigger source - - External trigger edge - - injected channels sequencer. - - 2. Get the Specified Injected channel conversion data: This subsection - provides an important function in the ADC peripheral since it returns the - converted data of the specific injected channel. - -@endverbatim - * @{ - */ -/** - * @brief Configures for the selected ADC injected channel its corresponding - * rank in the sequencer and its sample time. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_Channel: the ADC channel to configure. - * This parameter can be one of the following values: - * @arg ADC_Channel_0: ADC Channel0 selected - * @arg ADC_Channel_1: ADC Channel1 selected - * @arg ADC_Channel_2: ADC Channel2 selected - * @arg ADC_Channel_3: ADC Channel3 selected - * @arg ADC_Channel_4: ADC Channel4 selected - * @arg ADC_Channel_5: ADC Channel5 selected - * @arg ADC_Channel_6: ADC Channel6 selected - * @arg ADC_Channel_7: ADC Channel7 selected - * @arg ADC_Channel_8: ADC Channel8 selected - * @arg ADC_Channel_9: ADC Channel9 selected - * @arg ADC_Channel_10: ADC Channel10 selected - * @arg ADC_Channel_11: ADC Channel11 selected - * @arg ADC_Channel_12: ADC Channel12 selected - * @arg ADC_Channel_13: ADC Channel13 selected - * @arg ADC_Channel_14: ADC Channel14 selected - * @arg ADC_Channel_15: ADC Channel15 selected - * @arg ADC_Channel_16: ADC Channel16 selected - * @arg ADC_Channel_17: ADC Channel17 selected - * @arg ADC_Channel_18: ADC Channel18 selected - * @param Rank: The rank in the injected group sequencer. - * This parameter must be between 1 to 4. - * @param ADC_SampleTime: The sample time value to be set for the selected channel. - * This parameter can be one of the following values: - * @arg ADC_SampleTime_3Cycles: Sample time equal to 3 cycles - * @arg ADC_SampleTime_15Cycles: Sample time equal to 15 cycles - * @arg ADC_SampleTime_28Cycles: Sample time equal to 28 cycles - * @arg ADC_SampleTime_56Cycles: Sample time equal to 56 cycles - * @arg ADC_SampleTime_84Cycles: Sample time equal to 84 cycles - * @arg ADC_SampleTime_112Cycles: Sample time equal to 112 cycles - * @arg ADC_SampleTime_144Cycles: Sample time equal to 144 cycles - * @arg ADC_SampleTime_480Cycles: Sample time equal to 480 cycles - * @retval None - */ -void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) -{ - uint32_t tmpreg1 = 0, tmpreg2 = 0, tmpreg3 = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_CHANNEL(ADC_Channel)); - assert_param(IS_ADC_INJECTED_RANK(Rank)); - assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); - /* if ADC_Channel_10 ... ADC_Channel_18 is selected */ - if (ADC_Channel > ADC_Channel_9) - { - /* Get the old register value */ - tmpreg1 = ADCx->SMPR1; - /* Calculate the mask to clear */ - tmpreg2 = SMPR1_SMP_SET << (3*(ADC_Channel - 10)); - /* Clear the old sample time */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_SampleTime << (3*(ADC_Channel - 10)); - /* Set the new sample time */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SMPR1 = tmpreg1; - } - else /* ADC_Channel include in ADC_Channel_[0..9] */ - { - /* Get the old register value */ - tmpreg1 = ADCx->SMPR2; - /* Calculate the mask to clear */ - tmpreg2 = SMPR2_SMP_SET << (3 * ADC_Channel); - /* Clear the old sample time */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set */ - tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); - /* Set the new sample time */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->SMPR2 = tmpreg1; - } - /* Rank configuration */ - /* Get the old register value */ - tmpreg1 = ADCx->JSQR; - /* Get JL value: Number = JL+1 */ - tmpreg3 = (tmpreg1 & JSQR_JL_SET)>> 20; - /* Calculate the mask to clear: ((Rank-1)+(4-JL-1)) */ - tmpreg2 = JSQR_JSQ_SET << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1))); - /* Clear the old JSQx bits for the selected rank */ - tmpreg1 &= ~tmpreg2; - /* Calculate the mask to set: ((Rank-1)+(4-JL-1)) */ - tmpreg2 = (uint32_t)ADC_Channel << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1))); - /* Set the JSQx bits for the selected rank */ - tmpreg1 |= tmpreg2; - /* Store the new register value */ - ADCx->JSQR = tmpreg1; -} - -/** - * @brief Configures the sequencer length for injected channels - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param Length: The sequencer length. - * This parameter must be a number between 1 to 4. - * @retval None - */ -void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length) -{ - uint32_t tmpreg1 = 0; - uint32_t tmpreg2 = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_INJECTED_LENGTH(Length)); - - /* Get the old register value */ - tmpreg1 = ADCx->JSQR; - - /* Clear the old injected sequence length JL bits */ - tmpreg1 &= JSQR_JL_RESET; - - /* Set the injected sequence length JL bits */ - tmpreg2 = Length - 1; - tmpreg1 |= tmpreg2 << 20; - - /* Store the new register value */ - ADCx->JSQR = tmpreg1; -} - -/** - * @brief Set the injected channels conversion value offset - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_InjectedChannel: the ADC injected channel to set its offset. - * This parameter can be one of the following values: - * @arg ADC_InjectedChannel_1: Injected Channel1 selected - * @arg ADC_InjectedChannel_2: Injected Channel2 selected - * @arg ADC_InjectedChannel_3: Injected Channel3 selected - * @arg ADC_InjectedChannel_4: Injected Channel4 selected - * @param Offset: the offset value for the selected ADC injected channel - * This parameter must be a 12bit value. - * @retval None - */ -void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset) -{ - __IO uint32_t tmp = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel)); - assert_param(IS_ADC_OFFSET(Offset)); - - tmp = (uint32_t)ADCx; - tmp += ADC_InjectedChannel; - - /* Set the selected injected channel data offset */ - *(__IO uint32_t *) tmp = (uint32_t)Offset; -} - - /** - * @brief Configures the ADCx external trigger for injected channels conversion. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_ExternalTrigInjecConv: specifies the ADC trigger to start injected conversion. - * This parameter can be one of the following values: - * @arg ADC_ExternalTrigInjecConv_T1_CC4: Timer1 capture compare4 selected - * @arg ADC_ExternalTrigInjecConv_T1_TRGO: Timer1 TRGO event selected - * @arg ADC_ExternalTrigInjecConv_T2_CC1: Timer2 capture compare1 selected - * @arg ADC_ExternalTrigInjecConv_T2_TRGO: Timer2 TRGO event selected - * @arg ADC_ExternalTrigInjecConv_T3_CC2: Timer3 capture compare2 selected - * @arg ADC_ExternalTrigInjecConv_T3_CC4: Timer3 capture compare4 selected - * @arg ADC_ExternalTrigInjecConv_T4_CC1: Timer4 capture compare1 selected - * @arg ADC_ExternalTrigInjecConv_T4_CC2: Timer4 capture compare2 selected - * @arg ADC_ExternalTrigInjecConv_T4_CC3: Timer4 capture compare3 selected - * @arg ADC_ExternalTrigInjecConv_T4_TRGO: Timer4 TRGO event selected - * @arg ADC_ExternalTrigInjecConv_T5_CC4: Timer5 capture compare4 selected - * @arg ADC_ExternalTrigInjecConv_T5_TRGO: Timer5 TRGO event selected - * @arg ADC_ExternalTrigInjecConv_T8_CC2: Timer8 capture compare2 selected - * @arg ADC_ExternalTrigInjecConv_T8_CC3: Timer8 capture compare3 selected - * @arg ADC_ExternalTrigInjecConv_T8_CC4: Timer8 capture compare4 selected - * @arg ADC_ExternalTrigInjecConv_Ext_IT15: External interrupt line 15 event selected - * @retval None - */ -void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_EXT_INJEC_TRIG(ADC_ExternalTrigInjecConv)); - - /* Get the old register value */ - tmpreg = ADCx->CR2; - - /* Clear the old external event selection for injected group */ - tmpreg &= CR2_JEXTSEL_RESET; - - /* Set the external event selection for injected group */ - tmpreg |= ADC_ExternalTrigInjecConv; - - /* Store the new register value */ - ADCx->CR2 = tmpreg; -} - -/** - * @brief Configures the ADCx external trigger edge for injected channels conversion. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_ExternalTrigInjecConvEdge: specifies the ADC external trigger edge - * to start injected conversion. - * This parameter can be one of the following values: - * @arg ADC_ExternalTrigInjecConvEdge_None: external trigger disabled for - * injected conversion - * @arg ADC_ExternalTrigInjecConvEdge_Rising: detection on rising edge - * @arg ADC_ExternalTrigInjecConvEdge_Falling: detection on falling edge - * @arg ADC_ExternalTrigInjecConvEdge_RisingFalling: detection on both rising - * and falling edge - * @retval None - */ -void ADC_ExternalTrigInjectedConvEdgeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConvEdge) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(ADC_ExternalTrigInjecConvEdge)); - /* Get the old register value */ - tmpreg = ADCx->CR2; - /* Clear the old external trigger edge for injected group */ - tmpreg &= CR2_JEXTEN_RESET; - /* Set the new external trigger edge for injected group */ - tmpreg |= ADC_ExternalTrigInjecConvEdge; - /* Store the new register value */ - ADCx->CR2 = tmpreg; -} - -/** - * @brief Enables the selected ADC software start conversion of the injected channels. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @retval None - */ -void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - /* Enable the selected ADC conversion for injected group */ - ADCx->CR2 |= (uint32_t)ADC_CR2_JSWSTART; -} - -/** - * @brief Gets the selected ADC Software start injected conversion Status. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @retval The new state of ADC software start injected conversion (SET or RESET). - */ -FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - - /* Check the status of JSWSTART bit */ - if ((ADCx->CR2 & ADC_CR2_JSWSTART) != (uint32_t)RESET) - { - /* JSWSTART bit is set */ - bitstatus = SET; - } - else - { - /* JSWSTART bit is reset */ - bitstatus = RESET; - } - /* Return the JSWSTART bit status */ - return bitstatus; -} - -/** - * @brief Enables or disables the selected ADC automatic injected group - * conversion after regular one. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the selected ADC auto injected conversion - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected ADC automatic injected group conversion */ - ADCx->CR1 |= (uint32_t)ADC_CR1_JAUTO; - } - else - { - /* Disable the selected ADC automatic injected group conversion */ - ADCx->CR1 &= (uint32_t)(~ADC_CR1_JAUTO); - } -} - -/** - * @brief Enables or disables the discontinuous mode for injected group - * channel for the specified ADC - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param NewState: new state of the selected ADC discontinuous mode on injected - * group channel. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected ADC injected discontinuous mode */ - ADCx->CR1 |= (uint32_t)ADC_CR1_JDISCEN; - } - else - { - /* Disable the selected ADC injected discontinuous mode */ - ADCx->CR1 &= (uint32_t)(~ADC_CR1_JDISCEN); - } -} - -/** - * @brief Returns the ADC injected channel conversion result - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_InjectedChannel: the converted ADC injected channel. - * This parameter can be one of the following values: - * @arg ADC_InjectedChannel_1: Injected Channel1 selected - * @arg ADC_InjectedChannel_2: Injected Channel2 selected - * @arg ADC_InjectedChannel_3: Injected Channel3 selected - * @arg ADC_InjectedChannel_4: Injected Channel4 selected - * @retval The Data conversion value. - */ -uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel)); - - tmp = (uint32_t)ADCx; - tmp += ADC_InjectedChannel + JDR_OFFSET; - - /* Returns the selected injected channel conversion data value */ - return (uint16_t) (*(__IO uint32_t*) tmp); -} -/** - * @} - */ - -/** @defgroup ADC_Group7 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - - This section provides functions allowing to configure the ADC Interrupts and - to get the status and clear flags and Interrupts pending bits. - - Each ADC provides 4 Interrupts sources and 6 Flags which can be divided into - 3 groups: - - I. Flags and Interrupts for ADC regular channels - ================================================= - Flags : - ---------- - 1. ADC_FLAG_OVR : Overrun detection when regular converted data are lost - - 2. ADC_FLAG_EOC : Regular channel end of conversion ==> to indicate (depending - on EOCS bit, managed by ADC_EOCOnEachRegularChannelCmd() ) the end of: - ==> a regular CHANNEL conversion - ==> sequence of regular GROUP conversions . - - 3. ADC_FLAG_STRT: Regular channel start ==> to indicate when regular CHANNEL - conversion starts. - - Interrupts : - ------------ - 1. ADC_IT_OVR : specifies the interrupt source for Overrun detection event. - 2. ADC_IT_EOC : specifies the interrupt source for Regular channel end of - conversion event. - - - II. Flags and Interrupts for ADC Injected channels - ================================================= - Flags : - ---------- - 1. ADC_FLAG_JEOC : Injected channel end of conversion ==> to indicate at - the end of injected GROUP conversion - - 2. ADC_FLAG_JSTRT: Injected channel start ==> to indicate hardware when - injected GROUP conversion starts. - - Interrupts : - ------------ - 1. ADC_IT_JEOC : specifies the interrupt source for Injected channel end of - conversion event. - - III. General Flags and Interrupts for the ADC - ================================================= - Flags : - ---------- - 1. ADC_FLAG_AWD: Analog watchdog ==> to indicate if the converted voltage - crosses the programmed thresholds values. - - Interrupts : - ------------ - 1. ADC_IT_AWD : specifies the interrupt source for Analog watchdog event. - - - The user should identify which mode will be used in his application to manage - the ADC controller events: Polling mode or Interrupt mode. - - In the Polling Mode it is advised to use the following functions: - - ADC_GetFlagStatus() : to check if flags events occur. - - ADC_ClearFlag() : to clear the flags events. - - In the Interrupt Mode it is advised to use the following functions: - - ADC_ITConfig() : to enable or disable the interrupt source. - - ADC_GetITStatus() : to check if Interrupt occurs. - - ADC_ClearITPendingBit() : to clear the Interrupt pending Bit - (corresponding Flag). -@endverbatim - * @{ - */ -/** - * @brief Enables or disables the specified ADC interrupts. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_IT: specifies the ADC interrupt sources to be enabled or disabled. - * This parameter can be one of the following values: - * @arg ADC_IT_EOC: End of conversion interrupt mask - * @arg ADC_IT_AWD: Analog watchdog interrupt mask - * @arg ADC_IT_JEOC: End of injected conversion interrupt mask - * @arg ADC_IT_OVR: Overrun interrupt enable - * @param NewState: new state of the specified ADC interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState) -{ - uint32_t itmask = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_ADC_IT(ADC_IT)); - - /* Get the ADC IT index */ - itmask = (uint8_t)ADC_IT; - itmask = (uint32_t)0x01 << itmask; - - if (NewState != DISABLE) - { - /* Enable the selected ADC interrupts */ - ADCx->CR1 |= itmask; - } - else - { - /* Disable the selected ADC interrupts */ - ADCx->CR1 &= (~(uint32_t)itmask); - } -} - -/** - * @brief Checks whether the specified ADC flag is set or not. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg ADC_FLAG_AWD: Analog watchdog flag - * @arg ADC_FLAG_EOC: End of conversion flag - * @arg ADC_FLAG_JEOC: End of injected group conversion flag - * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag - * @arg ADC_FLAG_STRT: Start of regular group conversion flag - * @arg ADC_FLAG_OVR: Overrun flag - * @retval The new state of ADC_FLAG (SET or RESET). - */ -FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_GET_FLAG(ADC_FLAG)); - - /* Check the status of the specified ADC flag */ - if ((ADCx->SR & ADC_FLAG) != (uint8_t)RESET) - { - /* ADC_FLAG is set */ - bitstatus = SET; - } - else - { - /* ADC_FLAG is reset */ - bitstatus = RESET; - } - /* Return the ADC_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the ADCx's pending flags. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg ADC_FLAG_AWD: Analog watchdog flag - * @arg ADC_FLAG_EOC: End of conversion flag - * @arg ADC_FLAG_JEOC: End of injected group conversion flag - * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag - * @arg ADC_FLAG_STRT: Start of regular group conversion flag - * @arg ADC_FLAG_OVR: Overrun flag - * @retval None - */ -void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) -{ - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_CLEAR_FLAG(ADC_FLAG)); - - /* Clear the selected ADC flags */ - ADCx->SR = ~(uint32_t)ADC_FLAG; -} - -/** - * @brief Checks whether the specified ADC interrupt has occurred or not. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_IT: specifies the ADC interrupt source to check. - * This parameter can be one of the following values: - * @arg ADC_IT_EOC: End of conversion interrupt mask - * @arg ADC_IT_AWD: Analog watchdog interrupt mask - * @arg ADC_IT_JEOC: End of injected conversion interrupt mask - * @arg ADC_IT_OVR: Overrun interrupt mask - * @retval The new state of ADC_IT (SET or RESET). - */ -ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT) -{ - ITStatus bitstatus = RESET; - uint32_t itmask = 0, enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_IT(ADC_IT)); - - /* Get the ADC IT index */ - itmask = ADC_IT >> 8; - - /* Get the ADC_IT enable bit status */ - enablestatus = (ADCx->CR1 & ((uint32_t)0x01 << (uint8_t)ADC_IT)) ; - - /* Check the status of the specified ADC interrupt */ - if (((ADCx->SR & itmask) != (uint32_t)RESET) && enablestatus) - { - /* ADC_IT is set */ - bitstatus = SET; - } - else - { - /* ADC_IT is reset */ - bitstatus = RESET; - } - /* Return the ADC_IT status */ - return bitstatus; -} - -/** - * @brief Clears the ADCx's interrupt pending bits. - * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. - * @param ADC_IT: specifies the ADC interrupt pending bit to clear. - * This parameter can be one of the following values: - * @arg ADC_IT_EOC: End of conversion interrupt mask - * @arg ADC_IT_AWD: Analog watchdog interrupt mask - * @arg ADC_IT_JEOC: End of injected conversion interrupt mask - * @arg ADC_IT_OVR: Overrun interrupt mask - * @retval None - */ -void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT) -{ - uint8_t itmask = 0; - /* Check the parameters */ - assert_param(IS_ADC_ALL_PERIPH(ADCx)); - assert_param(IS_ADC_IT(ADC_IT)); - /* Get the ADC IT index */ - itmask = (uint8_t)(ADC_IT >> 8); - /* Clear the selected ADC interrupt pending bits */ - ADCx->SR = ~(uint32_t)itmask; -} -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_can.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_can.c deleted file mode 100644 index 4fdfe1236..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_can.c +++ /dev/null @@ -1,1698 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_can.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the Controller area network (CAN) peripheral: - * - Initialization and Configuration - * - CAN Frames Transmission - * - CAN Frames Reception - * - Operation modes switch - * - Error management - * - Interrupts and flags - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - - * 1. Enable the CAN controller interface clock using - * RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); for CAN1 - * and RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE); for CAN2 - * @note In case you are using CAN2 only, you have to enable the CAN1 clock. - * - * 2. CAN pins configuration - * - Enable the clock for the CAN GPIOs using the following function: - * RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); - * - Connect the involved CAN pins to AF9 using the following function - * GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_CANx); - * - Configure these CAN pins in alternate function mode by calling - * the function GPIO_Init(); - * - * 3. Initialise and configure the CAN using CAN_Init() and - * CAN_FilterInit() functions. - * - * 4. Transmit the desired CAN frame using CAN_Transmit() function. - * - * 5. Check the transmission of a CAN frame using CAN_TransmitStatus() - * function. - * - * 6. Cancel the transmission of a CAN frame using CAN_CancelTransmit() - * function. - * - * 7. Receive a CAN frame using CAN_Recieve() function. - * - * 8. Release the receive FIFOs using CAN_FIFORelease() function. - * - * 9. Return the number of pending received frames using - * CAN_MessagePending() function. - * - * 10. To control CAN events you can use one of the following two methods: - * - Check on CAN flags using the CAN_GetFlagStatus() function. - * - Use CAN interrupts through the function CAN_ITConfig() at - * initialization phase and CAN_GetITStatus() function into - * interrupt routines to check if the event has occurred or not. - * After checking on a flag you should clear it using CAN_ClearFlag() - * function. And after checking on an interrupt event you should - * clear it using CAN_ClearITPendingBit() function. - * - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_can.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup CAN - * @brief CAN driver modules - * @{ - */ -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* CAN Master Control Register bits */ -#define MCR_DBF ((uint32_t)0x00010000) /* software master reset */ - -/* CAN Mailbox Transmit Request */ -#define TMIDxR_TXRQ ((uint32_t)0x00000001) /* Transmit mailbox request */ - -/* CAN Filter Master Register bits */ -#define FMR_FINIT ((uint32_t)0x00000001) /* Filter init mode */ - -/* Time out for INAK bit */ -#define INAK_TIMEOUT ((uint32_t)0x0000FFFF) -/* Time out for SLAK bit */ -#define SLAK_TIMEOUT ((uint32_t)0x0000FFFF) - -/* Flags in TSR register */ -#define CAN_FLAGS_TSR ((uint32_t)0x08000000) -/* Flags in RF1R register */ -#define CAN_FLAGS_RF1R ((uint32_t)0x04000000) -/* Flags in RF0R register */ -#define CAN_FLAGS_RF0R ((uint32_t)0x02000000) -/* Flags in MSR register */ -#define CAN_FLAGS_MSR ((uint32_t)0x01000000) -/* Flags in ESR register */ -#define CAN_FLAGS_ESR ((uint32_t)0x00F00000) - -/* Mailboxes definition */ -#define CAN_TXMAILBOX_0 ((uint8_t)0x00) -#define CAN_TXMAILBOX_1 ((uint8_t)0x01) -#define CAN_TXMAILBOX_2 ((uint8_t)0x02) - -#define CAN_MODE_MASK ((uint32_t) 0x00000003) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ -static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit); - -/** @defgroup CAN_Private_Functions - * @{ - */ - -/** @defgroup CAN_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - This section provides functions allowing to - - Initialize the CAN peripherals : Prescaler, operating mode, the maximum number - of time quanta to perform resynchronization, the number of time quanta in - Bit Segment 1 and 2 and many other modes. - Refer to @ref CAN_InitTypeDef for more details. - - Configures the CAN reception filter. - - Select the start bank filter for slave CAN. - - Enables or disables the Debug Freeze mode for CAN - - Enables or disables the CAN Time Trigger Operation communication mode - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the CAN peripheral registers to their default reset values. - * @param CANx: where x can be 1 or 2 to select the CAN peripheral. - * @retval None. - */ -void CAN_DeInit(CAN_TypeDef* CANx) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - - if (CANx == CAN1) - { - /* Enable CAN1 reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, ENABLE); - /* Release CAN1 from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, DISABLE); - } - else - { - /* Enable CAN2 reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, ENABLE); - /* Release CAN2 from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, DISABLE); - } -} - -/** - * @brief Initializes the CAN peripheral according to the specified - * parameters in the CAN_InitStruct. - * @param CANx: where x can be 1 or 2 to select the CAN peripheral. - * @param CAN_InitStruct: pointer to a CAN_InitTypeDef structure that contains - * the configuration information for the CAN peripheral. - * @retval Constant indicates initialization succeed which will be - * CAN_InitStatus_Failed or CAN_InitStatus_Success. - */ -uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct) -{ - uint8_t InitStatus = CAN_InitStatus_Failed; - uint32_t wait_ack = 0x00000000; - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_TTCM)); - assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_ABOM)); - assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_AWUM)); - assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_NART)); - assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_RFLM)); - assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_TXFP)); - assert_param(IS_CAN_MODE(CAN_InitStruct->CAN_Mode)); - assert_param(IS_CAN_SJW(CAN_InitStruct->CAN_SJW)); - assert_param(IS_CAN_BS1(CAN_InitStruct->CAN_BS1)); - assert_param(IS_CAN_BS2(CAN_InitStruct->CAN_BS2)); - assert_param(IS_CAN_PRESCALER(CAN_InitStruct->CAN_Prescaler)); - - /* Exit from sleep mode */ - CANx->MCR &= (~(uint32_t)CAN_MCR_SLEEP); - - /* Request initialisation */ - CANx->MCR |= CAN_MCR_INRQ ; - - /* Wait the acknowledge */ - while (((CANx->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) && (wait_ack != INAK_TIMEOUT)) - { - wait_ack++; - } - - /* Check acknowledge */ - if ((CANx->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) - { - InitStatus = CAN_InitStatus_Failed; - } - else - { - /* Set the time triggered communication mode */ - if (CAN_InitStruct->CAN_TTCM == ENABLE) - { - CANx->MCR |= CAN_MCR_TTCM; - } - else - { - CANx->MCR &= ~(uint32_t)CAN_MCR_TTCM; - } - - /* Set the automatic bus-off management */ - if (CAN_InitStruct->CAN_ABOM == ENABLE) - { - CANx->MCR |= CAN_MCR_ABOM; - } - else - { - CANx->MCR &= ~(uint32_t)CAN_MCR_ABOM; - } - - /* Set the automatic wake-up mode */ - if (CAN_InitStruct->CAN_AWUM == ENABLE) - { - CANx->MCR |= CAN_MCR_AWUM; - } - else - { - CANx->MCR &= ~(uint32_t)CAN_MCR_AWUM; - } - - /* Set the no automatic retransmission */ - if (CAN_InitStruct->CAN_NART == ENABLE) - { - CANx->MCR |= CAN_MCR_NART; - } - else - { - CANx->MCR &= ~(uint32_t)CAN_MCR_NART; - } - - /* Set the receive FIFO locked mode */ - if (CAN_InitStruct->CAN_RFLM == ENABLE) - { - CANx->MCR |= CAN_MCR_RFLM; - } - else - { - CANx->MCR &= ~(uint32_t)CAN_MCR_RFLM; - } - - /* Set the transmit FIFO priority */ - if (CAN_InitStruct->CAN_TXFP == ENABLE) - { - CANx->MCR |= CAN_MCR_TXFP; - } - else - { - CANx->MCR &= ~(uint32_t)CAN_MCR_TXFP; - } - - /* Set the bit timing register */ - CANx->BTR = (uint32_t)((uint32_t)CAN_InitStruct->CAN_Mode << 30) | \ - ((uint32_t)CAN_InitStruct->CAN_SJW << 24) | \ - ((uint32_t)CAN_InitStruct->CAN_BS1 << 16) | \ - ((uint32_t)CAN_InitStruct->CAN_BS2 << 20) | \ - ((uint32_t)CAN_InitStruct->CAN_Prescaler - 1); - - /* Request leave initialisation */ - CANx->MCR &= ~(uint32_t)CAN_MCR_INRQ; - - /* Wait the acknowledge */ - wait_ack = 0; - - while (((CANx->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) && (wait_ack != INAK_TIMEOUT)) - { - wait_ack++; - } - - /* ...and check acknowledged */ - if ((CANx->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) - { - InitStatus = CAN_InitStatus_Failed; - } - else - { - InitStatus = CAN_InitStatus_Success ; - } - } - - /* At this step, return the status of initialization */ - return InitStatus; -} - -/** - * @brief Configures the CAN reception filter according to the specified - * parameters in the CAN_FilterInitStruct. - * @param CAN_FilterInitStruct: pointer to a CAN_FilterInitTypeDef structure that - * contains the configuration information. - * @retval None - */ -void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct) -{ - uint32_t filter_number_bit_pos = 0; - /* Check the parameters */ - assert_param(IS_CAN_FILTER_NUMBER(CAN_FilterInitStruct->CAN_FilterNumber)); - assert_param(IS_CAN_FILTER_MODE(CAN_FilterInitStruct->CAN_FilterMode)); - assert_param(IS_CAN_FILTER_SCALE(CAN_FilterInitStruct->CAN_FilterScale)); - assert_param(IS_CAN_FILTER_FIFO(CAN_FilterInitStruct->CAN_FilterFIFOAssignment)); - assert_param(IS_FUNCTIONAL_STATE(CAN_FilterInitStruct->CAN_FilterActivation)); - - filter_number_bit_pos = ((uint32_t)1) << CAN_FilterInitStruct->CAN_FilterNumber; - - /* Initialisation mode for the filter */ - CAN1->FMR |= FMR_FINIT; - - /* Filter Deactivation */ - CAN1->FA1R &= ~(uint32_t)filter_number_bit_pos; - - /* Filter Scale */ - if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_16bit) - { - /* 16-bit scale for the filter */ - CAN1->FS1R &= ~(uint32_t)filter_number_bit_pos; - - /* First 16-bit identifier and First 16-bit mask */ - /* Or First 16-bit identifier and Second 16-bit identifier */ - CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 = - ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow) << 16) | - (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow); - - /* Second 16-bit identifier and Second 16-bit mask */ - /* Or Third 16-bit identifier and Fourth 16-bit identifier */ - CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 = - ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) | - (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh); - } - - if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_32bit) - { - /* 32-bit scale for the filter */ - CAN1->FS1R |= filter_number_bit_pos; - /* 32-bit identifier or First 32-bit identifier */ - CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 = - ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh) << 16) | - (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow); - /* 32-bit mask or Second 32-bit identifier */ - CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 = - ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) | - (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow); - } - - /* Filter Mode */ - if (CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdMask) - { - /*Id/Mask mode for the filter*/ - CAN1->FM1R &= ~(uint32_t)filter_number_bit_pos; - } - else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */ - { - /*Identifier list mode for the filter*/ - CAN1->FM1R |= (uint32_t)filter_number_bit_pos; - } - - /* Filter FIFO assignment */ - if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_Filter_FIFO0) - { - /* FIFO 0 assignation for the filter */ - CAN1->FFA1R &= ~(uint32_t)filter_number_bit_pos; - } - - if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_Filter_FIFO1) - { - /* FIFO 1 assignation for the filter */ - CAN1->FFA1R |= (uint32_t)filter_number_bit_pos; - } - - /* Filter activation */ - if (CAN_FilterInitStruct->CAN_FilterActivation == ENABLE) - { - CAN1->FA1R |= filter_number_bit_pos; - } - - /* Leave the initialisation mode for the filter */ - CAN1->FMR &= ~FMR_FINIT; -} - -/** - * @brief Fills each CAN_InitStruct member with its default value. - * @param CAN_InitStruct: pointer to a CAN_InitTypeDef structure which ill be initialized. - * @retval None - */ -void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct) -{ - /* Reset CAN init structure parameters values */ - - /* Initialize the time triggered communication mode */ - CAN_InitStruct->CAN_TTCM = DISABLE; - - /* Initialize the automatic bus-off management */ - CAN_InitStruct->CAN_ABOM = DISABLE; - - /* Initialize the automatic wake-up mode */ - CAN_InitStruct->CAN_AWUM = DISABLE; - - /* Initialize the no automatic retransmission */ - CAN_InitStruct->CAN_NART = DISABLE; - - /* Initialize the receive FIFO locked mode */ - CAN_InitStruct->CAN_RFLM = DISABLE; - - /* Initialize the transmit FIFO priority */ - CAN_InitStruct->CAN_TXFP = DISABLE; - - /* Initialize the CAN_Mode member */ - CAN_InitStruct->CAN_Mode = CAN_Mode_Normal; - - /* Initialize the CAN_SJW member */ - CAN_InitStruct->CAN_SJW = CAN_SJW_1tq; - - /* Initialize the CAN_BS1 member */ - CAN_InitStruct->CAN_BS1 = CAN_BS1_4tq; - - /* Initialize the CAN_BS2 member */ - CAN_InitStruct->CAN_BS2 = CAN_BS2_3tq; - - /* Initialize the CAN_Prescaler member */ - CAN_InitStruct->CAN_Prescaler = 1; -} - -/** - * @brief Select the start bank filter for slave CAN. - * @param CAN_BankNumber: Select the start slave bank filter from 1..27. - * @retval None - */ -void CAN_SlaveStartBank(uint8_t CAN_BankNumber) -{ - /* Check the parameters */ - assert_param(IS_CAN_BANKNUMBER(CAN_BankNumber)); - - /* Enter Initialisation mode for the filter */ - CAN1->FMR |= FMR_FINIT; - - /* Select the start slave bank */ - CAN1->FMR &= (uint32_t)0xFFFFC0F1 ; - CAN1->FMR |= (uint32_t)(CAN_BankNumber)<<8; - - /* Leave Initialisation mode for the filter */ - CAN1->FMR &= ~FMR_FINIT; -} - -/** - * @brief Enables or disables the DBG Freeze for CAN. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param NewState: new state of the CAN peripheral. - * This parameter can be: ENABLE (CAN reception/transmission is frozen - * during debug. Reception FIFOs can still be accessed/controlled normally) - * or DISABLE (CAN is working during debug). - * @retval None - */ -void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable Debug Freeze */ - CANx->MCR |= MCR_DBF; - } - else - { - /* Disable Debug Freeze */ - CANx->MCR &= ~MCR_DBF; - } -} - - -/** - * @brief Enables or disables the CAN Time TriggerOperation communication mode. - * @note DLC must be programmed as 8 in order Time Stamp (2 bytes) to be - * sent over the CAN bus. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param NewState: Mode new state. This parameter can be: ENABLE or DISABLE. - * When enabled, Time stamp (TIME[15:0]) value is sent in the last two - * data bytes of the 8-byte message: TIME[7:0] in data byte 6 and TIME[15:8] - * in data byte 7. - * @retval None - */ -void CAN_TTComModeCmd(CAN_TypeDef* CANx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the TTCM mode */ - CANx->MCR |= CAN_MCR_TTCM; - - /* Set TGT bits */ - CANx->sTxMailBox[0].TDTR |= ((uint32_t)CAN_TDT0R_TGT); - CANx->sTxMailBox[1].TDTR |= ((uint32_t)CAN_TDT1R_TGT); - CANx->sTxMailBox[2].TDTR |= ((uint32_t)CAN_TDT2R_TGT); - } - else - { - /* Disable the TTCM mode */ - CANx->MCR &= (uint32_t)(~(uint32_t)CAN_MCR_TTCM); - - /* Reset TGT bits */ - CANx->sTxMailBox[0].TDTR &= ((uint32_t)~CAN_TDT0R_TGT); - CANx->sTxMailBox[1].TDTR &= ((uint32_t)~CAN_TDT1R_TGT); - CANx->sTxMailBox[2].TDTR &= ((uint32_t)~CAN_TDT2R_TGT); - } -} -/** - * @} - */ - - -/** @defgroup CAN_Group2 CAN Frames Transmission functions - * @brief CAN Frames Transmission functions - * -@verbatim - =============================================================================== - CAN Frames Transmission functions - =============================================================================== - This section provides functions allowing to - - Initiate and transmit a CAN frame message (if there is an empty mailbox). - - Check the transmission status of a CAN Frame - - Cancel a transmit request - -@endverbatim - * @{ - */ - -/** - * @brief Initiates and transmits a CAN frame message. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param TxMessage: pointer to a structure which contains CAN Id, CAN DLC and CAN data. - * @retval The number of the mailbox that is used for transmission or - * CAN_TxStatus_NoMailBox if there is no empty mailbox. - */ -uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage) -{ - uint8_t transmit_mailbox = 0; - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_IDTYPE(TxMessage->IDE)); - assert_param(IS_CAN_RTR(TxMessage->RTR)); - assert_param(IS_CAN_DLC(TxMessage->DLC)); - - /* Select one empty transmit mailbox */ - if ((CANx->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) - { - transmit_mailbox = 0; - } - else if ((CANx->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) - { - transmit_mailbox = 1; - } - else if ((CANx->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) - { - transmit_mailbox = 2; - } - else - { - transmit_mailbox = CAN_TxStatus_NoMailBox; - } - - if (transmit_mailbox != CAN_TxStatus_NoMailBox) - { - /* Set up the Id */ - CANx->sTxMailBox[transmit_mailbox].TIR &= TMIDxR_TXRQ; - if (TxMessage->IDE == CAN_Id_Standard) - { - assert_param(IS_CAN_STDID(TxMessage->StdId)); - CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->StdId << 21) | \ - TxMessage->RTR); - } - else - { - assert_param(IS_CAN_EXTID(TxMessage->ExtId)); - CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->ExtId << 3) | \ - TxMessage->IDE | \ - TxMessage->RTR); - } - - /* Set up the DLC */ - TxMessage->DLC &= (uint8_t)0x0000000F; - CANx->sTxMailBox[transmit_mailbox].TDTR &= (uint32_t)0xFFFFFFF0; - CANx->sTxMailBox[transmit_mailbox].TDTR |= TxMessage->DLC; - - /* Set up the data field */ - CANx->sTxMailBox[transmit_mailbox].TDLR = (((uint32_t)TxMessage->Data[3] << 24) | - ((uint32_t)TxMessage->Data[2] << 16) | - ((uint32_t)TxMessage->Data[1] << 8) | - ((uint32_t)TxMessage->Data[0])); - CANx->sTxMailBox[transmit_mailbox].TDHR = (((uint32_t)TxMessage->Data[7] << 24) | - ((uint32_t)TxMessage->Data[6] << 16) | - ((uint32_t)TxMessage->Data[5] << 8) | - ((uint32_t)TxMessage->Data[4])); - /* Request transmission */ - CANx->sTxMailBox[transmit_mailbox].TIR |= TMIDxR_TXRQ; - } - return transmit_mailbox; -} - -/** - * @brief Checks the transmission status of a CAN Frame. - * @param CANx: where x can be 1 or 2 to select the CAN peripheral. - * @param TransmitMailbox: the number of the mailbox that is used for transmission. - * @retval CAN_TxStatus_Ok if the CAN driver transmits the message, - * CAN_TxStatus_Failed in an other case. - */ -uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox) -{ - uint32_t state = 0; - - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_TRANSMITMAILBOX(TransmitMailbox)); - - switch (TransmitMailbox) - { - case (CAN_TXMAILBOX_0): - state = CANx->TSR & (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0); - break; - case (CAN_TXMAILBOX_1): - state = CANx->TSR & (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1); - break; - case (CAN_TXMAILBOX_2): - state = CANx->TSR & (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2); - break; - default: - state = CAN_TxStatus_Failed; - break; - } - switch (state) - { - /* transmit pending */ - case (0x0): state = CAN_TxStatus_Pending; - break; - /* transmit failed */ - case (CAN_TSR_RQCP0 | CAN_TSR_TME0): state = CAN_TxStatus_Failed; - break; - case (CAN_TSR_RQCP1 | CAN_TSR_TME1): state = CAN_TxStatus_Failed; - break; - case (CAN_TSR_RQCP2 | CAN_TSR_TME2): state = CAN_TxStatus_Failed; - break; - /* transmit succeeded */ - case (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0):state = CAN_TxStatus_Ok; - break; - case (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1):state = CAN_TxStatus_Ok; - break; - case (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2):state = CAN_TxStatus_Ok; - break; - default: state = CAN_TxStatus_Failed; - break; - } - return (uint8_t) state; -} - -/** - * @brief Cancels a transmit request. - * @param CANx: where x can be 1 or 2 to select the CAN peripheral. - * @param Mailbox: Mailbox number. - * @retval None - */ -void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_TRANSMITMAILBOX(Mailbox)); - /* abort transmission */ - switch (Mailbox) - { - case (CAN_TXMAILBOX_0): CANx->TSR |= CAN_TSR_ABRQ0; - break; - case (CAN_TXMAILBOX_1): CANx->TSR |= CAN_TSR_ABRQ1; - break; - case (CAN_TXMAILBOX_2): CANx->TSR |= CAN_TSR_ABRQ2; - break; - default: - break; - } -} -/** - * @} - */ - - -/** @defgroup CAN_Group3 CAN Frames Reception functions - * @brief CAN Frames Reception functions - * -@verbatim - =============================================================================== - CAN Frames Reception functions - =============================================================================== - This section provides functions allowing to - - Receive a correct CAN frame - - Release a specified receive FIFO (2 FIFOs are available) - - Return the number of the pending received CAN frames - -@endverbatim - * @{ - */ - -/** - * @brief Receives a correct CAN frame. - * @param CANx: where x can be 1 or 2 to select the CAN peripheral. - * @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1. - * @param RxMessage: pointer to a structure receive frame which contains CAN Id, - * CAN DLC, CAN data and FMI number. - * @retval None - */ -void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_FIFO(FIFONumber)); - /* Get the Id */ - RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONumber].RIR; - if (RxMessage->IDE == CAN_Id_Standard) - { - RxMessage->StdId = (uint32_t)0x000007FF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 21); - } - else - { - RxMessage->ExtId = (uint32_t)0x1FFFFFFF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 3); - } - - RxMessage->RTR = (uint8_t)0x02 & CANx->sFIFOMailBox[FIFONumber].RIR; - /* Get the DLC */ - RxMessage->DLC = (uint8_t)0x0F & CANx->sFIFOMailBox[FIFONumber].RDTR; - /* Get the FMI */ - RxMessage->FMI = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDTR >> 8); - /* Get the data field */ - RxMessage->Data[0] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDLR; - RxMessage->Data[1] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 8); - RxMessage->Data[2] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 16); - RxMessage->Data[3] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 24); - RxMessage->Data[4] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDHR; - RxMessage->Data[5] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 8); - RxMessage->Data[6] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 16); - RxMessage->Data[7] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 24); - /* Release the FIFO */ - /* Release FIFO0 */ - if (FIFONumber == CAN_FIFO0) - { - CANx->RF0R |= CAN_RF0R_RFOM0; - } - /* Release FIFO1 */ - else /* FIFONumber == CAN_FIFO1 */ - { - CANx->RF1R |= CAN_RF1R_RFOM1; - } -} - -/** - * @brief Releases the specified receive FIFO. - * @param CANx: where x can be 1 or 2 to select the CAN peripheral. - * @param FIFONumber: FIFO to release, CAN_FIFO0 or CAN_FIFO1. - * @retval None - */ -void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_FIFO(FIFONumber)); - /* Release FIFO0 */ - if (FIFONumber == CAN_FIFO0) - { - CANx->RF0R |= CAN_RF0R_RFOM0; - } - /* Release FIFO1 */ - else /* FIFONumber == CAN_FIFO1 */ - { - CANx->RF1R |= CAN_RF1R_RFOM1; - } -} - -/** - * @brief Returns the number of pending received messages. - * @param CANx: where x can be 1 or 2 to select the CAN peripheral. - * @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1. - * @retval NbMessage : which is the number of pending message. - */ -uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber) -{ - uint8_t message_pending=0; - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_FIFO(FIFONumber)); - if (FIFONumber == CAN_FIFO0) - { - message_pending = (uint8_t)(CANx->RF0R&(uint32_t)0x03); - } - else if (FIFONumber == CAN_FIFO1) - { - message_pending = (uint8_t)(CANx->RF1R&(uint32_t)0x03); - } - else - { - message_pending = 0; - } - return message_pending; -} -/** - * @} - */ - - -/** @defgroup CAN_Group4 CAN Operation modes functions - * @brief CAN Operation modes functions - * -@verbatim - =============================================================================== - CAN Operation modes functions - =============================================================================== - This section provides functions allowing to select the CAN Operation modes - - sleep mode - - normal mode - - initialization mode - -@endverbatim - * @{ - */ - - -/** - * @brief Selects the CAN Operation mode. - * @param CAN_OperatingMode: CAN Operating Mode. - * This parameter can be one of @ref CAN_OperatingMode_TypeDef enumeration. - * @retval status of the requested mode which can be - * - CAN_ModeStatus_Failed: CAN failed entering the specific mode - * - CAN_ModeStatus_Success: CAN Succeed entering the specific mode - */ -uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode) -{ - uint8_t status = CAN_ModeStatus_Failed; - - /* Timeout for INAK or also for SLAK bits*/ - uint32_t timeout = INAK_TIMEOUT; - - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_OPERATING_MODE(CAN_OperatingMode)); - - if (CAN_OperatingMode == CAN_OperatingMode_Initialization) - { - /* Request initialisation */ - CANx->MCR = (uint32_t)((CANx->MCR & (uint32_t)(~(uint32_t)CAN_MCR_SLEEP)) | CAN_MCR_INRQ); - - /* Wait the acknowledge */ - while (((CANx->MSR & CAN_MODE_MASK) != CAN_MSR_INAK) && (timeout != 0)) - { - timeout--; - } - if ((CANx->MSR & CAN_MODE_MASK) != CAN_MSR_INAK) - { - status = CAN_ModeStatus_Failed; - } - else - { - status = CAN_ModeStatus_Success; - } - } - else if (CAN_OperatingMode == CAN_OperatingMode_Normal) - { - /* Request leave initialisation and sleep mode and enter Normal mode */ - CANx->MCR &= (uint32_t)(~(CAN_MCR_SLEEP|CAN_MCR_INRQ)); - - /* Wait the acknowledge */ - while (((CANx->MSR & CAN_MODE_MASK) != 0) && (timeout!=0)) - { - timeout--; - } - if ((CANx->MSR & CAN_MODE_MASK) != 0) - { - status = CAN_ModeStatus_Failed; - } - else - { - status = CAN_ModeStatus_Success; - } - } - else if (CAN_OperatingMode == CAN_OperatingMode_Sleep) - { - /* Request Sleep mode */ - CANx->MCR = (uint32_t)((CANx->MCR & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP); - - /* Wait the acknowledge */ - while (((CANx->MSR & CAN_MODE_MASK) != CAN_MSR_SLAK) && (timeout!=0)) - { - timeout--; - } - if ((CANx->MSR & CAN_MODE_MASK) != CAN_MSR_SLAK) - { - status = CAN_ModeStatus_Failed; - } - else - { - status = CAN_ModeStatus_Success; - } - } - else - { - status = CAN_ModeStatus_Failed; - } - - return (uint8_t) status; -} - -/** - * @brief Enters the Sleep (low power) mode. - * @param CANx: where x can be 1 or 2 to select the CAN peripheral. - * @retval CAN_Sleep_Ok if sleep entered, CAN_Sleep_Failed otherwise. - */ -uint8_t CAN_Sleep(CAN_TypeDef* CANx) -{ - uint8_t sleepstatus = CAN_Sleep_Failed; - - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - - /* Request Sleep mode */ - CANx->MCR = (((CANx->MCR) & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP); - - /* Sleep mode status */ - if ((CANx->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) == CAN_MSR_SLAK) - { - /* Sleep mode not entered */ - sleepstatus = CAN_Sleep_Ok; - } - /* return sleep mode status */ - return (uint8_t)sleepstatus; -} - -/** - * @brief Wakes up the CAN peripheral from sleep mode . - * @param CANx: where x can be 1 or 2 to select the CAN peripheral. - * @retval CAN_WakeUp_Ok if sleep mode left, CAN_WakeUp_Failed otherwise. - */ -uint8_t CAN_WakeUp(CAN_TypeDef* CANx) -{ - uint32_t wait_slak = SLAK_TIMEOUT; - uint8_t wakeupstatus = CAN_WakeUp_Failed; - - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - - /* Wake up request */ - CANx->MCR &= ~(uint32_t)CAN_MCR_SLEEP; - - /* Sleep mode status */ - while(((CANx->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)&&(wait_slak!=0x00)) - { - wait_slak--; - } - if((CANx->MSR & CAN_MSR_SLAK) != CAN_MSR_SLAK) - { - /* wake up done : Sleep mode exited */ - wakeupstatus = CAN_WakeUp_Ok; - } - /* return wakeup status */ - return (uint8_t)wakeupstatus; -} -/** - * @} - */ - - -/** @defgroup CAN_Group5 CAN Bus Error management functions - * @brief CAN Bus Error management functions - * -@verbatim - =============================================================================== - CAN Bus Error management functions - =============================================================================== - This section provides functions allowing to - - Return the CANx's last error code (LEC) - - Return the CANx Receive Error Counter (REC) - - Return the LSB of the 9-bit CANx Transmit Error Counter(TEC). - - @note If TEC is greater than 255, The CAN is in bus-off state. - @note if REC or TEC are greater than 96, an Error warning flag occurs. - @note if REC or TEC are greater than 127, an Error Passive Flag occurs. - -@endverbatim - * @{ - */ - -/** - * @brief Returns the CANx's last error code (LEC). - * @param CANx: where x can be 1 or 2 to select the CAN peripheral. - * @retval Error code: - * - CAN_ERRORCODE_NoErr: No Error - * - CAN_ERRORCODE_StuffErr: Stuff Error - * - CAN_ERRORCODE_FormErr: Form Error - * - CAN_ERRORCODE_ACKErr : Acknowledgment Error - * - CAN_ERRORCODE_BitRecessiveErr: Bit Recessive Error - * - CAN_ERRORCODE_BitDominantErr: Bit Dominant Error - * - CAN_ERRORCODE_CRCErr: CRC Error - * - CAN_ERRORCODE_SoftwareSetErr: Software Set Error - */ -uint8_t CAN_GetLastErrorCode(CAN_TypeDef* CANx) -{ - uint8_t errorcode=0; - - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - - /* Get the error code*/ - errorcode = (((uint8_t)CANx->ESR) & (uint8_t)CAN_ESR_LEC); - - /* Return the error code*/ - return errorcode; -} - -/** - * @brief Returns the CANx Receive Error Counter (REC). - * @note In case of an error during reception, this counter is incremented - * by 1 or by 8 depending on the error condition as defined by the CAN - * standard. After every successful reception, the counter is - * decremented by 1 or reset to 120 if its value was higher than 128. - * When the counter value exceeds 127, the CAN controller enters the - * error passive state. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @retval CAN Receive Error Counter. - */ -uint8_t CAN_GetReceiveErrorCounter(CAN_TypeDef* CANx) -{ - uint8_t counter=0; - - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - - /* Get the Receive Error Counter*/ - counter = (uint8_t)((CANx->ESR & CAN_ESR_REC)>> 24); - - /* Return the Receive Error Counter*/ - return counter; -} - - -/** - * @brief Returns the LSB of the 9-bit CANx Transmit Error Counter(TEC). - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @retval LSB of the 9-bit CAN Transmit Error Counter. - */ -uint8_t CAN_GetLSBTransmitErrorCounter(CAN_TypeDef* CANx) -{ - uint8_t counter=0; - - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - - /* Get the LSB of the 9-bit CANx Transmit Error Counter(TEC) */ - counter = (uint8_t)((CANx->ESR & CAN_ESR_TEC)>> 16); - - /* Return the LSB of the 9-bit CANx Transmit Error Counter(TEC) */ - return counter; -} -/** - * @} - */ - -/** @defgroup CAN_Group6 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - - This section provides functions allowing to configure the CAN Interrupts and - to get the status and clear flags and Interrupts pending bits. - - The CAN provides 14 Interrupts sources and 15 Flags: - - =============== - Flags : - =============== - The 15 flags can be divided on 4 groups: - - A. Transmit Flags - ----------------------- - CAN_FLAG_RQCP0, - CAN_FLAG_RQCP1, - CAN_FLAG_RQCP2 : Request completed MailBoxes 0, 1 and 2 Flags - Set when when the last request (transmit or abort) has - been performed. - - B. Receive Flags - ----------------------- - - CAN_FLAG_FMP0, - CAN_FLAG_FMP1 : FIFO 0 and 1 Message Pending Flags - set to signal that messages are pending in the receive - FIFO. - These Flags are cleared only by hardware. - - CAN_FLAG_FF0, - CAN_FLAG_FF1 : FIFO 0 and 1 Full Flags - set when three messages are stored in the selected - FIFO. - - CAN_FLAG_FOV0 - CAN_FLAG_FOV1 : FIFO 0 and 1 Overrun Flags - set when a new message has been received and passed - the filter while the FIFO was full. - - C. Operating Mode Flags - ----------------------- - CAN_FLAG_WKU : Wake up Flag - set to signal that a SOF bit has been detected while - the CAN hardware was in Sleep mode. - - CAN_FLAG_SLAK : Sleep acknowledge Flag - Set to signal that the CAN has entered Sleep Mode. - - D. Error Flags - ----------------------- - CAN_FLAG_EWG : Error Warning Flag - Set when the warning limit has been reached (Receive - Error Counter or Transmit Error Counter greater than 96). - This Flag is cleared only by hardware. - - CAN_FLAG_EPV : Error Passive Flag - Set when the Error Passive limit has been reached - (Receive Error Counter or Transmit Error Counter - greater than 127). - This Flag is cleared only by hardware. - - CAN_FLAG_BOF : Bus-Off Flag - set when CAN enters the bus-off state. The bus-off - state is entered on TEC overflow, greater than 255. - This Flag is cleared only by hardware. - - CAN_FLAG_LEC : Last error code Flag - set If a message has been transferred (reception or - transmission) with error, and the error code is hold. - - =============== - Interrupts : - =============== - The 14 interrupts can be divided on 4 groups: - - A. Transmit interrupt - ----------------------- - CAN_IT_TME : Transmit mailbox empty Interrupt - if enabled, this interrupt source is pending when - no transmit request are pending for Tx mailboxes. - - B. Receive Interrupts - ----------------------- - CAN_IT_FMP0, - CAN_IT_FMP1 : FIFO 0 and FIFO1 message pending Interrupts - if enabled, these interrupt sources are pending when - messages are pending in the receive FIFO. - The corresponding interrupt pending bits are cleared - only by hardware. - - CAN_IT_FF0, - CAN_IT_FF1 : FIFO 0 and FIFO1 full Interrupts - if enabled, these interrupt sources are pending when - three messages are stored in the selected FIFO. - - CAN_IT_FOV0, - CAN_IT_FOV1 : FIFO 0 and FIFO1 overrun Interrupts - if enabled, these interrupt sources are pending when - a new message has been received and passed the filter - while the FIFO was full. - - C. Operating Mode Interrupts - ------------------------------- - CAN_IT_WKU : Wake-up Interrupt - if enabled, this interrupt source is pending when - a SOF bit has been detected while the CAN hardware was - in Sleep mode. - - CAN_IT_SLK : Sleep acknowledge Interrupt - if enabled, this interrupt source is pending when - the CAN has entered Sleep Mode. - - D. Error Interrupts - ----------------------- - CAN_IT_EWG : Error warning Interrupt - if enabled, this interrupt source is pending when - the warning limit has been reached (Receive Error - Counter or Transmit Error Counter=96). - - CAN_IT_EPV : Error passive Interrupt - if enabled, this interrupt source is pending when - the Error Passive limit has been reached (Receive - Error Counter or Transmit Error Counter>127). - - CAN_IT_BOF : Bus-off Interrupt - if enabled, this interrupt source is pending when - CAN enters the bus-off state. The bus-off state is - entered on TEC overflow, greater than 255. - This Flag is cleared only by hardware. - - CAN_IT_LEC : Last error code Interrupt - if enabled, this interrupt source is pending when - a message has been transferred (reception or - transmission) with error, and the error code is hold. - - CAN_IT_ERR : Error Interrupt - if enabled, this interrupt source is pending when - an error condition is pending. - - - Managing the CAN controller events : - ------------------------------------ - The user should identify which mode will be used in his application to manage - the CAN controller events: Polling mode or Interrupt mode. - - 1. In the Polling Mode it is advised to use the following functions: - - CAN_GetFlagStatus() : to check if flags events occur. - - CAN_ClearFlag() : to clear the flags events. - - - - 2. In the Interrupt Mode it is advised to use the following functions: - - CAN_ITConfig() : to enable or disable the interrupt source. - - CAN_GetITStatus() : to check if Interrupt occurs. - - CAN_ClearITPendingBit() : to clear the Interrupt pending Bit (corresponding Flag). - @note This function has no impact on CAN_IT_FMP0 and CAN_IT_FMP1 Interrupts - pending bits since there are cleared only by hardware. - -@endverbatim - * @{ - */ -/** - * @brief Enables or disables the specified CANx interrupts. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param CAN_IT: specifies the CAN interrupt sources to be enabled or disabled. - * This parameter can be: - * @arg CAN_IT_TME: Transmit mailbox empty Interrupt - * @arg CAN_IT_FMP0: FIFO 0 message pending Interrupt - * @arg CAN_IT_FF0: FIFO 0 full Interrupt - * @arg CAN_IT_FOV0: FIFO 0 overrun Interrupt - * @arg CAN_IT_FMP1: FIFO 1 message pending Interrupt - * @arg CAN_IT_FF1: FIFO 1 full Interrupt - * @arg CAN_IT_FOV1: FIFO 1 overrun Interrupt - * @arg CAN_IT_WKU: Wake-up Interrupt - * @arg CAN_IT_SLK: Sleep acknowledge Interrupt - * @arg CAN_IT_EWG: Error warning Interrupt - * @arg CAN_IT_EPV: Error passive Interrupt - * @arg CAN_IT_BOF: Bus-off Interrupt - * @arg CAN_IT_LEC: Last error code Interrupt - * @arg CAN_IT_ERR: Error Interrupt - * @param NewState: new state of the CAN interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_IT(CAN_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected CANx interrupt */ - CANx->IER |= CAN_IT; - } - else - { - /* Disable the selected CANx interrupt */ - CANx->IER &= ~CAN_IT; - } -} -/** - * @brief Checks whether the specified CAN flag is set or not. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param CAN_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg CAN_FLAG_RQCP0: Request MailBox0 Flag - * @arg CAN_FLAG_RQCP1: Request MailBox1 Flag - * @arg CAN_FLAG_RQCP2: Request MailBox2 Flag - * @arg CAN_FLAG_FMP0: FIFO 0 Message Pending Flag - * @arg CAN_FLAG_FF0: FIFO 0 Full Flag - * @arg CAN_FLAG_FOV0: FIFO 0 Overrun Flag - * @arg CAN_FLAG_FMP1: FIFO 1 Message Pending Flag - * @arg CAN_FLAG_FF1: FIFO 1 Full Flag - * @arg CAN_FLAG_FOV1: FIFO 1 Overrun Flag - * @arg CAN_FLAG_WKU: Wake up Flag - * @arg CAN_FLAG_SLAK: Sleep acknowledge Flag - * @arg CAN_FLAG_EWG: Error Warning Flag - * @arg CAN_FLAG_EPV: Error Passive Flag - * @arg CAN_FLAG_BOF: Bus-Off Flag - * @arg CAN_FLAG_LEC: Last error code Flag - * @retval The new state of CAN_FLAG (SET or RESET). - */ -FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG) -{ - FlagStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_GET_FLAG(CAN_FLAG)); - - - if((CAN_FLAG & CAN_FLAGS_ESR) != (uint32_t)RESET) - { - /* Check the status of the specified CAN flag */ - if ((CANx->ESR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET) - { - /* CAN_FLAG is set */ - bitstatus = SET; - } - else - { - /* CAN_FLAG is reset */ - bitstatus = RESET; - } - } - else if((CAN_FLAG & CAN_FLAGS_MSR) != (uint32_t)RESET) - { - /* Check the status of the specified CAN flag */ - if ((CANx->MSR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET) - { - /* CAN_FLAG is set */ - bitstatus = SET; - } - else - { - /* CAN_FLAG is reset */ - bitstatus = RESET; - } - } - else if((CAN_FLAG & CAN_FLAGS_TSR) != (uint32_t)RESET) - { - /* Check the status of the specified CAN flag */ - if ((CANx->TSR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET) - { - /* CAN_FLAG is set */ - bitstatus = SET; - } - else - { - /* CAN_FLAG is reset */ - bitstatus = RESET; - } - } - else if((CAN_FLAG & CAN_FLAGS_RF0R) != (uint32_t)RESET) - { - /* Check the status of the specified CAN flag */ - if ((CANx->RF0R & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET) - { - /* CAN_FLAG is set */ - bitstatus = SET; - } - else - { - /* CAN_FLAG is reset */ - bitstatus = RESET; - } - } - else /* If(CAN_FLAG & CAN_FLAGS_RF1R != (uint32_t)RESET) */ - { - /* Check the status of the specified CAN flag */ - if ((uint32_t)(CANx->RF1R & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET) - { - /* CAN_FLAG is set */ - bitstatus = SET; - } - else - { - /* CAN_FLAG is reset */ - bitstatus = RESET; - } - } - /* Return the CAN_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the CAN's pending flags. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param CAN_FLAG: specifies the flag to clear. - * This parameter can be one of the following values: - * @arg CAN_FLAG_RQCP0: Request MailBox0 Flag - * @arg CAN_FLAG_RQCP1: Request MailBox1 Flag - * @arg CAN_FLAG_RQCP2: Request MailBox2 Flag - * @arg CAN_FLAG_FF0: FIFO 0 Full Flag - * @arg CAN_FLAG_FOV0: FIFO 0 Overrun Flag - * @arg CAN_FLAG_FF1: FIFO 1 Full Flag - * @arg CAN_FLAG_FOV1: FIFO 1 Overrun Flag - * @arg CAN_FLAG_WKU: Wake up Flag - * @arg CAN_FLAG_SLAK: Sleep acknowledge Flag - * @arg CAN_FLAG_LEC: Last error code Flag - * @retval None - */ -void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG) -{ - uint32_t flagtmp=0; - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_CLEAR_FLAG(CAN_FLAG)); - - if (CAN_FLAG == CAN_FLAG_LEC) /* ESR register */ - { - /* Clear the selected CAN flags */ - CANx->ESR = (uint32_t)RESET; - } - else /* MSR or TSR or RF0R or RF1R */ - { - flagtmp = CAN_FLAG & 0x000FFFFF; - - if ((CAN_FLAG & CAN_FLAGS_RF0R)!=(uint32_t)RESET) - { - /* Receive Flags */ - CANx->RF0R = (uint32_t)(flagtmp); - } - else if ((CAN_FLAG & CAN_FLAGS_RF1R)!=(uint32_t)RESET) - { - /* Receive Flags */ - CANx->RF1R = (uint32_t)(flagtmp); - } - else if ((CAN_FLAG & CAN_FLAGS_TSR)!=(uint32_t)RESET) - { - /* Transmit Flags */ - CANx->TSR = (uint32_t)(flagtmp); - } - else /* If((CAN_FLAG & CAN_FLAGS_MSR)!=(uint32_t)RESET) */ - { - /* Operating mode Flags */ - CANx->MSR = (uint32_t)(flagtmp); - } - } -} - -/** - * @brief Checks whether the specified CANx interrupt has occurred or not. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param CAN_IT: specifies the CAN interrupt source to check. - * This parameter can be one of the following values: - * @arg CAN_IT_TME: Transmit mailbox empty Interrupt - * @arg CAN_IT_FMP0: FIFO 0 message pending Interrupt - * @arg CAN_IT_FF0: FIFO 0 full Interrupt - * @arg CAN_IT_FOV0: FIFO 0 overrun Interrupt - * @arg CAN_IT_FMP1: FIFO 1 message pending Interrupt - * @arg CAN_IT_FF1: FIFO 1 full Interrupt - * @arg CAN_IT_FOV1: FIFO 1 overrun Interrupt - * @arg CAN_IT_WKU: Wake-up Interrupt - * @arg CAN_IT_SLK: Sleep acknowledge Interrupt - * @arg CAN_IT_EWG: Error warning Interrupt - * @arg CAN_IT_EPV: Error passive Interrupt - * @arg CAN_IT_BOF: Bus-off Interrupt - * @arg CAN_IT_LEC: Last error code Interrupt - * @arg CAN_IT_ERR: Error Interrupt - * @retval The current state of CAN_IT (SET or RESET). - */ -ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT) -{ - ITStatus itstatus = RESET; - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_IT(CAN_IT)); - - /* check the interrupt enable bit */ - if((CANx->IER & CAN_IT) != RESET) - { - /* in case the Interrupt is enabled, .... */ - switch (CAN_IT) - { - case CAN_IT_TME: - /* Check CAN_TSR_RQCPx bits */ - itstatus = CheckITStatus(CANx->TSR, CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2); - break; - case CAN_IT_FMP0: - /* Check CAN_RF0R_FMP0 bit */ - itstatus = CheckITStatus(CANx->RF0R, CAN_RF0R_FMP0); - break; - case CAN_IT_FF0: - /* Check CAN_RF0R_FULL0 bit */ - itstatus = CheckITStatus(CANx->RF0R, CAN_RF0R_FULL0); - break; - case CAN_IT_FOV0: - /* Check CAN_RF0R_FOVR0 bit */ - itstatus = CheckITStatus(CANx->RF0R, CAN_RF0R_FOVR0); - break; - case CAN_IT_FMP1: - /* Check CAN_RF1R_FMP1 bit */ - itstatus = CheckITStatus(CANx->RF1R, CAN_RF1R_FMP1); - break; - case CAN_IT_FF1: - /* Check CAN_RF1R_FULL1 bit */ - itstatus = CheckITStatus(CANx->RF1R, CAN_RF1R_FULL1); - break; - case CAN_IT_FOV1: - /* Check CAN_RF1R_FOVR1 bit */ - itstatus = CheckITStatus(CANx->RF1R, CAN_RF1R_FOVR1); - break; - case CAN_IT_WKU: - /* Check CAN_MSR_WKUI bit */ - itstatus = CheckITStatus(CANx->MSR, CAN_MSR_WKUI); - break; - case CAN_IT_SLK: - /* Check CAN_MSR_SLAKI bit */ - itstatus = CheckITStatus(CANx->MSR, CAN_MSR_SLAKI); - break; - case CAN_IT_EWG: - /* Check CAN_ESR_EWGF bit */ - itstatus = CheckITStatus(CANx->ESR, CAN_ESR_EWGF); - break; - case CAN_IT_EPV: - /* Check CAN_ESR_EPVF bit */ - itstatus = CheckITStatus(CANx->ESR, CAN_ESR_EPVF); - break; - case CAN_IT_BOF: - /* Check CAN_ESR_BOFF bit */ - itstatus = CheckITStatus(CANx->ESR, CAN_ESR_BOFF); - break; - case CAN_IT_LEC: - /* Check CAN_ESR_LEC bit */ - itstatus = CheckITStatus(CANx->ESR, CAN_ESR_LEC); - break; - case CAN_IT_ERR: - /* Check CAN_MSR_ERRI bit */ - itstatus = CheckITStatus(CANx->MSR, CAN_MSR_ERRI); - break; - default: - /* in case of error, return RESET */ - itstatus = RESET; - break; - } - } - else - { - /* in case the Interrupt is not enabled, return RESET */ - itstatus = RESET; - } - - /* Return the CAN_IT status */ - return itstatus; -} - -/** - * @brief Clears the CANx's interrupt pending bits. - * @param CANx: where x can be 1 or 2 to to select the CAN peripheral. - * @param CAN_IT: specifies the interrupt pending bit to clear. - * This parameter can be one of the following values: - * @arg CAN_IT_TME: Transmit mailbox empty Interrupt - * @arg CAN_IT_FF0: FIFO 0 full Interrupt - * @arg CAN_IT_FOV0: FIFO 0 overrun Interrupt - * @arg CAN_IT_FF1: FIFO 1 full Interrupt - * @arg CAN_IT_FOV1: FIFO 1 overrun Interrupt - * @arg CAN_IT_WKU: Wake-up Interrupt - * @arg CAN_IT_SLK: Sleep acknowledge Interrupt - * @arg CAN_IT_EWG: Error warning Interrupt - * @arg CAN_IT_EPV: Error passive Interrupt - * @arg CAN_IT_BOF: Bus-off Interrupt - * @arg CAN_IT_LEC: Last error code Interrupt - * @arg CAN_IT_ERR: Error Interrupt - * @retval None - */ -void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT) -{ - /* Check the parameters */ - assert_param(IS_CAN_ALL_PERIPH(CANx)); - assert_param(IS_CAN_CLEAR_IT(CAN_IT)); - - switch (CAN_IT) - { - case CAN_IT_TME: - /* Clear CAN_TSR_RQCPx (rc_w1)*/ - CANx->TSR = CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2; - break; - case CAN_IT_FF0: - /* Clear CAN_RF0R_FULL0 (rc_w1)*/ - CANx->RF0R = CAN_RF0R_FULL0; - break; - case CAN_IT_FOV0: - /* Clear CAN_RF0R_FOVR0 (rc_w1)*/ - CANx->RF0R = CAN_RF0R_FOVR0; - break; - case CAN_IT_FF1: - /* Clear CAN_RF1R_FULL1 (rc_w1)*/ - CANx->RF1R = CAN_RF1R_FULL1; - break; - case CAN_IT_FOV1: - /* Clear CAN_RF1R_FOVR1 (rc_w1)*/ - CANx->RF1R = CAN_RF1R_FOVR1; - break; - case CAN_IT_WKU: - /* Clear CAN_MSR_WKUI (rc_w1)*/ - CANx->MSR = CAN_MSR_WKUI; - break; - case CAN_IT_SLK: - /* Clear CAN_MSR_SLAKI (rc_w1)*/ - CANx->MSR = CAN_MSR_SLAKI; - break; - case CAN_IT_EWG: - /* Clear CAN_MSR_ERRI (rc_w1) */ - CANx->MSR = CAN_MSR_ERRI; - /* @note the corresponding Flag is cleared by hardware depending on the CAN Bus status*/ - break; - case CAN_IT_EPV: - /* Clear CAN_MSR_ERRI (rc_w1) */ - CANx->MSR = CAN_MSR_ERRI; - /* @note the corresponding Flag is cleared by hardware depending on the CAN Bus status*/ - break; - case CAN_IT_BOF: - /* Clear CAN_MSR_ERRI (rc_w1) */ - CANx->MSR = CAN_MSR_ERRI; - /* @note the corresponding Flag is cleared by hardware depending on the CAN Bus status*/ - break; - case CAN_IT_LEC: - /* Clear LEC bits */ - CANx->ESR = RESET; - /* Clear CAN_MSR_ERRI (rc_w1) */ - CANx->MSR = CAN_MSR_ERRI; - break; - case CAN_IT_ERR: - /*Clear LEC bits */ - CANx->ESR = RESET; - /* Clear CAN_MSR_ERRI (rc_w1) */ - CANx->MSR = CAN_MSR_ERRI; - /* @note BOFF, EPVF and EWGF Flags are cleared by hardware depending on the CAN Bus status*/ - break; - default: - break; - } -} - /** - * @} - */ - -/** - * @brief Checks whether the CAN interrupt has occurred or not. - * @param CAN_Reg: specifies the CAN interrupt register to check. - * @param It_Bit: specifies the interrupt source bit to check. - * @retval The new state of the CAN Interrupt (SET or RESET). - */ -static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit) -{ - ITStatus pendingbitstatus = RESET; - - if ((CAN_Reg & It_Bit) != (uint32_t)RESET) - { - /* CAN_IT is set */ - pendingbitstatus = SET; - } - else - { - /* CAN_IT is reset */ - pendingbitstatus = RESET; - } - return pendingbitstatus; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_crc.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_crc.c deleted file mode 100644 index 5c2733074..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_crc.c +++ /dev/null @@ -1,127 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_crc.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides all the CRC firmware functions. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_crc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup CRC - * @brief CRC driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup CRC_Private_Functions - * @{ - */ - -/** - * @brief Resets the CRC Data register (DR). - * @param None - * @retval None - */ -void CRC_ResetDR(void) -{ - /* Reset CRC generator */ - CRC->CR = CRC_CR_RESET; -} - -/** - * @brief Computes the 32-bit CRC of a given data word(32-bit). - * @param Data: data word(32-bit) to compute its CRC - * @retval 32-bit CRC - */ -uint32_t CRC_CalcCRC(uint32_t Data) -{ - CRC->DR = Data; - - return (CRC->DR); -} - -/** - * @brief Computes the 32-bit CRC of a given buffer of data word(32-bit). - * @param pBuffer: pointer to the buffer containing the data to be computed - * @param BufferLength: length of the buffer to be computed - * @retval 32-bit CRC - */ -uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength) -{ - uint32_t index = 0; - - for(index = 0; index < BufferLength; index++) - { - CRC->DR = pBuffer[index]; - } - return (CRC->DR); -} - -/** - * @brief Returns the current CRC value. - * @param None - * @retval 32-bit CRC - */ -uint32_t CRC_GetCRC(void) -{ - return (CRC->DR); -} - -/** - * @brief Stores a 8-bit data in the Independent Data(ID) register. - * @param IDValue: 8-bit value to be stored in the ID register - * @retval None - */ -void CRC_SetIDRegister(uint8_t IDValue) -{ - CRC->IDR = IDValue; -} - -/** - * @brief Returns the 8-bit data stored in the Independent Data(ID) register - * @param None - * @retval 8-bit value of the ID register - */ -uint8_t CRC_GetIDRegister(void) -{ - return (CRC->IDR); -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp.c deleted file mode 100644 index 8ba35d3ad..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp.c +++ /dev/null @@ -1,850 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_cryp.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the Cryptographic processor (CRYP) peripheral: - * - Initialization and Configuration functions - * - Data treatment functions - * - Context swapping functions - * - DMA interface function - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable the CRYP controller clock using - * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, ENABLE); function. - * - * 2. Initialise the CRYP using CRYP_Init(), CRYP_KeyInit() and if - * needed CRYP_IVInit(). - * - * 3. Flush the IN and OUT FIFOs by using CRYP_FIFOFlush() function. - * - * 4. Enable the CRYP controller using the CRYP_Cmd() function. - * - * 5. If using DMA for Data input and output transfer, - * Activate the needed DMA Requests using CRYP_DMACmd() function - - * 6. If DMA is not used for data transfer, use CRYP_DataIn() and - * CRYP_DataOut() functions to enter data to IN FIFO and get result - * from OUT FIFO. - * - * 7. To control CRYP events you can use one of the following - * two methods: - * - Check on CRYP flags using the CRYP_GetFlagStatus() function. - * - Use CRYP interrupts through the function CRYP_ITConfig() at - * initialization phase and CRYP_GetITStatus() function into - * interrupt routines in processing phase. - * - * 8. Save and restore Cryptographic processor context using - * CRYP_SaveContext() and CRYP_RestoreContext() functions. - * - * - * =================================================================== - * Procedure to perform an encryption or a decryption - * =================================================================== - * - * Initialization - * =============== - * 1. Initialize the peripheral using CRYP_Init(), CRYP_KeyInit() and - * CRYP_IVInit functions: - * - Configure the key size (128-, 192- or 256-bit, in the AES only) - * - Enter the symmetric key - * - Configure the data type - * - In case of decryption in AES-ECB or AES-CBC, you must prepare - * the key: configure the key preparation mode. Then Enable the CRYP - * peripheral using CRYP_Cmd() function: the BUSY flag is set. - * Wait until BUSY flag is reset : the key is prepared for decryption - * - Configure the algorithm and chaining (the DES/TDES in ECB/CBC, the - * AES in ECB/CBC/CTR) - * - Configure the direction (encryption/decryption). - * - Write the initialization vectors (in CBC or CTR modes only) - * - * 2. Flush the IN and OUT FIFOs using the CRYP_FIFOFlush() function - * - * - * Basic Processing mode (polling mode) - * ==================================== - * 1. Enable the cryptographic processor using CRYP_Cmd() function. - * - * 2. Write the first blocks in the input FIFO (2 to 8 words) using - * CRYP_DataIn() function. - * - * 3. Repeat the following sequence until the complete message has been - * processed: - * - * a) Wait for flag CRYP_FLAG_OFNE occurs (using CRYP_GetFlagStatus() - * function), then read the OUT-FIFO using CRYP_DataOut() function - * (1 block or until the FIFO is empty) - * - * b) Wait for flag CRYP_FLAG_IFNF occurs, (using CRYP_GetFlagStatus() - * function then write the IN FIFO using CRYP_DataIn() function - * (1 block or until the FIFO is full) - * - * 4. At the end of the processing, CRYP_FLAG_BUSY flag will be reset and - * both FIFOs are empty (CRYP_FLAG_IFEM is set and CRYP_FLAG_OFNE is - * reset). You can disable the peripheral using CRYP_Cmd() function. - * - * Interrupts Processing mode - * =========================== - * In this mode, Processing is done when the data are transferred by the - * CPU during interrupts. - * - * 1. Enable the interrupts CRYP_IT_INI and CRYP_IT_OUTI using - * CRYP_ITConfig() function. - * - * 2. Enable the cryptographic processor using CRYP_Cmd() function. - * - * 3. In the CRYP_IT_INI interrupt handler : load the input message into the - * IN FIFO using CRYP_DataIn() function . You can load 2 or 4 words at a - * time, or load data until the IN FIFO is full. When the last word of - * the message has been entered into the IN FIFO, disable the CRYP_IT_INI - * interrupt (using CRYP_ITConfig() function). - * - * 4. In the CRYP_IT_OUTI interrupt handler : read the output message from - * the OUT FIFO using CRYP_DataOut() function. You can read 1 block (2 or - * 4 words) at a time or read data until the FIFO is empty. - * When the last word has been read, INIM=0, BUSY=0 and both FIFOs are - * empty (CRYP_FLAG_IFEM is set and CRYP_FLAG_OFNE is reset). - * You can disable the CRYP_IT_OUTI interrupt (using CRYP_ITConfig() - * function) and you can disable the peripheral using CRYP_Cmd() function. - * - * DMA Processing mode - * ==================== - * In this mode, Processing is done when the DMA is used to transfer the - * data from/to the memory. - * - * 1. Configure the DMA controller to transfer the input data from the - * memory using DMA_Init() function. - * The transfer length is the length of the message. - * As message padding is not managed by the peripheral, the message - * length must be an entire number of blocks. The data are transferred - * in burst mode. The burst length is 4 words in the AES and 2 or 4 - * words in the DES/TDES. The DMA should be configured to set an - * interrupt on transfer completion of the output data to indicate that - * the processing is finished. - * Refer to DMA peripheral driver for more details. - * - * 2. Enable the cryptographic processor using CRYP_Cmd() function. - * Enable the DMA requests CRYP_DMAReq_DataIN and CRYP_DMAReq_DataOUT - * using CRYP_DMACmd() function. - * - * 3. All the transfers and processing are managed by the DMA and the - * cryptographic processor. The DMA transfer complete interrupt indicates - * that the processing is complete. Both FIFOs are normally empty and - * CRYP_FLAG_BUSY flag is reset. - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_cryp.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup CRYP - * @brief CRYP driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define FLAG_MASK ((uint8_t)0x20) -#define MAX_TIMEOUT ((uint16_t)0xFFFF) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup CRYP_Private_Functions - * @{ - */ - -/** @defgroup CRYP_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - This section provides functions allowing to - - Initialize the cryptographic Processor using CRYP_Init() function - - Encrypt or Decrypt - - mode : TDES-ECB, TDES-CBC, - DES-ECB, DES-CBC, - AES-ECB, AES-CBC, AES-CTR, AES-Key - - DataType : 32-bit data, 16-bit data, bit data or bit-string - - Key Size (only in AES modes) - - Configure the Encrypt or Decrypt Key using CRYP_KeyInit() function - - Configure the Initialization Vectors(IV) for CBC and CTR modes using - CRYP_IVInit() function. - - Flushes the IN and OUT FIFOs : using CRYP_FIFOFlush() function. - - Enable or disable the CRYP Processor using CRYP_Cmd() function - - -@endverbatim - * @{ - */ -/** - * @brief Deinitializes the CRYP peripheral registers to their default reset values - * @param None - * @retval None - */ -void CRYP_DeInit(void) -{ - /* Enable CRYP reset state */ - RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_CRYP, ENABLE); - - /* Release CRYP from reset state */ - RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_CRYP, DISABLE); -} - -/** - * @brief Initializes the CRYP peripheral according to the specified parameters - * in the CRYP_InitStruct. - * @param CRYP_InitStruct: pointer to a CRYP_InitTypeDef structure that contains - * the configuration information for the CRYP peripheral. - * @retval None - */ -void CRYP_Init(CRYP_InitTypeDef* CRYP_InitStruct) -{ - /* Check the parameters */ - assert_param(IS_CRYP_ALGOMODE(CRYP_InitStruct->CRYP_AlgoMode)); - assert_param(IS_CRYP_DATATYPE(CRYP_InitStruct->CRYP_DataType)); - assert_param(IS_CRYP_ALGODIR(CRYP_InitStruct->CRYP_AlgoDir)); - - /* Select Algorithm mode*/ - CRYP->CR &= ~CRYP_CR_ALGOMODE; - CRYP->CR |= CRYP_InitStruct->CRYP_AlgoMode; - - /* Select dataType */ - CRYP->CR &= ~CRYP_CR_DATATYPE; - CRYP->CR |= CRYP_InitStruct->CRYP_DataType; - - /* select Key size (used only with AES algorithm) */ - if ((CRYP_InitStruct->CRYP_AlgoMode == CRYP_AlgoMode_AES_ECB) || - (CRYP_InitStruct->CRYP_AlgoMode == CRYP_AlgoMode_AES_CBC) || - (CRYP_InitStruct->CRYP_AlgoMode == CRYP_AlgoMode_AES_CTR) || - (CRYP_InitStruct->CRYP_AlgoMode == CRYP_AlgoMode_AES_Key)) - { - assert_param(IS_CRYP_KEYSIZE(CRYP_InitStruct->CRYP_KeySize)); - CRYP->CR &= ~CRYP_CR_KEYSIZE; - CRYP->CR |= CRYP_InitStruct->CRYP_KeySize; /* Key size and value must be - configured once the key has - been prepared */ - } - - /* Select data Direction */ - CRYP->CR &= ~CRYP_CR_ALGODIR; - CRYP->CR |= CRYP_InitStruct->CRYP_AlgoDir; -} - -/** - * @brief Fills each CRYP_InitStruct member with its default value. - * @param CRYP_InitStruct: pointer to a CRYP_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void CRYP_StructInit(CRYP_InitTypeDef* CRYP_InitStruct) -{ - /* Initialize the CRYP_AlgoDir member */ - CRYP_InitStruct->CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; - - /* initialize the CRYP_AlgoMode member */ - CRYP_InitStruct->CRYP_AlgoMode = CRYP_AlgoMode_TDES_ECB; - - /* initialize the CRYP_DataType member */ - CRYP_InitStruct->CRYP_DataType = CRYP_DataType_32b; - - /* Initialize the CRYP_KeySize member */ - CRYP_InitStruct->CRYP_KeySize = CRYP_KeySize_128b; -} - -/** - * @brief Initializes the CRYP Keys according to the specified parameters in - * the CRYP_KeyInitStruct. - * @param CRYP_KeyInitStruct: pointer to a CRYP_KeyInitTypeDef structure that - * contains the configuration information for the CRYP Keys. - * @retval None - */ -void CRYP_KeyInit(CRYP_KeyInitTypeDef* CRYP_KeyInitStruct) -{ - /* Key Initialisation */ - CRYP->K0LR = CRYP_KeyInitStruct->CRYP_Key0Left; - CRYP->K0RR = CRYP_KeyInitStruct->CRYP_Key0Right; - CRYP->K1LR = CRYP_KeyInitStruct->CRYP_Key1Left; - CRYP->K1RR = CRYP_KeyInitStruct->CRYP_Key1Right; - CRYP->K2LR = CRYP_KeyInitStruct->CRYP_Key2Left; - CRYP->K2RR = CRYP_KeyInitStruct->CRYP_Key2Right; - CRYP->K3LR = CRYP_KeyInitStruct->CRYP_Key3Left; - CRYP->K3RR = CRYP_KeyInitStruct->CRYP_Key3Right; -} - -/** - * @brief Fills each CRYP_KeyInitStruct member with its default value. - * @param CRYP_KeyInitStruct: pointer to a CRYP_KeyInitTypeDef structure - * which will be initialized. - * @retval None - */ -void CRYP_KeyStructInit(CRYP_KeyInitTypeDef* CRYP_KeyInitStruct) -{ - CRYP_KeyInitStruct->CRYP_Key0Left = 0; - CRYP_KeyInitStruct->CRYP_Key0Right = 0; - CRYP_KeyInitStruct->CRYP_Key1Left = 0; - CRYP_KeyInitStruct->CRYP_Key1Right = 0; - CRYP_KeyInitStruct->CRYP_Key2Left = 0; - CRYP_KeyInitStruct->CRYP_Key2Right = 0; - CRYP_KeyInitStruct->CRYP_Key3Left = 0; - CRYP_KeyInitStruct->CRYP_Key3Right = 0; -} -/** - * @brief Initializes the CRYP Initialization Vectors(IV) according to the - * specified parameters in the CRYP_IVInitStruct. - * @param CRYP_IVInitStruct: pointer to a CRYP_IVInitTypeDef structure that contains - * the configuration information for the CRYP Initialization Vectors(IV). - * @retval None - */ -void CRYP_IVInit(CRYP_IVInitTypeDef* CRYP_IVInitStruct) -{ - CRYP->IV0LR = CRYP_IVInitStruct->CRYP_IV0Left; - CRYP->IV0RR = CRYP_IVInitStruct->CRYP_IV0Right; - CRYP->IV1LR = CRYP_IVInitStruct->CRYP_IV1Left; - CRYP->IV1RR = CRYP_IVInitStruct->CRYP_IV1Right; -} - -/** - * @brief Fills each CRYP_IVInitStruct member with its default value. - * @param CRYP_IVInitStruct: pointer to a CRYP_IVInitTypeDef Initialization - * Vectors(IV) structure which will be initialized. - * @retval None - */ -void CRYP_IVStructInit(CRYP_IVInitTypeDef* CRYP_IVInitStruct) -{ - CRYP_IVInitStruct->CRYP_IV0Left = 0; - CRYP_IVInitStruct->CRYP_IV0Right = 0; - CRYP_IVInitStruct->CRYP_IV1Left = 0; - CRYP_IVInitStruct->CRYP_IV1Right = 0; -} - -/** - * @brief Flushes the IN and OUT FIFOs (that is read and write pointers of the - * FIFOs are reset) - * @note The FIFOs must be flushed only when BUSY flag is reset. - * @param None - * @retval None - */ -void CRYP_FIFOFlush(void) -{ - /* Reset the read and write pointers of the FIFOs */ - CRYP->CR |= CRYP_CR_FFLUSH; -} - -/** - * @brief Enables or disables the CRYP peripheral. - * @param NewState: new state of the CRYP peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void CRYP_Cmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the Cryptographic processor */ - CRYP->CR |= CRYP_CR_CRYPEN; - } - else - { - /* Disable the Cryptographic processor */ - CRYP->CR &= ~CRYP_CR_CRYPEN; - } -} -/** - * @} - */ - -/** @defgroup CRYP_Group2 CRYP Data processing functions - * @brief CRYP Data processing functions - * -@verbatim - =============================================================================== - CRYP Data processing functions - =============================================================================== - This section provides functions allowing the encryption and decryption - operations: - - Enter data to be treated in the IN FIFO : using CRYP_DataIn() function. - - Get the data result from the OUT FIFO : using CRYP_DataOut() function. - -@endverbatim - * @{ - */ - -/** - * @brief Writes data in the Data Input register (DIN). - * @note After the DIN register has been read once or several times, - * the FIFO must be flushed (using CRYP_FIFOFlush() function). - * @param Data: data to write in Data Input register - * @retval None - */ -void CRYP_DataIn(uint32_t Data) -{ - CRYP->DR = Data; -} - -/** - * @brief Returns the last data entered into the output FIFO. - * @param None - * @retval Last data entered into the output FIFO. - */ -uint32_t CRYP_DataOut(void) -{ - return CRYP->DOUT; -} -/** - * @} - */ - -/** @defgroup CRYP_Group3 Context swapping functions - * @brief Context swapping functions - * -@verbatim - =============================================================================== - Context swapping functions - =============================================================================== - - This section provides functions allowing to save and store CRYP Context - - It is possible to interrupt an encryption/ decryption/ key generation process - to perform another processing with a higher priority, and to complete the - interrupted process later on, when the higher-priority task is complete. To do - so, the context of the interrupted task must be saved from the CRYP registers - to memory, and then be restored from memory to the CRYP registers. - - 1. To save the current context, use CRYP_SaveContext() function - 2. To restore the saved context, use CRYP_RestoreContext() function - - -@endverbatim - * @{ - */ - -/** - * @brief Saves the CRYP peripheral Context. - * @note This function stops DMA transfer before to save the context. After - * restoring the context, you have to enable the DMA again (if the DMA - * was previously used). - * @param CRYP_ContextSave: pointer to a CRYP_Context structure that contains - * the repository for current context. - * @param CRYP_KeyInitStruct: pointer to a CRYP_KeyInitTypeDef structure that - * contains the configuration information for the CRYP Keys. - * @retval None - */ -ErrorStatus CRYP_SaveContext(CRYP_Context* CRYP_ContextSave, - CRYP_KeyInitTypeDef* CRYP_KeyInitStruct) -{ - __IO uint32_t timeout = 0; - uint32_t ckeckmask = 0, bitstatus; - ErrorStatus status = ERROR; - - /* Stop DMA transfers on the IN FIFO by clearing the DIEN bit in the CRYP_DMACR */ - CRYP->DMACR &= ~(uint32_t)CRYP_DMACR_DIEN; - - /* Wait until both the IN and OUT FIFOs are empty - (IFEM=1 and OFNE=0 in the CRYP_SR register) and the - BUSY bit is cleared. */ - - if ((CRYP->CR & (uint32_t)(CRYP_CR_ALGOMODE_TDES_ECB | CRYP_CR_ALGOMODE_TDES_CBC)) != (uint32_t)0 )/* TDES */ - { - ckeckmask = CRYP_SR_IFEM | CRYP_SR_BUSY ; - } - else /* AES or DES */ - { - ckeckmask = CRYP_SR_IFEM | CRYP_SR_BUSY | CRYP_SR_OFNE; - } - - do - { - bitstatus = CRYP->SR & ckeckmask; - timeout++; - } - while ((timeout != MAX_TIMEOUT) && (bitstatus != CRYP_SR_IFEM)); - - if ((CRYP->SR & ckeckmask) != CRYP_SR_IFEM) - { - status = ERROR; - } - else - { - /* Stop DMA transfers on the OUT FIFO by - - writing the DOEN bit to 0 in the CRYP_DMACR register - - and clear the CRYPEN bit. */ - - CRYP->DMACR &= ~(uint32_t)CRYP_DMACR_DOEN; - CRYP->CR &= ~(uint32_t)CRYP_CR_CRYPEN; - - /* Save the current configuration (bits [9:2] in the CRYP_CR register) */ - CRYP_ContextSave->CR_bits9to2 = CRYP->CR & (CRYP_CR_KEYSIZE | - CRYP_CR_DATATYPE | - CRYP_CR_ALGOMODE | - CRYP_CR_ALGODIR); - - /* and, if not in ECB mode, the initialization vectors. */ - CRYP_ContextSave->CRYP_IV0LR = CRYP->IV0LR; - CRYP_ContextSave->CRYP_IV0RR = CRYP->IV0RR; - CRYP_ContextSave->CRYP_IV1LR = CRYP->IV1LR; - CRYP_ContextSave->CRYP_IV1RR = CRYP->IV1RR; - - /* save The key value */ - CRYP_ContextSave->CRYP_K0LR = CRYP_KeyInitStruct->CRYP_Key0Left; - CRYP_ContextSave->CRYP_K0RR = CRYP_KeyInitStruct->CRYP_Key0Right; - CRYP_ContextSave->CRYP_K1LR = CRYP_KeyInitStruct->CRYP_Key1Left; - CRYP_ContextSave->CRYP_K1RR = CRYP_KeyInitStruct->CRYP_Key1Right; - CRYP_ContextSave->CRYP_K2LR = CRYP_KeyInitStruct->CRYP_Key2Left; - CRYP_ContextSave->CRYP_K2RR = CRYP_KeyInitStruct->CRYP_Key2Right; - CRYP_ContextSave->CRYP_K3LR = CRYP_KeyInitStruct->CRYP_Key3Left; - CRYP_ContextSave->CRYP_K3RR = CRYP_KeyInitStruct->CRYP_Key3Right; - - /* When needed, save the DMA status (pointers for IN and OUT messages, - number of remaining bytes, etc.) */ - - status = SUCCESS; - } - - return status; -} - -/** - * @brief Restores the CRYP peripheral Context. - * @note Since teh DMA transfer is stopped in CRYP_SaveContext() function, - * after restoring the context, you have to enable the DMA again (if the - * DMA was previously used). - * @param CRYP_ContextRestore: pointer to a CRYP_Context structure that contains - * the repository for saved context. - * @note The data that were saved during context saving must be rewrited into - * the IN FIFO. - * @retval None - */ -void CRYP_RestoreContext(CRYP_Context* CRYP_ContextRestore) -{ - - /* Configure the processor with the saved configuration */ - CRYP->CR = CRYP_ContextRestore->CR_bits9to2; - - /* restore The key value */ - CRYP->K0LR = CRYP_ContextRestore->CRYP_K0LR; - CRYP->K0RR = CRYP_ContextRestore->CRYP_K0RR; - CRYP->K1LR = CRYP_ContextRestore->CRYP_K1LR; - CRYP->K1RR = CRYP_ContextRestore->CRYP_K1RR; - CRYP->K2LR = CRYP_ContextRestore->CRYP_K2LR; - CRYP->K2RR = CRYP_ContextRestore->CRYP_K2RR; - CRYP->K3LR = CRYP_ContextRestore->CRYP_K3LR; - CRYP->K3RR = CRYP_ContextRestore->CRYP_K3RR; - - /* and the initialization vectors. */ - CRYP->IV0LR = CRYP_ContextRestore->CRYP_IV0LR; - CRYP->IV0RR = CRYP_ContextRestore->CRYP_IV0RR; - CRYP->IV1LR = CRYP_ContextRestore->CRYP_IV1LR; - CRYP->IV1RR = CRYP_ContextRestore->CRYP_IV1RR; - - /* Enable the cryptographic processor */ - CRYP->CR |= CRYP_CR_CRYPEN; -} -/** - * @} - */ - -/** @defgroup CRYP_Group4 CRYP's DMA interface Configuration function - * @brief CRYP's DMA interface Configuration function - * -@verbatim - =============================================================================== - CRYP's DMA interface Configuration function - =============================================================================== - - This section provides functions allowing to configure the DMA interface for - CRYP data input and output transfer. - - When the DMA mode is enabled (using the CRYP_DMACmd() function), data can be - transferred: - - From memory to the CRYP IN FIFO using the DMA peripheral by enabling - the CRYP_DMAReq_DataIN request. - - From the CRYP OUT FIFO to the memory using the DMA peripheral by enabling - the CRYP_DMAReq_DataOUT request. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the CRYP DMA interface. - * @param CRYP_DMAReq: specifies the CRYP DMA transfer request to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg CRYP_DMAReq_DataOUT: DMA for outgoing(Tx) data transfer - * @arg CRYP_DMAReq_DataIN: DMA for incoming(Rx) data transfer - * @param NewState: new state of the selected CRYP DMA transfer request. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void CRYP_DMACmd(uint8_t CRYP_DMAReq, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_CRYP_DMAREQ(CRYP_DMAReq)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected CRYP DMA request */ - CRYP->DMACR |= CRYP_DMAReq; - } - else - { - /* Disable the selected CRYP DMA request */ - CRYP->DMACR &= (uint8_t)~CRYP_DMAReq; - } -} -/** - * @} - */ - -/** @defgroup CRYP_Group5 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - - This section provides functions allowing to configure the CRYP Interrupts and - to get the status and Interrupts pending bits. - - The CRYP provides 2 Interrupts sources and 7 Flags: - - Flags : - ------- - - 1. CRYP_FLAG_IFEM : Set when Input FIFO is empty. - This Flag is cleared only by hardware. - - 2. CRYP_FLAG_IFNF : Set when Input FIFO is not full. - This Flag is cleared only by hardware. - - - 3. CRYP_FLAG_INRIS : Set when Input FIFO Raw interrupt is pending - it gives the raw interrupt state prior to masking - of the input FIFO service interrupt. - This Flag is cleared only by hardware. - - 4. CRYP_FLAG_OFNE : Set when Output FIFO not empty. - This Flag is cleared only by hardware. - - 5. CRYP_FLAG_OFFU : Set when Output FIFO is full. - This Flag is cleared only by hardware. - - 6. CRYP_FLAG_OUTRIS : Set when Output FIFO Raw interrupt is pending - it gives the raw interrupt state prior to masking - of the output FIFO service interrupt. - This Flag is cleared only by hardware. - - 7. CRYP_FLAG_BUSY : Set when the CRYP core is currently processing a - block of data or a key preparation (for AES - decryption). - This Flag is cleared only by hardware. - To clear it, the CRYP core must be disabled and the - last processing has completed. - - Interrupts : - ------------ - - 1. CRYP_IT_INI : The input FIFO service interrupt is asserted when there - are less than 4 words in the input FIFO. - This interrupt is associated to CRYP_FLAG_INRIS flag. - - @note This interrupt is cleared by performing write operations - to the input FIFO until it holds 4 or more words. The - input FIFO service interrupt INMIS is enabled with the - CRYP enable bit. Consequently, when CRYP is disabled, the - INMIS signal is low even if the input FIFO is empty. - - - - 2. CRYP_IT_OUTI : The output FIFO service interrupt is asserted when there - is one or more (32-bit word) data items in the output FIFO. - This interrupt is associated to CRYP_FLAG_OUTRIS flag. - - @note This interrupt is cleared by reading data from the output - FIFO until there is no valid (32-bit) word left (that is, - the interrupt follows the state of the OFNE (output FIFO - not empty) flag). - - - Managing the CRYP controller events : - ------------------------------------ - The user should identify which mode will be used in his application to manage - the CRYP controller events: Polling mode or Interrupt mode. - - 1. In the Polling Mode it is advised to use the following functions: - - CRYP_GetFlagStatus() : to check if flags events occur. - - @note The CRYPT flags do not need to be cleared since they are cleared as - soon as the associated event are reset. - - - 2. In the Interrupt Mode it is advised to use the following functions: - - CRYP_ITConfig() : to enable or disable the interrupt source. - - CRYP_GetITStatus() : to check if Interrupt occurs. - - @note The CRYPT interrupts have no pending bits, the interrupt is cleared as - soon as the associated event is reset. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified CRYP interrupts. - * @param CRYP_IT: specifies the CRYP interrupt source to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg CRYP_IT_INI: Input FIFO interrupt - * @arg CRYP_IT_OUTI: Output FIFO interrupt - * @param NewState: new state of the specified CRYP interrupt. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void CRYP_ITConfig(uint8_t CRYP_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_CRYP_CONFIG_IT(CRYP_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected CRYP interrupt */ - CRYP->IMSCR |= CRYP_IT; - } - else - { - /* Disable the selected CRYP interrupt */ - CRYP->IMSCR &= (uint8_t)~CRYP_IT; - } -} - -/** - * @brief Checks whether the specified CRYP interrupt has occurred or not. - * @note This function checks the status of the masked interrupt (i.e the - * interrupt should be previously enabled). - * @param CRYP_IT: specifies the CRYP (masked) interrupt source to check. - * This parameter can be one of the following values: - * @arg CRYP_IT_INI: Input FIFO interrupt - * @arg CRYP_IT_OUTI: Output FIFO interrupt - * @retval The new state of CRYP_IT (SET or RESET). - */ -ITStatus CRYP_GetITStatus(uint8_t CRYP_IT) -{ - ITStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_CRYP_GET_IT(CRYP_IT)); - - /* Check the status of the specified CRYP interrupt */ - if ((CRYP->MISR & CRYP_IT) != (uint8_t)RESET) - { - /* CRYP_IT is set */ - bitstatus = SET; - } - else - { - /* CRYP_IT is reset */ - bitstatus = RESET; - } - /* Return the CRYP_IT status */ - return bitstatus; -} - -/** - * @brief Checks whether the specified CRYP flag is set or not. - * @param CRYP_FLAG: specifies the CRYP flag to check. - * This parameter can be one of the following values: - * @arg CRYP_FLAG_IFEM: Input FIFO Empty flag. - * @arg CRYP_FLAG_IFNF: Input FIFO Not Full flag. - * @arg CRYP_FLAG_OFNE: Output FIFO Not Empty flag. - * @arg CRYP_FLAG_OFFU: Output FIFO Full flag. - * @arg CRYP_FLAG_BUSY: Busy flag. - * @arg CRYP_FLAG_OUTRIS: Output FIFO raw interrupt flag. - * @arg CRYP_FLAG_INRIS: Input FIFO raw interrupt flag. - * @retval The new state of CRYP_FLAG (SET or RESET). - */ -FlagStatus CRYP_GetFlagStatus(uint8_t CRYP_FLAG) -{ - FlagStatus bitstatus = RESET; - uint32_t tempreg = 0; - - /* Check the parameters */ - assert_param(IS_CRYP_GET_FLAG(CRYP_FLAG)); - - /* check if the FLAG is in RISR register */ - if ((CRYP_FLAG & FLAG_MASK) != 0x00) - { - tempreg = CRYP->RISR; - } - else /* The FLAG is in SR register */ - { - tempreg = CRYP->SR; - } - - - /* Check the status of the specified CRYP flag */ - if ((tempreg & CRYP_FLAG ) != (uint8_t)RESET) - { - /* CRYP_FLAG is set */ - bitstatus = SET; - } - else - { - /* CRYP_FLAG is reset */ - bitstatus = RESET; - } - - /* Return the CRYP_FLAG status */ - return bitstatus; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp_aes.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp_aes.c deleted file mode 100644 index 00b9fe175..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_cryp_aes.c +++ /dev/null @@ -1,638 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_cryp_aes.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides high level functions to encrypt and decrypt an - * input message using AES in ECB/CBC/CTR modes. - * It uses the stm32f4xx_cryp.c/.h drivers to access the STM32F4xx CRYP - * peripheral. - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable The CRYP controller clock using - * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, ENABLE); function. - * - * 2. Encrypt and decrypt using AES in ECB Mode using CRYP_AES_ECB() - * function. - * - * 3. Encrypt and decrypt using AES in CBC Mode using CRYP_AES_CBC() - * function. - * - * 4. Encrypt and decrypt using AES in CTR Mode using CRYP_AES_CTR() - * function. - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_cryp.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup CRYP - * @brief CRYP driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define AESBUSY_TIMEOUT ((uint32_t) 0x00010000) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup CRYP_Private_Functions - * @{ - */ - -/** @defgroup CRYP_Group6 High Level AES functions - * @brief High Level AES functions - * -@verbatim - =============================================================================== - High Level AES functions - =============================================================================== - - -@endverbatim - * @{ - */ - -/** - * @brief Encrypt and decrypt using AES in ECB Mode - * @param Mode: encryption or decryption Mode. - * This parameter can be one of the following values: - * @arg MODE_ENCRYPT: Encryption - * @arg MODE_DECRYPT: Decryption - * @param Key: Key used for AES algorithm. - * @param Keysize: length of the Key, must be a 128, 192 or 256. - * @param Input: pointer to the Input buffer. - * @param Ilength: length of the Input buffer, must be a multiple of 16. - * @param Output: pointer to the returned buffer. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: Operation done - * - ERROR: Operation failed - */ -ErrorStatus CRYP_AES_ECB(uint8_t Mode, uint8_t* Key, uint16_t Keysize, - uint8_t* Input, uint32_t Ilength, uint8_t* Output) -{ - CRYP_InitTypeDef AES_CRYP_InitStructure; - CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure; - __IO uint32_t counter = 0; - uint32_t busystatus = 0; - ErrorStatus status = SUCCESS; - uint32_t keyaddr = (uint32_t)Key; - uint32_t inputaddr = (uint32_t)Input; - uint32_t outputaddr = (uint32_t)Output; - uint32_t i = 0; - - /* Crypto structures initialisation*/ - CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure); - - switch(Keysize) - { - case 128: - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr)); - break; - case 192: - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b; - AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr)); - break; - case 256: - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b; - AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr)); - break; - default: - break; - } - - /*------------------ AES Decryption ------------------*/ - if(Mode == MODE_DECRYPT) /* AES decryption */ - { - /* Flush IN/OUT FIFOs */ - CRYP_FIFOFlush(); - - /* Crypto Init for Key preparation for decryption process */ - AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt; - AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key; - AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b; - CRYP_Init(&AES_CRYP_InitStructure); - - /* Key Initialisation */ - CRYP_KeyInit(&AES_CRYP_KeyInitStructure); - - /* Enable Crypto processor */ - CRYP_Cmd(ENABLE); - - /* wait until the Busy flag is RESET */ - do - { - busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY); - counter++; - }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET)); - - if (busystatus != RESET) - { - status = ERROR; - } - else - { - /* Crypto Init for decryption process */ - AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt; - } - } - /*------------------ AES Encryption ------------------*/ - else /* AES encryption */ - { - - CRYP_KeyInit(&AES_CRYP_KeyInitStructure); - - /* Crypto Init for Encryption process */ - AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; - } - - AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB; - AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; - CRYP_Init(&AES_CRYP_InitStructure); - - /* Flush IN/OUT FIFOs */ - CRYP_FIFOFlush(); - - /* Enable Crypto processor */ - CRYP_Cmd(ENABLE); - - for(i=0; ((i
© COPYRIGHT 2011 STMicroelectronics
- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_cryp.h" - - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup CRYP - * @brief CRYP driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define DESBUSY_TIMEOUT ((uint32_t) 0x00010000) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - - -/** @defgroup CRYP_Private_Functions - * @{ - */ - -/** @defgroup CRYP_Group8 High Level DES functions - * @brief High Level DES functions - * -@verbatim - =============================================================================== - High Level DES functions - =============================================================================== -@endverbatim - * @{ - */ - -/** - * @brief Encrypt and decrypt using DES in ECB Mode - * @param Mode: encryption or decryption Mode. - * This parameter can be one of the following values: - * @arg MODE_ENCRYPT: Encryption - * @arg MODE_DECRYPT: Decryption - * @param Key: Key used for DES algorithm. - * @param Ilength: length of the Input buffer, must be a multiple of 8. - * @param Input: pointer to the Input buffer. - * @param Output: pointer to the returned buffer. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: Operation done - * - ERROR: Operation failed - */ -ErrorStatus CRYP_DES_ECB(uint8_t Mode, uint8_t Key[8], uint8_t *Input, - uint32_t Ilength, uint8_t *Output) -{ - CRYP_InitTypeDef DES_CRYP_InitStructure; - CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure; - __IO uint32_t counter = 0; - uint32_t busystatus = 0; - ErrorStatus status = SUCCESS; - uint32_t keyaddr = (uint32_t)Key; - uint32_t inputaddr = (uint32_t)Input; - uint32_t outputaddr = (uint32_t)Output; - uint32_t i = 0; - - /* Crypto structures initialisation*/ - CRYP_KeyStructInit(&DES_CRYP_KeyInitStructure); - - /* Crypto Init for Encryption process */ - if( Mode == MODE_ENCRYPT ) /* DES encryption */ - { - DES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; - } - else/* if( Mode == MODE_DECRYPT )*/ /* DES decryption */ - { - DES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt; - } - - DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_ECB; - DES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; - CRYP_Init(&DES_CRYP_InitStructure); - - /* Key Initialisation */ - DES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - DES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr)); - CRYP_KeyInit(& DES_CRYP_KeyInitStructure); - - /* Flush IN/OUT FIFO */ - CRYP_FIFOFlush(); - - /* Enable Crypto processor */ - CRYP_Cmd(ENABLE); - - for(i=0; ((i
© COPYRIGHT 2011 STMicroelectronics
- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_cryp.h" - - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup CRYP - * @brief CRYP driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define TDESBUSY_TIMEOUT ((uint32_t) 0x00010000) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - - -/** @defgroup CRYP_Private_Functions - * @{ - */ - -/** @defgroup CRYP_Group7 High Level TDES functions - * @brief High Level TDES functions - * -@verbatim - =============================================================================== - High Level TDES functions - =============================================================================== - - -@endverbatim - * @{ - */ - -/** - * @brief Encrypt and decrypt using TDES in ECB Mode - * @param Mode: encryption or decryption Mode. - * This parameter can be one of the following values: - * @arg MODE_ENCRYPT: Encryption - * @arg MODE_DECRYPT: Decryption - * @param Key: Key used for TDES algorithm. - * @param Ilength: length of the Input buffer, must be a multiple of 8. - * @param Input: pointer to the Input buffer. - * @param Output: pointer to the returned buffer. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: Operation done - * - ERROR: Operation failed - */ -ErrorStatus CRYP_TDES_ECB(uint8_t Mode, uint8_t Key[24], uint8_t *Input, - uint32_t Ilength, uint8_t *Output) -{ - CRYP_InitTypeDef TDES_CRYP_InitStructure; - CRYP_KeyInitTypeDef TDES_CRYP_KeyInitStructure; - __IO uint32_t counter = 0; - uint32_t busystatus = 0; - ErrorStatus status = SUCCESS; - uint32_t keyaddr = (uint32_t)Key; - uint32_t inputaddr = (uint32_t)Input; - uint32_t outputaddr = (uint32_t)Output; - uint32_t i = 0; - - /* Crypto structures initialisation*/ - CRYP_KeyStructInit(&TDES_CRYP_KeyInitStructure); - - /* Crypto Init for Encryption process */ - if(Mode == MODE_ENCRYPT) /* TDES encryption */ - { - TDES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; - } - else /*if(Mode == MODE_DECRYPT)*/ /* TDES decryption */ - { - TDES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt; - } - - TDES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_TDES_ECB; - TDES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; - CRYP_Init(&TDES_CRYP_InitStructure); - - /* Key Initialisation */ - TDES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - TDES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - TDES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - TDES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - TDES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr)); - keyaddr+=4; - TDES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr)); - CRYP_KeyInit(& TDES_CRYP_KeyInitStructure); - - /* Flush IN/OUT FIFO */ - CRYP_FIFOFlush(); - - /* Enable Crypto processor */ - CRYP_Cmd(ENABLE); - - for(i=0; ((i
© COPYRIGHT 2011 STMicroelectronics
- ****************************************************************************** - */ - - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_dac.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup DAC - * @brief DAC driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* CR register Mask */ -#define CR_CLEAR_MASK ((uint32_t)0x00000FFE) - -/* DAC Dual Channels SWTRIG masks */ -#define DUAL_SWTRIG_SET ((uint32_t)0x00000003) -#define DUAL_SWTRIG_RESET ((uint32_t)0xFFFFFFFC) - -/* DHR registers offsets */ -#define DHR12R1_OFFSET ((uint32_t)0x00000008) -#define DHR12R2_OFFSET ((uint32_t)0x00000014) -#define DHR12RD_OFFSET ((uint32_t)0x00000020) - -/* DOR register offset */ -#define DOR_OFFSET ((uint32_t)0x0000002C) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup DAC_Private_Functions - * @{ - */ - -/** @defgroup DAC_Group1 DAC channels configuration - * @brief DAC channels configuration: trigger, output buffer, data format - * -@verbatim - =============================================================================== - DAC channels configuration: trigger, output buffer, data format - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the DAC peripheral registers to their default reset values. - * @param None - * @retval None - */ -void DAC_DeInit(void) -{ - /* Enable DAC reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, ENABLE); - /* Release DAC from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, DISABLE); -} - -/** - * @brief Initializes the DAC peripheral according to the specified parameters - * in the DAC_InitStruct. - * @param DAC_Channel: the selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure that contains - * the configuration information for the specified DAC channel. - * @retval None - */ -void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct) -{ - uint32_t tmpreg1 = 0, tmpreg2 = 0; - - /* Check the DAC parameters */ - assert_param(IS_DAC_TRIGGER(DAC_InitStruct->DAC_Trigger)); - assert_param(IS_DAC_GENERATE_WAVE(DAC_InitStruct->DAC_WaveGeneration)); - assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude)); - assert_param(IS_DAC_OUTPUT_BUFFER_STATE(DAC_InitStruct->DAC_OutputBuffer)); - -/*---------------------------- DAC CR Configuration --------------------------*/ - /* Get the DAC CR value */ - tmpreg1 = DAC->CR; - /* Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits */ - tmpreg1 &= ~(CR_CLEAR_MASK << DAC_Channel); - /* Configure for the selected DAC channel: buffer output, trigger, - wave generation, mask/amplitude for wave generation */ - /* Set TSELx and TENx bits according to DAC_Trigger value */ - /* Set WAVEx bits according to DAC_WaveGeneration value */ - /* Set MAMPx bits according to DAC_LFSRUnmask_TriangleAmplitude value */ - /* Set BOFFx bit according to DAC_OutputBuffer value */ - tmpreg2 = (DAC_InitStruct->DAC_Trigger | DAC_InitStruct->DAC_WaveGeneration | - DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude | \ - DAC_InitStruct->DAC_OutputBuffer); - /* Calculate CR register value depending on DAC_Channel */ - tmpreg1 |= tmpreg2 << DAC_Channel; - /* Write to DAC CR */ - DAC->CR = tmpreg1; -} - -/** - * @brief Fills each DAC_InitStruct member with its default value. - * @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct) -{ -/*--------------- Reset DAC init structure parameters values -----------------*/ - /* Initialize the DAC_Trigger member */ - DAC_InitStruct->DAC_Trigger = DAC_Trigger_None; - /* Initialize the DAC_WaveGeneration member */ - DAC_InitStruct->DAC_WaveGeneration = DAC_WaveGeneration_None; - /* Initialize the DAC_LFSRUnmask_TriangleAmplitude member */ - DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; - /* Initialize the DAC_OutputBuffer member */ - DAC_InitStruct->DAC_OutputBuffer = DAC_OutputBuffer_Enable; -} - -/** - * @brief Enables or disables the specified DAC channel. - * @param DAC_Channel: The selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param NewState: new state of the DAC channel. - * This parameter can be: ENABLE or DISABLE. - * @note When the DAC channel is enabled the trigger source can no more be modified. - * @retval None - */ -void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected DAC channel */ - DAC->CR |= (DAC_CR_EN1 << DAC_Channel); - } - else - { - /* Disable the selected DAC channel */ - DAC->CR &= (~(DAC_CR_EN1 << DAC_Channel)); - } -} - -/** - * @brief Enables or disables the selected DAC channel software trigger. - * @param DAC_Channel: The selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param NewState: new state of the selected DAC channel software trigger. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable software trigger for the selected DAC channel */ - DAC->SWTRIGR |= (uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4); - } - else - { - /* Disable software trigger for the selected DAC channel */ - DAC->SWTRIGR &= ~((uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4)); - } -} - -/** - * @brief Enables or disables simultaneously the two DAC channels software triggers. - * @param NewState: new state of the DAC channels software triggers. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DAC_DualSoftwareTriggerCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable software trigger for both DAC channels */ - DAC->SWTRIGR |= DUAL_SWTRIG_SET; - } - else - { - /* Disable software trigger for both DAC channels */ - DAC->SWTRIGR &= DUAL_SWTRIG_RESET; - } -} - -/** - * @brief Enables or disables the selected DAC channel wave generation. - * @param DAC_Channel: The selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_Wave: specifies the wave type to enable or disable. - * This parameter can be one of the following values: - * @arg DAC_Wave_Noise: noise wave generation - * @arg DAC_Wave_Triangle: triangle wave generation - * @param NewState: new state of the selected DAC channel wave generation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_WAVE(DAC_Wave)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected wave generation for the selected DAC channel */ - DAC->CR |= DAC_Wave << DAC_Channel; - } - else - { - /* Disable the selected wave generation for the selected DAC channel */ - DAC->CR &= ~(DAC_Wave << DAC_Channel); - } -} - -/** - * @brief Set the specified data holding register value for DAC channel1. - * @param DAC_Align: Specifies the data alignment for DAC channel1. - * This parameter can be one of the following values: - * @arg DAC_Align_8b_R: 8bit right data alignment selected - * @arg DAC_Align_12b_L: 12bit left data alignment selected - * @arg DAC_Align_12b_R: 12bit right data alignment selected - * @param Data: Data to be loaded in the selected data holding register. - * @retval None - */ -void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_DAC_ALIGN(DAC_Align)); - assert_param(IS_DAC_DATA(Data)); - - tmp = (uint32_t)DAC_BASE; - tmp += DHR12R1_OFFSET + DAC_Align; - - /* Set the DAC channel1 selected data holding register */ - *(__IO uint32_t *) tmp = Data; -} - -/** - * @brief Set the specified data holding register value for DAC channel2. - * @param DAC_Align: Specifies the data alignment for DAC channel2. - * This parameter can be one of the following values: - * @arg DAC_Align_8b_R: 8bit right data alignment selected - * @arg DAC_Align_12b_L: 12bit left data alignment selected - * @arg DAC_Align_12b_R: 12bit right data alignment selected - * @param Data: Data to be loaded in the selected data holding register. - * @retval None - */ -void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_DAC_ALIGN(DAC_Align)); - assert_param(IS_DAC_DATA(Data)); - - tmp = (uint32_t)DAC_BASE; - tmp += DHR12R2_OFFSET + DAC_Align; - - /* Set the DAC channel2 selected data holding register */ - *(__IO uint32_t *)tmp = Data; -} - -/** - * @brief Set the specified data holding register value for dual channel DAC. - * @param DAC_Align: Specifies the data alignment for dual channel DAC. - * This parameter can be one of the following values: - * @arg DAC_Align_8b_R: 8bit right data alignment selected - * @arg DAC_Align_12b_L: 12bit left data alignment selected - * @arg DAC_Align_12b_R: 12bit right data alignment selected - * @param Data2: Data for DAC Channel2 to be loaded in the selected data holding register. - * @param Data1: Data for DAC Channel1 to be loaded in the selected data holding register. - * @note In dual mode, a unique register access is required to write in both - * DAC channels at the same time. - * @retval None - */ -void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1) -{ - uint32_t data = 0, tmp = 0; - - /* Check the parameters */ - assert_param(IS_DAC_ALIGN(DAC_Align)); - assert_param(IS_DAC_DATA(Data1)); - assert_param(IS_DAC_DATA(Data2)); - - /* Calculate and set dual DAC data holding register value */ - if (DAC_Align == DAC_Align_8b_R) - { - data = ((uint32_t)Data2 << 8) | Data1; - } - else - { - data = ((uint32_t)Data2 << 16) | Data1; - } - - tmp = (uint32_t)DAC_BASE; - tmp += DHR12RD_OFFSET + DAC_Align; - - /* Set the dual DAC selected data holding register */ - *(__IO uint32_t *)tmp = data; -} - -/** - * @brief Returns the last data output value of the selected DAC channel. - * @param DAC_Channel: The selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @retval The selected DAC channel data output value. - */ -uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - - tmp = (uint32_t) DAC_BASE ; - tmp += DOR_OFFSET + ((uint32_t)DAC_Channel >> 2); - - /* Returns the DAC channel data output register value */ - return (uint16_t) (*(__IO uint32_t*) tmp); -} -/** - * @} - */ - -/** @defgroup DAC_Group2 DMA management functions - * @brief DMA management functions - * -@verbatim - =============================================================================== - DMA management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified DAC channel DMA request. - * @note When enabled DMA1 is generated when an external trigger (EXTI Line9, - * TIM2, TIM4, TIM5, TIM6, TIM7 or TIM8 but not a software trigger) occurs. - * @param DAC_Channel: The selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param NewState: new state of the selected DAC channel DMA request. - * This parameter can be: ENABLE or DISABLE. - * @note The DAC channel1 is mapped on DMA1 Stream 5 channel7 which must be - * already configured. - * @note The DAC channel2 is mapped on DMA1 Stream 6 channel7 which must be - * already configured. - * @retval None - */ -void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected DAC channel DMA request */ - DAC->CR |= (DAC_CR_DMAEN1 << DAC_Channel); - } - else - { - /* Disable the selected DAC channel DMA request */ - DAC->CR &= (~(DAC_CR_DMAEN1 << DAC_Channel)); - } -} -/** - * @} - */ - -/** @defgroup DAC_Group3 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified DAC interrupts. - * @param DAC_Channel: The selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_IT: specifies the DAC interrupt sources to be enabled or disabled. - * This parameter can be the following values: - * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask - * @note The DMA underrun occurs when a second external trigger arrives before the - * acknowledgement for the first external trigger is received (first request). - * @param NewState: new state of the specified DAC interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_DAC_IT(DAC_IT)); - - if (NewState != DISABLE) - { - /* Enable the selected DAC interrupts */ - DAC->CR |= (DAC_IT << DAC_Channel); - } - else - { - /* Disable the selected DAC interrupts */ - DAC->CR &= (~(uint32_t)(DAC_IT << DAC_Channel)); - } -} - -/** - * @brief Checks whether the specified DAC flag is set or not. - * @param DAC_Channel: The selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_FLAG: specifies the flag to check. - * This parameter can be only of the following value: - * @arg DAC_FLAG_DMAUDR: DMA underrun flag - * @note The DMA underrun occurs when a second external trigger arrives before the - * acknowledgement for the first external trigger is received (first request). - * @retval The new state of DAC_FLAG (SET or RESET). - */ -FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_FLAG(DAC_FLAG)); - - /* Check the status of the specified DAC flag */ - if ((DAC->SR & (DAC_FLAG << DAC_Channel)) != (uint8_t)RESET) - { - /* DAC_FLAG is set */ - bitstatus = SET; - } - else - { - /* DAC_FLAG is reset */ - bitstatus = RESET; - } - /* Return the DAC_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the DAC channel's pending flags. - * @param DAC_Channel: The selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_FLAG: specifies the flag to clear. - * This parameter can be of the following value: - * @arg DAC_FLAG_DMAUDR: DMA underrun flag - * @note The DMA underrun occurs when a second external trigger arrives before the - * acknowledgement for the first external trigger is received (first request). - * @retval None - */ -void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_FLAG(DAC_FLAG)); - - /* Clear the selected DAC flags */ - DAC->SR = (DAC_FLAG << DAC_Channel); -} - -/** - * @brief Checks whether the specified DAC interrupt has occurred or not. - * @param DAC_Channel: The selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_IT: specifies the DAC interrupt source to check. - * This parameter can be the following values: - * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask - * @note The DMA underrun occurs when a second external trigger arrives before the - * acknowledgement for the first external trigger is received (first request). - * @retval The new state of DAC_IT (SET or RESET). - */ -ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT) -{ - ITStatus bitstatus = RESET; - uint32_t enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_IT(DAC_IT)); - - /* Get the DAC_IT enable bit status */ - enablestatus = (DAC->CR & (DAC_IT << DAC_Channel)) ; - - /* Check the status of the specified DAC interrupt */ - if (((DAC->SR & (DAC_IT << DAC_Channel)) != (uint32_t)RESET) && enablestatus) - { - /* DAC_IT is set */ - bitstatus = SET; - } - else - { - /* DAC_IT is reset */ - bitstatus = RESET; - } - /* Return the DAC_IT status */ - return bitstatus; -} - -/** - * @brief Clears the DAC channel's interrupt pending bits. - * @param DAC_Channel: The selected DAC channel. - * This parameter can be one of the following values: - * @arg DAC_Channel_1: DAC Channel1 selected - * @arg DAC_Channel_2: DAC Channel2 selected - * @param DAC_IT: specifies the DAC interrupt pending bit to clear. - * This parameter can be the following values: - * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask - * @note The DMA underrun occurs when a second external trigger arrives before the - * acknowledgement for the first external trigger is received (first request). - * @retval None - */ -void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT) -{ - /* Check the parameters */ - assert_param(IS_DAC_CHANNEL(DAC_Channel)); - assert_param(IS_DAC_IT(DAC_IT)); - - /* Clear the selected DAC interrupt pending bits */ - DAC->SR = (DAC_IT << DAC_Channel); -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dbgmcu.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dbgmcu.c deleted file mode 100644 index a89e1de3a..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dbgmcu.c +++ /dev/null @@ -1,174 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_dbgmcu.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides all the DBGMCU firmware functions. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_dbgmcu.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup DBGMCU - * @brief DBGMCU driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup DBGMCU_Private_Functions - * @{ - */ - -/** - * @brief Returns the device revision identifier. - * @param None - * @retval Device revision identifier - */ -uint32_t DBGMCU_GetREVID(void) -{ - return(DBGMCU->IDCODE >> 16); -} - -/** - * @brief Returns the device identifier. - * @param None - * @retval Device identifier - */ -uint32_t DBGMCU_GetDEVID(void) -{ - return(DBGMCU->IDCODE & IDCODE_DEVID_MASK); -} - -/** - * @brief Configures low power mode behavior when the MCU is in Debug mode. - * @param DBGMCU_Periph: specifies the low power mode. - * This parameter can be any combination of the following values: - * @arg DBGMCU_SLEEP: Keep debugger connection during SLEEP mode - * @arg DBGMCU_STOP: Keep debugger connection during STOP mode - * @arg DBGMCU_STANDBY: Keep debugger connection during STANDBY mode - * @param NewState: new state of the specified low power mode in Debug mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DBGMCU_PERIPH(DBGMCU_Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - DBGMCU->CR |= DBGMCU_Periph; - } - else - { - DBGMCU->CR &= ~DBGMCU_Periph; - } -} - -/** - * @brief Configures APB1 peripheral behavior when the MCU is in Debug mode. - * @param DBGMCU_Periph: specifies the APB1 peripheral. - * This parameter can be any combination of the following values: - * @arg DBGMCU_TIM2_STOP: TIM2 counter stopped when Core is halted - * @arg DBGMCU_TIM3_STOP: TIM3 counter stopped when Core is halted - * @arg DBGMCU_TIM4_STOP: TIM4 counter stopped when Core is halted - * @arg DBGMCU_TIM5_STOP: TIM5 counter stopped when Core is halted - * @arg DBGMCU_TIM6_STOP: TIM6 counter stopped when Core is halted - * @arg DBGMCU_TIM7_STOP: TIM7 counter stopped when Core is halted - * @arg DBGMCU_TIM12_STOP: TIM12 counter stopped when Core is halted - * @arg DBGMCU_TIM13_STOP: TIM13 counter stopped when Core is halted - * @arg DBGMCU_TIM14_STOP: TIM14 counter stopped when Core is halted - * @arg DBGMCU_RTC_STOP: RTC Calendar and Wakeup counter stopped when Core is halted. - * @arg DBGMCU_WWDG_STOP: Debug WWDG stopped when Core is halted - * @arg DBGMCU_IWDG_STOP: Debug IWDG stopped when Core is halted - * @arg DBGMCU_I2C1_SMBUS_TIMEOUT: I2C1 SMBUS timeout mode stopped when Core is halted - * @arg DBGMCU_I2C2_SMBUS_TIMEOUT: I2C2 SMBUS timeout mode stopped when Core is halted - * @arg DBGMCU_I2C3_SMBUS_TIMEOUT: I2C3 SMBUS timeout mode stopped when Core is halted - * @arg DBGMCU_CAN2_STOP: Debug CAN1 stopped when Core is halted - * @arg DBGMCU_CAN1_STOP: Debug CAN2 stopped when Core is halted - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DBGMCU_APB1PERIPH(DBGMCU_Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - DBGMCU->APB1FZ |= DBGMCU_Periph; - } - else - { - DBGMCU->APB1FZ &= ~DBGMCU_Periph; - } -} - -/** - * @brief Configures APB2 peripheral behavior when the MCU is in Debug mode. - * @param DBGMCU_Periph: specifies the APB2 peripheral. - * This parameter can be any combination of the following values: - * @arg DBGMCU_TIM1_STOP: TIM1 counter stopped when Core is halted - * @arg DBGMCU_TIM8_STOP: TIM8 counter stopped when Core is halted - * @arg DBGMCU_TIM9_STOP: TIM9 counter stopped when Core is halted - * @arg DBGMCU_TIM10_STOP: TIM10 counter stopped when Core is halted - * @arg DBGMCU_TIM11_STOP: TIM11 counter stopped when Core is halted - * @param NewState: new state of the specified peripheral in Debug mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DBGMCU_APB2PERIPH(DBGMCU_Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - DBGMCU->APB2FZ |= DBGMCU_Periph; - } - else - { - DBGMCU->APB2FZ &= ~DBGMCU_Periph; - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dcmi.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dcmi.c deleted file mode 100644 index 5e76501c6..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dcmi.c +++ /dev/null @@ -1,534 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_dcmi.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the DCMI peripheral: - * - Initialization and Configuration - * - Image capture functions - * - Interrupts and flags management - * - * @verbatim - * - * - * =================================================================== - * How to use this driver - * =================================================================== - * - * The sequence below describes how to use this driver to capture image - * from a camera module connected to the DCMI Interface. - * This sequence does not take into account the configuration of the - * camera module, which should be made before to configure and enable - * the DCMI to capture images. - * - * 1. Enable the clock for the DCMI and associated GPIOs using the following functions: - * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE); - * RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); - * - * 2. DCMI pins configuration - * - Connect the involved DCMI pins to AF13 using the following function - * GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_DCMI); - * - Configure these DCMI pins in alternate function mode by calling the function - * GPIO_Init(); - * - * 3. Declare a DCMI_InitTypeDef structure, for example: - * DCMI_InitTypeDef DCMI_InitStructure; - * and fill the DCMI_InitStructure variable with the allowed values - * of the structure member. - * - * 4. Initialize the DCMI interface by calling the function - * DCMI_Init(&DCMI_InitStructure); - * - * 5. Configure the DMA2_Stream1 channel1 to transfer Data from DCMI DR - * register to the destination memory buffer. - * - * 6. Enable DCMI interface using the function - * DCMI_Cmd(ENABLE); - * - * 7. Start the image capture using the function - * DCMI_CaptureCmd(ENABLE); - * - * 8. At this stage the DCMI interface waits for the first start of frame, - * then a DMA request is generated continuously/once (depending on the - * mode used, Continuous/Snapshot) to transfer the received data into - * the destination memory. - * - * @note If you need to capture only a rectangular window from the received - * image, you have to use the DCMI_CROPConfig() function to configure - * the coordinates and size of the window to be captured, then enable - * the Crop feature using DCMI_CROPCmd(ENABLE); - * In this case, the Crop configuration should be made before to enable - * and start the DCMI interface. - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_dcmi.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup DCMI - * @brief DCMI driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup DCMI_Private_Functions - * @{ - */ - -/** @defgroup DCMI_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the DCMI registers to their default reset values. - * @param None - * @retval None - */ -void DCMI_DeInit(void) -{ - DCMI->CR = 0x0; - DCMI->IER = 0x0; - DCMI->ICR = 0x1F; - DCMI->ESCR = 0x0; - DCMI->ESUR = 0x0; - DCMI->CWSTRTR = 0x0; - DCMI->CWSIZER = 0x0; -} - -/** - * @brief Initializes the DCMI according to the specified parameters in the DCMI_InitStruct. - * @param DCMI_InitStruct: pointer to a DCMI_InitTypeDef structure that contains - * the configuration information for the DCMI. - * @retval None - */ -void DCMI_Init(DCMI_InitTypeDef* DCMI_InitStruct) -{ - uint32_t temp = 0x0; - - /* Check the parameters */ - assert_param(IS_DCMI_CAPTURE_MODE(DCMI_InitStruct->DCMI_CaptureMode)); - assert_param(IS_DCMI_SYNCHRO(DCMI_InitStruct->DCMI_SynchroMode)); - assert_param(IS_DCMI_PCKPOLARITY(DCMI_InitStruct->DCMI_PCKPolarity)); - assert_param(IS_DCMI_VSPOLARITY(DCMI_InitStruct->DCMI_VSPolarity)); - assert_param(IS_DCMI_HSPOLARITY(DCMI_InitStruct->DCMI_HSPolarity)); - assert_param(IS_DCMI_CAPTURE_RATE(DCMI_InitStruct->DCMI_CaptureRate)); - assert_param(IS_DCMI_EXTENDED_DATA(DCMI_InitStruct->DCMI_ExtendedDataMode)); - - /* The DCMI configuration registers should be programmed correctly before - enabling the CR_ENABLE Bit and the CR_CAPTURE Bit */ - DCMI->CR &= ~(DCMI_CR_ENABLE | DCMI_CR_CAPTURE); - - /* Reset the old DCMI configuration */ - temp = DCMI->CR; - - temp &= ~((uint32_t)DCMI_CR_CM | DCMI_CR_ESS | DCMI_CR_PCKPOL | - DCMI_CR_HSPOL | DCMI_CR_VSPOL | DCMI_CR_FCRC_0 | - DCMI_CR_FCRC_1 | DCMI_CR_EDM_0 | DCMI_CR_EDM_1); - - /* Sets the new configuration of the DCMI peripheral */ - temp |= ((uint32_t)DCMI_InitStruct->DCMI_CaptureMode | - DCMI_InitStruct->DCMI_SynchroMode | - DCMI_InitStruct->DCMI_PCKPolarity | - DCMI_InitStruct->DCMI_VSPolarity | - DCMI_InitStruct->DCMI_HSPolarity | - DCMI_InitStruct->DCMI_CaptureRate | - DCMI_InitStruct->DCMI_ExtendedDataMode); - - DCMI->CR = temp; -} - -/** - * @brief Fills each DCMI_InitStruct member with its default value. - * @param DCMI_InitStruct : pointer to a DCMI_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void DCMI_StructInit(DCMI_InitTypeDef* DCMI_InitStruct) -{ - /* Set the default configuration */ - DCMI_InitStruct->DCMI_CaptureMode = DCMI_CaptureMode_Continuous; - DCMI_InitStruct->DCMI_SynchroMode = DCMI_SynchroMode_Hardware; - DCMI_InitStruct->DCMI_PCKPolarity = DCMI_PCKPolarity_Falling; - DCMI_InitStruct->DCMI_VSPolarity = DCMI_VSPolarity_Low; - DCMI_InitStruct->DCMI_HSPolarity = DCMI_HSPolarity_Low; - DCMI_InitStruct->DCMI_CaptureRate = DCMI_CaptureRate_All_Frame; - DCMI_InitStruct->DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b; -} - -/** - * @brief Initializes the DCMI peripheral CROP mode according to the specified - * parameters in the DCMI_CROPInitStruct. - * @note This function should be called before to enable and start the DCMI interface. - * @param DCMI_CROPInitStruct: pointer to a DCMI_CROPInitTypeDef structure that - * contains the configuration information for the DCMI peripheral CROP mode. - * @retval None - */ -void DCMI_CROPConfig(DCMI_CROPInitTypeDef* DCMI_CROPInitStruct) -{ - /* Sets the CROP window coordinates */ - DCMI->CWSTRTR = (uint32_t)((uint32_t)DCMI_CROPInitStruct->DCMI_HorizontalOffsetCount | - ((uint32_t)DCMI_CROPInitStruct->DCMI_VerticalStartLine << 16)); - - /* Sets the CROP window size */ - DCMI->CWSIZER = (uint32_t)(DCMI_CROPInitStruct->DCMI_CaptureCount | - ((uint32_t)DCMI_CROPInitStruct->DCMI_VerticalLineCount << 16)); -} - -/** - * @brief Enables or disables the DCMI Crop feature. - * @note This function should be called before to enable and start the DCMI interface. - * @param NewState: new state of the DCMI Crop feature. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DCMI_CROPCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the DCMI Crop feature */ - DCMI->CR |= (uint32_t)DCMI_CR_CROP; - } - else - { - /* Disable the DCMI Crop feature */ - DCMI->CR &= ~(uint32_t)DCMI_CR_CROP; - } -} - -/** - * @brief Sets the embedded synchronization codes - * @param DCMI_CodesInitTypeDef: pointer to a DCMI_CodesInitTypeDef structure that - * contains the embedded synchronization codes for the DCMI peripheral. - * @retval None - */ -void DCMI_SetEmbeddedSynchroCodes(DCMI_CodesInitTypeDef* DCMI_CodesInitStruct) -{ - DCMI->ESCR = (uint32_t)(DCMI_CodesInitStruct->DCMI_FrameStartCode | - ((uint32_t)DCMI_CodesInitStruct->DCMI_LineStartCode << 8)| - ((uint32_t)DCMI_CodesInitStruct->DCMI_LineEndCode << 16)| - ((uint32_t)DCMI_CodesInitStruct->DCMI_FrameEndCode << 24)); -} - -/** - * @brief Enables or disables the DCMI JPEG format. - * @note The Crop and Embedded Synchronization features cannot be used in this mode. - * @param NewState: new state of the DCMI JPEG format. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DCMI_JPEGCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the DCMI JPEG format */ - DCMI->CR |= (uint32_t)DCMI_CR_JPEG; - } - else - { - /* Disable the DCMI JPEG format */ - DCMI->CR &= ~(uint32_t)DCMI_CR_JPEG; - } -} -/** - * @} - */ - -/** @defgroup DCMI_Group2 Image capture functions - * @brief Image capture functions - * -@verbatim - =============================================================================== - Image capture functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the DCMI interface. - * @param NewState: new state of the DCMI interface. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DCMI_Cmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the DCMI by setting ENABLE bit */ - DCMI->CR |= (uint32_t)DCMI_CR_ENABLE; - } - else - { - /* Disable the DCMI by clearing ENABLE bit */ - DCMI->CR &= ~(uint32_t)DCMI_CR_ENABLE; - } -} - -/** - * @brief Enables or disables the DCMI Capture. - * @param NewState: new state of the DCMI capture. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DCMI_CaptureCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the DCMI Capture */ - DCMI->CR |= (uint32_t)DCMI_CR_CAPTURE; - } - else - { - /* Disable the DCMI Capture */ - DCMI->CR &= ~(uint32_t)DCMI_CR_CAPTURE; - } -} - -/** - * @brief Reads the data stored in the DR register. - * @param None - * @retval Data register value - */ -uint32_t DCMI_ReadData(void) -{ - return DCMI->DR; -} -/** - * @} - */ - -/** @defgroup DCMI_Group3 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the DCMI interface interrupts. - * @param DCMI_IT: specifies the DCMI interrupt sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask - * @arg DCMI_IT_OVF: Overflow interrupt mask - * @arg DCMI_IT_ERR: Synchronization error interrupt mask - * @arg DCMI_IT_VSYNC: VSYNC interrupt mask - * @arg DCMI_IT_LINE: Line interrupt mask - * @param NewState: new state of the specified DCMI interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DCMI_ITConfig(uint16_t DCMI_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DCMI_CONFIG_IT(DCMI_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the Interrupt sources */ - DCMI->IER |= DCMI_IT; - } - else - { - /* Disable the Interrupt sources */ - DCMI->IER &= (uint16_t)(~DCMI_IT); - } -} - -/** - * @brief Checks whether the DCMI interface flag is set or not. - * @param DCMI_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg DCMI_FLAG_FRAMERI: Frame capture complete Raw flag mask - * @arg DCMI_FLAG_OVFRI: Overflow Raw flag mask - * @arg DCMI_FLAG_ERRRI: Synchronization error Raw flag mask - * @arg DCMI_FLAG_VSYNCRI: VSYNC Raw flag mask - * @arg DCMI_FLAG_LINERI: Line Raw flag mask - * @arg DCMI_FLAG_FRAMEMI: Frame capture complete Masked flag mask - * @arg DCMI_FLAG_OVFMI: Overflow Masked flag mask - * @arg DCMI_FLAG_ERRMI: Synchronization error Masked flag mask - * @arg DCMI_FLAG_VSYNCMI: VSYNC Masked flag mask - * @arg DCMI_FLAG_LINEMI: Line Masked flag mask - * @arg DCMI_FLAG_HSYNC: HSYNC flag mask - * @arg DCMI_FLAG_VSYNC: VSYNC flag mask - * @arg DCMI_FLAG_FNE: Fifo not empty flag mask - * @retval The new state of DCMI_FLAG (SET or RESET). - */ -FlagStatus DCMI_GetFlagStatus(uint16_t DCMI_FLAG) -{ - FlagStatus bitstatus = RESET; - uint32_t dcmireg, tempreg = 0; - - /* Check the parameters */ - assert_param(IS_DCMI_GET_FLAG(DCMI_FLAG)); - - /* Get the DCMI register index */ - dcmireg = (((uint16_t)DCMI_FLAG) >> 12); - - if (dcmireg == 0x01) /* The FLAG is in RISR register */ - { - tempreg= DCMI->RISR; - } - else if (dcmireg == 0x02) /* The FLAG is in SR register */ - { - tempreg = DCMI->SR; - } - else /* The FLAG is in MISR register */ - { - tempreg = DCMI->MISR; - } - - if ((tempreg & DCMI_FLAG) != (uint16_t)RESET ) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the DCMI_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the DCMI's pending flags. - * @param DCMI_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg DCMI_FLAG_FRAMERI: Frame capture complete Raw flag mask - * @arg DCMI_FLAG_OVFRI: Overflow Raw flag mask - * @arg DCMI_FLAG_ERRRI: Synchronization error Raw flag mask - * @arg DCMI_FLAG_VSYNCRI: VSYNC Raw flag mask - * @arg DCMI_FLAG_LINERI: Line Raw flag mask - * @retval None - */ -void DCMI_ClearFlag(uint16_t DCMI_FLAG) -{ - /* Check the parameters */ - assert_param(IS_DCMI_CLEAR_FLAG(DCMI_FLAG)); - - /* Clear the flag by writing in the ICR register 1 in the corresponding - Flag position*/ - - DCMI->ICR = DCMI_FLAG; -} - -/** - * @brief Checks whether the DCMI interrupt has occurred or not. - * @param DCMI_IT: specifies the DCMI interrupt source to check. - * This parameter can be one of the following values: - * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask - * @arg DCMI_IT_OVF: Overflow interrupt mask - * @arg DCMI_IT_ERR: Synchronization error interrupt mask - * @arg DCMI_IT_VSYNC: VSYNC interrupt mask - * @arg DCMI_IT_LINE: Line interrupt mask - * @retval The new state of DCMI_IT (SET or RESET). - */ -ITStatus DCMI_GetITStatus(uint16_t DCMI_IT) -{ - ITStatus bitstatus = RESET; - uint32_t itstatus = 0; - - /* Check the parameters */ - assert_param(IS_DCMI_GET_IT(DCMI_IT)); - - itstatus = DCMI->MISR & DCMI_IT; /* Only masked interrupts are checked */ - - if ((itstatus != (uint16_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the DCMI's interrupt pending bits. - * @param DCMI_IT: specifies the DCMI interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask - * @arg DCMI_IT_OVF: Overflow interrupt mask - * @arg DCMI_IT_ERR: Synchronization error interrupt mask - * @arg DCMI_IT_VSYNC: VSYNC interrupt mask - * @arg DCMI_IT_LINE: Line interrupt mask - * @retval None - */ -void DCMI_ClearITPendingBit(uint16_t DCMI_IT) -{ - /* Clear the interrupt pending Bit by writing in the ICR register 1 in the - corresponding pending Bit position*/ - - DCMI->ICR = DCMI_IT; -} -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma.c deleted file mode 100644 index 92a3692d1..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma.c +++ /dev/null @@ -1,1283 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_dma.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the Direct Memory Access controller (DMA): - * - Initialization and Configuration - * - Data Counter - * - Double Buffer mode configuration and command - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable The DMA controller clock using RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA1, ENABLE) - * function for DMA1 or using RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA2, ENABLE) - * function for DMA2. - * - * 2. Enable and configure the peripheral to be connected to the DMA Stream - * (except for internal SRAM / FLASH memories: no initialization is - * necessary). - * - * 3. For a given Stream, program the required configuration through following parameters: - * Source and Destination addresses, Transfer Direction, Transfer size, Source and Destination - * data formats, Circular or Normal mode, Stream Priority level, Source and Destination - * Incrementation mode, FIFO mode and its Threshold (if needed), Burst mode for Source and/or - * Destination (if needed) using the DMA_Init() function. - * To avoid filling un-nesecessary fields, you can call DMA_StructInit() function - * to initialize a given structure with default values (reset values), the modify - * only necessary fields (ie. Source and Destination addresses, Transfer size and Data Formats). - * - * 4. Enable the NVIC and the corresponding interrupt(s) using the function - * DMA_ITConfig() if you need to use DMA interrupts. - * - * 5. Optionally, if the Circular mode is enabled, you can use the Double buffer mode by configuring - * the second Memory address and the first Memory to be used through the function - * DMA_DoubleBufferModeConfig(). Then enable the Double buffer mode through the function - * DMA_DoubleBufferModeCmd(). These operations must be done before step 6. - * - * 6. Enable the DMA stream using the DMA_Cmd() function. - * - * 7. Activate the needed Stream Request using PPP_DMACmd() function for - * any PPP peripheral except internal SRAM and FLASH (ie. SPI, USART ...) - * The function allowing this operation is provided in each PPP peripheral - * driver (ie. SPI_DMACmd for SPI peripheral). - * Once the Stream is enabled, it is not possible to modify its configuration - * unless the stream is stopped and disabled. - * After enabling the Stream, it is advised to monitor the EN bit status using - * the function DMA_GetCmdStatus(). In case of configuration errors or bus errors - * this bit will remain reset and all transfers on this Stream will remain on hold. - * - * 8. Optionally, you can configure the number of data to be transferred - * when the Stream is disabled (ie. after each Transfer Complete event - * or when a Transfer Error occurs) using the function DMA_SetCurrDataCounter(). - * And you can get the number of remaining data to be transferred using - * the function DMA_GetCurrDataCounter() at run time (when the DMA Stream is - * enabled and running). - * - * 9. To control DMA events you can use one of the following - * two methods: - * a- Check on DMA Stream flags using the function DMA_GetFlagStatus(). - * b- Use DMA interrupts through the function DMA_ITConfig() at initialization - * phase and DMA_GetITStatus() function into interrupt routines in - * communication phase. - * After checking on a flag you should clear it using DMA_ClearFlag() - * function. And after checking on an interrupt event you should - * clear it using DMA_ClearITPendingBit() function. - * - * 10. Optionally, if Circular mode and Double Buffer mode are enabled, you can modify - * the Memory Addresses using the function DMA_MemoryTargetConfig(). Make sure that - * the Memory Address to be modified is not the one currently in use by DMA Stream. - * This condition can be monitored using the function DMA_GetCurrentMemoryTarget(). - * - * 11. Optionally, Pause-Resume operations may be performed: - * The DMA_Cmd() function may be used to perform Pause-Resume operation. When a - * transfer is ongoing, calling this function to disable the Stream will cause the - * transfer to be paused. All configuration registers and the number of remaining - * data will be preserved. When calling again this function to re-enable the Stream, - * the transfer will be resumed from the point where it was paused. - * - * @note Memory-to-Memory transfer is possible by setting the address of the memory into - * the Peripheral registers. In this mode, Circular mode and Double Buffer mode - * are not allowed. - * - * @note The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is - * possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set - * Half-Word data size for the peripheral to access its data register and set Word data size - * for the Memory to gain in access time. Each two Half-words will be packed and written in - * a single access to a Word in the Memory). - * - * @note When FIFO is disabled, it is not allowed to configure different Data Sizes for Source - * and Destination. In this case the Peripheral Data Size will be applied to both Source - * and Destination. - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_dma.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup DMA - * @brief DMA driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* Masks Definition */ -#define TRANSFER_IT_ENABLE_MASK (uint32_t)(DMA_SxCR_TCIE | DMA_SxCR_HTIE | \ - DMA_SxCR_TEIE | DMA_SxCR_DMEIE) - -#define DMA_Stream0_IT_MASK (uint32_t)(DMA_LISR_FEIF0 | DMA_LISR_DMEIF0 | \ - DMA_LISR_TEIF0 | DMA_LISR_HTIF0 | \ - DMA_LISR_TCIF0) - -#define DMA_Stream1_IT_MASK (uint32_t)(DMA_Stream0_IT_MASK << 6) -#define DMA_Stream2_IT_MASK (uint32_t)(DMA_Stream0_IT_MASK << 16) -#define DMA_Stream3_IT_MASK (uint32_t)(DMA_Stream0_IT_MASK << 22) -#define DMA_Stream4_IT_MASK (uint32_t)(DMA_Stream0_IT_MASK | (uint32_t)0x20000000) -#define DMA_Stream5_IT_MASK (uint32_t)(DMA_Stream1_IT_MASK | (uint32_t)0x20000000) -#define DMA_Stream6_IT_MASK (uint32_t)(DMA_Stream2_IT_MASK | (uint32_t)0x20000000) -#define DMA_Stream7_IT_MASK (uint32_t)(DMA_Stream3_IT_MASK | (uint32_t)0x20000000) -#define TRANSFER_IT_MASK (uint32_t)0x0F3C0F3C -#define HIGH_ISR_MASK (uint32_t)0x20000000 -#define RESERVED_MASK (uint32_t)0x0F7D0F7D - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - - -/** @defgroup DMA_Private_Functions - * @{ - */ - -/** @defgroup DMA_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - - This subsection provides functions allowing to initialize the DMA Stream source - and destination addresses, incrementation and data sizes, transfer direction, - buffer size, circular/normal mode selection, memory-to-memory mode selection - and Stream priority value. - - The DMA_Init() function follows the DMA configuration procedures as described in - reference manual (RM0090) except the first point: waiting on EN bit to be reset. - This condition should be checked by user application using the function DMA_GetCmdStatus() - before calling the DMA_Init() function. - -@endverbatim - * @{ - */ - -/** - * @brief Deinitialize the DMAy Streamx registers to their default reset values. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @retval None - */ -void DMA_DeInit(DMA_Stream_TypeDef* DMAy_Streamx) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - - /* Disable the selected DMAy Streamx */ - DMAy_Streamx->CR &= ~((uint32_t)DMA_SxCR_EN); - - /* Reset DMAy Streamx control register */ - DMAy_Streamx->CR = 0; - - /* Reset DMAy Streamx Number of Data to Transfer register */ - DMAy_Streamx->NDTR = 0; - - /* Reset DMAy Streamx peripheral address register */ - DMAy_Streamx->PAR = 0; - - /* Reset DMAy Streamx memory 0 address register */ - DMAy_Streamx->M0AR = 0; - - /* Reset DMAy Streamx memory 1 address register */ - DMAy_Streamx->M1AR = 0; - - /* Reset DMAy Streamx FIFO control register */ - DMAy_Streamx->FCR = (uint32_t)0x00000021; - - /* Reset interrupt pending bits for the selected stream */ - if (DMAy_Streamx == DMA1_Stream0) - { - /* Reset interrupt pending bits for DMA1 Stream0 */ - DMA1->LIFCR = DMA_Stream0_IT_MASK; - } - else if (DMAy_Streamx == DMA1_Stream1) - { - /* Reset interrupt pending bits for DMA1 Stream1 */ - DMA1->LIFCR = DMA_Stream1_IT_MASK; - } - else if (DMAy_Streamx == DMA1_Stream2) - { - /* Reset interrupt pending bits for DMA1 Stream2 */ - DMA1->LIFCR = DMA_Stream2_IT_MASK; - } - else if (DMAy_Streamx == DMA1_Stream3) - { - /* Reset interrupt pending bits for DMA1 Stream3 */ - DMA1->LIFCR = DMA_Stream3_IT_MASK; - } - else if (DMAy_Streamx == DMA1_Stream4) - { - /* Reset interrupt pending bits for DMA1 Stream4 */ - DMA1->HIFCR = DMA_Stream4_IT_MASK; - } - else if (DMAy_Streamx == DMA1_Stream5) - { - /* Reset interrupt pending bits for DMA1 Stream5 */ - DMA1->HIFCR = DMA_Stream5_IT_MASK; - } - else if (DMAy_Streamx == DMA1_Stream6) - { - /* Reset interrupt pending bits for DMA1 Stream6 */ - DMA1->HIFCR = (uint32_t)DMA_Stream6_IT_MASK; - } - else if (DMAy_Streamx == DMA1_Stream7) - { - /* Reset interrupt pending bits for DMA1 Stream7 */ - DMA1->HIFCR = DMA_Stream7_IT_MASK; - } - else if (DMAy_Streamx == DMA2_Stream0) - { - /* Reset interrupt pending bits for DMA2 Stream0 */ - DMA2->LIFCR = DMA_Stream0_IT_MASK; - } - else if (DMAy_Streamx == DMA2_Stream1) - { - /* Reset interrupt pending bits for DMA2 Stream1 */ - DMA2->LIFCR = DMA_Stream1_IT_MASK; - } - else if (DMAy_Streamx == DMA2_Stream2) - { - /* Reset interrupt pending bits for DMA2 Stream2 */ - DMA2->LIFCR = DMA_Stream2_IT_MASK; - } - else if (DMAy_Streamx == DMA2_Stream3) - { - /* Reset interrupt pending bits for DMA2 Stream3 */ - DMA2->LIFCR = DMA_Stream3_IT_MASK; - } - else if (DMAy_Streamx == DMA2_Stream4) - { - /* Reset interrupt pending bits for DMA2 Stream4 */ - DMA2->HIFCR = DMA_Stream4_IT_MASK; - } - else if (DMAy_Streamx == DMA2_Stream5) - { - /* Reset interrupt pending bits for DMA2 Stream5 */ - DMA2->HIFCR = DMA_Stream5_IT_MASK; - } - else if (DMAy_Streamx == DMA2_Stream6) - { - /* Reset interrupt pending bits for DMA2 Stream6 */ - DMA2->HIFCR = DMA_Stream6_IT_MASK; - } - else - { - if (DMAy_Streamx == DMA2_Stream7) - { - /* Reset interrupt pending bits for DMA2 Stream7 */ - DMA2->HIFCR = DMA_Stream7_IT_MASK; - } - } -} - -/** - * @brief Initializes the DMAy Streamx according to the specified parameters in - * the DMA_InitStruct structure. - * @note Before calling this function, it is recommended to check that the Stream - * is actually disabled using the function DMA_GetCmdStatus(). - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @param DMA_InitStruct: pointer to a DMA_InitTypeDef structure that contains - * the configuration information for the specified DMA Stream. - * @retval None - */ -void DMA_Init(DMA_Stream_TypeDef* DMAy_Streamx, DMA_InitTypeDef* DMA_InitStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - assert_param(IS_DMA_CHANNEL(DMA_InitStruct->DMA_Channel)); - assert_param(IS_DMA_DIRECTION(DMA_InitStruct->DMA_DIR)); - assert_param(IS_DMA_BUFFER_SIZE(DMA_InitStruct->DMA_BufferSize)); - assert_param(IS_DMA_PERIPHERAL_INC_STATE(DMA_InitStruct->DMA_PeripheralInc)); - assert_param(IS_DMA_MEMORY_INC_STATE(DMA_InitStruct->DMA_MemoryInc)); - assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(DMA_InitStruct->DMA_PeripheralDataSize)); - assert_param(IS_DMA_MEMORY_DATA_SIZE(DMA_InitStruct->DMA_MemoryDataSize)); - assert_param(IS_DMA_MODE(DMA_InitStruct->DMA_Mode)); - assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority)); - assert_param(IS_DMA_FIFO_MODE_STATE(DMA_InitStruct->DMA_FIFOMode)); - assert_param(IS_DMA_FIFO_THRESHOLD(DMA_InitStruct->DMA_FIFOThreshold)); - assert_param(IS_DMA_MEMORY_BURST(DMA_InitStruct->DMA_MemoryBurst)); - assert_param(IS_DMA_PERIPHERAL_BURST(DMA_InitStruct->DMA_PeripheralBurst)); - - /*------------------------- DMAy Streamx CR Configuration ------------------*/ - /* Get the DMAy_Streamx CR value */ - tmpreg = DMAy_Streamx->CR; - - /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */ - tmpreg &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \ - DMA_SxCR_PL | DMA_SxCR_MSIZE | DMA_SxCR_PSIZE | \ - DMA_SxCR_MINC | DMA_SxCR_PINC | DMA_SxCR_CIRC | \ - DMA_SxCR_DIR)); - - /* Configure DMAy Streamx: */ - /* Set CHSEL bits according to DMA_CHSEL value */ - /* Set DIR bits according to DMA_DIR value */ - /* Set PINC bit according to DMA_PeripheralInc value */ - /* Set MINC bit according to DMA_MemoryInc value */ - /* Set PSIZE bits according to DMA_PeripheralDataSize value */ - /* Set MSIZE bits according to DMA_MemoryDataSize value */ - /* Set CIRC bit according to DMA_Mode value */ - /* Set PL bits according to DMA_Priority value */ - /* Set MBURST bits according to DMA_MemoryBurst value */ - /* Set PBURST bits according to DMA_PeripheralBurst value */ - tmpreg |= DMA_InitStruct->DMA_Channel | DMA_InitStruct->DMA_DIR | - DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc | - DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize | - DMA_InitStruct->DMA_Mode | DMA_InitStruct->DMA_Priority | - DMA_InitStruct->DMA_MemoryBurst | DMA_InitStruct->DMA_PeripheralBurst; - - /* Write to DMAy Streamx CR register */ - DMAy_Streamx->CR = tmpreg; - - /*------------------------- DMAy Streamx FCR Configuration -----------------*/ - /* Get the DMAy_Streamx FCR value */ - tmpreg = DMAy_Streamx->FCR; - - /* Clear DMDIS and FTH bits */ - tmpreg &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); - - /* Configure DMAy Streamx FIFO: - Set DMDIS bits according to DMA_FIFOMode value - Set FTH bits according to DMA_FIFOThreshold value */ - tmpreg |= DMA_InitStruct->DMA_FIFOMode | DMA_InitStruct->DMA_FIFOThreshold; - - /* Write to DMAy Streamx CR */ - DMAy_Streamx->FCR = tmpreg; - - /*------------------------- DMAy Streamx NDTR Configuration ----------------*/ - /* Write to DMAy Streamx NDTR register */ - DMAy_Streamx->NDTR = DMA_InitStruct->DMA_BufferSize; - - /*------------------------- DMAy Streamx PAR Configuration -----------------*/ - /* Write to DMAy Streamx PAR */ - DMAy_Streamx->PAR = DMA_InitStruct->DMA_PeripheralBaseAddr; - - /*------------------------- DMAy Streamx M0AR Configuration ----------------*/ - /* Write to DMAy Streamx M0AR */ - DMAy_Streamx->M0AR = DMA_InitStruct->DMA_Memory0BaseAddr; -} - -/** - * @brief Fills each DMA_InitStruct member with its default value. - * @param DMA_InitStruct : pointer to a DMA_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct) -{ - /*-------------- Reset DMA init structure parameters values ----------------*/ - /* Initialize the DMA_Channel member */ - DMA_InitStruct->DMA_Channel = 0; - - /* Initialize the DMA_PeripheralBaseAddr member */ - DMA_InitStruct->DMA_PeripheralBaseAddr = 0; - - /* Initialize the DMA_Memory0BaseAddr member */ - DMA_InitStruct->DMA_Memory0BaseAddr = 0; - - /* Initialize the DMA_DIR member */ - DMA_InitStruct->DMA_DIR = DMA_DIR_PeripheralToMemory; - - /* Initialize the DMA_BufferSize member */ - DMA_InitStruct->DMA_BufferSize = 0; - - /* Initialize the DMA_PeripheralInc member */ - DMA_InitStruct->DMA_PeripheralInc = DMA_PeripheralInc_Disable; - - /* Initialize the DMA_MemoryInc member */ - DMA_InitStruct->DMA_MemoryInc = DMA_MemoryInc_Disable; - - /* Initialize the DMA_PeripheralDataSize member */ - DMA_InitStruct->DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; - - /* Initialize the DMA_MemoryDataSize member */ - DMA_InitStruct->DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; - - /* Initialize the DMA_Mode member */ - DMA_InitStruct->DMA_Mode = DMA_Mode_Normal; - - /* Initialize the DMA_Priority member */ - DMA_InitStruct->DMA_Priority = DMA_Priority_Low; - - /* Initialize the DMA_FIFOMode member */ - DMA_InitStruct->DMA_FIFOMode = DMA_FIFOMode_Disable; - - /* Initialize the DMA_FIFOThreshold member */ - DMA_InitStruct->DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; - - /* Initialize the DMA_MemoryBurst member */ - DMA_InitStruct->DMA_MemoryBurst = DMA_MemoryBurst_Single; - - /* Initialize the DMA_PeripheralBurst member */ - DMA_InitStruct->DMA_PeripheralBurst = DMA_PeripheralBurst_Single; -} - -/** - * @brief Enables or disables the specified DMAy Streamx. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @param NewState: new state of the DMAy Streamx. - * This parameter can be: ENABLE or DISABLE. - * - * @note This function may be used to perform Pause-Resume operation. When a - * transfer is ongoing, calling this function to disable the Stream will - * cause the transfer to be paused. All configuration registers and the - * number of remaining data will be preserved. When calling again this - * function to re-enable the Stream, the transfer will be resumed from - * the point where it was paused. - * - * @note After configuring the DMA Stream (DMA_Init() function) and enabling the - * stream, it is recommended to check (or wait until) the DMA Stream is - * effectively enabled. A Stream may remain disabled if a configuration - * parameter is wrong. - * After disabling a DMA Stream, it is also recommended to check (or wait - * until) the DMA Stream is effectively disabled. If a Stream is disabled - * while a data transfer is ongoing, the current data will be transferred - * and the Stream will be effectively disabled only after the transfer of - * this single data is finished. - * - * @retval None - */ -void DMA_Cmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected DMAy Streamx by setting EN bit */ - DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_EN; - } - else - { - /* Disable the selected DMAy Streamx by clearing EN bit */ - DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_EN; - } -} - -/** - * @brief Configures, when the PINC (Peripheral Increment address mode) bit is - * set, if the peripheral address should be incremented with the data - * size (configured with PSIZE bits) or by a fixed offset equal to 4 - * (32-bit aligned addresses). - * - * @note This function has no effect if the Peripheral Increment mode is disabled. - * - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @param DMA_Pincos: specifies the Peripheral increment offset size. - * This parameter can be one of the following values: - * @arg DMA_PINCOS_Psize: Peripheral address increment is done - * accordingly to PSIZE parameter. - * @arg DMA_PINCOS_WordAligned: Peripheral address increment offset is - * fixed to 4 (32-bit aligned addresses). - * @retval None - */ -void DMA_PeriphIncOffsetSizeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_Pincos) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - assert_param(IS_DMA_PINCOS_SIZE(DMA_Pincos)); - - /* Check the needed Peripheral increment offset */ - if(DMA_Pincos != DMA_PINCOS_Psize) - { - /* Configure DMA_SxCR_PINCOS bit with the input parameter */ - DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_PINCOS; - } - else - { - /* Clear the PINCOS bit: Peripheral address incremented according to PSIZE */ - DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_PINCOS; - } -} - -/** - * @brief Configures, when the DMAy Streamx is disabled, the flow controller for - * the next transactions (Peripheral or Memory). - * - * @note Before enabling this feature, check if the used peripheral supports - * the Flow Controller mode or not. - * - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @param DMA_FlowCtrl: specifies the DMA flow controller. - * This parameter can be one of the following values: - * @arg DMA_FlowCtrl_Memory: DMAy_Streamx transactions flow controller is - * the DMA controller. - * @arg DMA_FlowCtrl_Peripheral: DMAy_Streamx transactions flow controller - * is the peripheral. - * @retval None - */ -void DMA_FlowControllerConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FlowCtrl) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - assert_param(IS_DMA_FLOW_CTRL(DMA_FlowCtrl)); - - /* Check the needed flow controller */ - if(DMA_FlowCtrl != DMA_FlowCtrl_Memory) - { - /* Configure DMA_SxCR_PFCTRL bit with the input parameter */ - DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_PFCTRL; - } - else - { - /* Clear the PFCTRL bit: Memory is the flow controller */ - DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_PFCTRL; - } -} -/** - * @} - */ - -/** @defgroup DMA_Group2 Data Counter functions - * @brief Data Counter functions - * -@verbatim - =============================================================================== - Data Counter functions - =============================================================================== - - This subsection provides function allowing to configure and read the buffer size - (number of data to be transferred). - - The DMA data counter can be written only when the DMA Stream is disabled - (ie. after transfer complete event). - - The following function can be used to write the Stream data counter value: - - void DMA_SetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx, uint16_t Counter); - -@note It is advised to use this function rather than DMA_Init() in situations where - only the Data buffer needs to be reloaded. - -@note If the Source and Destination Data Sizes are different, then the value written in - data counter, expressing the number of transfers, is relative to the number of - transfers from the Peripheral point of view. - ie. If Memory data size is Word, Peripheral data size is Half-Words, then the value - to be configured in the data counter is the number of Half-Words to be transferred - from/to the peripheral. - - The DMA data counter can be read to indicate the number of remaining transfers for - the relative DMA Stream. This counter is decremented at the end of each data - transfer and when the transfer is complete: - - If Normal mode is selected: the counter is set to 0. - - If Circular mode is selected: the counter is reloaded with the initial value - (configured before enabling the DMA Stream) - - The following function can be used to read the Stream data counter value: - - uint16_t DMA_GetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx); - -@endverbatim - * @{ - */ - -/** - * @brief Writes the number of data units to be transferred on the DMAy Streamx. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @param Counter: Number of data units to be transferred (from 0 to 65535) - * Number of data items depends only on the Peripheral data format. - * - * @note If Peripheral data format is Bytes: number of data units is equal - * to total number of bytes to be transferred. - * - * @note If Peripheral data format is Half-Word: number of data units is - * equal to total number of bytes to be transferred / 2. - * - * @note If Peripheral data format is Word: number of data units is equal - * to total number of bytes to be transferred / 4. - * - * @note In Memory-to-Memory transfer mode, the memory buffer pointed by - * DMAy_SxPAR register is considered as Peripheral. - * - * @retval The number of remaining data units in the current DMAy Streamx transfer. - */ -void DMA_SetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx, uint16_t Counter) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - - /* Write the number of data units to be transferred */ - DMAy_Streamx->NDTR = (uint16_t)Counter; -} - -/** - * @brief Returns the number of remaining data units in the current DMAy Streamx transfer. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @retval The number of remaining data units in the current DMAy Streamx transfer. - */ -uint16_t DMA_GetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - - /* Return the number of remaining data units for DMAy Streamx */ - return ((uint16_t)(DMAy_Streamx->NDTR)); -} -/** - * @} - */ - -/** @defgroup DMA_Group3 Double Buffer mode functions - * @brief Double Buffer mode functions - * -@verbatim - =============================================================================== - Double Buffer mode functions - =============================================================================== - - This subsection provides function allowing to configure and control the double - buffer mode parameters. - - The Double Buffer mode can be used only when Circular mode is enabled. - The Double Buffer mode cannot be used when transferring data from Memory to Memory. - - The Double Buffer mode allows to set two different Memory addresses from/to which - the DMA controller will access alternatively (after completing transfer to/from target - memory 0, it will start transfer to/from target memory 1). - This allows to reduce software overhead for double buffering and reduce the CPU - access time. - - Two functions must be called before calling the DMA_Init() function: - - void DMA_DoubleBufferModeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t Memory1BaseAddr, - uint32_t DMA_CurrentMemory); - - void DMA_DoubleBufferModeCmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState); - - DMA_DoubleBufferModeConfig() is called to configure the Memory 1 base address and the first - Memory target from/to which the transfer will start after enabling the DMA Stream. - Then DMA_DoubleBufferModeCmd() must be called to enable the Double Buffer mode (or disable - it when it should not be used). - - - Two functions can be called dynamically when the transfer is ongoing (or when the DMA Stream is - stopped) to modify on of the target Memories addresses or to check wich Memory target is currently - used: - - void DMA_MemoryTargetConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t MemoryBaseAddr, - uint32_t DMA_MemoryTarget); - - uint32_t DMA_GetCurrentMemoryTarget(DMA_Stream_TypeDef* DMAy_Streamx); - - DMA_MemoryTargetConfig() can be called to modify the base address of one of the two target Memories. - The Memory of which the base address will be modified must not be currently be used by the DMA Stream - (ie. if the DMA Stream is currently transferring from Memory 1 then you can only modify base address - of target Memory 0 and vice versa). - To check this condition, it is recommended to use the function DMA_GetCurrentMemoryTarget() which - returns the index of the Memory target currently in use by the DMA Stream. - -@endverbatim - * @{ - */ - -/** - * @brief Configures, when the DMAy Streamx is disabled, the double buffer mode - * and the current memory target. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @param Memory1BaseAddr: the base address of the second buffer (Memory 1) - * @param DMA_CurrentMemory: specifies which memory will be first buffer for - * the transactions when the Stream will be enabled. - * This parameter can be one of the following values: - * @arg DMA_Memory_0: Memory 0 is the current buffer. - * @arg DMA_Memory_1: Memory 1 is the current buffer. - * - * @note Memory0BaseAddr is set by the DMA structure configuration in DMA_Init(). - * - * @retval None - */ -void DMA_DoubleBufferModeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t Memory1BaseAddr, - uint32_t DMA_CurrentMemory) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - assert_param(IS_DMA_CURRENT_MEM(DMA_CurrentMemory)); - - if (DMA_CurrentMemory != DMA_Memory_0) - { - /* Set Memory 1 as current memory address */ - DMAy_Streamx->CR |= (uint32_t)(DMA_SxCR_CT); - } - else - { - /* Set Memory 0 as current memory address */ - DMAy_Streamx->CR &= ~(uint32_t)(DMA_SxCR_CT); - } - - /* Write to DMAy Streamx M1AR */ - DMAy_Streamx->M1AR = Memory1BaseAddr; -} - -/** - * @brief Enables or disables the double buffer mode for the selected DMA stream. - * @note This function can be called only when the DMA Stream is disabled. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @param NewState: new state of the DMAy Streamx double buffer mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DMA_DoubleBufferModeCmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Configure the Double Buffer mode */ - if (NewState != DISABLE) - { - /* Enable the Double buffer mode */ - DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_DBM; - } - else - { - /* Disable the Double buffer mode */ - DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_DBM; - } -} - -/** - * @brief Configures the Memory address for the next buffer transfer in double - * buffer mode (for dynamic use). This function can be called when the - * DMA Stream is enabled and when the transfer is ongoing. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @param MemoryBaseAddr: The base address of the target memory buffer - * @param DMA_MemoryTarget: Next memory target to be used. - * This parameter can be one of the following values: - * @arg DMA_Memory_0: To use the memory address 0 - * @arg DMA_Memory_1: To use the memory address 1 - * - * @note It is not allowed to modify the Base Address of a target Memory when - * this target is involved in the current transfer. ie. If the DMA Stream - * is currently transferring to/from Memory 1, then it not possible to - * modify Base address of Memory 1, but it is possible to modify Base - * address of Memory 0. - * To know which Memory is currently used, you can use the function - * DMA_GetCurrentMemoryTarget(). - * - * @retval None - */ -void DMA_MemoryTargetConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t MemoryBaseAddr, - uint32_t DMA_MemoryTarget) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - assert_param(IS_DMA_CURRENT_MEM(DMA_MemoryTarget)); - - /* Check the Memory target to be configured */ - if (DMA_MemoryTarget != DMA_Memory_0) - { - /* Write to DMAy Streamx M1AR */ - DMAy_Streamx->M1AR = MemoryBaseAddr; - } - else - { - /* Write to DMAy Streamx M0AR */ - DMAy_Streamx->M0AR = MemoryBaseAddr; - } -} - -/** - * @brief Returns the current memory target used by double buffer transfer. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @retval The memory target number: 0 for Memory0 or 1 for Memory1. - */ -uint32_t DMA_GetCurrentMemoryTarget(DMA_Stream_TypeDef* DMAy_Streamx) -{ - uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - - /* Get the current memory target */ - if ((DMAy_Streamx->CR & DMA_SxCR_CT) != 0) - { - /* Current memory buffer used is Memory 1 */ - tmp = 1; - } - else - { - /* Current memory buffer used is Memory 0 */ - tmp = 0; - } - return tmp; -} -/** - * @} - */ - -/** @defgroup DMA_Group4 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - - This subsection provides functions allowing to - - Check the DMA enable status - - Check the FIFO status - - Configure the DMA Interrupts sources and check or clear the flags or pending bits status. - - 1. DMA Enable status: - After configuring the DMA Stream (DMA_Init() function) and enabling the stream, - it is recommended to check (or wait until) the DMA Stream is effectively enabled. - A Stream may remain disabled if a configuration parameter is wrong. - After disabling a DMA Stream, it is also recommended to check (or wait until) the DMA - Stream is effectively disabled. If a Stream is disabled while a data transfer is ongoing, - the current data will be transferred and the Stream will be effectively disabled only after - this data transfer completion. - To monitor this state it is possible to use the following function: - - FunctionalState DMA_GetCmdStatus(DMA_Stream_TypeDef* DMAy_Streamx); - - 2. FIFO Status: - It is possible to monitor the FIFO status when a transfer is ongoing using the following - function: - - uint32_t DMA_GetFIFOStatus(DMA_Stream_TypeDef* DMAy_Streamx); - - 3. DMA Interrupts and Flags: - The user should identify which mode will be used in his application to manage the - DMA controller events: Polling mode or Interrupt mode. - - Polling Mode - ============= - Each DMA stream can be managed through 4 event Flags: - (x : DMA Stream number ) - 1. DMA_FLAG_FEIFx : to indicate that a FIFO Mode Transfer Error event occurred. - 2. DMA_FLAG_DMEIFx : to indicate that a Direct Mode Transfer Error event occurred. - 3. DMA_FLAG_TEIFx : to indicate that a Transfer Error event occurred. - 4. DMA_FLAG_HTIFx : to indicate that a Half-Transfer Complete event occurred. - 5. DMA_FLAG_TCIFx : to indicate that a Transfer Complete event occurred . - - In this Mode it is advised to use the following functions: - - FlagStatus DMA_GetFlagStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG); - - void DMA_ClearFlag(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG); - - Interrupt Mode - =============== - Each DMA Stream can be managed through 4 Interrupts: - - Interrupt Source - ---------------- - 1. DMA_IT_FEIFx : specifies the interrupt source for the FIFO Mode Transfer Error event. - 2. DMA_IT_DMEIFx : specifies the interrupt source for the Direct Mode Transfer Error event. - 3. DMA_IT_TEIFx : specifies the interrupt source for the Transfer Error event. - 4. DMA_IT_HTIFx : specifies the interrupt source for the Half-Transfer Complete event. - 5. DMA_IT_TCIFx : specifies the interrupt source for the a Transfer Complete event. - - In this Mode it is advised to use the following functions: - - void DMA_ITConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT, FunctionalState NewState); - - ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT); - - void DMA_ClearITPendingBit(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT); - -@endverbatim - * @{ - */ - -/** - * @brief Returns the status of EN bit for the specified DMAy Streamx. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * - * @note After configuring the DMA Stream (DMA_Init() function) and enabling - * the stream, it is recommended to check (or wait until) the DMA Stream - * is effectively enabled. A Stream may remain disabled if a configuration - * parameter is wrong. - * After disabling a DMA Stream, it is also recommended to check (or wait - * until) the DMA Stream is effectively disabled. If a Stream is disabled - * while a data transfer is ongoing, the current data will be transferred - * and the Stream will be effectively disabled only after the transfer - * of this single data is finished. - * - * @retval Current state of the DMAy Streamx (ENABLE or DISABLE). - */ -FunctionalState DMA_GetCmdStatus(DMA_Stream_TypeDef* DMAy_Streamx) -{ - FunctionalState state = DISABLE; - - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - - if ((DMAy_Streamx->CR & (uint32_t)DMA_SxCR_EN) != 0) - { - /* The selected DMAy Streamx EN bit is set (DMA is still transferring) */ - state = ENABLE; - } - else - { - /* The selected DMAy Streamx EN bit is cleared (DMA is disabled and - all transfers are complete) */ - state = DISABLE; - } - return state; -} - -/** - * @brief Returns the current DMAy Streamx FIFO filled level. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @retval The FIFO filling state. - * - DMA_FIFOStatus_Less1QuarterFull: when FIFO is less than 1 quarter-full - * and not empty. - * - DMA_FIFOStatus_1QuarterFull: if more than 1 quarter-full. - * - DMA_FIFOStatus_HalfFull: if more than 1 half-full. - * - DMA_FIFOStatus_3QuartersFull: if more than 3 quarters-full. - * - DMA_FIFOStatus_Empty: when FIFO is empty - * - DMA_FIFOStatus_Full: when FIFO is full - */ -uint32_t DMA_GetFIFOStatus(DMA_Stream_TypeDef* DMAy_Streamx) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - - /* Get the FIFO level bits */ - tmpreg = (uint32_t)((DMAy_Streamx->FCR & DMA_SxFCR_FS)); - - return tmpreg; -} - -/** - * @brief Checks whether the specified DMAy Streamx flag is set or not. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @param DMA_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg DMA_FLAG_TCIFx: Streamx transfer complete flag - * @arg DMA_FLAG_HTIFx: Streamx half transfer complete flag - * @arg DMA_FLAG_TEIFx: Streamx transfer error flag - * @arg DMA_FLAG_DMEIFx: Streamx direct mode error flag - * @arg DMA_FLAG_FEIFx: Streamx FIFO error flag - * Where x can be 0 to 7 to select the DMA Stream. - * @retval The new state of DMA_FLAG (SET or RESET). - */ -FlagStatus DMA_GetFlagStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG) -{ - FlagStatus bitstatus = RESET; - DMA_TypeDef* DMAy; - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - assert_param(IS_DMA_GET_FLAG(DMA_FLAG)); - - /* Determine the DMA to which belongs the stream */ - if (DMAy_Streamx < DMA2_Stream0) - { - /* DMAy_Streamx belongs to DMA1 */ - DMAy = DMA1; - } - else - { - /* DMAy_Streamx belongs to DMA2 */ - DMAy = DMA2; - } - - /* Check if the flag is in HISR or LISR */ - if ((DMA_FLAG & HIGH_ISR_MASK) != (uint32_t)RESET) - { - /* Get DMAy HISR register value */ - tmpreg = DMAy->HISR; - } - else - { - /* Get DMAy LISR register value */ - tmpreg = DMAy->LISR; - } - - /* Mask the reserved bits */ - tmpreg &= (uint32_t)RESERVED_MASK; - - /* Check the status of the specified DMA flag */ - if ((tmpreg & DMA_FLAG) != (uint32_t)RESET) - { - /* DMA_FLAG is set */ - bitstatus = SET; - } - else - { - /* DMA_FLAG is reset */ - bitstatus = RESET; - } - - /* Return the DMA_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the DMAy Streamx's pending flags. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @param DMA_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg DMA_FLAG_TCIFx: Streamx transfer complete flag - * @arg DMA_FLAG_HTIFx: Streamx half transfer complete flag - * @arg DMA_FLAG_TEIFx: Streamx transfer error flag - * @arg DMA_FLAG_DMEIFx: Streamx direct mode error flag - * @arg DMA_FLAG_FEIFx: Streamx FIFO error flag - * Where x can be 0 to 7 to select the DMA Stream. - * @retval None - */ -void DMA_ClearFlag(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG) -{ - DMA_TypeDef* DMAy; - - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - assert_param(IS_DMA_CLEAR_FLAG(DMA_FLAG)); - - /* Determine the DMA to which belongs the stream */ - if (DMAy_Streamx < DMA2_Stream0) - { - /* DMAy_Streamx belongs to DMA1 */ - DMAy = DMA1; - } - else - { - /* DMAy_Streamx belongs to DMA2 */ - DMAy = DMA2; - } - - /* Check if LIFCR or HIFCR register is targeted */ - if ((DMA_FLAG & HIGH_ISR_MASK) != (uint32_t)RESET) - { - /* Set DMAy HIFCR register clear flag bits */ - DMAy->HIFCR = (uint32_t)(DMA_FLAG & RESERVED_MASK); - } - else - { - /* Set DMAy LIFCR register clear flag bits */ - DMAy->LIFCR = (uint32_t)(DMA_FLAG & RESERVED_MASK); - } -} - -/** - * @brief Enables or disables the specified DMAy Streamx interrupts. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @param DMA_IT: specifies the DMA interrupt sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg DMA_IT_TC: Transfer complete interrupt mask - * @arg DMA_IT_HT: Half transfer complete interrupt mask - * @arg DMA_IT_TE: Transfer error interrupt mask - * @arg DMA_IT_FE: FIFO error interrupt mask - * @param NewState: new state of the specified DMA interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void DMA_ITConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - assert_param(IS_DMA_CONFIG_IT(DMA_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Check if the DMA_IT parameter contains a FIFO interrupt */ - if ((DMA_IT & DMA_IT_FE) != 0) - { - if (NewState != DISABLE) - { - /* Enable the selected DMA FIFO interrupts */ - DMAy_Streamx->FCR |= (uint32_t)DMA_IT_FE; - } - else - { - /* Disable the selected DMA FIFO interrupts */ - DMAy_Streamx->FCR &= ~(uint32_t)DMA_IT_FE; - } - } - - /* Check if the DMA_IT parameter contains a Transfer interrupt */ - if (DMA_IT != DMA_IT_FE) - { - if (NewState != DISABLE) - { - /* Enable the selected DMA transfer interrupts */ - DMAy_Streamx->CR |= (uint32_t)(DMA_IT & TRANSFER_IT_ENABLE_MASK); - } - else - { - /* Disable the selected DMA transfer interrupts */ - DMAy_Streamx->CR &= ~(uint32_t)(DMA_IT & TRANSFER_IT_ENABLE_MASK); - } - } -} - -/** - * @brief Checks whether the specified DMAy Streamx interrupt has occurred or not. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @param DMA_IT: specifies the DMA interrupt source to check. - * This parameter can be one of the following values: - * @arg DMA_IT_TCIFx: Streamx transfer complete interrupt - * @arg DMA_IT_HTIFx: Streamx half transfer complete interrupt - * @arg DMA_IT_TEIFx: Streamx transfer error interrupt - * @arg DMA_IT_DMEIFx: Streamx direct mode error interrupt - * @arg DMA_IT_FEIFx: Streamx FIFO error interrupt - * Where x can be 0 to 7 to select the DMA Stream. - * @retval The new state of DMA_IT (SET or RESET). - */ -ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT) -{ - ITStatus bitstatus = RESET; - DMA_TypeDef* DMAy; - uint32_t tmpreg = 0, enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - assert_param(IS_DMA_GET_IT(DMA_IT)); - - /* Determine the DMA to which belongs the stream */ - if (DMAy_Streamx < DMA2_Stream0) - { - /* DMAy_Streamx belongs to DMA1 */ - DMAy = DMA1; - } - else - { - /* DMAy_Streamx belongs to DMA2 */ - DMAy = DMA2; - } - - /* Check if the interrupt enable bit is in the CR or FCR register */ - if ((DMA_IT & TRANSFER_IT_MASK) != (uint32_t)RESET) - { - /* Get the interrupt enable position mask in CR register */ - tmpreg = (uint32_t)((DMA_IT >> 11) & TRANSFER_IT_ENABLE_MASK); - - /* Check the enable bit in CR register */ - enablestatus = (uint32_t)(DMAy_Streamx->CR & tmpreg); - } - else - { - /* Check the enable bit in FCR register */ - enablestatus = (uint32_t)(DMAy_Streamx->FCR & DMA_IT_FE); - } - - /* Check if the interrupt pending flag is in LISR or HISR */ - if ((DMA_IT & HIGH_ISR_MASK) != (uint32_t)RESET) - { - /* Get DMAy HISR register value */ - tmpreg = DMAy->HISR ; - } - else - { - /* Get DMAy LISR register value */ - tmpreg = DMAy->LISR ; - } - - /* mask all reserved bits */ - tmpreg &= (uint32_t)RESERVED_MASK; - - /* Check the status of the specified DMA interrupt */ - if (((tmpreg & DMA_IT) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET)) - { - /* DMA_IT is set */ - bitstatus = SET; - } - else - { - /* DMA_IT is reset */ - bitstatus = RESET; - } - - /* Return the DMA_IT status */ - return bitstatus; -} - -/** - * @brief Clears the DMAy Streamx's interrupt pending bits. - * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0 - * to 7 to select the DMA Stream. - * @param DMA_IT: specifies the DMA interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg DMA_IT_TCIFx: Streamx transfer complete interrupt - * @arg DMA_IT_HTIFx: Streamx half transfer complete interrupt - * @arg DMA_IT_TEIFx: Streamx transfer error interrupt - * @arg DMA_IT_DMEIFx: Streamx direct mode error interrupt - * @arg DMA_IT_FEIFx: Streamx FIFO error interrupt - * Where x can be 0 to 7 to select the DMA Stream. - * @retval None - */ -void DMA_ClearITPendingBit(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT) -{ - DMA_TypeDef* DMAy; - - /* Check the parameters */ - assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx)); - assert_param(IS_DMA_CLEAR_IT(DMA_IT)); - - /* Determine the DMA to which belongs the stream */ - if (DMAy_Streamx < DMA2_Stream0) - { - /* DMAy_Streamx belongs to DMA1 */ - DMAy = DMA1; - } - else - { - /* DMAy_Streamx belongs to DMA2 */ - DMAy = DMA2; - } - - /* Check if LIFCR or HIFCR register is targeted */ - if ((DMA_IT & HIGH_ISR_MASK) != (uint32_t)RESET) - { - /* Set DMAy HIFCR register clear interrupt bits */ - DMAy->HIFCR = (uint32_t)(DMA_IT & RESERVED_MASK); - } - else - { - /* Set DMAy LIFCR register clear interrupt bits */ - DMAy->LIFCR = (uint32_t)(DMA_IT & RESERVED_MASK); - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c deleted file mode 100644 index bcb597139..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c +++ /dev/null @@ -1,306 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_exti.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the EXTI peripheral: - * - Initialization and Configuration - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * EXTI features - * =================================================================== - * - * External interrupt/event lines are mapped as following: - * 1- All available GPIO pins are connected to the 16 external - * interrupt/event lines from EXTI0 to EXTI15. - * 2- EXTI line 16 is connected to the PVD Output - * 3- EXTI line 17 is connected to the RTC Alarm event - * 4- EXTI line 18 is connected to the USB OTG FS Wakeup from suspend event - * 5- EXTI line 19 is connected to the Ethernet Wakeup event - * 6- EXTI line 20 is connected to the USB OTG HS (configured in FS) Wakeup event - * 7- EXTI line 21 is connected to the RTC Tamper and Time Stamp events - * 8- EXTI line 22 is connected to the RTC Wakeup event - * - * =================================================================== - * How to use this driver - * =================================================================== - * - * In order to use an I/O pin as an external interrupt source, follow - * steps below: - * 1- Configure the I/O in input mode using GPIO_Init() - * 2- Select the input source pin for the EXTI line using SYSCFG_EXTILineConfig() - * 3- Select the mode(interrupt, event) and configure the trigger - * selection (Rising, falling or both) using EXTI_Init() - * 4- Configure NVIC IRQ channel mapped to the EXTI line using NVIC_Init() - * - * @note SYSCFG APB clock must be enabled to get write access to SYSCFG_EXTICRx - * registers using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_exti.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup EXTI - * @brief EXTI driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -#define EXTI_LINENONE ((uint32_t)0x00000) /* No interrupt selected */ - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup EXTI_Private_Functions - * @{ - */ - -/** @defgroup EXTI_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the EXTI peripheral registers to their default reset values. - * @param None - * @retval None - */ -void EXTI_DeInit(void) -{ - EXTI->IMR = 0x00000000; - EXTI->EMR = 0x00000000; - EXTI->RTSR = 0x00000000; - EXTI->FTSR = 0x00000000; - EXTI->PR = 0x007FFFFF; -} - -/** - * @brief Initializes the EXTI peripheral according to the specified - * parameters in the EXTI_InitStruct. - * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure - * that contains the configuration information for the EXTI peripheral. - * @retval None - */ -void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct) -{ - uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode)); - assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger)); - assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line)); - assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd)); - - tmp = (uint32_t)EXTI_BASE; - - if (EXTI_InitStruct->EXTI_LineCmd != DISABLE) - { - /* Clear EXTI line configuration */ - EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line; - EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line; - - tmp += EXTI_InitStruct->EXTI_Mode; - - *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; - - /* Clear Rising Falling edge configuration */ - EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line; - EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line; - - /* Select the trigger for the selected external interrupts */ - if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling) - { - /* Rising Falling edge */ - EXTI->RTSR |= EXTI_InitStruct->EXTI_Line; - EXTI->FTSR |= EXTI_InitStruct->EXTI_Line; - } - else - { - tmp = (uint32_t)EXTI_BASE; - tmp += EXTI_InitStruct->EXTI_Trigger; - - *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; - } - } - else - { - tmp += EXTI_InitStruct->EXTI_Mode; - - /* Disable the selected external lines */ - *(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line; - } -} - -/** - * @brief Fills each EXTI_InitStruct member with its reset value. - * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct) -{ - EXTI_InitStruct->EXTI_Line = EXTI_LINENONE; - EXTI_InitStruct->EXTI_Mode = EXTI_Mode_Interrupt; - EXTI_InitStruct->EXTI_Trigger = EXTI_Trigger_Falling; - EXTI_InitStruct->EXTI_LineCmd = DISABLE; -} - -/** - * @brief Generates a Software interrupt on selected EXTI line. - * @param EXTI_Line: specifies the EXTI line on which the software interrupt - * will be generated. - * This parameter can be any combination of EXTI_Linex where x can be (0..22) - * @retval None - */ -void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line) -{ - /* Check the parameters */ - assert_param(IS_EXTI_LINE(EXTI_Line)); - - EXTI->SWIER |= EXTI_Line; -} - -/** - * @} - */ - -/** @defgroup EXTI_Group2 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Checks whether the specified EXTI line flag is set or not. - * @param EXTI_Line: specifies the EXTI line flag to check. - * This parameter can be EXTI_Linex where x can be(0..22) - * @retval The new state of EXTI_Line (SET or RESET). - */ -FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_GET_EXTI_LINE(EXTI_Line)); - - if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the EXTI's line pending flags. - * @param EXTI_Line: specifies the EXTI lines flags to clear. - * This parameter can be any combination of EXTI_Linex where x can be (0..22) - * @retval None - */ -void EXTI_ClearFlag(uint32_t EXTI_Line) -{ - /* Check the parameters */ - assert_param(IS_EXTI_LINE(EXTI_Line)); - - EXTI->PR = EXTI_Line; -} - -/** - * @brief Checks whether the specified EXTI line is asserted or not. - * @param EXTI_Line: specifies the EXTI line to check. - * This parameter can be EXTI_Linex where x can be(0..22) - * @retval The new state of EXTI_Line (SET or RESET). - */ -ITStatus EXTI_GetITStatus(uint32_t EXTI_Line) -{ - ITStatus bitstatus = RESET; - uint32_t enablestatus = 0; - /* Check the parameters */ - assert_param(IS_GET_EXTI_LINE(EXTI_Line)); - - enablestatus = EXTI->IMR & EXTI_Line; - if (((EXTI->PR & EXTI_Line) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the EXTI's line pending bits. - * @param EXTI_Line: specifies the EXTI lines to clear. - * This parameter can be any combination of EXTI_Linex where x can be (0..22) - * @retval None - */ -void EXTI_ClearITPendingBit(uint32_t EXTI_Line) -{ - /* Check the parameters */ - assert_param(IS_EXTI_LINE(EXTI_Line)); - - EXTI->PR = EXTI_Line; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_flash.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_flash.c deleted file mode 100644 index a3bce02ec..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_flash.c +++ /dev/null @@ -1,1054 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_flash.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the FLASH peripheral: - * - FLASH Interface configuration - * - FLASH Memory Programming - * - Option Bytes Programming - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * - * This driver provides functions to configure and program the FLASH - * memory of all STM32F4xx devices. - * These functions are split in 4 groups: - * - * 1. FLASH Interface configuration functions: this group includes the - * management of the following features: - * - Set the latency - * - Enable/Disable the prefetch buffer - * - Enable/Disable the Instruction cache and the Data cache - * - Reset the Instruction cache and the Data cache - * - * 2. FLASH Memory Programming functions: this group includes all needed - * functions to erase and program the main memory: - * - Lock and Unlock the FLASH interface - * - Erase function: Erase sector, erase all sectors - * - Program functions: byte, half word, word and double word - * - * 3. Option Bytes Programming functions: this group includes all needed - * functions to manage the Option Bytes: - * - Set/Reset the write protection - * - Set the Read protection Level - * - Set the BOR level - * - Program the user Option Bytes - * - Launch the Option Bytes loader - * - * 4. Interrupts and flags management functions: this group - * includes all needed functions to: - * - Enable/Disable the FLASH interrupt sources - * - Get flags status - * - Clear flags - * - Get FLASH operation status - * - Wait for last FLASH operation - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_flash.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup FLASH - * @brief FLASH driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define SECTOR_MASK ((uint32_t)0xFFFFFF07) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup FLASH_Private_Functions - * @{ - */ - -/** @defgroup FLASH_Group1 FLASH Interface configuration functions - * @brief FLASH Interface configuration functions - * - -@verbatim - =============================================================================== - FLASH Interface configuration functions - =============================================================================== - - This group includes the following functions: - - void FLASH_SetLatency(uint32_t FLASH_Latency) - To correctly read data from FLASH memory, the number of wait states (LATENCY) - must be correctly programmed according to the frequency of the CPU clock - (HCLK) and the supply voltage of the device. - +-------------------------------------------------------------------------------------+ - | Latency | HCLK clock frequency (MHz) | - | |---------------------------------------------------------------------| - | | voltage range | voltage range | voltage range | voltage range | - | | 2.7 V - 3.6 V | 2.4 V - 2.7 V | 2.1 V - 2.4 V | 1.8 V - 2.1 V | - |---------------|----------------|----------------|-----------------|-----------------| - |0WS(1CPU cycle)|0 < HCLK <= 30 |0 < HCLK <= 24 |0 < HCLK <= 18 |0 < HCLK <= 16 | - |---------------|----------------|----------------|-----------------|-----------------| - |1WS(2CPU cycle)|30 < HCLK <= 60 |24 < HCLK <= 48 |18 < HCLK <= 36 |16 < HCLK <= 32 | - |---------------|----------------|----------------|-----------------|-----------------| - |2WS(3CPU cycle)|60 < HCLK <= 90 |48 < HCLK <= 72 |36 < HCLK <= 54 |32 < HCLK <= 48 | - |---------------|----------------|----------------|-----------------|-----------------| - |3WS(4CPU cycle)|90 < HCLK <= 120|72 < HCLK <= 96 |54 < HCLK <= 72 |48 < HCLK <= 64 | - |---------------|----------------|----------------|-----------------|-----------------| - |4WS(5CPU cycle)| NA |96 < HCLK <= 120|72 < HCLK <= 90 |64 < HCLK <= 80 | - |---------------|----------------|----------------|-----------------|-----------------| - |5WS(6CPU cycle)| NA | NA |90 < HCLK <= 108 |80 < HCLK <= 96 | - |---------------|----------------|----------------|-----------------|-----------------| - |6WS(7CPU cycle)| NA | NA |108 < HCLK <= 120|96 < HCLK <= 112 | - |---------------|----------------|----------------|-----------------|-----------------| - |7WS(8CPU cycle)| NA | NA | NA |112 < HCLK <= 120| - |***************|****************|****************|*****************|*****************|*****************************+ - | | voltage range | voltage range | voltage range | voltage range | voltage range 2.7 V - 3.6 V | - | | 2.7 V - 3.6 V | 2.4 V - 2.7 V | 2.1 V - 2.4 V | 1.8 V - 2.1 V | with External Vpp = 9V | - |---------------|----------------|----------------|-----------------|-----------------|-----------------------------| - |Max Parallelism| x32 | x16 | x8 | x64 | - |---------------|----------------|----------------|-----------------|-----------------|-----------------------------| - |PSIZE[1:0] | 10 | 01 | 00 | 11 | - +-------------------------------------------------------------------------------------------------------------------+ - - - void FLASH_PrefetchBufferCmd(FunctionalState NewState) - - void FLASH_InstructionCacheCmd(FunctionalState NewState) - - void FLASH_DataCacheCmd(FunctionalState NewState) - - void FLASH_InstructionCacheReset(void) - - void FLASH_DataCacheReset(void) - - The unlock sequence is not needed for these functions. - -@endverbatim - * @{ - */ - -/** - * @brief Sets the code latency value. - * @param FLASH_Latency: specifies the FLASH Latency value. - * This parameter can be one of the following values: - * @arg FLASH_Latency_0: FLASH Zero Latency cycle - * @arg FLASH_Latency_1: FLASH One Latency cycle - * @arg FLASH_Latency_2: FLASH Two Latency cycles - * @arg FLASH_Latency_3: FLASH Three Latency cycles - * @arg FLASH_Latency_4: FLASH Four Latency cycles - * @arg FLASH_Latency_5: FLASH Five Latency cycles - * @arg FLASH_Latency_6: FLASH Six Latency cycles - * @arg FLASH_Latency_7: FLASH Seven Latency cycles - * @retval None - */ -void FLASH_SetLatency(uint32_t FLASH_Latency) -{ - /* Check the parameters */ - assert_param(IS_FLASH_LATENCY(FLASH_Latency)); - - /* Perform Byte access to FLASH_ACR[8:0] to set the Latency value */ - *(__IO uint8_t *)ACR_BYTE0_ADDRESS = (uint8_t)FLASH_Latency; -} - -/** - * @brief Enables or disables the Prefetch Buffer. - * @param NewState: new state of the Prefetch Buffer. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FLASH_PrefetchBufferCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Enable or disable the Prefetch Buffer */ - if(NewState != DISABLE) - { - FLASH->ACR |= FLASH_ACR_PRFTEN; - } - else - { - FLASH->ACR &= (~FLASH_ACR_PRFTEN); - } -} - -/** - * @brief Enables or disables the Instruction Cache feature. - * @param NewState: new state of the Instruction Cache. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FLASH_InstructionCacheCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if(NewState != DISABLE) - { - FLASH->ACR |= FLASH_ACR_ICEN; - } - else - { - FLASH->ACR &= (~FLASH_ACR_ICEN); - } -} - -/** - * @brief Enables or disables the Data Cache feature. - * @param NewState: new state of the Data Cache. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FLASH_DataCacheCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if(NewState != DISABLE) - { - FLASH->ACR |= FLASH_ACR_DCEN; - } - else - { - FLASH->ACR &= (~FLASH_ACR_DCEN); - } -} - -/** - * @brief Resets the Instruction Cache. - * @note This function must be used only when the Instruction Cache is disabled. - * @param None - * @retval None - */ -void FLASH_InstructionCacheReset(void) -{ - FLASH->ACR |= FLASH_ACR_ICRST; -} - -/** - * @brief Resets the Data Cache. - * @note This function must be used only when the Data Cache is disabled. - * @param None - * @retval None - */ -void FLASH_DataCacheReset(void) -{ - FLASH->ACR |= FLASH_ACR_DCRST; -} - -/** - * @} - */ - -/** @defgroup FLASH_Group2 FLASH Memory Programming functions - * @brief FLASH Memory Programming functions - * -@verbatim - =============================================================================== - FLASH Memory Programming functions - =============================================================================== - - This group includes the following functions: - - void FLASH_Unlock(void) - - void FLASH_Lock(void) - - FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange) - - FLASH_Status FLASH_EraseAllSectors(uint8_t VoltageRange) - - FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data) - - FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data) - - FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) - - FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data) - - Any operation of erase or program should follow these steps: - 1. Call the FLASH_Unlock() function to enable the FLASH control register access - - 2. Call the desired function to erase sector(s) or program data - - 3. Call the FLASH_Lock() function to disable the FLASH control register access - (recommended to protect the FLASH memory against possible unwanted operation) - -@endverbatim - * @{ - */ - -/** - * @brief Unlocks the FLASH control register access - * @param None - * @retval None - */ -void FLASH_Unlock(void) -{ - if((FLASH->CR & FLASH_CR_LOCK) != RESET) - { - /* Authorize the FLASH Registers access */ - FLASH->KEYR = FLASH_KEY1; - FLASH->KEYR = FLASH_KEY2; - } -} - -/** - * @brief Locks the FLASH control register access - * @param None - * @retval None - */ -void FLASH_Lock(void) -{ - /* Set the LOCK Bit to lock the FLASH Registers access */ - FLASH->CR |= FLASH_CR_LOCK; -} - -/** - * @brief Erases a specified FLASH Sector. - * - * @param FLASH_Sector: The Sector number to be erased. - * This parameter can be a value between FLASH_Sector_0 and FLASH_Sector_11 - * - * @param VoltageRange: The device voltage range which defines the erase parallelism. - * This parameter can be one of the following values: - * @arg VoltageRange_1: when the device voltage range is 1.8V to 2.1V, - * the operation will be done by byte (8-bit) - * @arg VoltageRange_2: when the device voltage range is 2.1V to 2.7V, - * the operation will be done by half word (16-bit) - * @arg VoltageRange_3: when the device voltage range is 2.7V to 3.6V, - * the operation will be done by word (32-bit) - * @arg VoltageRange_4: when the device voltage range is 2.7V to 3.6V + External Vpp, - * the operation will be done by double word (64-bit) - * - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, - * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. - */ -FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange) -{ - uint32_t tmp_psize = 0x0; - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_FLASH_SECTOR(FLASH_Sector)); - assert_param(IS_VOLTAGERANGE(VoltageRange)); - - if(VoltageRange == VoltageRange_1) - { - tmp_psize = FLASH_PSIZE_BYTE; - } - else if(VoltageRange == VoltageRange_2) - { - tmp_psize = FLASH_PSIZE_HALF_WORD; - } - else if(VoltageRange == VoltageRange_3) - { - tmp_psize = FLASH_PSIZE_WORD; - } - else - { - tmp_psize = FLASH_PSIZE_DOUBLE_WORD; - } - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to erase the sector */ - FLASH->CR &= CR_PSIZE_MASK; - FLASH->CR |= tmp_psize; - FLASH->CR &= SECTOR_MASK; - FLASH->CR |= FLASH_CR_SER | FLASH_Sector; - FLASH->CR |= FLASH_CR_STRT; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(); - - /* if the erase operation is completed, disable the SER Bit */ - FLASH->CR &= (~FLASH_CR_SER); - FLASH->CR &= SECTOR_MASK; - } - /* Return the Erase Status */ - return status; -} - -/** - * @brief Erases all FLASH Sectors. - * - * @param VoltageRange: The device voltage range which defines the erase parallelism. - * This parameter can be one of the following values: - * @arg VoltageRange_1: when the device voltage range is 1.8V to 2.1V, - * the operation will be done by byte (8-bit) - * @arg VoltageRange_2: when the device voltage range is 2.1V to 2.7V, - * the operation will be done by half word (16-bit) - * @arg VoltageRange_3: when the device voltage range is 2.7V to 3.6V, - * the operation will be done by word (32-bit) - * @arg VoltageRange_4: when the device voltage range is 2.7V to 3.6V + External Vpp, - * the operation will be done by double word (64-bit) - * - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, - * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. - */ -FLASH_Status FLASH_EraseAllSectors(uint8_t VoltageRange) -{ - uint32_t tmp_psize = 0x0; - FLASH_Status status = FLASH_COMPLETE; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(); - assert_param(IS_VOLTAGERANGE(VoltageRange)); - - if(VoltageRange == VoltageRange_1) - { - tmp_psize = FLASH_PSIZE_BYTE; - } - else if(VoltageRange == VoltageRange_2) - { - tmp_psize = FLASH_PSIZE_HALF_WORD; - } - else if(VoltageRange == VoltageRange_3) - { - tmp_psize = FLASH_PSIZE_WORD; - } - else - { - tmp_psize = FLASH_PSIZE_DOUBLE_WORD; - } - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to erase all sectors */ - FLASH->CR &= CR_PSIZE_MASK; - FLASH->CR |= tmp_psize; - FLASH->CR |= FLASH_CR_MER; - FLASH->CR |= FLASH_CR_STRT; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(); - - /* if the erase operation is completed, disable the MER Bit */ - FLASH->CR &= (~FLASH_CR_MER); - - } - /* Return the Erase Status */ - return status; -} - -/** - * @brief Programs a double word (64-bit) at a specified address. - * @note This function must be used when the device voltage range is from - * 2.7V to 3.6V and an External Vpp is present. - * @param Address: specifies the address to be programmed. - * @param Data: specifies the data to be programmed. - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, - * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. - */ -FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_FLASH_ADDRESS(Address)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new data */ - FLASH->CR &= CR_PSIZE_MASK; - FLASH->CR |= FLASH_PSIZE_DOUBLE_WORD; - FLASH->CR |= FLASH_CR_PG; - - *(__IO uint64_t*)Address = Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(); - - /* if the program operation is completed, disable the PG Bit */ - FLASH->CR &= (~FLASH_CR_PG); - } - /* Return the Program Status */ - return status; -} - -/** - * @brief Programs a word (32-bit) at a specified address. - * @param Address: specifies the address to be programmed. - * This parameter can be any address in Program memory zone or in OTP zone. - * @note This function must be used when the device voltage range is from 2.7V to 3.6V. - * @param Data: specifies the data to be programmed. - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, - * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. - */ -FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_FLASH_ADDRESS(Address)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new data */ - FLASH->CR &= CR_PSIZE_MASK; - FLASH->CR |= FLASH_PSIZE_WORD; - FLASH->CR |= FLASH_CR_PG; - - *(__IO uint32_t*)Address = Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(); - - /* if the program operation is completed, disable the PG Bit */ - FLASH->CR &= (~FLASH_CR_PG); - } - /* Return the Program Status */ - return status; -} - -/** - * @brief Programs a half word (16-bit) at a specified address. - * @note This function must be used when the device voltage range is from 2.1V to 3.6V. - * @param Address: specifies the address to be programmed. - * This parameter can be any address in Program memory zone or in OTP zone. - * @param Data: specifies the data to be programmed. - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, - * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. - */ -FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_FLASH_ADDRESS(Address)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new data */ - FLASH->CR &= CR_PSIZE_MASK; - FLASH->CR |= FLASH_PSIZE_HALF_WORD; - FLASH->CR |= FLASH_CR_PG; - - *(__IO uint16_t*)Address = Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(); - - /* if the program operation is completed, disable the PG Bit */ - FLASH->CR &= (~FLASH_CR_PG); - } - /* Return the Program Status */ - return status; -} - -/** - * @brief Programs a byte (8-bit) at a specified address. - * @note This function can be used within all the device supply voltage ranges. - * @param Address: specifies the address to be programmed. - * This parameter can be any address in Program memory zone or in OTP zone. - * @param Data: specifies the data to be programmed. - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, - * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. - */ -FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_FLASH_ADDRESS(Address)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(); - - if(status == FLASH_COMPLETE) - { - /* if the previous operation is completed, proceed to program the new data */ - FLASH->CR &= CR_PSIZE_MASK; - FLASH->CR |= FLASH_PSIZE_BYTE; - FLASH->CR |= FLASH_CR_PG; - - *(__IO uint8_t*)Address = Data; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(); - - /* if the program operation is completed, disable the PG Bit */ - FLASH->CR &= (~FLASH_CR_PG); - } - - /* Return the Program Status */ - return status; -} - -/** - * @} - */ - -/** @defgroup FLASH_Group3 Option Bytes Programming functions - * @brief Option Bytes Programming functions - * -@verbatim - =============================================================================== - Option Bytes Programming functions - =============================================================================== - - This group includes the following functions: - - void FLASH_OB_Unlock(void) - - void FLASH_OB_Lock(void) - - void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) - - void FLASH_OB_RDPConfig(uint8_t OB_RDP) - - void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) - - void FLASH_OB_BORConfig(uint8_t OB_BOR) - - FLASH_Status FLASH_ProgramOTP(uint32_t Address, uint32_t Data) - - FLASH_Status FLASH_OB_Launch(void) - - uint32_t FLASH_OB_GetUser(void) - - uint8_t FLASH_OB_GetWRP(void) - - uint8_t FLASH_OB_GetRDP(void) - - uint8_t FLASH_OB_GetBOR(void) - - Any operation of erase or program should follow these steps: - 1. Call the FLASH_OB_Unlock() function to enable the FLASH option control register access - - 2. Call one or several functions to program the desired Option Bytes: - - void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) => to Enable/Disable - the desired sector write protection - - void FLASH_OB_RDPConfig(uint8_t OB_RDP) => to set the desired read Protection Level - - void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) => to configure - the user Option Bytes. - - void FLASH_OB_BORConfig(uint8_t OB_BOR) => to set the BOR Level - - 3. Once all needed Option Bytes to be programmed are correctly written, call the - FLASH_OB_Launch() function to launch the Option Bytes programming process. - - @note When changing the IWDG mode from HW to SW or from SW to HW, a system - reset is needed to make the change effective. - - 4. Call the FLASH_OB_Lock() function to disable the FLASH option control register - access (recommended to protect the Option Bytes against possible unwanted operations) - -@endverbatim - * @{ - */ - -/** - * @brief Unlocks the FLASH Option Control Registers access. - * @param None - * @retval None - */ -void FLASH_OB_Unlock(void) -{ - if((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != RESET) - { - /* Authorizes the Option Byte register programming */ - FLASH->OPTKEYR = FLASH_OPT_KEY1; - FLASH->OPTKEYR = FLASH_OPT_KEY2; - } -} - -/** - * @brief Locks the FLASH Option Control Registers access. - * @param None - * @retval None - */ -void FLASH_OB_Lock(void) -{ - /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */ - FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK; -} - -/** - * @brief Enables or disables the write protection of the desired sectors - * @param OB_WRP: specifies the sector(s) to be write protected or unprotected. - * This parameter can be one of the following values: - * @arg OB_WRP: A value between OB_WRP_Sector0 and OB_WRP_Sector11 - * @arg OB_WRP_Sector_All - * @param Newstate: new state of the Write Protection. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_OB_WRP(OB_WRP)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - status = FLASH_WaitForLastOperation(); - - if(status == FLASH_COMPLETE) - { - if(NewState != DISABLE) - { - *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS &= (~OB_WRP); - } - else - { - *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS |= (uint16_t)OB_WRP; - } - } -} - -/** - * @brief Sets the read protection level. - * @param OB_RDP: specifies the read protection level. - * This parameter can be one of the following values: - * @arg OB_RDP_Level_0: No protection - * @arg OB_RDP_Level_1: Read protection of the memory - * @arg OB_RDP_Level_2: Full chip protection - * - * !!!Warning!!! When enabling OB_RDP level 2 it's no more possible to go back to level 1 or 0 - * - * @retval None - */ -void FLASH_OB_RDPConfig(uint8_t OB_RDP) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_OB_RDP(OB_RDP)); - - status = FLASH_WaitForLastOperation(); - - if(status == FLASH_COMPLETE) - { - *(__IO uint8_t*)OPTCR_BYTE1_ADDRESS = OB_RDP; - - } -} - -/** - * @brief Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY. - * @param OB_IWDG: Selects the IWDG mode - * This parameter can be one of the following values: - * @arg OB_IWDG_SW: Software IWDG selected - * @arg OB_IWDG_HW: Hardware IWDG selected - * @param OB_STOP: Reset event when entering STOP mode. - * This parameter can be one of the following values: - * @arg OB_STOP_NoRST: No reset generated when entering in STOP - * @arg OB_STOP_RST: Reset generated when entering in STOP - * @param OB_STDBY: Reset event when entering Standby mode. - * This parameter can be one of the following values: - * @arg OB_STDBY_NoRST: No reset generated when entering in STANDBY - * @arg OB_STDBY_RST: Reset generated when entering in STANDBY - * @retval None - */ -void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) -{ - uint8_t optiontmp = 0xFF; - FLASH_Status status = FLASH_COMPLETE; - - /* Check the parameters */ - assert_param(IS_OB_IWDG_SOURCE(OB_IWDG)); - assert_param(IS_OB_STOP_SOURCE(OB_STOP)); - assert_param(IS_OB_STDBY_SOURCE(OB_STDBY)); - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(); - - if(status == FLASH_COMPLETE) - { - /* Mask OPTLOCK, OPTSTRT and BOR_LEV bits */ - optiontmp = (uint8_t)((*(__IO uint8_t *)OPTCR_BYTE0_ADDRESS) & (uint8_t)0x0F); - - /* Update User Option Byte */ - *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS = OB_IWDG | (uint8_t)(OB_STDBY | (uint8_t)(OB_STOP | ((uint8_t)optiontmp))); - } -} - -/** - * @brief Sets the BOR Level. - * @param OB_BOR: specifies the Option Bytes BOR Reset Level. - * This parameter can be one of the following values: - * @arg OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V - * @arg OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V - * @arg OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V - * @arg OB_BOR_OFF: Supply voltage ranges from 1.62 to 2.1 V - * @retval None - */ -void FLASH_OB_BORConfig(uint8_t OB_BOR) -{ - /* Check the parameters */ - assert_param(IS_OB_BOR(OB_BOR)); - - /* Set the BOR Level */ - *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS &= (~FLASH_OPTCR_BOR_LEV); - *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= OB_BOR; - -} - -/** - * @brief Launch the option byte loading. - * @param None - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, - * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. - */ -FLASH_Status FLASH_OB_Launch(void) -{ - FLASH_Status status = FLASH_COMPLETE; - - /* Set the OPTSTRT bit in OPTCR register */ - *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= FLASH_OPTCR_OPTSTRT; - - /* Wait for last operation to be completed */ - status = FLASH_WaitForLastOperation(); - - return status; -} - -/** - * @brief Returns the FLASH User Option Bytes values. - * @param None - * @retval The FLASH User Option Bytes values: IWDG_SW(Bit0), RST_STOP(Bit1) - * and RST_STDBY(Bit2). - */ -uint8_t FLASH_OB_GetUser(void) -{ - /* Return the User Option Byte */ - return (uint8_t)(FLASH->OPTCR >> 5); -} - -/** - * @brief Returns the FLASH Write Protection Option Bytes value. - * @param None - * @retval The FLASH Write Protection Option Bytes value - */ -uint16_t FLASH_OB_GetWRP(void) -{ - /* Return the FLASH write protection Register value */ - return (*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS)); -} - -/** - * @brief Returns the FLASH Read Protection level. - * @param None - * @retval FLASH ReadOut Protection Status: - * - SET, when OB_RDP_Level_1 or OB_RDP_Level_2 is set - * - RESET, when OB_RDP_Level_0 is set - */ -FlagStatus FLASH_OB_GetRDP(void) -{ - FlagStatus readstatus = RESET; - - if ((*(__IO uint8_t*)(OPTCR_BYTE1_ADDRESS) != (uint8_t)OB_RDP_Level_0)) - { - readstatus = SET; - } - else - { - readstatus = RESET; - } - return readstatus; -} - -/** - * @brief Returns the FLASH BOR level. - * @param None - * @retval The FLASH BOR level: - * - OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V - * - OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V - * - OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V - * - OB_BOR_OFF : Supply voltage ranges from 1.62 to 2.1 V - */ -uint8_t FLASH_OB_GetBOR(void) -{ - /* Return the FLASH BOR level */ - return (uint8_t)(*(__IO uint8_t *)(OPTCR_BYTE0_ADDRESS) & (uint8_t)0x0C); -} - -/** - * @} - */ - -/** @defgroup FLASH_Group4 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified FLASH interrupts. - * @param FLASH_IT: specifies the FLASH interrupt sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg FLASH_IT_ERR: FLASH Error Interrupt - * @arg FLASH_IT_EOP: FLASH end of operation Interrupt - * @retval None - */ -void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FLASH_IT(FLASH_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if(NewState != DISABLE) - { - /* Enable the interrupt sources */ - FLASH->CR |= FLASH_IT; - } - else - { - /* Disable the interrupt sources */ - FLASH->CR &= ~(uint32_t)FLASH_IT; - } -} - -/** - * @brief Checks whether the specified FLASH flag is set or not. - * @param FLASH_FLAG: specifies the FLASH flag to check. - * This parameter can be one of the following values: - * @arg FLASH_FLAG_EOP: FLASH End of Operation flag - * @arg FLASH_FLAG_OPERR: FLASH operation Error flag - * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag - * @arg FLASH_FLAG_PGAERR: FLASH Programming Alignment error flag - * @arg FLASH_FLAG_PGPERR: FLASH Programming Parallelism error flag - * @arg FLASH_FLAG_PGSERR: FLASH Programming Sequence error flag - * @arg FLASH_FLAG_BSY: FLASH Busy flag - * @retval The new state of FLASH_FLAG (SET or RESET). - */ -FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)); - - if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the new state of FLASH_FLAG (SET or RESET) */ - return bitstatus; -} - -/** - * @brief Clears the FLASH's pending flags. - * @param FLASH_FLAG: specifies the FLASH flags to clear. - * This parameter can be any combination of the following values: - * @arg FLASH_FLAG_EOP: FLASH End of Operation flag - * @arg FLASH_FLAG_OPERR: FLASH operation Error flag - * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag - * @arg FLASH_FLAG_PGAERR: FLASH Programming Alignment error flag - * @arg FLASH_FLAG_PGPERR: FLASH Programming Parallelism error flag - * @arg FLASH_FLAG_PGSERR: FLASH Programming Sequence error flag - * @retval None - */ -void FLASH_ClearFlag(uint32_t FLASH_FLAG) -{ - /* Check the parameters */ - assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)); - - /* Clear the flags */ - FLASH->SR = FLASH_FLAG; -} - -/** - * @brief Returns the FLASH Status. - * @param None - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, - * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. - */ -FLASH_Status FLASH_GetStatus(void) -{ - FLASH_Status flashstatus = FLASH_COMPLETE; - - if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY) - { - flashstatus = FLASH_BUSY; - } - else - { - if((FLASH->SR & FLASH_FLAG_WRPERR) != (uint32_t)0x00) - { - flashstatus = FLASH_ERROR_WRP; - } - else - { - if((FLASH->SR & (uint32_t)0xEF) != (uint32_t)0x00) - { - flashstatus = FLASH_ERROR_PROGRAM; - } - else - { - if((FLASH->SR & FLASH_FLAG_OPERR) != (uint32_t)0x00) - { - flashstatus = FLASH_ERROR_OPERATION; - } - else - { - flashstatus = FLASH_COMPLETE; - } - } - } - } - /* Return the FLASH Status */ - return flashstatus; -} - -/** - * @brief Waits for a FLASH operation to complete. - * @param None - * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, - * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. - */ -FLASH_Status FLASH_WaitForLastOperation(void) -{ - __IO FLASH_Status status = FLASH_COMPLETE; - - /* Check for the FLASH Status */ - status = FLASH_GetStatus(); - - /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset. - Even if the FLASH operation fails, the BUSY flag will be reset and an error - flag will be set */ - while(status == FLASH_BUSY) - { - status = FLASH_GetStatus(); - } - /* Return the operation status */ - return status; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_fsmc.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_fsmc.c deleted file mode 100644 index 788e627aa..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_fsmc.c +++ /dev/null @@ -1,982 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_fsmc.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the FSMC peripheral: - * - Interface with SRAM, PSRAM, NOR and OneNAND memories - * - Interface with NAND memories - * - Interface with 16-bit PC Card compatible memories - * - Interrupts and flags management - * - ****************************************************************************** - - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_fsmc.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup FSMC - * @brief FSMC driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* --------------------- FSMC registers bit mask ---------------------------- */ -/* FSMC BCRx Mask */ -#define BCR_MBKEN_SET ((uint32_t)0x00000001) -#define BCR_MBKEN_RESET ((uint32_t)0x000FFFFE) -#define BCR_FACCEN_SET ((uint32_t)0x00000040) - -/* FSMC PCRx Mask */ -#define PCR_PBKEN_SET ((uint32_t)0x00000004) -#define PCR_PBKEN_RESET ((uint32_t)0x000FFFFB) -#define PCR_ECCEN_SET ((uint32_t)0x00000040) -#define PCR_ECCEN_RESET ((uint32_t)0x000FFFBF) -#define PCR_MEMORYTYPE_NAND ((uint32_t)0x00000008) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup FSMC_Private_Functions - * @{ - */ - -/** @defgroup FSMC_Group1 NOR/SRAM Controller functions - * @brief NOR/SRAM Controller functions - * -@verbatim - =============================================================================== - NOR/SRAM Controller functions - =============================================================================== - - The following sequence should be followed to configure the FSMC to interface with - SRAM, PSRAM, NOR or OneNAND memory connected to the NOR/SRAM Bank: - - 1. Enable the clock for the FSMC and associated GPIOs using the following functions: - RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE); - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); - - 2. FSMC pins configuration - - Connect the involved FSMC pins to AF12 using the following function - GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_FSMC); - - Configure these FSMC pins in alternate function mode by calling the function - GPIO_Init(); - - 3. Declare a FSMC_NORSRAMInitTypeDef structure, for example: - FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; - and fill the FSMC_NORSRAMInitStructure variable with the allowed values of - the structure member. - - 4. Initialize the NOR/SRAM Controller by calling the function - FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); - - 5. Then enable the NOR/SRAM Bank, for example: - FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE); - - 6. At this stage you can read/write from/to the memory connected to the NOR/SRAM Bank. - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the FSMC NOR/SRAM Banks registers to their default - * reset values. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank1_NORSRAM1: FSMC Bank1 NOR/SRAM1 - * @arg FSMC_Bank1_NORSRAM2: FSMC Bank1 NOR/SRAM2 - * @arg FSMC_Bank1_NORSRAM3: FSMC Bank1 NOR/SRAM3 - * @arg FSMC_Bank1_NORSRAM4: FSMC Bank1 NOR/SRAM4 - * @retval None - */ -void FSMC_NORSRAMDeInit(uint32_t FSMC_Bank) -{ - /* Check the parameter */ - assert_param(IS_FSMC_NORSRAM_BANK(FSMC_Bank)); - - /* FSMC_Bank1_NORSRAM1 */ - if(FSMC_Bank == FSMC_Bank1_NORSRAM1) - { - FSMC_Bank1->BTCR[FSMC_Bank] = 0x000030DB; - } - /* FSMC_Bank1_NORSRAM2, FSMC_Bank1_NORSRAM3 or FSMC_Bank1_NORSRAM4 */ - else - { - FSMC_Bank1->BTCR[FSMC_Bank] = 0x000030D2; - } - FSMC_Bank1->BTCR[FSMC_Bank + 1] = 0x0FFFFFFF; - FSMC_Bank1E->BWTR[FSMC_Bank] = 0x0FFFFFFF; -} - -/** - * @brief Initializes the FSMC NOR/SRAM Banks according to the specified - * parameters in the FSMC_NORSRAMInitStruct. - * @param FSMC_NORSRAMInitStruct : pointer to a FSMC_NORSRAMInitTypeDef structure - * that contains the configuration information for the FSMC NOR/SRAM - * specified Banks. - * @retval None - */ -void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct) -{ - /* Check the parameters */ - assert_param(IS_FSMC_NORSRAM_BANK(FSMC_NORSRAMInitStruct->FSMC_Bank)); - assert_param(IS_FSMC_MUX(FSMC_NORSRAMInitStruct->FSMC_DataAddressMux)); - assert_param(IS_FSMC_MEMORY(FSMC_NORSRAMInitStruct->FSMC_MemoryType)); - assert_param(IS_FSMC_MEMORY_WIDTH(FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth)); - assert_param(IS_FSMC_BURSTMODE(FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode)); - assert_param(IS_FSMC_ASYNWAIT(FSMC_NORSRAMInitStruct->FSMC_AsynchronousWait)); - assert_param(IS_FSMC_WAIT_POLARITY(FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity)); - assert_param(IS_FSMC_WRAP_MODE(FSMC_NORSRAMInitStruct->FSMC_WrapMode)); - assert_param(IS_FSMC_WAIT_SIGNAL_ACTIVE(FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive)); - assert_param(IS_FSMC_WRITE_OPERATION(FSMC_NORSRAMInitStruct->FSMC_WriteOperation)); - assert_param(IS_FSMC_WAITE_SIGNAL(FSMC_NORSRAMInitStruct->FSMC_WaitSignal)); - assert_param(IS_FSMC_EXTENDED_MODE(FSMC_NORSRAMInitStruct->FSMC_ExtendedMode)); - assert_param(IS_FSMC_WRITE_BURST(FSMC_NORSRAMInitStruct->FSMC_WriteBurst)); - assert_param(IS_FSMC_ADDRESS_SETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime)); - assert_param(IS_FSMC_ADDRESS_HOLD_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime)); - assert_param(IS_FSMC_DATASETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime)); - assert_param(IS_FSMC_TURNAROUND_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration)); - assert_param(IS_FSMC_CLK_DIV(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision)); - assert_param(IS_FSMC_DATA_LATENCY(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency)); - assert_param(IS_FSMC_ACCESS_MODE(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode)); - - /* Bank1 NOR/SRAM control register configuration */ - FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank] = - (uint32_t)FSMC_NORSRAMInitStruct->FSMC_DataAddressMux | - FSMC_NORSRAMInitStruct->FSMC_MemoryType | - FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth | - FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode | - FSMC_NORSRAMInitStruct->FSMC_AsynchronousWait | - FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity | - FSMC_NORSRAMInitStruct->FSMC_WrapMode | - FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive | - FSMC_NORSRAMInitStruct->FSMC_WriteOperation | - FSMC_NORSRAMInitStruct->FSMC_WaitSignal | - FSMC_NORSRAMInitStruct->FSMC_ExtendedMode | - FSMC_NORSRAMInitStruct->FSMC_WriteBurst; - if(FSMC_NORSRAMInitStruct->FSMC_MemoryType == FSMC_MemoryType_NOR) - { - FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank] |= (uint32_t)BCR_FACCEN_SET; - } - /* Bank1 NOR/SRAM timing register configuration */ - FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank+1] = - (uint32_t)FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime | - (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime << 4) | - (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime << 8) | - (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration << 16) | - (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision << 20) | - (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency << 24) | - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode; - - - /* Bank1 NOR/SRAM timing register for write configuration, if extended mode is used */ - if(FSMC_NORSRAMInitStruct->FSMC_ExtendedMode == FSMC_ExtendedMode_Enable) - { - assert_param(IS_FSMC_ADDRESS_SETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime)); - assert_param(IS_FSMC_ADDRESS_HOLD_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime)); - assert_param(IS_FSMC_DATASETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime)); - assert_param(IS_FSMC_CLK_DIV(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision)); - assert_param(IS_FSMC_DATA_LATENCY(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency)); - assert_param(IS_FSMC_ACCESS_MODE(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode)); - FSMC_Bank1E->BWTR[FSMC_NORSRAMInitStruct->FSMC_Bank] = - (uint32_t)FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime | - (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime << 4 )| - (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime << 8) | - (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision << 20) | - (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency << 24) | - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode; - } - else - { - FSMC_Bank1E->BWTR[FSMC_NORSRAMInitStruct->FSMC_Bank] = 0x0FFFFFFF; - } -} - -/** - * @brief Fills each FSMC_NORSRAMInitStruct member with its default value. - * @param FSMC_NORSRAMInitStruct: pointer to a FSMC_NORSRAMInitTypeDef structure - * which will be initialized. - * @retval None - */ -void FSMC_NORSRAMStructInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct) -{ - /* Reset NOR/SRAM Init structure parameters values */ - FSMC_NORSRAMInitStruct->FSMC_Bank = FSMC_Bank1_NORSRAM1; - FSMC_NORSRAMInitStruct->FSMC_DataAddressMux = FSMC_DataAddressMux_Enable; - FSMC_NORSRAMInitStruct->FSMC_MemoryType = FSMC_MemoryType_SRAM; - FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; - FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; - FSMC_NORSRAMInitStruct->FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; - FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; - FSMC_NORSRAMInitStruct->FSMC_WrapMode = FSMC_WrapMode_Disable; - FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; - FSMC_NORSRAMInitStruct->FSMC_WriteOperation = FSMC_WriteOperation_Enable; - FSMC_NORSRAMInitStruct->FSMC_WaitSignal = FSMC_WaitSignal_Enable; - FSMC_NORSRAMInitStruct->FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; - FSMC_NORSRAMInitStruct->FSMC_WriteBurst = FSMC_WriteBurst_Disable; - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime = 0xF; - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime = 0xF; - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime = 0xFF; - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration = 0xF; - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision = 0xF; - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency = 0xF; - FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode = FSMC_AccessMode_A; - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime = 0xF; - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime = 0xF; - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime = 0xFF; - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_BusTurnAroundDuration = 0xF; - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision = 0xF; - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency = 0xF; - FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode = FSMC_AccessMode_A; -} - -/** - * @brief Enables or disables the specified NOR/SRAM Memory Bank. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank1_NORSRAM1: FSMC Bank1 NOR/SRAM1 - * @arg FSMC_Bank1_NORSRAM2: FSMC Bank1 NOR/SRAM2 - * @arg FSMC_Bank1_NORSRAM3: FSMC Bank1 NOR/SRAM3 - * @arg FSMC_Bank1_NORSRAM4: FSMC Bank1 NOR/SRAM4 - * @param NewState: new state of the FSMC_Bank. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState) -{ - assert_param(IS_FSMC_NORSRAM_BANK(FSMC_Bank)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected NOR/SRAM Bank by setting the PBKEN bit in the BCRx register */ - FSMC_Bank1->BTCR[FSMC_Bank] |= BCR_MBKEN_SET; - } - else - { - /* Disable the selected NOR/SRAM Bank by clearing the PBKEN bit in the BCRx register */ - FSMC_Bank1->BTCR[FSMC_Bank] &= BCR_MBKEN_RESET; - } -} -/** - * @} - */ - -/** @defgroup FSMC_Group2 NAND Controller functions - * @brief NAND Controller functions - * -@verbatim - =============================================================================== - NAND Controller functions - =============================================================================== - - The following sequence should be followed to configure the FSMC to interface with - 8-bit or 16-bit NAND memory connected to the NAND Bank: - - 1. Enable the clock for the FSMC and associated GPIOs using the following functions: - RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE); - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); - - 2. FSMC pins configuration - - Connect the involved FSMC pins to AF12 using the following function - GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_FSMC); - - Configure these FSMC pins in alternate function mode by calling the function - GPIO_Init(); - - 3. Declare a FSMC_NANDInitTypeDef structure, for example: - FSMC_NANDInitTypeDef FSMC_NANDInitStructure; - and fill the FSMC_NANDInitStructure variable with the allowed values of - the structure member. - - 4. Initialize the NAND Controller by calling the function - FSMC_NANDInit(&FSMC_NANDInitStructure); - - 5. Then enable the NAND Bank, for example: - FSMC_NANDCmd(FSMC_Bank3_NAND, ENABLE); - - 6. At this stage you can read/write from/to the memory connected to the NAND Bank. - -@note To enable the Error Correction Code (ECC), you have to use the function - FSMC_NANDECCCmd(FSMC_Bank3_NAND, ENABLE); - and to get the current ECC value you have to use the function - ECCval = FSMC_GetECC(FSMC_Bank3_NAND); - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the FSMC NAND Banks registers to their default reset values. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @retval None - */ -void FSMC_NANDDeInit(uint32_t FSMC_Bank) -{ - /* Check the parameter */ - assert_param(IS_FSMC_NAND_BANK(FSMC_Bank)); - - if(FSMC_Bank == FSMC_Bank2_NAND) - { - /* Set the FSMC_Bank2 registers to their reset values */ - FSMC_Bank2->PCR2 = 0x00000018; - FSMC_Bank2->SR2 = 0x00000040; - FSMC_Bank2->PMEM2 = 0xFCFCFCFC; - FSMC_Bank2->PATT2 = 0xFCFCFCFC; - } - /* FSMC_Bank3_NAND */ - else - { - /* Set the FSMC_Bank3 registers to their reset values */ - FSMC_Bank3->PCR3 = 0x00000018; - FSMC_Bank3->SR3 = 0x00000040; - FSMC_Bank3->PMEM3 = 0xFCFCFCFC; - FSMC_Bank3->PATT3 = 0xFCFCFCFC; - } -} - -/** - * @brief Initializes the FSMC NAND Banks according to the specified parameters - * in the FSMC_NANDInitStruct. - * @param FSMC_NANDInitStruct : pointer to a FSMC_NANDInitTypeDef structure that - * contains the configuration information for the FSMC NAND specified Banks. - * @retval None - */ -void FSMC_NANDInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct) -{ - uint32_t tmppcr = 0x00000000, tmppmem = 0x00000000, tmppatt = 0x00000000; - - /* Check the parameters */ - assert_param( IS_FSMC_NAND_BANK(FSMC_NANDInitStruct->FSMC_Bank)); - assert_param( IS_FSMC_WAIT_FEATURE(FSMC_NANDInitStruct->FSMC_Waitfeature)); - assert_param( IS_FSMC_MEMORY_WIDTH(FSMC_NANDInitStruct->FSMC_MemoryDataWidth)); - assert_param( IS_FSMC_ECC_STATE(FSMC_NANDInitStruct->FSMC_ECC)); - assert_param( IS_FSMC_ECCPAGE_SIZE(FSMC_NANDInitStruct->FSMC_ECCPageSize)); - assert_param( IS_FSMC_TCLR_TIME(FSMC_NANDInitStruct->FSMC_TCLRSetupTime)); - assert_param( IS_FSMC_TAR_TIME(FSMC_NANDInitStruct->FSMC_TARSetupTime)); - assert_param(IS_FSMC_SETUP_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime)); - assert_param(IS_FSMC_WAIT_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime)); - assert_param(IS_FSMC_HOLD_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime)); - assert_param(IS_FSMC_HIZ_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime)); - assert_param(IS_FSMC_SETUP_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime)); - assert_param(IS_FSMC_WAIT_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime)); - assert_param(IS_FSMC_HOLD_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime)); - assert_param(IS_FSMC_HIZ_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime)); - - /* Set the tmppcr value according to FSMC_NANDInitStruct parameters */ - tmppcr = (uint32_t)FSMC_NANDInitStruct->FSMC_Waitfeature | - PCR_MEMORYTYPE_NAND | - FSMC_NANDInitStruct->FSMC_MemoryDataWidth | - FSMC_NANDInitStruct->FSMC_ECC | - FSMC_NANDInitStruct->FSMC_ECCPageSize | - (FSMC_NANDInitStruct->FSMC_TCLRSetupTime << 9 )| - (FSMC_NANDInitStruct->FSMC_TARSetupTime << 13); - - /* Set tmppmem value according to FSMC_CommonSpaceTimingStructure parameters */ - tmppmem = (uint32_t)FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime | - (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime << 8) | - (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime << 16)| - (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime << 24); - - /* Set tmppatt value according to FSMC_AttributeSpaceTimingStructure parameters */ - tmppatt = (uint32_t)FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime | - (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime << 8) | - (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime << 16)| - (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime << 24); - - if(FSMC_NANDInitStruct->FSMC_Bank == FSMC_Bank2_NAND) - { - /* FSMC_Bank2_NAND registers configuration */ - FSMC_Bank2->PCR2 = tmppcr; - FSMC_Bank2->PMEM2 = tmppmem; - FSMC_Bank2->PATT2 = tmppatt; - } - else - { - /* FSMC_Bank3_NAND registers configuration */ - FSMC_Bank3->PCR3 = tmppcr; - FSMC_Bank3->PMEM3 = tmppmem; - FSMC_Bank3->PATT3 = tmppatt; - } -} - - -/** - * @brief Fills each FSMC_NANDInitStruct member with its default value. - * @param FSMC_NANDInitStruct: pointer to a FSMC_NANDInitTypeDef structure which - * will be initialized. - * @retval None - */ -void FSMC_NANDStructInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct) -{ - /* Reset NAND Init structure parameters values */ - FSMC_NANDInitStruct->FSMC_Bank = FSMC_Bank2_NAND; - FSMC_NANDInitStruct->FSMC_Waitfeature = FSMC_Waitfeature_Disable; - FSMC_NANDInitStruct->FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; - FSMC_NANDInitStruct->FSMC_ECC = FSMC_ECC_Disable; - FSMC_NANDInitStruct->FSMC_ECCPageSize = FSMC_ECCPageSize_256Bytes; - FSMC_NANDInitStruct->FSMC_TCLRSetupTime = 0x0; - FSMC_NANDInitStruct->FSMC_TARSetupTime = 0x0; - FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime = 0xFC; - FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; - FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; - FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; - FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime = 0xFC; - FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; - FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; - FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; -} - -/** - * @brief Enables or disables the specified NAND Memory Bank. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @param NewState: new state of the FSMC_Bank. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState) -{ - assert_param(IS_FSMC_NAND_BANK(FSMC_Bank)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected NAND Bank by setting the PBKEN bit in the PCRx register */ - if(FSMC_Bank == FSMC_Bank2_NAND) - { - FSMC_Bank2->PCR2 |= PCR_PBKEN_SET; - } - else - { - FSMC_Bank3->PCR3 |= PCR_PBKEN_SET; - } - } - else - { - /* Disable the selected NAND Bank by clearing the PBKEN bit in the PCRx register */ - if(FSMC_Bank == FSMC_Bank2_NAND) - { - FSMC_Bank2->PCR2 &= PCR_PBKEN_RESET; - } - else - { - FSMC_Bank3->PCR3 &= PCR_PBKEN_RESET; - } - } -} -/** - * @brief Enables or disables the FSMC NAND ECC feature. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @param NewState: new state of the FSMC NAND ECC feature. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FSMC_NANDECCCmd(uint32_t FSMC_Bank, FunctionalState NewState) -{ - assert_param(IS_FSMC_NAND_BANK(FSMC_Bank)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected NAND Bank ECC function by setting the ECCEN bit in the PCRx register */ - if(FSMC_Bank == FSMC_Bank2_NAND) - { - FSMC_Bank2->PCR2 |= PCR_ECCEN_SET; - } - else - { - FSMC_Bank3->PCR3 |= PCR_ECCEN_SET; - } - } - else - { - /* Disable the selected NAND Bank ECC function by clearing the ECCEN bit in the PCRx register */ - if(FSMC_Bank == FSMC_Bank2_NAND) - { - FSMC_Bank2->PCR2 &= PCR_ECCEN_RESET; - } - else - { - FSMC_Bank3->PCR3 &= PCR_ECCEN_RESET; - } - } -} - -/** - * @brief Returns the error correction code register value. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @retval The Error Correction Code (ECC) value. - */ -uint32_t FSMC_GetECC(uint32_t FSMC_Bank) -{ - uint32_t eccval = 0x00000000; - - if(FSMC_Bank == FSMC_Bank2_NAND) - { - /* Get the ECCR2 register value */ - eccval = FSMC_Bank2->ECCR2; - } - else - { - /* Get the ECCR3 register value */ - eccval = FSMC_Bank3->ECCR3; - } - /* Return the error correction code value */ - return(eccval); -} -/** - * @} - */ - -/** @defgroup FSMC_Group3 PCCARD Controller functions - * @brief PCCARD Controller functions - * -@verbatim - =============================================================================== - PCCARD Controller functions - =============================================================================== - - The following sequence should be followed to configure the FSMC to interface with - 16-bit PC Card compatible memory connected to the PCCARD Bank: - - 1. Enable the clock for the FSMC and associated GPIOs using the following functions: - RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE); - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); - - 2. FSMC pins configuration - - Connect the involved FSMC pins to AF12 using the following function - GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_FSMC); - - Configure these FSMC pins in alternate function mode by calling the function - GPIO_Init(); - - 3. Declare a FSMC_PCCARDInitTypeDef structure, for example: - FSMC_PCCARDInitTypeDef FSMC_PCCARDInitStructure; - and fill the FSMC_PCCARDInitStructure variable with the allowed values of - the structure member. - - 4. Initialize the PCCARD Controller by calling the function - FSMC_PCCARDInit(&FSMC_PCCARDInitStructure); - - 5. Then enable the PCCARD Bank: - FSMC_PCCARDCmd(ENABLE); - - 6. At this stage you can read/write from/to the memory connected to the PCCARD Bank. - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the FSMC PCCARD Bank registers to their default reset values. - * @param None - * @retval None - */ -void FSMC_PCCARDDeInit(void) -{ - /* Set the FSMC_Bank4 registers to their reset values */ - FSMC_Bank4->PCR4 = 0x00000018; - FSMC_Bank4->SR4 = 0x00000000; - FSMC_Bank4->PMEM4 = 0xFCFCFCFC; - FSMC_Bank4->PATT4 = 0xFCFCFCFC; - FSMC_Bank4->PIO4 = 0xFCFCFCFC; -} - -/** - * @brief Initializes the FSMC PCCARD Bank according to the specified parameters - * in the FSMC_PCCARDInitStruct. - * @param FSMC_PCCARDInitStruct : pointer to a FSMC_PCCARDInitTypeDef structure - * that contains the configuration information for the FSMC PCCARD Bank. - * @retval None - */ -void FSMC_PCCARDInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct) -{ - /* Check the parameters */ - assert_param(IS_FSMC_WAIT_FEATURE(FSMC_PCCARDInitStruct->FSMC_Waitfeature)); - assert_param(IS_FSMC_TCLR_TIME(FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime)); - assert_param(IS_FSMC_TAR_TIME(FSMC_PCCARDInitStruct->FSMC_TARSetupTime)); - - assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime)); - assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime)); - assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime)); - assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime)); - - assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime)); - assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime)); - assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime)); - assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime)); - assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime)); - assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime)); - assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime)); - assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime)); - - /* Set the PCR4 register value according to FSMC_PCCARDInitStruct parameters */ - FSMC_Bank4->PCR4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_Waitfeature | - FSMC_MemoryDataWidth_16b | - (FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime << 9) | - (FSMC_PCCARDInitStruct->FSMC_TARSetupTime << 13); - - /* Set PMEM4 register value according to FSMC_CommonSpaceTimingStructure parameters */ - FSMC_Bank4->PMEM4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime | - (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime << 8) | - (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime << 16)| - (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime << 24); - - /* Set PATT4 register value according to FSMC_AttributeSpaceTimingStructure parameters */ - FSMC_Bank4->PATT4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime | - (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime << 8) | - (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime << 16)| - (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime << 24); - - /* Set PIO4 register value according to FSMC_IOSpaceTimingStructure parameters */ - FSMC_Bank4->PIO4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime | - (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime << 8) | - (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime << 16)| - (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime << 24); -} - -/** - * @brief Fills each FSMC_PCCARDInitStruct member with its default value. - * @param FSMC_PCCARDInitStruct: pointer to a FSMC_PCCARDInitTypeDef structure - * which will be initialized. - * @retval None - */ -void FSMC_PCCARDStructInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct) -{ - /* Reset PCCARD Init structure parameters values */ - FSMC_PCCARDInitStruct->FSMC_Waitfeature = FSMC_Waitfeature_Disable; - FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime = 0x0; - FSMC_PCCARDInitStruct->FSMC_TARSetupTime = 0x0; - FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC; - FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC; -} - -/** - * @brief Enables or disables the PCCARD Memory Bank. - * @param NewState: new state of the PCCARD Memory Bank. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FSMC_PCCARDCmd(FunctionalState NewState) -{ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the PCCARD Bank by setting the PBKEN bit in the PCR4 register */ - FSMC_Bank4->PCR4 |= PCR_PBKEN_SET; - } - else - { - /* Disable the PCCARD Bank by clearing the PBKEN bit in the PCR4 register */ - FSMC_Bank4->PCR4 &= PCR_PBKEN_RESET; - } -} -/** - * @} - */ - -/** @defgroup FSMC_Group4 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified FSMC interrupts. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD - * @param FSMC_IT: specifies the FSMC interrupt sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt. - * @arg FSMC_IT_Level: Level edge detection interrupt. - * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt. - * @param NewState: new state of the specified FSMC interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void FSMC_ITConfig(uint32_t FSMC_Bank, uint32_t FSMC_IT, FunctionalState NewState) -{ - assert_param(IS_FSMC_IT_BANK(FSMC_Bank)); - assert_param(IS_FSMC_IT(FSMC_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected FSMC_Bank2 interrupts */ - if(FSMC_Bank == FSMC_Bank2_NAND) - { - FSMC_Bank2->SR2 |= FSMC_IT; - } - /* Enable the selected FSMC_Bank3 interrupts */ - else if (FSMC_Bank == FSMC_Bank3_NAND) - { - FSMC_Bank3->SR3 |= FSMC_IT; - } - /* Enable the selected FSMC_Bank4 interrupts */ - else - { - FSMC_Bank4->SR4 |= FSMC_IT; - } - } - else - { - /* Disable the selected FSMC_Bank2 interrupts */ - if(FSMC_Bank == FSMC_Bank2_NAND) - { - - FSMC_Bank2->SR2 &= (uint32_t)~FSMC_IT; - } - /* Disable the selected FSMC_Bank3 interrupts */ - else if (FSMC_Bank == FSMC_Bank3_NAND) - { - FSMC_Bank3->SR3 &= (uint32_t)~FSMC_IT; - } - /* Disable the selected FSMC_Bank4 interrupts */ - else - { - FSMC_Bank4->SR4 &= (uint32_t)~FSMC_IT; - } - } -} - -/** - * @brief Checks whether the specified FSMC flag is set or not. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD - * @param FSMC_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg FSMC_FLAG_RisingEdge: Rising edge detection Flag. - * @arg FSMC_FLAG_Level: Level detection Flag. - * @arg FSMC_FLAG_FallingEdge: Falling edge detection Flag. - * @arg FSMC_FLAG_FEMPT: Fifo empty Flag. - * @retval The new state of FSMC_FLAG (SET or RESET). - */ -FlagStatus FSMC_GetFlagStatus(uint32_t FSMC_Bank, uint32_t FSMC_FLAG) -{ - FlagStatus bitstatus = RESET; - uint32_t tmpsr = 0x00000000; - - /* Check the parameters */ - assert_param(IS_FSMC_GETFLAG_BANK(FSMC_Bank)); - assert_param(IS_FSMC_GET_FLAG(FSMC_FLAG)); - - if(FSMC_Bank == FSMC_Bank2_NAND) - { - tmpsr = FSMC_Bank2->SR2; - } - else if(FSMC_Bank == FSMC_Bank3_NAND) - { - tmpsr = FSMC_Bank3->SR3; - } - /* FSMC_Bank4_PCCARD*/ - else - { - tmpsr = FSMC_Bank4->SR4; - } - - /* Get the flag status */ - if ((tmpsr & FSMC_FLAG) != (uint16_t)RESET ) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the flag status */ - return bitstatus; -} - -/** - * @brief Clears the FSMC's pending flags. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD - * @param FSMC_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg FSMC_FLAG_RisingEdge: Rising edge detection Flag. - * @arg FSMC_FLAG_Level: Level detection Flag. - * @arg FSMC_FLAG_FallingEdge: Falling edge detection Flag. - * @retval None - */ -void FSMC_ClearFlag(uint32_t FSMC_Bank, uint32_t FSMC_FLAG) -{ - /* Check the parameters */ - assert_param(IS_FSMC_GETFLAG_BANK(FSMC_Bank)); - assert_param(IS_FSMC_CLEAR_FLAG(FSMC_FLAG)) ; - - if(FSMC_Bank == FSMC_Bank2_NAND) - { - FSMC_Bank2->SR2 &= ~FSMC_FLAG; - } - else if(FSMC_Bank == FSMC_Bank3_NAND) - { - FSMC_Bank3->SR3 &= ~FSMC_FLAG; - } - /* FSMC_Bank4_PCCARD*/ - else - { - FSMC_Bank4->SR4 &= ~FSMC_FLAG; - } -} - -/** - * @brief Checks whether the specified FSMC interrupt has occurred or not. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD - * @param FSMC_IT: specifies the FSMC interrupt source to check. - * This parameter can be one of the following values: - * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt. - * @arg FSMC_IT_Level: Level edge detection interrupt. - * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt. - * @retval The new state of FSMC_IT (SET or RESET). - */ -ITStatus FSMC_GetITStatus(uint32_t FSMC_Bank, uint32_t FSMC_IT) -{ - ITStatus bitstatus = RESET; - uint32_t tmpsr = 0x0, itstatus = 0x0, itenable = 0x0; - - /* Check the parameters */ - assert_param(IS_FSMC_IT_BANK(FSMC_Bank)); - assert_param(IS_FSMC_GET_IT(FSMC_IT)); - - if(FSMC_Bank == FSMC_Bank2_NAND) - { - tmpsr = FSMC_Bank2->SR2; - } - else if(FSMC_Bank == FSMC_Bank3_NAND) - { - tmpsr = FSMC_Bank3->SR3; - } - /* FSMC_Bank4_PCCARD*/ - else - { - tmpsr = FSMC_Bank4->SR4; - } - - itstatus = tmpsr & FSMC_IT; - - itenable = tmpsr & (FSMC_IT >> 3); - if ((itstatus != (uint32_t)RESET) && (itenable != (uint32_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the FSMC's interrupt pending bits. - * @param FSMC_Bank: specifies the FSMC Bank to be used - * This parameter can be one of the following values: - * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND - * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND - * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD - * @param FSMC_IT: specifies the interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt. - * @arg FSMC_IT_Level: Level edge detection interrupt. - * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt. - * @retval None - */ -void FSMC_ClearITPendingBit(uint32_t FSMC_Bank, uint32_t FSMC_IT) -{ - /* Check the parameters */ - assert_param(IS_FSMC_IT_BANK(FSMC_Bank)); - assert_param(IS_FSMC_IT(FSMC_IT)); - - if(FSMC_Bank == FSMC_Bank2_NAND) - { - FSMC_Bank2->SR2 &= ~(FSMC_IT >> 3); - } - else if(FSMC_Bank == FSMC_Bank3_NAND) - { - FSMC_Bank3->SR3 &= ~(FSMC_IT >> 3); - } - /* FSMC_Bank4_PCCARD*/ - else - { - FSMC_Bank4->SR4 &= ~(FSMC_IT >> 3); - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c deleted file mode 100644 index c3a60439a..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c +++ /dev/null @@ -1,561 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_gpio.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the GPIO peripheral: - * - Initialization and Configuration - * - GPIO Read and Write - * - GPIO Alternate functions configuration - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable the GPIO AHB clock using the following function - * RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); - * - * 2. Configure the GPIO pin(s) using GPIO_Init() - * Four possible configuration are available for each pin: - * - Input: Floating, Pull-up, Pull-down. - * - Output: Push-Pull (Pull-up, Pull-down or no Pull) - * Open Drain (Pull-up, Pull-down or no Pull). - * In output mode, the speed is configurable: 2 MHz, 25 MHz, - * 50 MHz or 100 MHz. - * - Alternate Function: Push-Pull (Pull-up, Pull-down or no Pull) - * Open Drain (Pull-up, Pull-down or no Pull). - * - Analog: required mode when a pin is to be used as ADC channel - * or DAC output. - * - * 3- Peripherals alternate function: - * - For ADC and DAC, configure the desired pin in analog mode using - * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AN; - * - For other peripherals (TIM, USART...): - * - Connect the pin to the desired peripherals' Alternate - * Function (AF) using GPIO_PinAFConfig() function - * - Configure the desired pin in alternate function mode using - * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF - * - Select the type, pull-up/pull-down and output speed via - * GPIO_PuPd, GPIO_OType and GPIO_Speed members - * - Call GPIO_Init() function - * - * 4. To get the level of a pin configured in input mode use GPIO_ReadInputDataBit() - * - * 5. To set/reset the level of a pin configured in output mode use - * GPIO_SetBits()/GPIO_ResetBits() - * - * 6. During and just after reset, the alternate functions are not - * active and the GPIO pins are configured in input floating mode - * (except JTAG pins). - * - * 7. The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as - * general-purpose (PC14 and PC15, respectively) when the LSE - * oscillator is off. The LSE has priority over the GPIO function. - * - * 8. The HSE oscillator pins OSC_IN/OSC_OUT can be used as - * general-purpose PH0 and PH1, respectively, when the HSE - * oscillator is off. The HSE has priority over the GPIO function. - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_gpio.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup GPIO - * @brief GPIO driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup GPIO_Private_Functions - * @{ - */ - -/** @defgroup GPIO_Group1 Initialization and Configuration - * @brief Initialization and Configuration - * -@verbatim - =============================================================================== - Initialization and Configuration - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the GPIOx peripheral registers to their default reset values. - * @note By default, The GPIO pins are configured in input floating mode (except JTAG pins). - * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. - * @retval None - */ -void GPIO_DeInit(GPIO_TypeDef* GPIOx) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - - if (GPIOx == GPIOA) - { - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, ENABLE); - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, DISABLE); - } - else if (GPIOx == GPIOB) - { - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, ENABLE); - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, DISABLE); - } - else if (GPIOx == GPIOC) - { - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOC, ENABLE); - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOC, DISABLE); - } - else if (GPIOx == GPIOD) - { - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOD, ENABLE); - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOD, DISABLE); - } - else if (GPIOx == GPIOE) - { - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOE, ENABLE); - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOE, DISABLE); - } - else if (GPIOx == GPIOF) - { - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOF, ENABLE); - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOF, DISABLE); - } - else if (GPIOx == GPIOG) - { - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOG, ENABLE); - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOG, DISABLE); - } - else if (GPIOx == GPIOH) - { - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOH, ENABLE); - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOH, DISABLE); - } - else - { - if (GPIOx == GPIOI) - { - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOI, ENABLE); - RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOI, DISABLE); - } - } -} - -/** - * @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_InitStruct. - * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. - * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that contains - * the configuration information for the specified GPIO peripheral. - * @retval None - */ -void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) -{ - uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00; - - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); - assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); - assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd)); - - /* -------------------------Configure the port pins---------------- */ - /*-- GPIO Mode Configuration --*/ - for (pinpos = 0x00; pinpos < 0x10; pinpos++) - { - pos = ((uint32_t)0x01) << pinpos; - /* Get the port pins position */ - currentpin = (GPIO_InitStruct->GPIO_Pin) & pos; - - if (currentpin == pos) - { - GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2)); - GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2)); - - if ((GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) || (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_AF)) - { - /* Check Speed mode parameters */ - assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed)); - - /* Speed mode configuration */ - GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2)); - GPIOx->OSPEEDR |= ((uint32_t)(GPIO_InitStruct->GPIO_Speed) << (pinpos * 2)); - - /* Check Output mode parameters */ - assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType)); - - /* Output mode configuration*/ - GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos)) ; - GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << ((uint16_t)pinpos)); - } - - /* Pull-up Pull down resistor configuration*/ - GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2)); - GPIOx->PUPDR |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) << (pinpos * 2)); - } - } -} - -/** - * @brief Fills each GPIO_InitStruct member with its default value. - * @param GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will be initialized. - * @retval None - */ -void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct) -{ - /* Reset GPIO init structure parameters values */ - GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All; - GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStruct->GPIO_OType = GPIO_OType_PP; - GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_NOPULL; -} - -/** - * @brief Locks GPIO Pins configuration registers. - * @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, - * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH. - * @note The configuration of the locked GPIO pins can no longer be modified - * until the next reset. - * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bit to be locked. - * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). - * @retval None - */ -void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - __IO uint32_t tmp = 0x00010000; - - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GPIO_PIN(GPIO_Pin)); - - tmp |= GPIO_Pin; - /* Set LCKK bit */ - GPIOx->LCKR = tmp; - /* Reset LCKK bit */ - GPIOx->LCKR = GPIO_Pin; - /* Set LCKK bit */ - GPIOx->LCKR = tmp; - /* Read LCKK bit*/ - tmp = GPIOx->LCKR; - /* Read LCKK bit*/ - tmp = GPIOx->LCKR; -} - -/** - * @} - */ - -/** @defgroup GPIO_Group2 GPIO Read and Write - * @brief GPIO Read and Write - * -@verbatim - =============================================================================== - GPIO Read and Write - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Reads the specified input port pin. - * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bit to read. - * This parameter can be GPIO_Pin_x where x can be (0..15). - * @retval The input port pin value. - */ -uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - uint8_t bitstatus = 0x00; - - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); - - if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET) - { - bitstatus = (uint8_t)Bit_SET; - } - else - { - bitstatus = (uint8_t)Bit_RESET; - } - return bitstatus; -} - -/** - * @brief Reads the specified GPIO input data port. - * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. - * @retval GPIO input data port value. - */ -uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - - return ((uint16_t)GPIOx->IDR); -} - -/** - * @brief Reads the specified output data port bit. - * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bit to read. - * This parameter can be GPIO_Pin_x where x can be (0..15). - * @retval The output port pin value. - */ -uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - uint8_t bitstatus = 0x00; - - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); - - if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET) - { - bitstatus = (uint8_t)Bit_SET; - } - else - { - bitstatus = (uint8_t)Bit_RESET; - } - return bitstatus; -} - -/** - * @brief Reads the specified GPIO output data port. - * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. - * @retval GPIO output data port value. - */ -uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - - return ((uint16_t)GPIOx->ODR); -} - -/** - * @brief Sets the selected data port bits. - * @note This functions uses GPIOx_BSRR register to allow atomic read/modify - * accesses. In this way, there is no risk of an IRQ occurring between - * the read and the modify access. - * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bits to be written. - * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). - * @retval None - */ -void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GPIO_PIN(GPIO_Pin)); - - GPIOx->BSRRL = GPIO_Pin; -} - -/** - * @brief Clears the selected data port bits. - * @note This functions uses GPIOx_BSRR register to allow atomic read/modify - * accesses. In this way, there is no risk of an IRQ occurring between - * the read and the modify access. - * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bits to be written. - * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). - * @retval None - */ -void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GPIO_PIN(GPIO_Pin)); - - GPIOx->BSRRH = GPIO_Pin; -} - -/** - * @brief Sets or clears the selected data port bit. - * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. - * @param GPIO_Pin: specifies the port bit to be written. - * This parameter can be one of GPIO_Pin_x where x can be (0..15). - * @param BitVal: specifies the value to be written to the selected bit. - * This parameter can be one of the BitAction enum values: - * @arg Bit_RESET: to clear the port pin - * @arg Bit_SET: to set the port pin - * @retval None - */ -void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); - assert_param(IS_GPIO_BIT_ACTION(BitVal)); - - if (BitVal != Bit_RESET) - { - GPIOx->BSRRL = GPIO_Pin; - } - else - { - GPIOx->BSRRH = GPIO_Pin ; - } -} - -/** - * @brief Writes data to the specified GPIO data port. - * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. - * @param PortVal: specifies the value to be written to the port output data register. - * @retval None - */ -void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - - GPIOx->ODR = PortVal; -} - -/** - * @brief Toggles the specified GPIO pins.. - * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. - * @param GPIO_Pin: Specifies the pins to be toggled. - * @retval None - */ -void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) -{ - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - - GPIOx->ODR ^= GPIO_Pin; -} - -/** - * @} - */ - -/** @defgroup GPIO_Group3 GPIO Alternate functions configuration function - * @brief GPIO Alternate functions configuration function - * -@verbatim - =============================================================================== - GPIO Alternate functions configuration function - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Changes the mapping of the specified pin. - * @param GPIOx: where x can be (A..I) to select the GPIO peripheral. - * @param GPIO_PinSource: specifies the pin for the Alternate function. - * This parameter can be GPIO_PinSourcex where x can be (0..15). - * @param GPIO_AFSelection: selects the pin to used as Alternate function. - * This parameter can be one of the following values: - * @arg GPIO_AF_RTC_50Hz: Connect RTC_50Hz pin to AF0 (default after reset) - * @arg GPIO_AF_MCO: Connect MCO pin (MCO1 and MCO2) to AF0 (default after reset) - * @arg GPIO_AF_TAMPER: Connect TAMPER pins (TAMPER_1 and TAMPER_2) to AF0 (default after reset) - * @arg GPIO_AF_SWJ: Connect SWJ pins (SWD and JTAG)to AF0 (default after reset) - * @arg GPIO_AF_TRACE: Connect TRACE pins to AF0 (default after reset) - * @arg GPIO_AF_TIM1: Connect TIM1 pins to AF1 - * @arg GPIO_AF_TIM2: Connect TIM2 pins to AF1 - * @arg GPIO_AF_TIM3: Connect TIM3 pins to AF2 - * @arg GPIO_AF_TIM4: Connect TIM4 pins to AF2 - * @arg GPIO_AF_TIM5: Connect TIM5 pins to AF2 - * @arg GPIO_AF_TIM8: Connect TIM8 pins to AF3 - * @arg GPIO_AF_TIM9: Connect TIM9 pins to AF3 - * @arg GPIO_AF_TIM10: Connect TIM10 pins to AF3 - * @arg GPIO_AF_TIM11: Connect TIM11 pins to AF3 - * @arg GPIO_AF_I2C1: Connect I2C1 pins to AF4 - * @arg GPIO_AF_I2C2: Connect I2C2 pins to AF4 - * @arg GPIO_AF_I2C3: Connect I2C3 pins to AF4 - * @arg GPIO_AF_SPI1: Connect SPI1 pins to AF5 - * @arg GPIO_AF_SPI2: Connect SPI2/I2S2 pins to AF5 - * @arg GPIO_AF_SPI3: Connect SPI3/I2S3 pins to AF6 - * @arg GPIO_AF_I2S3ext: Connect I2S3ext pins to AF7 - * @arg GPIO_AF_USART1: Connect USART1 pins to AF7 - * @arg GPIO_AF_USART2: Connect USART2 pins to AF7 - * @arg GPIO_AF_USART3: Connect USART3 pins to AF7 - * @arg GPIO_AF_UART4: Connect UART4 pins to AF8 - * @arg GPIO_AF_UART5: Connect UART5 pins to AF8 - * @arg GPIO_AF_USART6: Connect USART6 pins to AF8 - * @arg GPIO_AF_CAN1: Connect CAN1 pins to AF9 - * @arg GPIO_AF_CAN2: Connect CAN2 pins to AF9 - * @arg GPIO_AF_TIM12: Connect TIM12 pins to AF9 - * @arg GPIO_AF_TIM13: Connect TIM13 pins to AF9 - * @arg GPIO_AF_TIM14: Connect TIM14 pins to AF9 - * @arg GPIO_AF_OTG_FS: Connect OTG_FS pins to AF10 - * @arg GPIO_AF_OTG_HS: Connect OTG_HS pins to AF10 - * @arg GPIO_AF_ETH: Connect ETHERNET pins to AF11 - * @arg GPIO_AF_FSMC: Connect FSMC pins to AF12 - * @arg GPIO_AF_OTG_HS_FS: Connect OTG HS (configured in FS) pins to AF12 - * @arg GPIO_AF_SDIO: Connect SDIO pins to AF12 - * @arg GPIO_AF_DCMI: Connect DCMI pins to AF13 - * @arg GPIO_AF_EVENTOUT: Connect EVENTOUT pins to AF15 - * @retval None - */ -void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF) -{ - uint32_t temp = 0x00; - uint32_t temp_2 = 0x00; - - /* Check the parameters */ - assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); - assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource)); - assert_param(IS_GPIO_AF(GPIO_AF)); - - temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ; - GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ; - temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp; - GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash.c deleted file mode 100644 index 3d8df299a..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash.c +++ /dev/null @@ -1,700 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_hash.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the HASH / HMAC Processor (HASH) peripheral: - * - Initialization and Configuration functions - * - Message Digest generation functions - * - context swapping functions - * - DMA interface function - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * HASH operation : - * ---------------- - * 1. Enable the HASH controller clock using - * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, ENABLE) function. - * - * 2. Initialise the HASH using HASH_Init() function. - * - * 3 . Reset the HASH processor core, so that the HASH will be ready - * to compute he message digest of a new message by using - * HASH_Reset() function. - * - * 4. Enable the HASH controller using the HASH_Cmd() function. - * - * 5. if using DMA for Data input transfer, Activate the DMA Request - * using HASH_DMACmd() function - * - * 6. if DMA is not used for data transfer, use HASH_DataIn() function - * to enter data to IN FIFO. - * - * - * 7. Configure the Number of valid bits in last word of the message - * using HASH_SetLastWordValidBitsNbr() function. - * - * 8. if the message length is not an exact multiple of 512 bits, - * then the function HASH_StartDigest() must be called to - * launch the computation of the final digest. - * - * 9. Once computed, the digest can be read using HASH_GetDigest() - * function. - * - * 10. To control HASH events you can use one of the following - * two methods: - * a- Check on HASH flags using the HASH_GetFlagStatus() function. - * b- Use HASH interrupts through the function HASH_ITConfig() at - * initialization phase and HASH_GetITStatus() function into - * interrupt routines in hashing phase. - * After checking on a flag you should clear it using HASH_ClearFlag() - * function. And after checking on an interrupt event you should - * clear it using HASH_ClearITPendingBit() function. - * - * 11. Save and restore hash processor context using - * HASH_SaveContext() and HASH_RestoreContext() functions. - * - * - * - * HMAC operation : - * ---------------- - * The HMAC algorithm is used for message authentication, by - * irreversibly binding the message being processed to a key chosen - * by the user. - * For HMAC specifications, refer to "HMAC: keyed-hashing for message - * authentication, H. Krawczyk, M. Bellare, R. Canetti, February 1997" - * - * Basically, the HMAC algorithm consists of two nested hash operations: - * HMAC(message) = Hash[((key | pad) XOR 0x5C) | Hash(((key | pad) XOR 0x36) | message)] - * where: - * - "pad" is a sequence of zeroes needed to extend the key to the - * length of the underlying hash function data block (that is - * 512 bits for both the SHA-1 and MD5 hash algorithms) - * - "|" represents the concatenation operator - * - * - * To compute the HMAC, four different phases are required: - * - * 1. Initialise the HASH using HASH_Init() function to do HMAC - * operation. - * - * 2. The key (to be used for the inner hash function) is then given - * to the core. This operation follows the same mechanism as the - * one used to send the message in the hash operation (that is, - * by HASH_DataIn() function and, finally, - * HASH_StartDigest() function. - * - * 3. Once the last word has been entered and computation has started, - * the hash processor elaborates the key. It is then ready to - * accept the message text using the same mechanism as the one - * used to send the message in the hash operation. - * - * 4. After the first hash round, the hash processor returns "ready" - * to indicate that it is ready to receive the key to be used for - * the outer hash function (normally, this key is the same as the - * one used for the inner hash function). When the last word of - * the key is entered and computation starts, the HMAC result is - * made available using HASH_GetDigest() function. - * - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_hash.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup HASH - * @brief HASH driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup HASH_Private_Functions - * @{ - */ - -/** @defgroup HASH_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - This section provides functions allowing to - - Initialize the HASH peripheral - - Configure the HASH Processor - - MD5/SHA1, - - HASH/HMAC, - - datatype - - HMAC Key (if mode = HMAC) - - Reset the HASH Processor - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the HASH peripheral registers to their default reset values - * @param None - * @retval None - */ -void HASH_DeInit(void) -{ - /* Enable HASH reset state */ - RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_HASH, ENABLE); - /* Release HASH from reset state */ - RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_HASH, DISABLE); -} - -/** - * @brief Initializes the HASH peripheral according to the specified parameters - * in the HASH_InitStruct structure. - * @note the hash processor is reset when calling this function so that the - * HASH will be ready to compute the message digest of a new message. - * There is no need to call HASH_Reset() function. - * @param HASH_InitStruct: pointer to a HASH_InitTypeDef structure that contains - * the configuration information for the HASH peripheral. - * @note The field HASH_HMACKeyType in HASH_InitTypeDef must be filled only - * if the algorithm mode is HMAC. - * @retval None - */ -void HASH_Init(HASH_InitTypeDef* HASH_InitStruct) -{ - /* Check the parameters */ - assert_param(IS_HASH_ALGOSELECTION(HASH_InitStruct->HASH_AlgoSelection)); - assert_param(IS_HASH_DATATYPE(HASH_InitStruct->HASH_DataType)); - assert_param(IS_HASH_ALGOMODE(HASH_InitStruct->HASH_AlgoMode)); - - /* Configure the Algorithm used, algorithm mode and the datatype */ - HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE); - HASH->CR |= (HASH_InitStruct->HASH_AlgoSelection | \ - HASH_InitStruct->HASH_DataType | \ - HASH_InitStruct->HASH_AlgoMode); - - /* if algorithm mode is HMAC, set the Key */ - if(HASH_InitStruct->HASH_AlgoMode == HASH_AlgoMode_HMAC) - { - assert_param(IS_HASH_HMAC_KEYTYPE(HASH_InitStruct->HASH_HMACKeyType)); - HASH->CR &= ~HASH_CR_LKEY; - HASH->CR |= HASH_InitStruct->HASH_HMACKeyType; - } - - /* Reset the HASH processor core, so that the HASH will be ready to compute - the message digest of a new message */ - HASH->CR |= HASH_CR_INIT; -} - -/** - * @brief Fills each HASH_InitStruct member with its default value. - * @param HASH_InitStruct : pointer to a HASH_InitTypeDef structure which will - * be initialized. - * @note The default values set are : Processor mode is HASH, Algorithm selected is SHA1, - * Data type selected is 32b and HMAC Key Type is short key. - * @retval None - */ -void HASH_StructInit(HASH_InitTypeDef* HASH_InitStruct) -{ - /* Initialize the HASH_AlgoSelection member */ - HASH_InitStruct->HASH_AlgoSelection = HASH_AlgoSelection_SHA1; - - /* Initialize the HASH_AlgoMode member */ - HASH_InitStruct->HASH_AlgoMode = HASH_AlgoMode_HASH; - - /* Initialize the HASH_DataType member */ - HASH_InitStruct->HASH_DataType = HASH_DataType_32b; - - /* Initialize the HASH_HMACKeyType member */ - HASH_InitStruct->HASH_HMACKeyType = HASH_HMACKeyType_ShortKey; -} - -/** - * @brief Resets the HASH processor core, so that the HASH will be ready - * to compute the message digest of a new message. - * @note Calling this function will clear the HASH_SR_DCIS (Digest calculation - * completion interrupt status) bit corresponding to HASH_IT_DCI - * interrupt and HASH_FLAG_DCIS flag. - * @param None - * @retval None - */ -void HASH_Reset(void) -{ - /* Reset the HASH processor core */ - HASH->CR |= HASH_CR_INIT; -} -/** - * @} - */ - -/** @defgroup HASH_Group2 Message Digest generation functions - * @brief Message Digest generation functions - * -@verbatim - =============================================================================== - Message Digest generation functions - =============================================================================== - This section provides functions allowing the generation of message digest: - - Push data in the IN FIFO : using HASH_DataIn() - - Get the number of words set in IN FIFO, use HASH_GetInFIFOWordsNbr() - - set the last word valid bits number using HASH_SetLastWordValidBitsNbr() - - start digest calculation : using HASH_StartDigest() - - Get the Digest message : using HASH_GetDigest() - -@endverbatim - * @{ - */ - - -/** - * @brief Configure the Number of valid bits in last word of the message - * @param ValidNumber: Number of valid bits in last word of the message. - * This parameter must be a number between 0 and 0x1F. - * - 0x00: All 32 bits of the last data written are valid - * - 0x01: Only bit [0] of the last data written is valid - * - 0x02: Only bits[1:0] of the last data written are valid - * - 0x03: Only bits[2:0] of the last data written are valid - * - ... - * - 0x1F: Only bits[30:0] of the last data written are valid - * @note The Number of valid bits must be set before to start the message - * digest competition (in Hash and HMAC) and key treatment(in HMAC). - * @retval None - */ -void HASH_SetLastWordValidBitsNbr(uint16_t ValidNumber) -{ - /* Check the parameters */ - assert_param(IS_HASH_VALIDBITSNUMBER(ValidNumber)); - - /* Configure the Number of valid bits in last word of the message */ - HASH->STR &= ~(HASH_STR_NBW); - HASH->STR |= ValidNumber; -} - -/** - * @brief Writes data in the Data Input FIFO - * @param Data: new data of the message to be processed. - * @retval None - */ -void HASH_DataIn(uint32_t Data) -{ - /* Write in the DIN register a new data */ - HASH->DIN = Data; -} - -/** - * @brief Returns the number of words already pushed into the IN FIFO. - * @param None - * @retval The value of words already pushed into the IN FIFO. - */ -uint8_t HASH_GetInFIFOWordsNbr(void) -{ - /* Return the value of NBW bits */ - return ((HASH->CR & HASH_CR_NBW) >> 8); -} - -/** - * @brief Provides the message digest result. - * @note In MD5 mode, Data[4] filed of HASH_MsgDigest structure is not used - * and is read as zero. - * @param HASH_MessageDigest: pointer to a HASH_MsgDigest structure which will - * hold the message digest result - * @retval None - */ -void HASH_GetDigest(HASH_MsgDigest* HASH_MessageDigest) -{ - /* Get the data field */ - HASH_MessageDigest->Data[0] = HASH->HR[0]; - HASH_MessageDigest->Data[1] = HASH->HR[1]; - HASH_MessageDigest->Data[2] = HASH->HR[2]; - HASH_MessageDigest->Data[3] = HASH->HR[3]; - HASH_MessageDigest->Data[4] = HASH->HR[4]; -} - -/** - * @brief Starts the message padding and calculation of the final message - * @param None - * @retval None - */ -void HASH_StartDigest(void) -{ - /* Start the Digest calculation */ - HASH->STR |= HASH_STR_DCAL; -} -/** - * @} - */ - -/** @defgroup HASH_Group3 Context swapping functions - * @brief Context swapping functions - * -@verbatim - =============================================================================== - Context swapping functions - =============================================================================== - - This section provides functions allowing to save and store HASH Context - - It is possible to interrupt a HASH/HMAC process to perform another processing - with a higher priority, and to complete the interrupted process later on, when - the higher priority task is complete. To do so, the context of the interrupted - task must be saved from the HASH registers to memory, and then be restored - from memory to the HASH registers. - - 1. To save the current context, use HASH_SaveContext() function - 2. To restore the saved context, use HASH_RestoreContext() function - - -@endverbatim - * @{ - */ - -/** - * @brief Save the Hash peripheral Context. - * @note The context can be saved only when no block is currently being - * processed. So user must wait for DINIS = 1 (the last block has been - * processed and the input FIFO is empty) or NBW != 0 (the FIFO is not - * full and no processing is ongoing). - * @param HASH_ContextSave: pointer to a HASH_Context structure that contains - * the repository for current context. - * @retval None - */ -void HASH_SaveContext(HASH_Context* HASH_ContextSave) -{ - uint8_t i = 0; - - /* save context registers */ - HASH_ContextSave->HASH_IMR = HASH->IMR; - HASH_ContextSave->HASH_STR = HASH->STR; - HASH_ContextSave->HASH_CR = HASH->CR; - for(i=0; i<=50;i++) - { - HASH_ContextSave->HASH_CSR[i] = HASH->CSR[i]; - } -} - -/** - * @brief Restore the Hash peripheral Context. - * @note After calling this function, user can restart the processing from the - * point where it has been interrupted. - * @param HASH_ContextRestore: pointer to a HASH_Context structure that contains - * the repository for saved context. - * @retval None - */ -void HASH_RestoreContext(HASH_Context* HASH_ContextRestore) -{ - uint8_t i = 0; - - /* restore context registers */ - HASH->IMR = HASH_ContextRestore->HASH_IMR; - HASH->STR = HASH_ContextRestore->HASH_STR; - HASH->CR = HASH_ContextRestore->HASH_CR; - - /* Initialize the hash processor */ - HASH->CR |= HASH_CR_INIT; - - /* continue restoring context registers */ - for(i=0; i<=50;i++) - { - HASH->CSR[i] = HASH_ContextRestore->HASH_CSR[i]; - } -} -/** - * @} - */ - -/** @defgroup HASH_Group4 HASH's DMA interface Configuration function - * @brief HASH's DMA interface Configuration function - * -@verbatim - =============================================================================== - HASH's DMA interface Configuration function - =============================================================================== - - This section provides functions allowing to configure the DMA interface for - HASH/ HMAC data input transfer. - - When the DMA mode is enabled (using the HASH_DMACmd() function), data can be - sent to the IN FIFO using the DMA peripheral. - - - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the HASH DMA interface. - * @note The DMA is disabled by hardware after the end of transfer. - * @param NewState: new state of the selected HASH DMA transfer request. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void HASH_DMACmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the HASH DMA request */ - HASH->CR |= HASH_CR_DMAE; - } - else - { - /* Disable the HASH DMA request */ - HASH->CR &= ~HASH_CR_DMAE; - } -} -/** - * @} - */ - -/** @defgroup HASH_Group5 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - - This section provides functions allowing to configure the HASH Interrupts and - to get the status and clear flags and Interrupts pending bits. - - The HASH provides 2 Interrupts sources and 5 Flags: - - Flags : - ---------- - 1. HASH_FLAG_DINIS : set when 16 locations are free in the Data IN FIFO - which means that a new block (512 bit) can be entered - into the input buffer. - - 2. HASH_FLAG_DCIS : set when Digest calculation is complete - - 3. HASH_FLAG_DMAS : set when HASH's DMA interface is enabled (DMAE=1) or - a transfer is ongoing. - This Flag is cleared only by hardware. - - 4. HASH_FLAG_BUSY : set when The hash core is processing a block of data - This Flag is cleared only by hardware. - - 5. HASH_FLAG_DINNE : set when Data IN FIFO is not empty which means that - the Data IN FIFO contains at least one word of data. - This Flag is cleared only by hardware. - - Interrupts : - ------------ - - 1. HASH_IT_DINI : if enabled, this interrupt source is pending when 16 - locations are free in the Data IN FIFO which means that - a new block (512 bit) can be entered into the input buffer. - This interrupt source is cleared using - HASH_ClearITPendingBit(HASH_IT_DINI) function. - - 2. HASH_IT_DCI : if enabled, this interrupt source is pending when Digest - calculation is complete. - This interrupt source is cleared using - HASH_ClearITPendingBit(HASH_IT_DCI) function. - - Managing the HASH controller events : - ------------------------------------ - The user should identify which mode will be used in his application to manage - the HASH controller events: Polling mode or Interrupt mode. - - 1. In the Polling Mode it is advised to use the following functions: - - HASH_GetFlagStatus() : to check if flags events occur. - - HASH_ClearFlag() : to clear the flags events. - - 2. In the Interrupt Mode it is advised to use the following functions: - - HASH_ITConfig() : to enable or disable the interrupt source. - - HASH_GetITStatus() : to check if Interrupt occurs. - - HASH_ClearITPendingBit() : to clear the Interrupt pending Bit - (corresponding Flag). - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified HASH interrupts. - * @param HASH_IT: specifies the HASH interrupt source to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg HASH_IT_DINI: Data Input interrupt - * @arg HASH_IT_DCI: Digest Calculation Completion Interrupt - * @param NewState: new state of the specified HASH interrupt. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void HASH_ITConfig(uint8_t HASH_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_HASH_IT(HASH_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected HASH interrupt */ - HASH->IMR |= HASH_IT; - } - else - { - /* Disable the selected HASH interrupt */ - HASH->IMR &= (uint8_t) ~HASH_IT; - } -} - -/** - * @brief Checks whether the specified HASH flag is set or not. - * @param HASH_FLAG: specifies the HASH flag to check. - * This parameter can be one of the following values: - * @arg HASH_FLAG_DINIS: Data input interrupt status flag - * @arg HASH_FLAG_DCIS: Digest calculation completion interrupt status flag - * @arg HASH_FLAG_BUSY: Busy flag - * @arg HASH_FLAG_DMAS: DMAS Status flag - * @arg HASH_FLAG_DINNE: Data Input register (DIN) not empty status flag - * @retval The new state of HASH_FLAG (SET or RESET) - */ -FlagStatus HASH_GetFlagStatus(uint16_t HASH_FLAG) -{ - FlagStatus bitstatus = RESET; - uint32_t tempreg = 0; - - /* Check the parameters */ - assert_param(IS_HASH_GET_FLAG(HASH_FLAG)); - - /* check if the FLAG is in CR register */ - if ((HASH_FLAG & HASH_FLAG_DINNE) != (uint16_t)RESET ) - { - tempreg = HASH->CR; - } - else /* The FLAG is in SR register */ - { - tempreg = HASH->SR; - } - - /* Check the status of the specified HASH flag */ - if ((tempreg & HASH_FLAG) != (uint16_t)RESET) - { - /* HASH is set */ - bitstatus = SET; - } - else - { - /* HASH_FLAG is reset */ - bitstatus = RESET; - } - - /* Return the HASH_FLAG status */ - return bitstatus; -} -/** - * @brief Clears the HASH flags. - * @param HASH_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg HASH_FLAG_DINIS: Data Input Flag - * @arg HASH_FLAG_DCIS: Digest Calculation Completion Flag - * @retval None - */ -void HASH_ClearFlag(uint16_t HASH_FLAG) -{ - /* Check the parameters */ - assert_param(IS_HASH_CLEAR_FLAG(HASH_FLAG)); - - /* Clear the selected HASH flags */ - HASH->SR = ~(uint32_t)HASH_FLAG; -} -/** - * @brief Checks whether the specified HASH interrupt has occurred or not. - * @param HASH_IT: specifies the HASH interrupt source to check. - * This parameter can be one of the following values: - * @arg HASH_IT_DINI: Data Input interrupt - * @arg HASH_IT_DCI: Digest Calculation Completion Interrupt - * @retval The new state of HASH_IT (SET or RESET). - */ -ITStatus HASH_GetITStatus(uint8_t HASH_IT) -{ - ITStatus bitstatus = RESET; - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_HASH_GET_IT(HASH_IT)); - - - /* Check the status of the specified HASH interrupt */ - tmpreg = HASH->SR; - - if (((HASH->IMR & tmpreg) & HASH_IT) != RESET) - { - /* HASH_IT is set */ - bitstatus = SET; - } - else - { - /* HASH_IT is reset */ - bitstatus = RESET; - } - /* Return the HASH_IT status */ - return bitstatus; -} - -/** - * @brief Clears the HASH interrupt pending bit(s). - * @param HASH_IT: specifies the HASH interrupt pending bit(s) to clear. - * This parameter can be any combination of the following values: - * @arg HASH_IT_DINI: Data Input interrupt - * @arg HASH_IT_DCI: Digest Calculation Completion Interrupt - * @retval None - */ -void HASH_ClearITPendingBit(uint8_t HASH_IT) -{ - /* Check the parameters */ - assert_param(IS_HASH_IT(HASH_IT)); - - /* Clear the selected HASH interrupt pending bit */ - HASH->SR = (uint8_t)~HASH_IT; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash_md5.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash_md5.c deleted file mode 100644 index 2a61fafd5..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_hash_md5.c +++ /dev/null @@ -1,314 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_hash_md5.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides high level functions to compute the HASH MD5 and - * HMAC MD5 Digest of an input message. - * It uses the stm32f4xx_hash.c/.h drivers to access the STM32F4xx HASH - * peripheral. - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable The HASH controller clock using - * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, ENABLE); function. - * - * 2. Calculate the HASH MD5 Digest using HASH_MD5() function. - * - * 3. Calculate the HMAC MD5 Digest using HMAC_MD5() function. - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_hash.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup HASH - * @brief HASH driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define MD5BUSY_TIMEOUT ((uint32_t) 0x00010000) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup HASH_Private_Functions - * @{ - */ - -/** @defgroup HASH_Group7 High Level MD5 functions - * @brief High Level MD5 Hash and HMAC functions - * -@verbatim - =============================================================================== - High Level MD5 Hash and HMAC functions - =============================================================================== - - -@endverbatim - * @{ - */ - -/** - * @brief Compute the HASH MD5 digest. - * @param Input: pointer to the Input buffer to be treated. - * @param Ilen: length of the Input buffer. - * @param Output: the returned digest - * @retval An ErrorStatus enumeration value: - * - SUCCESS: digest computation done - * - ERROR: digest computation failed - */ -ErrorStatus HASH_MD5(uint8_t *Input, uint32_t Ilen, uint8_t Output[16]) -{ - HASH_InitTypeDef MD5_HASH_InitStructure; - HASH_MsgDigest MD5_MessageDigest; - __IO uint16_t nbvalidbitsdata = 0; - uint32_t i = 0; - __IO uint32_t counter = 0; - uint32_t busystatus = 0; - ErrorStatus status = SUCCESS; - uint32_t inputaddr = (uint32_t)Input; - uint32_t outputaddr = (uint32_t)Output; - - - /* Number of valid bits in last word of the Input data */ - nbvalidbitsdata = 8 * (Ilen % 4); - - /* HASH peripheral initialization */ - HASH_DeInit(); - - /* HASH Configuration */ - MD5_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_MD5; - MD5_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HASH; - MD5_HASH_InitStructure.HASH_DataType = HASH_DataType_8b; - HASH_Init(&MD5_HASH_InitStructure); - - /* Configure the number of valid bits in last word of the data */ - HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); - - /* Write the Input block in the IN FIFO */ - for(i=0; i 64) - { - /* HMAC long Key */ - MD5_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey; - } - else - { - /* HMAC short Key */ - MD5_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_ShortKey; - } - HASH_Init(&MD5_HASH_InitStructure); - - /* Configure the number of valid bits in last word of the Key */ - HASH_SetLastWordValidBitsNbr(nbvalidbitskey); - - /* Write the Key */ - for(i=0; i
© COPYRIGHT 2011 STMicroelectronics
- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_hash.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup HASH - * @brief HASH driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define SHA1BUSY_TIMEOUT ((uint32_t) 0x00010000) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup HASH_Private_Functions - * @{ - */ - -/** @defgroup HASH_Group6 High Level SHA1 functions - * @brief High Level SHA1 Hash and HMAC functions - * -@verbatim - =============================================================================== - High Level SHA1 Hash and HMAC functions - =============================================================================== - - -@endverbatim - * @{ - */ - -/** - * @brief Compute the HASH SHA1 digest. - * @param Input: pointer to the Input buffer to be treated. - * @param Ilen: length of the Input buffer. - * @param Output: the returned digest - * @retval An ErrorStatus enumeration value: - * - SUCCESS: digest computation done - * - ERROR: digest computation failed - */ -ErrorStatus HASH_SHA1(uint8_t *Input, uint32_t Ilen, uint8_t Output[20]) -{ - HASH_InitTypeDef SHA1_HASH_InitStructure; - HASH_MsgDigest SHA1_MessageDigest; - __IO uint16_t nbvalidbitsdata = 0; - uint32_t i = 0; - __IO uint32_t counter = 0; - uint32_t busystatus = 0; - ErrorStatus status = SUCCESS; - uint32_t inputaddr = (uint32_t)Input; - uint32_t outputaddr = (uint32_t)Output; - - /* Number of valid bits in last word of the Input data */ - nbvalidbitsdata = 8 * (Ilen % 4); - - /* HASH peripheral initialization */ - HASH_DeInit(); - - /* HASH Configuration */ - SHA1_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_SHA1; - SHA1_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HASH; - SHA1_HASH_InitStructure.HASH_DataType = HASH_DataType_8b; - HASH_Init(&SHA1_HASH_InitStructure); - - /* Configure the number of valid bits in last word of the data */ - HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); - - /* Write the Input block in the IN FIFO */ - for(i=0; i 64) - { - /* HMAC long Key */ - SHA1_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey; - } - else - { - /* HMAC short Key */ - SHA1_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_ShortKey; - } - HASH_Init(&SHA1_HASH_InitStructure); - - /* Configure the number of valid bits in last word of the Key */ - HASH_SetLastWordValidBitsNbr(nbvalidbitskey); - - /* Write the Key */ - for(i=0; iGPIO_Mode = GPIO_Mode_AF - * - Select the type, pull-up/pull-down and output speed via - * GPIO_PuPd, GPIO_OType and GPIO_Speed members - * - Call GPIO_Init() function - * Recommended configuration is Push-Pull, Pull-up, Open-Drain. - * Add an external pull up if necessary (typically 4.7 KOhm). - * - * 4. Program the Mode, duty cycle , Own address, Ack, Speed and Acknowledged - * Address using the I2C_Init() function. - * - * 5. Optionally you can enable/configure the following parameters without - * re-initialization (i.e there is no need to call again I2C_Init() function): - * - Enable the acknowledge feature using I2C_AcknowledgeConfig() function - * - Enable the dual addressing mode using I2C_DualAddressCmd() function - * - Enable the general call using the I2C_GeneralCallCmd() function - * - Enable the clock stretching using I2C_StretchClockCmd() function - * - Enable the fast mode duty cycle using the I2C_FastModeDutyCycleConfig() - * function. - * - Configure the NACK position for Master Receiver mode in case of - * 2 bytes reception using the function I2C_NACKPositionConfig(). - * - Enable the PEC Calculation using I2C_CalculatePEC() function - * - For SMBus Mode: - * - Enable the Address Resolution Protocol (ARP) using I2C_ARPCmd() function - * - Configure the SMBusAlert pin using I2C_SMBusAlertConfig() function - * - * 6. Enable the NVIC and the corresponding interrupt using the function - * I2C_ITConfig() if you need to use interrupt mode. - * - * 7. When using the DMA mode - * - Configure the DMA using DMA_Init() function - * - Active the needed channel Request using I2C_DMACmd() or - * I2C_DMALastTransferCmd() function. - * @note When using DMA mode, I2C interrupts may be used at the same time to - * control the communication flow (Start/Stop/Ack... events and errors). - * - * 8. Enable the I2C using the I2C_Cmd() function. - * - * 9. Enable the DMA using the DMA_Cmd() function when using DMA mode in the - * transfers. - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_i2c.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup I2C - * @brief I2C driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -#define CR1_CLEAR_MASK ((uint16_t)0xFBF5) /*I2C_ClockSpeed)); - assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode)); - assert_param(IS_I2C_DUTY_CYCLE(I2C_InitStruct->I2C_DutyCycle)); - assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1)); - assert_param(IS_I2C_ACK_STATE(I2C_InitStruct->I2C_Ack)); - assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress)); - -/*---------------------------- I2Cx CR2 Configuration ------------------------*/ - /* Get the I2Cx CR2 value */ - tmpreg = I2Cx->CR2; - /* Clear frequency FREQ[5:0] bits */ - tmpreg &= (uint16_t)~((uint16_t)I2C_CR2_FREQ); - /* Get pclk1 frequency value */ - RCC_GetClocksFreq(&rcc_clocks); - pclk1 = rcc_clocks.PCLK1_Frequency; - /* Set frequency bits depending on pclk1 value */ - freqrange = (uint16_t)(pclk1 / 1000000); - tmpreg |= freqrange; - /* Write to I2Cx CR2 */ - I2Cx->CR2 = tmpreg; - -/*---------------------------- I2Cx CCR Configuration ------------------------*/ - /* Disable the selected I2C peripheral to configure TRISE */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PE); - /* Reset tmpreg value */ - /* Clear F/S, DUTY and CCR[11:0] bits */ - tmpreg = 0; - - /* Configure speed in standard mode */ - if (I2C_InitStruct->I2C_ClockSpeed <= 100000) - { - /* Standard mode speed calculate */ - result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed << 1)); - /* Test if CCR value is under 0x4*/ - if (result < 0x04) - { - /* Set minimum allowed value */ - result = 0x04; - } - /* Set speed value for standard mode */ - tmpreg |= result; - /* Set Maximum Rise Time for standard mode */ - I2Cx->TRISE = freqrange + 1; - } - /* Configure speed in fast mode */ - /* To use the I2C at 400 KHz (in fast mode), the PCLK1 frequency (I2C peripheral - input clock) must be a multiple of 10 MHz */ - else /*(I2C_InitStruct->I2C_ClockSpeed <= 400000)*/ - { - if (I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_2) - { - /* Fast mode speed calculate: Tlow/Thigh = 2 */ - result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 3)); - } - else /*I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_16_9*/ - { - /* Fast mode speed calculate: Tlow/Thigh = 16/9 */ - result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 25)); - /* Set DUTY bit */ - result |= I2C_DutyCycle_16_9; - } - - /* Test if CCR value is under 0x1*/ - if ((result & I2C_CCR_CCR) == 0) - { - /* Set minimum allowed value */ - result |= (uint16_t)0x0001; - } - /* Set speed value and set F/S bit for fast mode */ - tmpreg |= (uint16_t)(result | I2C_CCR_FS); - /* Set Maximum Rise Time for fast mode */ - I2Cx->TRISE = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1); - } - - /* Write to I2Cx CCR */ - I2Cx->CCR = tmpreg; - /* Enable the selected I2C peripheral */ - I2Cx->CR1 |= I2C_CR1_PE; - -/*---------------------------- I2Cx CR1 Configuration ------------------------*/ - /* Get the I2Cx CR1 value */ - tmpreg = I2Cx->CR1; - /* Clear ACK, SMBTYPE and SMBUS bits */ - tmpreg &= CR1_CLEAR_MASK; - /* Configure I2Cx: mode and acknowledgement */ - /* Set SMBTYPE and SMBUS bits according to I2C_Mode value */ - /* Set ACK bit according to I2C_Ack value */ - tmpreg |= (uint16_t)((uint32_t)I2C_InitStruct->I2C_Mode | I2C_InitStruct->I2C_Ack); - /* Write to I2Cx CR1 */ - I2Cx->CR1 = tmpreg; - -/*---------------------------- I2Cx OAR1 Configuration -----------------------*/ - /* Set I2Cx Own Address1 and acknowledged address */ - I2Cx->OAR1 = (I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1); -} - -/** - * @brief Fills each I2C_InitStruct member with its default value. - * @param I2C_InitStruct: pointer to an I2C_InitTypeDef structure which will be initialized. - * @retval None - */ -void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct) -{ -/*---------------- Reset I2C init structure parameters values ----------------*/ - /* initialize the I2C_ClockSpeed member */ - I2C_InitStruct->I2C_ClockSpeed = 5000; - /* Initialize the I2C_Mode member */ - I2C_InitStruct->I2C_Mode = I2C_Mode_I2C; - /* Initialize the I2C_DutyCycle member */ - I2C_InitStruct->I2C_DutyCycle = I2C_DutyCycle_2; - /* Initialize the I2C_OwnAddress1 member */ - I2C_InitStruct->I2C_OwnAddress1 = 0; - /* Initialize the I2C_Ack member */ - I2C_InitStruct->I2C_Ack = I2C_Ack_Disable; - /* Initialize the I2C_AcknowledgedAddress member */ - I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; -} - -/** - * @brief Enables or disables the specified I2C peripheral. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param NewState: new state of the I2Cx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C peripheral */ - I2Cx->CR1 |= I2C_CR1_PE; - } - else - { - /* Disable the selected I2C peripheral */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PE); - } -} - -/** - * @brief Generates I2Cx communication START condition. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param NewState: new state of the I2C START condition generation. - * This parameter can be: ENABLE or DISABLE. - * @retval None. - */ -void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Generate a START condition */ - I2Cx->CR1 |= I2C_CR1_START; - } - else - { - /* Disable the START condition generation */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_START); - } -} - -/** - * @brief Generates I2Cx communication STOP condition. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param NewState: new state of the I2C STOP condition generation. - * This parameter can be: ENABLE or DISABLE. - * @retval None. - */ -void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Generate a STOP condition */ - I2Cx->CR1 |= I2C_CR1_STOP; - } - else - { - /* Disable the STOP condition generation */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_STOP); - } -} - -/** - * @brief Transmits the address byte to select the slave device. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param Address: specifies the slave address which will be transmitted - * @param I2C_Direction: specifies whether the I2C device will be a Transmitter - * or a Receiver. - * This parameter can be one of the following values - * @arg I2C_Direction_Transmitter: Transmitter mode - * @arg I2C_Direction_Receiver: Receiver mode - * @retval None. - */ -void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_DIRECTION(I2C_Direction)); - /* Test on the direction to set/reset the read/write bit */ - if (I2C_Direction != I2C_Direction_Transmitter) - { - /* Set the address bit0 for read */ - Address |= I2C_OAR1_ADD0; - } - else - { - /* Reset the address bit0 for write */ - Address &= (uint8_t)~((uint8_t)I2C_OAR1_ADD0); - } - /* Send the address */ - I2Cx->DR = Address; -} - -/** - * @brief Enables or disables the specified I2C acknowledge feature. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param NewState: new state of the I2C Acknowledgement. - * This parameter can be: ENABLE or DISABLE. - * @retval None. - */ -void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the acknowledgement */ - I2Cx->CR1 |= I2C_CR1_ACK; - } - else - { - /* Disable the acknowledgement */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ACK); - } -} - -/** - * @brief Configures the specified I2C own address2. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param Address: specifies the 7bit I2C own address2. - * @retval None. - */ -void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address) -{ - uint16_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - - /* Get the old register value */ - tmpreg = I2Cx->OAR2; - - /* Reset I2Cx Own address2 bit [7:1] */ - tmpreg &= (uint16_t)~((uint16_t)I2C_OAR2_ADD2); - - /* Set I2Cx Own address2 */ - tmpreg |= (uint16_t)((uint16_t)Address & (uint16_t)0x00FE); - - /* Store the new register value */ - I2Cx->OAR2 = tmpreg; -} - -/** - * @brief Enables or disables the specified I2C dual addressing mode. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param NewState: new state of the I2C dual addressing mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable dual addressing mode */ - I2Cx->OAR2 |= I2C_OAR2_ENDUAL; - } - else - { - /* Disable dual addressing mode */ - I2Cx->OAR2 &= (uint16_t)~((uint16_t)I2C_OAR2_ENDUAL); - } -} - -/** - * @brief Enables or disables the specified I2C general call feature. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param NewState: new state of the I2C General call. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable generall call */ - I2Cx->CR1 |= I2C_CR1_ENGC; - } - else - { - /* Disable generall call */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENGC); - } -} - -/** - * @brief Enables or disables the specified I2C software reset. - * @note When software reset is enabled, the I2C IOs are released (this can - * be useful to recover from bus errors). - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param NewState: new state of the I2C software reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Peripheral under reset */ - I2Cx->CR1 |= I2C_CR1_SWRST; - } - else - { - /* Peripheral not under reset */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_SWRST); - } -} - -/** - * @brief Enables or disables the specified I2C Clock stretching. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param NewState: new state of the I2Cx Clock stretching. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState == DISABLE) - { - /* Enable the selected I2C Clock stretching */ - I2Cx->CR1 |= I2C_CR1_NOSTRETCH; - } - else - { - /* Disable the selected I2C Clock stretching */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_NOSTRETCH); - } -} - -/** - * @brief Selects the specified I2C fast mode duty cycle. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param I2C_DutyCycle: specifies the fast mode duty cycle. - * This parameter can be one of the following values: - * @arg I2C_DutyCycle_2: I2C fast mode Tlow/Thigh = 2 - * @arg I2C_DutyCycle_16_9: I2C fast mode Tlow/Thigh = 16/9 - * @retval None - */ -void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_DUTY_CYCLE(I2C_DutyCycle)); - if (I2C_DutyCycle != I2C_DutyCycle_16_9) - { - /* I2C fast mode Tlow/Thigh=2 */ - I2Cx->CCR &= I2C_DutyCycle_2; - } - else - { - /* I2C fast mode Tlow/Thigh=16/9 */ - I2Cx->CCR |= I2C_DutyCycle_16_9; - } -} - -/** - * @brief Selects the specified I2C NACK position in master receiver mode. - * @note This function is useful in I2C Master Receiver mode when the number - * of data to be received is equal to 2. In this case, this function - * should be called (with parameter I2C_NACKPosition_Next) before data - * reception starts,as described in the 2-byte reception procedure - * recommended in Reference Manual in Section: Master receiver. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param I2C_NACKPosition: specifies the NACK position. - * This parameter can be one of the following values: - * @arg I2C_NACKPosition_Next: indicates that the next byte will be the last - * received byte. - * @arg I2C_NACKPosition_Current: indicates that current byte is the last - * received byte. - * - * @note This function configures the same bit (POS) as I2C_PECPositionConfig() - * but is intended to be used in I2C mode while I2C_PECPositionConfig() - * is intended to used in SMBUS mode. - * - * @retval None - */ -void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_NACK_POSITION(I2C_NACKPosition)); - - /* Check the input parameter */ - if (I2C_NACKPosition == I2C_NACKPosition_Next) - { - /* Next byte in shift register is the last received byte */ - I2Cx->CR1 |= I2C_NACKPosition_Next; - } - else - { - /* Current byte in shift register is the last received byte */ - I2Cx->CR1 &= I2C_NACKPosition_Current; - } -} - -/** - * @brief Drives the SMBusAlert pin high or low for the specified I2C. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param I2C_SMBusAlert: specifies SMBAlert pin level. - * This parameter can be one of the following values: - * @arg I2C_SMBusAlert_Low: SMBAlert pin driven low - * @arg I2C_SMBusAlert_High: SMBAlert pin driven high - * @retval None - */ -void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_SMBUS_ALERT(I2C_SMBusAlert)); - if (I2C_SMBusAlert == I2C_SMBusAlert_Low) - { - /* Drive the SMBusAlert pin Low */ - I2Cx->CR1 |= I2C_SMBusAlert_Low; - } - else - { - /* Drive the SMBusAlert pin High */ - I2Cx->CR1 &= I2C_SMBusAlert_High; - } -} - -/** - * @brief Enables or disables the specified I2C ARP. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param NewState: new state of the I2Cx ARP. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C ARP */ - I2Cx->CR1 |= I2C_CR1_ENARP; - } - else - { - /* Disable the selected I2C ARP */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENARP); - } -} -/** - * @} - */ - -/** @defgroup I2C_Group2 Data transfers functions - * @brief Data transfers functions - * -@verbatim - =============================================================================== - Data transfers functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Sends a data byte through the I2Cx peripheral. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param Data: Byte to be transmitted.. - * @retval None - */ -void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - /* Write in the DR register the data to be sent */ - I2Cx->DR = Data; -} - -/** - * @brief Returns the most recent received data by the I2Cx peripheral. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @retval The value of the received data. - */ -uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - /* Return the data in the DR register */ - return (uint8_t)I2Cx->DR; -} - -/** - * @} - */ - -/** @defgroup I2C_Group3 PEC management functions - * @brief PEC management functions - * -@verbatim - =============================================================================== - PEC management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified I2C PEC transfer. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param NewState: new state of the I2C PEC transmission. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C PEC transmission */ - I2Cx->CR1 |= I2C_CR1_PEC; - } - else - { - /* Disable the selected I2C PEC transmission */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PEC); - } -} - -/** - * @brief Selects the specified I2C PEC position. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param I2C_PECPosition: specifies the PEC position. - * This parameter can be one of the following values: - * @arg I2C_PECPosition_Next: indicates that the next byte is PEC - * @arg I2C_PECPosition_Current: indicates that current byte is PEC - * - * @note This function configures the same bit (POS) as I2C_NACKPositionConfig() - * but is intended to be used in SMBUS mode while I2C_NACKPositionConfig() - * is intended to used in I2C mode. - * - * @retval None - */ -void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_PEC_POSITION(I2C_PECPosition)); - if (I2C_PECPosition == I2C_PECPosition_Next) - { - /* Next byte in shift register is PEC */ - I2Cx->CR1 |= I2C_PECPosition_Next; - } - else - { - /* Current byte in shift register is PEC */ - I2Cx->CR1 &= I2C_PECPosition_Current; - } -} - -/** - * @brief Enables or disables the PEC value calculation of the transferred bytes. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param NewState: new state of the I2Cx PEC value calculation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C PEC calculation */ - I2Cx->CR1 |= I2C_CR1_ENPEC; - } - else - { - /* Disable the selected I2C PEC calculation */ - I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENPEC); - } -} - -/** - * @brief Returns the PEC value for the specified I2C. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @retval The PEC value. - */ -uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - /* Return the selected I2C PEC value */ - return ((I2Cx->SR2) >> 8); -} - -/** - * @} - */ - -/** @defgroup I2C_Group4 DMA transfers management functions - * @brief DMA transfers management functions - * -@verbatim - =============================================================================== - DMA transfers management functions - =============================================================================== - This section provides functions allowing to configure the I2C DMA channels - requests. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified I2C DMA requests. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param NewState: new state of the I2C DMA transfer. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected I2C DMA requests */ - I2Cx->CR2 |= I2C_CR2_DMAEN; - } - else - { - /* Disable the selected I2C DMA requests */ - I2Cx->CR2 &= (uint16_t)~((uint16_t)I2C_CR2_DMAEN); - } -} - -/** - * @brief Specifies that the next DMA transfer is the last one. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param NewState: new state of the I2C DMA last transfer. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Next DMA transfer is the last transfer */ - I2Cx->CR2 |= I2C_CR2_LAST; - } - else - { - /* Next DMA transfer is not the last transfer */ - I2Cx->CR2 &= (uint16_t)~((uint16_t)I2C_CR2_LAST); - } -} - -/** - * @} - */ - -/** @defgroup I2C_Group5 Interrupts events and flags management functions - * @brief Interrupts, events and flags management functions - * -@verbatim - =============================================================================== - Interrupts, events and flags management functions - =============================================================================== - This section provides functions allowing to configure the I2C Interrupts - sources and check or clear the flags or pending bits status. - The user should identify which mode will be used in his application to manage - the communication: Polling mode, Interrupt mode or DMA mode. - - =============================================================================== - I2C State Monitoring Functions - =============================================================================== - This I2C driver provides three different ways for I2C state monitoring - depending on the application requirements and constraints: - - - 1. Basic state monitoring (Using I2C_CheckEvent() function) - ----------------------------------------------------------- - It compares the status registers (SR1 and SR2) content to a given event - (can be the combination of one or more flags). - It returns SUCCESS if the current status includes the given flags - and returns ERROR if one or more flags are missing in the current status. - - - When to use - - This function is suitable for most applications as well as for startup - activity since the events are fully described in the product reference - manual (RM0090). - - It is also suitable for users who need to define their own events. - - - Limitations - - If an error occurs (ie. error flags are set besides to the monitored - flags), the I2C_CheckEvent() function may return SUCCESS despite - the communication hold or corrupted real state. - In this case, it is advised to use error interrupts to monitor - the error events and handle them in the interrupt IRQ handler. - - @note - For error management, it is advised to use the following functions: - - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR). - - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs. - Where x is the peripheral instance (I2C1, I2C2 ...) - - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into the - I2Cx_ER_IRQHandler() function in order to determine which error occurred. - - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd() - and/or I2C_GenerateStop() in order to clear the error flag and source - and return to correct communication status. - - - 2. Advanced state monitoring (Using the function I2C_GetLastEvent()) - -------------------------------------------------------------------- - Using the function I2C_GetLastEvent() which returns the image of both status - registers in a single word (uint32_t) (Status Register 2 value is shifted left - by 16 bits and concatenated to Status Register 1). - - - When to use - - This function is suitable for the same applications above but it - allows to overcome the mentioned limitation of I2C_GetFlagStatus() - function. - - The returned value could be compared to events already defined in - the library (stm32f4xx_i2c.h) or to custom values defined by user. - This function is suitable when multiple flags are monitored at the - same time. - - At the opposite of I2C_CheckEvent() function, this function allows - user to choose when an event is accepted (when all events flags are - set and no other flags are set or just when the needed flags are set - like I2C_CheckEvent() function. - - - Limitations - - User may need to define his own events. - - Same remark concerning the error management is applicable for this - function if user decides to check only regular communication flags - (and ignores error flags). - - - 3. Flag-based state monitoring (Using the function I2C_GetFlagStatus()) - ----------------------------------------------------------------------- - - Using the function I2C_GetFlagStatus() which simply returns the status of - one single flag (ie. I2C_FLAG_RXNE ...). - - - When to use - - This function could be used for specific applications or in debug - phase. - - It is suitable when only one flag checking is needed (most I2C - events are monitored through multiple flags). - - Limitations: - - When calling this function, the Status register is accessed. - Some flags are cleared when the status register is accessed. - So checking the status of one Flag, may clear other ones. - - Function may need to be called twice or more in order to monitor - one single event. - - For detailed description of Events, please refer to section I2C_Events in - stm32f4xx_i2c.h file. - -@endverbatim - * @{ - */ - -/** - * @brief Reads the specified I2C register and returns its value. - * @param I2C_Register: specifies the register to read. - * This parameter can be one of the following values: - * @arg I2C_Register_CR1: CR1 register. - * @arg I2C_Register_CR2: CR2 register. - * @arg I2C_Register_OAR1: OAR1 register. - * @arg I2C_Register_OAR2: OAR2 register. - * @arg I2C_Register_DR: DR register. - * @arg I2C_Register_SR1: SR1 register. - * @arg I2C_Register_SR2: SR2 register. - * @arg I2C_Register_CCR: CCR register. - * @arg I2C_Register_TRISE: TRISE register. - * @retval The value of the read register. - */ -uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_REGISTER(I2C_Register)); - - tmp = (uint32_t) I2Cx; - tmp += I2C_Register; - - /* Return the selected register value */ - return (*(__IO uint16_t *) tmp); -} - -/** - * @brief Enables or disables the specified I2C interrupts. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param I2C_IT: specifies the I2C interrupts sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg I2C_IT_BUF: Buffer interrupt mask - * @arg I2C_IT_EVT: Event interrupt mask - * @arg I2C_IT_ERR: Error interrupt mask - * @param NewState: new state of the specified I2C interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_I2C_CONFIG_IT(I2C_IT)); - - if (NewState != DISABLE) - { - /* Enable the selected I2C interrupts */ - I2Cx->CR2 |= I2C_IT; - } - else - { - /* Disable the selected I2C interrupts */ - I2Cx->CR2 &= (uint16_t)~I2C_IT; - } -} - -/* - =============================================================================== - 1. Basic state monitoring - =============================================================================== - */ - -/** - * @brief Checks whether the last I2Cx Event is equal to the one passed - * as parameter. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param I2C_EVENT: specifies the event to be checked. - * This parameter can be one of the following values: - * @arg I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: EV1 - * @arg I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: EV1 - * @arg I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED: EV1 - * @arg I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED: EV1 - * @arg I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED: EV1 - * @arg I2C_EVENT_SLAVE_BYTE_RECEIVED: EV2 - * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF): EV2 - * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL): EV2 - * @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED: EV3 - * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF): EV3 - * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL): EV3 - * @arg I2C_EVENT_SLAVE_ACK_FAILURE: EV3_2 - * @arg I2C_EVENT_SLAVE_STOP_DETECTED: EV4 - * @arg I2C_EVENT_MASTER_MODE_SELECT: EV5 - * @arg I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: EV6 - * @arg I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: EV6 - * @arg I2C_EVENT_MASTER_BYTE_RECEIVED: EV7 - * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTING: EV8 - * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTED: EV8_2 - * @arg I2C_EVENT_MASTER_MODE_ADDRESS10: EV9 - * - * @note For detailed description of Events, please refer to section I2C_Events - * in stm32f4xx_i2c.h file. - * - * @retval An ErrorStatus enumeration value: - * - SUCCESS: Last event is equal to the I2C_EVENT - * - ERROR: Last event is different from the I2C_EVENT - */ -ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) -{ - uint32_t lastevent = 0; - uint32_t flag1 = 0, flag2 = 0; - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_EVENT(I2C_EVENT)); - - /* Read the I2Cx status register */ - flag1 = I2Cx->SR1; - flag2 = I2Cx->SR2; - flag2 = flag2 << 16; - - /* Get the last event value from I2C status register */ - lastevent = (flag1 | flag2) & FLAG_MASK; - - /* Check whether the last event contains the I2C_EVENT */ - if ((lastevent & I2C_EVENT) == I2C_EVENT) - { - /* SUCCESS: last event is equal to I2C_EVENT */ - status = SUCCESS; - } - else - { - /* ERROR: last event is different from I2C_EVENT */ - status = ERROR; - } - /* Return status */ - return status; -} - -/* - =============================================================================== - 2. Advanced state monitoring - =============================================================================== - */ - -/** - * @brief Returns the last I2Cx Event. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * - * @note For detailed description of Events, please refer to section I2C_Events - * in stm32f4xx_i2c.h file. - * - * @retval The last event - */ -uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx) -{ - uint32_t lastevent = 0; - uint32_t flag1 = 0, flag2 = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - - /* Read the I2Cx status register */ - flag1 = I2Cx->SR1; - flag2 = I2Cx->SR2; - flag2 = flag2 << 16; - - /* Get the last event value from I2C status register */ - lastevent = (flag1 | flag2) & FLAG_MASK; - - /* Return status */ - return lastevent; -} - -/* - =============================================================================== - 3. Flag-based state monitoring - =============================================================================== - */ - -/** - * @brief Checks whether the specified I2C flag is set or not. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param I2C_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg I2C_FLAG_DUALF: Dual flag (Slave mode) - * @arg I2C_FLAG_SMBHOST: SMBus host header (Slave mode) - * @arg I2C_FLAG_SMBDEFAULT: SMBus default header (Slave mode) - * @arg I2C_FLAG_GENCALL: General call header flag (Slave mode) - * @arg I2C_FLAG_TRA: Transmitter/Receiver flag - * @arg I2C_FLAG_BUSY: Bus busy flag - * @arg I2C_FLAG_MSL: Master/Slave flag - * @arg I2C_FLAG_SMBALERT: SMBus Alert flag - * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag - * @arg I2C_FLAG_PECERR: PEC error in reception flag - * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) - * @arg I2C_FLAG_AF: Acknowledge failure flag - * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) - * @arg I2C_FLAG_BERR: Bus error flag - * @arg I2C_FLAG_TXE: Data register empty flag (Transmitter) - * @arg I2C_FLAG_RXNE: Data register not empty (Receiver) flag - * @arg I2C_FLAG_STOPF: Stop detection flag (Slave mode) - * @arg I2C_FLAG_ADD10: 10-bit header sent flag (Master mode) - * @arg I2C_FLAG_BTF: Byte transfer finished flag - * @arg I2C_FLAG_ADDR: Address sent flag (Master mode) "ADSL" - * Address matched flag (Slave mode)"ENDAD" - * @arg I2C_FLAG_SB: Start bit flag (Master mode) - * @retval The new state of I2C_FLAG (SET or RESET). - */ -FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) -{ - FlagStatus bitstatus = RESET; - __IO uint32_t i2creg = 0, i2cxbase = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_GET_FLAG(I2C_FLAG)); - - /* Get the I2Cx peripheral base address */ - i2cxbase = (uint32_t)I2Cx; - - /* Read flag register index */ - i2creg = I2C_FLAG >> 28; - - /* Get bit[23:0] of the flag */ - I2C_FLAG &= FLAG_MASK; - - if(i2creg != 0) - { - /* Get the I2Cx SR1 register address */ - i2cxbase += 0x14; - } - else - { - /* Flag in I2Cx SR2 Register */ - I2C_FLAG = (uint32_t)(I2C_FLAG >> 16); - /* Get the I2Cx SR2 register address */ - i2cxbase += 0x18; - } - - if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET) - { - /* I2C_FLAG is set */ - bitstatus = SET; - } - else - { - /* I2C_FLAG is reset */ - bitstatus = RESET; - } - - /* Return the I2C_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the I2Cx's pending flags. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param I2C_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg I2C_FLAG_SMBALERT: SMBus Alert flag - * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag - * @arg I2C_FLAG_PECERR: PEC error in reception flag - * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) - * @arg I2C_FLAG_AF: Acknowledge failure flag - * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) - * @arg I2C_FLAG_BERR: Bus error flag - * - * @note STOPF (STOP detection) is cleared by software sequence: a read operation - * to I2C_SR1 register (I2C_GetFlagStatus()) followed by a write operation - * to I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral). - * @note ADD10 (10-bit header sent) is cleared by software sequence: a read - * operation to I2C_SR1 (I2C_GetFlagStatus()) followed by writing the - * second byte of the address in DR register. - * @note BTF (Byte Transfer Finished) is cleared by software sequence: a read - * operation to I2C_SR1 register (I2C_GetFlagStatus()) followed by a - * read/write to I2C_DR register (I2C_SendData()). - * @note ADDR (Address sent) is cleared by software sequence: a read operation to - * I2C_SR1 register (I2C_GetFlagStatus()) followed by a read operation to - * I2C_SR2 register ((void)(I2Cx->SR2)). - * @note SB (Start Bit) is cleared software sequence: a read operation to I2C_SR1 - * register (I2C_GetFlagStatus()) followed by a write operation to I2C_DR - * register (I2C_SendData()). - * - * @retval None - */ -void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) -{ - uint32_t flagpos = 0; - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_CLEAR_FLAG(I2C_FLAG)); - /* Get the I2C flag position */ - flagpos = I2C_FLAG & FLAG_MASK; - /* Clear the selected I2C flag */ - I2Cx->SR1 = (uint16_t)~flagpos; -} - -/** - * @brief Checks whether the specified I2C interrupt has occurred or not. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param I2C_IT: specifies the interrupt source to check. - * This parameter can be one of the following values: - * @arg I2C_IT_SMBALERT: SMBus Alert flag - * @arg I2C_IT_TIMEOUT: Timeout or Tlow error flag - * @arg I2C_IT_PECERR: PEC error in reception flag - * @arg I2C_IT_OVR: Overrun/Underrun flag (Slave mode) - * @arg I2C_IT_AF: Acknowledge failure flag - * @arg I2C_IT_ARLO: Arbitration lost flag (Master mode) - * @arg I2C_IT_BERR: Bus error flag - * @arg I2C_IT_TXE: Data register empty flag (Transmitter) - * @arg I2C_IT_RXNE: Data register not empty (Receiver) flag - * @arg I2C_IT_STOPF: Stop detection flag (Slave mode) - * @arg I2C_IT_ADD10: 10-bit header sent flag (Master mode) - * @arg I2C_IT_BTF: Byte transfer finished flag - * @arg I2C_IT_ADDR: Address sent flag (Master mode) "ADSL" - * Address matched flag (Slave mode)"ENDAD" - * @arg I2C_IT_SB: Start bit flag (Master mode) - * @retval The new state of I2C_IT (SET or RESET). - */ -ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT) -{ - ITStatus bitstatus = RESET; - uint32_t enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_GET_IT(I2C_IT)); - - /* Check if the interrupt source is enabled or not */ - enablestatus = (uint32_t)(((I2C_IT & ITEN_MASK) >> 16) & (I2Cx->CR2)) ; - - /* Get bit[23:0] of the flag */ - I2C_IT &= FLAG_MASK; - - /* Check the status of the specified I2C flag */ - if (((I2Cx->SR1 & I2C_IT) != (uint32_t)RESET) && enablestatus) - { - /* I2C_IT is set */ - bitstatus = SET; - } - else - { - /* I2C_IT is reset */ - bitstatus = RESET; - } - /* Return the I2C_IT status */ - return bitstatus; -} - -/** - * @brief Clears the I2Cx's interrupt pending bits. - * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral. - * @param I2C_IT: specifies the interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg I2C_IT_SMBALERT: SMBus Alert interrupt - * @arg I2C_IT_TIMEOUT: Timeout or Tlow error interrupt - * @arg I2C_IT_PECERR: PEC error in reception interrupt - * @arg I2C_IT_OVR: Overrun/Underrun interrupt (Slave mode) - * @arg I2C_IT_AF: Acknowledge failure interrupt - * @arg I2C_IT_ARLO: Arbitration lost interrupt (Master mode) - * @arg I2C_IT_BERR: Bus error interrupt - * - * @note STOPF (STOP detection) is cleared by software sequence: a read operation - * to I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to - * I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral). - * @note ADD10 (10-bit header sent) is cleared by software sequence: a read - * operation to I2C_SR1 (I2C_GetITStatus()) followed by writing the second - * byte of the address in I2C_DR register. - * @note BTF (Byte Transfer Finished) is cleared by software sequence: a read - * operation to I2C_SR1 register (I2C_GetITStatus()) followed by a - * read/write to I2C_DR register (I2C_SendData()). - * @note ADDR (Address sent) is cleared by software sequence: a read operation to - * I2C_SR1 register (I2C_GetITStatus()) followed by a read operation to - * I2C_SR2 register ((void)(I2Cx->SR2)). - * @note SB (Start Bit) is cleared by software sequence: a read operation to - * I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to - * I2C_DR register (I2C_SendData()). - * @retval None - */ -void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT) -{ - uint32_t flagpos = 0; - /* Check the parameters */ - assert_param(IS_I2C_ALL_PERIPH(I2Cx)); - assert_param(IS_I2C_CLEAR_IT(I2C_IT)); - - /* Get the I2C flag position */ - flagpos = I2C_IT & FLAG_MASK; - - /* Clear the selected I2C flag */ - I2Cx->SR1 = (uint16_t)~flagpos; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_iwdg.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_iwdg.c deleted file mode 100644 index 30c9658c1..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_iwdg.c +++ /dev/null @@ -1,263 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_iwdg.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the Independent watchdog (IWDG) peripheral: - * - Prescaler and Counter configuration - * - IWDG activation - * - Flag management - * - * @verbatim - * - * =================================================================== - * IWDG features - * =================================================================== - * - * The IWDG can be started by either software or hardware (configurable - * through option byte). - * - * The IWDG is clocked by its own dedicated low-speed clock (LSI) and - * thus stays active even if the main clock fails. - * Once the IWDG is started, the LSI is forced ON and cannot be disabled - * (LSI cannot be disabled too), and the counter starts counting down from - * the reset value of 0xFFF. When it reaches the end of count value (0x000) - * a system reset is generated. - * The IWDG counter should be reloaded at regular intervals to prevent - * an MCU reset. - * - * The IWDG is implemented in the VDD voltage domain that is still functional - * in STOP and STANDBY mode (IWDG reset can wake-up from STANDBY). - * - * IWDGRST flag in RCC_CSR register can be used to inform when a IWDG - * reset occurs. - * - * Min-max timeout value @32KHz (LSI): ~125us / ~32.7s - * The IWDG timeout may vary due to LSI frequency dispersion. STM32F4xx - * devices provide the capability to measure the LSI frequency (LSI clock - * connected internally to TIM5 CH4 input capture). The measured value - * can be used to have an IWDG timeout with an acceptable accuracy. - * For more information, please refer to the STM32F4xx Reference manual - * - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable write access to IWDG_PR and IWDG_RLR registers using - * IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable) function - * - * 2. Configure the IWDG prescaler using IWDG_SetPrescaler() function - * - * 3. Configure the IWDG counter value using IWDG_SetReload() function. - * This value will be loaded in the IWDG counter each time the counter - * is reloaded, then the IWDG will start counting down from this value. - * - * 4. Start the IWDG using IWDG_Enable() function, when the IWDG is used - * in software mode (no need to enable the LSI, it will be enabled - * by hardware) - * - * 5. Then the application program must reload the IWDG counter at regular - * intervals during normal operation to prevent an MCU reset, using - * IWDG_ReloadCounter() function. - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_iwdg.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup IWDG - * @brief IWDG driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* KR register bit mask */ -#define KR_KEY_RELOAD ((uint16_t)0xAAAA) -#define KR_KEY_ENABLE ((uint16_t)0xCCCC) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup IWDG_Private_Functions - * @{ - */ - -/** @defgroup IWDG_Group1 Prescaler and Counter configuration functions - * @brief Prescaler and Counter configuration functions - * -@verbatim - =============================================================================== - Prescaler and Counter configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables write access to IWDG_PR and IWDG_RLR registers. - * @param IWDG_WriteAccess: new state of write access to IWDG_PR and IWDG_RLR registers. - * This parameter can be one of the following values: - * @arg IWDG_WriteAccess_Enable: Enable write access to IWDG_PR and IWDG_RLR registers - * @arg IWDG_WriteAccess_Disable: Disable write access to IWDG_PR and IWDG_RLR registers - * @retval None - */ -void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess) -{ - /* Check the parameters */ - assert_param(IS_IWDG_WRITE_ACCESS(IWDG_WriteAccess)); - IWDG->KR = IWDG_WriteAccess; -} - -/** - * @brief Sets IWDG Prescaler value. - * @param IWDG_Prescaler: specifies the IWDG Prescaler value. - * This parameter can be one of the following values: - * @arg IWDG_Prescaler_4: IWDG prescaler set to 4 - * @arg IWDG_Prescaler_8: IWDG prescaler set to 8 - * @arg IWDG_Prescaler_16: IWDG prescaler set to 16 - * @arg IWDG_Prescaler_32: IWDG prescaler set to 32 - * @arg IWDG_Prescaler_64: IWDG prescaler set to 64 - * @arg IWDG_Prescaler_128: IWDG prescaler set to 128 - * @arg IWDG_Prescaler_256: IWDG prescaler set to 256 - * @retval None - */ -void IWDG_SetPrescaler(uint8_t IWDG_Prescaler) -{ - /* Check the parameters */ - assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler)); - IWDG->PR = IWDG_Prescaler; -} - -/** - * @brief Sets IWDG Reload value. - * @param Reload: specifies the IWDG Reload value. - * This parameter must be a number between 0 and 0x0FFF. - * @retval None - */ -void IWDG_SetReload(uint16_t Reload) -{ - /* Check the parameters */ - assert_param(IS_IWDG_RELOAD(Reload)); - IWDG->RLR = Reload; -} - -/** - * @brief Reloads IWDG counter with value defined in the reload register - * (write access to IWDG_PR and IWDG_RLR registers disabled). - * @param None - * @retval None - */ -void IWDG_ReloadCounter(void) -{ - IWDG->KR = KR_KEY_RELOAD; -} - -/** - * @} - */ - -/** @defgroup IWDG_Group2 IWDG activation function - * @brief IWDG activation function - * -@verbatim - =============================================================================== - IWDG activation function - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables IWDG (write access to IWDG_PR and IWDG_RLR registers disabled). - * @param None - * @retval None - */ -void IWDG_Enable(void) -{ - IWDG->KR = KR_KEY_ENABLE; -} - -/** - * @} - */ - -/** @defgroup IWDG_Group3 Flag management function - * @brief Flag management function - * -@verbatim - =============================================================================== - Flag management function - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Checks whether the specified IWDG flag is set or not. - * @param IWDG_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg IWDG_FLAG_PVU: Prescaler Value Update on going - * @arg IWDG_FLAG_RVU: Reload Value Update on going - * @retval The new state of IWDG_FLAG (SET or RESET). - */ -FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_IWDG_FLAG(IWDG_FLAG)); - if ((IWDG->SR & IWDG_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the flag status */ - return bitstatus; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_pwr.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_pwr.c deleted file mode 100644 index ff16e2d82..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_pwr.c +++ /dev/null @@ -1,638 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_pwr.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the Power Controller (PWR) peripheral: - * - Backup Domain Access - * - PVD configuration - * - WakeUp pin configuration - * - Backup Regulator configuration - * - Performance Mode and FLASH Power Down configuration functions - * - Low Power modes configuration - * - Flags management - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_pwr.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup PWR - * @brief PWR driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* --------- PWR registers bit address in the alias region ---------- */ -#define PWR_OFFSET (PWR_BASE - PERIPH_BASE) - -/* --- CR Register ---*/ - -/* Alias word address of DBP bit */ -#define CR_OFFSET (PWR_OFFSET + 0x00) -#define DBP_BitNumber 0x08 -#define CR_DBP_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (DBP_BitNumber * 4)) - -/* Alias word address of PVDE bit */ -#define PVDE_BitNumber 0x04 -#define CR_PVDE_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PVDE_BitNumber * 4)) - -/* Alias word address of FPDS bit */ -#define FPDS_BitNumber 0x09 -#define CR_FPDS_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (FPDS_BitNumber * 4)) - -/* Alias word address of PMODE bit */ -#define PMODE_BitNumber 0x0E -#define CR_PMODE_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PMODE_BitNumber * 4)) - - -/* --- CSR Register ---*/ - -/* Alias word address of EWUP bit */ -#define CSR_OFFSET (PWR_OFFSET + 0x04) -#define EWUP_BitNumber 0x08 -#define CSR_EWUP_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (EWUP_BitNumber * 4)) - -/* Alias word address of BRE bit */ -#define BRE_BitNumber 0x09 -#define CSR_BRE_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (BRE_BitNumber * 4)) - -/* ------------------ PWR registers bit mask ------------------------ */ - -/* CR register bit mask */ -#define CR_DS_MASK ((uint32_t)0xFFFFFFFC) -#define CR_PLS_MASK ((uint32_t)0xFFFFFF1F) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup PWR_Private_Functions - * @{ - */ - -/** @defgroup PWR_Group1 Backup Domain Access function - * @brief Backup Domain Access function - * -@verbatim - =============================================================================== - Backup Domain Access function - =============================================================================== - - After reset, the backup domain (RTC registers, RTC backup data - registers and backup SRAM) is protected against possible unwanted - write accesses. - To enable access to the RTC Domain and RTC registers, proceed as follows: - - Enable the Power Controller (PWR) APB1 interface clock using the - RCC_APB1PeriphClockCmd() function. - - Enable access to RTC domain using the PWR_BackupAccessCmd() function. - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the PWR peripheral registers to their default reset values. - * @param None - * @retval None - */ -void PWR_DeInit(void) -{ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, DISABLE); -} - -/** - * @brief Enables or disables access to the backup domain (RTC registers, RTC - * backup data registers and backup SRAM). - * @note If the HSE divided by 2, 3, ..31 is used as the RTC clock, the - * Backup Domain Access should be kept enabled. - * @param NewState: new state of the access to the backup domain. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_BackupAccessCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_DBP_BB = (uint32_t)NewState; -} - -/** - * @} - */ - -/** @defgroup PWR_Group2 PVD configuration functions - * @brief PVD configuration functions - * -@verbatim - =============================================================================== - PVD configuration functions - =============================================================================== - - - The PVD is used to monitor the VDD power supply by comparing it to a threshold - selected by the PVD Level (PLS[2:0] bits in the PWR_CR). - - A PVDO flag is available to indicate if VDD/VDDA is higher or lower than the - PVD threshold. This event is internally connected to the EXTI line16 - and can generate an interrupt if enabled through the EXTI registers. - - The PVD is stopped in Standby mode. - -@endverbatim - * @{ - */ - -/** - * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD). - * @param PWR_PVDLevel: specifies the PVD detection level - * This parameter can be one of the following values: - * @arg PWR_PVDLevel_0: PVD detection level set to 2.0V - * @arg PWR_PVDLevel_1: PVD detection level set to 2.2V - * @arg PWR_PVDLevel_2: PVD detection level set to 2.3V - * @arg PWR_PVDLevel_3: PVD detection level set to 2.5V - * @arg PWR_PVDLevel_4: PVD detection level set to 2.7V - * @arg PWR_PVDLevel_5: PVD detection level set to 2.8V - * @arg PWR_PVDLevel_6: PVD detection level set to 2.9V - * @arg PWR_PVDLevel_7: PVD detection level set to 3.0V - * @note Refer to the electrical characteristics of you device datasheet for more details. - * @retval None - */ -void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_PWR_PVD_LEVEL(PWR_PVDLevel)); - - tmpreg = PWR->CR; - - /* Clear PLS[7:5] bits */ - tmpreg &= CR_PLS_MASK; - - /* Set PLS[7:5] bits according to PWR_PVDLevel value */ - tmpreg |= PWR_PVDLevel; - - /* Store the new value */ - PWR->CR = tmpreg; -} - -/** - * @brief Enables or disables the Power Voltage Detector(PVD). - * @param NewState: new state of the PVD. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_PVDCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)NewState; -} - -/** - * @} - */ - -/** @defgroup PWR_Group3 WakeUp pin configuration functions - * @brief WakeUp pin configuration functions - * -@verbatim - =============================================================================== - WakeUp pin configuration functions - =============================================================================== - - - WakeUp pin is used to wakeup the system from Standby mode. This pin is - forced in input pull down configuration and is active on rising edges. - - There is only one WakeUp pin: WakeUp Pin 1 on PA.00. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the WakeUp Pin functionality. - * @param NewState: new state of the WakeUp Pin functionality. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_WakeUpPinCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CSR_EWUP_BB = (uint32_t)NewState; -} - -/** - * @} - */ - -/** @defgroup PWR_Group4 Backup Regulator configuration functions - * @brief Backup Regulator configuration functions - * -@verbatim - =============================================================================== - Backup Regulator configuration functions - =============================================================================== - - - The backup domain includes 4 Kbytes of backup SRAM accessible only from the - CPU, and address in 32-bit, 16-bit or 8-bit mode. Its content is retained - even in Standby or VBAT mode when the low power backup regulator is enabled. - It can be considered as an internal EEPROM when VBAT is always present. - You can use the PWR_BackupRegulatorCmd() function to enable the low power - backup regulator and use the PWR_GetFlagStatus(PWR_FLAG_BRR) to check if it is - ready or not. - - - When the backup domain is supplied by VDD (analog switch connected to VDD) - the backup SRAM is powered from VDD which replaces the VBAT power supply to - save battery life. - - - The backup SRAM is not mass erased by an tamper event. It is read protected - to prevent confidential data, such as cryptographic private key, from being - accessed. The backup SRAM can be erased only through the Flash interface when - a protection level change from level 1 to level 0 is requested. - Refer to the description of Read protection (RDP) in the Flash programming manual. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the Backup Regulator. - * @param NewState: new state of the Backup Regulator. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_BackupRegulatorCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CSR_BRE_BB = (uint32_t)NewState; -} - -/** - * @} - */ - -/** @defgroup PWR_Group5 Performance Mode and FLASH Power Down configuration functions - * @brief Performance Mode and FLASH Power Down configuration functions - * -@verbatim - =============================================================================== - Performance Mode and FLASH Power Down configuration functions - =============================================================================== - - - By setting the PMODE bit in the PWR_CR register by using the PWR_HighPerformanceModeCmd() - function, the high performance mode is selected and the high voltage regulator - minimum value should be around 1.2V. - When reset, the low performance mode is selected and the low voltage regulator - minimum value should be around 1.08V. - - - By setting the FPDS bit in the PWR_CR register by using the PWR_FlashPowerDownCmd() - function, the Flash memory also enters power down mode when the device enters - Stop mode. When the Flash memory is in power down mode, an additional startup - delay is incurred when waking up from Stop mode. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the high performance mode. - * @param NewState: new state of the performance mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_HighPerformanceModeCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_PMODE_BB = (uint32_t)NewState; -} - -/** - * @brief Enables or disables the Flash Power Down in STOP mode. - * @param NewState: new state of the Flash power mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void PWR_FlashPowerDownCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_FPDS_BB = (uint32_t)NewState; -} - -/** - * @} - */ - -/** @defgroup PWR_Group6 Low Power modes configuration functions - * @brief Low Power modes configuration functions - * -@verbatim - =============================================================================== - Low Power modes configuration functions - =============================================================================== - - The devices feature 3 low-power modes: - - Sleep mode: Cortex-M4 core stopped, peripherals kept running. - - Stop mode: all clocks are stopped, regulator running, regulator in low power mode - - Standby mode: 1.2V domain powered off. - - Sleep mode - =========== - - Entry: - - The Sleep mode is entered by using the __WFI() or __WFE() functions. - - Exit: - - Any peripheral interrupt acknowledged by the nested vectored interrupt - controller (NVIC) can wake up the device from Sleep mode. - - Stop mode - ========== - In Stop mode, all clocks in the 1.2V domain are stopped, the PLL, the HSI, - and the HSE RC oscillators are disabled. Internal SRAM and register contents - are preserved. - The voltage regulator can be configured either in normal or low-power mode. - To minimize the consumption In Stop mode, FLASH can be powered off before - entering the Stop mode. It can be switched on again by software after exiting - the Stop mode using the PWR_FlashPowerDownCmd() function. - - - Entry: - - The Stop mode is entered using the PWR_EnterSTOPMode(PWR_Regulator_LowPower,) - function with regulator in LowPower or with Regulator ON. - - Exit: - - Any EXTI Line (Internal or External) configured in Interrupt/Event mode. - - Standby mode - ============ - The Standby mode allows to achieve the lowest power consumption. It is based - on the Cortex-M4 deepsleep mode, with the voltage regulator disabled. - The 1.2V domain is consequently powered off. The PLL, the HSI oscillator and - the HSE oscillator are also switched off. SRAM and register contents are lost - except for the RTC registers, RTC backup registers, backup SRAM and Standby - circuitry. - - The voltage regulator is OFF. - - - Entry: - - The Standby mode is entered using the PWR_EnterSTANDBYMode() function. - - Exit: - - WKUP pin rising edge, RTC alarm (Alarm A and Alarm B), RTC wakeup, - tamper event, time-stamp event, external reset in NRST pin, IWDG reset. - - Auto-wakeup (AWU) from low-power mode - ===================================== - The MCU can be woken up from low-power mode by an RTC Alarm event, an RTC - Wakeup event, a tamper event, a time-stamp event, or a comparator event, - without depending on an external interrupt (Auto-wakeup mode). - - - RTC auto-wakeup (AWU) from the Stop mode - ---------------------------------------- - - - To wake up from the Stop mode with an RTC alarm event, it is necessary to: - - Configure the EXTI Line 17 to be sensitive to rising edges (Interrupt - or Event modes) using the EXTI_Init() function. - - Enable the RTC Alarm Interrupt using the RTC_ITConfig() function - - Configure the RTC to generate the RTC alarm using the RTC_SetAlarm() - and RTC_AlarmCmd() functions. - - To wake up from the Stop mode with an RTC Tamper or time stamp event, it - is necessary to: - - Configure the EXTI Line 21 to be sensitive to rising edges (Interrupt - or Event modes) using the EXTI_Init() function. - - Enable the RTC Tamper or time stamp Interrupt using the RTC_ITConfig() - function - - Configure the RTC to detect the tamper or time stamp event using the - RTC_TimeStampConfig(), RTC_TamperTriggerConfig() and RTC_TamperCmd() - functions. - - To wake up from the Stop mode with an RTC WakeUp event, it is necessary to: - - Configure the EXTI Line 22 to be sensitive to rising edges (Interrupt - or Event modes) using the EXTI_Init() function. - - Enable the RTC WakeUp Interrupt using the RTC_ITConfig() function - - Configure the RTC to generate the RTC WakeUp event using the RTC_WakeUpClockConfig(), - RTC_SetWakeUpCounter() and RTC_WakeUpCmd() functions. - - - RTC auto-wakeup (AWU) from the Standby mode - ------------------------------------------- - - To wake up from the Standby mode with an RTC alarm event, it is necessary to: - - Enable the RTC Alarm Interrupt using the RTC_ITConfig() function - - Configure the RTC to generate the RTC alarm using the RTC_SetAlarm() - and RTC_AlarmCmd() functions. - - To wake up from the Standby mode with an RTC Tamper or time stamp event, it - is necessary to: - - Enable the RTC Tamper or time stamp Interrupt using the RTC_ITConfig() - function - - Configure the RTC to detect the tamper or time stamp event using the - RTC_TimeStampConfig(), RTC_TamperTriggerConfig() and RTC_TamperCmd() - functions. - - To wake up from the Standby mode with an RTC WakeUp event, it is necessary to: - - Enable the RTC WakeUp Interrupt using the RTC_ITConfig() function - - Configure the RTC to generate the RTC WakeUp event using the RTC_WakeUpClockConfig(), - RTC_SetWakeUpCounter() and RTC_WakeUpCmd() functions. - -@endverbatim - * @{ - */ - -/** - * @brief Enters STOP mode. - * - * @note In Stop mode, all I/O pins keep the same state as in Run mode. - * @note When exiting Stop mode by issuing an interrupt or a wakeup event, - * the HSI RC oscillator is selected as system clock. - * @note When the voltage regulator operates in low power mode, an additional - * startup delay is incurred when waking up from Stop mode. - * By keeping the internal regulator ON during Stop mode, the consumption - * is higher although the startup time is reduced. - * - * @param PWR_Regulator: specifies the regulator state in STOP mode. - * This parameter can be one of the following values: - * @arg PWR_Regulator_ON: STOP mode with regulator ON - * @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode - * @param PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction. - * This parameter can be one of the following values: - * @arg PWR_STOPEntry_WFI: enter STOP mode with WFI instruction - * @arg PWR_STOPEntry_WFE: enter STOP mode with WFE instruction - * @retval None - */ -void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_PWR_REGULATOR(PWR_Regulator)); - assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry)); - - /* Select the regulator state in STOP mode ---------------------------------*/ - tmpreg = PWR->CR; - /* Clear PDDS and LPDSR bits */ - tmpreg &= CR_DS_MASK; - - /* Set LPDSR bit according to PWR_Regulator value */ - tmpreg |= PWR_Regulator; - - /* Store the new value */ - PWR->CR = tmpreg; - - /* Set SLEEPDEEP bit of Cortex System Control Register */ - SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - - /* Select STOP mode entry --------------------------------------------------*/ - if(PWR_STOPEntry == PWR_STOPEntry_WFI) - { - /* Request Wait For Interrupt */ - __WFI(); - } - else - { - /* Request Wait For Event */ - __WFE(); - } - /* Reset SLEEPDEEP bit of Cortex System Control Register */ - SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); -} - -/** - * @brief Enters STANDBY mode. - * @note In Standby mode, all I/O pins are high impedance except for: - * - Reset pad (still available) - * - RTC_AF1 pin (PC13) if configured for tamper, time-stamp, RTC - * Alarm out, or RTC clock calibration out. - * - RTC_AF2 pin (PI8) if configured for tamper or time-stamp. - * - WKUP pin 1 (PA0) if enabled. - * @param None - * @retval None - */ -void PWR_EnterSTANDBYMode(void) -{ - /* Clear Wakeup flag */ - PWR->CR |= PWR_CR_CWUF; - - /* Select STANDBY mode */ - PWR->CR |= PWR_CR_PDDS; - - /* Set SLEEPDEEP bit of Cortex System Control Register */ - SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - -/* This option is used to ensure that store operations are completed */ -#if defined ( __CC_ARM ) - __force_stores(); -#endif - /* Request Wait For Interrupt */ - __WFI(); -} - -/** - * @} - */ - -/** @defgroup PWR_Group7 Flags management functions - * @brief Flags management functions - * -@verbatim - =============================================================================== - Flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Checks whether the specified PWR flag is set or not. - * @param PWR_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg PWR_FLAG_WU: Wake Up flag. This flag indicates that a wakeup event - * was received from the WKUP pin or from the RTC alarm (Alarm A - * or Alarm B), RTC Tamper event, RTC TimeStamp event or RTC Wakeup. - * An additional wakeup event is detected if the WKUP pin is enabled - * (by setting the EWUP bit) when the WKUP pin level is already high. - * @arg PWR_FLAG_SB: StandBy flag. This flag indicates that the system was - * resumed from StandBy mode. - * @arg PWR_FLAG_PVDO: PVD Output. This flag is valid only if PVD is enabled - * by the PWR_PVDCmd() function. The PVD is stopped by Standby mode - * For this reason, this bit is equal to 0 after Standby or reset - * until the PVDE bit is set. - * @arg PWR_FLAG_BRR: Backup regulator ready flag. This bit is not reset - * when the device wakes up from Standby mode or by a system reset - * or power reset. - * @arg PWR_FLAG_REGRDY: Main regulator ready flag. - * @retval The new state of PWR_FLAG (SET or RESET). - */ -FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG) -{ - FlagStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_PWR_GET_FLAG(PWR_FLAG)); - - if ((PWR->CSR & PWR_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the flag status */ - return bitstatus; -} - -/** - * @brief Clears the PWR's pending flags. - * @param PWR_FLAG: specifies the flag to clear. - * This parameter can be one of the following values: - * @arg PWR_FLAG_WU: Wake Up flag - * @arg PWR_FLAG_SB: StandBy flag - * @retval None - */ -void PWR_ClearFlag(uint32_t PWR_FLAG) -{ - /* Check the parameters */ - assert_param(IS_PWR_CLEAR_FLAG(PWR_FLAG)); - - PWR->CR |= PWR_FLAG << 2; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c deleted file mode 100644 index 7bd4a983a..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c +++ /dev/null @@ -1,1811 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_rcc.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the Reset and clock control (RCC) peripheral: - * - Internal/external clocks, PLL, CSS and MCO configuration - * - System, AHB and APB busses clocks configuration - * - Peripheral clocks configuration - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * RCC specific features - * =================================================================== - * - * After reset the device is running from Internal High Speed oscillator - * (HSI 16MHz) with Flash 0 wait state, Flash prefetch buffer, D-Cache - * and I-Cache are disabled, and all peripherals are off except internal - * SRAM, Flash and JTAG. - * - There is no prescaler on High speed (AHB) and Low speed (APB) busses; - * all peripherals mapped on these busses are running at HSI speed. - * - The clock for all peripherals is switched off, except the SRAM and FLASH. - * - All GPIOs are in input floating state, except the JTAG pins which - * are assigned to be used for debug purpose. - * - * Once the device started from reset, the user application has to: - * - Configure the clock source to be used to drive the System clock - * (if the application needs higher frequency/performance) - * - Configure the System clock frequency and Flash settings - * - Configure the AHB and APB busses prescalers - * - Enable the clock for the peripheral(s) to be used - * - Configure the clock source(s) for peripherals which clocks are not - * derived from the System clock (I2S, RTC, ADC, USB OTG FS/SDIO/RNG) - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup RCC - * @brief RCC driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* ------------ RCC registers bit address in the alias region ----------- */ -#define RCC_OFFSET (RCC_BASE - PERIPH_BASE) -/* --- CR Register ---*/ -/* Alias word address of HSION bit */ -#define CR_OFFSET (RCC_OFFSET + 0x00) -#define HSION_BitNumber 0x00 -#define CR_HSION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (HSION_BitNumber * 4)) -/* Alias word address of CSSON bit */ -#define CSSON_BitNumber 0x13 -#define CR_CSSON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (CSSON_BitNumber * 4)) -/* Alias word address of PLLON bit */ -#define PLLON_BitNumber 0x18 -#define CR_PLLON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLON_BitNumber * 4)) -/* Alias word address of PLLI2SON bit */ -#define PLLI2SON_BitNumber 0x1A -#define CR_PLLI2SON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLI2SON_BitNumber * 4)) - -/* --- CFGR Register ---*/ -/* Alias word address of I2SSRC bit */ -#define CFGR_OFFSET (RCC_OFFSET + 0x08) -#define I2SSRC_BitNumber 0x17 -#define CFGR_I2SSRC_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (I2SSRC_BitNumber * 4)) - -/* --- BDCR Register ---*/ -/* Alias word address of RTCEN bit */ -#define BDCR_OFFSET (RCC_OFFSET + 0x70) -#define RTCEN_BitNumber 0x0F -#define BDCR_RTCEN_BB (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (RTCEN_BitNumber * 4)) -/* Alias word address of BDRST bit */ -#define BDRST_BitNumber 0x10 -#define BDCR_BDRST_BB (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (BDRST_BitNumber * 4)) -/* --- CSR Register ---*/ -/* Alias word address of LSION bit */ -#define CSR_OFFSET (RCC_OFFSET + 0x74) -#define LSION_BitNumber 0x00 -#define CSR_LSION_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (LSION_BitNumber * 4)) -/* ---------------------- RCC registers bit mask ------------------------ */ -/* CFGR register bit mask */ -#define CFGR_MCO2_RESET_MASK ((uint32_t)0x07FFFFFF) -#define CFGR_MCO1_RESET_MASK ((uint32_t)0xF89FFFFF) - -/* RCC Flag Mask */ -#define FLAG_MASK ((uint8_t)0x1F) - -/* CR register byte 3 (Bits[23:16]) base address */ -#define CR_BYTE3_ADDRESS ((uint32_t)0x40023802) - -/* CIR register byte 2 (Bits[15:8]) base address */ -#define CIR_BYTE2_ADDRESS ((uint32_t)(RCC_BASE + 0x0C + 0x01)) - -/* CIR register byte 3 (Bits[23:16]) base address */ -#define CIR_BYTE3_ADDRESS ((uint32_t)(RCC_BASE + 0x0C + 0x02)) - -/* BDCR register base address */ -#define BDCR_ADDRESS (PERIPH_BASE + BDCR_OFFSET) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; - -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup RCC_Private_Functions - * @{ - */ - -/** @defgroup RCC_Group1 Internal and external clocks, PLL, CSS and MCO configuration functions - * @brief Internal and external clocks, PLL, CSS and MCO configuration functions - * -@verbatim - =============================================================================== - Internal/external clocks, PLL, CSS and MCO configuration functions - =============================================================================== - - This section provide functions allowing to configure the internal/external clocks, - PLLs, CSS and MCO pins. - - 1. HSI (high-speed internal), 16 MHz factory-trimmed RC used directly or through - the PLL as System clock source. - - 2. LSI (low-speed internal), 32 KHz low consumption RC used as IWDG and/or RTC - clock source. - - 3. HSE (high-speed external), 4 to 26 MHz crystal oscillator used directly or - through the PLL as System clock source. Can be used also as RTC clock source. - - 4. LSE (low-speed external), 32 KHz oscillator used as RTC clock source. - - 5. PLL (clocked by HSI or HSE), featuring two different output clocks: - - The first output is used to generate the high speed system clock (up to 120 MHz) - - The second output is used to generate the clock for the USB OTG FS (48 MHz), - the random analog generator (<=48 MHz) and the SDIO (<= 48 MHz). - - 6. PLLI2S (clocked by HSI or HSE), used to generate an accurate clock to achieve - high-quality audio performance on the I2S interface. - - 7. CSS (Clock security system), once enable and if a HSE clock failure occurs - (HSE used directly or through PLL as System clock source), the System clock - is automatically switched to HSI and an interrupt is generated if enabled. - The interrupt is linked to the Cortex-M4 NMI (Non-Maskable Interrupt) - exception vector. - - 8. MCO1 (microcontroller clock output), used to output HSI, LSE, HSE or PLL - clock (through a configurable prescaler) on PA8 pin. - - 9. MCO2 (microcontroller clock output), used to output HSE, PLL, SYSCLK or PLLI2S - clock (through a configurable prescaler) on PC9 pin. - -@endverbatim - * @{ - */ - -/** - * @brief Resets the RCC clock configuration to the default reset state. - * @note The default reset state of the clock configuration is given below: - * - HSI ON and used as system clock source - * - HSE, PLL and PLLI2S OFF - * - AHB, APB1 and APB2 prescaler set to 1. - * - CSS, MCO1 and MCO2 OFF - * - All interrupts disabled - * @note This function doesn't modify the configuration of the - * - Peripheral clocks - * - LSI, LSE and RTC clocks - * @param None - * @retval None - */ -void RCC_DeInit(void) -{ - /* Set HSION bit */ - RCC->CR |= (uint32_t)0x00000001; - - /* Reset CFGR register */ - RCC->CFGR = 0x00000000; - - /* Reset HSEON, CSSON and PLLON bits */ - RCC->CR &= (uint32_t)0xFEF6FFFF; - - /* Reset PLLCFGR register */ - RCC->PLLCFGR = 0x24003010; - - /* Reset HSEBYP bit */ - RCC->CR &= (uint32_t)0xFFFBFFFF; - - /* Disable all interrupts */ - RCC->CIR = 0x00000000; -} - -/** - * @brief Configures the External High Speed oscillator (HSE). - * @note After enabling the HSE (RCC_HSE_ON or RCC_HSE_Bypass), the application - * software should wait on HSERDY flag to be set indicating that HSE clock - * is stable and can be used to clock the PLL and/or system clock. - * @note HSE state can not be changed if it is used directly or through the - * PLL as system clock. In this case, you have to select another source - * of the system clock then change the HSE state (ex. disable it). - * @note The HSE is stopped by hardware when entering STOP and STANDBY modes. - * @note This function reset the CSSON bit, so if the Clock security system(CSS) - * was previously enabled you have to enable it again after calling this - * function. - * @param RCC_HSE: specifies the new state of the HSE. - * This parameter can be one of the following values: - * @arg RCC_HSE_OFF: turn OFF the HSE oscillator, HSERDY flag goes low after - * 6 HSE oscillator clock cycles. - * @arg RCC_HSE_ON: turn ON the HSE oscillator - * @arg RCC_HSE_Bypass: HSE oscillator bypassed with external clock - * @retval None - */ -void RCC_HSEConfig(uint8_t RCC_HSE) -{ - /* Check the parameters */ - assert_param(IS_RCC_HSE(RCC_HSE)); - - /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/ - *(__IO uint8_t *) CR_BYTE3_ADDRESS = RCC_HSE_OFF; - - /* Set the new HSE configuration -------------------------------------------*/ - *(__IO uint8_t *) CR_BYTE3_ADDRESS = RCC_HSE; -} - -/** - * @brief Waits for HSE start-up. - * @note This functions waits on HSERDY flag to be set and return SUCCESS if - * this flag is set, otherwise returns ERROR if the timeout is reached - * and this flag is not set. The timeout value is defined by the constant - * HSE_STARTUP_TIMEOUT in stm32f4xx.h file. You can tailor it depending - * on the HSE crystal used in your application. - * @param None - * @retval An ErrorStatus enumeration value: - * - SUCCESS: HSE oscillator is stable and ready to use - * - ERROR: HSE oscillator not yet ready - */ -ErrorStatus RCC_WaitForHSEStartUp(void) -{ - __IO uint32_t startupcounter = 0; - ErrorStatus status = ERROR; - FlagStatus hsestatus = RESET; - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - hsestatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY); - startupcounter++; - } while((startupcounter != HSE_STARTUP_TIMEOUT) && (hsestatus == RESET)); - - if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET) - { - status = SUCCESS; - } - else - { - status = ERROR; - } - return (status); -} - -/** - * @brief Adjusts the Internal High Speed oscillator (HSI) calibration value. - * @note The calibration is used to compensate for the variations in voltage - * and temperature that influence the frequency of the internal HSI RC. - * @param HSICalibrationValue: specifies the calibration trimming value. - * This parameter must be a number between 0 and 0x1F. - * @retval None - */ -void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_RCC_CALIBRATION_VALUE(HSICalibrationValue)); - - tmpreg = RCC->CR; - - /* Clear HSITRIM[4:0] bits */ - tmpreg &= ~RCC_CR_HSITRIM; - - /* Set the HSITRIM[4:0] bits according to HSICalibrationValue value */ - tmpreg |= (uint32_t)HSICalibrationValue << 3; - - /* Store the new value */ - RCC->CR = tmpreg; -} - -/** - * @brief Enables or disables the Internal High Speed oscillator (HSI). - * @note The HSI is stopped by hardware when entering STOP and STANDBY modes. - * It is used (enabled by hardware) as system clock source after startup - * from Reset, wakeup from STOP and STANDBY mode, or in case of failure - * of the HSE used directly or indirectly as system clock (if the Clock - * Security System CSS is enabled). - * @note HSI can not be stopped if it is used as system clock source. In this case, - * you have to select another source of the system clock then stop the HSI. - * @note After enabling the HSI, the application software should wait on HSIRDY - * flag to be set indicating that HSI clock is stable and can be used as - * system clock source. - * @param NewState: new state of the HSI. - * This parameter can be: ENABLE or DISABLE. - * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator - * clock cycles. - * @retval None - */ -void RCC_HSICmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CR_HSION_BB = (uint32_t)NewState; -} - -/** - * @brief Configures the External Low Speed oscillator (LSE). - * @note As the LSE is in the Backup domain and write access is denied to - * this domain after reset, you have to enable write access using - * PWR_BackupAccessCmd(ENABLE) function before to configure the LSE - * (to be done once after reset). - * @note After enabling the LSE (RCC_LSE_ON or RCC_LSE_Bypass), the application - * software should wait on LSERDY flag to be set indicating that LSE clock - * is stable and can be used to clock the RTC. - * @param RCC_LSE: specifies the new state of the LSE. - * This parameter can be one of the following values: - * @arg RCC_LSE_OFF: turn OFF the LSE oscillator, LSERDY flag goes low after - * 6 LSE oscillator clock cycles. - * @arg RCC_LSE_ON: turn ON the LSE oscillator - * @arg RCC_LSE_Bypass: LSE oscillator bypassed with external clock - * @retval None - */ -void RCC_LSEConfig(uint8_t RCC_LSE) -{ - /* Check the parameters */ - assert_param(IS_RCC_LSE(RCC_LSE)); - - /* Reset LSEON and LSEBYP bits before configuring the LSE ------------------*/ - /* Reset LSEON bit */ - *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF; - - /* Reset LSEBYP bit */ - *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF; - - /* Configure LSE (RCC_LSE_OFF is already covered by the code section above) */ - switch (RCC_LSE) - { - case RCC_LSE_ON: - /* Set LSEON bit */ - *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_ON; - break; - case RCC_LSE_Bypass: - /* Set LSEBYP and LSEON bits */ - *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_Bypass | RCC_LSE_ON; - break; - default: - break; - } -} - -/** - * @brief Enables or disables the Internal Low Speed oscillator (LSI). - * @note After enabling the LSI, the application software should wait on - * LSIRDY flag to be set indicating that LSI clock is stable and can - * be used to clock the IWDG and/or the RTC. - * @note LSI can not be disabled if the IWDG is running. - * @param NewState: new state of the LSI. - * This parameter can be: ENABLE or DISABLE. - * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator - * clock cycles. - * @retval None - */ -void RCC_LSICmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CSR_LSION_BB = (uint32_t)NewState; -} - -/** - * @brief Configures the main PLL clock source, multiplication and division factors. - * @note This function must be used only when the main PLL is disabled. - * - * @param RCC_PLLSource: specifies the PLL entry clock source. - * This parameter can be one of the following values: - * @arg RCC_PLLSource_HSI: HSI oscillator clock selected as PLL clock entry - * @arg RCC_PLLSource_HSE: HSE oscillator clock selected as PLL clock entry - * @note This clock source (RCC_PLLSource) is common for the main PLL and PLLI2S. - * - * @param PLLM: specifies the division factor for PLL VCO input clock - * This parameter must be a number between 0 and 63. - * @note You have to set the PLLM parameter correctly to ensure that the VCO input - * frequency ranges from 1 to 2 MHz. It is recommended to select a frequency - * of 2 MHz to limit PLL jitter. - * - * @param PLLN: specifies the multiplication factor for PLL VCO output clock - * This parameter must be a number between 192 and 432. - * @note You have to set the PLLN parameter correctly to ensure that the VCO - * output frequency is between 192 and 432 MHz. - * - * @param PLLP: specifies the division factor for main system clock (SYSCLK) - * This parameter must be a number in the range {2, 4, 6, or 8}. - * @note You have to set the PLLP parameter correctly to not exceed 120 MHz on - * the System clock frequency. - * - * @param PLLQ: specifies the division factor for OTG FS, SDIO and RNG clocks - * This parameter must be a number between 4 and 15. - * @note If the USB OTG FS is used in your application, you have to set the - * PLLQ parameter correctly to have 48 MHz clock for the USB. However, - * the SDIO and RNG need a frequency lower than or equal to 48 MHz to work - * correctly. - * - * @retval None - */ -void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ) -{ - /* Check the parameters */ - assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource)); - assert_param(IS_RCC_PLLM_VALUE(PLLM)); - assert_param(IS_RCC_PLLN_VALUE(PLLN)); - assert_param(IS_RCC_PLLP_VALUE(PLLP)); - assert_param(IS_RCC_PLLQ_VALUE(PLLQ)); - - RCC->PLLCFGR = PLLM | (PLLN << 6) | (((PLLP >> 1) -1) << 16) | (RCC_PLLSource) | - (PLLQ << 24); -} - -/** - * @brief Enables or disables the main PLL. - * @note After enabling the main PLL, the application software should wait on - * PLLRDY flag to be set indicating that PLL clock is stable and can - * be used as system clock source. - * @note The main PLL can not be disabled if it is used as system clock source - * @note The main PLL is disabled by hardware when entering STOP and STANDBY modes. - * @param NewState: new state of the main PLL. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_PLLCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) CR_PLLON_BB = (uint32_t)NewState; -} - -/** - * @brief Configures the PLLI2S clock multiplication and division factors. - * - * @note PLLI2S is available only in Silicon RevisionB and RevisionY. - * @note This function must be used only when the PLLI2S is disabled. - * @note PLLI2S clock source is common with the main PLL (configured in - * RCC_PLLConfig function ) - * - * @param PLLI2SN: specifies the multiplication factor for PLLI2S VCO output clock - * This parameter must be a number between 192 and 432. - * @note You have to set the PLLI2SN parameter correctly to ensure that the VCO - * output frequency is between 192 and 432 MHz. - * - * @param PLLI2SR: specifies the division factor for I2S clock - * This parameter must be a number between 2 and 7. - * @note You have to set the PLLI2SR parameter correctly to not exceed 192 MHz - * on the I2S clock frequency. - * - * @retval None - */ -void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR) -{ - /* Check the parameters */ - assert_param(IS_RCC_PLLI2SN_VALUE(PLLI2SN)); - assert_param(IS_RCC_PLLI2SR_VALUE(PLLI2SR)); - - RCC->PLLI2SCFGR = (PLLI2SN << 6) | (PLLI2SR << 28); -} - -/** - * @brief Enables or disables the PLLI2S. - * @note PLLI2S is available only in RevisionB and RevisionY - * @note The PLLI2S is disabled by hardware when entering STOP and STANDBY modes. - * @param NewState: new state of the PLLI2S. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_PLLI2SCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) CR_PLLI2SON_BB = (uint32_t)NewState; -} - -/** - * @brief Enables or disables the Clock Security System. - * @note If a failure is detected on the HSE oscillator clock, this oscillator - * is automatically disabled and an interrupt is generated to inform the - * software about the failure (Clock Security System Interrupt, CSSI), - * allowing the MCU to perform rescue operations. The CSSI is linked to - * the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector. - * @param NewState: new state of the Clock Security System. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_ClockSecuritySystemCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) CR_CSSON_BB = (uint32_t)NewState; -} - -/** - * @brief Selects the clock source to output on MCO1 pin(PA8). - * @note PA8 should be configured in alternate function mode. - * @param RCC_MCO1Source: specifies the clock source to output. - * This parameter can be one of the following values: - * @arg RCC_MCO1Source_HSI: HSI clock selected as MCO1 source - * @arg RCC_MCO1Source_LSE: LSE clock selected as MCO1 source - * @arg RCC_MCO1Source_HSE: HSE clock selected as MCO1 source - * @arg RCC_MCO1Source_PLLCLK: main PLL clock selected as MCO1 source - * @param RCC_MCO1Div: specifies the MCO1 prescaler. - * This parameter can be one of the following values: - * @arg RCC_MCO1Div_1: no division applied to MCO1 clock - * @arg RCC_MCO1Div_2: division by 2 applied to MCO1 clock - * @arg RCC_MCO1Div_3: division by 3 applied to MCO1 clock - * @arg RCC_MCO1Div_4: division by 4 applied to MCO1 clock - * @arg RCC_MCO1Div_5: division by 5 applied to MCO1 clock - * @retval None - */ -void RCC_MCO1Config(uint32_t RCC_MCO1Source, uint32_t RCC_MCO1Div) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_MCO1SOURCE(RCC_MCO1Source)); - assert_param(IS_RCC_MCO1DIV(RCC_MCO1Div)); - - tmpreg = RCC->CFGR; - - /* Clear MCO1[1:0] and MCO1PRE[2:0] bits */ - tmpreg &= CFGR_MCO1_RESET_MASK; - - /* Select MCO1 clock source and prescaler */ - tmpreg |= RCC_MCO1Source | RCC_MCO1Div; - - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -/** - * @brief Selects the clock source to output on MCO2 pin(PC9). - * @note PC9 should be configured in alternate function mode. - * @param RCC_MCO2Source: specifies the clock source to output. - * This parameter can be one of the following values: - * @arg RCC_MCO2Source_SYSCLK: System clock (SYSCLK) selected as MCO2 source - * @arg RCC_MCO2Source_PLLI2SCLK: PLLI2S clock selected as MCO2 source - * @arg RCC_MCO2Source_HSE: HSE clock selected as MCO2 source - * @arg RCC_MCO2Source_PLLCLK: main PLL clock selected as MCO2 source - * @param RCC_MCO2Div: specifies the MCO2 prescaler. - * This parameter can be one of the following values: - * @arg RCC_MCO2Div_1: no division applied to MCO2 clock - * @arg RCC_MCO2Div_2: division by 2 applied to MCO2 clock - * @arg RCC_MCO2Div_3: division by 3 applied to MCO2 clock - * @arg RCC_MCO2Div_4: division by 4 applied to MCO2 clock - * @arg RCC_MCO2Div_5: division by 5 applied to MCO2 clock - * @retval None - */ -void RCC_MCO2Config(uint32_t RCC_MCO2Source, uint32_t RCC_MCO2Div) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_MCO2SOURCE(RCC_MCO2Source)); - assert_param(IS_RCC_MCO2DIV(RCC_MCO2Div)); - - tmpreg = RCC->CFGR; - - /* Clear MCO2 and MCO2PRE[2:0] bits */ - tmpreg &= CFGR_MCO2_RESET_MASK; - - /* Select MCO2 clock source and prescaler */ - tmpreg |= RCC_MCO2Source | RCC_MCO2Div; - - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -/** - * @} - */ - -/** @defgroup RCC_Group2 System AHB and APB busses clocks configuration functions - * @brief System, AHB and APB busses clocks configuration functions - * -@verbatim - =============================================================================== - System, AHB and APB busses clocks configuration functions - =============================================================================== - - This section provide functions allowing to configure the System, AHB, APB1 and - APB2 busses clocks. - - 1. Several clock sources can be used to drive the System clock (SYSCLK): HSI, - HSE and PLL. - The AHB clock (HCLK) is derived from System clock through configurable prescaler - and used to clock the CPU, memory and peripherals mapped on AHB bus (DMA, GPIO...). - APB1 (PCLK1) and APB2 (PCLK2) clocks are derived from AHB clock through - configurable prescalers and used to clock the peripherals mapped on these busses. - You can use "RCC_GetClocksFreq()" function to retrieve the frequencies of these clocks. - -@note All the peripheral clocks are derived from the System clock (SYSCLK) except: - - I2S: the I2S clock can be derived either from a specific PLL (PLLI2S) or - from an external clock mapped on the I2S_CKIN pin. - You have to use RCC_I2SCLKConfig() function to configure this clock. - - RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock - divided by 2 to 31. You have to use RCC_RTCCLKConfig() and RCC_RTCCLKCmd() - functions to configure this clock. - - USB OTG FS, SDIO and RTC: USB OTG FS require a frequency equal to 48 MHz - to work correctly, while the SDIO require a frequency equal or lower than - to 48. This clock is derived of the main PLL through PLLQ divider. - - IWDG clock which is always the LSI clock. - - 2. The maximum frequency of the SYSCLK and HCLK is 120 MHz, PCLK2 60 MHz and PCLK1 30 MHz. - Depending on the device voltage range, the maximum frequency should be - adapted accordingly: - +-------------------------------------------------------------------------------------+ - | Latency | HCLK clock frequency (MHz) | - | |---------------------------------------------------------------------| - | | voltage range | voltage range | voltage range | voltage range | - | | 2.7 V - 3.6 V | 2.4 V - 2.7 V | 2.1 V - 2.4 V | 1.8 V - 2.1 V | - |---------------|----------------|----------------|-----------------|-----------------| - |0WS(1CPU cycle)|0 < HCLK <= 30 |0 < HCLK <= 24 |0 < HCLK <= 18 |0 < HCLK <= 16 | - |---------------|----------------|----------------|-----------------|-----------------| - |1WS(2CPU cycle)|30 < HCLK <= 60 |24 < HCLK <= 48 |18 < HCLK <= 36 |16 < HCLK <= 32 | - |---------------|----------------|----------------|-----------------|-----------------| - |2WS(3CPU cycle)|60 < HCLK <= 90 |48 < HCLK <= 72 |36 < HCLK <= 54 |32 < HCLK <= 48 | - |---------------|----------------|----------------|-----------------|-----------------| - |3WS(4CPU cycle)|90 < HCLK <= 120|72 < HCLK <= 96 |54 < HCLK <= 72 |48 < HCLK <= 64 | - |---------------|----------------|----------------|-----------------|-----------------| - |4WS(5CPU cycle)| NA |96 < HCLK <= 120|72 < HCLK <= 90 |64 < HCLK <= 80 | - |---------------|----------------|----------------|-----------------|-----------------| - |5WS(6CPU cycle)| NA | NA |90 < HCLK <= 108 |80 < HCLK <= 96 | - |---------------|----------------|----------------|-----------------|-----------------| - |6WS(7CPU cycle)| NA | NA |108 < HCLK <= 120|96 < HCLK <= 112 | - |---------------|----------------|----------------|-----------------|-----------------| - |7WS(8CPU cycle)| NA | NA | NA |112 < HCLK <= 120| - +-------------------------------------------------------------------------------------+ - - -@endverbatim - * @{ - */ - -/** - * @brief Configures the system clock (SYSCLK). - * @note The HSI is used (enabled by hardware) as system clock source after - * startup from Reset, wake-up from STOP and STANDBY mode, or in case - * of failure of the HSE used directly or indirectly as system clock - * (if the Clock Security System CSS is enabled). - * @note A switch from one clock source to another occurs only if the target - * clock source is ready (clock stable after startup delay or PLL locked). - * If a clock source which is not yet ready is selected, the switch will - * occur when the clock source will be ready. - * You can use RCC_GetSYSCLKSource() function to know which clock is - * currently used as system clock source. - * @param RCC_SYSCLKSource: specifies the clock source used as system clock. - * This parameter can be one of the following values: - * @arg RCC_SYSCLKSource_HSI: HSI selected as system clock source - * @arg RCC_SYSCLKSource_HSE: HSE selected as system clock source - * @arg RCC_SYSCLKSource_PLLCLK: PLL selected as system clock source - * @retval None - */ -void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_SYSCLK_SOURCE(RCC_SYSCLKSource)); - - tmpreg = RCC->CFGR; - - /* Clear SW[1:0] bits */ - tmpreg &= ~RCC_CFGR_SW; - - /* Set SW[1:0] bits according to RCC_SYSCLKSource value */ - tmpreg |= RCC_SYSCLKSource; - - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -/** - * @brief Returns the clock source used as system clock. - * @param None - * @retval The clock source used as system clock. The returned value can be one - * of the following: - * - 0x00: HSI used as system clock - * - 0x04: HSE used as system clock - * - 0x08: PLL used as system clock - */ -uint8_t RCC_GetSYSCLKSource(void) -{ - return ((uint8_t)(RCC->CFGR & RCC_CFGR_SWS)); -} - -/** - * @brief Configures the AHB clock (HCLK). - * @note Depending on the device voltage range, the software has to set correctly - * these bits to ensure that HCLK not exceed the maximum allowed frequency - * (for more details refer to section above - * "CPU, AHB and APB busses clocks configuration functions") - * @param RCC_SYSCLK: defines the AHB clock divider. This clock is derived from - * the system clock (SYSCLK). - * This parameter can be one of the following values: - * @arg RCC_SYSCLK_Div1: AHB clock = SYSCLK - * @arg RCC_SYSCLK_Div2: AHB clock = SYSCLK/2 - * @arg RCC_SYSCLK_Div4: AHB clock = SYSCLK/4 - * @arg RCC_SYSCLK_Div8: AHB clock = SYSCLK/8 - * @arg RCC_SYSCLK_Div16: AHB clock = SYSCLK/16 - * @arg RCC_SYSCLK_Div64: AHB clock = SYSCLK/64 - * @arg RCC_SYSCLK_Div128: AHB clock = SYSCLK/128 - * @arg RCC_SYSCLK_Div256: AHB clock = SYSCLK/256 - * @arg RCC_SYSCLK_Div512: AHB clock = SYSCLK/512 - * @retval None - */ -void RCC_HCLKConfig(uint32_t RCC_SYSCLK) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_HCLK(RCC_SYSCLK)); - - tmpreg = RCC->CFGR; - - /* Clear HPRE[3:0] bits */ - tmpreg &= ~RCC_CFGR_HPRE; - - /* Set HPRE[3:0] bits according to RCC_SYSCLK value */ - tmpreg |= RCC_SYSCLK; - - /* Store the new value */ - RCC->CFGR = tmpreg; -} - - -/** - * @brief Configures the Low Speed APB clock (PCLK1). - * @param RCC_HCLK: defines the APB1 clock divider. This clock is derived from - * the AHB clock (HCLK). - * This parameter can be one of the following values: - * @arg RCC_HCLK_Div1: APB1 clock = HCLK - * @arg RCC_HCLK_Div2: APB1 clock = HCLK/2 - * @arg RCC_HCLK_Div4: APB1 clock = HCLK/4 - * @arg RCC_HCLK_Div8: APB1 clock = HCLK/8 - * @arg RCC_HCLK_Div16: APB1 clock = HCLK/16 - * @retval None - */ -void RCC_PCLK1Config(uint32_t RCC_HCLK) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_PCLK(RCC_HCLK)); - - tmpreg = RCC->CFGR; - - /* Clear PPRE1[2:0] bits */ - tmpreg &= ~RCC_CFGR_PPRE1; - - /* Set PPRE1[2:0] bits according to RCC_HCLK value */ - tmpreg |= RCC_HCLK; - - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -/** - * @brief Configures the High Speed APB clock (PCLK2). - * @param RCC_HCLK: defines the APB2 clock divider. This clock is derived from - * the AHB clock (HCLK). - * This parameter can be one of the following values: - * @arg RCC_HCLK_Div1: APB2 clock = HCLK - * @arg RCC_HCLK_Div2: APB2 clock = HCLK/2 - * @arg RCC_HCLK_Div4: APB2 clock = HCLK/4 - * @arg RCC_HCLK_Div8: APB2 clock = HCLK/8 - * @arg RCC_HCLK_Div16: APB2 clock = HCLK/16 - * @retval None - */ -void RCC_PCLK2Config(uint32_t RCC_HCLK) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_PCLK(RCC_HCLK)); - - tmpreg = RCC->CFGR; - - /* Clear PPRE2[2:0] bits */ - tmpreg &= ~RCC_CFGR_PPRE2; - - /* Set PPRE2[2:0] bits according to RCC_HCLK value */ - tmpreg |= RCC_HCLK << 3; - - /* Store the new value */ - RCC->CFGR = tmpreg; -} - -/** - * @brief Returns the frequencies of different on chip clocks; SYSCLK, HCLK, - * PCLK1 and PCLK2. - * - * @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: - * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) - * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**) - * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**) - * or HSI_VALUE(*) multiplied/divided by the PLL factors. - * @note (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value - * 16 MHz) but the real value may vary depending on the variations - * in voltage and temperature. - * @note (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value - * 25 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. - * - * @note The result of this function could be not correct when using fractional - * value for HSE crystal. - * - * @param RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold - * the clocks frequencies. - * - * @note This function can be used by the user application to compute the - * baudrate for the communication peripherals or configure other parameters. - * @note Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function - * must be called to update the structure's field. Otherwise, any - * configuration based on this function will be incorrect. - * - * @retval None - */ -void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks) -{ - uint32_t tmp = 0, presc = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; - - /* Get SYSCLK source -------------------------------------------------------*/ - tmp = RCC->CFGR & RCC_CFGR_SWS; - - switch (tmp) - { - case 0x00: /* HSI used as system clock source */ - RCC_Clocks->SYSCLK_Frequency = HSI_VALUE; - break; - case 0x04: /* HSE used as system clock source */ - RCC_Clocks->SYSCLK_Frequency = HSE_VALUE; - break; - case 0x08: /* PLL used as system clock source */ - - /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN - SYSCLK = PLL_VCO / PLLP - */ - pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; - pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; - - if (pllsource != 0) - { - /* HSE used as PLL clock source */ - pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); - } - else - { - /* HSI used as PLL clock source */ - pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); - } - - pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; - RCC_Clocks->SYSCLK_Frequency = pllvco/pllp; - break; - default: - RCC_Clocks->SYSCLK_Frequency = HSI_VALUE; - break; - } - /* Compute HCLK, PCLK1 and PCLK2 clocks frequencies ------------------------*/ - - /* Get HCLK prescaler */ - tmp = RCC->CFGR & RCC_CFGR_HPRE; - tmp = tmp >> 4; - presc = APBAHBPrescTable[tmp]; - /* HCLK clock frequency */ - RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc; - - /* Get PCLK1 prescaler */ - tmp = RCC->CFGR & RCC_CFGR_PPRE1; - tmp = tmp >> 10; - presc = APBAHBPrescTable[tmp]; - /* PCLK1 clock frequency */ - RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc; - - /* Get PCLK2 prescaler */ - tmp = RCC->CFGR & RCC_CFGR_PPRE2; - tmp = tmp >> 13; - presc = APBAHBPrescTable[tmp]; - /* PCLK2 clock frequency */ - RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc; -} - -/** - * @} - */ - -/** @defgroup RCC_Group3 Peripheral clocks configuration functions - * @brief Peripheral clocks configuration functions - * -@verbatim - =============================================================================== - Peripheral clocks configuration functions - =============================================================================== - - This section provide functions allowing to configure the Peripheral clocks. - - 1. The RTC clock which is derived from the LSI, LSE or HSE clock divided by 2 to 31. - - 2. After restart from Reset or wakeup from STANDBY, all peripherals are off - except internal SRAM, Flash and JTAG. Before to start using a peripheral you - have to enable its interface clock. You can do this using RCC_AHBPeriphClockCmd() - , RCC_APB2PeriphClockCmd() and RCC_APB1PeriphClockCmd() functions. - - 3. To reset the peripherals configuration (to the default state after device reset) - you can use RCC_AHBPeriphResetCmd(), RCC_APB2PeriphResetCmd() and - RCC_APB1PeriphResetCmd() functions. - - 4. To further reduce power consumption in SLEEP mode the peripheral clocks can - be disabled prior to executing the WFI or WFE instructions. You can do this - using RCC_AHBPeriphClockLPModeCmd(), RCC_APB2PeriphClockLPModeCmd() and - RCC_APB1PeriphClockLPModeCmd() functions. - -@endverbatim - * @{ - */ - -/** - * @brief Configures the RTC clock (RTCCLK). - * @note As the RTC clock configuration bits are in the Backup domain and write - * access is denied to this domain after reset, you have to enable write - * access using PWR_BackupAccessCmd(ENABLE) function before to configure - * the RTC clock source (to be done once after reset). - * @note Once the RTC clock is configured it can't be changed unless the - * Backup domain is reset using RCC_BackupResetCmd() function, or by - * a Power On Reset (POR). - * - * @param RCC_RTCCLKSource: specifies the RTC clock source. - * This parameter can be one of the following values: - * @arg RCC_RTCCLKSource_LSE: LSE selected as RTC clock - * @arg RCC_RTCCLKSource_LSI: LSI selected as RTC clock - * @arg RCC_RTCCLKSource_HSE_Divx: HSE clock divided by x selected - * as RTC clock, where x:[2,31] - * - * @note If the LSE or LSI is used as RTC clock source, the RTC continues to - * work in STOP and STANDBY modes, and can be used as wakeup source. - * However, when the HSE clock is used as RTC clock source, the RTC - * cannot be used in STOP and STANDBY modes. - * @note The maximum input clock frequency for RTC is 1MHz (when using HSE as - * RTC clock source). - * - * @retval None - */ -void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RCC_RTCCLK_SOURCE(RCC_RTCCLKSource)); - - if ((RCC_RTCCLKSource & 0x00000300) == 0x00000300) - { /* If HSE is selected as RTC clock source, configure HSE division factor for RTC clock */ - tmpreg = RCC->CFGR; - - /* Clear RTCPRE[4:0] bits */ - tmpreg &= ~RCC_CFGR_RTCPRE; - - /* Configure HSE division factor for RTC clock */ - tmpreg |= (RCC_RTCCLKSource & 0xFFFFCFF); - - /* Store the new value */ - RCC->CFGR = tmpreg; - } - - /* Select the RTC clock source */ - RCC->BDCR |= (RCC_RTCCLKSource & 0x00000FFF); -} - -/** - * @brief Enables or disables the RTC clock. - * @note This function must be used only after the RTC clock source was selected - * using the RCC_RTCCLKConfig function. - * @param NewState: new state of the RTC clock. This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_RTCCLKCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) BDCR_RTCEN_BB = (uint32_t)NewState; -} - -/** - * @brief Forces or releases the Backup domain reset. - * @note This function resets the RTC peripheral (including the backup registers) - * and the RTC clock source selection in RCC_CSR register. - * @note The BKPSRAM is not affected by this reset. - * @param NewState: new state of the Backup domain reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_BackupResetCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - *(__IO uint32_t *) BDCR_BDRST_BB = (uint32_t)NewState; -} - -/** - * @brief Configures the I2S clock source (I2SCLK). - * - * @note This function must be called before enabling the I2S APB clock. - * @note This function applies only to Silicon RevisionB and RevisionY. - * - * @param RCC_I2SCLKSource: specifies the I2S clock source. - * This parameter can be one of the following values: - * @arg RCC_I2S2CLKSource_PLLI2S: PLLI2S clock used as I2S clock source - * @arg RCC_I2S2CLKSource_Ext: External clock mapped on the I2S_CKIN pin - * used as I2S clock source - * @retval None - */ -void RCC_I2SCLKConfig(uint32_t RCC_I2SCLKSource) -{ - /* Check the parameters */ - assert_param(IS_RCC_I2SCLK_SOURCE(RCC_I2SCLKSource)); - - *(__IO uint32_t *) CFGR_I2SSRC_BB = RCC_I2SCLKSource; -} - -/** - * @brief Enables or disables the AHB1 peripheral clock. - * @note After reset, the peripheral clock (used for registers read/write access) - * is disabled and the application software has to enable this clock before - * using it. - * @param RCC_AHBPeriph: specifies the AHB1 peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_AHB1Periph_GPIOA: GPIOA clock - * @arg RCC_AHB1Periph_GPIOB: GPIOB clock - * @arg RCC_AHB1Periph_GPIOC: GPIOC clock - * @arg RCC_AHB1Periph_GPIOD: GPIOD clock - * @arg RCC_AHB1Periph_GPIOE: GPIOE clock - * @arg RCC_AHB1Periph_GPIOF: GPIOF clock - * @arg RCC_AHB1Periph_GPIOG: GPIOG clock - * @arg RCC_AHB1Periph_GPIOG: GPIOG clock - * @arg RCC_AHB1Periph_GPIOI: GPIOI clock - * @arg RCC_AHB1Periph_CRC: CRC clock - * @arg RCC_AHB1Periph_BKPSRAM: BKPSRAM interface clock - * @arg RCC_AHB1Periph_DMA1: DMA1 clock - * @arg RCC_AHB1Periph_DMA2: DMA2 clock - * @arg RCC_AHB1Periph_ETH_MAC: Ethernet MAC clock - * @arg RCC_AHB1Periph_ETH_MAC_Tx: Ethernet Transmission clock - * @arg RCC_AHB1Periph_ETH_MAC_Rx: Ethernet Reception clock - * @arg RCC_AHB1Periph_ETH_MAC_PTP: Ethernet PTP clock - * @arg RCC_AHB1Periph_OTG_HS: USB OTG HS clock - * @arg RCC_AHB1Periph_OTG_HS_ULPI: USB OTG HS ULPI clock - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_AHB1_CLOCK_PERIPH(RCC_AHB1Periph)); - - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - RCC->AHB1ENR |= RCC_AHB1Periph; - } - else - { - RCC->AHB1ENR &= ~RCC_AHB1Periph; - } -} - -/** - * @brief Enables or disables the AHB2 peripheral clock. - * @note After reset, the peripheral clock (used for registers read/write access) - * is disabled and the application software has to enable this clock before - * using it. - * @param RCC_AHBPeriph: specifies the AHB2 peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_AHB2Periph_DCMI: DCMI clock - * @arg RCC_AHB2Periph_CRYP: CRYP clock - * @arg RCC_AHB2Periph_HASH: HASH clock - * @arg RCC_AHB2Periph_RNG: RNG clock - * @arg RCC_AHB2Periph_OTG_FS: USB OTG FS clock - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_AHB2_PERIPH(RCC_AHB2Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->AHB2ENR |= RCC_AHB2Periph; - } - else - { - RCC->AHB2ENR &= ~RCC_AHB2Periph; - } -} - -/** - * @brief Enables or disables the AHB3 peripheral clock. - * @note After reset, the peripheral clock (used for registers read/write access) - * is disabled and the application software has to enable this clock before - * using it. - * @param RCC_AHBPeriph: specifies the AHB3 peripheral to gates its clock. - * This parameter must be: RCC_AHB3Periph_FSMC - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_AHB3_PERIPH(RCC_AHB3Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->AHB3ENR |= RCC_AHB3Periph; - } - else - { - RCC->AHB3ENR &= ~RCC_AHB3Periph; - } -} - -/** - * @brief Enables or disables the Low Speed APB (APB1) peripheral clock. - * @note After reset, the peripheral clock (used for registers read/write access) - * is disabled and the application software has to enable this clock before - * using it. - * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_APB1Periph_TIM2: TIM2 clock - * @arg RCC_APB1Periph_TIM3: TIM3 clock - * @arg RCC_APB1Periph_TIM4: TIM4 clock - * @arg RCC_APB1Periph_TIM5: TIM5 clock - * @arg RCC_APB1Periph_TIM6: TIM6 clock - * @arg RCC_APB1Periph_TIM7: TIM7 clock - * @arg RCC_APB1Periph_TIM12: TIM12 clock - * @arg RCC_APB1Periph_TIM13: TIM13 clock - * @arg RCC_APB1Periph_TIM14: TIM14 clock - * @arg RCC_APB1Periph_WWDG: WWDG clock - * @arg RCC_APB1Periph_SPI2: SPI2 clock - * @arg RCC_APB1Periph_SPI3: SPI3 clock - * @arg RCC_APB1Periph_USART2: USART2 clock - * @arg RCC_APB1Periph_USART3: USART3 clock - * @arg RCC_APB1Periph_UART4: UART4 clock - * @arg RCC_APB1Periph_UART5: UART5 clock - * @arg RCC_APB1Periph_I2C1: I2C1 clock - * @arg RCC_APB1Periph_I2C2: I2C2 clock - * @arg RCC_APB1Periph_I2C3: I2C3 clock - * @arg RCC_APB1Periph_CAN1: CAN1 clock - * @arg RCC_APB1Periph_CAN2: CAN2 clock - * @arg RCC_APB1Periph_PWR: PWR clock - * @arg RCC_APB1Periph_DAC: DAC clock - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->APB1ENR |= RCC_APB1Periph; - } - else - { - RCC->APB1ENR &= ~RCC_APB1Periph; - } -} - -/** - * @brief Enables or disables the High Speed APB (APB2) peripheral clock. - * @note After reset, the peripheral clock (used for registers read/write access) - * is disabled and the application software has to enable this clock before - * using it. - * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_APB2Periph_TIM1: TIM1 clock - * @arg RCC_APB2Periph_TIM8: TIM8 clock - * @arg RCC_APB2Periph_USART1: USART1 clock - * @arg RCC_APB2Periph_USART6: USART6 clock - * @arg RCC_APB2Periph_ADC1: ADC1 clock - * @arg RCC_APB2Periph_ADC2: ADC2 clock - * @arg RCC_APB2Periph_ADC3: ADC3 clock - * @arg RCC_APB2Periph_SDIO: SDIO clock - * @arg RCC_APB2Periph_SPI1: SPI1 clock - * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock - * @arg RCC_APB2Periph_TIM9: TIM9 clock - * @arg RCC_APB2Periph_TIM10: TIM10 clock - * @arg RCC_APB2Periph_TIM11: TIM11 clock - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->APB2ENR |= RCC_APB2Periph; - } - else - { - RCC->APB2ENR &= ~RCC_APB2Periph; - } -} - -/** - * @brief Forces or releases AHB1 peripheral reset. - * @param RCC_AHB1Periph: specifies the AHB1 peripheral to reset. - * This parameter can be any combination of the following values: - * @arg RCC_AHB1Periph_GPIOA: GPIOA clock - * @arg RCC_AHB1Periph_GPIOB: GPIOB clock - * @arg RCC_AHB1Periph_GPIOC: GPIOC clock - * @arg RCC_AHB1Periph_GPIOD: GPIOD clock - * @arg RCC_AHB1Periph_GPIOE: GPIOE clock - * @arg RCC_AHB1Periph_GPIOF: GPIOF clock - * @arg RCC_AHB1Periph_GPIOG: GPIOG clock - * @arg RCC_AHB1Periph_GPIOG: GPIOG clock - * @arg RCC_AHB1Periph_GPIOI: GPIOI clock - * @arg RCC_AHB1Periph_CRC: CRC clock - * @arg RCC_AHB1Periph_DMA1: DMA1 clock - * @arg RCC_AHB1Periph_DMA2: DMA2 clock - * @arg RCC_AHB1Periph_ETH_MAC: Ethernet MAC clock - * @arg RCC_AHB1Periph_OTG_HS: USB OTG HS clock - * - * @param NewState: new state of the specified peripheral reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_AHB1_RESET_PERIPH(RCC_AHB1Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->AHB1RSTR |= RCC_AHB1Periph; - } - else - { - RCC->AHB1RSTR &= ~RCC_AHB1Periph; - } -} - -/** - * @brief Forces or releases AHB2 peripheral reset. - * @param RCC_AHB2Periph: specifies the AHB2 peripheral to reset. - * This parameter can be any combination of the following values: - * @arg RCC_AHB2Periph_DCMI: DCMI clock - * @arg RCC_AHB2Periph_CRYP: CRYP clock - * @arg RCC_AHB2Periph_HASH: HASH clock - * @arg RCC_AHB2Periph_RNG: RNG clock - * @arg RCC_AHB2Periph_OTG_FS: USB OTG FS clock - * @param NewState: new state of the specified peripheral reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_AHB2_PERIPH(RCC_AHB2Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->AHB2RSTR |= RCC_AHB2Periph; - } - else - { - RCC->AHB2RSTR &= ~RCC_AHB2Periph; - } -} - -/** - * @brief Forces or releases AHB3 peripheral reset. - * @param RCC_AHB3Periph: specifies the AHB3 peripheral to reset. - * This parameter must be: RCC_AHB3Periph_FSMC - * @param NewState: new state of the specified peripheral reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_AHB3_PERIPH(RCC_AHB3Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - RCC->AHB3RSTR |= RCC_AHB3Periph; - } - else - { - RCC->AHB3RSTR &= ~RCC_AHB3Periph; - } -} - -/** - * @brief Forces or releases Low Speed APB (APB1) peripheral reset. - * @param RCC_APB1Periph: specifies the APB1 peripheral to reset. - * This parameter can be any combination of the following values: - * @arg RCC_APB1Periph_TIM2: TIM2 clock - * @arg RCC_APB1Periph_TIM3: TIM3 clock - * @arg RCC_APB1Periph_TIM4: TIM4 clock - * @arg RCC_APB1Periph_TIM5: TIM5 clock - * @arg RCC_APB1Periph_TIM6: TIM6 clock - * @arg RCC_APB1Periph_TIM7: TIM7 clock - * @arg RCC_APB1Periph_TIM12: TIM12 clock - * @arg RCC_APB1Periph_TIM13: TIM13 clock - * @arg RCC_APB1Periph_TIM14: TIM14 clock - * @arg RCC_APB1Periph_WWDG: WWDG clock - * @arg RCC_APB1Periph_SPI2: SPI2 clock - * @arg RCC_APB1Periph_SPI3: SPI3 clock - * @arg RCC_APB1Periph_USART2: USART2 clock - * @arg RCC_APB1Periph_USART3: USART3 clock - * @arg RCC_APB1Periph_UART4: UART4 clock - * @arg RCC_APB1Periph_UART5: UART5 clock - * @arg RCC_APB1Periph_I2C1: I2C1 clock - * @arg RCC_APB1Periph_I2C2: I2C2 clock - * @arg RCC_APB1Periph_I2C3: I2C3 clock - * @arg RCC_APB1Periph_CAN1: CAN1 clock - * @arg RCC_APB1Periph_CAN2: CAN2 clock - * @arg RCC_APB1Periph_PWR: PWR clock - * @arg RCC_APB1Periph_DAC: DAC clock - * @param NewState: new state of the specified peripheral reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - RCC->APB1RSTR |= RCC_APB1Periph; - } - else - { - RCC->APB1RSTR &= ~RCC_APB1Periph; - } -} - -/** - * @brief Forces or releases High Speed APB (APB2) peripheral reset. - * @param RCC_APB2Periph: specifies the APB2 peripheral to reset. - * This parameter can be any combination of the following values: - * @arg RCC_APB2Periph_TIM1: TIM1 clock - * @arg RCC_APB2Periph_TIM8: TIM8 clock - * @arg RCC_APB2Periph_USART1: USART1 clock - * @arg RCC_APB2Periph_USART6: USART6 clock - * @arg RCC_APB2Periph_ADC1: ADC1 clock - * @arg RCC_APB2Periph_ADC2: ADC2 clock - * @arg RCC_APB2Periph_ADC3: ADC3 clock - * @arg RCC_APB2Periph_SDIO: SDIO clock - * @arg RCC_APB2Periph_SPI1: SPI1 clock - * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock - * @arg RCC_APB2Periph_TIM9: TIM9 clock - * @arg RCC_APB2Periph_TIM10: TIM10 clock - * @arg RCC_APB2Periph_TIM11: TIM11 clock - * @param NewState: new state of the specified peripheral reset. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB2_RESET_PERIPH(RCC_APB2Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - RCC->APB2RSTR |= RCC_APB2Periph; - } - else - { - RCC->APB2RSTR &= ~RCC_APB2Periph; - } -} - -/** - * @brief Enables or disables the AHB1 peripheral clock during Low Power (Sleep) mode. - * @note Peripheral clock gating in SLEEP mode can be used to further reduce - * power consumption. - * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. - * @note By default, all peripheral clocks are enabled during SLEEP mode. - * @param RCC_AHBPeriph: specifies the AHB1 peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_AHB1Periph_GPIOA: GPIOA clock - * @arg RCC_AHB1Periph_GPIOB: GPIOB clock - * @arg RCC_AHB1Periph_GPIOC: GPIOC clock - * @arg RCC_AHB1Periph_GPIOD: GPIOD clock - * @arg RCC_AHB1Periph_GPIOE: GPIOE clock - * @arg RCC_AHB1Periph_GPIOF: GPIOF clock - * @arg RCC_AHB1Periph_GPIOG: GPIOG clock - * @arg RCC_AHB1Periph_GPIOG: GPIOG clock - * @arg RCC_AHB1Periph_GPIOI: GPIOI clock - * @arg RCC_AHB1Periph_CRC: CRC clock - * @arg RCC_AHB1Periph_BKPSRAM: BKPSRAM interface clock - * @arg RCC_AHB1Periph_DMA1: DMA1 clock - * @arg RCC_AHB1Periph_DMA2: DMA2 clock - * @arg RCC_AHB1Periph_ETH_MAC: Ethernet MAC clock - * @arg RCC_AHB1Periph_ETH_MAC_Tx: Ethernet Transmission clock - * @arg RCC_AHB1Periph_ETH_MAC_Rx: Ethernet Reception clock - * @arg RCC_AHB1Periph_ETH_MAC_PTP: Ethernet PTP clock - * @arg RCC_AHB1Periph_OTG_HS: USB OTG HS clock - * @arg RCC_AHB1Periph_OTG_HS_ULPI: USB OTG HS ULPI clock - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_AHB1PeriphClockLPModeCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_AHB1_LPMODE_PERIPH(RCC_AHB1Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - RCC->AHB1LPENR |= RCC_AHB1Periph; - } - else - { - RCC->AHB1LPENR &= ~RCC_AHB1Periph; - } -} - -/** - * @brief Enables or disables the AHB2 peripheral clock during Low Power (Sleep) mode. - * @note Peripheral clock gating in SLEEP mode can be used to further reduce - * power consumption. - * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. - * @note By default, all peripheral clocks are enabled during SLEEP mode. - * @param RCC_AHBPeriph: specifies the AHB2 peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_AHB2Periph_DCMI: DCMI clock - * @arg RCC_AHB2Periph_CRYP: CRYP clock - * @arg RCC_AHB2Periph_HASH: HASH clock - * @arg RCC_AHB2Periph_RNG: RNG clock - * @arg RCC_AHB2Periph_OTG_FS: USB OTG FS clock - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_AHB2PeriphClockLPModeCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_AHB2_PERIPH(RCC_AHB2Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - RCC->AHB2LPENR |= RCC_AHB2Periph; - } - else - { - RCC->AHB2LPENR &= ~RCC_AHB2Periph; - } -} - -/** - * @brief Enables or disables the AHB3 peripheral clock during Low Power (Sleep) mode. - * @note Peripheral clock gating in SLEEP mode can be used to further reduce - * power consumption. - * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. - * @note By default, all peripheral clocks are enabled during SLEEP mode. - * @param RCC_AHBPeriph: specifies the AHB3 peripheral to gates its clock. - * This parameter must be: RCC_AHB3Periph_FSMC - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_AHB3PeriphClockLPModeCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_AHB3_PERIPH(RCC_AHB3Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - RCC->AHB3LPENR |= RCC_AHB3Periph; - } - else - { - RCC->AHB3LPENR &= ~RCC_AHB3Periph; - } -} - -/** - * @brief Enables or disables the APB1 peripheral clock during Low Power (Sleep) mode. - * @note Peripheral clock gating in SLEEP mode can be used to further reduce - * power consumption. - * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. - * @note By default, all peripheral clocks are enabled during SLEEP mode. - * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_APB1Periph_TIM2: TIM2 clock - * @arg RCC_APB1Periph_TIM3: TIM3 clock - * @arg RCC_APB1Periph_TIM4: TIM4 clock - * @arg RCC_APB1Periph_TIM5: TIM5 clock - * @arg RCC_APB1Periph_TIM6: TIM6 clock - * @arg RCC_APB1Periph_TIM7: TIM7 clock - * @arg RCC_APB1Periph_TIM12: TIM12 clock - * @arg RCC_APB1Periph_TIM13: TIM13 clock - * @arg RCC_APB1Periph_TIM14: TIM14 clock - * @arg RCC_APB1Periph_WWDG: WWDG clock - * @arg RCC_APB1Periph_SPI2: SPI2 clock - * @arg RCC_APB1Periph_SPI3: SPI3 clock - * @arg RCC_APB1Periph_USART2: USART2 clock - * @arg RCC_APB1Periph_USART3: USART3 clock - * @arg RCC_APB1Periph_UART4: UART4 clock - * @arg RCC_APB1Periph_UART5: UART5 clock - * @arg RCC_APB1Periph_I2C1: I2C1 clock - * @arg RCC_APB1Periph_I2C2: I2C2 clock - * @arg RCC_APB1Periph_I2C3: I2C3 clock - * @arg RCC_APB1Periph_CAN1: CAN1 clock - * @arg RCC_APB1Periph_CAN2: CAN2 clock - * @arg RCC_APB1Periph_PWR: PWR clock - * @arg RCC_APB1Periph_DAC: DAC clock - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - RCC->APB1LPENR |= RCC_APB1Periph; - } - else - { - RCC->APB1LPENR &= ~RCC_APB1Periph; - } -} - -/** - * @brief Enables or disables the APB2 peripheral clock during Low Power (Sleep) mode. - * @note Peripheral clock gating in SLEEP mode can be used to further reduce - * power consumption. - * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. - * @note By default, all peripheral clocks are enabled during SLEEP mode. - * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock. - * This parameter can be any combination of the following values: - * @arg RCC_APB2Periph_TIM1: TIM1 clock - * @arg RCC_APB2Periph_TIM8: TIM8 clock - * @arg RCC_APB2Periph_USART1: USART1 clock - * @arg RCC_APB2Periph_USART6: USART6 clock - * @arg RCC_APB2Periph_ADC1: ADC1 clock - * @arg RCC_APB2Periph_ADC2: ADC2 clock - * @arg RCC_APB2Periph_ADC3: ADC3 clock - * @arg RCC_APB2Periph_SDIO: SDIO clock - * @arg RCC_APB2Periph_SPI1: SPI1 clock - * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock - * @arg RCC_APB2Periph_TIM9: TIM9 clock - * @arg RCC_APB2Periph_TIM10: TIM10 clock - * @arg RCC_APB2Periph_TIM11: TIM11 clock - * @param NewState: new state of the specified peripheral clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - RCC->APB2LPENR |= RCC_APB2Periph; - } - else - { - RCC->APB2LPENR &= ~RCC_APB2Periph; - } -} - -/** - * @} - */ - -/** @defgroup RCC_Group4 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified RCC interrupts. - * @param RCC_IT: specifies the RCC interrupt sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg RCC_IT_LSIRDY: LSI ready interrupt - * @arg RCC_IT_LSERDY: LSE ready interrupt - * @arg RCC_IT_HSIRDY: HSI ready interrupt - * @arg RCC_IT_HSERDY: HSE ready interrupt - * @arg RCC_IT_PLLRDY: main PLL ready interrupt - * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt - * @param NewState: new state of the specified RCC interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RCC_IT(RCC_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Perform Byte access to RCC_CIR[14:8] bits to enable the selected interrupts */ - *(__IO uint8_t *) CIR_BYTE2_ADDRESS |= RCC_IT; - } - else - { - /* Perform Byte access to RCC_CIR[14:8] bits to disable the selected interrupts */ - *(__IO uint8_t *) CIR_BYTE2_ADDRESS &= (uint8_t)~RCC_IT; - } -} - -/** - * @brief Checks whether the specified RCC flag is set or not. - * @param RCC_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready - * @arg RCC_FLAG_HSERDY: HSE oscillator clock ready - * @arg RCC_FLAG_PLLRDY: main PLL clock ready - * @arg RCC_FLAG_PLLI2SRDY: PLLI2S clock ready - * @arg RCC_FLAG_LSERDY: LSE oscillator clock ready - * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready - * @arg RCC_FLAG_BORRST: POR/PDR or BOR reset - * @arg RCC_FLAG_PINRST: Pin reset - * @arg RCC_FLAG_PORRST: POR/PDR reset - * @arg RCC_FLAG_SFTRST: Software reset - * @arg RCC_FLAG_IWDGRST: Independent Watchdog reset - * @arg RCC_FLAG_WWDGRST: Window Watchdog reset - * @arg RCC_FLAG_LPWRRST: Low Power reset - * @retval The new state of RCC_FLAG (SET or RESET). - */ -FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG) -{ - uint32_t tmp = 0; - uint32_t statusreg = 0; - FlagStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_RCC_FLAG(RCC_FLAG)); - - /* Get the RCC register index */ - tmp = RCC_FLAG >> 5; - if (tmp == 1) /* The flag to check is in CR register */ - { - statusreg = RCC->CR; - } - else if (tmp == 2) /* The flag to check is in BDCR register */ - { - statusreg = RCC->BDCR; - } - else /* The flag to check is in CSR register */ - { - statusreg = RCC->CSR; - } - - /* Get the flag position */ - tmp = RCC_FLAG & FLAG_MASK; - if ((statusreg & ((uint32_t)1 << tmp)) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the flag status */ - return bitstatus; -} - -/** - * @brief Clears the RCC reset flags. - * The reset flags are: RCC_FLAG_PINRST, RCC_FLAG_PORRST, RCC_FLAG_SFTRST, - * RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST - * @param None - * @retval None - */ -void RCC_ClearFlag(void) -{ - /* Set RMVF bit to clear the reset flags */ - RCC->CSR |= RCC_CSR_RMVF; -} - -/** - * @brief Checks whether the specified RCC interrupt has occurred or not. - * @param RCC_IT: specifies the RCC interrupt source to check. - * This parameter can be one of the following values: - * @arg RCC_IT_LSIRDY: LSI ready interrupt - * @arg RCC_IT_LSERDY: LSE ready interrupt - * @arg RCC_IT_HSIRDY: HSI ready interrupt - * @arg RCC_IT_HSERDY: HSE ready interrupt - * @arg RCC_IT_PLLRDY: main PLL ready interrupt - * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt - * @arg RCC_IT_CSS: Clock Security System interrupt - * @retval The new state of RCC_IT (SET or RESET). - */ -ITStatus RCC_GetITStatus(uint8_t RCC_IT) -{ - ITStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_RCC_GET_IT(RCC_IT)); - - /* Check the status of the specified RCC interrupt */ - if ((RCC->CIR & RCC_IT) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - /* Return the RCC_IT status */ - return bitstatus; -} - -/** - * @brief Clears the RCC's interrupt pending bits. - * @param RCC_IT: specifies the interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg RCC_IT_LSIRDY: LSI ready interrupt - * @arg RCC_IT_LSERDY: LSE ready interrupt - * @arg RCC_IT_HSIRDY: HSI ready interrupt - * @arg RCC_IT_HSERDY: HSE ready interrupt - * @arg RCC_IT_PLLRDY: main PLL ready interrupt - * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt - * @arg RCC_IT_CSS: Clock Security System interrupt - * @retval None - */ -void RCC_ClearITPendingBit(uint8_t RCC_IT) -{ - /* Check the parameters */ - assert_param(IS_RCC_CLEAR_IT(RCC_IT)); - - /* Perform Byte access to RCC_CIR[23:16] bits to clear the selected interrupt - pending bits */ - *(__IO uint8_t *) CIR_BYTE3_ADDRESS = RCC_IT; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rng.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rng.c deleted file mode 100644 index 51817dcc0..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rng.c +++ /dev/null @@ -1,399 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_rng.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the Random Number Generator (RNG) peripheral: - * - Initialization and Configuration - * - Get 32 bit Random number - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable The RNG controller clock using - * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE) function. - * - * 2. Activate the RNG peripheral using RNG_Cmd() function. - * - * 3. Wait until the 32 bit Random number Generator contains a valid - * random data (using polling/interrupt mode). For more details, - * refer to "Interrupts and flags management functions" module - * description. - * - * 4. Get the 32 bit Random number using RNG_GetRandomNumber() function - * - * 5. To get another 32 bit Random number, go to step 3. - * - * - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_rng.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup RNG - * @brief RNG driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup RNG_Private_Functions - * @{ - */ - -/** @defgroup RNG_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - This section provides functions allowing to - - Initialize the RNG peripheral - - Enable or disable the RNG peripheral - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the RNG peripheral registers to their default reset values. - * @param None - * @retval None - */ -void RNG_DeInit(void) -{ - /* Enable RNG reset state */ - RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_RNG, ENABLE); - - /* Release RNG from reset state */ - RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_RNG, DISABLE); -} - -/** - * @brief Enables or disables the RNG peripheral. - * @param NewState: new state of the RNG peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RNG_Cmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the RNG */ - RNG->CR |= RNG_CR_RNGEN; - } - else - { - /* Disable the RNG */ - RNG->CR &= ~RNG_CR_RNGEN; - } -} -/** - * @} - */ - -/** @defgroup RNG_Group2 Get 32 bit Random number function - * @brief Get 32 bit Random number function - * - -@verbatim - =============================================================================== - Get 32 bit Random number function - =============================================================================== - This section provides a function allowing to get the 32 bit Random number - - @note Before to call this function you have to wait till DRDY flag is set, - using RNG_GetFlagStatus(RNG_FLAG_DRDY) function. - -@endverbatim - * @{ - */ - - -/** - * @brief Returns a 32-bit random number. - * - * @note Before to call this function you have to wait till DRDY (data ready) - * flag is set, using RNG_GetFlagStatus(RNG_FLAG_DRDY) function. - * @note Each time the the Random number data is read (using RNG_GetRandomNumber() - * function), the RNG_FLAG_DRDY flag is automatically cleared. - * @note In the case of a seed error, the generation of random numbers is - * interrupted for as long as the SECS bit is '1'. If a number is - * available in the RNG_DR register, it must not be used because it may - * not have enough entropy. In this case, it is recommended to clear the - * SEIS bit(using RNG_ClearFlag(RNG_FLAG_SECS) function), then disable - * and enable the RNG peripheral (using RNG_Cmd() function) to - * reinitialize and restart the RNG. - * @note In the case of a clock error, the RNG is no more able to generate - * random numbers because the PLL48CLK clock is not correct. User have - * to check that the clock controller is correctly configured to provide - * the RNG clock and clear the CEIS bit (using RNG_ClearFlag(RNG_FLAG_CECS) - * function) . The clock error has no impact on the previously generated - * random numbers, and the RNG_DR register contents can be used. - * - * @param None - * @retval 32-bit random number. - */ -uint32_t RNG_GetRandomNumber(void) -{ - /* Return the 32 bit random number from the DR register */ - return RNG->DR; -} - - -/** - * @} - */ - -/** @defgroup RNG_Group3 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - - This section provides functions allowing to configure the RNG Interrupts and - to get the status and clear flags and Interrupts pending bits. - - The RNG provides 3 Interrupts sources and 3 Flags: - - Flags : - ---------- - 1. RNG_FLAG_DRDY : In the case of the RNG_DR register contains valid - random data. it is cleared by reading the valid data - (using RNG_GetRandomNumber() function). - - 2. RNG_FLAG_CECS : In the case of a seed error detection. - - 3. RNG_FLAG_SECS : In the case of a clock error detection. - - - Interrupts : - ------------ - if enabled, an RNG interrupt is pending : - - 1. In the case of the RNG_DR register contains valid random data. - This interrupt source is cleared once the RNG_DR register has been read - (using RNG_GetRandomNumber() function) until a new valid value is - computed. - - or - 2. In the case of a seed error : One of the following faulty sequences has - been detected: - - More than 64 consecutive bits at the same value (0 or 1) - - More than 32 consecutive alternance of 0 and 1 (0101010101...01) - This interrupt source is cleared using RNG_ClearITPendingBit(RNG_IT_SEI) - function. - - or - 3. In the case of a clock error : the PLL48CLK (RNG peripheral clock source) - was not correctly detected (fPLL48CLK< fHCLK/16). - This interrupt source is cleared using RNG_ClearITPendingBit(RNG_IT_CEI) - function. - @note In this case, User have to check that the clock controller is - correctly configured to provide the RNG clock. - - Managing the RNG controller events : - ------------------------------------ - The user should identify which mode will be used in his application to manage - the RNG controller events: Polling mode or Interrupt mode. - - 1. In the Polling Mode it is advised to use the following functions: - - RNG_GetFlagStatus() : to check if flags events occur. - - RNG_ClearFlag() : to clear the flags events. - - @note RNG_FLAG_DRDY can not be cleared by RNG_ClearFlag(). it is cleared only - by reading the Random number data. - - 2. In the Interrupt Mode it is advised to use the following functions: - - RNG_ITConfig() : to enable or disable the interrupt source. - - RNG_GetITStatus() : to check if Interrupt occurs. - - RNG_ClearITPendingBit() : to clear the Interrupt pending Bit - (corresponding Flag). - - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the RNG interrupt. - * @note The RNG provides 3 interrupt sources, - * - Computed data is ready event (DRDY), and - * - Seed error Interrupt (SEI) and - * - Clock error Interrupt (CEI), - * all these interrupts sources are enabled by setting the IE bit in - * CR register. However, each interrupt have its specific status bit - * (see RNG_GetITStatus() function) and clear bit except the DRDY event - * (see RNG_ClearITPendingBit() function). - * @param NewState: new state of the RNG interrupt. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RNG_ITConfig(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the RNG interrupt */ - RNG->CR |= RNG_CR_IE; - } - else - { - /* Disable the RNG interrupt */ - RNG->CR &= ~RNG_CR_IE; - } -} - -/** - * @brief Checks whether the specified RNG flag is set or not. - * @param RNG_FLAG: specifies the RNG flag to check. - * This parameter can be one of the following values: - * @arg RNG_FLAG_DRDY: Data Ready flag. - * @arg RNG_FLAG_CECS: Clock Error Current flag. - * @arg RNG_FLAG_SECS: Seed Error Current flag. - * @retval The new state of RNG_FLAG (SET or RESET). - */ -FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_RNG_GET_FLAG(RNG_FLAG)); - - /* Check the status of the specified RNG flag */ - if ((RNG->SR & RNG_FLAG) != (uint8_t)RESET) - { - /* RNG_FLAG is set */ - bitstatus = SET; - } - else - { - /* RNG_FLAG is reset */ - bitstatus = RESET; - } - /* Return the RNG_FLAG status */ - return bitstatus; -} - - -/** - * @brief Clears the RNG flags. - * @param RNG_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg RNG_FLAG_CECS: Clock Error Current flag. - * @arg RNG_FLAG_SECS: Seed Error Current flag. - * @note RNG_FLAG_DRDY can not be cleared by RNG_ClearFlag() function. - * This flag is cleared only by reading the Random number data (using - * RNG_GetRandomNumber() function). - * @retval None - */ -void RNG_ClearFlag(uint8_t RNG_FLAG) -{ - /* Check the parameters */ - assert_param(IS_RNG_CLEAR_FLAG(RNG_FLAG)); - /* Clear the selected RNG flags */ - RNG->SR = ~(uint32_t)(((uint32_t)RNG_FLAG) << 4); -} - -/** - * @brief Checks whether the specified RNG interrupt has occurred or not. - * @param RNG_IT: specifies the RNG interrupt source to check. - * This parameter can be one of the following values: - * @arg RNG_IT_CEI: Clock Error Interrupt. - * @arg RNG_IT_SEI: Seed Error Interrupt. - * @retval The new state of RNG_IT (SET or RESET). - */ -ITStatus RNG_GetITStatus(uint8_t RNG_IT) -{ - ITStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_RNG_GET_IT(RNG_IT)); - - /* Check the status of the specified RNG interrupt */ - if ((RNG->SR & RNG_IT) != (uint8_t)RESET) - { - /* RNG_IT is set */ - bitstatus = SET; - } - else - { - /* RNG_IT is reset */ - bitstatus = RESET; - } - /* Return the RNG_IT status */ - return bitstatus; -} - - -/** - * @brief Clears the RNG interrupt pending bit(s). - * @param RNG_IT: specifies the RNG interrupt pending bit(s) to clear. - * This parameter can be any combination of the following values: - * @arg RNG_IT_CEI: Clock Error Interrupt. - * @arg RNG_IT_SEI: Seed Error Interrupt. - * @retval None - */ -void RNG_ClearITPendingBit(uint8_t RNG_IT) -{ - /* Check the parameters */ - assert_param(IS_RNG_IT(RNG_IT)); - - /* Clear the selected RNG interrupt pending bit */ - RNG->SR = (uint8_t)~RNG_IT; -} -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - - -/** - * @} - */ - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rtc.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rtc.c deleted file mode 100644 index 53b9ca1ac..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rtc.c +++ /dev/null @@ -1,2733 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_rtc.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the Real-Time Clock (RTC) peripheral: - * - Initialization - * - Calendar (Time and Date) configuration - * - Alarms (Alarm A and Alarm B) configuration - * - WakeUp Timer configuration - * - Daylight Saving configuration - * - Output pin Configuration - * - Coarse digital Calibration configuration - * - Smooth digital Calibration configuration - * - TimeStamp configuration - * - Tampers configuration - * - Backup Data Registers configuration - * - Shift control synchronisation - * - RTC Tamper and TimeStamp Pins Selection and Output Type Config configuration - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * Backup Domain Operating Condition - * =================================================================== - * The real-time clock (RTC), the RTC backup registers, and the backup - * SRAM (BKP SRAM) can be powered from the VBAT voltage when the main - * VDD supply is powered off. - * To retain the content of the RTC backup registers, backup SRAM, - * and supply the RTC when VDD is turned off, VBAT pin can be connected - * to an optional standby voltage supplied by a battery or by another - * source. - * - * To allow the RTC to operate even when the main digital supply (VDD) - * is turned off, the VBAT pin powers the following blocks: - * 1 - The RTC - * 2 - The LSE oscillator - * 3 - The backup SRAM when the low power backup regulator is enabled - * 4 - PC13 to PC15 I/Os, plus PI8 I/O (when available) - * - * When the backup domain is supplied by VDD (analog switch connected - * to VDD), the following functions are available: - * 1 - PC14 and PC15 can be used as either GPIO or LSE pins - * 2 - PC13 can be used as a GPIO or as the RTC_AF1 pin - * 3 - PI8 can be used as a GPIO or as the RTC_AF2 pin - * - * When the backup domain is supplied by VBAT (analog switch connected - * to VBAT because VDD is not present), the following functions are available: - * 1 - PC14 and PC15 can be used as LSE pins only - * 2 - PC13 can be used as the RTC_AF1 pin - * 3 - PI8 can be used as the RTC_AF2 pin - * - * =================================================================== - * Backup Domain Reset - * =================================================================== - * The backup domain reset sets all RTC registers and the RCC_BDCR - * register to their reset values. The BKPSRAM is not affected by this - * reset. The only way of resetting the BKPSRAM is through the Flash - * interface by requesting a protection level change from 1 to 0. - * A backup domain reset is generated when one of the following events - * occurs: - * 1 - Software reset, triggered by setting the BDRST bit in the - * RCC Backup domain control register (RCC_BDCR). You can use the - * RCC_BackupResetCmd(). - * 2 - VDD or VBAT power on, if both supplies have previously been - * powered off. - * - * =================================================================== - * Backup Domain Access - * =================================================================== - * After reset, the backup domain (RTC registers, RTC backup data - * registers and backup SRAM) is protected against possible unwanted - * write accesses. - * To enable access to the RTC Domain and RTC registers, proceed as follows: - * - Enable the Power Controller (PWR) APB1 interface clock using the - * RCC_APB1PeriphClockCmd() function. - * - Enable access to RTC domain using the PWR_BackupAccessCmd() function. - * - Select the RTC clock source using the RCC_RTCCLKConfig() function. - * - Enable RTC Clock using the RCC_RTCCLKCmd() function. - * - * =================================================================== - * RTC Driver: how to use it - * =================================================================== - * - Enable the RTC domain access (see description in the section above) - * - Configure the RTC Prescaler (Asynchronous and Synchronous) and - * RTC hour format using the RTC_Init() function. - * - * Time and Date configuration - * =========================== - * - To configure the RTC Calendar (Time and Date) use the RTC_SetTime() - * and RTC_SetDate() functions. - * - To read the RTC Calendar, use the RTC_GetTime() and RTC_GetDate() - * functions. - * - Use the RTC_DayLightSavingConfig() function to add or sub one - * hour to the RTC Calendar. - * - * Alarm configuration - * =================== - * - To configure the RTC Alarm use the RTC_SetAlarm() function. - * - Enable the selected RTC Alarm using the RTC_AlarmCmd() function - * - To read the RTC Alarm, use the RTC_GetAlarm() function. - * - To read the RTC alarm SubSecond, use the RTC_GetAlarmSubSecond() function. - * - * RTC Wakeup configuration - * ======================== - * - Configure the RTC Wakeup Clock source use the RTC_WakeUpClockConfig() - * function. - * - Configure the RTC WakeUp Counter using the RTC_SetWakeUpCounter() - * function - * - Enable the RTC WakeUp using the RTC_WakeUpCmd() function - * - To read the RTC WakeUp Counter register, use the RTC_GetWakeUpCounter() - * function. - * - * Outputs configuration - * ===================== - * The RTC has 2 different outputs: - * - AFO_ALARM: this output is used to manage the RTC Alarm A, Alarm B - * and WaKeUp signals. - * To output the selected RTC signal on RTC_AF1 pin, use the - * RTC_OutputConfig() function. - * - AFO_CALIB: this output is 512Hz signal or 1Hz . - * To output the RTC Clock on RTC_AF1 pin, use the RTC_CalibOutputCmd() - * function. - * - * Smooth digital Calibration configuration - * ================================= - * - Configure the RTC Original Digital Calibration Value and the corresponding - * calibration cycle period (32s,16s and 8s) using the RTC_SmoothCalibConfig() - * function. - * - * Coarse digital Calibration configuration - * ================================= - * - Configure the RTC Coarse Calibration Value and the corresponding - * sign using the RTC_CoarseCalibConfig() function. - * - Enable the RTC Coarse Calibration using the RTC_CoarseCalibCmd() - * function - * - * TimeStamp configuration - * ======================= - * - Configure the RTC_AF1 trigger and enables the RTC TimeStamp - * using the RTC_TimeStampCmd() function. - * - To read the RTC TimeStamp Time and Date register, use the - * RTC_GetTimeStamp() function. - * - To read the RTC TimeStamp SubSecond register, use the - * RTC_GetTimeStampSubSecond() function. - * - The TAMPER1 alternate function can be mapped either to RTC_AF1(PC13) - * or RTC_AF2 (PI8) depending on the value of TAMP1INSEL bit in - * RTC_TAFCR register. You can use the RTC_TamperPinSelection() - * function to select the corresponding pin. - * - * Tamper configuration - * ==================== - * - Enable the RTC Tamper using the RTC_TamperCmd() function. - * - Configure the Tamper filter count using RTC_TamperFilterConfig() - * function. - * - Configure the RTC Tamper trigger Edge or Level according to the Tamper - * filter (if equal to 0 Edge else Level) value using the RTC_TamperConfig() function. - * - Configure the Tamper sampling frequency using RTC_TamperSamplingFreqConfig() - * function. - * - Configure the Tamper precharge or discharge duration using - * RTC_TamperPinsPrechargeDuration() function. - * - Enable the Tamper Pull-UP using RTC_TamperPullUpDisableCmd() function. - * - Enable the Time stamp on Tamper detection event using - * RTC_TSOnTamperDetecCmd() function. - * - The TIMESTAMP alternate function can be mapped to either RTC_AF1 - * or RTC_AF2 depending on the value of the TSINSEL bit in the - * RTC_TAFCR register. You can use the RTC_TimeStampPinSelection() - * function to select the corresponding pin. - * - * Backup Data Registers configuration - * =================================== - * - To write to the RTC Backup Data registers, use the RTC_WriteBackupRegister() - * function. - * - To read the RTC Backup Data registers, use the RTC_ReadBackupRegister() - * function. - * - * =================================================================== - * RTC and low power modes - * =================================================================== - * The MCU can be woken up from a low power mode by an RTC alternate - * function. - * The RTC alternate functions are the RTC alarms (Alarm A and Alarm B), - * RTC wakeup, RTC tamper event detection and RTC time stamp event detection. - * These RTC alternate functions can wake up the system from the Stop - * and Standby lowpower modes. - * The system can also wake up from low power modes without depending - * on an external interrupt (Auto-wakeup mode), by using the RTC alarm - * or the RTC wakeup events. - * The RTC provides a programmable time base for waking up from the - * Stop or Standby mode at regular intervals. - * Wakeup from STOP and Standby modes is possible only when the RTC - * clock source is LSE or LSI. - * - * =================================================================== - * Selection of RTC_AF1 alternate functions - * =================================================================== - * The RTC_AF1 pin (PC13) can be used for the following purposes: - * - AFO_ALARM output - * - AFO_CALIB output - * - AFI_TAMPER - * - AFI_TIMESTAMP - * - * +-------------------------------------------------------------------------------------------------------------+ - * | Pin |AFO_ALARM |AFO_CALIB |AFI_TAMPER |AFI_TIMESTAMP | TAMP1INSEL | TSINSEL |ALARMOUTTYPE | - * | configuration | ENABLED | ENABLED | ENABLED | ENABLED |TAMPER1 pin |TIMESTAMP pin | AFO_ALARM | - * | and function | | | | | selection | selection |Configuration | - * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------| - * | Alarm out | | | | | Don't | Don't | | - * | output OD | 1 |Don't care|Don't care | Don't care | care | care | 0 | - * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------| - * | Alarm out | | | | | Don't | Don't | | - * | output PP | 1 |Don't care|Don't care | Don't care | care | care | 1 | - * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------| - * | Calibration out | | | | | Don't | Don't | | - * | output PP | 0 | 1 |Don't care | Don't care | care | care | Don't care | - * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------| - * | TAMPER input | | | | | | Don't | | - * | floating | 0 | 0 | 1 | 0 | 0 | care | Don't care | - * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------| - * | TIMESTAMP and | | | | | | | | - * | TAMPER input | 0 | 0 | 1 | 1 | 0 | 0 | Don't care | - * | floating | | | | | | | | - * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------| - * | TIMESTAMP input | | | | | Don't | | | - * | floating | 0 | 0 | 0 | 1 | care | 0 | Don't care | - * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------| - * | Standard GPIO | 0 | 0 | 0 | 0 | Don't care | Don't care | Don't care | - * +-------------------------------------------------------------------------------------------------------------+ - * - * - * =================================================================== - * Selection of RTC_AF2 alternate functions - * =================================================================== - * The RTC_AF2 pin (PI8) can be used for the following purposes: - * - AFI_TAMPER - * - AFI_TIMESTAMP - * - * +---------------------------------------------------------------------------------------+ - * | Pin |AFI_TAMPER |AFI_TIMESTAMP | TAMP1INSEL | TSINSEL |ALARMOUTTYPE | - * | configuration | ENABLED | ENABLED |TAMPER1 pin |TIMESTAMP pin | AFO_ALARM | - * | and function | | | selection | selection |Configuration | - * |-----------------|-----------|--------------|------------|--------------|--------------| - * | TAMPER input | | | | Don't | | - * | floating | 1 | 0 | 1 | care | Don't care | - * |-----------------|-----------|--------------|------------|--------------|--------------| - * | TIMESTAMP and | | | | | | - * | TAMPER input | 1 | 1 | 1 | 1 | Don't care | - * | floating | | | | | | - * |-----------------|-----------|--------------|------------|--------------|--------------| - * | TIMESTAMP input | | | Don't | | | - * | floating | 0 | 1 | care | 1 | Don't care | - * |-----------------|-----------|--------------|------------|--------------|--------------| - * | Standard GPIO | 0 | 0 | Don't care | Don't care | Don't care | - * +---------------------------------------------------------------------------------------+ - * - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_rtc.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup RTC - * @brief RTC driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* Masks Definition */ -#define RTC_TR_RESERVED_MASK ((uint32_t)0x007F7F7F) -#define RTC_DR_RESERVED_MASK ((uint32_t)0x00FFFF3F) -#define RTC_INIT_MASK ((uint32_t)0xFFFFFFFF) -#define RTC_RSF_MASK ((uint32_t)0xFFFFFF5F) -#define RTC_FLAGS_MASK ((uint32_t)(RTC_FLAG_TSOVF | RTC_FLAG_TSF | RTC_FLAG_WUTF | \ - RTC_FLAG_ALRBF | RTC_FLAG_ALRAF | RTC_FLAG_INITF | \ - RTC_FLAG_RSF | RTC_FLAG_INITS | RTC_FLAG_WUTWF | \ - RTC_FLAG_ALRBWF | RTC_FLAG_ALRAWF | RTC_FLAG_TAMP1F )) - -#define INITMODE_TIMEOUT ((uint32_t) 0x00010000) -#define SYNCHRO_TIMEOUT ((uint32_t) 0x00020000) -#define RECALPF_TIMEOUT ((uint32_t) 0x00020000) -#define SHPF_TIMEOUT ((uint32_t) 0x00001000) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -static uint8_t RTC_ByteToBcd2(uint8_t Value); -static uint8_t RTC_Bcd2ToByte(uint8_t Value); - -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup RTC_Private_Functions - * @{ - */ - -/** @defgroup RTC_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - - This section provide functions allowing to initialize and configure the RTC - Prescaler (Synchronous and Asynchronous), RTC Hour format, disable RTC registers - Write protection, enter and exit the RTC initialization mode, RTC registers - synchronization check and reference clock detection enable. - - 1. The RTC Prescaler is programmed to generate the RTC 1Hz time base. It is - split into 2 programmable prescalers to minimize power consumption. - - A 7-bit asynchronous prescaler and A 13-bit synchronous prescaler. - - When both prescalers are used, it is recommended to configure the asynchronous - prescaler to a high value to minimize consumption. - - 2. All RTC registers are Write protected. Writing to the RTC registers - is enabled by writing a key into the Write Protection register, RTC_WPR. - - 3. To Configure the RTC Calendar, user application should enter initialization - mode. In this mode, the calendar counter is stopped and its value can be - updated. When the initialization sequence is complete, the calendar restarts - counting after 4 RTCCLK cycles. - - 4. To read the calendar through the shadow registers after Calendar initialization, - calendar update or after wakeup from low power modes the software must first - clear the RSF flag. The software must then wait until it is set again before - reading the calendar, which means that the calendar registers have been - correctly copied into the RTC_TR and RTC_DR shadow registers. - The RTC_WaitForSynchro() function implements the above software sequence - (RSF clear and RSF check). - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the RTC registers to their default reset values. - * @note This function doesn't reset the RTC Clock source and RTC Backup Data - * registers. - * @param None - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC registers are deinitialized - * - ERROR: RTC registers are not deinitialized - */ -ErrorStatus RTC_DeInit(void) -{ - __IO uint32_t wutcounter = 0x00; - uint32_t wutwfstatus = 0x00; - ErrorStatus status = ERROR; - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Set Initialization mode */ - if (RTC_EnterInitMode() == ERROR) - { - status = ERROR; - } - else - { - /* Reset TR, DR and CR registers */ - RTC->TR = (uint32_t)0x00000000; - RTC->DR = (uint32_t)0x00002101; - /* Reset All CR bits except CR[2:0] */ - RTC->CR &= (uint32_t)0x00000007; - - /* Wait till RTC WUTWF flag is set and if Time out is reached exit */ - do - { - wutwfstatus = RTC->ISR & RTC_ISR_WUTWF; - wutcounter++; - } while((wutcounter != INITMODE_TIMEOUT) && (wutwfstatus == 0x00)); - - if ((RTC->ISR & RTC_ISR_WUTWF) == RESET) - { - status = ERROR; - } - else - { - /* Reset all RTC CR register bits */ - RTC->CR &= (uint32_t)0x00000000; - RTC->WUTR = (uint32_t)0x0000FFFF; - RTC->PRER = (uint32_t)0x007F00FF; - RTC->CALIBR = (uint32_t)0x00000000; - RTC->ALRMAR = (uint32_t)0x00000000; - RTC->ALRMBR = (uint32_t)0x00000000; - - /* Reset ISR register and exit initialization mode */ - RTC->ISR = (uint32_t)0x00000000; - - /* Reset Tamper and alternate functions configuration register */ - RTC->TAFCR = 0x00000000; - - if(RTC_WaitForSynchro() == ERROR) - { - status = ERROR; - } - else - { - status = SUCCESS; - } - } - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @brief Initializes the RTC registers according to the specified parameters - * in RTC_InitStruct. - * @param RTC_InitStruct: pointer to a RTC_InitTypeDef structure that contains - * the configuration information for the RTC peripheral. - * @note The RTC Prescaler register is write protected and can be written in - * initialization mode only. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC registers are initialized - * - ERROR: RTC registers are not initialized - */ -ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct) -{ - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_RTC_HOUR_FORMAT(RTC_InitStruct->RTC_HourFormat)); - assert_param(IS_RTC_ASYNCH_PREDIV(RTC_InitStruct->RTC_AsynchPrediv)); - assert_param(IS_RTC_SYNCH_PREDIV(RTC_InitStruct->RTC_SynchPrediv)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Set Initialization mode */ - if (RTC_EnterInitMode() == ERROR) - { - status = ERROR; - } - else - { - /* Clear RTC CR FMT Bit */ - RTC->CR &= ((uint32_t)~(RTC_CR_FMT)); - /* Set RTC_CR register */ - RTC->CR |= ((uint32_t)(RTC_InitStruct->RTC_HourFormat)); - - /* Configure the RTC PRER */ - RTC->PRER = (uint32_t)(RTC_InitStruct->RTC_SynchPrediv); - RTC->PRER |= (uint32_t)(RTC_InitStruct->RTC_AsynchPrediv << 16); - - /* Exit Initialization mode */ - RTC_ExitInitMode(); - - status = SUCCESS; - } - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @brief Fills each RTC_InitStruct member with its default value. - * @param RTC_InitStruct: pointer to a RTC_InitTypeDef structure which will be - * initialized. - * @retval None - */ -void RTC_StructInit(RTC_InitTypeDef* RTC_InitStruct) -{ - /* Initialize the RTC_HourFormat member */ - RTC_InitStruct->RTC_HourFormat = RTC_HourFormat_24; - - /* Initialize the RTC_AsynchPrediv member */ - RTC_InitStruct->RTC_AsynchPrediv = (uint32_t)0x7F; - - /* Initialize the RTC_SynchPrediv member */ - RTC_InitStruct->RTC_SynchPrediv = (uint32_t)0xFF; -} - -/** - * @brief Enables or disables the RTC registers write protection. - * @note All the RTC registers are write protected except for RTC_ISR[13:8], - * RTC_TAFCR and RTC_BKPxR. - * @note Writing a wrong key reactivates the write protection. - * @note The protection mechanism is not affected by system reset. - * @param NewState: new state of the write protection. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RTC_WriteProtectionCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - } - else - { - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - } -} - -/** - * @brief Enters the RTC Initialization mode. - * @note The RTC Initialization mode is write protected, use the - * RTC_WriteProtectionCmd(DISABLE) before calling this function. - * @param None - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC is in Init mode - * - ERROR: RTC is not in Init mode - */ -ErrorStatus RTC_EnterInitMode(void) -{ - __IO uint32_t initcounter = 0x00; - ErrorStatus status = ERROR; - uint32_t initstatus = 0x00; - - /* Check if the Initialization mode is set */ - if ((RTC->ISR & RTC_ISR_INITF) == (uint32_t)RESET) - { - /* Set the Initialization mode */ - RTC->ISR = (uint32_t)RTC_INIT_MASK; - - /* Wait till RTC is in INIT state and if Time out is reached exit */ - do - { - initstatus = RTC->ISR & RTC_ISR_INITF; - initcounter++; - } while((initcounter != INITMODE_TIMEOUT) && (initstatus == 0x00)); - - if ((RTC->ISR & RTC_ISR_INITF) != RESET) - { - status = SUCCESS; - } - else - { - status = ERROR; - } - } - else - { - status = SUCCESS; - } - - return (status); -} - -/** - * @brief Exits the RTC Initialization mode. - * @note When the initialization sequence is complete, the calendar restarts - * counting after 4 RTCCLK cycles. - * @note The RTC Initialization mode is write protected, use the - * RTC_WriteProtectionCmd(DISABLE) before calling this function. - * @param None - * @retval None - */ -void RTC_ExitInitMode(void) -{ - /* Exit Initialization mode */ - RTC->ISR &= (uint32_t)~RTC_ISR_INIT; -} - -/** - * @brief Waits until the RTC Time and Date registers (RTC_TR and RTC_DR) are - * synchronized with RTC APB clock. - * @note The RTC Resynchronization mode is write protected, use the - * RTC_WriteProtectionCmd(DISABLE) before calling this function. - * @note To read the calendar through the shadow registers after Calendar - * initialization, calendar update or after wakeup from low power modes - * the software must first clear the RSF flag. - * The software must then wait until it is set again before reading - * the calendar, which means that the calendar registers have been - * correctly copied into the RTC_TR and RTC_DR shadow registers. - * @param None - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC registers are synchronised - * - ERROR: RTC registers are not synchronised - */ -ErrorStatus RTC_WaitForSynchro(void) -{ - __IO uint32_t synchrocounter = 0; - ErrorStatus status = ERROR; - uint32_t synchrostatus = 0x00; - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Clear RSF flag */ - RTC->ISR &= (uint32_t)RTC_RSF_MASK; - - /* Wait the registers to be synchronised */ - do - { - synchrostatus = RTC->ISR & RTC_ISR_RSF; - synchrocounter++; - } while((synchrocounter != SYNCHRO_TIMEOUT) && (synchrostatus == 0x00)); - - if ((RTC->ISR & RTC_ISR_RSF) != RESET) - { - status = SUCCESS; - } - else - { - status = ERROR; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return (status); -} - -/** - * @brief Enables or disables the RTC reference clock detection. - * @param NewState: new state of the RTC reference clock. - * This parameter can be: ENABLE or DISABLE. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC reference clock detection is enabled - * - ERROR: RTC reference clock detection is disabled - */ -ErrorStatus RTC_RefClockCmd(FunctionalState NewState) -{ - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Set Initialization mode */ - if (RTC_EnterInitMode() == ERROR) - { - status = ERROR; - } - else - { - if (NewState != DISABLE) - { - /* Enable the RTC reference clock detection */ - RTC->CR |= RTC_CR_REFCKON; - } - else - { - /* Disable the RTC reference clock detection */ - RTC->CR &= ~RTC_CR_REFCKON; - } - /* Exit Initialization mode */ - RTC_ExitInitMode(); - - status = SUCCESS; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @brief Enables or Disables the Bypass Shadow feature. - * @note When the Bypass Shadow is enabled the calendar value are taken - * directly from the Calendar counter. - * @param NewState: new state of the Bypass Shadow feature. - * This parameter can be: ENABLE or DISABLE. - * @retval None -*/ -void RTC_BypassShadowCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - if (NewState != DISABLE) - { - /* Set the BYPSHAD bit */ - RTC->CR |= (uint8_t)RTC_CR_BYPSHAD; - } - else - { - /* Reset the BYPSHAD bit */ - RTC->CR &= (uint8_t)~RTC_CR_BYPSHAD; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @} - */ - -/** @defgroup RTC_Group2 Time and Date configuration functions - * @brief Time and Date configuration functions - * -@verbatim - =============================================================================== - Time and Date configuration functions - =============================================================================== - - This section provide functions allowing to program and read the RTC Calendar - (Time and Date). - -@endverbatim - * @{ - */ - -/** - * @brief Set the RTC current time. - * @param RTC_Format: specifies the format of the entered parameters. - * This parameter can be one of the following values: - * @arg RTC_Format_BIN: Binary data format - * @arg RTC_Format_BCD: BCD data format - * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure that contains - * the time configuration information for the RTC. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC Time register is configured - * - ERROR: RTC Time register is not configured - */ -ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct) -{ - uint32_t tmpreg = 0; - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_RTC_FORMAT(RTC_Format)); - - if (RTC_Format == RTC_Format_BIN) - { - if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) - { - assert_param(IS_RTC_HOUR12(RTC_TimeStruct->RTC_Hours)); - assert_param(IS_RTC_H12(RTC_TimeStruct->RTC_H12)); - } - else - { - RTC_TimeStruct->RTC_H12 = 0x00; - assert_param(IS_RTC_HOUR24(RTC_TimeStruct->RTC_Hours)); - } - assert_param(IS_RTC_MINUTES(RTC_TimeStruct->RTC_Minutes)); - assert_param(IS_RTC_SECONDS(RTC_TimeStruct->RTC_Seconds)); - } - else - { - if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) - { - tmpreg = RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours); - assert_param(IS_RTC_HOUR12(tmpreg)); - assert_param(IS_RTC_H12(RTC_TimeStruct->RTC_H12)); - } - else - { - RTC_TimeStruct->RTC_H12 = 0x00; - assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours))); - } - assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes))); - assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds))); - } - - /* Check the input parameters format */ - if (RTC_Format != RTC_Format_BIN) - { - tmpreg = (((uint32_t)(RTC_TimeStruct->RTC_Hours) << 16) | \ - ((uint32_t)(RTC_TimeStruct->RTC_Minutes) << 8) | \ - ((uint32_t)RTC_TimeStruct->RTC_Seconds) | \ - ((uint32_t)(RTC_TimeStruct->RTC_H12) << 16)); - } - else - { - tmpreg = (uint32_t)(((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Hours) << 16) | \ - ((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Minutes) << 8) | \ - ((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Seconds)) | \ - (((uint32_t)RTC_TimeStruct->RTC_H12) << 16)); - } - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Set Initialization mode */ - if (RTC_EnterInitMode() == ERROR) - { - status = ERROR; - } - else - { - /* Set the RTC_TR register */ - RTC->TR = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK); - - /* Exit Initialization mode */ - RTC_ExitInitMode(); - - if(RTC_WaitForSynchro() == ERROR) - { - status = ERROR; - } - else - { - status = SUCCESS; - } - - } - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @brief Fills each RTC_TimeStruct member with its default value - * (Time = 00h:00min:00sec). - * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure which will be - * initialized. - * @retval None - */ -void RTC_TimeStructInit(RTC_TimeTypeDef* RTC_TimeStruct) -{ - /* Time = 00h:00min:00sec */ - RTC_TimeStruct->RTC_H12 = RTC_H12_AM; - RTC_TimeStruct->RTC_Hours = 0; - RTC_TimeStruct->RTC_Minutes = 0; - RTC_TimeStruct->RTC_Seconds = 0; -} - -/** - * @brief Get the RTC current Time. - * @param RTC_Format: specifies the format of the returned parameters. - * This parameter can be one of the following values: - * @arg RTC_Format_BIN: Binary data format - * @arg RTC_Format_BCD: BCD data format - * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure that will - * contain the returned current time configuration. - * @retval None - */ -void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_FORMAT(RTC_Format)); - - /* Get the RTC_TR register */ - tmpreg = (uint32_t)(RTC->TR & RTC_TR_RESERVED_MASK); - - /* Fill the structure fields with the read parameters */ - RTC_TimeStruct->RTC_Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16); - RTC_TimeStruct->RTC_Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8); - RTC_TimeStruct->RTC_Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU)); - RTC_TimeStruct->RTC_H12 = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 16); - - /* Check the input parameters format */ - if (RTC_Format == RTC_Format_BIN) - { - /* Convert the structure parameters to Binary format */ - RTC_TimeStruct->RTC_Hours = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours); - RTC_TimeStruct->RTC_Minutes = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes); - RTC_TimeStruct->RTC_Seconds = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds); - } -} - -/** - * @brief Gets the RTC current Calendar Subseconds value. - * @note This function freeze the Time and Date registers after reading the - * SSR register. - * @param None - * @retval RTC current Calendar Subseconds value. - */ -uint32_t RTC_GetSubSecond(void) -{ - uint32_t tmpreg = 0; - - /* Get subseconds values from the correspondent registers*/ - tmpreg = (uint32_t)(RTC->SSR); - - /* Read DR register to unfroze calendar registers */ - (void) (RTC->DR); - - return (tmpreg); -} - -/** - * @brief Set the RTC current date. - * @param RTC_Format: specifies the format of the entered parameters. - * This parameter can be one of the following values: - * @arg RTC_Format_BIN: Binary data format - * @arg RTC_Format_BCD: BCD data format - * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure that contains - * the date configuration information for the RTC. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC Date register is configured - * - ERROR: RTC Date register is not configured - */ -ErrorStatus RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct) -{ - uint32_t tmpreg = 0; - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_RTC_FORMAT(RTC_Format)); - - if ((RTC_Format == RTC_Format_BIN) && ((RTC_DateStruct->RTC_Month & 0x10) == 0x10)) - { - RTC_DateStruct->RTC_Month = (RTC_DateStruct->RTC_Month & (uint32_t)~(0x10)) + 0x0A; - } - if (RTC_Format == RTC_Format_BIN) - { - assert_param(IS_RTC_YEAR(RTC_DateStruct->RTC_Year)); - assert_param(IS_RTC_MONTH(RTC_DateStruct->RTC_Month)); - assert_param(IS_RTC_DATE(RTC_DateStruct->RTC_Date)); - } - else - { - assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(RTC_DateStruct->RTC_Year))); - tmpreg = RTC_Bcd2ToByte(RTC_DateStruct->RTC_Month); - assert_param(IS_RTC_MONTH(tmpreg)); - tmpreg = RTC_Bcd2ToByte(RTC_DateStruct->RTC_Date); - assert_param(IS_RTC_DATE(tmpreg)); - } - assert_param(IS_RTC_WEEKDAY(RTC_DateStruct->RTC_WeekDay)); - - /* Check the input parameters format */ - if (RTC_Format != RTC_Format_BIN) - { - tmpreg = ((((uint32_t)RTC_DateStruct->RTC_Year) << 16) | \ - (((uint32_t)RTC_DateStruct->RTC_Month) << 8) | \ - ((uint32_t)RTC_DateStruct->RTC_Date) | \ - (((uint32_t)RTC_DateStruct->RTC_WeekDay) << 13)); - } - else - { - tmpreg = (((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Year) << 16) | \ - ((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Month) << 8) | \ - ((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Date)) | \ - ((uint32_t)RTC_DateStruct->RTC_WeekDay << 13)); - } - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Set Initialization mode */ - if (RTC_EnterInitMode() == ERROR) - { - status = ERROR; - } - else - { - /* Set the RTC_DR register */ - RTC->DR = (uint32_t)(tmpreg & RTC_DR_RESERVED_MASK); - - /* Exit Initialization mode */ - RTC_ExitInitMode(); - - if(RTC_WaitForSynchro() == ERROR) - { - status = ERROR; - } - else - { - status = SUCCESS; - } - } - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @brief Fills each RTC_DateStruct member with its default value - * (Monday, January 01 xx00). - * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure which will be - * initialized. - * @retval None - */ -void RTC_DateStructInit(RTC_DateTypeDef* RTC_DateStruct) -{ - /* Monday, January 01 xx00 */ - RTC_DateStruct->RTC_WeekDay = RTC_Weekday_Monday; - RTC_DateStruct->RTC_Date = 1; - RTC_DateStruct->RTC_Month = RTC_Month_January; - RTC_DateStruct->RTC_Year = 0; -} - -/** - * @brief Get the RTC current date. - * @param RTC_Format: specifies the format of the returned parameters. - * This parameter can be one of the following values: - * @arg RTC_Format_BIN: Binary data format - * @arg RTC_Format_BCD: BCD data format - * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure that will - * contain the returned current date configuration. - * @retval None - */ -void RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_FORMAT(RTC_Format)); - - /* Get the RTC_TR register */ - tmpreg = (uint32_t)(RTC->DR & RTC_DR_RESERVED_MASK); - - /* Fill the structure fields with the read parameters */ - RTC_DateStruct->RTC_Year = (uint8_t)((tmpreg & (RTC_DR_YT | RTC_DR_YU)) >> 16); - RTC_DateStruct->RTC_Month = (uint8_t)((tmpreg & (RTC_DR_MT | RTC_DR_MU)) >> 8); - RTC_DateStruct->RTC_Date = (uint8_t)(tmpreg & (RTC_DR_DT | RTC_DR_DU)); - RTC_DateStruct->RTC_WeekDay = (uint8_t)((tmpreg & (RTC_DR_WDU)) >> 13); - - /* Check the input parameters format */ - if (RTC_Format == RTC_Format_BIN) - { - /* Convert the structure parameters to Binary format */ - RTC_DateStruct->RTC_Year = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Year); - RTC_DateStruct->RTC_Month = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Month); - RTC_DateStruct->RTC_Date = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Date); - RTC_DateStruct->RTC_WeekDay = (uint8_t)(RTC_DateStruct->RTC_WeekDay); - } -} - -/** - * @} - */ - -/** @defgroup RTC_Group3 Alarms configuration functions - * @brief Alarms (Alarm A and Alarm B) configuration functions - * -@verbatim - =============================================================================== - Alarms (Alarm A and Alarm B) configuration functions - =============================================================================== - - This section provide functions allowing to program and read the RTC Alarms. - -@endverbatim - * @{ - */ - -/** - * @brief Set the specified RTC Alarm. - * @note The Alarm register can only be written when the corresponding Alarm - * is disabled (Use the RTC_AlarmCmd(DISABLE)). - * @param RTC_Format: specifies the format of the returned parameters. - * This parameter can be one of the following values: - * @arg RTC_Format_BIN: Binary data format - * @arg RTC_Format_BCD: BCD data format - * @param RTC_Alarm: specifies the alarm to be configured. - * This parameter can be one of the following values: - * @arg RTC_Alarm_A: to select Alarm A - * @arg RTC_Alarm_B: to select Alarm B - * @param RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that - * contains the alarm configuration parameters. - * @retval None - */ -void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_FORMAT(RTC_Format)); - assert_param(IS_RTC_ALARM(RTC_Alarm)); - assert_param(IS_ALARM_MASK(RTC_AlarmStruct->RTC_AlarmMask)); - assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel)); - - if (RTC_Format == RTC_Format_BIN) - { - if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) - { - assert_param(IS_RTC_HOUR12(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours)); - assert_param(IS_RTC_H12(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12)); - } - else - { - RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = 0x00; - assert_param(IS_RTC_HOUR24(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours)); - } - assert_param(IS_RTC_MINUTES(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes)); - assert_param(IS_RTC_SECONDS(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds)); - - if(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel == RTC_AlarmDateWeekDaySel_Date) - { - assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(RTC_AlarmStruct->RTC_AlarmDateWeekDay)); - } - else - { - assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(RTC_AlarmStruct->RTC_AlarmDateWeekDay)); - } - } - else - { - if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET) - { - tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours); - assert_param(IS_RTC_HOUR12(tmpreg)); - assert_param(IS_RTC_H12(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12)); - } - else - { - RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = 0x00; - assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours))); - } - - assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes))); - assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds))); - - if(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel == RTC_AlarmDateWeekDaySel_Date) - { - tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay); - assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(tmpreg)); - } - else - { - tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay); - assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(tmpreg)); - } - } - - /* Check the input parameters format */ - if (RTC_Format != RTC_Format_BIN) - { - tmpreg = (((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours) << 16) | \ - ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes) << 8) | \ - ((uint32_t)RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds) | \ - ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12) << 16) | \ - ((uint32_t)(RTC_AlarmStruct->RTC_AlarmDateWeekDay) << 24) | \ - ((uint32_t)RTC_AlarmStruct->RTC_AlarmDateWeekDaySel) | \ - ((uint32_t)RTC_AlarmStruct->RTC_AlarmMask)); - } - else - { - tmpreg = (((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours) << 16) | \ - ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes) << 8) | \ - ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds)) | \ - ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12) << 16) | \ - ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmDateWeekDay) << 24) | \ - ((uint32_t)RTC_AlarmStruct->RTC_AlarmDateWeekDaySel) | \ - ((uint32_t)RTC_AlarmStruct->RTC_AlarmMask)); - } - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Configure the Alarm register */ - if (RTC_Alarm == RTC_Alarm_A) - { - RTC->ALRMAR = (uint32_t)tmpreg; - } - else - { - RTC->ALRMBR = (uint32_t)tmpreg; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @brief Fills each RTC_AlarmStruct member with its default value - * (Time = 00h:00mn:00sec / Date = 1st day of the month/Mask = - * all fields are masked). - * @param RTC_AlarmStruct: pointer to a @ref RTC_AlarmTypeDef structure which - * will be initialized. - * @retval None - */ -void RTC_AlarmStructInit(RTC_AlarmTypeDef* RTC_AlarmStruct) -{ - /* Alarm Time Settings : Time = 00h:00mn:00sec */ - RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = RTC_H12_AM; - RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = 0; - RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = 0; - RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = 0; - - /* Alarm Date Settings : Date = 1st day of the month */ - RTC_AlarmStruct->RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date; - RTC_AlarmStruct->RTC_AlarmDateWeekDay = 1; - - /* Alarm Masks Settings : Mask = all fields are not masked */ - RTC_AlarmStruct->RTC_AlarmMask = RTC_AlarmMask_None; -} - -/** - * @brief Get the RTC Alarm value and masks. - * @param RTC_Format: specifies the format of the output parameters. - * This parameter can be one of the following values: - * @arg RTC_Format_BIN: Binary data format - * @arg RTC_Format_BCD: BCD data format - * @param RTC_Alarm: specifies the alarm to be read. - * This parameter can be one of the following values: - * @arg RTC_Alarm_A: to select Alarm A - * @arg RTC_Alarm_B: to select Alarm B - * @param RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that will - * contains the output alarm configuration values. - * @retval None - */ -void RTC_GetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_FORMAT(RTC_Format)); - assert_param(IS_RTC_ALARM(RTC_Alarm)); - - /* Get the RTC_ALRMxR register */ - if (RTC_Alarm == RTC_Alarm_A) - { - tmpreg = (uint32_t)(RTC->ALRMAR); - } - else - { - tmpreg = (uint32_t)(RTC->ALRMBR); - } - - /* Fill the structure with the read parameters */ - RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = (uint32_t)((tmpreg & (RTC_ALRMAR_HT | \ - RTC_ALRMAR_HU)) >> 16); - RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = (uint32_t)((tmpreg & (RTC_ALRMAR_MNT | \ - RTC_ALRMAR_MNU)) >> 8); - RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = (uint32_t)(tmpreg & (RTC_ALRMAR_ST | \ - RTC_ALRMAR_SU)); - RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = (uint32_t)((tmpreg & RTC_ALRMAR_PM) >> 16); - RTC_AlarmStruct->RTC_AlarmDateWeekDay = (uint32_t)((tmpreg & (RTC_ALRMAR_DT | RTC_ALRMAR_DU)) >> 24); - RTC_AlarmStruct->RTC_AlarmDateWeekDaySel = (uint32_t)(tmpreg & RTC_ALRMAR_WDSEL); - RTC_AlarmStruct->RTC_AlarmMask = (uint32_t)(tmpreg & RTC_AlarmMask_All); - - if (RTC_Format == RTC_Format_BIN) - { - RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = RTC_Bcd2ToByte(RTC_AlarmStruct-> \ - RTC_AlarmTime.RTC_Hours); - RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = RTC_Bcd2ToByte(RTC_AlarmStruct-> \ - RTC_AlarmTime.RTC_Minutes); - RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = RTC_Bcd2ToByte(RTC_AlarmStruct-> \ - RTC_AlarmTime.RTC_Seconds); - RTC_AlarmStruct->RTC_AlarmDateWeekDay = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay); - } -} - -/** - * @brief Enables or disables the specified RTC Alarm. - * @param RTC_Alarm: specifies the alarm to be configured. - * This parameter can be any combination of the following values: - * @arg RTC_Alarm_A: to select Alarm A - * @arg RTC_Alarm_B: to select Alarm B - * @param NewState: new state of the specified alarm. - * This parameter can be: ENABLE or DISABLE. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC Alarm is enabled/disabled - * - ERROR: RTC Alarm is not enabled/disabled - */ -ErrorStatus RTC_AlarmCmd(uint32_t RTC_Alarm, FunctionalState NewState) -{ - __IO uint32_t alarmcounter = 0x00; - uint32_t alarmstatus = 0x00; - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_RTC_CMD_ALARM(RTC_Alarm)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Configure the Alarm state */ - if (NewState != DISABLE) - { - RTC->CR |= (uint32_t)RTC_Alarm; - - status = SUCCESS; - } - else - { - /* Disable the Alarm in RTC_CR register */ - RTC->CR &= (uint32_t)~RTC_Alarm; - - /* Wait till RTC ALRxWF flag is set and if Time out is reached exit */ - do - { - alarmstatus = RTC->ISR & (RTC_Alarm >> 8); - alarmcounter++; - } while((alarmcounter != INITMODE_TIMEOUT) && (alarmstatus == 0x00)); - - if ((RTC->ISR & (RTC_Alarm >> 8)) == RESET) - { - status = ERROR; - } - else - { - status = SUCCESS; - } - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @brief Configure the RTC AlarmA/B Subseconds value and mask.* - * @note This function is performed only when the Alarm is disabled. - * @param RTC_Alarm: specifies the alarm to be configured. - * This parameter can be one of the following values: - * @arg RTC_Alarm_A: to select Alarm A - * @arg RTC_Alarm_B: to select Alarm B - * @param RTC_AlarmSubSecondValue: specifies the Subseconds value. - * This parameter can be a value from 0 to 0x00007FFF. - * @param RTC_AlarmSubSecondMask: specifies the Subseconds Mask. - * This parameter can be any combination of the following values: - * @arg RTC_AlarmSubSecondMask_All : All Alarm SS fields are masked. - * There is no comparison on sub seconds for Alarm. - * @arg RTC_AlarmSubSecondMask_SS14_1 : SS[14:1] are don't care in Alarm comparison. - * Only SS[0] is compared - * @arg RTC_AlarmSubSecondMask_SS14_2 : SS[14:2] are don't care in Alarm comparison. - * Only SS[1:0] are compared - * @arg RTC_AlarmSubSecondMask_SS14_3 : SS[14:3] are don't care in Alarm comparison. - * Only SS[2:0] are compared - * @arg RTC_AlarmSubSecondMask_SS14_4 : SS[14:4] are don't care in Alarm comparison. - * Only SS[3:0] are compared - * @arg RTC_AlarmSubSecondMask_SS14_5 : SS[14:5] are don't care in Alarm comparison. - * Only SS[4:0] are compared - * @arg RTC_AlarmSubSecondMask_SS14_6 : SS[14:6] are don't care in Alarm comparison. - * Only SS[5:0] are compared - * @arg RTC_AlarmSubSecondMask_SS14_7 : SS[14:7] are don't care in Alarm comparison. - * Only SS[6:0] are compared - * @arg RTC_AlarmSubSecondMask_SS14_8 : SS[14:8] are don't care in Alarm comparison. - * Only SS[7:0] are compared - * @arg RTC_AlarmSubSecondMask_SS14_9 : SS[14:9] are don't care in Alarm comparison. - * Only SS[8:0] are compared - * @arg RTC_AlarmSubSecondMask_SS14_10: SS[14:10] are don't care in Alarm comparison. - * Only SS[9:0] are compared - * @arg RTC_AlarmSubSecondMask_SS14_11: SS[14:11] are don't care in Alarm comparison. - * Only SS[10:0] are compared - * @arg RTC_AlarmSubSecondMask_SS14_12: SS[14:12] are don't care in Alarm comparison. - * Only SS[11:0] are compared - * @arg RTC_AlarmSubSecondMask_SS14_13: SS[14:13] are don't care in Alarm comparison. - * Only SS[12:0] are compared - * @arg RTC_AlarmSubSecondMask_SS14 : SS[14] is don't care in Alarm comparison. - * Only SS[13:0] are compared - * @arg RTC_AlarmSubSecondMask_None : SS[14:0] are compared and must match - * to activate alarm - * @retval None - */ -void RTC_AlarmSubSecondConfig(uint32_t RTC_Alarm, uint32_t RTC_AlarmSubSecondValue, uint32_t RTC_AlarmSubSecondMask) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_ALARM(RTC_Alarm)); - assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(RTC_AlarmSubSecondValue)); - assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(RTC_AlarmSubSecondMask)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Configure the Alarm A or Alarm B SubSecond registers */ - tmpreg = (uint32_t) (uint32_t)(RTC_AlarmSubSecondValue) | (uint32_t)(RTC_AlarmSubSecondMask); - - if (RTC_Alarm == RTC_Alarm_A) - { - /* Configure the AlarmA SubSecond register */ - RTC->ALRMASSR = tmpreg; - } - else - { - /* Configure the Alarm B SubSecond register */ - RTC->ALRMBSSR = tmpreg; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - -} - -/** - * @brief Gets the RTC Alarm Subseconds value. - * @param RTC_Alarm: specifies the alarm to be read. - * This parameter can be one of the following values: - * @arg RTC_Alarm_A: to select Alarm A - * @arg RTC_Alarm_B: to select Alarm B - * @param None - * @retval RTC Alarm Subseconds value. - */ -uint32_t RTC_GetAlarmSubSecond(uint32_t RTC_Alarm) -{ - uint32_t tmpreg = 0; - - /* Get the RTC_ALRMxR register */ - if (RTC_Alarm == RTC_Alarm_A) - { - tmpreg = (uint32_t)((RTC->ALRMASSR) & RTC_ALRMASSR_SS); - } - else - { - tmpreg = (uint32_t)((RTC->ALRMBSSR) & RTC_ALRMBSSR_SS); - } - - return (tmpreg); -} - -/** - * @} - */ - -/** @defgroup RTC_Group4 WakeUp Timer configuration functions - * @brief WakeUp Timer configuration functions - * -@verbatim - =============================================================================== - WakeUp Timer configuration functions - =============================================================================== - - This section provide functions allowing to program and read the RTC WakeUp. - -@endverbatim - * @{ - */ - -/** - * @brief Configures the RTC Wakeup clock source. - * @note The WakeUp Clock source can only be changed when the RTC WakeUp - * is disabled (Use the RTC_WakeUpCmd(DISABLE)). - * @param RTC_WakeUpClock: Wakeup Clock source. - * This parameter can be one of the following values: - * @arg RTC_WakeUpClock_RTCCLK_Div16: RTC Wakeup Counter Clock = RTCCLK/16 - * @arg RTC_WakeUpClock_RTCCLK_Div8: RTC Wakeup Counter Clock = RTCCLK/8 - * @arg RTC_WakeUpClock_RTCCLK_Div4: RTC Wakeup Counter Clock = RTCCLK/4 - * @arg RTC_WakeUpClock_RTCCLK_Div2: RTC Wakeup Counter Clock = RTCCLK/2 - * @arg RTC_WakeUpClock_CK_SPRE_16bits: RTC Wakeup Counter Clock = CK_SPRE - * @arg RTC_WakeUpClock_CK_SPRE_17bits: RTC Wakeup Counter Clock = CK_SPRE - * @retval None - */ -void RTC_WakeUpClockConfig(uint32_t RTC_WakeUpClock) -{ - /* Check the parameters */ - assert_param(IS_RTC_WAKEUP_CLOCK(RTC_WakeUpClock)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Clear the Wakeup Timer clock source bits in CR register */ - RTC->CR &= (uint32_t)~RTC_CR_WUCKSEL; - - /* Configure the clock source */ - RTC->CR |= (uint32_t)RTC_WakeUpClock; - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @brief Configures the RTC Wakeup counter. - * @note The RTC WakeUp counter can only be written when the RTC WakeUp - * is disabled (Use the RTC_WakeUpCmd(DISABLE)). - * @param RTC_WakeUpCounter: specifies the WakeUp counter. - * This parameter can be a value from 0x0000 to 0xFFFF. - * @retval None - */ -void RTC_SetWakeUpCounter(uint32_t RTC_WakeUpCounter) -{ - /* Check the parameters */ - assert_param(IS_RTC_WAKEUP_COUNTER(RTC_WakeUpCounter)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Configure the Wakeup Timer counter */ - RTC->WUTR = (uint32_t)RTC_WakeUpCounter; - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @brief Returns the RTC WakeUp timer counter value. - * @param None - * @retval The RTC WakeUp Counter value. - */ -uint32_t RTC_GetWakeUpCounter(void) -{ - /* Get the counter value */ - return ((uint32_t)(RTC->WUTR & RTC_WUTR_WUT)); -} - -/** - * @brief Enables or Disables the RTC WakeUp timer. - * @param NewState: new state of the WakeUp timer. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -ErrorStatus RTC_WakeUpCmd(FunctionalState NewState) -{ - __IO uint32_t wutcounter = 0x00; - uint32_t wutwfstatus = 0x00; - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - if (NewState != DISABLE) - { - /* Enable the Wakeup Timer */ - RTC->CR |= (uint32_t)RTC_CR_WUTE; - status = SUCCESS; - } - else - { - /* Disable the Wakeup Timer */ - RTC->CR &= (uint32_t)~RTC_CR_WUTE; - /* Wait till RTC WUTWF flag is set and if Time out is reached exit */ - do - { - wutwfstatus = RTC->ISR & RTC_ISR_WUTWF; - wutcounter++; - } while((wutcounter != INITMODE_TIMEOUT) && (wutwfstatus == 0x00)); - - if ((RTC->ISR & RTC_ISR_WUTWF) == RESET) - { - status = ERROR; - } - else - { - status = SUCCESS; - } - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @} - */ - -/** @defgroup RTC_Group5 Daylight Saving configuration functions - * @brief Daylight Saving configuration functions - * -@verbatim - =============================================================================== - Daylight Saving configuration functions - =============================================================================== - - This section provide functions allowing to configure the RTC DayLight Saving. - -@endverbatim - * @{ - */ - -/** - * @brief Adds or substract one hour from the current time. - * @param RTC_DayLightSaveOperation: the value of hour adjustment. - * This parameter can be one of the following values: - * @arg RTC_DayLightSaving_SUB1H: Substract one hour (winter time) - * @arg RTC_DayLightSaving_ADD1H: Add one hour (summer time) - * @param RTC_StoreOperation: Specifies the value to be written in the BCK bit - * in CR register to store the operation. - * This parameter can be one of the following values: - * @arg RTC_StoreOperation_Reset: BCK Bit Reset - * @arg RTC_StoreOperation_Set: BCK Bit Set - * @retval None - */ -void RTC_DayLightSavingConfig(uint32_t RTC_DayLightSaving, uint32_t RTC_StoreOperation) -{ - /* Check the parameters */ - assert_param(IS_RTC_DAYLIGHT_SAVING(RTC_DayLightSaving)); - assert_param(IS_RTC_STORE_OPERATION(RTC_StoreOperation)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Clear the bits to be configured */ - RTC->CR &= (uint32_t)~(RTC_CR_BCK); - - /* Configure the RTC_CR register */ - RTC->CR |= (uint32_t)(RTC_DayLightSaving | RTC_StoreOperation); - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @brief Returns the RTC Day Light Saving stored operation. - * @param None - * @retval RTC Day Light Saving stored operation. - * - RTC_StoreOperation_Reset - * - RTC_StoreOperation_Set - */ -uint32_t RTC_GetStoreOperation(void) -{ - return (RTC->CR & RTC_CR_BCK); -} - -/** - * @} - */ - -/** @defgroup RTC_Group6 Output pin Configuration function - * @brief Output pin Configuration function - * -@verbatim - =============================================================================== - Output pin Configuration function - =============================================================================== - - This section provide functions allowing to configure the RTC Output source. - -@endverbatim - * @{ - */ - -/** - * @brief Configures the RTC output source (AFO_ALARM). - * @param RTC_Output: Specifies which signal will be routed to the RTC output. - * This parameter can be one of the following values: - * @arg RTC_Output_Disable: No output selected - * @arg RTC_Output_AlarmA: signal of AlarmA mapped to output - * @arg RTC_Output_AlarmB: signal of AlarmB mapped to output - * @arg RTC_Output_WakeUp: signal of WakeUp mapped to output - * @param RTC_OutputPolarity: Specifies the polarity of the output signal. - * This parameter can be one of the following: - * @arg RTC_OutputPolarity_High: The output pin is high when the - * ALRAF/ALRBF/WUTF is high (depending on OSEL) - * @arg RTC_OutputPolarity_Low: The output pin is low when the - * ALRAF/ALRBF/WUTF is high (depending on OSEL) - * @retval None - */ -void RTC_OutputConfig(uint32_t RTC_Output, uint32_t RTC_OutputPolarity) -{ - /* Check the parameters */ - assert_param(IS_RTC_OUTPUT(RTC_Output)); - assert_param(IS_RTC_OUTPUT_POL(RTC_OutputPolarity)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Clear the bits to be configured */ - RTC->CR &= (uint32_t)~(RTC_CR_OSEL | RTC_CR_POL); - - /* Configure the output selection and polarity */ - RTC->CR |= (uint32_t)(RTC_Output | RTC_OutputPolarity); - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @} - */ - -/** @defgroup RTC_Group7 Digital Calibration configuration functions - * @brief Coarse Calibration configuration functions - * -@verbatim - =============================================================================== - Digital Calibration configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Configures the Coarse calibration parameters. - * @param RTC_CalibSign: specifies the sign of the coarse calibration value. - * This parameter can be one of the following values: - * @arg RTC_CalibSign_Positive: The value sign is positive - * @arg RTC_CalibSign_Negative: The value sign is negative - * @param Value: value of coarse calibration expressed in ppm (coded on 5 bits). - * - * @note This Calibration value should be between 0 and 63 when using negative - * sign with a 2-ppm step. - * - * @note This Calibration value should be between 0 and 126 when using positive - * sign with a 4-ppm step. - * - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC Coarse calibration are initialized - * - ERROR: RTC Coarse calibration are not initialized - */ -ErrorStatus RTC_CoarseCalibConfig(uint32_t RTC_CalibSign, uint32_t Value) -{ - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_RTC_CALIB_SIGN(RTC_CalibSign)); - assert_param(IS_RTC_CALIB_VALUE(Value)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Set Initialization mode */ - if (RTC_EnterInitMode() == ERROR) - { - status = ERROR; - } - else - { - /* Set the coarse calibration value */ - RTC->CALIBR = (uint32_t)(RTC_CalibSign | Value); - /* Exit Initialization mode */ - RTC_ExitInitMode(); - - status = SUCCESS; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @brief Enables or disables the Coarse calibration process. - * @param NewState: new state of the Coarse calibration. - * This parameter can be: ENABLE or DISABLE. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC Coarse calibration are enabled/disabled - * - ERROR: RTC Coarse calibration are not enabled/disabled - */ -ErrorStatus RTC_CoarseCalibCmd(FunctionalState NewState) -{ - ErrorStatus status = ERROR; - - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Set Initialization mode */ - if (RTC_EnterInitMode() == ERROR) - { - status = ERROR; - } - else - { - if (NewState != DISABLE) - { - /* Enable the Coarse Calibration */ - RTC->CR |= (uint32_t)RTC_CR_DCE; - } - else - { - /* Disable the Coarse Calibration */ - RTC->CR &= (uint32_t)~RTC_CR_DCE; - } - /* Exit Initialization mode */ - RTC_ExitInitMode(); - - status = SUCCESS; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return status; -} - -/** - * @brief Enables or disables the RTC clock to be output through the relative pin. - * @param NewState: new state of the digital calibration Output. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RTC_CalibOutputCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - if (NewState != DISABLE) - { - /* Enable the RTC clock output */ - RTC->CR |= (uint32_t)RTC_CR_COE; - } - else - { - /* Disable the RTC clock output */ - RTC->CR &= (uint32_t)~RTC_CR_COE; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @brief Configure the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz). - * @param RTC_CalibOutput : Select the Calibration output Selection . - * This parameter can be one of the following values: - * @arg RTC_CalibOutput_512Hz: A signal has a regular waveform at 512Hz. - * @arg RTC_CalibOutput_1Hz : A signal has a regular waveform at 1Hz. - * @retval None -*/ -void RTC_CalibOutputConfig(uint32_t RTC_CalibOutput) -{ - /* Check the parameters */ - assert_param(IS_RTC_CALIB_OUTPUT(RTC_CalibOutput)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /*clear flags before config*/ - RTC->CR &= (uint32_t)~(RTC_CR_COSEL); - - /* Configure the RTC_CR register */ - RTC->CR |= (uint32_t)RTC_CalibOutput; - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @brief Configures the Smooth Calibration Settings. - * @param RTC_SmoothCalibPeriod : Select the Smooth Calibration Period. - * This parameter can be can be one of the following values: - * @arg RTC_SmoothCalibPeriod_32sec : The smooth calibration periode is 32s. - * @arg RTC_SmoothCalibPeriod_16sec : The smooth calibration periode is 16s. - * @arg RTC_SmoothCalibPeriod_8sec : The smooth calibartion periode is 8s. - * @param RTC_SmoothCalibPlusPulses : Select to Set or reset the CALP bit. - * This parameter can be one of the following values: - * @arg RTC_SmoothCalibPlusPulses_Set : Add one RTCCLK puls every 2**11 pulses. - * @arg RTC_SmoothCalibPlusPulses_Reset: No RTCCLK pulses are added. - * @param RTC_SmouthCalibMinusPulsesValue: Select the value of CALM[8:0] bits. - * This parameter can be one any value from 0 to 0x000001FF. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC Calib registers are configured - * - ERROR: RTC Calib registers are not configured -*/ -ErrorStatus RTC_SmoothCalibConfig(uint32_t RTC_SmoothCalibPeriod, - uint32_t RTC_SmoothCalibPlusPulses, - uint32_t RTC_SmouthCalibMinusPulsesValue) -{ - ErrorStatus status = ERROR; - uint32_t recalpfcount = 0; - - /* Check the parameters */ - assert_param(IS_RTC_SMOOTH_CALIB_PERIOD(RTC_SmoothCalibPeriod)); - assert_param(IS_RTC_SMOOTH_CALIB_PLUS(RTC_SmoothCalibPlusPulses)); - assert_param(IS_RTC_SMOOTH_CALIB_MINUS(RTC_SmouthCalibMinusPulsesValue)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* check if a calibration is pending*/ - if ((RTC->ISR & RTC_ISR_RECALPF) != RESET) - { - /* wait until the Calibration is completed*/ - while (((RTC->ISR & RTC_ISR_RECALPF) != RESET) && (recalpfcount != RECALPF_TIMEOUT)) - { - recalpfcount++; - } - } - - /* check if the calibration pending is completed or if there is no calibration operation at all*/ - if ((RTC->ISR & RTC_ISR_RECALPF) == RESET) - { - /* Configure the Smooth calibration settings */ - RTC->CALR = (uint32_t)((uint32_t)RTC_SmoothCalibPeriod | (uint32_t)RTC_SmoothCalibPlusPulses | (uint32_t)RTC_SmouthCalibMinusPulsesValue); - - status = SUCCESS; - } - else - { - status = ERROR; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return (ErrorStatus)(status); -} - -/** - * @} - */ - - -/** @defgroup RTC_Group8 TimeStamp configuration functions - * @brief TimeStamp configuration functions - * -@verbatim - =============================================================================== - TimeStamp configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or Disables the RTC TimeStamp functionality with the - * specified time stamp pin stimulating edge. - * @param RTC_TimeStampEdge: Specifies the pin edge on which the TimeStamp is - * activated. - * This parameter can be one of the following: - * @arg RTC_TimeStampEdge_Rising: the Time stamp event occurs on the rising - * edge of the related pin. - * @arg RTC_TimeStampEdge_Falling: the Time stamp event occurs on the - * falling edge of the related pin. - * @param NewState: new state of the TimeStamp. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RTC_TimeStampCmd(uint32_t RTC_TimeStampEdge, FunctionalState NewState) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_TIMESTAMP_EDGE(RTC_TimeStampEdge)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Get the RTC_CR register and clear the bits to be configured */ - tmpreg = (uint32_t)(RTC->CR & (uint32_t)~(RTC_CR_TSEDGE | RTC_CR_TSE)); - - /* Get the new configuration */ - if (NewState != DISABLE) - { - tmpreg |= (uint32_t)(RTC_TimeStampEdge | RTC_CR_TSE); - } - else - { - tmpreg |= (uint32_t)(RTC_TimeStampEdge); - } - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Configure the Time Stamp TSEDGE and Enable bits */ - RTC->CR = (uint32_t)tmpreg; - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @brief Get the RTC TimeStamp value and masks. - * @param RTC_Format: specifies the format of the output parameters. - * This parameter can be one of the following values: - * @arg RTC_Format_BIN: Binary data format - * @arg RTC_Format_BCD: BCD data format - * @param RTC_StampTimeStruct: pointer to a RTC_TimeTypeDef structure that will - * contains the TimeStamp time values. - * @param RTC_StampDateStruct: pointer to a RTC_DateTypeDef structure that will - * contains the TimeStamp date values. - * @retval None - */ -void RTC_GetTimeStamp(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_StampTimeStruct, - RTC_DateTypeDef* RTC_StampDateStruct) -{ - uint32_t tmptime = 0, tmpdate = 0; - - /* Check the parameters */ - assert_param(IS_RTC_FORMAT(RTC_Format)); - - /* Get the TimeStamp time and date registers values */ - tmptime = (uint32_t)(RTC->TSTR & RTC_TR_RESERVED_MASK); - tmpdate = (uint32_t)(RTC->TSDR & RTC_DR_RESERVED_MASK); - - /* Fill the Time structure fields with the read parameters */ - RTC_StampTimeStruct->RTC_Hours = (uint8_t)((tmptime & (RTC_TR_HT | RTC_TR_HU)) >> 16); - RTC_StampTimeStruct->RTC_Minutes = (uint8_t)((tmptime & (RTC_TR_MNT | RTC_TR_MNU)) >> 8); - RTC_StampTimeStruct->RTC_Seconds = (uint8_t)(tmptime & (RTC_TR_ST | RTC_TR_SU)); - RTC_StampTimeStruct->RTC_H12 = (uint8_t)((tmptime & (RTC_TR_PM)) >> 16); - - /* Fill the Date structure fields with the read parameters */ - RTC_StampDateStruct->RTC_Year = 0; - RTC_StampDateStruct->RTC_Month = (uint8_t)((tmpdate & (RTC_DR_MT | RTC_DR_MU)) >> 8); - RTC_StampDateStruct->RTC_Date = (uint8_t)(tmpdate & (RTC_DR_DT | RTC_DR_DU)); - RTC_StampDateStruct->RTC_WeekDay = (uint8_t)((tmpdate & (RTC_DR_WDU)) >> 13); - - /* Check the input parameters format */ - if (RTC_Format == RTC_Format_BIN) - { - /* Convert the Time structure parameters to Binary format */ - RTC_StampTimeStruct->RTC_Hours = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Hours); - RTC_StampTimeStruct->RTC_Minutes = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Minutes); - RTC_StampTimeStruct->RTC_Seconds = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Seconds); - - /* Convert the Date structure parameters to Binary format */ - RTC_StampDateStruct->RTC_Month = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_Month); - RTC_StampDateStruct->RTC_Date = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_Date); - RTC_StampDateStruct->RTC_WeekDay = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_WeekDay); - } -} - -/** - * @brief Get the RTC timestamp Subseconds value. - * @param None - * @retval RTC current timestamp Subseconds value. - */ -uint32_t RTC_GetTimeStampSubSecond(void) -{ - /* Get timestamp subseconds values from the correspondent registers */ - return (uint32_t)(RTC->TSSSR); -} - -/** - * @} - */ - -/** @defgroup RTC_Group9 Tampers configuration functions - * @brief Tampers configuration functions - * -@verbatim - =============================================================================== - Tampers configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Configures the select Tamper pin edge. - * @param RTC_Tamper: Selected tamper pin. - * This parameter can be RTC_Tamper_1. - * @param RTC_TamperTrigger: Specifies the trigger on the tamper pin that - * stimulates tamper event. - * This parameter can be one of the following values: - * @arg RTC_TamperTrigger_RisingEdge: Rising Edge of the tamper pin causes tamper event. - * @arg RTC_TamperTrigger_FallingEdge: Falling Edge of the tamper pin causes tamper event. - * @arg RTC_TamperTrigger_LowLevel: Low Level of the tamper pin causes tamper event. - * @arg RTC_TamperTrigger_HighLevel: High Level of the tamper pin causes tamper event. - * @retval None - */ -void RTC_TamperTriggerConfig(uint32_t RTC_Tamper, uint32_t RTC_TamperTrigger) -{ - /* Check the parameters */ - assert_param(IS_RTC_TAMPER(RTC_Tamper)); - assert_param(IS_RTC_TAMPER_TRIGGER(RTC_TamperTrigger)); - - if (RTC_TamperTrigger == RTC_TamperTrigger_RisingEdge) - { - /* Configure the RTC_TAFCR register */ - RTC->TAFCR &= (uint32_t)((uint32_t)~(RTC_Tamper << 1)); - } - else - { - /* Configure the RTC_TAFCR register */ - RTC->TAFCR |= (uint32_t)(RTC_Tamper << 1); - } -} - -/** - * @brief Enables or Disables the Tamper detection. - * @param RTC_Tamper: Selected tamper pin. - * This parameter can be RTC_Tamper_1. - * @param NewState: new state of the tamper pin. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RTC_TamperCmd(uint32_t RTC_Tamper, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RTC_TAMPER(RTC_Tamper)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected Tamper pin */ - RTC->TAFCR |= (uint32_t)RTC_Tamper; - } - else - { - /* Disable the selected Tamper pin */ - RTC->TAFCR &= (uint32_t)~RTC_Tamper; - } -} - -/** - * @brief Configures the Tampers Filter. - * @param RTC_TamperFilter: Specifies the tampers filter. - * This parameter can be one of the following values: - * @arg RTC_TamperFilter_Disable: Tamper filter is disabled. - * @arg RTC_TamperFilter_2Sample: Tamper is activated after 2 consecutive - * samples at the active level - * @arg RTC_TamperFilter_4Sample: Tamper is activated after 4 consecutive - * samples at the active level - * @arg RTC_TamperFilter_8Sample: Tamper is activated after 8 consecutive - * samples at the active level - * @retval None - */ -void RTC_TamperFilterConfig(uint32_t RTC_TamperFilter) -{ - /* Check the parameters */ - assert_param(IS_RTC_TAMPER_FILTER(RTC_TamperFilter)); - - /* Clear TAMPFLT[1:0] bits in the RTC_TAFCR register */ - RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPFLT); - - /* Configure the RTC_TAFCR register */ - RTC->TAFCR |= (uint32_t)RTC_TamperFilter; -} - -/** - * @brief Configures the Tampers Sampling Frequency. - * @param RTC_TamperSamplingFreq: Specifies the tampers Sampling Frequency. - * This parameter can be one of the following values: - * @arg RTC_TamperSamplingFreq_RTCCLK_Div32768: Each of the tamper inputs are sampled - * with a frequency = RTCCLK / 32768 - * @arg RTC_TamperSamplingFreq_RTCCLK_Div16384: Each of the tamper inputs are sampled - * with a frequency = RTCCLK / 16384 - * @arg RTC_TamperSamplingFreq_RTCCLK_Div8192: Each of the tamper inputs are sampled - * with a frequency = RTCCLK / 8192 - * @arg RTC_TamperSamplingFreq_RTCCLK_Div4096: Each of the tamper inputs are sampled - * with a frequency = RTCCLK / 4096 - * @arg RTC_TamperSamplingFreq_RTCCLK_Div2048: Each of the tamper inputs are sampled - * with a frequency = RTCCLK / 2048 - * @arg RTC_TamperSamplingFreq_RTCCLK_Div1024: Each of the tamper inputs are sampled - * with a frequency = RTCCLK / 1024 - * @arg RTC_TamperSamplingFreq_RTCCLK_Div512: Each of the tamper inputs are sampled - * with a frequency = RTCCLK / 512 - * @arg RTC_TamperSamplingFreq_RTCCLK_Div256: Each of the tamper inputs are sampled - * with a frequency = RTCCLK / 256 - * @retval None - */ -void RTC_TamperSamplingFreqConfig(uint32_t RTC_TamperSamplingFreq) -{ - /* Check the parameters */ - assert_param(IS_RTC_TAMPER_SAMPLING_FREQ(RTC_TamperSamplingFreq)); - - /* Clear TAMPFREQ[2:0] bits in the RTC_TAFCR register */ - RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPFREQ); - - /* Configure the RTC_TAFCR register */ - RTC->TAFCR |= (uint32_t)RTC_TamperSamplingFreq; -} - -/** - * @brief Configures the Tampers Pins input Precharge Duration. - * @param RTC_TamperPrechargeDuration: Specifies the Tampers Pins input - * Precharge Duration. - * This parameter can be one of the following values: - * @arg RTC_TamperPrechargeDuration_1RTCCLK: Tamper pins are pre-charged before sampling during 1 RTCCLK cycle - * @arg RTC_TamperPrechargeDuration_2RTCCLK: Tamper pins are pre-charged before sampling during 2 RTCCLK cycle - * @arg RTC_TamperPrechargeDuration_4RTCCLK: Tamper pins are pre-charged before sampling during 4 RTCCLK cycle - * @arg RTC_TamperPrechargeDuration_8RTCCLK: Tamper pins are pre-charged before sampling during 8 RTCCLK cycle - * @retval None - */ -void RTC_TamperPinsPrechargeDuration(uint32_t RTC_TamperPrechargeDuration) -{ - /* Check the parameters */ - assert_param(IS_RTC_TAMPER_PRECHARGE_DURATION(RTC_TamperPrechargeDuration)); - - /* Clear TAMPPRCH[1:0] bits in the RTC_TAFCR register */ - RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPPRCH); - - /* Configure the RTC_TAFCR register */ - RTC->TAFCR |= (uint32_t)RTC_TamperPrechargeDuration; -} - -/** - * @brief Enables or Disables the TimeStamp on Tamper Detection Event. - * @note The timestamp is valid even the TSE bit in tamper control register - * is reset. - * @param NewState: new state of the timestamp on tamper event. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RTC_TimeStampOnTamperDetectionCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Save timestamp on tamper detection event */ - RTC->TAFCR |= (uint32_t)RTC_TAFCR_TAMPTS; - } - else - { - /* Tamper detection does not cause a timestamp to be saved */ - RTC->TAFCR &= (uint32_t)~RTC_TAFCR_TAMPTS; - } -} - -/** - * @brief Enables or Disables the Precharge of Tamper pin. - * @param NewState: new state of tamper pull up. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RTC_TamperPullUpCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable precharge of the selected Tamper pin */ - RTC->TAFCR &= (uint32_t)~RTC_TAFCR_TAMPPUDIS; - } - else - { - /* Disable precharge of the selected Tamper pin */ - RTC->TAFCR |= (uint32_t)RTC_TAFCR_TAMPPUDIS; - } -} - -/** - * @} - */ - -/** @defgroup RTC_Group10 Backup Data Registers configuration functions - * @brief Backup Data Registers configuration functions - * -@verbatim - =============================================================================== - Backup Data Registers configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Writes a data in a specified RTC Backup data register. - * @param RTC_BKP_DR: RTC Backup data Register number. - * This parameter can be: RTC_BKP_DRx where x can be from 0 to 19 to - * specify the register. - * @param Data: Data to be written in the specified RTC Backup data register. - * @retval None - */ -void RTC_WriteBackupRegister(uint32_t RTC_BKP_DR, uint32_t Data) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_RTC_BKP(RTC_BKP_DR)); - - tmp = RTC_BASE + 0x50; - tmp += (RTC_BKP_DR * 4); - - /* Write the specified register */ - *(__IO uint32_t *)tmp = (uint32_t)Data; -} - -/** - * @brief Reads data from the specified RTC Backup data Register. - * @param RTC_BKP_DR: RTC Backup data Register number. - * This parameter can be: RTC_BKP_DRx where x can be from 0 to 19 to - * specify the register. - * @retval None - */ -uint32_t RTC_ReadBackupRegister(uint32_t RTC_BKP_DR) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_RTC_BKP(RTC_BKP_DR)); - - tmp = RTC_BASE + 0x50; - tmp += (RTC_BKP_DR * 4); - - /* Read the specified register */ - return (*(__IO uint32_t *)tmp); -} - -/** - * @} - */ - -/** @defgroup RTC_Group11 RTC Tamper and TimeStamp Pins Selection and Output Type Config configuration functions - * @brief RTC Tamper and TimeStamp Pins Selection and Output Type Config - * configuration functions - * -@verbatim - =============================================================================== - RTC Tamper and TimeStamp Pins Selection and Output Type Config configuration - functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Selects the RTC Tamper Pin. - * @param RTC_TamperPin: specifies the RTC Tamper Pin. - * This parameter can be one of the following values: - * @arg RTC_TamperPin_PC13: PC13 is selected as RTC Tamper Pin. - * @arg RTC_TamperPin_PI8: PI8 is selected as RTC Tamper Pin. - * @retval None - */ -void RTC_TamperPinSelection(uint32_t RTC_TamperPin) -{ - /* Check the parameters */ - assert_param(IS_RTC_TAMPER_PIN(RTC_TamperPin)); - - RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPINSEL); - RTC->TAFCR |= (uint32_t)(RTC_TamperPin); -} - -/** - * @brief Selects the RTC TimeStamp Pin. - * @param RTC_TimeStampPin: specifies the RTC TimeStamp Pin. - * This parameter can be one of the following values: - * @arg RTC_TimeStampPin_PC13: PC13 is selected as RTC TimeStamp Pin. - * @arg RTC_TimeStampPin_PI8: PI8 is selected as RTC TimeStamp Pin. - * @retval None - */ -void RTC_TimeStampPinSelection(uint32_t RTC_TimeStampPin) -{ - /* Check the parameters */ - assert_param(IS_RTC_TIMESTAMP_PIN(RTC_TimeStampPin)); - - RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TSINSEL); - RTC->TAFCR |= (uint32_t)(RTC_TimeStampPin); -} - -/** - * @brief Configures the RTC Output Pin mode. - * @param RTC_OutputType: specifies the RTC Output (PC13) pin mode. - * This parameter can be one of the following values: - * @arg RTC_OutputType_OpenDrain: RTC Output (PC13) is configured in - * Open Drain mode. - * @arg RTC_OutputType_PushPull: RTC Output (PC13) is configured in - * Push Pull mode. - * @retval None - */ -void RTC_OutputTypeConfig(uint32_t RTC_OutputType) -{ - /* Check the parameters */ - assert_param(IS_RTC_OUTPUT_TYPE(RTC_OutputType)); - - RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_ALARMOUTTYPE); - RTC->TAFCR |= (uint32_t)(RTC_OutputType); -} - -/** - * @} - */ - -/** @defgroup RTC_Group12 Shift control synchronisation functions - * @brief Shift control synchronisation functions - * -@verbatim - =============================================================================== - Shift control synchronisation functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Configures the Synchronization Shift Control Settings. - * @note When REFCKON is set, firmware must not write to Shift control register - * @param RTC_ShiftAdd1S : Select to add or not 1 second to the time Calendar. - * This parameter can be one of the following values : - * @arg RTC_ShiftAdd1S_Set : Add one second to the clock calendar. - * @arg RTC_ShiftAdd1S_Reset: No effect. - * @param RTC_ShiftSubFS: Select the number of Second Fractions to Substitute. - * This parameter can be one any value from 0 to 0x7FFF. - * @retval An ErrorStatus enumeration value: - * - SUCCESS: RTC Shift registers are configured - * - ERROR: RTC Shift registers are not configured -*/ -ErrorStatus RTC_SynchroShiftConfig(uint32_t RTC_ShiftAdd1S, uint32_t RTC_ShiftSubFS) -{ - ErrorStatus status = ERROR; - uint32_t shpfcount = 0; - - /* Check the parameters */ - assert_param(IS_RTC_SHIFT_ADD1S(RTC_ShiftAdd1S)); - assert_param(IS_RTC_SHIFT_SUBFS(RTC_ShiftSubFS)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - /* Check if a Shift is pending*/ - if ((RTC->ISR & RTC_ISR_SHPF) != RESET) - { - /* Wait until the shift is completed*/ - while (((RTC->ISR & RTC_ISR_SHPF) != RESET) && (shpfcount != SHPF_TIMEOUT)) - { - shpfcount++; - } - } - - /* Check if the Shift pending is completed or if there is no Shift operation at all*/ - if ((RTC->ISR & RTC_ISR_SHPF) == RESET) - { - /* check if the reference clock detection is disabled */ - if((RTC->CR & RTC_CR_REFCKON) == RESET) - { - /* Configure the Shift settings */ - RTC->SHIFTR = (uint32_t)(uint32_t)(RTC_ShiftSubFS) | (uint32_t)(RTC_ShiftAdd1S); - - if(RTC_WaitForSynchro() == ERROR) - { - status = ERROR; - } - else - { - status = SUCCESS; - } - } - else - { - status = ERROR; - } - } - else - { - status = ERROR; - } - - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; - - return (ErrorStatus)(status); -} - -/** - * @} - */ - -/** @defgroup RTC_Group13 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - All RTC interrupts are connected to the EXTI controller. - - - To enable the RTC Alarm interrupt, the following sequence is required: - - Configure and enable the EXTI Line 17 in interrupt mode and select the rising - edge sensitivity using the EXTI_Init() function. - - Configure and enable the RTC_Alarm IRQ channel in the NVIC using the NVIC_Init() - function. - - Configure the RTC to generate RTC alarms (Alarm A and/or Alarm B) using - the RTC_SetAlarm() and RTC_AlarmCmd() functions. - - - To enable the RTC Wakeup interrupt, the following sequence is required: - - Configure and enable the EXTI Line 22 in interrupt mode and select the rising - edge sensitivity using the EXTI_Init() function. - - Configure and enable the RTC_WKUP IRQ channel in the NVIC using the NVIC_Init() - function. - - Configure the RTC to generate the RTC wakeup timer event using the - RTC_WakeUpClockConfig(), RTC_SetWakeUpCounter() and RTC_WakeUpCmd() functions. - - - To enable the RTC Tamper interrupt, the following sequence is required: - - Configure and enable the EXTI Line 21 in interrupt mode and select the rising - edge sensitivity using the EXTI_Init() function. - - Configure and enable the TAMP_STAMP IRQ channel in the NVIC using the NVIC_Init() - function. - - Configure the RTC to detect the RTC tamper event using the - RTC_TamperTriggerConfig() and RTC_TamperCmd() functions. - - - To enable the RTC TimeStamp interrupt, the following sequence is required: - - Configure and enable the EXTI Line 21 in interrupt mode and select the rising - edge sensitivity using the EXTI_Init() function. - - Configure and enable the TAMP_STAMP IRQ channel in the NVIC using the NVIC_Init() - function. - - Configure the RTC to detect the RTC time-stamp event using the - RTC_TimeStampCmd() functions. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified RTC interrupts. - * @param RTC_IT: specifies the RTC interrupt sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg RTC_IT_TS: Time Stamp interrupt mask - * @arg RTC_IT_WUT: WakeUp Timer interrupt mask - * @arg RTC_IT_ALRB: Alarm B interrupt mask - * @arg RTC_IT_ALRA: Alarm A interrupt mask - * @arg RTC_IT_TAMP: Tamper event interrupt mask - * @param NewState: new state of the specified RTC interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_RTC_CONFIG_IT(RTC_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* Disable the write protection for RTC registers */ - RTC->WPR = 0xCA; - RTC->WPR = 0x53; - - if (NewState != DISABLE) - { - /* Configure the Interrupts in the RTC_CR register */ - RTC->CR |= (uint32_t)(RTC_IT & ~RTC_TAFCR_TAMPIE); - /* Configure the Tamper Interrupt in the RTC_TAFCR */ - RTC->TAFCR |= (uint32_t)(RTC_IT & RTC_TAFCR_TAMPIE); - } - else - { - /* Configure the Interrupts in the RTC_CR register */ - RTC->CR &= (uint32_t)~(RTC_IT & (uint32_t)~RTC_TAFCR_TAMPIE); - /* Configure the Tamper Interrupt in the RTC_TAFCR */ - RTC->TAFCR &= (uint32_t)~(RTC_IT & RTC_TAFCR_TAMPIE); - } - /* Enable the write protection for RTC registers */ - RTC->WPR = 0xFF; -} - -/** - * @brief Checks whether the specified RTC flag is set or not. - * @param RTC_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg RTC_FLAG_TAMP1F: Tamper 1 event flag - * @arg RTC_FLAG_TSOVF: Time Stamp OverFlow flag - * @arg RTC_FLAG_TSF: Time Stamp event flag - * @arg RTC_FLAG_WUTF: WakeUp Timer flag - * @arg RTC_FLAG_ALRBF: Alarm B flag - * @arg RTC_FLAG_ALRAF: Alarm A flag - * @arg RTC_FLAG_INITF: Initialization mode flag - * @arg RTC_FLAG_RSF: Registers Synchronized flag - * @arg RTC_FLAG_INITS: Registers Configured flag - * @arg RTC_FLAG_WUTWF: WakeUp Timer Write flag - * @arg RTC_FLAG_ALRBWF: Alarm B Write flag - * @arg RTC_FLAG_ALRAWF: Alarm A write flag - * @retval The new state of RTC_FLAG (SET or RESET). - */ -FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG) -{ - FlagStatus bitstatus = RESET; - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_GET_FLAG(RTC_FLAG)); - - /* Get all the flags */ - tmpreg = (uint32_t)(RTC->ISR & RTC_FLAGS_MASK); - - /* Return the status of the flag */ - if ((tmpreg & RTC_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the RTC's pending flags. - * @param RTC_FLAG: specifies the RTC flag to clear. - * This parameter can be any combination of the following values: - * @arg RTC_FLAG_TAMP1F: Tamper 1 event flag - * @arg RTC_FLAG_TSOVF: Time Stamp Overflow flag - * @arg RTC_FLAG_TSF: Time Stamp event flag - * @arg RTC_FLAG_WUTF: WakeUp Timer flag - * @arg RTC_FLAG_ALRBF: Alarm B flag - * @arg RTC_FLAG_ALRAF: Alarm A flag - * @arg RTC_FLAG_RSF: Registers Synchronized flag - * @retval None - */ -void RTC_ClearFlag(uint32_t RTC_FLAG) -{ - /* Check the parameters */ - assert_param(IS_RTC_CLEAR_FLAG(RTC_FLAG)); - - /* Clear the Flags in the RTC_ISR register */ - RTC->ISR = (uint32_t)((uint32_t)(~((RTC_FLAG | RTC_ISR_INIT)& 0x0000FFFF) | (uint32_t)(RTC->ISR & RTC_ISR_INIT))); -} - -/** - * @brief Checks whether the specified RTC interrupt has occurred or not. - * @param RTC_IT: specifies the RTC interrupt source to check. - * This parameter can be one of the following values: - * @arg RTC_IT_TS: Time Stamp interrupt - * @arg RTC_IT_WUT: WakeUp Timer interrupt - * @arg RTC_IT_ALRB: Alarm B interrupt - * @arg RTC_IT_ALRA: Alarm A interrupt - * @arg RTC_IT_TAMP1: Tamper 1 event interrupt - * @retval The new state of RTC_IT (SET or RESET). - */ -ITStatus RTC_GetITStatus(uint32_t RTC_IT) -{ - ITStatus bitstatus = RESET; - uint32_t tmpreg = 0, enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_RTC_GET_IT(RTC_IT)); - - /* Get the TAMPER Interrupt enable bit and pending bit */ - tmpreg = (uint32_t)(RTC->TAFCR & (RTC_TAFCR_TAMPIE)); - - /* Get the Interrupt enable Status */ - enablestatus = (uint32_t)((RTC->CR & RTC_IT) | (tmpreg & (RTC_IT >> 15))); - - /* Get the Interrupt pending bit */ - tmpreg = (uint32_t)((RTC->ISR & (uint32_t)(RTC_IT >> 4))); - - /* Get the status of the Interrupt */ - if ((enablestatus != (uint32_t)RESET) && ((tmpreg & 0x0000FFFF) != (uint32_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the RTC's interrupt pending bits. - * @param RTC_IT: specifies the RTC interrupt pending bit to clear. - * This parameter can be any combination of the following values: - * @arg RTC_IT_TS: Time Stamp interrupt - * @arg RTC_IT_WUT: WakeUp Timer interrupt - * @arg RTC_IT_ALRB: Alarm B interrupt - * @arg RTC_IT_ALRA: Alarm A interrupt - * @arg RTC_IT_TAMP1: Tamper 1 event interrupt - * @retval None - */ -void RTC_ClearITPendingBit(uint32_t RTC_IT) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_RTC_CLEAR_IT(RTC_IT)); - - /* Get the RTC_ISR Interrupt pending bits mask */ - tmpreg = (uint32_t)(RTC_IT >> 4); - - /* Clear the interrupt pending bits in the RTC_ISR register */ - RTC->ISR = (uint32_t)((uint32_t)(~((tmpreg | RTC_ISR_INIT)& 0x0000FFFF) | (uint32_t)(RTC->ISR & RTC_ISR_INIT))); -} - -/** - * @} - */ - -/** - * @brief Converts a 2 digit decimal to BCD format. - * @param Value: Byte to be converted. - * @retval Converted byte - */ -static uint8_t RTC_ByteToBcd2(uint8_t Value) -{ - uint8_t bcdhigh = 0; - - while (Value >= 10) - { - bcdhigh++; - Value -= 10; - } - - return ((uint8_t)(bcdhigh << 4) | Value); -} - -/** - * @brief Convert from 2 digit BCD to Binary. - * @param Value: BCD value to be converted. - * @retval Converted word - */ -static uint8_t RTC_Bcd2ToByte(uint8_t Value) -{ - uint8_t tmp = 0; - tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10; - return (tmp + (Value & (uint8_t)0x0F)); -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_sdio.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_sdio.c deleted file mode 100644 index 9984cea30..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_sdio.c +++ /dev/null @@ -1,1004 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_sdio.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the Secure digital input/output interface (SDIO) - * peripheral: - * - Initialization and Configuration - * - Command path state machine (CPSM) management - * - Data path state machine (DPSM) management - * - SDIO IO Cards mode management - * - CE-ATA mode management - * - DMA transfers management - * - Interrupts and flags management - * - * @verbatim - * - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. The SDIO clock (SDIOCLK = 48 MHz) is coming from a specific output - * of PLL (PLL48CLK). Before to start working with SDIO peripheral - * make sure that the PLL is well configured. - * The SDIO peripheral uses two clock signals: - * - SDIO adapter clock (SDIOCLK = 48 MHz) - * - APB2 bus clock (PCLK2) - * PCLK2 and SDIO_CK clock frequencies must respect the following condition: - * Frequenc(PCLK2) >= (3 / 8 x Frequency(SDIO_CK)) - * - * 2. Enable peripheral clock using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, ENABLE). - * - * 3. According to the SDIO mode, enable the GPIO clocks using - * RCC_AHB1PeriphClockCmd() function. - * The I/O can be one of the following configurations: - * - 1-bit data length: SDIO_CMD, SDIO_CK and D0. - * - 4-bit data length: SDIO_CMD, SDIO_CK and D[3:0]. - * - 8-bit data length: SDIO_CMD, SDIO_CK and D[7:0]. - * - * 4. Peripheral's alternate function: - * - Connect the pin to the desired peripherals' Alternate - * Function (AF) using GPIO_PinAFConfig() function - * - Configure the desired pin in alternate function by: - * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF - * - Select the type, pull-up/pull-down and output speed via - * GPIO_PuPd, GPIO_OType and GPIO_Speed members - * - Call GPIO_Init() function - * - * 5. Program the Clock Edge, Clock Bypass, Clock Power Save, Bus Wide, - * hardware, flow control and the Clock Divider using the SDIO_Init() - * function. - * - * 6. Enable the Power ON State using the SDIO_SetPowerState(SDIO_PowerState_ON) - * function. - * - * 7. Enable the clock using the SDIO_ClockCmd() function. - * - * 8. Enable the NVIC and the corresponding interrupt using the function - * SDIO_ITConfig() if you need to use interrupt mode. - * - * 9. When using the DMA mode - * - Configure the DMA using DMA_Init() function - * - Active the needed channel Request using SDIO_DMACmd() function - * - * 10. Enable the DMA using the DMA_Cmd() function, when using DMA mode. - * - * 11. To control the CPSM (Command Path State Machine) and send - * commands to the card use the SDIO_SendCommand(), - * SDIO_GetCommandResponse() and SDIO_GetResponse() functions. - * First, user has to fill the command structure (pointer to - * SDIO_CmdInitTypeDef) according to the selected command to be sent. - * The parameters that should be filled are: - * - Command Argument - * - Command Index - * - Command Response type - * - Command Wait - * - CPSM Status (Enable or Disable) - * - * To check if the command is well received, read the SDIO_CMDRESP - * register using the SDIO_GetCommandResponse(). - * The SDIO responses registers (SDIO_RESP1 to SDIO_RESP2), use the - * SDIO_GetResponse() function. - * - * 12. To control the DPSM (Data Path State Machine) and send/receive - * data to/from the card use the SDIO_DataConfig(), SDIO_GetDataCounter(), - * SDIO_ReadData(), SDIO_WriteData() and SDIO_GetFIFOCount() functions. - * - * Read Operations - * --------------- - * a) First, user has to fill the data structure (pointer to - * SDIO_DataInitTypeDef) according to the selected data type to - * be received. - * The parameters that should be filled are: - * - Data TimeOut - * - Data Length - * - Data Block size - * - Data Transfer direction: should be from card (To SDIO) - * - Data Transfer mode - * - DPSM Status (Enable or Disable) - * - * b) Configure the SDIO resources to receive the data from the card - * according to selected transfer mode (Refer to Step 8, 9 and 10). - * - * c) Send the selected Read command (refer to step 11). - * - * d) Use the SDIO flags/interrupts to check the transfer status. - * - * Write Operations - * --------------- - * a) First, user has to fill the data structure (pointer to - * SDIO_DataInitTypeDef) according to the selected data type to - * be received. - * The parameters that should be filled are: - * - Data TimeOut - * - Data Length - * - Data Block size - * - Data Transfer direction: should be to card (To CARD) - * - Data Transfer mode - * - DPSM Status (Enable or Disable) - * - * b) Configure the SDIO resources to send the data to the card - * according to selected transfer mode (Refer to Step 8, 9 and 10). - * - * c) Send the selected Write command (refer to step 11). - * - * d) Use the SDIO flags/interrupts to check the transfer status. - * - * - * @endverbatim - * - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_sdio.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup SDIO - * @brief SDIO driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* ------------ SDIO registers bit address in the alias region ----------- */ -#define SDIO_OFFSET (SDIO_BASE - PERIPH_BASE) - -/* --- CLKCR Register ---*/ -/* Alias word address of CLKEN bit */ -#define CLKCR_OFFSET (SDIO_OFFSET + 0x04) -#define CLKEN_BitNumber 0x08 -#define CLKCR_CLKEN_BB (PERIPH_BB_BASE + (CLKCR_OFFSET * 32) + (CLKEN_BitNumber * 4)) - -/* --- CMD Register ---*/ -/* Alias word address of SDIOSUSPEND bit */ -#define CMD_OFFSET (SDIO_OFFSET + 0x0C) -#define SDIOSUSPEND_BitNumber 0x0B -#define CMD_SDIOSUSPEND_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (SDIOSUSPEND_BitNumber * 4)) - -/* Alias word address of ENCMDCOMPL bit */ -#define ENCMDCOMPL_BitNumber 0x0C -#define CMD_ENCMDCOMPL_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ENCMDCOMPL_BitNumber * 4)) - -/* Alias word address of NIEN bit */ -#define NIEN_BitNumber 0x0D -#define CMD_NIEN_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (NIEN_BitNumber * 4)) - -/* Alias word address of ATACMD bit */ -#define ATACMD_BitNumber 0x0E -#define CMD_ATACMD_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ATACMD_BitNumber * 4)) - -/* --- DCTRL Register ---*/ -/* Alias word address of DMAEN bit */ -#define DCTRL_OFFSET (SDIO_OFFSET + 0x2C) -#define DMAEN_BitNumber 0x03 -#define DCTRL_DMAEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (DMAEN_BitNumber * 4)) - -/* Alias word address of RWSTART bit */ -#define RWSTART_BitNumber 0x08 -#define DCTRL_RWSTART_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTART_BitNumber * 4)) - -/* Alias word address of RWSTOP bit */ -#define RWSTOP_BitNumber 0x09 -#define DCTRL_RWSTOP_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTOP_BitNumber * 4)) - -/* Alias word address of RWMOD bit */ -#define RWMOD_BitNumber 0x0A -#define DCTRL_RWMOD_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWMOD_BitNumber * 4)) - -/* Alias word address of SDIOEN bit */ -#define SDIOEN_BitNumber 0x0B -#define DCTRL_SDIOEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (SDIOEN_BitNumber * 4)) - -/* ---------------------- SDIO registers bit mask ------------------------ */ -/* --- CLKCR Register ---*/ -/* CLKCR register clear mask */ -#define CLKCR_CLEAR_MASK ((uint32_t)0xFFFF8100) - -/* --- PWRCTRL Register ---*/ -/* SDIO PWRCTRL Mask */ -#define PWR_PWRCTRL_MASK ((uint32_t)0xFFFFFFFC) - -/* --- DCTRL Register ---*/ -/* SDIO DCTRL Clear Mask */ -#define DCTRL_CLEAR_MASK ((uint32_t)0xFFFFFF08) - -/* --- CMD Register ---*/ -/* CMD Register clear mask */ -#define CMD_CLEAR_MASK ((uint32_t)0xFFFFF800) - -/* SDIO RESP Registers Address */ -#define SDIO_RESP_ADDR ((uint32_t)(SDIO_BASE + 0x14)) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup SDIO_Private_Functions - * @{ - */ - -/** @defgroup SDIO_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the SDIO peripheral registers to their default reset values. - * @param None - * @retval None - */ -void SDIO_DeInit(void) -{ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, DISABLE); -} - -/** - * @brief Initializes the SDIO peripheral according to the specified - * parameters in the SDIO_InitStruct. - * @param SDIO_InitStruct : pointer to a SDIO_InitTypeDef structure - * that contains the configuration information for the SDIO peripheral. - * @retval None - */ -void SDIO_Init(SDIO_InitTypeDef* SDIO_InitStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_SDIO_CLOCK_EDGE(SDIO_InitStruct->SDIO_ClockEdge)); - assert_param(IS_SDIO_CLOCK_BYPASS(SDIO_InitStruct->SDIO_ClockBypass)); - assert_param(IS_SDIO_CLOCK_POWER_SAVE(SDIO_InitStruct->SDIO_ClockPowerSave)); - assert_param(IS_SDIO_BUS_WIDE(SDIO_InitStruct->SDIO_BusWide)); - assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(SDIO_InitStruct->SDIO_HardwareFlowControl)); - -/*---------------------------- SDIO CLKCR Configuration ------------------------*/ - /* Get the SDIO CLKCR value */ - tmpreg = SDIO->CLKCR; - - /* Clear CLKDIV, PWRSAV, BYPASS, WIDBUS, NEGEDGE, HWFC_EN bits */ - tmpreg &= CLKCR_CLEAR_MASK; - - /* Set CLKDIV bits according to SDIO_ClockDiv value */ - /* Set PWRSAV bit according to SDIO_ClockPowerSave value */ - /* Set BYPASS bit according to SDIO_ClockBypass value */ - /* Set WIDBUS bits according to SDIO_BusWide value */ - /* Set NEGEDGE bits according to SDIO_ClockEdge value */ - /* Set HWFC_EN bits according to SDIO_HardwareFlowControl value */ - tmpreg |= (SDIO_InitStruct->SDIO_ClockDiv | SDIO_InitStruct->SDIO_ClockPowerSave | - SDIO_InitStruct->SDIO_ClockBypass | SDIO_InitStruct->SDIO_BusWide | - SDIO_InitStruct->SDIO_ClockEdge | SDIO_InitStruct->SDIO_HardwareFlowControl); - - /* Write to SDIO CLKCR */ - SDIO->CLKCR = tmpreg; -} - -/** - * @brief Fills each SDIO_InitStruct member with its default value. - * @param SDIO_InitStruct: pointer to an SDIO_InitTypeDef structure which - * will be initialized. - * @retval None - */ -void SDIO_StructInit(SDIO_InitTypeDef* SDIO_InitStruct) -{ - /* SDIO_InitStruct members default value */ - SDIO_InitStruct->SDIO_ClockDiv = 0x00; - SDIO_InitStruct->SDIO_ClockEdge = SDIO_ClockEdge_Rising; - SDIO_InitStruct->SDIO_ClockBypass = SDIO_ClockBypass_Disable; - SDIO_InitStruct->SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; - SDIO_InitStruct->SDIO_BusWide = SDIO_BusWide_1b; - SDIO_InitStruct->SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; -} - -/** - * @brief Enables or disables the SDIO Clock. - * @param NewState: new state of the SDIO Clock. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_ClockCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CLKCR_CLKEN_BB = (uint32_t)NewState; -} - -/** - * @brief Sets the power status of the controller. - * @param SDIO_PowerState: new state of the Power state. - * This parameter can be one of the following values: - * @arg SDIO_PowerState_OFF: SDIO Power OFF - * @arg SDIO_PowerState_ON: SDIO Power ON - * @retval None - */ -void SDIO_SetPowerState(uint32_t SDIO_PowerState) -{ - /* Check the parameters */ - assert_param(IS_SDIO_POWER_STATE(SDIO_PowerState)); - - SDIO->POWER = SDIO_PowerState; -} - -/** - * @brief Gets the power status of the controller. - * @param None - * @retval Power status of the controller. The returned value can be one of the - * following values: - * - 0x00: Power OFF - * - 0x02: Power UP - * - 0x03: Power ON - */ -uint32_t SDIO_GetPowerState(void) -{ - return (SDIO->POWER & (~PWR_PWRCTRL_MASK)); -} - -/** - * @} - */ - -/** @defgroup SDIO_Group2 Command path state machine (CPSM) management functions - * @brief Command path state machine (CPSM) management functions - * -@verbatim - =============================================================================== - Command path state machine (CPSM) management functions - =============================================================================== - - This section provide functions allowing to program and read the Command path - state machine (CPSM). - -@endverbatim - * @{ - */ - -/** - * @brief Initializes the SDIO Command according to the specified - * parameters in the SDIO_CmdInitStruct and send the command. - * @param SDIO_CmdInitStruct : pointer to a SDIO_CmdInitTypeDef - * structure that contains the configuration information for the SDIO - * command. - * @retval None - */ -void SDIO_SendCommand(SDIO_CmdInitTypeDef *SDIO_CmdInitStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_SDIO_CMD_INDEX(SDIO_CmdInitStruct->SDIO_CmdIndex)); - assert_param(IS_SDIO_RESPONSE(SDIO_CmdInitStruct->SDIO_Response)); - assert_param(IS_SDIO_WAIT(SDIO_CmdInitStruct->SDIO_Wait)); - assert_param(IS_SDIO_CPSM(SDIO_CmdInitStruct->SDIO_CPSM)); - -/*---------------------------- SDIO ARG Configuration ------------------------*/ - /* Set the SDIO Argument value */ - SDIO->ARG = SDIO_CmdInitStruct->SDIO_Argument; - -/*---------------------------- SDIO CMD Configuration ------------------------*/ - /* Get the SDIO CMD value */ - tmpreg = SDIO->CMD; - /* Clear CMDINDEX, WAITRESP, WAITINT, WAITPEND, CPSMEN bits */ - tmpreg &= CMD_CLEAR_MASK; - /* Set CMDINDEX bits according to SDIO_CmdIndex value */ - /* Set WAITRESP bits according to SDIO_Response value */ - /* Set WAITINT and WAITPEND bits according to SDIO_Wait value */ - /* Set CPSMEN bits according to SDIO_CPSM value */ - tmpreg |= (uint32_t)SDIO_CmdInitStruct->SDIO_CmdIndex | SDIO_CmdInitStruct->SDIO_Response - | SDIO_CmdInitStruct->SDIO_Wait | SDIO_CmdInitStruct->SDIO_CPSM; - - /* Write to SDIO CMD */ - SDIO->CMD = tmpreg; -} - -/** - * @brief Fills each SDIO_CmdInitStruct member with its default value. - * @param SDIO_CmdInitStruct: pointer to an SDIO_CmdInitTypeDef - * structure which will be initialized. - * @retval None - */ -void SDIO_CmdStructInit(SDIO_CmdInitTypeDef* SDIO_CmdInitStruct) -{ - /* SDIO_CmdInitStruct members default value */ - SDIO_CmdInitStruct->SDIO_Argument = 0x00; - SDIO_CmdInitStruct->SDIO_CmdIndex = 0x00; - SDIO_CmdInitStruct->SDIO_Response = SDIO_Response_No; - SDIO_CmdInitStruct->SDIO_Wait = SDIO_Wait_No; - SDIO_CmdInitStruct->SDIO_CPSM = SDIO_CPSM_Disable; -} - -/** - * @brief Returns command index of last command for which response received. - * @param None - * @retval Returns the command index of the last command response received. - */ -uint8_t SDIO_GetCommandResponse(void) -{ - return (uint8_t)(SDIO->RESPCMD); -} - -/** - * @brief Returns response received from the card for the last command. - * @param SDIO_RESP: Specifies the SDIO response register. - * This parameter can be one of the following values: - * @arg SDIO_RESP1: Response Register 1 - * @arg SDIO_RESP2: Response Register 2 - * @arg SDIO_RESP3: Response Register 3 - * @arg SDIO_RESP4: Response Register 4 - * @retval The Corresponding response register value. - */ -uint32_t SDIO_GetResponse(uint32_t SDIO_RESP) -{ - __IO uint32_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_SDIO_RESP(SDIO_RESP)); - - tmp = SDIO_RESP_ADDR + SDIO_RESP; - - return (*(__IO uint32_t *) tmp); -} - -/** - * @} - */ - -/** @defgroup SDIO_Group3 Data path state machine (DPSM) management functions - * @brief Data path state machine (DPSM) management functions - * -@verbatim - =============================================================================== - Data path state machine (DPSM) management functions - =============================================================================== - - This section provide functions allowing to program and read the Data path - state machine (DPSM). - -@endverbatim - * @{ - */ - -/** - * @brief Initializes the SDIO data path according to the specified - * parameters in the SDIO_DataInitStruct. - * @param SDIO_DataInitStruct : pointer to a SDIO_DataInitTypeDef structure - * that contains the configuration information for the SDIO command. - * @retval None - */ -void SDIO_DataConfig(SDIO_DataInitTypeDef* SDIO_DataInitStruct) -{ - uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_SDIO_DATA_LENGTH(SDIO_DataInitStruct->SDIO_DataLength)); - assert_param(IS_SDIO_BLOCK_SIZE(SDIO_DataInitStruct->SDIO_DataBlockSize)); - assert_param(IS_SDIO_TRANSFER_DIR(SDIO_DataInitStruct->SDIO_TransferDir)); - assert_param(IS_SDIO_TRANSFER_MODE(SDIO_DataInitStruct->SDIO_TransferMode)); - assert_param(IS_SDIO_DPSM(SDIO_DataInitStruct->SDIO_DPSM)); - -/*---------------------------- SDIO DTIMER Configuration ---------------------*/ - /* Set the SDIO Data TimeOut value */ - SDIO->DTIMER = SDIO_DataInitStruct->SDIO_DataTimeOut; - -/*---------------------------- SDIO DLEN Configuration -----------------------*/ - /* Set the SDIO DataLength value */ - SDIO->DLEN = SDIO_DataInitStruct->SDIO_DataLength; - -/*---------------------------- SDIO DCTRL Configuration ----------------------*/ - /* Get the SDIO DCTRL value */ - tmpreg = SDIO->DCTRL; - /* Clear DEN, DTMODE, DTDIR and DBCKSIZE bits */ - tmpreg &= DCTRL_CLEAR_MASK; - /* Set DEN bit according to SDIO_DPSM value */ - /* Set DTMODE bit according to SDIO_TransferMode value */ - /* Set DTDIR bit according to SDIO_TransferDir value */ - /* Set DBCKSIZE bits according to SDIO_DataBlockSize value */ - tmpreg |= (uint32_t)SDIO_DataInitStruct->SDIO_DataBlockSize | SDIO_DataInitStruct->SDIO_TransferDir - | SDIO_DataInitStruct->SDIO_TransferMode | SDIO_DataInitStruct->SDIO_DPSM; - - /* Write to SDIO DCTRL */ - SDIO->DCTRL = tmpreg; -} - -/** - * @brief Fills each SDIO_DataInitStruct member with its default value. - * @param SDIO_DataInitStruct: pointer to an SDIO_DataInitTypeDef structure - * which will be initialized. - * @retval None - */ -void SDIO_DataStructInit(SDIO_DataInitTypeDef* SDIO_DataInitStruct) -{ - /* SDIO_DataInitStruct members default value */ - SDIO_DataInitStruct->SDIO_DataTimeOut = 0xFFFFFFFF; - SDIO_DataInitStruct->SDIO_DataLength = 0x00; - SDIO_DataInitStruct->SDIO_DataBlockSize = SDIO_DataBlockSize_1b; - SDIO_DataInitStruct->SDIO_TransferDir = SDIO_TransferDir_ToCard; - SDIO_DataInitStruct->SDIO_TransferMode = SDIO_TransferMode_Block; - SDIO_DataInitStruct->SDIO_DPSM = SDIO_DPSM_Disable; -} - -/** - * @brief Returns number of remaining data bytes to be transferred. - * @param None - * @retval Number of remaining data bytes to be transferred - */ -uint32_t SDIO_GetDataCounter(void) -{ - return SDIO->DCOUNT; -} - -/** - * @brief Read one data word from Rx FIFO. - * @param None - * @retval Data received - */ -uint32_t SDIO_ReadData(void) -{ - return SDIO->FIFO; -} - -/** - * @brief Write one data word to Tx FIFO. - * @param Data: 32-bit data word to write. - * @retval None - */ -void SDIO_WriteData(uint32_t Data) -{ - SDIO->FIFO = Data; -} - -/** - * @brief Returns the number of words left to be written to or read from FIFO. - * @param None - * @retval Remaining number of words. - */ -uint32_t SDIO_GetFIFOCount(void) -{ - return SDIO->FIFOCNT; -} - -/** - * @} - */ - -/** @defgroup SDIO_Group4 SDIO IO Cards mode management functions - * @brief SDIO IO Cards mode management functions - * -@verbatim - =============================================================================== - SDIO IO Cards mode management functions - =============================================================================== - - This section provide functions allowing to program and read the SDIO IO Cards. - -@endverbatim - * @{ - */ - -/** - * @brief Starts the SD I/O Read Wait operation. - * @param NewState: new state of the Start SDIO Read Wait operation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_StartSDIOReadWait(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) DCTRL_RWSTART_BB = (uint32_t) NewState; -} - -/** - * @brief Stops the SD I/O Read Wait operation. - * @param NewState: new state of the Stop SDIO Read Wait operation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_StopSDIOReadWait(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) DCTRL_RWSTOP_BB = (uint32_t) NewState; -} - -/** - * @brief Sets one of the two options of inserting read wait interval. - * @param SDIO_ReadWaitMode: SD I/O Read Wait operation mode. - * This parameter can be: - * @arg SDIO_ReadWaitMode_CLK: Read Wait control by stopping SDIOCLK - * @arg SDIO_ReadWaitMode_DATA2: Read Wait control using SDIO_DATA2 - * @retval None - */ -void SDIO_SetSDIOReadWaitMode(uint32_t SDIO_ReadWaitMode) -{ - /* Check the parameters */ - assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode)); - - *(__IO uint32_t *) DCTRL_RWMOD_BB = SDIO_ReadWaitMode; -} - -/** - * @brief Enables or disables the SD I/O Mode Operation. - * @param NewState: new state of SDIO specific operation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_SetSDIOOperation(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) DCTRL_SDIOEN_BB = (uint32_t)NewState; -} - -/** - * @brief Enables or disables the SD I/O Mode suspend command sending. - * @param NewState: new state of the SD I/O Mode suspend command. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_SendSDIOSuspendCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CMD_SDIOSUSPEND_BB = (uint32_t)NewState; -} - -/** - * @} - */ - -/** @defgroup SDIO_Group5 CE-ATA mode management functions - * @brief CE-ATA mode management functions - * -@verbatim - =============================================================================== - CE-ATA mode management functions - =============================================================================== - - This section provide functions allowing to program and read the CE-ATA card. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the command completion signal. - * @param NewState: new state of command completion signal. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_CommandCompletionCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CMD_ENCMDCOMPL_BB = (uint32_t)NewState; -} - -/** - * @brief Enables or disables the CE-ATA interrupt. - * @param NewState: new state of CE-ATA interrupt. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_CEATAITCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CMD_NIEN_BB = (uint32_t)((~((uint32_t)NewState)) & ((uint32_t)0x1)); -} - -/** - * @brief Sends CE-ATA command (CMD61). - * @param NewState: new state of CE-ATA command. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_SendCEATACmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CMD_ATACMD_BB = (uint32_t)NewState; -} - -/** - * @} - */ - -/** @defgroup SDIO_Group6 DMA transfers management functions - * @brief DMA transfers management functions - * -@verbatim - =============================================================================== - DMA transfers management functions - =============================================================================== - - This section provide functions allowing to program SDIO DMA transfer. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the SDIO DMA request. - * @param NewState: new state of the selected SDIO DMA request. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_DMACmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) DCTRL_DMAEN_BB = (uint32_t)NewState; -} - -/** - * @} - */ - -/** @defgroup SDIO_Group7 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the SDIO interrupts. - * @param SDIO_IT: specifies the SDIO interrupt sources to be enabled or disabled. - * This parameter can be one or a combination of the following values: - * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt - * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt - * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt - * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt - * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt - * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt - * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt - * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt - * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt - * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide - * bus mode interrupt - * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt - * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt - * @arg SDIO_IT_TXACT: Data transmit in progress interrupt - * @arg SDIO_IT_RXACT: Data receive in progress interrupt - * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt - * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt - * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt - * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt - * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt - * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt - * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt - * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt - * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt - * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt - * @param NewState: new state of the specified SDIO interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SDIO_ITConfig(uint32_t SDIO_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SDIO_IT(SDIO_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the SDIO interrupts */ - SDIO->MASK |= SDIO_IT; - } - else - { - /* Disable the SDIO interrupts */ - SDIO->MASK &= ~SDIO_IT; - } -} - -/** - * @brief Checks whether the specified SDIO flag is set or not. - * @param SDIO_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed) - * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) - * @arg SDIO_FLAG_CTIMEOUT: Command response timeout - * @arg SDIO_FLAG_DTIMEOUT: Data timeout - * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error - * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error - * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed) - * @arg SDIO_FLAG_CMDSENT: Command sent (no response required) - * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero) - * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide bus mode. - * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed) - * @arg SDIO_FLAG_CMDACT: Command transfer in progress - * @arg SDIO_FLAG_TXACT: Data transmit in progress - * @arg SDIO_FLAG_RXACT: Data receive in progress - * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty - * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full - * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full - * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full - * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty - * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty - * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO - * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO - * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received - * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61 - * @retval The new state of SDIO_FLAG (SET or RESET). - */ -FlagStatus SDIO_GetFlagStatus(uint32_t SDIO_FLAG) -{ - FlagStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_SDIO_FLAG(SDIO_FLAG)); - - if ((SDIO->STA & SDIO_FLAG) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the SDIO's pending flags. - * @param SDIO_FLAG: specifies the flag to clear. - * This parameter can be one or a combination of the following values: - * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed) - * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) - * @arg SDIO_FLAG_CTIMEOUT: Command response timeout - * @arg SDIO_FLAG_DTIMEOUT: Data timeout - * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error - * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error - * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed) - * @arg SDIO_FLAG_CMDSENT: Command sent (no response required) - * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero) - * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide bus mode - * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed) - * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received - * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61 - * @retval None - */ -void SDIO_ClearFlag(uint32_t SDIO_FLAG) -{ - /* Check the parameters */ - assert_param(IS_SDIO_CLEAR_FLAG(SDIO_FLAG)); - - SDIO->ICR = SDIO_FLAG; -} - -/** - * @brief Checks whether the specified SDIO interrupt has occurred or not. - * @param SDIO_IT: specifies the SDIO interrupt source to check. - * This parameter can be one of the following values: - * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt - * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt - * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt - * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt - * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt - * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt - * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt - * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt - * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt - * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide - * bus mode interrupt - * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt - * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt - * @arg SDIO_IT_TXACT: Data transmit in progress interrupt - * @arg SDIO_IT_RXACT: Data receive in progress interrupt - * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt - * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt - * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt - * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt - * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt - * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt - * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt - * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt - * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt - * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt - * @retval The new state of SDIO_IT (SET or RESET). - */ -ITStatus SDIO_GetITStatus(uint32_t SDIO_IT) -{ - ITStatus bitstatus = RESET; - - /* Check the parameters */ - assert_param(IS_SDIO_GET_IT(SDIO_IT)); - if ((SDIO->STA & SDIO_IT) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the SDIO's interrupt pending bits. - * @param SDIO_IT: specifies the interrupt pending bit to clear. - * This parameter can be one or a combination of the following values: - * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt - * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt - * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt - * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt - * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt - * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt - * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt - * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt - * @arg SDIO_IT_DATAEND: Data end (data counter, SDIO_DCOUNT, is zero) interrupt - * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide - * bus mode interrupt - * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt - * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 - * @retval None - */ -void SDIO_ClearITPendingBit(uint32_t SDIO_IT) -{ - /* Check the parameters */ - assert_param(IS_SDIO_CLEAR_IT(SDIO_IT)); - - SDIO->ICR = SDIO_IT; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_spi.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_spi.c deleted file mode 100644 index 5f478d192..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_spi.c +++ /dev/null @@ -1,1290 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_spi.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the Serial peripheral interface (SPI): - * - Initialization and Configuration - * - Data transfers functions - * - Hardware CRC Calculation - * - DMA transfers management - * - Interrupts and flags management - * - * @verbatim - * - * - * =================================================================== - * How to use this driver - * =================================================================== - * - * 1. Enable peripheral clock using the following functions - * RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE) for SPI1 - * RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE) for SPI2 - * RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE) for SPI3. - * - * 2. Enable SCK, MOSI, MISO and NSS GPIO clocks using RCC_AHB1PeriphClockCmd() - * function. - * In I2S mode, if an external clock source is used then the I2S CKIN pin GPIO - * clock should also be enabled. - * - * 3. Peripherals alternate function: - * - Connect the pin to the desired peripherals' Alternate - * Function (AF) using GPIO_PinAFConfig() function - * - Configure the desired pin in alternate function by: - * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF - * - Select the type, pull-up/pull-down and output speed via - * GPIO_PuPd, GPIO_OType and GPIO_Speed members - * - Call GPIO_Init() function - * In I2S mode, if an external clock source is used then the I2S CKIN pin - * should be also configured in Alternate function Push-pull pull-up mode. - * - * 4. Program the Polarity, Phase, First Data, Baud Rate Prescaler, Slave - * Management, Peripheral Mode and CRC Polynomial values using the SPI_Init() - * function. - * In I2S mode, program the Mode, Standard, Data Format, MCLK Output, Audio - * frequency and Polarity using I2S_Init() function. - * For I2S mode, make sure that either: - * - I2S PLL is configured using the functions RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S), - * RCC_PLLI2SCmd(ENABLE) and RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY). - * or - * - External clock source is configured using the function - * RCC_I2SCLKConfig(RCC_I2S2CLKSource_Ext) and after setting correctly the define constant - * I2S_EXTERNAL_CLOCK_VAL in the stm32f4xx_conf.h file. - * - * 5. Enable the NVIC and the corresponding interrupt using the function - * SPI_ITConfig() if you need to use interrupt mode. - * - * 6. When using the DMA mode - * - Configure the DMA using DMA_Init() function - * - Active the needed channel Request using SPI_I2S_DMACmd() function - * - * 7. Enable the SPI using the SPI_Cmd() function or enable the I2S using - * I2S_Cmd(). - * - * 8. Enable the DMA using the DMA_Cmd() function when using DMA mode. - * - * 9. Optionally, you can enable/configure the following parameters without - * re-initialization (i.e there is no need to call again SPI_Init() function): - * - When bidirectional mode (SPI_Direction_1Line_Rx or SPI_Direction_1Line_Tx) - * is programmed as Data direction parameter using the SPI_Init() function - * it can be possible to switch between SPI_Direction_Tx or SPI_Direction_Rx - * using the SPI_BiDirectionalLineConfig() function. - * - When SPI_NSS_Soft is selected as Slave Select Management parameter - * using the SPI_Init() function it can be possible to manage the - * NSS internal signal using the SPI_NSSInternalSoftwareConfig() function. - * - Reconfigure the data size using the SPI_DataSizeConfig() function - * - Enable or disable the SS output using the SPI_SSOutputCmd() function - * - * 10. To use the CRC Hardware calculation feature refer to the Peripheral - * CRC hardware Calculation subsection. - * - * - * It is possible to use SPI in I2S full duplex mode, in this case, each SPI - * peripheral is able to manage sending and receiving data simultaneously - * using two data lines. Each SPI peripheral has an extended block called I2Sxext - * (ie. I2S2ext for SPI2 and I2S3ext for SPI3). - * The extension block is not a full SPI IP, it is used only as I2S slave to - * implement full duplex mode. The extension block uses the same clock sources - * as its master. - * To configure I2S full duplex you have to: - * - * 1. Configure SPIx in I2S mode (I2S_Init() function) as described above. - * - * 2. Call the I2S_FullDuplexConfig() function using the same strucutre passed to - * I2S_Init() function. - * - * 3. Call I2S_Cmd() for SPIx then for its extended block. - * - * 4. To configure interrupts or DMA requests and to get/clear flag status, - * use I2Sxext instance for the extension block. - * - * Functions that can be called with I2Sxext instances are: - * I2S_Cmd(), I2S_FullDuplexConfig(), SPI_I2S_ReceiveData(), SPI_I2S_SendData(), - * SPI_I2S_DMACmd(), SPI_I2S_ITConfig(), SPI_I2S_GetFlagStatus(), SPI_I2S_ClearFlag(), - * SPI_I2S_GetITStatus() and SPI_I2S_ClearITPendingBit(). - * - * Example: To use SPI3 in Full duplex mode (SPI3 is Master Tx, I2S3ext is Slave Rx): - * - * RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); - * I2S_StructInit(&I2SInitStruct); - * I2SInitStruct.Mode = I2S_Mode_MasterTx; - * I2S_Init(SPI3, &I2SInitStruct); - * I2S_FullDuplexConfig(SPI3ext, &I2SInitStruct) - * I2S_Cmd(SPI3, ENABLE); - * I2S_Cmd(SPI3ext, ENABLE); - * ... - * while (SPI_I2S_GetFlagStatus(SPI2, SPI_FLAG_TXE) == RESET) - * {} - * SPI_I2S_SendData(SPI3, txdata[i]); - * ... - * while (SPI_I2S_GetFlagStatus(I2S3ext, SPI_FLAG_RXNE) == RESET) - * {} - * rxdata[i] = SPI_I2S_ReceiveData(I2S3ext); - * ... - * - * - * - * @note This driver supports only the I2S clock scheme available in Silicon - * RevisionB and RevisionY. - * - * @note In I2S mode: if an external clock is used as source clock for the I2S, - * then the define I2S_EXTERNAL_CLOCK_VAL in file stm32f4xx_conf.h should - * be enabled and set to the value of the source clock frequency (in Hz). - * - * @note In SPI mode: To use the SPI TI mode, call the function SPI_TIModeCmd() - * just after calling the function SPI_Init(). - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_spi.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup SPI - * @brief SPI driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* SPI registers Masks */ -#define CR1_CLEAR_MASK ((uint16_t)0x3040) -#define I2SCFGR_CLEAR_MASK ((uint16_t)0xF040) - -/* RCC PLLs masks */ -#define PLLCFGR_PPLR_MASK ((uint32_t)0x70000000) -#define PLLCFGR_PPLN_MASK ((uint32_t)0x00007FC0) - -#define SPI_CR2_FRF ((uint16_t)0x0010) -#define SPI_SR_TIFRFE ((uint16_t)0x0100) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup SPI_Private_Functions - * @{ - */ - -/** @defgroup SPI_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - - This section provides a set of functions allowing to initialize the SPI Direction, - SPI Mode, SPI Data Size, SPI Polarity, SPI Phase, SPI NSS Management, SPI Baud - Rate Prescaler, SPI First Bit and SPI CRC Polynomial. - - The SPI_Init() function follows the SPI configuration procedures for Master mode - and Slave mode (details for these procedures are available in reference manual - (RM0090)). - -@endverbatim - * @{ - */ - -/** - * @brief Deinitialize the SPIx peripheral registers to their default reset values. - * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 - * in SPI mode or 2 or 3 in I2S mode. - * - * @note The extended I2S blocks (ie. I2S2ext and I2S3ext blocks) are deinitialized - * when the relative I2S peripheral is deinitialized (the extended block's clock - * is managed by the I2S peripheral clock). - * - * @retval None - */ -void SPI_I2S_DeInit(SPI_TypeDef* SPIx) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - if (SPIx == SPI1) - { - /* Enable SPI1 reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE); - /* Release SPI1 from reset state */ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE); - } - else if (SPIx == SPI2) - { - /* Enable SPI2 reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE); - /* Release SPI2 from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE); - } - else - { - if (SPIx == SPI3) - { - /* Enable SPI3 reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE); - /* Release SPI3 from reset state */ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE); - } - } -} - -/** - * @brief Initializes the SPIx peripheral according to the specified - * parameters in the SPI_InitStruct. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure that - * contains the configuration information for the specified SPI peripheral. - * @retval None - */ -void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct) -{ - uint16_t tmpreg = 0; - - /* check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - /* Check the SPI parameters */ - assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction)); - assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode)); - assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize)); - assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL)); - assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA)); - assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS)); - assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler)); - assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit)); - assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial)); - -/*---------------------------- SPIx CR1 Configuration ------------------------*/ - /* Get the SPIx CR1 value */ - tmpreg = SPIx->CR1; - /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */ - tmpreg &= CR1_CLEAR_MASK; - /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler - master/salve mode, CPOL and CPHA */ - /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */ - /* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */ - /* Set LSBFirst bit according to SPI_FirstBit value */ - /* Set BR bits according to SPI_BaudRatePrescaler value */ - /* Set CPOL bit according to SPI_CPOL value */ - /* Set CPHA bit according to SPI_CPHA value */ - tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode | - SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL | - SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS | - SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit); - /* Write to SPIx CR1 */ - SPIx->CR1 = tmpreg; - - /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */ - SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SMOD); -/*---------------------------- SPIx CRCPOLY Configuration --------------------*/ - /* Write to SPIx CRCPOLY */ - SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial; -} - -/** - * @brief Initializes the SPIx peripheral according to the specified - * parameters in the I2S_InitStruct. - * @param SPIx: where x can be 2 or 3 to select the SPI peripheral (configured in I2S mode). - * @param I2S_InitStruct: pointer to an I2S_InitTypeDef structure that - * contains the configuration information for the specified SPI peripheral - * configured in I2S mode. - * - * @note The function calculates the optimal prescaler needed to obtain the most - * accurate audio frequency (depending on the I2S clock source, the PLL values - * and the product configuration). But in case the prescaler value is greater - * than 511, the default value (0x02) will be configured instead. - * - * @note if an external clock is used as source clock for the I2S, then the define - * I2S_EXTERNAL_CLOCK_VAL in file stm32f4xx_conf.h should be enabled and set - * to the value of the the source clock frequency (in Hz). - * - * @retval None - */ -void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct) -{ - uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1; - uint32_t tmp = 0, i2sclk = 0; -#ifndef I2S_EXTERNAL_CLOCK_VAL - uint32_t pllm = 0, plln = 0, pllr = 0; -#endif /* I2S_EXTERNAL_CLOCK_VAL */ - - /* Check the I2S parameters */ - assert_param(IS_SPI_23_PERIPH(SPIx)); - assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode)); - assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard)); - assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat)); - assert_param(IS_I2S_MCLK_OUTPUT(I2S_InitStruct->I2S_MCLKOutput)); - assert_param(IS_I2S_AUDIO_FREQ(I2S_InitStruct->I2S_AudioFreq)); - assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL)); - -/*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/ - /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */ - SPIx->I2SCFGR &= I2SCFGR_CLEAR_MASK; - SPIx->I2SPR = 0x0002; - - /* Get the I2SCFGR register value */ - tmpreg = SPIx->I2SCFGR; - - /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/ - if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default) - { - i2sodd = (uint16_t)0; - i2sdiv = (uint16_t)2; - } - /* If the requested audio frequency is not the default, compute the prescaler */ - else - { - /* Check the frame length (For the Prescaler computing) *******************/ - if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b) - { - /* Packet length is 16 bits */ - packetlength = 1; - } - else - { - /* Packet length is 32 bits */ - packetlength = 2; - } - - /* Get I2S source Clock frequency (only in Silicon RevisionB and RevisionY) */ - - /* If an external I2S clock has to be used, this define should be set - in the project configuration or in the stm32f4xx_conf.h file */ - #ifdef I2S_EXTERNAL_CLOCK_VAL - /* Set external clock as I2S clock source */ - if ((RCC->CFGR & RCC_CFGR_I2SSRC) == 0) - { - RCC->CFGR |= (uint32_t)RCC_CFGR_I2SSRC; - } - - /* Set the I2S clock to the external clock value */ - i2sclk = I2S_EXTERNAL_CLOCK_VAL; - - #else /* There is no define for External I2S clock source */ - /* Set PLLI2S as I2S clock source */ - if ((RCC->CFGR & RCC_CFGR_I2SSRC) != 0) - { - RCC->CFGR &= ~(uint32_t)RCC_CFGR_I2SSRC; - } - - /* Get the PLLI2SN value */ - plln = (uint32_t)(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6) & \ - (RCC_PLLI2SCFGR_PLLI2SN >> 6)); - - /* Get the PLLI2SR value */ - pllr = (uint32_t)(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28) & \ - (RCC_PLLI2SCFGR_PLLI2SR >> 28)); - - /* Get the PLLM value */ - pllm = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM); - - /* Get the I2S source clock value */ - i2sclk = (uint32_t)(((HSE_VALUE / pllm) * plln) / pllr); - #endif /* I2S_EXTERNAL_CLOCK_VAL */ - - /* Compute the Real divider depending on the MCLK output state, with a floating point */ - if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable) - { - /* MCLK output is enabled */ - tmp = (uint16_t)(((((i2sclk / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5); - } - else - { - /* MCLK output is disabled */ - tmp = (uint16_t)(((((i2sclk / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5); - } - - /* Remove the flatting point */ - tmp = tmp / 10; - - /* Check the parity of the divider */ - i2sodd = (uint16_t)(tmp & (uint16_t)0x0001); - - /* Compute the i2sdiv prescaler */ - i2sdiv = (uint16_t)((tmp - i2sodd) / 2); - - /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */ - i2sodd = (uint16_t) (i2sodd << 8); - } - - /* Test if the divider is 1 or 0 or greater than 0xFF */ - if ((i2sdiv < 2) || (i2sdiv > 0xFF)) - { - /* Set the default values */ - i2sdiv = 2; - i2sodd = 0; - } - - /* Write to SPIx I2SPR register the computed value */ - SPIx->I2SPR = (uint16_t)((uint16_t)i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput)); - - /* Configure the I2S with the SPI_InitStruct values */ - tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(I2S_InitStruct->I2S_Mode | \ - (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \ - (uint16_t)I2S_InitStruct->I2S_CPOL)))); - - /* Write to SPIx I2SCFGR */ - SPIx->I2SCFGR = tmpreg; -} - -/** - * @brief Fills each SPI_InitStruct member with its default value. - * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure which will be initialized. - * @retval None - */ -void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct) -{ -/*--------------- Reset SPI init structure parameters values -----------------*/ - /* Initialize the SPI_Direction member */ - SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex; - /* initialize the SPI_Mode member */ - SPI_InitStruct->SPI_Mode = SPI_Mode_Slave; - /* initialize the SPI_DataSize member */ - SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b; - /* Initialize the SPI_CPOL member */ - SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low; - /* Initialize the SPI_CPHA member */ - SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge; - /* Initialize the SPI_NSS member */ - SPI_InitStruct->SPI_NSS = SPI_NSS_Hard; - /* Initialize the SPI_BaudRatePrescaler member */ - SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; - /* Initialize the SPI_FirstBit member */ - SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB; - /* Initialize the SPI_CRCPolynomial member */ - SPI_InitStruct->SPI_CRCPolynomial = 7; -} - -/** - * @brief Fills each I2S_InitStruct member with its default value. - * @param I2S_InitStruct: pointer to a I2S_InitTypeDef structure which will be initialized. - * @retval None - */ -void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct) -{ -/*--------------- Reset I2S init structure parameters values -----------------*/ - /* Initialize the I2S_Mode member */ - I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx; - - /* Initialize the I2S_Standard member */ - I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips; - - /* Initialize the I2S_DataFormat member */ - I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b; - - /* Initialize the I2S_MCLKOutput member */ - I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable; - - /* Initialize the I2S_AudioFreq member */ - I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default; - - /* Initialize the I2S_CPOL member */ - I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low; -} - -/** - * @brief Enables or disables the specified SPI peripheral. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param NewState: new state of the SPIx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected SPI peripheral */ - SPIx->CR1 |= SPI_CR1_SPE; - } - else - { - /* Disable the selected SPI peripheral */ - SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE); - } -} - -/** - * @brief Enables or disables the specified SPI peripheral (in I2S mode). - * @param SPIx: where x can be 2 or 3 to select the SPI peripheral (or I2Sxext - * for full duplex mode). - * @param NewState: new state of the SPIx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_23_PERIPH_EXT(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected SPI peripheral (in I2S mode) */ - SPIx->I2SCFGR |= SPI_I2SCFGR_I2SE; - } - else - { - /* Disable the selected SPI peripheral in I2S mode */ - SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SE); - } -} - -/** - * @brief Configures the data size for the selected SPI. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param SPI_DataSize: specifies the SPI data size. - * This parameter can be one of the following values: - * @arg SPI_DataSize_16b: Set data frame format to 16bit - * @arg SPI_DataSize_8b: Set data frame format to 8bit - * @retval None - */ -void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_DATASIZE(SPI_DataSize)); - /* Clear DFF bit */ - SPIx->CR1 &= (uint16_t)~SPI_DataSize_16b; - /* Set new DFF bit value */ - SPIx->CR1 |= SPI_DataSize; -} - -/** - * @brief Selects the data transfer direction in bidirectional mode for the specified SPI. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param SPI_Direction: specifies the data transfer direction in bidirectional mode. - * This parameter can be one of the following values: - * @arg SPI_Direction_Tx: Selects Tx transmission direction - * @arg SPI_Direction_Rx: Selects Rx receive direction - * @retval None - */ -void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_DIRECTION(SPI_Direction)); - if (SPI_Direction == SPI_Direction_Tx) - { - /* Set the Tx only mode */ - SPIx->CR1 |= SPI_Direction_Tx; - } - else - { - /* Set the Rx only mode */ - SPIx->CR1 &= SPI_Direction_Rx; - } -} - -/** - * @brief Configures internally by software the NSS pin for the selected SPI. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param SPI_NSSInternalSoft: specifies the SPI NSS internal state. - * This parameter can be one of the following values: - * @arg SPI_NSSInternalSoft_Set: Set NSS pin internally - * @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally - * @retval None - */ -void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft)); - if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset) - { - /* Set NSS pin internally by software */ - SPIx->CR1 |= SPI_NSSInternalSoft_Set; - } - else - { - /* Reset NSS pin internally by software */ - SPIx->CR1 &= SPI_NSSInternalSoft_Reset; - } -} - -/** - * @brief Enables or disables the SS output for the selected SPI. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param NewState: new state of the SPIx SS output. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected SPI SS output */ - SPIx->CR2 |= (uint16_t)SPI_CR2_SSOE; - } - else - { - /* Disable the selected SPI SS output */ - SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE); - } -} - -/** - * @brief Enables or disables the SPIx/I2Sx DMA interface. - * - * @note This function can be called only after the SPI_Init() function has - * been called. - * @note When TI mode is selected, the control bits SSM, SSI, CPOL and CPHA - * are not taken into consideration and are configured by hardware - * respectively to the TI mode requirements. - * - * @param SPIx: where x can be 1, 2 or 3 - * @param NewState: new state of the selected SPI TI communication mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the TI mode for the selected SPI peripheral */ - SPIx->CR2 |= SPI_CR2_FRF; - } - else - { - /* Disable the TI mode for the selected SPI peripheral */ - SPIx->CR2 &= (uint16_t)~SPI_CR2_FRF; - } -} - -/** - * @brief Configures the full duplex mode for the I2Sx peripheral using its - * extension I2Sxext according to the specified parameters in the - * I2S_InitStruct. - * @param I2Sxext: where x can be 2 or 3 to select the I2S peripheral extension block. - * @param I2S_InitStruct: pointer to an I2S_InitTypeDef structure that - * contains the configuration information for the specified I2S peripheral - * extension. - * - * @note The structure pointed by I2S_InitStruct parameter should be the same - * used for the master I2S peripheral. In this case, if the master is - * configured as transmitter, the slave will be receiver and vice versa. - * Or you can force a different mode by modifying the field I2S_Mode to the - * value I2S_SlaveRx or I2S_SlaveTx indepedently of the master configuration. - * - * @note The I2S full duplex extension can be configured in slave mode only. - * - * @retval None - */ -void I2S_FullDuplexConfig(SPI_TypeDef* I2Sxext, I2S_InitTypeDef* I2S_InitStruct) -{ - uint16_t tmpreg = 0, tmp = 0; - - /* Check the I2S parameters */ - assert_param(IS_I2S_EXT_PERIPH(I2Sxext)); - assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode)); - assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard)); - assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat)); - assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL)); - -/*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/ - /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */ - I2Sxext->I2SCFGR &= I2SCFGR_CLEAR_MASK; - I2Sxext->I2SPR = 0x0002; - - /* Get the I2SCFGR register value */ - tmpreg = I2Sxext->I2SCFGR; - - /* Get the mode to be configured for the extended I2S */ - if ((I2S_InitStruct->I2S_Mode == I2S_Mode_MasterTx) || (I2S_InitStruct->I2S_Mode == I2S_Mode_SlaveTx)) - { - tmp = I2S_Mode_SlaveRx; - } - else - { - if ((I2S_InitStruct->I2S_Mode == I2S_Mode_MasterRx) || (I2S_InitStruct->I2S_Mode == I2S_Mode_SlaveRx)) - { - tmp = I2S_Mode_SlaveTx; - } - } - - - /* Configure the I2S with the SPI_InitStruct values */ - tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(tmp | \ - (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \ - (uint16_t)I2S_InitStruct->I2S_CPOL)))); - - /* Write to SPIx I2SCFGR */ - I2Sxext->I2SCFGR = tmpreg; -} - -/** - * @} - */ - -/** @defgroup SPI_Group2 Data transfers functions - * @brief Data transfers functions - * -@verbatim - =============================================================================== - Data transfers functions - =============================================================================== - - This section provides a set of functions allowing to manage the SPI data transfers - - In reception, data are received and then stored into an internal Rx buffer while - In transmission, data are first stored into an internal Tx buffer before being - transmitted. - - The read access of the SPI_DR register can be done using the SPI_I2S_ReceiveData() - function and returns the Rx buffered value. Whereas a write access to the SPI_DR - can be done using SPI_I2S_SendData() function and stores the written data into - Tx buffer. - -@endverbatim - * @{ - */ - -/** - * @brief Returns the most recent received data by the SPIx/I2Sx peripheral. - * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 - * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. - * @retval The value of the received data. - */ -uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); - - /* Return the data in the DR register */ - return SPIx->DR; -} - -/** - * @brief Transmits a Data through the SPIx/I2Sx peripheral. - * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 - * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. - * @param Data: Data to be transmitted. - * @retval None - */ -void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); - - /* Write in the DR register the data to be sent */ - SPIx->DR = Data; -} - -/** - * @} - */ - -/** @defgroup SPI_Group3 Hardware CRC Calculation functions - * @brief Hardware CRC Calculation functions - * -@verbatim - =============================================================================== - Hardware CRC Calculation functions - =============================================================================== - - This section provides a set of functions allowing to manage the SPI CRC hardware - calculation - - SPI communication using CRC is possible through the following procedure: - 1. Program the Data direction, Polarity, Phase, First Data, Baud Rate Prescaler, - Slave Management, Peripheral Mode and CRC Polynomial values using the SPI_Init() - function. - 2. Enable the CRC calculation using the SPI_CalculateCRC() function. - 3. Enable the SPI using the SPI_Cmd() function - 4. Before writing the last data to the TX buffer, set the CRCNext bit using the - SPI_TransmitCRC() function to indicate that after transmission of the last - data, the CRC should be transmitted. - 5. After transmitting the last data, the SPI transmits the CRC. The SPI_CR1_CRCNEXT - bit is reset. The CRC is also received and compared against the SPI_RXCRCR - value. - If the value does not match, the SPI_FLAG_CRCERR flag is set and an interrupt - can be generated when the SPI_I2S_IT_ERR interrupt is enabled. - -@note It is advised not to read the calculated CRC values during the communication. - -@note When the SPI is in slave mode, be careful to enable CRC calculation only - when the clock is stable, that is, when the clock is in the steady state. - If not, a wrong CRC calculation may be done. In fact, the CRC is sensitive - to the SCK slave input clock as soon as CRCEN is set, and this, whatever - the value of the SPE bit. - -@note With high bitrate frequencies, be careful when transmitting the CRC. - As the number of used CPU cycles has to be as low as possible in the CRC - transfer phase, it is forbidden to call software functions in the CRC - transmission sequence to avoid errors in the last data and CRC reception. - In fact, CRCNEXT bit has to be written before the end of the transmission/reception - of the last data. - -@note For high bit rate frequencies, it is advised to use the DMA mode to avoid the - degradation of the SPI speed performance due to CPU accesses impacting the - SPI bandwidth. - -@note When the STM32F4xx is configured as slave and the NSS hardware mode is - used, the NSS pin needs to be kept low between the data phase and the CRC - phase. - -@note When the SPI is configured in slave mode with the CRC feature enabled, CRC - calculation takes place even if a high level is applied on the NSS pin. - This may happen for example in case of a multi-slave environment where the - communication master addresses slaves alternately. - -@note Between a slave de-selection (high level on NSS) and a new slave selection - (low level on NSS), the CRC value should be cleared on both master and slave - sides in order to resynchronize the master and slave for their respective - CRC calculation. - -@note To clear the CRC, follow the procedure below: - 1. Disable SPI using the SPI_Cmd() function - 2. Disable the CRC calculation using the SPI_CalculateCRC() function. - 3. Enable the CRC calculation using the SPI_CalculateCRC() function. - 4. Enable SPI using the SPI_Cmd() function. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the CRC value calculation of the transferred bytes. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param NewState: new state of the SPIx CRC value calculation. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the selected SPI CRC calculation */ - SPIx->CR1 |= SPI_CR1_CRCEN; - } - else - { - /* Disable the selected SPI CRC calculation */ - SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCEN); - } -} - -/** - * @brief Transmit the SPIx CRC value. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @retval None - */ -void SPI_TransmitCRC(SPI_TypeDef* SPIx) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - /* Enable the selected SPI CRC transmission */ - SPIx->CR1 |= SPI_CR1_CRCNEXT; -} - -/** - * @brief Returns the transmit or the receive CRC register value for the specified SPI. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @param SPI_CRC: specifies the CRC register to be read. - * This parameter can be one of the following values: - * @arg SPI_CRC_Tx: Selects Tx CRC register - * @arg SPI_CRC_Rx: Selects Rx CRC register - * @retval The selected CRC register value.. - */ -uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC) -{ - uint16_t crcreg = 0; - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - assert_param(IS_SPI_CRC(SPI_CRC)); - if (SPI_CRC != SPI_CRC_Rx) - { - /* Get the Tx CRC register */ - crcreg = SPIx->TXCRCR; - } - else - { - /* Get the Rx CRC register */ - crcreg = SPIx->RXCRCR; - } - /* Return the selected CRC register */ - return crcreg; -} - -/** - * @brief Returns the CRC Polynomial register value for the specified SPI. - * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral. - * @retval The CRC Polynomial register value. - */ -uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH(SPIx)); - - /* Return the CRC polynomial register */ - return SPIx->CRCPR; -} - -/** - * @} - */ - -/** @defgroup SPI_Group4 DMA transfers management functions - * @brief DMA transfers management functions - * -@verbatim - =============================================================================== - DMA transfers management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the SPIx/I2Sx DMA interface. - * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 - * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. - * @param SPI_I2S_DMAReq: specifies the SPI DMA transfer request to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request - * @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request - * @param NewState: new state of the selected SPI DMA transfer request. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_SPI_I2S_DMAREQ(SPI_I2S_DMAReq)); - - if (NewState != DISABLE) - { - /* Enable the selected SPI DMA requests */ - SPIx->CR2 |= SPI_I2S_DMAReq; - } - else - { - /* Disable the selected SPI DMA requests */ - SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq; - } -} - -/** - * @} - */ - -/** @defgroup SPI_Group5 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - - This section provides a set of functions allowing to configure the SPI Interrupts - sources and check or clear the flags or pending bits status. - The user should identify which mode will be used in his application to manage - the communication: Polling mode, Interrupt mode or DMA mode. - - Polling Mode - ============= - In Polling Mode, the SPI/I2S communication can be managed by 9 flags: - 1. SPI_I2S_FLAG_TXE : to indicate the status of the transmit buffer register - 2. SPI_I2S_FLAG_RXNE : to indicate the status of the receive buffer register - 3. SPI_I2S_FLAG_BSY : to indicate the state of the communication layer of the SPI. - 4. SPI_FLAG_CRCERR : to indicate if a CRC Calculation error occur - 5. SPI_FLAG_MODF : to indicate if a Mode Fault error occur - 6. SPI_I2S_FLAG_OVR : to indicate if an Overrun error occur - 7. I2S_FLAG_TIFRFE: to indicate a Frame Format error occurs. - 8. I2S_FLAG_UDR: to indicate an Underrun error occurs. - 9. I2S_FLAG_CHSIDE: to indicate Channel Side. - -@note Do not use the BSY flag to handle each data transmission or reception. It is - better to use the TXE and RXNE flags instead. - - In this Mode it is advised to use the following functions: - - FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); - - void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); - - Interrupt Mode - =============== - In Interrupt Mode, the SPI communication can be managed by 3 interrupt sources - and 7 pending bits: - Pending Bits: - ------------- - 1. SPI_I2S_IT_TXE : to indicate the status of the transmit buffer register - 2. SPI_I2S_IT_RXNE : to indicate the status of the receive buffer register - 3. SPI_IT_CRCERR : to indicate if a CRC Calculation error occur (available in SPI mode only) - 4. SPI_IT_MODF : to indicate if a Mode Fault error occur (available in SPI mode only) - 5. SPI_I2S_IT_OVR : to indicate if an Overrun error occur - 6. I2S_IT_UDR : to indicate an Underrun Error occurs (available in I2S mode only). - 7. I2S_FLAG_TIFRFE : to indicate a Frame Format error occurs (available in TI mode only). - - Interrupt Source: - ----------------- - 1. SPI_I2S_IT_TXE: specifies the interrupt source for the Tx buffer empty - interrupt. - 2. SPI_I2S_IT_RXNE : specifies the interrupt source for the Rx buffer not - empty interrupt. - 3. SPI_I2S_IT_ERR : specifies the interrupt source for the errors interrupt. - - In this Mode it is advised to use the following functions: - - void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState); - - ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); - - void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); - - DMA Mode - ======== - In DMA Mode, the SPI communication can be managed by 2 DMA Channel requests: - 1. SPI_I2S_DMAReq_Tx: specifies the Tx buffer DMA transfer request - 2. SPI_I2S_DMAReq_Rx: specifies the Rx buffer DMA transfer request - - In this Mode it is advised to use the following function: - - void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState); - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified SPI/I2S interrupts. - * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 - * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. - * @param SPI_I2S_IT: specifies the SPI interrupt source to be enabled or disabled. - * This parameter can be one of the following values: - * @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask - * @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask - * @arg SPI_I2S_IT_ERR: Error interrupt mask - * @param NewState: new state of the specified SPI interrupt. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState) -{ - uint16_t itpos = 0, itmask = 0 ; - - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT)); - - /* Get the SPI IT index */ - itpos = SPI_I2S_IT >> 4; - - /* Set the IT mask */ - itmask = (uint16_t)1 << (uint16_t)itpos; - - if (NewState != DISABLE) - { - /* Enable the selected SPI interrupt */ - SPIx->CR2 |= itmask; - } - else - { - /* Disable the selected SPI interrupt */ - SPIx->CR2 &= (uint16_t)~itmask; - } -} - -/** - * @brief Checks whether the specified SPIx/I2Sx flag is set or not. - * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 - * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. - * @param SPI_I2S_FLAG: specifies the SPI flag to check. - * This parameter can be one of the following values: - * @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag. - * @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag. - * @arg SPI_I2S_FLAG_BSY: Busy flag. - * @arg SPI_I2S_FLAG_OVR: Overrun flag. - * @arg SPI_FLAG_MODF: Mode Fault flag. - * @arg SPI_FLAG_CRCERR: CRC Error flag. - * @arg SPI_I2S_FLAG_TIFRFE: Format Error. - * @arg I2S_FLAG_UDR: Underrun Error flag. - * @arg I2S_FLAG_CHSIDE: Channel Side flag. - * @retval The new state of SPI_I2S_FLAG (SET or RESET). - */ -FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); - assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG)); - - /* Check the status of the specified SPI flag */ - if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET) - { - /* SPI_I2S_FLAG is set */ - bitstatus = SET; - } - else - { - /* SPI_I2S_FLAG is reset */ - bitstatus = RESET; - } - /* Return the SPI_I2S_FLAG status */ - return bitstatus; -} - -/** - * @brief Clears the SPIx CRC Error (CRCERR) flag. - * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 - * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. - * @param SPI_I2S_FLAG: specifies the SPI flag to clear. - * This function clears only CRCERR flag. - * @arg SPI_FLAG_CRCERR: CRC Error flag. - * - * @note OVR (OverRun error) flag is cleared by software sequence: a read - * operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by a read - * operation to SPI_SR register (SPI_I2S_GetFlagStatus()). - * @note UDR (UnderRun error) flag is cleared by a read operation to - * SPI_SR register (SPI_I2S_GetFlagStatus()). - * @note MODF (Mode Fault) flag is cleared by software sequence: a read/write - * operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by a - * write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI). - * - * @retval None - */ -void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG) -{ - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); - assert_param(IS_SPI_I2S_CLEAR_FLAG(SPI_I2S_FLAG)); - - /* Clear the selected SPI CRC Error (CRCERR) flag */ - SPIx->SR = (uint16_t)~SPI_I2S_FLAG; -} - -/** - * @brief Checks whether the specified SPIx/I2Sx interrupt has occurred or not. - * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 - * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. - * @param SPI_I2S_IT: specifies the SPI interrupt source to check. - * This parameter can be one of the following values: - * @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt. - * @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt. - * @arg SPI_I2S_IT_OVR: Overrun interrupt. - * @arg SPI_IT_MODF: Mode Fault interrupt. - * @arg SPI_IT_CRCERR: CRC Error interrupt. - * @arg I2S_IT_UDR: Underrun interrupt. - * @arg SPI_I2S_IT_TIFRFE: Format Error interrupt. - * @retval The new state of SPI_I2S_IT (SET or RESET). - */ -ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT) -{ - ITStatus bitstatus = RESET; - uint16_t itpos = 0, itmask = 0, enablestatus = 0; - - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); - assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT)); - - /* Get the SPI_I2S_IT index */ - itpos = 0x01 << (SPI_I2S_IT & 0x0F); - - /* Get the SPI_I2S_IT IT mask */ - itmask = SPI_I2S_IT >> 4; - - /* Set the IT mask */ - itmask = 0x01 << itmask; - - /* Get the SPI_I2S_IT enable bit status */ - enablestatus = (SPIx->CR2 & itmask) ; - - /* Check the status of the specified SPI interrupt */ - if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus) - { - /* SPI_I2S_IT is set */ - bitstatus = SET; - } - else - { - /* SPI_I2S_IT is reset */ - bitstatus = RESET; - } - /* Return the SPI_I2S_IT status */ - return bitstatus; -} - -/** - * @brief Clears the SPIx CRC Error (CRCERR) interrupt pending bit. - * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3 - * in SPI mode or 2 or 3 in I2S mode or I2Sxext for I2S full duplex mode. - * @param SPI_I2S_IT: specifies the SPI interrupt pending bit to clear. - * This function clears only CRCERR interrupt pending bit. - * @arg SPI_IT_CRCERR: CRC Error interrupt. - * - * @note OVR (OverRun Error) interrupt pending bit is cleared by software - * sequence: a read operation to SPI_DR register (SPI_I2S_ReceiveData()) - * followed by a read operation to SPI_SR register (SPI_I2S_GetITStatus()). - * @note UDR (UnderRun Error) interrupt pending bit is cleared by a read - * operation to SPI_SR register (SPI_I2S_GetITStatus()). - * @note MODF (Mode Fault) interrupt pending bit is cleared by software sequence: - * a read/write operation to SPI_SR register (SPI_I2S_GetITStatus()) - * followed by a write operation to SPI_CR1 register (SPI_Cmd() to enable - * the SPI). - * @retval None - */ -void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT) -{ - uint16_t itpos = 0; - /* Check the parameters */ - assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx)); - assert_param(IS_SPI_I2S_CLEAR_IT(SPI_I2S_IT)); - - /* Get the SPI_I2S IT index */ - itpos = 0x01 << (SPI_I2S_IT & 0x0F); - - /* Clear the selected SPI CRC Error (CRCERR) interrupt pending bit */ - SPIx->SR = (uint16_t)~itpos; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c deleted file mode 100644 index 0aa22b42f..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c +++ /dev/null @@ -1,204 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_syscfg.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the SYSCFG peripheral. - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * - * This driver provides functions for: - * - * 1. Remapping the memory accessible in the code area using SYSCFG_MemoryRemapConfig() - * - * 2. Manage the EXTI lines connection to the GPIOs using SYSCFG_EXTILineConfig() - * - * 3. Select the ETHERNET media interface (RMII/RII) using SYSCFG_ETH_MediaInterfaceConfig() - * - * @note SYSCFG APB clock must be enabled to get write access to SYSCFG registers, - * using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_syscfg.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup SYSCFG - * @brief SYSCFG driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* ------------ RCC registers bit address in the alias region ----------- */ -#define SYSCFG_OFFSET (SYSCFG_BASE - PERIPH_BASE) -/* --- PMC Register ---*/ -/* Alias word address of MII_RMII_SEL bit */ -#define PMC_OFFSET (SYSCFG_OFFSET + 0x04) -#define MII_RMII_SEL_BitNumber ((uint8_t)0x17) -#define PMC_MII_RMII_SEL_BB (PERIPH_BB_BASE + (PMC_OFFSET * 32) + (MII_RMII_SEL_BitNumber * 4)) - -/* --- CMPCR Register ---*/ -/* Alias word address of CMP_PD bit */ -#define CMPCR_OFFSET (SYSCFG_OFFSET + 0x20) -#define CMP_PD_BitNumber ((uint8_t)0x00) -#define CMPCR_CMP_PD_BB (PERIPH_BB_BASE + (CMPCR_OFFSET * 32) + (CMP_PD_BitNumber * 4)) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup SYSCFG_Private_Functions - * @{ - */ - -/** - * @brief Deinitializes the Alternate Functions (remap and EXTI configuration) - * registers to their default reset values. - * @param None - * @retval None - */ -void SYSCFG_DeInit(void) -{ - RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, DISABLE); -} - -/** - * @brief Changes the mapping of the specified pin. - * @param SYSCFG_Memory: selects the memory remapping. - * This parameter can be one of the following values: - * @arg SYSCFG_MemoryRemap_Flash: Main Flash memory mapped at 0x00000000 - * @arg SYSCFG_MemoryRemap_SystemFlash: System Flash memory mapped at 0x00000000 - * @arg SYSCFG_MemoryRemap_FSMC: FSMC (Bank1 (NOR/PSRAM 1 and 2) mapped at 0x00000000 - * @arg SYSCFG_MemoryRemap_SRAM: Embedded SRAM (112kB) mapped at 0x00000000 - * - * @note In remap mode, the FSMC addressing is fixed to the remap address area only - * (Bank1 NOR/PSRAM 1 and NOR/PSRAM 2) and FSMC control registers are not - * accessible. The FSMC remap function must be disabled to allows addressing - * other memory devices through the FSMC and/or to access FSMC control - * registers. - * - * @retval None - */ -void SYSCFG_MemoryRemapConfig(uint8_t SYSCFG_MemoryRemap) -{ - /* Check the parameters */ - assert_param(IS_SYSCFG_MEMORY_REMAP_CONFING(SYSCFG_MemoryRemap)); - - SYSCFG->MEMRMP = SYSCFG_MemoryRemap; -} - -/** - * @brief Selects the GPIO pin used as EXTI Line. - * @param EXTI_PortSourceGPIOx : selects the GPIO port to be used as source for - * EXTI lines where x can be (A..I). - * @param EXTI_PinSourcex: specifies the EXTI line to be configured. - * This parameter can be EXTI_PinSourcex where x can be (0..15, except - * for EXTI_PortSourceGPIOI x can be (0..11). - * @retval None - */ -void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex) -{ - uint32_t tmp = 0x00; - - /* Check the parameters */ - assert_param(IS_EXTI_PORT_SOURCE(EXTI_PortSourceGPIOx)); - assert_param(IS_EXTI_PIN_SOURCE(EXTI_PinSourcex)); - - tmp = ((uint32_t)0x0F) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03)); - SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] &= ~tmp; - SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] |= (((uint32_t)EXTI_PortSourceGPIOx) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03))); -} - -/** - * @brief Selects the ETHERNET media interface - * @param SYSCFG_ETH_MediaInterface: specifies the Media Interface mode. - * This parameter can be one of the following values: - * @arg SYSCFG_ETH_MediaInterface_MII: MII mode selected - * @arg SYSCFG_ETH_MediaInterface_RMII: RMII mode selected - * @retval None - */ -void SYSCFG_ETH_MediaInterfaceConfig(uint32_t SYSCFG_ETH_MediaInterface) -{ - assert_param(IS_SYSCFG_ETH_MEDIA_INTERFACE(SYSCFG_ETH_MediaInterface)); - /* Configure MII_RMII selection bit */ - *(__IO uint32_t *) PMC_MII_RMII_SEL_BB = SYSCFG_ETH_MediaInterface; -} - -/** - * @brief Enables or disables the I/O Compensation Cell. - * @note The I/O compensation cell can be used only when the device supply - * voltage ranges from 2.4 to 3.6 V. - * @param NewState: new state of the I/O Compensation Cell. - * This parameter can be one of the following values: - * @arg ENABLE: I/O compensation cell enabled - * @arg DISABLE: I/O compensation cell power-down mode - * @retval None - */ -void SYSCFG_CompensationCellCmd(FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - *(__IO uint32_t *) CMPCR_CMP_PD_BB = (uint32_t)NewState; -} - -/** - * @brief Checks whether the I/O Compensation Cell ready flag is set or not. - * @param None - * @retval The new state of the I/O Compensation Cell ready flag (SET or RESET) - */ -FlagStatus SYSCFG_GetCompensationCellStatus(void) -{ - FlagStatus bitstatus = RESET; - - if ((SYSCFG->CMPCR & SYSCFG_CMPCR_READY ) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.c deleted file mode 100644 index 711a66df7..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.c +++ /dev/null @@ -1,3349 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_tim.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the TIM peripheral: - * - TimeBase management - * - Output Compare management - * - Input Capture management - * - Advanced-control timers (TIM1 and TIM8) specific features - * - Interrupts, DMA and flags management - * - Clocks management - * - Synchronization management - * - Specific interface management - * - Specific remapping management - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * This driver provides functions to configure and program the TIM - * of all STM32F4xx devices. - * These functions are split in 9 groups: - * - * 1. TIM TimeBase management: this group includes all needed functions - * to configure the TM Timebase unit: - * - Set/Get Prescaler - * - Set/Get Autoreload - * - Counter modes configuration - * - Set Clock division - * - Select the One Pulse mode - * - Update Request Configuration - * - Update Disable Configuration - * - Auto-Preload Configuration - * - Enable/Disable the counter - * - * 2. TIM Output Compare management: this group includes all needed - * functions to configure the Capture/Compare unit used in Output - * compare mode: - * - Configure each channel, independently, in Output Compare mode - * - Select the output compare modes - * - Select the Polarities of each channel - * - Set/Get the Capture/Compare register values - * - Select the Output Compare Fast mode - * - Select the Output Compare Forced mode - * - Output Compare-Preload Configuration - * - Clear Output Compare Reference - * - Select the OCREF Clear signal - * - Enable/Disable the Capture/Compare Channels - * - * 3. TIM Input Capture management: this group includes all needed - * functions to configure the Capture/Compare unit used in - * Input Capture mode: - * - Configure each channel in input capture mode - * - Configure Channel1/2 in PWM Input mode - * - Set the Input Capture Prescaler - * - Get the Capture/Compare values - * - * 4. Advanced-control timers (TIM1 and TIM8) specific features - * - Configures the Break input, dead time, Lock level, the OSSI, - * the OSSR State and the AOE(automatic output enable) - * - Enable/Disable the TIM peripheral Main Outputs - * - Select the Commutation event - * - Set/Reset the Capture Compare Preload Control bit - * - * 5. TIM interrupts, DMA and flags management - * - Enable/Disable interrupt sources - * - Get flags status - * - Clear flags/ Pending bits - * - Enable/Disable DMA requests - * - Configure DMA burst mode - * - Select CaptureCompare DMA request - * - * 6. TIM clocks management: this group includes all needed functions - * to configure the clock controller unit: - * - Select internal/External clock - * - Select the external clock mode: ETR(Mode1/Mode2), TIx or ITRx - * - * 7. TIM synchronization management: this group includes all needed - * functions to configure the Synchronization unit: - * - Select Input Trigger - * - Select Output Trigger - * - Select Master Slave Mode - * - ETR Configuration when used as external trigger - * - * 8. TIM specific interface management, this group includes all - * needed functions to use the specific TIM interface: - * - Encoder Interface Configuration - * - Select Hall Sensor - * - * 9. TIM specific remapping management includes the Remapping - * configuration of specific timers - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_tim.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup TIM - * @brief TIM driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* ---------------------- TIM registers bit mask ------------------------ */ -#define SMCR_ETR_MASK ((uint16_t)0x00FF) -#define CCMR_OFFSET ((uint16_t)0x0018) -#define CCER_CCE_SET ((uint16_t)0x0001) -#define CCER_CCNE_SET ((uint16_t)0x0004) -#define CCMR_OC13M_MASK ((uint16_t)0xFF8F) -#define CCMR_OC24M_MASK ((uint16_t)0x8FFF) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter); -static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter); -static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter); -static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter); - -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup TIM_Private_Functions - * @{ - */ - -/** @defgroup TIM_Group1 TimeBase management functions - * @brief TimeBase management functions - * -@verbatim - =============================================================================== - TimeBase management functions - =============================================================================== - - =================================================================== - TIM Driver: how to use it in Timing(Time base) Mode - =================================================================== - To use the Timer in Timing(Time base) mode, the following steps are mandatory: - - 1. Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function - - 2. Fill the TIM_TimeBaseInitStruct with the desired parameters. - - 3. Call TIM_TimeBaseInit(TIMx, &TIM_TimeBaseInitStruct) to configure the Time Base unit - with the corresponding configuration - - 4. Enable the NVIC if you need to generate the update interrupt. - - 5. Enable the corresponding interrupt using the function TIM_ITConfig(TIMx, TIM_IT_Update) - - 6. Call the TIM_Cmd(ENABLE) function to enable the TIM counter. - - Note1: All other functions can be used separately to modify, if needed, - a specific feature of the Timer. - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the TIMx peripheral registers to their default reset values. - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @retval None - - */ -void TIM_DeInit(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - - if (TIMx == TIM1) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, DISABLE); - } - else if (TIMx == TIM2) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, DISABLE); - } - else if (TIMx == TIM3) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, DISABLE); - } - else if (TIMx == TIM4) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, DISABLE); - } - else if (TIMx == TIM5) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, DISABLE); - } - else if (TIMx == TIM6) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, DISABLE); - } - else if (TIMx == TIM7) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, DISABLE); - } - else if (TIMx == TIM8) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, DISABLE); - } - else if (TIMx == TIM9) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, DISABLE); - } - else if (TIMx == TIM10) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, DISABLE); - } - else if (TIMx == TIM11) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, DISABLE); - } - else if (TIMx == TIM12) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, DISABLE); - } - else if (TIMx == TIM13) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, DISABLE); - } - else - { - if (TIMx == TIM14) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, DISABLE); - } - } -} - -/** - * @brief Initializes the TIMx Time Base Unit peripheral according to - * the specified parameters in the TIM_TimeBaseInitStruct. - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef structure - * that contains the configuration information for the specified TIM peripheral. - * @retval None - */ -void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) -{ - uint16_t tmpcr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode)); - assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision)); - - tmpcr1 = TIMx->CR1; - - if((TIMx == TIM1) || (TIMx == TIM8)|| - (TIMx == TIM2) || (TIMx == TIM3)|| - (TIMx == TIM4) || (TIMx == TIM5)) - { - /* Select the Counter Mode */ - tmpcr1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS)); - tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode; - } - - if((TIMx != TIM6) && (TIMx != TIM7)) - { - /* Set the clock division */ - tmpcr1 &= (uint16_t)(~TIM_CR1_CKD); - tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision; - } - - TIMx->CR1 = tmpcr1; - - /* Set the Autoreload value */ - TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ; - - /* Set the Prescaler value */ - TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler; - - if ((TIMx == TIM1) || (TIMx == TIM8)) - { - /* Set the Repetition Counter value */ - TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter; - } - - /* Generate an update event to reload the Prescaler - and the repetition counter(only for TIM1 and TIM8) value immediatly */ - TIMx->EGR = TIM_PSCReloadMode_Immediate; -} - -/** - * @brief Fills each TIM_TimeBaseInitStruct member with its default value. - * @param TIM_TimeBaseInitStruct : pointer to a TIM_TimeBaseInitTypeDef - * structure which will be initialized. - * @retval None - */ -void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) -{ - /* Set the default configuration */ - TIM_TimeBaseInitStruct->TIM_Period = 0xFFFFFFFF; - TIM_TimeBaseInitStruct->TIM_Prescaler = 0x0000; - TIM_TimeBaseInitStruct->TIM_ClockDivision = TIM_CKD_DIV1; - TIM_TimeBaseInitStruct->TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseInitStruct->TIM_RepetitionCounter = 0x0000; -} - -/** - * @brief Configures the TIMx Prescaler. - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @param Prescaler: specifies the Prescaler Register value - * @param TIM_PSCReloadMode: specifies the TIM Prescaler Reload mode - * This parameter can be one of the following values: - * @arg TIM_PSCReloadMode_Update: The Prescaler is loaded at the update event. - * @arg TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediatly. - * @retval None - */ -void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_PRESCALER_RELOAD(TIM_PSCReloadMode)); - /* Set the Prescaler value */ - TIMx->PSC = Prescaler; - /* Set or reset the UG Bit */ - TIMx->EGR = TIM_PSCReloadMode; -} - -/** - * @brief Specifies the TIMx Counter Mode to be used. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_CounterMode: specifies the Counter Mode to be used - * This parameter can be one of the following values: - * @arg TIM_CounterMode_Up: TIM Up Counting Mode - * @arg TIM_CounterMode_Down: TIM Down Counting Mode - * @arg TIM_CounterMode_CenterAligned1: TIM Center Aligned Mode1 - * @arg TIM_CounterMode_CenterAligned2: TIM Center Aligned Mode2 - * @arg TIM_CounterMode_CenterAligned3: TIM Center Aligned Mode3 - * @retval None - */ -void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode) -{ - uint16_t tmpcr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_COUNTER_MODE(TIM_CounterMode)); - - tmpcr1 = TIMx->CR1; - - /* Reset the CMS and DIR Bits */ - tmpcr1 &= (uint16_t)~(TIM_CR1_DIR | TIM_CR1_CMS); - - /* Set the Counter Mode */ - tmpcr1 |= TIM_CounterMode; - - /* Write to TIMx CR1 register */ - TIMx->CR1 = tmpcr1; -} - -/** - * @brief Sets the TIMx Counter Register value - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @param Counter: specifies the Counter register new value. - * @retval None - */ -void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - - /* Set the Counter Register value */ - TIMx->CNT = Counter; -} - -/** - * @brief Sets the TIMx Autoreload Register value - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @param Autoreload: specifies the Autoreload register new value. - * @retval None - */ -void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - - /* Set the Autoreload Register value */ - TIMx->ARR = Autoreload; -} - -/** - * @brief Gets the TIMx Counter value. - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @retval Counter Register value - */ -uint32_t TIM_GetCounter(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - - /* Get the Counter Register value */ - return TIMx->CNT; -} - -/** - * @brief Gets the TIMx Prescaler value. - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @retval Prescaler Register value. - */ -uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - - /* Get the Prescaler Register value */ - return TIMx->PSC; -} - -/** - * @brief Enables or Disables the TIMx Update event. - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @param NewState: new state of the TIMx UDIS bit - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Set the Update Disable Bit */ - TIMx->CR1 |= TIM_CR1_UDIS; - } - else - { - /* Reset the Update Disable Bit */ - TIMx->CR1 &= (uint16_t)~TIM_CR1_UDIS; - } -} - -/** - * @brief Configures the TIMx Update Request Interrupt source. - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @param TIM_UpdateSource: specifies the Update source. - * This parameter can be one of the following values: - * @arg TIM_UpdateSource_Regular: Source of update is the counter - * overflow/underflow or the setting of UG bit, or an update - * generation through the slave mode controller. - * @arg TIM_UpdateSource_Global: Source of update is counter overflow/underflow. - * @retval None - */ -void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_UPDATE_SOURCE(TIM_UpdateSource)); - - if (TIM_UpdateSource != TIM_UpdateSource_Global) - { - /* Set the URS Bit */ - TIMx->CR1 |= TIM_CR1_URS; - } - else - { - /* Reset the URS Bit */ - TIMx->CR1 &= (uint16_t)~TIM_CR1_URS; - } -} - -/** - * @brief Enables or disables TIMx peripheral Preload register on ARR. - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @param NewState: new state of the TIMx peripheral Preload register - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Set the ARR Preload Bit */ - TIMx->CR1 |= TIM_CR1_ARPE; - } - else - { - /* Reset the ARR Preload Bit */ - TIMx->CR1 &= (uint16_t)~TIM_CR1_ARPE; - } -} - -/** - * @brief Selects the TIMx's One Pulse Mode. - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @param TIM_OPMode: specifies the OPM Mode to be used. - * This parameter can be one of the following values: - * @arg TIM_OPMode_Single - * @arg TIM_OPMode_Repetitive - * @retval None - */ -void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_OPM_MODE(TIM_OPMode)); - - /* Reset the OPM Bit */ - TIMx->CR1 &= (uint16_t)~TIM_CR1_OPM; - - /* Configure the OPM Mode */ - TIMx->CR1 |= TIM_OPMode; -} - -/** - * @brief Sets the TIMx Clock Division value. - * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. - * @param TIM_CKD: specifies the clock division value. - * This parameter can be one of the following value: - * @arg TIM_CKD_DIV1: TDTS = Tck_tim - * @arg TIM_CKD_DIV2: TDTS = 2*Tck_tim - * @arg TIM_CKD_DIV4: TDTS = 4*Tck_tim - * @retval None - */ -void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_CKD_DIV(TIM_CKD)); - - /* Reset the CKD Bits */ - TIMx->CR1 &= (uint16_t)(~TIM_CR1_CKD); - - /* Set the CKD value */ - TIMx->CR1 |= TIM_CKD; -} - -/** - * @brief Enables or disables the specified TIM peripheral. - * @param TIMx: where x can be 1 to 14 to select the TIMx peripheral. - * @param NewState: new state of the TIMx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the TIM Counter */ - TIMx->CR1 |= TIM_CR1_CEN; - } - else - { - /* Disable the TIM Counter */ - TIMx->CR1 &= (uint16_t)~TIM_CR1_CEN; - } -} -/** - * @} - */ - -/** @defgroup TIM_Group2 Output Compare management functions - * @brief Output Compare management functions - * -@verbatim - =============================================================================== - Output Compare management functions - =============================================================================== - - =================================================================== - TIM Driver: how to use it in Output Compare Mode - =================================================================== - To use the Timer in Output Compare mode, the following steps are mandatory: - - 1. Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function - - 2. Configure the TIM pins by configuring the corresponding GPIO pins - - 2. Configure the Time base unit as described in the first part of this driver, - if needed, else the Timer will run with the default configuration: - - Autoreload value = 0xFFFF - - Prescaler value = 0x0000 - - Counter mode = Up counting - - Clock Division = TIM_CKD_DIV1 - - 3. Fill the TIM_OCInitStruct with the desired parameters including: - - The TIM Output Compare mode: TIM_OCMode - - TIM Output State: TIM_OutputState - - TIM Pulse value: TIM_Pulse - - TIM Output Compare Polarity : TIM_OCPolarity - - 4. Call TIM_OCxInit(TIMx, &TIM_OCInitStruct) to configure the desired channel with the - corresponding configuration - - 5. Call the TIM_Cmd(ENABLE) function to enable the TIM counter. - - Note1: All other functions can be used separately to modify, if needed, - a specific feature of the Timer. - - Note2: In case of PWM mode, this function is mandatory: - TIM_OCxPreloadConfig(TIMx, TIM_OCPreload_ENABLE); - - Note3: If the corresponding interrupt or DMA request are needed, the user should: - 1. Enable the NVIC (or the DMA) to use the TIM interrupts (or DMA requests). - 2. Enable the corresponding interrupt (or DMA request) using the function - TIM_ITConfig(TIMx, TIM_IT_CCx) (or TIM_DMA_Cmd(TIMx, TIM_DMA_CCx)) - -@endverbatim - * @{ - */ - -/** - * @brief Initializes the TIMx Channel1 according to the specified parameters in - * the TIM_OCInitStruct. - * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. - * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains - * the configuration information for the specified TIM peripheral. - * @retval None - */ -void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); - assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); - - /* Disable the Channel 1: Reset the CC1E Bit */ - TIMx->CCER &= (uint16_t)~TIM_CCER_CC1E; - - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - /* Get the TIMx CR2 register value */ - tmpcr2 = TIMx->CR2; - - /* Get the TIMx CCMR1 register value */ - tmpccmrx = TIMx->CCMR1; - - /* Reset the Output Compare Mode Bits */ - tmpccmrx &= (uint16_t)~TIM_CCMR1_OC1M; - tmpccmrx &= (uint16_t)~TIM_CCMR1_CC1S; - /* Select the Output Compare Mode */ - tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; - - /* Reset the Output Polarity level */ - tmpccer &= (uint16_t)~TIM_CCER_CC1P; - /* Set the Output Compare Polarity */ - tmpccer |= TIM_OCInitStruct->TIM_OCPolarity; - - /* Set the Output State */ - tmpccer |= TIM_OCInitStruct->TIM_OutputState; - - if((TIMx == TIM1) || (TIMx == TIM8)) - { - assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); - assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); - assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); - assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); - - /* Reset the Output N Polarity level */ - tmpccer &= (uint16_t)~TIM_CCER_CC1NP; - /* Set the Output N Polarity */ - tmpccer |= TIM_OCInitStruct->TIM_OCNPolarity; - /* Reset the Output N State */ - tmpccer &= (uint16_t)~TIM_CCER_CC1NE; - - /* Set the Output N State */ - tmpccer |= TIM_OCInitStruct->TIM_OutputNState; - /* Reset the Output Compare and Output Compare N IDLE State */ - tmpcr2 &= (uint16_t)~TIM_CR2_OIS1; - tmpcr2 &= (uint16_t)~TIM_CR2_OIS1N; - /* Set the Output Idle state */ - tmpcr2 |= TIM_OCInitStruct->TIM_OCIdleState; - /* Set the Output N Idle state */ - tmpcr2 |= TIM_OCInitStruct->TIM_OCNIdleState; - } - /* Write to TIMx CR2 */ - TIMx->CR2 = tmpcr2; - - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmrx; - - /* Set the Capture Compare Register value */ - TIMx->CCR1 = TIM_OCInitStruct->TIM_Pulse; - - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Initializes the TIMx Channel2 according to the specified parameters - * in the TIM_OCInitStruct. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM - * peripheral. - * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains - * the configuration information for the specified TIM peripheral. - * @retval None - */ -void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); - assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); - - /* Disable the Channel 2: Reset the CC2E Bit */ - TIMx->CCER &= (uint16_t)~TIM_CCER_CC2E; - - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - /* Get the TIMx CR2 register value */ - tmpcr2 = TIMx->CR2; - - /* Get the TIMx CCMR1 register value */ - tmpccmrx = TIMx->CCMR1; - - /* Reset the Output Compare mode and Capture/Compare selection Bits */ - tmpccmrx &= (uint16_t)~TIM_CCMR1_OC2M; - tmpccmrx &= (uint16_t)~TIM_CCMR1_CC2S; - - /* Select the Output Compare Mode */ - tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8); - - /* Reset the Output Polarity level */ - tmpccer &= (uint16_t)~TIM_CCER_CC2P; - /* Set the Output Compare Polarity */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 4); - - /* Set the Output State */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 4); - - if((TIMx == TIM1) || (TIMx == TIM8)) - { - assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); - assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); - assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); - assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); - - /* Reset the Output N Polarity level */ - tmpccer &= (uint16_t)~TIM_CCER_CC2NP; - /* Set the Output N Polarity */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 4); - /* Reset the Output N State */ - tmpccer &= (uint16_t)~TIM_CCER_CC2NE; - - /* Set the Output N State */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 4); - /* Reset the Output Compare and Output Compare N IDLE State */ - tmpcr2 &= (uint16_t)~TIM_CR2_OIS2; - tmpcr2 &= (uint16_t)~TIM_CR2_OIS2N; - /* Set the Output Idle state */ - tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 2); - /* Set the Output N Idle state */ - tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 2); - } - /* Write to TIMx CR2 */ - TIMx->CR2 = tmpcr2; - - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmrx; - - /* Set the Capture Compare Register value */ - TIMx->CCR2 = TIM_OCInitStruct->TIM_Pulse; - - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Initializes the TIMx Channel3 according to the specified parameters - * in the TIM_OCInitStruct. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains - * the configuration information for the specified TIM peripheral. - * @retval None - */ -void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); - assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); - - /* Disable the Channel 3: Reset the CC2E Bit */ - TIMx->CCER &= (uint16_t)~TIM_CCER_CC3E; - - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - /* Get the TIMx CR2 register value */ - tmpcr2 = TIMx->CR2; - - /* Get the TIMx CCMR2 register value */ - tmpccmrx = TIMx->CCMR2; - - /* Reset the Output Compare mode and Capture/Compare selection Bits */ - tmpccmrx &= (uint16_t)~TIM_CCMR2_OC3M; - tmpccmrx &= (uint16_t)~TIM_CCMR2_CC3S; - /* Select the Output Compare Mode */ - tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; - - /* Reset the Output Polarity level */ - tmpccer &= (uint16_t)~TIM_CCER_CC3P; - /* Set the Output Compare Polarity */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 8); - - /* Set the Output State */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 8); - - if((TIMx == TIM1) || (TIMx == TIM8)) - { - assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); - assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); - assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); - assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); - - /* Reset the Output N Polarity level */ - tmpccer &= (uint16_t)~TIM_CCER_CC3NP; - /* Set the Output N Polarity */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 8); - /* Reset the Output N State */ - tmpccer &= (uint16_t)~TIM_CCER_CC3NE; - - /* Set the Output N State */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 8); - /* Reset the Output Compare and Output Compare N IDLE State */ - tmpcr2 &= (uint16_t)~TIM_CR2_OIS3; - tmpcr2 &= (uint16_t)~TIM_CR2_OIS3N; - /* Set the Output Idle state */ - tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 4); - /* Set the Output N Idle state */ - tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 4); - } - /* Write to TIMx CR2 */ - TIMx->CR2 = tmpcr2; - - /* Write to TIMx CCMR2 */ - TIMx->CCMR2 = tmpccmrx; - - /* Set the Capture Compare Register value */ - TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse; - - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Initializes the TIMx Channel4 according to the specified parameters - * in the TIM_OCInitStruct. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains - * the configuration information for the specified TIM peripheral. - * @retval None - */ -void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); - assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); - - /* Disable the Channel 4: Reset the CC4E Bit */ - TIMx->CCER &= (uint16_t)~TIM_CCER_CC4E; - - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - /* Get the TIMx CR2 register value */ - tmpcr2 = TIMx->CR2; - - /* Get the TIMx CCMR2 register value */ - tmpccmrx = TIMx->CCMR2; - - /* Reset the Output Compare mode and Capture/Compare selection Bits */ - tmpccmrx &= (uint16_t)~TIM_CCMR2_OC4M; - tmpccmrx &= (uint16_t)~TIM_CCMR2_CC4S; - - /* Select the Output Compare Mode */ - tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8); - - /* Reset the Output Polarity level */ - tmpccer &= (uint16_t)~TIM_CCER_CC4P; - /* Set the Output Compare Polarity */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 12); - - /* Set the Output State */ - tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 12); - - if((TIMx == TIM1) || (TIMx == TIM8)) - { - assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); - /* Reset the Output Compare IDLE State */ - tmpcr2 &=(uint16_t) ~TIM_CR2_OIS4; - /* Set the Output Idle state */ - tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 6); - } - /* Write to TIMx CR2 */ - TIMx->CR2 = tmpcr2; - - /* Write to TIMx CCMR2 */ - TIMx->CCMR2 = tmpccmrx; - - /* Set the Capture Compare Register value */ - TIMx->CCR4 = TIM_OCInitStruct->TIM_Pulse; - - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Fills each TIM_OCInitStruct member with its default value. - * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure which will - * be initialized. - * @retval None - */ -void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct) -{ - /* Set the default configuration */ - TIM_OCInitStruct->TIM_OCMode = TIM_OCMode_Timing; - TIM_OCInitStruct->TIM_OutputState = TIM_OutputState_Disable; - TIM_OCInitStruct->TIM_OutputNState = TIM_OutputNState_Disable; - TIM_OCInitStruct->TIM_Pulse = 0x00000000; - TIM_OCInitStruct->TIM_OCPolarity = TIM_OCPolarity_High; - TIM_OCInitStruct->TIM_OCNPolarity = TIM_OCPolarity_High; - TIM_OCInitStruct->TIM_OCIdleState = TIM_OCIdleState_Reset; - TIM_OCInitStruct->TIM_OCNIdleState = TIM_OCNIdleState_Reset; -} - -/** - * @brief Selects the TIM Output Compare Mode. - * @note This function disables the selected channel before changing the Output - * Compare Mode. If needed, user has to enable this channel using - * TIM_CCxCmd() and TIM_CCxNCmd() functions. - * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. - * @param TIM_Channel: specifies the TIM Channel - * This parameter can be one of the following values: - * @arg TIM_Channel_1: TIM Channel 1 - * @arg TIM_Channel_2: TIM Channel 2 - * @arg TIM_Channel_3: TIM Channel 3 - * @arg TIM_Channel_4: TIM Channel 4 - * @param TIM_OCMode: specifies the TIM Output Compare Mode. - * This parameter can be one of the following values: - * @arg TIM_OCMode_Timing - * @arg TIM_OCMode_Active - * @arg TIM_OCMode_Toggle - * @arg TIM_OCMode_PWM1 - * @arg TIM_OCMode_PWM2 - * @arg TIM_ForcedAction_Active - * @arg TIM_ForcedAction_InActive - * @retval None - */ -void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode) -{ - uint32_t tmp = 0; - uint16_t tmp1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_CHANNEL(TIM_Channel)); - assert_param(IS_TIM_OCM(TIM_OCMode)); - - tmp = (uint32_t) TIMx; - tmp += CCMR_OFFSET; - - tmp1 = CCER_CCE_SET << (uint16_t)TIM_Channel; - - /* Disable the Channel: Reset the CCxE Bit */ - TIMx->CCER &= (uint16_t) ~tmp1; - - if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3)) - { - tmp += (TIM_Channel>>1); - - /* Reset the OCxM bits in the CCMRx register */ - *(__IO uint32_t *) tmp &= CCMR_OC13M_MASK; - - /* Configure the OCxM bits in the CCMRx register */ - *(__IO uint32_t *) tmp |= TIM_OCMode; - } - else - { - tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1; - - /* Reset the OCxM bits in the CCMRx register */ - *(__IO uint32_t *) tmp &= CCMR_OC24M_MASK; - - /* Configure the OCxM bits in the CCMRx register */ - *(__IO uint32_t *) tmp |= (uint16_t)(TIM_OCMode << 8); - } -} - -/** - * @brief Sets the TIMx Capture Compare1 Register value - * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. - * @param Compare1: specifies the Capture Compare1 register new value. - * @retval None - */ -void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - - /* Set the Capture Compare1 Register value */ - TIMx->CCR1 = Compare1; -} - -/** - * @brief Sets the TIMx Capture Compare2 Register value - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM - * peripheral. - * @param Compare2: specifies the Capture Compare2 register new value. - * @retval None - */ -void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - - /* Set the Capture Compare2 Register value */ - TIMx->CCR2 = Compare2; -} - -/** - * @brief Sets the TIMx Capture Compare3 Register value - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param Compare3: specifies the Capture Compare3 register new value. - * @retval None - */ -void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - - /* Set the Capture Compare3 Register value */ - TIMx->CCR3 = Compare3; -} - -/** - * @brief Sets the TIMx Capture Compare4 Register value - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param Compare4: specifies the Capture Compare4 register new value. - * @retval None - */ -void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - - /* Set the Capture Compare4 Register value */ - TIMx->CCR4 = Compare4; -} - -/** - * @brief Forces the TIMx output 1 waveform to active or inactive level. - * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. - * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. - * This parameter can be one of the following values: - * @arg TIM_ForcedAction_Active: Force active level on OC1REF - * @arg TIM_ForcedAction_InActive: Force inactive level on OC1REF. - * @retval None - */ -void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) -{ - uint16_t tmpccmr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); - tmpccmr1 = TIMx->CCMR1; - - /* Reset the OC1M Bits */ - tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC1M; - - /* Configure The Forced output Mode */ - tmpccmr1 |= TIM_ForcedAction; - - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Forces the TIMx output 2 waveform to active or inactive level. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM - * peripheral. - * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. - * This parameter can be one of the following values: - * @arg TIM_ForcedAction_Active: Force active level on OC2REF - * @arg TIM_ForcedAction_InActive: Force inactive level on OC2REF. - * @retval None - */ -void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) -{ - uint16_t tmpccmr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); - tmpccmr1 = TIMx->CCMR1; - - /* Reset the OC2M Bits */ - tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC2M; - - /* Configure The Forced output Mode */ - tmpccmr1 |= (uint16_t)(TIM_ForcedAction << 8); - - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Forces the TIMx output 3 waveform to active or inactive level. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. - * This parameter can be one of the following values: - * @arg TIM_ForcedAction_Active: Force active level on OC3REF - * @arg TIM_ForcedAction_InActive: Force inactive level on OC3REF. - * @retval None - */ -void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); - - tmpccmr2 = TIMx->CCMR2; - - /* Reset the OC1M Bits */ - tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC3M; - - /* Configure The Forced output Mode */ - tmpccmr2 |= TIM_ForcedAction; - - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Forces the TIMx output 4 waveform to active or inactive level. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. - * This parameter can be one of the following values: - * @arg TIM_ForcedAction_Active: Force active level on OC4REF - * @arg TIM_ForcedAction_InActive: Force inactive level on OC4REF. - * @retval None - */ -void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); - tmpccmr2 = TIMx->CCMR2; - - /* Reset the OC2M Bits */ - tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC4M; - - /* Configure The Forced output Mode */ - tmpccmr2 |= (uint16_t)(TIM_ForcedAction << 8); - - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Enables or disables the TIMx peripheral Preload register on CCR1. - * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. - * @param TIM_OCPreload: new state of the TIMx peripheral Preload register - * This parameter can be one of the following values: - * @arg TIM_OCPreload_Enable - * @arg TIM_OCPreload_Disable - * @retval None - */ -void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) -{ - uint16_t tmpccmr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); - - tmpccmr1 = TIMx->CCMR1; - - /* Reset the OC1PE Bit */ - tmpccmr1 &= (uint16_t)(~TIM_CCMR1_OC1PE); - - /* Enable or Disable the Output Compare Preload feature */ - tmpccmr1 |= TIM_OCPreload; - - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Enables or disables the TIMx peripheral Preload register on CCR2. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM - * peripheral. - * @param TIM_OCPreload: new state of the TIMx peripheral Preload register - * This parameter can be one of the following values: - * @arg TIM_OCPreload_Enable - * @arg TIM_OCPreload_Disable - * @retval None - */ -void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) -{ - uint16_t tmpccmr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); - - tmpccmr1 = TIMx->CCMR1; - - /* Reset the OC2PE Bit */ - tmpccmr1 &= (uint16_t)(~TIM_CCMR1_OC2PE); - - /* Enable or Disable the Output Compare Preload feature */ - tmpccmr1 |= (uint16_t)(TIM_OCPreload << 8); - - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Enables or disables the TIMx peripheral Preload register on CCR3. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCPreload: new state of the TIMx peripheral Preload register - * This parameter can be one of the following values: - * @arg TIM_OCPreload_Enable - * @arg TIM_OCPreload_Disable - * @retval None - */ -void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); - - tmpccmr2 = TIMx->CCMR2; - - /* Reset the OC3PE Bit */ - tmpccmr2 &= (uint16_t)(~TIM_CCMR2_OC3PE); - - /* Enable or Disable the Output Compare Preload feature */ - tmpccmr2 |= TIM_OCPreload; - - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Enables or disables the TIMx peripheral Preload register on CCR4. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCPreload: new state of the TIMx peripheral Preload register - * This parameter can be one of the following values: - * @arg TIM_OCPreload_Enable - * @arg TIM_OCPreload_Disable - * @retval None - */ -void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); - - tmpccmr2 = TIMx->CCMR2; - - /* Reset the OC4PE Bit */ - tmpccmr2 &= (uint16_t)(~TIM_CCMR2_OC4PE); - - /* Enable or Disable the Output Compare Preload feature */ - tmpccmr2 |= (uint16_t)(TIM_OCPreload << 8); - - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Configures the TIMx Output Compare 1 Fast feature. - * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. - * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCFast_Enable: TIM output compare fast enable - * @arg TIM_OCFast_Disable: TIM output compare fast disable - * @retval None - */ -void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) -{ - uint16_t tmpccmr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); - - /* Get the TIMx CCMR1 register value */ - tmpccmr1 = TIMx->CCMR1; - - /* Reset the OC1FE Bit */ - tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC1FE; - - /* Enable or Disable the Output Compare Fast Bit */ - tmpccmr1 |= TIM_OCFast; - - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Configures the TIMx Output Compare 2 Fast feature. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM - * peripheral. - * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCFast_Enable: TIM output compare fast enable - * @arg TIM_OCFast_Disable: TIM output compare fast disable - * @retval None - */ -void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) -{ - uint16_t tmpccmr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); - - /* Get the TIMx CCMR1 register value */ - tmpccmr1 = TIMx->CCMR1; - - /* Reset the OC2FE Bit */ - tmpccmr1 &= (uint16_t)(~TIM_CCMR1_OC2FE); - - /* Enable or Disable the Output Compare Fast Bit */ - tmpccmr1 |= (uint16_t)(TIM_OCFast << 8); - - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Configures the TIMx Output Compare 3 Fast feature. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCFast_Enable: TIM output compare fast enable - * @arg TIM_OCFast_Disable: TIM output compare fast disable - * @retval None - */ -void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); - - /* Get the TIMx CCMR2 register value */ - tmpccmr2 = TIMx->CCMR2; - - /* Reset the OC3FE Bit */ - tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC3FE; - - /* Enable or Disable the Output Compare Fast Bit */ - tmpccmr2 |= TIM_OCFast; - - /* Write to TIMx CCMR2 */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Configures the TIMx Output Compare 4 Fast feature. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCFast_Enable: TIM output compare fast enable - * @arg TIM_OCFast_Disable: TIM output compare fast disable - * @retval None - */ -void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); - - /* Get the TIMx CCMR2 register value */ - tmpccmr2 = TIMx->CCMR2; - - /* Reset the OC4FE Bit */ - tmpccmr2 &= (uint16_t)(~TIM_CCMR2_OC4FE); - - /* Enable or Disable the Output Compare Fast Bit */ - tmpccmr2 |= (uint16_t)(TIM_OCFast << 8); - - /* Write to TIMx CCMR2 */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Clears or safeguards the OCREF1 signal on an external event - * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. - * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCClear_Enable: TIM Output clear enable - * @arg TIM_OCClear_Disable: TIM Output clear disable - * @retval None - */ -void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) -{ - uint16_t tmpccmr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); - - tmpccmr1 = TIMx->CCMR1; - - /* Reset the OC1CE Bit */ - tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC1CE; - - /* Enable or Disable the Output Compare Clear Bit */ - tmpccmr1 |= TIM_OCClear; - - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Clears or safeguards the OCREF2 signal on an external event - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM - * peripheral. - * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCClear_Enable: TIM Output clear enable - * @arg TIM_OCClear_Disable: TIM Output clear disable - * @retval None - */ -void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) -{ - uint16_t tmpccmr1 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); - - tmpccmr1 = TIMx->CCMR1; - - /* Reset the OC2CE Bit */ - tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC2CE; - - /* Enable or Disable the Output Compare Clear Bit */ - tmpccmr1 |= (uint16_t)(TIM_OCClear << 8); - - /* Write to TIMx CCMR1 register */ - TIMx->CCMR1 = tmpccmr1; -} - -/** - * @brief Clears or safeguards the OCREF3 signal on an external event - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCClear_Enable: TIM Output clear enable - * @arg TIM_OCClear_Disable: TIM Output clear disable - * @retval None - */ -void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); - - tmpccmr2 = TIMx->CCMR2; - - /* Reset the OC3CE Bit */ - tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC3CE; - - /* Enable or Disable the Output Compare Clear Bit */ - tmpccmr2 |= TIM_OCClear; - - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Clears or safeguards the OCREF4 signal on an external event - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. - * This parameter can be one of the following values: - * @arg TIM_OCClear_Enable: TIM Output clear enable - * @arg TIM_OCClear_Disable: TIM Output clear disable - * @retval None - */ -void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) -{ - uint16_t tmpccmr2 = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); - - tmpccmr2 = TIMx->CCMR2; - - /* Reset the OC4CE Bit */ - tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC4CE; - - /* Enable or Disable the Output Compare Clear Bit */ - tmpccmr2 |= (uint16_t)(TIM_OCClear << 8); - - /* Write to TIMx CCMR2 register */ - TIMx->CCMR2 = tmpccmr2; -} - -/** - * @brief Configures the TIMx channel 1 polarity. - * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. - * @param TIM_OCPolarity: specifies the OC1 Polarity - * This parameter can be one of the following values: - * @arg TIM_OCPolarity_High: Output Compare active high - * @arg TIM_OCPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) -{ - uint16_t tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); - - tmpccer = TIMx->CCER; - - /* Set or Reset the CC1P Bit */ - tmpccer &= (uint16_t)(~TIM_CCER_CC1P); - tmpccer |= TIM_OCPolarity; - - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx Channel 1N polarity. - * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. - * @param TIM_OCNPolarity: specifies the OC1N Polarity - * This parameter can be one of the following values: - * @arg TIM_OCNPolarity_High: Output Compare active high - * @arg TIM_OCNPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) -{ - uint16_t tmpccer = 0; - /* Check the parameters */ - assert_param(IS_TIM_LIST4_PERIPH(TIMx)); - assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); - - tmpccer = TIMx->CCER; - - /* Set or Reset the CC1NP Bit */ - tmpccer &= (uint16_t)~TIM_CCER_CC1NP; - tmpccer |= TIM_OCNPolarity; - - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx channel 2 polarity. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM - * peripheral. - * @param TIM_OCPolarity: specifies the OC2 Polarity - * This parameter can be one of the following values: - * @arg TIM_OCPolarity_High: Output Compare active high - * @arg TIM_OCPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) -{ - uint16_t tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); - - tmpccer = TIMx->CCER; - - /* Set or Reset the CC2P Bit */ - tmpccer &= (uint16_t)(~TIM_CCER_CC2P); - tmpccer |= (uint16_t)(TIM_OCPolarity << 4); - - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx Channel 2N polarity. - * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. - * @param TIM_OCNPolarity: specifies the OC2N Polarity - * This parameter can be one of the following values: - * @arg TIM_OCNPolarity_High: Output Compare active high - * @arg TIM_OCNPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) -{ - uint16_t tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST4_PERIPH(TIMx)); - assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); - - tmpccer = TIMx->CCER; - - /* Set or Reset the CC2NP Bit */ - tmpccer &= (uint16_t)~TIM_CCER_CC2NP; - tmpccer |= (uint16_t)(TIM_OCNPolarity << 4); - - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx channel 3 polarity. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCPolarity: specifies the OC3 Polarity - * This parameter can be one of the following values: - * @arg TIM_OCPolarity_High: Output Compare active high - * @arg TIM_OCPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) -{ - uint16_t tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); - - tmpccer = TIMx->CCER; - - /* Set or Reset the CC3P Bit */ - tmpccer &= (uint16_t)~TIM_CCER_CC3P; - tmpccer |= (uint16_t)(TIM_OCPolarity << 8); - - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx Channel 3N polarity. - * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. - * @param TIM_OCNPolarity: specifies the OC3N Polarity - * This parameter can be one of the following values: - * @arg TIM_OCNPolarity_High: Output Compare active high - * @arg TIM_OCNPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) -{ - uint16_t tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST4_PERIPH(TIMx)); - assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); - - tmpccer = TIMx->CCER; - - /* Set or Reset the CC3NP Bit */ - tmpccer &= (uint16_t)~TIM_CCER_CC3NP; - tmpccer |= (uint16_t)(TIM_OCNPolarity << 8); - - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Configures the TIMx channel 4 polarity. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_OCPolarity: specifies the OC4 Polarity - * This parameter can be one of the following values: - * @arg TIM_OCPolarity_High: Output Compare active high - * @arg TIM_OCPolarity_Low: Output Compare active low - * @retval None - */ -void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) -{ - uint16_t tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); - - tmpccer = TIMx->CCER; - - /* Set or Reset the CC4P Bit */ - tmpccer &= (uint16_t)~TIM_CCER_CC4P; - tmpccer |= (uint16_t)(TIM_OCPolarity << 12); - - /* Write to TIMx CCER register */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Enables or disables the TIM Capture Compare Channel x. - * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. - * @param TIM_Channel: specifies the TIM Channel - * This parameter can be one of the following values: - * @arg TIM_Channel_1: TIM Channel 1 - * @arg TIM_Channel_2: TIM Channel 2 - * @arg TIM_Channel_3: TIM Channel 3 - * @arg TIM_Channel_4: TIM Channel 4 - * @param TIM_CCx: specifies the TIM Channel CCxE bit new state. - * This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable. - * @retval None - */ -void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx) -{ - uint16_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_CHANNEL(TIM_Channel)); - assert_param(IS_TIM_CCX(TIM_CCx)); - - tmp = CCER_CCE_SET << TIM_Channel; - - /* Reset the CCxE Bit */ - TIMx->CCER &= (uint16_t)~ tmp; - - /* Set or reset the CCxE Bit */ - TIMx->CCER |= (uint16_t)(TIM_CCx << TIM_Channel); -} - -/** - * @brief Enables or disables the TIM Capture Compare Channel xN. - * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. - * @param TIM_Channel: specifies the TIM Channel - * This parameter can be one of the following values: - * @arg TIM_Channel_1: TIM Channel 1 - * @arg TIM_Channel_2: TIM Channel 2 - * @arg TIM_Channel_3: TIM Channel 3 - * @param TIM_CCxN: specifies the TIM Channel CCxNE bit new state. - * This parameter can be: TIM_CCxN_Enable or TIM_CCxN_Disable. - * @retval None - */ -void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN) -{ - uint16_t tmp = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST4_PERIPH(TIMx)); - assert_param(IS_TIM_COMPLEMENTARY_CHANNEL(TIM_Channel)); - assert_param(IS_TIM_CCXN(TIM_CCxN)); - - tmp = CCER_CCNE_SET << TIM_Channel; - - /* Reset the CCxNE Bit */ - TIMx->CCER &= (uint16_t) ~tmp; - - /* Set or reset the CCxNE Bit */ - TIMx->CCER |= (uint16_t)(TIM_CCxN << TIM_Channel); -} -/** - * @} - */ - -/** @defgroup TIM_Group3 Input Capture management functions - * @brief Input Capture management functions - * -@verbatim - =============================================================================== - Input Capture management functions - =============================================================================== - - =================================================================== - TIM Driver: how to use it in Input Capture Mode - =================================================================== - To use the Timer in Input Capture mode, the following steps are mandatory: - - 1. Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function - - 2. Configure the TIM pins by configuring the corresponding GPIO pins - - 2. Configure the Time base unit as described in the first part of this driver, - if needed, else the Timer will run with the default configuration: - - Autoreload value = 0xFFFF - - Prescaler value = 0x0000 - - Counter mode = Up counting - - Clock Division = TIM_CKD_DIV1 - - 3. Fill the TIM_ICInitStruct with the desired parameters including: - - TIM Channel: TIM_Channel - - TIM Input Capture polarity: TIM_ICPolarity - - TIM Input Capture selection: TIM_ICSelection - - TIM Input Capture Prescaler: TIM_ICPrescaler - - TIM Input CApture filter value: TIM_ICFilter - - 4. Call TIM_ICInit(TIMx, &TIM_ICInitStruct) to configure the desired channel with the - corresponding configuration and to measure only frequency or duty cycle of the input signal, - or, - Call TIM_PWMIConfig(TIMx, &TIM_ICInitStruct) to configure the desired channels with the - corresponding configuration and to measure the frequency and the duty cycle of the input signal - - 5. Enable the NVIC or the DMA to read the measured frequency. - - 6. Enable the corresponding interrupt (or DMA request) to read the Captured value, - using the function TIM_ITConfig(TIMx, TIM_IT_CCx) (or TIM_DMA_Cmd(TIMx, TIM_DMA_CCx)) - - 7. Call the TIM_Cmd(ENABLE) function to enable the TIM counter. - - 8. Use TIM_GetCapturex(TIMx); to read the captured value. - - Note1: All other functions can be used separately to modify, if needed, - a specific feature of the Timer. - -@endverbatim - * @{ - */ - -/** - * @brief Initializes the TIM peripheral according to the specified parameters - * in the TIM_ICInitStruct. - * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. - * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure that contains - * the configuration information for the specified TIM peripheral. - * @retval None - */ -void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_IC_POLARITY(TIM_ICInitStruct->TIM_ICPolarity)); - assert_param(IS_TIM_IC_SELECTION(TIM_ICInitStruct->TIM_ICSelection)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICInitStruct->TIM_ICPrescaler)); - assert_param(IS_TIM_IC_FILTER(TIM_ICInitStruct->TIM_ICFilter)); - - if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) - { - /* TI1 Configuration */ - TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, - TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } - else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_2) - { - /* TI2 Configuration */ - TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, - TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } - else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_3) - { - /* TI3 Configuration */ - TI3_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, - TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC3Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } - else - { - /* TI4 Configuration */ - TI4_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, - TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC4Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } -} - -/** - * @brief Fills each TIM_ICInitStruct member with its default value. - * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure which will - * be initialized. - * @retval None - */ -void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct) -{ - /* Set the default configuration */ - TIM_ICInitStruct->TIM_Channel = TIM_Channel_1; - TIM_ICInitStruct->TIM_ICPolarity = TIM_ICPolarity_Rising; - TIM_ICInitStruct->TIM_ICSelection = TIM_ICSelection_DirectTI; - TIM_ICInitStruct->TIM_ICPrescaler = TIM_ICPSC_DIV1; - TIM_ICInitStruct->TIM_ICFilter = 0x00; -} - -/** - * @brief Configures the TIM peripheral according to the specified parameters - * in the TIM_ICInitStruct to measure an external PWM signal. - * @param TIMx: where x can be 1, 2, 3, 4, 5,8, 9 or 12 to select the TIM - * peripheral. - * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure that contains - * the configuration information for the specified TIM peripheral. - * @retval None - */ -void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) -{ - uint16_t icoppositepolarity = TIM_ICPolarity_Rising; - uint16_t icoppositeselection = TIM_ICSelection_DirectTI; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - - /* Select the Opposite Input Polarity */ - if (TIM_ICInitStruct->TIM_ICPolarity == TIM_ICPolarity_Rising) - { - icoppositepolarity = TIM_ICPolarity_Falling; - } - else - { - icoppositepolarity = TIM_ICPolarity_Rising; - } - /* Select the Opposite Input */ - if (TIM_ICInitStruct->TIM_ICSelection == TIM_ICSelection_DirectTI) - { - icoppositeselection = TIM_ICSelection_IndirectTI; - } - else - { - icoppositeselection = TIM_ICSelection_DirectTI; - } - if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) - { - /* TI1 Configuration */ - TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - /* TI2 Configuration */ - TI2_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } - else - { - /* TI2 Configuration */ - TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, - TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - /* TI1 Configuration */ - TI1_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); - /* Set the Input Capture Prescaler value */ - TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); - } -} - -/** - * @brief Gets the TIMx Input Capture 1 value. - * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. - * @retval Capture Compare 1 Register value. - */ -uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - - /* Get the Capture 1 Register value */ - return TIMx->CCR1; -} - -/** - * @brief Gets the TIMx Input Capture 2 value. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM - * peripheral. - * @retval Capture Compare 2 Register value. - */ -uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - - /* Get the Capture 2 Register value */ - return TIMx->CCR2; -} - -/** - * @brief Gets the TIMx Input Capture 3 value. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @retval Capture Compare 3 Register value. - */ -uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - - /* Get the Capture 3 Register value */ - return TIMx->CCR3; -} - -/** - * @brief Gets the TIMx Input Capture 4 value. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @retval Capture Compare 4 Register value. - */ -uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - - /* Get the Capture 4 Register value */ - return TIMx->CCR4; -} - -/** - * @brief Sets the TIMx Input Capture 1 prescaler. - * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. - * @param TIM_ICPSC: specifies the Input Capture1 prescaler new value. - * This parameter can be one of the following values: - * @arg TIM_ICPSC_DIV1: no prescaler - * @arg TIM_ICPSC_DIV2: capture is done once every 2 events - * @arg TIM_ICPSC_DIV4: capture is done once every 4 events - * @arg TIM_ICPSC_DIV8: capture is done once every 8 events - * @retval None - */ -void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); - - /* Reset the IC1PSC Bits */ - TIMx->CCMR1 &= (uint16_t)~TIM_CCMR1_IC1PSC; - - /* Set the IC1PSC value */ - TIMx->CCMR1 |= TIM_ICPSC; -} - -/** - * @brief Sets the TIMx Input Capture 2 prescaler. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM - * peripheral. - * @param TIM_ICPSC: specifies the Input Capture2 prescaler new value. - * This parameter can be one of the following values: - * @arg TIM_ICPSC_DIV1: no prescaler - * @arg TIM_ICPSC_DIV2: capture is done once every 2 events - * @arg TIM_ICPSC_DIV4: capture is done once every 4 events - * @arg TIM_ICPSC_DIV8: capture is done once every 8 events - * @retval None - */ -void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); - - /* Reset the IC2PSC Bits */ - TIMx->CCMR1 &= (uint16_t)~TIM_CCMR1_IC2PSC; - - /* Set the IC2PSC value */ - TIMx->CCMR1 |= (uint16_t)(TIM_ICPSC << 8); -} - -/** - * @brief Sets the TIMx Input Capture 3 prescaler. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ICPSC: specifies the Input Capture3 prescaler new value. - * This parameter can be one of the following values: - * @arg TIM_ICPSC_DIV1: no prescaler - * @arg TIM_ICPSC_DIV2: capture is done once every 2 events - * @arg TIM_ICPSC_DIV4: capture is done once every 4 events - * @arg TIM_ICPSC_DIV8: capture is done once every 8 events - * @retval None - */ -void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); - - /* Reset the IC3PSC Bits */ - TIMx->CCMR2 &= (uint16_t)~TIM_CCMR2_IC3PSC; - - /* Set the IC3PSC value */ - TIMx->CCMR2 |= TIM_ICPSC; -} - -/** - * @brief Sets the TIMx Input Capture 4 prescaler. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ICPSC: specifies the Input Capture4 prescaler new value. - * This parameter can be one of the following values: - * @arg TIM_ICPSC_DIV1: no prescaler - * @arg TIM_ICPSC_DIV2: capture is done once every 2 events - * @arg TIM_ICPSC_DIV4: capture is done once every 4 events - * @arg TIM_ICPSC_DIV8: capture is done once every 8 events - * @retval None - */ -void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); - - /* Reset the IC4PSC Bits */ - TIMx->CCMR2 &= (uint16_t)~TIM_CCMR2_IC4PSC; - - /* Set the IC4PSC value */ - TIMx->CCMR2 |= (uint16_t)(TIM_ICPSC << 8); -} -/** - * @} - */ - -/** @defgroup TIM_Group4 Advanced-control timers (TIM1 and TIM8) specific features - * @brief Advanced-control timers (TIM1 and TIM8) specific features - * -@verbatim - =============================================================================== - Advanced-control timers (TIM1 and TIM8) specific features - =============================================================================== - - =================================================================== - TIM Driver: how to use the Break feature - =================================================================== - After configuring the Timer channel(s) in the appropriate Output Compare mode: - - 1. Fill the TIM_BDTRInitStruct with the desired parameters for the Timer - Break Polarity, dead time, Lock level, the OSSI/OSSR State and the - AOE(automatic output enable). - - 2. Call TIM_BDTRConfig(TIMx, &TIM_BDTRInitStruct) to configure the Timer - - 3. Enable the Main Output using TIM_CtrlPWMOutputs(TIM1, ENABLE) - - 4. Once the break even occurs, the Timer's output signals are put in reset - state or in a known state (according to the configuration made in - TIM_BDTRConfig() function). - -@endverbatim - * @{ - */ - -/** - * @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State - * and the AOE(automatic output enable). - * @param TIMx: where x can be 1 or 8 to select the TIM - * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure that - * contains the BDTR Register configuration information for the TIM peripheral. - * @retval None - */ -void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST4_PERIPH(TIMx)); - assert_param(IS_TIM_OSSR_STATE(TIM_BDTRInitStruct->TIM_OSSRState)); - assert_param(IS_TIM_OSSI_STATE(TIM_BDTRInitStruct->TIM_OSSIState)); - assert_param(IS_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->TIM_LOCKLevel)); - assert_param(IS_TIM_BREAK_STATE(TIM_BDTRInitStruct->TIM_Break)); - assert_param(IS_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->TIM_BreakPolarity)); - assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->TIM_AutomaticOutput)); - - /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State, - the OSSI State, the dead time value and the Automatic Output Enable Bit */ - TIMx->BDTR = (uint32_t)TIM_BDTRInitStruct->TIM_OSSRState | TIM_BDTRInitStruct->TIM_OSSIState | - TIM_BDTRInitStruct->TIM_LOCKLevel | TIM_BDTRInitStruct->TIM_DeadTime | - TIM_BDTRInitStruct->TIM_Break | TIM_BDTRInitStruct->TIM_BreakPolarity | - TIM_BDTRInitStruct->TIM_AutomaticOutput; -} - -/** - * @brief Fills each TIM_BDTRInitStruct member with its default value. - * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure which - * will be initialized. - * @retval None - */ -void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct) -{ - /* Set the default configuration */ - TIM_BDTRInitStruct->TIM_OSSRState = TIM_OSSRState_Disable; - TIM_BDTRInitStruct->TIM_OSSIState = TIM_OSSIState_Disable; - TIM_BDTRInitStruct->TIM_LOCKLevel = TIM_LOCKLevel_OFF; - TIM_BDTRInitStruct->TIM_DeadTime = 0x00; - TIM_BDTRInitStruct->TIM_Break = TIM_Break_Disable; - TIM_BDTRInitStruct->TIM_BreakPolarity = TIM_BreakPolarity_Low; - TIM_BDTRInitStruct->TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; -} - -/** - * @brief Enables or disables the TIM peripheral Main Outputs. - * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral. - * @param NewState: new state of the TIM peripheral Main Outputs. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST4_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the TIM Main Output */ - TIMx->BDTR |= TIM_BDTR_MOE; - } - else - { - /* Disable the TIM Main Output */ - TIMx->BDTR &= (uint16_t)~TIM_BDTR_MOE; - } -} - -/** - * @brief Selects the TIM peripheral Commutation event. - * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral - * @param NewState: new state of the Commutation event. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST4_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Set the COM Bit */ - TIMx->CR2 |= TIM_CR2_CCUS; - } - else - { - /* Reset the COM Bit */ - TIMx->CR2 &= (uint16_t)~TIM_CR2_CCUS; - } -} - -/** - * @brief Sets or Resets the TIM peripheral Capture Compare Preload Control bit. - * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral - * @param NewState: new state of the Capture Compare Preload Control bit - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST4_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Set the CCPC Bit */ - TIMx->CR2 |= TIM_CR2_CCPC; - } - else - { - /* Reset the CCPC Bit */ - TIMx->CR2 &= (uint16_t)~TIM_CR2_CCPC; - } -} -/** - * @} - */ - -/** @defgroup TIM_Group5 Interrupts DMA and flags management functions - * @brief Interrupts, DMA and flags management functions - * -@verbatim - =============================================================================== - Interrupts, DMA and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified TIM interrupts. - * @param TIMx: where x can be 1 to 14 to select the TIMx peripheral. - * @param TIM_IT: specifies the TIM interrupts sources to be enabled or disabled. - * This parameter can be any combination of the following values: - * @arg TIM_IT_Update: TIM update Interrupt source - * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source - * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source - * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source - * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source - * @arg TIM_IT_COM: TIM Commutation Interrupt source - * @arg TIM_IT_Trigger: TIM Trigger Interrupt source - * @arg TIM_IT_Break: TIM Break Interrupt source - * - * @note For TIM6 and TIM7 only the parameter TIM_IT_Update can be used - * @note For TIM9 and TIM12 only one of the following parameters can be used: TIM_IT_Update, - * TIM_IT_CC1, TIM_IT_CC2 or TIM_IT_Trigger. - * @note For TIM10, TIM11, TIM13 and TIM14 only one of the following parameters can - * be used: TIM_IT_Update or TIM_IT_CC1 - * @note TIM_IT_COM and TIM_IT_Break can be used only with TIM1 and TIM8 - * - * @param NewState: new state of the TIM interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_IT(TIM_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the Interrupt sources */ - TIMx->DIER |= TIM_IT; - } - else - { - /* Disable the Interrupt sources */ - TIMx->DIER &= (uint16_t)~TIM_IT; - } -} - -/** - * @brief Configures the TIMx event to be generate by software. - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @param TIM_EventSource: specifies the event source. - * This parameter can be one or more of the following values: - * @arg TIM_EventSource_Update: Timer update Event source - * @arg TIM_EventSource_CC1: Timer Capture Compare 1 Event source - * @arg TIM_EventSource_CC2: Timer Capture Compare 2 Event source - * @arg TIM_EventSource_CC3: Timer Capture Compare 3 Event source - * @arg TIM_EventSource_CC4: Timer Capture Compare 4 Event source - * @arg TIM_EventSource_COM: Timer COM event source - * @arg TIM_EventSource_Trigger: Timer Trigger Event source - * @arg TIM_EventSource_Break: Timer Break event source - * - * @note TIM6 and TIM7 can only generate an update event. - * @note TIM_EventSource_COM and TIM_EventSource_Break are used only with TIM1 and TIM8. - * - * @retval None - */ -void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_EVENT_SOURCE(TIM_EventSource)); - - /* Set the event sources */ - TIMx->EGR = TIM_EventSource; -} - -/** - * @brief Checks whether the specified TIM flag is set or not. - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @param TIM_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg TIM_FLAG_Update: TIM update Flag - * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag - * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag - * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag - * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag - * @arg TIM_FLAG_COM: TIM Commutation Flag - * @arg TIM_FLAG_Trigger: TIM Trigger Flag - * @arg TIM_FLAG_Break: TIM Break Flag - * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 over capture Flag - * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 over capture Flag - * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 over capture Flag - * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 over capture Flag - * - * @note TIM6 and TIM7 can have only one update flag. - * @note TIM_FLAG_COM and TIM_FLAG_Break are used only with TIM1 and TIM8. - * - * @retval The new state of TIM_FLAG (SET or RESET). - */ -FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) -{ - ITStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_GET_FLAG(TIM_FLAG)); - - - if ((TIMx->SR & TIM_FLAG) != (uint16_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the TIMx's pending flags. - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @param TIM_FLAG: specifies the flag bit to clear. - * This parameter can be any combination of the following values: - * @arg TIM_FLAG_Update: TIM update Flag - * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag - * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag - * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag - * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag - * @arg TIM_FLAG_COM: TIM Commutation Flag - * @arg TIM_FLAG_Trigger: TIM Trigger Flag - * @arg TIM_FLAG_Break: TIM Break Flag - * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 over capture Flag - * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 over capture Flag - * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 over capture Flag - * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 over capture Flag - * - * @note TIM6 and TIM7 can have only one update flag. - * @note TIM_FLAG_COM and TIM_FLAG_Break are used only with TIM1 and TIM8. - * - * @retval None - */ -void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - - /* Clear the flags */ - TIMx->SR = (uint16_t)~TIM_FLAG; -} - -/** - * @brief Checks whether the TIM interrupt has occurred or not. - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @param TIM_IT: specifies the TIM interrupt source to check. - * This parameter can be one of the following values: - * @arg TIM_IT_Update: TIM update Interrupt source - * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source - * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source - * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source - * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source - * @arg TIM_IT_COM: TIM Commutation Interrupt source - * @arg TIM_IT_Trigger: TIM Trigger Interrupt source - * @arg TIM_IT_Break: TIM Break Interrupt source - * - * @note TIM6 and TIM7 can generate only an update interrupt. - * @note TIM_IT_COM and TIM_IT_Break are used only with TIM1 and TIM8. - * - * @retval The new state of the TIM_IT(SET or RESET). - */ -ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT) -{ - ITStatus bitstatus = RESET; - uint16_t itstatus = 0x0, itenable = 0x0; - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - assert_param(IS_TIM_GET_IT(TIM_IT)); - - itstatus = TIMx->SR & TIM_IT; - - itenable = TIMx->DIER & TIM_IT; - if ((itstatus != (uint16_t)RESET) && (itenable != (uint16_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the TIMx's interrupt pending bits. - * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. - * @param TIM_IT: specifies the pending bit to clear. - * This parameter can be any combination of the following values: - * @arg TIM_IT_Update: TIM1 update Interrupt source - * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source - * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source - * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source - * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source - * @arg TIM_IT_COM: TIM Commutation Interrupt source - * @arg TIM_IT_Trigger: TIM Trigger Interrupt source - * @arg TIM_IT_Break: TIM Break Interrupt source - * - * @note TIM6 and TIM7 can generate only an update interrupt. - * @note TIM_IT_COM and TIM_IT_Break are used only with TIM1 and TIM8. - * - * @retval None - */ -void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT) -{ - /* Check the parameters */ - assert_param(IS_TIM_ALL_PERIPH(TIMx)); - - /* Clear the IT pending Bit */ - TIMx->SR = (uint16_t)~TIM_IT; -} - -/** - * @brief Configures the TIMx's DMA interface. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_DMABase: DMA Base address. - * This parameter can be one of the following values: - * @arg TIM_DMABase_CR1 - * @arg TIM_DMABase_CR2 - * @arg TIM_DMABase_SMCR - * @arg TIM_DMABase_DIER - * @arg TIM1_DMABase_SR - * @arg TIM_DMABase_EGR - * @arg TIM_DMABase_CCMR1 - * @arg TIM_DMABase_CCMR2 - * @arg TIM_DMABase_CCER - * @arg TIM_DMABase_CNT - * @arg TIM_DMABase_PSC - * @arg TIM_DMABase_ARR - * @arg TIM_DMABase_RCR - * @arg TIM_DMABase_CCR1 - * @arg TIM_DMABase_CCR2 - * @arg TIM_DMABase_CCR3 - * @arg TIM_DMABase_CCR4 - * @arg TIM_DMABase_BDTR - * @arg TIM_DMABase_DCR - * @param TIM_DMABurstLength: DMA Burst length. This parameter can be one value - * between: TIM_DMABurstLength_1Transfer and TIM_DMABurstLength_18Transfers. - * @retval None - */ -void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_DMA_BASE(TIM_DMABase)); - assert_param(IS_TIM_DMA_LENGTH(TIM_DMABurstLength)); - - /* Set the DMA Base and the DMA Burst Length */ - TIMx->DCR = TIM_DMABase | TIM_DMABurstLength; -} - -/** - * @brief Enables or disables the TIMx's DMA Requests. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7 or 8 to select the TIM peripheral. - * @param TIM_DMASource: specifies the DMA Request sources. - * This parameter can be any combination of the following values: - * @arg TIM_DMA_Update: TIM update Interrupt source - * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source - * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source - * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source - * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source - * @arg TIM_DMA_COM: TIM Commutation DMA source - * @arg TIM_DMA_Trigger: TIM Trigger DMA source - * @param NewState: new state of the DMA Request sources. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST5_PERIPH(TIMx)); - assert_param(IS_TIM_DMA_SOURCE(TIM_DMASource)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the DMA sources */ - TIMx->DIER |= TIM_DMASource; - } - else - { - /* Disable the DMA sources */ - TIMx->DIER &= (uint16_t)~TIM_DMASource; - } -} - -/** - * @brief Selects the TIMx peripheral Capture Compare DMA source. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param NewState: new state of the Capture Compare DMA source - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Set the CCDS Bit */ - TIMx->CR2 |= TIM_CR2_CCDS; - } - else - { - /* Reset the CCDS Bit */ - TIMx->CR2 &= (uint16_t)~TIM_CR2_CCDS; - } -} -/** - * @} - */ - -/** @defgroup TIM_Group6 Clocks management functions - * @brief Clocks management functions - * -@verbatim - =============================================================================== - Clocks management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Configures the TIMx internal Clock - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM - * peripheral. - * @retval None - */ -void TIM_InternalClockConfig(TIM_TypeDef* TIMx) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - - /* Disable slave mode to clock the prescaler directly with the internal clock */ - TIMx->SMCR &= (uint16_t)~TIM_SMCR_SMS; -} - -/** - * @brief Configures the TIMx Internal Trigger as External Clock - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM - * peripheral. - * @param TIM_InputTriggerSource: Trigger source. - * This parameter can be one of the following values: - * @arg TIM_TS_ITR0: Internal Trigger 0 - * @arg TIM_TS_ITR1: Internal Trigger 1 - * @arg TIM_TS_ITR2: Internal Trigger 2 - * @arg TIM_TS_ITR3: Internal Trigger 3 - * @retval None - */ -void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_INTERNAL_TRIGGER_SELECTION(TIM_InputTriggerSource)); - - /* Select the Internal Trigger */ - TIM_SelectInputTrigger(TIMx, TIM_InputTriggerSource); - - /* Select the External clock mode1 */ - TIMx->SMCR |= TIM_SlaveMode_External1; -} - -/** - * @brief Configures the TIMx Trigger as External Clock - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 - * to select the TIM peripheral. - * @param TIM_TIxExternalCLKSource: Trigger source. - * This parameter can be one of the following values: - * @arg TIM_TIxExternalCLK1Source_TI1ED: TI1 Edge Detector - * @arg TIM_TIxExternalCLK1Source_TI1: Filtered Timer Input 1 - * @arg TIM_TIxExternalCLK1Source_TI2: Filtered Timer Input 2 - * @param TIM_ICPolarity: specifies the TIx Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @param ICFilter: specifies the filter value. - * This parameter must be a value between 0x0 and 0xF. - * @retval None - */ -void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, - uint16_t TIM_ICPolarity, uint16_t ICFilter) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_IC_POLARITY(TIM_ICPolarity)); - assert_param(IS_TIM_IC_FILTER(ICFilter)); - - /* Configure the Timer Input Clock Source */ - if (TIM_TIxExternalCLKSource == TIM_TIxExternalCLK1Source_TI2) - { - TI2_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); - } - else - { - TI1_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); - } - /* Select the Trigger source */ - TIM_SelectInputTrigger(TIMx, TIM_TIxExternalCLKSource); - /* Select the External clock mode1 */ - TIMx->SMCR |= TIM_SlaveMode_External1; -} - -/** - * @brief Configures the External clock Mode1 - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. - * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. - * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. - * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. - * @param TIM_ExtTRGPolarity: The external Trigger Polarity. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. - * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. - * @param ExtTRGFilter: External Trigger Filter. - * This parameter must be a value between 0x00 and 0x0F - * @retval None - */ -void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, - uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) -{ - uint16_t tmpsmcr = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); - assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); - assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); - /* Configure the ETR Clock source */ - TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); - - /* Get the TIMx SMCR register value */ - tmpsmcr = TIMx->SMCR; - - /* Reset the SMS Bits */ - tmpsmcr &= (uint16_t)~TIM_SMCR_SMS; - - /* Select the External clock mode1 */ - tmpsmcr |= TIM_SlaveMode_External1; - - /* Select the Trigger selection : ETRF */ - tmpsmcr &= (uint16_t)~TIM_SMCR_TS; - tmpsmcr |= TIM_TS_ETRF; - - /* Write to TIMx SMCR */ - TIMx->SMCR = tmpsmcr; -} - -/** - * @brief Configures the External clock Mode2 - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. - * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. - * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. - * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. - * @param TIM_ExtTRGPolarity: The external Trigger Polarity. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. - * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. - * @param ExtTRGFilter: External Trigger Filter. - * This parameter must be a value between 0x00 and 0x0F - * @retval None - */ -void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, - uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); - assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); - assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); - - /* Configure the ETR Clock source */ - TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); - - /* Enable the External clock mode2 */ - TIMx->SMCR |= TIM_SMCR_ECE; -} -/** - * @} - */ - -/** @defgroup TIM_Group7 Synchronization management functions - * @brief Synchronization management functions - * -@verbatim - =============================================================================== - Synchronization management functions - =============================================================================== - - =================================================================== - TIM Driver: how to use it in synchronization Mode - =================================================================== - Case of two/several Timers - ************************** - 1. Configure the Master Timers using the following functions: - - void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource); - - void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode); - 2. Configure the Slave Timers using the following functions: - - void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); - - void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); - - Case of Timers and external trigger(ETR pin) - ******************************************** - 1. Configure the External trigger using this function: - - void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, - uint16_t ExtTRGFilter); - 2. Configure the Slave Timers using the following functions: - - void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); - - void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); - -@endverbatim - * @{ - */ - -/** - * @brief Selects the Input Trigger source - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 - * to select the TIM peripheral. - * @param TIM_InputTriggerSource: The Input Trigger source. - * This parameter can be one of the following values: - * @arg TIM_TS_ITR0: Internal Trigger 0 - * @arg TIM_TS_ITR1: Internal Trigger 1 - * @arg TIM_TS_ITR2: Internal Trigger 2 - * @arg TIM_TS_ITR3: Internal Trigger 3 - * @arg TIM_TS_TI1F_ED: TI1 Edge Detector - * @arg TIM_TS_TI1FP1: Filtered Timer Input 1 - * @arg TIM_TS_TI2FP2: Filtered Timer Input 2 - * @arg TIM_TS_ETRF: External Trigger input - * @retval None - */ -void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource) -{ - uint16_t tmpsmcr = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST1_PERIPH(TIMx)); - assert_param(IS_TIM_TRIGGER_SELECTION(TIM_InputTriggerSource)); - - /* Get the TIMx SMCR register value */ - tmpsmcr = TIMx->SMCR; - - /* Reset the TS Bits */ - tmpsmcr &= (uint16_t)~TIM_SMCR_TS; - - /* Set the Input Trigger source */ - tmpsmcr |= TIM_InputTriggerSource; - - /* Write to TIMx SMCR */ - TIMx->SMCR = tmpsmcr; -} - -/** - * @brief Selects the TIMx Trigger Output Mode. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7 or 8 to select the TIM peripheral. - * - * @param TIM_TRGOSource: specifies the Trigger Output source. - * This parameter can be one of the following values: - * - * - For all TIMx - * @arg TIM_TRGOSource_Reset: The UG bit in the TIM_EGR register is used as the trigger output(TRGO) - * @arg TIM_TRGOSource_Enable: The Counter Enable CEN is used as the trigger output(TRGO) - * @arg TIM_TRGOSource_Update: The update event is selected as the trigger output(TRGO) - * - * - For all TIMx except TIM6 and TIM7 - * @arg TIM_TRGOSource_OC1: The trigger output sends a positive pulse when the CC1IF flag - * is to be set, as soon as a capture or compare match occurs(TRGO) - * @arg TIM_TRGOSource_OC1Ref: OC1REF signal is used as the trigger output(TRGO) - * @arg TIM_TRGOSource_OC2Ref: OC2REF signal is used as the trigger output(TRGO) - * @arg TIM_TRGOSource_OC3Ref: OC3REF signal is used as the trigger output(TRGO) - * @arg TIM_TRGOSource_OC4Ref: OC4REF signal is used as the trigger output(TRGO) - * - * @retval None - */ -void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST5_PERIPH(TIMx)); - assert_param(IS_TIM_TRGO_SOURCE(TIM_TRGOSource)); - - /* Reset the MMS Bits */ - TIMx->CR2 &= (uint16_t)~TIM_CR2_MMS; - /* Select the TRGO source */ - TIMx->CR2 |= TIM_TRGOSource; -} - -/** - * @brief Selects the TIMx Slave Mode. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM peripheral. - * @param TIM_SlaveMode: specifies the Timer Slave Mode. - * This parameter can be one of the following values: - * @arg TIM_SlaveMode_Reset: Rising edge of the selected trigger signal(TRGI) reinitialize - * the counter and triggers an update of the registers - * @arg TIM_SlaveMode_Gated: The counter clock is enabled when the trigger signal (TRGI) is high - * @arg TIM_SlaveMode_Trigger: The counter starts at a rising edge of the trigger TRGI - * @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter - * @retval None - */ -void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_SLAVE_MODE(TIM_SlaveMode)); - - /* Reset the SMS Bits */ - TIMx->SMCR &= (uint16_t)~TIM_SMCR_SMS; - - /* Select the Slave Mode */ - TIMx->SMCR |= TIM_SlaveMode; -} - -/** - * @brief Sets or Resets the TIMx Master/Slave Mode. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM peripheral. - * @param TIM_MasterSlaveMode: specifies the Timer Master Slave Mode. - * This parameter can be one of the following values: - * @arg TIM_MasterSlaveMode_Enable: synchronization between the current timer - * and its slaves (through TRGO) - * @arg TIM_MasterSlaveMode_Disable: No action - * @retval None - */ -void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_MSM_STATE(TIM_MasterSlaveMode)); - - /* Reset the MSM Bit */ - TIMx->SMCR &= (uint16_t)~TIM_SMCR_MSM; - - /* Set or Reset the MSM Bit */ - TIMx->SMCR |= TIM_MasterSlaveMode; -} - -/** - * @brief Configures the TIMx External Trigger (ETR). - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. - * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. - * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. - * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. - * @param TIM_ExtTRGPolarity: The external Trigger Polarity. - * This parameter can be one of the following values: - * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. - * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. - * @param ExtTRGFilter: External Trigger Filter. - * This parameter must be a value between 0x00 and 0x0F - * @retval None - */ -void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, - uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) -{ - uint16_t tmpsmcr = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST3_PERIPH(TIMx)); - assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); - assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); - assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); - - tmpsmcr = TIMx->SMCR; - - /* Reset the ETR Bits */ - tmpsmcr &= SMCR_ETR_MASK; - - /* Set the Prescaler, the Filter value and the Polarity */ - tmpsmcr |= (uint16_t)(TIM_ExtTRGPrescaler | (uint16_t)(TIM_ExtTRGPolarity | (uint16_t)(ExtTRGFilter << (uint16_t)8))); - - /* Write to TIMx SMCR */ - TIMx->SMCR = tmpsmcr; -} -/** - * @} - */ - -/** @defgroup TIM_Group8 Specific interface management functions - * @brief Specific interface management functions - * -@verbatim - =============================================================================== - Specific interface management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Configures the TIMx Encoder Interface. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM - * peripheral. - * @param TIM_EncoderMode: specifies the TIMx Encoder Mode. - * This parameter can be one of the following values: - * @arg TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level. - * @arg TIM_EncoderMode_TI2: Counter counts on TI2FP2 edge depending on TI1FP1 level. - * @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending - * on the level of the other input. - * @param TIM_IC1Polarity: specifies the IC1 Polarity - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Falling: IC Falling edge. - * @arg TIM_ICPolarity_Rising: IC Rising edge. - * @param TIM_IC2Polarity: specifies the IC2 Polarity - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Falling: IC Falling edge. - * @arg TIM_ICPolarity_Rising: IC Rising edge. - * @retval None - */ -void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, - uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity) -{ - uint16_t tmpsmcr = 0; - uint16_t tmpccmr1 = 0; - uint16_t tmpccer = 0; - - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_TIM_ENCODER_MODE(TIM_EncoderMode)); - assert_param(IS_TIM_IC_POLARITY(TIM_IC1Polarity)); - assert_param(IS_TIM_IC_POLARITY(TIM_IC2Polarity)); - - /* Get the TIMx SMCR register value */ - tmpsmcr = TIMx->SMCR; - - /* Get the TIMx CCMR1 register value */ - tmpccmr1 = TIMx->CCMR1; - - /* Get the TIMx CCER register value */ - tmpccer = TIMx->CCER; - - /* Set the encoder Mode */ - tmpsmcr &= (uint16_t)~TIM_SMCR_SMS; - tmpsmcr |= TIM_EncoderMode; - - /* Select the Capture Compare 1 and the Capture Compare 2 as input */ - tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR1_CC2S); - tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0; - - /* Set the TI1 and the TI2 Polarities */ - tmpccer &= ((uint16_t)~TIM_CCER_CC1P) & ((uint16_t)~TIM_CCER_CC2P); - tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4)); - - /* Write to TIMx SMCR */ - TIMx->SMCR = tmpsmcr; - - /* Write to TIMx CCMR1 */ - TIMx->CCMR1 = tmpccmr1; - - /* Write to TIMx CCER */ - TIMx->CCER = tmpccer; -} - -/** - * @brief Enables or disables the TIMx's Hall sensor interface. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM - * peripheral. - * @param NewState: new state of the TIMx Hall sensor interface. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST2_PERIPH(TIMx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Set the TI1S Bit */ - TIMx->CR2 |= TIM_CR2_TI1S; - } - else - { - /* Reset the TI1S Bit */ - TIMx->CR2 &= (uint16_t)~TIM_CR2_TI1S; - } -} -/** - * @} - */ - -/** @defgroup TIM_Group9 Specific remapping management function - * @brief Specific remapping management function - * -@verbatim - =============================================================================== - Specific remapping management function - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Configures the TIM2, TIM5 and TIM11 Remapping input capabilities. - * @param TIMx: where x can be 2, 5 or 11 to select the TIM peripheral. - * @param TIM_Remap: specifies the TIM input remapping source. - * This parameter can be one of the following values: - * @arg TIM2_TIM8_TRGO: TIM2 ITR1 input is connected to TIM8 Trigger output(default) - * @arg TIM2_ETH_PTP: TIM2 ITR1 input is connected to ETH PTP trogger output. - * @arg TIM2_USBFS_SOF: TIM2 ITR1 input is connected to USB FS SOF. - * @arg TIM2_USBHS_SOF: TIM2 ITR1 input is connected to USB HS SOF. - * @arg TIM5_GPIO: TIM5 CH4 input is connected to dedicated Timer pin(default) - * @arg TIM5_LSI: TIM5 CH4 input is connected to LSI clock. - * @arg TIM5_LSE: TIM5 CH4 input is connected to LSE clock. - * @arg TIM5_RTC: TIM5 CH4 input is connected to RTC Output event. - * @arg TIM11_GPIO: TIM11 CH4 input is connected to dedicated Timer pin(default) - * @arg TIM11_HSE: TIM11 CH4 input is connected to HSE_RTC clock - * (HSE divided by a programmable prescaler) - * @retval None - */ -void TIM_RemapConfig(TIM_TypeDef* TIMx, uint16_t TIM_Remap) -{ - /* Check the parameters */ - assert_param(IS_TIM_LIST6_PERIPH(TIMx)); - assert_param(IS_TIM_REMAP(TIM_Remap)); - - /* Set the Timer remapping configuration */ - TIMx->OR = TIM_Remap; -} -/** - * @} - */ - -/** - * @brief Configure the TI1 as Input. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 - * to select the TIM peripheral. - * @param TIM_ICPolarity : The Input Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @arg TIM_ICPolarity_BothEdge - * @param TIM_ICSelection: specifies the input to be used. - * This parameter can be one of the following values: - * @arg TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1. - * @arg TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2. - * @arg TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC. - * @param TIM_ICFilter: Specifies the Input Capture Filter. - * This parameter must be a value between 0x00 and 0x0F. - * @retval None - */ -static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter) -{ - uint16_t tmpccmr1 = 0, tmpccer = 0; - - /* Disable the Channel 1: Reset the CC1E Bit */ - TIMx->CCER &= (uint16_t)~TIM_CCER_CC1E; - tmpccmr1 = TIMx->CCMR1; - tmpccer = TIMx->CCER; - - /* Select the Input and set the filter */ - tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR1_IC1F); - tmpccmr1 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4)); - - /* Select the Polarity and set the CC1E Bit */ - tmpccer &= (uint16_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP); - tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC1E); - - /* Write to TIMx CCMR1 and CCER registers */ - TIMx->CCMR1 = tmpccmr1; - TIMx->CCER = tmpccer; -} - -/** - * @brief Configure the TI2 as Input. - * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM - * peripheral. - * @param TIM_ICPolarity : The Input Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @arg TIM_ICPolarity_BothEdge - * @param TIM_ICSelection: specifies the input to be used. - * This parameter can be one of the following values: - * @arg TIM_ICSelection_DirectTI: TIM Input 2 is selected to be connected to IC2. - * @arg TIM_ICSelection_IndirectTI: TIM Input 2 is selected to be connected to IC1. - * @arg TIM_ICSelection_TRC: TIM Input 2 is selected to be connected to TRC. - * @param TIM_ICFilter: Specifies the Input Capture Filter. - * This parameter must be a value between 0x00 and 0x0F. - * @retval None - */ -static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter) -{ - uint16_t tmpccmr1 = 0, tmpccer = 0, tmp = 0; - - /* Disable the Channel 2: Reset the CC2E Bit */ - TIMx->CCER &= (uint16_t)~TIM_CCER_CC2E; - tmpccmr1 = TIMx->CCMR1; - tmpccer = TIMx->CCER; - tmp = (uint16_t)(TIM_ICPolarity << 4); - - /* Select the Input and set the filter */ - tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC2S) & ((uint16_t)~TIM_CCMR1_IC2F); - tmpccmr1 |= (uint16_t)(TIM_ICFilter << 12); - tmpccmr1 |= (uint16_t)(TIM_ICSelection << 8); - - /* Select the Polarity and set the CC2E Bit */ - tmpccer &= (uint16_t)~(TIM_CCER_CC2P | TIM_CCER_CC2NP); - tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC2E); - - /* Write to TIMx CCMR1 and CCER registers */ - TIMx->CCMR1 = tmpccmr1 ; - TIMx->CCER = tmpccer; -} - -/** - * @brief Configure the TI3 as Input. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ICPolarity : The Input Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @arg TIM_ICPolarity_BothEdge - * @param TIM_ICSelection: specifies the input to be used. - * This parameter can be one of the following values: - * @arg TIM_ICSelection_DirectTI: TIM Input 3 is selected to be connected to IC3. - * @arg TIM_ICSelection_IndirectTI: TIM Input 3 is selected to be connected to IC4. - * @arg TIM_ICSelection_TRC: TIM Input 3 is selected to be connected to TRC. - * @param TIM_ICFilter: Specifies the Input Capture Filter. - * This parameter must be a value between 0x00 and 0x0F. - * @retval None - */ -static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter) -{ - uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; - - /* Disable the Channel 3: Reset the CC3E Bit */ - TIMx->CCER &= (uint16_t)~TIM_CCER_CC3E; - tmpccmr2 = TIMx->CCMR2; - tmpccer = TIMx->CCER; - tmp = (uint16_t)(TIM_ICPolarity << 8); - - /* Select the Input and set the filter */ - tmpccmr2 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR2_IC3F); - tmpccmr2 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4)); - - /* Select the Polarity and set the CC3E Bit */ - tmpccer &= (uint16_t)~(TIM_CCER_CC3P | TIM_CCER_CC3NP); - tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC3E); - - /* Write to TIMx CCMR2 and CCER registers */ - TIMx->CCMR2 = tmpccmr2; - TIMx->CCER = tmpccer; -} - -/** - * @brief Configure the TI4 as Input. - * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. - * @param TIM_ICPolarity : The Input Polarity. - * This parameter can be one of the following values: - * @arg TIM_ICPolarity_Rising - * @arg TIM_ICPolarity_Falling - * @arg TIM_ICPolarity_BothEdge - * @param TIM_ICSelection: specifies the input to be used. - * This parameter can be one of the following values: - * @arg TIM_ICSelection_DirectTI: TIM Input 4 is selected to be connected to IC4. - * @arg TIM_ICSelection_IndirectTI: TIM Input 4 is selected to be connected to IC3. - * @arg TIM_ICSelection_TRC: TIM Input 4 is selected to be connected to TRC. - * @param TIM_ICFilter: Specifies the Input Capture Filter. - * This parameter must be a value between 0x00 and 0x0F. - * @retval None - */ -static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, - uint16_t TIM_ICFilter) -{ - uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; - - /* Disable the Channel 4: Reset the CC4E Bit */ - TIMx->CCER &= (uint16_t)~TIM_CCER_CC4E; - tmpccmr2 = TIMx->CCMR2; - tmpccer = TIMx->CCER; - tmp = (uint16_t)(TIM_ICPolarity << 12); - - /* Select the Input and set the filter */ - tmpccmr2 &= ((uint16_t)~TIM_CCMR1_CC2S) & ((uint16_t)~TIM_CCMR1_IC2F); - tmpccmr2 |= (uint16_t)(TIM_ICSelection << 8); - tmpccmr2 |= (uint16_t)(TIM_ICFilter << 12); - - /* Select the Polarity and set the CC4E Bit */ - tmpccer &= (uint16_t)~(TIM_CCER_CC4P | TIM_CCER_CC4NP); - tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC4E); - - /* Write to TIMx CCMR2 and CCER registers */ - TIMx->CCMR2 = tmpccmr2; - TIMx->CCER = tmpccer ; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c deleted file mode 100644 index 6ae03e00f..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c +++ /dev/null @@ -1,1462 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_usart.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the Universal synchronous asynchronous receiver - * transmitter (USART): - * - Initialization and Configuration - * - Data transfers - * - Multi-Processor Communication - * - LIN mode - * - Half-duplex mode - * - Smartcard mode - * - IrDA mode - * - DMA transfers management - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable peripheral clock using the follwoing functions - * RCC_APB2PeriphClockCmd(RCC_APB2Periph_USARTx, ENABLE) for USART1 and USART6 - * RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE) for USART2, USART3, UART4 or UART5. - * - * 2. According to the USART mode, enable the GPIO clocks using - * RCC_AHB1PeriphClockCmd() function. (The I/O can be TX, RX, CTS, - * or/and SCLK). - * - * 3. Peripheral's alternate function: - * - Connect the pin to the desired peripherals' Alternate - * Function (AF) using GPIO_PinAFConfig() function - * - Configure the desired pin in alternate function by: - * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF - * - Select the type, pull-up/pull-down and output speed via - * GPIO_PuPd, GPIO_OType and GPIO_Speed members - * - Call GPIO_Init() function - * - * 4. Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware - * flow control and Mode(Receiver/Transmitter) using the USART_Init() - * function. - * - * 5. For synchronous mode, enable the clock and program the polarity, - * phase and last bit using the USART_ClockInit() function. - * - * 5. Enable the NVIC and the corresponding interrupt using the function - * USART_ITConfig() if you need to use interrupt mode. - * - * 6. When using the DMA mode - * - Configure the DMA using DMA_Init() function - * - Active the needed channel Request using USART_DMACmd() function - * - * 7. Enable the USART using the USART_Cmd() function. - * - * 8. Enable the DMA using the DMA_Cmd() function, when using DMA mode. - * - * Refer to Multi-Processor, LIN, half-duplex, Smartcard, IrDA sub-sections - * for more details - * - * In order to reach higher communication baudrates, it is possible to - * enable the oversampling by 8 mode using the function USART_OverSampling8Cmd(). - * This function should be called after enabling the USART clock (RCC_APBxPeriphClockCmd()) - * and before calling the function USART_Init(). - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_usart.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup USART - * @brief USART driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/*!< USART CR1 register clear Mask ((~(uint16_t)0xE9F3)) */ -#define CR1_CLEAR_MASK ((uint16_t)(USART_CR1_M | USART_CR1_PCE | \ - USART_CR1_PS | USART_CR1_TE | \ - USART_CR1_RE)) - -/*!< USART CR2 register clock bits clear Mask ((~(uint16_t)0xF0FF)) */ -#define CR2_CLOCK_CLEAR_MASK ((uint16_t)(USART_CR2_CLKEN | USART_CR2_CPOL | \ - USART_CR2_CPHA | USART_CR2_LBCL)) - -/*!< USART CR3 register clear Mask ((~(uint16_t)0xFCFF)) */ -#define CR3_CLEAR_MASK ((uint16_t)(USART_CR3_RTSE | USART_CR3_CTSE)) - -/*!< USART Interrupts mask */ -#define IT_MASK ((uint16_t)0x001F) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup USART_Private_Functions - * @{ - */ - -/** @defgroup USART_Group1 Initialization and Configuration functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - Initialization and Configuration functions - =============================================================================== - - This subsection provides a set of functions allowing to initialize the USART - in asynchronous and in synchronous modes. - - For the asynchronous mode only these parameters can be configured: - - Baud Rate - - Word Length - - Stop Bit - - Parity: If the parity is enabled, then the MSB bit of the data written - in the data register is transmitted but is changed by the parity bit. - Depending on the frame length defined by the M bit (8-bits or 9-bits), - the possible USART frame formats are as listed in the following table: - +-------------------------------------------------------------+ - | M bit | PCE bit | USART frame | - |---------------------|---------------------------------------| - | 0 | 0 | | SB | 8 bit data | STB | | - |---------|-----------|---------------------------------------| - | 0 | 1 | | SB | 7 bit data | PB | STB | | - |---------|-----------|---------------------------------------| - | 1 | 0 | | SB | 9 bit data | STB | | - |---------|-----------|---------------------------------------| - | 1 | 1 | | SB | 8 bit data | PB | STB | | - +-------------------------------------------------------------+ - - Hardware flow control - - Receiver/transmitter modes - - The USART_Init() function follows the USART asynchronous configuration procedure - (details for the procedure are available in reference manual (RM0090)). - - - For the synchronous mode in addition to the asynchronous mode parameters these - parameters should be also configured: - - USART Clock Enabled - - USART polarity - - USART phase - - USART LastBit - - These parameters can be configured using the USART_ClockInit() function. - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the USARTx peripheral registers to their default reset values. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @retval None - */ -void USART_DeInit(USART_TypeDef* USARTx) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - - if (USARTx == USART1) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); - } - else if (USARTx == USART2) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE); - } - else if (USARTx == USART3) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE); - } - else if (USARTx == UART4) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, DISABLE); - } - else if (USARTx == UART5) - { - RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, DISABLE); - } - else - { - if (USARTx == USART6) - { - RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, DISABLE); - } - } -} - -/** - * @brief Initializes the USARTx peripheral according to the specified - * parameters in the USART_InitStruct . - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param USART_InitStruct: pointer to a USART_InitTypeDef structure that contains - * the configuration information for the specified USART peripheral. - * @retval None - */ -void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct) -{ - uint32_t tmpreg = 0x00, apbclock = 0x00; - uint32_t integerdivider = 0x00; - uint32_t fractionaldivider = 0x00; - RCC_ClocksTypeDef RCC_ClocksStatus; - - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_BAUDRATE(USART_InitStruct->USART_BaudRate)); - assert_param(IS_USART_WORD_LENGTH(USART_InitStruct->USART_WordLength)); - assert_param(IS_USART_STOPBITS(USART_InitStruct->USART_StopBits)); - assert_param(IS_USART_PARITY(USART_InitStruct->USART_Parity)); - assert_param(IS_USART_MODE(USART_InitStruct->USART_Mode)); - assert_param(IS_USART_HARDWARE_FLOW_CONTROL(USART_InitStruct->USART_HardwareFlowControl)); - - /* The hardware flow control is available only for USART1, USART2, USART3 and USART6 */ - if (USART_InitStruct->USART_HardwareFlowControl != USART_HardwareFlowControl_None) - { - assert_param(IS_USART_1236_PERIPH(USARTx)); - } - -/*---------------------------- USART CR2 Configuration -----------------------*/ - tmpreg = USARTx->CR2; - - /* Clear STOP[13:12] bits */ - tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP); - - /* Configure the USART Stop Bits, Clock, CPOL, CPHA and LastBit : - Set STOP[13:12] bits according to USART_StopBits value */ - tmpreg |= (uint32_t)USART_InitStruct->USART_StopBits; - - /* Write to USART CR2 */ - USARTx->CR2 = (uint16_t)tmpreg; - -/*---------------------------- USART CR1 Configuration -----------------------*/ - tmpreg = USARTx->CR1; - - /* Clear M, PCE, PS, TE and RE bits */ - tmpreg &= (uint32_t)~((uint32_t)CR1_CLEAR_MASK); - - /* Configure the USART Word Length, Parity and mode: - Set the M bits according to USART_WordLength value - Set PCE and PS bits according to USART_Parity value - Set TE and RE bits according to USART_Mode value */ - tmpreg |= (uint32_t)USART_InitStruct->USART_WordLength | USART_InitStruct->USART_Parity | - USART_InitStruct->USART_Mode; - - /* Write to USART CR1 */ - USARTx->CR1 = (uint16_t)tmpreg; - -/*---------------------------- USART CR3 Configuration -----------------------*/ - tmpreg = USARTx->CR3; - - /* Clear CTSE and RTSE bits */ - tmpreg &= (uint32_t)~((uint32_t)CR3_CLEAR_MASK); - - /* Configure the USART HFC : - Set CTSE and RTSE bits according to USART_HardwareFlowControl value */ - tmpreg |= USART_InitStruct->USART_HardwareFlowControl; - - /* Write to USART CR3 */ - USARTx->CR3 = (uint16_t)tmpreg; - -/*---------------------------- USART BRR Configuration -----------------------*/ - /* Configure the USART Baud Rate */ - RCC_GetClocksFreq(&RCC_ClocksStatus); - - if ((USARTx == USART1) || (USARTx == USART6)) - { - apbclock = RCC_ClocksStatus.PCLK2_Frequency; - } - else - { - apbclock = RCC_ClocksStatus.PCLK1_Frequency; - } - - /* Determine the integer part */ - if ((USARTx->CR1 & USART_CR1_OVER8) != 0) - { - /* Integer part computing in case Oversampling mode is 8 Samples */ - integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate))); - } - else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */ - { - /* Integer part computing in case Oversampling mode is 16 Samples */ - integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate))); - } - tmpreg = (integerdivider / 100) << 4; - - /* Determine the fractional part */ - fractionaldivider = integerdivider - (100 * (tmpreg >> 4)); - - /* Implement the fractional part in the register */ - if ((USARTx->CR1 & USART_CR1_OVER8) != 0) - { - tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07); - } - else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */ - { - tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F); - } - - /* Write to USART BRR register */ - USARTx->BRR = (uint16_t)tmpreg; -} - -/** - * @brief Fills each USART_InitStruct member with its default value. - * @param USART_InitStruct: pointer to a USART_InitTypeDef structure which will - * be initialized. - * @retval None - */ -void USART_StructInit(USART_InitTypeDef* USART_InitStruct) -{ - /* USART_InitStruct members default value */ - USART_InitStruct->USART_BaudRate = 9600; - USART_InitStruct->USART_WordLength = USART_WordLength_8b; - USART_InitStruct->USART_StopBits = USART_StopBits_1; - USART_InitStruct->USART_Parity = USART_Parity_No ; - USART_InitStruct->USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - USART_InitStruct->USART_HardwareFlowControl = USART_HardwareFlowControl_None; -} - -/** - * @brief Initializes the USARTx peripheral Clock according to the - * specified parameters in the USART_ClockInitStruct . - * @param USARTx: where x can be 1, 2, 3 or 6 to select the USART peripheral. - * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef structure that - * contains the configuration information for the specified USART peripheral. - * @note The Smart Card and Synchronous modes are not available for UART4 and UART5. - * @retval None - */ -void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct) -{ - uint32_t tmpreg = 0x00; - /* Check the parameters */ - assert_param(IS_USART_1236_PERIPH(USARTx)); - assert_param(IS_USART_CLOCK(USART_ClockInitStruct->USART_Clock)); - assert_param(IS_USART_CPOL(USART_ClockInitStruct->USART_CPOL)); - assert_param(IS_USART_CPHA(USART_ClockInitStruct->USART_CPHA)); - assert_param(IS_USART_LASTBIT(USART_ClockInitStruct->USART_LastBit)); - -/*---------------------------- USART CR2 Configuration -----------------------*/ - tmpreg = USARTx->CR2; - /* Clear CLKEN, CPOL, CPHA and LBCL bits */ - tmpreg &= (uint32_t)~((uint32_t)CR2_CLOCK_CLEAR_MASK); - /* Configure the USART Clock, CPOL, CPHA and LastBit ------------*/ - /* Set CLKEN bit according to USART_Clock value */ - /* Set CPOL bit according to USART_CPOL value */ - /* Set CPHA bit according to USART_CPHA value */ - /* Set LBCL bit according to USART_LastBit value */ - tmpreg |= (uint32_t)USART_ClockInitStruct->USART_Clock | USART_ClockInitStruct->USART_CPOL | - USART_ClockInitStruct->USART_CPHA | USART_ClockInitStruct->USART_LastBit; - /* Write to USART CR2 */ - USARTx->CR2 = (uint16_t)tmpreg; -} - -/** - * @brief Fills each USART_ClockInitStruct member with its default value. - * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef structure - * which will be initialized. - * @retval None - */ -void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct) -{ - /* USART_ClockInitStruct members default value */ - USART_ClockInitStruct->USART_Clock = USART_Clock_Disable; - USART_ClockInitStruct->USART_CPOL = USART_CPOL_Low; - USART_ClockInitStruct->USART_CPHA = USART_CPHA_1Edge; - USART_ClockInitStruct->USART_LastBit = USART_LastBit_Disable; -} - -/** - * @brief Enables or disables the specified USART peripheral. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param NewState: new state of the USARTx peripheral. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the selected USART by setting the UE bit in the CR1 register */ - USARTx->CR1 |= USART_CR1_UE; - } - else - { - /* Disable the selected USART by clearing the UE bit in the CR1 register */ - USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_UE); - } -} - -/** - * @brief Sets the system clock prescaler. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param USART_Prescaler: specifies the prescaler clock. - * @note The function is used for IrDA mode with UART4 and UART5. - * @retval None - */ -void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - - /* Clear the USART prescaler */ - USARTx->GTPR &= USART_GTPR_GT; - /* Set the USART prescaler */ - USARTx->GTPR |= USART_Prescaler; -} - -/** - * @brief Enables or disables the USART's 8x oversampling mode. - * @note This function has to be called before calling USART_Init() function - * in order to have correct baudrate Divider value. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param NewState: new state of the USART 8x oversampling mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the 8x Oversampling mode by setting the OVER8 bit in the CR1 register */ - USARTx->CR1 |= USART_CR1_OVER8; - } - else - { - /* Disable the 8x Oversampling mode by clearing the OVER8 bit in the CR1 register */ - USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_OVER8); - } -} - -/** - * @brief Enables or disables the USART's one bit sampling method. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param NewState: new state of the USART one bit sampling method. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the one bit method by setting the ONEBITE bit in the CR3 register */ - USARTx->CR3 |= USART_CR3_ONEBIT; - } - else - { - /* Disable the one bit method by clearing the ONEBITE bit in the CR3 register */ - USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_ONEBIT); - } -} - -/** - * @} - */ - -/** @defgroup USART_Group2 Data transfers functions - * @brief Data transfers functions - * -@verbatim - =============================================================================== - Data transfers functions - =============================================================================== - - This subsection provides a set of functions allowing to manage the USART data - transfers. - - During an USART reception, data shifts in least significant bit first through - the RX pin. In this mode, the USART_DR register consists of a buffer (RDR) - between the internal bus and the received shift register. - - When a transmission is taking place, a write instruction to the USART_DR register - stores the data in the TDR register and which is copied in the shift register - at the end of the current transmission. - - The read access of the USART_DR register can be done using the USART_ReceiveData() - function and returns the RDR buffered value. Whereas a write access to the USART_DR - can be done using USART_SendData() function and stores the written data into - TDR buffer. - -@endverbatim - * @{ - */ - -/** - * @brief Transmits single data through the USARTx peripheral. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param Data: the data to transmit. - * @retval None - */ -void USART_SendData(USART_TypeDef* USARTx, uint16_t Data) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_DATA(Data)); - - /* Transmit Data */ - USARTx->DR = (Data & (uint16_t)0x01FF); -} - -/** - * @brief Returns the most recent received data by the USARTx peripheral. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @retval The received data. - */ -uint16_t USART_ReceiveData(USART_TypeDef* USARTx) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - - /* Receive Data */ - return (uint16_t)(USARTx->DR & (uint16_t)0x01FF); -} - -/** - * @} - */ - -/** @defgroup USART_Group3 MultiProcessor Communication functions - * @brief Multi-Processor Communication functions - * -@verbatim - =============================================================================== - Multi-Processor Communication functions - =============================================================================== - - This subsection provides a set of functions allowing to manage the USART - multiprocessor communication. - - For instance one of the USARTs can be the master, its TX output is connected to - the RX input of the other USART. The others are slaves, their respective TX outputs - are logically ANDed together and connected to the RX input of the master. - - USART multiprocessor communication is possible through the following procedure: - 1. Program the Baud rate, Word length = 9 bits, Stop bits, Parity, Mode transmitter - or Mode receiver and hardware flow control values using the USART_Init() - function. - 2. Configures the USART address using the USART_SetAddress() function. - 3. Configures the wake up method (USART_WakeUp_IdleLine or USART_WakeUp_AddressMark) - using USART_WakeUpConfig() function only for the slaves. - 4. Enable the USART using the USART_Cmd() function. - 5. Enter the USART slaves in mute mode using USART_ReceiverWakeUpCmd() function. - - The USART Slave exit from mute mode when receive the wake up condition. - -@endverbatim - * @{ - */ - -/** - * @brief Sets the address of the USART node. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param USART_Address: Indicates the address of the USART node. - * @retval None - */ -void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_ADDRESS(USART_Address)); - - /* Clear the USART address */ - USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_ADD); - /* Set the USART address node */ - USARTx->CR2 |= USART_Address; -} - -/** - * @brief Determines if the USART is in mute mode or not. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param NewState: new state of the USART mute mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the USART mute mode by setting the RWU bit in the CR1 register */ - USARTx->CR1 |= USART_CR1_RWU; - } - else - { - /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */ - USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_RWU); - } -} -/** - * @brief Selects the USART WakeUp method. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param USART_WakeUp: specifies the USART wakeup method. - * This parameter can be one of the following values: - * @arg USART_WakeUp_IdleLine: WakeUp by an idle line detection - * @arg USART_WakeUp_AddressMark: WakeUp by an address mark - * @retval None - */ -void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_WAKEUP(USART_WakeUp)); - - USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_WAKE); - USARTx->CR1 |= USART_WakeUp; -} - -/** - * @} - */ - -/** @defgroup USART_Group4 LIN mode functions - * @brief LIN mode functions - * -@verbatim - =============================================================================== - LIN mode functions - =============================================================================== - - This subsection provides a set of functions allowing to manage the USART LIN - Mode communication. - - In LIN mode, 8-bit data format with 1 stop bit is required in accordance with - the LIN standard. - - Only this LIN Feature is supported by the USART IP: - - LIN Master Synchronous Break send capability and LIN slave break detection - capability : 13-bit break generation and 10/11 bit break detection - - - USART LIN Master transmitter communication is possible through the following procedure: - 1. Program the Baud rate, Word length = 8bits, Stop bits = 1bit, Parity, - Mode transmitter or Mode receiver and hardware flow control values using - the USART_Init() function. - 2. Enable the USART using the USART_Cmd() function. - 3. Enable the LIN mode using the USART_LINCmd() function. - 4. Send the break character using USART_SendBreak() function. - - USART LIN Master receiver communication is possible through the following procedure: - 1. Program the Baud rate, Word length = 8bits, Stop bits = 1bit, Parity, - Mode transmitter or Mode receiver and hardware flow control values using - the USART_Init() function. - 2. Enable the USART using the USART_Cmd() function. - 3. Configures the break detection length using the USART_LINBreakDetectLengthConfig() - function. - 4. Enable the LIN mode using the USART_LINCmd() function. - - -@note In LIN mode, the following bits must be kept cleared: - - CLKEN in the USART_CR2 register, - - STOP[1:0], SCEN, HDSEL and IREN in the USART_CR3 register. - -@endverbatim - * @{ - */ - -/** - * @brief Sets the USART LIN Break detection length. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param USART_LINBreakDetectLength: specifies the LIN break detection length. - * This parameter can be one of the following values: - * @arg USART_LINBreakDetectLength_10b: 10-bit break detection - * @arg USART_LINBreakDetectLength_11b: 11-bit break detection - * @retval None - */ -void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_LIN_BREAK_DETECT_LENGTH(USART_LINBreakDetectLength)); - - USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_LBDL); - USARTx->CR2 |= USART_LINBreakDetectLength; -} - -/** - * @brief Enables or disables the USART's LIN mode. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param NewState: new state of the USART LIN mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the LIN mode by setting the LINEN bit in the CR2 register */ - USARTx->CR2 |= USART_CR2_LINEN; - } - else - { - /* Disable the LIN mode by clearing the LINEN bit in the CR2 register */ - USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_LINEN); - } -} - -/** - * @brief Transmits break characters. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @retval None - */ -void USART_SendBreak(USART_TypeDef* USARTx) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - - /* Send break characters */ - USARTx->CR1 |= USART_CR1_SBK; -} - -/** - * @} - */ - -/** @defgroup USART_Group5 Halfduplex mode function - * @brief Half-duplex mode function - * -@verbatim - =============================================================================== - Half-duplex mode function - =============================================================================== - - This subsection provides a set of functions allowing to manage the USART - Half-duplex communication. - - The USART can be configured to follow a single-wire half-duplex protocol where - the TX and RX lines are internally connected. - - USART Half duplex communication is possible through the following procedure: - 1. Program the Baud rate, Word length, Stop bits, Parity, Mode transmitter - or Mode receiver and hardware flow control values using the USART_Init() - function. - 2. Configures the USART address using the USART_SetAddress() function. - 3. Enable the USART using the USART_Cmd() function. - 4. Enable the half duplex mode using USART_HalfDuplexCmd() function. - - -@note The RX pin is no longer used -@note In Half-duplex mode the following bits must be kept cleared: - - LINEN and CLKEN bits in the USART_CR2 register. - - SCEN and IREN bits in the USART_CR3 register. - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the USART's Half Duplex communication. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param NewState: new state of the USART Communication. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ - USARTx->CR3 |= USART_CR3_HDSEL; - } - else - { - /* Disable the Half-Duplex mode by clearing the HDSEL bit in the CR3 register */ - USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_HDSEL); - } -} - -/** - * @} - */ - - -/** @defgroup USART_Group6 Smartcard mode functions - * @brief Smartcard mode functions - * -@verbatim - =============================================================================== - Smartcard mode functions - =============================================================================== - - This subsection provides a set of functions allowing to manage the USART - Smartcard communication. - - The Smartcard interface is designed to support asynchronous protocol Smartcards as - defined in the ISO 7816-3 standard. - - The USART can provide a clock to the smartcard through the SCLK output. - In smartcard mode, SCLK is not associated to the communication but is simply derived - from the internal peripheral input clock through a 5-bit prescaler. - - Smartcard communication is possible through the following procedure: - 1. Configures the Smartcard Prescaler using the USART_SetPrescaler() function. - 2. Configures the Smartcard Guard Time using the USART_SetGuardTime() function. - 3. Program the USART clock using the USART_ClockInit() function as following: - - USART Clock enabled - - USART CPOL Low - - USART CPHA on first edge - - USART Last Bit Clock Enabled - 4. Program the Smartcard interface using the USART_Init() function as following: - - Word Length = 9 Bits - - 1.5 Stop Bit - - Even parity - - BaudRate = 12096 baud - - Hardware flow control disabled (RTS and CTS signals) - - Tx and Rx enabled - 5. Optionally you can enable the parity error interrupt using the USART_ITConfig() - function - 6. Enable the USART using the USART_Cmd() function. - 7. Enable the Smartcard NACK using the USART_SmartCardNACKCmd() function. - 8. Enable the Smartcard interface using the USART_SmartCardCmd() function. - - Please refer to the ISO 7816-3 specification for more details. - - -@note It is also possible to choose 0.5 stop bit for receiving but it is recommended - to use 1.5 stop bits for both transmitting and receiving to avoid switching - between the two configurations. -@note In smartcard mode, the following bits must be kept cleared: - - LINEN bit in the USART_CR2 register. - - HDSEL and IREN bits in the USART_CR3 register. -@note Smartcard mode is available on USART peripherals only (not available on UART4 - and UART5 peripherals). - -@endverbatim - * @{ - */ - -/** - * @brief Sets the specified USART guard time. - * @param USARTx: where x can be 1, 2, 3 or 6 to select the USART or - * UART peripheral. - * @param USART_GuardTime: specifies the guard time. - * @retval None - */ -void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime) -{ - /* Check the parameters */ - assert_param(IS_USART_1236_PERIPH(USARTx)); - - /* Clear the USART Guard time */ - USARTx->GTPR &= USART_GTPR_PSC; - /* Set the USART guard time */ - USARTx->GTPR |= (uint16_t)((uint16_t)USART_GuardTime << 0x08); -} - -/** - * @brief Enables or disables the USART's Smart Card mode. - * @param USARTx: where x can be 1, 2, 3 or 6 to select the USART or - * UART peripheral. - * @param NewState: new state of the Smart Card mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_1236_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the SC mode by setting the SCEN bit in the CR3 register */ - USARTx->CR3 |= USART_CR3_SCEN; - } - else - { - /* Disable the SC mode by clearing the SCEN bit in the CR3 register */ - USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_SCEN); - } -} - -/** - * @brief Enables or disables NACK transmission. - * @param USARTx: where x can be 1, 2, 3 or 6 to select the USART or - * UART peripheral. - * @param NewState: new state of the NACK transmission. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_1236_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - if (NewState != DISABLE) - { - /* Enable the NACK transmission by setting the NACK bit in the CR3 register */ - USARTx->CR3 |= USART_CR3_NACK; - } - else - { - /* Disable the NACK transmission by clearing the NACK bit in the CR3 register */ - USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_NACK); - } -} - -/** - * @} - */ - -/** @defgroup USART_Group7 IrDA mode functions - * @brief IrDA mode functions - * -@verbatim - =============================================================================== - IrDA mode functions - =============================================================================== - - This subsection provides a set of functions allowing to manage the USART - IrDA communication. - - IrDA is a half duplex communication protocol. If the Transmitter is busy, any data - on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver - is busy, data on the TX from the USART to IrDA will not be encoded by IrDA. - While receiving data, transmission should be avoided as the data to be transmitted - could be corrupted. - - IrDA communication is possible through the following procedure: - 1. Program the Baud rate, Word length = 8 bits, Stop bits, Parity, Transmitter/Receiver - modes and hardware flow control values using the USART_Init() function. - 2. Enable the USART using the USART_Cmd() function. - 3. Configures the IrDA pulse width by configuring the prescaler using - the USART_SetPrescaler() function. - 4. Configures the IrDA USART_IrDAMode_LowPower or USART_IrDAMode_Normal mode - using the USART_IrDAConfig() function. - 5. Enable the IrDA using the USART_IrDACmd() function. - -@note A pulse of width less than two and greater than one PSC period(s) may or may - not be rejected. -@note The receiver set up time should be managed by software. The IrDA physical layer - specification specifies a minimum of 10 ms delay between transmission and - reception (IrDA is a half duplex protocol). -@note In IrDA mode, the following bits must be kept cleared: - - LINEN, STOP and CLKEN bits in the USART_CR2 register. - - SCEN and HDSEL bits in the USART_CR3 register. - -@endverbatim - * @{ - */ - -/** - * @brief Configures the USART's IrDA interface. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param USART_IrDAMode: specifies the IrDA mode. - * This parameter can be one of the following values: - * @arg USART_IrDAMode_LowPower - * @arg USART_IrDAMode_Normal - * @retval None - */ -void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_IRDA_MODE(USART_IrDAMode)); - - USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_IRLP); - USARTx->CR3 |= USART_IrDAMode; -} - -/** - * @brief Enables or disables the USART's IrDA interface. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param NewState: new state of the IrDA mode. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the IrDA mode by setting the IREN bit in the CR3 register */ - USARTx->CR3 |= USART_CR3_IREN; - } - else - { - /* Disable the IrDA mode by clearing the IREN bit in the CR3 register */ - USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_IREN); - } -} - -/** - * @} - */ - -/** @defgroup USART_Group8 DMA transfers management functions - * @brief DMA transfers management functions - * -@verbatim - =============================================================================== - DMA transfers management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the USART's DMA interface. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param USART_DMAReq: specifies the DMA request. - * This parameter can be any combination of the following values: - * @arg USART_DMAReq_Tx: USART DMA transmit request - * @arg USART_DMAReq_Rx: USART DMA receive request - * @param NewState: new state of the DMA Request sources. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_DMAREQ(USART_DMAReq)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - if (NewState != DISABLE) - { - /* Enable the DMA transfer for selected requests by setting the DMAT and/or - DMAR bits in the USART CR3 register */ - USARTx->CR3 |= USART_DMAReq; - } - else - { - /* Disable the DMA transfer for selected requests by clearing the DMAT and/or - DMAR bits in the USART CR3 register */ - USARTx->CR3 &= (uint16_t)~USART_DMAReq; - } -} - -/** - * @} - */ - -/** @defgroup USART_Group9 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - - This subsection provides a set of functions allowing to configure the USART - Interrupts sources, DMA channels requests and check or clear the flags or - pending bits status. - The user should identify which mode will be used in his application to manage - the communication: Polling mode, Interrupt mode or DMA mode. - - Polling Mode - ============= - In Polling Mode, the SPI communication can be managed by 10 flags: - 1. USART_FLAG_TXE : to indicate the status of the transmit buffer register - 2. USART_FLAG_RXNE : to indicate the status of the receive buffer register - 3. USART_FLAG_TC : to indicate the status of the transmit operation - 4. USART_FLAG_IDLE : to indicate the status of the Idle Line - 5. USART_FLAG_CTS : to indicate the status of the nCTS input - 6. USART_FLAG_LBD : to indicate the status of the LIN break detection - 7. USART_FLAG_NE : to indicate if a noise error occur - 8. USART_FLAG_FE : to indicate if a frame error occur - 9. USART_FLAG_PE : to indicate if a parity error occur - 10. USART_FLAG_ORE : to indicate if an Overrun error occur - - In this Mode it is advised to use the following functions: - - FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); - - void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG); - - Interrupt Mode - =============== - In Interrupt Mode, the USART communication can be managed by 8 interrupt sources - and 10 pending bits: - - Pending Bits: - ------------- - 1. USART_IT_TXE : to indicate the status of the transmit buffer register - 2. USART_IT_RXNE : to indicate the status of the receive buffer register - 3. USART_IT_TC : to indicate the status of the transmit operation - 4. USART_IT_IDLE : to indicate the status of the Idle Line - 5. USART_IT_CTS : to indicate the status of the nCTS input - 6. USART_IT_LBD : to indicate the status of the LIN break detection - 7. USART_IT_NE : to indicate if a noise error occur - 8. USART_IT_FE : to indicate if a frame error occur - 9. USART_IT_PE : to indicate if a parity error occur - 10. USART_IT_ORE : to indicate if an Overrun error occur - - Interrupt Source: - ----------------- - 1. USART_IT_TXE : specifies the interrupt source for the Tx buffer empty - interrupt. - 2. USART_IT_RXNE : specifies the interrupt source for the Rx buffer not - empty interrupt. - 3. USART_IT_TC : specifies the interrupt source for the Transmit complete - interrupt. - 4. USART_IT_IDLE : specifies the interrupt source for the Idle Line interrupt. - 5. USART_IT_CTS : specifies the interrupt source for the CTS interrupt. - 6. USART_IT_LBD : specifies the interrupt source for the LIN break detection - interrupt. - 7. USART_IT_PE : specifies the interrupt source for the parity error interrupt. - 8. USART_IT_ERR : specifies the interrupt source for the errors interrupt. - -@note Some parameters are coded in order to use them as interrupt source or as pending bits. - - In this Mode it is advised to use the following functions: - - void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState); - - ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT); - - void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT); - - DMA Mode - ======== - In DMA Mode, the USART communication can be managed by 2 DMA Channel requests: - 1. USART_DMAReq_Tx: specifies the Tx buffer DMA transfer request - 2. USART_DMAReq_Rx: specifies the Rx buffer DMA transfer request - - In this Mode it is advised to use the following function: - - void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState); - -@endverbatim - * @{ - */ - -/** - * @brief Enables or disables the specified USART interrupts. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param USART_IT: specifies the USART interrupt sources to be enabled or disabled. - * This parameter can be one of the following values: - * @arg USART_IT_CTS: CTS change interrupt - * @arg USART_IT_LBD: LIN Break detection interrupt - * @arg USART_IT_TXE: Transmit Data Register empty interrupt - * @arg USART_IT_TC: Transmission complete interrupt - * @arg USART_IT_RXNE: Receive Data register not empty interrupt - * @arg USART_IT_IDLE: Idle line detection interrupt - * @arg USART_IT_PE: Parity Error interrupt - * @arg USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error) - * @param NewState: new state of the specified USARTx interrupts. - * This parameter can be: ENABLE or DISABLE. - * @retval None - */ -void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState) -{ - uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00; - uint32_t usartxbase = 0x00; - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_CONFIG_IT(USART_IT)); - assert_param(IS_FUNCTIONAL_STATE(NewState)); - - /* The CTS interrupt is not available for UART4 and UART5 */ - if (USART_IT == USART_IT_CTS) - { - assert_param(IS_USART_1236_PERIPH(USARTx)); - } - - usartxbase = (uint32_t)USARTx; - - /* Get the USART register index */ - usartreg = (((uint8_t)USART_IT) >> 0x05); - - /* Get the interrupt position */ - itpos = USART_IT & IT_MASK; - itmask = (((uint32_t)0x01) << itpos); - - if (usartreg == 0x01) /* The IT is in CR1 register */ - { - usartxbase += 0x0C; - } - else if (usartreg == 0x02) /* The IT is in CR2 register */ - { - usartxbase += 0x10; - } - else /* The IT is in CR3 register */ - { - usartxbase += 0x14; - } - if (NewState != DISABLE) - { - *(__IO uint32_t*)usartxbase |= itmask; - } - else - { - *(__IO uint32_t*)usartxbase &= ~itmask; - } -} - -/** - * @brief Checks whether the specified USART flag is set or not. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param USART_FLAG: specifies the flag to check. - * This parameter can be one of the following values: - * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5) - * @arg USART_FLAG_LBD: LIN Break detection flag - * @arg USART_FLAG_TXE: Transmit data register empty flag - * @arg USART_FLAG_TC: Transmission Complete flag - * @arg USART_FLAG_RXNE: Receive data register not empty flag - * @arg USART_FLAG_IDLE: Idle Line detection flag - * @arg USART_FLAG_ORE: OverRun Error flag - * @arg USART_FLAG_NE: Noise Error flag - * @arg USART_FLAG_FE: Framing Error flag - * @arg USART_FLAG_PE: Parity Error flag - * @retval The new state of USART_FLAG (SET or RESET). - */ -FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG) -{ - FlagStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_FLAG(USART_FLAG)); - - /* The CTS flag is not available for UART4 and UART5 */ - if (USART_FLAG == USART_FLAG_CTS) - { - assert_param(IS_USART_1236_PERIPH(USARTx)); - } - - if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears the USARTx's pending flags. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param USART_FLAG: specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5). - * @arg USART_FLAG_LBD: LIN Break detection flag. - * @arg USART_FLAG_TC: Transmission Complete flag. - * @arg USART_FLAG_RXNE: Receive data register not empty flag. - * - * @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun - * error) and IDLE (Idle line detected) flags are cleared by software - * sequence: a read operation to USART_SR register (USART_GetFlagStatus()) - * followed by a read operation to USART_DR register (USART_ReceiveData()). - * @note RXNE flag can be also cleared by a read to the USART_DR register - * (USART_ReceiveData()). - * @note TC flag can be also cleared by software sequence: a read operation to - * USART_SR register (USART_GetFlagStatus()) followed by a write operation - * to USART_DR register (USART_SendData()). - * @note TXE flag is cleared only by a write to the USART_DR register - * (USART_SendData()). - * - * @retval None - */ -void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG) -{ - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_CLEAR_FLAG(USART_FLAG)); - - /* The CTS flag is not available for UART4 and UART5 */ - if ((USART_FLAG & USART_FLAG_CTS) == USART_FLAG_CTS) - { - assert_param(IS_USART_1236_PERIPH(USARTx)); - } - - USARTx->SR = (uint16_t)~USART_FLAG; -} - -/** - * @brief Checks whether the specified USART interrupt has occurred or not. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param USART_IT: specifies the USART interrupt source to check. - * This parameter can be one of the following values: - * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) - * @arg USART_IT_LBD: LIN Break detection interrupt - * @arg USART_IT_TXE: Transmit Data Register empty interrupt - * @arg USART_IT_TC: Transmission complete interrupt - * @arg USART_IT_RXNE: Receive Data register not empty interrupt - * @arg USART_IT_IDLE: Idle line detection interrupt - * @arg USART_IT_ORE: OverRun Error interrupt - * @arg USART_IT_NE: Noise Error interrupt - * @arg USART_IT_FE: Framing Error interrupt - * @arg USART_IT_PE: Parity Error interrupt - * @retval The new state of USART_IT (SET or RESET). - */ -ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT) -{ - uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00; - ITStatus bitstatus = RESET; - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_GET_IT(USART_IT)); - - /* The CTS interrupt is not available for UART4 and UART5 */ - if (USART_IT == USART_IT_CTS) - { - assert_param(IS_USART_1236_PERIPH(USARTx)); - } - - /* Get the USART register index */ - usartreg = (((uint8_t)USART_IT) >> 0x05); - /* Get the interrupt position */ - itmask = USART_IT & IT_MASK; - itmask = (uint32_t)0x01 << itmask; - - if (usartreg == 0x01) /* The IT is in CR1 register */ - { - itmask &= USARTx->CR1; - } - else if (usartreg == 0x02) /* The IT is in CR2 register */ - { - itmask &= USARTx->CR2; - } - else /* The IT is in CR3 register */ - { - itmask &= USARTx->CR3; - } - - bitpos = USART_IT >> 0x08; - bitpos = (uint32_t)0x01 << bitpos; - bitpos &= USARTx->SR; - if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET)) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - - return bitstatus; -} - -/** - * @brief Clears the USARTx's interrupt pending bits. - * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or - * UART peripheral. - * @param USART_IT: specifies the interrupt pending bit to clear. - * This parameter can be one of the following values: - * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) - * @arg USART_IT_LBD: LIN Break detection interrupt - * @arg USART_IT_TC: Transmission complete interrupt. - * @arg USART_IT_RXNE: Receive Data register not empty interrupt. - * - * @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun - * error) and IDLE (Idle line detected) pending bits are cleared by - * software sequence: a read operation to USART_SR register - * (USART_GetITStatus()) followed by a read operation to USART_DR register - * (USART_ReceiveData()). - * @note RXNE pending bit can be also cleared by a read to the USART_DR register - * (USART_ReceiveData()). - * @note TC pending bit can be also cleared by software sequence: a read - * operation to USART_SR register (USART_GetITStatus()) followed by a write - * operation to USART_DR register (USART_SendData()). - * @note TXE pending bit is cleared only by a write to the USART_DR register - * (USART_SendData()). - * - * @retval None - */ -void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT) -{ - uint16_t bitpos = 0x00, itmask = 0x00; - /* Check the parameters */ - assert_param(IS_USART_ALL_PERIPH(USARTx)); - assert_param(IS_USART_CLEAR_IT(USART_IT)); - - /* The CTS interrupt is not available for UART4 and UART5 */ - if (USART_IT == USART_IT_CTS) - { - assert_param(IS_USART_1236_PERIPH(USARTx)); - } - - bitpos = USART_IT >> 0x08; - itmask = ((uint16_t)0x01 << (uint16_t)bitpos); - USARTx->SR = (uint16_t)~itmask; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_wwdg.c b/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_wwdg.c deleted file mode 100644 index 3491c6d88..000000000 --- a/example/stm32f4/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_wwdg.c +++ /dev/null @@ -1,303 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_wwdg.c - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 25-August-2011 - * @brief This file provides firmware functions to manage the following - * functionalities of the Window watchdog (WWDG) peripheral: - * - Prescaler, Refresh window and Counter configuration - * - WWDG activation - * - Interrupts and flags management - * - * @verbatim - * - * =================================================================== - * WWDG features - * =================================================================== - * - * Once enabled the WWDG generates a system reset on expiry of a programmed - * time period, unless the program refreshes the counter (downcounter) - * before to reach 0x3F value (i.e. a reset is generated when the counter - * value rolls over from 0x40 to 0x3F). - * An MCU reset is also generated if the counter value is refreshed - * before the counter has reached the refresh window value. This - * implies that the counter must be refreshed in a limited window. - * - * Once enabled the WWDG cannot be disabled except by a system reset. - * - * WWDGRST flag in RCC_CSR register can be used to inform when a WWDG - * reset occurs. - * - * The WWDG counter input clock is derived from the APB clock divided - * by a programmable prescaler. - * - * WWDG counter clock = PCLK1 / Prescaler - * WWDG timeout = (WWDG counter clock) * (counter value) - * - * Min-max timeout value @30 MHz(PCLK1): ~136.5 us / ~69.9 ms - * - * =================================================================== - * How to use this driver - * =================================================================== - * 1. Enable WWDG clock using RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE) function - * - * 2. Configure the WWDG prescaler using WWDG_SetPrescaler() function - * - * 3. Configure the WWDG refresh window using WWDG_SetWindowValue() function - * - * 4. Set the WWDG counter value and start it using WWDG_Enable() function. - * When the WWDG is enabled the counter value should be configured to - * a value greater than 0x40 to prevent generating an immediate reset. - * - * 5. Optionally you can enable the Early wakeup interrupt which is - * generated when the counter reach 0x40. - * Once enabled this interrupt cannot be disabled except by a system reset. - * - * 6. Then the application program must refresh the WWDG counter at regular - * intervals during normal operation to prevent an MCU reset, using - * WWDG_SetCounter() function. This operation must occur only when - * the counter value is lower than the refresh window value, - * programmed using WWDG_SetWindowValue(). - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_wwdg.h" -#include "stm32f4xx_rcc.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @defgroup WWDG - * @brief WWDG driver modules - * @{ - */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ - -/* ----------- WWDG registers bit address in the alias region ----------- */ -#define WWDG_OFFSET (WWDG_BASE - PERIPH_BASE) -/* Alias word address of EWI bit */ -#define CFR_OFFSET (WWDG_OFFSET + 0x04) -#define EWI_BitNumber 0x09 -#define CFR_EWI_BB (PERIPH_BB_BASE + (CFR_OFFSET * 32) + (EWI_BitNumber * 4)) - -/* --------------------- WWDG registers bit mask ------------------------ */ -/* CFR register bit mask */ -#define CFR_WDGTB_MASK ((uint32_t)0xFFFFFE7F) -#define CFR_W_MASK ((uint32_t)0xFFFFFF80) -#define BIT_MASK ((uint8_t)0x7F) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** @defgroup WWDG_Private_Functions - * @{ - */ - -/** @defgroup WWDG_Group1 Prescaler, Refresh window and Counter configuration functions - * @brief Prescaler, Refresh window and Counter configuration functions - * -@verbatim - =============================================================================== - Prescaler, Refresh window and Counter configuration functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Deinitializes the WWDG peripheral registers to their default reset values. - * @param None - * @retval None - */ -void WWDG_DeInit(void) -{ - RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, ENABLE); - RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, DISABLE); -} - -/** - * @brief Sets the WWDG Prescaler. - * @param WWDG_Prescaler: specifies the WWDG Prescaler. - * This parameter can be one of the following values: - * @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1 - * @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2 - * @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4 - * @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8 - * @retval None - */ -void WWDG_SetPrescaler(uint32_t WWDG_Prescaler) -{ - uint32_t tmpreg = 0; - /* Check the parameters */ - assert_param(IS_WWDG_PRESCALER(WWDG_Prescaler)); - /* Clear WDGTB[1:0] bits */ - tmpreg = WWDG->CFR & CFR_WDGTB_MASK; - /* Set WDGTB[1:0] bits according to WWDG_Prescaler value */ - tmpreg |= WWDG_Prescaler; - /* Store the new value */ - WWDG->CFR = tmpreg; -} - -/** - * @brief Sets the WWDG window value. - * @param WindowValue: specifies the window value to be compared to the downcounter. - * This parameter value must be lower than 0x80. - * @retval None - */ -void WWDG_SetWindowValue(uint8_t WindowValue) -{ - __IO uint32_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_WWDG_WINDOW_VALUE(WindowValue)); - /* Clear W[6:0] bits */ - - tmpreg = WWDG->CFR & CFR_W_MASK; - - /* Set W[6:0] bits according to WindowValue value */ - tmpreg |= WindowValue & (uint32_t) BIT_MASK; - - /* Store the new value */ - WWDG->CFR = tmpreg; -} - -/** - * @brief Enables the WWDG Early Wakeup interrupt(EWI). - * @note Once enabled this interrupt cannot be disabled except by a system reset. - * @param None - * @retval None - */ -void WWDG_EnableIT(void) -{ - *(__IO uint32_t *) CFR_EWI_BB = (uint32_t)ENABLE; -} - -/** - * @brief Sets the WWDG counter value. - * @param Counter: specifies the watchdog counter value. - * This parameter must be a number between 0x40 and 0x7F (to prevent generating - * an immediate reset) - * @retval None - */ -void WWDG_SetCounter(uint8_t Counter) -{ - /* Check the parameters */ - assert_param(IS_WWDG_COUNTER(Counter)); - /* Write to T[6:0] bits to configure the counter value, no need to do - a read-modify-write; writing a 0 to WDGA bit does nothing */ - WWDG->CR = Counter & BIT_MASK; -} -/** - * @} - */ - -/** @defgroup WWDG_Group2 WWDG activation functions - * @brief WWDG activation functions - * -@verbatim - =============================================================================== - WWDG activation function - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Enables WWDG and load the counter value. - * @param Counter: specifies the watchdog counter value. - * This parameter must be a number between 0x40 and 0x7F (to prevent generating - * an immediate reset) - * @retval None - */ -void WWDG_Enable(uint8_t Counter) -{ - /* Check the parameters */ - assert_param(IS_WWDG_COUNTER(Counter)); - WWDG->CR = WWDG_CR_WDGA | Counter; -} -/** - * @} - */ - -/** @defgroup WWDG_Group3 Interrupts and flags management functions - * @brief Interrupts and flags management functions - * -@verbatim - =============================================================================== - Interrupts and flags management functions - =============================================================================== - -@endverbatim - * @{ - */ - -/** - * @brief Checks whether the Early Wakeup interrupt flag is set or not. - * @param None - * @retval The new state of the Early Wakeup interrupt flag (SET or RESET) - */ -FlagStatus WWDG_GetFlagStatus(void) -{ - FlagStatus bitstatus = RESET; - - if ((WWDG->SR) != (uint32_t)RESET) - { - bitstatus = SET; - } - else - { - bitstatus = RESET; - } - return bitstatus; -} - -/** - * @brief Clears Early Wakeup interrupt flag. - * @param None - * @retval None - */ -void WWDG_ClearFlag(void) -{ - WWDG->SR = (uint32_t)RESET; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h b/example/stm32f4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h deleted file mode 100644 index f58ff0601..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h +++ /dev/null @@ -1,158 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_audio_core.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header file for the usbd_audio_core.c file. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ - -#ifndef __USB_AUDIO_CORE_H_ -#define __USB_AUDIO_CORE_H_ - -#include "usbd_ioreq.h" -#include "usbd_req.h" -#include "usbd_desc.h" - - - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup usbd_audio - * @brief This file is the Header file for USBD_audio.c - * @{ - */ - - -/** @defgroup usbd_audio_Exported_Defines - * @{ - */ - -/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */ -#define AUDIO_OUT_PACKET (uint32_t)(((USBD_AUDIO_FREQ * 2 * 2) /1000)) - -/* Number of sub-packets in the audio transfer buffer. You can modify this value but always make sure - that it is an even number and higher than 3 */ -#define OUT_PACKET_NUM 4 -/* Total size of the audio transfer buffer */ -#define TOTAL_OUT_BUF_SIZE ((uint32_t)(AUDIO_OUT_PACKET * OUT_PACKET_NUM)) - -#define AUDIO_CONFIG_DESC_SIZE 109 -#define AUDIO_INTERFACE_DESC_SIZE 9 -#define USB_AUDIO_DESC_SIZ 0x09 -#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE 0x09 -#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE 0x07 - -#define AUDIO_DESCRIPTOR_TYPE 0x21 -#define USB_DEVICE_CLASS_AUDIO 0x01 -#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01 -#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02 -#define AUDIO_PROTOCOL_UNDEFINED 0x00 -#define AUDIO_STREAMING_GENERAL 0x01 -#define AUDIO_STREAMING_FORMAT_TYPE 0x02 - -/* Audio Descriptor Types */ -#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24 -#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25 - -/* Audio Control Interface Descriptor Subtypes */ -#define AUDIO_CONTROL_HEADER 0x01 -#define AUDIO_CONTROL_INPUT_TERMINAL 0x02 -#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03 -#define AUDIO_CONTROL_FEATURE_UNIT 0x06 - -#define AUDIO_INPUT_TERMINAL_DESC_SIZE 0x0C -#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE 0x09 -#define AUDIO_STREAMING_INTERFACE_DESC_SIZE 0x07 - -#define AUDIO_CONTROL_MUTE 0x0001 - -#define AUDIO_FORMAT_TYPE_I 0x01 -#define AUDIO_FORMAT_TYPE_III 0x03 - -#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 -#define AUDIO_ENDPOINT_GENERAL 0x01 - -#define AUDIO_REQ_GET_CUR 0x81 -#define AUDIO_REQ_SET_CUR 0x01 - -#define AUDIO_OUT_STREAMING_CTRL 0x02 - -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_TypesDefinitions - * @{ - */ -typedef struct _Audio_Fops -{ - uint8_t (*Init) (uint32_t AudioFreq, uint32_t Volume, uint32_t options); - uint8_t (*DeInit) (uint32_t options); - uint8_t (*AudioCmd) (uint8_t* pbuf, uint32_t size, uint8_t cmd); - uint8_t (*VolumeCtl) (uint8_t vol); - uint8_t (*MuteCtl) (uint8_t cmd); - uint8_t (*PeriodicTC) (uint8_t cmd); - uint8_t (*GetState) (void); -}AUDIO_FOPS_TypeDef; -/** - * @} - */ - - - -/** @defgroup USBD_CORE_Exported_Macros - * @{ - */ -#define AUDIO_PACKET_SZE(frq) (uint8_t)(((frq * 2 * 2)/1000) & 0xFF), \ - (uint8_t)((((frq * 2 * 2)/1000) >> 8) & 0xFF) -#define SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16)) -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Variables - * @{ - */ - -extern USBD_Class_cb_TypeDef AUDIO_cb; - -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Functions - * @{ - */ -/** - * @} - */ - -#endif // __USB_AUDIO_CORE_H_ -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_out_if.h b/example/stm32f4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_out_if.h deleted file mode 100644 index a6b53fa83..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_out_if.h +++ /dev/null @@ -1,117 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_audio_out_if.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header file for the usbd_audio_out_if.c file. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ - -#ifndef __USB_AUDIO_OUT_IF_H_ -#define __USB_AUDIO_OUT_IF_H_ - -#ifdef STM32F2XX - #include "stm322xg_usb_audio_codec.h" -#elif defined(STM32F10X_CL) - #include "stm3210c_usb_audio_codec.h" -#endif /* STM32F2XX */ - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup usbd_audio - * @brief This file is the Header file for USBD_audio.c - * @{ - */ - - -/** @defgroup usbd_audio_Exported_Defines - * @{ - */ -/* Audio Commands enmueration */ -typedef enum -{ - AUDIO_CMD_PLAY = 1, - AUDIO_CMD_PAUSE, - AUDIO_CMD_STOP, -}AUDIO_CMD_TypeDef; - -/* Mute commands */ -#define AUDIO_MUTE 0x01 -#define AUDIO_UNMUTE 0x00 - -/* Functions return value */ -#define AUDIO_OK 0x00 -#define AUDIO_FAIL 0xFF - -/* Audio Machine States */ -#define AUDIO_STATE_INACTIVE 0x00 -#define AUDIO_STATE_ACTIVE 0x01 -#define AUDIO_STATE_PLAYING 0x02 -#define AUDIO_STATE_PAUSED 0x03 -#define AUDIO_STATE_STOPPED 0x04 -#define AUDIO_STATE_ERROR 0x05 - -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USBD_CORE_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Variables - * @{ - */ - -extern AUDIO_FOPS_TypeDef AUDIO_OUT_fops; - -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Functions - * @{ - */ -/** - * @} - */ - -#endif /* __USB_AUDIO_OUT_IF_H_ */ -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c b/example/stm32f4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c deleted file mode 100644 index b26f574a3..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c +++ /dev/null @@ -1,665 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_audio_core.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the high layer firmware functions to manage the - * following functionalities of the USB Audio Class: - * - Initialization and Configuration of high and low layer - * - Enumeration as Audio Streaming Device - * - Audio Streaming data transfer - * - AudioControl requests management - * - Error management - * - * @verbatim - * - * =================================================================== - * Audio Class Driver Description - * =================================================================== - * This driver manages the Audio Class 1.0 following the "USB Device Class Definition for - * Audio Devices V1.0 Mar 18, 98". - * This driver implements the following aspects of the specification: - * - Device descriptor management - * - Configuration descriptor management - * - Standard AC Interface Descriptor management - * - 1 Audio Streaming Interface (with single channel, PCM, Stereo mode) - * - 1 Audio Streaming Endpoint - * - 1 Audio Terminal Input (1 channel) - * - Audio Class-Specific AC Interfaces - * - Audio Class-Specific AS Interfaces - * - AudioControl Requests: only SET_CUR and GET_CUR requests are supported (for Mute) - * - Audio Feature Unit (limited to Mute control) - * - Audio Synchronization type: Asynchronous - * - Single fixed audio sampling rate (configurable in usbd_conf.h file) - * - * @note - * The Audio Class 1.0 is based on USB Specification 1.0 and thus supports only - * Low and Full speed modes and does not allow High Speed transfers. - * Please refer to "USB Device Class Definition for Audio Devices V1.0 Mar 18, 98" - * for more details. - * - * These aspects may be enriched or modified for a specific user application. - * - * This driver doesn't implement the following aspects of the specification - * (but it is possible to manage these features with some modifications on this driver): - * - AudioControl Endpoint management - * - AudioControl requsests other than SET_CUR and GET_CUR - * - Abstraction layer for AudioControl requests (only Mute functionality is managed) - * - Audio Synchronization type: Adaptive - * - Audio Compression modules and interfaces - * - MIDI interfaces and modules - * - Mixer/Selector/Processing/Extension Units (Feature unit is limited to Mute control) - * - Any other application-specific modules - * - Multiple and Variable audio sampling rates - * - Out Streaming Endpoint/Interface (microphone) - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ - -#include "usbd_audio_core.h" -#include "usbd_audio_out_if.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup usbd_audio - * @brief usbd core module - * @{ - */ - -/** @defgroup usbd_audio_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_audio_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_audio_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_audio_Private_FunctionPrototypes - * @{ - */ - -/********************************************* - AUDIO Device library callbacks - *********************************************/ -static uint8_t usbd_audio_Init (void *pdev, uint8_t cfgidx); -static uint8_t usbd_audio_DeInit (void *pdev, uint8_t cfgidx); -static uint8_t usbd_audio_Setup (void *pdev, USB_SETUP_REQ *req); -static uint8_t usbd_audio_EP0_RxReady(void *pdev); -static uint8_t usbd_audio_DataIn (void *pdev, uint8_t epnum); -static uint8_t usbd_audio_DataOut (void *pdev, uint8_t epnum); -static uint8_t usbd_audio_SOF (void *pdev); -static uint8_t usbd_audio_OUT_Incplt (void *pdev); - -/********************************************* - AUDIO Requests management functions - *********************************************/ -static void AUDIO_Req_GetCurrent(void *pdev, USB_SETUP_REQ *req); -static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req); -static uint8_t *USBD_audio_GetCfgDesc (uint8_t speed, uint16_t *length); -/** - * @} - */ - -/** @defgroup usbd_audio_Private_Variables - * @{ - */ -/* Main Buffer for Audio Data Out transfers and its relative pointers */ -uint8_t IsocOutBuff [TOTAL_OUT_BUF_SIZE * 2]; -uint8_t* IsocOutWrPtr = IsocOutBuff; -uint8_t* IsocOutRdPtr = IsocOutBuff; - -/* Main Buffer for Audio Control Rrequests transfers and its relative variables */ -uint8_t AudioCtl[64]; -uint8_t AudioCtlCmd = 0; -uint32_t AudioCtlLen = 0; -uint8_t AudioCtlUnit = 0; - -static uint32_t PlayFlag = 0; - -static __IO uint32_t usbd_audio_AltSet = 0; -static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE]; - -/* AUDIO interface class callbacks structure */ -USBD_Class_cb_TypeDef AUDIO_cb = -{ - usbd_audio_Init, - usbd_audio_DeInit, - usbd_audio_Setup, - NULL, /* EP0_TxSent */ - usbd_audio_EP0_RxReady, - usbd_audio_DataIn, - usbd_audio_DataOut, - usbd_audio_SOF, - NULL, - usbd_audio_OUT_Incplt, - USBD_audio_GetCfgDesc, -#ifdef USB_OTG_HS_CORE - USBD_audio_GetCfgDesc, /* use same config as per FS */ -#endif -}; - -/* USB AUDIO device Configuration Descriptor */ -static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE] = -{ - /* Configuration 1 */ - 0x09, /* bLength */ - USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ - LOBYTE(AUDIO_CONFIG_DESC_SIZE), /* wTotalLength 109 bytes*/ - HIBYTE(AUDIO_CONFIG_DESC_SIZE), - 0x02, /* bNumInterfaces */ - 0x01, /* bConfigurationValue */ - 0x00, /* iConfiguration */ - 0xC0, /* bmAttributes BUS Powred*/ - 0x32, /* bMaxPower = 100 mA*/ - /* 09 byte*/ - - /* USB Speaker Standard interface descriptor */ - AUDIO_INTERFACE_DESC_SIZE, /* bLength */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - 0x00, /* bInterfaceNumber */ - 0x00, /* bAlternateSetting */ - 0x00, /* bNumEndpoints */ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ - AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - /* 09 byte*/ - - /* USB Speaker Class-specific AC Interface Descriptor */ - AUDIO_INTERFACE_DESC_SIZE, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */ - 0x00, /* 1.00 */ /* bcdADC */ - 0x01, - 0x27, /* wTotalLength = 39*/ - 0x00, - 0x01, /* bInCollection */ - 0x01, /* baInterfaceNr */ - /* 09 byte*/ - - /* USB Speaker Input Terminal Descriptor */ - AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */ - 0x01, /* bTerminalID */ - 0x01, /* wTerminalType AUDIO_TERMINAL_USB_STREAMING 0x0101 */ - 0x01, - 0x00, /* bAssocTerminal */ - 0x01, /* bNrChannels */ - 0x00, /* wChannelConfig 0x0000 Mono */ - 0x00, - 0x00, /* iChannelNames */ - 0x00, /* iTerminal */ - /* 12 byte*/ - - /* USB Speaker Audio Feature Unit Descriptor */ - 0x09, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */ - AUDIO_OUT_STREAMING_CTRL, /* bUnitID */ - 0x01, /* bSourceID */ - 0x01, /* bControlSize */ - AUDIO_CONTROL_MUTE, /* bmaControls(0) */ - 0x00, /* bmaControls(1) */ - 0x00, /* iTerminal */ - /* 09 byte*/ - - /*USB Speaker Output Terminal Descriptor */ - 0x09, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */ - 0x03, /* bTerminalID */ - 0x01, /* wTerminalType 0x0301*/ - 0x03, - 0x00, /* bAssocTerminal */ - 0x02, /* bSourceID */ - 0x00, /* iTerminal */ - /* 09 byte*/ - - /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */ - /* Interface 1, Alternate Setting 0 */ - AUDIO_INTERFACE_DESC_SIZE, /* bLength */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - 0x01, /* bInterfaceNumber */ - 0x00, /* bAlternateSetting */ - 0x00, /* bNumEndpoints */ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ - AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - /* 09 byte*/ - - /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Operational */ - /* Interface 1, Alternate Setting 1 */ - AUDIO_INTERFACE_DESC_SIZE, /* bLength */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - 0x01, /* bInterfaceNumber */ - 0x01, /* bAlternateSetting */ - 0x01, /* bNumEndpoints */ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ - AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - /* 09 byte*/ - - /* USB Speaker Audio Streaming Interface Descriptor */ - AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ - 0x01, /* bTerminalLink */ - 0x01, /* bDelay */ - 0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001*/ - 0x00, - /* 07 byte*/ - - /* USB Speaker Audio Type III Format Interface Descriptor */ - 0x0B, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ - AUDIO_FORMAT_TYPE_III, /* bFormatType */ - 0x02, /* bNrChannels */ - 0x02, /* bSubFrameSize : 2 Bytes per frame (16bits) */ - 16, /* bBitResolution (16-bits per sample) */ - 0x01, /* bSamFreqType only one frequency supported */ - SAMPLE_FREQ(USBD_AUDIO_FREQ), /* Audio sampling frequency coded on 3 bytes */ - /* 11 byte*/ - - /* Endpoint 1 - Standard Descriptor */ - AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint*/ - USB_ENDPOINT_TYPE_ISOCHRONOUS, /* bmAttributes */ - AUDIO_PACKET_SZE(USBD_AUDIO_FREQ), /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */ - 0x01, /* bInterval */ - 0x00, /* bRefresh */ - 0x00, /* bSynchAddress */ - /* 09 byte*/ - - /* Endpoint - Audio Streaming Descriptor*/ - AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */ - AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ - 0x00, /* bmAttributes */ - 0x00, /* bLockDelayUnits */ - 0x00, /* wLockDelay */ - 0x00, - /* 07 byte*/ -} ; - -/** - * @} - */ - -/** @defgroup usbd_audio_Private_Functions - * @{ - */ - -/** -* @brief usbd_audio_Init -* Initilaizes the AUDIO interface. -* @param pdev: device instance -* @param cfgidx: Configuration index -* @retval status -*/ -static uint8_t usbd_audio_Init (void *pdev, - uint8_t cfgidx) -{ - /* Open EP OUT */ - DCD_EP_Open(pdev, - AUDIO_OUT_EP, - AUDIO_OUT_PACKET, - USB_OTG_EP_ISOC); - - /* Initialize the Audio output Hardware layer */ - if (AUDIO_OUT_fops.Init(USBD_AUDIO_FREQ, DEFAULT_VOLUME, 0) != USBD_OK) - { - return USBD_FAIL; - } - - /* Prepare Out endpoint to receive audio data */ - DCD_EP_PrepareRx(pdev, - AUDIO_OUT_EP, - (uint8_t*)IsocOutBuff, - AUDIO_OUT_PACKET); - - return USBD_OK; -} - -/** -* @brief usbd_audio_Init -* DeInitializes the AUDIO layer. -* @param pdev: device instance -* @param cfgidx: Configuration index -* @retval status -*/ -static uint8_t usbd_audio_DeInit (void *pdev, - uint8_t cfgidx) -{ - DCD_EP_Close (pdev , AUDIO_OUT_EP); - - /* DeInitialize the Audio output Hardware layer */ - if (AUDIO_OUT_fops.DeInit(0) != USBD_OK) - { - return USBD_FAIL; - } - - return USBD_OK; -} - -/** - * @brief usbd_audio_Setup - * Handles the Audio control request parsing. - * @param pdev: instance - * @param req: usb requests - * @retval status - */ -static uint8_t usbd_audio_Setup (void *pdev, - USB_SETUP_REQ *req) -{ - uint16_t len; - uint8_t *pbuf; - - switch (req->bmRequest & USB_REQ_TYPE_MASK) - { - /* AUDIO Class Requests -------------------------------*/ - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - case AUDIO_REQ_GET_CUR: - AUDIO_Req_GetCurrent(pdev, req); - break; - - case AUDIO_REQ_SET_CUR: - AUDIO_Req_SetCurrent(pdev, req); - break; - - default: - USBD_CtlError (pdev, req); - return USBD_FAIL; - } - break; - - /* Standard Requests -------------------------------*/ - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - if( (req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE) - { -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - pbuf = usbd_audio_Desc; -#else - pbuf = usbd_audio_CfgDesc + 18; -#endif - len = MIN(USB_AUDIO_DESC_SIZ , req->wLength); - } - - USBD_CtlSendData (pdev, - pbuf, - len); - break; - - case USB_REQ_GET_INTERFACE : - USBD_CtlSendData (pdev, - (uint8_t *)&usbd_audio_AltSet, - 1); - break; - - case USB_REQ_SET_INTERFACE : - if ((uint8_t)(req->wValue) < AUDIO_TOTAL_IF_NUM) - { - usbd_audio_AltSet = (uint8_t)(req->wValue); - } - else - { - /* Call the error management function (command will be nacked */ - USBD_CtlError (pdev, req); - } - break; - } - } - return USBD_OK; -} - -/** - * @brief usbd_audio_EP0_RxReady - * Handles audio control requests data. - * @param pdev: device device instance - * @retval status - */ -static uint8_t usbd_audio_EP0_RxReady (void *pdev) -{ - /* Check if an AudioControl request has been issued */ - if (AudioCtlCmd == AUDIO_REQ_SET_CUR) - {/* In this driver, to simplify code, only SET_CUR request is managed */ - /* Check for which addressed unit the AudioControl request has been issued */ - if (AudioCtlUnit == AUDIO_OUT_STREAMING_CTRL) - {/* In this driver, to simplify code, only one unit is manage */ - /* Call the audio interface mute function */ - AUDIO_OUT_fops.MuteCtl(AudioCtl[0]); - - /* Reset the AudioCtlCmd variable to prevent re-entering this function */ - AudioCtlCmd = 0; - AudioCtlLen = 0; - } - } - - return USBD_OK; -} - -/** - * @brief usbd_audio_DataIn - * Handles the audio IN data stage. - * @param pdev: instance - * @param epnum: endpoint number - * @retval status - */ -static uint8_t usbd_audio_DataIn (void *pdev, uint8_t epnum) -{ - return USBD_OK; -} - -/** - * @brief usbd_audio_DataOut - * Handles the Audio Out data stage. - * @param pdev: instance - * @param epnum: endpoint number - * @retval status - */ -static uint8_t usbd_audio_DataOut (void *pdev, uint8_t epnum) -{ - if (epnum == AUDIO_OUT_EP) - { - /* Increment the Buffer pointer or roll it back when all buffers are full */ - if (IsocOutWrPtr >= (IsocOutBuff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM))) - {/* All buffers are full: roll back */ - IsocOutWrPtr = IsocOutBuff; - } - else - {/* Increment the buffer pointer */ - IsocOutWrPtr += AUDIO_OUT_PACKET; - } - - /* Toggle the frame index */ - ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].even_odd_frame = - (((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].even_odd_frame)? 0:1; - - /* Prepare Out endpoint to receive next audio packet */ - DCD_EP_PrepareRx(pdev, - AUDIO_OUT_EP, - (uint8_t*)(IsocOutWrPtr), - AUDIO_OUT_PACKET); - - /* Trigger the start of streaming only when half buffer is full */ - if ((PlayFlag == 0) && (IsocOutWrPtr >= (IsocOutBuff + ((AUDIO_OUT_PACKET * OUT_PACKET_NUM) / 2)))) - { - /* Enable start of Streaming */ - PlayFlag = 1; - } - } - - return USBD_OK; -} - -/** - * @brief usbd_audio_SOF - * Handles the SOF event (data buffer update and synchronization). - * @param pdev: instance - * @param epnum: endpoint number - * @retval status - */ -static uint8_t usbd_audio_SOF (void *pdev) -{ - /* Check if there are available data in stream buffer. - In this function, a single variable (PlayFlag) is used to avoid software delays. - The play operation must be executed as soon as possible after the SOF detection. */ - if (PlayFlag) - { - /* Start playing received packet */ - AUDIO_OUT_fops.AudioCmd((uint8_t*)(IsocOutRdPtr), /* Samples buffer pointer */ - AUDIO_OUT_PACKET, /* Number of samples in Bytes */ - AUDIO_CMD_PLAY); /* Command to be processed */ - - /* Increment the Buffer pointer or roll it back when all buffers all full */ - if (IsocOutRdPtr >= (IsocOutBuff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM))) - {/* Roll back to the start of buffer */ - IsocOutRdPtr = IsocOutBuff; - } - else - {/* Increment to the next sub-buffer */ - IsocOutRdPtr += AUDIO_OUT_PACKET; - } - - /* If all available buffers have been consumed, stop playing */ - if (IsocOutRdPtr == IsocOutWrPtr) - { - /* Pause the audio stream */ - AUDIO_OUT_fops.AudioCmd((uint8_t*)(IsocOutBuff), /* Samples buffer pointer */ - AUDIO_OUT_PACKET, /* Number of samples in Bytes */ - AUDIO_CMD_PAUSE); /* Command to be processed */ - - /* Stop entering play loop */ - PlayFlag = 0; - - /* Reset buffer pointers */ - IsocOutRdPtr = IsocOutBuff; - IsocOutWrPtr = IsocOutBuff; - } - } - - return USBD_OK; -} - -/** - * @brief usbd_audio_OUT_Incplt - * Handles the iso out incomplete event. - * @param pdev: instance - * @retval status - */ -static uint8_t usbd_audio_OUT_Incplt (void *pdev) -{ - return USBD_OK; -} - -/****************************************************************************** - AUDIO Class requests management -******************************************************************************/ -/** - * @brief AUDIO_Req_GetCurrent - * Handles the GET_CUR Audio control request. - * @param pdev: instance - * @param req: setup class request - * @retval status - */ -static void AUDIO_Req_GetCurrent(void *pdev, USB_SETUP_REQ *req) -{ - /* Send the current mute state */ - USBD_CtlSendData (pdev, - AudioCtl, - req->wLength); -} - -/** - * @brief AUDIO_Req_SetCurrent - * Handles the SET_CUR Audio control request. - * @param pdev: instance - * @param req: setup class request - * @retval status - */ -static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req) -{ - if (req->wLength) - { - /* Prepare the reception of the buffer over EP0 */ - USBD_CtlPrepareRx (pdev, - AudioCtl, - req->wLength); - - /* Set the global variables indicating current request and its length - to the function usbd_audio_EP0_RxReady() which will process the request */ - AudioCtlCmd = AUDIO_REQ_SET_CUR; /* Set the request value */ - AudioCtlLen = req->wLength; /* Set the request data length */ - AudioCtlUnit = HIBYTE(req->wIndex); /* Set the request target unit */ - } -} - -/** - * @brief USBD_audio_GetCfgDesc - * Returns configuration descriptor. - * @param speed : current device speed - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -static uint8_t *USBD_audio_GetCfgDesc (uint8_t speed, uint16_t *length) -{ - *length = sizeof (usbd_audio_CfgDesc); - return usbd_audio_CfgDesc; -} -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_out_if.c b/example/stm32f4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_out_if.c deleted file mode 100644 index 21d98394f..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/audio/src/usbd_audio_out_if.c +++ /dev/null @@ -1,318 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_audio_out_if.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the Audio Out (palyback) interface API. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_audio_core.h" -#include "usbd_audio_out_if.h" - - - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup usbd_audio_out_if - * @brief usbd out interface module - * @{ - */ - -/** @defgroup usbd_audio_out_if_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_audio_out_if_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_audio_out_if_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_audio_out_if_Private_FunctionPrototypes - * @{ - */ -static uint8_t Init (uint32_t AudioFreq, uint32_t Volume, uint32_t options); -static uint8_t DeInit (uint32_t options); -static uint8_t AudioCmd (uint8_t* pbuf, uint32_t size, uint8_t cmd); -static uint8_t VolumeCtl (uint8_t vol); -static uint8_t MuteCtl (uint8_t cmd); -static uint8_t PeriodicTC (uint8_t cmd); -static uint8_t GetState (void); - -/** - * @} - */ - -/** @defgroup usbd_audio_out_if_Private_Variables - * @{ - */ -AUDIO_FOPS_TypeDef AUDIO_OUT_fops = -{ - Init, - DeInit, - AudioCmd, - VolumeCtl, - MuteCtl, - PeriodicTC, - GetState -}; - -static uint8_t AudioState = AUDIO_STATE_INACTIVE; - -/** - * @} - */ - -/** @defgroup usbd_audio_out_if_Private_Functions - * @{ - */ - -/** - * @brief Init - * Initialize and configures all required resources for audio play function. - * @param AudioFreq: Statrtup audio frequency. - * @param Volume: Startup volume to be set. - * @param options: specific options passed to low layer function. - * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. - */ -static uint8_t Init (uint32_t AudioFreq, - uint32_t Volume, - uint32_t options) -{ - static uint32_t Initialized = 0; - - /* Check if the low layer has already been initialized */ - if (Initialized == 0) - { - /* Call low layer function */ - if (EVAL_AUDIO_Init(OUTPUT_DEVICE_AUTO, Volume, AudioFreq) != 0) - { - AudioState = AUDIO_STATE_ERROR; - return AUDIO_FAIL; - } - - /* Set the Initialization flag to prevent reinitializing the interface again */ - Initialized = 1; - } - - /* Update the Audio state machine */ - AudioState = AUDIO_STATE_ACTIVE; - - return AUDIO_OK; -} - -/** - * @brief DeInit - * Free all resources used by low layer and stops audio-play function. - * @param options: options passed to low layer function. - * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. - */ -static uint8_t DeInit (uint32_t options) -{ - /* Update the Audio state machine */ - AudioState = AUDIO_STATE_INACTIVE; - - return AUDIO_OK; -} - -/** - * @brief AudioCmd - * Play, Stop, Pause or Resume current file. - * @param pbuf: address from which file shoud be played. - * @param size: size of the current buffer/file. - * @param cmd: command to be executed, can be AUDIO_CMD_PLAY , AUDIO_CMD_PAUSE, - * AUDIO_CMD_RESUME or AUDIO_CMD_STOP. - * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. - */ -static uint8_t AudioCmd(uint8_t* pbuf, - uint32_t size, - uint8_t cmd) -{ - /* Check the current state */ - if ((AudioState == AUDIO_STATE_INACTIVE) || (AudioState == AUDIO_STATE_ERROR)) - { - AudioState = AUDIO_STATE_ERROR; - return AUDIO_FAIL; - } - - switch (cmd) - { - /* Process the PLAY command ----------------------------*/ - case AUDIO_CMD_PLAY: - /* If current state is Active or Stopped */ - if ((AudioState == AUDIO_STATE_ACTIVE) || \ - (AudioState == AUDIO_STATE_STOPPED) || \ - (AudioState == AUDIO_STATE_PLAYING)) - { - Audio_MAL_Play((uint32_t)pbuf, (size/2)); - AudioState = AUDIO_STATE_PLAYING; - return AUDIO_OK; - } - /* If current state is Paused */ - else if (AudioState == AUDIO_STATE_PAUSED) - { - if (EVAL_AUDIO_PauseResume(AUDIO_RESUME, (uint32_t)pbuf, (size/2)) != 0) - { - AudioState = AUDIO_STATE_ERROR; - return AUDIO_FAIL; - } - else - { - AudioState = AUDIO_STATE_PLAYING; - return AUDIO_OK; - } - } - else /* Not allowed command */ - { - return AUDIO_FAIL; - } - - /* Process the STOP command ----------------------------*/ - case AUDIO_CMD_STOP: - if (AudioState != AUDIO_STATE_PLAYING) - { - /* Unsupported command */ - return AUDIO_FAIL; - } - else if (EVAL_AUDIO_Stop(CODEC_PDWN_SW) != 0) - { - AudioState = AUDIO_STATE_ERROR; - return AUDIO_FAIL; - } - else - { - AudioState = AUDIO_STATE_STOPPED; - return AUDIO_OK; - } - - /* Process the PAUSE command ---------------------------*/ - case AUDIO_CMD_PAUSE: - if (AudioState != AUDIO_STATE_PLAYING) - { - /* Unsupported command */ - return AUDIO_FAIL; - } - else if (EVAL_AUDIO_PauseResume(AUDIO_PAUSE, (uint32_t)pbuf, (size/2)) != 0) - { - AudioState = AUDIO_STATE_ERROR; - return AUDIO_FAIL; - } - else - { - AudioState = AUDIO_STATE_PAUSED; - return AUDIO_OK; - } - - /* Unsupported command ---------------------------------*/ - default: - return AUDIO_FAIL; - } -} - -/** - * @brief VolumeCtl - * Set the volume level in % - * @param vol: volume level to be set in % (from 0% to 100%) - * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. - */ -static uint8_t VolumeCtl (uint8_t vol) -{ - /* Call low layer volume setting function */ - if (EVAL_AUDIO_VolumeCtl(vol) != 0) - { - AudioState = AUDIO_STATE_ERROR; - return AUDIO_FAIL; - } - - return AUDIO_OK; -} - -/** - * @brief MuteCtl - * Mute or Unmute the audio current output - * @param cmd: can be 0 to unmute, or 1 to mute. - * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. - */ -static uint8_t MuteCtl (uint8_t cmd) -{ - /* Call low layer mute setting function */ - if (EVAL_AUDIO_Mute(cmd) != 0) - { - AudioState = AUDIO_STATE_ERROR; - return AUDIO_FAIL; - } - - return AUDIO_OK; -} - -/** - * @brief - * - * @param - * @param - * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else. - */ -static uint8_t PeriodicTC (uint8_t cmd) -{ - - - return AUDIO_OK; -} - - -/** - * @brief GetState - * Return the current state of the audio machine - * @param None - * @retval Current State. - */ -static uint8_t GetState (void) -{ - return AudioState; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h b/example/stm32f4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h deleted file mode 100644 index 926f42e13..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h +++ /dev/null @@ -1,137 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_cdc_core.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header file for the usbd_cdc_core.c file. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ - -#ifndef __USB_CDC_CORE_H_ -#define __USB_CDC_CORE_H_ - -#include "usbd_ioreq.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup usbd_cdc - * @brief This file is the Header file for USBD_cdc.c - * @{ - */ - - -/** @defgroup usbd_cdc_Exported_Defines - * @{ - */ -#define USB_CDC_CONFIG_DESC_SIZ (67) -#define USB_CDC_DESC_SIZ (67-9) - -#define CDC_DESCRIPTOR_TYPE 0x21 - -#define DEVICE_CLASS_CDC 0x02 -#define DEVICE_SUBCLASS_CDC 0x00 - - -#define USB_DEVICE_DESCRIPTOR_TYPE 0x01 -#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02 -#define USB_STRING_DESCRIPTOR_TYPE 0x03 -#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04 -#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05 - -#define STANDARD_ENDPOINT_DESC_SIZE 0x09 - -#define CDC_DATA_IN_PACKET_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 57) - -#define CDC_DATA_OUT_PACKET_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 64) - -/*---------------------------------------------------------------------*/ -/* CDC definitions */ -/*---------------------------------------------------------------------*/ - -/**************************************************/ -/* CDC Requests */ -/**************************************************/ -#define SEND_ENCAPSULATED_COMMAND 0x00 -#define GET_ENCAPSULATED_RESPONSE 0x01 -#define SET_COMM_FEATURE 0x02 -#define GET_COMM_FEATURE 0x03 -#define CLEAR_COMM_FEATURE 0x04 -#define SET_LINE_CODING 0x20 -#define GET_LINE_CODING 0x21 -#define SET_CONTROL_LINE_STATE 0x22 -#define SEND_BREAK 0x23 -#define NO_CMD 0xFF - -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_TypesDefinitions - * @{ - */ -typedef struct _CDC_IF_PROP -{ - uint16_t (*pIf_Init) (void); - uint16_t (*pIf_DeInit) (void); - uint16_t (*pIf_Ctrl) (uint32_t Cmd, uint8_t* Buf, uint32_t Len); - uint16_t (*pIf_DataTx) (uint8_t* Buf, uint32_t Len); - uint16_t (*pIf_DataRx) (uint8_t* Buf, uint32_t Len); -} -CDC_IF_Prop_TypeDef; -/** - * @} - */ - - - -/** @defgroup USBD_CORE_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Variables - * @{ - */ - -extern USBD_Class_cb_TypeDef USBD_CDC_cb; -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Functions - * @{ - */ -/** - * @} - */ - -#endif // __USB_CDC_CORE_H_ -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h b/example/stm32f4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h deleted file mode 100644 index 1a12508e6..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_cdc_if_template.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Header for dfu_mal.c file. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CDC_IF_TEMPLATE_H -#define __USBD_CDC_IF_TEMPLATE_H - -/* Includes ------------------------------------------------------------------*/ -#ifdef STM32F2XX - #include "stm32f2xx.h" -#elif defined(STM32F10X_CL) - #include "stm32f10x.h" -#endif /* STM32F2XX */ - -#include "usbd_conf.h" -#include "usbd_cdc_core.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -extern CDC_IF_Prop_TypeDef TEMPLATE_fops; - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -#endif /* __USBD_CDC_IF_TEMPLATE_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c b/example/stm32f4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c deleted file mode 100644 index 8d1f15d32..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c +++ /dev/null @@ -1,811 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_cdc_core.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the high layer firmware functions to manage the - * following functionalities of the USB CDC Class: - * - Initialization and Configuration of high and low layer - * - Enumeration as CDC Device (and enumeration for each implemented memory interface) - * - OUT/IN data transfer - * - Command IN transfer (class requests management) - * - Error management - * - * @verbatim - * - * =================================================================== - * CDC Class Driver Description - * =================================================================== - * This driver manages the "Universal Serial Bus Class Definitions for Communications Devices - * Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus - * Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007" - * This driver implements the following aspects of the specification: - * - Device descriptor management - * - Configuration descriptor management - * - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN) - * - Requests management (as described in section 6.2 in specification) - * - Abstract Control Model compliant - * - Union Functional collection (using 1 IN endpoint for control) - * - Data interface class - - * @note - * For the Abstract Control Model, this core allows only transmitting the requests to - * lower layer dispatcher (ie. usbd_cdc_vcp.c/.h) which should manage each request and - * perform relative actions. - * - * These aspects may be enriched or modified for a specific user application. - * - * This driver doesn't implement the following aspects of the specification - * (but it is possible to manage these features with some modifications on this driver): - * - Any class-specific aspect relative to communication classes should be managed by user application. - * - All communication classes other than PSTN are not managed - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_cdc_core.h" -#include "usbd_desc.h" -#include "usbd_req.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup usbd_cdc - * @brief usbd core module - * @{ - */ - -/** @defgroup usbd_cdc_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_cdc_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_cdc_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_cdc_Private_FunctionPrototypes - * @{ - */ - -/********************************************* - CDC Device library callbacks - *********************************************/ -static uint8_t usbd_cdc_Init (void *pdev, uint8_t cfgidx); -static uint8_t usbd_cdc_DeInit (void *pdev, uint8_t cfgidx); -static uint8_t usbd_cdc_Setup (void *pdev, USB_SETUP_REQ *req); -static uint8_t usbd_cdc_EP0_RxReady (void *pdev); -static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum); -static uint8_t usbd_cdc_DataOut (void *pdev, uint8_t epnum); -static uint8_t usbd_cdc_SOF (void *pdev); - -/********************************************* - CDC specific management functions - *********************************************/ -static void Handle_USBAsynchXfer (void *pdev); -static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length); -#ifdef USE_USB_OTG_HS -static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length); -#endif -/** - * @} - */ - -/** @defgroup usbd_cdc_Private_Variables - * @{ - */ -extern CDC_IF_Prop_TypeDef APP_FOPS; -extern uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC]; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN static __IO uint32_t usbd_cdc_AltSet __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t USB_Rx_Buffer [CDC_DATA_MAX_PACKET_SIZE] __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t APP_Rx_Buffer [APP_RX_DATA_SIZE] __ALIGN_END ; - - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t CmdBuff[CDC_CMD_PACKET_SZE] __ALIGN_END ; - -uint32_t APP_Rx_ptr_in = 0; -uint32_t APP_Rx_ptr_out = 0; -uint32_t APP_Rx_length = 0; - -uint8_t USB_Tx_State = 0; - -static uint32_t cdcCmd = 0xFF; -static uint32_t cdcLen = 0; - -/* CDC interface class callbacks structure */ -USBD_Class_cb_TypeDef USBD_CDC_cb = -{ - usbd_cdc_Init, - usbd_cdc_DeInit, - usbd_cdc_Setup, - NULL, /* EP0_TxSent, */ - usbd_cdc_EP0_RxReady, - usbd_cdc_DataIn, - usbd_cdc_DataOut, - usbd_cdc_SOF, - NULL, - NULL, - USBD_cdc_GetCfgDesc, -#ifdef USE_USB_OTG_HS - USBD_cdc_GetOtherCfgDesc, /* use same cobfig as per FS */ -#endif /* USE_USB_OTG_HS */ -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* USB CDC device Configuration Descriptor */ -__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - /*Configuration Descriptor*/ - 0x09, /* bLength: Configuration Descriptor size */ - USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */ - USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ - 0x00, - 0x02, /* bNumInterfaces: 2 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: self powered */ - 0x32, /* MaxPower 0 mA */ - - /*---------------------------------------------------------------------------*/ - - /*Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */ - /* Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoints used */ - 0x02, /* bInterfaceClass: Communication Interface Class */ - 0x02, /* bInterfaceSubClass: Abstract Control Model */ - 0x01, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface: */ - - /*Header Functional Descriptor*/ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header Func Desc */ - 0x10, /* bcdCDC: spec release number */ - 0x01, - - /*Call Management Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x01, /* bDescriptorSubtype: Call Management Func Desc */ - 0x00, /* bmCapabilities: D0+D1 */ - 0x01, /* bDataInterface: 1 */ - - /*ACM Functional Descriptor*/ - 0x04, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ - 0x02, /* bmCapabilities */ - - /*Union Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x06, /* bDescriptorSubtype: Union func desc */ - 0x00, /* bMasterInterface: Communication class interface */ - 0x01, /* bSlaveInterface0: Data Class Interface */ - - /*Endpoint 2 Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ - CDC_CMD_EP, /* bEndpointAddress */ - 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_CMD_PACKET_SZE), /* wMaxPacketSize: */ - HIBYTE(CDC_CMD_PACKET_SZE), -#ifdef USE_USB_OTG_HS - 0x10, /* bInterval: */ -#else - 0xFF, /* bInterval: */ -#endif /* USE_USB_OTG_HS */ - - /*---------------------------------------------------------------------------*/ - - /*Data class interface descriptor*/ - 0x09, /* bLength: Endpoint Descriptor size */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */ - 0x01, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: Two endpoints used */ - 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface: */ - - /*Endpoint OUT Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ - CDC_OUT_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_DATA_MAX_PACKET_SIZE), - 0x00, /* bInterval: ignore for Bulk transfer */ - - /*Endpoint IN Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ - CDC_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_DATA_MAX_PACKET_SIZE), - 0x00 /* bInterval: ignore for Bulk transfer */ -} ; - -#ifdef USE_USB_OTG_HS -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuation Descriptor size */ - USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, - USB_CDC_CONFIG_DESC_SIZ, - 0x00, - 0x02, /* bNumInterfaces: 2 interfaces */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ - - /*Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */ - /* Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoints used */ - 0x02, /* bInterfaceClass: Communication Interface Class */ - 0x02, /* bInterfaceSubClass: Abstract Control Model */ - 0x01, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface: */ - - /*Header Functional Descriptor*/ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header Func Desc */ - 0x10, /* bcdCDC: spec release number */ - 0x01, - - /*Call Management Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x01, /* bDescriptorSubtype: Call Management Func Desc */ - 0x00, /* bmCapabilities: D0+D1 */ - 0x01, /* bDataInterface: 1 */ - - /*ACM Functional Descriptor*/ - 0x04, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ - 0x02, /* bmCapabilities */ - - /*Union Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x06, /* bDescriptorSubtype: Union func desc */ - 0x00, /* bMasterInterface: Communication class interface */ - 0x01, /* bSlaveInterface0: Data Class Interface */ - - /*Endpoint 2 Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ - CDC_CMD_EP, /* bEndpointAddress */ - 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_CMD_PACKET_SZE), /* wMaxPacketSize: */ - HIBYTE(CDC_CMD_PACKET_SZE), - 0xFF, /* bInterval: */ - - /*---------------------------------------------------------------------------*/ - - /*Data class interface descriptor*/ - 0x09, /* bLength: Endpoint Descriptor size */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */ - 0x01, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: Two endpoints used */ - 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface: */ - - /*Endpoint OUT Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ - CDC_OUT_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize: */ - 0x00, - 0x00, /* bInterval: ignore for Bulk transfer */ - - /*Endpoint IN Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */ - CDC_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize: */ - 0x00, - 0x00 /* bInterval */ -}; -#endif /* USE_USB_OTG_HS */ - -/** - * @} - */ - -/** @defgroup usbd_cdc_Private_Functions - * @{ - */ - -/** - * @brief usbd_cdc_Init - * Initilaize the CDC interface - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -static uint8_t usbd_cdc_Init (void *pdev, - uint8_t cfgidx) -{ - uint8_t *pbuf; - - /* Open EP IN */ - DCD_EP_Open(pdev, - CDC_IN_EP, - CDC_DATA_IN_PACKET_SIZE, - USB_OTG_EP_BULK); - - /* Open EP OUT */ - DCD_EP_Open(pdev, - CDC_OUT_EP, - CDC_DATA_OUT_PACKET_SIZE, - USB_OTG_EP_BULK); - - /* Open Command IN EP */ - DCD_EP_Open(pdev, - CDC_CMD_EP, - CDC_CMD_PACKET_SZE, - USB_OTG_EP_INT); - - pbuf = (uint8_t *)USBD_DeviceDesc; - pbuf[4] = DEVICE_CLASS_CDC; - pbuf[5] = DEVICE_SUBCLASS_CDC; - - /* Initialize the Interface physical components */ - APP_FOPS.pIf_Init(); - - /* Prepare Out endpoint to receive next packet */ - DCD_EP_PrepareRx(pdev, - CDC_OUT_EP, - (uint8_t*)(USB_Rx_Buffer), - CDC_DATA_OUT_PACKET_SIZE); - - return USBD_OK; -} - -/** - * @brief usbd_cdc_Init - * DeInitialize the CDC layer - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -static uint8_t usbd_cdc_DeInit (void *pdev, - uint8_t cfgidx) -{ - /* Open EP IN */ - DCD_EP_Close(pdev, - CDC_IN_EP); - - /* Open EP OUT */ - DCD_EP_Close(pdev, - CDC_OUT_EP); - - /* Open Command IN EP */ - DCD_EP_Close(pdev, - CDC_CMD_EP); - - /* Restore default state of the Interface physical components */ - APP_FOPS.pIf_DeInit(); - - return USBD_OK; -} - -/** - * @brief usbd_cdc_Setup - * Handle the CDC specific requests - * @param pdev: instance - * @param req: usb requests - * @retval status - */ -static uint8_t usbd_cdc_Setup (void *pdev, - USB_SETUP_REQ *req) -{ - uint16_t len; - uint8_t *pbuf; - - switch (req->bmRequest & USB_REQ_TYPE_MASK) - { - /* CDC Class Requests -------------------------------*/ - case USB_REQ_TYPE_CLASS : - /* Check if the request is a data setup packet */ - if (req->wLength) - { - /* Check if the request is Device-to-Host */ - if (req->bmRequest & 0x80) - { - /* Get the data to be sent to Host from interface layer */ - APP_FOPS.pIf_Ctrl(req->bRequest, CmdBuff, req->wLength); - - /* Send the data to the host */ - USBD_CtlSendData (pdev, - CmdBuff, - req->wLength); - } - else /* Host-to-Device requeset */ - { - /* Set the value of the current command to be processed */ - cdcCmd = req->bRequest; - cdcLen = req->wLength; - - /* Prepare the reception of the buffer over EP0 - Next step: the received data will be managed in usbd_cdc_EP0_TxSent() - function. */ - USBD_CtlPrepareRx (pdev, - CmdBuff, - req->wLength); - } - } - else /* No Data request */ - { - /* Transfer the command to the interface layer */ - APP_FOPS.pIf_Ctrl(req->bRequest, NULL, 0); - } - - return USBD_OK; - - default: - USBD_CtlError (pdev, req); - return USBD_FAIL; - - - - /* Standard Requests -------------------------------*/ - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - if( (req->wValue >> 8) == CDC_DESCRIPTOR_TYPE) - { -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - pbuf = usbd_cdc_Desc; -#else - pbuf = usbd_cdc_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM); -#endif - len = MIN(USB_CDC_DESC_SIZ , req->wLength); - } - - USBD_CtlSendData (pdev, - pbuf, - len); - break; - - case USB_REQ_GET_INTERFACE : - USBD_CtlSendData (pdev, - (uint8_t *)&usbd_cdc_AltSet, - 1); - break; - - case USB_REQ_SET_INTERFACE : - if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM) - { - usbd_cdc_AltSet = (uint8_t)(req->wValue); - } - else - { - /* Call the error management function (command will be nacked */ - USBD_CtlError (pdev, req); - } - break; - } - } - return USBD_OK; -} - -/** - * @brief usbd_cdc_EP0_RxReady - * Data received on control endpoint - * @param pdev: device device instance - * @retval status - */ -static uint8_t usbd_cdc_EP0_RxReady (void *pdev) -{ - if (cdcCmd != NO_CMD) - { - /* Process the data */ - APP_FOPS.pIf_Ctrl(cdcCmd, CmdBuff, cdcLen); - - /* Reset the command variable to default value */ - cdcCmd = NO_CMD; - } - - return USBD_OK; -} - -/** - * @brief usbd_audio_DataIn - * Data sent on non-control IN endpoint - * @param pdev: device instance - * @param epnum: endpoint number - * @retval status - */ -static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum) -{ - uint16_t USB_Tx_ptr; - uint16_t USB_Tx_length; - - if (USB_Tx_State == 1) - { - if (APP_Rx_length == 0) - { - USB_Tx_State = 0; - } - else - { - if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE){ - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; - - APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; - APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; - } - else - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = APP_Rx_length; - - APP_Rx_ptr_out += APP_Rx_length; - APP_Rx_length = 0; - } - - /* Prepare the available data buffer to be sent on IN endpoint */ - DCD_EP_Tx (pdev, - CDC_IN_EP, - (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], - USB_Tx_length); - } - } - - return USBD_OK; -} - -/** - * @brief usbd_audio_DataOut - * Data received on non-control Out endpoint - * @param pdev: device instance - * @param epnum: endpoint number - * @retval status - */ -static uint8_t usbd_cdc_DataOut (void *pdev, uint8_t epnum) -{ - uint16_t USB_Rx_Cnt; - - /* Get the received data buffer and update the counter */ - USB_Rx_Cnt = ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].xfer_count; - - /* USB data will be immediately processed, this allow next USB traffic being - NAKed till the end of the application Xfer */ - APP_FOPS.pIf_DataRx(USB_Rx_Buffer, USB_Rx_Cnt); - - /* Prepare Out endpoint to receive next packet */ - DCD_EP_PrepareRx(pdev, - CDC_OUT_EP, - (uint8_t*)(USB_Rx_Buffer), - CDC_DATA_OUT_PACKET_SIZE); - - return USBD_OK; -} - -/** - * @brief usbd_audio_SOF - * Start Of Frame event management - * @param pdev: instance - * @param epnum: endpoint number - * @retval status - */ -static uint8_t usbd_cdc_SOF (void *pdev) -{ - static uint32_t FrameCount = 0; - - if (FrameCount++ == CDC_IN_FRAME_INTERVAL) - { - /* Reset the frame counter */ - FrameCount = 0; - - /* Check the data to be sent through IN pipe */ - Handle_USBAsynchXfer(pdev); - } - - return USBD_OK; -} - -/** - * @brief Handle_USBAsynchXfer - * Send data to USB - * @param pdev: instance - * @retval None - */ -static void Handle_USBAsynchXfer (void *pdev) -{ - uint16_t USB_Tx_ptr; - uint16_t USB_Tx_length; - - if(USB_Tx_State != 1) - { - if (APP_Rx_ptr_out == APP_RX_DATA_SIZE) - { - APP_Rx_ptr_out = 0; - } - - if(APP_Rx_ptr_out == APP_Rx_ptr_in) - { - USB_Tx_State = 0; - return; - } - - if(APP_Rx_ptr_out > APP_Rx_ptr_in) /* rollback */ - { - APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out; - - } - else - { - APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out; - - } -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - APP_Rx_length &= ~0x03; -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - - if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE) - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; - - APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; - APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; - } - else - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = APP_Rx_length; - - APP_Rx_ptr_out += APP_Rx_length; - APP_Rx_length = 0; - } - USB_Tx_State = 1; - - DCD_EP_Tx (pdev, - CDC_IN_EP, - (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], - USB_Tx_length); - } - -} - -/** - * @brief USBD_cdc_GetCfgDesc - * Return configuration descriptor - * @param speed : current device speed - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length) -{ - *length = sizeof (usbd_cdc_CfgDesc); - return usbd_cdc_CfgDesc; -} - -/** - * @brief USBD_cdc_GetCfgDesc - * Return configuration descriptor - * @param speed : current device speed - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -#ifdef USE_USB_OTG_HS -static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length) -{ - *length = sizeof (usbd_cdc_OtherCfgDesc); - return usbd_cdc_OtherCfgDesc; -} -#endif -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c b/example/stm32f4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c deleted file mode 100644 index 406f30a22..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c +++ /dev/null @@ -1,202 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_cdc_if_template.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Generic media access Layer. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED -#pragma data_alignment = 4 -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_cdc_if_template.h" -#include "stm32_eval.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* These are external variables imported from CDC core to be used for IN - transfer management. */ -extern uint8_t APP_Rx_Buffer []; /* Write CDC received data in this buffer. - These data will be sent over USB IN endpoint - in the CDC core functions. */ -extern uint32_t APP_Rx_ptr_in; /* Increment this pointer or roll it back to - start address when writing received data - in the buffer APP_Rx_Buffer. */ - -/* Private function prototypes -----------------------------------------------*/ -static uint16_t TEMPLATE_Init (void); -static uint16_t TEMPLATE_DeInit (void); -static uint16_t TEMPLATE_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len); -static uint16_t TEMPLATE_DataTx (uint8_t* Buf, uint32_t Len); -static uint16_t TEMPLATE_DataRx (uint8_t* Buf, uint32_t Len); - -CDC_IF_Prop_TypeDef TEMPLATE_fops = -{ - TEMPLATE_Init, - TEMPLATE_DeInit, - TEMPLATE_Ctrl, - TEMPLATE_DataTx, - TEMPLATE_DataRx -}; - -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief TEMPLATE_Init - * Initializes the CDC media low layer - * @param None - * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL - */ -static uint16_t TEMPLATE_Init(void) -{ - /* - Add your initialization code here - */ - return USBD_OK; -} - -/** - * @brief TEMPLATE_DeInit - * DeInitializes the CDC media low layer - * @param None - * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL - */ -static uint16_t TEMPLATE_DeInit(void) -{ - /* - Add your deinitialization code here - */ - return USBD_OK; -} - - -/** - * @brief TEMPLATE_Ctrl - * Manage the CDC class requests - * @param Cmd: Command code - * @param Buf: Buffer containing command data (request parameters) - * @param Len: Number of data to be sent (in bytes) - * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL - */ -static uint16_t TEMPLATE_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len) -{ - switch (Cmd) - { - case SEND_ENCAPSULATED_COMMAND: - /* Add your code here */ - break; - - case GET_ENCAPSULATED_RESPONSE: - /* Add your code here */ - break; - - case SET_COMM_FEATURE: - /* Add your code here */ - break; - - case GET_COMM_FEATURE: - /* Add your code here */ - break; - - case CLEAR_COMM_FEATURE: - /* Add your code here */ - break; - - case SET_LINE_CODING: - /* Add your code here */ - break; - - case GET_LINE_CODING: - /* Add your code here */ - break; - - case SET_CONTROL_LINE_STATE: - /* Add your code here */ - break; - - case SEND_BREAK: - /* Add your code here */ - break; - - default: - break; - } - - return USBD_OK; -} - -/** - * @brief TEMPLATE_DataTx - * CDC received data to be send over USB IN endpoint are managed in - * this function. - * @param Buf: Buffer of data to be sent - * @param Len: Number of data to be sent (in bytes) - * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL - */ -static uint16_t TEMPLATE_DataTx (uint8_t* Buf, uint32_t Len) -{ - - /* Get the data to be sent */ - for (i = 0; i < Len; i++) - { - /* APP_Rx_Buffer[APP_Rx_ptr_in] = XXX_ReceiveData(XXX); */ - } - - /* Increment the in pointer */ - APP_Rx_ptr_in++; - - /* To avoid buffer overflow */ - if(APP_Rx_ptr_in == APP_RX_DATA_SIZE) - { - APP_Rx_ptr_in = 0; - } - - return USBD_OK; -} - -/** - * @brief TEMPLATE_DataRx - * Data received over USB OUT endpoint are sent over CDC interface - * through this function. - * - * @note - * This function will block any OUT packet reception on USB endpoint - * untill exiting this function. If you exit this function before transfer - * is complete on CDC interface (ie. using DMA controller) it will result - * in receiving more data while previous ones are still not sent. - * - * @param Buf: Buffer of data to be received - * @param Len: Number of data received (in bytes) - * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL - */ -static uint16_t TEMPLATE_DataRx (uint8_t* Buf, uint32_t Len) -{ - uint32_t i; - - /* Send the received buffer */ - for (i = 0; i < Len; i++) - { - /* XXXX_SendData(XXXX, *(Buf + i) ); */ - } - - return USBD_OK; -} - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h b/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h deleted file mode 100644 index aadffb148..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h +++ /dev/null @@ -1,187 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_dfu_core.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header file for the usbd_dfu_core.c file. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ - -#ifndef __USB_DFU_CORE_H_ -#define __USB_DFU_CORE_H_ - -#include "usbd_ioreq.h" -#include "usbd_dfu_mal.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup usbd_dfu - * @brief This file is the Header file for USBD_dfu.c - * @{ - */ - - -/** @defgroup usbd_dfu_Exported_Defines - * @{ - */ -#define USB_DFU_CONFIG_DESC_SIZ (18 + (9 * USBD_ITF_MAX_NUM)) -#define USB_DFU_DESC_SIZ 9 - -#define DFU_DESCRIPTOR_TYPE 0x21 - - -/*---------------------------------------------------------------------*/ -/* DFU definitions */ -/*---------------------------------------------------------------------*/ - - - -/**************************************************/ -/* DFU Requests DFU states */ -/**************************************************/ - - -#define STATE_appIDLE 0 -#define STATE_appDETACH 1 -#define STATE_dfuIDLE 2 -#define STATE_dfuDNLOAD_SYNC 3 -#define STATE_dfuDNBUSY 4 -#define STATE_dfuDNLOAD_IDLE 5 -#define STATE_dfuMANIFEST_SYNC 6 -#define STATE_dfuMANIFEST 7 -#define STATE_dfuMANIFEST_WAIT_RESET 8 -#define STATE_dfuUPLOAD_IDLE 9 -#define STATE_dfuERROR 10 - -/**************************************************/ -/* DFU Requests DFU status */ -/**************************************************/ - -#define STATUS_OK 0x00 -#define STATUS_ERRTARGET 0x01 -#define STATUS_ERRFILE 0x02 -#define STATUS_ERRWRITE 0x03 -#define STATUS_ERRERASE 0x04 -#define STATUS_ERRCHECK_ERASED 0x05 -#define STATUS_ERRPROG 0x06 -#define STATUS_ERRVERIFY 0x07 -#define STATUS_ERRADDRESS 0x08 -#define STATUS_ERRNOTDONE 0x09 -#define STATUS_ERRFIRMWARE 0x0A -#define STATUS_ERRVENDOR 0x0B -#define STATUS_ERRUSBR 0x0C -#define STATUS_ERRPOR 0x0D -#define STATUS_ERRUNKNOWN 0x0E -#define STATUS_ERRSTALLEDPKT 0x0F - -/**************************************************/ -/* DFU Requests DFU states Manifestation State */ -/**************************************************/ - -#define Manifest_complete 0x00 -#define Manifest_In_Progress 0x01 - - -/**************************************************/ -/* Special Commands with Download Request */ -/**************************************************/ - -#define CMD_GETCOMMANDS 0x00 -#define CMD_SETADDRESSPOINTER 0x21 -#define CMD_ERASE 0x41 - -/**************************************************/ -/* Other defines */ -/**************************************************/ -/* Bit Detach capable = bit 3 in bmAttributes field */ -#define DFU_DETACH_MASK (uint8_t)(1 << 4) -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_TypesDefinitions - * @{ - */ -/**************************************************/ -/* DFU Requests */ -/**************************************************/ - -typedef enum _DFU_REQUESTS { - DFU_DETACH = 0, - DFU_DNLOAD = 1, - DFU_UPLOAD, - DFU_GETSTATUS, - DFU_CLRSTATUS, - DFU_GETSTATE, - DFU_ABORT -} DFU_REQUESTS; - -typedef void (*pFunction)(void); -/** - * @} - */ - - - -/** @defgroup USBD_CORE_Exported_Macros - * @{ - */ -/********** Descriptor of DFU interface 0 Alternate setting n ****************/ -#define USBD_DFU_IF_DESC(n) 0x09, /* bLength: Interface Descriptor size */ \ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \ - 0x00, /* bInterfaceNumber: Number of Interface */ \ - (n), /* bAlternateSetting: Alternate setting */ \ - 0x00, /* bNumEndpoints*/ \ - 0xFE, /* bInterfaceClass: Application Specific Class Code */ \ - 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */ \ - 0x02, /* nInterfaceProtocol: DFU mode protocol */ \ - USBD_IDX_INTERFACE_STR + (n) + 1 /* iInterface: Index of string descriptor */ \ - /* 18 */ - -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Variables - * @{ - */ - -extern USBD_Class_cb_TypeDef DFU_cb; -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Functions - * @{ - */ -/** - * @} - */ - -#endif // __USB_DFU_CORE_H_ -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h b/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h deleted file mode 100644 index 9ed095b73..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h +++ /dev/null @@ -1,79 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_dfu_mal.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Header for usbd_dfu_mal.c file. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __DFU_MAL_H -#define __DFU_MAL_H - -/* Includes ------------------------------------------------------------------*/ -#ifdef STM32F2XX - #include "stm32f2xx.h" -#elif defined(STM32F10X_CL) - #include "stm32f10x.h" -#endif /* STM32F2XX */ - -#include "usbd_conf.h" -#include "usbd_dfu_core.h" - -/* Exported types ------------------------------------------------------------*/ -typedef struct _DFU_MAL_PROP -{ - const uint8_t* pStrDesc; - uint16_t (*pMAL_Init) (void); - uint16_t (*pMAL_DeInit) (void); - uint16_t (*pMAL_Erase) (uint32_t Add); - uint16_t (*pMAL_Write) (uint32_t Add, uint32_t Len); - uint8_t *(*pMAL_Read) (uint32_t Add, uint32_t Len); - uint16_t (*pMAL_CheckAdd) (uint32_t Add); - const uint32_t EraseTiming; - const uint32_t WriteTiming; -} -DFU_MAL_Prop_TypeDef; - - -/* Exported constants --------------------------------------------------------*/ -#define MAL_OK 0 -#define MAL_FAIL 1 - -/* utils macro ---------------------------------------------------------------*/ -#define _1st_BYTE(x) (uint8_t)((x)&0xFF) /* 1st addressing cycle */ -#define _2nd_BYTE(x) (uint8_t)(((x)&0xFF00)>>8) /* 2nd addressing cycle */ -#define _3rd_BYTE(x) (uint8_t)(((x)&0xFF0000)>>16) /* 3rd addressing cycle */ -#define _4th_BYTE(x) (uint8_t)(((x)&0xFF000000)>>24) /* 4th addressing cycle */ - -/* Exported macro ------------------------------------------------------------*/ -#define SET_POLLING_TIMING(x) buffer[1] = _1st_BYTE(x);\ - buffer[2] = _2nd_BYTE(x);\ - buffer[3] = _3rd_BYTE(x); - -/* Exported functions ------------------------------------------------------- */ - -uint16_t MAL_Init (void); -uint16_t MAL_DeInit (void); -uint16_t MAL_Erase (uint32_t SectorAddress); -uint16_t MAL_Write (uint32_t SectorAddress, uint32_t DataLength); -uint8_t *MAL_Read (uint32_t SectorAddress, uint32_t DataLength); -uint16_t MAL_GetStatus(uint32_t SectorAddress ,uint8_t Cmd, uint8_t *buffer); - -extern uint8_t MAL_Buffer[XFERSIZE]; /* RAM Buffer for Downloaded Data */ -#endif /* __DFU_MAL_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h b/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h deleted file mode 100644 index 07e49dfb2..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_flash_if.h - * @author MCD Application Team - * @version V1.0.0RC1 - * @date 18-March-2011 - * @brief Header for usbd_flash_if.c file. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __FLASH_IF_MAL_H -#define __FLASH_IF_MAL_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_dfu_mal.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -#define FLASH_START_ADD 0x08000000 - -#ifdef STM32F2XX - #define FLASH_END_ADD 0x08100000 - #define FLASH_IF_STRING "@Internal Flash /0x08000000/03*016Ka,01*016Kg,01*064Kg,07*128Kg" -#elif defined(STM32F10X_CL) - #define FLASH_END_ADD 0x08040000 - #define FLASH_IF_STRING "@Internal Flash /0x08000000/06*002Ka,122*002Kg" -#endif /* STM32F2XX */ - - -extern DFU_MAL_Prop_TypeDef DFU_Flash_cb; - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -#endif /* __FLASH_IF_MAL_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h b/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h deleted file mode 100644 index d1e0dda9a..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_mem_if_template.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Header for usbd_mem_if_template.c file. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __MEM_IF_MAL_H -#define __MEM_IF_MAL_H - -/* Includes ------------------------------------------------------------------*/ -#ifdef STM32F2XX - #include "stm32f2xx.h" -#endif /* STM32F2XX */ -#include "usbd_dfu_mal.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -#define MEM_START_ADD 0x00000000 /* Dummy start address */ -#define MEM_END_ADD (uint32_t)(MEM_START_ADD + (5 * 1024)) /* Dummy Size = 5KB */ - -#define MEM_IF_STRING "@Dummy Memory /0x00000000/01*002Kg,03*001Kg" - -extern DFU_MAL_Prop_TypeDef DFU_Mem_cb; - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -#endif /* __MEM_IF_MAL_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_otp_if.h b/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_otp_if.h deleted file mode 100644 index ef7e06101..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/inc/usbd_otp_if.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_otp_if.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Header for usbd_otp_if.c file. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __OTP_IF_MAL_H -#define __OTP_IF_MAL_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_dfu_mal.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -#define OTP_START_ADD 0x1FFF7800 -#define OTP_END_ADD (uint32_t)(OTP_START_ADD + 528) - -#define OTP_IF_STRING "@OTP Area /0x1FFF7800/01*512 g,01*016 g" - -extern DFU_MAL_Prop_TypeDef DFU_Otp_cb; - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -#endif /* __OTP_IF_MAL_H */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c b/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c deleted file mode 100644 index 316031672..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c +++ /dev/null @@ -1,1046 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_dfu_core.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the high layer firmware functions to manage the - * following functionalities of the USB DFU Class: - * - Initialization and Configuration of high and low layer - * - Enumeration as DFU Device (and enumeration for each implemented memory interface) - * - Transfers to/from memory interfaces - * - Easy-to-customize "plug-in-like" modules for adding/removing memory interfaces. - * - Error management - * - * @verbatim - * - * =================================================================== - * DFU Class Driver Description - * =================================================================== - * This driver manages the DFU class V1.1 following the "Device Class Specification for - * Device Firmware Upgrade Version 1.1 Aug 5, 2004". - * This driver implements the following aspects of the specification: - * - Device descriptor management - * - Configuration descriptor management - * - Enumeration as DFU device (in DFU mode only) - * - Requests management (supporting ST DFU sub-protocol) - * - Memory operations management (Download/Upload/Erase/Detach/GetState/GetStatus) - * - DFU state machine implementation. - * - * @note - * ST DFU sub-protocol is compliant with DFU protocol and use sub-requests to manage - * memory addressing, commands processing, specific memories operations (ie. Erase) ... - * As required by the DFU specification, only endpoint 0 is used in this application. - * Other endpoints and functions may be added to the application (ie. DFU ...) - * - * These aspects may be enriched or modified for a specific user application. - * - * This driver doesn't implement the following aspects of the specification - * (but it is possible to manage these features with some modifications on this driver): - * - Manifestation Tolerant mode - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_dfu_core.h" -#include "usbd_desc.h" -#include "usbd_req.h" -#include "usb_bsp.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup usbd_dfu - * @brief usbd core module - * @{ - */ - -/** @defgroup usbd_dfu_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_dfu_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_dfu_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup usbd_dfu_Private_FunctionPrototypes - * @{ - */ - -/********************************************* - DFU Device library callbacks - *********************************************/ -static uint8_t usbd_dfu_Init (void *pdev, - uint8_t cfgidx); - -static uint8_t usbd_dfu_DeInit (void *pdev, - uint8_t cfgidx); - -static uint8_t usbd_dfu_Setup (void *pdev, - USB_SETUP_REQ *req); - -static uint8_t EP0_TxSent (void *pdev); - -static uint8_t EP0_RxReady (void *pdev); - - -static uint8_t *USBD_DFU_GetCfgDesc (uint8_t speed, - uint16_t *length); - - -#ifdef USB_OTG_HS_CORE -static uint8_t *USBD_DFU_GetOtherCfgDesc (uint8_t speed, - uint16_t *length); -#endif - -static uint8_t* USBD_DFU_GetUsrStringDesc (uint8_t speed, - uint8_t index , - uint16_t *length); - -/********************************************* - DFU Requests management functions - *********************************************/ -static void DFU_Req_DETACH (void *pdev, - USB_SETUP_REQ *req); - -static void DFU_Req_DNLOAD (void *pdev, - USB_SETUP_REQ *req); - -static void DFU_Req_UPLOAD (void *pdev, - USB_SETUP_REQ *req); - -static void DFU_Req_GETSTATUS (void *pdev); - -static void DFU_Req_CLRSTATUS (void *pdev); - -static void DFU_Req_GETSTATE (void *pdev); - -static void DFU_Req_ABORT (void *pdev); - -static void DFU_LeaveDFUMode (void *pdev); - -/** - * @} - */ - -/** @defgroup usbd_dfu_Private_Variables - * @{ - */ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t usbd_dfu_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END ; - - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t usbd_dfu_OtherCfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END ; - -/* The list of Interface String descriptor pointers is defined in usbd_dfu_mal.c - file. This list can be updated whenever a memory has to be added or removed */ -extern const uint8_t* usbd_dfu_StringDesc[]; - -/* State Machine variables */ -uint8_t DeviceState; -uint8_t DeviceStatus[6]; -uint32_t Manifest_State = Manifest_complete; -/* Data Management variables */ -static uint32_t wBlockNum = 0, wlength = 0; -static uint32_t Pointer = APP_DEFAULT_ADD; /* Base Address to Erase, Program or Read */ -static __IO uint32_t usbd_dfu_AltSet = 0; - -extern uint8_t MAL_Buffer[]; - -/* DFU interface class callbacks structure */ -USBD_Class_cb_TypeDef DFU_cb = -{ - usbd_dfu_Init, - usbd_dfu_DeInit, - usbd_dfu_Setup, - EP0_TxSent, - EP0_RxReady, - NULL, /* DataIn, */ - NULL, /* DataOut, */ - NULL, /*SOF */ - NULL, - NULL, - USBD_DFU_GetCfgDesc, -#ifdef USB_OTG_HS_CORE - USBD_DFU_GetOtherCfgDesc, /* use same cobfig as per FS */ -#endif - USBD_DFU_GetUsrStringDesc, -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* USB DFU device Configuration Descriptor */ -__ALIGN_BEGIN uint8_t usbd_dfu_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuation Descriptor size */ - USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */ - USB_DFU_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ - 0x00, - 0x01, /*bNumInterfaces: 1 interface*/ - 0x01, /*bConfigurationValue: Configuration value*/ - 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ - 0xC0, /*bmAttributes: bus powered and Supprts Remote Wakeup */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ - /* 09 */ - - /********** Descriptor of DFU interface 0 Alternate setting 0 **************/ - USBD_DFU_IF_DESC(0), /* This interface is mandatory for all devices */ - -#if (USBD_ITF_MAX_NUM > 1) - /********** Descriptor of DFU interface 0 Alternate setting 1 **************/ - USBD_DFU_IF_DESC(1), -#endif /* (USBD_ITF_MAX_NUM > 1) */ - -#if (USBD_ITF_MAX_NUM > 2) - /********** Descriptor of DFU interface 0 Alternate setting 2 **************/ - USBD_DFU_IF_DESC(2), -#endif /* (USBD_ITF_MAX_NUM > 2) */ - -#if (USBD_ITF_MAX_NUM > 3) - /********** Descriptor of DFU interface 0 Alternate setting 3 **************/ - USBD_DFU_IF_DESC(3), -#endif /* (USBD_ITF_MAX_NUM > 3) */ - -#if (USBD_ITF_MAX_NUM > 4) - /********** Descriptor of DFU interface 0 Alternate setting 4 **************/ - USBD_DFU_IF_DESC(4), -#endif /* (USBD_ITF_MAX_NUM > 4) */ - -#if (USBD_ITF_MAX_NUM > 5) - /********** Descriptor of DFU interface 0 Alternate setting 5 **************/ - USBD_DFU_IF_DESC(5), -#endif /* (USBD_ITF_MAX_NUM > 5) */ - -#if (USBD_ITF_MAX_NUM > 6) -#error "ERROR: usbd_dfu_core.c: Modify the file to support more descriptors!" -#endif /* (USBD_ITF_MAX_NUM > 6) */ - - /******************** DFU Functional Descriptor********************/ - 0x09, /*blength = 9 Bytes*/ - DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/ - 0x0B, /*bmAttribute - bitCanDnload = 1 (bit 0) - bitCanUpload = 1 (bit 1) - bitManifestationTolerant = 0 (bit 2) - bitWillDetach = 1 (bit 3) - Reserved (bit4-6) - bitAcceleratedST = 0 (bit 7)*/ - 0xFF, /*DetachTimeOut= 255 ms*/ - 0x00, - /*WARNING: In DMA mode the multiple MPS packets feature is still not supported - ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */ - TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/ - 0x1A, /* bcdDFUVersion*/ - 0x01 - /***********************************************************/ - /* 9*/ -} ; - -#ifdef USE_USB_OTG_HS -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -__ALIGN_BEGIN uint8_t usbd_dfu_OtherCfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuation Descriptor size */ - USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_DFU_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ - 0x00, - 0x01, /*bNumInterfaces: 1 interface*/ - 0x01, /*bConfigurationValue: Configuration value*/ - 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ - 0xC0, /*bmAttributes: bus powered and Supprts Remote Wakeup */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ - /* 09 */ - - /********** Descriptor of DFU interface 0 Alternate setting 0 **************/ - USBD_DFU_IF_DESC(0), /* This interface is mandatory for all devices */ - -#if (USBD_ITF_MAX_NUM > 1) - /********** Descriptor of DFU interface 0 Alternate setting 1 **************/ - USBD_DFU_IF_DESC(1), -#endif /* (USBD_ITF_MAX_NUM > 1) */ - -#if (USBD_ITF_MAX_NUM > 2) - /********** Descriptor of DFU interface 0 Alternate setting 2 **************/ - USBD_DFU_IF_DESC(2), -#endif /* (USBD_ITF_MAX_NUM > 2) */ - -#if (USBD_ITF_MAX_NUM > 3) - /********** Descriptor of DFU interface 0 Alternate setting 3 **************/ - USBD_DFU_IF_DESC(3), -#endif /* (USBD_ITF_MAX_NUM > 3) */ - -#if (USBD_ITF_MAX_NUM > 4) - /********** Descriptor of DFU interface 0 Alternate setting 4 **************/ - USBD_DFU_IF_DESC(4), -#endif /* (USBD_ITF_MAX_NUM > 4) */ - -#if (USBD_ITF_MAX_NUM > 5) - /********** Descriptor of DFU interface 0 Alternate setting 5 **************/ - USBD_DFU_IF_DESC(5), -#endif /* (USBD_ITF_MAX_NUM > 5) */ - -#if (USBD_ITF_MAX_NUM > 6) -#error "ERROR: usbd_dfu_core.c: Modify the file to support more descriptors!" -#endif /* (USBD_ITF_MAX_NUM > 6) */ - - /******************** DFU Functional Descriptor********************/ - 0x09, /*blength = 9 Bytes*/ - DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/ - 0x0B, /*bmAttribute - bitCanDnload = 1 (bit 0) - bitCanUpload = 1 (bit 1) - bitManifestationTolerant = 0 (bit 2) - bitWillDetach = 1 (bit 3) - Reserved (bit4-6) - bitAcceleratedST = 0 (bit 7)*/ - 0xFF, /*DetachTimeOut= 255 ms*/ - 0x00, - /*WARNING: In DMA mode the multiple MPS packets feature is still not supported - ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */ - TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/ - 0x1A, /* bcdDFUVersion*/ - 0x01 - /***********************************************************/ - /* 9*/ -}; -#endif /* USE_USB_OTG_HS */ - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif - -__ALIGN_BEGIN static uint8_t usbd_dfu_Desc[USB_DFU_DESC_SIZ] __ALIGN_END = -{ - 0x09, /*blength = 9 Bytes*/ - DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/ - 0x0B, /*bmAttribute - bitCanDnload = 1 (bit 0) - bitCanUpload = 1 (bit 1) - bitManifestationTolerant = 0 (bit 2) - bitWillDetach = 1 (bit 3) - Reserved (bit4-6) - bitAcceleratedST = 0 (bit 7)*/ - 0xFF, /*DetachTimeOut= 255 ms*/ - 0x00, - /*WARNING: In DMA mode the multiple MPS packets feature is still not supported - ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */ - TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/ - 0x1A, /* bcdDFUVersion*/ - 0x01 -}; -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -/** - * @} - */ - -/** @defgroup usbd_dfu_Private_Functions - * @{ - */ - -/** - * @brief usbd_dfu_Init - * Initializes the DFU interface. - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -static uint8_t usbd_dfu_Init (void *pdev, - uint8_t cfgidx) -{ - /* Initilialize the MAL(Media Access Layer) */ - MAL_Init(); - - /* Initialize the state of the DFU interface */ - DeviceState = STATE_dfuIDLE; - DeviceStatus[0] = STATUS_OK; - DeviceStatus[4] = DeviceState; - - return USBD_OK; -} - -/** - * @brief usbd_dfu_Init - * De-initializes the DFU layer. - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -static uint8_t usbd_dfu_DeInit (void *pdev, - uint8_t cfgidx) -{ - /* Restore default state */ - DeviceState = STATE_dfuIDLE; - DeviceStatus[0] = STATUS_OK; - DeviceStatus[4] = DeviceState; - wBlockNum = 0; - wlength = 0; - - /* DeInitilialize the MAL(Media Access Layer) */ - MAL_DeInit(); - - return USBD_OK; -} - -/** - * @brief usbd_dfu_Setup - * Handles the DFU request parsing. - * @param pdev: instance - * @param req: usb requests - * @retval status - */ -static uint8_t usbd_dfu_Setup (void *pdev, - USB_SETUP_REQ *req) -{ - uint16_t len = 0; - uint8_t *pbuf = NULL; - - switch (req->bmRequest & USB_REQ_TYPE_MASK) - { - /* DFU Class Requests -------------------------------*/ - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - case DFU_DNLOAD: - DFU_Req_DNLOAD(pdev, req); - break; - - case DFU_UPLOAD: - DFU_Req_UPLOAD(pdev, req); - break; - - case DFU_GETSTATUS: - DFU_Req_GETSTATUS(pdev); - break; - - case DFU_CLRSTATUS: - DFU_Req_CLRSTATUS(pdev); - break; - - case DFU_GETSTATE: - DFU_Req_GETSTATE(pdev); - break; - - case DFU_ABORT: - DFU_Req_ABORT(pdev); - break; - - case DFU_DETACH: - DFU_Req_DETACH(pdev, req); - break; - - default: - USBD_CtlError (pdev, req); - return USBD_FAIL; - } - break; - - /* Standard Requests -------------------------------*/ - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - if( (req->wValue >> 8) == DFU_DESCRIPTOR_TYPE) - { -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - pbuf = usbd_dfu_Desc; -#else - pbuf = usbd_dfu_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM); -#endif - len = MIN(USB_DFU_DESC_SIZ , req->wLength); - } - - USBD_CtlSendData (pdev, - pbuf, - len); - break; - - case USB_REQ_GET_INTERFACE : - USBD_CtlSendData (pdev, - (uint8_t *)&usbd_dfu_AltSet, - 1); - break; - - case USB_REQ_SET_INTERFACE : - if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM) - { - usbd_dfu_AltSet = (uint8_t)(req->wValue); - } - else - { - /* Call the error management function (command will be nacked */ - USBD_CtlError (pdev, req); - } - break; - } - } - return USBD_OK; -} - -/** - * @brief EP0_TxSent - * Handles the DFU control endpoint data IN stage. - * @param pdev: device instance - * @retval status - */ -static uint8_t EP0_TxSent (void *pdev) -{ - uint32_t Addr; - USB_SETUP_REQ req; - - if (DeviceState == STATE_dfuDNBUSY) - { - /* Decode the Special Command*/ - if (wBlockNum == 0) - { - if ((MAL_Buffer[0] == CMD_GETCOMMANDS) && (wlength == 1)) - {} - else if (( MAL_Buffer[0] == CMD_SETADDRESSPOINTER ) && (wlength == 5)) - { - Pointer = MAL_Buffer[1]; - Pointer += MAL_Buffer[2] << 8; - Pointer += MAL_Buffer[3] << 16; - Pointer += MAL_Buffer[4] << 24; - } - else if (( MAL_Buffer[0] == CMD_ERASE ) && (wlength == 5)) - { - Pointer = MAL_Buffer[1]; - Pointer += MAL_Buffer[2] << 8; - Pointer += MAL_Buffer[3] << 16; - Pointer += MAL_Buffer[4] << 24; - MAL_Erase(Pointer); - } - else - { - /* Reset the global length and block number */ - wlength = 0; - wBlockNum = 0; - /* Call the error management function (command will be nacked) */ - req.bmRequest = 0; - req.wLength = 1; - USBD_CtlError (pdev, &req); - } - } - /* Regular Download Command */ - else if (wBlockNum > 1) - { - /* Decode the required address */ - Addr = ((wBlockNum - 2) * XFERSIZE) + Pointer; - - /* Preform the write operation */ - MAL_Write(Addr, wlength); - } - /* Reset the global lenght and block number */ - wlength = 0; - wBlockNum = 0; - - /* Update the state machine */ - DeviceState = STATE_dfuDNLOAD_SYNC; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - return USBD_OK; - } - else if (DeviceState == STATE_dfuMANIFEST)/* Manifestation in progress*/ - { - /* Start leaving DFU mode */ - DFU_LeaveDFUMode(pdev); - } - - return USBD_OK; -} - -/** - * @brief EP0_RxReady - * Handles the DFU control endpoint data OUT stage. - * @param pdev: device instance - * @retval status - */ -static uint8_t EP0_RxReady (void *pdev) -{ - return USBD_OK; -} - - -/****************************************************************************** - DFU Class requests management -******************************************************************************/ -/** - * @brief DFU_Req_DETACH - * Handles the DFU DETACH request. - * @param pdev: device instance - * @param req: pointer to the request structure. - * @retval None. - */ -static void DFU_Req_DETACH(void *pdev, USB_SETUP_REQ *req) -{ - if (DeviceState == STATE_dfuIDLE || DeviceState == STATE_dfuDNLOAD_SYNC - || DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuMANIFEST_SYNC - || DeviceState == STATE_dfuUPLOAD_IDLE ) - { - /* Update the state machine */ - DeviceState = STATE_dfuIDLE; - DeviceStatus[0] = STATUS_OK; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/ - DeviceStatus[4] = DeviceState; - DeviceStatus[5] = 0; /*iString*/ - wBlockNum = 0; - wlength = 0; - } - - /* Check the detach capability in the DFU functional descriptor */ - if ((usbd_dfu_CfgDesc[12 + (9 * USBD_ITF_MAX_NUM)]) & DFU_DETACH_MASK) - { - /* Perform an Attach-Detach operation on USB bus */ - DCD_DevDisconnect (pdev); - DCD_DevConnect (pdev); - } - else - { - /* Wait for the period of time specified in Detach request */ - USB_OTG_BSP_mDelay (req->wValue); - } -} - -/** - * @brief DFU_Req_DNLOAD - * Handles the DFU DNLOAD request. - * @param pdev: device instance - * @param req: pointer to the request structure - * @retval None - */ -static void DFU_Req_DNLOAD(void *pdev, USB_SETUP_REQ *req) -{ - /* Data setup request */ - if (req->wLength > 0) - { - if ((DeviceState == STATE_dfuIDLE) || (DeviceState == STATE_dfuDNLOAD_IDLE)) - { - /* Update the global length and block number */ - wBlockNum = req->wValue; - wlength = req->wLength; - - /* Update the state machine */ - DeviceState = STATE_dfuDNLOAD_SYNC; - DeviceStatus[4] = DeviceState; - - /* Prepare the reception of the buffer over EP0 */ - USBD_CtlPrepareRx (pdev, - (uint8_t*)MAL_Buffer, - wlength); - } - /* Unsupported state */ - else - { - /* Call the error management function (command will be nacked */ - USBD_CtlError (pdev, req); - } - } - /* 0 Data DNLOAD request */ - else - { - /* End of DNLOAD operation*/ - if (DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuIDLE ) - { - Manifest_State = Manifest_In_Progress; - DeviceState = STATE_dfuMANIFEST_SYNC; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - DeviceStatus[4] = DeviceState; - } - else - { - /* Call the error management function (command will be nacked */ - USBD_CtlError (pdev, req); - } - } -} - -/** - * @brief DFU_Req_UPLOAD - * Handles the DFU UPLOAD request. - * @param pdev: instance - * @param req: pointer to the request structure - * @retval status - */ -static void DFU_Req_UPLOAD(void *pdev, USB_SETUP_REQ *req) -{ - uint8_t *Phy_Addr = NULL; - uint32_t Addr = 0; - - /* Data setup request */ - if (req->wLength > 0) - { - if ((DeviceState == STATE_dfuIDLE) || (DeviceState == STATE_dfuUPLOAD_IDLE)) - { - /* Update the global langth and block number */ - wBlockNum = req->wValue; - wlength = req->wLength; - - /* DFU Get Command */ - if (wBlockNum == 0) - { - /* Update the state machine */ - DeviceState = (wlength > 3)? STATE_dfuIDLE:STATE_dfuUPLOAD_IDLE; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - - /* Store the values of all supported commands */ - MAL_Buffer[0] = CMD_GETCOMMANDS; - MAL_Buffer[1] = CMD_SETADDRESSPOINTER; - MAL_Buffer[2] = CMD_ERASE; - - /* Send the status data over EP0 */ - USBD_CtlSendData (pdev, - (uint8_t *)(&(MAL_Buffer[0])), - 3); - } - else if (wBlockNum > 1) - { - DeviceState = STATE_dfuUPLOAD_IDLE ; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - Addr = ((wBlockNum - 2) * XFERSIZE) + Pointer; /* Change is Accelerated*/ - - /* Return the physical address where data are stored */ - Phy_Addr = MAL_Read(Addr, wlength); - - /* Send the status data over EP0 */ - USBD_CtlSendData (pdev, - Phy_Addr, - wlength); - } - else /* unsupported wBlockNum */ - { - DeviceState = STATUS_ERRSTALLEDPKT; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - - /* Call the error management function (command will be nacked */ - USBD_CtlError (pdev, req); - } - } - /* Unsupported state */ - else - { - wlength = 0; - wBlockNum = 0; - /* Call the error management function (command will be nacked */ - USBD_CtlError (pdev, req); - } - } - /* No Data setup request */ - else - { - DeviceState = STATE_dfuIDLE; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - DeviceStatus[4] = DeviceState; - } -} - -/** - * @brief DFU_Req_GETSTATUS - * Handles the DFU GETSTATUS request. - * @param pdev: instance - * @retval status - */ -static void DFU_Req_GETSTATUS(void *pdev) -{ - switch (DeviceState) - { - case STATE_dfuDNLOAD_SYNC: - if (wlength != 0) - { - DeviceState = STATE_dfuDNBUSY; - DeviceStatus[4] = DeviceState; - if ((wBlockNum == 0) && (MAL_Buffer[0] == CMD_ERASE)) - { - MAL_GetStatus(Pointer, 0, DeviceStatus); - } - else - { - MAL_GetStatus(Pointer, 1, DeviceStatus); - } - } - else /* (wlength==0)*/ - { - DeviceState = STATE_dfuDNLOAD_IDLE; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - } - break; - - case STATE_dfuMANIFEST_SYNC : - if (Manifest_State == Manifest_In_Progress) - { - DeviceState = STATE_dfuMANIFEST; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 1; /*bwPollTimeout = 1ms*/ - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - //break; - } - else if ((Manifest_State == Manifest_complete) && \ - ((usbd_dfu_CfgDesc[(11 + (9 * USBD_ITF_MAX_NUM))]) & 0x04)) - { - DeviceState = STATE_dfuIDLE; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - //break; - } - break; - - default : - break; - } - - /* Send the status data over EP0 */ - USBD_CtlSendData (pdev, - (uint8_t *)(&(DeviceStatus[0])), - 6); -} - -/** - * @brief DFU_Req_CLRSTATUS - * Handles the DFU CLRSTATUS request. - * @param pdev: device instance - * @retval status - */ -static void DFU_Req_CLRSTATUS(void *pdev) -{ - if (DeviceState == STATE_dfuERROR) - { - DeviceState = STATE_dfuIDLE; - DeviceStatus[0] = STATUS_OK;/*bStatus*/ - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/ - DeviceStatus[4] = DeviceState;/*bState*/ - DeviceStatus[5] = 0;/*iString*/ - } - else - { /*State Error*/ - DeviceState = STATE_dfuERROR; - DeviceStatus[0] = STATUS_ERRUNKNOWN;/*bStatus*/ - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/ - DeviceStatus[4] = DeviceState;/*bState*/ - DeviceStatus[5] = 0;/*iString*/ - } -} - -/** - * @brief DFU_Req_GETSTATE - * Handles the DFU GETSTATE request. - * @param pdev: device instance - * @retval None - */ -static void DFU_Req_GETSTATE(void *pdev) -{ - /* Return the current state of the DFU interface */ - USBD_CtlSendData (pdev, - &DeviceState, - 1); -} - -/** - * @brief DFU_Req_ABORT - * Handles the DFU ABORT request. - * @param pdev: device instance - * @retval None - */ -static void DFU_Req_ABORT(void *pdev) -{ - if (DeviceState == STATE_dfuIDLE || DeviceState == STATE_dfuDNLOAD_SYNC - || DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuMANIFEST_SYNC - || DeviceState == STATE_dfuUPLOAD_IDLE ) - { - DeviceState = STATE_dfuIDLE; - DeviceStatus[0] = STATUS_OK; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/ - DeviceStatus[4] = DeviceState; - DeviceStatus[5] = 0; /*iString*/ - wBlockNum = 0; - wlength = 0; - } -} - -/** - * @brief DFU_LeaveDFUMode - * Handles the sub-protocol DFU leave DFU mode request (leaves DFU mode - * and resets device to jump to user loaded code). - * @param pdev: device instance - * @retval None - */ -void DFU_LeaveDFUMode(void *pdev) -{ - Manifest_State = Manifest_complete; - - if ((usbd_dfu_CfgDesc[(11 + (9 * USBD_ITF_MAX_NUM))]) & 0x04) - { - DeviceState = STATE_dfuMANIFEST_SYNC; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - return; - } - else - { - DeviceState = STATE_dfuMANIFEST_WAIT_RESET; - DeviceStatus[4] = DeviceState; - DeviceStatus[1] = 0; - DeviceStatus[2] = 0; - DeviceStatus[3] = 0; - - /* Disconnect the USB device */ - DCD_DevDisconnect (pdev); - - /* DeInitilialize the MAL(Media Access Layer) */ - MAL_DeInit(); - - /* Generate system reset to allow jumping to the user code */ - NVIC_SystemReset(); - - /* This instruction will not be reached (system reset) */ - return; - } -} - -/** - * @brief USBD_DFU_GetCfgDesc - * Returns configuration descriptor - * @param speed : current device speed - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -static uint8_t *USBD_DFU_GetCfgDesc (uint8_t speed, uint16_t *length) -{ - *length = sizeof (usbd_dfu_CfgDesc); - return usbd_dfu_CfgDesc; -} - -#ifdef USB_OTG_HS_CORE -/** - * @brief USBD_DFU_GetOtherCfgDesc - * Returns other speed configuration descriptor. - * @param speed : current device speed - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -static uint8_t *USBD_DFU_GetOtherCfgDesc (uint8_t speed, uint16_t *length) -{ - *length = sizeof (usbd_dfu_OtherCfgDesc); - return usbd_dfu_OtherCfgDesc; -} -#endif - -/** - * @brief USBD_DFU_GetUsrStringDesc - * Manages the transfer of memory interfaces string descriptors. - * @param speed : current device speed - * @param index: desciptor index - * @param length : pointer data length - * @retval pointer to the descriptor table or NULL if the descriptor is not supported. - */ -static uint8_t* USBD_DFU_GetUsrStringDesc (uint8_t speed, uint8_t index , uint16_t *length) -{ - /* Check if the requested string interface is supported */ - if (index <= (USBD_IDX_INTERFACE_STR + USBD_ITF_MAX_NUM)) - { - - - USBD_GetString ((uint8_t *)usbd_dfu_StringDesc[index - USBD_IDX_INTERFACE_STR - 1], USBD_StrDesc, length); - return USBD_StrDesc; - } - /* Not supported Interface Descriptor index */ - else - { - return NULL; - } -} -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c b/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c deleted file mode 100644 index 3d301e93c..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c +++ /dev/null @@ -1,281 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_dfu_mal.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Generic media access Layer. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_dfu_mal.h" - -#include "usbd_flash_if.h" - -#ifdef DFU_MAL_SUPPORT_OTP - #include "usbd_otp_if.h" -#endif - -#ifdef DFU_MAL_SUPPORT_MEM - #include "usbd_mem_if_template.h" -#endif - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ - -/* Global Memories callback and string descriptors reference tables. - To add a new memory, modify the value of MAX_USED_MEDIA in usbd_dfu_mal.h - and add the pointer to the callback structure in this table. - Then add the pointer to the memory string descriptor in usbd_dfu_StringDesc table. - No other operation is required. */ -DFU_MAL_Prop_TypeDef* tMALTab[MAX_USED_MEDIA] = { - &DFU_Flash_cb -#ifdef DFU_MAL_SUPPORT_OTP - , &DFU_Otp_cb -#endif -#ifdef DFU_MAL_SUPPORT_MEM - , &DFU_Mem_cb -#endif -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -__ALIGN_BEGIN const uint8_t* usbd_dfu_StringDesc[MAX_USED_MEDIA] __ALIGN_END = { - FLASH_IF_STRING -#ifdef DFU_MAL_SUPPORT_OTP - , OTP_IF_STRING -#endif -#ifdef DFU_MAL_SUPPORT_MEM - , MEM_IF_STRING -#endif -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* RAM Buffer for Downloaded Data */ -__ALIGN_BEGIN uint8_t MAL_Buffer[XFERSIZE] __ALIGN_END ; - -/* Private function prototypes -----------------------------------------------*/ -static uint8_t MAL_CheckAdd (uint32_t Add); -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief MAL_Init - * Initializes the Media on the STM32 - * @param None - * @retval Result of the opeartion (MAL_OK in all cases) - */ -uint16_t MAL_Init(void) -{ - uint32_t memIdx = 0; - - /* Init all supported memories */ - for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++) - { - /* If the check addres is positive, exit with the memory index */ - if (tMALTab[memIdx]->pMAL_Init != NULL) - { - tMALTab[memIdx]->pMAL_Init(); - } - } - - return MAL_OK; -} - -/** - * @brief MAL_DeInit - * DeInitializes the Media on the STM32 - * @param None - * @retval Result of the opeartion (MAL_OK in all cases) - */ -uint16_t MAL_DeInit(void) -{ - uint32_t memIdx = 0; - - /* Init all supported memories */ - for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++) - { - /* Check if the command is supported */ - if (tMALTab[memIdx]->pMAL_DeInit != NULL) - { - tMALTab[memIdx]->pMAL_DeInit(); - } - } - - return MAL_OK; -} - -/** - * @brief MAL_Erase - * Erase a sector of memory. - * @param Add: Sector address/code - * @retval Result of the opeartion: MAL_OK if all operations are OK else MAL_FAIL - */ -uint16_t MAL_Erase(uint32_t Add) -{ - uint32_t memIdx = MAL_CheckAdd(Add); - - /* Check if the area is protected */ - if (DFU_MAL_IS_PROTECTED_AREA(Add)) - { - return MAL_FAIL; - } - - if (memIdx < MAX_USED_MEDIA) - { - /* Check if the command is supported */ - if (tMALTab[memIdx]->pMAL_Erase != NULL) - { - return tMALTab[memIdx]->pMAL_Erase(Add); - } - else - { - return MAL_FAIL; - } - } - else - { - return MAL_FAIL; - } -} - -/** - * @brief MAL_Write - * Write sectors of memory. - * @param Add: Sector address/code - * @param Len: Number of data to be written (in bytes) - * @retval Result of the opeartion: MAL_OK if all operations are OK else MAL_FAIL - */ -uint16_t MAL_Write (uint32_t Add, uint32_t Len) -{ - uint32_t memIdx = MAL_CheckAdd(Add); - - /* Check if the area is protected */ - if (DFU_MAL_IS_PROTECTED_AREA(Add)) - { - return MAL_FAIL; - } - - if (memIdx < MAX_USED_MEDIA) - { - /* Check if the command is supported */ - if (tMALTab[memIdx]->pMAL_Write != NULL) - { - return tMALTab[memIdx]->pMAL_Write(Add, Len); - } - else - { - return MAL_FAIL; - } - } - else - { - return MAL_FAIL; - } -} - -/** - * @brief MAL_Read - * Read sectors of memory. - * @param Add: Sector address/code - * @param Len: Number of data to be written (in bytes) - * @retval Buffer pointer - */ -uint8_t *MAL_Read (uint32_t Add, uint32_t Len) -{ - uint32_t memIdx = MAL_CheckAdd(Add); - - if (memIdx < MAX_USED_MEDIA) - { - /* Check if the command is supported */ - if (tMALTab[memIdx]->pMAL_Read != NULL) - { - return tMALTab[memIdx]->pMAL_Read(Add, Len); - } - else - { - return MAL_Buffer; - } - } - else - { - return MAL_Buffer; - } -} - -/** - * @brief MAL_GetStatus - * Get the status of a given memory. - * @param Add: Sector address/code (allow to determine which memory will be addressed) - * @param Cmd: 0 for erase and 1 for write - * @param buffer: pointer to the buffer where the status data will be stored. - * @retval Buffer pointer - */ -uint16_t MAL_GetStatus(uint32_t Add , uint8_t Cmd, uint8_t *buffer) -{ - uint32_t memIdx = MAL_CheckAdd(Add); - - if (memIdx < MAX_USED_MEDIA) - { - if (Cmd & 0x01) - { - SET_POLLING_TIMING(tMALTab[memIdx]->EraseTiming); - } - else - { - SET_POLLING_TIMING(tMALTab[memIdx]->WriteTiming); - } - - return MAL_OK; - } - else - { - return MAL_FAIL; - } -} - -/** - * @brief MAL_CheckAdd - * Determine which memory should be managed. - * @param Add: Sector address/code (allow to determine which memory will be addressed) - * @retval Index of the addressed memory. - */ -static uint8_t MAL_CheckAdd(uint32_t Add) -{ - uint32_t memIdx = 0; - - /* Check with all supported memories */ - for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++) - { - /* If the check addres is positive, exit with the memory index */ - if (tMALTab[memIdx]->pMAL_CheckAdd(Add) == MAL_OK) - { - return memIdx; - } - } - /* If no memory found, return MAX_USED_MEDIA */ - return (MAX_USED_MEDIA); -} - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c b/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c deleted file mode 100644 index d5604d837..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c +++ /dev/null @@ -1,221 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_flash_if.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Specific media access Layer for internal flash. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_flash_if.h" -#include "usbd_dfu_mal.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ - -/* Private function prototypes -----------------------------------------------*/ -uint16_t FLASH_If_Init(void); -uint16_t FLASH_If_Erase (uint32_t Add); -uint16_t FLASH_If_Write (uint32_t Add, uint32_t Len); -uint8_t *FLASH_If_Read (uint32_t Add, uint32_t Len); -uint16_t FLASH_If_DeInit(void); -uint16_t FLASH_If_CheckAdd(uint32_t Add); - - -/* Private variables ---------------------------------------------------------*/ -DFU_MAL_Prop_TypeDef DFU_Flash_cb = - { - FLASH_IF_STRING, - FLASH_If_Init, - FLASH_If_DeInit, - FLASH_If_Erase, - FLASH_If_Write, - FLASH_If_Read, - FLASH_If_CheckAdd, - 50, /* Erase Time in ms */ - 50 /* Programming Time in ms */ - }; - -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief FLASH_If_Init - * Memory initialization routine. - * @param None - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t FLASH_If_Init(void) -{ - /* Unlock the internal flash */ - FLASH_Unlock(); - - return MAL_OK; -} - -/** - * @brief FLASH_If_DeInit - * Memory deinitialization routine. - * @param None - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t FLASH_If_DeInit(void) -{ - /* Lock the internal flash */ - FLASH_Lock(); - - return MAL_OK; -} - -/******************************************************************************* -* Function Name : FLASH_If_Erase -* Description : Erase sector -* Input : None -* Output : None -* Return : None -*******************************************************************************/ -uint16_t FLASH_If_Erase(uint32_t Add) -{ -#ifdef STM32F2XX - /* Check which sector has to be erased */ - if (Add < 0x08004000) - { - FLASH_EraseSector(FLASH_Sector_0, VoltageRange_3); - } - else if (Add < 0x08008000) - { - FLASH_EraseSector(FLASH_Sector_1, VoltageRange_3); - } - else if (Add < 0x0800C000) - { - FLASH_EraseSector(FLASH_Sector_2, VoltageRange_3); - } - else if (Add < 0x08010000) - { - FLASH_EraseSector(FLASH_Sector_3, VoltageRange_3); - } - else if (Add < 0x08020000) - { - FLASH_EraseSector(FLASH_Sector_4, VoltageRange_3); - } - else if (Add < 0x08040000) - { - FLASH_EraseSector(FLASH_Sector_5, VoltageRange_3); - } - else if (Add < 0x08060000) - { - FLASH_EraseSector(FLASH_Sector_6, VoltageRange_3); - } - else if (Add < 0x08080000) - { - FLASH_EraseSector(FLASH_Sector_7, VoltageRange_3); - } - else if (Add < 0x080A0000) - { - FLASH_EraseSector(FLASH_Sector_8, VoltageRange_3); - } - else if (Add < 0x080C0000) - { - FLASH_EraseSector(FLASH_Sector_9, VoltageRange_3); - } - else if (Add < 0x080E0000) - { - FLASH_EraseSector(FLASH_Sector_10, VoltageRange_3); - } - else if (Add < 0x08100000) - { - FLASH_EraseSector(FLASH_Sector_11, VoltageRange_3); - } - else - { - return MAL_FAIL; - } -#elif defined(STM32F10X_CL) - /* Call the standard Flash erase function */ - FLASH_ErasePage(Add); -#endif /* STM32F2XX */ - - return MAL_OK; -} - -/** - * @brief FLASH_If_Write - * Memory write routine. - * @param Add: Address to be written to. - * @param Len: Number of data to be written (in bytes). - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t FLASH_If_Write(uint32_t Add, uint32_t Len) -{ - uint32_t idx = 0; - - if (Len & 0x3) /* Not an aligned data */ - { - for (idx = Len; idx < ((Len & 0xFFFC) + 4); idx++) - { - MAL_Buffer[idx] = 0xFF; - } - } - - /* Data received are Word multiple */ - for (idx = 0; idx < Len; idx = idx + 4) - { - FLASH_ProgramWord(Add, *(uint32_t *)(MAL_Buffer + idx)); - Add += 4; - } - return MAL_OK; -} - -/** - * @brief FLASH_If_Read - * Memory read routine. - * @param Add: Address to be read from. - * @param Len: Number of data to be read (in bytes). - * @retval Pointer to the phyisical address where data should be read. - */ -uint8_t *FLASH_If_Read (uint32_t Add, uint32_t Len) -{ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - uint32_t idx = 0; - for (idx = 0; idx < Len; idx += 4) - { - *(uint32_t*)(MAL_Buffer + idx) = *(uint32_t *)(Add + idx); - } - return (uint8_t*)(MAL_Buffer); -#else - return (uint8_t *)(Add); -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -} - -/** - * @brief FLASH_If_CheckAdd - * Check if the address is an allowed address for this memory. - * @param Add: Address to be checked. - * @param Len: Number of data to be read (in bytes). - * @retval MAL_OK if the address is allowed, MAL_FAIL else. - */ -uint16_t FLASH_If_CheckAdd(uint32_t Add) -{ - if ((Add >= FLASH_START_ADD) && (Add < FLASH_END_ADD)) - { - return MAL_OK; - } - else - { - return MAL_FAIL; - } -} -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c b/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c deleted file mode 100644 index 4295e40ff..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c +++ /dev/null @@ -1,133 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_mem_if_template.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Specific media access Layer for a template memory. This file is - provided as template example showing how to implement a new memory - interface based on pre-defined API. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_mem_if_template.h" -#include "usbd_dfu_mal.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ - -/* Private function prototypes -----------------------------------------------*/ -uint16_t MEM_If_Init(void); -uint16_t MEM_If_Erase (uint32_t Add); -uint16_t MEM_If_Write (uint32_t Add, uint32_t Len); -uint8_t *MEM_If_Read (uint32_t Add, uint32_t Len); -uint16_t MEM_If_DeInit(void); -uint16_t MEM_If_CheckAdd(uint32_t Add); - - -/* Private variables ---------------------------------------------------------*/ -DFU_MAL_Prop_TypeDef DFU_Mem_cb = - { - MEM_IF_STRING, - MEM_If_Init, - MEM_If_DeInit, - MEM_If_Erase, - MEM_If_Write, - MEM_If_Read, - MEM_If_CheckAdd, - 10, /* Erase Time in ms */ - 10 /* Programming Time in ms */ - }; - -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief MEM_If_Init - * Memory initialization routine. - * @param None - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t MEM_If_Init(void) -{ - return MAL_OK; -} - -/** - * @brief MEM_If_DeInit - * Memory deinitialization routine. - * @param None - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t MEM_If_DeInit(void) -{ - return MAL_OK; -} - -/** - * @brief MEM_If_Erase - * Erase sector. - * @param Add: Address of sector to be erased. - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t MEM_If_Erase(uint32_t Add) -{ - return MAL_OK; -} - -/** - * @brief MEM_If_Write - * Memory write routine. - * @param Add: Address to be written to. - * @param Len: Number of data to be written (in bytes). - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t MEM_If_Write(uint32_t Add, uint32_t Len) -{ - return MAL_OK; -} - -/** - * @brief MEM_If_Read - * Memory read routine. - * @param Add: Address to be read from. - * @param Len: Number of data to be read (in bytes). - * @retval Pointer to the phyisical address where data should be read. - */ -uint8_t *MEM_If_Read (uint32_t Add, uint32_t Len) -{ - /* Return a valid address to avoid HardFault */ - return (uint8_t*)(MAL_Buffer); -} - -/** - * @brief MEM_If_CheckAdd - * Check if the address is an allowed address for this memory. - * @param Add: Address to be checked. - * @param Len: Number of data to be read (in bytes). - * @retval MAL_OK if the address is allowed, MAL_FAIL else. - */ -uint16_t MEM_If_CheckAdd(uint32_t Add) -{ - if ((Add >= MEM_START_ADD) && (Add < MEM_END_ADD)) - { - return MAL_OK; - } - else - { - return MAL_FAIL; - } -} -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_otp_if.c b/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_otp_if.c deleted file mode 100644 index 5970c0ea3..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/dfu/src/usbd_otp_if.c +++ /dev/null @@ -1,120 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_otp_if.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Specific media access Layer for OTP (One Time Programming) memory. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_otp_if.h" -#include "usbd_dfu_mal.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ - -/* Private function prototypes -----------------------------------------------*/ -uint16_t OTP_If_Write (uint32_t Add, uint32_t Len); -uint8_t *OTP_If_Read (uint32_t Add, uint32_t Len); -uint16_t OTP_If_DeInit(void); -uint16_t OTP_If_CheckAdd(uint32_t Add); - - -/* Private variables ---------------------------------------------------------*/ -DFU_MAL_Prop_TypeDef DFU_Otp_cb = - { - OTP_IF_STRING, - NULL, /* Init not supported*/ - NULL, /* DeInit not supported */ - NULL, /* Erase not supported */ - OTP_If_Write, - OTP_If_Read, - OTP_If_CheckAdd, - 1, /* Erase Time in ms */ - 10 /* Programming Time in ms */ - }; - -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief OTP_If_Write - * Memory write routine. - * @param Add: Address to be written to. - * @param Len: Number of data to be written (in bytes). - * @retval MAL_OK if operation is successeful, MAL_FAIL else. - */ -uint16_t OTP_If_Write(uint32_t Add, uint32_t Len) -{ - uint32_t idx = 0; - - if (Len & 0x3) /* Not an aligned data */ - { - for (idx = Len; idx < ((Len & 0xFFFC) + 4); idx++) - { - MAL_Buffer[idx] = 0xFF; - } - } - - /* Data received are Word multiple */ - for (idx = 0; idx < Len; idx = idx + 4) - { - FLASH_ProgramWord(Add, *(uint32_t *)(MAL_Buffer + idx)); - Add += 4; - } - return MAL_OK; -} - -/** - * @brief OTP_If_Read - * Memory read routine. - * @param Add: Address to be read from. - * @param Len: Number of data to be read (in bytes). - * @retval Pointer to the phyisical address where data should be read. - */ -uint8_t *OTP_If_Read (uint32_t Add, uint32_t Len) -{ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - uint32_t idx = 0; - for (idx = 0; idx < Len; idx += 4) - { - *(uint32_t*)(MAL_Buffer + idx) = *(uint32_t *)(Add + idx); - } - return (uint8_t*)(MAL_Buffer); -#else - return (uint8_t*)(Add); -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -} - -/** - * @brief OTP_If_CheckAdd - * Check if the address is an allowed address for this memory. - * @param Add: Address to be checked. - * @param Len: Number of data to be read (in bytes). - * @retval MAL_OK if the address is allowed, MAL_FAIL else. - */ -uint16_t OTP_If_CheckAdd(uint32_t Add) -{ - if ((Add >= OTP_START_ADD) && (Add < OTP_END_ADD)) - { - return MAL_OK; - } - else - { - return MAL_FAIL; - } -} -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h b/example/stm32f4/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h deleted file mode 100644 index d93fc77d6..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h +++ /dev/null @@ -1,110 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_hid_core.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header file for the usbd_hid_core.c file. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ - -#ifndef __USB_HID_CORE_H_ -#define __USB_HID_CORE_H_ - -#include "usbd_ioreq.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_HID - * @brief This file is the Header file for USBD_msc.c - * @{ - */ - - -/** @defgroup USBD_HID_Exported_Defines - * @{ - */ -#define USB_HID_CONFIG_DESC_SIZ 34 -#define USB_HID_DESC_SIZ 9 -#define HID_MOUSE_REPORT_DESC_SIZE 74 - -#define HID_DESCRIPTOR_TYPE 0x21 -#define HID_REPORT_DESC 0x22 - - -#define HID_REQ_SET_PROTOCOL 0x0B -#define HID_REQ_GET_PROTOCOL 0x03 - -#define HID_REQ_SET_IDLE 0x0A -#define HID_REQ_GET_IDLE 0x02 - -#define HID_REQ_SET_REPORT 0x09 -#define HID_REQ_GET_REPORT 0x01 -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_TypesDefinitions - * @{ - */ - - -/** - * @} - */ - - - -/** @defgroup USBD_CORE_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Variables - * @{ - */ - -extern USBD_Class_cb_TypeDef USBD_HID_cb; -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Functions - * @{ - */ -uint8_t USBD_HID_SendReport (USB_OTG_CORE_HANDLE *pdev, - uint8_t *report, - uint16_t len); -/** - * @} - */ - -#endif // __USB_HID_CORE_H_ -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c b/example/stm32f4/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c deleted file mode 100644 index a56c5ed49..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c +++ /dev/null @@ -1,460 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_hid_core.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the HID core functions. - * - * @verbatim - * - * =================================================================== - * HID Class Description - * =================================================================== - * This module manages the HID class V1.11 following the "Device Class Definition - * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001". - * This driver implements the following aspects of the specification: - * - The Boot Interface Subclass - * - The Mouse protocol - * - Usage Page : Generic Desktop - * - Usage : Joystick) - * - Collection : Application - * - * @note In HS mode and when the DMA is used, all variables and data structures - * dealing with the DMA during the transaction process should be 32-bit aligned. - * - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_hid_core.h" -#include "usbd_desc.h" -#include "usbd_req.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup USBD_HID - * @brief usbd core module - * @{ - */ - -/** @defgroup USBD_HID_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_HID_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBD_HID_Private_Macros - * @{ - */ -/** - * @} - */ - - - - -/** @defgroup USBD_HID_Private_FunctionPrototypes - * @{ - */ - - -static uint8_t USBD_HID_Init (void *pdev, - uint8_t cfgidx); - -static uint8_t USBD_HID_DeInit (void *pdev, - uint8_t cfgidx); - -static uint8_t USBD_HID_Setup (void *pdev, - USB_SETUP_REQ *req); - -static uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length); - -static uint8_t USBD_HID_DataIn (void *pdev, uint8_t epnum); -/** - * @} - */ - -/** @defgroup USBD_HID_Private_Variables - * @{ - */ - -USBD_Class_cb_TypeDef USBD_HID_cb = -{ - USBD_HID_Init, - USBD_HID_DeInit, - USBD_HID_Setup, - NULL, /*EP0_TxSent*/ - NULL, /*EP0_RxReady*/ - USBD_HID_DataIn, /*DataIn*/ - NULL, /*DataOut*/ - NULL, /*SOF */ - NULL, - NULL, - USBD_HID_GetCfgDesc, -#ifdef USB_OTG_HS_CORE - USBD_HID_GetCfgDesc, /* use same config as per FS */ -#endif -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN static uint32_t USBD_HID_AltSet __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN static uint32_t USBD_HID_Protocol __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN static uint32_t USBD_HID_IdleState __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* USB HID device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuration Descriptor size */ - USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */ - USB_HID_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ - 0x00, - 0x01, /*bNumInterfaces: 1 interface*/ - 0x01, /*bConfigurationValue: Configuration value*/ - 0x00, /*iConfiguration: Index of string descriptor describing - the configuration*/ - 0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /*bLength: Interface Descriptor size*/ - USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/ - 0x00, /*bInterfaceNumber: Number of Interface*/ - 0x00, /*bAlternateSetting: Alternate setting*/ - 0x01, /*bNumEndpoints*/ - 0x03, /*bInterfaceClass: HID*/ - 0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ - 0x02, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ - 0, /*iInterface: Index of string descriptor*/ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /*bLength: HID Descriptor size*/ - HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ - 0x11, /*bcdHID: HID Class Spec release number*/ - 0x01, - 0x00, /*bCountryCode: Hardware target country*/ - 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /*bLength: Endpoint Descriptor size*/ - USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/ - - HID_IN_EP, /*bEndpointAddress: Endpoint Address (IN)*/ - 0x03, /*bmAttributes: Interrupt endpoint*/ - HID_IN_PACKET, /*wMaxPacketSize: 4 Byte max */ - 0x00, - 0x0A, /*bInterval: Polling Interval (10 ms)*/ - /* 34 */ -} ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = -{ - 0x05, 0x01, - 0x09, 0x02, - 0xA1, 0x01, - 0x09, 0x01, - - 0xA1, 0x00, - 0x05, 0x09, - 0x19, 0x01, - 0x29, 0x03, - - 0x15, 0x00, - 0x25, 0x01, - 0x95, 0x03, - 0x75, 0x01, - - 0x81, 0x02, - 0x95, 0x01, - 0x75, 0x05, - 0x81, 0x01, - - 0x05, 0x01, - 0x09, 0x30, - 0x09, 0x31, - 0x09, 0x38, - - 0x15, 0x81, - 0x25, 0x7F, - 0x75, 0x08, - 0x95, 0x03, - - 0x81, 0x06, - 0xC0, 0x09, - 0x3c, 0x05, - 0xff, 0x09, - - 0x01, 0x15, - 0x00, 0x25, - 0x01, 0x75, - 0x01, 0x95, - - 0x02, 0xb1, - 0x22, 0x75, - 0x06, 0x95, - 0x01, 0xb1, - - 0x01, 0xc0 -}; - -/** - * @} - */ - -/** @defgroup USBD_HID_Private_Functions - * @{ - */ - -/** - * @brief USBD_HID_Init - * Initialize the HID interface - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -static uint8_t USBD_HID_Init (void *pdev, - uint8_t cfgidx) -{ - - /* Open EP IN */ - DCD_EP_Open(pdev, - HID_IN_EP, - HID_IN_PACKET, - USB_OTG_EP_INT); - - /* Open EP OUT */ - DCD_EP_Open(pdev, - HID_OUT_EP, - HID_OUT_PACKET, - USB_OTG_EP_INT); - - return USBD_OK; -} - -/** - * @brief USBD_HID_Init - * DeInitialize the HID layer - * @param pdev: device instance - * @param cfgidx: Configuration index - * @retval status - */ -static uint8_t USBD_HID_DeInit (void *pdev, - uint8_t cfgidx) -{ - /* Close HID EPs */ - DCD_EP_Close (pdev , HID_IN_EP); - DCD_EP_Close (pdev , HID_OUT_EP); - - - return USBD_OK; -} - -/** - * @brief USBD_HID_Setup - * Handle the HID specific requests - * @param pdev: instance - * @param req: usb requests - * @retval status - */ -static uint8_t USBD_HID_Setup (void *pdev, - USB_SETUP_REQ *req) -{ - uint16_t len = 0; - uint8_t *pbuf = NULL; - - switch (req->bmRequest & USB_REQ_TYPE_MASK) - { - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - - - case HID_REQ_SET_PROTOCOL: - USBD_HID_Protocol = (uint8_t)(req->wValue); - break; - - case HID_REQ_GET_PROTOCOL: - USBD_CtlSendData (pdev, - (uint8_t *)&USBD_HID_Protocol, - 1); - break; - - case HID_REQ_SET_IDLE: - USBD_HID_IdleState = (uint8_t)(req->wValue >> 8); - break; - - case HID_REQ_GET_IDLE: - USBD_CtlSendData (pdev, - (uint8_t *)&USBD_HID_IdleState, - 1); - break; - - default: - USBD_CtlError (pdev, req); - return USBD_FAIL; - } - break; - - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - if( req->wValue >> 8 == HID_REPORT_DESC) - { - len = MIN(HID_MOUSE_REPORT_DESC_SIZE , req->wLength); - pbuf = HID_MOUSE_ReportDesc; - } - else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE) - { - -//#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED -// pbuf = USBD_HID_Desc; -//#else - pbuf = USBD_HID_CfgDesc + 0x12; -//#endif - len = MIN(USB_HID_DESC_SIZ , req->wLength); - } - - USBD_CtlSendData (pdev, - pbuf, - len); - - break; - - case USB_REQ_GET_INTERFACE : - USBD_CtlSendData (pdev, - (uint8_t *)&USBD_HID_AltSet, - 1); - break; - - case USB_REQ_SET_INTERFACE : - USBD_HID_AltSet = (uint8_t)(req->wValue); - break; - } - } - return USBD_OK; -} - -/** - * @brief USBD_HID_SendReport - * Send HID Report - * @param pdev: device instance - * @param buff: pointer to report - * @retval status - */ -uint8_t USBD_HID_SendReport (USB_OTG_CORE_HANDLE *pdev, - uint8_t *report, - uint16_t len) -{ - if (pdev->dev.device_status == USB_OTG_CONFIGURED ) - { - DCD_EP_Tx (pdev, HID_IN_EP, report, len); - } - return USBD_OK; -} - -/** - * @brief USBD_HID_GetCfgDesc - * return configuration descriptor - * @param speed : current device speed - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -static uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length) -{ - *length = sizeof (USBD_HID_CfgDesc); - return USBD_HID_CfgDesc; -} - -/** - * @brief USBD_HID_DataIn - * handle data IN Stage - * @param pdev: device instance - * @param epnum: endpoint index - * @retval status - */ -static uint8_t USBD_HID_DataIn (void *pdev, - uint8_t epnum) -{ - - /* Ensure that the FIFO is empty before a new transfer, this condition could - be caused by a new transfer before the end of the previous transfer */ - DCD_EP_Flush(pdev, HID_IN_EP); - return USBD_OK; -} - -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h b/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h deleted file mode 100644 index 64b6d262c..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h +++ /dev/null @@ -1,147 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_msc_bot.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header for the usbd_msc_bot.c file - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#include "usbd_core.h" - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_MSC_BOT_H -#define __USBD_MSC_BOT_H - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup MSC_BOT - * @brief This file is the Header file for usbd_bot.c - * @{ - */ - - -/** @defgroup USBD_CORE_Exported_Defines - * @{ - */ -#define BOT_IDLE 0 /* Idle state */ -#define BOT_DATA_OUT 1 /* Data Out state */ -#define BOT_DATA_IN 2 /* Data In state */ -#define BOT_LAST_DATA_IN 3 /* Last Data In Last */ -#define BOT_SEND_DATA 4 /* Send Immediate data */ - -#define BOT_CBW_SIGNATURE 0x43425355 -#define BOT_CSW_SIGNATURE 0x53425355 -#define BOT_CBW_LENGTH 31 -#define BOT_CSW_LENGTH 13 - -/* CSW Status Definitions */ -#define CSW_CMD_PASSED 0x00 -#define CSW_CMD_FAILED 0x01 -#define CSW_PHASE_ERROR 0x02 - -/* BOT Status */ -#define BOT_STATE_NORMAL 0 -#define BOT_STATE_RECOVERY 1 -#define BOT_STATE_ERROR 2 - - -#define DIR_IN 0 -#define DIR_OUT 1 -#define BOTH_DIR 2 - -/** - * @} - */ - -/** @defgroup MSC_CORE_Private_TypesDefinitions - * @{ - */ - -typedef struct _MSC_BOT_CBW -{ - uint32_t dSignature; - uint32_t dTag; - uint32_t dDataLength; - uint8_t bmFlags; - uint8_t bLUN; - uint8_t bCBLength; - uint8_t CB[16]; -} -MSC_BOT_CBW_TypeDef; - - -typedef struct _MSC_BOT_CSW -{ - uint32_t dSignature; - uint32_t dTag; - uint32_t dDataResidue; - uint8_t bStatus; -} -MSC_BOT_CSW_TypeDef; - -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_Types - * @{ - */ - -extern uint8_t MSC_BOT_Data[]; -extern uint16_t MSC_BOT_DataLen; -extern uint8_t MSC_BOT_State; -extern uint8_t MSC_BOT_BurstMode; -extern MSC_BOT_CBW_TypeDef MSC_BOT_cbw; -extern MSC_BOT_CSW_TypeDef MSC_BOT_csw; -/** - * @} - */ -/** @defgroup USBD_CORE_Exported_FunctionsPrototypes - * @{ - */ -void MSC_BOT_Init (USB_OTG_CORE_HANDLE *pdev); -void MSC_BOT_Reset (USB_OTG_CORE_HANDLE *pdev); -void MSC_BOT_DeInit (USB_OTG_CORE_HANDLE *pdev); -void MSC_BOT_DataIn (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum); - -void MSC_BOT_DataOut (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum); - -void MSC_BOT_SendCSW (USB_OTG_CORE_HANDLE *pdev, - uint8_t CSW_Status); - -void MSC_BOT_CplClrFeature (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum); -/** - * @} - */ - -#endif /* __USBD_MSC_BOT_H */ -/** - * @} - */ - -/** -* @} -*/ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h b/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h deleted file mode 100644 index be1d401e2..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_msc_core.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header for the usbd_msc_core.c file - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef _USB_MSC_CORE_H_ -#define _USB_MSC_CORE_H_ - -#include "usbd_ioreq.h" - -/** @addtogroup USBD_MSC_BOT - * @{ - */ - -/** @defgroup USBD_MSC - * @brief This file is the Header file for USBD_msc.c - * @{ - */ - - -/** @defgroup USBD_BOT_Exported_Defines - * @{ - */ - - -#define BOT_GET_MAX_LUN 0xFE -#define BOT_RESET 0xFF -#define USB_MSC_CONFIG_DESC_SIZ 32 - -#define MSC_EPIN_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 22) - -#define MSC_EPOUT_SIZE *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 29) - -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Types - * @{ - */ - -extern USBD_Class_cb_TypeDef USBD_MSC_cb; -/** - * @} - */ - -/** - * @} - */ -#endif // _USB_MSC_CORE_H_ -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h b/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h deleted file mode 100644 index e0a677f88..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_msc_data.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header for the usbd_msc_data.c file - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef _USBD_MSC_DATA_H_ -#define _USBD_MSC_DATA_H_ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_conf.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USB_INFO - * @brief general defines for the usb device library file - * @{ - */ - -/** @defgroup USB_INFO_Exported_Defines - * @{ - */ -#define MODE_SENSE6_LEN 8 -#define MODE_SENSE10_LEN 8 -#define LENGTH_INQUIRY_PAGE00 7 -#define LENGTH_FORMAT_CAPACITIES 20 - -/** - * @} - */ - - -/** @defgroup USBD_INFO_Exported_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USBD_INFO_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_INFO_Exported_Variables - * @{ - */ -extern const uint8_t MSC_Page00_Inquiry_Data[]; -extern const uint8_t MSC_Mode_Sense6_data[]; -extern const uint8_t MSC_Mode_Sense10_data[] ; - -/** - * @} - */ - -/** @defgroup USBD_INFO_Exported_FunctionsPrototype - * @{ - */ - -/** - * @} - */ - -#endif /* _USBD_MSC_DATA_H_ */ - -/** - * @} - */ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h b/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h deleted file mode 100644 index 811e9ee8b..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h +++ /dev/null @@ -1,106 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_msc_mem.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header for the STORAGE DISK file file - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef __USBD_MEM_H -#define __USBD_MEM_H -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_MEM - * @brief header file for the storage disk file - * @{ - */ - -/** @defgroup USBD_MEM_Exported_Defines - * @{ - */ -#define USBD_STD_INQUIRY_LENGTH 36 -/** - * @} - */ - - -/** @defgroup USBD_MEM_Exported_TypesDefinitions - * @{ - */ - -typedef struct _USBD_STORAGE -{ - int8_t (* Init) (uint8_t lun); - int8_t (* GetCapacity) (uint8_t lun, uint32_t *block_num, uint32_t *block_size); - int8_t (* IsReady) (uint8_t lun); - int8_t (* IsWriteProtected) (uint8_t lun); - int8_t (* Read) (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); - int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); - int8_t (* GetMaxLun)(void); - int8_t *pInquiry; - -}USBD_STORAGE_cb_TypeDef; -/** - * @} - */ - - - -/** @defgroup USBD_MEM_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_MEM_Exported_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_MEM_Exported_FunctionsPrototype - * @{ - */ -extern USBD_STORAGE_cb_TypeDef *USBD_STORAGE_fops; -/** - * @} - */ - -#endif /* __USBD_MEM_H */ -/** - * @} - */ - -/** - * @} - */ - -/** -* @} -*/ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h b/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h deleted file mode 100644 index 5ba83ad1d..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h +++ /dev/null @@ -1,189 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_msc_scsi.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header for the usbd_msc_scsi.c file - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_MSC_SCSI_H -#define __USBD_MSC_SCSI_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_SCSI - * @brief header file for the storage disk file - * @{ - */ - -/** @defgroup USBD_SCSI_Exported_Defines - * @{ - */ - -#define SENSE_LIST_DEEPTH 4 - -/* SCSI Commands */ -#define SCSI_FORMAT_UNIT 0x04 -#define SCSI_INQUIRY 0x12 -#define SCSI_MODE_SELECT6 0x15 -#define SCSI_MODE_SELECT10 0x55 -#define SCSI_MODE_SENSE6 0x1A -#define SCSI_MODE_SENSE10 0x5A -#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E -#define SCSI_READ6 0x08 -#define SCSI_READ10 0x28 -#define SCSI_READ12 0xA8 -#define SCSI_READ16 0x88 - -#define SCSI_READ_CAPACITY10 0x25 -#define SCSI_READ_CAPACITY16 0x9E - -#define SCSI_REQUEST_SENSE 0x03 -#define SCSI_START_STOP_UNIT 0x1B -#define SCSI_TEST_UNIT_READY 0x00 -#define SCSI_WRITE6 0x0A -#define SCSI_WRITE10 0x2A -#define SCSI_WRITE12 0xAA -#define SCSI_WRITE16 0x8A - -#define SCSI_VERIFY10 0x2F -#define SCSI_VERIFY12 0xAF -#define SCSI_VERIFY16 0x8F - -#define SCSI_SEND_DIAGNOSTIC 0x1D -#define SCSI_READ_FORMAT_CAPACITIES 0x23 - -#define NO_SENSE 0 -#define RECOVERED_ERROR 1 -#define NOT_READY 2 -#define MEDIUM_ERROR 3 -#define HARDWARE_ERROR 4 -#define ILLEGAL_REQUEST 5 -#define UNIT_ATTENTION 6 -#define DATA_PROTECT 7 -#define BLANK_CHECK 8 -#define VENDOR_SPECIFIC 9 -#define COPY_ABORTED 10 -#define ABORTED_COMMAND 11 -#define VOLUME_OVERFLOW 13 -#define MISCOMPARE 14 - - -#define INVALID_CDB 0x20 -#define INVALID_FIELED_IN_COMMAND 0x24 -#define PARAMETER_LIST_LENGTH_ERROR 0x1A -#define INVALID_FIELD_IN_PARAMETER_LIST 0x26 -#define ADDRESS_OUT_OF_RANGE 0x21 -#define MEDIUM_NOT_PRESENT 0x3A -#define MEDIUM_HAVE_CHANGED 0x28 -#define WRITE_PROTECTED 0x27 -#define UNRECOVERED_READ_ERROR 0x11 -#define WRITE_FAULT 0x03 - -#define READ_FORMAT_CAPACITY_DATA_LEN 0x0C -#define READ_CAPACITY10_DATA_LEN 0x08 -#define MODE_SENSE10_DATA_LEN 0x08 -#define MODE_SENSE6_DATA_LEN 0x04 -#define REQUEST_SENSE_DATA_LEN 0x12 -#define STANDARD_INQUIRY_DATA_LEN 0x24 -#define BLKVFY 0x04 - -extern uint8_t Page00_Inquiry_Data[]; -extern uint8_t Standard_Inquiry_Data[]; -extern uint8_t Standard_Inquiry_Data2[]; -extern uint8_t Mode_Sense6_data[]; -extern uint8_t Mode_Sense10_data[]; -extern uint8_t Scsi_Sense_Data[]; -extern uint8_t ReadCapacity10_Data[]; -extern uint8_t ReadFormatCapacity_Data []; -/** - * @} - */ - - -/** @defgroup USBD_SCSI_Exported_TypesDefinitions - * @{ - */ - -typedef struct _SENSE_ITEM { - char Skey; - union { - struct _ASCs { - char ASC; - char ASCQ; - }b; - unsigned int ASC; - char *pData; - } w; -} SCSI_Sense_TypeDef; -/** - * @} - */ - -/** @defgroup USBD_SCSI_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_SCSI_Exported_Variables - * @{ - */ -extern SCSI_Sense_TypeDef SCSI_Sense [SENSE_LIST_DEEPTH]; -extern uint8_t SCSI_Sense_Head; -extern uint8_t SCSI_Sense_Tail; - -/** - * @} - */ -/** @defgroup USBD_SCSI_Exported_FunctionsPrototype - * @{ - */ -int8_t SCSI_ProcessCmd(USB_OTG_CORE_HANDLE *pdev, - uint8_t lun, - uint8_t *cmd); - -void SCSI_SenseCode(uint8_t lun, - uint8_t sKey, - uint8_t ASC); - -/** - * @} - */ - -#endif /* __USBD_MSC_SCSI_H */ -/** - * @} - */ - -/** - * @} - */ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c b/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c deleted file mode 100644 index 01c88ddda..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c +++ /dev/null @@ -1,393 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_msc_bot.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides all the BOT protocol core functions. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_msc_bot.h" -#include "usbd_msc_scsi.h" -#include "usbd_ioreq.h" -#include "usbd_msc_mem.h" -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup MSC_BOT - * @brief BOT protocol module - * @{ - */ - -/** @defgroup MSC_BOT_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_BOT_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup MSC_BOT_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_BOT_Private_Variables - * @{ - */ -uint16_t MSC_BOT_DataLen; -uint8_t MSC_BOT_State; -uint8_t MSC_BOT_Status; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t MSC_BOT_Data[MSC_MEDIA_PACKET] __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN MSC_BOT_CBW_TypeDef MSC_BOT_cbw __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN MSC_BOT_CSW_TypeDef MSC_BOT_csw __ALIGN_END ; -/** - * @} - */ - - -/** @defgroup MSC_BOT_Private_FunctionPrototypes - * @{ - */ -static void MSC_BOT_CBW_Decode (USB_OTG_CORE_HANDLE *pdev); - -static void MSC_BOT_SendData (USB_OTG_CORE_HANDLE *pdev, - uint8_t* pbuf, - uint16_t len); - -static void MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev); -/** - * @} - */ - - -/** @defgroup MSC_BOT_Private_Functions - * @{ - */ - - - -/** -* @brief MSC_BOT_Init -* Initialize the BOT Process -* @param pdev: device instance -* @retval None -*/ -void MSC_BOT_Init (USB_OTG_CORE_HANDLE *pdev) -{ - MSC_BOT_State = BOT_IDLE; - MSC_BOT_Status = BOT_STATE_NORMAL; - USBD_STORAGE_fops->Init(0); - - DCD_EP_Flush(pdev, MSC_OUT_EP); - DCD_EP_Flush(pdev, MSC_IN_EP); - /* Prapare EP to Receive First BOT Cmd */ - DCD_EP_PrepareRx (pdev, - MSC_OUT_EP, - (uint8_t *)&MSC_BOT_cbw, - BOT_CBW_LENGTH); -} - -/** -* @brief MSC_BOT_Reset -* Reset the BOT Machine -* @param pdev: device instance -* @retval None -*/ -void MSC_BOT_Reset (USB_OTG_CORE_HANDLE *pdev) -{ - MSC_BOT_State = BOT_IDLE; - MSC_BOT_Status = BOT_STATE_RECOVERY; - /* Prapare EP to Receive First BOT Cmd */ - DCD_EP_PrepareRx (pdev, - MSC_OUT_EP, - (uint8_t *)&MSC_BOT_cbw, - BOT_CBW_LENGTH); -} - -/** -* @brief MSC_BOT_DeInit -* Uninitialize the BOT Machine -* @param pdev: device instance -* @retval None -*/ -void MSC_BOT_DeInit (USB_OTG_CORE_HANDLE *pdev) -{ - MSC_BOT_State = BOT_IDLE; -} - -/** -* @brief MSC_BOT_DataIn -* Handle BOT IN data stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval None -*/ -void MSC_BOT_DataIn (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum) -{ - - switch (MSC_BOT_State) - { - case BOT_DATA_IN: - if(SCSI_ProcessCmd(pdev, - MSC_BOT_cbw.bLUN, - &MSC_BOT_cbw.CB[0]) < 0) - { - MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED); - } - break; - - case BOT_SEND_DATA: - case BOT_LAST_DATA_IN: - MSC_BOT_SendCSW (pdev, CSW_CMD_PASSED); - - break; - - default: - break; - } -} -/** -* @brief MSC_BOT_DataOut -* Proccess MSC OUT data -* @param pdev: device instance -* @param epnum: endpoint index -* @retval None -*/ -void MSC_BOT_DataOut (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum) -{ - switch (MSC_BOT_State) - { - case BOT_IDLE: - MSC_BOT_CBW_Decode(pdev); - break; - - case BOT_DATA_OUT: - - if(SCSI_ProcessCmd(pdev, - MSC_BOT_cbw.bLUN, - &MSC_BOT_cbw.CB[0]) < 0) - { - MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED); - } - - break; - - default: - break; - } - -} - -/** -* @brief MSC_BOT_CBW_Decode -* Decode the CBW command and set the BOT state machine accordingtly -* @param pdev: device instance -* @retval None -*/ -static void MSC_BOT_CBW_Decode (USB_OTG_CORE_HANDLE *pdev) -{ - - MSC_BOT_csw.dTag = MSC_BOT_cbw.dTag; - MSC_BOT_csw.dDataResidue = MSC_BOT_cbw.dDataLength; - - if ((USBD_GetRxCount (pdev ,MSC_OUT_EP) != BOT_CBW_LENGTH) || - (MSC_BOT_cbw.dSignature != BOT_CBW_SIGNATURE)|| - (MSC_BOT_cbw.bLUN > 1) || - (MSC_BOT_cbw.bCBLength < 1) || - (MSC_BOT_cbw.bCBLength > 16)) - { - - SCSI_SenseCode(MSC_BOT_cbw.bLUN, - ILLEGAL_REQUEST, - INVALID_CDB); - MSC_BOT_Status = BOT_STATE_ERROR; - MSC_BOT_Abort(pdev); - - } - else - { - if(SCSI_ProcessCmd(pdev, - MSC_BOT_cbw.bLUN, - &MSC_BOT_cbw.CB[0]) < 0) - { - MSC_BOT_Abort(pdev); - } - /*Burst xfer handled internally*/ - else if ((MSC_BOT_State != BOT_DATA_IN) && - (MSC_BOT_State != BOT_DATA_OUT) && - (MSC_BOT_State != BOT_LAST_DATA_IN)) - { - if (MSC_BOT_DataLen > 0) - { - MSC_BOT_SendData(pdev, - MSC_BOT_Data, - MSC_BOT_DataLen); - } - else if (MSC_BOT_DataLen == 0) - { - MSC_BOT_SendCSW (pdev, - CSW_CMD_PASSED); - } - } - } -} - -/** -* @brief MSC_BOT_SendData -* Send the requested data -* @param pdev: device instance -* @param buf: pointer to data buffer -* @param len: Data Length -* @retval None -*/ -static void MSC_BOT_SendData(USB_OTG_CORE_HANDLE *pdev, - uint8_t* buf, - uint16_t len) -{ - - len = MIN (MSC_BOT_cbw.dDataLength, len); - MSC_BOT_csw.dDataResidue -= len; - MSC_BOT_csw.bStatus = CSW_CMD_PASSED; - MSC_BOT_State = BOT_SEND_DATA; - - DCD_EP_Tx (pdev, MSC_IN_EP, buf, len); -} - -/** -* @brief MSC_BOT_SendCSW -* Send the Command Status Wrapper -* @param pdev: device instance -* @param status : CSW status -* @retval None -*/ -void MSC_BOT_SendCSW (USB_OTG_CORE_HANDLE *pdev, - uint8_t CSW_Status) -{ - MSC_BOT_csw.dSignature = BOT_CSW_SIGNATURE; - MSC_BOT_csw.bStatus = CSW_Status; - MSC_BOT_State = BOT_IDLE; - - DCD_EP_Tx (pdev, - MSC_IN_EP, - (uint8_t *)&MSC_BOT_csw, - BOT_CSW_LENGTH); - - /* Prapare EP to Receive next Cmd */ - DCD_EP_PrepareRx (pdev, - MSC_OUT_EP, - (uint8_t *)&MSC_BOT_cbw, - BOT_CBW_LENGTH); - -} - -/** -* @brief MSC_BOT_Abort -* Abort the current transfer -* @param pdev: device instance -* @retval status -*/ - -static void MSC_BOT_Abort (USB_OTG_CORE_HANDLE *pdev) -{ - - if ((MSC_BOT_cbw.bmFlags == 0) && - (MSC_BOT_cbw.dDataLength != 0) && - (MSC_BOT_Status == BOT_STATE_NORMAL) ) - { - DCD_EP_Stall(pdev, MSC_OUT_EP ); - } - DCD_EP_Stall(pdev, MSC_IN_EP); - - if(MSC_BOT_Status == BOT_STATE_ERROR) - { - DCD_EP_PrepareRx (pdev, - MSC_OUT_EP, - (uint8_t *)&MSC_BOT_cbw, - BOT_CBW_LENGTH); - } -} - -/** -* @brief MSC_BOT_CplClrFeature -* Complete the clear feature request -* @param pdev: device instance -* @param epnum: endpoint index -* @retval None -*/ - -void MSC_BOT_CplClrFeature (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum) -{ - if(MSC_BOT_Status == BOT_STATE_ERROR )/* Bad CBW Signature */ - { - DCD_EP_Stall(pdev, MSC_IN_EP); - MSC_BOT_Status = BOT_STATE_NORMAL; - } - else if(((epnum & 0x80) == 0x80) && ( MSC_BOT_Status != BOT_STATE_RECOVERY)) - { - MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED); - } - -} -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c b/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c deleted file mode 100644 index cf03ef4de..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c +++ /dev/null @@ -1,490 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_msc_core.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides all the MSC core functions. - * - * @verbatim - * - * =================================================================== - * MSC Class Description - * =================================================================== - * This module manages the MSC class V1.0 following the "Universal - * Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0 - * Sep. 31, 1999". - * This driver implements the following aspects of the specification: - * - Bulk-Only Transport protocol - * - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3)) - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_msc_mem.h" -#include "usbd_msc_core.h" -#include "usbd_msc_bot.h" -#include "usbd_req.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup MSC_CORE - * @brief Mass storage core module - * @{ - */ - -/** @defgroup MSC_CORE_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_CORE_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup MSC_CORE_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_CORE_Private_FunctionPrototypes - * @{ - */ -uint8_t USBD_MSC_Init (void *pdev, - uint8_t cfgidx); - -uint8_t USBD_MSC_DeInit (void *pdev, - uint8_t cfgidx); - -uint8_t USBD_MSC_Setup (void *pdev, - USB_SETUP_REQ *req); - -uint8_t USBD_MSC_DataIn (void *pdev, - uint8_t epnum); - - -uint8_t USBD_MSC_DataOut (void *pdev, - uint8_t epnum); - -uint8_t *USBD_MSC_GetCfgDesc (uint8_t speed, - uint16_t *length); - -#ifdef USB_OTG_HS_CORE -uint8_t *USBD_MSC_GetOtherCfgDesc (uint8_t speed, - uint16_t *length); -#endif - - -uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ]; - - - - -/** - * @} - */ - - -/** @defgroup MSC_CORE_Private_Variables - * @{ - */ - - -USBD_Class_cb_TypeDef USBD_MSC_cb = -{ - USBD_MSC_Init, - USBD_MSC_DeInit, - USBD_MSC_Setup, - NULL, /*EP0_TxSent*/ - NULL, /*EP0_RxReady*/ - USBD_MSC_DataIn, - USBD_MSC_DataOut, - NULL, /*SOF */ - NULL, - NULL, - USBD_MSC_GetCfgDesc, -#ifdef USB_OTG_HS_CORE - USBD_MSC_GetOtherCfgDesc, -#endif -}; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -/* USB Mass storage device Configuration Descriptor */ -/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ -__ALIGN_BEGIN uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - - 0x09, /* bLength: Configuation Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_MSC_CONFIG_DESC_SIZ, - - 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ - - /******************** Mass Storage interface ********************/ - 0x09, /* bLength: Interface Descriptor size */ - 0x04, /* bDescriptorType: */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints*/ - 0x08, /* bInterfaceClass: MSC Class */ - 0x06, /* bInterfaceSubClass : SCSI transparent*/ - 0x50, /* nInterfaceProtocol */ - 0x05, /* iInterface: */ - /******************** Mass Storage Endpoints ********************/ - 0x07, /*Endpoint descriptor length = 7*/ - 0x05, /*Endpoint descriptor type */ - MSC_IN_EP, /*Endpoint address (IN, address 1) */ - 0x02, /*Bulk endpoint type */ - LOBYTE(MSC_MAX_PACKET), - HIBYTE(MSC_MAX_PACKET), - 0x00, /*Polling interval in milliseconds */ - - 0x07, /*Endpoint descriptor length = 7 */ - 0x05, /*Endpoint descriptor type */ - MSC_OUT_EP, /*Endpoint address (OUT, address 1) */ - 0x02, /*Bulk endpoint type */ - LOBYTE(MSC_MAX_PACKET), - HIBYTE(MSC_MAX_PACKET), - 0x00 /*Polling interval in milliseconds*/ -}; -#ifdef USB_OTG_HS_CORE - #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif - #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t USBD_MSC_OtherCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - - 0x09, /* bLength: Configuation Descriptor size */ - USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, - USB_MSC_CONFIG_DESC_SIZ, - - 0x00, - 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ - - /******************** Mass Storage interface ********************/ - 0x09, /* bLength: Interface Descriptor size */ - 0x04, /* bDescriptorType: */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints*/ - 0x08, /* bInterfaceClass: MSC Class */ - 0x06, /* bInterfaceSubClass : SCSI transparent command set*/ - 0x50, /* nInterfaceProtocol */ - 0x05, /* iInterface: */ - /******************** Mass Storage Endpoints ********************/ - 0x07, /*Endpoint descriptor length = 7*/ - 0x05, /*Endpoint descriptor type */ - MSC_IN_EP, /*Endpoint address (IN, address 1) */ - 0x02, /*Bulk endpoint type */ - 0x40, - 0x00, - 0x00, /*Polling interval in milliseconds */ - - 0x07, /*Endpoint descriptor length = 7 */ - 0x05, /*Endpoint descriptor type */ - MSC_OUT_EP, /*Endpoint address (OUT, address 1) */ - 0x02, /*Bulk endpoint type */ - 0x40, - 0x00, - 0x00 /*Polling interval in milliseconds*/ -}; -#endif - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN static uint8_t USBD_MSC_MaxLun __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN static uint8_t USBD_MSC_AltSet __ALIGN_END = 0; - -/** - * @} - */ - - -/** @defgroup MSC_CORE_Private_Functions - * @{ - */ - -/** -* @brief USBD_MSC_Init -* Initialize the mass storage configuration -* @param pdev: device instance -* @param cfgidx: configuration index -* @retval status -*/ -uint8_t USBD_MSC_Init (void *pdev, - uint8_t cfgidx) -{ - USBD_MSC_DeInit(pdev , cfgidx ); - - /* Open EP IN */ - DCD_EP_Open(pdev, - MSC_IN_EP, - MSC_EPIN_SIZE, - USB_OTG_EP_BULK); - - /* Open EP OUT */ - DCD_EP_Open(pdev, - MSC_OUT_EP, - MSC_EPOUT_SIZE, - USB_OTG_EP_BULK); - - /* Init the BOT layer */ - MSC_BOT_Init(pdev); - - return USBD_OK; -} - -/** -* @brief USBD_MSC_DeInit -* DeInitilaize the mass storage configuration -* @param pdev: device instance -* @param cfgidx: configuration index -* @retval status -*/ -uint8_t USBD_MSC_DeInit (void *pdev, - uint8_t cfgidx) -{ - /* Close MSC EPs */ - DCD_EP_Close (pdev , MSC_IN_EP); - DCD_EP_Close (pdev , MSC_OUT_EP); - - /* Un Init the BOT layer */ - MSC_BOT_DeInit(pdev); - return USBD_OK; -} -/** -* @brief USBD_MSC_Setup -* Handle the MSC specific requests -* @param pdev: device instance -* @param req: USB request -* @retval status -*/ -uint8_t USBD_MSC_Setup (void *pdev, USB_SETUP_REQ *req) -{ - - switch (req->bmRequest & USB_REQ_TYPE_MASK) - { - - /* Class request */ - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - case BOT_GET_MAX_LUN : - - if((req->wValue == 0) && - (req->wLength == 1) && - ((req->bmRequest & 0x80) == 0x80)) - { - USBD_MSC_MaxLun = USBD_STORAGE_fops->GetMaxLun(); - if(USBD_MSC_MaxLun > 0) - { - USBD_CtlSendData (pdev, - &USBD_MSC_MaxLun, - 1); - } - else - { - USBD_CtlError(pdev , req); - return USBD_FAIL; - - } - } - else - { - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - break; - - case BOT_RESET : - if((req->wValue == 0) && - (req->wLength == 0) && - ((req->bmRequest & 0x80) != 0x80)) - { - MSC_BOT_Reset(pdev); - } - else - { - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - break; - - default: - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - break; - /* Interface & Endpoint request */ - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_INTERFACE : - USBD_CtlSendData (pdev, - &USBD_MSC_AltSet, - 1); - break; - - case USB_REQ_SET_INTERFACE : - USBD_MSC_AltSet = (uint8_t)(req->wValue); - break; - - case USB_REQ_CLEAR_FEATURE: - - /* Flush the FIFO and Clear the stall status */ - DCD_EP_Flush(pdev, (uint8_t)req->wIndex); - - /* Re-activate the EP */ - DCD_EP_Close (pdev , (uint8_t)req->wIndex); - if((((uint8_t)req->wIndex) & 0x80) == 0x80) - { - DCD_EP_Open(pdev, - ((uint8_t)req->wIndex), - MSC_EPIN_SIZE, - USB_OTG_EP_BULK); - } - else - { - DCD_EP_Open(pdev, - ((uint8_t)req->wIndex), - MSC_EPOUT_SIZE, - USB_OTG_EP_BULK); - } - - /* Handle BOT error */ - MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); - break; - - } - break; - - default: - break; - } - return USBD_OK; -} - -/** -* @brief USBD_MSC_DataIn -* handle data IN Stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval status -*/ -uint8_t USBD_MSC_DataIn (void *pdev, - uint8_t epnum) -{ - MSC_BOT_DataIn(pdev , epnum); - return USBD_OK; -} - -/** -* @brief USBD_MSC_DataOut -* handle data OUT Stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval status -*/ -uint8_t USBD_MSC_DataOut (void *pdev, - uint8_t epnum) -{ - MSC_BOT_DataOut(pdev , epnum); - return USBD_OK; -} - -/** -* @brief USBD_MSC_GetCfgDesc -* return configuration descriptor -* @param speed : current device speed -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ -uint8_t *USBD_MSC_GetCfgDesc (uint8_t speed, uint16_t *length) -{ - *length = sizeof (USBD_MSC_CfgDesc); - return USBD_MSC_CfgDesc; -} - -/** -* @brief USBD_MSC_GetOtherCfgDesc -* return other speed configuration descriptor -* @param speed : current device speed -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ -#ifdef USB_OTG_HS_CORE -uint8_t *USBD_MSC_GetOtherCfgDesc (uint8_t speed, - uint16_t *length) -{ - *length = sizeof (USBD_MSC_OtherCfgDesc); - return USBD_MSC_OtherCfgDesc; -} -#endif -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c b/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c deleted file mode 100644 index b5b0f2db5..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c +++ /dev/null @@ -1,128 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_msc_data.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides all the vital inquiry pages and sense data. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_msc_data.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup MSC_DATA - * @brief Mass storage info/data module - * @{ - */ - -/** @defgroup MSC_DATA_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_DATA_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_DATA_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_DATA_Private_Variables - * @{ - */ - - -/* USB Mass storage Page 0 Inquiry Data */ -const uint8_t MSC_Page00_Inquiry_Data[] = {//7 - 0x00, - 0x00, - 0x00, - (LENGTH_INQUIRY_PAGE00 - 4), - 0x00, - 0x80, - 0x83 -}; -/* USB Mass storage sense 6 Data */ -const uint8_t MSC_Mode_Sense6_data[] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; -/* USB Mass storage sense 10 Data */ -const uint8_t MSC_Mode_Sense10_data[] = { - 0x00, - 0x06, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; -/** - * @} - */ - - -/** @defgroup MSC_DATA_Private_FunctionPrototypes - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_DATA_Private_Functions - * @{ - */ - -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c b/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c deleted file mode 100644 index 8cff583bd..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c +++ /dev/null @@ -1,722 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_msc_scsi.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides all the USBD SCSI layer functions. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_msc_bot.h" -#include "usbd_msc_scsi.h" -#include "usbd_msc_mem.h" -#include "usbd_msc_data.h" - - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup MSC_SCSI - * @brief Mass storage SCSI layer module - * @{ - */ - -/** @defgroup MSC_SCSI_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_SCSI_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup MSC_SCSI_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup MSC_SCSI_Private_Variables - * @{ - */ - -SCSI_Sense_TypeDef SCSI_Sense [SENSE_LIST_DEEPTH]; -uint8_t SCSI_Sense_Head; -uint8_t SCSI_Sense_Tail; - -uint32_t SCSI_blk_size; -uint32_t SCSI_blk_nbr; - -uint32_t SCSI_blk_addr; -uint32_t SCSI_blk_len; - -USB_OTG_CORE_HANDLE *cdev; -/** - * @} - */ - - -/** @defgroup MSC_SCSI_Private_FunctionPrototypes - * @{ - */ -static int8_t SCSI_TestUnitReady(uint8_t lun, uint8_t *params); -static int8_t SCSI_Inquiry(uint8_t lun, uint8_t *params); -static int8_t SCSI_ReadFormatCapacity(uint8_t lun, uint8_t *params); -static int8_t SCSI_ReadCapacity10(uint8_t lun, uint8_t *params); -static int8_t SCSI_RequestSense (uint8_t lun, uint8_t *params); -static int8_t SCSI_StartStopUnit(uint8_t lun, uint8_t *params); -static int8_t SCSI_ModeSense6 (uint8_t lun, uint8_t *params); -static int8_t SCSI_ModeSense10 (uint8_t lun, uint8_t *params); -static int8_t SCSI_Write10(uint8_t lun , uint8_t *params); -static int8_t SCSI_Read10(uint8_t lun , uint8_t *params); -static int8_t SCSI_Verify10(uint8_t lun, uint8_t *params); -static int8_t SCSI_CheckAddressRange (uint8_t lun , - uint32_t blk_offset , - uint16_t blk_nbr); -static int8_t SCSI_ProcessRead (uint8_t lun); - -static int8_t SCSI_ProcessWrite (uint8_t lun); -/** - * @} - */ - - -/** @defgroup MSC_SCSI_Private_Functions - * @{ - */ - - -/** -* @brief SCSI_ProcessCmd -* Process SCSI commands -* @param pdev: device instance -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -int8_t SCSI_ProcessCmd(USB_OTG_CORE_HANDLE *pdev, - uint8_t lun, - uint8_t *params) -{ - cdev = pdev; - - switch (params[0]) - { - case SCSI_TEST_UNIT_READY: - return SCSI_TestUnitReady(lun, params); - - case SCSI_REQUEST_SENSE: - return SCSI_RequestSense (lun, params); - case SCSI_INQUIRY: - return SCSI_Inquiry(lun, params); - - case SCSI_START_STOP_UNIT: - return SCSI_StartStopUnit(lun, params); - - case SCSI_ALLOW_MEDIUM_REMOVAL: - return SCSI_StartStopUnit(lun, params); - - case SCSI_MODE_SENSE6: - return SCSI_ModeSense6 (lun, params); - - case SCSI_MODE_SENSE10: - return SCSI_ModeSense10 (lun, params); - - case SCSI_READ_FORMAT_CAPACITIES: - return SCSI_ReadFormatCapacity(lun, params); - - case SCSI_READ_CAPACITY10: - return SCSI_ReadCapacity10(lun, params); - - case SCSI_READ10: - return SCSI_Read10(lun, params); - - case SCSI_WRITE10: - return SCSI_Write10(lun, params); - - case SCSI_VERIFY10: - return SCSI_Verify10(lun, params); - - default: - SCSI_SenseCode(lun, - ILLEGAL_REQUEST, - INVALID_CDB); - return -1; - } -} - - -/** -* @brief SCSI_TestUnitReady -* Process SCSI Test Unit Ready Command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_TestUnitReady(uint8_t lun, uint8_t *params) -{ - - /* case 9 : Hi > D0 */ - if (MSC_BOT_cbw.dDataLength != 0) - { - SCSI_SenseCode(MSC_BOT_cbw.bLUN, - ILLEGAL_REQUEST, - INVALID_CDB); - return -1; - } - - if(USBD_STORAGE_fops->IsReady(lun) !=0 ) - { - SCSI_SenseCode(lun, - NOT_READY, - MEDIUM_NOT_PRESENT); - return -1; - } - MSC_BOT_DataLen = 0; - return 0; -} - -/** -* @brief SCSI_Inquiry -* Process Inquiry command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_Inquiry(uint8_t lun, uint8_t *params) -{ - uint8_t* pPage; - uint16_t len; - - if (params[1] & 0x01)/*Evpd is set*/ - { - pPage = (uint8_t *)MSC_Page00_Inquiry_Data; - len = LENGTH_INQUIRY_PAGE00; - } - else - { - - pPage = (uint8_t *)&USBD_STORAGE_fops->pInquiry[lun * USBD_STD_INQUIRY_LENGTH]; - len = pPage[4] + 5; - - if (params[4] <= len) - { - len = params[4]; - } - } - MSC_BOT_DataLen = len; - - while (len) - { - len--; - MSC_BOT_Data[len] = pPage[len]; - } - return 0; -} - -/** -* @brief SCSI_ReadCapacity10 -* Process Read Capacity 10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_ReadCapacity10(uint8_t lun, uint8_t *params) -{ - - if(USBD_STORAGE_fops->GetCapacity(lun, &SCSI_blk_nbr, &SCSI_blk_size) != 0) - { - SCSI_SenseCode(lun, - NOT_READY, - MEDIUM_NOT_PRESENT); - return -1; - } - else - { - - MSC_BOT_Data[0] = (uint8_t)(SCSI_blk_nbr - 1 >> 24); - MSC_BOT_Data[1] = (uint8_t)(SCSI_blk_nbr - 1 >> 16); - MSC_BOT_Data[2] = (uint8_t)(SCSI_blk_nbr - 1 >> 8); - MSC_BOT_Data[3] = (uint8_t)(SCSI_blk_nbr - 1); - - MSC_BOT_Data[4] = (uint8_t)(SCSI_blk_size >> 24); - MSC_BOT_Data[5] = (uint8_t)(SCSI_blk_size >> 16); - MSC_BOT_Data[6] = (uint8_t)(SCSI_blk_size >> 8); - MSC_BOT_Data[7] = (uint8_t)(SCSI_blk_size); - - MSC_BOT_DataLen = 8; - return 0; - } -} -/** -* @brief SCSI_ReadFormatCapacity -* Process Read Format Capacity command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_ReadFormatCapacity(uint8_t lun, uint8_t *params) -{ - - uint32_t blk_size; - uint32_t blk_nbr; - uint16_t i; - - for(i=0 ; i < 12 ; i++) - { - MSC_BOT_Data[i] = 0; - } - - if(USBD_STORAGE_fops->GetCapacity(lun, &blk_nbr, &blk_size) != 0) - { - SCSI_SenseCode(lun, - NOT_READY, - MEDIUM_NOT_PRESENT); - return -1; - } - else - { - MSC_BOT_Data[3] = 0x08; - MSC_BOT_Data[4] = (uint8_t)(blk_nbr - 1 >> 24); - MSC_BOT_Data[5] = (uint8_t)(blk_nbr - 1 >> 16); - MSC_BOT_Data[6] = (uint8_t)(blk_nbr - 1 >> 8); - MSC_BOT_Data[7] = (uint8_t)(blk_nbr - 1); - - MSC_BOT_Data[8] = 0x02; - MSC_BOT_Data[9] = (uint8_t)(blk_size >> 16); - MSC_BOT_Data[10] = (uint8_t)(blk_size >> 8); - MSC_BOT_Data[11] = (uint8_t)(blk_size); - - MSC_BOT_DataLen = 12; - return 0; - } -} -/** -* @brief SCSI_ModeSense6 -* Process Mode Sense6 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_ModeSense6 (uint8_t lun, uint8_t *params) -{ - - uint16_t len = 8 ; - MSC_BOT_DataLen = len; - - while (len) - { - len--; - MSC_BOT_Data[len] = MSC_Mode_Sense6_data[len]; - } - return 0; -} - -/** -* @brief SCSI_ModeSense10 -* Process Mode Sense10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_ModeSense10 (uint8_t lun, uint8_t *params) -{ - uint16_t len = 8; - - MSC_BOT_DataLen = len; - - while (len) - { - len--; - MSC_BOT_Data[len] = MSC_Mode_Sense10_data[len]; - } - return 0; -} - -/** -* @brief SCSI_RequestSense -* Process Request Sense command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ - -static int8_t SCSI_RequestSense (uint8_t lun, uint8_t *params) -{ - uint8_t i; - - for(i=0 ; i < REQUEST_SENSE_DATA_LEN ; i++) - { - MSC_BOT_Data[i] = 0; - } - - MSC_BOT_Data[0] = 0x70; - MSC_BOT_Data[7] = REQUEST_SENSE_DATA_LEN - 6; - - if((SCSI_Sense_Head != SCSI_Sense_Tail)) { - - MSC_BOT_Data[2] = SCSI_Sense[SCSI_Sense_Head].Skey; - MSC_BOT_Data[12] = SCSI_Sense[SCSI_Sense_Head].w.b.ASCQ; - MSC_BOT_Data[13] = SCSI_Sense[SCSI_Sense_Head].w.b.ASC; - SCSI_Sense_Head++; - - if (SCSI_Sense_Head == SENSE_LIST_DEEPTH) - { - SCSI_Sense_Head = 0; - } - } - MSC_BOT_DataLen = REQUEST_SENSE_DATA_LEN; - - if (params[4] <= REQUEST_SENSE_DATA_LEN) - { - MSC_BOT_DataLen = params[4]; - } - return 0; -} - -/** -* @brief SCSI_SenseCode -* Load the last error code in the error list -* @param lun: Logical unit number -* @param sKey: Sense Key -* @param ASC: Additional Sense Key -* @retval none - -*/ -void SCSI_SenseCode(uint8_t lun, uint8_t sKey, uint8_t ASC) -{ - SCSI_Sense[SCSI_Sense_Tail].Skey = sKey; - SCSI_Sense[SCSI_Sense_Tail].w.ASC = ASC << 8; - SCSI_Sense_Tail++; - if (SCSI_Sense_Tail == SENSE_LIST_DEEPTH) - { - SCSI_Sense_Tail = 0; - } -} -/** -* @brief SCSI_StartStopUnit -* Process Start Stop Unit command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_StartStopUnit(uint8_t lun, uint8_t *params) -{ - MSC_BOT_DataLen = 0; - return 0; -} - -/** -* @brief SCSI_Read10 -* Process Read10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ -static int8_t SCSI_Read10(uint8_t lun , uint8_t *params) -{ - if(MSC_BOT_State == BOT_IDLE) /* Idle */ - { - - /* case 10 : Ho <> Di */ - - if ((MSC_BOT_cbw.bmFlags & 0x80) != 0x80) - { - SCSI_SenseCode(MSC_BOT_cbw.bLUN, - ILLEGAL_REQUEST, - INVALID_CDB); - return -1; - } - - if(USBD_STORAGE_fops->IsReady(lun) !=0 ) - { - SCSI_SenseCode(lun, - NOT_READY, - MEDIUM_NOT_PRESENT); - return -1; - } - - SCSI_blk_addr = (params[2] << 24) | \ - (params[3] << 16) | \ - (params[4] << 8) | \ - params[5]; - - SCSI_blk_len = (params[7] << 8) | \ - params[8]; - - - - if( SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0) - { - return -1; /* error */ - } - - MSC_BOT_State = BOT_DATA_IN; - SCSI_blk_addr *= SCSI_blk_size; - SCSI_blk_len *= SCSI_blk_size; - - /* cases 4,5 : Hi <> Dn */ - if (MSC_BOT_cbw.dDataLength != SCSI_blk_len) - { - SCSI_SenseCode(MSC_BOT_cbw.bLUN, - ILLEGAL_REQUEST, - INVALID_CDB); - return -1; - } - } - MSC_BOT_DataLen = MSC_MEDIA_PACKET; - - return SCSI_ProcessRead(lun); -} - -/** -* @brief SCSI_Write10 -* Process Write10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ - -static int8_t SCSI_Write10 (uint8_t lun , uint8_t *params) -{ - if (MSC_BOT_State == BOT_IDLE) /* Idle */ - { - - /* case 8 : Hi <> Do */ - - if ((MSC_BOT_cbw.bmFlags & 0x80) == 0x80) - { - SCSI_SenseCode(MSC_BOT_cbw.bLUN, - ILLEGAL_REQUEST, - INVALID_CDB); - return -1; - } - - /* Check whether Media is ready */ - if(USBD_STORAGE_fops->IsReady(lun) !=0 ) - { - SCSI_SenseCode(lun, - NOT_READY, - MEDIUM_NOT_PRESENT); - return -1; - } - - /* Check If media is write-protected */ - if(USBD_STORAGE_fops->IsWriteProtected(lun) !=0 ) - { - SCSI_SenseCode(lun, - NOT_READY, - WRITE_PROTECTED); - return -1; - } - - - SCSI_blk_addr = (params[2] << 24) | \ - (params[3] << 16) | \ - (params[4] << 8) | \ - params[5]; - SCSI_blk_len = (params[7] << 8) | \ - params[8]; - - /* check if LBA address is in the right range */ - if(SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0) - { - return -1; /* error */ - } - - SCSI_blk_addr *= SCSI_blk_size; - SCSI_blk_len *= SCSI_blk_size; - - /* cases 3,11,13 : Hn,Ho <> D0 */ - if (MSC_BOT_cbw.dDataLength != SCSI_blk_len) - { - SCSI_SenseCode(MSC_BOT_cbw.bLUN, - ILLEGAL_REQUEST, - INVALID_CDB); - return -1; - } - - /* Prepare EP to receive first data packet */ - MSC_BOT_State = BOT_DATA_OUT; - DCD_EP_PrepareRx (cdev, - MSC_OUT_EP, - MSC_BOT_Data, - MIN (SCSI_blk_len, MSC_MEDIA_PACKET)); - } - else /* Write Process ongoing */ - { - return SCSI_ProcessWrite(lun); - } - return 0; -} - - -/** -* @brief SCSI_Verify10 -* Process Verify10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ - -static int8_t SCSI_Verify10(uint8_t lun , uint8_t *params){ - if ((params[1]& 0x02) == 0x02) - { - SCSI_SenseCode (lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND); - return -1; /* Error, Verify Mode Not supported*/ - } - - if(SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0) - { - return -1; /* error */ - } - MSC_BOT_DataLen = 0; - return 0; -} - -/** -* @brief SCSI_CheckAddressRange -* Check address range -* @param lun: Logical unit number -* @param blk_offset: first block address -* @param blk_nbr: number of block to be processed -* @retval status -*/ -static int8_t SCSI_CheckAddressRange (uint8_t lun , uint32_t blk_offset , uint16_t blk_nbr) -{ - - if ((blk_offset + blk_nbr) > SCSI_blk_nbr ) - { - SCSI_SenseCode(lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE); - return -1; - } - return 0; -} - -/** -* @brief SCSI_ProcessRead -* Handle Read Process -* @param lun: Logical unit number -* @retval status -*/ -static int8_t SCSI_ProcessRead (uint8_t lun) -{ - uint32_t len; - - len = MIN(SCSI_blk_len , MSC_MEDIA_PACKET); - - if( USBD_STORAGE_fops->Read(lun , - MSC_BOT_Data, - SCSI_blk_addr / SCSI_blk_size, - len / SCSI_blk_size) < 0) - { - - SCSI_SenseCode(lun, HARDWARE_ERROR, UNRECOVERED_READ_ERROR); - return -1; - } - - - DCD_EP_Tx (cdev, - MSC_IN_EP, - MSC_BOT_Data, - len); - - - SCSI_blk_addr += len; - SCSI_blk_len -= len; - - /* case 6 : Hi = Di */ - MSC_BOT_csw.dDataResidue -= len; - - if (SCSI_blk_len == 0) - { - MSC_BOT_State = BOT_LAST_DATA_IN; - } - return 0; -} - -/** -* @brief SCSI_ProcessWrite -* Handle Write Process -* @param lun: Logical unit number -* @retval status -*/ - -static int8_t SCSI_ProcessWrite (uint8_t lun) -{ - uint32_t len; - - len = MIN(SCSI_blk_len , MSC_MEDIA_PACKET); - - if(USBD_STORAGE_fops->Write(lun , - MSC_BOT_Data, - SCSI_blk_addr / SCSI_blk_size, - len / SCSI_blk_size) < 0) - { - SCSI_SenseCode(lun, HARDWARE_ERROR, WRITE_FAULT); - return -1; - } - - - SCSI_blk_addr += len; - SCSI_blk_len -= len; - - /* case 12 : Ho = Do */ - MSC_BOT_csw.dDataResidue -= len; - - if (SCSI_blk_len == 0) - { - MSC_BOT_SendCSW (cdev, CSW_CMD_PASSED); - } - else - { - /* Prapare EP to Receive next packet */ - DCD_EP_PrepareRx (cdev, - MSC_OUT_EP, - MSC_BOT_Data, - MIN (SCSI_blk_len, MSC_MEDIA_PACKET)); - } - - return 0; -} -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c b/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c deleted file mode 100644 index 927e9dd45..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c +++ /dev/null @@ -1,179 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_storage_template.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Memory management layer - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_msc_mem.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Extern function prototypes ------------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -#define STORAGE_LUN_NBR 1 - -int8_t STORAGE_Init (uint8_t lun); - -int8_t STORAGE_GetCapacity (uint8_t lun, - uint32_t *block_num, - uint16_t *block_size); - -int8_t STORAGE_IsReady (uint8_t lun); - -int8_t STORAGE_IsWriteProtected (uint8_t lun); - -int8_t STORAGE_Read (uint8_t lun, - uint8_t *buf, - uint32_t blk_addr, - uint16_t blk_len); - -int8_t STORAGE_Write (uint8_t lun, - uint8_t *buf, - uint32_t blk_addr, - uint16_t blk_len); - -int8_t STORAGE_GetMaxLun (void); - -/* USB Mass storage Standard Inquiry Data */ -const int8_t STORAGE_Inquirydata[] = {//36 - - /* LUN 0 */ - 0x00, - 0x80, - 0x02, - 0x02, - (USBD_STD_INQUIRY_LENGTH - 5), - 0x00, - 0x00, - 0x00, - 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */ - 'P', 'r', 'o', 'd', 'u', 't', ' ', ' ', /* Product : 16 Bytes */ - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - '0', '.', '0' ,'1', /* Version : 4 Bytes */ -}; - -USBD_STORAGE_cb_TypeDef USBD_MICRO_SDIO_fops = -{ - STORAGE_Init, - STORAGE_GetCapacity, - STORAGE_IsReady, - STORAGE_IsWriteProtected, - STORAGE_Read, - STORAGE_Write, - STORAGE_GetMaxLun, - STORAGE_Inquirydata, - -}; - -USBD_STORAGE_cb_TypeDef *USBD_STORAGE_fops = &USBD_MICRO_SDIO_fops; -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the microSD card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_Init (uint8_t lun) -{ - return (0); -} - -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint16_t *block_size) -{ - return (0); -} - -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_IsReady (uint8_t lun) -{ - return (0); -} - -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_IsWriteProtected (uint8_t lun) -{ - return 0; -} - -/******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_Read (uint8_t lun, - uint8_t *buf, - uint32_t blk_addr, - uint16_t blk_len) -{ - return 0; -} -/******************************************************************************* -* Function Name : Write_Memory -* Description : Handle the Write operation to the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_Write (uint8_t lun, - uint8_t *buf, - uint32_t blk_addr, - uint16_t blk_len) -{ - return (0); -} -/******************************************************************************* -* Function Name : Write_Memory -* Description : Handle the Write operation to the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ -int8_t STORAGE_GetMaxLun (void) -{ - return (STORAGE_LUN_NBR - 1); -} - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h b/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h deleted file mode 100644 index 34cd39d11..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_conf_template.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief usb device configuration template file - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CONF__H__ -#define __USBD_CONF__H__ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f2xx.h" - - - -/** @defgroup USB_CONF_Exported_Defines - * @{ - */ -#define USE_USB_OTG_HS - -#define USBD_CFG_MAX_NUM 1 -#define USB_MAX_STR_DESC_SIZ 64 -#define USBD_EP0_MAX_PACKET_SIZE 64 - -/** - * @} - */ - - -/** @defgroup USB_CONF_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_CONF_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -#endif //__USBD_CONF__H__ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_core.h b/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_core.h deleted file mode 100644 index fb20acf63..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_core.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_core.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Header file for usbd_core.c - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_CORE_H -#define __USBD_CORE_H - -/* Includes ------------------------------------------------------------------*/ -#include "usb_dcd.h" -#include "usbd_def.h" -#include "usbd_conf.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_CORE - * @brief This file is the Header file for usbd_core.c file - * @{ - */ - - -/** @defgroup USBD_CORE_Exported_Defines - * @{ - */ - -typedef enum { - USBD_OK = 0, - USBD_BUSY, - USBD_FAIL, -}USBD_Status; -/** - * @} - */ - - -/** @defgroup USBD_CORE_Exported_TypesDefinitions - * @{ - */ - - -/** - * @} - */ - - - -/** @defgroup USBD_CORE_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_CORE_Exported_FunctionsPrototype - * @{ - */ -void USBD_Init(USB_OTG_CORE_HANDLE *pdev, - USB_OTG_CORE_ID_TypeDef coreID, - USBD_DEVICE *pDevice, - USBD_Class_cb_TypeDef *class_cb, - USBD_Usr_cb_TypeDef *usr_cb); - -USBD_Status USBD_DeInit(USB_OTG_CORE_HANDLE *pdev); - -USBD_Status USBD_ClrCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx); - -USBD_Status USBD_SetCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx); - -/** - * @} - */ - -#endif /* __USBD_CORE_H */ - -/** - * @} - */ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - - diff --git a/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_def.h b/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_def.h deleted file mode 100644 index a8c86710d..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_def.h +++ /dev/null @@ -1,149 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_def.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief general defines for the usb device library - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef __USBD_DEF_H -#define __USBD_DEF_H -/* Includes ------------------------------------------------------------------*/ -#include "usbd_conf.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USB_DEF - * @brief general defines for the usb device library file - * @{ - */ - -/** @defgroup USB_DEF_Exported_Defines - * @{ - */ - -#ifndef NULL -#define NULL 0 -#endif - -#define USB_LEN_DEV_QUALIFIER_DESC 0x0A -#define USB_LEN_DEV_DESC 0x12 -#define USB_LEN_CFG_DESC 0x09 -#define USB_LEN_IF_DESC 0x09 -#define USB_LEN_EP_DESC 0x07 -#define USB_LEN_OTG_DESC 0x03 - -#define USBD_IDX_LANGID_STR 0x00 -#define USBD_IDX_MFC_STR 0x01 -#define USBD_IDX_PRODUCT_STR 0x02 -#define USBD_IDX_SERIAL_STR 0x03 -#define USBD_IDX_CONFIG_STR 0x04 -#define USBD_IDX_INTERFACE_STR 0x05 - -#define USB_REQ_TYPE_STANDARD 0x00 -#define USB_REQ_TYPE_CLASS 0x20 -#define USB_REQ_TYPE_VENDOR 0x40 -#define USB_REQ_TYPE_MASK 0x60 - -#define USB_REQ_RECIPIENT_DEVICE 0x00 -#define USB_REQ_RECIPIENT_INTERFACE 0x01 -#define USB_REQ_RECIPIENT_ENDPOINT 0x02 -#define USB_REQ_RECIPIENT_MASK 0x03 - -#define USB_REQ_GET_STATUS 0x00 -#define USB_REQ_CLEAR_FEATURE 0x01 -#define USB_REQ_SET_FEATURE 0x03 -#define USB_REQ_SET_ADDRESS 0x05 -#define USB_REQ_GET_DESCRIPTOR 0x06 -#define USB_REQ_SET_DESCRIPTOR 0x07 -#define USB_REQ_GET_CONFIGURATION 0x08 -#define USB_REQ_SET_CONFIGURATION 0x09 -#define USB_REQ_GET_INTERFACE 0x0A -#define USB_REQ_SET_INTERFACE 0x0B -#define USB_REQ_SYNCH_FRAME 0x0C - -#define USB_DESC_TYPE_DEVICE 1 -#define USB_DESC_TYPE_CONFIGURATION 2 -#define USB_DESC_TYPE_STRING 3 -#define USB_DESC_TYPE_INTERFACE 4 -#define USB_DESC_TYPE_ENDPOINT 5 -#define USB_DESC_TYPE_DEVICE_QUALIFIER 6 -#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7 - - -#define USB_CONFIG_REMOTE_WAKEUP 2 -#define USB_CONFIG_SELF_POWERED 1 - -#define USB_FEATURE_EP_HALT 0 -#define USB_FEATURE_REMOTE_WAKEUP 1 -#define USB_FEATURE_TEST_MODE 2 - -/** - * @} - */ - - -/** @defgroup USBD_DEF_Exported_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USBD_DEF_Exported_Macros - * @{ - */ -#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ - (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8)) - -#define LOBYTE(x) ((uint8_t)(x & 0x00FF)) -#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8)) -/** - * @} - */ - -/** @defgroup USBD_DEF_Exported_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_DEF_Exported_FunctionsPrototype - * @{ - */ - -/** - * @} - */ - -#endif /* __USBD_DEF_H */ - -/** - * @} - */ - -/** -* @} -*/ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h b/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h deleted file mode 100644 index ca755f2bb..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h +++ /dev/null @@ -1,115 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_ioreq.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header file for the usbd_ioreq.c file - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef __USBD_IOREQ_H_ -#define __USBD_IOREQ_H_ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" -#include "usbd_core.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_IOREQ - * @brief header file for the usbd_ioreq.c file - * @{ - */ - -/** @defgroup USBD_IOREQ_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Exported_Types - * @{ - */ - - -/** - * @} - */ - - - -/** @defgroup USBD_IOREQ_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_IOREQ_Exported_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype - * @{ - */ - -USBD_Status USBD_CtlSendData (USB_OTG_CORE_HANDLE *pdev, - uint8_t *buf, - uint16_t len); - -USBD_Status USBD_CtlContinueSendData (USB_OTG_CORE_HANDLE *pdev, - uint8_t *pbuf, - uint16_t len); - -USBD_Status USBD_CtlPrepareRx (USB_OTG_CORE_HANDLE *pdev, - uint8_t *pbuf, - uint16_t len); - -USBD_Status USBD_CtlContinueRx (USB_OTG_CORE_HANDLE *pdev, - uint8_t *pbuf, - uint16_t len); - -USBD_Status USBD_CtlSendStatus (USB_OTG_CORE_HANDLE *pdev); - -USBD_Status USBD_CtlReceiveStatus (USB_OTG_CORE_HANDLE *pdev); - -uint16_t USBD_GetRxCount (USB_OTG_CORE_HANDLE *pdev , - uint8_t epnum); - -/** - * @} - */ - -#endif /* __USBD_IOREQ_H_ */ - -/** - * @} - */ - -/** -* @} -*/ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_req.h b/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_req.h deleted file mode 100644 index 9aa9e44a3..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_req.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_req.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief header file for the usbd_req.c file - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ - -#ifndef __USB_REQUEST_H_ -#define __USB_REQUEST_H_ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_def.h" -#include "usbd_core.h" -#include "usbd_conf.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - -/** @defgroup USBD_REQ - * @brief header file for the usbd_ioreq.c file - * @{ - */ - -/** @defgroup USBD_REQ_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_REQ_Exported_Types - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USBD_REQ_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_REQ_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_REQ_Exported_FunctionsPrototype - * @{ - */ - -USBD_Status USBD_StdDevReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req); -USBD_Status USBD_StdItfReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req); -USBD_Status USBD_StdEPReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req); -void USBD_ParseSetupRequest( USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -void USBD_CtlError( USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len); -/** - * @} - */ - -#endif /* __USB_REQUEST_H_ */ - -/** - * @} - */ - -/** -* @} -*/ - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_usr.h b/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_usr.h deleted file mode 100644 index 44e7b1dd2..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Core/inc/usbd_usr.h +++ /dev/null @@ -1,135 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_usr.h - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief Header file for usbd_usr.c - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBD_USR_H__ -#define __USBD_USR_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_core.h" - - -/** @addtogroup USBD_USER - * @{ - */ - -/** @addtogroup USBD_MSC_DEMO_USER_CALLBACKS - * @{ - */ - -/** @defgroup USBD_USR - * @brief This file is the Header file for usbd_usr.c - * @{ - */ - - -/** @defgroup USBD_USR_Exported_Types - * @{ - */ - -extern USBD_Usr_cb_TypeDef USR_cb; -extern USBD_Usr_cb_TypeDef USR_FS_cb; -extern USBD_Usr_cb_TypeDef USR_HS_cb; - - - -/** - * @} - */ - - - -/** @defgroup USBD_USR_Exported_Defines - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBD_USR_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBD_USR_Exported_Variables - * @{ - */ - -void USBD_USR_Init(void); -void USBD_USR_DeviceReset (uint8_t speed); -void USBD_USR_DeviceConfigured (void); -void USBD_USR_DeviceSuspended(void); -void USBD_USR_DeviceResumed(void); - -void USBD_USR_DeviceConnected(void); -void USBD_USR_DeviceDisconnected(void); - -void USBD_USR_FS_Init(void); -void USBD_USR_FS_DeviceReset (uint8_t speed); -void USBD_USR_FS_DeviceConfigured (void); -void USBD_USR_FS_DeviceSuspended(void); -void USBD_USR_FS_DeviceResumed(void); - -void USBD_USR_FS_DeviceConnected(void); -void USBD_USR_FS_DeviceDisconnected(void); - -void USBD_USR_HS_Init(void); -void USBD_USR_HS_DeviceReset (uint8_t speed); -void USBD_USR_HS_DeviceConfigured (void); -void USBD_USR_HS_DeviceSuspended(void); -void USBD_USR_HS_DeviceResumed(void); - -void USBD_USR_HS_DeviceConnected(void); -void USBD_USR_HS_DeviceDisconnected(void); - -/** - * @} - */ - -/** @defgroup USBD_USR_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - -#endif /*__USBD_USR_H__*/ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - - - diff --git a/example/stm32f4/STM32_USB_Device_Library/Core/src/usbd_core.c b/example/stm32f4/STM32_USB_Device_Library/Core/src/usbd_core.c deleted file mode 100644 index 2a51d3aef..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Core/src/usbd_core.c +++ /dev/null @@ -1,476 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_core.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides all the USBD core functions. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_core.h" -#include "usbd_req.h" -#include "usbd_ioreq.h" -#include "usb_dcd_int.h" -#include "usb_bsp.h" - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY -* @{ -*/ - - -/** @defgroup USBD_CORE -* @brief usbd core module -* @{ -*/ - -/** @defgroup USBD_CORE_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBD_CORE_Private_Defines -* @{ -*/ - -/** -* @} -*/ - - -/** @defgroup USBD_CORE_Private_Macros -* @{ -*/ -/** -* @} -*/ - - - - -/** @defgroup USBD_CORE_Private_FunctionPrototypes -* @{ -*/ -static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev); -static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); -static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); -static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev); -static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE *pdev); -static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE *pdev); -static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE *pdev); -#ifdef VBUS_SENSING_ENABLED -static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev); -static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE *pdev); -#endif -static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE *pdev); -static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE *pdev); -/** -* @} -*/ - -/** @defgroup USBD_CORE_Private_Variables -* @{ -*/ - - - -USBD_DCD_INT_cb_TypeDef USBD_DCD_INT_cb = -{ - USBD_DataOutStage, - USBD_DataInStage, - USBD_SetupStage, - USBD_SOF, - USBD_Reset, - USBD_Suspend, - USBD_Resume, - USBD_IsoINIncomplete, - USBD_IsoOUTIncomplete, -#ifdef VBUS_SENSING_ENABLED -USBD_DevConnected, -USBD_DevDisconnected, -#endif -}; - -USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops = &USBD_DCD_INT_cb; -/** -* @} -*/ - -/** @defgroup USBD_CORE_Private_Functions -* @{ -*/ - -/** -* @brief USBD_Init -* Initailizes the device stack and load the class driver -* @param pdev: device instance -* @param core_address: USB OTG core ID -* @param class_cb: Class callback structure address -* @param usr_cb: User callback structure address -* @retval None -*/ -void USBD_Init(USB_OTG_CORE_HANDLE *pdev, - USB_OTG_CORE_ID_TypeDef coreID, - USBD_DEVICE *pDevice, - USBD_Class_cb_TypeDef *class_cb, - USBD_Usr_cb_TypeDef *usr_cb) -{ - /* Hardware Init */ - USB_OTG_BSP_Init(pdev); - - USBD_DeInit(pdev); - - /*Register class and user callbacks */ - pdev->dev.class_cb = class_cb; - pdev->dev.usr_cb = usr_cb; - pdev->dev.usr_device = pDevice; - - /* set USB OTG core params */ - DCD_Init(pdev , coreID); - - /* Upon Init call usr callback */ - pdev->dev.usr_cb->Init(); - - /* Enable Interrupts */ - USB_OTG_BSP_EnableInterrupt(pdev); -} - -/** -* @brief USBD_DeInit -* Re-Initialize th deviuce library -* @param pdev: device instance -* @retval status: status -*/ -USBD_Status USBD_DeInit(USB_OTG_CORE_HANDLE *pdev) -{ - /* Software Init */ - - return USBD_OK; -} - -/** -* @brief USBD_SetupStage -* Handle the setup stage -* @param pdev: device instance -* @retval status -*/ -static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev) -{ - USB_SETUP_REQ req; - - USBD_ParseSetupRequest(pdev , &req); - - switch (req.bmRequest & 0x1F) - { - case USB_REQ_RECIPIENT_DEVICE: - USBD_StdDevReq (pdev, &req); - break; - - case USB_REQ_RECIPIENT_INTERFACE: - USBD_StdItfReq(pdev, &req); - break; - - case USB_REQ_RECIPIENT_ENDPOINT: - USBD_StdEPReq(pdev, &req); - break; - - default: - DCD_EP_Stall(pdev , req.bmRequest & 0x80); - break; - } - return USBD_OK; -} - -/** -* @brief USBD_DataOutStage -* Handle data out stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval status -*/ -static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) -{ - USB_OTG_EP *ep; - - if(epnum == 0) - { - ep = &pdev->dev.out_ep[0]; - if ( pdev->dev.device_state == USB_OTG_EP0_DATA_OUT) - { - if(ep->rem_data_len > ep->maxpacket) - { - ep->rem_data_len -= ep->maxpacket; - - if(pdev->cfg.dma_enable == 1) - { - /* in slave mode this, is handled by the RxSTSQLvl ISR */ - ep->xfer_buff += ep->maxpacket; - } - USBD_CtlContinueRx (pdev, - ep->xfer_buff, - MIN(ep->rem_data_len ,ep->maxpacket)); - } - else - { - if((pdev->dev.class_cb->EP0_RxReady != NULL)&& - (pdev->dev.device_status == USB_OTG_CONFIGURED)) - { - pdev->dev.class_cb->EP0_RxReady(pdev); - } - USBD_CtlSendStatus(pdev); - } - } - } - else if((pdev->dev.class_cb->DataOut != NULL)&& - (pdev->dev.device_status == USB_OTG_CONFIGURED)) - { - pdev->dev.class_cb->DataOut(pdev, epnum); - } - return USBD_OK; -} - -/** -* @brief USBD_DataInStage -* Handle data in stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval status -*/ -static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) -{ - USB_OTG_EP *ep; - - if(epnum == 0) - { - ep = &pdev->dev.in_ep[0]; - if ( pdev->dev.device_state == USB_OTG_EP0_DATA_IN) - { - if(ep->rem_data_len > ep->maxpacket) - { - ep->rem_data_len -= ep->maxpacket; - if(pdev->cfg.dma_enable == 1) - { - /* in slave mode this, is handled by the TxFifoEmpty ISR */ - ep->xfer_buff += ep->maxpacket; - } - USBD_CtlContinueSendData (pdev, - ep->xfer_buff, - ep->rem_data_len); - } - else - { /* last packet is MPS multiple, so send ZLP packet */ - if((ep->total_data_len % ep->maxpacket == 0) && - (ep->total_data_len >= ep->maxpacket) && - (ep->total_data_len < ep->ctl_data_len )) - { - - USBD_CtlContinueSendData(pdev , NULL, 0); - ep->ctl_data_len = 0; - } - else - { - if((pdev->dev.class_cb->EP0_TxSent != NULL)&& - (pdev->dev.device_status == USB_OTG_CONFIGURED)) - { - pdev->dev.class_cb->EP0_TxSent(pdev); - } - USBD_CtlReceiveStatus(pdev); - } - } - } - } - else if((pdev->dev.class_cb->DataIn != NULL)&& - (pdev->dev.device_status == USB_OTG_CONFIGURED)) - { - pdev->dev.class_cb->DataIn(pdev, epnum); - } - return USBD_OK; -} - -/** -* @brief USBD_Reset -* Handle Reset event -* @param pdev: device instance -* @retval status -*/ - -static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE *pdev) -{ - /* Open EP0 OUT */ - DCD_EP_Open(pdev, - 0x00, - USB_OTG_MAX_EP0_SIZE, - EP_TYPE_CTRL); - - /* Open EP0 IN */ - DCD_EP_Open(pdev, - 0x80, - USB_OTG_MAX_EP0_SIZE, - EP_TYPE_CTRL); - - /* Upon Reset call usr call back */ - pdev->dev.device_status = USB_OTG_DEFAULT; - pdev->dev.usr_cb->DeviceReset(pdev->cfg.speed); - - return USBD_OK; -} - -/** -* @brief USBD_Resume -* Handle Resume event -* @param pdev: device instance -* @retval status -*/ - -static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE *pdev) -{ - /* Upon Resume call usr call back */ - pdev->dev.usr_cb->DeviceResumed(); - pdev->dev.device_status = USB_OTG_CONFIGURED; - return USBD_OK; -} - - -/** -* @brief USBD_Suspend -* Handle Suspend event -* @param pdev: device instance -* @retval status -*/ - -static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE *pdev) -{ - - pdev->dev.device_status = USB_OTG_SUSPENDED; - /* Upon Resume call usr call back */ - pdev->dev.usr_cb->DeviceSuspended(); - return USBD_OK; -} - - -/** -* @brief USBD_SOF -* Handle SOF event -* @param pdev: device instance -* @retval status -*/ - -static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev) -{ - if(pdev->dev.class_cb->SOF) - { - pdev->dev.class_cb->SOF(pdev); - } - return USBD_OK; -} -/** -* @brief USBD_SetCfg -* Configure device and start the interface -* @param pdev: device instance -* @param cfgidx: configuration index -* @retval status -*/ - -USBD_Status USBD_SetCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx) -{ - pdev->dev.class_cb->Init(pdev, cfgidx); - - /* Upon set config call usr call back */ - pdev->dev.usr_cb->DeviceConfigured(); - return USBD_OK; -} - -/** -* @brief USBD_ClrCfg -* Clear current configuration -* @param pdev: device instance -* @param cfgidx: configuration index -* @retval status: USBD_Status -*/ -USBD_Status USBD_ClrCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx) -{ - pdev->dev.class_cb->DeInit(pdev, cfgidx); - return USBD_OK; -} - -/** -* @brief USBD_IsoINIncomplete -* Handle iso in incomplete event -* @param pdev: device instance -* @retval status -*/ -static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE *pdev) -{ - pdev->dev.class_cb->IsoINIncomplete(pdev); - return USBD_OK; -} - -/** -* @brief USBD_IsoOUTIncomplete -* Handle iso out incomplete event -* @param pdev: device instance -* @retval status -*/ -static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE *pdev) -{ - pdev->dev.class_cb->IsoOUTIncomplete(pdev); - return USBD_OK; -} - -#ifdef VBUS_SENSING_ENABLED -/** -* @brief USBD_DevConnected -* Handle device connection event -* @param pdev: device instance -* @retval status -*/ -static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev) -{ - pdev->dev.usr_cb->DeviceConnected(); - return USBD_OK; -} - -/** -* @brief USBD_DevDisconnected -* Handle device disconnection event -* @param pdev: device instance -* @retval status -*/ -static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE *pdev) -{ - pdev->dev.usr_cb->DeviceDisconnected(); - pdev->dev.class_cb->DeInit(pdev, 0); - return USBD_OK; -} -#endif -/** -* @} -*/ - - -/** -* @} -*/ - - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_Device_Library/Core/src/usbd_ioreq.c b/example/stm32f4/STM32_USB_Device_Library/Core/src/usbd_ioreq.c deleted file mode 100644 index 6964766bd..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Core/src/usbd_ioreq.c +++ /dev/null @@ -1,237 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_ioreq.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the IO requests APIs for control endpoints. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_ioreq.h" -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup USBD_IOREQ - * @brief control I/O requests module - * @{ - */ - -/** @defgroup USBD_IOREQ_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_Variables - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_FunctionPrototypes - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_IOREQ_Private_Functions - * @{ - */ - -/** -* @brief USBD_CtlSendData -* send data on the ctl pipe -* @param pdev: device instance -* @param buff: pointer to data buffer -* @param len: length of data to be sent -* @retval status -*/ -USBD_Status USBD_CtlSendData (USB_OTG_CORE_HANDLE *pdev, - uint8_t *pbuf, - uint16_t len) -{ - USBD_Status ret = USBD_OK; - - pdev->dev.in_ep[0].total_data_len = len; - pdev->dev.in_ep[0].rem_data_len = len; - pdev->dev.device_state = USB_OTG_EP0_DATA_IN; - - DCD_EP_Tx (pdev, 0, pbuf, len); - - return ret; -} - -/** -* @brief USBD_CtlContinueSendData -* continue sending data on the ctl pipe -* @param pdev: device instance -* @param buff: pointer to data buffer -* @param len: length of data to be sent -* @retval status -*/ -USBD_Status USBD_CtlContinueSendData (USB_OTG_CORE_HANDLE *pdev, - uint8_t *pbuf, - uint16_t len) -{ - USBD_Status ret = USBD_OK; - - DCD_EP_Tx (pdev, 0, pbuf, len); - - - return ret; -} - -/** -* @brief USBD_CtlPrepareRx -* receive data on the ctl pipe -* @param pdev: USB OTG device instance -* @param buff: pointer to data buffer -* @param len: length of data to be received -* @retval status -*/ -USBD_Status USBD_CtlPrepareRx (USB_OTG_CORE_HANDLE *pdev, - uint8_t *pbuf, - uint16_t len) -{ - USBD_Status ret = USBD_OK; - - pdev->dev.out_ep[0].total_data_len = len; - pdev->dev.out_ep[0].rem_data_len = len; - pdev->dev.device_state = USB_OTG_EP0_DATA_OUT; - - DCD_EP_PrepareRx (pdev, - 0, - pbuf, - len); - - - return ret; -} - -/** -* @brief USBD_CtlContinueRx -* continue receive data on the ctl pipe -* @param pdev: USB OTG device instance -* @param buff: pointer to data buffer -* @param len: length of data to be received -* @retval status -*/ -USBD_Status USBD_CtlContinueRx (USB_OTG_CORE_HANDLE *pdev, - uint8_t *pbuf, - uint16_t len) -{ - USBD_Status ret = USBD_OK; - - DCD_EP_PrepareRx (pdev, - 0, - pbuf, - len); - return ret; -} -/** -* @brief USBD_CtlSendStatus -* send zero lzngth packet on the ctl pipe -* @param pdev: USB OTG device instance -* @retval status -*/ -USBD_Status USBD_CtlSendStatus (USB_OTG_CORE_HANDLE *pdev) -{ - USBD_Status ret = USBD_OK; - pdev->dev.device_state = USB_OTG_EP0_STATUS_IN; - DCD_EP_Tx (pdev, - 0, - NULL, - 0); - - USB_OTG_EP0_OutStart(pdev); - - return ret; -} - -/** -* @brief USBD_CtlReceiveStatus -* receive zero lzngth packet on the ctl pipe -* @param pdev: USB OTG device instance -* @retval status -*/ -USBD_Status USBD_CtlReceiveStatus (USB_OTG_CORE_HANDLE *pdev) -{ - USBD_Status ret = USBD_OK; - pdev->dev.device_state = USB_OTG_EP0_STATUS_OUT; - DCD_EP_PrepareRx ( pdev, - 0, - NULL, - 0); - - USB_OTG_EP0_OutStart(pdev); - - return ret; -} - - -/** -* @brief USBD_GetRxCount -* returns the received data length -* @param pdev: USB OTG device instance -* epnum: endpoint index -* @retval Rx Data blength -*/ -uint16_t USBD_GetRxCount (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) -{ - return pdev->dev.out_ep[epnum].xfer_count; -} - -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_Device_Library/Core/src/usbd_req.c b/example/stm32f4/STM32_USB_Device_Library/Core/src/usbd_req.c deleted file mode 100644 index f08d26c6c..000000000 --- a/example/stm32f4/STM32_USB_Device_Library/Core/src/usbd_req.c +++ /dev/null @@ -1,868 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_req.c - * @author MCD Application Team - * @version V1.0.0 - * @date 22-July-2011 - * @brief This file provides the standard USB requests following chapter 9. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_req.h" -#include "usbd_ioreq.h" -#include "usbd_desc.h" - - -/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup USBD_REQ - * @brief USB standard requests module - * @{ - */ - -/** @defgroup USBD_REQ_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_Variables - * @{ - */ - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint32_t USBD_ep_status __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint32_t USBD_default_cfg __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint32_t USBD_cfg_status __ALIGN_END = 0; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ] __ALIGN_END ; -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_FunctionPrototypes - * @{ - */ -static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -static void USBD_SetAddress(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -static void USBD_SetConfig(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -static void USBD_GetConfig(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -static void USBD_GetStatus(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -static void USBD_ClrFeature(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req); - -static uint8_t USBD_GetLen(uint8_t *buf); -/** - * @} - */ - - -/** @defgroup USBD_REQ_Private_Functions - * @{ - */ - - -/** -* @brief USBD_StdDevReq -* Handle standard usb device requests -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -USBD_Status USBD_StdDevReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req) -{ - USBD_Status ret = USBD_OK; - - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - - USBD_GetDescriptor (pdev, req) ; - break; - - case USB_REQ_SET_ADDRESS: - USBD_SetAddress(pdev, req); - break; - - case USB_REQ_SET_CONFIGURATION: - USBD_SetConfig (pdev , req); - break; - - case USB_REQ_GET_CONFIGURATION: - USBD_GetConfig (pdev , req); - break; - - case USB_REQ_GET_STATUS: - USBD_GetStatus (pdev , req); - break; - - - case USB_REQ_SET_FEATURE: - USBD_SetFeature (pdev , req); - break; - - case USB_REQ_CLEAR_FEATURE: - USBD_ClrFeature (pdev , req); - break; - - default: - USBD_CtlError(pdev , req); - break; - } - - return ret; -} - -/** -* @brief USBD_StdItfReq -* Handle standard usb interface requests -* @param pdev: USB OTG device instance -* @param req: usb request -* @retval status -*/ -USBD_Status USBD_StdItfReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req) -{ - USBD_Status ret = USBD_OK; - - switch (pdev->dev.device_status) - { - case USB_OTG_CONFIGURED: - - if (LOBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) - { - pdev->dev.class_cb->Setup (pdev, req); - - if((req->wLength == 0)&& (ret == USBD_OK)) - { - USBD_CtlSendStatus(pdev); - } - } - else - { - USBD_CtlError(pdev , req); - } - break; - - default: - USBD_CtlError(pdev , req); - break; - } - return ret; -} - -/** -* @brief USBD_StdEPReq -* Handle standard usb endpoint requests -* @param pdev: USB OTG device instance -* @param req: usb request -* @retval status -*/ -USBD_Status USBD_StdEPReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req) -{ - - uint8_t ep_addr; - USBD_Status ret = USBD_OK; - - ep_addr = LOBYTE(req->wIndex); - - switch (req->bRequest) - { - - case USB_REQ_SET_FEATURE : - - switch (pdev->dev.device_status) - { - case USB_OTG_ADDRESSED: - if ((ep_addr != 0x00) && (ep_addr != 0x80)) - { - DCD_EP_Stall(pdev , ep_addr); - } - break; - - case USB_OTG_CONFIGURED: - if (req->wValue == USB_FEATURE_EP_HALT) - { - if ((ep_addr != 0x00) && (ep_addr != 0x80)) - { - DCD_EP_Stall(pdev , ep_addr); - - } - } - pdev->dev.class_cb->Setup (pdev, req); - USBD_CtlSendStatus(pdev); - - break; - - default: - USBD_CtlError(pdev , req); - break; - } - break; - - case USB_REQ_CLEAR_FEATURE : - - switch (pdev->dev.device_status) - { - case USB_OTG_ADDRESSED: - if ((ep_addr != 0x00) && (ep_addr != 0x80)) - { - DCD_EP_Stall(pdev , ep_addr); - } - break; - - case USB_OTG_CONFIGURED: - if (req->wValue == USB_FEATURE_EP_HALT) - { - if ((ep_addr != 0x00) && (ep_addr != 0x80)) - { - DCD_EP_ClrStall(pdev , ep_addr); - pdev->dev.class_cb->Setup (pdev, req); - } - USBD_CtlSendStatus(pdev); - } - break; - - default: - USBD_CtlError(pdev , req); - break; - } - break; - - case USB_REQ_GET_STATUS: - switch (pdev->dev.device_status) - { - case USB_OTG_ADDRESSED: - if ((ep_addr != 0x00) && (ep_addr != 0x80)) - { - DCD_EP_Stall(pdev , ep_addr); - } - break; - - case USB_OTG_CONFIGURED: - - - if ((ep_addr & 0x80)== 0x80) - { - if(pdev->dev.in_ep[ep_addr & 0x7F].is_stall) - { - USBD_ep_status = 0x0001; - } - else - { - USBD_ep_status = 0x0000; - } - } - else if ((ep_addr & 0x80)== 0x00) - { - if(pdev->dev.out_ep[ep_addr].is_stall) - { - USBD_ep_status = 0x0001; - } - - else - { - USBD_ep_status = 0x0000; - } - } - USBD_CtlSendData (pdev, - (uint8_t *)&USBD_ep_status, - 2); - break; - - default: - USBD_CtlError(pdev , req); - break; - } - break; - - default: - break; - } - return ret; -} -/** -* @brief USBD_GetDescriptor -* Handle Get Descriptor requests -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - uint16_t len; - uint8_t *pbuf; - - switch (req->wValue >> 8) - { - case USB_DESC_TYPE_DEVICE: - pbuf = pdev->dev.usr_device->GetDeviceDescriptor(pdev->cfg.speed, &len); - if ((req->wLength == 64) ||( pdev->dev.device_status == USB_OTG_DEFAULT)) - { - len = 8; - } - break; - - case USB_DESC_TYPE_CONFIGURATION: - pbuf = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len); -#ifdef USB_OTG_HS_CORE - if((pdev->cfg.speed == USB_OTG_SPEED_FULL )&& - (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY)) - { - pbuf = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len); - } -#endif - pbuf[1] = USB_DESC_TYPE_CONFIGURATION; - pdev->dev.pConfig_descriptor = pbuf; - break; - - case USB_DESC_TYPE_STRING: - switch ((uint8_t)(req->wValue)) - { - case USBD_IDX_LANGID_STR: - pbuf = pdev->dev.usr_device->GetLangIDStrDescriptor(pdev->cfg.speed, &len); - break; - - case USBD_IDX_MFC_STR: - pbuf = pdev->dev.usr_device->GetManufacturerStrDescriptor(pdev->cfg.speed, &len); - break; - - case USBD_IDX_PRODUCT_STR: - pbuf = pdev->dev.usr_device->GetProductStrDescriptor(pdev->cfg.speed, &len); - break; - - case USBD_IDX_SERIAL_STR: - pbuf = pdev->dev.usr_device->GetSerialStrDescriptor(pdev->cfg.speed, &len); - break; - - case USBD_IDX_CONFIG_STR: - pbuf = pdev->dev.usr_device->GetConfigurationStrDescriptor(pdev->cfg.speed, &len); - break; - - case USBD_IDX_INTERFACE_STR: - pbuf = pdev->dev.usr_device->GetInterfaceStrDescriptor(pdev->cfg.speed, &len); - break; - - default: -#ifdef USB_SUPPORT_USER_STRING_DESC - pbuf = pdev->dev.class_cb->GetUsrStrDescriptor(pdev->cfg.speed, (req->wValue) , &len); - break; -#else - USBD_CtlError(pdev , req); - return; -#endif /* USBD_CtlError(pdev , req); */ - } - break; - case USB_DESC_TYPE_DEVICE_QUALIFIER: -#ifdef USB_OTG_HS_CORE - if(pdev->cfg.speed == USB_OTG_SPEED_HIGH ) - { - - pbuf = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len); - - USBD_DeviceQualifierDesc[4]= pbuf[14]; - USBD_DeviceQualifierDesc[5]= pbuf[15]; - USBD_DeviceQualifierDesc[6]= pbuf[16]; - - pbuf = USBD_DeviceQualifierDesc; - len = USB_LEN_DEV_QUALIFIER_DESC; - break; - } - else - { - USBD_CtlError(pdev , req); - return; - } -#else - USBD_CtlError(pdev , req); - return; -#endif - - case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: -#ifdef USB_OTG_HS_CORE - - if(pdev->cfg.speed == USB_OTG_SPEED_HIGH ) - { - pbuf = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len); - pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; - break; - } - else - { - USBD_CtlError(pdev , req); - return; - } -#else - USBD_CtlError(pdev , req); - return; -#endif - - - default: - USBD_CtlError(pdev , req); - return; - } - - if((len != 0)&& (req->wLength != 0)) - { - - len = MIN(len , req->wLength); - - USBD_CtlSendData (pdev, - pbuf, - len); - } - -} - -/** -* @brief USBD_SetAddress -* Set device address -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -static void USBD_SetAddress(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - uint8_t dev_addr; - - if ((req->wIndex == 0) && (req->wLength == 0)) - { - dev_addr = (uint8_t)(req->wValue) & 0x7F; - - if (pdev->dev.device_status == USB_OTG_CONFIGURED) - { - USBD_CtlError(pdev , req); - } - else - { - pdev->dev.device_address = dev_addr; - DCD_EP_SetAddress(pdev, dev_addr); - USBD_CtlSendStatus(pdev); - - if (dev_addr != 0) - { - pdev->dev.device_status = USB_OTG_ADDRESSED; - } - else - { - pdev->dev.device_status = USB_OTG_DEFAULT; - } - } - } - else - { - USBD_CtlError(pdev , req); - } -} - -/** -* @brief USBD_SetConfig -* Handle Set device configuration request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -static void USBD_SetConfig(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - - static uint8_t cfgidx; - - cfgidx = (uint8_t)(req->wValue); - - if (cfgidx > USBD_CFG_MAX_NUM ) - { - USBD_CtlError(pdev , req); - } - else - { - switch (pdev->dev.device_status) - { - case USB_OTG_ADDRESSED: - if (cfgidx) - { - pdev->dev.device_config = cfgidx; - pdev->dev.device_status = USB_OTG_CONFIGURED; - USBD_SetCfg(pdev , cfgidx); - USBD_CtlSendStatus(pdev); - } - else - { - USBD_CtlSendStatus(pdev); - } - break; - - case USB_OTG_CONFIGURED: - if (cfgidx == 0) - { - pdev->dev.device_status = USB_OTG_ADDRESSED; - pdev->dev.device_config = cfgidx; - USBD_ClrCfg(pdev , cfgidx); - USBD_CtlSendStatus(pdev); - - } - else if (cfgidx != pdev->dev.device_config) - { - /* Clear old configuration */ - USBD_ClrCfg(pdev , pdev->dev.device_config); - - /* set new configuration */ - pdev->dev.device_config = cfgidx; - USBD_SetCfg(pdev , cfgidx); - USBD_CtlSendStatus(pdev); - } - else - { - USBD_CtlSendStatus(pdev); - } - break; - - default: - USBD_CtlError(pdev , req); - break; - } - } -} - -/** -* @brief USBD_GetConfig -* Handle Get device configuration request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -static void USBD_GetConfig(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - - if (req->wLength != 1) - { - USBD_CtlError(pdev , req); - } - else - { - switch (pdev->dev.device_status ) - { - case USB_OTG_ADDRESSED: - - USBD_CtlSendData (pdev, - (uint8_t *)&USBD_default_cfg, - 1); - break; - - case USB_OTG_CONFIGURED: - - USBD_CtlSendData (pdev, - &pdev->dev.device_config, - 1); - break; - - default: - USBD_CtlError(pdev , req); - break; - } - } -} - -/** -* @brief USBD_GetStatus -* Handle Get Status request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -static void USBD_GetStatus(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - - switch (pdev->dev.device_status) - { - case USB_OTG_ADDRESSED: - case USB_OTG_CONFIGURED: - - if (pdev->dev.DevRemoteWakeup) - { - USBD_cfg_status = USB_CONFIG_SELF_POWERED | USB_CONFIG_REMOTE_WAKEUP; - } - else - { - USBD_cfg_status = USB_CONFIG_SELF_POWERED; - } - - USBD_CtlSendData (pdev, - (uint8_t *)&USBD_cfg_status, - 1); - break; - - default : - USBD_CtlError(pdev , req); - break; - } -} - - -/** -* @brief USBD_SetFeature -* Handle Set device feature request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - - USB_OTG_DCTL_TypeDef dctl; - uint8_t test_mode = 0; - - if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) - { - pdev->dev.DevRemoteWakeup = 1; - pdev->dev.class_cb->Setup (pdev, req); - USBD_CtlSendStatus(pdev); - } - - else if ((req->wValue == USB_FEATURE_TEST_MODE) && - ((req->wIndex & 0xFF) == 0)) - { - dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL); - - test_mode = req->wIndex >> 8; - switch (test_mode) - { - case 1: // TEST_J - dctl.b.tstctl = 1; - break; - - case 2: // TEST_K - dctl.b.tstctl = 2; - break; - - case 3: // TEST_SE0_NAK - dctl.b.tstctl = 3; - break; - - case 4: // TEST_PACKET - dctl.b.tstctl = 4; - break; - - case 5: // TEST_FORCE_ENABLE - dctl.b.tstctl = 5; - break; - } - USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32); - USBD_CtlSendStatus(pdev); - } - -} - - -/** -* @brief USBD_ClrFeature -* Handle clear device feature request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ -static void USBD_ClrFeature(USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - switch (pdev->dev.device_status) - { - case USB_OTG_ADDRESSED: - case USB_OTG_CONFIGURED: - if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) - { - pdev->dev.DevRemoteWakeup = 0; - pdev->dev.class_cb->Setup (pdev, req); - USBD_CtlSendStatus(pdev); - } - break; - - default : - USBD_CtlError(pdev , req); - break; - } -} - -/** -* @brief USBD_ParseSetupRequest -* Copy buffer into setup structure -* @param pdev: device instance -* @param req: usb request -* @retval None -*/ - -void USBD_ParseSetupRequest( USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - req->bmRequest = *(uint8_t *) (pdev->dev.setup_packet); - req->bRequest = *(uint8_t *) (pdev->dev.setup_packet + 1); - req->wValue = SWAPBYTE (pdev->dev.setup_packet + 2); - req->wIndex = SWAPBYTE (pdev->dev.setup_packet + 4); - req->wLength = SWAPBYTE (pdev->dev.setup_packet + 6); - - pdev->dev.in_ep[0].ctl_data_len = req->wLength ; - pdev->dev.device_state = USB_OTG_EP0_SETUP; -} - -/** -* @brief USBD_CtlError -* Handle USB low level Error -* @param pdev: device instance -* @param req: usb request -* @retval None -*/ - -void USBD_CtlError( USB_OTG_CORE_HANDLE *pdev, - USB_SETUP_REQ *req) -{ - if((req->bmRequest & 0x80) == 0x80) - { - DCD_EP_Stall(pdev , 0x80); - } - else - { - if(req->wLength == 0) - { - DCD_EP_Stall(pdev , 0x80); - } - else - { - DCD_EP_Stall(pdev , 0); - } - } - USB_OTG_EP0_OutStart(pdev); -} - - -/** - * @brief USBD_GetString - * Convert Ascii string into unicode one - * @param desc : descriptor buffer - * @param unicode : Formatted string buffer (unicode) - * @param len : descriptor length - * @retval None - */ -void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) -{ - uint8_t idx = 0; - - if (desc != NULL) - { - *len = USBD_GetLen(desc) * 2 + 2; - unicode[idx++] = *len; - unicode[idx++] = USB_DESC_TYPE_STRING; - - while (*desc != NULL) - { - unicode[idx++] = *desc++; - unicode[idx++] = 0x00; - } - } -} - -/** - * @brief USBD_GetLen - * return the string length - * @param buf : pointer to the ascii string buffer - * @retval string length - */ -static uint8_t USBD_GetLen(uint8_t *buf) -{ - uint8_t len = 0; - - while (*buf != NULL) - { - len++; - buf++; - } - - return len; -} -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_core.h b/example/stm32f4/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_core.h deleted file mode 100644 index e6d0b79a0..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_core.h +++ /dev/null @@ -1,195 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_hid_core.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file contains all the prototypes for the usbh_hid_core.c - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive ----------------------------------------------*/ -#ifndef __USBH_HID_CORE_H -#define __USBH_HID_CORE_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbh_core.h" -#include "usbh_stdreq.h" -#include "usb_bsp.h" -#include "usbh_ioreq.h" -#include "usbh_hcs.h" - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_CLASS - * @{ - */ - -/** @addtogroup USBH_HID_CLASS - * @{ - */ - -/** @defgroup USBH_HID_CORE - * @brief This file is the Header file for USBH_HID_CORE.c - * @{ - */ - - -/** @defgroup USBH_HID_CORE_Exported_Types - * @{ - */ - - -/* States for HID State Machine */ -typedef enum -{ - HID_IDLE= 0, - HID_SEND_DATA, - HID_BUSY, - HID_GET_DATA, - HID_POLL, - HID_ERROR, -} -HID_State; - -typedef enum -{ - HID_REQ_IDLE = 0, - HID_REQ_GET_REPORT_DESC, - HID_REQ_GET_HID_DESC, - HID_REQ_SET_IDLE, - HID_REQ_SET_PROTOCOL, - HID_REQ_SET_REPORT, - -} -HID_CtlState; - -typedef struct HID_cb -{ - void (*Init) (void); - void (*Decode) (uint8_t *data); - -} HID_cb_TypeDef; - -typedef struct _HID_Report -{ - uint8_t ReportID; - uint8_t ReportType; - uint16_t UsagePage; - uint32_t Usage[2]; - uint32_t NbrUsage; - uint32_t UsageMin; - uint32_t UsageMax; - int32_t LogMin; - int32_t LogMax; - int32_t PhyMin; - int32_t PhyMax; - int32_t UnitExp; - uint32_t Unit; - uint32_t ReportSize; - uint32_t ReportCnt; - uint32_t Flag; - uint32_t PhyUsage; - uint32_t AppUsage; - uint32_t LogUsage; -} -HID_Report_TypeDef; - -/* Structure for HID process */ -typedef struct _HID_Process -{ - uint8_t buff[64]; - uint8_t hc_num_in; - uint8_t hc_num_out; - HID_State state; - uint8_t HIDIntOutEp; - uint8_t HIDIntInEp; - HID_CtlState ctl_state; - uint16_t length; - uint8_t ep_addr; - uint16_t poll; - __IO uint16_t timer; - HID_cb_TypeDef *cb; -} -HID_Machine_TypeDef; - -/** - * @} - */ - -/** @defgroup USBH_HID_CORE_Exported_Defines - * @{ - */ - -#define USB_HID_REQ_GET_REPORT 0x01 -#define USB_HID_GET_IDLE 0x02 -#define USB_HID_GET_PROTOCOL 0x03 -#define USB_HID_SET_REPORT 0x09 -#define USB_HID_SET_IDLE 0x0A -#define USB_HID_SET_PROTOCOL 0x0B -/** - * @} - */ - -/** @defgroup USBH_HID_CORE_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_HID_CORE_Exported_Variables - * @{ - */ -extern USBH_Class_cb_TypeDef HID_cb; -/** - * @} - */ - -/** @defgroup USBH_HID_CORE_Exported_FunctionsPrototype - * @{ - */ - -USBH_Status USBH_Set_Report (USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t reportType, - uint8_t reportId, - uint8_t reportLen, - uint8_t* reportBuff); -/** - * @} - */ - - -#endif /* __USBH_HID_CORE_H */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_keybd.h b/example/stm32f4/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_keybd.h deleted file mode 100644 index 08f6b9f58..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_keybd.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_hid_keybd.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file contains all the prototypes for the usbh_hid_keybd.c - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive -----------------------------------------------*/ -#ifndef __USBH_HID_KEYBD_H -#define __USBH_HID_KEYBD_H - -/* Includes ------------------------------------------------------------------*/ -#include "usb_conf.h" -#include "usbh_hid_core.h" - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_CLASS - * @{ - */ - -/** @addtogroup USBH_HID_CLASS - * @{ - */ - -/** @defgroup USBH_HID_KEYBD - * @brief This file is the Header file for USBH_HID_KEYBD.c - * @{ - */ - - -/** @defgroup USBH_HID_KEYBD_Exported_Types - * @{ - */ - - -/** - * @} - */ - -/** @defgroup USBH_HID_KEYBD_Exported_Defines - * @{ - */ -//#define QWERTY_KEYBOARD -#define AZERTY_KEYBOARD - -#define KBD_LEFT_CTRL 0x01 -#define KBD_LEFT_SHIFT 0x02 -#define KBD_LEFT_ALT 0x04 -#define KBD_LEFT_GUI 0x08 -#define KBD_RIGHT_CTRL 0x10 -#define KBD_RIGHT_SHIFT 0x20 -#define KBD_RIGHT_ALT 0x40 -#define KBD_RIGHT_GUI 0x80 - -#define KBR_MAX_NBR_PRESSED 6 - -/** - * @} - */ - -/** @defgroup USBH_HID_KEYBD_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_HID_KEYBD_Exported_Variables - * @{ - */ - -extern HID_cb_TypeDef HID_KEYBRD_cb; -/** - * @} - */ - -/** @defgroup USBH_HID_KEYBD_Exported_FunctionsPrototype - * @{ - */ -void USR_KEYBRD_Init (void); -void USR_KEYBRD_ProcessData (uint8_t pbuf); -/** - * @} - */ - -#endif /* __USBH_HID_KEYBD_H */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_mouse.h b/example/stm32f4/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_mouse.h deleted file mode 100644 index eb2c2aeb0..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_mouse.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_hid_mouse.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file contains all the prototypes for the usbh_hid_mouse.c - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - - -/* Define to prevent recursive ----------------------------------------------*/ -#ifndef __USBH_HID_MOUSE_H -#define __USBH_HID_MOUSE_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbh_hid_core.h" - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_CLASS - * @{ - */ - -/** @addtogroup USBH_HID_CLASS - * @{ - */ - -/** @defgroup USBH_HID_MOUSE - * @brief This file is the Header file for USBH_HID_MOUSE.c - * @{ - */ - - -/** @defgroup USBH_HID_MOUSE_Exported_Types - * @{ - */ -typedef struct _HID_MOUSE_Data -{ - uint8_t x; - uint8_t y; - uint8_t z; /* Not Supported */ - uint8_t button; -} -HID_MOUSE_Data_TypeDef; - -/** - * @} - */ - -/** @defgroup USBH_HID_MOUSE_Exported_Defines - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_HID_MOUSE_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_HID_MOUSE_Exported_Variables - * @{ - */ - -extern HID_cb_TypeDef HID_MOUSE_cb; -extern HID_MOUSE_Data_TypeDef HID_MOUSE_Data; -/** - * @} - */ - -/** @defgroup USBH_HID_MOUSE_Exported_FunctionsPrototype - * @{ - */ -void USR_MOUSE_Init (void); -void USR_MOUSE_ProcessData (HID_MOUSE_Data_TypeDef *data); -/** - * @} - */ - -#endif /* __USBH_HID_MOUSE_H */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_core.c b/example/stm32f4/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_core.c deleted file mode 100644 index 53cb1969d..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_core.c +++ /dev/null @@ -1,640 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_hid_core.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file is the HID Layer Handlers for USB Host HID class. - * - * @verbatim - * - * =================================================================== - * HID Class Description - * =================================================================== - * This module manages the MSC class V1.11 following the "Device Class Definition - * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001". - * This driver implements the following aspects of the specification: - * - The Boot Interface Subclass - * - The Mouse and Keyboard protocols - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbh_hid_core.h" -#include "usbh_hid_mouse.h" -#include "usbh_hid_keybd.h" - -/** @addtogroup USBH_LIB -* @{ -*/ - -/** @addtogroup USBH_CLASS -* @{ -*/ - -/** @addtogroup USBH_HID_CLASS -* @{ -*/ - -/** @defgroup USBH_HID_CORE -* @brief This file includes HID Layer Handlers for USB Host HID class. -* @{ -*/ - -/** @defgroup USBH_HID_CORE_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBH_HID_CORE_Private_Defines -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBH_HID_CORE_Private_Macros -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBH_HID_CORE_Private_Variables -* @{ -*/ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN HID_Machine_TypeDef HID_Machine __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN HID_Report_TypeDef HID_Report __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN USB_Setup_TypeDef HID_Setup __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN USBH_HIDDesc_TypeDef HID_Desc __ALIGN_END ; - -__IO uint8_t flag = 0; -/** -* @} -*/ - - -/** @defgroup USBH_HID_CORE_Private_FunctionPrototypes -* @{ -*/ - -static USBH_Status USBH_HID_InterfaceInit (USB_OTG_CORE_HANDLE *pdev , - void *phost); - -static void USBH_ParseHIDDesc (USBH_HIDDesc_TypeDef *desc, uint8_t *buf); - -static void USBH_HID_InterfaceDeInit (USB_OTG_CORE_HANDLE *pdev , - void *phost); - -static USBH_Status USBH_HID_Handle(USB_OTG_CORE_HANDLE *pdev , - void *phost); - -static USBH_Status USBH_HID_ClassRequest(USB_OTG_CORE_HANDLE *pdev , - void *phost); - -static USBH_Status USBH_Get_HID_ReportDescriptor (USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint16_t length); - -static USBH_Status USBH_Get_HID_Descriptor (USB_OTG_CORE_HANDLE *pdev,\ - USBH_HOST *phost, - uint16_t length); - -static USBH_Status USBH_Set_Idle (USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t duration, - uint8_t reportId); - -static USBH_Status USBH_Set_Protocol (USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t protocol); - - -USBH_Class_cb_TypeDef HID_cb = -{ - USBH_HID_InterfaceInit, - USBH_HID_InterfaceDeInit, - USBH_HID_ClassRequest, - USBH_HID_Handle -}; -/** -* @} -*/ - - -/** @defgroup USBH_HID_CORE_Private_Functions -* @{ -*/ - -/** -* @brief USBH_HID_InterfaceInit -* The function init the HID class. -* @param pdev: Selected device -* @param hdev: Selected device property -* @retval USBH_Status :Response for USB HID driver intialization -*/ -static USBH_Status USBH_HID_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev, - void *phost) -{ - uint8_t maxEP; - USBH_HOST *pphost = phost; - - uint8_t num =0; - USBH_Status status = USBH_BUSY ; - HID_Machine.state = HID_ERROR; - - - if(pphost->device_prop.Itf_Desc[0].bInterfaceSubClass == HID_BOOT_CODE) - { - /*Decode Bootclass Protocl: Mouse or Keyboard*/ - if(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == HID_KEYBRD_BOOT_CODE) - { - HID_Machine.cb = &HID_KEYBRD_cb; - } - else if(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == HID_MOUSE_BOOT_CODE) - { - HID_Machine.cb = &HID_MOUSE_cb; - } - - HID_Machine.state = HID_IDLE; - HID_Machine.ctl_state = HID_REQ_IDLE; - HID_Machine.ep_addr = pphost->device_prop.Ep_Desc[0][0].bEndpointAddress; - HID_Machine.length = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize; - HID_Machine.poll = pphost->device_prop.Ep_Desc[0][0].bInterval ; - - /* Check fo available number of endpoints */ - /* Find the number of EPs in the Interface Descriptor */ - /* Choose the lower number in order not to overrun the buffer allocated */ - maxEP = ( (pphost->device_prop.Itf_Desc[0].bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) ? - pphost->device_prop.Itf_Desc[0].bNumEndpoints : - USBH_MAX_NUM_ENDPOINTS); - - - /* Decode endpoint IN and OUT address from interface descriptor */ - for (num=0; num < maxEP; num++) - { - if(pphost->device_prop.Ep_Desc[0][num].bEndpointAddress & 0x80) - { - HID_Machine.HIDIntInEp = (pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); - HID_Machine.hc_num_in =\ - USBH_Alloc_Channel(pdev, - pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); - - /* Open channel for IN endpoint */ - USBH_Open_Channel (pdev, - HID_Machine.hc_num_in, - pphost->device_prop.address, - pphost->device_prop.speed, - EP_TYPE_INTR, - HID_Machine.length); - } - else - { - HID_Machine.HIDIntOutEp = (pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); - HID_Machine.hc_num_out =\ - USBH_Alloc_Channel(pdev, - pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); - - /* Open channel for OUT endpoint */ - USBH_Open_Channel (pdev, - HID_Machine.hc_num_out, - pphost->device_prop.address, - pphost->device_prop.speed, - EP_TYPE_INTR, - HID_Machine.length); - } - - } - - flag =0; - status = USBH_OK; - } - else - { - pphost->usr_cb->USBH_USR_DeviceNotSupported(); - } - - return status; - -} - - - -/** -* @brief USBH_HID_InterfaceDeInit -* The function DeInit the Host Channels used for the HID class. -* @param pdev: Selected device -* @param hdev: Selected device property -* @retval None -*/ -void USBH_HID_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev, - void *phost) -{ - //USBH_HOST *pphost = phost; - - if(HID_Machine.hc_num_in != 0x00) - { - USB_OTG_HC_Halt(pdev, HID_Machine.hc_num_in); - USBH_Free_Channel (pdev, HID_Machine.hc_num_in); - HID_Machine.hc_num_in = 0; /* Reset the Channel as Free */ - } - - if(HID_Machine.hc_num_out != 0x00) - { - USB_OTG_HC_Halt(pdev, HID_Machine.hc_num_out); - USBH_Free_Channel (pdev, HID_Machine.hc_num_out); - HID_Machine.hc_num_out = 0; /* Reset the Channel as Free */ - } - - flag = 0; -} - -/** -* @brief USBH_HID_ClassRequest -* The function is responsible for handling HID Class requests -* for HID class. -* @param pdev: Selected device -* @param hdev: Selected device property -* @retval USBH_Status :Response for USB Set Protocol request -*/ -static USBH_Status USBH_HID_ClassRequest(USB_OTG_CORE_HANDLE *pdev , - void *phost) -{ - USBH_HOST *pphost = phost; - - USBH_Status status = USBH_BUSY; - USBH_Status classReqStatus = USBH_BUSY; - - - /* Switch HID state machine */ - switch (HID_Machine.ctl_state) - { - case HID_IDLE: - case HID_REQ_GET_HID_DESC: - - /* Get HID Desc */ - if (USBH_Get_HID_Descriptor (pdev, pphost, USB_HID_DESC_SIZE)== USBH_OK) - { - - USBH_ParseHIDDesc(&HID_Desc, pdev->host.Rx_Buffer); - HID_Machine.ctl_state = HID_REQ_GET_REPORT_DESC; - } - - break; - case HID_REQ_GET_REPORT_DESC: - - - /* Get Report Desc */ - if (USBH_Get_HID_ReportDescriptor(pdev , pphost, HID_Desc.wItemLength) == USBH_OK) - { - HID_Machine.ctl_state = HID_REQ_SET_IDLE; - } - - break; - - case HID_REQ_SET_IDLE: - - classReqStatus = USBH_Set_Idle (pdev, pphost, 0, 0); - - /* set Idle */ - if (classReqStatus == USBH_OK) - { - HID_Machine.ctl_state = HID_REQ_SET_PROTOCOL; - } - else if(classReqStatus == USBH_NOT_SUPPORTED) - { - HID_Machine.ctl_state = HID_REQ_SET_PROTOCOL; - } - break; - - case HID_REQ_SET_PROTOCOL: - /* set protocol */ - if (USBH_Set_Protocol (pdev ,pphost, 0) == USBH_OK) - { - HID_Machine.ctl_state = HID_REQ_IDLE; - - /* all requests performed*/ - status = USBH_OK; - } - break; - - default: - break; - } - - return status; -} - - -/** -* @brief USBH_HID_Handle -* The function is for managing state machine for HID data transfers -* @param pdev: Selected device -* @param hdev: Selected device property -* @retval USBH_Status -*/ -static USBH_Status USBH_HID_Handle(USB_OTG_CORE_HANDLE *pdev , - void *phost) -{ - USBH_HOST *pphost = phost; - USBH_Status status = USBH_OK; - - switch (HID_Machine.state) - { - - case HID_IDLE: - HID_Machine.cb->Init(); - HID_Machine.state = HID_GET_DATA; - break; - - case HID_GET_DATA: - - /* Sync with start of Even Frame */ - while(USB_OTG_IsEvenFrame(pdev) == FALSE); - - USBH_InterruptReceiveData(pdev, - HID_Machine.buff, - HID_Machine.length, - HID_Machine.hc_num_in); - flag = 1; - - HID_Machine.state = HID_POLL; - HID_Machine.timer = HCD_GetCurrentFrame(pdev); - break; - - case HID_POLL: - if(( HCD_GetCurrentFrame(pdev) - HID_Machine.timer) >= HID_Machine.poll) - { - HID_Machine.state = HID_GET_DATA; - } - else if(HCD_GetURB_State(pdev , HID_Machine.hc_num_in) == URB_DONE) - { - if(flag == 1) /* handle data once */ - { - flag = 0; - HID_Machine.cb->Decode(HID_Machine.buff); - } - } - else if(HCD_GetURB_State(pdev, HID_Machine.hc_num_in) == URB_STALL) /* IN Endpoint Stalled */ - { - - /* Issue Clear Feature on interrupt IN endpoint */ - if( (USBH_ClrFeature(pdev, - pphost, - HID_Machine.ep_addr, - HID_Machine.hc_num_in)) == USBH_OK) - { - /* Change state to issue next IN token */ - HID_Machine.state = HID_GET_DATA; - - } - - } - break; - - default: - break; - } - return status; -} - - -/** -* @brief USBH_Get_HID_ReportDescriptor -* Issue report Descriptor command to the device. Once the response -* received, parse the report descriptor and update the status. -* @param pdev : Selected device -* @param Length : HID Report Descriptor Length -* @retval USBH_Status : Response for USB HID Get Report Descriptor Request -*/ -static USBH_Status USBH_Get_HID_ReportDescriptor (USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint16_t length) -{ - - USBH_Status status; - - status = USBH_GetDescriptor(pdev, - phost, - USB_REQ_RECIPIENT_INTERFACE - | USB_REQ_TYPE_STANDARD, - USB_DESC_HID_REPORT, - pdev->host.Rx_Buffer, - length); - - /* HID report descriptor is available in pdev->host.Rx_Buffer. - In case of USB Boot Mode devices for In report handling , - HID report descriptor parsing is not required. - In case, for supporting Non-Boot Protocol devices and output reports, - user may parse the report descriptor*/ - - - return status; -} - -/** -* @brief USBH_Get_HID_Descriptor -* Issue HID Descriptor command to the device. Once the response -* received, parse the report descriptor and update the status. -* @param pdev : Selected device -* @param Length : HID Descriptor Length -* @retval USBH_Status : Response for USB HID Get Report Descriptor Request -*/ -static USBH_Status USBH_Get_HID_Descriptor (USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint16_t length) -{ - - USBH_Status status; - - status = USBH_GetDescriptor(pdev, - phost, - USB_REQ_RECIPIENT_INTERFACE - | USB_REQ_TYPE_STANDARD, - USB_DESC_HID, - pdev->host.Rx_Buffer, - length); - - return status; -} - -/** -* @brief USBH_Set_Idle -* Set Idle State. -* @param pdev: Selected device -* @param duration: Duration for HID Idle request -* @param reportID : Targetted report ID for Set Idle request -* @retval USBH_Status : Response for USB Set Idle request -*/ -static USBH_Status USBH_Set_Idle (USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t duration, - uint8_t reportId) -{ - - phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\ - USB_REQ_TYPE_CLASS; - - - phost->Control.setup.b.bRequest = USB_HID_SET_IDLE; - phost->Control.setup.b.wValue.w = (duration << 8 ) | reportId; - - phost->Control.setup.b.wIndex.w = 0; - phost->Control.setup.b.wLength.w = 0; - - return USBH_CtlReq(pdev, phost, 0 , 0 ); -} - - -/** -* @brief USBH_Set_Report -* Issues Set Report -* @param pdev: Selected device -* @param reportType : Report type to be sent -* @param reportID : Targetted report ID for Set Report request -* @param reportLen : Length of data report to be send -* @param reportBuff : Report Buffer -* @retval USBH_Status : Response for USB Set Idle request -*/ -USBH_Status USBH_Set_Report (USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t reportType, - uint8_t reportId, - uint8_t reportLen, - uint8_t* reportBuff) -{ - - phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\ - USB_REQ_TYPE_CLASS; - - - phost->Control.setup.b.bRequest = USB_HID_SET_REPORT; - phost->Control.setup.b.wValue.w = (reportType << 8 ) | reportId; - - phost->Control.setup.b.wIndex.w = 0; - phost->Control.setup.b.wLength.w = reportLen; - - return USBH_CtlReq(pdev, phost, reportBuff , reportLen ); -} - - -/** -* @brief USBH_Set_Protocol -* Set protocol State. -* @param pdev: Selected device -* @param protocol : Set Protocol for HID : boot/report protocol -* @retval USBH_Status : Response for USB Set Protocol request -*/ -static USBH_Status USBH_Set_Protocol(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t protocol) -{ - - - phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\ - USB_REQ_TYPE_CLASS; - - - phost->Control.setup.b.bRequest = USB_HID_SET_PROTOCOL; - - if(protocol != 0) - { - /* Boot Protocol */ - phost->Control.setup.b.wValue.w = 0; - } - else - { - /*Report Protocol*/ - phost->Control.setup.b.wValue.w = 1; - } - - phost->Control.setup.b.wIndex.w = 0; - phost->Control.setup.b.wLength.w = 0; - - return USBH_CtlReq(pdev, phost, 0 , 0 ); - -} - -/** -* @brief USBH_ParseHIDDesc -* This function Parse the HID descriptor -* @param buf: Buffer where the source descriptor is available -* @retval None -*/ -static void USBH_ParseHIDDesc (USBH_HIDDesc_TypeDef *desc, uint8_t *buf) -{ - - desc->bLength = *(uint8_t *) (buf + 0); - desc->bDescriptorType = *(uint8_t *) (buf + 1); - desc->bcdHID = LE16 (buf + 2); - desc->bCountryCode = *(uint8_t *) (buf + 4); - desc->bNumDescriptors = *(uint8_t *) (buf + 5); - desc->bReportDescriptorType = *(uint8_t *) (buf + 6); - desc->wItemLength = LE16 (buf + 7); - -} -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - - -/** -* @} -*/ - - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_keybd.c b/example/stm32f4/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_keybd.c deleted file mode 100644 index ae0df34d2..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_keybd.c +++ /dev/null @@ -1,338 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_hid_keybd.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file is the application layer for USB Host HID Keyboard handling - * QWERTY and AZERTY Keyboard are supported as per the selection in - * usbh_hid_keybd.h - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - - -/* Includes ------------------------------------------------------------------*/ -#include "usbh_hid_keybd.h" - -/** @addtogroup USBH_LIB -* @{ -*/ - -/** @addtogroup USBH_CLASS -* @{ -*/ - -/** @addtogroup USBH_HID_CLASS -* @{ -*/ - -/** @defgroup USBH_HID_KEYBD -* @brief This file includes HID Layer Handlers for USB Host HID class. -* @{ -*/ - -/** @defgroup USBH_HID_KEYBD_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBH_HID_KEYBD_Private_Defines -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBH_HID_KEYBD_Private_Macros -* @{ -*/ -/** -* @} -*/ - -/** @defgroup USBH_HID_KEYBD_Private_FunctionPrototypes -* @{ -*/ -static void KEYBRD_Init (void); -static void KEYBRD_Decode(uint8_t *data); - -/** -* @} -*/ - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined (__CC_ARM) /*!< ARM Compiler */ - __align(4) - #elif defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #elif defined (__GNUC__) /*!< GNU Compiler */ - #pragma pack(4) - #elif defined (__TASKING__) /*!< TASKING Compiler */ - __align(4) - #endif /* __CC_ARM */ -#endif - -/** @defgroup USBH_HID_KEYBD_Private_Variables -* @{ -*/ -HID_cb_TypeDef HID_KEYBRD_cb= -{ - KEYBRD_Init, - KEYBRD_Decode -}; - -/* -******************************************************************************* -* LOCAL CONSTANTS -******************************************************************************* -*/ - -static const uint8_t HID_KEYBRD_Codes[] = { - 0, 0, 0, 0, 31, 50, 48, 33, - 19, 34, 35, 36, 24, 37, 38, 39, /* 0x00 - 0x0F */ - 52, 51, 25, 26, 17, 20, 32, 21, - 23, 49, 18, 47, 22, 46, 2, 3, /* 0x10 - 0x1F */ - 4, 5, 6, 7, 8, 9, 10, 11, - 43, 110, 15, 16, 61, 12, 13, 27, /* 0x20 - 0x2F */ - 28, 29, 42, 40, 41, 1, 53, 54, - 55, 30, 112, 113, 114, 115, 116, 117, /* 0x30 - 0x3F */ - 118, 119, 120, 121, 122, 123, 124, 125, - 126, 75, 80, 85, 76, 81, 86, 89, /* 0x40 - 0x4F */ - 79, 84, 83, 90, 95, 100, 105, 106, - 108, 93, 98, 103, 92, 97, 102, 91, /* 0x50 - 0x5F */ - 96, 101, 99, 104, 45, 129, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6F */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7F */ - 0, 0, 0, 0, 0, 107, 0, 56, - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8F */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9F */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xAF */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0 - 0xBF */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0 - 0xCF */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0 - 0xDF */ - 58, 44, 60, 127, 64, 57, 62, 128 /* 0xE0 - 0xE7 */ -}; - -#ifdef QWERTY_KEYBOARD -static const int8_t HID_KEYBRD_Key[] = { - '\0', '`', '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '-', '=', '\0', '\r', - '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', - 'i', 'o', 'p', '[', ']', '\\', - '\0', 'a', 's', 'd', 'f', 'g', 'h', 'j', - 'k', 'l', ';', '\'', '\0', '\n', - '\0', '\0', 'z', 'x', 'c', 'v', 'b', 'n', - 'm', ',', '.', '/', '\0', '\0', - '\0', '\0', '\0', ' ', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\r', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '7', '4', '1', - '\0', '/', '8', '5', '2', - '0', '*', '9', '6', '3', - '.', '-', '+', '\0', '\n', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0' -}; - -static const int8_t HID_KEYBRD_ShiftKey[] = { - '\0', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', - '_', '+', '\0', '\0', '\0', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', - 'I', 'O', 'P', '{', '}', '|', '\0', 'A', 'S', 'D', 'F', 'G', - 'H', 'J', 'K', 'L', ':', '"', '\0', '\n', '\0', '\0', 'Z', 'X', - 'C', 'V', 'B', 'N', 'M', '<', '>', '?', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' -}; - -#else - -static const int8_t HID_KEYBRD_Key[] = { - '\0', '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', - '-', '=', '\0', '\r', '\t', 'a', 'z', 'e', 'r', 't', 'y', 'u', - 'i', 'o', 'p', '[', ']', '\\', '\0', 'q', 's', 'd', 'f', 'g', - 'h', 'j', 'k', 'l', 'm', '\0', '\0', '\n', '\0', '\0', 'w', 'x', - 'c', 'v', 'b', 'n', ',', ';', ':', '!', '\0', '\0', '\0', '\0', - '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\r', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '7', '4', '1','\0', '/', - '8', '5', '2', '0', '*', '9', '6', '3', '.', '-', '+', '\0', - '\n', '\0', '\0', '\0', '\0', '\0', '\0','\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' -}; - -static const int8_t HID_KEYBRD_ShiftKey[] = { - '\0', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', - '+', '\0', '\0', '\0', 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', - 'P', '{', '}', '*', '\0', 'Q', 'S', 'D', 'F', 'G', 'H', 'J', 'K', - 'L', 'M', '%', '\0', '\n', '\0', '\0', 'W', 'X', 'C', 'V', 'B', 'N', - '?', '.', '/', '\0', '\0', '\0','\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' -}; -#endif - -/** -* @} -*/ - - -/** @defgroup USBH_HID_KEYBD_Private_Functions -* @{ -*/ - - -/** -* @brief KEYBRD_Init. -* Initialize the keyboard function. -* @param None -* @retval None -*/ -static void KEYBRD_Init (void) -{ - /* Call User Init*/ - USR_KEYBRD_Init(); -} - -/** -* @brief KEYBRD_ProcessData. -* The function is to decode the pressed keys. -* @param pbuf : Pointer to the HID IN report data buffer -* @retval None -*/ - -static void KEYBRD_Decode(uint8_t *pbuf) -{ - static uint8_t shift; - static uint8_t keys[KBR_MAX_NBR_PRESSED]; - static uint8_t keys_new[KBR_MAX_NBR_PRESSED]; - static uint8_t keys_last[KBR_MAX_NBR_PRESSED]; - static uint8_t key_newest; - static uint8_t nbr_keys; - static uint8_t nbr_keys_new; - static uint8_t nbr_keys_last; - uint8_t ix; - uint8_t jx; - uint8_t error; - uint8_t output; - - nbr_keys = 0; - nbr_keys_new = 0; - nbr_keys_last = 0; - key_newest = 0x00; - - - /* Check if Shift key is pressed */ - if ((pbuf[0] == KBD_LEFT_SHIFT) || (pbuf[0] == KBD_RIGHT_SHIFT)) { - shift = TRUE; - } else { - shift = FALSE; - } - - error = FALSE; - - /* Check for the value of pressed key */ - for (ix = 2; ix < 2 + KBR_MAX_NBR_PRESSED; ix++) { - if ((pbuf[ix] == 0x01) || - (pbuf[ix] == 0x02) || - (pbuf[ix] == 0x03)) { - error = TRUE; - } - } - - if (error == TRUE) { - return; - } - - nbr_keys = 0; - nbr_keys_new = 0; - for (ix = 2; ix < 2 + KBR_MAX_NBR_PRESSED; ix++) { - if (pbuf[ix] != 0) { - keys[nbr_keys] = pbuf[ix]; - nbr_keys++; - for (jx = 0; jx < nbr_keys_last; jx++) { - if (pbuf[ix] == keys_last[jx]) { - break; - } - } - - if (jx == nbr_keys_last) { - keys_new[nbr_keys_new] = pbuf[ix]; - nbr_keys_new++; - } - } - } - - if (nbr_keys_new == 1) { - key_newest = keys_new[0]; - - if (shift == TRUE) { - output = HID_KEYBRD_ShiftKey[HID_KEYBRD_Codes[key_newest]]; - } else { - output = HID_KEYBRD_Key[HID_KEYBRD_Codes[key_newest]]; - } - - /* call user process handle */ - USR_KEYBRD_ProcessData(output); - } else { - key_newest = 0x00; - } - - - nbr_keys_last = nbr_keys; - for (ix = 0; ix < KBR_MAX_NBR_PRESSED; ix++) { - keys_last[ix] = keys[ix]; - } -} - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_mouse.c b/example/stm32f4/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_mouse.c deleted file mode 100644 index f3ec2fc93..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_mouse.c +++ /dev/null @@ -1,155 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_hid_mouse.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file is the application layer for USB Host HID Mouse Handling. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbh_hid_mouse.h" - - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_CLASS - * @{ - */ - -/** @addtogroup USBH_HID_CLASS - * @{ - */ - -/** @defgroup USBH_HID_MOUSE - * @brief This file includes HID Layer Handlers for USB Host HID class. - * @{ - */ - -/** @defgroup USBH_HID_MOUSE_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_HID_MOUSE_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_HID_MOUSE_Private_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_HID_MOUSE_Private_FunctionPrototypes - * @{ - */ -static void MOUSE_Init (void); -static void MOUSE_Decode(uint8_t *data); -/** - * @} - */ - - -/** @defgroup USBH_HID_MOUSE_Private_Variables - * @{ - */ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined (__CC_ARM) /*!< ARM Compiler */ - __align(4) - #elif defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #elif defined (__GNUC__) /*!< GNU Compiler */ - #pragma pack(4) - #elif defined (__TASKING__) /*!< TASKING Compiler */ - __align(4) - #endif /* __CC_ARM */ -#endif - - -HID_MOUSE_Data_TypeDef HID_MOUSE_Data; -HID_cb_TypeDef HID_MOUSE_cb = -{ - MOUSE_Init, - MOUSE_Decode, -}; -/** - * @} - */ - - -/** @defgroup USBH_HID_MOUSE_Private_Functions - * @{ - */ - -/** -* @brief MOUSE_Init -* Init Mouse State. -* @param None -* @retval None -*/ -static void MOUSE_Init ( void) -{ - /* Call User Init*/ - USR_MOUSE_Init(); -} - -/** -* @brief MOUSE_Decode -* Decode Mouse data -* @param data : Pointer to Mouse HID data buffer -* @retval None -*/ -static void MOUSE_Decode(uint8_t *data) -{ - HID_MOUSE_Data.button = data[0]; - - HID_MOUSE_Data.x = data[1]; - HID_MOUSE_Data.y = data[2]; - - USR_MOUSE_ProcessData(&HID_MOUSE_Data); - -} -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_bot.h b/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_bot.h deleted file mode 100644 index 27e96598d..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_bot.h +++ /dev/null @@ -1,221 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_msc_bot.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Header file for usbh_msc_bot.c - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive ----------------------------------------------*/ -#ifndef __USBH_MSC_BOT_H__ -#define __USBH_MSC_BOT_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usbh_stdreq.h" - - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_CLASS - * @{ - */ - -/** @addtogroup USBH_MSC_CLASS - * @{ - */ - -/** @defgroup USBH_MSC_BOT - * @brief This file is the Header file for usbh_msc_core.c - * @{ - */ - - -/** @defgroup USBH_MSC_BOT_Exported_Types - * @{ - */ - -typedef union _USBH_CBW_Block -{ - struct __CBW - { - uint32_t CBWSignature; - uint32_t CBWTag; - uint32_t CBWTransferLength; - uint8_t CBWFlags; - uint8_t CBWLUN; - uint8_t CBWLength; - uint8_t CBWCB[16]; -}field; - uint8_t CBWArray[31]; -}HostCBWPkt_TypeDef; - -typedef enum -{ - USBH_MSC_BOT_INIT_STATE = 0, - USBH_MSC_BOT_RESET, - USBH_MSC_GET_MAX_LUN, - USBH_MSC_TEST_UNIT_READY, - USBH_MSC_READ_CAPACITY10, - USBH_MSC_MODE_SENSE6, - USBH_MSC_REQUEST_SENSE, - USBH_MSC_BOT_USB_TRANSFERS, - USBH_MSC_DEFAULT_APPLI_STATE, - USBH_MSC_CTRL_ERROR_STATE, - USBH_MSC_UNRECOVERED_STATE -} -MSCState; - - -typedef struct _BOTXfer -{ -uint8_t MSCState; -uint8_t MSCStateBkp; -uint8_t MSCStateCurrent; -uint8_t CmdStateMachine; -uint8_t BOTState; -uint8_t BOTStateBkp; -uint8_t* pRxTxBuff; -uint16_t DataLength; -uint8_t BOTXferErrorCount; -uint8_t BOTXferStatus; -} USBH_BOTXfer_TypeDef; - - -typedef union _USBH_CSW_Block -{ - struct __CSW - { - uint32_t CSWSignature; - uint32_t CSWTag; - uint32_t CSWDataResidue; - uint8_t CSWStatus; - }field; - uint8_t CSWArray[13]; -}HostCSWPkt_TypeDef; - -/** - * @} - */ - - - -/** @defgroup USBH_MSC_BOT_Exported_Defines - * @{ - */ -#define USBH_MSC_SEND_CBW 1 -#define USBH_MSC_SENT_CBW 2 -#define USBH_MSC_BOT_DATAIN_STATE 3 -#define USBH_MSC_BOT_DATAOUT_STATE 4 -#define USBH_MSC_RECEIVE_CSW_STATE 5 -#define USBH_MSC_DECODE_CSW 6 -#define USBH_MSC_BOT_ERROR_IN 7 -#define USBH_MSC_BOT_ERROR_OUT 8 - - -#define USBH_MSC_BOT_CBW_SIGNATURE 0x43425355 -#define USBH_MSC_BOT_CBW_TAG 0x20304050 -#define USBH_MSC_BOT_CSW_SIGNATURE 0x53425355 -#define USBH_MSC_CSW_DATA_LENGTH 0x000D -#define USBH_MSC_BOT_CBW_PACKET_LENGTH 31 -#define USBH_MSC_CSW_LENGTH 13 -#define USBH_MSC_CSW_MAX_LENGTH 63 - -/* CSW Status Definitions */ -#define USBH_MSC_CSW_CMD_PASSED 0x00 -#define USBH_MSC_CSW_CMD_FAILED 0x01 -#define USBH_MSC_CSW_PHASE_ERROR 0x02 - -#define USBH_MSC_SEND_CSW_DISABLE 0 -#define USBH_MSC_SEND_CSW_ENABLE 1 - -#define USBH_MSC_DIR_IN 0 -#define USBH_MSC_DIR_OUT 1 -#define USBH_MSC_BOTH_DIR 2 - -//#define USBH_MSC_PAGE_LENGTH 0x40 -#define USBH_MSC_PAGE_LENGTH 512 - - -#define CBW_CB_LENGTH 16 -#define CBW_LENGTH 10 -#define CBW_LENGTH_TEST_UNIT_READY 6 - -#define USB_REQ_BOT_RESET 0xFF -#define USB_REQ_GET_MAX_LUN 0xFE - -#define MAX_BULK_STALL_COUNT_LIMIT 0x04 /* If STALL is seen on Bulk - Endpoint continously, this means - that device and Host has phase error - Hence a Reset is needed */ - -/** - * @} - */ - -/** @defgroup USBH_MSC_BOT_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_MSC_BOT_Exported_Variables - * @{ - */ -extern USBH_BOTXfer_TypeDef USBH_MSC_BOTXferParam; -extern HostCBWPkt_TypeDef USBH_MSC_CBWData; -extern HostCSWPkt_TypeDef USBH_MSC_CSWData; -/** - * @} - */ - -/** @defgroup USBH_MSC_BOT_Exported_FunctionsPrototype - * @{ - */ -void USBH_MSC_HandleBOTXfer(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost); -uint8_t USBH_MSC_DecodeCSW(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost); -void USBH_MSC_Init(USB_OTG_CORE_HANDLE *pdev); -USBH_Status USBH_MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t direction); -/** - * @} - */ - -#endif //__USBH_MSC_BOT_H__ - - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_core.h b/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_core.h deleted file mode 100644 index 72ab4cef3..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_core.h +++ /dev/null @@ -1,141 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_msc_core.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file contains all the prototypes for the usbh_msc_core.c - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive ----------------------------------------------*/ -#ifndef __USBH_MSC_CORE_H -#define __USBH_MSC_CORE_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbh_core.h" -#include "usbh_stdreq.h" -#include "usb_bsp.h" -#include "usbh_ioreq.h" -#include "usbh_hcs.h" -#include "usbh_msc_core.h" -#include "usbh_msc_scsi.h" -#include "usbh_msc_bot.h" - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_CLASS - * @{ - */ - -/** @addtogroup USBH_MSC_CLASS - * @{ - */ - -/** @defgroup USBH_MSC_CORE - * @brief This file is the Header file for usbh_msc_core.c - * @{ - */ - - -/** @defgroup USBH_MSC_CORE_Exported_Types - * @{ - */ - - -/* Structure for MSC process */ -typedef struct _MSC_Process -{ - uint8_t hc_num_in; - uint8_t hc_num_out; - uint8_t MSBulkOutEp; - uint8_t MSBulkInEp; - uint16_t MSBulkInEpSize; - uint16_t MSBulkOutEpSize; - uint8_t buff[USBH_MSC_MPS_SIZE]; - uint8_t maxLun; -} -MSC_Machine_TypeDef; - - -/** - * @} - */ - - - -/** @defgroup USBH_MSC_CORE_Exported_Defines - * @{ - */ - -#define USB_REQ_BOT_RESET 0xFF -#define USB_REQ_GET_MAX_LUN 0xFE - - -/** - * @} - */ - -/** @defgroup USBH_MSC_CORE_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_MSC_CORE_Exported_Variables - * @{ - */ -extern USBH_Class_cb_TypeDef USBH_MSC_cb; -extern MSC_Machine_TypeDef MSC_Machine; -extern uint8_t MSCErrorCount; - -/** - * @} - */ - -/** @defgroup USBH_MSC_CORE_Exported_FunctionsPrototype - * @{ - */ - - - -/** - * @} - */ - -#endif /* __USBH_MSC_CORE_H */ - - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_scsi.h b/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_scsi.h deleted file mode 100644 index 3bdf4ec6d..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_scsi.h +++ /dev/null @@ -1,163 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_msc_scsi.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Header file for usbh_msc_scsi.c - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive ----------------------------------------------*/ -#ifndef __USBH_MSC_SCSI_H__ -#define __USBH_MSC_SCSI_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usbh_stdreq.h" - - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_CLASS - * @{ - */ - -/** @addtogroup USBH_MSC_CLASS - * @{ - */ - -/** @defgroup USBH_MSC_SCSI - * @brief This file is the Header file for usbh_msc_scsi.c - * @{ - */ - - -/** @defgroup USBH_MSC_SCSI_Exported_Types - * @{ - */ -typedef enum { - USBH_MSC_OK = 0, - USBH_MSC_FAIL = 1, - USBH_MSC_PHASE_ERROR = 2, - USBH_MSC_BUSY = 3 -}USBH_MSC_Status_TypeDef; - -typedef enum { - CMD_UNINITIALIZED_STATE =0, - CMD_SEND_STATE, - CMD_WAIT_STATUS -} CMD_STATES_TypeDef; - - - -typedef struct __MassStorageParameter -{ - uint32_t MSCapacity; - uint32_t MSSenseKey; - uint16_t MSPageLength; - uint8_t MSBulkOutEp; - uint8_t MSBulkInEp; - uint8_t MSWriteProtect; -} MassStorageParameter_TypeDef; -/** - * @} - */ - - - -/** @defgroup USBH_MSC_SCSI_Exported_Defines - * @{ - */ - - - -#define OPCODE_TEST_UNIT_READY 0X00 -#define OPCODE_READ_CAPACITY10 0x25 -#define OPCODE_MODE_SENSE6 0x1A -#define OPCODE_READ10 0x28 -#define OPCODE_WRITE10 0x2A -#define OPCODE_REQUEST_SENSE 0x03 - -#define DESC_REQUEST_SENSE 0X00 -#define ALLOCATION_LENGTH_REQUEST_SENSE 63 -#define XFER_LEN_READ_CAPACITY10 8 -#define XFER_LEN_MODE_SENSE6 63 - -#define MASK_MODE_SENSE_WRITE_PROTECT 0x80 -#define MODE_SENSE_PAGE_CONTROL_FIELD 0x00 -#define MODE_SENSE_PAGE_CODE 0x3F -#define DISK_WRITE_PROTECTED 0x01 -/** - * @} - */ - -/** @defgroup USBH_MSC_SCSI_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup _Exported_Variables - * @{ - */ -extern MassStorageParameter_TypeDef USBH_MSC_Param; -/** - * @} - */ - -/** @defgroup USBH_MSC_SCSI_Exported_FunctionsPrototype - * @{ - */ -uint8_t USBH_MSC_TestUnitReady(USB_OTG_CORE_HANDLE *pdev); -uint8_t USBH_MSC_ReadCapacity10(USB_OTG_CORE_HANDLE *pdev); -uint8_t USBH_MSC_ModeSense6(USB_OTG_CORE_HANDLE *pdev); -uint8_t USBH_MSC_RequestSense(USB_OTG_CORE_HANDLE *pdev); -uint8_t USBH_MSC_Write10(USB_OTG_CORE_HANDLE *pdev, - uint8_t *, - uint32_t , - uint32_t ); -uint8_t USBH_MSC_Read10(USB_OTG_CORE_HANDLE *pdev, - uint8_t *, - uint32_t , - uint32_t ); -void USBH_MSC_StateMachine(USB_OTG_CORE_HANDLE *pdev); - -/** - * @} - */ - -#endif //__USBH_MSC_SCSI_H__ - - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_bot.c b/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_bot.c deleted file mode 100644 index eeb10755b..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_bot.c +++ /dev/null @@ -1,613 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_msc_bot.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file includes the mass storage related functions - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbh_msc_core.h" -#include "usbh_msc_scsi.h" -#include "usbh_msc_bot.h" -#include "usbh_ioreq.h" -#include "usbh_def.h" -#include "usb_hcd_int.h" - - -/** @addtogroup USBH_LIB -* @{ -*/ - -/** @addtogroup USBH_CLASS -* @{ -*/ - -/** @addtogroup USBH_MSC_CLASS -* @{ -*/ - -/** @defgroup USBH_MSC_BOT -* @brief This file includes the mass storage related functions -* @{ -*/ - - -/** @defgroup USBH_MSC_BOT_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - -/** @defgroup USBH_MSC_BOT_Private_Defines -* @{ -*/ -/** -* @} -*/ - -/** @defgroup USBH_MSC_BOT_Private_Macros -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBH_MSC_BOT_Private_Variables -* @{ -*/ - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN HostCBWPkt_TypeDef USBH_MSC_CBWData __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN HostCSWPkt_TypeDef USBH_MSC_CSWData __ALIGN_END ; - - -static uint32_t BOTStallErrorCount; /* Keeps count of STALL Error Cases*/ - -/** -* @} -*/ - - -/** @defgroup USBH_MSC_BOT_Private_FunctionPrototypes -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBH_MSC_BOT_Exported_Variables -* @{ -*/ -USBH_BOTXfer_TypeDef USBH_MSC_BOTXferParam; -/** -* @} -*/ - - -/** @defgroup USBH_MSC_BOT_Private_Functions -* @{ -*/ - - -/** -* @brief USBH_MSC_Init -* Initializes the mass storage parameters -* @param None -* @retval None -*/ -void USBH_MSC_Init(USB_OTG_CORE_HANDLE *pdev ) -{ - if(HCD_IsDeviceConnected(pdev)) - { - USBH_MSC_CBWData.field.CBWSignature = USBH_MSC_BOT_CBW_SIGNATURE; - USBH_MSC_CBWData.field.CBWTag = USBH_MSC_BOT_CBW_TAG; - USBH_MSC_CBWData.field.CBWLUN = 0; /*Only one LUN is supported*/ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - } - - BOTStallErrorCount = 0; - MSCErrorCount = 0; -} - -/** -* @brief USBH_MSC_HandleBOTXfer -* This function manages the different states of BOT transfer and -* updates the status to upper layer. -* @param None -* @retval None -* -*/ -void USBH_MSC_HandleBOTXfer (USB_OTG_CORE_HANDLE *pdev ,USBH_HOST *phost) -{ - uint8_t xferDirection, index; - static uint32_t remainingDataLength; - static uint8_t *datapointer; - static uint8_t error_direction; - USBH_Status status; - - URB_STATE URB_Status = URB_IDLE; - - if(HCD_IsDeviceConnected(pdev)) - { - - switch (USBH_MSC_BOTXferParam.BOTState) - { - case USBH_MSC_SEND_CBW: - /* send CBW */ - USBH_BulkSendData (pdev, - &USBH_MSC_CBWData.CBWArray[0], - USBH_MSC_BOT_CBW_PACKET_LENGTH , - MSC_Machine.hc_num_out); - - USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_SEND_CBW; - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SENT_CBW; - - break; - - case USBH_MSC_SENT_CBW: - URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_out); - - if(URB_Status == URB_DONE) - { - BOTStallErrorCount = 0; - USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_SENT_CBW; - - /* If the CBW Pkt is sent successful, then change the state */ - xferDirection = (USBH_MSC_CBWData.field.CBWFlags & USB_REQ_DIR_MASK); - - if ( USBH_MSC_CBWData.field.CBWTransferLength != 0 ) - { - remainingDataLength = USBH_MSC_CBWData.field.CBWTransferLength ; - datapointer = USBH_MSC_BOTXferParam.pRxTxBuff; - - /* If there is Data Transfer Stage */ - if (xferDirection == USB_D2H) - { - /* Data Direction is IN */ - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_DATAIN_STATE; - } - else - { - /* Data Direction is OUT */ - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_DATAOUT_STATE; - } - } - - else - {/* If there is NO Data Transfer Stage */ - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE; - } - - } - else if(URB_Status == URB_NOTREADY) - { - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp; - } - else if(URB_Status == URB_STALL) - { - error_direction = USBH_MSC_DIR_OUT; - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_OUT; - } - break; - - case USBH_MSC_BOT_DATAIN_STATE: - - URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_in); - /* BOT DATA IN stage */ - if((URB_Status == URB_DONE) ||(USBH_MSC_BOTXferParam.BOTStateBkp != USBH_MSC_BOT_DATAIN_STATE)) - { - BOTStallErrorCount = 0; - USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_BOT_DATAIN_STATE; - - if(remainingDataLength > USBH_MSC_MPS_SIZE) - { - USBH_BulkReceiveData (pdev, - datapointer, - USBH_MSC_MPS_SIZE , - MSC_Machine.hc_num_in); - - remainingDataLength -= USBH_MSC_MPS_SIZE; - datapointer = datapointer + USBH_MSC_MPS_SIZE; - } - else if ( remainingDataLength == 0) - { - /* If value was 0, and successful transfer, then change the state */ - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE; - } - else - { - USBH_BulkReceiveData (pdev, - datapointer, - remainingDataLength , - MSC_Machine.hc_num_in); - - remainingDataLength = 0; /* Reset this value and keep in same state */ - } - } - else if(URB_Status == URB_STALL) - { - /* This is Data Stage STALL Condition */ - - error_direction = USBH_MSC_DIR_IN; - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_IN; - - /* Refer to USB Mass-Storage Class : BOT (www.usb.org) - 6.7.2 Host expects to receive data from the device - 3. On a STALL condition receiving data, then: - The host shall accept the data received. - The host shall clear the Bulk-In pipe. - 4. The host shall attempt to receive a CSW. - - USBH_MSC_BOTXferParam.BOTStateBkp is used to switch to the Original - state after the ClearFeature Command is issued. - */ - USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE; - - } - break; - - - case USBH_MSC_BOT_DATAOUT_STATE: - /* BOT DATA OUT stage */ - URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_out); - if(URB_Status == URB_DONE) - { - BOTStallErrorCount = 0; - USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_BOT_DATAOUT_STATE; - if(remainingDataLength > USBH_MSC_MPS_SIZE) - { - USBH_BulkSendData (pdev, - datapointer, - USBH_MSC_MPS_SIZE , - MSC_Machine.hc_num_out); - datapointer = datapointer + USBH_MSC_MPS_SIZE; - remainingDataLength = remainingDataLength - USBH_MSC_MPS_SIZE; - } - else if ( remainingDataLength == 0) - { - /* If value was 0, and successful transfer, then change the state */ - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE; - } - else - { - USBH_BulkSendData (pdev, - datapointer, - remainingDataLength , - MSC_Machine.hc_num_out); - - remainingDataLength = 0; /* Reset this value and keep in same state */ - } - } - - else if(URB_Status == URB_NOTREADY) - { - USBH_BulkSendData (pdev, - (datapointer - USBH_MSC_MPS_SIZE), - USBH_MSC_MPS_SIZE , - MSC_Machine.hc_num_out); - } - - else if(URB_Status == URB_STALL) - { - error_direction = USBH_MSC_DIR_OUT; - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_OUT; - - /* Refer to USB Mass-Storage Class : BOT (www.usb.org) - 6.7.3 Ho - Host expects to send data to the device - 3. On a STALL condition sending data, then: - " The host shall clear the Bulk-Out pipe. - 4. The host shall attempt to receive a CSW. - - The Above statement will do the clear the Bulk-Out pipe. - The Below statement will help in Getting the CSW. - - USBH_MSC_BOTXferParam.BOTStateBkp is used to switch to the Original - state after the ClearFeature Command is issued. - */ - - USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE; - - } - break; - - case USBH_MSC_RECEIVE_CSW_STATE: - /* BOT CSW stage */ - /* NOTE: We cannot reset the BOTStallErrorCount here as it may come from - the clearFeature from previous command */ - - USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE; - - USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray; - USBH_MSC_BOTXferParam.DataLength = USBH_MSC_CSW_MAX_LENGTH; - - for(index = USBH_MSC_CSW_LENGTH; index != 0; index--) - { - USBH_MSC_CSWData.CSWArray[index] = 0; - } - - USBH_MSC_CSWData.CSWArray[0] = 0; - - USBH_BulkReceiveData (pdev, - USBH_MSC_BOTXferParam.pRxTxBuff, - USBH_MSC_CSW_MAX_LENGTH , - MSC_Machine.hc_num_in); - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_DECODE_CSW; - - break; - - case USBH_MSC_DECODE_CSW: - URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_in); - /* Decode CSW */ - if(URB_Status == URB_DONE) - { - BOTStallErrorCount = 0; - USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE; - - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateCurrent ; - - USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_DecodeCSW(pdev , phost); - } - else if(URB_Status == URB_STALL) - { - error_direction = USBH_MSC_DIR_IN; - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_IN; - } - break; - - case USBH_MSC_BOT_ERROR_IN: - status = USBH_MSC_BOT_Abort(pdev, phost, USBH_MSC_DIR_IN); - if (status == USBH_OK) - { - /* Check if the error was due in Both the directions */ - if (error_direction == USBH_MSC_BOTH_DIR) - {/* If Both directions are Needed, Switch to OUT Direction */ - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_OUT; - } - else - { - /* Switch Back to the Original State, In many cases this will be - USBH_MSC_RECEIVE_CSW_STATE state */ - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp; - } - } - else if (status == USBH_UNRECOVERED_ERROR) - { - /* This means that there is a STALL Error limit, Do Reset Recovery */ - USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_PHASE_ERROR; - } - break; - - case USBH_MSC_BOT_ERROR_OUT: - status = USBH_MSC_BOT_Abort(pdev, phost, USBH_MSC_DIR_OUT); - if ( status == USBH_OK) - { /* Switch Back to the Original State */ - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp; - } - else if (status == USBH_UNRECOVERED_ERROR) - { - /* This means that there is a STALL Error limit, Do Reset Recovery */ - USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_PHASE_ERROR; - } - break; - - default: - break; - } - } -} - -/** -* @brief USBH_MSC_BOT_Abort -* This function manages the different Error handling for STALL -* @param direction : IN / OUT -* @retval None -*/ -USBH_Status USBH_MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t direction) -{ - USBH_Status status; - - status = USBH_BUSY; - - switch (direction) - { - case USBH_MSC_DIR_IN : - /* send ClrFeture on Bulk IN endpoint */ - status = USBH_ClrFeature(pdev, - phost, - MSC_Machine.MSBulkInEp, - MSC_Machine.hc_num_in); - - break; - - case USBH_MSC_DIR_OUT : - /*send ClrFeature on Bulk OUT endpoint */ - status = USBH_ClrFeature(pdev, - phost, - MSC_Machine.MSBulkOutEp, - MSC_Machine.hc_num_out); - break; - - default: - break; - } - - BOTStallErrorCount++; /* Check Continous Number of times, STALL has Occured */ - if (BOTStallErrorCount > MAX_BULK_STALL_COUNT_LIMIT ) - { - status = USBH_UNRECOVERED_ERROR; - } - - return status; -} - -/** -* @brief USBH_MSC_DecodeCSW -* This function decodes the CSW received by the device and updates the -* same to upper layer. -* @param None -* @retval On success USBH_MSC_OK, on failure USBH_MSC_FAIL -* @notes -* Refer to USB Mass-Storage Class : BOT (www.usb.org) -* 6.3.1 Valid CSW Conditions : -* The host shall consider the CSW valid when: -* 1. dCSWSignature is equal to 53425355h -* 2. the CSW is 13 (Dh) bytes in length, -* 3. dCSWTag matches the dCBWTag from the corresponding CBW. -*/ - -uint8_t USBH_MSC_DecodeCSW(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost) -{ - uint8_t status; - uint32_t dataXferCount = 0; - status = USBH_MSC_FAIL; - - if(HCD_IsDeviceConnected(pdev)) - { - /*Checking if the transfer length is diffrent than 13*/ - dataXferCount = HCD_GetXferCnt(pdev, MSC_Machine.hc_num_in); - - if(dataXferCount != USBH_MSC_CSW_LENGTH) - { - /*(4) Hi > Dn (Host expects to receive data from the device, - Device intends to transfer no data) - (5) Hi > Di (Host expects to receive data from the device, - Device intends to send data to the host) - (9) Ho > Dn (Host expects to send data to the device, - Device intends to transfer no data) - (11) Ho > Do (Host expects to send data to the device, - Device intends to receive data from the host)*/ - - - status = USBH_MSC_PHASE_ERROR; - } - else - { /* CSW length is Correct */ - - /* Check validity of the CSW Signature and CSWStatus */ - if(USBH_MSC_CSWData.field.CSWSignature == USBH_MSC_BOT_CSW_SIGNATURE) - {/* Check Condition 1. dCSWSignature is equal to 53425355h */ - - if(USBH_MSC_CSWData.field.CSWTag == USBH_MSC_CBWData.field.CBWTag) - { - /* Check Condition 3. dCSWTag matches the dCBWTag from the - corresponding CBW */ - - if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_OK) - { - /* Refer to USB Mass-Storage Class : BOT (www.usb.org) - - Hn Host expects no data transfers - Hi Host expects to receive data from the device - Ho Host expects to send data to the device - - Dn Device intends to transfer no data - Di Device intends to send data to the host - Do Device intends to receive data from the host - - Section 6.7 - (1) Hn = Dn (Host expects no data transfers, - Device intends to transfer no data) - (6) Hi = Di (Host expects to receive data from the device, - Device intends to send data to the host) - (12) Ho = Do (Host expects to send data to the device, - Device intends to receive data from the host) - - */ - - status = USBH_MSC_OK; - } - else if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_FAIL) - { - status = USBH_MSC_FAIL; - } - - else if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_PHASE_ERROR) - { - /* Refer to USB Mass-Storage Class : BOT (www.usb.org) - Section 6.7 - (2) Hn < Di ( Host expects no data transfers, - Device intends to send data to the host) - (3) Hn < Do ( Host expects no data transfers, - Device intends to receive data from the host) - (7) Hi < Di ( Host expects to receive data from the device, - Device intends to send data to the host) - (8) Hi <> Do ( Host expects to receive data from the device, - Device intends to receive data from the host) - (10) Ho <> Di (Host expects to send data to the device, - Di Device intends to send data to the host) - (13) Ho < Do (Host expects to send data to the device, - Device intends to receive data from the host) - */ - - status = USBH_MSC_PHASE_ERROR; - } - } /* CSW Tag Matching is Checked */ - } /* CSW Signature Correct Checking */ - else - { - /* If the CSW Signature is not valid, We sall return the Phase Error to - Upper Layers for Reset Recovery */ - - status = USBH_MSC_PHASE_ERROR; - } - } /* CSW Length Check*/ - } - - USBH_MSC_BOTXferParam.BOTXferStatus = status; - return status; -} - - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_core.c b/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_core.c deleted file mode 100644 index 466399e90..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_core.c +++ /dev/null @@ -1,559 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_msc_core.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file implements the MSC class driver functions - * =================================================================== - * MSC Class Description - * =================================================================== - * This module manages the MSC class V1.0 following the "Universal - * Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0 - * Sep. 31, 1999". - * This driver implements the following aspects of the specification: - * - Bulk-Only Transport protocol - * - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3)) - * - * @endverbatim - * - ****************************************************************************** - * @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 2011 STMicroelectronics

-*/ - -/* Includes ------------------------------------------------------------------*/ - -#include "usbh_msc_core.h" -#include "usbh_msc_scsi.h" -#include "usbh_msc_bot.h" -#include "usbh_core.h" - - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_CLASS - * @{ - */ - -/** @addtogroup USBH_MSC_CLASS - * @{ - */ - -/** @defgroup USBH_MSC_CORE - * @brief This file includes the mass storage related functions - * @{ - */ - - -/** @defgroup USBH_MSC_CORE_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_MSC_CORE_Private_Defines - * @{ - */ -#define USBH_MSC_ERROR_RETRY_LIMIT 10 -/** - * @} - */ - -/** @defgroup USBH_MSC_CORE_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_MSC_CORE_Private_Variables - * @{ - */ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN MSC_Machine_TypeDef MSC_Machine __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN USB_Setup_TypeDef MSC_Setup __ALIGN_END ; -uint8_t MSCErrorCount = 0; - - -/** - * @} - */ - - -/** @defgroup USBH_MSC_CORE_Private_FunctionPrototypes - * @{ - */ - -static USBH_Status USBH_MSC_InterfaceInit (USB_OTG_CORE_HANDLE *pdev , - void *phost); - -static void USBH_MSC_InterfaceDeInit (USB_OTG_CORE_HANDLE *pdev , - void *phost); - -static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev , - void *phost); - -static USBH_Status USBH_MSC_ClassRequest(USB_OTG_CORE_HANDLE *pdev , - void *phost); - -static USBH_Status USBH_MSC_BOTReset(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost); -static USBH_Status USBH_MSC_GETMaxLUN(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost); - - -USBH_Class_cb_TypeDef USBH_MSC_cb = -{ - USBH_MSC_InterfaceInit, - USBH_MSC_InterfaceDeInit, - USBH_MSC_ClassRequest, - USBH_MSC_Handle, -}; - -void USBH_MSC_ErrorHandle(uint8_t status); - -/** - * @} - */ - - -/** @defgroup USBH_MSC_CORE_Exported_Variables - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBH_MSC_CORE_Private_Functions - * @{ - */ - - -/** - * @brief USBH_MSC_InterfaceInit - * Interface initialization for MSC class. - * @param pdev: Selected device - * @param hdev: Selected device property - * @retval USBH_Status : Status of class request handled. - */ -static USBH_Status USBH_MSC_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev, - void *phost) -{ - USBH_HOST *pphost = phost; - - if((pphost->device_prop.Itf_Desc[0].bInterfaceClass == MSC_CLASS) && \ - (pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == MSC_PROTOCOL)) - { - if(pphost->device_prop.Ep_Desc[0][0].bEndpointAddress & 0x80) - { - MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress); - MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize; - } - else - { - MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress); - MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0] [0].wMaxPacketSize; - } - - if(pphost->device_prop.Ep_Desc[0][1].bEndpointAddress & 0x80) - { - MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress); - MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize; - } - else - { - MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress); - MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize; - } - - MSC_Machine.hc_num_out = USBH_Alloc_Channel(pdev, - MSC_Machine.MSBulkOutEp); - MSC_Machine.hc_num_in = USBH_Alloc_Channel(pdev, - MSC_Machine.MSBulkInEp); - - /* Open the new channels */ - USBH_Open_Channel (pdev, - MSC_Machine.hc_num_out, - pphost->device_prop.address, - pphost->device_prop.speed, - EP_TYPE_BULK, - MSC_Machine.MSBulkOutEpSize); - - USBH_Open_Channel (pdev, - MSC_Machine.hc_num_in, - pphost->device_prop.address, - pphost->device_prop.speed, - EP_TYPE_BULK, - MSC_Machine.MSBulkInEpSize); - - } - - else - { - pphost->usr_cb->USBH_USR_DeviceNotSupported(); - } - - return USBH_OK ; - -} - - -/** - * @brief USBH_MSC_InterfaceDeInit - * De-Initialize interface by freeing host channels allocated to interface - * @param pdev: Selected device - * @param hdev: Selected device property - * @retval None - */ -void USBH_MSC_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev, - void *phost) -{ - if ( MSC_Machine.hc_num_out) - { - USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_out); - USBH_Free_Channel (pdev, MSC_Machine.hc_num_out); - MSC_Machine.hc_num_out = 0; /* Reset the Channel as Free */ - } - - if ( MSC_Machine.hc_num_in) - { - USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_in); - USBH_Free_Channel (pdev, MSC_Machine.hc_num_in); - MSC_Machine.hc_num_in = 0; /* Reset the Channel as Free */ - } -} - -/** - * @brief USBH_MSC_ClassRequest - * This function will only initialize the MSC state machine - * @param pdev: Selected device - * @param hdev: Selected device property - * @retval USBH_Status : Status of class request handled. - */ - -static USBH_Status USBH_MSC_ClassRequest(USB_OTG_CORE_HANDLE *pdev , - void *phost) -{ - - USBH_Status status = USBH_OK ; - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_INIT_STATE; - - return status; -} - - -/** - * @brief USBH_MSC_Handle - * MSC state machine handler - * @param pdev: Selected device - * @param hdev: Selected device property - * @retval USBH_Status - */ - -static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev , - void *phost) -{ - USBH_HOST *pphost = phost; - - USBH_Status status = USBH_BUSY; - uint8_t mscStatus = USBH_MSC_BUSY; - uint8_t appliStatus = 0; - - static uint8_t maxLunExceed = FALSE; - - - if(HCD_IsDeviceConnected(pdev)) - { - switch(USBH_MSC_BOTXferParam.MSCState) - { - case USBH_MSC_BOT_INIT_STATE: - USBH_MSC_Init(pdev); - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_RESET; - break; - - case USBH_MSC_BOT_RESET: - /* Issue BOT RESET request */ - status = USBH_MSC_BOTReset(pdev, phost); - if(status == USBH_OK ) - { - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_GET_MAX_LUN; - } - - if(status == USBH_NOT_SUPPORTED ) - { - /* If the Command has failed, then we need to move to Next State, after - STALL condition is cleared by Control-Transfer */ - USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_GET_MAX_LUN; - - /* a Clear Feature should be issued here */ - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_CTRL_ERROR_STATE; - } - break; - - case USBH_MSC_GET_MAX_LUN: - /* Issue GetMaxLUN request */ - status = USBH_MSC_GETMaxLUN(pdev, phost); - - if(status == USBH_OK ) - { - MSC_Machine.maxLun = *(MSC_Machine.buff) ; - - /* If device has more that one logical unit then it is not supported */ - if((MSC_Machine.maxLun > 0) && (maxLunExceed == FALSE)) - { - maxLunExceed = TRUE; - pphost->usr_cb->USBH_USR_DeviceNotSupported(); - - break; - } - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_TEST_UNIT_READY; - } - - if(status == USBH_NOT_SUPPORTED ) - { - /* If the Command has failed, then we need to move to Next State, after - STALL condition is cleared by Control-Transfer */ - USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_TEST_UNIT_READY; - - /* a Clear Feature should be issued here */ - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_CTRL_ERROR_STATE; - } - break; - - case USBH_MSC_CTRL_ERROR_STATE: - /* Issue Clearfeature request */ - status = USBH_ClrFeature(pdev, - phost, - 0x00, - pphost->Control.hc_num_out); - if(status == USBH_OK ) - { - /* If GetMaxLun Request not support, assume Single LUN configuration */ - MSC_Machine.maxLun = 0; - - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp; - } - break; - - case USBH_MSC_TEST_UNIT_READY: - /* Issue SCSI command TestUnitReady */ - mscStatus = USBH_MSC_TestUnitReady(pdev); - - if(mscStatus == USBH_MSC_OK ) - { - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_READ_CAPACITY10; - MSCErrorCount = 0; - status = USBH_OK; - } - else - { - USBH_MSC_ErrorHandle(mscStatus); - } - break; - - case USBH_MSC_READ_CAPACITY10: - /* Issue READ_CAPACITY10 SCSI command */ - mscStatus = USBH_MSC_ReadCapacity10(pdev); - if(mscStatus == USBH_MSC_OK ) - { - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_MODE_SENSE6; - MSCErrorCount = 0; - status = USBH_OK; - } - else - { - USBH_MSC_ErrorHandle(mscStatus); - } - break; - - case USBH_MSC_MODE_SENSE6: - /* Issue ModeSense6 SCSI command for detecting if device is write-protected */ - mscStatus = USBH_MSC_ModeSense6(pdev); - if(mscStatus == USBH_MSC_OK ) - { - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_DEFAULT_APPLI_STATE; - MSCErrorCount = 0; - status = USBH_OK; - } - else - { - USBH_MSC_ErrorHandle(mscStatus); - } - break; - - case USBH_MSC_REQUEST_SENSE: - /* Issue RequestSense SCSI command for retreiving error code */ - mscStatus = USBH_MSC_RequestSense(pdev); - if(mscStatus == USBH_MSC_OK ) - { - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp; - status = USBH_OK; - } - else - { - USBH_MSC_ErrorHandle(mscStatus); - } - break; - - case USBH_MSC_BOT_USB_TRANSFERS: - /* Process the BOT state machine */ - USBH_MSC_HandleBOTXfer(pdev , phost); - break; - - case USBH_MSC_DEFAULT_APPLI_STATE: - /* Process Application callback for MSC */ - appliStatus = pphost->usr_cb->USBH_USR_MSC_Application(); - if(appliStatus == 0) - { - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_DEFAULT_APPLI_STATE; - } - else if (appliStatus == 1) - { - /* De-init requested from application layer */ - status = USBH_APPLY_DEINIT; - } - break; - - case USBH_MSC_UNRECOVERED_STATE: - - status = USBH_UNRECOVERED_ERROR; - - break; - - default: - break; - - } - } - return status; -} - - - -/** - * @brief USBH_MSC_BOTReset - * This request is used to reset the mass storage device and its - * associated interface. This class-specific request shall ready the - * device for the next CBW from the host. - * @param pdev: Selected device - * @retval USBH_Status : Status of class request handled. - */ -static USBH_Status USBH_MSC_BOTReset(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost) -{ - - phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS | \ - USB_REQ_RECIPIENT_INTERFACE; - - phost->Control.setup.b.bRequest = USB_REQ_BOT_RESET; - phost->Control.setup.b.wValue.w = 0; - phost->Control.setup.b.wIndex.w = 0; - phost->Control.setup.b.wLength.w = 0; - - return USBH_CtlReq(pdev, phost, 0 , 0 ); -} - - -/** - * @brief USBH_MSC_GETMaxLUN - * This request is used to reset the mass storage device and its - * associated interface. This class-specific request shall ready the - * device for the next CBW from the host. - * @param pdev: Selected device - * @retval USBH_Status : USB ctl xfer status - */ -static USBH_Status USBH_MSC_GETMaxLUN(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost) -{ - phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_CLASS | \ - USB_REQ_RECIPIENT_INTERFACE; - - phost->Control.setup.b.bRequest = USB_REQ_GET_MAX_LUN; - phost->Control.setup.b.wValue.w = 0; - phost->Control.setup.b.wIndex.w = 0; - phost->Control.setup.b.wLength.w = 1; - - return USBH_CtlReq(pdev, phost, MSC_Machine.buff , 1 ); -} - -/** - * @brief USBH_MSC_ErrorHandle - * The function is for handling errors occuring during the MSC - * state machine - * @param status - * @retval None - */ - -void USBH_MSC_ErrorHandle(uint8_t status) -{ - if(status == USBH_MSC_FAIL) - { - MSCErrorCount++; - if(MSCErrorCount < USBH_MSC_ERROR_RETRY_LIMIT) - { /* Try MSC level error recovery, Issue the request Sense to get - Drive error reason */ - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_REQUEST_SENSE; - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - } - else - { - /* Error trials exceeded the limit, go to unrecovered state */ - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_UNRECOVERED_STATE; - } - } - else if(status == USBH_MSC_PHASE_ERROR) - { - /* Phase error, Go to Unrecoovered state */ - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_UNRECOVERED_STATE; - } - else if(status == USBH_MSC_BUSY) - { - /*No change in state*/ - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_fatfs.c b/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_fatfs.c deleted file mode 100644 index 57a3c9c0f..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_fatfs.c +++ /dev/null @@ -1,186 +0,0 @@ - -#include "usb_conf.h" -#include "diskio.h" -#include "usbh_msc_core.h" -/*-------------------------------------------------------------------------- - -Module Private Functions and Variables - ----------------------------------------------------------------------------*/ - -static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */ - -extern USB_OTG_CORE_HANDLE USB_OTG_Core; -extern USBH_HOST USB_Host; - -/*-----------------------------------------------------------------------*/ -/* Initialize Disk Drive */ -/*-----------------------------------------------------------------------*/ - -DSTATUS disk_initialize ( - BYTE drv /* Physical drive number (0) */ - ) -{ - - if(HCD_IsDeviceConnected(&USB_OTG_Core)) - { - Stat &= ~STA_NOINIT; - } - - return Stat; - - -} - - - -/*-----------------------------------------------------------------------*/ -/* Get Disk Status */ -/*-----------------------------------------------------------------------*/ - -DSTATUS disk_status ( - BYTE drv /* Physical drive number (0) */ - ) -{ - if (drv) return STA_NOINIT; /* Supports only single drive */ - return Stat; -} - - - -/*-----------------------------------------------------------------------*/ -/* Read Sector(s) */ -/*-----------------------------------------------------------------------*/ - -DRESULT disk_read ( - BYTE drv, /* Physical drive number (0) */ - BYTE *buff, /* Pointer to the data buffer to store read data */ - DWORD sector, /* Start sector number (LBA) */ - BYTE count /* Sector count (1..255) */ - ) -{ - BYTE status = USBH_MSC_OK; - - if (drv || !count) return RES_PARERR; - if (Stat & STA_NOINIT) return RES_NOTRDY; - - - if(HCD_IsDeviceConnected(&USB_OTG_Core)) - { - - do - { - status = USBH_MSC_Read10(&USB_OTG_Core, buff,sector,512); - USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host); - - if(!HCD_IsDeviceConnected(&USB_OTG_Core)) - { - return RES_ERROR; - } - } - while(status == USBH_MSC_BUSY ); - } - - if(status == USBH_MSC_OK) - return RES_OK; - return RES_ERROR; - -} - - - -/*-----------------------------------------------------------------------*/ -/* Write Sector(s) */ -/*-----------------------------------------------------------------------*/ - -#if _READONLY == 0 -DRESULT disk_write ( - BYTE drv, /* Physical drive number (0) */ - const BYTE *buff, /* Pointer to the data to be written */ - DWORD sector, /* Start sector number (LBA) */ - BYTE count /* Sector count (1..255) */ - ) -{ - BYTE status = USBH_MSC_OK; - if (drv || !count) return RES_PARERR; - if (Stat & STA_NOINIT) return RES_NOTRDY; - if (Stat & STA_PROTECT) return RES_WRPRT; - - - if(HCD_IsDeviceConnected(&USB_OTG_Core)) - { - do - { - status = USBH_MSC_Write10(&USB_OTG_Core,(BYTE*)buff,sector,512); - USBH_MSC_HandleBOTXfer(&USB_OTG_Core, &USB_Host); - - if(!HCD_IsDeviceConnected(&USB_OTG_Core)) - { - return RES_ERROR; - } - } - - while(status == USBH_MSC_BUSY ); - - } - - if(status == USBH_MSC_OK) - return RES_OK; - return RES_ERROR; -} -#endif /* _READONLY == 0 */ - - - -/*-----------------------------------------------------------------------*/ -/* Miscellaneous Functions */ -/*-----------------------------------------------------------------------*/ - -#if _USE_IOCTL != 0 -DRESULT disk_ioctl ( - BYTE drv, /* Physical drive number (0) */ - BYTE ctrl, /* Control code */ - void *buff /* Buffer to send/receive control data */ - ) -{ - DRESULT res = RES_OK; - - if (drv) return RES_PARERR; - - res = RES_ERROR; - - if (Stat & STA_NOINIT) return RES_NOTRDY; - - switch (ctrl) { - case CTRL_SYNC : /* Make sure that no pending write process */ - - res = RES_OK; - break; - - case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ - - *(DWORD*)buff = (DWORD) USBH_MSC_Param.MSCapacity; - res = RES_OK; - break; - - case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */ - *(WORD*)buff = 512; - res = RES_OK; - break; - - case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */ - - *(DWORD*)buff = 512; - - break; - - - default: - res = RES_PARERR; - } - - - - return res; -} -#endif /* _USE_IOCTL != 0 */ diff --git a/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_scsi.c b/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_scsi.c deleted file mode 100644 index f6bb7c4c2..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_scsi.c +++ /dev/null @@ -1,674 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_msc_scsi.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file implements the SCSI commands - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbh_msc_core.h" -#include "usbh_msc_scsi.h" -#include "usbh_msc_bot.h" -#include "usbh_ioreq.h" -#include "usbh_def.h" - - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_CLASS - * @{ - */ - -/** @addtogroup USBH_MSC_CLASS - * @{ - */ - -/** @defgroup USBH_MSC_SCSI - * @brief This file includes the mass storage related functions - * @{ - */ - - -/** @defgroup USBH_MSC_SCSI_Private_TypesDefinitions - * @{ - */ - -MassStorageParameter_TypeDef USBH_MSC_Param; -/** - * @} - */ - -/** @defgroup USBH_MSC_SCSI_Private_Defines - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_MSC_SCSI_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_MSC_SCSI_Private_Variables - * @{ - */ - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t USBH_DataInBuffer[512] __ALIGN_END ; - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 - #endif -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ -__ALIGN_BEGIN uint8_t USBH_DataOutBuffer[512] __ALIGN_END ; -/** - * @} - */ - - -/** @defgroup USBH_MSC_SCSI_Private_FunctionPrototypes - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_MSC_SCSI_Exported_Variables - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBH_MSC_SCSI_Private_Functions - * @{ - */ - - - - -/** - * @brief USBH_MSC_TestUnitReady - * Issues 'Test unit ready' command to the device. Once the response - * received, it updates the status to upper layer. - * @param None - * @retval Status - */ -uint8_t USBH_MSC_TestUnitReady (USB_OTG_CORE_HANDLE *pdev) -{ - uint8_t index; - USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY; - - if(HCD_IsDeviceConnected(pdev)) - { - switch(USBH_MSC_BOTXferParam.CmdStateMachine) - { - case CMD_SEND_STATE: - /*Prepare the CBW and relevent field*/ - USBH_MSC_CBWData.field.CBWTransferLength = 0; /* No Data Transfer */ - USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT; - USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH_TEST_UNIT_READY; - USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray; - USBH_MSC_BOTXferParam.DataLength = USBH_MSC_CSW_MAX_LENGTH; - USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_TEST_UNIT_READY; - - for(index = CBW_CB_LENGTH; index != 0; index--) - { - USBH_MSC_CBWData.field.CBWCB[index] = 0x00; - } - - USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_TEST_UNIT_READY; - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW; - /* Start the transfer, then let the state - machine magage the other transactions */ - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS; - USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY; - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS; - - status = USBH_MSC_BUSY; - break; - - case CMD_WAIT_STATUS: - if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) - { - /* Commands successfully sent and Response Received */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - - status = USBH_MSC_OK; - } - else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) - { - /* Failure Mode */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_FAIL; - } - - else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR ) - { - /* Failure Mode */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_PHASE_ERROR; - } - break; - - default: - break; - } - } - return status; -} - - -/** - * @brief USBH_MSC_ReadCapacity10 - * Issue the read capacity command to the device. Once the response - * received, it updates the status to upper layer - * @param None - * @retval Status - */ -uint8_t USBH_MSC_ReadCapacity10(USB_OTG_CORE_HANDLE *pdev) -{ - uint8_t index; - USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY; - - if(HCD_IsDeviceConnected(pdev)) - { - switch(USBH_MSC_BOTXferParam.CmdStateMachine) - { - case CMD_SEND_STATE: - /*Prepare the CBW and relevent field*/ - USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_READ_CAPACITY10; - USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; - USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; - - USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer; - USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_READ_CAPACITY10; - - for(index = CBW_CB_LENGTH; index != 0; index--) - { - USBH_MSC_CBWData.field.CBWCB[index] = 0x00; - } - - USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ_CAPACITY10; - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW; - - /* Start the transfer, then let the state machine manage the other - transactions */ - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS; - USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY; - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS; - - status = USBH_MSC_BUSY; - break; - - case CMD_WAIT_STATUS: - if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) - { - /*assign the capacity*/ - (((uint8_t*)&USBH_MSC_Param.MSCapacity )[3]) = USBH_DataInBuffer[0]; - (((uint8_t*)&USBH_MSC_Param.MSCapacity )[2]) = USBH_DataInBuffer[1]; - (((uint8_t*)&USBH_MSC_Param.MSCapacity )[1]) = USBH_DataInBuffer[2]; - (((uint8_t*)&USBH_MSC_Param.MSCapacity )[0]) = USBH_DataInBuffer[3]; - - /*assign the page length*/ - (((uint8_t*)&USBH_MSC_Param.MSPageLength )[1]) = USBH_DataInBuffer[6]; - (((uint8_t*)&USBH_MSC_Param.MSPageLength )[0]) = USBH_DataInBuffer[7]; - - /* Commands successfully sent and Response Received */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_OK; - } - else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) - { - /* Failure Mode */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_FAIL; - } - else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR ) - { - /* Failure Mode */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_PHASE_ERROR; - } - else - { - /* Wait for the Commands to get Completed */ - /* NO Change in state Machine */ - } - break; - - default: - break; - } - } - return status; -} - - -/** - * @brief USBH_MSC_ModeSense6 - * Issue the Mode Sense6 Command to the device. This function is used - * for reading the WriteProtect Status of the Mass-Storage device. - * @param None - * @retval Status - */ -uint8_t USBH_MSC_ModeSense6(USB_OTG_CORE_HANDLE *pdev) -{ - uint8_t index; - USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY; - - if(HCD_IsDeviceConnected(pdev)) - { - switch(USBH_MSC_BOTXferParam.CmdStateMachine) - { - case CMD_SEND_STATE: - /*Prepare the CBW and relevent field*/ - USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_MODE_SENSE6; - USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; - USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; - - USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer; - USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_MODE_SENSE6; - - for(index = CBW_CB_LENGTH; index != 0; index--) - { - USBH_MSC_CBWData.field.CBWCB[index] = 0x00; - } - - USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_MODE_SENSE6; - USBH_MSC_CBWData.field.CBWCB[2] = MODE_SENSE_PAGE_CONTROL_FIELD | \ - MODE_SENSE_PAGE_CODE; - - USBH_MSC_CBWData.field.CBWCB[4] = XFER_LEN_MODE_SENSE6; - - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW; - - /* Start the transfer, then let the state machine manage the other - transactions */ - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS; - USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY; - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS; - - status = USBH_MSC_BUSY; - break; - - case CMD_WAIT_STATUS: - if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) - { - /* Assign the Write Protect status */ - /* If WriteProtect = 0, Writing is allowed - If WriteProtect != 0, Disk is Write Protected */ - if ( USBH_DataInBuffer[2] & MASK_MODE_SENSE_WRITE_PROTECT) - { - USBH_MSC_Param.MSWriteProtect = DISK_WRITE_PROTECTED; - } - else - { - USBH_MSC_Param.MSWriteProtect = 0; - } - - /* Commands successfully sent and Response Received */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_OK; - } - else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) - { - /* Failure Mode */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_FAIL; - } - else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR ) - { - /* Failure Mode */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_PHASE_ERROR; - } - else - { - /* Wait for the Commands to get Completed */ - /* NO Change in state Machine */ - } - break; - - default: - break; - } - } - return status; -} - -/** - * @brief USBH_MSC_RequestSense - * Issues the Request Sense command to the device. Once the response - * received, it updates the status to upper layer - * @param None - * @retval Status - */ -uint8_t USBH_MSC_RequestSense(USB_OTG_CORE_HANDLE *pdev) -{ - USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY; - - uint8_t index; - - - if(HCD_IsDeviceConnected(pdev)) - { - switch(USBH_MSC_BOTXferParam.CmdStateMachine) - { - case CMD_SEND_STATE: - - /*Prepare the CBW and relevent field*/ - USBH_MSC_CBWData.field.CBWTransferLength = \ - ALLOCATION_LENGTH_REQUEST_SENSE; - USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; - USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; - - USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer; - USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_BOTXferParam.MSCStateCurrent; - USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_REQUEST_SENSE; - - - for(index = CBW_CB_LENGTH; index != 0; index--) - { - USBH_MSC_CBWData.field.CBWCB[index] = 0x00; - } - - USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_REQUEST_SENSE; - USBH_MSC_CBWData.field.CBWCB[1] = DESC_REQUEST_SENSE; - USBH_MSC_CBWData.field.CBWCB[4] = ALLOCATION_LENGTH_REQUEST_SENSE; - - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW; - /* Start the transfer, then let the state machine magage - the other transactions */ - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS; - USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY; - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS; - - status = USBH_MSC_BUSY; - - break; - - case CMD_WAIT_STATUS: - - if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) - { - /* Get Sense data*/ - (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[3]) = USBH_DataInBuffer[0]; - (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[2]) = USBH_DataInBuffer[1]; - (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[1]) = USBH_DataInBuffer[2]; - (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[0]) = USBH_DataInBuffer[3]; - - /* Commands successfully sent and Response Received */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_OK; - } - else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) - { - /* Failure Mode */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_FAIL; - } - - else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR ) - { - /* Failure Mode */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_PHASE_ERROR; - } - - else - { - /* Wait for the Commands to get Completed */ - /* NO Change in state Machine */ - } - break; - - default: - break; - } - } - return status; -} - - -/** - * @brief USBH_MSC_Write10 - * Issue the write command to the device. Once the response received, - * it updates the status to upper layer - * @param dataBuffer : DataBuffer contains the data to write - * @param address : Address to which the data will be written - * @param nbOfbytes : NbOfbytes to be written - * @retval Status - */ -uint8_t USBH_MSC_Write10(USB_OTG_CORE_HANDLE *pdev, - uint8_t *dataBuffer, - uint32_t address, - uint32_t nbOfbytes) -{ - uint8_t index; - USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY; - uint16_t nbOfPages; - - if(HCD_IsDeviceConnected(pdev)) - { - switch(USBH_MSC_BOTXferParam.CmdStateMachine) - { - case CMD_SEND_STATE: - USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes; - USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT; - USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; - USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer; - - - for(index = CBW_CB_LENGTH; index != 0; index--) - { - USBH_MSC_CBWData.field.CBWCB[index] = 0x00; - } - - USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_WRITE10; - - /*logical block address*/ - USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t*)&address)[3]) ; - USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t*)&address)[2]); - USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t*)&address)[1]); - USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t*)&address)[0]); - - /*USBH_MSC_PAGE_LENGTH = 512*/ - nbOfPages = nbOfbytes/ USBH_MSC_PAGE_LENGTH; - - /*Tranfer length */ - USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ; - USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ; - - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW; - /* Start the transfer, then let the state machine - magage the other transactions */ - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS; - USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY; - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS; - - status = USBH_MSC_BUSY; - - break; - - case CMD_WAIT_STATUS: - if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) - { - /* Commands successfully sent and Response Received */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_OK; - } - else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) - { - /* Failure Mode */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - } - - else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR ) - { - /* Failure Mode */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_PHASE_ERROR; - } - break; - - default: - break; - } - } - return status; -} - -/** - * @brief USBH_MSC_Read10 - * Issue the read command to the device. Once the response received, - * it updates the status to upper layer - * @param dataBuffer : DataBuffer will contain the data to be read - * @param address : Address from which the data will be read - * @param nbOfbytes : NbOfbytes to be read - * @retval Status - */ -uint8_t USBH_MSC_Read10(USB_OTG_CORE_HANDLE *pdev, - uint8_t *dataBuffer, - uint32_t address, - uint32_t nbOfbytes) -{ - uint8_t index; - static USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY; - uint16_t nbOfPages; - status = USBH_MSC_BUSY; - - if(HCD_IsDeviceConnected(pdev)) - { - switch(USBH_MSC_BOTXferParam.CmdStateMachine) - { - case CMD_SEND_STATE: - /*Prepare the CBW and relevent field*/ - USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes; - USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; - USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; - - USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer; - - for(index = CBW_CB_LENGTH; index != 0; index--) - { - USBH_MSC_CBWData.field.CBWCB[index] = 0x00; - } - - USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ10; - - /*logical block address*/ - - USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t*)&address)[3]); - USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t*)&address)[2]); - USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t*)&address)[1]); - USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t*)&address)[0]); - - /*USBH_MSC_PAGE_LENGTH = 512*/ - nbOfPages = nbOfbytes/ USBH_MSC_PAGE_LENGTH; - - /*Tranfer length */ - USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ; - USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ; - - - USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW; - /* Start the transfer, then let the state machine - magage the other transactions */ - USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS; - USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY; - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS; - - status = USBH_MSC_BUSY; - - break; - - case CMD_WAIT_STATUS: - - if((USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) && \ - (HCD_IsDeviceConnected(pdev))) - { - /* Commands successfully sent and Response Received */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_OK; - } - else if (( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) && \ - (HCD_IsDeviceConnected(pdev))) - { - /* Failure Mode */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - } - - else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR ) - { - /* Failure Mode */ - USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE; - status = USBH_MSC_PHASE_ERROR; - } - else - { - /* Wait for the Commands to get Completed */ - /* NO Change in state Machine */ - } - break; - - default: - break; - } - } - return status; -} - - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_conf_template.h b/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_conf_template.h deleted file mode 100644 index 7e41bf8cd..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_conf_template.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_conf_template - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief General USB Host library configuration - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USBH_CONF__H__ -#define __USBH_CONF__H__ - -/* Includes ------------------------------------------------------------------*/ -/** @addtogroup USBH_OTG_DRIVER - * @{ - */ - -/** @defgroup USBH_CONF - * @brief usb otg low level driver configuration file - * @{ - */ - -/** @defgroup USBH_CONF_Exported_Defines - * @{ - */ - -#define USBH_MAX_NUM_ENDPOINTS 2 -#define USBH_MAX_NUM_INTERFACES 2 -#ifdef USE_USB_OTG_FS -#define USBH_MSC_MPS_SIZE 0x40 -#else -#define USBH_MSC_MPS_SIZE 0x200 -#endif - -/** - * @} - */ - - -/** @defgroup USBH_CONF_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_CONF_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_CONF_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_CONF_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -#endif //__USBH_CONF__H__ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_core.h b/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_core.h deleted file mode 100644 index 3a8de2c67..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_core.h +++ /dev/null @@ -1,289 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_core.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Header file for usbh_core.c - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive ----------------------------------------------*/ -#ifndef __USBH_CORE_H -#define __USBH_CORE_H - -/* Includes ------------------------------------------------------------------*/ -#include "usb_hcd.h" -#include "usbh_def.h" -#include "usbh_conf.h" - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_LIB_CORE -* @{ -*/ - -/** @defgroup USBH_CORE - * @brief This file is the Header file for usbh_core.c - * @{ - */ - - -/** @defgroup USBH_CORE_Exported_Defines - * @{ - */ - -#define MSC_CLASS 0x08 -#define HID_CLASS 0x03 -#define MSC_PROTOCOL 0x50 -#define CBI_PROTOCOL 0x01 - - -#define USBH_MAX_ERROR_COUNT 2 -#define USBH_DEVICE_ADDRESS_DEFAULT 0 -#define USBH_DEVICE_ADDRESS 1 - - -/** - * @} - */ - - -/** @defgroup USBH_CORE_Exported_Types - * @{ - */ - -typedef enum { - USBH_OK = 0, - USBH_BUSY, - USBH_FAIL, - USBH_NOT_SUPPORTED, - USBH_UNRECOVERED_ERROR, - USBH_ERROR_SPEED_UNKNOWN, - USBH_APPLY_DEINIT -}USBH_Status; - -/* Following states are used for gState */ -typedef enum { - HOST_IDLE =0, - HOST_ISSUE_CORE_RESET, - HOST_DEV_ATTACHED, - HOST_DEV_DISCONNECTED, - HOST_ISSUE_RESET, - HOST_DETECT_DEVICE_SPEED, - HOST_ENUMERATION, - HOST_CLASS_REQUEST, - HOST_CLASS, - HOST_CTRL_XFER, - HOST_USR_INPUT, - HOST_SUSPENDED, - HOST_ERROR_STATE -}HOST_State; - -/* Following states are used for EnumerationState */ -typedef enum { - ENUM_IDLE = 0, - ENUM_GET_FULL_DEV_DESC, - ENUM_SET_ADDR, - ENUM_GET_CFG_DESC, - ENUM_GET_FULL_CFG_DESC, - ENUM_GET_MFC_STRING_DESC, - ENUM_GET_PRODUCT_STRING_DESC, - ENUM_GET_SERIALNUM_STRING_DESC, - ENUM_SET_CONFIGURATION, - ENUM_DEV_CONFIGURED -} ENUM_State; - - - -/* Following states are used for CtrlXferStateMachine */ -typedef enum { - CTRL_IDLE =0, - CTRL_SETUP, - CTRL_SETUP_WAIT, - CTRL_DATA_IN, - CTRL_DATA_IN_WAIT, - CTRL_DATA_OUT, - CTRL_DATA_OUT_WAIT, - CTRL_STATUS_IN, - CTRL_STATUS_IN_WAIT, - CTRL_STATUS_OUT, - CTRL_STATUS_OUT_WAIT, - CTRL_ERROR -} -CTRL_State; - -typedef enum { - USBH_USR_NO_RESP = 0, - USBH_USR_RESP_OK = 1, -} -USBH_USR_Status; - -/* Following states are used for RequestState */ -typedef enum { - CMD_IDLE =0, - CMD_SEND, - CMD_WAIT -} CMD_State; - - - -typedef struct _Ctrl -{ - uint8_t hc_num_in; - uint8_t hc_num_out; - uint8_t ep0size; - uint8_t *buff; - uint16_t length; - uint8_t errorcount; - uint16_t timer; - CTRL_STATUS status; - USB_Setup_TypeDef setup; - CTRL_State state; - -} USBH_Ctrl_TypeDef; - - - -typedef struct _DeviceProp -{ - - uint8_t address; - uint8_t speed; - USBH_DevDesc_TypeDef Dev_Desc; - USBH_CfgDesc_TypeDef Cfg_Desc; - USBH_InterfaceDesc_TypeDef Itf_Desc[USBH_MAX_NUM_INTERFACES]; - USBH_EpDesc_TypeDef Ep_Desc[USBH_MAX_NUM_INTERFACES][USBH_MAX_NUM_ENDPOINTS]; - USBH_HIDDesc_TypeDef HID_Desc; - -}USBH_Device_TypeDef; - -typedef struct _USBH_Class_cb -{ - USBH_Status (*Init)\ - (USB_OTG_CORE_HANDLE *pdev , void *phost); - void (*DeInit)\ - (USB_OTG_CORE_HANDLE *pdev , void *phost); - USBH_Status (*Requests)\ - (USB_OTG_CORE_HANDLE *pdev , void *phost); - USBH_Status (*Machine)\ - (USB_OTG_CORE_HANDLE *pdev , void *phost); - -} USBH_Class_cb_TypeDef; - - -typedef struct _USBH_USR_PROP -{ - void (*Init)(void); /* HostLibInitialized */ - void (*DeInit)(void); /* HostLibInitialized */ - void (*DeviceAttached)(void); /* DeviceAttached */ - void (*ResetDevice)(void); - void (*DeviceDisconnected)(void); - void (*OverCurrentDetected)(void); - void (*DeviceSpeedDetected)(uint8_t DeviceSpeed); /* DeviceSpeed */ - void (*DeviceDescAvailable)(void *); /* DeviceDescriptor is available */ - void (*DeviceAddressAssigned)(void); /* Address is assigned to USB Device */ - void (*ConfigurationDescAvailable)(USBH_CfgDesc_TypeDef *, - USBH_InterfaceDesc_TypeDef *, - USBH_EpDesc_TypeDef *); - /* Configuration Descriptor available */ - void (*ManufacturerString)(void *); /* ManufacturerString*/ - void (*ProductString)(void *); /* ProductString*/ - void (*SerialNumString)(void *); /* SerialNubString*/ - void (*EnumerationDone)(void); /* Enumeration finished */ - USBH_USR_Status (*UserInput)(void); - int (*USBH_USR_MSC_Application) (void); - void (*USBH_USR_DeviceNotSupported)(void); /* Device is not supported*/ - void (*UnrecoveredError)(void); - -} -USBH_Usr_cb_TypeDef; - -typedef struct _Host_TypeDef -{ - HOST_State gState; /* Host State Machine Value */ - HOST_State gStateBkp; /* backup of previous State machine value */ - ENUM_State EnumState; /* Enumeration state Machine */ - CMD_State RequestState; - USBH_Ctrl_TypeDef Control; - - USBH_Device_TypeDef device_prop; - - USBH_Class_cb_TypeDef *class_cb; - USBH_Usr_cb_TypeDef *usr_cb; - - -} USBH_HOST, *pUSBH_HOST; - -/** - * @} - */ - - - -/** @defgroup USBH_CORE_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBH_CORE_Exported_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBH_CORE_Exported_FunctionsPrototype - * @{ - */ -void USBH_Init(USB_OTG_CORE_HANDLE *pdev, - USB_OTG_CORE_ID_TypeDef coreID, - USBH_HOST *phost, - USBH_Class_cb_TypeDef *class_cb, - USBH_Usr_cb_TypeDef *usr_cb); - -USBH_Status USBH_DeInit(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost); -void USBH_Process(USB_OTG_CORE_HANDLE *pdev , - USBH_HOST *phost); -void USBH_ErrorHandle(USBH_HOST *phost, - USBH_Status errType); - -/** - * @} - */ - -#endif /* __USBH_CORE_H */ -/** - * @} - */ - -/** - * @} - */ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_def.h b/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_def.h deleted file mode 100644 index 35ebeb42d..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_def.h +++ /dev/null @@ -1,280 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_def.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Definitions used in the USB host library - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_LIB_CORE -* @{ -*/ - -/** @defgroup USBH_DEF - * @brief This file is includes USB descriptors - * @{ - */ - -#ifndef USBH_DEF_H -#define USBH_DEF_H - -#ifndef USBH_NULL -#define USBH_NULL ((void *)0) -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - - -#define ValBit(VAR,POS) (VAR & (1 << POS)) -#define SetBit(VAR,POS) (VAR |= (1 << POS)) -#define ClrBit(VAR,POS) (VAR &= ((1 << POS)^255)) - -#define LE16(addr) (((u16)(*((u8 *)(addr))))\ - + (((u16)(*(((u8 *)(addr)) + 1))) << 8)) - -#define USB_LEN_DESC_HDR 0x02 -#define USB_LEN_DEV_DESC 0x12 -#define USB_LEN_CFG_DESC 0x09 -#define USB_LEN_IF_DESC 0x09 -#define USB_LEN_EP_DESC 0x07 -#define USB_LEN_OTG_DESC 0x03 -#define USB_LEN_SETUP_PKT 0x08 - -/* bmRequestType :D7 Data Phase Transfer Direction */ -#define USB_REQ_DIR_MASK 0x80 -#define USB_H2D 0x00 -#define USB_D2H 0x80 - -/* bmRequestType D6..5 Type */ -#define USB_REQ_TYPE_STANDARD 0x00 -#define USB_REQ_TYPE_CLASS 0x20 -#define USB_REQ_TYPE_VENDOR 0x40 -#define USB_REQ_TYPE_RESERVED 0x60 - -/* bmRequestType D4..0 Recipient */ -#define USB_REQ_RECIPIENT_DEVICE 0x00 -#define USB_REQ_RECIPIENT_INTERFACE 0x01 -#define USB_REQ_RECIPIENT_ENDPOINT 0x02 -#define USB_REQ_RECIPIENT_OTHER 0x03 - -/* Table 9-4. Standard Request Codes */ -/* bRequest , Value */ -#define USB_REQ_GET_STATUS 0x00 -#define USB_REQ_CLEAR_FEATURE 0x01 -#define USB_REQ_SET_FEATURE 0x03 -#define USB_REQ_SET_ADDRESS 0x05 -#define USB_REQ_GET_DESCRIPTOR 0x06 -#define USB_REQ_SET_DESCRIPTOR 0x07 -#define USB_REQ_GET_CONFIGURATION 0x08 -#define USB_REQ_SET_CONFIGURATION 0x09 -#define USB_REQ_GET_INTERFACE 0x0A -#define USB_REQ_SET_INTERFACE 0x0B -#define USB_REQ_SYNCH_FRAME 0x0C - -/* Table 9-5. Descriptor Types of USB Specifications */ -#define USB_DESC_TYPE_DEVICE 1 -#define USB_DESC_TYPE_CONFIGURATION 2 -#define USB_DESC_TYPE_STRING 3 -#define USB_DESC_TYPE_INTERFACE 4 -#define USB_DESC_TYPE_ENDPOINT 5 -#define USB_DESC_TYPE_DEVICE_QUALIFIER 6 -#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7 -#define USB_DESC_TYPE_INTERFACE_POWER 8 -#define USB_DESC_TYPE_HID 0x21 -#define USB_DESC_TYPE_HID_REPORT 0x22 - - -#define USB_DEVICE_DESC_SIZE 18 -#define USB_CONFIGURATION_DESC_SIZE 9 -#define USB_HID_DESC_SIZE 9 -#define USB_INTERFACE_DESC_SIZE 9 -#define USB_ENDPOINT_DESC_SIZE 7 - -/* Descriptor Type and Descriptor Index */ -/* Use the following values when calling the function USBH_GetDescriptor */ -#define USB_DESC_DEVICE ((USB_DESC_TYPE_DEVICE << 8) & 0xFF00) -#define USB_DESC_CONFIGURATION ((USB_DESC_TYPE_CONFIGURATION << 8) & 0xFF00) -#define USB_DESC_STRING ((USB_DESC_TYPE_STRING << 8) & 0xFF00) -#define USB_DESC_INTERFACE ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00) -#define USB_DESC_ENDPOINT ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00) -#define USB_DESC_DEVICE_QUALIFIER ((USB_DESC_TYPE_DEVICE_QUALIFIER << 8) & 0xFF00) -#define USB_DESC_OTHER_SPEED_CONFIGURATION ((USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION << 8) & 0xFF00) -#define USB_DESC_INTERFACE_POWER ((USB_DESC_TYPE_INTERFACE_POWER << 8) & 0xFF00) -#define USB_DESC_HID_REPORT ((USB_DESC_TYPE_HID_REPORT << 8) & 0xFF00) -#define USB_DESC_HID ((USB_DESC_TYPE_HID << 8) & 0xFF00) - - -#define USB_EP_TYPE_CTRL 0x00 -#define USB_EP_TYPE_ISOC 0x01 -#define USB_EP_TYPE_BULK 0x02 -#define USB_EP_TYPE_INTR 0x03 - -#define USB_EP_DIR_OUT 0x00 -#define USB_EP_DIR_IN 0x80 -#define USB_EP_DIR_MSK 0x80 - -/* supported classes */ -#define USB_MSC_CLASS 0x08 -#define USB_HID_CLASS 0x03 - -/* Interface Descriptor field values for HID Boot Protocol */ -#define HID_BOOT_CODE 0x01 -#define HID_KEYBRD_BOOT_CODE 0x01 -#define HID_MOUSE_BOOT_CODE 0x02 - -/* As per USB specs 9.2.6.4 :Standard request with data request timeout: 5sec - Standard request with no data stage timeout : 50ms */ -#define DATA_STAGE_TIMEOUT 5000 -#define NODATA_STAGE_TIMEOUT 50 - -/** - * @} - */ - - -#define USBH_CONFIGURATION_DESCRIPTOR_SIZE (USB_CONFIGURATION_DESC_SIZE \ - + USB_INTERFACE_DESC_SIZE\ - + (USBH_MAX_NUM_ENDPOINTS * USB_ENDPOINT_DESC_SIZE)) - - -#define CONFIG_DESC_wTOTAL_LENGTH (ConfigurationDescriptorData.ConfigDescfield.\ - ConfigurationDescriptor.wTotalLength) - - -/* This Union is copied from usb_core.h */ -typedef union -{ - uint16_t w; - struct BW - { - uint8_t msb; - uint8_t lsb; - } - bw; -} -uint16_t_uint8_t; - - -typedef union _USB_Setup -{ - uint8_t d8[8]; - - struct _SetupPkt_Struc - { - uint8_t bmRequestType; - uint8_t bRequest; - uint16_t_uint8_t wValue; - uint16_t_uint8_t wIndex; - uint16_t_uint8_t wLength; - } b; -} -USB_Setup_TypeDef; - -typedef struct _DescHeader -{ - uint8_t bLength; - uint8_t bDescriptorType; -} -USBH_DescHeader_t; - -typedef struct _DeviceDescriptor -{ - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t bcdUSB; /* USB Specification Number which device complies too */ - uint8_t bDeviceClass; - uint8_t bDeviceSubClass; - uint8_t bDeviceProtocol; - /* If equal to Zero, each interface specifies its own class - code if equal to 0xFF, the class code is vendor specified. - Otherwise field is valid Class Code.*/ - uint8_t bMaxPacketSize; - uint16_t idVendor; /* Vendor ID (Assigned by USB Org) */ - uint16_t idProduct; /* Product ID (Assigned by Manufacturer) */ - uint16_t bcdDevice; /* Device Release Number */ - uint8_t iManufacturer; /* Index of Manufacturer String Descriptor */ - uint8_t iProduct; /* Index of Product String Descriptor */ - uint8_t iSerialNumber; /* Index of Serial Number String Descriptor */ - uint8_t bNumConfigurations; /* Number of Possible Configurations */ -} -USBH_DevDesc_TypeDef; - - -typedef struct _ConfigurationDescriptor -{ - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t wTotalLength; /* Total Length of Data Returned */ - uint8_t bNumInterfaces; /* Number of Interfaces */ - uint8_t bConfigurationValue; /* Value to use as an argument to select this configuration*/ - uint8_t iConfiguration; /*Index of String Descriptor Describing this configuration */ - uint8_t bmAttributes; /* D7 Bus Powered , D6 Self Powered, D5 Remote Wakeup , D4..0 Reserved (0)*/ - uint8_t bMaxPower; /*Maximum Power Consumption */ -} -USBH_CfgDesc_TypeDef; - - -typedef struct _HIDDescriptor -{ - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t bcdHID; /* indicates what endpoint this descriptor is describing */ - uint8_t bCountryCode; /* specifies the transfer type. */ - uint8_t bNumDescriptors; /* specifies the transfer type. */ - uint8_t bReportDescriptorType; /* Maximum Packet Size this endpoint is capable of sending or receiving */ - uint16_t wItemLength; /* is used to specify the polling interval of certain transfers. */ -} -USBH_HIDDesc_TypeDef; - - -typedef struct _InterfaceDescriptor -{ - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bInterfaceNumber; - uint8_t bAlternateSetting; /* Value used to select alternative setting */ - uint8_t bNumEndpoints; /* Number of Endpoints used for this interface */ - uint8_t bInterfaceClass; /* Class Code (Assigned by USB Org) */ - uint8_t bInterfaceSubClass; /* Subclass Code (Assigned by USB Org) */ - uint8_t bInterfaceProtocol; /* Protocol Code */ - uint8_t iInterface; /* Index of String Descriptor Describing this interface */ - -} -USBH_InterfaceDesc_TypeDef; - - -typedef struct _EndpointDescriptor -{ - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bEndpointAddress; /* indicates what endpoint this descriptor is describing */ - uint8_t bmAttributes; /* specifies the transfer type. */ - uint16_t wMaxPacketSize; /* Maximum Packet Size this endpoint is capable of sending or receiving */ - uint8_t bInterval; /* is used to specify the polling interval of certain transfers. */ -} -USBH_EpDesc_TypeDef; -#endif -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_hcs.h b/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_hcs.h deleted file mode 100644 index c5310b21b..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_hcs.h +++ /dev/null @@ -1,125 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_hcs.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Header file for usbh_hcs.c - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive ----------------------------------------------*/ -#ifndef __USBH_HCS_H -#define __USBH_HCS_H - -/* Includes ------------------------------------------------------------------*/ -#include "usbh_core.h" - - - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_LIB_CORE -* @{ -*/ - -/** @defgroup USBH_HCS - * @brief This file is the header file for usbh_hcs.c - * @{ - */ - -/** @defgroup USBH_HCS_Exported_Defines - * @{ - */ -#define HC_MAX 8 - -#define HC_OK 0x0000 -#define HC_USED 0x8000 -#define HC_ERROR 0xFFFF -#define HC_USED_MASK 0x7FFF -/** - * @} - */ - -/** @defgroup USBH_HCS_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_HCS_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_HCS_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_HCS_Exported_FunctionsPrototype - * @{ - */ - -uint8_t USBH_Alloc_Channel(USB_OTG_CORE_HANDLE *pdev, uint8_t ep_addr); - -uint8_t USBH_Free_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t idx); - -uint8_t USBH_DeAllocate_AllChannel (USB_OTG_CORE_HANDLE *pdev); - -uint8_t USBH_Open_Channel (USB_OTG_CORE_HANDLE *pdev, - uint8_t ch_num, - uint8_t dev_address, - uint8_t speed, - uint8_t ep_type, - uint16_t mps); - -uint8_t USBH_Modify_Channel (USB_OTG_CORE_HANDLE *pdev, - uint8_t hc_num, - uint8_t dev_address, - uint8_t speed, - uint8_t ep_type, - uint16_t mps); -/** - * @} - */ - - - -#endif /* __USBH_HCS_H */ - - -/** - * @} - */ - -/** - * @} - */ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_ioreq.h b/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_ioreq.h deleted file mode 100644 index 4bdd43698..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_ioreq.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_ioreq.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Header file for usbh_ioreq.c - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive ----------------------------------------------*/ -#ifndef __USBH_IOREQ_H -#define __USBH_IOREQ_H - -/* Includes ------------------------------------------------------------------*/ -#include "usb_conf.h" -#include "usbh_core.h" -#include "usbh_def.h" - - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_LIB_CORE -* @{ -*/ - -/** @defgroup USBH_IOREQ - * @brief This file is the header file for usbh_ioreq.c - * @{ - */ - - -/** @defgroup USBH_IOREQ_Exported_Defines - * @{ - */ -#define USBH_SETUP_PKT_SIZE 8 -#define USBH_EP0_EP_NUM 0 -#define USBH_MAX_PACKET_SIZE 0x40 -/** - * @} - */ - - -/** @defgroup USBH_IOREQ_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_IOREQ_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_IOREQ_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_IOREQ_Exported_FunctionsPrototype - * @{ - */ -USBH_Status USBH_CtlSendSetup ( USB_OTG_CORE_HANDLE *pdev, - uint8_t *buff, - uint8_t hc_num); - -USBH_Status USBH_CtlSendData ( USB_OTG_CORE_HANDLE *pdev, - uint8_t *buff, - uint8_t length, - uint8_t hc_num); - -USBH_Status USBH_CtlReceiveData( USB_OTG_CORE_HANDLE *pdev, - uint8_t *buff, - uint8_t length, - uint8_t hc_num); - -USBH_Status USBH_BulkReceiveData( USB_OTG_CORE_HANDLE *pdev, - uint8_t *buff, - uint16_t length, - uint8_t hc_num); - -USBH_Status USBH_BulkSendData ( USB_OTG_CORE_HANDLE *pdev, - uint8_t *buff, - uint16_t length, - uint8_t hc_num); - -USBH_Status USBH_InterruptReceiveData( USB_OTG_CORE_HANDLE *pdev, - uint8_t *buff, - uint8_t length, - uint8_t hc_num); - -USBH_Status USBH_InterruptSendData( USB_OTG_CORE_HANDLE *pdev, - uint8_t *buff, - uint8_t length, - uint8_t hc_num); - -USBH_Status USBH_CtlReq (USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t *buff, - uint16_t length); -/** - * @} - */ - -#endif /* __USBH_IOREQ_H */ - -/** - * @} - */ - -/** - * @} - */ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_stdreq.h b/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_stdreq.h deleted file mode 100644 index 22bf3d1da..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Core/inc/usbh_stdreq.h +++ /dev/null @@ -1,148 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_stdreq.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Header file for usbh_stdreq.c - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive ----------------------------------------------*/ -#ifndef __USBH_STDREQ_H -#define __USBH_STDREQ_H - -/* Includes ------------------------------------------------------------------*/ - -#include "usb_conf.h" -#include "usb_hcd.h" -#include "usbh_core.h" -#include "usbh_def.h" - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_LIB_CORE -* @{ -*/ - -/** @defgroup USBH_STDREQ - * @brief This file is the - * @{ - */ - - -/** @defgroup USBH_STDREQ_Exported_Defines - * @{ - */ -/*Standard Feature Selector for clear feature command*/ -#define FEATURE_SELECTOR_ENDPOINT 0X00 -#define FEATURE_SELECTOR_DEVICE 0X01 - - -#define INTERFACE_DESC_TYPE 0x04 -#define ENDPOINT_DESC_TYPE 0x05 -#define INTERFACE_DESC_SIZE 0x09 - - -#define USBH_HID_CLASS 0x03 - -/** - * @} - */ - - -/** @defgroup USBH_STDREQ_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_STDREQ_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_STDREQ_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_STDREQ_Exported_FunctionsPrototype - * @{ - */ -USBH_Status USBH_GetDescriptor(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t req_type, - uint16_t value_idx, - uint8_t* buff, - uint16_t length ); - -USBH_Status USBH_Get_DevDesc(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t length); - -USBH_Status USBH_Get_StringDesc(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t string_index, - uint8_t *buff, - uint16_t length); - -USBH_Status USBH_SetCfg(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint16_t configuration_value); - -USBH_Status USBH_Get_CfgDesc(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint16_t length); - -USBH_Status USBH_SetAddress(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t DeviceAddress); - -USBH_Status USBH_ClrFeature(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t ep_num, uint8_t hc_num); - -USBH_Status USBH_Issue_ClrFeature(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t ep_num); -/** - * @} - */ - -#endif /* __USBH_STDREQ_H */ - -/** - * @} - */ - -/** - * @} - */ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_core.c b/example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_core.c deleted file mode 100644 index a15535752..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_core.c +++ /dev/null @@ -1,842 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_core.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file implements the functions for the core state machine process - * the enumeration and the control transfer process - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ -/* Includes ------------------------------------------------------------------*/ - -#include "usbh_ioreq.h" -#include "usb_bsp.h" -#include "usbh_hcs.h" -#include "usbh_stdreq.h" -#include "usbh_core.h" - - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_LIB_CORE -* @{ -*/ - -/** @defgroup USBH_CORE - * @brief TThis file handles the basic enumaration when a device is connected - * to the host. - * @{ - */ - -/** @defgroup USBH_CORE_Private_TypesDefinitions - * @{ - */ -void USBH_Disconnect (void *pdev); -void USBH_Connect (void *pdev); - -USB_OTG_hPort_TypeDef USBH_DeviceConnStatus_cb = -{ - USBH_Disconnect, - USBH_Connect, - 0, - 0, - 0, - 0 -}; -/** - * @} - */ - - -/** @defgroup USBH_CORE_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_CORE_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_CORE_Private_Variables - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_CORE_Private_FunctionPrototypes - * @{ - */ -static USBH_Status USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost); -USBH_Status USBH_HandleControl (USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost); - -/** - * @} - */ - - -/** @defgroup USBH_CORE_Private_Functions - * @{ - */ - - -/** - * @brief USBH_Connect - * USB Connect callback function from the Interrupt. - * @param selected device - * @retval none - */ -void USBH_Connect (void *pdev) -{ - USB_OTG_CORE_HANDLE *ppdev = pdev; - ppdev->host.port_cb->ConnStatus = 1; - ppdev->host.port_cb->ConnHandled = 0; -} - -/** - * @brief USBH_Disconnect - * USB Disconnect callback function from the Interrupt. - * @param selected device - * @retval none - */ - -void USBH_Disconnect (void *pdev) -{ - - USB_OTG_CORE_HANDLE *ppdev = pdev; - - /* Make device Not connected flag true */ - ppdev->host.port_cb->DisconnStatus = 1; - ppdev->host.port_cb->DisconnHandled = 0; -} - -/** - * @brief USBH_Init - * Host hardware and stack initializations - * @param class_cb: Class callback structure address - * @param usr_cb: User callback structure address - * @retval None - */ -void USBH_Init(USB_OTG_CORE_HANDLE *pdev, - USB_OTG_CORE_ID_TypeDef coreID, - USBH_HOST *phost, - USBH_Class_cb_TypeDef *class_cb, - USBH_Usr_cb_TypeDef *usr_cb) -{ - - /* Hardware Init */ - USB_OTG_BSP_Init(pdev); - - /* configure GPIO pin used for switching VBUS power */ - USB_OTG_BSP_ConfigVBUS(0); - - - /* Host de-initializations */ - USBH_DeInit(pdev, phost); - - /*Register class and user callbacks */ - phost->class_cb = class_cb; - phost->usr_cb = usr_cb; - pdev->host.port_cb = &USBH_DeviceConnStatus_cb; - - pdev->host.port_cb->ConnStatus = 0; - pdev->host.port_cb->DisconnStatus = 0; - - - /* Start the USB OTG core */ - HCD_Init(pdev , coreID); - - /* Upon Init call usr call back */ - phost->usr_cb->Init(); - - /* Enable Interrupts */ - USB_OTG_BSP_EnableInterrupt(pdev); -} - -/** - * @brief USBH_DeInit - * Re-Initialize Host - * @param None - * @retval status: USBH_Status - */ -USBH_Status USBH_DeInit(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost) -{ - /* Software Init */ - - phost->gState = HOST_IDLE; - phost->gStateBkp = HOST_IDLE; - phost->EnumState = ENUM_IDLE; - phost->RequestState = CMD_SEND; - - phost->Control.state = CTRL_SETUP; - phost->Control.ep0size = USB_OTG_MAX_EP0_SIZE; - - phost->device_prop.address = USBH_DEVICE_ADDRESS_DEFAULT; - phost->device_prop.speed = HPRT0_PRTSPD_FULL_SPEED; - - USBH_Free_Channel (pdev, phost->Control.hc_num_in); - USBH_Free_Channel (pdev, phost->Control.hc_num_out); - return USBH_OK; -} - -/** -* @brief USBH_Process -* USB Host core main state machine process -* @param None -* @retval None -*/ -void USBH_Process(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost) -{ - volatile USBH_Status status = USBH_FAIL; - - switch (phost->gState) - { - case HOST_ISSUE_CORE_RESET : - - if ( HCD_ResetPort(pdev) == 0) - { - phost->gState = HOST_IDLE; - } - break; - - case HOST_IDLE : - - if (HCD_IsDeviceConnected(pdev)) - { - /* Wait for USB Connect Interrupt void USBH_ISR_Connected(void) */ - USBH_DeAllocate_AllChannel(pdev); - phost->gState = HOST_DEV_ATTACHED; - } - break; - - case HOST_DEV_ATTACHED : - - phost->usr_cb->DeviceAttached(); - pdev->host.port_cb->DisconnStatus = 0; - pdev->host.port_cb->ConnHandled = 1; - - phost->Control.hc_num_out = USBH_Alloc_Channel(pdev, 0x00); - phost->Control.hc_num_in = USBH_Alloc_Channel(pdev, 0x80); - - /* Reset USB Device */ - if ( HCD_ResetPort(pdev) == 0) - { - phost->usr_cb->ResetDevice(); - /* Wait for USB USBH_ISR_PrtEnDisableChange() - Host is Now ready to start the Enumeration - */ - - phost->device_prop.speed = HCD_GetCurrentSpeed(pdev); - - phost->gState = HOST_ENUMERATION; - phost->usr_cb->DeviceSpeedDetected(phost->device_prop.speed); - - /* Open Control pipes */ - USBH_Open_Channel (pdev, - phost->Control.hc_num_in, - phost->device_prop.address, - phost->device_prop.speed, - EP_TYPE_CTRL, - phost->Control.ep0size); - - /* Open Control pipes */ - USBH_Open_Channel (pdev, - phost->Control.hc_num_out, - phost->device_prop.address, - phost->device_prop.speed, - EP_TYPE_CTRL, - phost->Control.ep0size); - } - break; - - case HOST_ENUMERATION: - /* Check for enumeration status */ - if ( USBH_HandleEnum(pdev , phost) == USBH_OK) - { - /* The function shall return USBH_OK when full enumeration is complete */ - - /* user callback for end of device basic enumeration */ - phost->usr_cb->EnumerationDone(); - - phost->gState = HOST_USR_INPUT; - } - break; - - case HOST_USR_INPUT: - /*The function should return user response true to move to class state */ - if ( phost->usr_cb->UserInput() == USBH_USR_RESP_OK) - { - if((phost->class_cb->Init(pdev, phost))\ - == USBH_OK) - { - phost->gState = HOST_CLASS_REQUEST; - } - } - break; - - case HOST_CLASS_REQUEST: - /* process class standard contol requests state machine */ - status = phost->class_cb->Requests(pdev, phost); - - if(status == USBH_OK) - { - phost->gState = HOST_CLASS; - } - - else - { - USBH_ErrorHandle(phost, status); - } - - - break; - case HOST_CLASS: - /* process class state machine */ - status = phost->class_cb->Machine(pdev, phost); - USBH_ErrorHandle(phost, status); - break; - - case HOST_CTRL_XFER: - /* process control transfer state machine */ - USBH_HandleControl(pdev, phost); - break; - - case HOST_SUSPENDED: - break; - - case HOST_ERROR_STATE: - /* Re-Initilaize Host for new Enumeration */ - USBH_DeInit(pdev, phost); - phost->usr_cb->DeInit(); - phost->class_cb->DeInit(pdev, &phost->device_prop); - break; - - default : - break; - } - - /* check device disconnection event */ - if (!(HCD_IsDeviceConnected(pdev)) && - (pdev->host.port_cb->DisconnHandled == 0)) - { - /* Manage User disconnect operations*/ - phost->usr_cb->DeviceDisconnected(); - - pdev->host.port_cb->DisconnHandled = 1; /* Handle to avoid the Re-entry*/ - - /* Re-Initilaize Host for new Enumeration */ - USBH_DeInit(pdev, phost); - phost->usr_cb->DeInit(); - phost->class_cb->DeInit(pdev, &phost->device_prop); - } -} - - -/** - * @brief USBH_ErrorHandle - * This function handles the Error on Host side. - * @param errType : Type of Error or Busy/OK state - * @retval None - */ -void USBH_ErrorHandle(USBH_HOST *phost, USBH_Status errType) -{ - /* Error unrecovered or not supported device speed */ - if ( (errType == USBH_ERROR_SPEED_UNKNOWN) || - (errType == USBH_UNRECOVERED_ERROR) ) - { - phost->usr_cb->UnrecoveredError(); - phost->gState = HOST_ERROR_STATE; - } - /* USB host restart requested from application layer */ - else if(errType == USBH_APPLY_DEINIT) - { - phost->gState = HOST_ERROR_STATE; - /* user callback for initalization */ - phost->usr_cb->Init(); - } -} - - -/** - * @brief USBH_HandleEnum - * This function includes the complete enumeration process - * @param pdev: Selected device - * @retval USBH_Status - */ -static USBH_Status USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost) -{ - USBH_Status Status = USBH_BUSY; - uint8_t Local_Buffer[64]; - - switch (phost->EnumState) - { - case ENUM_IDLE: - /* Get Device Desc for only 1st 8 bytes : To get EP0 MaxPacketSize */ - if ( USBH_Get_DevDesc(pdev , phost, 8) == USBH_OK) - { - phost->Control.ep0size = phost->device_prop.Dev_Desc.bMaxPacketSize; - - /* Issue Reset */ - HCD_ResetPort(pdev); - phost->EnumState = ENUM_GET_FULL_DEV_DESC; - - /* modify control channels configuration for MaxPacket size */ - USBH_Modify_Channel (pdev, - phost->Control.hc_num_out, - 0, - 0, - 0, - phost->Control.ep0size); - - USBH_Modify_Channel (pdev, - phost->Control.hc_num_in, - 0, - 0, - 0, - phost->Control.ep0size); - } - break; - - case ENUM_GET_FULL_DEV_DESC: - /* Get FULL Device Desc */ - if ( USBH_Get_DevDesc(pdev, phost, USB_DEVICE_DESC_SIZE)\ - == USBH_OK) - { - /* user callback for device descriptor available */ - phost->usr_cb->DeviceDescAvailable(&phost->device_prop.Dev_Desc); - phost->EnumState = ENUM_SET_ADDR; - } - break; - - case ENUM_SET_ADDR: - /* set address */ - if ( USBH_SetAddress(pdev, phost, USBH_DEVICE_ADDRESS) == USBH_OK) - { - phost->device_prop.address = USBH_DEVICE_ADDRESS; - - /* user callback for device address assigned */ - phost->usr_cb->DeviceAddressAssigned(); - phost->EnumState = ENUM_GET_CFG_DESC; - - /* modify control channels to update device address */ - USBH_Modify_Channel (pdev, - phost->Control.hc_num_in, - phost->device_prop.address, - 0, - 0, - 0); - - USBH_Modify_Channel (pdev, - phost->Control.hc_num_out, - phost->device_prop.address, - 0, - 0, - 0); - } - break; - - case ENUM_GET_CFG_DESC: - /* get standard configuration descriptor */ - if ( USBH_Get_CfgDesc(pdev, - phost, - USB_CONFIGURATION_DESC_SIZE) == USBH_OK) - { - phost->EnumState = ENUM_GET_FULL_CFG_DESC; - } - break; - - case ENUM_GET_FULL_CFG_DESC: - /* get FULL config descriptor (config, interface, endpoints) */ - if (USBH_Get_CfgDesc(pdev, - phost, - phost->device_prop.Cfg_Desc.wTotalLength) == USBH_OK) - { - /* User callback for configuration descriptors available */ - phost->usr_cb->ConfigurationDescAvailable(&phost->device_prop.Cfg_Desc, - phost->device_prop.Itf_Desc, - phost->device_prop.Ep_Desc[0]); - - phost->EnumState = ENUM_GET_MFC_STRING_DESC; - } - break; - - case ENUM_GET_MFC_STRING_DESC: - if (phost->device_prop.Dev_Desc.iManufacturer != 0) - { /* Check that Manufacturer String is available */ - - if ( USBH_Get_StringDesc(pdev, - phost, - phost->device_prop.Dev_Desc.iManufacturer, - Local_Buffer , - 0xff) == USBH_OK) - { - /* User callback for Manufacturing string */ - phost->usr_cb->ManufacturerString(Local_Buffer); - phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC; - } - } - else - { - phost->usr_cb->ManufacturerString("N/A"); - phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC; - } - break; - - case ENUM_GET_PRODUCT_STRING_DESC: - if (phost->device_prop.Dev_Desc.iProduct != 0) - { /* Check that Product string is available */ - if ( USBH_Get_StringDesc(pdev, - phost, - phost->device_prop.Dev_Desc.iProduct, - Local_Buffer, - 0xff) == USBH_OK) - { - /* User callback for Product string */ - phost->usr_cb->ProductString(Local_Buffer); - phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC; - } - } - else - { - phost->usr_cb->ProductString("N/A"); - phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC; - } - break; - - case ENUM_GET_SERIALNUM_STRING_DESC: - if (phost->device_prop.Dev_Desc.iSerialNumber != 0) - { /* Check that Serial number string is available */ - if ( USBH_Get_StringDesc(pdev, - phost, - phost->device_prop.Dev_Desc.iSerialNumber, - Local_Buffer, - 0xff) == USBH_OK) - { - /* User callback for Serial number string */ - phost->usr_cb->SerialNumString(Local_Buffer); - phost->EnumState = ENUM_SET_CONFIGURATION; - } - } - else - { - phost->usr_cb->SerialNumString("N/A"); - phost->EnumState = ENUM_SET_CONFIGURATION; - } - break; - - case ENUM_SET_CONFIGURATION: - /* set configuration (default config) */ - if (USBH_SetCfg(pdev, - phost, - phost->device_prop.Cfg_Desc.bConfigurationValue) == USBH_OK) - { - phost->EnumState = ENUM_DEV_CONFIGURED; - } - break; - - - case ENUM_DEV_CONFIGURED: - /* user callback for enumeration done */ - Status = USBH_OK; - break; - - default: - break; - } - return Status; -} - - -/** - * @brief USBH_HandleControl - * Handles the USB control transfer state machine - * @param pdev: Selected device - * @retval Status - */ -USBH_Status USBH_HandleControl (USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost) -{ - uint8_t direction; - static uint16_t timeout = 0; - USBH_Status status = USBH_OK; - URB_STATE URB_Status = URB_IDLE; - - phost->Control.status = CTRL_START; - - - switch (phost->Control.state) - { - case CTRL_SETUP: - /* send a SETUP packet */ - USBH_CtlSendSetup (pdev, - phost->Control.setup.d8 , - phost->Control.hc_num_out); - phost->Control.state = CTRL_SETUP_WAIT; - break; - - case CTRL_SETUP_WAIT: - - URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out); - /* case SETUP packet sent successfully */ - if(URB_Status == URB_DONE) - { - direction = (phost->Control.setup.b.bmRequestType & USB_REQ_DIR_MASK); - - /* check if there is a data stage */ - if (phost->Control.setup.b.wLength.w != 0 ) - { - timeout = DATA_STAGE_TIMEOUT; - if (direction == USB_D2H) - { - /* Data Direction is IN */ - phost->Control.state = CTRL_DATA_IN; - } - else - { - /* Data Direction is OUT */ - phost->Control.state = CTRL_DATA_OUT; - } - } - /* No DATA stage */ - else - { - timeout = NODATA_STAGE_TIMEOUT; - - /* If there is No Data Transfer Stage */ - if (direction == USB_D2H) - { - /* Data Direction is IN */ - phost->Control.state = CTRL_STATUS_OUT; - } - else - { - /* Data Direction is OUT */ - phost->Control.state = CTRL_STATUS_IN; - } - } - /* Set the delay timer to enable timeout for data stage completion */ - phost->Control.timer = HCD_GetCurrentFrame(pdev); - } - else if(URB_Status == URB_ERROR) - { - phost->Control.state = CTRL_ERROR; - phost->Control.status = CTRL_XACTERR; - } - break; - - case CTRL_DATA_IN: - /* Issue an IN token */ - USBH_CtlReceiveData(pdev, - phost->Control.buff, - phost->Control.length, - phost->Control.hc_num_in); - - phost->Control.state = CTRL_DATA_IN_WAIT; - break; - - case CTRL_DATA_IN_WAIT: - - URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in); - - /* check is DATA packet transfered successfully */ - if (URB_Status == URB_DONE) - { - phost->Control.state = CTRL_STATUS_OUT; - } - - /* manage error cases*/ - if (URB_Status == URB_STALL) - { - /* In stall case, return to previous machine state*/ - phost->gState = phost->gStateBkp; - } - else if (URB_Status == URB_ERROR) - { - /* Device error */ - phost->Control.state = CTRL_ERROR; - } - else if ((HCD_GetCurrentFrame(pdev)- phost->Control.timer) > timeout) - { - /* timeout for IN transfer */ - phost->Control.state = CTRL_ERROR; - } - break; - - case CTRL_DATA_OUT: - /* Start DATA out transfer (only one DATA packet)*/ - - pdev->host.hc[phost->Control.hc_num_out].toggle_out ^= 1; - - USBH_CtlSendData (pdev, - phost->Control.buff, - phost->Control.length , - phost->Control.hc_num_out); - - phost->Control.state = CTRL_DATA_OUT_WAIT; - break; - - case CTRL_DATA_OUT_WAIT: - - URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out); - if (URB_Status == URB_DONE) - { /* If the Setup Pkt is sent successful, then change the state */ - phost->Control.state = CTRL_STATUS_IN; - } - - /* handle error cases */ - else if (URB_Status == URB_STALL) - { - /* In stall case, return to previous machine state*/ - phost->gState = phost->gStateBkp; - } - else if (URB_Status == URB_NOTREADY) - { - /* Nack received from device */ - phost->Control.state = CTRL_DATA_OUT; - } - else if (URB_Status == URB_ERROR) - { - /* device error */ - phost->Control.state = CTRL_ERROR; - } - break; - - - case CTRL_STATUS_IN: - /* Send 0 bytes out packet */ - USBH_CtlReceiveData (pdev, - 0, - 0, - phost->Control.hc_num_in); - - phost->Control.state = CTRL_STATUS_IN_WAIT; - - break; - - case CTRL_STATUS_IN_WAIT: - - URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in); - - if ( URB_Status == URB_DONE) - { /* Control transfers completed, Exit the State Machine */ - phost->gState = phost->gStateBkp; - } - - else if (URB_Status == URB_ERROR) - { - phost->Control.state = CTRL_ERROR; - } - - else if((HCD_GetCurrentFrame(pdev)\ - - phost->Control.timer) > timeout) - { - phost->Control.state = CTRL_ERROR; - } - else if(URB_Status == URB_STALL) - { - /* Control transfers completed, Exit the State Machine */ - phost->gState = phost->gStateBkp; - phost->Control.status = CTRL_STALL; - status = USBH_NOT_SUPPORTED; - } - break; - - case CTRL_STATUS_OUT: - pdev->host.hc[phost->Control.hc_num_out].toggle_out ^= 1; - USBH_CtlSendData (pdev, - 0, - 0, - phost->Control.hc_num_out); - - phost->Control.state = CTRL_STATUS_OUT_WAIT; - break; - - case CTRL_STATUS_OUT_WAIT: - - URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out); - if (URB_Status == URB_DONE) - { - phost->gState = phost->gStateBkp; - } - else if (URB_Status == URB_NOTREADY) - { - phost->Control.state = CTRL_STATUS_OUT; - } - else if (URB_Status == URB_ERROR) - { - phost->Control.state = CTRL_ERROR; - } - break; - - case CTRL_ERROR: - /* - After a halt condition is encountered or an error is detected by the - host, a control endpoint is allowed to recover by accepting the next Setup - PID; i.e., recovery actions via some other pipe are not required for control - endpoints. For the Default Control Pipe, a device reset will ultimately be - required to clear the halt or error condition if the next Setup PID is not - accepted. - */ - if (++ phost->Control.errorcount <= USBH_MAX_ERROR_COUNT) - { - /* Do the transmission again, starting from SETUP Packet */ - phost->Control.state = CTRL_SETUP; - } - else - { - phost->Control.status = CTRL_FAIL; - phost->gState = phost->gStateBkp; - - status = USBH_FAIL; - } - break; - - default: - break; - } - return status; -} - - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - - - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_hcs.c b/example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_hcs.c deleted file mode 100644 index c703d3998..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_hcs.c +++ /dev/null @@ -1,253 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_hcs.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file implements functions for opening and closing host channels - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usbh_hcs.h" - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_LIB_CORE -* @{ -*/ - -/** @defgroup USBH_HCS - * @brief This file includes opening and closing host channels - * @{ - */ - -/** @defgroup USBH_HCS_Private_Defines - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_HCS_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_HCS_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_HCS_Private_Variables - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBH_HCS_Private_FunctionPrototypes - * @{ - */ -static uint16_t USBH_GetFreeChannel (USB_OTG_CORE_HANDLE *pdev); -/** - * @} - */ - - -/** @defgroup USBH_HCS_Private_Functions - * @{ - */ - - - -/** - * @brief USBH_Open_Channel - * Open a pipe - * @param pdev : Selected device - * @param hc_num: Host channel Number - * @param dev_address: USB Device address allocated to attached device - * @param speed : USB device speed (Full/Low) - * @param ep_type: end point type (Bulk/int/ctl) - * @param mps: max pkt size - * @retval Status - */ -uint8_t USBH_Open_Channel (USB_OTG_CORE_HANDLE *pdev, - uint8_t hc_num, - uint8_t dev_address, - uint8_t speed, - uint8_t ep_type, - uint16_t mps) -{ - - pdev->host.hc[hc_num].ep_num = pdev->host.channel[hc_num]& 0x7F; - pdev->host.hc[hc_num].ep_is_in = (pdev->host.channel[hc_num] & 0x80 ) == 0x80; - pdev->host.hc[hc_num].dev_addr = dev_address; - pdev->host.hc[hc_num].ep_type = ep_type; - pdev->host.hc[hc_num].max_packet = mps; - pdev->host.hc[hc_num].speed = speed; - pdev->host.hc[hc_num].toggle_in = 0; - pdev->host.hc[hc_num].toggle_out = 0; - if(speed == HPRT0_PRTSPD_HIGH_SPEED) - { - pdev->host.hc[hc_num].do_ping = 1; - } - - USB_OTG_HC_Init(pdev, hc_num) ; - - return HC_OK; - -} - -/** - * @brief USBH_Modify_Channel - * Modify a pipe - * @param pdev : Selected device - * @param hc_num: Host channel Number - * @param dev_address: USB Device address allocated to attached device - * @param speed : USB device speed (Full/Low) - * @param ep_type: end point type (Bulk/int/ctl) - * @param mps: max pkt size - * @retval Status - */ -uint8_t USBH_Modify_Channel (USB_OTG_CORE_HANDLE *pdev, - uint8_t hc_num, - uint8_t dev_address, - uint8_t speed, - uint8_t ep_type, - uint16_t mps) -{ - - if(dev_address != 0) - { - pdev->host.hc[hc_num].dev_addr = dev_address; - } - - if((pdev->host.hc[hc_num].max_packet != mps) && (mps != 0)) - { - pdev->host.hc[hc_num].max_packet = mps; - } - - if((pdev->host.hc[hc_num].speed != speed ) && (speed != 0 )) - { - pdev->host.hc[hc_num].speed = speed; - } - - USB_OTG_HC_Init(pdev, hc_num); - return HC_OK; - -} - -/** - * @brief USBH_Alloc_Channel - * Allocate a new channel for the pipe - * @param ep_addr: End point for which the channel to be allocated - * @retval hc_num: Host channel number - */ -uint8_t USBH_Alloc_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t ep_addr) -{ - uint16_t hc_num; - - hc_num = USBH_GetFreeChannel(pdev); - - if (hc_num != HC_ERROR) - { - pdev->host.channel[hc_num] = HC_USED | ep_addr; - } - return hc_num; -} - -/** - * @brief USBH_Free_Pipe - * Free the USB host channel - * @param idx: Channel number to be freed - * @retval Status - */ -uint8_t USBH_Free_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t idx) -{ - if(idx < HC_MAX) - { - pdev->host.channel[idx] &= HC_USED_MASK; - } - return USBH_OK; -} - - -/** - * @brief USBH_DeAllocate_AllChannel - * Free all USB host channel -* @param pdev : core instance - * @retval Status - */ -uint8_t USBH_DeAllocate_AllChannel (USB_OTG_CORE_HANDLE *pdev) -{ - uint8_t idx; - - for (idx = 2; idx < HC_MAX ; idx ++) - { - pdev->host.channel[idx] = 0; - } - return USBH_OK; -} - -/** - * @brief USBH_GetFreeChannel - * Get a free channel number for allocation to a device endpoint - * @param None - * @retval idx: Free Channel number - */ -static uint16_t USBH_GetFreeChannel (USB_OTG_CORE_HANDLE *pdev) -{ - uint8_t idx = 0; - - for (idx = 0 ; idx < HC_MAX ; idx++) - { - if ((pdev->host.channel[idx] & HC_USED) == 0) - { - return idx; - } - } - return HC_ERROR; -} - - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_ioreq.c b/example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_ioreq.c deleted file mode 100644 index a89084803..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_ioreq.c +++ /dev/null @@ -1,419 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_ioreq.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file handles the issuing of the USB transactions - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ -/* Includes ------------------------------------------------------------------*/ - -#include "usbh_ioreq.h" - -/** @addtogroup USBH_LIB - * @{ - */ - -/** @addtogroup USBH_LIB_CORE -* @{ -*/ - -/** @defgroup USBH_IOREQ - * @brief This file handles the standard protocol processing (USB v2.0) - * @{ - */ - - -/** @defgroup USBH_IOREQ_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_IOREQ_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USBH_IOREQ_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_IOREQ_Private_Variables - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBH_IOREQ_Private_FunctionPrototypes - * @{ - */ -static USBH_Status USBH_SubmitSetupRequest(USBH_HOST *phost, - uint8_t* buff, - uint16_t length); - -/** - * @} - */ - - -/** @defgroup USBH_IOREQ_Private_Functions - * @{ - */ - - -/** - * @brief USBH_CtlReq - * USBH_CtlReq sends a control request and provide the status after - * completion of the request - * @param pdev: Selected device - * @param req: Setup Request Structure - * @param buff: data buffer address to store the response - * @param length: length of the response - * @retval Status - */ -USBH_Status USBH_CtlReq (USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t *buff, - uint16_t length) -{ - USBH_Status status; - URB_STATE URB_Status = URB_IDLE; - - URB_Status = HCD_GetURB_State(pdev, phost->Control.hc_num_out); - - status = USBH_BUSY; - - switch (phost->RequestState) - { - case CMD_SEND: - /* Start a SETUP transfer */ - USBH_SubmitSetupRequest(phost, buff, length); - phost->RequestState = CMD_WAIT; - status = USBH_BUSY; - break; - - case CMD_WAIT: - if (URB_Status == URB_DONE) - { - /* Commands successfully sent and Response Received */ - phost->RequestState = CMD_SEND; - status = USBH_OK; - } - else if (URB_Status == URB_ERROR) - { - /* Failure Mode */ - phost->RequestState = CMD_SEND; - status = USBH_FAIL; - } - else if (URB_Status == URB_STALL) - { - /* Commands successfully sent and Response Received */ - phost->RequestState = CMD_SEND; - status = USBH_NOT_SUPPORTED; - } - break; - - default: - break; - } - return status; -} - -/** - * @brief USBH_CtlSendSetup - * Sends the Setup Packet to the Device - * @param pdev: Selected device - * @param buff: Buffer pointer from which the Data will be send to Device - * @param hc_num: Host channel Number - * @retval Status - */ -USBH_Status USBH_CtlSendSetup ( USB_OTG_CORE_HANDLE *pdev, - uint8_t *buff, - uint8_t hc_num){ - pdev->host.hc[hc_num].ep_is_in = 0; - pdev->host.hc[hc_num].data_pid = HC_PID_SETUP; - pdev->host.hc[hc_num].xfer_buff = buff; - pdev->host.hc[hc_num].xfer_len = USBH_SETUP_PKT_SIZE; - - return (USBH_Status)HCD_SubmitRequest (pdev , hc_num); -} - - -/** - * @brief USBH_CtlSendData - * Sends a data Packet to the Device - * @param pdev: Selected device - * @param buff: Buffer pointer from which the Data will be sent to Device - * @param length: Length of the data to be sent - * @param hc_num: Host channel Number - * @retval Status - */ -USBH_Status USBH_CtlSendData ( USB_OTG_CORE_HANDLE *pdev, - uint8_t *buff, - uint8_t length, - uint8_t hc_num) -{ - pdev->host.hc[hc_num].ep_is_in = 0; - pdev->host.hc[hc_num].xfer_buff = buff; - pdev->host.hc[hc_num].xfer_len = length; - - if ( length == 0 ) - { /* For Status OUT stage, Length==0, Status Out PID = 1 */ - pdev->host.hc[hc_num].toggle_out = 1; - } - - /* Set the Data Toggle bit as per the Flag */ - if ( pdev->host.hc[hc_num].toggle_out == 0) - { /* Put the PID 0 */ - pdev->host.hc[hc_num].data_pid = HC_PID_DATA0; - } - else - { /* Put the PID 1 */ - pdev->host.hc[hc_num].data_pid = HC_PID_DATA1 ; - } - - HCD_SubmitRequest (pdev , hc_num); - - return USBH_OK; -} - - -/** - * @brief USBH_CtlReceiveData - * Receives the Device Response to the Setup Packet - * @param pdev: Selected device - * @param buff: Buffer pointer in which the response needs to be copied - * @param length: Length of the data to be received - * @param hc_num: Host channel Number - * @retval Status. - */ -USBH_Status USBH_CtlReceiveData(USB_OTG_CORE_HANDLE *pdev, - uint8_t* buff, - uint8_t length, - uint8_t hc_num) -{ - - pdev->host.hc[hc_num].ep_is_in = 1; - pdev->host.hc[hc_num].data_pid = HC_PID_DATA1; - pdev->host.hc[hc_num].xfer_buff = buff; - pdev->host.hc[hc_num].xfer_len = length; - - HCD_SubmitRequest (pdev , hc_num); - - return USBH_OK; - -} - - -/** - * @brief USBH_BulkSendData - * Sends the Bulk Packet to the device - * @param pdev: Selected device - * @param buff: Buffer pointer from which the Data will be sent to Device - * @param length: Length of the data to be sent - * @param hc_num: Host channel Number - * @retval Status - */ -USBH_Status USBH_BulkSendData ( USB_OTG_CORE_HANDLE *pdev, - uint8_t *buff, - uint16_t length, - uint8_t hc_num) -{ - pdev->host.hc[hc_num].ep_is_in = 0; - pdev->host.hc[hc_num].xfer_buff = buff; - pdev->host.hc[hc_num].xfer_len = length; - - /* Set the Data Toggle bit as per the Flag */ - if ( pdev->host.hc[hc_num].toggle_out == 0) - { /* Put the PID 0 */ - pdev->host.hc[hc_num].data_pid = HC_PID_DATA0; - } - else - { /* Put the PID 1 */ - pdev->host.hc[hc_num].data_pid = HC_PID_DATA1 ; - } - - HCD_SubmitRequest (pdev , hc_num); - return USBH_OK; -} - - -/** - * @brief USBH_BulkReceiveData - * Receives IN bulk packet from device - * @param pdev: Selected device - * @param buff: Buffer pointer in which the received data packet to be copied - * @param length: Length of the data to be received - * @param hc_num: Host channel Number - * @retval Status. - */ -USBH_Status USBH_BulkReceiveData( USB_OTG_CORE_HANDLE *pdev, - uint8_t *buff, - uint16_t length, - uint8_t hc_num) -{ - pdev->host.hc[hc_num].ep_is_in = 1; - pdev->host.hc[hc_num].xfer_buff = buff; - pdev->host.hc[hc_num].xfer_len = length; - - - if( pdev->host.hc[hc_num].toggle_in == 0) - { - pdev->host.hc[hc_num].data_pid = HC_PID_DATA0; - } - else - { - pdev->host.hc[hc_num].data_pid = HC_PID_DATA1; - } - - HCD_SubmitRequest (pdev , hc_num); - return USBH_OK; -} - - -/** - * @brief USBH_InterruptReceiveData - * Receives the Device Response to the Interrupt IN token - * @param pdev: Selected device - * @param buff: Buffer pointer in which the response needs to be copied - * @param length: Length of the data to be received - * @param hc_num: Host channel Number - * @retval Status. - */ -USBH_Status USBH_InterruptReceiveData( USB_OTG_CORE_HANDLE *pdev, - uint8_t *buff, - uint8_t length, - uint8_t hc_num) -{ - - pdev->host.hc[hc_num].ep_is_in = 1; - pdev->host.hc[hc_num].xfer_buff = buff; - pdev->host.hc[hc_num].xfer_len = length; - - - - if(pdev->host.hc[hc_num].toggle_in == 0) - { - pdev->host.hc[hc_num].data_pid = HC_PID_DATA0; - } - else - { - pdev->host.hc[hc_num].data_pid = HC_PID_DATA1; - } - - /* toggle DATA PID */ - pdev->host.hc[hc_num].toggle_in ^= 1; - - HCD_SubmitRequest (pdev , hc_num); - - return USBH_OK; -} - -/** - * @brief USBH_InterruptSendData - * Sends the data on Interrupt OUT Endpoint - * @param pdev: Selected device - * @param buff: Buffer pointer from where the data needs to be copied - * @param length: Length of the data to be sent - * @param hc_num: Host channel Number - * @retval Status. - */ -USBH_Status USBH_InterruptSendData( USB_OTG_CORE_HANDLE *pdev, - uint8_t *buff, - uint8_t length, - uint8_t hc_num) -{ - - pdev->host.hc[hc_num].ep_is_in = 0; - pdev->host.hc[hc_num].xfer_buff = buff; - pdev->host.hc[hc_num].xfer_len = length; - - if(pdev->host.hc[hc_num].toggle_in == 0) - { - pdev->host.hc[hc_num].data_pid = HC_PID_DATA0; - } - else - { - pdev->host.hc[hc_num].data_pid = HC_PID_DATA1; - } - - pdev->host.hc[hc_num].toggle_in ^= 1; - - HCD_SubmitRequest (pdev , hc_num); - - return USBH_OK; -} - - -/** - * @brief USBH_SubmitSetupRequest - * Start a setup transfer by changing the state-machine and - * initializing the required variables needed for the Control Transfer - * @param pdev: Selected device - * @param setup: Setup Request Structure - * @param buff: Buffer used for setup request - * @param length: Length of the data - * @retval Status. -*/ -static USBH_Status USBH_SubmitSetupRequest(USBH_HOST *phost, - uint8_t* buff, - uint16_t length) -{ - - /* Save Global State */ - phost->gStateBkp = phost->gState; - - /* Prepare the Transactions */ - phost->gState = HOST_CTRL_XFER; - phost->Control.buff = buff; - phost->Control.length = length; - phost->Control.state = CTRL_SETUP; - - return USBH_OK; -} - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - - diff --git a/example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_stdreq.c b/example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_stdreq.c deleted file mode 100644 index fb90c4ba7..000000000 --- a/example/stm32f4/STM32_USB_HOST_Library/Core/src/usbh_stdreq.c +++ /dev/null @@ -1,551 +0,0 @@ -/** - ****************************************************************************** - * @file usbh_stdreq.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file implements the standard requests for device enumeration - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ -/* Includes ------------------------------------------------------------------*/ - -#include "usbh_ioreq.h" -#include "usbh_stdreq.h" - -/** @addtogroup USBH_LIB -* @{ -*/ - -/** @addtogroup USBH_LIB_CORE -* @{ -*/ - -/** @defgroup USBH_STDREQ -* @brief This file implements the standard requests for device enumeration -* @{ -*/ - - -/** @defgroup USBH_STDREQ_Private_Defines -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBH_STDREQ_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - - -/** @defgroup USBH_STDREQ_Private_Macros -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBH_STDREQ_Private_Variables -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USBH_STDREQ_Private_FunctionPrototypes -* @{ -*/ -static void USBH_ParseDevDesc (USBH_DevDesc_TypeDef* , uint8_t *buf, uint16_t length); - -static void USBH_ParseCfgDesc (USBH_CfgDesc_TypeDef* cfg_desc, - USBH_InterfaceDesc_TypeDef* itf_desc, - USBH_EpDesc_TypeDef* ep_desc, - uint8_t *buf, - uint16_t length); -static USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf, - uint16_t *ptr); - -static void USBH_ParseInterfaceDesc (USBH_InterfaceDesc_TypeDef *if_descriptor, uint8_t *buf); -static void USBH_ParseEPDesc (USBH_EpDesc_TypeDef *ep_descriptor, uint8_t *buf); - -static void USBH_ParseStringDesc (uint8_t* psrc, uint8_t* pdest, uint16_t length); -/** -* @} -*/ - - -/** @defgroup USBH_STDREQ_Private_Functions -* @{ -*/ - - -/** -* @brief USBH_Get_DevDesc -* Issue Get Device Descriptor command to the device. Once the response -* received, it parses the device descriptor and updates the status. -* @param pdev: Selected device -* @param dev_desc: Device Descriptor buffer address -* @param pdev->host.Rx_Buffer: Receive Buffer address -* @param length: Length of the descriptor -* @retval Status -*/ -USBH_Status USBH_Get_DevDesc(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t length) -{ - - USBH_Status status; - - if((status = USBH_GetDescriptor(pdev, - phost, - USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD, - USB_DESC_DEVICE, - pdev->host.Rx_Buffer, - length)) == USBH_OK) - { - /* Commands successfully sent and Response Received */ - USBH_ParseDevDesc(&phost->device_prop.Dev_Desc, pdev->host.Rx_Buffer, length); - } - return status; -} - -/** -* @brief USBH_Get_CfgDesc -* Issues Configuration Descriptor to the device. Once the response -* received, it parses the configuartion descriptor and updates the -* status. -* @param pdev: Selected device -* @param cfg_desc: Configuration Descriptor address -* @param itf_desc: Interface Descriptor address -* @param ep_desc: Endpoint Descriptor address -* @param length: Length of the descriptor -* @retval Status -*/ -USBH_Status USBH_Get_CfgDesc(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint16_t length) - -{ - USBH_Status status; - - if((status = USBH_GetDescriptor(pdev, - phost, - USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD, - USB_DESC_CONFIGURATION, - pdev->host.Rx_Buffer, - length)) == USBH_OK) - { - /* Commands successfully sent and Response Received */ - USBH_ParseCfgDesc (&phost->device_prop.Cfg_Desc, - phost->device_prop.Itf_Desc, - phost->device_prop.Ep_Desc[0], - pdev->host.Rx_Buffer, - length); - - } - return status; -} - - -/** -* @brief USBH_Get_StringDesc -* Issues string Descriptor command to the device. Once the response -* received, it parses the string descriptor and updates the status. -* @param pdev: Selected device -* @param string_index: String index for the descriptor -* @param buff: Buffer address for the descriptor -* @param length: Length of the descriptor -* @retval Status -*/ -USBH_Status USBH_Get_StringDesc(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t string_index, - uint8_t *buff, - uint16_t length) -{ - USBH_Status status; - - if((status = USBH_GetDescriptor(pdev, - phost, - USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD, - USB_DESC_STRING | string_index, - pdev->host.Rx_Buffer, - length)) == USBH_OK) - { - /* Commands successfully sent and Response Received */ - USBH_ParseStringDesc(pdev->host.Rx_Buffer,buff, length); - } - return status; -} - -/** -* @brief USBH_GetDescriptor -* Issues Descriptor command to the device. Once the response received, -* it parses the descriptor and updates the status. -* @param pdev: Selected device -* @param req_type: Descriptor type -* @param value_idx: wValue for the GetDescriptr request -* @param buff: Buffer to store the descriptor -* @param length: Length of the descriptor -* @retval Status -*/ -USBH_Status USBH_GetDescriptor(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t req_type, - uint16_t value_idx, - uint8_t* buff, - uint16_t length ) -{ - phost->Control.setup.b.bmRequestType = USB_D2H | req_type; - phost->Control.setup.b.bRequest = USB_REQ_GET_DESCRIPTOR; - phost->Control.setup.b.wValue.w = value_idx; - - if ((value_idx & 0xff00) == USB_DESC_STRING) - { - phost->Control.setup.b.wIndex.w = 0x0409; - } - else - { - phost->Control.setup.b.wIndex.w = 0; - } - phost->Control.setup.b.wLength.w = length; - return USBH_CtlReq(pdev, phost, buff , length ); -} - -/** -* @brief USBH_SetAddress -* This command sets the address to the connected device -* @param pdev: Selected device -* @param DeviceAddress: Device address to assign -* @retval Status -*/ -USBH_Status USBH_SetAddress(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t DeviceAddress) -{ - phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE | \ - USB_REQ_TYPE_STANDARD; - - phost->Control.setup.b.bRequest = USB_REQ_SET_ADDRESS; - - phost->Control.setup.b.wValue.w = (uint16_t)DeviceAddress; - phost->Control.setup.b.wIndex.w = 0; - phost->Control.setup.b.wLength.w = 0; - - return USBH_CtlReq(pdev, phost, 0 , 0 ); -} - -/** -* @brief USBH_SetCfg -* The command sets the configuration value to the connected device -* @param pdev: Selected device -* @param cfg_idx: Configuration value -* @retval Status -*/ -USBH_Status USBH_SetCfg(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint16_t cfg_idx) -{ - - phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE |\ - USB_REQ_TYPE_STANDARD; - phost->Control.setup.b.bRequest = USB_REQ_SET_CONFIGURATION; - phost->Control.setup.b.wValue.w = cfg_idx; - phost->Control.setup.b.wIndex.w = 0; - phost->Control.setup.b.wLength.w = 0; - - return USBH_CtlReq(pdev, phost, 0 , 0 ); -} - -/** -* @brief USBH_ClrFeature -* This request is used to clear or disable a specific feature. - -* @param pdev: Selected device -* @param ep_num: endpoint number -* @param hc_num: Host channel number -* @retval Status -*/ -USBH_Status USBH_ClrFeature(USB_OTG_CORE_HANDLE *pdev, - USBH_HOST *phost, - uint8_t ep_num, - uint8_t hc_num) -{ - - phost->Control.setup.b.bmRequestType = USB_H2D | - USB_REQ_RECIPIENT_ENDPOINT | - USB_REQ_TYPE_STANDARD; - - phost->Control.setup.b.bRequest = USB_REQ_CLEAR_FEATURE; - phost->Control.setup.b.wValue.w = FEATURE_SELECTOR_ENDPOINT; - phost->Control.setup.b.wIndex.w = ep_num; - phost->Control.setup.b.wLength.w = 0; - - if ((ep_num & USB_REQ_DIR_MASK ) == USB_D2H) - { /* EP Type is IN */ - pdev->host.hc[hc_num].toggle_in = 0; - } - else - {/* EP Type is OUT */ - pdev->host.hc[hc_num].toggle_out = 0; - } - - return USBH_CtlReq(pdev, phost, 0 , 0 ); -} - -/** -* @brief USBH_ParseDevDesc -* This function Parses the device descriptor -* @param dev_desc: device_descriptor destinaton address -* @param buf: Buffer where the source descriptor is available -* @param length: Length of the descriptor -* @retval None -*/ -static void USBH_ParseDevDesc (USBH_DevDesc_TypeDef* dev_desc, - uint8_t *buf, - uint16_t length) -{ - dev_desc->bLength = *(uint8_t *) (buf + 0); - dev_desc->bDescriptorType = *(uint8_t *) (buf + 1); - dev_desc->bcdUSB = LE16 (buf + 2); - dev_desc->bDeviceClass = *(uint8_t *) (buf + 4); - dev_desc->bDeviceSubClass = *(uint8_t *) (buf + 5); - dev_desc->bDeviceProtocol = *(uint8_t *) (buf + 6); - dev_desc->bMaxPacketSize = *(uint8_t *) (buf + 7); - - if (length > 8) - { /* For 1st time after device connection, Host may issue only 8 bytes for - Device Descriptor Length */ - dev_desc->idVendor = LE16 (buf + 8); - dev_desc->idProduct = LE16 (buf + 10); - dev_desc->bcdDevice = LE16 (buf + 12); - dev_desc->iManufacturer = *(uint8_t *) (buf + 14); - dev_desc->iProduct = *(uint8_t *) (buf + 15); - dev_desc->iSerialNumber = *(uint8_t *) (buf + 16); - dev_desc->bNumConfigurations = *(uint8_t *) (buf + 17); - } -} - -/** -* @brief USBH_ParseCfgDesc -* This function Parses the configuration descriptor -* @param cfg_desc: Configuration Descriptor address -* @param itf_desc: Interface Descriptor address -* @param ep_desc: Endpoint Descriptor address -* @param buf: Buffer where the source descriptor is available -* @param length: Length of the descriptor -* @retval None -*/ -static void USBH_ParseCfgDesc (USBH_CfgDesc_TypeDef* cfg_desc, - USBH_InterfaceDesc_TypeDef* itf_desc, - USBH_EpDesc_TypeDef* ep_desc, - uint8_t *buf, - uint16_t length) -{ - USBH_InterfaceDesc_TypeDef *pif ; - USBH_EpDesc_TypeDef *pep; - USBH_DescHeader_t *pdesc = (USBH_DescHeader_t *)buf; - uint16_t ptr; - int8_t if_ix; - int8_t ep_ix; - - pdesc = (USBH_DescHeader_t *)buf; - - /* Parse configuration descriptor */ - cfg_desc->bLength = *(uint8_t *) (buf + 0); - cfg_desc->bDescriptorType = *(uint8_t *) (buf + 1); - cfg_desc->wTotalLength = LE16 (buf + 2); - cfg_desc->bNumInterfaces = *(uint8_t *) (buf + 4); - cfg_desc->bConfigurationValue = *(uint8_t *) (buf + 5); - cfg_desc->iConfiguration = *(uint8_t *) (buf + 6); - cfg_desc->bmAttributes = *(uint8_t *) (buf + 7); - cfg_desc->bMaxPower = *(uint8_t *) (buf + 8); - - - if (length > USB_CONFIGURATION_DESC_SIZE) - { - ptr = USB_LEN_CFG_DESC; - - if ( cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES) - { - if_ix = 0; - pif = (USBH_InterfaceDesc_TypeDef *)0; - - /* Parse Interface descriptor relative to the current configuration */ - if(cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES) - { - while (if_ix < cfg_desc->bNumInterfaces) - { - pdesc = USBH_GetNextDesc((uint8_t *)pdesc, &ptr); - if (pdesc->bDescriptorType == USB_DESC_TYPE_INTERFACE) - { - pif = &itf_desc[if_ix]; - USBH_ParseInterfaceDesc (pif, (uint8_t *)pdesc); - ep_ix = 0; - - /* Parse Ep descriptors relative to the current interface */ - if(pif->bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) - { - while (ep_ix < pif->bNumEndpoints) - { - pdesc = USBH_GetNextDesc((void* )pdesc, &ptr); - if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT) - { - pep = &ep_desc[ep_ix]; - USBH_ParseEPDesc (pep, (uint8_t *)pdesc); - ep_ix++; - } - else - { - ptr += pdesc->bLength; - } - } - } - if_ix++; - } - else - { - ptr += pdesc->bLength; - } - } - } - } - } -} - - -/** -* @brief USBH_ParseInterfaceDesc -* This function Parses the interface descriptor -* @param if_descriptor : Interface descriptor destination -* @param buf: Buffer where the descriptor data is available -* @retval None -*/ -static void USBH_ParseInterfaceDesc (USBH_InterfaceDesc_TypeDef *if_descriptor, - uint8_t *buf) -{ - if_descriptor->bLength = *(uint8_t *) (buf + 0); - if_descriptor->bDescriptorType = *(uint8_t *) (buf + 1); - if_descriptor->bInterfaceNumber = *(uint8_t *) (buf + 2); - if_descriptor->bAlternateSetting = *(uint8_t *) (buf + 3); - if_descriptor->bNumEndpoints = *(uint8_t *) (buf + 4); - if_descriptor->bInterfaceClass = *(uint8_t *) (buf + 5); - if_descriptor->bInterfaceSubClass = *(uint8_t *) (buf + 6); - if_descriptor->bInterfaceProtocol = *(uint8_t *) (buf + 7); - if_descriptor->iInterface = *(uint8_t *) (buf + 8); -} - -/** -* @brief USBH_ParseEPDesc -* This function Parses the endpoint descriptor -* @param ep_descriptor: Endpoint descriptor destination address -* @param buf: Buffer where the parsed descriptor stored -* @retval None -*/ -static void USBH_ParseEPDesc (USBH_EpDesc_TypeDef *ep_descriptor, - uint8_t *buf) -{ - - ep_descriptor->bLength = *(uint8_t *) (buf + 0); - ep_descriptor->bDescriptorType = *(uint8_t *) (buf + 1); - ep_descriptor->bEndpointAddress = *(uint8_t *) (buf + 2); - ep_descriptor->bmAttributes = *(uint8_t *) (buf + 3); - ep_descriptor->wMaxPacketSize = LE16 (buf + 4); - ep_descriptor->bInterval = *(uint8_t *) (buf + 6); -} - -/** -* @brief USBH_ParseStringDesc -* This function Parses the string descriptor -* @param psrc: Source pointer containing the descriptor data -* @param pdest: Destination address pointer -* @param length: Length of the descriptor -* @retval None -*/ -static void USBH_ParseStringDesc (uint8_t* psrc, - uint8_t* pdest, - uint16_t length) -{ - uint16_t strlength; - uint16_t idx; - - /* The UNICODE string descriptor is not NULL-terminated. The string length is - computed by substracting two from the value of the first byte of the descriptor. - */ - - /* Check which is lower size, the Size of string or the length of bytes read - from the device */ - - if ( psrc[1] == USB_DESC_TYPE_STRING) - { /* Make sure the Descriptor is String Type */ - - /* psrc[0] contains Size of Descriptor, subtract 2 to get the length of string */ - strlength = ( ( (psrc[0]-2) <= length) ? (psrc[0]-2) :length); - psrc += 2; /* Adjust the offset ignoring the String Len and Descriptor type */ - - for (idx = 0; idx < strlength; idx+=2 ) - {/* Copy Only the string and ignore the UNICODE ID, hence add the src */ - *pdest = psrc[idx]; - pdest++; - } - *pdest = 0; /* mark end of string */ - } -} - -/** -* @brief USBH_GetNextDesc -* This function return the next descriptor header -* @param buf: Buffer where the cfg descriptor is available -* @param ptr: data popinter inside the cfg descriptor -* @retval next header -*/ -static USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf, uint16_t *ptr) -{ - USBH_DescHeader_t *pnext; - - *ptr += ((USBH_DescHeader_t *)pbuf)->bLength; - pnext = (USBH_DescHeader_t *)((uint8_t *)pbuf + \ - ((USBH_DescHeader_t *)pbuf)->bLength); - - return(pnext); -} - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - - - - diff --git a/example/stm32f4/STM32_USB_OTG_Driver/Release_Notes.html b/example/stm32f4/STM32_USB_OTG_Driver/Release_Notes.html deleted file mode 100644 index 17d2a0832..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/Release_Notes.html +++ /dev/null @@ -1,941 +0,0 @@ - - - - - - - - -Release Notes for STM32F105/7xx and STM32F2xx USB OTG Driver - - - - - -
- -

 

- -
- - - - - -
- - - - - - - -
-

Back to Release page

-
-

Release Notes for STM32F105/7xx and STM32F2xx USB OTG Driver

-

Copyright - 2011 STMicroelectronics

-

-
-

 

- - - - -
-

Contents

-
    -
  1. STM32F105/7xx and STM32F2xx USB OTG Driver update History
  2. -
  3. License
  4. -
-

STM32F105/7xx and STM32F2xx USB OTG Driver  update History

V2.0.0 / 22-July-2011

Main -Changes

-
  • Second official version supporting STM32F105/7 and STM32F2xx devices
  • Rename the Library from "STM32_USB_HOST_Driver" to "STM32_USB_OTG_Driver"
  • Add support for STM32F2xx devices
  • Add support for Device and OTG modes
  • Change HCD layer to support High speed core
  • Change the Low level driver to support multi core support for Host mode
  • Add Stop mechanism for Host and Device modes
  • Change VBUS enabling method, to use the external or the internal VBUS when using the ULPI

V1.0.0 - 11/29/2010

-
  • Created 

License

-

The use of this STM32 software is governed by the terms and conditions of the License Agreement "MCD-ST Liberty SW License Agreement 20Jul2011 v0.1.pdf" available in the root of this package. 

-
-
-
-

For - complete documentation on STM32(CORTEX M3) 32-Bit - Microcontrollers visit www.st.com/STM32

-
-

-
- -
- -

 

- -
- - \ No newline at end of file diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_bsp.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_bsp.h deleted file mode 100644 index 0e7c12eef..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_bsp.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - ****************************************************************************** - * @file usb_bsp.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Specific api's relative to the used hardware platform - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_BSP__H__ -#define __USB_BSP__H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_core.h" -#include "stm32f4_discovery.h" - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_BSP - * @brief This file is the - * @{ - */ - - -/** @defgroup USB_BSP_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_BSP_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_BSP_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_BSP_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_BSP_Exported_FunctionsPrototype - * @{ - */ -void BSP_Init(void); - -void USB_OTG_BSP_Init (USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_BSP_uDelay (const uint32_t usec); -void USB_OTG_BSP_mDelay (const uint32_t msec); -void USB_OTG_BSP_EnableInterrupt (USB_OTG_CORE_HANDLE *pdev); -#ifdef USE_HOST_MODE -void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev,uint8_t state); -#endif -/** - * @} - */ - -#endif //__USB_BSP__H__ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_conf_template.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_conf_template.h deleted file mode 100644 index 39b35529e..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_conf_template.h +++ /dev/null @@ -1,287 +0,0 @@ -/** - ****************************************************************************** - * @file usb_conf.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief general low level driver configuration - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_CONF__H__ -#define __USB_CONF__H__ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f2xx.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_CONF - * @brief USB low level driver configuration file - * @{ - */ - -/** @defgroup USB_CONF_Exported_Defines - * @{ - */ - -/* USB Core and PHY interface configuration. - Tip: To avoid modifying these defines each time you need to change the USB - configuration, you can declare the needed define in your toolchain - compiler preprocessor. - */ -#ifndef USE_USB_OTG_FS - //#define USE_USB_OTG_FS -#endif /* USE_USB_OTG_FS */ - -#ifndef USE_USB_OTG_HS - //#define USE_USB_OTG_HS -#endif /* USE_USB_OTG_HS */ - -#ifndef USE_ULPI_PHY - //#define USE_ULPI_PHY -#endif /* USE_ULPI_PHY */ - -#ifndef USE_EMBEDDED_PHY - //#define USE_EMBEDDED_PHY -#endif /* USE_EMBEDDED_PHY */ - -#ifndef USE_I2C_PHY - //#define USE_I2C_PHY -#endif /* USE_I2C_PHY */ - - -#ifdef USE_USB_OTG_FS - #define USB_OTG_FS_CORE -#endif - -#ifdef USE_USB_OTG_HS - #define USB_OTG_HS_CORE -#endif - -/******************************************************************************* -* FIFO Size Configuration in Device mode -* -* (i) Receive data FIFO size = RAM for setup packets + -* OUT endpoint control information + -* data OUT packets + miscellaneous -* Space = ONE 32-bits words -* --> RAM for setup packets = 10 spaces -* (n is the nbr of CTRL EPs the device core supports) -* --> OUT EP CTRL info = 1 space -* (one space for status information written to the FIFO along with each -* received packet) -* --> data OUT packets = (Largest Packet Size / 4) + 1 spaces -* (MINIMUM to receive packets) -* --> OR data OUT packets = at least 2*(Largest Packet Size / 4) + 1 spaces -* (if high-bandwidth EP is enabled or multiple isochronous EPs) -* --> miscellaneous = 1 space per OUT EP -* (one space for transfer complete status information also pushed to the -* FIFO with each endpoint's last packet) -* -* (ii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for -* that particular IN EP. More space allocated in the IN EP Tx FIFO results -* in a better performance on the USB and can hide latencies on the AHB. -* -* (iii) TXn min size = 16 words. (n : Transmit FIFO index) -* (iv) When a TxFIFO is not used, the Configuration should be as follows: -* case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes) -* --> Txm can use the space allocated for Txn. -* case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes) -* --> Txn should be configured with the minimum space of 16 words -* (v) The FIFO is used optimally when used TxFIFOs are allocated in the top -* of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones. -*******************************************************************************/ - -/******************************************************************************* -* FIFO Size Configuration in Host mode -* -* (i) Receive data FIFO size = (Largest Packet Size / 4) + 1 or -* 2x (Largest Packet Size / 4) + 1, If a -* high-bandwidth channel or multiple isochronous -* channels are enabled -* -* (ii) For the host nonperiodic Transmit FIFO is the largest maximum packet size -* for all supported nonperiodic OUT channels. Typically, a space -* corresponding to two Largest Packet Size is recommended. -* -* (iii) The minimum amount of RAM required for Host periodic Transmit FIFO is -* the largest maximum packet size for all supported periodic OUT channels. -* If there is at least one High Bandwidth Isochronous OUT endpoint, -* then the space must be at least two times the maximum packet size for -* that channel. -*******************************************************************************/ - -/****************** USB OTG HS CONFIGURATION **********************************/ -#ifdef USB_OTG_HS_CORE - #define RX_FIFO_HS_SIZE 512 - #define TX0_FIFO_HS_SIZE 512 - #define TX1_FIFO_HS_SIZE 512 - #define TX2_FIFO_HS_SIZE 0 - #define TX3_FIFO_HS_SIZE 0 - #define TX4_FIFO_HS_SIZE 0 - #define TX5_FIFO_HS_SIZE 0 - #define TXH_NP_HS_FIFOSIZ 96 - #define TXH_P_HS_FIFOSIZ 96 - - //#define USB_OTG_HS_LOW_PWR_MGMT_SUPPORT - //#define USB_OTG_HS_SOF_OUTPUT_ENABLED - - //#define USB_OTG_INTERNAL_VBUS_ENABLED - #define USB_OTG_EXTERNAL_VBUS_ENABLED - - #ifdef USE_ULPI_PHY - #define USB_OTG_ULPI_PHY_ENABLED - #endif - #ifdef USE_EMBEDDED_PHY - #define USB_OTG_EMBEDDED_PHY_ENABLED - #endif - #ifdef USE_I2C_PHY - #define USB_OTG_I2C_PHY_ENABLED - #endif - #define USB_OTG_HS_INTERNAL_DMA_ENABLED - #define USB_OTG_HS_DEDICATED_EP1_ENABLED -#endif - -/****************** USB OTG FS CONFIGURATION **********************************/ -#ifdef USB_OTG_FS_CORE - #define RX_FIFO_FS_SIZE 128 - #define TX0_FIFO_FS_SIZE 64 - #define TX1_FIFO_FS_SIZE 128 - #define TX2_FIFO_FS_SIZE 0 - #define TX3_FIFO_FS_SIZE 0 - #define TXH_NP_HS_FIFOSIZ 96 - #define TXH_P_HS_FIFOSIZ 96 - - //#define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT - //#define USB_OTG_FS_SOF_OUTPUT_ENABLED -#endif - -/****************** USB OTG MODE CONFIGURATION ********************************/ -//#define USE_HOST_MODE -#define USE_DEVICE_MODE -//#define USE_OTG_MODE - - -#ifndef USB_OTG_FS_CORE - #ifndef USB_OTG_HS_CORE - #error "USB_OTG_HS_CORE or USB_OTG_FS_CORE should be defined" - #endif -#endif - - -#ifndef USE_DEVICE_MODE - #ifndef USE_HOST_MODE - #error "USE_DEVICE_MODE or USE_HOST_MODE should be defined" - #endif -#endif - -#ifndef USE_USB_OTG_HS - #ifndef USE_USB_OTG_FS - #error "USE_USB_OTG_HS or USE_USB_OTG_FS should be defined" - #endif -#else //USE_USB_OTG_HS - #ifndef USE_ULPI_PHY - #ifndef USE_EMBEDDED_PHY - #ifndef USE_I2C_PHY - #error "USE_ULPI_PHY or USE_EMBEDDED_PHY or USE_I2C_PHY should be defined" - #endif - #endif - #endif -#endif - -/****************** C Compilers dependant keywords ****************************/ -/* In HS mode and when the DMA is used, all variables and data structures dealing - with the DMA during the transaction process should be 4-bytes aligned */ -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - #if defined (__GNUC__) /* GNU Compiler */ - #define __ALIGN_END __attribute__ ((aligned (4))) - #define __ALIGN_BEGIN - #else - #define __ALIGN_END - #if defined (__CC_ARM) /* ARM Compiler */ - #define __ALIGN_BEGIN __align(4) - #elif defined (__ICCARM__) /* IAR Compiler */ - #define __ALIGN_BEGIN - #elif defined (__TASKING__) /* TASKING Compiler */ - #define __ALIGN_BEGIN __align(4) - #endif /* __CC_ARM */ - #endif /* __GNUC__ */ -#else - #define __ALIGN_BEGIN - #define __ALIGN_END -#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ - -/* __packed keyword used to decrease the data type alignment to 1-byte */ -#if defined (__CC_ARM) /* ARM Compiler */ - #define __packed __packed -#elif defined (__ICCARM__) /* IAR Compiler */ - #define __packed __packed -#elif defined ( __GNUC__ ) /* GNU Compiler */ - #define __packed __attribute__ ((__packed__)) -#elif defined (__TASKING__) /* TASKING Compiler */ - #define __packed __unaligned -#endif /* __CC_ARM */ - -/** - * @} - */ - - -/** @defgroup USB_CONF_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_CONF_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CONF_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -#endif //__USB_CONF__H__ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_core.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_core.h deleted file mode 100644 index 82a09e15c..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_core.h +++ /dev/null @@ -1,408 +0,0 @@ -/** - ****************************************************************************** - * @file usb_core.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Header of the Core Layer - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_CORE_H__ -#define __USB_CORE_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_conf.h" -#include "usb_regs.h" -#include "usb_defines.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_CORE - * @brief usb otg driver core layer - * @{ - */ - - -/** @defgroup USB_CORE_Exported_Defines - * @{ - */ - -#define USB_OTG_EP0_IDLE 0 -#define USB_OTG_EP0_SETUP 1 -#define USB_OTG_EP0_DATA_IN 2 -#define USB_OTG_EP0_DATA_OUT 3 -#define USB_OTG_EP0_STATUS_IN 4 -#define USB_OTG_EP0_STATUS_OUT 5 -#define USB_OTG_EP0_STALL 6 - -#define USB_OTG_EP_TX_DIS 0x0000 -#define USB_OTG_EP_TX_STALL 0x0010 -#define USB_OTG_EP_TX_NAK 0x0020 -#define USB_OTG_EP_TX_VALID 0x0030 - -#define USB_OTG_EP_RX_DIS 0x0000 -#define USB_OTG_EP_RX_STALL 0x1000 -#define USB_OTG_EP_RX_NAK 0x2000 -#define USB_OTG_EP_RX_VALID 0x3000 -/** - * @} - */ -#define MAX_DATA_LENGTH 0xFF - -/** @defgroup USB_CORE_Exported_Types - * @{ - */ - - -typedef enum { - USB_OTG_OK = 0, - USB_OTG_FAIL -}USB_OTG_STS; - -typedef enum { - HC_IDLE = 0, - HC_XFRC, - HC_HALTED, - HC_NAK, - HC_NYET, - HC_STALL, - HC_XACTERR, - HC_BBLERR, - HC_DATATGLERR, -}HC_STATUS; - -typedef enum { - URB_IDLE = 0, - URB_DONE, - URB_NOTREADY, - URB_ERROR, - URB_STALL -}URB_STATE; - -typedef enum { - CTRL_START = 0, - CTRL_XFRC, - CTRL_HALTED, - CTRL_NAK, - CTRL_STALL, - CTRL_XACTERR, - CTRL_BBLERR, - CTRL_DATATGLERR, - CTRL_FAIL -}CTRL_STATUS; - - -typedef struct USB_OTG_hc -{ - uint8_t dev_addr ; - uint8_t ep_num; - uint8_t ep_is_in; - uint8_t speed; - uint8_t do_ping; - uint8_t ep_type; - uint16_t max_packet; - uint8_t data_pid; - uint8_t *xfer_buff; - uint32_t xfer_len; - uint32_t xfer_count; - uint8_t toggle_in; - uint8_t toggle_out; - uint32_t dma_addr; -} -USB_OTG_HC , *PUSB_OTG_HC; - -typedef struct USB_OTG_ep -{ - uint8_t num; - uint8_t is_in; - uint8_t is_stall; - uint8_t type; - uint8_t data_pid_start; - uint8_t even_odd_frame; - uint16_t tx_fifo_num; - uint32_t maxpacket; - /* transaction level variables*/ - uint8_t *xfer_buff; - uint32_t dma_addr; - uint32_t xfer_len; - uint32_t xfer_count; - /* Transfer level variables*/ - uint32_t rem_data_len; - uint32_t total_data_len; - uint32_t ctl_data_len; - -} - -USB_OTG_EP , *PUSB_OTG_EP; - - - -typedef struct USB_OTG_core_cfg -{ - uint8_t host_channels; - uint8_t dev_endpoints; - uint8_t speed; - uint8_t dma_enable; - uint16_t mps; - uint16_t TotalFifoSize; - uint8_t phy_itface; - uint8_t Sof_output; - uint8_t low_power; - uint8_t coreID; - -} -USB_OTG_CORE_CFGS, *PUSB_OTG_CORE_CFGS; - - - -typedef struct usb_setup_req { - - uint8_t bmRequest; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -} USB_SETUP_REQ; - -typedef struct _Device_TypeDef -{ - uint8_t *(*GetDeviceDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetLangIDStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetManufacturerStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetProductStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetSerialStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetConfigurationStrDescriptor)( uint8_t speed , uint16_t *length); - uint8_t *(*GetInterfaceStrDescriptor)( uint8_t speed , uint16_t *length); -} USBD_DEVICE, *pUSBD_DEVICE; - -typedef struct USB_OTG_hPort -{ - void (*Disconnect) (void *phost); - void (*Connect) (void *phost); - uint8_t ConnStatus; - uint8_t DisconnStatus; - uint8_t ConnHandled; - uint8_t DisconnHandled; -} USB_OTG_hPort_TypeDef; - -typedef struct _Device_cb -{ - uint8_t (*Init) (void *pdev , uint8_t cfgidx); - uint8_t (*DeInit) (void *pdev , uint8_t cfgidx); - /* Control Endpoints*/ - uint8_t (*Setup) (void *pdev , USB_SETUP_REQ *req); - uint8_t (*EP0_TxSent) (void *pdev ); - uint8_t (*EP0_RxReady) (void *pdev ); - /* Class Specific Endpoints*/ - uint8_t (*DataIn) (void *pdev , uint8_t epnum); - uint8_t (*DataOut) (void *pdev , uint8_t epnum); - uint8_t (*SOF) (void *pdev); - uint8_t (*IsoINIncomplete) (void *pdev); - uint8_t (*IsoOUTIncomplete) (void *pdev); - - uint8_t *(*GetConfigDescriptor)( uint8_t speed , uint16_t *length); -#ifdef USB_OTG_HS_CORE - uint8_t *(*GetOtherConfigDescriptor)( uint8_t speed , uint16_t *length); -#endif - -#ifdef USB_SUPPORT_USER_STRING_DESC - uint8_t *(*GetUsrStrDescriptor)( uint8_t speed ,uint8_t index, uint16_t *length); -#endif - -} USBD_Class_cb_TypeDef; - - - -typedef struct _USBD_USR_PROP -{ - void (*Init)(void); - void (*DeviceReset)(uint8_t speed); - void (*DeviceConfigured)(void); - void (*DeviceSuspended)(void); - void (*DeviceResumed)(void); - - void (*DeviceConnected)(void); - void (*DeviceDisconnected)(void); - -} -USBD_Usr_cb_TypeDef; - -typedef struct _DCD -{ - uint8_t device_config; - uint8_t device_state; - uint8_t device_status; - uint8_t device_address; - uint32_t DevRemoteWakeup; - USB_OTG_EP in_ep [USB_OTG_MAX_TX_FIFOS]; - USB_OTG_EP out_ep [USB_OTG_MAX_TX_FIFOS]; - uint8_t setup_packet [8*3]; - USBD_Class_cb_TypeDef *class_cb; - USBD_Usr_cb_TypeDef *usr_cb; - USBD_DEVICE *usr_device; - uint8_t *pConfig_descriptor; - } -DCD_DEV , *DCD_PDEV; - - -typedef struct _HCD -{ - uint8_t Rx_Buffer [MAX_DATA_LENGTH]; - __IO uint32_t ConnSts; - __IO uint32_t ErrCnt[USB_OTG_MAX_TX_FIFOS]; - __IO uint32_t XferCnt[USB_OTG_MAX_TX_FIFOS]; - __IO HC_STATUS HC_Status[USB_OTG_MAX_TX_FIFOS]; - __IO URB_STATE URB_State[USB_OTG_MAX_TX_FIFOS]; - USB_OTG_HC hc [USB_OTG_MAX_TX_FIFOS]; - uint16_t channel [USB_OTG_MAX_TX_FIFOS]; - USB_OTG_hPort_TypeDef *port_cb; -} -HCD_DEV , *USB_OTG_USBH_PDEV; - - -typedef struct _OTG -{ - uint8_t OTG_State; - uint8_t OTG_PrevState; - uint8_t OTG_Mode; -} -OTG_DEV , *USB_OTG_USBO_PDEV; - -typedef struct USB_OTG_handle -{ - USB_OTG_CORE_CFGS cfg; - USB_OTG_CORE_REGS regs; -#ifdef USE_DEVICE_MODE - DCD_DEV dev; -#endif -#ifdef USE_HOST_MODE - HCD_DEV host; -#endif -#ifdef USE_OTG_MODE - OTG_DEV otg; -#endif -} -USB_OTG_CORE_HANDLE , *PUSB_OTG_CORE_HANDLE; - -/** - * @} - */ - - -/** @defgroup USB_CORE_Exported_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_CORE_Exported_FunctionsPrototype - * @{ - */ - - -USB_OTG_STS USB_OTG_CoreInit (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_SelectCore (USB_OTG_CORE_HANDLE *pdev, - USB_OTG_CORE_ID_TypeDef coreID); -USB_OTG_STS USB_OTG_EnableGlobalInt (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev); -void* USB_OTG_ReadPacket (USB_OTG_CORE_HANDLE *pdev , - uint8_t *dest, - uint16_t len); -USB_OTG_STS USB_OTG_WritePacket (USB_OTG_CORE_HANDLE *pdev , - uint8_t *src, - uint8_t ch_ep_num, - uint16_t len); -USB_OTG_STS USB_OTG_FlushTxFifo (USB_OTG_CORE_HANDLE *pdev , uint32_t num); -USB_OTG_STS USB_OTG_FlushRxFifo (USB_OTG_CORE_HANDLE *pdev); - -uint32_t USB_OTG_ReadCoreItr (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ReadOtgItr (USB_OTG_CORE_HANDLE *pdev); -uint8_t USB_OTG_IsHostMode (USB_OTG_CORE_HANDLE *pdev); -uint8_t USB_OTG_IsDeviceMode (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_GetMode (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_PhyInit (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_SetCurrentMode (USB_OTG_CORE_HANDLE *pdev, - uint8_t mode); - -/*********************** HOST APIs ********************************************/ -#ifdef USE_HOST_MODE -USB_OTG_STS USB_OTG_CoreInitHost (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_EnableHostInt (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_HC_Init (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num); -USB_OTG_STS USB_OTG_HC_Halt (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num); -USB_OTG_STS USB_OTG_HC_StartXfer (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num); -USB_OTG_STS USB_OTG_HC_DoPing (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num); -uint32_t USB_OTG_ReadHostAllChannels_intr (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ResetPort (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ReadHPRT0 (USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state); -void USB_OTG_InitFSLSPClkSel (USB_OTG_CORE_HANDLE *pdev ,uint8_t freq); -uint8_t USB_OTG_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev) ; -void USB_OTG_StopHost (USB_OTG_CORE_HANDLE *pdev); -#endif -/********************* DEVICE APIs ********************************************/ -#ifdef USE_DEVICE_MODE -USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_EnableDevInt (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ReadDevAllInEPItr (USB_OTG_CORE_HANDLE *pdev); -enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_EP0Activate (USB_OTG_CORE_HANDLE *pdev); -USB_OTG_STS USB_OTG_EPActivate (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EPStartXfer (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EPSetStall (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -USB_OTG_STS USB_OTG_EPClearStall (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep); -uint32_t USB_OTG_ReadDevAllOutEp_itr (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_ReadDevOutEP_itr (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); -uint32_t USB_OTG_ReadDevAllInEPItr (USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_InitDevSpeed (USB_OTG_CORE_HANDLE *pdev , uint8_t speed); -uint8_t USBH_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev); -void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status); -uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep); -#endif -/** - * @} - */ - -#endif /* __USB_CORE_H__ */ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_dcd.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_dcd.h deleted file mode 100644 index 6bfd89939..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_dcd.h +++ /dev/null @@ -1,158 +0,0 @@ -/** - ****************************************************************************** - * @file usb_dcd.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Peripheral Driver Header file - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __DCD_H__ -#define __DCD_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_core.h" - - -/** @addtogroup USB_OTG_DRIVER -* @{ -*/ - -/** @defgroup USB_DCD -* @brief This file is the -* @{ -*/ - - -/** @defgroup USB_DCD_Exported_Defines -* @{ -*/ -#define USB_OTG_EP_CONTROL 0 -#define USB_OTG_EP_ISOC 1 -#define USB_OTG_EP_BULK 2 -#define USB_OTG_EP_INT 3 -#define USB_OTG_EP_MASK 3 - -/* Device Status */ -#define USB_OTG_DEFAULT 1 -#define USB_OTG_ADDRESSED 2 -#define USB_OTG_CONFIGURED 3 -#define USB_OTG_SUSPENDED 4 - -/** -* @} -*/ - - -/** @defgroup USB_DCD_Exported_Types -* @{ -*/ -/******************************************************************************** -Data structure type -********************************************************************************/ -typedef struct -{ - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bEndpointAddress; - uint8_t bmAttributes; - uint16_t wMaxPacketSize; - uint8_t bInterval; -} -EP_DESCRIPTOR , *PEP_DESCRIPTOR; - -/** -* @} -*/ - - -/** @defgroup USB_DCD_Exported_Macros -* @{ -*/ -/** -* @} -*/ - -/** @defgroup USB_DCD_Exported_Variables -* @{ -*/ -/** -* @} -*/ - -/** @defgroup USB_DCD_Exported_FunctionsPrototype -* @{ -*/ -/******************************************************************************** -EXPORTED FUNCTION FROM THE USB-OTG LAYER -********************************************************************************/ -void DCD_Init(USB_OTG_CORE_HANDLE *pdev , - USB_OTG_CORE_ID_TypeDef coreID); - -void DCD_DevConnect (USB_OTG_CORE_HANDLE *pdev); -void DCD_DevDisconnect (USB_OTG_CORE_HANDLE *pdev); -void DCD_EP_SetAddress (USB_OTG_CORE_HANDLE *pdev, - uint8_t address); -uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev , - uint8_t ep_addr, - uint16_t ep_mps, - uint8_t ep_type); - -uint32_t DCD_EP_Close (USB_OTG_CORE_HANDLE *pdev, - uint8_t ep_addr); - - -uint32_t DCD_EP_PrepareRx ( USB_OTG_CORE_HANDLE *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint16_t buf_len); - -uint32_t DCD_EP_Tx (USB_OTG_CORE_HANDLE *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint32_t buf_len); -uint32_t DCD_EP_Stall (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum); -uint32_t DCD_EP_ClrStall (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum); -uint32_t DCD_EP_Flush (USB_OTG_CORE_HANDLE *pdev, - uint8_t epnum); -uint32_t DCD_Handle_ISR(USB_OTG_CORE_HANDLE *pdev); - -uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev , - uint8_t epnum); - -void DCD_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , - uint8_t epnum , - uint32_t Status); - -/** -* @} -*/ - - -#endif //__DCD_H__ - - -/** -* @} -*/ - -/** -* @} -*/ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h deleted file mode 100644 index 9df1a4172..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_dcd_int.h +++ /dev/null @@ -1,121 +0,0 @@ -/** - ****************************************************************************** - * @file usb_dcd_int.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Peripheral Device Interface Layer - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef USB_DCD_INT_H__ -#define USB_DCD_INT_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_dcd.h" - - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_DCD_INT - * @brief This file is the - * @{ - */ - - -/** @defgroup USB_DCD_INT_Exported_Defines - * @{ - */ - -typedef struct _USBD_DCD_INT -{ - uint8_t (* DataOutStage) (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); - uint8_t (* DataInStage) (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum); - uint8_t (* SetupStage) (USB_OTG_CORE_HANDLE *pdev); - uint8_t (* SOF) (USB_OTG_CORE_HANDLE *pdev); - uint8_t (* Reset) (USB_OTG_CORE_HANDLE *pdev); - uint8_t (* Suspend) (USB_OTG_CORE_HANDLE *pdev); - uint8_t (* Resume) (USB_OTG_CORE_HANDLE *pdev); - uint8_t (* IsoINIncomplete) (USB_OTG_CORE_HANDLE *pdev); - uint8_t (* IsoOUTIncomplete) (USB_OTG_CORE_HANDLE *pdev); - - uint8_t (* DevConnected) (USB_OTG_CORE_HANDLE *pdev); - uint8_t (* DevDisconnected) (USB_OTG_CORE_HANDLE *pdev); - -}USBD_DCD_INT_cb_TypeDef; - -extern USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops; -/** - * @} - */ - - -/** @defgroup USB_DCD_INT_Exported_Types - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_DCD_INT_Exported_Macros - * @{ - */ - -#define CLEAR_IN_EP_INTR(epnum,intr) \ - diepint.d32=0; \ - diepint.b.intr = 1; \ - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT,diepint.d32); - -#define CLEAR_OUT_EP_INTR(epnum,intr) \ - doepint.d32=0; \ - doepint.b.intr = 1; \ - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT,doepint.d32); - -/** - * @} - */ - -/** @defgroup USB_DCD_INT_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_DCD_INT_Exported_FunctionsPrototype - * @{ - */ - -uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev); - -/** - * @} - */ - - -#endif // USB_DCD_INT_H__ - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_defines.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_defines.h deleted file mode 100644 index b119c2586..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_defines.h +++ /dev/null @@ -1,244 +0,0 @@ -/** - ****************************************************************************** - * @file usb_defines.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Header of the Core Layer - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_DEF_H__ -#define __USB_DEF_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_conf.h" - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_DEFINES - * @brief This file is the - * @{ - */ - - -/** @defgroup USB_DEFINES_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup _CORE_DEFINES_ - * @{ - */ - -#define USB_OTG_SPEED_PARAM_HIGH 0 -#define USB_OTG_SPEED_PARAM_HIGH_IN_FULL 1 -#define USB_OTG_SPEED_PARAM_FULL 3 - -#define USB_OTG_SPEED_HIGH 0 -#define USB_OTG_SPEED_FULL 1 - -#define USB_OTG_ULPI_PHY 1 -#define USB_OTG_EMBEDDED_PHY 2 -#define USB_OTG_I2C_PHY 3 - -/** - * @} - */ - - -/** @defgroup _GLOBAL_DEFINES_ - * @{ - */ -#define GAHBCFG_TXFEMPTYLVL_EMPTY 1 -#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0 -#define GAHBCFG_GLBINT_ENABLE 1 -#define GAHBCFG_INT_DMA_BURST_SINGLE 0 -#define GAHBCFG_INT_DMA_BURST_INCR 1 -#define GAHBCFG_INT_DMA_BURST_INCR4 3 -#define GAHBCFG_INT_DMA_BURST_INCR8 5 -#define GAHBCFG_INT_DMA_BURST_INCR16 7 -#define GAHBCFG_DMAENABLE 1 -#define GAHBCFG_TXFEMPTYLVL_EMPTY 1 -#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0 -#define GRXSTS_PKTSTS_IN 2 -#define GRXSTS_PKTSTS_IN_XFER_COMP 3 -#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5 -#define GRXSTS_PKTSTS_CH_HALTED 7 -/** - * @} - */ - - -/** @defgroup _OnTheGo_DEFINES_ - * @{ - */ -#define MODE_HNP_SRP_CAPABLE 0 -#define MODE_SRP_ONLY_CAPABLE 1 -#define MODE_NO_HNP_SRP_CAPABLE 2 -#define MODE_SRP_CAPABLE_DEVICE 3 -#define MODE_NO_SRP_CAPABLE_DEVICE 4 -#define MODE_SRP_CAPABLE_HOST 5 -#define MODE_NO_SRP_CAPABLE_HOST 6 -#define A_HOST 1 -#define A_SUSPEND 2 -#define A_PERIPHERAL 3 -#define B_PERIPHERAL 4 -#define B_HOST 5 -#define DEVICE_MODE 0 -#define HOST_MODE 1 -#define OTG_MODE 2 -/** - * @} - */ - - -/** @defgroup __DEVICE_DEFINES_ - * @{ - */ -#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0 -#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1 -#define DSTS_ENUMSPD_LS_PHY_6MHZ 2 -#define DSTS_ENUMSPD_FS_PHY_48MHZ 3 - -#define DCFG_FRAME_INTERVAL_80 0 -#define DCFG_FRAME_INTERVAL_85 1 -#define DCFG_FRAME_INTERVAL_90 2 -#define DCFG_FRAME_INTERVAL_95 3 - -#define DEP0CTL_MPS_64 0 -#define DEP0CTL_MPS_32 1 -#define DEP0CTL_MPS_16 2 -#define DEP0CTL_MPS_8 3 - -#define EP_SPEED_LOW 0 -#define EP_SPEED_FULL 1 -#define EP_SPEED_HIGH 2 - -#define EP_TYPE_CTRL 0 -#define EP_TYPE_ISOC 1 -#define EP_TYPE_BULK 2 -#define EP_TYPE_INTR 3 -#define EP_TYPE_MSK 3 - -#define STS_GOUT_NAK 1 -#define STS_DATA_UPDT 2 -#define STS_XFER_COMP 3 -#define STS_SETUP_COMP 4 -#define STS_SETUP_UPDT 6 -/** - * @} - */ - - -/** @defgroup __HOST_DEFINES_ - * @{ - */ -#define HC_PID_DATA0 0 -#define HC_PID_DATA2 1 -#define HC_PID_DATA1 2 -#define HC_PID_SETUP 3 - -#define HPRT0_PRTSPD_HIGH_SPEED 0 -#define HPRT0_PRTSPD_FULL_SPEED 1 -#define HPRT0_PRTSPD_LOW_SPEED 2 - -#define HCFG_30_60_MHZ 0 -#define HCFG_48_MHZ 1 -#define HCFG_6_MHZ 2 - -#define HCCHAR_CTRL 0 -#define HCCHAR_ISOC 1 -#define HCCHAR_BULK 2 -#define HCCHAR_INTR 3 - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - -/** - * @} - */ - - -/** @defgroup USB_DEFINES_Exported_Types - * @{ - */ - -typedef enum -{ - USB_OTG_HS_CORE_ID = 0, - USB_OTG_FS_CORE_ID = 1 -}USB_OTG_CORE_ID_TypeDef; -/** - * @} - */ - - -/** @defgroup USB_DEFINES_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_DEFINES_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_DEFINES_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -/** @defgroup Internal_Macro's - * @{ - */ -#define USB_OTG_READ_REG32(reg) (*(__IO uint32_t *)reg) -#define USB_OTG_WRITE_REG32(reg,value) (*(__IO uint32_t *)reg = value) -#define USB_OTG_MODIFY_REG32(reg,clear_mask,set_mask) \ - USB_OTG_WRITE_REG32(reg, (((USB_OTG_READ_REG32(reg)) & ~clear_mask) | set_mask ) ) - -/******************************************************************************** - ENUMERATION TYPE -********************************************************************************/ -enum USB_OTG_SPEED { - USB_SPEED_UNKNOWN = 0, - USB_SPEED_LOW, - USB_SPEED_FULL, - USB_SPEED_HIGH -}; - -#endif //__USB_DEFINES__H__ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_hcd.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_hcd.h deleted file mode 100644 index 15e8ab161..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_hcd.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - ****************************************************************************** - * @file usb_hcd.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Host layer Header file - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_HCD_H__ -#define __USB_HCD_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_regs.h" -#include "usb_core.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_HCD - * @brief This file is the - * @{ - */ - - -/** @defgroup USB_HCD_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_HCD_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_HCD_Exported_FunctionsPrototype - * @{ - */ -uint32_t HCD_Init (USB_OTG_CORE_HANDLE *pdev , - USB_OTG_CORE_ID_TypeDef coreID); -uint32_t HCD_HC_Init (USB_OTG_CORE_HANDLE *pdev , - uint8_t hc_num); -uint32_t HCD_SubmitRequest (USB_OTG_CORE_HANDLE *pdev , - uint8_t hc_num) ; -uint32_t HCD_GetCurrentSpeed (USB_OTG_CORE_HANDLE *pdev); -uint32_t HCD_ResetPort (USB_OTG_CORE_HANDLE *pdev); -uint32_t HCD_IsDeviceConnected (USB_OTG_CORE_HANDLE *pdev); -uint32_t HCD_GetCurrentFrame (USB_OTG_CORE_HANDLE *pdev) ; -URB_STATE HCD_GetURB_State (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num); -uint32_t HCD_GetXferCnt (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num); -HC_STATUS HCD_GetHCState (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num) ; -/** - * @} - */ - -#endif //__USB_HCD_H__ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h deleted file mode 100644 index c95c59f82..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_hcd_int.h +++ /dev/null @@ -1,126 +0,0 @@ -/** - ****************************************************************************** - * @file usb_hcd_int.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Peripheral Device Interface Layer - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __HCD_INT_H__ -#define __HCD_INT_H__ - - -/* Includes ------------------------------------------------------------------*/ -#include "usb_hcd.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_HCD_INT - * @brief This file is the - * @{ - */ - - -/** @defgroup USB_HCD_INT_Exported_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_INT_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_INT_Exported_Macros - * @{ - */ - -#define CLEAR_HC_INT(HC_REGS, intr) \ - {\ - USB_OTG_HCINTn_TypeDef hcint_clear; \ - hcint_clear.d32 = 0; \ - hcint_clear.b.intr = 1; \ - USB_OTG_WRITE_REG32(&((HC_REGS)->HCINT), hcint_clear.d32);\ - }\ - -#define MASK_HOST_INT_CHH(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ - GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ - GINTMSK.b.chhltd = 0; \ - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} - -#define UNMASK_HOST_INT_CHH(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ - GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ - GINTMSK.b.chhltd = 1; \ - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} - -#define MASK_HOST_INT_ACK(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ - GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ - GINTMSK.b.ack = 0; \ - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} - -#define UNMASK_HOST_INT_ACK(hc_num) { USB_OTG_HCGINTMSK_TypeDef GINTMSK; \ - GINTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK); \ - GINTMSK.b.ack = 1; \ - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, GINTMSK.d32);} - -/** - * @} - */ - -/** @defgroup USB_HCD_INT_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_HCD_INT_Exported_FunctionsPrototype - * @{ - */ -/* Callbacks handler */ -void ConnectCallback_Handler(USB_OTG_CORE_HANDLE *pdev); -void Disconnect_Callback_Handler(USB_OTG_CORE_HANDLE *pdev); -void Overcurrent_Callback_Handler(USB_OTG_CORE_HANDLE *pdev); -uint32_t USBH_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev); - -/** - * @} - */ - - - -#endif //__HCD_INT_H__ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_otg.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_otg.h deleted file mode 100644 index 54d61b827..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_otg.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - ****************************************************************************** - * @file usb_otg.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief OTG Core Header - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_OTG__ -#define __USB_OTG__ - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_OTG - * @brief This file is the - * @{ - */ - - -/** @defgroup USB_OTG_Exported_Defines - * @{ - */ - - -void USB_OTG_InitiateSRP(void); -void USB_OTG_InitiateHNP(uint8_t state , uint8_t mode); -void USB_OTG_Switchback (USB_OTG_CORE_HANDLE *pdev); -uint32_t USB_OTG_GetCurrentState (USB_OTG_CORE_HANDLE *pdev); - -uint32_t STM32_USBO_OTG_ISR_Handler(USB_OTG_CORE_HANDLE *pdev); -/** - * @} - */ - - -/** @defgroup USB_OTG_Exported_Types - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_OTG_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_OTG_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_OTG_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -#endif //__USB_OTG__ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_regs.h b/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_regs.h deleted file mode 100644 index cd71ddfaf..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/inc/usb_regs.h +++ /dev/null @@ -1,1206 +0,0 @@ -/** - ****************************************************************************** - * @file usb_regs.h - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief hardware registers - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __USB_OTG_REGS_H__ -#define __USB_OTG_REGS_H__ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_conf.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_REGS - * @brief This file is the - * @{ - */ - - -/** @defgroup USB_REGS_Exported_Defines - * @{ - */ - -#define USB_OTG_HS_BASE_ADDR 0x40040000 -#define USB_OTG_FS_BASE_ADDR 0x50000000 - -#define USB_OTG_CORE_GLOBAL_REGS_OFFSET 0x000 -#define USB_OTG_DEV_GLOBAL_REG_OFFSET 0x800 -#define USB_OTG_DEV_IN_EP_REG_OFFSET 0x900 -#define USB_OTG_EP_REG_OFFSET 0x20 -#define USB_OTG_DEV_OUT_EP_REG_OFFSET 0xB00 -#define USB_OTG_HOST_GLOBAL_REG_OFFSET 0x400 -#define USB_OTG_HOST_PORT_REGS_OFFSET 0x440 -#define USB_OTG_HOST_CHAN_REGS_OFFSET 0x500 -#define USB_OTG_CHAN_REGS_OFFSET 0x20 -#define USB_OTG_PCGCCTL_OFFSET 0xE00 -#define USB_OTG_DATA_FIFO_OFFSET 0x1000 -#define USB_OTG_DATA_FIFO_SIZE 0x1000 - - -#define USB_OTG_MAX_TX_FIFOS 15 - -#define USB_OTG_HS_MAX_PACKET_SIZE 512 -#define USB_OTG_FS_MAX_PACKET_SIZE 64 -#define USB_OTG_MAX_EP0_SIZE 64 -/** - * @} - */ - -/** @defgroup USB_REGS_Exported_Types - * @{ - */ - -/** @defgroup __USB_OTG_Core_register - * @{ - */ -typedef struct _USB_OTG_GREGS //000h -{ - __IO uint32_t GOTGCTL; /* USB_OTG Control and Status Register 000h*/ - __IO uint32_t GOTGINT; /* USB_OTG Interrupt Register 004h*/ - __IO uint32_t GAHBCFG; /* Core AHB Configuration Register 008h*/ - __IO uint32_t GUSBCFG; /* Core USB Configuration Register 00Ch*/ - __IO uint32_t GRSTCTL; /* Core Reset Register 010h*/ - __IO uint32_t GINTSTS; /* Core Interrupt Register 014h*/ - __IO uint32_t GINTMSK; /* Core Interrupt Mask Register 018h*/ - __IO uint32_t GRXSTSR; /* Receive Sts Q Read Register 01Ch*/ - __IO uint32_t GRXSTSP; /* Receive Sts Q Read & POP Register 020h*/ - __IO uint32_t GRXFSIZ; /* Receive FIFO Size Register 024h*/ - __IO uint32_t DIEPTXF0_HNPTXFSIZ; /* EP0 / Non Periodic Tx FIFO Size Register 028h*/ - __IO uint32_t HNPTXSTS; /* Non Periodic Tx FIFO/Queue Sts reg 02Ch*/ - __IO uint32_t GI2CCTL; /* I2C Access Register 030h*/ - uint32_t Reserved34; /* PHY Vendor Control Register 034h*/ - __IO uint32_t GCCFG; /* General Purpose IO Register 038h*/ - __IO uint32_t CID; /* User ID Register 03Ch*/ - uint32_t Reserved40[48]; /* Reserved 040h-0FFh*/ - __IO uint32_t HPTXFSIZ; /* Host Periodic Tx FIFO Size Reg 100h*/ - __IO uint32_t DIEPTXF[USB_OTG_MAX_TX_FIFOS];/* dev Periodic Transmit FIFO */ -} -USB_OTG_GREGS; -/** - * @} - */ - - -/** @defgroup __device_Registers - * @{ - */ -typedef struct _USB_OTG_DREGS // 800h -{ - __IO uint32_t DCFG; /* dev Configuration Register 800h*/ - __IO uint32_t DCTL; /* dev Control Register 804h*/ - __IO uint32_t DSTS; /* dev Status Register (RO) 808h*/ - uint32_t Reserved0C; /* Reserved 80Ch*/ - __IO uint32_t DIEPMSK; /* dev IN Endpoint Mask 810h*/ - __IO uint32_t DOEPMSK; /* dev OUT Endpoint Mask 814h*/ - __IO uint32_t DAINT; /* dev All Endpoints Itr Reg 818h*/ - __IO uint32_t DAINTMSK; /* dev All Endpoints Itr Mask 81Ch*/ - uint32_t Reserved20; /* Reserved 820h*/ - uint32_t Reserved9; /* Reserved 824h*/ - __IO uint32_t DVBUSDIS; /* dev VBUS discharge Register 828h*/ - __IO uint32_t DVBUSPULSE; /* dev VBUS Pulse Register 82Ch*/ - __IO uint32_t DTHRCTL; /* dev thr 830h*/ - __IO uint32_t DIEPEMPMSK; /* dev empty msk 834h*/ - __IO uint32_t DEACHINT; /* dedicated EP interrupt 838h*/ - __IO uint32_t DEACHMSK; /* dedicated EP msk 83Ch*/ - uint32_t Reserved40; /* dedicated EP mask 840h*/ - __IO uint32_t DINEP1MSK; /* dedicated EP mask 844h*/ - uint32_t Reserved44[15]; /* Reserved 844-87Ch*/ - __IO uint32_t DOUTEP1MSK; /* dedicated EP msk 884h*/ -} -USB_OTG_DREGS; -/** - * @} - */ - - -/** @defgroup __IN_Endpoint-Specific_Register - * @{ - */ -typedef struct _USB_OTG_INEPREGS -{ - __IO uint32_t DIEPCTL; /* dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h*/ - uint32_t Reserved04; /* Reserved 900h + (ep_num * 20h) + 04h*/ - __IO uint32_t DIEPINT; /* dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h*/ - uint32_t Reserved0C; /* Reserved 900h + (ep_num * 20h) + 0Ch*/ - __IO uint32_t DIEPTSIZ; /* IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h*/ - __IO uint32_t DIEPDMA; /* IN Endpoint DMA Address Reg 900h + (ep_num * 20h) + 14h*/ - __IO uint32_t DTXFSTS;/*IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h*/ - uint32_t Reserved18; /* Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/ -} -USB_OTG_INEPREGS; -/** - * @} - */ - - -/** @defgroup __OUT_Endpoint-Specific_Registers - * @{ - */ -typedef struct _USB_OTG_OUTEPREGS -{ - __IO uint32_t DOEPCTL; /* dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h*/ - __IO uint32_t DOUTEPFRM; /* dev OUT Endpoint Frame number B00h + (ep_num * 20h) + 04h*/ - __IO uint32_t DOEPINT; /* dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h*/ - uint32_t Reserved0C; /* Reserved B00h + (ep_num * 20h) + 0Ch*/ - __IO uint32_t DOEPTSIZ; /* dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h*/ - __IO uint32_t DOEPDMA; /* dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h*/ - uint32_t Reserved18[2]; /* Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/ -} -USB_OTG_OUTEPREGS; -/** - * @} - */ - - -/** @defgroup __Host_Mode_Register_Structures - * @{ - */ -typedef struct _USB_OTG_HREGS -{ - __IO uint32_t HCFG; /* Host Configuration Register 400h*/ - __IO uint32_t HFIR; /* Host Frame Interval Register 404h*/ - __IO uint32_t HFNUM; /* Host Frame Nbr/Frame Remaining 408h*/ - uint32_t Reserved40C; /* Reserved 40Ch*/ - __IO uint32_t HPTXSTS; /* Host Periodic Tx FIFO/ Queue Status 410h*/ - __IO uint32_t HAINT; /* Host All Channels Interrupt Register 414h*/ - __IO uint32_t HAINTMSK; /* Host All Channels Interrupt Mask 418h*/ -} -USB_OTG_HREGS; -/** - * @} - */ - - -/** @defgroup __Host_Channel_Specific_Registers - * @{ - */ -typedef struct _USB_OTG_HC_REGS -{ - __IO uint32_t HCCHAR; - __IO uint32_t HCSPLT; - __IO uint32_t HCINT; - __IO uint32_t HCGINTMSK; - __IO uint32_t HCTSIZ; - __IO uint32_t HCDMA; - uint32_t Reserved[2]; -} -USB_OTG_HC_REGS; -/** - * @} - */ - - -/** @defgroup __otg_Core_registers - * @{ - */ -typedef struct USB_OTG_core_regs //000h -{ - USB_OTG_GREGS *GREGS; - USB_OTG_DREGS *DREGS; - USB_OTG_HREGS *HREGS; - USB_OTG_INEPREGS *INEP_REGS[USB_OTG_MAX_TX_FIFOS]; - USB_OTG_OUTEPREGS *OUTEP_REGS[USB_OTG_MAX_TX_FIFOS]; - USB_OTG_HC_REGS *HC_REGS[USB_OTG_MAX_TX_FIFOS]; - __IO uint32_t *HPRT0; - __IO uint32_t *DFIFO[USB_OTG_MAX_TX_FIFOS]; - __IO uint32_t *PCGCCTL; -} -USB_OTG_CORE_REGS , *PUSB_OTG_CORE_REGS; -typedef union _USB_OTG_OTGCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t sesreqscs : - 1; -uint32_t sesreq : - 1; -uint32_t Reserved2_7 : - 6; -uint32_t hstnegscs : - 1; -uint32_t hnpreq : - 1; -uint32_t hstsethnpen : - 1; -uint32_t devhnpen : - 1; -uint32_t Reserved12_15 : - 4; -uint32_t conidsts : - 1; -uint32_t Reserved17 : - 1; -uint32_t asesvld : - 1; -uint32_t bsesvld : - 1; -uint32_t currmod : - 1; -uint32_t Reserved21_31 : - 11; - } - b; -} USB_OTG_OTGCTL_TypeDef ; -typedef union _USB_OTG_GOTGINT_TypeDef -{ - uint32_t d32; - struct - { -uint32_t Reserved0_1 : - 2; -uint32_t sesenddet : - 1; -uint32_t Reserved3_7 : - 5; -uint32_t sesreqsucstschng : - 1; -uint32_t hstnegsucstschng : - 1; -uint32_t reserver10_16 : - 7; -uint32_t hstnegdet : - 1; -uint32_t adevtoutchng : - 1; -uint32_t debdone : - 1; -uint32_t Reserved31_20 : - 12; - } - b; -} USB_OTG_GOTGINT_TypeDef ; -typedef union _USB_OTG_GAHBCFG_TypeDef -{ - uint32_t d32; - struct - { -uint32_t glblintrmsk : - 1; -uint32_t hburstlen : - 4; -uint32_t dmaenable : - 1; -uint32_t Reserved : - 1; -uint32_t nptxfemplvl_txfemplvl : - 1; -uint32_t ptxfemplvl : - 1; -uint32_t Reserved9_31 : - 23; - } - b; -} USB_OTG_GAHBCFG_TypeDef ; -typedef union _USB_OTG_GUSBCFG_TypeDef -{ - uint32_t d32; - struct - { -uint32_t toutcal : - 3; -uint32_t phyif : - 1; -uint32_t ulpi_utmi_sel : - 1; -uint32_t fsintf : - 1; -uint32_t physel : - 1; -uint32_t ddrsel : - 1; -uint32_t srpcap : - 1; -uint32_t hnpcap : - 1; -uint32_t usbtrdtim : - 4; -uint32_t nptxfrwnden : - 1; -uint32_t phylpwrclksel : - 1; -uint32_t otgutmifssel : - 1; -uint32_t ulpi_fsls : - 1; -uint32_t ulpi_auto_res : - 1; -uint32_t ulpi_clk_sus_m : - 1; -uint32_t ulpi_ext_vbus_drv : - 1; -uint32_t ulpi_int_vbus_indicator : - 1; -uint32_t term_sel_dl_pulse : - 1; -uint32_t Reserved : - 6; -uint32_t force_host : - 1; -uint32_t force_dev : - 1; -uint32_t corrupt_tx : - 1; - } - b; -} USB_OTG_GUSBCFG_TypeDef ; -typedef union _USB_OTG_GRSTCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t csftrst : - 1; -uint32_t hsftrst : - 1; -uint32_t hstfrm : - 1; -uint32_t intknqflsh : - 1; -uint32_t rxfflsh : - 1; -uint32_t txfflsh : - 1; -uint32_t txfnum : - 5; -uint32_t Reserved11_29 : - 19; -uint32_t dmareq : - 1; -uint32_t ahbidle : - 1; - } - b; -} USB_OTG_GRSTCTL_TypeDef ; -typedef union _USB_OTG_GINTMSK_TypeDef -{ - uint32_t d32; - struct - { -uint32_t Reserved0 : - 1; -uint32_t modemismatch : - 1; -uint32_t otgintr : - 1; -uint32_t sofintr : - 1; -uint32_t rxstsqlvl : - 1; -uint32_t nptxfempty : - 1; -uint32_t ginnakeff : - 1; -uint32_t goutnakeff : - 1; -uint32_t Reserved8 : - 1; -uint32_t i2cintr : - 1; -uint32_t erlysuspend : - 1; -uint32_t usbsuspend : - 1; -uint32_t usbreset : - 1; -uint32_t enumdone : - 1; -uint32_t isooutdrop : - 1; -uint32_t eopframe : - 1; -uint32_t Reserved16 : - 1; -uint32_t epmismatch : - 1; -uint32_t inepintr : - 1; -uint32_t outepintr : - 1; -uint32_t incomplisoin : - 1; -uint32_t incomplisoout : - 1; -uint32_t Reserved22_23 : - 2; -uint32_t portintr : - 1; -uint32_t hcintr : - 1; -uint32_t ptxfempty : - 1; -uint32_t Reserved27 : - 1; -uint32_t conidstschng : - 1; -uint32_t disconnect : - 1; -uint32_t sessreqintr : - 1; -uint32_t wkupintr : - 1; - } - b; -} USB_OTG_GINTMSK_TypeDef ; -typedef union _USB_OTG_GINTSTS_TypeDef -{ - uint32_t d32; - struct - { -uint32_t curmode : - 1; -uint32_t modemismatch : - 1; -uint32_t otgintr : - 1; -uint32_t sofintr : - 1; -uint32_t rxstsqlvl : - 1; -uint32_t nptxfempty : - 1; -uint32_t ginnakeff : - 1; -uint32_t goutnakeff : - 1; -uint32_t Reserved8 : - 1; -uint32_t i2cintr : - 1; -uint32_t erlysuspend : - 1; -uint32_t usbsuspend : - 1; -uint32_t usbreset : - 1; -uint32_t enumdone : - 1; -uint32_t isooutdrop : - 1; -uint32_t eopframe : - 1; -uint32_t intimerrx : - 1; -uint32_t epmismatch : - 1; -uint32_t inepint: - 1; -uint32_t outepintr : - 1; -uint32_t incomplisoin : - 1; -uint32_t incomplisoout : - 1; -uint32_t Reserved22_23 : - 2; -uint32_t portintr : - 1; -uint32_t hcintr : - 1; -uint32_t ptxfempty : - 1; -uint32_t Reserved27 : - 1; -uint32_t conidstschng : - 1; -uint32_t disconnect : - 1; -uint32_t sessreqintr : - 1; -uint32_t wkupintr : - 1; - } - b; -} USB_OTG_GINTSTS_TypeDef ; -typedef union _USB_OTG_DRXSTS_TypeDef -{ - uint32_t d32; - struct - { -uint32_t epnum : - 4; -uint32_t bcnt : - 11; -uint32_t dpid : - 2; -uint32_t pktsts : - 4; -uint32_t fn : - 4; -uint32_t Reserved : - 7; - } - b; -} USB_OTG_DRXSTS_TypeDef ; -typedef union _USB_OTG_GRXSTS_TypeDef -{ - uint32_t d32; - struct - { -uint32_t chnum : - 4; -uint32_t bcnt : - 11; -uint32_t dpid : - 2; -uint32_t pktsts : - 4; -uint32_t Reserved : - 11; - } - b; -} USB_OTG_GRXFSTS_TypeDef ; -typedef union _USB_OTG_FSIZ_TypeDef -{ - uint32_t d32; - struct - { -uint32_t startaddr : - 16; -uint32_t depth : - 16; - } - b; -} USB_OTG_FSIZ_TypeDef ; -typedef union _USB_OTG_HNPTXSTS_TypeDef -{ - uint32_t d32; - struct - { -uint32_t nptxfspcavail : - 16; -uint32_t nptxqspcavail : - 8; -uint32_t nptxqtop_terminate : - 1; -uint32_t nptxqtop_timer : - 2; -uint32_t nptxqtop : - 2; -uint32_t chnum : - 2; -uint32_t Reserved : - 1; - } - b; -} USB_OTG_HNPTXSTS_TypeDef ; -typedef union _USB_OTG_DTXFSTSn_TypeDef -{ - uint32_t d32; - struct - { -uint32_t txfspcavail : - 16; -uint32_t Reserved : - 16; - } - b; -} USB_OTG_DTXFSTSn_TypeDef ; -typedef union _USB_OTG_GI2CCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t rwdata : - 8; -uint32_t regaddr : - 8; -uint32_t addr : - 7; -uint32_t i2cen : - 1; -uint32_t ack : - 1; -uint32_t i2csuspctl : - 1; -uint32_t i2cdevaddr : - 2; -uint32_t dat_se0: - 1; -uint32_t Reserved : - 1; -uint32_t rw : - 1; -uint32_t bsydne : - 1; - } - b; -} USB_OTG_GI2CCTL_TypeDef ; -typedef union _USB_OTG_GCCFG_TypeDef -{ - uint32_t d32; - struct - { -uint32_t Reserved_in : - 16; -uint32_t pwdn : - 1; -uint32_t i2cifen : - 1; -uint32_t vbussensingA : - 1; -uint32_t vbussensingB : - 1; -uint32_t sofouten : - 1; -uint32_t disablevbussensing : - 1; -uint32_t Reserved_out : - 10; - } - b; -} USB_OTG_GCCFG_TypeDef ; - -typedef union _USB_OTG_DCFG_TypeDef -{ - uint32_t d32; - struct - { -uint32_t devspd : - 2; -uint32_t nzstsouthshk : - 1; -uint32_t Reserved3 : - 1; -uint32_t devaddr : - 7; -uint32_t perfrint : - 2; -uint32_t Reserved13_17 : - 5; -uint32_t epmscnt : - 4; - } - b; -} USB_OTG_DCFG_TypeDef ; -typedef union _USB_OTG_DCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t rmtwkupsig : - 1; -uint32_t sftdiscon : - 1; -uint32_t gnpinnaksts : - 1; -uint32_t goutnaksts : - 1; -uint32_t tstctl : - 3; -uint32_t sgnpinnak : - 1; -uint32_t cgnpinnak : - 1; -uint32_t sgoutnak : - 1; -uint32_t cgoutnak : - 1; -uint32_t Reserved : - 21; - } - b; -} USB_OTG_DCTL_TypeDef ; -typedef union _USB_OTG_DSTS_TypeDef -{ - uint32_t d32; - struct - { -uint32_t suspsts : - 1; -uint32_t enumspd : - 2; -uint32_t errticerr : - 1; -uint32_t Reserved4_7: - 4; -uint32_t soffn : - 14; -uint32_t Reserved22_31 : - 10; - } - b; -} USB_OTG_DSTS_TypeDef ; -typedef union _USB_OTG_DIEPINTn_TypeDef -{ - uint32_t d32; - struct - { -uint32_t xfercompl : - 1; -uint32_t epdisabled : - 1; -uint32_t ahberr : - 1; -uint32_t timeout : - 1; -uint32_t intktxfemp : - 1; -uint32_t intknepmis : - 1; -uint32_t inepnakeff : - 1; -uint32_t emptyintr : - 1; -uint32_t txfifoundrn : - 1; -uint32_t Reserved08_31 : - 23; - } - b; -} USB_OTG_DIEPINTn_TypeDef ; -typedef union _USB_OTG_DIEPINTn_TypeDef USB_OTG_DIEPMSK_TypeDef ; -typedef union _USB_OTG_DOEPINTn_TypeDef -{ - uint32_t d32; - struct - { -uint32_t xfercompl : - 1; -uint32_t epdisabled : - 1; -uint32_t ahberr : - 1; -uint32_t setup : - 1; -uint32_t Reserved04_31 : - 28; - } - b; -} USB_OTG_DOEPINTn_TypeDef ; -typedef union _USB_OTG_DOEPINTn_TypeDef USB_OTG_DOEPMSK_TypeDef ; - -typedef union _USB_OTG_DAINT_TypeDef -{ - uint32_t d32; - struct - { -uint32_t in : - 16; -uint32_t out : - 16; - } - ep; -} USB_OTG_DAINT_TypeDef ; - -typedef union _USB_OTG_DTHRCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t non_iso_thr_en : - 1; -uint32_t iso_thr_en : - 1; -uint32_t tx_thr_len : - 9; -uint32_t Reserved11_15 : - 5; -uint32_t rx_thr_en : - 1; -uint32_t rx_thr_len : - 9; -uint32_t Reserved26_31 : - 6; - } - b; -} USB_OTG_DTHRCTL_TypeDef ; -typedef union _USB_OTG_DEPCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t mps : - 11; -uint32_t reserved : - 4; -uint32_t usbactep : - 1; -uint32_t dpid : - 1; -uint32_t naksts : - 1; -uint32_t eptype : - 2; -uint32_t snp : - 1; -uint32_t stall : - 1; -uint32_t txfnum : - 4; -uint32_t cnak : - 1; -uint32_t snak : - 1; -uint32_t setd0pid : - 1; -uint32_t setd1pid : - 1; -uint32_t epdis : - 1; -uint32_t epena : - 1; - } - b; -} USB_OTG_DEPCTL_TypeDef ; -typedef union _USB_OTG_DEPXFRSIZ_TypeDef -{ - uint32_t d32; - struct - { -uint32_t xfersize : - 19; -uint32_t pktcnt : - 10; -uint32_t mc : - 2; -uint32_t Reserved : - 1; - } - b; -} USB_OTG_DEPXFRSIZ_TypeDef ; -typedef union _USB_OTG_DEP0XFRSIZ_TypeDef -{ - uint32_t d32; - struct - { -uint32_t xfersize : - 7; -uint32_t Reserved7_18 : - 12; -uint32_t pktcnt : - 2; -uint32_t Reserved20_28 : - 9; -uint32_t supcnt : - 2; - uint32_t Reserved31; - } - b; -} USB_OTG_DEP0XFRSIZ_TypeDef ; -typedef union _USB_OTG_HCFG_TypeDef -{ - uint32_t d32; - struct - { -uint32_t fslspclksel : - 2; -uint32_t fslssupp : - 1; - } - b; -} USB_OTG_HCFG_TypeDef ; -typedef union _USB_OTG_HFRMINTRVL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t frint : - 16; -uint32_t Reserved : - 16; - } - b; -} USB_OTG_HFRMINTRVL_TypeDef ; - -typedef union _USB_OTG_HFNUM_TypeDef -{ - uint32_t d32; - struct - { -uint32_t frnum : - 16; -uint32_t frrem : - 16; - } - b; -} USB_OTG_HFNUM_TypeDef ; -typedef union _USB_OTG_HPTXSTS_TypeDef -{ - uint32_t d32; - struct - { -uint32_t ptxfspcavail : - 16; -uint32_t ptxqspcavail : - 8; -uint32_t ptxqtop_terminate : - 1; -uint32_t ptxqtop_timer : - 2; -uint32_t ptxqtop : - 2; -uint32_t chnum : - 2; -uint32_t ptxqtop_odd : - 1; - } - b; -} USB_OTG_HPTXSTS_TypeDef ; -typedef union _USB_OTG_HPRT0_TypeDef -{ - uint32_t d32; - struct - { -uint32_t prtconnsts : - 1; -uint32_t prtconndet : - 1; -uint32_t prtena : - 1; -uint32_t prtenchng : - 1; -uint32_t prtovrcurract : - 1; -uint32_t prtovrcurrchng : - 1; -uint32_t prtres : - 1; -uint32_t prtsusp : - 1; -uint32_t prtrst : - 1; -uint32_t Reserved9 : - 1; -uint32_t prtlnsts : - 2; -uint32_t prtpwr : - 1; -uint32_t prttstctl : - 4; -uint32_t prtspd : - 2; -uint32_t Reserved19_31 : - 13; - } - b; -} USB_OTG_HPRT0_TypeDef ; -typedef union _USB_OTG_HAINT_TypeDef -{ - uint32_t d32; - struct - { -uint32_t chint : - 16; -uint32_t Reserved : - 16; - } - b; -} USB_OTG_HAINT_TypeDef ; -typedef union _USB_OTG_HAINTMSK_TypeDef -{ - uint32_t d32; - struct - { -uint32_t chint : - 16; -uint32_t Reserved : - 16; - } - b; -} USB_OTG_HAINTMSK_TypeDef ; -typedef union _USB_OTG_HCCHAR_TypeDef -{ - uint32_t d32; - struct - { -uint32_t mps : - 11; -uint32_t epnum : - 4; -uint32_t epdir : - 1; -uint32_t Reserved : - 1; -uint32_t lspddev : - 1; -uint32_t eptype : - 2; -uint32_t multicnt : - 2; -uint32_t devaddr : - 7; -uint32_t oddfrm : - 1; -uint32_t chdis : - 1; -uint32_t chen : - 1; - } - b; -} USB_OTG_HCCHAR_TypeDef ; -typedef union _USB_OTG_HCSPLT_TypeDef -{ - uint32_t d32; - struct - { -uint32_t prtaddr : - 7; -uint32_t hubaddr : - 7; -uint32_t xactpos : - 2; -uint32_t compsplt : - 1; -uint32_t Reserved : - 14; -uint32_t spltena : - 1; - } - b; -} USB_OTG_HCSPLT_TypeDef ; -typedef union _USB_OTG_HCINTn_TypeDef -{ - uint32_t d32; - struct - { -uint32_t xfercompl : - 1; -uint32_t chhltd : - 1; -uint32_t ahberr : - 1; -uint32_t stall : - 1; -uint32_t nak : - 1; -uint32_t ack : - 1; -uint32_t nyet : - 1; -uint32_t xacterr : - 1; -uint32_t bblerr : - 1; -uint32_t frmovrun : - 1; -uint32_t datatglerr : - 1; -uint32_t Reserved : - 21; - } - b; -} USB_OTG_HCINTn_TypeDef ; -typedef union _USB_OTG_HCTSIZn_TypeDef -{ - uint32_t d32; - struct - { -uint32_t xfersize : - 19; -uint32_t pktcnt : - 10; -uint32_t pid : - 2; -uint32_t dopng : - 1; - } - b; -} USB_OTG_HCTSIZn_TypeDef ; -typedef union _USB_OTG_HCGINTMSK_TypeDef -{ - uint32_t d32; - struct - { -uint32_t xfercompl : - 1; -uint32_t chhltd : - 1; -uint32_t ahberr : - 1; -uint32_t stall : - 1; -uint32_t nak : - 1; -uint32_t ack : - 1; -uint32_t nyet : - 1; -uint32_t xacterr : - 1; -uint32_t bblerr : - 1; -uint32_t frmovrun : - 1; -uint32_t datatglerr : - 1; -uint32_t Reserved : - 21; - } - b; -} USB_OTG_HCGINTMSK_TypeDef ; -typedef union _USB_OTG_PCGCCTL_TypeDef -{ - uint32_t d32; - struct - { -uint32_t stoppclk : - 1; -uint32_t gatehclk : - 1; -uint32_t Reserved : - 30; - } - b; -} USB_OTG_PCGCCTL_TypeDef ; - -/** - * @} - */ - - -/** @defgroup USB_REGS_Exported_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_REGS_Exported_Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_REGS_Exported_FunctionsPrototype - * @{ - */ -/** - * @} - */ - - -#endif //__USB_OTG_REGS_H__ - - -/** - * @} - */ - -/** - * @} - */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_bsp_template.c b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_bsp_template.c deleted file mode 100644 index c3f515bcd..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_bsp_template.c +++ /dev/null @@ -1,200 +0,0 @@ -/** - ****************************************************************************** - * @file usb_bsp.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief This file is responsible to offer board support package and is - * configurable by user. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_bsp.h" - -/** @addtogroup USB_OTG_DRIVER -* @{ -*/ - -/** @defgroup USB_BSP - * @brief This file is responsible to offer board support package - * @{ - */ - -/** @defgroup USB_BSP_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_BSP_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - - - -/** @defgroup USB_BSP_Private_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup USBH_BSP_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup USBH_BSP_Private_FunctionPrototypes - * @{ - */ -/** - * @} - */ - -/** @defgroup USB_BSP_Private_Functions - * @{ - */ - - -/** - * @brief USB_OTG_BSP_Init - * Initilizes BSP configurations - * @param None - * @retval None - */ - -void USB_OTG_BSP_Init(void) -{ - -} -/** - * @brief USB_OTG_BSP_EnableInterrupt - * Enabele USB Global interrupt - * @param None - * @retval None - */ -void USB_OTG_BSP_EnableInterrupt(void) -{ - -} - -/** - * @brief BSP_Drive_VBUS - * Drives the Vbus signal through IO - * @param speed : Full, Low - * @param state : VBUS states - * @retval None - */ - -void USB_OTG_BSP_DriveVBUS(uint32_t speed, uint8_t state) -{ - -} - -/** - * @brief USB_OTG_BSP_ConfigVBUS - * Configures the IO for the Vbus and OverCurrent - * @param Speed : Full, Low - * @retval None - */ - -void USB_OTG_BSP_ConfigVBUS(uint32_t speed) -{ - -} - -/** - * @brief USB_OTG_BSP_TimeInit - * Initialises delay unit Systick timer /Timer2 - * @param None - * @retval None - */ -void USB_OTG_BSP_TimeInit ( void ) -{ - -} - -/** - * @brief USB_OTG_BSP_uDelay - * This function provides delay time in micro sec - * @param usec : Value of delay required in micro sec - * @retval None - */ -void USB_OTG_BSP_uDelay (const uint32_t usec) -{ - - uint32_t count = 0; - const uint32_t utime = (120 * usec / 7); - do - { - if ( ++count > utime ) - { - return ; - } - } - while (1); - -} - - -/** - * @brief USB_OTG_BSP_mDelay - * This function provides delay time in milli sec - * @param msec : Value of delay required in milli sec - * @retval None - */ -void USB_OTG_BSP_mDelay (const uint32_t msec) -{ - - USB_OTG_BSP_uDelay(msec * 1000); - -} - - -/** - * @brief USB_OTG_BSP_TimerIRQ - * Time base IRQ - * @param None - * @retval None - */ - -void USB_OTG_BSP_TimerIRQ (void) -{ - -} - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_core.c b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_core.c deleted file mode 100644 index 74e432ac2..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_core.c +++ /dev/null @@ -1,2187 +0,0 @@ -/** - ****************************************************************************** - * @file usb_core.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief USB-OTG Core Layer - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_core.h" -#include "usb_bsp.h" - - -/** @addtogroup USB_OTG_DRIVER -* @{ -*/ - -/** @defgroup USB_CORE -* @brief This file includes the USB-OTG Core Layer -* @{ -*/ - - -/** @defgroup USB_CORE_Private_Defines -* @{ -*/ - -/** -* @} -*/ - - -/** @defgroup USB_CORE_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - - -/** @defgroup USB_CORE_Private_Macros -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_CORE_Private_Variables -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_CORE_Private_FunctionPrototypes -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_CORE_Private_Functions -* @{ -*/ - -/** -* @brief USB_OTG_EnableCommonInt -* Initializes the commmon interrupts, used in both device and modes -* @param pdev : Selected device -* @retval None -*/ -static void USB_OTG_EnableCommonInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTMSK_TypeDef int_mask; - - int_mask.d32 = 0; - /* Clear any pending USB_OTG Interrupts */ -#ifndef USE_OTG_MODE - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GOTGINT, 0xFFFFFFFF); -#endif - /* Clear any pending interrupts */ - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF); - /* Enable the interrupts in the INTMSK */ - int_mask.b.wkupintr = 1; - int_mask.b.usbsuspend = 1; - -#ifdef USE_OTG_MODE - int_mask.b.otgintr = 1; - int_mask.b.sessreqintr = 1; - int_mask.b.conidstschng = 1; -#endif - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32); -} - -/** -* @brief USB_OTG_CoreReset : Soft reset of the core -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -static USB_OTG_STS USB_OTG_CoreReset(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - __IO USB_OTG_GRSTCTL_TypeDef greset; - uint32_t count = 0; - - greset.d32 = 0; - /* Wait for AHB master IDLE state. */ - do - { - USB_OTG_BSP_uDelay(3); - greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL); - if (++count > 200000) - { - return USB_OTG_OK; - } - } - while (greset.b.ahbidle == 0); - /* Core Soft Reset */ - count = 0; - greset.b.csftrst = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRSTCTL, greset.d32 ); - do - { - greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL); - if (++count > 200000) - { - break; - } - } - while (greset.b.csftrst == 1); - /* Wait for 3 PHY Clocks*/ - USB_OTG_BSP_uDelay(3); - return status; -} - -/** -* @brief USB_OTG_WritePacket : Writes a packet into the Tx FIFO associated -* with the EP -* @param pdev : Selected device -* @param src : source pointer -* @param ch_ep_num : end point number -* @param bytes : No. of bytes -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_WritePacket(USB_OTG_CORE_HANDLE *pdev, - uint8_t *src, - uint8_t ch_ep_num, - uint16_t len) -{ - USB_OTG_STS status = USB_OTG_OK; - if (pdev->cfg.dma_enable == 0) - { - uint32_t count32b= 0 , i= 0; - __IO uint32_t *fifo; - - count32b = (len + 3) / 4; - fifo = pdev->regs.DFIFO[ch_ep_num]; - for (i = 0; i < count32b; i++, src+=4) - { - USB_OTG_WRITE_REG32( fifo, *((__packed uint32_t *)src) ); - } - } - return status; -} - - -/** -* @brief USB_OTG_ReadPacket : Reads a packet from the Rx FIFO -* @param pdev : Selected device -* @param dest : Destination Pointer -* @param bytes : No. of bytes -* @retval None -*/ -void *USB_OTG_ReadPacket(USB_OTG_CORE_HANDLE *pdev, - uint8_t *dest, - uint16_t len) -{ - uint32_t i=0; - uint32_t count32b = (len + 3) / 4; - - __IO uint32_t *fifo = pdev->regs.DFIFO[0]; - - for ( i = 0; i < count32b; i++, dest += 4 ) - { - *(__packed uint32_t *)dest = USB_OTG_READ_REG32(fifo); - - } - return ((void *)dest); -} - -/** -* @brief USB_OTG_SelectCore -* Initialize core registers address. -* @param pdev : Selected device -* @param coreID : USB OTG Core ID -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_SelectCore(USB_OTG_CORE_HANDLE *pdev, - USB_OTG_CORE_ID_TypeDef coreID) -{ - uint32_t i , baseAddress = 0; - USB_OTG_STS status = USB_OTG_OK; - - pdev->cfg.dma_enable = 0; - - /* at startup the core is in FS mode */ - pdev->cfg.speed = USB_OTG_SPEED_FULL; - pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ; - - /* initialize device cfg following its address */ - if (coreID == USB_OTG_FS_CORE_ID) - { - baseAddress = USB_OTG_FS_BASE_ADDR; - pdev->cfg.coreID = USB_OTG_FS_CORE_ID; - pdev->cfg.host_channels = 8 ; - pdev->cfg.dev_endpoints = 4 ; - pdev->cfg.TotalFifoSize = 320; /* in 32-bits */ - pdev->cfg.phy_itface = USB_OTG_EMBEDDED_PHY; - -#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED - pdev->cfg.Sof_output = 1; -#endif - -#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT - pdev->cfg.low_power = 1; -#endif - } - else if (coreID == USB_OTG_HS_CORE_ID) - { - baseAddress = USB_OTG_HS_BASE_ADDR; - pdev->cfg.coreID = USB_OTG_HS_CORE_ID; - pdev->cfg.host_channels = 12 ; - pdev->cfg.dev_endpoints = 6 ; - pdev->cfg.TotalFifoSize = 1280;/* in 32-bits */ - -#ifdef USB_OTG_ULPI_PHY_ENABLED - pdev->cfg.phy_itface = USB_OTG_ULPI_PHY; -#else - #ifdef USB_OTG_EMBEDDED_PHY_ENABLED - pdev->cfg.phy_itface = USB_OTG_EMBEDDED_PHY; - #else - #ifdef USB_OTG_I2C_PHY_ENABLED - pdev->cfg.phy_itface = USB_OTG_I2C_PHY; - #endif - #endif -#endif - -#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - pdev->cfg.dma_enable = 1; -#endif - -#ifdef USB_OTG_HS_SOF_OUTPUT_ENABLED - pdev->cfg.Sof_output = 1; -#endif - -#ifdef USB_OTG_HS_LOW_PWR_MGMT_SUPPORT - pdev->cfg.low_power = 1; -#endif - - } - - pdev->regs.GREGS = (USB_OTG_GREGS *)(baseAddress + \ - USB_OTG_CORE_GLOBAL_REGS_OFFSET); - pdev->regs.DREGS = (USB_OTG_DREGS *) (baseAddress + \ - USB_OTG_DEV_GLOBAL_REG_OFFSET); - - for (i = 0; i < pdev->cfg.dev_endpoints; i++) - { - pdev->regs.INEP_REGS[i] = (USB_OTG_INEPREGS *) \ - (baseAddress + USB_OTG_DEV_IN_EP_REG_OFFSET + \ - (i * USB_OTG_EP_REG_OFFSET)); - pdev->regs.OUTEP_REGS[i] = (USB_OTG_OUTEPREGS *) \ - (baseAddress + USB_OTG_DEV_OUT_EP_REG_OFFSET + \ - (i * USB_OTG_EP_REG_OFFSET)); - } - pdev->regs.HREGS = (USB_OTG_HREGS *)(baseAddress + \ - USB_OTG_HOST_GLOBAL_REG_OFFSET); - pdev->regs.HPRT0 = (uint32_t *)(baseAddress + USB_OTG_HOST_PORT_REGS_OFFSET); - - for (i = 0; i < pdev->cfg.host_channels; i++) - { - pdev->regs.HC_REGS[i] = (USB_OTG_HC_REGS *)(baseAddress + \ - USB_OTG_HOST_CHAN_REGS_OFFSET + \ - (i * USB_OTG_CHAN_REGS_OFFSET)); - } - for (i = 0; i < pdev->cfg.host_channels; i++) - { - pdev->regs.DFIFO[i] = (uint32_t *)(baseAddress + USB_OTG_DATA_FIFO_OFFSET +\ - (i * USB_OTG_DATA_FIFO_SIZE)); - } - pdev->regs.PCGCCTL = (uint32_t *)(baseAddress + USB_OTG_PCGCCTL_OFFSET); - - return status; -} - - -/** -* @brief USB_OTG_CoreInit -* Initializes the USB_OTG controller registers and prepares the core -* device mode or host mode operation. -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_CoreInit(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GUSBCFG_TypeDef usbcfg; - USB_OTG_GCCFG_TypeDef gccfg; - USB_OTG_GI2CCTL_TypeDef i2cctl; - USB_OTG_GAHBCFG_TypeDef ahbcfg; - - usbcfg.d32 = 0; - gccfg.d32 = 0; - ahbcfg.d32 = 0; - - - - if (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY) - { - gccfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GCCFG); - gccfg.b.pwdn = 0; - - if (pdev->cfg.Sof_output) - { - gccfg.b.sofouten = 1; - } - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32); - - /* Init The ULPI Interface */ - usbcfg.d32 = 0; - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - - usbcfg.b.physel = 0; /* HS Interface */ -#ifdef USB_OTG_INTERNAL_VBUS_ENABLED - usbcfg.b.ulpi_ext_vbus_drv = 0; /* Use internal VBUS */ -#else - #ifdef USB_OTG_EXTERNAL_VBUS_ENABLED - usbcfg.b.ulpi_ext_vbus_drv = 1; /* Use external VBUS */ - #endif -#endif - usbcfg.b.term_sel_dl_pulse = 0; /* Data line pulsing using utmi_txvalid */ - usbcfg.b.ulpi_utmi_sel = 1; /* ULPI seleInterfacect */ - - usbcfg.b.phyif = 0; /* 8 bits */ - usbcfg.b.ddrsel = 0; /* single data rate */ - - usbcfg.b.ulpi_fsls = 0; - usbcfg.b.ulpi_clk_sus_m = 0; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - - /* Reset after a PHY select */ - USB_OTG_CoreReset(pdev); - - if(pdev->cfg.dma_enable == 1) - { - - ahbcfg.b.hburstlen = 5; /* 64 x 32-bits*/ - ahbcfg.b.dmaenable = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32); - - } - } - else /* FS interface (embedded Phy or I2C Phy) */ - { - - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);; - usbcfg.b.physel = 1; /* FS Interface */ - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - /* Reset after a PHY select and set Host mode */ - USB_OTG_CoreReset(pdev); - /* Enable the I2C interface and deactivate the power down*/ - gccfg.d32 = 0; - gccfg.b.pwdn = 1; - - if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) - { - gccfg.b.i2cifen = 1; - } - gccfg.b.vbussensingA = 1 ; - gccfg.b.vbussensingB = 1 ; -#ifndef VBUS_SENSING_ENABLED - gccfg.b.disablevbussensing = 1; -#endif - - if(pdev->cfg.Sof_output) - { - gccfg.b.sofouten = 1; - } - - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32); - USB_OTG_BSP_mDelay(20); - /* Program GUSBCFG.OtgUtmifsSel to I2C*/ - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - - if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) - { - usbcfg.b.otgutmifssel = 1; - } - - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - - if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY) - { - /*Program GI2CCTL.I2CEn*/ - i2cctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GI2CCTL); - i2cctl.b.i2cdevaddr = 1; - i2cctl.b.i2cen = 0; - i2cctl.b.dat_se0 = 1; - i2cctl.b.addr = 0x2D; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GI2CCTL, i2cctl.d32); - - USB_OTG_BSP_mDelay(200); - - i2cctl.b.i2cen = 1; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GI2CCTL, i2cctl.d32); - USB_OTG_BSP_mDelay(200); - } - } - /* case the HS core is working in FS mode */ - if(pdev->cfg.dma_enable == 1) - { - - ahbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GAHBCFG); - ahbcfg.b.hburstlen = 5; /* 64 x 32-bits*/ - ahbcfg.b.dmaenable = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32); - - } - /* initialize OTG features */ -#ifdef USE_OTG_MODE - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - usbcfg.b.hnpcap = 1; - usbcfg.b.srpcap = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - USB_OTG_EnableCommonInt(pdev); -#endif - return status; -} -/** -* @brief USB_OTG_EnableGlobalInt -* Enables the controller's Global Int in the AHB Config reg -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EnableGlobalInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GAHBCFG_TypeDef ahbcfg; - - ahbcfg.d32 = 0; - ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ - USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GAHBCFG, 0, ahbcfg.d32); - return status; -} - - -/** -* @brief USB_OTG_DisableGlobalInt -* Enables the controller's Global Int in the AHB Config reg -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GAHBCFG_TypeDef ahbcfg; - ahbcfg.d32 = 0; - ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ - USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32, 0); - return status; -} - - -/** -* @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO -* @param pdev : Selected device -* @param num : FO num -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_FlushTxFifo (USB_OTG_CORE_HANDLE *pdev , uint32_t num ) -{ - USB_OTG_STS status = USB_OTG_OK; - __IO USB_OTG_GRSTCTL_TypeDef greset; - - uint32_t count = 0; - greset.d32 = 0; - greset.b.txfflsh = 1; - greset.b.txfnum = num; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GRSTCTL, greset.d32 ); - do - { - greset.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRSTCTL); - if (++count > 200000) - { - break; - } - } - while (greset.b.txfflsh == 1); - /* Wait for 3 PHY Clocks*/ - USB_OTG_BSP_uDelay(3); - return status; -} - - -/** -* @brief USB_OTG_FlushRxFifo : Flush a Rx FIFO -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_FlushRxFifo( USB_OTG_CORE_HANDLE *pdev ) -{ - USB_OTG_STS status = USB_OTG_OK; - __IO USB_OTG_GRSTCTL_TypeDef greset; - uint32_t count = 0; - - greset.d32 = 0; - greset.b.rxfflsh = 1; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GRSTCTL, greset.d32 ); - do - { - greset.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRSTCTL); - if (++count > 200000) - { - break; - } - } - while (greset.b.rxfflsh == 1); - /* Wait for 3 PHY Clocks*/ - USB_OTG_BSP_uDelay(3); - return status; -} - - -/** -* @brief USB_OTG_SetCurrentMode : Set ID line -* @param pdev : Selected device -* @param mode : (Host/device) -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_SetCurrentMode(USB_OTG_CORE_HANDLE *pdev , uint8_t mode) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GUSBCFG_TypeDef usbcfg; - - usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - - usbcfg.b.force_host = 0; - usbcfg.b.force_dev = 0; - - if ( mode == HOST_MODE) - { - usbcfg.b.force_host = 1; - } - else if ( mode == DEVICE_MODE) - { - usbcfg.b.force_dev = 1; - } - - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); - USB_OTG_BSP_mDelay(50); - return status; -} - - -/** -* @brief USB_OTG_GetMode : Get current mode -* @param pdev : Selected device -* @retval current mode -*/ -uint32_t USB_OTG_GetMode(USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS ) & 0x1); -} - - -/** -* @brief USB_OTG_IsDeviceMode : Check if it is device mode -* @param pdev : Selected device -* @retval num_in_ep -*/ -uint8_t USB_OTG_IsDeviceMode(USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_GetMode(pdev) != HOST_MODE); -} - - -/** -* @brief USB_OTG_IsHostMode : Check if it is host mode -* @param pdev : Selected device -* @retval num_in_ep -*/ -uint8_t USB_OTG_IsHostMode(USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_GetMode(pdev) == HOST_MODE); -} - - -/** -* @brief USB_OTG_ReadCoreItr : returns the Core Interrupt register -* @param pdev : Selected device -* @retval Status -*/ -uint32_t USB_OTG_ReadCoreItr(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t v = 0; - v = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS); - v &= USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTMSK); - return v; -} - - -/** -* @brief USB_OTG_ReadOtgItr : returns the USB_OTG Interrupt register -* @param pdev : Selected device -* @retval Status -*/ -uint32_t USB_OTG_ReadOtgItr (USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_READ_REG32 (&pdev->regs.GREGS->GOTGINT)); -} - -#ifdef USE_HOST_MODE -/** -* @brief USB_OTG_CoreInitHost : Initializes USB_OTG controller for host mode -* @param pdev : Selected device -* @retval status -*/ -USB_OTG_STS USB_OTG_CoreInitHost(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_FSIZ_TypeDef nptxfifosize; - USB_OTG_FSIZ_TypeDef ptxfifosize; - USB_OTG_HCFG_TypeDef hcfg; - -#ifdef USE_OTG_MODE - USB_OTG_OTGCTL_TypeDef gotgctl; -#endif - - uint32_t i = 0; - - nptxfifosize.d32 = 0; - ptxfifosize.d32 = 0; -#ifdef USE_OTG_MODE - gotgctl.d32 = 0; -#endif - hcfg.d32 = 0; - - - /* configure charge pump IO */ - USB_OTG_BSP_ConfigVBUS(pdev); - - /* Restart the Phy Clock */ - USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0); - - /* Initialize Host Configuration Register */ - USB_OTG_InitFSLSPClkSel(pdev , HCFG_48_MHZ); /* in init phase */ - - hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG); - hcfg.b.fslssupp = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32); - - /* Configure data FIFO sizes */ - /* Rx FIFO */ -#ifdef USB_OTG_FS_CORE - if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID) - { - /* set Rx FIFO size */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE); - nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE; - nptxfifosize.b.depth = TXH_NP_FS_FIFOSIZ; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32); - - ptxfifosize.b.startaddr = RX_FIFO_FS_SIZE + TXH_NP_FS_FIFOSIZ; - ptxfifosize.b.depth = TXH_P_FS_FIFOSIZ; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32); - } -#endif -#ifdef USB_OTG_HS_CORE - if (pdev->cfg.coreID == USB_OTG_HS_CORE_ID) - { - /* set Rx FIFO size */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE); - nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE; - nptxfifosize.b.depth = TXH_NP_HS_FIFOSIZ; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32); - - ptxfifosize.b.startaddr = RX_FIFO_HS_SIZE + TXH_NP_HS_FIFOSIZ; - ptxfifosize.b.depth = TXH_P_HS_FIFOSIZ; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32); - } -#endif - -#ifdef USE_OTG_MODE - /* Clear Host Set HNP Enable in the USB_OTG Control Register */ - gotgctl.b.hstsethnpen = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GOTGCTL, gotgctl.d32, 0); -#endif - - /* Make sure the FIFOs are flushed. */ - USB_OTG_FlushTxFifo(pdev, 0x10 ); /* all Tx FIFOs */ - USB_OTG_FlushRxFifo(pdev); - - - /* Clear all pending HC Interrupts */ - for (i = 0; i < pdev->cfg.host_channels; i++) - { - USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCINT, 0xFFFFFFFF ); - USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCGINTMSK, 0 ); - } -#ifndef USE_OTG_MODE - USB_OTG_DriveVbus(pdev, 1); -#endif - - USB_OTG_EnableHostInt(pdev); - return status; -} - -/** -* @brief USB_OTG_IsEvenFrame -* This function returns the frame number for sof packet -* @param pdev : Selected device -* @retval Frame number -*/ -uint8_t USB_OTG_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev) -{ - return !(USB_OTG_READ_REG32(&pdev->regs.HREGS->HFNUM) & 0x1); -} - -/** -* @brief USB_OTG_DriveVbus : set/reset vbus -* @param pdev : Selected device -* @param state : VBUS state -* @retval None -*/ -void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state) -{ - USB_OTG_HPRT0_TypeDef hprt0; - - hprt0.d32 = 0; - - /* enable disable the external charge pump */ - USB_OTG_BSP_DriveVBUS(pdev, state); - - /* Turn on the Host port power. */ - hprt0.d32 = USB_OTG_ReadHPRT0(pdev); - if ((hprt0.b.prtpwr == 0 ) && (state == 1 )) - { - hprt0.b.prtpwr = 1; - USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); - } - if ((hprt0.b.prtpwr == 1 ) && (state == 0 )) - { - hprt0.b.prtpwr = 0; - USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); - } - - USB_OTG_BSP_mDelay(200); -} -/** -* @brief USB_OTG_EnableHostInt: Enables the Host mode interrupts -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EnableHostInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GINTMSK_TypeDef intmsk; - intmsk.d32 = 0; - /* Disable all interrupts. */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTMSK, 0); - - /* Clear any pending interrupts. */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF); - - /* Enable the common interrupts */ - USB_OTG_EnableCommonInt(pdev); - - if (pdev->cfg.dma_enable == 0) - { - intmsk.b.rxstsqlvl = 1; - } - intmsk.b.portintr = 1; - intmsk.b.hcintr = 1; - intmsk.b.disconnect = 1; - intmsk.b.sofintr = 1; - intmsk.b.incomplisoout = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32); - return status; -} - -/** -* @brief USB_OTG_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the -* HCFG register on the PHY type -* @param pdev : Selected device -* @param freq : clock frequency -* @retval None -*/ -void USB_OTG_InitFSLSPClkSel(USB_OTG_CORE_HANDLE *pdev , uint8_t freq) -{ - USB_OTG_HCFG_TypeDef hcfg; - - hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG); - hcfg.b.fslspclksel = freq; - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32); -} - - -/** -* @brief USB_OTG_ReadHPRT0 : Reads HPRT0 to modify later -* @param pdev : Selected device -* @retval HPRT0 value -*/ -uint32_t USB_OTG_ReadHPRT0(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HPRT0_TypeDef hprt0; - - hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0); - hprt0.b.prtena = 0; - hprt0.b.prtconndet = 0; - hprt0.b.prtenchng = 0; - hprt0.b.prtovrcurrchng = 0; - return hprt0.d32; -} - - -/** -* @brief USB_OTG_ReadHostAllChannels_intr : Register PCD Callbacks -* @param pdev : Selected device -* @retval Status -*/ -uint32_t USB_OTG_ReadHostAllChannels_intr (USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_READ_REG32 (&pdev->regs.HREGS->HAINT)); -} - - -/** -* @brief USB_OTG_ResetPort : Reset Host Port -* @param pdev : Selected device -* @retval status -* @note : (1)The application must wait at least 10 ms (+ 10 ms security) -* before clearing the reset bit. -*/ -uint32_t USB_OTG_ResetPort(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HPRT0_TypeDef hprt0; - - hprt0.d32 = USB_OTG_ReadHPRT0(pdev); - hprt0.b.prtrst = 1; - USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); - USB_OTG_BSP_mDelay (10); /* See Note #1 */ - hprt0.b.prtrst = 0; - USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); - USB_OTG_BSP_mDelay (20); - return 1; -} - - -/** -* @brief USB_OTG_HC_Init : Prepares a host channel for transferring packets -* @param pdev : Selected device -* @param hc_num : channel number -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_HC_Init(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - USB_OTG_STS status = USB_OTG_OK; - uint32_t intr_enable = 0; - USB_OTG_HCGINTMSK_TypeDef hcintmsk; - USB_OTG_GINTMSK_TypeDef gintmsk; - USB_OTG_HCCHAR_TypeDef hcchar; - USB_OTG_HCINTn_TypeDef hcint; - - - gintmsk.d32 = 0; - hcintmsk.d32 = 0; - hcchar.d32 = 0; - - /* Clear old interrupt conditions for this host channel. */ - hcint.d32 = 0xFFFFFFFF; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINT, hcint.d32); - - /* Enable channel interrupts required for this transfer. */ - hcintmsk.d32 = 0; - - if (pdev->cfg.dma_enable == 1) - { - hcintmsk.b.ahberr = 1; - } - - switch (pdev->host.hc[hc_num].ep_type) - { - case EP_TYPE_CTRL: - case EP_TYPE_BULK: - hcintmsk.b.xfercompl = 1; - hcintmsk.b.stall = 1; - hcintmsk.b.xacterr = 1; - hcintmsk.b.datatglerr = 1; - hcintmsk.b.nak = 1; - if (pdev->host.hc[hc_num].ep_is_in) - { - hcintmsk.b.bblerr = 1; - } - else - { - hcintmsk.b.nyet = 1; - if (pdev->host.hc[hc_num].do_ping) - { - hcintmsk.b.ack = 1; - } - } - break; - case EP_TYPE_INTR: - hcintmsk.b.xfercompl = 1; - hcintmsk.b.nak = 1; - hcintmsk.b.stall = 1; - hcintmsk.b.xacterr = 1; - hcintmsk.b.datatglerr = 1; - hcintmsk.b.frmovrun = 1; - - if (pdev->host.hc[hc_num].ep_is_in) - { - hcintmsk.b.bblerr = 1; - } - - break; - case EP_TYPE_ISOC: - hcintmsk.b.xfercompl = 1; - hcintmsk.b.frmovrun = 1; - hcintmsk.b.ack = 1; - - if (pdev->host.hc[hc_num].ep_is_in) - { - hcintmsk.b.xacterr = 1; - hcintmsk.b.bblerr = 1; - } - break; - } - - - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, hcintmsk.d32); - - - /* Enable the top level host channel interrupt. */ - intr_enable = (1 << hc_num); - USB_OTG_MODIFY_REG32(&pdev->regs.HREGS->HAINTMSK, 0, intr_enable); - - /* Make sure host channel interrupts are enabled. */ - gintmsk.b.hcintr = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, 0, gintmsk.d32); - - /* Program the HCCHAR register */ - hcchar.d32 = 0; - hcchar.b.devaddr = pdev->host.hc[hc_num].dev_addr; - hcchar.b.epnum = pdev->host.hc[hc_num].ep_num; - hcchar.b.epdir = pdev->host.hc[hc_num].ep_is_in; - hcchar.b.lspddev = (pdev->host.hc[hc_num].speed == HPRT0_PRTSPD_LOW_SPEED); - hcchar.b.eptype = pdev->host.hc[hc_num].ep_type; - hcchar.b.mps = pdev->host.hc[hc_num].max_packet; - if (pdev->host.hc[hc_num].ep_type == HCCHAR_INTR) - { - hcchar.b.oddfrm = 1; - } - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); - return status; -} - - -/** -* @brief USB_OTG_HC_StartXfer : Start transfer -* @param pdev : Selected device -* @param hc_num : channel number -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_HC_StartXfer(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_HCCHAR_TypeDef hcchar; - USB_OTG_HCTSIZn_TypeDef hctsiz; - USB_OTG_HNPTXSTS_TypeDef hnptxsts; - USB_OTG_HPTXSTS_TypeDef hptxsts; - USB_OTG_GINTMSK_TypeDef intmsk; - uint16_t len_words = 0; - - uint16_t num_packets; - uint16_t max_hc_pkt_count; - - max_hc_pkt_count = 256; - hctsiz.d32 = 0; - hcchar.d32 = 0; - intmsk.d32 = 0; - - /* Compute the expected number of packets associated to the transfer */ - if (pdev->host.hc[hc_num].xfer_len > 0) - { - num_packets = (pdev->host.hc[hc_num].xfer_len + \ - pdev->host.hc[hc_num].max_packet - 1) / pdev->host.hc[hc_num].max_packet; - - if (num_packets > max_hc_pkt_count) - { - num_packets = max_hc_pkt_count; - pdev->host.hc[hc_num].xfer_len = num_packets * \ - pdev->host.hc[hc_num].max_packet; - } - } - else - { - num_packets = 1; - } - if (pdev->host.hc[hc_num].ep_is_in) - { - pdev->host.hc[hc_num].xfer_len = num_packets * \ - pdev->host.hc[hc_num].max_packet; - } - /* Initialize the HCTSIZn register */ - hctsiz.b.xfersize = pdev->host.hc[hc_num].xfer_len; - hctsiz.b.pktcnt = num_packets; - hctsiz.b.pid = pdev->host.hc[hc_num].data_pid; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCDMA, (unsigned int)pdev->host.hc[hc_num].xfer_buff); - } - - - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR); - hcchar.b.oddfrm = USB_OTG_IsEvenFrame(pdev); - - /* Set host channel enable */ - hcchar.b.chen = 1; - hcchar.b.chdis = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); - - if (pdev->cfg.dma_enable == 0) /* Slave mode */ - { - if((pdev->host.hc[hc_num].ep_is_in == 0) && - (pdev->host.hc[hc_num].xfer_len > 0)) - { - switch(pdev->host.hc[hc_num].ep_type) - { - /* Non periodic transfer */ - case EP_TYPE_CTRL: - case EP_TYPE_BULK: - - hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS); - len_words = (pdev->host.hc[hc_num].xfer_len + 3) / 4; - - /* check if there is enough space in FIFO space */ - if(len_words > hnptxsts.b.nptxfspcavail) - { - /* need to process data in nptxfempty interrupt */ - intmsk.b.nptxfempty = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32); - } - - break; - /* Periodic transfer */ - case EP_TYPE_INTR: - case EP_TYPE_ISOC: - hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS); - len_words = (pdev->host.hc[hc_num].xfer_len + 3) / 4; - /* check if there is enough space in FIFO space */ - if(len_words > hptxsts.b.ptxfspcavail) /* split the transfer */ - { - /* need to process data in ptxfempty interrupt */ - intmsk.b.ptxfempty = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32); - } - break; - - default: - break; - } - - /* Write packet into the Tx FIFO. */ - USB_OTG_WritePacket(pdev, - pdev->host.hc[hc_num].xfer_buff , - hc_num, pdev->host.hc[hc_num].xfer_len); - } - } - return status; -} - - -/** -* @brief USB_OTG_HC_Halt : Halt channel -* @param pdev : Selected device -* @param hc_num : channel number -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_HC_Halt(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_HNPTXSTS_TypeDef nptxsts; - USB_OTG_HPTXSTS_TypeDef hptxsts; - USB_OTG_HCCHAR_TypeDef hcchar; - - nptxsts.d32 = 0; - hptxsts.d32 = 0; - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR); - hcchar.b.chen = 1; - hcchar.b.chdis = 1; - - /* Check for space in the request queue to issue the halt. */ - if (hcchar.b.eptype == HCCHAR_CTRL || hcchar.b.eptype == HCCHAR_BULK) - { - nptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS); - if (nptxsts.b.nptxqspcavail == 0) - { - hcchar.b.chen = 0; - } - } - else - { - hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS); - if (hptxsts.b.ptxqspcavail == 0) - { - hcchar.b.chen = 0; - } - } - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); - return status; -} - -/** -* @brief Issue a ping token -* @param None -* @retval : None -*/ -USB_OTG_STS USB_OTG_HC_DoPing(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_HCCHAR_TypeDef hcchar; - USB_OTG_HCTSIZn_TypeDef hctsiz; - - hctsiz.d32 = 0; - hctsiz.b.dopng = 1; - hctsiz.b.pktcnt = 1; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32); - - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR); - hcchar.b.chen = 1; - hcchar.b.chdis = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32); - return status; -} - -/** -* @brief Stop the device and clean up fifo's -* @param None -* @retval : None -*/ -void USB_OTG_StopHost(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HCCHAR_TypeDef hcchar; - uint32_t i; - - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HAINTMSK , 0); - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HAINT, 0xFFFFFFFF); - /* Flush out any leftover queued requests. */ - - for (i = 0; i < pdev->cfg.host_channels; i++) - { - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[i]->HCCHAR); - hcchar.b.chen = 0; - hcchar.b.chdis = 1; - hcchar.b.epdir = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[i]->HCCHAR, hcchar.d32); - } - - /* Flush the FIFO */ - USB_OTG_FlushRxFifo(pdev); - USB_OTG_FlushTxFifo(pdev , 0x10 ); -} -#endif -#ifdef USE_DEVICE_MODE -/* PCD Core Layer */ - -/** -* @brief USB_OTG_InitDevSpeed :Initializes the DevSpd field of DCFG register -* depending the PHY type and the enumeration speed of the device. -* @param pdev : Selected device -* @retval : None -*/ -void USB_OTG_InitDevSpeed(USB_OTG_CORE_HANDLE *pdev , uint8_t speed) -{ - USB_OTG_DCFG_TypeDef dcfg; - - dcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCFG); - dcfg.b.devspd = speed; - USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCFG, dcfg.d32); -} - - -/** -* @brief USB_OTG_CoreInitDev : Initializes the USB_OTG controller registers -* for device mode -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - uint32_t i; - USB_OTG_DCFG_TypeDef dcfg; - USB_OTG_FSIZ_TypeDef nptxfifosize; - USB_OTG_FSIZ_TypeDef txfifosize; - USB_OTG_DIEPMSK_TypeDef msk; - USB_OTG_DTHRCTL_TypeDef dthrctl; - - depctl.d32 = 0; - dcfg.d32 = 0; - nptxfifosize.d32 = 0; - txfifosize.d32 = 0; - msk.d32 = 0; - - /* Restart the Phy Clock */ - USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0); - /* Device configuration register */ - dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG); - dcfg.b.perfrint = DCFG_FRAME_INTERVAL_80; - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32 ); - -#ifdef USB_OTG_FS_CORE - if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID ) - { - - /* Set Full speed phy */ - USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_FULL); - - /* set Rx FIFO size */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE); - - /* EP0 TX*/ - nptxfifosize.b.depth = TX0_FIFO_FS_SIZE; - nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 ); - - - /* EP1 TX*/ - txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth; - txfifosize.b.depth = TX1_FIFO_FS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 ); - - - /* EP2 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX2_FIFO_FS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 ); - - - /* EP3 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX3_FIFO_FS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 ); - } -#endif -#ifdef USB_OTG_HS_CORE - if(pdev->cfg.coreID == USB_OTG_HS_CORE_ID ) - { - - /* Set High speed phy */ - - if(pdev->cfg.phy_itface == USB_OTG_ULPI_PHY) - { - USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH); - } - else /* set High speed phy in Full speed mode */ - { - USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH_IN_FULL); - } - - /* set Rx FIFO size */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE); - - /* EP0 TX*/ - nptxfifosize.b.depth = TX0_FIFO_HS_SIZE; - nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 ); - - - /* EP1 TX*/ - txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth; - txfifosize.b.depth = TX1_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 ); - - - /* EP2 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX2_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 ); - - - /* EP3 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX3_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 ); - - /* EP4 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX4_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[3], txfifosize.d32 ); - - - /* EP5 TX*/ - txfifosize.b.startaddr += txfifosize.b.depth; - txfifosize.b.depth = TX5_FIFO_HS_SIZE; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[4], txfifosize.d32 ); - } -#endif - /* Flush the FIFOs */ - USB_OTG_FlushTxFifo(pdev , 0x10); /* all Tx FIFOs */ - USB_OTG_FlushRxFifo(pdev); - /* Clear all pending Device Interrupts */ - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 ); - - for (i = 0; i < pdev->cfg.dev_endpoints; i++) - { - depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[i]->DIEPCTL); - if (depctl.b.epena) - { - depctl.d32 = 0; - depctl.b.epdis = 1; - depctl.b.snak = 1; - } - else - { - depctl.d32 = 0; - } - USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPCTL, depctl.d32); - USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPTSIZ, 0); - USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF); - } - for (i = 0; i < pdev->cfg.dev_endpoints; i++) - { - USB_OTG_DEPCTL_TypeDef depctl; - depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[i]->DOEPCTL); - if (depctl.b.epena) - { - depctl.d32 = 0; - depctl.b.epdis = 1; - depctl.b.snak = 1; - } - else - { - depctl.d32 = 0; - } - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPCTL, depctl.d32); - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPTSIZ, 0); - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF); - } - msk.d32 = 0; - msk.b.txfifoundrn = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPMSK, msk.d32, msk.d32); - - if (pdev->cfg.dma_enable == 1) - { - dthrctl.d32 = 0; - dthrctl.b.non_iso_thr_en = 1; - dthrctl.b.iso_thr_en = 1; - dthrctl.b.tx_thr_len = 64; - dthrctl.b.rx_thr_en = 1; - dthrctl.b.rx_thr_len = 64; - USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DTHRCTL, dthrctl.d32); - } - USB_OTG_EnableDevInt(pdev); - return status; -} - - -/** -* @brief USB_OTG_EnableDevInt : Enables the Device mode interrupts -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EnableDevInt(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_GINTMSK_TypeDef intmsk; - - intmsk.d32 = 0; - - /* Disable all interrupts. */ - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, 0); - /* Clear any pending interrupts */ - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF); - /* Enable the common interrupts */ - USB_OTG_EnableCommonInt(pdev); - - if (pdev->cfg.dma_enable == 0) - { - intmsk.b.rxstsqlvl = 1; - } - - /* Enable interrupts matching to the Device mode ONLY */ - intmsk.b.usbsuspend = 1; - intmsk.b.usbreset = 1; - intmsk.b.enumdone = 1; - intmsk.b.inepintr = 1; - intmsk.b.outepintr = 1; - intmsk.b.sofintr = 1; - - intmsk.b.incomplisoin = 1; - intmsk.b.incomplisoout = 1; -#ifdef VBUS_SENSING_ENABLED - intmsk.b.sessreqintr = 1; - intmsk.b.otgintr = 1; -#endif - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32); - return status; -} - - -/** -* @brief USB_OTG_GetDeviceSpeed -* Get the device speed from the device status register -* @param None -* @retval status -*/ -enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_DSTS_TypeDef dsts; - enum USB_OTG_SPEED speed = USB_SPEED_UNKNOWN; - - - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - - switch (dsts.b.enumspd) - { - case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ: - speed = USB_SPEED_HIGH; - break; - case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ: - case DSTS_ENUMSPD_FS_PHY_48MHZ: - speed = USB_SPEED_FULL; - break; - - case DSTS_ENUMSPD_LS_PHY_6MHZ: - speed = USB_SPEED_LOW; - break; - } - - return speed; -} -/** -* @brief enables EP0 OUT to receive SETUP packets and configures EP0 -* for transmitting packets -* @param None -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EP0Activate(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DSTS_TypeDef dsts; - USB_OTG_DEPCTL_TypeDef diepctl; - USB_OTG_DCTL_TypeDef dctl; - - dctl.d32 = 0; - /* Read the Device Status and Endpoint 0 Control registers */ - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - diepctl.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL); - /* Set the MPS of the IN EP based on the enumeration speed */ - switch (dsts.b.enumspd) - { - case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ: - case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ: - case DSTS_ENUMSPD_FS_PHY_48MHZ: - diepctl.b.mps = DEP0CTL_MPS_64; - break; - case DSTS_ENUMSPD_LS_PHY_6MHZ: - diepctl.b.mps = DEP0CTL_MPS_8; - break; - } - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL, diepctl.d32); - dctl.b.cgnpinnak = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, dctl.d32); - return status; -} - - -/** -* @brief USB_OTG_EPActivate : Activates an EP -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPActivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - USB_OTG_DAINT_TypeDef daintmsk; - __IO uint32_t *addr; - - - depctl.d32 = 0; - daintmsk.d32 = 0; - /* Read DEPCTLn register */ - if (ep->is_in == 1) - { - addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL; - daintmsk.ep.in = 1 << ep->num; - } - else - { - addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL; - daintmsk.ep.out = 1 << ep->num; - } - /* If the EP is already active don't change the EP Control - * register. */ - depctl.d32 = USB_OTG_READ_REG32(addr); - if (!depctl.b.usbactep) - { - depctl.b.mps = ep->maxpacket; - depctl.b.eptype = ep->type; - depctl.b.txfnum = ep->tx_fifo_num; - depctl.b.setd0pid = 1; - depctl.b.usbactep = 1; - USB_OTG_WRITE_REG32(addr, depctl.d32); - } - /* Enable the Interrupt for this EP */ -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED - if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID)) - { - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, 0, daintmsk.d32); - } - else -#endif - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, 0, daintmsk.d32); - return status; -} - - -/** -* @brief USB_OTG_EPDeactivate : Deactivates an EP -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - USB_OTG_DAINT_TypeDef daintmsk; - __IO uint32_t *addr; - - depctl.d32 = 0; - daintmsk.d32 = 0; - /* Read DEPCTLn register */ - if (ep->is_in == 1) - { - addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL; - daintmsk.ep.in = 1 << ep->num; - } - else - { - addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL; - daintmsk.ep.out = 1 << ep->num; - } - depctl.b.usbactep = 0; - USB_OTG_WRITE_REG32(addr, depctl.d32); - /* Disable the Interrupt for this EP */ - -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED - if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID)) - { - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, daintmsk.d32, 0); - } - else -#endif - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, daintmsk.d32, 0); - return status; -} - - -/** -* @brief USB_OTG_EPStartXfer : Handle the setup for data xfer for an EP and -* starts the xfer -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPStartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - USB_OTG_DEPXFRSIZ_TypeDef deptsiz; - USB_OTG_DSTS_TypeDef dsts; - uint32_t fifoemptymsk = 0; - - depctl.d32 = 0; - deptsiz.d32 = 0; - /* IN endpoint */ - if (ep->is_in == 1) - { - depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPCTL)); - deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ)); - /* Zero Length Packet? */ - if (ep->xfer_len == 0) - { - deptsiz.b.xfersize = 0; - deptsiz.b.pktcnt = 1; - } - else - { - /* Program the transfer size and packet count - * as follows: xfersize = N * maxpacket + - * short_packet pktcnt = N + (short_packet - * exist ? 1 : 0) - */ - deptsiz.b.xfersize = ep->xfer_len; - deptsiz.b.pktcnt = (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket; - - if (ep->type == EP_TYPE_ISOC) - { - deptsiz.b.mc = 1; - } - } - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ, deptsiz.d32); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr); - } - else - { - if (ep->type != EP_TYPE_ISOC) - { - /* Enable the Tx FIFO Empty Interrupt for this EP */ - if (ep->xfer_len > 0) - { - fifoemptymsk = 1 << ep->num; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk); - } - } - } - - - if (ep->type == EP_TYPE_ISOC) - { - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - - if (((dsts.b.soffn)&0x1) == 0) - { - depctl.b.setd1pid = 1; - } - else - { - depctl.b.setd0pid = 1; - } - } - - /* EP enable, IN data in FIFO */ - depctl.b.cnak = 1; - depctl.b.epena = 1; - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPCTL, depctl.d32); - - if (ep->type == EP_TYPE_ISOC) - { - USB_OTG_WritePacket(pdev, ep->xfer_buff, ep->num, ep->xfer_len); - } - } - else - { - /* OUT endpoint */ - depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL)); - deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ)); - /* Program the transfer size and packet count as follows: - * pktcnt = N - * xfersize = N * maxpacket - */ - if (ep->xfer_len == 0) - { - deptsiz.b.xfersize = ep->maxpacket; - deptsiz.b.pktcnt = 1; - } - else - { - deptsiz.b.pktcnt = (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket; - deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket; - } - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr); - } - - if (ep->type == EP_TYPE_ISOC) - { - if (ep->even_odd_frame) - { - depctl.b.setd1pid = 1; - } - else - { - depctl.b.setd0pid = 1; - } - } - /* EP enable */ - depctl.b.cnak = 1; - depctl.b.epena = 1; - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL, depctl.d32); - } - return status; -} - - -/** -* @brief USB_OTG_EP0StartXfer : Handle the setup for a data xfer for EP0 and -* starts the xfer -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - USB_OTG_DEP0XFRSIZ_TypeDef deptsiz; - USB_OTG_INEPREGS *in_regs; - uint32_t fifoemptymsk = 0; - - depctl.d32 = 0; - deptsiz.d32 = 0; - /* IN endpoint */ - if (ep->is_in == 1) - { - in_regs = pdev->regs.INEP_REGS[0]; - depctl.d32 = USB_OTG_READ_REG32(&in_regs->DIEPCTL); - deptsiz.d32 = USB_OTG_READ_REG32(&in_regs->DIEPTSIZ); - /* Zero Length Packet? */ - if (ep->xfer_len == 0) - { - deptsiz.b.xfersize = 0; - deptsiz.b.pktcnt = 1; - - } - else - { - if (ep->xfer_len > ep->maxpacket) - { - ep->xfer_len = ep->maxpacket; - deptsiz.b.xfersize = ep->maxpacket; - } - else - { - deptsiz.b.xfersize = ep->xfer_len; - } - deptsiz.b.pktcnt = 1; - } - USB_OTG_WRITE_REG32(&in_regs->DIEPTSIZ, deptsiz.d32); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr); - } - - /* EP enable, IN data in FIFO */ - depctl.b.cnak = 1; - depctl.b.epena = 1; - USB_OTG_WRITE_REG32(&in_regs->DIEPCTL, depctl.d32); - - - - if (pdev->cfg.dma_enable == 0) - { - /* Enable the Tx FIFO Empty Interrupt for this EP */ - if (ep->xfer_len > 0) - { - { - fifoemptymsk |= 1 << ep->num; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk); - } - } - } - } - else - { - /* OUT endpoint */ - depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - deptsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ); - /* Program the transfer size and packet count as follows: - * xfersize = N * (maxpacket + 4 - (maxpacket % 4)) - * pktcnt = N */ - if (ep->xfer_len == 0) - { - deptsiz.b.xfersize = ep->maxpacket; - deptsiz.b.pktcnt = 1; - } - else - { - ep->xfer_len = ep->maxpacket; - deptsiz.b.xfersize = ep->maxpacket; - deptsiz.b.pktcnt = 1; - } - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32); - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr); - } - /* EP enable */ - depctl.b.cnak = 1; - depctl.b.epena = 1; - USB_OTG_WRITE_REG32 (&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL), depctl.d32); - - } - return status; -} - - -/** -* @brief USB_OTG_EPSetStall : Set the EP STALL -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPSetStall(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - __IO uint32_t *depctl_addr; - - depctl.d32 = 0; - if (ep->is_in == 1) - { - depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - /* set the disable and stall bits */ - if (depctl.b.epena) - { - depctl.b.epdis = 1; - } - depctl.b.stall = 1; - USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); - } - else - { - depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - /* set the stall bit */ - depctl.b.stall = 1; - USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); - } - return status; -} - - -/** -* @brief Clear the EP STALL -* @param pdev : Selected device -* @retval USB_OTG_STS : status -*/ -USB_OTG_STS USB_OTG_EPClearStall(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep) -{ - USB_OTG_STS status = USB_OTG_OK; - USB_OTG_DEPCTL_TypeDef depctl; - __IO uint32_t *depctl_addr; - - depctl.d32 = 0; - - if (ep->is_in == 1) - { - depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); - } - else - { - depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - } - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - /* clear the stall bits */ - depctl.b.stall = 0; - if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK) - { - depctl.b.setd0pid = 1; /* DATA0 */ - } - USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); - return status; -} - - -/** -* @brief USB_OTG_ReadDevAllOutEp_itr : returns OUT endpoint interrupt bits -* @param pdev : Selected device -* @retval OUT endpoint interrupt bits -*/ -uint32_t USB_OTG_ReadDevAllOutEp_itr(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t v; - v = USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINT); - v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINTMSK); - return ((v & 0xffff0000) >> 16); -} - - -/** -* @brief USB_OTG_ReadDevOutEP_itr : returns Device OUT EP Interrupt register -* @param pdev : Selected device -* @param ep : end point number -* @retval Device OUT EP Interrupt register -*/ -uint32_t USB_OTG_ReadDevOutEP_itr(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) -{ - uint32_t v; - v = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT); - v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOEPMSK); - return v; -} - - -/** -* @brief USB_OTG_ReadDevAllInEPItr : Get int status register -* @param pdev : Selected device -* @retval int status register -*/ -uint32_t USB_OTG_ReadDevAllInEPItr(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t v; - v = USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINT); - v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINTMSK); - return (v & 0xffff); -} - -/** -* @brief configures EPO to receive SETUP packets -* @param None -* @retval : None -*/ -void USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_DEP0XFRSIZ_TypeDef doeptsize0; - doeptsize0.d32 = 0; - doeptsize0.b.supcnt = 3; - doeptsize0.b.pktcnt = 1; - doeptsize0.b.xfersize = 8 * 3; - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPTSIZ, doeptsize0.d32 ); - - if (pdev->cfg.dma_enable == 1) - { - USB_OTG_DEPCTL_TypeDef doepctl; - doepctl.d32 = 0; - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPDMA, - (uint32_t)&pdev->dev.setup_packet); - - /* EP enable */ - doepctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[0]->DOEPCTL); - doepctl.b.epena = 1; - doepctl.d32 = 0x80008000; - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPCTL, doepctl.d32); - } -} - -/** -* @brief USB_OTG_RemoteWakeup : active remote wakeup signalling -* @param None -* @retval : None -*/ -void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev) -{ - - USB_OTG_DCTL_TypeDef dctl; - USB_OTG_DSTS_TypeDef dsts; - USB_OTG_PCGCCTL_TypeDef power; - - if (pdev->dev.DevRemoteWakeup) - { - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - if(dsts.b.suspsts == 1) - { - if(pdev->cfg.low_power) - { - /* un-gate USB Core clock */ - power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL); - power.b.gatehclk = 0; - power.b.stoppclk = 0; - USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); - } - /* active Remote wakeup signaling */ - dctl.d32 = 0; - dctl.b.rmtwkupsig = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, 0, dctl.d32); - USB_OTG_BSP_mDelay(5); - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 ); - } - } -} - - -/** -* @brief USB_OTG_UngateClock : active USB Core clock -* @param None -* @retval : None -*/ -void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev) -{ - if(pdev->cfg.low_power) - { - - USB_OTG_DSTS_TypeDef dsts; - USB_OTG_PCGCCTL_TypeDef power; - - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - - if(dsts.b.suspsts == 1) - { - /* un-gate USB Core clock */ - power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL); - power.b.gatehclk = 0; - power.b.stoppclk = 0; - USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); - - } - } -} - -/** -* @brief Stop the device and clean up fifo's -* @param None -* @retval : None -*/ -void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t i; - - pdev->dev.device_status = 1; - - for (i = 0; i < pdev->cfg.dev_endpoints ; i++) - { - USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF); - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF); - } - - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 ); - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF ); - - /* Flush the FIFO */ - USB_OTG_FlushRxFifo(pdev); - USB_OTG_FlushTxFifo(pdev , 0x10 ); -} - -/** -* @brief returns the EP Status -* @param pdev : Selected device -* ep : endpoint structure -* @retval : EP status -*/ - -uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep) -{ - USB_OTG_DEPCTL_TypeDef depctl; - __IO uint32_t *depctl_addr; - uint32_t Status = 0; - - depctl.d32 = 0; - if (ep->is_in == 1) - { - depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - - if (depctl.b.stall == 1) - Status = USB_OTG_EP_TX_STALL; - else if (depctl.b.naksts == 1) - Status = USB_OTG_EP_TX_NAK; - else - Status = USB_OTG_EP_TX_VALID; - - } - else - { - depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - if (depctl.b.stall == 1) - Status = USB_OTG_EP_RX_STALL; - else if (depctl.b.naksts == 1) - Status = USB_OTG_EP_RX_NAK; - else - Status = USB_OTG_EP_RX_VALID; - } - - /* Return the current status */ - return Status; -} - -/** -* @brief Set the EP Status -* @param pdev : Selected device -* Status : new Status -* ep : EP structure -* @retval : None -*/ -void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status) -{ - USB_OTG_DEPCTL_TypeDef depctl; - __IO uint32_t *depctl_addr; - - depctl.d32 = 0; - - /* Process for IN endpoint */ - if (ep->is_in == 1) - { - depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - - if (Status == USB_OTG_EP_TX_STALL) - { - USB_OTG_EPSetStall(pdev, ep); return; - } - else if (Status == USB_OTG_EP_TX_NAK) - depctl.b.snak = 1; - else if (Status == USB_OTG_EP_TX_VALID) - { - if (depctl.b.stall == 1) - { - ep->even_odd_frame = 0; - USB_OTG_EPClearStall(pdev, ep); - return; - } - depctl.b.cnak = 1; - depctl.b.usbactep = 1; - depctl.b.epena = 1; - } - else if (Status == USB_OTG_EP_TX_DIS) - depctl.b.usbactep = 0; - } - else /* Process for OUT endpoint */ - { - depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL); - depctl.d32 = USB_OTG_READ_REG32(depctl_addr); - - if (Status == USB_OTG_EP_RX_STALL) { - depctl.b.stall = 1; - } - else if (Status == USB_OTG_EP_RX_NAK) - depctl.b.snak = 1; - else if (Status == USB_OTG_EP_RX_VALID) - { - if (depctl.b.stall == 1) - { - ep->even_odd_frame = 0; - USB_OTG_EPClearStall(pdev, ep); - return; - } - depctl.b.cnak = 1; - depctl.b.usbactep = 1; - depctl.b.epena = 1; - } - else if (Status == USB_OTG_EP_RX_DIS) - { - depctl.b.usbactep = 0; - } - } - - USB_OTG_WRITE_REG32(depctl_addr, depctl.d32); -} - -#endif -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_dcd.c b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_dcd.c deleted file mode 100644 index c3336cb84..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_dcd.c +++ /dev/null @@ -1,472 +0,0 @@ -/** - ****************************************************************************** - * @file usb_dcd.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Peripheral Device Interface Layer - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_dcd.h" -#include "usb_bsp.h" - - -/** @addtogroup USB_OTG_DRIVER -* @{ -*/ - -/** @defgroup USB_DCD -* @brief This file is the interface between EFSL ans Host mass-storage class -* @{ -*/ - - -/** @defgroup USB_DCD_Private_Defines -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_DCD_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - - -/** @defgroup USB_DCD_Private_Macros -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_DCD_Private_Variables -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_DCD_Private_FunctionPrototypes -* @{ -*/ - -/** -* @} -*/ - - -/** @defgroup USB_DCD_Private_Functions -* @{ -*/ - - - -void DCD_Init(USB_OTG_CORE_HANDLE *pdev , - USB_OTG_CORE_ID_TypeDef coreID) -{ - uint32_t i; - USB_OTG_EP *ep; - - USB_OTG_SelectCore (pdev , coreID); - - pdev->dev.device_status = USB_OTG_DEFAULT; - pdev->dev.device_address = 0; - - /* Init ep structure */ - for (i = 0; i < pdev->cfg.dev_endpoints ; i++) - { - ep = &pdev->dev.in_ep[i]; - /* Init ep structure */ - ep->is_in = 1; - ep->num = i; - ep->tx_fifo_num = i; - /* Control until ep is actvated */ - ep->type = EP_TYPE_CTRL; - ep->maxpacket = USB_OTG_MAX_EP0_SIZE; - ep->xfer_buff = 0; - ep->xfer_len = 0; - } - - for (i = 0; i < pdev->cfg.dev_endpoints; i++) - { - ep = &pdev->dev.out_ep[i]; - /* Init ep structure */ - ep->is_in = 0; - ep->num = i; - ep->tx_fifo_num = i; - /* Control until ep is activated */ - ep->type = EP_TYPE_CTRL; - ep->maxpacket = USB_OTG_MAX_EP0_SIZE; - ep->xfer_buff = 0; - ep->xfer_len = 0; - } - - USB_OTG_DisableGlobalInt(pdev); - - /*Init the Core (common init.) */ - USB_OTG_CoreInit(pdev); - - - /* Force Device Mode*/ - USB_OTG_SetCurrentMode(pdev, DEVICE_MODE); - - /* Init Device */ - USB_OTG_CoreInitDev(pdev); - - - /* Enable USB Global interrupt */ - USB_OTG_EnableGlobalInt(pdev); -} - - -/** -* @brief Configure an EP -* @param pdev : Device instance -* @param epdesc : Endpoint Descriptor -* @retval : status -*/ -uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev , - uint8_t ep_addr, - uint16_t ep_mps, - uint8_t ep_type) -{ - USB_OTG_EP *ep; - - if ((ep_addr & 0x80) == 0x80) - { - ep = &pdev->dev.in_ep[ep_addr & 0x7F]; - } - else - { - ep = &pdev->dev.out_ep[ep_addr & 0x7F]; - } - ep->num = ep_addr & 0x7F; - - ep->is_in = (0x80 & ep_addr) != 0; - ep->maxpacket = ep_mps; - ep->type = ep_type; - if (ep->is_in) - { - /* Assign a Tx FIFO */ - ep->tx_fifo_num = ep->num; - } - /* Set initial data PID. */ - if (ep_type == USB_OTG_EP_BULK ) - { - ep->data_pid_start = 0; - } - USB_OTG_EPActivate(pdev , ep ); - return 0; -} -/** -* @brief called when an EP is disabled -* @param pdev: device instance -* @param ep_addr: endpoint address -* @retval : status -*/ -uint32_t DCD_EP_Close(USB_OTG_CORE_HANDLE *pdev , uint8_t ep_addr) -{ - USB_OTG_EP *ep; - - if ((ep_addr&0x80) == 0x80) - { - ep = &pdev->dev.in_ep[ep_addr & 0x7F]; - } - else - { - ep = &pdev->dev.out_ep[ep_addr & 0x7F]; - } - ep->num = ep_addr & 0x7F; - ep->is_in = (0x80 & ep_addr) != 0; - USB_OTG_EPDeactivate(pdev , ep ); - return 0; -} - - -/** -* @brief DCD_EP_PrepareRx -* @param pdev: device instance -* @param ep_addr: endpoint address -* @param pbuf: pointer to Rx buffer -* @param buf_len: data length -* @retval : status -*/ -uint32_t DCD_EP_PrepareRx( USB_OTG_CORE_HANDLE *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint16_t buf_len) -{ - USB_OTG_EP *ep; - - ep = &pdev->dev.out_ep[ep_addr & 0x7F]; - - /*setup and start the Xfer */ - ep->xfer_buff = pbuf; - ep->xfer_len = buf_len; - ep->xfer_count = 0; - ep->is_in = 0; - ep->num = ep_addr & 0x7F; - - if (pdev->cfg.dma_enable == 1) - { - ep->dma_addr = (uint32_t)pbuf; - } - - if ( ep->num == 0 ) - { - USB_OTG_EP0StartXfer(pdev , ep); - } - else - { - USB_OTG_EPStartXfer(pdev, ep ); - } - return 0; -} - -/** -* @brief Transmit data over USB -* @param pdev: device instance -* @param ep_addr: endpoint address -* @param pbuf: pointer to Tx buffer -* @param buf_len: data length -* @retval : status -*/ -uint32_t DCD_EP_Tx ( USB_OTG_CORE_HANDLE *pdev, - uint8_t ep_addr, - uint8_t *pbuf, - uint32_t buf_len) -{ - USB_OTG_EP *ep; - - ep = &pdev->dev.in_ep[ep_addr & 0x7F]; - - /* Setup and start the Transfer */ - ep->is_in = 1; - ep->num = ep_addr & 0x7F; - ep->xfer_buff = pbuf; - ep->dma_addr = (uint32_t)pbuf; - ep->xfer_count = 0; - ep->xfer_len = buf_len; - - if ( ep->num == 0 ) - { - USB_OTG_EP0StartXfer(pdev , ep); - } - else - { - USB_OTG_EPStartXfer(pdev, ep ); - } - return 0; -} - - -/** -* @brief Stall an endpoint. -* @param pdev: device instance -* @param epnum: endpoint address -* @retval : status -*/ -uint32_t DCD_EP_Stall (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum) -{ - USB_OTG_EP *ep; - if ((0x80 & epnum) == 0x80) - { - ep = &pdev->dev.in_ep[epnum & 0x7F]; - } - else - { - ep = &pdev->dev.out_ep[epnum]; - } - - ep->is_stall = 1; - ep->num = epnum & 0x7F; - ep->is_in = ((epnum & 0x80) == 0x80); - - USB_OTG_EPSetStall(pdev , ep); - return (0); -} - - -/** -* @brief Clear stall condition on endpoints. -* @param pdev: device instance -* @param epnum: endpoint address -* @retval : status -*/ -uint32_t DCD_EP_ClrStall (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum) -{ - USB_OTG_EP *ep; - if ((0x80 & epnum) == 0x80) - { - ep = &pdev->dev.in_ep[epnum & 0x7F]; - } - else - { - ep = &pdev->dev.out_ep[epnum]; - } - - ep->is_stall = 0; - ep->num = epnum & 0x7F; - ep->is_in = ((epnum & 0x80) == 0x80); - - USB_OTG_EPClearStall(pdev , ep); - return (0); -} - - -/** -* @brief This Function flushes the FIFOs. -* @param pdev: device instance -* @param epnum: endpoint address -* @retval : status -*/ -uint32_t DCD_EP_Flush (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum) -{ - - if ((epnum & 0x80) == 0x80) - { - USB_OTG_FlushTxFifo(pdev, epnum & 0x7F); - } - else - { - USB_OTG_FlushRxFifo(pdev); - } - - return (0); -} - - -/** -* @brief This Function set USB device address -* @param pdev: device instance -* @param address: new device address -* @retval : status -*/ -void DCD_EP_SetAddress (USB_OTG_CORE_HANDLE *pdev, uint8_t address) -{ - USB_OTG_DCFG_TypeDef dcfg; - dcfg.d32 = 0; - dcfg.b.devaddr = address; - USB_OTG_MODIFY_REG32( &pdev->regs.DREGS->DCFG, 0, dcfg.d32); -} - -/** -* @brief Connect device (enable internal pull-up) -* @param pdev: device instance -* @retval : None -*/ -void DCD_DevConnect (USB_OTG_CORE_HANDLE *pdev) -{ -#ifndef USE_OTG_MODE - USB_OTG_DCTL_TypeDef dctl; - dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL); - /* Connect device */ - dctl.b.sftdiscon = 0; - USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32); - USB_OTG_BSP_mDelay(3); -#endif -} - - -/** -* @brief Disconnect device (disable internal pull-up) -* @param pdev: device instance -* @retval : None -*/ -void DCD_DevDisconnect (USB_OTG_CORE_HANDLE *pdev) -{ -#ifndef USE_OTG_MODE - USB_OTG_DCTL_TypeDef dctl; - dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL); - /* Disconnect device for 3ms */ - dctl.b.sftdiscon = 1; - USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32); - USB_OTG_BSP_mDelay(3); -#endif -} - - -/** -* @brief returns the EP Status -* @param pdev : Selected device -* epnum : endpoint address -* @retval : EP status -*/ - -uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,uint8_t epnum) -{ - USB_OTG_EP *ep; - uint32_t Status = 0; - - if ((0x80 & epnum) == 0x80) - { - ep = &pdev->dev.in_ep[epnum & 0x7F]; - } - else - { - ep = &pdev->dev.out_ep[epnum]; - } - - Status = USB_OTG_GetEPStatus(pdev ,ep); - - /* Return the current status */ - return Status; -} - -/** -* @brief Set the EP Status -* @param pdev : Selected device -* Status : new Status -* epnum : EP address -* @retval : None -*/ -void DCD_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum , uint32_t Status) -{ - USB_OTG_EP *ep; - - if ((0x80 & epnum) == 0x80) - { - ep = &pdev->dev.in_ep[epnum & 0x7F]; - } - else - { - ep = &pdev->dev.out_ep[epnum]; - } - - USB_OTG_SetEPStatus(pdev ,ep , Status); -} - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_dcd_int.c b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_dcd_int.c deleted file mode 100644 index eac902edc..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_dcd_int.c +++ /dev/null @@ -1,886 +0,0 @@ -/** - ****************************************************************************** - * @file usb_dcd_int.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Peripheral Device interrupt subroutines - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_dcd_int.h" -/** @addtogroup USB_OTG_DRIVER -* @{ -*/ - -/** @defgroup USB_DCD_INT -* @brief This file contains the interrupt subroutines for the Device mode. -* @{ -*/ - - -/** @defgroup USB_DCD_INT_Private_Defines -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_DCD_INT_Private_TypesDefinitions -* @{ -*/ -/** -* @} -*/ - - - -/** @defgroup USB_DCD_INT_Private_Macros -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_DCD_INT_Private_Variables -* @{ -*/ -/** -* @} -*/ - - -/** @defgroup USB_DCD_INT_Private_FunctionPrototypes -* @{ -*/ -/* static functions */ -static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum); - -/* Interrupt Handlers */ -static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev); - -static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev , uint32_t epnum); - -static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev); - -static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev); -#ifdef VBUS_SENSING_ENABLED -static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev); -#endif - -/** -* @} -*/ - - -/** @defgroup USB_DCD_INT_Private_Functions -* @{ -*/ - - -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED -/** -* @brief USBD_OTG_EP1OUT_ISR_Handler -* handles all USB Interrupts -* @param pdev: device instance -* @retval status -*/ -uint32_t USBD_OTG_EP1OUT_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) -{ - - USB_OTG_DOEPINTn_TypeDef doepint; - USB_OTG_DEPXFRSIZ_TypeDef deptsiz; - - doepint.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[1]->DOEPINT); - doepint.d32&= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOUTEP1MSK); - - /* Transfer complete */ - if ( doepint.b.xfercompl ) - { - /* Clear the bit in DOEPINTn for this interrupt */ - CLEAR_OUT_EP_INTR(1, xfercompl); - if (pdev->cfg.dma_enable == 1) - { - deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[1]->DOEPTSIZ)); - /*ToDo : handle more than one single MPS size packet */ - pdev->dev.out_ep[1].xfer_count = pdev->dev.out_ep[1].maxpacket - \ - deptsiz.b.xfersize; - } - /* Inform upper layer: data ready */ - /* RX COMPLETE */ - USBD_DCD_INT_fops->DataOutStage(pdev , 1); - - } - - /* Endpoint disable */ - if ( doepint.b.epdisabled ) - { - /* Clear the bit in DOEPINTn for this interrupt */ - CLEAR_OUT_EP_INTR(1, epdisabled); - } - /* AHB Error */ - if ( doepint.b.ahberr ) - { - CLEAR_OUT_EP_INTR(1, ahberr); - } - return 1; -} - -/** -* @brief USBD_OTG_EP1IN_ISR_Handler -* handles all USB Interrupts -* @param pdev: device instance -* @retval status -*/ -uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) -{ - - USB_OTG_DIEPINTn_TypeDef diepint; - uint32_t fifoemptymsk, msk, emp; - - msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DINEP1MSK); - emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK); - msk |= ((emp >> 1 ) & 0x1) << 7; - diepint.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[1]->DIEPINT) & msk; - - if ( diepint.b.xfercompl ) - { - fifoemptymsk = 0x1 << 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0); - CLEAR_IN_EP_INTR(1, xfercompl); - /* TX COMPLETE */ - USBD_DCD_INT_fops->DataInStage(pdev , 1); - } - if ( diepint.b.ahberr ) - { - CLEAR_IN_EP_INTR(1, ahberr); - } - if ( diepint.b.epdisabled ) - { - CLEAR_IN_EP_INTR(1, epdisabled); - } - if ( diepint.b.timeout ) - { - CLEAR_IN_EP_INTR(1, timeout); - } - if (diepint.b.intktxfemp) - { - CLEAR_IN_EP_INTR(1, intktxfemp); - } - if (diepint.b.intknepmis) - { - CLEAR_IN_EP_INTR(1, intknepmis); - } - if (diepint.b.inepnakeff) - { - CLEAR_IN_EP_INTR(1, inepnakeff); - } - if (diepint.b.emptyintr) - { - DCD_WriteEmptyTxFifo(pdev , 1); - CLEAR_IN_EP_INTR(1, emptyintr); - } - return 1; -} -#endif - -/** -* @brief STM32_USBF_OTG_ISR_Handler -* handles all USB Interrupts -* @param pdev: device instance -* @retval status -*/ -uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintr_status; - uint32_t retval = 0; - - if (USB_OTG_IsDeviceMode(pdev)) /* ensure that we are in device mode */ - { - gintr_status.d32 = USB_OTG_ReadCoreItr(pdev); - if (!gintr_status.d32) /* avoid spurious interrupt */ - { - return 0; - } - - if (gintr_status.b.outepintr) - { - retval |= DCD_HandleOutEP_ISR(pdev); - } - - if (gintr_status.b.inepint) - { - retval |= DCD_HandleInEP_ISR(pdev); - } - - if (gintr_status.b.modemismatch) - { - USB_OTG_GINTSTS_TypeDef gintsts; - - /* Clear interrupt */ - gintsts.d32 = 0; - gintsts.b.modemismatch = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); - } - - if (gintr_status.b.wkupintr) - { - retval |= DCD_HandleResume_ISR(pdev); - } - - if (gintr_status.b.usbsuspend) - { - retval |= DCD_HandleUSBSuspend_ISR(pdev); - } - if (gintr_status.b.sofintr) - { - retval |= DCD_HandleSof_ISR(pdev); - - } - - if (gintr_status.b.rxstsqlvl) - { - retval |= DCD_HandleRxStatusQueueLevel_ISR(pdev); - - } - - if (gintr_status.b.usbreset) - { - retval |= DCD_HandleUsbReset_ISR(pdev); - - } - if (gintr_status.b.enumdone) - { - retval |= DCD_HandleEnumDone_ISR(pdev); - } - - if (gintr_status.b.incomplisoin) - { - retval |= DCD_IsoINIncomplete_ISR(pdev); - } - - if (gintr_status.b.incomplisoout) - { - retval |= DCD_IsoOUTIncomplete_ISR(pdev); - } -#ifdef VBUS_SENSING_ENABLED - if (gintr_status.b.sessreqintr) - { - retval |= DCD_SessionRequest_ISR(pdev); - } - - if (gintr_status.b.otgintr) - { - retval |= DCD_OTG_ISR(pdev); - } -#endif - } - return retval; -} - -#ifdef VBUS_SENSING_ENABLED -/** -* @brief DCD_SessionRequest_ISR -* Indicates that the USB_OTG controller has detected a connection -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - USBD_DCD_INT_fops->DevConnected (pdev); - - /* Clear interrupt */ - gintsts.d32 = 0; - gintsts.b.sessreqintr = 1; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32); - return 1; -} - -/** -* @brief DCD_OTG_ISR -* Indicates that the USB_OTG controller has detected an OTG event: -* used to detect the end of session i.e. disconnection -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - - USB_OTG_GOTGINT_TypeDef gotgint; - - gotgint.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGINT); - - if (gotgint.b.sesenddet) - { - USBD_DCD_INT_fops->DevDisconnected (pdev); - } - /* Clear OTG interrupt */ - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGINT, gotgint.d32); - return 1; -} -#endif -/** -* @brief DCD_HandleResume_ISR -* Indicates that the USB_OTG controller has detected a resume or -* remote Wake-up sequence -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - USB_OTG_DCTL_TypeDef devctl; - USB_OTG_PCGCCTL_TypeDef power; - - if(pdev->cfg.low_power) - { - /* un-gate USB Core clock */ - power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL); - power.b.gatehclk = 0; - power.b.stoppclk = 0; - USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); - } - - /* Clear the Remote Wake-up Signaling */ - devctl.d32 = 0; - devctl.b.rmtwkupsig = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, devctl.d32, 0); - - /* Inform upper layer by the Resume Event */ - USBD_DCD_INT_fops->Resume (pdev); - - /* Clear interrupt */ - gintsts.d32 = 0; - gintsts.b.wkupintr = 1; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32); - return 1; -} - -/** -* @brief USB_OTG_HandleUSBSuspend_ISR -* Indicates that SUSPEND state has been detected on the USB -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - USB_OTG_PCGCCTL_TypeDef power; - USB_OTG_DSTS_TypeDef dsts; - - USBD_DCD_INT_fops->Suspend (pdev); - - dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); - - /* Clear interrupt */ - gintsts.d32 = 0; - gintsts.b.usbsuspend = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); - - if((pdev->cfg.low_power) && (dsts.b.suspsts == 1)) - { - /* switch-off the clocks */ - power.d32 = 0; - power.b.stoppclk = 1; - USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32); - - power.b.gatehclk = 1; - USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32); - - /* Request to enter Sleep mode after exit from current ISR */ - SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk); - } - return 1; -} - -/** -* @brief DCD_HandleInEP_ISR -* Indicates that an IN EP has a pending Interrupt -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_DIEPINTn_TypeDef diepint; - - uint32_t ep_intr; - uint32_t epnum = 0; - uint32_t fifoemptymsk; - diepint.d32 = 0; - ep_intr = USB_OTG_ReadDevAllInEPItr(pdev); - - while ( ep_intr ) - { - if (ep_intr&0x1) /* In ITR */ - { - diepint.d32 = DCD_ReadDevInEP(pdev , epnum); /* Get In ITR status */ - if ( diepint.b.xfercompl ) - { - fifoemptymsk = 0x1 << epnum; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0); - CLEAR_IN_EP_INTR(epnum, xfercompl); - /* TX COMPLETE */ - USBD_DCD_INT_fops->DataInStage(pdev , epnum); - - if (pdev->cfg.dma_enable == 1) - { - if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_IN)) - { - /* prepare to rx more setup packets */ - USB_OTG_EP0_OutStart(pdev); - } - } - } - if ( diepint.b.ahberr ) - { - CLEAR_IN_EP_INTR(epnum, ahberr); - } - if ( diepint.b.timeout ) - { - CLEAR_IN_EP_INTR(epnum, timeout); - } - if (diepint.b.intktxfemp) - { - CLEAR_IN_EP_INTR(epnum, intktxfemp); - } - if (diepint.b.intknepmis) - { - CLEAR_IN_EP_INTR(epnum, intknepmis); - } - if (diepint.b.inepnakeff) - { - CLEAR_IN_EP_INTR(epnum, inepnakeff); - } - if ( diepint.b.epdisabled ) - { - CLEAR_IN_EP_INTR(epnum, epdisabled); - } - if (diepint.b.emptyintr) - { - - DCD_WriteEmptyTxFifo(pdev , epnum); - - CLEAR_IN_EP_INTR(epnum, emptyintr); - } - } - epnum++; - ep_intr >>= 1; - } - - return 1; -} - -/** -* @brief DCD_HandleOutEP_ISR -* Indicates that an OUT EP has a pending Interrupt -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t ep_intr; - USB_OTG_DOEPINTn_TypeDef doepint; - USB_OTG_DEPXFRSIZ_TypeDef deptsiz; - uint32_t epnum = 0; - - doepint.d32 = 0; - - /* Read in the device interrupt bits */ - ep_intr = USB_OTG_ReadDevAllOutEp_itr(pdev); - - while ( ep_intr ) - { - if (ep_intr&0x1) - { - - doepint.d32 = USB_OTG_ReadDevOutEP_itr(pdev, epnum); - - /* Transfer complete */ - if ( doepint.b.xfercompl ) - { - /* Clear the bit in DOEPINTn for this interrupt */ - CLEAR_OUT_EP_INTR(epnum, xfercompl); - if (pdev->cfg.dma_enable == 1) - { - deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[epnum]->DOEPTSIZ)); - /*ToDo : handle more than one single MPS size packet */ - pdev->dev.out_ep[epnum].xfer_count = pdev->dev.out_ep[epnum].maxpacket - \ - deptsiz.b.xfersize; - } - /* Inform upper layer: data ready */ - /* RX COMPLETE */ - USBD_DCD_INT_fops->DataOutStage(pdev , epnum); - - if (pdev->cfg.dma_enable == 1) - { - if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_OUT)) - { - /* prepare to rx more setup packets */ - USB_OTG_EP0_OutStart(pdev); - } - } - } - /* Endpoint disable */ - if ( doepint.b.epdisabled ) - { - /* Clear the bit in DOEPINTn for this interrupt */ - CLEAR_OUT_EP_INTR(epnum, epdisabled); - } - /* AHB Error */ - if ( doepint.b.ahberr ) - { - CLEAR_OUT_EP_INTR(epnum, ahberr); - } - /* Setup Phase Done (control EPs) */ - if ( doepint.b.setup ) - { - - /* inform the upper layer that a setup packet is available */ - /* SETUP COMPLETE */ - USBD_DCD_INT_fops->SetupStage(pdev); - CLEAR_OUT_EP_INTR(epnum, setup); - } - } - epnum++; - ep_intr >>= 1; - } - return 1; -} - -/** -* @brief DCD_HandleSof_ISR -* Handles the SOF Interrupts -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef GINTSTS; - - - USBD_DCD_INT_fops->SOF(pdev); - - /* Clear interrupt */ - GINTSTS.d32 = 0; - GINTSTS.b.sofintr = 1; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, GINTSTS.d32); - - return 1; -} - -/** -* @brief DCD_HandleRxStatusQueueLevel_ISR -* Handles the Rx Status Queue Level Interrupt -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTMSK_TypeDef int_mask; - USB_OTG_DRXSTS_TypeDef status; - USB_OTG_EP *ep; - - /* Disable the Rx Status Queue Level interrupt */ - int_mask.d32 = 0; - int_mask.b.rxstsqlvl = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32, 0); - - /* Get the Status from the top of the FIFO */ - status.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRXSTSP ); - - ep = &pdev->dev.out_ep[status.b.epnum]; - - switch (status.b.pktsts) - { - case STS_GOUT_NAK: - break; - case STS_DATA_UPDT: - if (status.b.bcnt) - { - USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt); - ep->xfer_buff += status.b.bcnt; - ep->xfer_count += status.b.bcnt; - } - break; - case STS_XFER_COMP: - break; - case STS_SETUP_COMP: - break; - case STS_SETUP_UPDT: - /* Copy the setup packet received in FIFO into the setup buffer in RAM */ - USB_OTG_ReadPacket(pdev , pdev->dev.setup_packet, 8); - ep->xfer_count += status.b.bcnt; - break; - default: - break; - } - - /* Enable the Rx Status Queue Level interrupt */ - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, int_mask.d32); - - return 1; -} - -/** -* @brief DCD_WriteEmptyTxFifo -* check FIFO for the next packet to be loaded -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum) -{ - USB_OTG_DTXFSTSn_TypeDef txstatus; - USB_OTG_EP *ep; - uint32_t len = 0; - uint32_t len32b; - txstatus.d32 = 0; - - ep = &pdev->dev.in_ep[epnum]; - - len = ep->xfer_len - ep->xfer_count; - - if (len > ep->maxpacket) - { - len = ep->maxpacket; - } - - len32b = (len + 3) / 4; - txstatus.d32 = USB_OTG_READ_REG32( &pdev->regs.INEP_REGS[epnum]->DTXFSTS); - - - - while (txstatus.b.txfspcavail > len32b && - ep->xfer_count < ep->xfer_len && - ep->xfer_len != 0) - { - /* Write the FIFO */ - len = ep->xfer_len - ep->xfer_count; - - if (len > ep->maxpacket) - { - len = ep->maxpacket; - } - len32b = (len + 3) / 4; - - USB_OTG_WritePacket (pdev , ep->xfer_buff, epnum, len); - - ep->xfer_buff += len; - ep->xfer_count += len; - - txstatus.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DTXFSTS); - } - - return 1; -} - -/** -* @brief DCD_HandleUsbReset_ISR -* This interrupt occurs when a USB Reset is detected -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_DAINT_TypeDef daintmsk; - USB_OTG_DOEPMSK_TypeDef doepmsk; - USB_OTG_DIEPMSK_TypeDef diepmsk; - USB_OTG_DCFG_TypeDef dcfg; - USB_OTG_DCTL_TypeDef dctl; - USB_OTG_GINTSTS_TypeDef gintsts; - uint32_t i; - - dctl.d32 = 0; - daintmsk.d32 = 0; - doepmsk.d32 = 0; - diepmsk.d32 = 0; - dcfg.d32 = 0; - gintsts.d32 = 0; - - /* Clear the Remote Wake-up Signaling */ - dctl.b.rmtwkupsig = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 ); - - /* Flush the Tx FIFO */ - USB_OTG_FlushTxFifo(pdev , 0 ); - - for (i = 0; i < pdev->cfg.dev_endpoints ; i++) - { - USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF); - USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF); - } - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF ); - - daintmsk.ep.in = 1; - daintmsk.ep.out = 1; - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, daintmsk.d32 ); - - doepmsk.b.setup = 1; - doepmsk.b.xfercompl = 1; - doepmsk.b.ahberr = 1; - doepmsk.b.epdisabled = 1; - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, doepmsk.d32 ); -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOUTEP1MSK, doepmsk.d32 ); -#endif - diepmsk.b.xfercompl = 1; - diepmsk.b.timeout = 1; - diepmsk.b.epdisabled = 1; - diepmsk.b.ahberr = 1; - diepmsk.b.intknepmis = 1; - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, diepmsk.d32 ); -#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DINEP1MSK, diepmsk.d32 ); -#endif - /* Reset Device Address */ - dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG); - dcfg.b.devaddr = 0; - USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32); - - - /* setup EP0 to receive SETUP packets */ - USB_OTG_EP0_OutStart(pdev); - - /* Clear interrupt */ - gintsts.d32 = 0; - gintsts.b.usbreset = 1; - USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32); - - /*Reset internal state machine */ - USBD_DCD_INT_fops->Reset(pdev); - return 1; -} - -/** -* @brief DCD_HandleEnumDone_ISR -* Read the device status register and set the device speed -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - USB_OTG_GUSBCFG_TypeDef gusbcfg; - - USB_OTG_EP0Activate(pdev); - - /* Set USB turn-around time based on device speed and PHY interface. */ - gusbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); - - /* Full or High speed */ - if ( USB_OTG_GetDeviceSpeed(pdev) == USB_SPEED_HIGH) - { - pdev->cfg.speed = USB_OTG_SPEED_HIGH; - pdev->cfg.mps = USB_OTG_HS_MAX_PACKET_SIZE ; - gusbcfg.b.usbtrdtim = 9; - } - else - { - pdev->cfg.speed = USB_OTG_SPEED_FULL; - pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ; - gusbcfg.b.usbtrdtim = 5; - } - - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, gusbcfg.d32); - - /* Clear interrupt */ - gintsts.d32 = 0; - gintsts.b.enumdone = 1; - USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, gintsts.d32 ); - return 1; -} - - -/** -* @brief DCD_IsoINIncomplete_ISR -* handle the ISO IN incomplete interrupt -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - - gintsts.d32 = 0; - - USBD_DCD_INT_fops->IsoINIncomplete (pdev); - - /* Clear interrupt */ - gintsts.b.incomplisoin = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); - - return 1; -} - -/** -* @brief DCD_IsoOUTIncomplete_ISR -* handle the ISO OUT incomplete interrupt -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - - gintsts.d32 = 0; - - USBD_DCD_INT_fops->IsoOUTIncomplete (pdev); - - /* Clear interrupt */ - gintsts.b.incomplisoout = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); - return 1; -} -/** -* @brief DCD_ReadDevInEP -* Reads ep flags -* @param pdev: device instance -* @retval status -*/ -static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum) -{ - uint32_t v, msk, emp; - msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPMSK); - emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK); - msk |= ((emp >> epnum) & 0x1) << 7; - v = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT) & msk; - return v; -} - - - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_hcd.c b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_hcd.c deleted file mode 100644 index 689d061ae..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_hcd.c +++ /dev/null @@ -1,256 +0,0 @@ -/** - ****************************************************************************** - * @file usb_hcd.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Host Interface Layer - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_core.h" -#include "usb_hcd.h" -#include "usb_conf.h" -#include "usb_bsp.h" - - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_HCD - * @brief This file is the interface between EFSL ans Host mass-storage class - * @{ - */ - - -/** @defgroup USB_HCD_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USB_HCD_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_Private_Variables - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_Private_FunctionPrototypes - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_Private_Functions - * @{ - */ - -/** - * @brief HCD_Init - * Initialize the HOST portion of the driver. - * @param pdev: Selected device - * @param base_address: OTG base address - * @retval Status - */ -uint32_t HCD_Init(USB_OTG_CORE_HANDLE *pdev , - USB_OTG_CORE_ID_TypeDef coreID) -{ - uint8_t i = 0; - pdev->host.ConnSts = 0; - - for (i= 0; i< USB_OTG_MAX_TX_FIFOS; i++) - { - pdev->host.ErrCnt[i] = 0; - pdev->host.XferCnt[i] = 0; - pdev->host.HC_Status[i] = HC_IDLE; - } - pdev->host.hc[0].max_packet = 8; - - USB_OTG_SelectCore(pdev, coreID); -#ifndef DUAL_ROLE_MODE_ENABLED - USB_OTG_DisableGlobalInt(pdev); - USB_OTG_CoreInit(pdev); - - /* Force Host Mode*/ - USB_OTG_SetCurrentMode(pdev , HOST_MODE); - USB_OTG_CoreInitHost(pdev); - USB_OTG_EnableGlobalInt(pdev); -#endif - - return 0; -} - - -/** - * @brief HCD_GetCurrentSpeed - * Get Current device Speed. - * @param pdev : Selected device - * @retval Status - */ - -uint32_t HCD_GetCurrentSpeed (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HPRT0_TypeDef HPRT0; - HPRT0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0); - - return HPRT0.b.prtspd; -} - -/** - * @brief HCD_ResetPort - * Issues the reset command to device - * @param pdev : Selected device - * @retval Status - */ -uint32_t HCD_ResetPort(USB_OTG_CORE_HANDLE *pdev) -{ - /* - Before starting to drive a USB reset, the application waits for the OTG - interrupt triggered by the debounce done bit (DBCDNE bit in OTG_FS_GOTGINT), - which indicates that the bus is stable again after the electrical debounce - caused by the attachment of a pull-up resistor on DP (FS) or DM (LS). - */ - - USB_OTG_ResetPort(pdev); - return 0; -} - -/** - * @brief HCD_IsDeviceConnected - * Check if the device is connected. - * @param pdev : Selected device - * @retval Device connection status. 1 -> connected and 0 -> disconnected - * - */ -uint32_t HCD_IsDeviceConnected(USB_OTG_CORE_HANDLE *pdev) -{ - return (pdev->host.ConnSts); -} - -/** - * @brief HCD_GetCurrentFrame - * This function returns the frame number for sof packet - * @param pdev : Selected device - * @retval Frame number - * - */ -uint32_t HCD_GetCurrentFrame (USB_OTG_CORE_HANDLE *pdev) -{ - return (USB_OTG_READ_REG32(&pdev->regs.HREGS->HFNUM) & 0xFFFF) ; -} - -/** - * @brief HCD_GetURB_State - * This function returns the last URBstate - * @param pdev: Selected device - * @retval URB_STATE - * - */ -URB_STATE HCD_GetURB_State (USB_OTG_CORE_HANDLE *pdev , uint8_t ch_num) -{ - return pdev->host.URB_State[ch_num] ; -} - -/** - * @brief HCD_GetXferCnt - * This function returns the last URBstate - * @param pdev: Selected device - * @retval No. of data bytes transferred - * - */ -uint32_t HCD_GetXferCnt (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num) -{ - return pdev->host.XferCnt[ch_num] ; -} - - - -/** - * @brief HCD_GetHCState - * This function returns the HC Status - * @param pdev: Selected device - * @retval HC_STATUS - * - */ -HC_STATUS HCD_GetHCState (USB_OTG_CORE_HANDLE *pdev , uint8_t ch_num) -{ - return pdev->host.HC_Status[ch_num] ; -} - -/** - * @brief HCD_HC_Init - * This function prepare a HC and start a transfer - * @param pdev: Selected device - * @param hc_num: Channel number - * @retval status - */ -uint32_t HCD_HC_Init (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - return USB_OTG_HC_Init(pdev, hc_num); -} - -/** - * @brief HCD_SubmitRequest - * This function prepare a HC and start a transfer - * @param pdev: Selected device - * @param hc_num: Channel number - * @retval status - */ -uint32_t HCD_SubmitRequest (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num) -{ - - pdev->host.URB_State[hc_num] = URB_IDLE; - pdev->host.hc[hc_num].xfer_count = 0 ; - return USB_OTG_HC_StartXfer(pdev, hc_num); -} - - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_hcd_int.c b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_hcd_int.c deleted file mode 100644 index bd4081fb3..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_hcd_int.c +++ /dev/null @@ -1,832 +0,0 @@ -/** - ****************************************************************************** - * @file usb_hcd_int.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief Host driver interrupt subroutines - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_core.h" -#include "usb_defines.h" -#include "usb_hcd_int.h" - -#if defined (__CC_ARM) /*!< ARM Compiler */ - #pragma O0 -#elif defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma O0 -#elif defined (__GNUC__) /*!< GNU Compiler */ - #pragma GCC optimize ("O0") -#elif defined (__TASKING__) /*!< TASKING Compiler */ - #pragma optimize=0 - -#endif /* __CC_ARM */ - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_HCD_INT - * @brief This file contains the interrupt subroutines for the Host mode. - * @{ - */ - - -/** @defgroup USB_HCD_INT_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_INT_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USB_HCD_INT_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_INT_Private_Variables - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_HCD_INT_Private_FunctionPrototypes - * @{ - */ - -static uint32_t USB_OTG_USBH_handle_sof_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t USB_OTG_USBH_handle_port_ISR(USB_OTG_CORE_HANDLE *pdev); -static uint32_t USB_OTG_USBH_handle_hc_ISR (USB_OTG_CORE_HANDLE *pdev); -static uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev , - uint32_t num); -static uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev , - uint32_t num); -static uint32_t USB_OTG_USBH_handle_rx_qlvl_ISR (USB_OTG_CORE_HANDLE *pdev); -static uint32_t USB_OTG_USBH_handle_nptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev); -static uint32_t USB_OTG_USBH_handle_ptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev); -static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev); -static uint32_t USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (USB_OTG_CORE_HANDLE *pdev); - -/** - * @} - */ - - -/** @defgroup USB_HCD_INT_Private_Functions - * @{ - */ - -/** - * @brief HOST_Handle_ISR - * This function handles all USB Host Interrupts - * @param pdev: Selected device - * @retval status - */ - -uint32_t USBH_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - uint32_t retval = 0; - - gintsts.d32 = 0; - - /* Check if HOST Mode */ - if (USB_OTG_IsHostMode(pdev)) - { - gintsts.d32 = USB_OTG_ReadCoreItr(pdev); - if (!gintsts.d32) - { - return 0; - } - - if (gintsts.b.sofintr) - { - retval |= USB_OTG_USBH_handle_sof_ISR (pdev); - } - - if (gintsts.b.rxstsqlvl) - { - retval |= USB_OTG_USBH_handle_rx_qlvl_ISR (pdev); - } - - if (gintsts.b.nptxfempty) - { - retval |= USB_OTG_USBH_handle_nptxfempty_ISR (pdev); - } - - if (gintsts.b.ptxfempty) - { - retval |= USB_OTG_USBH_handle_ptxfempty_ISR (pdev); - } - - if (gintsts.b.hcintr) - { - retval |= USB_OTG_USBH_handle_hc_ISR (pdev); - } - - if (gintsts.b.portintr) - { - retval |= USB_OTG_USBH_handle_port_ISR (pdev); - } - - if (gintsts.b.disconnect) - { - retval |= USB_OTG_USBH_handle_Disconnect_ISR (pdev); - - } - - if (gintsts.b.incomplisoout) - { - retval |= USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (pdev); - } - - - } - return retval; -} - -/** - * @brief USB_OTG_USBH_handle_hc_ISR - * This function indicates that one or more host channels has a pending - * @param pdev: Selected device - * @retval status - */ -static uint32_t USB_OTG_USBH_handle_hc_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HAINT_TypeDef haint; - USB_OTG_HCCHAR_TypeDef hcchar; - uint32_t i = 0; - uint32_t retval = 0; - - /* Clear appropriate bits in HCINTn to clear the interrupt bit in - * GINTSTS */ - - haint.d32 = USB_OTG_ReadHostAllChannels_intr(pdev); - - for (i = 0; i < pdev->cfg.host_channels ; i++) - { - if (haint.b.chint & (1 << i)) - { - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[i]->HCCHAR); - - if (hcchar.b.epdir) - { - retval |= USB_OTG_USBH_handle_hc_n_In_ISR (pdev, i); - } - else - { - retval |= USB_OTG_USBH_handle_hc_n_Out_ISR (pdev, i); - } - } - } - - return retval; -} - -/** - * @brief USB_OTG_otg_hcd_handle_sof_intr - * Handles the start-of-frame interrupt in host mode. - * @param pdev: Selected device - * @retval status - */ -static uint32_t USB_OTG_USBH_handle_sof_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - - - gintsts.d32 = 0; - /* Clear interrupt */ - gintsts.b.sofintr = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); - - return 1; -} - -/** - * @brief USB_OTG_USBH_handle_Disconnect_ISR - * Handles disconnect event. - * @param pdev: Selected device - * @retval status - */ -static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - - pdev->host.ConnSts = 0; - gintsts.d32 = 0; - - pdev->host.port_cb->Disconnect(pdev); - - /* Clear interrupt */ - gintsts.b.disconnect = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); - - return 1; -} - -/** - * @brief USB_OTG_USBH_handle_nptxfempty_ISR - * Handles non periodic tx fifo empty. - * @param pdev: Selected device - * @retval status - */ -static uint32_t USB_OTG_USBH_handle_nptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTMSK_TypeDef intmsk; - USB_OTG_HNPTXSTS_TypeDef hnptxsts; - uint16_t len_words , len; - - hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS); - - len_words = (pdev->host.hc[hnptxsts.b.chnum].xfer_len + 3) / 4; - - while ((hnptxsts.b.nptxfspcavail > len_words)&& - (pdev->host.hc[hnptxsts.b.chnum].xfer_len != 0)) - { - - len = hnptxsts.b.nptxfspcavail * 4; - - if (len > pdev->host.hc[hnptxsts.b.chnum].xfer_len) - { - /* Last packet */ - len = pdev->host.hc[hnptxsts.b.chnum].xfer_len; - - intmsk.d32 = 0; - intmsk.b.nptxfempty = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0); - } - - len_words = (pdev->host.hc[hnptxsts.b.chnum].xfer_len + 3) / 4; - - USB_OTG_WritePacket (pdev , pdev->host.hc[hnptxsts.b.chnum].xfer_buff, hnptxsts.b.chnum, len); - - pdev->host.hc[hnptxsts.b.chnum].xfer_buff += len; - pdev->host.hc[hnptxsts.b.chnum].xfer_len -= len; - pdev->host.hc[hnptxsts.b.chnum].xfer_count += len; - - hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS); - } - - return 1; -} - -/** - * @brief USB_OTG_USBH_handle_ptxfempty_ISR - * Handles periodic tx fifo empty - * @param pdev: Selected device - * @retval status - */ -static uint32_t USB_OTG_USBH_handle_ptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTMSK_TypeDef intmsk; - USB_OTG_HPTXSTS_TypeDef hptxsts; - uint16_t len_words , len; - - hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS); - - len_words = (pdev->host.hc[hptxsts.b.chnum].xfer_len + 3) / 4; - - while ((hptxsts.b.ptxfspcavail > len_words)&& - (pdev->host.hc[hptxsts.b.chnum].xfer_len != 0)) - { - - len = hptxsts.b.ptxfspcavail * 4; - - if (len > pdev->host.hc[hptxsts.b.chnum].xfer_len) - { - len = pdev->host.hc[hptxsts.b.chnum].xfer_len; - /* Last packet */ - intmsk.d32 = 0; - intmsk.b.ptxfempty = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0); - } - - len_words = (pdev->host.hc[hptxsts.b.chnum].xfer_len + 3) / 4; - - USB_OTG_WritePacket (pdev , pdev->host.hc[hptxsts.b.chnum].xfer_buff, hptxsts.b.chnum, len); - - pdev->host.hc[hptxsts.b.chnum].xfer_buff += len; - pdev->host.hc[hptxsts.b.chnum].xfer_len -= len; - pdev->host.hc[hptxsts.b.chnum].xfer_count += len; - - hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS); - } - - return 1; -} - -/** - * @brief USB_OTG_USBH_handle_port_ISR - * This function determines which interrupt conditions have occurred - * @param pdev: Selected device - * @retval status - */ -static uint32_t USB_OTG_USBH_handle_port_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_HPRT0_TypeDef hprt0; - USB_OTG_HPRT0_TypeDef hprt0_dup; - USB_OTG_HCFG_TypeDef hcfg; - uint32_t do_reset = 0; - uint32_t retval = 0; - - hcfg.d32 = 0; - hprt0.d32 = 0; - hprt0_dup.d32 = 0; - - hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0); - hprt0_dup.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0); - - /* Clear the interrupt bits in GINTSTS */ - - hprt0_dup.b.prtena = 0; - hprt0_dup.b.prtconndet = 0; - hprt0_dup.b.prtenchng = 0; - hprt0_dup.b.prtovrcurrchng = 0; - - /* Port Connect Detected */ - if (hprt0.b.prtconndet) - { - pdev->host.port_cb->Connect(pdev); - hprt0_dup.b.prtconndet = 1; - do_reset = 1; - retval |= 1; - } - - /* Port Enable Changed */ - if (hprt0.b.prtenchng) - { - hprt0_dup.b.prtenchng = 1; - if (hprt0.b.prtena == 1) - { - pdev->host.ConnSts = 1; - - if ((hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED) || - (hprt0.b.prtspd == HPRT0_PRTSPD_FULL_SPEED)) - { - - hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG); - - if (hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED) - { - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 6000 ); - if (hcfg.b.fslspclksel != HCFG_6_MHZ) - { - if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID) - { - USB_OTG_InitFSLSPClkSel(pdev ,HCFG_6_MHZ ); - } - do_reset = 1; - } - } - else - { - - USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 48000 ); - if (hcfg.b.fslspclksel != HCFG_48_MHZ) - { - USB_OTG_InitFSLSPClkSel(pdev ,HCFG_48_MHZ ); - do_reset = 1; - } - } - } - else - { - do_reset = 1; - } - } - } - /* Overcurrent Change Interrupt */ - if (hprt0.b.prtovrcurrchng) - { - hprt0_dup.b.prtovrcurrchng = 1; - retval |= 1; - } - if (do_reset) - { - USB_OTG_ResetPort(pdev); - - } - /* Clear Port Interrupts */ - USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0_dup.d32); - - return retval; -} - -/** - * @brief USB_OTG_USBH_handle_hc_n_Out_ISR - * Handles interrupt for a specific Host Channel - * @param pdev: Selected device - * @param hc_num: Channel number - * @retval status - */ -uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num) -{ - - USB_OTG_HCINTn_TypeDef hcint; - USB_OTG_HCGINTMSK_TypeDef hcintmsk; - USB_OTG_HC_REGS *hcreg; - USB_OTG_HCCHAR_TypeDef hcchar; - - hcreg = pdev->regs.HC_REGS[num]; - hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT); - hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCGINTMSK); - hcint.d32 = hcint.d32 & hcintmsk.d32; - - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR); - - if (hcint.b.ahberr) - { - CLEAR_HC_INT(hcreg ,ahberr); - UNMASK_HOST_INT_CHH (num); - } - else if (hcint.b.ack) - { - CLEAR_HC_INT(hcreg , ack); - } - - else if (hcint.b.xfercompl) - { - pdev->host.ErrCnt[num] = 0; - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , xfercompl); - pdev->host.HC_Status[num] = HC_XFRC; - } - - else if (hcint.b.stall) - { - CLEAR_HC_INT(hcreg , stall); - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - pdev->host.HC_Status[num] = HC_STALL; - } - - else if (hcint.b.nak) - { - pdev->host.ErrCnt[num] = 0; - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , nak); - pdev->host.HC_Status[num] = HC_NAK; - } - - else if (hcint.b.xacterr) - { - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - pdev->host.ErrCnt[num] ++; - pdev->host.HC_Status[num] = HC_XACTERR; - CLEAR_HC_INT(hcreg , xacterr); - } - else if (hcint.b.nyet) - { - pdev->host.ErrCnt[num] = 0; - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , nyet); - pdev->host.HC_Status[num] = HC_NYET; - } - else if (hcint.b.datatglerr) - { - - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , nak); - pdev->host.HC_Status[num] = HC_DATATGLERR; - - CLEAR_HC_INT(hcreg , datatglerr); - } - else if (hcint.b.chhltd) - { - MASK_HOST_INT_CHH (num); - - if(pdev->host.HC_Status[num] == HC_XFRC) - { - pdev->host.URB_State[num] = URB_DONE; - - if (hcchar.b.eptype == EP_TYPE_BULK) - { - pdev->host.hc[num].toggle_out ^= 1; - } - } - else if(pdev->host.HC_Status[num] == HC_NAK) - { - pdev->host.URB_State[num] = URB_NOTREADY; - } - else if(pdev->host.HC_Status[num] == HC_NYET) - { - if(pdev->host.hc[num].do_ping == 1) - { - USB_OTG_HC_DoPing(pdev, num); - } - pdev->host.URB_State[num] = URB_NOTREADY; - } - else if(pdev->host.HC_Status[num] == HC_STALL) - { - pdev->host.URB_State[num] = URB_STALL; - } - else if(pdev->host.HC_Status[num] == HC_XACTERR) - { - if (pdev->host.ErrCnt[num] == 3) - { - pdev->host.URB_State[num] = URB_ERROR; - pdev->host.ErrCnt[num] = 0; - } - } - CLEAR_HC_INT(hcreg , chhltd); - } - - - return 1; -} - -/** - * @brief USB_OTG_USBH_handle_hc_n_In_ISR - * Handles interrupt for a specific Host Channel - * @param pdev: Selected device - * @param hc_num: Channel number - * @retval status - */ -uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num) -{ - USB_OTG_HCINTn_TypeDef hcint; - USB_OTG_HCGINTMSK_TypeDef hcintmsk; - USB_OTG_HCCHAR_TypeDef hcchar; - USB_OTG_HCTSIZn_TypeDef hctsiz; - USB_OTG_HC_REGS *hcreg; - - - hcreg = pdev->regs.HC_REGS[num]; - hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT); - hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCGINTMSK); - hcint.d32 = hcint.d32 & hcintmsk.d32; - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR); - hcintmsk.d32 = 0; - - - if (hcint.b.ahberr) - { - CLEAR_HC_INT(hcreg ,ahberr); - UNMASK_HOST_INT_CHH (num); - } - else if (hcint.b.ack) - { - CLEAR_HC_INT(hcreg ,ack); - } - - else if (hcint.b.stall) - { - UNMASK_HOST_INT_CHH (num); - pdev->host.HC_Status[num] = HC_STALL; - CLEAR_HC_INT(hcreg , nak); /* Clear the NAK Condition */ - CLEAR_HC_INT(hcreg , stall); /* Clear the STALL Condition */ - hcint.b.nak = 0; /* NOTE: When there is a 'stall', reset also nak, - else, the pdev->host.HC_Status = HC_STALL - will be overwritten by 'nak' in code below */ - USB_OTG_HC_Halt(pdev, num); - } - else if (hcint.b.datatglerr) - { - - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , nak); - pdev->host.HC_Status[num] = HC_DATATGLERR; - CLEAR_HC_INT(hcreg , datatglerr); - } - - if (hcint.b.frmovrun) - { - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg ,frmovrun); - } - - else if (hcint.b.xfercompl) - { - - if (pdev->cfg.dma_enable == 1) - { - hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCTSIZ); - pdev->host.XferCnt[num] = pdev->host.hc[num].xfer_len - hctsiz.b.xfersize; - } - - pdev->host.HC_Status[num] = HC_XFRC; - pdev->host.ErrCnt [num]= 0; - CLEAR_HC_INT(hcreg , xfercompl); - - if ((hcchar.b.eptype == EP_TYPE_CTRL)|| - (hcchar.b.eptype == EP_TYPE_BULK)) - { - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , nak); - pdev->host.hc[num].toggle_in ^= 1; - - } - else if(hcchar.b.eptype == EP_TYPE_INTR) - { - hcchar.b.oddfrm = 1; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32); - pdev->host.URB_State[num] = URB_DONE; - } - - } - else if (hcint.b.chhltd) - { - MASK_HOST_INT_CHH (num); - - if(pdev->host.HC_Status[num] == HC_XFRC) - { - pdev->host.URB_State[num] = URB_DONE; - } - - else if (pdev->host.HC_Status[num] == HC_STALL) - { - pdev->host.URB_State[num] = URB_STALL; - } - - else if((pdev->host.HC_Status[num] == HC_XACTERR) || - (pdev->host.HC_Status[num] == HC_DATATGLERR)) - { - pdev->host.ErrCnt[num] = 0; - pdev->host.URB_State[num] = URB_ERROR; - - } - else if(hcchar.b.eptype == EP_TYPE_INTR) - { - pdev->host.hc[num].toggle_in ^= 1; - } - - CLEAR_HC_INT(hcreg , chhltd); - - } - else if (hcint.b.xacterr) - { - UNMASK_HOST_INT_CHH (num); - pdev->host.ErrCnt[num] ++; - pdev->host.HC_Status[num] = HC_XACTERR; - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , xacterr); - - } - else if (hcint.b.nak) - { - if(hcchar.b.eptype == EP_TYPE_INTR) - { - UNMASK_HOST_INT_CHH (num); - USB_OTG_HC_Halt(pdev, num); - CLEAR_HC_INT(hcreg , nak); - } - else if ((hcchar.b.eptype == EP_TYPE_CTRL)|| - (hcchar.b.eptype == EP_TYPE_BULK)) - { - /* re-activate the channel */ - hcchar.b.chen = 1; - hcchar.b.chdis = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32); - } - pdev->host.HC_Status[num] = HC_NAK; - } - - - return 1; - -} - -/** - * @brief USB_OTG_USBH_handle_rx_qlvl_ISR - * Handles the Rx Status Queue Level Interrupt - * @param pdev: Selected device - * @retval status - */ - -static uint32_t USB_OTG_USBH_handle_rx_qlvl_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GRXFSTS_TypeDef grxsts; - USB_OTG_GINTMSK_TypeDef intmsk; - USB_OTG_HCTSIZn_TypeDef hctsiz; - USB_OTG_HCCHAR_TypeDef hcchar; - __IO uint8_t channelnum =0; - uint32_t count; - - /* Disable the Rx Status Queue Level interrupt */ - intmsk.d32 = 0; - intmsk.b.rxstsqlvl = 1; - USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0); - - grxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRXSTSP); - channelnum = grxsts.b.chnum; - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[channelnum]->HCCHAR); - - switch (grxsts.b.pktsts) - { - case GRXSTS_PKTSTS_IN: - /* Read the data into the host buffer. */ - if ((grxsts.b.bcnt > 0) && (pdev->host.hc[channelnum].xfer_buff != (void *)0)) - { - - USB_OTG_ReadPacket(pdev, pdev->host.hc[channelnum].xfer_buff, grxsts.b.bcnt); - /*manage multiple Xfer */ - pdev->host.hc[grxsts.b.chnum].xfer_buff += grxsts.b.bcnt; - pdev->host.hc[grxsts.b.chnum].xfer_count += grxsts.b.bcnt; - - - count = pdev->host.hc[channelnum].xfer_count; - pdev->host.XferCnt[channelnum] = count; - - hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[channelnum]->HCTSIZ); - if(hctsiz.b.pktcnt > 0) - { - /* re-activate the channel when more packets are expected */ - hcchar.b.chen = 1; - hcchar.b.chdis = 0; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[channelnum]->HCCHAR, hcchar.d32); - } - } - break; - - case GRXSTS_PKTSTS_IN_XFER_COMP: - - case GRXSTS_PKTSTS_DATA_TOGGLE_ERR: - case GRXSTS_PKTSTS_CH_HALTED: - default: - break; - } - - /* Enable the Rx Status Queue Level interrupt */ - intmsk.b.rxstsqlvl = 1; - USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, 0, intmsk.d32); - return 1; -} - -/** - * @brief USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR - * Handles the incomplete Periodic transfer Interrupt - * @param pdev: Selected device - * @retval status - */ -static uint32_t USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (USB_OTG_CORE_HANDLE *pdev) -{ - - USB_OTG_GINTSTS_TypeDef gintsts; - USB_OTG_HCCHAR_TypeDef hcchar; - - - - - hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[0]->HCCHAR); - hcchar.b.chen = 1; - hcchar.b.chdis = 1; - USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[0]->HCCHAR, hcchar.d32); - - gintsts.d32 = 0; - /* Clear interrupt */ - gintsts.b.incomplisoout = 1; - USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); - - return 1; -} - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ - diff --git a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_otg.c b/example/stm32f4/STM32_USB_OTG_Driver/src/usb_otg.c deleted file mode 100644 index fbb71ecb4..000000000 --- a/example/stm32f4/STM32_USB_OTG_Driver/src/usb_otg.c +++ /dev/null @@ -1,175 +0,0 @@ -/** - ****************************************************************************** - * @file usb_otg.c - * @author MCD Application Team - * @version V2.0.0 - * @date 22-July-2011 - * @brief OTG Core Layer - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "usb_defines.h" -#include "usb_regs.h" -#include "usb_core.h" -#include "usb_otg.h" - -/** @addtogroup USB_OTG_DRIVER - * @{ - */ - -/** @defgroup USB_OTG - * @brief This file is the interface between EFSL ans Host mass-storage class - * @{ - */ - - -/** @defgroup USB_OTG_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_OTG_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - - -/** @defgroup USB_OTG_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_OTG_Private_Variables - * @{ - */ -/** - * @} - */ - - -/** @defgroup USB_OTG_Private_FunctionPrototypes - * @{ - */ - -static uint32_t USB_OTG_Read_itr(USB_OTG_CORE_HANDLE *pdev); - -/** - * @} - */ - - -/** @defgroup USB_OTG_Private_Functions - * @{ - */ - - -/* OTG Interrupt Handler */ - - -/** - * @brief STM32_USBO_OTG_ISR_Handler - * - * @param None - * @retval : None - */ -uint32_t STM32_USBO_OTG_ISR_Handler(USB_OTG_CORE_HANDLE *pdev) -{ - uint32_t retval = 0; - USB_OTG_GINTSTS_TypeDef gintsts ; - gintsts.d32 = 0; - - gintsts.d32 = USB_OTG_Read_itr(pdev); - if (gintsts.d32 == 0) - { - return 0; - } - if (gintsts.b.otgintr) - { - retval |= 1;//USB_OTG_HandleOTG_ISR(pdev); - } - if (gintsts.b.conidstschng) - { - retval |= 2;//USB_OTG_HandleConnectorIDStatusChange_ISR(pdev); - } - if (gintsts.b.sessreqintr) - { - retval |= 3;//USB_OTG_HandleSessionRequest_ISR(pdev); - } - return retval; -} - - -/** - * @brief USB_OTG_Read_itr - * returns the Core Interrupt register - * @param None - * @retval : status - */ -static uint32_t USB_OTG_Read_itr(USB_OTG_CORE_HANDLE *pdev) -{ - USB_OTG_GINTSTS_TypeDef gintsts; - USB_OTG_GINTMSK_TypeDef gintmsk; - USB_OTG_GINTMSK_TypeDef gintmsk_common; - - - gintsts.d32 = 0; - gintmsk.d32 = 0; - gintmsk_common.d32 = 0; - - /* OTG interrupts */ - gintmsk_common.b.sessreqintr = 1; - gintmsk_common.b.conidstschng = 1; - gintmsk_common.b.otgintr = 1; - - gintsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS); - gintmsk.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTMSK); - return ((gintsts.d32 & gintmsk.d32 ) & gintmsk_common.d32); -} - - -/** - * @brief USB_OTG_GetCurrentState - * Return current OTG State - * @param None - * @retval : None - */ -uint32_t USB_OTG_GetCurrentState (USB_OTG_CORE_HANDLE *pdev) -{ - return pdev->otg.OTG_State; -} - - -/** -* @} -*/ - -/** -* @} -*/ - -/** -* @} -*/ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Utilities/STM32F4-Discovery/Release_Notes.html b/example/stm32f4/Utilities/STM32F4-Discovery/Release_Notes.html deleted file mode 100644 index 7b270b4f1..000000000 --- a/example/stm32f4/Utilities/STM32F4-Discovery/Release_Notes.html +++ /dev/null @@ -1,151 +0,0 @@ - - - - - - - - - - - - - - - - Release Notes for STM32F4-Discovery Board Drivers - - - - - - - - - - -
-


-

-
- - - - - - -
- - - - - - - - - -
-

Back to Release page

-
-

Release -Notes for STM32F4-Discovery Board Drivers

-

Copyright -2011 STMicroelectronics

-

-
-

 

- - - - - - -
-

Contents

-
    -
  1. STM32F4-Discovery Board Drivers update History
  2. -
  3. License
  4. -
- - -

STM32F4-Discovery Board Drivers update History

For more information on the STM32F4-Discovery board visit www.st.com/stm32f4-discovery.

V1.0.0 / 19-September-2011

-

Main -Changes

- -
  • First official version of the STM32F4-Discovery Board Drivers

License

-

The -enclosed firmware and all the related documentation are not covered by -a License Agreement, if you need such License you can contact your -local STMicroelectronics office.

- - 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. - -
-
-

For -complete documentation on STMicroelectronics Microcontrollers visit www.st.com

-
-

-
-
-

 

-
- - \ No newline at end of file diff --git a/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery.c b/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery.c deleted file mode 100644 index ff0d69718..000000000 --- a/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery.c +++ /dev/null @@ -1,257 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4_discovery.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file provides set of firmware functions to manage Leds and - * push-button available on STM32F4-Discovery Kit from STMicroelectronics. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4_discovery.h" - -//ADDED BY ME!!!!!!!!!!!!!!!!!!!! -#include "stm32f4xx_conf.h" - - -/** @addtogroup Utilities - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY - * @{ - */ - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL - * @brief This file provides set of firmware functions to manage Leds and push-button - * available on STM32F4-Discovery Kit from STMicroelectronics. - * @{ - */ - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Private_Defines - * @{ - */ -/** - * @} - */ - - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Private_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Private_Variables - * @{ - */ -GPIO_TypeDef* GPIO_PORT[LEDn] = {LED4_GPIO_PORT, LED3_GPIO_PORT, LED5_GPIO_PORT, - LED6_GPIO_PORT}; -const uint16_t GPIO_PIN[LEDn] = {LED4_PIN, LED3_PIN, LED5_PIN, - LED6_PIN}; -const uint32_t GPIO_CLK[LEDn] = {LED4_GPIO_CLK, LED3_GPIO_CLK, LED5_GPIO_CLK, - LED6_GPIO_CLK}; - -GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {USER_BUTTON_GPIO_PORT }; - -const uint16_t BUTTON_PIN[BUTTONn] = {USER_BUTTON_PIN }; - -const uint32_t BUTTON_CLK[BUTTONn] = {USER_BUTTON_GPIO_CLK }; - -const uint16_t BUTTON_EXTI_LINE[BUTTONn] = {USER_BUTTON_EXTI_LINE }; - -const uint8_t BUTTON_PORT_SOURCE[BUTTONn] = {USER_BUTTON_EXTI_PORT_SOURCE}; - -const uint8_t BUTTON_PIN_SOURCE[BUTTONn] = {USER_BUTTON_EXTI_PIN_SOURCE }; -const uint8_t BUTTON_IRQn[BUTTONn] = {USER_BUTTON_EXTI_IRQn }; - -NVIC_InitTypeDef NVIC_InitStructure; - -/** - * @} - */ - - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Private_Functions - * @{ - */ - -/** - * @brief Configures LED GPIO. - * @param Led: Specifies the Led to be configured. - * This parameter can be one of following parameters: - * @arg LED4 - * @arg LED3 - * @arg LED5 - * @arg LED6 - * @retval None - */ -void STM_EVAL_LEDInit(Led_TypeDef Led) -{ - GPIO_InitTypeDef GPIO_InitStructure; - - /* Enable the GPIO_LED Clock */ - RCC_AHB1PeriphClockCmd(GPIO_CLK[Led], ENABLE); - - /* Configure the GPIO_LED pin */ - GPIO_InitStructure.GPIO_Pin = GPIO_PIN[Led]; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIO_PORT[Led], &GPIO_InitStructure); -} - -/** - * @brief Turns selected LED On. - * @param Led: Specifies the Led to be set on. - * This parameter can be one of following parameters: - * @arg LED4 - * @arg LED3 - * @arg LED5 - * @arg LED6 - * @retval None - */ -void STM_EVAL_LEDOn(Led_TypeDef Led) -{ - GPIO_PORT[Led]->BSRRL = GPIO_PIN[Led]; -} - -/** - * @brief Turns selected LED Off. - * @param Led: Specifies the Led to be set off. - * This parameter can be one of following parameters: - * @arg LED4 - * @arg LED3 - * @arg LED5 - * @arg LED6 - * @retval None - */ -void STM_EVAL_LEDOff(Led_TypeDef Led) -{ - GPIO_PORT[Led]->BSRRH = GPIO_PIN[Led]; -} - -/** - * @brief Toggles the selected LED. - * @param Led: Specifies the Led to be toggled. - * This parameter can be one of following parameters: - * @arg LED4 - * @arg LED3 - * @arg LED5 - * @arg LED6 - * @retval None - */ -void STM_EVAL_LEDToggle(Led_TypeDef Led) -{ - GPIO_PORT[Led]->ODR ^= GPIO_PIN[Led]; -} - -/** - * @brief Configures Button GPIO and EXTI Line. - * @param Button: Specifies the Button to be configured. - * This parameter should be: BUTTON_USER - * @param Button_Mode: Specifies Button mode. - * This parameter can be one of following parameters: - * @arg BUTTON_MODE_GPIO: Button will be used as simple IO - * @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt - * generation capability - * @retval None - */ -void STM_EVAL_PBInit(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode) -{ - GPIO_InitTypeDef GPIO_InitStructure; - EXTI_InitTypeDef EXTI_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; - - /* Enable the BUTTON Clock */ - RCC_AHB1PeriphClockCmd(BUTTON_CLK[Button], ENABLE); - RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); - - /* Configure Button pin as input */ - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Pin = BUTTON_PIN[Button]; - GPIO_Init(BUTTON_PORT[Button], &GPIO_InitStructure); - - if (Button_Mode == BUTTON_MODE_EXTI) - { - /* Connect Button EXTI Line to Button GPIO Pin */ - SYSCFG_EXTILineConfig(BUTTON_PORT_SOURCE[Button], BUTTON_PIN_SOURCE[Button]); - - /* Configure Button EXTI line */ - EXTI_InitStructure.EXTI_Line = BUTTON_EXTI_LINE[Button]; - EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; - EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; - EXTI_InitStructure.EXTI_LineCmd = ENABLE; - EXTI_Init(&EXTI_InitStructure); - - /* Enable and set Button EXTI Interrupt to the lowest priority */ - NVIC_InitStructure.NVIC_IRQChannel = BUTTON_IRQn[Button]; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - - NVIC_Init(&NVIC_InitStructure); - } -} - -/** - * @brief Returns the selected Button state. - * @param Button: Specifies the Button to be checked. - * This parameter should be: BUTTON_USER - * @retval The Button GPIO pin value. - */ -uint32_t STM_EVAL_PBGetState(Button_TypeDef Button) -{ - return GPIO_ReadInputDataBit(BUTTON_PORT[Button], BUTTON_PIN[Button]); -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery.h b/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery.h deleted file mode 100644 index c6fec4221..000000000 --- a/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery.h +++ /dev/null @@ -1,158 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4_discovery.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file contains definitions for STM32F4-Discovery Kit's Leds and - * push-button hardware resources. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4_DISCOVERY_H -#define __STM32F4_DISCOVERY_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ - #include "stm32f4xx.h" - -/** @addtogroup Utilities - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY_LOW_LEVEL - * @{ - */ - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Exported_Types - * @{ - */ -typedef enum -{ - LED4 = 0, - LED3 = 1, - LED5 = 2, - LED6 = 3 -} Led_TypeDef; - -typedef enum -{ - BUTTON_USER = 0, -} Button_TypeDef; - -typedef enum -{ - BUTTON_MODE_GPIO = 0, - BUTTON_MODE_EXTI = 1 -} ButtonMode_TypeDef; -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Exported_Constants - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY_LOW_LEVEL_LED - * @{ - */ -#define LEDn 4 - -#define LED4_PIN GPIO_Pin_12 -#define LED4_GPIO_PORT GPIOD -#define LED4_GPIO_CLK RCC_AHB1Periph_GPIOD - -#define LED3_PIN GPIO_Pin_13 -#define LED3_GPIO_PORT GPIOD -#define LED3_GPIO_CLK RCC_AHB1Periph_GPIOD - -#define LED5_PIN GPIO_Pin_14 -#define LED5_GPIO_PORT GPIOD -#define LED5_GPIO_CLK RCC_AHB1Periph_GPIOD - -#define LED6_PIN GPIO_Pin_15 -#define LED6_GPIO_PORT GPIOD -#define LED6_GPIO_CLK RCC_AHB1Periph_GPIOD -/** - * @} - */ - -/** @addtogroup STM32F4_DISCOVERY_LOW_LEVEL_BUTTON - * @{ - */ -#define BUTTONn 1 - -/** - * @brief Wakeup push-button - */ -#define USER_BUTTON_PIN GPIO_Pin_0 -#define USER_BUTTON_GPIO_PORT GPIOA -#define USER_BUTTON_GPIO_CLK RCC_AHB1Periph_GPIOA -#define USER_BUTTON_EXTI_LINE EXTI_Line0 -#define USER_BUTTON_EXTI_PORT_SOURCE EXTI_PortSourceGPIOA -#define USER_BUTTON_EXTI_PIN_SOURCE EXTI_PinSource0 -#define USER_BUTTON_EXTI_IRQn EXTI0_IRQn -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Exported_Macros - * @{ - */ -/** - * @} - */ - - -/** @defgroup STM32F4_DISCOVERY_LOW_LEVEL_Exported_Functions - * @{ - */ -void STM_EVAL_LEDInit(Led_TypeDef Led); -void STM_EVAL_LEDOn(Led_TypeDef Led); -void STM_EVAL_LEDOff(Led_TypeDef Led); -void STM_EVAL_LEDToggle(Led_TypeDef Led); -void STM_EVAL_PBInit(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode); -uint32_t STM_EVAL_PBGetState(Button_TypeDef Button); -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4_DISCOVERY_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_audio_codec.c b/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_audio_codec.c deleted file mode 100644 index 0445aa571..000000000 --- a/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_audio_codec.c +++ /dev/null @@ -1,1651 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4_discovery_audio_codec.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file includes the low layer driver for CS43L22 Audio Codec - * available on STM32F4-Discovery Kit. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/*============================================================================================================================== - User NOTES -1. How To use this driver: --------------------------- - - This driver supports STM32F4xx devices on STM32F4-Discovery Kit. - - - Configure the options in file stm32f4_discovery_audio_codec.h in the section CONFIGURATION. - Refer to the sections 2 and 3 to have more details on the possible configurations. - - - Call the function EVAL_AUDIO_Init( - OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER, - OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_AUTO or - OUTPUT_DEVICE_BOTH) - Volume: initial volume to be set (0 is min (mute), 100 is max (100%) - AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000 ...) - this parameter is relative to the audio file/stream type. - ) - This function configures all the hardware required for the audio application (codec, I2C, I2S, - GPIOs, DMA and interrupt if needed). This function returns 0 if configuration is OK. - if the returned value is different from 0 or the function is stuck then the communication with - the codec (try to un-plug the power or reset device in this case). - + OUTPUT_DEVICE_SPEAKER: only speaker will be set as output for the audio stream. - + OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream. - + OUTPUT_DEVICE_AUTO: Selection of output device is made through external switch (implemented - into the audio jack on the evaluation board). When the Headphone is connected it is used - as output. When the headphone is disconnected from the audio jack, the output is - automatically switched to Speaker. - + OUTPUT_DEVICE_BOTH: both Speaker and Headphone are used as outputs for the audio stream - at the same time. - - - Call the function EVAL_AUDIO_Play( - pBuffer: pointer to the audio data file address - Size: size of the buffer to be sent in Bytes - ) - to start playing (for the first time) from the audio file/stream. - - - Call the function EVAL_AUDIO_PauseResume( - Cmd: AUDIO_PAUSE (or 0) to pause playing or AUDIO_RESUME (or - any value different from 0) to resume playing. - ) - Note. After calling EVAL_AUDIO_PauseResume() function for pause, only EVAL_AUDIO_PauseResume() should be called - for resume (it is not allowed to call EVAL_AUDIO_Play() in this case). - Note. This function should be called only when the audio file is played or paused (not stopped). - - - For each mode, you may need to implement the relative callback functions into your code. - The Callback functions are named EVAL_AUDIO_XXX_CallBack() and only their prototypes are declared in - the stm32f4_discovery_audio_codec.h file. (refer to the example for more details on the callbacks implementations) - - - To Stop playing, to modify the volume level or to mute, use the functions - EVAL_AUDIO_Stop(), EVAL_AUDIO_VolumeCtl() and EVAL_AUDIO_Mute(). - - - The driver API and the callback functions are at the end of the stm32f4_discovery_audio_codec.h file. - - - Driver architecture: - -------------------- - This driver is composed of three main layers: - o High Audio Layer: consists of the function API exported in the stm32f4_discovery_audio_codec.h file - (EVAL_AUDIO_Init(), EVAL_AUDIO_Play() ...) - o Codec Control layer: consists of the functions API controlling the audio codec (CS43L22) and - included as local functions in file stm32f4_discovery_audio_codec.c (Codec_Init(), Codec_Play() ...) - o Media Access Layer (MAL): which consists of functions allowing to access the media containing/ - providing the audio file/stream. These functions are also included as local functions into - the stm32f4_discovery_audio_codec.c file (Audio_MAL_Init(), Audio_MAL_Play() ...) - Each set of functions (layer) may be implemented independently of the others and customized when - needed. - -2. Modes description: ---------------------- - + AUDIO_MAL_MODE_NORMAL : is suitable when the audio file is in a memory location. - + AUDIO_MAL_MODE_CIRCULAR: is suitable when the audio data are read either from a - memory location or from a device at real time (double buffer could be used). - -3. DMA interrupts description: ------------------------------- - + EVAL_AUDIO_IT_TC_ENABLE: Enable this define to use the DMA end of transfer interrupt. - then, a callback should be implemented by user to perform specific actions - when the DMA has finished the transfer. - + EVAL_AUDIO_IT_HT_ENABLE: Enable this define to use the DMA end of half transfer interrupt. - then, a callback should be implemented by user to perform specific actions - when the DMA has reached the half of the buffer transfer (generally, it is useful - to load the first half of buffer while DMA is loading from the second half). - + EVAL_AUDIO_IT_ER_ENABLE: Enable this define to manage the cases of error on DMA transfer. - -4. Known Limitations: ---------------------- - 1- When using the Speaker, if the audio file quality is not high enough, the speaker output - may produce high and uncomfortable noise level. To avoid this issue, to use speaker - output properly, try to increase audio file sampling rate (typically higher than 48KHz). - This operation will lead to larger file size. - 2- Communication with the audio codec (through I2C) may be corrupted if it is interrupted by some - user interrupt routines (in this case, interrupts could be disabled just before the start of - communication then re-enabled when it is over). Note that this communication is only done at - the configuration phase (EVAL_AUDIO_Init() or EVAL_AUDIO_Stop()) and when Volume control modification is - performed (EVAL_AUDIO_VolumeCtl() or EVAL_AUDIO_Mute()). When the audio data is played, no communication is - required with the audio codec. - 3- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size, - File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file. - 4- Mono audio streaming is not supported (in order to play mono audio streams, each data should be sent twice - on the I2S or should be duplicated on the source buffer. Or convert the stream in stereo before playing). - 5- Supports only 16-bit audio data size. -===============================================================================================================================*/ - - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4_discovery_audio_codec.h" -//ADDED BY ME!!!!!!!!!!!!!!!!!!!! -#include "stm32f4xx_conf.h" - -/** @addtogroup Utilities - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY_AUDIO_CODEC - * @brief This file includes the low layer driver for CS43L22 Audio Codec - * available on STM32F4-Discovery Kit. - * @{ - */ - -/** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Private_Types - * @{ - */ -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Private_Defines - * @{ - */ - -/* Mask for the bit EN of the I2S CFGR register */ -#define I2S_ENABLE_MASK 0x0400 - -/* Delay for the Codec to be correctly reset */ -#define CODEC_RESET_DELAY 0x4FFF - -/* Codec audio Standards */ -#ifdef I2S_STANDARD_PHILLIPS - #define CODEC_STANDARD 0x04 - #define I2S_STANDARD I2S_Standard_Phillips -#elif defined(I2S_STANDARD_MSB) - #define CODEC_STANDARD 0x00 - #define I2S_STANDARD I2S_Standard_MSB -#elif defined(I2S_STANDARD_LSB) - #define CODEC_STANDARD 0x08 - #define I2S_STANDARD I2S_Standard_LSB -#else - #error "Error: No audio communication standard selected !" -#endif /* I2S_STANDARD */ - -/* The 7 bits Codec address (sent through I2C interface) */ -#define CODEC_ADDRESS 0x94 /* b00100111 */ -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Private_Macros - * @{ - */ -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Private_Variables - * @{ - */ -/* This structure is declared global because it is handled by two different functions */ -static DMA_InitTypeDef DMA_InitStructure; -DMA_InitTypeDef AUDIO_MAL_DMA_InitStructure; - -uint32_t AudioTotalSize = 0xFFFF; /* This variable holds the total size of the audio file */ -uint32_t AudioRemSize = 0xFFFF; /* This variable holds the remaining data in audio file */ -uint16_t *CurrentPos; /* This variable holds the current position of audio pointer */ - -__IO uint32_t CODECTimeout = CODEC_LONG_TIMEOUT; -__IO uint8_t OutputDev = 0; - - -__IO uint32_t CurrAudioInterface = AUDIO_INTERFACE_I2S; //AUDIO_INTERFACE_DAC -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Private_Function_Prototypes - * @{ - */ -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Private_Functions - * @{ - */ -static void Audio_MAL_IRQHandler(void); -/*----------------------------------- - Audio Codec functions - ------------------------------------------*/ -/* High Layer codec functions */ -static uint32_t Codec_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq); -static uint32_t Codec_DeInit(void); -static uint32_t Codec_Play(void); -static uint32_t Codec_PauseResume(uint32_t Cmd); -static uint32_t Codec_Stop(uint32_t Cmd); -static uint32_t Codec_VolumeCtrl(uint8_t Volume); -static uint32_t Codec_Mute(uint32_t Cmd); -/* Low layer codec functions */ -static void Codec_CtrlInterface_Init(void); -static void Codec_CtrlInterface_DeInit(void); -static void Codec_AudioInterface_Init(uint32_t AudioFreq); -static void Codec_AudioInterface_DeInit(void); -static void Codec_Reset(void); -static uint32_t Codec_WriteRegister(uint8_t RegisterAddr, uint8_t RegisterValue); -static uint32_t Codec_ReadRegister(uint8_t RegisterAddr); -static void Codec_GPIO_Init(void); -static void Codec_GPIO_DeInit(void); -static void Delay(__IO uint32_t nCount); -/*----------------------------------------------------------------------------*/ - -/*----------------------------------- - MAL (Media Access Layer) functions - ------------------------------------------*/ -/* Peripherals configuration functions */ -static void Audio_MAL_Init(void); -static void Audio_MAL_DeInit(void); -static void Audio_MAL_Play(uint32_t Addr, uint32_t Size); -static void Audio_MAL_PauseResume(uint32_t Cmd, uint32_t Addr); -static void Audio_MAL_Stop(void); -/*----------------------------------------------------------------------------*/ - - /* DMA Stream definitions */ - uint32_t AUDIO_MAL_DMA_CLOCK = AUDIO_I2S_DMA_CLOCK; - DMA_Stream_TypeDef * AUDIO_MAL_DMA_STREAM = AUDIO_I2S_DMA_STREAM ; - uint32_t AUDIO_MAL_DMA_DREG = AUDIO_I2S_DMA_DREG; - uint32_t AUDIO_MAL_DMA_CHANNEL = AUDIO_I2S_DMA_CHANNEL; - uint32_t AUDIO_MAL_DMA_IRQ = AUDIO_I2S_DMA_IRQ ; - uint32_t AUDIO_MAL_DMA_FLAG_TC = AUDIO_I2S_DMA_FLAG_TC; - uint32_t AUDIO_MAL_DMA_FLAG_HT = AUDIO_I2S_DMA_FLAG_HT; - uint32_t AUDIO_MAL_DMA_FLAG_FE = AUDIO_I2S_DMA_FLAG_FE; - uint32_t AUDIO_MAL_DMA_FLAG_TE = AUDIO_I2S_DMA_FLAG_TE; - uint32_t AUDIO_MAL_DMA_FLAG_DME = AUDIO_I2S_DMA_FLAG_DME; - -/** - * @brief Set the current audio interface (I2S or DAC). - * @param Interface: AUDIO_INTERFACE_I2S or AUDIO_INTERFACE_DAC - * @retval None - */ -void EVAL_AUDIO_SetAudioInterface(uint32_t Interface) -{ - CurrAudioInterface = Interface; - - if (CurrAudioInterface == AUDIO_INTERFACE_I2S) - { - /* DMA Stream definitions */ - AUDIO_MAL_DMA_CLOCK = AUDIO_I2S_DMA_CLOCK; - AUDIO_MAL_DMA_STREAM = AUDIO_I2S_DMA_STREAM; - AUDIO_MAL_DMA_DREG = AUDIO_I2S_DMA_DREG; - AUDIO_MAL_DMA_CHANNEL = AUDIO_I2S_DMA_CHANNEL; - AUDIO_MAL_DMA_IRQ = AUDIO_I2S_DMA_IRQ ; - AUDIO_MAL_DMA_FLAG_TC = AUDIO_I2S_DMA_FLAG_TC; - AUDIO_MAL_DMA_FLAG_HT = AUDIO_I2S_DMA_FLAG_HT; - AUDIO_MAL_DMA_FLAG_FE = AUDIO_I2S_DMA_FLAG_FE; - AUDIO_MAL_DMA_FLAG_TE = AUDIO_I2S_DMA_FLAG_TE; - AUDIO_MAL_DMA_FLAG_DME = AUDIO_I2S_DMA_FLAG_DME; - } - else if (Interface == AUDIO_INTERFACE_DAC) - { - /* DMA Stream definitions */ - AUDIO_MAL_DMA_CLOCK = AUDIO_DAC_DMA_CLOCK; - AUDIO_MAL_DMA_STREAM = AUDIO_DAC_DMA_STREAM; - AUDIO_MAL_DMA_DREG = AUDIO_DAC_DMA_DREG; - AUDIO_MAL_DMA_CHANNEL = AUDIO_DAC_DMA_CHANNEL; - AUDIO_MAL_DMA_IRQ = AUDIO_DAC_DMA_IRQ ; - AUDIO_MAL_DMA_FLAG_TC = AUDIO_DAC_DMA_FLAG_TC; - AUDIO_MAL_DMA_FLAG_HT = AUDIO_DAC_DMA_FLAG_HT; - AUDIO_MAL_DMA_FLAG_FE = AUDIO_DAC_DMA_FLAG_FE; - AUDIO_MAL_DMA_FLAG_TE = AUDIO_DAC_DMA_FLAG_TE; - AUDIO_MAL_DMA_FLAG_DME = AUDIO_DAC_DMA_FLAG_DME; - } -} - -/** - * @brief Configure the audio peripherals. - * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, - * OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO . - * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) - * @param AudioFreq: Audio frequency used to play the audio stream. - * @retval 0 if correct communication, else wrong communication - */ -uint32_t EVAL_AUDIO_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq) -{ - /* Perform low layer Codec initialization */ - if (Codec_Init(OutputDevice, VOLUME_CONVERT(Volume), AudioFreq) != 0) - { - return 1; - } - else - { - /* I2S data transfer preparation: - Prepare the Media to be used for the audio transfer from memory to I2S peripheral */ - Audio_MAL_Init(); - - /* Return 0 when all operations are OK */ - return 0; - } -} - -/** - * @brief Deinitializes all the resources used by the codec (those initialized - * by EVAL_AUDIO_Init() function). - * @param None - * @retval 0 if correct communication, else wrong communication - */ -uint32_t EVAL_AUDIO_DeInit(void) -{ - /* DeInitialize the Media layer */ - Audio_MAL_DeInit(); - - /* DeInitialize Codec */ - Codec_DeInit(); - - return 0; -} - -/** - * @brief Starts playing audio stream from a data buffer for a determined size. - * @param pBuffer: Pointer to the buffer - * @param Size: Number of audio data BYTES. - * @retval 0 if correct communication, else wrong communication - */ -uint32_t EVAL_AUDIO_Play(uint16_t* pBuffer, uint32_t Size) -{ - /* Set the total number of data to be played (count in half-word) */ - AudioTotalSize = Size/2; - - /* Call the audio Codec Play function */ - Codec_Play(); - - /* Update the Media layer and enable it for play */ - Audio_MAL_Play((uint32_t)pBuffer, (uint32_t)(DMA_MAX(AudioTotalSize / 2))); - - /* Update the remaining number of data to be played */ - AudioRemSize = (Size/2) - DMA_MAX(AudioTotalSize); - - /* Update the current audio pointer position */ - CurrentPos = pBuffer + DMA_MAX(AudioTotalSize); - - return 0; -} - -/** - * @brief This function Pauses or Resumes the audio file stream. In case - * of using DMA, the DMA Pause feature is used. In all cases the I2S - * peripheral is disabled. - * - * @WARNING When calling EVAL_AUDIO_PauseResume() function for pause, only - * this function should be called for resume (use of EVAL_AUDIO_Play() - * function for resume could lead to unexpected behavior). - * - * @param Cmd: AUDIO_PAUSE (or 0) to pause, AUDIO_RESUME (or any value different - * from 0) to resume. - * @retval 0 if correct communication, else wrong communication - */ -uint32_t EVAL_AUDIO_PauseResume(uint32_t Cmd) -{ - /* Call the Audio Codec Pause/Resume function */ - if (Codec_PauseResume(Cmd) != 0) - { - return 1; - } - else - { - /* Call the Media layer pause/resume function */ - Audio_MAL_PauseResume(Cmd, 0); - - /* Return 0 if all operations are OK */ - return 0; - } -} - -/** - * @brief Stops audio playing and Power down the Audio Codec. - * @param Option: could be one of the following parameters - * - CODEC_PDWN_SW: for software power off (by writing registers). - * Then no need to reconfigure the Codec after power on. - * - CODEC_PDWN_HW: completely shut down the codec (physically). - * Then need to reconfigure the Codec after power on. - * @retval 0 if correct communication, else wrong communication - */ -uint32_t EVAL_AUDIO_Stop(uint32_t Option) -{ - /* Call Audio Codec Stop function */ - if (Codec_Stop(Option) != 0) - { - return 1; - } - else - { - /* Call Media layer Stop function */ - Audio_MAL_Stop(); - - /* Update the remaining data number */ - AudioRemSize = AudioTotalSize; - - /* Return 0 when all operations are correctly done */ - return 0; - } -} - -/** - * @brief Controls the current audio volume level. - * @param Volume: Volume level to be set in percentage from 0% to 100% (0 for - * Mute and 100 for Max volume level). - * @retval 0 if correct communication, else wrong communication - */ -uint32_t EVAL_AUDIO_VolumeCtl(uint8_t Volume) -{ - /* Call the codec volume control function with converted volume value */ - return (Codec_VolumeCtrl(VOLUME_CONVERT(Volume))); -} - -/** - * @brief Enables or disables the MUTE mode by software - * @param Command: could be AUDIO_MUTE_ON to mute sound or AUDIO_MUTE_OFF to - * unmute the codec and restore previous volume level. - * @retval 0 if correct communication, else wrong communication - */ -uint32_t EVAL_AUDIO_Mute(uint32_t Cmd) -{ - /* Call the Codec Mute function */ - return (Codec_Mute(Cmd)); -} - -/** - * @brief This function handles main Media layer interrupt. - * @param None - * @retval 0 if correct communication, else wrong communication - */ -static void Audio_MAL_IRQHandler(void) -{ -#ifndef AUDIO_MAL_MODE_NORMAL - uint16_t *pAddr = (uint16_t *)CurrentPos; - uint32_t Size = AudioRemSize; -#endif /* AUDIO_MAL_MODE_NORMAL */ - -#ifdef AUDIO_MAL_DMA_IT_TC_EN - /* Transfer complete interrupt */ - if (DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC) != RESET) - { - #ifdef AUDIO_MAL_MODE_NORMAL - /* Check if the end of file has been reached */ - if (AudioRemSize > 0) - { - /* Wait the DMA Stream to be effectively disabled */ - while (DMA_GetCmdStatus(AUDIO_MAL_DMA_STREAM) != DISABLE) - {} - - /* Clear the Interrupt flag */ - DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC); - - /* Re-Configure the buffer address and size */ - DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) CurrentPos; - DMA_InitStructure.DMA_BufferSize = (uint32_t) (DMA_MAX(AudioRemSize)); - - /* Configure the DMA Stream with the new parameters */ - DMA_Init(AUDIO_MAL_DMA_STREAM, &DMA_InitStructure); - - /* Enable the I2S DMA Stream*/ - DMA_Cmd(AUDIO_MAL_DMA_STREAM, ENABLE); - - /* Update the current pointer position */ - CurrentPos += DMA_MAX(AudioRemSize); - - /* Update the remaining number of data to be played */ - AudioRemSize -= DMA_MAX(AudioRemSize); - } - else - { - /* Disable the I2S DMA Stream*/ - DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE); - - /* Clear the Interrupt flag */ - DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC); - - /* Manage the remaining file size and new address offset: This function - should be coded by user (its prototype is already declared in stm32f4_discovery_audio_codec.h) */ - EVAL_AUDIO_TransferComplete_CallBack((uint32_t)CurrentPos, 0); - } - - #elif defined(AUDIO_MAL_MODE_CIRCULAR) - /* Manage the remaining file size and new address offset: This function - should be coded by user (its prototype is already declared in stm32f4_discovery_audio_codec.h) */ - EVAL_AUDIO_TransferComplete_CallBack(pAddr, Size); - - /* Clear the Interrupt flag */ - DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC); - #endif /* AUDIO_MAL_MODE_NORMAL */ - } -#endif /* AUDIO_MAL_DMA_IT_TC_EN */ - -#ifdef AUDIO_MAL_DMA_IT_HT_EN - /* Half Transfer complete interrupt */ - if (DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_HT) != RESET) - { - /* Manage the remaining file size and new address offset: This function - should be coded by user (its prototype is already declared in stm32f4_discovery_audio_codec.h) */ - EVAL_AUDIO_HalfTransfer_CallBack((uint32_t)pAddr, Size); - - /* Clear the Interrupt flag */ - DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_HT); - } -#endif /* AUDIO_MAL_DMA_IT_HT_EN */ - -#ifdef AUDIO_MAL_DMA_IT_TE_EN - /* FIFO Error interrupt */ - if ((DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TE) != RESET) || \ - (DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_FE) != RESET) || \ - (DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_DME) != RESET)) - - { - /* Manage the error generated on DMA FIFO: This function - should be coded by user (its prototype is already declared in stm32f4_discovery_audio_codec.h) */ - EVAL_AUDIO_Error_CallBack((uint32_t*)&pAddr); - - /* Clear the Interrupt flag */ - DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TE | AUDIO_MAL_DMA_FLAG_FE | \ - AUDIO_MAL_DMA_FLAG_DME); - } -#endif /* AUDIO_MAL_DMA_IT_TE_EN */ -} - -/** - * @brief This function handles main I2S interrupt. - * @param None - * @retval 0 if correct communication, else wrong communication - */ -void Audio_MAL_I2S_IRQHandler(void) -{ - Audio_MAL_IRQHandler(); -} - -/** - * @brief This function handles main DAC interrupt. - * @param None - * @retval 0 if correct communication, else wrong communication - */ -void Audio_MAL_DAC_IRQHandler(void) -{ - Audio_MAL_IRQHandler(); -} - -/** - * @brief I2S interrupt management - * @param None - * @retval None - */ -void Audio_I2S_IRQHandler(void) -{ - /* Check on the I2S TXE flag */ - if (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) != RESET) - { - if (CurrAudioInterface == AUDIO_INTERFACE_DAC) - { - /* Wirte data to the DAC interface */ - DAC_SetChannel1Data(DAC_Align_12b_L, EVAL_AUDIO_GetSampleCallBack()); - } - - /* Send dummy data on I2S to avoid the underrun condition */ - SPI_I2S_SendData(CODEC_I2S, EVAL_AUDIO_GetSampleCallBack()); - } -} -/*======================== - - CS43L22 Audio Codec Control Functions - ==============================*/ -/** - * @brief Initializes the audio codec and all related interfaces (control - * interface: I2C and audio interface: I2S) - * @param OutputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, - * OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO . - * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) - * @param AudioFreq: Audio frequency used to play the audio stream. - * @retval 0 if correct communication, else wrong communication - */ -static uint32_t Codec_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq) -{ - uint32_t counter = 0; - - /* Configure the Codec related IOs */ - Codec_GPIO_Init(); - - /* Reset the Codec Registers */ - Codec_Reset(); - - /* Initialize the Control interface of the Audio Codec */ - Codec_CtrlInterface_Init(); - - /* Keep Codec powered OFF */ - counter += Codec_WriteRegister(0x02, 0x01); - - counter += Codec_WriteRegister(0x04, 0xAF); /* SPK always OFF & HP always ON */ - OutputDev = 0xAF; - - /* Clock configuration: Auto detection */ - counter += Codec_WriteRegister(0x05, 0x81); - - /* Set the Slave Mode and the audio Standard */ - counter += Codec_WriteRegister(0x06, CODEC_STANDARD); - - /* Set the Master volume */ - Codec_VolumeCtrl(Volume); - - if (CurrAudioInterface == AUDIO_INTERFACE_DAC) - { - /* Enable the PassThrough on AIN1A and AIN1B */ - counter += Codec_WriteRegister(0x08, 0x01); - counter += Codec_WriteRegister(0x09, 0x01); - - /* Route the analog input to the HP line */ - counter += Codec_WriteRegister(0x0E, 0xC0); - - /* Set the Passthough volume */ - counter += Codec_WriteRegister(0x14, 0x00); - counter += Codec_WriteRegister(0x15, 0x00); - } - - /* Power on the Codec */ - counter += Codec_WriteRegister(0x02, 0x9E); - - /* Additional configuration for the CODEC. These configurations are done to reduce - the time needed for the Codec to power off. If these configurations are removed, - then a long delay should be added between powering off the Codec and switching - off the I2S peripheral MCLK clock (which is the operating clock for Codec). - If this delay is not inserted, then the codec will not shut down properly and - it results in high noise after shut down. */ - - /* Disable the analog soft ramp */ - counter += Codec_WriteRegister(0x0A, 0x00); - if (CurrAudioInterface != AUDIO_INTERFACE_DAC) - { - /* Disable the digital soft ramp */ - counter += Codec_WriteRegister(0x0E, 0x04); - } - /* Disable the limiter attack level */ - counter += Codec_WriteRegister(0x27, 0x00); - /* Adjust Bass and Treble levels */ - counter += Codec_WriteRegister(0x1F, 0x0F); - /* Adjust PCM volume level */ - counter += Codec_WriteRegister(0x1A, 0x0A); - counter += Codec_WriteRegister(0x1B, 0x0A); - - /* Configure the I2S peripheral */ - Codec_AudioInterface_Init(AudioFreq); - - /* Return communication control value */ - return counter; -} - -/** - * @brief Restore the audio codec state to default state and free all used - * resources. - * @param None - * @retval 0 if correct communication, else wrong communication - */ -static uint32_t Codec_DeInit(void) -{ - uint32_t counter = 0; - - /* Reset the Codec Registers */ - Codec_Reset(); - - /* Keep Codec powered OFF */ - counter += Codec_WriteRegister(0x02, 0x01); - - /* Deinitialize all use GPIOs */ - Codec_GPIO_DeInit(); - - /* Disable the Codec control interface */ - Codec_CtrlInterface_DeInit(); - - /* Deinitialize the Codec audio interface (I2S) */ - Codec_AudioInterface_DeInit(); - - /* Return communication control value */ - return counter; -} - -/** - * @brief Start the audio Codec play feature. - * @note For this codec no Play options are required. - * @param None - * @retval 0 if correct communication, else wrong communication - */ -static uint32_t Codec_Play(void) -{ - /* - No actions required on Codec level for play command - */ - - /* Return communication control value */ - return 0; -} - -/** - * @brief Pauses and resumes playing on the audio codec. - * @param Cmd: AUDIO_PAUSE (or 0) to pause, AUDIO_RESUME (or any value different - * from 0) to resume. - * @retval 0 if correct communication, else wrong communication - */ -static uint32_t Codec_PauseResume(uint32_t Cmd) -{ - uint32_t counter = 0; - - /* Pause the audio file playing */ - if (Cmd == AUDIO_PAUSE) - { - /* Mute the output first */ - counter += Codec_Mute(AUDIO_MUTE_ON); - - /* Put the Codec in Power save mode */ - counter += Codec_WriteRegister(0x02, 0x01); - } - else /* AUDIO_RESUME */ - { - /* Unmute the output first */ - counter += Codec_Mute(AUDIO_MUTE_OFF); - - counter += Codec_WriteRegister(0x04, OutputDev); - - /* Exit the Power save mode */ - counter += Codec_WriteRegister(0x02, 0x9E); - } - - return counter; -} - -/** - * @brief Stops audio Codec playing. It powers down the codec. - * @param CodecPdwnMode: selects the power down mode. - * - CODEC_PDWN_SW: only mutes the audio codec. When resuming from this - * mode the codec keeps the previous initialization - * (no need to re-Initialize the codec registers). - * - CODEC_PDWN_HW: Physically power down the codec. When resuming from this - * mode, the codec is set to default configuration - * (user should re-Initialize the codec in order to - * play again the audio stream). - * @retval 0 if correct communication, else wrong communication - */ -static uint32_t Codec_Stop(uint32_t CodecPdwnMode) -{ - uint32_t counter = 0; - - /* Mute the output first */ - Codec_Mute(AUDIO_MUTE_ON); - - if (CodecPdwnMode == CODEC_PDWN_SW) - { - /* Power down the DAC and the speaker (PMDAC and PMSPK bits)*/ - counter += Codec_WriteRegister(0x02, 0x9F); - } - else /* CODEC_PDWN_HW */ - { - /* Power down the DAC components */ - counter += Codec_WriteRegister(0x02, 0x9F); - - /* Wait at least 100us */ - Delay(0xFFF); - - /* Reset The pin */ - GPIO_WriteBit(AUDIO_RESET_GPIO, AUDIO_RESET_PIN, Bit_RESET); - } - - return counter; -} - -/** - * @brief Sets higher or lower the codec volume level. - * @param Volume: a byte value from 0 to 255 (refer to codec registers - * description for more details). - * @retval 0 if correct communication, else wrong communication - */ -static uint32_t Codec_VolumeCtrl(uint8_t Volume) -{ - uint32_t counter = 0; - - if (Volume > 0xE6) - { - /* Set the Master volume */ - counter += Codec_WriteRegister(0x20, Volume - 0xE7); - counter += Codec_WriteRegister(0x21, Volume - 0xE7); - } - else - { - /* Set the Master volume */ - counter += Codec_WriteRegister(0x20, Volume + 0x19); - counter += Codec_WriteRegister(0x21, Volume + 0x19); - } - - return counter; -} - -/** - * @brief Enables or disables the mute feature on the audio codec. - * @param Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the - * mute mode. - * @retval 0 if correct communication, else wrong communication - */ -static uint32_t Codec_Mute(uint32_t Cmd) -{ - uint32_t counter = 0; - - /* Set the Mute mode */ - if (Cmd == AUDIO_MUTE_ON) - { - counter += Codec_WriteRegister(0x04, 0xFF); - } - else /* AUDIO_MUTE_OFF Disable the Mute */ - { - counter += Codec_WriteRegister(0x04, OutputDev); - } - - return counter; -} - -/** - * @brief Resets the audio codec. It restores the default configuration of the - * codec (this function shall be called before initializing the codec). - * @note This function calls an external driver function: The IO Expander driver. - * @param None - * @retval None - */ -static void Codec_Reset(void) -{ - /* Power Down the codec */ - GPIO_WriteBit(AUDIO_RESET_GPIO, AUDIO_RESET_PIN, Bit_RESET); - - /* wait for a delay to insure registers erasing */ - Delay(CODEC_RESET_DELAY); - - /* Power on the codec */ - GPIO_WriteBit(AUDIO_RESET_GPIO, AUDIO_RESET_PIN, Bit_SET); -} - -/** - * @brief Writes a Byte to a given register into the audio codec through the - control interface (I2C) - * @param RegisterAddr: The address (location) of the register to be written. - * @param RegisterValue: the Byte value to be written into destination register. - * @retval 0 if correct communication, else wrong communication - */ -static uint32_t Codec_WriteRegister(uint8_t RegisterAddr, uint8_t RegisterValue) -{ - uint32_t result = 0; - - /*!< While the bus is busy */ - CODECTimeout = CODEC_LONG_TIMEOUT; - while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BUSY)) - { - if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); - } - - /* Start the config sequence */ - I2C_GenerateSTART(CODEC_I2C, ENABLE); - - /* Test on EV5 and clear it */ - CODECTimeout = CODEC_FLAG_TIMEOUT; - while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_MODE_SELECT)) - { - if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); - } - - /* Transmit the slave address and enable writing operation */ - I2C_Send7bitAddress(CODEC_I2C, CODEC_ADDRESS, I2C_Direction_Transmitter); - - /* Test on EV6 and clear it */ - CODECTimeout = CODEC_FLAG_TIMEOUT; - while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) - { - if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); - } - - /* Transmit the first address for write operation */ - I2C_SendData(CODEC_I2C, RegisterAddr); - - /* Test on EV8 and clear it */ - CODECTimeout = CODEC_FLAG_TIMEOUT; - while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTING)) - { - if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); - } - - /* Prepare the register value to be sent */ - I2C_SendData(CODEC_I2C, RegisterValue); - - /*!< Wait till all data have been physically transferred on the bus */ - CODECTimeout = CODEC_LONG_TIMEOUT; - while(!I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BTF)) - { - if((CODECTimeout--) == 0) Codec_TIMEOUT_UserCallback(); - } - - /* End the configuration sequence */ - I2C_GenerateSTOP(CODEC_I2C, ENABLE); - -#ifdef VERIFY_WRITTENDATA - /* Verify that the data has been correctly written */ - result = (Codec_ReadRegister(RegisterAddr) == RegisterValue)? 0:1; -#endif /* VERIFY_WRITTENDATA */ - - /* Return the verifying value: 0 (Passed) or 1 (Failed) */ - return result; -} - -/** - * @brief Reads and returns the value of an audio codec register through the - * control interface (I2C). - * @param RegisterAddr: Address of the register to be read. - * @retval Value of the register to be read or dummy value if the communication - * fails. - */ -static uint32_t Codec_ReadRegister(uint8_t RegisterAddr) -{ - uint32_t result = 0; - - /*!< While the bus is busy */ - CODECTimeout = CODEC_LONG_TIMEOUT; - while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BUSY)) - { - if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); - } - - /* Start the config sequence */ - I2C_GenerateSTART(CODEC_I2C, ENABLE); - - /* Test on EV5 and clear it */ - CODECTimeout = CODEC_FLAG_TIMEOUT; - while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_MODE_SELECT)) - { - if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); - } - - /* Transmit the slave address and enable writing operation */ - I2C_Send7bitAddress(CODEC_I2C, CODEC_ADDRESS, I2C_Direction_Transmitter); - - /* Test on EV6 and clear it */ - CODECTimeout = CODEC_FLAG_TIMEOUT; - while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) - { - if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); - } - - /* Transmit the register address to be read */ - I2C_SendData(CODEC_I2C, RegisterAddr); - - /* Test on EV8 and clear it */ - CODECTimeout = CODEC_FLAG_TIMEOUT; - while (I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BTF) == RESET) - { - if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); - } - - /*!< Send START condition a second time */ - I2C_GenerateSTART(CODEC_I2C, ENABLE); - - /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */ - CODECTimeout = CODEC_FLAG_TIMEOUT; - while(!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_MODE_SELECT)) - { - if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); - } - - /*!< Send Codec address for read */ - I2C_Send7bitAddress(CODEC_I2C, CODEC_ADDRESS, I2C_Direction_Receiver); - - /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */ - CODECTimeout = CODEC_FLAG_TIMEOUT; - while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_ADDR) == RESET) - { - if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); - } - - /*!< Disable Acknowledgment */ - I2C_AcknowledgeConfig(CODEC_I2C, DISABLE); - - /* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */ - (void)CODEC_I2C->SR2; - - /*!< Send STOP Condition */ - I2C_GenerateSTOP(CODEC_I2C, ENABLE); - - /* Wait for the byte to be received */ - CODECTimeout = CODEC_FLAG_TIMEOUT; - while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_RXNE) == RESET) - { - if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); - } - - /*!< Read the byte received from the Codec */ - result = I2C_ReceiveData(CODEC_I2C); - - /* Wait to make sure that STOP flag has been cleared */ - CODECTimeout = CODEC_FLAG_TIMEOUT; - while(CODEC_I2C->CR1 & I2C_CR1_STOP) - { - if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); - } - - /*!< Re-Enable Acknowledgment to be ready for another reception */ - I2C_AcknowledgeConfig(CODEC_I2C, ENABLE); - - /* Clear AF flag for next communication */ - I2C_ClearFlag(CODEC_I2C, I2C_FLAG_AF); - - /* Return the byte read from Codec */ - return result; -} - -/** - * @brief Initializes the Audio Codec control interface (I2C). - * @param None - * @retval None - */ -static void Codec_CtrlInterface_Init(void) -{ - I2C_InitTypeDef I2C_InitStructure; - - /* Enable the CODEC_I2C peripheral clock */ - RCC_APB1PeriphClockCmd(CODEC_I2C_CLK, ENABLE); - - /* CODEC_I2C peripheral configuration */ - I2C_DeInit(CODEC_I2C); - I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; - I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; - I2C_InitStructure.I2C_OwnAddress1 = 0x33; - I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; - I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; - I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED; - /* Enable the I2C peripheral */ - I2C_Cmd(CODEC_I2C, ENABLE); - I2C_Init(CODEC_I2C, &I2C_InitStructure); -} - -/** - * @brief Restore the Audio Codec control interface to its default state. - * This function doesn't de-initialize the I2C because the I2C peripheral - * may be used by other modules. - * @param None - * @retval None - */ -static void Codec_CtrlInterface_DeInit(void) -{ - /* Disable the I2C peripheral */ /* This step is not done here because - the I2C interface can be used by other modules */ - /* I2C_DeInit(CODEC_I2C); */ -} - -/** - * @brief Initializes the Audio Codec audio interface (I2S) - * @note This function assumes that the I2S input clock (through PLL_R in - * Devices RevA/Z and through dedicated PLLI2S_R in Devices RevB/Y) - * is already configured and ready to be used. - * @param AudioFreq: Audio frequency to be configured for the I2S peripheral. - * @retval None - */ -static void Codec_AudioInterface_Init(uint32_t AudioFreq) -{ - I2S_InitTypeDef I2S_InitStructure; - DAC_InitTypeDef DAC_InitStructure; - - /* Enable the CODEC_I2S peripheral clock */ - RCC_APB1PeriphClockCmd(CODEC_I2S_CLK, ENABLE); - - /* CODEC_I2S peripheral configuration */ - SPI_I2S_DeInit(CODEC_I2S); - I2S_InitStructure.I2S_AudioFreq = AudioFreq; - I2S_InitStructure.I2S_Standard = I2S_STANDARD; - I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b; - I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low; -#ifdef DAC_USE_I2S_DMA - if (CurrAudioInterface == AUDIO_INTERFACE_DAC) - { - I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx; - } - else - { -#else - I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx; -#endif -#ifdef DAC_USE_I2S_DMA - } -#endif /* DAC_USE_I2S_DMA */ -#ifdef CODEC_MCLK_ENABLED - I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable; -#elif defined(CODEC_MCLK_DISABLED) - I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable; -#else -#error "No selection for the MCLK output has been defined !" -#endif /* CODEC_MCLK_ENABLED */ - - /* Initialize the I2S peripheral with the structure above */ - I2S_Init(CODEC_I2S, &I2S_InitStructure); - - - /* Configure the DAC interface */ - if (CurrAudioInterface == AUDIO_INTERFACE_DAC) - { - /* DAC Periph clock enable */ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); - - /* DAC channel1 Configuration */ - DAC_InitStructure.DAC_Trigger = DAC_Trigger_None; - DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; - DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; - DAC_Init(AUDIO_DAC_CHANNEL, &DAC_InitStructure); - - /* Enable DAC Channel1 */ - DAC_Cmd(AUDIO_DAC_CHANNEL, ENABLE); - } - - /* The I2S peripheral will be enabled only in the EVAL_AUDIO_Play() function - or by user functions if DMA mode not enabled */ -} - -/** - * @brief Restores the Audio Codec audio interface to its default state. - * @param None - * @retval None - */ -static void Codec_AudioInterface_DeInit(void) -{ - /* Disable the CODEC_I2S peripheral (in case it hasn't already been disabled) */ - I2S_Cmd(CODEC_I2S, DISABLE); - - /* Deinitialize the CODEC_I2S peripheral */ - SPI_I2S_DeInit(CODEC_I2S); - - /* Disable the CODEC_I2S peripheral clock */ - RCC_APB1PeriphClockCmd(CODEC_I2S_CLK, DISABLE); -} - -/** - * @brief Initializes IOs used by the Audio Codec (on the control and audio - * interfaces). - * @param None - * @retval None - */ -static void Codec_GPIO_Init(void) -{ - GPIO_InitTypeDef GPIO_InitStructure; - - /* Enable Reset GPIO Clock */ - RCC_AHB1PeriphClockCmd(AUDIO_RESET_GPIO_CLK,ENABLE); - - /* Audio reset pin configuration -------------------------------------------------*/ - GPIO_InitStructure.GPIO_Pin = AUDIO_RESET_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(AUDIO_RESET_GPIO, &GPIO_InitStructure); - - /* Enable I2S and I2C GPIO clocks */ - RCC_AHB1PeriphClockCmd(CODEC_I2C_GPIO_CLOCK | CODEC_I2S_GPIO_CLOCK, ENABLE); - - /* CODEC_I2C SCL and SDA pins configuration -------------------------------------*/ - GPIO_InitStructure.GPIO_Pin = CODEC_I2C_SCL_PIN | CODEC_I2C_SDA_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(CODEC_I2C_GPIO, &GPIO_InitStructure); - /* Connect pins to I2C peripheral */ - GPIO_PinAFConfig(CODEC_I2C_GPIO, CODEC_I2S_SCL_PINSRC, CODEC_I2C_GPIO_AF); - GPIO_PinAFConfig(CODEC_I2C_GPIO, CODEC_I2S_SDA_PINSRC, CODEC_I2C_GPIO_AF); - - /* CODEC_I2S pins configuration: WS, SCK and SD pins -----------------------------*/ - GPIO_InitStructure.GPIO_Pin = CODEC_I2S_SCK_PIN | CODEC_I2S_SD_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(CODEC_I2S_GPIO, &GPIO_InitStructure); - - /* Connect pins to I2S peripheral */ - GPIO_PinAFConfig(CODEC_I2S_WS_GPIO, CODEC_I2S_WS_PINSRC, CODEC_I2S_GPIO_AF); - GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SCK_PINSRC, CODEC_I2S_GPIO_AF); - - if (CurrAudioInterface != AUDIO_INTERFACE_DAC) - { - GPIO_InitStructure.GPIO_Pin = CODEC_I2S_WS_PIN ; - GPIO_Init(CODEC_I2S_WS_GPIO, &GPIO_InitStructure); - GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SD_PINSRC, CODEC_I2S_GPIO_AF); - } - else - { - /* GPIOA clock enable (to be used with DAC) */ - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); - - /* DAC channel 1 & 2 (DAC_OUT1 = PA.4) configuration */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOA, &GPIO_InitStructure); - } - -#ifdef CODEC_MCLK_ENABLED - /* CODEC_I2S pins configuration: MCK pin */ - GPIO_InitStructure.GPIO_Pin = CODEC_I2S_MCK_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(CODEC_I2S_MCK_GPIO, &GPIO_InitStructure); - /* Connect pins to I2S peripheral */ - GPIO_PinAFConfig(CODEC_I2S_MCK_GPIO, CODEC_I2S_MCK_PINSRC, CODEC_I2S_GPIO_AF); -#endif /* CODEC_MCLK_ENABLED */ -} - -/** - * @brief Restores the IOs used by the Audio Codec interface to their default state. - * @param None - * @retval None - */ -static void Codec_GPIO_DeInit(void) -{ - GPIO_InitTypeDef GPIO_InitStructure; - - /* Deinitialize all the GPIOs used by the driver */ - GPIO_InitStructure.GPIO_Pin = CODEC_I2S_SCK_PIN | CODEC_I2S_SD_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(CODEC_I2S_GPIO, &GPIO_InitStructure); - - GPIO_InitStructure.GPIO_Pin = CODEC_I2S_WS_PIN ; - GPIO_Init(CODEC_I2S_WS_GPIO, &GPIO_InitStructure); - - /* Disconnect pins from I2S peripheral */ - GPIO_PinAFConfig(CODEC_I2S_WS_GPIO, CODEC_I2S_WS_PINSRC, 0x00); - GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SCK_PINSRC, 0x00); - GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SD_PINSRC, 0x00); - -#ifdef CODEC_MCLK_ENABLED - /* CODEC_I2S pins deinitialization: MCK pin */ - GPIO_InitStructure.GPIO_Pin = CODEC_I2S_MCK_PIN; - GPIO_Init(CODEC_I2S_MCK_GPIO, &GPIO_InitStructure); - /* Disconnect pins from I2S peripheral */ - GPIO_PinAFConfig(CODEC_I2S_MCK_GPIO, CODEC_I2S_MCK_PINSRC, CODEC_I2S_GPIO_AF); -#endif /* CODEC_MCLK_ENABLED */ -} - -/** - * @brief Inserts a delay time (not accurate timing). - * @param nCount: specifies the delay time length. - * @retval None - */ -static void Delay( __IO uint32_t nCount) -{ - for (; nCount != 0; nCount--); -} - -#ifdef USE_DEFAULT_TIMEOUT_CALLBACK -/** - * @brief Basic management of the timeout situation. - * @param None - * @retval None - */ -uint32_t Codec_TIMEOUT_UserCallback(void) -{ - /* Block communication and all processes */ - while (1) - { - } -} -#endif /* USE_DEFAULT_TIMEOUT_CALLBACK */ -/*======================== - - Audio MAL Interface Control Functions - - ==============================*/ - -/** - * @brief Initializes and prepares the Media to perform audio data transfer - * from Media to the I2S peripheral. - * @param None - * @retval None - */ -static void Audio_MAL_Init(void) -{ - -#ifdef I2S_INTERRUPT - NVIC_InitTypeDef NVIC_InitStructure; - - NVIC_InitStructure.NVIC_IRQChannel = SPI3_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelSubPriority =0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - - SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, ENABLE); - - I2S_Cmd(SPI3, ENABLE); -#else -#if defined(AUDIO_MAL_DMA_IT_TC_EN) || defined(AUDIO_MAL_DMA_IT_HT_EN) || defined(AUDIO_MAL_DMA_IT_TE_EN) - NVIC_InitTypeDef NVIC_InitStructure; -#endif - - if (CurrAudioInterface == AUDIO_INTERFACE_I2S) - { - /* Enable the DMA clock */ - RCC_AHB1PeriphClockCmd(AUDIO_MAL_DMA_CLOCK, ENABLE); - - /* Configure the DMA Stream */ - DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE); - DMA_DeInit(AUDIO_MAL_DMA_STREAM); - /* Set the parameters to be configured */ - DMA_InitStructure.DMA_Channel = AUDIO_MAL_DMA_CHANNEL; - DMA_InitStructure.DMA_PeripheralBaseAddr = AUDIO_MAL_DMA_DREG; - DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)0; /* This field will be configured in play function */ - DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; - DMA_InitStructure.DMA_BufferSize = (uint32_t)0xFFFE; /* This field will be configured in play function */ - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_InitStructure.DMA_PeripheralDataSize = AUDIO_MAL_DMA_PERIPH_DATA_SIZE; - DMA_InitStructure.DMA_MemoryDataSize = AUDIO_MAL_DMA_MEM_DATA_SIZE; -#ifdef AUDIO_MAL_MODE_NORMAL - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; -#elif defined(AUDIO_MAL_MODE_CIRCULAR) - DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; -#else -#error "AUDIO_MAL_MODE_NORMAL or AUDIO_MAL_MODE_CIRCULAR should be selected !!" -#endif /* AUDIO_MAL_MODE_NORMAL */ - DMA_InitStructure.DMA_Priority = DMA_Priority_High; - DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; - DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; - DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; - DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; - DMA_Init(AUDIO_MAL_DMA_STREAM, &DMA_InitStructure); - - /* Enable the selected DMA interrupts (selected in "stm32f4_discovery_eval_audio_codec.h" defines) */ -#ifdef AUDIO_MAL_DMA_IT_TC_EN - DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_TC, ENABLE); -#endif /* AUDIO_MAL_DMA_IT_TC_EN */ -#ifdef AUDIO_MAL_DMA_IT_HT_EN - DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_HT, ENABLE); -#endif /* AUDIO_MAL_DMA_IT_HT_EN */ -#ifdef AUDIO_MAL_DMA_IT_TE_EN - DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_TE | DMA_IT_FE | DMA_IT_DME, ENABLE); -#endif /* AUDIO_MAL_DMA_IT_TE_EN */ - -#if defined(AUDIO_MAL_DMA_IT_TC_EN) || defined(AUDIO_MAL_DMA_IT_HT_EN) || defined(AUDIO_MAL_DMA_IT_TE_EN) - /* I2S DMA IRQ Channel configuration */ - NVIC_InitStructure.NVIC_IRQChannel = AUDIO_MAL_DMA_IRQ; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = EVAL_AUDIO_IRQ_PREPRIO; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = EVAL_AUDIO_IRQ_SUBRIO; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); -#endif - } - -#ifdef DAC_USE_I2S_DMA - else - { - /* Enable the DMA clock */ - RCC_AHB1PeriphClockCmd(AUDIO_MAL_DMA_CLOCK, ENABLE); - - /* Configure the DMA Stream */ - DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE); - DMA_DeInit(AUDIO_MAL_DMA_STREAM); - /* Set the parameters to be configured */ - DMA_InitStructure.DMA_Channel = AUDIO_MAL_DMA_CHANNEL; - DMA_InitStructure.DMA_PeripheralBaseAddr = AUDIO_MAL_DMA_DREG; - DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)0; /* This field will be configured in play function */ - DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; - DMA_InitStructure.DMA_BufferSize = (uint32_t)0xFFFE; /* This field will be configured in play function */ - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_InitStructure.DMA_PeripheralDataSize = AUDIO_MAL_DMA_PERIPH_DATA_SIZE; - DMA_InitStructure.DMA_MemoryDataSize = AUDIO_MAL_DMA_MEM_DATA_SIZE; -#ifdef AUDIO_MAL_MODE_NORMAL - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; -#elif defined(AUDIO_MAL_MODE_CIRCULAR) - DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; -#else -#error "AUDIO_MAL_MODE_NORMAL or AUDIO_MAL_MODE_CIRCULAR should be selected !!" -#endif /* AUDIO_MAL_MODE_NORMAL */ - DMA_InitStructure.DMA_Priority = DMA_Priority_High; - DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; - DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; - DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; - DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; - DMA_Init(AUDIO_MAL_DMA_STREAM, &DMA_InitStructure); - - /* Enable the selected DMA interrupts (selected in "stm32f4_discovery_eval_audio_codec.h" defines) */ -#ifdef AUDIO_MAL_DMA_IT_TC_EN - DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_TC, ENABLE); -#endif /* AUDIO_MAL_DMA_IT_TC_EN */ -#ifdef AUDIO_MAL_DMA_IT_HT_EN - DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_HT, ENABLE); -#endif /* AUDIO_MAL_DMA_IT_HT_EN */ -#ifdef AUDIO_MAL_DMA_IT_TE_EN - DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_TE | DMA_IT_FE | DMA_IT_DME, ENABLE); -#endif /* AUDIO_MAL_DMA_IT_TE_EN */ - -#if defined(AUDIO_MAL_DMA_IT_TC_EN) || defined(AUDIO_MAL_DMA_IT_HT_EN) || defined(AUDIO_MAL_DMA_IT_TE_EN) - /* I2S DMA IRQ Channel configuration */ - NVIC_InitStructure.NVIC_IRQChannel = AUDIO_MAL_DMA_IRQ; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = EVAL_AUDIO_IRQ_PREPRIO; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = EVAL_AUDIO_IRQ_SUBRIO; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); -#endif - } -#endif /* DAC_USE_I2S_DMA */ - - if (CurrAudioInterface == AUDIO_INTERFACE_I2S) - { - /* Enable the I2S DMA request */ - SPI_I2S_DMACmd(CODEC_I2S, SPI_I2S_DMAReq_Tx, ENABLE); - } - else - { - /* Configure the STM32 DAC to geenrate audio analog signal */ - DAC_Config(); - -#ifndef DAC_USE_I2S_DMA - /* Enable the I2S interrupt used to write into the DAC register */ - SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, ENABLE); - - /* I2S DMA IRQ Channel configuration */ - NVIC_InitStructure.NVIC_IRQChannel = CODEC_I2S_IRQ; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = EVAL_AUDIO_IRQ_PREPRIO; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = EVAL_AUDIO_IRQ_SUBRIO; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); -#else - /* Enable the I2S DMA request */ - SPI_I2S_DMACmd(CODEC_I2S, SPI_I2S_DMAReq_Rx, ENABLE); -#endif /* DAC_USE_I2S_DMA */ - } -#endif -} - -/** - * @brief Restore default state of the used Media. - * @param None - * @retval None - */ -static void Audio_MAL_DeInit(void) -{ -#if defined(AUDIO_MAL_DMA_IT_TC_EN) || defined(AUDIO_MAL_DMA_IT_HT_EN) || defined(AUDIO_MAL_DMA_IT_TE_EN) - NVIC_InitTypeDef NVIC_InitStructure; - - /* Deinitialize the NVIC interrupt for the I2S DMA Stream */ - NVIC_InitStructure.NVIC_IRQChannel = AUDIO_MAL_DMA_IRQ; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = EVAL_AUDIO_IRQ_PREPRIO; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = EVAL_AUDIO_IRQ_SUBRIO; - NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; - NVIC_Init(&NVIC_InitStructure); -#endif - - /* Disable the DMA stream before the deinit */ - DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE); - - /* Dinitialize the DMA Stream */ - DMA_DeInit(AUDIO_MAL_DMA_STREAM); - - /* - The DMA clock is not disabled, since it can be used by other streams - */ -} - -/** - * @brief Starts playing audio stream from the audio Media. - * @param None - * @retval None - */ -static void Audio_MAL_Play(uint32_t Addr, uint32_t Size) -{ - if (CurrAudioInterface == AUDIO_INTERFACE_I2S) - { - /* Configure the buffer address and size */ - DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Addr; - DMA_InitStructure.DMA_BufferSize = (uint32_t)Size; - - /* Configure the DMA Stream with the new parameters */ - DMA_Init(AUDIO_MAL_DMA_STREAM, &DMA_InitStructure); - - /* Enable the I2S DMA Stream*/ - DMA_Cmd(AUDIO_MAL_DMA_STREAM, ENABLE); - } -#ifndef DAC_USE_I2S_DMA - else - { - /* Configure the buffer address and size */ - DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Addr; - DMA_InitStructure.DMA_BufferSize = (uint32_t)Size; - - /* Configure the DMA Stream with the new parameters */ - DMA_Init(AUDIO_MAL_DMA_STREAM, &DMA_InitStructure); - - /* Enable the I2S DMA Stream*/ - DMA_Cmd(AUDIO_MAL_DMA_STREAM, ENABLE); - } -#endif /* DAC_USE_I2S_DMA */ - - /* If the I2S peripheral is still not enabled, enable it */ - if ((CODEC_I2S->I2SCFGR & I2S_ENABLE_MASK) == 0) - { - I2S_Cmd(CODEC_I2S, ENABLE); - } -} - -/** - * @brief Pauses or Resumes the audio stream playing from the Media. - * @param Cmd: AUDIO_PAUSE (or 0) to pause, AUDIO_RESUME (or any value different - * from 0) to resume. - * @param Addr: Address from/at which the audio stream should resume/pause. - * @retval None - */ -static void Audio_MAL_PauseResume(uint32_t Cmd, uint32_t Addr) -{ - /* Pause the audio file playing */ - if (Cmd == AUDIO_PAUSE) - { - /* Disable the I2S DMA request */ - SPI_I2S_DMACmd(CODEC_I2S, SPI_I2S_DMAReq_Tx, DISABLE); - - /* Pause the I2S DMA Stream - Note. For the STM32F4xx devices, the DMA implements a pause feature, - by disabling the stream, all configuration is preserved and data - transfer is paused till the next enable of the stream. - This feature is not available on STM32F4xx devices. */ - DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE); - } - else /* AUDIO_RESUME */ - { - /* Enable the I2S DMA request */ - SPI_I2S_DMACmd(CODEC_I2S, SPI_I2S_DMAReq_Tx, ENABLE); - - /* Resume the I2S DMA Stream - Note. For the STM32F4xx devices, the DMA implements a pause feature, - by disabling the stream, all configuration is preserved and data - transfer is paused till the next enable of the stream. - This feature is not available on STM32F4xx devices. */ - DMA_Cmd(AUDIO_MAL_DMA_STREAM, ENABLE); - - /* If the I2S peripheral is still not enabled, enable it */ - if ((CODEC_I2S->I2SCFGR & I2S_ENABLE_MASK) == 0) - { - I2S_Cmd(CODEC_I2S, ENABLE); - } - } -} - -/** - * @brief Stops audio stream playing on the used Media. - * @param None - * @retval None - */ -static void Audio_MAL_Stop(void) -{ - /* Stop the Transfer on the I2S side: Stop and disable the DMA stream */ - DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE); - - /* Clear all the DMA flags for the next transfer */ - DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC |AUDIO_MAL_DMA_FLAG_HT | \ - AUDIO_MAL_DMA_FLAG_FE | AUDIO_MAL_DMA_FLAG_TE); - - /* - The I2S DMA requests are not disabled here. - */ - - /* In all modes, disable the I2S peripheral */ - I2S_Cmd(CODEC_I2S, DISABLE); -} - -/** - * @brief DAC Channel1 Configuration - * @param None - * @retval None - */ -void DAC_Config(void) -{ - DAC_InitTypeDef DAC_InitStructure; - GPIO_InitTypeDef GPIO_InitStructure; - - /* DMA1 clock and GPIOA clock enable (to be used with DAC) */ - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 | RCC_AHB1Periph_GPIOA, ENABLE); - - /* DAC Periph clock enable */ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); - - /* DAC channel 1 & 2 (DAC_OUT1 = PA.4) configuration */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* DAC channel1 Configuration */ - DAC_InitStructure.DAC_Trigger = DAC_Trigger_None; - DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; - DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; - DAC_Init(AUDIO_DAC_CHANNEL, &DAC_InitStructure); - - /* Enable DAC Channel1 */ - DAC_Cmd(AUDIO_DAC_CHANNEL, ENABLE); -} -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_audio_codec.h b/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_audio_codec.h deleted file mode 100644 index 33ba0e77d..000000000 --- a/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_audio_codec.h +++ /dev/null @@ -1,304 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4_discovery_audio_codec.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file contains all the functions prototypes for the - * stm32f4_discovery_audio_codec.c driver. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4_DISCOVERY_AUDIOCODEC_H -#define __STM32F4_DISCOVERY_AUDIOCODEC_H - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" -#include "stm32f4xx_gpio.h" - -/** @addtogroup Utilities - * @{ - */ - - -/** @addtogroup STM32F4_DISCOVERY - * @{ - */ - -/** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC - * @{ - */ - - -/** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Exported_Types - * @{ - */ - -/** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Exported_Constants - * @{ - */ - -/*------------------------------------ - CONFIGURATION: Audio Codec Driver Configuration parameters - ----------------------------------------*/ -#define I2S_INTERRUPT -/* Audio Transfer mode (DMA, Interrupt or Polling) */ -#define AUDIO_MAL_MODE_NORMAL /* Uncomment this line to enable the audio - Transfer using DMA */ -/* #define AUDIO_MAL_MODE_CIRCULAR */ /* Uncomment this line to enable the audio - Transfer using DMA */ - -/* For the DMA modes select the interrupt that will be used */ -#define AUDIO_MAL_DMA_IT_TC_EN /* Uncomment this line to enable DMA Transfer Complete interrupt */ -/* #define AUDIO_MAL_DMA_IT_HT_EN */ /* Uncomment this line to enable DMA Half Transfer Complete interrupt */ -/* #define AUDIO_MAL_DMA_IT_TE_EN */ /* Uncomment this line to enable DMA Transfer Error interrupt */ - -/* Select the interrupt preemption priority and subpriority for the DMA interrupt */ -#define EVAL_AUDIO_IRQ_PREPRIO 0 /* Select the preemption priority level(0 is the highest) */ -#define EVAL_AUDIO_IRQ_SUBRIO 0 /* Select the sub-priority level (0 is the highest) */ - -/* Uncomment the following line to use the default Codec_TIMEOUT_UserCallback() - function implemented in stm32f4_discovery_audio_codec.c file. - Codec_TIMEOUT_UserCallback() function is called whenever a timeout condition - occurs during communication (waiting on an event that doesn't occur, bus - errors, busy devices ...). */ -/* #define USE_DEFAULT_TIMEOUT_CALLBACK */ - -/* Enable this define to use the I2S DMA for writing into DAC register */ -//#define DAC_USE_I2S_DMA -/*----------------------------------------------------------------------------*/ - -/*------------------------------------ - OPTIONAL Configuration defines parameters - ----------------------------------------*/ -/* I2C clock speed configuration (in Hz) - WARNING: - Make sure that this define is not already declared in other files (ie. - stm322xg_eval.h file). It can be used in parallel by other modules. */ -#ifndef I2C_SPEED - #define I2C_SPEED 100000 -#endif /* I2C_SPEED */ - -/* Uncomment defines below to select standard for audio communication between - Codec and I2S peripheral */ -#define I2S_STANDARD_PHILLIPS -/* #define I2S_STANDARD_MSB */ -/* #define I2S_STANDARD_LSB */ - -/* Uncomment the defines below to select if the Master clock mode should be - enabled or not */ -#define CODEC_MCLK_ENABLED -/* #deine CODEC_MCLK_DISABLED */ - -/* Uncomment this line to enable verifying data sent to codec after each write - operation */ -#define VERIFY_WRITTENDATA -/*----------------------------------------------------------------------------*/ - -/*----------------------------------- - Hardware Configuration defines parameters - -----------------------------------------*/ -/* Audio Reset Pin definition */ -#define AUDIO_RESET_GPIO_CLK RCC_AHB1Periph_GPIOD -#define AUDIO_RESET_PIN GPIO_Pin_4 -#define AUDIO_RESET_GPIO GPIOD - -/* I2S peripheral configuration defines */ -#define CODEC_I2S SPI3 -#define CODEC_I2S_CLK RCC_APB1Periph_SPI3 -#define CODEC_I2S_ADDRESS 0x40003C0C -#define CODEC_I2S_GPIO_AF GPIO_AF_SPI3 -#define CODEC_I2S_IRQ SPI3_IRQn -#define CODEC_I2S_GPIO_CLOCK (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOA) -#define CODEC_I2S_WS_PIN GPIO_Pin_4 -#define CODEC_I2S_SCK_PIN GPIO_Pin_10 -#define CODEC_I2S_SD_PIN GPIO_Pin_12 -#define CODEC_I2S_MCK_PIN GPIO_Pin_7 -#define CODEC_I2S_WS_PINSRC GPIO_PinSource4 -#define CODEC_I2S_SCK_PINSRC GPIO_PinSource10 -#define CODEC_I2S_SD_PINSRC GPIO_PinSource12 -#define CODEC_I2S_MCK_PINSRC GPIO_PinSource7 -#define CODEC_I2S_GPIO GPIOC -#define CODEC_I2S_WS_GPIO GPIOA -#define CODEC_I2S_MCK_GPIO GPIOC -#define Audio_I2S_IRQHandler SPI3_IRQHandler - - - #define AUDIO_MAL_DMA_PERIPH_DATA_SIZE DMA_PeripheralDataSize_HalfWord - #define AUDIO_MAL_DMA_MEM_DATA_SIZE DMA_MemoryDataSize_HalfWord - #define DMA_MAX_SZE 0xFFFF - - - #define DAC_DHR12L1_ADDRESS 0x4000740C - #define DAC_DHR12R1_ADDRESS 0x40007408 - #define DAC_DHR8R1_ADDRESS 0x40007410 - #define AUDIO_DAC_CHANNEL DAC_Channel_1 - - /* I2S DMA Stream definitions */ - #define AUDIO_I2S_DMA_CLOCK RCC_AHB1Periph_DMA1 - #define AUDIO_I2S_DMA_STREAM DMA1_Stream7 - #define AUDIO_I2S_DMA_DREG CODEC_I2S_ADDRESS - #define AUDIO_I2S_DMA_CHANNEL DMA_Channel_0 - #define AUDIO_I2S_DMA_IRQ DMA1_Stream7_IRQn - #define AUDIO_I2S_DMA_FLAG_TC DMA_FLAG_TCIF7 - #define AUDIO_I2S_DMA_FLAG_HT DMA_FLAG_HTIF7 - #define AUDIO_I2S_DMA_FLAG_FE DMA_FLAG_FEIF7 - #define AUDIO_I2S_DMA_FLAG_TE DMA_FLAG_TEIF7 - #define AUDIO_I2S_DMA_FLAG_DME DMA_FLAG_DMEIF7 - - #define Audio_MAL_I2S_IRQHandler DMA1_Stream7_IRQHandler - - - /* DAC DMA Stream definitions */ - #define AUDIO_DAC_DMA_CLOCK RCC_AHB1Periph_DMA1 - #define AUDIO_DAC_DMA_STREAM DMA1_Stream0 - #define AUDIO_DAC_DMA_DREG DAC_DHR12L1_ADDRESS - #define AUDIO_DAC_DMA_CHANNEL DMA_Channel_0 - #define AUDIO_DAC_DMA_IRQ DMA1_Stream0_IRQn - #define AUDIO_DAC_DMA_FLAG_TC DMA_FLAG_TCIF0 - #define AUDIO_DAC_DMA_FLAG_HT DMA_FLAG_HTIF0 - #define AUDIO_DAC_DMA_FLAG_FE DMA_FLAG_FEIF0 - #define AUDIO_DAC_DMA_FLAG_TE DMA_FLAG_TEIF0 - #define AUDIO_DAC_DMA_FLAG_DME DMA_FLAG_DMEIF0 - - #define Audio_MAL_DAC_IRQHandler DMA1_Stream0_IRQHandler - - -/* I2C peripheral configuration defines (control interface of the audio codec) */ -#define CODEC_I2C I2C1 -#define CODEC_I2C_CLK RCC_APB1Periph_I2C1 -#define CODEC_I2C_GPIO_CLOCK RCC_AHB1Periph_GPIOB -#define CODEC_I2C_GPIO_AF GPIO_AF_I2C1 -#define CODEC_I2C_GPIO GPIOB -#define CODEC_I2C_SCL_PIN GPIO_Pin_6 -#define CODEC_I2C_SDA_PIN GPIO_Pin_9 -#define CODEC_I2S_SCL_PINSRC GPIO_PinSource6 -#define CODEC_I2S_SDA_PINSRC GPIO_PinSource9 - -/* Maximum Timeout values for flags and events waiting loops. These timeouts are - not based on accurate values, they just guarantee that the application will - not remain stuck if the I2C communication is corrupted. - You may modify these timeout values depending on CPU frequency and application - conditions (interrupts routines ...). */ -#define CODEC_FLAG_TIMEOUT ((uint32_t)0x1000) -#define CODEC_LONG_TIMEOUT ((uint32_t)(300 * CODEC_FLAG_TIMEOUT)) -/*----------------------------------------------------------------------------*/ - -/*----------------------------------- - Audio Codec User defines - -----------------------------------------*/ -/* Audio interface : I2S or DAC */ -#define AUDIO_INTERFACE_I2S 1 -#define AUDIO_INTERFACE_DAC 2 - -/* Codec output DEVICE */ -#define OUTPUT_DEVICE_SPEAKER 1 -#define OUTPUT_DEVICE_HEADPHONE 2 -#define OUTPUT_DEVICE_BOTH 3 -#define OUTPUT_DEVICE_AUTO 4 - -/* Volume Levels values */ -#define DEFAULT_VOLMIN 0x00 -#define DEFAULT_VOLMAX 0xFF -#define DEFAULT_VOLSTEP 0x04 - -#define AUDIO_PAUSE 0 -#define AUDIO_RESUME 1 - -/* Codec POWER DOWN modes */ -#define CODEC_PDWN_HW 1 -#define CODEC_PDWN_SW 2 - -/* MUTE commands */ -#define AUDIO_MUTE_ON 1 -#define AUDIO_MUTE_OFF 0 -/*----------------------------------------------------------------------------*/ -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Exported_Macros - * @{ - */ -#define VOLUME_CONVERT(x) ((Volume > 100)? 100:((uint8_t)((Volume * 255) / 100))) -#define DMA_MAX(x) (((x) <= DMA_MAX_SZE)? (x):DMA_MAX_SZE) - -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Exported_Functions - * @{ - */ -void EVAL_AUDIO_SetAudioInterface(uint32_t Interface); -uint32_t EVAL_AUDIO_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq); -uint32_t EVAL_AUDIO_DeInit(void); -uint32_t EVAL_AUDIO_Play(uint16_t* pBuffer, uint32_t Size); -uint32_t EVAL_AUDIO_PauseResume(uint32_t Cmd); -uint32_t EVAL_AUDIO_Stop(uint32_t CodecPowerDown_Mode); -uint32_t EVAL_AUDIO_VolumeCtl(uint8_t Volume); -uint32_t EVAL_AUDIO_Mute(uint32_t Command); -void DAC_Config(void); - -/* User Callbacks: user has to implement these functions in his code if - they are needed. -----------------------------------------------------------*/ - -uint16_t EVAL_AUDIO_GetSampleCallBack(void); - -/* This function is called when the requested data has been completely transferred. - In Normal mode (when the define AUDIO_MAL_MODE_NORMAL is enabled) this function - is called at the end of the whole audio file. - In circular mode (when the define AUDIO_MAL_MODE_CIRCULAR is enabled) this - function is called at the end of the current buffer transmission. */ -void EVAL_AUDIO_TransferComplete_CallBack(uint32_t pBuffer, uint32_t Size); - -/* This function is called when half of the requested buffer has been transferred - This callback is useful in Circular mode only (when AUDIO_MAL_MODE_CIRCULAR - define is enabled)*/ -void EVAL_AUDIO_HalfTransfer_CallBack(uint32_t pBuffer, uint32_t Size); - -/* This function is called when an Interrupt due to transfer error on or peripheral - error occurs. */ -void EVAL_AUDIO_Error_CallBack(void* pData); - -/* Codec_TIMEOUT_UserCallback() function is called whenever a timeout condition - occurs during communication (waiting on an event that doesn't occur, bus - errors, busy devices ...) on the Codec control interface (I2C). - You can use the default timeout callback implementation by uncommenting the - define USE_DEFAULT_TIMEOUT_CALLBACK in stm32f4_discovery_audio_codec.h file. - Typically the user implementation of this callback should reset I2C peripheral - and re-initialize communication or in worst case reset all the application. */ -uint32_t Codec_TIMEOUT_UserCallback(void); - -#endif /* __STM32F4_DISCOVERY_AUDIOCODEC_H */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_lis302dl.c b/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_lis302dl.c deleted file mode 100644 index d354dc453..000000000 --- a/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_lis302dl.c +++ /dev/null @@ -1,504 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4_discovery_lis302dl.c - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file provides a set of functions needed to manage the LIS302DL - * MEMS accelerometer available on STM32F4-Discovery Kit. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4_discovery_lis302dl.h" -//ADDED BY ME!!!!!!!!!!!!!!!!!!!! -#include "stm32f4xx_conf.h" - -/** @addtogroup Utilities - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY_LIS302DL - * @{ - */ - - -/** @defgroup STM32F4_DISCOVERY_LIS302DL_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LIS302DL_Private_Defines - * @{ - */ -__IO uint32_t LIS302DLTimeout = LIS302DL_FLAG_TIMEOUT; - -/* Read/Write command */ -#define READWRITE_CMD ((uint8_t)0x80) -/* Multiple byte read/write command */ -#define MULTIPLEBYTE_CMD ((uint8_t)0x40) -/* Dummy Byte Send by the SPI Master device in order to generate the Clock to the Slave device */ -#define DUMMY_BYTE ((uint8_t)0x00) - -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LIS302DL_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LIS302DL_Private_Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LIS302DL_Private_FunctionPrototypes - * @{ - */ -static uint8_t LIS302DL_SendByte(uint8_t byte); -static void LIS302DL_LowLevel_Init(void); -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LIS302DL_Private_Functions - * @{ - */ - - -/** - * @brief Set LIS302DL Initialization. - * @param LIS302DL_Config_Struct: pointer to a LIS302DL_Config_TypeDef structure - * that contains the configuration setting for the LIS302DL. - * @retval None - */ -void LIS302DL_Init(LIS302DL_InitTypeDef *LIS302DL_InitStruct) -{ - uint8_t ctrl = 0x00; - - /* Configure the low level interface ---------------------------------------*/ - LIS302DL_LowLevel_Init(); - - /* Configure MEMS: data rate, power mode, full scale, self test and axes */ - ctrl = (uint8_t) (LIS302DL_InitStruct->Output_DataRate | LIS302DL_InitStruct->Power_Mode | \ - LIS302DL_InitStruct->Full_Scale | LIS302DL_InitStruct->Self_Test | \ - LIS302DL_InitStruct->Axes_Enable); - - /* Write value to MEMS CTRL_REG1 regsister */ - LIS302DL_Write(&ctrl, LIS302DL_CTRL_REG1_ADDR, 1); -} - -/** - * @brief Set LIS302DL Internal High Pass Filter configuration. - * @param LIS302DL_Filter_ConfigTypeDef: pointer to a LIS302DL_FilterConfig_TypeDef - * structure that contains the configuration setting for the LIS302DL Filter. - * @retval None - */ -void LIS302DL_FilterConfig(LIS302DL_FilterConfigTypeDef *LIS302DL_FilterConfigStruct) -{ - uint8_t ctrl = 0x00; - - /* Read CTRL_REG2 register */ - LIS302DL_Read(&ctrl, LIS302DL_CTRL_REG2_ADDR, 1); - - /* Clear high pass filter cut-off level, interrupt and data selection bits*/ - ctrl &= (uint8_t)~(LIS302DL_FILTEREDDATASELECTION_OUTPUTREGISTER | \ - LIS302DL_HIGHPASSFILTER_LEVEL_3 | \ - LIS302DL_HIGHPASSFILTERINTERRUPT_1_2); - /* Configure MEMS high pass filter cut-off level, interrupt and data selection bits */ - ctrl |= (uint8_t)(LIS302DL_FilterConfigStruct->HighPassFilter_Data_Selection | \ - LIS302DL_FilterConfigStruct->HighPassFilter_CutOff_Frequency | \ - LIS302DL_FilterConfigStruct->HighPassFilter_Interrupt); - - /* Write value to MEMS CTRL_REG2 register */ - LIS302DL_Write(&ctrl, LIS302DL_CTRL_REG2_ADDR, 1); -} - -/** - * @brief Set LIS302DL Interrupt configuration - * @param LIS302DL_InterruptConfig_TypeDef: pointer to a LIS302DL_InterruptConfig_TypeDef - * structure that contains the configuration setting for the LIS302DL Interrupt. - * @retval None - */ -void LIS302DL_InterruptConfig(LIS302DL_InterruptConfigTypeDef *LIS302DL_IntConfigStruct) -{ - uint8_t ctrl = 0x00; - - /* Read CLICK_CFG register */ - LIS302DL_Read(&ctrl, LIS302DL_CLICK_CFG_REG_ADDR, 1); - - /* Configure latch Interrupt request, click interrupts and double click interrupts */ - ctrl = (uint8_t)(LIS302DL_IntConfigStruct->Latch_Request| \ - LIS302DL_IntConfigStruct->SingleClick_Axes | \ - LIS302DL_IntConfigStruct->DoubleClick_Axes); - - /* Write value to MEMS CLICK_CFG register */ - LIS302DL_Write(&ctrl, LIS302DL_CLICK_CFG_REG_ADDR, 1); -} - -/** - * @brief Change the lowpower mode for LIS302DL - * @param LowPowerMode: new state for the lowpower mode. - * This parameter can be one of the following values: - * @arg LIS302DL_LOWPOWERMODE_POWERDOWN: Power down mode - * @arg LIS302DL_LOWPOWERMODE_ACTIVE: Active mode - * @retval None - */ -void LIS302DL_LowpowerCmd(uint8_t LowPowerMode) -{ - uint8_t tmpreg; - - /* Read CTRL_REG1 register */ - LIS302DL_Read(&tmpreg, LIS302DL_CTRL_REG1_ADDR, 1); - - /* Set new low power mode configuration */ - tmpreg &= (uint8_t)~LIS302DL_LOWPOWERMODE_ACTIVE; - tmpreg |= LowPowerMode; - - /* Write value to MEMS CTRL_REG1 regsister */ - LIS302DL_Write(&tmpreg, LIS302DL_CTRL_REG1_ADDR, 1); -} - -/** - * @brief Data Rate command - * @param DataRateValue: Data rate value - * This parameter can be one of the following values: - * @arg LIS302DL_DATARATE_100: 100 Hz output data rate - * @arg LIS302DL_DATARATE_400: 400 Hz output data rate - * @retval None - */ -void LIS302DL_DataRateCmd(uint8_t DataRateValue) -{ - uint8_t tmpreg; - - /* Read CTRL_REG1 register */ - LIS302DL_Read(&tmpreg, LIS302DL_CTRL_REG1_ADDR, 1); - - /* Set new Data rate configuration */ - tmpreg &= (uint8_t)~LIS302DL_DATARATE_400; - tmpreg |= DataRateValue; - - /* Write value to MEMS CTRL_REG1 regsister */ - LIS302DL_Write(&tmpreg, LIS302DL_CTRL_REG1_ADDR, 1); -} - -/** - * @brief Change the Full Scale of LIS302DL - * @param FS_value: new full scale value. - * This parameter can be one of the following values: - * @arg LIS302DL_FULLSCALE_2_3: +-2.3g - * @arg LIS302DL_FULLSCALE_9_2: +-9.2g - * @retval None - */ -void LIS302DL_FullScaleCmd(uint8_t FS_value) -{ - uint8_t tmpreg; - - /* Read CTRL_REG1 register */ - LIS302DL_Read(&tmpreg, LIS302DL_CTRL_REG1_ADDR, 1); - - /* Set new full scale configuration */ - tmpreg &= (uint8_t)~LIS302DL_FULLSCALE_9_2; - tmpreg |= FS_value; - - /* Write value to MEMS CTRL_REG1 regsister */ - LIS302DL_Write(&tmpreg, LIS302DL_CTRL_REG1_ADDR, 1); -} - -/** - * @brief Reboot memory content of LIS302DL - * @param None - * @retval None - */ -void LIS302DL_RebootCmd(void) -{ - uint8_t tmpreg; - /* Read CTRL_REG2 register */ - LIS302DL_Read(&tmpreg, LIS302DL_CTRL_REG2_ADDR, 1); - - /* Enable or Disable the reboot memory */ - tmpreg |= LIS302DL_BOOT_REBOOTMEMORY; - - /* Write value to MEMS CTRL_REG2 regsister */ - LIS302DL_Write(&tmpreg, LIS302DL_CTRL_REG2_ADDR, 1); -} - -/** - * @brief Writes one byte to the LIS302DL. - * @param pBuffer : pointer to the buffer containing the data to be written to the LIS302DL. - * @param WriteAddr : LIS302DL's internal address to write to. - * @param NumByteToWrite: Number of bytes to write. - * @retval None - */ -void LIS302DL_Write(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite) -{ - /* Configure the MS bit: - - When 0, the address will remain unchanged in multiple read/write commands. - - When 1, the address will be auto incremented in multiple read/write commands. - */ - if(NumByteToWrite > 0x01) - { - WriteAddr |= (uint8_t)MULTIPLEBYTE_CMD; - } - /* Set chip select Low at the start of the transmission */ - LIS302DL_CS_LOW(); - - /* Send the Address of the indexed register */ - LIS302DL_SendByte(WriteAddr); - /* Send the data that will be written into the device (MSB First) */ - while(NumByteToWrite >= 0x01) - { - LIS302DL_SendByte(*pBuffer); - NumByteToWrite--; - pBuffer++; - } - - /* Set chip select High at the end of the transmission */ - LIS302DL_CS_HIGH(); -} - -/** - * @brief Reads a block of data from the LIS302DL. - * @param pBuffer : pointer to the buffer that receives the data read from the LIS302DL. - * @param ReadAddr : LIS302DL's internal address to read from. - * @param NumByteToRead : number of bytes to read from the LIS302DL. - * @retval None - */ -void LIS302DL_Read(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead) -{ - if(NumByteToRead > 0x01) - { - ReadAddr |= (uint8_t)(READWRITE_CMD | MULTIPLEBYTE_CMD); - } - else - { - ReadAddr |= (uint8_t)READWRITE_CMD; - } - /* Set chip select Low at the start of the transmission */ - LIS302DL_CS_LOW(); - - /* Send the Address of the indexed register */ - LIS302DL_SendByte(ReadAddr); - - /* Receive the data that will be read from the device (MSB First) */ - while(NumByteToRead > 0x00) - { - /* Send dummy byte (0x00) to generate the SPI clock to LIS302DL (Slave device) */ - *pBuffer = LIS302DL_SendByte(DUMMY_BYTE); - NumByteToRead--; - pBuffer++; - } - - /* Set chip select High at the end of the transmission */ - LIS302DL_CS_HIGH(); -} - -/** - * @brief Read LIS302DL output register, and calculate the acceleration - * ACC[mg]=SENSITIVITY* (out_h*256+out_l)/16 (12 bit rappresentation) - * @param s16 buffer to store data - * @retval None - */ -void LIS302DL_ReadACC(int32_t* out) -{ - uint8_t buffer[6]; - uint8_t crtl, i = 0x00; - - LIS302DL_Read(&crtl, LIS302DL_CTRL_REG1_ADDR, 1); - LIS302DL_Read(buffer, LIS302DL_OUT_X_ADDR, 6); - - switch(crtl & 0x20) - { - /* FS bit = 0 ==> Sensitivity typical value = 18milligals/digit*/ - case 0x00: - for(i=0; i<0x03; i++) - { - *out =(int32_t)(LIS302DL_SENSITIVITY_2_3G * (int8_t)buffer[2*i]); - out++; - } - break; - /* FS bit = 1 ==> Sensitivity typical value = 72milligals/digit*/ - case 0x20: - for(i=0; i<0x03; i++) - { - *out =(int32_t)(LIS302DL_SENSITIVITY_9_2G * (int8_t)buffer[2*i]); - out++; - } - break; - default: - break; - } - } - -/** - * @brief Initializes the low level interface used to drive the LIS302DL - * @param None - * @retval None - */ -static void LIS302DL_LowLevel_Init(void) -{ - GPIO_InitTypeDef GPIO_InitStructure; - SPI_InitTypeDef SPI_InitStructure; - - /* Enable the SPI periph */ - RCC_APB2PeriphClockCmd(LIS302DL_SPI_CLK, ENABLE); - - /* Enable SCK, MOSI and MISO GPIO clocks */ - RCC_AHB1PeriphClockCmd(LIS302DL_SPI_SCK_GPIO_CLK | LIS302DL_SPI_MISO_GPIO_CLK | LIS302DL_SPI_MOSI_GPIO_CLK, ENABLE); - - /* Enable CS GPIO clock */ - RCC_AHB1PeriphClockCmd(LIS302DL_SPI_CS_GPIO_CLK, ENABLE); - - /* Enable INT1 GPIO clock */ - RCC_AHB1PeriphClockCmd(LIS302DL_SPI_INT1_GPIO_CLK, ENABLE); - - /* Enable INT2 GPIO clock */ - RCC_AHB1PeriphClockCmd(LIS302DL_SPI_INT2_GPIO_CLK, ENABLE); - - GPIO_PinAFConfig(LIS302DL_SPI_SCK_GPIO_PORT, LIS302DL_SPI_SCK_SOURCE, LIS302DL_SPI_SCK_AF); - GPIO_PinAFConfig(LIS302DL_SPI_MISO_GPIO_PORT, LIS302DL_SPI_MISO_SOURCE, LIS302DL_SPI_MISO_AF); - GPIO_PinAFConfig(LIS302DL_SPI_MOSI_GPIO_PORT, LIS302DL_SPI_MOSI_SOURCE, LIS302DL_SPI_MOSI_AF); - - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - - /* SPI SCK pin configuration */ - GPIO_InitStructure.GPIO_Pin = LIS302DL_SPI_SCK_PIN; - GPIO_Init(LIS302DL_SPI_SCK_GPIO_PORT, &GPIO_InitStructure); - - /* SPI MOSI pin configuration */ - GPIO_InitStructure.GPIO_Pin = LIS302DL_SPI_MOSI_PIN; - GPIO_Init(LIS302DL_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure); - - /* SPI MISO pin configuration */ - GPIO_InitStructure.GPIO_Pin = LIS302DL_SPI_MISO_PIN; - GPIO_Init(LIS302DL_SPI_MISO_GPIO_PORT, &GPIO_InitStructure); - - /* SPI configuration -------------------------------------------------------*/ - SPI_I2S_DeInit(LIS302DL_SPI); - SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; - SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; - SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; - SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; - SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; - SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; - SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; - SPI_InitStructure.SPI_CRCPolynomial = 7; - SPI_InitStructure.SPI_Mode = SPI_Mode_Master; - SPI_Init(LIS302DL_SPI, &SPI_InitStructure); - - /* Enable SPI1 */ - SPI_Cmd(LIS302DL_SPI, ENABLE); - - /* Configure GPIO PIN for Lis Chip select */ - GPIO_InitStructure.GPIO_Pin = LIS302DL_SPI_CS_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(LIS302DL_SPI_CS_GPIO_PORT, &GPIO_InitStructure); - - /* Deselect : Chip Select high */ - GPIO_SetBits(LIS302DL_SPI_CS_GPIO_PORT, LIS302DL_SPI_CS_PIN); - - /* Configure GPIO PINs to detect Interrupts */ - GPIO_InitStructure.GPIO_Pin = LIS302DL_SPI_INT1_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(LIS302DL_SPI_INT1_GPIO_PORT, &GPIO_InitStructure); - - GPIO_InitStructure.GPIO_Pin = LIS302DL_SPI_INT2_PIN; - GPIO_Init(LIS302DL_SPI_INT2_GPIO_PORT, &GPIO_InitStructure); -} - -/** - * @brief Sends a Byte through the SPI interface and return the Byte received - * from the SPI bus. - * @param Byte : Byte send. - * @retval The received byte value - */ -static uint8_t LIS302DL_SendByte(uint8_t byte) -{ - /* Loop while DR register in not emplty */ - LIS302DLTimeout = LIS302DL_FLAG_TIMEOUT; - while (SPI_I2S_GetFlagStatus(LIS302DL_SPI, SPI_I2S_FLAG_TXE) == RESET) - { - if((LIS302DLTimeout--) == 0) return LIS302DL_TIMEOUT_UserCallback(); - } - - /* Send a Byte through the SPI peripheral */ - SPI_I2S_SendData(LIS302DL_SPI, byte); - - /* Wait to receive a Byte */ - LIS302DLTimeout = LIS302DL_FLAG_TIMEOUT; - while (SPI_I2S_GetFlagStatus(LIS302DL_SPI, SPI_I2S_FLAG_RXNE) == RESET) - { - if((LIS302DLTimeout--) == 0) return LIS302DL_TIMEOUT_UserCallback(); - } - - /* Return the Byte read from the SPI bus */ - return (uint8_t)SPI_I2S_ReceiveData(LIS302DL_SPI); -} - -#ifdef USE_DEFAULT_TIMEOUT_CALLBACK -/** - * @brief Basic management of the timeout situation. - * @param None. - * @retval None. - */ -uint32_t LIS302DL_TIMEOUT_UserCallback(void) -{ - /* Block communication and all processes */ - while (1) - { - } -} -#endif /* USE_DEFAULT_TIMEOUT_CALLBACK */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_lis302dl.h b/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_lis302dl.h deleted file mode 100644 index b99cb8091..000000000 --- a/example/stm32f4/Utilities/STM32F4-Discovery/stm32f4_discovery_lis302dl.h +++ /dev/null @@ -1,772 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4_discovery_lis302dl.h - * @author MCD Application Team - * @version V1.0.0 - * @date 19-September-2011 - * @brief This file contains all the functions prototypes for the stm32f4_discovery_lis302dl.c - * firmware driver. - ****************************************************************************** - * @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 2011 STMicroelectronics

- ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4_DISCOVERY_LIS302DL_H -#define __STM32F4_DISCOVERY_LIS302DL_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ - #include "stm32f4xx.h" - -/** @addtogroup Utilities - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY - * @{ - */ - -/** @addtogroup STM32F4_DISCOVERY_LIS302DL - * @{ - */ - - -/** @defgroup STM32F4_DISCOVERY_LIS302DL_Exported_Types - * @{ - */ - -/* LIS302DL struct */ -typedef struct -{ - uint8_t Power_Mode; /* Power-down/Active Mode */ - uint8_t Output_DataRate; /* OUT data rate 100 Hz / 400 Hz */ - uint8_t Axes_Enable; /* Axes enable */ - uint8_t Full_Scale; /* Full scale */ - uint8_t Self_Test; /* Self test */ -}LIS302DL_InitTypeDef; - -/* LIS302DL High Pass Filter struct */ -typedef struct -{ - uint8_t HighPassFilter_Data_Selection; /* Internal filter bypassed or data from internal filter send to output register*/ - uint8_t HighPassFilter_CutOff_Frequency; /* High pass filter cut-off frequency */ - uint8_t HighPassFilter_Interrupt; /* High pass filter enabled for Freefall/WakeUp #1 or #2 */ -}LIS302DL_FilterConfigTypeDef; - -/* LIS302DL Interrupt struct */ -typedef struct -{ - uint8_t Latch_Request; /* Latch interrupt request into CLICK_SRC register*/ - uint8_t SingleClick_Axes; /* Single Click Axes Interrupts */ - uint8_t DoubleClick_Axes; /* Double Click Axes Interrupts */ -}LIS302DL_InterruptConfigTypeDef; - -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LIS302DL_Exported_Constants - * @{ - */ - -/* Uncomment the following line to use the default LIS302DL_TIMEOUT_UserCallback() - function implemented in stm32f4_discovery_lis302dl.c file. - LIS302DL_TIMEOUT_UserCallback() function is called whenever a timeout condition - occure during communication (waiting transmit data register empty flag(TXE) - or waiting receive data register is not empty flag (RXNE)). */ -/* #define USE_DEFAULT_TIMEOUT_CALLBACK */ - -/* Maximum Timeout values for flags waiting loops. These timeouts are not based - on accurate values, they just guarantee that the application will not remain - stuck if the SPI communication is corrupted. - You may modify these timeout values depending on CPU frequency and application - conditions (interrupts routines ...). */ -#define LIS302DL_FLAG_TIMEOUT ((uint32_t)0x1000) - -/** - * @brief LIS302DL SPI Interface pins - */ -#define LIS302DL_SPI SPI1 -#define LIS302DL_SPI_CLK RCC_APB2Periph_SPI1 - -#define LIS302DL_SPI_SCK_PIN GPIO_Pin_5 /* PA.05 */ -#define LIS302DL_SPI_SCK_GPIO_PORT GPIOA /* GPIOA */ -#define LIS302DL_SPI_SCK_GPIO_CLK RCC_AHB1Periph_GPIOA -#define LIS302DL_SPI_SCK_SOURCE GPIO_PinSource5 -#define LIS302DL_SPI_SCK_AF GPIO_AF_SPI1 - -#define LIS302DL_SPI_MISO_PIN GPIO_Pin_6 /* PA.6 */ -#define LIS302DL_SPI_MISO_GPIO_PORT GPIOA /* GPIOA */ -#define LIS302DL_SPI_MISO_GPIO_CLK RCC_AHB1Periph_GPIOA -#define LIS302DL_SPI_MISO_SOURCE GPIO_PinSource6 -#define LIS302DL_SPI_MISO_AF GPIO_AF_SPI1 - -#define LIS302DL_SPI_MOSI_PIN GPIO_Pin_7 /* PA.7 */ -#define LIS302DL_SPI_MOSI_GPIO_PORT GPIOA /* GPIOA */ -#define LIS302DL_SPI_MOSI_GPIO_CLK RCC_AHB1Periph_GPIOA -#define LIS302DL_SPI_MOSI_SOURCE GPIO_PinSource7 -#define LIS302DL_SPI_MOSI_AF GPIO_AF_SPI1 - -#define LIS302DL_SPI_CS_PIN GPIO_Pin_3 /* PE.03 */ -#define LIS302DL_SPI_CS_GPIO_PORT GPIOE /* GPIOE */ -#define LIS302DL_SPI_CS_GPIO_CLK RCC_AHB1Periph_GPIOE - -#define LIS302DL_SPI_INT1_PIN GPIO_Pin_0 /* PE.00 */ -#define LIS302DL_SPI_INT1_GPIO_PORT GPIOE /* GPIOE */ -#define LIS302DL_SPI_INT1_GPIO_CLK RCC_AHB1Periph_GPIOE -#define LIS302DL_SPI_INT1_EXTI_LINE EXTI_Line0 -#define LIS302DL_SPI_INT1_EXTI_PORT_SOURCE EXTI_PortSourceGPIOE -#define LIS302DL_SPI_INT1_EXTI_PIN_SOURCE EXTI_PinSource0 -#define LIS302DL_SPI_INT1_EXTI_IRQn EXTI0_IRQn - -#define LIS302DL_SPI_INT2_PIN GPIO_Pin_1 /* PE.01 */ -#define LIS302DL_SPI_INT2_GPIO_PORT GPIOE /* GPIOE */ -#define LIS302DL_SPI_INT2_GPIO_CLK RCC_AHB1Periph_GPIOE -#define LIS302DL_SPI_INT2_EXTI_LINE EXTI_Line1 -#define LIS302DL_SPI_INT2_EXTI_PORT_SOURCE EXTI_PortSourceGPIOE -#define LIS302DL_SPI_INT2_EXTI_PIN_SOURCE EXTI_PinSource1 -#define LIS302DL_SPI_INT2_EXTI_IRQn EXTI1_IRQn - - -/******************************************************************************/ -/*************************** START REGISTER MAPPING **************************/ -/******************************************************************************/ - -/******************************************************************************* -* WHO_AM_I Register: Device Identification Register -* Read only register -* Default value: 0x3B -*******************************************************************************/ -#define LIS302DL_WHO_AM_I_ADDR 0x0F - -/******************************************************************************* -* CTRL_REG1 Register: Control Register 1 -* Read Write register -* Default value: 0x07 -* 7 DR: Data Rate selection. -* 0 - 100 Hz output data rate -* 1 - 400 Hz output data rate -* 6 PD: Power Down control. -* 0 - power down mode -* 1 - active mode -* 5 FS: Full Scale selection. -* 0 - Typical measurement range 2.3 -* 1 - Typical measurement range 9.2 -* 4:3 STP-STM Self Test Enable: -* STP | STM | mode -* ---------------------------- -* 0 | 0 | Normal mode -* 0 | 1 | Self Test M -* 1 | 0 | Self Test P -* 2 Zen: Z axis enable. -* 0 - Z axis disabled -* 1- Z axis enabled -* 1 Yen: Y axis enable. -* 0 - Y axis disabled -* 1- Y axis enabled -* 0 Xen: X axis enable. -* 0 - X axis disabled -* 1- X axis enabled -********************************************************************************/ -#define LIS302DL_CTRL_REG1_ADDR 0x20 - -/******************************************************************************* -* CTRL_REG2 Regsiter: Control Register 2 -* Read Write register -* Default value: 0x00 -* 7 SIM: SPI Serial Interface Mode Selection. -* 0 - 4 wire interface -* 1 - 3 wire interface -* 6 BOOT: Reboot memory content -* 0 - normal mode -* 1 - reboot memory content -* 5 Reserved -* 4 FDS: Filtered data selection. -* 0 - internal filter bypassed -* 1 - data from internal filter sent to output register -* 3 HP FF_WU2: High pass filter enabled for FreeFall/WakeUp#2. -* 0 - filter bypassed -* 1 - filter enabled -* 2 HP FF_WU1: High pass filter enabled for FreeFall/WakeUp#1. -* 0 - filter bypassed -* 1 - filter enabled -* 1:0 HP coeff2-HP coeff1 High pass filter cut-off frequency (ft) configuration. -* ft= ODR[hz]/6*HP coeff -* HP coeff2 | HP coeff1 | HP coeff -* ------------------------------------------- -* 0 | 0 | 8 -* 0 | 1 | 16 -* 1 | 0 | 32 -* 1 | 1 | 64 -* HP coeff | ft[hz] | ft[hz] | -* |ODR 100Hz | ODR 400Hz | -* -------------------------------------------- -* 00 | 2 | 8 | -* 01 | 1 | 4 | -* 10 | 0.5 | 2 | -* 11 | 0.25 | 1 | -*******************************************************************************/ -#define LIS302DL_CTRL_REG2_ADDR 0x21 - -/******************************************************************************* -* CTRL_REG3 Register: Interrupt Control Register -* Read Write register -* Default value: 0x00 -* 7 IHL active: Interrupt active high/low. -* 0 - active high -* 1 - active low -* 6 PP_OD: push-pull/open-drain. -* 0 - push-pull -* 1 - open-drain -* 5:3 I2_CFG2 - I2_CFG0 Data signal on INT2 pad control bits -* 2:0 I1_CFG2 - I1_CFG0 Data signal on INT1 pad control bits -* I1(2)_CFG2 | I1(2)_CFG1 | I1(2)_CFG0 | INT1(2) Pad -* ---------------------------------------------------------- -* 0 | 0 | 0 | GND -* 0 | 0 | 1 | FreeFall/WakeUp#1 -* 0 | 1 | 0 | FreeFall/WakeUp#2 -* 0 | 1 | 1 | FreeFall/WakeUp#1 or FreeFall/WakeUp#2 -* 1 | 0 | 0 | Data ready -* 1 | 1 | 1 | Click interrupt -*******************************************************************************/ -#define LIS302DL_CTRL_REG3_ADDR 0x22 - -/******************************************************************************* -* HP_FILTER_RESET Register: Dummy register. Reading at this address zeroes -* instantaneously the content of the internal high pass filter. If the high pass -* filter is enabled all three axes are instantaneously set to 0g. -* This allows to overcome the settling time of the high pass filter. -* Read only register -* Default value: Dummy -*******************************************************************************/ -#define LIS302DL_HP_FILTER_RESET_REG_ADDR 0x23 - -/******************************************************************************* -* STATUS_REG Register: Status Register -* Default value: 0x00 -* 7 ZYXOR: X, Y and Z axis data overrun. -* 0: no overrun has occurred -* 1: new data has overwritten the previous one before it was read -* 6 ZOR: Z axis data overrun. -* 0: no overrun has occurred -* 1: new data for Z-axis has overwritten the previous one before it was read -* 5 yOR: y axis data overrun. -* 0: no overrun has occurred -* 1: new data for y-axis has overwritten the previous one before it was read -* 4 XOR: X axis data overrun. -* 0: no overrun has occurred -* 1: new data for X-axis has overwritten the previous one before it was read -* 3 ZYXDA: X, Y and Z axis new data available -* 0: a new set of data is not yet available -* 1: a new set of data is available -* 2 ZDA: Z axis new data available. -* 0: a new set of data is not yet available -* 1: a new data for Z axis is available -* 1 YDA: Y axis new data available -* 0: a new set of data is not yet available -* 1: a new data for Y axis is available -* 0 XDA: X axis new data available -* 0: a new set of data is not yet available -* 1: a new data for X axis is available -*******************************************************************************/ -#define LIS302DL_STATUS_REG_ADDR 0x27 - -/******************************************************************************* -* OUT_X Register: X-axis output Data -* Read only register -* Default value: output -* 7:0 XD7-XD0: X-axis output Data -*******************************************************************************/ -#define LIS302DL_OUT_X_ADDR 0x29 - -/******************************************************************************* -* OUT_Y Register: Y-axis output Data -* Read only register -* Default value: output -* 7:0 YD7-YD0: Y-axis output Data -*******************************************************************************/ -#define LIS302DL_OUT_Y_ADDR 0x2B - -/******************************************************************************* -* OUT_Z Register: Z-axis output Data -* Read only register -* Default value: output -* 7:0 ZD7-ZD0: Z-axis output Data -*******************************************************************************/ -#define LIS302DL_OUT_Z_ADDR 0x2D - -/******************************************************************************* -* FF_WW_CFG_1 Register: Configuration register for Interrupt 1 source. -* Read write register -* Default value: 0x00 -* 7 AOI: AND/OR combination of Interrupt events. -* 0: OR combination of interrupt events -* 1: AND combination of interrupt events -* 6 LIR: Latch/not latch interrupt request -* 0: interrupt request not latched -* 1: interrupt request latched -* 5 ZHIE: Enable interrupt generation on Z high event. -* 0: disable interrupt request -* 1: enable interrupt request on measured accel. value higher than preset threshold -* 4 ZLIE: Enable interrupt generation on Z low event. -* 0: disable interrupt request -* 1: enable interrupt request on measured accel. value lower than preset threshold -* 3 YHIE: Enable interrupt generation on Y high event. -* 0: disable interrupt request -* 1: enable interrupt request on measured accel. value higher than preset threshold -* 2 YLIE: Enable interrupt generation on Y low event. -* 0: disable interrupt request -* 1: enable interrupt request on measured accel. value lower than preset threshold -* 1 XHIE: Enable interrupt generation on X high event. -* 0: disable interrupt request -* 1: enable interrupt request on measured accel. value higher than preset threshold -* 0 XLIE: Enable interrupt generation on X low event. -* 0: disable interrupt request -* 1: enable interrupt request on measured accel. value lower than preset threshold -*******************************************************************************/ -#define LIS302DL_FF_WU_CFG1_REG_ADDR 0x30 - -/******************************************************************************* -* FF_WU_SRC_1 Register: Interrupt 1 source register. -* Reading at this address clears FF_WU_SRC_1 register and the FF, WU 1 interrupt -* and allow the refreshment of data in the FF_WU_SRC_1 register if the latched option -* was chosen. -* Read only register -* Default value: 0x00 -* 7 Reserved -* 6 IA: Interrupt active. -* 0: no interrupt has been generated -* 1: one or more interrupts have been generated -* 5 ZH: Z high. -* 0: no interrupt -* 1: ZH event has occurred -* 4 ZL: Z low. -* 0: no interrupt -* 1: ZL event has occurred -* 3 YH: Y high. -* 0: no interrupt -* 1: YH event has occurred -* 2 YL: Y low. -* 0: no interrupt -* 1: YL event has occurred -* 1 YH: X high. -* 0: no interrupt -* 1: XH event has occurred -* 0 YL: X low. -* 0: no interrupt -* 1: XL event has occurred -*******************************************************************************/ -#define LIS302DL_FF_WU_SRC1_REG_ADDR 0x31 - -/******************************************************************************* -* FF_WU_THS_1 Register: Threshold register -* Read Write register -* Default value: 0x00 -* 7 DCRM: Reset mode selection. -* 0 - counter resetted -* 1 - counter decremented -* 6 THS6-THS0: Free-fall/wake-up threshold value. -*******************************************************************************/ -#define LIS302DL_FF_WU_THS1_REG_ADDR 0x32 - -/******************************************************************************* -* FF_WU_DURATION_1 Register: duration Register -* Read Write register -* Default value: 0x00 -* 7:0 D7-D0 Duration value. (Duration steps and maximum values depend on the ODR chosen) - ******************************************************************************/ -#define LIS302DL_FF_WU_DURATION1_REG_ADDR 0x33 - -/******************************************************************************* -* FF_WW_CFG_2 Register: Configuration register for Interrupt 2 source. -* Read write register -* Default value: 0x00 -* 7 AOI: AND/OR combination of Interrupt events. -* 0: OR combination of interrupt events -* 1: AND combination of interrupt events -* 6 LIR: Latch/not latch interrupt request -* 0: interrupt request not latched -* 1: interrupt request latched -* 5 ZHIE: Enable interrupt generation on Z high event. -* 0: disable interrupt request -* 1: enable interrupt request on measured accel. value higher than preset threshold -* 4 ZLIE: Enable interrupt generation on Z low event. -* 0: disable interrupt request -* 1: enable interrupt request on measured accel. value lower than preset threshold -* 3 YHIE: Enable interrupt generation on Y high event. -* 0: disable interrupt request -* 1: enable interrupt request on measured accel. value higher than preset threshold -* 2 YLIE: Enable interrupt generation on Y low event. -* 0: disable interrupt request -* 1: enable interrupt request on measured accel. value lower than preset threshold -* 1 XHIE: Enable interrupt generation on X high event. -* 0: disable interrupt request -* 1: enable interrupt request on measured accel. value higher than preset threshold -* 0 XLIE: Enable interrupt generation on X low event. -* 0: disable interrupt request -* 1: enable interrupt request on measured accel. value lower than preset threshold -*******************************************************************************/ -#define LIS302DL_FF_WU_CFG2_REG_ADDR 0x34 - -/******************************************************************************* -* FF_WU_SRC_2 Register: Interrupt 2 source register. -* Reading at this address clears FF_WU_SRC_2 register and the FF, WU 2 interrupt -* and allow the refreshment of data in the FF_WU_SRC_2 register if the latched option -* was chosen. -* Read only register -* Default value: 0x00 -* 7 Reserved -* 6 IA: Interrupt active. -* 0: no interrupt has been generated -* 1: one or more interrupts have been generated -* 5 ZH: Z high. -* 0: no interrupt -* 1: ZH event has occurred -* 4 ZL: Z low. -* 0: no interrupt -* 1: ZL event has occurred -* 3 YH: Y high. -* 0: no interrupt -* 1: YH event has occurred -* 2 YL: Y low. -* 0: no interrupt -* 1: YL event has occurred -* 1 YH: X high. -* 0: no interrupt -* 1: XH event has occurred -* 0 YL: X low. -* 0: no interrupt -* 1: XL event has occurred -*******************************************************************************/ -#define LIS302DL_FF_WU_SRC2_REG_ADDR 0x35 - -/******************************************************************************* -* FF_WU_THS_2 Register: Threshold register -* Read Write register -* Default value: 0x00 -* 7 DCRM: Reset mode selection. -* 0 - counter resetted -* 1 - counter decremented -* 6 THS6-THS0: Free-fall/wake-up threshold value. -*******************************************************************************/ -#define LIS302DL_FF_WU_THS2_REG_ADDR 0x36 - -/******************************************************************************* -* FF_WU_DURATION_2 Register: duration Register -* Read Write register -* Default value: 0x00 -* 7:0 D7-D0 Duration value. (Duration steps and maximum values depend on the ODR chosen) - ******************************************************************************/ -#define LIS302DL_FF_WU_DURATION2_REG_ADDR 0x37 - -/****************************************************************************** -* CLICK_CFG Register: click Register -* Read Write register -* Default value: 0x00 -* 7 Reserved -* 6 LIR: Latch Interrupt request. -* 0: interrupt request not latched -* 1: interrupt request latched -* 5 Double_Z: Enable interrupt generation on double click event on Z axis. -* 0: disable interrupt request -* 1: enable interrupt request -* 4 Single_Z: Enable interrupt generation on single click event on Z axis. -* 0: disable interrupt request -* 1: enable interrupt request -* 3 Double_Y: Enable interrupt generation on double click event on Y axis. -* 0: disable interrupt request -* 1: enable interrupt request -* 2 Single_Y: Enable interrupt generation on single click event on Y axis. -* 0: disable interrupt request -* 1: enable interrupt request -* 1 Double_X: Enable interrupt generation on double click event on X axis. -* 0: disable interrupt request -* 1: enable interrupt request -* 0 Single_y: Enable interrupt generation on single click event on X axis. -* 0: disable interrupt request -* 1: enable interrupt request - ******************************************************************************/ -#define LIS302DL_CLICK_CFG_REG_ADDR 0x38 - -/****************************************************************************** -* CLICK_SRC Register: click status Register -* Read only register -* Default value: 0x00 -* 7 Reserved -* 6 IA: Interrupt active. -* 0: no interrupt has been generated -* 1: one or more interrupts have been generated -* 5 Double_Z: Double click on Z axis event. -* 0: no interrupt -* 1: Double Z event has occurred -* 4 Single_Z: Z low. -* 0: no interrupt -* 1: Single Z event has occurred -* 3 Double_Y: Y high. -* 0: no interrupt -* 1: Double Y event has occurred -* 2 Single_Y: Y low. -* 0: no interrupt -* 1: Single Y event has occurred -* 1 Double_X: X high. -* 0: no interrupt -* 1: Double X event has occurred -* 0 Single_X: X low. -* 0: no interrupt -* 1: Single X event has occurred -*******************************************************************************/ -#define LIS302DL_CLICK_SRC_REG_ADDR 0x39 - -/******************************************************************************* -* CLICK_THSY_X Register: Click threshold Y and X register -* Read Write register -* Default value: 0x00 -* 7:4 THSy3-THSy0: Click threshold on Y axis, step 0.5g -* 3:0 THSx3-THSx0: Click threshold on X axis, step 0.5g -*******************************************************************************/ -#define LIS302DL_CLICK_THSY_X_REG_ADDR 0x3B - -/******************************************************************************* -* CLICK_THSZ Register: Click threshold Z register -* Read Write register -* Default value: 0x00 -* 7:4 Reserved -* 3:0 THSz3-THSz0: Click threshold on Z axis, step 0.5g -*******************************************************************************/ -#define LIS302DL_CLICK_THSZ_REG_ADDR 0x3C - -/******************************************************************************* -* CLICK_TimeLimit Register: Time Limit register -* Read Write register -* Default value: 0x00 -* 7:0 Dur7-Dur0: Time Limit value, step 0.5g -*******************************************************************************/ -#define LIS302DL_CLICK_TIMELIMIT_REG_ADDR 0x3D - -/******************************************************************************* -* CLICK_Latency Register: Latency register -* Read Write register -* Default value: 0x00 -* 7:0 Lat7-Lat0: Latency value, step 1msec -*******************************************************************************/ -#define LIS302DL_CLICK_LATENCY_REG_ADDR 0x3E - -/******************************************************************************* -* CLICK_Window Register: Window register -* Read Write register -* Default value: 0x00 -* 7:0 Win7-Win0: Window value, step 1msec -*******************************************************************************/ -#define LIS302DL_CLICK_WINDOW_REG_ADDR 0x3F - -/******************************************************************************/ -/**************************** END REGISTER MAPPING ***************************/ -/******************************************************************************/ - -#define LIS302DL_SENSITIVITY_2_3G 18 /* 18 mg/digit*/ -#define LIS302DL_SENSITIVITY_9_2G 72 /* 72 mg/digit*/ - -/** @defgroup Data_Rate_selection - * @{ - */ -#define LIS302DL_DATARATE_100 ((uint8_t)0x00) -#define LIS302DL_DATARATE_400 ((uint8_t)0x80) -/** - * @} - */ - -/** @defgroup Power_Mode_selection - * @{ - */ -#define LIS302DL_LOWPOWERMODE_POWERDOWN ((uint8_t)0x00) -#define LIS302DL_LOWPOWERMODE_ACTIVE ((uint8_t)0x40) -/** - * @} - */ - -/** @defgroup Full_Scale_selection - * @{ - */ -#define LIS302DL_FULLSCALE_2_3 ((uint8_t)0x00) -#define LIS302DL_FULLSCALE_9_2 ((uint8_t)0x20) -/** - * @} - */ - -/** @defgroup Self_Test_selection - * @{ - */ -#define LIS302DL_SELFTEST_NORMAL ((uint8_t)0x00) -#define LIS302DL_SELFTEST_P ((uint8_t)0x10) -#define LIS302DL_SELFTEST_M ((uint8_t)0x08) -/** - * @} - */ - -/** @defgroup Direction_XYZ_selection - * @{ - */ -#define LIS302DL_X_ENABLE ((uint8_t)0x01) -#define LIS302DL_Y_ENABLE ((uint8_t)0x02) -#define LIS302DL_Z_ENABLE ((uint8_t)0x04) -#define LIS302DL_XYZ_ENABLE ((uint8_t)0x07) -/** - * @} - */ - - /** @defgroup SPI_Serial_Interface_Mode_selection - * @{ - */ -#define LIS302DL_SERIALINTERFACE_4WIRE ((uint8_t)0x00) -#define LIS302DL_SERIALINTERFACE_3WIRE ((uint8_t)0x80) -/** - * @} - */ - - /** @defgroup Boot_Mode_selection - * @{ - */ -#define LIS302DL_BOOT_NORMALMODE ((uint8_t)0x00) -#define LIS302DL_BOOT_REBOOTMEMORY ((uint8_t)0x40) -/** - * @} - */ - - /** @defgroup Filtered_Data_Selection_Mode_selection - * @{ - */ -#define LIS302DL_FILTEREDDATASELECTION_BYPASSED ((uint8_t)0x00) -#define LIS302DL_FILTEREDDATASELECTION_OUTPUTREGISTER ((uint8_t)0x20) -/** - * @} - */ - - /** @defgroup High_Pass_Filter_Interrupt_selection - * @{ - */ -#define LIS302DL_HIGHPASSFILTERINTERRUPT_OFF ((uint8_t)0x00) -#define LIS302DL_HIGHPASSFILTERINTERRUPT_1 ((uint8_t)0x04) -#define LIS302DL_HIGHPASSFILTERINTERRUPT_2 ((uint8_t)0x08) -#define LIS302DL_HIGHPASSFILTERINTERRUPT_1_2 ((uint8_t)0x0C) -/** - * @} - */ - - /** @defgroup High_Pass_Filter_selection - * @{ - */ -#define LIS302DL_HIGHPASSFILTER_LEVEL_0 ((uint8_t)0x00) -#define LIS302DL_HIGHPASSFILTER_LEVEL_1 ((uint8_t)0x01) -#define LIS302DL_HIGHPASSFILTER_LEVEL_2 ((uint8_t)0x02) -#define LIS302DL_HIGHPASSFILTER_LEVEL_3 ((uint8_t)0x03) -/** - * @} - */ - - -/** @defgroup latch_Interrupt_Request_selection - * @{ - */ -#define LIS302DL_INTERRUPTREQUEST_NOTLATCHED ((uint8_t)0x00) -#define LIS302DL_INTERRUPTREQUEST_LATCHED ((uint8_t)0x40) -/** - * @} - */ - -/** @defgroup Click_Interrupt_XYZ_selection - * @{ - */ -#define LIS302DL_CLICKINTERRUPT_XYZ_DISABLE ((uint8_t)0x00) -#define LIS302DL_CLICKINTERRUPT_X_ENABLE ((uint8_t)0x01) -#define LIS302DL_CLICKINTERRUPT_Y_ENABLE ((uint8_t)0x04) -#define LIS302DL_CLICKINTERRUPT_Z_ENABLE ((uint8_t)0x10) -#define LIS302DL_CLICKINTERRUPT_XYZ_ENABLE ((uint8_t)0x15) -/** - * @} - */ - -/** @defgroup Double_Click_Interrupt_XYZ_selection - * @{ - */ -#define LIS302DL_DOUBLECLICKINTERRUPT_XYZ_DISABLE ((uint8_t)0x00) -#define LIS302DL_DOUBLECLICKINTERRUPT_X_ENABLE ((uint8_t)0x02) -#define LIS302DL_DOUBLECLICKINTERRUPT_Y_ENABLE ((uint8_t)0x08) -#define LIS302DL_DOUBLECLICKINTERRUPT_Z_ENABLE ((uint8_t)0x20) -#define LIS302DL_DOUBLECLICKINTERRUPT_XYZ_ENABLE ((uint8_t)0x2A) -/** - * @} - */ -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LIS302DL_Exported_Macros - * @{ - */ -#define LIS302DL_CS_LOW() GPIO_ResetBits(LIS302DL_SPI_CS_GPIO_PORT, LIS302DL_SPI_CS_PIN) -#define LIS302DL_CS_HIGH() GPIO_SetBits(LIS302DL_SPI_CS_GPIO_PORT, LIS302DL_SPI_CS_PIN) -/** - * @} - */ - -/** @defgroup STM32F4_DISCOVERY_LIS302DL_Exported_Functions - * @{ - */ -void LIS302DL_Init(LIS302DL_InitTypeDef *LIS302DL_InitStruct); -void LIS302DL_InterruptConfig(LIS302DL_InterruptConfigTypeDef *LIS302DL_InterruptConfigStruct); -void LIS302DL_FilterConfig(LIS302DL_FilterConfigTypeDef *LIS302DL_FilterConfigStruct); -void LIS302DL_LowpowerCmd(uint8_t LowPowerMode); -void LIS302DL_FullScaleCmd(uint8_t FS_value); -void LIS302DL_DataRateCmd(uint8_t DataRateValue); -void LIS302DL_RebootCmd(void); -void LIS302DL_ReadACC(int32_t* out); -void LIS302DL_Write(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite); -void LIS302DL_Read(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead); - -/* USER Callbacks: This is function for which prototype only is declared in - MEMS accelerometre driver and that should be implemented into user applicaiton. */ -/* LIS302DL_TIMEOUT_UserCallback() function is called whenever a timeout condition - occure during communication (waiting transmit data register empty flag(TXE) - or waiting receive data register is not empty flag (RXNE)). - You can use the default timeout callback implementation by uncommenting the - define USE_DEFAULT_TIMEOUT_CALLBACK in stm32f4_discovery_lis302dl.h file. - Typically the user implementation of this callback should reset MEMS peripheral - and re-initialize communication or in worst case reset all the application. */ -uint32_t LIS302DL_TIMEOUT_UserCallback(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4_DISCOVERY_LIS302DL_H */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - - -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ From b48db26a32f43c9ad7755136cef88a8613ef38fd Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 20 Jun 2012 19:16:40 +0000 Subject: [PATCH 0171/1435] Update primary README with current documentation --- README | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/README b/README index d99337c2a..cd4fc5af5 100644 --- a/README +++ b/README @@ -35,8 +35,20 @@ IF YOU HAVE AN STLINKv2 You're ready to go :) -To run the gdb server, do (you do not need sudo if you have set up -permissions correctly): +COMPILING +~~~~~~~~~ +This project was converted to Autotools by a well meaning individual. The +following steps will build the project for you. + +$ ./autogen.sh +$ ./configure +$ make + +USING THE GDBSERVER +~~~~~~~~~~~~~~~~~~~ +To run the gdb server: (you do not need sudo if you have set up +permissions correctly) + $ make && [sudo] ./st-util There are a few options: @@ -52,8 +64,21 @@ There are a few options: -p 4242, --listen_port=1234 Set the gdb server listen port. (default port: 4242) -Then, in gdb: (remember, you need to run an _ARM_ gdb, not an x86 gdb) -(gdb) target remote :4242 +Then, in your project directory, someting like this... +(remember, you need to run an _ARM_ gdb, not an x86 gdb) + +$ arm-none-eabi-gdb fancyblink.elf +... +(gdb) tar extended-remote :4242 +... +(gdb) load +Loading section .text, size 0x458 lma 0x8000000 +Loading section .data, size 0x8 lma 0x8000458 +Start address 0x80001c1, load size 1120 +Transfer rate: 1 KB/sec, 560 bytes/write. +(gdb) +... +(gdb) continue Have fun! From 37aa61a74d5e45dde29af562a0e27898211c35b4 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 20 Jun 2012 19:35:46 +0000 Subject: [PATCH 0172/1435] Update tutorial documentation to reflect current code. --- doc/tutorial/tutorial.pdf | Bin 115939 -> 110584 bytes doc/tutorial/tutorial.tex | 134 ++++++++++++-------------------------- 2 files changed, 40 insertions(+), 94 deletions(-) diff --git a/doc/tutorial/tutorial.pdf b/doc/tutorial/tutorial.pdf index 275e7a8fdd0755096ea549faab603b091439772e..b73396ce73035085f757c109b178fdebdd3c6515 100644 GIT binary patch delta 72841 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 F{{cW6E*1a) delta 77973 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�>$FZGHniOM1ZfTQ6cyfze!K-btyanux)b%FX0s)lKcM1Ks9`UtA8 z943%NbNmwz0qKG7+P%GGS~oH{5J=V4@*FY@_gyLXUt>a}(=QDKf@GsryYq1q7)Y*>$u7qNhWddyirX=j`fIElVDdNxug~Uz zo3V>3Z7g} z0h0t*5qE$o-RKTi5l6VW0qaH z{b3R%sQcTlx4>}n@0M(buDlAZswU$cnf(@gvmL7UtF~zbmu(48g4ALw;6Te~Bn8G4dD7z&F zaBaYAcdh&40R~R{m1+6!X;x15kH3^d(@*ZvIXE|!`JGWBsoygAZ6w&c`H*amB=qFj z5y`kO{L5~%o@81xDi8AZcBFk*2E)4U175$C!5r19OToePFR06P`+e76Qj`xzo*vw% z4df?cx6u6a$+}UXn=Y&0`IFi_sQR47DZT+G-;8Rv2gn$Y8o%2z`l42xm~9b5+hd#r z5C02iicKd5ulT6>m=J`4^bPZ;4GBDjHo_R>Z+b&O@ezy8vK3OHD5)iDPpHgW;~QhK zr8IZvQn$M2z4>I=Ttn&3O68$S)zvg;^i#ZWem1{xiTR`p8~O0jc2W`5AJ%^O451DCxyFEr7XZ)IQF?{D{1iWhHamjNQZgBQ(^;2 zzIZ~m?tVPfrAL;cUZd`3lLZ#c0!2sfcj@HXE1;uMaAj(BYth_TO=)qyelcV+_9)k= zjxuJ`n<-W5pZ9O#Jz7Q;`sL|YBuuvHXqs9wRFV?6;25O&RVk17fFy;$P5jtDJM^@& zl~)VjWF@3lH(dr)w>ha~Ij4#|`Xonmnc$cK*>NhGT6Kr+XqW=@n-X1ILQdr4?^wMA z2f!mHk5WS~4AL&;e({`PeNBK= zxyNGo<=HQqJnMrvlhz?!J+220h5UT-9|gNk65Yhf$>N1;q~QmG)A{H89u}o5zx2c4 zv;Vf=Z%1aJGcoA=eaAg|xWh!e`~np;#laN&|B(0W|3ls*>ZmJAOG(m;D~jo`vZePi zgJLD$H#mTbCYvT(Za+GX)5P(J1}|QTT`9Hv(|jG!DlZW&DMGltwF#3LiI|_ z+$*A+9FZH}}Dul#Y%lzcxsCRCLe!&OY zaCO&la6=G2D>q?Cm`Wg6z&M}tA9ED{`A7_MPI4I?0$N6|`4J*5Sozga{|~JHe)THB zm>Wn%vMz}GnOEJE+trc#1O#T5=2om-Q7IS_;w+vs5E=%l6@9USM(uo!P6jc7a7jr? zAu(Zr%%Xzav-~!BCNx@F0DT71lTKQ27K3VALb||v5f&k4SLP95Ucs*}?DwG{T6x;Q z{JXw>JsU&J3_`FpaX5qGfKM@A?0iW;M+I2|X0zA141yqhF$G&@U@V`XFGtBl)?Er0 z7xn^Q8DE^nP^`3!ys)}iJ^Y{2)C~4lpx0$)77(+n4Xj`p0nE72$05MgSNKar;1}0d zy2jk-t?w-GjS-A=-feq4KHgZz#njg+9w% z_B8{2oj&o^)AdDo@a6FE_k#5lfLu?5FDzBo4&VFFR{?FM1@rGEZ{Zeaz^0`r0O0mQC?BJ=|&(1D`+$h#0M zk)NUl1&r^|&MaU!gI^?6AR&Xqg9s)G?;$!M2xEz5({W1-F3xwfC6vw) zLjd(0pCKY?R9_@q3DbkyP#n)+ayq(zyuHKM^Vc>E)B->P|C2`D7ayOz9MBCMh5Cer ztAF+t|H55#>?)=|uKSDvBLi(j<&tXtiUunhJ4c3i$@qZ()YAJL>$}Bo|BxNO*T1F~ z+HiFBT>(~L*jT=>As%dQ%I#3Du=0?w0FjP=%bKTs1sBv*e?p29=zqZnM>f7-L;QZP zofbi+7|0*BC(-7g{q{i$o-#JQwEX<^!}7BhE0Iup<>j%zVxmtckt{=9wS$ zCR-4m)8_*5=oqfG-Am7pp~nrV<45N3H4)JqQDgou49MM~wc*jVUE?58_fJ`PpElh8 zNf^-MR9W~>!hj3Nkkbb?MC{OoF^Wd!TaOmp{>2S54BXXAIbK2)_Uy^k>et<7W-DJ1 zjQh(OJnTKzC-&EaGBnCDD8Lb9oYlhp7xs50vQ1AdX1{y+2L4et>BfRganYTT%c+yU zM7V5ON!`&&9|6JA0H`fuRAjkbE)XMzdE<990+SL$t;(mk6Ue`TQt3|~7(wh@6z z?_ZjgZ2X>o6Lzi5_Qbaf;*=77;fc#+%ox4Wv1*YRd>XH@&=1Mx%4+8Q3xv(5tAA_6 zHQSy3a>X}%oo>wjrwW28>?IW0P^_l66XSLw)9U?c!yYN+T4DAZYL_^G8{NpRNArrS zL2gL@FzfRbDnoL5JKoyK;}Q+(F?KJzr&SSF!)%nE z;os>&Wq<8UHmJE$&=j#Rk&g4U$(Q$Onv@m(W3lHO@&yl6@?wDNsKe-5wbR(%TL_!A zTQm0P_7As}Dwh4G>O=6K;I)H4G5qQ?Ge4XdbOsR``f2XihuX>SR?KKqyiS8+8~P3q zj_GfFAb=+i{@z|8-(5WELJV9@2yoA6Ns{tAum3+oWNTN9-$HLieQuw2?+HT(o4;QKG}2U0T>z z;H?x~D(TLp%r`LJjKou~oUN+QCK~u1+EQq6C2x`pdM1^(o$@KWBX$8k*v$SpM0c%j?y83*hBeE6smyghTbXn85~qK5>uBti<(7aXTa4SG zddgo*b}a`4DQ;8Gq3Hkp(sJ@(v>QE4c8SC)+p);(t2=dbVN!CT&48>953jE)1brhA52BAt zF;jpDnd|iA8~ansBZ%Rxn|XL$`)ojUN!ge7hy13lyoKY9Z>*K=!`ypZ1s&AaDl=$} zxEUYvEDvY*?THgl5FEdy`-n&``C1dYi9C?;+1?4 zDqyHI=RU-s2FvWgx;mTt4a#G_^U|Lgq@Q-hnI|LzGU5t}jaJ`XPd+?A6Y9-6qcR&y z-c(|EgGNk3Ux%z5JP+iLYZw}@TsT>Ex^58QEG5{KWhj@JvUqrMWM;u`NVZ(2g#CEK z;AGG98gNa{5I1=Y#><}Ro#Y&={hWJGqr~^Csw>}s(v`S*rQJ@<$LN`X-(3p-0lVar zs3f|AyJq@k9xg}S$yX+Qd zC!5NY+?#-FxkC>g!kZ)tjmU|Us4rVs;%|K%3FuHbMaT~ieStWuAy$sUL2qxmz33v6 zQ6{Fkf&w3Xt>h~YXWeXBZpnB!pYY`dS%P8)Q^OM8?jSmZ-}pp}7~cJEE*5U6z#7Jg ze{0?Yf2wB$z4L=SHQZ!k{da{ydvZE3M>w;%yf5RmmF`0L?G90u;#@7RyHQ?He^i)j z()Wt404!l4gT!J>;n1FSTbC=~gp8Ohji0yv0^NQ-1HP)Csj}XXlgi9M&R6=wI>Q-Z zAw9n}an!_PA=_a=w2WprXGXDrNurdDVWMtEKknrR;x7XV>7Pz}OdH|l>u=HkHW;Ps zS8f=dM;(fitUti%KZ!O?;qmJw;dp9r~D-^VqJyP^><(uddCt~FjIs;24J;S4|R8wedY zOU2X41R!|aw#fL|E4dAIM#8_C%b4wbpgtn~bmJzrBC!r1`j_G3B0dL1-AQnUbEXORufDW{1z9%iGR|2p)oK?MT0*qZ0DOX4S4&v6SJY&Hi31C zO_xzR@Kak235Z_HI_muNX3A&!Q%3Up`LHwZ;r#S!gQ{W#XwhOl^^b(XX<$Q99I|H10$6ctT-xW2+veZbb;$xccaM0>AD-~O zXOM-oI99EV-USkvD!3wvWfJ#`E}5V`Wju5GX0(H{08O!9o5zKh-V3cUY^jRX(z^!{ zxq7=h9&52FvBX&U0UfKxa#s|Sn6lCT*j-9B%KrP+Bem}Uos5h2I4qY9Be4)ZqdI&Z z_kjAUJ4d!PI?bmHY;4`L>?hqRJkQLb*6$NLi=;VJPO4Q1R9>pAHM7hBn!JY!sC%kcHkY{Pr98ll0UQ&NqZ3vvyQ z`%7gh-Qm!YxW9MruL{w^oNrF58E~1W+AmtTajSTM4&K523p!!>?&J~auk3(Ebw=p| zN8c?nB2(x4ts7-GI|FAyqx_QX$FOVY+yy*z^=EwlD^GkmvSI_cGzC>2VRGgQl@b zqI3hFBv&KmP=1=l0^Kb!UVFpiZQbr=H$L%OiNuE$h4zYtMCZ|}iF!g_@;y(k5S1H` zndif{X91vgyPWEH6~bA`zh*a>kIe7$f~w^CFA!x;@433`J5Z0ZUEdVk%tWueX1pPE z$WT%HtsNQAb$k$k3rA`zh_@IW518y>q(b0uI@+eJ#7(`ug>$bVbHBb5DOcs^)Rn_5 ziof1F8$J&*@kzv+TK8N=EV7SxT012AcicsIU(NW?qi{oZ_|~cB0Wom`!=^tBp-;BK z_?T$UyOWq}{pHo6X4xIgsC~Ty+pgzP12(WemB%lJp@(86+JdXA@H1c43Zdi*V;%sx zsUMGhG@3G;n8AkEyCzlhw-R(zbC25NK0FfKtcbs^5XCo}y$xidEb*VB@Ua<^&sh#9 zr`}%y@@nZ`Wn$2;d9)S+AB&-ipLtcALHU{D?TXI_m2;V(x7v%`uH$EH$Ox2r=GXzb zrw-GmIw}#vbukH+TH9^=c z8r}T0C2L}EjBTne*8z)?l|L&9rvdA@09p7eF{e4C;(pqLkiLhgEn5?0hIzmR*Q7JEN944YRzXANM+r1WTd60YH zj+$`YjgEIP!oQm4I=}D~?k(+OR>yDbIulw7G6GDs=OEm71yZhkTJ9QVt9aM04u`UM z5N5`UemFXbTtZ>ZB&mr`asu$4hR!3{=8-n&7&2TD!N%7`Et8lM0@+v{(eN614ig$V z*%b-eI+kUoLdDEt>J*bKGZF^dVF`u1!vT{IbBo@*m654OJQz|Sr)3bOcha$m@B3#P zRSX9=*n`A55MS!3Z~cxznW@%PvBjo7aQcrrZE5JaDtKzgz%xW-kp%9^CFx)GVa|iB zu?*lmwCrl#sIaBO&u2??s>@zNcW9H9y=*k(khw)5vrdpiTsRk^O@jm~i!rF|RBI$# zu=mS%?@w(8p%T;=lW4ND_epnxUt`LlHMzn{A;WPA=|-^<>Y7<4Ur;}V=<|q4JGfhI zbTsDaI(G)**u&AK5`Ym~xOX9cyJ76X|gX1r^C8fv~3wL*IU8nu2UX9BMt2W-pYy%QzoHUiq(7)l`(ka;rC_ zry&GHpEy|6!jYGb6p}sIww0GrMksdUwAhr%Jz`@h&q&H~H9(~jiDq&?r`*I6mXmYQ z$S>a!KRc`G6;Jq#9Ac6wK{pl=O*TOIhgO1L2qDoAQVy?YtSMIYo8&VuNBN35>b_zVY86doJ#!9iGBWOffyU48m0{#6bvs+7o(YHCC1J zeG#vrc*iGntO4q}GPESjfiPKqM#m~laV%nd818r50WCP%>`v^jDZZkv@T2!^+@ZWg z^s5pu>)%<8?A^}L#p3>r$_gyE*YP410-(B*k_AR+3FY~@De}wj}P*xiN6#{?a zi>rTsb)1C8t_j;YEn!r)1i-`4?}X5XyboXdg~|FN_mTu<;!?!jg;41e^txr!%uwCn_KSK&&#F+ zFv`V{Yk)){7Zk)}y7D+$bgJ!Eqw=ERR*UTkE}hvD*Ed*|18gpt1e_3*K2@1ABTdp> zck|)IZwkRW+YlbnxQ>Itg`QASlqqlRRv*}8OUk9XOd5TCEC{+t+R61`jn&zYDT61~jB*Y_iJH(Lr?Hj9r zCbM2oe;jM6WX4!Q=E7x$e)puKEYQ9_D^2b6$`A3bI3Zz@ga3qTpy(=H(k?CsqP4V2 zh=cg2w`iC$F9Wm7i(LQU^@H=?mw+d0E-B6H1hc}jtSQLtw~3c08nmS^nqnsbE~E0@q{!#* zk+Qqht9(?|LWv|5Ne+@mjR0 z&(K`v*w70#d<$;zssDZD!-Ftr9iVRi_)!=SL&9!l$;&Ao+RuNP~|=qTogaU zI*@-ufKk!xUSq7|t)yzR*wmPZ4(wnxYY`W1vWQ)wU;L^HL8Y(qZi+9*M3+Facf$Qi3CPhq%f|X)+vQzx;6zpnd7(>=PQ~Ti7Q% z*PwzHRm>e=Rz7FjUeY7Pauz#(u7bea$A=R?uk+QkX)*CxI!kx;D<(k|f8Hgg$;mQy z!1KdsOY1~P>XoL-|as=KDDUvWmI-Fj$c2z|ieE*nB8lGWGa;s~ z8gy3IdDXf#x$&TamRAH!Xl}_i>)=l1+g62D*to*(gS)?ie=g4(PPy@cxjq#pL1_^fHEoBe!!&QNi>sf0)U5m0I?<{q`X( z^tT9hevY2h`WFt8EDw5{esOT03c&}ne6&0ww1?$#N*q)3w)6Vo%dVn##iwYnbBY-l z*{BL=S5kFQDwbE)DT%sMurGSiP+%{oHyzlj`Y1?ru#kEvr2nxR>p%vfdR3%}hsj$ZhH@YG+>u@6xl)tQ-mA|?puE@m}Rcd>+2QpXM@W|a3l#U zT{KB`#1=tK#CG|-@MnWxS<-EZfg*?aDW6F3B(2U0&VMz|e~nJvzMom{g-*eZR^1V_ zYA&KPv{Cw`$f?nZ4=pt4_NgfiLc1|75Rrq!-nQHr84P>(R+=(j_FG_WFU@!!>!sip z@rG{lx9A-LPp~(F5!3Io7~I3?N*BZ(bAzNm0!TQt&qA1#Qu)g|4xjvkB^bAI#0NgY z-`vjEpJ3enxrOeL<=_tZ#5g`sCJ@9+G zc+VFjk|c=qiJ+??%iOQ0KS2QszxGKl%$4#?y~KavSMSmxQFv)FQl?ib$q^voe2jgrCR zDc6^8+w;s{o?{*Y6m;pUJ@P5M*CqSG$Y0(UXCR%{#nC5vL*A}0cLg;iFSa|x9e;Vp zf2Kf>yuLOKTaJXr8w|Hjs;6CaY73vx6(i#rM&4a^U4CI(H~#DOvKp|nFUdR0C!sG{Tq8)m%+eAF6 zlk|!oB%Ydkkp{b(7ZocdqPSUOs(CdHldzSwb~ZX9bZFs-s5LR3ub4K${5aH*e{36a zVoyot2^hupDx|pzha-z`b9k9(h1(7@~Pedu3|)OG9YF zF?#YZ(Z)3@44)fE;8%a4e{SKtp+cu-$5Zhxlz_mJmdb4@(n_^=4m-sot(wh~v7HN0 zvf*FHl4~rvwxS67YwP_CUzw)mU5h)H$f_17u``;c0#tR`W@F0DmbDlyj7%8$sJ)tk zmQ6LWu&ZvK$^^t+RS&UU^jA;%n2mkOJ$~FcX3ZX+D`hq9A+X_sf2#mIrSB^8d8?6b zSwGS+j72ggxNFZRMeh>$>?cPmLbez-$di_Dz~`!#l=8b^-C$se@vyBA8NK+JvlX#{ z`^T)>R0z@vwezyBi!?Ib%dk@$u~tMKe<0s@lbpd-iS{kiaDI4nTJEq%I0&~oe|Brf zC7cB$d%k-#a=OzQe+<(+HJB2ba}dL=IzKK|U7D^f@B%DCRoG@(f}@c1jlGO%*J95r zzeQ=uv-smeD0T6@MRwIxHY&2n4B%&($_os#1!jrJh79&vS}pQ!G&D9dmN*L;X(ilY zv(M(RF~B)}lY`83t0iV1-C~_szX1`jcva-17Zi; zur?mL3rBY~$#K^AbVk!~4an3xN+v!UJmo^xFG@U20hJ=1={{v!&L8aBuKR$9zcvCz<^HYjsMs|O<13yRI}T-F8>{K zv!0tzKO$WAJ0;&$vj3)-rNCmNRut1_t84&LcS2_(36rZSO|H5P3R`<(p7-K-?i@T6 zTx`xEETa(Abu)zG4C=~8$R}r3;@Cva;@GI*E)_@zeWI`UB%#>>wiaS*f4cEyVO88}H z3O{5DsHbizXAuiJ<**ih&@bZ3l3ktXtu!@*u7s7Imy)@C3RN&*JO8kL7~Q!w@}zHu z{82Fw+NY;jN4@9f5E|l&2}K-yNl%RwMgVDYe;%r~4R#hl(ju#mR4_`ejM0LY2W50v zLYI{@qW>t`sa2d)wCBYXhJ^a``O((7S=hl?)F_?1gi?c|alfnTmtnfmY6hIg*U=zE z%{rGe6A}TQOuPJU9?SJ|M`nVfdYxw)-8Hg!)!=REAUj%^pH&hhN}8)Dn$NbsaBue34N29cf08qyIM{guR4J3pNG_@`d`AI{8}U8gwBpc(&uU8^AKoK-cs2mqav(nreteZFVY( zAY;~1+Ua3*PfEXcuIQ#`ycAe|;N4JDv7dY0Qt!$RF%|%%>uIAE&*7vIBzoNl=;RG+jgsYGkxJS z549tIMj^>C0qeAp{Wv-GiLV3ItEAbQz+iCs^Xb!kCFM=Xj9BVVy>51y3OIl3%dQs{ z&oiY%%`;X4Iz*&M4d-MA*^AjYg_4Gd11P;KE?4un!#9O;H|*lm&BK~@f3>XR4~(T{ z$+=wg>_eNoZJRnr(x#Jmdkz$mRp?-(2~Rd+=^PngCI=p18rrAv(ClSPgv0A3be7}rZ&sU z;LjDAJb0!WdME9-tzkS#fArz$b_F?o#{bsr+@Q-23XNEb!sXfd5?}w_4 zXJ}TxsIdK%LK2|qI7jmKL{Mfm$-#fW4E|gpe7}c87^&SN%-XL#e-3j+!G<_coK+CP z34Z{_wjCGnm2m}cH|Qz2MS^uu`lho}w|@ef!~B=gr?(DcRcoP7zjp8&2K7!pnLl#7 ze?_N}7zZD0!b9dDcKr&c?s6P|gd4qmT>g3O#FLgJp(V)wCs$!%Bx4;|jtMKqt-&qb zOiTU&RF>Aahqu_*f0N5@4AZn#tPj-*M5o!`J+k)5DJ_ofE>rJ&HO)_8vS`k~YIq~D zeB*nxVd`u#LE}wvY+%lk2!*@eun$V~P%$mOYn@K_C6~m5$PY1z)=sM8GYH?YNlEr| zN<+R_9?Bq@3E6LVK+wMl)(MGD`hw|SMC2RFWnQEISeZ!)e+>CXaktJlutU(%!S<~S zbC%jvgYhLlnN8?*eyVIhguYg4agQz~@blI8+SD1!HCi#VN7M+!4~Z>axzq=pDS6dU zzLEp7IE60L+gJ(hh~MwAR<~NEEZ}7XLy32?v|OY8H6-xg-Ro65+5zWN zoMEWSf5A!q%;?jC4PRGA! z+~L)6S{gxN=~pKnUL!z3OCEGGYDf4p*x7Xrj`B!~v+~85UO#r#TgI{Ljx3q3v?^2% z+f2dTWShAyvXG~oeEkb*%KH6RFw|p9-IhziC8BT&%_k|Y`Rx#5`&`*{W?G=w zvl+VVz3*6RV1{jZL4tB=D>#S<-+N9~&Pa6of5>UyQ~T|5gmx&(BgkDhe901y)@w#C z)3f8u^Qu6L;eAi4tn^)8jI43yp2wmHjwt(rha@vKUfQ)i$|h3x!fM%~h17(Kjm6z` zkirJHH$Jb-2WeYkFOh!{L$_dE*KJw^UiSV{s*tL ze;~}Tv{fNP13{|PeN&N#&|dR5$Rj9xJint@BrhaY^M0a~XuA&_JddO-iSH!WpoN4B zA3FNG+tz-1i+iFfXoE!~(X`2?xn}93;YWy4Alz!>2FOhp|8(3;j}uPBKX8KMg84C$#r{MGWuMY~k#t%Plvb(2IYNKM5R8=Dl5aJL8f@RXl%Fsd>W*G8c zf0>~_)zbmzVF02j9r!IiR%%_SK9`Cq4UrHROEjF&o+1Hw1Ae+K1gF*_UGeqPf8E5e zA5s*2i;b|o@zak?w}a@=N;Ho5%0X??y>k<@v?!Xp_3# zp+bMubsRh%qqtv`Rl6`=td5WTkd-2RgaTBsJ$)>a?G8d+arj)19%_27Lb1*g=b4DR zKTvz5uIR&;tuqUAZa#M>R@*F6f8(S!jdZn+htnGDNZK<0HmPSL`W2V32%ETr< z@A4SJ?K*ea&fnKXuk~|GfPv^fiDK7?O^?v~s)tEVsg`l@+!8F-u_AtZY)^+cEdR9| z8_3fH!wbzVD8rbAlN)Nt6e0=w2qqRLFYtW9)o`Q0`fBn9wK)KS^Ye;5fAKs|N#_=I z!W$)9nMCjtLPV@pmP`gzxOib+A78rH;hJ3Y@bq(Znu^a_Hxnpbb@7 zo*ll{y^z(aOu_VVI)0{&EzBb=(X)-RdNoxLTlzwye2Yq62>}Ph3j+>yj6~JOL_LM2 zK0wm^xtTM1`1)@PR=B7yb*+^QNV3a?qcED zlFGy#tl_$se?CAwue?`s-1~-~Aq#TU;DFr3fqPP>$U41{eZp75hWNCzI6M0w@3gZ< z%LiI)(^CVhz{M`sv+^`>R2KgujJuGmG+#JbtXoEDi(#OwQQs@WEczZ!huS-{L zWCb~ht%qUmZHM9|^MGMu@}pnZ%hMLYC)L01-5f){d#`JL(4hYIfwh*(Npas17FJ!k z_1(*miAW^RS5CZFb?=RgSH`n}N^?1~Sn0U8Y5R;(5=m!7X}yiGvH9C9D`F&AlROs@ znu6zpe@t|Rg%O24F_IEuZ>+6x+L*)KC>4Gia=i&NM5Sp}3`>(rWWpTF?evceKZGBs zcUPB|@I=NW=frGmh{IdCr1a&i4f?A+>8<)w+hVh*Mk4xQQL6Yl#A{K|;`K<}3Iddv zgQlfU2eU2Mp1Ob^h z^!D%uc0i84s6M}>GhQ?WG!B(C{scEQCdid`oTK`&#gfK7#W$Jy@=_E{`mIHCa*wYj zMVW#*LE-&6Ovw!yb!A>QqC2)*KcTtC;o%Hy%hP*wUAVGh4-@1pbM0Vn-sic(kieR* ze}ufn*mpEW%6?;1V$xrUMWfBX%N`#8 zz`gQx?1$d?YIi{oJvOWG7=9p3l!2P(V&D`i4;}Xt&fi_p!%rrvgT3BtSQWM>BxZLd zzDag-vg>Y9$egj}W&fQDLw2PAlYY%@f4@`}H^s%LQ#08-UrPoa}jA9F7Q z%{tUrPDZ9=w%FZ~iZBB!W;poLzjbjBBnoLW8)18)8p}+jss#wwU2t_C_Tvf_M z#-wtE?XXW??UpWSqOH}`2^uy&e>zPTgeQ7vy#Z%vb1}&S$2zI;ec8fHJbRQgYyKUf zwSr+SA_>BgH!H3BJ2|;G=}8-LuKZ%25 zjSXlPDA4?m!cLQ~0zXb~o^%faCW_@(`JW}%EC*ibr)HGGNQnc?_*y-`hOaB&sk}p; zB2>1hK4QMR9c=;Q-z1wPKL2HfMOo$GF9k7!Q8ZDJ~a&_%F)sy~J!(s-}61$CMUt0cy{M$-X6Wb=Y-+BPz z<|eou483coM77Q&$+rfsoPdI*chF7e_T+c1tO`uk z9T`#cAg7%B0e?BIm;`@ySTjRU%t);Qs2=2D+nt304m`O@R7}A$5<}eM5Zp6T_ z^jl}={oX^mpfLgH*cOVHciFdegZD{e8yYb~JRd0bt`pz67w{aKYRZ3f7+F#4G3NB2 zx~+uCN5zU$AZ~XvE!`=OA!cAG_&NhiauUyApxB;-I;));f4oFdJ3>{`pU%0A*NE&{ zTgXOCX}D%K2o>y8YWk*-!`oKbJd=GCubf2%2N+Vl-TdZH$NYUIn0bR1%#? z1NySeFv5gOMV;#~nW_DVN-u>%O0v72mu30O*5XtEO?tVFdK%N=qJ2ddF)LeaU3C$^ zpSe_mi}P2+Wd$g9X3S(DWnift5l_3s&&>K$Jc19`fAV`t_xRA}yYHuQn_;4olwhu{ z4!sy_7+v~o@ygiMpnYD|ler9|2at*yBzSXC){-7oqQInNZ-xWos@hV<$XSSOJ|6$?A>C*8!lc9f1g&ObiXlL z#11WKe?}OLeiXhJ9toz1e0FCS(++N|ad^#TDVevrni@U4siU(sh>LCaGbAQr&L^dhhnJf=0}R7;R`6UC`2HbITqXe{ZT8T&f72FN9>;L5lV!h`?0W!GvQl zE2Zp+5E2-z;(K!BC9v$7D|jQsL1^EdG2X-@Y>n^M=@POVFyJl(tB4$Adq7IB$R1#l ztGef~LG#c&qSoNSg=Bt3+Dc1NX6}6b;LA`bq`{@%pop@sDzhtKGcAo|@|1W=k{Am_ ze=xY@@ZeVO>Vjqy!i$Z7$SuLVfb)?|d(45gC`k{{L{yJkNY3=j?#~QM*YSAGQ-pEj zP3w+K{&~xptv_CQX~ITC+-T%_Y_mv_CX(_sJa*_pMenD0nANpe8y5=ux(oM0$j4sx zGZk&|_R<_oWey?B)eAWnb{shFxt&%Yg_pFJsD@zWlb_+*oJTR}eR9eC zR?1qz&yPuPHNFt|znU$I!~bKPW}K#;ulE{fgsHL7|8Yg{k#CqGFSL$UUY`W^B5J6$5bRdj#nsq z#7=o~ph9~~v}exu$@{4$AjOxMf3*f2O^W0SE}>_D$`af}KiUg_M`7Ai`#Bf)B~LW_cgclL+s&Pjopt>a8A8mlGux7%}gBlln1HrG!@` zxY*jlxK)+qCidwk_GurXnDR1syj2s=&=qtsUqxtNGwv#g^!S}ODAX≥mH{s?0LS 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 diff --git a/doc/tutorial/tutorial.tex b/doc/tutorial/tutorial.tex index 2045d77da..5860ca888 100644 --- a/doc/tutorial/tutorial.tex +++ b/doc/tutorial/tutorial.tex @@ -61,6 +61,7 @@ \section{Installing STLINK} \begin{itemize} \item libusb-1.0 \item pkg-config +\item autotools \end{itemize} \paragraph{} @@ -79,30 +80,27 @@ \section{Installing STLINK} \begin{small} \begin{lstlisting}[frame=tb] $> cd stlink.git -$> make +$> ./autogen.sh +$> ./configure +$> make \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). +\item a GDB server (stlink.git/st-util), +\item a flash manipulation tool (stlink.git/st-flash). \end{itemize} \newpage -\section{Building and running a program in SRAM} +\section{Using the GDB server} \paragraph{} -A simple LED blinking example is provided in the example directory. It is built using:\\ -\begin{small} -\begin{lstlisting}[frame=tb] -cd stlink.git/example/blink ; -PATH=$TOOLCHAIN_PATH/bin:$PATH make -\end{lstlisting} -\end{small} -This builds three files, one for each of the Discovery boards currently -available, linked to run from SRAM. (So no risk of overwriting anything you didn't mean to) -These blink examples can safely be used to verify that: +This assumes you have got the libopencm3 project downloaded in [ocm3]. The +libopencm3 project has some good, reliable examples for each of the Discovery boards. + +Even if you don't plan on using libopencm3, the examples they provide will help you +verify that: \begin{itemize} \item Your installed toolchain is capable of compiling for cortex M3/M4 targets @@ -131,7 +129,7 @@ \section{Building and running a program in SRAM} Then, GDB can be used to interact with the kit:\\ \begin{small} \begin{lstlisting}[frame=tb] -$> $TOOLCHAIN_PATH/bin/arm-none-eabi-gdb +$> $TOOLCHAIN_PATH/bin/arm-none-eabi-gdb example_file.elf \end{lstlisting} \end{small} @@ -139,99 +137,73 @@ \section{Building and running a program in SRAM} From GDB, connect to the server using:\\ \begin{small} \begin{lstlisting}[frame=tb] -$> target extended localhost:4242 +(gdb) target extended localhost:4242 \end{lstlisting} \end{small} \paragraph{} -By default, the program was linked such that the base address is 0x20000000. From the architecture -memory map, GDB knows this address belongs to SRAM. To load the program in SRAM, simply use:\\ +GDB has memory maps for as many chips as it knows about, and will load your project +into either flash or SRAM based on how the project was linked. Linking projects +to boot from SRAM is beyond the scope of this document. + +Because of these built in memory maps, after specifying the .elf at the command line, now +we can simply "load" the target:\\ \begin{small} \begin{lstlisting}[frame=tb] -$> # Choose one as appropriate for your Discovery kit -$> load blink_32L.elf | load blink_32VL.elf | load blink_F4.elf +(gdb) load \end{lstlisting} \end{small} \paragraph{} -GDB automatically set the PC register to the correct value, 0x20000000 in this case. Then, you -can run the program using:\\ +st-util will load all sections into their appropriate addresses, and "correctly" set the PC +register. So, to run your freshly loaded program, simply "continue"\\ \begin{small} \begin{lstlisting}[frame=tb] -$> continue +(gdb) continue \end{lstlisting} \end{small} \paragraph{} -All the LEDs on the board should now be blinking in time (those leds are near the user and reset buttons). +Your program should now be running, and, if you used one of the blinking examples from +libopencm3, the LEDs on the board should be blinking for you. \newpage \section{Building and flashing a program} \paragraph{} -FLASH memory reading and writing is done by a separate tool, as shown below:\\ +If you want to simply flash binary files to arbitrary sections of memory, or +read arbitary addresses of memory out to a binary file, use the st-flash tool, +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 v1 out.bin 0x8000000 4096 +$> ./st-flash read v1 out.bin 0x8000000 4096 # stlinkv2 command -$> ./flash read out.bin 0x8000000 4096 +$> ./st-flash read out.bin 0x8000000 4096 # stlinkv1 command to write the file in.bin into flash -$> ./flash write v1 in.bin 0x8000000 +$> ./st-flash write v1 in.bin 0x8000000 # stlinkv2 command -$> ./flash write in.bin 0x8000000 +$> ./st-flash write in.bin 0x8000000 \end{lstlisting} \end{small} \paragraph{} -A LED blinking example is provided:\\ +Of course, you can use this instead of the gdb server, if you prefer. Just remember +to use the ".bin" image, rather than the .elf file.\\ \begin{small} \begin{lstlisting}[frame=tb] -# build the example, resulting in blink.bin -$> cd stlink.git/example/blink_flash -$> PATH=$TOOLCHAIN_PATH:$PATH make CONFIG_STM32L_DISCOVERY=1 # write blink.bin into FLASH -$> sudo ./flash write blink.bin 0x08000000 +$> [sudo] ./st-flash write fancy_blink.bin 0x08000000 \end{lstlisting} \end{small} \paragraph{} Upon reset, the board LEDs should be blinking. -\newpage -\section{Building and installing the CHIBIOS kernel} -\paragraph{} -CHIBIOS is an open source RTOS. More information can be found on the project website: -\begin{center} -http://www.chibios.org/dokuwiki/doku.php -\end{center} - -\paragraph{} -It supports several boards, including the STM32L DISCOVERY kit: -\begin{center} -http://www.chibios.org/dokuwiki/doku.php?id=chibios:articles:stm32l\_discovery -\end{center} - -\paragraph{} -The installation procedure is detailed below:\\ -\begin{small} -\begin{lstlisting}[frame=tb] -# checkout and build CHIBIOS for STM32L DISCOVERY kits -svn checkout https://chibios.svn.sourceforge.net/svnroot/chibios/trunk -cd chibios/trunk/demos/ARMCM3-STM32L152-DISCOVERY -PATH=$TOOLCHAIN_PATH:$PATH make - -# flash the image into STM32L -sudo ./flash write build/ch.bin 0x08000000 -\end{lstlisting} -\end{small} - \newpage \section{Notes} @@ -242,36 +214,7 @@ \subsection{Disassembling THUMB code in GDB} if you want to disassemble the code at 0x20000000, use:\\ \begin{small} \begin{lstlisting}[frame=tb] -$> disassemble 0x20000001 -\end{lstlisting} -\end{small} - - -\subsection{libstm32l\_discovery} -\paragraph{} -The repository includes the STM32L discovery library source code from ST original firmware packages, -available here:\\ -\begin{small} -\begin{lstlisting}[frame=tb] -http://www.st.com/internet/evalboard/product/250990.jsp#FIRMWARE -\end{lstlisting} -\end{small} - -\paragraph{} -It is built using:\\ -\begin{small} -\begin{lstlisting}[frame=tb] -$> cd stlink.git/example/libstm32l_discovery/build -$> make -\end{lstlisting} -\end{small} - -\paragraph{} -An example using the library can be built using:\\ -\begin{small} -\begin{lstlisting}[frame=tb] -$> cd stlink.git/example/lcd -$> make +(gdb) disassemble 0x20000001 \end{lstlisting} \end{small} @@ -283,6 +226,9 @@ \section{References} documentation related to the STM32L mcu \item http://www.st.com/internet/evalboard/product/250990.jsp\\ documentation related to the STM32L discovery kit +\item http://www.libopencm3.org\\ + libopencm3, a project providing a firmware library, with solid examples for Cortex + M3, M4 and M0 processors from any vendor. \end{itemize} \end{document} From 406ac425028bd0ea5f01555521ef05eee84b0825 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 3 May 2012 22:05:32 +0000 Subject: [PATCH 0173/1435] Display proper final page write count for 32L --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 08bd0bb4d..a4e2a5370 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1323,7 +1323,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uns if (sl->verbose >= 1) { /* show progress. writing procedure is slow and previous errors are misleading */ - fprintf(stdout, "\r%3u/%u halfpages written", count, num_half_pages); + fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); fflush(stdout); } while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) { From 5b6eb51bd22c44fa8d9e70519b561dc64c37f6c9 Mon Sep 17 00:00:00 2001 From: Michael Sparmann Date: Tue, 3 Jul 2012 15:10:07 +0200 Subject: [PATCH 0174/1435] Fix "monitor reset" gdb command being misinterpreted as "monitor resume" by checking for the full word, not just the first two chars. --- gdbserver/gdb-server.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 7a525d535..f60aadcf4 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -163,7 +163,7 @@ int main(int argc, char** argv) { if(sl == NULL) return 1; break; } - + printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); sl->verbose=0; @@ -249,7 +249,7 @@ char* make_memory_map(stlink_t *sl) { } -/* +/* * DWT_COMP0 0xE0001020 * DWT_MASK0 0xE0001024 * DWT_FUNCTION0 0xE0001028 @@ -282,7 +282,7 @@ static void init_data_watchpoints(stlink_t *sl) { #endif // set trcena in debug command to turn on dwt unit - stlink_write_debug32(sl, 0xE000EDFC, + stlink_write_debug32(sl, 0xE000EDFC, stlink_read_debug32(sl, 0xE000EDFC) | (1<<24)); // make sure all watchpoints are cleared @@ -695,31 +695,31 @@ int serve(stlink_t *sl, int port) { } else { params = separator + 1; } - - if (!strncmp(params,"7265",4)) {// resume + + if (!strncmp(params,"726573756d65",12)) {// resume #ifdef DEBUG printf("Rcmd: resume\n"); #endif stlink_run(sl); reply = strdup("OK"); - } else if (!strncmp(params,"6861",4)) { //half + } else if (!strncmp(params,"68616c74",8)) { //halt reply = strdup("OK"); - + stlink_force_debug(sl); #ifdef DEBUG printf("Rcmd: halt\n"); #endif - } else if (!strncmp(params,"7265",4)) { //reset + } else if (!strncmp(params,"7265736574",10)) { //reset reply = strdup("OK"); - + stlink_force_debug(sl); stlink_reset(sl); init_code_breakpoints(sl); init_data_watchpoints(sl); - + #ifdef DEBUG printf("Rcmd: reset\n"); #endif @@ -729,7 +729,7 @@ int serve(stlink_t *sl, int port) { #endif } - + } if(reply == NULL) From e8601c816ae61ae0a5fa2a5c176c75e5dc523ac1 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Sun, 8 Jul 2012 15:49:36 -0400 Subject: [PATCH 0175/1435] Updated .gitignore to include test binaries --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index cf2f1a448..6ed8efce9 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,8 @@ config.status compile st-flash st-util +test_usb +test_sg *.deps* *.dirstamp *.a From a71f48db1055dd7cbd73260e089a63e86afaebb8 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Sun, 8 Jul 2012 21:04:30 -0400 Subject: [PATCH 0176/1435] Read Cortex M4F floating point registers Since the ST-LINK does not seem to support reading these registers, I have implemented functions that will manually request these registers and add them to the reg struct. As of now, these functions are just backend and are not integrated into anything, however I have verified that they work with the STM32F407 DISCOVERY board. --- src/stlink-common.c | 17 +++++++++++++++++ src/stlink-common.h | 6 ++++++ src/stlink-usb.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index a4e2a5370..359d39adc 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -577,6 +577,11 @@ void stlink_read_all_regs(stlink_t *sl, reg *regp) { sl->backend->read_all_regs(sl, regp); } +void stlink_read_all_unsupported_regs(stlink_t *sl, reg *regp) { + DLOG("*** stlink_read_all_unsupported_regs ***\n"); + sl->backend->read_all_unsupported_regs(sl, regp); +} + void stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) { DLOG("*** stlink_write_reg\n"); sl->backend->write_reg(sl, reg, idx); @@ -594,6 +599,18 @@ void stlink_read_reg(stlink_t *sl, int r_idx, reg *regp) { sl->backend->read_reg(sl, r_idx, regp); } +void stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { + DLOG("*** stlink_read_unsupported_reg\n"); + DLOG(" (%d) ***\n", r_idx); + + if (r_idx != 0x21 || r_idx < 0x40 || r_idx > 0x5f) { + fprintf(stderr, "Error: register address must be in [0x21, 0x40..0x5f]\n"); + return; + } + + sl->backend->read_unsupported_reg(sl, r_idx, regp); +} + unsigned int is_core_halted(stlink_t *sl) { /* return non zero if core is halted */ stlink_status(sl); diff --git a/src/stlink-common.h b/src/stlink-common.h index ee59094b6..c982b3df6 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -238,11 +238,13 @@ extern "C" { typedef struct { uint32_t r[16]; + uint32_t s[32]; uint32_t xpsr; uint32_t main_sp; uint32_t process_sp; uint32_t rw; uint32_t rw2; + uint32_t fpscr; } reg; typedef uint32_t stm32_addr_t; @@ -295,6 +297,8 @@ extern "C" { void (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); void (*read_all_regs) (stlink_t *sl, reg * regp); void (*read_reg) (stlink_t *sl, int r_idx, reg * regp); + void (*read_all_unsupported_regs) (stlink_t *sl, reg *regp); + void (*read_unsupported_reg) (stlink_t *sl, int r_idx, reg *regp); void (*write_reg) (stlink_t *sl, uint32_t reg, int idx); void (*step) (stlink_t * stl); int (*current_mode) (stlink_t * stl); @@ -360,7 +364,9 @@ extern "C" { void stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); void stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); void stlink_read_all_regs(stlink_t *sl, reg *regp); + void stlink_read_all_unsupported_regs(stlink_t *sl, reg *regp); void stlink_read_reg(stlink_t *sl, int r_idx, reg *regp); + void stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp); void stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); void stlink_step(stlink_t *sl); int stlink_current_mode(stlink_t *sl); diff --git a/src/stlink-usb.c b/src/stlink-usb.c index a25f7ec55..397723c25 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -576,6 +576,38 @@ void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { } } +void _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { + uint32_t r; + + sl->q_buf[0] = (unsigned char) r_idx; + for (int i = 1; i < 4; i++) { + sl->q_buf[i] = 0; + } + + _stlink_usb_write_mem32(sl, 0xE000EDF4, 4); + _stlink_usb_read_mem32(sl, 0xE000EDF8, 4); + + r = read_uint32(sl->q_buf, 0); + DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); + + switch (r_idx) { + case 0x21: + regp->fpscr = r; + break; + default: + regp->s[r_idx - 0x40] = r; + break; + } +} + +void _stlink_usb_read_all_unsupported_regs(stlink_t *sl, reg *regp) { + _stlink_usb_read_unsupported_reg(sl, 0x21, regp); + + for (int i = 0; i < 32; i++) { + _stlink_usb_read_unsupported_reg(sl, 0x40+i, regp); + } +} + void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; @@ -616,6 +648,8 @@ stlink_backend_t _stlink_usb_backend = { _stlink_usb_write_mem8, _stlink_usb_read_all_regs, _stlink_usb_read_reg, + _stlink_usb_read_all_unsupported_regs, + _stlink_usb_read_unsupported_reg, _stlink_usb_write_reg, _stlink_usb_step, _stlink_usb_current_mode, From b1e65ea367a450e8a37584cdee334562149b2a7c Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Sun, 8 Jul 2012 23:04:35 -0400 Subject: [PATCH 0177/1435] Extra registers integration with GDB The support for extra registers has been added to GDB. Now all core registers can be read from GDB. Write support has not yet been added. --- gdbserver/gdb-server.c | 99 +++++++++++++++++++++++++++++++++++++++++- src/stlink-common.c | 15 +++++-- src/stlink-common.h | 4 ++ src/stlink-usb.c | 7 +++ 4 files changed, 121 insertions(+), 4 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index f60aadcf4..789b609e1 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -192,6 +192,71 @@ int main(int argc, char** argv) { return 0; } +static const char* const target_description_F4 = + "" + "" + "" + " arm" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + static const char* const memory_map_template_F4 = "" "chip_id==STM32_CHIPID_F4) { + reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); + } + else { + reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); + } } else if(!strcmp(queryName, "Xfer")) { char *type, *op, *__s_addr, *s_length; char *tok = params; @@ -674,6 +744,9 @@ int serve(stlink_t *sl, int port) { if(!strcmp(type, "memory-map") && !strcmp(op, "read")) data = current_memory_map; + if(!strcmp(type, "features") && !strcmp(op, "read")) + data = target_description_F4; + if(data) { unsigned data_length = strlen(data); if(addr + length > data_length) @@ -881,6 +954,30 @@ int serve(stlink_t *sl, int port) { } else if(id == 0x19) { stlink_read_reg(sl, 16, ®p); myreg = htonl(regp.xpsr); + } else if(id == 0x1A) { + stlink_read_reg(sl, 17, ®p); + myreg = htonl(regp.main_sp); + } else if(id == 0x1B) { + stlink_read_reg(sl, 18, ®p); + myreg = htonl(regp.process_sp); + } else if(id == 0x1C) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.control); + } else if(id == 0x1D) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.faultmask); + } else if(id == 0x1E) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.basepri); + } else if(id == 0x1F) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.primask); + } else if(id >= 0x20 && id < 0x40) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.s[id-0x20]); + } else if(id == 0x40) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.fpscr); } else { reply = strdup("E00"); } diff --git a/src/stlink-common.c b/src/stlink-common.c index 359d39adc..1e9c01114 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -600,15 +600,24 @@ void stlink_read_reg(stlink_t *sl, int r_idx, reg *regp) { } void stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { + int r_convert; + DLOG("*** stlink_read_unsupported_reg\n"); DLOG(" (%d) ***\n", r_idx); - if (r_idx != 0x21 || r_idx < 0x40 || r_idx > 0x5f) { - fprintf(stderr, "Error: register address must be in [0x21, 0x40..0x5f]\n"); + /* Convert to values used by DCRSR */ + if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ + r_convert = 0x14; + } else if (r_idx == 0x40) { /* FPSCR */ + r_convert = 0x21; + } else if (r_idx >= 0x20 && r_idx < 0x40) { + r_convert = 0x40 + (r_idx - 0x20); + } else { + fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); return; } - sl->backend->read_unsupported_reg(sl, r_idx, regp); + sl->backend->read_unsupported_reg(sl, r_convert, regp); } unsigned int is_core_halted(stlink_t *sl) { diff --git a/src/stlink-common.h b/src/stlink-common.h index c982b3df6..5a82e1f49 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -244,6 +244,10 @@ extern "C" { uint32_t process_sp; uint32_t rw; uint32_t rw2; + uint8_t control; + uint8_t faultmask; + uint8_t basepri; + uint8_t primask; uint32_t fpscr; } reg; diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 397723c25..fdd636b61 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -576,6 +576,7 @@ void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { } } +/* See section C1.6 of the ARMv7-M Architecture Reference Manual */ void _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { uint32_t r; @@ -591,6 +592,12 @@ void _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); switch (r_idx) { + case 0x14: + regp->primask = (uint8_t) (r & 0xFF); + regp->basepri = (uint8_t) ((r>>8) & 0xFF); + regp->faultmask = (uint8_t) ((r>>16) & 0xFF); + regp->control = (uint8_t) ((r>>24) & 0xFF); + break; case 0x21: regp->fpscr = r; break; From c6274f026b7848cf45029eccc327f8215738a743 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Mon, 9 Jul 2012 01:00:53 -0400 Subject: [PATCH 0178/1435] Write to extra (FP, etc) registers from GDB The extra registers added in my previous commit can now be modified from within GDB. Since the ST-LINK does not support accessing these registers, a workaround was used from reading an writing to them. That is, the Debug Core Register Selector Register (DCRSR) can be written with the register requested, and it will be read/written to/from the Debug Core Register Data Register (DCRDR). The standard ST-LINK memory access functions are used to make these accesses. A target descriptor XML file is sent to GDB from the server, which tells GDB which registers exist on the target. This is only supported for the STM32F4, and has only been tested on the STM32F4DISCOVERY. I tested st-util on an STM32L-DISCOVERY and my changes did not seem to interfere with its operation. --- AUTHORS | 3 ++- gdbserver/gdb-server.c | 16 +++++++++++++++ src/stlink-common.c | 21 ++++++++++++++++++++ src/stlink-common.h | 4 ++++ src/stlink-usb.c | 44 ++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 85 insertions(+), 3 deletions(-) diff --git a/AUTHORS b/AUTHORS index 1096c1735..5c52c64f3 100644 --- a/AUTHORS +++ b/AUTHORS @@ -14,4 +14,5 @@ bravikov@gmail.com jnosky - codegrinder69@hotmail.com marpe@mimuw.edu.pl marco.cassinerio@gmail.com -jserv@0xlab.org \ No newline at end of file +jserv@0xlab.org +michael@pratt.im diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 789b609e1..ae06952bf 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -999,6 +999,22 @@ int serve(stlink_t *sl, int port) { stlink_write_reg(sl, ntohl(value), reg); } else if(reg == 0x19) { stlink_write_reg(sl, ntohl(value), 16); + } else if(reg == 0x1A) { + stlink_write_reg(sl, ntohl(value), 17); + } else if(reg == 0x1B) { + stlink_write_reg(sl, ntohl(value), 18); + } else if(reg == 0x1C) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x1D) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x1E) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x1F) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg >= 0x20 && reg < 0x40) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x40) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); } else { reply = strdup("E00"); } diff --git a/src/stlink-common.c b/src/stlink-common.c index 1e9c01114..a86d98549 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -620,6 +620,27 @@ void stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { sl->backend->read_unsupported_reg(sl, r_convert, regp); } +void stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg *regp) { + int r_convert; + + DLOG("*** stlink_write_unsupported_reg\n"); + DLOG(" (%d) ***\n", r_idx); + + /* Convert to values used by DCRSR */ + if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ + r_convert = r_idx; /* The backend function handles this */ + } else if (r_idx == 0x40) { /* FPSCR */ + r_convert = 0x21; + } else if (r_idx >= 0x20 && r_idx < 0x40) { + r_convert = 0x40 + (r_idx - 0x20); + } else { + fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); + return; + } + + sl->backend->write_unsupported_reg(sl, val, r_convert, regp); +} + unsigned int is_core_halted(stlink_t *sl) { /* return non zero if core is halted */ stlink_status(sl); diff --git a/src/stlink-common.h b/src/stlink-common.h index 5a82e1f49..2e30e71c3 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -112,6 +112,8 @@ extern "C" { /* Cortex™-M3 Technical Reference Manual */ /* Debug Halting Control and Status Register */ #define DHCSR 0xe000edf0 +#define DCRSR 0xe000edf4 +#define DCRDR 0xe000edf8 #define DBGKEY 0xa05f0000 /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ @@ -303,6 +305,7 @@ extern "C" { void (*read_reg) (stlink_t *sl, int r_idx, reg * regp); void (*read_all_unsupported_regs) (stlink_t *sl, reg *regp); void (*read_unsupported_reg) (stlink_t *sl, int r_idx, reg *regp); + void (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, reg *regp); void (*write_reg) (stlink_t *sl, uint32_t reg, int idx); void (*step) (stlink_t * stl); int (*current_mode) (stlink_t * stl); @@ -371,6 +374,7 @@ extern "C" { void stlink_read_all_unsupported_regs(stlink_t *sl, reg *regp); void stlink_read_reg(stlink_t *sl, int r_idx, reg *regp); void stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp); + void stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, reg *regp); void stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); void stlink_step(stlink_t *sl); int stlink_current_mode(stlink_t *sl); diff --git a/src/stlink-usb.c b/src/stlink-usb.c index fdd636b61..277431a87 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -585,8 +585,8 @@ void _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { sl->q_buf[i] = 0; } - _stlink_usb_write_mem32(sl, 0xE000EDF4, 4); - _stlink_usb_read_mem32(sl, 0xE000EDF8, 4); + _stlink_usb_write_mem32(sl, DCRSR, 4); + _stlink_usb_read_mem32(sl, DCRDR, 4); r = read_uint32(sl->q_buf, 0); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); @@ -608,6 +608,7 @@ void _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { } void _stlink_usb_read_all_unsupported_regs(stlink_t *sl, reg *regp) { + _stlink_usb_read_unsupported_reg(sl, 0x14, regp); _stlink_usb_read_unsupported_reg(sl, 0x21, regp); for (int i = 0; i < 32; i++) { @@ -615,6 +616,44 @@ void _stlink_usb_read_all_unsupported_regs(stlink_t *sl, reg *regp) { } } +/* See section C1.6 of the ARMv7-M Architecture Reference Manual */ +void _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg *regp) { + if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ + /* These are held in the same register */ + _stlink_usb_read_unsupported_reg(sl, 0x14, regp); + + val = (uint8_t) (val>>24); + + switch (r_idx) { + case 0x1C: /* control */ + val = (((uint32_t) val) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) regp->primask); + break; + case 0x1D: /* faultmask */ + val = (((uint32_t) regp->control) << 24) | (((uint32_t) val) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) regp->primask); + break; + case 0x1E: /* basepri */ + val = (((uint32_t) regp->control) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) val) << 8) | ((uint32_t) regp->primask); + break; + case 0x1F: /* primask */ + val = (((uint32_t) regp->control) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) val); + break; + } + + r_idx = 0x14; + } + + write_uint32(sl->q_buf, val); + + _stlink_usb_write_mem32(sl, DCRDR, 4); + + sl->q_buf[0] = (unsigned char) r_idx; + sl->q_buf[1] = 0; + sl->q_buf[2] = 0x01; + sl->q_buf[3] = 0; + + _stlink_usb_write_mem32(sl, DCRSR, 4); +} + void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; @@ -657,6 +696,7 @@ stlink_backend_t _stlink_usb_backend = { _stlink_usb_read_reg, _stlink_usb_read_all_unsupported_regs, _stlink_usb_read_unsupported_reg, + _stlink_usb_write_unsupported_reg, _stlink_usb_write_reg, _stlink_usb_step, _stlink_usb_current_mode, From f300f74a0c3e0f66feae6a270ca8b01436ef28d9 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Mon, 9 Jul 2012 11:06:50 -0400 Subject: [PATCH 0179/1435] Fix the stlink-sg backend to leave space for new functions --- src/stlink-sg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 4cae3ee11..ae610bac7 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -872,6 +872,9 @@ stlink_backend_t _stlink_sg_backend = { _stlink_sg_write_mem8, _stlink_sg_read_all_regs, _stlink_sg_read_reg, + NULL, /* read_all_unsupported_regs */ + NULL, /* read_unsupported_regs */ + NULL, /* write_unsupported_regs */ _stlink_sg_write_reg, _stlink_sg_step, _stlink_sg_current_mode, From ca0f89c20bb090daf92e2a2498f8324947c90ea4 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Mon, 9 Jul 2012 11:08:55 -0400 Subject: [PATCH 0180/1435] Fix build warning --- src/stlink-common.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index a86d98549..e142233f7 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -936,7 +936,9 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) } /* Ignore NULL Bytes at end of file */ - ftruncate(fd, size - num_empty); + if (!ftruncate(fd, size - num_empty)) { + error = -1; + } /* success */ error = 0; @@ -1452,7 +1454,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned for(off = 0; off < len;) { size_t size = len - off > 0x8000 ? 0x8000 : len - off; - printf("size: %u\n", size); + printf("size: %zu\n", size); if (run_flash_loader(sl, &fl, addr + off, base + off, size) == -1) { WLOG("run_flash_loader(%#zx) failed! == -1\n", addr + off); From 684d76afa0f36d9c9cc3974f11fd42aa95e22c02 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Sun, 19 Aug 2012 12:19:25 -0400 Subject: [PATCH 0181/1435] Fix watchpoint support Setting of watchpoints was nested inside of a case statement, so it would only run for that case, even though it supports all cases. --- gdbserver/gdb-server.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index ae06952bf..e6368ea31 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -1108,13 +1108,14 @@ int serve(stlink_t *sl, int port) { wf = WATCHREAD; } else { wf = WATCHACCESS; - if(add_data_watchpoint(sl, wf, addr, len) < 0) { - reply = strdup("E00"); - } else { - reply = strdup("OK"); - break; - } } + + if(add_data_watchpoint(sl, wf, addr, len) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + break; + } } default: From e197cd8e2e71bfdfb57ee21aaba0eeb2d189b494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=A4rtner?= Date: Wed, 22 Aug 2012 15:33:19 +0200 Subject: [PATCH 0182/1435] Added kext for os x 10.8 I added a kext for mountain lion to osx.tar.gz and modified install.sh to use the right one or fail if no suitable kext is available. --- stlinkv1_macosx_driver/osx.tar.gz | Bin 23264 -> 23437 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/stlinkv1_macosx_driver/osx.tar.gz b/stlinkv1_macosx_driver/osx.tar.gz index 6e7bb275ba87719974b35d6ddb051c74b6cb914e..a4af6670bd8f9521f359104e1911fc91c57ad871 100644 GIT binary patch literal 23437 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

~qEFlG{Xb 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 d_krS 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�_R&V`)I1TVxBwpP-mqV% ze`eFhI-vhC?3>{M8Ae{Vl=aw}UN$-tEQQN(MyXBHpKh0M? zink+xta;M2WY%UY)2FPN8T0(LGLs8+W_wq*@r_CPVH24q^hNCZD+x_OlASwYMNqO5 zpCo6R(T6aiHJ8xRXR#jVPR4+(EioA)63d*O_{K4LFMQLhrb8&#u4eC~I- z>*?;vd=N$XleMT^DpH45tp^M!ckCdXf*%g}g4R$&t{7?Xd!nVuF4gUp8+(x=8A!&D zuSr_jx2vtob<&V^QB7n;ZKWgYszTS2|7XMi+ccso75TTLAZaBZPXCYW>LfkwpV3jy ze?aMfYZ{O%{PUP5OZIQGiNyb>m;W~SU#|ZFTdI60{v8iC?|(&@XE6LHofQjul2+&Y zlz%6S(IZJp((0~^@Q?7I?Voy_*8d6Hf)J?+*VK|3RA-gdZX-riBT#65^j?vnRZpBd zUGTf2BEZH# zc=%}HhU+)QM*G)pUKH3_)fS|9dOeya>~Hs`n?-Fr+uasO+kLd!t?_2>R^onaoG!j; zFUqzLe9%~a^(M^YaV*!a)S6Cndaw|nxm$;2LwZ#TARPNw$VQ_}*hQ)9E;3ll)&@1# zcdpW;s8O)l)%wZjls1C(7wEKDFV)g!@-E+)UHkyq+k1Q?E_iv#&CSmRY~;#2?6)Kd zq!k@d-LzF}pYNXal&@FciCA4%2`)Xf>p{Yczcpq~Yh0f7Zi~-&b?;WUs{t6*Nc~JyheongiL_k5a9Z! zu1L(|1WCDQNN@}&&F(0Po$#5lUI;jzah6o&;*e-5LlNZUWt4QrpE z8~nPWFGQk7hmj2s%8pF~YD_4~oHNOSNdtufG&MZtA7SpvsLnr1?!Mo{MR*^*G0g(O ztrvGYJMNA1hhl-@54%bo54*MF4?yHu|5@O=GX+kd$JZa%FL=S&Vji8-bgPrPfbFIA zrv{r&##JCmzGG$0Ja=s@gJ~rc*&@4jwsF{nQiJtCJ1R{zu2qSQ7TyI0+P7s#_Sjk- zOYI~(abpUlw7YQVDR94p>cx^*be0lJt*F>+8G#lhSTHg$JM0MK>DrZVru?zN%FOY! z>dh+6OQZ~yT0XV|@Wco4O9%-jRyq(8jE(Y(_;C{Rjn+sd$gba!gGmsdz~WlfK8WjP z*03Y8F|E~y*y)#ljuzE#78zrA3UaC~&W#44#)Gx+YAidAKp<4Fu-Ebak{A+RExu?h z$FN!vG$#{4bAc`^&axKgs>`;Is}X6bUXc?cTA@uZ&mO8a?_MrELK+{1>&Z7_in$zt zzpQ&X6chU31J29z`M_}I1EKa_)*p7~N&z>-v;3azA6&N|LI48b2XN;n>wQv!?-3c% z+xRK*?B$!#QFuJ8^Tb*y5K?gvcz)YsubmALslqP?2ONFwDvS|*(TC*gh*OmivsBm} z0OfOV0>o<0RDc1A6=O&z^F-s9pOsInRlX^q1e9=mvwSt4xq~wTI#%KK)#dt&Hj=V+ zCOz%6cpRMVrP1{o#?sZjZONe%7@e-NY=}y}PVzANU787lF`TK>h-T-m6F%`8@AE2t z9~&`K`?^blH`iFr`4>i0KNHl2WLHwuLA|W@$OU%rX3f>#{~>+g3P*~I(lj>Dn557 z|MX?oUwi{rXsXHI2Sj)x8t<(aj9ekN1ZbXAiLqld7e}zO^ghA8x(GGw09R}L=R%&p zg5L|G?E;kkq7h3#{Dbx7*V9V>x#s83Ro89S%sZ|`9IbpHw5R14lFAoIR?3!W-O?U~ zo_-BM*tI^ozd8sPmb~OVd+ztilG`gt(Cql}p&Rk`;$zy`MeCi8{mSPogEo3a^_uVs z9>nCD!5eM-fL#KA#_L;wn8*Oq<0|!+r-O7lx_y5NfYrofd= zzhfIWQfYRRRfOu&xSm$8n=aDe8mT8%I0Yfk=Pi@-+*#Ha;lkS0ZOkD?%sfMwdaUmn z(69$@Ghw*+4s`pvAEj2pfQK6%(`iv*ac@UA?w@jp4@y;LQOKqIW{K$Z!)X|Wd?Fgw z$QAYY?y#+IduC!6fa$BJ7jv!zf<`#HY~>%MoF?sv2T>VAw#7Wx#=J!mdmR4rF!)h4 zaHkSfW5NV?E2ija{agEw%SbOhr}ANbS0_p`IJ(Rk(Ll^8a!Qy79=qea6XW}wpxubu zmAI9DI}dy2H4gCYnEk-F#9~a$6l-JVOn3Ni zVwyDDNw@a=GmrMSE0EgPn230%QA1gYU*SOC<5vXeRxHUmGuTYWIKHtA4}upoSlQ;9 zTRyet>x!@AFW5h_*tFc;KACZ64n|CapJS+KQ@zSDD|Wow*F{BZzqzn!hI)|FWhr+; zHy?8~P*J0{3AQP&9orukLz-fnH!Z(FeU7CHM8bO*E%7$YEcf_%!Irob zha3rZA`Dubu)&=jj)<6cb;Up)&k!o5=0_q3!gDV@jEe6{;`LhksX%+4Ogvhk*I`4^z(P+qto3`FO5@cX@ z$f(~@PFibkzRifGoQ7}u8Q}*X6tf&yc9g9#ETk5xfFpJw;YBoUT6j3$kJ6awBIy?* ztfw@Ln2PO>>P;JyKnFa`8mYDFR7x}iW-9C;?ju73#1P;`o6p`86TEGZDipYbyeveVP4JH1cvd&75Pcz<*zwuM9LY58H%pS zKmn8{mzoG3wlYcAz=U_KF(IO*0mLXQK_VpZ<+mRY)b|TlnMpG`!KW(K#xOlk{Gt4!0JFk6L@u7xsdp zM1ZUD0oO$k7bS+uqX%ZvQnjU|9T>RD4$6hHgf_no=%oAeW+{YED0(sm?n-Bx+`ia( zR(#$rCN#oOFx*zKo49;(y$TQ|V?FGnVNI=fLAjj|AW~1M}7jn?+BM5O6^oo{f)OqC5 zB>zdj_;D~q@!JxlWL+#BeRPqA%0*AkC(v`!%Gl|VAmV+?fis0#fG6iiI$+Q(j-2Xn z*r*pFkp0FV3Qx4*rVS)x^G`_J8UD4nk*3W@Ncv0IcD+%xcS%gS|CH;Cu9OvwJJp=) zxGmg5q8%a)O}{Zpg|YbJx2nzaZ~ghlZg6vNJqBb22i@yX7-7YdU7(6egCOmWRQjr` zb{kJPe|imyLqjcYaS!6bXQnA(IVr4hkU{j;8U?q~jFt4MX<}H(p^^7ed1yjrF*v|$ z&Br2=@^Lkp3BJi6H>*I9hyV0&nY%1;H&k1jt>aYd)fbhkm;!qhndfhU@m>#Q9tPA|8l)aTqBE-*(XHhn<2OnDmDfGX<^;>Q3$-gzi#Ev|;!; z{`qyq#{M9emFt%S^+*$HcyBc2XWc@_Vn_(KsFIk9p|VBDLz#p1LoG|W7L$pY(-?LG z9m2R>sDk~YU_B(+v z=FQHmd=!6F?W5tGty^^S0NQ9_2R0+J|!-Is_jVeFPt@%a@pui1T*?QRDs! z0G_pJJ-Vqg^C6;U&*ha|jHA}mXsHsQ09uLA)QNvbp;N;yRU6aj(L`F@( zz7RmN>XV(47VqK_sEEEfIm!Cj`-Wqbo{mc@zQK48UA0yX0RMOqgohZf^6Y~rkLQ5z zpLCh;7|Cr+b)N_7b8CqgL}oeVl#S(LO zmffKdofVOg@@1C)_oZ&eG-O8Dd9&Ky_=KY%0SXhi)BzKp5{ez&jLOY~(oyfX6Ej-^b*N+&Vp9t?1?-b4b*YTtK6itTH*uecexiqYli5qD## z5s4v&eo1w0U9lI@jh8KUT7tD=AqsWPkz5ha7kzUqK#b%Y)U{L_Z_GcSWlrtbz+8%D zLa2<0p@84o56*L~L0%ux!e#sjQtg8<@y7k+wc+O;L4l`wL=jzpRlRkMMIqV23LS;W z4PMxU|MirCn3-fIyYQJj7iopm7A}%i zm}y(HvmlVJZ&OH*eC!CM)}U$3OHDFCYKS7Q>HJkL`eV^+ayz_k$6g?1gTZk|Y^>ii ze@@r2YtcrJ(|=5&f>Lkw@tdv3zDg0t)m8mrdF-t%PT;x_G@fZXRIX}49{iwk#SHEP z@h9$<#PRY2Kkr*B2vZ5<+A*=JQoM;%*i3{<8%r}hj?irs^z;0%RB$)k_mdpdY7Ufk zC$wt|lC|3u&5l~cm#EuR?dV5#MQ-_xlguxVh~dDp3X4YVpfRV9D=K#uR$(gg4+Fl zJMYKVr(QhRLCm`{Q(JwcW-vX(8Ie|NmAqB=$QItv!@^&B+8=iBBWAmic5X*Jyal#Q zo24zTAKJ0t353)6b~lY}{QmLmmYfr#^}A^q5(~7h3(y@&s5{u5q3#{&;ZkpP` z$T3{A&y%za7uj7mGG?n&5^;4;NAiN(AXIwZ75bZQ=-e!1+L~=Zkh{tnVLZ`e&m^bX zlR?rne^QeR3=?jTN$7UXip1dV0IwBi657oEY={<@BaR$sK#!CfBt>hy7QhR#x~pJPr1XA`Ld!oNgyYniuX zW1ww3-PgR3dYFf##J6kL#1$r#`lR8$@}eNgQ@ZEjqKdsOR^qWOK18i~Ei1?B$3031 z!?$kl5I28t3$Em!NoDZsjgj)P+5(A)%UNVU?mv!R_n6nOicn`aIG|x^ULXbKw!4f_ z;)e6($X7#2#C_lD?Zx(jK?|fxACmf&glUEGvD$3WU>_xqUpnTazVO$RhUiW)CJ?-Z zeLXC+M`Uz8K!)QP0Vpx9kpp-FiUXh+3sH>(ymU*R4E@w1Uf{c&=D$<&Ma1H{h3s*N zS$*Sd(GiFo9H>+$79=#XZ;E8u?MPh+pILAJ&8k*U+p-vIPD~%$V`!0MA3yV6aqml% zagw-h3LbHO)=2n@2OeAP`90bHdNoCbldT3f5K-g9r%}x$E*YS%?f4g|s(ULUkn-QG zs==Zm&5r6VvjqX4_`Il#J?3qxT}Fe*w)&?fK0~n;HcjcxYKG@NU!EdDTaI$fQR}%0 z%G3?zzKY03^3xk>mq!qP5lY`bwCbB>P~LyhsvM#JPg)i0{l93{&U;+5lz-EzH}wCD zR>l1nt-9d)KeXz|)9`b;$8HFDnOf>Uw5p)*rTEO+tV2K>xioB8b<+!9Dqh%uhe}A> z-80tTAD+}q+vKGF#i;U~f2}CkzPYBql3It0lxA7NR1WZgl4i!GhKzIaBt!^HR|=5i z$TYGLBQ@bQk|qUQ6)rkz?_j8q`?tIiscs`||Du~qb316Hx8!-}?_a}&eTVqmW!+cY zR8xQLGOrotl}Ff3J1uAt!Qi!6Wu#L#*pB9v_l zd?~eD^G`KnQ91ciYG`({k}6BkKi!=sECQG_MuJJ({&B9y_TSO|u_VF$k2g}9e?$}M)J5fMdjG8^ zEsbhz-Sr^+fBXBd&}yQ8Z51g0lfSk#EXR}RkCL{Azl9W6ll)Udw$4A6Eb|2*)-n(_ zsiN`>=0;dLl=ky;Lso`HsH8-<$>SJ#qA3dqx@|PC*2Z#`yxQdM{(njGdT}R3!+izSWNK9)Xu`) z!h?kY!@+s%P&-e-V$*)i+J|2Y0*WF{M^3g_Sj8`vr5}*~8S&X;YjBt7iO$qAtda0` zf~;Hpa^Y*yLrZu;h~KG)iy_jyZ2NV*rDrgoy9mA?j zvC>+i3&TOb==yVFdj=*;bH30Tbl6y2Q$f&O(Z)yw<3TY?Cy6{`3}gLcxVwGdD_;{A zpDN@ktf`b5f!>i6U93GC6y|j|?EvR^tHe#6y;A43ZTG!*$mJ$@{zkDEFa_5PTmXAW zzRq8~{S4I_-?YAEW1KqyA-;dP(0P=b(T$N*`o|3b*yDN1Ru1DdY`-w}D( ze)=jb+qisuJya=Yy?-1OtpHm94U~wtYXWsakm^$b^#CkK6=2L?5Dc*fD8E^S5LgoK zcNg%-9Qr5RvWS-+<_J6B)N^X=t>82?8(0J4HU-$v*w}WdMYg`%i$Ua(-tIq+MwgH<% zp9yXedL3iUXC7o@q~to1@m~o%p7B$Cff#yY0kohO{y^|R!GN!EyQ(7ZHE5vXxM%+8 z2m1YMK?dq)0#DfqkQRi)8URc-M*1um1025DIe-Db8=(Oe9=Ae~Kpu+U zKsSH|$1M{=0`Qzrcp7L(_$LS$2PyyhI}xPp&9J{a*5>c@fB`CI{~CJzHAEuJW_#Ia z_(9dICxK1CvIO5X90ZE8!AncImP=o&13z&4BYRV!6Un2o99r6MzP%96C zhMa$$Gq6s(0$m>ZoLB)=cYo&|0Nfk3=>9O zwp%^=fOKBK1k$CqfV6%gu8U6~6Hf9cQBSZxksJC9Fr5ODP7mCL6|;;N*abJ9101G< zajzs(1Uv*|=LO`W{pk4DssMhK%v*m}1>v3|G_%;B#d!@`er^%R!TNfD7ibKHJ4}tD z3ZnQb>;o-sSJCrx;?i_??745RI8u8(WWQi71tS7F<3vgpwZzV0Q_14EgabeeD(?h7 zJq`|(KPmS7gZs>H<@R!5KcDqW{Mo)kCLRTh+O!a9Ng@K_LGV5jPWL<%iW(s5-ul2i z?}oNb;`;|mm~P$yp*9C--_!SIgKB|*qp#yVHG#MN;|Hw1D}7g{0Pju79iNrm-kaP4 zxB1^zHOmHdC#B05`pIC$iOHP9>LW$<=IVbgJMMsi#SUyaelu~H`#j!H3vn}!m7Yb=fuLv=zc)YA{t@3T z?sL_9P;ZsF8jfbY++3)yfAL8Po2&mVN_=y0Fz6}3R4y_t`on+i&O3RSFpg?K5s%;W zJdw_%=ZNA>obJ^$#8|Gd_qX>SW@hdrG_Wqv!fV}3$ zi#Vg-U8j$i+I4h!kEf8{eW$Zg<5}8E5SFAyq z3IDyQVtozBOmVydYJ!fO?h+K9fB}x|Lsi^g6W4(3QmtV{_fNK+^=0Iw%2ea zF-P$&$#kd7z8Y?OvDQ!=zN z&T`n#!^uH=oD|xRcBhAqMY=O|lX?w|45GooPGI{x4)gl#c;}O_#e^|&j4P=%u()nkGoy%70KAayth7D#3y7XRp@{?hmrHKnh7tcGGoS;XY zRq77~NiWW3Jj1C4JK3k-?wIZi$I4sg2rgh}itH#X1kSo8A?zyoVFfELx7izl^c!T| zeL|ke%W>b&p5G^fdM5j!Fc>^8K;XFZbsBTzKfWVZRD|t`=3ZmI-m{8hA11 z8#K$C=$V>8@xtZ`zPE|+Tc+?K-vSVx}3V*o-A5IPCmdBVc?=6JV3|h62?H zhwz?<%iU6<8Y1{++4AYfVbap=cq8z7F&cNB7zCNNn_bvqg`<rn7lH#((MPmGxns4;;0Vk!dDag zvRCL#A)Bj48{Jr4dzuEP+Dx8u+ia5MSAV1J>4H`w(Lg$NHlz|GMTMST{=SjJL#N;oZ?&DBN&4q>;luF=sZ;YRmaS65D2!lH~l7A z8TeE<{VprgRu+O3mhb$2P1J>;X19>=+d`4?A3MP|Qz&G3!W|bz&Z3T-g;j(|d$4iW z!^;u4bTyuJRj}D4cwh>w3Z-vXu?kXXn?S_<;d4e?%X98?wLC{J5GbRE96B3At#c~ zaHQBI3wSv5EXGgtt-6p6Gv4mlGz;yGSKAn=A{E;s#i1?sOr9v)ob)4^pF~wp=&T7qHbG+-zj#|anoj`^{-#zHIpYrY{7jB?6 zS{SJ&uS5(ncnG=SAJmknqvA)IQ|lv0oZqm+j+YVdD~5+7psl4&e&jYDW`bjU_}Ea> zD1R_K*G#=~%x@6r-tf)c91tpa!UzS7?vj2^ww}ts;^}r25Y9$3{r)r}Skd)7QAMn;cK>>-3s(K=3YA!5_No*J&{+ zUo9aTJKXhWziXUZgH`$0?JK#2)D%$>s_CyG>bE7K={-%fAK{3M8T-RyC)(ESRB}I# z98$|$Wv-qfis<0jkJjcbD{qz;R`@$PyP<26YLIHwYI_`};~1BXo3R8Wkq^G!wm;vEES>(zMfBkf$5SEzw_P{B%ye!_&nzFNusqFn zEgP0`w(Lf(r-D3_7Xlb$O>elv*S#GTM=QyUr+~~0FgC*CCu|Q+M`@l$+!`3aL-}He z9Bqq@!7u7eW1rRbJFO_!e?cUv&SYY!xhXOh$1e94D?uoy@KA3rb2lwcRuv(N5D`O6 zFO!_{Liq8MSQ=bf!f_9T7Wrz9GEu>oLa*c3@zoNEfH9XEeeN0W;4ES?;n$dMJj& z0a@P}R}lQZm_P8V+!GZiNux=4YicF-`%0Bh~bT{o6+8odwG8Fg&3`csjBZ|!BS;hOrycHVI$TL&2%sj$|~RGla9;bt|_%@KP5y{ zJs7p?%`&44DrCA+rNEC-tqMgXv=sV2+35}~R8koaH*zcob$;F5Xr|a@o8aF$OC$=B zpGoo_vcJLM$R167s{j3$ouXrB*O?v#ZIxG1|ad?Ask=-u|VZ8qn z7#Zj0dM2$E-5U0c7GYA|QuCz%5HKy|XK|r#e)pGe5?2g)I_f{5ccIMD*z`+@>G#6~ zw87p9JRf75p16(l&{S_NGu7LF-0Ka?;eJNNo!9oE`)hn977Vh6=(vK3%GtySM58r% z+2+rZ`EyyJmfKC`-krk*BQ3GC>{7v%W8CZQVTo4ll`RI8f=URmAYRTgZLEiUPoG57z--%0K zxuu=E0+&d{+mvqQCpBZ)t+HGrCsLYjesM)Nzl!L%@~3z9=yJLSNYvE~TS)#Gg0DmU zizH1^m67Z0v(cl5+77%JGuEPVyVMlMD6y8&)`m;nw<~DYO&CXxkJoD39*~X-PFAMT zznhlvGt{Eb-JB!us-*~8N}AiJv8TUaG+Zg&19N(5C)!7gyY9DpJ8ER-U_;4$BM0Sg zPa#fNjVP3P_Gv||F^m_uwYlVS8fDlU{M0-)#(vEP-v;)wlbGoVYg?;P;FNC>Co}V* zA_#6l4@JpBDVlW__$c*CIFgkhYhtmLfW2Y?3ePdkt0F6bnM8Q5ub1N)@fA`c0VC2F zM&4t2SCW%?O{Gb(T@Lp|j60gtR#@jI%9`um)e5KR)%p9&{++&9(R=3p@E(?(b*nqX z`r{$<)V$juylWkLmVQgDs1lA&Dn|`vj>l4Pq59F;bDSqA`bFeq8+-!>$jvk$IjZR1w=?WX^Ve=sjJ&rVuV_SfwpM zmilJd1d7U0W0{c@v>}ye6>Q1MJeU^}0-8w7JqM81X_jda(Rw-2`5e<=OA4Bqj6^2Q z6=rT$-m#V(vx6n0(h`KTmrkX-S^Wd-W^JxdjjILLTs*+r$TpGHfE^S8tZwPyhp$Sp z!VVU4_FcVuTd3t@@qA+2Yv)rj$u+Tyk(_g@@nhM@l7M@X;##KNzMBX?==S?*cC1@k zEmc}8TDpkw5u@EMO1sR-n?gb+F<;r1bzwFvXjm7RwQ3FP*Znu|hyAzhckRoIcZJU8 zl#KB+?%k}yVn1$esHlB<>P41%qQ=YAzf!Qa4{aEP23XgfCZ+QsHR2{{B+)pO^zfjO z#K}k&cmxC~J&zYlaYH;G_jZbP?g9axqHlrxiEH)9i`mG`&c^B zWvgB`Tg6KEOO?)M*?mTW#(pHabS#LnhsZ^_gm<|F^E;`m0)zT!u^>CR^|)&Fl6~Mj z;|k}(g5)?u&%^WqFL!()>z3mN^{958zPio#fv>; z=x1$HBo9ajQ{hS!mMHViuO;)40!(_-fM?~T;BuOlitN2NBNb6;f_#MqM?+#*;NoNw zi9_2#C?S~GUiA*rgZ;v%4R)^2D<^I;dZ?|+%ZV)S9gNi&m+s=`ro0R5F+JRlSjK1V zNTo{W7*M5T>puNqrp=mdi5C|{4>hPq+ZTW(8+q7kfu2NQH1|HC4EYZ0GIm=|>aEXA zp<4FVz5+Me>|ii3Z?#F#8D`#Vv!%8)GhC43SKFlcA-h~}!CYMB{6&XAIEyz$3?f$)qT5iFmPpDIo7)aL*h_i7|bd6m}c47DQ9@I?D&$7 zW10JMi(hkFSq6TuBg-mQ2AbN_RPY5mlFBKmz922F6)jyZr>B5?+3SJd?Go4_55F*f z7uzrJjQPWq6Sy>BC9kalAOmerBH zR3$+L?E#8|L!7D{aHaZ}rVUIBn2Pe`9H<=Cvi;b7%WUJXZwYTw)!mMwjM*rcUsHJe z_Px4uuSAjXE?1%emP#|*6dKEqTqmpSlQsUoy`z6l8^`i1{VTl8{;=(&U~Ge7)9wx* zrsYb20g`R+dc!ziQcs9sY}2N{d&Tw>ovD<#E&Vy-=8_COSL+R1H`seYfJFn zfZXh|o_DY>bAYD^N4dzoXu<#dFPA~Ap+s{+Sx(4A#(^(AUV z$gr&}V-l}XsJ(Ohc3A=Ak4nbGV%EQ^di#9J|WH)gzl$P##eC# zo`>_Sa28Lj)rlr)3Xmj0zr+TCZVS#YuPXS$-anod^5T_^bz5ONc%GbJU*2Bc?vN?S z)CTNHsY??6lo}4 zY{erN$%qNRJ7|jWk4ZE&1xsLDb#>F-n}zC?URFz|taV8h3h2Si;ZFmxZcgL2ZaPMH zYoNoBVo~5v$d_hQJPG|IHJmSE_=^McJiXCid-3D2A?)s+>;nl5H4ze|+fD}~*(OMT zro$?xxiPJDxW81>KlWj;3b z8>DwyHu8TiceeHeNpDCh$C^p4%S^l3!o@#i>#6z~aDn{c+o+_5+;pnA*8=T@yz^;l z+CtyfZY)Qli3#HIebCLOptvT;u}(3Mz!V~GXt%brc1SG(#a87LvBf+BY~YzD;HoC$ ziatugrGyXXkE`I}X9D-(7X)m`<$8+=KO49ozZhE~!V0ei#tQy6q^xZ)R`9hUl7TmB z4aPQDEBMP6F z?|*!uTi#=MfmJ4togQaX+O)H}r4qNp{}`~YCfW);VIu=nFi6N#>Km&K=3bfPCam8% z3HQ?+Xa-;;-!}{NU6%15u=L_Q`Aoscqt6tO4~&t`lmtiUf9M+@37;fBHGC@L910!l zN?orn)x~w+p`IVJZoP8`a}6)dQm^Q_pGXgJGal|x5@nl$Ad0fUi}glLl4YcP8bJ~= zS`$)*@Q{*J{NGJzL$m}-dBupeByJz^r>iZ0y>5n@`_EcaX_o&=zQDhn1>>rk3 z%x-?V?w|;(sT`>CbNRc|A6}>Kt3#M0nw*rWq+|`=a#E&}k~L1vNts4U=8!xm9MuA2`p(i`3FXX_WL6VqpwsWA*&)GqdWhJ41(m69RMDX zB)C5ksAouo+uD_GaL$d!uq=e84qh2V^8CzAxVPezXvB5q5UPnr@}3r*5AMu!8#v`w zI-LID^Vhp^{(2NW(#{-K19Vb$<0j>|>J^SKmWiYc5W7d3(oD@*gb2=_&2`5Rz(&TQ z7)U3e-hpiJryLRu`<=1*V&Fwl6290df+7aS8ObR}?H6t5l-m+zNdGRcv66{U;FKf8 zgMr`@Kz%$7T_BNUkI6rk$E>mU9# zf#1}dWA0Rzfo2!@6F-5N6+fwUKaCKjn>$(-vN3Y!9#mtWdx7C+)9=yIJDpA+yf?if z6DKgO-fHR+c|X`3k3Xqaylc~l>o=_$N5BYH+~G_3vxTvrsn#_D6{?afHN?7vGlNC2 z%I;Q3GH`QejEwbH6!mnq?RxX|MlUBIQU*nIOY$EnlPj$_aF*I$oGd)W|R z*iiNDJdNX3=FGE420w0(0)eP>029;QGSZD}3lD-@1Y%h{pH~|*GJ;aHXC-F?!lg?M zm&nc_<+z5YpS1OQx-j)^c;clAZ~(R$2OCxW6uKSTlX%z;W3Qik!=LOTB8K8v4VhtM zp@*M1sg)R-;^$kUKKcd<0@rINivRVu>4)h|Ihzmq?MZ9$0ZjDsigIgf_#8(oP zzUV{Gio2PmY#Psxj5;Hw#pb4r{E@X*rVn1i#zR!YG_>_g&FN-Y-(2f3E^@+UyL*1%|X3@ROJrE80}db$^FU zvG=1LeAguN%O>}5F}y(rWHUzW0%GZEniRh@)l^5MGY0cLe7(a`em>6M&%I66&W|2A)iS}5h4a(GD6Q->_-S1iWW3X=X&K*H!4(JS-$>)2Z+DD{#g3; zZ))GV%7ro*jg<*lxVs9Sfw=RU$svPhs#fJ4wk@1%{Z)NUE)}pR zts_+Mqu#r4kg_Nl&FMy$3h@MEOYSC(*dxpPPV{~DAZ=(YCdI{KqbBQW1Iu zr&w%FI&Y^W*dDfK{R?Fdzsy^m*?DX5oW4}s8I3>8$8TFxWj>uv`eTT*N956)PG{cz zFl?RmJM-aaKJIry50zo7Jy7Po{`+}r*qwJq!&!fLt{|un%G3ip8+Dbze0DzU58t3? zZ))D7(RkKB>;Dt=ZZw<^KzF$+u-G5=M&m($IztT%l!O&K3OSv%27~#yHG9jRTqwR% zCPUOQ)V=dTpwr}+d4Ke-Ka2StQ3SvtPq5Z6ch+S&n)PsCFOx`C-NrrQIKPiLg*PN}m$V z?_o+Di2z{)?Uk?m3sPwu^&`p2y`k zoe#XI^k6jH>(K;gm}2}NlZKDIvEy)RvUmr9)v6RF{&>`MRmFY<0CYDu8=D+j#JNj= zZ0oOwy*BY=O3M2mo|QYGjs5R`AmI|c_dg^_F7Q>kF4Xh)KaNpe{ds${=020<{?{es zAe1K)0c=qa-?x=%<7_!B5eBK@)@4fW0Qfa|fi%O+C>vGsz0w<$V zQHCY1^vSljzgH?>zI>q@GLX9hfEMJnx0-2xg-QJqyppB8ETLuy_CR;gug;OK_~9j^2zDoK?RMuNT6 za2@0b>o#1Si)gUcZQVP8*ga>O9D=REA;n$%4y1dKaOgf({( zzn_%jatQw;JFpYlNQwUtyQL8S>oq~jSQ_u=a^xJ3jX%;N>%cfwUPY!*q(Et1BuNC@UE^INp zRj|>o*9iJ6hI)Z;K12U?3cW(RutU&G1g8~-2>%WGaj{f?DzH8{0 zC3<#R$lZw}l(_jXKVtqjX8qsO|M>jJ8svZLb^gfu|0iAl-^2e$$^WwPzb@5|?f>Qc zPvrkY=6~b%|5SN7$baPj=lg$-Q}X<8p8x&+^1u0xn{S@{&3D}VB$?lQ$IZ`NSp2_- z%>Od^|KR`0x&MERl8yg|=YQGwFIJ^I{yR!Jg#Y)+|Hkp(&HuXmuS@kj{yR#^^S^n? jOJ4Glm%QX9FL}vJUhPrLjd4{D&t0O$h%G+`s^ From ff1a7aa50be2878bb47c83637c076a93eeef70a9 Mon Sep 17 00:00:00 2001 From: Jeff Kent Date: Wed, 19 Sep 2012 12:22:28 -0500 Subject: [PATCH 0183/1435] workaround for asserting nRST, issue "monitor jtag_reset" from gdb --- gdbserver/gdb-server.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index e6368ea31..9d27ae48a 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -784,6 +784,16 @@ int serve(stlink_t *sl, int port) { #ifdef DEBUG printf("Rcmd: halt\n"); +#endif + } else if (!strncmp(params,"6a7461675f7265736574",20)) { //jtag_reset + reply = strdup("OK"); + + stlink_jtag_reset(sl, 1); + stlink_jtag_reset(sl, 0); + stlink_force_debug(sl); + +#ifdef DEBUG + printf("Rcmd: jtag_reset\n"); #endif } else if (!strncmp(params,"7265736574",10)) { //reset reply = strdup("OK"); From 8604e0b62510564a571ce0ad0eb79bd31fb58fd9 Mon Sep 17 00:00:00 2001 From: Pekka Nikander Date: Thu, 4 Oct 2012 09:17:50 +0300 Subject: [PATCH 0184/1435] src/stlink-common.c: Fix white spaces, unify coding style --- src/stlink-common.c | 409 +++++++++++++++++++++----------------------- 1 file changed, 193 insertions(+), 216 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index e142233f7..217c01faf 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -231,7 +231,7 @@ static void set_flash_cr_mer(stlink_t *sl) { if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); - else + else stlink_write_debug32(sl, FLASH_CR, stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_MER)); } @@ -240,7 +240,7 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); - else + else stlink_write_debug32(sl, FLASH_CR, stlink_read_debug32(sl, FLASH_CR) & ~(1 << FLASH_CR_MER)); } @@ -254,7 +254,7 @@ static void set_flash_cr_strt(stlink_t *sl) { } else { stlink_write_debug32( - sl, FLASH_CR, + sl, FLASH_CR, stlink_read_debug32(sl,FLASH_CR) |(1 << FLASH_CR_STRT) ); } } @@ -422,7 +422,7 @@ int stlink_load_device_params(stlink_t *sl) { const chip_params_t *params = NULL; sl->core_id = stlink_core_id(sl); uint32_t chip_id = stlink_chip_id(sl); - + sl->chip_id = chip_id & 0xfff; /* Fix chip_id for F4 rev A errata , Read CPU ID, as CoreID is the same for F2/F4*/ if (sl->chip_id == 0x411) { @@ -441,11 +441,11 @@ int stlink_load_device_params(stlink_t *sl) { WLOG("unknown chip id! %#x\n", chip_id); return -1; } - + // These are fixed... sl->flash_base = STM32_FLASH_BASE; sl->sram_base = STM32_SRAM_BASE; - + // read flash size from hardware, if possible... if (sl->chip_id == STM32_CHIPID_F2) { sl->flash_size = 0x100000; /* Use maximum, User must care!*/ @@ -459,11 +459,11 @@ int stlink_load_device_params(stlink_t *sl) { sl->sram_size = params->sram_size; sl->sys_base = params->bootrom_base; sl->sys_size = params->bootrom_size; - + ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); // TODO make note of variable page size here..... ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %zd bytes\n", - sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, + sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, sl->flash_pgsz); return 0; } @@ -518,7 +518,7 @@ void stlink_version(stlink_t *sl) { DLOG("*** looking up stlink version\n"); sl->backend->version(sl); _parse_version(sl, &sl->version); - + DLOG("st vid = 0x%04x (expect 0x%04x)\n", sl->version.st_vid, USB_ST_VID); DLOG("stlink pid = 0x%04x\n", sl->version.stlink_pid); DLOG("stlink version = 0x%x\n", sl->version.stlink_v); @@ -993,8 +993,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - if ((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) - { + if ((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1020,9 +1019,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) #if DEBUG_FLASH fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); #endif - } - else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) - { + } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { uint32_t val; @@ -1032,8 +1029,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) /* check pecr.pelock is cleared */ val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 0)) - { + if (val & (1 << 0)) { WLOG("pecr.pelock not clear (%#x)\n", val); return -1; } @@ -1044,8 +1040,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) /* check pecr.prglock is cleared */ val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 1)) - { + if (val & (1 << 1)) { WLOG("pecr.prglock not clear (%#x)\n", val); return -1; } @@ -1057,8 +1052,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) /* check pecr.optlock is cleared */ val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 2)) - { + if (val & (1 << 2)) { fprintf(stderr, "pecr.prglock not clear\n"); return -1; } @@ -1077,8 +1071,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) it. If someone has a problem, please drop an email. */ while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) - { - } + ; #endif /* fix_to_be_confirmed */ @@ -1090,16 +1083,13 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) Test shows that a few iterations is performed in the following loop before busy bit is cleared.*/ while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) - { - } + ; /* reset lock bits */ val = stlink_read_debug32(sl, STM32L_FLASH_PECR) | (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - } - else if (sl->core_id == STM32VL_CORE_ID) - { + } else if (sl->core_id == STM32VL_CORE_ID) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1120,9 +1110,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) /* relock the flash */ lock_flash(sl); - } - - else { + } else { WLOG("unknown coreid: %x\n", sl->core_id); return -1; } @@ -1133,42 +1121,41 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } int stlink_erase_flash_mass(stlink_t *sl) { - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { - /* erase each page */ - int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; - for (i = 0; i < num_pages; i++) { - /* addr must be an addr inside the page */ - stm32_addr_t addr = sl->flash_base + i * sl->flash_pgsz; - if (stlink_erase_flash_page(sl, addr) == -1) { - WLOG("Failed to erase_flash_page(%#zx) == -1\n", addr); - return -1; - } - fprintf(stdout,"\rFlash page at %5d/%5d erased", i, num_pages); - fflush(stdout); - } - fprintf(stdout, "\n"); - } - else { - /* wait for ongoing op to finish */ - wait_flash_busy(sl); - - /* unlock if locked */ - unlock_flash_if(sl); - - /* set the mass erase bit */ - set_flash_cr_mer(sl); - - /* start erase operation, reset by hw with bsy bit */ - set_flash_cr_strt(sl); - - /* wait for completion */ - wait_flash_busy_progress(sl); - - /* relock the flash */ - lock_flash(sl); - - /* todo: verify the erased memory */ - } + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { + /* erase each page */ + int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; + for (i = 0; i < num_pages; i++) { + /* addr must be an addr inside the page */ + stm32_addr_t addr = sl->flash_base + i * sl->flash_pgsz; + if (stlink_erase_flash_page(sl, addr) == -1) { + WLOG("Failed to erase_flash_page(%#zx) == -1\n", addr); + return -1; + } + fprintf(stdout,"\rFlash page at %5d/%5d erased", i, num_pages); + fflush(stdout); + } + fprintf(stdout, "\n"); + } else { + /* wait for ongoing op to finish */ + wait_flash_busy(sl); + + /* unlock if locked */ + unlock_flash_if(sl); + + /* set the mass erase bit */ + set_flash_cr_mer(sl); + + /* start erase operation, reset by hw with bsy bit */ + set_flash_cr_strt(sl); + + /* wait for completion */ + wait_flash_busy_progress(sl); + + /* relock the flash */ + lock_flash(sl); + + /* todo: verify the erased memory */ + } return 0; } @@ -1212,67 +1199,60 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { static const uint8_t loader_code_stm32l[] = { - /* openocd.git/contrib/loaders/flash/stm32lx.S - r0, input, dest addr - r1, input, source addr - r2, input, word count - r3, output, word count - */ + /* openocd.git/contrib/loaders/flash/stm32lx.S + r0, input, dest addr + r1, input, source addr + r2, input, word count + r3, output, word count + */ - 0x00, 0x23, - 0x04, 0xe0, + 0x00, 0x23, + 0x04, 0xe0, - 0x51, 0xf8, 0x04, 0xcb, - 0x40, 0xf8, 0x04, 0xcb, - 0x01, 0x33, + 0x51, 0xf8, 0x04, 0xcb, + 0x40, 0xf8, 0x04, 0xcb, + 0x01, 0x33, - 0x93, 0x42, - 0xf8, 0xd3, - 0x00, 0xbe + 0x93, 0x42, + 0xf8, 0xd3, + 0x00, 0xbe }; - static const uint8_t loader_code_stm32f4[] = { - // flashloaders/stm32f4.s + static const uint8_t loader_code_stm32f4[] = { + // flashloaders/stm32f4.s - 0x07, 0x4b, + 0x07, 0x4b, - 0x62, 0xb1, - 0x04, 0x68, - 0x0c, 0x60, + 0x62, 0xb1, + 0x04, 0x68, + 0x0c, 0x60, - 0xdc, 0x89, - 0x14, 0xf0, 0x01, 0x0f, - 0xfb, 0xd1, - 0x00, 0xf1, 0x04, 0x00, - 0x01, 0xf1, 0x04, 0x01, - 0xa2, 0xf1, 0x01, 0x02, - 0xf1, 0xe7, + 0xdc, 0x89, + 0x14, 0xf0, 0x01, 0x0f, + 0xfb, 0xd1, + 0x00, 0xf1, 0x04, 0x00, + 0x01, 0xf1, 0x04, 0x01, + 0xa2, 0xf1, 0x01, 0x02, + 0xf1, 0xe7, - 0x00, 0xbe, + 0x00, 0xbe, - 0x00, 0x3c, 0x02, 0x40, - }; + 0x00, 0x3c, 0x02, 0x40, + }; const uint8_t* loader_code; size_t loader_size; - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) /* stm32l */ - { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); - } - else if (sl->core_id == STM32VL_CORE_ID) - { + } else if (sl->core_id == STM32VL_CORE_ID) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); - } - else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) - { - loader_code = loader_code_stm32f4; - loader_size = sizeof(loader_code_stm32f4); - } - else - { + } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { + loader_code = loader_code_stm32f4; + loader_size = sizeof(loader_code_stm32f4); + } else { WLOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); return -1; } @@ -1339,7 +1319,7 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, } int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned num_half_pages) -{ +{ unsigned int count; uint32_t val; flash_loader_t fl; @@ -1354,7 +1334,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uns val = stlink_read_debug32(sl, STM32L_FLASH_PECR); val |= (1 << FLASH_L1_FPRG); stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - + val |= (1 << FLASH_L1_PROG); stlink_write_debug32(sl, STM32L_FLASH_PECR, val); while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) {} @@ -1428,18 +1408,18 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned page_count++; } fprintf(stdout,"\n"); - ILOG("Finished erasing %d pages of %d (%#x) bytes\n", + ILOG("Finished erasing %d pages of %d (%#x) bytes\n", page_count, sl->flash_pgsz, sl->flash_pgsz); if ((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) { /* todo: check write operation */ - ILOG("Starting Flash write for F2/F4\n"); - /* flash loader initialization */ - if (init_flash_loader(sl, &fl) == -1) { - WLOG("init_flash_loader() == -1\n"); - return -1; - } + ILOG("Starting Flash write for F2/F4\n"); + /* flash loader initialization */ + if (init_flash_loader(sl, &fl) == -1) { + WLOG("init_flash_loader() == -1\n"); + return -1; + } /* First unlock the cr */ unlock_flash_if(sl); @@ -1451,38 +1431,39 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned /* set programming mode */ set_flash_cr_pg(sl); - for(off = 0; off < len;) { - size_t size = len - off > 0x8000 ? 0x8000 : len - off; + for(off = 0; off < len;) { + size_t size = len - off > 0x8000 ? 0x8000 : len - off; - printf("size: %zu\n", size); + printf("size: %zu\n", size); - if (run_flash_loader(sl, &fl, addr + off, base + off, size) == -1) { - WLOG("run_flash_loader(%#zx) failed! == -1\n", addr + off); - return -1; - } + if (run_flash_loader(sl, &fl, addr + off, base + off, size) == -1) { + WLOG("run_flash_loader(%#zx) failed! == -1\n", addr + off); + return -1; + } - off += size; - } + off += size; + } #if 0 #define PROGRESS_CHUNK_SIZE 0x1000 /* write a word in program memory */ for (off = 0; off < len; off += sizeof(uint32_t)) { - uint32_t data; - if (sl->verbose >= 1) { - if ((off & (PROGRESS_CHUNK_SIZE - 1)) == 0) { - /* show progress. writing procedure is slow - and previous errors are misleading */ - const uint32_t pgnum = (off / PROGRESS_CHUNK_SIZE)+1; - const uint32_t pgcount = len / PROGRESS_CHUNK_SIZE +1; - fprintf(stdout, "Writing %ukB chunk %u out of %u\n", PROGRESS_CHUNK_SIZE/1024, pgnum, pgcount); - } - } - - write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); - stlink_write_debug32(sl, addr + off, data); - - /* wait for sr.busy to be cleared */ + uint32_t data; + if (sl->verbose >= 1) { + if ((off & (PROGRESS_CHUNK_SIZE - 1)) == 0) { + /* show progress. writing procedure is slow + and previous errors are misleading */ + const uint32_t pgnum = (off / PROGRESS_CHUNK_SIZE)+1; + const uint32_t pgcount = len / PROGRESS_CHUNK_SIZE +1; + fprintf(stdout, "Writing %ukB chunk %u out of %u\n", + PROGRESS_CHUNK_SIZE/1024, pgnum, pgcount); + } + } + + write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); + stlink_write_debug32(sl, addr + off, data); + + /* wait for sr.busy to be cleared */ wait_flash_busy(sl); } @@ -1494,8 +1475,6 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned fprintf(stdout, "Final CR:0x%x\n", read_flash_cr(sl)); #endif - - } //STM32F4END else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { @@ -1533,70 +1512,69 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned } off = 0; if (len > L1_WRITE_BLOCK_SIZE) { - if (stm32l1_write_half_pages(sl, addr, base, len/L1_WRITE_BLOCK_SIZE) == -1){ + if (stm32l1_write_half_pages(sl, addr, base, len/L1_WRITE_BLOCK_SIZE) == -1) { /* This may happen on a blank device! */ WLOG("\nwrite_half_pages failed == -1\n"); - } - else{ + } else { off = (len /L1_WRITE_BLOCK_SIZE)*L1_WRITE_BLOCK_SIZE; } } /* write remainingword in program memory */ for ( ; off < len; off += sizeof(uint32_t)) { - uint32_t data; - if (off > 254) - fprintf(stdout, "\r"); - - if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) { - fprintf(stdout, "\r%3zd/%3zd pages written", - off/sl->flash_pgsz, len/sl->flash_pgsz); - fflush(stdout); - } + uint32_t data; + if (off > 254) + fprintf(stdout, "\r"); + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) { + fprintf(stdout, "\r%3zd/%3zd pages written", + off/sl->flash_pgsz, len/sl->flash_pgsz); + fflush(stdout); + } - write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); - stlink_write_debug32(sl, addr + off, data); + write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); + stlink_write_debug32(sl, addr + off, data); - /* wait for sr.busy to be cleared */ - while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) { - } + /* wait for sr.busy to be cleared */ + while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) + ; #if 0 /* todo: check redo write operation */ - /* check written bytes. todo: should be on a per page basis. */ - data = stlink_read_debug32(sl, addr + off); - if (data == *(uint32_t*)(base + off)) { - /* re erase the page and redo the write operation */ - uint32_t page; - uint32_t val; + /* check written bytes. todo: should be on a per page basis. */ + data = stlink_read_debug32(sl, addr + off); + if (data == *(uint32_t*)(base + off)) { + /* re erase the page and redo the write operation */ + uint32_t page; + uint32_t val; - /* fail if successive write count too low */ - if (nwrites < sl->flash_pgsz) { - fprintf(stderr, "writes operation failure count too high, aborting\n"); - return -1; - } + /* fail if successive write count too low */ + if (nwrites < sl->flash_pgsz) { + fprintf(stderr, "writes operation failure count too high, aborting\n"); + return -1; + } - nwrites = 0; + nwrites = 0; - /* assume addr aligned */ - if (off % sl->flash_pgsz) off &= ~(sl->flash_pgsz - 1); - page = addr + off; + /* assume addr aligned */ + if (off % sl->flash_pgsz) off &= ~(sl->flash_pgsz - 1); + page = addr + off; - fprintf(stderr, "invalid write @0x%x(0x%x): 0x%x != 0x%x. retrying.\n", - page, addr + off, read_uint32(base + off, 0), read_uint32(sl->q_buf, 0)); + fprintf(stderr, "invalid write @0x%x(0x%x): 0x%x != 0x%x. retrying.\n", + page, addr + off, read_uint32(base + off, 0), read_uint32(sl->q_buf, 0)); - /* reset lock bits */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR) - | (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + /* reset lock bits */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR) + | (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - stlink_erase_flash_page(sl, page); + stlink_erase_flash_page(sl, page); - goto redo_write; - } + goto redo_write; + } - /* increment successive writes counter */ - ++nwrites; + /* increment successive writes counter */ + ++nwrites; #endif /* todo: check redo write operation */ } @@ -1640,7 +1618,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned WLOG("unknown coreid, not sure how to write: %x\n", sl->core_id); return -1; } - + return stlink_verify_write_flash(sl, addr, base, len); } @@ -1695,49 +1673,48 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { - size_t count = size / sizeof(uint32_t); - if (size % sizeof(uint32_t)) ++count; + size_t count = size / sizeof(uint32_t); + if (size % sizeof(uint32_t)) ++count; - /* setup core */ - stlink_write_reg(sl, target, 0); /* target */ - stlink_write_reg(sl, fl->buf_addr, 1); /* source */ - stlink_write_reg(sl, count, 2); /* count (32 bits words) */ - stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ + /* setup core */ + stlink_write_reg(sl, target, 0); /* target */ + stlink_write_reg(sl, fl->buf_addr, 1); /* source */ + stlink_write_reg(sl, count, 2); /* count (32 bits words) */ + stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ } else if (sl->core_id == STM32VL_CORE_ID) { - size_t count = size / sizeof(uint16_t); - if (size % sizeof(uint16_t)) ++count; + size_t count = size / sizeof(uint16_t); + if (size % sizeof(uint16_t)) ++count; - /* setup core */ - stlink_write_reg(sl, fl->buf_addr, 0); /* source */ - stlink_write_reg(sl, target, 1); /* target */ - stlink_write_reg(sl, count, 2); /* count (16 bits half words) */ - stlink_write_reg(sl, 0, 3); /* flash bank 0 (input) */ - stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ + /* setup core */ + stlink_write_reg(sl, fl->buf_addr, 0); /* source */ + stlink_write_reg(sl, target, 1); /* target */ + stlink_write_reg(sl, count, 2); /* count (16 bits half words) */ + stlink_write_reg(sl, 0, 3); /* flash bank 0 (input) */ + stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { + } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { - size_t count = size / sizeof(uint32_t); - if (size % sizeof(uint32_t)) ++count; + size_t count = size / sizeof(uint32_t); + if (size % sizeof(uint32_t)) ++count; - /* setup core */ - stlink_write_reg(sl, fl->buf_addr, 0); /* source */ - stlink_write_reg(sl, target, 1); /* target */ - stlink_write_reg(sl, count, 2); /* count (32 bits words) */ - stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ + /* setup core */ + stlink_write_reg(sl, fl->buf_addr, 0); /* source */ + stlink_write_reg(sl, target, 1); /* target */ + stlink_write_reg(sl, count, 2); /* count (32 bits words) */ + stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ } else { - fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id); - return -1; + fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id); + return -1; } /* run loader */ stlink_run(sl); /* wait until done (reaches breakpoint) */ - while ((is_core_halted(sl) == 0) && (i <1000)) - { + while ((is_core_halted(sl) == 0) && (i <1000)) { i++; } @@ -1745,7 +1722,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons fprintf(stderr, "run error\n"); return -1; } - + /* check written byte count */ if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { From f0256c69cb3aa421f9266fd9adecbe5343036eb2 Mon Sep 17 00:00:00 2001 From: Pekka Nikander Date: Fri, 5 Oct 2012 15:30:28 +0300 Subject: [PATCH 0185/1435] src/stlink-common.[ch]: Another fix on white spaces, unifying coding style --- src/stlink-common.c | 129 +++++++++++++++++++++----------------------- src/stlink-common.h | 6 +-- 2 files changed, 64 insertions(+), 71 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 217c01faf..7e3dc1b35 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -134,23 +134,23 @@ static inline uint32_t read_flash_obr(stlink_t *sl) { } static inline uint32_t read_flash_cr(stlink_t *sl) { - uint32_t res; - if((sl->chip_id==STM32_CHIPID_F2) ||(sl->chip_id==STM32_CHIPID_F4)) - res = stlink_read_debug32(sl, FLASH_F4_CR); - else - res = stlink_read_debug32(sl, FLASH_CR); + uint32_t res; + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) + res = stlink_read_debug32(sl, FLASH_F4_CR); + else + res = stlink_read_debug32(sl, FLASH_CR); #if DEBUG_FLASH - fprintf(stdout, "CR:0x%x\n", res); + fprintf(stdout, "CR:0x%x\n", res); #endif - return res; + return res; } static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ - if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) - return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK); - else - return read_flash_cr(sl) & (1 << FLASH_CR_LOCK); + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) + return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK); + else + return read_flash_cr(sl) & (1 << FLASH_CR_LOCK); } static void unlock_flash(stlink_t *sl) { @@ -159,14 +159,13 @@ static void unlock_flash(stlink_t *sl) { an invalid sequence results in a definitive lock of the FPEC block until next reset. */ - if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) { + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) { stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); - stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); - } - else { + stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); + } else { stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY1); - stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY2); - } + stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY2); + } } @@ -185,11 +184,10 @@ static int unlock_flash_if(stlink_t *sl) { } static void lock_flash(stlink_t *sl) { - if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) { + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) { const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); stlink_write_debug32(sl, FLASH_F4_CR, n); - } - else { + } else { /* write to 1 only. reset by hw at unlock sequence */ const uint32_t n = read_flash_cr(sl) | (1 << FLASH_CR_LOCK); stlink_write_debug32(sl, FLASH_CR, n); @@ -198,12 +196,11 @@ static void lock_flash(stlink_t *sl) { static void set_flash_cr_pg(stlink_t *sl) { - if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) { + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_CR_PG); stlink_write_debug32(sl, FLASH_F4_CR, x); - } - else { + } else { const uint32_t n = 1 << FLASH_CR_PG; stlink_write_debug32(sl, FLASH_CR, n); } @@ -211,7 +208,7 @@ static void set_flash_cr_pg(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); - if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) stlink_write_debug32(sl, FLASH_F4_CR, n); else stlink_write_debug32(sl, FLASH_CR, n); @@ -228,7 +225,7 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { } static void set_flash_cr_mer(stlink_t *sl) { - if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); else @@ -237,7 +234,7 @@ static void set_flash_cr_mer(stlink_t *sl) { } static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { - if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); else @@ -246,17 +243,14 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { } static void set_flash_cr_strt(stlink_t *sl) { - if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) - { - uint32_t x = read_flash_cr(sl); - x |= (1 << FLASH_F4_CR_STRT); - stlink_write_debug32(sl, FLASH_F4_CR, x); - } - else { - stlink_write_debug32( - sl, FLASH_CR, - stlink_read_debug32(sl,FLASH_CR) |(1 << FLASH_CR_STRT) ); - } + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) { + uint32_t x = read_flash_cr(sl); + x |= (1 << FLASH_F4_CR_STRT); + stlink_write_debug32(sl, FLASH_F4_CR, x); + } else { + stlink_write_debug32(sl, FLASH_CR, + stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_STRT) ); + } } static inline uint32_t read_flash_acr(stlink_t *sl) { @@ -264,20 +258,20 @@ static inline uint32_t read_flash_acr(stlink_t *sl) { } static inline uint32_t read_flash_sr(stlink_t *sl) { - uint32_t res; - if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) - res = stlink_read_debug32(sl, FLASH_F4_SR); - else - res = stlink_read_debug32(sl, FLASH_SR); + uint32_t res; + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) + res = stlink_read_debug32(sl, FLASH_F4_SR); + else + res = stlink_read_debug32(sl, FLASH_SR); //fprintf(stdout, "SR:0x%x\n", *(uint32_t*) sl->q_buf); return res; } static inline unsigned int is_flash_busy(stlink_t *sl) { - if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) - return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY); - else - return read_flash_sr(sl) & (1 << FLASH_SR_BSY); + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) + return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY); + else + return read_flash_sr(sl) & (1 << FLASH_SR_BSY); } static void wait_flash_busy(stlink_t *sl) { @@ -290,8 +284,7 @@ static void wait_flash_busy_progress(stlink_t *sl) { int i = 0; fprintf(stdout, "Mass erasing"); fflush(stdout); - while (is_flash_busy(sl)) - { + while (is_flash_busy(sl)) { usleep(10000); i++; if (i % 100 == 0) { @@ -427,11 +420,11 @@ int stlink_load_device_params(stlink_t *sl) { /* Fix chip_id for F4 rev A errata , Read CPU ID, as CoreID is the same for F2/F4*/ if (sl->chip_id == 0x411) { uint32_t cpuid = stlink_read_debug32(sl, 0xE000ED00); - if((cpuid & 0xfff0) == 0xc240) + if ((cpuid & 0xfff0) == 0xc240) sl->chip_id = 0x413; } - for(size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { + for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { if(devices[i].chip_id == sl->chip_id) { params = &devices[i]; break; @@ -894,7 +887,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) int error = -1; size_t off; int num_empty = 0; - unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM)?0:0xff; + unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM)?0:0xff; const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); if (fd == -1) { @@ -976,7 +969,7 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ - if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) { + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector<4) sl->flash_pgsz=0x4000; else if(sector<5) sl->flash_pgsz=0x10000; @@ -993,7 +986,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - if ((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) { + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1244,17 +1237,17 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { size_t loader_size; if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { /* stm32l */ - loader_code = loader_code_stm32l; - loader_size = sizeof(loader_code_stm32l); + loader_code = loader_code_stm32l; + loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID) { - loader_code = loader_code_stm32vl; - loader_size = sizeof(loader_code_stm32vl); + loader_code = loader_code_stm32vl; + loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { - loader_code = loader_code_stm32f4; - loader_size = sizeof(loader_code_stm32f4); + loader_code = loader_code_stm32f4; + loader_size = sizeof(loader_code_stm32f4); } else { - WLOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); - return -1; + WLOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); + return -1; } memcpy(sl->q_buf, loader_code, loader_size); @@ -1411,7 +1404,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned ILOG("Finished erasing %d pages of %d (%#x) bytes\n", page_count, sl->flash_pgsz, sl->flash_pgsz); - if ((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) { + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) { /* todo: check write operation */ ILOG("Starting Flash write for F2/F4\n"); @@ -1743,13 +1736,13 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { + } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { - stlink_read_reg(sl, 2, &rr); - if (rr.r[2] != 0) { - fprintf(stderr, "write error, count == %u\n", rr.r[2]); - return -1; - } + stlink_read_reg(sl, 2, &rr); + if (rr.r[2] != 0) { + fprintf(stderr, "write error, count == %u\n", rr.r[2]); + return -1; + } } else { diff --git a/src/stlink-common.h b/src/stlink-common.h index 2e30e71c3..7ffdfc0cd 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -129,9 +129,9 @@ extern "C" { } 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[] = { +// 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[] = { { // table 2, PM0063 .chip_id = 0x410, .description = "F1 Medium-density device", From bfc368c57e2ef2701d2100dd61f1d2f7cb30b302 Mon Sep 17 00:00:00 2001 From: Pekka Nikander Date: Fri, 5 Oct 2012 15:32:48 +0300 Subject: [PATCH 0186/1435] src/stlink-common.c: Improve error reporting --- src/stlink-common.c | 52 +++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 7e3dc1b35..702536aed 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -18,6 +18,7 @@ #define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args) #define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args) #define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args) +#define ELOG(format, args...) ugly_log(UERROR, LOG_TAG, format, ## args) #define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args) /* todo: stm32l15xxx flash memory, pm0062 manual */ @@ -1104,7 +1105,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) /* relock the flash */ lock_flash(sl); } else { - WLOG("unknown coreid: %x\n", sl->core_id); + WLOG("unknown coreid %x, page erase failed\n", sl->core_id); return -1; } @@ -1246,7 +1247,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { loader_code = loader_code_stm32f4; loader_size = sizeof(loader_code_stm32f4); } else { - WLOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); + ELOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); return -1; } @@ -1302,7 +1303,7 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, stlink_read_mem32(sl, address + off, aligned_size); if (memcmp(sl->q_buf, data + off, cmp_size)) { - WLOG("Verification of flash failed at offset: %zd\n", off); + ELOG("Verification of flash failed at offset: %zd\n", off); return -1; } } @@ -1369,19 +1370,22 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned /* check addr range is inside the flash */ stlink_calculate_pagesize(sl, addr); if (addr < sl->flash_base) { - WLOG("addr too low %#x < %#x\n", addr, sl->flash_base); + ELOG("addr too low %#x < %#x\n", addr, sl->flash_base); return -1; } else if ((addr + len) < addr) { - WLOG("addr overruns\n"); + ELOG("addr overruns\n"); return -1; } else if ((addr + len) > (sl->flash_base + sl->flash_size)) { - WLOG("addr too high\n"); + ELOG("addr too high\n"); return -1; - } else if ((addr & 1) || (len & 1)) { - WLOG("unaligned addr or size\n"); + } else if (addr & 1) { + ELOG("unaligned addr 0x%x\n", addr); return -1; + } else if (len & 1) { + WLOG("unaligned len 0x%x -- padding with zero\n", len); + len += 1; } else if (addr & (sl->flash_pgsz - 1)) { - WLOG("addr not a multiple of pagesize, not supported\n"); + ELOG("addr not a multiple of pagesize, not supported\n"); return -1; } @@ -1392,7 +1396,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + off)) { /* addr must be an addr inside the page */ if (stlink_erase_flash_page(sl, addr + off) == -1) { - WLOG("Failed to erase_flash_page(%#zx) == -1\n", addr + off); + ELOG("Failed to erase_flash_page(%#zx) == -1\n", addr + off); return -1; } fprintf(stdout,"\rFlash page at addr: 0x%08lx erased", @@ -1410,7 +1414,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned ILOG("Starting Flash write for F2/F4\n"); /* flash loader initialization */ if (init_flash_loader(sl, &fl) == -1) { - WLOG("init_flash_loader() == -1\n"); + ELOG("init_flash_loader() == -1\n"); return -1; } @@ -1430,7 +1434,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned printf("size: %zu\n", size); if (run_flash_loader(sl, &fl, addr + off, base + off, size) == -1) { - WLOG("run_flash_loader(%#zx) failed! == -1\n", addr + off); + ELOG("run_flash_loader(%#zx) failed! == -1\n", addr + off); return -1; } @@ -1580,7 +1584,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned ILOG("Starting Flash write for VL core id\n"); /* flash loader initialization */ if (init_flash_loader(sl, &fl) == -1) { - WLOG("init_flash_loader() == -1\n"); + ELOG("init_flash_loader() == -1\n"); return -1; } @@ -1595,7 +1599,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned set_flash_cr_pg(sl); //DLOG("Finished setting flash cr pg, running loader!\n"); if (run_flash_loader(sl, &fl, addr + off, base + off, size) == -1) { - WLOG("run_flash_loader(%#zx) failed! == -1\n", addr + off); + ELOG("run_flash_loader(%#zx) failed! == -1\n", addr + off); return -1; } lock_flash(sl); @@ -1608,7 +1612,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned } fprintf(stdout, "\n"); } else { - WLOG("unknown coreid, not sure how to write: %x\n", sl->core_id); + ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); return -1; } @@ -1629,7 +1633,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM)?0:0xff; mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { - WLOG("map_file() == -1\n"); + ELOG("map_file() == -1\n"); return -1; } for(index = 0; index < mf.len; index ++) { @@ -1660,7 +1664,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons // FIXME This can never return -1 if (write_buffer_to_sram(sl, fl, buf, size) == -1) { // IMPOSSIBLE! - WLOG("write_buffer_to_sram() == -1\n"); + ELOG("write_buffer_to_sram() == -1\n"); return -1; } @@ -1699,20 +1703,22 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ } else { - fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id); + fprintf(stderr, "unknown coreid 0x%x, don't know what flash loader to use\n", sl->core_id); return -1; } /* run loader */ stlink_run(sl); +#define WAIT_ROUNDS 1000 /* wait until done (reaches breakpoint) */ - while ((is_core_halted(sl) == 0) && (i <1000)) { - i++; + for (i = 0; i < WAIT_ROUNDS; i++) { + if (is_core_halted(sl)) + break; } - if ( i > 999) { - fprintf(stderr, "run error\n"); + if (i >= WAIT_ROUNDS) { + fatal("flash loader run error\n"); return -1; } @@ -1746,7 +1752,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } else { - fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id); + fprintf(stderr, "unknown coreid 0x%x, can't check written byte count\n", sl->core_id); return -1; } From e8b15c0e787c7d5fc90c35d53165fcf36afb39e3 Mon Sep 17 00:00:00 2001 From: Pekka Nikander Date: Fri, 5 Oct 2012 15:34:03 +0300 Subject: [PATCH 0187/1435] Add support for STM32F0-Discovery --- flashloaders/stm32f0.s | 32 +++++++++++++++++++++ src/stlink-common.c | 63 ++++++++++++++++++++++++++++++++++++++---- src/stlink-common.h | 2 ++ 3 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 flashloaders/stm32f0.s diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s new file mode 100644 index 000000000..f35fe406e --- /dev/null +++ b/flashloaders/stm32f0.s @@ -0,0 +1,32 @@ +/* Adopted from STM AN4065 stm32f0xx_flash.c:FLASH_ProgramWord */ + +write: + ldr r4, STM32_FLASH_BASE + mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ + mov r6, #4 /* PGERR */ +write_half_word: + ldr r3, [r4, #16] /* FLASH->CR */ + orr r3, r5 + str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ + ldrh r3, [r0] /* r3 = *sram */ + strh r3, [r1] /* *flash = r3 */ +busy: + ldr r3, [r4, #12] /* FLASH->SR */ + tst r3, r5 /* FLASH_SR_BUSY */ + beq busy + + tst r3, r6 /* PGERR */ + bne exit + + add r0, r0, #2 /* sram += 2 */ + add r1, r1, #2 /* flash += 2 */ + sub r2, r2, #0x01 /* count-- */ + cmp r2, #0 + bne write_half_word +exit: + ldr r3, [r4, #16] /* FLASH->CR */ + bic r3, r5 + str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ + bkpt #0x00 + +STM32_FLASH_BASE: .word 0x40022000 diff --git a/src/stlink-common.c b/src/stlink-common.c index 702536aed..03de0b8ec 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -25,6 +25,7 @@ /* stm32f FPEC flash controller interface, pm0063 manual */ // TODO - all of this needs to be abstracted out.... +// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, August 2012) #define FLASH_REGS_ADDR 0x40022000 #define FLASH_REGS_SIZE 0x28 @@ -36,6 +37,7 @@ #define FLASH_OBR (FLASH_REGS_ADDR + 0x1c) #define FLASH_WRPR (FLASH_REGS_ADDR + 0x20) +// For STM32F05x, the RDPTR_KEY may be wrong, but as it is not used anywhere... #define FLASH_RDPTR_KEY 0x00a5 #define FLASH_KEY1 0x45670123 #define FLASH_KEY2 0xcdef89ab @@ -1083,7 +1085,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) val = stlink_read_debug32(sl, STM32L_FLASH_PECR) | (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - } else if (sl->core_id == STM32VL_CORE_ID) { + } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1191,6 +1193,54 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */ }; + /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ + static const uint8_t loader_code_stm32f0[] = { +#if 1 + /* + * These two NOPs here are a safety precaution, added by Pekka Nikander + * while debugging the STM32F05x support. They may not be needed, but + * there were strange problems with simpler programs, like a program + * that had just a breakpoint or a program that first moved zero to register r2 + * and then had a breakpoint. So, it appears safest to have these two nops. + * + * Feel free to remove them, if you dare, but then please do test the result + * rigorously. Also, if you remove these, it may be a good idea first to + * #if 0 them out, with a comment when these were taken out, and to remove + * these only a few months later... But YMMV. + */ + 0x00, 0x30, // nop /* add r0,#0 */ + 0x00, 0x30, // nop /* add r0,#0 */ +#endif + 0x0A, 0x4C, // ldr r4, STM32_FLASH_BASE + 0x01, 0x25, // mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ + 0x04, 0x26, // mov r6, #4 /* PGERR */ + // write_half_word: + 0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */ + 0x2B, 0x43, // orr r3, r5 + 0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ + 0x03, 0x88, // ldrh r3, [r0] /* r3 = *sram */ + 0x0B, 0x80, // strh r3, [r1] /* *flash = r3 */ + // busy: + 0xE3, 0x68, // ldr r3, [r4, #12] /* FLASH->SR */ + 0x2B, 0x42, // tst r3, r5 /* FLASH_SR_BUSY */ + 0xFC, 0xD0, // beq busy + + 0x33, 0x42, // tst r3, r6 /* PGERR */ + 0x04, 0xD1, // bne exit + + 0x02, 0x30, // add r0, r0, #2 /* sram += 2 */ + 0x02, 0x31, // add r1, r1, #2 /* flash += 2 */ + 0x01, 0x3A, // sub r2, r2, #0x01 /* count-- */ + 0x00, 0x2A, // cmp r2, #0 + 0xF0, 0xD1, // bne write_half_word + // exit: + 0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */ + 0xAB, 0x43, // bic r3, r5 + 0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ + 0x00, 0xBE, // bkpt #0x00 + 0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */ + }; + static const uint8_t loader_code_stm32l[] = { /* openocd.git/contrib/loaders/flash/stm32lx.S @@ -1246,6 +1296,9 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { loader_code = loader_code_stm32f4; loader_size = sizeof(loader_code_stm32f4); + } else if (sl->chip_id == STM32_CHIPID_F0) { + loader_code = loader_code_stm32f0; + loader_size = sizeof(loader_code_stm32f0); } else { ELOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); return -1; @@ -1580,8 +1633,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned val = stlink_read_debug32(sl, STM32L_FLASH_PECR) | (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - } else if (sl->core_id == STM32VL_CORE_ID) { - ILOG("Starting Flash write for VL core id\n"); + } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID) { + ILOG("Starting Flash write for VL/F0 core id\n"); /* flash loader initialization */ if (init_flash_loader(sl, &fl) == -1) { ELOG("init_flash_loader() == -1\n"); @@ -1679,7 +1732,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, count, 2); /* count (32 bits words) */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - } else if (sl->core_id == STM32VL_CORE_ID) { + } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID) { size_t count = size / sizeof(uint16_t); if (size % sizeof(uint16_t)) ++count; @@ -1734,7 +1787,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - } else if (sl->core_id == STM32VL_CORE_ID) { + } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { diff --git a/src/stlink-common.h b/src/stlink-common.h index 7ffdfc0cd..c5c7d407d 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -85,6 +85,7 @@ extern "C" { #define STM32VL_CORE_ID 0x1ba01477 #define STM32L_CORE_ID 0x2ba01477 #define STM32F4_CORE_ID 0x2ba01477 +#define STM32F0_CORE_ID 0xbb11477 #define CORE_M3_R1 0x1BA00477 #define CORE_M3_R2 0x4BA00477 #define CORE_M4_R0 0x2BA01477 @@ -104,6 +105,7 @@ extern "C" { #define STM32_CHIPID_F1_VL_MEDIUM 0x420 #define STM32_CHIPID_F1_VL_HIGH 0x428 #define STM32_CHIPID_F1_XL 0x430 +#define STM32_CHIPID_F0 0x440 // Constant STM32 memory map figures #define STM32_FLASH_BASE 0x08000000 From aa66f4ed87cd0d6f781440d8cd0e205eabcd425a Mon Sep 17 00:00:00 2001 From: "Wojciech A. Koszek" Date: Sat, 3 Nov 2012 23:20:17 -0700 Subject: [PATCH 0188/1435] Bring the support for STM32 F3 Discovery board (ARM Techcon 2012) Support was tested by attaching USB cable to USB ST-LINK USB port, starting ./st-util Which resulted in proper device recognition: 2012-11-03T23:11:25 INFO src/stlink-common.c: Device connected is: F3 device, id 0x10016422 2012-11-03T23:11:25 INFO src/stlink-common.c: SRAM size: 0xa000 bytes (40 KiB), Flash: 0x40000 bytes (256 KiB) in pages of 2048 bytes Chip ID is 00000422, Core ID is 2ba01477. Then from GDB, after "target remove localhost:4242", I tested reads: x/w 0x20000000 And writes: set {int}0x20000000 1 And ELF loading: (gdb) load main Loading section .text, size 0x10 lma 0x20000000 Start address 0x20000000, load size 16 Transfer rate: 410 bytes/sec, 16 bytes/write. And verified dissasembly (in my case--with Thumb mode) with objdump -d output: (gdb) set arm force-mode thumb (gdb) x/7i 0x20000000 => 0x20000000: push {r7} 0x20000002: sub sp, #12 0x20000004: add r7, sp, #0 0x20000006: ldr r3, [r7, #4] 0x20000008: add.w r3, r3, #1 0x2000000c: str r3, [r7, #4] 0x2000000e: b.n 0x20000006 --- src/stlink-common.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/stlink-common.h b/src/stlink-common.h index c5c7d407d..0330e624b 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -208,6 +208,17 @@ static const chip_params_t devices[] = { .bootrom_base = 0x1ffff000, .bootrom_size = 0x800 }, + { + // This is STK32F303VCT6 device from STM32 F3 Discovery board. + // Support based on DM00043574.pdf (RM0316) document. + .chip_id = 0x422, + .description = "F3 device", + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, { .chip_id = 0x428, .description = "F1 High-density value line device", From 79429149716d1fa2107b47cbcfde232db4a20747 Mon Sep 17 00:00:00 2001 From: lementec Date: Thu, 15 Nov 2012 17:37:00 +0100 Subject: [PATCH 0189/1435] [ merge ] STM32_CHIPIP_F3 patch from Geoffrey Brown --- src/stlink-common.c | 10 +++++----- src/stlink-common.h | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 03de0b8ec..66006f083 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1085,7 +1085,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) val = stlink_read_debug32(sl, STM32L_FLASH_PECR) | (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID) { + } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1290,7 +1290,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); - } else if (sl->core_id == STM32VL_CORE_ID) { + } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { @@ -1633,7 +1633,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned val = stlink_read_debug32(sl, STM32L_FLASH_PECR) | (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID) { + } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3) { ILOG("Starting Flash write for VL/F0 core id\n"); /* flash loader initialization */ if (init_flash_loader(sl, &fl) == -1) { @@ -1732,7 +1732,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, count, 2); /* count (32 bits words) */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID) { + } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3) { size_t count = size / sizeof(uint16_t); if (size % sizeof(uint16_t)) ++count; @@ -1787,7 +1787,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID) { + } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { diff --git a/src/stlink-common.h b/src/stlink-common.h index 0330e624b..6f451f5b8 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -84,6 +84,7 @@ extern "C" { // TODO clean this up... #define STM32VL_CORE_ID 0x1ba01477 #define STM32L_CORE_ID 0x2ba01477 +#define STM32F3_CORE_ID 0x2ba01477 #define STM32F4_CORE_ID 0x2ba01477 #define STM32F0_CORE_ID 0xbb11477 #define CORE_M3_R1 0x1BA00477 @@ -98,6 +99,7 @@ extern "C" { #define STM32_CHIPID_F1_MEDIUM 0x410 #define STM32_CHIPID_F2 0x411 #define STM32_CHIPID_F1_LOW 0x412 +#define STM32_CHIPID_F3 0x422 #define STM32_CHIPID_F4 0x413 #define STM32_CHIPID_F1_HIGH 0x414 #define STM32_CHIPID_L1_MEDIUM 0x416 From 08872f834db4f4954490e614ca80e59fa6f95dbe Mon Sep 17 00:00:00 2001 From: Fabien Le Mentec Date: Sun, 25 Nov 2012 09:50:44 -0600 Subject: [PATCH 0190/1435] [ merge ] Andreas Seltenreich patches --- gdbserver/gdb-server.c | 35 +++++++++++++++++++++++++++++------ src/stlink-common.c | 6 +++--- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 9d27ae48a..04490add6 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -1076,20 +1076,43 @@ int serve(stlink_t *sl, int port) { stm32_addr_t start = strtoul(s_start, NULL, 16); unsigned count = strtoul(s_count, NULL, 16); - for(unsigned int i = 0; i < count; i ++) { + if(start % 4) { + unsigned align_count = 4 - start % 4; + if (align_count > count) align_count = count; + for(unsigned int i = 0; i < align_count; i ++) { char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; uint8_t byte = strtoul(hex, NULL, 16); sl->q_buf[i] = byte; + } + stlink_write_mem8(sl, start, align_count); + start += align_count; + count -= align_count; + hexdata += 2*align_count; } - if((count % 4) == 0 && (start % 4) == 0) { - stlink_write_mem32(sl, start, count); - } else { - stlink_write_mem8(sl, start, count); + if(count - count % 4) { + unsigned aligned_count = count - count % 4; + + for(unsigned int i = 0; i < aligned_count; i ++) { + char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; + uint8_t byte = strtoul(hex, NULL, 16); + sl->q_buf[i] = byte; + } + stlink_write_mem32(sl, start, aligned_count); + count -= aligned_count; + start += aligned_count; + hexdata += 2*aligned_count; } + if(count) { + for(unsigned int i = 0; i < count; i ++) { + char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; + uint8_t byte = strtoul(hex, NULL, 16); + sl->q_buf[i] = byte; + } + stlink_write_mem8(sl, start, count); + } reply = strdup("OK"); - break; } diff --git a/src/stlink-common.c b/src/stlink-common.c index 66006f083..033cb5272 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -543,7 +543,7 @@ void stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); if (len % 4 != 0) { fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); - return; + abort(); } sl->backend->write_mem32(sl, addr, len); } @@ -553,7 +553,7 @@ void stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { if (len % 4 != 0) { // !!! never ever: fw gives just wrong values fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); - return; + abort(); } sl->backend->read_mem32(sl, addr, len); } @@ -563,7 +563,7 @@ void stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { if (len > 0x40 ) { // !!! never ever: Writing more then 0x40 bytes gives unexpected behaviour fprintf(stderr, "Error: Data length > 64: +%d byte.\n", len); - return; + abort(); } sl->backend->write_mem8(sl, addr, len); } From 7505f99b2a579534ddd69a1e4c476af4ed1e4a32 Mon Sep 17 00:00:00 2001 From: Fabien Le Mentec Date: Wed, 28 Nov 2012 12:48:50 -0600 Subject: [PATCH 0191/1435] [ merge ] patch from jgobat@gmail.com, add STM32F373 support --- src/stlink-common.c | 10 +++++----- src/stlink-common.h | 12 ++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 033cb5272..1ac3d6029 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1085,7 +1085,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) val = stlink_read_debug32(sl, STM32L_FLASH_PECR) | (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3) { + } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1290,7 +1290,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); - } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3) { + } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { @@ -1633,7 +1633,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned val = stlink_read_debug32(sl, STM32L_FLASH_PECR) | (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3) { + } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { ILOG("Starting Flash write for VL/F0 core id\n"); /* flash loader initialization */ if (init_flash_loader(sl, &fl) == -1) { @@ -1732,7 +1732,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, count, 2); /* count (32 bits words) */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3) { + } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { size_t count = size / sizeof(uint16_t); if (size % sizeof(uint16_t)) ++count; @@ -1787,7 +1787,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3) { + } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { diff --git a/src/stlink-common.h b/src/stlink-common.h index 6f451f5b8..6496a10c2 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -100,6 +100,7 @@ extern "C" { #define STM32_CHIPID_F2 0x411 #define STM32_CHIPID_F1_LOW 0x412 #define STM32_CHIPID_F3 0x422 +#define STM32_CHIPID_F37x 0x432 #define STM32_CHIPID_F4 0x413 #define STM32_CHIPID_F1_HIGH 0x414 #define STM32_CHIPID_L1_MEDIUM 0x416 @@ -221,6 +222,17 @@ static const chip_params_t devices[] = { .bootrom_base = 0x1ffff000, .bootrom_size = 0x800 }, + { + // This is STK32F373VCT6 device from STM32 F373 eval board + // Support based on 303 above (37x and 30x have same memory map) + .chip_id = 0x432, + .description = "F3 device", + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, { .chip_id = 0x428, .description = "F1 High-density value line device", From 1c2828cc914260a57299461373bf835f90043863 Mon Sep 17 00:00:00 2001 From: Fabien Le Mentec Date: Thu, 27 Dec 2012 07:00:46 -0600 Subject: [PATCH 0192/1435] [ merge ] patch from fischermi@t-online.de, GDB server endless loop --- gdbserver/gdb-server.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 04490add6..1b5fc8401 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -650,7 +650,8 @@ int serve(stlink_t *sl, int port) { perror("listen"); return 1; } - + +start_again: stlink_force_debug(sl); stlink_reset(sl); init_code_breakpoints(sl); @@ -681,7 +682,7 @@ int serve(stlink_t *sl, int port) { int status = gdb_recv_packet(client, &packet); if(status < 0) { fprintf(stderr, "cannot recv: %d\n", status); - return 1; + goto start_again; } #ifdef DEBUG @@ -1220,7 +1221,9 @@ int serve(stlink_t *sl, int port) { int result = gdb_send_packet(client, reply); if(result != 0) { fprintf(stderr, "cannot send: %d\n", result); - return 1; + free(reply); + free(packet); + goto start_again; } free(reply); From acbfa3ad6fb9c464bfd998b2cdd01989af6a55ed Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Mon, 31 Dec 2012 23:09:30 +0000 Subject: [PATCH 0193/1435] bump version --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 1f00f3a80..daf7da20a 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([stlink],[0.5.3],[davem@devkitpro.org]) +AC_INIT([stlink],[0.5.4],[davem@devkitpro.org]) AC_CONFIG_SRCDIR([src/stlink-common.c]) AC_CONFIG_LIBOBJ_DIR([src]) AM_INIT_AUTOMAKE([1.10]) From 79b413ca5b898982a79aa6673c44f9cd22f05c5b Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Mon, 31 Dec 2012 23:11:46 +0000 Subject: [PATCH 0194/1435] bump version --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index daf7da20a..df41a3dbd 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([stlink],[0.5.4],[davem@devkitpro.org]) +AC_INIT([stlink],[0.5.5],[davem@devkitpro.org]) AC_CONFIG_SRCDIR([src/stlink-common.c]) AC_CONFIG_LIBOBJ_DIR([src]) AM_INIT_AUTOMAKE([1.10]) From da129b2ccdc00ff9a33c708718656935cc0efe82 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sun, 6 Jan 2013 15:33:48 +0000 Subject: [PATCH 0195/1435] fix write_flash size of len for 64bit --- src/stlink-common.c | 2 +- src/stlink-common.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 1ac3d6029..82d607089 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1415,7 +1415,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uns return 0; } -int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned len) { +int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { size_t off; flash_loader_t fl; ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", diff --git a/src/stlink-common.h b/src/stlink-common.h index 6496a10c2..a2b73d93b 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -410,10 +410,10 @@ static const chip_params_t devices[] = { // unprocessed int stlink_erase_flash_mass(stlink_t* sl); - int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, unsigned length); + int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length); 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, unsigned length); + 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); From f22b91b57a9dea96113946b810394e9fd1a524e5 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sun, 6 Jan 2013 15:34:54 +0000 Subject: [PATCH 0196/1435] file needs to be Binary for windows O_BINARY only defined on windows --- src/stlink-common.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 82d607089..2d7db142c 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -14,6 +14,10 @@ #include "stlink-common.h" #include "uglylogging.h" +#ifndef _WIN32 +#define O_BINARY 0 +#endif + #define LOG_TAG __FILE__ #define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args) #define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args) @@ -757,7 +761,7 @@ static int map_file(mapped_file_t* mf, const char* path) { int error = -1; struct stat st; - const int fd = open(path, O_RDONLY); + const int fd = open(path, O_RDONLY | O_BINARY); if (fd == -1) { fprintf(stderr, "open(%s) == -1\n", path); return -1; From 23884e8b42e035d35cfe0f1c969a9938516700a2 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Sun, 6 Jan 2013 16:00:57 +0000 Subject: [PATCH 0197/1435] bump version --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index df41a3dbd..e8923ed36 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([stlink],[0.5.5],[davem@devkitpro.org]) +AC_INIT([stlink],[0.5.6],[davem@devkitpro.org]) AC_CONFIG_SRCDIR([src/stlink-common.c]) AC_CONFIG_LIBOBJ_DIR([src]) AM_INIT_AUTOMAKE([1.10]) From 0ed390771c0ace3f048153591ec7476cc54b9392 Mon Sep 17 00:00:00 2001 From: A Sheaff Date: Wed, 9 Jan 2013 17:00:52 -0500 Subject: [PATCH 0198/1435] Clears DMA config registers for Discovery F4 board to allow flash programming. See texane/stlink issue #74. --- flash/main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/flash/main.c b/flash/main.c index 4716b66e1..1d616ae95 100644 --- a/flash/main.c +++ b/flash/main.c @@ -123,6 +123,14 @@ int main(int ac, char** av) if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); +// Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 + memset(sl->q_buf,0,4); + for (int i=0;i<8;i++) { + stlink_write_mem32(sl,0x40026000+0x10+0x18*i,4); + stlink_write_mem32(sl,0x40026400+0x10+0x18*i,4); + stlink_write_mem32(sl,0x40026000+0x24+0x18*i,4); + stlink_write_mem32(sl,0x40026400+0x24+0x18*i,4); + } if (o.cmd == DO_WRITE) /* write */ { if ((o.addr >= sl->flash_base) && From 44445dd7b0f557bb9ff2fe22e0da17b03560c673 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Tue, 12 Feb 2013 19:38:46 +0100 Subject: [PATCH 0199/1435] Fix byte count when doing unaligned memory read, fix issue #127 - when start is adjusted, count should also be adjusted, - then, count is rounded to the next multiple of word size. --- gdbserver/gdb-server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 1b5fc8401..f92fc05f0 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -1056,9 +1056,9 @@ int serve(stlink_t *sl, int port) { unsigned count = strtoul(s_count, NULL, 16); unsigned adj_start = start % 4; + unsigned count_rnd = (count + adj_start + 4 - 1) / 4 * 4; - stlink_read_mem32(sl, start - adj_start, (count % 4 == 0) ? - count : count + 4 - (count % 4)); + stlink_read_mem32(sl, start - adj_start, count_rnd); reply = calloc(count * 2 + 1, 1); for(unsigned int i = 0; i < count; i++) { From 3569970998cb8c15acb7754c167c5f35dad70a72 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 6 Mar 2013 12:03:27 -0500 Subject: [PATCH 0200/1435] Revert "[ merge ] patch from fischermi@t-online.de, GDB server endless loop" This reverts commit 1c2828cc914260a57299461373bf835f90043863. --- gdbserver/gdb-server.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index f92fc05f0..5f0a43b68 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -650,8 +650,7 @@ int serve(stlink_t *sl, int port) { perror("listen"); return 1; } - -start_again: + stlink_force_debug(sl); stlink_reset(sl); init_code_breakpoints(sl); @@ -682,7 +681,7 @@ int serve(stlink_t *sl, int port) { int status = gdb_recv_packet(client, &packet); if(status < 0) { fprintf(stderr, "cannot recv: %d\n", status); - goto start_again; + return 1; } #ifdef DEBUG @@ -1221,9 +1220,7 @@ int serve(stlink_t *sl, int port) { int result = gdb_send_packet(client, reply); if(result != 0) { fprintf(stderr, "cannot send: %d\n", result); - free(reply); - free(packet); - goto start_again; + return 1; } free(reply); From 9bed540624ac45ff334917a51c564caa278d5833 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 6 Mar 2013 12:52:12 -0500 Subject: [PATCH 0201/1435] Add persistence support to gdb-server When started with -m, or connected with 'target extended-remote', the GDB server will not terminate upon disconnection from GDB, instead it will begin listening for conenctions again. Starting with extended-remote also has the advantage of allowing 'run' to be used to reset the target and begin again. Unfortunately, 'start' is not working properly, as it does not send a reset packet (R), so it complains when it tries to access memory before it is connected to the target. --- gdbserver/gdb-server.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 5f0a43b68..414ad8a7b 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -40,6 +40,11 @@ static const char hex[] = "0123456789abcdef"; static const char* current_memory_map = NULL; +/* Persistent mode flag. + * In persistent mode, server starts listening again + * on GDB disconnect. */ +int persistent = 0; + typedef struct _st_state_t { // things from command line, bleh int stlink_version; @@ -62,6 +67,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { {"stlink_version", required_argument, NULL, 's'}, {"stlinkv1", no_argument, NULL, '1'}, {"listen_port", required_argument, NULL, 'p'}, + {"multi", optional_argument, NULL, 'm'}, {0, 0, 0, 0}, }; const char * help_str = "%s - usage:\n\n" @@ -76,13 +82,16 @@ int parse_options(int argc, char** argv, st_state_t *st) { " -p 4242, --listen_port=1234\n" "\t\t\tSet the gdb server listen port. " "(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n" + " -m, --multi\n" + "\t\t\tSet gdb server to extended mode.\n" + "\t\t\tst-util will continue listening for connections after disconnect.\n" ; int option_index = 0; int c; int q; - while ((c = getopt_long(argc, argv, "hv::d:s:1p:", long_options, &option_index)) != -1) { + while ((c = getopt_long(argc, argv, "hv::d:s:1p:m", long_options, &option_index)) != -1) { switch (c) { case 0: printf("XXXXX Shouldn't really normally come here, only if there's no corresponding option\n"); @@ -129,6 +138,9 @@ int parse_options(int argc, char** argv, st_state_t *st) { } st->listen_port = q; break; + case 'm': + persistent = 1; + break; } } @@ -177,7 +189,9 @@ int main(int argc, char** argv) { } #endif - while(serve(sl, state.listen_port) == 0); + do { + serve(sl, state.listen_port); + } while (persistent); #ifdef __MINGW32__ winsock_error: @@ -1189,6 +1203,12 @@ int serve(stlink_t *sl, int port) { * We do support that always. */ + /* + * Also, set to persistent mode + * to allow GDB disconnect. + */ + persistent = 1; + reply = strdup("OK"); break; @@ -1220,6 +1240,8 @@ int serve(stlink_t *sl, int port) { int result = gdb_send_packet(client, reply); if(result != 0) { fprintf(stderr, "cannot send: %d\n", result); + free(reply); + free(packet); return 1; } From 4d1ee4d97eb5d282833e542dfb88192240381ed4 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 6 Mar 2013 14:23:17 -0500 Subject: [PATCH 0202/1435] Move persistence flag to st_state_t It makes sense for it to be with all other state data. This meant passing the entire state struct into serve. --- gdbserver/gdb-server.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 414ad8a7b..8190e1061 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -40,11 +40,6 @@ static const char hex[] = "0123456789abcdef"; static const char* current_memory_map = NULL; -/* Persistent mode flag. - * In persistent mode, server starts listening again - * on GDB disconnect. */ -int persistent = 0; - typedef struct _st_state_t { // things from command line, bleh int stlink_version; @@ -52,10 +47,11 @@ typedef struct _st_state_t { char devicename[100]; int logging_level; int listen_port; + int persistent; } st_state_t; -int serve(stlink_t *sl, int port); +int serve(stlink_t *sl, st_state_t *st); char* make_memory_map(stlink_t *sl); @@ -139,7 +135,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { st->listen_port = q; break; case 'm': - persistent = 1; + st->persistent = 1; break; } } @@ -190,8 +186,8 @@ int main(int argc, char** argv) { #endif do { - serve(sl, state.listen_port); - } while (persistent); + serve(sl, &state); + } while (state.persistent); #ifdef __MINGW32__ winsock_error: @@ -639,7 +635,7 @@ static int flash_go(stlink_t *sl) { return error; } -int serve(stlink_t *sl, int port) { +int serve(stlink_t *sl, st_state_t *st) { int sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0) { perror("socket"); @@ -653,7 +649,7 @@ int serve(stlink_t *sl, int port) { memset(&serv_addr,0,sizeof(struct sockaddr_in)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - serv_addr.sin_port = htons(port); + serv_addr.sin_port = htons(st->listen_port); if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { perror("bind"); @@ -670,7 +666,7 @@ int serve(stlink_t *sl, int port) { init_code_breakpoints(sl); init_data_watchpoints(sl); - printf("Listening at *:%d...\n", port); + printf("Listening at *:%d...\n", st->listen_port); int client = accept(sock, NULL, NULL); //signal (SIGINT, SIG_DFL); @@ -1207,7 +1203,7 @@ int serve(stlink_t *sl, int port) { * Also, set to persistent mode * to allow GDB disconnect. */ - persistent = 1; + st->persistent = 1; reply = strdup("OK"); From 2216d28452f5e97088fbfd4bd6f6daf187d5e53a Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 6 Mar 2013 16:15:15 -0500 Subject: [PATCH 0203/1435] Add SIGINT handler for stlink cleanup SIGINT causes st-util to immediately exit, without closing the open stlink. This leaves devices (at least the F4 Discovery) in a state where they are unable to reset. st-util could still connect and control them, but a power cycle was required before they could reset on their own. A signal handler is added for SIGINT, which performs cleanup and closing of the open stlink device, allowing it to function normally on disconnect. --- gdbserver/gdb-server.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 8190e1061..32f0d8baf 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -36,6 +36,8 @@ //Allways update the FLASH_PAGE before each use, by calling stlink_calculate_pagesize #define FLASH_PAGE (sl->flash_pgsz) +stlink_t *connected_stlink = NULL; + static const char hex[] = "0123456789abcdef"; static const char* current_memory_map = NULL; @@ -54,6 +56,16 @@ typedef struct _st_state_t { int serve(stlink_t *sl, st_state_t *st); char* make_memory_map(stlink_t *sl); +static void cleanup(int signal __attribute__((unused))) { + if (connected_stlink) { + /* Switch back to mass storage mode before closing. */ + stlink_run(connected_stlink); + stlink_exit_debug_mode(connected_stlink); + stlink_close(connected_stlink); + } + + exit(1); +} int parse_options(int argc, char** argv, st_state_t *st) { static struct option long_options[] = { @@ -172,6 +184,9 @@ int main(int argc, char** argv) { break; } + connected_stlink = sl; + signal(SIGINT, &cleanup); + printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); sl->verbose=0; From 69fecdca633e72547e90245d327d5d92c0488be8 Mon Sep 17 00:00:00 2001 From: Ian Griffiths <6thimage@gmail.com> Date: Wed, 20 Mar 2013 13:01:49 +0000 Subject: [PATCH 0204/1435] Added lock state check to stlink_erase_flash_page. On the STM32L152 processor, the erase fails for the first page as the lock is already disabled (with the unlocking code causing the lock to become re-enabled). This commit adds checking of the lock state and will only unlock if necessary. --- src/stlink-common.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 2d7db142c..4c662fbcf 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1023,26 +1023,30 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) uint32_t val; - /* disable pecr protection */ - stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); - stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405); - - /* check pecr.pelock is cleared */ + /* check if the locks are set */ val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 0)) { - WLOG("pecr.pelock not clear (%#x)\n", val); - return -1; - } + if((val & (1<<0))||(val & (1<<1))) { + /* disable pecr protection */ + stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); + stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405); + + /* check pecr.pelock is cleared */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + if (val & (1 << 0)) { + WLOG("pecr.pelock not clear (%#x)\n", val); + return -1; + } - /* unlock program memory */ - stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf); - stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516); + /* unlock program memory */ + stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf); + stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516); - /* check pecr.prglock is cleared */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 1)) { - WLOG("pecr.prglock not clear (%#x)\n", val); - return -1; + /* check pecr.prglock is cleared */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + if (val & (1 << 1)) { + WLOG("pecr.prglock not clear (%#x)\n", val); + return -1; + } } /* unused: unlock the option byte block */ From 0b2c10568773f84e06e65258359653d85cb4754e Mon Sep 17 00:00:00 2001 From: Ian Griffiths <6thimage@gmail.com> Date: Thu, 21 Mar 2013 16:28:15 +0000 Subject: [PATCH 0205/1435] Limited DMA clearing to STM32F4, removed fatal error for flash loading. Commit 0ed3907 added the clearing of DMA registers that was preventing programming (see issue #74), however it uses hardcoded addresses of the DMA registers on the STM32F4. This seems to prevent the flashing and verification on STM32L1, as the registers only partly cover the range zeroed. So the DMA clearing has been limited to the STM32F4 microcontroller. Additionally, sometimes, typically directly after erases, a 'flash loader run error' will occur that terminates the writing. This is not necessary, as the writing is successfully performed by page writing (line 1581 onwards of stlink-common.c), and so has been returned to a error message (see issue #112). There is a comment on line 1574 (added by Uwe Bonnes in commit 0164043f) that this may happen on blank devices, and so the fatal error message is the incorrect response. --- flash/main.c | 3 +++ src/stlink-common.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/flash/main.c b/flash/main.c index 1d616ae95..110c2964d 100644 --- a/flash/main.c +++ b/flash/main.c @@ -124,6 +124,8 @@ int main(int ac, char** av) stlink_enter_swd_mode(sl); // Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 + if (sl->chip_id == STM32_CHIPID_F4) + { memset(sl->q_buf,0,4); for (int i=0;i<8;i++) { stlink_write_mem32(sl,0x40026000+0x10+0x18*i,4); @@ -131,6 +133,7 @@ int main(int ac, char** av) stlink_write_mem32(sl,0x40026000+0x24+0x18*i,4); stlink_write_mem32(sl,0x40026400+0x24+0x18*i,4); } + } if (o.cmd == DO_WRITE) /* write */ { if ((o.addr >= sl->flash_base) && diff --git a/src/stlink-common.c b/src/stlink-common.c index 4c662fbcf..a60f2b670 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1779,7 +1779,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } if (i >= WAIT_ROUNDS) { - fatal("flash loader run error\n"); + ELOG("flash loader run error\n"); return -1; } From 8df5b3be5edd177ecbbc355fff976b6afba20962 Mon Sep 17 00:00:00 2001 From: Fabien Le Mentec Date: Mon, 1 Apr 2013 15:36:52 -0500 Subject: [PATCH 0206/1435] [ update ] bind gdb server on INADDR_ANY, as requested by thomas@popp.ws --- gdbserver/gdb-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 32f0d8baf..ad7ce6570 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -663,7 +663,7 @@ int serve(stlink_t *sl, st_state_t *st) { struct sockaddr_in serv_addr; memset(&serv_addr,0,sizeof(struct sockaddr_in)); serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(st->listen_port); if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { From e5772dffbf7c1e9dbe6b9d6b5a013bf3d487ce5f Mon Sep 17 00:00:00 2001 From: Jack Peel Date: Wed, 3 Apr 2013 16:43:13 -0700 Subject: [PATCH 0207/1435] Add Support for STM32L1xx Medium Plus and High density Devices Using reference RM0038 Rev 7 The flash size register moved and the values in the registers changed their meaning Note that Medium Plus and High density deives have the same device ID, but only the Medium Plus definition is used in the code (the High comes along for free) --- src/stlink-common.c | 28 +++++++++++++++++++--------- src/stlink-common.h | 11 +++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index a60f2b670..9603cb264 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -18,6 +18,7 @@ #define O_BINARY 0 #endif + #define LOG_TAG __FILE__ #define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args) #define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args) @@ -451,6 +452,14 @@ int stlink_load_device_params(stlink_t *sl) { sl->flash_size = 0x100000; /* Use maximum, User must care!*/ } else if (sl->chip_id == STM32_CHIPID_F4) { sl->flash_size = 0x100000; //todo: RM0090 error; size register same address as unique ID + } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_L1_MEDIUM_PLUS) { + uint32_t flash_size = stlink_read_debug32(sl, params->flash_size_reg) & 0x1; + // 0 is 384k and 1 is 256k + if ( flash_size == 0 ) { + sl->flash_size = 384 * 1024; + } else { + sl->flash_size = 256 * 1024; + } } else { uint32_t flash_size = stlink_read_debug32(sl, params->flash_size_reg) & 0xffff; sl->flash_size = flash_size * 1024; @@ -833,6 +842,7 @@ int stlink_fwrite_sram size_t off; mapped_file_t mf = MAPPED_FILE_INITIALIZER; + if (map_file(&mf, path) == -1) { fprintf(stderr, "map_file() == -1\n"); return -1; @@ -853,7 +863,6 @@ int stlink_fwrite_sram fprintf(stderr, "unaligned addr or size\n"); goto on_error; } - /* do the copy by 1k blocks */ for (off = 0; off < mf.len; off += 1024) { size_t size = 1024; @@ -894,7 +903,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) int error = -1; size_t off; int num_empty = 0; - unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM)?0:0xff; + unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS)?0:0xff; const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); if (fd == -1) { @@ -1019,7 +1028,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) #if DEBUG_FLASH fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); #endif - } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { + } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) { uint32_t val; @@ -1125,7 +1134,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } int stlink_erase_flash_mass(stlink_t *sl) { - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS ) { /* erase each page */ int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -1295,7 +1304,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { const uint8_t* loader_code; size_t loader_size; - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { /* stm32l */ + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS ) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { @@ -1535,7 +1544,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } //STM32F4END - else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { + else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) { /* use fast word write. todo: half page. */ uint32_t val; @@ -1691,7 +1700,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { /* write the file in flash at addr */ int err; unsigned int num_empty = 0, index; - unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM)?0:0xff; + unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS)?0:0xff; mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { ELOG("map_file() == -1\n"); @@ -1729,7 +1738,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1774,6 +1783,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons #define WAIT_ROUNDS 1000 /* wait until done (reaches breakpoint) */ for (i = 0; i < WAIT_ROUNDS; i++) { + usleep(10); if (is_core_halted(sl)) break; } @@ -1784,7 +1794,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } /* check written byte count */ - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; diff --git a/src/stlink-common.h b/src/stlink-common.h index a2b73d93b..f0141aa06 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -104,6 +104,8 @@ extern "C" { #define STM32_CHIPID_F4 0x413 #define STM32_CHIPID_F1_HIGH 0x414 #define STM32_CHIPID_L1_MEDIUM 0x416 +#define STM32_CHIPID_L1_MEDIUM_PLUS 0x436 +#define STM32_CHIPID_L1_HIGH 0x436 #define STM32_CHIPID_F1_CONN 0x418 #define STM32_CHIPID_F1_VL_MEDIUM 0x420 #define STM32_CHIPID_F1_VL_HIGH 0x428 @@ -193,6 +195,15 @@ static const chip_params_t devices[] = { .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000 }, + { + .chip_id = STM32_CHIPID_L1_MEDIUM_PLUS, + .description = "L1 Medium-Plus-density device", + .flash_size_reg = 0x1ff800CC, + .flash_pagesize = 0x100, + .sram_size = 0x8000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, { .chip_id = 0x418, .description = "F1 Connectivity line device", From 55b9ecd36c35669510b70cfaac53098e8a786587 Mon Sep 17 00:00:00 2001 From: Jack Peel Date: Fri, 5 Apr 2013 09:06:26 -0700 Subject: [PATCH 0208/1435] Add support for the STM32L1 Medium density device flash size calculation In devices before "Rev X" the flash size register is 0 so we assume 128k Note that "Rev X" is a LATER revision than "Rev Y" and others that might seem like they are later! --- src/stlink-common.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index 9603cb264..05ee12cd3 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -452,6 +452,14 @@ int stlink_load_device_params(stlink_t *sl) { sl->flash_size = 0x100000; /* Use maximum, User must care!*/ } else if (sl->chip_id == STM32_CHIPID_F4) { sl->flash_size = 0x100000; //todo: RM0090 error; size register same address as unique ID + } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { + // if the flash size is zero, we assume it is 128k, if not we calculate the real value + uint32_t flash_size = stlink_read_debug32(sl,params->flash_size_reg) & 0xffff; + if ( flash_size == 0 ) { + sl->flash_size = 128 * 1024; + } else { + sl->flash_size = flash_size * 1024; + } } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_L1_MEDIUM_PLUS) { uint32_t flash_size = stlink_read_debug32(sl, params->flash_size_reg) & 0x1; // 0 is 384k and 1 is 256k From 04c142c69b0075a2004896d7046fe78fd015a02c Mon Sep 17 00:00:00 2001 From: Jack Peel Date: Fri, 5 Apr 2013 17:55:19 -0700 Subject: [PATCH 0209/1435] Add SIGTERM signal handler to also call cleanup When stopping st-util under Eclipse as an external tool the st-util receives a SIGTERM signal, and would not return the device to usb mass storage mode. This change now calls cleanup in the SIGTERM handler too!! --- gdbserver/gdb-server.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index ad7ce6570..f9c06f983 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -67,6 +67,8 @@ static void cleanup(int signal __attribute__((unused))) { exit(1); } + + int parse_options(int argc, char** argv, st_state_t *st) { static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, @@ -186,6 +188,7 @@ int main(int argc, char** argv) { connected_stlink = sl; signal(SIGINT, &cleanup); + signal(SIGTERM, &cleanup); printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); From 821a21482f93e65376fd99032da3f5e8db79951b Mon Sep 17 00:00:00 2001 From: Andrey Yurovsky Date: Sat, 13 Apr 2013 22:32:09 -0700 Subject: [PATCH 0210/1435] Don't use magic numbers for chip_id field The chip IDs are defined up top and those macros are used throughout the code so let's remove the magic numbers in .chip_id so that everything is using the macros. No functionality changes, just a find/replace. --- src/stlink-common.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/stlink-common.h b/src/stlink-common.h index f0141aa06..68f5082e4 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -140,7 +140,7 @@ extern "C" { // also the Reference manuals. (flash size reg is normally in ref man) static const chip_params_t devices[] = { { // table 2, PM0063 - .chip_id = 0x410, + .chip_id = STM32_CHIPID_F1_MEDIUM, .description = "F1 Medium-density device", .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, @@ -149,7 +149,7 @@ static const chip_params_t devices[] = { .bootrom_size = 0x800 }, { // table 1, PM0059 - .chip_id = 0x411, + .chip_id = STM32_CHIPID_F2, .description = "F2 device", .flash_size_reg = 0, /* no flash size reg found in the docs! */ .flash_pagesize = 0x20000, @@ -158,7 +158,7 @@ static const chip_params_t devices[] = { .bootrom_size = 0x7800 }, { // PM0063 - .chip_id = 0x412, + .chip_id = STM32_CHIPID_F1_LOW, .description = "F1 Low-density device", .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, @@ -167,7 +167,7 @@ static const chip_params_t devices[] = { .bootrom_size = 0x800 }, { - .chip_id = 0x413, + .chip_id = STM32_CHIPID_F4, .description = "F4 device", .flash_size_reg = 0x1FFF7A10, //RM0090 error same as unique ID .flash_pagesize = 0x4000, @@ -176,7 +176,7 @@ static const chip_params_t devices[] = { .bootrom_size = 0x7800 }, { - .chip_id = 0x414, + .chip_id = STM32_CHIPID_F1_HIGH, .description = "F1 High-density device", .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -187,7 +187,7 @@ static const chip_params_t devices[] = { { // This ignores the EEPROM! (and uses the page erase size, // not the sector write protection...) - .chip_id = 0x416, + .chip_id = STM32_CHIPID_L1_MEDIUM, .description = "L1 Med-density device", .flash_size_reg = 0x1ff8004c, .flash_pagesize = 0x100, @@ -205,7 +205,7 @@ static const chip_params_t devices[] = { .bootrom_size = 0x1000 }, { - .chip_id = 0x418, + .chip_id = STM32_CHIPID_F1_CONN, .description = "F1 Connectivity line device", .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -214,7 +214,7 @@ static const chip_params_t devices[] = { .bootrom_size = 0x4800 }, { - .chip_id = 0x420, + .chip_id = STM32_CHIPID_F1_VL_MEDIUM, .description = "F1 Medium-density Value Line device", .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, @@ -225,7 +225,7 @@ static const chip_params_t devices[] = { { // This is STK32F303VCT6 device from STM32 F3 Discovery board. // Support based on DM00043574.pdf (RM0316) document. - .chip_id = 0x422, + .chip_id = STM32_CHIPID_F3, .description = "F3 device", .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, @@ -236,7 +236,7 @@ static const chip_params_t devices[] = { { // This is STK32F373VCT6 device from STM32 F373 eval board // Support based on 303 above (37x and 30x have same memory map) - .chip_id = 0x432, + .chip_id = STM32_CHIPID_F37x, .description = "F3 device", .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, @@ -245,7 +245,7 @@ static const chip_params_t devices[] = { .bootrom_size = 0x800 }, { - .chip_id = 0x428, + .chip_id = STM32_CHIPID_F1_VL_HIGH, .description = "F1 High-density value line device", .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -254,7 +254,7 @@ static const chip_params_t devices[] = { .bootrom_size = 0x800 }, { - .chip_id = 0x430, + .chip_id = STM32_CHIPID_F1_XL, .description = "F1 XL-density device", .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -265,7 +265,7 @@ static const chip_params_t devices[] = { { //Use this as an example for mapping future chips: //RM0091 document was used to find these paramaters - .chip_id = 0x440, + .chip_id = STM32_CHIPID_F0, .description = "F0 device", .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 From 90d380e8d15ce5a7d1e4190794e212e26cbe6a2b Mon Sep 17 00:00:00 2001 From: Alexey Cherevatenko Date: Tue, 23 Apr 2013 15:17:09 +0300 Subject: [PATCH 0211/1435] Environment STLINK_DEVICE allow to choose ST_LINK --- src/stlink-usb.c | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 277431a87..825ee0aea 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -729,15 +729,46 @@ stlink_t* stlink_open_usb(const int verbose) { goto on_error; } - slu->usb_handle = libusb_open_device_with_vid_pid(slu->libusb_ctx, USB_ST_VID, USB_STLINK_32L_PID); - if (slu->usb_handle == NULL) { - slu->usb_handle = libusb_open_device_with_vid_pid(slu->libusb_ctx, USB_ST_VID, USB_STLINK_PID); - if (slu->usb_handle == NULL) { - WLOG("Couldn't find any ST-Link/V2 devices\n"); + libusb_device **list; + int cnt = libusb_get_device_list(slu->libusb_ctx, &list); + struct libusb_device_descriptor desc; + int devBus =0; + int devAddr=0; + + char *device = getenv("STLINK_DEVICE"); + if (device) { + char *c = strchr(device,':'); + if (c==NULL) { + WLOG("STLINK_DEVICE must be : format\n"); goto on_error; } - slu->protocoll = 1; + devBus=atoi(device); + *c++=0; + devAddr=atoi(c); + ILOG("bus %03d dev %03d\n",devBus, devAddr); + } + while (cnt){ + cnt--; + libusb_get_device_descriptor( list[cnt], &desc ); + 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_PID) slu->protocoll = 1; break; + } + + if (cnt==0){ + WLOG("Couldn't find %s ST-Link/V2 devices\n",(devBus && devAddr)?"matched":"any"); + goto on_error; + } else { + if( libusb_open(list[cnt], &slu->usb_handle) !=0){ + WLOG("Couldn't open ST-Link/V2 device %03d:%03d\n",libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); + goto on_error; + } } + + libusb_free_device_list(list, 1); + if (libusb_kernel_driver_active(slu->usb_handle, 0) == 1) { int r; From 74138a7f93f3f66d03ddebe243f6b7db4a90b9a6 Mon Sep 17 00:00:00 2001 From: Andrew 'Necromant' Andrianov Date: Mon, 6 May 2013 01:50:35 +0400 Subject: [PATCH 0212/1435] Add STlink terminal draft Signed-off-by: Andrew 'Necromant' Andrianov --- Makefile.am | 10 ++- src/st-term.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 src/st-term.c diff --git a/Makefile.am b/Makefile.am index a315dd726..9c99297ec 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,18 +2,20 @@ AUTOMAKE_OPTIONS = subdir-objects -bin_PROGRAMS = st-flash st-util +bin_PROGRAMS = st-flash st-util st-term noinst_LIBRARIES = libstlink.a st_flash_SOURCES = flash/main.c +st_term_SOURCES = src/st-term.c st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c mingw/mingw.c mingw/mingw.h CFILES = \ src/stlink-common.c \ src/stlink-usb.c \ src/stlink-sg.c \ - src/uglylogging.c + src/uglylogging.c \ + src/st-term.c HFILES = \ src/stlink-common.h \ @@ -33,5 +35,9 @@ st_flash_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_src st_util_LDADD = libstlink.a st_util_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw +st_term_LDADD = libstlink.a +st_term_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw + + EXTRA_DIST = autogen.sh diff --git a/src/st-term.c b/src/st-term.c new file mode 100644 index 000000000..f442d56fd --- /dev/null +++ b/src/st-term.c @@ -0,0 +1,174 @@ +#include +#include "stlink-common.h" + +#define STLINKY_MAGIC 0xDEADF00D + +struct stlinky { + stlink_t *sl; + uint32_t off; + size_t bufsize; +}; + +void dump_qbuf(stlink_t* s) +{ + printf("== 0x%x\n", *(uint32_t*)s->q_buf); +} + +/* Detects stlinky in RAM, returns handler */ +struct stlinky* stlinky_detect(stlink_t* sl) +{ + static const uint32_t sram_base = 0x20000000; + struct stlinky* st = malloc(sizeof(struct stlinky)); + st->sl = sl; + printf("sram: 0x%x bytes @ 0x%x\n", sl->sram_base, sl->sram_size); + uint32_t off; + for (off = 0; off < sl->sram_size; off += 4) { + stlink_read_mem32(sl, sram_base + off, 4); + if ( STLINKY_MAGIC== *(uint32_t*) sl->q_buf) + { + printf("stlinky detected at 0x%x\n", sram_base + off); + st->off = sram_base + off; + stlink_read_mem32(sl, st->off + 4, 4); + st->bufsize = (size_t) *(unsigned char*) sl->q_buf; + printf("stlinky buffer size 0x%zu (%hhx)\n", st->bufsize); + return st; + } + } + return NULL; +} + + +size_t stlinky_rx(struct stlinky *st, char* buffer) +{ + unsigned char tx = 0; + while(tx == 0) { + stlink_read_mem32(st->sl, st->off+4, 4); + tx = (unsigned char) st->sl->q_buf[1]; + } + size_t rs = tx + (4 - (tx % 4)); /* voodoo */ + stlink_read_mem32(st->sl, st->off+8, rs); + printf(st->sl->q_buf); + *st->sl->q_buf=0x0; + stlink_write_mem8(st->sl, st->off+5, 1); +} + + +int main(int ac, char** av) { + stlink_t* sl; + reg regs; + + /* unused */ + ac = ac; + av = av; + + sl = stlink_open_usb(10); + if (sl != NULL) { + printf("ST Link terminal :: Created by Necromant\n"); + stlink_version(sl); + + printf("mode before doing anything: %d\n", stlink_current_mode(sl)); + + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { + printf("-- exit_dfu_mode\n"); + stlink_exit_dfu_mode(sl); + } + + printf("-- enter_swd_mode\n"); + stlink_enter_swd_mode(sl); + + printf("-- mode after entering swd mode: %d\n", stlink_current_mode(sl)); + + printf("-- chip id: %#x\n", sl->chip_id); + printf("-- core_id: %#x\n", sl->core_id); + + cortex_m3_cpuid_t cpuid; + stlink_cpu_id(sl, &cpuid); + printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); + printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); + + stlink_reset(sl); + stlink_force_debug(sl); + stlink_run(sl); + stlink_status(sl); + /* wait for device to boot */ + + sleep(1); + + struct stlinky *st = stlinky_detect(sl); + if (st == NULL) + { + printf("stlinky magic not found in sram :("); + } + + while(1) { + stlinky_rx(st, NULL); + } + //sleep(90); + + printf("-- read_sram\n"); + // static const uint32_t sram_base = 0x8000000; + // uint32_t off; + //for (off = 0; off < 16; off += 4) + // stlink_read_mem32(sl, sram_base + off, 4); + + //printf("FP_CTRL\n"); + //stlink_read_mem32(sl, CM3_REG_FP_CTRL, 4); + + // no idea what reg this is.. */ + // stlink_read_mem32(sl, 0xe000ed90, 4); + // no idea what register this is... + // stlink_read_mem32(sl, 0xe000edf0, 4); + // offset 0xC into TIM11 register? TIMx_DIER? + // stlink_read_mem32(sl, 0x4001100c, 4); */ + + /* Test 32 bit Write */ + write_uint32(sl->q_buf,0x01234567); + stlink_write_mem32(sl,0x200000a8,4); +#if 0 + write_uint32(sl->q_buf,0x89abcdef); + stlink_write_mem32(sl,0x200000ac, 4); + stlink_read_mem32(sl, 0x200000a8, 4); + stlink_read_mem32(sl, 0x200000ac, 4); + + /* Test 8 bit write */ + write_uint32(sl->q_buf,0x01234567); + stlink_write_mem8(sl,0x200001a8,3); + write_uint32(sl->q_buf,0x89abcdef); + stlink_write_mem8(sl, 0x200001ac, 3); + stlink_read_mem32(sl, 0x200001a8, 4); + stlink_read_mem32(sl, 0x200001ac, 4); + + printf("-- status\n"); + stlink_status(sl); + + printf("-- reset\n"); + stlink_reset(sl); + stlink_force_debug(sl); + /* Test reg write*/ + stlink_write_reg(sl, 0x01234567, 3); + stlink_write_reg(sl, 0x89abcdef, 4); + stlink_write_reg(sl, 0x12345678, 15); + for (off = 0; off < 21; off += 1) + stlink_read_reg(sl, off, ®s); + + + stlink_read_all_regs(sl, ®s); + + printf("-- status\n"); + stlink_status(sl); + + printf("-- step\n"); + stlink_step(sl); + + printf("-- run\n"); + stlink_run(sl); + + printf("-- exit_debug_mode\n"); +#endif + stlink_exit_debug_mode(sl); + + stlink_close(sl); + } + + return 0; +} From d59be1f42793a92430bde44188e8b5e08febd08e Mon Sep 17 00:00:00 2001 From: Andrew 'Necromant' Andrianov Date: Mon, 6 May 2013 08:59:25 +0400 Subject: [PATCH 0213/1435] working st-term proof-of-concept. Period. Signed-off-by: Andrew 'Necromant' Andrianov --- src/st-term.c | 263 ++++++++++++++++++++++++++------------------------ 1 file changed, 138 insertions(+), 125 deletions(-) diff --git a/src/st-term.c b/src/st-term.c index f442d56fd..7f045b6e4 100644 --- a/src/st-term.c +++ b/src/st-term.c @@ -1,4 +1,13 @@ #include +/* According to POSIX.1-2001 */ +#include +#include +#include +#include +#include +#include +#include +#include #include "stlink-common.h" #define STLINKY_MAGIC 0xDEADF00D @@ -9,20 +18,16 @@ struct stlinky { size_t bufsize; }; -void dump_qbuf(stlink_t* s) -{ - printf("== 0x%x\n", *(uint32_t*)s->q_buf); -} -/* Detects stlinky in RAM, returns handler */ -struct stlinky* stlinky_detect(stlink_t* sl) +/* Detects stlinky in RAM, returns handler */ +struct stlinky* stlinky_detect(stlink_t* sl) { - static const uint32_t sram_base = 0x20000000; + static const uint32_t sram_base = 0x20000000; struct stlinky* st = malloc(sizeof(struct stlinky)); st->sl = sl; printf("sram: 0x%x bytes @ 0x%x\n", sl->sram_base, sl->sram_size); - uint32_t off; - for (off = 0; off < sl->sram_size; off += 4) { + uint32_t off; + for (off = 0; off < sl->sram_size; off += 4) { stlink_read_mem32(sl, sram_base + off, 4); if ( STLINKY_MAGIC== *(uint32_t*) sl->q_buf) { @@ -30,13 +35,19 @@ struct stlinky* stlinky_detect(stlink_t* sl) st->off = sram_base + off; stlink_read_mem32(sl, st->off + 4, 4); st->bufsize = (size_t) *(unsigned char*) sl->q_buf; - printf("stlinky buffer size 0x%zu (%hhx)\n", st->bufsize); + printf("stlinky buffer size 0x%zu\n", st->bufsize); return st; } } return NULL; } +int stlinky_canrx(struct stlinky *st) +{ + stlink_read_mem32(st->sl, st->off+4, 4); + unsigned char tx = (unsigned char) st->sl->q_buf[1]; + return (int) tx; +} size_t stlinky_rx(struct stlinky *st, char* buffer) { @@ -47,128 +58,130 @@ size_t stlinky_rx(struct stlinky *st, char* buffer) } size_t rs = tx + (4 - (tx % 4)); /* voodoo */ stlink_read_mem32(st->sl, st->off+8, rs); - printf(st->sl->q_buf); + memcpy(buffer, st->sl->q_buf, (size_t) tx); *st->sl->q_buf=0x0; stlink_write_mem8(st->sl, st->off+5, 1); + return (size_t) tx; +} + +size_t stlinky_tx(struct stlinky *st, char* buffer, size_t sz) +{ + unsigned char rx = 1; + while(rx != 0) { + stlink_read_mem32(st->sl, st->off+4, 4); + rx = (unsigned char) st->sl->q_buf[2]; + } + memcpy(st->sl->q_buf, buffer, sz); + size_t rs = sz + (4 - (sz % 4)); /* voodoo */ + stlink_write_mem32(st->sl, st->off+8+st->bufsize, rs); + *st->sl->q_buf=(unsigned char) sz; + stlink_write_mem8(st->sl, st->off+6, 1); + return (size_t) rx; } +int kbhit() +{ + struct timeval tv; + fd_set fds; + tv.tv_sec = 0; + tv.tv_usec = 0; + FD_ZERO(&fds); + FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0 + select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); + return FD_ISSET(STDIN_FILENO, &fds); +} -int main(int ac, char** av) { - stlink_t* sl; - reg regs; - - /* unused */ - ac = ac; - av = av; - - sl = stlink_open_usb(10); - if (sl != NULL) { - printf("ST Link terminal :: Created by Necromant\n"); - stlink_version(sl); - - printf("mode before doing anything: %d\n", stlink_current_mode(sl)); - - if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { - printf("-- exit_dfu_mode\n"); - stlink_exit_dfu_mode(sl); - } - - printf("-- enter_swd_mode\n"); - stlink_enter_swd_mode(sl); - - printf("-- mode after entering swd mode: %d\n", stlink_current_mode(sl)); - - printf("-- chip id: %#x\n", sl->chip_id); - printf("-- core_id: %#x\n", sl->core_id); - - cortex_m3_cpuid_t cpuid; - stlink_cpu_id(sl, &cpuid); - printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); - printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); - - stlink_reset(sl); - stlink_force_debug(sl); - stlink_run(sl); - stlink_status(sl); - /* wait for device to boot */ - - sleep(1); - - struct stlinky *st = stlinky_detect(sl); - if (st == NULL) +void nonblock(int state) +{ + struct termios ttystate; + + //get the terminal state + tcgetattr(STDIN_FILENO, &ttystate); + + if (state==1) + { + //turn off canonical mode + ttystate.c_lflag &= ~ICANON; + ttystate.c_lflag &= ~ECHO; + //minimum of number input read. + ttystate.c_cc[VMIN] = 1; + } + else if (state==0) { - printf("stlinky magic not found in sram :("); + //turn on canonical mode + ttystate.c_lflag |= ICANON | ECHO; } + //set the terminal attributes. + tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); + +} + +static int keep_running = 1; +void cleanup(int dummy) +{ + keep_running = 0; + printf("\n\nGot a signal - terminating\n"); +} - while(1) { - stlinky_rx(st, NULL); + +int main(int ac, char** av) { + stlink_t* sl; + + /* unused */ + ac = ac; + av = av; + sl = stlink_open_usb(10); + if (sl != NULL) { + printf("ST-Linky proof-of-concept terminal :: Created by Necromant for lulz\n"); + stlink_version(sl); + stlink_enter_swd_mode(sl); + printf("chip id: %#x\n", sl->chip_id); + printf("core_id: %#x\n", sl->core_id); + + cortex_m3_cpuid_t cpuid; + stlink_cpu_id(sl, &cpuid); + printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); + printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); + + stlink_reset(sl); + stlink_force_debug(sl); + stlink_run(sl); + stlink_status(sl); + + /* wait for device to boot */ + /* TODO: Make timeout adjustable via command line */ + sleep(1); + + struct stlinky *st = stlinky_detect(sl); + if (st == NULL) + { + printf("stlinky magic not found in sram :("); + } + char* rxbuf = malloc(st->bufsize); + char* txbuf = malloc(st->bufsize); + size_t tmp; + nonblock(1); + int fd = fileno(stdin); + int saved_flags = fcntl(fd, F_GETFL); + fcntl(fd, F_SETFL, saved_flags & ~O_NONBLOCK); + signal(SIGINT, cleanup); + printf("Entering interactive terminal. CTRL+C to exit\n"); + while(1) { + if (stlinky_canrx(st)) { + tmp = stlinky_rx(st, rxbuf); + fwrite(rxbuf,tmp,1,stdout); + fflush(stdout); + } + if (kbhit()) { + tmp = read(fd, txbuf, st->bufsize); + stlinky_tx(st,txbuf,tmp); + } + if (!keep_running) + break; + } + nonblock(0); + stlink_exit_debug_mode(sl); + stlink_close(sl); } - //sleep(90); - - printf("-- read_sram\n"); - // static const uint32_t sram_base = 0x8000000; - // uint32_t off; - //for (off = 0; off < 16; off += 4) - // stlink_read_mem32(sl, sram_base + off, 4); - - //printf("FP_CTRL\n"); - //stlink_read_mem32(sl, CM3_REG_FP_CTRL, 4); - - // no idea what reg this is.. */ - // stlink_read_mem32(sl, 0xe000ed90, 4); - // no idea what register this is... - // stlink_read_mem32(sl, 0xe000edf0, 4); - // offset 0xC into TIM11 register? TIMx_DIER? - // stlink_read_mem32(sl, 0x4001100c, 4); */ - - /* Test 32 bit Write */ - write_uint32(sl->q_buf,0x01234567); - stlink_write_mem32(sl,0x200000a8,4); -#if 0 - write_uint32(sl->q_buf,0x89abcdef); - stlink_write_mem32(sl,0x200000ac, 4); - stlink_read_mem32(sl, 0x200000a8, 4); - stlink_read_mem32(sl, 0x200000ac, 4); - - /* Test 8 bit write */ - write_uint32(sl->q_buf,0x01234567); - stlink_write_mem8(sl,0x200001a8,3); - write_uint32(sl->q_buf,0x89abcdef); - stlink_write_mem8(sl, 0x200001ac, 3); - stlink_read_mem32(sl, 0x200001a8, 4); - stlink_read_mem32(sl, 0x200001ac, 4); - - printf("-- status\n"); - stlink_status(sl); - - printf("-- reset\n"); - stlink_reset(sl); - stlink_force_debug(sl); - /* Test reg write*/ - stlink_write_reg(sl, 0x01234567, 3); - stlink_write_reg(sl, 0x89abcdef, 4); - stlink_write_reg(sl, 0x12345678, 15); - for (off = 0; off < 21; off += 1) - stlink_read_reg(sl, off, ®s); - - - stlink_read_all_regs(sl, ®s); - - printf("-- status\n"); - stlink_status(sl); - - printf("-- step\n"); - stlink_step(sl); - - printf("-- run\n"); - stlink_run(sl); - - printf("-- exit_debug_mode\n"); -#endif - stlink_exit_debug_mode(sl); - - stlink_close(sl); - } - - return 0; + return 0; } From 32e2fceec615c973754e7f86c14f8f5b7b046323 Mon Sep 17 00:00:00 2001 From: Andrew 'Necromant' Andrianov Date: Mon, 6 May 2013 09:54:10 +0400 Subject: [PATCH 0214/1435] st-term: handle two signals and fixups Signed-off-by: Andrew 'Necromant' Andrianov --- src/st-term.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/st-term.c b/src/st-term.c index 7f045b6e4..f4643933c 100644 --- a/src/st-term.c +++ b/src/st-term.c @@ -35,7 +35,7 @@ struct stlinky* stlinky_detect(stlink_t* sl) st->off = sram_base + off; stlink_read_mem32(sl, st->off + 4, 4); st->bufsize = (size_t) *(unsigned char*) sl->q_buf; - printf("stlinky buffer size 0x%zu\n", st->bufsize); + printf("stlinky buffer size 0x%zu \n", st->bufsize); return st; } } @@ -117,10 +117,16 @@ void nonblock(int state) } static int keep_running = 1; +static int sigcount=0; void cleanup(int dummy) { + sigcount++; keep_running = 0; - printf("\n\nGot a signal - terminating\n"); + printf("\n\nGot a signal\n"); + if (sigcount==2) { + printf("\n\nGot a second signal - bailing out\n"); + exit(1); + } } @@ -155,7 +161,8 @@ int main(int ac, char** av) { struct stlinky *st = stlinky_detect(sl); if (st == NULL) { - printf("stlinky magic not found in sram :("); + printf("stlinky magic not found in sram :(\n"); + goto bailout; } char* rxbuf = malloc(st->bufsize); char* txbuf = malloc(st->bufsize); @@ -165,7 +172,7 @@ int main(int ac, char** av) { int saved_flags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, saved_flags & ~O_NONBLOCK); signal(SIGINT, cleanup); - printf("Entering interactive terminal. CTRL+C to exit\n"); + printf("Entering interactive terminal. CTRL+C to exit\n\n\n"); while(1) { if (stlinky_canrx(st)) { tmp = stlinky_rx(st, rxbuf); @@ -179,6 +186,7 @@ int main(int ac, char** av) { if (!keep_running) break; } + bailout: nonblock(0); stlink_exit_debug_mode(sl); stlink_close(sl); From 4e09a06bfc9a95b3d4bd2f71ce7ebdf4bacf672a Mon Sep 17 00:00:00 2001 From: kevin Date: Tue, 7 May 2013 13:33:58 +0100 Subject: [PATCH 0215/1435] Ensure that the USB device search succeeds if the matched device is at index 0. --- src/stlink-usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 825ee0aea..d57458428 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -757,9 +757,9 @@ stlink_t* stlink_open_usb(const int verbose) { if (desc.idProduct == USB_STLINK_PID) slu->protocoll = 1; break; } - if (cnt==0){ - WLOG("Couldn't find %s ST-Link/V2 devices\n",(devBus && devAddr)?"matched":"any"); - goto on_error; + if (cnt < 0) { + WLOG ("Couldn't find %s ST-Link/V2 devices\n",(devBus && devAddr)?"matched":"any"); + goto on_error; } else { if( libusb_open(list[cnt], &slu->usb_handle) !=0){ WLOG("Couldn't open ST-Link/V2 device %03d:%03d\n",libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); From bffa1b5259002229fe60ad8f392b5d9e902112a3 Mon Sep 17 00:00:00 2001 From: Jonas Danielsson Date: Mon, 10 Jun 2013 11:32:01 +0200 Subject: [PATCH 0216/1435] gui: add initial gtk implementation --- gui/Makefile.am | 30 ++ gui/stlink-gui.c | 950 ++++++++++++++++++++++++++++++++++++++++++++++ gui/stlink-gui.h | 93 +++++ gui/stlink-gui.ui | 666 ++++++++++++++++++++++++++++++++ 4 files changed, 1739 insertions(+) create mode 100644 gui/Makefile.am create mode 100644 gui/stlink-gui.c create mode 100644 gui/stlink-gui.h create mode 100644 gui/stlink-gui.ui diff --git a/gui/Makefile.am b/gui/Makefile.am new file mode 100644 index 000000000..19c067278 --- /dev/null +++ b/gui/Makefile.am @@ -0,0 +1,30 @@ +bin_PROGRAMS = stlink-gui + +stlink_gui_SOURCES = \ + stlink-gui.c \ + stlink-gui.h + +stlink_gui_CPPFLAGS = \ + -I$(top_srcdir) \ + $(AM_CPPFLAGS) \ + -I$(top_builddir)/src \ + @GTK_CFLAGS@ + +stlink_gui_CFLAGS = \ + $(WARN_CFLAGS) \ + $(AM_CFLAGS) \ + -DSTLINK_UI_DIR="\"$(uidir)\"" + +stlink_gui_LDFLAGS = \ + $(AM_LDFLAGS) + +stlink_gui_LDADD = \ + $(INTLLIBS) \ + $(top_builddir)/libstlink.a \ + @GTK_LIBS@ + +uidir = $(pkgdatadir)/ui +ui_DATA = stlink-gui.ui +EXTRA_DIST = $(ui_DATA) + +-include $(top_srcdir)/git.mk diff --git a/gui/stlink-gui.c b/gui/stlink-gui.c new file mode 100644 index 000000000..756d7666c --- /dev/null +++ b/gui/stlink-gui.c @@ -0,0 +1,950 @@ +#include +#include +#include +#include + +#include "stlink-common.h" +#include "stlink-gui.h" + +#define MEM_READ_SIZE 1024 + +#ifndef G_VALUE_INIT +#define G_VALUE_INIT {0, {{0}}} +#endif + +G_DEFINE_TYPE (STlinkGUI, stlink_gui, G_TYPE_OBJECT); + +static void +stlink_gui_dispose (GObject *gobject) +{ + G_OBJECT_CLASS (stlink_gui_parent_class)->dispose (gobject); +} + +static void +stlink_gui_finalize (GObject *gobject) +{ + G_OBJECT_CLASS (stlink_gui_parent_class)->finalize (gobject); +} + +static void +stlink_gui_class_init (STlinkGUIClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = stlink_gui_dispose; + gobject_class->finalize = stlink_gui_finalize; +} + +static void +stlink_gui_init (STlinkGUI *self) +{ + self->sl = NULL; + self->filename = NULL; + + self->progress.activity_mode = FALSE; + self->progress.fraction = 0; + + self->flash_mem.memory = NULL; + self->flash_mem.size = 0; + self->flash_mem.base = 0; + + self->file_mem.memory = NULL; + self->file_mem.size = 0; + self->file_mem.base = 0; +} + +static gboolean +set_info_error_message_idle (STlinkGUI *gui) +{ + if (gui->error_message != NULL) { + gchar *markup; + + markup = g_markup_printf_escaped ("%s", gui->error_message); + gtk_label_set_markup (gui->infolabel, markup); + gtk_info_bar_set_message_type (gui->infobar, GTK_MESSAGE_ERROR); + gtk_widget_show (GTK_WIDGET (gui->infobar)); + + g_free (markup); + g_free (gui->error_message); + gui->error_message = NULL; + } + return FALSE; +} + +static void +stlink_gui_set_info_error_message (STlinkGUI *gui, const gchar *message) +{ + gui->error_message = g_strdup (message); + g_idle_add ((GSourceFunc) set_info_error_message_idle, gui); +} + +static void +stlink_gui_set_sensitivity (STlinkGUI *gui, gboolean sensitivity) +{ + gtk_widget_set_sensitive (GTK_WIDGET (gui->open_button), sensitivity); + + if (sensitivity && gui->sl) + gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), sensitivity); + + if (sensitivity && !gui->sl) + gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), sensitivity); + + if (sensitivity && gui->sl && gui->filename) + gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), sensitivity); +} + +static void +mem_view_init_headers (GtkTreeView *view) +{ + GtkCellRenderer *renderer; + gint i; + + g_return_if_fail (view != NULL); + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (view, + -1, + "Address", + renderer, + "text", + 0, /* column */ + NULL); + for (i = 0; i < 4; i++) { + gchar *label; + + label = g_strdup_printf ("%X", i * 4); + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (view, + -1, + label, + renderer, + "text", + (i + 1), /* column */ + NULL); + g_free (label); + } + + for (i = 0; i < 5; i++) { + GtkTreeViewColumn *column = gtk_tree_view_get_column (view, i); + gtk_tree_view_column_set_expand (column, TRUE); + } +} + +static void +mem_view_add_as_hex (GtkListStore *store, + GtkTreeIter *iter, + gint column, + guint32 value) +{ + gchar *hex_str; + + hex_str = g_strdup_printf ("0x%08X", value); + gtk_list_store_set (store, iter, column, hex_str, -1); + g_free (hex_str); +} + +static void +mem_view_add_buffer (GtkListStore *store, + GtkTreeIter *iter, + guint32 address, + guchar *buffer, + gint len) +{ + guint32 *word; + gint i, step; + gint column = 0; + + step = sizeof (*word); + + for (i = 0; i < len; i += step) { + word = (guint *) &buffer[i]; + + if (column == 0) { + /* new row */ + gtk_list_store_append (store, iter); + + /* add address */ + mem_view_add_as_hex (store, iter, column, (address + i)); + } + mem_view_add_as_hex (store, iter, (column + 1), *word); + column = (column + 1) % step; + } +} + +static guint32 +hexstr_to_guint32 (const gchar *str, GError **err) +{ + guint32 val; + gchar *end_ptr; + + val = strtoul (str, &end_ptr, 16); + if ((errno == ERANGE && val == LONG_MAX) || (errno != 0 && val == 0)) { + g_set_error (err, + g_quark_from_string ("hextou32"), + 1, + "Invalid hexstring"); + return LONG_MAX; + } + if (end_ptr == str) { + g_set_error (err, + g_quark_from_string ("hextou32"), + 2, + "Invalid hexstring"); + return LONG_MAX; + } + return val; +} + + +static void +stlink_gui_update_mem_view (STlinkGUI *gui, struct mem_t *mem, GtkTreeView *view) { + GtkListStore *store; + GtkTreeIter iter; + + store = GTK_LIST_STORE (gtk_tree_view_get_model (view)); + + mem_view_add_buffer (store, + &iter, + mem->base, + mem->memory, + mem->size); + + gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); + gtk_progress_bar_set_fraction (gui->progress.bar, 0); + stlink_gui_set_sensitivity (gui, TRUE); +} + +static gboolean +stlink_gui_update_devmem_view (STlinkGUI *gui) +{ + stlink_gui_update_mem_view (gui, &gui->flash_mem, gui->devmem_treeview); + return FALSE; +} + + +static void +stlink_gui_populate_devmem_view (STlinkGUI *gui) +{ + guint off; + stm32_addr_t addr; + + g_return_if_fail (gui != NULL); + g_return_if_fail (gui->sl != NULL); + + addr = gui->sl->flash_base; + + if (gui->flash_mem.memory) { + g_free (gui->flash_mem.memory); + } + gui->flash_mem.memory = g_malloc (gui->sl->flash_size); + gui->flash_mem.size = gui->sl->flash_size; + gui->flash_mem.base = gui->sl->flash_base; + + for (off = 0; off < gui->sl->flash_size; off += MEM_READ_SIZE) { + guint n_read = MEM_READ_SIZE; + + if (off + MEM_READ_SIZE > gui->sl->flash_size) { + n_read = gui->sl->flash_size - off; + + /* align if needed */ + if (n_read & 3) { + n_read = (n_read + 4) & ~(3); + } + } + /* reads to sl->q_buf */ + stlink_read_mem32(gui->sl, addr + off, n_read); + if (gui->sl->q_len < 0) { + stlink_gui_set_info_error_message (gui, "Failed to read memory"); + g_free (gui->flash_mem.memory); + gui->flash_mem.memory = NULL; + return; + } + memcpy (gui->flash_mem.memory + off, gui->sl->q_buf, n_read); + gui->progress.fraction = (gdouble) (off + n_read) / gui->sl->flash_size; + } + g_idle_add ((GSourceFunc) stlink_gui_update_devmem_view, gui); +} + +static gboolean +stlink_gui_update_filemem_view (STlinkGUI *gui) +{ + gchar *basename; + + basename = g_path_get_basename (gui->filename); + gtk_notebook_set_tab_label_text (gui->notebook, + GTK_WIDGET (gtk_notebook_get_nth_page (gui->notebook, 1)), + basename); + g_free (basename); + + stlink_gui_update_mem_view (gui, &gui->file_mem, gui->filemem_treeview); + + return FALSE; +} + +static gpointer +stlink_gui_populate_filemem_view (STlinkGUI *gui) +{ + guchar buffer[MEM_READ_SIZE]; + GFile *file; + GFileInfo *file_info; + GInputStream *input_stream; + gint off; + GError *err = NULL; + + g_return_val_if_fail (gui != NULL, NULL); + g_return_val_if_fail (gui->filename != NULL, NULL); + + file = g_file_new_for_path (gui->filename); + input_stream = G_INPUT_STREAM (g_file_read (file, NULL, &err)); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out; + } + + file_info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (input_stream), + G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, &err); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out_input; + } + if (gui->file_mem.memory) { + g_free (gui->file_mem.memory); + } + gui->file_mem.size = g_file_info_get_size (file_info); + gui->file_mem.memory = g_malloc (gui->file_mem.size); + + for (off = 0; off < gui->file_mem.size; off += MEM_READ_SIZE) { + guint n_read = MEM_READ_SIZE; + + if (off + MEM_READ_SIZE > gui->file_mem.size) { + n_read = gui->file_mem.size - off; + } + + if (g_input_stream_read (G_INPUT_STREAM (input_stream), + &buffer, n_read, NULL, &err) == -1) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out_input; + } + memcpy (gui->file_mem.memory + off, buffer, n_read); + gui->progress.fraction = (gdouble) (off + n_read) / gui->file_mem.size; + } + g_idle_add ((GSourceFunc) stlink_gui_update_filemem_view, gui); + + out_input: + g_object_unref (input_stream); + out: + g_object_unref (file); + return NULL; +} + +static void mem_jmp (GtkTreeView *view, + GtkEntry *entry, + guint32 base_addr, + gsize size, + GError **err) +{ + GtkTreeModel *model; + guint32 jmp_addr; + GtkTreeIter iter; + + jmp_addr = hexstr_to_guint32 (gtk_entry_get_text (entry), err); + if (err && *err) { + return; + } + + if (jmp_addr < base_addr || jmp_addr > base_addr + size) { + g_set_error (err, + g_quark_from_string ("mem_jmp"), + 1, + "Invalid address"); + return; + } + + model = gtk_tree_view_get_model (view); + if (!model) { + return; + } + + if (gtk_tree_model_get_iter_first (model, &iter)) { + do { + guint32 addr; + GValue value = G_VALUE_INIT; + GError *err = NULL; + + gtk_tree_model_get_value (model, &iter, 0, &value); + if (G_VALUE_HOLDS_STRING (&value)) { + addr = hexstr_to_guint32 (g_value_get_string (&value), &err); + if (!err) { + if (addr == (jmp_addr & 0xFFFFFFF0)) { + GtkTreeSelection *selection; + GtkTreePath *path; + + selection = gtk_tree_view_get_selection (view); + path = gtk_tree_model_get_path (model, &iter); + + gtk_tree_selection_select_iter (selection, &iter); + gtk_tree_view_scroll_to_cell (view, + path, + NULL, + TRUE, + 0.0, + 0.0); + gtk_tree_path_free (path); + } + } + } + g_value_unset (&value); + } while (gtk_tree_model_iter_next (model, &iter)); + } +} + +static void +devmem_jmp_cb (GtkWidget *widget, gpointer data) +{ + STlinkGUI *gui; + GError *err = NULL; + + gui = STLINK_GUI (data); + + mem_jmp (gui->devmem_treeview, + gui->devmem_jmp_entry, + gui->sl->flash_base, + gui->sl->flash_size, + &err); + + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + } +} + +static void +filemem_jmp_cb (GtkWidget *widget, gpointer data) +{ + STlinkGUI *gui; + GError *err = NULL; + + gui = STLINK_GUI (data); + + g_return_if_fail (gui->filename != NULL); + + mem_jmp (gui->filemem_treeview, + gui->filemem_jmp_entry, + 0, + gui->file_mem.size, + &err); + + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + } +} + +static gchar * +dev_format_chip_id (guint32 chip_id) +{ + gint i; + + for (i = 0; i < sizeof (devices) / sizeof (devices[0]); i++) { + if (chip_id == devices[i].chip_id) { + return g_strdup (devices[i].description); + } + } + return g_strdup_printf ("0x%x", chip_id); +} + +static gchar * +dev_format_mem_size (gsize flash_size) +{ + return g_strdup_printf ("%u kB", flash_size / 1024); +} + + +static void +stlink_gui_set_connected (STlinkGUI *gui) +{ + gchar *tmp_str; + GtkListStore *store; + GtkTreeIter iter; + + gtk_statusbar_push (gui->statusbar, + gtk_statusbar_get_context_id (gui->statusbar, "conn"), + "Connected"); + + gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->devmem_box), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), FALSE); + + if (gui->filename) { + gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), TRUE); + } + + tmp_str = dev_format_chip_id (gui->sl->chip_id); + gtk_label_set_text (gui->chip_id_label, tmp_str); + g_free (tmp_str); + + tmp_str = g_strdup_printf ("0x%x", gui->sl->core_id); + gtk_label_set_text (gui->core_id_label, tmp_str); + g_free (tmp_str); + + tmp_str = dev_format_mem_size (gui->sl->flash_size); + gtk_label_set_text (gui->flash_size_label, tmp_str); + g_free (tmp_str); + + tmp_str = dev_format_mem_size (gui->sl->sram_size); + gtk_label_set_text (gui->ram_size_label, tmp_str); + g_free (tmp_str); + + tmp_str = g_strdup_printf ("0x%08X", gui->sl->flash_base); + gtk_entry_set_text (gui->devmem_jmp_entry, tmp_str); + gtk_editable_set_editable (GTK_EDITABLE (gui->devmem_jmp_entry), TRUE); + g_free (tmp_str); + + store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + gtk_list_store_clear (store); + } + + stlink_gui_set_sensitivity (gui, FALSE); + gtk_notebook_set_current_page (gui->notebook, PAGE_DEVMEM); + gtk_widget_show (GTK_WIDGET (gui->progress.bar)); + gtk_progress_bar_set_text (gui->progress.bar, "Reading memory"); + + g_thread_new ("devmem", (GThreadFunc) stlink_gui_populate_devmem_view, gui); +} + +static void +connect_button_cb (GtkWidget *widget, gpointer data) +{ + STlinkGUI *gui; + gint i; + + gui = STLINK_GUI (data); + + if (gui->sl != NULL) + return; + + /* try version 1 then version 2 */ + gui->sl = stlink_v1_open(0); + if (gui->sl == NULL) { + gui->sl = stlink_open_usb(0); + } + if (gui->sl == NULL) { + stlink_gui_set_info_error_message (gui, "Failed to connect to STLink."); return; + } + + /* code below taken from flash/main.c, refactoring might be in order */ + if (stlink_current_mode(gui->sl) == STLINK_DEV_DFU_MODE) + stlink_exit_dfu_mode(gui->sl); + + if (stlink_current_mode(gui->sl) != STLINK_DEV_DEBUG_MODE) + stlink_enter_swd_mode(gui->sl); + + /* Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 */ + if (gui->sl->chip_id == STM32_CHIPID_F4) { + memset(gui->sl->q_buf, 0, 4); + for (i = 0; i < 8; i++) { + stlink_write_mem32(gui->sl, 0x40026000 + 0x10 + 0x18 * i, 4); + stlink_write_mem32(gui->sl, 0x40026400 + 0x10 + 0x18 * i, 4); + stlink_write_mem32(gui->sl, 0x40026000 + 0x24 + 0x18 * i, 4); + stlink_write_mem32(gui->sl, 0x40026400 + 0x24 + 0x18 * i, 4); + } + } + stlink_gui_set_connected (gui); +} + +static void stlink_gui_set_disconnected (STlinkGUI *gui) +{ + gtk_statusbar_push (gui->statusbar, + gtk_statusbar_get_context_id (gui->statusbar, "conn"), + "Disconnected"); + + gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), TRUE); +} + +static void +disconnect_button_cb (GtkWidget *widget, gpointer data) +{ + STlinkGUI *gui; + + gui = STLINK_GUI (data); + + if (gui->sl != NULL) { + stlink_exit_debug_mode(gui->sl); + stlink_close(gui->sl); + gui->sl = NULL; + } + stlink_gui_set_disconnected (gui); +} + + +static void +stlink_gui_open_file (STlinkGUI *gui) +{ + GtkWidget *dialog; + GtkListStore *store; + GtkTreeIter iter; + + dialog = gtk_file_chooser_dialog_new ("Open file", + gui->window, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); + + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + gui->filename = + gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + + store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->filemem_treeview)); + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + gtk_list_store_clear (store); + } + + stlink_gui_set_sensitivity (gui, FALSE); + gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); + gtk_widget_show (GTK_WIDGET (gui->progress.bar)); + gtk_progress_bar_set_text (gui->progress.bar, "Reading file"); + g_thread_new ("file", (GThreadFunc) stlink_gui_populate_filemem_view, gui); + } + gtk_widget_destroy (dialog); +} + +static void +open_button_cb (GtkWidget *widget, gpointer data) +{ + STlinkGUI *gui; + + gui = STLINK_GUI (data); + + stlink_gui_open_file (gui); +} + +static gboolean +stlink_gui_write_flash_update (STlinkGUI *gui) +{ + stlink_gui_set_sensitivity (gui, TRUE); + gui->progress.activity_mode = FALSE; + gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); + + return FALSE; +} + +static void +stlink_gui_write_flash (STlinkGUI *gui) +{ + g_return_if_fail (gui->sl != NULL); + g_return_if_fail (gui->filename != NULL); + + if (stlink_fwrite_flash(gui->sl, gui->filename, gui->sl->flash_base) < 0) { + stlink_gui_set_info_error_message (gui, "Failed to write to flash"); + } + + g_idle_add ((GSourceFunc) stlink_gui_write_flash_update, gui); +} + +static void +flash_button_cb (GtkWidget *widget, gpointer data) +{ + STlinkGUI *gui; + gchar *tmp_str; + guint32 address; + gint result; + GError *err = NULL; + + gui = STLINK_GUI (data); + g_return_if_fail (gui->sl != NULL); + + if (!g_strcmp0 (gtk_entry_get_text (gui->flash_dialog_entry), "")) { + tmp_str = g_strdup_printf ("0x%08X", gui->sl->flash_base); + gtk_entry_set_text (gui->flash_dialog_entry, tmp_str); + g_free (tmp_str); + } + + result = gtk_dialog_run (gui->flash_dialog); + if (result == GTK_RESPONSE_OK) { + address = hexstr_to_guint32 (gtk_entry_get_text (gui->flash_dialog_entry), + &err); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + } else { + if (address > gui->sl->flash_base + gui->sl->flash_size || + address < gui->sl->flash_base) { + stlink_gui_set_info_error_message (gui, "Invalid address"); + } + else if (address + gui->file_mem.size > + gui->sl->flash_base + gui->sl->flash_size) { + stlink_gui_set_info_error_message (gui, "Binary overwrites flash"); + } else { + stlink_gui_set_sensitivity (gui, FALSE); + gtk_progress_bar_set_text (gui->progress.bar, + "Writing to flash"); + gui->progress.activity_mode = TRUE; + gtk_widget_show (GTK_WIDGET (gui->progress.bar)); + g_thread_new ("flash", + (GThreadFunc) stlink_gui_write_flash, gui); + } + } + } +} + +static gboolean +progress_pulse_timeout (STlinkGUI *gui) { + if (gui->progress.activity_mode) { + gtk_progress_bar_pulse (gui->progress.bar); + } else { + gtk_progress_bar_set_fraction (gui->progress.bar, gui->progress.fraction); + } + return TRUE; +} + +static void +notebook_switch_page_cb (GtkNotebook *notebook, + GtkWidget *widget, + guint page_num, + gpointer data) +{ + STlinkGUI *gui; + + gui = STLINK_GUI (data); + + if (page_num == 1) { + if (gui->filename == NULL) { + stlink_gui_open_file (gui); + } + } +} + +static void +dnd_received_cb (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint target_type, + guint time, + gpointer data) +{ + GFile *file_uri; + gchar **file_list; + const guchar *file_data; + STlinkGUI *gui = STLINK_GUI (data); + GtkListStore *store; + GtkTreeIter iter; + + if (selection_data != NULL && + gtk_selection_data_get_length (selection_data) > 0) { + switch (target_type) { + case TARGET_FILENAME: + + if (gui->filename) { + g_free (gui->filename); + } + + file_data = gtk_selection_data_get_data (selection_data); + file_list = g_strsplit ((gchar *)file_data, "\r\n", 0); + + file_uri = g_file_new_for_uri (file_list[0]); + gui->filename = g_file_get_path (file_uri); + + g_strfreev (file_list); + g_object_unref (file_uri); + + + store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + gtk_list_store_clear (store); + } + + stlink_gui_set_sensitivity (gui, FALSE); + gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); + gtk_widget_show (GTK_WIDGET (gui->progress.bar)); + gtk_progress_bar_set_text (gui->progress.bar, "Reading file"); + g_thread_new ("file", (GThreadFunc) stlink_gui_populate_filemem_view, gui); + break; + } + } + gtk_drag_finish (context, + TRUE, + gdk_drag_context_get_suggested_action (context) == GDK_ACTION_MOVE, + time); +} + +void +stlink_gui_init_dnd (STlinkGUI *gui) +{ + GtkTargetEntry target_list[] = { + { "text/uri-list", 0, TARGET_FILENAME }, + }; + + gtk_drag_dest_set (GTK_WIDGET (gui->window), + GTK_DEST_DEFAULT_ALL, + target_list, + G_N_ELEMENTS (target_list), + GDK_ACTION_COPY); + + g_signal_connect (gui->window, "drag-data-received", + G_CALLBACK (dnd_received_cb), gui); +} + +static void +stlink_gui_build_ui (STlinkGUI *gui) { + GtkBuilder *builder; + GtkListStore *devmem_store; + GtkListStore *filemem_store; + + builder = gtk_builder_new (); + if (!gtk_builder_add_from_file (builder, STLINK_UI_DIR "/stlink-gui.ui", NULL)) { + /* woot */ + } + + gui->window = GTK_WINDOW (gtk_builder_get_object (builder, "window")); + g_signal_connect (G_OBJECT (gui->window), "destroy", + G_CALLBACK (gtk_main_quit), NULL); + + /* set up toolutton clicked callbacks */ + gui->open_button = + GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "open_button")); + g_signal_connect (G_OBJECT (gui->open_button), "clicked", + G_CALLBACK (open_button_cb), gui); + + gui->connect_button = + GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "connect_button")); + g_signal_connect (G_OBJECT (gui->connect_button), "clicked", + G_CALLBACK (connect_button_cb), gui); + + gui->disconnect_button = + GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "disconnect_button")); + g_signal_connect (G_OBJECT (gui->disconnect_button), "clicked", + G_CALLBACK (disconnect_button_cb), gui); + + gui->flash_button = + GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "flash_button")); + g_signal_connect (G_OBJECT (gui->flash_button), "clicked", + G_CALLBACK (flash_button_cb), gui); + + gui->devmem_treeview = + GTK_TREE_VIEW (gtk_builder_get_object (builder, "devmem_treeview")); + gtk_tree_view_set_rules_hint (gui->devmem_treeview, TRUE); + mem_view_init_headers (gui->devmem_treeview); + devmem_store = gtk_list_store_new (5, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); + gtk_tree_view_set_model (gui->devmem_treeview, GTK_TREE_MODEL (devmem_store)); + g_object_unref (devmem_store); + + gui->filemem_treeview = + GTK_TREE_VIEW (gtk_builder_get_object (builder, "filemem_treeview")); + gtk_tree_view_set_rules_hint (gui->filemem_treeview, TRUE); + mem_view_init_headers (gui->filemem_treeview); + filemem_store = gtk_list_store_new (5, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); + gtk_tree_view_set_model (gui->filemem_treeview, GTK_TREE_MODEL (filemem_store)); + g_object_unref (filemem_store); + + gui->core_id_label = + GTK_LABEL (gtk_builder_get_object (builder, "core_id_value")); + + gui->chip_id_label = + GTK_LABEL (gtk_builder_get_object (builder, "chip_id_value")); + + gui->flash_size_label = + GTK_LABEL (gtk_builder_get_object (builder, "flash_size_value")); + + gui->ram_size_label = + GTK_LABEL (gtk_builder_get_object (builder, "ram_size_value")); + + gui->device_frame = + GTK_FRAME (gtk_builder_get_object (builder, "device_frame")); + + gui->notebook = + GTK_NOTEBOOK (gtk_builder_get_object (builder, "mem_notebook")); + g_signal_connect (gui->notebook, "switch-page", + G_CALLBACK (notebook_switch_page_cb), gui); + + gui->devmem_box = + GTK_BOX (gtk_builder_get_object (builder, "devmem_box")); + + gui->filemem_box = + GTK_BOX (gtk_builder_get_object (builder, "filemem_box")); + + gui->devmem_jmp_entry = + GTK_ENTRY (gtk_builder_get_object (builder, "devmem_jmp_entry")); + g_signal_connect (gui->devmem_jmp_entry, "activate", + G_CALLBACK (devmem_jmp_cb), gui); + + gui->filemem_jmp_entry = + GTK_ENTRY (gtk_builder_get_object (builder, "filemem_jmp_entry")); + g_signal_connect (gui->filemem_jmp_entry, "activate", + G_CALLBACK (filemem_jmp_cb), gui); + gtk_editable_set_editable (GTK_EDITABLE (gui->filemem_jmp_entry), TRUE); + + gui->progress.bar = + GTK_PROGRESS_BAR (gtk_builder_get_object (builder, "progressbar")); + gtk_progress_bar_set_show_text (gui->progress.bar, TRUE); + gui->progress.timer = g_timeout_add (100, + (GSourceFunc) progress_pulse_timeout, + gui); + + gui->statusbar = + GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")); + + gui->infobar = + GTK_INFO_BAR (gtk_builder_get_object (builder, "infobar")); + gtk_info_bar_add_button (gui->infobar, GTK_STOCK_OK, GTK_RESPONSE_OK); + gui->infolabel = GTK_LABEL (gtk_label_new ("")); + gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (gui->infobar)), + GTK_WIDGET (gui->infolabel)); + g_signal_connect (gui->infobar, "response", G_CALLBACK (gtk_widget_hide), NULL); + + /* flash dialog */ + gui->flash_dialog = + GTK_DIALOG (gtk_builder_get_object (builder, "flash_dialog")); + g_signal_connect_swapped (gui->flash_dialog, "response", + G_CALLBACK (gtk_widget_hide), gui->flash_dialog); + + gui->flash_dialog_ok = + GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_ok_button")); + + gui->flash_dialog_cancel = + GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_cancel_button")); + + gui->flash_dialog_entry = + GTK_ENTRY (gtk_builder_get_object (builder, "flash_dialog_entry")); + + /* make it so */ + gtk_widget_show_all (GTK_WIDGET (gui->window)); + gtk_widget_hide (GTK_WIDGET (gui->infobar)); + gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); + + stlink_gui_set_disconnected (gui); +} + +int +main (int argc, char **argv) +{ + STlinkGUI *gui; + + gtk_init (&argc, &argv); + + gui = g_object_new (STLINK_TYPE_GUI, NULL); + stlink_gui_build_ui (gui); + stlink_gui_init_dnd (gui); + + gtk_main (); + + return 0; +} diff --git a/gui/stlink-gui.h b/gui/stlink-gui.h new file mode 100644 index 000000000..a91c869ac --- /dev/null +++ b/gui/stlink-gui.h @@ -0,0 +1,93 @@ + +#ifndef __STLINK_GUI_H__ +#define __STLINK_GUI_H__ + +#include + +#define STLINK_TYPE_GUI (stlink_gui_get_type ()) +#define STLINK_GUI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STLINK_TYPE_GUI, STlinkGUI)) +#define STLINK_IS_GUI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STLINK_TYPE_GUI)) +#define STLINK_GUI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STLINK_TYPE_GUI, STlinkGUIClass)) +#define STLINK_IS_GUI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STLINK_TYPE_GUI)) +#define STLINK_GUI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STLINK_TYPE_GUI, STlinkGUIlass)) +#define STLINK_GUI_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), STLINK_TYPE_GUI, STlinkGUIPrivate)) + +typedef struct _STlinkGUI STlinkGUI; +typedef struct _STlinkGUIClass STlinkGUIClass; +typedef struct _STlinkGUIPrivate STlinkGUIPrivate; + +enum stlink_gui_pages_t { + PAGE_DEVMEM, + PAGE_FILEMEM +}; + +enum stlink_gui_dnd_targets_t { + TARGET_FILENAME, + TARGET_ROOTWIN +}; + +struct progress_t { + GtkProgressBar *bar; + guint timer; + gboolean activity_mode; + gdouble fraction; +}; + +struct mem_t { + guchar *memory; + gsize size; + guint32 base; +}; + +struct _STlinkGUI +{ + GObject parent_instance; + + /*< private >*/ + GtkWindow *window; + GtkTreeView *devmem_treeview; + GtkTreeView *filemem_treeview; + GtkSpinner *spinner; + GtkStatusbar *statusbar; + GtkInfoBar *infobar; + GtkLabel *infolabel; + GtkNotebook *notebook; + GtkFrame *device_frame; + GtkLabel *chip_id_label; + GtkLabel *core_id_label; + GtkLabel *flash_size_label; + GtkLabel *ram_size_label; + GtkBox *devmem_box; + GtkEntry *devmem_jmp_entry; + GtkBox *filemem_box; + GtkEntry *filemem_jmp_entry; + GtkToolButton *connect_button; + GtkToolButton *disconnect_button; + GtkToolButton *flash_button; + GtkToolButton *open_button; + + /* flash dialog */ + GtkDialog *flash_dialog; + GtkButton *flash_dialog_ok; + GtkButton *flash_dialog_cancel; + GtkEntry *flash_dialog_entry; + + struct progress_t progress; + struct mem_t flash_mem; + struct mem_t file_mem; + + gchar *error_message; + gchar *filename; + stlink_t *sl; +}; + +struct _STlinkGUIClass +{ + GObjectClass parent_class; + + /* class members */ +}; + +GType stlink_gui_get_type (void); + +#endif diff --git a/gui/stlink-gui.ui b/gui/stlink-gui.ui new file mode 100644 index 000000000..193925ce1 --- /dev/null +++ b/gui/stlink-gui.ui @@ -0,0 +1,666 @@ + + + + + False + 5 + Flash device + dialog + + + False + vertical + 2 + + + False + end + + + gtk-cancel + True + False + True + True + + + False + True + 0 + + + + + gtk-ok + True + False + True + True + + + False + True + 1 + + + + + False + True + end + 0 + + + + + True + False + 5 + 5 + 5 + 5 + 5 + True + + + True + False + Address to write at: + + + 0 + 0 + 1 + 1 + + + + + True + True + + 12 + + + 1 + 0 + 1 + 1 + + + + + False + True + 2 + + + + + + flash_dialog_cancel_button + flash_dialog_ok_button + + + + False + STlink GUI + 550 + 480 + + + True + False + vertical + + + True + False + True + + + True + False + Open + Open + True + gtk-open + + + False + True + + + + + True + False + Connect + Connect + True + gtk-connect + + + False + True + + + + + True + False + Disconnect + Disconnect + True + gtk-disconnect + + + False + True + + + + + True + False + Flash + Flash + True + gtk-media-record + + + False + True + + + + + True + False + + + True + False + start + 5 + 5 + + + + + False + True + + + + + 0 + 0 + 1 + 1 + + + + + True + False + 5 + 5 + 5 + + + True + False + 0.98999999999999999 + 4 + 4 + 1 + 0 + + + True + False + 12 + 12 + + + True + False + 2 + 6 + True + + + True + False + 1 + 1 + 0 + 0 + Chip: + + + 0 + 0 + 1 + 1 + + + + + True + False + 0 + 0 + Core: + + + 0 + 1 + 1 + 1 + + + + + True + False + 0 + 0 + Flash size: + + + 0 + 2 + 1 + 1 + + + + + True + False + 0 + 0 + True + + + 1 + 1 + 1 + 1 + + + + + True + False + 0 + 0 + 20 + + + 1 + 0 + 1 + 1 + + + + + True + False + 0 + 0 + + + 1 + 2 + 1 + 1 + + + + + True + False + 0 + 0 + Ram size: + + + 0 + 3 + 1 + 1 + + + + + True + False + 0 + 0 + + + 1 + 3 + 1 + 1 + + + + + + + + + True + False + 0.49000000953674316 + 2 + <b>Device</b> + True + + + + + 0 + 0 + 1 + 1 + + + + + 0 + 2 + 1 + 1 + + + + + True + False + 5 + 5 + 5 + vertical + 2 + + + 0 + 4 + 1 + 1 + + + + + True + False + 5 + 5 + 5 + 5 + + + True + False + vertical + + + True + False + + + True + False + start + 5 + 5 + 5 + 5 + Goto address: + + + 0 + 0 + 1 + 1 + + + + + True + True + 5 + 5 + 5 + 5 + 15 + + 12 + + + 1 + 0 + 1 + 1 + + + + + False + True + 0 + + + + + True + False + True + in + + + True + False + True + both + + + + + + + + False + True + 1 + + + + + Device memory + + + + + True + False + Device memory + + + False + + + + + True + False + vertical + + + True + False + + + True + False + 5 + 5 + 5 + 5 + Goto address: + + + 0 + 0 + 1 + 1 + + + + + True + True + 5 + 5 + 5 + 5 + 15 + + 12 + + + 1 + 0 + 1 + 1 + + + + + False + True + 0 + + + + + True + False + True + in + + + True + False + True + both + + + + + + + + False + True + 1 + + + + + 1 + + + + + True + False + No file + + + 1 + False + + + + + + + + + + + + + + + + + 0 + 3 + 1 + 1 + + + + + True + True + False + error + + + False + 8 + 5 + + + + + + True + True + 0 + + + + + False + 5 + vertical + 6 + end + + + + + + + + + + + + False + True + 1 + + + + + 0 + 1 + 1 + 1 + + + + + + From 688d6565fbe84cadf64cf4c8014ed5aa7299487d Mon Sep 17 00:00:00 2001 From: Jonas Danielsson Date: Mon, 10 Jun 2013 11:33:05 +0200 Subject: [PATCH 0217/1435] autoconf: add --with-gtk option to enable gui --- Makefile.am | 2 ++ configure.ac | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/Makefile.am b/Makefile.am index 9c99297ec..538db1a87 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,7 @@ # Makefile.am -- Process this file with automake to produce Makefile.in +SUBDIRS = . $(MAYBE_GUI) + AUTOMAKE_OPTIONS = subdir-objects bin_PROGRAMS = st-flash st-util st-term diff --git a/configure.ac b/configure.ac index e8923ed36..53f827893 100644 --- a/configure.ac +++ b/configure.ac @@ -34,6 +34,17 @@ case "${host}" in CPPFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CPPFLAGS" ;; esac + +MAYBE_GUI= +AC_ARG_WITH([gtk], AS_HELP_STRING([--with-gtk], [enable GTK+ gui])) +if test "x$with_gtk" = "xyes"; then + PKG_CHECK_MODULES([GTK], [gtk+-3.0]) + PKG_CHECK_MODULES([GLIB], [glib-2.0 > 2.32.0]) + MAYBE_GUI=gui + AC_CONFIG_FILES([gui/Makefile]) +fi +AC_SUBST([MAYBE_GUI]) + AC_CONFIG_FILES([Makefile]) AC_OUTPUT From cb8e6c65f95bf7495fac9c467e7d884a28bec995 Mon Sep 17 00:00:00 2001 From: Jonas Danielsson Date: Thu, 13 Jun 2013 08:03:21 +0200 Subject: [PATCH 0218/1435] stlink-gui: add check for existence of UI file --- gui/stlink-gui.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gui/stlink-gui.c b/gui/stlink-gui.c index 756d7666c..fde1d34ba 100644 --- a/gui/stlink-gui.c +++ b/gui/stlink-gui.c @@ -798,10 +798,15 @@ stlink_gui_build_ui (STlinkGUI *gui) { GtkBuilder *builder; GtkListStore *devmem_store; GtkListStore *filemem_store; + gchar *ui_file = STLINK_UI_DIR "/stlink-gui.ui"; + if (!g_file_test (ui_file, G_FILE_TEST_EXISTS)) { + ui_file = "stlink-gui.ui"; + } builder = gtk_builder_new (); - if (!gtk_builder_add_from_file (builder, STLINK_UI_DIR "/stlink-gui.ui", NULL)) { - /* woot */ + if (!gtk_builder_add_from_file (builder, ui_file, NULL)) { + g_printerr ("Failed to load UI file: %s\n", ui_file); + exit (1); } gui->window = GTK_WINDOW (gtk_builder_get_object (builder, "window")); From 5553cd1674ca94fc7be0377fb886dd8a54766d6c Mon Sep 17 00:00:00 2001 From: "Breton M. Saunders" Date: Fri, 14 Jun 2013 16:13:33 +0100 Subject: [PATCH 0219/1435] Added support for small f0 devices with core id 0x444 --- src/stlink-common.c | 7 +++++-- src/stlink-common.h | 14 +++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 05ee12cd3..ade2664fb 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1110,7 +1110,10 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) val = stlink_read_debug32(sl, STM32L_FLASH_PECR) | (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { + } else if (sl->core_id == STM32VL_CORE_ID + || sl->core_id == STM32F0_CORE_ID + || sl->chip_id == STM32_CHIPID_F3 + || sl->chip_id == STM32_CHIPID_F37x) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1321,7 +1324,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { loader_code = loader_code_stm32f4; loader_size = sizeof(loader_code_stm32f4); - } else if (sl->chip_id == STM32_CHIPID_F0) { + } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F0_SMALL) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); } else { diff --git a/src/stlink-common.h b/src/stlink-common.h index 68f5082e4..d2f274f82 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -111,6 +111,7 @@ extern "C" { #define STM32_CHIPID_F1_VL_HIGH 0x428 #define STM32_CHIPID_F1_XL 0x430 #define STM32_CHIPID_F0 0x440 +#define STM32_CHIPID_F0_SMALL 0x444 // Constant STM32 memory map figures #define STM32_FLASH_BASE 0x08000000 @@ -272,7 +273,18 @@ static const chip_params_t devices[] = { .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 - } + }, + { + //Use this as an example for mapping future chips: + //RM0091 document was used to find these paramaters + .chip_id = STM32_CHIPID_F0_SMALL, + .description = "F0 small device", + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + }, }; From 7f8750db3320c3c63be5d8b064498601b8a0dddb Mon Sep 17 00:00:00 2001 From: Andrey Yurovsky Date: Fri, 21 Jun 2013 11:59:35 -0700 Subject: [PATCH 0220/1435] add new STM32F401 parts (F4 variant) Nearly identical to STM32F403/407 but has different chip ID and RAM size: http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1577/LN1810 --- src/stlink-common.c | 61 ++++++++++++++++++++++++++++++--------------- src/stlink-common.h | 24 +++++++++++++++++- 2 files changed, 64 insertions(+), 21 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 05ee12cd3..ed1583d5a 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -143,7 +143,8 @@ static inline uint32_t read_flash_obr(stlink_t *sl) { static inline uint32_t read_flash_cr(stlink_t *sl) { uint32_t res; - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_LP)) res = stlink_read_debug32(sl, FLASH_F4_CR); else res = stlink_read_debug32(sl, FLASH_CR); @@ -155,7 +156,8 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_LP)) return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK); else return read_flash_cr(sl) & (1 << FLASH_CR_LOCK); @@ -167,7 +169,8 @@ static void unlock_flash(stlink_t *sl) { an invalid sequence results in a definitive lock of the FPEC block until next reset. */ - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) { + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_LP)) { stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); } else { @@ -192,7 +195,8 @@ static int unlock_flash_if(stlink_t *sl) { } static void lock_flash(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) { + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_LP)) { const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); stlink_write_debug32(sl, FLASH_F4_CR, n); } else { @@ -204,7 +208,8 @@ static void lock_flash(stlink_t *sl) { static void set_flash_cr_pg(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) { + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_LP)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_CR_PG); stlink_write_debug32(sl, FLASH_F4_CR, x); @@ -216,7 +221,8 @@ static void set_flash_cr_pg(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_LP)) stlink_write_debug32(sl, FLASH_F4_CR, n); else stlink_write_debug32(sl, FLASH_CR, n); @@ -233,7 +239,8 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { } static void set_flash_cr_mer(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_LP)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); else @@ -242,7 +249,8 @@ static void set_flash_cr_mer(stlink_t *sl) { } static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_LP)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); else @@ -251,7 +259,8 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { } static void set_flash_cr_strt(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) { + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_LP)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_F4_CR_STRT); stlink_write_debug32(sl, FLASH_F4_CR, x); @@ -267,7 +276,8 @@ static inline uint32_t read_flash_acr(stlink_t *sl) { static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res; - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_LP)) res = stlink_read_debug32(sl, FLASH_F4_SR); else res = stlink_read_debug32(sl, FLASH_SR); @@ -276,7 +286,8 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { } static inline unsigned int is_flash_busy(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_LP)) return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY); else return read_flash_sr(sl) & (1 << FLASH_SR_BSY); @@ -450,7 +461,8 @@ int stlink_load_device_params(stlink_t *sl) { // read flash size from hardware, if possible... if (sl->chip_id == STM32_CHIPID_F2) { sl->flash_size = 0x100000; /* Use maximum, User must care!*/ - } else if (sl->chip_id == STM32_CHIPID_F4) { + } else if (sl->chip_id == STM32_CHIPID_F4 || + sl->chip_id == STM32_CHIPID_F4_LP) { sl->flash_size = 0x100000; //todo: RM0090 error; size register same address as unique ID } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { // if the flash size is zero, we assume it is 128k, if not we calculate the real value @@ -993,7 +1005,8 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) { + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_LP)) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector<4) sl->flash_pgsz=0x4000; else if(sector<5) sl->flash_pgsz=0x10000; @@ -1010,7 +1023,8 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) { + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_LP)) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1110,7 +1124,10 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) val = stlink_read_debug32(sl, STM32L_FLASH_PECR) | (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { + } else if (sl->core_id == STM32VL_CORE_ID + || sl->core_id == STM32F0_CORE_ID + || sl->chip_id == STM32_CHIPID_F3 + || sl->chip_id == STM32_CHIPID_F37x) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1318,10 +1335,11 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); - } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { + } else if (sl->chip_id == STM32_CHIPID_F2 || + sl->chip_id == STM32_CHIPID_F4 || sl->chip_id == STM32_CHIPID_F4_LP) { loader_code = loader_code_stm32f4; loader_size = sizeof(loader_code_stm32f4); - } else if (sl->chip_id == STM32_CHIPID_F0) { + } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F0_SMALL) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); } else { @@ -1486,7 +1504,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t ILOG("Finished erasing %d pages of %d (%#x) bytes\n", page_count, sl->flash_pgsz, sl->flash_pgsz); - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) { + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_LP)) { /* todo: check write operation */ ILOG("Starting Flash write for F2/F4\n"); @@ -1769,7 +1788,8 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, 0, 3); /* flash bank 0 (input) */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { + } else if (sl->chip_id == STM32_CHIPID_F2 || + sl->chip_id == STM32_CHIPID_F4 || sl->chip_id == STM32_CHIPID_F4_LP) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1821,7 +1841,8 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { + } else if (sl->chip_id == STM32_CHIPID_F2 || + sl->chip_id == STM32_CHIPID_F4 || sl->chip_id == STM32_CHIPID_F4_LP) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { diff --git a/src/stlink-common.h b/src/stlink-common.h index 68f5082e4..8b1be82c8 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -102,6 +102,7 @@ extern "C" { #define STM32_CHIPID_F3 0x422 #define STM32_CHIPID_F37x 0x432 #define STM32_CHIPID_F4 0x413 +#define STM32_CHIPID_F4_LP 0x423 #define STM32_CHIPID_F1_HIGH 0x414 #define STM32_CHIPID_L1_MEDIUM 0x416 #define STM32_CHIPID_L1_MEDIUM_PLUS 0x436 @@ -111,6 +112,7 @@ extern "C" { #define STM32_CHIPID_F1_VL_HIGH 0x428 #define STM32_CHIPID_F1_XL 0x430 #define STM32_CHIPID_F0 0x440 +#define STM32_CHIPID_F0_SMALL 0x444 // Constant STM32 memory map figures #define STM32_FLASH_BASE 0x08000000 @@ -175,6 +177,15 @@ static const chip_params_t devices[] = { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 }, + { + .chip_id = STM32_CHIPID_F4_LP, + .description = "F4 device (low power)", + .flash_size_reg = 0x1FFF7A10, + .flash_pagesize = 0x4000, + .sram_size = 0x10000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, { .chip_id = STM32_CHIPID_F1_HIGH, .description = "F1 High-density device", @@ -272,7 +283,18 @@ static const chip_params_t devices[] = { .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 - } + }, + { + //Use this as an example for mapping future chips: + //RM0091 document was used to find these paramaters + .chip_id = STM32_CHIPID_F0_SMALL, + .description = "F0 small device", + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + }, }; From ff1e88398c0de2084b13196a422101224fed2779 Mon Sep 17 00:00:00 2001 From: Burns Date: Fri, 21 Jun 2013 17:36:15 -0400 Subject: [PATCH 0221/1435] Support for STM32L1 medium-plus chips with chip id 0x427 -Changed the STM32L1 "medium plus" (id 0x436) support to be called HIGH. -Added the device id 0x427 and call it medium plus. -Gave the loader more time so it stopped timing out and thinking it failed. -Added st-term to .gitignore Note: ST seems to call some chips with 436 medium plus and some high. It seemed easier to name 436 high and 427 medium plus. --- .gitignore | 1 + src/stlink-common.c | 30 +++++++++++++++++++----------- src/stlink-common.h | 22 +++++++++++++++++++--- 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 6ed8efce9..d7df95e81 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ config.status compile st-flash st-util +st-term test_usb test_sg *.deps* diff --git a/src/stlink-common.c b/src/stlink-common.c index ade2664fb..2b208bc54 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -452,7 +452,7 @@ int stlink_load_device_params(stlink_t *sl) { sl->flash_size = 0x100000; /* Use maximum, User must care!*/ } else if (sl->chip_id == STM32_CHIPID_F4) { sl->flash_size = 0x100000; //todo: RM0090 error; size register same address as unique ID - } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { + } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) { // if the flash size is zero, we assume it is 128k, if not we calculate the real value uint32_t flash_size = stlink_read_debug32(sl,params->flash_size_reg) & 0xffff; if ( flash_size == 0 ) { @@ -460,7 +460,7 @@ int stlink_load_device_params(stlink_t *sl) { } else { sl->flash_size = flash_size * 1024; } - } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_L1_MEDIUM_PLUS) { + } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_L1_HIGH) { uint32_t flash_size = stlink_read_debug32(sl, params->flash_size_reg) & 0x1; // 0 is 384k and 1 is 256k if ( flash_size == 0 ) { @@ -911,7 +911,8 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) int error = -1; size_t off; int num_empty = 0; - unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS)?0:0xff; + unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS + || sl->chip_id == STM32_CHIPID_L1_HIGH) ? 0:0xff; const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); if (fd == -1) { @@ -1036,7 +1037,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) #if DEBUG_FLASH fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); #endif - } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) { + } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS + || sl->chip_id == STM32_CHIPID_L1_HIGH) { uint32_t val; @@ -1145,7 +1147,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } int stlink_erase_flash_mass(stlink_t *sl) { - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS ) { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS + || sl->chip_id == STM32_CHIPID_L1_HIGH) { /* erase each page */ int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -1315,7 +1318,8 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { const uint8_t* loader_code; size_t loader_size; - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS ) { /* stm32l */ + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS + || sl->chip_id == STM32_CHIPID_L1_HIGH ) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { @@ -1555,7 +1559,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } //STM32F4END - else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) { + else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS + || sl->chip_id == STM32_CHIPID_L1_HIGH ) { /* use fast word write. todo: half page. */ uint32_t val; @@ -1711,7 +1716,8 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { /* write the file in flash at addr */ int err; unsigned int num_empty = 0, index; - unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS)?0:0xff; + unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS + || sl->chip_id == STM32_CHIPID_L1_HIGH )?0:0xff; mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { ELOG("map_file() == -1\n"); @@ -1749,7 +1755,8 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS + || sl->chip_id == STM32_CHIPID_L1_HIGH ) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1791,7 +1798,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons /* run loader */ stlink_run(sl); -#define WAIT_ROUNDS 1000 +#define WAIT_ROUNDS 10000 /* wait until done (reaches breakpoint) */ for (i = 0; i < WAIT_ROUNDS; i++) { usleep(10); @@ -1805,7 +1812,8 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } /* check written byte count */ - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS + || sl->chip_id == STM32_CHIPID_L1_HIGH ) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; diff --git a/src/stlink-common.h b/src/stlink-common.h index d2f274f82..7553224cd 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -104,7 +104,13 @@ extern "C" { #define STM32_CHIPID_F4 0x413 #define STM32_CHIPID_F1_HIGH 0x414 #define STM32_CHIPID_L1_MEDIUM 0x416 -#define STM32_CHIPID_L1_MEDIUM_PLUS 0x436 +#define STM32_CHIPID_L1_MEDIUM_PLUS 0x427 +/* + * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" + * and some that are called "High". 0x427 is assigned to the other "Medium- + * plus" chips. To make it a bit simpler we just call 427 MEDIUM_PLUS and + * 0x436 HIGH. + */ #define STM32_CHIPID_L1_HIGH 0x436 #define STM32_CHIPID_F1_CONN 0x418 #define STM32_CHIPID_F1_VL_MEDIUM 0x420 @@ -199,12 +205,22 @@ static const chip_params_t devices[] = { { .chip_id = STM32_CHIPID_L1_MEDIUM_PLUS, .description = "L1 Medium-Plus-density device", - .flash_size_reg = 0x1ff800CC, + .flash_size_reg = 0x1ff800cc, .flash_pagesize = 0x100, - .sram_size = 0x8000, + .sram_size = 0x8000,/*Not completely clear if there are some with 48K*/ .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000 }, + { + .chip_id = STM32_CHIPID_L1_HIGH, + .description = "L1 High-density device", + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0xC000, /*Not completely clear if there are some with 32K*/ + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, + { .chip_id = STM32_CHIPID_F1_CONN, .description = "F1 Connectivity line device", From 328dfd24fae56531d2df21ce2dfc781aefcc46c5 Mon Sep 17 00:00:00 2001 From: "Breton M. Saunders" Date: Tue, 9 Jul 2013 16:02:07 +0100 Subject: [PATCH 0222/1435] Added proper reset support; now asserts nrst and then performs sysreset. --- src/stlink-common.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index 23bea5836..b0de0ab34 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -499,6 +499,11 @@ int stlink_load_device_params(stlink_t *sl) { void stlink_reset(stlink_t *sl) { DLOG("*** stlink_reset ***\n"); + // Step 1: assert jtag reset + sl->backend->jtag_reset(sl, 1); + // Step 2: deassert jtag reset + sl->backend->jtag_reset(sl, 0); + // Step 3: perform the sysreset command sl->backend->reset(sl); } From f14323195cdc6b9c547c42de174ee127c66dead7 Mon Sep 17 00:00:00 2001 From: lementec Date: Thu, 18 Jul 2013 17:42:59 +0200 Subject: [PATCH 0223/1435] jtag reset introduced in 57d068097eb57aa7ee985ddb1edea90a5d6d5d8a breaks things --- src/stlink-common.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index b0de0ab34..23bea5836 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -499,11 +499,6 @@ int stlink_load_device_params(stlink_t *sl) { void stlink_reset(stlink_t *sl) { DLOG("*** stlink_reset ***\n"); - // Step 1: assert jtag reset - sl->backend->jtag_reset(sl, 1); - // Step 2: deassert jtag reset - sl->backend->jtag_reset(sl, 0); - // Step 3: perform the sysreset command sl->backend->reset(sl); } From 36cd837fc9382c8ccc5da2a562c261f2a47a9736 Mon Sep 17 00:00:00 2001 From: JohannesTaelman Date: Tue, 13 Aug 2013 15:37:44 +0200 Subject: [PATCH 0224/1435] fixed USB VID/PID detection bug When a USB device with same VID but different PID is found, it got selected as STLINK device. --- src/stlink-usb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index d57458428..9895da855 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -754,7 +754,10 @@ stlink_t* stlink_open_usb(const int verbose) { 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_PID) slu->protocoll = 1; break; + if (desc.idProduct == USB_STLINK_PID) { + slu->protocoll = 1; + break; + } } if (cnt < 0) { From 596fb35916ef2f1da8b817fa4b6e365e71c0fc5a Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 6 Mar 2013 15:24:15 -0500 Subject: [PATCH 0225/1435] Add option to not reset board on connect '-n' in st-util will cause it to skip the reset step, and thus allow you to begin debugging at whatever point the code may currently be at. Adding this feature required changing the stlink_open functions to accept a reset flag that tells them whether or not to reset after connecting. Skipping reset does not seem to have any adverse effects on stlink usb devices. Unfortunately, I have to stlink v1 devices to test. --- flash/main.c | 4 ++-- gdbserver/gdb-server.c | 34 +++++++++++++++++++++++++--------- src/st-term.c | 2 +- src/stlink-sg.c | 6 ++++-- src/stlink-sg.h | 2 +- src/stlink-usb.c | 6 ++++-- src/stlink-usb.h | 2 +- src/test_sg.c | 2 +- src/test_usb.c | 2 +- 9 files changed, 40 insertions(+), 20 deletions(-) diff --git a/flash/main.c b/flash/main.c index 110c2964d..980af63be 100644 --- a/flash/main.c +++ b/flash/main.c @@ -106,13 +106,13 @@ int main(int ac, char** av) if (o.devname != NULL) /* stlinkv1 */ { - sl = stlink_v1_open(50); + sl = stlink_v1_open(50, 1); if (sl == NULL) goto on_error; sl->verbose = 50; } else /* stlinkv2 */ { - sl = stlink_open_usb(50); + sl = stlink_open_usb(50, 1); if (sl == NULL) goto on_error; sl->verbose = 50; } diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index f9c06f983..d0a6a02d7 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -50,6 +50,7 @@ typedef struct _st_state_t { int logging_level; int listen_port; int persistent; + int reset; } st_state_t; @@ -78,6 +79,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { {"stlinkv1", no_argument, NULL, '1'}, {"listen_port", required_argument, NULL, 'p'}, {"multi", optional_argument, NULL, 'm'}, + {"no-reset", optional_argument, NULL, 'n'}, {0, 0, 0, 0}, }; const char * help_str = "%s - usage:\n\n" @@ -95,13 +97,15 @@ int parse_options(int argc, char** argv, st_state_t *st) { " -m, --multi\n" "\t\t\tSet gdb server to extended mode.\n" "\t\t\tst-util will continue listening for connections after disconnect.\n" + " -n, --no-reset\n" + "\t\t\tDo not reset board on connection.\n" ; int option_index = 0; int c; int q; - while ((c = getopt_long(argc, argv, "hv::d:s:1p:m", long_options, &option_index)) != -1) { + while ((c = getopt_long(argc, argv, "hv::d:s:1p:mn", long_options, &option_index)) != -1) { switch (c) { case 0: printf("XXXXX Shouldn't really normally come here, only if there's no corresponding option\n"); @@ -151,6 +155,9 @@ int parse_options(int argc, char** argv, st_state_t *st) { case 'm': st->persistent = 1; break; + case 'n': + st->reset = 0; + break; } } @@ -174,14 +181,15 @@ int main(int argc, char** argv) { state.stlink_version = 2; state.logging_level = DEFAULT_LOGGING_LEVEL; state.listen_port = DEFAULT_GDB_LISTEN_PORT; + state.reset = 1; /* By default, reset board */ parse_options(argc, argv, &state); switch (state.stlink_version) { case 2: - sl = stlink_open_usb(state.logging_level); + sl = stlink_open_usb(state.logging_level, 0); if(sl == NULL) return 1; break; case 1: - sl = stlink_v1_open(state.logging_level); + sl = stlink_v1_open(state.logging_level, 0); if(sl == NULL) return 1; break; } @@ -190,6 +198,10 @@ int main(int argc, char** argv) { signal(SIGINT, &cleanup); signal(SIGTERM, &cleanup); + if (state.reset) { + stlink_reset(sl); + } + printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); sl->verbose=0; @@ -205,6 +217,9 @@ int main(int argc, char** argv) { do { serve(sl, &state); + + /* Continue */ + stlink_run(sl); } while (state.persistent); #ifdef __MINGW32__ @@ -213,7 +228,6 @@ int main(int argc, char** argv) { #endif /* Switch back to mass storage mode before closing. */ - stlink_run(sl); stlink_exit_debug_mode(sl); stlink_close(sl); @@ -679,11 +693,6 @@ int serve(stlink_t *sl, st_state_t *st) { return 1; } - stlink_force_debug(sl); - stlink_reset(sl); - init_code_breakpoints(sl); - init_data_watchpoints(sl); - printf("Listening at *:%d...\n", st->listen_port); int client = accept(sock, NULL, NULL); @@ -695,6 +704,13 @@ int serve(stlink_t *sl, st_state_t *st) { close(sock); + stlink_force_debug(sl); + if (st->reset) { + stlink_reset(sl); + } + init_code_breakpoints(sl); + init_data_watchpoints(sl); + printf("GDB connected.\n"); /* diff --git a/src/st-term.c b/src/st-term.c index f4643933c..9be3263af 100644 --- a/src/st-term.c +++ b/src/st-term.c @@ -136,7 +136,7 @@ int main(int ac, char** av) { /* unused */ ac = ac; av = av; - sl = stlink_open_usb(10); + sl = stlink_open_usb(10, 1); if (sl != NULL) { printf("ST-Linky proof-of-concept terminal :: Created by Necromant for lulz\n"); stlink_version(sl); diff --git a/src/stlink-sg.c b/src/stlink-sg.c index ae610bac7..be1f7526b 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -1021,7 +1021,7 @@ stlink_t* stlink_v1_open_inner(const int verbose) { return sl; } -stlink_t* stlink_v1_open(const int verbose) { +stlink_t* stlink_v1_open(const int verbose, int reset) { stlink_t *sl = stlink_v1_open_inner(verbose); if (sl == NULL) { fputs("Error: could not open stlink device\n", stderr); @@ -1030,7 +1030,9 @@ stlink_t* stlink_v1_open(const int verbose) { // by now, it _must_ be fully open and in a useful mode.... stlink_enter_swd_mode(sl); /* Now we are ready to read the parameters */ - stlink_reset(sl); + if (reset) { + stlink_reset(sl); + } stlink_load_device_params(sl); ILOG("Successfully opened a stlink v1 debugger\n"); return sl; diff --git a/src/stlink-sg.h b/src/stlink-sg.h index beecac324..f8871db99 100644 --- a/src/stlink-sg.h +++ b/src/stlink-sg.h @@ -63,7 +63,7 @@ extern "C" { reg reg; }; - stlink_t* stlink_v1_open(const int verbose); + stlink_t* stlink_v1_open(const int verbose, int reset); #ifdef __cplusplus } diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 9895da855..858361c66 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -704,7 +704,7 @@ stlink_backend_t _stlink_usb_backend = { }; -stlink_t* stlink_open_usb(const int verbose) { +stlink_t* stlink_open_usb(const int verbose, int reset) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; int error = -1; @@ -833,7 +833,9 @@ stlink_t* stlink_open_usb(const int verbose) { stlink_enter_swd_mode(sl); } - stlink_reset(sl); + if (reset) { + stlink_reset(sl); + } stlink_load_device_params(sl); stlink_version(sl); diff --git a/src/stlink-usb.h b/src/stlink-usb.h index 63b53695e..f433193c8 100644 --- a/src/stlink-usb.h +++ b/src/stlink-usb.h @@ -30,7 +30,7 @@ extern "C" { unsigned int cmd_len; }; - stlink_t* stlink_open_usb(const int verbose); + stlink_t* stlink_open_usb(const int verbose, int reset); #ifdef __cplusplus diff --git a/src/test_sg.c b/src/test_sg.c index 51b0f074c..bc16a1c7c 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -52,7 +52,7 @@ int main(int argc, char *argv[]) { break; } - stlink_t *sl = stlink_v1_open(99); + stlink_t *sl = stlink_v1_open(99, 1); if (sl == NULL) return EXIT_FAILURE; diff --git a/src/test_usb.c b/src/test_usb.c index be4981db0..5e8806d29 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(10); + sl = stlink_open_usb(10, 1); if (sl != NULL) { printf("-- version\n"); stlink_version(sl); From 77f85f32097975a2511fecac39b789dac6f0d4f7 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sat, 24 Aug 2013 13:40:03 +0400 Subject: [PATCH 0226/1435] Update list of known working targets --- README | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README b/README index cd4fc5af5..d717dc22a 100644 --- a/README +++ b/README @@ -163,8 +163,9 @@ STLink v2 (as found on the 32L and F4 Discovery boards) Known Working Targets: * STM32F100xx (Medium Density VL, as on the 32VL Discovery board) * STM32L1xx (STM32L Discovery board) -* STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on a custom boards +* STM32F103VC, STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on custom boards (https://github.com/UweBonnes/wiki_fuer_alex/layout/usps...) +* STM32F303xx (STM32F3 Discovery board) * STM32F407xx (STM32F4 Discovery board) Please report any and all known working combinations so I can update this! From 00eb8b959d3207dffd8e15eeec6550b65b057a35 Mon Sep 17 00:00:00 2001 From: texane Date: Sat, 31 Aug 2013 22:04:21 -0500 Subject: [PATCH 0227/1435] [ fix ] 0001-stlink-gui-Follow-new-stlink_open-usage, fix from Jim Huang --- gui/stlink-gui.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gui/stlink-gui.c b/gui/stlink-gui.c index fde1d34ba..3646c3a4f 100644 --- a/gui/stlink-gui.c +++ b/gui/stlink-gui.c @@ -528,9 +528,9 @@ connect_button_cb (GtkWidget *widget, gpointer data) return; /* try version 1 then version 2 */ - gui->sl = stlink_v1_open(0); + gui->sl = stlink_v1_open(0, 1); if (gui->sl == NULL) { - gui->sl = stlink_open_usb(0); + gui->sl = stlink_open_usb(0, 1); } if (gui->sl == NULL) { stlink_gui_set_info_error_message (gui, "Failed to connect to STLink."); return; From 0a6c0903c65439cfeb0aabee31521662d1e61a0e Mon Sep 17 00:00:00 2001 From: texane Date: Sat, 31 Aug 2013 22:09:05 -0500 Subject: [PATCH 0228/1435] [ fix ] missing exit prototype, include stdlib.h --- src/st-term.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/st-term.c b/src/st-term.c index 9be3263af..346cca58f 100644 --- a/src/st-term.c +++ b/src/st-term.c @@ -1,4 +1,5 @@ #include +#include /* According to POSIX.1-2001 */ #include #include From 57700499f1ae4ec327eaf36fe957244002b461db Mon Sep 17 00:00:00 2001 From: Maxime Vincent Date: Sun, 1 Sep 2013 09:23:19 +0200 Subject: [PATCH 0229/1435] Fixed the DEBUG switch in gdb-server.c --- gdbserver/gdb-server.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index d0a6a02d7..13c5d1641 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -384,7 +384,7 @@ struct code_hw_watchpoint { struct code_hw_watchpoint data_watches[DATA_WATCH_NUM]; static void init_data_watchpoints(stlink_t *sl) { - #ifdef DEBUG + #if DEBUG printf("init watchpoints\n"); #endif @@ -419,7 +419,7 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr for(i = 0; i < DATA_WATCH_NUM; i++) { // is this an empty slot ? if(data_watches[i].fun == WATCHDISABLED) { - #ifdef DEBUG + #if DEBUG printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len); #endif @@ -443,7 +443,7 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr } } - #ifdef DEBUG + #if DEBUG printf("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len); #endif return -1; @@ -455,7 +455,7 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) for(i = 0 ; i < DATA_WATCH_NUM; i++) { if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) { - #ifdef DEBUG + #if DEBUG printf("delete watchpoint %d addr %x\n", i, addr); #endif @@ -466,7 +466,7 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) } } - #ifdef DEBUG + #if DEBUG printf("failure: delete watchpoint addr %x\n", addr); #endif @@ -527,7 +527,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { else brk->type &= ~type; if(brk->type == 0) { - #ifdef DEBUG + #if DEBUG printf("clearing hw break %d\n", id); #endif @@ -535,7 +535,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { } else { uint32_t mask = (brk->addr) | 1 | (brk->type << 30); - #ifdef DEBUG + #if DEBUG printf("setting hw break %d at %08x (%d)\n", id, brk->addr, brk->type); printf("reg %08x \n", @@ -631,7 +631,7 @@ static int flash_go(stlink_t *sl) { stlink_reset(sl); for(struct flash_block* fb = flash_root; fb; fb = fb->next) { - #ifdef DEBUG + #if DEBUG printf("flash_do: block %08x -> %04x\n", fb->addr, fb->length); #endif @@ -641,7 +641,7 @@ static int flash_go(stlink_t *sl) { //Update FLASH_PAGE stlink_calculate_pagesize(sl, page); - #ifdef DEBUG + #if DEBUG printf("flash_do: page %08x\n", page); #endif @@ -728,7 +728,7 @@ int serve(stlink_t *sl, st_state_t *st) { return 1; } - #ifdef DEBUG + #if DEBUG printf("recv: %s\n", packet); #endif @@ -753,7 +753,7 @@ int serve(stlink_t *sl, st_state_t *st) { char* queryName = calloc(queryNameLength + 1, 1); strncpy(queryName, &packet[1], queryNameLength); - #ifdef DEBUG + #if DEBUG printf("query: %s;%s\n", queryName, params); #endif @@ -778,7 +778,7 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned addr = strtoul(__s_addr, NULL, 16), length = strtoul(s_length, NULL, 16); - #ifdef DEBUG + #if DEBUG printf("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", type, op, annex, addr, length); #endif @@ -815,7 +815,7 @@ int serve(stlink_t *sl, st_state_t *st) { if (!strncmp(params,"726573756d65",12)) {// resume -#ifdef DEBUG +#if DEBUG printf("Rcmd: resume\n"); #endif stlink_run(sl); @@ -826,7 +826,7 @@ int serve(stlink_t *sl, st_state_t *st) { stlink_force_debug(sl); -#ifdef DEBUG +#if DEBUG printf("Rcmd: halt\n"); #endif } else if (!strncmp(params,"6a7461675f7265736574",20)) { //jtag_reset @@ -836,7 +836,7 @@ int serve(stlink_t *sl, st_state_t *st) { stlink_jtag_reset(sl, 0); stlink_force_debug(sl); -#ifdef DEBUG +#if DEBUG printf("Rcmd: jtag_reset\n"); #endif } else if (!strncmp(params,"7265736574",10)) { //reset @@ -847,11 +847,11 @@ int serve(stlink_t *sl, st_state_t *st) { init_code_breakpoints(sl); init_data_watchpoints(sl); -#ifdef DEBUG +#if DEBUG printf("Rcmd: reset\n"); #endif } else { -#ifdef DEBUG +#if DEBUG printf("Rcmd: %s\n", params); #endif @@ -883,7 +883,7 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned addr = strtoul(__s_addr, NULL, 16), length = strtoul(s_length, NULL, 16); - #ifdef DEBUG + #if DEBUG printf("FlashErase: addr:%08x,len:%04x\n", addr, length); #endif @@ -921,7 +921,7 @@ int serve(stlink_t *sl, st_state_t *st) { if(dec_index % 2 != 0) dec_index++; - #ifdef DEBUG + #if DEBUG printf("binary packet %d -> %d\n", data_length, dec_index); #endif @@ -1263,7 +1263,7 @@ int serve(stlink_t *sl, st_state_t *st) { } if(reply) { - #ifdef DEBUG + #if DEBUG printf("send: %s\n", reply); #endif From e19054a4b36068329211cf5069ed92b06be66d8c Mon Sep 17 00:00:00 2001 From: Andrew 'Necromant' Andrianov Date: Sun, 29 Sep 2013 16:22:07 +0400 Subject: [PATCH 0230/1435] Add st-info utility Signed-off-by: Andrew 'Necromant' Andrianov --- Makefile.am | 9 ++++-- src/st-info.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/st-info.c diff --git a/Makefile.am b/Makefile.am index 538db1a87..ab3201f03 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,12 +4,13 @@ SUBDIRS = . $(MAYBE_GUI) AUTOMAKE_OPTIONS = subdir-objects -bin_PROGRAMS = st-flash st-util st-term +bin_PROGRAMS = st-flash st-util st-term st-info noinst_LIBRARIES = libstlink.a st_flash_SOURCES = flash/main.c st_term_SOURCES = src/st-term.c +st_info_SOURCES = src/st-info.c st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c mingw/mingw.c mingw/mingw.h CFILES = \ @@ -17,7 +18,8 @@ CFILES = \ src/stlink-usb.c \ src/stlink-sg.c \ src/uglylogging.c \ - src/st-term.c + src/st-term.c \ + src/st-info.c HFILES = \ src/stlink-common.h \ @@ -40,6 +42,9 @@ st_util_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcd st_term_LDADD = libstlink.a st_term_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw +st_info_LDADD = libstlink.a +st_info_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw + EXTRA_DIST = autogen.sh diff --git a/src/st-info.c b/src/st-info.c new file mode 100644 index 000000000..6b251bce2 --- /dev/null +++ b/src/st-info.c @@ -0,0 +1,88 @@ +/* simple wrapper around the stlink_flash_write function */ + +// TODO - this should be done as just a simple flag to the st-util command line... + + +#include +#include +#include +#include +#include "stlink-common.h" + +static void usage(void) +{ + puts("st-info --flash"); + puts("st-info --sram"); + puts("st-info --descr"); + puts("st-info --pagesize"); + puts("st-info --chipid"); +} + +static int print_data(stlink_t* sl, int ac, char** av) +{ + int ret = 0; + if (strcmp(av[1], "--flash") == 0) + printf("0x%lx\n", sl->flash_size); + else if (strcmp(av[1], "--sram") == 0) + printf("0x%lx\n", sl->sram_size); + else if (strcmp(av[1], "--pagesize") == 0) + printf("0x%lx\n", sl->flash_pgsz); + else if (strcmp(av[1], "--chipid") == 0) + printf("0x%.4x\n", sl->chip_id); + else if (strcmp(av[1], "--descr")==0) { + const chip_params_t *params = NULL; + for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { + if(devices[i].chip_id == sl->chip_id) { + params = &devices[i]; + break; + } + } + if (params == NULL) { + return -1; + } + printf("%s\n", params->description); + } +} + + +stlink_t* open_sl() +{ + stlink_t* sl; + sl = stlink_v1_open(0, 1); + if (sl == NULL) + sl = stlink_open_usb(0, 1); + return sl; +} + + +int main(int ac, char** av) +{ + stlink_t* sl = NULL; + int err = -1; + if (ac < 2) { + usage(); + return -1; + } + + sl = open_sl(); + + if (sl == NULL) { + return -1; + } + sl->verbose=0; + 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); + + err = print_data(sl, ac, av); + + if (sl != NULL) + { + stlink_exit_debug_mode(sl); + stlink_close(sl); + } + + return err; +} From e886396e0e0ee27f8df2182f4d1a96bf59efedfb Mon Sep 17 00:00:00 2001 From: htk Date: Mon, 30 Sep 2013 01:51:26 +0200 Subject: [PATCH 0231/1435] Support for reading target voltage --- gdbserver/gdb-server.c | 6 ++++++ src/stlink-common.c | 16 ++++++++++++++++ src/stlink-common.h | 3 +++ src/stlink-sg.c | 3 ++- src/stlink-usb.c | 31 ++++++++++++++++++++++++++++++- 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 13c5d1641..bf1478122 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -172,6 +172,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { int main(int argc, char** argv) { + uint32_t voltage; stlink_t *sl = NULL; @@ -204,6 +205,11 @@ int main(int argc, char** argv) { printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); + voltage = stlink_target_voltage(sl); + if (voltage != -1) { + printf("Target voltage is %d mV.\n", voltage); + } + sl->verbose=0; current_memory_map = make_memory_map(sl); diff --git a/src/stlink-common.c b/src/stlink-common.c index 23bea5836..9613080ba 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -561,6 +561,22 @@ void stlink_version(stlink_t *sl) { } } +int stlink_target_voltage(stlink_t *sl) { + int voltage = -1; + DLOG("*** reading target voltage\n"); + if (sl->backend->target_voltage != NULL) { + voltage = sl->backend->target_voltage(sl); + if (voltage != -1) { + DLOG("target voltage = %ldmV\n", voltage); + } else { + DLOG("error reading target voltage\n"); + } + } else { + DLOG("reading voltage not supported by backend\n"); + } + return voltage; +} + uint32_t stlink_read_debug32(stlink_t *sl, uint32_t addr) { uint32_t data = sl->backend->read_debug32(sl, addr); DLOG("*** stlink_read_debug32 %x is %#x\n", data, addr); diff --git a/src/stlink-common.h b/src/stlink-common.h index c17019568..0ac4f12e0 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -34,6 +34,7 @@ extern "C" { #define STLINK_GET_VERSION 0xf1 #define STLINK_GET_CURRENT_MODE 0xf5 +#define STLINK_GET_TARGET_VOLTAGE 0xF7 #define STLINK_DEBUG_COMMAND 0xF2 #define STLINK_DFU_COMMAND 0xF3 @@ -386,6 +387,7 @@ static const chip_params_t devices[] = { void (*step) (stlink_t * stl); int (*current_mode) (stlink_t * stl); void (*force_debug) (stlink_t *sl); + uint32_t (*target_voltage) (stlink_t *sl); } stlink_backend_t; struct _stlink { @@ -455,6 +457,7 @@ static const chip_params_t devices[] = { void stlink_step(stlink_t *sl); int stlink_current_mode(stlink_t *sl); void stlink_force_debug(stlink_t *sl); + int stlink_target_voltage(stlink_t *sl); // unprocessed diff --git a/src/stlink-sg.c b/src/stlink-sg.c index be1f7526b..53e93cce0 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -878,7 +878,8 @@ stlink_backend_t _stlink_sg_backend = { _stlink_sg_write_reg, _stlink_sg_step, _stlink_sg_current_mode, - _stlink_sg_force_debug + _stlink_sg_force_debug, + NULL }; static stlink_t* stlink_open(const int verbose) { diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 858361c66..fa2bd7e08 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -203,6 +203,34 @@ void _stlink_usb_version(stlink_t *sl) { } } +int _stlink_usb_target_voltage(stlink_t *sl) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const rdata = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + uint32_t rep_len = 8; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + uint32_t factor, reading; + int voltage; + + cmd[i++] = STLINK_GET_TARGET_VOLTAGE; + + size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); + if (size == -1) { + printf("[!] send_recv\n"); + return -1; + } else if (size != 8) { + printf("[!] wrong length\n"); + return -1; + } + + factor = (rdata[3] << 24) | (rdata[2] << 16) | (rdata[1] << 8) | (rdata[0] << 0); + reading = (rdata[7] << 24) | (rdata[6] << 16) | (rdata[5] << 8) | (rdata[4] << 0); + voltage = 2400 * reading / factor; + + return voltage; +} + uint32_t _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const rdata = sl->q_buf; @@ -700,7 +728,8 @@ stlink_backend_t _stlink_usb_backend = { _stlink_usb_write_reg, _stlink_usb_step, _stlink_usb_current_mode, - _stlink_usb_force_debug + _stlink_usb_force_debug, + _stlink_usb_target_voltage }; From a13e75a25a322a9115f59cb753686ec9a2c7b6f7 Mon Sep 17 00:00:00 2001 From: texane Date: Mon, 30 Sep 2013 09:15:47 -0500 Subject: [PATCH 0232/1435] [ fix ] st-info warnings --- src/st-info.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/st-info.c b/src/st-info.c index 6b251bce2..e28a4f12c 100644 --- a/src/st-info.c +++ b/src/st-info.c @@ -18,7 +18,7 @@ static void usage(void) puts("st-info --chipid"); } -static int print_data(stlink_t* sl, int ac, char** av) +static int print_data(stlink_t* sl, char** av) { int ret = 0; if (strcmp(av[1], "--flash") == 0) @@ -42,10 +42,11 @@ static int print_data(stlink_t* sl, int ac, char** av) } printf("%s\n", params->description); } + return ret; } -stlink_t* open_sl() +stlink_t* open_sl(void) { stlink_t* sl; sl = stlink_v1_open(0, 1); @@ -76,7 +77,7 @@ int main(int ac, char** av) if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); - err = print_data(sl, ac, av); + err = print_data(sl, av); if (sl != NULL) { From f15ef16aea0304d008ad689ef7d10fa1b40cfc90 Mon Sep 17 00:00:00 2001 From: texane Date: Mon, 14 Oct 2013 18:07:46 -0500 Subject: [PATCH 0233/1435] [ patch from Uwe Bonnes ] determine flash size for more devices --- src/stlink-common.c | 21 ++++++--------------- src/stlink-common.h | 6 +++--- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 9613080ba..a08da392c 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -434,6 +434,7 @@ int stlink_load_device_params(stlink_t *sl) { const chip_params_t *params = NULL; sl->core_id = stlink_core_id(sl); uint32_t chip_id = stlink_chip_id(sl); + uint32_t flash_size; sl->chip_id = chip_id & 0xfff; /* Fix chip_id for F4 rev A errata , Read CPU ID, as CoreID is the same for F2/F4*/ @@ -457,23 +458,14 @@ int stlink_load_device_params(stlink_t *sl) { // These are fixed... sl->flash_base = STM32_FLASH_BASE; sl->sram_base = STM32_SRAM_BASE; + flash_size = stlink_read_debug32(sl,(params->flash_size_reg) & ~3); + if (params->flash_size_reg & 2) + flash_size = flash_size >>16; + flash_size = flash_size & 0xffff; - // read flash size from hardware, if possible... - if (sl->chip_id == STM32_CHIPID_F2) { - sl->flash_size = 0x100000; /* Use maximum, User must care!*/ - } else if (sl->chip_id == STM32_CHIPID_F4 || - sl->chip_id == STM32_CHIPID_F4_LP) { - sl->flash_size = 0x100000; //todo: RM0090 error; size register same address as unique ID - } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) { - // if the flash size is zero, we assume it is 128k, if not we calculate the real value - uint32_t flash_size = stlink_read_debug32(sl,params->flash_size_reg) & 0xffff; - if ( flash_size == 0 ) { + if ((sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) && ( flash_size == 0 )) { sl->flash_size = 128 * 1024; - } else { - sl->flash_size = flash_size * 1024; - } } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_L1_HIGH) { - uint32_t flash_size = stlink_read_debug32(sl, params->flash_size_reg) & 0x1; // 0 is 384k and 1 is 256k if ( flash_size == 0 ) { sl->flash_size = 384 * 1024; @@ -481,7 +473,6 @@ int stlink_load_device_params(stlink_t *sl) { sl->flash_size = 256 * 1024; } } else { - uint32_t flash_size = stlink_read_debug32(sl, params->flash_size_reg) & 0xffff; sl->flash_size = flash_size * 1024; } sl->flash_pgsz = params->flash_pagesize; diff --git a/src/stlink-common.h b/src/stlink-common.h index 0ac4f12e0..5d300941e 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -160,7 +160,7 @@ static const chip_params_t devices[] = { { // table 1, PM0059 .chip_id = STM32_CHIPID_F2, .description = "F2 device", - .flash_size_reg = 0, /* no flash size reg found in the docs! */ + .flash_size_reg = 0x1ff7a22, /* RM0033 sind Rev 4*/ .flash_pagesize = 0x20000, .sram_size = 0x20000, .bootrom_base = 0x1fff0000, @@ -178,7 +178,7 @@ static const chip_params_t devices[] = { { .chip_id = STM32_CHIPID_F4, .description = "F4 device", - .flash_size_reg = 0x1FFF7A10, //RM0090 error same as unique ID + .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ .flash_pagesize = 0x4000, .sram_size = 0x30000, .bootrom_base = 0x1fff0000, @@ -187,7 +187,7 @@ static const chip_params_t devices[] = { { .chip_id = STM32_CHIPID_F4_LP, .description = "F4 device (low power)", - .flash_size_reg = 0x1FFF7A10, + .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, .sram_size = 0x10000, .bootrom_base = 0x1fff0000, From e40741e8275d722ebda534525089853ae5369e86 Mon Sep 17 00:00:00 2001 From: texane Date: Mon, 14 Oct 2013 18:08:42 -0500 Subject: [PATCH 0234/1435] [ patch from Uwe Bonnes ] add STM32F42x and F43x-parts (bank handling not yet supported) --- src/stlink-common.c | 40 ++++++++++++++++++++-------------------- src/stlink-common.h | 10 ++++++++++ 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index a08da392c..b7645fe88 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -144,7 +144,7 @@ static inline uint32_t read_flash_obr(stlink_t *sl) { static inline uint32_t read_flash_cr(stlink_t *sl) { uint32_t res; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_LP)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) res = stlink_read_debug32(sl, FLASH_F4_CR); else res = stlink_read_debug32(sl, FLASH_CR); @@ -157,7 +157,7 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_LP)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK); else return read_flash_cr(sl) & (1 << FLASH_CR_LOCK); @@ -170,7 +170,7 @@ static void unlock_flash(stlink_t *sl) { the FPEC block until next reset. */ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_LP)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); } else { @@ -196,7 +196,7 @@ static int unlock_flash_if(stlink_t *sl) { static void lock_flash(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_LP)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); stlink_write_debug32(sl, FLASH_F4_CR, n); } else { @@ -209,7 +209,7 @@ static void lock_flash(stlink_t *sl) { static void set_flash_cr_pg(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_LP)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_CR_PG); stlink_write_debug32(sl, FLASH_F4_CR, x); @@ -222,7 +222,7 @@ static void set_flash_cr_pg(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_LP)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) stlink_write_debug32(sl, FLASH_F4_CR, n); else stlink_write_debug32(sl, FLASH_CR, n); @@ -240,7 +240,7 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { static void set_flash_cr_mer(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_LP)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); else @@ -250,7 +250,7 @@ static void set_flash_cr_mer(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_LP)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); else @@ -260,7 +260,7 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { static void set_flash_cr_strt(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_LP)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_F4_CR_STRT); stlink_write_debug32(sl, FLASH_F4_CR, x); @@ -277,7 +277,7 @@ static inline uint32_t read_flash_acr(stlink_t *sl) { static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_LP)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) res = stlink_read_debug32(sl, FLASH_F4_SR); else res = stlink_read_debug32(sl, FLASH_SR); @@ -287,7 +287,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { static inline unsigned int is_flash_busy(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_LP)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY); else return read_flash_sr(sl) & (1 << FLASH_SR_BSY); @@ -1014,7 +1014,7 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_LP)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector<4) sl->flash_pgsz=0x4000; else if(sector<5) sl->flash_pgsz=0x10000; @@ -1032,7 +1032,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_LP)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1346,8 +1346,8 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); - } else if (sl->chip_id == STM32_CHIPID_F2 || - sl->chip_id == STM32_CHIPID_F4 || sl->chip_id == STM32_CHIPID_F4_LP) { + } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || + sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD){ loader_code = loader_code_stm32f4; loader_size = sizeof(loader_code_stm32f4); } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F0_SMALL) { @@ -1516,7 +1516,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t page_count, sl->flash_pgsz, sl->flash_pgsz); if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_LP)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { /* todo: check write operation */ ILOG("Starting Flash write for F2/F4\n"); @@ -1802,8 +1802,8 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, 0, 3); /* flash bank 0 (input) */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - } else if (sl->chip_id == STM32_CHIPID_F2 || - sl->chip_id == STM32_CHIPID_F4 || sl->chip_id == STM32_CHIPID_F4_LP) { + } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || + sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1856,8 +1856,8 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - } else if (sl->chip_id == STM32_CHIPID_F2 || - sl->chip_id == STM32_CHIPID_F4 || sl->chip_id == STM32_CHIPID_F4_LP) { + } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || + sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { diff --git a/src/stlink-common.h b/src/stlink-common.h index 5d300941e..edf8c6733 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -103,6 +103,7 @@ extern "C" { #define STM32_CHIPID_F3 0x422 #define STM32_CHIPID_F37x 0x432 #define STM32_CHIPID_F4 0x413 +#define STM32_CHIPID_F4_HD 0x419 #define STM32_CHIPID_F4_LP 0x423 #define STM32_CHIPID_F1_HIGH 0x414 #define STM32_CHIPID_L1_MEDIUM 0x416 @@ -184,6 +185,15 @@ static const chip_params_t devices[] = { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 }, + { + .chip_id = STM32_CHIPID_F4_HD, + .description = "F42x and F43x device", + .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ + .flash_pagesize = 0x4000, + .sram_size = 0x30000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, { .chip_id = STM32_CHIPID_F4_LP, .description = "F4 device (low power)", From c2e22f961dd6ea3e44774131f781d6da230f313a Mon Sep 17 00:00:00 2001 From: Chris Hiszpanski Date: Wed, 23 Oct 2013 22:59:32 -0700 Subject: [PATCH 0235/1435] Fixes issue #161 --- flash/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flash/main.c b/flash/main.c index 980af63be..8f3a149ba 100644 --- a/flash/main.c +++ b/flash/main.c @@ -146,7 +146,7 @@ int main(int ac, char** av) } } else if ((o.addr >= sl->sram_base) && - (o.addr < sl->sram_base + sl->sram_size)) + (o.addr < sl->sram_base + sl->sram_size)) { err = stlink_fwrite_sram(sl, o.filename, o.addr); if (err == -1) { @@ -154,7 +154,7 @@ int main(int ac, char** av) goto on_error; } } - else if (o.cmd == DO_ERASE) + } else if (o.cmd == DO_ERASE) { err = stlink_erase_flash_mass(sl); if (err == -1) From 5851dee3cd95d7b0276caa22b9d2992c8b1147fa Mon Sep 17 00:00:00 2001 From: Olivier Gay Date: Sun, 27 Oct 2013 15:19:29 +0100 Subject: [PATCH 0236/1435] Fix build issues with MinGW Remove st-term from the list of the targets for MinGW. st-term uses termios and would require a rewrite to have it compile on MinGW. Also remove cleanup signal handlers in gdb-server for MinGW to compile. --- Makefile.am | 9 ++++++++- configure.ac | 4 ++++ gdbserver/gdb-server.c | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index ab3201f03..2ddbf475d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,11 @@ SUBDIRS = . $(MAYBE_GUI) AUTOMAKE_OPTIONS = subdir-objects +if MINGW +bin_PROGRAMS = st-flash st-util st-info +else bin_PROGRAMS = st-flash st-util st-term st-info +endif noinst_LIBRARIES = libstlink.a @@ -18,9 +22,12 @@ CFILES = \ src/stlink-usb.c \ src/stlink-sg.c \ src/uglylogging.c \ - src/st-term.c \ src/st-info.c +if !MINGW +CFILES += src/st-term.c +endif + HFILES = \ src/stlink-common.h \ src/stlink-usb.h \ diff --git a/configure.ac b/configure.ac index 53f827893..f1357b121 100644 --- a/configure.ac +++ b/configure.ac @@ -32,7 +32,11 @@ case "${host}" in *-mingw32*) LIBS="$LIBS -lws2_32" CPPFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CPPFLAGS" + AC_DEFINE_UNQUOTED(MINGW,1,[This is a MinGW system]) + AM_CONDITIONAL(MINGW, true) ;; + *) + AM_CONDITIONAL(MINGW, false) esac MAYBE_GUI= diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index bf1478122..a6de1b20d 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -57,6 +57,7 @@ typedef struct _st_state_t { int serve(stlink_t *sl, st_state_t *st); char* make_memory_map(stlink_t *sl); +#ifndef __MINGW32__ static void cleanup(int signal __attribute__((unused))) { if (connected_stlink) { /* Switch back to mass storage mode before closing. */ @@ -67,6 +68,7 @@ static void cleanup(int signal __attribute__((unused))) { exit(1); } +#endif @@ -196,8 +198,10 @@ int main(int argc, char** argv) { } connected_stlink = sl; +#ifndef __MINGW32__ signal(SIGINT, &cleanup); signal(SIGTERM, &cleanup); +#endif if (state.reset) { stlink_reset(sl); From c02a84641cb7da10e84af0093420dc1502313465 Mon Sep 17 00:00:00 2001 From: Olivier Gay Date: Sun, 27 Oct 2013 16:17:08 +0100 Subject: [PATCH 0237/1435] Restore gdb-server cleanup handlers for MinGW There were removed in my previous commit 5851dee due to compilation errors. It actually appears these signals are supported in MinGW but there was an include error for MinGW, this commit fixes it. --- gdbserver/gdb-server.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index a6de1b20d..69eadda49 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -18,7 +19,6 @@ #include #include #include -#include #endif #include @@ -57,7 +57,6 @@ typedef struct _st_state_t { int serve(stlink_t *sl, st_state_t *st); char* make_memory_map(stlink_t *sl); -#ifndef __MINGW32__ static void cleanup(int signal __attribute__((unused))) { if (connected_stlink) { /* Switch back to mass storage mode before closing. */ @@ -68,7 +67,6 @@ static void cleanup(int signal __attribute__((unused))) { exit(1); } -#endif @@ -198,10 +196,8 @@ int main(int argc, char** argv) { } connected_stlink = sl; -#ifndef __MINGW32__ signal(SIGINT, &cleanup); signal(SIGTERM, &cleanup); -#endif if (state.reset) { stlink_reset(sl); From 3652f98a5d6c8bbe4707c5764b10e5bb9a13c370 Mon Sep 17 00:00:00 2001 From: Olivier Gay Date: Sun, 27 Oct 2013 17:05:13 +0100 Subject: [PATCH 0238/1435] Fix all compilation warnings --- gdbserver/gdb-server.c | 2 +- src/st-term.c | 10 ++++++++-- src/stlink-common.h | 2 +- src/stlink-usb.c | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 69eadda49..7e8bb685a 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -172,7 +172,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { int main(int argc, char** argv) { - uint32_t voltage; + int32_t voltage; stlink_t *sl = NULL; diff --git a/src/st-term.c b/src/st-term.c index 346cca58f..bbf7ea37e 100644 --- a/src/st-term.c +++ b/src/st-term.c @@ -13,6 +13,11 @@ #define STLINKY_MAGIC 0xDEADF00D +#define READ_UINT32_LE(buf) ((uint32_t) ( buf[0] \ + | buf[1] << 8 \ + | buf[2] << 16 \ + | buf[3] << 24)) + struct stlinky { stlink_t *sl; uint32_t off; @@ -26,11 +31,11 @@ struct stlinky* stlinky_detect(stlink_t* sl) static const uint32_t sram_base = 0x20000000; struct stlinky* st = malloc(sizeof(struct stlinky)); st->sl = sl; - printf("sram: 0x%x bytes @ 0x%x\n", sl->sram_base, sl->sram_size); + printf("sram: 0x%x bytes @ 0x%zx\n", sl->sram_base, sl->sram_size); uint32_t off; for (off = 0; off < sl->sram_size; off += 4) { stlink_read_mem32(sl, sram_base + off, 4); - if ( STLINKY_MAGIC== *(uint32_t*) sl->q_buf) + if (STLINKY_MAGIC == READ_UINT32_LE(sl->q_buf)) { printf("stlinky detected at 0x%x\n", sram_base + off); st->off = sram_base + off; @@ -121,6 +126,7 @@ static int keep_running = 1; static int sigcount=0; void cleanup(int dummy) { + (void) dummy; sigcount++; keep_running = 0; printf("\n\nGot a signal\n"); diff --git a/src/stlink-common.h b/src/stlink-common.h index edf8c6733..579622892 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -397,7 +397,7 @@ static const chip_params_t devices[] = { void (*step) (stlink_t * stl); int (*current_mode) (stlink_t * stl); void (*force_debug) (stlink_t *sl); - uint32_t (*target_voltage) (stlink_t *sl); + int32_t (*target_voltage) (stlink_t *sl); } stlink_backend_t; struct _stlink { diff --git a/src/stlink-usb.c b/src/stlink-usb.c index fa2bd7e08..ec4053ac7 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -203,7 +203,7 @@ void _stlink_usb_version(stlink_t *sl) { } } -int _stlink_usb_target_voltage(stlink_t *sl) { +int32_t _stlink_usb_target_voltage(stlink_t *sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const rdata = sl->q_buf; unsigned char* const cmd = sl->c_buf; From c9ebf53474b1b1f0ca28d33982b2a01122698bfd Mon Sep 17 00:00:00 2001 From: Chris Dew Date: Mon, 28 Oct 2013 15:09:49 +0000 Subject: [PATCH 0239/1435] Added STM32F429I-DISCO --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index d717dc22a..cc0fb66ab 100644 --- a/README +++ b/README @@ -167,6 +167,7 @@ Known Working Targets: (https://github.com/UweBonnes/wiki_fuer_alex/layout/usps...) * STM32F303xx (STM32F3 Discovery board) * STM32F407xx (STM32F4 Discovery board) +* STM32F429I-DISCO (STM32F4 Discovery board with LCD) Please report any and all known working combinations so I can update this! From da7aebfdf6c90002c92a2f82384bb79e71b4907a Mon Sep 17 00:00:00 2001 From: texane Date: Tue, 29 Oct 2013 16:13:56 -0500 Subject: [PATCH 0240/1435] [ update ] README, STM32F439VIT6 working as reported by Pawel Kraszewski --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index cc0fb66ab..963ccd4a9 100644 --- a/README +++ b/README @@ -168,6 +168,7 @@ Known Working Targets: * STM32F303xx (STM32F3 Discovery board) * STM32F407xx (STM32F4 Discovery board) * STM32F429I-DISCO (STM32F4 Discovery board with LCD) +* STM32F439VIT6 (discovery board reseated CPU) Please report any and all known working combinations so I can update this! From fcdee3bc6dcc31a514ea60f256b92f99d35e225a Mon Sep 17 00:00:00 2001 From: Dan Hepler Date: Wed, 30 Oct 2013 13:14:09 -0700 Subject: [PATCH 0241/1435] Added known working targets STM32L151CB and STM32L152RB. --- README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README b/README index 963ccd4a9..01751a7cf 100644 --- a/README +++ b/README @@ -169,6 +169,8 @@ Known Working Targets: * STM32F407xx (STM32F4 Discovery board) * STM32F429I-DISCO (STM32F4 Discovery board with LCD) * STM32F439VIT6 (discovery board reseated CPU) +* STM32L151CB (custom board) +* STM32L152RB (STM32L-Discovery board, custom board) Please report any and all known working combinations so I can update this! From 99e8194f7f1b098aa301b66ad75e8c6a3a2b6804 Mon Sep 17 00:00:00 2001 From: Jim Paris Date: Thu, 31 Oct 2013 18:02:55 -0400 Subject: [PATCH 0242/1435] Add --reset option to trigger a reset both before and after flashing. --- flash/main.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/flash/main.c b/flash/main.c index 8f3a149ba..014b627e9 100644 --- a/flash/main.c +++ b/flash/main.c @@ -17,13 +17,14 @@ struct opts const char* filename; stm32_addr_t addr; size_t size; + int reset; }; static void usage(void) { - puts("stlinkv1 command line: ./flash {read|write} /dev/sgX path addr "); + puts("stlinkv1 command line: ./flash [--reset] {read|write} /dev/sgX path addr "); puts("stlinkv1 command line: ./flash /dev/sgX erase"); - puts("stlinkv2 command line: ./flash {read|write} path addr "); + puts("stlinkv2 command line: ./flash [--reset] {read|write} path addr "); puts("stlinkv2 command line: ./flash erase"); puts(" use hex format for addr and "); } @@ -37,6 +38,17 @@ static int get_opts(struct opts* o, int ac, char** av) if (ac < 1) return -1; + if (strcmp(av[0], "--reset") == 0) + { + o->reset = 1; + ac--; + av++; + } + else + { + o->reset = 0; + } + /* stlinkv2 */ o->devname = NULL; @@ -123,6 +135,9 @@ int main(int ac, char** av) if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); + if (o.reset) + stlink_reset(sl); + // Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 if (sl->chip_id == STM32_CHIPID_F4) { @@ -179,6 +194,9 @@ int main(int ac, char** av) } } + if (o.reset) + stlink_reset(sl); + /* success */ err = 0; From badeef227a1705d9ecb5521266b88065b8b59795 Mon Sep 17 00:00:00 2001 From: Onno Kortmann Date: Fri, 6 Dec 2013 20:30:01 -0800 Subject: [PATCH 0243/1435] Properly detect and warn if multiple stlinky magic bytes are detected Stlinky can silently fail if its magic bytes are present anywhere else in the SRAM. This change makes st-term detect all stlinky structures, warn about multiple occurences and will use the last one detected. --- src/st-term.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/st-term.c b/src/st-term.c index bbf7ea37e..a6a97fc1c 100644 --- a/src/st-term.c +++ b/src/st-term.c @@ -30,6 +30,7 @@ struct stlinky* stlinky_detect(stlink_t* sl) { static const uint32_t sram_base = 0x20000000; struct stlinky* st = malloc(sizeof(struct stlinky)); + int multiple=0; st->sl = sl; printf("sram: 0x%x bytes @ 0x%zx\n", sl->sram_base, sl->sram_size); uint32_t off; @@ -37,14 +38,22 @@ struct stlinky* stlinky_detect(stlink_t* sl) stlink_read_mem32(sl, sram_base + off, 4); if (STLINKY_MAGIC == READ_UINT32_LE(sl->q_buf)) { + if (multiple > 0) + printf("WARNING: another "); printf("stlinky detected at 0x%x\n", sram_base + off); st->off = sram_base + off; stlink_read_mem32(sl, st->off + 4, 4); st->bufsize = (size_t) *(unsigned char*) sl->q_buf; printf("stlinky buffer size 0x%zu \n", st->bufsize); - return st; + multiple++; } } + if (multiple > 0) { + if (multiple > 1) { + printf("Using last stlinky structure detected\n"); + } + return st; + } return NULL; } From 93c070d84c00bf3f6fa75d41ddacbdd0bb757f5a Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Wed, 11 Dec 2013 20:31:37 +0100 Subject: [PATCH 0244/1435] st-term magic byte via commandline argument --- .gitignore | 1 + src/st-term.c | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index d7df95e81..090257037 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ compile st-flash st-util st-term +st-info test_usb test_sg *.deps* diff --git a/src/st-term.c b/src/st-term.c index a6a97fc1c..4f2f9f77c 100644 --- a/src/st-term.c +++ b/src/st-term.c @@ -39,7 +39,7 @@ struct stlinky* stlinky_detect(stlink_t* sl) if (STLINKY_MAGIC == READ_UINT32_LE(sl->q_buf)) { if (multiple > 0) - printf("WARNING: another "); + printf("WARNING: another "); printf("stlinky detected at 0x%x\n", sram_base + off); st->off = sram_base + off; stlink_read_mem32(sl, st->off + 4, 4); @@ -148,10 +148,8 @@ void cleanup(int dummy) int main(int ac, char** av) { stlink_t* sl; - - /* unused */ - ac = ac; - av = av; + struct stlinky *st; + sl = stlink_open_usb(10, 1); if (sl != NULL) { printf("ST-Linky proof-of-concept terminal :: Created by Necromant for lulz\n"); @@ -174,7 +172,19 @@ int main(int ac, char** av) { /* TODO: Make timeout adjustable via command line */ sleep(1); - struct stlinky *st = stlinky_detect(sl); + if(ac == 1){ + st = stlinky_detect(sl); + }else if(ac == 2){ + st = malloc(sizeof(struct stlinky)); + st->sl = sl; + st->off = (int)strtol(av[1], NULL, 16); + printf("using stlinky at 0x%x\n", st->off); + stlink_read_mem32(sl, st->off + 4, 4); + st->bufsize = (size_t) *(unsigned char*) sl->q_buf; + printf("stlinky buffer size 0x%zu \n", st->bufsize); + }else{ + goto bailout; + } if (st == NULL) { printf("stlinky magic not found in sram :(\n"); From 9bb1a0c3d73f400cb4874a6bd17bf4b03b88bd74 Mon Sep 17 00:00:00 2001 From: texane Date: Wed, 11 Dec 2013 22:48:40 -0600 Subject: [PATCH 0245/1435] [ fix ] ident typo --- src/st-term.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/st-term.c b/src/st-term.c index 4f2f9f77c..7f18425db 100644 --- a/src/st-term.c +++ b/src/st-term.c @@ -38,8 +38,7 @@ struct stlinky* stlinky_detect(stlink_t* sl) stlink_read_mem32(sl, sram_base + off, 4); if (STLINKY_MAGIC == READ_UINT32_LE(sl->q_buf)) { - if (multiple > 0) - printf("WARNING: another "); + if (multiple > 0) printf("WARNING: another "); printf("stlinky detected at 0x%x\n", sram_base + off); st->off = sram_base + off; stlink_read_mem32(sl, st->off + 4, 4); From 3c6d6293dd7a5d2ca70f441582b1042834dc7d66 Mon Sep 17 00:00:00 2001 From: Jan Sarenik Date: Wed, 18 Dec 2013 09:24:51 +0100 Subject: [PATCH 0246/1435] stlinkv1_macosx_driver: add Mavericks The diff was as easy as adding a new select option for 10.9 version in install.sh, and a little patch fixing com.apple.kpi.libkern version string. Don't forget to install latest libusb, i.e. libusbx in homebrew! --- stlinkv1_macosx_driver/osx.tar.gz | Bin 23437 -> 22405 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/stlinkv1_macosx_driver/osx.tar.gz b/stlinkv1_macosx_driver/osx.tar.gz index a4af6670bd8f9521f359104e1911fc91c57ad871..51a7a3248574e128d4a38b4624e7b26be8fa4a23 100644 GIT binary patch literal 22405 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

~qEFlG{Xb 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 d_krS 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 Date: Thu, 19 Dec 2013 23:43:11 +0400 Subject: [PATCH 0247/1435] Process SIGINT and SIGTERM only in safe places --- src/st-term.c | 67 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/src/st-term.c b/src/st-term.c index 7f18425db..241518e7a 100644 --- a/src/st-term.c +++ b/src/st-term.c @@ -18,12 +18,48 @@ | buf[2] << 16 \ | buf[3] << 24)) +static stlink_t* sl; +sigset_t sig_mask; + struct stlinky { stlink_t *sl; uint32_t off; size_t bufsize; }; +void nonblock(int state); + +static void cleanup(int signal __attribute__((unused))) { + if (sl) { + /* Switch back to mass storage mode before closing. */ + stlink_run(sl); + stlink_exit_debug_mode(sl); + stlink_close(sl); + } + + printf("\n"); + nonblock(0); + exit(1); +} + +void sig_init() { + sigemptyset(&sig_mask); + sigaddset(&sig_mask, SIGINT); + sigaddset(&sig_mask, SIGTERM); + signal(SIGINT, &cleanup); + signal(SIGTERM, &cleanup); + sigprocmask(SIG_BLOCK, &sig_mask, NULL); +} + +void sig_process() { + sigset_t pending; + sigpending(&pending); + if (sigismember(&pending, SIGINT) || sigismember(&pending, SIGTERM)) { + sigprocmask(SIG_UNBLOCK, &sig_mask, NULL); + sigsuspend(&pending); + sigprocmask(SIG_BLOCK, &sig_mask, NULL); + } +} /* Detects stlinky in RAM, returns handler */ struct stlinky* stlinky_detect(stlink_t* sl) @@ -35,6 +71,7 @@ struct stlinky* stlinky_detect(stlink_t* sl) printf("sram: 0x%x bytes @ 0x%zx\n", sl->sram_base, sl->sram_size); uint32_t off; for (off = 0; off < sl->sram_size; off += 4) { + if (off % 1024 == 0) sig_process(); stlink_read_mem32(sl, sram_base + off, 4); if (STLINKY_MAGIC == READ_UINT32_LE(sl->q_buf)) { @@ -130,25 +167,11 @@ void nonblock(int state) } -static int keep_running = 1; -static int sigcount=0; -void cleanup(int dummy) -{ - (void) dummy; - sigcount++; - keep_running = 0; - printf("\n\nGot a signal\n"); - if (sigcount==2) { - printf("\n\nGot a second signal - bailing out\n"); - exit(1); - } -} - - int main(int ac, char** av) { - stlink_t* sl; struct stlinky *st; + sig_init(); + sl = stlink_open_usb(10, 1); if (sl != NULL) { printf("ST-Linky proof-of-concept terminal :: Created by Necromant for lulz\n"); @@ -182,12 +205,12 @@ int main(int ac, char** av) { st->bufsize = (size_t) *(unsigned char*) sl->q_buf; printf("stlinky buffer size 0x%zu \n", st->bufsize); }else{ - goto bailout; + cleanup(0); } if (st == NULL) { printf("stlinky magic not found in sram :(\n"); - goto bailout; + cleanup(0); } char* rxbuf = malloc(st->bufsize); char* txbuf = malloc(st->bufsize); @@ -196,9 +219,9 @@ int main(int ac, char** av) { int fd = fileno(stdin); int saved_flags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, saved_flags & ~O_NONBLOCK); - signal(SIGINT, cleanup); printf("Entering interactive terminal. CTRL+C to exit\n\n\n"); while(1) { + sig_process(); if (stlinky_canrx(st)) { tmp = stlinky_rx(st, rxbuf); fwrite(rxbuf,tmp,1,stdout); @@ -208,13 +231,7 @@ int main(int ac, char** av) { tmp = read(fd, txbuf, st->bufsize); stlinky_tx(st,txbuf,tmp); } - if (!keep_running) - break; } - bailout: - nonblock(0); - stlink_exit_debug_mode(sl); - stlink_close(sl); } return 0; } From 2e6ba2093588536214edd0da0cf09eaa9a9da014 Mon Sep 17 00:00:00 2001 From: Jonas Norling Date: Wed, 22 Jan 2014 21:48:35 +0100 Subject: [PATCH 0248/1435] Correct address for STM32F2 flash size register There was a typo in the flash size register address for STM32F2. Change to correct address. Verified against STM32F207 reference manual (RM0033 Rev 5 section 33.2), and an STM32F217 chip. --- src/stlink-common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.h b/src/stlink-common.h index 579622892..ee16d5a63 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -161,7 +161,7 @@ static const chip_params_t devices[] = { { // table 1, PM0059 .chip_id = STM32_CHIPID_F2, .description = "F2 device", - .flash_size_reg = 0x1ff7a22, /* RM0033 sind Rev 4*/ + .flash_size_reg = 0x1fff7a22, /* As in RM0033 Rev 5*/ .flash_pagesize = 0x20000, .sram_size = 0x20000, .bootrom_base = 0x1fff0000, From a4ff7ba1f4c81a3bfbf4eb284233f65b713d502b Mon Sep 17 00:00:00 2001 From: Jonas Norling Date: Wed, 22 Jan 2014 22:10:52 +0100 Subject: [PATCH 0249/1435] Remove unsupported --device option to st-util Setting the STLINK device with -d hasn't worked for some time, but the STLINK_DEVICE environment variable works instead. Remove the option, update documentation and help text. --- README | 20 ++++++++++++++------ gdbserver/gdb-server.c | 24 ++++++++---------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/README b/README index 01751a7cf..853c51826 100644 --- a/README +++ b/README @@ -55,14 +55,22 @@ There are a few options: ./st-util - usage: - -h, --help Print this help - -vXX, --verbose=XX specify a specific verbosity level (0..99) - -v, --verbose specify generally verbose logging + -h, --help Print this help + -vXX, --verbose=XX Specify a specific verbosity level (0..99) + -v, --verbose Specify generally verbose logging -s X, --stlink_version=X - Choose what version of stlink to use, (defaults to 2) - -1, --stlinkv1 Force stlink version 1 + Choose what version of stlink to use, (defaults to 2) + -1, --stlinkv1 Force stlink version 1 -p 4242, --listen_port=1234 - Set the gdb server listen port. (default port: 4242) + Set the gdb server listen port. (default port: 4242) + -m, --multi + Set gdb server to extended mode. + st-util will continue listening for connections after disconnect. + -n, --no-reset + Do not reset board on connection. + +The STLINKv2 device to use can be specified in the environment +variable STLINK_DEVICE on the format :. Then, in your project directory, someting like this... (remember, you need to run an _ARM_ gdb, not an x86 gdb) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 7e8bb685a..13902ee03 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -45,10 +45,8 @@ static const char* current_memory_map = NULL; typedef struct _st_state_t { // things from command line, bleh int stlink_version; - // "/dev/serial/by-id/usb-FTDI_TTL232R-3V3_FTE531X6-if00-port0" is only 58 chars - char devicename[100]; int logging_level; - int listen_port; + int listen_port; int persistent; int reset; } st_state_t; @@ -74,7 +72,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"verbose", optional_argument, NULL, 'v'}, - {"device", required_argument, NULL, 'd'}, {"stlink_version", required_argument, NULL, 's'}, {"stlinkv1", no_argument, NULL, '1'}, {"listen_port", required_argument, NULL, 'p'}, @@ -84,10 +81,8 @@ int parse_options(int argc, char** argv, st_state_t *st) { }; const char * help_str = "%s - usage:\n\n" " -h, --help\t\tPrint this help\n" - " -vXX, --verbose=XX\tspecify a specific verbosity level (0..99)\n" - " -v, --verbose\tspecify generally verbose logging\n" - " -d , --device=/dev/stlink2_1\n" - "\t\t\tWhere is your stlink device connected?\n" + " -vXX, --verbose=XX\tSpecify a specific verbosity level (0..99)\n" + " -v, --verbose\t\tSpecify generally verbose logging\n" " -s X, --stlink_version=X\n" "\t\t\tChoose what version of stlink to use, (defaults to 2)\n" " -1, --stlinkv1\tForce stlink version 1\n" @@ -99,13 +94,17 @@ int parse_options(int argc, char** argv, st_state_t *st) { "\t\t\tst-util will continue listening for connections after disconnect.\n" " -n, --no-reset\n" "\t\t\tDo not reset board on connection.\n" + "\n" + "The STLINKv2 device to use can be specified in the environment\n" + "variable STLINK_DEVICE on the format :.\n" + "\n" ; int option_index = 0; int c; int q; - while ((c = getopt_long(argc, argv, "hv::d:s:1p:mn", long_options, &option_index)) != -1) { + while ((c = getopt_long(argc, argv, "hv::s:1p:mn", long_options, &option_index)) != -1) { switch (c) { case 0: printf("XXXXX Shouldn't really normally come here, only if there's no corresponding option\n"); @@ -125,13 +124,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { } else { st->logging_level = DEFAULT_LOGGING_LEVEL; } - break; - case 'd': - if (strlen(optarg) > sizeof (st->devicename)) { - fprintf(stderr, "device name too long: %zd\n", strlen(optarg)); - } else { - strcpy(st->devicename, optarg); - } break; case '1': st->stlink_version = 1; From cd9dbe4b061902a15413c4f3d14ea0a4e90f9510 Mon Sep 17 00:00:00 2001 From: texane Date: Sat, 25 Jan 2014 08:07:57 -0600 Subject: [PATCH 0250/1435] [ add ] INSTALL.mingw using dandev37 comments --- INSTALL.mingw | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 INSTALL.mingw diff --git a/INSTALL.mingw b/INSTALL.mingw new file mode 100644 index 000000000..5cd8cca11 --- /dev/null +++ b/INSTALL.mingw @@ -0,0 +1,41 @@ +from dandev37: + +Here's a step by step from a clean install to successfully setup MinGW and build +libusb-1.0 and stlink for MS Windows. Hopefully this helps someone. + +1. Install MinGW and MSYS to C:\MinGW with the graphical installer from +http://sourceforge.net/projects/mingw/files/Installer/mingw-get-setup.exe/download +and add these packages: +mingw32-base +mingw-developer-toolkit + +2. Add C:\MinGW\bin to your path. + +3. Create the C:\MinGW\msys\1.0\etc\fstab file to mount C:\MinGW as /mingw as per +http://www.mingw.org/wiki/MSYS: + +#Win32_Path Mount_Point +c:/mingw /mingw + +4. Download these three glib, pkg-config, pkg-config-dev archives and extract +contents to C:\MinGW +http://win32builder.gnome.org/packages/3.6/glib_2.34.3-1_win32.zip +http://win32builder.gnome.org/packages/3.6/pkg-config_0.28-1_win32.zip +http://win32builder.gnome.org/packages/3.6/pkg-config-dev_0.28-1_win32.zip + +5. Download latest libusb-1.0 source from git://git.libusb.org/libusb.git and +build (prefix as per http://www.mingw.org/wiki/MSYS) + +./autogen.sh +./configure --prefix=/mingw +make +make install + +6. Repeat for stlink source from https://github.com/texane/stlink + +./autogen.sh +./configure --prefix=/mingw +make +make install + +7. Enjoy the fruits of the stlink developers. From bc49ed608e0fdfde92dbfd0b462456c8269f2faa Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 26 Jan 2014 11:39:59 -0600 Subject: [PATCH 0251/1435] [ update ] INSTALL.mingw using Vanya comments --- INSTALL.mingw | 1 + 1 file changed, 1 insertion(+) diff --git a/INSTALL.mingw b/INSTALL.mingw index 5cd8cca11..56220101e 100644 --- a/INSTALL.mingw +++ b/INSTALL.mingw @@ -10,6 +10,7 @@ mingw32-base mingw-developer-toolkit 2. Add C:\MinGW\bin to your path. +Note: a user reports she had to use c:\MinGW\msys\1.0\bin 3. Create the C:\MinGW\msys\1.0\etc\fstab file to mount C:\MinGW as /mingw as per http://www.mingw.org/wiki/MSYS: From 5dcd45d8a48aaead2a2d1d1b9c36ab14f507628b Mon Sep 17 00:00:00 2001 From: Jim Paris Date: Fri, 31 Jan 2014 16:26:35 -0500 Subject: [PATCH 0252/1435] When ignoring the end of a file, make sure we don't ignore partial words. Consider a 128-byte write to the chip. If the last 2 bytes are considered "empty", then len is adjusted to 126, and run_flash_loader will only copy 126 bytes to RAM. However, run_flash_loader then proceeds to round up to 32 words (128 bytes) when flashing, which has the effect of clobbering those last two "empty" bytes with junk data. --- src/stlink-common.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index b7645fe88..b942dea06 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1752,8 +1752,10 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { else num_empty = 0; } + /* Round down to words */ + num_empty -= (num_empty & 3); if(num_empty != 0) { - ILOG("Ignoring %d bytes of Zeros at end of file\n",num_empty); + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); mf.len -= num_empty; } err = stlink_write_flash(sl, addr, mf.base, mf.len); From fdcb50e0de9eedd99d7f1c501f7c0d8d9c32f876 Mon Sep 17 00:00:00 2001 From: Jens Hoffmann Date: Thu, 20 Feb 2014 13:28:04 +0100 Subject: [PATCH 0253/1435] 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 000000000..a5a79b91c --- /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 ee16d5a63..400560408 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 ec4053ac7..fe841833d 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 From 83e9f70dd83d2f14f7297f1968724edc778589e5 Mon Sep 17 00:00:00 2001 From: Jens Hoffmann Date: Fri, 21 Feb 2014 15:12:16 +0100 Subject: [PATCH 0254/1435] Added STM32F401RE chip id. Nucleo F401RE board got 512K flash and 96K sram. This commit adds device definition for this controller. --- src/stlink-common.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/stlink-common.h b/src/stlink-common.h index 400560408..8430fc55d 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -106,6 +106,7 @@ extern "C" { #define STM32_CHIPID_F4 0x413 #define STM32_CHIPID_F4_HD 0x419 #define STM32_CHIPID_F4_LP 0x423 +#define STM32_CHIPID_F4_DE 0x433 #define STM32_CHIPID_F1_HIGH 0x414 #define STM32_CHIPID_L1_MEDIUM 0x416 #define STM32_CHIPID_L1_MEDIUM_PLUS 0x427 @@ -204,6 +205,15 @@ static const chip_params_t devices[] = { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 }, + { + .chip_id = STM32_CHIPID_F4_DE, + .description = "F4 device (Dynamic Efficency)", + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x18000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, { .chip_id = STM32_CHIPID_F1_HIGH, .description = "F1 High-density device", From 746d0201a7f753b20078b1e6d293b81d3b7d0822 Mon Sep 17 00:00:00 2001 From: dandev37 Date: Fri, 28 Feb 2014 12:23:51 -0800 Subject: [PATCH 0255/1435] Update MinGW instructions for USB 3.0 hub support. Report libusb_open() error code to the user. --- INSTALL.mingw | 6 ++++-- src/stlink-usb.c | 35 ++++++++++++++++++----------------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/INSTALL.mingw b/INSTALL.mingw index 56220101e..c8df0fd70 100644 --- a/INSTALL.mingw +++ b/INSTALL.mingw @@ -24,8 +24,10 @@ http://win32builder.gnome.org/packages/3.6/glib_2.34.3-1_win32.zip http://win32builder.gnome.org/packages/3.6/pkg-config_0.28-1_win32.zip http://win32builder.gnome.org/packages/3.6/pkg-config-dev_0.28-1_win32.zip -5. Download latest libusb-1.0 source from git://git.libusb.org/libusb.git and -build (prefix as per http://www.mingw.org/wiki/MSYS) +5. Download latest libusb-1.0 source from +https://github.com/libusb/libusb (newer repo, includes USB 3.0 hub support) +OR the old git://git.libusb.org/libusb.git (original repo, NO USB 3.0 support) +and build (prefix as per http://www.mingw.org/wiki/MSYS) ./autogen.sh ./configure --prefix=/mingw diff --git a/src/stlink-usb.c b/src/stlink-usb.c index fe841833d..8e910bcf2 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -150,7 +150,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, (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 */ + /* The STLink doesn't seem to evaluate the sequence number */ handle->sg_transfer_idx++; if (res ) return -1; } @@ -766,18 +766,18 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { char *device = getenv("STLINK_DEVICE"); if (device) { - char *c = strchr(device,':'); - if (c==NULL) { - WLOG("STLINK_DEVICE must be : format\n"); - goto on_error; - } - devBus=atoi(device); - *c++=0; - devAddr=atoi(c); - ILOG("bus %03d dev %03d\n",devBus, devAddr); + char *c = strchr(device,':'); + if (c==NULL) { + WLOG("STLINK_DEVICE must be : format\n"); + goto on_error; + } + devBus=atoi(device); + *c++=0; + devAddr=atoi(c); + ILOG("bus %03d dev %03d\n",devBus, devAddr); } while (cnt){ - cnt--; + cnt--; libusb_get_device_descriptor( list[cnt], &desc ); if (desc.idVendor!=USB_ST_VID) continue; if (devBus && devAddr) @@ -790,13 +790,14 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { } if (cnt < 0) { - WLOG ("Couldn't find %s ST-Link/V2 devices\n",(devBus && devAddr)?"matched":"any"); - goto on_error; + WLOG ("Couldn't find %s ST-Link/V2 devices\n",(devBus && devAddr)?"matched":"any"); + goto on_error; } else { - if( libusb_open(list[cnt], &slu->usb_handle) !=0){ - WLOG("Couldn't open ST-Link/V2 device %03d:%03d\n",libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); - goto on_error; - } + int error = libusb_open(list[cnt], &slu->usb_handle); + if( error !=0 ) { + WLOG("Error %d opening ST-Link/V2 device %03d:%03d\n", error, libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); + goto on_error; + } } libusb_free_device_list(list, 1); From 71d0958873abc358aff8e4874b0d2e2f8e083040 Mon Sep 17 00:00:00 2001 From: tekaikko Date: Wed, 5 Mar 2014 15:19:49 +0100 Subject: [PATCH 0256/1435] Update stlink-common.h Adding support for STM32F07x CAN connectivity devices --- src/stlink-common.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/stlink-common.h b/src/stlink-common.h index 8430fc55d..b70ba9e15 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -123,6 +123,7 @@ extern "C" { #define STM32_CHIPID_F1_XL 0x430 #define STM32_CHIPID_F0 0x440 #define STM32_CHIPID_F0_SMALL 0x444 +#define STM32_CHIPID_F0_CAN 0x448 // Constant STM32 memory map figures #define STM32_FLASH_BASE 0x08000000 @@ -311,6 +312,17 @@ static const chip_params_t devices[] = { .bootrom_base = 0x1fffe000, .bootrom_size = 0x1800 }, + { + //Use this as an example for mapping future chips: + //RM0091 document was used to find these paramaters + .chip_id = STM32_CHIPID_F0_CAN, + .description = "F07x device", + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 + .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 + .bootrom_size = 0x3000 // "System memory" byte size in hex from Table 2 + }, { //Use this as an example for mapping future chips: //RM0091 document was used to find these paramaters From 2121354caf99360d90f59961f3bea168dd144cce Mon Sep 17 00:00:00 2001 From: tekaikko Date: Wed, 5 Mar 2014 15:21:03 +0100 Subject: [PATCH 0257/1435] Update stlink-common.c Adding support for STM32F07x CAN connectivity devices --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index b942dea06..c7cc24a6c 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1350,7 +1350,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD){ loader_code = loader_code_stm32f4; loader_size = sizeof(loader_code_stm32f4); - } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F0_SMALL) { + } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); } else { From 0b88c379c32e8b1567c1afbfdf102e7265fa5813 Mon Sep 17 00:00:00 2001 From: tekaikko Date: Wed, 5 Mar 2014 15:22:34 +0100 Subject: [PATCH 0258/1435] Update stlink-common.c fix typo --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index c7cc24a6c..bf9f389f8 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1350,7 +1350,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD){ loader_code = loader_code_stm32f4; loader_size = sizeof(loader_code_stm32f4); - } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL) { + } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); } else { From 94c7ac86dcb2a18ab4b2b60309892f6102a53205 Mon Sep 17 00:00:00 2001 From: Sean Simmons Date: Sat, 8 Mar 2014 11:21:16 -0500 Subject: [PATCH 0259/1435] * Improved support for STM32L152RE - flash/ram sizes, now correct, flash programming works. * Cleaned up checking of FP_CTRL register in gdb-server.c * Added source code for stm32lx.s flashloader - just for reference. --- flashloaders/stm32lx.s | 63 ++++++++++++++++++++++++++++++++++++++++++ gdbserver/gdb-server.c | 11 ++++++-- src/st-term.c | 2 +- src/stlink-common.c | 16 +++++------ src/stlink-common.h | 11 +++++++- 5 files changed, 91 insertions(+), 12 deletions(-) create mode 100644 flashloaders/stm32lx.s diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s new file mode 100644 index 000000000..6e8ccb089 --- /dev/null +++ b/flashloaders/stm32lx.s @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2010 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * Copyright (C) 2011 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * + * Copyright (C) 2011 Clement Burin des Roziers * + * clement.burin-des-roziers@hikob.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +// Build : arm-eabi-gcc -c stm32lx.S + .text + .syntax unified + .cpu cortex-m3 + .thumb + .thumb_func + .global write + +/* + r0 - destination address + r1 - source address + r2 - count +*/ + + // Set 0 to r3 + movs r3, #0 + // Go to compare + b.n test_done + +write_word: + // Load one word from address in r0, increment by 4 + ldr.w ip, [r1], #4 + // Store the word to address in r1, increment by 4 + str.w ip, [r0], #4 + // Increment r3 + adds r3, #1 + +test_done: + // Compare r3 and r2 + cmp r3, r2 + // Loop if not zero + bcc.n write_word + + // Set breakpoint to exit + bkpt #0x00 + diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 13902ee03..459d1012b 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -472,6 +472,7 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) } #define CODE_BREAK_NUM 6 +#define CODE_LIT_NUM 2 #define CODE_BREAK_LOW 0x01 #define CODE_BREAK_HIGH 0x02 @@ -485,8 +486,14 @@ struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM]; static void init_code_breakpoints(stlink_t *sl) { memset(sl->q_buf, 0, 4); stlink_write_debug32(sl, CM3_REG_FP_CTRL, 0x03 /*KEY | ENABLE4*/); - printf("KARL - should read back as 0x03, not 60 02 00 00\n"); - stlink_read_debug32(sl, CM3_REG_FP_CTRL); + unsigned int val = stlink_read_debug32(sl, CM3_REG_FP_CTRL); + if (((val & 3) != 1) || + ((((val >> 8) & 0x70) | ((val >> 4) & 0xf)) != CODE_BREAK_NUM) || + (((val >> 8) & 0xf) != CODE_LIT_NUM)){ + fprintf(stderr, "[FP_CTRL] = 0x%08x expecting 0x%08x\n", val, + ((CODE_BREAK_NUM & 0x70) << 8) | (CODE_LIT_NUM << 8) | ((CODE_BREAK_NUM & 0xf) << 4) | 1); + } + for(int i = 0; i < CODE_BREAK_NUM; i++) { code_breaks[i].type = 0; diff --git a/src/st-term.c b/src/st-term.c index 241518e7a..6881f6218 100644 --- a/src/st-term.c +++ b/src/st-term.c @@ -168,7 +168,7 @@ void nonblock(int state) } int main(int ac, char** av) { - struct stlinky *st; + struct stlinky *st=NULL; sig_init(); diff --git a/src/stlink-common.c b/src/stlink-common.c index bf9f389f8..86eca084f 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -931,7 +931,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) size_t off; int num_empty = 0; unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH) ? 0:0xff; + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) ? 0:0xff; const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); if (fd == -1) { @@ -1059,7 +1059,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); #endif } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { uint32_t val; @@ -1169,7 +1169,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) int stlink_erase_flash_mass(stlink_t *sl) { if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { /* erase each page */ int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -1340,7 +1340,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { size_t loader_size; if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH ) { /* stm32l */ + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { @@ -1583,7 +1583,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } //STM32F4END else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH ) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { /* use fast word write. todo: half page. */ uint32_t val; @@ -1740,7 +1740,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { int err; unsigned int num_empty = 0, index; unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH )?0:0xff; + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE )?0:0xff; mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { ELOG("map_file() == -1\n"); @@ -1781,7 +1781,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH ) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1839,7 +1839,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons /* check written byte count */ if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH ) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; diff --git a/src/stlink-common.h b/src/stlink-common.h index b70ba9e15..cce4d9f3e 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -117,6 +117,7 @@ extern "C" { * 0x436 HIGH. */ #define STM32_CHIPID_L1_HIGH 0x436 +#define STM32_CHIPID_L152_RE 0x437 #define STM32_CHIPID_F1_CONN 0x418 #define STM32_CHIPID_F1_VL_MEDIUM 0x420 #define STM32_CHIPID_F1_VL_HIGH 0x428 @@ -253,7 +254,15 @@ static const chip_params_t devices[] = { .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000 }, - + { + .chip_id = STM32_CHIPID_L152_RE, + .description = "L152RE", + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0x14000, /*Not completely clear if there are some with 32K*/ + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, { .chip_id = STM32_CHIPID_F1_CONN, .description = "F1 Connectivity line device", From 9b1c00452a251fe516dd0248fbdf05990d217710 Mon Sep 17 00:00:00 2001 From: Pete Date: Mon, 10 Mar 2014 14:32:09 -0400 Subject: [PATCH 0260/1435] Fix segv if only --reset option given We didn't recheck that there are enough parameters after shifting the --reset option off the list. --- flash/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flash/main.c b/flash/main.c index 014b627e9..d550eeeed 100644 --- a/flash/main.c +++ b/flash/main.c @@ -48,6 +48,8 @@ static int get_opts(struct opts* o, int ac, char** av) { o->reset = 0; } + + if (ac < 1) return -1; /* stlinkv2 */ o->devname = NULL; From 4531918c9706cbe4a9eadeb3112a0136e21db0c7 Mon Sep 17 00:00:00 2001 From: texane Date: Thu, 13 Mar 2014 07:28:40 -0500 Subject: [PATCH 0261/1435] [ update ] flash support for the STM32F401XX (installed on the nucleo F4 boards) --- src/stlink-common.c | 50 ++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 86eca084f..0d11a63eb 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -143,7 +143,7 @@ static inline uint32_t read_flash_obr(stlink_t *sl) { static inline uint32_t read_flash_cr(stlink_t *sl) { uint32_t res; - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||(sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) res = stlink_read_debug32(sl, FLASH_F4_CR); else @@ -156,7 +156,7 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK); else @@ -169,7 +169,7 @@ static void unlock_flash(stlink_t *sl) { an invalid sequence results in a definitive lock of the FPEC block until next reset. */ - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); @@ -195,7 +195,7 @@ static int unlock_flash_if(stlink_t *sl) { } static void lock_flash(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); stlink_write_debug32(sl, FLASH_F4_CR, n); @@ -208,7 +208,7 @@ static void lock_flash(stlink_t *sl) { static void set_flash_cr_pg(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_CR_PG); @@ -221,7 +221,7 @@ static void set_flash_cr_pg(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) stlink_write_debug32(sl, FLASH_F4_CR, n); else @@ -239,7 +239,7 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { } static void set_flash_cr_mer(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); @@ -249,7 +249,7 @@ static void set_flash_cr_mer(stlink_t *sl) { } static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); @@ -259,7 +259,7 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { } static void set_flash_cr_strt(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_F4_CR_STRT); @@ -276,7 +276,7 @@ static inline uint32_t read_flash_acr(stlink_t *sl) { static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res; - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) res = stlink_read_debug32(sl, FLASH_F4_SR); else @@ -286,7 +286,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { } static inline unsigned int is_flash_busy(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY); else @@ -931,7 +931,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) size_t off; int num_empty = 0; unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) ? 0:0xff; + || sl->chip_id == STM32_CHIPID_L1_HIGH) ? 0:0xff; const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); if (fd == -1) { @@ -1013,7 +1013,7 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector<4) sl->flash_pgsz=0x4000; @@ -1031,7 +1031,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1059,7 +1059,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); #endif } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { + || sl->chip_id == STM32_CHIPID_L1_HIGH) { uint32_t val; @@ -1169,7 +1169,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) int stlink_erase_flash_mass(stlink_t *sl) { if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { + || sl->chip_id == STM32_CHIPID_L1_HIGH) { /* erase each page */ int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -1340,13 +1340,13 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { size_t loader_size; if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { /* stm32l */ + || sl->chip_id == STM32_CHIPID_L1_HIGH ) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); - } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || + } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD){ loader_code = loader_code_stm32f4; loader_size = sizeof(loader_code_stm32f4); @@ -1515,7 +1515,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t ILOG("Finished erasing %d pages of %d (%#x) bytes\n", page_count, sl->flash_pgsz, sl->flash_pgsz); - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { /* todo: check write operation */ @@ -1583,7 +1583,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } //STM32F4END else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { + || sl->chip_id == STM32_CHIPID_L1_HIGH ) { /* use fast word write. todo: half page. */ uint32_t val; @@ -1740,7 +1740,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { int err; unsigned int num_empty = 0, index; unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE )?0:0xff; + || sl->chip_id == STM32_CHIPID_L1_HIGH )?0:0xff; mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { ELOG("map_file() == -1\n"); @@ -1781,7 +1781,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { + || sl->chip_id == STM32_CHIPID_L1_HIGH ) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1804,7 +1804,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, 0, 3); /* flash bank 0 (input) */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || + } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD) { size_t count = size / sizeof(uint32_t); @@ -1839,7 +1839,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons /* check written byte count */ if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { + || sl->chip_id == STM32_CHIPID_L1_HIGH ) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1858,7 +1858,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || + } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD) { stlink_read_reg(sl, 2, &rr); From 5e9b096c9c6755449d729e5b7c3d95b4ae5eb27d Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 16 Mar 2014 14:36:52 -0500 Subject: [PATCH 0262/1435] [ fix ] fix STM32L152RE broken by previous commit --- src/stlink-common.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 0d11a63eb..545434b4e 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -931,7 +931,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) size_t off; int num_empty = 0; unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH) ? 0:0xff; + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) ? 0:0xff; const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); if (fd == -1) { @@ -1059,7 +1059,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); #endif } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { uint32_t val; @@ -1169,7 +1169,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) int stlink_erase_flash_mass(stlink_t *sl) { if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { /* erase each page */ int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -1340,7 +1340,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { size_t loader_size; if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH ) { /* stm32l */ + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { @@ -1583,7 +1583,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } //STM32F4END else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH ) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { /* use fast word write. todo: half page. */ uint32_t val; @@ -1740,7 +1740,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { int err; unsigned int num_empty = 0, index; unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH )?0:0xff; + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE )?0:0xff; mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { ELOG("map_file() == -1\n"); @@ -1781,7 +1781,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH ) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1839,7 +1839,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons /* check written byte count */ if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH ) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; From 75be8af5477810871bdc2d03dff1f00d33309b11 Mon Sep 17 00:00:00 2001 From: "Theodore A. Roth" Date: Tue, 15 Apr 2014 09:46:26 -0600 Subject: [PATCH 0263/1435] Quell compiler warning. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Building on a 32-bit linux system was generating the following: src/st-info.c: In function ‘print_data’: src/st-info.c:25:3: warning: format ‘%lx’ expects argument of type \ ‘long unsigned int’, but argument 2 has type ‘size_t’ [-Wformat] src/st-info.c:27:3: warning: format ‘%lx’ expects argument of type \ ‘long unsigned int’, but argument 2 has type ‘size_t’ [-Wformat] src/st-info.c:29:3: warning: format ‘%lx’ expects argument of type \ ‘long unsigned int’, but argument 2 has type ‘size_t’ [-Wformat] Using '%zx' eliminates the warning in a platform agnostic way. --- src/st-info.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/st-info.c b/src/st-info.c index e28a4f12c..28f3fb823 100644 --- a/src/st-info.c +++ b/src/st-info.c @@ -22,11 +22,11 @@ static int print_data(stlink_t* sl, char** av) { int ret = 0; if (strcmp(av[1], "--flash") == 0) - printf("0x%lx\n", sl->flash_size); + printf("0x%zx\n", sl->flash_size); else if (strcmp(av[1], "--sram") == 0) - printf("0x%lx\n", sl->sram_size); + printf("0x%zx\n", sl->sram_size); else if (strcmp(av[1], "--pagesize") == 0) - printf("0x%lx\n", sl->flash_pgsz); + printf("0x%zx\n", sl->flash_pgsz); else if (strcmp(av[1], "--chipid") == 0) printf("0x%.4x\n", sl->chip_id); else if (strcmp(av[1], "--descr")==0) { From 8f96d26a522d870a50f7cb58a7e4a709dcb0dac6 Mon Sep 17 00:00:00 2001 From: fhars Date: Wed, 16 Apr 2014 10:41:33 +0200 Subject: [PATCH 0264/1435] Update README This board uses a ST-Link/V2-1 interface. I don't know what differences there are between v2 and v2-1, but they seem to be small enough that first tests worked as expected. --- README | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README b/README index 853c51826..3d25ae34c 100644 --- a/README +++ b/README @@ -180,5 +180,8 @@ Known Working Targets: * STM32L151CB (custom board) * STM32L152RB (STM32L-Discovery board, custom board) -Please report any and all known working combinations so I can update this! +STLink v2-1 (as found on the Nucleo boards) +Known Working Targets: +* STM32F401xx (STM32 Nucleo-F401RE board) +Please report any and all known working combinations so I can update this! From 788d2df7723e9da3a0369365f56830ab9541e9c7 Mon Sep 17 00:00:00 2001 From: Olivier Croquette Date: Mon, 19 May 2014 10:35:24 +0200 Subject: [PATCH 0265/1435] Include signal.h to define SIGINT Fix build error with MinGW --- gdbserver/gdb-server.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 459d1012b..a3ed335ad 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #ifdef __MINGW32__ From bf3d7a0dddb6db7e12f711c7ad8c0ebcf30d64fe Mon Sep 17 00:00:00 2001 From: orangeudav Date: Mon, 26 May 2014 01:36:59 +0400 Subject: [PATCH 0266/1435] Fix OS X's version detecting --- stlinkv1_macosx_driver/README | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/stlinkv1_macosx_driver/README b/stlinkv1_macosx_driver/README index adf3cca87..7b47f410f 100644 --- a/stlinkv1_macosx_driver/README +++ b/stlinkv1_macosx_driver/README @@ -22,4 +22,11 @@ tar xzvf osx.tar.gz Then, install the driver using: sudo make osx_stlink_shield -no reboot required. \ No newline at end of file +no reboot required. + +P.S. If error `OS X version not supported` occurs. For the latest versions of Mac OS X you may need to change the `osx/install.sh` as follows: +``` +< ISOSXLION=$(sw_vers -productVersion) +--- +> ISOSXLION=$(sw_vers -productVersion | sed -e 's:.[[:digit:]]*$::') +``` From 2dbf4970f021f2e36163c630e74ce56ffd24f7c0 Mon Sep 17 00:00:00 2001 From: Stany MARCEL Date: Wed, 4 Jun 2014 00:13:46 +0200 Subject: [PATCH 0267/1435] Correct gui build when builddir is not srcdir --- gui/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/Makefile.am b/gui/Makefile.am index 19c067278..97b780e43 100644 --- a/gui/Makefile.am +++ b/gui/Makefile.am @@ -7,7 +7,7 @@ stlink_gui_SOURCES = \ stlink_gui_CPPFLAGS = \ -I$(top_srcdir) \ $(AM_CPPFLAGS) \ - -I$(top_builddir)/src \ + -I$(top_srcdir)/src \ @GTK_CFLAGS@ stlink_gui_CFLAGS = \ From 0d1521c4abfafeba4daab5adf92d9081f70c75db Mon Sep 17 00:00:00 2001 From: Viacheslav Dobromyslov Date: Fri, 20 Jun 2014 21:11:09 +1100 Subject: [PATCH 0268/1435] udev rules initialization and STM32F0Discovery Added udev rules initialization. Added STM32F0Discovery board to the supported boards list. --- README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README b/README index 3d25ae34c..c0ccc7b73 100644 --- a/README +++ b/README @@ -113,6 +113,7 @@ For convenience, you may install udev rules file, 49-stlinkv*.rules, located in the root of repository. You will need to copy it to /etc/udev/rules.d, and then either reboot or execute $ udevadm control --reload-rules +$ udevadm trigger Udev will now create a /dev/stlinkv2_XX or /dev/stlinkv1_XX file, with the appropriate permissions. This is currently all the device is for, (only one stlink of each version is supported at @@ -169,6 +170,7 @@ No information: STLink v2 (as found on the 32L and F4 Discovery boards) Known Working Targets: +* STM32F0Discovery (STM32F0 Discovery board) * STM32F100xx (Medium Density VL, as on the 32VL Discovery board) * STM32L1xx (STM32L Discovery board) * STM32F103VC, STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on custom boards From 95834ef5ed5e2ada7d420404f1ff98cb6bcc543c Mon Sep 17 00:00:00 2001 From: sneuf Date: Tue, 1 Jul 2014 16:42:27 +0200 Subject: [PATCH 0269/1435] Add F3 small devices (F301, F302) with ID 0x439 - Add F3 small devices (F301, F302) with MCU device ID code 0x439 - Sort supported devices by MCU device ID code --- src/stlink-common.h | 63 +++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/src/stlink-common.h b/src/stlink-common.h index cce4d9f3e..1bedbf497 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -98,33 +98,46 @@ extern "C" { * DBGMCU_IDCODE register (0xE0042000) */ // stm32 chipids, only lower 12 bits.. -#define STM32_CHIPID_F1_MEDIUM 0x410 -#define STM32_CHIPID_F2 0x411 -#define STM32_CHIPID_F1_LOW 0x412 -#define STM32_CHIPID_F3 0x422 -#define STM32_CHIPID_F37x 0x432 -#define STM32_CHIPID_F4 0x413 -#define STM32_CHIPID_F4_HD 0x419 -#define STM32_CHIPID_F4_LP 0x423 -#define STM32_CHIPID_F4_DE 0x433 -#define STM32_CHIPID_F1_HIGH 0x414 -#define STM32_CHIPID_L1_MEDIUM 0x416 +#define STM32_CHIPID_F1_MEDIUM 0x410 +#define STM32_CHIPID_F2 0x411 +#define STM32_CHIPID_F1_LOW 0x412 +#define STM32_CHIPID_F4 0x413 +#define STM32_CHIPID_F1_HIGH 0x414 + +#define STM32_CHIPID_L1_MEDIUM 0x416 + +#define STM32_CHIPID_F1_CONN 0x418 +#define STM32_CHIPID_F4_HD 0x419 +#define STM32_CHIPID_F1_VL_MEDIUM 0x420 + +#define STM32_CHIPID_F3 0x422 +#define STM32_CHIPID_F4_LP 0x423 + #define STM32_CHIPID_L1_MEDIUM_PLUS 0x427 +#define STM32_CHIPID_F1_VL_HIGH 0x428 + +#define STM32_CHIPID_F1_XL 0x430 + +#define STM32_CHIPID_F37x 0x432 +#define STM32_CHIPID_F4_DE 0x433 + +#define STM32_CHIPID_L1_HIGH 0x436 +#define STM32_CHIPID_L152_RE 0x437 + + +#define STM32_CHIPID_F3_SMALL 0x439 +#define STM32_CHIPID_F0 0x440 + +#define STM32_CHIPID_F0_SMALL 0x444 + +#define STM32_CHIPID_F0_CAN 0x448 + /* * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" * and some that are called "High". 0x427 is assigned to the other "Medium- * plus" chips. To make it a bit simpler we just call 427 MEDIUM_PLUS and * 0x436 HIGH. */ -#define STM32_CHIPID_L1_HIGH 0x436 -#define STM32_CHIPID_L152_RE 0x437 -#define STM32_CHIPID_F1_CONN 0x418 -#define STM32_CHIPID_F1_VL_MEDIUM 0x420 -#define STM32_CHIPID_F1_VL_HIGH 0x428 -#define STM32_CHIPID_F1_XL 0x430 -#define STM32_CHIPID_F0 0x440 -#define STM32_CHIPID_F0_SMALL 0x444 -#define STM32_CHIPID_F0_CAN 0x448 // Constant STM32 memory map figures #define STM32_FLASH_BASE 0x08000000 @@ -354,6 +367,16 @@ static const chip_params_t devices[] = { .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 }, + { + // STM32F30x + .chip_id = STM32_CHIPID_F3_SMALL, + .description = "F3 small device", + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1fffd800, + .bootrom_size = 0x2000 + }, }; From 3b443dc1c8690ee4b45f477cd83165dca700e60a Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 9 Jul 2014 22:31:11 -0700 Subject: [PATCH 0270/1435] Reindent all source files The indentation of various st-link source files is highly inconsistent. Reindent all source files to 4 space indentions for consistency. I went with 4 space indentations, as it was the most common style. --- flash/main.c | 340 +++---- flashloaders/stm32f0.s | 46 +- flashloaders/stm32f4.s | 26 +- flashloaders/stm32lx.s | 51 +- gdbserver/gdb-remote.c | 248 +++-- gdbserver/gdb-server.c | 1944 ++++++++++++++++++++-------------------- gui/stlink-gui.c | 1332 +++++++++++++-------------- gui/stlink-gui.h | 102 +-- mingw/mingw.c | 198 ++-- src/mmap.c | 28 +- src/mmap.h | 4 +- src/st-info.c | 118 +-- src/st-term.c | 352 ++++---- src/stlink-common.c | 538 +++++------ src/stlink-common.h | 335 ++++--- src/stlink-sg.c | 363 ++++---- src/stlink-sg.h | 10 +- src/stlink-usb.c | 104 +-- src/stlink-usb.h | 6 +- src/test_sg.c | 288 +++--- src/test_usb.c | 10 +- src/uglylogging.c | 52 +- src/uglylogging.h | 4 +- 23 files changed, 3247 insertions(+), 3252 deletions(-) diff --git a/flash/main.c b/flash/main.c index d550eeeed..8f5b351de 100644 --- a/flash/main.c +++ b/flash/main.c @@ -12,12 +12,12 @@ enum st_cmds {DO_WRITE = 0, DO_READ = 1, DO_ERASE = 2}; struct opts { - enum st_cmds cmd; - const char* devname; - const char* filename; - stm32_addr_t addr; - size_t size; - int reset; + enum st_cmds cmd; + const char* devname; + const char* filename; + stm32_addr_t addr; + size_t size; + int reset; }; static void usage(void) @@ -31,183 +31,183 @@ static void usage(void) 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 < 1) return -1; - - if (strcmp(av[0], "--reset") == 0) - { - o->reset = 1; - ac--; - av++; - } - else - { - o->reset = 0; - } - - if (ac < 1) return -1; - - /* stlinkv2 */ - o->devname = NULL; - - if (strcmp(av[0], "erase") == 0) - { - o->cmd = DO_ERASE; - - /* stlinkv1 mode */ - if (ac == 2) + /* stlinkv1 command line: ./flash {read|write} /dev/sgX path addr */ + /* stlinkv2 command line: ./flash {read|write} path addr */ + + unsigned int i = 0; + + if (ac < 1) return -1; + + if (strcmp(av[0], "--reset") == 0) + { + o->reset = 1; + ac--; + av++; + } + else { - o->devname = av[1]; - i = 1; + o->reset = 0; } - } - else { - if (ac < 3) return -1; - if (strcmp(av[0], "read") == 0) - { - o->cmd = DO_READ; - - /* stlinkv1 mode */ - if (ac == 5) - { - o->devname = av[1]; - i = 1; - } - if (ac > 3) - o->size = strtoul(av[i + 3], NULL, 16); - } - else if (strcmp(av[0], "write") == 0) - { - o->cmd = DO_WRITE; - - /* stlinkv1 mode */ - if (ac == 4) - { - o->devname = av[1]; - i = 1; - } - } - else - { - return -1; - } - } - - o->filename = av[i + 1]; - o->addr = strtoul(av[i + 2], NULL, 16); - - return 0; -} + + if (ac < 1) return -1; + + /* stlinkv2 */ + o->devname = NULL; + + if (strcmp(av[0], "erase") == 0) + { + o->cmd = DO_ERASE; + + /* stlinkv1 mode */ + if (ac == 2) + { + o->devname = av[1]; + i = 1; + } + } + else { + if (ac < 3) return -1; + if (strcmp(av[0], "read") == 0) + { + o->cmd = DO_READ; + + /* stlinkv1 mode */ + if (ac == 5) + { + o->devname = av[1]; + i = 1; + } + if (ac > 3) + o->size = strtoul(av[i + 3], NULL, 16); + } + else if (strcmp(av[0], "write") == 0) + { + o->cmd = DO_WRITE; + + /* stlinkv1 mode */ + if (ac == 4) + { + o->devname = av[1]; + i = 1; + } + } + 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; - - o.size = 0; - if (get_opts(&o, ac - 1, av + 1) == -1) - { - printf("invalid command line\n"); - usage(); - goto on_error; - } - - if (o.devname != NULL) /* stlinkv1 */ - { - sl = stlink_v1_open(50, 1); - if (sl == NULL) goto on_error; - sl->verbose = 50; - } - else /* stlinkv2 */ - { - sl = stlink_open_usb(50, 1); - if (sl == NULL) goto on_error; - sl->verbose = 50; - } - - 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); - - if (o.reset) - stlink_reset(sl); - -// Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 - if (sl->chip_id == STM32_CHIPID_F4) - { - memset(sl->q_buf,0,4); - for (int i=0;i<8;i++) { - stlink_write_mem32(sl,0x40026000+0x10+0x18*i,4); - stlink_write_mem32(sl,0x40026400+0x10+0x18*i,4); - stlink_write_mem32(sl,0x40026000+0x24+0x18*i,4); - stlink_write_mem32(sl,0x40026400+0x24+0x18*i,4); - } - } - if (o.cmd == DO_WRITE) /* write */ - { - if ((o.addr >= sl->flash_base) && - (o.addr < sl->flash_base + sl->flash_size)) { - err = stlink_fwrite_flash(sl, o.filename, o.addr); - if (err == -1) - { - printf("stlink_fwrite_flash() == -1\n"); - goto on_error; - } + stlink_t* sl = NULL; + struct opts o; + int err = -1; + + o.size = 0; + if (get_opts(&o, ac - 1, av + 1) == -1) + { + printf("invalid command line\n"); + usage(); + goto on_error; } - else if ((o.addr >= sl->sram_base) && - (o.addr < sl->sram_base + sl->sram_size)) { - err = stlink_fwrite_sram(sl, o.filename, o.addr); - if (err == -1) - { - printf("stlink_sram_flash() == -1\n"); - goto on_error; - } - } - } else if (o.cmd == DO_ERASE) - { - err = stlink_erase_flash_mass(sl); - if (err == -1) + + if (o.devname != NULL) /* stlinkv1 */ { - printf("stlink_fwrite_flash() == -1\n"); - goto on_error; + sl = stlink_v1_open(50, 1); + if (sl == NULL) goto on_error; + sl->verbose = 50; } - } - else /* read */ - { - if ((o.addr >= sl->flash_base) && (o.size == 0) && - (o.addr < sl->flash_base + sl->flash_size)) - o.size = sl->flash_size; - else if ((o.addr >= sl->sram_base) && (o.size == 0) && - (o.addr < sl->sram_base + sl->sram_size)) - o.size = sl->sram_size; - err = stlink_fread(sl, o.filename, o.addr, o.size); - if (err == -1) + else /* stlinkv2 */ { - printf("stlink_fread() == -1\n"); - goto on_error; + sl = stlink_open_usb(50, 1); + if (sl == NULL) goto on_error; + sl->verbose = 50; } - } - if (o.reset) - stlink_reset(sl); + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) + stlink_exit_dfu_mode(sl); - /* success */ - err = 0; + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) + stlink_enter_swd_mode(sl); - on_error: - if (sl != NULL) - { - stlink_exit_debug_mode(sl); - stlink_close(sl); - } + if (o.reset) + stlink_reset(sl); + + // Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 + if (sl->chip_id == STM32_CHIPID_F4) + { + memset(sl->q_buf,0,4); + for (int i=0;i<8;i++) { + stlink_write_mem32(sl,0x40026000+0x10+0x18*i,4); + stlink_write_mem32(sl,0x40026400+0x10+0x18*i,4); + stlink_write_mem32(sl,0x40026000+0x24+0x18*i,4); + stlink_write_mem32(sl,0x40026400+0x24+0x18*i,4); + } + } + if (o.cmd == DO_WRITE) /* write */ + { + if ((o.addr >= sl->flash_base) && + (o.addr < sl->flash_base + sl->flash_size)) { + err = stlink_fwrite_flash(sl, o.filename, o.addr); + if (err == -1) + { + printf("stlink_fwrite_flash() == -1\n"); + goto on_error; + } + } + else if ((o.addr >= sl->sram_base) && + (o.addr < sl->sram_base + sl->sram_size)) { + err = stlink_fwrite_sram(sl, o.filename, o.addr); + if (err == -1) + { + printf("stlink_sram_flash() == -1\n"); + goto on_error; + } + } + } else if (o.cmd == DO_ERASE) + { + err = stlink_erase_flash_mass(sl); + if (err == -1) + { + printf("stlink_fwrite_flash() == -1\n"); + goto on_error; + } + } + else /* read */ + { + if ((o.addr >= sl->flash_base) && (o.size == 0) && + (o.addr < sl->flash_base + sl->flash_size)) + o.size = sl->flash_size; + else if ((o.addr >= sl->sram_base) && (o.size == 0) && + (o.addr < sl->sram_base + sl->sram_size)) + o.size = sl->sram_size; + err = stlink_fread(sl, o.filename, o.addr, o.size); + if (err == -1) + { + printf("stlink_fread() == -1\n"); + goto on_error; + } + } + + if (o.reset) + stlink_reset(sl); + + /* success */ + err = 0; + +on_error: + if (sl != NULL) + { + stlink_exit_debug_mode(sl); + stlink_close(sl); + } - return err; + return err; } diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index f35fe406e..fe12f90f3 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -1,32 +1,32 @@ /* Adopted from STM AN4065 stm32f0xx_flash.c:FLASH_ProgramWord */ -write: - ldr r4, STM32_FLASH_BASE - mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ - mov r6, #4 /* PGERR */ +write: + ldr r4, STM32_FLASH_BASE + mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ + mov r6, #4 /* PGERR */ write_half_word: - ldr r3, [r4, #16] /* FLASH->CR */ - orr r3, r5 - str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ - ldrh r3, [r0] /* r3 = *sram */ - strh r3, [r1] /* *flash = r3 */ + ldr r3, [r4, #16] /* FLASH->CR */ + orr r3, r5 + str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ + ldrh r3, [r0] /* r3 = *sram */ + strh r3, [r1] /* *flash = r3 */ busy: - ldr r3, [r4, #12] /* FLASH->SR */ - tst r3, r5 /* FLASH_SR_BUSY */ - beq busy + ldr r3, [r4, #12] /* FLASH->SR */ + tst r3, r5 /* FLASH_SR_BUSY */ + beq busy - tst r3, r6 /* PGERR */ - bne exit + tst r3, r6 /* PGERR */ + bne exit - add r0, r0, #2 /* sram += 2 */ - add r1, r1, #2 /* flash += 2 */ - sub r2, r2, #0x01 /* count-- */ - cmp r2, #0 - bne write_half_word + add r0, r0, #2 /* sram += 2 */ + add r1, r1, #2 /* flash += 2 */ + sub r2, r2, #0x01 /* count-- */ + cmp r2, #0 + bne write_half_word exit: - ldr r3, [r4, #16] /* FLASH->CR */ - bic r3, r5 - str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ - bkpt #0x00 + ldr r3, [r4, #16] /* FLASH->CR */ + bic r3, r5 + str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ + bkpt #0x00 STM32_FLASH_BASE: .word 0x40022000 diff --git a/flashloaders/stm32f4.s b/flashloaders/stm32f4.s index 6cad73042..21f5a8f7f 100644 --- a/flashloaders/stm32f4.s +++ b/flashloaders/stm32f4.s @@ -8,23 +8,23 @@ @ r4 = temp start: - ldr r3, flash_base + ldr r3, flash_base next: - cbz r2, done - ldr r4, [r0] - str r4, [r1] + cbz r2, done + ldr r4, [r0] + str r4, [r1] wait: - ldrh r4, [r3, #0x0e] - tst.w r4, #1 - bne wait - - add r0, #4 - add r1, #4 - sub r2, #1 - b next + ldrh r4, [r3, #0x0e] + tst.w r4, #1 + bne wait + + add r0, #4 + add r1, #4 + sub r2, #1 + b next done: - bkpt + bkpt .align 2 diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index 6e8ccb089..799d1345c 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -26,38 +26,37 @@ // Build : arm-eabi-gcc -c stm32lx.S - .text - .syntax unified - .cpu cortex-m3 - .thumb - .thumb_func - .global write + .text + .syntax unified + .cpu cortex-m3 + .thumb + .thumb_func + .global write /* - r0 - destination address - r1 - source address - r2 - count + r0 - destination address + r1 - source address + r2 - count */ - // Set 0 to r3 - movs r3, #0 - // Go to compare - b.n test_done + // Set 0 to r3 + movs r3, #0 + // Go to compare + b.n test_done write_word: - // Load one word from address in r0, increment by 4 - ldr.w ip, [r1], #4 - // Store the word to address in r1, increment by 4 - str.w ip, [r0], #4 - // Increment r3 - adds r3, #1 + // Load one word from address in r0, increment by 4 + ldr.w ip, [r1], #4 + // Store the word to address in r1, increment by 4 + str.w ip, [r0], #4 + // Increment r3 + adds r3, #1 test_done: - // Compare r3 and r2 - cmp r3, r2 - // Loop if not zero - bcc.n write_word - - // Set breakpoint to exit - bkpt #0x00 + // Compare r3 and r2 + cmp r3, r2 + // Loop if not zero + bcc.n write_word + // Set breakpoint to exit + bkpt #0x00 diff --git a/gdbserver/gdb-remote.c b/gdbserver/gdb-remote.c index edf53389b..a9eef3333 100644 --- a/gdbserver/gdb-remote.c +++ b/gdbserver/gdb-remote.c @@ -1,10 +1,8 @@ -/* -*- tab-width:8 -*- */ - /* - Copyright (C) 2011 Peter Zotov - Use of this source code is governed by a BSD-style - license that can be found in the LICENSE file. -*/ + * Copyright (C) 2011 Peter Zotov + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ #include #include @@ -20,141 +18,141 @@ static const char hex[] = "0123456789abcdef"; int gdb_send_packet(int fd, char* data) { - int length = strlen(data) + 5; - char* packet = malloc(length); /* '$' data (hex) '#' cksum (hex) */ - - memset(packet, 0, length); - - packet[0] = '$'; - - uint8_t cksum = 0; - for(unsigned int i = 0; i < strlen(data); i++) { - packet[i + 1] = data[i]; - cksum += data[i]; - } - - packet[length - 4] = '#'; - packet[length - 3] = hex[cksum >> 4]; - packet[length - 2] = hex[cksum & 0xf]; - - while(1) { - if(write(fd, packet, length) != length) { - free(packet); - return -2; - } - - char ack; - if(read(fd, &ack, 1) != 1) { - free(packet); - return -2; - } - - if(ack == '+') { - free(packet); - return 0; - } - } + int length = strlen(data) + 5; + char* packet = malloc(length); /* '$' data (hex) '#' cksum (hex) */ + + memset(packet, 0, length); + + packet[0] = '$'; + + uint8_t cksum = 0; + for(unsigned int i = 0; i < strlen(data); i++) { + packet[i + 1] = data[i]; + cksum += data[i]; + } + + packet[length - 4] = '#'; + packet[length - 3] = hex[cksum >> 4]; + packet[length - 2] = hex[cksum & 0xf]; + + while(1) { + if(write(fd, packet, length) != length) { + free(packet); + return -2; + } + + char ack; + if(read(fd, &ack, 1) != 1) { + free(packet); + return -2; + } + + if(ack == '+') { + free(packet); + return 0; + } + } } #define ALLOC_STEP 1024 int gdb_recv_packet(int fd, char** buffer) { - unsigned packet_size = ALLOC_STEP + 1, packet_idx = 0; - uint8_t cksum = 0; - char recv_cksum[3] = {0}; - char* packet_buffer = malloc(packet_size); - unsigned state; + unsigned packet_size = ALLOC_STEP + 1, packet_idx = 0; + uint8_t cksum = 0; + char recv_cksum[3] = {0}; + char* packet_buffer = malloc(packet_size); + unsigned state; start: - state = 0; - /* - * 0: waiting $ - * 1: data, waiting # - * 2: cksum 1 - * 3: cksum 2 - * 4: fin - */ - - char c; - while(state != 4) { - if(read(fd, &c, 1) != 1) { - return -2; - } - - switch(state) { - case 0: - if(c != '$') { - // ignore - } else { - state = 1; - } - break; - - case 1: - if(c == '#') { - state = 2; - } else { - packet_buffer[packet_idx++] = c; - cksum += c; - - if(packet_idx == packet_size) { - packet_size += ALLOC_STEP; - packet_buffer = realloc(packet_buffer, packet_size); - } - } - break; - - case 2: - recv_cksum[0] = c; - state = 3; - break; - - case 3: - recv_cksum[1] = c; - state = 4; - break; - } - } - - uint8_t recv_cksum_int = strtoul(recv_cksum, NULL, 16); - if(recv_cksum_int != cksum) { - char nack = '-'; - if(write(fd, &nack, 1) != 1) { - return -2; - } - - goto start; - } else { - char ack = '+'; - if(write(fd, &ack, 1) != 1) { - return -2; - } - } - - packet_buffer[packet_idx] = 0; - *buffer = packet_buffer; - - return packet_idx; + state = 0; + /* + * 0: waiting $ + * 1: data, waiting # + * 2: cksum 1 + * 3: cksum 2 + * 4: fin + */ + + char c; + while(state != 4) { + if(read(fd, &c, 1) != 1) { + return -2; + } + + switch(state) { + case 0: + if(c != '$') { + // ignore + } else { + state = 1; + } + break; + + case 1: + if(c == '#') { + state = 2; + } else { + packet_buffer[packet_idx++] = c; + cksum += c; + + if(packet_idx == packet_size) { + packet_size += ALLOC_STEP; + packet_buffer = realloc(packet_buffer, packet_size); + } + } + break; + + case 2: + recv_cksum[0] = c; + state = 3; + break; + + case 3: + recv_cksum[1] = c; + state = 4; + break; + } + } + + uint8_t recv_cksum_int = strtoul(recv_cksum, NULL, 16); + if(recv_cksum_int != cksum) { + char nack = '-'; + if(write(fd, &nack, 1) != 1) { + return -2; + } + + goto start; + } else { + char ack = '+'; + if(write(fd, &ack, 1) != 1) { + return -2; + } + } + + packet_buffer[packet_idx] = 0; + *buffer = packet_buffer; + + return packet_idx; } // Here we skip any characters which are not \x03, GDB interrupt. // As we use the mode with ACK, in a (very unlikely) situation of a packet // lost because of this skipping, it will be resent anyway. int gdb_check_for_interrupt(int fd) { - struct pollfd pfd; - pfd.fd = fd; - pfd.events = POLLIN; + struct pollfd pfd; + pfd.fd = fd; + pfd.events = POLLIN; - if(poll(&pfd, 1, 0) != 0) { - char c; + if(poll(&pfd, 1, 0) != 0) { + char c; - if(read(fd, &c, 1) != 1) - return -2; + if(read(fd, &c, 1) != 1) + return -2; - if(c == '\x03') // ^C - return 1; - } + if(c == '\x03') // ^C + return 1; + } - return 0; + return 0; } diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index a3ed335ad..71ab44016 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -1,10 +1,9 @@ -/* -*- tab-width:8 -*- */ #define DEBUG 0 /* - Copyright (C) 2011 Peter Zotov - Use of this source code is governed by a BSD-style - license that can be found in the LICENSE file. -*/ + * Copyright (C) 2011 Peter Zotov + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ #include #include @@ -75,31 +74,31 @@ int parse_options(int argc, char** argv, st_state_t *st) { {"verbose", optional_argument, NULL, 'v'}, {"stlink_version", required_argument, NULL, 's'}, {"stlinkv1", no_argument, NULL, '1'}, - {"listen_port", required_argument, NULL, 'p'}, - {"multi", optional_argument, NULL, 'm'}, - {"no-reset", optional_argument, NULL, 'n'}, + {"listen_port", required_argument, NULL, 'p'}, + {"multi", optional_argument, NULL, 'm'}, + {"no-reset", optional_argument, NULL, 'n'}, {0, 0, 0, 0}, }; - const char * help_str = "%s - usage:\n\n" - " -h, --help\t\tPrint this help\n" - " -vXX, --verbose=XX\tSpecify a specific verbosity level (0..99)\n" - " -v, --verbose\t\tSpecify generally verbose logging\n" - " -s X, --stlink_version=X\n" - "\t\t\tChoose what version of stlink to use, (defaults to 2)\n" - " -1, --stlinkv1\tForce stlink version 1\n" - " -p 4242, --listen_port=1234\n" - "\t\t\tSet the gdb server listen port. " - "(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n" - " -m, --multi\n" - "\t\t\tSet gdb server to extended mode.\n" - "\t\t\tst-util will continue listening for connections after disconnect.\n" - " -n, --no-reset\n" - "\t\t\tDo not reset board on connection.\n" - "\n" - "The STLINKv2 device to use can be specified in the environment\n" - "variable STLINK_DEVICE on the format :.\n" - "\n" - ; + const char * help_str = "%s - usage:\n\n" + " -h, --help\t\tPrint this help\n" + " -vXX, --verbose=XX\tSpecify a specific verbosity level (0..99)\n" + " -v, --verbose\t\tSpecify generally verbose logging\n" + " -s X, --stlink_version=X\n" + "\t\t\tChoose what version of stlink to use, (defaults to 2)\n" + " -1, --stlinkv1\tForce stlink version 1\n" + " -p 4242, --listen_port=1234\n" + "\t\t\tSet the gdb server listen port. " + "(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n" + " -m, --multi\n" + "\t\t\tSet gdb server to extended mode.\n" + "\t\t\tst-util will continue listening for connections after disconnect.\n" + " -n, --no-reset\n" + "\t\t\tDo not reset board on connection.\n" + "\n" + "The STLINKv2 device to use can be specified in the environment\n" + "variable STLINK_DEVICE on the format :.\n" + "\n" + ; int option_index = 0; @@ -107,50 +106,50 @@ int parse_options(int argc, char** argv, st_state_t *st) { int q; while ((c = getopt_long(argc, argv, "hv::s:1p:mn", long_options, &option_index)) != -1) { switch (c) { - case 0: - printf("XXXXX Shouldn't really normally come here, only if there's no corresponding option\n"); - printf("option %s", long_options[option_index].name); - if (optarg) { - printf(" with arg %s", optarg); - } - printf("\n"); - break; - case 'h': - printf(help_str, argv[0]); - exit(EXIT_SUCCESS); - break; - case 'v': - if (optarg) { - st->logging_level = atoi(optarg); - } else { - st->logging_level = DEFAULT_LOGGING_LEVEL; - } - break; - case '1': - st->stlink_version = 1; - break; - case 's': - sscanf(optarg, "%i", &q); - if (q < 0 || q > 2) { - fprintf(stderr, "stlink version %d unknown!\n", q); - exit(EXIT_FAILURE); - } - st->stlink_version = q; - break; - case 'p': - sscanf(optarg, "%i", &q); - if (q < 0) { - fprintf(stderr, "Can't use a negative port to listen on: %d\n", q); - exit(EXIT_FAILURE); - } - st->listen_port = q; - break; - case 'm': - st->persistent = 1; - break; - case 'n': - st->reset = 0; - break; + case 0: + printf("XXXXX Shouldn't really normally come here, only if there's no corresponding option\n"); + printf("option %s", long_options[option_index].name); + if (optarg) { + printf(" with arg %s", optarg); + } + printf("\n"); + break; + case 'h': + printf(help_str, argv[0]); + exit(EXIT_SUCCESS); + break; + case 'v': + if (optarg) { + st->logging_level = atoi(optarg); + } else { + st->logging_level = DEFAULT_LOGGING_LEVEL; + } + break; + case '1': + st->stlink_version = 1; + break; + case 's': + sscanf(optarg, "%i", &q); + if (q < 0 || q > 2) { + fprintf(stderr, "stlink version %d unknown!\n", q); + exit(EXIT_FAILURE); + } + st->stlink_version = q; + break; + case 'p': + sscanf(optarg, "%i", &q); + if (q < 0) { + fprintf(stderr, "Can't use a negative port to listen on: %d\n", q); + exit(EXIT_FAILURE); + } + st->listen_port = q; + break; + case 'm': + st->persistent = 1; + break; + case 'n': + st->reset = 0; + break; } } @@ -165,27 +164,27 @@ int parse_options(int argc, char** argv, st_state_t *st) { int main(int argc, char** argv) { - int32_t voltage; - - stlink_t *sl = NULL; - - st_state_t state; - memset(&state, 0, sizeof(state)); - // set defaults... - state.stlink_version = 2; - state.logging_level = DEFAULT_LOGGING_LEVEL; - state.listen_port = DEFAULT_GDB_LISTEN_PORT; - state.reset = 1; /* By default, reset board */ - parse_options(argc, argv, &state); - switch (state.stlink_version) { - case 2: - sl = stlink_open_usb(state.logging_level, 0); - if(sl == NULL) return 1; - break; - case 1: - sl = stlink_v1_open(state.logging_level, 0); - if(sl == NULL) return 1; - break; + int32_t voltage; + + stlink_t *sl = NULL; + + st_state_t state; + memset(&state, 0, sizeof(state)); + // set defaults... + state.stlink_version = 2; + state.logging_level = DEFAULT_LOGGING_LEVEL; + state.listen_port = DEFAULT_GDB_LISTEN_PORT; + state.reset = 1; /* By default, reset board */ + parse_options(argc, argv, &state); + switch (state.stlink_version) { + case 2: + sl = stlink_open_usb(state.logging_level, 0); + if(sl == NULL) return 1; + break; + case 1: + sl = stlink_v1_open(state.logging_level, 0); + if(sl == NULL) return 1; + break; } connected_stlink = sl; @@ -193,44 +192,44 @@ int main(int argc, char** argv) { signal(SIGTERM, &cleanup); if (state.reset) { - stlink_reset(sl); + stlink_reset(sl); } - printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); + printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); - voltage = stlink_target_voltage(sl); - if (voltage != -1) { - printf("Target voltage is %d mV.\n", voltage); - } + voltage = stlink_target_voltage(sl); + if (voltage != -1) { + printf("Target voltage is %d mV.\n", voltage); + } - sl->verbose=0; + sl->verbose=0; - current_memory_map = make_memory_map(sl); + current_memory_map = make_memory_map(sl); #ifdef __MINGW32__ - WSADATA wsadata; - if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0 ) { - goto winsock_error; - } + WSADATA wsadata; + if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0 ) { + goto winsock_error; + } #endif - do { - serve(sl, &state); + do { + serve(sl, &state); - /* Continue */ - stlink_run(sl); - } while (state.persistent); + /* Continue */ + stlink_run(sl); + } while (state.persistent); #ifdef __MINGW32__ winsock_error: - WSACleanup(); + WSACleanup(); #endif - /* Switch back to mass storage mode before closing. */ - stlink_exit_debug_mode(sl); - stlink_close(sl); + /* Switch back to mass storage mode before closing. */ + stlink_exit_debug_mode(sl); + stlink_close(sl); - return 0; + return 0; } static const char* const target_description_F4 = @@ -299,59 +298,59 @@ static const char* const target_description_F4 = ""; static const char* const memory_map_template_F4 = - "" - "" - "" - " " // code = sram, bootrom or flash; flash is bigger - " " // ccm ram - " " // sram - " " //Sectors 0..3 - " 0x4000" //16kB - " " - " " //Sector 4 - " 0x10000" //64kB - " " - " " //Sectors 5..11 - " 0x20000" //128kB - " " - " " // peripheral regs - " " // cortex regs - " " // bootrom - " " // option byte area - ""; + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // ccm ram + " " // sram + " " //Sectors 0..3 + " 0x4000" //16kB + " " + " " //Sector 4 + " 0x10000" //64kB + " " + " " //Sectors 5..11 + " 0x20000" //128kB + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + " " // option byte area + ""; static const char* const memory_map_template = - "" - "" - "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram 8k - " " - " 0x%zx" - " " - " " // peripheral regs - " " // cortex regs - " " // bootrom - " " // option byte area - ""; + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // sram 8k + " " + " 0x%zx" + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + " " // option byte area + ""; char* make_memory_map(stlink_t *sl) { - /* This will be freed in serve() */ - char* map = malloc(4096); - map[0] = '\0'; + /* This will be freed in serve() */ + char* map = malloc(4096); + map[0] = '\0'; - if(sl->chip_id==STM32_CHIPID_F4) { - strcpy(map, memory_map_template_F4); + if(sl->chip_id==STM32_CHIPID_F4) { + strcpy(map, memory_map_template_F4); } else { snprintf(map, 4096, memory_map_template, - sl->flash_size, - sl->sram_size, - sl->flash_size, sl->flash_pgsz, - sl->sys_base, sl->sys_size); + sl->flash_size, + sl->sram_size, + sl->flash_size, sl->flash_pgsz, + sl->sys_base, sl->sys_size); } - return map; + return map; } @@ -375,101 +374,101 @@ char* make_memory_map(stlink_t *sl) { enum watchfun { WATCHDISABLED = 0, WATCHREAD = 5, WATCHWRITE = 6, WATCHACCESS = 7 }; struct code_hw_watchpoint { - stm32_addr_t addr; - uint8_t mask; - enum watchfun fun; + stm32_addr_t addr; + uint8_t mask; + enum watchfun fun; }; struct code_hw_watchpoint data_watches[DATA_WATCH_NUM]; static void init_data_watchpoints(stlink_t *sl) { - #if DEBUG - printf("init watchpoints\n"); - #endif - - // set trcena in debug command to turn on dwt unit - stlink_write_debug32(sl, 0xE000EDFC, - stlink_read_debug32(sl, 0xE000EDFC) | (1<<24)); - - // make sure all watchpoints are cleared - for(int i = 0; i < DATA_WATCH_NUM; i++) { - data_watches[i].fun = WATCHDISABLED; - stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); - } +#if DEBUG + printf("init watchpoints\n"); +#endif + + // set trcena in debug command to turn on dwt unit + stlink_write_debug32(sl, 0xE000EDFC, + stlink_read_debug32(sl, 0xE000EDFC) | (1<<24)); + + // make sure all watchpoints are cleared + for(int i = 0; i < DATA_WATCH_NUM; i++) { + data_watches[i].fun = WATCHDISABLED; + stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); + } } static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr, unsigned int len) { - int i = 0; - uint32_t mask; - - // computer mask - // find a free watchpoint - // configure - - mask = -1; - i = len; - while(i) { - i >>= 1; - mask++; - } - - if((mask != (uint32_t)-1) && (mask < 16)) { - for(i = 0; i < DATA_WATCH_NUM; i++) { - // is this an empty slot ? - if(data_watches[i].fun == WATCHDISABLED) { - #if DEBUG - printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len); - #endif - - data_watches[i].fun = wf; - data_watches[i].addr = addr; - data_watches[i].mask = mask; - - // insert comparator address - stlink_write_debug32(sl, 0xE0001020 + i * 16, addr); - - // insert mask - stlink_write_debug32(sl, 0xE0001024 + i * 16, mask); - - // insert function - stlink_write_debug32(sl, 0xE0001028 + i * 16, wf); - - // just to make sure the matched bit is clear ! - stlink_read_debug32(sl, 0xE0001028 + i * 16); - return 0; - } - } - } - - #if DEBUG - printf("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len); - #endif - return -1; + int i = 0; + uint32_t mask; + + // computer mask + // find a free watchpoint + // configure + + mask = -1; + i = len; + while(i) { + i >>= 1; + mask++; + } + + if((mask != (uint32_t)-1) && (mask < 16)) { + for(i = 0; i < DATA_WATCH_NUM; i++) { + // is this an empty slot ? + if(data_watches[i].fun == WATCHDISABLED) { +#if DEBUG + printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len); +#endif + + data_watches[i].fun = wf; + data_watches[i].addr = addr; + data_watches[i].mask = mask; + + // insert comparator address + stlink_write_debug32(sl, 0xE0001020 + i * 16, addr); + + // insert mask + stlink_write_debug32(sl, 0xE0001024 + i * 16, mask); + + // insert function + stlink_write_debug32(sl, 0xE0001028 + i * 16, wf); + + // just to make sure the matched bit is clear ! + stlink_read_debug32(sl, 0xE0001028 + i * 16); + return 0; + } + } + } + +#if DEBUG + printf("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len); +#endif + return -1; } static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { - int i; + int i; - for(i = 0 ; i < DATA_WATCH_NUM; i++) { - if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) { - #if DEBUG - printf("delete watchpoint %d addr %x\n", i, addr); - #endif + for(i = 0 ; i < DATA_WATCH_NUM; i++) { + if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) { +#if DEBUG + printf("delete watchpoint %d addr %x\n", i, addr); +#endif - data_watches[i].fun = WATCHDISABLED; - stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); + data_watches[i].fun = WATCHDISABLED; + stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); - return 0; - } - } + return 0; + } + } - #if DEBUG - printf("failure: delete watchpoint addr %x\n", addr); - #endif +#if DEBUG + printf("failure: delete watchpoint addr %x\n", addr); +#endif - return -1; + return -1; } #define CODE_BREAK_NUM 6 @@ -478,814 +477,813 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) #define CODE_BREAK_HIGH 0x02 struct code_hw_breakpoint { - stm32_addr_t addr; - int type; + stm32_addr_t addr; + int type; }; struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM]; static void init_code_breakpoints(stlink_t *sl) { - memset(sl->q_buf, 0, 4); - stlink_write_debug32(sl, CM3_REG_FP_CTRL, 0x03 /*KEY | ENABLE4*/); - unsigned int val = stlink_read_debug32(sl, CM3_REG_FP_CTRL); - if (((val & 3) != 1) || + memset(sl->q_buf, 0, 4); + stlink_write_debug32(sl, CM3_REG_FP_CTRL, 0x03 /*KEY | ENABLE4*/); + unsigned int val = stlink_read_debug32(sl, CM3_REG_FP_CTRL); + if (((val & 3) != 1) || ((((val >> 8) & 0x70) | ((val >> 4) & 0xf)) != CODE_BREAK_NUM) || (((val >> 8) & 0xf) != CODE_LIT_NUM)){ - fprintf(stderr, "[FP_CTRL] = 0x%08x expecting 0x%08x\n", val, - ((CODE_BREAK_NUM & 0x70) << 8) | (CODE_LIT_NUM << 8) | ((CODE_BREAK_NUM & 0xf) << 4) | 1); - } - + fprintf(stderr, "[FP_CTRL] = 0x%08x expecting 0x%08x\n", val, + ((CODE_BREAK_NUM & 0x70) << 8) | (CODE_LIT_NUM << 8) | ((CODE_BREAK_NUM & 0xf) << 4) | 1); + } + - for(int i = 0; i < CODE_BREAK_NUM; i++) { - code_breaks[i].type = 0; - stlink_write_debug32(sl, CM3_REG_FP_COMP0 + i * 4, 0); - } + for(int i = 0; i < CODE_BREAK_NUM; i++) { + code_breaks[i].type = 0; + stlink_write_debug32(sl, CM3_REG_FP_COMP0 + i * 4, 0); + } } static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { - stm32_addr_t fpb_addr = addr & ~0x3; - int type = addr & 0x2 ? CODE_BREAK_HIGH : CODE_BREAK_LOW; - - if(addr & 1) { - fprintf(stderr, "update_code_breakpoint: unaligned address %08x\n", addr); - return -1; - } - - int id = -1; - for(int i = 0; i < CODE_BREAK_NUM; i++) { - if(fpb_addr == code_breaks[i].addr || - (set && code_breaks[i].type == 0)) { - id = i; - break; - } - } - - if(id == -1) { - if(set) return -1; // Free slot not found - else return 0; // Breakpoint is already removed - } - - struct code_hw_breakpoint* brk = &code_breaks[id]; - - brk->addr = fpb_addr; - - if(set) brk->type |= type; - else brk->type &= ~type; - - if(brk->type == 0) { - #if DEBUG - printf("clearing hw break %d\n", id); - #endif - - stlink_write_debug32(sl, 0xe0002008 + id * 4, 0); - } else { - uint32_t mask = (brk->addr) | 1 | (brk->type << 30); - - #if DEBUG - printf("setting hw break %d at %08x (%d)\n", - id, brk->addr, brk->type); - printf("reg %08x \n", - mask); - #endif - - stlink_write_debug32(sl, 0xe0002008 + id * 4, mask); - } - - return 0; + stm32_addr_t fpb_addr = addr & ~0x3; + int type = addr & 0x2 ? CODE_BREAK_HIGH : CODE_BREAK_LOW; + + if(addr & 1) { + fprintf(stderr, "update_code_breakpoint: unaligned address %08x\n", addr); + return -1; + } + + int id = -1; + for(int i = 0; i < CODE_BREAK_NUM; i++) { + if(fpb_addr == code_breaks[i].addr || + (set && code_breaks[i].type == 0)) { + id = i; + break; + } + } + + if(id == -1) { + if(set) return -1; // Free slot not found + else return 0; // Breakpoint is already removed + } + + struct code_hw_breakpoint* brk = &code_breaks[id]; + + brk->addr = fpb_addr; + + if(set) brk->type |= type; + else brk->type &= ~type; + + if(brk->type == 0) { +#if DEBUG + printf("clearing hw break %d\n", id); +#endif + + stlink_write_debug32(sl, 0xe0002008 + id * 4, 0); + } else { + uint32_t mask = (brk->addr) | 1 | (brk->type << 30); + +#if DEBUG + printf("setting hw break %d at %08x (%d)\n", + id, brk->addr, brk->type); + printf("reg %08x \n", + mask); +#endif + + stlink_write_debug32(sl, 0xe0002008 + id * 4, mask); + } + + return 0; } struct flash_block { - stm32_addr_t addr; - unsigned length; - uint8_t* data; + stm32_addr_t addr; + unsigned length; + uint8_t* data; - struct flash_block* next; + struct flash_block* next; }; static struct flash_block* flash_root; static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { - if(addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) { - fprintf(stderr, "flash_add_block: incorrect bounds\n"); - return -1; - } + if(addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) { + fprintf(stderr, "flash_add_block: incorrect bounds\n"); + return -1; + } - stlink_calculate_pagesize(sl, addr); - if(addr % FLASH_PAGE != 0 || length % FLASH_PAGE != 0) { - fprintf(stderr, "flash_add_block: unaligned block\n"); - return -1; - } + stlink_calculate_pagesize(sl, addr); + if(addr % FLASH_PAGE != 0 || length % FLASH_PAGE != 0) { + fprintf(stderr, "flash_add_block: unaligned block\n"); + return -1; + } - struct flash_block* new = malloc(sizeof(struct flash_block)); - new->next = flash_root; + struct flash_block* new = malloc(sizeof(struct flash_block)); + new->next = flash_root; - new->addr = addr; - new->length = length; - new->data = calloc(length, 1); + new->addr = addr; + new->length = length; + new->data = calloc(length, 1); - flash_root = new; + flash_root = new; - return 0; + return 0; } static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { - unsigned int fit_blocks = 0, fit_length = 0; - - for(struct flash_block* fb = flash_root; fb; fb = fb->next) { - /* Block: ------X------Y-------- - * Data: a-----b - * a--b - * a-----------b - * Block intersects with data, if: - * a < Y && b > x - */ - - unsigned X = fb->addr, Y = fb->addr + fb->length; - unsigned a = addr, b = addr + length; - if(a < Y && b > X) { - // from start of the block - unsigned start = (a > X ? a : X) - X; - unsigned end = (b > Y ? Y : b) - X; - - memcpy(fb->data + start, data, end - start); - - fit_blocks++; - fit_length += end - start; - } - } - - if(fit_blocks == 0) { - fprintf(stderr, "Unfit data block %08x -> %04x\n", addr, length); - return -1; - } - - if(fit_length != length) { - fprintf(stderr, "warning: data block %08x -> %04x truncated to %04x\n", - addr, length, fit_length); - fprintf(stderr, "(this is not an error, just a GDB glitch)\n"); - } - - return 0; + unsigned int fit_blocks = 0, fit_length = 0; + + for(struct flash_block* fb = flash_root; fb; fb = fb->next) { + /* Block: ------X------Y-------- + * Data: a-----b + * a--b + * a-----------b + * Block intersects with data, if: + * a < Y && b > x + */ + + unsigned X = fb->addr, Y = fb->addr + fb->length; + unsigned a = addr, b = addr + length; + if(a < Y && b > X) { + // from start of the block + unsigned start = (a > X ? a : X) - X; + unsigned end = (b > Y ? Y : b) - X; + + memcpy(fb->data + start, data, end - start); + + fit_blocks++; + fit_length += end - start; + } + } + + if(fit_blocks == 0) { + fprintf(stderr, "Unfit data block %08x -> %04x\n", addr, length); + return -1; + } + + if(fit_length != length) { + fprintf(stderr, "warning: data block %08x -> %04x truncated to %04x\n", + addr, length, fit_length); + fprintf(stderr, "(this is not an error, just a GDB glitch)\n"); + } + + return 0; } static int flash_go(stlink_t *sl) { - int error = -1; + int error = -1; - // Some kinds of clock settings do not allow writing to flash. - stlink_reset(sl); + // Some kinds of clock settings do not allow writing to flash. + stlink_reset(sl); - for(struct flash_block* fb = flash_root; fb; fb = fb->next) { - #if DEBUG - printf("flash_do: block %08x -> %04x\n", fb->addr, fb->length); - #endif + for(struct flash_block* fb = flash_root; fb; fb = fb->next) { +#if DEBUG + printf("flash_do: block %08x -> %04x\n", fb->addr, fb->length); +#endif - unsigned length = fb->length; - for(stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += FLASH_PAGE) { + unsigned length = fb->length; + for(stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += FLASH_PAGE) { - //Update FLASH_PAGE - stlink_calculate_pagesize(sl, page); + //Update FLASH_PAGE + stlink_calculate_pagesize(sl, page); - #if DEBUG - printf("flash_do: page %08x\n", page); - #endif +#if DEBUG + printf("flash_do: page %08x\n", page); +#endif - if(stlink_write_flash(sl, page, fb->data + (page - fb->addr), - length > FLASH_PAGE ? FLASH_PAGE : length) < 0) - goto error; - } - } + if(stlink_write_flash(sl, page, fb->data + (page - fb->addr), + length > FLASH_PAGE ? FLASH_PAGE : length) < 0) + goto error; + } + } - stlink_reset(sl); + stlink_reset(sl); - error = 0; + error = 0; error: - for(struct flash_block* fb = flash_root, *next; fb; fb = next) { - next = fb->next; - free(fb->data); - free(fb); - } + for(struct flash_block* fb = flash_root, *next; fb; fb = next) { + next = fb->next; + free(fb->data); + free(fb); + } - flash_root = NULL; + flash_root = NULL; - return error; + return error; } int serve(stlink_t *sl, st_state_t *st) { - int sock = socket(AF_INET, SOCK_STREAM, 0); - if(sock < 0) { - perror("socket"); - return 1; - } - - unsigned int val = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); - - struct sockaddr_in serv_addr; - memset(&serv_addr,0,sizeof(struct sockaddr_in)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = INADDR_ANY; - serv_addr.sin_port = htons(st->listen_port); - - if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { - perror("bind"); - return 1; - } - - if(listen(sock, 5) < 0) { - perror("listen"); - return 1; - } - - printf("Listening at *:%d...\n", st->listen_port); - - int client = accept(sock, NULL, NULL); - //signal (SIGINT, SIG_DFL); - if(client < 0) { - perror("accept"); - return 1; - } - - close(sock); - - stlink_force_debug(sl); - if (st->reset) { - stlink_reset(sl); + int sock = socket(AF_INET, SOCK_STREAM, 0); + if(sock < 0) { + perror("socket"); + return 1; + } + + unsigned int val = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); + + struct sockaddr_in serv_addr; + memset(&serv_addr,0,sizeof(struct sockaddr_in)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(st->listen_port); + + if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { + perror("bind"); + return 1; + } + + if(listen(sock, 5) < 0) { + perror("listen"); + return 1; + } + + printf("Listening at *:%d...\n", st->listen_port); + + int client = accept(sock, NULL, NULL); + //signal (SIGINT, SIG_DFL); + if(client < 0) { + perror("accept"); + return 1; + } + + close(sock); + + stlink_force_debug(sl); + if (st->reset) { + stlink_reset(sl); } - init_code_breakpoints(sl); - init_data_watchpoints(sl); - - printf("GDB connected.\n"); - - /* - * To allow resetting the chip from GDB it is required to - * emulate attaching and detaching to target. - */ - unsigned int attached = 1; - - while(1) { - char* packet; - - int status = gdb_recv_packet(client, &packet); - if(status < 0) { - fprintf(stderr, "cannot recv: %d\n", status); - return 1; - } - - #if DEBUG - printf("recv: %s\n", packet); - #endif - - char* reply = NULL; - reg regp; - - switch(packet[0]) { - case 'q': { - if(packet[1] == 'P' || packet[1] == 'C' || packet[1] == 'L') { - reply = strdup(""); - break; - } - - char *separator = strstr(packet, ":"), *params = ""; - if(separator == NULL) { - separator = packet + strlen(packet); - } else { - params = separator + 1; - } - - unsigned queryNameLength = (separator - &packet[1]); - char* queryName = calloc(queryNameLength + 1, 1); - strncpy(queryName, &packet[1], queryNameLength); - - #if DEBUG - printf("query: %s;%s\n", queryName, params); - #endif - - if(!strcmp(queryName, "Supported")) { - if(sl->chip_id==STM32_CHIPID_F4) { - reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); + init_code_breakpoints(sl); + init_data_watchpoints(sl); + + printf("GDB connected.\n"); + + /* + * To allow resetting the chip from GDB it is required to + * emulate attaching and detaching to target. + */ + unsigned int attached = 1; + + while(1) { + char* packet; + + int status = gdb_recv_packet(client, &packet); + if(status < 0) { + fprintf(stderr, "cannot recv: %d\n", status); + return 1; + } + +#if DEBUG + printf("recv: %s\n", packet); +#endif + + char* reply = NULL; + reg regp; + + switch(packet[0]) { + case 'q': { + if(packet[1] == 'P' || packet[1] == 'C' || packet[1] == 'L') { + reply = strdup(""); + break; } - else { - reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); + + char *separator = strstr(packet, ":"), *params = ""; + if(separator == NULL) { + separator = packet + strlen(packet); + } else { + params = separator + 1; } - } else if(!strcmp(queryName, "Xfer")) { - char *type, *op, *__s_addr, *s_length; - char *tok = params; - char *annex __attribute__((unused)); - - type = strsep(&tok, ":"); - op = strsep(&tok, ":"); - annex = strsep(&tok, ":"); - __s_addr = strsep(&tok, ","); - s_length = tok; - - unsigned addr = strtoul(__s_addr, NULL, 16), - length = strtoul(s_length, NULL, 16); - - #if DEBUG - printf("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", - type, op, annex, addr, length); - #endif - - const char* data = NULL; - - if(!strcmp(type, "memory-map") && !strcmp(op, "read")) - data = current_memory_map; - - if(!strcmp(type, "features") && !strcmp(op, "read")) - data = target_description_F4; - - if(data) { - unsigned data_length = strlen(data); - if(addr + length > data_length) - length = data_length - addr; - - if(length == 0) { - reply = strdup("l"); - } else { - reply = calloc(length + 2, 1); - reply[0] = 'm'; - strncpy(&reply[1], data, length); - } - } - } else if(!strncmp(queryName, "Rcmd,",4)) { - // Rcmd uses the wrong separator - char *separator = strstr(packet, ","), *params = ""; - if(separator == NULL) { - separator = packet + strlen(packet); - } else { - params = separator + 1; - } - - - if (!strncmp(params,"726573756d65",12)) {// resume + + unsigned queryNameLength = (separator - &packet[1]); + char* queryName = calloc(queryNameLength + 1, 1); + strncpy(queryName, &packet[1], queryNameLength); + +#if DEBUG + printf("query: %s;%s\n", queryName, params); +#endif + + if(!strcmp(queryName, "Supported")) { + if(sl->chip_id==STM32_CHIPID_F4) { + reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); + } + else { + reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); + } + } else if(!strcmp(queryName, "Xfer")) { + char *type, *op, *__s_addr, *s_length; + char *tok = params; + char *annex __attribute__((unused)); + + type = strsep(&tok, ":"); + op = strsep(&tok, ":"); + annex = strsep(&tok, ":"); + __s_addr = strsep(&tok, ","); + s_length = tok; + + unsigned addr = strtoul(__s_addr, NULL, 16), + length = strtoul(s_length, NULL, 16); + +#if DEBUG + printf("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", + type, op, annex, addr, length); +#endif + + const char* data = NULL; + + if(!strcmp(type, "memory-map") && !strcmp(op, "read")) + data = current_memory_map; + + if(!strcmp(type, "features") && !strcmp(op, "read")) + data = target_description_F4; + + if(data) { + unsigned data_length = strlen(data); + if(addr + length > data_length) + length = data_length - addr; + + if(length == 0) { + reply = strdup("l"); + } else { + reply = calloc(length + 2, 1); + reply[0] = 'm'; + strncpy(&reply[1], data, length); + } + } + } else if(!strncmp(queryName, "Rcmd,",4)) { + // Rcmd uses the wrong separator + char *separator = strstr(packet, ","), *params = ""; + if(separator == NULL) { + separator = packet + strlen(packet); + } else { + params = separator + 1; + } + + + if (!strncmp(params,"726573756d65",12)) {// resume #if DEBUG - printf("Rcmd: resume\n"); + printf("Rcmd: resume\n"); #endif - stlink_run(sl); + stlink_run(sl); + + reply = strdup("OK"); + } else if (!strncmp(params,"68616c74",8)) { //halt + reply = strdup("OK"); - reply = strdup("OK"); - } else if (!strncmp(params,"68616c74",8)) { //halt - reply = strdup("OK"); + stlink_force_debug(sl); - stlink_force_debug(sl); +#if DEBUG + printf("Rcmd: halt\n"); +#endif + } else if (!strncmp(params,"6a7461675f7265736574",20)) { //jtag_reset + reply = strdup("OK"); + + stlink_jtag_reset(sl, 1); + stlink_jtag_reset(sl, 0); + stlink_force_debug(sl); #if DEBUG - printf("Rcmd: halt\n"); + printf("Rcmd: jtag_reset\n"); #endif - } else if (!strncmp(params,"6a7461675f7265736574",20)) { //jtag_reset - reply = strdup("OK"); + } else if (!strncmp(params,"7265736574",10)) { //reset + reply = strdup("OK"); - stlink_jtag_reset(sl, 1); - stlink_jtag_reset(sl, 0); - stlink_force_debug(sl); + stlink_force_debug(sl); + stlink_reset(sl); + init_code_breakpoints(sl); + init_data_watchpoints(sl); #if DEBUG - printf("Rcmd: jtag_reset\n"); + printf("Rcmd: reset\n"); +#endif + } else { +#if DEBUG + printf("Rcmd: %s\n", params); #endif - } else if (!strncmp(params,"7265736574",10)) { //reset - reply = strdup("OK"); - stlink_force_debug(sl); - stlink_reset(sl); - init_code_breakpoints(sl); - init_data_watchpoints(sl); + } + + } + + if(reply == NULL) + reply = strdup(""); + + free(queryName); + + break; + } + + case 'v': { + char *params = NULL; + char *cmdName = strtok_r(packet, ":;", ¶ms); + + cmdName++; // vCommand -> Command + + if(!strcmp(cmdName, "FlashErase")) { + char *__s_addr, *s_length; + char *tok = params; + + __s_addr = strsep(&tok, ","); + s_length = tok; + + unsigned addr = strtoul(__s_addr, NULL, 16), + length = strtoul(s_length, NULL, 16); #if DEBUG - printf("Rcmd: reset\n"); + printf("FlashErase: addr:%08x,len:%04x\n", + addr, length); #endif - } else { + + if(flash_add_block(addr, length, sl) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + } + } else if(!strcmp(cmdName, "FlashWrite")) { + char *__s_addr, *data; + char *tok = params; + + __s_addr = strsep(&tok, ":"); + data = tok; + + unsigned addr = strtoul(__s_addr, NULL, 16); + unsigned data_length = status - (data - packet); + + // Length of decoded data cannot be more than + // encoded, as escapes are removed. + // Additional byte is reserved for alignment fix. + uint8_t *decoded = calloc(data_length + 1, 1); + unsigned dec_index = 0; + for(unsigned int i = 0; i < data_length; i++) { + if(data[i] == 0x7d) { + i++; + decoded[dec_index++] = data[i] ^ 0x20; + } else { + decoded[dec_index++] = data[i]; + } + } + + // Fix alignment + if(dec_index % 2 != 0) + dec_index++; + #if DEBUG - printf("Rcmd: %s\n", params); + printf("binary packet %d -> %d\n", data_length, dec_index); #endif - } - - } - - if(reply == NULL) - reply = strdup(""); - - free(queryName); - - break; - } - - case 'v': { - char *params = NULL; - char *cmdName = strtok_r(packet, ":;", ¶ms); - - cmdName++; // vCommand -> Command - - if(!strcmp(cmdName, "FlashErase")) { - char *__s_addr, *s_length; - char *tok = params; - - __s_addr = strsep(&tok, ","); - s_length = tok; - - unsigned addr = strtoul(__s_addr, NULL, 16), - length = strtoul(s_length, NULL, 16); - - #if DEBUG - printf("FlashErase: addr:%08x,len:%04x\n", - addr, length); - #endif - - if(flash_add_block(addr, length, sl) < 0) { - reply = strdup("E00"); - } else { - reply = strdup("OK"); - } - } else if(!strcmp(cmdName, "FlashWrite")) { - char *__s_addr, *data; - char *tok = params; - - __s_addr = strsep(&tok, ":"); - data = tok; - - unsigned addr = strtoul(__s_addr, NULL, 16); - unsigned data_length = status - (data - packet); - - // Length of decoded data cannot be more than - // encoded, as escapes are removed. - // Additional byte is reserved for alignment fix. - uint8_t *decoded = calloc(data_length + 1, 1); - unsigned dec_index = 0; - for(unsigned int i = 0; i < data_length; i++) { - if(data[i] == 0x7d) { - i++; - decoded[dec_index++] = data[i] ^ 0x20; - } else { - decoded[dec_index++] = data[i]; - } - } - - // Fix alignment - if(dec_index % 2 != 0) - dec_index++; - - #if DEBUG - printf("binary packet %d -> %d\n", data_length, dec_index); - #endif - - if(flash_populate(addr, decoded, dec_index) < 0) { - reply = strdup("E00"); - } else { - reply = strdup("OK"); - } - } else if(!strcmp(cmdName, "FlashDone")) { - if(flash_go(sl) < 0) { - reply = strdup("E00"); - } else { - reply = strdup("OK"); - } - } else if(!strcmp(cmdName, "Kill")) { - attached = 0; - - reply = strdup("OK"); - } - - if(reply == NULL) - reply = strdup(""); - - break; - } - - case 'c': - stlink_run(sl); - - while(1) { - int status = gdb_check_for_interrupt(client); - if(status < 0) { - fprintf(stderr, "cannot check for int: %d\n", status); - return 1; - } - - if(status == 1) { - stlink_force_debug(sl); - break; - } - - stlink_status(sl); - if(sl->core_stat == STLINK_CORE_HALTED) { - break; - } - - usleep(100000); - } - - reply = strdup("S05"); // TRAP - break; - - case 's': - stlink_step(sl); - - reply = strdup("S05"); // TRAP - break; - - case '?': - if(attached) { - reply = strdup("S05"); // TRAP - } else { - /* Stub shall reply OK if not attached. */ - reply = strdup("OK"); - } - break; - - case 'g': - stlink_read_all_regs(sl, ®p); - - reply = calloc(8 * 16 + 1, 1); - for(int i = 0; i < 16; i++) - sprintf(&reply[i * 8], "%08x", htonl(regp.r[i])); - - break; - - case 'p': { - unsigned id = strtoul(&packet[1], NULL, 16); - unsigned myreg = 0xDEADDEAD; - - if(id < 16) { - stlink_read_reg(sl, id, ®p); - myreg = htonl(regp.r[id]); - } else if(id == 0x19) { - stlink_read_reg(sl, 16, ®p); - myreg = htonl(regp.xpsr); - } else if(id == 0x1A) { - stlink_read_reg(sl, 17, ®p); - myreg = htonl(regp.main_sp); - } else if(id == 0x1B) { - stlink_read_reg(sl, 18, ®p); - myreg = htonl(regp.process_sp); - } else if(id == 0x1C) { - stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.control); - } else if(id == 0x1D) { - stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.faultmask); - } else if(id == 0x1E) { - stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.basepri); - } else if(id == 0x1F) { - stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.primask); - } else if(id >= 0x20 && id < 0x40) { - stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.s[id-0x20]); - } else if(id == 0x40) { - stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.fpscr); - } else { - reply = strdup("E00"); - } - - reply = calloc(8 + 1, 1); - sprintf(reply, "%08x", myreg); - - break; - } - - case 'P': { - char* s_reg = &packet[1]; - char* s_value = strstr(&packet[1], "=") + 1; - - unsigned reg = strtoul(s_reg, NULL, 16); - unsigned value = strtoul(s_value, NULL, 16); - - if(reg < 16) { - stlink_write_reg(sl, ntohl(value), reg); - } else if(reg == 0x19) { - stlink_write_reg(sl, ntohl(value), 16); - } else if(reg == 0x1A) { - stlink_write_reg(sl, ntohl(value), 17); - } else if(reg == 0x1B) { - stlink_write_reg(sl, ntohl(value), 18); - } else if(reg == 0x1C) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x1D) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x1E) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x1F) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg >= 0x20 && reg < 0x40) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x40) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else { - reply = strdup("E00"); - } - - if(!reply) { - reply = strdup("OK"); - } - - break; - } - - case 'G': - for(int i = 0; i < 16; i++) { - char str[9] = {0}; - strncpy(str, &packet[1 + i * 8], 8); - uint32_t reg = strtoul(str, NULL, 16); - stlink_write_reg(sl, ntohl(reg), i); - } - - reply = strdup("OK"); - break; - - case 'm': { - char* s_start = &packet[1]; - char* s_count = strstr(&packet[1], ",") + 1; - - stm32_addr_t start = strtoul(s_start, NULL, 16); - unsigned count = strtoul(s_count, NULL, 16); - - unsigned adj_start = start % 4; - unsigned count_rnd = (count + adj_start + 4 - 1) / 4 * 4; - - stlink_read_mem32(sl, start - adj_start, count_rnd); - - reply = calloc(count * 2 + 1, 1); - for(unsigned int i = 0; i < count; i++) { - reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4]; - reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf]; - } - - break; - } - - case 'M': { - char* s_start = &packet[1]; - char* s_count = strstr(&packet[1], ",") + 1; - char* hexdata = strstr(packet, ":") + 1; - - stm32_addr_t start = strtoul(s_start, NULL, 16); - unsigned count = strtoul(s_count, NULL, 16); - - if(start % 4) { - unsigned align_count = 4 - start % 4; - if (align_count > count) align_count = count; - for(unsigned int i = 0; i < align_count; i ++) { - char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; - uint8_t byte = strtoul(hex, NULL, 16); - sl->q_buf[i] = byte; - } - stlink_write_mem8(sl, start, align_count); - start += align_count; - count -= align_count; - hexdata += 2*align_count; - } - - if(count - count % 4) { - unsigned aligned_count = count - count % 4; - - for(unsigned int i = 0; i < aligned_count; i ++) { - char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; - uint8_t byte = strtoul(hex, NULL, 16); - sl->q_buf[i] = byte; - } - stlink_write_mem32(sl, start, aligned_count); - count -= aligned_count; - start += aligned_count; - hexdata += 2*aligned_count; - } - - if(count) { - for(unsigned int i = 0; i < count; i ++) { - char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; - uint8_t byte = strtoul(hex, NULL, 16); - sl->q_buf[i] = byte; - } - stlink_write_mem8(sl, start, count); - } - reply = strdup("OK"); - break; - } - - case 'Z': { - char *endptr; - stm32_addr_t addr = strtoul(&packet[3], &endptr, 16); - stm32_addr_t len = strtoul(&endptr[1], NULL, 16); - - switch (packet[1]) { - case '1': - if(update_code_breakpoint(sl, addr, 1) < 0) { - reply = strdup("E00"); - } else { - reply = strdup("OK"); - } - break; - - case '2': // insert write watchpoint - case '3': // insert read watchpoint - case '4': // insert access watchpoint - { - enum watchfun wf; - if(packet[1] == '2') { - wf = WATCHWRITE; - } else if(packet[1] == '3') { - wf = WATCHREAD; - } else { - wf = WATCHACCESS; - } - - if(add_data_watchpoint(sl, wf, addr, len) < 0) { + if(flash_populate(addr, decoded, dec_index) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + } + } else if(!strcmp(cmdName, "FlashDone")) { + if(flash_go(sl) < 0) { reply = strdup("E00"); } else { reply = strdup("OK"); + } + } else if(!strcmp(cmdName, "Kill")) { + attached = 0; + + reply = strdup("OK"); + } + + if(reply == NULL) + reply = strdup(""); + + break; + } + + case 'c': + stlink_run(sl); + + while(1) { + int status = gdb_check_for_interrupt(client); + if(status < 0) { + fprintf(stderr, "cannot check for int: %d\n", status); + return 1; + } + + if(status == 1) { + stlink_force_debug(sl); + break; + } + + stlink_status(sl); + if(sl->core_stat == STLINK_CORE_HALTED) { + break; + } + + usleep(100000); + } + + reply = strdup("S05"); // TRAP + break; + + case 's': + stlink_step(sl); + + reply = strdup("S05"); // TRAP + break; + + case '?': + if(attached) { + reply = strdup("S05"); // TRAP + } else { + /* Stub shall reply OK if not attached. */ + reply = strdup("OK"); + } + break; + + case 'g': + stlink_read_all_regs(sl, ®p); + + reply = calloc(8 * 16 + 1, 1); + for(int i = 0; i < 16; i++) + sprintf(&reply[i * 8], "%08x", htonl(regp.r[i])); + + break; + + case 'p': { + unsigned id = strtoul(&packet[1], NULL, 16); + unsigned myreg = 0xDEADDEAD; + + if(id < 16) { + stlink_read_reg(sl, id, ®p); + myreg = htonl(regp.r[id]); + } else if(id == 0x19) { + stlink_read_reg(sl, 16, ®p); + myreg = htonl(regp.xpsr); + } else if(id == 0x1A) { + stlink_read_reg(sl, 17, ®p); + myreg = htonl(regp.main_sp); + } else if(id == 0x1B) { + stlink_read_reg(sl, 18, ®p); + myreg = htonl(regp.process_sp); + } else if(id == 0x1C) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.control); + } else if(id == 0x1D) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.faultmask); + } else if(id == 0x1E) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.basepri); + } else if(id == 0x1F) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.primask); + } else if(id >= 0x20 && id < 0x40) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.s[id-0x20]); + } else if(id == 0x40) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.fpscr); + } else { + reply = strdup("E00"); + } + + reply = calloc(8 + 1, 1); + sprintf(reply, "%08x", myreg); + + break; + } + + case 'P': { + char* s_reg = &packet[1]; + char* s_value = strstr(&packet[1], "=") + 1; + + unsigned reg = strtoul(s_reg, NULL, 16); + unsigned value = strtoul(s_value, NULL, 16); + + if(reg < 16) { + stlink_write_reg(sl, ntohl(value), reg); + } else if(reg == 0x19) { + stlink_write_reg(sl, ntohl(value), 16); + } else if(reg == 0x1A) { + stlink_write_reg(sl, ntohl(value), 17); + } else if(reg == 0x1B) { + stlink_write_reg(sl, ntohl(value), 18); + } else if(reg == 0x1C) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x1D) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x1E) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x1F) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg >= 0x20 && reg < 0x40) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x40) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else { + reply = strdup("E00"); + } + + if(!reply) { + reply = strdup("OK"); + } + + break; + } + + case 'G': + for(int i = 0; i < 16; i++) { + char str[9] = {0}; + strncpy(str, &packet[1 + i * 8], 8); + uint32_t reg = strtoul(str, NULL, 16); + stlink_write_reg(sl, ntohl(reg), i); + } + + reply = strdup("OK"); + break; + + case 'm': { + char* s_start = &packet[1]; + char* s_count = strstr(&packet[1], ",") + 1; + + stm32_addr_t start = strtoul(s_start, NULL, 16); + unsigned count = strtoul(s_count, NULL, 16); + + unsigned adj_start = start % 4; + unsigned count_rnd = (count + adj_start + 4 - 1) / 4 * 4; + + stlink_read_mem32(sl, start - adj_start, count_rnd); + + reply = calloc(count * 2 + 1, 1); + for(unsigned int i = 0; i < count; i++) { + reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4]; + reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf]; + } + + break; + } + + case 'M': { + char* s_start = &packet[1]; + char* s_count = strstr(&packet[1], ",") + 1; + char* hexdata = strstr(packet, ":") + 1; + + stm32_addr_t start = strtoul(s_start, NULL, 16); + unsigned count = strtoul(s_count, NULL, 16); + + if(start % 4) { + unsigned align_count = 4 - start % 4; + if (align_count > count) align_count = count; + for(unsigned int i = 0; i < align_count; i ++) { + char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; + uint8_t byte = strtoul(hex, NULL, 16); + sl->q_buf[i] = byte; + } + stlink_write_mem8(sl, start, align_count); + start += align_count; + count -= align_count; + hexdata += 2*align_count; + } + + if(count - count % 4) { + unsigned aligned_count = count - count % 4; + + for(unsigned int i = 0; i < aligned_count; i ++) { + char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; + uint8_t byte = strtoul(hex, NULL, 16); + sl->q_buf[i] = byte; + } + stlink_write_mem32(sl, start, aligned_count); + count -= aligned_count; + start += aligned_count; + hexdata += 2*aligned_count; + } + + if(count) { + for(unsigned int i = 0; i < count; i ++) { + char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; + uint8_t byte = strtoul(hex, NULL, 16); + sl->q_buf[i] = byte; + } + stlink_write_mem8(sl, start, count); + } + reply = strdup("OK"); + break; + } + + case 'Z': { + char *endptr; + stm32_addr_t addr = strtoul(&packet[3], &endptr, 16); + stm32_addr_t len = strtoul(&endptr[1], NULL, 16); + + switch (packet[1]) { + case '1': + if(update_code_breakpoint(sl, addr, 1) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + } break; + + case '2': // insert write watchpoint + case '3': // insert read watchpoint + case '4': { // insert access watchpoint + enum watchfun wf; + if(packet[1] == '2') { + wf = WATCHWRITE; + } else if(packet[1] == '3') { + wf = WATCHREAD; + } else { + wf = WATCHACCESS; + } + + if(add_data_watchpoint(sl, wf, addr, len) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + break; + } } - } - - default: - reply = strdup(""); - } - break; - } - case 'z': { - char *endptr; - stm32_addr_t addr = strtoul(&packet[3], &endptr, 16); - //stm32_addr_t len = strtoul(&endptr[1], NULL, 16); - - switch (packet[1]) { - case '1': // remove breakpoint - update_code_breakpoint(sl, addr, 0); - reply = strdup("OK"); - break; - - case '2' : // remove write watchpoint - case '3' : // remove read watchpoint - case '4' : // remove access watchpoint - if(delete_data_watchpoint(sl, addr) < 0) { - reply = strdup("E00"); - } else { - reply = strdup("OK"); - break; - } - - default: - reply = strdup(""); - } - break; - } - - case '!': { - /* - * Enter extended mode which allows restarting. - * We do support that always. - */ - - /* - * Also, set to persistent mode - * to allow GDB disconnect. - */ - st->persistent = 1; - - reply = strdup("OK"); - - break; - } - - case 'R': { - /* Reset the core. */ - - stlink_reset(sl); - init_code_breakpoints(sl); - init_data_watchpoints(sl); - - attached = 1; - - reply = strdup("OK"); - - break; - } - - default: - reply = strdup(""); - } - - if(reply) { - #if DEBUG - printf("send: %s\n", reply); - #endif - - int result = gdb_send_packet(client, reply); - if(result != 0) { - fprintf(stderr, "cannot send: %d\n", result); - free(reply); - free(packet); - return 1; - } - - free(reply); - } - - free(packet); - } - - return 0; + + default: + reply = strdup(""); + } + break; + } + case 'z': { + char *endptr; + stm32_addr_t addr = strtoul(&packet[3], &endptr, 16); + //stm32_addr_t len = strtoul(&endptr[1], NULL, 16); + + switch (packet[1]) { + case '1': // remove breakpoint + update_code_breakpoint(sl, addr, 0); + reply = strdup("OK"); + break; + + case '2' : // remove write watchpoint + case '3' : // remove read watchpoint + case '4' : // remove access watchpoint + if(delete_data_watchpoint(sl, addr) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + break; + } + + default: + reply = strdup(""); + } + break; + } + + case '!': { + /* + * Enter extended mode which allows restarting. + * We do support that always. + */ + + /* + * Also, set to persistent mode + * to allow GDB disconnect. + */ + st->persistent = 1; + + reply = strdup("OK"); + + break; + } + + case 'R': { + /* Reset the core. */ + + stlink_reset(sl); + init_code_breakpoints(sl); + init_data_watchpoints(sl); + + attached = 1; + + reply = strdup("OK"); + + break; + } + + default: + reply = strdup(""); + } + + if(reply) { +#if DEBUG + printf("send: %s\n", reply); +#endif + + int result = gdb_send_packet(client, reply); + if(result != 0) { + fprintf(stderr, "cannot send: %d\n", result); + free(reply); + free(packet); + return 1; + } + + free(reply); + } + + free(packet); + } + + return 0; } diff --git a/gui/stlink-gui.c b/gui/stlink-gui.c index 3646c3a4f..f60e92db0 100644 --- a/gui/stlink-gui.c +++ b/gui/stlink-gui.c @@ -17,117 +17,117 @@ G_DEFINE_TYPE (STlinkGUI, stlink_gui, G_TYPE_OBJECT); static void stlink_gui_dispose (GObject *gobject) { - G_OBJECT_CLASS (stlink_gui_parent_class)->dispose (gobject); + G_OBJECT_CLASS (stlink_gui_parent_class)->dispose (gobject); } static void stlink_gui_finalize (GObject *gobject) { - G_OBJECT_CLASS (stlink_gui_parent_class)->finalize (gobject); + G_OBJECT_CLASS (stlink_gui_parent_class)->finalize (gobject); } static void stlink_gui_class_init (STlinkGUIClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - gobject_class->dispose = stlink_gui_dispose; - gobject_class->finalize = stlink_gui_finalize; + gobject_class->dispose = stlink_gui_dispose; + gobject_class->finalize = stlink_gui_finalize; } static void stlink_gui_init (STlinkGUI *self) { - self->sl = NULL; - self->filename = NULL; + self->sl = NULL; + self->filename = NULL; - self->progress.activity_mode = FALSE; - self->progress.fraction = 0; + self->progress.activity_mode = FALSE; + self->progress.fraction = 0; - self->flash_mem.memory = NULL; - self->flash_mem.size = 0; - self->flash_mem.base = 0; + self->flash_mem.memory = NULL; + self->flash_mem.size = 0; + self->flash_mem.base = 0; - self->file_mem.memory = NULL; - self->file_mem.size = 0; - self->file_mem.base = 0; + self->file_mem.memory = NULL; + self->file_mem.size = 0; + self->file_mem.base = 0; } static gboolean set_info_error_message_idle (STlinkGUI *gui) { - if (gui->error_message != NULL) { - gchar *markup; + if (gui->error_message != NULL) { + gchar *markup; - markup = g_markup_printf_escaped ("%s", gui->error_message); - gtk_label_set_markup (gui->infolabel, markup); - gtk_info_bar_set_message_type (gui->infobar, GTK_MESSAGE_ERROR); - gtk_widget_show (GTK_WIDGET (gui->infobar)); + markup = g_markup_printf_escaped ("%s", gui->error_message); + gtk_label_set_markup (gui->infolabel, markup); + gtk_info_bar_set_message_type (gui->infobar, GTK_MESSAGE_ERROR); + gtk_widget_show (GTK_WIDGET (gui->infobar)); - g_free (markup); - g_free (gui->error_message); - gui->error_message = NULL; - } - return FALSE; + g_free (markup); + g_free (gui->error_message); + gui->error_message = NULL; + } + return FALSE; } static void stlink_gui_set_info_error_message (STlinkGUI *gui, const gchar *message) { - gui->error_message = g_strdup (message); - g_idle_add ((GSourceFunc) set_info_error_message_idle, gui); + gui->error_message = g_strdup (message); + g_idle_add ((GSourceFunc) set_info_error_message_idle, gui); } static void stlink_gui_set_sensitivity (STlinkGUI *gui, gboolean sensitivity) { - gtk_widget_set_sensitive (GTK_WIDGET (gui->open_button), sensitivity); + gtk_widget_set_sensitive (GTK_WIDGET (gui->open_button), sensitivity); - if (sensitivity && gui->sl) - gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), sensitivity); + if (sensitivity && gui->sl) + gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), sensitivity); - if (sensitivity && !gui->sl) - gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), sensitivity); + if (sensitivity && !gui->sl) + gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), sensitivity); - if (sensitivity && gui->sl && gui->filename) - gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), sensitivity); + if (sensitivity && gui->sl && gui->filename) + gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), sensitivity); } static void mem_view_init_headers (GtkTreeView *view) { - GtkCellRenderer *renderer; - gint i; - - g_return_if_fail (view != NULL); - - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_insert_column_with_attributes (view, - -1, - "Address", - renderer, - "text", - 0, /* column */ - NULL); - for (i = 0; i < 4; i++) { - gchar *label; - - label = g_strdup_printf ("%X", i * 4); - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_insert_column_with_attributes (view, - -1, - label, - renderer, - "text", - (i + 1), /* column */ - NULL); - g_free (label); - } - - for (i = 0; i < 5; i++) { - GtkTreeViewColumn *column = gtk_tree_view_get_column (view, i); - gtk_tree_view_column_set_expand (column, TRUE); - } + GtkCellRenderer *renderer; + gint i; + + g_return_if_fail (view != NULL); + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (view, + -1, + "Address", + renderer, + "text", + 0, /* column */ + NULL); + for (i = 0; i < 4; i++) { + gchar *label; + + label = g_strdup_printf ("%X", i * 4); + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (view, + -1, + label, + renderer, + "text", + (i + 1), /* column */ + NULL); + g_free (label); + } + + for (i = 0; i < 5; i++) { + GtkTreeViewColumn *column = gtk_tree_view_get_column (view, i); + gtk_tree_view_column_set_expand (column, TRUE); + } } static void @@ -136,11 +136,11 @@ mem_view_add_as_hex (GtkListStore *store, gint column, guint32 value) { - gchar *hex_str; + gchar *hex_str; - hex_str = g_strdup_printf ("0x%08X", value); - gtk_list_store_set (store, iter, column, hex_str, -1); - g_free (hex_str); + hex_str = g_strdup_printf ("0x%08X", value); + gtk_list_store_set (store, iter, column, hex_str, -1); + g_free (hex_str); } static void @@ -150,194 +150,194 @@ mem_view_add_buffer (GtkListStore *store, guchar *buffer, gint len) { - guint32 *word; - gint i, step; - gint column = 0; + guint32 *word; + gint i, step; + gint column = 0; - step = sizeof (*word); + step = sizeof (*word); - for (i = 0; i < len; i += step) { - word = (guint *) &buffer[i]; + for (i = 0; i < len; i += step) { + word = (guint *) &buffer[i]; - if (column == 0) { - /* new row */ - gtk_list_store_append (store, iter); + if (column == 0) { + /* new row */ + gtk_list_store_append (store, iter); - /* add address */ - mem_view_add_as_hex (store, iter, column, (address + i)); - } - mem_view_add_as_hex (store, iter, (column + 1), *word); - column = (column + 1) % step; - } + /* add address */ + mem_view_add_as_hex (store, iter, column, (address + i)); + } + mem_view_add_as_hex (store, iter, (column + 1), *word); + column = (column + 1) % step; + } } static guint32 hexstr_to_guint32 (const gchar *str, GError **err) { - guint32 val; - gchar *end_ptr; + guint32 val; + gchar *end_ptr; - val = strtoul (str, &end_ptr, 16); - if ((errno == ERANGE && val == LONG_MAX) || (errno != 0 && val == 0)) { - g_set_error (err, - g_quark_from_string ("hextou32"), - 1, - "Invalid hexstring"); - return LONG_MAX; - } - if (end_ptr == str) { - g_set_error (err, - g_quark_from_string ("hextou32"), - 2, - "Invalid hexstring"); - return LONG_MAX; - } - return val; + val = strtoul (str, &end_ptr, 16); + if ((errno == ERANGE && val == LONG_MAX) || (errno != 0 && val == 0)) { + g_set_error (err, + g_quark_from_string ("hextou32"), + 1, + "Invalid hexstring"); + return LONG_MAX; + } + if (end_ptr == str) { + g_set_error (err, + g_quark_from_string ("hextou32"), + 2, + "Invalid hexstring"); + return LONG_MAX; + } + return val; } static void stlink_gui_update_mem_view (STlinkGUI *gui, struct mem_t *mem, GtkTreeView *view) { - GtkListStore *store; - GtkTreeIter iter; + GtkListStore *store; + GtkTreeIter iter; - store = GTK_LIST_STORE (gtk_tree_view_get_model (view)); + store = GTK_LIST_STORE (gtk_tree_view_get_model (view)); - mem_view_add_buffer (store, - &iter, - mem->base, - mem->memory, - mem->size); + mem_view_add_buffer (store, + &iter, + mem->base, + mem->memory, + mem->size); - gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); - gtk_progress_bar_set_fraction (gui->progress.bar, 0); - stlink_gui_set_sensitivity (gui, TRUE); + gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); + gtk_progress_bar_set_fraction (gui->progress.bar, 0); + stlink_gui_set_sensitivity (gui, TRUE); } static gboolean stlink_gui_update_devmem_view (STlinkGUI *gui) { - stlink_gui_update_mem_view (gui, &gui->flash_mem, gui->devmem_treeview); - return FALSE; + stlink_gui_update_mem_view (gui, &gui->flash_mem, gui->devmem_treeview); + return FALSE; } static void stlink_gui_populate_devmem_view (STlinkGUI *gui) { - guint off; - stm32_addr_t addr; - - g_return_if_fail (gui != NULL); - g_return_if_fail (gui->sl != NULL); - - addr = gui->sl->flash_base; - - if (gui->flash_mem.memory) { - g_free (gui->flash_mem.memory); - } - gui->flash_mem.memory = g_malloc (gui->sl->flash_size); - gui->flash_mem.size = gui->sl->flash_size; - gui->flash_mem.base = gui->sl->flash_base; - - for (off = 0; off < gui->sl->flash_size; off += MEM_READ_SIZE) { - guint n_read = MEM_READ_SIZE; - - if (off + MEM_READ_SIZE > gui->sl->flash_size) { - n_read = gui->sl->flash_size - off; - - /* align if needed */ - if (n_read & 3) { - n_read = (n_read + 4) & ~(3); - } - } - /* reads to sl->q_buf */ - stlink_read_mem32(gui->sl, addr + off, n_read); - if (gui->sl->q_len < 0) { - stlink_gui_set_info_error_message (gui, "Failed to read memory"); - g_free (gui->flash_mem.memory); - gui->flash_mem.memory = NULL; - return; - } - memcpy (gui->flash_mem.memory + off, gui->sl->q_buf, n_read); - gui->progress.fraction = (gdouble) (off + n_read) / gui->sl->flash_size; - } - g_idle_add ((GSourceFunc) stlink_gui_update_devmem_view, gui); + guint off; + stm32_addr_t addr; + + g_return_if_fail (gui != NULL); + g_return_if_fail (gui->sl != NULL); + + addr = gui->sl->flash_base; + + if (gui->flash_mem.memory) { + g_free (gui->flash_mem.memory); + } + gui->flash_mem.memory = g_malloc (gui->sl->flash_size); + gui->flash_mem.size = gui->sl->flash_size; + gui->flash_mem.base = gui->sl->flash_base; + + for (off = 0; off < gui->sl->flash_size; off += MEM_READ_SIZE) { + guint n_read = MEM_READ_SIZE; + + if (off + MEM_READ_SIZE > gui->sl->flash_size) { + n_read = gui->sl->flash_size - off; + + /* align if needed */ + if (n_read & 3) { + n_read = (n_read + 4) & ~(3); + } + } + /* reads to sl->q_buf */ + stlink_read_mem32(gui->sl, addr + off, n_read); + if (gui->sl->q_len < 0) { + stlink_gui_set_info_error_message (gui, "Failed to read memory"); + g_free (gui->flash_mem.memory); + gui->flash_mem.memory = NULL; + return; + } + memcpy (gui->flash_mem.memory + off, gui->sl->q_buf, n_read); + gui->progress.fraction = (gdouble) (off + n_read) / gui->sl->flash_size; + } + g_idle_add ((GSourceFunc) stlink_gui_update_devmem_view, gui); } static gboolean stlink_gui_update_filemem_view (STlinkGUI *gui) { - gchar *basename; + gchar *basename; - basename = g_path_get_basename (gui->filename); - gtk_notebook_set_tab_label_text (gui->notebook, - GTK_WIDGET (gtk_notebook_get_nth_page (gui->notebook, 1)), - basename); - g_free (basename); + basename = g_path_get_basename (gui->filename); + gtk_notebook_set_tab_label_text (gui->notebook, + GTK_WIDGET (gtk_notebook_get_nth_page (gui->notebook, 1)), + basename); + g_free (basename); - stlink_gui_update_mem_view (gui, &gui->file_mem, gui->filemem_treeview); + stlink_gui_update_mem_view (gui, &gui->file_mem, gui->filemem_treeview); - return FALSE; + return FALSE; } static gpointer stlink_gui_populate_filemem_view (STlinkGUI *gui) { - guchar buffer[MEM_READ_SIZE]; - GFile *file; - GFileInfo *file_info; - GInputStream *input_stream; - gint off; - GError *err = NULL; - - g_return_val_if_fail (gui != NULL, NULL); - g_return_val_if_fail (gui->filename != NULL, NULL); - - file = g_file_new_for_path (gui->filename); - input_stream = G_INPUT_STREAM (g_file_read (file, NULL, &err)); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out; - } - - file_info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (input_stream), - G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, &err); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out_input; - } - if (gui->file_mem.memory) { - g_free (gui->file_mem.memory); - } - gui->file_mem.size = g_file_info_get_size (file_info); - gui->file_mem.memory = g_malloc (gui->file_mem.size); - - for (off = 0; off < gui->file_mem.size; off += MEM_READ_SIZE) { - guint n_read = MEM_READ_SIZE; - - if (off + MEM_READ_SIZE > gui->file_mem.size) { - n_read = gui->file_mem.size - off; - } - - if (g_input_stream_read (G_INPUT_STREAM (input_stream), - &buffer, n_read, NULL, &err) == -1) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out_input; - } - memcpy (gui->file_mem.memory + off, buffer, n_read); - gui->progress.fraction = (gdouble) (off + n_read) / gui->file_mem.size; - } - g_idle_add ((GSourceFunc) stlink_gui_update_filemem_view, gui); - - out_input: - g_object_unref (input_stream); - out: - g_object_unref (file); - return NULL; + guchar buffer[MEM_READ_SIZE]; + GFile *file; + GFileInfo *file_info; + GInputStream *input_stream; + gint off; + GError *err = NULL; + + g_return_val_if_fail (gui != NULL, NULL); + g_return_val_if_fail (gui->filename != NULL, NULL); + + file = g_file_new_for_path (gui->filename); + input_stream = G_INPUT_STREAM (g_file_read (file, NULL, &err)); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out; + } + + file_info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (input_stream), + G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, &err); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out_input; + } + if (gui->file_mem.memory) { + g_free (gui->file_mem.memory); + } + gui->file_mem.size = g_file_info_get_size (file_info); + gui->file_mem.memory = g_malloc (gui->file_mem.size); + + for (off = 0; off < gui->file_mem.size; off += MEM_READ_SIZE) { + guint n_read = MEM_READ_SIZE; + + if (off + MEM_READ_SIZE > gui->file_mem.size) { + n_read = gui->file_mem.size - off; + } + + if (g_input_stream_read (G_INPUT_STREAM (input_stream), + &buffer, n_read, NULL, &err) == -1) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out_input; + } + memcpy (gui->file_mem.memory + off, buffer, n_read); + gui->progress.fraction = (gdouble) (off + n_read) / gui->file_mem.size; + } + g_idle_add ((GSourceFunc) stlink_gui_update_filemem_view, gui); + +out_input: + g_object_unref (input_stream); +out: + g_object_unref (file); + return NULL; } static void mem_jmp (GtkTreeView *view, @@ -346,362 +346,362 @@ static void mem_jmp (GtkTreeView *view, gsize size, GError **err) { - GtkTreeModel *model; - guint32 jmp_addr; - GtkTreeIter iter; - - jmp_addr = hexstr_to_guint32 (gtk_entry_get_text (entry), err); - if (err && *err) { - return; - } - - if (jmp_addr < base_addr || jmp_addr > base_addr + size) { - g_set_error (err, - g_quark_from_string ("mem_jmp"), - 1, - "Invalid address"); - return; - } - - model = gtk_tree_view_get_model (view); - if (!model) { - return; - } - - if (gtk_tree_model_get_iter_first (model, &iter)) { - do { - guint32 addr; - GValue value = G_VALUE_INIT; - GError *err = NULL; - - gtk_tree_model_get_value (model, &iter, 0, &value); - if (G_VALUE_HOLDS_STRING (&value)) { - addr = hexstr_to_guint32 (g_value_get_string (&value), &err); - if (!err) { - if (addr == (jmp_addr & 0xFFFFFFF0)) { - GtkTreeSelection *selection; - GtkTreePath *path; - - selection = gtk_tree_view_get_selection (view); - path = gtk_tree_model_get_path (model, &iter); - - gtk_tree_selection_select_iter (selection, &iter); - gtk_tree_view_scroll_to_cell (view, - path, - NULL, - TRUE, - 0.0, - 0.0); - gtk_tree_path_free (path); - } - } - } - g_value_unset (&value); - } while (gtk_tree_model_iter_next (model, &iter)); - } + GtkTreeModel *model; + guint32 jmp_addr; + GtkTreeIter iter; + + jmp_addr = hexstr_to_guint32 (gtk_entry_get_text (entry), err); + if (err && *err) { + return; + } + + if (jmp_addr < base_addr || jmp_addr > base_addr + size) { + g_set_error (err, + g_quark_from_string ("mem_jmp"), + 1, + "Invalid address"); + return; + } + + model = gtk_tree_view_get_model (view); + if (!model) { + return; + } + + if (gtk_tree_model_get_iter_first (model, &iter)) { + do { + guint32 addr; + GValue value = G_VALUE_INIT; + GError *err = NULL; + + gtk_tree_model_get_value (model, &iter, 0, &value); + if (G_VALUE_HOLDS_STRING (&value)) { + addr = hexstr_to_guint32 (g_value_get_string (&value), &err); + if (!err) { + if (addr == (jmp_addr & 0xFFFFFFF0)) { + GtkTreeSelection *selection; + GtkTreePath *path; + + selection = gtk_tree_view_get_selection (view); + path = gtk_tree_model_get_path (model, &iter); + + gtk_tree_selection_select_iter (selection, &iter); + gtk_tree_view_scroll_to_cell (view, + path, + NULL, + TRUE, + 0.0, + 0.0); + gtk_tree_path_free (path); + } + } + } + g_value_unset (&value); + } while (gtk_tree_model_iter_next (model, &iter)); + } } static void devmem_jmp_cb (GtkWidget *widget, gpointer data) { - STlinkGUI *gui; - GError *err = NULL; + STlinkGUI *gui; + GError *err = NULL; - gui = STLINK_GUI (data); + gui = STLINK_GUI (data); - mem_jmp (gui->devmem_treeview, - gui->devmem_jmp_entry, - gui->sl->flash_base, - gui->sl->flash_size, - &err); + mem_jmp (gui->devmem_treeview, + gui->devmem_jmp_entry, + gui->sl->flash_base, + gui->sl->flash_size, + &err); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - } + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + } } static void filemem_jmp_cb (GtkWidget *widget, gpointer data) { - STlinkGUI *gui; - GError *err = NULL; + STlinkGUI *gui; + GError *err = NULL; - gui = STLINK_GUI (data); + gui = STLINK_GUI (data); - g_return_if_fail (gui->filename != NULL); + g_return_if_fail (gui->filename != NULL); - mem_jmp (gui->filemem_treeview, - gui->filemem_jmp_entry, - 0, - gui->file_mem.size, - &err); + mem_jmp (gui->filemem_treeview, + gui->filemem_jmp_entry, + 0, + gui->file_mem.size, + &err); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - } + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + } } static gchar * dev_format_chip_id (guint32 chip_id) { - gint i; + gint i; - for (i = 0; i < sizeof (devices) / sizeof (devices[0]); i++) { - if (chip_id == devices[i].chip_id) { - return g_strdup (devices[i].description); - } - } - return g_strdup_printf ("0x%x", chip_id); + for (i = 0; i < sizeof (devices) / sizeof (devices[0]); i++) { + if (chip_id == devices[i].chip_id) { + return g_strdup (devices[i].description); + } + } + return g_strdup_printf ("0x%x", chip_id); } static gchar * dev_format_mem_size (gsize flash_size) { - return g_strdup_printf ("%u kB", flash_size / 1024); + return g_strdup_printf ("%u kB", flash_size / 1024); } static void stlink_gui_set_connected (STlinkGUI *gui) { - gchar *tmp_str; - GtkListStore *store; - GtkTreeIter iter; + gchar *tmp_str; + GtkListStore *store; + GtkTreeIter iter; - gtk_statusbar_push (gui->statusbar, - gtk_statusbar_get_context_id (gui->statusbar, "conn"), - "Connected"); + gtk_statusbar_push (gui->statusbar, + gtk_statusbar_get_context_id (gui->statusbar, "conn"), + "Connected"); - gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), TRUE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->devmem_box), TRUE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->devmem_box), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), FALSE); - if (gui->filename) { - gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), TRUE); - } + if (gui->filename) { + gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), TRUE); + } - tmp_str = dev_format_chip_id (gui->sl->chip_id); - gtk_label_set_text (gui->chip_id_label, tmp_str); - g_free (tmp_str); + tmp_str = dev_format_chip_id (gui->sl->chip_id); + gtk_label_set_text (gui->chip_id_label, tmp_str); + g_free (tmp_str); - tmp_str = g_strdup_printf ("0x%x", gui->sl->core_id); - gtk_label_set_text (gui->core_id_label, tmp_str); - g_free (tmp_str); + tmp_str = g_strdup_printf ("0x%x", gui->sl->core_id); + gtk_label_set_text (gui->core_id_label, tmp_str); + g_free (tmp_str); - tmp_str = dev_format_mem_size (gui->sl->flash_size); - gtk_label_set_text (gui->flash_size_label, tmp_str); - g_free (tmp_str); + tmp_str = dev_format_mem_size (gui->sl->flash_size); + gtk_label_set_text (gui->flash_size_label, tmp_str); + g_free (tmp_str); - tmp_str = dev_format_mem_size (gui->sl->sram_size); - gtk_label_set_text (gui->ram_size_label, tmp_str); - g_free (tmp_str); + tmp_str = dev_format_mem_size (gui->sl->sram_size); + gtk_label_set_text (gui->ram_size_label, tmp_str); + g_free (tmp_str); - tmp_str = g_strdup_printf ("0x%08X", gui->sl->flash_base); - gtk_entry_set_text (gui->devmem_jmp_entry, tmp_str); - gtk_editable_set_editable (GTK_EDITABLE (gui->devmem_jmp_entry), TRUE); - g_free (tmp_str); + tmp_str = g_strdup_printf ("0x%08X", gui->sl->flash_base); + gtk_entry_set_text (gui->devmem_jmp_entry, tmp_str); + gtk_editable_set_editable (GTK_EDITABLE (gui->devmem_jmp_entry), TRUE); + g_free (tmp_str); - store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { - gtk_list_store_clear (store); - } + store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + gtk_list_store_clear (store); + } - stlink_gui_set_sensitivity (gui, FALSE); - gtk_notebook_set_current_page (gui->notebook, PAGE_DEVMEM); - gtk_widget_show (GTK_WIDGET (gui->progress.bar)); - gtk_progress_bar_set_text (gui->progress.bar, "Reading memory"); + stlink_gui_set_sensitivity (gui, FALSE); + gtk_notebook_set_current_page (gui->notebook, PAGE_DEVMEM); + gtk_widget_show (GTK_WIDGET (gui->progress.bar)); + gtk_progress_bar_set_text (gui->progress.bar, "Reading memory"); - g_thread_new ("devmem", (GThreadFunc) stlink_gui_populate_devmem_view, gui); + g_thread_new ("devmem", (GThreadFunc) stlink_gui_populate_devmem_view, gui); } static void connect_button_cb (GtkWidget *widget, gpointer data) { - STlinkGUI *gui; - gint i; + STlinkGUI *gui; + gint i; - gui = STLINK_GUI (data); + gui = STLINK_GUI (data); - if (gui->sl != NULL) - return; + if (gui->sl != NULL) + return; - /* try version 1 then version 2 */ - gui->sl = stlink_v1_open(0, 1); - if (gui->sl == NULL) { - gui->sl = stlink_open_usb(0, 1); - } - if (gui->sl == NULL) { - stlink_gui_set_info_error_message (gui, "Failed to connect to STLink."); return; - } + /* try version 1 then version 2 */ + gui->sl = stlink_v1_open(0, 1); + if (gui->sl == NULL) { + gui->sl = stlink_open_usb(0, 1); + } + if (gui->sl == NULL) { + stlink_gui_set_info_error_message (gui, "Failed to connect to STLink."); return; + } - /* code below taken from flash/main.c, refactoring might be in order */ - if (stlink_current_mode(gui->sl) == STLINK_DEV_DFU_MODE) - stlink_exit_dfu_mode(gui->sl); + /* code below taken from flash/main.c, refactoring might be in order */ + if (stlink_current_mode(gui->sl) == STLINK_DEV_DFU_MODE) + stlink_exit_dfu_mode(gui->sl); - if (stlink_current_mode(gui->sl) != STLINK_DEV_DEBUG_MODE) - stlink_enter_swd_mode(gui->sl); + if (stlink_current_mode(gui->sl) != STLINK_DEV_DEBUG_MODE) + stlink_enter_swd_mode(gui->sl); - /* Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 */ - if (gui->sl->chip_id == STM32_CHIPID_F4) { - memset(gui->sl->q_buf, 0, 4); - for (i = 0; i < 8; i++) { - stlink_write_mem32(gui->sl, 0x40026000 + 0x10 + 0x18 * i, 4); - stlink_write_mem32(gui->sl, 0x40026400 + 0x10 + 0x18 * i, 4); - stlink_write_mem32(gui->sl, 0x40026000 + 0x24 + 0x18 * i, 4); - stlink_write_mem32(gui->sl, 0x40026400 + 0x24 + 0x18 * i, 4); - } - } - stlink_gui_set_connected (gui); + /* Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 */ + if (gui->sl->chip_id == STM32_CHIPID_F4) { + memset(gui->sl->q_buf, 0, 4); + for (i = 0; i < 8; i++) { + stlink_write_mem32(gui->sl, 0x40026000 + 0x10 + 0x18 * i, 4); + stlink_write_mem32(gui->sl, 0x40026400 + 0x10 + 0x18 * i, 4); + stlink_write_mem32(gui->sl, 0x40026000 + 0x24 + 0x18 * i, 4); + stlink_write_mem32(gui->sl, 0x40026400 + 0x24 + 0x18 * i, 4); + } + } + stlink_gui_set_connected (gui); } static void stlink_gui_set_disconnected (STlinkGUI *gui) { - gtk_statusbar_push (gui->statusbar, - gtk_statusbar_get_context_id (gui->statusbar, "conn"), - "Disconnected"); + gtk_statusbar_push (gui->statusbar, + gtk_statusbar_get_context_id (gui->statusbar, "conn"), + "Disconnected"); - gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), TRUE); } static void disconnect_button_cb (GtkWidget *widget, gpointer data) { - STlinkGUI *gui; + STlinkGUI *gui; - gui = STLINK_GUI (data); + gui = STLINK_GUI (data); - if (gui->sl != NULL) { - stlink_exit_debug_mode(gui->sl); - stlink_close(gui->sl); - gui->sl = NULL; - } - stlink_gui_set_disconnected (gui); + if (gui->sl != NULL) { + stlink_exit_debug_mode(gui->sl); + stlink_close(gui->sl); + gui->sl = NULL; + } + stlink_gui_set_disconnected (gui); } static void stlink_gui_open_file (STlinkGUI *gui) { - GtkWidget *dialog; - GtkListStore *store; - GtkTreeIter iter; + GtkWidget *dialog; + GtkListStore *store; + GtkTreeIter iter; - dialog = gtk_file_chooser_dialog_new ("Open file", - gui->window, - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL); + dialog = gtk_file_chooser_dialog_new ("Open file", + gui->window, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { - gui->filename = - gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + gui->filename = + gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); - store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->filemem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { - gtk_list_store_clear (store); - } + store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->filemem_treeview)); + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + gtk_list_store_clear (store); + } - stlink_gui_set_sensitivity (gui, FALSE); - gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); - gtk_widget_show (GTK_WIDGET (gui->progress.bar)); - gtk_progress_bar_set_text (gui->progress.bar, "Reading file"); - g_thread_new ("file", (GThreadFunc) stlink_gui_populate_filemem_view, gui); - } - gtk_widget_destroy (dialog); + stlink_gui_set_sensitivity (gui, FALSE); + gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); + gtk_widget_show (GTK_WIDGET (gui->progress.bar)); + gtk_progress_bar_set_text (gui->progress.bar, "Reading file"); + g_thread_new ("file", (GThreadFunc) stlink_gui_populate_filemem_view, gui); + } + gtk_widget_destroy (dialog); } static void open_button_cb (GtkWidget *widget, gpointer data) { - STlinkGUI *gui; + STlinkGUI *gui; - gui = STLINK_GUI (data); + gui = STLINK_GUI (data); - stlink_gui_open_file (gui); + stlink_gui_open_file (gui); } static gboolean stlink_gui_write_flash_update (STlinkGUI *gui) { - stlink_gui_set_sensitivity (gui, TRUE); - gui->progress.activity_mode = FALSE; - gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); + stlink_gui_set_sensitivity (gui, TRUE); + gui->progress.activity_mode = FALSE; + gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); - return FALSE; + return FALSE; } static void stlink_gui_write_flash (STlinkGUI *gui) { - g_return_if_fail (gui->sl != NULL); - g_return_if_fail (gui->filename != NULL); + g_return_if_fail (gui->sl != NULL); + g_return_if_fail (gui->filename != NULL); - if (stlink_fwrite_flash(gui->sl, gui->filename, gui->sl->flash_base) < 0) { - stlink_gui_set_info_error_message (gui, "Failed to write to flash"); - } + if (stlink_fwrite_flash(gui->sl, gui->filename, gui->sl->flash_base) < 0) { + stlink_gui_set_info_error_message (gui, "Failed to write to flash"); + } - g_idle_add ((GSourceFunc) stlink_gui_write_flash_update, gui); + g_idle_add ((GSourceFunc) stlink_gui_write_flash_update, gui); } static void flash_button_cb (GtkWidget *widget, gpointer data) { - STlinkGUI *gui; - gchar *tmp_str; - guint32 address; - gint result; - GError *err = NULL; - - gui = STLINK_GUI (data); - g_return_if_fail (gui->sl != NULL); - - if (!g_strcmp0 (gtk_entry_get_text (gui->flash_dialog_entry), "")) { - tmp_str = g_strdup_printf ("0x%08X", gui->sl->flash_base); - gtk_entry_set_text (gui->flash_dialog_entry, tmp_str); - g_free (tmp_str); - } - - result = gtk_dialog_run (gui->flash_dialog); - if (result == GTK_RESPONSE_OK) { - address = hexstr_to_guint32 (gtk_entry_get_text (gui->flash_dialog_entry), - &err); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - } else { - if (address > gui->sl->flash_base + gui->sl->flash_size || - address < gui->sl->flash_base) { - stlink_gui_set_info_error_message (gui, "Invalid address"); - } - else if (address + gui->file_mem.size > - gui->sl->flash_base + gui->sl->flash_size) { - stlink_gui_set_info_error_message (gui, "Binary overwrites flash"); - } else { - stlink_gui_set_sensitivity (gui, FALSE); - gtk_progress_bar_set_text (gui->progress.bar, - "Writing to flash"); - gui->progress.activity_mode = TRUE; - gtk_widget_show (GTK_WIDGET (gui->progress.bar)); - g_thread_new ("flash", - (GThreadFunc) stlink_gui_write_flash, gui); - } - } - } + STlinkGUI *gui; + gchar *tmp_str; + guint32 address; + gint result; + GError *err = NULL; + + gui = STLINK_GUI (data); + g_return_if_fail (gui->sl != NULL); + + if (!g_strcmp0 (gtk_entry_get_text (gui->flash_dialog_entry), "")) { + tmp_str = g_strdup_printf ("0x%08X", gui->sl->flash_base); + gtk_entry_set_text (gui->flash_dialog_entry, tmp_str); + g_free (tmp_str); + } + + result = gtk_dialog_run (gui->flash_dialog); + if (result == GTK_RESPONSE_OK) { + address = hexstr_to_guint32 (gtk_entry_get_text (gui->flash_dialog_entry), + &err); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + } else { + if (address > gui->sl->flash_base + gui->sl->flash_size || + address < gui->sl->flash_base) { + stlink_gui_set_info_error_message (gui, "Invalid address"); + } + else if (address + gui->file_mem.size > + gui->sl->flash_base + gui->sl->flash_size) { + stlink_gui_set_info_error_message (gui, "Binary overwrites flash"); + } else { + stlink_gui_set_sensitivity (gui, FALSE); + gtk_progress_bar_set_text (gui->progress.bar, + "Writing to flash"); + gui->progress.activity_mode = TRUE; + gtk_widget_show (GTK_WIDGET (gui->progress.bar)); + g_thread_new ("flash", + (GThreadFunc) stlink_gui_write_flash, gui); + } + } + } } static gboolean progress_pulse_timeout (STlinkGUI *gui) { - if (gui->progress.activity_mode) { - gtk_progress_bar_pulse (gui->progress.bar); - } else { - gtk_progress_bar_set_fraction (gui->progress.bar, gui->progress.fraction); - } - return TRUE; + if (gui->progress.activity_mode) { + gtk_progress_bar_pulse (gui->progress.bar); + } else { + gtk_progress_bar_set_fraction (gui->progress.bar, gui->progress.fraction); + } + return TRUE; } static void @@ -710,15 +710,15 @@ notebook_switch_page_cb (GtkNotebook *notebook, guint page_num, gpointer data) { - STlinkGUI *gui; + STlinkGUI *gui; - gui = STLINK_GUI (data); + gui = STLINK_GUI (data); - if (page_num == 1) { - if (gui->filename == NULL) { - stlink_gui_open_file (gui); - } - } + if (page_num == 1) { + if (gui->filename == NULL) { + stlink_gui_open_file (gui); + } + } } static void @@ -731,225 +731,225 @@ dnd_received_cb (GtkWidget *widget, guint time, gpointer data) { - GFile *file_uri; - gchar **file_list; - const guchar *file_data; - STlinkGUI *gui = STLINK_GUI (data); - GtkListStore *store; - GtkTreeIter iter; + GFile *file_uri; + gchar **file_list; + const guchar *file_data; + STlinkGUI *gui = STLINK_GUI (data); + GtkListStore *store; + GtkTreeIter iter; - if (selection_data != NULL && - gtk_selection_data_get_length (selection_data) > 0) { - switch (target_type) { - case TARGET_FILENAME: + if (selection_data != NULL && + gtk_selection_data_get_length (selection_data) > 0) { + switch (target_type) { + case TARGET_FILENAME: - if (gui->filename) { - g_free (gui->filename); - } + if (gui->filename) { + g_free (gui->filename); + } - file_data = gtk_selection_data_get_data (selection_data); - file_list = g_strsplit ((gchar *)file_data, "\r\n", 0); + file_data = gtk_selection_data_get_data (selection_data); + file_list = g_strsplit ((gchar *)file_data, "\r\n", 0); - file_uri = g_file_new_for_uri (file_list[0]); - gui->filename = g_file_get_path (file_uri); + file_uri = g_file_new_for_uri (file_list[0]); + gui->filename = g_file_get_path (file_uri); - g_strfreev (file_list); - g_object_unref (file_uri); + g_strfreev (file_list); + g_object_unref (file_uri); - store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { - gtk_list_store_clear (store); - } + store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + gtk_list_store_clear (store); + } - stlink_gui_set_sensitivity (gui, FALSE); - gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); - gtk_widget_show (GTK_WIDGET (gui->progress.bar)); - gtk_progress_bar_set_text (gui->progress.bar, "Reading file"); - g_thread_new ("file", (GThreadFunc) stlink_gui_populate_filemem_view, gui); - break; - } - } - gtk_drag_finish (context, - TRUE, - gdk_drag_context_get_suggested_action (context) == GDK_ACTION_MOVE, - time); + stlink_gui_set_sensitivity (gui, FALSE); + gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); + gtk_widget_show (GTK_WIDGET (gui->progress.bar)); + gtk_progress_bar_set_text (gui->progress.bar, "Reading file"); + g_thread_new ("file", (GThreadFunc) stlink_gui_populate_filemem_view, gui); + break; + } + } + gtk_drag_finish (context, + TRUE, + gdk_drag_context_get_suggested_action (context) == GDK_ACTION_MOVE, + time); } void stlink_gui_init_dnd (STlinkGUI *gui) { - GtkTargetEntry target_list[] = { - { "text/uri-list", 0, TARGET_FILENAME }, - }; + GtkTargetEntry target_list[] = { + { "text/uri-list", 0, TARGET_FILENAME }, + }; - gtk_drag_dest_set (GTK_WIDGET (gui->window), - GTK_DEST_DEFAULT_ALL, - target_list, - G_N_ELEMENTS (target_list), - GDK_ACTION_COPY); + gtk_drag_dest_set (GTK_WIDGET (gui->window), + GTK_DEST_DEFAULT_ALL, + target_list, + G_N_ELEMENTS (target_list), + GDK_ACTION_COPY); - g_signal_connect (gui->window, "drag-data-received", - G_CALLBACK (dnd_received_cb), gui); + g_signal_connect (gui->window, "drag-data-received", + G_CALLBACK (dnd_received_cb), gui); } static void stlink_gui_build_ui (STlinkGUI *gui) { - GtkBuilder *builder; - GtkListStore *devmem_store; - GtkListStore *filemem_store; - gchar *ui_file = STLINK_UI_DIR "/stlink-gui.ui"; - - if (!g_file_test (ui_file, G_FILE_TEST_EXISTS)) { - ui_file = "stlink-gui.ui"; - } - builder = gtk_builder_new (); - if (!gtk_builder_add_from_file (builder, ui_file, NULL)) { - g_printerr ("Failed to load UI file: %s\n", ui_file); - exit (1); - } - - gui->window = GTK_WINDOW (gtk_builder_get_object (builder, "window")); - g_signal_connect (G_OBJECT (gui->window), "destroy", - G_CALLBACK (gtk_main_quit), NULL); - - /* set up toolutton clicked callbacks */ - gui->open_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "open_button")); - g_signal_connect (G_OBJECT (gui->open_button), "clicked", - G_CALLBACK (open_button_cb), gui); - - gui->connect_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "connect_button")); - g_signal_connect (G_OBJECT (gui->connect_button), "clicked", - G_CALLBACK (connect_button_cb), gui); - - gui->disconnect_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "disconnect_button")); - g_signal_connect (G_OBJECT (gui->disconnect_button), "clicked", - G_CALLBACK (disconnect_button_cb), gui); - - gui->flash_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "flash_button")); - g_signal_connect (G_OBJECT (gui->flash_button), "clicked", - G_CALLBACK (flash_button_cb), gui); - - gui->devmem_treeview = - GTK_TREE_VIEW (gtk_builder_get_object (builder, "devmem_treeview")); - gtk_tree_view_set_rules_hint (gui->devmem_treeview, TRUE); - mem_view_init_headers (gui->devmem_treeview); - devmem_store = gtk_list_store_new (5, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING); - gtk_tree_view_set_model (gui->devmem_treeview, GTK_TREE_MODEL (devmem_store)); - g_object_unref (devmem_store); - - gui->filemem_treeview = - GTK_TREE_VIEW (gtk_builder_get_object (builder, "filemem_treeview")); - gtk_tree_view_set_rules_hint (gui->filemem_treeview, TRUE); - mem_view_init_headers (gui->filemem_treeview); - filemem_store = gtk_list_store_new (5, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING); - gtk_tree_view_set_model (gui->filemem_treeview, GTK_TREE_MODEL (filemem_store)); - g_object_unref (filemem_store); - - gui->core_id_label = - GTK_LABEL (gtk_builder_get_object (builder, "core_id_value")); - - gui->chip_id_label = - GTK_LABEL (gtk_builder_get_object (builder, "chip_id_value")); - - gui->flash_size_label = - GTK_LABEL (gtk_builder_get_object (builder, "flash_size_value")); - - gui->ram_size_label = - GTK_LABEL (gtk_builder_get_object (builder, "ram_size_value")); - - gui->device_frame = - GTK_FRAME (gtk_builder_get_object (builder, "device_frame")); - - gui->notebook = - GTK_NOTEBOOK (gtk_builder_get_object (builder, "mem_notebook")); - g_signal_connect (gui->notebook, "switch-page", - G_CALLBACK (notebook_switch_page_cb), gui); - - gui->devmem_box = - GTK_BOX (gtk_builder_get_object (builder, "devmem_box")); - - gui->filemem_box = - GTK_BOX (gtk_builder_get_object (builder, "filemem_box")); - - gui->devmem_jmp_entry = - GTK_ENTRY (gtk_builder_get_object (builder, "devmem_jmp_entry")); - g_signal_connect (gui->devmem_jmp_entry, "activate", - G_CALLBACK (devmem_jmp_cb), gui); - - gui->filemem_jmp_entry = - GTK_ENTRY (gtk_builder_get_object (builder, "filemem_jmp_entry")); - g_signal_connect (gui->filemem_jmp_entry, "activate", - G_CALLBACK (filemem_jmp_cb), gui); - gtk_editable_set_editable (GTK_EDITABLE (gui->filemem_jmp_entry), TRUE); - - gui->progress.bar = - GTK_PROGRESS_BAR (gtk_builder_get_object (builder, "progressbar")); - gtk_progress_bar_set_show_text (gui->progress.bar, TRUE); - gui->progress.timer = g_timeout_add (100, - (GSourceFunc) progress_pulse_timeout, - gui); - - gui->statusbar = - GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")); - - gui->infobar = - GTK_INFO_BAR (gtk_builder_get_object (builder, "infobar")); - gtk_info_bar_add_button (gui->infobar, GTK_STOCK_OK, GTK_RESPONSE_OK); - gui->infolabel = GTK_LABEL (gtk_label_new ("")); - gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (gui->infobar)), - GTK_WIDGET (gui->infolabel)); - g_signal_connect (gui->infobar, "response", G_CALLBACK (gtk_widget_hide), NULL); - - /* flash dialog */ - gui->flash_dialog = - GTK_DIALOG (gtk_builder_get_object (builder, "flash_dialog")); - g_signal_connect_swapped (gui->flash_dialog, "response", - G_CALLBACK (gtk_widget_hide), gui->flash_dialog); - - gui->flash_dialog_ok = - GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_ok_button")); - - gui->flash_dialog_cancel = - GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_cancel_button")); - - gui->flash_dialog_entry = - GTK_ENTRY (gtk_builder_get_object (builder, "flash_dialog_entry")); - - /* make it so */ - gtk_widget_show_all (GTK_WIDGET (gui->window)); - gtk_widget_hide (GTK_WIDGET (gui->infobar)); - gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); - - stlink_gui_set_disconnected (gui); + GtkBuilder *builder; + GtkListStore *devmem_store; + GtkListStore *filemem_store; + gchar *ui_file = STLINK_UI_DIR "/stlink-gui.ui"; + + if (!g_file_test (ui_file, G_FILE_TEST_EXISTS)) { + ui_file = "stlink-gui.ui"; + } + builder = gtk_builder_new (); + if (!gtk_builder_add_from_file (builder, ui_file, NULL)) { + g_printerr ("Failed to load UI file: %s\n", ui_file); + exit (1); + } + + gui->window = GTK_WINDOW (gtk_builder_get_object (builder, "window")); + g_signal_connect (G_OBJECT (gui->window), "destroy", + G_CALLBACK (gtk_main_quit), NULL); + + /* set up toolutton clicked callbacks */ + gui->open_button = + GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "open_button")); + g_signal_connect (G_OBJECT (gui->open_button), "clicked", + G_CALLBACK (open_button_cb), gui); + + gui->connect_button = + GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "connect_button")); + g_signal_connect (G_OBJECT (gui->connect_button), "clicked", + G_CALLBACK (connect_button_cb), gui); + + gui->disconnect_button = + GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "disconnect_button")); + g_signal_connect (G_OBJECT (gui->disconnect_button), "clicked", + G_CALLBACK (disconnect_button_cb), gui); + + gui->flash_button = + GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "flash_button")); + g_signal_connect (G_OBJECT (gui->flash_button), "clicked", + G_CALLBACK (flash_button_cb), gui); + + gui->devmem_treeview = + GTK_TREE_VIEW (gtk_builder_get_object (builder, "devmem_treeview")); + gtk_tree_view_set_rules_hint (gui->devmem_treeview, TRUE); + mem_view_init_headers (gui->devmem_treeview); + devmem_store = gtk_list_store_new (5, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); + gtk_tree_view_set_model (gui->devmem_treeview, GTK_TREE_MODEL (devmem_store)); + g_object_unref (devmem_store); + + gui->filemem_treeview = + GTK_TREE_VIEW (gtk_builder_get_object (builder, "filemem_treeview")); + gtk_tree_view_set_rules_hint (gui->filemem_treeview, TRUE); + mem_view_init_headers (gui->filemem_treeview); + filemem_store = gtk_list_store_new (5, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); + gtk_tree_view_set_model (gui->filemem_treeview, GTK_TREE_MODEL (filemem_store)); + g_object_unref (filemem_store); + + gui->core_id_label = + GTK_LABEL (gtk_builder_get_object (builder, "core_id_value")); + + gui->chip_id_label = + GTK_LABEL (gtk_builder_get_object (builder, "chip_id_value")); + + gui->flash_size_label = + GTK_LABEL (gtk_builder_get_object (builder, "flash_size_value")); + + gui->ram_size_label = + GTK_LABEL (gtk_builder_get_object (builder, "ram_size_value")); + + gui->device_frame = + GTK_FRAME (gtk_builder_get_object (builder, "device_frame")); + + gui->notebook = + GTK_NOTEBOOK (gtk_builder_get_object (builder, "mem_notebook")); + g_signal_connect (gui->notebook, "switch-page", + G_CALLBACK (notebook_switch_page_cb), gui); + + gui->devmem_box = + GTK_BOX (gtk_builder_get_object (builder, "devmem_box")); + + gui->filemem_box = + GTK_BOX (gtk_builder_get_object (builder, "filemem_box")); + + gui->devmem_jmp_entry = + GTK_ENTRY (gtk_builder_get_object (builder, "devmem_jmp_entry")); + g_signal_connect (gui->devmem_jmp_entry, "activate", + G_CALLBACK (devmem_jmp_cb), gui); + + gui->filemem_jmp_entry = + GTK_ENTRY (gtk_builder_get_object (builder, "filemem_jmp_entry")); + g_signal_connect (gui->filemem_jmp_entry, "activate", + G_CALLBACK (filemem_jmp_cb), gui); + gtk_editable_set_editable (GTK_EDITABLE (gui->filemem_jmp_entry), TRUE); + + gui->progress.bar = + GTK_PROGRESS_BAR (gtk_builder_get_object (builder, "progressbar")); + gtk_progress_bar_set_show_text (gui->progress.bar, TRUE); + gui->progress.timer = g_timeout_add (100, + (GSourceFunc) progress_pulse_timeout, + gui); + + gui->statusbar = + GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")); + + gui->infobar = + GTK_INFO_BAR (gtk_builder_get_object (builder, "infobar")); + gtk_info_bar_add_button (gui->infobar, GTK_STOCK_OK, GTK_RESPONSE_OK); + gui->infolabel = GTK_LABEL (gtk_label_new ("")); + gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (gui->infobar)), + GTK_WIDGET (gui->infolabel)); + g_signal_connect (gui->infobar, "response", G_CALLBACK (gtk_widget_hide), NULL); + + /* flash dialog */ + gui->flash_dialog = + GTK_DIALOG (gtk_builder_get_object (builder, "flash_dialog")); + g_signal_connect_swapped (gui->flash_dialog, "response", + G_CALLBACK (gtk_widget_hide), gui->flash_dialog); + + gui->flash_dialog_ok = + GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_ok_button")); + + gui->flash_dialog_cancel = + GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_cancel_button")); + + gui->flash_dialog_entry = + GTK_ENTRY (gtk_builder_get_object (builder, "flash_dialog_entry")); + + /* make it so */ + gtk_widget_show_all (GTK_WIDGET (gui->window)); + gtk_widget_hide (GTK_WIDGET (gui->infobar)); + gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); + + stlink_gui_set_disconnected (gui); } int main (int argc, char **argv) { - STlinkGUI *gui; + STlinkGUI *gui; - gtk_init (&argc, &argv); + gtk_init (&argc, &argv); - gui = g_object_new (STLINK_TYPE_GUI, NULL); - stlink_gui_build_ui (gui); - stlink_gui_init_dnd (gui); + gui = g_object_new (STLINK_TYPE_GUI, NULL); + stlink_gui_build_ui (gui); + stlink_gui_init_dnd (gui); - gtk_main (); + gtk_main (); - return 0; + return 0; } diff --git a/gui/stlink-gui.h b/gui/stlink-gui.h index a91c869ac..0c90648a4 100644 --- a/gui/stlink-gui.h +++ b/gui/stlink-gui.h @@ -17,75 +17,75 @@ typedef struct _STlinkGUIClass STlinkGUIClass; typedef struct _STlinkGUIPrivate STlinkGUIPrivate; enum stlink_gui_pages_t { - PAGE_DEVMEM, - PAGE_FILEMEM + PAGE_DEVMEM, + PAGE_FILEMEM }; enum stlink_gui_dnd_targets_t { - TARGET_FILENAME, - TARGET_ROOTWIN + TARGET_FILENAME, + TARGET_ROOTWIN }; struct progress_t { - GtkProgressBar *bar; - guint timer; - gboolean activity_mode; - gdouble fraction; + GtkProgressBar *bar; + guint timer; + gboolean activity_mode; + gdouble fraction; }; struct mem_t { - guchar *memory; - gsize size; - guint32 base; + guchar *memory; + gsize size; + guint32 base; }; struct _STlinkGUI { - GObject parent_instance; - - /*< private >*/ - GtkWindow *window; - GtkTreeView *devmem_treeview; - GtkTreeView *filemem_treeview; - GtkSpinner *spinner; - GtkStatusbar *statusbar; - GtkInfoBar *infobar; - GtkLabel *infolabel; - GtkNotebook *notebook; - GtkFrame *device_frame; - GtkLabel *chip_id_label; - GtkLabel *core_id_label; - GtkLabel *flash_size_label; - GtkLabel *ram_size_label; - GtkBox *devmem_box; - GtkEntry *devmem_jmp_entry; - GtkBox *filemem_box; - GtkEntry *filemem_jmp_entry; - GtkToolButton *connect_button; - GtkToolButton *disconnect_button; - GtkToolButton *flash_button; - GtkToolButton *open_button; - - /* flash dialog */ - GtkDialog *flash_dialog; - GtkButton *flash_dialog_ok; - GtkButton *flash_dialog_cancel; - GtkEntry *flash_dialog_entry; - - struct progress_t progress; - struct mem_t flash_mem; - struct mem_t file_mem; - - gchar *error_message; - gchar *filename; - stlink_t *sl; + GObject parent_instance; + + /*< private >*/ + GtkWindow *window; + GtkTreeView *devmem_treeview; + GtkTreeView *filemem_treeview; + GtkSpinner *spinner; + GtkStatusbar *statusbar; + GtkInfoBar *infobar; + GtkLabel *infolabel; + GtkNotebook *notebook; + GtkFrame *device_frame; + GtkLabel *chip_id_label; + GtkLabel *core_id_label; + GtkLabel *flash_size_label; + GtkLabel *ram_size_label; + GtkBox *devmem_box; + GtkEntry *devmem_jmp_entry; + GtkBox *filemem_box; + GtkEntry *filemem_jmp_entry; + GtkToolButton *connect_button; + GtkToolButton *disconnect_button; + GtkToolButton *flash_button; + GtkToolButton *open_button; + + /* flash dialog */ + GtkDialog *flash_dialog; + GtkButton *flash_dialog_ok; + GtkButton *flash_dialog_cancel; + GtkEntry *flash_dialog_entry; + + struct progress_t progress; + struct mem_t flash_mem; + struct mem_t file_mem; + + gchar *error_message; + gchar *filename; + stlink_t *sl; }; struct _STlinkGUIClass { - GObjectClass parent_class; + GObjectClass parent_class; - /* class members */ + /* class members */ }; GType stlink_gui_get_type (void); diff --git a/mingw/mingw.c b/mingw/mingw.c index 493dcbaa2..266a87c64 100644 --- a/mingw/mingw.c +++ b/mingw/mingw.c @@ -22,30 +22,30 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) FD_ZERO(&ofds); FD_ZERO(&efds); for (i = 0, op = ip = 0; i < nfds; ++i) { - fds[i].revents = 0; - if(fds[i].events & (POLLIN|POLLPRI)) { - ip = &ifds; - FD_SET(fds[i].fd, ip); - } - if(fds[i].events & POLLOUT) { - op = &ofds; - FD_SET(fds[i].fd, op); - } - FD_SET(fds[i].fd, &efds); + fds[i].revents = 0; + if(fds[i].events & (POLLIN|POLLPRI)) { + ip = &ifds; + FD_SET(fds[i].fd, ip); + } + if(fds[i].events & POLLOUT) { + op = &ofds; + FD_SET(fds[i].fd, op); + } + FD_SET(fds[i].fd, &efds); } /* Set up the timeval structure for the timeout parameter */ if(timo < 0) { - toptr = 0; + toptr = 0; } else { - toptr = &timeout; - timeout.tv_sec = timo / 1000; - timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000; + toptr = &timeout; + timeout.tv_sec = timo / 1000; + timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000; } #ifdef DEBUG_POLL printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n", - (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op); + (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op); #endif rc = select(0, ip, op, &efds, toptr); #ifdef DEBUG_POLL @@ -53,23 +53,23 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) #endif if(rc <= 0) - return rc; + return rc; if(rc > 0) { for ( i = 0; i < nfds; ++i) { int fd = fds[i].fd; - if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) - fds[i].revents |= POLLIN; - if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) - fds[i].revents |= POLLOUT; - if(FD_ISSET(fd, &efds)) - /* Some error was detected ... should be some way to know. */ - fds[i].revents |= POLLHUP; + if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) + fds[i].revents |= POLLIN; + if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) + fds[i].revents |= POLLOUT; + if(FD_ISSET(fd, &efds)) + /* Some error was detected ... should be some way to know. */ + fds[i].revents |= POLLHUP; #ifdef DEBUG_POLL - printf("%d %d %d revent = %x\n", - FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds), - fds[i].revents - ); + printf("%d %d %d revent = %x\n", + FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds), + fds[i].revents + ); #endif } } @@ -79,14 +79,14 @@ static void set_connect_errno(int winsock_err) { switch(winsock_err) { - case WSAEINVAL: - case WSAEALREADY: - case WSAEWOULDBLOCK: - errno = EINPROGRESS; - break; - default: - errno = winsock_err; - break; + case WSAEINVAL: + case WSAEALREADY: + case WSAEWOULDBLOCK: + errno = EINPROGRESS; + break; + default: + errno = winsock_err; + break; } } @@ -94,12 +94,12 @@ static void set_socket_errno(int winsock_err) { switch(winsock_err) { - case WSAEWOULDBLOCK: - errno = EAGAIN; - break; - default: - errno = winsock_err; - break; + case WSAEWOULDBLOCK: + errno = EAGAIN; + break; + default: + errno = winsock_err; + break; } } /* @@ -192,75 +192,75 @@ ssize_t win32_read_socket(SOCKET fd, void *buf, int n) char * win32_strtok_r(char *s, const char *delim, char **lasts) { - register char *spanp; - register int c, sc; - char *tok; + register char *spanp; + register int c, sc; + char *tok; - if (s == NULL && (s = *lasts) == NULL) - return (NULL); + if (s == NULL && (s = *lasts) == NULL) + return (NULL); - /* - * Skip (span) leading delimiters (s += strspn(s, delim), sort of). - */ + /* + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). + */ cont: - c = *s++; - for (spanp = (char *)delim; (sc = *spanp++) != 0;) { - if (c == sc) - goto cont; - } + c = *s++; + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + if (c == sc) + goto cont; + } - if (c == 0) { /* no non-delimiter characters */ - *lasts = NULL; - return (NULL); - } - tok = s - 1; + if (c == 0) { /* no non-delimiter characters */ + *lasts = NULL; + return (NULL); + } + tok = s - 1; - /* - * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). - * Note that delim must have one NUL; we stop if we see that, too. - */ - for (;;) { - c = *s++; - spanp = (char *)delim; - do { - if ((sc = *spanp++) == c) { - if (c == 0) - s = NULL; - else - s[-1] = 0; - *lasts = s; - return (tok); - } - } while (sc != 0); - } - /* NOTREACHED */ + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *lasts = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ } char *win32_strsep (char **stringp, const char *delim) { - register char *s; - register const char *spanp; - register int c, sc; - char *tok; + register char *s; + register const char *spanp; + register int c, sc; + char *tok; - if ((s = *stringp) == NULL) - return (NULL); - for (tok = s;;) { - c = *s++; - spanp = delim; - do { - if ((sc = *spanp++) == c) { - if (c == 0) - s = NULL; - else - s[-1] = 0; - *stringp = s; - return (tok); - } - } while (sc != 0); - } - /* NOTREACHED */ + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ } #endif diff --git a/src/mmap.c b/src/mmap.c index 9c631da2d..c5794da91 100644 --- a/src/mmap.c +++ b/src/mmap.c @@ -7,27 +7,27 @@ void *mmap (void *addr, size_t len, int prot, int flags, int fd, long long offset) { - void *buf; - ssize_t count; + void *buf; + ssize_t count; - if ( addr || fd == -1 || (prot & PROT_WRITE)) return MAP_FAILED; + if ( addr || fd == -1 || (prot & PROT_WRITE)) return MAP_FAILED; - buf = malloc(len); - if ( NULL == buf ) return MAP_FAILED; + buf = malloc(len); + if ( NULL == buf ) return MAP_FAILED; - if (lseek(fd,offset,SEEK_SET) != offset) return MAP_FAILED; + if (lseek(fd,offset,SEEK_SET) != offset) return MAP_FAILED; - count = read(fd, buf, len); + count = read(fd, buf, len); - if (count != len) { - free (buf); - return MAP_FAILED; - } + if (count != len) { + free (buf); + return MAP_FAILED; + } - return buf; + return buf; } int munmap (void *addr, size_t len) { - free (addr); - return 0; + free (addr); + return 0; } diff --git a/src/mmap.h b/src/mmap.h index bff766c4a..71de819fa 100644 --- a/src/mmap.h +++ b/src/mmap.h @@ -19,8 +19,8 @@ extern "C" { #endif -void *mmap(void *addr, size_t len, int prot, int flags, int fd, long long offset); -int munmap(void *addr, size_t len); + void *mmap(void *addr, size_t len, int prot, int flags, int fd, long long offset); + int munmap(void *addr, size_t len); #ifdef __cplusplus } diff --git a/src/st-info.c b/src/st-info.c index 28f3fb823..6fe2f8d7a 100644 --- a/src/st-info.c +++ b/src/st-info.c @@ -11,79 +11,79 @@ static void usage(void) { - puts("st-info --flash"); - puts("st-info --sram"); - puts("st-info --descr"); - puts("st-info --pagesize"); - puts("st-info --chipid"); + puts("st-info --flash"); + puts("st-info --sram"); + puts("st-info --descr"); + puts("st-info --pagesize"); + puts("st-info --chipid"); } static int print_data(stlink_t* sl, char** av) { - int ret = 0; - if (strcmp(av[1], "--flash") == 0) - printf("0x%zx\n", sl->flash_size); - else if (strcmp(av[1], "--sram") == 0) - printf("0x%zx\n", sl->sram_size); - else if (strcmp(av[1], "--pagesize") == 0) - printf("0x%zx\n", sl->flash_pgsz); - else if (strcmp(av[1], "--chipid") == 0) - printf("0x%.4x\n", sl->chip_id); - else if (strcmp(av[1], "--descr")==0) { - const chip_params_t *params = NULL; - for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { - if(devices[i].chip_id == sl->chip_id) { - params = &devices[i]; - break; - } - } - if (params == NULL) { - return -1; - } - printf("%s\n", params->description); - } - return ret; -} + int ret = 0; + if (strcmp(av[1], "--flash") == 0) + printf("0x%zx\n", sl->flash_size); + else if (strcmp(av[1], "--sram") == 0) + printf("0x%zx\n", sl->sram_size); + else if (strcmp(av[1], "--pagesize") == 0) + printf("0x%zx\n", sl->flash_pgsz); + else if (strcmp(av[1], "--chipid") == 0) + printf("0x%.4x\n", sl->chip_id); + else if (strcmp(av[1], "--descr")==0) { + const chip_params_t *params = NULL; + for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { + if(devices[i].chip_id == sl->chip_id) { + params = &devices[i]; + break; + } + } + if (params == NULL) { + return -1; + } + printf("%s\n", params->description); + } + return ret; +} -stlink_t* open_sl(void) +stlink_t* open_sl(void) { - stlink_t* sl; - sl = stlink_v1_open(0, 1); - if (sl == NULL) - sl = stlink_open_usb(0, 1); - return sl; + stlink_t* sl; + sl = stlink_v1_open(0, 1); + if (sl == NULL) + sl = stlink_open_usb(0, 1); + return sl; } int main(int ac, char** av) { - stlink_t* sl = NULL; - int err = -1; - if (ac < 2) { - usage(); - return -1; - } + stlink_t* sl = NULL; + int err = -1; + if (ac < 2) { + usage(); + return -1; + } + + sl = open_sl(); + + if (sl == NULL) { + return -1; + } + sl->verbose=0; + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) + stlink_exit_dfu_mode(sl); - sl = open_sl(); - - if (sl == NULL) { - return -1; - } - sl->verbose=0; - 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); - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) - stlink_enter_swd_mode(sl); + err = print_data(sl, av); - err = print_data(sl, av); - - if (sl != NULL) - { - stlink_exit_debug_mode(sl); - stlink_close(sl); - } + if (sl != NULL) + { + stlink_exit_debug_mode(sl); + stlink_close(sl); + } - return err; + return err; } diff --git a/src/st-term.c b/src/st-term.c index 6881f6218..8350cfffc 100644 --- a/src/st-term.c +++ b/src/st-term.c @@ -13,225 +13,225 @@ #define STLINKY_MAGIC 0xDEADF00D -#define READ_UINT32_LE(buf) ((uint32_t) ( buf[0] \ - | buf[1] << 8 \ - | buf[2] << 16 \ - | buf[3] << 24)) +#define READ_UINT32_LE(buf) ((uint32_t) ( buf[0] \ + | buf[1] << 8 \ + | buf[2] << 16 \ + | buf[3] << 24)) static stlink_t* sl; sigset_t sig_mask; struct stlinky { - stlink_t *sl; - uint32_t off; - size_t bufsize; + stlink_t *sl; + uint32_t off; + size_t bufsize; }; void nonblock(int state); static void cleanup(int signal __attribute__((unused))) { - if (sl) { - /* Switch back to mass storage mode before closing. */ - stlink_run(sl); - stlink_exit_debug_mode(sl); - stlink_close(sl); - } - - printf("\n"); - nonblock(0); - exit(1); + if (sl) { + /* Switch back to mass storage mode before closing. */ + stlink_run(sl); + stlink_exit_debug_mode(sl); + stlink_close(sl); + } + + printf("\n"); + nonblock(0); + exit(1); } void sig_init() { - sigemptyset(&sig_mask); - sigaddset(&sig_mask, SIGINT); - sigaddset(&sig_mask, SIGTERM); - signal(SIGINT, &cleanup); - signal(SIGTERM, &cleanup); - sigprocmask(SIG_BLOCK, &sig_mask, NULL); + sigemptyset(&sig_mask); + sigaddset(&sig_mask, SIGINT); + sigaddset(&sig_mask, SIGTERM); + signal(SIGINT, &cleanup); + signal(SIGTERM, &cleanup); + sigprocmask(SIG_BLOCK, &sig_mask, NULL); } void sig_process() { - sigset_t pending; - sigpending(&pending); - if (sigismember(&pending, SIGINT) || sigismember(&pending, SIGTERM)) { - sigprocmask(SIG_UNBLOCK, &sig_mask, NULL); - sigsuspend(&pending); - sigprocmask(SIG_BLOCK, &sig_mask, NULL); - } + sigset_t pending; + sigpending(&pending); + if (sigismember(&pending, SIGINT) || sigismember(&pending, SIGTERM)) { + sigprocmask(SIG_UNBLOCK, &sig_mask, NULL); + sigsuspend(&pending); + sigprocmask(SIG_BLOCK, &sig_mask, NULL); + } } /* Detects stlinky in RAM, returns handler */ struct stlinky* stlinky_detect(stlink_t* sl) { - static const uint32_t sram_base = 0x20000000; - struct stlinky* st = malloc(sizeof(struct stlinky)); - int multiple=0; - st->sl = sl; - printf("sram: 0x%x bytes @ 0x%zx\n", sl->sram_base, sl->sram_size); - uint32_t off; - for (off = 0; off < sl->sram_size; off += 4) { - if (off % 1024 == 0) sig_process(); - stlink_read_mem32(sl, sram_base + off, 4); - if (STLINKY_MAGIC == READ_UINT32_LE(sl->q_buf)) - { - if (multiple > 0) printf("WARNING: another "); - printf("stlinky detected at 0x%x\n", sram_base + off); - st->off = sram_base + off; - stlink_read_mem32(sl, st->off + 4, 4); - st->bufsize = (size_t) *(unsigned char*) sl->q_buf; - printf("stlinky buffer size 0x%zu \n", st->bufsize); - multiple++; - } - } - if (multiple > 0) { - if (multiple > 1) { - printf("Using last stlinky structure detected\n"); - } - return st; - } - return NULL; + static const uint32_t sram_base = 0x20000000; + struct stlinky* st = malloc(sizeof(struct stlinky)); + int multiple=0; + st->sl = sl; + printf("sram: 0x%x bytes @ 0x%zx\n", sl->sram_base, sl->sram_size); + uint32_t off; + for (off = 0; off < sl->sram_size; off += 4) { + if (off % 1024 == 0) sig_process(); + stlink_read_mem32(sl, sram_base + off, 4); + if (STLINKY_MAGIC == READ_UINT32_LE(sl->q_buf)) + { + if (multiple > 0) printf("WARNING: another "); + printf("stlinky detected at 0x%x\n", sram_base + off); + st->off = sram_base + off; + stlink_read_mem32(sl, st->off + 4, 4); + st->bufsize = (size_t) *(unsigned char*) sl->q_buf; + printf("stlinky buffer size 0x%zu \n", st->bufsize); + multiple++; + } + } + if (multiple > 0) { + if (multiple > 1) { + printf("Using last stlinky structure detected\n"); + } + return st; + } + return NULL; } int stlinky_canrx(struct stlinky *st) { - stlink_read_mem32(st->sl, st->off+4, 4); - unsigned char tx = (unsigned char) st->sl->q_buf[1]; - return (int) tx; + stlink_read_mem32(st->sl, st->off+4, 4); + unsigned char tx = (unsigned char) st->sl->q_buf[1]; + return (int) tx; } size_t stlinky_rx(struct stlinky *st, char* buffer) { - unsigned char tx = 0; - while(tx == 0) { - stlink_read_mem32(st->sl, st->off+4, 4); - tx = (unsigned char) st->sl->q_buf[1]; - } - size_t rs = tx + (4 - (tx % 4)); /* voodoo */ - stlink_read_mem32(st->sl, st->off+8, rs); - memcpy(buffer, st->sl->q_buf, (size_t) tx); - *st->sl->q_buf=0x0; - stlink_write_mem8(st->sl, st->off+5, 1); - return (size_t) tx; + unsigned char tx = 0; + while(tx == 0) { + stlink_read_mem32(st->sl, st->off+4, 4); + tx = (unsigned char) st->sl->q_buf[1]; + } + size_t rs = tx + (4 - (tx % 4)); /* voodoo */ + stlink_read_mem32(st->sl, st->off+8, rs); + memcpy(buffer, st->sl->q_buf, (size_t) tx); + *st->sl->q_buf=0x0; + stlink_write_mem8(st->sl, st->off+5, 1); + return (size_t) tx; } size_t stlinky_tx(struct stlinky *st, char* buffer, size_t sz) { - unsigned char rx = 1; - while(rx != 0) { - stlink_read_mem32(st->sl, st->off+4, 4); - rx = (unsigned char) st->sl->q_buf[2]; - } - memcpy(st->sl->q_buf, buffer, sz); - size_t rs = sz + (4 - (sz % 4)); /* voodoo */ - stlink_write_mem32(st->sl, st->off+8+st->bufsize, rs); - *st->sl->q_buf=(unsigned char) sz; - stlink_write_mem8(st->sl, st->off+6, 1); - return (size_t) rx; + unsigned char rx = 1; + while(rx != 0) { + stlink_read_mem32(st->sl, st->off+4, 4); + rx = (unsigned char) st->sl->q_buf[2]; + } + memcpy(st->sl->q_buf, buffer, sz); + size_t rs = sz + (4 - (sz % 4)); /* voodoo */ + stlink_write_mem32(st->sl, st->off+8+st->bufsize, rs); + *st->sl->q_buf=(unsigned char) sz; + stlink_write_mem8(st->sl, st->off+6, 1); + return (size_t) rx; } int kbhit() { - struct timeval tv; - fd_set fds; - tv.tv_sec = 0; - tv.tv_usec = 0; - FD_ZERO(&fds); - FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0 - select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); - return FD_ISSET(STDIN_FILENO, &fds); + struct timeval tv; + fd_set fds; + tv.tv_sec = 0; + tv.tv_usec = 0; + FD_ZERO(&fds); + FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0 + select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); + return FD_ISSET(STDIN_FILENO, &fds); } void nonblock(int state) { - struct termios ttystate; - - //get the terminal state - tcgetattr(STDIN_FILENO, &ttystate); - - if (state==1) - { - //turn off canonical mode - ttystate.c_lflag &= ~ICANON; - ttystate.c_lflag &= ~ECHO; - //minimum of number input read. - ttystate.c_cc[VMIN] = 1; - } - else if (state==0) - { - //turn on canonical mode - ttystate.c_lflag |= ICANON | ECHO; - } - //set the terminal attributes. - tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); + struct termios ttystate; + + //get the terminal state + tcgetattr(STDIN_FILENO, &ttystate); + + if (state==1) + { + //turn off canonical mode + ttystate.c_lflag &= ~ICANON; + ttystate.c_lflag &= ~ECHO; + //minimum of number input read. + ttystate.c_cc[VMIN] = 1; + } + else if (state==0) + { + //turn on canonical mode + ttystate.c_lflag |= ICANON | ECHO; + } + //set the terminal attributes. + tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); } int main(int ac, char** av) { - struct stlinky *st=NULL; - - sig_init(); - - sl = stlink_open_usb(10, 1); - if (sl != NULL) { - printf("ST-Linky proof-of-concept terminal :: Created by Necromant for lulz\n"); - stlink_version(sl); - stlink_enter_swd_mode(sl); - printf("chip id: %#x\n", sl->chip_id); - printf("core_id: %#x\n", sl->core_id); - - cortex_m3_cpuid_t cpuid; - stlink_cpu_id(sl, &cpuid); - printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); - printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); - - stlink_reset(sl); - stlink_force_debug(sl); - stlink_run(sl); - stlink_status(sl); - - /* wait for device to boot */ - /* TODO: Make timeout adjustable via command line */ - sleep(1); - - if(ac == 1){ - st = stlinky_detect(sl); - }else if(ac == 2){ - st = malloc(sizeof(struct stlinky)); - st->sl = sl; - st->off = (int)strtol(av[1], NULL, 16); - printf("using stlinky at 0x%x\n", st->off); - stlink_read_mem32(sl, st->off + 4, 4); - st->bufsize = (size_t) *(unsigned char*) sl->q_buf; - printf("stlinky buffer size 0x%zu \n", st->bufsize); - }else{ - cleanup(0); - } - if (st == NULL) - { - printf("stlinky magic not found in sram :(\n"); - cleanup(0); - } - char* rxbuf = malloc(st->bufsize); - char* txbuf = malloc(st->bufsize); - size_t tmp; - nonblock(1); - int fd = fileno(stdin); - int saved_flags = fcntl(fd, F_GETFL); - fcntl(fd, F_SETFL, saved_flags & ~O_NONBLOCK); - printf("Entering interactive terminal. CTRL+C to exit\n\n\n"); - while(1) { - sig_process(); - if (stlinky_canrx(st)) { - tmp = stlinky_rx(st, rxbuf); - fwrite(rxbuf,tmp,1,stdout); - fflush(stdout); - } - if (kbhit()) { - tmp = read(fd, txbuf, st->bufsize); - stlinky_tx(st,txbuf,tmp); - } - } - } - return 0; + struct stlinky *st=NULL; + + sig_init(); + + sl = stlink_open_usb(10, 1); + if (sl != NULL) { + printf("ST-Linky proof-of-concept terminal :: Created by Necromant for lulz\n"); + stlink_version(sl); + stlink_enter_swd_mode(sl); + printf("chip id: %#x\n", sl->chip_id); + printf("core_id: %#x\n", sl->core_id); + + cortex_m3_cpuid_t cpuid; + stlink_cpu_id(sl, &cpuid); + printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); + printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); + + stlink_reset(sl); + stlink_force_debug(sl); + stlink_run(sl); + stlink_status(sl); + + /* wait for device to boot */ + /* TODO: Make timeout adjustable via command line */ + sleep(1); + + if(ac == 1){ + st = stlinky_detect(sl); + }else if(ac == 2){ + st = malloc(sizeof(struct stlinky)); + st->sl = sl; + st->off = (int)strtol(av[1], NULL, 16); + printf("using stlinky at 0x%x\n", st->off); + stlink_read_mem32(sl, st->off + 4, 4); + st->bufsize = (size_t) *(unsigned char*) sl->q_buf; + printf("stlinky buffer size 0x%zu \n", st->bufsize); + }else{ + cleanup(0); + } + if (st == NULL) + { + printf("stlinky magic not found in sram :(\n"); + cleanup(0); + } + char* rxbuf = malloc(st->bufsize); + char* txbuf = malloc(st->bufsize); + size_t tmp; + nonblock(1); + int fd = fileno(stdin); + int saved_flags = fcntl(fd, F_GETFL); + fcntl(fd, F_SETFL, saved_flags & ~O_NONBLOCK); + printf("Entering interactive terminal. CTRL+C to exit\n\n\n"); + while(1) { + sig_process(); + if (stlinky_canrx(st)) { + tmp = stlinky_rx(st, rxbuf); + fwrite(rxbuf,tmp,1,stdout); + fflush(stdout); + } + if (kbhit()) { + tmp = read(fd, txbuf, st->bufsize); + stlinky_tx(st,txbuf,tmp); + } + } + } + return 0; } diff --git a/src/stlink-common.c b/src/stlink-common.c index 545434b4e..ce1306b12 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -144,7 +144,7 @@ static inline uint32_t read_flash_obr(stlink_t *sl) { static inline uint32_t read_flash_cr(stlink_t *sl) { uint32_t res; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||(sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) res = stlink_read_debug32(sl, FLASH_F4_CR); else res = stlink_read_debug32(sl, FLASH_CR); @@ -157,7 +157,7 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK); else return read_flash_cr(sl) & (1 << FLASH_CR_LOCK); @@ -168,13 +168,13 @@ static void unlock_flash(stlink_t *sl) { 2 key values are written to the FLASH_KEYR register. an invalid sequence results in a definitive lock of the FPEC block until next reset. - */ + */ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { - stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); } else { - stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY1); + stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY1); stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY2); } @@ -196,9 +196,9 @@ static int unlock_flash_if(stlink_t *sl) { static void lock_flash(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { - const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); - stlink_write_debug32(sl, FLASH_F4_CR, n); + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); + stlink_write_debug32(sl, FLASH_F4_CR, n); } else { /* write to 1 only. reset by hw at unlock sequence */ const uint32_t n = read_flash_cr(sl) | (1 << FLASH_CR_LOCK); @@ -209,10 +209,10 @@ static void lock_flash(stlink_t *sl) { static void set_flash_cr_pg(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { - uint32_t x = read_flash_cr(sl); - x |= (1 << FLASH_CR_PG); - stlink_write_debug32(sl, FLASH_F4_CR, x); + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + uint32_t x = read_flash_cr(sl); + x |= (1 << FLASH_CR_PG); + stlink_write_debug32(sl, FLASH_F4_CR, x); } else { const uint32_t n = 1 << FLASH_CR_PG; stlink_write_debug32(sl, FLASH_CR, n); @@ -222,8 +222,8 @@ static void set_flash_cr_pg(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) - stlink_write_debug32(sl, FLASH_F4_CR, n); + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + stlink_write_debug32(sl, FLASH_F4_CR, n); else stlink_write_debug32(sl, FLASH_CR, n); } @@ -240,33 +240,33 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { static void set_flash_cr_mer(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) stlink_write_debug32(sl, FLASH_F4_CR, - stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); + stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); else stlink_write_debug32(sl, FLASH_CR, - stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_MER)); + stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_MER)); } static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) stlink_write_debug32(sl, FLASH_F4_CR, - stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); + stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); else stlink_write_debug32(sl, FLASH_CR, - stlink_read_debug32(sl, FLASH_CR) & ~(1 << FLASH_CR_MER)); + stlink_read_debug32(sl, FLASH_CR) & ~(1 << FLASH_CR_MER)); } static void set_flash_cr_strt(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_F4_CR_STRT); stlink_write_debug32(sl, FLASH_F4_CR, x); } else { stlink_write_debug32(sl, FLASH_CR, - stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_STRT) ); + stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_STRT) ); } } @@ -277,7 +277,7 @@ static inline uint32_t read_flash_acr(stlink_t *sl) { static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) res = stlink_read_debug32(sl, FLASH_F4_SR); else res = stlink_read_debug32(sl, FLASH_SR); @@ -287,7 +287,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { static inline unsigned int is_flash_busy(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY); else return read_flash_sr(sl) & (1 << FLASH_SR_BSY); @@ -464,7 +464,7 @@ int stlink_load_device_params(stlink_t *sl) { flash_size = flash_size & 0xffff; if ((sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) && ( flash_size == 0 )) { - sl->flash_size = 128 * 1024; + sl->flash_size = 128 * 1024; } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_L1_HIGH) { // 0 is 384k and 1 is 256k if ( flash_size == 0 ) { @@ -483,8 +483,8 @@ int stlink_load_device_params(stlink_t *sl) { ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); // TODO make note of variable page size here..... ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %zd bytes\n", - sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, - sl->flash_pgsz); + sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, + sl->flash_pgsz); return 0; } @@ -557,11 +557,11 @@ int stlink_target_voltage(stlink_t *sl) { DLOG("*** reading target voltage\n"); if (sl->backend->target_voltage != NULL) { voltage = sl->backend->target_voltage(sl); - if (voltage != -1) { + if (voltage != -1) { DLOG("target voltage = %ldmV\n", voltage); - } else { + } else { DLOG("error reading target voltage\n"); - } + } } else { DLOG("reading voltage not supported by backend\n"); } @@ -691,15 +691,15 @@ void stlink_step(stlink_t *sl) { int stlink_current_mode(stlink_t *sl) { int mode = sl->backend->current_mode(sl); switch (mode) { - case STLINK_DEV_DFU_MODE: - DLOG("stlink current mode: dfu\n"); - return mode; - case STLINK_DEV_DEBUG_MODE: - DLOG("stlink current mode: debug (jtag or swd)\n"); - return mode; - case STLINK_DEV_MASS_MODE: - DLOG("stlink current mode: mass\n"); - return mode; + case STLINK_DEV_DFU_MODE: + DLOG("stlink current mode: dfu\n"); + return mode; + case STLINK_DEV_DEBUG_MODE: + DLOG("stlink current mode: debug (jtag or swd)\n"); + return mode; + case STLINK_DEV_MASS_MODE: + DLOG("stlink current mode: mass\n"); + return mode; } DLOG("stlink mode: unknown!\n"); return STLINK_DEV_UNKNOWN_MODE; @@ -750,17 +750,17 @@ void stlink_core_stat(stlink_t *sl) { return; switch (sl->q_buf[0]) { - case STLINK_CORE_RUNNING: - sl->core_stat = STLINK_CORE_RUNNING; - DLOG(" core status: running\n"); - return; - case STLINK_CORE_HALTED: - sl->core_stat = STLINK_CORE_HALTED; - DLOG(" core status: halted\n"); - return; - default: - sl->core_stat = STLINK_CORE_STAT_UNKNOWN; - fprintf(stderr, " core status: unknown\n"); + case STLINK_CORE_RUNNING: + sl->core_stat = STLINK_CORE_RUNNING; + DLOG(" core status: running\n"); + return; + case STLINK_CORE_HALTED: + sl->core_stat = STLINK_CORE_HALTED; + DLOG(" core status: halted\n"); + return; + default: + sl->core_stat = STLINK_CORE_STAT_UNKNOWN; + fprintf(stderr, " core status: unknown\n"); } } @@ -773,11 +773,11 @@ void stlink_print_data(stlink_t * sl) { for (int i = 0; i < sl->q_len; i++) { if (i % 16 == 0) { /* - if (sl->q_data_dir == Q_DATA_OUT) - fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i); - else - fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); - */ + if (sl->q_data_dir == Q_DATA_OUT) + fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i); + else + fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); + */ } fprintf(stdout, " %02x", (unsigned int) sl->q_buf[i]); } @@ -931,7 +931,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) size_t off; int num_empty = 0; unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) ? 0:0xff; + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) ? 0:0xff; const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); if (fd == -1) { @@ -940,32 +940,32 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) } if (size <1) - size = sl->flash_size; + size = sl->flash_size; if (size > sl->flash_size) - size = sl->flash_size; + size = sl->flash_size; /* do the copy by 1k blocks */ for (off = 0; off < size; off += 1024) { size_t read_size = 1024; - size_t rounded_size; - size_t index; + size_t rounded_size; + size_t index; if ((off + read_size) > size) - read_size = size - off; + read_size = size - off; /* round size if needed */ - rounded_size = read_size; + rounded_size = read_size; if (rounded_size & 3) - rounded_size = (rounded_size + 4) & ~(3); + rounded_size = (rounded_size + 4) & ~(3); stlink_read_mem32(sl, addr + off, rounded_size); - for(index = 0; index < read_size; index ++) { - if (sl->q_buf[index] == erased_pattern) - num_empty ++; - else - num_empty = 0; - } + for(index = 0; index < read_size; index ++) { + if (sl->q_buf[index] == erased_pattern) + num_empty ++; + else + num_empty = 0; + } if (write(fd, sl->q_buf, read_size) != (ssize_t) read_size) { fprintf(stderr, "write() != read_size\n"); goto on_error; @@ -1013,14 +1013,14 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { - uint32_t sector=calculate_F4_sectornum(flashaddr); - if (sector<4) sl->flash_pgsz=0x4000; - else if(sector<5) sl->flash_pgsz=0x10000; - else sl->flash_pgsz=0x20000; - } - return (sl->flash_pgsz); + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + uint32_t sector=calculate_F4_sectornum(flashaddr); + if (sector<4) sl->flash_pgsz=0x4000; + else if(sector<5) sl->flash_pgsz=0x10000; + else sl->flash_pgsz=0x20000; + } + return (sl->flash_pgsz); } /** @@ -1032,144 +1032,144 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { - /* wait for ongoing op to finish */ - wait_flash_busy(sl); + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + /* wait for ongoing op to finish */ + wait_flash_busy(sl); - /* unlock if locked */ - unlock_flash_if(sl); + /* unlock if locked */ + unlock_flash_if(sl); - /* select the page to erase */ - // calculate the actual page from the address - uint32_t sector=calculate_F4_sectornum(flashaddr); + /* select the page to erase */ + // calculate the actual page from the address + uint32_t sector=calculate_F4_sectornum(flashaddr); - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x\n", sector, stlink_calculate_pagesize(sl, flashaddr)); - write_flash_cr_snb(sl, sector); + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x\n", sector, stlink_calculate_pagesize(sl, flashaddr)); + write_flash_cr_snb(sl, sector); - /* start erase operation */ - set_flash_cr_strt(sl); + /* start erase operation */ + set_flash_cr_strt(sl); - /* wait for completion */ - wait_flash_busy(sl); + /* wait for completion */ + wait_flash_busy(sl); - /* relock the flash */ - //todo: fails to program if this is in - lock_flash(sl); + /* relock the flash */ + //todo: fails to program if this is in + lock_flash(sl); #if DEBUG_FLASH - fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); + fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); #endif - } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { + } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { - uint32_t val; + uint32_t val; - /* check if the locks are set */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if((val & (1<<0))||(val & (1<<1))) { - /* disable pecr protection */ - stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); - stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405); - - /* check pecr.pelock is cleared */ + /* check if the locks are set */ val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 0)) { - WLOG("pecr.pelock not clear (%#x)\n", val); - return -1; - } + if((val & (1<<0))||(val & (1<<1))) { + /* disable pecr protection */ + stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); + stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405); - /* unlock program memory */ - stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf); - stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516); + /* check pecr.pelock is cleared */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + if (val & (1 << 0)) { + WLOG("pecr.pelock not clear (%#x)\n", val); + return -1; + } - /* check pecr.prglock is cleared */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 1)) { - WLOG("pecr.prglock not clear (%#x)\n", val); - return -1; + /* unlock program memory */ + stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf); + stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516); + + /* check pecr.prglock is cleared */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + if (val & (1 << 1)) { + WLOG("pecr.prglock not clear (%#x)\n", val); + return -1; + } } - } - /* unused: unlock the option byte block */ + /* unused: unlock the option byte block */ #if 0 - stlink_write_debug32(sl, STM32L_FLASH_OPTKEYR, 0xfbead9c8); - stlink_write_debug32(sl, STM32L_FLASH_OPTKEYR, 0x24252627); + stlink_write_debug32(sl, STM32L_FLASH_OPTKEYR, 0xfbead9c8); + stlink_write_debug32(sl, STM32L_FLASH_OPTKEYR, 0x24252627); - /* check pecr.optlock is cleared */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 2)) { - fprintf(stderr, "pecr.prglock not clear\n"); - return -1; - } + /* check pecr.optlock is cleared */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + if (val & (1 << 2)) { + fprintf(stderr, "pecr.prglock not clear\n"); + return -1; + } #endif - /* set pecr.{erase,prog} */ - val |= (1 << 9) | (1 << 3); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + /* set pecr.{erase,prog} */ + val |= (1 << 9) | (1 << 3); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); #if 0 /* fix_to_be_confirmed */ - /* wait for sr.busy to be cleared - MP: Test shows that busy bit is not set here. Perhaps, PM0062 is - wrong and we do not need to wait here for clearing the busy bit. - TEXANE: ok, if experience says so and it works for you, we comment - it. If someone has a problem, please drop an email. - */ - while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) - ; + /* wait for sr.busy to be cleared + * MP: Test shows that busy bit is not set here. Perhaps, PM0062 is + * wrong and we do not need to wait here for clearing the busy bit. + * TEXANE: ok, if experience says so and it works for you, we comment + * it. If someone has a problem, please drop an email. + */ + while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) + ; #endif /* fix_to_be_confirmed */ - /* write 0 to the first word of the page to be erased */ - stlink_write_debug32(sl, flashaddr, 0); - - /* MP: It is better to wait for clearing the busy bit after issuing - page erase command, even though PM0062 recommends to wait before it. - Test shows that a few iterations is performed in the following loop - before busy bit is cleared.*/ - while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) - ; - - /* reset lock bits */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR) - | (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - } else if (sl->core_id == STM32VL_CORE_ID - || sl->core_id == STM32F0_CORE_ID - || sl->chip_id == STM32_CHIPID_F3 - || sl->chip_id == STM32_CHIPID_F37x) { - /* wait for ongoing op to finish */ - wait_flash_busy(sl); + /* write 0 to the first word of the page to be erased */ + stlink_write_debug32(sl, flashaddr, 0); + + /* MP: It is better to wait for clearing the busy bit after issuing + page erase command, even though PM0062 recommends to wait before it. + Test shows that a few iterations is performed in the following loop + before busy bit is cleared.*/ + while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) + ; + + /* reset lock bits */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR) + | (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + } else if (sl->core_id == STM32VL_CORE_ID + || sl->core_id == STM32F0_CORE_ID + || sl->chip_id == STM32_CHIPID_F3 + || sl->chip_id == STM32_CHIPID_F37x) { + /* wait for ongoing op to finish */ + wait_flash_busy(sl); - /* unlock if locked */ - unlock_flash_if(sl); + /* unlock if locked */ + unlock_flash_if(sl); - /* set the page erase bit */ - set_flash_cr_per(sl); + /* set the page erase bit */ + set_flash_cr_per(sl); - /* select the page to erase */ - write_flash_ar(sl, flashaddr); + /* select the page to erase */ + write_flash_ar(sl, flashaddr); - /* start erase operation, reset by hw with bsy bit */ - set_flash_cr_strt(sl); + /* start erase operation, reset by hw with bsy bit */ + set_flash_cr_strt(sl); - /* wait for completion */ - wait_flash_busy(sl); + /* wait for completion */ + wait_flash_busy(sl); - /* relock the flash */ - lock_flash(sl); - } else { - WLOG("unknown coreid %x, page erase failed\n", sl->core_id); - return -1; - } + /* relock the flash */ + lock_flash(sl); + } else { + WLOG("unknown coreid %x, page erase failed\n", sl->core_id); + return -1; + } - /* todo: verify the erased page */ + /* todo: verify the erased page */ - return 0; + return 0; } int stlink_erase_flash_mass(stlink_t *sl) { if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { /* erase each page */ int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -1266,13 +1266,13 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0x0A, 0x4C, // ldr r4, STM32_FLASH_BASE 0x01, 0x25, // mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ 0x04, 0x26, // mov r6, #4 /* PGERR */ - // write_half_word: + // write_half_word: 0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */ 0x2B, 0x43, // orr r3, r5 0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ 0x03, 0x88, // ldrh r3, [r0] /* r3 = *sram */ 0x0B, 0x80, // strh r3, [r1] /* *flash = r3 */ - // busy: + // busy: 0xE3, 0x68, // ldr r3, [r4, #12] /* FLASH->SR */ 0x2B, 0x42, // tst r3, r5 /* FLASH_SR_BUSY */ 0xFC, 0xD0, // beq busy @@ -1285,7 +1285,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0x01, 0x3A, // sub r2, r2, #0x01 /* count-- */ 0x00, 0x2A, // cmp r2, #0 0xF0, 0xD1, // bne write_half_word - // exit: + // exit: 0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */ 0xAB, 0x43, // bic r3, r5 0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ @@ -1300,7 +1300,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { r1, input, source addr r2, input, word count r3, output, word count - */ + */ 0x00, 0x23, 0x04, 0xe0, @@ -1340,14 +1340,14 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { size_t loader_size; if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { /* stm32l */ + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || - sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD){ + sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD){ loader_code = loader_code_stm32f4; loader_size = sizeof(loader_code_stm32f4); } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL) { @@ -1473,7 +1473,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t size_t off; flash_loader_t fl; ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", - len, len, addr, addr); + len, len, addr, addr); /* check addr range is inside the flash */ stlink_calculate_pagesize(sl, addr); if (addr < sl->flash_base) { @@ -1507,17 +1507,17 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t return -1; } fprintf(stdout,"\rFlash page at addr: 0x%08lx erased", - (unsigned long)addr + off); + (unsigned long)addr + off); fflush(stdout); page_count++; } fprintf(stdout,"\n"); ILOG("Finished erasing %d pages of %d (%#x) bytes\n", - page_count, sl->flash_pgsz, sl->flash_pgsz); + page_count, sl->flash_pgsz, sl->flash_pgsz); if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { - /* todo: check write operation */ + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + /* todo: check write operation */ ILOG("Starting Flash write for F2/F4\n"); /* flash loader initialization */ @@ -1526,15 +1526,15 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t return -1; } - /* First unlock the cr */ - unlock_flash_if(sl); + /* First unlock the cr */ + unlock_flash_if(sl); - /* TODO: Check that Voltage range is 2.7 - 3.6 V */ - /* set parallelisim to 32 bit*/ - write_flash_cr_psiz(sl, 2); + /* TODO: Check that Voltage range is 2.7 - 3.6 V */ + /* set parallelisim to 32 bit*/ + write_flash_cr_psiz(sl, 2); - /* set programming mode */ - set_flash_cr_pg(sl); + /* set programming mode */ + set_flash_cr_pg(sl); for(off = 0; off < len;) { size_t size = len - off > 0x8000 ? 0x8000 : len - off; @@ -1551,8 +1551,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t #if 0 #define PROGRESS_CHUNK_SIZE 0x1000 - /* write a word in program memory */ - for (off = 0; off < len; off += sizeof(uint32_t)) { + /* write a word in program memory */ + for (off = 0; off < len; off += sizeof(uint32_t)) { uint32_t data; if (sl->verbose >= 1) { if ((off & (PROGRESS_CHUNK_SIZE - 1)) == 0) { @@ -1569,65 +1569,65 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t stlink_write_debug32(sl, addr + off, data); /* wait for sr.busy to be cleared */ - wait_flash_busy(sl); + wait_flash_busy(sl); - } + } #endif - /* Relock flash */ - lock_flash(sl); + /* Relock flash */ + lock_flash(sl); #if 0 /* todo: debug mode */ - fprintf(stdout, "Final CR:0x%x\n", read_flash_cr(sl)); + fprintf(stdout, "Final CR:0x%x\n", read_flash_cr(sl)); #endif } //STM32F4END else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { - /* use fast word write. todo: half page. */ - uint32_t val; + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { + /* use fast word write. todo: half page. */ + uint32_t val; #if 0 /* todo: check write operation */ - uint32_t nwrites = sl->flash_pgsz; + uint32_t nwrites = sl->flash_pgsz; - redo_write: +redo_write: #endif /* todo: check write operation */ - /* disable pecr protection */ - stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); - stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405); - - /* check pecr.pelock is cleared */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 0)) { - fprintf(stderr, "pecr.pelock not clear\n"); - return -1; - } - - /* unlock program memory */ - stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf); - stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516); - - /* check pecr.prglock is cleared */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 1)) { - fprintf(stderr, "pecr.prglock not clear\n"); - return -1; - } - off = 0; + /* disable pecr protection */ + stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); + stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405); + + /* check pecr.pelock is cleared */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + if (val & (1 << 0)) { + fprintf(stderr, "pecr.pelock not clear\n"); + return -1; + } + + /* unlock program memory */ + stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf); + stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516); + + /* check pecr.prglock is cleared */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + if (val & (1 << 1)) { + fprintf(stderr, "pecr.prglock not clear\n"); + return -1; + } + off = 0; if (len > L1_WRITE_BLOCK_SIZE) { if (stm32l1_write_half_pages(sl, addr, base, len/L1_WRITE_BLOCK_SIZE) == -1) { - /* This may happen on a blank device! */ + /* This may happen on a blank device! */ WLOG("\nwrite_half_pages failed == -1\n"); - } else { - off = (len /L1_WRITE_BLOCK_SIZE)*L1_WRITE_BLOCK_SIZE; - } - } + } else { + off = (len /L1_WRITE_BLOCK_SIZE)*L1_WRITE_BLOCK_SIZE; + } + } - /* write remainingword in program memory */ - for ( ; off < len; off += sizeof(uint32_t)) { + /* write remainingword in program memory */ + for ( ; off < len; off += sizeof(uint32_t)) { uint32_t data; if (off > 254) fprintf(stdout, "\r"); @@ -1683,12 +1683,12 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t ++nwrites; #endif /* todo: check redo write operation */ - } + } fprintf(stdout, "\n"); - /* reset lock bits */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR) - | (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + /* reset lock bits */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR) + | (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { ILOG("Starting Flash write for VL/F0 core id\n"); /* flash loader initialization */ @@ -1715,7 +1715,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t if (sl->verbose >= 1) { /* show progress. writing procedure is slow and previous errors are misleading */ - fprintf(stdout, "\r%3u/%lu pages written", write_block_count++, (unsigned long)len/sl->flash_pgsz); + fprintf(stdout, "\r%3u/%lu pages written", write_block_count++, (unsigned long)len/sl->flash_pgsz); fflush(stdout); } } @@ -1740,23 +1740,23 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { int err; unsigned int num_empty = 0, index; unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE )?0:0xff; + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE )?0:0xff; mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { ELOG("map_file() == -1\n"); return -1; } for(index = 0; index < mf.len; index ++) { - if (mf.base[index] == erased_pattern) - num_empty ++; - else - num_empty = 0; + if (mf.base[index] == erased_pattern) + num_empty ++; + else + num_empty = 0; } /* Round down to words */ num_empty -= (num_empty & 3); if(num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); - mf.len -= num_empty; + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); + mf.len -= num_empty; } err = stlink_write_flash(sl, addr, mf.base, mf.len); /* set stack*/ @@ -1781,7 +1781,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1805,7 +1805,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || - sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD) { + sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1839,27 +1839,27 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons /* check written byte count */ if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { - size_t count = size / sizeof(uint32_t); - if (size % sizeof(uint32_t)) ++count; + size_t count = size / sizeof(uint32_t); + if (size % sizeof(uint32_t)) ++count; - stlink_read_reg(sl, 3, &rr); - if (rr.r[3] != count) { - fprintf(stderr, "write error, count == %u\n", rr.r[3]); - return -1; - } + stlink_read_reg(sl, 3, &rr); + if (rr.r[3] != count) { + fprintf(stderr, "write error, count == %u\n", rr.r[3]); + return -1; + } } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { - stlink_read_reg(sl, 2, &rr); - if (rr.r[2] != 0) { - fprintf(stderr, "write error, count == %u\n", rr.r[2]); - return -1; - } + stlink_read_reg(sl, 2, &rr); + if (rr.r[2] != 0) { + fprintf(stderr, "write error, count == %u\n", rr.r[2]); + return -1; + } } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || - sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD) { + sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { @@ -1869,8 +1869,8 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } else { - fprintf(stderr, "unknown coreid 0x%x, can't check written byte count\n", sl->core_id); - return -1; + fprintf(stderr, "unknown coreid 0x%x, can't check written byte count\n", sl->core_id); + return -1; } diff --git a/src/stlink-common.h b/src/stlink-common.h index 1bedbf497..898b2a59a 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -7,7 +7,7 @@ */ #ifndef STLINK_COMMON_H -#define STLINK_COMMON_H +#define STLINK_COMMON_H #ifdef __cplusplus extern "C" { @@ -77,12 +77,12 @@ extern "C" { #define STLINK_JTAG_DRIVE_NRST 0x3c #define STLINK_JTAG_DRIVE_NRST 0x3c -// cortex m3 technical reference manual + // cortex m3 technical reference manual #define CM3_REG_CPUID 0xE000ED00 #define CM3_REG_FP_CTRL 0xE0002000 #define CM3_REG_FP_COMP0 0xE0002008 -/* cortex core ids */ + /* cortex core ids */ // TODO clean this up... #define STM32VL_CORE_ID 0x1ba01477 #define STM32L_CORE_ID 0x2ba01477 @@ -93,11 +93,11 @@ extern "C" { #define CORE_M3_R2 0x4BA00477 #define CORE_M4_R0 0x2BA01477 -/* - * Chip IDs are explained in the appropriate programming manual for the - * DBGMCU_IDCODE register (0xE0042000) - */ -// stm32 chipids, only lower 12 bits.. + /* + * Chip IDs are explained in the appropriate programming manual for the + * DBGMCU_IDCODE register (0xE0042000) + */ + // stm32 chipids, only lower 12 bits.. #define STM32_CHIPID_F1_MEDIUM 0x410 #define STM32_CHIPID_F2 0x411 #define STM32_CHIPID_F1_LOW 0x412 @@ -132,252 +132,252 @@ extern "C" { #define STM32_CHIPID_F0_CAN 0x448 -/* - * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" - * and some that are called "High". 0x427 is assigned to the other "Medium- - * plus" chips. To make it a bit simpler we just call 427 MEDIUM_PLUS and - * 0x436 HIGH. - */ + /* + * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" + * and some that are called "High". 0x427 is assigned to the other "Medium- + * plus" chips. To make it a bit simpler we just call 427 MEDIUM_PLUS and + * 0x436 HIGH. + */ -// Constant STM32 memory map figures + // Constant STM32 memory map figures #define STM32_FLASH_BASE 0x08000000 #define STM32_SRAM_BASE 0x20000000 -/* Cortex™-M3 Technical Reference Manual */ -/* Debug Halting Control and Status Register */ + /* Cortex™-M3 Technical Reference Manual */ + /* Debug Halting Control and Status Register */ #define DHCSR 0xe000edf0 #define DCRSR 0xe000edf4 #define DCRDR 0xe000edf8 #define DBGKEY 0xa05f0000 -/* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ + /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ #define C_BUF_LEN 32 typedef struct chip_params_ { - uint32_t chip_id; - char* description; + uint32_t chip_id; + char* description; uint32_t flash_size_reg; - uint32_t flash_pagesize; - uint32_t sram_size; - uint32_t bootrom_base, bootrom_size; + uint32_t flash_pagesize; + 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[] = { + // 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[] = { { // table 2, PM0063 .chip_id = STM32_CHIPID_F1_MEDIUM, .description = "F1 Medium-density device", .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x5000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .flash_pagesize = 0x400, + .sram_size = 0x5000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, { // table 1, PM0059 .chip_id = STM32_CHIPID_F2, - .description = "F2 device", - .flash_size_reg = 0x1fff7a22, /* As in RM0033 Rev 5*/ - .flash_pagesize = 0x20000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .description = "F2 device", + .flash_size_reg = 0x1fff7a22, /* As in RM0033 Rev 5*/ + .flash_pagesize = 0x20000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 }, { // PM0063 .chip_id = STM32_CHIPID_F1_LOW, - .description = "F1 Low-density device", - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2800, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .description = "F1 Low-density device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2800, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, { .chip_id = STM32_CHIPID_F4, - .description = "F4 device", - .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ - .flash_pagesize = 0x4000, - .sram_size = 0x30000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .description = "F4 device", + .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ + .flash_pagesize = 0x4000, + .sram_size = 0x30000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 }, { .chip_id = STM32_CHIPID_F4_HD, - .description = "F42x and F43x device", - .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ - .flash_pagesize = 0x4000, - .sram_size = 0x30000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .description = "F42x and F43x device", + .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ + .flash_pagesize = 0x4000, + .sram_size = 0x30000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 }, { .chip_id = STM32_CHIPID_F4_LP, - .description = "F4 device (low power)", - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x10000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .description = "F4 device (low power)", + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x10000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 }, { .chip_id = STM32_CHIPID_F4_DE, - .description = "F4 device (Dynamic Efficency)", - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .description = "F4 device (Dynamic Efficency)", + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x18000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 }, { .chip_id = STM32_CHIPID_F1_HIGH, - .description = "F1 High-density device", - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .description = "F1 High-density device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, { - // This ignores the EEPROM! (and uses the page erase size, - // not the sector write protection...) + // This ignores the EEPROM! (and uses the page erase size, + // not the sector write protection...) .chip_id = STM32_CHIPID_L1_MEDIUM, - .description = "L1 Med-density device", - .flash_size_reg = 0x1ff8004c, - .flash_pagesize = 0x100, - .sram_size = 0x4000, - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 + .description = "L1 Med-density device", + .flash_size_reg = 0x1ff8004c, + .flash_pagesize = 0x100, + .sram_size = 0x4000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 }, { .chip_id = STM32_CHIPID_L1_MEDIUM_PLUS, - .description = "L1 Medium-Plus-density device", - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x8000,/*Not completely clear if there are some with 48K*/ - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 + .description = "L1 Medium-Plus-density device", + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0x8000,/*Not completely clear if there are some with 48K*/ + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 }, { .chip_id = STM32_CHIPID_L1_HIGH, - .description = "L1 High-density device", - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0xC000, /*Not completely clear if there are some with 32K*/ - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 + .description = "L1 High-density device", + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0xC000, /*Not completely clear if there are some with 32K*/ + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 }, { .chip_id = STM32_CHIPID_L152_RE, - .description = "L152RE", - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x14000, /*Not completely clear if there are some with 32K*/ - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 + .description = "L152RE", + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0x14000, /*Not completely clear if there are some with 32K*/ + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 }, { .chip_id = STM32_CHIPID_F1_CONN, - .description = "F1 Connectivity line device", - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1fffb000, - .bootrom_size = 0x4800 + .description = "F1 Connectivity line device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1fffb000, + .bootrom_size = 0x4800 }, { .chip_id = STM32_CHIPID_F1_VL_MEDIUM, - .description = "F1 Medium-density Value Line device", - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .description = "F1 Medium-density Value Line device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, { - // This is STK32F303VCT6 device from STM32 F3 Discovery board. - // Support based on DM00043574.pdf (RM0316) document. + // This is STK32F303VCT6 device from STM32 F3 Discovery board. + // Support based on DM00043574.pdf (RM0316) document. .chip_id = STM32_CHIPID_F3, - .description = "F3 device", - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .description = "F3 device", + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, { - // This is STK32F373VCT6 device from STM32 F373 eval board - // Support based on 303 above (37x and 30x have same memory map) + // This is STK32F373VCT6 device from STM32 F373 eval board + // Support based on 303 above (37x and 30x have same memory map) .chip_id = STM32_CHIPID_F37x, - .description = "F3 device", - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .description = "F3 device", + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, { .chip_id = STM32_CHIPID_F1_VL_HIGH, - .description = "F1 High-density value line device", - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x8000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .description = "F1 High-density value line device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x8000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, { .chip_id = STM32_CHIPID_F1_XL, - .description = "F1 XL-density device", - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x18000, - .bootrom_base = 0x1fffe000, - .bootrom_size = 0x1800 + .description = "F1 XL-density device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x18000, + .bootrom_base = 0x1fffe000, + .bootrom_size = 0x1800 }, - { - //Use this as an example for mapping future chips: - //RM0091 document was used to find these paramaters + { + //Use this as an example for mapping future chips: + //RM0091 document was used to find these paramaters .chip_id = STM32_CHIPID_F0_CAN, - .description = "F07x device", - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 - .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 - .bootrom_size = 0x3000 // "System memory" byte size in hex from Table 2 + .description = "F07x device", + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 + .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 + .bootrom_size = 0x3000 // "System memory" byte size in hex from Table 2 }, { //Use this as an example for mapping future chips: //RM0091 document was used to find these paramaters .chip_id = STM32_CHIPID_F0, - .description = "F0 device", - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + .description = "F0 device", + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 }, { //Use this as an example for mapping future chips: //RM0091 document was used to find these paramaters .chip_id = STM32_CHIPID_F0_SMALL, - .description = "F0 small device", - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + .description = "F0 small device", + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 }, { - // STM32F30x + // STM32F30x .chip_id = STM32_CHIPID_F3_SMALL, - .description = "F3 small device", - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1fffd800, - .bootrom_size = 0x2000 + .description = "F3 small device", + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1fffd800, + .bootrom_size = 0x2000 }, - }; + }; typedef struct { @@ -566,4 +566,3 @@ static const chip_params_t devices[] = { #endif #endif /* STLINK_COMMON_H */ - diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 53e93cce0..1aefe6135 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -1,77 +1,77 @@ /* - Copyright (c) 2010 "Capt'ns Missing Link" Authors. All rights reserved. - Use of this source code is governed by a BSD-style - license that can be found in the LICENSE file. - - A linux stlink access demo. The purpose of this file is to mitigate the usual - "reinventing the wheel" force by incompatible licenses and give you an idea, - how to access the stlink device. That doesn't mean you should be a free-loader - and not contribute your improvements to this code. - - Author: Martin Capitanio - The stlink related constants kindly provided by Oliver Spencer (OpenOCD) - for use in a GPL compatible license. - - Tested compatibility: linux, gcc >= 4.3.3 - - The communication is based on standard USB mass storage device - BOT (Bulk Only Transfer) - - Endpoint 1: BULK_IN, 64 bytes max - - Endpoint 2: BULK_OUT, 64 bytes max - - All CBW transfers are ordered with the LSB (byte 0) first (little endian). - Any command must be answered before sending the next command. - Each USB transfer must complete in less than 1s. - - SB Device Class Definition for Mass Storage Devices: - www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf - - dt - Data Transfer (IN/OUT) - CBW - Command Block Wrapper - CSW - Command Status Wrapper - RFU - Reserved for Future Use - - Originally, this driver used scsi pass through commands, which required the - usb-storage module to be loaded, providing the /dev/sgX links. The USB mass - storage implementation on the STLinkv1 is however terribly broken, and it can - take many minutes for the kernel to give up. - - However, in Nov 2011, the scsi pass through was replaced by raw libusb, so - instead of having to let usb-storage struggle with the device, and also greatly - limiting the portability of the driver, you can now tell usb-storage to simply - ignore this device completely. - - usb-storage.quirks - http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob_plain;f=Documentation/kernel-parameters.txt - Each entry has the form VID:PID:Flags where VID and PID are Vendor and Product - ID values (4-digit hex numbers) and Flags is a set of characters, each corresponding - to a common usb-storage quirk flag as follows: - - a = SANE_SENSE (collect more than 18 bytes of sense data); - b = BAD_SENSE (don't collect more than 18 bytes of sense data); - c = FIX_CAPACITY (decrease the reported device capacity by one sector); - h = CAPACITY_HEURISTICS (decrease the reported device capacity by one sector if the number is odd); - i = IGNORE_DEVICE (don't bind to this device); - l = NOT_LOCKABLE (don't try to lock and unlock ejectable media); - m = MAX_SECTORS_64 (don't transfer more than 64 sectors = 32 KB at a time); - o = CAPACITY_OK (accept the capacity reported by the device); - r = IGNORE_RESIDUE (the device reports bogus residue values); - s = SINGLE_LUN (the device has only one Logical Unit); - w = NO_WP_DETECT (don't test whether the medium is write-protected). - - Example: quirks=0419:aaf5:rl,0421:0433:rc - http://permalink.gmane.org/gmane.linux.usb.general/35053 - - For the stlinkv1, you just want the following - - modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i - - Equivalently, you can add a line saying - - options usb-storage quirks=483:3744:i - - to your /etc/modprobe.conf or /etc/modprobe.d/local.conf (or add the "quirks=..." - part to an existing options line for usb-storage). + * Copyright (c) 2010 "Capt'ns Missing Link" Authors. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * + * A linux stlink access demo. The purpose of this file is to mitigate the usual + * "reinventing the wheel" force by incompatible licenses and give you an idea, + * how to access the stlink device. That doesn't mean you should be a free-loader + * and not contribute your improvements to this code. + * + * Author: Martin Capitanio + * The stlink related constants kindly provided by Oliver Spencer (OpenOCD) + * for use in a GPL compatible license. + * + * Tested compatibility: linux, gcc >= 4.3.3 + * + * The communication is based on standard USB mass storage device + * BOT (Bulk Only Transfer) + * - Endpoint 1: BULK_IN, 64 bytes max + * - Endpoint 2: BULK_OUT, 64 bytes max + * + * All CBW transfers are ordered with the LSB (byte 0) first (little endian). + * Any command must be answered before sending the next command. + * Each USB transfer must complete in less than 1s. + * + * SB Device Class Definition for Mass Storage Devices: + * www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf + * + * dt - Data Transfer (IN/OUT) + * CBW - Command Block Wrapper + * CSW - Command Status Wrapper + * RFU - Reserved for Future Use + * + * Originally, this driver used scsi pass through commands, which required the + * usb-storage module to be loaded, providing the /dev/sgX links. The USB mass + * storage implementation on the STLinkv1 is however terribly broken, and it can + * take many minutes for the kernel to give up. + * + * However, in Nov 2011, the scsi pass through was replaced by raw libusb, so + * instead of having to let usb-storage struggle with the device, and also greatly + * limiting the portability of the driver, you can now tell usb-storage to simply + * ignore this device completely. + * + * usb-storage.quirks + * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob_plain;f=Documentation/kernel-parameters.txt + * Each entry has the form VID:PID:Flags where VID and PID are Vendor and Product + * ID values (4-digit hex numbers) and Flags is a set of characters, each corresponding + * to a common usb-storage quirk flag as follows: + * + * a = SANE_SENSE (collect more than 18 bytes of sense data); + * b = BAD_SENSE (don't collect more than 18 bytes of sense data); + * c = FIX_CAPACITY (decrease the reported device capacity by one sector); + * h = CAPACITY_HEURISTICS (decrease the reported device capacity by one sector if the number is odd); + * i = IGNORE_DEVICE (don't bind to this device); + * l = NOT_LOCKABLE (don't try to lock and unlock ejectable media); + * m = MAX_SECTORS_64 (don't transfer more than 64 sectors = 32 KB at a time); + * o = CAPACITY_OK (accept the capacity reported by the device); + * r = IGNORE_RESIDUE (the device reports bogus residue values); + * s = SINGLE_LUN (the device has only one Logical Unit); + * w = NO_WP_DETECT (don't test whether the medium is write-protected). + * + * Example: quirks=0419:aaf5:rl,0421:0433:rc + * http://permalink.gmane.org/gmane.linux.usb.general/35053 + * + * For the stlinkv1, you just want the following + * + * modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i + * + * Equivalently, you can add a line saying + * + * options usb-storage quirks=483:3744:i + * + * to your /etc/modprobe.conf or /etc/modprobe.d/local.conf (or add the "quirks=..." + * part to an existing options line for usb-storage). */ @@ -108,7 +108,8 @@ static void clear_cdb(struct stlink_libsg *sl) { /** * Close and free any _backend_ related information... * @param sl - */void _stlink_sg_close(stlink_t *sl) { + */ +void _stlink_sg_close(stlink_t *sl) { if (sl) { struct stlink_libsg *slsg = sl->backend_data; libusb_close(slsg->usb_handle); @@ -126,7 +127,7 @@ static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t end int try = 0; do { ret = libusb_bulk_transfer(handle, endpoint, (unsigned char *)&csw, sizeof(csw), - &transferred, SG_TIMEOUT_MSEC); + &transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint); } @@ -175,11 +176,11 @@ static int dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) { * @param lun * @param flags * @param expected_rx_size - * @return + * @return */ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint_out, - uint8_t *cdb, uint8_t cdb_length, - uint8_t lun, uint8_t flags, uint32_t expected_rx_size) { + uint8_t *cdb, uint8_t cdb_length, + uint8_t lun, uint8_t flags, uint32_t expected_rx_size) { DLOG("Sending usb m-s cmd: cdblen:%d, rxsize=%d\n", cdb_length, expected_rx_size); dump_CDB_command(cdb, cdb_length); @@ -211,13 +212,13 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint // Now the actual CDB request assert(cdb_length <= CDB_SL); memcpy(&(c_buf[i]), cdb, cdb_length); - + int sending_length = STLINK_SG_SIZE; - + // send.... do { ret = libusb_bulk_transfer(handle, endpoint_out, c_buf, sending_length, - &real_transferred, SG_TIMEOUT_MSEC); + &real_transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint_out); } @@ -237,7 +238,7 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint * @param endpoint_in * @param endpoint_out */ -static void + static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out) { DLOG("Fetching sense...\n"); @@ -248,7 +249,7 @@ get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_ou cdb[0] = REQUEST_SENSE; cdb[4] = REQUEST_SENSE_LENGTH; uint32_t tag = send_usb_mass_storage_command(handle, endpoint_out, cdb, sizeof(cdb), 0, - LIBUSB_ENDPOINT_IN, REQUEST_SENSE_LENGTH); + LIBUSB_ENDPOINT_IN, REQUEST_SENSE_LENGTH); if (tag == 0) { WLOG("refusing to send request sense with tag 0\n"); return; @@ -259,7 +260,7 @@ get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_ou int try = 0; do { ret = libusb_bulk_transfer(handle, endpoint_in, sense, sizeof(sense), - &transferred, SG_TIMEOUT_MSEC); + &transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint_in); } @@ -289,20 +290,20 @@ get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_ou * Just send a buffer on an endpoint, no questions asked. * Handles repeats, and time outs. Also handles reading status reports and sense * @param handle libusb device * - * @param endpoint_out sends - * @param endpoint_in used to read status reports back in + * @param endpoint_out sends + * @param endpoint_in used to read status reports back in * @param cbuf what to send * @param length how much to send * @return number of bytes actually sent, or -1 for failures. */ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, - unsigned char endpoint_in, unsigned char *cbuf, unsigned int length) { + unsigned char endpoint_in, unsigned char *cbuf, unsigned int length) { int ret; int real_transferred; int try = 0; do { ret = libusb_bulk_transfer(handle, endpoint_out, cbuf, length, - &real_transferred, SG_TIMEOUT_MSEC); + &real_transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint_out); } @@ -312,7 +313,7 @@ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, WLOG("sending failed: %d\n", ret); return -1; } - + // now, swallow up the status, so that things behave nicely... uint32_t received_tag; // -ve is for my errors, 0 is good, +ve is libusb sense status bytes @@ -328,7 +329,7 @@ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, get_sense(handle, endpoint_in, endpoint_out); return -1; } - + return real_transferred; } @@ -338,10 +339,10 @@ int stlink_q(stlink_t *sl) { //uint8_t cdb_len = 6; // FIXME varies!!! uint8_t cdb_len = 10; // FIXME varies!!! uint8_t lun = 0; // always zero... - uint32_t tag = send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, - sg->cdb_cmd_blk, cdb_len, lun, LIBUSB_ENDPOINT_IN, sl->q_len); - - + uint32_t tag = send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, + sg->cdb_cmd_blk, cdb_len, lun, LIBUSB_ENDPOINT_IN, sl->q_len); + + // now wait for our response... // length copied from stlink-usb... int rx_length = sl->q_len; @@ -350,8 +351,8 @@ int stlink_q(stlink_t *sl) { int ret; if (rx_length > 0) { do { - ret = libusb_bulk_transfer(sg->usb_handle, sg->ep_rep, sl->q_buf, rx_length, - &real_transferred, SG_TIMEOUT_MSEC); + ret = libusb_bulk_transfer(sg->usb_handle, sg->ep_rep, sl->q_buf, rx_length, + &real_transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(sg->usb_handle, sg->ep_req); } @@ -401,14 +402,14 @@ void stlink_stat(stlink_t *stl, char *txt) { stlink_print_data(stl); switch (stl->q_buf[0]) { - case STLINK_OK: - DLOG(" %s: ok\n", txt); - return; - case STLINK_FALSE: - DLOG(" %s: false\n", txt); - return; - default: - DLOG(" %s: unknown\n", txt); + case STLINK_OK: + DLOG(" %s: ok\n", txt); + return; + case STLINK_FALSE: + DLOG(" %s: false\n", txt); + return; + default: + DLOG(" %s: unknown\n", txt); } } @@ -471,48 +472,48 @@ void _stlink_sg_exit_dfu_mode(stlink_t *sl) { sl->q_len = 0; // ?? stlink_q(sl); /* - [135121.844564] sd 19:0:0:0: [sdb] Unhandled error code - [135121.844569] sd 19:0:0:0: [sdb] Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK - [135121.844574] sd 19:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 10 00 00 00 08 00 - [135121.844584] end_request: I/O error, dev sdb, sector 4096 - [135121.844590] Buffer I/O error on device sdb, logical block 512 - [135130.122567] usb 6-1: reset full speed USB device using uhci_hcd and address 7 - [135130.274551] usb 6-1: device firmware changed - [135130.274618] usb 6-1: USB disconnect, address 7 - [135130.275186] VFS: busy inodes on changed media or resized disk sdb - [135130.275424] VFS: busy inodes on changed media or resized disk sdb - [135130.286758] VFS: busy inodes on changed media or resized disk sdb - [135130.292796] VFS: busy inodes on changed media or resized disk sdb - [135130.301481] VFS: busy inodes on changed media or resized disk sdb - [135130.304316] VFS: busy inodes on changed media or resized disk sdb - [135130.431113] usb 6-1: new full speed USB device using uhci_hcd and address 8 - [135130.629444] usb-storage 6-1:1.0: Quirks match for vid 0483 pid 3744: 102a1 - [135130.629492] scsi20 : usb-storage 6-1:1.0 - [135131.625600] scsi 20:0:0:0: Direct-Access STM32 PQ: 0 ANSI: 0 - [135131.627010] sd 20:0:0:0: Attached scsi generic sg2 type 0 - [135131.633603] sd 20:0:0:0: [sdb] 64000 512-byte logical blocks: (32.7 MB/31.2 MiB) - [135131.633613] sd 20:0:0:0: [sdb] Assuming Write Enabled - [135131.633620] sd 20:0:0:0: [sdb] Assuming drive cache: write through - [135131.640584] sd 20:0:0:0: [sdb] Assuming Write Enabled - [135131.640592] sd 20:0:0:0: [sdb] Assuming drive cache: write through - [135131.640609] sdb: - [135131.652634] sd 20:0:0:0: [sdb] Assuming Write Enabled - [135131.652639] sd 20:0:0:0: [sdb] Assuming drive cache: write through - [135131.652645] sd 20:0:0:0: [sdb] Attached SCSI removable disk - [135131.671536] sd 20:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE - [135131.671548] sd 20:0:0:0: [sdb] Sense Key : Illegal Request [current] - [135131.671553] sd 20:0:0:0: [sdb] Add. Sense: Logical block address out of range - [135131.671560] sd 20:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 f9 80 00 00 08 00 - [135131.671570] end_request: I/O error, dev sdb, sector 63872 - [135131.671575] Buffer I/O error on device sdb, logical block 7984 - [135131.678527] sd 20:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE - [135131.678532] sd 20:0:0:0: [sdb] Sense Key : Illegal Request [current] - [135131.678537] sd 20:0:0:0: [sdb] Add. Sense: Logical block address out of range - [135131.678542] sd 20:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 f9 80 00 00 08 00 - [135131.678551] end_request: I/O error, dev sdb, sector 63872 - ... - [135131.853565] end_request: I/O error, dev sdb, sector 4096 - */ + [135121.844564] sd 19:0:0:0: [sdb] Unhandled error code + [135121.844569] sd 19:0:0:0: [sdb] Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK + [135121.844574] sd 19:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 10 00 00 00 08 00 + [135121.844584] end_request: I/O error, dev sdb, sector 4096 + [135121.844590] Buffer I/O error on device sdb, logical block 512 + [135130.122567] usb 6-1: reset full speed USB device using uhci_hcd and address 7 + [135130.274551] usb 6-1: device firmware changed + [135130.274618] usb 6-1: USB disconnect, address 7 + [135130.275186] VFS: busy inodes on changed media or resized disk sdb + [135130.275424] VFS: busy inodes on changed media or resized disk sdb + [135130.286758] VFS: busy inodes on changed media or resized disk sdb + [135130.292796] VFS: busy inodes on changed media or resized disk sdb + [135130.301481] VFS: busy inodes on changed media or resized disk sdb + [135130.304316] VFS: busy inodes on changed media or resized disk sdb + [135130.431113] usb 6-1: new full speed USB device using uhci_hcd and address 8 + [135130.629444] usb-storage 6-1:1.0: Quirks match for vid 0483 pid 3744: 102a1 + [135130.629492] scsi20 : usb-storage 6-1:1.0 + [135131.625600] scsi 20:0:0:0: Direct-Access STM32 PQ: 0 ANSI: 0 + [135131.627010] sd 20:0:0:0: Attached scsi generic sg2 type 0 + [135131.633603] sd 20:0:0:0: [sdb] 64000 512-byte logical blocks: (32.7 MB/31.2 MiB) + [135131.633613] sd 20:0:0:0: [sdb] Assuming Write Enabled + [135131.633620] sd 20:0:0:0: [sdb] Assuming drive cache: write through + [135131.640584] sd 20:0:0:0: [sdb] Assuming Write Enabled + [135131.640592] sd 20:0:0:0: [sdb] Assuming drive cache: write through + [135131.640609] sdb: + [135131.652634] sd 20:0:0:0: [sdb] Assuming Write Enabled + [135131.652639] sd 20:0:0:0: [sdb] Assuming drive cache: write through + [135131.652645] sd 20:0:0:0: [sdb] Attached SCSI removable disk + [135131.671536] sd 20:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE + [135131.671548] sd 20:0:0:0: [sdb] Sense Key : Illegal Request [current] + [135131.671553] sd 20:0:0:0: [sdb] Add. Sense: Logical block address out of range + [135131.671560] sd 20:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 f9 80 00 00 08 00 + [135131.671570] end_request: I/O error, dev sdb, sector 63872 + [135131.671575] Buffer I/O error on device sdb, logical block 7984 + [135131.678527] sd 20:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE + [135131.678532] sd 20:0:0:0: [sdb] Sense Key : Illegal Request [current] + [135131.678537] sd 20:0:0:0: [sdb] Add. Sense: Logical block address out of range + [135131.678542] sd 20:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 f9 80 00 00 08 00 + [135131.678551] end_request: I/O error, dev sdb, sector 63872 + ... + [135131.853565] end_request: I/O error, dev sdb, sector 4096 + */ } void _stlink_sg_core_id(stlink_t *sl) { @@ -586,7 +587,7 @@ void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { stlink_print_data(sl); // TODO - most of this should be re-extracted up.... - + // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71 | 72-75 | 76-79 | 80-83 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 for (int i = 0; i < 16; i++) { @@ -630,23 +631,23 @@ void _stlink_sg_read_reg(stlink_t *sl, int r_idx, reg *regp) { DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); switch (r_idx) { - case 16: - regp->xpsr = r; - break; - case 17: - regp->main_sp = r; - break; - case 18: - regp->process_sp = r; - break; - case 19: - regp->rw = r; //XXX ?(primask, basemask etc.) - break; - case 20: - regp->rw2 = r; //XXX ?(primask, basemask etc.) - break; - default: - regp->r[r_idx] = r; + case 16: + regp->xpsr = r; + break; + case 17: + regp->main_sp = r; + break; + case 18: + regp->process_sp = r; + break; + case 19: + regp->rw = r; //XXX ?(primask, basemask etc.) + break; + case 20: + regp->rw2 = r; //XXX ?(primask, basemask etc.) + break; + default: + regp->r[r_idx] = r; } } @@ -883,7 +884,7 @@ stlink_backend_t _stlink_sg_backend = { }; static stlink_t* stlink_open(const int verbose) { - + stlink_t *sl = malloc(sizeof (stlink_t)); memset(sl, 0, sizeof(stlink_t)); struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg)); @@ -891,16 +892,16 @@ static stlink_t* stlink_open(const int verbose) { WLOG("Couldn't malloc stlink and stlink_sg structures out of memory!\n"); return NULL; } - + if (libusb_init(&(slsg->libusb_ctx))) { WLOG("failed to init libusb context, wrong version of libraries?\n"); free(sl); free(slsg); return NULL; } - + libusb_set_debug(slsg->libusb_ctx, 3); - + slsg->usb_handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, USB_ST_VID, USB_STLINK_PID); if (slsg->usb_handle == NULL) { WLOG("Failed to find an stlink v1 by VID:PID\n"); @@ -910,10 +911,10 @@ static stlink_t* stlink_open(const int verbose) { free(slsg); return NULL; } - - // TODO + + // TODO // Could read the interface config descriptor, and assert lots of the assumptions - + // assumption: numInterfaces is always 1... if (libusb_kernel_driver_active(slsg->usb_handle, 0) == 1) { int r = libusb_detach_kernel_driver(slsg->usb_handle, 0); @@ -939,7 +940,7 @@ static stlink_t* stlink_open(const int verbose) { return NULL; } - + // assumption: bConfigurationValue is always 1 if (config != 1) { WLOG("Your stlink got into a real weird configuration, trying to fix it!\n"); @@ -967,9 +968,9 @@ static stlink_t* stlink_open(const int verbose) { // assumption: endpoint config is fixed mang. really. slsg->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; slsg->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; - + DLOG("Successfully opened stlinkv1 by libusb :)\n"); - + sl->verbose = verbose; sl->backend_data = slsg; sl->backend = &_stlink_sg_backend; @@ -991,15 +992,15 @@ stlink_t* stlink_v1_open_inner(const int verbose) { stlink_version(sl); if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { - ugly_log(UERROR, LOG_TAG, - "WTF? successfully opened, but unable to read version details. BROKEN!\n"); + ugly_log(UERROR, LOG_TAG, + "WTF? successfully opened, but unable to read version details. BROKEN!\n"); return NULL; } DLOG("Reading current mode...\n"); switch (stlink_current_mode(sl)) { case STLINK_DEV_MASS_MODE: - return sl; + return sl; case STLINK_DEV_DEBUG_MODE: // TODO go to mass? return sl; @@ -1010,12 +1011,12 @@ stlink_t* stlink_v1_open_inner(const int verbose) { DLOG("Attempting to exit DFU mode\n"); _stlink_sg_exit_dfu_mode(sl); - + // re-query device info (and retest) stlink_version(sl); if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { - ugly_log(UERROR, LOG_TAG, - "WTF? successfully opened, but unable to read version details. BROKEN!\n"); + ugly_log(UERROR, LOG_TAG, + "WTF? successfully opened, but unable to read version details. BROKEN!\n"); return NULL; } @@ -1029,7 +1030,7 @@ stlink_t* stlink_v1_open(const int verbose, int reset) { return NULL; } // by now, it _must_ be fully open and in a useful mode.... - stlink_enter_swd_mode(sl); + stlink_enter_swd_mode(sl); /* Now we are ready to read the parameters */ if (reset) { stlink_reset(sl); diff --git a/src/stlink-sg.h b/src/stlink-sg.h index f8871db99..7c0202851 100644 --- a/src/stlink-sg.h +++ b/src/stlink-sg.h @@ -1,4 +1,4 @@ -/* +/* * File: stlink-sg.h * Author: karl * @@ -11,11 +11,11 @@ #ifdef __cplusplus extern "C" { #endif - + #include #include "stlink-common.h" - - // device access + + // device access #define RDWR 0 #define RO 1 #define SG_TIMEOUT_SEC 1 // actually 1 is about 2 sec @@ -46,7 +46,7 @@ extern "C" { libusb_device_handle *usb_handle; unsigned ep_rep; unsigned ep_req; - + int sg_fd; int do_scsi_pt_err; diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 8e910bcf2..23ff19176 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -16,17 +16,17 @@ #define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args) #define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args) -/* code from bsd timersub.h +/* code from bsd timersub.h http://www.gnu-darwin.org/www001/src/ports/net/libevnet/work/libevnet-0.3.8/libnostd/bsd/sys/time/timersub.h.html */ #if !defined timersub #define timersub(a, b, r) do { \ - (r)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (r)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((r)->tv_usec < 0) { \ - --(r)->tv_sec; \ - (r)->tv_usec += 1000000; \ - } \ + (r)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (r)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((r)->tv_usec < 0) { \ + --(r)->tv_sec; \ + (r)->tv_usec += 1000000; \ + } \ } while (0) #endif @@ -135,14 +135,14 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, if (rxsize != 0) { /* read the response */ - + libusb_fill_bulk_transfer(handle->rep_trans, handle->usb_handle, - handle->ep_rep, rxbuf, rxsize, NULL, NULL, 0); - + 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]; @@ -237,7 +237,7 @@ uint32_t _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr) { unsigned char* const cmd = sl->c_buf; ssize_t size; const int rep_len = 8; - + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_JTAG_READDEBUG_32BIT; @@ -256,7 +256,7 @@ void _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { unsigned char* const cmd = sl->c_buf; ssize_t size; const int rep_len = 2; - + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_JTAG_WRITEDEBUG_32BIT; @@ -306,7 +306,7 @@ int _stlink_usb_current_mode(stlink_t * sl) { ssize_t size; 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) { @@ -582,7 +582,7 @@ void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { stlink_print_data(sl); r = read_uint32(sl->q_buf, 0); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); - + switch (r_idx) { case 16: regp->xpsr = r; @@ -620,18 +620,18 @@ void _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); switch (r_idx) { - case 0x14: - regp->primask = (uint8_t) (r & 0xFF); - regp->basepri = (uint8_t) ((r>>8) & 0xFF); - regp->faultmask = (uint8_t) ((r>>16) & 0xFF); - regp->control = (uint8_t) ((r>>24) & 0xFF); - break; - case 0x21: - regp->fpscr = r; - break; - default: - regp->s[r_idx - 0x40] = r; - break; + case 0x14: + regp->primask = (uint8_t) (r & 0xFF); + regp->basepri = (uint8_t) ((r>>8) & 0xFF); + regp->faultmask = (uint8_t) ((r>>16) & 0xFF); + regp->control = (uint8_t) ((r>>24) & 0xFF); + break; + case 0x21: + regp->fpscr = r; + break; + default: + regp->s[r_idx - 0x40] = r; + break; } } @@ -653,18 +653,18 @@ void _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, re val = (uint8_t) (val>>24); switch (r_idx) { - case 0x1C: /* control */ - val = (((uint32_t) val) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) regp->primask); - break; - case 0x1D: /* faultmask */ - val = (((uint32_t) regp->control) << 24) | (((uint32_t) val) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) regp->primask); - break; - case 0x1E: /* basepri */ - val = (((uint32_t) regp->control) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) val) << 8) | ((uint32_t) regp->primask); - break; - case 0x1F: /* primask */ - val = (((uint32_t) regp->control) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) val); - break; + case 0x1C: /* control */ + val = (((uint32_t) val) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) regp->primask); + break; + case 0x1D: /* faultmask */ + val = (((uint32_t) regp->control) << 24) | (((uint32_t) val) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) regp->primask); + break; + case 0x1E: /* basepri */ + val = (((uint32_t) regp->control) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) val) << 8) | ((uint32_t) regp->primask); + break; + case 0x1F: /* primask */ + val = (((uint32_t) regp->control) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) val); + break; } r_idx = 0x14; @@ -750,20 +750,20 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { ugly_init(verbose); sl->backend = &_stlink_usb_backend; sl->backend_data = slu; - + sl->core_stat = STLINK_CORE_STAT_UNKNOWN; if (libusb_init(&(slu->libusb_ctx))) { WLOG("failed to init libusb context, wrong version of libraries?\n"); goto on_error; } - + libusb_device **list; int cnt = libusb_get_device_list(slu->libusb_ctx, &list); struct libusb_device_descriptor desc; int devBus =0; int devAddr=0; - + char *device = getenv("STLINK_DEVICE"); if (device) { char *c = strchr(device,':'); @@ -788,7 +788,7 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { break; } } - + if (cnt < 0) { WLOG ("Couldn't find %s ST-Link/V2 devices\n",(devBus && devAddr)?"matched":"any"); goto on_error; @@ -799,13 +799,13 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { goto on_error; } } - + libusb_free_device_list(list, 1); - + if (libusb_kernel_driver_active(slu->usb_handle, 0) == 1) { int r; - + r = libusb_detach_kernel_driver(slu->usb_handle, 0); if (r<0) { WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-r)); @@ -848,9 +848,9 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { // TODO - could use the scanning techniq from stm8 code here... slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; if (desc.idProduct == USB_STLINK_NUCLEO_PID) { - slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; + slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; } else { - slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; + slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; } slu->sg_transfer_idx = 0; @@ -860,12 +860,12 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { /* success */ if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { - ILOG("-- exit_dfu_mode\n"); - stlink_exit_dfu_mode(sl); + ILOG("-- exit_dfu_mode\n"); + stlink_exit_dfu_mode(sl); } if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { - stlink_enter_swd_mode(sl); + stlink_enter_swd_mode(sl); } if (reset) { @@ -891,7 +891,7 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { on_error: if( slu->libusb_ctx) - libusb_exit(slu->libusb_ctx); + libusb_exit(slu->libusb_ctx); if (sl != NULL) free(sl); if (slu != NULL) free(slu); return 0; diff --git a/src/stlink-usb.h b/src/stlink-usb.h index f433193c8..58b60e430 100644 --- a/src/stlink-usb.h +++ b/src/stlink-usb.h @@ -1,4 +1,4 @@ -/* +/* * File: stlink-usb.h * Author: karl * @@ -14,7 +14,7 @@ extern "C" { #include #include "stlink-common.h" - + #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 @@ -29,7 +29,7 @@ extern "C" { unsigned int sg_transfer_idx; unsigned int cmd_len; }; - + stlink_t* stlink_open_usb(const int verbose, int reset); diff --git a/src/test_sg.c b/src/test_sg.c index bc16a1c7c..dea6ffb21 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -33,196 +33,196 @@ static void __attribute__((unused)) mark_buf(stlink_t *sl) { int main(int argc, char *argv[]) { - /* Avoid unused parameter warning */ - (void)argv; - // set scpi lib debug level: 0 for no debug info, 10 for lots - - switch (argc) { - case 1: - fputs( - "\nUsage: stlink-access-test [anything at all] ...\n" - "\n*** Notice: The stlink firmware violates the USB standard.\n" - "*** Because we just use libusb, we can just tell the kernel's\n" - "*** driver to simply ignore the device...\n" - "*** Unplug the stlink and execute once as root:\n" - "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n\n", - stderr); - return EXIT_FAILURE; - default: + /* Avoid unused parameter warning */ + (void)argv; + // set scpi lib debug level: 0 for no debug info, 10 for lots + + switch (argc) { + case 1: + fputs( + "\nUsage: stlink-access-test [anything at all] ...\n" + "\n*** Notice: The stlink firmware violates the USB standard.\n" + "*** Because we just use libusb, we can just tell the kernel's\n" + "*** driver to simply ignore the device...\n" + "*** Unplug the stlink and execute once as root:\n" + "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n\n", + stderr); + return EXIT_FAILURE; + default: break; - } - - stlink_t *sl = stlink_v1_open(99, 1); - if (sl == NULL) - return EXIT_FAILURE; - - // we are in mass mode, go to swd - stlink_enter_swd_mode(sl); - stlink_current_mode(sl); - stlink_core_id(sl); - //---------------------------------------------------------------------- - - stlink_status(sl); - //stlink_force_debug(sl); - stlink_reset(sl); - stlink_status(sl); - // core system control block - stlink_read_mem32(sl, 0xe000ed00, 4); - DLOG("cpu id base register: SCB_CPUID = got 0x%08x expect 0x411fc231\n", read_uint32(sl->q_buf, 0)); - // no MPU - stlink_read_mem32(sl, 0xe000ed90, 4); - DLOG("mpu type register: MPU_TYPER = got 0x%08x expect 0x0\n", read_uint32(sl->q_buf, 0)); + } + + stlink_t *sl = stlink_v1_open(99, 1); + if (sl == NULL) + return EXIT_FAILURE; + + // we are in mass mode, go to swd + stlink_enter_swd_mode(sl); + stlink_current_mode(sl); + stlink_core_id(sl); + //---------------------------------------------------------------------- + + stlink_status(sl); + //stlink_force_debug(sl); + stlink_reset(sl); + stlink_status(sl); + // core system control block + stlink_read_mem32(sl, 0xe000ed00, 4); + DLOG("cpu id base register: SCB_CPUID = got 0x%08x expect 0x411fc231\n", read_uint32(sl->q_buf, 0)); + // no MPU + stlink_read_mem32(sl, 0xe000ed90, 4); + DLOG("mpu type register: MPU_TYPER = got 0x%08x expect 0x0\n", read_uint32(sl->q_buf, 0)); #if 0 - stlink_read_mem32(sl, 0xe000edf0, 4); - DD(sl, "DHCSR = 0x%08x", read_uint32(sl->q_buf, 0)); + stlink_read_mem32(sl, 0xe000edf0, 4); + DD(sl, "DHCSR = 0x%08x", read_uint32(sl->q_buf, 0)); - stlink_read_mem32(sl, 0x4001100c, 4); - DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); + stlink_read_mem32(sl, 0x4001100c, 4); + DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); #endif #if 0 - // happy new year 2011: let blink all the leds - // see "RM0041 Reference manual - STM32F100xx advanced ARM-based 32-bit MCUs" + // happy new year 2011: let blink all the leds + // see "RM0041 Reference manual - STM32F100xx advanced ARM-based 32-bit MCUs" #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) // pin 8 #define LED_GREEN (1<<9) // pin 9 - stlink_read_mem32(sl, GPIOC_CRH, 4); - uint32_t io_conf = read_uint32(sl->q_buf, 0); - DLOG("GPIOC_CRH = 0x%08x\n", io_conf); - - // set: general purpose output push-pull, output mode, max speed 10 MHz. - write_uint32(sl->q_buf, 0x44444411); - stlink_write_mem32(sl, GPIOC_CRH, 4); - - memset(sl->q_buf, 0, sizeof(sl->q_buf)); - for (int i = 0; i < 100; i++) { - write_uint32(sl->q_buf, LED_BLUE | LED_GREEN); - stlink_write_mem32(sl, GPIOC_ODR, 4); - /* stlink_read_mem32(sl, 0x4001100c, 4); */ - /* DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); */ - usleep(100 * 1000); - - memset(sl->q_buf, 0, sizeof(sl->q_buf)); - stlink_write_mem32(sl, GPIOC_ODR, 4); // PC lo + stlink_read_mem32(sl, GPIOC_CRH, 4); + uint32_t io_conf = read_uint32(sl->q_buf, 0); + DLOG("GPIOC_CRH = 0x%08x\n", io_conf); + + // set: general purpose output push-pull, output mode, max speed 10 MHz. + write_uint32(sl->q_buf, 0x44444411); + stlink_write_mem32(sl, GPIOC_CRH, 4); + + memset(sl->q_buf, 0, sizeof(sl->q_buf)); + for (int i = 0; i < 100; i++) { + write_uint32(sl->q_buf, LED_BLUE | LED_GREEN); + stlink_write_mem32(sl, GPIOC_ODR, 4); + /* stlink_read_mem32(sl, 0x4001100c, 4); */ + /* DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); */ usleep(100 * 1000); - } - write_uint32(sl->q_buf, io_conf); // set old state + + memset(sl->q_buf, 0, sizeof(sl->q_buf)); + stlink_write_mem32(sl, GPIOC_ODR, 4); // PC lo + usleep(100 * 1000); + } + write_uint32(sl->q_buf, io_conf); // set old state #endif #if 0 - // TODO rtfm: stlink doesn't have flash write routines - // writing to the flash area confuses the fw for the next read access - - //stlink_read_mem32(sl, 0, 1024*6); - // flash 0x08000000 128kB - fputs("++++++++++ read a flash at 0x0800 0000\n", stderr); - stlink_read_mem32(sl, 0x08000000, 1024 * 6); //max 6kB - clear_buf(sl); - stlink_read_mem32(sl, 0x08000c00, 5); - stlink_read_mem32(sl, 0x08000c00, 4); - mark_buf(sl); - stlink_write_mem32(sl, 0x08000c00, 4); - stlink_read_mem32(sl, 0x08000c00, 256); - stlink_read_mem32(sl, 0x08000c00, 256); + // TODO rtfm: stlink doesn't have flash write routines + // writing to the flash area confuses the fw for the next read access + + //stlink_read_mem32(sl, 0, 1024*6); + // flash 0x08000000 128kB + fputs("++++++++++ read a flash at 0x0800 0000\n", stderr); + stlink_read_mem32(sl, 0x08000000, 1024 * 6); //max 6kB + clear_buf(sl); + stlink_read_mem32(sl, 0x08000c00, 5); + stlink_read_mem32(sl, 0x08000c00, 4); + mark_buf(sl); + stlink_write_mem32(sl, 0x08000c00, 4); + stlink_read_mem32(sl, 0x08000c00, 256); + stlink_read_mem32(sl, 0x08000c00, 256); #endif #if 0 - // sram 0x20000000 8kB - fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); + // sram 0x20000000 8kB + fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); mark_buf(sl); - //stlink_write_mem8(sl, 0x20000000, 16); + //stlink_write_mem8(sl, 0x20000000, 16); - //stlink_write_mem8(sl, 0x20000000, 1); - //stlink_write_mem8(sl, 0x20000001, 1); - stlink_write_mem8(sl, 0x2000000b, 3); - stlink_read_mem32(sl, 0x20000000, 16); + //stlink_write_mem8(sl, 0x20000000, 1); + //stlink_write_mem8(sl, 0x20000001, 1); + stlink_write_mem8(sl, 0x2000000b, 3); + stlink_read_mem32(sl, 0x20000000, 16); #endif #if 0 - // a not aligned mem32 access doesn't work indeed - fputs("\n++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); + // a not aligned mem32 access doesn't work indeed + fputs("\n++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); - mark_buf(sl); - stlink_write_mem32(sl, 0x20000000, 1); - stlink_read_mem32(sl, 0x20000000, 16); - mark_buf(sl); - stlink_write_mem32(sl, 0x20000001, 1); - stlink_read_mem32(sl, 0x20000000, 16); - mark_buf(sl); - stlink_write_mem32(sl, 0x2000000b, 3); - stlink_read_mem32(sl, 0x20000000, 16); - - mark_buf(sl); - stlink_write_mem32(sl, 0x20000000, 17); - stlink_read_mem32(sl, 0x20000000, 32); + mark_buf(sl); + stlink_write_mem32(sl, 0x20000000, 1); + stlink_read_mem32(sl, 0x20000000, 16); + mark_buf(sl); + stlink_write_mem32(sl, 0x20000001, 1); + stlink_read_mem32(sl, 0x20000000, 16); + mark_buf(sl); + stlink_write_mem32(sl, 0x2000000b, 3); + stlink_read_mem32(sl, 0x20000000, 16); + + mark_buf(sl); + stlink_write_mem32(sl, 0x20000000, 17); + stlink_read_mem32(sl, 0x20000000, 32); #endif #if 0 - // sram 0x20000000 8kB - fputs("++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++\n", stderr); + // sram 0x20000000 8kB + fputs("++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); - mark_buf(sl); - stlink_write_mem8(sl, 0x20000000, 64); - stlink_read_mem32(sl, 0x20000000, 64); - - mark_buf(sl); - stlink_write_mem32(sl, 0x20000000, 1024 * 8); //8kB - stlink_read_mem32(sl, 0x20000000, 1024 * 6); - stlink_read_mem32(sl, 0x20000000 + 1024 * 6, 1024 * 2); + mark_buf(sl); + stlink_write_mem8(sl, 0x20000000, 64); + stlink_read_mem32(sl, 0x20000000, 64); + + mark_buf(sl); + stlink_write_mem32(sl, 0x20000000, 1024 * 8); //8kB + stlink_read_mem32(sl, 0x20000000, 1024 * 6); + stlink_read_mem32(sl, 0x20000000 + 1024 * 6, 1024 * 2); #endif #if 1 reg regs; - stlink_read_all_regs(sl, ®s); - stlink_step(sl); - fputs("++++++++++ write r0 = 0x12345678\n", stderr); - stlink_write_reg(sl, 0x12345678, 0); - stlink_read_reg(sl, 0, ®s); - stlink_read_all_regs(sl, ®s); + stlink_read_all_regs(sl, ®s); + stlink_step(sl); + fputs("++++++++++ write r0 = 0x12345678\n", stderr); + stlink_write_reg(sl, 0x12345678, 0); + stlink_read_reg(sl, 0, ®s); + stlink_read_all_regs(sl, ®s); #endif #if 0 - stlink_run(sl); - stlink_status(sl); + stlink_run(sl); + stlink_status(sl); - stlink_force_debug(sl); - stlink_status(sl); + stlink_force_debug(sl); + stlink_status(sl); #endif #if 0 /* read the system bootloader */ - fputs("\n++++++++++ reading bootloader ++++++++++++++++\n\n", stderr); - stlink_fread(sl, "/tmp/barfoo", sl->sys_base, sl->sys_size); + fputs("\n++++++++++ reading bootloader ++++++++++++++++\n\n", stderr); + stlink_fread(sl, "/tmp/barfoo", sl->sys_base, sl->sys_size); #endif #if 0 /* read the flash memory */ - fputs("\n+++++++ read flash memory\n\n", stderr); - /* mark_buf(sl); */ - stlink_read_mem32(sl, 0x08000000, 4); + fputs("\n+++++++ read flash memory\n\n", stderr); + /* mark_buf(sl); */ + stlink_read_mem32(sl, 0x08000000, 4); #endif #if 0 /* flash programming */ - fputs("\n+++++++ program flash memory\n\n", stderr); - stlink_fwrite_flash(sl, "/tmp/foobar", 0x08000000); + fputs("\n+++++++ program flash memory\n\n", stderr); + stlink_fwrite_flash(sl, "/tmp/foobar", 0x08000000); #endif #if 0 /* check file contents */ - fputs("\n+++++++ check flash memory\n\n", stderr); - { - const int res = stlink_fcheck_flash(sl, "/tmp/foobar", 0x08000000); - printf("_____ stlink_fcheck_flash() == %d\n", res); - } + fputs("\n+++++++ check flash memory\n\n", stderr); + { + const int res = stlink_fcheck_flash(sl, "/tmp/foobar", 0x08000000); + printf("_____ stlink_fcheck_flash() == %d\n", res); + } #endif #if 0 - fputs("\n+++++++ sram write and execute\n\n", stderr); - stlink_fwrite_sram(sl, "/tmp/foobar", sl->sram_base); - stlink_run_at(sl, sl->sram_base); + fputs("\n+++++++ sram write and execute\n\n", stderr); + stlink_fwrite_sram(sl, "/tmp/foobar", sl->sram_base); + stlink_run_at(sl, sl->sram_base); #endif #if 0 - stlink_run(sl); - stlink_status(sl); - //---------------------------------------------------------------------- - // back to mass mode, just in case ... - stlink_exit_debug_mode(sl); - stlink_current_mode(sl); - stlink_close(sl); + stlink_run(sl); + stlink_status(sl); + //---------------------------------------------------------------------- + // back to mass mode, just in case ... + stlink_exit_debug_mode(sl); + stlink_current_mode(sl); + stlink_close(sl); #endif - //fflush(stderr); fflush(stdout); - return EXIT_SUCCESS; + //fflush(stderr); fflush(stdout); + return EXIT_SUCCESS; } diff --git a/src/test_usb.c b/src/test_usb.c index 5e8806d29..eb8e54cdd 100644 --- a/src/test_usb.c +++ b/src/test_usb.c @@ -14,7 +14,7 @@ int main(int ac, char** av) { if (sl != NULL) { printf("-- version\n"); stlink_version(sl); - + printf("mode before doing anything: %d\n", stlink_current_mode(sl)); if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { @@ -43,7 +43,7 @@ int main(int ac, char** av) { printf("FP_CTRL\n"); stlink_read_mem32(sl, CM3_REG_FP_CTRL, 4); - + // no idea what reg this is.. */ // stlink_read_mem32(sl, 0xe000ed90, 4); // no idea what register this is... @@ -58,7 +58,7 @@ int main(int ac, char** av) { stlink_write_mem32(sl,0x200000ac, 4); stlink_read_mem32(sl, 0x200000a8, 4); stlink_read_mem32(sl, 0x200000ac, 4); - + /* Test 8 bit write */ write_uint32(sl->q_buf,0x01234567); stlink_write_mem8(sl,0x200001a8,3); @@ -79,8 +79,8 @@ int main(int ac, char** av) { stlink_write_reg(sl, 0x12345678, 15); for (off = 0; off < 21; off += 1) stlink_read_reg(sl, off, ®s); - - + + stlink_read_all_regs(sl, ®s); printf("-- status\n"); diff --git a/src/uglylogging.c b/src/uglylogging.c index c6d07f89f..a04ab3391 100644 --- a/src/uglylogging.c +++ b/src/uglylogging.c @@ -1,7 +1,7 @@ -/* - * UglyLogging. Slow, yet another wheel reinvented, but enough to make the +/* + * UglyLogging. Slow, yet another wheel reinvented, but enough to make the * rest of our code pretty enough. - * + * */ #include @@ -30,29 +30,29 @@ int ugly_log(int level, const char *tag, const char *format, ...) { tt = localtime(&mytt); fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", tt->tm_year + 1900, tt->tm_mon + 1, tt->tm_mday, tt->tm_hour, tt->tm_min, tt->tm_sec); switch (level) { - case UDEBUG: - fprintf(stderr, "DEBUG %s: ", tag); - break; - case UINFO: - fprintf(stderr, "INFO %s: ", tag); - break; - case UWARN: - fprintf(stderr, "WARN %s: ", tag); - break; - case UERROR: - fprintf(stderr, "ERROR %s: ", tag); - break; - case UFATAL: - fprintf(stderr, "FATAL %s: ", tag); - vfprintf(stderr, format, args); - exit(EXIT_FAILURE); - // NEVER GETS HERE!!! - break; - default: - fprintf(stderr, "%d %s: ", level, tag); - break; + case UDEBUG: + fprintf(stderr, "DEBUG %s: ", tag); + break; + case UINFO: + fprintf(stderr, "INFO %s: ", tag); + break; + case UWARN: + fprintf(stderr, "WARN %s: ", tag); + break; + case UERROR: + fprintf(stderr, "ERROR %s: ", tag); + break; + case UFATAL: + fprintf(stderr, "FATAL %s: ", tag); + vfprintf(stderr, format, args); + exit(EXIT_FAILURE); + // NEVER GETS HERE!!! + break; + default: + fprintf(stderr, "%d %s: ", level, tag); + break; } - vfprintf(stderr, format, args); + vfprintf(stderr, format, args); va_end(args); return 1; -} \ No newline at end of file +} diff --git a/src/uglylogging.h b/src/uglylogging.h index fa34d460c..5122820b9 100644 --- a/src/uglylogging.h +++ b/src/uglylogging.h @@ -1,4 +1,4 @@ -/* +/* * Ugly, low performance, configurable level, logging "framework" */ @@ -8,7 +8,7 @@ #ifdef __cplusplus extern "C" { #endif - + #define UDEBUG 90 #define UINFO 50 #define UWARN 30 From ff957bd11b5193d71f54849e06fe6deb6b72d6eb Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 9 Jul 2014 22:52:07 -0700 Subject: [PATCH 0271/1435] Remove toremove/ This directory has been awaiting deletion for 3 years. It is time to go. --- toremove/stm32l/src/stlink-hw.h | 45 - toremove/stm32l_notes/USB_traces.ods | Bin 114358 -> 0 bytes toremove/stm32l_notes/break.csv | 162 - toremove/stm32l_notes/device_connection.csv | 64 - toremove/stm32l_notes/go.csv | 3076 ------------------- toremove/stm32l_notes/notes | 15 - toremove/stm32l_notes/read_memory.csv | 260 -- toremove/stm32l_notes/step_into.csv | 194 -- 8 files changed, 3816 deletions(-) delete mode 100644 toremove/stm32l/src/stlink-hw.h delete mode 100644 toremove/stm32l_notes/USB_traces.ods delete mode 100644 toremove/stm32l_notes/break.csv delete mode 100644 toremove/stm32l_notes/device_connection.csv delete mode 100644 toremove/stm32l_notes/go.csv delete mode 100644 toremove/stm32l_notes/notes delete mode 100644 toremove/stm32l_notes/read_memory.csv delete mode 100644 toremove/stm32l_notes/step_into.csv diff --git a/toremove/stm32l/src/stlink-hw.h b/toremove/stm32l/src/stlink-hw.h deleted file mode 100644 index ca558cb6d..000000000 --- a/toremove/stm32l/src/stlink-hw.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef STLINK_HW_H_INCLUDED -# define STLINK_HW_H_INCLUDED - -// STLINK_DEBUG_RESETSYS, etc: -#define STLINK_OK 0x80 -#define STLINK_FALSE 0x81 -#define STLINK_CORE_RUNNING 0x80 -#define STLINK_CORE_HALTED 0x81 -#define STLINK_CORE_STAT_UNKNOWN -1 - -#define STLINK_GET_VERSION 0xf1 -#define STLINK_GET_CURRENT_MODE 0xf5 - -#define STLINK_DEBUG_COMMAND 0xF2 -#define STLINK_DFU_COMMAND 0xF3 -#define STLINK_DFU_EXIT 0x07 - -// STLINK_GET_CURRENT_MODE -#define STLINK_DEV_DFU_MODE 0x00 -#define STLINK_DEV_MASS_MODE 0x01 -#define STLINK_DEV_DEBUG_MODE 0x02 -#define STLINK_DEV_UNKNOWN_MODE -1 - -// jtag mode cmds -#define STLINK_DEBUG_ENTER 0x20 -#define STLINK_DEBUG_EXIT 0x21 -#define STLINK_DEBUG_READCOREID 0x22 -#define STLINK_DEBUG_GETSTATUS 0x01 -#define STLINK_DEBUG_FORCEDEBUG 0x02 -#define STLINK_DEBUG_RESETSYS 0x03 -#define STLINK_DEBUG_READALLREGS 0x04 -#define STLINK_DEBUG_READREG 0x05 -#define STLINK_DEBUG_WRITEREG 0x06 -#define STLINK_DEBUG_READMEM_32BIT 0x07 -#define STLINK_DEBUG_WRITEMEM_32BIT 0x08 -#define STLINK_DEBUG_RUNCORE 0x09 -#define STLINK_DEBUG_STEPCORE 0x0a -#define STLINK_DEBUG_SETFP 0x0b -#define STLINK_DEBUG_WRITEMEM_8BIT 0x0d -#define STLINK_DEBUG_CLEARFP 0x0e -#define STLINK_DEBUG_WRITEDEBUGREG 0x0f -#define STLINK_DEBUG_ENTER_SWD 0xa3 -#define STLINK_DEBUG_ENTER_JTAG 0x00 - -#endif /* STLINK_HW_H_INCLUDED */ diff --git a/toremove/stm32l_notes/USB_traces.ods b/toremove/stm32l_notes/USB_traces.ods deleted file mode 100644 index 607c5f955a97ff29db036938954ba112dc9aeb08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114358 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

H6V5&jC}YwvKblydQBuSf#H5_Ax2t+ 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 h?~ADx@!#X`E>9N^y$@X$bc9S{Z({tvzflt%yn diff --git a/toremove/stm32l_notes/break.csv b/toremove/stm32l_notes/break.csv deleted file mode 100644 index ac1fadf0a..000000000 --- a/toremove/stm32l_notes/break.csv +++ /dev/null @@ -1,162 +0,0 @@ -USBlyzer Report - -Capture List - -Type,Seq,Time,Elapsed,Duration,Request,Request Details,Raw Data,I/O,C:I:E,Device Object,Device Name,Driver Name,IRP,Status -START,0001,17:45:39.429,,,,,,,,,,,, -URB,0002,17:45:39.503,73.849 ms,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0003-0002,17:45:39.505,75.843 ms,1.995 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0004,17:45:39.505,75.897 ms,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0005-0004,17:45:39.507,77.812 ms,1.916 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0006,17:45:39.707,277.851 ms,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0007-0006,17:45:39.709,279.821 ms,1.969 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0008,17:45:39.709,279.860 ms,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0009-0008,17:45:39.711,281.806 ms,1.946 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0010,17:45:39.911,481.876 ms,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0011-0010,17:45:39.913,483.827 ms,1.952 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0012,17:45:39.913,483.872 ms,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0013-0012,17:45:39.915,485.806 ms,1.934 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0014,17:45:40.115,685.865 ms,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0015-0014,17:45:40.116,687.797 ms,1.932 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0016,17:45:40.117,687.841 ms,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0017-0016,17:45:40.118,689.796 ms,1.955 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0018,17:45:40.319,889.869 ms,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0019-0018,17:45:40.320,891.792 ms,1.922 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0020,17:45:40.321,891.830 ms,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0021-0020,17:45:40.321,892.814 ms,984 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0022,17:45:40.522,1.092884 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0023-0022,17:45:40.523,1.094793 s,1.909 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0024,17:45:40.524,1.094839 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0025-0024,17:45:40.525,1.096788 s,1.949 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0026,17:45:40.725,1.295894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0027-0026,17:45:40.726,1.297784 s,1.891 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0028,17:45:40.726,1.297822 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0029-0028,17:45:40.728,1.299784 s,1.962 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0030,17:45:40.928,1.498899 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0031-0030,17:45:40.929,1.500780 s,1.881 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0032,17:45:40.929,1.500814 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0033-0032,17:45:40.931,1.502781 s,1.967 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0034,17:45:41.131,1.701903 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0035-0034,17:45:41.132,1.703782 s,1.879 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0036,17:45:41.132,1.703816 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0037-0036,17:45:41.134,1.705777 s,1.961 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0038,17:45:41.334,1.904910 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0039-0038,17:45:41.335,1.906771 s,1.862 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0040,17:45:41.335,1.906805 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0041-0040,17:45:41.337,1.908771 s,1.966 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0042,17:45:41.537,2.107928 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0043-0042,17:45:41.538,2.109777 s,1.849 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0044,17:45:41.538,2.109811 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0045-0044,17:45:41.540,2.111768 s,1.958 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0046,17:45:41.540,2.111800 s,,Bulk or Interrupt Transfer,16 bytes data,F2 35 F0 ED 00 E0 03 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 35 F0 ED 00 E0 03 00 5F A0 00 00 00 00 00 00 -URB,0047-0046,17:45:41.541,2.112767 s,967 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0048,17:45:41.541,2.112791 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0049-0048,17:45:41.543,2.114766 s,1.975 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0050,17:45:41.543,2.114793 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0051-0050,17:45:41.544,2.115767 s,974 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0052,17:45:41.544,2.115790 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0053-0052,17:45:41.546,2.117768 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 03 00 03 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 03 00 03 01 -URB,0054,17:45:41.546,2.117799 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0055-0054,17:45:41.547,2.118768 s,968 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0056,17:45:41.547,2.118793 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0057-0056,17:45:41.549,2.120767 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 03 00 03 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 03 00 03 00 -URB,0058,17:45:41.549,2.120798 s,,Bulk or Interrupt Transfer,16 bytes data,F2 41 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0059-0058,17:45:41.550,2.121767 s,969 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0060,17:45:41.550,2.121792 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0061-0060,17:45:41.552,2.123768 s,1.976 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0062,17:45:41.552,2.123798 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 FC ED 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 07 FC ED 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0063-0062,17:45:41.553,2.124767 s,969 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0064,17:45:41.553,2.124791 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0065-0064,17:45:41.555,2.126767 s,1.977 ms,Bulk or Interrupt Transfer,4 bytes data,00 00 00 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),00 00 00 01 -URB,0066,17:45:41.555,2.126794 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0067-0066,17:45:41.556,2.127767 s,973 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0068,17:45:41.556,2.127791 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0069-0068,17:45:41.558,2.129767 s,1.976 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0070,17:45:41.558,2.129794 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 FC ED 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 08 FC ED 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0071-0070,17:45:41.559,2.130767 s,972 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0072,17:45:41.559,2.130791 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 01,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,00 00 00 01 -URB,0073-0072,17:45:41.561,2.132768 s,1.977 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0074,17:45:41.561,2.132793 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0075-0074,17:45:41.563,2.134767 s,1.974 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0076,17:45:41.563,2.134790 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0077-0076,17:45:41.565,2.136767 s,1.977 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0078,17:45:41.565,2.136798 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 28 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 08 28 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0079-0078,17:45:41.566,2.137767 s,969 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0080,17:45:41.566,2.137791 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,00 00 00 00 -URB,0081-0080,17:45:41.568,2.139766 s,1.975 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0082,17:45:41.568,2.139792 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0083-0082,17:45:41.570,2.141767 s,1.975 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0084,17:45:41.570,2.141792 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0085-0084,17:45:41.572,2.143769 s,1.977 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0086,17:45:41.572,2.143800 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 38 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 08 38 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0087-0086,17:45:41.573,2.144767 s,967 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0088,17:45:41.573,2.144791 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,00 00 00 00 -URB,0089-0088,17:45:41.575,2.146766 s,1.975 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0090,17:45:41.575,2.146791 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0091-0090,17:45:41.577,2.148766 s,1.975 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0092,17:45:41.577,2.148790 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0093-0092,17:45:41.579,2.150766 s,1.976 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0094,17:45:41.579,2.150793 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 48 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 08 48 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0095-0094,17:45:41.580,2.151767 s,974 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0096,17:45:41.580,2.151790 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,00 00 00 00 -URB,0097-0096,17:45:41.582,2.153766 s,1.975 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0098,17:45:41.582,2.153790 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0099-0098,17:45:41.584,2.155769 s,1.979 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0100,17:45:41.584,2.155793 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0101-0100,17:45:41.586,2.157767 s,1.974 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0102,17:45:41.586,2.157797 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 58 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 08 58 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0103-0102,17:45:41.587,2.158767 s,970 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0104,17:45:41.587,2.158791 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,00 00 00 00 -URB,0105-0104,17:45:41.589,2.160766 s,1.975 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0106,17:45:41.589,2.160792 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0107-0106,17:45:41.591,2.162766 s,1.974 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0108,17:45:41.591,2.162791 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0109-0108,17:45:41.593,2.164767 s,1.975 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0110,17:45:41.593,2.164801 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3A 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 3A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0111-0110,17:45:41.594,2.165766 s,965 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0112,17:45:41.594,2.165790 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0113-0112,17:45:41.599,2.170766 s,4.976 ms,Bulk or Interrupt Transfer,64 bytes data,80 00 00 01 04 00 00 00...,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 04 00 00 00 00 00 00 00 3F 00 00 00 06 00 00 00 C8 14 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 88 19 00 20 6B 01 00 20 -URB,0114,17:45:41.599,2.170777 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0115-0114,17:45:41.601,2.172761 s,1.984 ms,Bulk or Interrupt Transfer,24 bytes data,A8 0A 00 20 00 00 00 21...,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),A8 0A 00 20 00 00 00 21 88 19 00 20 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0116,17:45:41.601,2.172796 s,,Bulk or Interrupt Transfer,16 bytes data,F2 0C A8 0A 00 20 02 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 0C A8 0A 00 20 02 00 00 00 00 00 00 00 00 00 -URB,0117-0116,17:45:41.602,2.173763 s,968 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0118,17:45:41.602,2.173789 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0119-0118,17:45:41.604,2.175766 s,1.977 ms,Bulk or Interrupt Transfer,2 bytes data,01 D0,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),01 D0 -URB,0120,17:45:41.604,2.175792 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0121-0120,17:45:41.605,2.176766 s,974 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0122,17:45:41.605,2.176794 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0123-0122,17:45:41.607,2.178767 s,1.973 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0124,17:45:41.608,2.178876 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 04 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 07 04 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0125-0124,17:45:41.608,2.179765 s,889 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0126,17:45:41.608,2.179791 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0127-0126,17:45:41.610,2.181767 s,1.975 ms,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),00 00 00 00 -URB,0128,17:45:41.610,2.181793 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0129-0128,17:45:41.611,2.182766 s,973 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,0130,17:45:41.611,2.182789 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0131-0130,17:45:41.613,2.184766 s,1.977 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0132,17:45:41.614,2.185390 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 94 19 00 20 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 07 94 19 00 20 04 00 00 00 00 00 00 00 00 00 -URB,0133-0132,17:45:41.614,2.185766 s,376 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,0134,17:45:41.614,2.185793 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0135-0134,17:45:41.616,2.187766 s,1.972 ms,Bulk or Interrupt Transfer,4 bytes data,1D 0E 00 20,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),1D 0E 00 20 -URB,0136,17:45:41.616,2.187794 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0137-0136,17:45:41.617,2.188767 s,973 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,0138,17:45:41.617,2.188791 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0139-0138,17:45:41.619,2.190766 s,1.975 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0140,17:45:41.620,2.191087 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 9C 19 00 20 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 07 9C 19 00 20 04 00 00 00 00 00 00 00 00 00 -URB,0141-0140,17:45:41.620,2.191766 s,679 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,0142,17:45:41.620,2.191790 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0143-0142,17:45:41.622,2.193765 s,1.975 ms,Bulk or Interrupt Transfer,4 bytes data,83 0F 00 20,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),83 0F 00 20 -URB,0144,17:45:41.622,2.193791 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0145-0144,17:45:41.623,2.194768 s,977 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,0146,17:45:41.623,2.194792 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0147-0146,17:45:41.625,2.196767 s,1.975 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0148,17:45:41.626,2.197059 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 E4 19 00 20 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 07 E4 19 00 20 04 00 00 00 00 00 00 00 00 00 -URB,0149-0148,17:45:41.626,2.197765 s,706 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,0150,17:45:41.626,2.197789 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0151-0150,17:45:41.628,2.199766 s,1.977 ms,Bulk or Interrupt Transfer,4 bytes data,67 14 00 20,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),67 14 00 20 -URB,0152,17:45:41.628,2.199792 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0153-0152,17:45:41.629,2.200766 s,974 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,0154,17:45:41.629,2.200790 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0155-0154,17:45:41.631,2.202765 s,1.976 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 - -This report was generated by USBlyzer http://www.usblyzer.com/ diff --git a/toremove/stm32l_notes/device_connection.csv b/toremove/stm32l_notes/device_connection.csv deleted file mode 100644 index e2de02dd8..000000000 --- a/toremove/stm32l_notes/device_connection.csv +++ /dev/null @@ -1,64 +0,0 @@ -USBlyzer Report - -Capture List - -Type,Seq,Time,Elapsed,Duration,Request,Request Details,Raw Data,I/O,C:I:E,Device Object,Device Name,Driver Name,IRP,Status -START,0001,16:01:27.054,,,,,,,,,,,, -Create,0002,16:05:07.963,220.908617 s,,Create,ST-LinkUpgrade.exe,,,,FFFFFA800373FB40h,,WinUsb,FFFFFA8002864690h, -Create,0003-0002,16:05:07.963,220.908641 s,24 us,Create,ST-LinkUpgrade.exe,,,,FFFFFA800373FB40h,,WinUsb,FFFFFA8002864690h,Success -URB,0004,16:05:07.963,220.908764 s,,Bulk or Interrupt Transfer,16 bytes data,F1 80 00 00 00 00 00 00...,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA8002864690h,,F1 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0005-0004,16:05:07.965,220.910795 s,2.032 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA8002864690h,Success (Success) -URB,0006,16:05:07.965,220.910876 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80027BBA50h, -URB,0007-0006,16:05:07.968,220.912779 s,1.903 ms,Bulk or Interrupt Transfer,6 bytes data,23 80 83 04 48 37,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80027BBA50h,Success (Success),23 80 83 04 48 37 -URB,0008,16:05:07.968,220.912813 s,,Bulk or Interrupt Transfer,16 bytes data,F5 00 00 00 00 00 00 00...,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA8002864690h,,F5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0009-0008,16:05:07.968,220.913777 s,965 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA8002864690h,Success (Success) -URB,0010,16:05:07.968,220.913800 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80027BBA50h, -URB,0011-0010,16:05:07.970,220.914777 s,978 us,Bulk or Interrupt Transfer,2 bytes data,00 01,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80027BBA50h,Success (Success),00 01 -URB,0012,16:05:07.970,220.914803 s,,Bulk or Interrupt Transfer,16 bytes data,F3 08 00 00 00 00 00 00...,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA8002864690h,,F3 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0013-0012,16:05:07.970,220.915778 s,975 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA8002864690h,Success (Success) -URB,0014,16:05:07.970,220.915799 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80027BBA50h, -URB,0015-0014,16:05:07.973,220.917778 s,1.979 ms,Bulk or Interrupt Transfer,20 bytes data,40 00 FF FF 4A 82 34 06...,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80027BBA50h,Success (Success),40 00 FF FF 4A 82 34 06 53 FF 68 06 48 82 57 51 07 38 12 87 -URB,0016,16:05:07.973,220.917815 s,,Bulk or Interrupt Transfer,16 bytes data,F1 80 00 00 00 00 00 00...,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA8002864690h,,F1 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0017-0016,16:05:07.973,220.918777 s,963 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA8002864690h,Success (Success) -URB,0018,16:05:07.973,220.918799 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80027BBA50h, -URB,0019-0018,16:05:07.975,220.920778 s,1.978 ms,Bulk or Interrupt Transfer,6 bytes data,23 80 83 04 48 37,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80027BBA50h,Success (Success),23 80 83 04 48 37 -Cleanup,0020,16:07:29.920,362.863914 s,,Cleanup,ST-LinkUpgrade.exe,,,,FFFFFA800373FB40h,,WinUsb,FFFFFA80038D78F0h, -Cleanup,0021-0020,16:07:29.920,362.863990 s,76 us,Cleanup,ST-LinkUpgrade.exe,,,,FFFFFA800373FB40h,,WinUsb,FFFFFA80038D78F0h,Success -Close,0022,16:07:29.920,362.863994 s,,Close,,,,,FFFFFA800373FB40h,,WinUsb,FFFFFA80038D78F0h, -Close,0023-0022,16:07:29.920,362.863998 s,4 us,Close,,,,,FFFFFA800373FB40h,,WinUsb,FFFFFA80038D78F0h,Success -Create,0024,16:07:43.292,376.235500 s,,Create,ST-LINK_gdbserver.exe,,,,FFFFFA800373FB40h,,WinUsb,FFFFFA80067CE0D0h, -Create,0025-0024,16:07:43.292,376.235525 s,24 us,Create,ST-LINK_gdbserver.exe,,,,FFFFFA800373FB40h,,WinUsb,FFFFFA80067CE0D0h,Success -URB,0026,16:07:43.292,376.235653 s,,Bulk or Interrupt Transfer,16 bytes data,F1 80 00 00 00 00 00 00...,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80067CE0D0h,,F1 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0027-0026,16:07:43.294,376.237673 s,2.020 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80067CE0D0h,Success (Success) -URB,0028,16:07:43.294,376.237720 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80070C7170h, -URB,0029-0028,16:07:43.296,376.239653 s,1.933 ms,Bulk or Interrupt Transfer,6 bytes data,23 80 83 04 48 37,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80070C7170h,Success (Success),23 80 83 04 48 37 -URB,0030,16:07:43.296,376.239690 s,,Bulk or Interrupt Transfer,16 bytes data,F5 00 00 00 00 00 00 00...,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80067CE0D0h,,F5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0031-0030,16:07:43.297,376.240648 s,959 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80067CE0D0h,Success (Success) -URB,0032,16:07:43.297,376.240676 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80070C7170h, -URB,0033-0032,16:07:43.299,376.242648 s,1.972 ms,Bulk or Interrupt Transfer,2 bytes data,00 01,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80070C7170h,Success (Success),00 01 -URB,0034,16:07:43.299,376.242680 s,,Bulk or Interrupt Transfer,16 bytes data,F3 07 00 00 00 00 00 00...,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80067CE0D0h,,F3 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0035-0034,16:07:43.300,376.243647 s,967 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80067CE0D0h,Success (Success) -URB,0036,16:07:43.301,376.244139 s,,Bulk or Interrupt Transfer,16 bytes data,F2 30 00 00 00 00 00 00...,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80047EC010h,,F2 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0037-0036,16:07:43.302,376.245654 s,1.515 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80047EC010h,Success (Success) -URB,0038,16:07:43.302,376.245686 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80070C7170h, -URB,0039-0038,16:07:43.304,376.247651 s,1.965 ms,Bulk or Interrupt Transfer,2 bytes data,04 00,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80070C7170h,Success (Success),04 00 -URB,0040,16:07:43.305,376.247993 s,,Bulk or Interrupt Transfer,16 bytes data,F2 32 00 00 00 00 00 00...,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80047EC010h,,F2 32 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0041-0040,16:07:43.305,376.248654 s,661 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80047EC010h,Success (Success) -URB,0042,16:07:43.305,376.248685 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80070C7170h, -URB,0043-0042,16:07:43.307,376.250665 s,1.979 ms,Bulk or Interrupt Transfer,2 bytes data,04 00,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80070C7170h,Success (Success),04 00 -URB,0044,16:07:43.307,376.250708 s,,Bulk or Interrupt Transfer,16 bytes data,F5 00 00 00 00 00 00 00...,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80047EC010h,,F5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0045-0044,16:07:43.309,376.251656 s,948 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80047EC010h,Success (Success) -URB,0046,16:07:43.309,376.251689 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80070C7170h, -URB,0047-0046,16:07:43.310,376.253650 s,1.961 ms,Bulk or Interrupt Transfer,2 bytes data,02 00,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80070C7170h,Success (Success),02 00 -URB,0048,16:07:43.310,376.253680 s,,Bulk or Interrupt Transfer,16 bytes data,F2 35 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80047EC010h,,F2 35 F0 ED 00 E0 00 00 5F A0 00 00 00 00 00 00 -URB,0049-0048,16:07:43.311,376.254647 s,967 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80047EC010h,Success (Success) -URB,0050,16:07:43.311,376.254672 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80070C7170h, -URB,0051-0050,16:07:43.314,376.256648 s,1.976 ms,Bulk or Interrupt Transfer,2 bytes data,08 00,in,01:00:81,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80070C7170h,Success (Success),08 00 -URB,0052,16:07:43.314,376.256675 s,,Bulk or Interrupt Transfer,16 bytes data,F2 21 00 00 00 00 00 00...,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80047EC010h,,F2 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0053-0052,16:07:43.314,376.257649 s,974 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800393B2F0h,USBPDO-7,usbhub,FFFFFA80047EC010h,Success (Success) -Cleanup,0054,16:07:43.314,376.257674 s,,Cleanup,ST-LINK_gdbserver.exe,,,,FFFFFA800373FB40h,,WinUsb,FFFFFA80047EC010h, -Cleanup,0055-0054,16:07:43.314,376.257719 s,45 us,Cleanup,ST-LINK_gdbserver.exe,,,,FFFFFA800373FB40h,,WinUsb,FFFFFA80047EC010h,Success -Close,0056,16:07:43.314,376.257722 s,,Close,,,,,FFFFFA800373FB40h,,WinUsb,FFFFFA80047EC010h, -Close,0057-0056,16:07:43.314,376.257726 s,3 us,Close,,,,,FFFFFA800373FB40h,,WinUsb,FFFFFA80047EC010h,Success - -This report was generated by USBlyzer http://www.usblyzer.com/ diff --git a/toremove/stm32l_notes/go.csv b/toremove/stm32l_notes/go.csv deleted file mode 100644 index 1ca10439d..000000000 --- a/toremove/stm32l_notes/go.csv +++ /dev/null @@ -1,3076 +0,0 @@ -USBlyzer Report - -Capture List - -Type,Seq,Time,Elapsed,Duration,Request,Request Details,Raw Data,I/O,C:I:E,Device Object,Device Name,Driver Name,IRP,Status -START,0001,17:43:38.035,,,,,,,,,,,, -URB,0002,17:44:01.236,23.201589 s,,Bulk or Interrupt Transfer,16 bytes data,F2 0C 40 11 00 20 02 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 0C 40 11 00 20 02 00 00 00 00 00 00 00 00 00 -URB,0003-0002,17:44:01.238,23.203514 s,1.924 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,0004,17:44:01.238,23.203558 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0005-0004,17:44:01.240,23.205498 s,1.940 ms,Bulk or Interrupt Transfer,2 bytes data,70 47,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),70 47 -URB,0006,17:44:01.240,23.205532 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0007-0006,17:44:01.241,23.206491 s,960 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0008,17:44:01.241,23.206517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0009-0008,17:44:01.243,23.208494 s,1.976 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0010,17:44:01.243,23.208535 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 FC ED 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 07 FC ED 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0011-0010,17:44:01.244,23.209491 s,956 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0012,17:44:01.244,23.209515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0013-0012,17:44:01.246,23.211490 s,1.975 ms,Bulk or Interrupt Transfer,4 bytes data,00 00 00 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),00 00 00 01 -URB,0014,17:44:01.246,23.211517 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0015-0014,17:44:01.247,23.212490 s,973 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0016,17:44:01.247,23.212515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0017-0016,17:44:01.249,23.214501 s,1.986 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0018,17:44:01.249,23.214544 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 FC ED 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 08 FC ED 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0019-0018,17:44:01.250,23.215493 s,949 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0020,17:44:01.250,23.215522 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 01,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,00 00 00 01 -URB,0021-0020,17:44:01.252,23.217580 s,2.058 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0022,17:44:01.252,23.217648 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0023-0022,17:44:01.254,23.219490 s,1.843 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0024,17:44:01.254,23.219518 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0025-0024,17:44:01.256,23.221489 s,1.971 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0026,17:44:01.256,23.221519 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 28 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 08 28 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0027-0026,17:44:01.257,23.222489 s,969 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0028,17:44:01.257,23.222512 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,00 00 00 00 -URB,0029-0028,17:44:01.259,23.224489 s,1.976 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0030,17:44:01.259,23.224513 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0031-0030,17:44:01.261,23.226489 s,1.975 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0032,17:44:01.261,23.226512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0033-0032,17:44:01.263,23.228488 s,1.976 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0034,17:44:01.263,23.228515 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 38 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 08 38 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0035-0034,17:44:01.264,23.229489 s,974 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0036,17:44:01.264,23.229513 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,00 00 00 00 -URB,0037-0036,17:44:01.266,23.231489 s,1.976 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0038,17:44:01.266,23.231523 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0039-0038,17:44:01.268,23.233488 s,1.965 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0040,17:44:01.268,23.233512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0041-0040,17:44:01.270,23.235488 s,1.976 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0042,17:44:01.270,23.235514 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 48 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 08 48 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0043-0042,17:44:01.271,23.236487 s,973 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0044,17:44:01.271,23.236510 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,00 00 00 00 -URB,0045-0044,17:44:01.272,23.237487 s,977 us,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0046,17:44:01.272,23.237512 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0047-0046,17:44:01.273,23.238488 s,976 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0048,17:44:01.273,23.238512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0049-0048,17:44:01.275,23.240489 s,1.977 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0050,17:44:01.275,23.240516 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 58 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 08 58 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0051-0050,17:44:01.276,23.241489 s,973 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0052,17:44:01.276,23.241511 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,00 00 00 00 -URB,0053-0052,17:44:01.278,23.243487 s,1.976 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0054,17:44:01.278,23.243511 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0055-0054,17:44:01.279,23.244488 s,978 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0056,17:44:01.279,23.244513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0057-0056,17:44:01.281,23.246491 s,1.978 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0058,17:44:01.281,23.246535 s,,Bulk or Interrupt Transfer,16 bytes data,F2 35 F0 ED 00 E0 01 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 35 F0 ED 00 E0 01 00 5F A0 00 00 00 00 00 00 -URB,0059-0058,17:44:01.282,23.247488 s,953 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0060,17:44:01.282,23.247512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0061-0060,17:44:01.284,23.249527 s,2.015 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0062,17:44:01.285,23.249896 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0063-0062,17:44:01.285,23.250503 s,606 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0064,17:44:01.285,23.250533 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0065-0064,17:44:01.287,23.252495 s,1.962 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0066,17:44:01.288,23.252884 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0067-0066,17:44:01.288,23.253503 s,619 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0068,17:44:01.288,23.253528 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0069-0068,17:44:01.290,23.255495 s,1.967 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0070,17:44:01.291,23.255892 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0071-0070,17:44:01.291,23.256498 s,605 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0072,17:44:01.291,23.256526 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0073-0072,17:44:01.293,23.258496 s,1.969 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0074,17:44:01.294,23.258894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0075-0074,17:44:01.294,23.259494 s,600 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0076,17:44:01.294,23.259523 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0077-0076,17:44:01.296,23.261494 s,1.971 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0078,17:44:01.297,23.261891 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0079-0078,17:44:01.297,23.262495 s,604 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0080,17:44:01.297,23.262521 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0081-0080,17:44:01.299,23.264495 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0082,17:44:01.300,23.264888 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0083-0082,17:44:01.300,23.265494 s,607 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0084,17:44:01.300,23.265520 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0085-0084,17:44:01.302,23.267581 s,2.061 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0086,17:44:01.303,23.267906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0087-0086,17:44:01.303,23.268497 s,591 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0088,17:44:01.303,23.268527 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0089-0088,17:44:01.305,23.270494 s,1.967 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0090,17:44:01.306,23.270899 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0091-0090,17:44:01.306,23.271494 s,595 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0092,17:44:01.306,23.271522 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0093-0092,17:44:01.308,23.273498 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0094,17:44:01.309,23.273886 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0095-0094,17:44:01.309,23.274495 s,609 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0096,17:44:01.309,23.274520 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0097-0096,17:44:01.311,23.276494 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0098,17:44:01.312,23.276884 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0099-0098,17:44:01.312,23.277494 s,610 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0100,17:44:01.312,23.277518 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0101-0100,17:44:01.314,23.279495 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0102,17:44:01.315,23.279888 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0103-0102,17:44:01.315,23.280494 s,607 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0104,17:44:01.315,23.280517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0105-0104,17:44:01.317,23.282495 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0106,17:44:01.318,23.282883 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0107-0106,17:44:01.318,23.283494 s,611 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0108,17:44:01.318,23.283517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0109-0108,17:44:01.320,23.285493 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0110,17:44:01.321,23.285893 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0111-0110,17:44:01.321,23.286494 s,601 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0112,17:44:01.321,23.286520 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0113-0112,17:44:01.323,23.288494 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0114,17:44:01.324,23.288887 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0115-0114,17:44:01.324,23.289495 s,608 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0116,17:44:01.324,23.289519 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0117-0116,17:44:01.326,23.291494 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0118,17:44:01.327,23.291891 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0119-0118,17:44:01.327,23.292493 s,602 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0120,17:44:01.327,23.292517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0121-0120,17:44:01.329,23.294494 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0122,17:44:01.330,23.294883 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0123-0122,17:44:01.330,23.295494 s,611 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0124,17:44:01.330,23.295517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0125-0124,17:44:01.332,23.297495 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0126,17:44:01.333,23.297883 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0127-0126,17:44:01.333,23.298494 s,610 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0128,17:44:01.333,23.298517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0129-0128,17:44:01.335,23.300494 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0130,17:44:01.336,23.300889 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0131-0130,17:44:01.336,23.301494 s,606 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0132,17:44:01.336,23.301518 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0133-0132,17:44:01.338,23.303494 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0134,17:44:01.339,23.303884 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0135-0134,17:44:01.339,23.304494 s,610 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0136,17:44:01.339,23.304517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0137-0136,17:44:01.341,23.306493 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0138,17:44:01.342,23.306884 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0139-0138,17:44:01.342,23.307496 s,612 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0140,17:44:01.342,23.307520 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0141-0140,17:44:01.344,23.309501 s,1.981 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0142,17:44:01.345,23.309893 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0143-0142,17:44:01.345,23.310495 s,602 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0144,17:44:01.345,23.310521 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0145-0144,17:44:01.347,23.312495 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0146,17:44:01.348,23.312884 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0147-0146,17:44:01.348,23.313493 s,609 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0148,17:44:01.348,23.313517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0149-0148,17:44:01.350,23.315494 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0150,17:44:01.351,23.315884 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0151-0150,17:44:01.351,23.316494 s,610 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0152,17:44:01.351,23.316517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0153-0152,17:44:01.353,23.318494 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0154,17:44:01.354,23.318886 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0155-0154,17:44:01.354,23.319494 s,608 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0156,17:44:01.354,23.319518 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0157-0156,17:44:01.356,23.321494 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0158,17:44:01.357,23.321890 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0159-0158,17:44:01.357,23.322494 s,604 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0160,17:44:01.357,23.322517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0161-0160,17:44:01.359,23.324493 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0162,17:44:01.360,23.324886 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0163-0162,17:44:01.360,23.325493 s,607 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0164,17:44:01.360,23.325517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0165-0164,17:44:01.362,23.327495 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0166,17:44:01.363,23.327887 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0167-0166,17:44:01.363,23.328494 s,607 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0168,17:44:01.363,23.328517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0169-0168,17:44:01.365,23.330494 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0170,17:44:01.366,23.330888 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0171-0170,17:44:01.366,23.331493 s,605 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0172,17:44:01.366,23.331518 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0173-0172,17:44:01.368,23.333493 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0174,17:44:01.369,23.333885 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0175-0174,17:44:01.369,23.334497 s,612 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0176,17:44:01.369,23.334520 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0177-0176,17:44:01.371,23.336494 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0178,17:44:01.372,23.336887 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0179-0178,17:44:01.372,23.337493 s,606 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0180,17:44:01.372,23.337516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0181-0180,17:44:01.374,23.339494 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0182,17:44:01.375,23.339889 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0183-0182,17:44:01.375,23.340492 s,603 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0184,17:44:01.375,23.340517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0185-0184,17:44:01.377,23.342494 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0186,17:44:01.378,23.342886 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0187-0186,17:44:01.378,23.343493 s,607 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0188,17:44:01.378,23.343516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0189-0188,17:44:01.380,23.345494 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0190,17:44:01.381,23.345888 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0191-0190,17:44:01.381,23.346493 s,605 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0192,17:44:01.381,23.346516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0193-0192,17:44:01.383,23.348495 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0194,17:44:01.384,23.348887 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0195-0194,17:44:01.384,23.349493 s,605 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0196,17:44:01.384,23.349516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0197-0196,17:44:01.386,23.351494 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0198,17:44:01.387,23.351891 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0199-0198,17:44:01.387,23.352493 s,602 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0200,17:44:01.387,23.352516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0201-0200,17:44:01.389,23.354493 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0202,17:44:01.390,23.354887 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0203-0202,17:44:01.390,23.355492 s,605 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0204,17:44:01.390,23.355516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0205-0204,17:44:01.392,23.357492 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0206,17:44:01.393,23.357886 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0207-0206,17:44:01.393,23.358493 s,607 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0208,17:44:01.393,23.358516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0209-0208,17:44:01.395,23.360494 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0210,17:44:01.396,23.360885 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0211-0210,17:44:01.396,23.361493 s,607 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0212,17:44:01.396,23.361516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0213-0212,17:44:01.398,23.363492 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0214,17:44:01.399,23.363886 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0215-0214,17:44:01.399,23.364493 s,607 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0216,17:44:01.399,23.364516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0217-0216,17:44:01.401,23.366493 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0218,17:44:01.402,23.366886 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0219-0218,17:44:01.402,23.367492 s,607 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0220,17:44:01.402,23.367516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0221-0220,17:44:01.404,23.369494 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0222,17:44:01.405,23.369888 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0223-0222,17:44:01.405,23.370492 s,604 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0224,17:44:01.405,23.370516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0225-0224,17:44:01.407,23.372492 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0226,17:44:01.408,23.372890 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0227-0226,17:44:01.408,23.373492 s,602 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0228,17:44:01.408,23.373515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0229-0228,17:44:01.410,23.375494 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0230,17:44:01.411,23.375887 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0231-0230,17:44:01.411,23.376492 s,606 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0232,17:44:01.411,23.376516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0233-0232,17:44:01.413,23.378492 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0234,17:44:01.414,23.378886 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0235-0234,17:44:01.414,23.379492 s,606 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0236,17:44:01.414,23.379515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0237-0236,17:44:01.416,23.381492 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0238,17:44:01.417,23.381895 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0239-0238,17:44:01.417,23.382503 s,607 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0240,17:44:01.417,23.382534 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0241-0240,17:44:01.419,23.384495 s,1.961 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0242,17:44:01.420,23.384887 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0243-0242,17:44:01.420,23.385492 s,605 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0244,17:44:01.420,23.385516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0245-0244,17:44:01.422,23.387493 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0246,17:44:01.423,23.387888 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0247-0246,17:44:01.423,23.388492 s,604 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0248,17:44:01.423,23.388516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0249-0248,17:44:01.425,23.390493 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0250,17:44:01.426,23.390889 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0251-0250,17:44:01.426,23.391492 s,603 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0252,17:44:01.426,23.391516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0253-0252,17:44:01.428,23.393492 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0254,17:44:01.429,23.393887 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0255-0254,17:44:01.429,23.394492 s,606 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0256,17:44:01.429,23.394516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0257-0256,17:44:01.431,23.396491 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0258,17:44:01.432,23.396887 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0259-0258,17:44:01.432,23.397492 s,605 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0260,17:44:01.432,23.397515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0261-0260,17:44:01.434,23.399492 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0262,17:44:01.435,23.399888 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0263-0262,17:44:01.435,23.400492 s,604 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0264,17:44:01.435,23.400515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0265-0264,17:44:01.437,23.402492 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0266,17:44:01.438,23.402893 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0267-0266,17:44:01.438,23.403492 s,600 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0268,17:44:01.438,23.403517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0269-0268,17:44:01.440,23.405492 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0270,17:44:01.441,23.405888 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0271-0270,17:44:01.441,23.406492 s,604 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0272,17:44:01.441,23.406515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0273-0272,17:44:01.443,23.408491 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0274,17:44:01.444,23.408912 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0275-0274,17:44:01.444,23.409490 s,578 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0276,17:44:01.444,23.409520 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0277-0276,17:44:01.446,23.411489 s,1.969 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0278,17:44:01.447,23.411894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0279-0278,17:44:01.447,23.412492 s,598 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0280,17:44:01.447,23.412516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0281-0280,17:44:01.449,23.414492 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0282,17:44:01.450,23.414888 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0283-0282,17:44:01.450,23.415491 s,603 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0284,17:44:01.450,23.415515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0285-0284,17:44:01.452,23.417492 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0286,17:44:01.453,23.417888 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0287-0286,17:44:01.453,23.418491 s,603 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0288,17:44:01.453,23.418514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0289-0288,17:44:01.455,23.420492 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0290,17:44:01.456,23.420890 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0291-0290,17:44:01.456,23.421491 s,601 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0292,17:44:01.456,23.421515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0293-0292,17:44:01.458,23.423496 s,1.981 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0294,17:44:01.459,23.423889 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0295-0294,17:44:01.459,23.424492 s,603 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0296,17:44:01.459,23.424515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0297-0296,17:44:01.461,23.426492 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0298,17:44:01.462,23.426888 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0299-0298,17:44:01.462,23.427491 s,603 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0300,17:44:01.462,23.427515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0301-0300,17:44:01.464,23.429492 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0302,17:44:01.465,23.429892 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0303-0302,17:44:01.465,23.430491 s,600 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0304,17:44:01.465,23.430516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0305-0304,17:44:01.467,23.432491 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0306,17:44:01.468,23.432889 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0307-0306,17:44:01.468,23.433491 s,602 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0308,17:44:01.468,23.433514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0309-0308,17:44:01.470,23.435492 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0310,17:44:01.471,23.435891 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0311-0310,17:44:01.471,23.436491 s,600 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0312,17:44:01.471,23.436516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0313-0312,17:44:01.473,23.438493 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0314,17:44:01.474,23.438890 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0315-0314,17:44:01.474,23.439491 s,601 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0316,17:44:01.474,23.439516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0317-0316,17:44:01.476,23.441492 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0318,17:44:01.477,23.441894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0319-0318,17:44:01.477,23.442492 s,598 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0320,17:44:01.477,23.442516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0321-0320,17:44:01.479,23.444490 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0322,17:44:01.480,23.444892 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0323-0322,17:44:01.480,23.445491 s,599 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0324,17:44:01.480,23.445514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0325-0324,17:44:01.482,23.447492 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0326,17:44:01.483,23.447889 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0327-0326,17:44:01.483,23.448490 s,601 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0328,17:44:01.483,23.448514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0329-0328,17:44:01.485,23.450491 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0330,17:44:01.486,23.450892 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0331-0330,17:44:01.486,23.451490 s,598 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0332,17:44:01.486,23.451514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0333-0332,17:44:01.488,23.453491 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0334,17:44:01.489,23.453892 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0335-0334,17:44:01.489,23.454492 s,600 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0336,17:44:01.489,23.454516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0337-0336,17:44:01.491,23.456490 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0338,17:44:01.492,23.456889 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0339-0338,17:44:01.492,23.457494 s,604 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0340,17:44:01.492,23.457517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0341-0340,17:44:01.494,23.459491 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0342,17:44:01.495,23.459889 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0343-0342,17:44:01.495,23.460490 s,601 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0344,17:44:01.495,23.460513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0345-0344,17:44:01.497,23.462490 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0346,17:44:01.498,23.462889 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0347-0346,17:44:01.498,23.463490 s,601 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0348,17:44:01.498,23.463514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0349-0348,17:44:01.500,23.465491 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0350,17:44:01.501,23.465890 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0351-0350,17:44:01.501,23.466491 s,601 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0352,17:44:01.501,23.466514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0353-0352,17:44:01.503,23.468491 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0354,17:44:01.504,23.468891 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0355-0354,17:44:01.504,23.469490 s,598 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0356,17:44:01.504,23.469513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0357-0356,17:44:01.506,23.471493 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0358,17:44:01.507,23.471897 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0359-0358,17:44:01.507,23.472491 s,594 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0360,17:44:01.507,23.472516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0361-0360,17:44:01.509,23.474490 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0362,17:44:01.510,23.474890 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0363-0362,17:44:01.510,23.475490 s,600 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0364,17:44:01.510,23.475514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0365-0364,17:44:01.512,23.477491 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0366,17:44:01.513,23.477891 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0367-0366,17:44:01.513,23.478490 s,599 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0368,17:44:01.513,23.478514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0369-0368,17:44:01.515,23.480491 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0370,17:44:01.516,23.480890 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0371-0370,17:44:01.516,23.481490 s,600 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0372,17:44:01.516,23.481514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0373-0372,17:44:01.518,23.483491 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0374,17:44:01.519,23.483891 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0375-0374,17:44:01.519,23.484490 s,599 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0376,17:44:01.519,23.484515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0377-0376,17:44:01.521,23.486490 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0378,17:44:01.522,23.486890 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0379-0378,17:44:01.522,23.487490 s,600 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0380,17:44:01.522,23.487514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0381-0380,17:44:01.524,23.489490 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0382,17:44:01.525,23.489894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0383-0382,17:44:01.525,23.490491 s,597 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0384,17:44:01.525,23.490515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0385-0384,17:44:01.527,23.492490 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0386,17:44:01.528,23.492891 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0387-0386,17:44:01.528,23.493489 s,598 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0388,17:44:01.528,23.493513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0389-0388,17:44:01.530,23.495490 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0390,17:44:01.531,23.495891 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0391-0390,17:44:01.531,23.496489 s,599 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0392,17:44:01.531,23.496513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0393-0392,17:44:01.533,23.498490 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0394,17:44:01.534,23.498891 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0395-0394,17:44:01.534,23.499489 s,598 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0396,17:44:01.534,23.499513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0397-0396,17:44:01.536,23.501506 s,1.992 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0398,17:44:01.537,23.501906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0399-0398,17:44:01.537,23.502503 s,597 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0400,17:44:01.537,23.502536 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0401-0400,17:44:01.539,23.504496 s,1.960 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0402,17:44:01.540,23.504897 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0403-0402,17:44:01.540,23.505490 s,592 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0404,17:44:01.540,23.505514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0405-0404,17:44:01.542,23.507490 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0406,17:44:01.543,23.507891 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0407-0406,17:44:01.543,23.508489 s,598 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0408,17:44:01.543,23.508513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0409-0408,17:44:01.545,23.510491 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0410,17:44:01.546,23.510917 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0411-0410,17:44:01.546,23.511487 s,569 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0412,17:44:01.546,23.511515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0413-0412,17:44:01.548,23.513484 s,1.969 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0414,17:44:01.549,23.513914 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0415-0414,17:44:01.549,23.514487 s,573 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0416,17:44:01.549,23.514515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0417-0416,17:44:01.551,23.516490 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0418,17:44:01.552,23.516893 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0419-0418,17:44:01.552,23.517489 s,596 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0420,17:44:01.552,23.517513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0421-0420,17:44:01.554,23.519493 s,1.981 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0422,17:44:01.555,23.519892 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0423-0422,17:44:01.555,23.520491 s,598 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0424,17:44:01.555,23.520514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0425-0424,17:44:01.557,23.522490 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0426,17:44:01.558,23.522894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0427-0426,17:44:01.558,23.523489 s,595 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0428,17:44:01.558,23.523513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0429-0428,17:44:01.560,23.525489 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0430,17:44:01.561,23.525892 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0431-0430,17:44:01.561,23.526489 s,597 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0432,17:44:01.561,23.526513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0433-0432,17:44:01.563,23.528490 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0434,17:44:01.564,23.528894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0435-0434,17:44:01.564,23.529489 s,595 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0436,17:44:01.564,23.529514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0437-0436,17:44:01.566,23.531489 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0438,17:44:01.567,23.531899 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0439-0438,17:44:01.567,23.532489 s,590 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0440,17:44:01.567,23.532514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0441-0440,17:44:01.569,23.534489 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0442,17:44:01.570,23.534893 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0443-0442,17:44:01.570,23.535490 s,597 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0444,17:44:01.570,23.535513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0445-0444,17:44:01.572,23.537489 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0446,17:44:01.573,23.537899 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0447-0446,17:44:01.573,23.538489 s,590 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0448,17:44:01.573,23.538513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0449-0448,17:44:01.575,23.540489 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0450,17:44:01.576,23.540893 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0451-0450,17:44:01.576,23.541488 s,595 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0452,17:44:01.576,23.541511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0453-0452,17:44:01.578,23.543489 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0454,17:44:01.579,23.543893 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0455-0454,17:44:01.579,23.544489 s,596 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0456,17:44:01.579,23.544513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0457-0456,17:44:01.581,23.546491 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0458,17:44:01.582,23.546895 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0459-0458,17:44:01.582,23.547488 s,593 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0460,17:44:01.582,23.547512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0461-0460,17:44:01.584,23.549489 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0462,17:44:01.585,23.549896 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0463-0462,17:44:01.585,23.550490 s,593 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0464,17:44:01.585,23.550514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0465-0464,17:44:01.587,23.552489 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0466,17:44:01.588,23.552894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0467-0466,17:44:01.588,23.553491 s,597 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0468,17:44:01.588,23.553515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0469-0468,17:44:01.590,23.555488 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0470,17:44:01.591,23.555918 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8007DE2010h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0471-0470,17:44:01.591,23.556484 s,566 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8007DE2010h,Success (Success) -URB,0472,17:44:01.591,23.556512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0473-0472,17:44:01.593,23.558529 s,2.017 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0474,17:44:01.594,23.558897 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0475-0474,17:44:01.594,23.559500 s,603 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0476,17:44:01.594,23.559530 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0477-0476,17:44:01.596,23.561491 s,1.961 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0478,17:44:01.597,23.561907 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0479-0478,17:44:01.597,23.562488 s,582 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0480,17:44:01.597,23.562513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0481-0480,17:44:01.599,23.564489 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0482,17:44:01.600,23.564895 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0483-0482,17:44:01.600,23.565492 s,597 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0484,17:44:01.600,23.565517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0485-0484,17:44:01.602,23.567488 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0486,17:44:01.603,23.567894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0487-0486,17:44:01.603,23.568488 s,594 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0488,17:44:01.603,23.568512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0489-0488,17:44:01.605,23.570493 s,1.981 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0490,17:44:01.606,23.570895 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0491-0490,17:44:01.606,23.571489 s,594 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0492,17:44:01.606,23.571514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0493-0492,17:44:01.608,23.573489 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0494,17:44:01.609,23.573900 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0495-0494,17:44:01.609,23.574489 s,588 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0496,17:44:01.609,23.574513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0497-0496,17:44:01.611,23.576489 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0498,17:44:01.612,23.576894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0499-0498,17:44:01.612,23.577488 s,594 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0500,17:44:01.612,23.577511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0501-0500,17:44:01.614,23.579490 s,1.979 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0502,17:44:01.615,23.579894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0503-0502,17:44:01.615,23.580489 s,595 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0504,17:44:01.615,23.580512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0505-0504,17:44:01.617,23.582489 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0506,17:44:01.618,23.582894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0507-0506,17:44:01.618,23.583489 s,595 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0508,17:44:01.618,23.583512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0509-0508,17:44:01.620,23.585489 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0510,17:44:01.621,23.585894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0511-0510,17:44:01.621,23.586488 s,594 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0512,17:44:01.621,23.586511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0513-0512,17:44:01.623,23.588488 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0514,17:44:01.624,23.588898 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0515-0514,17:44:01.624,23.589488 s,591 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0516,17:44:01.624,23.589512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0517-0516,17:44:01.626,23.591487 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0518,17:44:01.627,23.591900 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0519-0518,17:44:01.627,23.592489 s,589 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0520,17:44:01.627,23.592513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0521-0520,17:44:01.629,23.594488 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0522,17:44:01.630,23.594894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0523-0522,17:44:01.630,23.595488 s,594 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0524,17:44:01.630,23.595511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0525-0524,17:44:01.632,23.597487 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0526,17:44:01.633,23.597894 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0527-0526,17:44:01.633,23.598488 s,594 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0528,17:44:01.633,23.598512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0529-0528,17:44:01.635,23.600490 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0530,17:44:01.636,23.600905 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0531-0530,17:44:01.636,23.601502 s,596 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0532,17:44:01.636,23.601530 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0533-0532,17:44:01.638,23.603487 s,1.957 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0534,17:44:01.639,23.603897 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0535-0534,17:44:01.639,23.604488 s,591 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0536,17:44:01.639,23.604512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0537-0536,17:44:01.641,23.606489 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0538,17:44:01.642,23.606897 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0539-0538,17:44:01.642,23.607488 s,592 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0540,17:44:01.642,23.607512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0541-0540,17:44:01.644,23.609487 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0542,17:44:01.645,23.609899 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0543-0542,17:44:01.645,23.610488 s,589 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0544,17:44:01.645,23.610513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0545-0544,17:44:01.647,23.612487 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0546,17:44:01.648,23.612896 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0547-0546,17:44:01.648,23.613490 s,595 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0548,17:44:01.648,23.613514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0549-0548,17:44:01.650,23.615488 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0550,17:44:01.651,23.615895 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0551-0550,17:44:01.651,23.616488 s,592 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0552,17:44:01.651,23.616511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0553-0552,17:44:01.653,23.618488 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0554,17:44:01.654,23.618896 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0555-0554,17:44:01.654,23.619487 s,591 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0556,17:44:01.654,23.619511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0557-0556,17:44:01.656,23.621487 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0558,17:44:01.657,23.621901 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0559-0558,17:44:01.657,23.622487 s,587 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0560,17:44:01.657,23.622511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0561-0560,17:44:01.659,23.624488 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0562,17:44:01.660,23.624895 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0563-0562,17:44:01.660,23.625488 s,592 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0564,17:44:01.660,23.625511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0565-0564,17:44:01.662,23.627489 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0566,17:44:01.663,23.627896 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0567-0566,17:44:01.663,23.628487 s,591 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0568,17:44:01.663,23.628510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0569-0568,17:44:01.665,23.630488 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0570,17:44:01.666,23.630898 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0571-0570,17:44:01.666,23.631488 s,589 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0572,17:44:01.666,23.631512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0573-0572,17:44:01.668,23.633487 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0574,17:44:01.669,23.633896 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0575-0574,17:44:01.669,23.634487 s,591 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0576,17:44:01.669,23.634511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0577-0576,17:44:01.671,23.636487 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0578,17:44:01.672,23.636896 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0579-0578,17:44:01.672,23.637489 s,593 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0580,17:44:01.672,23.637512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0581-0580,17:44:01.674,23.639488 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0582,17:44:01.675,23.639897 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0583-0582,17:44:01.675,23.640488 s,591 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0584,17:44:01.675,23.640511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0585-0584,17:44:01.677,23.642487 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0586,17:44:01.678,23.642896 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0587-0586,17:44:01.678,23.643487 s,591 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0588,17:44:01.678,23.643510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0589-0588,17:44:01.680,23.645487 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0590,17:44:01.681,23.645896 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0591-0590,17:44:01.681,23.646487 s,590 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0592,17:44:01.681,23.646510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0593-0592,17:44:01.683,23.648487 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0594,17:44:01.684,23.648899 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0595-0594,17:44:01.684,23.649487 s,588 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0596,17:44:01.684,23.649511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0597-0596,17:44:01.686,23.651487 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0598,17:44:01.687,23.651901 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0599-0598,17:44:01.687,23.652487 s,585 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0600,17:44:01.687,23.652510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0601-0600,17:44:01.689,23.654489 s,1.979 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0602,17:44:01.690,23.654899 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0603-0602,17:44:01.690,23.655490 s,591 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0604,17:44:01.690,23.655514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0605-0604,17:44:01.692,23.657487 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0606,17:44:01.693,23.657898 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0607-0606,17:44:01.693,23.658488 s,589 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0608,17:44:01.693,23.658511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0609-0608,17:44:01.695,23.660486 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0610,17:44:01.696,23.660897 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0611-0610,17:44:01.696,23.661486 s,589 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0612,17:44:01.696,23.661510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0613-0612,17:44:01.698,23.663487 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0614,17:44:01.699,23.663899 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0615-0614,17:44:01.699,23.664486 s,587 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0616,17:44:01.699,23.664511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0617-0616,17:44:01.701,23.666486 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0618,17:44:01.702,23.666898 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0619-0618,17:44:01.702,23.667486 s,588 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0620,17:44:01.702,23.667510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0621-0620,17:44:01.704,23.669490 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0622,17:44:01.705,23.669901 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0623-0622,17:44:01.705,23.670487 s,587 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0624,17:44:01.705,23.670512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0625-0624,17:44:01.707,23.672487 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0626,17:44:01.708,23.672898 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0627-0626,17:44:01.708,23.673487 s,589 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0628,17:44:01.708,23.673510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0629-0628,17:44:01.710,23.675486 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0630,17:44:01.711,23.675898 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0631-0630,17:44:01.711,23.676487 s,589 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0632,17:44:01.711,23.676510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0633-0632,17:44:01.713,23.678487 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0634,17:44:01.714,23.678898 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0635-0634,17:44:01.714,23.679486 s,588 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0636,17:44:01.714,23.679510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0637-0636,17:44:01.716,23.681486 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0638,17:44:01.717,23.681904 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0639-0638,17:44:01.717,23.682486 s,582 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0640,17:44:01.717,23.682510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0641-0640,17:44:01.719,23.684485 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0642,17:44:01.720,23.684898 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0643-0642,17:44:01.720,23.685486 s,588 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0644,17:44:01.720,23.685510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0645-0644,17:44:01.722,23.687486 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0646,17:44:01.723,23.687898 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0647-0646,17:44:01.723,23.688486 s,588 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0648,17:44:01.723,23.688510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0649-0648,17:44:01.725,23.690486 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0650,17:44:01.726,23.690901 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0651-0650,17:44:01.726,23.691486 s,584 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0652,17:44:01.726,23.691509 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0653-0652,17:44:01.728,23.693486 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0654,17:44:01.729,23.693898 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0655-0654,17:44:01.729,23.694486 s,588 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0656,17:44:01.729,23.694510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0657-0656,17:44:01.731,23.696486 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0658,17:44:01.732,23.696899 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0659-0658,17:44:01.732,23.697486 s,587 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0660,17:44:01.732,23.697509 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0661-0660,17:44:01.734,23.699487 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0662,17:44:01.735,23.699900 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0663-0662,17:44:01.735,23.700486 s,586 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0664,17:44:01.735,23.700512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0665-0664,17:44:01.737,23.702486 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0666,17:44:01.738,23.702899 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0667-0666,17:44:01.738,23.703490 s,591 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0668,17:44:01.738,23.703514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0669-0668,17:44:01.740,23.705486 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0670,17:44:01.741,23.705899 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0671-0670,17:44:01.741,23.706487 s,587 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0672,17:44:01.741,23.706511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0673-0672,17:44:01.743,23.708486 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0674,17:44:01.744,23.708904 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0675-0674,17:44:01.744,23.709488 s,584 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0676,17:44:01.744,23.709515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0677-0676,17:44:01.746,23.711487 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0678,17:44:01.747,23.711906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0679-0678,17:44:01.747,23.712491 s,585 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0680,17:44:01.747,23.712520 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0681-0680,17:44:01.749,23.714489 s,1.969 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0682,17:44:01.750,23.714913 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0683-0682,17:44:01.750,23.715487 s,574 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0684,17:44:01.750,23.715516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0685-0684,17:44:01.752,23.717495 s,1.979 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0686,17:44:01.753,23.717908 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0687-0686,17:44:01.753,23.718488 s,580 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0688,17:44:01.753,23.718516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0689-0688,17:44:01.755,23.720485 s,1.969 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0690,17:44:01.756,23.720912 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0691-0690,17:44:01.756,23.721490 s,577 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0692,17:44:01.756,23.721516 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0693-0692,17:44:01.758,23.723484 s,1.968 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0694,17:44:01.759,23.723901 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0695-0694,17:44:01.759,23.724485 s,584 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0696,17:44:01.759,23.724508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0697-0696,17:44:01.761,23.726486 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0698,17:44:01.762,23.726899 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0699-0698,17:44:01.762,23.727485 s,586 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0700,17:44:01.762,23.727508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0701-0700,17:44:01.764,23.729487 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0702,17:44:01.765,23.729910 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0703-0702,17:44:01.765,23.730486 s,575 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0704,17:44:01.765,23.730512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0705-0704,17:44:01.767,23.732485 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0706,17:44:01.768,23.732900 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0707-0706,17:44:01.768,23.733485 s,585 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0708,17:44:01.768,23.733509 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0709-0708,17:44:01.770,23.735486 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0710,17:44:01.771,23.735900 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0711-0710,17:44:01.771,23.736489 s,589 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0712,17:44:01.771,23.736512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0713-0712,17:44:01.773,23.738485 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0714,17:44:01.774,23.738900 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0715-0714,17:44:01.774,23.739485 s,584 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0716,17:44:01.774,23.739508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0717-0716,17:44:01.776,23.741485 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0718,17:44:01.777,23.741907 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0719-0718,17:44:01.777,23.742485 s,578 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0720,17:44:01.777,23.742509 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0721-0720,17:44:01.779,23.744486 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0722,17:44:01.780,23.744906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0723-0722,17:44:01.780,23.745486 s,581 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0724,17:44:01.780,23.745512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0725-0724,17:44:01.782,23.747486 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0726,17:44:01.783,23.747908 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0727-0726,17:44:01.783,23.748485 s,577 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0728,17:44:01.783,23.748511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0729-0728,17:44:01.785,23.750485 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0730,17:44:01.786,23.750906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0731-0730,17:44:01.786,23.751486 s,580 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0732,17:44:01.786,23.751510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0733-0732,17:44:01.788,23.753485 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0734,17:44:01.789,23.753901 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0735-0734,17:44:01.789,23.754484 s,583 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0736,17:44:01.789,23.754507 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0737-0736,17:44:01.791,23.756487 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0738,17:44:01.792,23.756901 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0739-0738,17:44:01.792,23.757484 s,583 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0740,17:44:01.792,23.757508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0741-0740,17:44:01.794,23.759485 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0742,17:44:01.795,23.759904 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0743-0742,17:44:01.795,23.760485 s,581 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0744,17:44:01.795,23.760509 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0745-0744,17:44:01.797,23.762486 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0746,17:44:01.798,23.762904 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0747-0746,17:44:01.798,23.763484 s,580 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0748,17:44:01.798,23.763508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0749-0748,17:44:01.800,23.765484 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0750,17:44:01.801,23.765902 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0751-0750,17:44:01.801,23.766529 s,627 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0752,17:44:01.801,23.766553 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0753-0752,17:44:01.803,23.768492 s,1.939 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0754,17:44:01.804,23.768914 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0755-0754,17:44:01.804,23.769490 s,577 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0756,17:44:01.804,23.769519 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0757-0756,17:44:01.806,23.771485 s,1.965 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0758,17:44:01.807,23.771909 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0759-0758,17:44:01.807,23.772484 s,575 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0760,17:44:01.807,23.772508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0761-0760,17:44:01.809,23.774486 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0762,17:44:01.810,23.774901 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0763-0762,17:44:01.810,23.775487 s,586 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0764,17:44:01.810,23.775511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0765-0764,17:44:01.812,23.777486 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0766,17:44:01.813,23.777906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0767-0766,17:44:01.813,23.778486 s,580 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0768,17:44:01.813,23.778511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0769-0768,17:44:01.815,23.780484 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0770,17:44:01.816,23.780907 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0771-0770,17:44:01.816,23.781485 s,578 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0772,17:44:01.816,23.781508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0773-0772,17:44:01.818,23.783486 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0774,17:44:01.819,23.783904 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0775-0774,17:44:01.819,23.784486 s,582 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0776,17:44:01.819,23.784509 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0777-0776,17:44:01.821,23.786485 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0778,17:44:01.822,23.786902 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0779-0778,17:44:01.822,23.787483 s,581 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0780,17:44:01.822,23.787507 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0781-0780,17:44:01.824,23.789485 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0782,17:44:01.825,23.789906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0783-0782,17:44:01.825,23.790484 s,578 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0784,17:44:01.825,23.790509 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0785-0784,17:44:01.827,23.792485 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0786,17:44:01.828,23.792902 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0787-0786,17:44:01.828,23.793484 s,582 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0788,17:44:01.828,23.793508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0789-0788,17:44:01.830,23.795484 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0790,17:44:01.831,23.795902 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0791-0790,17:44:01.831,23.796484 s,582 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0792,17:44:01.831,23.796508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0793-0792,17:44:01.833,23.798484 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0794,17:44:01.834,23.798902 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0795-0794,17:44:01.834,23.799485 s,583 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0796,17:44:01.834,23.799509 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0797-0796,17:44:01.836,23.801485 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0798,17:44:01.837,23.801908 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0799-0798,17:44:01.837,23.802484 s,576 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0800,17:44:01.837,23.802508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0801-0800,17:44:01.839,23.804483 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0802,17:44:01.840,23.804903 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0803-0802,17:44:01.840,23.805484 s,581 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0804,17:44:01.840,23.805507 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0805-0804,17:44:01.842,23.807488 s,1.981 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0806,17:44:01.843,23.807910 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0807-0806,17:44:01.843,23.808486 s,576 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0808,17:44:01.843,23.808511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0809-0808,17:44:01.845,23.810485 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0810,17:44:01.846,23.810909 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0811-0810,17:44:01.846,23.811484 s,575 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0812,17:44:01.846,23.811508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0813-0812,17:44:01.848,23.813484 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0814,17:44:01.849,23.813904 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0815-0814,17:44:01.849,23.814485 s,581 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0816,17:44:01.849,23.814508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0817-0816,17:44:01.851,23.816484 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0818,17:44:01.852,23.816905 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0819-0818,17:44:01.852,23.817483 s,578 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0820,17:44:01.852,23.817508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0821-0820,17:44:01.854,23.819484 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0822,17:44:01.855,23.819903 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0823-0822,17:44:01.855,23.820483 s,580 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0824,17:44:01.855,23.820507 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0825-0824,17:44:01.857,23.822484 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0826,17:44:01.858,23.822903 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0827-0826,17:44:01.858,23.823483 s,580 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0828,17:44:01.858,23.823506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0829-0828,17:44:01.860,23.825487 s,1.981 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0830,17:44:01.861,23.825922 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0831-0830,17:44:01.861,23.826480 s,558 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0832,17:44:01.861,23.826509 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0833-0832,17:44:01.863,23.828476 s,1.967 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0834,17:44:01.864,23.828919 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0835-0834,17:44:01.864,23.829481 s,563 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0836,17:44:01.864,23.829508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0837-0836,17:44:01.866,23.831484 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0838,17:44:01.867,23.831911 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0839-0838,17:44:01.867,23.832483 s,572 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0840,17:44:01.867,23.832507 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0841-0840,17:44:01.869,23.834484 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0842,17:44:01.870,23.834905 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0843-0842,17:44:01.870,23.835483 s,578 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0844,17:44:01.870,23.835506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0845-0844,17:44:01.872,23.837484 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0846,17:44:01.873,23.837910 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0847-0846,17:44:01.873,23.838484 s,574 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0848,17:44:01.873,23.838508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0849-0848,17:44:01.875,23.840485 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0850,17:44:01.876,23.840907 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0851-0850,17:44:01.876,23.841479 s,572 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0852,17:44:01.876,23.841506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0853-0852,17:44:01.878,23.843476 s,1.970 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0854,17:44:01.879,23.843916 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0855-0854,17:44:01.879,23.844485 s,568 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0856,17:44:01.879,23.844511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0857-0856,17:44:01.881,23.846483 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0858,17:44:01.882,23.846906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0859-0858,17:44:01.882,23.847482 s,576 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0860,17:44:01.882,23.847507 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0861-0860,17:44:01.884,23.849485 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0862,17:44:01.885,23.849911 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0863-0862,17:44:01.885,23.850482 s,571 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0864,17:44:01.885,23.850508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0865-0864,17:44:01.887,23.852483 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0866,17:44:01.888,23.852905 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0867-0866,17:44:01.888,23.853482 s,578 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0868,17:44:01.888,23.853507 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0869-0868,17:44:01.890,23.855484 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0870,17:44:01.891,23.855908 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0871-0870,17:44:01.891,23.856483 s,575 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0872,17:44:01.891,23.856507 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0873-0872,17:44:01.893,23.858485 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0874,17:44:01.894,23.858905 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0875-0874,17:44:01.894,23.859483 s,578 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0876,17:44:01.894,23.859506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0877-0876,17:44:01.896,23.861483 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0878,17:44:01.897,23.861910 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0879-0878,17:44:01.897,23.862483 s,572 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0880,17:44:01.897,23.862506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0881-0880,17:44:01.899,23.864482 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0882,17:44:01.900,23.864904 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0883-0882,17:44:01.900,23.865483 s,578 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0884,17:44:01.900,23.865506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0885-0884,17:44:01.902,23.867483 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0886,17:44:01.903,23.867905 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0887-0886,17:44:01.903,23.868482 s,578 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0888,17:44:01.903,23.868506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0889-0888,17:44:01.905,23.870518 s,2.013 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0890,17:44:01.906,23.870911 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0891-0890,17:44:01.906,23.871488 s,576 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0892,17:44:01.906,23.871517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0893-0892,17:44:01.908,23.873487 s,1.971 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0894,17:44:01.909,23.873914 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0895-0894,17:44:01.909,23.874486 s,572 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0896,17:44:01.909,23.874513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0897-0896,17:44:01.911,23.876488 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0898,17:44:01.912,23.876909 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0899-0898,17:44:01.912,23.877482 s,572 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0900,17:44:01.912,23.877506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0901-0900,17:44:01.914,23.879483 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0902,17:44:01.915,23.879906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0903-0902,17:44:01.915,23.880482 s,576 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0904,17:44:01.915,23.880505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0905-0904,17:44:01.917,23.882483 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0906,17:44:01.918,23.882910 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0907-0906,17:44:01.918,23.883483 s,573 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0908,17:44:01.918,23.883506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0909-0908,17:44:01.920,23.885483 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0910,17:44:01.921,23.885906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0911-0910,17:44:01.921,23.886482 s,577 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0912,17:44:01.921,23.886505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0913-0912,17:44:01.923,23.888483 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0914,17:44:01.924,23.888907 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0915-0914,17:44:01.924,23.889483 s,576 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0916,17:44:01.924,23.889508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0917-0916,17:44:01.926,23.891482 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0918,17:44:01.927,23.891913 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0919-0918,17:44:01.927,23.892482 s,569 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0920,17:44:01.927,23.892506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0921-0920,17:44:01.929,23.894483 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0922,17:44:01.930,23.894906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0923-0922,17:44:01.930,23.895483 s,577 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0924,17:44:01.930,23.895507 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0925-0924,17:44:01.932,23.897482 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0926,17:44:01.933,23.897906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0927-0926,17:44:01.933,23.898482 s,575 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0928,17:44:01.933,23.898506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0929-0928,17:44:01.935,23.900482 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0930,17:44:01.936,23.900906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0931-0930,17:44:01.936,23.901482 s,576 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0932,17:44:01.936,23.901506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0933-0932,17:44:01.938,23.903482 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0934,17:44:01.939,23.903906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0935-0934,17:44:01.939,23.904482 s,576 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0936,17:44:01.939,23.904506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0937-0936,17:44:01.941,23.906483 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0938,17:44:01.942,23.906906 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0939-0938,17:44:01.942,23.907482 s,576 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0940,17:44:01.942,23.907506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0941-0940,17:44:01.944,23.909481 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0942,17:44:01.945,23.909909 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0943-0942,17:44:01.945,23.910513 s,604 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0944,17:44:01.945,23.910539 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0945-0944,17:44:01.947,23.912487 s,1.948 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0946,17:44:01.948,23.912912 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0947-0946,17:44:01.948,23.913485 s,573 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0948,17:44:01.948,23.913512 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0949-0948,17:44:01.950,23.915486 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0950,17:44:01.951,23.915911 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0951-0950,17:44:01.951,23.916481 s,569 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0952,17:44:01.951,23.916506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0953-0952,17:44:01.953,23.918507 s,2.001 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0954,17:44:01.954,23.918910 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0955-0954,17:44:01.954,23.919487 s,577 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0956,17:44:01.954,23.919513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0957-0956,17:44:01.956,23.921482 s,1.969 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0958,17:44:01.957,23.921915 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0959-0958,17:44:01.957,23.922481 s,566 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0960,17:44:01.957,23.922506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0961-0960,17:44:01.959,23.924482 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0962,17:44:01.960,23.924910 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0963-0962,17:44:01.960,23.925483 s,573 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0964,17:44:01.960,23.925509 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0965-0964,17:44:01.961,23.926505 s,996 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0966,17:44:01.962,23.926908 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0967-0966,17:44:01.962,23.927483 s,575 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0968,17:44:01.962,23.927509 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0969-0968,17:44:01.964,23.929482 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0970,17:44:01.965,23.929915 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0971-0970,17:44:01.965,23.930482 s,566 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0972,17:44:01.965,23.930508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0973-0972,17:44:01.967,23.932481 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0974,17:44:01.968,23.932908 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0975-0974,17:44:01.968,23.933481 s,573 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0976,17:44:01.968,23.933504 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0977-0976,17:44:01.969,23.934505 s,1.001 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0978,17:44:01.970,23.934910 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0979-0978,17:44:01.970,23.935488 s,578 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0980,17:44:01.970,23.935515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0981-0980,17:44:01.972,23.937484 s,1.969 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0982,17:44:01.973,23.937918 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0983-0982,17:44:01.973,23.938482 s,564 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0984,17:44:01.973,23.938507 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0985-0984,17:44:01.975,23.940482 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0986,17:44:01.976,23.940910 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0987-0986,17:44:01.976,23.941484 s,574 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0988,17:44:01.976,23.941508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0989-0988,17:44:01.977,23.942504 s,996 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0990,17:44:01.978,23.942909 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0991-0990,17:44:01.978,23.943484 s,575 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0992,17:44:01.978,23.943509 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0993-0992,17:44:01.980,23.945482 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0994,17:44:01.981,23.945910 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0995-0994,17:44:01.981,23.946481 s,570 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,0996,17:44:01.981,23.946505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0997-0996,17:44:01.983,23.948481 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,0998,17:44:01.984,23.948909 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0999-0998,17:44:01.984,23.949481 s,572 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1000,17:44:01.984,23.949505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1001-1000,17:44:01.985,23.950503 s,998 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1002,17:44:01.986,23.950914 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1003-1002,17:44:01.986,23.951485 s,572 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1004,17:44:01.986,23.951513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1005-1004,17:44:01.988,23.953482 s,1.969 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1006,17:44:01.989,23.953911 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1007-1006,17:44:01.989,23.954481 s,570 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1008,17:44:01.989,23.954505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1009-1008,17:44:01.991,23.956480 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1010,17:44:01.992,23.956908 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1011-1010,17:44:01.992,23.957484 s,576 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1012,17:44:01.992,23.957508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1013-1012,17:44:01.993,23.958504 s,996 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1014,17:44:01.994,23.958909 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1015-1014,17:44:01.994,23.959485 s,575 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1016,17:44:01.994,23.959510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1017-1016,17:44:01.996,23.961481 s,1.971 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1018,17:44:01.997,23.961911 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1019-1018,17:44:01.997,23.962481 s,570 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1020,17:44:01.997,23.962505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1021-1020,17:44:01.999,23.964481 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1022,17:44:02.000,23.964908 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1023-1022,17:44:02.000,23.965481 s,572 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1024,17:44:02.000,23.965504 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1025-1024,17:44:02.001,23.966505 s,1.001 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1026,17:44:02.002,23.966909 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1027-1026,17:44:02.002,23.967484 s,575 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1028,17:44:02.002,23.967509 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1029-1028,17:44:02.004,23.969482 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1030,17:44:02.005,23.969919 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1031-1030,17:44:02.005,23.970480 s,561 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1032,17:44:02.005,23.970505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1033-1032,17:44:02.007,23.972481 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1034,17:44:02.008,23.972909 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1035-1034,17:44:02.008,23.973483 s,575 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1036,17:44:02.008,23.973507 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1037-1036,17:44:02.009,23.974504 s,997 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1038,17:44:02.010,23.974911 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1039-1038,17:44:02.010,23.975484 s,573 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1040,17:44:02.010,23.975511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1041-1040,17:44:02.012,23.977482 s,1.971 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1042,17:44:02.013,23.977912 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1043-1042,17:44:02.013,23.978480 s,569 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1044,17:44:02.013,23.978504 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1045-1044,17:44:02.015,23.980481 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1046,17:44:02.016,23.980914 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1047-1046,17:44:02.016,23.981481 s,566 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1048,17:44:02.016,23.981506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1049-1048,17:44:02.017,23.982505 s,1000 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1050,17:44:02.018,23.982911 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1051-1050,17:44:02.018,23.983486 s,575 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1052,17:44:02.018,23.983513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1053-1052,17:44:02.020,23.985482 s,1.969 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1054,17:44:02.021,23.985915 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1055-1054,17:44:02.021,23.986480 s,565 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1056,17:44:02.021,23.986505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1057-1056,17:44:02.023,23.988480 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1058,17:44:02.024,23.988911 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1059-1058,17:44:02.024,23.989483 s,572 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1060,17:44:02.024,23.989508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1061-1060,17:44:02.025,23.990504 s,996 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1062,17:44:02.026,23.990912 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1063-1062,17:44:02.026,23.991487 s,575 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1064,17:44:02.026,23.991515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1065-1064,17:44:02.028,23.993482 s,1.968 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1066,17:44:02.029,23.993913 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1067-1066,17:44:02.029,23.994480 s,566 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1068,17:44:02.029,23.994504 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1069-1068,17:44:02.031,23.996480 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1070,17:44:02.032,23.996910 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1071-1070,17:44:02.032,23.997480 s,570 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1072,17:44:02.032,23.997503 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1073-1072,17:44:02.033,23.998504 s,1.001 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1074,17:44:02.034,23.998910 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1075-1074,17:44:02.034,23.999484 s,573 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1076,17:44:02.034,23.999510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1077-1076,17:44:02.036,24.001489 s,1.979 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1078,17:44:02.037,24.001970 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1079-1078,17:44:02.037,24.002479 s,509 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008264310h,Success (Success) -URB,1080,17:44:02.037,24.002521 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1081-1080,17:44:02.039,24.004477 s,1.956 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1082,17:44:02.040,24.004914 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1083-1082,17:44:02.040,24.005485 s,572 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1084,17:44:02.040,24.005510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1085-1084,17:44:02.041,24.006513 s,1.003 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1086,17:44:02.042,24.006912 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1087-1086,17:44:02.042,24.007486 s,574 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1088,17:44:02.042,24.007513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1089-1088,17:44:02.044,24.009483 s,1.970 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1090,17:44:02.045,24.009923 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1091-1090,17:44:02.045,24.010480 s,557 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1092,17:44:02.045,24.010506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1093-1092,17:44:02.047,24.012481 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1094,17:44:02.048,24.012915 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1095-1094,17:44:02.048,24.013481 s,566 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1096,17:44:02.048,24.013506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1097-1096,17:44:02.049,24.014511 s,1.005 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1098,17:44:02.050,24.014915 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1099-1098,17:44:02.050,24.015483 s,568 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1100,17:44:02.050,24.015508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1101-1100,17:44:02.052,24.017482 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1102,17:44:02.053,24.017913 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1103-1102,17:44:02.053,24.018478 s,565 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1104,17:44:02.053,24.018502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1105-1104,17:44:02.055,24.020484 s,1.981 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1106,17:44:02.056,24.020913 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1107-1106,17:44:02.056,24.021480 s,566 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1108,17:44:02.056,24.021504 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1109-1108,17:44:02.057,24.022503 s,999 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1110,17:44:02.058,24.022912 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1111-1110,17:44:02.058,24.023485 s,572 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1112,17:44:02.058,24.023513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1113-1112,17:44:02.060,24.025485 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1114,17:44:02.061,24.025922 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1115-1114,17:44:02.061,24.026479 s,557 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1116,17:44:02.061,24.026505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1117-1116,17:44:02.063,24.028479 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1118,17:44:02.064,24.028913 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1119-1118,17:44:02.064,24.029479 s,566 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1120,17:44:02.064,24.029503 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1121-1120,17:44:02.065,24.030507 s,1.003 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1122,17:44:02.066,24.030913 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1123-1122,17:44:02.066,24.031483 s,571 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1124,17:44:02.066,24.031508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1125-1124,17:44:02.068,24.033482 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1126,17:44:02.069,24.033916 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1127-1126,17:44:02.069,24.034480 s,564 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1128,17:44:02.069,24.034504 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1129-1128,17:44:02.071,24.036483 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1130,17:44:02.072,24.036914 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1131-1130,17:44:02.072,24.037479 s,565 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1132,17:44:02.072,24.037503 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1133-1132,17:44:02.073,24.038504 s,1.001 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1134,17:44:02.074,24.038912 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1135-1134,17:44:02.074,24.039481 s,569 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1136,17:44:02.074,24.039508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1137-1136,17:44:02.076,24.041483 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1138,17:44:02.077,24.041921 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1139-1138,17:44:02.077,24.042479 s,558 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1140,17:44:02.077,24.042505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1141-1140,17:44:02.079,24.044478 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1142,17:44:02.080,24.044913 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1143-1142,17:44:02.080,24.045479 s,566 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1144,17:44:02.080,24.045504 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1145-1144,17:44:02.081,24.046502 s,999 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1146,17:44:02.082,24.046913 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1147-1146,17:44:02.082,24.047481 s,569 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1148,17:44:02.082,24.047507 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1149-1148,17:44:02.084,24.049479 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1150,17:44:02.085,24.049921 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1151-1150,17:44:02.085,24.050478 s,558 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1152,17:44:02.085,24.050505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1153-1152,17:44:02.087,24.052479 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1154,17:44:02.088,24.052916 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1155-1154,17:44:02.088,24.053479 s,563 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1156,17:44:02.088,24.053503 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1157-1156,17:44:02.089,24.054503 s,999 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1158,17:44:02.090,24.054914 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1159-1158,17:44:02.090,24.055484 s,570 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1160,17:44:02.090,24.055510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1161-1160,17:44:02.092,24.057479 s,1.970 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1162,17:44:02.093,24.057917 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1163-1162,17:44:02.093,24.058478 s,561 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1164,17:44:02.093,24.058502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1165-1164,17:44:02.095,24.060479 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1166,17:44:02.096,24.060915 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1167-1166,17:44:02.096,24.061479 s,564 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1168,17:44:02.096,24.061504 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1169-1168,17:44:02.097,24.062502 s,998 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1170,17:44:02.098,24.062913 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1171-1170,17:44:02.098,24.063482 s,569 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1172,17:44:02.098,24.063508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1173-1172,17:44:02.100,24.065480 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1174,17:44:02.101,24.065915 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1175-1174,17:44:02.101,24.066478 s,564 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1176,17:44:02.101,24.066502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1177-1176,17:44:02.103,24.068479 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1178,17:44:02.104,24.068918 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1179-1178,17:44:02.104,24.069479 s,561 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1180,17:44:02.104,24.069506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1181-1180,17:44:02.105,24.070506 s,1.001 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1182,17:44:02.106,24.070916 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1183-1182,17:44:02.106,24.071486 s,570 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1184,17:44:02.106,24.071513 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1185-1184,17:44:02.108,24.073479 s,1.967 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1186,17:44:02.109,24.073920 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1187-1186,17:44:02.109,24.074478 s,558 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1188,17:44:02.109,24.074502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1189-1188,17:44:02.111,24.076478 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1190,17:44:02.112,24.076912 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1191-1190,17:44:02.112,24.077478 s,566 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1192,17:44:02.112,24.077502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1193-1192,17:44:02.113,24.078502 s,1.000 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1194,17:44:02.114,24.078917 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1195-1194,17:44:02.114,24.079482 s,565 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1196,17:44:02.114,24.079507 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1197-1196,17:44:02.116,24.081480 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1198,17:44:02.117,24.081916 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1199-1198,17:44:02.117,24.082479 s,563 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1200,17:44:02.117,24.082504 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1201-1200,17:44:02.119,24.084478 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1202,17:44:02.120,24.084913 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1203-1202,17:44:02.120,24.085478 s,565 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1204,17:44:02.120,24.085501 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1205-1204,17:44:02.121,24.086502 s,1.001 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1206,17:44:02.122,24.086925 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1207-1206,17:44:02.122,24.087482 s,557 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1208,17:44:02.122,24.087515 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1209-1208,17:44:02.124,24.089479 s,1.964 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1210,17:44:02.125,24.089939 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1211-1210,17:44:02.125,24.090481 s,542 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1212,17:44:02.125,24.090511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1213-1212,17:44:02.127,24.092478 s,1.967 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1214,17:44:02.128,24.092915 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1215-1214,17:44:02.128,24.093479 s,564 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1216,17:44:02.128,24.093503 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1217-1216,17:44:02.129,24.094510 s,1.007 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1218,17:44:02.130,24.094914 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1219-1218,17:44:02.130,24.095481 s,567 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1220,17:44:02.130,24.095508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1221-1220,17:44:02.132,24.097479 s,1.971 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1222,17:44:02.133,24.097918 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1223-1222,17:44:02.133,24.098478 s,561 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1224,17:44:02.133,24.098503 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1225-1224,17:44:02.135,24.100478 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1226,17:44:02.136,24.100914 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1227-1226,17:44:02.136,24.101478 s,564 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1228,17:44:02.136,24.101501 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1229-1228,17:44:02.137,24.102512 s,1.011 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1230,17:44:02.138,24.102924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1231-1230,17:44:02.138,24.103484 s,559 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1232,17:44:02.138,24.103510 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1233-1232,17:44:02.140,24.105481 s,1.970 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1234,17:44:02.141,24.105924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1235-1234,17:44:02.141,24.106478 s,554 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1236,17:44:02.141,24.106504 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1237-1236,17:44:02.143,24.108478 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1238,17:44:02.144,24.108924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1239-1238,17:44:02.144,24.109482 s,558 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1240,17:44:02.144,24.109507 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1241-1240,17:44:02.145,24.110507 s,1.000 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1242,17:44:02.146,24.110915 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1243-1242,17:44:02.146,24.111480 s,565 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1244,17:44:02.146,24.111505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1245-1244,17:44:02.148,24.113480 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1246,17:44:02.149,24.113917 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1247-1246,17:44:02.149,24.114477 s,561 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1248,17:44:02.149,24.114501 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1249-1248,17:44:02.151,24.116478 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1250,17:44:02.152,24.116914 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1251-1250,17:44:02.152,24.117478 s,564 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1252,17:44:02.152,24.117501 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1253-1252,17:44:02.153,24.118501 s,1000 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1254,17:44:02.154,24.118915 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1255-1254,17:44:02.154,24.119481 s,566 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1256,17:44:02.154,24.119506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1257-1256,17:44:02.156,24.121479 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1258,17:44:02.157,24.121923 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1259-1258,17:44:02.157,24.122478 s,555 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1260,17:44:02.157,24.122506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1261-1260,17:44:02.159,24.124482 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1262,17:44:02.160,24.124918 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1263-1262,17:44:02.160,24.125476 s,558 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1264,17:44:02.160,24.125500 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1265-1264,17:44:02.161,24.126501 s,1.001 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1266,17:44:02.162,24.126916 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1267-1266,17:44:02.162,24.127480 s,565 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1268,17:44:02.162,24.127506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1269-1268,17:44:02.164,24.129478 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1270,17:44:02.165,24.129925 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1271-1270,17:44:02.165,24.130477 s,552 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1272,17:44:02.165,24.130502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1273-1272,17:44:02.167,24.132478 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1274,17:44:02.168,24.132915 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1275-1274,17:44:02.168,24.133477 s,562 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1276,17:44:02.168,24.133501 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1277-1276,17:44:02.169,24.134503 s,1.001 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1278,17:44:02.170,24.134916 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1279-1278,17:44:02.170,24.135482 s,566 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1280,17:44:02.170,24.135508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1281-1280,17:44:02.172,24.137480 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1282,17:44:02.173,24.137939 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1283-1282,17:44:02.173,24.138479 s,540 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1284,17:44:02.173,24.138508 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1285-1284,17:44:02.175,24.140477 s,1.969 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1286,17:44:02.176,24.140918 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1287-1286,17:44:02.176,24.141476 s,558 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1288,17:44:02.176,24.141500 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1289-1288,17:44:02.177,24.142502 s,1.002 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1290,17:44:02.178,24.142916 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1291-1290,17:44:02.178,24.143480 s,564 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1292,17:44:02.178,24.143505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1293-1292,17:44:02.180,24.145477 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1294,17:44:02.181,24.145917 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1295-1294,17:44:02.181,24.146478 s,561 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1296,17:44:02.181,24.146502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1297-1296,17:44:02.183,24.148477 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1298,17:44:02.184,24.148917 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1299-1298,17:44:02.184,24.149477 s,560 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1300,17:44:02.184,24.149502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1301-1300,17:44:02.185,24.150501 s,999 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1302,17:44:02.186,24.150917 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1303-1302,17:44:02.186,24.151481 s,564 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1304,17:44:02.186,24.151506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1305-1304,17:44:02.188,24.153478 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1306,17:44:02.189,24.153919 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1307-1306,17:44:02.189,24.154477 s,558 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1308,17:44:02.189,24.154502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1309-1308,17:44:02.191,24.156477 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1310,17:44:02.192,24.156918 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1311-1310,17:44:02.192,24.157477 s,559 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1312,17:44:02.192,24.157502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1313-1312,17:44:02.193,24.158501 s,999 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1314,17:44:02.194,24.158917 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1315-1314,17:44:02.194,24.159489 s,572 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1316,17:44:02.194,24.159523 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1317-1316,17:44:02.196,24.161480 s,1.958 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1318,17:44:02.197,24.161929 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1319-1318,17:44:02.197,24.162471 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1320,17:44:02.197,24.162494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1321-1320,17:44:02.199,24.164470 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1322,17:44:02.200,24.164914 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1323-1322,17:44:02.200,24.165470 s,556 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1324,17:44:02.200,24.165492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1325-1324,17:44:02.201,24.166510 s,1.018 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1326,17:44:02.202,24.166918 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1327-1326,17:44:02.202,24.167473 s,555 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1328,17:44:02.202,24.167500 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1329-1328,17:44:02.204,24.169485 s,1.986 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1330,17:44:02.205,24.169923 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1331-1330,17:44:02.205,24.170474 s,550 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1332,17:44:02.205,24.170502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1333-1332,17:44:02.207,24.172477 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1334,17:44:02.208,24.172921 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1335-1334,17:44:02.208,24.173470 s,549 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1336,17:44:02.208,24.173494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1337-1336,17:44:02.209,24.174504 s,1.009 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1338,17:44:02.210,24.174916 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1339-1338,17:44:02.210,24.175474 s,558 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1340,17:44:02.210,24.175500 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1341-1340,17:44:02.212,24.177474 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1342,17:44:02.213,24.177917 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1343-1342,17:44:02.213,24.178470 s,552 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1344,17:44:02.213,24.178493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1345-1344,17:44:02.215,24.180469 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1346,17:44:02.216,24.180928 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80085419A0h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1347-1346,17:44:02.216,24.181471 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80085419A0h,Success (Success) -URB,1348,17:44:02.216,24.181503 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1349-1348,17:44:02.217,24.182498 s,994 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1350,17:44:02.218,24.182915 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1351-1350,17:44:02.218,24.183472 s,557 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1352,17:44:02.218,24.183498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1353-1352,17:44:02.220,24.185472 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1354,17:44:02.221,24.185917 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1355-1354,17:44:02.221,24.186471 s,554 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1356,17:44:02.221,24.186493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1357-1356,17:44:02.223,24.188469 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1358,17:44:02.224,24.188916 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1359-1358,17:44:02.224,24.189470 s,553 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1360,17:44:02.224,24.189494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1361-1360,17:44:02.225,24.190497 s,1.003 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1362,17:44:02.226,24.190916 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1363-1362,17:44:02.226,24.191472 s,556 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1364,17:44:02.226,24.191497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1365-1364,17:44:02.228,24.193472 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1366,17:44:02.229,24.193917 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1367-1366,17:44:02.229,24.194470 s,554 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1368,17:44:02.229,24.194493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1369-1368,17:44:02.231,24.196469 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1370,17:44:02.232,24.196914 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1371-1370,17:44:02.232,24.197469 s,555 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1372,17:44:02.232,24.197491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1373-1372,17:44:02.233,24.198469 s,978 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1374,17:44:02.234,24.198915 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1375-1374,17:44:02.234,24.199469 s,554 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1376,17:44:02.234,24.199492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1377-1376,17:44:02.236,24.201470 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1378,17:44:02.237,24.201917 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1379-1378,17:44:02.237,24.202478 s,561 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1380,17:44:02.237,24.202509 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1381-1380,17:44:02.239,24.204473 s,1.964 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1382,17:44:02.240,24.204920 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1383-1382,17:44:02.240,24.205471 s,551 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1384,17:44:02.240,24.205495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1385-1384,17:44:02.241,24.206505 s,1.010 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1386,17:44:02.242,24.206918 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1387-1386,17:44:02.242,24.207493 s,575 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1388,17:44:02.242,24.207524 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1389-1388,17:44:02.244,24.209481 s,1.956 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1390,17:44:02.245,24.209930 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1391-1390,17:44:02.245,24.210476 s,546 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1392,17:44:02.245,24.210503 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1393-1392,17:44:02.247,24.212475 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1394,17:44:02.248,24.212919 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1395-1394,17:44:02.248,24.213476 s,557 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1396,17:44:02.248,24.213499 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1397-1396,17:44:02.249,24.214511 s,1.012 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1398,17:44:02.250,24.214919 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1399-1398,17:44:02.250,24.215479 s,561 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1400,17:44:02.250,24.215505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1401-1400,17:44:02.252,24.217477 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1402,17:44:02.253,24.217922 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1403-1402,17:44:02.253,24.218475 s,554 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1404,17:44:02.253,24.218499 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1405-1404,17:44:02.255,24.220476 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1406,17:44:02.256,24.220918 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1407-1406,17:44:02.256,24.221476 s,558 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1408,17:44:02.256,24.221499 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1409-1408,17:44:02.257,24.222504 s,1.005 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1410,17:44:02.258,24.222924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1411-1410,17:44:02.258,24.223479 s,555 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1412,17:44:02.258,24.223505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1413-1412,17:44:02.260,24.225476 s,1.971 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1414,17:44:02.261,24.225921 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1415-1414,17:44:02.261,24.226476 s,555 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1416,17:44:02.261,24.226500 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1417-1416,17:44:02.263,24.228476 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1418,17:44:02.264,24.228922 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1419-1418,17:44:02.264,24.229479 s,557 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1420,17:44:02.264,24.229506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1421-1420,17:44:02.266,24.231784 s,2.278 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1422,17:44:02.267,24.231919 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1423-1422,17:44:02.267,24.232477 s,558 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1424,17:44:02.267,24.232503 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1425-1424,17:44:02.269,24.234476 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1426,17:44:02.270,24.234918 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1427-1426,17:44:02.270,24.235475 s,557 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1428,17:44:02.270,24.235498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1429-1428,17:44:02.272,24.237476 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1430,17:44:02.273,24.237925 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1431-1430,17:44:02.273,24.238476 s,551 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1432,17:44:02.273,24.238499 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1433-1432,17:44:02.275,24.240480 s,1.981 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1434,17:44:02.276,24.240921 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1435-1434,17:44:02.276,24.241475 s,554 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1436,17:44:02.276,24.241500 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1437-1436,17:44:02.278,24.243475 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1438,17:44:02.279,24.243919 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1439-1438,17:44:02.279,24.244475 s,556 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1440,17:44:02.279,24.244499 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1441-1440,17:44:02.281,24.246475 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1442,17:44:02.282,24.246919 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1443-1442,17:44:02.282,24.247476 s,557 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1444,17:44:02.282,24.247499 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1445-1444,17:44:02.284,24.249475 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1446,17:44:02.285,24.249924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1447-1446,17:44:02.285,24.250475 s,552 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1448,17:44:02.285,24.250500 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1449-1448,17:44:02.287,24.252474 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1450,17:44:02.288,24.252919 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1451-1450,17:44:02.288,24.253475 s,556 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1452,17:44:02.288,24.253499 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1453-1452,17:44:02.290,24.255475 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1454,17:44:02.291,24.255959 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096E4160h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1455-1454,17:44:02.291,24.256471 s,512 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096E4160h,Success (Success) -URB,1456,17:44:02.291,24.256501 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1457-1456,17:44:02.293,24.258473 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1458,17:44:02.294,24.258921 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1459-1458,17:44:02.294,24.259474 s,553 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1460,17:44:02.294,24.259499 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1461-1460,17:44:02.295,24.260521 s,1.022 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1462,17:44:02.296,24.260928 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1463-1462,17:44:02.296,24.261476 s,548 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1464,17:44:02.296,24.261505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1465-1464,17:44:02.298,24.263476 s,1.971 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1466,17:44:02.299,24.263930 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1467-1466,17:44:02.299,24.264476 s,546 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1468,17:44:02.299,24.264502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1469-1468,17:44:02.301,24.266475 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1470,17:44:02.302,24.266922 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1471-1470,17:44:02.302,24.267474 s,552 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1472,17:44:02.302,24.267498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1473-1472,17:44:02.304,24.269475 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1474,17:44:02.305,24.269923 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1475-1474,17:44:02.305,24.270475 s,552 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1476,17:44:02.305,24.270500 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1477-1476,17:44:02.307,24.272476 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1478,17:44:02.308,24.272920 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1479-1478,17:44:02.308,24.273475 s,555 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1480,17:44:02.308,24.273498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1481-1480,17:44:02.310,24.275475 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1482,17:44:02.311,24.275922 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1483-1482,17:44:02.311,24.276474 s,552 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1484,17:44:02.311,24.276498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1485-1484,17:44:02.313,24.278475 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1486,17:44:02.314,24.278921 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1487-1486,17:44:02.314,24.279475 s,553 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1488,17:44:02.314,24.279499 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1489-1488,17:44:02.316,24.281475 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1490,17:44:02.317,24.281930 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1491-1490,17:44:02.317,24.282475 s,545 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1492,17:44:02.317,24.282499 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1493-1492,17:44:02.319,24.284474 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1494,17:44:02.320,24.284921 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1495-1494,17:44:02.320,24.285477 s,556 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1496,17:44:02.320,24.285501 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1497-1496,17:44:02.322,24.287475 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1498,17:44:02.323,24.287920 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1499-1498,17:44:02.323,24.288475 s,554 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1500,17:44:02.323,24.288498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1501-1500,17:44:02.325,24.290474 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1502,17:44:02.326,24.290924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1503-1502,17:44:02.326,24.291474 s,549 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1504,17:44:02.326,24.291499 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1505-1504,17:44:02.328,24.293474 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1506,17:44:02.329,24.293923 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1507-1506,17:44:02.329,24.294475 s,552 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1508,17:44:02.329,24.294500 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1509-1508,17:44:02.331,24.296477 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1510,17:44:02.332,24.296928 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1511-1510,17:44:02.332,24.297474 s,546 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1512,17:44:02.332,24.297498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1513-1512,17:44:02.334,24.299474 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1514,17:44:02.335,24.299921 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1515-1514,17:44:02.335,24.300474 s,553 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1516,17:44:02.335,24.300497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1517-1516,17:44:02.337,24.302474 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1518,17:44:02.338,24.302921 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1519-1518,17:44:02.338,24.303474 s,552 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1520,17:44:02.338,24.303497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1521-1520,17:44:02.340,24.305475 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1522,17:44:02.341,24.305925 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1523-1522,17:44:02.341,24.306476 s,551 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1524,17:44:02.341,24.306503 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1525-1524,17:44:02.343,24.308474 s,1.971 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1526,17:44:02.344,24.308940 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1527-1526,17:44:02.344,24.309470 s,531 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1528,17:44:02.344,24.309501 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1529-1528,17:44:02.346,24.311472 s,1.971 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1530,17:44:02.347,24.311930 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1531-1530,17:44:02.347,24.312474 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1532,17:44:02.347,24.312498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1533-1532,17:44:02.349,24.314474 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1534,17:44:02.350,24.314922 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1535-1534,17:44:02.350,24.315473 s,552 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1536,17:44:02.350,24.315497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1537-1536,17:44:02.352,24.317474 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1538,17:44:02.353,24.317922 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1539-1538,17:44:02.353,24.318476 s,555 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1540,17:44:02.353,24.318500 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1541-1540,17:44:02.355,24.320475 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1542,17:44:02.356,24.320922 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1543-1542,17:44:02.356,24.321474 s,552 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1544,17:44:02.356,24.321497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1545-1544,17:44:02.358,24.323482 s,1.984 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1546,17:44:02.359,24.323937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1547-1546,17:44:02.359,24.324475 s,538 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1548,17:44:02.359,24.324504 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1549-1548,17:44:02.361,24.326477 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1550,17:44:02.362,24.326932 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1551-1550,17:44:02.362,24.327473 s,541 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1552,17:44:02.362,24.327498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1553-1552,17:44:02.364,24.329474 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1554,17:44:02.365,24.329925 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1555-1554,17:44:02.365,24.330473 s,548 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1556,17:44:02.365,24.330498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1557-1556,17:44:02.367,24.332473 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1558,17:44:02.368,24.332922 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1559-1558,17:44:02.368,24.333473 s,551 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1560,17:44:02.368,24.333497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1561-1560,17:44:02.370,24.335474 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1562,17:44:02.371,24.335922 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1563-1562,17:44:02.371,24.336474 s,552 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1564,17:44:02.371,24.336498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1565-1564,17:44:02.373,24.338474 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1566,17:44:02.374,24.338922 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1567-1566,17:44:02.374,24.339474 s,551 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1568,17:44:02.374,24.339497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1569-1568,17:44:02.376,24.341473 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1570,17:44:02.377,24.341929 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1571-1570,17:44:02.377,24.342474 s,545 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1572,17:44:02.377,24.342497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1573-1572,17:44:02.379,24.344473 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1574,17:44:02.380,24.344923 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1575-1574,17:44:02.380,24.345473 s,550 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1576,17:44:02.380,24.345496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1577-1576,17:44:02.382,24.347473 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1578,17:44:02.383,24.347923 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1579-1578,17:44:02.383,24.348473 s,551 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1580,17:44:02.383,24.348496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1581-1580,17:44:02.385,24.350474 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1582,17:44:02.386,24.350927 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1583-1582,17:44:02.386,24.351477 s,550 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1584,17:44:02.386,24.351502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1585-1584,17:44:02.388,24.353473 s,1.971 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1586,17:44:02.389,24.353924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1587-1586,17:44:02.389,24.354473 s,550 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1588,17:44:02.389,24.354497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1589-1588,17:44:02.391,24.356472 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1590,17:44:02.392,24.356925 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1591-1590,17:44:02.392,24.357472 s,547 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1592,17:44:02.392,24.357497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1593-1592,17:44:02.394,24.359474 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1594,17:44:02.395,24.359927 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1595-1594,17:44:02.395,24.360473 s,546 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1596,17:44:02.395,24.360496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1597-1596,17:44:02.397,24.362473 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1598,17:44:02.398,24.362923 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1599-1598,17:44:02.398,24.363472 s,549 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1600,17:44:02.398,24.363495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1601-1600,17:44:02.400,24.365476 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1602,17:44:02.401,24.365924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1603-1602,17:44:02.401,24.366473 s,549 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1604,17:44:02.401,24.366496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1605-1604,17:44:02.403,24.368472 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1606,17:44:02.404,24.368924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1607-1606,17:44:02.404,24.369473 s,549 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1608,17:44:02.404,24.369497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1609-1608,17:44:02.406,24.371473 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1610,17:44:02.407,24.371929 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1611-1610,17:44:02.407,24.372472 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1612,17:44:02.407,24.372496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1613-1612,17:44:02.409,24.374473 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1614,17:44:02.410,24.374924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1615-1614,17:44:02.410,24.375472 s,549 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1616,17:44:02.410,24.375496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1617-1616,17:44:02.412,24.377473 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1618,17:44:02.413,24.377924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1619-1618,17:44:02.413,24.378473 s,549 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1620,17:44:02.413,24.378497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1621-1620,17:44:02.415,24.380514 s,2.018 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1622,17:44:02.416,24.380926 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1623-1622,17:44:02.416,24.381478 s,552 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1624,17:44:02.416,24.381506 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1625-1624,17:44:02.418,24.383488 s,1.982 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1626,17:44:02.419,24.383932 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1627-1626,17:44:02.419,24.384475 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1628,17:44:02.419,24.384503 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1629-1628,17:44:02.421,24.386473 s,1.970 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1630,17:44:02.422,24.386924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1631-1630,17:44:02.422,24.387473 s,549 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1632,17:44:02.422,24.387497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1633-1632,17:44:02.424,24.389473 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1634,17:44:02.425,24.389930 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1635-1634,17:44:02.425,24.390472 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1636,17:44:02.425,24.390498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1637-1636,17:44:02.427,24.392473 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1638,17:44:02.428,24.392929 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1639-1638,17:44:02.428,24.393473 s,544 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1640,17:44:02.428,24.393497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1641-1640,17:44:02.430,24.395472 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1642,17:44:02.431,24.395924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1643-1642,17:44:02.431,24.396472 s,548 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1644,17:44:02.431,24.396496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1645-1644,17:44:02.433,24.398473 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1646,17:44:02.434,24.398925 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1647-1646,17:44:02.434,24.399473 s,549 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1648,17:44:02.434,24.399497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1649-1648,17:44:02.436,24.401473 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1650,17:44:02.437,24.401931 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1651-1650,17:44:02.437,24.402473 s,542 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1652,17:44:02.437,24.402496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1653-1652,17:44:02.439,24.404472 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1654,17:44:02.440,24.404924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1655-1654,17:44:02.440,24.405474 s,550 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1656,17:44:02.440,24.405498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1657-1656,17:44:02.442,24.407473 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1658,17:44:02.443,24.407924 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1659-1658,17:44:02.443,24.408472 s,547 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1660,17:44:02.443,24.408495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1661-1660,17:44:02.445,24.410473 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1662,17:44:02.446,24.410929 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1663-1662,17:44:02.446,24.411471 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1664,17:44:02.446,24.411496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1665-1664,17:44:02.448,24.413471 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1666,17:44:02.449,24.413926 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1667-1666,17:44:02.449,24.414472 s,546 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1668,17:44:02.449,24.414496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1669-1668,17:44:02.451,24.416472 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1670,17:44:02.452,24.416925 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1671-1670,17:44:02.452,24.417473 s,547 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1672,17:44:02.452,24.417496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1673-1672,17:44:02.454,24.419475 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1674,17:44:02.455,24.419927 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1675-1674,17:44:02.455,24.420471 s,544 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1676,17:44:02.455,24.420495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1677-1676,17:44:02.457,24.422472 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1678,17:44:02.458,24.422930 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1679-1678,17:44:02.458,24.423471 s,542 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1680,17:44:02.458,24.423495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1681-1680,17:44:02.460,24.425473 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1682,17:44:02.461,24.425926 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1683-1682,17:44:02.461,24.426472 s,546 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1684,17:44:02.461,24.426496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1685-1684,17:44:02.463,24.428472 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1686,17:44:02.464,24.428927 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1687-1686,17:44:02.464,24.429471 s,544 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1688,17:44:02.464,24.429495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1689-1688,17:44:02.466,24.431472 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1690,17:44:02.467,24.431932 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1691-1690,17:44:02.467,24.432472 s,541 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1692,17:44:02.467,24.432496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1693-1692,17:44:02.469,24.434472 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1694,17:44:02.470,24.434926 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1695-1694,17:44:02.470,24.435471 s,545 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1696,17:44:02.470,24.435495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1697-1696,17:44:02.472,24.437471 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1698,17:44:02.473,24.437932 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1699-1698,17:44:02.473,24.438471 s,539 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1700,17:44:02.473,24.438495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1701-1700,17:44:02.475,24.440473 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1702,17:44:02.476,24.440926 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1703-1702,17:44:02.476,24.441471 s,545 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1704,17:44:02.476,24.441494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1705-1704,17:44:02.478,24.443471 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1706,17:44:02.479,24.443927 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1707-1706,17:44:02.479,24.444472 s,545 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1708,17:44:02.479,24.444495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1709-1708,17:44:02.481,24.446472 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1710,17:44:02.482,24.446927 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1711-1710,17:44:02.482,24.447472 s,545 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1712,17:44:02.482,24.447495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1713-1712,17:44:02.484,24.449471 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1714,17:44:02.485,24.449929 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1715-1714,17:44:02.485,24.450471 s,542 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1716,17:44:02.485,24.450496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1717-1716,17:44:02.487,24.452471 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1718,17:44:02.488,24.452927 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1719-1718,17:44:02.488,24.453474 s,547 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1720,17:44:02.488,24.453498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1721-1720,17:44:02.490,24.455472 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1722,17:44:02.491,24.455972 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096E4160h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1723-1722,17:44:02.491,24.456466 s,495 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096E4160h,Success (Success) -URB,1724,17:44:02.491,24.456494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1725-1724,17:44:02.493,24.458469 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1726,17:44:02.494,24.458928 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1727-1726,17:44:02.494,24.459471 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1728,17:44:02.494,24.459494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1729-1728,17:44:02.496,24.461471 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1730,17:44:02.497,24.461931 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1731-1730,17:44:02.497,24.462471 s,540 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1732,17:44:02.497,24.462495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1733-1732,17:44:02.499,24.464471 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1734,17:44:02.500,24.464927 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1735-1734,17:44:02.500,24.465470 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1736,17:44:02.500,24.465494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1737-1736,17:44:02.502,24.467473 s,1.979 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1738,17:44:02.503,24.467927 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1739-1738,17:44:02.503,24.468470 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1740,17:44:02.503,24.468494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1741-1740,17:44:02.505,24.470472 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1742,17:44:02.506,24.470930 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1743-1742,17:44:02.506,24.471471 s,541 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1744,17:44:02.506,24.471495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1745-1744,17:44:02.508,24.473471 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1746,17:44:02.509,24.473928 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1747-1746,17:44:02.509,24.474470 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1748,17:44:02.509,24.474494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1749-1748,17:44:02.511,24.476470 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1750,17:44:02.512,24.476929 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1751-1750,17:44:02.512,24.477471 s,542 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1752,17:44:02.512,24.477494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1753-1752,17:44:02.514,24.479471 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1754,17:44:02.515,24.479928 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1755-1754,17:44:02.515,24.480470 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1756,17:44:02.515,24.480494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1757-1756,17:44:02.517,24.482471 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1758,17:44:02.518,24.482928 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1759-1758,17:44:02.518,24.483470 s,542 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1760,17:44:02.518,24.483493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1761-1760,17:44:02.520,24.485470 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1762,17:44:02.521,24.485928 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1763-1762,17:44:02.521,24.486470 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1764,17:44:02.521,24.486494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1765-1764,17:44:02.523,24.488471 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1766,17:44:02.524,24.488929 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1767-1766,17:44:02.524,24.489471 s,541 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1768,17:44:02.524,24.489494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1769-1768,17:44:02.526,24.491470 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1770,17:44:02.527,24.491932 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1771-1770,17:44:02.527,24.492470 s,538 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1772,17:44:02.527,24.492494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1773-1772,17:44:02.529,24.494470 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1774,17:44:02.530,24.494928 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1775-1774,17:44:02.530,24.495471 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1776,17:44:02.530,24.495494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1777-1776,17:44:02.532,24.497470 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1778,17:44:02.533,24.497928 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1779-1778,17:44:02.533,24.498470 s,542 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1780,17:44:02.533,24.498494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1781-1780,17:44:02.535,24.500470 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1782,17:44:02.536,24.500929 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1783-1782,17:44:02.536,24.501485 s,556 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1784,17:44:02.536,24.501514 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1785-1784,17:44:02.538,24.503473 s,1.959 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1786,17:44:02.539,24.503932 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1787-1786,17:44:02.539,24.504470 s,538 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1788,17:44:02.539,24.504494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1789-1788,17:44:02.541,24.506469 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1790,17:44:02.542,24.506928 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1791-1790,17:44:02.542,24.507470 s,542 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1792,17:44:02.542,24.507493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1793-1792,17:44:02.544,24.509470 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1794,17:44:02.545,24.509933 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1795-1794,17:44:02.545,24.510470 s,538 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1796,17:44:02.545,24.510495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1797-1796,17:44:02.547,24.512470 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1798,17:44:02.548,24.512929 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1799-1798,17:44:02.548,24.513470 s,541 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1800,17:44:02.548,24.513493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1801-1800,17:44:02.550,24.515470 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1802,17:44:02.551,24.515929 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1803-1802,17:44:02.551,24.516470 s,541 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1804,17:44:02.551,24.516493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1805-1804,17:44:02.553,24.518471 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1806,17:44:02.554,24.518929 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1807-1806,17:44:02.554,24.519470 s,541 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1808,17:44:02.554,24.519493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1809-1808,17:44:02.556,24.521471 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1810,17:44:02.557,24.521934 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1811-1810,17:44:02.557,24.522473 s,539 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1812,17:44:02.557,24.522497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1813-1812,17:44:02.559,24.524484 s,1.987 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1814,17:44:02.560,24.524933 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1815-1814,17:44:02.560,24.525474 s,541 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1816,17:44:02.560,24.525502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1817-1816,17:44:02.562,24.527474 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1818,17:44:02.563,24.527930 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1819-1818,17:44:02.563,24.528470 s,540 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1820,17:44:02.563,24.528494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1821-1820,17:44:02.565,24.530470 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1822,17:44:02.566,24.530932 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1823-1822,17:44:02.566,24.531469 s,537 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1824,17:44:02.566,24.531494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1825-1824,17:44:02.567,24.532523 s,1.029 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1826,17:44:02.568,24.532932 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1827-1826,17:44:02.568,24.533476 s,544 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1828,17:44:02.568,24.533504 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1829-1828,17:44:02.570,24.535471 s,1.968 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1830,17:44:02.571,24.535939 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1831-1830,17:44:02.571,24.536470 s,531 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1832,17:44:02.571,24.536495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1833-1832,17:44:02.573,24.538471 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1834,17:44:02.574,24.538930 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1835-1834,17:44:02.574,24.539472 s,542 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1836,17:44:02.574,24.539497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1837-1836,17:44:02.576,24.541470 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1838,17:44:02.577,24.541932 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1839-1838,17:44:02.577,24.542469 s,537 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1840,17:44:02.577,24.542493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1841-1840,17:44:02.579,24.544470 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1842,17:44:02.580,24.544930 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1843-1842,17:44:02.580,24.545470 s,539 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1844,17:44:02.580,24.545493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1845-1844,17:44:02.582,24.547469 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1846,17:44:02.583,24.547930 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1847-1846,17:44:02.583,24.548493 s,563 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1848,17:44:02.583,24.548518 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1849-1848,17:44:02.585,24.550471 s,1.954 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1850,17:44:02.586,24.550933 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1851-1850,17:44:02.586,24.551470 s,537 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1852,17:44:02.586,24.551495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1853-1852,17:44:02.588,24.553473 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1854,17:44:02.589,24.553931 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1855-1854,17:44:02.589,24.554469 s,538 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1856,17:44:02.589,24.554493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1857-1856,17:44:02.591,24.556469 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1858,17:44:02.592,24.556933 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1859-1858,17:44:02.592,24.557468 s,535 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1860,17:44:02.592,24.557492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1861-1860,17:44:02.594,24.559470 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1862,17:44:02.595,24.559931 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1863-1862,17:44:02.595,24.560469 s,538 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1864,17:44:02.595,24.560492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1865-1864,17:44:02.597,24.562470 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1866,17:44:02.598,24.562931 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1867-1866,17:44:02.598,24.563468 s,538 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1868,17:44:02.598,24.563492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1869-1868,17:44:02.600,24.565469 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1870,17:44:02.601,24.565930 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1871-1870,17:44:02.601,24.566470 s,540 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1872,17:44:02.601,24.566494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1873-1872,17:44:02.603,24.568469 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1874,17:44:02.604,24.568933 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1875-1874,17:44:02.604,24.569468 s,535 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1876,17:44:02.604,24.569492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1877-1876,17:44:02.606,24.571469 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1878,17:44:02.607,24.571932 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1879-1878,17:44:02.607,24.572468 s,537 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1880,17:44:02.607,24.572492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1881-1880,17:44:02.609,24.574469 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1882,17:44:02.610,24.574934 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1883-1882,17:44:02.610,24.575469 s,535 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1884,17:44:02.610,24.575493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1885-1884,17:44:02.612,24.577470 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1886,17:44:02.613,24.577932 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1887-1886,17:44:02.613,24.578470 s,538 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1888,17:44:02.613,24.578493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1889-1888,17:44:02.615,24.580469 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1890,17:44:02.616,24.580934 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1891-1890,17:44:02.616,24.581469 s,535 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1892,17:44:02.616,24.581492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1893-1892,17:44:02.618,24.583469 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1894,17:44:02.619,24.583932 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1895-1894,17:44:02.619,24.584468 s,536 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1896,17:44:02.619,24.584492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1897-1896,17:44:02.621,24.586470 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1898,17:44:02.622,24.586938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1899-1898,17:44:02.622,24.587467 s,530 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1900,17:44:02.622,24.587493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1901-1900,17:44:02.624,24.589468 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1902,17:44:02.625,24.589943 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1903-1902,17:44:02.625,24.590468 s,525 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1904,17:44:02.625,24.590494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1905-1904,17:44:02.627,24.592469 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1906,17:44:02.628,24.592935 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1907-1906,17:44:02.628,24.593471 s,537 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1908,17:44:02.628,24.593496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1909-1908,17:44:02.630,24.595468 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1910,17:44:02.631,24.595933 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1911-1910,17:44:02.631,24.596468 s,535 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1912,17:44:02.631,24.596492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1913-1912,17:44:02.633,24.598468 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1914,17:44:02.634,24.598933 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1915-1914,17:44:02.634,24.599468 s,536 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1916,17:44:02.634,24.599492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1917-1916,17:44:02.636,24.601469 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1918,17:44:02.637,24.601933 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1919-1918,17:44:02.637,24.602468 s,535 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1920,17:44:02.637,24.602492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1921-1920,17:44:02.639,24.604468 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1922,17:44:02.640,24.604932 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1923-1922,17:44:02.640,24.605468 s,535 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1924,17:44:02.640,24.605491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1925-1924,17:44:02.642,24.607471 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1926,17:44:02.643,24.607934 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1927-1926,17:44:02.643,24.608468 s,534 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1928,17:44:02.643,24.608491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1929-1928,17:44:02.645,24.610468 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1930,17:44:02.646,24.610935 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1931-1930,17:44:02.646,24.611468 s,532 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1932,17:44:02.646,24.611492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1933-1932,17:44:02.648,24.613469 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1934,17:44:02.649,24.613937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1935-1934,17:44:02.649,24.614467 s,531 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1936,17:44:02.649,24.614493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1937-1936,17:44:02.651,24.616468 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1938,17:44:02.652,24.616933 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1939-1938,17:44:02.652,24.617468 s,535 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1940,17:44:02.652,24.617491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1941-1940,17:44:02.654,24.619468 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1942,17:44:02.655,24.619933 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1943-1942,17:44:02.655,24.620467 s,535 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1944,17:44:02.655,24.620491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1945-1944,17:44:02.657,24.622468 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1946,17:44:02.658,24.622937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1947-1946,17:44:02.658,24.623468 s,530 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1948,17:44:02.658,24.623491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1949-1948,17:44:02.660,24.625467 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1950,17:44:02.661,24.625933 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1951-1950,17:44:02.661,24.626468 s,535 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1952,17:44:02.661,24.626492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1953-1952,17:44:02.663,24.628467 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1954,17:44:02.664,24.628935 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1955-1954,17:44:02.664,24.629468 s,533 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1956,17:44:02.664,24.629492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1957-1956,17:44:02.666,24.631468 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1958,17:44:02.667,24.631934 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1959-1958,17:44:02.667,24.632468 s,534 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1960,17:44:02.667,24.632491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1961-1960,17:44:02.669,24.634469 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1962,17:44:02.670,24.634936 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1963-1962,17:44:02.670,24.635467 s,531 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1964,17:44:02.670,24.635491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1965-1964,17:44:02.672,24.637468 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1966,17:44:02.673,24.637940 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1967-1966,17:44:02.673,24.638468 s,527 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1968,17:44:02.673,24.638492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1969-1968,17:44:02.675,24.640468 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1970,17:44:02.676,24.640934 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1971-1970,17:44:02.676,24.641470 s,536 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1972,17:44:02.676,24.641493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1973-1972,17:44:02.678,24.643467 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1974,17:44:02.679,24.643934 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1975-1974,17:44:02.679,24.644467 s,532 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1976,17:44:02.679,24.644490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1977-1976,17:44:02.681,24.646467 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1978,17:44:02.682,24.646934 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1979-1978,17:44:02.682,24.647467 s,533 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1980,17:44:02.682,24.647491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1981-1980,17:44:02.684,24.649468 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1982,17:44:02.685,24.649937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1983-1982,17:44:02.685,24.650468 s,530 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1984,17:44:02.685,24.650492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1985-1984,17:44:02.687,24.652467 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1986,17:44:02.688,24.652934 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1987-1986,17:44:02.688,24.653467 s,532 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1988,17:44:02.688,24.653491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1989-1988,17:44:02.690,24.655470 s,1.979 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1990,17:44:02.691,24.655938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1991-1990,17:44:02.691,24.656468 s,530 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1992,17:44:02.691,24.656491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1993-1992,17:44:02.693,24.658467 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1994,17:44:02.694,24.658936 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1995-1994,17:44:02.694,24.659468 s,532 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,1996,17:44:02.694,24.659491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,1997-1996,17:44:02.696,24.661467 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,1998,17:44:02.697,24.661935 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,1999-1998,17:44:02.697,24.662467 s,532 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2000,17:44:02.697,24.662490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2001-2000,17:44:02.699,24.664467 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2002,17:44:02.700,24.664934 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2003-2002,17:44:02.700,24.665467 s,532 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2004,17:44:02.700,24.665490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2005-2004,17:44:02.702,24.667469 s,1.979 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2006,17:44:02.703,24.667936 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2007-2006,17:44:02.703,24.668467 s,530 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2008,17:44:02.703,24.668492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2009-2008,17:44:02.705,24.670468 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2010,17:44:02.706,24.670938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2011-2010,17:44:02.706,24.671467 s,529 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2012,17:44:02.706,24.671492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2013-2012,17:44:02.708,24.673467 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2014,17:44:02.709,24.673937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2015-2014,17:44:02.709,24.674467 s,530 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2016,17:44:02.709,24.674492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2017-2016,17:44:02.711,24.676467 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2018,17:44:02.712,24.676936 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2019-2018,17:44:02.712,24.677466 s,530 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2020,17:44:02.712,24.677490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2021-2020,17:44:02.714,24.679468 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2022,17:44:02.715,24.679936 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2023-2022,17:44:02.715,24.680466 s,530 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2024,17:44:02.715,24.680490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2025-2024,17:44:02.717,24.682467 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2026,17:44:02.718,24.682935 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2027-2026,17:44:02.718,24.683467 s,532 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2028,17:44:02.718,24.683490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2029-2028,17:44:02.720,24.685467 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2030,17:44:02.721,24.685935 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2031-2030,17:44:02.721,24.686467 s,532 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2032,17:44:02.721,24.686490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2033-2032,17:44:02.723,24.688470 s,1.981 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2034,17:44:02.724,24.688938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2035-2034,17:44:02.724,24.689481 s,543 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2036,17:44:02.724,24.689511 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2037-2036,17:44:02.726,24.691474 s,1.963 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2038,17:44:02.727,24.691937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2039-2038,17:44:02.727,24.692473 s,536 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2040,17:44:02.727,24.692498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2041-2040,17:44:02.729,24.694467 s,1.969 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2042,17:44:02.730,24.694936 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2043-2042,17:44:02.730,24.695466 s,530 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2044,17:44:02.730,24.695491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2045-2044,17:44:02.732,24.697467 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2046,17:44:02.733,24.697936 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2047-2046,17:44:02.733,24.698466 s,531 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2048,17:44:02.733,24.698490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2049-2048,17:44:02.735,24.700473 s,1.984 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2050,17:44:02.736,24.700936 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2051-2050,17:44:02.736,24.701466 s,529 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2052,17:44:02.736,24.701490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2053-2052,17:44:02.738,24.703469 s,1.979 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2054,17:44:02.739,24.703937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2055-2054,17:44:02.739,24.704475 s,538 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2056,17:44:02.739,24.704498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2057-2056,17:44:02.741,24.706474 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2058,17:44:02.742,24.706937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2059-2058,17:44:02.742,24.707474 s,537 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2060,17:44:02.742,24.707497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2061-2060,17:44:02.744,24.709467 s,1.970 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2062,17:44:02.745,24.709945 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2063-2062,17:44:02.745,24.710474 s,529 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2064,17:44:02.745,24.710500 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2065-2064,17:44:02.747,24.712468 s,1.968 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2066,17:44:02.748,24.712944 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2067-2066,17:44:02.748,24.713475 s,531 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2068,17:44:02.748,24.713500 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2069-2068,17:44:02.750,24.715466 s,1.966 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2070,17:44:02.751,24.715937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2071-2070,17:44:02.751,24.716466 s,529 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2072,17:44:02.751,24.716490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2073-2072,17:44:02.753,24.718466 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2074,17:44:02.754,24.718937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2075-2074,17:44:02.754,24.719466 s,529 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2076,17:44:02.754,24.719491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2077-2076,17:44:02.756,24.721466 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2078,17:44:02.757,24.721937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2079-2078,17:44:02.757,24.722467 s,530 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2080,17:44:02.757,24.722491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2081-2080,17:44:02.759,24.724466 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2082,17:44:02.760,24.724937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2083-2082,17:44:02.760,24.725465 s,528 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2084,17:44:02.760,24.725489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2085-2084,17:44:02.762,24.727467 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2086,17:44:02.763,24.727937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2087-2086,17:44:02.763,24.728465 s,529 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2088,17:44:02.763,24.728489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2089-2088,17:44:02.765,24.730466 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2090,17:44:02.766,24.730941 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2091-2090,17:44:02.766,24.731465 s,525 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2092,17:44:02.766,24.731490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2093-2092,17:44:02.768,24.733466 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2094,17:44:02.769,24.733937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2095-2094,17:44:02.769,24.734466 s,529 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2096,17:44:02.769,24.734490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2097-2096,17:44:02.771,24.736465 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2098,17:44:02.772,24.736937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2099-2098,17:44:02.772,24.737468 s,531 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2100,17:44:02.772,24.737492 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2101-2100,17:44:02.774,24.739466 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2102,17:44:02.775,24.739937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2103-2102,17:44:02.775,24.740465 s,528 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2104,17:44:02.775,24.740489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2105-2104,17:44:02.777,24.742467 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2106,17:44:02.778,24.742938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2107-2106,17:44:02.778,24.743465 s,527 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2108,17:44:02.778,24.743489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2109-2108,17:44:02.780,24.745466 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2110,17:44:02.781,24.745938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2111-2110,17:44:02.781,24.746465 s,527 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2112,17:44:02.781,24.746489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2113-2112,17:44:02.783,24.748465 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2114,17:44:02.784,24.748939 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2115-2114,17:44:02.784,24.749465 s,526 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2116,17:44:02.784,24.749489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2117-2116,17:44:02.786,24.751468 s,1.979 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2118,17:44:02.787,24.751938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2119-2118,17:44:02.787,24.752465 s,527 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2120,17:44:02.787,24.752488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2121-2120,17:44:02.789,24.754465 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2122,17:44:02.790,24.754939 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2123-2122,17:44:02.790,24.755464 s,525 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2124,17:44:02.790,24.755488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2125-2124,17:44:02.792,24.757465 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2126,17:44:02.793,24.757938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2127-2126,17:44:02.793,24.758465 s,527 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2128,17:44:02.793,24.758488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2129-2128,17:44:02.795,24.760466 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2130,17:44:02.796,24.760940 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2131-2130,17:44:02.796,24.761466 s,525 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2132,17:44:02.796,24.761489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2133-2132,17:44:02.798,24.763466 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2134,17:44:02.799,24.763938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2135-2134,17:44:02.799,24.764465 s,527 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2136,17:44:02.799,24.764489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2137-2136,17:44:02.801,24.766465 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2138,17:44:02.802,24.766938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2139-2138,17:44:02.802,24.767466 s,527 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2140,17:44:02.802,24.767489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2141-2140,17:44:02.804,24.769465 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2142,17:44:02.805,24.769941 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2143-2142,17:44:02.805,24.770464 s,523 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2144,17:44:02.805,24.770489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2145-2144,17:44:02.807,24.772465 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2146,17:44:02.808,24.772940 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2147-2146,17:44:02.808,24.773464 s,524 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2148,17:44:02.808,24.773487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2149-2148,17:44:02.810,24.775466 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2150,17:44:02.811,24.775939 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2151-2150,17:44:02.811,24.776465 s,526 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2152,17:44:02.811,24.776488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2153-2152,17:44:02.813,24.778466 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2154,17:44:02.814,24.778939 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2155-2154,17:44:02.814,24.779464 s,525 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2156,17:44:02.814,24.779488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2157-2156,17:44:02.816,24.781465 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2158,17:44:02.817,24.781952 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2159-2158,17:44:02.817,24.782476 s,524 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2160,17:44:02.817,24.782505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2161-2160,17:44:02.819,24.784463 s,1.958 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2162,17:44:02.820,24.784938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2163-2162,17:44:02.820,24.785458 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2164,17:44:02.820,24.785480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2165-2164,17:44:02.822,24.787457 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2166,17:44:02.823,24.787937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2167-2166,17:44:02.823,24.788458 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2168,17:44:02.823,24.788480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2169-2168,17:44:02.824,24.789461 s,980 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2170,17:44:02.825,24.789939 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2171-2170,17:44:02.825,24.790459 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2172,17:44:02.825,24.790482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2173-2172,17:44:02.827,24.792457 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2174,17:44:02.828,24.792937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2175-2174,17:44:02.828,24.793458 s,521 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2176,17:44:02.828,24.793481 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2177-2176,17:44:02.830,24.795457 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2178,17:44:02.831,24.795938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2179-2178,17:44:02.831,24.796457 s,519 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2180,17:44:02.831,24.796479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2181-2180,17:44:02.832,24.797458 s,978 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2182,17:44:02.833,24.797937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2183-2182,17:44:02.833,24.798458 s,521 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2184,17:44:02.833,24.798487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2185-2184,17:44:02.835,24.800457 s,1.970 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2186,17:44:02.836,24.800937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2187-2186,17:44:02.836,24.801458 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2188,17:44:02.836,24.801480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2189-2188,17:44:02.838,24.803457 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2190,17:44:02.839,24.803937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2191-2190,17:44:02.839,24.804458 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2192,17:44:02.839,24.804480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2193-2192,17:44:02.840,24.805457 s,978 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2194,17:44:02.841,24.805937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2195-2194,17:44:02.841,24.806458 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2196,17:44:02.841,24.806480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2197-2196,17:44:02.843,24.808458 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2198,17:44:02.844,24.808938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2199-2198,17:44:02.844,24.809457 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2200,17:44:02.844,24.809480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2201-2200,17:44:02.846,24.811456 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2202,17:44:02.847,24.811937 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2203-2202,17:44:02.847,24.812457 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2204,17:44:02.847,24.812479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2205-2204,17:44:02.848,24.813457 s,978 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2206,17:44:02.849,24.813938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2207-2206,17:44:02.849,24.814457 s,519 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2208,17:44:02.849,24.814479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2209-2208,17:44:02.851,24.816457 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2210,17:44:02.852,24.816938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2211-2210,17:44:02.852,24.817457 s,519 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2212,17:44:02.852,24.817479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2213-2212,17:44:02.854,24.819457 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2214,17:44:02.855,24.819938 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2215-2214,17:44:02.855,24.820457 s,519 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2216,17:44:02.855,24.820479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2217-2216,17:44:02.856,24.821457 s,978 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2218,17:44:02.857,24.821945 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2219-2218,17:44:02.857,24.822457 s,512 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2220,17:44:02.857,24.822479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2221-2220,17:44:02.859,24.824457 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2222,17:44:02.860,24.824939 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2223-2222,17:44:02.860,24.825457 s,518 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2224,17:44:02.860,24.825480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2225-2224,17:44:02.862,24.827457 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2226,17:44:02.863,24.827939 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2227-2226,17:44:02.863,24.828457 s,518 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2228,17:44:02.863,24.828479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2229-2228,17:44:02.864,24.829471 s,992 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2230,17:44:02.865,24.829943 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2231-2230,17:44:02.865,24.830468 s,526 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2232,17:44:02.865,24.830494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2233-2232,17:44:02.867,24.832464 s,1.970 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2234,17:44:02.868,24.832941 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2235-2234,17:44:02.868,24.833463 s,522 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2236,17:44:02.868,24.833487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2237-2236,17:44:02.870,24.835464 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2238,17:44:02.871,24.835940 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2239-2238,17:44:02.871,24.836463 s,523 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2240,17:44:02.871,24.836487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2241-2240,17:44:02.873,24.838467 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2242,17:44:02.874,24.838942 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2243-2242,17:44:02.874,24.839464 s,522 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2244,17:44:02.874,24.839488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2245-2244,17:44:02.876,24.841464 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2246,17:44:02.877,24.841941 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2247-2246,17:44:02.877,24.842464 s,523 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2248,17:44:02.877,24.842487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2249-2248,17:44:02.879,24.844463 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2250,17:44:02.880,24.844942 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2251-2250,17:44:02.880,24.845464 s,522 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2252,17:44:02.880,24.845487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2253-2252,17:44:02.882,24.847464 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2254,17:44:02.883,24.847941 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2255-2254,17:44:02.883,24.848463 s,522 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2256,17:44:02.883,24.848487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2257-2256,17:44:02.885,24.850463 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2258,17:44:02.886,24.850944 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2259-2258,17:44:02.886,24.851463 s,518 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2260,17:44:02.886,24.851487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2261-2260,17:44:02.888,24.853464 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2262,17:44:02.889,24.853946 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2263-2262,17:44:02.889,24.854464 s,519 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2264,17:44:02.889,24.854489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2265-2264,17:44:02.891,24.856463 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2266,17:44:02.892,24.856943 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2267-2266,17:44:02.892,24.857463 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2268,17:44:02.892,24.857488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2269-2268,17:44:02.894,24.859463 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2270,17:44:02.895,24.859945 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2271-2270,17:44:02.895,24.860463 s,518 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2272,17:44:02.895,24.860487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2273-2272,17:44:02.897,24.862463 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2274,17:44:02.898,24.862942 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2275-2274,17:44:02.898,24.863463 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2276,17:44:02.898,24.863486 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2277-2276,17:44:02.900,24.865463 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2278,17:44:02.901,24.865942 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2279-2278,17:44:02.901,24.866463 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2280,17:44:02.901,24.866486 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2281-2280,17:44:02.903,24.868463 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2282,17:44:02.904,24.868945 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2283-2282,17:44:02.904,24.869466 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2284,17:44:02.904,24.869491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2285-2284,17:44:02.906,24.871465 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2286,17:44:02.907,24.871943 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2287-2286,17:44:02.907,24.872466 s,523 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2288,17:44:02.907,24.872489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2289-2288,17:44:02.909,24.874463 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2290,17:44:02.910,24.874943 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2291-2290,17:44:02.910,24.875463 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2292,17:44:02.910,24.875486 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2293-2292,17:44:02.912,24.877463 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2294,17:44:02.913,24.877943 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2295-2294,17:44:02.913,24.878463 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2296,17:44:02.913,24.878486 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2297-2296,17:44:02.915,24.880463 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2298,17:44:02.916,24.880943 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2299-2298,17:44:02.916,24.881462 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2300,17:44:02.916,24.881486 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2301-2300,17:44:02.918,24.883463 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2302,17:44:02.919,24.883942 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2303-2302,17:44:02.919,24.884508 s,566 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2304,17:44:02.919,24.884533 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2305-2304,17:44:02.921,24.886508 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2306,17:44:02.922,24.886959 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2307-2306,17:44:02.922,24.887468 s,509 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2308,17:44:02.922,24.887499 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2309-2308,17:44:02.924,24.889493 s,1.994 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2310,17:44:02.925,24.889959 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2311-2310,17:44:02.925,24.890469 s,509 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2312,17:44:02.925,24.890498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2313-2312,17:44:02.927,24.892498 s,2.000 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2314,17:44:02.928,24.892966 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2315-2314,17:44:02.928,24.893481 s,515 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2316,17:44:02.928,24.893517 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2317-2316,17:44:02.930,24.895471 s,1.953 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2318,17:44:02.931,24.895955 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2319-2318,17:44:02.931,24.896468 s,513 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2320,17:44:02.931,24.896498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2321-2320,17:44:02.933,24.898463 s,1.965 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2322,17:44:02.934,24.899023 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2323-2322,17:44:02.934,24.899463 s,440 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2324,17:44:02.934,24.899495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2325-2324,17:44:02.936,24.901462 s,1.967 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2326,17:44:02.937,24.901953 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2327-2326,17:44:02.937,24.902499 s,546 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2328,17:44:02.937,24.902545 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2329-2328,17:44:02.939,24.904556 s,2.011 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2330,17:44:02.940,24.904949 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2331-2330,17:44:02.940,24.905466 s,517 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2332,17:44:02.940,24.905494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2333-2332,17:44:02.942,24.907461 s,1.967 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2334,17:44:02.943,24.907946 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2335-2334,17:44:02.943,24.908461 s,515 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2336,17:44:02.943,24.908486 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2337-2336,17:44:02.945,24.910463 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2338,17:44:02.946,24.910959 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2339-2338,17:44:02.946,24.911462 s,503 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2340,17:44:02.946,24.911491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2341-2340,17:44:02.948,24.913462 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2342,17:44:02.949,24.913948 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2343-2342,17:44:02.949,24.914462 s,514 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2344,17:44:02.949,24.914486 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2345-2344,17:44:02.951,24.916462 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2346,17:44:02.952,24.916946 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2347-2346,17:44:02.952,24.917464 s,518 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2348,17:44:02.952,24.917489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2349-2348,17:44:02.954,24.919462 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2350,17:44:02.955,24.919946 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2351-2350,17:44:02.955,24.920463 s,517 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2352,17:44:02.955,24.920487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2353-2352,17:44:02.957,24.922462 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2354,17:44:02.958,24.922951 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2355-2354,17:44:02.958,24.923464 s,513 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2356,17:44:02.958,24.923488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2357-2356,17:44:02.960,24.925461 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2358,17:44:02.961,24.925946 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2359-2358,17:44:02.961,24.926465 s,519 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2360,17:44:02.961,24.926489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2361-2360,17:44:02.963,24.928461 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2362,17:44:02.964,24.928949 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2363-2362,17:44:02.964,24.929469 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2364,17:44:02.964,24.929496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2365-2364,17:44:02.966,24.931462 s,1.965 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2366,17:44:02.967,24.931947 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2367-2366,17:44:02.967,24.932461 s,515 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2368,17:44:02.967,24.932487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2369-2368,17:44:02.969,24.934462 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2370,17:44:02.970,24.934947 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2371-2370,17:44:02.970,24.935462 s,516 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2372,17:44:02.970,24.935487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2373-2372,17:44:02.972,24.937473 s,1.986 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2374,17:44:02.973,24.938041 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2375-2374,17:44:02.973,24.938475 s,434 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2376,17:44:02.973,24.938541 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2377-2376,17:44:02.975,24.940483 s,1.942 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2378,17:44:02.976,24.941008 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2379-2378,17:44:02.976,24.941483 s,475 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2380,17:44:02.976,24.941540 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2381-2380,17:44:02.978,24.943485 s,1.945 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2382,17:44:02.979,24.943980 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2383-2382,17:44:02.979,24.944464 s,484 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2384,17:44:02.979,24.944496 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2385-2384,17:44:02.981,24.946472 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2386,17:44:02.982,24.946974 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2387-2386,17:44:02.982,24.947470 s,496 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2388,17:44:02.982,24.947518 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2389-2388,17:44:02.984,24.949461 s,1.944 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2390,17:44:02.985,24.949987 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2391-2390,17:44:02.985,24.950462 s,475 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2392,17:44:02.985,24.950491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2393-2392,17:44:02.987,24.952462 s,1.971 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2394,17:44:02.988,24.952952 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2395-2394,17:44:02.988,24.953461 s,510 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2396,17:44:02.988,24.953488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2397-2396,17:44:02.990,24.955468 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2398,17:44:02.991,24.956003 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2399-2398,17:44:02.991,24.956462 s,459 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2400,17:44:02.991,24.956494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2401-2400,17:44:02.993,24.958459 s,1.965 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2402,17:44:02.994,24.958944 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2403-2402,17:44:02.994,24.959458 s,513 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2404,17:44:02.994,24.959481 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2405-2404,17:44:02.996,24.961477 s,1.996 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2406,17:44:02.997,24.962161 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096E4160h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2407-2406,17:44:02.997,24.962468 s,308 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096E4160h,Success (Success) -URB,2408,17:44:02.997,24.962638 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2409-2408,17:44:02.999,24.964468 s,1.830 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2410,17:44:03.000,24.964956 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2411-2410,17:44:03.000,24.965487 s,531 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2412,17:44:03.000,24.965525 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2413-2412,17:44:03.002,24.967484 s,1.959 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2414,17:44:03.003,24.967949 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2415-2414,17:44:03.003,24.968469 s,520 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2416,17:44:03.003,24.968497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2417-2416,17:44:03.005,24.970464 s,1.967 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2418,17:44:03.006,24.970950 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2419-2418,17:44:03.006,24.971462 s,511 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2420,17:44:03.006,24.971488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2421-2420,17:44:03.008,24.973462 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2422,17:44:03.009,24.973947 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2423-2422,17:44:03.009,24.974461 s,514 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2424,17:44:03.009,24.974486 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2425-2424,17:44:03.011,24.976462 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2426,17:44:03.012,24.976947 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2427-2426,17:44:03.012,24.977461 s,515 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2428,17:44:03.012,24.977485 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2429-2428,17:44:03.014,24.979475 s,1.990 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2430,17:44:03.015,24.979996 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2431-2430,17:44:03.015,24.980474 s,478 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2432,17:44:03.015,24.980708 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2433-2432,17:44:03.017,24.982459 s,1.751 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2434,17:44:03.018,24.982953 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2435-2434,17:44:03.018,24.983462 s,509 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2436,17:44:03.018,24.983486 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2437-2436,17:44:03.020,24.985461 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2438,17:44:03.021,24.985947 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2439-2438,17:44:03.021,24.986460 s,513 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2440,17:44:03.021,24.986484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2441-2440,17:44:03.023,24.988461 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2442,17:44:03.024,24.988950 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2443-2442,17:44:03.024,24.989460 s,511 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2444,17:44:03.024,24.989485 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2445-2444,17:44:03.026,24.991461 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2446,17:44:03.027,24.991947 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2447-2446,17:44:03.027,24.992461 s,514 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2448,17:44:03.027,24.992484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2449-2448,17:44:03.029,24.994467 s,1.983 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2450,17:44:03.030,24.994956 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2451-2450,17:44:03.030,24.995461 s,505 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2452,17:44:03.030,24.995488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2453-2452,17:44:03.032,24.997459 s,1.971 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2454,17:44:03.033,24.997953 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2455-2454,17:44:03.033,24.998461 s,509 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2456,17:44:03.033,24.998485 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2457-2456,17:44:03.035,25.000461 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2458,17:44:03.036,25.000949 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2459-2458,17:44:03.036,25.001472 s,523 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2460,17:44:03.036,25.001502 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2461-2460,17:44:03.038,25.003463 s,1.961 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2462,17:44:03.039,25.003954 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2463-2462,17:44:03.039,25.004465 s,512 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2464,17:44:03.039,25.004495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2465-2464,17:44:03.041,25.006472 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2466,17:44:03.042,25.007032 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2467-2466,17:44:03.042,25.007461 s,428 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2468,17:44:03.042,25.007495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2469-2468,17:44:03.044,25.009462 s,1.967 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2470,17:44:03.045,25.009969 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2471-2470,17:44:03.045,25.010462 s,492 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2472,17:44:03.045,25.010491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2473-2472,17:44:03.047,25.012459 s,1.969 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2474,17:44:03.048,25.012950 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2475-2474,17:44:03.048,25.013460 s,509 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2476,17:44:03.048,25.013485 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2477-2476,17:44:03.050,25.015464 s,1.979 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2478,17:44:03.051,25.015967 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2479-2478,17:44:03.051,25.016460 s,494 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2480,17:44:03.051,25.016487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2481-2480,17:44:03.053,25.018462 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2482,17:44:03.054,25.018950 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2483-2482,17:44:03.054,25.019459 s,509 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2484,17:44:03.054,25.019484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2485-2484,17:44:03.056,25.021460 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2486,17:44:03.057,25.021951 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2487-2486,17:44:03.057,25.022460 s,509 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2488,17:44:03.057,25.022485 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2489-2488,17:44:03.059,25.024461 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2490,17:44:03.060,25.024963 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2491-2490,17:44:03.060,25.025461 s,498 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2492,17:44:03.060,25.025489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2493-2492,17:44:03.062,25.027460 s,1.970 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2494,17:44:03.063,25.027950 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2495-2494,17:44:03.063,25.028460 s,510 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2496,17:44:03.063,25.028485 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2497-2496,17:44:03.065,25.030460 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2498,17:44:03.066,25.030962 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2499-2498,17:44:03.066,25.031460 s,498 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2500,17:44:03.066,25.031488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2501-2500,17:44:03.068,25.033460 s,1.971 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2502,17:44:03.069,25.033953 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2503-2502,17:44:03.069,25.034459 s,506 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2504,17:44:03.069,25.034484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2505-2504,17:44:03.071,25.036459 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2506,17:44:03.072,25.036950 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2507-2506,17:44:03.072,25.037460 s,510 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2508,17:44:03.072,25.037485 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2509-2508,17:44:03.074,25.039466 s,1.981 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2510,17:44:03.075,25.039951 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2511-2510,17:44:03.075,25.040463 s,512 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2512,17:44:03.075,25.040489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2513-2512,17:44:03.077,25.042464 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2514,17:44:03.078,25.042954 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2515-2514,17:44:03.078,25.043464 s,510 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2516,17:44:03.078,25.043493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2517-2516,17:44:03.080,25.045471 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2518,17:44:03.081,25.045956 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2519-2518,17:44:03.081,25.046482 s,526 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2520,17:44:03.081,25.046520 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2521-2520,17:44:03.083,25.048513 s,1.993 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2522,17:44:03.084,25.048960 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2523-2522,17:44:03.084,25.049488 s,528 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2524,17:44:03.084,25.049533 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2525-2524,17:44:03.086,25.051467 s,1.933 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2526,17:44:03.087,25.051951 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2527-2526,17:44:03.087,25.052461 s,509 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2528,17:44:03.087,25.052486 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2529-2528,17:44:03.089,25.054461 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2530,17:44:03.090,25.054950 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2531-2530,17:44:03.090,25.055460 s,510 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2532,17:44:03.090,25.055484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2533-2532,17:44:03.092,25.057459 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2534,17:44:03.093,25.057950 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2535-2534,17:44:03.093,25.058460 s,510 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2536,17:44:03.093,25.058484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2537-2536,17:44:03.095,25.060459 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2538,17:44:03.096,25.060950 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2539-2538,17:44:03.096,25.061460 s,511 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2540,17:44:03.096,25.061484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2541-2540,17:44:03.098,25.063462 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2542,17:44:03.099,25.063950 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2543-2542,17:44:03.099,25.064459 s,509 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2544,17:44:03.099,25.064483 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2545-2544,17:44:03.101,25.066470 s,1.987 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2546,17:44:03.102,25.067003 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2547-2546,17:44:03.102,25.067459 s,456 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80089DFC60h,Success (Success) -URB,2548,17:44:03.102,25.067490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2549-2548,17:44:03.104,25.069485 s,1.995 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2550,17:44:03.105,25.070003 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2551-2550,17:44:03.105,25.070458 s,454 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2552,17:44:03.105,25.070489 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2553-2552,17:44:03.107,25.072462 s,1.973 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2554,17:44:03.108,25.072954 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2555-2554,17:44:03.108,25.073459 s,505 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2556,17:44:03.108,25.073484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2557-2556,17:44:03.110,25.075458 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2558,17:44:03.111,25.075950 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2559-2558,17:44:03.111,25.076458 s,508 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2560,17:44:03.111,25.076483 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2561-2560,17:44:03.113,25.078459 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2562,17:44:03.114,25.078952 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2563-2562,17:44:03.114,25.079459 s,507 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2564,17:44:03.114,25.079483 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2565-2564,17:44:03.116,25.081459 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2566,17:44:03.117,25.081950 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2567-2566,17:44:03.117,25.082458 s,509 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2568,17:44:03.117,25.082482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2569-2568,17:44:03.119,25.084459 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2570,17:44:03.120,25.084952 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2571-2570,17:44:03.120,25.085459 s,507 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2572,17:44:03.120,25.085483 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2573-2572,17:44:03.122,25.087460 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2574,17:44:03.123,25.087951 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2575-2574,17:44:03.123,25.088459 s,508 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2576,17:44:03.123,25.088483 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2577-2576,17:44:03.125,25.090459 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2578,17:44:03.126,25.090954 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2579-2578,17:44:03.126,25.091458 s,504 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2580,17:44:03.126,25.091483 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2581-2580,17:44:03.128,25.093459 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2582,17:44:03.129,25.093951 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2583-2582,17:44:03.129,25.094459 s,507 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2584,17:44:03.129,25.094482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2585-2584,17:44:03.131,25.096459 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2586,17:44:03.132,25.096951 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2587-2586,17:44:03.132,25.097458 s,508 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2588,17:44:03.132,25.097482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2589-2588,17:44:03.134,25.099459 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2590,17:44:03.135,25.099954 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2591-2590,17:44:03.135,25.100470 s,516 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2592,17:44:03.135,25.100505 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2593-2592,17:44:03.137,25.102463 s,1.958 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2594,17:44:03.138,25.102964 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2595-2594,17:44:03.138,25.103458 s,494 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2596,17:44:03.138,25.103484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2597-2596,17:44:03.140,25.105459 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2598,17:44:03.141,25.105951 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2599-2598,17:44:03.141,25.106459 s,508 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2600,17:44:03.141,25.106483 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2601-2600,17:44:03.143,25.108458 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2602,17:44:03.144,25.108955 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2603-2602,17:44:03.144,25.109458 s,503 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2604,17:44:03.144,25.109482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2605-2604,17:44:03.146,25.111458 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2606,17:44:03.147,25.111952 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2607-2606,17:44:03.147,25.112458 s,506 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2608,17:44:03.147,25.112482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2609-2608,17:44:03.149,25.114462 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2610,17:44:03.150,25.114952 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2611-2610,17:44:03.150,25.115458 s,506 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2612,17:44:03.150,25.115481 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2613-2612,17:44:03.152,25.117461 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2614,17:44:03.153,25.117960 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2615-2614,17:44:03.153,25.118459 s,500 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2616,17:44:03.153,25.118486 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2617-2616,17:44:03.155,25.120458 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2618,17:44:03.156,25.120953 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2619-2618,17:44:03.156,25.121459 s,506 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2620,17:44:03.156,25.121482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2621-2620,17:44:03.158,25.123457 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2622,17:44:03.159,25.123952 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2623-2622,17:44:03.159,25.124457 s,505 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2624,17:44:03.159,25.124481 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2625-2624,17:44:03.161,25.126458 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2626,17:44:03.162,25.126952 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2627-2626,17:44:03.162,25.127458 s,506 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2628,17:44:03.162,25.127481 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2629-2628,17:44:03.164,25.129458 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2630,17:44:03.165,25.129955 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2631-2630,17:44:03.165,25.130458 s,502 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2632,17:44:03.165,25.130482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2633-2632,17:44:03.167,25.132458 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2634,17:44:03.168,25.132953 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2635-2634,17:44:03.168,25.133458 s,505 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2636,17:44:03.168,25.133482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2637-2636,17:44:03.170,25.135458 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2638,17:44:03.171,25.135953 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2639-2638,17:44:03.171,25.136458 s,506 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2640,17:44:03.171,25.136482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2641-2640,17:44:03.173,25.138458 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2642,17:44:03.174,25.138957 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2643-2642,17:44:03.174,25.139458 s,501 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2644,17:44:03.174,25.139482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2645-2644,17:44:03.176,25.141457 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2646,17:44:03.177,25.141953 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2647-2646,17:44:03.177,25.142457 s,505 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2648,17:44:03.177,25.142481 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2649-2648,17:44:03.179,25.144459 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2650,17:44:03.180,25.144952 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2651-2650,17:44:03.180,25.145457 s,505 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2652,17:44:03.180,25.145481 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2653-2652,17:44:03.182,25.147457 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2654,17:44:03.183,25.147953 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2655-2654,17:44:03.183,25.148460 s,507 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2656,17:44:03.183,25.148484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2657-2656,17:44:03.185,25.150458 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2658,17:44:03.186,25.150956 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2659-2658,17:44:03.186,25.151458 s,502 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2660,17:44:03.186,25.151482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2661-2660,17:44:03.188,25.153457 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2662,17:44:03.189,25.153953 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2663-2662,17:44:03.189,25.154457 s,504 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2664,17:44:03.189,25.154482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2665-2664,17:44:03.191,25.156457 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2666,17:44:03.192,25.156953 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2667-2666,17:44:03.192,25.157457 s,503 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2668,17:44:03.192,25.157480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2669-2668,17:44:03.194,25.159457 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2670,17:44:03.195,25.159953 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2671-2670,17:44:03.195,25.160457 s,504 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2672,17:44:03.195,25.160480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2673-2672,17:44:03.197,25.162460 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2674,17:44:03.198,25.162953 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2675-2674,17:44:03.198,25.163457 s,503 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2676,17:44:03.198,25.163480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2677-2676,17:44:03.200,25.165457 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2678,17:44:03.201,25.165953 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2679-2678,17:44:03.201,25.166457 s,504 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2680,17:44:03.201,25.166481 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2681-2680,17:44:03.203,25.168457 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2682,17:44:03.204,25.168956 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2683-2682,17:44:03.204,25.169458 s,502 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2684,17:44:03.204,25.169482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2685-2684,17:44:03.206,25.171457 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2686,17:44:03.207,25.171955 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2687-2686,17:44:03.207,25.172456 s,501 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2688,17:44:03.207,25.172480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2689-2688,17:44:03.209,25.174458 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2690,17:44:03.210,25.174954 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2691-2690,17:44:03.210,25.175457 s,503 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2692,17:44:03.210,25.175482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2693-2692,17:44:03.212,25.177458 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2694,17:44:03.213,25.177957 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2695-2694,17:44:03.213,25.178458 s,501 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2696,17:44:03.213,25.178481 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2697-2696,17:44:03.215,25.180459 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2698,17:44:03.216,25.180956 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2699-2698,17:44:03.216,25.181457 s,501 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2700,17:44:03.216,25.181481 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2701-2700,17:44:03.218,25.183457 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2702,17:44:03.219,25.183955 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2703-2702,17:44:03.219,25.184457 s,503 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2704,17:44:03.219,25.184481 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2705-2704,17:44:03.221,25.186457 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2706,17:44:03.222,25.186954 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2707-2706,17:44:03.222,25.187456 s,502 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2708,17:44:03.222,25.187480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2709-2708,17:44:03.224,25.189457 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2710,17:44:03.225,25.189958 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2711-2710,17:44:03.225,25.190456 s,498 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2712,17:44:03.225,25.190481 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2713-2712,17:44:03.227,25.192457 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2714,17:44:03.228,25.192955 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2715-2714,17:44:03.228,25.193456 s,501 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2716,17:44:03.228,25.193480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2717-2716,17:44:03.230,25.195456 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2718,17:44:03.231,25.195955 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2719-2718,17:44:03.231,25.196459 s,504 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2720,17:44:03.231,25.196483 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2721-2720,17:44:03.233,25.198457 s,1.974 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2722,17:44:03.234,25.198955 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2723-2722,17:44:03.234,25.199457 s,502 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2724,17:44:03.234,25.199481 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2725-2724,17:44:03.236,25.201456 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2726,17:44:03.237,25.201954 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2727-2726,17:44:03.237,25.202456 s,502 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2728,17:44:03.237,25.202481 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2729-2728,17:44:03.239,25.204456 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2730,17:44:03.240,25.204956 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2731-2730,17:44:03.240,25.205456 s,500 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2732,17:44:03.240,25.205479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2733-2732,17:44:03.242,25.207457 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2734,17:44:03.243,25.207955 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2735-2734,17:44:03.243,25.208456 s,501 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2736,17:44:03.243,25.208479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2737-2736,17:44:03.245,25.210459 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2738,17:44:03.246,25.210958 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2739-2738,17:44:03.246,25.211456 s,498 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2740,17:44:03.246,25.211480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2741-2740,17:44:03.248,25.213456 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2742,17:44:03.249,25.213955 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2743-2742,17:44:03.249,25.214457 s,502 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2744,17:44:03.249,25.214480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2745-2744,17:44:03.251,25.216456 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2746,17:44:03.252,25.216957 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2747-2746,17:44:03.252,25.217456 s,499 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2748,17:44:03.252,25.217480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2749-2748,17:44:03.254,25.219456 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2750,17:44:03.255,25.219955 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2751-2750,17:44:03.255,25.220455 s,500 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2752,17:44:03.255,25.220479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2753-2752,17:44:03.257,25.222457 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2754,17:44:03.258,25.222957 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2755-2754,17:44:03.258,25.223456 s,498 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2756,17:44:03.258,25.223479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2757-2756,17:44:03.260,25.225457 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2758,17:44:03.261,25.225955 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2759-2758,17:44:03.261,25.226456 s,500 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2760,17:44:03.261,25.226479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2761-2760,17:44:03.263,25.228456 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2762,17:44:03.264,25.228957 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2763-2762,17:44:03.264,25.229456 s,500 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2764,17:44:03.264,25.229480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2765-2764,17:44:03.266,25.231456 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2766,17:44:03.267,25.231956 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2767-2766,17:44:03.267,25.232494 s,538 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2768,17:44:03.267,25.232518 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2769-2768,17:44:03.269,25.234456 s,1.938 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2770,17:44:03.270,25.234955 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2771-2770,17:44:03.270,25.235455 s,500 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2772,17:44:03.270,25.235478 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2773-2772,17:44:03.272,25.237456 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2774,17:44:03.273,25.237956 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2775-2774,17:44:03.273,25.238456 s,500 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2776,17:44:03.273,25.238479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2777-2776,17:44:03.275,25.240457 s,1.978 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2778,17:44:03.276,25.240956 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2779-2778,17:44:03.276,25.241456 s,500 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2780,17:44:03.276,25.241479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2781-2780,17:44:03.278,25.243459 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2782,17:44:03.279,25.243965 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2783-2782,17:44:03.279,25.244458 s,492 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2784,17:44:03.279,25.244483 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2785-2784,17:44:03.281,25.246455 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2786,17:44:03.282,25.246957 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2787-2786,17:44:03.282,25.247456 s,500 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2788,17:44:03.282,25.247480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2789-2788,17:44:03.284,25.249456 s,1.976 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2790,17:44:03.285,25.249961 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2791-2790,17:44:03.285,25.250455 s,494 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2792,17:44:03.285,25.250480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2793-2792,17:44:03.287,25.252455 s,1.975 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2794,17:44:03.288,25.252957 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2795-2794,17:44:03.288,25.253455 s,498 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2796,17:44:03.288,25.253479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2797-2796,17:44:03.290,25.255456 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2798,17:44:03.291,25.255961 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2799-2798,17:44:03.291,25.256455 s,495 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2800,17:44:03.291,25.256479 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2801-2800,17:44:03.293,25.258459 s,1.979 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2802,17:44:03.493,25.457998 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2803-2802,17:44:03.494,25.459467 s,1.469 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2804,17:44:03.494,25.459504 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2805-2804,17:44:03.496,25.461453 s,1.949 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2806,17:44:03.696,25.661009 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2807-2806,17:44:03.696,25.661459 s,450 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2808,17:44:03.696,25.661497 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2809-2808,17:44:03.698,25.663451 s,1.954 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2810,17:44:03.898,25.863006 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2811-2810,17:44:03.899,25.864456 s,1.450 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2812,17:44:03.899,25.864490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2813-2812,17:44:03.901,25.866445 s,1.955 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2814,17:44:04.101,26.066042 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2815-2814,17:44:04.102,26.067440 s,1.397 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2816,17:44:04.102,26.067484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2817-2816,17:44:04.104,26.069440 s,1.957 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2818,17:44:04.304,26.269024 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2819-2818,17:44:04.305,26.270456 s,1.432 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2820,17:44:04.305,26.270494 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2821-2820,17:44:04.307,26.272438 s,1.944 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2822,17:44:04.507,26.472043 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2823-2822,17:44:04.508,26.473433 s,1.390 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2824,17:44:04.508,26.473470 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2825-2824,17:44:04.510,26.475432 s,1.962 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2826,17:44:04.710,26.675053 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2827-2826,17:44:04.711,26.676426 s,1.373 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2828,17:44:04.711,26.676465 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2829-2828,17:44:04.713,26.678449 s,1.984 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2830,17:44:04.913,26.878041 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2831-2830,17:44:04.914,26.879423 s,1.382 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2832,17:44:04.914,26.879458 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2833-2832,17:44:04.916,26.881424 s,1.966 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2834,17:44:05.116,27.081075 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2835-2834,17:44:05.117,27.082449 s,1.373 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2836,17:44:05.117,27.082493 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2837-2836,17:44:05.119,27.084422 s,1.929 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2838,17:44:05.319,27.284059 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2839-2838,17:44:05.319,27.284430 s,371 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2840,17:44:05.319,27.284465 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2841-2840,17:44:05.321,27.286417 s,1.952 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2842,17:44:05.521,27.486126 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2843-2842,17:44:05.522,27.487435 s,1.309 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2844,17:44:05.522,27.487488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2845-2844,17:44:05.524,27.489414 s,1.926 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2846,17:44:05.724,27.689111 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2847-2846,17:44:05.725,27.690425 s,1.314 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2848,17:44:05.725,27.690467 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2849-2848,17:44:05.727,27.692411 s,1.944 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2850,17:44:05.927,27.892084 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2851-2850,17:44:05.928,27.893411 s,1.327 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2852,17:44:05.928,27.893445 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2853-2852,17:44:05.930,27.895406 s,1.961 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2854,17:44:06.131,28.095131 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2855-2854,17:44:06.132,28.096402 s,1.271 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2856,17:44:06.132,28.096451 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2857-2856,17:44:06.134,28.098399 s,1.949 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2858,17:44:06.334,28.298115 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2859-2858,17:44:06.335,28.299412 s,1.297 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2860,17:44:06.335,28.299450 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2861-2860,17:44:06.337,28.301397 s,1.946 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2862,17:44:06.537,28.501282 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2863-2862,17:44:06.538,28.502510 s,1.228 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2864,17:44:06.538,28.502566 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2865-2864,17:44:06.540,28.504400 s,1.834 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2866,17:44:06.740,28.704127 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2867-2866,17:44:06.741,28.705415 s,1.288 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2868,17:44:06.741,28.705457 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2869-2868,17:44:06.743,28.707391 s,1.934 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2870,17:44:06.943,28.907119 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2871-2870,17:44:06.944,28.908393 s,1.273 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2872,17:44:06.944,28.908424 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2873-2872,17:44:06.946,28.910386 s,1.962 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2874,17:44:07.146,29.110143 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2875-2874,17:44:07.147,29.111401 s,1.257 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2876,17:44:07.147,29.111438 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2877-2876,17:44:07.149,29.113382 s,1.944 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2878,17:44:07.349,29.313134 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2879-2878,17:44:07.350,29.314382 s,1.248 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2880,17:44:07.350,29.314413 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2881-2880,17:44:07.352,29.316383 s,1.970 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2882,17:44:07.552,29.516148 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2883-2882,17:44:07.552,29.516414 s,266 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2884,17:44:07.552,29.516463 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2885-2884,17:44:07.554,29.518450 s,1.987 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2886,17:44:07.754,29.718162 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2887-2886,17:44:07.755,29.719393 s,1.231 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008618A00h,Success (Success) -URB,2888,17:44:07.755,29.719435 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2889-2888,17:44:07.757,29.721372 s,1.937 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2890,17:44:07.957,29.921162 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2891-2890,17:44:07.958,29.922380 s,1.217 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,Success (Success) -URB,2892,17:44:07.958,29.922416 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2893-2892,17:44:07.960,29.924364 s,1.948 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2894,17:44:08.160,30.124182 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80090A2240h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2895-2894,17:44:08.160,30.124382 s,200 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80090A2240h,Success (Success) -URB,2896,17:44:08.160,30.124421 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2897-2896,17:44:08.162,30.126362 s,1.941 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2898,17:44:08.362,30.326171 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80090A2240h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2899-2898,17:44:08.363,30.327364 s,1.193 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80090A2240h,Success (Success) -URB,2900,17:44:08.363,30.327396 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2901-2900,17:44:08.365,30.329357 s,1.961 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2902,17:44:08.565,30.529243 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80090A2240h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2903-2902,17:44:08.566,30.530370 s,1.128 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80090A2240h,Success (Success) -URB,2904,17:44:08.566,30.530416 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2905-2904,17:44:08.568,30.532354 s,1.939 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2906,17:44:08.768,30.732226 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2907-2906,17:44:08.769,30.733354 s,1.128 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,2908,17:44:08.769,30.733390 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2909-2908,17:44:08.771,30.735349 s,1.959 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2910,17:44:08.971,30.935204 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2911-2910,17:44:08.972,30.936358 s,1.153 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,2912,17:44:08.972,30.936394 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2913-2912,17:44:08.974,30.938344 s,1.951 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2914,17:44:09.174,31.138386 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2915-2914,17:44:09.176,31.140614 s,2.228 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2916,17:44:09.176,31.141138 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2917-2916,17:44:09.178,31.142377 s,1.239 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2918,17:44:09.378,31.342234 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2919-2918,17:44:09.379,31.343364 s,1.130 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2920,17:44:09.379,31.343409 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2921-2920,17:44:09.381,31.345338 s,1.929 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2922,17:44:09.581,31.545238 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2923-2922,17:44:09.582,31.546405 s,1.167 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2924,17:44:09.582,31.546476 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2925-2924,17:44:09.584,31.548397 s,1.921 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2926,17:44:09.784,31.748253 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2927-2926,17:44:09.785,31.749373 s,1.120 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2928,17:44:09.785,31.749432 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2929-2928,17:44:09.787,31.751333 s,1.901 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2930,17:44:09.987,31.951274 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2931-2930,17:44:09.989,31.953326 s,2.052 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2932,17:44:09.989,31.953367 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2933-2932,17:44:09.991,31.955325 s,1.958 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2934,17:44:10.191,32.155260 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2935-2934,17:44:10.192,32.156329 s,1.070 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2936,17:44:10.192,32.156369 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2937-2936,17:44:10.194,32.158322 s,1.953 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2938,17:44:10.394,32.358247 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2939-2938,17:44:10.395,32.359313 s,1.066 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2940,17:44:10.395,32.359348 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2941-2940,17:44:10.397,32.361314 s,1.966 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2942,17:44:10.597,32.561287 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2943-2942,17:44:10.599,32.563314 s,2.027 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2944,17:44:10.599,32.563356 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2945-2944,17:44:10.601,32.565313 s,1.956 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2946,17:44:10.801,32.765267 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2947-2946,17:44:10.802,32.766328 s,1.061 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2948,17:44:10.802,32.766362 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2949-2948,17:44:10.804,32.768308 s,1.946 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2950,17:44:11.004,32.968270 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2951-2950,17:44:11.006,32.970303 s,2.033 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2952,17:44:11.006,32.970338 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2953-2952,17:44:11.008,32.972304 s,1.966 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2954,17:44:11.208,33.172295 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2955-2954,17:44:11.210,33.174324 s,2.029 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2956,17:44:11.210,33.174368 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2957-2956,17:44:11.212,33.176304 s,1.936 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2958,17:44:11.412,33.376288 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2959-2958,17:44:11.414,33.378296 s,2.008 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2960,17:44:11.414,33.378329 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2961-2960,17:44:11.416,33.380306 s,1.977 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2962,17:44:11.616,33.580321 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2963-2962,17:44:11.618,33.582321 s,2.000 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2964,17:44:11.618,33.582364 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2965-2964,17:44:11.620,33.584295 s,1.931 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2966,17:44:11.820,33.784305 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2967-2966,17:44:11.822,33.786293 s,1.988 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2968,17:44:11.822,33.786326 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2969-2968,17:44:11.824,33.788296 s,1.970 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2970,17:44:12.024,33.988313 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2971-2970,17:44:12.026,33.990287 s,1.974 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2972,17:44:12.026,33.990323 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2973-2972,17:44:12.028,33.992287 s,1.964 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2974,17:44:12.228,34.192334 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2975-2974,17:44:12.230,34.194289 s,1.955 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2976,17:44:12.230,34.194328 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2977-2976,17:44:12.232,34.196282 s,1.954 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2978,17:44:12.432,34.396337 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2979-2978,17:44:12.433,34.398278 s,1.941 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2980,17:44:12.434,34.398314 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2981-2980,17:44:12.435,34.400277 s,1.962 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2982,17:44:12.636,34.600355 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2983-2982,17:44:12.637,34.602271 s,1.917 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2984,17:44:12.638,34.602318 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2985-2984,17:44:12.639,34.604272 s,1.954 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2986,17:44:12.840,34.804346 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2987-2986,17:44:12.841,34.806287 s,1.941 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2988,17:44:12.842,34.806326 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2989-2988,17:44:12.843,34.808271 s,1.945 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2990,17:44:13.043,35.007405 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2991-2990,17:44:13.044,35.009268 s,1.863 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008C93820h,Success (Success) -URB,2992,17:44:13.045,35.009318 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2993-2992,17:44:13.046,35.011270 s,1.952 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2994,17:44:13.247,35.211376 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2995-2994,17:44:13.248,35.213259 s,1.883 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,2996,17:44:13.248,35.213297 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,2997-2996,17:44:13.249,35.214282 s,985 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,2998,17:44:13.449,35.413373 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,2999-2998,17:44:13.450,35.415252 s,1.879 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,3000,17:44:13.450,35.415287 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3001-3000,17:44:13.452,35.417254 s,1.967 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3002,17:44:13.652,35.616388 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3003-3002,17:44:13.653,35.618251 s,1.864 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,3004,17:44:13.653,35.618291 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3005-3004,17:44:13.655,35.620252 s,1.961 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3006,17:44:13.855,35.819381 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3007-3006,17:44:13.856,35.821251 s,1.869 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,3008,17:44:13.856,35.821283 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3009-3008,17:44:13.858,35.823249 s,1.966 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3010,17:44:14.058,36.022442 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3011-3010,17:44:14.059,36.024267 s,1.826 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,3012,17:44:14.059,36.024319 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3013-3012,17:44:14.061,36.026260 s,1.941 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3014,17:44:14.261,36.225411 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3015-3014,17:44:14.262,36.227242 s,1.831 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,3016,17:44:14.262,36.227285 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3017-3016,17:44:14.264,36.229241 s,1.955 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3018,17:44:14.464,36.428427 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3019-3018,17:44:14.465,36.430249 s,1.822 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,3020,17:44:14.465,36.430285 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3021-3020,17:44:14.467,36.432237 s,1.952 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3022,17:44:14.667,36.631483 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3023-3022,17:44:14.668,36.633340 s,1.857 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA800897DB00h,Success (Success) -URB,3024,17:44:14.669,36.633598 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3025-3024,17:44:14.670,36.635238 s,1.640 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3026,17:44:14.870,36.834453 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3027-3026,17:44:14.871,36.836267 s,1.814 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,Success (Success) -URB,3028,17:44:14.871,36.836320 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3029-3028,17:44:14.873,36.838287 s,1.968 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3030,17:44:15.073,37.037457 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3031-3030,17:44:15.074,37.039228 s,1.772 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,Success (Success) -URB,3032,17:44:15.074,37.039285 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3033-3032,17:44:15.076,37.041226 s,1.942 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3034,17:44:15.276,37.240460 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3035-3034,17:44:15.277,37.242230 s,1.770 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,Success (Success) -URB,3036,17:44:15.277,37.242280 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3037-3036,17:44:15.279,37.244225 s,1.945 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3038,17:44:15.479,37.443460 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3039-3038,17:44:15.480,37.445219 s,1.759 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,Success (Success) -URB,3040,17:44:15.480,37.445264 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3041-3040,17:44:15.482,37.447218 s,1.954 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3042,17:44:15.682,37.646461 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3043-3042,17:44:15.683,37.648213 s,1.752 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,Success (Success) -URB,3044,17:44:15.683,37.648253 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3045-3044,17:44:15.685,37.650214 s,1.961 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3046,17:44:15.885,37.849462 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3047-3046,17:44:15.886,37.851209 s,1.746 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,Success (Success) -URB,3048,17:44:15.886,37.851247 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3049-3048,17:44:15.888,37.853208 s,1.962 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3050,17:44:16.088,38.052541 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3051-3050,17:44:16.089,38.054228 s,1.688 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,Success (Success) -URB,3052,17:44:16.089,38.054373 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3053-3052,17:44:16.091,38.056220 s,1.847 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3054,17:44:16.291,38.255483 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3055-3054,17:44:16.292,38.257199 s,1.717 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,Success (Success) -URB,3056,17:44:16.292,38.257234 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3057-3056,17:44:16.294,38.259200 s,1.966 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3058,17:44:16.494,38.458488 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3059-3058,17:44:16.495,38.460196 s,1.708 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,Success (Success) -URB,3060,17:44:16.495,38.460231 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3061-3060,17:44:16.497,38.462220 s,1.989 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3062,17:44:16.697,38.661501 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3063-3062,17:44:16.698,38.663191 s,1.690 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,Success (Success) -URB,3064,17:44:16.698,38.663232 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3065-3064,17:44:16.700,38.665190 s,1.958 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 -URB,3066,17:44:16.900,38.864494 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,3067-3066,17:44:16.901,38.866188 s,1.694 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008435C60h,Success (Success) -URB,3068,17:44:16.901,38.866223 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,3069-3068,17:44:16.903,38.868189 s,1.966 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 01 00 01 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 01 00 01 01 - -This report was generated by USBlyzer http://www.usblyzer.com/ diff --git a/toremove/stm32l_notes/notes b/toremove/stm32l_notes/notes deleted file mode 100644 index 242371e79..000000000 --- a/toremove/stm32l_notes/notes +++ /dev/null @@ -1,15 +0,0 @@ -. tools used for reversing under windows (all free or eval version) - . ST set tools package contains a working programmer (stvp) - . http://www.st.com/internet/com/SOFTWARE_RESOURCES/TOOL/TOOLSET/sttoolset.zip - . IAR latest version contains a working debugger - . http://www.iar.com/website1/1.0.1.0/68/1/ - . usblyzer to snif the corresponding usb frames - . http://www.usblyzer.com/ - -. Linux - . usb kernel module compiled with debugging enabled - . usbmon - . libusb - -. stm32l chip - . http://www.st.com/internet/mcu/product/248820.jsp \ No newline at end of file diff --git a/toremove/stm32l_notes/read_memory.csv b/toremove/stm32l_notes/read_memory.csv deleted file mode 100644 index 0d26683b4..000000000 --- a/toremove/stm32l_notes/read_memory.csv +++ /dev/null @@ -1,260 +0,0 @@ -USBlyzer Report - -Capture List - -Type,Seq,Time,Elapsed,Duration,Request,Request Details,Raw Data,I/O,C:I:E,Device Object,Device Name,Driver Name,IRP,Status -START,0001,15:09:38.756,,,,,,,,,,,, -Create,0002,15:12:32.934,174.174733 s,,Create,stvp.exe,,,,FFFFFA80074F4960h,,WinUsb,FFFFFA8006FD8320h, -Create,0003-0002,15:12:32.935,174.174759 s,26 us,Create,stvp.exe,,,,FFFFFA80074F4960h,,WinUsb,FFFFFA8006FD8320h,Success -URB,0004,15:12:32.935,174.174880 s,,Bulk or Interrupt Transfer,16 bytes data,F1 80 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F1 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0005-0004,15:12:32.936,174.176236 s,1.356 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0006,15:12:32.936,174.176269 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0007-0006,15:12:32.938,174.178222 s,1.953 ms,Bulk or Interrupt Transfer,6 bytes data,23 80 83 04 48 37,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),23 80 83 04 48 37 -URB,0008,15:12:32.938,174.178249 s,,Bulk or Interrupt Transfer,16 bytes data,F5 00 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0009-0008,15:12:32.939,174.179221 s,972 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0010,15:12:32.939,174.179239 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0011-0010,15:12:32.941,174.181221 s,1.982 ms,Bulk or Interrupt Transfer,2 bytes data,00 01,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),00 01 -URB,0012,15:12:32.941,174.181243 s,,Bulk or Interrupt Transfer,16 bytes data,F3 07 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F3 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0013-0012,15:12:32.942,174.182221 s,978 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0014,15:12:32.943,174.182760 s,,Bulk or Interrupt Transfer,16 bytes data,F2 30 A3 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 30 A3 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0015-0014,15:12:32.944,174.184221 s,1.462 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0016,15:12:32.944,174.184238 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0017-0016,15:12:32.945,174.185221 s,982 us,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0018,15:12:32.945,174.185242 s,,Bulk or Interrupt Transfer,16 bytes data,F2 32 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 32 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0019-0018,15:12:32.946,174.186221 s,979 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0020,15:12:32.946,174.186239 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0021-0020,15:12:32.948,174.188221 s,1.982 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0022,15:12:32.948,174.188240 s,,Bulk or Interrupt Transfer,16 bytes data,F2 35 F0 ED 00 E0 03 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 35 F0 ED 00 E0 03 00 5F A0 00 00 00 00 00 00 -URB,0023-0022,15:12:32.949,174.189220 s,980 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0024,15:12:32.949,174.189237 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0025-0024,15:12:32.951,174.191221 s,1.983 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0026,15:12:32.951,174.191240 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0027-0026,15:12:32.952,174.192221 s,980 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0028,15:12:32.952,174.192237 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0029-0028,15:12:32.953,174.193222 s,985 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 00 03 00 03 03,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 00 00 03 00 03 03 -URB,0030,15:12:32.953,174.193242 s,,Bulk or Interrupt Transfer,16 bytes data,F2 35 F0 ED 00 E0 03 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 35 F0 ED 00 E0 03 00 5F A0 00 00 00 00 00 00 -URB,0031-0030,15:12:32.954,174.194221 s,979 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0032,15:12:32.954,174.194239 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0033-0032,15:12:32.956,174.196221 s,1.981 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0034,15:12:32.956,174.196241 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0035-0034,15:12:32.957,174.197221 s,980 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0036,15:12:32.957,174.197240 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0037-0036,15:12:32.959,174.199220 s,1.980 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 00 03 00 03 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 00 00 03 00 03 00 -URB,0038,15:12:32.959,174.199240 s,,Bulk or Interrupt Transfer,16 bytes data,F2 35 FC ED 00 E0 01 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 35 FC ED 00 E0 01 00 00 00 00 00 00 00 00 00 -URB,0039-0038,15:12:32.960,174.200220 s,979 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0040,15:12:32.960,174.200237 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0041-0040,15:12:32.961,174.201221 s,984 us,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0042,15:12:32.961,174.201241 s,,Bulk or Interrupt Transfer,16 bytes data,F2 35 0C ED 00 E0 04 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 35 0C ED 00 E0 04 00 FA 05 00 00 00 00 00 00 -URB,0043-0042,15:12:32.962,174.202220 s,980 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0044,15:12:32.962,174.202237 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0045-0044,15:12:32.964,174.204220 s,1.983 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0046,15:12:32.964,174.204243 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 0C ED 00 E0 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 36 0C ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0047-0046,15:12:32.965,174.205221 s,978 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0048,15:12:32.965,174.205238 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0049-0048,15:12:32.967,174.207220 s,1.981 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 00 00 00 05 FA,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 00 00 00 00 05 FA -URB,0050,15:12:32.967,174.207239 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0051-0050,15:12:32.968,174.208219 s,980 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0052,15:12:32.968,174.208236 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0053-0052,15:12:32.969,174.209220 s,984 us,Bulk or Interrupt Transfer,8 bytes data,80 00 00 00 03 00 03 02,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 00 00 03 00 03 02 -URB,0054,15:12:32.969,174.209241 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0055-0054,15:12:32.970,174.210220 s,980 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0056,15:12:32.970,174.210237 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0057-0056,15:12:32.972,174.212221 s,1.984 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 00 03 00 03 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 00 00 03 00 03 00 -URB,0058,15:12:32.972,174.212240 s,,Bulk or Interrupt Transfer,16 bytes data,F2 35 FC ED 00 E0 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 35 FC ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0059-0058,15:12:32.973,174.213220 s,980 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0060,15:12:32.973,174.213237 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0061-0060,15:12:32.975,174.215220 s,1.983 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0062,15:12:32.975,174.215241 s,,Bulk or Interrupt Transfer,16 bytes data,F2 31 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0063-0062,15:12:32.976,174.216220 s,980 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0064,15:12:32.976,174.216238 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0065-0064,15:12:32.977,174.217220 s,983 us,Bulk or Interrupt Transfer,12 bytes data,80 00 00 00 77 14 A0 2B...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 00 00 77 14 A0 2B 00 00 00 00 -URB,0066,15:12:32.977,174.217240 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 20 04 E0 04 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 20 04 E0 04 00 00 00 00 00 00 00 00 00 -URB,0067-0066,15:12:32.978,174.218220 s,980 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0068,15:12:32.978,174.218237 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0069-0068,15:12:32.980,174.220220 s,1.983 ms,Bulk or Interrupt Transfer,4 bytes data,16 64 18 10,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),16 64 18 10 -URB,0070,15:12:32.980,174.220240 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0071-0070,15:12:32.981,174.221220 s,980 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0072,15:12:32.981,174.221237 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0073-0072,15:12:32.983,174.223220 s,1.983 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0074,15:12:32.983,174.223243 s,,Bulk or Interrupt Transfer,16 bytes data,F2 34 0F 00 00 00 20 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 34 0F 00 00 00 20 00 00 00 00 00 00 00 00 00 -URB,0075-0074,15:12:32.984,174.224222 s,979 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0076,15:12:32.984,174.224239 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0077-0076,15:12:32.985,174.225220 s,981 us,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0078,15:12:32.985,174.225239 s,,Bulk or Interrupt Transfer,16 bytes data,F2 34 11 00 40 00 20 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 34 11 00 40 00 20 00 00 00 00 00 00 00 00 00 -URB,0079-0078,15:12:32.986,174.226221 s,981 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0080,15:12:32.986,174.226238 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0081-0080,15:12:32.988,174.228225 s,1.987 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0082,15:12:32.988,174.228257 s,,Bulk or Interrupt Transfer,16 bytes data,F2 34 10 00 00 00 01 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 34 10 00 00 00 01 00 00 00 00 00 00 00 00 00 -URB,0083-0082,15:12:32.989,174.229225 s,968 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0084,15:12:32.989,174.229243 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0085-0084,15:12:32.991,174.231221 s,1.978 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0086,15:12:32.991,174.231244 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 00 00 00 20 04 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 08 00 00 00 20 04 00 00 00 00 00 00 00 00 00 -URB,0087-0086,15:12:32.992,174.232221 s,977 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0088,15:12:32.992,174.232239 s,,Bulk or Interrupt Transfer,4 bytes data,55 AA 88 00,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,55 AA 88 00 -URB,0089-0088,15:12:32.993,174.233221 s,982 us,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0090,15:12:32.993,174.233239 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0091-0090,15:12:32.994,174.234222 s,983 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0092,15:12:32.994,174.234242 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0093-0092,15:12:32.996,174.236221 s,1.979 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0094,15:12:32.996,174.236242 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 00 00 20 04 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 00 00 20 04 00 00 00 00 00 00 00 00 00 -URB,0095-0094,15:12:32.997,174.237221 s,979 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0096,15:12:32.997,174.237238 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0097-0096,15:12:32.999,174.239222 s,1.984 ms,Bulk or Interrupt Transfer,4 bytes data,55 AA 88 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),55 AA 88 00 -URB,0098,15:12:32.999,174.239260 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0099-0098,15:12:33.000,174.240228 s,968 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0100,15:12:33.000,174.240266 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0101-0100,15:12:33.002,174.242226 s,1.960 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0102,15:12:33.002,174.242263 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 20 04 E0 04 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 20 04 E0 04 00 00 00 00 00 00 00 00 00 -URB,0103-0102,15:12:33.003,174.243226 s,964 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0104,15:12:33.003,174.243245 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0105-0104,15:12:33.005,174.245219 s,1.975 ms,Bulk or Interrupt Transfer,4 bytes data,16 64 18 10,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),16 64 18 10 -URB,0106,15:12:33.005,174.245240 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0107-0106,15:12:33.006,174.246220 s,980 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0108,15:12:33.006,174.246237 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0109-0108,15:12:33.008,174.248219 s,1.982 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0110,15:12:33.008,174.248242 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 1C 3C 02 40 04 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 1C 3C 02 40 04 00 00 00 00 00 00 00 00 00 -URB,0111-0110,15:12:33.009,174.249219 s,977 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0112,15:12:33.009,174.249236 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0113-0112,15:12:33.010,174.250220 s,984 us,Bulk or Interrupt Transfer,4 bytes data,AA 00 78 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),AA 00 78 00 -URB,0114,15:12:33.010,174.250239 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0115-0114,15:12:33.011,174.251219 s,980 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0116,15:12:33.011,174.251236 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0117-0116,15:12:33.013,174.253220 s,1.983 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0118,15:12:33.013,174.253240 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 20 3C 02 40 04 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 20 3C 02 40 04 00 00 00 00 00 00 00 00 00 -URB,0119-0118,15:12:33.014,174.254220 s,980 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0120,15:12:33.014,174.254239 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0121-0120,15:12:33.016,174.256221 s,1.982 ms,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),00 00 00 00 -URB,0122,15:12:33.016,174.256241 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0123-0122,15:12:33.017,174.257219 s,978 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0124,15:12:33.017,174.257236 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0125-0124,15:12:33.018,174.258220 s,984 us,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0126,15:12:33.018,174.258252 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 00 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 00 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0127-0126,15:12:33.019,174.259220 s,969 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0128,15:12:33.019,174.259241 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0129-0128,15:12:33.097,174.337240 s,77.999 ms,Bulk or Interrupt Transfer,4096 bytes data,28 06 00 20 69 58 00 08...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),28 06 00 20 69 58 00 08 91 54 00 08 93 54 00 08 95 54 00 08 97 54 00 08 99 54 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9B 54 00 08 9D 54 00 08 00 00 00 00 9F 54 00 08 A1 54 00 08 B1 58 00 08 B5 58 00 08 B9 58 00 08 75 56 00 08 C1 58 00 08 C5 58 00 08 27 56 00 08 CD 58 00 08 D1 58 00 08 D5 58 00 08 D9 58 00 08 DD 58 00 08 E1 58 00 08 E5 58 00 08 E9 58 00 08 ED 58 00 08 F1 58 00 08 F5 58 00 08 F9 58 00 08 FD 58 00 08 01 59 00 08 05 59 00 08 09 59 00 08 0D 59 00 08 11 59 00 08 15 59 00 08 19 59 00 08 1D 59 00 08 21 59 00 08 25 59 00 08 29 59 00 08 2D 59 00 08 31 59 00 08 35 59 00 08 39 59 00 08 3D 59 00 08 41 59 00 08 45 59 00 08 49 59 00 08 4D 59 00 08 51 59 00 08 55 59 00 08 59 59 00 08 5D 59 00 08 61 59 00 08 10 B5 84 B0 20 20 AD F8 00 00 AD F8 -URB,0130,15:12:33.097,174.337275 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0131-0130,15:12:33.099,174.339219 s,1.944 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0132,15:12:33.099,174.339238 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0133-0132,15:12:33.101,174.341218 s,1.981 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0134,15:12:33.103,174.343580 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 10 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 10 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0135-0134,15:12:33.105,174.345221 s,1.641 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0136,15:12:33.105,174.345247 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0137-0136,15:12:33.183,174.423249 s,78.002 ms,Bulk or Interrupt Transfer,4096 bytes data,01 01 43 EA 81 31 11 43...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),01 01 43 EA 81 31 11 43 81 61 FF F7 CC FD 01 F0 A4 FD 31 BD 38 B5 04 46 01 25 07 E0 2B 46 00 22 11 46 20 46 FF F7 44 FE 64 1C 6D 1C 20 78 00 28 02 D0 ED B2 08 2D F1 D3 31 BD 38 B5 04 46 01 25 06 E0 00 22 11 46 00 A8 FF F7 32 FE A4 1C 6D 1C 20 88 00 28 1B D0 ED B2 08 2D 18 D2 8D F8 00 00 20 88 00 F4 70 40 B0 F5 80 4F 09 D0 B0 F5 00 4F 2B 46 E6 D1 00 22 01 21 00 A8 FF F7 19 FE E5 E7 2B 46 01 22 00 21 00 A8 FF F7 12 FE DE E7 31 BD 80 B5 04 20 01 F0 65 FD 00 28 FA D1 00 20 3F 49 02 46 02 E0 41 F8 20 20 40 1C 10 28 FA D3 BD E8 01 40 01 F0 52 BD 2D E9 F0 43 83 B0 05 46 0E 46 14 46 00 A8 07 21 01 F0 BB FD 00 2D 5E D0 28 46 00 27 02 E0 7F 1C FF B2 40 1C 01 78 00 29 F9 D1 28 46 FF F7 97 FF 20 46 00 F0 87 FB 4F F0 00 08 0A E0 20 46 00 F0 81 FB 09 F1 01 09 5F FA 89 F9 -URB,0138,15:12:33.183,174.423297 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0139-0138,15:12:33.185,174.425217 s,1.920 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0140,15:12:33.185,174.425240 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0141-0140,15:12:33.187,174.427221 s,1.981 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0142,15:12:33.189,174.428964 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 20 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 20 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0143-0142,15:12:33.190,174.430218 s,1.254 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0144,15:12:33.190,174.430240 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0145-0144,15:12:33.268,174.508249 s,78.008 ms,Bulk or Interrupt Transfer,4096 bytes data,0A 98 78 60 0C 98 F8 60...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),0A 98 78 60 0C 98 F8 60 0E 98 78 61 0D 98 38 61 FF F7 B1 FA 4F F4 00 60 00 F0 6F FE 00 20 00 F0 86 FE 00 20 00 F0 5B FE 00 20 00 F0 6D F8 FF F7 7F FD 01 20 00 F0 1D FF 01 20 00 F0 16 FE FE F7 7D FD 01 20 20 70 40 46 10 B0 BD E8 F0 81 00 00 18 ED 00 E0 00 E4 00 E0 10 E0 00 E0 34 01 00 20 00 00 02 40 00 04 02 40 00 08 02 40 00 0C 02 40 00 10 02 40 00 14 02 40 00 24 01 40 1C 38 02 40 22 02 00 20 23 02 00 20 10 B5 04 00 06 D0 01 2C 04 D0 B5 21 0F F2 00 20 FF F7 DC FB DF F8 C0 01 01 68 49 08 54 EA 41 01 01 60 10 BD 10 B5 04 00 06 D0 01 2C 04 D0 CB 21 0F F2 DC 10 FF F7 CA FB DF F8 9C 01 00 2C 01 68 03 D0 41 F0 02 01 01 60 10 BD 21 F0 02 01 01 60 10 BD 10 B5 04 00 06 D0 01 2C 04 D0 E6 21 0F F2 B0 10 FF F7 B3 FB DF F8 70 01 00 2C 01 68 03 D0 41 F0 04 01 01 60 10 BD -URB,0146,15:12:33.268,174.508317 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0147-0146,15:12:33.270,174.510218 s,1.900 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0148,15:12:33.270,174.510240 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0149-0148,15:12:33.272,174.512259 s,2.019 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0150,15:12:33.274,174.514519 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 30 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 30 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0151-0150,15:12:33.275,174.515232 s,712 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0152,15:12:33.275,174.515266 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0153-0152,15:12:33.353,174.593260 s,77.994 ms,Bulk or Interrupt Transfer,4096 bytes data,04 60 10 BD 10 B5 04 00...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),04 60 10 BD 10 B5 04 00 09 D0 01 2C 07 D0 05 2C 05 D0 40 F2 BD 11 0F F2 78 40 FE F7 1B FC DF F8 28 04 00 21 01 70 04 70 10 BD 10 B5 04 00 07 D0 01 2C 05 D0 40 F2 D5 11 0F F2 54 40 FE F7 0A FC DF F8 08 04 04 60 10 BD 10 B5 04 00 0B D0 01 2C 09 D0 02 2C 07 D0 03 2C 05 D0 40 F2 B7 21 0F F2 30 40 FE F7 F7 FB DF F8 E8 03 01 68 89 08 54 EA 81 01 01 60 10 BD DF F8 D8 03 00 68 00 F0 0C 00 70 47 10 B5 04 00 15 D0 80 2C 13 D0 90 2C 11 D0 A0 2C 0F D0 B0 2C 0D D0 C0 2C 0B D0 D0 2C 09 D0 E0 2C 07 D0 F0 2C 05 D0 40 F2 ED 21 0F F2 E0 30 FE F7 D0 FB DF F8 98 03 01 68 21 F0 F0 01 21 43 01 60 10 BD 10 B5 04 00 11 D0 B4 F5 80 6F 0E D0 B4 F5 A0 6F 0B D0 B4 F5 C0 6F 08 D0 B4 F5 E0 6F 05 D0 4F F4 43 71 0F F2 A8 30 FE F7 B3 FB DF F8 60 03 01 68 21 F4 E0 61 21 43 01 60 10 BD 10 B5 -URB,0154,15:12:33.353,174.593333 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0155-0154,15:12:33.355,174.595215 s,1.882 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0156,15:12:33.355,174.595238 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0157-0156,15:12:33.357,174.597214 s,1.976 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0158,15:12:33.359,174.599172 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 40 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 40 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0159-0158,15:12:33.360,174.600219 s,1.047 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0160,15:12:33.360,174.600245 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0161-0160,15:12:33.438,174.678234 s,77.989 ms,Bulk or Interrupt Transfer,4096 bytes data,B8 F1 04 0F 0E D0 B8 F1...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),B8 F1 04 0F 0E D0 B8 F1 05 0F 0B D0 B8 F1 06 0F 08 D0 B8 F1 07 0F 05 D0 40 F2 FF 21 0F F2 8C 10 FD F7 18 FC 07 21 14 2D 0B D3 E0 68 A5 F1 14 02 02 EB 42 02 91 40 88 43 08 FA 02 F1 08 43 E0 60 16 E0 0A 2D 0B D3 20 69 A5 F1 0A 02 02 EB 42 02 91 40 88 43 08 FA 02 F1 08 43 20 61 08 E0 60 69 05 EB 45 02 91 40 88 43 08 FA 02 F1 08 43 60 61 1F 21 07 2E 09 D2 20 6C 07 EB 87 02 91 40 88 43 05 FA 02 F1 08 43 20 64 33 E0 0D 2E 0A D2 E0 6B F2 1F 02 EB 82 02 91 40 88 43 05 FA 02 F1 08 43 E0 63 26 E0 13 2E 0B D2 A0 6B A6 F1 0D 02 02 EB 82 02 91 40 88 43 05 FA 02 F1 08 43 A0 63 18 E0 19 2E 0B D2 60 6B A6 F1 13 02 02 EB 82 02 91 40 88 43 05 FA 02 F1 08 43 60 63 0A E0 20 6B A6 F1 19 02 02 EB 82 02 91 40 88 43 05 FA 02 F1 08 43 20 63 BD E8 F0 81 10 B5 04 46 DF F8 3C 00 84 42 -URB,0162,15:12:33.438,174.678274 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0163-0162,15:12:33.440,174.680211 s,1.937 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0164,15:12:33.440,174.680231 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0165-0164,15:12:33.441,174.681211 s,980 us,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0166,15:12:33.443,174.682929 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 50 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 50 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0167-0166,15:12:33.443,174.683214 s,285 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0168,15:12:33.443,174.683237 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0169-0168,15:12:33.521,174.761232 s,77.994 ms,Bulk or Interrupt Transfer,4096 bytes data,41 02 08 4B 1B 68 03 EB...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),41 02 08 4B 1B 68 03 EB 42 02 52 89 96 3A 41 F2 F3 23 92 B2 9A 42 ED D3 FF 20 70 47 00 20 70 47 95 01 00 20 10 02 00 20 B8 01 00 20 24 02 00 20 30 01 00 20 F8 01 00 20 58 58 00 08 60 58 00 08 B0 01 00 20 A8 01 00 20 18 02 00 20 97 01 00 20 98 01 00 20 1A 02 00 20 1C 02 00 20 1E 02 00 20 84 58 00 08 00 01 00 08 00 02 00 00 00 00 A0 FF A0 00 20 00 00 00 60 FF 20 FF 60 00 00 00 00 00 10 B5 08 4C 00 20 20 83 01 20 00 F0 D8 F8 01 00 02 D0 20 8B 08 43 20 83 20 8B 00 28 01 D0 FF F7 61 FA 10 BD DC 01 00 20 2D E9 F8 4F 01 20 80 F3 10 88 DF F8 84 03 DF F8 84 13 02 68 0A 60 00 21 01 60 08 46 80 F3 10 88 DF F8 74 43 DF F8 74 B3 DF F8 74 63 DF F8 64 03 00 68 41 1E DF F8 5C 23 11 60 00 28 00 F0 A9 80 DF F8 60 73 38 78 40 1E 38 70 DF F8 5C 03 01 78 49 1E 01 70 C9 B2 00 29 -URB,0170,15:12:33.521,174.761271 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0171-0170,15:12:33.523,174.763211 s,1.940 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0172,15:12:33.523,174.763233 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0173-0172,15:12:33.525,174.765209 s,1.977 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0174,15:12:33.527,174.766919 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 60 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 60 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0175-0174,15:12:33.528,174.768211 s,1.291 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0176,15:12:33.528,174.768234 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0177-0176,15:12:33.604,174.844240 s,76.007 ms,Bulk or Interrupt Transfer,4096 bytes data,00 00 00 00 00 00 00 00...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0178,15:12:33.604,174.844301 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0179-0178,15:12:33.606,174.846214 s,1.913 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0180,15:12:33.606,174.846234 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0181-0180,15:12:33.608,174.848208 s,1.973 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0182,15:12:33.610,174.849977 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 70 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 70 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0183-0182,15:12:33.610,174.850213 s,236 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0184,15:12:33.610,174.850235 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0185-0184,15:12:33.687,174.927228 s,76.993 ms,Bulk or Interrupt Transfer,4096 bytes data,00 00 00 00 00 00 00 00...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0186,15:12:33.687,174.927268 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0187-0186,15:12:33.689,174.929206 s,1.939 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0188,15:12:33.689,174.929226 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0189-0188,15:12:33.690,174.930206 s,980 us,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0190,15:12:33.692,174.932148 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 80 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 80 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0191-0190,15:12:33.693,174.933211 s,1.062 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0192,15:12:33.693,174.933237 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0193-0192,15:12:33.769,175.009241 s,76.004 ms,Bulk or Interrupt Transfer,4096 bytes data,00 00 00 00 00 00 00 00...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0194,15:12:33.769,175.009307 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0195-0194,15:12:33.771,175.011249 s,1.942 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0196,15:12:33.771,175.011349 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0197-0196,15:12:33.773,175.013221 s,1.872 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0198,15:12:33.775,175.015272 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 90 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 90 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0199-0198,15:12:33.777,175.017218 s,1.946 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0200,15:12:33.777,175.017254 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0201-0200,15:12:33.853,175.093245 s,75.991 ms,Bulk or Interrupt Transfer,4096 bytes data,00 00 00 00 00 00 00 00...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0202,15:12:33.853,175.093309 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0203-0202,15:12:33.855,175.095204 s,1.895 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0204,15:12:33.855,175.095227 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0205-0204,15:12:33.857,175.097203 s,1.976 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0206,15:12:33.859,175.098972 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 A0 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 A0 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0207-0206,15:12:33.859,175.099209 s,237 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0208,15:12:33.859,175.099233 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0209-0208,15:12:33.936,175.176223 s,76.990 ms,Bulk or Interrupt Transfer,4096 bytes data,00 00 00 00 00 00 00 00...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0210,15:12:33.936,175.176266 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0211-0210,15:12:33.938,175.178203 s,1.937 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0212,15:12:33.938,175.178223 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0213-0212,15:12:33.940,175.180202 s,1.979 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0214,15:12:33.942,175.181915 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 B0 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 B0 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0215-0214,15:12:33.943,175.183205 s,1.291 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0216,15:12:33.943,175.183234 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0217-0216,15:12:34.019,175.259226 s,75.993 ms,Bulk or Interrupt Transfer,4096 bytes data,00 00 00 00 00 00 00 00...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0218,15:12:34.019,175.259275 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0219-0218,15:12:34.021,175.261201 s,1.926 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0220,15:12:34.021,175.261221 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0221-0220,15:12:34.023,175.263200 s,1.979 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0222,15:12:34.025,175.265126 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 C0 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 C0 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0223-0222,15:12:34.026,175.266209 s,1.083 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0224,15:12:34.026,175.266234 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0225-0224,15:12:34.102,175.342223 s,75.989 ms,Bulk or Interrupt Transfer,4096 bytes data,00 00 00 00 00 00 00 00...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0226,15:12:34.102,175.342270 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0227-0226,15:12:34.104,175.344199 s,1.929 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0228,15:12:34.104,175.344219 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0229-0228,15:12:34.105,175.345202 s,983 us,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0230,15:12:34.107,175.346917 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 D0 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 D0 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0231-0230,15:12:34.107,175.347202 s,285 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0232,15:12:34.107,175.347225 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0233-0232,15:12:34.184,175.424221 s,76.996 ms,Bulk or Interrupt Transfer,4096 bytes data,00 00 00 00 00 00 00 00...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0234,15:12:34.184,175.424272 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0235-0234,15:12:34.186,175.426198 s,1.926 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0236,15:12:34.186,175.426219 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0237-0236,15:12:34.188,175.428197 s,1.978 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0238,15:12:34.190,175.429912 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 E0 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 07 00 E0 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0239-0238,15:12:34.191,175.431198 s,1.286 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0240,15:12:34.191,175.431220 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0241-0240,15:12:34.267,175.507225 s,76.005 ms,Bulk or Interrupt Transfer,4096 bytes data,00 00 00 00 00 00 00 00...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0242,15:12:34.267,175.507282 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0243-0242,15:12:34.269,175.509198 s,1.916 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8006FD8320h,Success (Success) -URB,0244,15:12:34.269,175.509228 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0245-0244,15:12:34.271,175.511235 s,2.007 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 -URB,0246,15:12:34.274,175.513803 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 00 F0 00 08 00 10...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8002902010h,,F2 07 00 F0 00 08 00 10 00 00 00 00 00 00 00 00 -URB,0247-0246,15:12:34.274,175.514220 s,417 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8002902010h,Success (Success) -URB,0248,15:12:34.274,175.514296 s,,Bulk or Interrupt Transfer,4096 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0249-0248,15:12:34.351,175.591234 s,76.938 ms,Bulk or Interrupt Transfer,4096 bytes data,00 00 00 00 00 00 00 00...,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0250,15:12:34.351,175.591304 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8002902010h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0251-0250,15:12:34.353,175.593195 s,1.891 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA8002902010h,Success (Success) -URB,0252,15:12:34.353,175.593216 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h, -URB,0253-0252,15:12:34.354,175.594194 s,978 us,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA800750D060h,USBPDO-10,usbhub,FFFFFA80072A3010h,Success (Success),80 00 - -This report was generated by USBlyzer http://www.usblyzer.com/ diff --git a/toremove/stm32l_notes/step_into.csv b/toremove/stm32l_notes/step_into.csv deleted file mode 100644 index a3d141f71..000000000 --- a/toremove/stm32l_notes/step_into.csv +++ /dev/null @@ -1,194 +0,0 @@ -USBlyzer Report - -Capture List - -Type,Seq,Time,Elapsed,Duration,Request,Request Details,Raw Data,I/O,C:I:E,Device Object,Device Name,Driver Name,IRP,Status -START,0001,17:41:03.981,,,,,,,,,,,, -URB,0002,17:41:09.226,5.245187 s,,Bulk or Interrupt Transfer,16 bytes data,F2 0C 40 11 00 20 02 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 0C 40 11 00 20 02 00 00 00 00 00 00 00 00 00 -URB,0003-0002,17:41:09.227,5.246467 s,1.280 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0004,17:41:09.227,5.246524 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0005-0004,17:41:09.229,5.248463 s,1.939 ms,Bulk or Interrupt Transfer,2 bytes data,70 47,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),70 47 -URB,0006,17:41:09.229,5.248519 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0007-0006,17:41:09.230,5.249462 s,943 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0008,17:41:09.230,5.249491 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0009-0008,17:41:09.232,5.251472 s,1.981 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0010,17:41:09.232,5.251514 s,,Bulk or Interrupt Transfer,16 bytes data,F2 0C 40 11 00 20 02 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 0C 40 11 00 20 02 00 00 00 00 00 00 00 00 00 -URB,0011-0010,17:41:09.233,5.252465 s,951 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0012,17:41:09.233,5.252495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0013-0012,17:41:09.235,5.254462 s,1.967 ms,Bulk or Interrupt Transfer,2 bytes data,70 47,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),70 47 -URB,0014,17:41:09.235,5.254493 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0015-0014,17:41:09.236,5.255462 s,969 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0016,17:41:09.236,5.255498 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0017-0016,17:41:09.238,5.257465 s,1.967 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0018,17:41:09.238,5.257575 s,,Bulk or Interrupt Transfer,16 bytes data,F2 0C 36 11 00 20 02 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 0C 36 11 00 20 02 00 00 00 00 00 00 00 00 00 -URB,0019-0018,17:41:09.239,5.258462 s,887 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0020,17:41:09.239,5.258490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0021-0020,17:41:09.241,5.260462 s,1.972 ms,Bulk or Interrupt Transfer,2 bytes data,05 4A,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),05 4A -URB,0022,17:41:09.241,5.260493 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0023-0022,17:41:09.242,5.261461 s,968 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0024,17:41:09.242,5.261486 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0025-0024,17:41:09.244,5.263461 s,1.975 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0026,17:41:09.244,5.263495 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 FC ED 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 07 FC ED 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0027-0026,17:41:09.245,5.264470 s,975 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0028,17:41:09.245,5.264534 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0029-0028,17:41:09.247,5.266457 s,1.923 ms,Bulk or Interrupt Transfer,4 bytes data,00 00 00 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),00 00 00 01 -URB,0030,17:41:09.247,5.266509 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0031-0030,17:41:09.248,5.267458 s,949 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0032,17:41:09.248,5.267484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0033-0032,17:41:09.250,5.269465 s,1.981 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0034,17:41:09.250,5.269495 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 FC ED 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 08 FC ED 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0035-0034,17:41:09.251,5.270461 s,966 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0036,17:41:09.251,5.270485 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 01,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,00 00 00 01 -URB,0037-0036,17:41:09.253,5.272462 s,1.977 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0038,17:41:09.253,5.272486 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0039-0038,17:41:09.255,5.274460 s,1.974 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0040,17:41:09.255,5.274484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0041-0040,17:41:09.257,5.276460 s,1.976 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0042,17:41:09.257,5.276493 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 28 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 08 28 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0043-0042,17:41:09.258,5.277460 s,968 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0044,17:41:09.258,5.277485 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,00 00 00 00 -URB,0045-0044,17:41:09.260,5.279461 s,1.976 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0046,17:41:09.260,5.279486 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0047-0046,17:41:09.262,5.281461 s,1.975 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0048,17:41:09.262,5.281488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0049-0048,17:41:09.264,5.283461 s,1.972 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0050,17:41:09.264,5.283491 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 38 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 08 38 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0051-0050,17:41:09.265,5.284460 s,969 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0052,17:41:09.265,5.284484 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,00 00 00 00 -URB,0053-0052,17:41:09.267,5.286461 s,1.976 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0054,17:41:09.267,5.286485 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0055-0054,17:41:09.269,5.288460 s,1.975 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0056,17:41:09.269,5.288485 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0057-0056,17:41:09.271,5.290460 s,1.975 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0058,17:41:09.271,5.290487 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 48 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 08 48 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0059-0058,17:41:09.272,5.291462 s,976 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0060,17:41:09.272,5.291486 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,00 00 00 00 -URB,0061-0060,17:41:09.274,5.293460 s,1.974 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0062,17:41:09.274,5.293485 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0063-0062,17:41:09.276,5.295460 s,1.975 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0064,17:41:09.276,5.295487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0065-0064,17:41:09.278,5.297460 s,1.973 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0066,17:41:09.278,5.297488 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 58 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 08 58 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0067-0066,17:41:09.279,5.298460 s,972 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0068,17:41:09.279,5.298485 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,00 00 00 00 -URB,0069-0068,17:41:09.281,5.300460 s,1.975 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0070,17:41:09.281,5.300484 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0071-0070,17:41:09.283,5.302461 s,1.976 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0072,17:41:09.283,5.302485 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0073-0072,17:41:09.285,5.304460 s,1.975 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0074,17:41:09.285,5.304502 s,,Bulk or Interrupt Transfer,16 bytes data,F2 0C 40 11 00 20 02 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 0C 40 11 00 20 02 00 00 00 00 00 00 00 00 00 -URB,0075-0074,17:41:09.286,5.305459 s,957 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0076,17:41:09.286,5.305483 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0077-0076,17:41:09.288,5.307460 s,1.977 ms,Bulk or Interrupt Transfer,2 bytes data,70 47,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),70 47 -URB,0078,17:41:09.288,5.307486 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0079-0078,17:41:09.289,5.308460 s,974 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0080,17:41:09.289,5.308484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0081-0080,17:41:09.291,5.310459 s,1.975 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0082,17:41:09.291,5.310485 s,,Bulk or Interrupt Transfer,16 bytes data,F2 0D 40 11 00 20 02 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 0D 40 11 00 20 02 00 00 00 00 00 00 00 00 00 -URB,0083-0082,17:41:09.292,5.311460 s,975 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0084,17:41:09.292,5.311483 s,,Bulk or Interrupt Transfer,2 bytes data,BE BE,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,BE BE -URB,0085-0084,17:41:09.294,5.313462 s,1.979 ms,Bulk or Interrupt Transfer,2 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0086,17:41:09.294,5.313486 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0087-0086,17:41:09.296,5.315460 s,1.973 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0088,17:41:09.296,5.315487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0089-0088,17:41:09.298,5.317461 s,1.973 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0090,17:41:09.298,5.317488 s,,Bulk or Interrupt Transfer,16 bytes data,F2 35 F0 ED 00 E0 01 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 35 F0 ED 00 E0 01 00 5F A0 00 00 00 00 00 00 -URB,0091-0090,17:41:09.299,5.318460 s,972 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0092,17:41:09.299,5.318484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0093-0092,17:41:09.301,5.320459 s,1.975 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0094,17:41:09.302,5.321032 s,,Bulk or Interrupt Transfer,16 bytes data,F2 36 F0 ED 00 E0 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 36 F0 ED 00 E0 00 00 00 00 00 00 00 00 00 00 -URB,0095-0094,17:41:09.302,5.321463 s,431 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0096,17:41:09.302,5.321490 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0097-0096,17:41:09.304,5.323462 s,1.972 ms,Bulk or Interrupt Transfer,8 bytes data,80 00 00 01 03 00 03 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 03 00 03 01 -URB,0098,17:41:09.304,5.323500 s,,Bulk or Interrupt Transfer,16 bytes data,F2 0D 40 11 00 20 02 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 0D 40 11 00 20 02 00 00 00 00 00 00 00 00 00 -URB,0099-0098,17:41:09.305,5.324460 s,960 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0100,17:41:09.305,5.324491 s,,Bulk or Interrupt Transfer,2 bytes data,70 47,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,70 47 -URB,0101-0100,17:41:09.307,5.326459 s,1.968 ms,Bulk or Interrupt Transfer,2 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0102,17:41:09.307,5.326489 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0103-0102,17:41:09.309,5.328461 s,1.972 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0104,17:41:09.309,5.328488 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0105-0104,17:41:09.311,5.330458 s,1.971 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0106,17:41:09.311,5.330495 s,,Bulk or Interrupt Transfer,16 bytes data,F2 41 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0107-0106,17:41:09.312,5.331460 s,965 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0108,17:41:09.312,5.331487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0109-0108,17:41:09.314,5.333460 s,1.972 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0110,17:41:09.314,5.333511 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 FC ED 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 07 FC ED 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0111-0110,17:41:09.315,5.334459 s,949 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0112,17:41:09.315,5.334485 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0113-0112,17:41:09.317,5.336460 s,1.975 ms,Bulk or Interrupt Transfer,4 bytes data,00 00 00 01,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),00 00 00 01 -URB,0114,17:41:09.317,5.336490 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0115-0114,17:41:09.318,5.337458 s,968 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0116,17:41:09.318,5.337484 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0117-0116,17:41:09.320,5.339459 s,1.975 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0118,17:41:09.320,5.339487 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 FC ED 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 08 FC ED 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0119-0118,17:41:09.321,5.340459 s,972 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0120,17:41:09.321,5.340484 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 01,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,00 00 00 01 -URB,0121-0120,17:41:09.323,5.342460 s,1.976 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0122,17:41:09.323,5.342484 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0123-0122,17:41:09.325,5.344459 s,1.975 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0124,17:41:09.325,5.344483 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0125-0124,17:41:09.327,5.346460 s,1.977 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0126,17:41:09.327,5.346487 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 28 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 08 28 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0127-0126,17:41:09.328,5.347459 s,972 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0128,17:41:09.328,5.347483 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,00 00 00 00 -URB,0129-0128,17:41:09.330,5.349459 s,1.976 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0130,17:41:09.330,5.349484 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0131-0130,17:41:09.332,5.351459 s,1.975 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0132,17:41:09.332,5.351482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0133-0132,17:41:09.334,5.353460 s,1.978 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0134,17:41:09.334,5.353486 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 38 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 08 38 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0135-0134,17:41:09.335,5.354459 s,973 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0136,17:41:09.335,5.354484 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,00 00 00 00 -URB,0137-0136,17:41:09.337,5.356459 s,1.975 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0138,17:41:09.337,5.356487 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0139-0138,17:41:09.339,5.358460 s,1.972 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0140,17:41:09.339,5.358485 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0141-0140,17:41:09.341,5.360459 s,1.973 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0142,17:41:09.341,5.360486 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 48 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 08 48 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0143-0142,17:41:09.342,5.361458 s,972 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0144,17:41:09.342,5.361483 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,00 00 00 00 -URB,0145-0144,17:41:09.344,5.363461 s,1.979 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0146,17:41:09.344,5.363486 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0147-0146,17:41:09.346,5.365459 s,1.973 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0148,17:41:09.346,5.365483 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0149-0148,17:41:09.348,5.367459 s,1.976 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0150,17:41:09.348,5.367485 s,,Bulk or Interrupt Transfer,16 bytes data,F2 08 58 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 08 58 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0151-0150,17:41:09.349,5.368459 s,974 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0152,17:41:09.349,5.368483 s,,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,00 00 00 00 -URB,0153-0152,17:41:09.351,5.370458 s,1.975 ms,Bulk or Interrupt Transfer,4 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0154,17:41:09.351,5.370483 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0155-0154,17:41:09.353,5.372460 s,1.976 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0156,17:41:09.353,5.372483 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0157-0156,17:41:09.355,5.374458 s,1.975 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0158,17:41:09.355,5.374493 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3A 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0159-0158,17:41:09.356,5.375459 s,966 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0160,17:41:09.356,5.375486 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0161-0160,17:41:09.361,5.380459 s,4.973 ms,Bulk or Interrupt Transfer,64 bytes data,80 00 00 01 00 00 00 20...,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 00 01 00 00 00 20 08 ED 00 E0 80 FF FF 1F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 A0 19 00 20 6B 0E 00 20 -URB,0162,17:41:09.361,5.380468 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0163-0162,17:41:09.363,5.382453 s,1.984 ms,Bulk or Interrupt Transfer,24 bytes data,40 11 00 20 00 00 00 01...,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),40 11 00 20 00 00 00 01 A0 19 00 20 00 00 00 00 00 00 00 00 01 00 00 00 -URB,0164,17:41:09.363,5.382485 s,,Bulk or Interrupt Transfer,16 bytes data,F2 0C 40 11 00 20 02 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 0C 40 11 00 20 02 00 00 00 00 00 00 00 00 00 -URB,0165-0164,17:41:09.364,5.383456 s,970 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0166,17:41:09.364,5.383480 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0167-0166,17:41:09.366,5.385458 s,1.978 ms,Bulk or Interrupt Transfer,2 bytes data,70 47,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),70 47 -URB,0168,17:41:09.366,5.385484 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0169-0168,17:41:09.367,5.386458 s,974 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0170,17:41:09.367,5.386482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0171-0170,17:41:09.369,5.388460 s,1.978 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0172,17:41:09.369,5.388623 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 04 10 00 E0 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 07 04 10 00 E0 04 00 00 00 00 00 00 00 00 00 -URB,0173-0172,17:41:09.370,5.389462 s,839 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0174,17:41:09.370,5.389487 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0175-0174,17:41:09.372,5.391459 s,1.972 ms,Bulk or Interrupt Transfer,4 bytes data,00 00 00 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),00 00 00 00 -URB,0176,17:41:09.372,5.391485 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0177-0176,17:41:09.373,5.392459 s,974 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA80096BC490h,Success (Success) -URB,0178,17:41:09.373,5.392482 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0179-0178,17:41:09.375,5.394458 s,1.976 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 -URB,0180,17:41:09.386,5.405429 s,,Bulk or Interrupt Transfer,16 bytes data,F2 07 E4 19 00 20 04 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008A08C60h,,F2 07 E4 19 00 20 04 00 00 00 00 00 00 00 00 00 -URB,0181-0180,17:41:09.387,5.406464 s,1.035 ms,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008A08C60h,Success (Success) -URB,0182,17:41:09.387,5.406495 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0183-0182,17:41:09.389,5.408458 s,1.963 ms,Bulk or Interrupt Transfer,4 bytes data,67 14 00 20,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),67 14 00 20 -URB,0184,17:41:09.389,5.408487 s,,Bulk or Interrupt Transfer,16 bytes data,F2 3B 00 00 00 00 00 00...,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008A08C60h,,F2 3B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -URB,0185-0184,17:41:09.390,5.409458 s,971 us,Bulk or Interrupt Transfer,16 bytes buffer,,out,01:00:02,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8008A08C60h,Success (Success) -URB,0186,17:41:09.390,5.409483 s,,Bulk or Interrupt Transfer,64 bytes buffer,,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h, -URB,0187-0186,17:41:09.392,5.411458 s,1.975 ms,Bulk or Interrupt Transfer,2 bytes data,80 00,in,01:00:81,FFFFFA8002E7E440h,USBPDO-12,usbhub,FFFFFA8009703010h,Success (Success),80 00 - -This report was generated by USBlyzer http://www.usblyzer.com/ From dae71f4a8e8a24753cfbcaa984fa67c84c0f7a90 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 9 Jul 2014 23:03:37 -0700 Subject: [PATCH 0272/1435] Remove unused code Remove unused #if 0'd code which has existed for years without being used. --- src/stlink-common.c | 97 +-------------------------------------------- 1 file changed, 2 insertions(+), 95 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index ce1306b12..9f7c18c97 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -355,16 +355,6 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { stlink_write_debug32(sl, FLASH_F4_CR, x); } -#if 0 /* todo */ - -static void disable_flash_read_protection(stlink_t *sl) { - /* erase the option byte area */ - /* rdp = 0x00a5; */ - /* reset */ -} -#endif /* todo */ - - // Delegates to the backends... void stlink_close(stlink_t *sl) { @@ -1089,19 +1079,6 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } } - /* unused: unlock the option byte block */ -#if 0 - stlink_write_debug32(sl, STM32L_FLASH_OPTKEYR, 0xfbead9c8); - stlink_write_debug32(sl, STM32L_FLASH_OPTKEYR, 0x24252627); - - /* check pecr.optlock is cleared */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 2)) { - fprintf(stderr, "pecr.prglock not clear\n"); - return -1; - } -#endif - /* set pecr.{erase,prog} */ val |= (1 << 9) | (1 << 3); stlink_write_debug32(sl, STM32L_FLASH_PECR, val); @@ -1549,37 +1526,9 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t off += size; } -#if 0 -#define PROGRESS_CHUNK_SIZE 0x1000 - /* write a word in program memory */ - for (off = 0; off < len; off += sizeof(uint32_t)) { - uint32_t data; - if (sl->verbose >= 1) { - if ((off & (PROGRESS_CHUNK_SIZE - 1)) == 0) { - /* show progress. writing procedure is slow - and previous errors are misleading */ - const uint32_t pgnum = (off / PROGRESS_CHUNK_SIZE)+1; - const uint32_t pgcount = len / PROGRESS_CHUNK_SIZE +1; - fprintf(stdout, "Writing %ukB chunk %u out of %u\n", - PROGRESS_CHUNK_SIZE/1024, pgnum, pgcount); - } - } - - write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); - stlink_write_debug32(sl, addr + off, data); - - /* wait for sr.busy to be cleared */ - wait_flash_busy(sl); - - } -#endif /* Relock flash */ lock_flash(sl); -#if 0 /* todo: debug mode */ - fprintf(stdout, "Final CR:0x%x\n", read_flash_cr(sl)); -#endif - } //STM32F4END else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS @@ -1587,13 +1536,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t /* use fast word write. todo: half page. */ uint32_t val; -#if 0 /* todo: check write operation */ - - uint32_t nwrites = sl->flash_pgsz; - -redo_write: - -#endif /* todo: check write operation */ + /* todo: check write operation */ /* disable pecr protection */ stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); @@ -1645,44 +1588,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) ; -#if 0 /* todo: check redo write operation */ - - /* check written bytes. todo: should be on a per page basis. */ - data = stlink_read_debug32(sl, addr + off); - if (data == *(uint32_t*)(base + off)) { - /* re erase the page and redo the write operation */ - uint32_t page; - uint32_t val; - - /* fail if successive write count too low */ - if (nwrites < sl->flash_pgsz) { - fprintf(stderr, "writes operation failure count too high, aborting\n"); - return -1; - } - - nwrites = 0; - - /* assume addr aligned */ - if (off % sl->flash_pgsz) off &= ~(sl->flash_pgsz - 1); - page = addr + off; - - fprintf(stderr, "invalid write @0x%x(0x%x): 0x%x != 0x%x. retrying.\n", - page, addr + off, read_uint32(base + off, 0), read_uint32(sl->q_buf, 0)); - - /* reset lock bits */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR) - | (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - - stlink_erase_flash_page(sl, page); - - goto redo_write; - } - - /* increment successive writes counter */ - ++nwrites; + /* todo: check redo write operation */ -#endif /* todo: check redo write operation */ } fprintf(stdout, "\n"); /* reset lock bits */ From 3c3b02e83e358edee5e704eb61b96d7d1561ff42 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Sat, 12 Jul 2014 13:19:41 -0700 Subject: [PATCH 0273/1435] gdbserver: use uglylogging logging Rather than putting debug printing in #ifdef blocks, use the same uglylogging framework used by core stlink code. To support this, the *LOG() macros are moved into the uglylogging.h header file, and always use the filename as the logging tag. --- gdbserver/gdb-server.c | 132 ++++++++++++++--------------------------- gdbserver/gdb-server.h | 11 ++++ src/stlink-common.c | 8 --- src/stlink-sg.c | 12 +--- src/stlink-usb.c | 6 -- src/test_sg.c | 6 -- src/uglylogging.h | 5 ++ 7 files changed, 61 insertions(+), 119 deletions(-) create mode 100644 gdbserver/gdb-server.h diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 71ab44016..37e116c89 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -1,4 +1,3 @@ -#define DEBUG 0 /* * Copyright (C) 2011 Peter Zotov * Use of this source code is governed by a BSD-style @@ -22,14 +21,10 @@ #endif #include +#include #include "gdb-remote.h" - -#define DEFAULT_LOGGING_LEVEL 50 -#define DEFAULT_GDB_LISTEN_PORT 4242 - -#define STRINGIFY_inner(name) #name -#define STRINGIFY(name) STRINGIFY_inner(name) +#include "gdb-server.h" #define FLASH_BASE 0x08000000 @@ -195,11 +190,11 @@ int main(int argc, char** argv) { stlink_reset(sl); } - printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); + ILOG("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); voltage = stlink_target_voltage(sl); if (voltage != -1) { - printf("Target voltage is %d mV.\n", voltage); + ILOG("Target voltage is %d mV.\n", voltage); } sl->verbose=0; @@ -382,9 +377,7 @@ struct code_hw_watchpoint { struct code_hw_watchpoint data_watches[DATA_WATCH_NUM]; static void init_data_watchpoints(stlink_t *sl) { -#if DEBUG - printf("init watchpoints\n"); -#endif + DLOG("init watchpoints\n"); // set trcena in debug command to turn on dwt unit stlink_write_debug32(sl, 0xE000EDFC, @@ -397,8 +390,8 @@ static void init_data_watchpoints(stlink_t *sl) { } } -static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr, unsigned int len) -{ +static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, + stm32_addr_t addr, unsigned int len) { int i = 0; uint32_t mask; @@ -417,9 +410,7 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr for(i = 0; i < DATA_WATCH_NUM; i++) { // is this an empty slot ? if(data_watches[i].fun == WATCHDISABLED) { -#if DEBUG - printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len); -#endif + DLOG("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len); data_watches[i].fun = wf; data_watches[i].addr = addr; @@ -441,9 +432,7 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr } } -#if DEBUG - printf("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len); -#endif + DLOG("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len); return -1; } @@ -453,9 +442,7 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) for(i = 0 ; i < DATA_WATCH_NUM; i++) { if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) { -#if DEBUG - printf("delete watchpoint %d addr %x\n", i, addr); -#endif + DLOG("delete watchpoint %d addr %x\n", i, addr); data_watches[i].fun = WATCHDISABLED; stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); @@ -464,9 +451,7 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) } } -#if DEBUG - printf("failure: delete watchpoint addr %x\n", addr); -#endif + DLOG("failure: delete watchpoint addr %x\n", addr); return -1; } @@ -490,7 +475,7 @@ static void init_code_breakpoints(stlink_t *sl) { if (((val & 3) != 1) || ((((val >> 8) & 0x70) | ((val >> 4) & 0xf)) != CODE_BREAK_NUM) || (((val >> 8) & 0xf) != CODE_LIT_NUM)){ - fprintf(stderr, "[FP_CTRL] = 0x%08x expecting 0x%08x\n", val, + ELOG("[FP_CTRL] = 0x%08x expecting 0x%08x\n", val, ((CODE_BREAK_NUM & 0x70) << 8) | (CODE_LIT_NUM << 8) | ((CODE_BREAK_NUM & 0xf) << 4) | 1); } @@ -506,7 +491,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { int type = addr & 0x2 ? CODE_BREAK_HIGH : CODE_BREAK_LOW; if(addr & 1) { - fprintf(stderr, "update_code_breakpoint: unaligned address %08x\n", addr); + ELOG("update_code_breakpoint: unaligned address %08x\n", addr); return -1; } @@ -532,20 +517,16 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { else brk->type &= ~type; if(brk->type == 0) { -#if DEBUG - printf("clearing hw break %d\n", id); -#endif + DLOG("clearing hw break %d\n", id); stlink_write_debug32(sl, 0xe0002008 + id * 4, 0); } else { uint32_t mask = (brk->addr) | 1 | (brk->type << 30); -#if DEBUG - printf("setting hw break %d at %08x (%d)\n", - id, brk->addr, brk->type); - printf("reg %08x \n", - mask); -#endif + DLOG("setting hw break %d at %08x (%d)\n", + id, brk->addr, brk->type); + DLOG("reg %08x \n", + mask); stlink_write_debug32(sl, 0xe0002008 + id * 4, mask); } @@ -567,13 +548,13 @@ static struct flash_block* flash_root; static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { if(addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) { - fprintf(stderr, "flash_add_block: incorrect bounds\n"); + ELOG("flash_add_block: incorrect bounds\n"); return -1; } stlink_calculate_pagesize(sl, addr); if(addr % FLASH_PAGE != 0 || length % FLASH_PAGE != 0) { - fprintf(stderr, "flash_add_block: unaligned block\n"); + ELOG("flash_add_block: unaligned block\n"); return -1; } @@ -616,14 +597,14 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { } if(fit_blocks == 0) { - fprintf(stderr, "Unfit data block %08x -> %04x\n", addr, length); + ELOG("Unfit data block %08x -> %04x\n", addr, length); return -1; } if(fit_length != length) { - fprintf(stderr, "warning: data block %08x -> %04x truncated to %04x\n", + WLOG("data block %08x -> %04x truncated to %04x\n", addr, length, fit_length); - fprintf(stderr, "(this is not an error, just a GDB glitch)\n"); + WLOG("(this is not an error, just a GDB glitch)\n"); } return 0; @@ -636,9 +617,7 @@ static int flash_go(stlink_t *sl) { stlink_reset(sl); for(struct flash_block* fb = flash_root; fb; fb = fb->next) { -#if DEBUG - printf("flash_do: block %08x -> %04x\n", fb->addr, fb->length); -#endif + DLOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length); unsigned length = fb->length; for(stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += FLASH_PAGE) { @@ -646,9 +625,7 @@ static int flash_go(stlink_t *sl) { //Update FLASH_PAGE stlink_calculate_pagesize(sl, page); -#if DEBUG - printf("flash_do: page %08x\n", page); -#endif + DLOG("flash_do: page %08x\n", page); if(stlink_write_flash(sl, page, fb->data + (page - fb->addr), length > FLASH_PAGE ? FLASH_PAGE : length) < 0) @@ -698,7 +675,7 @@ int serve(stlink_t *sl, st_state_t *st) { return 1; } - printf("Listening at *:%d...\n", st->listen_port); + ILOG("Listening at *:%d...\n", st->listen_port); int client = accept(sock, NULL, NULL); //signal (SIGINT, SIG_DFL); @@ -716,7 +693,7 @@ int serve(stlink_t *sl, st_state_t *st) { init_code_breakpoints(sl); init_data_watchpoints(sl); - printf("GDB connected.\n"); + ILOG("GDB connected.\n"); /* * To allow resetting the chip from GDB it is required to @@ -729,13 +706,11 @@ int serve(stlink_t *sl, st_state_t *st) { int status = gdb_recv_packet(client, &packet); if(status < 0) { - fprintf(stderr, "cannot recv: %d\n", status); + ELOG("cannot recv: %d\n", status); return 1; } -#if DEBUG - printf("recv: %s\n", packet); -#endif + DLOG("recv: %s\n", packet); char* reply = NULL; reg regp; @@ -758,9 +733,7 @@ int serve(stlink_t *sl, st_state_t *st) { char* queryName = calloc(queryNameLength + 1, 1); strncpy(queryName, &packet[1], queryNameLength); -#if DEBUG - printf("query: %s;%s\n", queryName, params); -#endif + DLOG("query: %s;%s\n", queryName, params); if(!strcmp(queryName, "Supported")) { if(sl->chip_id==STM32_CHIPID_F4) { @@ -783,10 +756,8 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned addr = strtoul(__s_addr, NULL, 16), length = strtoul(s_length, NULL, 16); -#if DEBUG - printf("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", - type, op, annex, addr, length); -#endif + DLOG("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", + type, op, annex, addr, length); const char* data = NULL; @@ -820,9 +791,7 @@ int serve(stlink_t *sl, st_state_t *st) { if (!strncmp(params,"726573756d65",12)) {// resume -#if DEBUG - printf("Rcmd: resume\n"); -#endif + DLOG("Rcmd: resume\n"); stlink_run(sl); reply = strdup("OK"); @@ -831,9 +800,7 @@ int serve(stlink_t *sl, st_state_t *st) { stlink_force_debug(sl); -#if DEBUG - printf("Rcmd: halt\n"); -#endif + DLOG("Rcmd: halt\n"); } else if (!strncmp(params,"6a7461675f7265736574",20)) { //jtag_reset reply = strdup("OK"); @@ -841,9 +808,7 @@ int serve(stlink_t *sl, st_state_t *st) { stlink_jtag_reset(sl, 0); stlink_force_debug(sl); -#if DEBUG - printf("Rcmd: jtag_reset\n"); -#endif + DLOG("Rcmd: jtag_reset\n"); } else if (!strncmp(params,"7265736574",10)) { //reset reply = strdup("OK"); @@ -852,14 +817,9 @@ int serve(stlink_t *sl, st_state_t *st) { init_code_breakpoints(sl); init_data_watchpoints(sl); -#if DEBUG - printf("Rcmd: reset\n"); -#endif + DLOG("Rcmd: reset\n"); } else { -#if DEBUG - printf("Rcmd: %s\n", params); -#endif - + DLOG("Rcmd: %s\n", params); } } @@ -888,10 +848,8 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned addr = strtoul(__s_addr, NULL, 16), length = strtoul(s_length, NULL, 16); -#if DEBUG - printf("FlashErase: addr:%08x,len:%04x\n", - addr, length); -#endif + DLOG("FlashErase: addr:%08x,len:%04x\n", + addr, length); if(flash_add_block(addr, length, sl) < 0) { reply = strdup("E00"); @@ -926,9 +884,7 @@ int serve(stlink_t *sl, st_state_t *st) { if(dec_index % 2 != 0) dec_index++; -#if DEBUG - printf("binary packet %d -> %d\n", data_length, dec_index); -#endif + DLOG("binary packet %d -> %d\n", data_length, dec_index); if(flash_populate(addr, decoded, dec_index) < 0) { reply = strdup("E00"); @@ -959,7 +915,7 @@ int serve(stlink_t *sl, st_state_t *st) { while(1) { int status = gdb_check_for_interrupt(client); if(status < 0) { - fprintf(stderr, "cannot check for int: %d\n", status); + ELOG("cannot check for int: %d\n", status); return 1; } @@ -1267,13 +1223,11 @@ int serve(stlink_t *sl, st_state_t *st) { } if(reply) { -#if DEBUG - printf("send: %s\n", reply); -#endif + DLOG("send: %s\n", reply); int result = gdb_send_packet(client, reply); if(result != 0) { - fprintf(stderr, "cannot send: %d\n", result); + ELOG("cannot send: %d\n", result); free(reply); free(packet); return 1; diff --git a/gdbserver/gdb-server.h b/gdbserver/gdb-server.h new file mode 100644 index 000000000..8c8d47114 --- /dev/null +++ b/gdbserver/gdb-server.h @@ -0,0 +1,11 @@ +#ifndef _GDB_SERVER_H +#define _GDB_SERVER_H + +#define STRINGIFY_inner(name) #name +#define STRINGIFY(name) STRINGIFY_inner(name) + +#define DEFAULT_LOGGING_LEVEL 50 +#define DEBUG_LOGGING_LEVEL 100 +#define DEFAULT_GDB_LISTEN_PORT 4242 + +#endif diff --git a/src/stlink-common.c b/src/stlink-common.c index 9f7c18c97..4e78a1d01 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -18,14 +18,6 @@ #define O_BINARY 0 #endif - -#define LOG_TAG __FILE__ -#define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args) -#define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args) -#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args) -#define ELOG(format, args...) ugly_log(UERROR, LOG_TAG, format, ## args) -#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args) - /* todo: stm32l15xxx flash memory, pm0062 manual */ /* stm32f FPEC flash controller interface, pm0063 manual */ diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 1aefe6135..bfe41574c 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -91,12 +91,6 @@ #include "stlink-sg.h" #include "uglylogging.h" -#define LOG_TAG __FILE__ -#define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args) -#define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args) -#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args) -#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args) - static void clear_cdb(struct stlink_libsg *sl) { for (size_t i = 0; i < sizeof (sl->cdb_cmd_blk); i++) sl->cdb_cmd_blk[i] = 0; @@ -992,8 +986,7 @@ stlink_t* stlink_v1_open_inner(const int verbose) { stlink_version(sl); if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { - ugly_log(UERROR, LOG_TAG, - "WTF? successfully opened, but unable to read version details. BROKEN!\n"); + ELOG("WTF? successfully opened, but unable to read version details. BROKEN!\n"); return NULL; } @@ -1015,8 +1008,7 @@ stlink_t* stlink_v1_open_inner(const int verbose) { // re-query device info (and retest) stlink_version(sl); if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { - ugly_log(UERROR, LOG_TAG, - "WTF? successfully opened, but unable to read version details. BROKEN!\n"); + ELOG("WTF? successfully opened, but unable to read version details. BROKEN!\n"); return NULL; } diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 23ff19176..4a62d9dd5 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -10,12 +10,6 @@ #include "stlink-usb.h" #include "uglylogging.h" -#define LOG_TAG __FILE__ -#define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args) -#define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args) -#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args) -#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args) - /* code from bsd timersub.h http://www.gnu-darwin.org/www001/src/ports/net/libevnet/work/libevnet-0.3.8/libnostd/bsd/sys/time/timersub.h.html */ diff --git a/src/test_sg.c b/src/test_sg.c index dea6ffb21..db7eed325 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -10,12 +10,6 @@ #include "stlink-common.h" #include "uglylogging.h" -#define LOG_TAG __FILE__ -#define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args) -#define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args) -#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args) -#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args) - static void __attribute__((unused)) mark_buf(stlink_t *sl) { memset(sl->q_buf, 0, sizeof(sl->q_buf)); sl->q_buf[0] = 0xaa; diff --git a/src/uglylogging.h b/src/uglylogging.h index 5122820b9..7099d919c 100644 --- a/src/uglylogging.h +++ b/src/uglylogging.h @@ -18,6 +18,11 @@ extern "C" { int ugly_init(int maximum_threshold); int ugly_log(int level, const char *tag, const char *format, ...); +#define DLOG(format, args...) ugly_log(UDEBUG, __FILE__, format, ## args) +#define ILOG(format, args...) ugly_log(UINFO, __FILE__, format, ## args) +#define WLOG(format, args...) ugly_log(UWARN, __FILE__, format, ## args) +#define ELOG(format, args...) ugly_log(UERROR, __FILE__, format, ## args) +#define fatal(format, args...) ugly_log(UFATAL, __FILE__, format, ## args) #ifdef __cplusplus } From e12842b49215ce4a92007b707361d0a235002976 Mon Sep 17 00:00:00 2001 From: mux Date: Thu, 17 Jul 2014 00:46:18 +0200 Subject: [PATCH 0274/1435] Send F4 memory-map and features for STM32F429 * Fix issues #250 #196 --- gdbserver/gdb-server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 37e116c89..5565b0b56 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -336,7 +336,7 @@ char* make_memory_map(stlink_t *sl) { char* map = malloc(4096); map[0] = '\0'; - if(sl->chip_id==STM32_CHIPID_F4) { + if(sl->chip_id==STM32_CHIPID_F4 || sl->chip_id==STM32_CHIPID_F4_HD) { strcpy(map, memory_map_template_F4); } else { snprintf(map, 4096, memory_map_template, @@ -736,7 +736,7 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("query: %s;%s\n", queryName, params); if(!strcmp(queryName, "Supported")) { - if(sl->chip_id==STM32_CHIPID_F4) { + if(sl->chip_id==STM32_CHIPID_F4 || sl->chip_id==STM32_CHIPID_F4_HD) { reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); } else { From ee68f1967aef7c70bf0dbba03095d912f05a3518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Netolick=C3=BD?= Date: Wed, 9 Jul 2014 15:13:31 +0200 Subject: [PATCH 0275/1435] Added support fo STM32L0x chip id and base params. --- src/stlink-common.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/stlink-common.h b/src/stlink-common.h index 898b2a59a..0a3c5d162 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -105,7 +105,7 @@ extern "C" { #define STM32_CHIPID_F1_HIGH 0x414 #define STM32_CHIPID_L1_MEDIUM 0x416 - +#define STM32_CHIPID_L0 0x417 #define STM32_CHIPID_F1_CONN 0x418 #define STM32_CHIPID_F4_HD 0x419 #define STM32_CHIPID_F1_VL_MEDIUM 0x420 @@ -377,7 +377,18 @@ extern "C" { .bootrom_base = 0x1fffd800, .bootrom_size = 0x2000 }, - }; + { + // STM32L0x + // RM0367,RM0377 documents was used to find these parameters + .chip_id = STM32_CHIPID_L0, + .description = "L0x3 device", + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x2000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x1000 + }, + }; typedef struct { From 44c645b7d74b7669b0e3988155528c2edcfbb05e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Netolick=C3=BD?= Date: Fri, 1 Aug 2014 21:28:22 +0200 Subject: [PATCH 0276/1435] Add support for STM32L0x. First try to support new STM32L0x family. Tested on NUCLEO-L053R8 development board http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260001 Chid ID, read, erase and write flash works fine. --- flashloaders/stm32l0x.s | 66 ++++++++++++++++ src/stlink-common.c | 161 ++++++++++++++++++++++++++++------------ 2 files changed, 181 insertions(+), 46 deletions(-) create mode 100644 flashloaders/stm32l0x.s diff --git a/flashloaders/stm32l0x.s b/flashloaders/stm32l0x.s new file mode 100644 index 000000000..9fc44468f --- /dev/null +++ b/flashloaders/stm32l0x.s @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2010 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * Copyright (C) 2011 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * + * Copyright (C) 2011 Clement Burin des Roziers * + * clement.burin-des-roziers@hikob.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +// Build : arm-eabi-gcc -c stm32lx.S + .text + .syntax unified + .cpu cortex-m0plus + .thumb + .thumb_func + .global write + +/* + r0 - destination address + r1 - source address + r2 - count +*/ + + // Set 0 to r3 + movs r3, #0 + // Go to compare + b.n test_done + +write_word: + // Load one word from address in r0, increment by 4 + ldr r4, [r1] + // Store the word to address in r1, increment by 4 + str r4, [r0] + // Increment r3 + adds r3, #1 + adds r1, #4 + // does not matter, only first addr is important + // next 15 bytes are in sequnce RM0367 page 66 + adds r0, #4 + +test_done: + // Compare r3 and r2 + cmp r3, r2 + // Loop if not zero + bcc.n write_word + + // Set breakpoint to exit + bkpt #0x00 diff --git a/src/stlink-common.c b/src/stlink-common.c index 4e78a1d01..b2e68b2c7 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -63,6 +63,20 @@ #define FLASH_L1_FPRG 10 #define FLASH_L1_PROG 3 +//STM32L0x flash register base and offsets +//same as 32L1 above +#define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) +#define FLASH_ACR_OFF ((uint32_t) 0x00) +#define FLASH_PECR_OFF ((uint32_t) 0x04) +#define FLASH_PDKEYR_OFF ((uint32_t) 0x08) +#define FLASH_PEKEYR_OFF ((uint32_t) 0x0c) +#define FLASH_PRGKEYR_OFF ((uint32_t) 0x10) +#define FLASH_OPTKEYR_OFF ((uint32_t) 0x14) +#define FLASH_SR_OFF ((uint32_t) 0x18) +#define FLASH_OBR_OFF ((uint32_t) 0x1c) +#define FLASH_WRPR_OFF ((uint32_t) 0x20) + + //STM32F4 #define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) @@ -78,6 +92,8 @@ #define FLASH_F4_CR_SNB_MASK 0x38 #define FLASH_F4_SR_BSY 16 +#define L1_WRITE_BLOCK_SIZE 0x80 +#define L0_WRITE_BLOCK_SIZE 0x40 void write_uint32(unsigned char* buf, uint32_t ui) { if (!is_bigendian()) { // le -> le (don't swap) @@ -1041,30 +1057,37 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); #endif } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE + || sl->chip_id == STM32_CHIPID_L0) { uint32_t val; + uint32_t flash_regs_base; + if (sl->chip_id == STM32_CHIPID_L0) { + flash_regs_base = STM32L0_FLASH_REGS_ADDR; + } else { + flash_regs_base = STM32L_FLASH_REGS_ADDR; + } /* check if the locks are set */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); if((val & (1<<0))||(val & (1<<1))) { /* disable pecr protection */ - stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); - stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x89abcdef); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x02030405); /* check pecr.pelock is cleared */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); if (val & (1 << 0)) { WLOG("pecr.pelock not clear (%#x)\n", val); return -1; } /* unlock program memory */ - stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf); - stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, 0x8c9daebf); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, 0x13141516); /* check pecr.prglock is cleared */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); if (val & (1 << 1)) { WLOG("pecr.prglock not clear (%#x)\n", val); return -1; @@ -1073,8 +1096,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) /* set pecr.{erase,prog} */ val |= (1 << 9) | (1 << 3); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); #if 0 /* fix_to_be_confirmed */ /* wait for sr.busy to be cleared @@ -1095,13 +1117,13 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) page erase command, even though PM0062 recommends to wait before it. Test shows that a few iterations is performed in the following loop before busy bit is cleared.*/ - while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) + while ((stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF) & (1 << 0)) != 0) ; /* reset lock bits */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR) + val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF) | (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 @@ -1138,7 +1160,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) int stlink_erase_flash_mass(stlink_t *sl) { if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE + || sl->chip_id == STM32_CHIPID_L0) { /* erase each page */ int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -1283,6 +1306,29 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0x00, 0xbe }; + static const uint8_t loader_code_stm32l0[] = { + + /* + r0, input, dest addr + r1, input, source addr + r2, input, word count + r3, output, word count + */ + + 0x00, 0x23, + 0x04, 0xe0, + + 0x0c, 0x68, + 0x04, 0x66, + 0x01, 0x33, + 0x04, 0x31, + 0x04, 0x30, + + 0x93, 0x42, + 0xf8, 0xd3, + 0x00, 0xbe + }; + static const uint8_t loader_code_stm32f4[] = { // flashloaders/stm32f4.s @@ -1309,7 +1355,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { size_t loader_size; if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { /* stm32l */ + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { @@ -1322,7 +1368,10 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); - } else { + } else if (sl->chip_id == STM32_CHIPID_L0) { + loader_code = loader_code_stm32l0; + loader_size = sizeof(loader_code_stm32l0); + } else { ELOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); return -1; } @@ -1388,12 +1437,20 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, } -int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned num_half_pages) +int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len, uint32_t pagesize) { unsigned int count; + unsigned int num_half_pages = len / pagesize; uint32_t val; + uint32_t flash_regs_base; flash_loader_t fl; + if (sl->chip_id == STM32_CHIPID_L0) { + flash_regs_base = STM32L0_FLASH_REGS_ADDR; + } else { + flash_regs_base = STM32L_FLASH_REGS_ADDR; + } + ILOG("Starting Half page flash write for STM32L core id\n"); /* flash loader initialization */ if (init_flash_loader(sl, &fl) == -1) { @@ -1401,21 +1458,20 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uns return -1; } /* Unlock already done */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); val |= (1 << FLASH_L1_FPRG); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); val |= (1 << FLASH_L1_PROG); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) {} + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + while ((stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF) & (1 << 0)) != 0) {} -#define L1_WRITE_BLOCK_SIZE 0x80 for (count = 0; count < num_half_pages; count ++) { - if (run_flash_loader(sl, &fl, addr + count * L1_WRITE_BLOCK_SIZE, base + count * L1_WRITE_BLOCK_SIZE, L1_WRITE_BLOCK_SIZE) == -1) { - WLOG("l1_run_flash_loader(%#zx) failed! == -1\n", addr + count * L1_WRITE_BLOCK_SIZE); - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + if (run_flash_loader(sl, &fl, addr + count * pagesize, base + count * pagesize, pagesize) == -1) { + WLOG("l1_run_flash_loader(%#zx) failed! == -1\n", addr + count * pagesize); + val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); val &= ~((1 << FLASH_L1_FPRG) |(1 << FLASH_L1_PROG)); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); return -1; } /* wait for sr.busy to be cleared */ @@ -1425,15 +1481,15 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uns fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); fflush(stdout); } - while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) { + while ((stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF) & (1 << 0)) != 0) { } } - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); val &= ~(1 << FLASH_L1_PROG); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); val &= ~(1 << FLASH_L1_FPRG); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); return 0; } @@ -1524,40 +1580,51 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } //STM32F4END else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE + || sl->chip_id == STM32_CHIPID_L0) { /* use fast word write. todo: half page. */ uint32_t val; + uint32_t flash_regs_base; + uint32_t pagesize; + + if (sl->chip_id == STM32_CHIPID_L0) { + flash_regs_base = STM32L0_FLASH_REGS_ADDR; + pagesize = L0_WRITE_BLOCK_SIZE; + } else { + flash_regs_base = STM32L_FLASH_REGS_ADDR; + pagesize = L1_WRITE_BLOCK_SIZE; + } /* todo: check write operation */ /* disable pecr protection */ - stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); - stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x89abcdef); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x02030405); /* check pecr.pelock is cleared */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); if (val & (1 << 0)) { fprintf(stderr, "pecr.pelock not clear\n"); return -1; } /* unlock program memory */ - stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf); - stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, 0x8c9daebf); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, 0x13141516); /* check pecr.prglock is cleared */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); if (val & (1 << 1)) { fprintf(stderr, "pecr.prglock not clear\n"); return -1; } off = 0; - if (len > L1_WRITE_BLOCK_SIZE) { - if (stm32l1_write_half_pages(sl, addr, base, len/L1_WRITE_BLOCK_SIZE) == -1) { + if (len > pagesize) { + if (stm32l1_write_half_pages(sl, addr, base, len, pagesize) == -1) { /* This may happen on a blank device! */ WLOG("\nwrite_half_pages failed == -1\n"); } else { - off = (len /L1_WRITE_BLOCK_SIZE)*L1_WRITE_BLOCK_SIZE; + off = (len / pagesize)*pagesize; } } @@ -1577,7 +1644,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t stlink_write_debug32(sl, addr + off, data); /* wait for sr.busy to be cleared */ - while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) + while ((stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF) & (1 << 0)) != 0) ; /* todo: check redo write operation */ @@ -1585,9 +1652,9 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } fprintf(stdout, "\n"); /* reset lock bits */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR) + val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF) | (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { ILOG("Starting Flash write for VL/F0 core id\n"); /* flash loader initialization */ @@ -1680,7 +1747,8 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE + || sl->chip_id == STM32_CHIPID_L0) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1738,7 +1806,8 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons /* check written byte count */ if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE + || sl->chip_id == STM32_CHIPID_L0) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; From 276be4fa42ba7a6fb6de7f8e1f8c0988de8dc708 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Thu, 7 Aug 2014 08:39:15 +0200 Subject: [PATCH 0277/1435] Support for nucleo 411re. --- src/stlink-common.c | 34 +++++++++++++++++----------------- src/stlink-common.h | 11 +++++++++++ 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index b2e68b2c7..cd7979b23 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -152,7 +152,7 @@ static inline uint32_t read_flash_obr(stlink_t *sl) { static inline uint32_t read_flash_cr(stlink_t *sl) { uint32_t res; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||(sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) res = stlink_read_debug32(sl, FLASH_F4_CR); else res = stlink_read_debug32(sl, FLASH_CR); @@ -165,7 +165,7 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) ) return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK); else return read_flash_cr(sl) & (1 << FLASH_CR_LOCK); @@ -178,7 +178,7 @@ static void unlock_flash(stlink_t *sl) { the FPEC block until next reset. */ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); } else { @@ -204,7 +204,7 @@ static int unlock_flash_if(stlink_t *sl) { static void lock_flash(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); stlink_write_debug32(sl, FLASH_F4_CR, n); } else { @@ -217,7 +217,7 @@ static void lock_flash(stlink_t *sl) { static void set_flash_cr_pg(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_CR_PG); stlink_write_debug32(sl, FLASH_F4_CR, x); @@ -230,7 +230,7 @@ static void set_flash_cr_pg(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) stlink_write_debug32(sl, FLASH_F4_CR, n); else stlink_write_debug32(sl, FLASH_CR, n); @@ -248,7 +248,7 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { static void set_flash_cr_mer(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); else @@ -258,7 +258,7 @@ static void set_flash_cr_mer(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); else @@ -268,7 +268,7 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { static void set_flash_cr_strt(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_F4_CR_STRT); stlink_write_debug32(sl, FLASH_F4_CR, x); @@ -285,7 +285,7 @@ static inline uint32_t read_flash_acr(stlink_t *sl) { static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) res = stlink_read_debug32(sl, FLASH_F4_SR); else res = stlink_read_debug32(sl, FLASH_SR); @@ -295,7 +295,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { static inline unsigned int is_flash_busy(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY); else return read_flash_sr(sl) & (1 << FLASH_SR_BSY); @@ -1012,7 +1012,7 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector<4) sl->flash_pgsz=0x4000; else if(sector<5) sl->flash_pgsz=0x10000; @@ -1030,7 +1030,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1362,7 +1362,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || - sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD){ + sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE)){ loader_code = loader_code_stm32f4; loader_size = sizeof(loader_code_stm32f4); } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL) { @@ -1541,7 +1541,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t page_count, sl->flash_pgsz, sl->flash_pgsz); if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { /* todo: check write operation */ ILOG("Starting Flash write for F2/F4\n"); @@ -1772,7 +1772,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || - sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD) { + sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE)) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1827,7 +1827,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || - sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD) { + sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE)) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { diff --git a/src/stlink-common.h b/src/stlink-common.h index 0a3c5d162..532f7d928 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -113,6 +113,8 @@ extern "C" { #define STM32_CHIPID_F3 0x422 #define STM32_CHIPID_F4_LP 0x423 +#define STM32_CHIPID_F411RE 0x431 + #define STM32_CHIPID_L1_MEDIUM_PLUS 0x427 #define STM32_CHIPID_F1_VL_HIGH 0x428 @@ -220,6 +222,15 @@ extern "C" { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 }, + { + .chip_id = STM32_CHIPID_F411RE, + .description = "F4 device (low power) - stm32f411re", + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, { .chip_id = STM32_CHIPID_F4_DE, .description = "F4 device (Dynamic Efficency)", From fde9ec67435d2dad137a3d40d4ff5ce38f97b7d1 Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Wed, 13 Aug 2014 16:00:40 +0200 Subject: [PATCH 0278/1435] jtag reset --- flash/main.c | 10 +++++++--- src/stlink-usb.c | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/flash/main.c b/flash/main.c index 8f5b351de..3e7c8143d 100644 --- a/flash/main.c +++ b/flash/main.c @@ -137,8 +137,10 @@ int main(int ac, char** av) if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); - if (o.reset) + if (o.reset){ + stlink_jtag_reset(sl,2); stlink_reset(sl); + } // Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 if (sl->chip_id == STM32_CHIPID_F4) @@ -196,8 +198,10 @@ int main(int ac, char** av) } } - if (o.reset) - stlink_reset(sl); + if (o.reset){ + stlink_jtag_reset(sl,2); + stlink_reset(sl); + } /* success */ err = 0; diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 4a62d9dd5..f6004d68c 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -432,7 +432,7 @@ void _stlink_usb_jtag_reset(stlink_t * sl, int value) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_JTAG_DRIVE_NRST; - cmd[i++] = (value)?0:1; + cmd[i++] = value; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { From 8f97b230fca22837643705449c49d82ce927ab5a Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Fri, 15 Aug 2014 10:44:24 +0200 Subject: [PATCH 0279/1435] gdb server fix, indentation --- flash/main.c | 10 +++++----- gdbserver/gdb-server.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/flash/main.c b/flash/main.c index 3e7c8143d..82803fe61 100644 --- a/flash/main.c +++ b/flash/main.c @@ -138,9 +138,9 @@ int main(int ac, char** av) stlink_enter_swd_mode(sl); if (o.reset){ - stlink_jtag_reset(sl,2); + stlink_jtag_reset(sl,2); stlink_reset(sl); - } + } // Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 if (sl->chip_id == STM32_CHIPID_F4) @@ -199,9 +199,9 @@ int main(int ac, char** av) } if (o.reset){ - stlink_jtag_reset(sl,2); - stlink_reset(sl); - } + stlink_jtag_reset(sl,2); + stlink_reset(sl); + } /* success */ err = 0; diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 5565b0b56..e5e754bd8 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -804,8 +804,8 @@ int serve(stlink_t *sl, st_state_t *st) { } else if (!strncmp(params,"6a7461675f7265736574",20)) { //jtag_reset reply = strdup("OK"); - stlink_jtag_reset(sl, 1); stlink_jtag_reset(sl, 0); + stlink_jtag_reset(sl, 1); stlink_force_debug(sl); DLOG("Rcmd: jtag_reset\n"); From 61fa5101e996abb3221486fbd7f71c6c0525c19a Mon Sep 17 00:00:00 2001 From: Martin Nowak Date: Wed, 20 Aug 2014 23:21:50 +0200 Subject: [PATCH 0280/1435] fix missing error msg when no suitable device is found --- src/stlink-usb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index f6004d68c..d9faaa9f8 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -770,8 +770,7 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { devAddr=atoi(c); ILOG("bus %03d dev %03d\n",devBus, devAddr); } - while (cnt){ - cnt--; + while (cnt--){ libusb_get_device_descriptor( list[cnt], &desc ); if (desc.idVendor!=USB_ST_VID) continue; if (devBus && devAddr) From add3285b5de9f9a2d845e81c6d54d4553453eec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lari=20Lehtom=C3=A4ki?= Date: Mon, 8 Sep 2014 18:49:11 +0300 Subject: [PATCH 0281/1435] Adds support for STM32F334 MCU --- src/stlink-common.c | 34 ++++++++++++++++++++++++++-------- src/stlink-common.h | 14 +++++++++++++- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index cd7979b23..22f3655de 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1127,7 +1127,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 - || sl->chip_id == STM32_CHIPID_F37x) { + || sl->chip_id == STM32_CHIPID_F37x + || sl->chip_id == STM32_CHIPID_F334) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1358,7 +1359,8 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); - } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { + } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || + sl->chip_id == STM32_CHIPID_F37x || sl->chip_id == STM32_CHIPID_F334) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || @@ -1540,8 +1542,12 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t ILOG("Finished erasing %d pages of %d (%#x) bytes\n", page_count, sl->flash_pgsz, sl->flash_pgsz); - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { + if ((sl->chip_id == STM32_CHIPID_F2) || + (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_DE) || + (sl->chip_id == STM32_CHIPID_F4_LP) || + (sl->chip_id == STM32_CHIPID_F4_HD) || + (sl->chip_id == STM32_CHIPID_F411RE)) { /* todo: check write operation */ ILOG("Starting Flash write for F2/F4\n"); @@ -1655,8 +1661,12 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF) | (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { - ILOG("Starting Flash write for VL/F0 core id\n"); + } else if (sl->core_id == STM32VL_CORE_ID || + sl->core_id == STM32F0_CORE_ID || + sl->chip_id == STM32_CHIPID_F3 || + sl->chip_id == STM32_CHIPID_F334 || + sl->chip_id == STM32_CHIPID_F37x) { + ILOG("Starting Flash write for VL/F0/F3 core id\n"); /* flash loader initialization */ if (init_flash_loader(sl, &fl) == -1) { ELOG("init_flash_loader() == -1\n"); @@ -1759,7 +1769,11 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, count, 2); /* count (32 bits words) */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { + } else if (sl->core_id == STM32VL_CORE_ID || + sl->core_id == STM32F0_CORE_ID || + sl->chip_id == STM32_CHIPID_F3 || + sl->chip_id == STM32_CHIPID_F37x || + sl->chip_id == STM32_CHIPID_F334) { size_t count = size / sizeof(uint16_t); if (size % sizeof(uint16_t)) ++count; @@ -1818,7 +1832,11 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { + } else if (sl->core_id == STM32VL_CORE_ID || + sl->core_id == STM32F0_CORE_ID || + sl->chip_id == STM32_CHIPID_F3 || + sl->chip_id == STM32_CHIPID_F37x || + sl->chip_id == STM32_CHIPID_F334) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { diff --git a/src/stlink-common.h b/src/stlink-common.h index 532f7d928..9f8b9cd70 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -125,7 +125,7 @@ extern "C" { #define STM32_CHIPID_L1_HIGH 0x436 #define STM32_CHIPID_L152_RE 0x437 - +#define STM32_CHIPID_F334 0x438 #define STM32_CHIPID_F3_SMALL 0x439 #define STM32_CHIPID_F0 0x440 @@ -399,6 +399,18 @@ extern "C" { .bootrom_base = 0x1ff0000, .bootrom_size = 0x1000 }, + { + // STM32F334 + // RM0364 document was used to find these parameters + .chip_id = STM32_CHIPID_F334, + .description = "F334 device", + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0x3000, + .bootrom_base = 0x1fffd800, + .bootrom_size = 0x2000 + }, + }; From b548f669672cecfa959aea66fb5663d5e76963d7 Mon Sep 17 00:00:00 2001 From: Victor Mayoral Vilches Date: Mon, 29 Sep 2014 14:26:20 -0700 Subject: [PATCH 0282/1435] Fix memory config for STM32F4 The previous memory map didn't allow to debug the whole flash memory. A new configuration has been added and should be used while working with the STM32F4Discovery. --- gdbserver/gdb-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index e5e754bd8..6ea9baecf 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -306,7 +306,7 @@ static const char* const memory_map_template_F4 = " " //Sector 4 " 0x10000" //64kB " " - " " //Sectors 5..11 + " " //Sectors 5..11 " 0x20000" //128kB " " " " // peripheral regs From f84abb99ff48899d0667afc80d6cf66392d0a007 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Oct 2014 20:16:51 +0200 Subject: [PATCH 0283/1435] [ update ] add ST NUCLEO F030R8 as a working target in README --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index c0ccc7b73..4adb21fc6 100644 --- a/README +++ b/README @@ -185,5 +185,6 @@ Known Working Targets: STLink v2-1 (as found on the Nucleo boards) Known Working Targets: * STM32F401xx (STM32 Nucleo-F401RE board) +* STM32F030R8T6 (STM32 Nucleo-F030R8 board) Please report any and all known working combinations so I can update this! From c49ec2867804fb2a32a9cc0cc6f90cd785ff4bd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bjo=CC=88rn=20Hauffe?= Date: Tue, 14 Oct 2014 20:58:11 +0200 Subject: [PATCH 0284/1435] add kernelextension for OS X 10.10 Yosemite --- stlinkv1_macosx_driver/README | 6 ++++++ stlinkv1_macosx_driver/osx.tar.gz | Bin 22405 -> 23580 bytes 2 files changed, 6 insertions(+) diff --git a/stlinkv1_macosx_driver/README b/stlinkv1_macosx_driver/README index 7b47f410f..0c0adba2d 100644 --- a/stlinkv1_macosx_driver/README +++ b/stlinkv1_macosx_driver/README @@ -30,3 +30,9 @@ P.S. If error `OS X version not supported` occurs. For the latest versions of Ma --- > ISOSXLION=$(sw_vers -productVersion | sed -e 's:.[[:digit:]]*$::') ``` +FOR OS X 10.10 Yosemite you must force the system to load unsigned kernelextensions +you can so this with this command + +sudo nvram boot-args="kext-dev-mode=1“ + +reboot the system! diff --git a/stlinkv1_macosx_driver/osx.tar.gz b/stlinkv1_macosx_driver/osx.tar.gz index 51a7a3248574e128d4a38b4624e7b26be8fa4a23..57bc314668c66f849b8fdcd50a5e38a430cac624 100644 GIT binary patch literal 23580 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
    j8Y(F{;Oc1p&o2`rjEgTlTet!n|}EG9(XKHIrH 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 M^A0x(5eCYC0W6&Nj{pDw literal 22405 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 Date: Tue, 14 Oct 2014 21:01:41 +0200 Subject: [PATCH 0285/1435] Update README --- stlinkv1_macosx_driver/README | 1 - 1 file changed, 1 deletion(-) diff --git a/stlinkv1_macosx_driver/README b/stlinkv1_macosx_driver/README index 0c0adba2d..0c789489c 100644 --- a/stlinkv1_macosx_driver/README +++ b/stlinkv1_macosx_driver/README @@ -31,7 +31,6 @@ P.S. If error `OS X version not supported` occurs. For the latest versions of Ma > ISOSXLION=$(sw_vers -productVersion | sed -e 's:.[[:digit:]]*$::') ``` FOR OS X 10.10 Yosemite you must force the system to load unsigned kernelextensions -you can so this with this command sudo nvram boot-args="kext-dev-mode=1“ From abe1a0f026807ad1aec26b3f1ac176fd053b661f Mon Sep 17 00:00:00 2001 From: Sven Wegener Date: Tue, 21 Oct 2014 10:04:10 +0200 Subject: [PATCH 0286/1435] SNB is wider than three bits on STM32F4 The SNB part of the FLASH_CR register is four bits wide on F4 devices and five bits wide on F4_HD devices. F4 devices have a reserved bit alongside the sector number, so just increase the bitmask to cover all five bits. Currently flashing breaks, if flahing sector eight and above before flashing lower sectors, because the highest bit is never unset. Signed-off-by: Sven Wegener --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 22f3655de..acc84169b 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -89,7 +89,7 @@ #define FLASH_F4_CR_LOCK 31 #define FLASH_F4_CR_SER 1 #define FLASH_F4_CR_SNB 3 -#define FLASH_F4_CR_SNB_MASK 0x38 +#define FLASH_F4_CR_SNB_MASK 0xf8 #define FLASH_F4_SR_BSY 16 #define L1_WRITE_BLOCK_SIZE 0x80 From 325dd000f2c7a40337180eb973234e4425f405ee Mon Sep 17 00:00:00 2001 From: lementec Date: Thu, 30 Oct 2014 14:38:36 +0100 Subject: [PATCH 0287/1435] update README, NUCLEO-F072RB as reported by kwikius --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index 4adb21fc6..6f0a1ade2 100644 --- a/README +++ b/README @@ -186,5 +186,6 @@ STLink v2-1 (as found on the Nucleo boards) Known Working Targets: * STM32F401xx (STM32 Nucleo-F401RE board) * STM32F030R8T6 (STM32 Nucleo-F030R8 board) +* STM32F072RBT6 (STM32 Nucleo-F072RB board) Please report any and all known working combinations so I can update this! From 10f07fccddb3a57568741ff847bec60e33868b6e Mon Sep 17 00:00:00 2001 From: Woodrow Douglass Date: Fri, 31 Oct 2014 10:47:34 -0400 Subject: [PATCH 0288/1435] Modify flash calculation functions to support 2MB devices in the STM32F4 series --- src/stlink-common.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index acc84169b..fca82284b 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1000,13 +1000,18 @@ int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, s } uint32_t calculate_F4_sectornum(uint32_t flashaddr){ + uint32_t offset = 0; flashaddr &= ~STM32_FLASH_BASE; //Page now holding the actual flash address - if (flashaddr<0x4000) return (0); - else if(flashaddr<0x8000) return(1); - else if(flashaddr<0xc000) return(2); - else if(flashaddr<0x10000) return(3); - else if(flashaddr<0x20000) return(4); - else return(flashaddr/0x20000)+4; + if (flashaddr >= 0x100000) { + offset = 12; + flashaddr -= 0x100000; + } + if (flashaddr<0x4000) return (offset + 0); + else if(flashaddr<0x8000) return(offset + 1); + else if(flashaddr<0xc000) return(offset + 2); + else if(flashaddr<0x10000) return(offset + 3); + else if(flashaddr<0x20000) return(offset + 4); + else return offset + (flashaddr/0x20000) +4; } @@ -1014,6 +1019,9 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { uint32_t sector=calculate_F4_sectornum(flashaddr); + if (sector>= 12) { + sector -= 12; + } if (sector<4) sl->flash_pgsz=0x4000; else if(sector<5) sl->flash_pgsz=0x10000; else sl->flash_pgsz=0x20000; From e80d5d2359b28fe65737d4d24d0d92410ba314be Mon Sep 17 00:00:00 2001 From: Woodrow Douglass Date: Fri, 31 Oct 2014 13:54:37 -0400 Subject: [PATCH 0289/1435] use correct SNB values for high flash pages on 2mb devices. --- src/stlink-common.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index fca82284b..4d30287ad 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1050,6 +1050,10 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) uint32_t sector=calculate_F4_sectornum(flashaddr); fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x\n", sector, stlink_calculate_pagesize(sl, flashaddr)); + + //the SNB values for flash sectors in the second bank do not directly follow the values for the first bank on 2mb devices... + if (sector >= 12) sector += 4; + write_flash_cr_snb(sl, sector); /* start erase operation */ From 3c39d6ba8033ac7777499d3795dfc4df0b463a12 Mon Sep 17 00:00:00 2001 From: lementec Date: Tue, 18 Nov 2014 10:55:41 +0100 Subject: [PATCH 0290/1435] add command line debug option to flash util --- flash/main.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/flash/main.c b/flash/main.c index 82803fe61..f875692d1 100644 --- a/flash/main.c +++ b/flash/main.c @@ -9,6 +9,9 @@ #include #include "stlink-common.h" +#define DEBUG_LOG_LEVEL 100 +#define STND_LOG_LEVEL 50 + enum st_cmds {DO_WRITE = 0, DO_READ = 1, DO_ERASE = 2}; struct opts { @@ -18,14 +21,15 @@ struct opts stm32_addr_t addr; size_t size; int reset; + int log_level; }; static void usage(void) { - puts("stlinkv1 command line: ./flash [--reset] {read|write} /dev/sgX path addr "); - puts("stlinkv1 command line: ./flash /dev/sgX erase"); - puts("stlinkv2 command line: ./flash [--reset] {read|write} path addr "); - puts("stlinkv2 command line: ./flash erase"); + puts("stlinkv1 command line: ./flash [--debug] [--reset] {read|write} /dev/sgX path addr "); + puts("stlinkv1 command line: ./flash [--debug] /dev/sgX erase"); + puts("stlinkv2 command line: ./flash [--debug] [--reset] {read|write} path addr "); + puts("stlinkv2 command line: ./flash [--debug] erase"); puts(" use hex format for addr and "); } @@ -38,6 +42,17 @@ static int get_opts(struct opts* o, int ac, char** av) if (ac < 1) return -1; + if (strcmp(av[0], "--debug") == 0) + { + o->log_level = DEBUG_LOG_LEVEL; + ac--; + av++; + } + else + { + o->log_level = STND_LOG_LEVEL; + } + if (strcmp(av[0], "--reset") == 0) { o->reset = 1; @@ -120,15 +135,15 @@ int main(int ac, char** av) if (o.devname != NULL) /* stlinkv1 */ { - sl = stlink_v1_open(50, 1); + sl = stlink_v1_open(o.log_level, 1); if (sl == NULL) goto on_error; - sl->verbose = 50; + sl->verbose = o.log_level; } else /* stlinkv2 */ { - sl = stlink_open_usb(50, 1); + sl = stlink_open_usb(o.log_level, 1); if (sl == NULL) goto on_error; - sl->verbose = 50; + sl->verbose = o.log_level; } if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) From 23e03fa07428610cb67cfb2dcea720de20a3b778 Mon Sep 17 00:00:00 2001 From: lementec Date: Tue, 18 Nov 2014 11:05:51 +0100 Subject: [PATCH 0291/1435] check stlink_load_device_params --- src/stlink-usb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index d9faaa9f8..d0baa0deb 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -864,10 +864,8 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { if (reset) { stlink_reset(sl); } - stlink_load_device_params(sl); stlink_version(sl); - - error = 0; + error = stlink_load_device_params(sl); on_libusb_error: if (devs != NULL) { @@ -887,6 +885,6 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { libusb_exit(slu->libusb_ctx); if (sl != NULL) free(sl); if (slu != NULL) free(slu); - return 0; + return NULL; } From 7d6dad8546efad7e55a82c3668cef7b49062c05e Mon Sep 17 00:00:00 2001 From: texane Date: Mon, 24 Nov 2014 16:29:09 -0600 Subject: [PATCH 0292/1435] Improve error message for not able to open --- src/stlink-usb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index d0baa0deb..d8b6c4673 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "stlink-common.h" #include "stlink-usb.h" @@ -788,7 +789,8 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { } else { int error = libusb_open(list[cnt], &slu->usb_handle); if( error !=0 ) { - WLOG("Error %d opening ST-Link/V2 device %03d:%03d\n", error, libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); + WLOG("Error %d (%s) opening ST-Link/V2 device %03d:%03d\n", + error, strerror (errno), libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); goto on_error; } } From d04fcf5cb68161d08ff98cd9d92b0d81b9242ce2 Mon Sep 17 00:00:00 2001 From: Rene Hopf Date: Tue, 2 Dec 2014 18:33:36 +0100 Subject: [PATCH 0293/1435] Support for stm32f100 low density devices --- src/stlink-common.c | 6 ++++++ src/stlink-common.h | 10 +++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 4d30287ad..2e45d42b9 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -478,6 +478,12 @@ int stlink_load_device_params(stlink_t *sl) { sl->sys_base = params->bootrom_base; sl->sys_size = params->bootrom_size; + //medium and low devices have the same chipid. ram size depends on flash size. + //STM32F100xx datasheet Doc ID 16455 Table 2 + if(sl->chip_id == STM32_CHIPID_F1_VL_MEDIUM_LOW && sl->flash_size < 64 * 1024){ + sl->sram_size = 0x1000; + } + ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); // TODO make note of variable page size here..... ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %zd bytes\n", diff --git a/src/stlink-common.h b/src/stlink-common.h index 9f8b9cd70..0379753b9 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -108,7 +108,7 @@ extern "C" { #define STM32_CHIPID_L0 0x417 #define STM32_CHIPID_F1_CONN 0x418 #define STM32_CHIPID_F4_HD 0x419 -#define STM32_CHIPID_F1_VL_MEDIUM 0x420 +#define STM32_CHIPID_F1_VL_MEDIUM_LOW 0x420 #define STM32_CHIPID_F3 0x422 #define STM32_CHIPID_F4_LP 0x423 @@ -296,12 +296,12 @@ extern "C" { .bootrom_base = 0x1fffb000, .bootrom_size = 0x4800 }, - { - .chip_id = STM32_CHIPID_F1_VL_MEDIUM, - .description = "F1 Medium-density Value Line device", + {//Low and Medium density VL have same chipid. RM0041 25.6.1 + .chip_id = STM32_CHIPID_F1_VL_MEDIUM_LOW, + .description = "F1 Medium/Low-density Value Line device", .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, - .sram_size = 0x2000, + .sram_size = 0x2000,//0x1000 for low density devices .bootrom_base = 0x1ffff000, .bootrom_size = 0x800 }, From 067430469a94cb3266585db88b8fb7e8f97c8857 Mon Sep 17 00:00:00 2001 From: Stefan Misik Date: Wed, 24 Dec 2014 22:36:44 +0100 Subject: [PATCH 0294/1435] Added AHB3 Peripherals definition for STM32F4 --- gdbserver/gdb-server.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 6ea9baecf..f0e965374 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -310,6 +310,7 @@ static const char* const memory_map_template_F4 = " 0x20000" //128kB " " " " // peripheral regs + " " // AHB3 Peripherals " " // cortex regs " " // bootrom " " // option byte area From cbab4b1e34b91622ae0bd879f540a66bc0d9b9c1 Mon Sep 17 00:00:00 2001 From: texane Date: Thu, 25 Dec 2014 21:31:26 -0600 Subject: [PATCH 0295/1435] update README for STM32F103RB support --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index 6f0a1ade2..ec58e9bb2 100644 --- a/README +++ b/README @@ -187,5 +187,6 @@ Known Working Targets: * STM32F401xx (STM32 Nucleo-F401RE board) * STM32F030R8T6 (STM32 Nucleo-F030R8 board) * STM32F072RBT6 (STM32 Nucleo-F072RB board) +* STM32F103RB (STM32 Nucleo-F103RB board) Please report any and all known working combinations so I can update this! From 845d9ea7cd419d437f5a5902da2e321414791230 Mon Sep 17 00:00:00 2001 From: Nic McDonald Date: Tue, 13 Jan 2015 13:19:34 -0800 Subject: [PATCH 0296/1435] added Nucleo F334R8 to README --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index ec58e9bb2..cedbd2474 100644 --- a/README +++ b/README @@ -188,5 +188,6 @@ Known Working Targets: * STM32F030R8T6 (STM32 Nucleo-F030R8 board) * STM32F072RBT6 (STM32 Nucleo-F072RB board) * STM32F103RB (STM32 Nucleo-F103RB board) +* STM32F334R8 (STM32 Nucleo-F334R8 board) Please report any and all known working combinations so I can update this! From f68e4c201f2defeb8fa8f7812887c4509f6c4808 Mon Sep 17 00:00:00 2001 From: Nic McDonald Date: Wed, 14 Jan 2015 22:52:13 -0800 Subject: [PATCH 0297/1435] change flash to st-flash Previous commit changed binary "flash" to "st-flash" but the actual code printed help message still called it "flash". This commit changes it to "st-flash". --- flash/main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flash/main.c b/flash/main.c index f875692d1..f84323217 100644 --- a/flash/main.c +++ b/flash/main.c @@ -26,17 +26,17 @@ struct opts static void usage(void) { - puts("stlinkv1 command line: ./flash [--debug] [--reset] {read|write} /dev/sgX path addr "); - puts("stlinkv1 command line: ./flash [--debug] /dev/sgX erase"); - puts("stlinkv2 command line: ./flash [--debug] [--reset] {read|write} path addr "); - puts("stlinkv2 command line: ./flash [--debug] erase"); + puts("stlinkv1 command line: ./st-flash [--debug] [--reset] {read|write} /dev/sgX path addr "); + puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); + puts("stlinkv2 command line: ./st-flash [--debug] [--reset] {read|write} path addr "); + puts("stlinkv2 command line: ./st-flash [--debug] erase"); puts(" use hex format for addr and "); } 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 */ + /* stlinkv1 command line: ./st-flash {read|write} /dev/sgX path addr */ + /* stlinkv2 command line: ./st-flash {read|write} path addr */ unsigned int i = 0; From 2daeabaead8c45bc8ead84c59391ece6c0bbcfac Mon Sep 17 00:00:00 2001 From: Ethan Zonca Date: Sat, 17 Jan 2015 14:24:38 -0500 Subject: [PATCH 0298/1435] Added support for flashing STM32F042 --- src/stlink-common.c | 2 +- src/stlink-common.h | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 2e45d42b9..6e327f028 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1385,7 +1385,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE)){ loader_code = loader_code_stm32f4; loader_size = sizeof(loader_code_stm32f4); - } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL) { + } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F04 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); } else if (sl->chip_id == STM32_CHIPID_L0) { diff --git a/src/stlink-common.h b/src/stlink-common.h index 0379753b9..ca50c910c 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -132,6 +132,8 @@ extern "C" { #define STM32_CHIPID_F0_SMALL 0x444 +#define STM32_CHIPID_F04 0x445 + #define STM32_CHIPID_F0_CAN 0x448 /* @@ -367,6 +369,17 @@ extern "C" { .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 }, + { + //Use this as an example for mapping future chips: + //RM0091 document was used to find these paramaters + .chip_id = STM32_CHIPID_F04, + .description = "F04x device", + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + }, { //Use this as an example for mapping future chips: //RM0091 document was used to find these paramaters From b2dac269232543ae595e349b1c5b64b6d0cb5af6 Mon Sep 17 00:00:00 2001 From: Simon Wright Date: Fri, 23 Jan 2015 20:43:23 +0000 Subject: [PATCH 0299/1435] Extra RAM for STM32F42xx. --- gdbserver/gdb-server.c | 27 ++++++++++++++++++++++++++- src/stlink-common.h | 2 +- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 6ea9baecf..275370991 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -315,6 +315,29 @@ static const char* const memory_map_template_F4 = " " // option byte area ""; +static const char* const memory_map_template_F4_HD = + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // ccm ram + " " // sram + " " //Sectors 0..3 + " 0x4000" //16kB + " " + " " //Sector 4 + " 0x10000" //64kB + " " + " " //Sectors 5..11 + " 0x20000" //128kB + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + " " // option byte area + ""; + static const char* const memory_map_template = "" "chip_id==STM32_CHIPID_F4 || sl->chip_id==STM32_CHIPID_F4_HD) { + if(sl->chip_id==STM32_CHIPID_F4) { strcpy(map, memory_map_template_F4); + } else if(sl->chip_id==STM32_CHIPID_F4_HD) { + strcpy(map, memory_map_template_F4_HD); } else { snprintf(map, 4096, memory_map_template, sl->flash_size, diff --git a/src/stlink-common.h b/src/stlink-common.h index 9f8b9cd70..17e488dcf 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -209,7 +209,7 @@ extern "C" { .description = "F42x and F43x device", .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ .flash_pagesize = 0x4000, - .sram_size = 0x30000, + .sram_size = 0x40000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 }, From 5608a3e72e0968a90322ce78f57d0c1bb0af66fd Mon Sep 17 00:00:00 2001 From: texane Date: Tue, 3 Feb 2015 19:07:06 +0100 Subject: [PATCH 0300/1435] add --enable-static support to autoconf --- configure.ac | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index f1357b121..b8eb66d58 100644 --- a/configure.ac +++ b/configure.ac @@ -13,8 +13,10 @@ AC_PROG_CC AC_PROG_INSTALL AC_CANONICAL_HOST AC_CANONICAL_BUILD -AC_PROG_RANLIB AM_PROG_CC_C_O +AC_CONFIG_MACRO_DIR([m4]) + +LT_INIT AC_CHECK_HEADERS(sys/mman.h) AC_CHECK_HEADERS(sys/poll.h) @@ -49,6 +51,11 @@ if test "x$with_gtk" = "xyes"; then fi AC_SUBST([MAYBE_GUI]) +AC_ARG_ENABLE([static], AS_HELP_STRING([--enable-static], [enable binaries static linking])) +if test "x$enable_static" = "xyes"; then + LDFLAGS="$LDFLAGS -all-static" +fi + AC_CONFIG_FILES([Makefile]) AC_OUTPUT From c8240526e23278ca9e78f8ad1b9cbf2f37c3035c Mon Sep 17 00:00:00 2001 From: texane Date: Tue, 3 Feb 2015 21:47:06 +0100 Subject: [PATCH 0301/1435] revert 5608a3e, breaks on ubuntu 14.04 --- configure.ac | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index b8eb66d58..f1357b121 100644 --- a/configure.ac +++ b/configure.ac @@ -13,10 +13,8 @@ AC_PROG_CC AC_PROG_INSTALL AC_CANONICAL_HOST AC_CANONICAL_BUILD +AC_PROG_RANLIB AM_PROG_CC_C_O -AC_CONFIG_MACRO_DIR([m4]) - -LT_INIT AC_CHECK_HEADERS(sys/mman.h) AC_CHECK_HEADERS(sys/poll.h) @@ -51,11 +49,6 @@ if test "x$with_gtk" = "xyes"; then fi AC_SUBST([MAYBE_GUI]) -AC_ARG_ENABLE([static], AS_HELP_STRING([--enable-static], [enable binaries static linking])) -if test "x$enable_static" = "xyes"; then - LDFLAGS="$LDFLAGS -all-static" -fi - AC_CONFIG_FILES([Makefile]) AC_OUTPUT From 31f0250d89bd4c1690f366e302de6972716e5951 Mon Sep 17 00:00:00 2001 From: giuseppe barba Date: Mon, 9 Feb 2015 21:54:05 +0100 Subject: [PATCH 0302/1435] Added support for flashing STM32F091 Signed-off-by: giuseppe barba --- src/stlink-common.c | 2 +- src/stlink-common.h | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 6e327f028..3256ccd89 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1385,7 +1385,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE)){ loader_code = loader_code_stm32f4; loader_size = sizeof(loader_code_stm32f4); - } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F04 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL) { + } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F04 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL || sl->chip_id == STM32_CHIPID_F09X) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); } else if (sl->chip_id == STM32_CHIPID_L0) { diff --git a/src/stlink-common.h b/src/stlink-common.h index aeeaa85a4..04a108101 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -129,7 +129,7 @@ extern "C" { #define STM32_CHIPID_F3_SMALL 0x439 #define STM32_CHIPID_F0 0x440 - +#define STM32_CHIPID_F09X 0x442 #define STM32_CHIPID_F0_SMALL 0x444 #define STM32_CHIPID_F04 0x445 @@ -369,6 +369,15 @@ extern "C" { .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 }, + { + .chip_id = STM32_CHIPID_F09X, + .description = "F09X device", + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) + .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) + .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 + .bootrom_size = 0x2000 // "System memory" byte size in hex from Table 2 + }, { //Use this as an example for mapping future chips: //RM0091 document was used to find these paramaters From 527de547088056f3bf206dc5dacb273704ff5300 Mon Sep 17 00:00:00 2001 From: Jakub Tyszkowski Date: Sat, 7 Mar 2015 18:29:38 +0100 Subject: [PATCH 0303/1435] Fix error being reported twice If 'stlink_v1_open_inner' returns NULL then 'stlink_v1_open' prints to stderr thus there is no need for the former one to print it also. This removes 'Error: could not open stlink device' being printed twice. --- src/stlink-sg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index bfe41574c..960455bab 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -980,7 +980,7 @@ stlink_t* stlink_v1_open_inner(const int verbose) { ugly_init(verbose); stlink_t *sl = stlink_open(verbose); if (sl == NULL) { - fputs("Error: could not open stlink device\n", stderr); + ELOG("Could not open stlink device\n"); return NULL; } From fc961745f5ff121e827702255872354f31f95547 Mon Sep 17 00:00:00 2001 From: Jakub Tyszkowski Date: Sat, 7 Mar 2015 18:42:16 +0100 Subject: [PATCH 0304/1435] Fix getting error message when successfully using stlinkV2 When using stlinkV2 you are constantly getting error messages from 'stlink_v1_open' when all goes well and 'stlink_open_usb' is used instead. This patch fixes this confusing behaviour and makes stlink-sg.c use logging macros consistently by removing last 'stderr' printout. It is not needed as 'stlink_v1_open_inner' is verbose enough. --- src/stlink-sg.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 960455bab..db68e2f4e 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -1017,10 +1017,9 @@ stlink_t* stlink_v1_open_inner(const int verbose) { stlink_t* stlink_v1_open(const int verbose, int reset) { stlink_t *sl = stlink_v1_open_inner(verbose); - if (sl == NULL) { - fputs("Error: could not open stlink device\n", stderr); + if (sl == NULL) return NULL; - } + // by now, it _must_ be fully open and in a useful mode.... stlink_enter_swd_mode(sl); /* Now we are ready to read the parameters */ From c6afdd500ceecf106fe177f2017bfada142f6d3a Mon Sep 17 00:00:00 2001 From: Jakub Tyszkowski Date: Sat, 7 Mar 2015 19:47:03 +0100 Subject: [PATCH 0305/1435] Remove redundant includes from stlink-sg.c Not sure why those were here. Probaly leftovers after refactoring? --- src/stlink-sg.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index db68e2f4e..b16a2edfc 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -79,13 +79,8 @@ #include #include #include -#include #include -#include -#include #include -#include -#include "mmap.h" #include "stlink-common.h" #include "stlink-sg.h" From 9b2f8930538630db8537b8c5601e8c4a9c074657 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Sun, 15 Mar 2015 17:49:30 +0200 Subject: [PATCH 0306/1435] Properly close socket on WIN32 to allow accepting further connections --- gdbserver/gdb-server.c | 13 +++++++++++++ mingw/mingw.c | 10 ++++++---- mingw/mingw.h | 1 + 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index daacb85cb..b1cea5cb5 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -733,6 +733,9 @@ int serve(stlink_t *sl, st_state_t *st) { int status = gdb_recv_packet(client, &packet); if(status < 0) { ELOG("cannot recv: %d\n", status); +#ifdef __MINGW32__ + win32_close_socket(sock); +#endif return 1; } @@ -942,6 +945,9 @@ int serve(stlink_t *sl, st_state_t *st) { int status = gdb_check_for_interrupt(client); if(status < 0) { ELOG("cannot check for int: %d\n", status); +#ifdef __MINGW32__ + win32_close_socket(sock); +#endif return 1; } @@ -1256,6 +1262,9 @@ int serve(stlink_t *sl, st_state_t *st) { ELOG("cannot send: %d\n", result); free(reply); free(packet); +#ifdef __MINGW32__ + win32_close_socket(sock); +#endif return 1; } @@ -1265,5 +1274,9 @@ int serve(stlink_t *sl, st_state_t *st) { free(packet); } +#ifdef __MINGW32__ + win32_close_socket(sock); +#endif + return 0; } diff --git a/mingw/mingw.c b/mingw/mingw.c index 266a87c64..3c5d025a3 100644 --- a/mingw/mingw.c +++ b/mingw/mingw.c @@ -163,14 +163,16 @@ win32_shutdown(SOCKET fd, int mode) } return rc; } -int win32_close_socket(SOCKET fd) { - int rc; - rc = closesocket(fd); +int win32_close_socket(SOCKET fd) +{ + int rc = closesocket(fd); + if(rc == SOCKET_ERROR) { + set_socket_errno(WSAGetLastError()); + } return rc; } - ssize_t win32_write_socket(SOCKET fd, void *buf, int n) { int rc = send(fd, buf, n, 0); diff --git a/mingw/mingw.h b/mingw/mingw.h index 28c7a82e0..1fcf93da2 100644 --- a/mingw/mingw.h +++ b/mingw/mingw.h @@ -54,6 +54,7 @@ SOCKET win32_socket(int, int, int); int win32_connect(SOCKET, struct sockaddr*, socklen_t); SOCKET win32_accept(SOCKET, struct sockaddr*, socklen_t *); int win32_shutdown(SOCKET, int); +int win32_close_socket(SOCKET fd); #define strtok_r(x, y, z) win32_strtok_r(x, y, z) #define strsep(x,y) win32_strsep(x,y) From dceade1c279f2efb2607365d67cd841e5e100437 Mon Sep 17 00:00:00 2001 From: texane Date: Fri, 20 Mar 2015 17:52:25 +0100 Subject: [PATCH 0307/1435] merge request: my STM32F042 has 6k of RAM according to table 2 of the datasheet --- src/stlink-common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.h b/src/stlink-common.h index 04a108101..3021691c6 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -385,7 +385,7 @@ extern "C" { .description = "F04x device", .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 + .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 }, From 39998145313394a93e0837d0903d7343fae9425d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uli=20K=C3=B6hler?= Date: Sat, 21 Mar 2015 20:07:21 +0100 Subject: [PATCH 0308/1435] Added STM32F030F4P6 to working targets --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index cedbd2474..5ed9dbf31 100644 --- a/README +++ b/README @@ -170,6 +170,7 @@ No information: STLink v2 (as found on the 32L and F4 Discovery boards) Known Working Targets: +* STM32F030F4P6 (custom board) * STM32F0Discovery (STM32F0 Discovery board) * STM32F100xx (Medium Density VL, as on the 32VL Discovery board) * STM32L1xx (STM32L Discovery board) From 9fc5f77774168f179bdbf79de7a24a82a2835e1e Mon Sep 17 00:00:00 2001 From: lementec Date: Wed, 25 Mar 2015 16:53:14 +0100 Subject: [PATCH 0309/1435] apply patch from rewolff: dont go bezurk if serve returns with error --- gdbserver/gdb-server.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index b1cea5cb5..0ddebb06f 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -209,7 +209,9 @@ int main(int argc, char** argv) { #endif do { - serve(sl, &state); + if (serve(sl, &state)) { + sleep (1); // don't go bezurk if serve returns with error + } /* Continue */ stlink_run(sl); From c72205661244e8b7711d2299175097cc02cfd7c1 Mon Sep 17 00:00:00 2001 From: texane Date: Fri, 3 Apr 2015 14:13:58 +0200 Subject: [PATCH 0310/1435] add HY-STM32 to working board set --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index 5ed9dbf31..bb46e6e8a 100644 --- a/README +++ b/README @@ -176,6 +176,7 @@ Known Working Targets: * STM32L1xx (STM32L Discovery board) * STM32F103VC, STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on custom boards (https://github.com/UweBonnes/wiki_fuer_alex/layout/usps...) +* STM32F103VET6 (HY-STM32 board) * STM32F303xx (STM32F3 Discovery board) * STM32F407xx (STM32F4 Discovery board) * STM32F429I-DISCO (STM32F4 Discovery board with LCD) From 1b46200b12ff8764a869a7365eb8253622100fed Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 5 Apr 2015 08:02:19 +0200 Subject: [PATCH 0311/1435] add Nucleo-F411RE to work board set --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index bb46e6e8a..be9245724 100644 --- a/README +++ b/README @@ -191,5 +191,6 @@ Known Working Targets: * STM32F072RBT6 (STM32 Nucleo-F072RB board) * STM32F103RB (STM32 Nucleo-F103RB board) * STM32F334R8 (STM32 Nucleo-F334R8 board) +* STM32F411RET6 (STM32 Nucleo-F411RE board) Please report any and all known working combinations so I can update this! From e73a5341028e95b5762f4d4db35c2f4b68a69cf3 Mon Sep 17 00:00:00 2001 From: texane Date: Fri, 10 Apr 2015 06:17:28 +0200 Subject: [PATCH 0312/1435] README, GDB load command issue --- README | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README b/README index be9245724..46ce11c4c 100644 --- a/README +++ b/README @@ -156,6 +156,11 @@ A: Sometimes when you will try to use GDB `next' command to skip a loop, it will use a rather inefficient single-stepping way of doing that. Set up a breakpoint manually in that case and do `continue'. +Q: Load command does not work in GDB. + +A: Some people report XML/EXPAT is not enabled by default when compiling +GDB. Memory map parsing thus fail. Use --enable-expat. + Currently known working combinations of programmer and target ============================================================= From 3b37cbf3c6a64d672271a9ce1257fa338ed493bc Mon Sep 17 00:00:00 2001 From: Kyle Manna Date: Wed, 22 Apr 2015 18:48:27 -0700 Subject: [PATCH 0313/1435] stlink: Add STM32F303 High Density Support * STK32F303RET6 device from STM32 F3 Nucelo board --- src/stlink-common.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/stlink-common.h b/src/stlink-common.h index 3021691c6..ac267e2ba 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -134,6 +134,8 @@ extern "C" { #define STM32_CHIPID_F04 0x445 +#define STM32_CHIPID_F303_HIGH 0x446 + #define STM32_CHIPID_F0_CAN 0x448 /* @@ -432,6 +434,17 @@ extern "C" { .bootrom_base = 0x1fffd800, .bootrom_size = 0x2000 }, + { + // This is STK32F303RET6 device from STM32 F3 Nucelo board. + // Support based on DM00043574.pdf (RM0316) document rev 5. + .chip_id = STM32_CHIPID_F303_HIGH, + .description = "F303 high density device", + .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register + .flash_pagesize = 0x800, // 4.2.1 Flash memory organization + .sram_size = 0x10000, // 3.3 Embedded SRAM + .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory + .bootrom_size = 0x2000 + }, }; From 7890d4ccfbca5d0debef9e35bdeca5c22d8100d3 Mon Sep 17 00:00:00 2001 From: Kyle Manna Date: Wed, 22 Apr 2015 18:55:30 -0700 Subject: [PATCH 0314/1435] README: Add STM32 Nucleo-F303RE board * Add another to the list. Preliminary testing works. --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index 46ce11c4c..922765e1d 100644 --- a/README +++ b/README @@ -195,6 +195,7 @@ Known Working Targets: * STM32F030R8T6 (STM32 Nucleo-F030R8 board) * STM32F072RBT6 (STM32 Nucleo-F072RB board) * STM32F103RB (STM32 Nucleo-F103RB board) +* STM32F303RET6 (STM32 Nucleo-F303RE board) * STM32F334R8 (STM32 Nucleo-F334R8 board) * STM32F411RET6 (STM32 Nucleo-F411RE board) From 0c900d76a97c86bfd9b41fd0f1f5c8d3566b877c Mon Sep 17 00:00:00 2001 From: Kyle Manna Date: Thu, 23 Apr 2015 17:03:28 -0700 Subject: [PATCH 0315/1435] stlink: Add flash support for STM32F303 High Density * Add the necessary teststo use the existing flash code. Haven't verified via datasheet if it's correct. * Works for me on the STM32F303RE Nucleo. --- src/stlink-common.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 3256ccd89..4599e6aa8 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1145,6 +1145,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 + || sl->chip_id == STM32_CHIPID_F303_HIGH || sl->chip_id == STM32_CHIPID_F37x || sl->chip_id == STM32_CHIPID_F334) { /* wait for ongoing op to finish */ @@ -1377,8 +1378,11 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); - } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || - sl->chip_id == STM32_CHIPID_F37x || sl->chip_id == STM32_CHIPID_F334) { + } else if (sl->core_id == STM32VL_CORE_ID + || sl->chip_id == STM32_CHIPID_F3 + || sl->chip_id == STM32_CHIPID_F303_HIGH + || sl->chip_id == STM32_CHIPID_F37x + || sl->chip_id == STM32_CHIPID_F334) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || @@ -1682,6 +1686,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || + sl->chip_id == STM32_CHIPID_F303_HIGH || sl->chip_id == STM32_CHIPID_F334 || sl->chip_id == STM32_CHIPID_F37x) { ILOG("Starting Flash write for VL/F0/F3 core id\n"); @@ -1790,6 +1795,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || + sl->chip_id == STM32_CHIPID_F303_HIGH || sl->chip_id == STM32_CHIPID_F37x || sl->chip_id == STM32_CHIPID_F334) { @@ -1853,6 +1859,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || + sl->chip_id == STM32_CHIPID_F303_HIGH || sl->chip_id == STM32_CHIPID_F37x || sl->chip_id == STM32_CHIPID_F334) { From 8c26581f5937a9f6603d3fbcf056f8aedeed3101 Mon Sep 17 00:00:00 2001 From: Robin Kreis Date: Tue, 28 Apr 2015 22:37:01 +0200 Subject: [PATCH 0316/1435] fix typo in stm32l0x flash loader The typo caused errors when flashing an stm32l052. This commit makes stlink-common.c match flashloaders/stm32l0x.s. --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 4599e6aa8..962cddbf5 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1339,7 +1339,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0x04, 0xe0, 0x0c, 0x68, - 0x04, 0x66, + 0x04, 0x60, 0x01, 0x33, 0x04, 0x31, 0x04, 0x30, From eaf4520fc0da817b3fc2f83bcd42460cb7804519 Mon Sep 17 00:00:00 2001 From: Robin Kreis Date: Wed, 29 Apr 2015 09:07:45 +0200 Subject: [PATCH 0317/1435] add some known working targets --- README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README b/README index 922765e1d..7aa3b8b69 100644 --- a/README +++ b/README @@ -182,10 +182,12 @@ Known Working Targets: * STM32F103VC, STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on custom boards (https://github.com/UweBonnes/wiki_fuer_alex/layout/usps...) * STM32F103VET6 (HY-STM32 board) +* STM32F105RCT6 (DecaWave EVB1000 board) * STM32F303xx (STM32F3 Discovery board) * STM32F407xx (STM32F4 Discovery board) * STM32F429I-DISCO (STM32F4 Discovery board with LCD) * STM32F439VIT6 (discovery board reseated CPU) +* STM32L052K8T6 (custom board) * STM32L151CB (custom board) * STM32L152RB (STM32L-Discovery board, custom board) From 0c11337f0211766b1ac31c2f4adb49aa2457aab0 Mon Sep 17 00:00:00 2001 From: Craig Lilley Date: Mon, 4 May 2015 23:16:31 +0100 Subject: [PATCH 0318/1435] Updated the memory map for stm32f42xxx and stm32f43xxx devices. * These devices have up to 256K of sram. * External memory accessed via the FMC controller is now accessible in GDB. --- gdbserver/gdb-server.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 0ddebb06f..5878222d8 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -325,7 +325,11 @@ static const char* const memory_map_template_F4_HD = "" " " // code = sram, bootrom or flash; flash is bigger " " // ccm ram - " " // sram + " " // sram + " " // fmc bank 1 (nor/psram/sram) + " " // fmc bank 2 & 3 (nand flash) + " " // fmc bank 4 (pc card) + " " // fmc sdram bank 1 & 2 " " //Sectors 0..3 " 0x4000" //16kB " " From af4a00a193609cf88b7d144b840d022484351568 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Mon, 18 May 2015 16:55:32 +0200 Subject: [PATCH 0319/1435] Fix F2 memory map This enables GCC to only erase needed pages. --- gdbserver/gdb-server.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 5878222d8..393474dd3 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -345,6 +345,28 @@ static const char* const memory_map_template_F4_HD = " " // option byte area ""; +static const char* const memory_map_template_F2 = + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // sram + " " //Sectors 0..3 + " 0x4000" //16kB + " " + " " //Sector 4 + " 0x10000" //64kB + " " + " " //Sectors 5.. + " 0x20000" //128kB + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + " " // option byte area + ""; + static const char* const memory_map_template = "" "chip_id==STM32_CHIPID_F4_HD) { strcpy(map, memory_map_template_F4_HD); + } else if(sl->chip_id==STM32_CHIPID_F2) { + snprintf(map, 4096, memory_map_template_F2, + sl->flash_size, + sl->sram_size, + sl->flash_size - 0x20000, + sl->sys_base, sl->sys_size); } else { snprintf(map, 4096, memory_map_template, sl->flash_size, From ee62707b4a6ed146dad59123e0ab7d1522dbb558 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Tue, 19 May 2015 16:30:51 +0200 Subject: [PATCH 0320/1435] Add STM32L1xx Cat.2 devices support --- src/stlink-common.c | 47 +++++++++++++++++++++++++-------------------- src/stlink-common.h | 10 ++++++++++ 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 962cddbf5..cbb2f255e 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -463,6 +463,8 @@ int stlink_load_device_params(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) && ( flash_size == 0 )) { sl->flash_size = 128 * 1024; + } else if (sl->chip_id == STM32_CHIPID_L1_CAT2) { + sl->flash_size = (flash_size & 0xff) * 1024; } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_L1_HIGH) { // 0 is 384k and 1 is 256k if ( flash_size == 0 ) { @@ -934,8 +936,9 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) int error = -1; size_t off; int num_empty = 0; - unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) ? 0:0xff; + unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 + || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH + || sl->chip_id == STM32_CHIPID_L152_RE) ? 0:0xff; const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); if (fd == -1) { @@ -1074,9 +1077,9 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) #if DEBUG_FLASH fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); #endif - } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE - || sl->chip_id == STM32_CHIPID_L0) { + } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 + || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH + || sl->chip_id == STM32_CHIPID_L152_RE || sl->chip_id == STM32_CHIPID_L0) { uint32_t val; uint32_t flash_regs_base; @@ -1179,9 +1182,9 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } int stlink_erase_flash_mass(stlink_t *sl) { - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE - || sl->chip_id == STM32_CHIPID_L0) { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 + || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH + || sl->chip_id == STM32_CHIPID_L152_RE || sl->chip_id == STM32_CHIPID_L0) { /* erase each page */ int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -1374,8 +1377,9 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { const uint8_t* loader_code; size_t loader_size; - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) { /* stm32l */ + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 + || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH + || sl->chip_id == STM32_CHIPID_L152_RE) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID @@ -1607,9 +1611,9 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } //STM32F4END - else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE - || sl->chip_id == STM32_CHIPID_L0) { + else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 + || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH + || sl->chip_id == STM32_CHIPID_L152_RE || sl->chip_id == STM32_CHIPID_L0) { /* use fast word write. todo: half page. */ uint32_t val; uint32_t flash_regs_base; @@ -1738,8 +1742,9 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { /* write the file in flash at addr */ int err; unsigned int num_empty = 0, index; - unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE )?0:0xff; + unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 + || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH + || sl->chip_id == STM32_CHIPID_L152_RE) ? 0:0xff; mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { ELOG("map_file() == -1\n"); @@ -1779,9 +1784,9 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE - || sl->chip_id == STM32_CHIPID_L0) { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 + || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH + || sl->chip_id == STM32_CHIPID_L152_RE || sl->chip_id == STM32_CHIPID_L0) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1843,9 +1848,9 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } /* check written byte count */ - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS - || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE - || sl->chip_id == STM32_CHIPID_L0) { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 + || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH + || sl->chip_id == STM32_CHIPID_L152_RE || sl->chip_id == STM32_CHIPID_L0) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; diff --git a/src/stlink-common.h b/src/stlink-common.h index ac267e2ba..a25ca4384 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -117,6 +117,7 @@ extern "C" { #define STM32_CHIPID_L1_MEDIUM_PLUS 0x427 #define STM32_CHIPID_F1_VL_HIGH 0x428 +#define STM32_CHIPID_L1_CAT2 0x429 #define STM32_CHIPID_F1_XL 0x430 @@ -264,6 +265,15 @@ extern "C" { .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000 }, + { + .chip_id = STM32_CHIPID_L1_CAT2, + .description = "L1 Cat.2 device", + .flash_size_reg = 0x1ff8004c, + .flash_pagesize = 0x100, + .sram_size = 0x8000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, { .chip_id = STM32_CHIPID_L1_MEDIUM_PLUS, .description = "L1 Medium-Plus-density device", From 71535104e47f2a96ce6a87a6da0fc4519bc64d15 Mon Sep 17 00:00:00 2001 From: Andy Isaacson Date: Tue, 9 Jun 2015 11:15:28 -0700 Subject: [PATCH 0321/1435] STM32F4 8-bit support for 1.8v operation Per ST doc DM00035129.pdf "DocID022063 Rev 5", the STM32F415xx data sheet, table 40 on page 110 of the PDF, 32-bit program operation is only possible above 2.7 Volts. In order to support programming on devices running at lower voltages, this commit adds an 8-bit programming mode and the necessary tests to enable it when the reported voltage is below 2.7 Volts. --- flashloaders/stm32f4lv.s | 33 +++++++++++++++++++++++++++ src/stlink-common.c | 49 +++++++++++++++++++++++++++++++++++----- 2 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 flashloaders/stm32f4lv.s diff --git a/flashloaders/stm32f4lv.s b/flashloaders/stm32f4lv.s new file mode 100644 index 000000000..f60ee8797 --- /dev/null +++ b/flashloaders/stm32f4lv.s @@ -0,0 +1,33 @@ +.global start +.syntax unified + +@ r0 = source +@ r1 = target +@ r2 = wordcount +@ r3 = flash_base +@ r4 = temp + +start: + lsls r2, r2, #2 + ldr r3, flash_base +next: + cbz r2, done + ldrb r4, [r0] + strb r4, [r1] + +wait: + ldrh r4, [r3, #0x0e] + tst.w r4, #1 + bne wait + + add r0, #1 + add r1, #1 + sub r2, #1 + b next +done: + bkpt + +.align 2 + +flash_base: + .word 0x40023c00 diff --git a/src/stlink-common.c b/src/stlink-common.c index cbb2f255e..972c9f31c 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -65,6 +65,7 @@ //STM32L0x flash register base and offsets //same as 32L1 above +// RM0090 - DM00031020.pdf #define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) #define FLASH_ACR_OFF ((uint32_t) 0x00) #define FLASH_PECR_OFF ((uint32_t) 0x04) @@ -1374,6 +1375,29 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0x00, 0x3c, 0x02, 0x40, }; + static const uint8_t loader_code_stm32f4_lv[] = { + // flashloaders/stm32f4lv.s + 0x92, 0x00, + + 0x08, 0x4b, + 0x62, 0xb1, + 0x04, 0x78, + 0x0c, 0x70, + + 0xdc, 0x89, + 0x14, 0xf0, 0x01, 0x0f, + 0xfb, 0xd1, + 0x00, 0xf1, 0x01, 0x00, + 0x01, 0xf1, 0x01, 0x01, + 0xa2, 0xf1, 0x01, 0x02, + 0xf1, 0xe7, + + 0x00, 0xbe, + 0x00, 0xbf, + + 0x00, 0x3c, 0x02, 0x40, + }; + const uint8_t* loader_code; size_t loader_size; @@ -1391,15 +1415,21 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE)){ - loader_code = loader_code_stm32f4; - loader_size = sizeof(loader_code_stm32f4); + int voltage = stlink_target_voltage(sl); + if (voltage > 2700) { + loader_code = loader_code_stm32f4; + loader_size = sizeof(loader_code_stm32f4); + } else { + loader_code = loader_code_stm32f4_lv; + loader_size = sizeof(loader_code_stm32f4_lv); + } } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F04 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL || sl->chip_id == STM32_CHIPID_F09X) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); } else if (sl->chip_id == STM32_CHIPID_L0) { - loader_code = loader_code_stm32l0; - loader_size = sizeof(loader_code_stm32l0); - } else { + loader_code = loader_code_stm32l0; + loader_size = sizeof(loader_code_stm32l0); + } else { ELOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); return -1; } @@ -1588,7 +1618,14 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t /* TODO: Check that Voltage range is 2.7 - 3.6 V */ /* set parallelisim to 32 bit*/ - write_flash_cr_psiz(sl, 2); + int voltage = stlink_target_voltage(sl); + if (voltage > 2700) { + printf("enabling 32-bit flash writes\n"); + write_flash_cr_psiz(sl, 2); + } else { + printf("Target voltage (%d mV) too low for 32-bit flash, using 8-bit flash writes\n", voltage); + write_flash_cr_psiz(sl, 0); + } /* set programming mode */ set_flash_cr_pg(sl); From 972ed48924fc1f118939b013e0b15f0faed1f26a Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Fri, 17 Jul 2015 11:55:28 +0300 Subject: [PATCH 0322/1435] Basic support for F446 --- src/stlink-common.c | 51 ++++++++++++++++++++++++++++++--------------- src/stlink-common.h | 11 ++++++++++ 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 972c9f31c..343795aeb 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -153,7 +153,8 @@ static inline uint32_t read_flash_obr(stlink_t *sl) { static inline uint32_t read_flash_cr(stlink_t *sl) { uint32_t res; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||(sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) res = stlink_read_debug32(sl, FLASH_F4_CR); else res = stlink_read_debug32(sl, FLASH_CR); @@ -166,7 +167,8 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) ) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK); else return read_flash_cr(sl) & (1 << FLASH_CR_LOCK); @@ -179,7 +181,8 @@ static void unlock_flash(stlink_t *sl) { the FPEC block until next reset. */ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) { stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); } else { @@ -205,7 +208,8 @@ static int unlock_flash_if(stlink_t *sl) { static void lock_flash(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) { const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); stlink_write_debug32(sl, FLASH_F4_CR, n); } else { @@ -218,7 +222,8 @@ static void lock_flash(stlink_t *sl) { static void set_flash_cr_pg(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_CR_PG); stlink_write_debug32(sl, FLASH_F4_CR, x); @@ -231,7 +236,8 @@ static void set_flash_cr_pg(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) stlink_write_debug32(sl, FLASH_F4_CR, n); else stlink_write_debug32(sl, FLASH_CR, n); @@ -249,7 +255,8 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { static void set_flash_cr_mer(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); else @@ -259,7 +266,8 @@ static void set_flash_cr_mer(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); else @@ -269,7 +277,8 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { static void set_flash_cr_strt(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_F4_CR_STRT); stlink_write_debug32(sl, FLASH_F4_CR, x); @@ -286,7 +295,8 @@ static inline uint32_t read_flash_acr(stlink_t *sl) { static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) res = stlink_read_debug32(sl, FLASH_F4_SR); else res = stlink_read_debug32(sl, FLASH_SR); @@ -296,7 +306,8 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { static inline unsigned int is_flash_busy(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY); else return read_flash_sr(sl) & (1 << FLASH_SR_BSY); @@ -1027,7 +1038,8 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector>= 12) { sector -= 12; @@ -1048,7 +1060,8 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE)) { + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1414,7 +1427,8 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || - sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE)){ + sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)){ int voltage = stlink_target_voltage(sl); if (voltage > 2700) { loader_code = loader_code_stm32f4; @@ -1603,7 +1617,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || - (sl->chip_id == STM32_CHIPID_F411RE)) { + (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) { /* todo: check write operation */ ILOG("Starting Flash write for F2/F4\n"); @@ -1852,7 +1867,8 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || - sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE)) { + sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1912,7 +1928,8 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || - sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE)) { + sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) || + (sl->chip_id == STM32_CHIPID_F446)) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { diff --git a/src/stlink-common.h b/src/stlink-common.h index a25ca4384..c3ac48d03 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -110,6 +110,7 @@ extern "C" { #define STM32_CHIPID_F4_HD 0x419 #define STM32_CHIPID_F1_VL_MEDIUM_LOW 0x420 +#define STM32_CHIPID_F446 0x421 #define STM32_CHIPID_F3 0x422 #define STM32_CHIPID_F4_LP 0x423 @@ -319,6 +320,16 @@ extern "C" { .bootrom_base = 0x1ffff000, .bootrom_size = 0x800 }, + { + // STM32F446x family. Support based on DM00135183.pdf (RM0390) document. + .chip_id = STM32_CHIPID_F446, + .description = "F446 device", + .flash_size_reg = 0x1fff7a22, + .flash_pagesize = 0x20000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, { // This is STK32F303VCT6 device from STM32 F3 Discovery board. // Support based on DM00043574.pdf (RM0316) document. From 98a41fa9c08605ac90200b9583f171eea0e08dd2 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Fri, 17 Jul 2015 12:34:37 +0300 Subject: [PATCH 0323/1435] GDN server: F446 support --- gdbserver/gdb-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 393474dd3..a7f3c6cba 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -388,7 +388,7 @@ char* make_memory_map(stlink_t *sl) { char* map = malloc(4096); map[0] = '\0'; - if(sl->chip_id==STM32_CHIPID_F4) { + if(sl->chip_id==STM32_CHIPID_F4 || sl->chip_id==STM32_CHIPID_F446) { strcpy(map, memory_map_template_F4); } else if(sl->chip_id==STM32_CHIPID_F4_HD) { strcpy(map, memory_map_template_F4_HD); From 67fd44b8370cca4994752df8abf0e2c45fdf995d Mon Sep 17 00:00:00 2001 From: Dave Vandervies Date: Sat, 18 Jul 2015 16:25:11 -0400 Subject: [PATCH 0324/1435] Add STM32L4 to CHIPID #defines and devices[] --- src/stlink-common.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/stlink-common.h b/src/stlink-common.h index c3ac48d03..3fceeef62 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -103,7 +103,7 @@ extern "C" { #define STM32_CHIPID_F1_LOW 0x412 #define STM32_CHIPID_F4 0x413 #define STM32_CHIPID_F1_HIGH 0x414 - +#define STM32_CHIPID_L4 0x415 /* Seen on L4x6 (RM0351) */ #define STM32_CHIPID_L1_MEDIUM 0x416 #define STM32_CHIPID_L0 0x417 #define STM32_CHIPID_F1_CONN 0x418 @@ -466,6 +466,20 @@ extern "C" { .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory .bootrom_size = 0x2000 }, + { + // STM32L4x6 + // From RM0351. + .chip_id = STM32_CHIPID_L4, + .description = "L4 device", + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1671) + .flash_pagesize = 0x800, // 2K (sec 3.2, page 78; also appears in sec 3.3.1 and tables 4-6 on pages 79-81) + // SRAM1 is "up to" 96k in the standard Cortex-M memory map; + // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) + .sram_size = 0x18000, + .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000 // 28k (per bank), same source as base + }, }; From ab464492f7774ce5c005c026b68479c49c16fa8d Mon Sep 17 00:00:00 2001 From: Dave Vandervies Date: Sun, 19 Jul 2015 22:58:43 -0400 Subject: [PATCH 0325/1435] Add supprt for STM32L4 flash driver No loader yet, but we can erase! --- src/stlink-common.c | 114 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 103 insertions(+), 11 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 343795aeb..07b8d6765 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -63,6 +63,28 @@ #define FLASH_L1_FPRG 10 #define FLASH_L1_PROG 3 +//32L4 register base is at FLASH_REGS_ADDR (0x40022000) +#define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) +#define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) +#define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) +#define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) + +#define STM32L4_FLASH_SR_BSY 16 +#define STM32L4_FLASH_SR_ERRMASK 0x3f8 /* SR [9:3] */ + +#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ +#define STM32L4_FLASH_CR_PG 0 /* Program */ +#define STM32L4_FLASH_CR_PER 1 /* Page erase */ +#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ +#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ +#define STM32L4_FLASH_CR_STRT 16 /* Start command */ +#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ +#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ +// Page is fully specified by BKER and PNB +#define STM32L4_FLASH_CR_PAGEMASK (0x1fflu << STM32L4_FLASH_CR_PNB) + +#define STM32L4_FLASH_OPTR_DUALBANK 21 + //STM32L0x flash register base and offsets //same as 32L1 above // RM0090 - DM00031020.pdf @@ -156,6 +178,8 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || (sl->chip_id == STM32_CHIPID_F446)) res = stlink_read_debug32(sl, FLASH_F4_CR); + else if (sl->chip_id == STM32_CHIPID_L4) + res = stlink_read_debug32(sl, STM32L4_FLASH_CR); else res = stlink_read_debug32(sl, FLASH_CR); #if DEBUG_FLASH @@ -166,12 +190,16 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ + uint32_t cr = read_flash_cr(sl); + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || (sl->chip_id == STM32_CHIPID_F446)) - return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK); + return cr & (1 << FLASH_F4_CR_LOCK); + else if (sl->chip_id == STM32_CHIPID_L4) + return cr & (1lu << STM32L4_FLASH_CR_LOCK); else - return read_flash_cr(sl) & (1 << FLASH_CR_LOCK); + return cr & (1 << FLASH_CR_LOCK); } static void unlock_flash(stlink_t *sl) { @@ -185,6 +213,9 @@ static void unlock_flash(stlink_t *sl) { (sl->chip_id == STM32_CHIPID_F446)) { stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); + } else if (sl->chip_id == STM32_CHIPID_L4) { + stlink_write_debug32(sl, STM32L4_FLASH_KEYR, FLASH_KEY1); + stlink_write_debug32(sl, STM32L4_FLASH_KEYR, FLASH_KEY2); } else { stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY1); stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY2); @@ -212,6 +243,9 @@ static void lock_flash(stlink_t *sl) { (sl->chip_id == STM32_CHIPID_F446)) { const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); stlink_write_debug32(sl, FLASH_F4_CR, n); + } else if (sl->chip_id == STM32_CHIPID_L4) { + const uint32_t n = read_flash_cr(sl) | (1lu << STM32L4_FLASH_CR_LOCK); + stlink_write_debug32(sl, STM32L4_FLASH_CR, n); } else { /* write to 1 only. reset by hw at unlock sequence */ const uint32_t n = read_flash_cr(sl) | (1 << FLASH_CR_LOCK); @@ -227,6 +261,10 @@ static void set_flash_cr_pg(stlink_t *sl) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_CR_PG); stlink_write_debug32(sl, FLASH_F4_CR, x); + } else if (sl->chip_id == STM32_CHIPID_L4) { + uint32_t x = read_flash_cr(sl); + x |= (1 << STM32L4_FLASH_CR_PG); + stlink_write_debug32(sl, STM32L4_FLASH_CR, x); } else { const uint32_t n = 1 << FLASH_CR_PG; stlink_write_debug32(sl, FLASH_CR, n); @@ -244,8 +282,14 @@ static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { } static void set_flash_cr_per(stlink_t *sl) { - const uint32_t n = 1 << FLASH_CR_PER; - stlink_write_debug32(sl, FLASH_CR, n); + if (sl->chip_id == STM32_CHIPID_L4) { + uint32_t n = read_flash_cr(sl); + n |= (1lu << STM32L4_FLASH_CR_PER); + stlink_write_debug32(sl, STM32L4_FLASH_CR, n); + } else { + const uint32_t n = 1 << FLASH_CR_PER; + stlink_write_debug32(sl, FLASH_CR, n); + } } static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { @@ -259,6 +303,11 @@ static void set_flash_cr_mer(stlink_t *sl) { (sl->chip_id == STM32_CHIPID_F446)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); + else if (sl->chip_id == STM32_CHIPID_L4) + stlink_write_debug32(sl, STM32L4_FLASH_CR, + stlink_read_debug32(sl, STM32L4_FLASH_CR) | + (1lu << STM32L4_FLASH_CR_MER1) | + (1lu << STM32L4_FLASH_CR_MER2)); else stlink_write_debug32(sl, FLASH_CR, stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_MER)); @@ -282,6 +331,10 @@ static void set_flash_cr_strt(stlink_t *sl) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_F4_CR_STRT); stlink_write_debug32(sl, FLASH_F4_CR, x); + } else if (sl->chip_id == STM32_CHIPID_L4) { + uint32_t x = read_flash_cr(sl); + x |= (1lu << STM32L4_FLASH_CR_STRT); + stlink_write_debug32(sl, STM32L4_FLASH_CR, x); } else { stlink_write_debug32(sl, FLASH_CR, stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_STRT) ); @@ -298,6 +351,8 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || (sl->chip_id == STM32_CHIPID_F446)) res = stlink_read_debug32(sl, FLASH_F4_SR); + else if (sl->chip_id == STM32_CHIPID_L4) + res = stlink_read_debug32(sl, STM32L4_FLASH_SR); else res = stlink_read_debug32(sl, FLASH_SR); //fprintf(stdout, "SR:0x%x\n", *(uint32_t*) sl->q_buf); @@ -309,6 +364,8 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || (sl->chip_id == STM32_CHIPID_F446)) return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY); + else if (sl->chip_id == STM32_CHIPID_L4) + return read_flash_sr(sl) & (1 << STM32L4_FLASH_SR_BSY); else return read_flash_sr(sl) & (1 << FLASH_SR_BSY); } @@ -375,6 +432,17 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { stlink_write_debug32(sl, FLASH_F4_CR, x); } +static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { + uint32_t x = read_flash_cr(sl); + x &=~ STM32L4_FLASH_CR_PAGEMASK; + x |= (n << STM32L4_FLASH_CR_PNB); + x |= (1lu << STM32L4_FLASH_CR_PER); +#if DEBUG_FLASH + fprintf(stdout, "BKER:PNB:0x%x 0x%x\n", x, n); +#endif + stlink_write_debug32(sl, STM32L4_FLASH_CR, x); +} + // Delegates to the backends... void stlink_close(stlink_t *sl) { @@ -1036,6 +1104,23 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ } +// Returns BKER:PNB for the given page address +uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { + uint32_t bker = 0; + uint32_t flashopt = stlink_read_debug32(sl, STM32L4_FLASH_OPTR); + flashaddr -= STM32_FLASH_BASE; + if (flashopt & (1lu << STM32L4_FLASH_OPTR_DUALBANK)) { + uint32_t banksize = sl->flash_size / 2; + if (flashaddr > banksize) { + flashaddr -= banksize; + bker = 0x100; + } + } + // For 1MB chips without the dual-bank option set, the page address will + // overflow into the BKER bit, which gives us the correct bank:page value. + return bker | flashaddr/sl->flash_pgsz; +} + uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || @@ -1061,7 +1146,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_L4)) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1069,15 +1154,22 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) unlock_flash_if(sl); /* select the page to erase */ - // calculate the actual page from the address - uint32_t sector=calculate_F4_sectornum(flashaddr); + if (sl->chip_id == STM32_CHIPID_L4) { + // calculate the actual bank+page from the address + uint32_t page = calculate_L4_page(sl, flashaddr); - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x\n", sector, stlink_calculate_pagesize(sl, flashaddr)); + write_flash_cr_bker_pnb(sl, page); + } else { + // calculate the actual page from the address + uint32_t sector=calculate_F4_sectornum(flashaddr); + + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x\n", sector, stlink_calculate_pagesize(sl, flashaddr)); - //the SNB values for flash sectors in the second bank do not directly follow the values for the first bank on 2mb devices... - if (sector >= 12) sector += 4; + //the SNB values for flash sectors in the second bank do not directly follow the values for the first bank on 2mb devices... + if (sector >= 12) sector += 4; - write_flash_cr_snb(sl, sector); + write_flash_cr_snb(sl, sector); + } /* start erase operation */ set_flash_cr_strt(sl); From 0419b8bec68b08acee490b4f0fcd35f9c7f4a496 Mon Sep 17 00:00:00 2001 From: Dave Vandervies Date: Mon, 20 Jul 2015 15:15:25 -0400 Subject: [PATCH 0326/1435] Flash loader for STM32L4 --- flashloaders/stm32l4.s | 39 +++++++++++++++++++++++++++++ src/stlink-common.c | 57 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 flashloaders/stm32l4.s diff --git a/flashloaders/stm32l4.s b/flashloaders/stm32l4.s new file mode 100644 index 000000000..4b908633d --- /dev/null +++ b/flashloaders/stm32l4.s @@ -0,0 +1,39 @@ +.global start +.syntax unified + +@ Adapted from stm32f4.s +@ STM32L4's flash controller expects double-word writes, has the flash +@ controller mapped in a different location with the registers we care about +@ moved down from the base address, and has BSY moved to bit 16 of SR. +@ r0 = source +@ r1 = target +@ r2 = wordcount +@ r3 = flash_base +@ r4 = temp +@ r5 = temp + +start: + ldr r3, flash_base +next: + cbz r2, done + ldr r4, [r0] /* copy doubleword from source to target */ + ldr r5, [r0, #4] + str r4, [r1] + str r5, [r1, #4] + +wait: + ldrh r4, [r3, #0x12] /* high half of status register */ + tst r4, #1 /* BSY = bit 16 */ + bne wait + + add r0, #8 + add r1, #8 + sub r2, #2 + b next +done: + bkpt + +.align 2 + +flash_base: + .word 0x40022000 diff --git a/src/stlink-common.c b/src/stlink-common.c index 07b8d6765..37beb905f 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1503,6 +1503,25 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0x00, 0x3c, 0x02, 0x40, }; + static const uint8_t loader_code_stm32l4[] = { + // flashloaders/stm32l4.s + 0x08, 0x4b, // start: ldr r3, [pc, #32] ; + 0x72, 0xb1, // next: cbz r2, + 0x04, 0x68, // ldr r4, [r0, #0] + 0x45, 0x68, // ldr r5, [r0, #4] + 0x0c, 0x60, // str r4, [r1, #0] + 0x4d, 0x60, // str r5, [r1, #4] + 0x5c, 0x8a, // wait: ldrh r4, [r3, #18] + 0x14, 0xf0, 0x01, 0x0f, // tst.w r4, #1 + 0xfb, 0xd1, // bne.n + 0x00, 0xf1, 0x08, 0x00, // add.w r0, r0, #8 + 0x01, 0xf1, 0x08, 0x01, // add.w r1, r1, #8 + 0xa2, 0xf1, 0x02, 0x02, // add.w r2, r2, #2 + 0xef, 0xe7, // b.n + 0x00, 0xbe, // done: bkpt 0x0000 + 0x00, 0x20, 0x02, 0x40 // flash_base: .word 0x40022000 + }; + const uint8_t* loader_code; size_t loader_size; @@ -1535,6 +1554,9 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { } else if (sl->chip_id == STM32_CHIPID_L0) { loader_code = loader_code_stm32l0; loader_size = sizeof(loader_code_stm32l0); + } else if (sl->chip_id == STM32_CHIPID_L4) { + loader_code = loader_code_stm32l4; + loader_size = sizeof(loader_code_stm32l4); } else { ELOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); return -1; @@ -1710,10 +1732,11 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) { + (sl->chip_id == STM32_CHIPID_F446) || + (sl->chip_id == STM32_CHIPID_L4)) { /* todo: check write operation */ - ILOG("Starting Flash write for F2/F4\n"); + ILOG("Starting Flash write for F2/F4/L4\n"); /* flash loader initialization */ if (init_flash_loader(sl, &fl) == -1) { ELOG("init_flash_loader() == -1\n"); @@ -1724,14 +1747,23 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t unlock_flash_if(sl); /* TODO: Check that Voltage range is 2.7 - 3.6 V */ - /* set parallelisim to 32 bit*/ - int voltage = stlink_target_voltage(sl); - if (voltage > 2700) { - printf("enabling 32-bit flash writes\n"); - write_flash_cr_psiz(sl, 2); + if (sl->chip_id != STM32_CHIPID_L4) { + /* set parallelisim to 32 bit*/ + int voltage = stlink_target_voltage(sl); + if (voltage > 2700) { + printf("enabling 32-bit flash writes\n"); + write_flash_cr_psiz(sl, 2); + } else { + printf("Target voltage (%d mV) too low for 32-bit flash, using 8-bit flash writes\n", voltage); + write_flash_cr_psiz(sl, 0); + } } else { - printf("Target voltage (%d mV) too low for 32-bit flash, using 8-bit flash writes\n", voltage); - write_flash_cr_psiz(sl, 0); + /* L4 does not have a byte-write mode */ + int voltage = stlink_target_voltage(sl); + if (voltage <= 2700) { + printf("Target voltage (%d mV) too low for flash writes!\n", voltage); + return -1; + } } /* set programming mode */ @@ -1960,10 +1992,13 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_L4)) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; + if (sl->chip_id == STM32_CHIPID_L4) { + if (count % 2) ++count; + } /* setup core */ stlink_write_reg(sl, fl->buf_addr, 0); /* source */ @@ -2021,7 +2056,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_L4)) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { From bc3d61adc399f7f3c6f67e387187825769ea2a75 Mon Sep 17 00:00:00 2001 From: Dave Vandervies Date: Mon, 20 Jul 2015 15:25:48 -0400 Subject: [PATCH 0327/1435] Clear STM32L4 PER,MER,PG bits The controller doesn't clear them automatically when the operation finishes, so to avoid getting errors we need to clear them manually before we request another operation. --- src/stlink-common.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 37beb905f..8c9d4090a 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -80,6 +80,10 @@ #define STM32L4_FLASH_CR_STRT 16 /* Start command */ #define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ #define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ +// Bits requesting flash operations (useful when we want to clear them) +#define STM32L4_FLASH_CR_OPBITS \ + ((1lu<chip_id == STM32_CHIPID_L4) { uint32_t x = read_flash_cr(sl); + x &=~ STM32L4_FLASH_CR_OPBITS; x |= (1 << STM32L4_FLASH_CR_PG); stlink_write_debug32(sl, STM32L4_FLASH_CR, x); } else { @@ -282,14 +287,8 @@ static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { } static void set_flash_cr_per(stlink_t *sl) { - if (sl->chip_id == STM32_CHIPID_L4) { - uint32_t n = read_flash_cr(sl); - n |= (1lu << STM32L4_FLASH_CR_PER); - stlink_write_debug32(sl, STM32L4_FLASH_CR, n); - } else { - const uint32_t n = 1 << FLASH_CR_PER; - stlink_write_debug32(sl, FLASH_CR, n); - } + const uint32_t n = 1 << FLASH_CR_PER; + stlink_write_debug32(sl, FLASH_CR, n); } static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { @@ -303,12 +302,12 @@ static void set_flash_cr_mer(stlink_t *sl) { (sl->chip_id == STM32_CHIPID_F446)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); - else if (sl->chip_id == STM32_CHIPID_L4) - stlink_write_debug32(sl, STM32L4_FLASH_CR, - stlink_read_debug32(sl, STM32L4_FLASH_CR) | - (1lu << STM32L4_FLASH_CR_MER1) | - (1lu << STM32L4_FLASH_CR_MER2)); - else + else if (sl->chip_id == STM32_CHIPID_L4) { + uint32_t x = stlink_read_debug32(sl, STM32L4_FLASH_CR); + x &=~ STM32L4_FLASH_CR_OPBITS; + x |= (1lu << STM32L4_FLASH_CR_MER1) | (1lu << STM32L4_FLASH_CR_MER2); + stlink_write_debug32(sl, STM32L4_FLASH_CR, x); + } else stlink_write_debug32(sl, FLASH_CR, stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_MER)); } @@ -434,6 +433,7 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { uint32_t x = read_flash_cr(sl); + x &=~ STM32L4_FLASH_CR_OPBITS; x &=~ STM32L4_FLASH_CR_PAGEMASK; x |= (n << STM32L4_FLASH_CR_PNB); x |= (1lu << STM32L4_FLASH_CR_PER); From 6d3f105d2a38e8805cf2f3502e88e88713907bac Mon Sep 17 00:00:00 2001 From: texane Date: Sat, 8 Aug 2015 16:03:49 +0200 Subject: [PATCH 0328/1435] FIX: "unaligned addr or size" in attempt of write the program in the RAM (#323) --- src/stlink-common.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 8c9d4090a..7bf6f7263 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -953,6 +953,7 @@ int stlink_fwrite_sram int error = -1; size_t off; + size_t len; mapped_file_t mf = MAPPED_FILE_INITIALIZER; @@ -971,16 +972,23 @@ int stlink_fwrite_sram } else if ((addr + mf.len) > (sl->sram_base + sl->sram_size)) { fprintf(stderr, "addr too high\n"); goto on_error; - } else if ((addr & 3) || (mf.len & 3)) { + } else if (addr & 3) { /* todo */ - fprintf(stderr, "unaligned addr or size\n"); + fprintf(stderr, "unaligned addr\n"); goto on_error; } + + len = mf.len; + + if(len & 3) { + len -= len & 3; + } + /* do the copy by 1k blocks */ - for (off = 0; off < mf.len; off += 1024) { + for (off = 0; off < len; off += 1024) { size_t size = 1024; - if ((off + size) > mf.len) - size = mf.len - off; + if ((off + size) > len) + size = len - off; memcpy(sl->q_buf, mf.base + off, size); @@ -991,6 +999,11 @@ int stlink_fwrite_sram stlink_write_mem32(sl, addr + off, size); } + if(mf.len > len) { + memcpy(sl->q_buf, mf.base + len, mf.len - len); + stlink_write_mem8(sl, addr + len, mf.len - len); + } + /* check the file ha been written */ if (check_file(sl, &mf, addr) == -1) { fprintf(stderr, "check_file() == -1\n"); From f83ed07f4512a05dcf4481c54aeae23ea522d2f1 Mon Sep 17 00:00:00 2001 From: Max Chen Date: Thu, 13 Aug 2015 14:24:09 +0800 Subject: [PATCH 0329/1435] fix can not flash STM32_F3_SMALL --- src/stlink-common.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index 7bf6f7263..3964d40e0 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1267,6 +1267,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 + || sl->chip_id == STM32_CHIPID_F3_SMALL || sl->chip_id == STM32_CHIPID_F303_HIGH || sl->chip_id == STM32_CHIPID_F37x || sl->chip_id == STM32_CHIPID_F334) { @@ -1545,6 +1546,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 + || sl->chip_id == STM32_CHIPID_F3_SMALL || sl->chip_id == STM32_CHIPID_F303_HIGH || sl->chip_id == STM32_CHIPID_F37x || sl->chip_id == STM32_CHIPID_F334) { @@ -1879,6 +1881,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || + sl->chip_id == STM32_CHIPID_F3_SMALL || sl->chip_id == STM32_CHIPID_F303_HIGH || sl->chip_id == STM32_CHIPID_F334 || sl->chip_id == STM32_CHIPID_F37x) { @@ -1989,6 +1992,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || + sl->chip_id == STM32_CHIPID_F3_SMALL || sl->chip_id == STM32_CHIPID_F303_HIGH || sl->chip_id == STM32_CHIPID_F37x || sl->chip_id == STM32_CHIPID_F334) { @@ -2057,6 +2061,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || + sl->chip_id == STM32_CHIPID_F3_SMALL || sl->chip_id == STM32_CHIPID_F303_HIGH || sl->chip_id == STM32_CHIPID_F37x || sl->chip_id == STM32_CHIPID_F334) { From 7fbd79eef39af26ba53d8117b8f80fc70b07ebd5 Mon Sep 17 00:00:00 2001 From: mlundinse Date: Thu, 13 Aug 2015 19:15:23 +0200 Subject: [PATCH 0330/1435] Added STM32F7 Support --- gdbserver/gdb-server.c | 26 +++++++++++++++++++++ src/stlink-common.c | 51 +++++++++++++++++++++++++++++------------- src/stlink-common.h | 12 ++++++++++ 3 files changed, 74 insertions(+), 15 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index a7f3c6cba..bae496d31 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -383,6 +383,30 @@ static const char* const memory_map_template = " " // option byte area ""; +static const char* const memory_map_template_F7 = + "" + "" + "" + " " // ITCM ram 16kB + " " // ITCM flash + " " // sram + " " // Sectors 0..3 + " 0x8000" // 32kB + " " + " " // Sector 4 + " 0x20000" // 128kB + " " + " " // Sectors 5..7 + " 0x40000" // 128kB + " " + " " // peripheral regs + " " // AHB3 Peripherals + " " // cortex regs + " " // bootrom + " " // option byte area + ""; + char* make_memory_map(stlink_t *sl) { /* This will be freed in serve() */ char* map = malloc(4096); @@ -390,6 +414,8 @@ char* make_memory_map(stlink_t *sl) { if(sl->chip_id==STM32_CHIPID_F4 || sl->chip_id==STM32_CHIPID_F446) { strcpy(map, memory_map_template_F4); + } else if(sl->chip_id==STM32_CHIPID_F4 || sl->chip_id==STM32_CHIPID_F7) { + strcpy(map, memory_map_template_F7); } else if(sl->chip_id==STM32_CHIPID_F4_HD) { strcpy(map, memory_map_template_F4_HD); } else if(sl->chip_id==STM32_CHIPID_F2) { diff --git a/src/stlink-common.c b/src/stlink-common.c index 7bf6f7263..dc24161d8 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -180,7 +180,7 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { uint32_t res; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||(sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) res = stlink_read_debug32(sl, FLASH_F4_CR); else if (sl->chip_id == STM32_CHIPID_L4) res = stlink_read_debug32(sl, STM32L4_FLASH_CR); @@ -198,7 +198,7 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) return cr & (1 << FLASH_F4_CR_LOCK); else if (sl->chip_id == STM32_CHIPID_L4) return cr & (1lu << STM32L4_FLASH_CR_LOCK); @@ -214,7 +214,7 @@ static void unlock_flash(stlink_t *sl) { */ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) { stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); } else if (sl->chip_id == STM32_CHIPID_L4) { @@ -244,7 +244,7 @@ static int unlock_flash_if(stlink_t *sl) { static void lock_flash(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) { const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); stlink_write_debug32(sl, FLASH_F4_CR, n); } else if (sl->chip_id == STM32_CHIPID_L4) { @@ -261,7 +261,7 @@ static void lock_flash(stlink_t *sl) { static void set_flash_cr_pg(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_CR_PG); stlink_write_debug32(sl, FLASH_F4_CR, x); @@ -280,7 +280,7 @@ static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) stlink_write_debug32(sl, FLASH_F4_CR, n); else stlink_write_debug32(sl, FLASH_CR, n); @@ -299,7 +299,7 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { static void set_flash_cr_mer(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); else if (sl->chip_id == STM32_CHIPID_L4) { @@ -315,7 +315,7 @@ static void set_flash_cr_mer(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); else @@ -326,7 +326,7 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { static void set_flash_cr_strt(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_F4_CR_STRT); stlink_write_debug32(sl, FLASH_F4_CR, x); @@ -348,7 +348,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) res = stlink_read_debug32(sl, FLASH_F4_SR); else if (sl->chip_id == STM32_CHIPID_L4) res = stlink_read_debug32(sl, STM32L4_FLASH_SR); @@ -361,7 +361,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { static inline unsigned int is_flash_busy(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY); else if (sl->chip_id == STM32_CHIPID_L4) return read_flash_sr(sl) & (1 << STM32L4_FLASH_SR_BSY); @@ -1137,7 +1137,7 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector>= 12) { sector -= 12; @@ -1159,7 +1159,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_L4)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_L4)) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1535,6 +1535,23 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0x00, 0x20, 0x02, 0x40 // flash_base: .word 0x40022000 }; + static const uint8_t loader_code_stm32f7[] = { + 0x08, 0x4b, + 0x72, 0xb1, + 0x04, 0x68, + 0x0c, 0x60, + 0xbf, 0xf3, 0x4f, 0x8f, // DSB Memory barrier for in order flash write + 0xdc, 0x89, + 0x14, 0xf0, 0x01, 0x0f, + 0xfb, 0xd1, + 0x00, 0xf1, 0x04, 0x00, + 0x01, 0xf1, 0x04, 0x01, + 0xa2, 0xf1, 0x01, 0x02, + 0xef, 0xe7, + 0x00, 0xbe, // bkpt #0x00 + 0x00, 0x3c, 0x02, 0x40, + }; + const uint8_t* loader_code; size_t loader_size; @@ -1561,6 +1578,9 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { loader_code = loader_code_stm32f4_lv; loader_size = sizeof(loader_code_stm32f4_lv); } + } else if (sl->chip_id == STM32_CHIPID_F7){ + loader_code = loader_code_stm32f7; + loader_size = sizeof(loader_code_stm32f7); } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F04 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL || sl->chip_id == STM32_CHIPID_F09X) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); @@ -1746,6 +1766,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || (sl->chip_id == STM32_CHIPID_F446) || + (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_L4)) { /* todo: check write operation */ @@ -2005,7 +2026,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_L4)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_L4)) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -2069,7 +2090,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_L4)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_L4)) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { diff --git a/src/stlink-common.h b/src/stlink-common.h index 3fceeef62..76f977e9b 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -140,6 +140,8 @@ extern "C" { #define STM32_CHIPID_F0_CAN 0x448 +#define STM32_CHIPID_F7 0x449 + /* * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" * and some that are called "High". 0x427 is assigned to the other "Medium- @@ -174,6 +176,16 @@ extern "C" { // 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[] = { + { + //RM0385 and DS10916 document was used to find these paramaters + .chip_id = STM32_CHIPID_F7, + .description = "F7 device", + .flash_size_reg = 0x1ff0f442, // section 41.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 + .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 + .bootrom_size = 0xEDC0 // "System memory" byte size in hex from DS Fig 18 + }, { // table 2, PM0063 .chip_id = STM32_CHIPID_F1_MEDIUM, .description = "F1 Medium-density device", From 21f87f56c419682072fcf64ec2f02877305eef55 Mon Sep 17 00:00:00 2001 From: mlundinse Date: Sat, 15 Aug 2015 18:56:40 +0200 Subject: [PATCH 0331/1435] Correct flash sector numbers and sizes for STM32F7 --- src/stlink-common.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index dc24161d8..53e5e9e70 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1117,6 +1117,14 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ } +uint32_t calculate_F7_sectornum(uint32_t flashaddr){ + flashaddr &= ~STM32_FLASH_BASE; //Page now holding the actual flash address + if(flashaddr<0x20000) return(flashaddr/0x8000); + else if(flashaddr<0x40000) return(4); + else return(flashaddr/0x40000) +4; + +} + // Returns BKER:PNB for the given page address uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { uint32_t bker = 0; @@ -1137,7 +1145,7 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) { + (sl->chip_id == STM32_CHIPID_F446)) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector>= 12) { sector -= 12; @@ -1146,6 +1154,12 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ else if(sector<5) sl->flash_pgsz=0x10000; else sl->flash_pgsz=0x20000; } + else if (sl->chip_id == STM32_CHIPID_F7) { + uint32_t sector=calculate_F7_sectornum(flashaddr); + if (sector<4) sl->flash_pgsz=0x8000; + else if(sector<5) sl->flash_pgsz=0x20000; + else sl->flash_pgsz=0x40000; + } return (sl->flash_pgsz); } @@ -1172,6 +1186,13 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) uint32_t page = calculate_L4_page(sl, flashaddr); write_flash_cr_bker_pnb(sl, page); + } else if (sl->chip_id == STM32_CHIPID_F7) { + // calculate the actual page from the address + uint32_t sector=calculate_F7_sectornum(flashaddr); + + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x\n", sector, stlink_calculate_pagesize(sl, flashaddr)); + + write_flash_cr_snb(sl, sector); } else { // calculate the actual page from the address uint32_t sector=calculate_F4_sectornum(flashaddr); From e69a02d76093d5baa4b5cbcd028213a0516da9d6 Mon Sep 17 00:00:00 2001 From: mlundinse Date: Sat, 15 Aug 2015 19:23:53 +0200 Subject: [PATCH 0332/1435] Make sure MCU is halted before running RAM based flashloaders. --- flash/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/flash/main.c b/flash/main.c index f84323217..2679bbbce 100644 --- a/flash/main.c +++ b/flash/main.c @@ -168,6 +168,11 @@ int main(int ac, char** av) stlink_write_mem32(sl,0x40026400+0x24+0x18*i,4); } } + + // Core must be halted to use RAM based flashloaders + stlink_force_debug(sl); + stlink_status(sl); + if (o.cmd == DO_WRITE) /* write */ { if ((o.addr >= sl->flash_base) && From 601d4d332967608ff49742942946ccb09e81a42a Mon Sep 17 00:00:00 2001 From: mlundinse Date: Sat, 15 Aug 2015 19:42:52 +0200 Subject: [PATCH 0333/1435] Make _stlink_usb_reset use hardreset --- src/stlink-common.h | 1 + src/stlink-usb.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/stlink-common.h b/src/stlink-common.h index 76f977e9b..9268da22c 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -68,6 +68,7 @@ extern "C" { #define STLINK_DEBUG_WRITEDEBUGREG 0x0f #define STLINK_DEBUG_ENTER_SWD 0xa3 #define STLINK_DEBUG_ENTER_JTAG 0x00 +#define STLINK_DEBUG_HARDRESET 0x3c // TODO - possible poor names... #define STLINK_SWD_ENTER 0x30 diff --git a/src/stlink-usb.c b/src/stlink-usb.c index d8b6c4673..47924c7be 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -413,7 +413,8 @@ void _stlink_usb_reset(stlink_t * sl) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_RESETSYS; + cmd[i++] = STLINK_DEBUG_HARDRESET; + cmd[i++] = 0x2; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { From e047ef25db9745e091a519520414a24bbea42b91 Mon Sep 17 00:00:00 2001 From: Dave Vandervies Date: Wed, 12 Aug 2015 17:34:32 -0400 Subject: [PATCH 0334/1435] Correctly compute flash write size for partial pages --- gdbserver/gdb-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index bae496d31..31f9beb00 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -705,8 +705,8 @@ static int flash_go(stlink_t *sl) { for(struct flash_block* fb = flash_root; fb; fb = fb->next) { DLOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length); - unsigned length = fb->length; for(stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += FLASH_PAGE) { + unsigned length = fb->length - (page - fb->addr); //Update FLASH_PAGE stlink_calculate_pagesize(sl, page); From bddf605006b85ccdf7a3ad2be5bb8bcd9b414609 Mon Sep 17 00:00:00 2001 From: bruno_dalbo Date: Mon, 17 Aug 2015 14:54:19 -0300 Subject: [PATCH 0335/1435] segmentation fault length fix --- gdbserver/gdb-server.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 0ddebb06f..d902eab7e 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -654,10 +654,12 @@ static int flash_go(stlink_t *sl) { stlink_calculate_pagesize(sl, page); DLOG("flash_do: page %08x\n", page); - + unsigned send = length > FLASH_PAGE ? FLASH_PAGE : length; if(stlink_write_flash(sl, page, fb->data + (page - fb->addr), - length > FLASH_PAGE ? FLASH_PAGE : length) < 0) + send) < 0) goto error; + length -= send; + } } From 69feeaa6003ec1450280bed7e0e9c552cdc1aa1d Mon Sep 17 00:00:00 2001 From: mlu Date: Fri, 21 Aug 2015 15:44:34 +0200 Subject: [PATCH 0336/1435] Revert "Make _stlink_usb_reset use hardreset" --- src/stlink-common.h | 1 - src/stlink-usb.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/stlink-common.h b/src/stlink-common.h index 9268da22c..76f977e9b 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -68,7 +68,6 @@ extern "C" { #define STLINK_DEBUG_WRITEDEBUGREG 0x0f #define STLINK_DEBUG_ENTER_SWD 0xa3 #define STLINK_DEBUG_ENTER_JTAG 0x00 -#define STLINK_DEBUG_HARDRESET 0x3c // TODO - possible poor names... #define STLINK_SWD_ENTER 0x30 diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 47924c7be..d8b6c4673 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -413,8 +413,7 @@ void _stlink_usb_reset(stlink_t * sl) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_HARDRESET; - cmd[i++] = 0x2; + cmd[i++] = STLINK_DEBUG_RESETSYS; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { From a13aeeeff7970c18be486d1f62565768e6b43d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20Can=20=C4=B0=C3=A7=C3=B6z?= Date: Thu, 3 Sep 2015 11:32:12 +0300 Subject: [PATCH 0337/1435] correct error message is given upon missing pkg-config package. fixes texane/stlink#338 --- configure.ac | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configure.ac b/configure.ac index f1357b121..203cc6bd5 100644 --- a/configure.ac +++ b/configure.ac @@ -20,6 +20,11 @@ AC_CHECK_HEADERS(sys/mman.h) AC_CHECK_HEADERS(sys/poll.h) AC_REPLACE_FUNCS(mmap) +if ! hash pkg-config; then + echo "ERROR: pkg-config is needed..." + exit 1 +fi + # Checks for libraries. PKG_CHECK_MODULES(USB, libusb-1.0 >= 1.0.0,, AC_MSG_ERROR([*** Required libusb-1.0 >= 1.0.0 not installed ***])) From 768fe88e6ca721758d1d19edad429ec19a6fc8d3 Mon Sep 17 00:00:00 2001 From: mlundinse Date: Sat, 3 Oct 2015 16:36:37 +0200 Subject: [PATCH 0338/1435] Breakpoint handling for Cortex M7 --- gdbserver/gdb-server.c | 47 +++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index c0166eb1e..27b801029 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -542,8 +542,9 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) return -1; } -#define CODE_BREAK_NUM 6 -#define CODE_LIT_NUM 2 +int code_break_num; +int code_lit_num; +#define CODE_BREAK_NUM_MAX 15 #define CODE_BREAK_LOW 0x01 #define CODE_BREAK_HIGH 0x02 @@ -552,37 +553,41 @@ struct code_hw_breakpoint { int type; }; -struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM]; +struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM_MAX]; static void init_code_breakpoints(stlink_t *sl) { memset(sl->q_buf, 0, 4); stlink_write_debug32(sl, CM3_REG_FP_CTRL, 0x03 /*KEY | ENABLE4*/); unsigned int val = stlink_read_debug32(sl, CM3_REG_FP_CTRL); - if (((val & 3) != 1) || - ((((val >> 8) & 0x70) | ((val >> 4) & 0xf)) != CODE_BREAK_NUM) || - (((val >> 8) & 0xf) != CODE_LIT_NUM)){ - ELOG("[FP_CTRL] = 0x%08x expecting 0x%08x\n", val, - ((CODE_BREAK_NUM & 0x70) << 8) | (CODE_LIT_NUM << 8) | ((CODE_BREAK_NUM & 0xf) << 4) | 1); - } + code_break_num = ((val >> 4) & 0xf); + code_lit_num = ((val >> 8) & 0xf); + ILOG("Found %i hw breakpoint registers\n", code_break_num); - for(int i = 0; i < CODE_BREAK_NUM; i++) { + for(int i = 0; i < code_break_num; i++) { code_breaks[i].type = 0; stlink_write_debug32(sl, CM3_REG_FP_COMP0 + i * 4, 0); } } static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { - stm32_addr_t fpb_addr = addr & ~0x3; - int type = addr & 0x2 ? CODE_BREAK_HIGH : CODE_BREAK_LOW; + stm32_addr_t fpb_addr; + uint32_t mask; + int type = (addr & 0x2) ? CODE_BREAK_HIGH : CODE_BREAK_LOW; if(addr & 1) { ELOG("update_code_breakpoint: unaligned address %08x\n", addr); return -1; } + if (sl->chip_id==STM32_CHIPID_F7) { + fpb_addr = addr; + } else { + fpb_addr = addr & ~0x3; + } + int id = -1; - for(int i = 0; i < CODE_BREAK_NUM; i++) { + for(int i = 0; i < code_break_num; i++) { if(fpb_addr == code_breaks[i].addr || (set && code_breaks[i].type == 0)) { id = i; @@ -599,16 +604,23 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { brk->addr = fpb_addr; - if(set) brk->type |= type; - else brk->type &= ~type; + if (sl->chip_id==STM32_CHIPID_F7) { + if(set) brk->type = type; + else brk->type = 0; + + mask = (brk->addr) | 1; + } else { + if(set) brk->type |= type; + else brk->type &= ~type; + + mask = (brk->addr) | 1 | (brk->type << 30); + } if(brk->type == 0) { DLOG("clearing hw break %d\n", id); stlink_write_debug32(sl, 0xe0002008 + id * 4, 0); } else { - uint32_t mask = (brk->addr) | 1 | (brk->type << 30); - DLOG("setting hw break %d at %08x (%d)\n", id, brk->addr, brk->type); DLOG("reg %08x \n", @@ -701,6 +713,7 @@ static int flash_go(stlink_t *sl) { // Some kinds of clock settings do not allow writing to flash. stlink_reset(sl); + stlink_force_debug(sl); for(struct flash_block* fb = flash_root; fb; fb = fb->next) { DLOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length); From e37b65762dd5c9fa66ce6eac0021f31161b6528a Mon Sep 17 00:00:00 2001 From: lementec Date: Mon, 12 Oct 2015 08:07:59 +0200 Subject: [PATCH 0339/1435] README, add working target --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index 7aa3b8b69..10feb7dc2 100644 --- a/README +++ b/README @@ -200,5 +200,6 @@ Known Working Targets: * STM32F303RET6 (STM32 Nucleo-F303RE board) * STM32F334R8 (STM32 Nucleo-F334R8 board) * STM32F411RET6 (STM32 Nucleo-F411RE board) +& STM32F756NGHx (STMF7 evaluation board) Please report any and all known working combinations so I can update this! From 92bbca73b0dc128573834e6992c4bd6689e67e63 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Fri, 23 Oct 2015 23:14:59 +0200 Subject: [PATCH 0340/1435] Add support to STM32F469/STM32F479 STM32F469 is a STM32F429 MCU with Dual-QSPI NOR support and DSI screen support. Signed-off-by: Maxime Coquelin --- src/stlink-common.c | 36 +++++++++++++++++++----------------- src/stlink-common.h | 12 ++++++++++++ 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 0ce67b25f..cfb1fbbaf 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -180,7 +180,7 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { uint32_t res; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||(sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) res = stlink_read_debug32(sl, FLASH_F4_CR); else if (sl->chip_id == STM32_CHIPID_L4) res = stlink_read_debug32(sl, STM32L4_FLASH_CR); @@ -198,7 +198,7 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) return cr & (1 << FLASH_F4_CR_LOCK); else if (sl->chip_id == STM32_CHIPID_L4) return cr & (1lu << STM32L4_FLASH_CR_LOCK); @@ -214,7 +214,7 @@ static void unlock_flash(stlink_t *sl) { */ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); } else if (sl->chip_id == STM32_CHIPID_L4) { @@ -244,7 +244,7 @@ static int unlock_flash_if(stlink_t *sl) { static void lock_flash(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); stlink_write_debug32(sl, FLASH_F4_CR, n); } else if (sl->chip_id == STM32_CHIPID_L4) { @@ -261,7 +261,7 @@ static void lock_flash(stlink_t *sl) { static void set_flash_cr_pg(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_CR_PG); stlink_write_debug32(sl, FLASH_F4_CR, x); @@ -280,7 +280,7 @@ static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) stlink_write_debug32(sl, FLASH_F4_CR, n); else stlink_write_debug32(sl, FLASH_CR, n); @@ -299,7 +299,7 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { static void set_flash_cr_mer(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); else if (sl->chip_id == STM32_CHIPID_L4) { @@ -315,7 +315,7 @@ static void set_flash_cr_mer(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) stlink_write_debug32(sl, FLASH_F4_CR, stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); else @@ -326,7 +326,7 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { static void set_flash_cr_strt(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { uint32_t x = read_flash_cr(sl); x |= (1 << FLASH_F4_CR_STRT); stlink_write_debug32(sl, FLASH_F4_CR, x); @@ -348,7 +348,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) res = stlink_read_debug32(sl, FLASH_F4_SR); else if (sl->chip_id == STM32_CHIPID_L4) res = stlink_read_debug32(sl, STM32L4_FLASH_SR); @@ -361,7 +361,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { static inline unsigned int is_flash_busy(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7)) + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY); else if (sl->chip_id == STM32_CHIPID_L4) return read_flash_sr(sl) & (1 << STM32L4_FLASH_SR_BSY); @@ -1145,7 +1145,7 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector>= 12) { sector -= 12; @@ -1173,7 +1173,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_L4)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_L4)|| (sl->chip_id == STM32_CHIPID_F4_DSI)) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1592,7 +1592,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446)){ + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F4_DSI)){ int voltage = stlink_target_voltage(sl); if (voltage > 2700) { loader_code = loader_code_stm32f4; @@ -1790,7 +1790,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t (sl->chip_id == STM32_CHIPID_F411RE) || (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || - (sl->chip_id == STM32_CHIPID_L4)) { + (sl->chip_id == STM32_CHIPID_L4) || + (sl->chip_id == STM32_CHIPID_F4_DSI)) { /* todo: check write operation */ ILOG("Starting Flash write for F2/F4/L4\n"); @@ -2051,7 +2052,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_L4)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_L4) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -2116,7 +2117,8 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_L4)) { + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_L4) || + (sl->chip_id == STM32_CHIPID_F4_DSI)) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { diff --git a/src/stlink-common.h b/src/stlink-common.h index 76f977e9b..a0bd64909 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -124,6 +124,9 @@ extern "C" { #define STM32_CHIPID_F37x 0x432 #define STM32_CHIPID_F4_DE 0x433 +#define STM32_CHIPID_F4_DE 0x433 + +#define STM32_CHIPID_F4_DSI 0x434 #define STM32_CHIPID_L1_HIGH 0x436 #define STM32_CHIPID_L152_RE 0x437 @@ -222,6 +225,15 @@ extern "C" { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 }, + { + .chip_id = STM32_CHIPID_F4_DSI, + .description = "F46x and F47x device", + .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ + .flash_pagesize = 0x4000, + .sram_size = 0x40000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, { .chip_id = STM32_CHIPID_F4_HD, .description = "F42x and F43x device", From 323920a41e5bcb14cf7f7c0e961a1709ef245028 Mon Sep 17 00:00:00 2001 From: Rytis Karpuska Date: Mon, 9 Nov 2015 20:03:42 +0200 Subject: [PATCH 0341/1435] Implement simple non-blocking ring buffer for communication over stlink --- src/st-term.c | 144 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 114 insertions(+), 30 deletions(-) diff --git a/src/st-term.c b/src/st-term.c index 8350cfffc..af7b85ee1 100644 --- a/src/st-term.c +++ b/src/st-term.c @@ -11,8 +11,30 @@ #include #include "stlink-common.h" +/* STLinky structure on STM chip + +struct stlinky { + uint32_t magic; + uint32_t bufsize; + uint32_t up_tail; + uint32_t up_head; + uint32_t dw_tail; + uint32_t dw_head; + char upbuf[CONFIG_LIB_STLINKY_BSIZE]; + char dwbuf[CONFIG_LIB_STLINKY_BSIZE]; +} __attribute__ ((packed)); +*/ + + #define STLINKY_MAGIC 0xDEADF00D +#define ST_TERM_MAX_BUFF_SIZE (1024*1024) //1Mb + +#define RX_Q_OFFSET 8 +#define RX_BUFF_OFFSET 24 +#define TX_Q_OFFSET 16 +#define TX_BUFF_OFFSET(bufsize) (24 + bufsize) + #define READ_UINT32_LE(buf) ((uint32_t) ( buf[0] \ | buf[1] << 8 \ | buf[2] << 16 \ @@ -79,7 +101,7 @@ struct stlinky* stlinky_detect(stlink_t* sl) printf("stlinky detected at 0x%x\n", sram_base + off); st->off = sram_base + off; stlink_read_mem32(sl, st->off + 4, 4); - st->bufsize = (size_t) *(unsigned char*) sl->q_buf; + st->bufsize = READ_UINT32_LE(sl->q_buf); printf("stlinky buffer size 0x%zu \n", st->bufsize); multiple++; } @@ -93,41 +115,98 @@ struct stlinky* stlinky_detect(stlink_t* sl) return NULL; } -int stlinky_canrx(struct stlinky *st) +static void stlinky_read_buff(struct stlinky *st, uint32_t off, uint32_t size, char *buffer) +{ + int aligned_size; + + if (size == 0) + return; + + //Read from device with 4-byte alignment + aligned_size = (size & 0xFFFFFFFC) + 8; + stlink_read_mem32(st->sl, off & 0xFFFFFFFC, aligned_size); + + //copy to local buffer + memcpy(buffer, st->sl->q_buf + (off & 0x3), size); + + return; +} + +static void stlinky_write_buf(struct stlinky *st, uint32_t off, uint32_t size, char *buffer) { - stlink_read_mem32(st->sl, st->off+4, 4); - unsigned char tx = (unsigned char) st->sl->q_buf[1]; - return (int) tx; + memcpy(st->sl->q_buf, buffer, size); + stlink_write_mem8(st->sl, off, size); + return; } size_t stlinky_rx(struct stlinky *st, char* buffer) { - unsigned char tx = 0; - while(tx == 0) { - stlink_read_mem32(st->sl, st->off+4, 4); - tx = (unsigned char) st->sl->q_buf[1]; + //read head and tail values + uint32_t tail, head; + stlink_read_mem32(st->sl, st->off + RX_Q_OFFSET, sizeof(tail) + sizeof(head)); + memcpy(&tail, &st->sl->q_buf[0], sizeof(tail)); + memcpy(&head, &st->sl->q_buf[sizeof(tail)], sizeof(head)); + + //return if empty + if(head == tail) + return 0; + + //read data + int size_read = 0; + if(head > tail){ + stlinky_read_buff(st, st->off + RX_BUFF_OFFSET + tail, head - tail, buffer); + size_read += head - tail; + } else if(head < tail){ + stlinky_read_buff(st, st->off + RX_BUFF_OFFSET + tail, st->bufsize - tail, buffer); + size_read += st->bufsize - tail; + + stlinky_read_buff(st, st->off + RX_BUFF_OFFSET, head, buffer + size_read); + size_read += head; } - size_t rs = tx + (4 - (tx % 4)); /* voodoo */ - stlink_read_mem32(st->sl, st->off+8, rs); - memcpy(buffer, st->sl->q_buf, (size_t) tx); - *st->sl->q_buf=0x0; - stlink_write_mem8(st->sl, st->off+5, 1); - return (size_t) tx; + + //move tail + tail = (tail + size_read) % st->bufsize; + + //write tail + memcpy(st->sl->q_buf, &tail, sizeof(tail)); + stlink_write_mem32(st->sl, st->off + RX_Q_OFFSET, sizeof(tail)); + + return size_read; } -size_t stlinky_tx(struct stlinky *st, char* buffer, size_t sz) +size_t stlinky_tx(struct stlinky *st, char* buffer, size_t siz) { - unsigned char rx = 1; - while(rx != 0) { - stlink_read_mem32(st->sl, st->off+4, 4); - rx = (unsigned char) st->sl->q_buf[2]; - } - memcpy(st->sl->q_buf, buffer, sz); - size_t rs = sz + (4 - (sz % 4)); /* voodoo */ - stlink_write_mem32(st->sl, st->off+8+st->bufsize, rs); - *st->sl->q_buf=(unsigned char) sz; - stlink_write_mem8(st->sl, st->off+6, 1); - return (size_t) rx; + //read head and tail values + uint32_t tail, head; + stlink_read_mem32(st->sl, st->off + TX_Q_OFFSET, sizeof(tail) + sizeof(head)); + memcpy(&tail, &st->sl->q_buf[0], sizeof(tail)); + memcpy(&head, &st->sl->q_buf[sizeof(tail)], sizeof(head)); + + //Figure out buffer usage + int usage = head - tail; + if (usage < 0) + usage += st->bufsize; + + //check if new data will fit + if (usage + siz >= st->bufsize) + return 0; + + //copy in data (take care of possible split) + int first_chunk = head + siz >= st->bufsize ? st->bufsize - head : siz; + int second_chunk = siz - first_chunk; + + //copy data + stlinky_write_buf(st, st->off + TX_BUFF_OFFSET(st->bufsize) + head, first_chunk, buffer); + if (second_chunk > 0) + stlinky_write_buf(st, st->off + TX_BUFF_OFFSET(st->bufsize), + second_chunk, buffer + first_chunk); + + //increment head pointer + head = (head + siz) % st->bufsize; + memcpy(st->sl->q_buf, &head, sizeof(head)); + stlink_write_mem32(st->sl, st->off + TX_Q_OFFSET + sizeof(tail), sizeof(head)); + + return siz; } int kbhit() @@ -202,7 +281,7 @@ int main(int ac, char** av) { st->off = (int)strtol(av[1], NULL, 16); printf("using stlinky at 0x%x\n", st->off); stlink_read_mem32(sl, st->off + 4, 4); - st->bufsize = (size_t) *(unsigned char*) sl->q_buf; + st->bufsize = READ_UINT32_LE(sl->q_buf); printf("stlinky buffer size 0x%zu \n", st->bufsize); }else{ cleanup(0); @@ -212,6 +291,10 @@ int main(int ac, char** av) { printf("stlinky magic not found in sram :(\n"); cleanup(0); } + if (st->bufsize > ST_TERM_MAX_BUFF_SIZE){ + printf("stlinky buffer size too big\n"); + cleanup(0); + } char* rxbuf = malloc(st->bufsize); char* txbuf = malloc(st->bufsize); size_t tmp; @@ -222,8 +305,9 @@ int main(int ac, char** av) { printf("Entering interactive terminal. CTRL+C to exit\n\n\n"); while(1) { sig_process(); - if (stlinky_canrx(st)) { - tmp = stlinky_rx(st, rxbuf); + tmp = stlinky_rx(st, rxbuf); + if(tmp > 0) + { fwrite(rxbuf,tmp,1,stdout); fflush(stdout); } From d4d28e401f219aaa2941a1fe92777208a99b6e2f Mon Sep 17 00:00:00 2001 From: Josh Bialkowski Date: Mon, 16 Nov 2015 16:50:08 -0800 Subject: [PATCH 0342/1435] first stab at a cmake build --- CMakeLists.txt | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..6fbb3baf4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,75 @@ +cmake_minimum_required(VERSION 2.8.11) +project(stlink) + +find_package(PkgConfig) + +pkg_check_modules(libusb REQUIRED libusb-1.0) +pkg_check_modules(gtk gtk+-3.0) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra") + +set(HFILES src/stlink-common.h + src/stlink-usb.h + src/stlink-sg.h + src/uglylogging.h + src/mmap.h) + +set(CFILES src/stlink-common.c + src/stlink-usb.c + src/stlink-sg.c + src/uglylogging.c + src/st-info.c) + +include_directories(${libusb_INCLUDE_DIRS}) +include_directories(src) +include_directories(mingw) + +add_library(stlink STATIC + ${HFILES} # header files for ide projects generated by cmake + ${CFILES}) +target_link_libraries(stlink ${libusb_LDFLAGS}) + +add_executable(st-flash flash/main.c) +target_link_libraries(st-flash stlink) + +add_executable(st-util gdbserver/gdb-remote.c + gdbserver/gdb-remote.h + gdbserver/gdb-server.c + gdbserver/gdb-server.h) +target_link_libraries(st-util stlink) + +install(TARGETS stlink st-flash st-util + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib) + +if(NOT ${MINGW}) + list(APPEND CFILES src/st-term.c) + add_executable(st-term src/st-term.c) + target_link_libraries(st-term stlink) + + install(TARGETS st-term + RUNTIME DESTINATION bin) +endif() + +if(gtk_FOUND) + include_directories(${gtk_INCLUDE_DIRS}) + set(GUI_SOURCES gui/stlink-gui.c + gui/stlink-gui.h) + + add_executable(stlink-gui-local ${GUI_SOURCES}) + set_target_properties(stlink-gui-local PROPERTIES + COMPILE_FLAGS -DSTLINK_UI_DIR=\\"${CMAKE_CURRENT_SOURCE_DIR}/gui\\") + target_link_libraries(stlink-gui-local stlink ${gtk_LDFLAGS}) + + set(INSTALLED_UI_DIR ${CMAKE_INSTALL_PREFIX}/share) + add_executable(stlink-gui ${GUI_SOURCES}) + set_target_properties(stlink-gui PROPERTIES + COMPILE_FLAGS -DSTLINK_UI_DIR=\\"${INSTALLED_UI_DIR}\\") + target_link_libraries(stlink-gui stlink ${gtk_LDFLAGS}) + + install(TARGETS stlink-gui + RUNTIME DESTINATION bin) + install(FILES gui/stlink-gui.ui + DESTINATION ${INSTALLED_UI_DIR}) +endif() + From deb2089e24236b24f4b2b53203210b03fcf878d1 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 19 Nov 2015 10:53:21 +0200 Subject: [PATCH 0343/1435] mingw compilation error (sleep) fixed --- mingw/mingw.h | 1 + 1 file changed, 1 insertion(+) diff --git a/mingw/mingw.h b/mingw/mingw.h index 1fcf93da2..cb333016c 100644 --- a/mingw/mingw.h +++ b/mingw/mingw.h @@ -65,5 +65,6 @@ char *win32_strsep(char **stringp, const char *delim); ssize_t win32_read_socket(SOCKET fd, void *buf, int n); ssize_t win32_write_socket(SOCKET fd, void *buf, int n); +static inline void sleep(unsigned ms) { Sleep(ms); } #endif From 308730bbadcd06353d662077db5d9713031ecec8 Mon Sep 17 00:00:00 2001 From: Josh Bialkowski Date: Thu, 19 Nov 2015 09:29:27 -0800 Subject: [PATCH 0344/1435] fix MINGW test in cmake --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fbb3baf4..2358898e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ install(TARGETS stlink st-flash st-util RUNTIME DESTINATION bin ARCHIVE DESTINATION lib) -if(NOT ${MINGW}) +if(NOT MINGW) list(APPEND CFILES src/st-term.c) add_executable(st-term src/st-term.c) target_link_libraries(st-term stlink) From 06fd9c4b700e681e04ec78f5664fd55674f94b6f Mon Sep 17 00:00:00 2001 From: Georg von Zengen Date: Mon, 7 Dec 2015 17:23:15 +0100 Subject: [PATCH 0345/1435] Added parameter to specify one stlink v2 of many This adds a parameter to the function stlink_open_usb and to the binary st-flash to specify one of multiple connected stlinks. As the identifier the iSerial of the stlink is used. If no serial is given the function and binary behave as before. --- flash/main.c | 38 +++++++++++++++++++++++++++++++++----- gdbserver/gdb-server.c | 2 +- gui/stlink-gui.c | 2 +- src/st-info.c | 2 +- src/st-term.c | 2 +- src/stlink-usb.c | 20 +++++++++++++++++--- src/stlink-usb.h | 2 +- src/test_usb.c | 2 +- 8 files changed, 56 insertions(+), 14 deletions(-) diff --git a/flash/main.c b/flash/main.c index 2679bbbce..d0d303a0d 100644 --- a/flash/main.c +++ b/flash/main.c @@ -17,6 +17,7 @@ struct opts { enum st_cmds cmd; const char* devname; + char *serial; const char* filename; stm32_addr_t addr; size_t size; @@ -26,11 +27,11 @@ struct opts static void usage(void) { - puts("stlinkv1 command line: ./st-flash [--debug] [--reset] {read|write} /dev/sgX path addr "); + puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--serial ] {read|write} /dev/sgX path addr "); puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); - puts("stlinkv2 command line: ./st-flash [--debug] [--reset] {read|write} path addr "); - puts("stlinkv2 command line: ./st-flash [--debug] erase"); - puts(" use hex format for addr and "); + puts("stlinkv2 command line: ./st-flash [--debug] [--reset] [--serial ] {read|write} path addr "); + puts("stlinkv2 command line: ./st-flash [--debug] [--serial ] erase"); + puts(" use hex format for addr, and "); } static int get_opts(struct opts* o, int ac, char** av) @@ -64,6 +65,31 @@ static int get_opts(struct opts* o, int ac, char** av) o->reset = 0; } + if (strcmp(av[0], "--serial") == 0) + { + ac--; + av++; + int i=strlen(av[0]); + if(i%2 != 0){ + puts("no valid hex value, length must be multiple of 2\n"); + return -1; + } + int j=0; + while(i>=0 && j<=13){ + char buffer[3]={0}; + memcpy(buffer,&av[0][i],2); + o->serial[12-j] = (char)strtol((const char*)buffer,NULL, 16); + j++; + i-=2; + } + ac--; + av++; + } + else + { + o->serial = NULL; + } + if (ac < 1) return -1; /* stlinkv2 */ @@ -123,6 +149,8 @@ int main(int ac, char** av) { stlink_t* sl = NULL; struct opts o; + char serial_buffer[13] = {0}; + o.serial = serial_buffer; int err = -1; o.size = 0; @@ -141,7 +169,7 @@ int main(int ac, char** av) } else /* stlinkv2 */ { - sl = stlink_open_usb(o.log_level, 1); + sl = stlink_open_usb(o.log_level, 1, o.serial); if (sl == NULL) goto on_error; sl->verbose = o.log_level; } diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 27b801029..b0245320e 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -173,7 +173,7 @@ int main(int argc, char** argv) { parse_options(argc, argv, &state); switch (state.stlink_version) { case 2: - sl = stlink_open_usb(state.logging_level, 0); + sl = stlink_open_usb(state.logging_level, 0, NULL); if(sl == NULL) return 1; break; case 1: diff --git a/gui/stlink-gui.c b/gui/stlink-gui.c index f60e92db0..93f92c462 100644 --- a/gui/stlink-gui.c +++ b/gui/stlink-gui.c @@ -530,7 +530,7 @@ connect_button_cb (GtkWidget *widget, gpointer data) /* try version 1 then version 2 */ gui->sl = stlink_v1_open(0, 1); if (gui->sl == NULL) { - gui->sl = stlink_open_usb(0, 1); + gui->sl = stlink_open_usb(0, 1, NULL); } if (gui->sl == NULL) { stlink_gui_set_info_error_message (gui, "Failed to connect to STLink."); return; diff --git a/src/st-info.c b/src/st-info.c index 6fe2f8d7a..66d9fb391 100644 --- a/src/st-info.c +++ b/src/st-info.c @@ -51,7 +51,7 @@ stlink_t* open_sl(void) stlink_t* sl; sl = stlink_v1_open(0, 1); if (sl == NULL) - sl = stlink_open_usb(0, 1); + sl = stlink_open_usb(0, 1, NULL); return sl; } diff --git a/src/st-term.c b/src/st-term.c index af7b85ee1..245ed5949 100644 --- a/src/st-term.c +++ b/src/st-term.c @@ -251,7 +251,7 @@ int main(int ac, char** av) { sig_init(); - sl = stlink_open_usb(10, 1); + sl = stlink_open_usb(10, 1, NULL); if (sl != NULL) { printf("ST-Linky proof-of-concept terminal :: Created by Necromant for lulz\n"); stlink_version(sl); diff --git a/src/stlink-usb.c b/src/stlink-usb.c index d8b6c4673..546f722ea 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -728,7 +728,7 @@ stlink_backend_t _stlink_usb_backend = { }; -stlink_t* stlink_open_usb(const int verbose, int reset) { +stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; int error = -1; @@ -747,7 +747,6 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { sl->backend_data = slu; sl->core_stat = STLINK_CORE_STAT_UNKNOWN; - if (libusb_init(&(slu->libusb_ctx))) { WLOG("failed to init libusb context, wrong version of libraries?\n"); goto on_error; @@ -776,7 +775,22 @@ 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) || (desc.idProduct == USB_STLINK_NUCLEO_PID) ) break; + if ( (desc.idProduct == USB_STLINK_32L_PID) || (desc.idProduct == USB_STLINK_NUCLEO_PID) ){ + if ((p_usb_iserial != NULL)){ + unsigned char buffer[13]; + struct libusb_device_handle* handle; + libusb_open(list[cnt], &handle); + libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, buffer, 13); + libusb_close(handle); + if (memcmp(p_usb_iserial,&buffer,12) == 0){ + break; + }else{ + continue; + } + }else{ + break; + } + } if (desc.idProduct == USB_STLINK_PID) { slu->protocoll = 1; break; diff --git a/src/stlink-usb.h b/src/stlink-usb.h index 58b60e430..d7e745f51 100644 --- a/src/stlink-usb.h +++ b/src/stlink-usb.h @@ -30,7 +30,7 @@ extern "C" { unsigned int cmd_len; }; - stlink_t* stlink_open_usb(const int verbose, int reset); + stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial); #ifdef __cplusplus diff --git a/src/test_usb.c b/src/test_usb.c index eb8e54cdd..787ac12ce 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(10, 1); + sl = stlink_open_usb(10, 1, NULL); if (sl != NULL) { printf("-- version\n"); stlink_version(sl); From 3ae69fe659bbc92a494a2c469327805c2516e99b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Luc=20B=C3=A9chennec?= Date: Tue, 15 Dec 2015 15:12:55 +0100 Subject: [PATCH 0346/1435] Added STM32L053R8 Hello, checked this board with stink. It communicates without flaw with the board: ``` 2015-12-15T14:47:03 INFO src/stlink-common.c: Loading device parameters.... 2015-12-15T14:47:03 INFO src/stlink-common.c: Device connected is: L0x3 device, id 0x10086417 2015-12-15T14:47:03 INFO src/stlink-common.c: SRAM size: 0x2000 bytes (8 KiB), Flash: 0x10000 bytes (64 KiB) in pages of 128 bytes 2015-12-15T14:47:03 INFO gdbserver/gdb-server.c: Chip ID is 00000417, Core ID is 0bc11477. 2015-12-15T14:47:03 INFO gdbserver/gdb-server.c: Target voltage is 3264 mV. 2015-12-15T14:47:03 INFO gdbserver/gdb-server.c: Listening at *:4242... ``` When I launch GDB and connect to the server, I get : ``` 2015-12-15T14:51:41 ERROR gdbserver/gdb-server.c: [FP_CTRL] = 0x00000041 expecting 0x00000261 2015-12-15T14:51:41 INFO gdbserver/gdb-server.c: GDB connected. ``` on the st-util side and : ``` Cannot access memory at address 0xffffffff ``` on the GDB side Reading and writing to memory and registers works however I get ``` Cannot access memory at address 0xffffffff ``` Each time I write to the memory or to a register --- README | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README b/README index 10feb7dc2..ac1dd0efd 100644 --- a/README +++ b/README @@ -200,6 +200,7 @@ Known Working Targets: * STM32F303RET6 (STM32 Nucleo-F303RE board) * STM32F334R8 (STM32 Nucleo-F334R8 board) * STM32F411RET6 (STM32 Nucleo-F411RE board) -& STM32F756NGHx (STMF7 evaluation board) +* STM32F756NGHx (STMF7 evaluation board) +* STM32L053R8 (STM32 Nucleo-L053R8 board) Please report any and all known working combinations so I can update this! From 177ef67b10f3d7e35cff91d470e09c9d09feec6b Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Thu, 17 Dec 2015 11:00:45 +0100 Subject: [PATCH 0347/1435] Do not send a NUL at end of packets to gdb. GDB doesn't need it and see the NUL as a junk character (visible with 'set debug remote 1'). --- gdbserver/gdb-remote.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/gdbserver/gdb-remote.c b/gdbserver/gdb-remote.c index a9eef3333..2f61b93ac 100644 --- a/gdbserver/gdb-remote.c +++ b/gdbserver/gdb-remote.c @@ -18,7 +18,8 @@ static const char hex[] = "0123456789abcdef"; int gdb_send_packet(int fd, char* data) { - int length = strlen(data) + 5; + unsigned int data_length = strlen(data); + int length = data_length + 4; char* packet = malloc(length); /* '$' data (hex) '#' cksum (hex) */ memset(packet, 0, length); @@ -26,14 +27,14 @@ int gdb_send_packet(int fd, char* data) { packet[0] = '$'; uint8_t cksum = 0; - for(unsigned int i = 0; i < strlen(data); i++) { + for(unsigned int i = 0; i < data_length; i++) { packet[i + 1] = data[i]; cksum += data[i]; } - packet[length - 4] = '#'; - packet[length - 3] = hex[cksum >> 4]; - packet[length - 2] = hex[cksum & 0xf]; + packet[length - 3] = '#'; + packet[length - 2] = hex[cksum >> 4]; + packet[length - 1] = hex[cksum & 0xf]; while(1) { if(write(fd, packet, length) != length) { From cce54ea2c71ffc7a2cc03e396c7c052f566f65a9 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Thu, 17 Dec 2015 11:05:00 +0100 Subject: [PATCH 0348/1435] stm32f7: also send features to gdb. So that 'extra' registers (msp, psp, ...) are visible to user. --- gdbserver/gdb-server.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index b0245320e..fd40fbfad 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -840,7 +840,9 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("query: %s;%s\n", queryName, params); if(!strcmp(queryName, "Supported")) { - if(sl->chip_id==STM32_CHIPID_F4 || sl->chip_id==STM32_CHIPID_F4_HD) { + if(sl->chip_id==STM32_CHIPID_F4 + || sl->chip_id==STM32_CHIPID_F4_HD + || sl->chip_id==STM32_CHIPID_F7) { reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); } else { From 54c8d2ca8b99c27761b45f35cd17f79512cb4a23 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Mon, 11 Jan 2016 15:44:17 +0100 Subject: [PATCH 0349/1435] st-util: synchronize cache for stm32f7 This patch handles the cache on the cortex-m7 stm32f7 cpu. When gdb inserts a soft breakpoint (which is the default for code in RAM), it replaces an instruction with a breakpoint instruction. But if the caches are enabled, the replacement may be made only in the D-cache. To reach the I-cache, the D-cache must be flushed and the I-cache invalidated. This implementation is coarse: it cleans the whole D-cache and invalidate the whole I-cache. It is possible to track which cache lines have to be cleaned and invalidated. --- gdbserver/gdb-server.c | 164 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index fd40fbfad..49c7e6dd4 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -49,6 +49,7 @@ typedef struct _st_state_t { int serve(stlink_t *sl, st_state_t *st); char* make_memory_map(stlink_t *sl); +static void init_cache (stlink_t *sl); static void cleanup(int signal __attribute__((unused))) { if (connected_stlink) { @@ -208,6 +209,8 @@ int main(int argc, char** argv) { } #endif + init_cache(sl); + do { if (serve(sl, &state)) { sleep (1); // don't go bezurk if serve returns with error @@ -750,6 +753,161 @@ static int flash_go(stlink_t *sl) { return error; } +#define CLIDR 0xE000ED78 +#define CTR 0xE000ED7C +#define CCSIDR 0xE000ED80 +#define CSSELR 0xE000ED84 +#define CCR 0xE000ED14 +#define CCR_DC (1 << 16) +#define CCR_IC (1 << 17) +#define DCCSW 0xE000EF6C +#define ICIALLU 0xE000EF50 + +struct cache_level_desc +{ + unsigned int nsets; + unsigned int nways; + unsigned int log2_nways; + unsigned int width; +}; + +struct cache_desc_t +{ + /* Minimal line size in bytes. */ + unsigned int dminline; + unsigned int iminline; + + /* Last level of unification (uniprocessor). */ + unsigned int louu; + + struct cache_level_desc icache[7]; + struct cache_level_desc dcache[7]; +}; + +static struct cache_desc_t cache_desc; + +/* Return the smallest R so that V <= (1 << R). Not performance critical. */ +static unsigned ceil_log2(unsigned v) +{ + unsigned res; + for (res = 0; (1 << res) < v; res++) + ; + return res; +} + +static void read_cache_level_desc(stlink_t *sl, struct cache_level_desc *desc) +{ + unsigned int ccsidr; + unsigned int log2_nsets; + ccsidr = stlink_read_debug32(sl, CCSIDR); + desc->nsets = ((ccsidr >> 13) & 0x3fff) + 1; + desc->nways = ((ccsidr >> 3) & 0x1ff) + 1; + desc->log2_nways = ceil_log2 (desc->nways); + log2_nsets = ceil_log2 (desc->nsets); + desc->width = 4 + (ccsidr & 7) + log2_nsets; + ILOG("%08x LineSize: %u, ways: %u, sets: %u (width: %u)\n", + ccsidr, 4 << (ccsidr & 7), desc->nways, desc->nsets, desc->width); +} + +static void init_cache (stlink_t *sl) { + unsigned int clidr; + unsigned int ccr; + unsigned int ctr; + int i; + + /* Assume only F7 has a cache. */ + if(sl->chip_id!=STM32_CHIPID_F7) + return; + + clidr = stlink_read_debug32(sl, CLIDR); + ccr = stlink_read_debug32(sl, CCR); + ctr = stlink_read_debug32(sl, CTR); + cache_desc.dminline = 4 << ((ctr >> 16) & 0x0f); + cache_desc.iminline = 4 << (ctr & 0x0f); + cache_desc.louu = (clidr >> 27) & 7; + + ILOG("Chip clidr: %08x, I-Cache: %s, D-Cache: %s\n", + clidr, ccr & CCR_IC ? "on" : "off", ccr & CCR_DC ? "on" : "off"); + ILOG(" cache: LoUU: %u, LoC: %u, LoUIS: %u\n", + (clidr >> 27) & 7, (clidr >> 24) & 7, (clidr >> 21) & 7); + ILOG(" cache: ctr: %08x, DminLine: %u bytes, IminLine: %u bytes\n", ctr, + cache_desc.dminline, cache_desc.iminline); + for(i = 0; i < 7; i++) + { + unsigned int ct = (clidr >> (3 * i)) & 0x07; + + cache_desc.dcache[i].width = 0; + cache_desc.icache[i].width = 0; + + if(ct == 2 || ct == 3 || ct == 4) + { + /* Data. */ + stlink_write_debug32(sl, CSSELR, i << 1); + ILOG("D-Cache L%d: ", i); + read_cache_level_desc(sl, &cache_desc.dcache[i]); + } + + if(ct == 1 || ct == 3) + { + /* Instruction. */ + stlink_write_debug32(sl, CSSELR, (i << 1) | 1); + ILOG("I-Cache L%d: ", i); + read_cache_level_desc(sl, &cache_desc.icache[i]); + } + } +} + +static void cache_flush(stlink_t *sl, unsigned ccr) { + int level; + + if (ccr & CCR_DC) + for (level = cache_desc.louu - 1; level >= 0; level--) + { + struct cache_level_desc *desc = &cache_desc.dcache[level]; + unsigned addr; + unsigned max_addr = 1 << desc->width; + unsigned way_sh = 32 - desc->log2_nways; + + /* D-cache clean by set-ways. */ + for (addr = (level << 1); addr < max_addr; addr += cache_desc.dminline) + { + unsigned int way; + + for (way = 0; way < desc->nways; way++) + stlink_write_debug32(sl, DCCSW, addr | (way << way_sh)); + } + } + + /* Invalidate all I-cache to oPU. */ + if (ccr & CCR_IC) + stlink_write_debug32(sl, ICIALLU, 0); +} + +static int cache_modified; + +static void cache_change(stm32_addr_t start, unsigned count) +{ + if (count == 0) + return; + (void)start; + cache_modified = 1; +} + +static void cache_sync(stlink_t *sl) +{ + unsigned ccr; + + if(sl->chip_id!=STM32_CHIPID_F7) + return; + if (!cache_modified) + return; + cache_modified = 0; + + ccr = stlink_read_debug32(sl, CCR); + if (ccr & (CCR_IC | CCR_DC)) + cache_flush(sl, ccr); +} + int serve(stlink_t *sl, st_state_t *st) { int sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0) { @@ -898,6 +1056,7 @@ int serve(stlink_t *sl, st_state_t *st) { if (!strncmp(params,"726573756d65",12)) {// resume DLOG("Rcmd: resume\n"); + cache_sync(sl); stlink_run(sl); reply = strdup("OK"); @@ -1016,6 +1175,7 @@ int serve(stlink_t *sl, st_state_t *st) { } case 'c': + cache_sync(sl); stlink_run(sl); while(1) { @@ -1045,6 +1205,7 @@ int serve(stlink_t *sl, st_state_t *st) { break; case 's': + cache_sync(sl); stlink_step(sl); reply = strdup("S05"); // TRAP @@ -1199,6 +1360,7 @@ int serve(stlink_t *sl, st_state_t *st) { sl->q_buf[i] = byte; } stlink_write_mem8(sl, start, align_count); + cache_change(start, align_count); start += align_count; count -= align_count; hexdata += 2*align_count; @@ -1213,6 +1375,7 @@ int serve(stlink_t *sl, st_state_t *st) { sl->q_buf[i] = byte; } stlink_write_mem32(sl, start, aligned_count); + cache_change(start, aligned_count); count -= aligned_count; start += aligned_count; hexdata += 2*aligned_count; @@ -1225,6 +1388,7 @@ int serve(stlink_t *sl, st_state_t *st) { sl->q_buf[i] = byte; } stlink_write_mem8(sl, start, count); + cache_change(start, count); } reply = strdup("OK"); break; From 433a0eb53aad10a00b4a1513099a1c54095a84f9 Mon Sep 17 00:00:00 2001 From: Greg Meiste Date: Mon, 19 Oct 2015 09:24:40 -0500 Subject: [PATCH 0350/1435] Allow flashing of STM32L4 down to 1.71 V The STM32L4 specification specifies that VDD can be 1.71 - 3.6 V. Signed-off-by: Greg Meiste --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index cfb1fbbaf..4ad28eef3 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1818,7 +1818,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } else { /* L4 does not have a byte-write mode */ int voltage = stlink_target_voltage(sl); - if (voltage <= 2700) { + if (voltage < 1710) { printf("Target voltage (%d mV) too low for flash writes!\n", voltage); return -1; } From ff40ab6681591efa23d1068faae3417ff75d2393 Mon Sep 17 00:00:00 2001 From: Greg Meiste Date: Wed, 27 May 2015 10:12:40 -0500 Subject: [PATCH 0351/1435] Fix issue where "unknown chip id!" is seen every other time Previously when running the program, reading the chip version would fail. Running the program a second time worked. This sequence is repeated the next time st-flash/st-util is run. Giving reset 10ms to complete before trying to read the chip version resolves the issue. Signed-off-by: Greg Meiste --- src/stlink-usb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 546f722ea..0911ff7b9 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "stlink-common.h" #include "stlink-usb.h" @@ -879,6 +880,7 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { if (reset) { stlink_reset(sl); + usleep(10000); } stlink_version(sl); error = stlink_load_device_params(sl); From 2d8cb6be855d83af9dfd46601d6e08faf957a563 Mon Sep 17 00:00:00 2001 From: Greg Meiste Date: Wed, 27 May 2015 13:20:07 -0500 Subject: [PATCH 0352/1435] Add memory map for STM32L4 Signed-off-by: Greg Meiste --- gdbserver/gdb-server.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 49c7e6dd4..12c7c9f94 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -370,6 +370,25 @@ static const char* const memory_map_template_F2 = " " // option byte area ""; +static const char* const memory_map_template_L4 = + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // SRAM2 (32 KB) + " " // SRAM1 (96 KB) + " " + " 0x800" + " " + " " // peripheral regs + " " // AHB3 Peripherals + " " // cortex regs + " " // bootrom + " " // option byte area + " " // option byte area + ""; + static const char* const memory_map_template = "" "sram_size, sl->flash_size - 0x20000, sl->sys_base, sl->sys_size); + } else if(sl->chip_id==STM32_CHIPID_L4) { + snprintf(map, 4096, memory_map_template_L4, + sl->flash_size, sl->flash_size); } else { snprintf(map, 4096, memory_map_template, sl->flash_size, From ea649eb6e7cf3dbe98dc00f5a96566df9b6fdcea Mon Sep 17 00:00:00 2001 From: Greg Meiste Date: Mon, 1 Feb 2016 09:08:59 -0600 Subject: [PATCH 0353/1435] st-util: Fix for connecting to running devices Previously, even with the reset enabled, st-util would not connect to a target if it was running. This change will reset the chip when opening the connection, which allows st-util to connect successfully. Signed-off-by: Greg Meiste --- gdbserver/gdb-server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 49c7e6dd4..1981fc5e2 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -174,11 +174,11 @@ int main(int argc, char** argv) { parse_options(argc, argv, &state); switch (state.stlink_version) { case 2: - sl = stlink_open_usb(state.logging_level, 0, NULL); + sl = stlink_open_usb(state.logging_level, state.reset, NULL); if(sl == NULL) return 1; break; case 1: - sl = stlink_v1_open(state.logging_level, 0); + sl = stlink_v1_open(state.logging_level, state.reset); if(sl == NULL) return 1; break; } From c632f855ef63a7421bf200f9979aee6ec57eb1ed Mon Sep 17 00:00:00 2001 From: "fabien.lementec" Date: Mon, 1 Feb 2016 17:02:55 +0100 Subject: [PATCH 0354/1435] fix signed unsigned comparison --- gdbserver/gdb-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 1fe076eec..c8152118b 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -812,7 +812,7 @@ static struct cache_desc_t cache_desc; static unsigned ceil_log2(unsigned v) { unsigned res; - for (res = 0; (1 << res) < v; res++) + for (res = 0; (1U << res) < v; res++) ; return res; } From 094fe67773541cd4547a4dbf4804f51b4293597e Mon Sep 17 00:00:00 2001 From: Bruno Dal Bo Date: Wed, 3 Feb 2016 13:06:18 -0800 Subject: [PATCH 0355/1435] fix on stm32l4 to clear flash mass erase flags on CR --- src/stlink-common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index 4ad28eef3..f2888d10b 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -435,6 +435,8 @@ static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { uint32_t x = read_flash_cr(sl); x &=~ STM32L4_FLASH_CR_OPBITS; x &=~ STM32L4_FLASH_CR_PAGEMASK; + x &= ~(1< Date: Wed, 3 Feb 2016 13:10:54 -0800 Subject: [PATCH 0356/1435] clean SR flags before programming CR --- src/stlink-common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stlink-common.c b/src/stlink-common.c index f2888d10b..04e616762 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -432,6 +432,7 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { } static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { + stlink_write_debug32(sl, STM32L4_FLASH_SR, 0xFFFFFFFF & ~(1< Date: Mon, 15 Feb 2016 14:55:09 +0100 Subject: [PATCH 0357/1435] Added STM32F051R8T6 --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index ac1dd0efd..1f9d33cdd 100644 --- a/README +++ b/README @@ -190,6 +190,7 @@ Known Working Targets: * STM32L052K8T6 (custom board) * STM32L151CB (custom board) * STM32L152RB (STM32L-Discovery board, custom board) +* STM32F051R8T6 (STM320518-EVAL board) STLink v2-1 (as found on the Nucleo boards) Known Working Targets: From 23c79078aceff7103fa56894e1554a71ee9e308c Mon Sep 17 00:00:00 2001 From: George Talusan Date: Thu, 18 Feb 2016 22:56:27 -0500 Subject: [PATCH 0358/1435] remove empty byte truncation from stlink_fread --- src/stlink-common.c | 41 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 04e616762..f17bf72c7 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1032,9 +1032,6 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) int error = -1; size_t off; int num_empty = 0; - unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 - || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH - || sl->chip_id == STM32_CHIPID_L152_RE) ? 0:0xff; const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); if (fd == -1) { @@ -1048,38 +1045,26 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) if (size > sl->flash_size) size = sl->flash_size; - /* do the copy by 1k blocks */ - for (off = 0; off < size; off += 1024) { - size_t read_size = 1024; - size_t rounded_size; - size_t index; - if ((off + read_size) > size) - read_size = size - off; + size_t cmp_size = (sl->flash_pgsz > 0x1800)? 0x1800:sl->flash_pgsz; + for (off = 0; off < size; off += cmp_size) { + size_t aligned_size; - /* round size if needed */ - rounded_size = read_size; - if (rounded_size & 3) - rounded_size = (rounded_size + 4) & ~(3); + /* adjust last page size */ + if ((off + cmp_size) > size) + cmp_size = size - off; - stlink_read_mem32(sl, addr + off, rounded_size); + aligned_size = cmp_size; + if (aligned_size & (4 - 1)) + aligned_size = (cmp_size + 4) & ~(4 - 1); - for(index = 0; index < read_size; index ++) { - if (sl->q_buf[index] == erased_pattern) - num_empty ++; - else - num_empty = 0; - } - if (write(fd, sl->q_buf, read_size) != (ssize_t) read_size) { - fprintf(stderr, "write() != read_size\n"); + stlink_read_mem32(sl, addr + off, aligned_size); + + if (write(fd, sl->q_buf, sl->q_len) != (ssize_t) aligned_size) { + fprintf(stderr, "write() != aligned_size\n"); goto on_error; } } - /* Ignore NULL Bytes at end of file */ - if (!ftruncate(fd, size - num_empty)) { - error = -1; - } - /* success */ error = 0; From 426cdd08669f51f8d8aa5307280f59898694a30c Mon Sep 17 00:00:00 2001 From: George Talusan Date: Fri, 19 Feb 2016 00:04:44 -0500 Subject: [PATCH 0359/1435] clamp gdb memory reads to 0x1800 --- gdbserver/gdb-server.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index c8152118b..b272f4caa 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -1353,6 +1353,12 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned adj_start = start % 4; unsigned count_rnd = (count + adj_start + 4 - 1) / 4 * 4; + if (count_rnd > sl->flash_pgsz) + count_rnd = sl->flash_pgsz; + if (count_rnd > 0x1800) + count_rnd = 0x1800; + if (count_rnd < count) + count = count_rnd; stlink_read_mem32(sl, start - adj_start, count_rnd); From 210858549fa7f6e2dad54486027cbe5f8ff66e16 Mon Sep 17 00:00:00 2001 From: George Talusan Date: Fri, 19 Feb 2016 11:11:31 -0500 Subject: [PATCH 0360/1435] use libusb synchronous api --- src/stlink-common.c | 1 - src/stlink-usb.c | 139 ++++++-------------------------------------- src/stlink-usb.h | 2 - 3 files changed, 19 insertions(+), 123 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index f17bf72c7..90d71f31e 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1031,7 +1031,6 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) int error = -1; size_t off; - int num_empty = 0; const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); if (fd == -1) { diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 0911ff7b9..d54aea875 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -12,32 +12,12 @@ #include "stlink-usb.h" #include "uglylogging.h" -/* code from bsd timersub.h -http://www.gnu-darwin.org/www001/src/ports/net/libevnet/work/libevnet-0.3.8/libnostd/bsd/sys/time/timersub.h.html -*/ -#if !defined timersub -#define timersub(a, b, r) do { \ - (r)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (r)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((r)->tv_usec < 0) { \ - --(r)->tv_sec; \ - (r)->tv_usec += 1000000; \ - } \ -} while (0) -#endif - 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? if (handle != NULL) { - if (handle->req_trans != NULL) - libusb_free_transfer(handle->req_trans); - - if (handle->rep_trans != NULL) - libusb_free_transfer(handle->rep_trans); - if (handle->usb_handle != NULL) { libusb_close(handle->usb_handle); } @@ -47,111 +27,42 @@ void _stlink_usb_close(stlink_t* sl) { } } - -struct trans_ctx { -#define TRANS_FLAGS_IS_DONE (1 << 0) -#define TRANS_FLAGS_HAS_ERROR (1 << 1) - volatile unsigned long flags; -}; - -#ifndef LIBUSB_CALL -# define LIBUSB_CALL -#endif - -static void LIBUSB_CALL on_trans_done(struct libusb_transfer * trans) { - struct trans_ctx * const ctx = trans->user_data; - - if (trans->status != LIBUSB_TRANSFER_COMPLETED) - ctx->flags |= TRANS_FLAGS_HAS_ERROR; - - ctx->flags |= TRANS_FLAGS_IS_DONE; -} - -int submit_wait(struct stlink_libusb *slu, struct libusb_transfer * trans) { - struct timeval start; - struct timeval now; - struct timeval diff; - struct trans_ctx trans_ctx; - enum libusb_error error; - - trans_ctx.flags = 0; - - /* brief intrusion inside the libusb interface */ - trans->callback = on_trans_done; - trans->user_data = &trans_ctx; - - if ((error = libusb_submit_transfer(trans))) { - printf("libusb_submit_transfer(%d)\n", error); - return -1; - } - - gettimeofday(&start, NULL); - - while (trans_ctx.flags == 0) { - struct timeval timeout; - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if (libusb_handle_events_timeout(slu->libusb_ctx, &timeout)) { - printf("libusb_handle_events()\n"); - return -1; - } - - gettimeofday(&now, NULL); - timersub(&now, &start, &diff); - if (diff.tv_sec >= 3) { - printf("libusb_handle_events() timeout\n"); - return -1; - } - } - - if (trans_ctx.flags & TRANS_FLAGS_HAS_ERROR) { - printf("libusb_handle_events() | has_error\n"); - return -1; - } - - return 0; -} - 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, - txbuf, txsize, - NULL, NULL, - 0 - ); - - if (submit_wait(handle, handle->req_trans)) return -1; + if (libusb_bulk_transfer(handle->usb_handle, handle->ep_req, + txbuf, + txsize, + &res, + 3000)) + return -1; - /* send_only */ 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 (libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, + rxbuf, + rxsize, + &res, + 3000)) + return -1; } 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); + if (libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, + sg_buf, + 13, + &res, + 3000)) + return -1; /* The STLink doesn't seem to evaluate the sequence number */ handle->sg_transfer_idx++; - if (res ) return -1; } - return handle->rep_trans->actual_length; + return res; } static inline int send_only @@ -843,18 +754,6 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { goto on_libusb_error; } - slu->req_trans = libusb_alloc_transfer(0); - if (slu->req_trans == NULL) { - WLOG("libusb_alloc_transfer failed\n"); - goto on_libusb_error; - } - - slu->rep_trans = libusb_alloc_transfer(0); - if (slu->rep_trans == NULL) { - 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; if (desc.idProduct == USB_STLINK_NUCLEO_PID) { diff --git a/src/stlink-usb.h b/src/stlink-usb.h index d7e745f51..938c07bcb 100644 --- a/src/stlink-usb.h +++ b/src/stlink-usb.h @@ -21,8 +21,6 @@ extern "C" { struct stlink_libusb { libusb_context* libusb_ctx; libusb_device_handle* usb_handle; - struct libusb_transfer* req_trans; - struct libusb_transfer* rep_trans; unsigned int ep_req; unsigned int ep_rep; int protocoll; From 969fa1279b98e1198aa4fc684b580d35b8f2c480 Mon Sep 17 00:00:00 2001 From: George Talusan Date: Mon, 22 Feb 2016 11:41:48 -0500 Subject: [PATCH 0361/1435] make usb backend status check work, remove some dead code --- src/stlink-usb.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index d54aea875..c4c693d2b 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -259,6 +259,7 @@ void _stlink_usb_status(stlink_t * sl) { printf("[!] send_recv\n"); return; } + sl->q_len = (size_t) size; } void _stlink_usb_force_debug(stlink_t *sl) { @@ -644,7 +645,6 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; int error = -1; - libusb_device** devs = NULL; int config; sl = malloc(sizeof (stlink_t)); @@ -785,10 +785,6 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { error = stlink_load_device_params(sl); on_libusb_error: - if (devs != NULL) { - libusb_free_device_list(devs, 1); - } - if (error == -1) { stlink_close(sl); return NULL; From 09a81132776d0be0ae563a31929eb2f33d68e8bd Mon Sep 17 00:00:00 2001 From: George Talusan Date: Mon, 22 Feb 2016 20:07:43 -0500 Subject: [PATCH 0362/1435] make st-flash clean up on sigint/term/segv, make gdb-server clean up on sigsegv. --- flash/main.c | 19 +++++++++++++++++++ gdbserver/gdb-server.c | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/flash/main.c b/flash/main.c index d0d303a0d..284068cb5 100644 --- a/flash/main.c +++ b/flash/main.c @@ -3,6 +3,7 @@ // TODO - this should be done as just a simple flag to the st-util command line... +#include #include #include #include @@ -12,6 +13,19 @@ #define DEBUG_LOG_LEVEL 100 #define STND_LOG_LEVEL 50 +stlink_t *connected_stlink = NULL; + +static void cleanup(int signal __attribute__((unused))) { + if (connected_stlink) { + /* Switch back to mass storage mode before closing. */ + stlink_run(connected_stlink); + stlink_exit_debug_mode(connected_stlink); + stlink_close(connected_stlink); + } + + exit(1); +} + enum st_cmds {DO_WRITE = 0, DO_READ = 1, DO_ERASE = 2}; struct opts { @@ -174,6 +188,11 @@ int main(int ac, char** av) sl->verbose = o.log_level; } + connected_stlink = sl; + signal(SIGINT, &cleanup); + signal(SIGTERM, &cleanup); + signal(SIGSEGV, &cleanup); + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) stlink_exit_dfu_mode(sl); diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index b272f4caa..0c31cff18 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #ifdef __MINGW32__ @@ -186,6 +185,7 @@ int main(int argc, char** argv) { connected_stlink = sl; signal(SIGINT, &cleanup); signal(SIGTERM, &cleanup); + signal(SIGSEGV, &cleanup); if (state.reset) { stlink_reset(sl); From 60bd03a5178e338b04703783a686d9c73633ba63 Mon Sep 17 00:00:00 2001 From: George Talusan Date: Sat, 27 Feb 2016 11:41:39 -0500 Subject: [PATCH 0363/1435] be quicker about determining erased byte pattern when flashing --- gdbserver/gdb-server.c | 2 +- src/stlink-common.c | 18 ++++++++++-------- src/stlink-common.h | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 0c31cff18..ef289f282 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -752,7 +752,7 @@ static int flash_go(stlink_t *sl) { DLOG("flash_do: page %08x\n", page); unsigned send = length > FLASH_PAGE ? FLASH_PAGE : length; if(stlink_write_flash(sl, page, fb->data + (page - fb->addr), - send) < 0) + send, 0) < 0) goto error; length -= send; diff --git a/src/stlink-common.c b/src/stlink-common.c index 90d71f31e..917a1e0e3 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1723,7 +1723,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uin return 0; } -int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { +int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len, uint8_t eraseonly) { size_t off; flash_loader_t fl; ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", @@ -1769,6 +1769,9 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t ILOG("Finished erasing %d pages of %d (%#x) bytes\n", page_count, sl->flash_pgsz, sl->flash_pgsz); + if (eraseonly) + return 0; + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || @@ -1972,19 +1975,18 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { ELOG("map_file() == -1\n"); return -1; } - for(index = 0; index < mf.len; index ++) { - if (mf.base[index] == erased_pattern) - num_empty ++; - else - num_empty = 0; + for(index = mf.len - 1; num_empty < mf.len; index --) { + if (mf.base[index] != erased_pattern) { + break; + } + num_empty ++; } /* Round down to words */ num_empty -= (num_empty & 3); if(num_empty != 0) { ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); - mf.len -= num_empty; } - err = stlink_write_flash(sl, addr, mf.base, mf.len); + err = stlink_write_flash(sl, addr, mf.base, num_empty == mf.len? mf.len : mf.len - num_empty, num_empty == mf.len); /* set stack*/ stlink_write_reg(sl, stlink_read_debug32(sl, addr ),13); /* Set PC to the reset routine*/ diff --git a/src/stlink-common.h b/src/stlink-common.h index a0bd64909..2751ac839 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -655,7 +655,7 @@ extern "C" { // unprocessed int stlink_erase_flash_mass(stlink_t* sl); - int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length); + int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); 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); From 5df03b2270d6a9c0194b5abc96da2eba9ab083ff Mon Sep 17 00:00:00 2001 From: texane Date: Sat, 27 Feb 2016 19:17:19 +0100 Subject: [PATCH 0364/1435] be quicker about determining erased byte pattern when flashing, more readable code --- src/stlink-common.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 917a1e0e3..51efae43f 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1966,7 +1966,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { /* write the file in flash at addr */ int err; - unsigned int num_empty = 0, index; + unsigned int num_empty, index; unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) ? 0:0xff; @@ -1975,11 +1975,11 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { ELOG("map_file() == -1\n"); return -1; } - for(index = mf.len - 1; num_empty < mf.len; index --) { - if (mf.base[index] != erased_pattern) { + index = mf.len; + for(num_empty = 0; num_empty != mf.len; ++num_empty) { + if (mf.base[--index] != erased_pattern) { break; } - num_empty ++; } /* Round down to words */ num_empty -= (num_empty & 3); From 61b41b03aaafc9ca11c076127ce2c19b323ba914 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 11 Mar 2016 22:13:09 +0100 Subject: [PATCH 0365/1435] Add st-info to CMakeLists.txt --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2358898e3..6f5be17ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,7 +38,10 @@ add_executable(st-util gdbserver/gdb-remote.c gdbserver/gdb-server.h) target_link_libraries(st-util stlink) -install(TARGETS stlink st-flash st-util +add_executable(st-info src/st-info.c) +target_link_libraries(st-info stlink) + +install(TARGETS stlink st-flash st-util st-info RUNTIME DESTINATION bin ARCHIVE DESTINATION lib) From bd272132992cf8308ad898aa2da9002a7344837d Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Thu, 10 Mar 2016 16:15:57 +0100 Subject: [PATCH 0366/1435] read_debug32: Use a pointer instead of returning the value This rework is done in order to prepare for propagating errors returned by libusb. Signed-off-by: Maxime Coquelin --- gdbserver/gdb-server.c | 24 +++--- src/stlink-common.c | 176 ++++++++++++++++++++++++----------------- src/stlink-common.h | 4 +- src/stlink-sg.c | 5 +- src/stlink-usb.c | 7 +- 5 files changed, 128 insertions(+), 88 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index ef289f282..eca6597b4 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -488,11 +488,13 @@ struct code_hw_watchpoint { struct code_hw_watchpoint data_watches[DATA_WATCH_NUM]; static void init_data_watchpoints(stlink_t *sl) { + uint32_t data; DLOG("init watchpoints\n"); + stlink_read_debug32(sl, 0xE000EDFC, &data); + data |= 1<<24; // set trcena in debug command to turn on dwt unit - stlink_write_debug32(sl, 0xE000EDFC, - stlink_read_debug32(sl, 0xE000EDFC) | (1<<24)); + stlink_write_debug32(sl, 0xE000EDFC, data); // make sure all watchpoints are cleared for(int i = 0; i < DATA_WATCH_NUM; i++) { @@ -504,7 +506,7 @@ static void init_data_watchpoints(stlink_t *sl) { static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr, unsigned int len) { int i = 0; - uint32_t mask; + uint32_t mask, dummy; // computer mask // find a free watchpoint @@ -537,7 +539,7 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stlink_write_debug32(sl, 0xE0001028 + i * 16, wf); // just to make sure the matched bit is clear ! - stlink_read_debug32(sl, 0xE0001028 + i * 16); + stlink_read_debug32(sl, 0xE0001028 + i * 16, &dummy); return 0; } } @@ -581,9 +583,10 @@ struct code_hw_breakpoint { struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM_MAX]; static void init_code_breakpoints(stlink_t *sl) { + unsigned int val; memset(sl->q_buf, 0, 4); stlink_write_debug32(sl, CM3_REG_FP_CTRL, 0x03 /*KEY | ENABLE4*/); - unsigned int val = stlink_read_debug32(sl, CM3_REG_FP_CTRL); + stlink_read_debug32(sl, CM3_REG_FP_CTRL, &val); code_break_num = ((val >> 4) & 0xf); code_lit_num = ((val >> 8) & 0xf); @@ -821,7 +824,8 @@ static void read_cache_level_desc(stlink_t *sl, struct cache_level_desc *desc) { unsigned int ccsidr; unsigned int log2_nsets; - ccsidr = stlink_read_debug32(sl, CCSIDR); + + stlink_read_debug32(sl, CCSIDR, &ccsidr); desc->nsets = ((ccsidr >> 13) & 0x3fff) + 1; desc->nways = ((ccsidr >> 3) & 0x1ff) + 1; desc->log2_nways = ceil_log2 (desc->nways); @@ -841,9 +845,9 @@ static void init_cache (stlink_t *sl) { if(sl->chip_id!=STM32_CHIPID_F7) return; - clidr = stlink_read_debug32(sl, CLIDR); - ccr = stlink_read_debug32(sl, CCR); - ctr = stlink_read_debug32(sl, CTR); + stlink_read_debug32(sl, CLIDR, &clidr); + stlink_read_debug32(sl, CCR, &ccr); + stlink_read_debug32(sl, CTR, &ctr); cache_desc.dminline = 4 << ((ctr >> 16) & 0x0f); cache_desc.iminline = 4 << (ctr & 0x0f); cache_desc.louu = (clidr >> 27) & 7; @@ -925,7 +929,7 @@ static void cache_sync(stlink_t *sl) return; cache_modified = 0; - ccr = stlink_read_debug32(sl, CCR); + stlink_read_debug32(sl, CCR, &ccr); if (ccr & (CCR_IC | CCR_DC)) cache_flush(sl, ccr); } diff --git a/src/stlink-common.c b/src/stlink-common.c index 51efae43f..a20f3fa4f 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -165,15 +165,21 @@ uint32_t read_uint32(const unsigned char *c, const int pt) { } static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { - return stlink_read_debug32(sl, FLASH_WRPR) & 0xff; + uint32_t rdp; + stlink_read_debug32(sl, FLASH_WRPR, &rdp); + return rdp & 0xff; } static inline uint32_t read_flash_wrpr(stlink_t *sl) { - return stlink_read_debug32(sl, FLASH_WRPR); + uint32_t wrpr; + stlink_read_debug32(sl, FLASH_WRPR, &wrpr); + return wrpr; } static inline uint32_t read_flash_obr(stlink_t *sl) { - return stlink_read_debug32(sl, FLASH_OBR); + uint32_t obr; + stlink_read_debug32(sl, FLASH_OBR, &obr); + return obr; } static inline uint32_t read_flash_cr(stlink_t *sl) { @@ -181,11 +187,11 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||(sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) - res = stlink_read_debug32(sl, FLASH_F4_CR); + stlink_read_debug32(sl, FLASH_F4_CR, &res); else if (sl->chip_id == STM32_CHIPID_L4) - res = stlink_read_debug32(sl, STM32L4_FLASH_CR); + stlink_read_debug32(sl, STM32L4_FLASH_CR, &res); else - res = stlink_read_debug32(sl, FLASH_CR); + stlink_read_debug32(sl, FLASH_CR, &res); #if DEBUG_FLASH fprintf(stdout, "CR:0x%x\n", res); #endif @@ -297,51 +303,63 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { } static void set_flash_cr_mer(stlink_t *sl) { + uint32_t val; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) - stlink_write_debug32(sl, FLASH_F4_CR, - stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); - else if (sl->chip_id == STM32_CHIPID_L4) { - uint32_t x = stlink_read_debug32(sl, STM32L4_FLASH_CR); - x &=~ STM32L4_FLASH_CR_OPBITS; - x |= (1lu << STM32L4_FLASH_CR_MER1) | (1lu << STM32L4_FLASH_CR_MER2); - stlink_write_debug32(sl, STM32L4_FLASH_CR, x); - } else - stlink_write_debug32(sl, FLASH_CR, - stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_MER)); + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { + stlink_read_debug32(sl, FLASH_F4_CR, &val); + val |= 1 << FLASH_CR_MER; + stlink_write_debug32(sl, FLASH_F4_CR, val); + } else if (sl->chip_id == STM32_CHIPID_L4) { + stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); + val &=~ STM32L4_FLASH_CR_OPBITS; + val |= (1lu << STM32L4_FLASH_CR_MER1) | (1lu << STM32L4_FLASH_CR_MER2); + stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + } else { + stlink_read_debug32(sl, FLASH_CR, &val); + val |= 1 << FLASH_CR_MER; + stlink_write_debug32(sl, FLASH_CR, val); + } } static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { + uint32_t val; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) - stlink_write_debug32(sl, FLASH_F4_CR, - stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); - else - stlink_write_debug32(sl, FLASH_CR, - stlink_read_debug32(sl, FLASH_CR) & ~(1 << FLASH_CR_MER)); + (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { + stlink_read_debug32(sl, FLASH_F4_CR, &val); + val &= ~(1 << FLASH_CR_MER); + stlink_write_debug32(sl, FLASH_F4_CR, val); + } else { + stlink_read_debug32(sl, FLASH_CR, &val); + val &= ~(1 << FLASH_CR_MER); + stlink_write_debug32(sl, FLASH_CR, val); + } } static void set_flash_cr_strt(stlink_t *sl) { + uint32_t val; if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { - uint32_t x = read_flash_cr(sl); - x |= (1 << FLASH_F4_CR_STRT); - stlink_write_debug32(sl, FLASH_F4_CR, x); + val = read_flash_cr(sl); + val |= (1 << FLASH_F4_CR_STRT); + stlink_write_debug32(sl, FLASH_F4_CR, val); } else if (sl->chip_id == STM32_CHIPID_L4) { - uint32_t x = read_flash_cr(sl); - x |= (1lu << STM32L4_FLASH_CR_STRT); - stlink_write_debug32(sl, STM32L4_FLASH_CR, x); + val = read_flash_cr(sl); + val |= (1lu << STM32L4_FLASH_CR_STRT); + stlink_write_debug32(sl, STM32L4_FLASH_CR, val); } else { - stlink_write_debug32(sl, FLASH_CR, - stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_STRT) ); + stlink_read_debug32(sl, FLASH_CR, &val); + val |= 1 << FLASH_CR_STRT; + stlink_write_debug32(sl, FLASH_CR, val); } } static inline uint32_t read_flash_acr(stlink_t *sl) { - return stlink_read_debug32(sl, FLASH_ACR); + uint32_t acr; + stlink_read_debug32(sl, FLASH_ACR, &acr); + return acr; } static inline uint32_t read_flash_sr(stlink_t *sl) { @@ -349,11 +367,11 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) - res = stlink_read_debug32(sl, FLASH_F4_SR); + stlink_read_debug32(sl, FLASH_F4_SR, &res); else if (sl->chip_id == STM32_CHIPID_L4) - res = stlink_read_debug32(sl, STM32L4_FLASH_SR); + stlink_read_debug32(sl, STM32L4_FLASH_SR, &res); else - res = stlink_read_debug32(sl, FLASH_SR); + stlink_read_debug32(sl, FLASH_SR, &res); //fprintf(stdout, "SR:0x%x\n", *(uint32_t*) sl->q_buf); return res; } @@ -486,8 +504,10 @@ uint32_t stlink_core_id(stlink_t *sl) { } uint32_t stlink_chip_id(stlink_t *sl) { - uint32_t chip_id = stlink_read_debug32(sl, 0xE0042000); - if (chip_id == 0) chip_id = stlink_read_debug32(sl, 0x40015800); //Try Corex M0 DBGMCU_IDCODE register address + uint32_t chip_id; + stlink_read_debug32(sl, 0xE0042000, &chip_id); + if (chip_id == 0) + stlink_read_debug32(sl, 0x40015800, &chip_id); //Try Corex M0 DBGMCU_IDCODE register address return chip_id; } @@ -497,7 +517,8 @@ uint32_t stlink_chip_id(stlink_t *sl) { * @param cpuid pointer to the result object */ void stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { - uint32_t raw = stlink_read_debug32(sl, CM3_REG_CPUID); + uint32_t raw; + stlink_read_debug32(sl, CM3_REG_CPUID, &raw); cpuid->implementer_id = (raw >> 24) & 0x7f; cpuid->variant = (raw >> 20) & 0xf; cpuid->part = (raw >> 4) & 0xfff; @@ -520,7 +541,8 @@ int stlink_load_device_params(stlink_t *sl) { sl->chip_id = chip_id & 0xfff; /* Fix chip_id for F4 rev A errata , Read CPU ID, as CoreID is the same for F2/F4*/ if (sl->chip_id == 0x411) { - uint32_t cpuid = stlink_read_debug32(sl, 0xE000ED00); + uint32_t cpuid; + stlink_read_debug32(sl, 0xE000ED00, &cpuid); if ((cpuid & 0xfff0) == 0xc240) sl->chip_id = 0x413; } @@ -539,7 +561,7 @@ int stlink_load_device_params(stlink_t *sl) { // These are fixed... sl->flash_base = STM32_FLASH_BASE; sl->sram_base = STM32_SRAM_BASE; - flash_size = stlink_read_debug32(sl,(params->flash_size_reg) & ~3); + stlink_read_debug32(sl,(params->flash_size_reg) & ~3, &flash_size); if (params->flash_size_reg & 2) flash_size = flash_size >>16; flash_size = flash_size & 0xffff; @@ -657,10 +679,10 @@ int stlink_target_voltage(stlink_t *sl) { return voltage; } -uint32_t stlink_read_debug32(stlink_t *sl, uint32_t addr) { - uint32_t data = sl->backend->read_debug32(sl, addr); +void stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { + sl->backend->read_debug32(sl, addr, data); DLOG("*** stlink_read_debug32 %x is %#x\n", data, addr); - return data; + return; } void stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { @@ -958,6 +980,7 @@ int stlink_fwrite_sram size_t off; size_t len; mapped_file_t mf = MAPPED_FILE_INITIALIZER; + uint32_t val; if (map_file(&mf, path) == -1) { @@ -1016,9 +1039,11 @@ int stlink_fwrite_sram /* success */ error = 0; /* set stack*/ - stlink_write_reg(sl, stlink_read_debug32(sl, addr ),13); + stlink_read_debug32(sl, addr, &val); + stlink_write_reg(sl, val, 13); /* Set PC to the reset routine*/ - stlink_write_reg(sl, stlink_read_debug32(sl, addr + 4),15); + stlink_read_debug32(sl, addr + 4, &val); + stlink_write_reg(sl, val, 15); stlink_run(sl); on_error: @@ -1115,7 +1140,8 @@ uint32_t calculate_F7_sectornum(uint32_t flashaddr){ // Returns BKER:PNB for the given page address uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { uint32_t bker = 0; - uint32_t flashopt = stlink_read_debug32(sl, STM32L4_FLASH_OPTR); + uint32_t flashopt; + stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); flashaddr -= STM32_FLASH_BASE; if (flashopt & (1lu << STM32L4_FLASH_OPTR_DUALBANK)) { uint32_t banksize = sl->flash_size / 2; @@ -1217,14 +1243,14 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } /* check if the locks are set */ - val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); if((val & (1<<0))||(val & (1<<1))) { /* disable pecr protection */ stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x89abcdef); stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x02030405); /* check pecr.pelock is cleared */ - val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); if (val & (1 << 0)) { WLOG("pecr.pelock not clear (%#x)\n", val); return -1; @@ -1235,7 +1261,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, 0x13141516); /* check pecr.prglock is cleared */ - val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); if (val & (1 << 1)) { WLOG("pecr.prglock not clear (%#x)\n", val); return -1; @@ -1253,8 +1279,9 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) * TEXANE: ok, if experience says so and it works for you, we comment * it. If someone has a problem, please drop an email. */ - while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) - ; + do { + stlink_read_debug32(sl, STM32L_FLASH_SR, &val) + } while((val & (1 << 0)) != 0); #endif /* fix_to_be_confirmed */ @@ -1265,12 +1292,13 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) page erase command, even though PM0062 recommends to wait before it. Test shows that a few iterations is performed in the following loop before busy bit is cleared.*/ - while ((stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF) & (1 << 0)) != 0) - ; + do { + stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); + } while ((val & (1 << 0)) != 0); /* reset lock bits */ - val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF) - | (1 << 0) | (1 << 1) | (1 << 2); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID @@ -1687,18 +1715,20 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uin return -1; } /* Unlock already done */ - val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << FLASH_L1_FPRG); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); val |= (1 << FLASH_L1_PROG); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - while ((stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF) & (1 << 0)) != 0) {} + do { + stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); + } while ((val & (1 << 0)) != 0); for (count = 0; count < num_half_pages; count ++) { if (run_flash_loader(sl, &fl, addr + count * pagesize, base + count * pagesize, pagesize) == -1) { WLOG("l1_run_flash_loader(%#zx) failed! == -1\n", addr + count * pagesize); - val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val &= ~((1 << FLASH_L1_FPRG) |(1 << FLASH_L1_PROG)); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); return -1; @@ -1710,13 +1740,14 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uin fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); fflush(stdout); } - while ((stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF) & (1 << 0)) != 0) { - } + do { + stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); + } while ((val & (1 << 0)) != 0); } - val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val &= ~(1 << FLASH_L1_PROG); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val &= ~(1 << FLASH_L1_FPRG); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); @@ -1858,7 +1889,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x02030405); /* check pecr.pelock is cleared */ - val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); if (val & (1 << 0)) { fprintf(stderr, "pecr.pelock not clear\n"); return -1; @@ -1869,7 +1900,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, 0x13141516); /* check pecr.prglock is cleared */ - val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); if (val & (1 << 1)) { fprintf(stderr, "pecr.prglock not clear\n"); return -1; @@ -1900,16 +1931,17 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t stlink_write_debug32(sl, addr + off, data); /* wait for sr.busy to be cleared */ - while ((stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF) & (1 << 0)) != 0) - ; + do { + stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); + } while ((val & (1 << 0)) != 0); /* todo: check redo write operation */ } fprintf(stdout, "\n"); /* reset lock bits */ - val = stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF) - | (1 << 0) | (1 << 1) | (1 << 2); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || @@ -1966,7 +1998,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { /* write the file in flash at addr */ int err; - unsigned int num_empty, index; + unsigned int num_empty, index, val; unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) ? 0:0xff; @@ -1988,9 +2020,11 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { } err = stlink_write_flash(sl, addr, mf.base, num_empty == mf.len? mf.len : mf.len - num_empty, num_empty == mf.len); /* set stack*/ - stlink_write_reg(sl, stlink_read_debug32(sl, addr ),13); + stlink_read_debug32(sl, addr, &val); + stlink_write_reg(sl, val, 13); /* Set PC to the reset routine*/ - stlink_write_reg(sl, stlink_read_debug32(sl, addr + 4),15); + stlink_read_debug32(sl, addr + 4, &val); + stlink_write_reg(sl, val, 15); stlink_run(sl); unmap_file(&mf); return err; diff --git a/src/stlink-common.h b/src/stlink-common.h index 2751ac839..b3f86768c 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -566,7 +566,7 @@ extern "C" { void (*run) (stlink_t * stl); void (*status) (stlink_t * stl); void (*version) (stlink_t *sl); - uint32_t (*read_debug32) (stlink_t *sl, uint32_t addr); + void (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); void (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); void (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); void (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); @@ -636,7 +636,7 @@ extern "C" { void stlink_run(stlink_t *sl); void stlink_status(stlink_t *sl); void stlink_version(stlink_t *sl); - uint32_t stlink_read_debug32(stlink_t *sl, uint32_t addr); + void stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); void stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); void stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); void stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); diff --git a/src/stlink-sg.c b/src/stlink-sg.c index b16a2edfc..3fdc0bde5 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -811,7 +811,7 @@ void _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { // Read one DWORD data from memory -uint32_t _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr) { +void _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_JTAG_READDEBUG_32BIT; @@ -820,7 +820,8 @@ uint32_t _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr) { sl->q_len = 8; stlink_q(sl); - return read_uint32(sl->q_buf, 4); + *data = read_uint32(sl->q_buf, 4); + return; } // Exit the jtag or swd mode and enter the mass mode. diff --git a/src/stlink-usb.c b/src/stlink-usb.c index c4c693d2b..927e44e96 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -138,7 +138,7 @@ int32_t _stlink_usb_target_voltage(stlink_t *sl) { return voltage; } -uint32_t _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr) { +void _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const rdata = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -152,9 +152,10 @@ uint32_t _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr) { size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return 0; + return; } - return read_uint32(rdata, 4); + *data = read_uint32(rdata, 4); + return; } void _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { From 5fcad7d2bf22c94b711f7c4423646a2ff5bafba8 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Thu, 10 Mar 2016 16:26:48 +0100 Subject: [PATCH 0367/1435] stlink_core_id: No need to return core_id value This rework is done in order to prepare for propagating errors returned by libusb. Signed-off-by: Maxime Coquelin --- src/stlink-common.c | 6 +++--- src/stlink-common.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index a20f3fa4f..683959362 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -494,13 +494,13 @@ void stlink_exit_dfu_mode(stlink_t *sl) { sl->backend->exit_dfu_mode(sl); } -uint32_t stlink_core_id(stlink_t *sl) { +void stlink_core_id(stlink_t *sl) { DLOG("*** stlink_core_id ***\n"); sl->backend->core_id(sl); if (sl->verbose > 2) stlink_print_data(sl); DLOG("core_id = 0x%08x\n", sl->core_id); - return sl->core_id; + return; } uint32_t stlink_chip_id(stlink_t *sl) { @@ -534,7 +534,7 @@ void stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { int stlink_load_device_params(stlink_t *sl) { ILOG("Loading device parameters....\n"); const chip_params_t *params = NULL; - sl->core_id = stlink_core_id(sl); + stlink_core_id(sl); uint32_t chip_id = stlink_chip_id(sl); uint32_t flash_size; diff --git a/src/stlink-common.h b/src/stlink-common.h index b3f86768c..fbbb2b42e 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -630,7 +630,7 @@ extern "C" { void stlink_exit_debug_mode(stlink_t *sl); void stlink_exit_dfu_mode(stlink_t *sl); void stlink_close(stlink_t *sl); - uint32_t stlink_core_id(stlink_t *sl); + void stlink_core_id(stlink_t *sl); void stlink_reset(stlink_t *sl); void stlink_jtag_reset(stlink_t *sl, int value); void stlink_run(stlink_t *sl); From 89c3b1462b8c4b96e2071a87883aed5e030bbef9 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Thu, 10 Mar 2016 16:39:26 +0100 Subject: [PATCH 0368/1435] stlink_target_voltage: Check for libusb error _stlink_usb_target_voltage already returns an error value. If value return is positive, this is a voltage, if negative this is an error. Check the return on callers side to inform there is an error in reading the voltage, instead of notifying of a too low voltage. Signed-off-by: Maxime Coquelin --- src/stlink-common.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 683959362..204491cf6 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1609,7 +1609,10 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) || (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F4_DSI)){ int voltage = stlink_target_voltage(sl); - if (voltage > 2700) { + if (voltage == -1) { + printf("Failed to read Target voltage\n"); + return voltage; + } else if (voltage > 2700) { loader_code = loader_code_stm32f4; loader_size = sizeof(loader_code_stm32f4); } else { @@ -1829,7 +1832,10 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t if (sl->chip_id != STM32_CHIPID_L4) { /* set parallelisim to 32 bit*/ int voltage = stlink_target_voltage(sl); - if (voltage > 2700) { + if (voltage == -1) { + printf("Failed to read Target voltage\n"); + return voltage; + } else if (voltage > 2700) { printf("enabling 32-bit flash writes\n"); write_flash_cr_psiz(sl, 2); } else { @@ -1839,7 +1845,10 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } else { /* L4 does not have a byte-write mode */ int voltage = stlink_target_voltage(sl); - if (voltage < 1710) { + if (voltage == -1) { + printf("Failed to read Target voltage\n"); + return voltage; + } else if (voltage < 1710) { printf("Target voltage (%d mV) too low for flash writes!\n", voltage); return -1; } From 64a48c704ff802b3a08cbdf0dd729f4a7a39ea67 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Fri, 11 Mar 2016 11:16:41 +0100 Subject: [PATCH 0369/1435] Make the backends propagate errors As the libusb returns errors, make the backends propagates them so that callers can decide to continue or stop task execution. Signed-off-by: Maxime Coquelin --- src/stlink-common.h | 46 ++++++------ src/stlink-sg.c | 155 ++++++++++++++++++++++++++------------ src/stlink-usb.c | 178 ++++++++++++++++++++++++++++++-------------- 3 files changed, 255 insertions(+), 124 deletions(-) diff --git a/src/stlink-common.h b/src/stlink-common.h index fbbb2b42e..467b9b90a 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -556,30 +556,30 @@ extern "C" { typedef struct _stlink_backend { void (*close) (stlink_t * sl); - void (*exit_debug_mode) (stlink_t * sl); - void (*enter_swd_mode) (stlink_t * sl); - void (*enter_jtag_mode) (stlink_t * stl); - void (*exit_dfu_mode) (stlink_t * stl); - void (*core_id) (stlink_t * stl); - void (*reset) (stlink_t * stl); - void (*jtag_reset) (stlink_t * stl, int value); - void (*run) (stlink_t * stl); - void (*status) (stlink_t * stl); - void (*version) (stlink_t *sl); - void (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); - void (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); - void (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); - void (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); - void (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); - void (*read_all_regs) (stlink_t *sl, reg * regp); - void (*read_reg) (stlink_t *sl, int r_idx, reg * regp); - void (*read_all_unsupported_regs) (stlink_t *sl, reg *regp); - void (*read_unsupported_reg) (stlink_t *sl, int r_idx, reg *regp); - void (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, reg *regp); - void (*write_reg) (stlink_t *sl, uint32_t reg, int idx); - void (*step) (stlink_t * stl); + int (*exit_debug_mode) (stlink_t * sl); + int (*enter_swd_mode) (stlink_t * sl); + int (*enter_jtag_mode) (stlink_t * stl); + int (*exit_dfu_mode) (stlink_t * stl); + int (*core_id) (stlink_t * stl); + int (*reset) (stlink_t * stl); + int (*jtag_reset) (stlink_t * stl, int value); + int (*run) (stlink_t * stl); + int (*status) (stlink_t * stl); + int (*version) (stlink_t *sl); + int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); + int (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); + int (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); + int (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); + int (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); + int (*read_all_regs) (stlink_t *sl, reg * regp); + int (*read_reg) (stlink_t *sl, int r_idx, reg * regp); + int (*read_all_unsupported_regs) (stlink_t *sl, reg *regp); + int (*read_unsupported_reg) (stlink_t *sl, int r_idx, reg *regp); + int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, reg *regp); + int (*write_reg) (stlink_t *sl, uint32_t reg, int idx); + int (*step) (stlink_t * stl); int (*current_mode) (stlink_t * stl); - void (*force_debug) (stlink_t *sl); + int (*force_debug) (stlink_t *sl); int32_t (*target_voltage) (stlink_t *sl); } stlink_backend_t; diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 3fdc0bde5..03df7d854 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -403,13 +403,13 @@ void stlink_stat(stlink_t *stl, char *txt) { } -void _stlink_sg_version(stlink_t *stl) { +int _stlink_sg_version(stlink_t *stl) { struct stlink_libsg *sl = stl->backend_data; clear_cdb(sl); sl->cdb_cmd_blk[0] = STLINK_GET_VERSION; stl->q_len = 6; sl->q_addr = 0; - stlink_q(stl); + return stlink_q(stl); } // Get stlink mode: @@ -422,44 +422,46 @@ int _stlink_sg_current_mode(stlink_t *stl) { sl->cdb_cmd_blk[0] = STLINK_GET_CURRENT_MODE; stl->q_len = 2; sl->q_addr = 0; - stlink_q(stl); + if (stlink_q(stl)) + return -1; + return stl->q_buf[0]; } // Exit the mass mode and enter the swd debug mode. -void _stlink_sg_enter_swd_mode(stlink_t *sl) { +int _stlink_sg_enter_swd_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_SWD; sl->q_len = 0; // >0 -> aboard - stlink_q(sl); + return stlink_q(sl); } // Exit the mass mode and enter the jtag debug mode. // (jtag is disabled in the discovery's stlink firmware) -void _stlink_sg_enter_jtag_mode(stlink_t *sl) { +int _stlink_sg_enter_jtag_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_enter_jtag_mode ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_JTAG; sl->q_len = 0; - stlink_q(sl); + return stlink_q(sl); } // XXX kernel driver performs reset, the device temporally disappears // Suspect this is no longer the case when we have ignore on? RECHECK -void _stlink_sg_exit_dfu_mode(stlink_t *sl) { +int _stlink_sg_exit_dfu_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_exit_dfu_mode ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[0] = STLINK_DFU_COMMAND; sg->cdb_cmd_blk[1] = STLINK_DFU_EXIT; sl->q_len = 0; // ?? - stlink_q(sl); + return stlink_q(sl); /* [135121.844564] sd 19:0:0:0: [sdb] Unhandled error code [135121.844569] sd 19:0:0:0: [sdb] Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK @@ -505,74 +507,91 @@ void _stlink_sg_exit_dfu_mode(stlink_t *sl) { */ } -void _stlink_sg_core_id(stlink_t *sl) { +int _stlink_sg_core_id(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; + int ret; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READCOREID; sl->q_len = 4; sg->q_addr = 0; - stlink_q(sl); + ret = stlink_q(sl); + if (ret) + return ret; + sl->core_id = read_uint32(sl->q_buf, 0); + return 0; } // Arm-core reset -> halted state. -void _stlink_sg_reset(stlink_t *sl) { +int _stlink_sg_reset(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_RESETSYS; sl->q_len = 2; sg->q_addr = 0; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_stat(sl, "core reset"); + return 0; } // Arm-core reset -> halted state. -void _stlink_sg_jtag_reset(stlink_t *sl, int value) { +int _stlink_sg_jtag_reset(stlink_t *sl, int value) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_JTAG_DRIVE_NRST; sg->cdb_cmd_blk[2] = (value)?0:1; sl->q_len = 3; sg->q_addr = 2; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_stat(sl, "core reset"); + + return 0; } // Arm-core status: halted or running. -void _stlink_sg_status(stlink_t *sl) { +int _stlink_sg_status(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_GETSTATUS; sl->q_len = 2; sg->q_addr = 0; - stlink_q(sl); + return stlink_q(sl); } // Force the core into the debug mode -> halted state. -void _stlink_sg_force_debug(stlink_t *sl) { +int _stlink_sg_force_debug(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_FORCEDEBUG; sl->q_len = 2; sg->q_addr = 0; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_stat(sl, "force debug"); + return 0; } // Read all arm-core registers. -void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { +int _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READALLREGS; sl->q_len = 84; sg->q_addr = 0; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_print_data(sl); // TODO - most of this should be re-extracted up.... @@ -590,27 +609,31 @@ void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { regp->rw = read_uint32(sl->q_buf, 76); regp->rw2 = read_uint32(sl->q_buf, 80); if (sl->verbose < 2) - return; + return 0; DLOG("xpsr = 0x%08x\n", regp->xpsr); DLOG("main_sp = 0x%08x\n", regp->main_sp); DLOG("process_sp = 0x%08x\n", regp->process_sp); DLOG("rw = 0x%08x\n", regp->rw); DLOG("rw2 = 0x%08x\n", regp->rw2); + + return 0; } // Read an arm-core register, the index must be in the range 0..20. // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 -void _stlink_sg_read_reg(stlink_t *sl, int r_idx, reg *regp) { +int _stlink_sg_read_reg(stlink_t *sl, int r_idx, reg *regp) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READREG; sg->cdb_cmd_blk[2] = r_idx; sl->q_len = 4; sg->q_addr = 0; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71 | 72-75 | 76-79 | 80-83 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 @@ -638,13 +661,15 @@ void _stlink_sg_read_reg(stlink_t *sl, int r_idx, reg *regp) { default: regp->r[r_idx] = r; } + + return 0; } // Write an arm-core register. Index: // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 -void _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) { +int _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEREG; @@ -654,8 +679,11 @@ void _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) { write_uint32(sg->cdb_cmd_blk + 3, reg); sl->q_len = 2; sg->q_addr = 0; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_stat(sl, "write reg"); + return 0; } // Write a register of the debug module of the core. @@ -679,26 +707,33 @@ void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { // Force the core exit the debug mode. -void _stlink_sg_run(stlink_t *sl) { +int _stlink_sg_run(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_RUNCORE; sl->q_len = 2; sg->q_addr = 0; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_stat(sl, "run core"); + + return 0; } // Step the arm-core. -void _stlink_sg_step(stlink_t *sl) { +int _stlink_sg_step(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_STEPCORE; sl->q_len = 2; sg->q_addr = 0; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_stat(sl, "step core"); + return 0; } // TODO test @@ -738,7 +773,7 @@ void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) { // Read a "len" bytes to the sl->q_buf from the memory, max 6kB (6144 bytes) -void _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READMEM_32BIT; @@ -754,14 +789,19 @@ void _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { // (broken residue issue) sl->q_len = len; sg->q_addr = addr; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_print_data(sl); + return 0; } // Write a "len" bytes from the sl->q_buf to the memory, max 64 Bytes. -void _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { +int _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; + int ret; + clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEMEM_8BIT; // 2-5: addr @@ -770,16 +810,27 @@ void _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { write_uint16(sg->cdb_cmd_blk + 6, len); // this sends the command... - send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); + ret = send_usb_mass_storage_command(sg->usb_handle, + sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); + if (ret == -1) + return ret; + // This sends the data... - send_usb_data_only(sg->usb_handle, sg->ep_req, sg->ep_rep, sl->q_buf, len); + ret = send_usb_data_only(sg->usb_handle, + sg->ep_req, sg->ep_rep, sl->q_buf, len); + if (ret == -1) + return ret; + stlink_print_data(sl); + return 0; } // Write a "len" bytes from the sl->q_buf to the memory, max Q_BUF_LEN bytes. -void _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; + int ret; + clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEMEM_32BIT; // 2-5: addr @@ -788,16 +839,24 @@ void _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { write_uint16(sg->cdb_cmd_blk + 6, len); // this sends the command... - send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); + ret = send_usb_mass_storage_command(sg->usb_handle, + sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); + if (ret == -1) + return ret; + // This sends the data... - send_usb_data_only(sg->usb_handle, sg->ep_req, sg->ep_rep, sl->q_buf, len); + ret = send_usb_data_only(sg->usb_handle, + sg->ep_req, sg->ep_rep, sl->q_buf, len); + if (ret == -1) + return ret; stlink_print_data(sl); + return 0; } // Write one DWORD data to memory -void _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { +int _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_JTAG_WRITEDEBUG_32BIT; @@ -805,36 +864,38 @@ void _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { write_uint32(sg->cdb_cmd_blk + 2, addr); write_uint32(sg->cdb_cmd_blk + 6, data); sl->q_len = 2; - stlink_q(sl); - + return stlink_q(sl); } // Read one DWORD data from memory -void _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { +int _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_JTAG_READDEBUG_32BIT; // 2-5: addr write_uint32(sg->cdb_cmd_blk + 2, addr); sl->q_len = 8; - stlink_q(sl); + if (stlink_q(sl)) + return -1; *data = read_uint32(sl->q_buf, 4); - return; + return 0; } // Exit the jtag or swd mode and enter the mass mode. -void _stlink_sg_exit_debug_mode(stlink_t *stl) { - +int _stlink_sg_exit_debug_mode(stlink_t *stl) +{ if (stl) { struct stlink_libsg* sl = stl->backend_data; clear_cdb(sl); sl->cdb_cmd_blk[1] = STLINK_DEBUG_EXIT; stl->q_len = 0; // >0 -> aboard - stlink_q(stl); + return stlink_q(stl); } + + return 0; } diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 927e44e96..8e52c6801 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -93,7 +93,7 @@ static int fill_command return i; } -void _stlink_usb_version(stlink_t *sl) { +int _stlink_usb_version(stlink_t *sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -106,8 +106,10 @@ void _stlink_usb_version(stlink_t *sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } int32_t _stlink_usb_target_voltage(stlink_t *sl) { @@ -138,7 +140,7 @@ int32_t _stlink_usb_target_voltage(stlink_t *sl) { return voltage; } -void _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { +int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const rdata = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -152,13 +154,13 @@ void _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } *data = read_uint32(rdata, 4); - return; + return 0; } -void _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { +int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const rdata = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -173,37 +175,54 @@ void _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } -void _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; + int i, ret; - int i = fill_command(sl, SG_DXFER_TO_DEV, len); + 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); + ret = send_only(slu, 0, cmd, slu->cmd_len); + if (ret == -1) + return ret; + + ret = send_only(slu, 1, data, len); + if (ret == -1) + return ret; - send_only(slu, 1, data, len); + return 0; } -void _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { +int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; + int i, ret; - int i = fill_command(sl, SG_DXFER_TO_DEV, 0); + 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); + ret = send_only(slu, 0, cmd, slu->cmd_len); + if (ret == -1) + return ret; + + ret = send_only(slu, 1, data, len); + if (ret == -1) + return ret; + + return 0; } @@ -224,7 +243,7 @@ int _stlink_usb_current_mode(stlink_t * sl) { return sl->q_buf[0]; } -void _stlink_usb_core_id(stlink_t * sl) { +int _stlink_usb_core_id(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; unsigned char* const data = sl->q_buf; @@ -238,13 +257,14 @@ void _stlink_usb_core_id(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return -1; } sl->core_id = read_uint32(data, 0); + return 0; } -void _stlink_usb_status(stlink_t * sl) { +int _stlink_usb_status(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -258,12 +278,14 @@ void _stlink_usb_status(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } sl->q_len = (size_t) size; + + return 0; } -void _stlink_usb_force_debug(stlink_t *sl) { +int _stlink_usb_force_debug(stlink_t *sl) { struct stlink_libusb *slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -276,11 +298,13 @@ void _stlink_usb_force_debug(stlink_t *sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } -void _stlink_usb_enter_swd_mode(stlink_t * sl) { +int _stlink_usb_enter_swd_mode(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; ssize_t size; @@ -294,11 +318,13 @@ void _stlink_usb_enter_swd_mode(stlink_t * sl) { size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } -void _stlink_usb_exit_dfu_mode(stlink_t* sl) { +int _stlink_usb_exit_dfu_mode(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; ssize_t size; @@ -310,15 +336,17 @@ void _stlink_usb_exit_dfu_mode(stlink_t* sl) { size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } /** * TODO - not convinced this does anything... * @param sl */ -void _stlink_usb_reset(stlink_t * sl) { +int _stlink_usb_reset(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -332,12 +360,14 @@ void _stlink_usb_reset(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } -void _stlink_usb_jtag_reset(stlink_t * sl, int value) { +int _stlink_usb_jtag_reset(stlink_t * sl, int value) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -352,12 +382,14 @@ void _stlink_usb_jtag_reset(stlink_t * sl, int value) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } -void _stlink_usb_step(stlink_t* sl) { +int _stlink_usb_step(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -371,15 +403,17 @@ void _stlink_usb_step(stlink_t* sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } /** * This seems to do a good job of restarting things from the beginning? * @param sl */ -void _stlink_usb_run(stlink_t* sl) { +int _stlink_usb_run(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -393,11 +427,13 @@ void _stlink_usb_run(stlink_t* sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } -void _stlink_usb_exit_debug_mode(stlink_t *sl) { +int _stlink_usb_exit_debug_mode(stlink_t *sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; ssize_t size; @@ -409,11 +445,13 @@ void _stlink_usb_exit_debug_mode(stlink_t *sl) { size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { printf("[!] send_only\n"); - return; + return size; } + + return 0; } -void _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -428,15 +466,16 @@ void _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } sl->q_len = (size_t) size; stlink_print_data(sl); + return 0; } -void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { +int _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; unsigned char* const data = sl->q_buf; @@ -449,7 +488,7 @@ void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } sl->q_len = (size_t) size; stlink_print_data(sl); @@ -461,16 +500,18 @@ void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { regp->rw = read_uint32(sl->q_buf, 76); regp->rw2 = read_uint32(sl->q_buf, 80); if (sl->verbose < 2) - return; + return 0; DLOG("xpsr = 0x%08x\n", read_uint32(sl->q_buf, 64)); DLOG("main_sp = 0x%08x\n", read_uint32(sl->q_buf, 68)); DLOG("process_sp = 0x%08x\n", read_uint32(sl->q_buf, 72)); DLOG("rw = 0x%08x\n", read_uint32(sl->q_buf, 76)); DLOG("rw2 = 0x%08x\n", read_uint32(sl->q_buf, 80)); + + return 0; } -void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { +int _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -485,7 +526,7 @@ void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } sl->q_len = (size_t) size; stlink_print_data(sl); @@ -511,19 +552,27 @@ void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { default: regp->r[r_idx] = r; } + + return 0; } /* See section C1.6 of the ARMv7-M Architecture Reference Manual */ -void _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { +int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { uint32_t r; + int ret; sl->q_buf[0] = (unsigned char) r_idx; for (int i = 1; i < 4; i++) { sl->q_buf[i] = 0; } - _stlink_usb_write_mem32(sl, DCRSR, 4); + ret = _stlink_usb_write_mem32(sl, DCRSR, 4); + if (ret == -1) + return ret; + _stlink_usb_read_mem32(sl, DCRDR, 4); + if (ret == -1) + return ret; r = read_uint32(sl->q_buf, 0); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); @@ -542,22 +591,39 @@ void _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { regp->s[r_idx - 0x40] = r; break; } + + return 0; } -void _stlink_usb_read_all_unsupported_regs(stlink_t *sl, reg *regp) { - _stlink_usb_read_unsupported_reg(sl, 0x14, regp); - _stlink_usb_read_unsupported_reg(sl, 0x21, regp); +int _stlink_usb_read_all_unsupported_regs(stlink_t *sl, reg *regp) { + int ret; + + ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); + if (ret == -1) + return ret; + + ret = _stlink_usb_read_unsupported_reg(sl, 0x21, regp); + if (ret == -1) + return ret; for (int i = 0; i < 32; i++) { - _stlink_usb_read_unsupported_reg(sl, 0x40+i, regp); + ret = _stlink_usb_read_unsupported_reg(sl, 0x40+i, regp); + if (ret == -1) + return ret; } + + return 0; } /* See section C1.6 of the ARMv7-M Architecture Reference Manual */ -void _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg *regp) { +int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg *regp) { + int ret; + if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ /* These are held in the same register */ - _stlink_usb_read_unsupported_reg(sl, 0x14, regp); + ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); + if (ret == -1) + return ret; val = (uint8_t) (val>>24); @@ -581,17 +647,19 @@ void _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, re write_uint32(sl->q_buf, val); - _stlink_usb_write_mem32(sl, DCRDR, 4); + ret = _stlink_usb_write_mem32(sl, DCRDR, 4); + if (ret == -1) + return ret; sl->q_buf[0] = (unsigned char) r_idx; sl->q_buf[1] = 0; sl->q_buf[2] = 0x01; sl->q_buf[3] = 0; - _stlink_usb_write_mem32(sl, DCRSR, 4); + return _stlink_usb_write_mem32(sl, DCRSR, 4); } -void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { +int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -606,10 +674,12 @@ void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } sl->q_len = (size_t) size; stlink_print_data(sl); + + return 0; } stlink_backend_t _stlink_usb_backend = { From 93e958f1371b4b0d5fb7171ea0f850902754ce7c Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Fri, 11 Mar 2016 15:27:56 +0100 Subject: [PATCH 0370/1435] stlink-common: Make stlink API propagate backend errors Signed-off-by: Maxime Coquelin --- src/stlink-common.c | 152 +++++++++++++++++++++++++++----------------- src/stlink-common.h | 50 +++++++-------- 2 files changed, 117 insertions(+), 85 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 204491cf6..fd9baba2d 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -472,43 +472,59 @@ void stlink_close(stlink_t *sl) { free(sl); } -void stlink_exit_debug_mode(stlink_t *sl) { +int stlink_exit_debug_mode(stlink_t *sl) { + int ret; + DLOG("*** stlink_exit_debug_mode ***\n"); - stlink_write_debug32(sl, DHCSR, DBGKEY); - sl->backend->exit_debug_mode(sl); + ret = stlink_write_debug32(sl, DHCSR, DBGKEY); + if (ret == -1) + return ret; + + return sl->backend->exit_debug_mode(sl); } -void stlink_enter_swd_mode(stlink_t *sl) { +int stlink_enter_swd_mode(stlink_t *sl) { DLOG("*** stlink_enter_swd_mode ***\n"); - sl->backend->enter_swd_mode(sl); + return sl->backend->enter_swd_mode(sl); } // Force the core into the debug mode -> halted state. -void stlink_force_debug(stlink_t *sl) { +int stlink_force_debug(stlink_t *sl) { DLOG("*** stlink_force_debug_mode ***\n"); - sl->backend->force_debug(sl); + return sl->backend->force_debug(sl); } -void stlink_exit_dfu_mode(stlink_t *sl) { +int stlink_exit_dfu_mode(stlink_t *sl) { DLOG("*** stlink_exit_dfu_mode ***\n"); - sl->backend->exit_dfu_mode(sl); + return sl->backend->exit_dfu_mode(sl); } -void stlink_core_id(stlink_t *sl) { +int stlink_core_id(stlink_t *sl) { + int ret; + DLOG("*** stlink_core_id ***\n"); - sl->backend->core_id(sl); + ret = sl->backend->core_id(sl); + if (ret == -1) { + ELOG("Failed to read core_id\n"); + return ret; + } if (sl->verbose > 2) stlink_print_data(sl); DLOG("core_id = 0x%08x\n", sl->core_id); - return; + return ret; } -uint32_t stlink_chip_id(stlink_t *sl) { - uint32_t chip_id; - stlink_read_debug32(sl, 0xE0042000, &chip_id); +int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { + int ret; + + ret = stlink_read_debug32(sl, 0xE0042000, chip_id); + if (ret == -1) + return ret; + if (chip_id == 0) - stlink_read_debug32(sl, 0x40015800, &chip_id); //Try Corex M0 DBGMCU_IDCODE register address - return chip_id; + ret = stlink_read_debug32(sl, 0x40015800, chip_id); //Try Corex M0 DBGMCU_IDCODE register address + + return ret; } /** @@ -516,14 +532,17 @@ uint32_t stlink_chip_id(stlink_t *sl) { * @param sl stlink context * @param cpuid pointer to the result object */ -void stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { +int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { uint32_t raw; - stlink_read_debug32(sl, CM3_REG_CPUID, &raw); + + if (stlink_read_debug32(sl, CM3_REG_CPUID, &raw)) + return -1; + cpuid->implementer_id = (raw >> 24) & 0x7f; cpuid->variant = (raw >> 20) & 0xf; cpuid->part = (raw >> 4) & 0xfff; cpuid->revision = raw & 0xf; - return; + return 0; } /** @@ -535,9 +554,10 @@ int stlink_load_device_params(stlink_t *sl) { ILOG("Loading device parameters....\n"); const chip_params_t *params = NULL; stlink_core_id(sl); - uint32_t chip_id = stlink_chip_id(sl); + uint32_t chip_id; uint32_t flash_size; + stlink_chip_id(sl, &chip_id); sl->chip_id = chip_id & 0xfff; /* Fix chip_id for F4 rev A errata , Read CPU ID, as CoreID is the same for F2/F4*/ if (sl->chip_id == 0x411) { @@ -599,25 +619,29 @@ int stlink_load_device_params(stlink_t *sl) { return 0; } -void stlink_reset(stlink_t *sl) { +int stlink_reset(stlink_t *sl) { DLOG("*** stlink_reset ***\n"); - sl->backend->reset(sl); + return sl->backend->reset(sl); } -void stlink_jtag_reset(stlink_t *sl, int value) { +int stlink_jtag_reset(stlink_t *sl, int value) { DLOG("*** stlink_jtag_reset ***\n"); - sl->backend->jtag_reset(sl, value); + return sl->backend->jtag_reset(sl, value); } -void stlink_run(stlink_t *sl) { +int stlink_run(stlink_t *sl) { DLOG("*** stlink_run ***\n"); - sl->backend->run(sl); + return sl->backend->run(sl); } -void stlink_status(stlink_t *sl) { +int stlink_status(stlink_t *sl) { + int ret; + DLOG("*** stlink_status ***\n"); - sl->backend->status(sl); + ret = sl->backend->status(sl); stlink_core_stat(sl); + + return ret; } /** @@ -645,9 +669,11 @@ void _parse_version(stlink_t *sl, stlink_version_t *slv) { return; } -void stlink_version(stlink_t *sl) { +int stlink_version(stlink_t *sl) { DLOG("*** looking up stlink version\n"); - sl->backend->version(sl); + if (sl->backend->version(sl)) + return -1; + _parse_version(sl, &sl->version); DLOG("st vid = 0x%04x (expect 0x%04x)\n", sl->version.st_vid, USB_ST_VID); @@ -661,6 +687,8 @@ void stlink_version(stlink_t *sl) { if (sl->version.swim_v == 0) { DLOG(" notice: the firmware doesn't support a swim interface\n"); } + + return -1; } int stlink_target_voltage(stlink_t *sl) { @@ -679,74 +707,78 @@ int stlink_target_voltage(stlink_t *sl) { return voltage; } -void stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { - sl->backend->read_debug32(sl, addr, data); - DLOG("*** stlink_read_debug32 %x is %#x\n", data, addr); - return; +int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { + int ret; + + ret = sl->backend->read_debug32(sl, addr, data); + if (!ret) + DLOG("*** stlink_read_debug32 %x is %#x\n", data, addr); + + return ret; } -void stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { +int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { DLOG("*** stlink_write_debug32 %x to %#x\n", data, addr); - sl->backend->write_debug32(sl, addr, data); + return sl->backend->write_debug32(sl, addr, data); } -void stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); if (len % 4 != 0) { fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); abort(); } - sl->backend->write_mem32(sl, addr, len); + return sl->backend->write_mem32(sl, addr, len); } -void stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_read_mem32 ***\n"); if (len % 4 != 0) { // !!! never ever: fw gives just wrong values fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); abort(); } - sl->backend->read_mem32(sl, addr, len); + return sl->backend->read_mem32(sl, addr, len); } -void stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { +int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem8 ***\n"); if (len > 0x40 ) { // !!! never ever: Writing more then 0x40 bytes gives unexpected behaviour fprintf(stderr, "Error: Data length > 64: +%d byte.\n", len); abort(); } - sl->backend->write_mem8(sl, addr, len); + return sl->backend->write_mem8(sl, addr, len); } -void stlink_read_all_regs(stlink_t *sl, reg *regp) { +int stlink_read_all_regs(stlink_t *sl, reg *regp) { DLOG("*** stlink_read_all_regs ***\n"); - sl->backend->read_all_regs(sl, regp); + return sl->backend->read_all_regs(sl, regp); } -void stlink_read_all_unsupported_regs(stlink_t *sl, reg *regp) { +int stlink_read_all_unsupported_regs(stlink_t *sl, reg *regp) { DLOG("*** stlink_read_all_unsupported_regs ***\n"); - sl->backend->read_all_unsupported_regs(sl, regp); + return sl->backend->read_all_unsupported_regs(sl, regp); } -void stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) { +int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) { DLOG("*** stlink_write_reg\n"); - sl->backend->write_reg(sl, reg, idx); + return sl->backend->write_reg(sl, reg, idx); } -void stlink_read_reg(stlink_t *sl, int r_idx, reg *regp) { +int stlink_read_reg(stlink_t *sl, int r_idx, reg *regp) { DLOG("*** stlink_read_reg\n"); DLOG(" (%d) ***\n", r_idx); if (r_idx > 20 || r_idx < 0) { fprintf(stderr, "Error: register index must be in [0..20]\n"); - return; + return -1; } - sl->backend->read_reg(sl, r_idx, regp); + return sl->backend->read_reg(sl, r_idx, regp); } -void stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { +int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { int r_convert; DLOG("*** stlink_read_unsupported_reg\n"); @@ -761,13 +793,13 @@ void stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { r_convert = 0x40 + (r_idx - 0x20); } else { fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); - return; + return -1; } - sl->backend->read_unsupported_reg(sl, r_convert, regp); + return sl->backend->read_unsupported_reg(sl, r_convert, regp); } -void stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg *regp) { +int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg *regp) { int r_convert; DLOG("*** stlink_write_unsupported_reg\n"); @@ -782,10 +814,10 @@ void stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg *re r_convert = 0x40 + (r_idx - 0x20); } else { fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); - return; + return -1; } - sl->backend->write_unsupported_reg(sl, val, r_convert, regp); + return sl->backend->write_unsupported_reg(sl, val, r_convert, regp); } unsigned int is_core_halted(stlink_t *sl) { @@ -794,9 +826,9 @@ unsigned int is_core_halted(stlink_t *sl) { return sl->q_buf[0] == STLINK_CORE_HALTED; } -void stlink_step(stlink_t *sl) { +int stlink_step(stlink_t *sl) { DLOG("*** stlink_step ***\n"); - sl->backend->step(sl); + return sl->backend->step(sl); } int stlink_current_mode(stlink_t *sl) { diff --git a/src/stlink-common.h b/src/stlink-common.h index 467b9b90a..e40886481 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -625,31 +625,31 @@ extern "C" { //stlink_t* stlink_quirk_open(const char *dev_name, const int verbose); // delegated functions... - void stlink_enter_swd_mode(stlink_t *sl); - void stlink_enter_jtag_mode(stlink_t *sl); - void stlink_exit_debug_mode(stlink_t *sl); - void stlink_exit_dfu_mode(stlink_t *sl); + int stlink_enter_swd_mode(stlink_t *sl); + int stlink_enter_jtag_mode(stlink_t *sl); + int stlink_exit_debug_mode(stlink_t *sl); + int stlink_exit_dfu_mode(stlink_t *sl); void stlink_close(stlink_t *sl); - void stlink_core_id(stlink_t *sl); - void stlink_reset(stlink_t *sl); - void stlink_jtag_reset(stlink_t *sl, int value); - void stlink_run(stlink_t *sl); - void stlink_status(stlink_t *sl); - void stlink_version(stlink_t *sl); - void stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); - void stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); - void stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); - void stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); - void stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); - void stlink_read_all_regs(stlink_t *sl, reg *regp); - void stlink_read_all_unsupported_regs(stlink_t *sl, reg *regp); - void stlink_read_reg(stlink_t *sl, int r_idx, reg *regp); - void stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp); - void stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, reg *regp); - void stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); - void stlink_step(stlink_t *sl); + int stlink_core_id(stlink_t *sl); + int stlink_reset(stlink_t *sl); + int stlink_jtag_reset(stlink_t *sl, int value); + int stlink_run(stlink_t *sl); + int stlink_status(stlink_t *sl); + int stlink_version(stlink_t *sl); + int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); + int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); + int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); + int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); + int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); + int stlink_read_all_regs(stlink_t *sl, reg *regp); + int stlink_read_all_unsupported_regs(stlink_t *sl, reg *regp); + int stlink_read_reg(stlink_t *sl, int r_idx, reg *regp); + int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp); + int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, reg *regp); + int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); + int stlink_step(stlink_t *sl); int stlink_current_mode(stlink_t *sl); - void stlink_force_debug(stlink_t *sl); + int stlink_force_debug(stlink_t *sl); int stlink_target_voltage(stlink_t *sl); @@ -661,8 +661,8 @@ extern "C" { 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); + int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); + int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); // privates, publics, the rest.... // TODO sort what is private, and what is not From a9f00bc5b7428ff3a2e5ea8744f726eccc2f4586 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Fri, 11 Mar 2016 16:57:34 +0100 Subject: [PATCH 0371/1435] st-flash: Improve error handling Now that libusb errors are propagated up to stlink API, we can handle these errors. Signed-off-by: Maxime Coquelin --- flash/main.c | 64 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/flash/main.c b/flash/main.c index 284068cb5..0ba429c66 100644 --- a/flash/main.c +++ b/flash/main.c @@ -172,36 +172,48 @@ int main(int ac, char** av) { printf("invalid command line\n"); usage(); - goto on_error; + return -1; } if (o.devname != NULL) /* stlinkv1 */ - { sl = stlink_v1_open(o.log_level, 1); - if (sl == NULL) goto on_error; - sl->verbose = o.log_level; - } else /* stlinkv2 */ - { sl = stlink_open_usb(o.log_level, 1, o.serial); - if (sl == NULL) goto on_error; - sl->verbose = o.log_level; - } + + if (sl == NULL) + return -1; + + sl->verbose = o.log_level; connected_stlink = sl; signal(SIGINT, &cleanup); signal(SIGTERM, &cleanup); signal(SIGSEGV, &cleanup); - if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) - stlink_exit_dfu_mode(sl); + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { + if (stlink_exit_dfu_mode(sl)) { + printf("Failed to exit DFU mode\n"); + goto on_error; + } + } - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) - stlink_enter_swd_mode(sl); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { + if (stlink_enter_swd_mode(sl)) { + printf("Failed to enter SWD mode\n"); + goto on_error; + } + } if (o.reset){ - stlink_jtag_reset(sl,2); - stlink_reset(sl); + if (stlink_jtag_reset(sl, 2)) { + printf("Failed to reset JTAG\n"); + goto on_error; + } + + if (stlink_reset(sl)) { + printf("Failed to reset device\n"); + goto on_error; + } } // Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 @@ -217,8 +229,15 @@ int main(int ac, char** av) } // Core must be halted to use RAM based flashloaders - stlink_force_debug(sl); - stlink_status(sl); + if (stlink_force_debug(sl)) { + printf("Failed to halt the core\n"); + goto on_error; + } + + if (stlink_status(sl)) { + printf("Failed to get Core's status\n"); + goto on_error; + } if (o.cmd == DO_WRITE) /* write */ { @@ -236,7 +255,7 @@ int main(int ac, char** av) err = stlink_fwrite_sram(sl, o.filename, o.addr); if (err == -1) { - printf("stlink_sram_flash() == -1\n"); + printf("stlink_fwrite_sram() == -1\n"); goto on_error; } } @@ -245,7 +264,7 @@ int main(int ac, char** av) err = stlink_erase_flash_mass(sl); if (err == -1) { - printf("stlink_fwrite_flash() == -1\n"); + printf("stlink_erase_flash_mass() == -1\n"); goto on_error; } } @@ -274,11 +293,8 @@ int main(int ac, char** av) err = 0; on_error: - if (sl != NULL) - { - stlink_exit_debug_mode(sl); - stlink_close(sl); - } + stlink_exit_debug_mode(sl); + stlink_close(sl); return err; } From abcd47f4216d40d1497eb4e07fc100e5979dd284 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Fri, 11 Mar 2016 18:51:15 +0100 Subject: [PATCH 0372/1435] stlink-common: Introduce type of flash controller enum Having a type of flash information has some advantages: - Make the code easier to read - Make adding family derivatives easier (only add a new entry in header file) - Make the backends error propagation easier to implement (less places to fix) Signed-off-by: Maxime Coquelin --- src/stlink-common.c | 331 ++++++++++++++++++++------------------------ src/stlink-common.h | 42 ++++++ 2 files changed, 190 insertions(+), 183 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index fd9baba2d..f15738e7f 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -183,15 +183,17 @@ static inline uint32_t read_flash_obr(stlink_t *sl) { } static inline uint32_t read_flash_cr(stlink_t *sl) { - uint32_t res; - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||(sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) - stlink_read_debug32(sl, FLASH_F4_CR, &res); - else if (sl->chip_id == STM32_CHIPID_L4) - stlink_read_debug32(sl, STM32L4_FLASH_CR, &res); + uint32_t reg, res; + + if (sl->flash_type == FLASH_TYPE_F4) + reg = FLASH_F4_CR; + else if (sl->flash_type == FLASH_TYPE_L4) + reg = STM32L4_FLASH_CR; else - stlink_read_debug32(sl, FLASH_CR, &res); + reg = FLASH_CR; + + stlink_read_debug32(sl, reg, &res); + #if DEBUG_FLASH fprintf(stdout, "CR:0x%x\n", res); #endif @@ -200,37 +202,34 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ - uint32_t cr = read_flash_cr(sl); + uint32_t cr_lock_shift, cr = read_flash_cr(sl); - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) - return cr & (1 << FLASH_F4_CR_LOCK); - else if (sl->chip_id == STM32_CHIPID_L4) - return cr & (1lu << STM32L4_FLASH_CR_LOCK); + if (sl->flash_type == FLASH_TYPE_F4) + cr_lock_shift = FLASH_F4_CR_LOCK; + else if (sl->flash_type == FLASH_TYPE_L4) + cr_lock_shift = STM32L4_FLASH_CR_LOCK; else - return cr & (1 << FLASH_CR_LOCK); + cr_lock_shift = FLASH_CR_LOCK; + + return cr & (1 << cr_lock_shift); } static void unlock_flash(stlink_t *sl) { + uint32_t key_reg; /* the unlock sequence consists of 2 write cycles where 2 key values are written to the FLASH_KEYR register. an invalid sequence results in a definitive lock of the FPEC block until next reset. */ - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { - stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1); - stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2); - } else if (sl->chip_id == STM32_CHIPID_L4) { - stlink_write_debug32(sl, STM32L4_FLASH_KEYR, FLASH_KEY1); - stlink_write_debug32(sl, STM32L4_FLASH_KEYR, FLASH_KEY2); - } else { - stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY1); - stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY2); - } + if (sl->flash_type == FLASH_TYPE_F4) + key_reg = FLASH_F4_KEYR; + else if (sl->flash_type == FLASH_TYPE_L4) + key_reg = STM32L4_FLASH_KEYR; + else + key_reg = FLASH_KEYR; + stlink_write_debug32(sl, key_reg, FLASH_KEY1); + stlink_write_debug32(sl, key_reg, FLASH_KEY2); } static int unlock_flash_if(stlink_t *sl) { @@ -248,48 +247,56 @@ static int unlock_flash_if(stlink_t *sl) { } static void lock_flash(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { - const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK); - stlink_write_debug32(sl, FLASH_F4_CR, n); - } else if (sl->chip_id == STM32_CHIPID_L4) { - const uint32_t n = read_flash_cr(sl) | (1lu << STM32L4_FLASH_CR_LOCK); - stlink_write_debug32(sl, STM32L4_FLASH_CR, n); + uint32_t cr_lock_shift, cr_reg, n; + + if (sl->flash_type == FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_lock_shift = STM32L4_FLASH_CR_LOCK; + } else if (sl->flash_type == FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_lock_shift = STM32L4_FLASH_CR_LOCK; } else { - /* write to 1 only. reset by hw at unlock sequence */ - const uint32_t n = read_flash_cr(sl) | (1 << FLASH_CR_LOCK); - stlink_write_debug32(sl, FLASH_CR, n); + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; } + + n = read_flash_cr(sl) | (1 << cr_lock_shift); + stlink_write_debug32(sl, cr_reg, n); } static void set_flash_cr_pg(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { - uint32_t x = read_flash_cr(sl); - x |= (1 << FLASH_CR_PG); - stlink_write_debug32(sl, FLASH_F4_CR, x); - } else if (sl->chip_id == STM32_CHIPID_L4) { - uint32_t x = read_flash_cr(sl); - x &=~ STM32L4_FLASH_CR_OPBITS; - x |= (1 << STM32L4_FLASH_CR_PG); - stlink_write_debug32(sl, STM32L4_FLASH_CR, x); + uint32_t cr_reg, x; + + x = read_flash_cr(sl); + + if (sl->flash_type == FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + x |= 1 << FLASH_CR_PG; + } else if (sl->flash_type == FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + x &= ~STM32L4_FLASH_CR_OPBITS; + x |= 1 << STM32L4_FLASH_CR_PG; } else { - const uint32_t n = 1 << FLASH_CR_PG; - stlink_write_debug32(sl, FLASH_CR, n); + cr_reg = FLASH_CR; + x = 1 << FLASH_CR_PG; } + + stlink_write_debug32(sl, cr_reg, x); } static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { - const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) - stlink_write_debug32(sl, FLASH_F4_CR, n); + uint32_t cr_reg, n; + + if (sl->flash_type == FLASH_TYPE_F4) + cr_reg = FLASH_F4_CR; + else if (sl->flash_type == FLASH_TYPE_L4) + cr_reg = STM32L4_FLASH_CR; else - stlink_write_debug32(sl, FLASH_CR, n); + cr_reg = FLASH_CR; + + n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); + stlink_write_debug32(sl, cr_reg, n); } static void set_flash_cr_per(stlink_t *sl) { @@ -303,57 +310,60 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { } static void set_flash_cr_mer(stlink_t *sl) { - uint32_t val; - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { - stlink_read_debug32(sl, FLASH_F4_CR, &val); - val |= 1 << FLASH_CR_MER; - stlink_write_debug32(sl, FLASH_F4_CR, val); - } else if (sl->chip_id == STM32_CHIPID_L4) { - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val &=~ STM32L4_FLASH_CR_OPBITS; - val |= (1lu << STM32L4_FLASH_CR_MER1) | (1lu << STM32L4_FLASH_CR_MER2); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + uint32_t val, cr_reg, cr_mer; + + if (sl->flash_type == FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_mer = 1 << FLASH_CR_MER; + } else if (sl->flash_type == FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); } else { - stlink_read_debug32(sl, FLASH_CR, &val); - val |= 1 << FLASH_CR_MER; - stlink_write_debug32(sl, FLASH_CR, val); + cr_reg = FLASH_CR; + cr_mer = 1 << FLASH_CR_MER; } + + stlink_read_debug32(sl, cr_reg, &val); + val |= cr_mer; + stlink_write_debug32(sl, cr_reg, val); } static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { - uint32_t val; - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { - stlink_read_debug32(sl, FLASH_F4_CR, &val); - val &= ~(1 << FLASH_CR_MER); - stlink_write_debug32(sl, FLASH_F4_CR, val); + uint32_t val, cr_reg, cr_mer; + + if (sl->flash_type == FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_mer = 1 << FLASH_CR_MER; + } else if (sl->flash_type == FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); } else { - stlink_read_debug32(sl, FLASH_CR, &val); - val &= ~(1 << FLASH_CR_MER); - stlink_write_debug32(sl, FLASH_CR, val); + cr_reg = FLASH_CR; + cr_mer = 1 << FLASH_CR_MER; } + + stlink_read_debug32(sl, cr_reg, &val); + val &= ~cr_mer; + stlink_write_debug32(sl, cr_reg, val); } static void set_flash_cr_strt(stlink_t *sl) { - uint32_t val; - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { - val = read_flash_cr(sl); - val |= (1 << FLASH_F4_CR_STRT); - stlink_write_debug32(sl, FLASH_F4_CR, val); - } else if (sl->chip_id == STM32_CHIPID_L4) { - val = read_flash_cr(sl); - val |= (1lu << STM32L4_FLASH_CR_STRT); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + uint32_t val, cr_reg, cr_strt; + + if (sl->flash_type == FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_strt = 1 << FLASH_F4_CR_STRT; + } else if (sl->flash_type == FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_strt = 1 << STM32L4_FLASH_CR_STRT; } else { - stlink_read_debug32(sl, FLASH_CR, &val); - val |= 1 << FLASH_CR_STRT; - stlink_write_debug32(sl, FLASH_CR, val); + cr_reg = FLASH_CR; + cr_strt = 1 << FLASH_CR_STRT; } + + stlink_read_debug32(sl, cr_reg, &val); + val |= cr_strt; + stlink_write_debug32(sl, cr_reg, val); } static inline uint32_t read_flash_acr(stlink_t *sl) { @@ -363,28 +373,31 @@ static inline uint32_t read_flash_acr(stlink_t *sl) { } static inline uint32_t read_flash_sr(stlink_t *sl) { - uint32_t res; - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) - stlink_read_debug32(sl, FLASH_F4_SR, &res); - else if (sl->chip_id == STM32_CHIPID_L4) - stlink_read_debug32(sl, STM32L4_FLASH_SR, &res); + uint32_t res, sr_reg; + + if (sl->flash_type == FLASH_TYPE_F4) + sr_reg = FLASH_F4_SR; + else if (sl->flash_type == FLASH_TYPE_L4) + sr_reg = STM32L4_FLASH_SR; else - stlink_read_debug32(sl, FLASH_SR, &res); - //fprintf(stdout, "SR:0x%x\n", *(uint32_t*) sl->q_buf); + sr_reg = FLASH_SR; + + stlink_read_debug32(sl, sr_reg, &res); + return res; } static inline unsigned int is_flash_busy(stlink_t *sl) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_F4_DSI)) - return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY); - else if (sl->chip_id == STM32_CHIPID_L4) - return read_flash_sr(sl) & (1 << STM32L4_FLASH_SR_BSY); + uint32_t sr_busy_shift; + + if (sl->flash_type == FLASH_TYPE_F4) + sr_busy_shift = FLASH_F4_SR_BSY; + else if (sl->flash_type == FLASH_TYPE_L4) + sr_busy_shift = STM32L4_FLASH_SR_BSY; else - return read_flash_sr(sl) & (1 << FLASH_SR_BSY); + sr_busy_shift = FLASH_SR_BSY; + + return read_flash_sr(sl) & (1 << sr_busy_shift); } static void wait_flash_busy(stlink_t *sl) { @@ -600,6 +613,7 @@ int stlink_load_device_params(stlink_t *sl) { } else { sl->flash_size = flash_size * 1024; } + sl->flash_type = params->flash_type; sl->flash_pgsz = params->flash_pagesize; sl->sram_size = params->sram_size; sl->sys_base = params->bootrom_base; @@ -1216,9 +1230,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_L4)|| (sl->chip_id == STM32_CHIPID_F4_DSI)) { + if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L4) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1262,9 +1274,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) #if DEBUG_FLASH fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); #endif - } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 - || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH - || sl->chip_id == STM32_CHIPID_L152_RE || sl->chip_id == STM32_CHIPID_L0) { + } else if (sl->flash_type == FLASH_TYPE_L0) { uint32_t val; uint32_t flash_regs_base; @@ -1332,13 +1342,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->core_id == STM32VL_CORE_ID - || sl->core_id == STM32F0_CORE_ID - || sl->chip_id == STM32_CHIPID_F3 - || sl->chip_id == STM32_CHIPID_F3_SMALL - || sl->chip_id == STM32_CHIPID_F303_HIGH - || sl->chip_id == STM32_CHIPID_F37x - || sl->chip_id == STM32_CHIPID_F334) { + } else if (sl->flash_type == FLASH_TYPE_F0) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1370,9 +1374,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } int stlink_erase_flash_mass(stlink_t *sl) { - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 - || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH - || sl->chip_id == STM32_CHIPID_L152_RE || sl->chip_id == STM32_CHIPID_L0) { + if (sl->flash_type == FLASH_TYPE_L0) { /* erase each page */ int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -1838,16 +1840,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t if (eraseonly) return 0; - if ((sl->chip_id == STM32_CHIPID_F2) || - (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || - (sl->chip_id == STM32_CHIPID_F4_HD) || - (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || - (sl->chip_id == STM32_CHIPID_F7) || - (sl->chip_id == STM32_CHIPID_L4) || - (sl->chip_id == STM32_CHIPID_F4_DSI)) { + if ((sl->flash_type == FLASH_TYPE_F4) || (sl->flash_type == FLASH_TYPE_L4)) { /* todo: check write operation */ ILOG("Starting Flash write for F2/F4/L4\n"); @@ -1907,9 +1900,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } //STM32F4END - else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 - || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH - || sl->chip_id == STM32_CHIPID_L152_RE || sl->chip_id == STM32_CHIPID_L0) { + else if (sl->flash_type == FLASH_TYPE_L0) { /* use fast word write. todo: half page. */ uint32_t val; uint32_t flash_regs_base; @@ -1984,13 +1975,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->core_id == STM32VL_CORE_ID || - sl->core_id == STM32F0_CORE_ID || - sl->chip_id == STM32_CHIPID_F3 || - sl->chip_id == STM32_CHIPID_F3_SMALL || - sl->chip_id == STM32_CHIPID_F303_HIGH || - sl->chip_id == STM32_CHIPID_F334 || - sl->chip_id == STM32_CHIPID_F37x) { + } else if (sl->flash_type == FLASH_TYPE_F0) { ILOG("Starting Flash write for VL/F0/F3 core id\n"); /* flash loader initialization */ if (init_flash_loader(sl, &fl) == -1) { @@ -2040,14 +2025,19 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { /* write the file in flash at addr */ int err; unsigned int num_empty, index, val; - unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 - || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH - || sl->chip_id == STM32_CHIPID_L152_RE) ? 0:0xff; + unsigned char erased_pattern; mapped_file_t mf = MAPPED_FILE_INITIALIZER; + if (map_file(&mf, path) == -1) { ELOG("map_file() == -1\n"); return -1; } + + if (sl->flash_type == FLASH_TYPE_L0) + erased_pattern = 0x00; + else + erased_pattern = 0xff; + index = mf.len; for(num_empty = 0; num_empty != mf.len; ++num_empty) { if (mf.base[--index] != erased_pattern) { @@ -2083,9 +2073,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 - || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH - || sl->chip_id == STM32_CHIPID_L152_RE || sl->chip_id == STM32_CHIPID_L0) { + if (sl->flash_type == FLASH_TYPE_L0) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -2096,13 +2084,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, count, 2); /* count (32 bits words) */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - } else if (sl->core_id == STM32VL_CORE_ID || - sl->core_id == STM32F0_CORE_ID || - sl->chip_id == STM32_CHIPID_F3 || - sl->chip_id == STM32_CHIPID_F3_SMALL || - sl->chip_id == STM32_CHIPID_F303_HIGH || - sl->chip_id == STM32_CHIPID_F37x || - sl->chip_id == STM32_CHIPID_F334) { + } else if (sl->flash_type == FLASH_TYPE_F0) { size_t count = size / sizeof(uint16_t); if (size % sizeof(uint16_t)) ++count; @@ -2114,10 +2096,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, 0, 3); /* flash bank 0 (input) */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || - sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_L4) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { - + } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L4) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; if (sl->chip_id == STM32_CHIPID_L4) { @@ -2152,10 +2131,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } /* check written byte count */ - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 - || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH - || sl->chip_id == STM32_CHIPID_L152_RE || sl->chip_id == STM32_CHIPID_L0) { - + if (sl->flash_type == FLASH_TYPE_L0) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -2165,25 +2141,14 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - } else if (sl->core_id == STM32VL_CORE_ID || - sl->core_id == STM32F0_CORE_ID || - sl->chip_id == STM32_CHIPID_F3 || - sl->chip_id == STM32_CHIPID_F3_SMALL || - sl->chip_id == STM32_CHIPID_F303_HIGH || - sl->chip_id == STM32_CHIPID_F37x || - sl->chip_id == STM32_CHIPID_F334) { - + } else if (sl->flash_type == FLASH_TYPE_F0) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { fprintf(stderr, "write error, count == %u\n", rr.r[2]); return -1; } - } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || - sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F7) || (sl->chip_id == STM32_CHIPID_L4) || - (sl->chip_id == STM32_CHIPID_F4_DSI)) { - + } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L4) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { fprintf(stderr, "write error, count == %u\n", rr.r[2]); diff --git a/src/stlink-common.h b/src/stlink-common.h index e40886481..e7be10ff0 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -166,9 +166,17 @@ extern "C" { /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ #define C_BUF_LEN 32 + enum flash_type { + FLASH_TYPE_F0, + FLASH_TYPE_L0, + FLASH_TYPE_F4, + FLASH_TYPE_L4, + }; + typedef struct chip_params_ { uint32_t chip_id; char* description; + enum flash_type flash_type; uint32_t flash_size_reg; uint32_t flash_pagesize; uint32_t sram_size; @@ -183,6 +191,7 @@ extern "C" { //RM0385 and DS10916 document was used to find these paramaters .chip_id = STM32_CHIPID_F7, .description = "F7 device", + .flash_type = FLASH_TYPE_F4, .flash_size_reg = 0x1ff0f442, // section 41.2 .flash_pagesize = 0x800, // No flash pages .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 @@ -192,6 +201,7 @@ extern "C" { { // table 2, PM0063 .chip_id = STM32_CHIPID_F1_MEDIUM, .description = "F1 Medium-density device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, .sram_size = 0x5000, @@ -201,6 +211,7 @@ extern "C" { { // table 1, PM0059 .chip_id = STM32_CHIPID_F2, .description = "F2 device", + .flash_type = FLASH_TYPE_F4, .flash_size_reg = 0x1fff7a22, /* As in RM0033 Rev 5*/ .flash_pagesize = 0x20000, .sram_size = 0x20000, @@ -210,6 +221,7 @@ extern "C" { { // PM0063 .chip_id = STM32_CHIPID_F1_LOW, .description = "F1 Low-density device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, .sram_size = 0x2800, @@ -219,6 +231,7 @@ extern "C" { { .chip_id = STM32_CHIPID_F4, .description = "F4 device", + .flash_type = FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ .flash_pagesize = 0x4000, .sram_size = 0x30000, @@ -228,6 +241,7 @@ extern "C" { { .chip_id = STM32_CHIPID_F4_DSI, .description = "F46x and F47x device", + .flash_type = FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ .flash_pagesize = 0x4000, .sram_size = 0x40000, @@ -237,6 +251,7 @@ extern "C" { { .chip_id = STM32_CHIPID_F4_HD, .description = "F42x and F43x device", + .flash_type = FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ .flash_pagesize = 0x4000, .sram_size = 0x40000, @@ -246,6 +261,7 @@ extern "C" { { .chip_id = STM32_CHIPID_F4_LP, .description = "F4 device (low power)", + .flash_type = FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, .sram_size = 0x10000, @@ -255,6 +271,7 @@ extern "C" { { .chip_id = STM32_CHIPID_F411RE, .description = "F4 device (low power) - stm32f411re", + .flash_type = FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, .sram_size = 0x20000, @@ -264,6 +281,7 @@ extern "C" { { .chip_id = STM32_CHIPID_F4_DE, .description = "F4 device (Dynamic Efficency)", + .flash_type = FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, .sram_size = 0x18000, @@ -273,6 +291,7 @@ extern "C" { { .chip_id = STM32_CHIPID_F1_HIGH, .description = "F1 High-density device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, .sram_size = 0x10000, @@ -284,6 +303,7 @@ extern "C" { // not the sector write protection...) .chip_id = STM32_CHIPID_L1_MEDIUM, .description = "L1 Med-density device", + .flash_type = FLASH_TYPE_L0, .flash_size_reg = 0x1ff8004c, .flash_pagesize = 0x100, .sram_size = 0x4000, @@ -293,6 +313,7 @@ extern "C" { { .chip_id = STM32_CHIPID_L1_CAT2, .description = "L1 Cat.2 device", + .flash_type = FLASH_TYPE_L0, .flash_size_reg = 0x1ff8004c, .flash_pagesize = 0x100, .sram_size = 0x8000, @@ -302,6 +323,7 @@ extern "C" { { .chip_id = STM32_CHIPID_L1_MEDIUM_PLUS, .description = "L1 Medium-Plus-density device", + .flash_type = FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, .flash_pagesize = 0x100, .sram_size = 0x8000,/*Not completely clear if there are some with 48K*/ @@ -311,6 +333,7 @@ extern "C" { { .chip_id = STM32_CHIPID_L1_HIGH, .description = "L1 High-density device", + .flash_type = FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, .flash_pagesize = 0x100, .sram_size = 0xC000, /*Not completely clear if there are some with 32K*/ @@ -320,6 +343,7 @@ extern "C" { { .chip_id = STM32_CHIPID_L152_RE, .description = "L152RE", + .flash_type = FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, .flash_pagesize = 0x100, .sram_size = 0x14000, /*Not completely clear if there are some with 32K*/ @@ -329,6 +353,7 @@ extern "C" { { .chip_id = STM32_CHIPID_F1_CONN, .description = "F1 Connectivity line device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, .sram_size = 0x10000, @@ -338,6 +363,7 @@ extern "C" { {//Low and Medium density VL have same chipid. RM0041 25.6.1 .chip_id = STM32_CHIPID_F1_VL_MEDIUM_LOW, .description = "F1 Medium/Low-density Value Line device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, .sram_size = 0x2000,//0x1000 for low density devices @@ -348,6 +374,7 @@ extern "C" { // STM32F446x family. Support based on DM00135183.pdf (RM0390) document. .chip_id = STM32_CHIPID_F446, .description = "F446 device", + .flash_type = FLASH_TYPE_F4, .flash_size_reg = 0x1fff7a22, .flash_pagesize = 0x20000, .sram_size = 0x20000, @@ -359,6 +386,7 @@ extern "C" { // Support based on DM00043574.pdf (RM0316) document. .chip_id = STM32_CHIPID_F3, .description = "F3 device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, .sram_size = 0xa000, @@ -370,6 +398,7 @@ extern "C" { // Support based on 303 above (37x and 30x have same memory map) .chip_id = STM32_CHIPID_F37x, .description = "F3 device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, .sram_size = 0xa000, @@ -379,6 +408,7 @@ extern "C" { { .chip_id = STM32_CHIPID_F1_VL_HIGH, .description = "F1 High-density value line device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, .sram_size = 0x8000, @@ -388,6 +418,7 @@ extern "C" { { .chip_id = STM32_CHIPID_F1_XL, .description = "F1 XL-density device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, .sram_size = 0x18000, @@ -399,6 +430,7 @@ extern "C" { //RM0091 document was used to find these paramaters .chip_id = STM32_CHIPID_F0_CAN, .description = "F07x device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x800, // Page sizes listed in Table 4 .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 @@ -410,6 +442,7 @@ extern "C" { //RM0091 document was used to find these paramaters .chip_id = STM32_CHIPID_F0, .description = "F0 device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 @@ -419,6 +452,7 @@ extern "C" { { .chip_id = STM32_CHIPID_F09X, .description = "F09X device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) @@ -430,6 +464,7 @@ extern "C" { //RM0091 document was used to find these paramaters .chip_id = STM32_CHIPID_F04, .description = "F04x device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 @@ -441,6 +476,7 @@ extern "C" { //RM0091 document was used to find these paramaters .chip_id = STM32_CHIPID_F0_SMALL, .description = "F0 small device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 @@ -451,6 +487,7 @@ extern "C" { // STM32F30x .chip_id = STM32_CHIPID_F3_SMALL, .description = "F3 small device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, .sram_size = 0xa000, @@ -462,6 +499,7 @@ extern "C" { // RM0367,RM0377 documents was used to find these parameters .chip_id = STM32_CHIPID_L0, .description = "L0x3 device", + .flash_type = FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, .sram_size = 0x2000, @@ -473,6 +511,7 @@ extern "C" { // RM0364 document was used to find these parameters .chip_id = STM32_CHIPID_F334, .description = "F334 device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, .sram_size = 0x3000, @@ -484,6 +523,7 @@ extern "C" { // Support based on DM00043574.pdf (RM0316) document rev 5. .chip_id = STM32_CHIPID_F303_HIGH, .description = "F303 high density device", + .flash_type = FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register .flash_pagesize = 0x800, // 4.2.1 Flash memory organization .sram_size = 0x10000, // 3.3 Embedded SRAM @@ -495,6 +535,7 @@ extern "C" { // From RM0351. .chip_id = STM32_CHIPID_L4, .description = "L4 device", + .flash_type = FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1671) .flash_pagesize = 0x800, // 2K (sec 3.2, page 78; also appears in sec 3.3.1 and tables 4-6 on pages 79-81) // SRAM1 is "up to" 96k in the standard Cortex-M memory map; @@ -605,6 +646,7 @@ extern "C" { #define STM32F4_FLASH_PGSZ 16384 #define STM32F4_FLASH_SIZE (128 * 1024 * 8) + enum flash_type flash_type; stm32_addr_t flash_base; size_t flash_size; size_t flash_pgsz; From 5693181e6be20b4a4ebca8d3c21d44cd61e753ca Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Mon, 14 Mar 2016 13:01:23 +0100 Subject: [PATCH 0373/1435] stlink-common: Simplify run_flash_loader() This patch simplifies run_flash_loader() function in preparation for error propagation from backends. Doing this, we have less call sites for stlink API. Signed-off-by: Maxime Coquelin --- src/stlink-common.c | 82 +++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 52 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index f15738e7f..5fbf57542 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -2064,7 +2064,9 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { reg rr; - int i = 0; + int target_reg, source_reg, i = 0; + size_t count; + DLOG("Running flash loader, write address:%#x, size: %zd\n", target, size); // FIXME This can never return -1 if (write_buffer_to_sram(sl, fl, buf, size) == -1) { @@ -2074,46 +2076,39 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } if (sl->flash_type == FLASH_TYPE_L0) { - - size_t count = size / sizeof(uint32_t); - if (size % sizeof(uint32_t)) ++count; - - /* setup core */ - stlink_write_reg(sl, target, 0); /* target */ - stlink_write_reg(sl, fl->buf_addr, 1); /* source */ - stlink_write_reg(sl, count, 2); /* count (32 bits words) */ - stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - + count = size / sizeof(uint32_t); + if (size % sizeof(uint32_t)) + ++count; + target_reg = 0; + source_reg = 1; } else if (sl->flash_type == FLASH_TYPE_F0) { - - size_t count = size / sizeof(uint16_t); - if (size % sizeof(uint16_t)) ++count; - - /* setup core */ - stlink_write_reg(sl, fl->buf_addr, 0); /* source */ - stlink_write_reg(sl, target, 1); /* target */ - stlink_write_reg(sl, count, 2); /* count (16 bits half words) */ - stlink_write_reg(sl, 0, 3); /* flash bank 0 (input) */ - stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - + count = size / sizeof(uint16_t); + if (size % sizeof(uint16_t)) + ++count; + target_reg = 1; + source_reg = 0; } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L4) { - size_t count = size / sizeof(uint32_t); - if (size % sizeof(uint32_t)) ++count; + count = size / sizeof(uint32_t); + if (size % sizeof(uint32_t)) + ++count; if (sl->chip_id == STM32_CHIPID_L4) { - if (count % 2) ++count; + if (count % 2) + ++count; } - - /* setup core */ - stlink_write_reg(sl, fl->buf_addr, 0); /* source */ - stlink_write_reg(sl, target, 1); /* target */ - stlink_write_reg(sl, count, 2); /* count (32 bits words) */ - stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - + target_reg = 1; + source_reg = 0; } else { fprintf(stderr, "unknown coreid 0x%x, don't know what flash loader to use\n", sl->core_id); return -1; } + /* setup core */ + stlink_write_reg(sl, fl->buf_addr, source_reg); /* source */ + stlink_write_reg(sl, target, target_reg); /* target */ + stlink_write_reg(sl, count, 2); /* count */ + stlink_write_reg(sl, 0, 3); /* flash bank 0 (input), only used on F0, but armless fopr others */ + stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ + /* run loader */ stlink_run(sl); @@ -2130,36 +2125,19 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } + stlink_read_all_regs(sl, &rr); + /* check written byte count */ if (sl->flash_type == FLASH_TYPE_L0) { - size_t count = size / sizeof(uint32_t); - if (size % sizeof(uint32_t)) ++count; - - stlink_read_reg(sl, 3, &rr); if (rr.r[3] != count) { fprintf(stderr, "write error, count == %u\n", rr.r[3]); return -1; } - - } else if (sl->flash_type == FLASH_TYPE_F0) { - stlink_read_reg(sl, 2, &rr); - if (rr.r[2] != 0) { - fprintf(stderr, "write error, count == %u\n", rr.r[2]); - return -1; - } - - } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L4) { - stlink_read_reg(sl, 2, &rr); + } else { if (rr.r[2] != 0) { fprintf(stderr, "write error, count == %u\n", rr.r[2]); return -1; } - - } else { - - fprintf(stderr, "unknown coreid 0x%x, can't check written byte count\n", sl->core_id); - return -1; - } return 0; From 907383da8ef95fedc630cdf7cf102d44ae229200 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Mon, 14 Mar 2016 13:32:48 +0100 Subject: [PATCH 0374/1435] stlink-common: Update STM32L0 and STM32L1 loader ABI This patch invert source and destination registers in the stm32l0 and stm32l1 loaders, so that it follows the same ABI as other stm32 loaders. Doing that, the run_flash_loader() function can be simplified a little. Signed-off-by: Maxime Coquelin --- flashloaders/stm32l0x.s | 8 ++++---- flashloaders/stm32lx.s | 8 ++++---- src/stlink-common.c | 38 +++++++++++++++----------------------- 3 files changed, 23 insertions(+), 31 deletions(-) diff --git a/flashloaders/stm32l0x.s b/flashloaders/stm32l0x.s index 9fc44468f..6c863c64a 100644 --- a/flashloaders/stm32l0x.s +++ b/flashloaders/stm32l0x.s @@ -34,8 +34,8 @@ .global write /* - r0 - destination address - r1 - source address + r0 - source address + r1 - destination address r2 - count */ @@ -46,9 +46,9 @@ write_word: // Load one word from address in r0, increment by 4 - ldr r4, [r1] + ldr r4, [r0] // Store the word to address in r1, increment by 4 - str r4, [r0] + str r4, [r1] // Increment r3 adds r3, #1 adds r1, #4 diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index 799d1345c..764594d9c 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -34,8 +34,8 @@ .global write /* - r0 - destination address - r1 - source address + r0 - source address + r1 - destination address r2 - count */ @@ -46,9 +46,9 @@ write_word: // Load one word from address in r0, increment by 4 - ldr.w ip, [r1], #4 + ldr.w ip, [r0], #4 // Store the word to address in r1, increment by 4 - str.w ip, [r0], #4 + str.w ip, [r1], #4 // Increment r3 adds r3, #1 diff --git a/src/stlink-common.c b/src/stlink-common.c index 5fbf57542..01ce06c6f 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1501,8 +1501,8 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { static const uint8_t loader_code_stm32l[] = { /* openocd.git/contrib/loaders/flash/stm32lx.S - r0, input, dest addr - r1, input, source addr + r0, input, source addr + r1, input, dest addr r2, input, word count r3, output, word count */ @@ -1510,8 +1510,8 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0x00, 0x23, 0x04, 0xe0, - 0x51, 0xf8, 0x04, 0xcb, - 0x40, 0xf8, 0x04, 0xcb, + 0x50, 0xf8, 0x04, 0xcb, + 0x41, 0xf8, 0x04, 0xcb, 0x01, 0x33, 0x93, 0x42, @@ -1522,8 +1522,8 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { static const uint8_t loader_code_stm32l0[] = { /* - r0, input, dest addr - r1, input, source addr + r0, input, source addr + r1, input, dest addr r2, input, word count r3, output, word count */ @@ -1531,8 +1531,8 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0x00, 0x23, 0x04, 0xe0, - 0x0c, 0x68, - 0x04, 0x60, + 0x04, 0x68, + 0x0c, 0x60, 0x01, 0x33, 0x04, 0x31, 0x04, 0x30, @@ -2064,7 +2064,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { reg rr; - int target_reg, source_reg, i = 0; + int i = 0; size_t count; DLOG("Running flash loader, write address:%#x, size: %zd\n", target, size); @@ -2075,19 +2075,13 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - if (sl->flash_type == FLASH_TYPE_L0) { - count = size / sizeof(uint32_t); - if (size % sizeof(uint32_t)) - ++count; - target_reg = 0; - source_reg = 1; - } else if (sl->flash_type == FLASH_TYPE_F0) { + if (sl->flash_type == FLASH_TYPE_F0) { count = size / sizeof(uint16_t); if (size % sizeof(uint16_t)) ++count; - target_reg = 1; - source_reg = 0; - } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L4) { + } else if (sl->flash_type == FLASH_TYPE_F4 || + sl->flash_type == FLASH_TYPE_L4 || + sl->flash_type == FLASH_TYPE_L0) { count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -2095,16 +2089,14 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons if (count % 2) ++count; } - target_reg = 1; - source_reg = 0; } else { fprintf(stderr, "unknown coreid 0x%x, don't know what flash loader to use\n", sl->core_id); return -1; } /* setup core */ - stlink_write_reg(sl, fl->buf_addr, source_reg); /* source */ - stlink_write_reg(sl, target, target_reg); /* target */ + stlink_write_reg(sl, fl->buf_addr, 0); /* source */ + stlink_write_reg(sl, target, 1); /* target */ stlink_write_reg(sl, count, 2); /* count */ stlink_write_reg(sl, 0, 3); /* flash bank 0 (input), only used on F0, but armless fopr others */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ From e43a737c3c9ffe56045181b306509c942fd9998a Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Mon, 14 Mar 2016 14:22:54 +0100 Subject: [PATCH 0375/1435] stlink-common: Update STM32L0/1 loaders to return remaining count in r2 All the loaders returns remaining work count in r2, except stm32l0/1. Make these loaders behaving as the others to simplify run_flash_loader() code. Signed-off-by: Maxime Coquelin --- flashloaders/stm32l0x.s | 12 +++++------- flashloaders/stm32lx.s | 12 +++++------- src/stlink-common.c | 30 ++++++++++-------------------- 3 files changed, 20 insertions(+), 34 deletions(-) diff --git a/flashloaders/stm32l0x.s b/flashloaders/stm32l0x.s index 6c863c64a..fcbd06e39 100644 --- a/flashloaders/stm32l0x.s +++ b/flashloaders/stm32l0x.s @@ -39,26 +39,24 @@ r2 - count */ - // Set 0 to r3 - movs r3, #0 // Go to compare - b.n test_done + b test_done write_word: // Load one word from address in r0, increment by 4 ldr r4, [r0] // Store the word to address in r1, increment by 4 str r4, [r1] - // Increment r3 - adds r3, #1 + // Decrement r2 + subs r2, #1 adds r1, #4 // does not matter, only first addr is important // next 15 bytes are in sequnce RM0367 page 66 adds r0, #4 test_done: - // Compare r3 and r2 - cmp r3, r2 + // Test r2 + cmp r2, #0 // Loop if not zero bcc.n write_word diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index 764594d9c..bb8f7c93f 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -39,22 +39,20 @@ r2 - count */ - // Set 0 to r3 - movs r3, #0 // Go to compare - b.n test_done + b test_done write_word: // Load one word from address in r0, increment by 4 ldr.w ip, [r0], #4 // Store the word to address in r1, increment by 4 str.w ip, [r1], #4 - // Increment r3 - adds r3, #1 + // Decrement r2 + subs r2, #1 test_done: - // Compare r3 and r2 - cmp r3, r2 + // Test r2 + cmp r2, #0 // Loop if not zero bcc.n write_word diff --git a/src/stlink-common.c b/src/stlink-common.c index 01ce06c6f..dce100daa 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1504,17 +1504,16 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { r0, input, source addr r1, input, dest addr r2, input, word count - r3, output, word count + r2, output, remaining word count */ - 0x00, 0x23, 0x04, 0xe0, 0x50, 0xf8, 0x04, 0xcb, 0x41, 0xf8, 0x04, 0xcb, - 0x01, 0x33, + 0x01, 0x3a, - 0x93, 0x42, + 0x00, 0x2a, 0xf8, 0xd3, 0x00, 0xbe }; @@ -1525,19 +1524,18 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { r0, input, source addr r1, input, dest addr r2, input, word count - r3, output, word count + r2, output, remaining word count */ - 0x00, 0x23, 0x04, 0xe0, 0x04, 0x68, 0x0c, 0x60, - 0x01, 0x33, + 0x01, 0x3a, 0x04, 0x31, 0x04, 0x30, - 0x93, 0x42, + 0x00, 0x2a, 0xf8, 0xd3, 0x00, 0xbe }; @@ -2117,19 +2115,11 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - stlink_read_all_regs(sl, &rr); - /* check written byte count */ - if (sl->flash_type == FLASH_TYPE_L0) { - if (rr.r[3] != count) { - fprintf(stderr, "write error, count == %u\n", rr.r[3]); - return -1; - } - } else { - if (rr.r[2] != 0) { - fprintf(stderr, "write error, count == %u\n", rr.r[2]); - return -1; - } + stlink_read_all_regs(sl, &rr); + if (rr.r[2] != 0) { + fprintf(stderr, "write error, count == %u\n", rr.r[2]); + return -1; } return 0; From d0458ee7564e99253c8a35d8b1ceba33e23e248f Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Mon, 14 Mar 2016 14:53:32 +0100 Subject: [PATCH 0376/1435] stlink-common: Fix STM32L4 loader write count to reflect 64bits granularity The stm32l4 loader expects a count of 32 bits words while its granularity is really 64 bits. This patch fixes this to simplify count calculation in run_flash_loader(). Signed-off-by: Maxime Coquelin --- flashloaders/stm32l4.s | 2 +- src/stlink-common.c | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/flashloaders/stm32l4.s b/flashloaders/stm32l4.s index 4b908633d..6aa2be050 100644 --- a/flashloaders/stm32l4.s +++ b/flashloaders/stm32l4.s @@ -28,7 +28,7 @@ wait: add r0, #8 add r1, #8 - sub r2, #2 + sub r2, #1 b next done: bkpt diff --git a/src/stlink-common.c b/src/stlink-common.c index dce100daa..76413b4fd 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1598,7 +1598,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0xfb, 0xd1, // bne.n 0x00, 0xf1, 0x08, 0x00, // add.w r0, r0, #8 0x01, 0xf1, 0x08, 0x01, // add.w r1, r1, #8 - 0xa2, 0xf1, 0x02, 0x02, // add.w r2, r2, #2 + 0xa2, 0xf1, 0x01, 0x02, // sub.w r2, r2, #1 0xef, 0xe7, // b.n 0x00, 0xbe, // done: bkpt 0x0000 0x00, 0x20, 0x02, 0x40 // flash_base: .word 0x40022000 @@ -2077,16 +2077,14 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons count = size / sizeof(uint16_t); if (size % sizeof(uint16_t)) ++count; - } else if (sl->flash_type == FLASH_TYPE_F4 || - sl->flash_type == FLASH_TYPE_L4 || - sl->flash_type == FLASH_TYPE_L0) { + } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L0) { count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; - if (sl->chip_id == STM32_CHIPID_L4) { - if (count % 2) - ++count; - } + } else if (sl->flash_type == FLASH_TYPE_L4) { + count = size / sizeof(uint64_t); + if (size % sizeof(uint64_t)) + ++count; } else { fprintf(stderr, "unknown coreid 0x%x, don't know what flash loader to use\n", sl->core_id); return -1; @@ -2116,7 +2114,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } /* check written byte count */ - stlink_read_all_regs(sl, &rr); + stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { fprintf(stderr, "write error, count == %u\n", rr.r[2]); return -1; From faa19b5280ba9f5bd0ffede853a300157a116954 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Mon, 14 Mar 2016 15:09:22 +0100 Subject: [PATCH 0377/1435] stlink-common: Ensure flash type is properly declared in device params Signed-off-by: Maxime Coquelin --- src/stlink-common.c | 11 +++++++---- src/stlink-common.h | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 76413b4fd..a1ccdfdcc 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -591,6 +591,12 @@ int stlink_load_device_params(stlink_t *sl) { return -1; } + if (params->flash_type == FLASH_TYPE_UNKNOWN) { + WLOG("Invalid flash type, please check device declaration\n"); + return -1; + } + + // These are fixed... sl->flash_base = STM32_FLASH_BASE; sl->sram_base = STM32_SRAM_BASE; @@ -2063,7 +2069,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons reg rr; int i = 0; - size_t count; + size_t count = 0; DLOG("Running flash loader, write address:%#x, size: %zd\n", target, size); // FIXME This can never return -1 @@ -2085,9 +2091,6 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons count = size / sizeof(uint64_t); if (size % sizeof(uint64_t)) ++count; - } else { - fprintf(stderr, "unknown coreid 0x%x, don't know what flash loader to use\n", sl->core_id); - return -1; } /* setup core */ diff --git a/src/stlink-common.h b/src/stlink-common.h index e7be10ff0..448d01a56 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -167,6 +167,7 @@ extern "C" { #define C_BUF_LEN 32 enum flash_type { + FLASH_TYPE_UNKNOWN = 0, FLASH_TYPE_F0, FLASH_TYPE_L0, FLASH_TYPE_F4, From 1611f5ea86513c4a866732a36ee9a80850d08f67 Mon Sep 17 00:00:00 2001 From: "fabien.lementec" Date: Wed, 16 Mar 2016 11:33:57 +0100 Subject: [PATCH 0378/1435] fix: stlink_version return code --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index a1ccdfdcc..ecd3eb4ef 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -708,7 +708,7 @@ int stlink_version(stlink_t *sl) { DLOG(" notice: the firmware doesn't support a swim interface\n"); } - return -1; + return 0; } int stlink_target_voltage(stlink_t *sl) { From 03024048eb089f0e909788fd52c1684c956f1938 Mon Sep 17 00:00:00 2001 From: texane Date: Wed, 16 Mar 2016 20:27:37 +0100 Subject: [PATCH 0379/1435] fix: chip_id now a pointer, dereference --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index ecd3eb4ef..47148614b 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -534,7 +534,7 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { if (ret == -1) return ret; - if (chip_id == 0) + if (*chip_id == 0) ret = stlink_read_debug32(sl, 0x40015800, chip_id); //Try Corex M0 DBGMCU_IDCODE register address return ret; From 8a190733a2fb6e70b7956c64f04ab258967d0798 Mon Sep 17 00:00:00 2001 From: texane Date: Thu, 17 Mar 2016 19:27:14 +0100 Subject: [PATCH 0380/1435] fix: FLASH_F4_CR_LOCK --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 47148614b..4ad86f8ef 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -251,7 +251,7 @@ static void lock_flash(stlink_t *sl) { if (sl->flash_type == FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; - cr_lock_shift = STM32L4_FLASH_CR_LOCK; + cr_lock_shift = FLASH_F4_CR_LOCK; } else if (sl->flash_type == FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; From b05f7008e49fca23765e1b54c2741af15ad65446 Mon Sep 17 00:00:00 2001 From: Sergey Alirzaev Date: Sun, 20 Mar 2016 05:28:07 +0300 Subject: [PATCH 0381/1435] avoid reading from NULL --- src/stlink-usb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 8e52c6801..b0ee00bed 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -720,8 +720,8 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { sl = malloc(sizeof (stlink_t)); slu = malloc(sizeof (struct stlink_libusb)); - if (sl == NULL) goto on_error; - if (slu == NULL) goto on_error; + if (sl == NULL) goto on_malloc_error; + if (slu == NULL) goto on_malloc_error; memset(sl, 0, sizeof (stlink_t)); memset(slu, 0, sizeof (struct stlink_libusb)); @@ -867,6 +867,7 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { on_error: if( slu->libusb_ctx) libusb_exit(slu->libusb_ctx); +on_malloc_error: if (sl != NULL) free(sl); if (slu != NULL) free(slu); return NULL; From 85abb8c056877c773b7d1184ca77c4b40d0393bc Mon Sep 17 00:00:00 2001 From: Tobias Badertscher Date: Sat, 2 Apr 2016 15:19:27 +0200 Subject: [PATCH 0382/1435] Proper writing of page 0 of second bank for stm32l476xe. --- src/stlink-common.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 4ad86f8ef..6d126d320 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -1197,7 +1197,7 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { flashaddr -= STM32_FLASH_BASE; if (flashopt & (1lu << STM32L4_FLASH_OPTR_DUALBANK)) { uint32_t banksize = sl->flash_size / 2; - if (flashaddr > banksize) { + if (flashaddr >= banksize) { flashaddr -= banksize; bker = 0x100; } @@ -1248,19 +1248,21 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) // calculate the actual bank+page from the address uint32_t page = calculate_L4_page(sl, flashaddr); + fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", page, stlink_calculate_pagesize(sl, flashaddr)); + write_flash_cr_bker_pnb(sl, page); } else if (sl->chip_id == STM32_CHIPID_F7) { // calculate the actual page from the address uint32_t sector=calculate_F7_sectornum(flashaddr); - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x\n", sector, stlink_calculate_pagesize(sl, flashaddr)); + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, stlink_calculate_pagesize(sl, flashaddr)); write_flash_cr_snb(sl, sector); } else { // calculate the actual page from the address uint32_t sector=calculate_F4_sectornum(flashaddr); - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x\n", sector, stlink_calculate_pagesize(sl, flashaddr)); + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, stlink_calculate_pagesize(sl, flashaddr)); //the SNB values for flash sectors in the second bank do not directly follow the values for the first bank on 2mb devices... if (sector >= 12) sector += 4; @@ -1390,7 +1392,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { WLOG("Failed to erase_flash_page(%#zx) == -1\n", addr); return -1; } - fprintf(stdout,"\rFlash page at %5d/%5d erased", i, num_pages); + fprintf(stdout,"-> Flash page at %5d/%5d erased\n", i, num_pages); fflush(stdout); } fprintf(stdout, "\n"); From b0251b9956e33059b3677dc48e7c0a5986595be0 Mon Sep 17 00:00:00 2001 From: Tobias Badertscher Date: Sat, 2 Apr 2016 18:18:39 +0200 Subject: [PATCH 0383/1435] Trace the read data in stlink_read_debug32 and not the address of the variable. --- src/stlink-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 6d126d320..3a6e260d1 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -732,7 +732,7 @@ int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { ret = sl->backend->read_debug32(sl, addr, data); if (!ret) - DLOG("*** stlink_read_debug32 %x is %#x\n", data, addr); + DLOG("*** stlink_read_debug32 %x is %#x\n", *data, addr); return ret; } From 89711265a59fce69a236dc4cb2ebc7b6557a08f4 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Wed, 6 Apr 2016 14:35:57 +0200 Subject: [PATCH 0384/1435] st-probe: Initial working stlink_probe_* API and CLI tool --- AUTHORS | 1 + CMakeLists.txt | 5 +- Makefile.am | 8 ++-- src/st-probe.c | 45 +++++++++++++++++ src/stlink-common.h | 2 + src/stlink-usb.c | 114 ++++++++++++++++++++++++++++++++++++++++---- src/stlink-usb.h | 3 +- 7 files changed, 164 insertions(+), 14 deletions(-) create mode 100644 src/st-probe.c diff --git a/AUTHORS b/AUTHORS index 5c52c64f3..aae9e2963 100644 --- a/AUTHORS +++ b/AUTHORS @@ -16,3 +16,4 @@ marpe@mimuw.edu.pl marco.cassinerio@gmail.com jserv@0xlab.org michael@pratt.im +jerry.jacobs@xor-gate.org diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f5be17ff..247e515a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,10 @@ target_link_libraries(st-util stlink) add_executable(st-info src/st-info.c) target_link_libraries(st-info stlink) -install(TARGETS stlink st-flash st-util st-info +add_executable(st-probe src/st-probe.c) +target_link_libraries(st-probe stlink) + +install(TARGETS stlink st-flash st-util st-info st-probe RUNTIME DESTINATION bin ARCHIVE DESTINATION lib) diff --git a/Makefile.am b/Makefile.am index 2ddbf475d..9a0b387e2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,9 +5,9 @@ SUBDIRS = . $(MAYBE_GUI) AUTOMAKE_OPTIONS = subdir-objects if MINGW -bin_PROGRAMS = st-flash st-util st-info +bin_PROGRAMS = st-flash st-util st-info st-probe else -bin_PROGRAMS = st-flash st-util st-term st-info +bin_PROGRAMS = st-flash st-util st-term st-info st-probe endif noinst_LIBRARIES = libstlink.a @@ -15,6 +15,7 @@ noinst_LIBRARIES = libstlink.a st_flash_SOURCES = flash/main.c st_term_SOURCES = src/st-term.c st_info_SOURCES = src/st-info.c +st_probe_SOURCES = src/st-probe.c st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c mingw/mingw.c mingw/mingw.h CFILES = \ @@ -52,6 +53,7 @@ st_term_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(t st_info_LDADD = libstlink.a st_info_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw +st_probe_LDADD = libstlink.a +st_probe_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw EXTRA_DIST = autogen.sh - diff --git a/src/st-probe.c b/src/st-probe.c new file mode 100644 index 000000000..f5cf3d829 --- /dev/null +++ b/src/st-probe.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include "stlink-common.h" + +void stlink_print_info(stlink_t *sl) +{ + const chip_params_t *params = NULL; + + for (size_t n = 0; n < sizeof(sl->serial); n++) + printf("%02x", sl->serial[n]); + printf("\n"); + + printf("\t flash: %zu (pagesize: %zu)\n", sl->flash_size, sl->flash_pgsz); + printf("\t sram: %zu\n", sl->sram_size); + printf("\tchipid: 0x%.4x\n", sl->chip_id); + + for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { + if(devices[i].chip_id == sl->chip_id) { + params = &devices[i]; + break; + } + } + + if (params) + printf("\t descr: %s\n", params->description); +} + +int main(void) +{ + stlink_t **stdevs; + size_t size; + + size = stlink_probe_usb(&stdevs); + + printf("Found %zu stlink programmers\n", size); + + for (size_t n = 0; n < size; n++) + stlink_print_info(stdevs[n]); + + stlink_probe_usb_free(&stdevs, size); + + return EXIT_SUCCESS; +} diff --git a/src/stlink-common.h b/src/stlink-common.h index 448d01a56..2b2d09b1a 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -641,6 +641,8 @@ extern "C" { uint32_t chip_id; int core_stat; + char serial[13]; + #define STM32_FLASH_PGSZ 1024 #define STM32L_FLASH_PGSZ 256 diff --git a/src/stlink-usb.c b/src/stlink-usb.c index b0ee00bed..ab555785c 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -363,7 +363,7 @@ int _stlink_usb_reset(stlink_t * sl) { return size; } - return 0; + return 0; } @@ -718,12 +718,10 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { int error = -1; int config; - sl = malloc(sizeof (stlink_t)); - slu = malloc(sizeof (struct stlink_libusb)); + sl = calloc(1, sizeof (stlink_t)); + slu = calloc(1, sizeof (struct stlink_libusb)); if (sl == NULL) goto on_malloc_error; if (slu == NULL) goto on_malloc_error; - memset(sl, 0, sizeof (stlink_t)); - memset(slu, 0, sizeof (struct stlink_libusb)); ugly_init(verbose); sl->backend = &_stlink_usb_backend; @@ -760,12 +758,11 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { if ((libusb_get_bus_number(list[cnt])!=devBus) || (libusb_get_device_address(list[cnt])!=devAddr)) continue; if ( (desc.idProduct == USB_STLINK_32L_PID) || (desc.idProduct == USB_STLINK_NUCLEO_PID) ){ if ((p_usb_iserial != NULL)){ - unsigned char buffer[13]; struct libusb_device_handle* handle; libusb_open(list[cnt], &handle); - libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, buffer, 13); + libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial)); libusb_close(handle); - if (memcmp(p_usb_iserial,&buffer,12) == 0){ + if (memcmp(p_usb_iserial,&sl->serial, sizeof(sl->serial) - 1) == 0){ break; }else{ continue; @@ -787,7 +784,7 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { int error = libusb_open(list[cnt], &slu->usb_handle); if( error !=0 ) { WLOG("Error %d (%s) opening ST-Link/V2 device %03d:%03d\n", - error, strerror (errno), libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); + error, strerror (errno), libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); goto on_error; } } @@ -873,3 +870,102 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { return NULL; } +static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { + stlink_t **_sldevs; + libusb_device *dev; + int i = 0; + size_t slcnt = 0; + size_t slcur = 0; + + /* Count stlink */ + while ((dev = devs[i++]) != NULL) { + struct libusb_device_descriptor desc; + int r = libusb_get_device_descriptor(dev, &desc); + if (r < 0) { + fprintf(stderr, "failed to get device descriptor"); + break; + } + + if (desc.idProduct != USB_STLINK_32L_PID && + desc.idProduct != USB_STLINK_NUCLEO_PID) + continue; + + slcnt++; + } + + /* Allocate list of pointers */ + _sldevs = calloc(slcnt, sizeof(stlink_t *)); + if (!_sldevs) { + *sldevs = NULL; + return 0; + } + + /* Open stlinks and attach to list */ + i = 0; + while ((dev = devs[i++]) != NULL) { + struct libusb_device_descriptor desc; + int r = libusb_get_device_descriptor(dev, &desc); + if (r < 0) { + fprintf(stderr, "failed to get device descriptor"); + break; + } + + if (desc.idProduct != USB_STLINK_32L_PID && + desc.idProduct != USB_STLINK_NUCLEO_PID) + continue; + + struct libusb_device_handle* handle; + char serial[13]; + memset(serial, 0, sizeof(serial)); + + libusb_open(dev, &handle); + libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial)); + libusb_close(handle); + + stlink_t *sl = NULL; + sl = stlink_open_usb(0, 1, serial); + if (!sl) + continue; + + _sldevs[slcur] = sl; + slcur++; + } + + *sldevs = _sldevs; + return slcnt; +} + +size_t stlink_probe_usb(stlink_t **stdevs[]) { + libusb_device **devs; + stlink_t **sldevs; + + size_t slcnt = 0; + int r; + ssize_t cnt; + + r = libusb_init(NULL); + if (r < 0) + return 0; + + cnt = libusb_get_device_list(NULL, &devs); + if (cnt < 0) + return 0; + + slcnt = stlink_probe_usb_devs(devs, &sldevs); + libusb_free_device_list(devs, 1); + + libusb_exit(NULL); + + *stdevs = sldevs; + return slcnt; +} + +void stlink_probe_usb_free(stlink_t ***stdevs, size_t size) { + if (stdevs == NULL || *stdevs == NULL || size == 0) + return; + + for (size_t n = 0; n < size; n++) + stlink_close((*stdevs)[n]); + free(*stdevs); + *stdevs = NULL; +} diff --git a/src/stlink-usb.h b/src/stlink-usb.h index 938c07bcb..801cafad3 100644 --- a/src/stlink-usb.h +++ b/src/stlink-usb.h @@ -29,7 +29,8 @@ extern "C" { }; stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial); - + size_t stlink_probe_usb(stlink_t **stdevs[]); + void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); #ifdef __cplusplus } From ca08bed617efc86a7765554c14a448b731f97eb3 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 7 Apr 2016 10:01:20 +0200 Subject: [PATCH 0385/1435] travis: Initial continues integration build on linux and osx * Fixup README to render HTML from Markdown * Fixup CMakeLists.txt to have a lower working minimum version * Add .travis.yml and .travis.sh for autobuild --- .travis.sh | 12 ++++++ .travis.yml | 12 ++++++ CMakeLists.txt | 2 +- README | 108 ++++++++++++++++++++++++++++++------------------- README.md | 1 + 5 files changed, 93 insertions(+), 42 deletions(-) create mode 100755 .travis.sh create mode 100644 .travis.yml create mode 120000 README.md diff --git a/.travis.sh b/.travis.sh new file mode 100755 index 000000000..cefeed142 --- /dev/null +++ b/.travis.sh @@ -0,0 +1,12 @@ +#!/bin/bash +if [ "$TRAVIS_OS_NAME" != "osx" ]; then + sudo apt-get update -qq || true + sudo apt-get install -qq -y --no-install-recommends libusb-1.0.0-dev +else + brew install libusb +fi + +mkdir build +cd build +cmake .. +make diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..b175bb670 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +sudo: true +language: c +script: + - ./.travis.sh +matrix: + include: + - os: osx + compiler: clang + - os: linux + compiler: gcc + - os: linux + compiler: clang diff --git a/CMakeLists.txt b/CMakeLists.txt index 247e515a9..e00d1ed28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.11) +cmake_minimum_required(VERSION 2.8.7) project(stlink) find_package(PkgConfig) diff --git a/README b/README index 1f9d33cdd..986de7002 100644 --- a/README +++ b/README @@ -1,54 +1,72 @@ -HOWTO -===== +STMicroelectronics Stlink Tools +=============================== + +[![Build Status](https://travis-ci.org/xor-gate/stlink.svg?branch=travis)](https://travis-ci.org/xor-gate/stlink) + +## HOWTO First, you have to know there are several boards supported by the software. Those boards use a chip to translate from USB to JTAG commands. The chip is called stlink and there are 2 versions: -. STLINKv1, present on STM32VL discovery kits, -. STLINKv2, present on STM32L discovery and later kits. -2 different transport layers are used: -. STLINKv1 uses SCSI passthru commands over USB, -. STLINKv2 uses raw USB commands. +* STLINKv1, present on STM32VL discovery kits, +* STLINKv2, present on STM32L discovery and later kits. + +Two different transport layers are used: -Common requirements -~~~~~~~~~~~~~~~~~~~ +* STLINKv1 uses SCSI passthru commands over USB +* STLINKv2 uses raw USB commands. + +## Common requirements . libusb-1.0 (You probably already have this, but you'll need the development version to compile) . pkg-config -IF YOU HAVE AN STLINKv1 -~~~~~~~~~~~~~~~~~~~~~~~ +## For STLINKv1 + The STLINKv1's SCSI emulation is very broken, so the best thing to do is tell your operating system to completely ignore it. Options (do one of these before you plug it in) - *) modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i -or *)1. add "options usb-storage quirks=483:3744:i" to /etc/modprobe.conf - *)2. modprobe -r usb-storage && modprobe usb-storage -or *)1. cp stlink_v1.modprobe.conf /etc/modprobe.d - *)2. modprobe -r usb-storage && modprobe usb-storage -IF YOU HAVE AN STLINKv2 -~~~~~~~~~~~~~~~~~~~~~~~ +* `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` +* or *)1. add "options usb-storage quirks=483:3744:i" to /etc/modprobe.conf +* *)2. modprobe -r usb-storage && modprobe usb-storage +* or *)1. cp stlink_v1.modprobe.conf /etc/modprobe.d +* *)2. modprobe -r usb-storage && modprobe usb-storage + +## For STLINKv2 You're ready to go :) -COMPILING -~~~~~~~~~ +## Build from sources + +### Autotools + This project was converted to Autotools by a well meaning individual. The following steps will build the project for you. +``` $ ./autogen.sh $ ./configure $ make +``` + +### CMake + +``` +$ mkdir build && cd build +$ cmake .. +$ make +``` + +## Using the gdb server -USING THE GDBSERVER -~~~~~~~~~~~~~~~~~~~ To run the gdb server: (you do not need sudo if you have set up permissions correctly) +``` $ make && [sudo] ./st-util There are a few options: @@ -68,13 +86,15 @@ There are a few options: st-util will continue listening for connections after disconnect. -n, --no-reset Do not reset board on connection. +``` The STLINKv2 device to use can be specified in the environment -variable STLINK_DEVICE on the format :. +variable STLINK_DEVICE on the format `:`. Then, in your project directory, someting like this... (remember, you need to run an _ARM_ gdb, not an x86 gdb) +``` $ arm-none-eabi-gdb fancyblink.elf ... (gdb) tar extended-remote :4242 @@ -87,50 +107,56 @@ Transfer rate: 1 KB/sec, 560 bytes/write. (gdb) ... (gdb) continue +``` Have fun! -Resetting the chip from GDB -=========================== +## Resetting the chip from GDB You may reset the chip using GDB if you want. You'll need to use `target extended-remote' command like in this session: + +``` (gdb) target extended-remote localhost:4242 Remote debugging using localhost:4242 0x080007a8 in _startup () (gdb) kill Kill the program being debugged? (y or n) y (gdb) run -Starting program: /home/whitequark/ST/apps/bally/firmware.elf +Starting program: /home/whitequark/ST/apps/bally/firmware.elf +``` Remember that you can shorten the commands. `tar ext :4242' is good enough for GDB. -Setting up udev rules -===================== +## Setting up udev rules For convenience, you may install udev rules file, 49-stlinkv*.rules, located in the root of repository. You will need to copy it to /etc/udev/rules.d, and then either reboot or execute + +``` $ udevadm control --reload-rules $ udevadm trigger +``` Udev will now create a /dev/stlinkv2_XX or /dev/stlinkv1_XX file, with the appropriate permissions. This is currently all the device is for, (only one stlink of each version is supported at any time presently) -Running programs from SRAM -========================== +## Running programs from SRAM You can run your firmware directly from SRAM if you want to. Just link it at 0x20000000 and do + +``` (gdb) load firmware.elf +``` It will be loaded, and pc will be adjusted to point to start of the code, if it is linked correctly (i.e. ELF has correct entry point). -Writing to flash -================ +## Writing to flash The GDB stub ships with a correct memory map, including the flash area. If you would link your executable to 0x08000000 and then do @@ -138,8 +164,7 @@ If you would link your executable to 0x08000000 and then do then it would be written to the memory. -FAQ -=== +## FAQ Q: My breakpoints do not work at all or only work once. @@ -161,20 +186,21 @@ Q: Load command does not work in GDB. A: Some people report XML/EXPAT is not enabled by default when compiling GDB. Memory map parsing thus fail. Use --enable-expat. -Currently known working combinations of programmer and target -============================================================= +## Currently known working combinations of programmer and target STLink v1 (as found on the 32VL Discovery board) -Known Working Targets: +Known working targets: + * STM32F100xx (Medium Density VL) * STM32F103 (according to jpa- on ##stm32) No information: + * everything else! -STLink v2 (as found on the 32L and F4 Discovery boards) -Known Working Targets: +STLink v2 (as found on the 32L and F4 Discovery boards), known working targets: + * STM32F030F4P6 (custom board) * STM32F0Discovery (STM32F0 Discovery board) * STM32F100xx (Medium Density VL, as on the 32VL Discovery board) @@ -192,8 +218,8 @@ Known Working Targets: * STM32L152RB (STM32L-Discovery board, custom board) * STM32F051R8T6 (STM320518-EVAL board) -STLink v2-1 (as found on the Nucleo boards) -Known Working Targets: +STLink v2-1 (as found on the Nucleo boards), known working targets: + * STM32F401xx (STM32 Nucleo-F401RE board) * STM32F030R8T6 (STM32 Nucleo-F030R8 board) * STM32F072RBT6 (STM32 Nucleo-F072RB board) diff --git a/README.md b/README.md new file mode 120000 index 000000000..100b93820 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +README \ No newline at end of file From 32807fb95080f3e500d2dbd64e319cc33577a658 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 7 Apr 2016 11:58:16 +0200 Subject: [PATCH 0386/1435] cmake: Add -ggdb flag when CMAKE_BUILD_TYPE=Debug, add more usefull and stricter compiler flags when supported --- CMakeLists.txt | 68 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 247e515a9..cae6bd139 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,48 @@ cmake_minimum_required(VERSION 2.8.11) -project(stlink) +project(stlink C) +include(CheckCCompilerFlag) find_package(PkgConfig) pkg_check_modules(libusb REQUIRED libusb-1.0) pkg_check_modules(gtk gtk+-3.0) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra") +function(add_cflag_if_supported flag) + string(REPLACE "-" "_" flagclean ${flag}) + string(REPLACE "=" "_" flagclean ${flagclean}) + string(REPLACE "+" "_" flagclean ${flagclean}) + string(REPLACE "," "_" flagclean ${flagclean}) + string(TOUPPER ${flagclean} flagclean) + + check_c_compiler_flag(${flag} C_SUPPORTS${flagclean}) + + if (C_SUPPORTS${flagclean}) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE) + endif() +endfunction() + +add_cflag_if_supported("-std=gnu99") +add_cflag_if_supported("-Wall") +add_cflag_if_supported("-Wextra") +add_cflag_if_supported("-Wshadow") +add_cflag_if_supported("-D_FORTIFY_SOURCE=2") +add_cflag_if_supported("-fstrict-aliasing") +add_cflag_if_supported("-Wformat") +add_cflag_if_supported("-Wformat-security") +add_cflag_if_supported("-Wmaybe-uninitialized") +add_cflag_if_supported("-Wmissing-variable-declarations") +add_cflag_if_supported("-Wshorten-64-to-32") +add_cflag_if_supported("-Wimplicit-function-declaration") +add_cflag_if_supported("-Wredundant-decls") +add_cflag_if_supported("-Wundef") + +if(${CMAKE_BUILD_TYPE} MATCHES "Debug") + include(CTest) + add_cflag_if_supported("-ggdb") + add_cflag_if_supported("-O0") +elseif() + add_cflag_if_supported("-O2") +endif() set(HFILES src/stlink-common.h src/stlink-usb.h @@ -24,34 +60,35 @@ include_directories(${libusb_INCLUDE_DIRS}) include_directories(src) include_directories(mingw) -add_library(stlink STATIC +add_library(${PROJECT_NAME} STATIC ${HFILES} # header files for ide projects generated by cmake ${CFILES}) -target_link_libraries(stlink ${libusb_LDFLAGS}) +target_link_libraries(${PROJECT_NAME} ${libusb_LDFLAGS}) add_executable(st-flash flash/main.c) -target_link_libraries(st-flash stlink) +target_link_libraries(st-flash ${PROJECT_NAME}) + +add_executable(st-info src/st-info.c) +target_link_libraries(st-info ${PROJECT_NAME}) + +add_executable(st-probe src/st-probe.c) +target_link_libraries(st-probe ${PROJECT_NAME}) add_executable(st-util gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c gdbserver/gdb-server.h) -target_link_libraries(st-util stlink) +target_link_libraries(st-util ${PROJECT_NAME}) -add_executable(st-info src/st-info.c) -target_link_libraries(st-info stlink) - -add_executable(st-probe src/st-probe.c) -target_link_libraries(st-probe stlink) - -install(TARGETS stlink st-flash st-util st-info st-probe +install(TARGETS ${PROJECT_NAME} st-flash st-util st-info st-probe RUNTIME DESTINATION bin - ARCHIVE DESTINATION lib) + ARCHIVE DESTINATION lib +) if(NOT MINGW) list(APPEND CFILES src/st-term.c) add_executable(st-term src/st-term.c) - target_link_libraries(st-term stlink) + target_link_libraries(st-term ${PROJECT_NAME}) install(TARGETS st-term RUNTIME DESTINATION bin) @@ -78,4 +115,3 @@ if(gtk_FOUND) install(FILES gui/stlink-gui.ui DESTINATION ${INSTALLED_UI_DIR}) endif() - From 1c32fc05b672d318578efda59371d4a426185c51 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 7 Apr 2016 12:08:05 +0200 Subject: [PATCH 0387/1435] st-probe: Fix segfault when programmer is already busy and null pointers are in the list --- src/st-probe.c | 3 +++ src/stlink-common.c | 2 ++ src/stlink-usb.c | 3 +++ 3 files changed, 8 insertions(+) diff --git a/src/st-probe.c b/src/st-probe.c index f5cf3d829..b58bb7ad6 100644 --- a/src/st-probe.c +++ b/src/st-probe.c @@ -8,6 +8,9 @@ void stlink_print_info(stlink_t *sl) { const chip_params_t *params = NULL; + if (!sl) + return; + for (size_t n = 0; n < sizeof(sl->serial); n++) printf("%02x", sl->serial[n]); printf("\n"); diff --git a/src/stlink-common.c b/src/stlink-common.c index 3a6e260d1..18c76fb86 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -481,6 +481,8 @@ static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { void stlink_close(stlink_t *sl) { DLOG("*** stlink_close ***\n"); + if (!sl) + return; sl->backend->close(sl); free(sl); } diff --git a/src/stlink-usb.c b/src/stlink-usb.c index ab555785c..8fed467ba 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -15,6 +15,9 @@ enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80}; void _stlink_usb_close(stlink_t* sl) { + if (!sl) + return; + struct stlink_libusb * const handle = sl->backend_data; // maybe we couldn't even get the usb device? if (handle != NULL) { From 7db660511e5a0668f244f6a2bffd8a87277bdc12 Mon Sep 17 00:00:00 2001 From: Nikolay Date: Fri, 8 Apr 2016 03:12:48 +0300 Subject: [PATCH 0388/1435] Beautify + El Capitan confirmation --- stlinkv1_macosx_driver/README | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/stlinkv1_macosx_driver/README b/stlinkv1_macosx_driver/README index 0c789489c..b789d243a 100644 --- a/stlinkv1_macosx_driver/README +++ b/stlinkv1_macosx_driver/README @@ -17,21 +17,30 @@ Attached to this mail you'll find the osx folder with the source code of the dri invoke the install.sh. First, unpack the osx.tar.gz contents: +```bash tar xzvf osx.tar.gz +``` Then, install the driver using: +```bash sudo make osx_stlink_shield +``` no reboot required. P.S. If error `OS X version not supported` occurs. For the latest versions of Mac OS X you may need to change the `osx/install.sh` as follows: -``` +```bash < ISOSXLION=$(sw_vers -productVersion) --- > ISOSXLION=$(sw_vers -productVersion | sed -e 's:.[[:digit:]]*$::') ``` + FOR OS X 10.10 Yosemite you must force the system to load unsigned kernelextensions +```bash sudo nvram boot-args="kext-dev-mode=1“ +``` reboot the system! + +(Update from another user) FOR OS X 10.11 El Capitan: the Yosemite kext works for my 10.11.4. From 438eafffd51bc90ec433a95db8edfdd2be137e0d Mon Sep 17 00:00:00 2001 From: Nikolay Date: Fri, 8 Apr 2016 03:16:59 +0300 Subject: [PATCH 0389/1435] renaming the README file to README.md --- stlinkv1_macosx_driver/{README => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename stlinkv1_macosx_driver/{README => README.md} (100%) diff --git a/stlinkv1_macosx_driver/README b/stlinkv1_macosx_driver/README.md similarity index 100% rename from stlinkv1_macosx_driver/README rename to stlinkv1_macosx_driver/README.md From 217e854010fde251321d907c0f4a3d48c1d68f87 Mon Sep 17 00:00:00 2001 From: Nikolay Date: Fri, 8 Apr 2016 03:26:30 +0300 Subject: [PATCH 0390/1435] driver README minor edits --- stlinkv1_macosx_driver/README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/stlinkv1_macosx_driver/README.md b/stlinkv1_macosx_driver/README.md index b789d243a..4e6b8c6a0 100644 --- a/stlinkv1_macosx_driver/README.md +++ b/stlinkv1_macosx_driver/README.md @@ -1,4 +1,5 @@ from: marco.cassinerio@gmail.com + to: texane@gmail.com Hi, @@ -14,9 +15,9 @@ version as well. Attached to this mail you'll find the osx folder with the source code of the driver, both drivers (for 10.6.x and 10.7.x), an install.sh script and the modified Makefile, i only added a line at the end which -invoke the install.sh. +invoke the `install.sh`. -First, unpack the osx.tar.gz contents: +First, unpack the `osx.tar.gz` contents: ```bash tar xzvf osx.tar.gz ``` @@ -35,7 +36,9 @@ P.S. If error `OS X version not supported` occurs. For the latest versions of Ma > ISOSXLION=$(sw_vers -productVersion | sed -e 's:.[[:digit:]]*$::') ``` -FOR OS X 10.10 Yosemite you must force the system to load unsigned kernelextensions +### OS X 10.10 Yosemite + +For OS X 10.10 Yosemite you must force the system to load unsigned kernelextensions ```bash sudo nvram boot-args="kext-dev-mode=1“ @@ -43,4 +46,8 @@ sudo nvram boot-args="kext-dev-mode=1“ reboot the system! -(Update from another user) FOR OS X 10.11 El Capitan: the Yosemite kext works for my 10.11.4. +### OS X 10.11 El Capitan + +(Update from another user) + +For OS X 10.11 El Capitan: the Yosemite kext seems to work (tested on 10.11.04). From 2e1204175e1bbe932ce4d9962d62b8adf18aad42 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 15 Apr 2016 15:53:35 +0200 Subject: [PATCH 0391/1435] Add -fPIC compiler flag, remove st-info from libstlink.a which is already specified by the st-info tool --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c9e75ea7..659218f74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ add_cflag_if_supported("-Wshorten-64-to-32") add_cflag_if_supported("-Wimplicit-function-declaration") add_cflag_if_supported("-Wredundant-decls") add_cflag_if_supported("-Wundef") +add_cflag_if_supported("-fPIC") if(${CMAKE_BUILD_TYPE} MATCHES "Debug") include(CTest) @@ -54,7 +55,7 @@ set(CFILES src/stlink-common.c src/stlink-usb.c src/stlink-sg.c src/uglylogging.c - src/st-info.c) + ) include_directories(${libusb_INCLUDE_DIRS}) include_directories(src) From a86d51b4699a07d4bfb0a2f1678b1f29c59530ec Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 15 Apr 2016 22:20:22 +0200 Subject: [PATCH 0392/1435] Fix hang when user has no libusb access because of plugdev under e.g linux. Add some better sanity checking when using libusb_open and cleanup accordingly. Fixes hang (debian 8, amd64, libusb 1.0.19): libusb: warning [add_to_flying_list] failed to arm first timerfd (errno 9) libusb: warning [libusb_close] internal signalling write failed, closing anyway --- src/stlink-usb.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 8fed467ba..36ac96872 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -877,6 +877,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { stlink_t **_sldevs; libusb_device *dev; int i = 0; + int ret = 0; size_t slcnt = 0; size_t slcur = 0; @@ -885,7 +886,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { struct libusb_device_descriptor desc; int r = libusb_get_device_descriptor(dev, &desc); if (r < 0) { - fprintf(stderr, "failed to get device descriptor"); + WLOG("failed to get libusb device descriptor\n"); break; } @@ -907,9 +908,9 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { i = 0; while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; - int r = libusb_get_device_descriptor(dev, &desc); - if (r < 0) { - fprintf(stderr, "failed to get device descriptor"); + ret = libusb_get_device_descriptor(dev, &desc); + if (ret < 0) { + WLOG("failed to get libusb device descriptor\n"); break; } @@ -921,7 +922,11 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { char serial[13]; memset(serial, 0, sizeof(serial)); - libusb_open(dev, &handle); + ret = libusb_open(dev, &handle); + if (ret < 0) { + WLOG("failed to get libusb device descriptor\n"); + break; + } libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial)); libusb_close(handle); @@ -934,6 +939,13 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { slcur++; } + /* Something went wrong */ + if (ret < 0) { + free(_sldevs); + *sldevs = NULL; + return 0; + } + *sldevs = _sldevs; return slcnt; } From db5f0297bf4840b85d37e3460e705f5344928a98 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 15 Apr 2016 23:09:45 +0200 Subject: [PATCH 0393/1435] * Merge st-probe tool into st-info * Fixup #318 serial print in stlink probe with trailing zeros * Refactor stlink-usb.h with some doxygen-style comments * Refactor some pieces of stlink_open_usb --- .gitignore | 1 + CMakeLists.txt | 5 +-- Makefile.am | 8 ++--- src/st-info.c | 63 +++++++++++++++++++++++++++++++------ src/st-probe.c | 48 ---------------------------- src/stlink-common.h | 3 +- src/stlink-usb.c | 76 ++++++++++++++++++++++++--------------------- src/stlink-usb.h | 27 +++++++++++----- src/uglylogging.h | 18 ++++++----- 9 files changed, 131 insertions(+), 118 deletions(-) delete mode 100644 src/st-probe.c diff --git a/.gitignore b/.gitignore index 090257037..1c8296454 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +build INSTALL Makefile.in aclocal.m4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 659218f74..cd329bb18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,16 +72,13 @@ target_link_libraries(st-flash ${PROJECT_NAME}) add_executable(st-info src/st-info.c) target_link_libraries(st-info ${PROJECT_NAME}) -add_executable(st-probe src/st-probe.c) -target_link_libraries(st-probe ${PROJECT_NAME}) - add_executable(st-util gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c gdbserver/gdb-server.h) target_link_libraries(st-util ${PROJECT_NAME}) -install(TARGETS ${PROJECT_NAME} st-flash st-util st-info st-probe +install(TARGETS ${PROJECT_NAME} st-flash st-util st-info RUNTIME DESTINATION bin ARCHIVE DESTINATION lib ) diff --git a/Makefile.am b/Makefile.am index 9a0b387e2..e8927bd4a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,9 +5,9 @@ SUBDIRS = . $(MAYBE_GUI) AUTOMAKE_OPTIONS = subdir-objects if MINGW -bin_PROGRAMS = st-flash st-util st-info st-probe +bin_PROGRAMS = st-flash st-util st-info else -bin_PROGRAMS = st-flash st-util st-term st-info st-probe +bin_PROGRAMS = st-flash st-util st-term st-info endif noinst_LIBRARIES = libstlink.a @@ -15,15 +15,13 @@ noinst_LIBRARIES = libstlink.a st_flash_SOURCES = flash/main.c st_term_SOURCES = src/st-term.c st_info_SOURCES = src/st-info.c -st_probe_SOURCES = src/st-probe.c st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c mingw/mingw.c mingw/mingw.h CFILES = \ src/stlink-common.c \ src/stlink-usb.c \ src/stlink-sg.c \ - src/uglylogging.c \ - src/st-info.c + src/uglylogging.c if !MINGW CFILES += src/st-term.c diff --git a/src/st-info.c b/src/st-info.c index 66d9fb391..2cea40e5c 100644 --- a/src/st-info.c +++ b/src/st-info.c @@ -1,13 +1,9 @@ -/* simple wrapper around the stlink_flash_write function */ - -// TODO - this should be done as just a simple flag to the st-util command line... - - #include #include #include #include -#include "stlink-common.h" + +#include static void usage(void) { @@ -16,9 +12,52 @@ static void usage(void) puts("st-info --descr"); puts("st-info --pagesize"); puts("st-info --chipid"); + puts("st-info --serial"); + puts("st-info --probe"); +} + +static void stlink_print_info(stlink_t *sl) +{ + const chip_params_t *params = NULL; + + if (!sl) + return; + + for (int n = 0; n < sl->serial_size; n++) + printf("%02x", sl->serial[n]); + printf("\n"); + + printf("\t flash: %zu (pagesize: %zu)\n", sl->flash_size, sl->flash_pgsz); + printf("\t sram: %zu\n", sl->sram_size); + printf("\tchipid: 0x%.4x\n", sl->chip_id); + + for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { + if (devices[i].chip_id == sl->chip_id) { + params = &devices[i]; + break; + } + } + + if (params) + printf("\t descr: %s\n", params->description); +} + +static void stlink_probe(void) +{ + stlink_t **stdevs; + size_t size; + + size = stlink_probe_usb(&stdevs); + + printf("Found %zu stlink programmers\n", size); + + for (size_t n = 0; n < size; n++) + stlink_print_info(stdevs[n]); + + stlink_probe_usb_free(&stdevs, size); } -static int print_data(stlink_t* sl, char** av) +static int print_data(stlink_t *sl, char **av) { int ret = 0; if (strcmp(av[1], "--flash") == 0) @@ -29,7 +68,13 @@ static int print_data(stlink_t* sl, char** av) printf("0x%zx\n", sl->flash_pgsz); else if (strcmp(av[1], "--chipid") == 0) printf("0x%.4x\n", sl->chip_id); - else if (strcmp(av[1], "--descr")==0) { + else if (strcmp(av[1], "--probe") == 0) + stlink_probe(); + else if (strcmp(av[1], "--serial") == 0) { + for (int n = 0; n < sl->serial_size; n++) + printf("%02x", sl->serial[n]); + printf("\n"); + } else if (strcmp(av[1], "--descr") == 0) { const chip_params_t *params = NULL; for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { if(devices[i].chip_id == sl->chip_id) { @@ -51,7 +96,7 @@ stlink_t* open_sl(void) stlink_t* sl; sl = stlink_v1_open(0, 1); if (sl == NULL) - sl = stlink_open_usb(0, 1, NULL); + sl = stlink_open_usb(0, 1, NULL); return sl; } diff --git a/src/st-probe.c b/src/st-probe.c deleted file mode 100644 index b58bb7ad6..000000000 --- a/src/st-probe.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include -#include "stlink-common.h" - -void stlink_print_info(stlink_t *sl) -{ - const chip_params_t *params = NULL; - - if (!sl) - return; - - for (size_t n = 0; n < sizeof(sl->serial); n++) - printf("%02x", sl->serial[n]); - printf("\n"); - - printf("\t flash: %zu (pagesize: %zu)\n", sl->flash_size, sl->flash_pgsz); - printf("\t sram: %zu\n", sl->sram_size); - printf("\tchipid: 0x%.4x\n", sl->chip_id); - - for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { - if(devices[i].chip_id == sl->chip_id) { - params = &devices[i]; - break; - } - } - - if (params) - printf("\t descr: %s\n", params->description); -} - -int main(void) -{ - stlink_t **stdevs; - size_t size; - - size = stlink_probe_usb(&stdevs); - - printf("Found %zu stlink programmers\n", size); - - for (size_t n = 0; n < size; n++) - stlink_print_info(stdevs[n]); - - stlink_probe_usb_free(&stdevs, size); - - return EXIT_SUCCESS; -} diff --git a/src/stlink-common.h b/src/stlink-common.h index 2b2d09b1a..e2f7b75c2 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -641,7 +641,8 @@ extern "C" { uint32_t chip_id; int core_stat; - char serial[13]; + char serial[16]; + int serial_size; #define STM32_FLASH_PGSZ 1024 #define STM32L_FLASH_PGSZ 256 diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 36ac96872..6125ec3fa 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -10,7 +10,6 @@ #include "stlink-common.h" #include "stlink-usb.h" -#include "uglylogging.h" enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80}; @@ -714,17 +713,19 @@ stlink_backend_t _stlink_usb_backend = { _stlink_usb_target_voltage }; - -stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16]) +{ stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; - int error = -1; + int ret = -1; int config; sl = calloc(1, sizeof (stlink_t)); slu = calloc(1, sizeof (struct stlink_libusb)); - if (sl == NULL) goto on_malloc_error; - if (slu == NULL) goto on_malloc_error; + if (sl == NULL) + goto on_malloc_error; + if (slu == NULL) + goto on_malloc_error; ugly_init(verbose); sl->backend = &_stlink_usb_backend; @@ -754,26 +755,32 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { devAddr=atoi(c); ILOG("bus %03d dev %03d\n",devBus, devAddr); } + while (cnt--){ libusb_get_device_descriptor( list[cnt], &desc ); - if (desc.idVendor!=USB_ST_VID) continue; + 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) || (desc.idProduct == USB_STLINK_NUCLEO_PID) ){ - if ((p_usb_iserial != NULL)){ - struct libusb_device_handle* handle; + if ((libusb_get_bus_number(list[cnt])!=devBus) || (libusb_get_device_address(list[cnt])!=devAddr)) + continue; + + if ( (desc.idProduct == USB_STLINK_32L_PID) || (desc.idProduct == USB_STLINK_NUCLEO_PID) ) { + if ((serial != NULL)) { + struct libusb_device_handle *handle; + libusb_open(list[cnt], &handle); - libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial)); + sl->serial_size = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial)); libusb_close(handle); - if (memcmp(p_usb_iserial,&sl->serial, sizeof(sl->serial) - 1) == 0){ - break; - }else{ + if (sl->serial_size < 0) continue; - } - }else{ + else if (memcmp(serial, &sl->serial, sl->serial_size) == 0) + break; + } else { break; } } + if (desc.idProduct == USB_STLINK_PID) { slu->protocoll = 1; break; @@ -784,23 +791,20 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { WLOG ("Couldn't find %s ST-Link/V2 devices\n",(devBus && devAddr)?"matched":"any"); goto on_error; } else { - int error = libusb_open(list[cnt], &slu->usb_handle); - if( error !=0 ) { - WLOG("Error %d (%s) opening ST-Link/V2 device %03d:%03d\n", - error, strerror (errno), libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); + ret = libusb_open(list[cnt], &slu->usb_handle); + if (ret != 0) { + WLOG("Error %d (%s) opening ST-Link/V2 device %03d:%03d\n", + ret, strerror (errno), libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); goto on_error; } } libusb_free_device_list(list, 1); - if (libusb_kernel_driver_active(slu->usb_handle, 0) == 1) { - int r; - - r = libusb_detach_kernel_driver(slu->usb_handle, 0); - if (r<0) { - WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-r)); + ret = libusb_detach_kernel_driver(slu->usb_handle, 0); + if (ret < 0) { + WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-ret)); goto on_libusb_error; } } @@ -837,8 +841,6 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { // TODO - never used at the moment, always CMD_SIZE slu->cmd_len = (slu->protocoll == 1)? STLINK_SG_SIZE: STLINK_CMD_SIZE; - /* success */ - if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { ILOG("-- exit_dfu_mode\n"); stlink_exit_dfu_mode(sl); @@ -852,24 +854,28 @@ stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial) { stlink_reset(sl); usleep(10000); } + stlink_version(sl); - error = stlink_load_device_params(sl); + ret = stlink_load_device_params(sl); on_libusb_error: - if (error == -1) { + if (ret == -1) { stlink_close(sl); return NULL; } - /* success */ return sl; on_error: - if( slu->libusb_ctx) + if (slu->libusb_ctx) libusb_exit(slu->libusb_ctx); + on_malloc_error: - if (sl != NULL) free(sl); - if (slu != NULL) free(slu); + if (sl != NULL) + free(sl); + if (slu != NULL) + free(slu); + return NULL; } diff --git a/src/stlink-usb.h b/src/stlink-usb.h index 801cafad3..747d54c74 100644 --- a/src/stlink-usb.h +++ b/src/stlink-usb.h @@ -6,14 +6,17 @@ */ #ifndef STLINK_USB_H -#define STLINK_USB_H - -#ifdef __cplusplus -extern "C" { -#endif +#define STLINK_USB_H +#include #include + #include "stlink-common.h" +#include "uglylogging.h" + +#ifdef __cplusplus +extern "C" { +#endif #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 @@ -28,13 +31,21 @@ extern "C" { unsigned int cmd_len; }; - stlink_t* stlink_open_usb(const int verbose, int reset, char *p_usb_iserial); + /** + * Open a stlink + * @param verbose Verbosity loglevel + * @param reset Reset stlink programmer + * @param serial Serial number to search for, when NULL the first stlink found is opened (binary format) + * @retval NULL Error while opening the stlink + * @retval !NULL Stlink found and ready to use + */ + stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16]); size_t stlink_probe_usb(stlink_t **stdevs[]); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* STLINK_USB_H */ +#endif /* STLINK_USB_H */ diff --git a/src/uglylogging.h b/src/uglylogging.h index 7099d919c..df816caed 100644 --- a/src/uglylogging.h +++ b/src/uglylogging.h @@ -9,14 +9,16 @@ extern "C" { #endif -#define UDEBUG 90 -#define UINFO 50 -#define UWARN 30 -#define UERROR 20 -#define UFATAL 10 - - int ugly_init(int maximum_threshold); - int ugly_log(int level, const char *tag, const char *format, ...); +enum ugly_loglevel { + UDEBUG = 90, + UINFO = 50, + UWARN = 30, + UERROR = 20, + UFATAL = 10 +}; + +int ugly_init(int maximum_threshold); +int ugly_log(int level, const char *tag, const char *format, ...); #define DLOG(format, args...) ugly_log(UDEBUG, __FILE__, format, ## args) #define ILOG(format, args...) ugly_log(UINFO, __FILE__, format, ## args) From 0e22df918ef58b06beebe9c0f73f38a3852c900b Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 15 Apr 2016 23:35:11 +0200 Subject: [PATCH 0394/1435] stlink_open_usb: Fix issue where serial is not cached when serial is not compared in search --- src/stlink-usb.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 6125ec3fa..f3f41e37a 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -756,31 +756,36 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 ILOG("bus %03d dev %03d\n",devBus, devAddr); } - while (cnt--){ + while (cnt--) { libusb_get_device_descriptor( list[cnt], &desc ); 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)) + 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) || (desc.idProduct == USB_STLINK_NUCLEO_PID) ) { - if ((serial != NULL)) { - struct libusb_device_handle *handle; - - libusb_open(list[cnt], &handle); - sl->serial_size = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial)); - libusb_close(handle); - if (sl->serial_size < 0) - continue; - else if (memcmp(serial, &sl->serial, sl->serial_size) == 0) - break; - } else { - break; } } + if ((desc.idProduct == USB_STLINK_32L_PID) || (desc.idProduct == USB_STLINK_NUCLEO_PID)) { + struct libusb_device_handle *handle; + + libusb_open(list[cnt], &handle); + sl->serial_size = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, + (unsigned char *)sl->serial, sizeof(sl->serial)); + libusb_close(handle); + + if (sl->serial_size < 0) + continue; + if (serial == NULL) + break; + if (memcmp(serial, &sl->serial, sl->serial_size) == 0) + break; + + continue; + } + if (desc.idProduct == USB_STLINK_PID) { slu->protocoll = 1; break; From a6b2f93661822b33de22aa533f09319850e352fe Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 24 Apr 2016 09:25:51 +0200 Subject: [PATCH 0395/1435] Fix issue #399: Some Nucleo devices (L476RG) do not return a valid serial --- src/stlink-usb.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index f3f41e37a..24f976988 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -776,10 +776,12 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 (unsigned char *)sl->serial, sizeof(sl->serial)); libusb_close(handle); - if (sl->serial_size < 0) - continue; - if (serial == NULL) + if ((serial == NULL) || (*serial == 0)) break; + + if (sl->serial_size < 0) + continue; + if (memcmp(serial, &sl->serial, sl->serial_size) == 0) break; @@ -938,7 +940,9 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { WLOG("failed to get libusb device descriptor\n"); break; } - libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial)); + ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial)); + if (ret < 0) *serial = 0; + libusb_close(handle); stlink_t *sl = NULL; From 5d088bde8bae782949b3f35b39592f295f35890f Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 29 Apr 2016 09:44:22 +0200 Subject: [PATCH 0396/1435] st-info: Add support for OpenOCD hla_serial printing --- README | 2 +- src/st-info.c | 54 ++++++++++++++++++++++++++++++++++-------------- src/stlink-usb.c | 4 +++- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/README b/README index d85fda7eb..e5a51cf5e 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ STMicroelectronics Stlink Tools =============================== -[![Build Status](https://travis-ci.org/xor-gate/stlink.svg?branch=travis)](https://travis-ci.org/xor-gate/stlink) +[![Build Status](https://travis-ci.org/texane/stlink.svg?branch=travis)](https://travis-ci.org/texane/stlink) ## HOWTO diff --git a/src/st-info.c b/src/st-info.c index 2cea40e5c..cf61bccbf 100644 --- a/src/st-info.c +++ b/src/st-info.c @@ -13,9 +13,30 @@ static void usage(void) puts("st-info --pagesize"); puts("st-info --chipid"); puts("st-info --serial"); + puts("st-info --hla-serial"); puts("st-info --probe"); } +/* Print normal or OpenOCD hla_serial with newline */ +static void stlink_print_serial(stlink_t *sl, bool openocd) +{ + const char *fmt; + + if (openocd) { + printf("\""); + fmt = "\\x%02x"; + } else { + fmt = "%02x"; + } + + for (int n = 0; n < sl->serial_size; n++) + printf(fmt, sl->serial[n]); + + if (openocd) + printf("\""); + printf("\n"); +} + static void stlink_print_info(stlink_t *sl) { const chip_params_t *params = NULL; @@ -23,13 +44,14 @@ static void stlink_print_info(stlink_t *sl) if (!sl) return; - for (int n = 0; n < sl->serial_size; n++) - printf("%02x", sl->serial[n]); - printf("\n"); + printf(" serial: "); + stlink_print_serial(sl, false); + printf("openocd: "); + stlink_print_serial(sl, true); - printf("\t flash: %zu (pagesize: %zu)\n", sl->flash_size, sl->flash_pgsz); - printf("\t sram: %zu\n", sl->sram_size); - printf("\tchipid: 0x%.4x\n", sl->chip_id); + printf(" flash: %zu (pagesize: %zu)\n", sl->flash_size, sl->flash_pgsz); + printf(" sram: %zu\n", sl->sram_size); + printf(" chipid: 0x%.4x\n", sl->chip_id); for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { if (devices[i].chip_id == sl->chip_id) { @@ -39,7 +61,7 @@ static void stlink_print_info(stlink_t *sl) } if (params) - printf("\t descr: %s\n", params->description); + printf(" descr: %s\n", params->description); } static void stlink_probe(void) @@ -59,7 +81,6 @@ static void stlink_probe(void) static int print_data(stlink_t *sl, char **av) { - int ret = 0; if (strcmp(av[1], "--flash") == 0) printf("0x%zx\n", sl->flash_size); else if (strcmp(av[1], "--sram") == 0) @@ -70,11 +91,11 @@ static int print_data(stlink_t *sl, char **av) printf("0x%.4x\n", sl->chip_id); else if (strcmp(av[1], "--probe") == 0) stlink_probe(); - else if (strcmp(av[1], "--serial") == 0) { - for (int n = 0; n < sl->serial_size; n++) - printf("%02x", sl->serial[n]); - printf("\n"); - } else if (strcmp(av[1], "--descr") == 0) { + else if (strcmp(av[1], "--serial") == 0) + stlink_print_serial(sl, false); + else if (strcmp(av[1], "--hla-serial") == 0) + stlink_print_serial(sl, true); + else if (strcmp(av[1], "--descr") == 0) { const chip_params_t *params = NULL; for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { if(devices[i].chip_id == sl->chip_id) { @@ -87,7 +108,8 @@ static int print_data(stlink_t *sl, char **av) } printf("%s\n", params->description); } - return ret; + + return 0; } @@ -115,7 +137,9 @@ int main(int ac, char** av) if (sl == NULL) { return -1; } - sl->verbose=0; + + sl->verbose = 0; + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) stlink_exit_dfu_mode(sl); diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 24f976988..e7e029880 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -940,8 +940,10 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { WLOG("failed to get libusb device descriptor\n"); break; } + ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial)); - if (ret < 0) *serial = 0; + if (ret < 0) + *serial = NULL; libusb_close(handle); From ea6a858d955f7c1541440dbf1b4cc09aa573f917 Mon Sep 17 00:00:00 2001 From: texane Date: Sat, 30 Apr 2016 08:51:56 +0200 Subject: [PATCH 0397/1435] update README --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index e5a51cf5e..b6a6de1e4 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ -STMicroelectronics Stlink Tools -=============================== +Open source version of the STMicroelectronics Stlink Tools +========================================================== [![Build Status](https://travis-ci.org/texane/stlink.svg?branch=travis)](https://travis-ci.org/texane/stlink) From c9fe1103bd2df3ee6724d4abd5e5647b0e97cf6a Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 1 May 2016 09:03:10 +0200 Subject: [PATCH 0398/1435] fix: remove st_probe variables from automake --- Makefile.am | 3 --- 1 file changed, 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index e8927bd4a..9afbc0f0b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,7 +51,4 @@ st_term_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(t st_info_LDADD = libstlink.a st_info_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw -st_probe_LDADD = libstlink.a -st_probe_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw - EXTRA_DIST = autogen.sh From 25deee1055cdea42a4b28597f36e612bec77a2a1 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Mon, 2 May 2016 16:47:23 +0200 Subject: [PATCH 0399/1435] st-info: --probe: Due to already claimed stlink one of them was zero. Fixes #401. --- src/st-info.c | 78 +++++++++++++++++++++++++----------------------- src/stlink-usb.c | 4 +++ 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/st-info.c b/src/st-info.c index cf61bccbf..1671468f0 100644 --- a/src/st-info.c +++ b/src/st-info.c @@ -61,7 +61,7 @@ static void stlink_print_info(stlink_t *sl) } if (params) - printf(" descr: %s\n", params->description); + printf(" descr: %s\n", params->description); } static void stlink_probe(void) @@ -79,8 +79,40 @@ static void stlink_probe(void) stlink_probe_usb_free(&stdevs, size); } -static int print_data(stlink_t *sl, char **av) +static stlink_t *stlink_open_first(void) { + stlink_t* sl = NULL; + sl = stlink_v1_open(0, 1); + if (sl == NULL) + sl = stlink_open_usb(0, 1, NULL); + + return sl; +} + +static int print_data(char **av) +{ + stlink_t* sl = NULL; + + // Probe needs all devices unclaimed + if (strcmp(av[1], "--probe") == 0) { + stlink_probe(); + return 0; + } + + sl = stlink_open_first(); + + if (sl == NULL) { + return -1; + } + + sl->verbose = 0; + + 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); + if (strcmp(av[1], "--flash") == 0) printf("0x%zx\n", sl->flash_size); else if (strcmp(av[1], "--sram") == 0) @@ -89,8 +121,6 @@ static int print_data(stlink_t *sl, char **av) printf("0x%zx\n", sl->flash_pgsz); else if (strcmp(av[1], "--chipid") == 0) printf("0x%.4x\n", sl->chip_id); - else if (strcmp(av[1], "--probe") == 0) - stlink_probe(); else if (strcmp(av[1], "--serial") == 0) stlink_print_serial(sl, false); else if (strcmp(av[1], "--hla-serial") == 0) @@ -109,50 +139,24 @@ static int print_data(stlink_t *sl, char **av) printf("%s\n", params->description); } - return 0; -} - + if (sl) + { + stlink_exit_debug_mode(sl); + stlink_close(sl); + } -stlink_t* open_sl(void) -{ - stlink_t* sl; - sl = stlink_v1_open(0, 1); - if (sl == NULL) - sl = stlink_open_usb(0, 1, NULL); - return sl; + return 0; } - int main(int ac, char** av) { - stlink_t* sl = NULL; int err = -1; if (ac < 2) { usage(); return -1; } - sl = open_sl(); - - if (sl == NULL) { - return -1; - } - - sl->verbose = 0; - - 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); - - err = print_data(sl, av); - - if (sl != NULL) - { - stlink_exit_debug_mode(sl); - stlink_close(sl); - } + err = print_data(av); return err; } diff --git a/src/stlink-usb.c b/src/stlink-usb.c index e7e029880..4cdefd795 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -743,6 +743,10 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 int devBus =0; int devAddr=0; + /* @TODO: Reading a environment variable in a usb open function is not very nice, this + should be refactored and moved into the CLI tools, and instead of giving USB_BUS:USB_ADDR a real stlink + serial string should be passed to this function. Probably people are using this but this is very odd because + as programmer can change to multiple busses and it is better to detect them based on serial. */ char *device = getenv("STLINK_DEVICE"); if (device) { char *c = strchr(device,':'); From eae5157466e8fd2eb6508c5b5f34aa1d5fe373ea Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Mon, 2 May 2016 17:01:53 +0200 Subject: [PATCH 0400/1435] TravisCI: Add building with autotools, catches bugs early as seen by issue #403 --- .travis.sh | 14 ++++++++++---- .travis.yml | 12 ++++++++++++ README | 15 +++++++-------- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/.travis.sh b/.travis.sh index cefeed142..6b69c638a 100755 --- a/.travis.sh +++ b/.travis.sh @@ -6,7 +6,13 @@ else brew install libusb fi -mkdir build -cd build -cmake .. -make +if [ "$BUILD_SYSTEM" == "cmake" ]; then + mkdir build + cd build + cmake .. + make +else + ./autogen.sh + ./configure + make +fi diff --git a/.travis.yml b/.travis.yml index b175bb670..5164d36c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,19 @@ matrix: include: - os: osx compiler: clang + env: "BUILD_SYSTEM=cmake" + - os: osx + compiler: clang + env: "BUILD_SYSTEM=autotools" + - os: linux + compiler: gcc + env: "BUILD_SYSTEM=cmake" + - os: linux + compiler: clang + env: "BUILD_SYSTEM=cmake" - os: linux compiler: gcc + env: "BUILD_SYSTEM=autotools" - os: linux compiler: clang + env: "BUILD_SYSTEM=autotools" diff --git a/README b/README index b6a6de1e4..da7fafa32 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ Open source version of the STMicroelectronics Stlink Tools ========================================================== -[![Build Status](https://travis-ci.org/texane/stlink.svg?branch=travis)](https://travis-ci.org/texane/stlink) +[![Build Status](https://travis-ci.org/texane/stlink.svg?branch=master)](https://travis-ci.org/texane/stlink) ## HOWTO @@ -19,9 +19,8 @@ Two different transport layers are used: ## Common requirements -. libusb-1.0 (You probably already have this, but you'll need the -development version to compile) -. pkg-config +* `pkg-config` +* `libusb-1.0` (plus development headers for building, on debian based distros `libusb-1.0.0-dev` package) ## For STLINKv1 @@ -31,10 +30,10 @@ is tell your operating system to completely ignore it. Options (do one of these before you plug it in) * `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` -* or *)1. add "options usb-storage quirks=483:3744:i" to /etc/modprobe.conf -* *)2. modprobe -r usb-storage && modprobe usb-storage -* or *)1. cp stlink_v1.modprobe.conf /etc/modprobe.d -* *)2. modprobe -r usb-storage && modprobe usb-storage +* or 1. `echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.conf` +* 2. `modprobe -r usb-storage && modprobe usb-storage` +* or 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` +* 2. `modprobe -r usb-storage && modprobe usb-storage` ## For STLINKv2 From a9cfb5619c1df8d4ef1f54230227578819f82881 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Tue, 3 May 2016 21:08:19 +0200 Subject: [PATCH 0401/1435] Add github ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..d06d402e5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,16 @@ +Thank you for giving feedback to the stlink project. Take some time to fill out + check boxes with a X in the following items so developers and other people can try to + to find out what is going on. And add/remove what is appropiate to your problem. + +When submitting a feature request, try to reuse the list and add/remove what is appropiate. + +- [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard +- [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 +- [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) +- [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 +- [ ] Target chip: e.g STM32F402VG + +A as-detailed description possible of the problem with debug output when available. + +Thanks you, +Stlink project maintainers From e653ca6cdf7f63dd70f748f970c1e0345bc19946 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Tue, 3 May 2016 21:09:21 +0200 Subject: [PATCH 0402/1435] ISSUE_TEMPLATE.md, fix typo --- .github/ISSUE_TEMPLATE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index d06d402e5..861711912 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -12,5 +12,5 @@ When submitting a feature request, try to reuse the list and add/remove what is A as-detailed description possible of the problem with debug output when available. -Thanks you, -Stlink project maintainers +Thank you, +The stlink project maintainers From d15a2535cae3a76608fe9e7b3a7da27f409fa400 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 5 May 2016 12:52:58 +0200 Subject: [PATCH 0403/1435] CMake: Dont use pkg-config to find libusb on Mac OSX, rewrite to CMake find module (tested on homebrew only) --- CMakeLists.txt | 8 +++++--- cmake/modules/FindLibUSB.cmake | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 cmake/modules/FindLibUSB.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index cd329bb18..d26f03c8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,9 @@ cmake_minimum_required(VERSION 2.8.7) include(CheckCCompilerFlag) find_package(PkgConfig) -pkg_check_modules(libusb REQUIRED libusb-1.0) +set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") + +find_package(LibUSB REQUIRED) pkg_check_modules(gtk gtk+-3.0) function(add_cflag_if_supported flag) @@ -57,14 +59,14 @@ set(CFILES src/stlink-common.c src/uglylogging.c ) -include_directories(${libusb_INCLUDE_DIRS}) +include_directories(${LIBUSB_INCLUDE_DIR}) include_directories(src) include_directories(mingw) add_library(${PROJECT_NAME} STATIC ${HFILES} # header files for ide projects generated by cmake ${CFILES}) -target_link_libraries(${PROJECT_NAME} ${libusb_LDFLAGS}) +target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARIES}) add_executable(st-flash flash/main.c) target_link_libraries(st-flash ${PROJECT_NAME}) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake new file mode 100644 index 000000000..2e518a7a6 --- /dev/null +++ b/cmake/modules/FindLibUSB.cmake @@ -0,0 +1,27 @@ +# FindLibUSB.cmake - Try to find the Hiredis library +# Once done this will define +# +# LIBUSB_FOUND - System has libusb +# LIBUSB_INCLUDE_DIR - The libusb include directory +# LIBUSB_LIBRARIES - The libraries needed to use libusb +# LIBUSB_DEFINITIONS - Compiler switches required for using libusb + +FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS + /usr + /usr/local + /opt + PATH_SUFFIXES libusb-1.0 + ) + +FIND_LIBRARY(LIBUSB_LIBRARIES NAMES usb-1.0 + HINTS + /usr + /usr/local + /opt + ) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARIES LIBUSB_INCLUDE_DIR) + +MARK_AS_ADVANCED(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARIES) From d25244304547517f8b67e78a1fb52eaec165b18d Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 5 May 2016 12:55:58 +0200 Subject: [PATCH 0404/1435] stlink-usb: Rewrite warning libusb_claim_interface, to be more human friendly. Fixes as discussed in #303 --- src/stlink-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 4cdefd795..98654129e 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -836,7 +836,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 } if (libusb_claim_interface(slu->usb_handle, 0)) { - WLOG("libusb_claim_interface() failed\n"); + WLOG("Stlink usb device found, but unable to claim (probably already in use?)\n"); goto on_libusb_error; } From 62fa371b421ce929b216a2265931f9c1546d1a69 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 5 May 2016 15:19:22 +0200 Subject: [PATCH 0405/1435] Add ChangeLog.md before bump to v1.2.0 --- ChangeLog | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ChangeLog.md | 1 + 2 files changed, 56 insertions(+) create mode 120000 ChangeLog.md diff --git a/ChangeLog b/ChangeLog index e69de29bb..00d82ee9f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -0,0 +1,55 @@ +Stlink ChangeLog +================ + +v1.2.0 +====== + +Release date: 16 may 2016 + +Features added: + +* Add multiple stlink probing (`st-info --probe`, `st-info --hla-serial`) with printing serial in hex and OpenOCD `hla_serial` format (Jerry Jacobs) +* Add stlink usb probe API functions (Jerry Jacobs) +* Added parameter to specify one stlink v2 of many (Georg von Zengen) + +Changes: + +* Refactoring/fixes of flash loader (Maxime Coquelin) + +Updates and fixes: + +* Synchronize cache for stm32f7 (Tristan Gingold) +* Allow flashing of STM32L4 down to 1.71 V (Greg Meiste) +* Fix on stm32l4 to clear flash mass erase flags on CR (Bruno Dal Bo) +* Proper writing of page 0 of second bank for stm32l476xe (Tobias Badertscher) +* Trace the read data in stlink_read_debug32 and not the address of the variable (Tobias Badertscher) +* Mac OS X El Capitan platform support confirmation (Nikolay) +* Do not send a NUL at end of packets to gdb (Tristan Gingold) +* Correctly compute flash write size for partial pages (Dave Vandervies) +* _stlink_usb_reset use hardreset (mlundinse) +* Make sure MCU is halted before running RAM based flashloaders (mlundinse) +* Could not flash STM32_F3_SMALL (Max Chen) +* STM32F4 8-bit support for 1.8v operation (Andy Isaacson) +* Fix F2 memory map (Nicolas Schodet) +* Memory map for stm32f42xxx and stm32f43xxx devices (Craig Lilley) +* Stm32l0x flash loader (Robin Kreis) + +Chip support added for: + +* STM32L053R8 (Jean-Luc Béchennec) +* STM32F7 Support (mlundinse) +* Add STM32L4 to CHIPID #defines and devices[], flash driver and loaded (Dave Vandervies) +* Basic support for F446 (Pavel Kirienko) +* STM32F303 High Density +* STM32L1xx Cat.2 devices (Nicolas Schodet) + +Board support added for: + +* Nucleo-F303RE (Kyle Manna) +* Nucleo-F411RE (texane) + +Build system: + +* Travis: Initial support for Travis continues integration on Linux & Mac OS X (Jerry Jacobs) +* CMake: Document in README.md and add extra strict compiler flags (Jerry Jacobs) +* CMake: First stab at a cmake build (Josh Bialkowski) diff --git a/ChangeLog.md b/ChangeLog.md new file mode 120000 index 000000000..b0936e8d0 --- /dev/null +++ b/ChangeLog.md @@ -0,0 +1 @@ +ChangeLog \ No newline at end of file From e454fe98191095333258cfcfa813585086f669ed Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 5 May 2016 14:46:42 +0200 Subject: [PATCH 0406/1435] Reorganize files: * Header files moved into include/stlink * doc/tutorial.{pdf/tex} converted to markdown for rendering by github and easy editing * Remove `stlink-` suffix from some C source files and move into `src/tools` --- CMakeLists.txt | 47 ++-- Makefile.am | 38 +-- README.md | 1 - TODO | 11 - TODO.md | 11 + configure.ac | 2 +- doc/tutorial.md | 190 ++++++++++++++ doc/tutorial/tutorial.pdf | Bin 110584 -> 0 bytes doc/tutorial/tutorial.tex | 234 ------------------ .../modprobe.d/stlink_v1.conf | 0 .../udev/rules.d/49-stlinkv1.rules | 0 .../udev/rules.d/49-stlinkv2-1.rules | 0 .../udev/rules.d/49-stlinkv2.rules | 0 flash/Makefile | 30 --- src/stlink-common.h => include/stlink.h | 25 +- src/uglylogging.h => include/stlink/logging.h | 0 {src => include/stlink}/mmap.h | 0 src/stlink-sg.h => include/stlink/sg.h | 8 +- src/stlink-usb.h => include/stlink/usb.h | 6 +- src/{stlink-common.c => common.c} | 6 +- {gdbserver => src/gdbserver}/Makefile | 0 {gdbserver => src/gdbserver}/gdb-remote.c | 0 {gdbserver => src/gdbserver}/gdb-remote.h | 0 {gdbserver => src/gdbserver}/gdb-server.c | 4 +- {gdbserver => src/gdbserver}/gdb-server.h | 0 src/{uglylogging.c => logging.c} | 3 +- {mingw => src/mingw}/mingw.c | 0 {mingw => src/mingw}/mingw.h | 0 src/mmap.c | 2 +- src/{stlink-sg.c => sg.c} | 5 +- flash/main.c => src/tools/flash.c | 3 +- src/{st-info.c => tools/info.c} | 2 +- src/{st-term.c => tools/term.c} | 3 +- src/{stlink-usb.c => usb.c} | 3 +- src/test_sg.c => tests/stlink_sg.c | 0 src/test_usb.c => tests/stlink_usb.c | 0 36 files changed, 276 insertions(+), 358 deletions(-) delete mode 120000 README.md delete mode 100644 TODO create mode 100644 TODO.md create mode 100644 doc/tutorial.md delete mode 100644 doc/tutorial/tutorial.pdf delete mode 100644 doc/tutorial/tutorial.tex rename stlink_v1.modprobe.conf => etc/modprobe.d/stlink_v1.conf (100%) rename 49-stlinkv1.rules => etc/udev/rules.d/49-stlinkv1.rules (100%) rename 49-stlinkv2-1.rules => etc/udev/rules.d/49-stlinkv2-1.rules (100%) rename 49-stlinkv2.rules => etc/udev/rules.d/49-stlinkv2.rules (100%) delete mode 100644 flash/Makefile rename src/stlink-common.h => include/stlink.h (99%) rename src/uglylogging.h => include/stlink/logging.h (100%) rename {src => include/stlink}/mmap.h (100%) rename src/stlink-sg.h => include/stlink/sg.h (96%) rename src/stlink-usb.h => include/stlink/usb.h (93%) rename src/{stlink-common.c => common.c} (99%) rename {gdbserver => src/gdbserver}/Makefile (100%) rename {gdbserver => src/gdbserver}/gdb-remote.c (100%) rename {gdbserver => src/gdbserver}/gdb-remote.h (100%) rename {gdbserver => src/gdbserver}/gdb-server.c (99%) rename {gdbserver => src/gdbserver}/gdb-server.h (100%) rename src/{uglylogging.c => logging.c} (97%) rename {mingw => src/mingw}/mingw.c (100%) rename {mingw => src/mingw}/mingw.h (100%) rename src/{stlink-sg.c => sg.c} (99%) rename flash/main.c => src/tools/flash.c (99%) rename src/{st-info.c => tools/info.c} (99%) rename src/{st-term.c => tools/term.c} (99%) rename src/{stlink-usb.c => usb.c} (99%) rename src/test_sg.c => tests/stlink_sg.c (100%) rename src/test_usb.c => tests/stlink_usb.c (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index d26f03c8f..f75ce611d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,37 +47,38 @@ elseif() add_cflag_if_supported("-O2") endif() -set(HFILES src/stlink-common.h - src/stlink-usb.h - src/stlink-sg.h - src/uglylogging.h - src/mmap.h) - -set(CFILES src/stlink-common.c - src/stlink-usb.c - src/stlink-sg.c - src/uglylogging.c - ) +set(STLINK_HEADERS include/stlink.h + include/stlink/usb.h + include/stlink/sg.h + include/stlink/logging.h + include/stlink/mmap.h +) + +set(STLINK_SOURCE src/common.c + src/usb.c + src/sg.c + src/logging.c +) include_directories(${LIBUSB_INCLUDE_DIR}) -include_directories(src) -include_directories(mingw) +include_directories(include) +include_directories(src/mingw) add_library(${PROJECT_NAME} STATIC - ${HFILES} # header files for ide projects generated by cmake - ${CFILES}) + ${STLINK_HEADERS} # header files for ide projects generated by cmake + ${STLINK_SOURCE}) target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARIES}) -add_executable(st-flash flash/main.c) +add_executable(st-flash src/tools/flash.c) target_link_libraries(st-flash ${PROJECT_NAME}) -add_executable(st-info src/st-info.c) +add_executable(st-info src/tools/info.c) target_link_libraries(st-info ${PROJECT_NAME}) -add_executable(st-util gdbserver/gdb-remote.c - gdbserver/gdb-remote.h - gdbserver/gdb-server.c - gdbserver/gdb-server.h) +add_executable(st-util src/gdbserver/gdb-remote.c + src/gdbserver/gdb-remote.h + src/gdbserver/gdb-server.c + src/gdbserver/gdb-server.h) target_link_libraries(st-util ${PROJECT_NAME}) install(TARGETS ${PROJECT_NAME} st-flash st-util st-info @@ -86,8 +87,8 @@ install(TARGETS ${PROJECT_NAME} st-flash st-util st-info ) if(NOT MINGW) - list(APPEND CFILES src/st-term.c) - add_executable(st-term src/st-term.c) + list(APPEND STLINK_SOURCE src/tools/term.c) + add_executable(st-term src/tools/term.c) target_link_libraries(st-term ${PROJECT_NAME}) install(TARGETS st-term diff --git a/Makefile.am b/Makefile.am index 9afbc0f0b..fc95184bc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,43 +12,43 @@ endif noinst_LIBRARIES = libstlink.a -st_flash_SOURCES = flash/main.c -st_term_SOURCES = src/st-term.c -st_info_SOURCES = src/st-info.c -st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c mingw/mingw.c mingw/mingw.h +st_flash_SOURCES = src/tools/flash.c +st_term_SOURCES = src/tools/term.c +st_info_SOURCES = src/tools/info.c +st_util_SOURCES = src/gdbserver/gdb-remote.c src/gdbserver/gdb-remote.h src/gdbserver/gdb-server.c src/mingw/mingw.c src/mingw/mingw.h CFILES = \ - src/stlink-common.c \ - src/stlink-usb.c \ - src/stlink-sg.c \ - src/uglylogging.c + src/common.c \ + src/usb.c \ + src/sg.c \ + src/logging.c if !MINGW -CFILES += src/st-term.c +CFILES += src/tools/term.c endif HFILES = \ - src/stlink-common.h \ - src/stlink-usb.h \ - src/stlink-sg.h \ - src/uglylogging.h \ - src/mmap.h + include/stlink.h \ + include/stlink/usb.h \ + include/stlink/sg.h \ + include/stlink/logging.h \ + include/stlink/mmap.h libstlink_a_SOURCES = $(CFILES) $(HFILES) -libstlink_a_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 libstlink_a_LIBADD = $(LIBOBJS) +libstlink_a_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/include st_flash_LDADD = libstlink.a -st_flash_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw +st_flash_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/include -I$(top_srcdir)/src/mingw st_util_LDADD = libstlink.a -st_util_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw +st_util_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/include -I$(top_srcdir)/src/mingw st_term_LDADD = libstlink.a -st_term_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw +st_term_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/include -I$(top_srcdir)/src/mingw st_info_LDADD = libstlink.a -st_info_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw +st_info_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/include -I$(top_srcdir)/src/mingw EXTRA_DIST = autogen.sh diff --git a/README.md b/README.md deleted file mode 120000 index 100b93820..000000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -README \ No newline at end of file diff --git a/TODO b/TODO deleted file mode 100644 index 2b0baf62f..000000000 --- a/TODO +++ /dev/null @@ -1,11 +0,0 @@ -. flash tool - . improve flash writing, still use word fast write... too slow - -. documentation - . make README points to doc/tutorial - -. compile and test a realtime kernel, for instance: -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/TODO.md b/TODO.md new file mode 100644 index 000000000..9c5059a49 --- /dev/null +++ b/TODO.md @@ -0,0 +1,11 @@ +# flash tool + +- improve flash writing, still use word fast write... too slow + +# documentation + +- make README points to doc/tutorial + +# testing + +- compile and test a realtime kernel (e.g ChibiOS) diff --git a/configure.ac b/configure.ac index 203cc6bd5..f37471740 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ(2.61) AC_INIT([stlink],[0.5.6],[davem@devkitpro.org]) -AC_CONFIG_SRCDIR([src/stlink-common.c]) +AC_CONFIG_SRCDIR([src/common.c]) AC_CONFIG_LIBOBJ_DIR([src]) AM_INIT_AUTOMAKE([1.10]) diff --git a/doc/tutorial.md b/doc/tutorial.md new file mode 100644 index 000000000..937e2da28 --- /dev/null +++ b/doc/tutorial.md @@ -0,0 +1,190 @@ +Using STM32 discovery kits with open source tools +======== + +This guide details the use of STMicroelectronics STM32 discovery kits in an open source environment. + +Installing a GNU toolchain +========================== + +Any toolchain supporting the cortex m3 should do. You can find the +necessary to install such a toolchain here: + +``` +https://github.com/esden/summon-arm-toolchain +``` + +Details for the installation are provided in the topmost `README` file. +This documentation assumes the toolchains is installed in a +`$TOOLCHAIN_PATH`. + +Installing STLINK +================= + +STLINK is open source software to program and debug ST’s STM32 Discovery +kits. Those kits have an onboard chip that translates USB commands sent +by the host PC into JTAG/SWD commands. This chip is called STLINK, (yes, +isn’t that confusing? suggest a better name!) and comes in 2 versions +(STLINK v1 and v2). From a software point of view, those versions differ +only in the transport layer used to communicate (v1 uses SCSI passthru +commands, while v2 uses raw USB). From a user point of view, they are +identical. + + +Before continuing, the following dependencies must be met: + +- libusb-1.0 +- pkg-config +- autotools + +STLINK should run on any system meeting the above constraints. + +The STLINK software source code is retrieved using: + +``` +$> git clone https://github.com/texane/stlink stlink.git +``` + +Everything can be built from the top directory: + +``` +$> cd stlink.git +$> ./autogen.sh +$> ./configure +$> make +``` + +It includes: + +- a communication library (stlink.git/libstlink.a), +- a GDB server (stlink.git/st-util), +- a flash manipulation tool (stlink.git/st-flash). + +Using the GDB server +==================== + + +This assumes you have got the libopencm3 project downloaded in `ocm3`. +The libopencm3 project has some good, reliable examples for each of the +Discovery boards. + +Even if you don’t plan on using libopencm3, the examples they provide +will help you verify that: + +- Your installed toolchain is capable of compiling for cortex M3/M4 + targets +- stlink is functional +- Your arm-none-eabi-gdb is functional +- Your board is functional + +A GDB server must be started to interact with the STM32. Depending on +the discovery kit you are using, you must run one of the 2 commands: + +``` +# STM32VL discovery kit (onboard ST-link) +$> ./st-util --stlinkv1 + +# STM32L or STM32F4 discovery kit (onboard ST-link/V2) +$> ./st-util + +# Full help for other options (listen port, version) +$> ./st-util --help +``` + +Then, GDB can be used to interact with the kit: + +``` +$> $TOOLCHAIN_PATH/bin/arm-none-eabi-gdb example_file.elf +``` + +From GDB, connect to the server using: + +``` +(gdb) target extended localhost:4242 +``` + +GDB has memory maps for as many chips as it knows about, and will load +your project into either flash or SRAM based on how the project was +linked. Linking projects to boot from SRAM is beyond the scope of this +document. + +Because of these built in memory maps, after specifying the .elf at the +command line, now we can simply “load” the target: + +``` +(gdb) load +``` + +st-util will load all sections into their appropriate addresses, and +“correctly” set the PC register. So, to run your freshly loaded program, +simply “continue” + +``` +(gdb) continue +``` + +Your program should now be running, and, if you used one of the blinking +examples from libopencm3, the LEDs on the board should be blinking for +you. + +Building and flashing a program +=============================== + +If you want to simply flash binary files to arbitrary sections of +memory, or read arbitary addresses of memory out to a binary file, use +the st-flash tool, as shown below: + +``` + +# stlinkv1 command to read 4096 from flash into out.bin +$> ./st-flash read v1 out.bin 0x8000000 4096 + +# stlinkv2 command +$> ./st-flash read out.bin 0x8000000 4096 + +# stlinkv1 command to write the file in.bin into flash +$> ./st-flash write v1 in.bin 0x8000000 + +# stlinkv2 command +$> ./st-flash write in.bin 0x8000000 +``` + +#### + +Of course, you can use this instead of the gdb server, if you prefer. +Just remember to use the “.bin” image, rather than the .elf file. + +``` + +# write blink.bin into FLASH +$> [sudo] ./st-flash write fancy_blink.bin 0x08000000 +``` + +Upon reset, the board LEDs should be blinking. + +Notes +===== + +Disassembling THUMB code in GDB +------------------------------- + +By default, the disassemble command in GDB operates in ARM mode. The +programs running on CORTEX-M3 are compiled in THUMB mode. To correctly +disassemble them under GDB, uses an odd address. For instance, if you +want to disassemble the code at 0x20000000, use:\ + +``` +(gdb) disassemble 0x20000001 +``` + +References +========== + +- + documentation related to the STM32L mcu + +- + documentation related to the STM32L discovery kit + +- + libopencm3, a project providing a firmware library, with solid + examples for Cortex M3, M4 and M0 processors from any vendor. diff --git a/doc/tutorial/tutorial.pdf b/doc/tutorial/tutorial.pdf deleted file mode 100644 index b73396ce73035085f757c109b178fdebdd3c6515..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110584 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

    F7N#fT_56|_1+x+jqH#Kr4(^OHy2cd; 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 diff --git a/doc/tutorial/tutorial.tex b/doc/tutorial/tutorial.tex deleted file mode 100644 index 5860ca888..000000000 --- a/doc/tutorial/tutorial.tex +++ /dev/null @@ -1,234 +0,0 @@ -\documentclass[a4paper, 11pt]{article} - -\usepackage{graphicx} -\usepackage{graphics} -\usepackage{verbatim} -\usepackage{listings} -\usepackage{color} - -\begin{document} - -\title{Using STM32 discovery kits with open source tools} -\author{STLINK development team} -\date{} - -\maketitle - -\newpage -\tableofcontents -\addtocontents{toc}{\protect\setcounter{tocdepth}{1}} - - -\newpage - -\section{Overview} -\paragraph{} -This guide details the use of STMicroelectronics STM32 discovery kits in -an open source environment. - - -\newpage - -\section{Installing a GNU toolchain} -\paragraph{} -Any toolchain supporting the cortex m3 should do. You can find the necessary -to install such a toolchain here:\\ -\begin{small} -\begin{lstlisting}[frame=tb] -https://github.com/esden/summon-arm-toolchain -\end{lstlisting} -\end{small} - -\paragraph{} -Details for the installation are provided in the topmost README file. -This documentation assumes the toolchains is installed in a \$TOOLCHAIN\_PATH. - - -\newpage - -\section{Installing STLINK} -\paragraph{} -STLINK is open source software to program and debug ST's STM32 Discovery kits. Those -kits have an onboard chip that translates USB commands sent by the host PC into -JTAG/SWD commands. This chip is called STLINK, (yes, isn't that confusing? suggest a better -name!) and comes in 2 versions (STLINK v1 and v2). From a software -point of view, those versions differ only in the transport layer used to communicate -(v1 uses SCSI passthru commands, while v2 uses raw USB). From a user point of view, they -are identical. - -\paragraph{} -Before continuing, the following dependencies must be met: -\begin{itemize} -\item libusb-1.0 -\item pkg-config -\item autotools -\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 -\end{lstlisting} -\end{small} - -\paragraph{} -Everything can be built from the top directory:\\ -\begin{small} -\begin{lstlisting}[frame=tb] -$> cd stlink.git -$> ./autogen.sh -$> ./configure -$> make -\end{lstlisting} -\end{small} -It includes: -\begin{itemize} -\item a communication library (stlink.git/libstlink.a), -\item a GDB server (stlink.git/st-util), -\item a flash manipulation tool (stlink.git/st-flash). -\end{itemize} - - -\newpage -\section{Using the GDB server} -\paragraph{} -This assumes you have got the libopencm3 project downloaded in [ocm3]. The -libopencm3 project has some good, reliable examples for each of the Discovery boards. - -Even if you don't plan on using libopencm3, the examples they provide will help you -verify that: - -\begin{itemize} -\item Your installed toolchain is capable of compiling for cortex M3/M4 targets -\item stlink is functional -\item Your arm-none-eabi-gdb is functional -\item Your board is functional -\end{itemize} - -\paragraph{} -A GDB server must be started to interact with the STM32. Depending on the discovery kit you -are using, you must run one of the 2 commands:\\ -\begin{small} -\begin{lstlisting}[frame=tb] -# STM32VL discovery kit (onboard ST-link) -$> ./st-util --stlinkv1 - -# STM32L or STM32F4 discovery kit (onboard ST-link/V2) -$> ./st-util - -# Full help for other options (listen port, version) -$> ./st-util --help -\end{lstlisting} -\end{small} - -\paragraph{} -Then, GDB can be used to interact with the kit:\\ -\begin{small} -\begin{lstlisting}[frame=tb] -$> $TOOLCHAIN_PATH/bin/arm-none-eabi-gdb example_file.elf -\end{lstlisting} -\end{small} - -\paragraph{} -From GDB, connect to the server using:\\ -\begin{small} -\begin{lstlisting}[frame=tb] -(gdb) target extended localhost:4242 -\end{lstlisting} -\end{small} - -\paragraph{} -GDB has memory maps for as many chips as it knows about, and will load your project -into either flash or SRAM based on how the project was linked. Linking projects -to boot from SRAM is beyond the scope of this document. - -Because of these built in memory maps, after specifying the .elf at the command line, now -we can simply "load" the target:\\ -\begin{small} -\begin{lstlisting}[frame=tb] -(gdb) load -\end{lstlisting} -\end{small} - -\paragraph{} -st-util will load all sections into their appropriate addresses, and "correctly" set the PC -register. So, to run your freshly loaded program, simply "continue"\\ -\begin{small} -\begin{lstlisting}[frame=tb] -(gdb) continue -\end{lstlisting} -\end{small} - -\paragraph{} -Your program should now be running, and, if you used one of the blinking examples from -libopencm3, the LEDs on the board should be blinking for you. - -\newpage -\section{Building and flashing a program} -\paragraph{} -If you want to simply flash binary files to arbitrary sections of memory, or -read arbitary addresses of memory out to a binary file, use the st-flash tool, -as shown below:\\ -\begin{small} -\begin{lstlisting}[frame=tb] - -# stlinkv1 command to read 4096 from flash into out.bin -$> ./st-flash read v1 out.bin 0x8000000 4096 - -# stlinkv2 command -$> ./st-flash read out.bin 0x8000000 4096 - -# stlinkv1 command to write the file in.bin into flash -$> ./st-flash write v1 in.bin 0x8000000 - -# stlinkv2 command -$> ./st-flash write in.bin 0x8000000 -\end{lstlisting} -\end{small} - -\paragraph{} -Of course, you can use this instead of the gdb server, if you prefer. Just remember -to use the ".bin" image, rather than the .elf file.\\ -\begin{small} -\begin{lstlisting}[frame=tb] - -# write blink.bin into FLASH -$> [sudo] ./st-flash write fancy_blink.bin 0x08000000 -\end{lstlisting} -\end{small} - -\paragraph{} -Upon reset, the board LEDs should be blinking. - -\newpage -\section{Notes} - -\subsection{Disassembling THUMB code in GDB} -\paragraph{} -By default, the disassemble command in GDB operates in ARM mode. The programs running on CORTEX-M3 -are compiled in THUMB mode. To correctly disassemble them under GDB, uses an odd address. For instance, -if you want to disassemble the code at 0x20000000, use:\\ -\begin{small} -\begin{lstlisting}[frame=tb] -(gdb) disassemble 0x20000001 -\end{lstlisting} -\end{small} - - -\newpage -\section{References} -\begin{itemize} -\item http://www.st.com/internet/mcu/product/248823.jsp\\ - documentation related to the STM32L mcu -\item http://www.st.com/internet/evalboard/product/250990.jsp\\ - documentation related to the STM32L discovery kit -\item http://www.libopencm3.org\\ - libopencm3, a project providing a firmware library, with solid examples for Cortex - M3, M4 and M0 processors from any vendor. -\end{itemize} - -\end{document} diff --git a/stlink_v1.modprobe.conf b/etc/modprobe.d/stlink_v1.conf similarity index 100% rename from stlink_v1.modprobe.conf rename to etc/modprobe.d/stlink_v1.conf diff --git a/49-stlinkv1.rules b/etc/udev/rules.d/49-stlinkv1.rules similarity index 100% rename from 49-stlinkv1.rules rename to etc/udev/rules.d/49-stlinkv1.rules diff --git a/49-stlinkv2-1.rules b/etc/udev/rules.d/49-stlinkv2-1.rules similarity index 100% rename from 49-stlinkv2-1.rules rename to etc/udev/rules.d/49-stlinkv2-1.rules diff --git a/49-stlinkv2.rules b/etc/udev/rules.d/49-stlinkv2.rules similarity index 100% rename from 49-stlinkv2.rules rename to etc/udev/rules.d/49-stlinkv2.rules diff --git a/flash/Makefile b/flash/Makefile deleted file mode 100644 index 5345dcbfd..000000000 --- a/flash/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -CFLAGS+=-g -CFLAGS+=-DDEBUG -CFLAGS+=-std=gnu99 -CFLAGS+=-Wall -Wextra -CFLAGS+=-I../src - -LDFLAGS=-L.. -lstlink - -# libusb location -LDFLAGS+=`pkg-config --libs libusb-1.0` -CFLAGS+=`pkg-config --cflags libusb-1.0` - -SRCS=main.c -OBJS=$(SRCS:.c=.o) - -NAME=st-flash - -all: $(NAME) - -$(NAME): $(OBJS) ../libstlink.a - $(CC) $(CFLAGS) -o $(NAME) $(OBJS) $(LDFLAGS) - -%.o: %.c - $(CC) $(CFLAGS) -c $^ -o $@ - -clean: - rm -f $(OBJS) - rm -f $(NAME) - -.PHONY: clean all diff --git a/src/stlink-common.h b/include/stlink.h similarity index 99% rename from src/stlink-common.h rename to include/stlink.h index e2f7b75c2..24b4dcf6e 100644 --- a/src/stlink-common.h +++ b/include/stlink.h @@ -1,20 +1,17 @@ /* - * File: stlink-common.h - * Bulk import from stlink-hw.h + * File: stlink.h * * This should contain all the common top level stlink interfaces, regardless * of how the backend does the work.... */ +#ifndef STLINK_H +#define STLINK_H -#ifndef STLINK_COMMON_H -#define STLINK_COMMON_H +#include -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif - -#include - // Max data transfer size. // 6kB = max mem32_read block, 8kB sram //#define Q_BUF_LEN 96 @@ -728,15 +725,11 @@ extern "C" { int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size); int stlink_load_device_params(stlink_t *sl); +#include "stlink/sg.h" +#include "stlink/usb.h" - -#include "stlink-sg.h" -#include "stlink-usb.h" - - - -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* STLINK_COMMON_H */ +#endif /* STLINK_H */ diff --git a/src/uglylogging.h b/include/stlink/logging.h similarity index 100% rename from src/uglylogging.h rename to include/stlink/logging.h diff --git a/src/mmap.h b/include/stlink/mmap.h similarity index 100% rename from src/mmap.h rename to include/stlink/mmap.h diff --git a/src/stlink-sg.h b/include/stlink/sg.h similarity index 96% rename from src/stlink-sg.h rename to include/stlink/sg.h index 7c0202851..56780f4c4 100644 --- a/src/stlink-sg.h +++ b/include/stlink/sg.h @@ -1,5 +1,5 @@ /* - * File: stlink-sg.h + * File: stlink/sg.h * Author: karl * * Created on October 1, 2011, 11:29 PM @@ -8,13 +8,13 @@ #ifndef STLINK_SG_H #define STLINK_SG_H +#include +#include "stlink.h" + #ifdef __cplusplus extern "C" { #endif -#include -#include "stlink-common.h" - // device access #define RDWR 0 #define RO 1 diff --git a/src/stlink-usb.h b/include/stlink/usb.h similarity index 93% rename from src/stlink-usb.h rename to include/stlink/usb.h index 747d54c74..76ac9211f 100644 --- a/src/stlink-usb.h +++ b/include/stlink/usb.h @@ -1,5 +1,5 @@ /* - * File: stlink-usb.h + * File: stlink/usb.h * Author: karl * * Created on October 1, 2011, 11:29 PM @@ -11,8 +11,8 @@ #include #include -#include "stlink-common.h" -#include "uglylogging.h" +#include "stlink.h" +#include "stlink/logging.h" #ifdef __cplusplus extern "C" { diff --git a/src/stlink-common.c b/src/common.c similarity index 99% rename from src/stlink-common.c rename to src/common.c index 18c76fb86..3e87824f1 100644 --- a/src/stlink-common.c +++ b/src/common.c @@ -9,10 +9,10 @@ #include #include #include -#include "mmap.h" -#include "stlink-common.h" -#include "uglylogging.h" +#include "stlink.h" +#include "stlink/mmap.h" +#include "stlink/logging.h" #ifndef _WIN32 #define O_BINARY 0 diff --git a/gdbserver/Makefile b/src/gdbserver/Makefile similarity index 100% rename from gdbserver/Makefile rename to src/gdbserver/Makefile diff --git a/gdbserver/gdb-remote.c b/src/gdbserver/gdb-remote.c similarity index 100% rename from gdbserver/gdb-remote.c rename to src/gdbserver/gdb-remote.c diff --git a/gdbserver/gdb-remote.h b/src/gdbserver/gdb-remote.h similarity index 100% rename from gdbserver/gdb-remote.h rename to src/gdbserver/gdb-remote.h diff --git a/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c similarity index 99% rename from gdbserver/gdb-server.c rename to src/gdbserver/gdb-server.c index eca6597b4..666251c1b 100644 --- a/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -19,8 +19,8 @@ #include #endif -#include -#include +#include +#include #include "gdb-remote.h" #include "gdb-server.h" diff --git a/gdbserver/gdb-server.h b/src/gdbserver/gdb-server.h similarity index 100% rename from gdbserver/gdb-server.h rename to src/gdbserver/gdb-server.h diff --git a/src/uglylogging.c b/src/logging.c similarity index 97% rename from src/uglylogging.c rename to src/logging.c index a04ab3391..4969c4400 100644 --- a/src/uglylogging.c +++ b/src/logging.c @@ -3,14 +3,13 @@ * rest of our code pretty enough. * */ - #include #include #include #include #include -#include "uglylogging.h" +#include "stlink/logging.h" static int max_level; diff --git a/mingw/mingw.c b/src/mingw/mingw.c similarity index 100% rename from mingw/mingw.c rename to src/mingw/mingw.c diff --git a/mingw/mingw.h b/src/mingw/mingw.h similarity index 100% rename from mingw/mingw.h rename to src/mingw/mingw.h diff --git a/src/mmap.c b/src/mmap.c index c5794da91..bee0dcece 100644 --- a/src/mmap.c +++ b/src/mmap.c @@ -3,7 +3,7 @@ #include #include -#include "mmap.h" +#include "stlink/mmap.h" void *mmap (void *addr, size_t len, int prot, int flags, int fd, long long offset) { diff --git a/src/stlink-sg.c b/src/sg.c similarity index 99% rename from src/stlink-sg.c rename to src/sg.c index 03df7d854..40570981d 100644 --- a/src/stlink-sg.c +++ b/src/sg.c @@ -82,9 +82,8 @@ #include #include -#include "stlink-common.h" -#include "stlink-sg.h" -#include "uglylogging.h" +#include "stlink.h" +#include "stlink/logging.h" static void clear_cdb(struct stlink_libsg *sl) { for (size_t i = 0; i < sizeof (sl->cdb_cmd_blk); i++) diff --git a/flash/main.c b/src/tools/flash.c similarity index 99% rename from flash/main.c rename to src/tools/flash.c index 0ba429c66..770289ba3 100644 --- a/flash/main.c +++ b/src/tools/flash.c @@ -8,7 +8,8 @@ #include #include #include -#include "stlink-common.h" + +#include #define DEBUG_LOG_LEVEL 100 #define STND_LOG_LEVEL 50 diff --git a/src/st-info.c b/src/tools/info.c similarity index 99% rename from src/st-info.c rename to src/tools/info.c index 1671468f0..e29184e5a 100644 --- a/src/st-info.c +++ b/src/tools/info.c @@ -3,7 +3,7 @@ #include #include -#include +#include static void usage(void) { diff --git a/src/st-term.c b/src/tools/term.c similarity index 99% rename from src/st-term.c rename to src/tools/term.c index 245ed5949..9b46e2a4c 100644 --- a/src/st-term.c +++ b/src/tools/term.c @@ -9,7 +9,8 @@ #include #include #include -#include "stlink-common.h" + +#include /* STLinky structure on STM chip diff --git a/src/stlink-usb.c b/src/usb.c similarity index 99% rename from src/stlink-usb.c rename to src/usb.c index 98654129e..e8d8ec39d 100644 --- a/src/stlink-usb.c +++ b/src/usb.c @@ -8,8 +8,7 @@ #include #include -#include "stlink-common.h" -#include "stlink-usb.h" +#include "stlink.h" enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80}; diff --git a/src/test_sg.c b/tests/stlink_sg.c similarity index 100% rename from src/test_sg.c rename to tests/stlink_sg.c diff --git a/src/test_usb.c b/tests/stlink_usb.c similarity index 100% rename from src/test_usb.c rename to tests/stlink_usb.c From bd21ced1ab457e38e87649c3746b10f6d8d04199 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 5 May 2016 19:49:16 +0200 Subject: [PATCH 0407/1435] README.md: Recover removed symlink to README --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 120000 README.md diff --git a/README.md b/README.md new file mode 120000 index 000000000..100b93820 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +README \ No newline at end of file From c267a3aaa84d2788940010f51568b99192f86436 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 5 May 2016 20:02:30 +0200 Subject: [PATCH 0408/1435] Update LICENSE with stlink contributors and notice license in README --- LICENSE | 14 ++++++++------ README | 4 ++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/LICENSE b/LICENSE index 37b124eba..3d464ca1e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,5 @@ +Copyright (c) 2011 The stlink project (github.com/texane/stlink) contributors. + All rights reserved. Copyright (c) 2011 The "Capt'ns Missing Link" Authors. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -5,14 +7,14 @@ modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. + notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. * Neither the name of Martin Capitanio nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT diff --git a/README b/README index da7fafa32..90bc0849d 100644 --- a/README +++ b/README @@ -230,3 +230,7 @@ STLink v2-1 (as found on the Nucleo boards), known working targets: * STM32L053R8 (STM32 Nucleo-L053R8 board) Please report any and all known working combinations so I can update this! + +## License + +The stlink library and tools are licensed under the [BSD license](LICENSE) From e30fcd4fd0b3d71b189cf30d81a84b2231de5714 Mon Sep 17 00:00:00 2001 From: Piotr Haber Date: Thu, 24 Mar 2016 10:03:31 +0100 Subject: [PATCH 0409/1435] Add support for L0x Category 5 devices --- include/stlink.h | 13 +++++++++++++ src/common.c | 8 ++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 24b4dcf6e..c29e2a663 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -137,6 +137,7 @@ extern "C" { #define STM32_CHIPID_F04 0x445 #define STM32_CHIPID_F303_HIGH 0x446 +#define STM32_CHIPID_L0_CAT5 0x447 #define STM32_CHIPID_F0_CAN 0x448 @@ -504,6 +505,18 @@ extern "C" { .bootrom_base = 0x1ff0000, .bootrom_size = 0x1000 }, + { + // STM32L0x Category 5 + // RM0367,RM0377 documents was used to find these parameters + .chip_id = STM32_CHIPID_L0_CAT5, + .description = "L0x Category 5 device", + .flash_type = FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x5000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x2000 + }, { // STM32F334 // RM0364 document was used to find these parameters diff --git a/src/common.c b/src/common.c index 3e87824f1..a167bb6d4 100644 --- a/src/common.c +++ b/src/common.c @@ -1288,7 +1288,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) uint32_t val; uint32_t flash_regs_base; - if (sl->chip_id == STM32_CHIPID_L0) { + if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; } else { flash_regs_base = STM32L_FLASH_REGS_ADDR; @@ -1667,7 +1667,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F04 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL || sl->chip_id == STM32_CHIPID_F09X) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); - } else if (sl->chip_id == STM32_CHIPID_L0) { + } else if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5) { loader_code = loader_code_stm32l0; loader_size = sizeof(loader_code_stm32l0); } else if (sl->chip_id == STM32_CHIPID_L4) { @@ -1747,7 +1747,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uin uint32_t flash_regs_base; flash_loader_t fl; - if (sl->chip_id == STM32_CHIPID_L0) { + if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; } else { flash_regs_base = STM32L_FLASH_REGS_ADDR; @@ -1914,7 +1914,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t uint32_t flash_regs_base; uint32_t pagesize; - if (sl->chip_id == STM32_CHIPID_L0) { + if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; pagesize = L0_WRITE_BLOCK_SIZE; } else { From f5d6cec4c72989fe2bb8ec4f4d03cce6f4505d23 Mon Sep 17 00:00:00 2001 From: Tom de Boer Date: Fri, 6 May 2016 13:47:00 +0200 Subject: [PATCH 0410/1435] Fix for broken STML0 and STML1 Commits 907383da8ef95fedc630cdf7cf102d44ae229200 and e43a737c3c9ffe56045181b306509c942fd9998a were causing issues for people with STML0's and STML1's. This commit reverses the changes in these two commits. --- flashloaders/stm32l0x.s | 20 +++++----- flashloaders/stm32lx.s | 20 +++++----- src/common.c | 87 ++++++++++++++++++++++++----------------- 3 files changed, 74 insertions(+), 53 deletions(-) diff --git a/flashloaders/stm32l0x.s b/flashloaders/stm32l0x.s index fcbd06e39..9fc44468f 100644 --- a/flashloaders/stm32l0x.s +++ b/flashloaders/stm32l0x.s @@ -34,29 +34,31 @@ .global write /* - r0 - source address - r1 - destination address + r0 - destination address + r1 - source address r2 - count */ + // Set 0 to r3 + movs r3, #0 // Go to compare - b test_done + b.n test_done write_word: // Load one word from address in r0, increment by 4 - ldr r4, [r0] + ldr r4, [r1] // Store the word to address in r1, increment by 4 - str r4, [r1] - // Decrement r2 - subs r2, #1 + str r4, [r0] + // Increment r3 + adds r3, #1 adds r1, #4 // does not matter, only first addr is important // next 15 bytes are in sequnce RM0367 page 66 adds r0, #4 test_done: - // Test r2 - cmp r2, #0 + // Compare r3 and r2 + cmp r3, r2 // Loop if not zero bcc.n write_word diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index bb8f7c93f..799d1345c 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -34,25 +34,27 @@ .global write /* - r0 - source address - r1 - destination address + r0 - destination address + r1 - source address r2 - count */ + // Set 0 to r3 + movs r3, #0 // Go to compare - b test_done + b.n test_done write_word: // Load one word from address in r0, increment by 4 - ldr.w ip, [r0], #4 + ldr.w ip, [r1], #4 // Store the word to address in r1, increment by 4 - str.w ip, [r1], #4 - // Decrement r2 - subs r2, #1 + str.w ip, [r0], #4 + // Increment r3 + adds r3, #1 test_done: - // Test r2 - cmp r2, #0 + // Compare r3 and r2 + cmp r3, r2 // Loop if not zero bcc.n write_word diff --git a/src/common.c b/src/common.c index a167bb6d4..7504c27ac 100644 --- a/src/common.c +++ b/src/common.c @@ -593,12 +593,6 @@ int stlink_load_device_params(stlink_t *sl) { return -1; } - if (params->flash_type == FLASH_TYPE_UNKNOWN) { - WLOG("Invalid flash type, please check device declaration\n"); - return -1; - } - - // These are fixed... sl->flash_base = STM32_FLASH_BASE; sl->sram_base = STM32_SRAM_BASE; @@ -1511,19 +1505,20 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { static const uint8_t loader_code_stm32l[] = { /* openocd.git/contrib/loaders/flash/stm32lx.S - r0, input, source addr - r1, input, dest addr + r0, input, dest addr + r1, input, source addr r2, input, word count - r2, output, remaining word count + r3, output, word count */ + 0x00, 0x23, 0x04, 0xe0, - 0x50, 0xf8, 0x04, 0xcb, - 0x41, 0xf8, 0x04, 0xcb, - 0x01, 0x3a, + 0x51, 0xf8, 0x04, 0xcb, + 0x40, 0xf8, 0x04, 0xcb, + 0x01, 0x33, - 0x00, 0x2a, + 0x93, 0x42, 0xf8, 0xd3, 0x00, 0xbe }; @@ -1531,21 +1526,22 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { static const uint8_t loader_code_stm32l0[] = { /* - r0, input, source addr - r1, input, dest addr + r0, input, dest addr + r1, input, source addr r2, input, word count - r2, output, remaining word count + r3, output, word count */ + 0x00, 0x23, 0x04, 0xe0, - 0x04, 0x68, - 0x0c, 0x60, - 0x01, 0x3a, + 0x0c, 0x68, + 0x04, 0x60, + 0x01, 0x33, 0x04, 0x31, 0x04, 0x30, - 0x00, 0x2a, + 0x93, 0x42, 0xf8, 0xd3, 0x00, 0xbe }; @@ -1608,7 +1604,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0xfb, 0xd1, // bne.n 0x00, 0xf1, 0x08, 0x00, // add.w r0, r0, #8 0x01, 0xf1, 0x08, 0x01, // add.w r1, r1, #8 - 0xa2, 0xf1, 0x01, 0x02, // sub.w r2, r2, #1 + 0xa2, 0xf1, 0x02, 0x02, // add.w r2, r2, #2 0xef, 0xe7, // b.n 0x00, 0xbe, // done: bkpt 0x0000 0x00, 0x20, 0x02, 0x40 // flash_base: .word 0x40022000 @@ -2072,8 +2068,8 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { reg rr; - int i = 0; - size_t count = 0; + int target_reg, source_reg, i = 0; + size_t count; DLOG("Running flash loader, write address:%#x, size: %zd\n", target, size); // FIXME This can never return -1 @@ -2083,23 +2079,36 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - if (sl->flash_type == FLASH_TYPE_F0) { + if (sl->flash_type == FLASH_TYPE_L0) { + count = size / sizeof(uint32_t); + if (size % sizeof(uint32_t)) + ++count; + target_reg = 0; + source_reg = 1; + } else if (sl->flash_type == FLASH_TYPE_F0) { count = size / sizeof(uint16_t); if (size % sizeof(uint16_t)) ++count; - } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L0) { + target_reg = 1; + source_reg = 0; + } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L4) { count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; - } else if (sl->flash_type == FLASH_TYPE_L4) { - count = size / sizeof(uint64_t); - if (size % sizeof(uint64_t)) - ++count; + if (sl->chip_id == STM32_CHIPID_L4) { + if (count % 2) + ++count; + } + target_reg = 1; + source_reg = 0; + } else { + fprintf(stderr, "unknown coreid 0x%x, don't know what flash loader to use\n", sl->core_id); + return -1; } /* setup core */ - stlink_write_reg(sl, fl->buf_addr, 0); /* source */ - stlink_write_reg(sl, target, 1); /* target */ + stlink_write_reg(sl, fl->buf_addr, source_reg); /* source */ + stlink_write_reg(sl, target, target_reg); /* target */ stlink_write_reg(sl, count, 2); /* count */ stlink_write_reg(sl, 0, 3); /* flash bank 0 (input), only used on F0, but armless fopr others */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ @@ -2120,11 +2129,19 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } + stlink_read_all_regs(sl, &rr); + /* check written byte count */ - stlink_read_reg(sl, 2, &rr); - if (rr.r[2] != 0) { - fprintf(stderr, "write error, count == %u\n", rr.r[2]); - return -1; + if (sl->flash_type == FLASH_TYPE_L0) { + if (rr.r[3] != count) { + fprintf(stderr, "write error, count == %u\n", rr.r[3]); + return -1; + } + } else { + if (rr.r[2] != 0) { + fprintf(stderr, "write error, count == %u\n", rr.r[2]); + return -1; + } } return 0; From 26949364f707622f01f246c58715f65cd8bb6cdb Mon Sep 17 00:00:00 2001 From: Tom de Boer Date: Fri, 6 May 2016 13:47:00 +0200 Subject: [PATCH 0411/1435] Fixed the STM32L-problem according to @gluedig See https://github.com/texane/stlink/issues/390#issuecomment-217382832 --- flashloaders/stm32l0x.s | 20 ++++----- flashloaders/stm32lx.s | 22 +++++----- src/common.c | 92 +++++++++++++++++------------------------ 3 files changed, 57 insertions(+), 77 deletions(-) diff --git a/flashloaders/stm32l0x.s b/flashloaders/stm32l0x.s index 9fc44468f..fcbd06e39 100644 --- a/flashloaders/stm32l0x.s +++ b/flashloaders/stm32l0x.s @@ -34,31 +34,29 @@ .global write /* - r0 - destination address - r1 - source address + r0 - source address + r1 - destination address r2 - count */ - // Set 0 to r3 - movs r3, #0 // Go to compare - b.n test_done + b test_done write_word: // Load one word from address in r0, increment by 4 - ldr r4, [r1] + ldr r4, [r0] // Store the word to address in r1, increment by 4 - str r4, [r0] - // Increment r3 - adds r3, #1 + str r4, [r1] + // Decrement r2 + subs r2, #1 adds r1, #4 // does not matter, only first addr is important // next 15 bytes are in sequnce RM0367 page 66 adds r0, #4 test_done: - // Compare r3 and r2 - cmp r3, r2 + // Test r2 + cmp r2, #0 // Loop if not zero bcc.n write_word diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index 799d1345c..f162c8827 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -34,29 +34,27 @@ .global write /* - r0 - destination address - r1 - source address + r0 - source address + r1 - destination address r2 - count */ - // Set 0 to r3 - movs r3, #0 // Go to compare - b.n test_done + b test_done write_word: // Load one word from address in r0, increment by 4 - ldr.w ip, [r1], #4 + ldr.w ip, [r0], #4 // Store the word to address in r1, increment by 4 - str.w ip, [r0], #4 - // Increment r3 - adds r3, #1 + str.w ip, [r1], #4 + // Decrement r2 + subs r2, #1 test_done: - // Compare r3 and r2 - cmp r3, r2 + // Test r2 + cmp r2, #0 // Loop if not zero - bcc.n write_word + bhi write_word // Set breakpoint to exit bkpt #0x00 diff --git a/src/common.c b/src/common.c index 7504c27ac..f8251a8c0 100644 --- a/src/common.c +++ b/src/common.c @@ -593,6 +593,12 @@ int stlink_load_device_params(stlink_t *sl) { return -1; } + if (params->flash_type == FLASH_TYPE_UNKNOWN) { + WLOG("Invalid flash type, please check device declaration\n"); + return -1; + } + + // These are fixed... sl->flash_base = STM32_FLASH_BASE; sl->sram_base = STM32_SRAM_BASE; @@ -1505,43 +1511,42 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { static const uint8_t loader_code_stm32l[] = { /* openocd.git/contrib/loaders/flash/stm32lx.S - r0, input, dest addr - r1, input, source addr + r0, input, source addr + r1, input, dest addr r2, input, word count - r3, output, word count + r2, output, remaining word count */ - 0x00, 0x23, 0x04, 0xe0, - 0x51, 0xf8, 0x04, 0xcb, - 0x40, 0xf8, 0x04, 0xcb, - 0x01, 0x33, + 0x50, 0xf8, 0x04, 0xcb, + 0x41, 0xf8, 0x04, 0xcb, + 0x01, 0x3a, - 0x93, 0x42, - 0xf8, 0xd3, - 0x00, 0xbe + 0x00, 0x2a, + 0xf8, 0xd8, + 0x00, 0xbe, + 0x00, 0x00 }; static const uint8_t loader_code_stm32l0[] = { /* - r0, input, dest addr - r1, input, source addr + r0, input, source addr + r1, input, dest addr r2, input, word count - r3, output, word count + r2, output, remaining word count */ - 0x00, 0x23, 0x04, 0xe0, - 0x0c, 0x68, - 0x04, 0x60, - 0x01, 0x33, + 0x04, 0x68, + 0x0c, 0x60, + 0x01, 0x3a, 0x04, 0x31, 0x04, 0x30, - 0x93, 0x42, + 0x00, 0x2a, 0xf8, 0xd3, 0x00, 0xbe }; @@ -1604,7 +1609,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0xfb, 0xd1, // bne.n 0x00, 0xf1, 0x08, 0x00, // add.w r0, r0, #8 0x01, 0xf1, 0x08, 0x01, // add.w r1, r1, #8 - 0xa2, 0xf1, 0x02, 0x02, // add.w r2, r2, #2 + 0xa2, 0xf1, 0x01, 0x02, // sub.w r2, r2, #1 0xef, 0xe7, // b.n 0x00, 0xbe, // done: bkpt 0x0000 0x00, 0x20, 0x02, 0x40 // flash_base: .word 0x40022000 @@ -2068,8 +2073,8 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { reg rr; - int target_reg, source_reg, i = 0; - size_t count; + int i = 0; + size_t count = 0; DLOG("Running flash loader, write address:%#x, size: %zd\n", target, size); // FIXME This can never return -1 @@ -2079,36 +2084,23 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - if (sl->flash_type == FLASH_TYPE_L0) { - count = size / sizeof(uint32_t); - if (size % sizeof(uint32_t)) - ++count; - target_reg = 0; - source_reg = 1; - } else if (sl->flash_type == FLASH_TYPE_F0) { + if (sl->flash_type == FLASH_TYPE_F0) { count = size / sizeof(uint16_t); if (size % sizeof(uint16_t)) ++count; - target_reg = 1; - source_reg = 0; - } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L4) { + } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L0) { count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; - if (sl->chip_id == STM32_CHIPID_L4) { - if (count % 2) - ++count; - } - target_reg = 1; - source_reg = 0; - } else { - fprintf(stderr, "unknown coreid 0x%x, don't know what flash loader to use\n", sl->core_id); - return -1; + } else if (sl->flash_type == FLASH_TYPE_L4) { + count = size / sizeof(uint64_t); + if (size % sizeof(uint64_t)) + ++count; } /* setup core */ - stlink_write_reg(sl, fl->buf_addr, source_reg); /* source */ - stlink_write_reg(sl, target, target_reg); /* target */ + stlink_write_reg(sl, fl->buf_addr, 0); /* source */ + stlink_write_reg(sl, target, 1); /* target */ stlink_write_reg(sl, count, 2); /* count */ stlink_write_reg(sl, 0, 3); /* flash bank 0 (input), only used on F0, but armless fopr others */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ @@ -2129,19 +2121,11 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - stlink_read_all_regs(sl, &rr); - /* check written byte count */ - if (sl->flash_type == FLASH_TYPE_L0) { - if (rr.r[3] != count) { - fprintf(stderr, "write error, count == %u\n", rr.r[3]); - return -1; - } - } else { - if (rr.r[2] != 0) { - fprintf(stderr, "write error, count == %u\n", rr.r[2]); - return -1; - } + stlink_read_reg(sl, 2, &rr); + if (rr.r[2] != 0) { + fprintf(stderr, "write error, count == %u\n", rr.r[2]); + return -1; } return 0; From 17ab4bcaa88c81ba7f952f8bfed0fb3387a4eaa0 Mon Sep 17 00:00:00 2001 From: Piotr Haber Date: Mon, 9 May 2016 08:22:11 +0200 Subject: [PATCH 0412/1435] Revert "Merge pull request #407 from tomdeboer/STML1_Fix" This reverts commit a591a30f85a3e6b152f94cd5cc1eb5ae113a3517, reversing changes made to 0bb22e9ed6c2c0899fc31ee71dcbc59f1211d893. --- flashloaders/stm32l0x.s | 20 +++++----- flashloaders/stm32lx.s | 20 +++++----- src/common.c | 87 +++++++++++++++++------------------------ 3 files changed, 53 insertions(+), 74 deletions(-) diff --git a/flashloaders/stm32l0x.s b/flashloaders/stm32l0x.s index 9fc44468f..fcbd06e39 100644 --- a/flashloaders/stm32l0x.s +++ b/flashloaders/stm32l0x.s @@ -34,31 +34,29 @@ .global write /* - r0 - destination address - r1 - source address + r0 - source address + r1 - destination address r2 - count */ - // Set 0 to r3 - movs r3, #0 // Go to compare - b.n test_done + b test_done write_word: // Load one word from address in r0, increment by 4 - ldr r4, [r1] + ldr r4, [r0] // Store the word to address in r1, increment by 4 - str r4, [r0] - // Increment r3 - adds r3, #1 + str r4, [r1] + // Decrement r2 + subs r2, #1 adds r1, #4 // does not matter, only first addr is important // next 15 bytes are in sequnce RM0367 page 66 adds r0, #4 test_done: - // Compare r3 and r2 - cmp r3, r2 + // Test r2 + cmp r2, #0 // Loop if not zero bcc.n write_word diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index 799d1345c..bb8f7c93f 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -34,27 +34,25 @@ .global write /* - r0 - destination address - r1 - source address + r0 - source address + r1 - destination address r2 - count */ - // Set 0 to r3 - movs r3, #0 // Go to compare - b.n test_done + b test_done write_word: // Load one word from address in r0, increment by 4 - ldr.w ip, [r1], #4 + ldr.w ip, [r0], #4 // Store the word to address in r1, increment by 4 - str.w ip, [r0], #4 - // Increment r3 - adds r3, #1 + str.w ip, [r1], #4 + // Decrement r2 + subs r2, #1 test_done: - // Compare r3 and r2 - cmp r3, r2 + // Test r2 + cmp r2, #0 // Loop if not zero bcc.n write_word diff --git a/src/common.c b/src/common.c index 7504c27ac..a167bb6d4 100644 --- a/src/common.c +++ b/src/common.c @@ -593,6 +593,12 @@ int stlink_load_device_params(stlink_t *sl) { return -1; } + if (params->flash_type == FLASH_TYPE_UNKNOWN) { + WLOG("Invalid flash type, please check device declaration\n"); + return -1; + } + + // These are fixed... sl->flash_base = STM32_FLASH_BASE; sl->sram_base = STM32_SRAM_BASE; @@ -1505,20 +1511,19 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { static const uint8_t loader_code_stm32l[] = { /* openocd.git/contrib/loaders/flash/stm32lx.S - r0, input, dest addr - r1, input, source addr + r0, input, source addr + r1, input, dest addr r2, input, word count - r3, output, word count + r2, output, remaining word count */ - 0x00, 0x23, 0x04, 0xe0, - 0x51, 0xf8, 0x04, 0xcb, - 0x40, 0xf8, 0x04, 0xcb, - 0x01, 0x33, + 0x50, 0xf8, 0x04, 0xcb, + 0x41, 0xf8, 0x04, 0xcb, + 0x01, 0x3a, - 0x93, 0x42, + 0x00, 0x2a, 0xf8, 0xd3, 0x00, 0xbe }; @@ -1526,22 +1531,21 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { static const uint8_t loader_code_stm32l0[] = { /* - r0, input, dest addr - r1, input, source addr + r0, input, source addr + r1, input, dest addr r2, input, word count - r3, output, word count + r2, output, remaining word count */ - 0x00, 0x23, 0x04, 0xe0, - 0x0c, 0x68, - 0x04, 0x60, - 0x01, 0x33, + 0x04, 0x68, + 0x0c, 0x60, + 0x01, 0x3a, 0x04, 0x31, 0x04, 0x30, - 0x93, 0x42, + 0x00, 0x2a, 0xf8, 0xd3, 0x00, 0xbe }; @@ -1604,7 +1608,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0xfb, 0xd1, // bne.n 0x00, 0xf1, 0x08, 0x00, // add.w r0, r0, #8 0x01, 0xf1, 0x08, 0x01, // add.w r1, r1, #8 - 0xa2, 0xf1, 0x02, 0x02, // add.w r2, r2, #2 + 0xa2, 0xf1, 0x01, 0x02, // sub.w r2, r2, #1 0xef, 0xe7, // b.n 0x00, 0xbe, // done: bkpt 0x0000 0x00, 0x20, 0x02, 0x40 // flash_base: .word 0x40022000 @@ -2068,8 +2072,8 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { reg rr; - int target_reg, source_reg, i = 0; - size_t count; + int i = 0; + size_t count = 0; DLOG("Running flash loader, write address:%#x, size: %zd\n", target, size); // FIXME This can never return -1 @@ -2079,36 +2083,23 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - if (sl->flash_type == FLASH_TYPE_L0) { - count = size / sizeof(uint32_t); - if (size % sizeof(uint32_t)) - ++count; - target_reg = 0; - source_reg = 1; - } else if (sl->flash_type == FLASH_TYPE_F0) { + if (sl->flash_type == FLASH_TYPE_F0) { count = size / sizeof(uint16_t); if (size % sizeof(uint16_t)) ++count; - target_reg = 1; - source_reg = 0; - } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L4) { + } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L0) { count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; - if (sl->chip_id == STM32_CHIPID_L4) { - if (count % 2) - ++count; - } - target_reg = 1; - source_reg = 0; - } else { - fprintf(stderr, "unknown coreid 0x%x, don't know what flash loader to use\n", sl->core_id); - return -1; + } else if (sl->flash_type == FLASH_TYPE_L4) { + count = size / sizeof(uint64_t); + if (size % sizeof(uint64_t)) + ++count; } /* setup core */ - stlink_write_reg(sl, fl->buf_addr, source_reg); /* source */ - stlink_write_reg(sl, target, target_reg); /* target */ + stlink_write_reg(sl, fl->buf_addr, 0); /* source */ + stlink_write_reg(sl, target, 1); /* target */ stlink_write_reg(sl, count, 2); /* count */ stlink_write_reg(sl, 0, 3); /* flash bank 0 (input), only used on F0, but armless fopr others */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ @@ -2129,19 +2120,11 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - stlink_read_all_regs(sl, &rr); - /* check written byte count */ - if (sl->flash_type == FLASH_TYPE_L0) { - if (rr.r[3] != count) { - fprintf(stderr, "write error, count == %u\n", rr.r[3]); - return -1; - } - } else { - if (rr.r[2] != 0) { - fprintf(stderr, "write error, count == %u\n", rr.r[2]); - return -1; - } + stlink_read_reg(sl, 2, &rr); + if (rr.r[2] != 0) { + fprintf(stderr, "write error, count == %u\n", rr.r[2]); + return -1; } return 0; From 013fc429de40f3e233e7831c4a90f778d42d70a3 Mon Sep 17 00:00:00 2001 From: Piotr Haber Date: Fri, 6 May 2016 09:08:31 +0200 Subject: [PATCH 0413/1435] fix for L0 flash loader --- src/common.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/common.c b/src/common.c index a167bb6d4..883a04548 100644 --- a/src/common.c +++ b/src/common.c @@ -1537,17 +1537,18 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { r2, output, remaining word count */ - 0x04, 0xe0, - - 0x04, 0x68, - 0x0c, 0x60, - 0x01, 0x3a, - 0x04, 0x31, - 0x04, 0x30, - - 0x00, 0x2a, - 0xf8, 0xd3, - 0x00, 0xbe + 0x00, 0xbf, // nop /* to make loader length % 4 = 0 */ + 0x04, 0xe0, // b test_done /* Go to compare */ + //write_word + 0x04, 0x68, // ldr r4, [r0] /* Load one word from address in r0 */ + 0x0c, 0x60, // str r4, [r1] /* Store the word to address in r1 */ + 0x04, 0x30, // adds r0, #4 /* Increment r0 */ + 0x04, 0x31, // adds r1, #4 /* Increment r1 */ + 0x01, 0x3a, // subs r2, #1 /* Decrement r2 */ + //test_done: + 0x00, 0x2a, // cmp r2, #0 /* Compare r2 to 0 */ + 0xf8, 0xd8, // bhi write_word /* Loop if above 0 */ + 0x00, 0xbe // bkpt #0x00 /* Set breakpoint to exit */ }; static const uint8_t loader_code_stm32f4[] = { From d8c4e7c1bd29921c2b24703d264669b9c711bae9 Mon Sep 17 00:00:00 2001 From: Piotr Haber Date: Mon, 9 May 2016 08:45:50 +0200 Subject: [PATCH 0414/1435] merge L0 and L1 flash loader --- src/common.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/src/common.c b/src/common.c index 883a04548..456c0b173 100644 --- a/src/common.c +++ b/src/common.c @@ -1510,27 +1510,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { static const uint8_t loader_code_stm32l[] = { - /* openocd.git/contrib/loaders/flash/stm32lx.S - r0, input, source addr - r1, input, dest addr - r2, input, word count - r2, output, remaining word count - */ - - 0x04, 0xe0, - - 0x50, 0xf8, 0x04, 0xcb, - 0x41, 0xf8, 0x04, 0xcb, - 0x01, 0x3a, - - 0x00, 0x2a, - 0xf8, 0xd3, - 0x00, 0xbe - }; - - static const uint8_t loader_code_stm32l0[] = { - - /* + /* based on openocd.git/contrib/loaders/flash/stm32lx.S r0, input, source addr r1, input, dest addr r2, input, word count @@ -1637,7 +1617,8 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH - || sl->chip_id == STM32_CHIPID_L152_RE) { /* stm32l */ + || sl->chip_id == STM32_CHIPID_L152_RE + || sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID @@ -1668,9 +1649,6 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F04 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL || sl->chip_id == STM32_CHIPID_F09X) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); - } else if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5) { - loader_code = loader_code_stm32l0; - loader_size = sizeof(loader_code_stm32l0); } else if (sl->chip_id == STM32_CHIPID_L4) { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); From 75ed6cfb9f461337cef2d42f14dfafb342812e44 Mon Sep 17 00:00:00 2001 From: Tom de Boer Date: Mon, 9 May 2016 10:55:57 +0200 Subject: [PATCH 0415/1435] Formatted comments and stm32lx.s --- flashloaders/stm32lx.s | 4 ++-- src/common.c | 34 ++++++++++++++-------------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index f162c8827..10e5644bf 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -25,7 +25,7 @@ ***************************************************************************/ -// Build : arm-eabi-gcc -c stm32lx.S +// Build : arm-eabi-gcc -c stm32lx.s .text .syntax unified .cpu cortex-m3 @@ -36,7 +36,7 @@ /* r0 - source address r1 - destination address - r2 - count + r2 - output, remaining word count */ // Go to compare diff --git a/src/common.c b/src/common.c index 456c0b173..a3ffda7e4 100644 --- a/src/common.c +++ b/src/common.c @@ -1509,26 +1509,20 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { }; static const uint8_t loader_code_stm32l[] = { - - /* based on openocd.git/contrib/loaders/flash/stm32lx.S - r0, input, source addr - r1, input, dest addr - r2, input, word count - r2, output, remaining word count - */ - - 0x00, 0xbf, // nop /* to make loader length % 4 = 0 */ - 0x04, 0xe0, // b test_done /* Go to compare */ - //write_word - 0x04, 0x68, // ldr r4, [r0] /* Load one word from address in r0 */ - 0x0c, 0x60, // str r4, [r1] /* Store the word to address in r1 */ - 0x04, 0x30, // adds r0, #4 /* Increment r0 */ - 0x04, 0x31, // adds r1, #4 /* Increment r1 */ - 0x01, 0x3a, // subs r2, #1 /* Decrement r2 */ - //test_done: - 0x00, 0x2a, // cmp r2, #0 /* Compare r2 to 0 */ - 0xf8, 0xd8, // bhi write_word /* Loop if above 0 */ - 0x00, 0xbe // bkpt #0x00 /* Set breakpoint to exit */ + // flashloaders/stm32lx.s + + 0x04, 0xe0, // b test_done ; Go to compare + // write_word: + 0x04, 0x68, // ldr r4, [r0] ; Load one word from address in r0 + 0x0c, 0x60, // str r4, [r1] ; Store the word to address in r1 + 0x04, 0x30, // adds r0, #4 ; Increment r0 + 0x04, 0x31, // adds r1, #4 ; Increment r1 + 0x01, 0x3a, // subs r2, #1 ; Decrement r2 + // test_done: + 0x00, 0x2a, // cmp r2, #0 ; Compare r2 to 0 + 0xf8, 0xd8, // bhi write_word ; Loop if above 0 + 0x00, 0xbe, // bkpt #0x00 ; Set breakpoint to exit + 0x00, 0x00 }; static const uint8_t loader_code_stm32f4[] = { From 742eba2cd64fdac65275213d2b2773f8a82b5164 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Wed, 11 May 2016 07:33:41 +0200 Subject: [PATCH 0416/1435] Reorganize stlink-gui and update README, add building gui with Travis CI on linux --- .travis.sh | 8 ++++++-- CMakeLists.txt | 6 +++--- Makefile.am | 2 +- README | 3 ++- configure.ac | 16 ++++++++-------- {gui => src/tools/gui}/Makefile.am | 6 +++--- {gui => src/tools/gui}/stlink-gui.c | 2 +- {gui => src/tools/gui}/stlink-gui.h | 0 {gui => src/tools/gui}/stlink-gui.ui | 0 9 files changed, 24 insertions(+), 19 deletions(-) rename {gui => src/tools/gui}/Makefile.am (89%) rename {gui => src/tools/gui}/stlink-gui.c (99%) rename {gui => src/tools/gui}/stlink-gui.h (100%) rename {gui => src/tools/gui}/stlink-gui.ui (100%) diff --git a/.travis.sh b/.travis.sh index 6b69c638a..13d2c1dcd 100755 --- a/.travis.sh +++ b/.travis.sh @@ -1,7 +1,7 @@ #!/bin/bash if [ "$TRAVIS_OS_NAME" != "osx" ]; then sudo apt-get update -qq || true - sudo apt-get install -qq -y --no-install-recommends libusb-1.0.0-dev + sudo apt-get install -qq -y --no-install-recommends libusb-1.0.0-dev libgtk-3-dev else brew install libusb fi @@ -13,6 +13,10 @@ if [ "$BUILD_SYSTEM" == "cmake" ]; then make else ./autogen.sh - ./configure + if [ "$TRAVIS_OS_NAME" == "osx" ]; then + ./configure + else + ./configure --with-gtk-gui + fi make fi diff --git a/CMakeLists.txt b/CMakeLists.txt index f75ce611d..1c56ed49d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,8 +97,8 @@ endif() if(gtk_FOUND) include_directories(${gtk_INCLUDE_DIRS}) - set(GUI_SOURCES gui/stlink-gui.c - gui/stlink-gui.h) + set(GUI_SOURCES src/tools/gui/stlink-gui.c + src/tools/gui/stlink-gui.h) add_executable(stlink-gui-local ${GUI_SOURCES}) set_target_properties(stlink-gui-local PROPERTIES @@ -113,6 +113,6 @@ if(gtk_FOUND) install(TARGETS stlink-gui RUNTIME DESTINATION bin) - install(FILES gui/stlink-gui.ui + install(FILES src/tools/gui/stlink-gui.ui DESTINATION ${INSTALLED_UI_DIR}) endif() diff --git a/Makefile.am b/Makefile.am index fc95184bc..7494913ac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ # Makefile.am -- Process this file with automake to produce Makefile.in -SUBDIRS = . $(MAYBE_GUI) +SUBDIRS = . $(STLINK_HAS_GUI) AUTOMAKE_OPTIONS = subdir-objects diff --git a/README b/README index 90bc0849d..89bb188c9 100644 --- a/README +++ b/README @@ -21,6 +21,7 @@ Two different transport layers are used: * `pkg-config` * `libusb-1.0` (plus development headers for building, on debian based distros `libusb-1.0.0-dev` package) +* (optional) for `stlink-gui` we need libgtk-3-dev ## For STLINKv1 @@ -48,7 +49,7 @@ following steps will build the project for you. ``` $ ./autogen.sh -$ ./configure +$ ./configure --with-gtk-gui $ make ``` diff --git a/configure.ac b/configure.ac index f37471740..7a101d55d 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([stlink],[0.5.6],[davem@devkitpro.org]) +AC_INIT([stlink],[1.2.0],[davem@devkitpro.org]) AC_CONFIG_SRCDIR([src/common.c]) AC_CONFIG_LIBOBJ_DIR([src]) AM_INIT_AUTOMAKE([1.10]) @@ -44,15 +44,15 @@ case "${host}" in AM_CONDITIONAL(MINGW, false) esac -MAYBE_GUI= -AC_ARG_WITH([gtk], AS_HELP_STRING([--with-gtk], [enable GTK+ gui])) -if test "x$with_gtk" = "xyes"; then - PKG_CHECK_MODULES([GTK], [gtk+-3.0]) +STLINK_HAS_GUI= +AC_ARG_WITH([gtk_gui], AS_HELP_STRING([--with-gtk-gui], [enable GTK3+ gui])) +if test "x$with_gtk_gui" = "xyes"; then + PKG_CHECK_MODULES([GTK3], [gtk+-3.0]) PKG_CHECK_MODULES([GLIB], [glib-2.0 > 2.32.0]) - MAYBE_GUI=gui - AC_CONFIG_FILES([gui/Makefile]) + STLINK_HAS_GUI=src/tools/gui + AC_CONFIG_FILES([src/tools/gui/Makefile]) fi -AC_SUBST([MAYBE_GUI]) +AC_SUBST([STLINK_HAS_GUI]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/gui/Makefile.am b/src/tools/gui/Makefile.am similarity index 89% rename from gui/Makefile.am rename to src/tools/gui/Makefile.am index 97b780e43..23e582fa8 100644 --- a/gui/Makefile.am +++ b/src/tools/gui/Makefile.am @@ -5,10 +5,10 @@ stlink_gui_SOURCES = \ stlink-gui.h stlink_gui_CPPFLAGS = \ - -I$(top_srcdir) \ + -I$(top_srcdir)/include \ $(AM_CPPFLAGS) \ -I$(top_srcdir)/src \ - @GTK_CFLAGS@ + @GTK3_CFLAGS@ stlink_gui_CFLAGS = \ $(WARN_CFLAGS) \ @@ -21,7 +21,7 @@ stlink_gui_LDFLAGS = \ stlink_gui_LDADD = \ $(INTLLIBS) \ $(top_builddir)/libstlink.a \ - @GTK_LIBS@ + @GTK3_LIBS@ uidir = $(pkgdatadir)/ui ui_DATA = stlink-gui.ui diff --git a/gui/stlink-gui.c b/src/tools/gui/stlink-gui.c similarity index 99% rename from gui/stlink-gui.c rename to src/tools/gui/stlink-gui.c index 93f92c462..944ad131b 100644 --- a/gui/stlink-gui.c +++ b/src/tools/gui/stlink-gui.c @@ -3,7 +3,7 @@ #include #include -#include "stlink-common.h" +#include #include "stlink-gui.h" #define MEM_READ_SIZE 1024 diff --git a/gui/stlink-gui.h b/src/tools/gui/stlink-gui.h similarity index 100% rename from gui/stlink-gui.h rename to src/tools/gui/stlink-gui.h diff --git a/gui/stlink-gui.ui b/src/tools/gui/stlink-gui.ui similarity index 100% rename from gui/stlink-gui.ui rename to src/tools/gui/stlink-gui.ui From 188496ce3d7eaa97d63f5c64c51966521ed3b453 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Wed, 11 May 2016 18:54:41 +0200 Subject: [PATCH 0417/1435] README.md: Document build dependencies, fixes #362 --- README | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README b/README index 89bb188c9..f6ac729bc 100644 --- a/README +++ b/README @@ -19,7 +19,12 @@ Two different transport layers are used: ## Common requirements +* Debian based distros (debian, ubuntu) + * `build-essential` + * `pkg-config` +* `intltool` +* `cmake` or (`autoconf` && `automake && `autogen`) * `libusb-1.0` (plus development headers for building, on debian based distros `libusb-1.0.0-dev` package) * (optional) for `stlink-gui` we need libgtk-3-dev From c1cbc158b5dcc0eb59a99dcab9bc0535d2698925 Mon Sep 17 00:00:00 2001 From: texane Date: Wed, 11 May 2016 18:56:26 +0200 Subject: [PATCH 0418/1435] Fixing NULL to char assignment --- src/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/usb.c b/src/usb.c index e8d8ec39d..9c04ec860 100644 --- a/src/usb.c +++ b/src/usb.c @@ -946,7 +946,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial)); if (ret < 0) - *serial = NULL; + *serial = 0; libusb_close(handle); From e83e1197af03cec838d377303eaf7dddf9e93c21 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 13 May 2016 12:16:16 +0200 Subject: [PATCH 0419/1435] Update ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 861711912..932e9387f 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,3 +1,5 @@ +**NOTICE: The issue may be closed without notice when not enough information is provided!** + Thank you for giving feedback to the stlink project. Take some time to fill out check boxes with a X in the following items so developers and other people can try to to find out what is going on. And add/remove what is appropiate to your problem. @@ -8,9 +10,19 @@ When submitting a feature request, try to reuse the list and add/remove what is - [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 - [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) - [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 -- [ ] Target chip: e.g STM32F402VG +- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` +- [ ] Target chip (and optional board): e.g STM32F402VG (STM32Fxxx Discovery) A as-detailed description possible of the problem with debug output when available. +Output: + +``` +OUTPUT/ERROR of the commandline tool(s) +``` + +Expected/description: +`short description of the expected value` + Thank you, The stlink project maintainers From 72b8e5ec87e4fa386a8e94fe68df29467d4354ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81ron=20RADICS?= Date: Mon, 16 May 2016 03:52:46 +0200 Subject: [PATCH 0420/1435] Add L0 Category 2 device (chip id: 0x425) --- include/stlink.h | 13 +++++++++++++ src/common.c | 8 ++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index c29e2a663..1ccbb8416 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -138,6 +138,7 @@ extern "C" { #define STM32_CHIPID_F303_HIGH 0x446 #define STM32_CHIPID_L0_CAT5 0x447 +#define STM32_CHIPID_L0_CAT2 0x425 #define STM32_CHIPID_F0_CAN 0x448 @@ -517,6 +518,18 @@ extern "C" { .bootrom_base = 0x1ff0000, .bootrom_size = 0x2000 }, + { + // STM32L0x Category 2 + // RM0367,RM0377 documents was used to find these parameters + .chip_id = STM32_CHIPID_L0_CAT2, + .description = "L0x Category 2 device", + .flash_type = FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x2000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x1000 + }, { // STM32F334 // RM0364 document was used to find these parameters diff --git a/src/common.c b/src/common.c index a3ffda7e4..24f9cd7fe 100644 --- a/src/common.c +++ b/src/common.c @@ -1288,7 +1288,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) uint32_t val; uint32_t flash_regs_base; - if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5) { + if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5 || sl->chip_id == STM32_CHIPID_L0_CAT2) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; } else { flash_regs_base = STM32L_FLASH_REGS_ADDR; @@ -1612,7 +1612,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE - || sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5) { /* stm32l */ + || sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5 || sl->chip_id == STM32_CHIPID_L0_CAT2) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID @@ -1720,7 +1720,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uin uint32_t flash_regs_base; flash_loader_t fl; - if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5) { + if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5 || sl->chip_id == STM32_CHIPID_L0_CAT2) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; } else { flash_regs_base = STM32L_FLASH_REGS_ADDR; @@ -1887,7 +1887,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t uint32_t flash_regs_base; uint32_t pagesize; - if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5) { + if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5 || sl->chip_id == STM32_CHIPID_L0_CAT2) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; pagesize = L0_WRITE_BLOCK_SIZE; } else { From de1f05ce8150ae9cee92a9ddbf471b718ea81095 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Mon, 16 May 2016 10:21:04 +0200 Subject: [PATCH 0421/1435] Move chipid defines and deduplicate chipid params code --- CMakeLists.txt | 30 +-- Makefile.am | 2 + include/stlink.h | 465 +------------------------------------ include/stlink/chipid.h | 77 ++++++ src/chipid.c | 402 ++++++++++++++++++++++++++++++++ src/common.c | 68 +++--- src/gdbserver/gdb-server.c | 24 +- src/tools/flash.c | 2 +- src/tools/gui/stlink-gui.c | 14 +- src/tools/info.c | 25 +- 10 files changed, 560 insertions(+), 549 deletions(-) create mode 100644 include/stlink/chipid.h create mode 100644 src/chipid.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c56ed49d..89bd85968 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,24 +40,28 @@ add_cflag_if_supported("-Wundef") add_cflag_if_supported("-fPIC") if(${CMAKE_BUILD_TYPE} MATCHES "Debug") - include(CTest) - add_cflag_if_supported("-ggdb") - add_cflag_if_supported("-O0") + include(CTest) + add_cflag_if_supported("-ggdb") + add_cflag_if_supported("-O0") elseif() - add_cflag_if_supported("-O2") + add_cflag_if_supported("-O2") endif() -set(STLINK_HEADERS include/stlink.h - include/stlink/usb.h - include/stlink/sg.h - include/stlink/logging.h - include/stlink/mmap.h +set(STLINK_HEADERS + include/stlink.h + include/stlink/usb.h + include/stlink/sg.h + include/stlink/logging.h + include/stlink/mmap.h + include/stlink/chipid.h ) -set(STLINK_SOURCE src/common.c - src/usb.c - src/sg.c - src/logging.c +set(STLINK_SOURCE + src/chipid.c + src/common.c + src/usb.c + src/sg.c + src/logging.c ) include_directories(${LIBUSB_INCLUDE_DIR}) diff --git a/Makefile.am b/Makefile.am index 7494913ac..a3114c6e4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,6 +18,7 @@ st_info_SOURCES = src/tools/info.c st_util_SOURCES = src/gdbserver/gdb-remote.c src/gdbserver/gdb-remote.h src/gdbserver/gdb-server.c src/mingw/mingw.c src/mingw/mingw.h CFILES = \ + src/chipid.c \ src/common.c \ src/usb.c \ src/sg.c \ @@ -29,6 +30,7 @@ endif HFILES = \ include/stlink.h \ + include/stlink/chipid.h \ include/stlink/usb.h \ include/stlink/sg.h \ include/stlink/logging.h \ diff --git a/include/stlink.h b/include/stlink.h index 1ccbb8416..3941f4216 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -8,10 +8,14 @@ #define STLINK_H #include +#include #ifdef __cplusplus extern "C" { #endif + +#define STLINK_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + // Max data transfer size. // 6kB = max mem32_read block, 8kB sram //#define Q_BUF_LEN 96 @@ -90,67 +94,6 @@ extern "C" { #define CORE_M3_R2 0x4BA00477 #define CORE_M4_R0 0x2BA01477 - /* - * Chip IDs are explained in the appropriate programming manual for the - * DBGMCU_IDCODE register (0xE0042000) - */ - // stm32 chipids, only lower 12 bits.. -#define STM32_CHIPID_F1_MEDIUM 0x410 -#define STM32_CHIPID_F2 0x411 -#define STM32_CHIPID_F1_LOW 0x412 -#define STM32_CHIPID_F4 0x413 -#define STM32_CHIPID_F1_HIGH 0x414 -#define STM32_CHIPID_L4 0x415 /* Seen on L4x6 (RM0351) */ -#define STM32_CHIPID_L1_MEDIUM 0x416 -#define STM32_CHIPID_L0 0x417 -#define STM32_CHIPID_F1_CONN 0x418 -#define STM32_CHIPID_F4_HD 0x419 -#define STM32_CHIPID_F1_VL_MEDIUM_LOW 0x420 - -#define STM32_CHIPID_F446 0x421 -#define STM32_CHIPID_F3 0x422 -#define STM32_CHIPID_F4_LP 0x423 - -#define STM32_CHIPID_F411RE 0x431 - -#define STM32_CHIPID_L1_MEDIUM_PLUS 0x427 -#define STM32_CHIPID_F1_VL_HIGH 0x428 -#define STM32_CHIPID_L1_CAT2 0x429 - -#define STM32_CHIPID_F1_XL 0x430 - -#define STM32_CHIPID_F37x 0x432 -#define STM32_CHIPID_F4_DE 0x433 -#define STM32_CHIPID_F4_DE 0x433 - -#define STM32_CHIPID_F4_DSI 0x434 - -#define STM32_CHIPID_L1_HIGH 0x436 -#define STM32_CHIPID_L152_RE 0x437 -#define STM32_CHIPID_F334 0x438 - -#define STM32_CHIPID_F3_SMALL 0x439 -#define STM32_CHIPID_F0 0x440 -#define STM32_CHIPID_F09X 0x442 -#define STM32_CHIPID_F0_SMALL 0x444 - -#define STM32_CHIPID_F04 0x445 - -#define STM32_CHIPID_F303_HIGH 0x446 -#define STM32_CHIPID_L0_CAT5 0x447 -#define STM32_CHIPID_L0_CAT2 0x425 - -#define STM32_CHIPID_F0_CAN 0x448 - -#define STM32_CHIPID_F7 0x449 - - /* - * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" - * and some that are called "High". 0x427 is assigned to the other "Medium- - * plus" chips. To make it a bit simpler we just call 427 MEDIUM_PLUS and - * 0x436 HIGH. - */ - // Constant STM32 memory map figures #define STM32_FLASH_BASE 0x08000000 #define STM32_SRAM_BASE 0x20000000 @@ -173,405 +116,7 @@ extern "C" { FLASH_TYPE_L4, }; - typedef struct chip_params_ { - uint32_t chip_id; - char* description; - enum flash_type flash_type; - uint32_t flash_size_reg; - uint32_t flash_pagesize; - 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[] = { - { - //RM0385 and DS10916 document was used to find these paramaters - .chip_id = STM32_CHIPID_F7, - .description = "F7 device", - .flash_type = FLASH_TYPE_F4, - .flash_size_reg = 0x1ff0f442, // section 41.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 - .bootrom_size = 0xEDC0 // "System memory" byte size in hex from DS Fig 18 - }, - { // table 2, PM0063 - .chip_id = STM32_CHIPID_F1_MEDIUM, - .description = "F1 Medium-density device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x5000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { // table 1, PM0059 - .chip_id = STM32_CHIPID_F2, - .description = "F2 device", - .flash_type = FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, /* As in RM0033 Rev 5*/ - .flash_pagesize = 0x20000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { // PM0063 - .chip_id = STM32_CHIPID_F1_LOW, - .description = "F1 Low-density device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2800, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - .chip_id = STM32_CHIPID_F4, - .description = "F4 device", - .flash_type = FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ - .flash_pagesize = 0x4000, - .sram_size = 0x30000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - .chip_id = STM32_CHIPID_F4_DSI, - .description = "F46x and F47x device", - .flash_type = FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ - .flash_pagesize = 0x4000, - .sram_size = 0x40000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - .chip_id = STM32_CHIPID_F4_HD, - .description = "F42x and F43x device", - .flash_type = FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ - .flash_pagesize = 0x4000, - .sram_size = 0x40000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - .chip_id = STM32_CHIPID_F4_LP, - .description = "F4 device (low power)", - .flash_type = FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x10000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - .chip_id = STM32_CHIPID_F411RE, - .description = "F4 device (low power) - stm32f411re", - .flash_type = FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - .chip_id = STM32_CHIPID_F4_DE, - .description = "F4 device (Dynamic Efficency)", - .flash_type = FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - .chip_id = STM32_CHIPID_F1_HIGH, - .description = "F1 High-density device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - // This ignores the EEPROM! (and uses the page erase size, - // not the sector write protection...) - .chip_id = STM32_CHIPID_L1_MEDIUM, - .description = "L1 Med-density device", - .flash_type = FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8004c, - .flash_pagesize = 0x100, - .sram_size = 0x4000, - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 - }, - { - .chip_id = STM32_CHIPID_L1_CAT2, - .description = "L1 Cat.2 device", - .flash_type = FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8004c, - .flash_pagesize = 0x100, - .sram_size = 0x8000, - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 - }, - { - .chip_id = STM32_CHIPID_L1_MEDIUM_PLUS, - .description = "L1 Medium-Plus-density device", - .flash_type = FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x8000,/*Not completely clear if there are some with 48K*/ - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 - }, - { - .chip_id = STM32_CHIPID_L1_HIGH, - .description = "L1 High-density device", - .flash_type = FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0xC000, /*Not completely clear if there are some with 32K*/ - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 - }, - { - .chip_id = STM32_CHIPID_L152_RE, - .description = "L152RE", - .flash_type = FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x14000, /*Not completely clear if there are some with 32K*/ - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 - }, - { - .chip_id = STM32_CHIPID_F1_CONN, - .description = "F1 Connectivity line device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1fffb000, - .bootrom_size = 0x4800 - }, - {//Low and Medium density VL have same chipid. RM0041 25.6.1 - .chip_id = STM32_CHIPID_F1_VL_MEDIUM_LOW, - .description = "F1 Medium/Low-density Value Line device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2000,//0x1000 for low density devices - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - // STM32F446x family. Support based on DM00135183.pdf (RM0390) document. - .chip_id = STM32_CHIPID_F446, - .description = "F446 device", - .flash_type = FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, - .flash_pagesize = 0x20000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - // This is STK32F303VCT6 device from STM32 F3 Discovery board. - // Support based on DM00043574.pdf (RM0316) document. - .chip_id = STM32_CHIPID_F3, - .description = "F3 device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - // This is STK32F373VCT6 device from STM32 F373 eval board - // Support based on 303 above (37x and 30x have same memory map) - .chip_id = STM32_CHIPID_F37x, - .description = "F3 device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - .chip_id = STM32_CHIPID_F1_VL_HIGH, - .description = "F1 High-density value line device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x8000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - .chip_id = STM32_CHIPID_F1_XL, - .description = "F1 XL-density device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x18000, - .bootrom_base = 0x1fffe000, - .bootrom_size = 0x1800 - }, - { - //Use this as an example for mapping future chips: - //RM0091 document was used to find these paramaters - .chip_id = STM32_CHIPID_F0_CAN, - .description = "F07x device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 - .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 - .bootrom_size = 0x3000 // "System memory" byte size in hex from Table 2 - }, - { - //Use this as an example for mapping future chips: - //RM0091 document was used to find these paramaters - .chip_id = STM32_CHIPID_F0, - .description = "F0 device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 - }, - { - .chip_id = STM32_CHIPID_F09X, - .description = "F09X device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) - .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) - .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 - .bootrom_size = 0x2000 // "System memory" byte size in hex from Table 2 - }, - { - //Use this as an example for mapping future chips: - //RM0091 document was used to find these paramaters - .chip_id = STM32_CHIPID_F04, - .description = "F04x device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 - }, - { - //Use this as an example for mapping future chips: - //RM0091 document was used to find these paramaters - .chip_id = STM32_CHIPID_F0_SMALL, - .description = "F0 small device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 - }, - { - // STM32F30x - .chip_id = STM32_CHIPID_F3_SMALL, - .description = "F3 small device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1fffd800, - .bootrom_size = 0x2000 - }, - { - // STM32L0x - // RM0367,RM0377 documents was used to find these parameters - .chip_id = STM32_CHIPID_L0, - .description = "L0x3 device", - .flash_type = FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000 - }, - { - // STM32L0x Category 5 - // RM0367,RM0377 documents was used to find these parameters - .chip_id = STM32_CHIPID_L0_CAT5, - .description = "L0x Category 5 device", - .flash_type = FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x5000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x2000 - }, - { - // STM32L0x Category 2 - // RM0367,RM0377 documents was used to find these parameters - .chip_id = STM32_CHIPID_L0_CAT2, - .description = "L0x Category 2 device", - .flash_type = FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000 - }, - { - // STM32F334 - // RM0364 document was used to find these parameters - .chip_id = STM32_CHIPID_F334, - .description = "F334 device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0x3000, - .bootrom_base = 0x1fffd800, - .bootrom_size = 0x2000 - }, - { - // This is STK32F303RET6 device from STM32 F3 Nucelo board. - // Support based on DM00043574.pdf (RM0316) document rev 5. - .chip_id = STM32_CHIPID_F303_HIGH, - .description = "F303 high density device", - .flash_type = FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register - .flash_pagesize = 0x800, // 4.2.1 Flash memory organization - .sram_size = 0x10000, // 3.3 Embedded SRAM - .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory - .bootrom_size = 0x2000 - }, - { - // STM32L4x6 - // From RM0351. - .chip_id = STM32_CHIPID_L4, - .description = "L4 device", - .flash_type = FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1671) - .flash_pagesize = 0x800, // 2K (sec 3.2, page 78; also appears in sec 3.3.1 and tables 4-6 on pages 79-81) - // SRAM1 is "up to" 96k in the standard Cortex-M memory map; - // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) - .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000 // 28k (per bank), same source as base - }, - - }; - +#include "stlink/chipid.h" typedef struct { uint32_t r[16]; diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h new file mode 100644 index 000000000..48215088f --- /dev/null +++ b/include/stlink/chipid.h @@ -0,0 +1,77 @@ +#ifndef STLINK_CHIPID_H_ +#define STLINK_CHIPID_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Chip IDs are explained in the appropriate programming manual for the + * DBGMCU_IDCODE register (0xE0042000) + * stm32 chipids, only lower 12 bits.. + */ +enum stlink_stm32_chipids { + STLINK_CHIPID_STM32_F1_MEDIUM = 0x410, + STLINK_CHIPID_STM32_F2 = 0x411, + STLINK_CHIPID_STM32_F1_LOW = 0x412, + STLINK_CHIPID_STM32_F4 = 0x413, + STLINK_CHIPID_STM32_F1_HIGH = 0x414, + STLINK_CHIPID_STM32_L4 = 0x415, + STLINK_CHIPID_STM32_L1_MEDIUM = 0x416, + STLINK_CHIPID_STM32_L0 = 0x417, + STLINK_CHIPID_STM32_F1_CONN = 0x418, + STLINK_CHIPID_STM32_F4_HD = 0x419, + STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW = 0x420, + STLINK_CHIPID_STM32_F446 = 0x421, + STLINK_CHIPID_STM32_F3 = 0x422, + STLINK_CHIPID_STM32_F4_LP = 0x423, + STLINK_CHIPID_STM32_L0_CAT2 = 0x425, + STLINK_CHIPID_STM32_L1_MEDIUM_PLUS = 0x427, + STLINK_CHIPID_STM32_F1_VL_HIGH = 0x428, + STLINK_CHIPID_STM32_L1_CAT2 = 0x429, + STLINK_CHIPID_STM32_F1_XL = 0x430, + STLINK_CHIPID_STM32_F411RE = 0x431, + STLINK_CHIPID_STM32_F37x = 0x432, + STLINK_CHIPID_STM32_F4_DE = 0x433, + STLINK_CHIPID_STM32_F4_DSI = 0x434, + /* + * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" + * and some that are called "High". 0x427 is assigned to the other "Medium- + * plus" chips. To make it a bit simpler we just call 427 MEDIUM_PLUS and + * 0x436 HIGH. + */ + STLINK_CHIPID_STM32_L1_HIGH = 0x436, + STLINK_CHIPID_STM32_L152_RE = 0x437, + STLINK_CHIPID_STM32_F334 = 0x438, + STLINK_CHIPID_STM32_F3_SMALL = 0x439, + STLINK_CHIPID_STM32_F0 = 0x440, + STLINK_CHIPID_STM32_F09X = 0x442, + STLINK_CHIPID_STM32_F0_SMALL = 0x444, + STLINK_CHIPID_STM32_F04 = 0x445, + STLINK_CHIPID_STM32_F303_HIGH = 0x446, + STLINK_CHIPID_STM32_L0_CAT5 = 0x447, + STLINK_CHIPID_STM32_F0_CAN = 0x448, + STLINK_CHIPID_STM32_F7 = 0x449 +}; + +/** + * Chipid parameters + */ +struct stlink_chipid_params { + uint32_t chip_id; + char *description; + enum flash_type flash_type; + uint32_t flash_size_reg; + uint32_t flash_pagesize; + uint32_t sram_size; + uint32_t bootrom_base; + uint32_t bootrom_size; +}; + +const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); + +#ifdef __cplusplus +} +#endif + +#endif /* STLINK_CHIPID_H_ */ diff --git a/src/chipid.c b/src/chipid.c new file mode 100644 index 000000000..92daeb28a --- /dev/null +++ b/src/chipid.c @@ -0,0 +1,402 @@ +#include "stlink.h" +#include "stlink/chipid.h" + +static const struct stlink_chipid_params devices[] = { + { + //RM0385 and DS10916 document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_F7, + .description = "F7 device", + .flash_type = FLASH_TYPE_F4, + .flash_size_reg = 0x1ff0f442, // section 41.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 + .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 + .bootrom_size = 0xEDC0 // "System memory" byte size in hex from DS Fig 18 + }, + { // table 2, PM0063 + .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, + .description = "F1 Medium-density device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x5000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { // table 1, PM0059 + .chip_id = STLINK_CHIPID_STM32_F2, + .description = "F2 device", + .flash_type = FLASH_TYPE_F4, + .flash_size_reg = 0x1fff7a22, /* As in RM0033 Rev 5*/ + .flash_pagesize = 0x20000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { // PM0063 + .chip_id = STLINK_CHIPID_STM32_F1_LOW, + .description = "F1 Low-density device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2800, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F4, + .description = "F4 device", + .flash_type = FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ + .flash_pagesize = 0x4000, + .sram_size = 0x30000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F4_DSI, + .description = "F46x and F47x device", + .flash_type = FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ + .flash_pagesize = 0x4000, + .sram_size = 0x40000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F4_HD, + .description = "F42x and F43x device", + .flash_type = FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ + .flash_pagesize = 0x4000, + .sram_size = 0x40000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F4_LP, + .description = "F4 device (low power)", + .flash_type = FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x10000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F411RE, + .description = "F4 device (low power) - stm32f411re", + .flash_type = FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F4_DE, + .description = "F4 device (Dynamic Efficency)", + .flash_type = FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x18000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F1_HIGH, + .description = "F1 High-density device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + // This ignores the EEPROM! (and uses the page erase size, + // not the sector write protection...) + .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM, + .description = "L1 Med-density device", + .flash_type = FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8004c, + .flash_pagesize = 0x100, + .sram_size = 0x4000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, + { + .chip_id = STLINK_CHIPID_STM32_L1_CAT2, + .description = "L1 Cat.2 device", + .flash_type = FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8004c, + .flash_pagesize = 0x100, + .sram_size = 0x8000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, + { + .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM_PLUS, + .description = "L1 Medium-Plus-density device", + .flash_type = FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0x8000,/*Not completely clear if there are some with 48K*/ + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, + { + .chip_id = STLINK_CHIPID_STM32_L1_HIGH, + .description = "L1 High-density device", + .flash_type = FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0xC000, /*Not completely clear if there are some with 32K*/ + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, + { + .chip_id = STLINK_CHIPID_STM32_L152_RE, + .description = "L152RE", + .flash_type = FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0x14000, /*Not completely clear if there are some with 32K*/ + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, + { + .chip_id = STLINK_CHIPID_STM32_F1_CONN, + .description = "F1 Connectivity line device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1fffb000, + .bootrom_size = 0x4800 + }, + {//Low and Medium density VL have same chipid. RM0041 25.6.1 + .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, + .description = "F1 Medium/Low-density Value Line device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2000,//0x1000 for low density devices + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + // STM32F446x family. Support based on DM00135183.pdf (RM0390) document. + .chip_id = STLINK_CHIPID_STM32_F446, + .description = "F446 device", + .flash_type = FLASH_TYPE_F4, + .flash_size_reg = 0x1fff7a22, + .flash_pagesize = 0x20000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + // This is STK32F303VCT6 device from STM32 F3 Discovery board. + // Support based on DM00043574.pdf (RM0316) document. + .chip_id = STLINK_CHIPID_STM32_F3, + .description = "F3 device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + // This is STK32F373VCT6 device from STM32 F373 eval board + // Support based on 303 above (37x and 30x have same memory map) + .chip_id = STLINK_CHIPID_STM32_F37x, + .description = "F3 device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F1_VL_HIGH, + .description = "F1 High-density value line device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x8000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F1_XL, + .description = "F1 XL-density device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x18000, + .bootrom_base = 0x1fffe000, + .bootrom_size = 0x1800 + }, + { + //Use this as an example for mapping future chips: + //RM0091 document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_F0_CAN, + .description = "F07x device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 + .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 + .bootrom_size = 0x3000 // "System memory" byte size in hex from Table 2 + }, + { + //Use this as an example for mapping future chips: + //RM0091 document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_F0, + .description = "F0 device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + }, + { + .chip_id = STLINK_CHIPID_STM32_F09X, + .description = "F09X device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) + .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) + .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 + .bootrom_size = 0x2000 // "System memory" byte size in hex from Table 2 + }, + { + //Use this as an example for mapping future chips: + //RM0091 document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_F04, + .description = "F04x device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + }, + { + //Use this as an example for mapping future chips: + //RM0091 document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_F0_SMALL, + .description = "F0 small device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + }, + { + // STM32F30x + .chip_id = STLINK_CHIPID_STM32_F3_SMALL, + .description = "F3 small device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1fffd800, + .bootrom_size = 0x2000 + }, + { + // STM32L0x + // RM0367,RM0377 documents was used to find these parameters + .chip_id = STLINK_CHIPID_STM32_L0, + .description = "L0x3 device", + .flash_type = FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x2000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x1000 + }, + { + // STM32L0x Category 5 + // RM0367,RM0377 documents was used to find these parameters + .chip_id = STLINK_CHIPID_STM32_L0_CAT5, + .description = "L0x Category 5 device", + .flash_type = FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x5000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x2000 + }, + { + // STM32L0x Category 2 + // RM0367,RM0377 documents was used to find these parameters + .chip_id = STLINK_CHIPID_STM32_L0_CAT2, + .description = "L0x Category 2 device", + .flash_type = FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x2000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x1000 + }, + { + // STM32F334 + // RM0364 document was used to find these parameters + .chip_id = STLINK_CHIPID_STM32_F334, + .description = "F334 device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0x3000, + .bootrom_base = 0x1fffd800, + .bootrom_size = 0x2000 + }, + { + // This is STK32F303RET6 device from STM32 F3 Nucelo board. + // Support based on DM00043574.pdf (RM0316) document rev 5. + .chip_id = STLINK_CHIPID_STM32_F303_HIGH, + .description = "F303 high density device", + .flash_type = FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register + .flash_pagesize = 0x800, // 4.2.1 Flash memory organization + .sram_size = 0x10000, // 3.3 Embedded SRAM + .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory + .bootrom_size = 0x2000 + }, + { + // STM32L4x6 + // From RM0351. + .chip_id = STLINK_CHIPID_STM32_L4, + .description = "L4 device", + .flash_type = FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1671) + .flash_pagesize = 0x800, // 2K (sec 3.2, page 78; also appears in sec 3.3.1 and tables 4-6 on pages 79-81) + // SRAM1 is "up to" 96k in the standard Cortex-M memory map; + // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) + .sram_size = 0x18000, + .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000 // 28k (per bank), same source as base + }, + + }; + +const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) +{ + struct stlink_chipid_params *params = NULL; + + for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) { + if (devices[n].chip_id == chipid) { + params = &devices[n]; + break; + } + } + + return params; +} diff --git a/src/common.c b/src/common.c index 24f9cd7fe..e975c0ae7 100644 --- a/src/common.c +++ b/src/common.c @@ -567,7 +567,7 @@ int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { */ int stlink_load_device_params(stlink_t *sl) { ILOG("Loading device parameters....\n"); - const chip_params_t *params = NULL; + struct stlink_chipid_params *params = NULL; stlink_core_id(sl); uint32_t chip_id; uint32_t flash_size; @@ -582,12 +582,7 @@ int stlink_load_device_params(stlink_t *sl) { sl->chip_id = 0x413; } - for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { - if(devices[i].chip_id == sl->chip_id) { - params = &devices[i]; - break; - } - } + params = stlink_chipid_get_params(sl->chip_id); if (params == NULL) { WLOG("unknown chip id! %#x\n", chip_id); return -1; @@ -598,7 +593,6 @@ int stlink_load_device_params(stlink_t *sl) { return -1; } - // These are fixed... sl->flash_base = STM32_FLASH_BASE; sl->sram_base = STM32_SRAM_BASE; @@ -607,11 +601,11 @@ int stlink_load_device_params(stlink_t *sl) { flash_size = flash_size >>16; flash_size = flash_size & 0xffff; - if ((sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) && ( flash_size == 0 )) { + if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS) && ( flash_size == 0 )) { sl->flash_size = 128 * 1024; - } else if (sl->chip_id == STM32_CHIPID_L1_CAT2) { + } else if (sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2) { sl->flash_size = (flash_size & 0xff) * 1024; - } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_L1_HIGH) { + } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_HIGH) { // 0 is 384k and 1 is 256k if ( flash_size == 0 ) { sl->flash_size = 384 * 1024; @@ -629,7 +623,7 @@ int stlink_load_device_params(stlink_t *sl) { //medium and low devices have the same chipid. ram size depends on flash size. //STM32F100xx datasheet Doc ID 16455 Table 2 - if(sl->chip_id == STM32_CHIPID_F1_VL_MEDIUM_LOW && sl->flash_size < 64 * 1024){ + if(sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW && sl->flash_size < 64 * 1024){ sl->sram_size = 0x1000; } @@ -1210,9 +1204,9 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD) || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F4_DSI)) { + if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || (sl->chip_id == STLINK_CHIPID_STM32_F4) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || (sl->chip_id == STLINK_CHIPID_STM32_F411RE) || + (sl->chip_id == STLINK_CHIPID_STM32_F446) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI)) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector>= 12) { sector -= 12; @@ -1221,7 +1215,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ else if(sector<5) sl->flash_pgsz=0x10000; else sl->flash_pgsz=0x20000; } - else if (sl->chip_id == STM32_CHIPID_F7) { + else if (sl->chip_id == STLINK_CHIPID_STM32_F7) { uint32_t sector=calculate_F7_sectornum(flashaddr); if (sector<4) sl->flash_pgsz=0x8000; else if(sector<5) sl->flash_pgsz=0x20000; @@ -1246,14 +1240,14 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) unlock_flash_if(sl); /* select the page to erase */ - if (sl->chip_id == STM32_CHIPID_L4) { + if (sl->chip_id == STLINK_CHIPID_STM32_L4) { // calculate the actual bank+page from the address uint32_t page = calculate_L4_page(sl, flashaddr); fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", page, stlink_calculate_pagesize(sl, flashaddr)); write_flash_cr_bker_pnb(sl, page); - } else if (sl->chip_id == STM32_CHIPID_F7) { + } else if (sl->chip_id == STLINK_CHIPID_STM32_F7) { // calculate the actual page from the address uint32_t sector=calculate_F7_sectornum(flashaddr); @@ -1288,7 +1282,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) uint32_t val; uint32_t flash_regs_base; - if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5 || sl->chip_id == STM32_CHIPID_L0_CAT2) { + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; } else { flash_regs_base = STM32L_FLASH_REGS_ADDR; @@ -1609,23 +1603,23 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { const uint8_t* loader_code; size_t loader_size; - if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2 - || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH - || sl->chip_id == STM32_CHIPID_L152_RE - || sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5 || sl->chip_id == STM32_CHIPID_L0_CAT2) { /* stm32l */ + if (sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2 + || sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS || sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH + || sl->chip_id == STLINK_CHIPID_STM32_L152_RE + || sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID - || sl->chip_id == STM32_CHIPID_F3 - || sl->chip_id == STM32_CHIPID_F3_SMALL - || sl->chip_id == STM32_CHIPID_F303_HIGH - || sl->chip_id == STM32_CHIPID_F37x - || sl->chip_id == STM32_CHIPID_F334) { + || sl->chip_id == STLINK_CHIPID_STM32_F3 + || sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL + || sl->chip_id == STLINK_CHIPID_STM32_F303_HIGH + || sl->chip_id == STLINK_CHIPID_STM32_F37x + || sl->chip_id == STLINK_CHIPID_STM32_F334) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); - } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) || - sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) || - (sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_F4_DSI)){ + } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 || sl->chip_id == STLINK_CHIPID_STM32_F4 || (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || + sl->chip_id == STLINK_CHIPID_STM32_F4_LP || sl->chip_id == STLINK_CHIPID_STM32_F4_HD || (sl->chip_id == STLINK_CHIPID_STM32_F411RE) || + (sl->chip_id == STLINK_CHIPID_STM32_F446) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI)){ int voltage = stlink_target_voltage(sl); if (voltage == -1) { printf("Failed to read Target voltage\n"); @@ -1637,13 +1631,13 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { loader_code = loader_code_stm32f4_lv; loader_size = sizeof(loader_code_stm32f4_lv); } - } else if (sl->chip_id == STM32_CHIPID_F7){ + } else if (sl->chip_id == STLINK_CHIPID_STM32_F7){ loader_code = loader_code_stm32f7; loader_size = sizeof(loader_code_stm32f7); - } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F04 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL || sl->chip_id == STM32_CHIPID_F09X) { + } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || sl->chip_id == STLINK_CHIPID_STM32_F04 || sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || sl->chip_id == STLINK_CHIPID_STM32_F0_SMALL || sl->chip_id == STLINK_CHIPID_STM32_F09X) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); - } else if (sl->chip_id == STM32_CHIPID_L4) { + } else if (sl->chip_id == STLINK_CHIPID_STM32_L4) { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); } else { @@ -1720,7 +1714,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uin uint32_t flash_regs_base; flash_loader_t fl; - if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5 || sl->chip_id == STM32_CHIPID_L0_CAT2) { + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; } else { flash_regs_base = STM32L_FLASH_REGS_ADDR; @@ -1835,7 +1829,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t unlock_flash_if(sl); /* TODO: Check that Voltage range is 2.7 - 3.6 V */ - if (sl->chip_id != STM32_CHIPID_L4) { + if (sl->chip_id != STLINK_CHIPID_STM32_L4) { /* set parallelisim to 32 bit*/ int voltage = stlink_target_voltage(sl); if (voltage == -1) { @@ -1887,7 +1881,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t uint32_t flash_regs_base; uint32_t pagesize; - if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5 || sl->chip_id == STM32_CHIPID_L0_CAT2) { + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; pagesize = L0_WRITE_BLOCK_SIZE; } else { diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 666251c1b..b57a299ac 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -434,19 +434,19 @@ char* make_memory_map(stlink_t *sl) { char* map = malloc(4096); map[0] = '\0'; - if(sl->chip_id==STM32_CHIPID_F4 || sl->chip_id==STM32_CHIPID_F446) { + if(sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F446) { strcpy(map, memory_map_template_F4); - } else if(sl->chip_id==STM32_CHIPID_F4 || sl->chip_id==STM32_CHIPID_F7) { + } else if(sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F7) { strcpy(map, memory_map_template_F7); - } else if(sl->chip_id==STM32_CHIPID_F4_HD) { + } else if(sl->chip_id==STLINK_CHIPID_STM32_F4_HD) { strcpy(map, memory_map_template_F4_HD); - } else if(sl->chip_id==STM32_CHIPID_F2) { + } else if(sl->chip_id==STLINK_CHIPID_STM32_F2) { snprintf(map, 4096, memory_map_template_F2, sl->flash_size, sl->sram_size, sl->flash_size - 0x20000, sl->sys_base, sl->sys_size); - } else if(sl->chip_id==STM32_CHIPID_L4) { + } else if(sl->chip_id==STLINK_CHIPID_STM32_L4) { snprintf(map, 4096, memory_map_template_L4, sl->flash_size, sl->flash_size); } else { @@ -608,7 +608,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { return -1; } - if (sl->chip_id==STM32_CHIPID_F7) { + if (sl->chip_id==STLINK_CHIPID_STM32_F7) { fpb_addr = addr; } else { fpb_addr = addr & ~0x3; @@ -632,7 +632,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { brk->addr = fpb_addr; - if (sl->chip_id==STM32_CHIPID_F7) { + if (sl->chip_id==STLINK_CHIPID_STM32_F7) { if(set) brk->type = type; else brk->type = 0; @@ -842,7 +842,7 @@ static void init_cache (stlink_t *sl) { int i; /* Assume only F7 has a cache. */ - if(sl->chip_id!=STM32_CHIPID_F7) + if(sl->chip_id!=STLINK_CHIPID_STM32_F7) return; stlink_read_debug32(sl, CLIDR, &clidr); @@ -923,7 +923,7 @@ static void cache_sync(stlink_t *sl) { unsigned ccr; - if(sl->chip_id!=STM32_CHIPID_F7) + if(sl->chip_id!=STLINK_CHIPID_STM32_F7) return; if (!cache_modified) return; @@ -1024,9 +1024,9 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("query: %s;%s\n", queryName, params); if(!strcmp(queryName, "Supported")) { - if(sl->chip_id==STM32_CHIPID_F4 - || sl->chip_id==STM32_CHIPID_F4_HD - || sl->chip_id==STM32_CHIPID_F7) { + if(sl->chip_id==STLINK_CHIPID_STM32_F4 + || sl->chip_id==STLINK_CHIPID_STM32_F4_HD + || sl->chip_id==STLINK_CHIPID_STM32_F7) { reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); } else { diff --git a/src/tools/flash.c b/src/tools/flash.c index 770289ba3..7bebd82f9 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -218,7 +218,7 @@ int main(int ac, char** av) } // Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 - if (sl->chip_id == STM32_CHIPID_F4) + if (sl->chip_id == STLINK_CHIPID_STM32_F4) { memset(sl->q_buf,0,4); for (int i=0;i<8;i++) { diff --git a/src/tools/gui/stlink-gui.c b/src/tools/gui/stlink-gui.c index 944ad131b..fd1cdf937 100644 --- a/src/tools/gui/stlink-gui.c +++ b/src/tools/gui/stlink-gui.c @@ -446,14 +446,14 @@ filemem_jmp_cb (GtkWidget *widget, gpointer data) static gchar * dev_format_chip_id (guint32 chip_id) { + const struct stlink_chipid_params *params; gint i; - for (i = 0; i < sizeof (devices) / sizeof (devices[0]); i++) { - if (chip_id == devices[i].chip_id) { - return g_strdup (devices[i].description); - } - } - return g_strdup_printf ("0x%x", chip_id); + params = stlink_chipid_get_params(chip_id); + if (!params) + return g_strdup_printf ("0x%x", chip_id); + + return g_strdup (params->description); } static gchar * @@ -544,7 +544,7 @@ connect_button_cb (GtkWidget *widget, gpointer data) stlink_enter_swd_mode(gui->sl); /* Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 */ - if (gui->sl->chip_id == STM32_CHIPID_F4) { + if (gui->sl->chip_id == STLINK_CHIPID_STM32_F4) { memset(gui->sl->q_buf, 0, 4); for (i = 0; i < 8; i++) { stlink_write_mem32(gui->sl, 0x40026000 + 0x10 + 0x18 * i, 4); diff --git a/src/tools/info.c b/src/tools/info.c index e29184e5a..0d0b82393 100644 --- a/src/tools/info.c +++ b/src/tools/info.c @@ -39,7 +39,7 @@ static void stlink_print_serial(stlink_t *sl, bool openocd) static void stlink_print_info(stlink_t *sl) { - const chip_params_t *params = NULL; + const struct stlink_chipid_params *params = NULL; if (!sl) return; @@ -53,15 +53,9 @@ static void stlink_print_info(stlink_t *sl) printf(" sram: %zu\n", sl->sram_size); printf(" chipid: 0x%.4x\n", sl->chip_id); - for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { - if (devices[i].chip_id == sl->chip_id) { - params = &devices[i]; - break; - } - } - - if (params) - printf(" descr: %s\n", params->description); + params = stlink_chipid_get_params(sl->chip_id); + if (params) + printf(" descr: %s\n", params->description); } static void stlink_probe(void) @@ -126,16 +120,9 @@ static int print_data(char **av) else if (strcmp(av[1], "--hla-serial") == 0) stlink_print_serial(sl, true); else if (strcmp(av[1], "--descr") == 0) { - const chip_params_t *params = NULL; - for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { - if(devices[i].chip_id == sl->chip_id) { - params = &devices[i]; - break; - } - } - if (params == NULL) { + const struct stlink_chipid_params *params = stlink_chipid_get_params(sl->chip_id); + if (params == NULL) return -1; - } printf("%s\n", params->description); } From 0c07627c7806ceaa357552d96c9df3a2055c6c6f Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Mon, 16 May 2016 15:55:34 +0200 Subject: [PATCH 0422/1435] stlink_gui: Fix compiler warning on overflow --- src/tools/gui/stlink-gui.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/gui/stlink-gui.c b/src/tools/gui/stlink-gui.c index fd1cdf937..247373e9d 100644 --- a/src/tools/gui/stlink-gui.c +++ b/src/tools/gui/stlink-gui.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -183,14 +184,14 @@ hexstr_to_guint32 (const gchar *str, GError **err) g_quark_from_string ("hextou32"), 1, "Invalid hexstring"); - return LONG_MAX; + return UINT32_MAX; } if (end_ptr == str) { g_set_error (err, g_quark_from_string ("hextou32"), 2, "Invalid hexstring"); - return LONG_MAX; + return UINT32_MAX; } return val; } From 7b1a571549f74f4a9c70cbcf989cdb0b93c0153a Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Tue, 17 May 2016 20:00:06 +0200 Subject: [PATCH 0423/1435] Update README Add Contributing and versioning to README --- README | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README b/README index f6ac729bc..b7fbf12cd 100644 --- a/README +++ b/README @@ -24,7 +24,7 @@ Two different transport layers are used: * `pkg-config` * `intltool` -* `cmake` or (`autoconf` && `automake && `autogen`) +* `cmake` or (`autoconf` && `automake` && `autogen`) * `libusb-1.0` (plus development headers for building, on debian based distros `libusb-1.0.0-dev` package) * (optional) for `stlink-gui` we need libgtk-3-dev @@ -168,7 +168,6 @@ If you would link your executable to 0x08000000 and then do (gdb) load firmware.elf then it would be written to the memory. - ## FAQ Q: My breakpoints do not work at all or only work once. @@ -237,6 +236,12 @@ STLink v2-1 (as found on the Nucleo boards), known working targets: Please report any and all known working combinations so I can update this! +## Contributing and versioning + +* The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) +* When creating a pull request, please open first a issue for discussion of new features +* TODO: Enforcement of coding style (linux codestyle + checkpatch) + ## License The stlink library and tools are licensed under the [BSD license](LICENSE) From ad3978720e4b5df93ee25720afd20268405f9d22 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Tue, 17 May 2016 20:19:30 +0200 Subject: [PATCH 0424/1435] Update README Fix link to UweBonnes/wiki_fuer_alex --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index b7fbf12cd..8fc282bc5 100644 --- a/README +++ b/README @@ -210,7 +210,7 @@ STLink v2 (as found on the 32L and F4 Discovery boards), known working targets: * STM32F100xx (Medium Density VL, as on the 32VL Discovery board) * STM32L1xx (STM32L Discovery board) * STM32F103VC, STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on custom boards - (https://github.com/UweBonnes/wiki_fuer_alex/layout/usps...) + from [UweBonnes/wiki_fuer_alex](https://github.com/UweBonnes/wiki_fuer_alex/tree/master/layout) * STM32F103VET6 (HY-STM32 board) * STM32F105RCT6 (DecaWave EVB1000 board) * STM32F303xx (STM32F3 Discovery board) From 9c635e419deca697ff823000aad2e39d47ec8d6c Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 19 May 2016 09:01:14 +0200 Subject: [PATCH 0425/1435] chipid: Initial support for STM32F410 --- include/stlink/chipid.h | 3 ++- src/chipid.c | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 48215088f..351bb5537 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -51,7 +51,8 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F303_HIGH = 0x446, STLINK_CHIPID_STM32_L0_CAT5 = 0x447, STLINK_CHIPID_STM32_F0_CAN = 0x448, - STLINK_CHIPID_STM32_F7 = 0x449 + STLINK_CHIPID_STM32_F7 = 0x449, + STLINK_CHIPID_STM32_F410 = 0x458 }; /** diff --git a/src/chipid.c b/src/chipid.c index 92daeb28a..b4fd2d66a 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -196,6 +196,17 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 }, + { + // STM32F410 MCUs. Support based on DM00180366.pdf (RM0401) document. + .chip_id = STLINK_CHIPID_STM32_F410, + .description = "F410 device", + .flash_type = FLASH_TYPE_F4, + .flash_size_reg = 0x1fff7a22, + .flash_pagesize = 0x4000, + .sram_size = 0x8000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, { // This is STK32F303VCT6 device from STM32 F3 Discovery board. // Support based on DM00043574.pdf (RM0316) document. From d83d7f7392009fc30e8688b68d5c4a7a244105f6 Mon Sep 17 00:00:00 2001 From: Jean-Marie Lemetayer Date: Thu, 19 May 2016 11:03:35 +0200 Subject: [PATCH 0426/1435] Fix const warning --- src/chipid.c | 2 +- src/common.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chipid.c b/src/chipid.c index 92daeb28a..2c92d1efc 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -389,7 +389,7 @@ static const struct stlink_chipid_params devices[] = { const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { - struct stlink_chipid_params *params = NULL; + const struct stlink_chipid_params *params = NULL; for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) { if (devices[n].chip_id == chipid) { diff --git a/src/common.c b/src/common.c index e975c0ae7..e61bc53b7 100644 --- a/src/common.c +++ b/src/common.c @@ -567,7 +567,7 @@ int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { */ int stlink_load_device_params(stlink_t *sl) { ILOG("Loading device parameters....\n"); - struct stlink_chipid_params *params = NULL; + const struct stlink_chipid_params *params = NULL; stlink_core_id(sl); uint32_t chip_id; uint32_t flash_size; From 8da1467bb1e1f28f3e7cf830a48c8cc61090e0d2 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 20 May 2016 17:51:27 +0200 Subject: [PATCH 0427/1435] common.c: Add STLINK_CHIPID_STM32_F410 for correct flash loader selection --- src/common.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/common.c b/src/common.c index e61bc53b7..729c739da 100644 --- a/src/common.c +++ b/src/common.c @@ -1617,9 +1617,16 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { || sl->chip_id == STLINK_CHIPID_STM32_F334) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 || sl->chip_id == STLINK_CHIPID_STM32_F4 || (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || - sl->chip_id == STLINK_CHIPID_STM32_F4_LP || sl->chip_id == STLINK_CHIPID_STM32_F4_HD || (sl->chip_id == STLINK_CHIPID_STM32_F411RE) || - (sl->chip_id == STLINK_CHIPID_STM32_F446) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI)){ + } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 || + sl->chip_id == STLINK_CHIPID_STM32_F4 || + sl->chip_id == STLINK_CHIPID_STM32_F4_DE || + sl->chip_id == STLINK_CHIPID_STM32_F4_LP || + sl->chip_id == STLINK_CHIPID_STM32_F4_HD || + sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || + sl->chip_id == STLINK_CHIPID_STM32_F410 || + sl->chip_id == STLINK_CHIPID_STM32_F411RE || + sl->chip_id == STLINK_CHIPID_STM32_F446 + ) { int voltage = stlink_target_voltage(sl); if (voltage == -1) { printf("Failed to read Target voltage\n"); From 893fa4f8da4661c8984aacc4df61237849913f3b Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 20 May 2016 18:12:41 +0200 Subject: [PATCH 0428/1435] logging.h: Add helpers so the log macros can have just one argument, needed for compilation on visual studio --- include/stlink/logging.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/include/stlink/logging.h b/include/stlink/logging.h index df816caed..81e5f598c 100644 --- a/include/stlink/logging.h +++ b/include/stlink/logging.h @@ -20,11 +20,18 @@ enum ugly_loglevel { int ugly_init(int maximum_threshold); int ugly_log(int level, const char *tag, const char *format, ...); -#define DLOG(format, args...) ugly_log(UDEBUG, __FILE__, format, ## args) -#define ILOG(format, args...) ugly_log(UINFO, __FILE__, format, ## args) -#define WLOG(format, args...) ugly_log(UWARN, __FILE__, format, ## args) -#define ELOG(format, args...) ugly_log(UERROR, __FILE__, format, ## args) -#define fatal(format, args...) ugly_log(UFATAL, __FILE__, format, ## args) +/** @todo we need to write this in a more generic way, for now this should compile + on visual studio (See http://stackoverflow.com/a/8673872/1836746) */ +#define DLOG_HELPER(format, ...) ugly_log(UDEBUG, __FILE__, format, __VA_ARGS__) +#define DLOG(...) DLOG_HELPER(__VA_ARGS__, "") +#define ILOG_HELPER(format, ...) ugly_log(UINFO, __FILE__, format, __VA_ARGS__) +#define ILOG(...) ILOG_HELPER(__VA_ARGS__, "") +#define WLOG_HELPER(format, ...) ugly_log(UWARN, __FILE__, format, __VA_ARGS__) +#define WLOG(...) WLOG_HELPER(__VA_ARGS__, "") +#define ELOG_HELPER(format, ...) ugly_log(UERROR, __FILE__, format, __VA_ARGS__) +#define ELOG(...) ELOG_HELPER(__VA_ARGS__, "") +#define fatal_helper(format, ...) ugly_log(UFATAL, __FILE__, format, __VA_ARGS__) +#define fatal(...) fatal_helper(__VA_ARGS__, "") #ifdef __cplusplus } From 48a8ac59e1ba7f98fe5c247f608be3cb3998e9c4 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 20 May 2016 20:03:57 +0200 Subject: [PATCH 0429/1435] Move STLINK_DEBUG_* defines into enum, move flash_loader code into seperate header and c file --- CMakeLists.txt | 2 + Makefile.am | 5 +- include/stlink.h | 36 +--- include/stlink/commands.h | 26 +++ include/stlink/flash_loader.h | 27 +++ src/common.c | 333 ++-------------------------------- src/flash_loader.c | 313 ++++++++++++++++++++++++++++++++ 7 files changed, 393 insertions(+), 349 deletions(-) create mode 100644 include/stlink/commands.h create mode 100644 include/stlink/flash_loader.h create mode 100644 src/flash_loader.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 89bd85968..dab482939 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ set(STLINK_HEADERS include/stlink/logging.h include/stlink/mmap.h include/stlink/chipid.h + include/stlink/flash_loader.h ) set(STLINK_SOURCE @@ -62,6 +63,7 @@ set(STLINK_SOURCE src/usb.c src/sg.c src/logging.c + src/flash_loader.c ) include_directories(${LIBUSB_INCLUDE_DIR}) diff --git a/Makefile.am b/Makefile.am index a3114c6e4..79ce10c22 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,7 +22,8 @@ CFILES = \ src/common.c \ src/usb.c \ src/sg.c \ - src/logging.c + src/logging.c \ + src/flash_loader.c if !MINGW CFILES += src/tools/term.c @@ -32,6 +33,8 @@ HFILES = \ include/stlink.h \ include/stlink/chipid.h \ include/stlink/usb.h \ + include/stlink/flash_loader.h \ + include/stlink/commands.h \ include/stlink/sg.h \ include/stlink/logging.h \ include/stlink/mmap.h diff --git a/include/stlink.h b/include/stlink.h index 3941f4216..a20f815cb 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -49,27 +49,6 @@ extern "C" { #define STLINK_DEV_DEBUG_MODE 0x02 #define STLINK_DEV_UNKNOWN_MODE -1 - // jtag mode cmds -#define STLINK_DEBUG_ENTER 0x20 -#define STLINK_DEBUG_EXIT 0x21 -#define STLINK_DEBUG_READCOREID 0x22 -#define STLINK_DEBUG_GETSTATUS 0x01 -#define STLINK_DEBUG_FORCEDEBUG 0x02 -#define STLINK_DEBUG_RESETSYS 0x03 -#define STLINK_DEBUG_READALLREGS 0x04 -#define STLINK_DEBUG_READREG 0x05 -#define STLINK_DEBUG_WRITEREG 0x06 -#define STLINK_DEBUG_READMEM_32BIT 0x07 -#define STLINK_DEBUG_WRITEMEM_32BIT 0x08 -#define STLINK_DEBUG_RUNCORE 0x09 -#define STLINK_DEBUG_STEPCORE 0x0a -#define STLINK_DEBUG_SETFP 0x0b -#define STLINK_DEBUG_WRITEMEM_8BIT 0x0d -#define STLINK_DEBUG_CLEARFP 0x0e -#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 @@ -116,8 +95,6 @@ extern "C" { FLASH_TYPE_L4, }; -#include "stlink/chipid.h" - typedef struct { uint32_t r[16]; uint32_t s[32]; @@ -135,6 +112,11 @@ extern "C" { typedef uint32_t stm32_addr_t; +typedef struct flash_loader { + stm32_addr_t loader_addr; /* loader sram adddr */ + stm32_addr_t buf_addr; /* buffer sram address */ +} flash_loader_t; + typedef struct _cortex_m3_cpuid_ { uint16_t implementer_id; uint16_t variant; @@ -150,11 +132,6 @@ extern "C" { uint32_t stlink_pid; } stlink_version_t; - typedef struct flash_loader { - stm32_addr_t loader_addr; /* loader sram adddr */ - stm32_addr_t buf_addr; /* buffer sram address */ - } flash_loader_t; - enum transport_type { TRANSPORT_TYPE_ZERO = 0, TRANSPORT_TYPE_LIBSG, @@ -298,6 +275,9 @@ extern "C" { #include "stlink/sg.h" #include "stlink/usb.h" +#include "stlink/commands.h" +#include "stlink/chipid.h" +#include "stlink/flash_loader.h" #ifdef __cplusplus } diff --git a/include/stlink/commands.h b/include/stlink/commands.h new file mode 100644 index 000000000..9ff5a8fb9 --- /dev/null +++ b/include/stlink/commands.h @@ -0,0 +1,26 @@ +#ifndef STLINK_COMMANDS_H_ +#define STLINK_COMMANDS_H_ + +enum stlink_debug_commands { + STLINK_DEBUG_ENTER_JTAG = 0x00, + STLINK_DEBUG_GETSTATUS = 0x01, + STLINK_DEBUG_FORCEDEBUG = 0x02, + STLINK_DEBUG_RESETSYS = 0x03, + STLINK_DEBUG_READALLREGS = 0x04, + STLINK_DEBUG_READREG = 0x05, + STLINK_DEBUG_WRITEREG = 0x06, + STLINK_DEBUG_READMEM_32BIT = 0x07, + STLINK_DEBUG_WRITEMEM_32BIT = 0x08, + STLINK_DEBUG_RUNCORE = 0x09, + STLINK_DEBUG_STEPCORE = 0x0a, + STLINK_DEBUG_SETFP = 0x0b, + STLINK_DEBUG_WRITEMEM_8BIT = 0x0d, + STLINK_DEBUG_CLEARFP = 0x0e, + STLINK_DEBUG_WRITEDEBUGREG = 0x0f, + STLINK_DEBUG_ENTER = 0x20, + STLINK_DEBUG_EXIT = 0x21, + STLINK_DEBUG_READCOREID = 0x22, + STLINK_DEBUG_ENTER_SWD = 0xa3 +}; + +#endif /* STLINK_COMMANDS_H_ */ diff --git a/include/stlink/flash_loader.h b/include/stlink/flash_loader.h new file mode 100644 index 000000000..95042f7b6 --- /dev/null +++ b/include/stlink/flash_loader.h @@ -0,0 +1,27 @@ +/* + * File: stlink.h + * + * This should contain all the common top level stlink interfaces, regardless + * of how the backend does the work.... + */ +#ifndef STLINK_FLASH_LOADER_H_ +#define STLINK_FLASH_LOADER_H_ + +#include +#include + +#include "stlink.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int stlink_flash_loader_init(stlink_t *sl, flash_loader_t* fl); +int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); +int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size); + +#ifdef __cplusplus +} +#endif + +#endif /* STLINK_FLASH_LOADER_H_ */ diff --git a/src/common.c b/src/common.c index 729c739da..727048125 100644 --- a/src/common.c +++ b/src/common.c @@ -1416,252 +1416,6 @@ int stlink_erase_flash_mass(stlink_t *sl) { return 0; } -int init_flash_loader(stlink_t *sl, flash_loader_t* fl) { - size_t size; - - /* allocate the loader in sram */ - if (write_loader_to_sram(sl, &fl->loader_addr, &size) == -1) { - WLOG("Failed to write flash loader to sram!\n"); - return -1; - } - - /* allocate a one page buffer in sram right after loader */ - fl->buf_addr = fl->loader_addr + size; - ILOG("Successfully loaded flash loader in sram\n"); - return 0; -} - -int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { - /* from openocd, contrib/loaders/flash/stm32.s */ - static const uint8_t loader_code_stm32vl[] = { - 0x08, 0x4c, /* ldr r4, STM32_FLASH_BASE */ - 0x1c, 0x44, /* add r4, r3 */ - /* write_half_word: */ - 0x01, 0x23, /* movs r3, #0x01 */ - 0x23, 0x61, /* str r3, [r4, #STM32_FLASH_CR_OFFSET] */ - 0x30, 0xf8, 0x02, 0x3b, /* ldrh r3, [r0], #0x02 */ - 0x21, 0xf8, 0x02, 0x3b, /* strh r3, [r1], #0x02 */ - /* busy: */ - 0xe3, 0x68, /* ldr r3, [r4, #STM32_FLASH_SR_OFFSET] */ - 0x13, 0xf0, 0x01, 0x0f, /* tst r3, #0x01 */ - 0xfb, 0xd0, /* beq busy */ - 0x13, 0xf0, 0x14, 0x0f, /* tst r3, #0x14 */ - 0x01, 0xd1, /* bne exit */ - 0x01, 0x3a, /* subs r2, r2, #0x01 */ - 0xf0, 0xd1, /* bne write_half_word */ - /* exit: */ - 0x00, 0xbe, /* bkpt #0x00 */ - 0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */ - }; - - /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ - static const uint8_t loader_code_stm32f0[] = { -#if 1 - /* - * These two NOPs here are a safety precaution, added by Pekka Nikander - * while debugging the STM32F05x support. They may not be needed, but - * there were strange problems with simpler programs, like a program - * that had just a breakpoint or a program that first moved zero to register r2 - * and then had a breakpoint. So, it appears safest to have these two nops. - * - * Feel free to remove them, if you dare, but then please do test the result - * rigorously. Also, if you remove these, it may be a good idea first to - * #if 0 them out, with a comment when these were taken out, and to remove - * these only a few months later... But YMMV. - */ - 0x00, 0x30, // nop /* add r0,#0 */ - 0x00, 0x30, // nop /* add r0,#0 */ -#endif - 0x0A, 0x4C, // ldr r4, STM32_FLASH_BASE - 0x01, 0x25, // mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ - 0x04, 0x26, // mov r6, #4 /* PGERR */ - // write_half_word: - 0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */ - 0x2B, 0x43, // orr r3, r5 - 0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ - 0x03, 0x88, // ldrh r3, [r0] /* r3 = *sram */ - 0x0B, 0x80, // strh r3, [r1] /* *flash = r3 */ - // busy: - 0xE3, 0x68, // ldr r3, [r4, #12] /* FLASH->SR */ - 0x2B, 0x42, // tst r3, r5 /* FLASH_SR_BUSY */ - 0xFC, 0xD0, // beq busy - - 0x33, 0x42, // tst r3, r6 /* PGERR */ - 0x04, 0xD1, // bne exit - - 0x02, 0x30, // add r0, r0, #2 /* sram += 2 */ - 0x02, 0x31, // add r1, r1, #2 /* flash += 2 */ - 0x01, 0x3A, // sub r2, r2, #0x01 /* count-- */ - 0x00, 0x2A, // cmp r2, #0 - 0xF0, 0xD1, // bne write_half_word - // exit: - 0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */ - 0xAB, 0x43, // bic r3, r5 - 0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ - 0x00, 0xBE, // bkpt #0x00 - 0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */ - }; - - static const uint8_t loader_code_stm32l[] = { - // flashloaders/stm32lx.s - - 0x04, 0xe0, // b test_done ; Go to compare - // write_word: - 0x04, 0x68, // ldr r4, [r0] ; Load one word from address in r0 - 0x0c, 0x60, // str r4, [r1] ; Store the word to address in r1 - 0x04, 0x30, // adds r0, #4 ; Increment r0 - 0x04, 0x31, // adds r1, #4 ; Increment r1 - 0x01, 0x3a, // subs r2, #1 ; Decrement r2 - // test_done: - 0x00, 0x2a, // cmp r2, #0 ; Compare r2 to 0 - 0xf8, 0xd8, // bhi write_word ; Loop if above 0 - 0x00, 0xbe, // bkpt #0x00 ; Set breakpoint to exit - 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32f4[] = { - // flashloaders/stm32f4.s - - 0x07, 0x4b, - - 0x62, 0xb1, - 0x04, 0x68, - 0x0c, 0x60, - - 0xdc, 0x89, - 0x14, 0xf0, 0x01, 0x0f, - 0xfb, 0xd1, - 0x00, 0xf1, 0x04, 0x00, - 0x01, 0xf1, 0x04, 0x01, - 0xa2, 0xf1, 0x01, 0x02, - 0xf1, 0xe7, - - 0x00, 0xbe, - - 0x00, 0x3c, 0x02, 0x40, - }; - - static const uint8_t loader_code_stm32f4_lv[] = { - // flashloaders/stm32f4lv.s - 0x92, 0x00, - - 0x08, 0x4b, - 0x62, 0xb1, - 0x04, 0x78, - 0x0c, 0x70, - - 0xdc, 0x89, - 0x14, 0xf0, 0x01, 0x0f, - 0xfb, 0xd1, - 0x00, 0xf1, 0x01, 0x00, - 0x01, 0xf1, 0x01, 0x01, - 0xa2, 0xf1, 0x01, 0x02, - 0xf1, 0xe7, - - 0x00, 0xbe, - 0x00, 0xbf, - - 0x00, 0x3c, 0x02, 0x40, - }; - - static const uint8_t loader_code_stm32l4[] = { - // flashloaders/stm32l4.s - 0x08, 0x4b, // start: ldr r3, [pc, #32] ; - 0x72, 0xb1, // next: cbz r2, - 0x04, 0x68, // ldr r4, [r0, #0] - 0x45, 0x68, // ldr r5, [r0, #4] - 0x0c, 0x60, // str r4, [r1, #0] - 0x4d, 0x60, // str r5, [r1, #4] - 0x5c, 0x8a, // wait: ldrh r4, [r3, #18] - 0x14, 0xf0, 0x01, 0x0f, // tst.w r4, #1 - 0xfb, 0xd1, // bne.n - 0x00, 0xf1, 0x08, 0x00, // add.w r0, r0, #8 - 0x01, 0xf1, 0x08, 0x01, // add.w r1, r1, #8 - 0xa2, 0xf1, 0x01, 0x02, // sub.w r2, r2, #1 - 0xef, 0xe7, // b.n - 0x00, 0xbe, // done: bkpt 0x0000 - 0x00, 0x20, 0x02, 0x40 // flash_base: .word 0x40022000 - }; - - static const uint8_t loader_code_stm32f7[] = { - 0x08, 0x4b, - 0x72, 0xb1, - 0x04, 0x68, - 0x0c, 0x60, - 0xbf, 0xf3, 0x4f, 0x8f, // DSB Memory barrier for in order flash write - 0xdc, 0x89, - 0x14, 0xf0, 0x01, 0x0f, - 0xfb, 0xd1, - 0x00, 0xf1, 0x04, 0x00, - 0x01, 0xf1, 0x04, 0x01, - 0xa2, 0xf1, 0x01, 0x02, - 0xef, 0xe7, - 0x00, 0xbe, // bkpt #0x00 - 0x00, 0x3c, 0x02, 0x40, - }; - - const uint8_t* loader_code; - size_t loader_size; - - if (sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2 - || sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS || sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH - || sl->chip_id == STLINK_CHIPID_STM32_L152_RE - || sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { /* stm32l */ - loader_code = loader_code_stm32l; - loader_size = sizeof(loader_code_stm32l); - } else if (sl->core_id == STM32VL_CORE_ID - || sl->chip_id == STLINK_CHIPID_STM32_F3 - || sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL - || sl->chip_id == STLINK_CHIPID_STM32_F303_HIGH - || sl->chip_id == STLINK_CHIPID_STM32_F37x - || sl->chip_id == STLINK_CHIPID_STM32_F334) { - loader_code = loader_code_stm32vl; - loader_size = sizeof(loader_code_stm32vl); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 || - sl->chip_id == STLINK_CHIPID_STM32_F4 || - sl->chip_id == STLINK_CHIPID_STM32_F4_DE || - sl->chip_id == STLINK_CHIPID_STM32_F4_LP || - sl->chip_id == STLINK_CHIPID_STM32_F4_HD || - sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || - sl->chip_id == STLINK_CHIPID_STM32_F410 || - sl->chip_id == STLINK_CHIPID_STM32_F411RE || - sl->chip_id == STLINK_CHIPID_STM32_F446 - ) { - int voltage = stlink_target_voltage(sl); - if (voltage == -1) { - printf("Failed to read Target voltage\n"); - return voltage; - } else if (voltage > 2700) { - loader_code = loader_code_stm32f4; - loader_size = sizeof(loader_code_stm32f4); - } else { - loader_code = loader_code_stm32f4_lv; - loader_size = sizeof(loader_code_stm32f4_lv); - } - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7){ - loader_code = loader_code_stm32f7; - loader_size = sizeof(loader_code_stm32f7); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || sl->chip_id == STLINK_CHIPID_STM32_F04 || sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || sl->chip_id == STLINK_CHIPID_STM32_F0_SMALL || sl->chip_id == STLINK_CHIPID_STM32_F09X) { - loader_code = loader_code_stm32f0; - loader_size = sizeof(loader_code_stm32f0); - } else if (sl->chip_id == STLINK_CHIPID_STM32_L4) { - loader_code = loader_code_stm32l4; - loader_size = sizeof(loader_code_stm32l4); - } else { - ELOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); - return -1; - } - - memcpy(sl->q_buf, loader_code, loader_size); - stlink_write_mem32(sl, sl->sram_base, loader_size); - - *addr = sl->sram_base; - *size = loader_size; - - /* success */ - return 0; -} - int stlink_fcheck_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { /* check the contents of path are at addr */ @@ -1729,8 +1483,8 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uin ILOG("Starting Half page flash write for STM32L core id\n"); /* flash loader initialization */ - if (init_flash_loader(sl, &fl) == -1) { - WLOG("init_flash_loader() == -1\n"); + if (stlink_flash_loader_init(sl, &fl) == -1) { + WLOG("stlink_flash_loader_init() == -1\n"); return -1; } /* Unlock already done */ @@ -1745,8 +1499,8 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uin } while ((val & (1 << 0)) != 0); for (count = 0; count < num_half_pages; count ++) { - if (run_flash_loader(sl, &fl, addr + count * pagesize, base + count * pagesize, pagesize) == -1) { - WLOG("l1_run_flash_loader(%#zx) failed! == -1\n", addr + count * pagesize); + if (stlink_flash_loader_run(sl, &fl, addr + count * pagesize, base + count * pagesize, pagesize) == -1) { + WLOG("l1_stlink_flash_loader_run(%#zx) failed! == -1\n", addr + count * pagesize); stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val &= ~((1 << FLASH_L1_FPRG) |(1 << FLASH_L1_PROG)); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); @@ -1827,8 +1581,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t ILOG("Starting Flash write for F2/F4/L4\n"); /* flash loader initialization */ - if (init_flash_loader(sl, &fl) == -1) { - ELOG("init_flash_loader() == -1\n"); + if (stlink_flash_loader_init(sl, &fl) == -1) { + ELOG("stlink_flash_loader_init() == -1\n"); return -1; } @@ -1869,8 +1623,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t printf("size: %zu\n", size); - if (run_flash_loader(sl, &fl, addr + off, base + off, size) == -1) { - ELOG("run_flash_loader(%#zx) failed! == -1\n", addr + off); + if (stlink_flash_loader_run(sl, &fl, addr + off, base + off, size) == -1) { + ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); return -1; } @@ -1960,8 +1714,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } else if (sl->flash_type == FLASH_TYPE_F0) { ILOG("Starting Flash write for VL/F0/F3 core id\n"); /* flash loader initialization */ - if (init_flash_loader(sl, &fl) == -1) { - ELOG("init_flash_loader() == -1\n"); + if (stlink_flash_loader_init(sl, &fl) == -1) { + ELOG("stlink_flash_loader_init() == -1\n"); return -1; } @@ -1974,9 +1728,9 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t /* unlock and set programming mode */ unlock_flash_if(sl); set_flash_cr_pg(sl); - //DLOG("Finished setting flash cr pg, running loader!\n"); - if (run_flash_loader(sl, &fl, addr + off, base + off, size) == -1) { - ELOG("run_flash_loader(%#zx) failed! == -1\n", addr + off); + DLOG("Finished setting flash cr pg, running loader!\n"); + if (stlink_flash_loader_run(sl, &fl, addr + off, base + off, size) == -1) { + ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); return -1; } lock_flash(sl); @@ -2042,64 +1796,3 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { unmap_file(&mf); return err; } - -int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { - - reg rr; - int i = 0; - size_t count = 0; - - DLOG("Running flash loader, write address:%#x, size: %zd\n", target, size); - // FIXME This can never return -1 - if (write_buffer_to_sram(sl, fl, buf, size) == -1) { - // IMPOSSIBLE! - ELOG("write_buffer_to_sram() == -1\n"); - return -1; - } - - if (sl->flash_type == FLASH_TYPE_F0) { - count = size / sizeof(uint16_t); - if (size % sizeof(uint16_t)) - ++count; - } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L0) { - count = size / sizeof(uint32_t); - if (size % sizeof(uint32_t)) - ++count; - } else if (sl->flash_type == FLASH_TYPE_L4) { - count = size / sizeof(uint64_t); - if (size % sizeof(uint64_t)) - ++count; - } - - /* setup core */ - stlink_write_reg(sl, fl->buf_addr, 0); /* source */ - stlink_write_reg(sl, target, 1); /* target */ - stlink_write_reg(sl, count, 2); /* count */ - stlink_write_reg(sl, 0, 3); /* flash bank 0 (input), only used on F0, but armless fopr others */ - stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - - /* run loader */ - stlink_run(sl); - -#define WAIT_ROUNDS 10000 - /* wait until done (reaches breakpoint) */ - for (i = 0; i < WAIT_ROUNDS; i++) { - usleep(10); - if (is_core_halted(sl)) - break; - } - - if (i >= WAIT_ROUNDS) { - ELOG("flash loader run error\n"); - return -1; - } - - /* check written byte count */ - stlink_read_reg(sl, 2, &rr); - if (rr.r[2] != 0) { - fprintf(stderr, "write error, count == %u\n", rr.r[2]); - return -1; - } - - return 0; -} diff --git a/src/flash_loader.c b/src/flash_loader.c new file mode 100644 index 000000000..bf4c92f14 --- /dev/null +++ b/src/flash_loader.c @@ -0,0 +1,313 @@ +#include "stlink.h" + +/* from openocd, contrib/loaders/flash/stm32.s */ +static const uint8_t loader_code_stm32vl[] = { + 0x08, 0x4c, /* ldr r4, STM32_FLASH_BASE */ + 0x1c, 0x44, /* add r4, r3 */ + /* write_half_word: */ + 0x01, 0x23, /* movs r3, #0x01 */ + 0x23, 0x61, /* str r3, [r4, #STM32_FLASH_CR_OFFSET] */ + 0x30, 0xf8, 0x02, 0x3b, /* ldrh r3, [r0], #0x02 */ + 0x21, 0xf8, 0x02, 0x3b, /* strh r3, [r1], #0x02 */ + /* busy: */ + 0xe3, 0x68, /* ldr r3, [r4, #STM32_FLASH_SR_OFFSET] */ + 0x13, 0xf0, 0x01, 0x0f, /* tst r3, #0x01 */ + 0xfb, 0xd0, /* beq busy */ + 0x13, 0xf0, 0x14, 0x0f, /* tst r3, #0x14 */ + 0x01, 0xd1, /* bne exit */ + 0x01, 0x3a, /* subs r2, r2, #0x01 */ + 0xf0, 0xd1, /* bne write_half_word */ + /* exit: */ + 0x00, 0xbe, /* bkpt #0x00 */ + 0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */ + }; + + /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ + static const uint8_t loader_code_stm32f0[] = { +#if 1 + /* + * These two NOPs here are a safety precaution, added by Pekka Nikander + * while debugging the STM32F05x support. They may not be needed, but + * there were strange problems with simpler programs, like a program + * that had just a breakpoint or a program that first moved zero to register r2 + * and then had a breakpoint. So, it appears safest to have these two nops. + * + * Feel free to remove them, if you dare, but then please do test the result + * rigorously. Also, if you remove these, it may be a good idea first to + * #if 0 them out, with a comment when these were taken out, and to remove + * these only a few months later... But YMMV. + */ + 0x00, 0x30, // nop /* add r0,#0 */ + 0x00, 0x30, // nop /* add r0,#0 */ +#endif + 0x0A, 0x4C, // ldr r4, STM32_FLASH_BASE + 0x01, 0x25, // mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ + 0x04, 0x26, // mov r6, #4 /* PGERR */ + // write_half_word: + 0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */ + 0x2B, 0x43, // orr r3, r5 + 0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ + 0x03, 0x88, // ldrh r3, [r0] /* r3 = *sram */ + 0x0B, 0x80, // strh r3, [r1] /* *flash = r3 */ + // busy: + 0xE3, 0x68, // ldr r3, [r4, #12] /* FLASH->SR */ + 0x2B, 0x42, // tst r3, r5 /* FLASH_SR_BUSY */ + 0xFC, 0xD0, // beq busy + + 0x33, 0x42, // tst r3, r6 /* PGERR */ + 0x04, 0xD1, // bne exit + + 0x02, 0x30, // add r0, r0, #2 /* sram += 2 */ + 0x02, 0x31, // add r1, r1, #2 /* flash += 2 */ + 0x01, 0x3A, // sub r2, r2, #0x01 /* count-- */ + 0x00, 0x2A, // cmp r2, #0 + 0xF0, 0xD1, // bne write_half_word + // exit: + 0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */ + 0xAB, 0x43, // bic r3, r5 + 0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ + 0x00, 0xBE, // bkpt #0x00 + 0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */ + }; + + static const uint8_t loader_code_stm32l[] = { + // flashloaders/stm32lx.s + + 0x04, 0xe0, // b test_done ; Go to compare + // write_word: + 0x04, 0x68, // ldr r4, [r0] ; Load one word from address in r0 + 0x0c, 0x60, // str r4, [r1] ; Store the word to address in r1 + 0x04, 0x30, // adds r0, #4 ; Increment r0 + 0x04, 0x31, // adds r1, #4 ; Increment r1 + 0x01, 0x3a, // subs r2, #1 ; Decrement r2 + // test_done: + 0x00, 0x2a, // cmp r2, #0 ; Compare r2 to 0 + 0xf8, 0xd8, // bhi write_word ; Loop if above 0 + 0x00, 0xbe, // bkpt #0x00 ; Set breakpoint to exit + 0x00, 0x00 + }; + + static const uint8_t loader_code_stm32f4[] = { + // flashloaders/stm32f4.s + + 0x07, 0x4b, + + 0x62, 0xb1, + 0x04, 0x68, + 0x0c, 0x60, + + 0xdc, 0x89, + 0x14, 0xf0, 0x01, 0x0f, + 0xfb, 0xd1, + 0x00, 0xf1, 0x04, 0x00, + 0x01, 0xf1, 0x04, 0x01, + 0xa2, 0xf1, 0x01, 0x02, + 0xf1, 0xe7, + + 0x00, 0xbe, + + 0x00, 0x3c, 0x02, 0x40, + }; + + static const uint8_t loader_code_stm32f4_lv[] = { + // flashloaders/stm32f4lv.s + 0x92, 0x00, + + 0x08, 0x4b, + 0x62, 0xb1, + 0x04, 0x78, + 0x0c, 0x70, + + 0xdc, 0x89, + 0x14, 0xf0, 0x01, 0x0f, + 0xfb, 0xd1, + 0x00, 0xf1, 0x01, 0x00, + 0x01, 0xf1, 0x01, 0x01, + 0xa2, 0xf1, 0x01, 0x02, + 0xf1, 0xe7, + + 0x00, 0xbe, + 0x00, 0xbf, + + 0x00, 0x3c, 0x02, 0x40, + }; + + static const uint8_t loader_code_stm32l4[] = { + // flashloaders/stm32l4.s + 0x08, 0x4b, // start: ldr r3, [pc, #32] ; + 0x72, 0xb1, // next: cbz r2, + 0x04, 0x68, // ldr r4, [r0, #0] + 0x45, 0x68, // ldr r5, [r0, #4] + 0x0c, 0x60, // str r4, [r1, #0] + 0x4d, 0x60, // str r5, [r1, #4] + 0x5c, 0x8a, // wait: ldrh r4, [r3, #18] + 0x14, 0xf0, 0x01, 0x0f, // tst.w r4, #1 + 0xfb, 0xd1, // bne.n + 0x00, 0xf1, 0x08, 0x00, // add.w r0, r0, #8 + 0x01, 0xf1, 0x08, 0x01, // add.w r1, r1, #8 + 0xa2, 0xf1, 0x01, 0x02, // sub.w r2, r2, #1 + 0xef, 0xe7, // b.n + 0x00, 0xbe, // done: bkpt 0x0000 + 0x00, 0x20, 0x02, 0x40 // flash_base: .word 0x40022000 + }; + + static const uint8_t loader_code_stm32f7[] = { + 0x08, 0x4b, + 0x72, 0xb1, + 0x04, 0x68, + 0x0c, 0x60, + 0xbf, 0xf3, 0x4f, 0x8f, // DSB Memory barrier for in order flash write + 0xdc, 0x89, + 0x14, 0xf0, 0x01, 0x0f, + 0xfb, 0xd1, + 0x00, 0xf1, 0x04, 0x00, + 0x01, 0xf1, 0x04, 0x01, + 0xa2, 0xf1, 0x01, 0x02, + 0xef, 0xe7, + 0x00, 0xbe, // bkpt #0x00 + 0x00, 0x3c, 0x02, 0x40, + }; + + + +int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) +{ + size_t size; + + /* allocate the loader in sram */ + if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { + WLOG("Failed to write flash loader to sram!\n"); + return -1; + } + + /* allocate a one page buffer in sram right after loader */ + fl->buf_addr = fl->loader_addr + size; + ILOG("Successfully loaded flash loader in sram\n"); + + return 0; +} + +int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) +{ + const uint8_t* loader_code; + size_t loader_size; + + if (sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2 + || sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS || sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH + || sl->chip_id == STLINK_CHIPID_STM32_L152_RE + || sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { /* stm32l */ + loader_code = loader_code_stm32l; + loader_size = sizeof(loader_code_stm32l); + } else if (sl->core_id == STM32VL_CORE_ID + || sl->chip_id == STLINK_CHIPID_STM32_F3 + || sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL + || sl->chip_id == STLINK_CHIPID_STM32_F303_HIGH + || sl->chip_id == STLINK_CHIPID_STM32_F37x + || sl->chip_id == STLINK_CHIPID_STM32_F334) { + loader_code = loader_code_stm32vl; + loader_size = sizeof(loader_code_stm32vl); + } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 || + sl->chip_id == STLINK_CHIPID_STM32_F4 || + sl->chip_id == STLINK_CHIPID_STM32_F4_DE || + sl->chip_id == STLINK_CHIPID_STM32_F4_LP || + sl->chip_id == STLINK_CHIPID_STM32_F4_HD || + sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || + sl->chip_id == STLINK_CHIPID_STM32_F410 || + sl->chip_id == STLINK_CHIPID_STM32_F411RE || + sl->chip_id == STLINK_CHIPID_STM32_F446 + ) { + int voltage = stlink_target_voltage(sl); + if (voltage == -1) { + printf("Failed to read Target voltage\n"); + return voltage; + } else if (voltage > 2700) { + loader_code = loader_code_stm32f4; + loader_size = sizeof(loader_code_stm32f4); + } else { + loader_code = loader_code_stm32f4_lv; + loader_size = sizeof(loader_code_stm32f4_lv); + } + } else if (sl->chip_id == STLINK_CHIPID_STM32_F7){ + loader_code = loader_code_stm32f7; + loader_size = sizeof(loader_code_stm32f7); + } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || sl->chip_id == STLINK_CHIPID_STM32_F04 || sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || sl->chip_id == STLINK_CHIPID_STM32_F0_SMALL || sl->chip_id == STLINK_CHIPID_STM32_F09X) { + loader_code = loader_code_stm32f0; + loader_size = sizeof(loader_code_stm32f0); + } else if (sl->chip_id == STLINK_CHIPID_STM32_L4) { + loader_code = loader_code_stm32l4; + loader_size = sizeof(loader_code_stm32l4); + } else { + ELOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); + return -1; + } + + memcpy(sl->q_buf, loader_code, loader_size); + stlink_write_mem32(sl, sl->sram_base, loader_size); + + *addr = sl->sram_base; + *size = loader_size; + + /* success */ + return 0; +} + +int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) +{ + reg rr; + int i = 0; + size_t count = 0; + + DLOG("Running flash loader, write address:%#x, size: %zd\n", target, size); + // FIXME This can never return -1 + if (write_buffer_to_sram(sl, fl, buf, size) == -1) { + // IMPOSSIBLE! + ELOG("write_buffer_to_sram() == -1\n"); + return -1; + } + + if (sl->flash_type == FLASH_TYPE_F0) { + count = size / sizeof(uint16_t); + if (size % sizeof(uint16_t)) + ++count; + } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L0) { + count = size / sizeof(uint32_t); + if (size % sizeof(uint32_t)) + ++count; + } else if (sl->flash_type == FLASH_TYPE_L4) { + count = size / sizeof(uint64_t); + if (size % sizeof(uint64_t)) + ++count; + } + + /* setup core */ + stlink_write_reg(sl, fl->buf_addr, 0); /* source */ + stlink_write_reg(sl, target, 1); /* target */ + stlink_write_reg(sl, count, 2); /* count */ + stlink_write_reg(sl, 0, 3); /* flash bank 0 (input), only used on F0, but armless fopr others */ + stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ + + /* run loader */ + stlink_run(sl); + +#define WAIT_ROUNDS 10000 + /* wait until done (reaches breakpoint) */ + for (i = 0; i < WAIT_ROUNDS; i++) { + usleep(10); + if (is_core_halted(sl)) + break; + } + + if (i >= WAIT_ROUNDS) { + ELOG("flash loader run error\n"); + return -1; + } + + /* check written byte count */ + stlink_read_reg(sl, 2, &rr); + if (rr.r[2] != 0) { + ELOG("write error, count == %u\n", rr.r[2]); + return -1; + } + + return 0; +} From f8d711818d020f727cdf6ca7192d43dad40604c8 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 20 May 2016 20:36:41 +0200 Subject: [PATCH 0430/1435] cmake: Search for static libusb-1.0 library on OSX and link with ObjC,CoreFoundation and IOKit frameworks --- CMakeLists.txt | 9 ++++- cmake/modules/FindLibUSB.cmake | 60 +++++++++++++++++++--------------- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dab482939..efadb5c7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,14 @@ include_directories(src/mingw) add_library(${PROJECT_NAME} STATIC ${STLINK_HEADERS} # header files for ide projects generated by cmake ${STLINK_SOURCE}) -target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARIES}) +target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARY}) + +if (APPLE) + find_library(ObjC objc) + find_library(CoreFoundation CoreFoundation) + find_library(IOKit IOKit) + target_link_libraries(${PROJECT_NAME} ${CoreFoundation} ${IOKit} ${ObjC}) +endif() add_executable(st-flash src/tools/flash.c) target_link_libraries(st-flash ${PROJECT_NAME}) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index 2e518a7a6..7f14ca125 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -1,27 +1,33 @@ -# FindLibUSB.cmake - Try to find the Hiredis library -# Once done this will define -# -# LIBUSB_FOUND - System has libusb -# LIBUSB_INCLUDE_DIR - The libusb include directory -# LIBUSB_LIBRARIES - The libraries needed to use libusb -# LIBUSB_DEFINITIONS - Compiler switches required for using libusb - -FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h - HINTS - /usr - /usr/local - /opt - PATH_SUFFIXES libusb-1.0 - ) - -FIND_LIBRARY(LIBUSB_LIBRARIES NAMES usb-1.0 - HINTS - /usr - /usr/local - /opt - ) - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARIES LIBUSB_INCLUDE_DIR) - -MARK_AS_ADVANCED(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARIES) +# FindLibUSB.cmake - Try to find the Hiredis library +# Once done this will define +# +# LIBUSB_FOUND - System has libusb +# LIBUSB_INCLUDE_DIR - The libusb include directory +# LIBUSB_LIBRARY - The libraries needed to use libusb +# LIBUSB_DEFINITIONS - Compiler switches required for using libusb + +FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS + /usr + /usr/local + /opt + PATH_SUFFIXES libusb-1.0 + ) + +if (APPLE) + set(LIBUSB_NAME libusb-1.0.a) +else() + set(LIBUSB_NAME usb-1.0) +endif() + +FIND_LIBRARY(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS + /usr + /usr/local + /opt +) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + +MARK_AS_ADVANCED(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) From 74389ba7b840fb8be27d3eea2b04b50927491a65 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 20 May 2016 20:49:29 +0200 Subject: [PATCH 0431/1435] travis: Add gcc-5 and clang-3.8 to matrix for linux cmake builds --- .travis.sh | 6 ++++++ .travis.yml | 27 ++++++++++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/.travis.sh b/.travis.sh index 13d2c1dcd..9e28d3ca1 100755 --- a/.travis.sh +++ b/.travis.sh @@ -1,4 +1,10 @@ #!/bin/bash +echo "-- C compilers available" +ls -1 /usr/bin/gcc* +ls -1 /usr/bin/clang* +ls -1 /usr/bin/scan-build* +echo "----" + if [ "$TRAVIS_OS_NAME" != "osx" ]; then sudo apt-get update -qq || true sudo apt-get install -qq -y --no-install-recommends libusb-1.0.0-dev libgtk-3-dev diff --git a/.travis.yml b/.travis.yml index 5164d36c5..0fae3aaeb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,24 +1,33 @@ sudo: true language: c +addons: + apt: + sources: + - llvm-toolchain-precise-3.8 + - ubuntu-toolchain-r-test + packages: + - clang-3.8 + - g++-5 + - gcc-5 script: - ./.travis.sh matrix: include: - - os: osx - compiler: clang - env: "BUILD_SYSTEM=cmake" - - os: osx + - os: linux + compiler: gcc + env: "BUILD_SYSTEM=autotools" + - os: linux compiler: clang env: "BUILD_SYSTEM=autotools" - os: linux - compiler: gcc + compiler: gcc-5 env: "BUILD_SYSTEM=cmake" - os: linux + compiler: clang-3.8 + env: "BUILD_SYSTEM=cmake" + - os: osx compiler: clang env: "BUILD_SYSTEM=cmake" - - os: linux - compiler: gcc - env: "BUILD_SYSTEM=autotools" - - os: linux + - os: osx compiler: clang env: "BUILD_SYSTEM=autotools" From e2a4fb37d4b13ad98e1349f6e57c877ef9c98e02 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 20 May 2016 23:11:43 +0200 Subject: [PATCH 0432/1435] Move USB defines into usb.h, move chip register defines into new reg.h --- include/stlink.h | 26 +++----------------------- include/stlink/reg.h | 8 ++++++++ include/stlink/usb.h | 5 +++++ src/common.c | 19 ++++++++++++------- src/flash_loader.c | 2 +- src/gdbserver/gdb-server.c | 6 +++--- src/go/main | Bin 0 -> 2777276 bytes src/sg.c | 9 ++++++--- src/usb.c | 16 ++++++++-------- 9 files changed, 46 insertions(+), 45 deletions(-) create mode 100644 include/stlink/reg.h create mode 100755 src/go/main diff --git a/include/stlink.h b/include/stlink.h index a20f815cb..3b860052f 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -9,6 +9,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -21,15 +22,7 @@ extern "C" { //#define Q_BUF_LEN 96 #define Q_BUF_LEN (1024 * 100) - // st-link vendor cmd's -#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 -#define STLINK_FALSE 0x81 #define STLINK_CORE_RUNNING 0x80 #define STLINK_CORE_HALTED 0x81 #define STLINK_CORE_STAT_UNKNOWN -1 @@ -41,7 +34,6 @@ extern "C" { #define STLINK_DEBUG_COMMAND 0xF2 #define STLINK_DFU_COMMAND 0xF3 #define STLINK_DFU_EXIT 0x07 - // enter dfu could be 0x08? // STLINK_GET_CURRENT_MODE #define STLINK_DEV_DFU_MODE 0x00 @@ -55,20 +47,10 @@ extern "C" { #define STLINK_JTAG_WRITEDEBUG_32BIT 0x35 #define STLINK_JTAG_READDEBUG_32BIT 0x36 #define STLINK_JTAG_DRIVE_NRST 0x3c -#define STLINK_JTAG_DRIVE_NRST 0x3c - - // cortex m3 technical reference manual -#define CM3_REG_CPUID 0xE000ED00 -#define CM3_REG_FP_CTRL 0xE0002000 -#define CM3_REG_FP_COMP0 0xE0002008 /* cortex core ids */ // TODO clean this up... #define STM32VL_CORE_ID 0x1ba01477 -#define STM32L_CORE_ID 0x2ba01477 -#define STM32F3_CORE_ID 0x2ba01477 -#define STM32F4_CORE_ID 0x2ba01477 -#define STM32F0_CORE_ID 0xbb11477 #define CORE_M3_R1 0x1BA00477 #define CORE_M3_R2 0x4BA00477 #define CORE_M4_R0 0x2BA01477 @@ -251,12 +233,9 @@ typedef struct flash_loader { 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 int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); - // privates, publics, the rest.... - // TODO sort what is private, and what is not int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); uint16_t read_uint16(const unsigned char *c, const int pt); @@ -266,7 +245,7 @@ typedef struct flash_loader { uint32_t read_uint32(const unsigned char *c, const int pt); void write_uint32(unsigned char* buf, uint32_t ui); void write_uint16(unsigned char* buf, uint16_t ui); - unsigned int is_core_halted(stlink_t *sl); + bool stlink_is_core_halted(stlink_t *sl); int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size); @@ -275,6 +254,7 @@ typedef struct flash_loader { #include "stlink/sg.h" #include "stlink/usb.h" +#include "stlink/reg.h" #include "stlink/commands.h" #include "stlink/chipid.h" #include "stlink/flash_loader.h" diff --git a/include/stlink/reg.h b/include/stlink/reg.h new file mode 100644 index 000000000..c6af166d3 --- /dev/null +++ b/include/stlink/reg.h @@ -0,0 +1,8 @@ +#ifndef STLINK_REG_H_ +#define STLINK_REG_H_ + +#define STLINK_REG_CM3_CPUID 0xE000ED00 +#define STLINK_REG_CM3_FP_CTRL 0xE0002000 +#define STLINK_REG_CM3_FP_COMP0 0xE0002008 + +#endif /* STLINK_REG_H_ */ diff --git a/include/stlink/usb.h b/include/stlink/usb.h index 76ac9211f..46e7419cf 100644 --- a/include/stlink/usb.h +++ b/include/stlink/usb.h @@ -18,6 +18,11 @@ extern "C" { #endif +#define STLINK_USB_VID_ST 0x0483 +#define STLINK_USB_PID_STLINK 0x3744 +#define STLINK_USB_PID_STLINK_32L 0x3748 +#define STLINK_USB_PID_STLINK_NUCLEO 0x374b + #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 diff --git a/src/common.c b/src/common.c index 727048125..493f1b90e 100644 --- a/src/common.c +++ b/src/common.c @@ -550,7 +550,7 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { uint32_t raw; - if (stlink_read_debug32(sl, CM3_REG_CPUID, &raw)) + if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &raw)) return -1; cpuid->implementer_id = (raw >> 24) & 0x7f; @@ -692,7 +692,7 @@ int stlink_version(stlink_t *sl) { _parse_version(sl, &sl->version); - DLOG("st vid = 0x%04x (expect 0x%04x)\n", sl->version.st_vid, USB_ST_VID); + DLOG("st vid = 0x%04x (expect 0x%04x)\n", sl->version.st_vid, STLINK_USB_VID_ST); DLOG("stlink pid = 0x%04x\n", sl->version.stlink_pid); DLOG("stlink version = 0x%x\n", sl->version.stlink_v); DLOG("jtag version = 0x%x\n", sl->version.jtag_v); @@ -836,10 +836,15 @@ int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg *reg return sl->backend->write_unsupported_reg(sl, val, r_convert, regp); } -unsigned int is_core_halted(stlink_t *sl) { - /* return non zero if core is halted */ - stlink_status(sl); - return sl->q_buf[0] == STLINK_CORE_HALTED; +bool stlink_is_core_halted(stlink_t *sl) +{ + bool ret = false; + + stlink_status(sl); + if (sl->q_buf[0] == STLINK_CORE_HALTED) + ret = true; + + return ret; } int stlink_step(stlink_t *sl) { @@ -900,7 +905,7 @@ void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { stlink_run(sl); - while (is_core_halted(sl) == 0) + while (stlink_is_core_halted(sl)) usleep(3000000); } diff --git a/src/flash_loader.c b/src/flash_loader.c index bf4c92f14..23f235b5b 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -293,7 +293,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe /* wait until done (reaches breakpoint) */ for (i = 0; i < WAIT_ROUNDS; i++) { usleep(10); - if (is_core_halted(sl)) + if (stlink_is_core_halted(sl)) break; } diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index b57a299ac..c50e5be32 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -585,8 +585,8 @@ struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM_MAX]; static void init_code_breakpoints(stlink_t *sl) { unsigned int val; memset(sl->q_buf, 0, 4); - stlink_write_debug32(sl, CM3_REG_FP_CTRL, 0x03 /*KEY | ENABLE4*/); - stlink_read_debug32(sl, CM3_REG_FP_CTRL, &val); + stlink_write_debug32(sl, STLINK_REG_CM3_FP_CTRL, 0x03 /*KEY | ENABLE4*/); + stlink_read_debug32(sl, STLINK_REG_CM3_FP_CTRL, &val); code_break_num = ((val >> 4) & 0xf); code_lit_num = ((val >> 8) & 0xf); @@ -594,7 +594,7 @@ static void init_code_breakpoints(stlink_t *sl) { for(int i = 0; i < code_break_num; i++) { code_breaks[i].type = 0; - stlink_write_debug32(sl, CM3_REG_FP_COMP0 + i * 4, 0); + stlink_write_debug32(sl, STLINK_REG_CM3_FP_COMP0 + i * 4, 0); } } diff --git a/src/go/main b/src/go/main new file mode 100755 index 0000000000000000000000000000000000000000..25baad2edac802c6e79e95b5578c84591aa88783 GIT binary patch literal 2777276 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%0A%{`UF&5fPPp>dU4Ih=%SRpoG1PVCCz z5Q&J4o_wyP<%&{<*-|M)xj}Wiu8FGqvCZT=4B%Ql|0^bXib}euGJb1f}#mS-jn&d^}|{=Ks4J9$Az<;&#dc+ z3Ypl0m@+bVC40v(Wl%P*n8bs9CC}rK$$hP&Si82fW-XblX%5y|Enb7Z2H7i2U42FR zrA||WkHZ;8PT0(lNX24FQi4=hgSw+ec=Xn=WrwVr7XYmZpGy*4&qS9_&JIP_3wfbx z+4_~I)FhJi@?97D;(d__Lh=RUze3a?~#0~mj(Z`I%*L5nkcybPCt zV-vzM@Rtbex}rf8NSR^tCVK$x>S9%#2h?EqPd%D~aIWw+*wN8%YF_~P%okE_)O@VIg>PmnuF?1Y9c)Z7os2@UtiqvZIG1 z|MFrOgGnB?Hh_~OkNoF6fkwp;06d%bah*&;Y_47Z|8tVrMTP}%0%B_iLrkuAQml8z zMf-oHY|M<3TT79`4ZJTioM<#meLxdQpa7?&UKQd~P3oH=Gju$Gff@&j*@v;}4##s7bDw6AIh2 zSTDRw-OQ~i#!-182p!X6+pw)Q=07Nsw_)(#T>mWo^8yydlFiuMDfq_R)^S|8g^hHA zbL4lU!UPoS0ae!Vztd+gO_+w;@zx`2_t#pb&*9HCr^3lZg7aHZ9oq9^L=yXB&;AqA zVnGQ9?`{gef#1o+nHS-EjQv)y0EUCN^Fbu|<)^I7_173ijI%<<*Tdbf+p4eg)z??3 zuREA|C-LhR#@A=KU$1*n@=j7;cTr#8)i%~%)j)xBh9~6@>)d#X72dHp^FD>~8m%%M zoZdKz{Vq7+W!$yk<76AFEI0;F>K8kYQDzp{-o2nJqWj}uV!@>>2jI#1Qc04`J}0O@@>5N%~5>PlfEg^CFp#E zUO}rFpL~sygD2ZXmv;7B?!c2t>dD)lCu{kn3rkz`7g5?~NNI~IZ=*+}tfdIkAu6(@ zS880rWm+K2_?~+xUa6BI826pdp^_#nOfu3;C&U423?#%^b44L2U9>m&>%}Qm;U>r8 z3FZUaKc28gzW|bMg%Cb;>tiYZOYoxF@8L?+Ofnq7m7Ltsfg5Rrs@zu*Ee-=mNX|!M-TypTJc2BG{(1Nvjb;0FG=s%*UYLt@~|rb!40*xg)$KH0c}&Tc-B-?u~RU2ZH^NI9fa z4k=_aoeam&<}22mImmxuXy;(uA0!}7{m|%l4m(boRPEU(P95|a_mtco%>%(UtwEFkw zc}rg8e$$41IQCAG3>#lRs;*Ruu8JX*YX+K9VT08AZ;g@)09gSPWa99FvQde$1sS-= zLemoL&=N8#$G2ydaB#-Dz^sa?418(gI5vK}Uink=3%2un-}?P&u-4h%9{v)4yKk$@ z-^?px@b}xrCVx_f+x`XqiX8rC`tjGg0sKAxSM--0gTIAW#Nh9ty81ii7q9+KLX}>2 zvDP1a5p-zl?<1&g5n6d3)j?yctlm#SW2bvG7FB*_vTD8lH_9GEx7O9y=F4O7bJCzX z`WjO0<>wgMBX>{4I#hPSU_o%4;vvg1Kk)E{b?1}d;cSP8zeE4jk#*_s9E<+vv=OR0 zL;7Q$v1~5`-(HWGv3lcZGRiEOo<#9sEtu^`{|aSK_0|`v1{B9VfXGIT@s3O&(ai~6 z*dVRjI(yWF2&q}y?|K4!aUbtG z_1|AAKZ!B;nR{srjh*AE`2K{><^P~T{zfztPW6(cWSA8D(z490OQyW76Z~7cTc&r#P zdpB~@%j2Eul;^+XpVDutTOPjBp^Ar}+Ww|JNqHFfT?6#-Z3F$&rH_KMzwe*&Z>-Bt z%UJyE$}#y7|5UoE0sQiah!Vc*?iLlZ!Y059#0V@IOYs zC1Xq8@?CzR619i^pD!@wFZ4HQ2>rD&@=(L$Ujp`Dk5%e8TMB!2AKro~8&_Q}^Ci3duh zZBuqozq0-a%kM<*UID^Q45$1*I;}{>Uzh-?+M{U1nx_?^+i(C3z`F7Qi1RIU0yEge zzo_;BcW8z@>xr+UBI^7hb?u?0b`>6JUUOa@X_kIv+e7^kHM5gYJ{doFGI9#25at1Qt&|D>}_^OOi{+j@Wc zCzjPuf7ANtKTvy}X3dffCD-laO^m_K-0T?KyyYou81am=QZ+a5$@SWwm^(90wh~6s zo1ocl^zNd;9@SnyavId++g_jPYj4cZsEs;Gf3;UzABJM_S7>TWh9~-c?$s7H%|Ee> z``GnOVga@an{oa~m@1=}V6z;S_N8^@yzxS5Kg-ro z6#X(-S#P`(MgMZ?mh;j-Tn9EDZ}8CVb?obhPrdYaGx{H~g4#pBeTH7BWg;2h&^?YwcQV zn_vBvm37-lnqL9C_hMC4JUXD>+Uln=hyg<*b^QB3$iH;VM)BV-M)A8_FQik(+Fbbm zqyhXNJ??MtfA{}B|I(Ek#lNl>Jo-OOdgX2X%joy6H4WhZv`8|I8Tr zKVhU<*cJb)8^Hg>;=iH)srB&xx8eg!`hvYIm-mUm@q<_u-C(@^zC%~Nb$f6!d8XPNJIfx?n>ZVxw*P`g{FM|TMElTklyUI)Na1bZsC@)U} zT{juEXPx%C%mMX}2e8|W+oXF_x{tkNej(jZQDiRcWtxz*U)OwSk_lKG(Utx7>oe9J zXC2hFHTI0m-i6io>q3?LafGzj%TfDr4Ubz+m{ieKSRzw`wQ}UK)P?e@_Adjy`tpP zB%_XeUR@bWKEcd=`TM&ci_>^r`E)SlKD@^ zS+T`*V+q9cgBFv=z5|mJeEZL&OnU66P`Zb`@_FQXB??u`>SEdQG*dp}f~J2EOFo0P z6mB`L_L`ZleBytF33W0>DceZqlc*WJChbb;f243vc(@k-S7rSnSDK0?QuHrndchRIP+1GMZP;Y0B zxEzxL617X?NVB+(#g($`WW)q;6j!*L#YG@N?ht zD1IWrkKYkynjMIlT@}L2>|!v})8h`K`%7d3eaU9T==8Ak$DDH-DE%+V!acMYIq$UH z5M$n{`Cf&{L(e_M%b0s=RS&M`6qeS&x{R}Vj8)qMrXI59;u9Hj`kHT>iM`E ztTmh1>nnL5V#V zWUgleIs6f`7Hkd+#t~JxE4Ud4e`Wzu6e^q*Tng#pR$uh`Ru;n08pctnnSo4Tt~)=u z=HKXIx(9Pu^I${hg~ph}iL^m1b3@{}{}ikc_e+s@?jNe|@5Q`w&;9ARf%glLSdSFJ zjQinNo%(+CNZ2lvh|X~=RN$mmNIs73b=ZtGt{+Pk6e`6CbNtTWItBYE5V#6Nh3IkS zB>L0VsBjVH#xJ-zzQQP4s2ptxPV5A;?^!KL%owmoV(>4jJe^3@mu${g`9jR34E;0NFn)%-^7?~&jnaUb;rxpO zqnp*t?Gui#nGtPob>+huzqakxXa6zev-3(;d3vFZzy06tm5)bXfyv_3N;c)(ulu)(v@6M=)%ZW^LW@ zbF}XFFnPkUX?TKY%jE)4$ao~pHkZ;KNt?}OQJ<{s);eq~I6ed~)-CUK~7n&s+7mbx!P*2(X|b&lec1Ogd@!p zStCGu^(T?Ou3v>VUB51sm)&)XPW}3t5PvI!7BA)CXK7RtE)ChteZwbf=lcwwVFLn z;yuS#j}|aJKI2AJV5Lmc_x_CJ9E} z@41|>O#D9IaPpsWRvbT&Yl0+&v>bE ztV`ci>v^BR?Re{p>;J5^3aGzGF!D$$o)Jo^>yg~vak3DY*-LHR%ll1 zkq?#MihfLXc<2p9e>`r-gX*_F*L$9kY7iYq^0^pTeyC-Zk~Il3vX7z*RtbQPEePa94~*i4QDFS0W!3(n#vxQ)FR^n@E(OAiOivGW@- zdW82Ic>vL0&>Yrzya2EWmySU`H3Q&=;_`0vzB0)LK5s0Q`Kd!*Z%G;IA0z0L#5S zfLhDn-Q<>($u8j9DnFJVSAaWX8TKOv;HfU)L|?!h1^8nuz_AA451%+Jck>0@i@_4G z{9g~Cmf@ua;QcP(#zlTCzn}oCJb+q;?F_&(UBG*N0WVX4_r(JI`bJkNzprsvKEoF< zQ2|~U3vh-3INJr>Qt8L?TNufK42wO0T81?S-~}$=OkcpE3h+`7pqAkW2H^hH4$J+0 z0S{4t2gd@OU;w`40`95sV|g(KXTb836w|?K3eye1D_y|neE~-)z|vTNzva7HKF9^k z^#wdy0rrdqIL`ol=VM2P&3pmZV7vt^?>RCC%OecH8(qM8@B7KHSOHeX0!%dklU=~; zeF0BWfXN<~wH-D#0GEB_u-w)c@EeSofaRZKQTWLXu2M$3fK~7Lu^dr=XL~5rX7j26 zc&rO}n=fE51=uPUV7>wPsePnGS@0-dz#0szfaS%pSU%DKEO7x>a}258aPCnBc#x;) zX{9`C0G{juj`s!3R)F8dV)-fqaMOp5mb>}_?p`J=KN$DZ-W`MF%YL8GeqL_`+7*6elBx}1Q#4)7GGI~R~9@t z&n4=Gm5$ij`w~^TRK#}q2sU}_z#oUSFiu}`jSG003%GQFx*a?4AE^NQcqrsp9{`IC zz(g0Y&=>GX1-M*K+fz*w)us=2Hvr%Iz+pMn7w{uCf+E59+nO?zACS$SpHN`{ZlgJ zEI%kEU;vJC0XM$w$MW3@@cuTY3^j#IuX1I0v~|Z-xqMlB4POqJ;BjaQm!=sBQD^cxBOUsMgi_MEU^8F9S1Uz^FXWpPs?GI+XBmLm zF5o=biLt(pkURz0Iu?a34Zz(PyVfjU?+X}EfXkCirRXZ4>T*|x&$)nYeF5LA5SDxN zF#&Z+xx)aw#09K+)6Z;1D8Qi}3bj%)48Q~z@HSt-4hpbKEWoXoxh%h7pHG4K$QN+s z`@(W*mdUdAhc6p|gI&PYZ}_o%hXQ;oU;^s0Jk$XEmkT)F7qF88+}7I!)Jh2&fR$B_ z*>v>qZ1+$|P`KjgYH9O(jn{kk8^Qxssahe9qxMV<1P0eGYfSndmWngYDQ1E^WP z+yMM&k;8INU%(&V6_&5Q-Ym=9nh_MXHUP)DfWN%v$MOsXc*wz~QnZ$rU+T)RvkUl$ zFJNB>{vEx&32j&K3Le94dHQUw_FP^hcXd;_q93mEnV z?5+TZdnnYc(IXAOl?xq~(|rNIdrMgE=>g;}tYCTFMXn6*Z~=dw>&NnR1$cK))39~X zix_~NT)+o?0kag~?afUO|MOOje4scoS>jJ*=f}ad8SAeg30JWAMGyu1~?XY}}FJN;8c#)n`tytDY z?>qzWNf+>7U%>fqhzvVca01^i%+AIk*_aEqSI?ylw!FaRGmL){o_T6yS3nKwb21 zG60Wr0q^$(%v69wo0v+`9{VT*@Uu4^me2GB-295Le29la?GM-IxH2qt0e}CuAIpy^ zz_uPhHE%OG%K+@|0?zgYJXZmJf2zr{nur*@!~p#64Tt3md;$M>Sy(>#vKX;VD+6%4 z3%LIoKbGexz<3X!ZagmT@5(UC1$@aD@KOc1x{=AUE_!zwfWN)&uzaO2U{eM7RxH5N z4ZtT{z=M1N-~5lr@a9uY3bkSXey+>%c`o2PPy5Mmhypy-L!quy<`{r~;xGXn!QSW# z*hT?vjyEaPCFL3e@I@Ce*%xrpOTzN&u>ji{fS0>~%bxOM`BnvZd3TdSEyK^UT^Tla z0Z01+rYOJ+4RnvfFI8lmg77uYo+uz0B>*sKYh}V<+~JMzyoNv zmkq#nE?|i-U>61W;K`;8b&S0x7{-kL5B2 z*wzE69c*s{@E8|xnlIq#3UKW}(|uv!k6PY&j?3~VFFP#v_64kdL0F#H&6J_0@FfFq zf(!WTEI*bXR)BpxfZ7g+7=URm;N!l4=P1CqSS%lI0Dk))hvgh!z@5(v%P*(JVEL1? zT^Ziv0`7gnkL7;tTlxbHeg`51=k7{SClNUBJaN{aC(P0Z#D%22@!- z%m8fa0*>+p3@X5%{xt1S$Jm?txk`ESMMs85`vQLWtg!r&2T&XK!v^3G7jVsEek|Xq z0Q-4Z)@E~!0ocX`EcOLFK>@b$0BWVQGXNL8;IMp>FW?vd7M3sau&j&TXMJ56-s%E= z^Qa%oQx#zISb*gQV2TSE@dfOm0GIDIwX7-ZYXE-yyu)%YU%;Q95teW1YL*mT^!A+T zvV4~dSo4S<%MU2PGh$KrssY%=1$@*Ou%80l(#51uyRWGR;8$}Tma}~Uw?8c`xAd^A z?Xb52Smpxme%O!Yrxf7ISQPH;zzY@N#66~#by%@70dVHYsL7x3k$M25RNn@Z6R_HYC692fA7hx}xCwE|rBM+}xf$#P}5^I3=G z!M=d46yVTU6ow7Jf4hMH@&#P@q_BK!EWj)SaG(oV`Jf-m!xZ3GyG@q0gWc8JWx25n zIMNsJFa>yjEWrO5fUo`Ak>QcPfGcJT%jbFkwH;n>0AA|?e)NDJ%VQN_d@R6J12D-2 z9OnyoyaJrR%aoyRFK;-*mErr(I4pPe1za~vSRUg6)FtIU1Mp@SaKj8gmM1B|BTk4> zQnC%epbL1nFW@N(aLZ1UWldq60r=t54$B$7fZsnMEHCU7gTl8mT^Zi#0$TU`v3#Eb ze9=RpZaj`Q08elMAMyq4qW~ZEP^c@ZQw_i`o^n_|+ZS-_uJi2?YO3)svT@a>r*w(mBZrl(8Wn+D*8F5tZBeqzg4fERiw)Dhfp z12E17yxteEy#h?}0P4EEy8-y}Y)6J|eF2v~CM=)i0n`;;3j^?K7qDuYAIpUb@Vz5U zrDzI|G5}k-fVcSqrYgX%Jxb9|dgH0C*({vpuzZv+;Mzxp<+*2?-3)sE-9rZ8Fc)z3 zy?!iDRDgGS0Cg|v`3B%&F5q}yz-|ig1&>m+KS(eDS3Kdc+|?Iw<0HaywFgj_lpjuU zWjNLa{Q4e0mhV-7i5`}@N)%l+-3rkeKWqS=;sQS63)o))_VZAv$N4WX0KcE z>thbfgM0y-DZn@npmwk)8i2E0z$U(c^Bxo#zV9h1n!@k8yCvm(7x48mKN()H01x(1 zsAc%70l4o`hvn;h0oy9T^Ri4k)b1|t3`IK}|H!Ue3j+mGej z6yV-p%xY9ea9s_+7B1i|zJNz5z{6@xK;4qqce1OLw;yq2c!V$D>KVfFjUJ_F2iwx1 zFy94S74~C!yaJr>QHrhtjxhk+yMRT$fL#^fa~?olmRlHrOCNSvKG7HO>-&Y}(H=lO zr+bAV!$KGE%c*`Wmn*=8Bh89l%W$dznCb$CeF1wa!2dp^Ir51yD<**%6=No*NsQSS z@i$`3_RJv?-1?nqDLPm<#vtlmJCm~D4^#ZOeD*#OTi^#1P@CSD-PD)d6W|ON@P1#w zK??9!&(a_rA5Av^w>;=5_Do;ECJJzbheEw7Eo1=BbOC>#?8ox!(}m?B9zflAs7-TO z?(YK5_65970bU#naGn9U=K+W13w!}vE5H`907n>r&%1#8C;72l!8S`IxaNCP%UXu1 z24JoW_>wQ+EebF(7KIy5a%I@e1-#N1@CXI?`HTY>j;AL&g`=i33Wpr0-W2Fd6TZYX z_vXmr-W=OYNr$~RM{xfRb)5RAp4&}vyZQwjVU7ZaU9bm8bNo`9t>EvVQ256_m-e~jV(e12*E-|kJ+;~4rJ=H(R-15K zTy}Vwbs}!%blRE|E^3VPvlk~`(dX(u*IZQTGpNtNi$fDO=b~Yk9p0Z)cI;C_4~{#pEHyPJeEsTB!@ZliZ_e( zWlOo7Gz~5;bmAo5%?>x^ds~|Fy?3YLPPd&_W4t!0V(jhN?}rDSa#Wk#W8%*0wk0R> zCLa&QzpggDp)&a-C%oVK83@?ErNgna(el#w0ks;pb29c8T-0a6zGCnZD0u*XLuHeQ zb#AzH%W4u)yQJIBobWE|ZoECI;`TW>-QtVu55{X)nwUB3{Db4(J04%XLu>v&w0#SF zQ$^Z-N?Ry56A%CX*e{fHAPm`5U6fV3Lnfk+aWO^}WdU`U`2a%r)m_Y&LjioemWdP+qjB_uF zjF^N-_CYRN_-MQuO?$sc+p8Ba155JFYB9poHt5GAK;M;v|Gvh5q~4T%ll6_-4t*a$ zqe4}`ac#1yH#d40;vF=oy7GlZk@A|=w1QKl?bfdXX;Ea};vy}f55#Xo2-5HF^gHYg z(tBk!H?-ULdZh40=2fE(ecGpbCq&TJ2%druN$$S5QMI-FXlQP8`ESu?1Eez1YEet) zK$fC#K3Y&NF>Cd{$cVB+X*eA<2p-Bz#{c_3H)0wk@9;j<`YQ`6S? z!aX0EPVJ{ZZ0-iiMM(C#kPPjeB#UN4s9W)0roJIxr0|vbcAMS>Deuia72;LK%1=YR zeulg7v5RoA5Au+zQOGa!MzGkI<{mn=mo3zuRo;U1w;&3Ypk*E9pxPtL9~pQF5kYIu zAhaQOEfV6*KZWyfS1-dY5>b?-b@AE`!$-PF|wD*Dz=5;oR^wzAO6PLiT z!MR=LzC7`X`zkcEY3`}h{;-D1Mt`FGk)D0g>d?X>xvNmg1$$HS`XYUnj=rt7?3B^B zZ7w@?^ysqFM&CB1?2OU3m6V<73pM2WD(ag+;|m=+>6VXLPxMD}ny0PtM?B3#e0@crX{mZ=CAFp|1M8!tJfWF?MHWg3tk^pb|t17-s+~ZYgim_Dx^soBpAF zX`f^3xA(Iz?P0Iq=CCgv-lhKAyz%y>IbFK8b#3YjRgiq5eqqJ|7z_Nv-MFm20;MmA z={>8UyQ-~a$KZ1}XiW*!xoW4^+RzlF@fp|?{8nUyT@qf9A|(H^96cYhY5g5%gKyMb z6?HFb+i8oF6WOaTrU>EeI=Zuh0x9Q`nW6SXSx+ekHQGcVZy9+)*?`mSP4>rbZIhdf z^&m=iHyR(ZoU5`dh1($CJ2 z5H+clM8I*lKUey-$@F)mrGGIqeKZEeXXsOHMm2E686fa5XK#Pb9habE!%z{+5#di$_J|Y(0>0M zK%ds^tJj^O_ABoE6FREn(S-fsv4fGxmnCGe+6Ve+hxVW&?J*cUl+rf;?4n5F#}v91 z{>5!ydg;J??lTYRzy7)>;Y+OXPp_i5l*~7J&7E7|DW69QA3Dz+h~W-LMj;rvyyzDy zc^D;9RdU4wo2~UX2zyY5O{XxL)S@|`hcFNN5^A=oVSq{h>(_qqhZhc(#hu?HRn&Q1 zlN};P5U0Tw{o!%Q@Ov~bQRH(WBgPKy&?=GIHvcRb!*&YYO647(%DY$Zsmfa^V$y(v z%ex%WQC^i(%dTJcD1R*K^U_QF+Frkge7e-xoH=of0TLxs+}hfeWEAeuFNv~Q-m0(5 zPjce}T#*r#KB1^flqtHGQ6i}1^a`rt^PrZm%Et<_DOoNI93-E%20g~flEN)19H1!J zDzps}LFZ|YHj*L z!I&~d44838_6HbkV{GI=`Kf1&O#Z&k22TN6QFQckmxqhL2Xl>Nz6#7KfrXdRM}REs z{a&kwHxF&Q>pHh~6#ecK+GfY^3p;7`72DeIv5ESY9Ktz+?e6M{owdyn$RQlgVg3dZ z4MBAv+x{}!zEIcdvmr9{({LA!91{9Xn36!pkojw_v;@Q^$95gWJ}F%MHPU}NQ7B}I zYSYQ83W6mx?`vE6=p=`%D{!QeKPr=7pO#!!k{iiaC$K7b(!8(T+Ul{epo&DV989&Y zmVBQHJwnbT-)9i#e96~8jZf-p>kMZ-J+`yYU{PJsPB|>A%)4?y$&6 zAKp$gkA~u^z4pp`p%j1kN=MaJd*!qE?W=EfBIQ)1#9tnMmdc;b&{r@)QWu(cLi<9> z<7J)EWozEJ{f#EAIPMM$*$R)L5?@}m z&R(?yxwTG_O21aJ-G#!gJ|6c`X}yT5j;yI=A|ykW<7A}Lv`F92OGY{Yk*d~}_b)t^ za_H@EyeA-v(aDA$u9K~GV&PB<=w83ATg5ipFWI)%VcJ_2+o?t>4veIr-$1HL9l0md z=1|%kTWdEY@@o$ep*wsT#vu<+!B2nqvVPhozxKvV0AKxgPQUi>TzTJ#D8ba-YWys8 zQXYML75fvYv|GC)6N+rZ_JTirVV)=KMe7^*2aix|J&Nir*vk!=hP<6nQh)dX!LK#> z>-BEMVIhz|d=KScgmHQOcirg4%oqpuK_Affagd}j#O_qycL;2VX2HpFcBXQ6wuvu* z9yUHo_J0$EXb%%Bk56WSQVt1(tH7Wj-=P1y>=N=kVkB^<ZkU3kAV#sGW8 z=pv3Gyhr*QmA^}-^`)iVc}HgcF2np~=85s50LP^fypSYFl=#r^hE~c>@=p8G3HgN; zXbWX06b5lAcQuAwP&55TQ+!QQosHJt+E0d1WQ05_L-JF0p-)04t*6OY)SfXgzwt7N zA|~6%BVrwGg30OaBYXEG&_%M76XWmDYAMqh_N9|prjw*hFx51foHFOX!|}ELX4)DV z#!}_Tut&)$%DS7@QhU42CL^&>pG;OlX^58+YFbM+q)OI@$Nt8ovwh*;;l1@AXz$nW z%F~))=pOshCU-^LhPLh3-tog4wB~v}N9!EgZm(}SDzq&-lJlT8F(XLp4M2uiv(+g!3(+S{q-$Q?UVXlIoiq^)F#QM9~Fv2wi+$8knVgtPJ4ARet5dp zYvIT612WcYp(uV~;IzsmPEQKk- zFoZ!i@862Cyter|)NlC!>d3;bQu`Ypp)Z4%NsVn1=%JcnlbbK5=06Hz9S0^TW!LUK z3B3XT8I7mhay%ux+Oy{got~5uK);0Y_Gs-Q^MOJ~t^k_SC(_3qp8FNa+#iP$ko%u0 zcOT_$IG#(-{}h>jU7Gej!t}r$O1SYYAgUkNT;sgO-Ei*b7pbBzl9})M5t+Y>|Aafu zDF0(@5nTk{xsM^4@}R+OrHimyofRu2*-%(KH? zG_#qwA3E4)&Y5UK3u&4p{Q3{@Ty;Z{xAg1vZF>?tU*^R;(IA7>h#>}781SnBe1bZ^ zN(AtDo92%l3CfKb(Wbv0zk`Uxu=9_z)jC=Vi|w4(G^Md_F*eg31yBelO3@~=l_C}%ruwrq8@VB$N{ zvBXTt^DP9)7)x9zL%vSwLO*!RVPgqrvMe7`SyE$(;vdj!t8t86{t~6anpS%KsPe=| zi}HK~Z>q`@L2hKrYSk$bt%YJU{1MV)R#~$QA@H4#f+f`6sSJw}S!E+IFS-CWvk;s- z2ZU!km&#Ct+YhH@bs}!A>;#V1vk~%KT1Xy+p!=4UUi5lTuB7I*)O{K-0EMr1%i4qrv4NDMQ6dpDQb9cCx(@}(0yBJTcjx`Lk=|wyD zBvPr1v;%sdGy>I-?DyXfB_u1f?3}_NaQW2Kz%<1HMLmR0L0?}AwOx_&->IQ$hqwzU zZj|Dl*>U`w8npVu#c6G;NZX4g_t6iVw^I1^PH(LQ9srVq=}A)banL5q4YL$kT3RLn#ACsC_JmF zier;04x!@edL>hMkV3?6xexa!EhQ_`T6|d_%*ID2az96Fk$HWMl&u5(*e=V5gCgT4bde2v~1 z4Y&P`w50{V43*6!$Ip9W+T&#iE!Ms-(q5cP@j_q!f-OeuE6t0dhbq#_YweZqA|*DJ zqP~bL-=}$N@H>WUH8$udjc;GGFVqC9^#=Wojktl_-cB6EP9r|3h(zfg8LPn3atzz3R7%=-HAxZQrw4Un#g zwwJuMxE(DDi&7V9twlq>nllYc7XHY5lyP3NjORy&JAK*~{r(mxGcw|IDa9H{!J_G# zXVFYxO{m>%50%5Ckm&BLwf=BtG5Fi((Y{TT%xy)z7ei~s)gqILLXl8!)E~ZE%;yVj z{cM;P<3FE$ViO`RCcPFWc91$7=u%{#gpFmLZbL(U_#INYx8Q4Uf!ZIEMQwn-8;VE& zYQOsp)LfDFm2c>pqR0)2(3Dk<=eB!3PpS9f;X=Ld!xQP9Q6e75+N&18 z6|$mHg4*$s;iFNmL`eX7RYN=Y2%dLwabzrpyHus$=~wE|RJb_k&sy)#+E5i^9os9f zg6@6c+&C?miEh0wdgMAf6($>SPb8FPlZ!lyP`Pq7Xcdj1!_QDd6}qI=uM@(>t56+} zog<{a;oM|(6hZsC_eM-F!sQg>b{XRllq=OEoQ!aAuOK6r!*l6b-J!KPX?aq`Av3QQ zN8>FYD6ri}J)O$H9 zVhLYf-qdmi+OV85JVT3fV#=T+dvtB9zQwrtulNsD0@YR}!waF2)-O{2P@E>HAv>l) z=b?hVvjekbmekG#|egF^EvNQf$0PTiunU>!7~hY*Dh z7f>`WwRzfhY`q#%B(UHirS!o}D5EX<(Uj3@uqRq4BFbkX3T^(Mh0aNOIBYuQu1(%Q zh3@xFwv8XZQRzMC3SI@mWXD&rmWrgtv1_hNl~Fmv&1doX{%8HYN&;J~&5 zuY-eF)Tg`yBF(!IWw2NN3MwpE`of_AdW9mpr_DdQLE2n-69O==uvgNmA7Z2|)?G&? zTV$WuMgnQn%S<5KUgp=nglT5XXW)9ykMwZ*wB1ERxBEu_2>RXE*(bf_k6fAK!}6yX zJ#NePYo8a}JwN!W)?H`!Y)%>Ji}|9tp9UwSUyY6Zq>(-i*--~EcVsv@1f;D(ZC{TK%}GX`joGs z`Zq<@(Uju^5rwMmc0{Q|;n{pIOvXcYx&z1qXN6BKrgb;68GnI^tIXvDG=4PWpT9yg zUXTBh^CPametvDeAD`sY%A3(@z1j|UXh$|VH0Y}ALh{w<=%{_|LSiVO*%NlN zcg5GTM;US3Swd$Iz%W^n=x_9sW|Bp+hYpvoN2h@<8d+X85(92>sfYzFC$*bShJJgt?wPTnr?MLpn2tNT8i5(ZG zvy&^iO+cG1C!Hy@y1Rh2>Rv`sP?hgo2j(@PZ!cK4*ZYIB?09r=WKg~j^wDeVe|^io z^h5iECSU#byrJ*;$lo$L#? zV@QIzk-hR3R61r#_Nqs4G;~=Dlw;GaJz$dY>U0#5Pz6n;GrTthyFs&S`5s@Cfd`joJ3f zY4D$dst2Y$Uz|?!lfq_|X8Er7{-udS0Z2=>HxJ1v%M}#BdCnB{%X4$GJBg@>M>$=r zqEdj0nkFuW18b?<6?8=t$%6d%SK6FkjGGgaxD6o|GA1XQps_5zRX2|*ql0w!B z*j<{eQ^CT@Ma5o>^Xu-4_w!KW9&O%6X!uT<>ZVjG^kU&@Yaz2o+piB~Aw>Qj?EsEl zNb+?;wa9Nc*?D+c6RCLDHL`?sZcJ4FOm}EK=E&2KQ=vZWDBE>4Q~(5Gm77_r$M#XyD_VLLwb=7s%YguG`NFJWHG4yU1ZQ90`hq}WJpowCl zwGj;#jkonE-alqr@I>bR8fwq6FRZsOT^AXE9=MY$)SkVp2O2jzSe9D*LhgcNcu5U} z^Fy_bltSb}2-3rjtHoMpr)6l%Sgs$xw#vJ)d=ZMRPlF`x@FFs*iUa-}`18t%sEmpO zees*rXs@~nSe3bsd?wN*Ju5ZJbwfmn7sH-}1WC_Yifl1Kf@j5mY_E5dv&`uaN2F_Q z!5626YxUSC>?hyq8QP8=crAt)Ra~EneY@9UkTS5X4eY0L9X@POxJn}l1tZWzh?(Zi*Bn0@5>hzBNUaYonmcQYfrh} zk106$Do>tLQ#J-z@{&#xV;=b<93oMXVdvMUB_krCG- z2^#HXNFsQaqgJr9;y`^Ur=r`ygXNbxy19bF#qx?Y5cje^X;Crjgn#@|-*A;oL1BoD z!$mNtaEMBXVItb4dzAw%4lU1K2@ej(n`5tf3P0SdC`rrH^fP(bC3cD^)=RL!mOGF? zwI5j-6$i=v+e1M#!1`7@D)l~ExeJf-H&#(?+k!Nc#D6V+LAnkVxVIvs0vqIb1ACG7 z1zWOHb?8J&aWH5@R?Azs@2+!^bgM`kv_ywaKon6R!%K^$H}5#pLU2u`nw?p6;%(U)`8l@+4e%3ba{sB8_q#v(#?yTk>HAh0`Fcdgj3gN!6P6bJI3!Uj-|Nx7LxXL(mCQCW!X=aa zL^g6fI5D`}ITabKfL?!h-^cr7Cdi(HrYG0CI{O188d`*ZSeU9 zklzMY9G=>uANT~rYdK;`dFUPy)`HZQ$L{@6`ApHfbnM0-K1nF!I@oloaJn0^F3W|e zCwVv4f0f;JP3YZD$oNk(@>CTWMvwY{D4*(fq@Zj>4Iv+GOUpfI`A9TECdy5z0=;L; zP7E`7067r@$d;2(bQ(k2s{;6yZmP3AhgoJJMUh7{`b*tqw@%|5=VENx@-b9S7=!jP zo=9m<>o{&|3w9$!@uBUZf#uj*b|$0S@A)f!V?NOG7hJUs^*{9TM9T6}A0uX9)xZ}% zui`BlQil$lbn94OU7E+=H2Vzc4eSdZkmB8ic}5<&^1CEPb>G^D%6c;}Torkn7Q8n{ z6$Np#TP|Uog{I-cZxUr3u7;yuRS*}sEd1Acsu=yM+i;pFA9{30@(!C6s--vVw;+ab zi~icjVs$QZf@leM!MsIFSe{56N+`FkpM~vnS-(zrbP5uE?@aUNx02e1-TP@;`J|=I7x2XLqlC;-UYGDjc$CU&2<>RIy@8$_zWIB0fl{ z;zJc*St6;T5~tR*G^~!?XdHu^mLRs6N(mlH;u0h`i_+G(i+BR zX@*PZ9Iugb6?7~?4~WE!a{dhGV+*bb;(z=252_}AX0IfROwTRHNga6h${gt`FskeV zYHYjhhdoFybW+wIy)>*m1m8d_YR^ulf_Gj)_j%EXXSM&*cD*NJA{sf8J2@uZS22&Y z#K=mlN6~UQ8vSMzde#6@8Do`XV)CjVi%b-04CC-lG&T(`mxXSsD&Aby7ikM*+NWvM zM#BMYXhcQ~kT;j4hI0D4OQ{#6bsRo;U|4^t^}S#H;m1V{9>ff`9>o4|6-{brS?G1@ zUwoRk2`8@ZFM;Ce>?oQGolo3_^@}>(LS-b%@L-y^sc3o}2edUz&y)MjIH~Q9T$T`% z?^j{P*q3P1?|GljYmd`!!?hU8pOL*_afctL%-r^Wf8ox4oDQeTd>;J)`!9(GWK#YL z3Vix;LWASTBgjD!8uF$~kX{}gT}VUaRiel0M(5pS**uZizlIKC{z;F7cp_t~#02!9 zoPc7a*Pb+kLo~298nV9f8sq5IkgG?!T!(~9DhiJniHX0T&ea!whWSk$E!4^#t3SL) zE$KY{EL`2Is4=#R2SSqm%AHutA-ekS#`)^^pPco<4ePGOYC+Z27#jP-BUhgZsrB2} z%Ys~oD`ak&#DVk-qdtvp$|1VDuESJ_I~G|xeNZv*fz$(wsg0;6;VEfqbA%nsyT^)R zJ_<8S>sZQ5k{!#Bs$+Rl#{4T{rVbXuG*F8Z5k1+uWG%|WhUts)Vm?Xh@iocvTFc13Xcc|$>2pu3pZ$qe>BdtT&N~kZ9 zJV$8Mf06$~zLT-7LC2Ha;mX0ZYP6D$Ohu}{qv84f0{cA+0DUX6gWYV|m_=eu_MO?c zAln(3%K0OA4#q~)7Jbh;G;77rrEtv2oGg59Cup! zBCRiUU`Tln+#ZN>w`Ai^u9(2I=h^RhkCH|DCg?IfXMr!P83(Q+BSL+J7B<0ZSOt3i zg|hT%r$>KJyR7o`=*37tr$;XX*{W13Xsx{%r9F5bOu-k)?GC{}Kb$W1-?dd7jNrcg zG4kua$bhQBB=R+w7b1>Litr4`#9`C;9Ny99bZ^R&(>*^tJ6*~H1a8icHh1a z5CcaTCZ&!r?4|ROXo5JZ(TMX4jYXr&m)Y;8hewX=0Ki~WQfBH!#k_P3r{wt9bS09Dke2yubd7gwq}bx(|IT%_EI&9$){^@ zZGxa!b*Bx_DQR1Oa>H{cEsKe5)qFS%RA&wn>suR)&%36bU+Sk}k8EvReJ4zqH?T zBh(D$w|j}=bx$kaEy$oC)_NjBpOc|6csMo>da(T>L=Y!lGbRwS25z7gKT!iO!7Nb& z3*JTz{2u=q&o6jlt55^A*k4$Jy|sc5wI=tzHqE>6@C`IP;??Q!4YWG3ffgCD z+aZc{H3`i%_Jp6DKsg-8@Jz?LU@z3zH}&3YSU^kNX43@r~8cc9&N^Y%vvszu_vTr%LxnZ zmjCQacBtAH9t~@%Gd#_ZlN2!?|@!>o>fdFY}kWzPeGOQ8y!gXyDFccg@>tTywR|CAufyYGKBSqpSOS@_J8A~ z5Zp>+K$b7NxE5+6ooicgP$;V32u%x>R>ihrsyOt(>wme zTD*N>v3)@?nm-S0sXn3On)G!Gs?>iTCEC$#AYrxBy2Yj7!ag8sWCzZh&7+7FGU9B? zjUOEmYaFz^ax$VPMaA+3ZTzL@%Lkum+DKF*B~@<6JmV9gvek6X&vVi|v?7sfcNz6p zm}p8o%JLP&&djofsu3F8)Kiq{95@mlMbQ&zL8O4Xu7Sr)yZa}~RnD~@5vfNkmZ>MF z;=vnC;Ot;qQj_zb$<#D~N)?dl&Po@xUGFCN_lZ)Kqg3S-b%cz1YKN$_4)mEftyFa2 zABvRH$pL4Ft^oa8$NsnC`*swe7>5qE^*9L;*@K=P<3ahTLwygSl;_djQsX%N24skR z7nm9h2B(GecRoubver|Q*KY#ts zPPm1a2uP3((8V7*l;sb7js?*-bqL`N-<5-1vhyGU7BZ%#iY<0D6tp7&FBt~&`dKQ9F=6xtLsl6Kr^Z~KV^U_~W5DE~fQs<=? zBJvTRm%a`;=#PP?HIQ20GC41OF~u#VxWlQt%8U=i(!t7mXi+YlmpYM8C)}3RrJb5C z>+MdwjTiOM6w!X)AS7$;%J9wsXy?V+gA2s5kaiTKlM^ zh}JsJXosbzis1tJK-yeM-l2UJdM;Sx4Qg*#JeBPo-8P3Nx8w4J+UAqnm#u+ZUJLPz z!}*b{w%K$lroW7J9IC%{fEFvx7SBN!jgHO9N9e&Wf};mD4sKCPK(LZ(_OQd~?!66J z<)?YHSxfe=$trh2N$&6iBwS*hud2SR7<~Vdd@jh;`V#QpB;HLfDkYwoYI z7-@+00}Lz>XKF6yC|GONXKmpToCi%EON?T~uojuqJl(NUE<1L@70azO-Cs`A*sLaT ztWC^+J05GhJbmjvwQ+C5-wJVBa1x&uoZZzIo*Zj=2?4V85tJKuM9YovOxn1+7nl#a ziGv;TEWzv{D9JKkqiBNSpj&G(x5FXS4lftMVO#6Dauag)AQd0YW*If&)`8qCkE3RJ zYBHD)!jV9&S9AMJ`LB$Va4dt1cF*u%YrZ@Q$G6d3krmo(|0FwSo?P$6P(6nAE1Y}D zdfPwxWBYcNC9t2~U+a#wJ3B7VBH_WTiePUuJrWP344E%#k`z5i`(?pMo{m?hbS{3V;bZQJoGt{93abf^d;W$c<=ycc( zGq~i`t6AwNGUC@xqFn1c!)aiY{?Zs4rO#;Q7DEHIURanfAApHemitYydWzp)w@WP6 zynD!XWrU(lq?n(Q%!|N`Ch665{UVSnfqsy4G?+6i)c2q)&Wo8+jov%iwV#CCB}N%J4IT(UiLcq=COnI8Tf%EA+(kyt$CD6 zB!Nc=PpkE1t?`fk+T#k=T7YVdTU88xW=)aFfeEhz1stvkAo9~^#>Fu zA0P%XO+m(i8|{P-4-0uZ93BS2R3eaDt-Uz5JU=XBd$sRjiu_0rl_`BTPK6pE3)Kp1 z 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͕dw9ycXewzK!nqJ{Laew~5T*s%Pt`!a?qZoWzWckgg> zmP>m_cS?J`Q<_h|+=^}q$z}3`-ak;h6fcgS3#a9Uy(}Y)SKzuq1#(kUaAd^#I(LvG zSlzq>t4C!Os10HV`U_SvCHii}?FKsWDyY(4%%60tsj!xCV4B_Km;482`X zI690zOkhL(5t;KTV}3UgRP}5b;b2K7M#_xF!Xk*%k2acHH|orwTpP4s`Nh4`o)0iy zm%C=yXqtmfNe1g5V=ccAc+V^SwG7*3*AjoDY=bh?zjbKrV%d^O_8*cfwaqT+ zcKu1e^c}W-WP>l;NVzWo@^YqN7I~3=X8p_tSqRMM!vgif_($Bjlhvy>_(P-8eB>KM zk)~#-DE?H6H~8ty6qt$iF<`ZXZt$faN6Z^!M2;3bR-l=SpF4fIXJ<+Hz(BuLCmy85 zhRo5$RgsZ6{%OyA&c#16ENdUw8dump>{9sBh26G#)ss;L>k1MeQ+8$LzUw;d(a){i zO+CQH>ne+y5Z*U5UVm~EzAbDm{P7cmsd%^)l1m_&m1G%YQS8vaV@QrkM$X+JBee>Y zhNR?WE1!{~A8#=!9pzpb;^K$Ht$xhxpru0hL{%KS>0`9GTYiDuug`WYVdqiy`UKbD z{$GCEs!LWT^WUdki|O?v_Omyg2jFD=NNNG0{B#W_?+*v155PM?S4h%~GRvwG{cR{i zG&9_|k8?j9qYkfKv%$YwdN4zoR+#AT;n@>$BQ^#b@!B;-jX2StcG0;iP4r#%Ed4|L z1p`L=#cr%Wc$`?qypxL(|o^X)LLf0KOvo38%v+5EiQ)?S*lUaPTbRAFlU#tAi` zl>Q0C?s+Nw6KX&y{S#_HbK>6BbzvB^$oh}rv7IvZ*P$ctKD^Ysvv=2SJV~VnG6lm{ zSqU!-pXHXtE+8`UM!$yD+_KaJH*%)=c}4oNB)Mf1qCconUFKtqh74fU|1}2iUP%&h zjdjqu2HZDXl3yU{U9fYc?7ZeueW6QpYy#%$sO$Udc>P5D_TF_v*$JTfQ8pKSPG8jQ z?2Pnh$Oa#B@z|ZrzjbfHru7}8P+#A_$6r%u)p3i{Z#_RlI-~NNCzYX7&+AX+FO1(6 zgZ-(mi?kH#TXJraF>zz{#`-QhjSV!6pT%LxQFGZ6%<9J2>%uE5Wk*gZc9hQ)Wu3 zDILkKFj;+jiI_}zjECYT%KUo8_0RlUpjf~5A~%sR8$SyymFirH0%k1a^pSv+wwrmN zKY8|7nnijhT%kUm+T>PF6<9p6Hbp)LF8)Luo6-2k@Q%smtY${=&CX*;>EltF!z-Sk<;*6hm=!%iIDPlWI?UYQJ=OK* z$8N}kQfP(S`) zE8{Eq<})ZS+od7NzK}z`@jW49liKaH^7=S2VMJP!s@}P4WNfdzwzk`<)+Vab&qt~K zBX$2rd4(-W@7s;-yyYHAe}^p6&wW33qrTBQb`^ezEz+OH=PR#BpHn_`z>06V`|gx` zKw;+NkCbJR{%HKgdxPI>FU}(U{g?#PyJKKQkIWyITGir^{t)f*ze6=$6O6Z(4MdHdw33fce9?b9cZe76q`yKk>6?MKx8 zp6`(v9KQUR7ffPWe%spA=hx{MqUir#AHcHu(=UYN`{jw7u4j0WfTuWFxhz8@*%eZ|XT7m7Jd{ZpSIA)6 zJ%7aSY29yo^8DDsgH%?((fj*t$rpswgJ4!adH*i=h5LFFzy2>)&!r#M^!4G1>Bj?@ zI!0>0L1fb}ZKjT9o#f}zU;q7UYx?!xzt+>v*MI8$X^RDz&A%vd0hl$S)N0Jy!js>R zY3LVbBCDT%|Jhm!sGoiR6~AzaUz^1bqVhUP8i~{s#}S444C0>uo2(~lS>N8wBx%FD zHY-1-KY9PP2?OPx%sarGP&1H?KNm#wQ!n6hLVXf1&`-a=ir;_b3UKwRO!-N>agW*k z1AV*XiBuvrPU^wiy;a0xdiq1K#&4mM_201pnskpwd?Ay5f^VwdBmt`LUO*)8-=u}O z_imCb>BRU#NZ%_sk>luFT&JIT2(@P!Z8vSa^07Y7iDvtcpP%Ke&o2B@%Onz02Z`hmf$%w_dyX_N~`#yXwZ9ZohWxrW-fj zxb>=Sk4&E5q_9)ZPi{&h#|-F6uHSakP8=?Gv2G7;FnNB=?Bnmw!a+^M(^fFza3}jn zdfkJnJp^i2{LKFSx#u4_M}ze)4+8O{1)lRV;Blr%U(%Rq_8a`|$!tR1VkUluDbz2_@CKQal$f!7`D1<5QvB4xhY&Yu@3vKI z<1Mk{-?Q5IPi*+>CFAGR_HznTW8ZZ`II?1zqv)cNQJza@{JR#9&;L-#&y|n-i2Y%UCug6(%YU%c z=i5(e{Qn1vgXPZwif!jmyTL;(r)H`^VI^nn@01Eo4Kf6cx!F{4Z_(^?d`%o`U+&ZN z_>_amc#K&v>@-%hT*UVEEn-n86t`Yi`!(yr{b%LBiKR0^`?@jtiak;y@s!Fci zl{~LC`QnKYsQ>;RhndNVfO;^Vd`W2VGCynDAsgSw5}^2;cG-+xHx!U<=VjO= z{k)uV#CO+wW#;^cf*i|KQKl1|A0Tg#qW3ja6i9^{i2rt z`~Upr`p?|^t?ZqZe_APg-pSW5`yc+k=YGGOP-^J+_>Irn*V_I={>0Ee`)7QrwnAGiS5_#|698Y8kN6U_`^4UEuZ+Y+~p?w@RM&kkIXaV_Zs^8IwVsz z0M`H8(IohW>!uTo%6ek?9*k{j_~u(0CBF2@z6Cgb!(NBumtjO^HVtLJJ6c3V{pV#txjVQgo=Z_IV3++GKOBaoQ+(E^d|0Z)htYS%9uy1!qOxdTjJcUE6Ye_kb>uEkxVLGD#&Q)+%i zs(+GOHSTnZ`zp)@92lurzS@&X6{K$UPR80sI+L`WbOz}>(pjXlNjpfP58a1~$2H_9 z@ftS3gP$)R4%g5%nZ*k}u8oiQV9WS+Jx6%QQ+((kjHMgb3&fipgug(%g)u(T03JNv z&7Z+*@E7tLaaz2fOUXx>92Y~Tdt5GX4PD4^jd(0Blr?zpNT*$+oJ<$?Elpi=ZMsOC zg$IQLMR>CXJ&OZ2;SdJAhor8ptYF*nW%X+|FJ*XywY=E33xq+vfZDa$N0}`mAMslH zkv5Ch+7NWXxBMb4s3-8D2Zw9$tS!N|*>vSE0T2eZO&9hp4Um~fdf+U)@hyMA2xIAi zy^|RpY1_zaw5#KiQG`cYEIf1{D;|6+SF>s9NBDGo33TC+W{V5gmKWs9biubWgncV> zTw9qSjHL%*ktU=8*TzS?I=)!>u>CIa7RJ&BzLg%a3~`Yk+&zoTzG3QCWkKUm;B zvERgWcoE0>v$kdJ3-;hlAAC3~Z>z6v;aPqm?;*DE;8}Xp`GLO02|3CJeI&evN52ja zY-5slNx=fc7M$e=<$<(Xd4i8RfJb=5myX}`t=ud>4`X=PNry+cG`9G@#PDW+H8Jvr zxX&TB@`R0a`f&}9{I8-1w(ziHVdT;|V3Y@(^$(VQ%Rltdrs322R-Z^4-1*`mhd%B( zcwp$K%Mbj!=^=+KU*5uUb|6RjoJkLy&WG8DzNH7{Vh(cX!flkVF~EpFqBna2V}0<_ z9_0xK`&Q<_2xC0EhdwF1zY&jcC|8uBdGHWE?Z8Wq$B|j^(q)cv2hYk0HY{GG&9L#T z{(vEeF3Jqf+FF{2a7d%Y3!3-Ba`C_pWGF*8=%O6Jvoc7>0lw8eXgVA)!de))boS7n zfrm7~z4boND~nI_P(GGl*a0?=aJWX^&4Y*j(_A1I;K4@PgJ)%haDqWohMr zaNwCUdkBy5u6cw*`NE~^-0IB>wNF7fYm@kGf(H-ubo0Uh4<0UEX7+oEG=EDHlMd$s z%OCJ84y47}J?tR;NW103Y@S{*?T*Wkg9Ib4Hhb(BsY@&Sx-nT50Vmk#IhF5%E_?6)2^ z^B%gmFU&)3{ouP~uwda)M@Wx(@GTD5xBeM?IMjuu4`pCu4^V_bz9BacUOK;)W`wgi zK@rZ%R4zSVJb2a)tPOx?=|dbyKX{-v&IJX}$}f=XYss@XpqsWS(51)hnJ&UX2lgx< zxHer&A9!$})(+5@Lf>?8-Aivapl=>Lc!V<#Y;DQp#uJeXhkFV?_pQ1C5phQYJ4H@Q&}IeqAWXZ_@@a=n8*K zxHgaUS>Ft5e7SVtkuLBMKhkR+Jjh_vJb2b`%o4-1#e)YOIHTZMU4mzEfDdQbDB4ci zgMSJF!ueuX{2cM%TO4v3JF^2>+Jle#7`%;=Ab4C`c)4`fh#UC_A0B0v_TX8&-YM6; z;?0hg2N3OP5(5Xt!;Y0P z^iT(8A2ja~K5j?Ihy<`aSbh;-oBRPrc(a+dm5vv3v=>V!WN-)%8PWw_J&$mChp<-8 zzFfn0Bp!U1z8nSL>{xn$!AHHq86VX6>H7rN;3K`zO?&X+;XsiF%NOkB(}Xb4xBJMb z*+H47J^0p6UzVP9 zScFF!;1CvRL)>ZmC~veKYgf>RGdq?qlp7p$%~^V2JMF=@`{fn)&Gin7kHmv-2M*?s9kRhFL zzWAlM5Qnmb48IX@2)|N1_;8jd;Jk;-@|UNOS$metj5C{HBA>8}yj%W2;XuKM96Io5 zlV30JkXhKGbV3gfvW?<_w~B|J)eF*#@t=KXgUs$R=mg?B5sCP;9@@ug;?EY3-)xg1 z{e9v=%|ixn&e9Ay_!eKA{Gher2Tgw5e9ElNY7I?j$5<8pDP*Px3K`-@{X%AApEeP|Zxo*80didDJ^0opAcF&iZOE)$gNJw!2jYax z`Xbz$NFVCMWYD+#rYZES%q%SOf_O}p4sX|xEfx=lu(KqBba}xR!hV`Gt!I65B(l53 z-z)we@vw<-MGi767hEGQwBP`{s~ly9X?tkRdE|5!UJmal;{; zl{>-!qm1CL62(CLnG&E&yxD}kyoU^Bl^>4*Lxypx|AU)utZNQx^#?KKyF8~5iN68{?UkRxq*yM`@(3F6XmuFwwgxQ7Grki)|vosc0NC<9+SWcCg$@{W4n z5?^)xvtAS)jr9?}$U`6Xj`Z}=TiQS&2QAVC&*XCH9I)9mx!rdiA^@*LeiS32R#zyW zM)s|4k@xg(vFX>-wfK=9IJ60rEA(Is^=j!Yx~IT{9C~n(c%%gwHcTJoXKCn_>j8RP zLm#qw4sxUg4ixs$KFucN>H5fDLyoX;xW{n+;J&y@yrs|Dr=>BFo2DIJ!ayH!!lAFm z?=Qk5EYbtH-IJ(Cv^Ct*CW9Q~95|EEcZ*NQkMQ=} z0sD6UBF}J06VeJ9@(f*gD=U*DjQMmJge&q0lP}jahK}{uNF!t@>$#G#1>(_nBaD?3 z!XS<4n@|T5}P@z=;z9RY0( z<*`(})w_j3{$LZ~E)@SL@s=+O109qVY!8Yb5dSP<*hN{?^Uy(g!NJaE@iU|_FlI!d zpl%Tcal(O(>u*a#tcw4h_GCSNMi{%7BDqGIeDSF7 z%fzD%APj6b@)kyd)pZDiyfm|8<&3s$Z3}5XPdv&4c91_fUwj}Qc|g7)M;RJMej0g% zv-o}}2}9XFM|hF=ugLYM#NR8|2xoPU`0IIuv$3+M#_7SmJ|cd*_#yEKXZI4~M_rzXUoF|1fU;G!Y6fg9PLcb{V^WqT>9&Nml zM;OG9_!{|iyl6C?-I6Qu?czJcw+XKUe6b_Z*DW_IPlU7juzWsOcqseliAS355sz?< z(q*!=y-0Kd@n|3T&6n=MJ>MY=JjxVlY~(GR1atL(I)p9!hQS`n6m}2}>2G8UGK8~s z5Xm(%I#2w3@n^vc3vCBwg7B8FMigONi5vDTY$JOnvotizli9U<6y2XhX#&^M)Rqizm}kHm{Xv3-;GR-yO0YYlJdM&dez?VD`7M3@jHOFXZKPo6gqJp0s%L`N1hkJi}m1c@shLPUj4D! z9J${c)Pr*pq)WVnaKYu$bJ>@RPVvh?g@cHjkmm}2vvg#eg&y#=ox%wEHcOjaw(OwON*>Z- zEFMWxrX4oI&_TO~yHNZ^@S^Z;q3?y4>-&V>C-kt;vUuoVJOZRNhPFzCB+jr$J$ z9Vqr9`%OXGaBcSl@_jyv!|UigU;G7f zeKGtg9i78MufX-9j!t>U+j*{d=uS6(mQU!SOyQ8;Kzv0!?!^P*eeq@SNE70?S3K(G zpm@_gEQ-_hmS)(Uu7|F*0qCA5{^8<3Bz`TtBoNPzYoj*rQt6m6_PRhk+BkGU({2>bi^D@7k(lHxs5yg8&14(%1re($gH zg8Og}Zzc^$y_kAVj^{D_9-c@UHPb;_5eD_RRJ^$eOmXd=@9IcsfV%Po!yRbTPcK68 zgMu{(XyV?zZTg5N6oU)!oh6!c^@VUKXMDqN#Vu;$V5X~uFlcY-Ji3QB;mzsRRJ0kD z&c(IMmGUDB5jq=j7@s@3#tV!(`5MQTvAnkhSD=pHt!0A#3x(77-{5_T6a5kH*Z)qB zdu+M*#JT3;c_BF=TDWsZ?E>$_+CxQWl3qso!tKg`F>xp99HadzpVO;!E9o4$lYD7> zX!mgF=TJVE{15dgGn5R{`2T{(?=_2Bt{OQ%BW%l{Iv~jK-7S{lutAX%r6le$E0&%q z7a(g6efBlE5YhukGAoYTmAW3q^*rVOEOo8w%6~?RpAL`f#nhGSjdr~+6@D;v{j1dV zK5ywpix=1Ju^s7iKdq%b9m13JoM?HOT~lgScFsx%J({4mj$`@VF9k%eNU<5 z3)bHbFY+ZqaS{2ETswxN63Pb_>f}Q8cNVpS8;7Gh&I;YfSL85L)@{NkTy-m~8 zj?4m6&smLNP2@&J-o^0Jngl_9u9R`rmvk@py?aQJj&tYwE$Uj8a$2fh_ZNRq+{Lbs!de=utFQQ={eh9f>_{ho@ zVI%yZD}#0%UJl~p53g~Vx%M=S2Ew(Ax5Bu*Sy7u^&q}WK7v9;DKfYZEjd1PadN@V_ zrVDOm0)IX2>(u^79Y_EC24sd_|2CB^$5*!ZT2hdM?wXxJ>iQmct$*}d!`u^sr`IT! zUcg#c$*|hJN#elK1aBeV3I!v<);cd+i#33TNY&h~Y%3LK=`7&V+ZyC4l79 z$pe;03TMKLTwRx?-&azd7i8^q zFh5?T<(0x_ui^|v?yuZAmLJ9Vjr$x$(;>W#M8#J%NvOFQ#xt6cEwx}uGqS8Gjb_Xu zN`*IhoEDP>Cc*74B?4C{%cUi7A>E(YW}-=9l-MkksfBnWJcBRw#>YMv0PKIX&fc@W(4H z|FpGhyN^@Clq^cI-DM(+8pymFndQ%SR68S=&hlrBjLev%85t)H1-USQW;2$hQfv27v1}>S6PMA8*(}mT7~e!enc z^mUPiPH1d1mL>7Vc_@_S^N`j{>}Rf|MaSu+0PlF5OUbO4Psuv0pD&hW(~{MreJZA8 z>9hn0RY&GD=UMh#I^#kvkmb^n(bKdBuFlm04T+jEfzPU~O&E9v~y1WP4+Pw!JWL#~Y|Ex}tw8=+< z_WSO8V1|6UhktPW_g_EyMM;wkLT|*Y>IYuF6w8pjJzxKj{Fm>kotrvlN~yR{{qoUS zY=}EmEW@3n{0A43fAh@`JUIGAu{opaA(1LRqGBkarM&ODnFmUd+7FK3V$rQr>N@9@<&873d7`E{~JMm~ShoA1h zx)fb})gS!e2lhS15|XB~{{MBZ7{*goJHDuQ(Ya4udS3etOCNabF&WUjbz$4x=Zs4i z@O*!BPsA>D(ZlYEHb(RAzI0srcI}4M#(3HmSdQ^h6}rF0AyNTU<&VOcN?ARTbS#Jd z6>WFlFrMoPg7Mkaw*B7Ok&$pb*I|^#Gja(%p6^h`Q~J)@c)r6KSNqqC>vnED%(?MO z)&=8tXIW7+u4n`8io ze>dOYMi=AD@4N55Z@W@*L#{pJkJnMhO&ok|9k+3k4OzzRg5#&f<6B?$R$@>l-D!;hV`Vi7-!O^{Arp>_{&oy_K|jrRRClU;X$Rt^Oa6|9Jgx9@wc2gd{S@{#M zR9ZfywDK~g2VbwW^g7DlpmgF*O2bzvjb5X)^m3&(UhBGGj!RGU7af}J%Vsz_MLIzm z{Yd%UgUmN+_jbiyf3NbA=~dgDop6;t@J?N*)F&<({u{=7pVEV*L8x}i^5GaYQF@Zn z$_CmySK|vvqlYOjU!b(IQo~K^vU+cdxO{=~{ZF(zyX6HMZ_g_=z5WLkmq-tOSn(9g zr}PlD-?LlOH?f)YOr~eG+Am$C)Vp2f-k9R@XVhMmwC7`*4x`>x8ot_1J4|;MX*X#P z=@i4scT<<2Zss?5q~e35RnjSj3yx{LQ=ixLbYHFUcK=TK-Vc=qza*Wf;mXXPcd^=^ zxKHzK!?)l$8oqqG@mU5~h-qFF8%an|zAc;+wid<@T-%>9n*WN?cogBaeA` z^`WOY)00&4&rrOU1z1_6_!%%JE;w27^A&pGnToORFI=!#@iP^A0rgA7{#h#jD8omm zD1NocPgVSS;tKH_3@=pq0CCWzcn7iN7v|yr5EumnTULIC&3+zZE~z=hZ*^}xp;77@ zmyNKG0OIU*wtGjZtpE9cd!DH6v)(&^o}bI+DdMa>=W{f%q_MvDs_gwWUHyYU)A(H? z^2&nC&r|#SEK(EVP!s)IexdfQzsVbDW`FVw&40a053keoaYj$xeDV1vspE;ck~Ybwv|uDSu{9UdY>F#C}+Z@IC2vE@JN;=XRP0u z4kCxai(xadYY2y);|MP%1*iMy(R}|s38*|??;osTD01CR?%(c5s6N))6}e{marTSO zuge`|+9xN(qXJNTa%|D=fq{~od`UPm;Lf(%yE|d+>)kb0P^x2cz){>V#^mU}^m$zQ zJd}1fE}seZU-j;nX7b89?VoHtVLpEUA&vXDxcpM*7xneZ$ziFskMq^`4qOSY9P-|` zFA)v);b7PezMOA6wn+{T-z81Qt-H^9Zch>@r)}RkFeF1i zlSvl(`v=^at7%rou37AlY4466oYOh5r!;m~v1rHM-Mi(7AUWPP zqX_9u=~HeqQpA}nGuKdV>fN4=OcLIAhj4ex@1`7#hy!5b0DJb14eWR9n3akouEON^ z<$o(MRX#GL|9_(b_Q~VPO#>r)EZJj7at36isXnpPD-Vg+ZL_crX8KS`Y^giWBaj{_j;0BuCyE=o zX1Lc{Zrm-Uha~dyuB~lG$LzWD7Ieu{@Fi!R4Qcy~866$7=gc{2-n<117B0Lfr6IxF zXUISS^Wj9fytx%$hxWc4z0DIdh-jbdeYt zWx&bT|EGY56pFrc64iF)A=%Egw|8{d`%Q@2XTjRsxqPQ;!6c6}XWr>_aVbGglFZ5Y z>bZ`GOd!wB&3vKb@lRV@$E?n|b6=sl?UG_dAj+Jlv@?=5|1k{TRS>4%Gzr619gq zLlw=PH@~Y3drY|uOC+ecxzdW><9O88&~rZw9&Rmd;;zAc+VLc>$d;@2&N*M8J!!`h zjcdAd|B1Y~f+RuTRC})YkQm&YKXT#p?vhM9i$Aw;Qdl}O-hwv>n72wh!^*CF=LE8 zYXqpbr>ia!>Dm|WnMlJSSK2|yBg#v_gE8UGl;(kizagb7YOcM#)rCW~;pRujF>l`c z)t;1#hM6thz+bv>uF;}tbfQ!E0(jDH(bUk;7B4>eCoUK@IEeGU}e zlOOMRt^~+l*tIhWH|Hd|pAqhv&YrYU+~tyzlTSVUj8{3H^a7H3DNYG?%4zRWd(xWS z4I@3`;>8sgZsu$$IT(|aoOb&C)I~<2y!ezQXa5pBaqYMf7D_>#e99^AOEs!|&VrNA zc<95IJ#zW-3ohXY3D**|Cz`R&@uay(HL`Jl1u^B>WjOKIwR_4DiQ={fzQlEu!q;jwZS&5^*y+z5t&5 zS~@58;l2!>W64d8MlMa}yN>6&ICNOf{n&K*yMX-u+VP~a*}q7;o;MTI*j>WnW;AD! z@q{IVA$K<{1yAl#*CEP{h@Ne=yg$a_^60rba6N`FwpX#r|cx9>9Dxb)lGhZqjy4cFaC3ZH4=EGD4|&zVFWb=+gR zNS{{u+!up~p3e1$_$54P-fNVHo)cXaZs7&*bUaB2xsLRc_R#TRq=K$(;XgQCl%G_N^lQ>_oc8ad7~vMVkNE5~l_f0!9~F@j^g{?H z_x{5j55KdW3r;@$EdSvbtX$g*UdP-8U8g?eob#7mv}*Ob%QwCQyqR+sE;{whv(JCT zMXN4Z|L9FWcH!nMSR~<=F1u*;x<_xiW&=LVN_yu@y3RP`%rhTy)>#j|RX^6c_Kpf%cwT}EkhGJ*>^nm2oyK0Rqg|{Bn0;=IudDZo54e6r`&ZeTq<#L zc_O^(we!$>dBNk9mPx(q6o;f0QvZ78N2FEKpojXT-VM|zt&sXRQlGR+8f>FJsdp3g zNh_rO&D1BYk_L~bKB@Nv>XTMT{adI{S|tr`r9P?mMCy}PNd4QWPg*4no9V_B@G6sPwMTUK52#2 zAEZ8Ml{DB%eNt~1^+_wF{!^(>S|ttcpgyU$oBE^`QhyKiNvov65cNsDVd|4sNc|G^ zNvov6)2L7CjZmMoLh6rFpR`IEj8UJ|+e>}Y3aNi5^+~Iw!9MDfdixbuNd3ELk2oT( zk_JzwKB@N%h9|9%`p;B;L|P>co<)69@7dHRt&sZT)F-Wy1`+j1y}PMTS|RoCp+0Gq zGXUlUr#@+g)IUId(kf~20_u}`FQh(ch17o$^+~Iw z!HcO+>ir4zNh_rOOQ=s;B@JFmeNyir^+_wF{-08xv`QMhjQXVB%c)OVA@yHDebOpv z@Ji~Fdat5BX@%5(HT6lWq`@KTlX|bAK52#2e=YS%tE9o}s88y>p8BK}QvVIqC#{kO zZ=^n{_a^F-R!IFa^+~Iw!JDanp;GT6>XTMT{T0+Ft&#>8Q=e4!m3P0ZA!&uwUrBw^ zDrvBa`lQ}!>XTMT{Wa7lt&#?pP@mLW%W#(}t&#@o7>?9iuQ(*FkouQVpR`IEY@j}= z_bBRQtt}tlU7Lmfcm6W(qJR?Nxe5ElX_dIPg)`Mw^E<9N*X+d`lQ}t6<0_@QvX`&lZGEw z98M|qexkHY8vK;u|82f&kN$U*R*nBNmHR(eS~1FS;V+c${ZeW8UFuuBN0eVB4L?Fm z8h(_RH2fGbY514Kq~Tu?lZGEBCJjG9Od3{*NyASPlZKxnCJjGLOd5WMm^A!rV$$$$ zh)Ki0B_<7z5|f61M@$-imY6jB95HG5d1BJ=3&f=17ZsOT{#D}26BfAo^uDL{5#FM> zZ20e0FZdPhkp|z_@X>Md4Ifj!|7+z}NW-@8 zpJ@2#?TnZ5D*669lpp<6!}&i`S|JU8PW|7hUGEnR_W;X*G<;BTber0%(60X^V$$%* zip#VU9#$OuQtf(AQ7pSfyZSGa25pL~q)|K5F+*vEH0)69%~V<@4Q45>l18%?`<+TF zq*bP)I?4R}O6B1krQTenWzygz#Z}U1o??H#(h6y~K(V(_X_++WQd}jC7Af`@E3J@* zCzF3%sdozH#AV{(ROOdhj#c9D*UFDhqyBFgj?_P0aqwHx+gT6qR9d0DN_n_M!$tq8 z)H_3||2w4>(kktQ4=BIPaNdK&v>%0R2WOH`d6hVNi1PijlvYT?hbs2YrXFc$S`l;Ohd{RT{Q5p>>^>-+(nw^W)p5LvsLK?1A?5$E-CJk0Au9B8%ze2mg zT-qm%PGY?Cl!k*!y`4&a`C@qr) z3l#^ulvYXo%V>u*+@RQdl+rS3aJk|tY4m8t{uSiYe)LqeA9X497b&ffhKtF+gM6d3 z69#I}+o-fm8f;=bq|ud%{mn`%q~6JDH{7kXOdOn|xJnwGs@U7ZaHQc?YR|h`X_+** zMsbxi+M?Lss0 zRrU+vO)B>uO8uJ^mq~-iE3Uqu@qa*RmHg-l3{QRk7R43P@XOl>sc+d!o|dKH4*U zoARp+ADpf7@GGicC9WD~_~=Qh=Ra9#g*5ys<9&+qz1x)rql}lh%5Xub@+xW6tJvSJ zG&)E1d|zpmcEYb|Jkc2W#Nj_Eze4@6PwiBw@AWGV&!ry2d*>-GQyvU3+?N=R*x#!- z+M)8Ql_&Kpl>37!56-7PX|zZ*C;7A&?qs?iu6%DF=`Q8_ ze?j~RrDgJir!u{?TP2R}px$n!71A>G!#&FPhLn~`gJH$NGL0v^U(;J9ziQaz|HS$# zsh)0zhWFo1e3w%H>7>t~{L6}~q-E-dU)Ow97_Lej zK2!C=e^I&jEX8Hg;Mt0+Mj0*|r{2G+UX|33lwTnYzoGK*Zsi9TY5Kf-XqWOT`TqSX zFH;^ohv7)0dlmc7RazkppQqS+zS8nnSPpErW%7dqDvwsE+`m|9h2gdqi1V;{%aKbFzDcpSLG6`E!$`4r zH`DP|rT*8HR+%2Jtomir;8B#5hTqk6haXaY@MaBPB`wo_^k>Qs?x8;Q{I@VX`4!^u zt;+Y_rnF2Nyq)1mqjx9{zo+T&4=au?*LW(#;XA2k;U2AW?>^<1NrQJW9BK4!#r}Jg zR!GD5D)!!|v`iXID6W!5?^o=9Kxu_E{By^)I*k7j#r~BlFB4aYgO92_+)O)H(av)jp18_z z!PVq5KJR&oqmQYbD&_uPG99GhUooEVYyEm3S6n6yK0$rbsG`{aq|yp$_$kHSrx~91 z%EZBE$R~}iVSbKjywP8)-2WS;71Ho;$={;kE2L%S&pS%Hv{NPy{*HXo=(Du*Ii(fS z@CO=yl{DO{@pz9>S|$x1%k+L;^}R1BEt3Y%S9$P7osB@`Lv&j{aW5`IAa3 zq~X77dcrR$-}|!CGHLJ?#Z}VitBU={soe@`mFbBNC_lVTss94fuc=;zH2ep}-ajfW zlLq%Iu98Ooq}cywr4>@|dd6?|KdiXQ{FW&XddMe@ZcrS4o$*-yUr7EB*)IP@<; z?U#>exZq!@&+t{^@JFie->BiDZ)iCGn@TIBVO6pBEv02r??tLtCXFT(S7@)w@lCi* z`Blaje4F-eBA>WS9Nx!vM;gA1m^6GhF=_Z7Vp5x7^IKU>DHC`)ujjm*k{n_QS=Vzl z#02pc;;u)iyh+Q^ZGzZU3uv&!?RGTpc8~{jiP`+rC&k4`_JXAM1W%+ed55 z3si3VM;#%aoVGZmC9`&xg*3=+*fWHH~0xI*YHP(Z6C0nL#ppzq4J}|!A8a9*Qk8rF^aoi zr?_;T;x29&3M&q*!I^e5%=`b{##TY^egUptKtdbqr@fd(|7P~Dz|<6ytgZ!98&%89g3rp z;?Bd0r-=6xhfh=aG2)1L%R6bG_%QJ#@sj&g-X#ao;p!-{?Z3D4U6gY_zN5r)ShNd& z_}wa>xJz;P9>u{k6nDK>anExU_qEiMxq|36+P>qnx-zyyg8WpLzl9+oGix zD&9{V5l<1zeeTjb@#nOEQ1P^M~M%;#OmX+WD~>KuJVo4nq2dESWO(APA1U@PqTKLG#fScn$}8&?AN(=( zFDIT-T)IN>vY#j}U#-~xnc@lJi1^?&D)0Qc$|s5U6IZuV{}(E+K1T5o;^?u8gI}sV zyg~6TzhZnhDn3qJzFG0n<0>ybL2>kJ#ojFpPaF{M{Ef;Z;`@oK#9Mx=^6*yGuMl@X zQSrL}q;I1Shz}9lzO!8qsJy#R^_R#~3taeA#Q}HhEZw1alDKEL;+?uM*Xtfq z?6>QJ&noc*aj8UmGgRL5G{qI-DdKfJE3-PH@}tB(qtu_N`Um$Z?wqCA+pqWl@zgUF zZ<(#~@YxLCskj^|o+7Ri-!ez#!E>qa78%QP+X2PiNhXpelx=_RQbWTC_dDs*ngYiWs4L~5>F8OZ&&%c#VQZqq4<8{(qYA= zlU3gJPQ}NGyYEvRoucycyA*ews<`_-iYJJp_bLufQ+f6MikF?PIQjs?8~&i;{YzBt zeME8T48>*QDdLHbsr<;9wEt;)BEoiH{R| zzft{Yg@!NvRm~wTb)n+u5)B_MQoM{C_?Ayre2jSFbj9~y%J54RhwF&X zP<))YdbZ;3%T(TTj^e|_72+=4z`!e?r}8Rs*ZGQXd6eo`iL1ojODVrxozie;v>Y~YTDnV@*d(t#Qr5J-*TnO1LDKP zQlH7%is3I;e4N-16d$=-<)teX%eVo}!izRje+%(diYvrjTNIbJs(gyr zdyL|qt&|g2h>sC>KSt%@V>NvFdg5yp`#p;9C-!boyz_CiPkcYIw@u}x>r`GMK1SUA zc$FWzUgcf4D&Eqg_}~*2-%lLfrdY;3t~|n!;crwN^eUbt_O?^LP2~~sB(dK|dp9w@ ze#OU$dj=GjEA;;yHv+_cp~-#0QCQxl`p6#7Bw!x6|G}mD~9l zM~Lm*i!J+A9^R+nJMU5)yhrg7;;#47-qTfnkoXAk6mj=6RNgb8;VZ;t;_hdve2TbC z9KK(}FL{>Ay$>qxe75554=FxGTqf=sr@arW{4lY9g!UqpPku!41abMJikIE3ayw6@ zOkDlA%J<)+ay$R!7;#TU<)!DSyhMCIaqubX->dR6@iF2l;#;1}`2Uvad7k3Q&naH= ze8p45CF1VStGr5FBJMe$;j6?I;+`*R_?{Q2+?!PFy-@MQmlQ|D;g=O3C-%Rp_|S_q zeEDmNm%UhV_dh5;Ok5#e_9rT@+^_OU;_#mo-|`aLBR)!e@LyEE|D`G~eM9k*gNnnd z;={z=w-hh?Q#pntK81J30}eYj;a13Vmt4q^h%XS zJpX2jc4!6XI7B|5Wj^LyG-hD4ry?b9BPjsC?o$!@pK>v5Kj@WdmZil zM&*ZzOTSedyk6yYZcmlChv)dLdxOeL4{G=+;<9X!fR4BFMwNHTb`!weZ&F<8P&`RI zF;j6^R{7K{#m9*!I~5;(v&zeh6!*MEakNJah7MJf;8r}EMY#Yc&&#KDBh zyVj_@`~8X!u2p=DcygWM@&{BtwVvVsoc8V9E@C_PYuR6@e3J45#8bpm#9jZFvh#qC zqd4FH?A%^av9xNI!A1k2>Ej-gWI13tBv3y zIk6d>eG0mF3ON2W^LK*>$Z@j!4D=*9LoSeq$R%>ev&f%21OD6}gHzw2f3kBXxP1V+ zmjQd^)LGP@qfYk7>RZ&Ghn_hHTqKvi4bHs)J^wv$-;3bF#o+WyVD~a`>&w*1IdcAT z=iJ;mQ)Q$Gji$=&1}e;3Yqn>x9R9Q?kU%p;m^N0s<{Zymn?XYN9L=N)kJ zA@CqM)D|{SkWb`+r>lzlid=e}bNW z8C)O-zekz)GxQXHpR%8Lv2k&EPx5cK$H`VV+4IL9w% zEwq3WVdQtmgA3#$ITeBKO@Lk^$0vb%qFjFp*yR_!rdq)sIWY~~UWWY6bZ~*3nE_6f zLobpG93KHaL(Y-2koF*q481De+ z9yw2L8wovsAoPB6=^$`>BjXWcw&QajD(cl8P zpIjt2je%YwcasYpSU)zF{*MOtl8ej11NcH=l}mx;K8k<*#aDm}d6?{MLjLr0mWMn<&XZF!pv#xf`sdR@ za*o_FljS*uIyp;jp9Q^0?kC4jMgI6~=y`GBGmit!z{+7E6TqJwffHMoAyVr7ka)#Ws3-#-v50gve z?l$_*aeZ?B2KwI>dj3YR+6|n%1>8@L-v&7QI6 zH?>3e9)#Xc4t~eG{Q&9@LC=%({ourb(36jWorA!s$H6&rj@)!G^u!kE17we!JOq0B zN6?4Kd2;$t=;}%6L*yhmwHSJqJV-8*lS%0AQ;biJKMhVD20cX{B^=+KSxW!po`8Q0J$3|iZvfmwcAuwyB=iiqha7(adec$Ri{xH%;zh3C z0lh@-A;({Wu8xMTUIu5#@t=U(j)9&h_mQ2~xc;%wv*a|nL>?gLUPu1+W%Tz3cz~RJ z6P!2>dhVyx$(cdwUxl80i#oYPZd=as{0w@YocKAoH3hv$?j>j5h8|l1-Tei)o17t+ z$m$*FUB}ZOxk%3a5_)PS^h6OnNG_7wS3%GG3c45YyWm78bm!OLescUb;I`G!v*bLv zKz2@`|KB2i4>|ceuyTq2jq-VpSzHOQZS4_qWC-lzUG=;{yPA+qyF>L*hF z6Lqpj?pg~y`)BAya_R$c>Llp#5_Pir3-xu-lYa%veR;pXERnm`bN#>w0zLVC=;^880kUcZw_VQl$$4^i8uZpH zxc+o-AK9Hjy%)Mi&XIF7p}SW?&&~qp$N?*dNepnK$|AAsF9=vi`(?A!o7 zzAN-Tvf2&Yek1fOd5G-o4!!3l=*d06>Spqu)X8~r*DZ{<7xd(DWaj|rvHPIs$!T)(KH&it))k&x_a zGB{lTt4(0aT(GWRL8T)$7oU|&@{`6kvMB4^26ze4`pnbgVIv%r~mshmmVK+j(WR=)##-v?*O@yn_Ip82l?=gG;d!0{pIC32pexdwXTJ?NQh!2{&P zP2~6KpWOBbuzNG~K5~}a^hfCG7U(_XGHEONfbR!){SA8RL9p{7`5|zY zTp~LkL3jGOJ~>YI$a!-7@5rwnM*bYR_z2kj2lV2j)B}DD>7@?Gd2xj;^hWO*)zo@fM@E&&gb z6PJQhO^kOLST%z)-v{T(&gJ05DCl|eAlW0gjfP$z=g38JYz%aD1^ji9UGe}qPIkv4 ze}ddiPLd1c6uEUA@~6oea)vxe&XL<%kl!Qsl8a>JLNAd!$WAZH-%obQP2-V2PEL~( zSqDRK`vekJ^?iO_T8G}*lh`VcuoPE2BcaxXb`9rEWULr>m7o&t7n181g! z)8rCa-3~p~3O#WLSWN@x?*b2!Q+Iro-QR*UyMgn60(a~V&i)k~ z+XJjV0{4?j*3gKR8Fuk)6rZ+o6|Q!Ri2Tei}Fv z@N}?qAarL2xQCo2tApr|+)Yl;ME(+4%>s8FjQlzB5IH`Z`XMY2xj;_Lfu1}Rx<~FO zC*#oD7DG?X1$*S;PT=k&^_{^ba$*5EcNqQe0`52*oY)oIv;^$z2JRsz$R%=ePw0J1 zkw3FHICBIzxes`l?CuNhK9ceF1DD9|SHS6`pr^=#Bl&UJvhkAt2$2CTjcc9(&B$lh^aXF2mP z2j|Fn@-SJg;QA@#&yv*&uyZ{0ZgOfB{T~m#uo|2vt2N-nO8Q$1E|HTbfxA{gch`Z3 z$muk=rxSYOWN>UX*duq7vm2lflZ)i86Occ-5qgpAk(2%pfXnwSoC4il!}4^4^W@Cw z;MCWk=g9qJkKA-3^a43eR%c-S0kTVOU5os2a)z8B50ca5wv!m2oF(VUL*&w#h}XXk z`7;@Cd_6dS7Ikv=Y;bEDdh%P~KC(x4PKI72cad}FApamac`mqp1M;i$!2RSLxpgD- z^tYks$no!hTQ@6?*)wa9C+w^ z^#39_cOke)Zn}v2PoTS5aFU!M=U#*ETns(`I{lGzZ-84bfnFeI$;G#zXD)@F{yDhm zGH~K|;KA>MGk*Z*E@%E>aI6>XeN3I4(J_Dj?7I?rmMov^@vq<0A?Q8id>Gt*HFPHm zE|7EN*#L;xSO0J50TSV(7Ucj{!BG^h@2z0=b(G!K62hc ze)k8^b2Z=`IXMm7dn5GhEO6INU^N%qdNX+*I8V-yTW^7$+=)6lJD>h;h3@VGR(;^a zZs0z0c6V_6Ht6|1!2RU(p5V6I=`R5;k)1{0o;#pt$+0`ZYH#Qnvb!(Xy^HzDIdX14 z=!v_b=gB#;M;<1t{gFR=5AtUY0JrD4{=wkbyyPL^4elqWPX@=Igzjtr_mLBu!Cg;5Po4sHo(3mQ1+h@ z3&Dfr^hMy*3(zxJ>g3$TT>nMr-X-7xa{5wm+e^^h%fNl)0=emB==twM&yrJ@gVih0 z<5z&Y$wl%IIoAulqk#OGE5QYF>MC&itI*R|gFSNg8gScBpy#dy=gHo6;MUim=dY(u zPW=F!c%AwUV2|wH2yTCa@yQ-JdlU6Hp(k(V`sDa6;I^MaFOmDm*;}EzgU~a5;2b$e zR&PNskW=LJZOC6BySIZAKSO?x+)qy30X_b6=s9whtnP%a-iDqecawAE5;=7j@~3`* z{E5541+uyaoOlO%k(?)cdFbvhp=a&|_mUI$ft@1Db3eF;oO%GPeg!@ILvS}a`5<_R ztR4b)yo>w=@&GyC554Wz&~p!i`^fo6z^%W5o_`daBj+9iyT65=dK{c3C!YYT-$8e_ zfYamxd5E0%pr?M1{Fxtt2g!*i!R-Q@i9(1*#H7r^O1A%F5k@DSO337q;f^dfnXTzDCJ`v;8o z3b>z~D}Y-|&@-=sd&$Y4fMb7w?z{%hkc;GDa{hJb>A%w78{i>w;!SYsZ_w3G!3DBM zPJGDq2chT5>9@eGA3=}*44fmE$W4ET?)@BkHsH6xv421>`~sXI=iUJile51Br-zY0 zT?7x26Tbp?d<@CKj7bhEmanp87msZ#kK98pk@?uYivJ1z z+i@FIrOCW4uJYt2OxvpxIYV~;jP;A;Bsqc0HkBdsGGFD%F;=Tc?jk!MAi>j!N|0O2 z{L4O-CijqY_mE5EVY2%n*6*l8{v_EWXUMJf^heH;i{xRl^AY@|8jwFh9w4X5@sZGTC9U{`<&Da%>XINA4o$ z$pvze+%_5co&UgJj+`LJra&){GvxfI$gieSCwGyR!ii~s94EK7B7ch9L(YU z?~(h+C9<;NY0SkcSe3Eiu@kAL{7}79)q4EC&+36^fWm|&XGNGf$Z*r z{HhH8GUPaUh@2v~w;_L)+(-7vv0b5;$Z2w-9R3UBEV*qr{ej?j@^+z zN%qJYvV0GPzkhq=3|UoT{ULIKoZJ)nGvt19p4_w-^dh;N?2LfFL2`oJwh;N#u1i zM=p>HDRPeNk&EQkqmkbo1Akd^imZ--o+YQq9@!(8$nLT9 zHx~YS$Vu`LIYVw=hWvSQAGt`59S7YR2Y+dDf;>o0lM`P>{v5fF?2(=2&`abr*=>RU zL2{DZmO}mvxtE+L50i`J)C!i@g+Gs+Ah#Y5Jx$J%bL3%iiJV%A{E6}KH$YC4U{z7E~p6YKYp)n4HEH=xHC(m&ZFC%y^2M9!1l1oFFQLeG#hrj7s-i}!5zKO3*-T^w*h+lmC#cg!Tn@+ z6F7bq^aMFePLWIG61nSYag+o7u$!5%rG%6-AThk6Jc%Y&0PxSyO0 zgFEhpUW|YT$(eF+=050d1-L{`k~{8)?u~#h-vj1vKUD?pAScLqa+)0bA=f9%_kj89 zJJnc!kQ^t+AEfR;?`7>m9B)I7j=&BLi zL-xqS^j{F1UB)Roz z>eqlXR}2>5<*+wY(!9su`|)epf%Rm&OZLd> zZ_x8EL(h;CuYgPBcmbUL5cxgwFgg1w{eJ}A{Rz0~@8HyH;68Gi9Qz0KEICcikv+0U zc88I_K+ceh3jsG(_=5Wh^z=mKC)&=%aOi~n zCi08W!NLC%*3UkE^P07*)~v!id9K&9&3czg`bM!^#f%g43HE2Gx87Oj$NA%%cs*&w znsu|yKgrfo3cVKoAY_$7M|}_)sqA7z)$XFp^bC8*($`x0P0MPDRE5S_Ro1vrRj5I! zUF<3Pn|h-@N9*-^k{%tJ8LA0QG$nJUqCW0e!14H zTeC^Zl~i_8O-L%$s$1brsTBQZWc?=kzeduxirpa=_`gTeX6f0^|EAN@owH|mt=QN# z``Ee1ty#CJbHnNtD?8mYz99kYk|!*-lJ?>nWoIql)De1j-%p8ghsAFYxAxmoG_jdt zLEN~c&2r9NXy@ELctzaKlfNWtW8Qkey2rBQR;d5K;vTD7+46e>#+0=G67g4TMZ2cO ze-Qs{NuMj$!9{pQsX2PQN=)N^-m|s*2TA&Hu_MHSILjpc zKg5~4VB0`n-zE@NS6RmE6MsQ_Ju2xZ#hwuh;=Ls4{~_K^^R|t5w)KU8MaFCT&enJ{ zBt1`TzE}`%Pf7m|@fPg7ZM>c@#*0r!d-jOGpnlg#`bM!^#DaKtOZtC^H+SCWw%mnZ z2$*5KVeuElD?49~cd|F?J>H*GNcp)D}lX)QettE&Rz zb&05^At;9^R1q+*1q+qGPTjRBDm+Q$o8krK> zr9$GIq*uaUZU)+SNc;!!KbCatyGm7x1@Xs8`oG3su=8i}_mtSP{P>N2{0p^-Um@{h ze*BS2t=B8yFFh0SyTpGG|1?RTBi17p#J@z+X1VD;oM-HN@fsZWD?f{0msldPV+(6k zBx9*tv}yFCLN#()wkKG#;6=^{j9V1HLEOJe`V$lLf~|2YByE-*#+5zlvkkp%;QW^d zPR~MpJH&4g_e4pbC3db@P~RIQy=~mrAN+iM{WE&d;#q6#MV6Jd{$=?u`(I==sYo`Y z9?@f@@*y47<+d&VEA$1HU8j@w!qJUNovC-x%dBrAj+%pVl_YLZuE_V48YAY41?AdZ z(*Lbo>(;FO(xUzSv!acV?GjS&Y*REAtkx8)xl+kj%I>0%wKn>3GI5lv$CN|fG5zdS zlD=82Pb?_c1ClmNZo7Uk*gvFS=sbDzinaa$DL-1Bn7puBMN%pg8Y@jyZcm9;DYZ~e z;9QD~J1l;K_Ncf}sVcD=F|(L{DCqx!etr9RpLImpklz!P=r<`o0>3LIy;^L||A*f; z3Gb?it1b_@rYz1}v{T#y-*KFN)kRy&TQBKGu~A}X`Cr<> z?^t}lH~4;&^xLtG-?frnFSg`|g_lXVz{Vv$~ zbABJ8Uw0n%hyHE+J}>E)#0vj|Upb!!eiJH^P+lnEmnB8N&c$2HJ5kb8#HNXv<-hF@ zE2Uur$A0TRYg$*SJpHD(@q4zUFBbd0Sa6(QD`~R?$6YY)430bLcLVozS?hTJd{}*v zB^|Jgbe|8^=?#)rEA=e6QHh<r zD*nv*^DRk#B=)gb5O3tAemM1;Jo=gK`N31x+Rc&lc(KW1 zLHUlL9_$Z~-MxK3y=K$wxu)4t1#7vL8Z`f+%cXxVhSad#Sh-O8<6lWZ^EUosi_0F=dG-=sErs@6t_0x=(5r0Ab zu9EZ*#BLG`;@u-@vut0#ji;?!IR}-Sy~NZmx!ylS{W>OFDpf3{zG_PiO)Vurqdvg* zQ()X-@f*aAU9MEMSglwPw?Wco**+}d+qpS3UQI*=&m3H0uim2>imh73+^q;gIg($M!c1O8}C9Z6Ie>=yn zkot?&iUs8wBWbhPyzbwAJ9n;IB~4(8<&3FzRApTCNMWif!@AxycF+u}#CTowXZEXa zO8UEE7l{S&?xNn#@!hH?K7X7^Fw+jluUL8F2_|aZ^7K7suAxFz7PNX++Y-J(x9Xbm zBP+{vrTm5MCi^fQ9xeUB1p5w4kF{3IiF!}gpYcq2s(a-q5Ni<&%Coy7^N0isc_R!%nyDaQiPX4(I5jS?FQfB!T39ye0zIZY91F>%PPj7M61F8ZDjb~{3-1&iFPryqOSkK*E$bM&K2(cx zCKjPyMJacyyk+Y3k)#j2N~uG|f_i-_X|tqXN4*B$_`-hY*K5%Rv)i>4LkoWyvWlS} zTK>z0c*)`A6iC{C$>8NtNN3^YI=s9J?GbsYSCyq&bxUM_?bxx%s7RSy$5-nG_8vNB zJ9@FM4UN3pirs95V+T)ce$tX!mg$JJ&S=q>$u4Ft{$k}fSo&be9+x-EB{jb*d`82x zveDsC+3m<5nE@#>+75S?$)ORGL&aoXCT$$EoAo{tsXSI@j})qsca3M1|H`LV{1YeS@wcx%04D?gH`sa zRk=*sH-8|uNBZim+aoLK`^6p;3%186k~T}?5p0L_V_&{Kj#zi%y7i~7+q%28c=|nS zi$lb?Z^=pCQh%0HM^r~5ByE}R$g|1FmSEKjdkw`S#XzaL$P zOX>8A^_9xWSgNT`HnCj0kC9Q78C&NVH*xLO`hHc?o5fBO3*ufTX|qh?yv}ca_~qO4 zs10j2b?&`l!-h4T8_Y>8IY#<9V++J)i`k1~s#Y3grs>q>)ULzjWqMR)wGKzdM`VvS z6AL5s_bfBWkR>UT?&h^9@q^?4V@X$DC*>6j$~RHcW-07oUO}40KmHHtJn5wMrLm&9%);8AHP_pX!cAk#hI$ts3ObJC2t`ZB%@t~y5 zat_<)OZpqX981=&S=qVI`t)h0B&lZUa>j^_7wcSJrD_Y7y4>1Y6q);wvucf=rYk~? zG1+ma>J#-|CQkk^w2!)8DOcE(YmB7#5j#jMDA)CpHcP%A+wDUhm)nek{BkXo`w^@5 zUb}wfiBhm=Q6Kh8Z58!7mjAMTTlly3$yK%YL_*qLsGhW1WaKhQ$6^h7g7j3o$`Q%e zn%YrOyDAis-rdn<&U86aW95hGW~orMtTR6{JF-(PmkKeF_5R>(EwcaK1QOHv>6hN*8PC;Ng}y;xA+gC%X2dd|n~Xgln^X46Kq36i&4 zvU8rSYI9ok%lSBJheH+8YsI7@Au%ljks6_}rFC_zLfh3L;Vsm}PwxUq5qwyTtS z)v^~OtV$e-a`xu7mh*l|zb#f23(7h72g+Z9?XvHqUw&L2v2o416U@eu!nPFkE`Hm` z{r}Hl!vjy99}M$$Ys@L>0`u>6AQ}UDQUB~yl&in9BsYMk~AO@jFk| zjx{n?CVRxl$aoo3H0Y&PS!}+vwG(md`tlYz5=O{gVut39DCKx9uaYChT%gD7RvFDS zh)tBkd9^-NE@mc5ZgYGz+e;-??z1zo(yEnXXoZ-0T@o54|D!S$5)R9BgcaStazy3w zYNbxqS*`c7_O}lT-EKvm()zS$n?9tnYQ*f=D7pF{Ehm_Gs9TySxf0t?-6Y$F?O7%1 zQDWo7g7(}?(q?&j2j>H`?aaQH$XU`OxC@(9eaTYqh8kO|rG8U%L|SFE)S}jwa+Zyf z0f@bm?C&jd9-d^4+Il}Yu?pqMO1$8BxJlA?h}|s~l;<%?`{mg|KVizV@0tyrD>q50 z>Jo>`t*QF7y2-8^Qzk>4(Kr^RilER!N1Y42t&m&@R<+cQE3%Tc)>N+sj36VQGI zDQD1rzn1j-Vt*0~>hY1J&GO%lM`^uN{Nph>W3i>` zdT=)J;FQBZ+BRR<$$!JvR|8n(?2i|t8A{U8D)*t z)mGWA4d$j)Z%8lGu8f-_FKK;+64d-`y?gN5!^? z1?~F}Nt>mOw!>k2AK3wS(I?uILZj@xt?AY(iJM8Iob7#E_k&|3y+Ul2SWwQjk~Yg1 z#+jX~*UG^};DUsk7&w4!Fvy%cN9n4aykJ zZAqKu>Fwulwu#5KsY@PUS|zPsmv{$SbxQ4}=V5K7QYWK+?rmGg`Ew<`v)C?TX3=6_ zxUShI&e~4XJ-e#jRqvFU%b9XJIE++={xjS7zgW_jiCytO`d_&s9r*wA_WpD9KP0|l zQclxe|B|%6U8%5G&|cM&Hp>_0SGK9gN^_2rRqLGEYB{aO)qkYHs$?!#YBR>nd&yE@ zybkdf%r9<`^jTu(iUsi=m$X^z9o+A3oqpw*ut-GVr+(^sZ9GtjizD^|(5K{pnxZ-rj5tb+Az%YV5TFSA~;s?^9*Se+l5 zD?@{tn3nBi>+(=#tRm7RGZItvh)`^tmJ5fyte9Np?jghNuw4-|_xMket!$5Nk)L<1 zw5l7+^&CG(xU9CUdTcZnu8_-#UugR=%lfG)x{Qd>enV3JpkEB%CHt$GD;Cu6C`p?o zxF0ohyZaoUuV3dWYy1I5OIG(<7isC|&kgx6M_(jUza#Tu^`FojsZyn$EjwYWj236h zD15wJ6x55oV96k$LAra#48KFsP?Z%8SCv(Tn0@7`>mIoF>|? zT#jnlG_%a;Rq7#gY;q-3ZrK%fG%8(NWw_3&k%zuCe@#!R#2F}WQp)2>k<5OyLDKh$ zJt!8Gcm6#n@0~x!c;NLHK0l87d^?}exhajES4!NHu@C$-WM%A){{PEu|0SpWms>3V zN-xwt9v-3Bj$OH z@9UTosnQ?HRFmAinP^W6mrab;)r4Y^>QL2^y<)ChSB;9*=?Ssvx=Akgd~ecLRc^RB z7OApt)XmXQ)T*qBMx$eEMpllEmdVz=($cqS{g~EcL+5B2zFiTCjg886w2a5Uh4#xz z`vlwjCQ0YT9uN!K?-fa#CD_i}AMg7wK4eix^6CN;|0 z+FZz1%9y4i)+{5Tu&%BtulBpVOH2smo`Z5Y`K{%cCF!`>PGV;H(*BOmC$>&Ek13wA zV(qlq8#^~G-zLzB;6-=r&v(mXC-ZxRS#i5 zS+(7BQ75dIeWY`p89%mULidI~)mA1n-~Zq6sq{%>F>{D{qNn{U+y94g<^Y)nZ?xq3;pD0^*56Zi#BfT+^}iQ z`gQwl*sy-XwAqJ4^~rCJagJKx7+-0|>k;3<`ROi6zaaLCSkMmtmb6)xZb3Wj!TS(f zkMl2!8w70eLT_4ILY5c0So<%};-z^@s7Z~>MAdG)%5hL3dvdux-LA5iSabAwmL=n6 zOU5gaovaiv+8C8buhc7+jL~&U?`~b7b%$TB(s$5q?e}fnZ@wn!lf=?uX8CXXO{Zz7 zC7U+LY|WRpR?2TJadJN5^ovhd(Cjy_N&07E?}!EM^;=1sWzr7jo41V@v{GIAnDuqi z9F|(uBG*{8a#ZR#+^7uW#_!)+zr7{BMC>TBAntjRHp{ZNv7P??i_f3m(o(}sE7qCm z%a&}Y$GRwFWkdHzE|RCQ$CaY$JZq{x*j)5C#YXQIJF-4JdP(InCp`M-dbx)-dWj>G zGhtUc5Se9*Hp}Hi(w?P{l#XSL9%n7Fr~0o)Th)4kIVl`qx`A13GESEita^K0H zbz~PkJ+#61BhUT#$9$Lg4dQl7`uk#6iUo0>lC)XspF!NO^Ex|-yN}%b^k>Fp*5*!J z3eNT~1%C{v{L~t$++s*3A&-nz>f@xts?(LRn7oFi6B`>lJTg;uaN)9$T+BwxWRxZM zaE_Pf-cu%S;u4h8`Qg^>>q>ft*c`E-oO?>zEIU5`9=>?-QrWt7iG5_`*SyeCaxYTd z8ETR4MlSK~QDxO~Ce??)jq(_`NBo*y+-#StBz=q6?P5XP$0co+9mQR}V&f+1*yl;) zMyFs^TTX+V)+c1OnlLI>8)=X!zgj!4kFly6>XiDx3Z4WkT#9%wXP?5tF-bcu{$fHf(HOct%u5L!n4iwxIblIVQ?X*%$xY&E?~& zj|z_%q12xGTXF@dvR9y1ng&9>|8( zYuBGDxm`8Im7lA1&8jL-|4H#>-ZAZXlBB;WcD7j1jyFi!EW!19-*)rXt<$^wIMR7; z6ROd({-C#5mS^2%ZIPk-6wg*akxQPj`Vvd`Sh8WmR+YKH302uTbda@|c^Gr4-LI`l z_O#FV4d@~zy^xnfi2;;pUG=$>zGxyM_o z)Rdyk07~f`Jy-6o&XsdjLwIzk$~+c+w~1qx!c{0wM&h*!oA$a`(l?0RA{LY<_OPE_ z4Y0p^d%J$m%zsORnf)$rJr%vjJQDE-eUDYHrWDH6f8^9SwY;gkNslW(E_Phy2t7{5 zvEyW%>s$FKc@>K_Mzr2gSuUrCMX{*dcaO>_9gi=_D8|RuTW~?hhXIdHSKFj=HcxJVlBG(#y_LzE^*7EDtD*Hs(3dylmA*p5^ zid4vPGD5B`r&wj~C^^zvMw>~hdZ}MX_M1tPHjmMS?DFQYuBwya>WG#G*;YsBo%E&J zT5Ycm9U$c^+<^MTAKALS_LX#p*fO!8K6gsmEKfg<^Y{+y7XEyF%tYO&FRja@9n_`zv${-bXhL1i*Vc*liJ=Y@Pi1dLebl2{>r-#iVl%~p z`fQT4S%Ug3-R}P1XWQo>Y@h#Vvt{n`>$A(54Qfg@tj>REE}B=ekdBCgO?X7WO=Eh^=~f^ky87Cpag#BMTwShcdeLJqOr zGGa5mET-*mWI!@s>Vj6Q|Cx0`!$)QJjlKJ z|G#hDET_fVy=+EkQ)G?)W^`wJ8d^v8?|ZO6IFE1bA0|qAXR$W1pgk{+nv}V3G?}jMs#l#>lKfqcm|{eYl}=bX7yNCX6F?p}s>~r`z-NSyp&wl(Tdn z>NOu7YBK4976lCz~f1rDg7BJJys-&?({m*cU0E*oq@}juYX7E+ziaqI_}%s1I&aDRqCFGwa~{e&=xyEK-`xaYvfEx&Hb^#%p?dYrI*K z-dSuHu^`?)k~Yg1p4;9UZ=3$2F0r3HCnhcWzC<)nIaP<{qHLT@^pA!cm3R^Dniapn z`TS-{-zj#FSP=JNNt@*h*C(Hk%kw$zR85JiVTt>>J5_1M8y0`Tb$8`6@*KEWt(aM~ z*pBY&u|GVq^EAmP7i5k)$1#2~^qUkPf!~y*PZV4Czxl=OLOb3pXPufkmXhLM;Fx;} zRh6|WPyhYmD`=jfiTVg>weIjYIe4(9!&ylZ4pWeA)y%fGNIaSWaCClvco;*qJ zG|CLIw3SSen^^vN`lHMfN zEf$pLK1rKpho4{k>^f(;nac1#_SP8xv6;S}CpKu!8L3(`wklX-%KfplOkUfgVsdIK z50#DduWPF1$>7MOsq^JjHd;Aq*zei*ClP1Za#N4W&q=d;QajA`C^`5Uiny-Y0A7@o%;j6AK>M7yiD`oJI?=q zm+imY3}x9pGGo?Ss!(s*re0P4HC&ZEuwLb#m?NRGQPZo(%k|r$nsEK>O1Tdsr(>z{ z&Jj7qPn8D%r_YyBgLFi*Bg#g#;&>gnyqTQXa}X48t}rLkmAy33!7zP#LjsrLV0ZTl~OlG*AeHN8-yX1B;# zpjoE$9J!9Ix8Kq75TRpFs;rTbp(CFulIlpcs@lw_Kg=D&!=&=2H>{G>vzAD^*3`^1 zmOF?O9ZT-TO_NJB+nHD$ZCtRA z47EpBg-0}sadm$|S#@I6Z7@e^y##);r zr&&kZGozExF8O!Rj@{BuuDoUTzw;%1vDjr|K|AIoZ5EsNJ+{B!yy>*`yaUjXb;@;R^Ib05L} zzHJn9#JXd6&7TcOl7p$2k8T3din_QpZFEZGc56f{7K1VlpS3@W24Wt=O$0Ow2y?W#-!1#W&T=vc9*(K6s5LXOW+%v5%KJU)8GCtadykRy z9I>6mf^u|9+ARN9dmrGpxBuzKz2!8qo7h})s*oEIPfK~sM{i6!$Y4gkpmKtwqH;NE zK1*9`Za#);W%`=u*vXaB@>(7y^_RjB%9)pPxblwK9#2a8Ik6YTf^xnoX|wET-0gp! z7R`lW_w=M1mTNc}=5IUfR_=S;{;zC3Pt26`9I<&~W-;4;N7s*joK5@!3x5~5C1NUG zW@E&gr2p=1{9hpHi^MMZAN>2DR}TEUYPzc)r2h)PY-##0imzZC`jMnV1*M{5L3@pt zv{`oa9M;;^8#l>k4%717h&iA$*2n$?r#^FpnwbkJ*Ic`sj~%{b$tN+*rSMdF21i$q zkZ(D#udysVR3QGHKcGF+63-Df+wUAnUn+KmSWuq3C2f`+J!ch^XMNffCpASr__0Q; zYI(Vu=~*h#D7XFOaZQ;`8ztkT>JjoOnGxkmcBFRQVf+?Yj$w%t6E@|Dyegl66l)O+ z%CT0`W(htow0-}}PkKm$oafK=-tPZ@Qp=R@>|9v2n_azLMjf@0`LfH`%7wEGOXPxk zqRjT}&m(j+O3z5CN^rB?_229$#hcLp5fV}bWK?}Ru-;ok-usgxwhN<7Dc(2 z{%5pfzmzX1|A3_55PM53D1YcDD1VOkOSYef-@GoUL2Ag72K=_Qyje;fQcuX_N>yZ{ zbmQ?cjZ%eXd$J6T!n0hvQf`pMZRtr`!nI}QOu4Ilojkc^K4UA}w1jdcC2mlzRgzvW zwoxo7*F};x%Z{!~)~(;vd8*vg+3auM@-%6v1I3OJJKyvI z=lETLnq9Qjpv+&CMNrIgnNveS%OfMD$dZnf+ww@Xt{B;3m&xM<yWvPdLSYsTHu zHI`dC(mXzVh@6i1wC7p;eag&-s88bct>?$3l3pg35)0~+mb6)J+QD<4TkGQ=&lg(D zE7WWmEXXGaq=6^;4cun#vmIsE{y)yn1Te0uYW(lrd2hB%W+s`WlcY&ANxGzay3&>| zX=zI+l!msHQh}yT)3kI+NLorkAtGP}fhedI6(UPPL@5Z0=m$~x{BR{8U`2rlD2Pa- zq7+5_|IWMbX4;ey{onS?JG11TbN74CcI}fnv;9TWeTaO`{_Q8=&j7yw4Bf-v{~6s@ zA>4km-3H-a+dASA)-4-Dn#)R60Qsem-$I51KK)tG==`M}PXj*}*Z>&%&-&jRf9?l{ z_zUmAo}sPT7pD`ruRH7o?)#2997tGoU3u31SPWqE$gIlJ&7Qh^b9Cy=;0ABSWMbi& z=cI;(ibKOjcvD@JbJ2)+B?^N=8a2*q9-erwGA(0YUVx}DY?oJ%D+{9i86m0sYZK`f)9fQmbwtW?dH?r$*uq zig6+f-h3weA_{=Nd+kVe5mVUvj#o9&BpoN2a7qxW$1=zc`BiXMQ64)_#;Tgd5t%J| zyjXsfc7})0NhKV-sK==y)DH+B=Y>X1Mk$r#55`lKv0-l7!MDFQiVZ?(2v)2g+UfvH zZNF_hQt}4MpW!L}VIBBoz()X6Kc6`yzhWQvq8`^)|4?~?R7$H_ z9=AE(<0<{PDsoF8->T~=!iHa5$4e0!$h=q@%yYtM<3f~#%d=>GnV+!olf?(!h17`j z>ZoTAQ;J2%sJRaA&godSxBC+1(`>XFVpzcroxgS&fDW3vnCSWVEI&9g99x-MR$i7+ z^XZwjR1l}kWDGCFDe#aCjY?Od|63Y%XJhP9MaJ3dDmBBtBT`bD;1 z7lDriY5~)34d9Y?`RDLghS(o&-_X(8VmdS)c+cVSgX2#~9PsL}seK`@JSaMh5DgHB zl{qKU@kFE1tP+9Hn6$*?!YK41A?Ky;e9hN>=(3D>{pri#_X7_ChOh5|OFB+I>C5+a zw(M!!c)oFinui%uU6b|67%C%S#2G18Nb^*UHQ>_=KbNIf4qgL{1`NGP;O|M#m%HxX z*|}kJ%lgw>_RxbAQjT)v%RlPkx_lRrpP9d}2LB}RX~59C3tW;} zH-`FaQ$C!fH|&L4y1mzKlgYuhz8b6Y3piS>c4`w)z!!gpJ;BN(G~EI6HFP7tq|87H zFm#85OFC{IJFc7yeeznGUe{=SpTds83Jou*aaOxeuSsZ-pUeyG;Cq0J0YmR{a7nrB zx;i%O!L&;1l#qioVx#pGWG10awkFbiR$Cn>*?rb(@FrjrVCZ&%OFA@E4>H(KFWR+g z!;bdto)o37O9Z~@3psdbZ+g$l6co(6|}Evi&}N<43QKw;WVb1 zL?mKatDFk*sW0%$|9qD2I`Hj4J7DPcf=hCIdx0yybL_l7gf4q&PBs4{+s%&$czFeV zmsQsnw62P$V@&pJHDy;8SEVuBB!VM}-&-E7P!o!9CSWm4GJ%)STGdWs%zP$v-a8{4 zR{4U`{1C$XxZ_qtg6H4>Y=0dIUI$DEOnH`oOUgCx zv^MY9(6MdL#`V%?)5-h95;4IzoXY5Y2=|*L^CJf#HR7)M{}-YoNxeEv4@te&uMb#Ly9nfk zlQDwb@HlER!qVra=c*75=-eo@x`t_fke?3nGaGy0C1lSCxIxz)OgW73(Q3OIq4TdxYkm$w&(zP8;4c6#0fwI= z;F5B+&k%l0{Rm%~*_C!?I#6Lv?Z#x4S}|NzaI|;bVuuq|jiP0lcYJ>8`?K@T8t@H3 z3t;%!11{+}y`(?>MSi-88O{WkX#5ZrQ?|mfruNv@yKD%?!NfGtJ4t93>RElz%de?K z*GF%Emj1Kg&jbB{q5nF#q~qxO^Z5|^dNQBdXx$h%RyBIir&ssu?D=gu__@Faz=nqG zmoEjE)HgJq#(U6f-++&R7iT2h_?n{J4v<(8qwE3eR?Z0kDuF^w;U}7zSm_8rs1iPw;yr;*f@VuM-7eEy4UxE}GwJ?{SRv&>u3r`zMcxR<4HdAPw4D)l zM)K_)q4@~ElGV@DfY$?y0mH|Q;F6~M>*i4X&{2G>F#Arn!*}WJ@UyPBE1vGX=3USE zY5G9ex*{;2oqcH#`|mL3eVjO>@s*j^>U6)#XCg8m7*dv9{x*A zX(^$XV?Q)V&$nQxx2BIDrADW$TRCxY6mr6!4yjLx#7n1xKD}P@uH_@4_Z;~1K>tzn z%7^+v`}6N0z0GYM?5HpECh|A* zuLR!*T;tP}`uor6p5C@|p%>KBl=O%*QrWf^`&+#}y*~0b^U53Ghk-vGMelvvYinmV z7ME9{SG!W71AhK>uVwr9>EJ7YHGri5sDGmx@d`(YJiUJoMT zi95x(thA5P{p7Br=sphqBjBh14c)DsUc4sRrFxyEQQGduuE^&rVwF~}Pp9N}+4`Fe z-T<5inEuiPF6n*ik^XWl!Bpl1I?Y(G@ zN5uZ4Ct5cnyeLsveq)UJ1-lwUz+jq{EF3(YiSGos9^=$SisRuxexIYBaPmT-6Ng*Y ziRwzcTx~qi#A@A3{k6Ir?eJ;(<+b3q0Jj0A9KQsYWc(c87-9z?`vY0;jxC4NWxwt@ z5?t%4VQQ@D=wNOPiI@Ed#7Oun%Ht#QkWF?3A%U2hx~e!F=Q*+yy5dA*EmR%}`#ck3WLfyh-poz|_Zuhov^M_3`5&a*4tEXxX(|o46pB9_0z5AJby#3%obK z&~Nr@;q<${#5#COfZbon*ubmRt3F2Q&RbqDR zIHN@OKSD~+Y$FkTVkr*8%d5kS`6N1Qm>AVmdmS*El&}O6HVgClKrotOkDE_)SAxwY zV~lKmAB;IMu9&<4X@8iGniq_fB;#UtP}ol_(Qyp?7?CA8Rq*wiKH0EIZJqAqv8Y)^C4^2P1$XYECfJ1<03 z?9hA(4OSX-@1shs2bKD%OBl>YRItqbdBC|}#+0Pq*}C2PXxCZ1mv%oaZ9IVN2{7$` z6}Y6+-e*6!O1JyTClS-5m7$9V;-9n!;^pq6*ep)(30rp+R^n7zMP!SqsGty4TrB#; z5z5`0M3*fQ|4KNti!DD@04Ba6VX7iPpbr`^ET4!)qxpmmf7H7mho_)ZA17jK8jTDV z<{m`6*ASmfVQpEWe#u%%>YwMApYmmRFXjI|_}_tl0jB)J|0uuC#uFGS&qog0y4r*x zUB01no0PrVepH`hCR}glThkHie?K*bBClseH;B)*Gai2x`4>kwV{KC(RP7SfnAE;N z^VI}hGe38N?*T6Hd670ePF~>epE>6ZwgGXjrUUzm5^*;VQK&*uPZfGSG!z|4-=aE; z#F|C|1fRfnQ3=8*{a37b`L@)3lfPrAm_Ku)ki@x0GW$1W6PBFLYF>s6vwiliV>-f#i3Z2p1-&YPpc?lzoLYLkUtCH${@p2{y7oiXCgZwgoJxA5J?cH za-95fj{crs)_{4$%`aaJxG(U_P$GT@H1Nl%kk>-5*{z-RmP668^oeI4;@D}V}6@mWp$sd%h~W& zmXCA5n}N-M;iCgw(x5%f5IM%?j+T}|Hd1w?CWoz=_10IhXe}v2%U8iDpX?McPJDU~ zk)PQ|J_Y^)@DgC?75>Gi=i7ChW_CN) z(-c19q_Kz))v1JMn#g27f*E@?ui}9hMMkLXJRB9{;sAsn_5wA|{=IEaXFfW`ANTNK z+UHX6tAXnP!{E5c7Zbfhld<}jX}*p?S2~mQo5H^$0|Tl6!`CcuNx9CY!WYVt4hi()TQQ_E z4QyklRHm$1J+?Kogvp?k;cM&;@!xV&7>lbDB;T%6H6LBjF?`$tejo54VE9<_w){G` zeCB9AyaqLUxAr^THoN^-0bcG=Z6(&M{yb}Ons}ROOeBKABDIbYT?>aL=gUUIrA?DO zQ=EHZxbNjT?Yu7q5}&bS@-LQ1#7FaI!5T6tW>!iBOXs=sBaw(5L$jM#6`v{=aAMh5 zj6FeF)a4ug<;Nz+@<+-iYuq!vPtq}b@j{~iI73~i9tqla+UirvX7`5v>wev>OZ2e${e>K&zi-}0so|%k6>eh^$0crGGEqU zUon+35R_8NRvZ)A!gzIux79efQu8W zX|^u=aqkHCg!lT2_qyV;m^Ev_wH~0CNAT8>(v?N}%_Jd_{9cujr7g}CjtBH-nmkjw>wG7D*)a5(!kER%7*FGcWn{O8%ZL-#G9oz;wXSn+GoG-;{6Z zhTYqDN%1^)!Z}UWX(?*amCzhZ2QMV)_v!5;zYO_FJANMgPTtx_qfGf$ zw%`(Qp%gLYnE^&tP^n$EwOS6B^8ie)^Qha?CAwwP*}5IAce8Yp;3YsgVCYT;m$W)} z|5>iXZ#3OuvvSVqv#p&Hi*X*Cd8~~@>rlY7KTd7Hb-TiM837;E9LD5{{rwu zz|bxDhey`>v9BL`+PA+k^M@B?ar0Kf^l!zFjWVa3u2*#5&$+l^%n#@ zwk*F#1C|#rWrhqeZYAEUh_Wtk_%zSfu!`7`V+jw>1lPLbl60k(DX_$8xBTOmA z_A#cWV&9gCPVyYc*|1@9E#|BvRVp}xRy>JQyADwhIwOBgoWHMR6{ja`aL*%;fai9f zb_+yT7ovVqwC1@EMrXrQfK!6zY(ab?^YC;8pH^VQl(7$P!u;Jkcqgpg5XW*s)+`&~;9wKEtJx_(zXZZrE%ahfZ2d)xAVXywGY+r`{(uAahtbZ zYVmP$LboPF{9e%o3rM=6|L*lKC%hs1NI^LgUL_ro8ZgveKGiz zz{dc?_Z{GpoE-MyNAoTFL}9yb8MD#M$tBi&gwwZUR3y76iF;s<8WI@85ruFYMVRR2 z-|zD?;M0?FX$81r21o*ipXuO|jDCCQKCji-Y^U3ARh%srwiR3T2!y_?($ON?b+bB~ zn?~aFwJ7oKixDh%%Y_}vFP44AY3eK9Hri@$*Y(o{J+nT168ww69f0BI8{m@6`Y_ZE zk}zDGh=JKG_0m2EhE4~@aNeo!$IFdFs$4LT?-0iUbI7#pSL&Wyp>bnhK-)}UaEc<7c$rPh}}*Kc}z9^2pvm=b{K<&d5t}p zat!!%FCt&lFKz_y0d5Bj-Cl4>=G-u3eVV+fW#jHv2{DRvtffPaqEZ9N12PYcNEBK1 z12zFi#es!(V9blmr#hHa`EEJa!*E)!RzDRA{T;dYy%`okN>au?;yUiSCQ>fh4+WtY8;~qLkz26FccFZv+HFnFBfV0j~_+;%a!I`Y9h2i0` z1dC0A)11RyWYlue9~>uK5iKqVy7}R_JEdqc+lYs4^>rG4;Deg~eeh@c!Pmfl1Uvzl ze((?Q{}2ARW78^OZ1fhnF2%%|03HzG(FcGOtke%E>#Gq_I=amBq8*)#^AA^=&_fia z>fyW;m(86;2M&iq2{*;CW^4$JlBVa6p`#mH;;jGIm9j4(?d5Qy8(8Ef2?o_#KqH zILS;57MxEwG1mXIlZZH5ohYtsiz_@CK~1!P05*=xl?Zm^4CDmU!l9^~c|U}7zd7)d zaNg6U%UKuE<&bjD1wRQ`3Yc;>`rn)R$~?`!?&Omg52?(s%CuEqZ*^l@%=#|@STZUj z_0#Xu*-t)Ze*6;nw}3|hL#IBf`N%OpPHJstF6i(k#ri7)$a|iYm*3h*ed_ze){pbk z_=L;|&o0YQ=q2dZ!uZe6VybeJvS*CMi$zl|{eiuoNdA#iP^mGb5=kOs%O)xz`+%9K z(QqDf^O zx;y;c^z~u8JACT(;UrzU#QJAJHHO`C)}uxdd5QPBcr(Fye0U*F#q|+%$YQ7AhD+GL zv)AXl1Z!|D#VHAv1VboWiIl-vxR{Y$5FF{@WdvoFfDK$%6cslWI-~PN4D9S_5j4~cfv>Hb~HdbTJXoP(;Jz`(dLrSprq`6}ch=DgN+ z_&KTZQ<|Sles*4-1%3*!95DR+3|x}&BRw?4UZu5J^OK#t`t4Wk7j3)Wek}4L+Qj<4 zJnP2dbW~b)q>3g>7R6^&&YT&|+-0K$9w}`}IQh{`6T8@z7tmUxhB3y7q&SSN4UxWz zs!+oAa=mMGEb&a|J8qI}zHAdKD|CbHUK%2{X&JqQV5K6HE)7LuX_OhNs*uAE=eW`` zlq+LHJJ4HpFxfA$|IV@AvN9azyk|T+56uH#4Xg!B`FDa#$|VQW{aZ@E@WKsSxBFYg zbmnw6NF#w#AOaLsN>$j_1L<;AueEd>RkP<|GS-04*F!#C=_gNsKL@-3 z7{1>0zc=%Qd1mK}rE(X7URAs)S!{5U9MbB$IbEewxYbRwi-L&j#Mp9$TBzxFeO}kg ztVFh7G=Q%K&H)VlUw})>wO`crB0ckXiuH&)4H524^_pNOn#aF7Mv8`?U zNoXZ^dfxgeZ!o7TV^)2mbw81LMTI04L-Widil&z`2XuX0p}P%2R;Xw4;cP7``_nYhqknA$GJ<|soQ?V_AK8q zA}OQ;ad8o$6-0!|B{nSBc}(RJbU{XLl=XDPR;-=+CF=+hOx{tx^q z;90=%^}7H4`|;%+5n(RHWlEw)9_Ag~zg>=C*{NY&L~I`!L1bTcrcH8|*R6+660?YD3G4w3KRy2U4gP*`!Vv!#y)LY5Yvb0Y7951U?QG-Air7wzn0Xp-L#MyQ zF?hoqj*C?DkZJmOa%@pK>%R*8Cjm)BEO5RnelN(bxP~xDs$eod@!-ug2^=O!l;|ivbmu;uk?sQt!821J{yjP8j zjPUBQ|2|#LEtI2{Po&;21HT%$4lw0B04`~94*i}fr@3M{RbNY`pRpiiE$XpRC|47l zMGo%?4hdXN$fbvF4f6+9jOAXwUAX)RG5{T#!Q&%TVp}7CYQXTZ1zgfRVIgdpG2Kn>RuQ}4obal0=Mq(0 zl!(=^Qbp|O=*qL)wUJUTj*bosF0FJkk($`V(8;AZL@DQOJGeeDSB-Tu>`NZh<#-4_ z%{ul3_@9Bd0aK1mrG7blJENi@e*3M>3kkp4xeId|FBV05z^?L4eQ#isgvIZVZ13?I z{qCg0c8o%WtiL&xSV_3f#CUIG>U-)AYx7NA?t^~0q#ykd{7K*$z?Az{|9dlT%`-cG&qAX}sde#X^-Lu%WZ{%<^ioJ} z%){(O%wia^O#Y+Q#a@5t@#)uP;dxo%lqW7`KbQ}A{0Te=>Pz^CaydBYi-zy!dQ;~U_T%zdwK z42l2O+04#RB4bg3oYyCN$MwI4yvNVFf^LE{4r02}@d{H1yuuDQG{uQrA5lf)k zjFe$als=XGLxorgpG9!*u@QnHsj7tQ$OBb(VFcY>#4SZjy+mCeBD-?c>3&TtXZydW z>myvAmETo?&jRKGrao>4m-KNzj`{=s)ATE;kIfw$b`W;Lmo`=&ROR<7`=I(vza4?Nqdyy~*VYX@#3W9>HUjewTWacVWUuqxf+SDZ553wnxUs5eU(~Fo33-J30d1 zJ7P+oVBh8ysON`%`75&XVk!7&U>sn|e=)cuWB+q}zh2z2VXH`Q(oF+$R(RQ7U(A%@ zT3=@Z;8thOlX&BM2O2`BsCY6G%;P?iIIDRo9IV4of-;v8iHXG}id~bulO8iK6LZCy zdSZSawlQ+&(?aonWIwr(xyj1>MDzbR{2BS{bKt)PUIz^S$q}0W+jHpITAMxoPnQBT zJ|@!CrWHlrf_^ApYzs#qpeWS=@7a(AtA`CwiS-q0O?a%ELZ32MwW_b!R{KviKWm|v zp}xF*5cnm)Wq{%5%ixkO^7n^Ej(K!{+Q`%_!=X)-|f5Qd1z}p8s952IUKA-V| zoxd0N6T{_k;o&97LLx}KR;q;}ye^14=C&sBqqo^z+E>C>&N5@U+sFxn*HZ0N?L!+BWR zogSO6lC>kKyzr>#@JMYWJjz+4>Swq`p}hQm1k^tRMa7{imcBpQa>Zdr*szj6(|jL< zFEejF3jPG}Gr;iuJ8(&6{vE2n?A)?pleeer;gXVDY(hX5-9o6EMFRvPKoc|@jsIL? zCb=%A-H@9oPjJJ{|;@bjY{IY8-N(W@|^w-og5# zf&a(xTDV6$dGFVc4)3!~{}KkfB8YLvBIS^A6 z<0;pG;QzrEp~jh7Icy}iNjh#N{%eU)UMuHRI`M~X=Yw{mdcmiG54>q=XJb3HZGYUh# z#a#hw7dMO{i^%70)M;#cktkuE${H5NRicEePD+OwT&ZTl|ejJKCzlIW$rS2W+r zQCYr6f{zC#0fz6n;F1R0bBG^9Yuizrr|M@dD7F?iS#Nm;dnGJQ3Goz|<%*k;e>fb0fGBXwd6nZQOm#f-CFeOOuDzt#NJj?V5c@JY7L0L}yq ze??<7fBXIO`P!czdrlwZ&vdiuUiaqMqpscSzU4lO>Sb|nq4iTV=|oy$UmPW@k$BdP z1(P6e+*-@#&t>Z87OCj9c3!+%d~xzHbURnALAD6Ikq=GY83=Q?wvtmj^@D;)7P>saM!w=i!vN za9DU8N3)1~fZep?UVubP22iyXfdi*B1Br{(RJ-=;g*|fWP7tPz!o;^X;r)k@-OG8Jb zfxDFTI@Vci8pC5~+NlU)^CT*-%>~AsXw(Cc=o`@dShd-HHv)VjFa!xglU5S1? z+zWm0<=6CQU9KbKZ~9?k9OnMO2*A)^3N9(vc_&N1eYaQPb!XAoTL`bdl&$1*GBI<; z6QhA}371W?a)gL>%sbkEt4Ik7>G`owbLQHMC8}KGTbi$K=o-H627efM1TcL47F^OU z|2%%qcZbe1re1b+>^-@~W3BNca-LZUgjP^R3=if%pTCsnm?(USofwfm5$Ir{$*FAo zWJdHfEPQ9Gg)X8rof`k5`J6RA%jXL4^*}RV_`C*O();ttjTq8lk7u&){g@;m-1uoj zm~8y3=I;>nP5=5c_`iU_ge-rP!6m(a|Jt;*v%Sr;#!A;cFLp!Iu)JK_tE~NavB>ef zFdUWn^KC8RcQeaZs*F>hkG4eiWUT!Cwdd@L$u>V|tLzud;NyeLAxy zW!rBZ_(oteVA^jtxTM_uYp`6no;GjW$zIQ|z;siuA{hBnbT5BnEXIS~O4L!(i%uuj zftM}L47y%>p=0{di{P&UzXuE-e*^z-_;?Q{K2CU+^eY}4#>81P$FMn!$UIoC zHjz)SPq)4G*=Qm*=Em0(aA7U~+A-y)M!Udi8u1-X>9gz|G!NIqpB zfr-w1FTXyYe*Kgz{WHK@fo*`H|0wvsqn{<7Zg0eN`}F`Xf3SJ^gxwammiC9NyV$%8 z@>k*#x20YOXGvzI{qiY49l2Uh!v~Y6l}1$012(d32H9y=P8i`S5uNX_I&|f z{vt!_psl=pSaNE%JXPQmfhm9~&vI}{x%LHHHtgKgwi&e}E80`C?1ok(ye0SJp)|*^ z0(f$WV}e3nl~Jxlekc!dZ6#is%^d3BgVUPi-whqpu6Kgp4SdC?{qN^v{~WYYn__3I zhKzN$wyl(W`~3U|$ScEpksCy&;RgUD07;U6F29q(bIkS)d)vI7PrcPp58Dz)NMw9i zuSgz5Z}G~}M4qM`yTGpmJ_eZj{1v#Qw|qU@V?*v4>mUwd$0j-2!IxZ5>U!F?PvBdV zuo}9;*3(3ZlmHGgVT3SeE5RBws!kUz4oCMmHGXEWTAdu6&K0wBnL9)pCRc@DZHq%2 zCem~a%vRWs4KEA0qum)a$IG^JwG$j2IEy=Cs_Zj_za;nk%Cl~Iwmc_;uLaHlOnH6? zE~)8xy)S!g$bG}qpM;hf+_s`6xGAdD1g_`@8u}B~V;DGo-Bx$oT12 z0tL8tO+s*bsa=3(V1g%6M*~Z7BB3;zvzfSYiTjrK>ZSv(Q-OPkYgdE{xiNLA_xZ7} zl=gekVb!Uc!lHuT*vT5ZCO;kHHIfeV$~0VKkCO5XU`is-x*6H>p9;PXI1e!8zZhIn zu6cH_{5v*yVTL@3lV{JogTa!=)jbUZh+^?la5>Qu1Cbr6i^xmd(zu9RCgA&R=AizB z=BF2W8R$tregXVV;7@?zXT(g+Pf?EbXOJH{+V%}wcbM~2`~BkGG9QQ`3T)^JShsSd zJxf2fqcl z4KRHE5?s>z)|=0#OfX&c4iU1RAul@c*9t*b;pfoM<5<6St1yjQ&Cw$n7r_A6YhxnE zHs3A4dW+yYNik50M8XJVR3MTcPsH-#A(q(9>S528O!(glOVm_3Z{iRM#xHwr6&QP%cRhtH33h@|Fy_Kjql+ z>ejl)=GLHwKBUSa5kJkr93#d$P|Gt>!Sa5dbIPD2c2|k!qX#-PiPyjX2mA-XPXNQm zVQ`O+9D1!|`M`9}(M|7*k=;Ud zIWC{{=Tgnrtl3$<)`9NTpK(CZIkO>r8^F3%l4-DBSw z@>Db5Qr=^Z_gZ`l=AjM!QS1J2ISRrt)LghWjwnMQ#Z)NX)>sx`Xuw=dASQuXsa;TILuZavNY@eL9jZ9b0fjg^{i zKlx_JSLVq-g1-g4?bDL=K9^tp#+FVTapi>GE_uHci6Vi-U?mw0O_E82KlM_tPp9$3 zZ24NjF9j|KO!*!Mmt^7_9`C2=m(K)|=&|q9z2HUtsJ#U*vW9-wx;&bWinAs+DYL+1 zTmT<6Y4!f}_tbXUIk1BpksKyD- zvcOW0IbM3Ib-iWgX3H}hd@is6Fy&beE-BZ&0)yjkdt2K!&rH;-$7k_2fGt&LyWDqU zojG_9aI!|z-A}%zpL`wsVc-$K&^-kHU(j8?VedxiC`>*w0Syo{zd9IV;w3~_IY~9nSP`}w8m;T{ zQmQtCfT9Ldj0F+AR&>uFD%{z_4sdkdl)kqa3Y(%qnt9HsfGou3^)r+}{m&I1fTZ-Yy!{jr|s>iv1o z=$DS==a}iP*Zy+kQ3;ds{otc$dK-F@R$pE@cUE!TSa_NQV8EoRlnD#hbCd$ea?tm6+1c8%-Iw3jSJ6=q+6(9pEYN?Am2<-dCJD4Y0!9`&iA5@! znu&SwLSjs^i?#{aIMditVjQ*UuZp_A9Ty>6aD!pGN3C4%CaEf^#Kr45|DrLUNR;1`}7B( zW#*U2BF?`+0+1v>{Wtq?L*MTm-U)kOJR^Ten&$U^@-lL{PVh^C4+EzDKLIW&w|sDi zw<)4K44xHJnc+x?#8Zg5vpdcng-+o4{JX5fn5~dsqfh@3`J3|nMd+SnTP|Se&jOd! z;KzmAGQ`6^4lqs70TB3=I>y5+43Klg?{;yA_2@x+R&vKY3C)G}eju%J{n7kFTg z=Y~1N1(1OUoWxaFreU>)QP0h`>?9YU%Rf)(XJ+X7>VhA`@6F&}1a9|ve4qBn^0~Eh zi7!j^8l{&;srU1L?Wp|S#kN%l3_ZIjvS;v|uFdmZ&rveK$6|9P1l`ixA6}EAiIbX>@eNG?rbFW!2Bq z<(aiKTb>o*O~59=l;;j`NyZ+a6{+b#3BI`B=4Io0io_0g9|mbh7m2ug z1)@|eD~9bjp*PFuXo4pK(zP&gHHENarP)Gs5E|LpWSWW&BmUhs=ArU5+VQQ!Q8sf3NIjM`B_ldxU2_rgS|Qa=2yJNN;D}kprsK+DvMRlPsm=j+qDL; z{UhkDa{^UH+j5hn*S3V|mC&|)g0Z^yNw8F{mM!Kv&Q&%wIGdoI?)dQ7(5&bz_B9Qf z--GaD=8^A#KLPvgCRS?DJE<%(gOoCgbQV@O8ksfZ?YVTvG0RmTpf8TC$B5 zrO8^>WDVHESlOoskfb*f`BqZnDSr9M&-A13gZ~8R0}Q*OCd-eM@@F#(107LiG(=^>p{yoq8hs3$1RtE=6<$(Hn^ZIO+48-v_Dq^Mo9=EwM6U^l@ z2=+lL8BIpY@I;d3-r=UGBtfYOv&H1ad*m{%9ru>bgc~o8+wt*b0oMCv>e&F320Qp0 z0_>L(0n|r5EBx|PK2!etz#jy@37GOf0WRra4!^0E3%tvuXzDK8S_WJdAV4`{Y|%vp z1F>i@6pGNHw&E}*DbuLwmMqu#O1~ZlJ{6b=7`o^9-{Yd9@Tb-t>p!_XO;pSyf|!q3Ct-vJ&23_nl#-<$Dn zp62|$qj8X*RB|kC!^;}+&=RqsxLUGp73Jns#+gsAy5V~gkKL-9I;HQA$s~=oauJNzyK`h0*(JwYrjQ)RmH6c!dShs3J z=Mie9vgSO=npJzLhakFjk z=qC}`2(k};OuK##{0`ttfT`affJ-v{?eo6fu<36ezp@xpy*OMyg@a6*@gA_cqY|%9 z_`HOg_4&g5-s5yQf&&SW@-v&6X}+C7@4Qa)Q*wr;C*y4__!M9UVE9?#f1hjod;I9I zY;}*>*g!5Du&slGym(T3!-Wng8IiKHB|^Mj!{ z?xU5nlgpy29c>8V{@7McAReTIRh~f0fTNqlt z=C&PTx`HeD@(rz9n<-_#P0^^R0NS!JQMg#BxbG(rMT3ok7}>oF)&z^N?RAC+aM1Hp z{RYiPa+R)6;Ufb+7MKW_`kv>1Z}>3Jqw9MT^QfBMyRPHWb!FD+y_iF?YRZ-CQ`nS- z^AG}@so3l2v{BRD=jSVQKM#H<@MXZz{a^okL(e=7T`$5n4vD*@p;O-VQgbRJ*6Ce{ zmPA30$6u%ruSnV~pvsfDuiEUcnpDPTqs!+bxjI|^vEb8zS%BeVwf}vte!p3wsxWWp z==vTrbz?EAS&oeE^d8%~%P>>q<_|KXQYj_YA5GLz+^!auGR=Pfhn|rmJq-Q`@Lj<0 zGXO3rmmH~mHyR?ZayFUT!LICd;Bl8L8|dc&rUki7hI}# z-uGL|bGYc4t^$ZHemQ_0hg3>9a^=w6K&+KQ+7(9b?U!jFGzTOWna*V zPEZ%H1~6r&)t7WOR%45%dyst1Jo&%iKLMTu4Bh9!{}Z~4TQuFT*$e0;y$GA2JJq9$ zEUio(@aZNuYr2^=S-Nw<7XXU@Nisfj*+EOZfQvk}>mq$AuXKqftFg)YD#OvUaf{bt z-{#%L6L7;2_for0w+9+#9eWh~Dd1T^C=1=cf=kM!e`;+$Mf`NPZ$Fv`{xqGz!tpzZ2w#j z-Uf66hQE)4OEULf>^ja5eWfQ{JeobJB3$A=g~_blrQ-i0Xh>t9vc4WDiZ@z6Za>9h$%J*;)Ro!6yK9fZ?wJT#^~j=6r4D z-`3_cckUrv;ZeQZX}S^VSyLL`l+}m+Dn*FAR&|~#AVO>;NmN24L{`4KP5N;UH)Kiv z-Ow@f-JRff1786QA72BPl*=DOt_}5hXgrB(YP1>~tu8!OP8OA3!W!`D93dY=r+6Lq z&Oin*bS8mI$~CXHHjBN&&|d4*T{PLT8oSu)5N@uLL!o#SLFZKMt;T-3O_%c`@;Ciq zKlrV{0l?7zI=H04{&3v5S>3VsJz1!~U8F+PdM_s=*TK$l23>SMmnw3?YjoPZY`NE6 z^I?4;TMw1s`T5!;HnMHwr&Syol(l)-<(4 zbAdgg&&NLKnD)2@`~dJJ!0>S&xTM_ezN?)Ou(I9LcPeBu=t)-UD|D)eUcvFMn!it8 zpv!%P{LK6iKgYI)1C@ZGw**|0iPt&QPGKkVIOs|EVKI77i@B=ZeudqZvR3voS8{OK>tyGWu0kTpXs5@}Hef2@dy4;q{NRe2o$r9ugaJ`WD!d<9JLvB($E~-4uV}RNXU@kZ^l_)C> z78A`6ehEACD)+BhUAr~EufdP$U+;nk&aJ_;_$tc%VNy9uGE?;xOxoVp^mkeSIL zYfZg1Q|y{uBH8ogyz9s;f?m_7+vn#i`{;h~SAo|7L-)`A_h$cWo@O3z>+}_?sbpay z&stMwElZ){b0cWmQ{04-ywGp|_1W^B0)94dE@0@igGYB@-k@njNyNiRvRdzpg!g`J426spkgpRlr$* zd@Ac%8@MD>zvgM`xwWlj=Y`%nUVkyuwX+~AH2sIj->e@$0)Gbh1z_k8fJ<_GeZuM?@f*bBy%QOo?1E{5r?7UR?z;lkU3QwF zB-QF1HVhF;4I8eA3Fcx*!Va-#uV4NR+4f%sekO1>VCe4v_vq({JBEC)#q_kyVwQ@T z_*+N~>}N!cMY*FDr@72+ay6n$+0U)ln zFH2c#FcNqS)BJcW!~Qr4^}=$A-Zn~cdoBT(5#!mRD!GZ2i5@8^fq4mh+O| zwz^X@CH3+_-R=i{K7`NjfIklW2rzs;<9~1J!#qvB?A~cOb&}%}N~-0$faCe=VW2|L zcWDGtzfUi-DLc_S=;O-VE1+Ap8=jx-Nq_ zd&*_~_>eB=e)6p)U$6ba?*kqH4Bc;oOUiYxF{{Ux^*cISA)9JkhIzu8cI)9liVJ$^ zXQwHnp0tveYI@<8Y&pxorvftpL$4WJQm%c6&}-(HDaDlV8FqUaPz9ucSX(K@R`?@| z#ip1(q5%jNqhLV-k-<1U92r3@*TP}AQs#x3@vj#Z{A}j}`_r1N)p(iT{_tVO{o~+= zfL{TI&){bL2XlS7?i)k=W4(G|aUEP+s|TE~1P(j)fOE=WhbfSa$NjEI<|Vw27{5v2 zvL?)$5<$#~lS#G9DN96x75Oz4?5EFmuE11IT^Ly4)eiH;hc%yT;ls?&+rhhlD*(gi z-Qbc2<>f>6_p<(XZpWp3iqvS+ZK8gT0TY0c>xEB())P&OJFVcf5{thmQ2;8O{78Nw zfdY~^jKQO-g2$E47<+?SqZvGSx#sT(^bLP`t=Pi=#em_j3jApPHVs)n2Kj?Mr*ZxY z7S2ZNb<7gOs)}`^j2pw8O3C0On%)-jGwt?a@T-Aq0YmQ#;F5CApVFTp+R@_O0x4AM zOIbLpW!io>=%6ET%iNTk9G+(R%`?X>tKO&onxDUnr*{P3!X6MX^z*7=Eq*my}a})?(_T@kCTO(%3!&9yz+VPK`djKJptZKlq!#p8!KI ze7>e<_T9(DhuYeTRm))c8&|L?oIt_pvAAqxXn`;naJb?$!?BKqdzmv+IOy}~Hj5u|++LxQqSCRl0tA$@1j3^;Oc%Smz#A|h&^?yPOuc3la+ z4mb}mbhm*^GW*Y`hxBtSptm-AfsY1tr0J$E8^7nZ^!I8p%&t-^IVID_m=73wC;Q(UI_7x{J)?pjq_^ledILVaZa+VvcL(@Az`cN>_mKa+ zp<|xM(A%{2!mVDEvq6H5LkTwR)AecX$d)e+J_4u$483vw_lAyn9z(C~!j_KB+r3La z2PvL+EX6*bUb~;4l;G_lAyn9zzdW8+IMte%p^FMhn(|OqZ|U&rj(6 z3H%-4UBJ+Dck1#RI_7x{y&WyctFpc2;^U~XKlSM~`uPdHX7KZY9e|;?$N%2YF;7Ep z*A^~M9XuFSR3@#p_1xvi?R5-9hT#~Z%SsyX>GhJInO}bf{ygw&z|eaeT#||7w|K}t zV^hoKmJa_M==9kC<1IOB`v}H@Y^d5PO^Ww-$~mDBfo+f_XO7y-`KZL|dRUXfACt(?|{#b@N2c( zRvwT548K+2Ub*~p&h10$OPXfVG_N--5Hah5VbUsU%Zcv{;Xw+5J~ z#lMrQFW_T6S_u@)71$!?sk1_3!(8qW{VKOA(-dvp_N6##)bk* z(j?~+ES1D*IB&2nBUmcQzeI7;O%;cT?28GD^*h`7gR+y**rrO|YRs0Z)J=ilJvKha zMZ`Mws?nN@i0v--~74SVOAjOK2 z$Js^-fLIJ5+8GrQQ>WtJ)IyVZMdiI44yQ&YOEAf*0^E=;R%loW=IE2DhLKdFy;QZ|GgO(=6PJXy@gBq9f~_|QrL$GP!5nsO$v~%`<$kG z$j?{k{sH_g;BCOrwL3LmhMsvIM|bniqltcUDA9JGUIY1=_B|K;Lf~S+&^rJw$;2_A z_2jYgV6SaET6XR35PD9JU44s9aL!TQ>y=2Scr%fq7O);dlO%2)+WZ!QaD1fa=outT zxd=t)vr8jVB33tuf$NA!zS=oYr2`p{yfyH7T|Y$?DfS^DRmApS0{u~;c|*%BH`f`_@6i1azZ!8pjkiVt_oy!j%T7p+9a zI2-F0$zHx4i4;?0^l_Ep=B8ph4^2oE4{c6NYQ!FQGvNx{H1f?*K^m+4P?|VN^LSqs zo{g?%w)16-_U-R0>`~k7a%Z1XTn98GxWJwhsPWpRA5onkz0{AXzbC?B9S2-ChpVch>zU~f9ulB<1`R+vU`M^Rzl1zC< zFFJHQwIcXymVFXGYqHihSx1Ns7C|5<{=_MV^+Km^pU!?iPZ_`WfPW46I$+B6i2uEz zW1eRGa)Rm5{ZopTEJ}o}wHfOs4iQ`^V_6Bs;E;6Crx)In9S^188K4F*^k#rd8ay}p z_hB1)n+E%#(|&%Nl1=sP5EFYdj!g_pLMMo_cZKrAs#fNJ-~Y+iwBPmMp8-Ax7`pd@ zOEP-rq2=`UOJ3`J)~*a#YkP2&h3;zT;V_3*NO~;-e1|~dl25Ns_Xzo#@gKd&w$i|G zz|fr!E-Bae_ghoz{w^1J*DH2gA)`NF{R+P)ZYm3=**j@}G%>Fs(n6ZJ+chzFI49TD z>f3sOY`ja?!#RqtXK6uHo-u@RZZQ{yFTjbKky<5gu``_y*=MO0 z_PJ`ES3ga6YyKPdX2-<`z_$TyfZ_iha7nrJF@FEi%y--W=XlN}9oKX8T-)zj{gHCo z^GzF_x>PB`9@h36iclAoi?AbHwowI!S2_m#tPBw~riAb7h>gzrxK3TgvDr)YU(x&? zfgjWFq8D@S0jdGR?;LPRx%yr6hMi{Obuu^0}&A-I9ihwj==#B=LWX79$n(^+@-R-IVg>rI!B4Mp- zvepP;xn-J|Re5X@8&JV|X~3u3PQLPy(Cq^MG;kAO=zbksl94mN$EVls z=O^?&489Mz1~BwK<$rJJnCCI{c8ZvNkluCgMQ^~T*H3sskfT&ReObwGUYn+K4Ho=6dLJQsb?g{yLcW_Z$AdZ$h;5l~4U&rhS8=n$B!D@E~ z(@oeNMVp2UpeDN2QU7EPe^8gVf%2I0egJ$M&<2?DUITt~J-=spceAIYo;lz>ZhPmO zIdZ;Rhp7J%1pE@^Ot!bdXd?lkVu4D8klrcxmv%P3Y2DW~KZl@a_<0@tkHA}i;fLxx zhM)KBXPO=DBSe!QqC&X)61gW+N*?RD?;{`?_4srf$=A@`2;Ko)2pGCIgG(~~?LF&Z zizl6<8eY}aFymf!4eR=p^%^%Y=xP|xbwmN=lQfX>s)Il+xavrii2u^xY+vCq@C{ub zuR+)F^-plOi}!%xs}NjLuJzs<2kmXth_{8)))DLKxMMrTMC%5S$d=32CWDey@)4nc zSzmU5Ujgg`485DdC7FAM-thfikLmxNyEtWtGJwEm2lV|yU(=83>!n8UBDpazhSl(+ zTm@)X2e0-XQvPq+!7}?Mc^T`GvHHHL`5J((nSY%R@pgMfF)f4nEP{h5H;pjr+z<@RV4ony{5=nAx?6+}?`7WmAovx)KETku0bEip ze{_#-%VwN1sE%~~$84_KT6YjTJLp2ylZ}lh4EmVB30^*p-_msZ{d|S)o8Zpnv^!wv zo)7NP_2oVNL-pGJr6%3>KU{B1GSYi(xE^)LIo%=aX$&?9!5+(t5fwhUlirEZ23H{w z7#sg#S%gbPb|t{(D*NPDvPLpFF~Jn(soBAp7+?KA&dvlduBv+Y@7;NC_Dm+3>}iro z(hbdK||ZU5Xs zAI<^Z`?zk`PM>dS*R$X+0xtokU2po|n{{nI&HVE8So_eIDU5&%tfdXsgUn?7)dP&u z2zkHLCH;h^SAVYVC!seBd_Hg}VCb#&zc+Nur=hpHl_d3Rcndd40eP??!OBwhwnrI4 z39~QhKC9GZthwr)!W8GH39bJZh%|OU=}l6;6dc)1%k$ zlt2E^ujen)4=;fK0(cED{JjG%Wv4%{bNfN_mlfce4q6trmNr>C&;ZPa3$9E@${n%O zr&oVocKuEVC$7FV7clgW1eY?*m)CONi{<{SO(jze<1zJL+Guq`O5Tc5#7Rm3EhzT+ z^mb66*{|;be-!8j488FAn%+8JPgtL$7inH`>Xx2pO08D%S2`fOM7ckp&b4vJKw4tu24IScXL%oI- z6(eYrlZRk1|dM;HI6!=eo=K<4?uYyY% z>>OX-yb{+OKj5xtQrY?5$2vLZdBw^+uiKH{o~1V#d-rAxdx84_L+=s)dvhPmeOIM@8&|Dfw`#>^)5^9*tr2T!oAoh77m3r; zJZCiLh)>V@dbWK9;6s5CfT1@RT#9)w&y@%0$~DA-kd3aB*bknb_9i|`t)+d$nJ1)U zB`04JGl7KM+CAO+g|_WRc)3rL`&4DT>aE5XbbojF^rZdY0>2OV9$@(S$p7B7|J|JT z8E<#b+M@l(yD+G;%Q`1-mjnuw8`Yr7aSWnUV2x^lh!C`F7QB1`O=neAy@!ODS z6_F{~lVTMzOp#D!LLAiEZPl%;^edXb*Pw6Y&EJ841pEUq{MB5n`7`HL?z}dqRcXVU za(pZ7bC>e?u#HHWaa9&9Bu`7J7VpBFmpH7H<%yZn38pUW$L7)B~NOb-}^V0%7 zvu~XN-VSU73_mx5OELGN+;Lj7LLO;lj-=8XaoS$mA&Slv9TPNoU12M=CiTjY`Hr#}>YPxLqN{Kh)hY@J0pAA6+5-_M%f5*M)F zsb$O+-tw=;<~J0KC*>JvdLqiDmcb*ws%Yw~;(>U~`@@I|x1cN>N7=D2VpgOsWmy~4 zIj%>)<4xT^JK@LNV_yQ_1^fvx{6?9XQp`Oz_nd^^&8=&8XSTy$;$7~ZknEBjc3L7B zE$t0huSJKk8Oe*|)Wq3H3XAe0SSwGB6&AYXjM0gxDb#T`-e#1xw={oCpl`-+9r#w@ zOu+DW1GtpI#t;4m3}3tbgMcW#GW24=IzJXxnM8GTC+f}URJ@FeLghmc^c;7toL4OW z)6~EGbE>IV^Ro+jhM&*DBbVD&9$@&X0sn9OtY~dJgQ4|w&5lm2RpQO+w_*;D?lO{7 z6^5r_?hScR}ntluQoArM>_%>iWVCcUDF2$S|x$80TuZibsu4 zV?&aWL{e3jMWXeL5D$({Vq9`H*NQdnj7WT}`72v<^$F36NGhVLLmc*Hkv#IE^?EWKr4`p>U7Ft2e04$BjN>!lKL>sR z7`}c7E@iNJ#jI~z)Ut}yN#5?1N-u`DQXV~JD}OUjw({{JsBr`0Wj%Y4^!fBN-_Z5T z{x~1}2;eBd&|l_%Z^qAjn*Gu1m4OT-XJbvfw8{Ddw37&mDC}csSF6<=uN{r=>2}}Y z*DG|N0e=N}4KQ@~xl;3G{1aaB?Q64iv+Z8Ic5}-@?5kxuwcB5FWo6AJB82Qv_asE0 zQ-t70stBRv$8+Pe-ZT0zawv0t`1QUvpx%Fg2d*OiCt&((8Mu@dUqA5f)4SVa>^4pVJFM*qhsVw-_&F}^ zB)Kn9_afff7oVkK4&ImuBy^ahV~^5V72=&owtJWEqH{Kj*plOR8K z9=6uVzhqc!vjk>(x#sGLxQK#b>qoT;U*JU zQ@f*FPj$b2oUXQa1oY7ml275+A3|&a#jV(gPYY+_GdhTgeyb7eRAJl{Pz3plX2<;{~QSH$hN-*T*_eM z#C%!Uyn0omX#D4Gkl|`r$UR^)5T7NYr?SpTl@bDswX^R{HOn&*U}P zc~b*E3K$0%K92#HV(dV2=eOJwgiWXMBCG^R`M0zadnl%BAsJZWi9}&q6*EO#0$C{r`pPr241K>{s&jN;@!fQ1@)BJrbofDrByGbGf zkeFS%uETyr2dTWozKp2EOZ)KkDK2Hfp?{S}KR}!taA*kDvE$b1qU&{}IBeRX;fOr-wB{yTVuq5UCE(w?yFT&9-{(`>aXR=p!1;h_$1VQ% zgU!d48(Z6?4XK7UM&FsmCB2jA2qmd-o_CRu9B)NV9xmKmDe|2v=Gs_ij*Z$$m&Si; zKKh_z&_4#~kg^t;uE&;z1_$FZZxCva!V0sg+x$fu0^QT;jmqe-Yr*yc1Qqup@ z?cPOwrrjTd$FJviz|h+VT#9*r+La?eFps<`)MbBe-)q}lcDeU6bT78hBGo-qD&fE| ziQ|wHRYf(&UPSFratYZU+}cop5gAS9s#e14aN}(Ix8|$erz`W~GVtqwn*hVt%l`L+ z%?pv|JjOEH1Dqx)IZe6)*1ND1AqYq{O5bYqIFieQcmy~#S7JvaSqpK%D{#v=N!YPM zcDy!E#FI~qxM^knqxmblLHCRBHwJt>Fwy_p9_5owZEH86-Vp)VlTdCg!!3<>9KYVJ z)M3VBJNOO2&46k5Z@{Gtrl0YSQLo_*SBa4mvE>`y5G0QbuuD4~>!C8q8YTjpbx1mSca3a zf=LE6y*9r-p?4nm<-k>dq4z`o`#sHfZx8ZLnbOQJM24CovmTx46N8$)I1`VOqCQCAzKuDVUdVuI^VKw z;u|gU==X#*zq{ba>^Gl*PrHR&E`Z^;`dgacPyBpsOMbQceTazAE1B~fnwPKhnC`Qm zwm+2UOYQpO+xp`%<^AzN{oCC^@3$xQACLb~YzBG?tV@T`L=slHb}T&HTP8`&j7B3& zN|=~2JT`_@G1-}mS?JXa3DGbTtM)$@@q+7t{yjqImZAzZng2qvmQ;8KwiVS9)RB;x zgs&~6mMMHAL21QoD2A|Ab(wOB-A_Ftxyw7Dgn`Wdn|^9sIoy|(`-)PF!;ZWQx^s&k zw%v#9aA|1YVyOww`XxNY%kP&l--)$ z2gZRP0L%sqAE$szF>%Cm;{&bTa58UjYfL(i#w1Lb?7A+*U@rAqBo zxWXv{uTv+4%E+d`P}{sQ$EqY&S@DP1m_7X-`;&ez-Gey;36!P&6QN4XtK|`STR-D_5lxg=#cD`qSt{ zW-8C)Bk4#vJWJ!nJk%tDkrnPbHvYvj=c*8AJy*Neyb!s}Qjxu^l z(o>47c&Wo7F4vv%P%+o9&Oo28C-1(g`{GB>QQt)#uaepuYb0gWm<*3mAHj zf$y0ffn_9<@9q>o_##EG8Y@$&+Znz?*DLF(96Sxw0fz2G|9d0xn?&Q4q#15;JVfB#;i+IGh?su4 z?R?!;{r)q3Y0dv@@Mrq>1Mt5Cp8$q`>pPnN!QNYQxzEg*z|?KDx`s*mUQW0?^ZDrU=?EWx2LC7UAHeWY^IhHU!OqX!_*k>z^kyB^r{QmMO-bPG zDi(Xs!3Rzl4AEh%;|MaEJYAG|GMPgE#b`7*ciZwLmafzN(*j*H9_NC009OKrub053 zn7A#sKDE32HIT3Vz(&3Hy8+J!;B>Y($NDQ{BPvu8VP)o&;doZ2B<&-vT!q!luw?KA zlwxk_5ay0sg~tn`CC_HXA>JUcgmKyf&c3#YBUbxx&3F1P&6o7&T<}AH!vVwhiT?Ly zJk95qjjPA^GXDnX?Gy**qkwL*o*wS)hrFN3jfrlmQL}{!O0Uny9ndlT_Zax|Ko4N} z7<#wnbFlYw*_{R~#)i-2(7H~3$R(3-=EJ4$L}6IXB{GR7Lsa!7$c(0(>TsCfh|Gga z9~L}h&MXeQBVzPwoSYr`c*@pd5K#>C)rDbJEC1?jR^~Y87`4;3@3A@Z@7LVne^Rge zbu0Xu_FN8rAMicEwC5vmDP}&b%*n?zpgpU3%B44*E_;7ZC-WWUecYh+G!gF?o|rlv z>u)1yB=;OiKM)OXCC=dx{ud9Yq6u6_qg9Tm_3UuH_-^I{h&yF?k0I7X7c)U_ww+sT zwV%D&8EbWo*6nDxC)tZnT|EtF**k&9ylP!kZ$xIFF} zDXTw%VS}uHE!IaJ2^NQVCH4-d;33;NM)UO=bWQ($0RC^_bHMO5@m|fBkzaG=!vTDG zhYask%$0UAyOw9y3+v^S(K3X%WAU;|KgmwO(cEHfBx=+*H z?EC*7mSY#{(-py^wAbDd@wUU3w?!-26}8@^A4D1zt56XDg7QwuBdfUXpcrJJNbVT) z%-opn2rG#?7KNP0Gx=H1BFOhVj2m$Jis(2#*b`XPV}_7rx9s@E7p^2+t2>`5p-_Wl%Yj{?<8$ zOEce-9qGUc$ReG}x@&Cdmvt(4iT+O2(g|si>v#v7?vKAuPv-k}@XLX#0Mn0m`ri*G zpXfW@kqZ~Kh=r4E`{`yRqzdmH_x^G0@AOkKstwWPmWa-Fth0#rwaw7<`~3Qae(XWw zo&m*xp78H{p7$S?IUxeR|v%42ipZx-EXaLiY^tGl8=KL-$<& zdqdBB8oJAfm%rHyL*r@F&l#WAPTW0y{m=UUz106U_&dORfT{oY{`aO{^VwhjL0b{m z34JxU)r%bDQQ2mwFn&HACV|&KLgxVR24F5==*;)OH}#v(emY)CAg}iGv$dml-A|8C z2mig<4{rwF2|Nmz`s*Ij^e^_$fo-|@p4P5mA70JG7}^;-;HH?}8M`^;eOwT@2}9PU zoiXd;@rSb;gu@9EjHwo^Ohtx0B0Pd^;ygQ@&kjk}uflxN&lIWID2md-Bck~zlU-70 z#MB86#(U)2iv7~hy#@nl>j4{8qcwXl(9rqXrH|1w~lZ;<&+CM6quFzVpfsG|0; zU{uU8hbZL*Gx^v>u$YF=Bji5d7P}8YC%lEty z-gIx`F1ECz#JXqV2yUI@Pz;4}gU;hN8VXi==_SO0FQis*{G3V7*hzG91$z2wXF_e& zq!j;xHyM;9sc;e9Jj^*XQk2M3N2^%4mP=w>4RKDuB70154gdYY!LNo&;)T!=U2%L_ zVM|0!atg^PouHoLKxjxvb^~_Ok*W~mlNrcQc(fOxJjFpcR8`;|fMR8VAu<0=5=qaU zF2QoD+(bZR!D6xvh1{x0Xk4hEu+|+Ka%zXWBgzVR&SUOWdH*IsO=%7jZappP4*^B; zcU+w9ZVg5L(* z37GMC5?sn)dKTZ`rOlfWM=~2cudWV^geRi_!+24Ic|2hw#p3KCnUnN<==JG`zn`UF z30@D31q}UTz@-d!P8j;0AkuiQ=v;47M=}+9$aFQCsGm+ISV)qjB08F<4co~RW1EEY zZB7SL1p_hq?`7NhkEYXggzlG4=$d}HAN+^Fj{(Ei2jEhSAJAA|PBQzA?>8g;f`h^< zw&$R5W8fyzt%&{7XOrc{D8sUzgjgflizV9VNx_&%lKiX>X$u=j3-Z2J&FqM2ccRjkm-f&8JKFCVL36u>9& zS8;V4$7Qh^A=GX;O_wM1EwENeN^|uU~)xP<|(ss^F0Lid&i&bWbGLSsLS}x-{x^L{t>x;u>1TUX@0KCCQ27 z9>-~NklLxp4)k}zs8D)O(CzM~U1lHe0e=g42QclP{+MpJxj!wyUv{yClRaG0Li+EIK>CK z^Hf1RKQt`DKMiq-aE@}96a|-_h_o6CiACvuZ07{xiU;2F80$Pqw_`henst6Xcqecx zVA}CGxRk-xkFWLBy2f7d@grXHG)eq~;~sBSi%I;HEDVOiFoAjL3$|h*QQDVj`r*g3 z^oM}&155)9{U3o#G4ZRG_;zzkqXSGK)+c>3WoiZhka>LPWNq4{c|*&!*M1 zPV?E&o$Z&S!A}B~1BTDjz@-ek_aDN%5Idp*&nViFK=?7P9Mx|3232a9E6n{~_nq8|t`S%#988I{Gs z&PYv__2Sc=_GET^4hBCFXa)@3i@>D}_FgAr<2So;E5ou)#%2;wc_elKVh_9j5HvO+ z)NROcoX>7B8Xk?L7iY7@ESvZo!@0Is4(G-HD0P!L4#@AL`{gz0r=c(B!JomMr|2iZ z@V7s>lp;Sat@Xz4=c3QwCLPsuXixH=_KQioCwaH>K8|@Ysr9C}A23lBaQG=08;kk# zL3S`Wh3&hpD5#FGgVA!eiB*{lR7Vg)UF=v>h+gZRX9G5mxs=XRHNV^8$ISO@!0!UO z0K@Mq;8F&g?*ry~(_%DXtAJC1#4>!vdX@F@0YiAJjTR243rSi+?&Zm^)~b#6Y>&_;%~$$|*?yb^J|8#~FnnDAE~Rr2KXZ?-jm^vDglYP=f}E*&;mUE*z34O=w7J@Au;9~t-Gg8u{fH(>a!ds_2r#yxl65PrF6H+!$AO)Fq? zHgLZ1TkpA?;eIn~2%M742=P_%h)tGgviD3PVar-jyS32f0o2{)| zSx+^T%AvrFoDHLe?CVi?Iwrv6EUtvDr4Cy8u^ttEY}I^OKg#YSCE(@25I~A7uH18X z(-|99jHk0U!^bkY3^uNn2dj*Q5$5*U87t%0yTq?U#-j~<6L8vqdX0X-e14(cV>V#S zLCv1Z;L6#a5h46E`t|RmE+hZE0R9s2>VW!l@6Wr{k5AD;U3W49qE5>+F?F-qqnlvC#Pe`W+Z>FLWn3tTIKJo!9vuj`tKMH1rve7L}4X2;|Zb4P>N#$HOB;L zgOtv%>Uq@!pY{AM?br;y6*v?S?ec>ALJAu0aL;pVTFQebOsh>1)EH}|fJOkvC-uOk*-8^-A75*f8~yp#}S%bTn-Q*46rVy3;> z5HuTwuvfZ$y4G{LUYVas@H8+CFmz}7-y3>nKQVOIw3=@3u;0`B@WjiI)RwakZzq+~ zaV(g1b~4EBYh!jSfknh5c7{6N7g^5r+wap6K5hWN8@LZJe7x*`KR6#U^OkMduy(7= zfes>_c!vValv>N%1J;dpDH)8%5YR(~k3p_I%`P0sREpcc8g)&-9M!%}^OgQ-wtuF8 z&jIEEhOevr?+3eAlgnW9?9Hv~*RGhdk1*DFQ4k@o0U>XBU(k9U?+JNF76%&n-((I^ z>|&951sh7V$8sc6H+#H3SNB^IS3hJiu8=E^$VxbZ<1A*tW{9g+$WiUHAPd_4zciE3dJx$1Q_mTm8d3VerFnK&2mM1cd4hr#lYdQ$E zK$y!{Irj$i+FaP7WZ^9bW&bic4N7}!Ve(1VH_ror~ozf51&upszCOQqvW9-MKelcLlBr+)GlS<(*;T9@pU89_5`g z&IL5e8N<)u!ssDtSY7_K*BsPNj**&bU~&*i!uUGQo4iRZyz2YwBhcBEd=?HK0EO*www6TBvjU$|=XB1!P> zZ(F5px7au}em&62w8Vz$j$oTabp3FLedl!sjA7Ol6FJG!*1Rj<;LCe zd0{*mlWrZ8?>J|%Jy{)SuT@vu_Gry_`by1r6MUulll1?o;9Gz*d|qYI-FnZL?`tAo zkmXJb1V z8%VLo9Y@A!I%9t|U%hKPW9%cm`n#^y{m=qEGk#}*e+}5?^C10T_E)pd_3yJ18?kNk z#_<51k+fDOt(wk1hgjspk$_9%}3KEf_R@Ly|C%>utse}4VKiv*~ zCvcZfV^96m_9gwagT|!&dUsKWsn`BF_hKLfNRfI6?8Ffe{{reV^`8XZ z46Gbb|6t?0{!942gUTEHdOHWy`+e|7fhPvkJ2>B_=H2+d$MD_g*B^cmesIB&x0M%HT`)%`1gRFJ})v}gZcT_k8VL|-aw;UH*P*<)fwKz zUY)c)kq};#M!$ZZT>9&;0iOg+0ZhBw!KFC@>bw)FWwMKpWef#(iasG!FEQ#RUPrahm6d+o`|*SFg} zO@agH_;Iu(g*aJawKP~{w85oHEXnm!_3E*%)pQrUlBL@W-U6Hg7`mIm{};O1{AN1D zXiLW0xO;?AO*Z4x?WSHcKVAXql`*`O%J9t1OP3FW~(be6o`EPtRJ05Gm zPXo>X4F4B_OBrn4qLSEcNK&NzwKL-YiFne|MiS4IcT(h;ItotuT%OKfBsXy zIq&}n{t56YVCYZ#rKX=AMBb<$E#!}GZQVR-ytklbEvLK03i$;aH<^~s0HM#wCXW&} zh!B!gLu5)Y!mQ5_SBwxMDo@Oke}mt>)h+(gtQ>wa{J*f3h~(Yh()_l=kD0$WfZqw+ z4H$lZ3od2w{XNUCzXf?5Z-U{+?V3`nrB_*hfMMn)t}K;kH@r<0+;eyj=Zt^{(|xhw)^iE>FaHh zmA7=;)>FK!<*PR2endM7#ComIK(9~#4!?epBX@#70X*gZP0j-&HWgjNcwmQD8 z`~42+n|bmh@Sgxb0}OwE2A49Jd;xC*lvEXx_k6yNHpUB&!0tY%!y)QbE=| zy0Iv_u@J991PcqXld&%mVYt$(-pbse`I+`cw!e-BKM`mK3_oXsOUa!FW;{GUH4-2OljNE>`^O-ta5TMK@Lz?p*2x8WC>wUCFE2E@8vZ-`~|%y8TCz%K=Mw_&$B)~ znHR5vzYF{hF#P=8|K7|C^J(~@f7;fziLNk}u3+sXNymJ0qxCLFUI{k~Y)8aq1fN3P z4OWv+x8YaWepn2C63`47x~<@Q>W7tUSIr}C*g`MuqD;?*17|Tk8?8?f6DnwV9NNs& zay8Yfr^~0ilX}fL(F6Wl;CFzb>%OV!ns={7Ir#@SHm}{p^=~EZ#^?>gynpA(`}Y;L z{H#AaX`PJVc0~Y%v%~X`(!qO(<@svBDWu(9e!X{4hiUH<;LiZh0j9mLg72xHH?-<5 zUg*c~N~O2dlzEf?Ra6X1#1zA&9VvB*uBY+4x;^P%XX#D_p9#zX4BaEZ_e7WeJ)(8< zksH29_x&%W+vn5WLA_}zmVW#W_)mcs0Yf+VmZm$*mq&BuQs}NeedU@~=~C~>X$CJi z2LhvkuK*)}2vBCN>j+q*Mfn{iSWzSz#9%EdheB`&D(`4GiV;SXGp>|W0@G1v;7a90 z%cC`zkKxs*u25vAE3?|~*8SB8UuK+^gSP^k0K@kS;8F&A50-eK8&_#XZsy8D&ixL1 zLXowhCuLzUvtDi3;pe?ypKQX-}duM7AB(v18cnNZvXf*@jnei%qKT#2AM#Lgc(1ZE! z@aoTVYv_nbEJ}E7mxKW*3qyfKL1^W$_&m%lh{Xtm(W;c9or)s_u8DTp_)gd1WKl=> zj0hWGlWHM+z}RSlH&o07OT-Y7&E;hY0&^ zJ!w1N52%l9`vu$Sw8?Arkz>ywuCl_w$ypMJI@1HX^XdQgZr%So=-)KI%ly9!{2Aam z!1RB?Z*>3f|6|?%yMDI&dCdHms5foi3J7(oHm{H8dO!PgPoL{pZCxR2LoLeIAy^rS zy#wMLjK|bI^^zy3h;I_|mx+@+2`W!5V?4(4y+rOQ;rr1+w>VF&bVArCIZxSW{bsB6 zfhPi1=4suICGcs^?Nh-w1E>4E@A>{p3s!92iWurI2QESxt2#rUNNMux-#MWE9`Kie zSNF31W>J}Y)u&DMR)=4I**jVOGvJefDS(v!mH*}a^$+c@zuT{W>wx+@z`p@py_fZ` z=&yfRfBk)a{jUwEzYqK);N!ile`SCDBl_!4|45JTwBKg?rxAQ1a4fJl{j+kd>Hqrv z`WyZFcMPb%3;Y4#p}nksQ-A%V`|EG_>;Ggx{mFN2D+QDQd&B?oHpBne{`$N8`j=2w zlFDQqlOoL81e~^)^?T`sy!ko4zy4mo{+$Ere-Zp8;1_#Y|1`sXCSxU^(c_wYFU$8x z@X^3HU~l?mx~X?k#%l2EZ5dE+JNUW4`FmOKM0!E5*M0i?qs_1X*#Y(Ug8vqHe{bs- zBWAC^r}Wp~>DOQXezsp4z~=(5t;00e=(;$L3!y#Cq0zy6G0{{retQkl&6Ch!%&>bgj|KLnoH%lg;0nfe?0>+kUE5AVwIUk5${7zON2|Eylu>+K#;?=QjM0Dir9^{$pz39sIH87uv)o-bv;&-TXz z@JYbFz+Uu6wl5ZBtVX}ywgL5C41O7K#opB`0)lZ?+L*QuNefSHe*HZI>i-k?hrnO= zx_%;_i<%&9QU76H{T+V&nLlLvG0_`{7LtjwC^zRg}||Z{8i?`GXHy{Z!w?P?Lf?^T*%KFu{LL{3SuDh#J~lz+P6>d z_UYW=*CTWu0e>2J7BF=3{;c^hb_{Rk=;wr3^M&AJ?QN=@vtUrH(V|;C~lS?=j&(`No#9g zz}g@|-VTaa(~zihXi_q3O&EeRUJ;)PTT;@5Vj~jZwH)LBP(<5=!4oeO-;^QpO4kdT z-{c3``+FVuXkZ**_}v#=%3yk>fhr}Z?Sxh=-kL08!179tImWRL8gQ>9U)1#4sn6&O zt^)4_z6BV1_kv3qOpn-4&%5Yp^CxtM*49SrU+C^|WpqN4h?B%xUOi1d-A|}jHUybZ zu@A8Y0m=bGcPzM+r~N#?Id&A|*W)#^$)thnu>Xq2x77Lyy512}6Z?>IJHYGDBA$iP zRd`R`XmdBT8@vjCuG_tp`sEKo{}S+T0@neC{_WsW7JX0OYjf$Z+1PrzM}OG{nH!z< zuW;>3SYK&Z*3tW+;wR~M2rGom&Jlj%td}(1KI(0tUZER6!B+{?0EX@ga4BPds_9zK z?tZWCrz=!@?7!Q*4fWWam{succl9Es4`1QEtmR;7e+g>C;0R2F0z`aUgt^Zt7`{kE zfRU=YVq!{M9fu~}SW=C%ljT?0Rs8dCBoYbofU+OVKWGy(%N|Jz^8@SyoQhB{tYy#( z3V%C&KBXN$1^*@RE5Nkl-~RVzzcHWv`Wev!n(QkLcgcF1O9-noJC*gc!of>TwDWLL z8O2XtL@?_Jxn%4nxgvq9er~HHg$F5(ztsFR{3W~27lI!P90y2|MKt7;&)$GCJaYp+Ul#^NQh4h?b!!VN=0QEzZ9x!$ZO; z#!&$!Qz2>z+=L%ifmv4D>$+c>;K%HLr-PphTmTq;?**4~rLUjPwMXygR}zcJoXb3{ zPzu&fNWgBu%bhm|9Sux68N!VTYbEKiG=P`OP-r-Y1+fI{!uqO%AM$>@_q?I``UJX$ zufmVWe+&!-3||Ytr405?>G8FK2;r+pH?`J_@KoCHkxZja zdAT1-LOZ4uzH;&w7;{6FD983up9-b)o0_i<=o-Gh3;renJChyi9;cRI7Q+ebEIw;uBU+QoSS(~GB#ULcO^PayUiYsxf0@5!_v=Hz zj|Gkg41ew5QU=rSX8Uc~3iuQ0vJ@GDeoOoP_L5Udu-+IB58~p*^8?wRMyPatVG+kK zfi7dQge2k~sxB4I`rgufJqum4pT7zI5%3Sd@OA3nHDB-g`oaTq?E5^v%$ktQtFD)T z_G$g$+>5=;nY}UVW9LvLfI_sZcyA_%P2uDZk)*Kf5A>!Ags|?LTqvy95hiegI@Afw z$wMc2%)!jUKmyBb3E?%QNb)lWy@*lxbr2whC>YKN=I-!dxXc~rDXveP&hOQ{bx%-7 zPi9Jd#ko(ZUPTc1;LElFA3O6PTsi=A&NLJ(uK8mv_dcwwIxI+rFSf3MryO?%RQdtU?J1^fvx?XCWYZg1Sr?=bAi z-Osb;l_zi6wAoK=yNTIY(;GNH_;$eV4ebARfK3J~-FI0oWFf=9lmF!rq-`~07$!Vh zk@|^Ej`gB&qOM?UxT=VNm5G94*={}#5dUx@$D>_r4}m?a{ZE?THuy2)a~}9D!0mwH zx9$_o@7P~!KCkpY&AFxdU5#p6R(4IF+UG-M_o-U%=Y>J<;~UWrc|$m}v%tC~G6_a` z%Hdfp5Y8v1LYN1DLum#|?zqBOrGOPy8Lf(?&KVb9gU0#FJf7kufLHo`AcRTp~z(auPpEtp!7<;VT^FsH} z%2lh0z31&M7b*6ZMRK(B%=Lb>)Tt-A#XQ`0r{ma&U6mMAVV$9vpPr3|BnFtF$gzOT zP3ihr^Hu-PEMGIh4*`w<3|}XMOW8ADn_BqlPvIX&;>azjDl(vliZK|ldE}CxlS5Q(El`iz>gu3sfRsJSZ5zoLxKf0+M(fN*>rqKw%t;@xRj}Me4zfD^`kVZ^WIx^r zelBnUVESvCclsko`u>C0zqR}RM0_jnXoAwv9=EULMc3|e|K`5vimX~?y+)%Wc;D4> z)p$&)Ly)>_S*9`P5LSIC_=4l`2Q0al(@FY&wb8kx?m4=sR=SLT><}_49xcG=OI^g8 z55}Ss`1eFvbTR;d+k9fz%W+>H^{yAG={QbdRI!uhPNWe!P8SpNJkbYCF)gMd0V_O_kqQqG?P>UO92 zM!S%|9T#ZvhQMlwJD$AX>GzZL<9*-{0uTFtlW{Wgz4uJ$4hNlP3e*Q2F z(*xlQGtsjU3rxkJj$UYUn!IYQbe?YCcIcRU@D1QQfky$u$KSxE3@TT(kShHYGgV3( z{||w03Q!J=0usQX#3K=*`9_i!5!-+hN+c{iP$U`*+qO6vGpsxXyX2-r@`|DYDUzfB z#F9G&yU#T8hi2RAOlZCvKGS^3xGVv00oDPA?>qeOjbFv{Iq$S0YAlpH$wJgK-p<%* zKSp>GyVEX~ASH4q=^!;w5=V7$Rp(|RQw>8PH!l<@sF0Ldwb(3%5tERsLm|5$iJTZi z@UIO?NSdLT1PoPE1DBEvUQG?5TK7t4QuA+pp5?y?yb`De4F4ni@6Eh2pJsloC$F>D z>oUb0^jKlJ#J!Ys;EN-W$8k-s+o#t?eHs2F{dEEOt-u|Cq4yrRlt-V^`@kzd+I>G* z(Yj$p^X5&P8Ex+%8QSZ-YrpN-z0Mns_i?EA^X#{slyw%8T4oj-lcIah0HT3{GK?1E zWNu!}A6KaF*tllbgzFKjL!pE0;>u#;2LBC%Th0-7SVLJqF#ghN~8FBU+`nE?NyG zy1n(bvX=0>(47T-1aLH9=pGL)Wti`uwy6B;4!M?WA7W3We^&;LiZh z0fz2N;8GU-4|L^O>5FtP-HmR0scvtXQvLH3mmg~`Fdr~co&iQT1{kH*SzMB@wI?#$usbZ7u2!p|!&$H=6VI1~8Gh+1)BIp7 z-9O(R2Y(KD0Wkc$11@ElFK-xsJhM(WHgk^3qS?H@4OU8$y*`~C)M@sK2f%*_{1`Cp{WZ80)BjicdP>t?zp<_TbfwYV_J{Tpw%u)K zo{&Y>qpTf-sVv~M9}!-p#zqnjxk%-BdewHO*>j}+Or_s$C(F-V@P)u)!0>YkxRe$@ zF6do3advj&2PQqeM5le8-s+DL-Q`(q_0MptlAAQS#3XRM8$&XwQ1#rogLn)|F60>b zQ*l5egIB&Y7PF&}7^I)*kgMj5KrMEaHU6SgYBt31Wt&8l7l#eBjhbNit4Fw4&{@TtIl zfZ=B$xD?|DWb~T5&%3q6QuJ0?EsIQG9*|g;Nv(D-z{wk^$ z*D3KBDhp31T(dC5E&Xa+9pcrFz5Y<$KbcT=KFtL`3OEKZ{G0(UCG7jh@64G`{riw` z({689Vr|=SHa*j)terSUjl!=X;!I{0j3@F7UcQkO{y!mCoD4!Py>yE62JWFgTUKV6 z=IdGLrun1v(_7#l0v`c}uT)s`75C@Qm+&RKwYOaeYaR9tT(LNh@3h68`z+p>-XJmS z3OspTk~(9IK)lJxQ_!95oHSmVtZ4f`z-Fb_^TeCyRt7X|Z+)eeGKP#g8^)dMMSR(-v z()RN=3tY;r#{VnlJ}dIS94pdi-S)oT?)p{lXXpu=QSC*=v$S zoiWbqhFA27GsOF4*c0r}GSi=R$9t^ABwb)$fD0%Q)7ZLuZPg*9toAXQpHAqR^?yJ3 z_kl+N!_U*;QVc)2@;P$m=H|8D%_7w}^T>SbtR}11O{rO;rJG@*1w+`UM_|AH`A`i$ z6c_;*dNaYLZ1>xrORsrzt61B0Ax8pzF8TBv<7`pp|OEL3*TaF)rng1JFMYBW8op$>>o(n;Nx7k0!J!rftT!fB1UbnAXWzm+~Tx3cd4DB(hrv z7|s#>9p2#6Yoop}^+`L=2fqZk95D2*1D7(`d$$C**wDP8Rs7;Ts&zP}3DqlbC&*K! z0it}Q)Hti%r}rB5nR)eR@IK&gJ`JJtg?8zXM&s*8&qHm3@p1F%kV#tSu$g73sKc*! zT0-+F?Km3zIN(IUwBr>2dn1SE>S@=vt|a@?%I3|)bK1CewalDUdJ6t(=h)o6TYWy=F6uS?_fzmUf!_dz?uq%DuWmn{S;qe~^CXw9m^u#aiR?(c7_oaI z7e-!;#9*PP)Oy7p9p*7Z&A~y7c%IHlYOXpRDXN&K&s`E#@l$1&1jhuEHStB~+2IGt z)@%=theNNRL~}{0B`e*nr2&b$tyEKvr;LOuK>toqh<((|gWV|!x4676P#ocD$Sy9p zpZ_pSrkoI>;vWLU(z=CbW_wZKS`|Jibej{uSX-B`D)@_vwnVN7c+qka=UhBrjx!yoX@Z58lRJ|NrRg63?mcukX5>tC};y_;LjXu3j>ND+o82l07 zai4}z`fv02pbeWh$|Tb>`C~qHY4Yn27i7D-2+Tgw_PYg160P*VS@#$`*Uem72!LI~%__T!LVB;nGeReLl(XvLb z`>qH`)(3pX1BocFXI6TDJzl#8(D@fQ3G%Fbpuc_KQu^QF{d>JxH$u->q?Wdg#ZT`s z#gEagMNsVyShwP^UdHrJ@M1(lJRX)ts0KAMJRTV_5j@-#Pr^hg45bwsiw@g2O5xl+ zK=Zd9`WfiUesT@?bHIy$;jccW`RnuFEg#MC<8E7VTJyRsvLy~}4`n_N+U=psZ13Ya z{joFX{dSH1?JVz?+Ruae@ZS~ZPBH^|BvlwwYvM$-$%~iOa%Ubk3FJK4FY2d*j}cpO;{`02=2Pf*L)?5 z2kZmjqkwUM;fwT--oGDgA258uR*I*9LilL2UT|yGOcHMQuYMi?e0uHFm!?LU_g8`6 z1l$T3dJlk0x$?{7`HUBOo7z^cTDQ4bdZHVR$`d@&Gw8$}XVAy77d)h#xCr|V>O|h8 z-;t`V^ufBlR!O$K#o%dRIAG{c2AA@uLHy<0R(NN)zxGm1E4f$4m&IWKIsSbZhzBvf zbMxdOakUz4b@_C+QZF}buiY1dUkzLb7`pd?OEGe1uKXbF7Ru7-%v17~nnxy-b8M7( zAG<`OB&kaw^3Z`id{-4D0+3qke3Qz%4$I#@Nk^ryxOr} zIaKqr9eT1xWFA}(-U-|WnErSIT*{d_aXSn@l8S@KRH%dCst3Dz%<(YO5XDAZ%1I zo$j58{%edLn(;C;BjiV1e*8+E9mBt#ePPZJo<}8Tn~On&q$m%UxDIM%{xFff;k&jo z(!SIq*m$JoufANNy>R1Aff5%KoL+jqzog;9b`n;63JSZvKv|4{hvjt<t!+FsMPaVPwc2?+=k1=+FD85&x72Cw#3Izs{EgoY z=JGFi8x79H=AZ%yOm(M(?4h3JNXRCVik&DHsUI6_`6q^v+uFv=789OgdnOOL z1pSmp$or&Puk`rz`>5a0j|@RC4kQ67@^g=L=WJQsI3N_+c5VnyE2#~6&ab~w>f?7= zFYCZtflUMIH})yH`$+w0uVtD-He{8Mct%L{`StIlE;BEF2L2}S8^HA6zrm&S&(|FJ z!J~3Co2H%>>3!I)76FrM;`C!LF)=t5Mj|Z{F`faGBw~`KA-|M!Y_U4oi&ZA|_bk!l zxu7b`&ob~0z$U=(a|yVV!QSsZej3>y=J|H6ULemy;V4;?gd=3Q9*pkfWrSyXpDQ;I zk2&;=b);(cYG>UXr}=pediDHG`u|Vhfok{z3_rJkOZoH{`n}`&S9gE+@c23CG#z8P zraN%Z69MG>9|gUS+ubKnr_fDt>y}WBswTcH0x~AJW1`{|Em_|ZxK5{#y(Bzz#F3a+ z>~ENNqm{zeK$0f7r0}apX;I0W2^$h||0^a*raF?4IE8d~csBo@btakGHW5ucz`qSR zr{I=QD-{O1+X&{vlwSm-d%S5 z8#XBg_lrMm$I89eUFPdD-CyCFtUNLdd;+i!VEXGoa4GNl^T_Bm%=zo}*K8e0iph)l znQS)6qw?+K0r?erX}%LK<#L-sDkwu1U{7whod&N~-nW}HA05y!^ZG9E2Y{V`;o})_ zDTC>U{CVw}{`T{cN}iHm2oH#4ABQDBWtlTi2Q-;rCQhbV(@&vkA;2G|!c^iKho zvd8^l-nuPbFptuPw|FdX*f^^U;_XBZk4Rwdkw6l|@-di@qoNdx9GO1gY`^3h87Y$h zzxw=$#5hHATdeNXM4{WYT=TgTK8(EdGw`>7-vWlue}GFFOkUFC)z;?w)^yk}^UgsB zZR4XrbK4!6MOV$k17Nx;wPyzA1(4t`BxaY?n^~#(XsFHh*HZ8%U=?8a_!_vB!R~F@ z{chCwe))~X?ydNjB30hPsmG``&gu>Fo9)KK za(z_V(cstLNnL4vmwoIp@NVE~z_jama4CbyrGEcN^y!w>W%ti%;7fsKz|g%7T*@~8-97hyI*{(7=H=^FjT-N#d+4*PK9m@u7x5U+ z#})eHRptHG_#qD@EYzTNPqc>dPCENKhax8p!G9{Ll6Hg$yBTjzIN07*@fV5MF%oP3 zGUTQRf=4OQJ@Sj=F;B{GQr9|ahP{+^)1t?#556<-E&W+AOj*T11z_4W1KewuZ%;DF z`Rw(l-!4%N(We~}@R=Wd(VDX;$}I%}+b@ zSmGW(w}E#74+4gtN5Q2Grg!*~e#T_dV-KEEnFF{PMkbWNTAOu6ET!gSQ-+v1*{hTv znUggi;o;eRcNF*mz#PEvaUr-A6L)Xt&v!pBzl0A7Wdje>dUk~W6Mk_=*akU_&xG_- z6kFSA*xpqTQbfXuq}cMxumC~}MCoz_kgh&+<(8Z3BW;CB% zo%wDk-%BX8Sj@PZ)a6QDWpnilGzVuyZWO+yG_>mW^}@f|A9$9q0ze3mB0u-IPG^g+ z&>YFlmAhEC#ide8qfci6bs9RSfNuac4xsa2FlIVGjDzY{u|(Z zz>HU7q;A__`U8KwJbI(XW4)=Jp&Cx(yn4pQ6$R-AyKKbbA*!Z~{6rYf#fk|&O@7!o za!Z`s0Eww^d~(Gbd`c8IZVgvdUyaG0l}&z!31zefFr{$GSvy|Q@z?WbP=F2%?Zx%O(_ z`8dCIee+hiv~CjO9rjZ1h~(lV-P4W(Zd^iVNvI|0ulC-$x_tUe{Q6~|X#+nS*an#P zclh6%{pCyPi#*Iy-Y7Z^$e&`!OCKQ1^gw=%N1i==i;hs&u+eWn^_%v82>uV?Q^3$q zj?(QPOrPMjU(@%xzO?OLyH(`4Ui|Iir9@_zpyXm)Go2K)$a0&U_0pf|P5$`%^-KFV zfNufL01W+e{qIft&F60Ng z7hvf9)&JhmF`qf~4s6v=7yaZu-kqG)?bDk!TKAvOI~x2r;6%XCTjPIk=$OwOdJ825 zi5cO3qMzjurC*bqb-#A`^$OjefcF5e0EX^c{`ZES`TP>PUuf(3dAoJ345!uP)2$zq zZSP$0Lx3XyLwAY)y`g75bLpPGYE|188+_>(D0lgEJN701 zuTR>0BlvB=oq(bDfd9RrV?J}}EyN*Jgt08ehjypf>(l$huTSVD$7A;ZR04+HaBwMx zj`_@?*NC=aeVeyG_qXx!-6?w2SeesxzqV1YIk(RPzZke2Fm!JMm$GsYJ-2@@H8yV) zIX>06^2i9o*-j7~s7fHZv0QA~_~&?5fb1r`!{Bq!G!0_`Oa4CB{ zm*=G_+$W7ah z%gfN{B#c@P@L_lC0RDaeR+-@mJpDADt@+prO|uVN4t@u4H(>hVH{f3J%zi&Iu>Pp+5?pr zYtX0;$hoia<9gib&8W;){NpnA~@vpNrD|G%!4QqJrm(@ zA?8gj+-?xzouh+A;jh{BL40{KSQO=TsIa;^36ZplCx%JI;X;*KR~SsqL}S;o57(i` zZCv2LXWOO0^5A~>ZlsY)%Yz3i;+yk^QywgixfsC0AL-qsyUz`{=flNhqJSKziZO4V za~PpD=I7z^UWpSzCC2Eylkl2Vm#kyLwDH@4&MdVNlVbiI;h){o827Ge`FY7$ZH@S> z)h1GsnkF7~ClslpE8MTrAo3>=m4W~wQ{r{%5K;}L=#TqsH7e>>@gNgftof8jvgxUU z(Ag(Di}f`q-Uz@D^nshDZBUd#jsr9cR$Cv#yHy+EX&9gVIIe5eBR@n+W?Y}8c%9?u5 z--2d?AQa9}wBTaTR<2HCLg3+ov!7c!8+T50iHA9jd|i%pz=d{TgwX4}R`ZvhlHIST zfiD0K2MmAfz@;4aLp|R=&GD~qlPBpFo)oxp`5D3^VPXO=O0*cvFNDWV$9gVY%7q%` zj6x$W9_pic(+sOwPMs4H_QrD2Iuz!XI}-y(*_?jdv#;0ubwfYR@3No04E_f27GU_> z1ums;kazrni!s$Woe&up+D%p;TJn9lWO?IWCI5Z;27moe&C;6>egtqdVCXFcm-1if zLD;*}_tV@K$)zdvwEJ}Lpx%0Zmv%l1{ygw=z|j2=+$)3V?fTm}QO2Ol{#a+YaK%xC zF$h=}M@pUX-YZvLcmrc`GO0(rY!>-mVzIPBe@{u@r2Apov@AadgD(V@0EVA+;8GU( zcIprM_A5r7S%DPeyXgNv_TB`(s_N?hK4;&1?v#*(1PC%-P-cNJgQ#3_!U2hbh=?X3 zgn$BxBnS>Isnu$&)l_ZkfSNkuP)*fZYf)3RmfEVRT16jQ^H{A`twyVswzj_CwTF9e zLK0&C&-=dr_w)WY{O(=3H(9^6)*jA2`|P3Bzmr{r@-d^8b-g?y7zn*AH(pFjRhUmx zoRp=>qqM$u%l{DiOZY_M@ig));19s@{|Q-AYd8JK>MR4A{j+tChKce6v4YX}r+FlL z9zS^JxDDT%nr!~h$y~P%MP3fdfa5(2S<+$l`guVozw6f2Y<9ahFmLH8U(Z51SgtjE56coj++L4h?2qNMf>lUK|YBZ*ZXI59U_1n5*H5 zta0Hma(3MNjx5W^j*>f!-ObqL^80b*XTWcPv->q(A?68`xW8#k`4+NdY5>Gmjfoj)(nD{Nsuq2XMgn1&NDCNR#P@gV-B?zH|}9Ve}LDo z)O$^p%Ib`9jJH|7tF1oqvl;nk;8EcC9=G2+9`~Njx3Q}7tgiWXMI2wV<>QcODQ5b5 zl0+T@#skMU-G1+Q+`HpjuOA^)S7!K1_Tk)ul9cx(SG2ySFR`!EeF@=dx4aEjulRX2 z@{Qmo;CS!0-#b3{-X*UtMI}Qf_Z8j?5`$@WIxR!t{?4|4RgGg!x)D?rwIpEk?eZuJUp{vka31Ve%2oq#NR;mDGHXv8!NyrXEa2o(1LtXV;PTduLbYa?#1Ij5(<$pG}yi(#888 z>$puDj}7CPY1x4ChI3IdA#IA@J@F z&s9gqW-}Ku&T60H(E($SljA`mFCN5LTbs|+VUGO^2FbUBBkY%x`EDA8`xX_xJLEOq zXX3Wg+9h#&5BX#8DR6dwVZV3ra_=r~biZolnlOLUx-&Xop5;WOB5!)idx=|hv8s^y z7D{hx=CxY>1&3wgwi0;**a#f|rS|&;c7E*cPUAVU56pVKpJFCvrQ2l=>C8n5Z)O9v z!x!?rJSO9*rMhKfy}duOKVxkBg;`lKAv~ON+$1ck!@%RM!pWxrX*%Le5*z4lp z-d#L6A@_*2oQ$;goUDFIQ9*z9cVW}_OE|NU8|Y9}W|`5zksdI-rB<)-u0!4o&IOM5 zBKy7LbMM{q>NdT+yv#3GWeM-V2ANeqhRtp`0y>K8N2)oRzQOXhqF>q?;g27oyndh< zIQ}unlH53VXMWCUtvr-9vm0yV{*1>b^~_w686GEW+OR?9u^f5mNi`eK$PP-$bmmwj zC&#>0t=E{4=h8!&uFN4p`GjYZny>lVt$nqYU+lXG`7-bw;Ox83e(&sZ?=C*o=7Dg! zkQ5d4Vd8L#?K2qnl#|Y>8EnnyC4X%4qYZtopZ_^>^hnk|0mnB0SyFe;;j1ebGT<*y z&J5)w>8}}{%7Yx&Eqe)0DljEA-i74&%r#hWlngjKU@3T@}MafyWy8E ziP$&bDAss`@xa+PA6e1`-HaPmSI)1Noas~_Qr>P(k>%XD5Vz_>!Zu%Ol`1N({2*(sKq0a=PjpsXhkc9);65e49TsDSJW#_v6^GsPgg*oQ2 zk-^{yPeBr_wGQ#9BF=%!Y;2d$p=n_?hl}P};UkqjLn-x`iBoK$u}9)G8hHws0i3;u z+V8uI6ZT3M%1$Lq+gnt6l)fz}@)k6(^G$RD6XMN%0Yl3Na$n#c2((x`8ZD35@gwBN zz!SjP@wWZm)z5}b{iw7ZdSg8zm^Ou_YJb(c&Ge@nEnsk!H_Zl}k6yvL2dV;5!oJp_3HI0iW06Ycko&%Jlxl{`u3hZ$~ywuza(d(f6z-X^P8 z{Cybt=io`;c%QM~cULa;VaodPONKa^}jtun?Do{lfd(g4Jeu8?9dP_g>@&!B2tXeZ+q6 z;_KdBoH@;VO&LzxbHp=Fm+Ut=E>2$^O-Zkmc3h|A6Sn>zpYeAD@)R%wINsy!_iOBR zXqA25<#_dDXqhURX5^OdS7uGYP}xCgStAQM{CWD3?JyRc$pa4B0*;7g7bV%D=qR36 zmWPTXBeh*6Pa3J=zf}(=H`MKV*67LNj z;Yy#GsTyo-p?S+K@4yo>@tBM}6U+gQ_fY%2<8$w6-Wq+}N;(=vY}udimZiMAS!pAs zj&YHRs>o}yd>31N;^#Kxo55|s@ip7;9gll=eCyfdCqt&kGgqX%f3T5A$C1=F%eNbS z?)sFwn7t4{A#i-dkR^3@Uy$aTs=Hb%O1ztBM!6?seJ#&vhPV|41-~%)xW?)e|F$B3 z1AG%WzANqb&M)`w{Htbgr(#uRK*8LT4(&B%8U{hr*87+6?-e_(_WG@RBhG6^i<*r>Q?q(f6Dk-YV`{5>Bwh- zdf<4!YQJ}U?!6mciLM#4!PREw?{~~i`Z<<&r`0RGe?tBMd<-1#7xsI{=iVJJE%OF8 ztz!=%c`%qRNyViv`1EX7F#fP>-@%GKTIAUTRb_@g#U1`%8ow8un5i#okk ze(!kQyW`JhUnw)~GbYsDuWB%%jRDe8W7IeFDrGU@NOcYCVRjn+omRj2|7YZnz^B0R zGi0L6v*UH|J@ZTWi!=P&M-5k(b>vSzZT+|Ug})kk12_{n{;$~Y9j|*&^E12527h%$ zUFPte+7=8nIHNuT)*kf zPW{cQF8HvJvHO&)tMsDLrrw`~Tn*L%$GgRT-<{uf z8bX@1xSjJ6K9q%F(GS_jL(hqLG(KIOM`lO)z`NcL4;0s*HT*4Bzxe$u@>}5V!10e= zZtQdXPj(uwc1IvJ`$O~`h!-RJZ5xw2b9gR1f7+u#-m1}~ruEMY`ke1i&+&%L@3$#0 z{jX@MntJ4@<^79-2){A76GqUnn66G%R|WnS`z*KQd1Ln$>~iBTmm^;bZUD~in~)`4 zZ2Ma-zhr!U(xf#Nb!#S_GWFEe>uM_Mr|FACX@wqzhR+o47|;H41es@4FA5!lfg9L_-7$! z^LJ4mohfCy=PO>PzAJ-)!{+t(B5imLyo1@+P4qOrWOy6U>-@e3`N!a=!0|qUEXkEm z=Xbh%?#bHd54&8JGGA}*KH~a^!E!#Gcpet-&r;WFD|jCJvi1M8j2-(TPX^O~vtt&r zBp3gl{MYwF+W#Aj|GC~C{x|Hh{-ZbTKk@_MA>ep-AWL%ocjTphrv1;b4kqXWEDqBn zv3{zM`6ZE7G6Bf`Gly!ejN83p{V&Umzm7m23nl_*#}s5qJv=wr#7svX#j?=1Udnt? z`4)B;zf6{zB!E}Pu8dr-EZ-LNIlr$!z8?GlIKEqvCG{fS`cN4mOs&D$LdLrz@P&nQ zraE0~p}f6n{A@?BV(@L?c)x=zsr&fWb|2qd@zun)&GPL+pX2)oc{lhMaD0Bn-uTvc&zG0s zYk1B0w*Y;PZzb|tumL!}jmSOwS1tRQozZmxDo7J1e{c96LZ8dW7m;5FZve;l7P6$? zl%LwF%C!}GO-X8|&c{CPGB=YQyG&}Zyd^6$yhkIS3{C}(w*pzx-pfxGtCS#lWKuW} z<_5|xprxEIivD2y-Hu-8?-R(+ffs<|eHmF&FZ?x+nfKB@wOQU|WrlYSaw%8>9Pct@ zNqhA-i`BJHnYM`wLMn&zWLU(@Tx?b~CS5l^?D&K^xu zVH286)zNxVZH9N?stj)l@+@#5aJ(txo_RN~+_bvu(%dhLv(55dj6RpYw zVPr|Y$luL8pN4ylKDxTQMzP_)jh|jshIc4(378HX?`&jAd(Gbtti`EgD9$I_Vx45- zOQeBIFYu054~p)FHw=FR`kmj~kZ%Wf0mpwYvZUVot*-=Sx;Eu-#iv*S#@g63j<;|%&p*L<;CLq?OX{uPx;nj*dG_h2@>xV5X~JtDdp<1C`byq3{9DlP_`i$X z1a1b7|2AYvz3|&jUD1wr*MK!z-gnUJcth2620EM61oR^~TC}RZa*f2c{6fF1pXogh;QDHN&y=ILOgwj@*ZK7Z z@(19r!14YKSyJbCy6)51@fqF?EHBfXSNUarc^}Yye*}*AZDdK^w~HBnS2FaZNiPx7SlIwbTYPT_AkIf=J?)maWNn7`IOOG^3^?9O z>Ip@)e>S|y(=)sake7gyf#W?D`AhR2SF_=e`kM9TH1_gqGf~Iuk{fEcp_b-uO0K0&*<27VSy~*#jb)_}*)$I`_x{$}%vQ%gKel0o%CeuaXdxn4P z8JYTZ6!M8+IdJ@^Axr8_{bKaO8eodu6%v5u+5&FQM#~M_W_68droDdO`j38BzkiMV zGI$L*{x)Puz2RS5r>Ek}R1RDCejpZ%F6&DS+I?>>%-@f|au#qw`Qe-iyN&h-@Xv)~2b_+Lhr)SGrj#=PXXIbG*( z_H})y)a{>L@)|!deka#wc#lM01eO5DyA1iu@TMK_!hlIx29$qj_?yt5gh2e>iQEc) z2OR$^$i3y)2QK$yKuN}cl6LF=hD^DehkOiJ1RVcjWJ#UNUDi0AyTq97%4O(I0-w6n zj16Snmd{YviCU9Bvi_srmHS7KUk85#j{j|BN$$Gc?f6JX_D27c?9mZ3M$%7@l;mB` zk~ogNW2gYtb?W!prqYj%JtZ|6dyYds8Jr57Jr&53dJzvUJ7-l@GHaV~bk|Mw+AVJr zdR-iLAU_5kw_L*L{O@*rB%3X(<5Kch<5#RUqkkmwBrp{?zh)x$(yuj@to6`Y-2L#6 zSMZ79Z9uQ{>uThC!TrGT{sdXlUj56ko=D%f2)Ns;@$&}I4<02T93{~{D{>{Xr5gr$hA0z)B{5NoRyoD^u#iQH$-nA8t{!c=>mYW*i zSIfm&uhf3VNn65R7*PA4(W_p$4*$d0S5lX;?+E1M!HK}xcQUf19^!P$%u~~6MirG- z>&F&-Gk0ny>YYiOEMF7)Ts$5?ei}Rr9N+WElDdsYHXG}HA26fg@q1+pkDPm1iV$h1 zQ~;hVsl{I7KaHOQ>odHQkmrDdfa5&`SyE4a&gq4p$ZbQBgJO~`$!^o1l z_cM#F7k(D}%kZ*qSekbb@+dG4INpiKl6vsdUEj)NPx_wPa?#UldAFd~`P+zmGq@c% z-n)<`Ie)ut*BxtdYChHdI3Ocw^_lT^^gI5$!GVNL-M@8JmP4v z!-(_s=^orKGb2g#zJq?pA8es74~l@}AAl^W7k=yM$tKT>x*afXw7li$b-d>yUji-z zj`s>=NqhCX18esK#swkc?=JK@-hUy-&SsBu;CKs=CH2N%Gg8eW7_%HmSMlx!*qSW= zGW0wCbCE9xR|3cXePl^{_j^zF;?y_YK${FD=gniBuZ?^MY(S)ziQWb#tjl{FJkE~L zIqdZV3W2j@0J5as$AM`fwvSVk>MjagFWH1!^e#ic<3AhuJh0Vr3UhD$&#=~dky2E`R4}1umUw=iG)PrAiHa1n(C(lhfs-(MOxew+hYb#bIPnkLW zRC(q#JNcFFi+Gc@Yxa2=zt2Lx1Y8E3T~{DW>NbD>GpmYIEw1QGlb0`#)?L^BF<%|; zHOEZccERt;-H@-ao*PU6&c4aWl6r{SDKlqD2j)MCU3a}Y&r8LPeOusn_C1XJGGPk^)UVPr{PGJbW*@tFY10vQv(LEa3` z1&)6!vZQX~)ib+vW>*1e+&W|6ynb9CsH}i-j6VsbSCVh++6k|V%Uj6p;1l5N+Knu! z7jdDZqh}!Ni$Hf%N?I*%>ii7vDaaeZM&NkQLYB1Gcx15_r;fz^1vUgp>DIQ{?#&Ty z;!<;g@w)~6&hNEfXU;V^8#w;2AWQ1O@2*+`X_T^Bt#w+S&2^IVrK&cbRh3*>Q?rh` zm(`q^+9*qWmeed@DOhs6`5m4!t;+mbdX~rBB)g$>`S}LXksMEJsOxX{eGu`hv9Ha4 z{B&`sxq$Tr;1b~Ca2c|sZu8-P`zT1&klUTiupYO#jh%+|yrx1Ek6rld;_<1(;X?L5 z2QD6QWJx`g3s+NDtvzdDMYVZYm3mRSALBV}Dg9{sVD$z{TZ#qHN zZsXqtTV|G~=Oz0Y{mohWM}C7jYM=x-zosGY#jh@Nde7_1noQx;OB?4V+55ISt5$Tl za8H{$H@U82Bi~D@@BYHmVEx#Foi0xAApZ^g6F5J&l}&GohlAzC3M%1iW+eW5eEEn=SlJ*52LN{Vv@cV_YTxddCl5a8mI zM3&S;d`_7;C3C;?<*ey;7~3ltXyQ{YHo-5?F>gk`9o%JY>M=h53syC7KMnM3!bWRH zdzKx2zQwtpU?^~L8i6dShd8;GdSTW2#jKFi&+t>fHrE9%Nljdm0NqBpE;R3B{9l7! z=l|D{ZvwXg$9pHTq;AVem#lJ4lz!3>FbTLW<7nwBwqgjNt0-;hU}Hx+JkE|mmonZB z#sX)@1Y}7)_}^7Kwb3+5-M9PYmVXWU9e*S8mEe1pQ<%H;e{ZZ=&ossUCd=2B#kcRb zd9Dej0O#*?WJzDrUzSHzXReRcG{v%KgIp2!76{G8%Mg zy9BV~FPSx&nP0Qba(7)ZZBNrs6W?9f=i)o_a-L&>1A!!Y-FsaBN3G6u>4w?-#};Sb z_mF=8ZUrvBcOXmZA-<=S^x`>NqvdNypW~AU;)B32;P^%&OLB49%Ia<+U;KVUyYF$X}WHfzTkc$^&DzijCs8~*6~ z^RC8rL{Dmj^&h>C_n*j#D|iL~9B(1ABz=`8ll@etM$} z-*)slKX)KM4_*R}?^R?;-TRrv)(bz|EpPI>8Qz)5hk(O@<2?#lQcr$P?}eWYqm7@9 z=yQJFg8VRe6ga-ektKESXBJy8{Hz^gcw^to@D4*B2POi?I|W%%Pkzqmg`eJ7!?y)} z&d*DcZvwXg$9E^Pr0)I9V(W#U?UuJ4y>1?H-uJm4fI-0V4nvmI{XAB^o`#OUJ`Ayo z#eTD!(3M_M(>Tufy9T|^-;0p11m6da_c~-rJ;c|wOc?`cAbK7hWZZnb;eQAHjz72> z84LlAKZz{K#k&(ChpTUxN*xA8@<_ktKbpxa)&Ydk%in{>JZe^gI6Zk*^0o0FM7w zWJzBl?iu!}1YKr2o|bj%m&Xpw=_y^e`07}#-fNs_>}iM3*%P~#IUt}IIC};oOX?vW zr%an>7T))?V7*|H;ai42$F~9bOi*t*gsEGeC@5Q)Za;mX!_Vt-KY(_o@d<97AF%JKsRc_p`*7CPx@dr21zJY$g z#b+S0q#okaVJ5+si%}0{Wtxf4GWcCNy$<|k$N2m&Sk;g3 zC3Rb0x?q)2zf#~v{gxn0gCUc_M$3$t7M@%KM*coC+8Ga6TIU8BWhtbK?(ouG+Mzd!MT& zJSB5XT;74#*){TJ_A>+r0B6_1$dbB^%a^yRICXxxXbz1e6>jPc?TH#E{5OP z_bcQV!7kwJdktAq4{@V}XFb5_eek*)V$ghz*1oZ~WbCU(-VDwK&c3b4lDduGe`sBC z`5S(jo2SH8|;rVfvIYv9NfjRH}MY>sEm%LJ zZXFY|R(1dFl8UwKy8c!;JH?FBTzLlf;vN40!}X`@s5ERsa%>k_z{ef`X8xwtjAq!I zj;rOGF-$gbYO{0R^p;@-^Gx|@CjVXesK1Nn2;eH<%E#5nlJ;H?{!i)XP;magQ95K> znfIiGNZ()j{C&Z6{j{Gxf2;2Ee}h-AEoI6}8|A^3moJbLck}!QxbjknEUAa~DkM(2;oTw1Z^%!P7?4lH^4B4xD1R@> z{!|#1Px+SL=PYFT4fM{Iqp72jP&gds40R6a4GF9H$8Y)keZZ^F+LIjRpNvk9JdSFn zXe2l(8sk{wusM#X{4neP4^5oK|5uP-18w%RZ2v3jIOs(m@Lqu51>R02qqU45TRjE$ zWcC3`BJT^v0GC`Gt83~i&XU`d6lzl5tJ-)Iz?cLt9LG_1&26@N*JSBE3;AsDl`i$_ z+$lwCsrL`G5*&0H&0&Hd+9h+?S6rvVt^Zm2Uq=1|c%uvbY|ph$R{SjHNWy-Q)Oxps z0*(bSIWMna{gdRMl3XLF!sLbd+2<2Z!64OI-qgLBxUWDi1C{nO`8^jeCOp(v$%sPb z8D({w*P7jaOcuN^2N5(_eU1FB+yCWOl1h_mVdk9()Igs z*F7(Jq>0xut4rdw8hI^PpRK=Y^*T0%m}HBivGLA`sf-v=V)bn2Z<72h zdLBXkIe5zIkv6b4(NE8tboR29l<2i;+c^Eh=cPFkj^wj%ec_kpZ{(i&yk%=@Cecn7Lg{9Uu`%jSyD?6eA7$jNCu8j8ml(cf=yQDQkhg%Z0LOPevZVGN_-0I< zK6SRuK&cX6%(HyYX82Mk8or(Ab9}!?eiwWQ9N#C%l3IIgU#8EVG0Wzlt`q4>(VAh@ zYP{r9!<+hPhWA9|O0Whv-u1|mN_+5gYRQ~gQ)bwVG*u&AH=gfIe3IdP2)#-4O8I#P z`M*FLaJ+9JOKRiECY`BRAfn|J=Bxg z(`L_}SzP%zf)$;nl)?c6qmue z%B1Veu8zb_CmY`6&oaC-kq-k$0mpkBvZUr7c&AO9F=P64-MgV_&{va8-FdYmZ^LrK zdo_BK=oNqOLEZs=4jk`O$dXEWi1W-@Q%Z=m%V1rF(sk&yj=bfk7~X;%8Qw9-Gr?To zcvHxd3VQH&%CzZIrx0nE!=@^w>(U>xnNuqa@5Sg%qF4OA5&2&50C2oNMV8di1Mk$C zv!_p+F;Zi`P5N@NPkG62;P0 zcUir{`yTQK;A8ul@VWa1IsE19wN>lrdovOsBLeS6xuZ$n|Fv6vC65|AMc=W=i@;+0 znfTJwsh?lFY2~`LmHI^4%-xeAXo$&OPML{M13KhK(R&5*cfmDQFCVAvJbitw+xS0; znLwWgE4PUu8D~gZeXZti8${nO76Oh+9MAOik@hCmc#owi@{uBdnPX7wz)!+;uNnXplt3M_v!pHcV z-9al{@H3wSmL)6Neebh)c!)$uhR8w(+Yz6UW>7+g1&rqs3k*!~6L}|blDLEu@|R}d zfS+O#XBlz}p73KLm~jTi_`(GyWF-~0UHExsyd@90FX#_ka`9p>Q<Ku1uv>N`{ZTTC2AW9j<`Q9|xdIdAKLn zlm}uMChQ1#q*VU#&@Mf-*v53~!Z1pwTzm+)LgnTQwqYHg( zgQ%Y;q0B^~Jy)_hlrXi5;nSQ@7&lw3-reYM<+k7n=0bwOK$5&R=XTxSUthIeb}}tH zt77B2D%tHaoSMw(1v2K@*hk8wR2B)5`)7t_y@Hjde3iqIM8EiRCUQO4VtM&ET^}o| z>ga;l{Ql9wD}wNsncM8?)*25+%w$X`BQD8)4)3gy5m3pzk6*oWmo^Rrgx_5 z{4)l1_@@g`Ho5=2Jd43o9FW@7q zS3Ym;biLM1=^=|3rfbQyMUtKJpoVDh`&RGRUs5-$-dV^8fP;ZcE)KL8RgC%BM(L9x zm%paf&)-Vj7CXO#d==bv=jA#S_&VsEkw zQRGHx5P{h*A%z(9J41T69Hd)hGtJA@`ns^qOUm zWMEilW7uS)*M5e{$M&arh-~vQ^lQ!q0SVxe%SSn!bYsPaRa2Ffy$SXj37kbSR%_V3xUCGaf>BmxDiPh7XrRN98w}9VXeUcF-WDjKPYq0uu zX6btk`E~Hep7hBuoYD7aw!TKIZ{RZ-eopSkY^SN9N%s=U0n2V6U{B{1lgxHk+&E=h0-FNQYpXPoe{mEeYM1JzQl=7M* zH*j_8QY{bDfzh1~ z7d(0I7+xF7TwIj6Qy7(**S&r3SGwPDInw!OlV>J4HmArl6Dq&R z4D69(`P%ZnY0J{zM7_q%w*0@K%ewAQ+=YA(xX*m1bF54zvQ?~KHFJ8|s)~)9*UHdD z(!1JEdfXmKM?e~7QnS_fPL{q8kUs*SX6ajBp;Z*1qJYz=xxF%f-(vrM?28$DW+Kl4 z2bs_GFS_z$dl5F;sY0v2)%l;L{|V%$z|&pmXS{W-OfWaYUs4!% zXx&C@j@NGWc`s-D?u*>D)SFAeAcy99hH<^frIsM!#INOxR(ky+;k*mPz zS^73qu+Rd##BIF;?1*_0TxXWt$Jm$PuGrku%d4~x=AV-k*DBNcNtarNZD>=t)=9CG zIezjpg^$!^?P-Hsy57rduE|z0GHiz{ymqViVxvR1ch@5~fm^clIy+ggBc(>x zsX$>$_cyrLlYEu(BCU;#ge1=~`O$_BH(vTz|MQCYPK=;zL2Sgl6{i3Qq=YMN`uwghz=Lun~`q=cXqAU+)AR_ zl*p&8YNeb0Cg;ETTOHSrk^ct%*|k3Ich}dVE}Yt5SH_nJfcYl@h{~uj<6+MKS2OkI z2;`%{Li3ppf%AX8IY7dA|1Ksv|4mS3NW`RbO@1|I>1{&38Qk8L-c2m*7Hf_3=j*`< zR{$_AY4x>b>H8FUH~72@eUz(;b@lF^+L(KlRw|Dbq*R%fuGH$C{a+dX7a%VJi_K>p z{NGf!uBu8$HMu|2XrxBmLT5!Pv{*}gWxRzX)mc7~hmE90%hQy_^Dy!w;OAZNtgKsA zzeX-1WtF_@rr*@R=WS%9*6C^Jnu|*w?_niPmrkvgui&+eU*nKxg9FWH`uAMEX84HN zMj1E=7x?^3Fr(hjpQIhVIFKHh%wxydwB%;@N}HAE6`W`C{o*X%Taa%DclF4-v8sA4 zbE>6*H`&z^n5;4lq?4VeA>(Jt^6k#z%l|#+!+=4+CFke*ipn)*>+7n^s2!4x`|5e) zl8x^KQj}fGBUxvPUs#uv2Fp`!bn5!I1^HaCwL6}ATD7ves&%U&lCo0ZeS`6QT~?f3 zjaKhNS$cnq{36)Zo!*UAwd>9@CO#?TBf&A|vkvj0|53kAwhRrkT~30$ zOnRS0!nsjuqZ#n~iYfOES^650uLR%kN*|je){B9rR$ms)ZbwbQlPij;)m%VQR)1TT z{&wWQg1>d4|BR}$I1L5;rY=3rC~Yu_ckLuEwO0SKHdAM$f3XU=8k_;-S&Mx0 zRb)wSou+$Vy}o{uEJT?ko%~vFn_uf4oX=?TAT=lykNKgf9}RI~JW&nSf9|zez83Vk z{>;nBuYx~V4q@tiF0Sy59nb5yN%~k!eQbhua~u85OZ?%=*L~Q6ubTWA``?*yhdIcH zfun%)=Tu}#13R5_oW*0;*AyjF!~NtC8vSj4gG>Y|QbW~n75HJlP$^!ypj0{cyhh94 zg#Ov+mw5gR`7!XM2=eh@DRBPRAWK^Jq_JbgFU)(E|N7P=W5w`R zbz|r`<+rL)&oOymo8KPtp7zIJMGT9g;g{*K$Zv!9fwL?BkH)UuyNo?AzOsj1oP9%3Mz)5(9(gY8w}u}K>9^s}h5JdI z65bpBd^I@sTOYGVg?Gy}e?9{~!=r}=&+x$1A0Fb`TpNDV=V(c_RNdi62PC5L&-~n_ zYL$xS?Yo~`xyDzD)erir)LH$3pIfR?N;<;GRjx?eE7C3MJRA-^Sb zYh1rIMjvCn#5TXVuh*jHg$JovWCYgaM8>GuQ$y4W>d3$#7K_q_h$O})CyDhL)bn8}z}0V8Dz`kx>&n32!Lxj_-#{C#6_ z`s00gzs#Ewnw70IivzY6O1WUYW_Vw92!nzPiFtnRJ~`1yPMrAl=l*|zTBa8GW3_s( z<-5k7R`^`~dIR~-;4i@0^LJ!zPxtM#lvBAv7nPo{Na|9pcYaW$_9vr*fSc$Nl|n(u z_pJYKD^Grwa=8S#3Y-oc-_6L9YHjUNN_*!QUX672nz)Q=5G6$zUi8 z$#TQe?`uR`p?lQm5l-z3fzpg&?nWDJnLynB5 zxQ4tp$*dVv^o8o!f>G3*zKYf&7#j(S>9icAG6Sm(+e|zf;G?zE`Ee!k&0srl_Uu5G z?M|0xKK1p+j@Y}I za*;$n8Y}|Nj=Pa1UGTJtN5il8j7!bN^%eC;tgESz{^Ib)&?Di?Lj>iAfqwgiuivKY z*Gc;IyvsxRnAy_DyC*U{yxmu`BSRx|vGzzF7mQH@B89QVDv!o-CCey-;4wc~p>h&I z&O?5`!TeTI<%OcTrzQ07MCGSJeWIiCLPa!-ha`e{)aP$upqH)w;H&3-|1Lka)-MUJ z@WX3WO|X-OEOm?Z|Gi8;3_%_PCIILEWMoM$AG+vgNxi7DdmVy%R^#70=yQCZBS+s?UJh`4`N+NC zTipfU_p?_wdGl0X{l~ntSibG( zbN=l>{w4S|aD2}p_kyp=tg$W4E}su(`&V+iiRZu%GJN|Z&jNFSMr;m&*m%GZv5MgKF62)A=dyf7&yM+$i3jJ?t*V; zHeZ9~TZ2BwcOLRZ;9J1)U5?xfz9YNfdp4V|-SX{1pX2)r@+V+7aD1O5_kwTrN=xX< z=Zl@nXX*|U&jsz7>*@;RN>B|P-Ld=H^7$vHc+2xmb^1w35e zgx_iW8~ah_`j|pK9xMfp?*U{lRM4! zg!e(TL@npaX8skhc;SeG{6h27Tl%goKZlNRToq2}Lq{-BQwIk9<7$4tpeSJAZhmf% zBTvxhbH5NoV=B%{i23vjgAsT7J~yciO8wQ3=-blx^_!s*)Grlksc_Nq! zoPUQROIl{{uh#u6+dsB6T3xkq+$7l~O84X2{QKy^(vcnZxe_ZfSVf6bJ$ImkzWf7q9g_{96FI$kmSrBm(w#*XdqB>6<*@^j>u!E3FA|=j(gF107B4CyCX7#PQv<_&cv_LG!!bbxed$Nnt0CGM zUfM1H0`$B4i<6O8fO5+z%w4yC!h6zMp432`gfQvd$GfD0hm2oMS$cnr{1DjDE4`&` z!?(81Ji#=&A4GSF)w?@OZ|pOkF@nB8QqT4t!9lb9PJ=H+*!Lc$HOk40s6GM6jW8ae zB|edGc+Hlt7TxZ;v=#Xha2as%Cx$U4d)Vn#cEIWbdnwxt70K@hQ8VSDD~ze;rSbLdx7K2N0zkTFHL>vIBu!)#kOg~Th#fX#}qR!M?I#b z-nNCjKdEWzs*u##52P)tV|;RwR_C=nZ1~I3U&=?qzaIHq&;T6&708l?*!Hy5wy$zs zJfc==gFN(MT;xSPE)w1Qoh#lgDWRF`b|e!-8R2o!9m=>p%Kad?ftu zBY!U3yEFU=WJ&$(ePwoiC{5G1_}l%*e3mRueTvZN>PH}QTktG#5c*%5ZhX=bA@^&AK5+(7%}-4~w1P|!(gWO#Ud zfajgYP4@o&QCb@>j~f1+=y&DoCFEDY?=7b=JO8rp-|A~>j+LV;3ACvoPlbc9eZG*i zddL1f%`E@$7q^`!{Yb!R^Rc+X`UNSOyAcOy31xJAX!~5b|3#XZc>2uJ+ zq|_K*$EhIRFOMOVXkL_l$ko2uE;KroKW6-V2)-nrNWMOY{5E(WID2ycVeBdSgNgIb z-)CPBq+D;>a0c@+HY_>2RvaJM5bOwj5%wE`-vs*Y3H1eAiILU0-Us24bizK9{>P}u znd&yyok`7ey!wbC z?@RA!h#JANf^Ub_2sNuc0C>*MfOji$w_-Gz|q;P0N>=Q;rL&JC);~g8mT!n8F z^S4GD{6r#toT^P|ceduAR+#AfE5F}Tb*73IOBG8!WBf@m!sh&0jC>kc37kJ?AxrAM zJ)@@2XH*=2ijpN1ilM{v@ub$fCm6!Bm|>V1_k&0uMs66%I6$#`fuv^3--3R}--`SP z@JHbI|Bful@pl}5lyU(7p;9s%{GGaq8N;qfy1qRg3}KX57Vw>-7Sp)yCRTS zqrCN5>;LDO>)jIMa!>^v|4)!5b${K1|0vmXUu-C!R_2#)3zz9`QNVcKD3v#o=>WL_ zta;8G8%&O~=J%lef_H9)u2JaKK%B8U{t&x zpBDuA@ex>mh9NFXawLAfcUfcz zBZ0Z}SNh5wOu+M&Gu33RjsAk=Z$Q7xzwaU60`35g|F_7JT>fRZTVu!D{5x^O+RB<$ zQjN*QKkHnKZ?&yv6IRIBe;iBVY#W$Iok%diCeae>*i0=aUQBzs!7#TYUd3G>M zXYBM~uFlvJGB~fxjHMXls-p41sDnmlW%5L>NQbB!18p5~{+;pX9qe^+{x@>s3-*o& z&Yu&JCG{9*J+`TDh>MelP*uOHh8N;cLx?fH(JGH}IG8&zF@JD@%8%#b66JQVl-vHi z4+#dxd1iz(Fer{k;(1c42XoIx1y2M+=}<0GKQd-`wJ#gHo3P9ECm%$99Q+bEyZd+{ zZFi6PpzSsp(aG-S|7pA1cNx2vVVASJ7WrJz0G!=-B1`Jg?nBMpva!5m;bgyL%Vg<~ zvnjw!(fujLff{AQC+%Y*p}76!H7@HO$4S`Zj2WE5O@i0aR{AccIpm!m8?WN5JDe_2BYMMKlS=U%-cJ?9sg1d6_^@DT zJUm<)PzDgDOVin(I997)(RY2#*g0E;ycBkboyQ`d0cwG>^KZzK%KvDt-><#h`8qDw zJ?@C*N!!SV#P|I#;(kNovWR~BC||#Qt(jpw68`HL*E>}h_ z2LZOP*VQhrju%@O74Q%!q5g|mv+-f!3qtC1xx|n1M^G{@2^E~mcLj9i6Pxl!^ea%u z@mTjVx-0z3Wq#3!@M%0j`;NcQxbUSRbp{U+w)_6LSOwqyz#qjB$`5_@PM9u2HC_Et zu{)%<@Tl$m6b;Ku^m)l2uvFa@DqKpTi+#cka{jmd!X2>m+ob!H1tpYpt`;zv;)Xp~e?FpdcApIg9Xt0hD~YBWFo zQ^oe_7aKe(%;L}dv4utIO+~1Ov5DyLL=Y54f*JiHeN-$uETZ-)WK-H$KAWe8;?l5( z<1y8jYaczU246iblMT)e{^2KcLPd*qi+_?*pP4u`;b)Sc zrJOy8{496@xHv=t6NiG=jsM|2`ineTu3S@E!6i~kT3hg&@aqBBpq(-O_B;ReKx%GN zKKqP}R5M~X`syRy(@n&~$?z!kg`y*QS%@3V!x(#55RQc|^rK@#BmC%4>ck|j?$0U; z0W&?KKTtSzz8`lz#^%d*n9$YF=IUbaIcT+oHbB1)(XTg}-|C}( zc*T5ge&7#f^q?`%dn0j}m>oHr-tI~21hO;FpX~Sd^YRLqqY+cbg-_&@c&Pt@1I87o zc;XVD*-|IS*i&Apf3UP5^Fv=QIb(w{gU1G^G7_;cyogfscRw^Ok{i^=F7VZm_^)=h`;&oNb#B15}ro7L#9=RhPcNId-H&VYv5H&N^nZ zsM88ntn#?ru}g#eWOy3eXMe{(b;Hps zRN;W2;`Gv0i%u;WJvFGPDmdVTpknEPqell7CyX6^0CH^X@}OdCzXOg7Do)&Q^ua;J ziqyD~LB(-H#vH*Xvqy~&Dk}CLJu|3SdDua!fc{f#NKmmPIc9!PQ96ChBs2^heKgJW z6gt@49o_DSFIC}#$QbHpgCA@1qo>8DMqg2})1!5<)1sBJ>CqLj1<{4P9|ac1W=7BA z=VOr<$7V$jkIg`y7G1{AC&vzp*6{O@Kz@Ib&L%I}-{jNmcql#2aUAkya2{~^bRV*$ zopxMl;IBHj&pMx$R;=43{r2Ilp-s<){MOL#!uqX5zrNt>w@UrG?{myiqPWJrH*=3r zV{M+i$BrG*QDh2F&kJb5ho}NBb0gGhoe!&W3b}Gc!@&%0eQ14Omg^PmY;chuJ0to{ zOl;oA_!CQH{27Hj6C4PfKeKX;KjC+cAMdnx>CXvfn_=hH$hKj31g{VC+lGC1-s{7p z^WS7NJ@R>i=~$<#MYpNo2kOY1RPalc z7?!xgPvl;wm`o}ss0=(^6|M`u?l0$})Gvsi$ynaCO#0*ofAHvm>T6;3HUlrA@}O*d zhVzGT0ehaWMcS2c3}^0_7eluh5muTT(&m2(C6OeW`D%Zetcryg+775 z**_MSVnLkkSDsLbtNnx;uTtdG??Vhi+~xT1?bsjsMG_6tVc@8@Z;U(o-4zi%OPiuim;F!X-^ z4i#zk6BqI)oa-07&U=A+F%<5L0f#f}CXv99lH65m zVbZv9&-;l;@GHf144IF^R{a#hYy4nbEE*lBUQ)4BqgVU9JnF}09s6WReaAm>o4@2> z-u)l>;ms#s?5`jvma3=KiGTB#FIDHMX!Y;>#Lv_!nQU2gvA-s9<`aJX@d0M;=$ZwzFO`d7Ay}<3MJ;=>mR&a9n*KYniNlr zdd{D!|7ynQ#Hwg}sC1=&ky<$J*p=!U-cDE*A#%kk>F5`^FSp({d6 z6TMi4mq#Z>5?A`eF7XrJ1Uzq(xzZ z;J_kgJLWPgGCCoWb8kB#73CU5xXd-*>bc87WZ5a9thBV9bbklm}T+ zAFD3%)lVU7D>L?74WH`=+>QJQcpNx;{!(D<+4h#PC-p(+_IOoIsT;o^*^qZh(HDLE zhP+?z|3x2ppw^i3w)LICyuvtfDxj|zQj=APdKyiRFjsy=)m zk-RFDzt4bjdcfcHgR%Jmn@##(V@7^x^pN06_FtJCrg@_s&g6yzXfAoVl<&(tz{0X(|IZ7pdS~Ke}&p%%s?S z?IvS1)OJVs`iSKI%Esqm6%6Q(8>&N<>FH6fHZbjg8(<`x`~Kj-amY^l0O z#eW#$W?+Y(|GA7FGaIpA@s(=OD)ldEZqE0I|IXjfd^~2@$i#>@{PB!FPxzf*Vm_QU zY*J$4dwyYY-|zal#W@$MNO3S%m&5k0rku3&&D5(GklzG<2Cke8C^Y3{e>?wu)yv(K z6X}GshaL?+3^5V^lF)}C{oFO~y;d}pOv_Qz!&4bmebuMro)KAC)OR44SBk==ehzEu zms1Mz0s{5*Q0y0e=*NEIICXGvyebO@`TFs`S9^i6w-$TceNO}OMc`Y&*?T#%Bv-$( z$2Y3i)vTN(TSW43oWb&$!;2}&i4PYIVzfj(h%_ zt>3Pf;JigQk1@@bWPV1{doq&bPjzayJgFjMukaj=Tn^3#&YvII?;VfxOWF;)AcV8t zhTQA>&HnX)emn18CT}+R<#Z6#FO|CA_xsZs0&MkJ=(QD=-(I*_Eq)+gt7;z#RlgM+ zpbprU)AzcZ{@ZfY^*Q~OdNb(%RuEhi?f*bL_;H*+yseP2#p&v9R_&HvZ1Q0@cDeDn z+LvIqj!rQNZ z$QulX1IIfOSyJcmzUsC0Yc{Q%#C)B}TWU5=tY&`tp zEIYEsjJ6#oWioXjr*GdvnN;PTM<24w6?As-DE0cY1@QJacl-}2YkV}z-@k0j#o0A*6w~4&gbGdf@fiCxmfMXUGIk~ z7?4{K6#rkOoe6wZ#o7PQnRCv)H~Y;-LRfMMJ0b*R6A;1(PRZ?HuT5FZJwU%1n`u{#NXL3V;K;Qr5^E>Cc zH_1HD>@&|i^9+O8P?tFps)A@xAS*48Plcm=$KfSXi02b zbfGW%hqX7G{I5fPo4zNYUjnZHo4$R}5*otuEE{&4{`=VJ>o=f6*VkE`hV4ISlK7<{ zwb(*^m#HwVbi#hFl)OhaFU~HIRYBlR;0tGrKSQnc&hvX}w$6cVM$UePMhQ}|2qH{b3(ABktp1o#O-NRCNt{``e7X2aw0+XYV5Bm|!@t z@}3MW;r}Z?O~sQQsBAIf49E_;+?d~JgnZzI8Zse(hpOxoF(0jnEz{>MFv;>=f zhuxog?EGt$hAyZ3Ru@4k^)qFwn~q!!$OW8r(p@`^p z4$ixJnPA+NIL^0CJ*g)ybXa;Ee;E2v@c8k?uf;YTCUTmMA8`j2dYDLr@gHate_l7w zDF9u74IRk8kutB<{*>b+Bkoj6-js&%PA3leEdAzc=vuJhIO3Ih(>~%eiKr}$x1mkE z&q2Qce(@i~tE-GiTV+bJJdF2Xn|Ql-_naP}H?ZMo`A{Ky1MLM~PV`~C<-}q0VLkMP z;Ns(mSMq`U4Xd6Ayh;mP8^*h)OQI0DTwu;qk<~bcH!HWD4NjP<~8Jj70IAe45h!yFQIHfS75`@@@4M2QLR#MC+^VYgi{{ITTUD{-Zjt{ zfQ`oy?}RnWk`bfKZ;dz90%kAk59G9Jy(^E{D%R+_?A-_iAv+a5h^qXKGu>9VIme9fc?W~cd ziN0lNS68pX?XP zWtf5=>sV@Gge!Ydonc5F6~_T=)kQhupO%>wJuw;?%65K<%I+K_;_QxP_Y6uheKutK z27RI#{8v^qmruAPmpG!i)X4%54S=~IF5YK zb!Otq4KiUXsCwF6>{eY9S)5O{93Wf#KB+ja6a(6BYAl-t{ryxg=B2pNZ@cjua6i)n zhjc-Tf2|v5#PV-&gDY?*nc)|xXsoBo$;!yf!0$pd#sTuI64b$7YC7u1gvyAFNXcn&$7!(GbeU1bB+0mYTWX+Ay4$o82p>Orn@ANJ@dafUY=_h@*z5EM0w=bW8 zP5%mL2|Gi*%jcn8`Vs1Z(ese_;yUjc_iM${`JbMC{Vw{oD!_oUIl~!rGP=?Xt-Ov$ zhLF+>)zi;LZ-5gBfC<2_+^(y-$iZZOG7DHz(#d%0OBZhs9B0Pn;1904L{j8tPT&xK zy{j-IdQiEKDD@NNe&VV-U3Z|9xYwkw3HcMqFXj6t^xNPaVAJ;}XbJ80TQ+^mRRtcCkf@wrJdPmOm}0E2of@couYF2|JsmWX}_etVjT2DFb!CKXF*G7uV1zNa9pyQ zEMzhGl&lEr-8^+72cI&~@Td81TGYjye3Kj*xzD7pf%xor_fzPXz$?J=`x070dwUtn zuT49iuwJ}5N#!j&D9ifJIQjqZpYm<->IW>EFyr*kwtTcvf06+xw8JF(YO-$&@i2Ti&P2PF5OhC+`3V}MQ9 zY0wgOx7)9?`7Zw6S8kfIepb!;^_7_LknN39<~;uG^`&2vjiBzTG$j^~L^D(9yf-T` zfvbAR@V}k-ZMokM{Zr5cEdS0Y9Gb7zuHEuqRkJ*qtqtzezCLny$quHNPl*Nc?S2o{ zUo3b$++$({MZr&0c|3*c9rJQCx<+($kkgjkVjfwUP4=g;2Tq1|mQ$EyXb-Wa&h&%q z{Inn{8H>nIyXr3ADSO1EqY61~IxdF323!wpIv#Vvr!sXt6 z4?m-O&^e+jaEg}}!)%EQc%(YZr#wICK|4N8ZG~w9Cv3v+AbhP{IRnv&gI>VOH3nM3 zamY1q?Z!2-CMgh^+{8||I9F<}a-Iu%sG`XEV&(0TSt;1I1|B;R54-AT!bd{=kBmH9 z;AiEz2l^54V_@ZZ0b0WG$}^dxEy$D`FQqa0Tv{bv+dJZ)gz}~Yqja!xoPt49hn7%| z_=!n5211vD;lRpq2DF6ZmE-hUq-c?v&*KyL7jdY!h}vI5J#!iPQ}CcI=T+R!nb;$v zfaN&VX`K6i%;ZZ0{A|Ab9Qq~j3b68g2K}GNQ?qPFs~e;ymJc{Va=y#xnn5EF!R~w1lJ2D{3|wUm=`8 zk;$l?SR{VpQHjnk&U2o@7Z;m*T{#gIL#9-jJTX@&^}SeEnyD8X!c3yK3evk_E0e;p zF#2ejaAZU=+(dLNPuc2aNQtIIvsi2QR`>f(^KK*m0pweVd@^o!9?aesC;<{=K07wt z=eP4&+pqK+kd)gDC}O0Jd$ozu3S??j=OH5#Kl_F@1?p&`p^yc z!py?YE^x}9H1gEJ+m`bV=)1tKHu4<3z9r?EBO8~iR$eT6e)`#Gq_eH}#3mFAJ|-f} zlRJ2lqnvJ~W7c`#{M5)*Seh*75zwQ-cpyRY>1gwcw)r%B;Vq`cNo?AS2IZZb6d4wpa z-QnwlI&SUv-L;uW#G&V#{5~R$pUzl7*>Gy6YosJHngUCS&m;rMoJcp7A4gKZXDUN( zdM7e9HQUF~i_W%3G%K1N#e8C-baztmQc{Z<)#{aM5lQQwG5J}G+;%>CBlI2Md%&ja z8E6UZ*KbFvf9#}fsvSZusegMJOX2`vB3CmH^E;d$|$;d%Qb<;&ES zn`)LNi@Ug9m2Fix6T2_auiv@)HC;dV^C1l(8&aJwg26Oa44U|fb4sd`!w)C0X6wcw zJd7+^$BCcZEP87%JzzzXf^|5P#PlpZo5ARs-*@5bfa6N@-4r~oVJoj~VHz+nN ztO6-ambbX<{K{-0xh#leX7J4vR!1?`Eom4`;q;Hc%5eR(Xpo;4?bV&0tUKT7XJk0m zNGV(n(p?otQhW^UsS)Yu0Mgh;PFE*WhsZp>%Z!{_klq~^!JHzCl9fJ#hn!>WqT=c2 zWcVxwqkXYQ@}dDXA)8MH)R2*x*m5~f`05Vs9_QD$K_}LH`B(71(?%9AWa& z+6T7pH`~<%sz8I1=AoP$FtB1B!36juS$i;%D&SL2tS7ecF+Y+L^&)a2;u;q#TGkPJ zjXYKGD-Y$_2z@!Y8d!O*hnDb4J3lS9UQVdxf`(=K0Gm|D26sDNGjg3KF&bDtM12EO z8Rr{nl2h9prl0sMzu!X_j$~{Hmfvg866$|t_R(*B%e*bWb8FVrtXsKs>V~z|@GEJK zH2QlZZgb>OSHD*1=L6=uJIr?vnb+gN-bg-zHRd{N)=)iC@e7$6FTuJw!L=v77<~CA z{avb2**jhWAe4%sN{UIE9L_ z(SOu)e;{V>PSblP9S4we6LQKp6FHfET`&UJbgYJ!u;D243S%6m`$(+^JK!F4KNBB- zFPqo(<~2)y_n7&R^%?z3liZn8=iMr1+!3`3ADdEWo{S6>W-eFWdj92d&7gm^n{&N8 zMvC}cl{zdKPaDT}`4KZOEB~EI$8O|IAg82bFZBNcH9DD&T4)KILc5Wc&|i)%k99I# zwH>9@^roUw&lb5&MN{3w3uNN^sbLy&x)k~=w89ObB;N)58*I72iR@owht*gWeB51hzb9j4}DJGfcm=pRxIX zS=khlk29Q`W7-YQFL+4`>$CBBdKzuEn42Us)ye+YNRFfvtz|A1^L`9wXlx_h{Pgi; z0!m;;0cKjUu~?6umYK*HPw8Sp9;A%-@8G`aV0`vek7KF%6H=z))?q?)0$Sb)0SUXy z_h&Ol^qRyB$Z7nGN!RVjUCU=F-+Q2+08as%u75yF_$q8~)(=vfbWN3X)vIqu^hD|0FB+YYHI-iFBno9*{seI{ z^04x!iL}=l_D=m@jl9#xCi~s_(C30xz{-0aw1izpn?G_I6nU|Qyvlo6j3IxC6?`i4 zq5<0zDPu@1j-3`cAyPnA5AbLE-J&y6CS*(yhpczG>eWyh82sJHvk!g=K1%-m8TxbZ zPhjOyrp4)fQA{H7Bh4OR1- z54{Lf1Iup(v;;eEY0qzl8E|sT#*7z6RnE|2RVvERA;x7uOUS2@cov3yo`-%H{0>+? z3&t5fD?&e=8^ZHPt@T2uD_m^jqw@;moU`6I=iGwF&Q7pzPIWF`!L&77cTVh6^bv)Z z$3$oV?u5nmzuQ>(+$oaD`5l~rbc(F!nVu0H&tf~XguX38UGfx@L~UC=s3ho-8TC1E zB0C|n!WvCP0TB(NZe^xq_KsF8g0=H68Hmcg^CAO-54_k&r}ST@Ja>^UJ3ss>^efR5=cXYpUThxs`_p>qlyxTIsNerPO%wY7) zVd^EzfH8g-wZ|n@9{upf?Adj0Pc_?}aCtQ69M(3`)NZMn3|9Sn2YqJ8#hJp}?#aPu znJvEUo)U~BO%St#IZ^aItFI4hjuD>+Z@W{1 zsq+7CyQc;7qS-=B2qwxZ^KExVaB8&M*|_A|p#}$~om@K2E?w2AEOTd7!;Neh^uTR^tq(?~oC z;*oa!BJ``^bzu4Y23kUgd@9#YsF*YZ*FkOAy>%$N+K^vjLb6?-1U(vz2bSM7XbDGa z*E(JEjK{Uys+z?y(pKj>TU4=+(YzQ5&(Z&XAmmq1e53eA(swWPPrx(4@_Pwd!mQ8^ z^ns@it>1oR9r2UvM(p(PwmUo)wC&BW@Z=j-l=`c_c3nw_UO$OVbbYo8MH0Ouy0KN>zx}H1>{Tz5PltuJ%_MAcc zac1M1725q|t!`smJeIR?%7VN2Ovur9mPvZbI)&+ZB9C|(21Z?^*n_|-6E7Z%B zg?=gQcysz1o%Bg7s@F;K&AF%wGzq2P63_{hfZ^aGFc3T|>IV66A$Wv-ixX5Cl2d4E zymB^EJEM##z==(u<}=^K=GyPX3ahA|z7#iFe2g*84DutH&|}2+jrpS(Q@2!h%TwYB zI(YdzzbNP#O@Ruc8F{0FJKe}KUMF`KGOv3o`))xvLpSlp)zpwfR$8ZcclNOSdBMyu zE)`4+7NCC4rx0;$!^}QCIFkiiCk}T;6sM6Teif5Lo}8%U_!Q?yWh{-|>T-secfA|j zD8FHMoU@l)I3DAIKBzi59?GJ>ixyOD%UK%!I>NbCcefNaA<@;8S2N{N%4g|6eg{2d zD(f3y%j?_F65jo}={F`ncWD0+mKSBkD7jG&lGXb89aq0j*3U`$xlBLrHNW_=(w{!} z^y>`$eAE1@$PBW$SomJBfHlJ?O0bA0*QTOG8Rd^g?>x$fid{(N2Fx+=MuKCU9Ca3T zawgO30e&}?7deetHyX52T~bTRGZ^u_6PR9~-eqWNFj5w^(G*6!Un;dTP=9BL;*2cE zfOTSdH1#z3bAa?G_$>LOrg=^PQh?2$F3=K=Hhy3nvVkixW$jl*jjVFEqrZ+aj&p;2 zY6RO2wo*@J0g>os_*D^~owuxqz6e|jEWhp0655}8wC!if`kLx>OIHkGDX!}9urGth z0}-x^;inUAmX$>u9~fNn9gVW$Jr~b}Iy8j*TZrHC{~Pod;7efn=S@E@{@Ur0=`&tN z4Q{w+9m1W#Y>Bn9!@j$Bn1157{nQ1}4}eF2<^M-$3Aes#>fx?-^R^l5^(jWFkBwg6 zhsEzhiGF73=kJX}hlKvH!+hARKbWsFA7)ZX#}ReDVB1ByRW!SPz8}xYQ!CjvnugYe zbq!V*Yf(>6VP+MlQch44Gx(0)+4-LGuX5FR@8@oWV;qyBEEaV*(9fi=Y(_GDXF#t2 ztAS15CD0O%)*r82KV!`_t`J+Xa;Y5DAe{wOd05uef=rBS7_MFC5790ndt{`Vp21LX zhC0`2>~Huth4D*$ehvD4@F}qTW2YMab{w#8TfgiXG<|+xo0vrm!dm}%cbeMZrmK9^ z+y$Hp`64=Pe{^(Y^gGe?-$e7@iK_k5$-NUr9X(9FBD@+07UWW-j z5c1tkyf(dWLVp1M2rS<}LrXYjdJo}x^aR%qH2GXQE6H~b^cmnBVEHbAmT(;D6%&m~ zE4Y+UC)geo*(2M7Z4Qc@X!!0TUYp+Mp??G32bS*#&=PEV?YjQ3@@>oYNC!gp9C{$6 zA>`k0c9Q>e=nAk9SpH{2OXwioXN_89D_Pr2FF#k?UuILoY|2kp=8!M(l@2oLZyz3AS7htIua0g*zIwJ*dvmprz<%=EEqTsahNc1Nf6u zizVKwAw~|TJUJig0o@x609KAw&=PvJ>o+$Vmy?4xZdg8Q5F2f{pOjVZj5QVZYBDwn zUzVN1TfJ_~`EpR_Gh2zJbHiLJvp!tdGiT3X^P?X&pn1GU`MDSbO!soUXiA7^G#A=& zw!7+MBZkv*l99U+x$L~+Md+8o-cVMlC+)}EL*x}nXX$&tsU8T)dYq*It^=9a$WARb zUEy113~XwVU&9RF($kXjsTt6-!8~B|Ydf@r_Vc+z_)l45^NX&pMXtT$(HQi=o<;m^ zq`I;Nn2#O`3SAL48IgQu#NEtiHivT~>FHwimq>o+Mtd{$8?Ej!{L4ldd0UVtfjlxl zI0*ff$T}}6?_6jJ9hR@;*CaL!q^GVEad~``o|Sxy$P*89B(FFsUS%IuMiJ69(#U-~a@qE=8~Q2m zGhp*Mt-{FNz8^XypIhZ_TP;KRAB!Zk^jh|4Y;-6)E^f5!T~tXZ`|w~u2eJokWS4v_ zJK4y;5cv{(mV93Zy%uZ$R{l$&CA7acpl02=wd>Xonp1NTd0kMxoUvi@+)U>c)HhCE zPlXjDi=09D`9}9FAwJshYa%|IU++P;fDc0+(jMC9Q^<#Hb75#2ZT~@2mJ{6n|Y`VT5{@#v5_Pug#tGfd|)x5@MZuPRuT=O;Nnh$yI zB0bssuFGumI&a#0YFuPo=D66n)N#*8#;MVNkBt6ErTNK9}DvHGlSgxNU%@tFCM1eWy`Gm6q7$6A=fBUB67Q@WA6xh0W0@%XbGc2 zziJC#H|vqL>p2QAb>*s>{)6Ne!-n9@!55!(yz|?c{3l6nP5idL?}gqEJ_MHkN6->%y|?41PIozneson&)_69`J~4Jd(XHIP z{c}{Y>MGqx**B-ROmCoVqp0$g+40Z3NGudUbU(nYc!J&nrqv%g7$4u z2u=mgTwGx3$ao~C8vc#MZ`1uO^o!tSVEMleEy2zkZ2KeKGuF>pyJ5;Ev&zgZ?L9a~ zGRvHGxvG!L;=PX&-w;(HpTdPnK7FCbfHGkDEQ6LXIXo}1Gu-co&&sxZaMd(JTr=&^ zuA07bFVA)Mx%Iv?tU#49kV%%6-LFS_WN1+7BC;p)Ea9s0JjMM*|z2;+^Nk&L$(dN3FUY!^fM{1m?IiL<9g_#kU?{ZeA-Nqd&Y+~CgCM(EF)LHGn0DYG0SfVl;a@h_$h!}DY(9Q0vYmyl4_JBoKug#Z`p?`QzT4E7*2|1+M!qh? zZ-ZODgE2}M=ymLGN)C>ocUMebyGKe|^Dzht7=*~l^O&beUWzpIpQjo5Ho?D)&oUm} z0DTwO1+09pLQCi%Kec>^X6Uz-&R5CF0z_<~klE_9IVnYaXf9?296Q6hn_N68%*F8j zkj4rlXX5OnK6wcAG%yQTIhR69u=?b;LVa?Ze5|OcIbZ5ylRM{GmumPmp6z(8lB-0t zj34T39L)6|1Jpt?@CM}<=cDAlOgyKQ%SgGviO)CkG{R4suH@Su=zZWlVCDH3TEf-s z>;&7$qw}qGnSyEHoc-bt%DLK;%X$a*>dB=UHnDXnQP1 zHW@K4G-99!#VxXtW3Ge zv5{vV{OmgUkI)~3PeU1Gylj82pp6_;rE-*V{;bqlD2E7AeI^KvVZ5WNlKDLu`b@AG z*mSOkmXIFWpZH-tB!1R5GNG0vHn`n%m-;I+HkIyRaC~1J*Q_XDC5%}WHn{j8%<@W8 z$nP?CjqY^)ZeF44r6ZR|by)uJv-$pO=nudjftBa)&=L~u?D~+WrgkOXv{%$Dm0l{h zYB`$s=;AEoKpj`_=Bg#^uLRs?Og@iQl{yymzaihU>LlNJ(2KwlVEL|rmSE?hZRTTk zU141_<(3ZPhJ#*%^I%=)I#)8(NmtN2%1o&BM0R|MN$+mrwds8s`nRA3Sib*+mJkc~ zRc;993%Y!l>-Ef1>k{gK`#1HO*f2hdy<)BufX}&wA*v87l>zF0te_(&sp7Qq=u$D< zKiij%;6~S*7FiW#Tgrs0Wk#;@CCUDv8u~JD6|i!B7g~b7C$X^ku=z{H2CWiCIXi2s zOCj8(^y^8yh4E>Gc%z&c`4*OI@Y>QR-Ybn$4$*EJ&b`4@P(jV#$^p?hY>gXM3rIDu&eljzVe(P4~`#~eH^1KHv zVRx8MyI(sjzruAXm6tmuKlAmSk|p~2ru!@>%BaXuEKe7pE6P+|a7jKJ^}%hf>gyF3 z#;`{2=FiIw@^ZlZ+-O=%oPa&#`im7OlNYGxxc_o=_m)%HxlF_xs#%|FS${)S=-3=5vBvQ4SCdTl zXy{YHTwwWcf|g+K$831!uyVS{UL@C`?(lagR+#BKP*mvV_K~-MqZH{X5C01)7pKxg z@`FxMcW!E~8d8i-Al9uXt^v|0nqRv9{jS@`-|XoJp(vyWar>&-kdw`w8# zp1KQs9K+$6a&hToHCF#O<7~)pH}NI-PSX1V^e@0`!1DVPT0(ohCiQShHMg;uwIF4$ zE5Np(7!_t0Sz2)DCtLMOP2)TR7bHbdP>LRg8^ldlSHI4rchtEie&Ig}dJdQeEdRyf z?`?l?-|&|$*Fi&MtkDN~3yM>n77nN8 z&J&8D+|uC;Yz2ek&Ij=7m79vYeo3d?A)2ceX^u@Hzk1@c z>D&eV6YvbM{5q{XG@W0C`x5YDR9htz3mHGe&ozmLIf|XfF@0tOWVhO?a-0v{hKN&C ztQOKyf13*#R7oa^In1BaG3PdjoxnGRSY9doT6g1!SJ$98+9}PG!(JE)@mE2&Xm`9_ zyBy?o=b)qSq|dc6IF3>up>!m)TxjyIDwJ31$@$P%fNOwF&t2i~t=-gPp&gaYzmrG; zOB9?nvPAhAOB7z2`x$TkAa;CR3-A#l4gpf|G})QW`e^#e=-7iGvl}DN3F94+po(jt|7mlI1%3;d{`!?`dHGi7cli00G4zu{NA%Nf3Z zEOJPwyV%HkJM!51>;2FVfk#6bW&YZJpQo*yGuBVm3#|l_aic0g-xJ1rpiR8d^SK8F zWC97tj(1+oxf@qiuj5Zm+|RfP`A0%i7=Jl&S-F=$*MODB8Gm`ry46G-N9;ITcM^@$ z9LBqgIBfYn4c!EuZxink=b19!lUC7xP^%8?BWCrl0p}8v&(5l(yq%ysgKj{Ag4#+5BdZ!7)X%(IKsGs`{>quCf>@Gp}O&7vUvnKtwU`Xe=Tv@ za=aS)T5x@v_>WPJrf(}HJ4&5V5_dxw@18dC{u=rn@P3N4&m{YW;3 z@%CF|(k}hj5a=mj4Y2*jBjN9D|8L)6KSri8tLQ4Tu73scyh2@`h4g1}<5S@qt{RvB zs2lH+mCv<#!#d@o+|%x^3-Y-rZ%$s8GwQ4^<2W}fKP%PBKI4km5>lgwbQzjIM3wTV z;vKt7eo-(!zfaIN{4C#D6tQ+2rf!IFAK>Mtz8^$hoBw%h*$)D}fK5+7XbJ7hp^cpq zNo%XnCyBYG^BL%JSi!v^i$`t6a-v!)@zm8BzO}?_`CbQo54ay#z7Io7u;mmF=h3b9 z9EWp7QSh$WKSC3fn|0%Q zzFrXG#+A(GnFjMFm;;=-ic*G9ewE?>5%F98|A78CP!}Zm2hbAQr#Bo=2HC}OZt3*F z`OaUN$N069M&>sl4c&LG%eHlF;$Cgz@fb6YsOo zFM(Hp&A(=72}g}zdb<9}p}U~!J1$C&zeLXA1qb7!|1bZh;kSkO=zewm_yP2N;9+3- z{RmpZG5IBj=C(Z3TX|k%_#GrZ%P(U+^B~X}Sbp80kAq)0R2NiTx;TT>HMmYDAa(uq zf0LgfzZJx1>%|q&H-c@z^4ktAp?&!s+TXNpTuP%Wy^2f9O1lp(px!rA?}0O1{g=e( zIJMWBbhZ$$<@*ol&Ko?ZJFt99pe5LLcclL25U$Pct4en;Z9AJH+vUWi4dP7`(B-_U z@c(b*SOFg^#}&{wf^ERcu^n1M$LVj~Xw&I$l=Kf6oC(jm(D(mv^-Gif((A(X6R+j_ z59s2J^z*>-?FTKPqx2ubwb^~fJ4*Unb3yulbZ9;x7v2*NbvGD!YT;+)xd!@XupL-= zz5^|xgM2tk8@jDrbFPdyt+r;#5l34O#%~PMPkff&=g_GadQKLw{Bofs*z_OP@3!TJ zZP{aHug=((r9JFsk<a zEA+E<=rIEj&&;jNo)`m>3sCrf3FWG-56d6EW$=}8@LSM#fbRh-*B)pIdA~OLqn+Ws zEx1!#RkL)%pw-pqhj$^`JJvX-@fTkow-~!0FNB|qce6(KG>ozqaTGaQ4UJ5}mts89 zBYl)RA_($M^T%>#zQE2MyZ(>t2ABRIv1~Y(_ z_jG6p_8gd9k6C$Vu3WRM&8SoF&b9fM?R+6~g-0X((0h&cmqh7~&sCdsY|QU(HT-WU ze%nt!3H>zqS;$ky)Ar+m<=bxnn>lM&uU@M!xR=}R%_nM59L90y-w}z{DGT{Ho0IA6 z0o@Dq0}_N!`}%n_KIP}1E8QjkR1TYR=jvz_E5{N{08FS4`PH`JcN6r@;I{t*zi>fk zm~DeucBF?#v9^SK_O;>jKhU3pgU7{ZoeVu~W(=jIr_^bPmgf&Vi%!Qr@ z<^u^GmyeC#uI!{xc1k7CArZ#k&?f#Tp!a}RfvtZn&=Puu{yU!!-^ua``B?vAjqbIk z3%i$Bq0~X;?22|}tECdxis_MT?_M{Jo@2hh&2>kr2|9NA@9ieN{VqwSw+wm`mEqul%xIT=3OPl!bhTa7p_)p@Wy0T`~vO}3X2a|>{{*T(k|24F_)N>-> zxaF4yO;Qu&T*7%Vn$Z7=-Xn~EI&s$N4jHbJ&j+w|H~*dsracuk@=>KMVGAii?)& zIoHJ&(^6xcxtpOjso6nxdMp}qIg9By_bPVSzA17@i2s+#pMA(<^XGHue}I35GIpFl zVZYHfW6BVsjH}24m5uM7gzza3`Aok&S#PSL*MWJHJL9Vzt&PH zIp8;|&wO?|8{E(Qu);hQI}>ktzf=C?6m}&Z_xx=43>|OnohH4_@Tuh+slT5=e+~S) zq#SW*9YVc%dAJ{Q6giRwQ|H}|C=(zXbgkYK>3rI-{^~H+I=-p~lkWJH$#Uxp zJr67ZmjA`j5-LM~I=wU|6J$KW$y<^C76 zmOE^J*3b80a_jL^1aI*;zU*a+T*`Sog$+5iATmol6<;HJ`O|fDPRmZifBIFPvnAwz zF7yT9LSXq{2`#}7>q*D_CvKjxW|=;x&+TM?<61Hiqd_?@YB3f?mWvoSxc)3FhU460 z%{R${Lsj;5I%K$ zmh!k5`fBhkVCA?CTEbhQKf+_>hsZINAxlc;fcJs>nU;l4=ntVRr-!l(b>~UErMrwA zE$~V3S>*UTbns2qz`)8;04-tXlV-g7}*QEB-f?O=;X;xvpsCr|sb)Vt?5%Jr8<=@c3HRJ=Z{5wHQIA(ul&P}!HP_|>O zaA;p9@s!_h_*N0G<$DSAmEc-n`Q8F8;h20Ghi%hr!~CB1%nyWo_Ytq-h@ktH2gu<@heNgrn&T z!r}4|l|iXi85Fm9R&Uju8-hb#W#{a zDc?d53c3R;*Jx-7kA>$MHiYlw_`oexHS3mFFRf`mv2Va)Ra-GG-l6C92b5EnHc1sQ zuPn@XAprB9f2Z9?u%e3o?G27M2>AJ}y5hnCP7+Hcl}cCExMrR=;Ej6%))5JKOv6% zd7NP2*iE3as`084h!2y`RO(uPaJa=?%&GMJ4nyuo76gw?Io67T(8t zX?Q-R1G(EwcDR7r|4c5R-td{8@}SDxoiSHcs^u(+D+k`Q=`0oSGt+8*yb6S zu8L#1xngrfvE&zy^-qlrr+V$>auF3986QzWT^e6BC|0Is&JE^AaeH5Z!YKj}M~iw2_$$)c~)?zuo2QAFBNRh4WKNQcm=Cx_T9yks1NGY)_{XQYxMIaSHB9j1~T8Q3%L0HJWf!i;+t|7 znH3A-op6%mug%(^D&1I0Rtoj?H5Iwhb;r6ZwG{MsuNb*okSoD=QV$M5e+_VQ*eZ7% zT0(oj;WRkY5{iIq=JZrg;%N!_E+k&Q)qHEA zzXNsvn_pi+OBfsK`8T}XzW#;lU~ZPITnqo=2Crm?$AO5;^z%JezYZw<+Un`o<{hYh zse-A_wsRXPwPM@*5mKAHw8gso>?aktKtm|4_-^g)-U?_RIKg2Cl}ogSjZ!|SVr#<#-y55EMT zC4bN%I_V%ASb2ItOE_l!OyX9wnspmiwhC0cQ_Q!;Av^;+?nGL}>5Djwd#C$z+}TdU zuZ$d3@UiXT8_;#&>X3KG^P4a~k-g0RyX+NHq7Tes zcdY)Q;bgr*URUcpk8^gD1JoYihZ}Cg;{OzBF2Z|HuJJVB3 z7}?|IO!HE2< z%xo_$h~Q{3iuQD@`h`+I^{^cFce(2HV2&2csr$1@M+pWv1S;3$*Z^-SQ=&xr>k@sx{2Y#M_wkCNIrsyNM&-h-IyueFq`sht zNnzAy9PcZaMlfgx-ji-OE~v>yhj=+QiVS2^*-oieE4(vQwZBPSp(5KApSgwr=lS1p z-3tE|951TTL3dRW3{eleZcf2=m07JOIkg8(K2N_r*}vC7UkEM%HlOREC0IR=f7rgz zl9e0g(-o~<*MCs8zVtylq6T(r_1bzTFUevC<1c%3r4KFfPi08vJ~3~bEBj*{P{k=` z=oJoq`ai?+hp+92{tlgf2jd^Ga$N*1VQh;j_gVW7E&u9e%cRe-4zue#)8e<84q+dC zfwcUlZ0EX?zLZ2PQk=jS4kb0s%`S|MiEx5tyUQ)U_qlZ6LxUl>WlH6mh91(K1B%nf zxyLOo-mx29_eX9)>e%3vh{_v_*V2Kh^szm0&O6A%Bh5+tW*Y67^83B(4#_!#`jtDR z)7k0^w_u2Wwt8O$L(e=USZfP7&>n8U9+79`YV${OgPqO+GFWN6-?vhK!q`;%wbW zFQ1FU-oP&`>Z*#xRj=!J&M8uzxy2>YB`3(v0e++~JxI#|{z(jxbW-D0U$xvXbblz4 zF;5GO{9BOE*3-M89|u1LR{lNE670U2EiYS6{RZfqZ0CgneZUQz>12M^$SYm)Q#ns^ zv@=z$^dHfu+c|GW9y{@M>muuLS82EuZVvq6%9-h4v9dx#O0C7Y~ z)Q6Tn0dcx{*SnE%#D5^g$kPD77@wtHKMVZ}@EWl4{2p4uamaJ%6t4x3Bt{}C_miPS z5iL=k7AwEKSi^%*HsM#AZsaTbUQ$0-34J!G23Ee+&=TGX^>RmU{}YxiTc;cUBQEO+ z-Rj@>`cYXb{V`D%oU8o-F7Db1@eIRvH}NL;Ecx;Z^qb(ul2qXV!E7Ccy!8jm6#*dEk887Hz5hqA2XR-VQ|0AIxjK8i; z{M(`L0C)Z;@mFZ|u8IEn*65w4F#eB-YdZWS|Gt8be4o3pfz7`{XbF4ToliZqzD&Y< zlN4Vgi}8m!n0ioFzVDz@k!wk=b%R{TnS_%S;%VffK#8x4crD+}&{u&i!1BEfTEemU zR;*fSMyErVe|{w9#Mh8*__q-MLOx5nKZg!}z`h@_{PXTI{NMd=(~s@`|7n3&HbE3sFm_?slG5XOD)12B|GgRAP|sL?=YA#A@!uREN|x%OM)w)jCE-t?qh)@~ zz*9tr|0vER(&DMnF-2x>jQLDgxrKzt@FmX>9=P4Zx1ZZJ#uZ)twOYS0IDz?cF86sd zrC-EEd{HFG2#Q&XabU^g4lOSd^q|XNm3I+0a@_8^AA4RIGwD%$8ihZAtqMKv0I!SN z#hsb*Q#Wt7%Ub^g{fjjD#fW%CbaUz&CWRT(a@V*gs%5>d^Zbu-Um%xpEu>edP?s@r zctE**#|$3Yb4bC!-R=o#0}A>NjI89(7q#j=%ln&h-$%LHdUpWY-ASDXw%lhxOW0uh z<#zjBW*nbav$SRz1A!E#z1i-Xz2?0>8+Y1GJn0#jx!J8qDo3cgACBxgONGS1DGhqg#(5JM|}; z^z1@jJ1=+&`c?1-u<1#?+ob2IH%)+x5z z6$O|HLyY_@kT1bE(he_yz6sm{to-*vOE^|PS}Wa8`AN8i91e0p#atON>y-0oY9A$c zi50RgD&;tPre7gr_(=5&VKUUnaR5Fdo5&H|!+Hp011m={v;?a!YCpd-{XwhClCm?# zOE*yGI&a{rKzhMa9DGu$z13Mdp1P3l3gYd@H^TRF=$pVT!1BEtTEgz|{)nUSMG3e{ z+r<==j^Xe}F{l_U1;_;NgH#-*kbb#DqsXtwqG+yjRj3awKPgNGW@*g zxU^`jFY~@Gg>r`yJqR0%o!EKIp=;~pSBTsB2bH=-hE=D2cv%0DYZRX)|DJ~aC1?g# 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�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

    -nCTg730s7fI<-VP@(cuL5@1n7+i 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≠qh~)0g3STk|~I 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

    5VwTlDecQ+fpY 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 i++) sl->cdb_cmd_blk[i] = 0; @@ -952,7 +955,7 @@ static stlink_t* stlink_open(const int verbose) { libusb_set_debug(slsg->libusb_ctx, 3); - slsg->usb_handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, USB_ST_VID, USB_STLINK_PID); + slsg->usb_handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, STLINK_USB_VID_ST, STLINK_USB_PID_STLINK); if (slsg->usb_handle == NULL) { WLOG("Failed to find an stlink v1 by VID:PID\n"); libusb_close(slsg->usb_handle); @@ -1041,7 +1044,7 @@ stlink_t* stlink_v1_open_inner(const int verbose) { } stlink_version(sl); - if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { + if ((sl->version.st_vid != STLINK_USB_VID_ST) || (sl->version.stlink_pid != STLINK_USB_PID_STLINK)) { ELOG("WTF? successfully opened, but unable to read version details. BROKEN!\n"); return NULL; } @@ -1063,7 +1066,7 @@ stlink_t* stlink_v1_open_inner(const int verbose) { // re-query device info (and retest) stlink_version(sl); - if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { + if ((sl->version.st_vid != STLINK_USB_VID_ST) || (sl->version.stlink_pid != STLINK_USB_PID_STLINK)) { ELOG("WTF? successfully opened, but unable to read version details. BROKEN!\n"); return NULL; } diff --git a/src/usb.c b/src/usb.c index 9c04ec860..b30399835 100644 --- a/src/usb.c +++ b/src/usb.c @@ -761,7 +761,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 while (cnt--) { libusb_get_device_descriptor( list[cnt], &desc ); - if (desc.idVendor != USB_ST_VID) + if (desc.idVendor != STLINK_USB_VID_ST) continue; if (devBus && devAddr) { @@ -771,7 +771,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 } } - if ((desc.idProduct == USB_STLINK_32L_PID) || (desc.idProduct == USB_STLINK_NUCLEO_PID)) { + if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) || (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO)) { struct libusb_device_handle *handle; libusb_open(list[cnt], &handle); @@ -791,7 +791,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 continue; } - if (desc.idProduct == USB_STLINK_PID) { + if (desc.idProduct == STLINK_USB_PID_STLINK) { slu->protocoll = 1; break; } @@ -841,7 +841,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 // TODO - could use the scanning techniq from stm8 code here... slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; - if (desc.idProduct == USB_STLINK_NUCLEO_PID) { + if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) { slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; } else { slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; @@ -906,8 +906,8 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { break; } - if (desc.idProduct != USB_STLINK_32L_PID && - desc.idProduct != USB_STLINK_NUCLEO_PID) + if (desc.idProduct != STLINK_USB_PID_STLINK_32L && + desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO) continue; slcnt++; @@ -930,8 +930,8 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { break; } - if (desc.idProduct != USB_STLINK_32L_PID && - desc.idProduct != USB_STLINK_NUCLEO_PID) + if (desc.idProduct != STLINK_USB_PID_STLINK_32L && + desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO) continue; struct libusb_device_handle* handle; From 43cbf733800129fde1fc741e0bf5e11f3edfc86e Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 20 May 2016 23:29:11 +0200 Subject: [PATCH 0433/1435] Further Refactor stlink.h into correct places and files, create backend.h --- include/stlink.h | 67 +++++-------------------------------- include/stlink/backend.h | 33 ++++++++++++++++++ include/stlink/chipid.h | 2 +- include/stlink/reg.h | 7 ++++ src/chipid.c | 72 ++++++++++++++++++++-------------------- src/common.c | 68 ++++++++++++++++++------------------- src/flash_loader.c | 6 ++-- src/usb.c | 8 ++--- 8 files changed, 126 insertions(+), 137 deletions(-) create mode 100644 include/stlink/backend.h diff --git a/include/stlink.h b/include/stlink.h index 3b860052f..72eebb70f 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -51,30 +51,20 @@ extern "C" { /* cortex core ids */ // TODO clean this up... #define STM32VL_CORE_ID 0x1ba01477 -#define CORE_M3_R1 0x1BA00477 -#define CORE_M3_R2 0x4BA00477 -#define CORE_M4_R0 0x2BA01477 // Constant STM32 memory map figures #define STM32_FLASH_BASE 0x08000000 #define STM32_SRAM_BASE 0x20000000 - /* Cortex™-M3 Technical Reference Manual */ - /* Debug Halting Control and Status Register */ -#define DHCSR 0xe000edf0 -#define DCRSR 0xe000edf4 -#define DCRDR 0xe000edf8 -#define DBGKEY 0xa05f0000 - /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ #define C_BUF_LEN 32 - enum flash_type { - FLASH_TYPE_UNKNOWN = 0, - FLASH_TYPE_F0, - FLASH_TYPE_L0, - FLASH_TYPE_F4, - FLASH_TYPE_L4, + enum stlink_flash_type { + STLINK_FLASH_TYPE_UNKNOWN = 0, + STLINK_FLASH_TYPE_F0, + STLINK_FLASH_TYPE_L0, + STLINK_FLASH_TYPE_F4, + STLINK_FLASH_TYPE_L4 }; typedef struct { @@ -123,34 +113,7 @@ typedef struct flash_loader { typedef struct _stlink stlink_t; - typedef struct _stlink_backend { - void (*close) (stlink_t * sl); - int (*exit_debug_mode) (stlink_t * sl); - int (*enter_swd_mode) (stlink_t * sl); - int (*enter_jtag_mode) (stlink_t * stl); - int (*exit_dfu_mode) (stlink_t * stl); - int (*core_id) (stlink_t * stl); - int (*reset) (stlink_t * stl); - int (*jtag_reset) (stlink_t * stl, int value); - int (*run) (stlink_t * stl); - int (*status) (stlink_t * stl); - int (*version) (stlink_t *sl); - int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); - int (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); - int (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); - int (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); - int (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); - int (*read_all_regs) (stlink_t *sl, reg * regp); - int (*read_reg) (stlink_t *sl, int r_idx, reg * regp); - int (*read_all_unsupported_regs) (stlink_t *sl, reg *regp); - int (*read_unsupported_reg) (stlink_t *sl, int r_idx, reg *regp); - int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, reg *regp); - int (*write_reg) (stlink_t *sl, uint32_t reg, int idx); - int (*step) (stlink_t * stl); - int (*current_mode) (stlink_t * stl); - int (*force_debug) (stlink_t *sl); - int32_t (*target_voltage) (stlink_t *sl); - } stlink_backend_t; +#include "stlink/backend.h" struct _stlink { struct _stlink_backend *backend; @@ -171,20 +134,12 @@ typedef struct flash_loader { char serial[16]; int serial_size; -#define STM32_FLASH_PGSZ 1024 -#define STM32L_FLASH_PGSZ 256 - -#define STM32F4_FLASH_PGSZ 16384 -#define STM32F4_FLASH_SIZE (128 * 1024 * 8) - - enum flash_type flash_type; + enum stlink_flash_type flash_type; stm32_addr_t flash_base; size_t flash_size; size_t flash_pgsz; /* sram settings */ -#define STM32_SRAM_SIZE (8 * 1024) -#define STM32L_SRAM_SIZE (16 * 1024) stm32_addr_t sram_base; size_t sram_size; @@ -195,9 +150,6 @@ typedef struct flash_loader { struct stlink_version_ version; }; - //stlink_t* stlink_quirk_open(const char *dev_name, const int verbose); - - // delegated functions... int stlink_enter_swd_mode(stlink_t *sl); int stlink_enter_jtag_mode(stlink_t *sl); int stlink_exit_debug_mode(stlink_t *sl); @@ -225,8 +177,6 @@ typedef struct flash_loader { int stlink_force_debug(stlink_t *sl); int stlink_target_voltage(stlink_t *sl); - - // unprocessed int stlink_erase_flash_mass(stlink_t* sl); int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); @@ -249,7 +199,6 @@ typedef struct flash_loader { int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size); - int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size); int stlink_load_device_params(stlink_t *sl); #include "stlink/sg.h" diff --git a/include/stlink/backend.h b/include/stlink/backend.h new file mode 100644 index 000000000..20b1c7132 --- /dev/null +++ b/include/stlink/backend.h @@ -0,0 +1,33 @@ +#ifndef STLINK_BACKEND_H_ +#define STLINK_BACKEND_H_ + + typedef struct _stlink_backend { + void (*close) (stlink_t * sl); + int (*exit_debug_mode) (stlink_t * sl); + int (*enter_swd_mode) (stlink_t * sl); + int (*enter_jtag_mode) (stlink_t * stl); + int (*exit_dfu_mode) (stlink_t * stl); + int (*core_id) (stlink_t * stl); + int (*reset) (stlink_t * stl); + int (*jtag_reset) (stlink_t * stl, int value); + int (*run) (stlink_t * stl); + int (*status) (stlink_t * stl); + int (*version) (stlink_t *sl); + int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); + int (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); + int (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); + int (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); + int (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); + int (*read_all_regs) (stlink_t *sl, reg * regp); + int (*read_reg) (stlink_t *sl, int r_idx, reg * regp); + int (*read_all_unsupported_regs) (stlink_t *sl, reg *regp); + int (*read_unsupported_reg) (stlink_t *sl, int r_idx, reg *regp); + int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, reg *regp); + int (*write_reg) (stlink_t *sl, uint32_t reg, int idx); + int (*step) (stlink_t * stl); + int (*current_mode) (stlink_t * stl); + int (*force_debug) (stlink_t *sl); + int32_t (*target_voltage) (stlink_t *sl); + } stlink_backend_t; + +#endif /* STLINK_BACKEND_H_ */ diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 351bb5537..a5012e38f 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -61,7 +61,7 @@ enum stlink_stm32_chipids { struct stlink_chipid_params { uint32_t chip_id; char *description; - enum flash_type flash_type; + enum stlink_flash_type flash_type; uint32_t flash_size_reg; uint32_t flash_pagesize; uint32_t sram_size; diff --git a/include/stlink/reg.h b/include/stlink/reg.h index c6af166d3..917325fb6 100644 --- a/include/stlink/reg.h +++ b/include/stlink/reg.h @@ -5,4 +5,11 @@ #define STLINK_REG_CM3_FP_CTRL 0xE0002000 #define STLINK_REG_CM3_FP_COMP0 0xE0002008 +/* Cortex™-M3 Technical Reference Manual */ +/* Debug Halting Control and Status Register */ +#define STLINK_REG_DHCSR 0xe000edf0 +#define STLINK_REG_DHCSR_DBGKEY 0xa05f0000 +#define STLINK_REG_DCRSR 0xe000edf4 +#define STLINK_REG_DCRDR 0xe000edf8 + #endif /* STLINK_REG_H_ */ diff --git a/src/chipid.c b/src/chipid.c index 423fbcb1b..c3f1a9278 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -6,7 +6,7 @@ static const struct stlink_chipid_params devices[] = { //RM0385 and DS10916 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F7, .description = "F7 device", - .flash_type = FLASH_TYPE_F4, + .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1ff0f442, // section 41.2 .flash_pagesize = 0x800, // No flash pages .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 @@ -16,7 +16,7 @@ static const struct stlink_chipid_params devices[] = { { // table 2, PM0063 .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, .description = "F1 Medium-density device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, .sram_size = 0x5000, @@ -26,7 +26,7 @@ static const struct stlink_chipid_params devices[] = { { // table 1, PM0059 .chip_id = STLINK_CHIPID_STM32_F2, .description = "F2 device", - .flash_type = FLASH_TYPE_F4, + .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1fff7a22, /* As in RM0033 Rev 5*/ .flash_pagesize = 0x20000, .sram_size = 0x20000, @@ -36,7 +36,7 @@ static const struct stlink_chipid_params devices[] = { { // PM0063 .chip_id = STLINK_CHIPID_STM32_F1_LOW, .description = "F1 Low-density device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, .sram_size = 0x2800, @@ -46,7 +46,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_F4, .description = "F4 device", - .flash_type = FLASH_TYPE_F4, + .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ .flash_pagesize = 0x4000, .sram_size = 0x30000, @@ -56,7 +56,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_F4_DSI, .description = "F46x and F47x device", - .flash_type = FLASH_TYPE_F4, + .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ .flash_pagesize = 0x4000, .sram_size = 0x40000, @@ -66,7 +66,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_F4_HD, .description = "F42x and F43x device", - .flash_type = FLASH_TYPE_F4, + .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ .flash_pagesize = 0x4000, .sram_size = 0x40000, @@ -76,7 +76,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_F4_LP, .description = "F4 device (low power)", - .flash_type = FLASH_TYPE_F4, + .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, .sram_size = 0x10000, @@ -86,7 +86,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_F411RE, .description = "F4 device (low power) - stm32f411re", - .flash_type = FLASH_TYPE_F4, + .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, .sram_size = 0x20000, @@ -96,7 +96,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_F4_DE, .description = "F4 device (Dynamic Efficency)", - .flash_type = FLASH_TYPE_F4, + .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, .sram_size = 0x18000, @@ -106,7 +106,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_F1_HIGH, .description = "F1 High-density device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, .sram_size = 0x10000, @@ -118,7 +118,7 @@ static const struct stlink_chipid_params devices[] = { // not the sector write protection...) .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM, .description = "L1 Med-density device", - .flash_type = FLASH_TYPE_L0, + .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8004c, .flash_pagesize = 0x100, .sram_size = 0x4000, @@ -128,7 +128,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_L1_CAT2, .description = "L1 Cat.2 device", - .flash_type = FLASH_TYPE_L0, + .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8004c, .flash_pagesize = 0x100, .sram_size = 0x8000, @@ -138,7 +138,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM_PLUS, .description = "L1 Medium-Plus-density device", - .flash_type = FLASH_TYPE_L0, + .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, .flash_pagesize = 0x100, .sram_size = 0x8000,/*Not completely clear if there are some with 48K*/ @@ -148,7 +148,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_L1_HIGH, .description = "L1 High-density device", - .flash_type = FLASH_TYPE_L0, + .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, .flash_pagesize = 0x100, .sram_size = 0xC000, /*Not completely clear if there are some with 32K*/ @@ -158,7 +158,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_L152_RE, .description = "L152RE", - .flash_type = FLASH_TYPE_L0, + .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, .flash_pagesize = 0x100, .sram_size = 0x14000, /*Not completely clear if there are some with 32K*/ @@ -168,7 +168,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_F1_CONN, .description = "F1 Connectivity line device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, .sram_size = 0x10000, @@ -178,7 +178,7 @@ static const struct stlink_chipid_params devices[] = { {//Low and Medium density VL have same chipid. RM0041 25.6.1 .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, .description = "F1 Medium/Low-density Value Line device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, .sram_size = 0x2000,//0x1000 for low density devices @@ -189,7 +189,7 @@ static const struct stlink_chipid_params devices[] = { // STM32F446x family. Support based on DM00135183.pdf (RM0390) document. .chip_id = STLINK_CHIPID_STM32_F446, .description = "F446 device", - .flash_type = FLASH_TYPE_F4, + .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1fff7a22, .flash_pagesize = 0x20000, .sram_size = 0x20000, @@ -200,7 +200,7 @@ static const struct stlink_chipid_params devices[] = { // STM32F410 MCUs. Support based on DM00180366.pdf (RM0401) document. .chip_id = STLINK_CHIPID_STM32_F410, .description = "F410 device", - .flash_type = FLASH_TYPE_F4, + .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1fff7a22, .flash_pagesize = 0x4000, .sram_size = 0x8000, @@ -212,7 +212,7 @@ static const struct stlink_chipid_params devices[] = { // Support based on DM00043574.pdf (RM0316) document. .chip_id = STLINK_CHIPID_STM32_F3, .description = "F3 device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, .sram_size = 0xa000, @@ -224,7 +224,7 @@ static const struct stlink_chipid_params devices[] = { // Support based on 303 above (37x and 30x have same memory map) .chip_id = STLINK_CHIPID_STM32_F37x, .description = "F3 device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, .sram_size = 0xa000, @@ -234,7 +234,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_F1_VL_HIGH, .description = "F1 High-density value line device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, .sram_size = 0x8000, @@ -244,7 +244,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_F1_XL, .description = "F1 XL-density device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, .sram_size = 0x18000, @@ -256,7 +256,7 @@ static const struct stlink_chipid_params devices[] = { //RM0091 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F0_CAN, .description = "F07x device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x800, // Page sizes listed in Table 4 .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 @@ -268,7 +268,7 @@ static const struct stlink_chipid_params devices[] = { //RM0091 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F0, .description = "F0 device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 @@ -278,7 +278,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_F09X, .description = "F09X device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) @@ -290,7 +290,7 @@ static const struct stlink_chipid_params devices[] = { //RM0091 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F04, .description = "F04x device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 @@ -302,7 +302,7 @@ static const struct stlink_chipid_params devices[] = { //RM0091 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F0_SMALL, .description = "F0 small device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 @@ -313,7 +313,7 @@ static const struct stlink_chipid_params devices[] = { // STM32F30x .chip_id = STLINK_CHIPID_STM32_F3_SMALL, .description = "F3 small device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, .sram_size = 0xa000, @@ -325,7 +325,7 @@ static const struct stlink_chipid_params devices[] = { // RM0367,RM0377 documents was used to find these parameters .chip_id = STLINK_CHIPID_STM32_L0, .description = "L0x3 device", - .flash_type = FLASH_TYPE_L0, + .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, .sram_size = 0x2000, @@ -337,7 +337,7 @@ static const struct stlink_chipid_params devices[] = { // RM0367,RM0377 documents was used to find these parameters .chip_id = STLINK_CHIPID_STM32_L0_CAT5, .description = "L0x Category 5 device", - .flash_type = FLASH_TYPE_L0, + .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, .sram_size = 0x5000, @@ -349,7 +349,7 @@ static const struct stlink_chipid_params devices[] = { // RM0367,RM0377 documents was used to find these parameters .chip_id = STLINK_CHIPID_STM32_L0_CAT2, .description = "L0x Category 2 device", - .flash_type = FLASH_TYPE_L0, + .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, .sram_size = 0x2000, @@ -361,7 +361,7 @@ static const struct stlink_chipid_params devices[] = { // RM0364 document was used to find these parameters .chip_id = STLINK_CHIPID_STM32_F334, .description = "F334 device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, .sram_size = 0x3000, @@ -373,7 +373,7 @@ static const struct stlink_chipid_params devices[] = { // Support based on DM00043574.pdf (RM0316) document rev 5. .chip_id = STLINK_CHIPID_STM32_F303_HIGH, .description = "F303 high density device", - .flash_type = FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register .flash_pagesize = 0x800, // 4.2.1 Flash memory organization .sram_size = 0x10000, // 3.3 Embedded SRAM @@ -385,7 +385,7 @@ static const struct stlink_chipid_params devices[] = { // From RM0351. .chip_id = STLINK_CHIPID_STM32_L4, .description = "L4 device", - .flash_type = FLASH_TYPE_L4, + .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1671) .flash_pagesize = 0x800, // 2K (sec 3.2, page 78; also appears in sec 3.3.1 and tables 4-6 on pages 79-81) // SRAM1 is "up to" 96k in the standard Cortex-M memory map; diff --git a/src/common.c b/src/common.c index 493f1b90e..2899f298d 100644 --- a/src/common.c +++ b/src/common.c @@ -185,9 +185,9 @@ static inline uint32_t read_flash_obr(stlink_t *sl) { static inline uint32_t read_flash_cr(stlink_t *sl) { uint32_t reg, res; - if (sl->flash_type == FLASH_TYPE_F4) + if (sl->flash_type == STLINK_FLASH_TYPE_F4) reg = FLASH_F4_CR; - else if (sl->flash_type == FLASH_TYPE_L4) + else if (sl->flash_type == STLINK_FLASH_TYPE_L4) reg = STM32L4_FLASH_CR; else reg = FLASH_CR; @@ -204,9 +204,9 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ uint32_t cr_lock_shift, cr = read_flash_cr(sl); - if (sl->flash_type == FLASH_TYPE_F4) + if (sl->flash_type == STLINK_FLASH_TYPE_F4) cr_lock_shift = FLASH_F4_CR_LOCK; - else if (sl->flash_type == FLASH_TYPE_L4) + else if (sl->flash_type == STLINK_FLASH_TYPE_L4) cr_lock_shift = STM32L4_FLASH_CR_LOCK; else cr_lock_shift = FLASH_CR_LOCK; @@ -221,9 +221,9 @@ static void unlock_flash(stlink_t *sl) { an invalid sequence results in a definitive lock of the FPEC block until next reset. */ - if (sl->flash_type == FLASH_TYPE_F4) + if (sl->flash_type == STLINK_FLASH_TYPE_F4) key_reg = FLASH_F4_KEYR; - else if (sl->flash_type == FLASH_TYPE_L4) + else if (sl->flash_type == STLINK_FLASH_TYPE_L4) key_reg = STM32L4_FLASH_KEYR; else key_reg = FLASH_KEYR; @@ -249,10 +249,10 @@ static int unlock_flash_if(stlink_t *sl) { static void lock_flash(stlink_t *sl) { uint32_t cr_lock_shift, cr_reg, n; - if (sl->flash_type == FLASH_TYPE_F4) { + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_lock_shift = FLASH_F4_CR_LOCK; - } else if (sl->flash_type == FLASH_TYPE_L4) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; } else { @@ -270,10 +270,10 @@ static void set_flash_cr_pg(stlink_t *sl) { x = read_flash_cr(sl); - if (sl->flash_type == FLASH_TYPE_F4) { + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == FLASH_TYPE_L4) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; x &= ~STM32L4_FLASH_CR_OPBITS; x |= 1 << STM32L4_FLASH_CR_PG; @@ -288,9 +288,9 @@ static void set_flash_cr_pg(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { uint32_t cr_reg, n; - if (sl->flash_type == FLASH_TYPE_F4) + if (sl->flash_type == STLINK_FLASH_TYPE_F4) cr_reg = FLASH_F4_CR; - else if (sl->flash_type == FLASH_TYPE_L4) + else if (sl->flash_type == STLINK_FLASH_TYPE_L4) cr_reg = STM32L4_FLASH_CR; else cr_reg = FLASH_CR; @@ -312,10 +312,10 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { static void set_flash_cr_mer(stlink_t *sl) { uint32_t val, cr_reg, cr_mer; - if (sl->flash_type == FLASH_TYPE_F4) { + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_mer = 1 << FLASH_CR_MER; - } else if (sl->flash_type == FLASH_TYPE_L4) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); } else { @@ -331,10 +331,10 @@ static void set_flash_cr_mer(stlink_t *sl) { static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { uint32_t val, cr_reg, cr_mer; - if (sl->flash_type == FLASH_TYPE_F4) { + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_mer = 1 << FLASH_CR_MER; - } else if (sl->flash_type == FLASH_TYPE_L4) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); } else { @@ -350,10 +350,10 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { static void set_flash_cr_strt(stlink_t *sl) { uint32_t val, cr_reg, cr_strt; - if (sl->flash_type == FLASH_TYPE_F4) { + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_strt = 1 << FLASH_F4_CR_STRT; - } else if (sl->flash_type == FLASH_TYPE_L4) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_strt = 1 << STM32L4_FLASH_CR_STRT; } else { @@ -375,9 +375,9 @@ static inline uint32_t read_flash_acr(stlink_t *sl) { static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res, sr_reg; - if (sl->flash_type == FLASH_TYPE_F4) + if (sl->flash_type == STLINK_FLASH_TYPE_F4) sr_reg = FLASH_F4_SR; - else if (sl->flash_type == FLASH_TYPE_L4) + else if (sl->flash_type == STLINK_FLASH_TYPE_L4) sr_reg = STM32L4_FLASH_SR; else sr_reg = FLASH_SR; @@ -390,9 +390,9 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { static inline unsigned int is_flash_busy(stlink_t *sl) { uint32_t sr_busy_shift; - if (sl->flash_type == FLASH_TYPE_F4) + if (sl->flash_type == STLINK_FLASH_TYPE_F4) sr_busy_shift = FLASH_F4_SR_BSY; - else if (sl->flash_type == FLASH_TYPE_L4) + else if (sl->flash_type == STLINK_FLASH_TYPE_L4) sr_busy_shift = STM32L4_FLASH_SR_BSY; else sr_busy_shift = FLASH_SR_BSY; @@ -491,7 +491,7 @@ int stlink_exit_debug_mode(stlink_t *sl) { int ret; DLOG("*** stlink_exit_debug_mode ***\n"); - ret = stlink_write_debug32(sl, DHCSR, DBGKEY); + ret = stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); if (ret == -1) return ret; @@ -588,7 +588,7 @@ int stlink_load_device_params(stlink_t *sl) { return -1; } - if (params->flash_type == FLASH_TYPE_UNKNOWN) { + if (params->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { WLOG("Invalid flash type, please check device declaration\n"); return -1; } @@ -800,7 +800,7 @@ int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { DLOG("*** stlink_read_unsupported_reg\n"); DLOG(" (%d) ***\n", r_idx); - /* Convert to values used by DCRSR */ + /* Convert to values used by STLINK_REG_DCRSR */ if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ r_convert = 0x14; } else if (r_idx == 0x40) { /* FPSCR */ @@ -821,7 +821,7 @@ int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg *reg DLOG("*** stlink_write_unsupported_reg\n"); DLOG(" (%d) ***\n", r_idx); - /* Convert to values used by DCRSR */ + /* Convert to values used by STLINK_REG_DCRSR */ if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ r_convert = r_idx; /* The backend function handles this */ } else if (r_idx == 0x40) { /* FPSCR */ @@ -1237,7 +1237,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L4) { + if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_L4) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1283,7 +1283,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) #if DEBUG_FLASH fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); #endif - } else if (sl->flash_type == FLASH_TYPE_L0) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { uint32_t val; uint32_t flash_regs_base; @@ -1351,7 +1351,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->flash_type == FLASH_TYPE_F0) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_F0) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1383,7 +1383,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } int stlink_erase_flash_mass(stlink_t *sl) { - if (sl->flash_type == FLASH_TYPE_L0) { + if (sl->flash_type == STLINK_FLASH_TYPE_L0) { /* erase each page */ int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -1581,7 +1581,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t if (eraseonly) return 0; - if ((sl->flash_type == FLASH_TYPE_F4) || (sl->flash_type == FLASH_TYPE_L4)) { + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_L4)) { /* todo: check write operation */ ILOG("Starting Flash write for F2/F4/L4\n"); @@ -1641,7 +1641,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } //STM32F4END - else if (sl->flash_type == FLASH_TYPE_L0) { + else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { /* use fast word write. todo: half page. */ uint32_t val; uint32_t flash_regs_base; @@ -1716,7 +1716,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->flash_type == FLASH_TYPE_F0) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_F0) { ILOG("Starting Flash write for VL/F0/F3 core id\n"); /* flash loader initialization */ if (stlink_flash_loader_init(sl, &fl) == -1) { @@ -1774,7 +1774,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { return -1; } - if (sl->flash_type == FLASH_TYPE_L0) + if (sl->flash_type == STLINK_FLASH_TYPE_L0) erased_pattern = 0x00; else erased_pattern = 0xff; diff --git a/src/flash_loader.c b/src/flash_loader.c index 23f235b5b..eaba6d3c5 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -265,15 +265,15 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe return -1; } - if (sl->flash_type == FLASH_TYPE_F0) { + if (sl->flash_type == STLINK_FLASH_TYPE_F0) { count = size / sizeof(uint16_t); if (size % sizeof(uint16_t)) ++count; - } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L0) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_L0) { count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; - } else if (sl->flash_type == FLASH_TYPE_L4) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { count = size / sizeof(uint64_t); if (size % sizeof(uint64_t)) ++count; diff --git a/src/usb.c b/src/usb.c index b30399835..3a72035ab 100644 --- a/src/usb.c +++ b/src/usb.c @@ -567,11 +567,11 @@ int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { sl->q_buf[i] = 0; } - ret = _stlink_usb_write_mem32(sl, DCRSR, 4); + ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4); if (ret == -1) return ret; - _stlink_usb_read_mem32(sl, DCRDR, 4); + _stlink_usb_read_mem32(sl, STLINK_REG_DCRDR, 4); if (ret == -1) return ret; @@ -648,7 +648,7 @@ int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg write_uint32(sl->q_buf, val); - ret = _stlink_usb_write_mem32(sl, DCRDR, 4); + ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRDR, 4); if (ret == -1) return ret; @@ -657,7 +657,7 @@ int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg sl->q_buf[2] = 0x01; sl->q_buf[3] = 0; - return _stlink_usb_write_mem32(sl, DCRSR, 4); + return _stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4); } int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { From f6229cae508ac17799d87e4424e97f0e7818d1cc Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 21 May 2016 00:23:23 +0200 Subject: [PATCH 0434/1435] Fixup tests/usb.c to read from correct SRAM base, fixes #351 --- CMakeLists.txt | 2 ++ tests/{stlink_usb.c => usb.c} | 15 +++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) rename tests/{stlink_usb.c => usb.c} (93%) diff --git a/CMakeLists.txt b/CMakeLists.txt index efadb5c7f..d61a0aee3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,3 +129,5 @@ if(gtk_FOUND) install(FILES src/tools/gui/stlink-gui.ui DESTINATION ${INSTALLED_UI_DIR}) endif() + +add_subdirectory(tests) diff --git a/tests/stlink_usb.c b/tests/usb.c similarity index 93% rename from tests/stlink_usb.c rename to tests/usb.c index 787ac12ce..1ae6442c1 100644 --- a/tests/stlink_usb.c +++ b/tests/usb.c @@ -1,15 +1,14 @@ #include -#include "stlink-common.h" +#include +int main(int ac, char** av) +{ + (void)ac; + (void)av; -int main(int ac, char** av) { stlink_t* sl; reg regs; - /* unused */ - ac = ac; - av = av; - sl = stlink_open_usb(10, 1, NULL); if (sl != NULL) { printf("-- version\n"); @@ -36,13 +35,13 @@ int main(int ac, char** av) { printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); printf("-- read_sram\n"); - static const uint32_t sram_base = 0x8000000; + static const uint32_t sram_base = STM32_SRAM_BASE; uint32_t off; for (off = 0; off < 16; off += 4) stlink_read_mem32(sl, sram_base + off, 4); printf("FP_CTRL\n"); - stlink_read_mem32(sl, CM3_REG_FP_CTRL, 4); + stlink_read_mem32(sl, STLINK_REG_CM3_FP_CTRL, 4); // no idea what reg this is.. */ // stlink_read_mem32(sl, 0xe000ed90, 4); From 486cc10c7081b8c85e8b8a1c8f70a6f178768e0c Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 21 May 2016 00:28:14 +0200 Subject: [PATCH 0435/1435] Add forgotten tests/CMakeLists.txt --- src/go/main | Bin 2777276 -> 0 bytes tests/CMakeLists.txt | 9 +++++++++ 2 files changed, 9 insertions(+) delete mode 100755 src/go/main create mode 100644 tests/CMakeLists.txt diff --git a/src/go/main b/src/go/main deleted file mode 100755 index 25baad2edac802c6e79e95b5578c84591aa88783..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2777276 zcmeFad3;nw)<4_{L0cAY5FLXO3EFBvmc%ttqa6Xg(MFkZ3!8*Z!y-h|K}2vGIsw|I z9mW+$92p&z5mX+>iH>VRfPf6jG9Zd5ipy;p(ScD>M)Lc9Pu1eQ)IXRA}oeeb8Q4;|}rrL}Rn0_iT7>qPv$+R^2z!Il5I;LpV0h!KN|uNp99 zz;CYO)1-eHNq4Q>5KcKN88PC90i`!2Wm4q>%;ET_?}3}EE&kf+S0hGL`m07&#xthE zTineh@XFIv7TmjZQXaT7TmdGIkvrl;cq7WkPOKO^1&o{O+n4J8|5k3F=KMylH(-6nHtni~n%%LbtX0Z^Ve(CRg5dyMN>;l_eG4!e1+R zHUQk)$ri7KS223xBpYBVyu}(`yOYTkE*I{P(B9FN{wd=o-KJ|xg}1!Ci?sIz1xA*GF5FZNEdqfRF{i?<8gl)@_6<0 zmM+%jvt2V=cyT0Ra{`yu`PU$;w+^D`|?wU9T_xuO&g2$;3PhR$H=c4~SbHPnT zpWHs>_Z~bK8EFrTh`*lpJ+Azhi}n)#<##%%tLh;=`HpQ=zv;T}$)iV3?2G;*7FCs_ z1R0g=o!=)9|AE=KQ7lD#OYxV0(;4JWbM?Lcu1f#d+xz;)jhZrY%3Xc0oHFwEv3E|M zGNH0>$#vI^^Y^*ce$e-(u~RC?L5cP)R<8(F;Fde#rtLbEK0rGsj~YL^PjRBn$RPMR%cZq@2lyqIQzYnfg|j5NQ~C@1 z1om?E(D&po{v)540utoq=HlO6DbM65vpb&RUzzd~T#HYU+t&xFds|<_Rg-@sMvNId zs_M28u`pfz}JeyH->@bq1?iw&=$YSbk3WMwM6H+L)ij;~bG_U3eQZ0r9V@aTXv zgST$@8PeWoDOC8k?rR9vVgA|hMot+y>9(fh2PTGRC`^w9tppZ6%`Z5ju7Sp#MJgK zUC>k7d+Ch|-qIY;5!&m3S21#QD!i}0I7i^wP`;`<^QhnnGq-?W`!5x|`O_7c_EV1z z9(4~(q~iBTS+6Ag9{Kk0@Kmk8{Qg3LUnuYk1%9ExFBJHN0>4n;7Yh7BfnO-_3k80m zz%LZ|g#y1&;1>$~|D6I&XU;C`;%YjxT7Kuq?>zavSAOTq?|t&SKz{F+-v{OQVfkGs zzkiV5Me_Sc`CTl(Ps;C~<@Xu+T_V5F$?r1xeL;Sg%kN9_`?CDj%I~Z4`Er~Gb}-)-{yq5OU%zaPu*PWk;zem|Gr zFXh*g-`(=NM}GIp@3->1Pk#R`zu(L60sQ(R*_}poaTQc^3pf|yihkMD)Ktzu zbo3*pE@o;IQ`a)JhN(N4dW)%Qre0?1DW;xds*b6}OzmXqVW!d$v5d}V>P)6)Gu4l& zX-rLGY7$eknHs~?GfWL(iqX^PAf~o6btO|VrY>bF1HszpxlEnFR4!B9m^zKAK1`j+ z)TKRqOuWoji;wM@On)GDTyGxa`G z&oK2RQ;V4Tj;Z^Z%0Lu7I*+MNOx?p&4pV-ndNVbisY{tEV`?x{H!*cLQ$D61V(JQ} zUS_I*sdt&`!_*f{d6?o%ZS)kTPGu^SsSBAphNxLm)xcC8QyZA7W$II=mNE4$Q%^FL))uLSNHyhLH92Qg)wqdca!UGNoOAm5 z1)~dZJ@3N&i!M5M)CK3|jV>5dIA+Yb=bc|T>Z0>;Exf4kyz|ChbZ+74?Q)vHL9Vf8 zxWk!?F_UCQ`g`V?mlS6jbIwCU%~^X6;I(mcozbb)ni76c?OxGVIH^H2xRcm zWi5D(mHIqcX1Kp6#|-O2A)jZO8ES8asyzW@3lvSrfk+xPnXEC?&uvDszwdd1f(lsf zlaMJwGQ$&bU%1IGhk45RQ(=N;<)$D?UN{PB-!tE)_99&y2_6KI9Axi; zB?w1D_J4D(yXp>2^8M{Pp}FWtlALprM@#bY50T^~Qke7z)@PYbE8=9F|96Pw0&9yu z9W1@_0N^(GBK_RHkYZi8weA~8(hLYvs7>@Ib5W7L3)EV8o*=!^N(bB6=rZxE*oEvUq`}afkQxyiD1h@ zYi556VGhMEkG<@_%nYqE>%Yh_(_%tta8?1?%WYkW>0g2Yqq0O(oeg8g8_eJ}gDZ0z zLTzGiSs$H-Hr@$x=_V%OW6XJ%^#}KqDs*yfbaH`?5xJi)fl?k((v0`8Jd2|hZVzz* zcMl`a1Ldg>l*4Vz@bzx9a81=sgaXvrhc{4sZU7eoPe=pX5b{$M_&r(HBruXu3&AA8 zK?&Ba8YdXdr(Im#-&2u>29`E31?-VRQ|F+MN8`1%I~y%N$!;-GLk$r82BAPw`=_3d zwhO^?g}_32afm33!<0VY^$ZUS$m#s)}DQ;J-7aE8idR(v`F>;ZOvP>=JNllMI%o^ zi|Cie8bI&LRU!zq(rhrpCis6aT#`2O&ZwDBK7a>@3p}{&hyOzV$5vcfd>9^_ zYer^(U{KK^0}c%kzRqoR_^OTQGZ38m%qFuJKz_gUcxBPyWHANbMbhekiqV+Jqvxcrxz!3+qnL)7*w@L_1x6-}E} z@4oI3zHNN3+8)Y~g$}XT&G2|M0V?6YgJW&Nis9%?bX9^GQu)!CBQD!f^hYTP!M=z# z>x*_vn)gL%i+vHm2!%b+LSM9fuJyhc_hM^((RY&Si_%12)LnX%UD3r1z4QM>R~!W# z>#AR&D`rbqB+FyJWL<3*)>pNImG{!#=QJb~Fo-4`nrU^osI7PmS@VX8+XM3)JqaTJ ztnOu$&Pr3JU!IWOZlm^8s^?6j_I8)IAZ9#>OgfLeH;q?R1|)8G-CF3#A@9TLZTNPV z^Hl=AsWX_!VJ2sx*9H$90&=cmd#b!M%y1VPyuw&jCkU>xb#^(nz!f_HZT3MZE%uIX zmwgd@VAJ4hK>;Gs-srQ&c(B2Etj_GdZC;{bx`5<|%~1J~Xb)p>m;yG~GXQ#MM!YuM zU7um}+37VNTxC4gV0MogeLgHU9<1{kkFD}`Uxf$g5D-<$qnb1DHxvy6^;tXqu6Ltm z2LRl)2*GZtx+e3>RHZvPl%!o4ZHCVi&4g-7<;g%Z+}R9cj0jG;mvtxi3&Wm4hZIC4@dGbH)A*tMVfL9<}Cl1_R$g)0T`+f8di#T@IJ| zcwyJ@wWxy?;b8$4GRzp>Kq2!56f&bX;__++&TX)A0X_CiOYQwH;B#4K3j8%Ev;yCl zBZFAcfBk8S*#5!>KV?unZL>k!CO)80(l${SUgK_A8NNBosSFuOL;e<(Vdc(NmEnOu zx2_C_J=dBtJbhe?%J6cUF&L*0&EN_M;yy8JWoBrb8LY$ow=jXQTeRyGO6o*XFB83k z!JD*~ycL4&2X)G|9cwA0HL??!gmEt?2Pg51F~=9T|3^=6+ZX63G`E@=pprmynz!r> zG=1DE&8weko#qw-6D>OfFWjbRp6U#=M)VIb{0GthrHL+bk|jRDQ4qbQjMg3lM1Lef z^b~skP0>3qoZa{MuC7_Tz>w+C97c6}ya;EXq8?(TCJ(>I>u`2koztxzeu{^y+wSa$ zVLzNE&%2!wk@^64h)69Xe}}ToYfk}vvOCGExA>~+ZagklkJIJxv+{T#9>1m@Z_exr zPY_D%0<&>NfPfn72b#Luaew<%p96SLSg9+-OF6-%en3lIXr! zPkiih#h$|B)dQW6=iza53bYsAEJ}JaiEoPKP4;XpG?BAOC>Dg+?Wbg8R{O zC6*u)o1Zu081b(Z`H)FJFF-3nv`m`(6o-SXC_2C%>Y-Etp=DaXx#bw;X~4%-UI~G~ zD?t|YhN@Zex~;7{z$0bCTyN)D&pL)7f z7s;M_H&p^qWU!7F!SYNL#>s53Uh4pBu*NQr0=dZKMIP|=%z@aSP}K#@eE#_k2%QPx zvkB~J49}_gW0L8cwka_|>rG?=N?ldRI@~WWyyOi^*Q)f8B=9anzbi-3>t{$}H;O3q zZ%&|Sb~_QPy{OI%)#QonB062Y6%Tx2Z(g9NOyyY02cZB1&q=kJ;Ux?qnoXz6 zphN-v1w#c@5dMp_Y<)H6 z0557(;e>RK8B#bQ4e3=lAq^K$;e<4VS>c4V7iqys!i}JRS9B973R>#<7{rT>IoZOa zd-9SP89F{kglX)a_be zbr~+Kmxu8h!DPl>SzxubpIO%+V{~;~kBfo=9$6TZQL(lag_fXdxELy98)~4;@`~9M z;0xaq_j&`*8Sn4_FV|DIEfS{bx=3mp8Fe_Z0`6#plU)(;SiF65a*}BZ+Q;jRTv*0M;8M!(7|I}c|758&;%WX zd|*3v*5MnAddtk<3{Sbsn9~4k%+SYX_#C5lIHMD2Xj;{1M?;P3&h$IN&ByjX4k*pq^DTh*!i#`D zuMf&(k5T)w$1R=mpyz;KKHozDH)@BRY|h#hz$5ab8*^VQ-XPC~S|=HEFF?#WaPS0U z?jtCHb{RFNBjF7kg6kO~FgS-5W_Sn(!)g8t(WpZ|r#7nBnDk~yG46v*s3FbB&m@*IbH$#p)mn~#pEwI5`)vBqo?u@D_r*f8}@jhGEsSHudWca7Q>A^r&v zQ|YHs9Rfx?CysGilx&$RGewDN?+n@KfM!)bqB_kNde9Rfr6So+J)9WeK#r3X>9LEL zg_6YJDO|yLv~&Fs_CJdM`9G|zo0bL;5|_-ItUU!tCGI9nJb!M>Dk7?6CvR{lmjf0avwsgqOlqMsPB- zN4mxkePNxujp~~OzYMrefg%b4!<}(z~8LX_CDA; zA%63R)(DX`SURn-PD~-D=+oe|pToI*iXPRCHI^b9epzJI)Urz1FN^ECIMo7g2>ZLL ze2gc7b>b{F=rGv5{Ag>~O~=X`u#~XbB8?Ha(HT*vrdKMEv!pT*w1Nklnxdyb1?AU8 zH$qaZD~bsRcMYQ8PBN;G!`tW}{6O6qa}T1eur5Z;ORaL}2oQ*^r^cdmaeDgj1h|0& znC}SyB!uF+2U_o*zb5#CHfimT=ia)ugq7{=sct%JVZGtWfo5n}xYuJxo`Fu*Gp zKW7SRy#jcRhn-v|wQ`Y>s*8+Kz?DKYBxdMaa!i3NGU~yu##?xeqPFqg7j|PT4Cj1W zCRz*DD9<4gy*@Nz4d3IsSgvYu78|()_h#q~y%5S?%=EHeiL^|wbh1|>tufOq=3XwP zE(Pf@W<8wc{_6XdEVu3(nCfzJD;)Pa*z6UuI1ywyA7lv}JjJLkqh@>b090DH|75tL ze*iE$I^i5|!Qa}c{H=#MR-CnmjimOH#$hEI8_$1SCsijYzVH3hW3XZ2jt6;xWt#nK zmM(n9xF1txMl}~dl2MFmXeH#!UMKlB8*{Hx_YL}f&PD2eDepsDnwiAljbak3d7(*6 zV|Fo#dfu?w5-mGUnM5w<#MBQ=;%2PM5xqNDnZ$a&u}xwX&Cp^r27@bvsp06m*|NkK zaL*=kgsh>P;mN_IL$0{&WP&42uhEWqxEj7am30rUbM^Wb}w$p14asMidVBjT^8p-}}zO93FmSkV<60Bls zSq-KAnsS-H9Zf0^9%@s0J_mI(JY}JMSdRvF4@f;f!@kdx6c_r1zM=IAZ3XYTqig8$ zvV*=$;$znv1iOv>p(v9 zs#F?YE;SbZWXzV3a^XJXeom@a6(9$dkr`ett!IuP@8dasWrhP>#-&`n7vkJu;eF3)G8h!v0Y$9b#FeP8+Ep}INJeCPY4)?xo zp@?KTFBHk&N|TgG`Xw7Ywn%nGrGr>kHzU@Rs}f|uHgB z#&+QE_58Y6kT}P~2qxD9j>Xs?eIVf=glpd3q2^CuM-*8K9WThqQC7|Qw`;M1_l6slTmuA?G z3@`NDk21 z9Oi%*O5KTg3oEJMD$Z*}GsC+8x^yw@@SGX$$q-JKRY(*GjZXj}*Hi;oS;y%FHREqm zi*AX!z|K)0(*2DV~;qXR=5)2;tLYvLBb-KHpNc@2SXDK9n;Q-VO>!W&;`Y@_)UY}%YvA!JW zK8cjIT3=5`eNH`K)EqC4S?>=Xpf<{0ftfLkX&YpM>|3*kW!76AeT8*Ka1HB-bVc_w znguJJR&|LP(Tm|Dy`wjY)c8VJ?+~iY^o6d^GQ-O>*}0}19MyIo^5{mx?1Zz&u+q?X zYB+s!;->!VHu>9q;g0>~(Km22(o1?oOPbc2!LQncntWifY1&pXoeOi6$03HQPlync zVKyf?nM2GvOghu0V3!`DA8EpZO|a=ZL3FX{zQPSt?heJ2`SxSUHyNDW$~K!J*zfZ( zI-s8+wmZRvA_$5VZCNp@=dw#9*@OQ_N4eeq$^c~#R~AMY4o9%5O=Uh>4@}ELKQ*mj z0wJ9B_J|v7RZtR&(%B8YFBUliJt*0cD{he|f}O4UtNpoRy*5Q3 zhmhxQik^jwL*i`x>or54Amq`;42$|X0A^?-f1!G_ekYRnQ|z6?EO{gqWGv6@(a3w# zOgqSXGyi)v05qX0DiJ||^4xVfL%>GOpGYR;%`s}Ba&bj;rIFsBD-Ib{f!o~VnhF{J z#?2;E?GV(S7Yrd@+CAmZK`$+RQTNiQ zZ@{8S`C|9Q=5O2^oeJ{BDU`5}@W(g6AI~!8#6-eGPce$1^px_!8DkOs6ZiD6R3Kp` z=sJov($No5W0)h82sk(pdW5_P`@_}Z+!vHmpqqq6KLE`J8Kby*y(bIB9Pem_7;wl*TTFmz2W*XhzC32(OUo$chUUB$# zKvu-QnXHI1U5}d3PeBezXjpHc-JIH*(C}1H(NI)$PDz?&LK;)5uIxZ>M(07~Hjdbh zApSdMk2PlDRwwb{+BfE+10;+VIySmRIqENenHq)o%$M$p-iEhU=__qq(f!KFO~`}H z2R=hlNUSI2)KK^uFdTaa%Zp|mASmT&(Jqxt7W}yNu8!Htj0TOXi;Go-> zdyarSgjmbAm>rD?7&D#w$tB}Q1kFNGH!e0{3y){%0Rs~B3ipEHu zlg$tU9(aPxoSu}BHs;!V5ij@|ii1kSdgyiHfm&k!#I)W^cnQ1Amp;6l7JvBwUe2bW z11-4)AlOhQ=-T6K`f^mr*3-`@c)*1%K?mG3SkMxNrzd?ibaxr40ToZfz!tJ`eF8;G zqih_e*Ge-b_>sVd1lcXS;E+9=!QW zicW-E7cPaFMG6z-r3FMS)&fF0)6@NsB*q5z8JndC*Tl{cyvwr{eEd`58U44YOv^wrwCjTYs{IwLb=t33 zYa}~xLqf!%d)Y^Ln@OB3&n#wXNyK+!Ntw~!UUvUzyhfw?N5tY;Yk{>D6gIBlp4H40iO3Rxp$~sn$ zZ2nxZTSBNItkB>d*avYFDEhm4Qz37PftDSr1OF?wmnlKAJ^0qWleX4oSIo>&n6rLG z=H(u7mo;}JNk}&*+#e;v3#B22>#&eMlKsxL4s8d7TvovVXLh2zM74Y&n~Zx1^-K~O zvg8U67s=TU6QK|COd&AL`(-!ei50W7+6Zu@A+L-LsLGF`dRuFxWOb z78esB*n4iP5^qRT^e{RzdYQaLivC?epy-FsXtO4op+Q(_iGlwufuhgl(M4wH3fO3D zXy_3r+9;1;*^1rKlbcnZ$;w?)d2F*Ua)ma*to=Lj0_@tc%04~zM_4wjEufKx*0459 z4vCuB*<=kX8Zwx!Vnn!E z)WqGqWSj{Oa77Pd;A^LEK-!wV3wHBN%*%+0OR;aOP(+2qIN=dKMeVSGuTx6lg_-C@ z`9nuDF3?ML1)mg<|1+&WvN-yKYb?dhfy&}$VdOwJKxK>x6b=8BJ##t4Suqe49^af` zZTy)7I5Zf!VPX2A78VO>UV`p*S&!cWh7KZJ2Kuphf_|ehO)OQ%mSJu2LhFIg(9F}I zoNP<3u1W2kdb4V)xO!|6ab>emv9!p|6!1U{0jv0|-(s;g>rjeVVJDu1G&9q>d?l#| z?5vYed+Y&JnN*)KM@}6O{~E5fl4N?kx3*IPsytp8D@yGh0}}$Ov5A|*lcqCEOXhHU z0R@zJ4-(QTb#;cPAbQDcuyL_8w?eOw(`|k%K1hC)XC1)lCcugPP>L^v3aR2m!5=e>8at^G zHRI?FYatv?Bk7PK)C6eSDUfo;D-*zal=OSsX(mfxg}iaBmj0x$!m}e`RWYu% zX{;V~q(7lcJ>nC{%+*OQwH;4_Ktc|IYCE;p#+h10u z8ve>(kefz;LvXQY(W;4YZ-s${0G_w#H_tpq@uTva$&V?1vk$9Nz@lw4QvK##n9gQ& zhc+`_7nWfT7Ju2OIhCG$crbkj>}0Fyz*`y{B|rbtUT#w>T)zC|=uV=HY^0u`Pjb*Q*JFCh}@*MH;`xGaS zs8PA;Y!PqEf2!oM-IWAWUBKn8ir{H>2iSDB#b9Y1zEK_3uCr-927l%-u5&+XA)NHl zyP+6u#M}!HI3b=ig5v73v02uMXkrQiNiHOZq>-}rmPB?cZeVC%3^ zrnTgGqA2c_9;dM5#0M9NDv(vm_7DbhN#bi$)bS^yAMv&GRL8;BUZ3P^V^abZ=e}U; zEwD+rCC*tF#);|IpfYk0DC<-rs#7 z-tB*=`5nHuUcqZre}or-qW4s;<&sM|*y6`8MK!1=rx>#N!Md9T5=ly0r za-BR%@{ymHN6JUO3lNek-veBuqondwA9*8QC2DWUM}ARqh^HAxlKZ^iBfkzSBqAgd zJV!F3*P=7=93JjST$;JiW$|1E%+)5EExDYoa#1|X9_1?k!{I8o$3h<4Hs0=Vo7*5A zHxzTSct-^znz+05TyDZ3P%M-^seT(Cc61MZY~8Tca&3co-Hz!DhfA8`ABM>5GKJ2W z6LcLklx?Bv$uXFRHML)^m$yrlC+a_wbtAX!m?KcA^d%ivn|?|rb4;~C0$0r1*nat{ zEv@+Fg`E2fL!~1(tiSThbIg#_FK>H2goXCMnP0x{8Db5ysQhv>dxyCkc=;;{q{)9 zVFnP6{bnCTC%DqxV14&bRJ^(Q_=p<>PzGHM51D!r1_UGor|KQsRTJbXGT5wpQ=q8b zX0k4LQ>Hr=N1qia+P{g9p}F9a1XpII9L#m@pRw8WD~uJl5;wA%+d2);r0Q5LUOYqF zm5KPbz!`@j030y{4u%Gb7RsYS1P(NQ9Kxc?z+tO=`zgChC{af=;aNOa)xLxy6aJJ4 zBrw{4ue<~zk|R1D`q8T0492V{V@lW+wYN zS~ZFk?a80<=&Mrc{g}T9(&5Hz82wv>mD#_&JRI<#1{ba!&{HmJ;2BhYQWs#7!!o(t z1ZTl;+{DUc`jx=PWd({xZe)+NH$(0Cq&zeBJA3ho+j{az62S%)``FsJ361QE<~sQ^ z9+=k;Q`-NY_#S)8eF*l>1A;!xM^*U3W4OCXuaFBid5!y?M7|QHX7hYVv$4^O%v=tq zGUcx=2_5i-cKQnIXJ*s?uE*Z{3EO+fIuY!|$2@jZJzmb(H86ZrW=YeEfuWng;+ruw z+yp0VVC1G;bKG_>XjPK-VgC0ejjP~KV|~cpnU|KxV$IH|)rVD>n7Rob$}oceA>WVN zE=L5W;V7rwn3q9V{-9Aki*K4%qwI{8`D-y5-?*Bv%))PHmSD0Lbi|o1)f`4E$P7#l z3~eaE(w5*)fJ|3v;JCGfJTPrd38U3L=!ndY5(*A0EBtoGEB2(^&A!n25CtyB#E;v$ z4~1<~lKpH_GJ~e4-RIb}!~w0i){wxJ2=ha$5rM;Yld)JQ z>gBV>dbwc6dJs9Ml(m=f$Ml6h^Mz)Bm+%;hbOyM(uyJM^GjzalI!0ond4pNM3ojXq z+Qe`Y@dzCgdxW&{pD7gIOuAH_;G}jm%H2TLauCUAUyNAZR_o7pI{G4B<=2&j4*CkW z&Adp0i382Zc(mYvxAIa<(5?d8a@P1j<=G{XUMuZGRBEn7K@b?lW?*W+r;wtjU}Rk> z(5=hmg8E*x&X3pk1)LV^A-Ro?XL>EB9ik^9MV3$Sd!)bTfLc%dTe9%1J>>VqNKMDZ z!#6{4q2WlP;EHq=1u zrDlHbxs{%ebvARwr&Ih?&#F2ygKQPzB-mo$!`TJmg=Hg*uGfJBTCVsBym3@4xvTjs z91;{{P%@DZX8p)HXhV%vB3;+`!pHic_^|}ResdAC;f)zOkB^0&^}D$z@?GO9f-rlm zFA3Fg6SqHOU?gJ=mgYe4e0+4sYs}q6?6FW*79hOGo8T&RI=6iP9d{*I=C0HRS+l|n zt(N6J@$EIBICxp6c>$9H4lr*ye+rlpjJ<}B^9B~Knc0Swg89MV6hG=f{Gj6;?A%62 zqab(_LGUzmj-Hed(}QrT&-{Ri5R1e)s(QQ#FCqIEzY6HC;vQE2P=NR0c}ggjD51b{9~26i*0Y5o z3M+v~9=+zNHzMxQem>S8MY303%9yCctJysWieS&@3K#&99`0A}EWSgLFU;{sn%P+F zX5D7!*NA1UU~gf9Ee99i4Cl0y8Ct+LV+>osgKMx<$`y;jJ9yhVt^>OWeN(_*)UiBn zM#ZB|>@NL?8%M4A>(DQEBGt@ZLVpC5{`llrR61)9L;_T*mi?YwTE0l_tHL#lZ*a}Q zl?KPEI=%G_;59;m#FN%D0Nbctcqy8K?lP(^7%%naI=l%lVTVJess>o+VqqHy`FcCG zo=bwO^jWMPm~yfn#M>j+8H&jfDFJkjQT;1a6<$(+3Y^`{d+udlLX@BhfT|03MST1{ zE6sHgMF<%z&0ZsdX$7>MCnQOG_&G&0f{9vK?pcSJ)d)VpXUg1*-bB;{Oaf3@crBo? zX96egmNB1bVn8ofs${4<6PsiNuTp@Z`@uCk?4=pToL@;M2#XAcf5f1Y>umDqE#=rf zX4_$-#$s_n_I=UQB0J<)<35KlnT-MR7yoJHZp@{D?yqFP7s2c9u7RW1VhaXj;1lF4 zssFSyeF%ZQngtu{sYrcTi?)HcV3BQdo$uL+t6JLy)hGud&-VoI%#6%ec_nO!hzDe* zfXMm%%s0pvP74%W+(NrwX}PN*6X0H|h92>mqP2#-ShNhO+Brn!jC#L; z)yKkUvWDB1;d=CyP{NYygK{1-H)tKeJt<=5_JiM1s5a=Q$B8xnWrKFI?6w*v5 zY088&-Byz{*R@I-yR=Q6MY@&*fuy!p3Dgy{DI`!C31r6p00PZsBn9*lsiB<2^|rsl zoTYTO5@fO`hX%mkWu1GnLro8`uJ0q_-8Jfnv-M`at1&NR{S9xAEZ(t?>|n}V^x5gK zHu@-Lk+1oS5zB$A9K9S@Yu7QNC1LCy=j}h$EleLXB@E97iimDR68e?D;>bp6!?@US!*4oa(IkRlFHe_CL~nOtGopx*U43F z9#jHGUx$LVKwlyBqIjeP1Wdgb0rMsVtW*T-trbTSFjYDsV5*jcfJtqw3fSup02c^Y zDFw`{1dJMp$LLsnGDHJCA{RWok>*_aTeeki%SWIrm>-wvlmYf?&Ho^-$mhIh2f(B9 z%)}$B8Yllpo3PE(;hQm;;-5W7N=f{M;T1Uj=$m_vBbVhc3AJ~3H!l3Ala+x%R#7<~ zj?R9e9&=qBbs@u$qzrG2SIx~~bKyS!=(^`}9B$~p7&(_e<5;8G4mDf%lz|n)s2Z+b z_Ba5w{-d8{5_~Qkp)3hssFd}>3bd*al#92DrQI;Enb`irSV5wF@OSEzzXR&h->G9; zA>kWvRk~*zpP=Vk{OPD>ZnJt+%j33E=#7h(Eu{=MBY$3o-PX( zP8*T$q!}1!sIiO8pM^rfqH+2HkYYQJs=DE34V`Nh4l}K)zEfxsYi35`258j+BCsq zpU8S*clPvA7`U0l9*tooO|^C=mPvoWme-;B25Wj6Wdy695qH6|bKU6q?ZE}jdofQ{{`j+3%{%L6LmS5!@pFC2|zKi$*` zkQqjXC}xt62r^4~lacIa?pJePxqO}1k)R?NqeRF9$>%Bm=RUOs&?KIMF9Zhtsga(w zawiI-V@ky-Giojrskhy#Pn5%RiaflaVs2-bbtk5ZS!)F*%q1~R5}^->ZaG#YgCnkY z2a0Ze6MEICc^kRtya;u83>utic5 z0kjDnsFNzX&}DX^hge9Tx}~y8HWaF00mQ1rZ5#$x9gicuc$?#-2&5{RB6Jj?Uatk0 znIYSo{3b%wd_Y9ALDYlyaF;k6XGT(}#vM&&)3{ZtLz_m`m$(qj7G9cF z!MC$k5|0K&lyWu-t246O9-}u)vrfW-r6!-@b(U2=j2^01%|l572nj4a65#BiIa~xN zyr}oG<0g~xQOBC^KAq;w-sR3xwnv5{*6r{ut!>C6-?~s*avqAY_yS%d+2hxC#H}jG z#uF!)6nh`NI2E?bMr>aj>cDm+GYTLLL4Y3#=SDHXt>OH4>{zip#F?RAG`82QgD($j z+F5m{BI-0EA5h4zKa-Mjc;w@nW<#k1^PX0*U?Fc60D;NYTNe_AKjD3}R~&_(?zsMk zsxhMAQ8y{K;gqAPT-Z6wy53oNwzV>c-KGO()>dpfu<}{o8+0f^Q`HkXm>BO2J-Wob zFgI{DnOSi-#0Lb5$TMsR91b6iVHmY06e|+39~+EUK*#)5HUK)?ODC!hH`e*YCz4%r ztAn$lFJ0C-*#F8pR1rlemJl|vI`S>fb#WGhcjvPH-9r^qc&cJHnr`bRvSl%JoRz@G`g#{Zb?5qmvo6K4@gO%ILRFnpo#U$=xI{}`u*k@K; z>64X^C6_O7aCr7#PuI)|3IT7*G>DK11YFk5*O5-5hcOojjTk?#EL)<`B2i!uw-uR# zob(N&leOhlF|exm^Sq?z!{g7trU|BG3Y-D)=g-mRw2_gOHMtfY&hM-x6nvt;C0_js zsif8~YSoUT6fw84obBL2EtC`fQ>twtQq&HMdBxiWxbh#S?Lb420YN7-5)VZGhS0&= zqO=-Uka01-l?$BXrgaMc{?yZ=wq>9pXTM8C4YP1ohvUI!pnDF4Eq!KU?Ia#S(lF;9 zdyZWs#X&|Dy|uR}Iac5iG1w&{%*t{J6Zitaa{_=v0C+lhPEg^~%))h*R|_qnv~Z)k!VNL+Sto*)1F12TEBl8y-WR>=w0V{kp9Cc&Xp^zE{vN8#{J2uOO8P$ z)~o-bPNdC5|an;vN9g9o`3ydBVp&9iYx;ji5!9o9&Ix$ubr z$j3gT6XLuP@GU+KfEaWA-t)~_Up7gEelO>iv5*7%y8Gg!ce6g)*9?Bzjq}d+u~W_Z z-KUzfK0|N`dDdX!5jb7jlQGHz-7D__$OhEFqW}x#;g8)bN8#Z*JUsPQBe#B^F$~J! zC)dmYJRNA`*CnA1#lf9vzT;NyGmV~G_8Fy{_8Eg$AbZEMiq0;i>-l0U%D#h_fKv(> zorFMG;lX#CV(YD8`!QG7-nvm;4!wjf`O(=WDfC#(7NSpl2yH{3Xokanj-3C2R>D$B zXbT<;;U?)btwWe~BBz2ss8mUBGknstzako8ytu)awn;oFoGY;bd*8Fo{0-*c-`_O# z!1MRL7et0N9Cy^ma?E^4TD*MlKt|;dqqd8gk24`Y=6>jnI4A;V0pVbM5P6r|%-_%B z_?x778jif=(@bW6t@xyG?^>{@U^jrHPgZm@-+Z+5hYxpr>Ws7TWJ}afT@^gwzO#S0 zM|g)+fW-t>hJbGfpMz)hyMWG-A#vsokTUNa$=Tg-Co_Ma`MRU_56$|9*65>95UgZ_4tRNO-QK}qOGGkl3J|2^|{2Or>E2KJ4E5z#lFG%t&7gXj73-!)%% zk@JNodKFIC7K6nWE z2g&i2h7Y65I8-Zm5mMYw`AL*M*aHY7R`q$u2#4uYHzx9XDk<`v4dVv+E@RxL0xKm3 zB_DHRR7+?9a$imb3zIXLtH7||?E)ySvJcyX2Vs)t%6zU~|L9hs?l)jd14XXq#m{+w zhBZ_SYc&pk!`0f`szSh6^st7}PtOShdGW_4z+L6s{vd(#>N0_oCvXOcjwy!+E5OK| z{6tIm8nEjsF6$^%*&$+7_)TZ9BwNT0(pJib%%V{FOw22N^o`V6b%?K%!FWqwHdInan@h?m-4(B(6+ z{w#)22Kv%|b`GCCo47v}_wp5A5Nq;7idbw1z_F9jEGSz{aa&UgXsGpiEz#8l(Sy_% z2-+~O+uAS#ptwqnOAeOcidAp9i5*-2gV$8?UOUWPge=zfWniw=@t9l+|1f+6{t?Px z6hB;ZM?R3fVw>*Sag~HCZVD}f3_=v~KYNaZ8Evm&1pq~P#bN|9^Fa;7lMI9z8Javj zQ1rL}InG3*K;BG{*KY65yM??1@Z}?X*VEC`M!tx^>%0phW&OAmEo7jGK0!+R&TA{} zDl z9cm`UD*z@c>z&>0tThaiGOI6K?8Qk4{BTtbzmE)*%v9i`1^7W|2b35k!1q#BBxe=i zlC_5OcFYRkrVacJRl*CM!lNgqvXQ(YvU*<&1$h+k+a-sEVmAm-f?n}m#vb%Bs|tl3KL@J68y=1 z&&2(3=-$C+w6LCPz1i3R#R&SZ3I6Ccf<@Gln|GO5KSg1S@Tf&Iv_qW8ZQ6-s@h$t| zL;?iCoOEz(XV-pX@Hpy&_JP>;azF6RF3fPDTT`tPvAP&en0 z#06FeV|2hfAYhA|z({+IY zDd1y)SMbPsQdP6`aYw0+EY$^5`3e0PO~-sX&NqQhU5?r26n*+Ts)XPkFDWnkZ7rjE zn5YSD7}V@M56#$>!I>$F^R(+7E$hxIpJ~e~0fH@qJP!rHYoJqQl-t!4F7F`RN9$NX zZ(MDhp27Sunnvw)#~HP2wbY2nY}6uyF+Nxd-2or2-t7JX%=+zP;MJ`+!y~XYf=(n4 zJ0kb)_7|$W8~2*sSKArC+OgVnE4tnjWHudn4GHsYtIhC`yRRM9Rz5ETaj zmeFm}TSOj#x5eeC`E-(R#EtK`>*RWbtF#%P? zR0Uioj0*5c#ZjQQ#cx)tp0JxB71G$K3Q>G>q9N@>u@K(4#Ew-LXpI;YX+tA>-XvZ4Zq4s*21q> zr}FEjRDMliRxF3+p^(4PoO+?A<;P|Uv!-n|YWpZQo%VmvrhVdUn%xqcUi-gd)7KX1 zJ{!Ex*=JaQSq@qF|BhFcj`_dlRpQNsquz$-cVyVjpK69(rx0!nx4+Y4R)4gYfY0Q_d? zXJO)NQ^`FN9`NnU|?v2oGlILeL?FSqvtyq_z zsiB7T8uzc_6YAI>6FRmV^$t$<(>k`B*0J4^b?gbmMs#c%Qw|;5jXL(y1oIlN3~5EZ zK2HN*28tnWOg?2I&Z_uGg=o|q=(iS>>5!I{X>N-eRj8`fYEE3OUTM^h7mXTMrsLzv zG;Rv0M~5WzC=@ZOp#FzOEmsWMiNm6EKhX^O6*=?k=u?V8uOWlB+)C@kKY}N@1j^<{ z=XeTXc75J@NTR2E7Lz)dVO@?Z4XRZ&9M&n^p2|~CA|hnZkTV@)y!!Sy+hell7?Yf) z-(SdFEjdj$f5)ac)ijp^{b{vhC~^|2u&(mvd`e+OnsMtjzH#~9OsJ<4i zaG>a=$KdDUt39|W!A>`fUrJJCs)++uB~xOAyT{-Jpk@)In7?kGKwg zGOZ0*$3j{4+6a_{u^1j<3~4((A%=kqlzHA=Qop;P|GXPKeTxIwzjHi~iiPh|68aGC zOWy%Jc9nw$a0*5MfNRTx5;`M@gXSO`JScyFjIrt5oX=FGS2~@W{so(j>XjUxicJ2M zDg6pQK-C@jUzZ>ZHD0~NA{u#H0&fC7@iZQ)Nu-The4^cW@muV0LPM2f#@Te;pGv9k zjW@CWOZXtG9X`n3M4@sm|HkYqAsz8;CEylK9f!+>ir{kD-&&7C#g>G-aCotf1GbjB z?JeqQbeoLVp5@Jv#%tG<#>Z<$5C>F2gg_9Z2FKN-6K#G~>}7p9k`Ki*v*+>Qs@b_@ z?17sAi{b|CO4k}cS=K+W5tb}GNSTW*RE?@*WfZKBsZFLRvR81olALJ^mr`PCii>QY zv0uFM@C0xl#(w<-MKYum7voeWwIOg9D0*d~u)ZvR3bm)3iaO&kMV&cenga8iGB#Vo zgl?n3`&t_5V;pa^g4rNX1ZH_ES_&DPK(E>avQ~{Jz#KFcm8odUJnFLplfzjab;-RyN*K76b(&*oy%kf&yooN&G;0}BWGP#ZUFK}>cHxQ6T zS6J_22y82d=u8as)R?&(nc-|-!ZM*1(Jl;1@83q9YweLsLR=Kd?7>Bz-G@mgQN$;8 ze38(&WXv-DfX;d;rajc~p$n$Cz zcfTi-Yf{UhJk3;_cP$apexz)};cDRS7=v#^SW_FmUb-u(_Tpj+(iV`BGOaC$f9O3t zdbe3S!s+O}oXU}C@?V@eya_`tm~;Z&k=tf`q5Q6E6V zz@0cjea009PZ<38%~VRy$A?j*h2TWU2b*fE3fwacrY1qi*tQhnd`yQ!s(4c7U}UL4 zvvIz3la@cukl4Z(_w{ofVsj`}A;PvyO>W{cG$WHKeh!0kn9^p6*} zBchDR0jBsQB;WutN&$(zMIemXa6aHX)|E>YRtXnxVzz7b0CuccAn03Od798U(dVJ; ztn2iCJ~^xRPco)ypU1aHK*OU1Rn7X!GTybjP{DzMkb zB8n&yD0*1EU#{L`bjSCP;g0kxfY_8D2UiwfJwa}Ks|v>`j8P?UC>d4&dvo{(`ndTN z;QOLI>G)yV3E76|Ngi$)82*-?pQ#>92#bJOxs8Y@L7}dWOU`rLSAp&e5s^!|6c%Do6SX$o`DFl7X`bTRKoECJG;p@ zt+-DRWTr1`)avoA>|hKs4!?+mLm(U+*Bxe_j*b-Y|JKeNT7`_26HRbz^;w9C#zAS@COH?l#topD|c~ zhM1ufJ(dh(gWRc_aVB{!wgo%e@%@6>f>62~TY*8{a5@O-YX7k-`X2oO%niPYD`}+M ziAT%WwdfHEs`0%#cIXN{qehpbO7hsCp_riInFMmUMzOFb*pM`NGPeTW~=i z>4Q3{6?(?A$f-eC0jRP#V)w_!vwR1!q-2pLxh0X!wQ?6gV6RsKo3LjXf9n1D->LEE zJQv%ghmzq5S>%w4#Dhv`|M*LI!y=gW10K4g(okpDc;~^PvmbyHOPL$8bc+`^fU72g zDdspbQP>ua#{#K-II<8j#xm#A9pO`G`4YM#XV@UwIA||bA#b3{?S1?x4WzZ1!+u_j z4IOag-17=0{haSxi`P60Un&o+r!~FWY+9QV4PQhcFsPV7QUUP-Q^t|7Pq#2YvrSB^ z45Wt2ry=O9>1g+0lw~YNMZ1lfEI~+Czv(531>9)@pGpqpcOsI4#rqr$DlBXgb>%Qp zD^A@N_Kx8RC6Ix>pdCh^oUaT%N$J;3MLSDP_=U*f!_X|a>sTzFFlx8s(UoPgd<3EA zlF$mA4kC|?TD+aa*vSqbmK4w;1y{LYm1I##17V;6UZrMofhS6>C=ol~8FyDlda)B_ ze_=IOaZ;H~!&tdbBH!nj8cyU(Gpe@CcEHiW|{~?5tWaEKPgm%%vvg*3EuD0!sH>_-6Zu%&C5V@9RQCsw6SVylCN1&0 zjZuB3^noIoqT#^s3AR8fQ_JC0plHy&Vy89=**k;4;+JNxB#v#$9fn= zXId{=AQ@#vT0*m$MK;J`7MZ%lSBbf!Gu~C~*;@le9R)dz-LNVt(O!l7pg_^yxooh) zeXCeDXUFx93Se5%#@ufhpYqVXJ{M$dR{cqZD12j(P`~~#wHX4l?BFJ$+jX%MOSu9G7@=a_k&bgHOHgQ=m4odw!_-J zM$p_P7ofRO4N*_WMM=Jhh%B7j7N;0?j7Vr{8x=m6ls84|F<8aK-m|=Hj}FJ>e^q=o z$GXSQgJ%$R?z&C*2Z{CN+MkC{SgJ>l9M$go!7_gW>VfWYO<;JX}@f^q-!Kd3;DtJCNU-~=!1$y=9>323_V zq9)3Zn}@t0A5QXmqy{J%HUFfTaRG!V&9`}n_c?*0JJoynrY(mLjouu*#M@Hk&C};B z&xIr5rkfIzdH0<4juy)ToIY}pri_r0nFFrNd|@xXs{#y8VhvR%nIQ~O394}bD}XBw zm&_L#ptTdk%QA0b#egD*-^AWbUYOC-ejB}+ddU^N7?)%h@z{8l6Y&miEDx%;^5>v) z55K;ACSn=rBrK9MYOe+nmE&V~PUR3K;OreL3|V9s(=HIW8)gr-(kct>4uE!|_15mHCl1YCp@=<3OKTdnDWh`Ku!gi3~t& zH^>cFnSMxNS;N~foiHpRRDmOkEFaT;H*2C1Jb}O!|AFgDy|#zCTp-!uIql4S?6#db zem>Nw@xidRfC|<`*r?o%iM#g_yY1-OVj|CYrF=|0kF2JEcb)dG2si4L*@0Y1z zK|SgPA0Lzz7k&gr>{Yz)g89qnebj&2hP_cCIWVkGdM+QG-LGGX>0JVN!q`T&d?FtB z@=+Y_I#O>jo(LSgW!kQX%RY2;9NNf>H=wz=fABLS&&sV1>dBH-^&N3LL-1Y>HyDes zUBa4&sRPiNf`Sy8Ay48(Zsn~GU!*CNUREfj?ZquVYdhZ)ka{`T1A+O)SsC}~Y}nJK z-rFGO4+h)Cziym}GhtgWJg#-(+h~L|Z4|j`_-%ONx(3zh@KZVzQdR%M^8r~hX%RF; zBT*~0z`4(J=&g6Ehll4dE!>TvkZdDljq!(!lXFk4-sz_Hs>`tH0-Ld9UHCWfI&@rIs473yusw~Fg{NSh4Qdc_l#hg9o2kQs`U9cEe zC~4a(hf$xew#d*)(v>=Gu97i)IE*&esP%i!PC(Q8-?Z`9w5IYms(+^{Qr`Xr92Wul zLSjKh6;IQ5LGyJrNGGcC(T`D>Cp`X`j2p0uahIy5k@sSbkBjnL!1}!f-g&?hpI65W zA7h`G;lt7ou*q@C#{tha$b>|*ttO}%Q}4{&v8kjsdm4RS0*C!074LoYZyv4l!%fr zY7?zl)bnz-aav*-dIIO*#kPQY=T+G(U{vqd@GI1iVu#$?-`@Fdrda6b`7m@2*hYpH zl>}PO{C;Ri+nc@}p7AQ?ufoyK61T+hxiaR&NDK-PWuW=Q9uaxy0|HSG%A@NrF=LW! zFhOqXL-8?G*JCplzQqAztEmMk1p5E=O!PzlqhX@5I1|ki zR2lEv@oo!Dq+WBf0_r~(d4-7*MoE~c)b1Dzz?FGYOa$}8FuG`Y?qx{ed;}&cZHbAN z-`y$`$qa2O69t$*&P2JIiQxSxCMwlDL*#{t2I&WbqI2kA$C>CMpMxcuF%d+!852D< z&{4v{MAtYVwZ=psp@z3udWKANy#t|#K@+%z8Y<+zM1e+? zS`J8OTCcxPdkJ2mn&sgtRq0sr0I$$g!O1Xci2cO|pFE#1^#Z`pQ5-_jtBSPFlbSO5 zOlr!q{`3)Q3UW*1MTGgc=JR(`vEhXNuI-y5ksHSsO(4GQKNl!j4c5P=1IpWR%v2(| z{Z|Wq_&!cCH#K4jX{4CFEb3ZdCn1eSXR+m(*6J@w6umDH-9n^iv%1B}@KesGzI?af zhV!X!WM-aEO(;-T=ZJfa!zkhn6nCXcPF7YT8syPL$PIc*ZYT;oNvhA7BkL5|r&vGz zMwV(*bS8zs47zMCm3;5Y!r=-d%f_ZrejSfD&Xdefu;>#A;~i z7Wl!K12mB@aXvT#+|^HumdjG=Yawp*I5xhXd&!xp>tnZK{+i8&Vk*V-3%rSE*gzhM zT?Z<;E6?V>&-%|0hQ-0pa5}gr5odUkHW;jy*wd&Oh>&IpM{`@s`sd{!z{n|jZKZ1s z2qOFhNg!A9EGzED)WK~365$_AlQIbBhDrVTMsBqE;7eqoCEYA~RNzPsIvKM0_9 z`501x`oLUvvnA-2lk^O>6vSD!-M66`vi5uxPKv^431=%^CE*B=_)BrhS;fW}XS#Jx zj0#tnX$W2SiKw9g5IH5Sp8evU?hr9nL8HrKYK6 z1U2D?fy&TxEU4Ha69M0W+~B7^m6>Bi_JBdK2PgQGyAqQ}r#)sQ~bXRs&h}p9)HGgG8aQqhDP5B&$YrFl^rAdhA zGUS`vyh&7wblFnzKKM`u1XdyH$JlBZTVNv!=Hz05RSH{)(6xXn$o}&r%~y+7#`!8K zry@Id&2Rk77HnVWJu~fn?6j~cZPai9lNs)&s9hy97B~%~Z`pPAn%ULLtFY0Bp0Bqko~=R;y^x&1LZ=*=qkwN%#)v zpm$5cC8C3(SP!joCDvt2#-Bxl9>jWWn>Xi_0I{j=`C_eATL1)@J zz`{n6__CQBY*znNSTkAQBR}l^dGrVNR=o;dyknx~#mp6l=S8kp$4L!P1qC$GT)xOJ z3lIayzdt z<3-KWc9lsIqtpQW)mOj;h=7xYNQ{34I^w@6qS&ErueBpSQP29RwHV(go~xs=0?RBiVm; z?ndhd?PTqHk2c;u*T>cYzQVVBI`44fLow)Eok6+JKXJ%Ph z7vVYBn4#(r=nkzMhdTjo9?+;ho!pGwf1*`o;~yP5b_v#iJiA@50XgI)q<9l_*^gN- zp0cbG-&IIqk|{?PG1yQ>+E89~LJ@JlPas_5#lCcCPfiCciyu3-MxY)L>=^HwI-E8H zNc-{iyF{h_B2<{Xbmd#wZ;v3!RZ^i|Z;tOjwy_Tr^TCxHzgmVxZ7?s0g-y$>@h__T z=manu7==8?LDMPvx)pq6(;(ar7FL~n6dss4VQr_h`ZsF^yxS&R|HBud&EY6VhxM^` zq3z?g{|gp5w7$mt`De@@;QscHy11Y>dYQ9+ zCIBO7a(O_cYfL=q$#0Q6=j(G2RR`0f{53&h#UW6$NIeQ*A9;q2SB2}0n(n-TlUt66 zymY`$M6wiCMPUSXjD%_NvsruQ&R0&%$l&!Pwhsy32#cm z_}b1JvXBHu0j+pYMgHs%C>mV@iAQM+SwIftn4zY)vaGKn^o>9wF47GMXxS?ywWAm9 zp|epPkq*G>Xy80eaMs_e!?zU+$z?|MXlB78BVTBfI1<N?889mtMm*t}nPz0LP(cs6CYsOruWw8Wf1i2-!Y z)2*mQ^o=Yq(Q49~v6RxT4)L@XU2VHqLy~X*Sc4@COhqBBPslzz^CjexPT>G$kklOA z4B9|tyvmC!`Y)QR{kvIOgWrUM?vJFw zcaX@fY49($XbpbpC4`i!!5?K=hcY#)19;L*gFj(I`Ccfb%q`i#kM`@OZz1lw43xY}E8P+LdMd7s-YifKUxffQ zxhnff8gwY=0It?DxMc`(wTZfT_ecBgE=028OzS@h7;P`twEi$t(YBn#bMl56_R9Vv ztU-GbCZ6>7a^MWTsZ{s;0rJ=;=1`MUpK1krF1wN8Pd6}SSB{y%>PU=usZQiYJqM}v>5O3(G3*@ zfv$90P1+GCk1fTE2dv*NA+e$lBcNxUQ4Uw;GNj_JO!M*U)PWeg=8}#D(mo`_E#Y#? zOqbUr}I(+BVDc}&+Vm00h+MW*9b^3?WzHZb3ps8w3DGQW2 z)2tE=hTsHiY3o@f>gDQaAbB}ox7Za`-yNna3QGABP*@xjBq@YD_y3S~F7QWN zNKo)Z1qsN}sIdki0*W=UqCwD})KIZ%8}C@F4T_2qE>_gwNr2O16kFS>)mC3`D7M;q zzm^yvD58Q|QL2Je-9uFH4qDCs`%t)p4lZu3Rcx^s)`Rr z9@e;JnbiJAmpTjVErFMcP`c2^;U0e@MRoywSPiz7>FViW9rH&DuA=mtqd3ixjMD`# zvSaQyJ7BUO4O0%Oy}*$`X9!BJ5DhZvvCv6=J{bI@05XW&T<+0b3a%3~HYBv>theRW$V`c+TV2_odMlEhY*f3@GkSy{HM&`Z3m5v=a@SbHa0=9QJTX^T9i!x zzJ9y+sZqBcNvTvwMOj!{#tTCc4 zy}v)`)h()+vV(@)8l~9d!N z+v|4>-*Hg@8ak8^L6+FI8=NxI(R_FR2VO{5sWP)6y6J;ePo};Pj}(+WIZ}oH!u5>) ze%D7%2@t|WAq8f`61`!}EtZUDiZ7~JR02Z6+qgAV)}rmSzs*H$&t+$qYYQ}>s`kI| z;THGBsbJ+}!%C<5{@?A#UI^Sl+1#ksZ2!1&i}TV zANSHQZzuR-a~nLp8&cssb%l1In1|iXr7bfQ^mjUlSDWa=;YA(LA!umJm%I3-@@L^k zzTiytG&@To04ppz1U#zD4PC#Tm*20hB9kW0NCW^1ge>nZTNxp_I6iG5 zgc&}>6_`Oj*r_k>@5R7TB1+Qh~HJwPbFn;lZ%Ky3bCc3stb= zF7VIt`cf6iz4kG?FI6K*>PDt-S_9Mw`AcOoc_r!`J%|skCyI=aO6IDO>4nPNu{34R z9D4o5kc3Oa6BGQC$6gd8Jil4c=G-ANM+dD z>?16i7dmfa9b83ulj^^a`o+B&9F098x$uKCBhZmu^Pi|`CZ?@iHb%)6`9fxq+s$fW z*s`ehpz7u;t6QpbW#-aKg11|Mzq>Egj)0~^;L+8kv8FQ_hVaU$pYX2l=DAb3;uJi_MNQ!K8{c zn!mgVQS>LuD&m>vDkzy9-OE%tEsP6^dSyt|8tC+Sk%^%b+W+`8VoOAZ<++V01QK7J zGZXhgX|acHl69IzKL#{wsBP(+vdU{`|N20=ircW zpi>wb+fmKCjbOCwbI0Eq>7yA7U?s5Y8=La;GJUAbVz`In_n2GqW5(tJ&-0=ZtjqX3 z3tWD^74ZLHL{L5R+~zw%Vxdze9fGg(RVqib8VKVE_fjA`5CqXNQpIQ+_~rz^^QZ3y z;(JB|jSg0G7e2_$dBvAf*IF9+y;Q#=Z8x1ALE=e~_bI%)=TD&5LUXpuUHbdA@2}`F z;FqvU=3CI6%2qpA(RM?GC@}NpxmOVPj zvQfP1_8fwy6YIxMc1GZ<{CZL2pEHq$<7)U6H5?Kats6%Xva9AV`aqS3lfQLA7M_#Q z1;fuO8ctfBY;cQ?2SxHv@hH;Z=a9jeR#^`_BfXJZLpt{d;uBRqbz7uA2dFN-jca7Cp!?AK!M!+z8AYnUmsLNH|DcSwN+Rs4@m6{{h`qSN_ zTQ!MnV_yr}^hxXHc!7LobcC$FAt-C=TAS~ z+6j-|b|#b?uFBViN$T;XiW2_VuOfOQE80Bg{_^ip-TpSkTBF5SGv>L!P%QJWh>&;| z(a>f7{aPf8zLg`naQ-p%MvJGwb~Ph!deL&iXQjUU_;(RH>aWJe8;oK06xzmL(Y1wD zKM#2Ur?UBlIMs`(_pT7QgxnJRqUWmZgNesqC1&<`uR!waa4WUFmRz53e- zcsmKa+wT)F$`bO6T>vk*AI8n&_9=l1gpevP=sw#9^;C8hLQqG9#S2GrDIf5U0DioR zb???I6M?_8euzK7e1Bf)MAUrz0k#ORDQ7YI@vD9;RjkN(&fpncfp_=jYjYNS)l$SJ zep&cpx&`#OuWo;4`2qgq!LyULPr2V2z7(6+OFv}0Y`Rh6zd1Oq!@ZEZ>aJ=Q%Hj>N*}~jxN!QwDJsZJ%F*@PtWm0&MB-k9% z9`PnC670C9(F(8ir|a9E<^$x>l9yKkxZmW>I853jdy_bnRemyKWc4FgZ>YFR|0PnJ ztG~eEWMfa%xx95!=UA+90R$c>S`1|R`NhEV)oqKZEUzYiS)$|lYHqwp_d9w;ab9(D zb4Lv^Xy?#YuRLYS<03;m20NZ1lmAMbXf}$E*ZFW3bqY}n3!Brb>iojk_=>26Jq6q? zrQ3E);$wIOHZT{TD^_iMT0 znm))^&HWB|A72&eLgqBpQ<--C6~l>d^;87eUcl35<#Ee z86R0v_En#E`5Oz)!?>SF`;NXobc{=%B(=;^?bHfM=O}4FkTf-sBIzee>JcQ>S<-kV zZIY^}Sy@5@2PowYr8LL?uv?^gW*_&lbA-bE%~VSrR8Xz?D)29o+;g;=|0>)jiKDKs!X>M)%9lgDHhdwGTh#o-*fs$)+G4m2?yBkdEN|=g~6J5IVf6 zOanP*iTDA=82jnH08m)m(L=DutjCm#L8iI<$c<`wxVOf-5q#5%%vAKM%;)e?xr01H zMLN2+Ku?@9@$bxB4C6{X4nys@oYd^R&@D|_l1FrgR~7}&miAuiUajE2PPMhPGqpDK z{MPaioq1ed9=rON+H&>oVG{*pEz`3s@g%k6Eml>1oTpmFEe&p><&`N}!bkK0zZ^8H zb8d#+bSfV^&#_w<~%J3jcMc+)#N{&=y*1ZLEI$fThV+XOZ!Uj z6`6OBil(o-kJ{A#2Agkk-r(aEI;&<3oc64&4X+(elqERV_ghX;Eg{gR!32@j>{vtJn|w4T<) z7i&XQc_&T;U-~XXVrBb`%f0A>QJ{-h*mm*0E%ELH2FvI&tRKgOU!0h7{gHH%dHUS0 zqvjh-UvKlF@}+5npSi}*jiBi+qq$x5goKUe19$k*L?m??&HVOj!iX`3v0=hc+G8xW zQFl0}vZKq*4(V$m(-tj59p}$1k8WcM0b-d6h$q6vxP2whksl)>G`6Q`Z1+b5RVdjO zc;VFNkch%JP}#odB<&{qZ2NuY&k)%<7MSzgi=8Ck5kA}ZK8<9981md*WOMyZ#V`@= zXB6aT%1iv&6GP7wCTUTHyWuC`BM2l+@hls`(`IMH2ao5qrpV9y264ll;%ml!jk$@R z&AUZq?0^9*Lbw|%dDNiUh!5SoE9~>iME)xQ<5AuS(V?k`_e*;bfKDNNvs1jY%)J?z zn`4MMF3v6+jDhmTzoU#TvlqbP`tp{>iDe;H9$t*e@=Ge*jXzd%;q3EuX5KeXn#_~_ z@y1q`?VpZE%KVYHtYyQ$mou0k~+L372<*V!C3rPKMCn3>(R8SpO7bh-vvz3 zY#p`J@WDs;hEJm9Ufu-h7nl-T26z1q?DvdJq?1aiNjFTg3F;k!tB1OplurSSI@q#( zr6-rN!-o-J$Y1lMhxH9=9vfO6v!?W88R+9nC#G+Bg4%@vspQ|C5YZ1~d~o&uqY)q@ zEBA?1INVprX%^-GZDRzhe*GKfZ@WSjYkmeoJ;WRydUT;_ z>EElet^9rSMQ9*yoE7pK%VHL+cBBBOA3|slIBn_KDIN?sQ-h-hm?d_==S%}jWCL+W z>Xs(ec7$-n2Ps5Ehm-WO&WmOJz^e6M3`eoXgOvo6R31&6E@P#GEa~|1hua*FHF7&K z-mSavld;*2AA)^iTT+ywf2MY1sW#aB3GC$Q>;5-HrsMO*`Z)#5lPf}w;tKU+omw#F zcJDEssH+m`f?clQ7$(ZZWrS*X z!Pud0e998*{0z2j5oTx7&s|#-`pl}cqGssQ>eOPJ%a)^IHuj79v7;8J<0Xe#SEdi- zk}trFA1{~Kbot8TcvQAeD<35W&5XG@jJxNr!_3m7h$*ol>{97{g2- z3t_?JKl9oWXi}^{JIQroq3gp|hhZhNRf|r`tPBYJ$%XCf{Jc%cGv6j~wqwPayUCA6 zQEA0OPN#crU?W4|XK=M{{46uf^p9+A+mVbl4Iq^gn&MqKU}h_FJUdI~e6@wS9GiEi zNtv*k*4`|2dol*YnY3IDCk`1)>ex*pj7+0DkDBApA33*mt#9TIOO7<-IpusMiz9aDln5rzDc9pArExTYSp}tt zizheqP;*T?2uS0J8;m#lE3%}=MK44R@9_=m2x(wivLjwYAA^a z2f+GL_S4za5-y=xF_+|$L@NwMPLS>hhAeX_WY9@t?=&7Wj$kjOMCdIWwb*?3=4@!7 zBN8Azlgm*#@Vb&DVCM)(@NfB4oWvAfwVA}5%DrBJGtm#t z2i2b+#Ndt9;B|t32Id@SGeoQC1T$c{`+b(LLMz&2!ZFi4G>n4=e)4cMozjE3){Yi) z4W30gk7_nB& zCtm!0q`Z;NoYtEK55BdBsOMmqScWlpbB%b&~fq;l{R!t;B# z_!Qc`tzt;+i5HWESs;IkXoUmcIlH_4-)X!)bQ$32M-SpZ-N_g?cm%~*4%FZ46 zqkaR3JNtF($OX}Wp;*21+}GC#9#!8~WvnT4wK!c$CNVMDF*fpiZ~rZ3thvax5`Axu zj}NOp_f`8n+J3Lmf&5HQWnofUjhT~JFSr5!>cM@Z=-D~aGkqkGFLa|`5t-r_jkM)c ztkG0b+giQ~IQ=HGIm@TxgI3ckc1Y$m>PtGllm9(q7VlrLQjb4otCoEu_Ks4oXvvU{ zzmgt=8!9(mG|cX8W$$+{WZa=p3bVUyF$A5*A`pAe zXwDNpDQK1ywi2Xeqx zV1=-1t`g;$pG+VM{uCmPC2i_xSRj*O^8Uh7aI~nRy(JX2_GG+FGb{mycgsUKnXv%N zjD~9!x`Y9XfFe(e&tq_Mx4Gu$K%}U^+&2oQ1N_dlysdS#gfp}0q0OGRyOrgB1WVdi zd9Z*7{6)BWm9ZKnA%uo`H>`oD_)?Hkd{hARfi{VKNpTe3tSEjKOlL>~9F(bei7N~G zL-E>yX!i|#6r0Ss?J;m-be5m{t5_Krmb>Z`|4BTvVMuWbBh>d~9R9uj6q`Fo(&XDw zfDA{lxq&Dt(oieJMka!U;lusNaf;P+bB)~WPDmgzgG0(WvNIl?EvpaFAb3!h4hUZdW&8Q8z)G;|Ob-3n#BJl;Bcpb)B$Z@+w zep_NFr*hT1)S+mhty?q(^n0S+!UT1=0r*JxiKE#ALwmrjo)Yl3yWGs-@V1{aw`@M! z{9vJl)D_A~gmh8fL;D3NdzD^FC=nUrIbJ(cRjla|(i9$PDB(&84S9vv9fZCBJr&Od z==+05*T~@a+^hWWV*O5i*^S9>ZZhaN=95sJaW;IW*)?{HuX{HCWgSyeVC?(_ke5$X82UsY0O}m?aqG@M* zC2%*Hv!sDca5QcFHJ2aG^%I>99JYBclcGU#G(qqJPpwcFe~yCz+pN>G!_NADZ0;L0 z=lO%A3#1QIjBj~H^s&-Q{&xKs`WjAJ1=#2EN@Snw?0BVQ_;uH0n>@4G@ma{8B0G&2 zh3wF8Jq`si!j%6^Yjml^?2}Wv`6ax1s1!mm8}zzjsWxuO_ox)yvFL--asxVy81DgV zOH&XhfOa&l2KN;R$!w>kkNwNaV{gyV{G$K#8htoCn^#3s3GlFax#kg@@=4`N$DRK@ zV$m0Ietv{XNauEE07Qy=?17<_E`phsdT;j4-Ew614rv2_v|h#)XK2%{)H zp8pM7TBZ!^5m}~y?L2q=JakMgJNUXX8g^(eeZ53q1${=I-L9{?J22bbuH${A+23Tp zVyg^D*%E1>7X9<*5~tF43npBrG?umPGC*;1>WTstO~*Ib@0Vh8KhshUpSz*D>K#pS z4IlqJM>ydC)`uj}O;pBPNvf$_97{f>{LMo+92Q(0+PGc5YUGqL;b5+i4UqLrtqudv z)fxu2ClxZ*^p^iJ)kgXPRz(=3)>HrA6GNYuw?Kn^ubZ0K^Fzg4XG+)E0F4r)-sYW- zm*#%7eBj4uCrjcQ&+cP172s!q^90aNr8&%7>M49J+guf^n2Ua83i4+}qCd>vATwfJ(YN#Z>aOi94zl^q9pJMKi)Lf2ng3*Sy*wh1d_PhNu5Z>1NSApc1gzM#5%T~9 zl$;Y`C5Nf1A0`1zWbHl=1;z}*4 z7dsY!}vfzb&@wT z4)pj4Rzp-#5~*Tms?e3tp_w)|7->ejkM54BH2+meLHpsnDT2L5wr{BxbQ=#lLQnkW%2%d83H zasN`t%Afd9Q@O!7=$XIW-RqgU8&7q%5-JnU#90WckB?g{Ir~y< zUflowUhsQvKmU7g{l=V=T{C^?HJ7h0COuv7FFh)k#*(i}D4TW1-^?0o#Pga4&hcXU zFZSc4S~WHIHhvJ0!i#By1TGeVwP*VAAbv>HcSgOJc+1p}V$Xr%Gl#N}DCA{EiS*rB z=(~HQ12fIhocL$MIR*FpDh|5{I&5P7q`&!&m|bc@?nfZj#~eaZBK4sc>zfiCFC>!h z_DpfuVs>dAy1`Vv6!TIdR^dlOORc0Wp7>VFHyHd%Tkypm+9UN52~}FCCM5)*G2-8c zGsxmy9H6`5VNGxx=v+$eFp0rJw~62f;Q(r>SIfMbBz9OdYAuycOn%dI+7aS#vsqt% ztUFGCk%cWw7QmFfIJJrQk*GS@1*6bjp=cN(TCBX*!yPN(ik#};CS6t0{y1SYYoul@ z&P;}hyTecOYp%@6wieaAV?tDEx+gR?ADXk&d*4OP zVq5J>ws#@>E$vzy8@bRDf`=Pwl+9?^nw;5e(5%W3*o>ezI>xK#6PWa(!hrWq{5v+c zQ4kpq7mXx0>|u)nt(!hs6d7&XLptLZ!U8KJL0ZPr3=|+v_SVm0oV;~3ip5K6&9b~0 z#)QxW*|E6&L$6}^jKM;c`CaHvWBufHm)i!T{+!O->H=>~`e&uscG#g{z9VW7q}9oP z6;5Y@ZyxnbP33FT2I=z1Iqz(yCsp$~_r9DXAHDc+(R&z1YAV-EJ0%p=6fefxLz+IuJ29U-qrdaT)LEt7^ds>J= z9hMk^Wbo45ZY~1TrR~>t&EDhRWjAi_OX!BEdrGYhg)sb<`ZK+P?!dbLgWP|Us?XF9 zCRVKJSL#CwURwWWBzs;?=qQBIqTEL z&<>#-HG)$!I0Z1p?tT4Rdce(dva`ZOn8u!jINgy2u_)H`eWM&Z{uh8ql-nGLAI6er zS+8)Bi#;?n1Toh50Dy#Ga;g#a)G+Eh2DOb)DWD&j7)s^2(xRaHA*oGs-uoL}ubN-! zGqFM;UvgQG_GGGk&V~c|2HBLTV(AY-?G5VvxAiu#1y_X~Rj(&8J&I;rFN}4pSk^PI z{VLV|T-Vye!Tq+XP1`jmLBSHvMXHX??Vz712wT+M=J=H3BW%=c2!p3{EO{?&Lf$t3 zp0@*=kU91d;m^%k|M{7PbaKx7ntL_r+sqG3TF_?o9lo$mPca)QvdRSBy=SiJcfWX0 z`deUEJ5N7ycC`Vg1|Q94vyr1*;cD*M(#5Ja^$M1h<-8GCCKXU=%5h{>>SqwbcS8D{ zk_a4-(A#{hP7gMq&QHf{cJYpy+6p_tqKi4+SbDQE zrh1ijFQYZ0U*NraRsn%NwMHaT{dt&oUfX%Mywt|z+gedgA7SLK=3u~aTnrqfN>P zxi4A`SQ>gNHRMc4eWGVob?Pl~yGhkLKP^QkUk;iy+DyNQ5?wWOR1GH2)XJI^7(*a$ zr5y{??Qit%(^{<$D{AsrP=!9vcp=fYxRTPNR#$)VMRlrWLhRlbd>w2l(Lt7HK|QO% zX71|QJyn%}0H`g`@Bl$PJ{{0<)ycZ>rxT_RxrG7DC{%PCeF_>bAB* zYl-m>klVxp%aA)E{Zr8Reoyojtgeb+0?GsJ-t;aD^AUJoT0l;}H{#qZQ&q1yC&D^* zrMP?R3bfSiO&JY}nGDQrsT8^=l;vQuxVwApgia{W|31e`)zVm-`HM3ex~ z9@F|(w=H4m0rE%*=#EJgYpNx6Lh9q{L1PVX;iMaV^?VA^D^Ub z?nbE@x*knSgj_vzd5x?AHY(LdLL5^GZ;xQuTQ>Ac^l7cx6JmN@BSNiLdcM|@>6xf} zcIJ1+&)=0J>;zj^sPtO3r{vhO?ea(te$K!}as?Vf4{YAk2dCpN?-=;fV`^a=S$h*T zeO{W+d%z|+fzcp1Qlm@dN&lSt^BD!kQhloQ3n?y|_Kkdj!>rAGA8dJGs#`wnRg?NE zk@Saz5vp?aOuAkmO_IBInm+9-X;*Ywv1!xpvXu&$#sS>|iQ#RDpGx-?pXl3F+;tHP28ITHfhd zJv3wdFq2Q^u5Ukdl%Ic*)ls^vPwbX~B*9Dr01GI+ zN){s;hUYBnqDiLYiE)UIu*S6|npwifezG{WQ_t8=Yi|g&PPg@nq4zevft48)5I)QX@w#|mH z&CN#I-5VYH-!*E-!GV!R)srm}@r2#mR(D$Hz<<%5bdbGUccz^eVpp7iL5%Vg=A{NpnJnCTx= z{bRC!{M0{A_K)NJV}gGiS+^Mp$>!DPYqx?zV{ICv*0ff(3EivtF@wJcS>Ey@y zROy?rg9}3PX{9$08MLhDEh;@R+Z^c>K!Ijr@PgVN^L{?0dEO&{+-=Hcf`-y19%yz0 zI##MS0x`WZ?F6c4<*{4CSGUxEpAKAcQ-llRE}Q3yelFgCbkI7@yq74N!nNVcycs*v z+$2?7$7E-#@MV_eu^rl9aVzY_E%A>h?ZIL6VkD{KGBFKqZEuEU8gh?yrDRi)gj-1s z(#$Mrg%eU=j`|!mm(8e)23IG)&Yynb*!c(Ol9QGX3lqsr{NGVH?Omk#uxbs2Ll$37 zRDi%054|0A&^9hWkzeiUD!&iwtI_sZ6%*~Q=MNTUS!saW>JF8@i0cNuGhA%$ zOopjjT{+!}eULXb2KjB73FI{0iK@DyPD`Se4BF`P)%2>`_v*;`VXxZfp>7TGh4b z<3_F4&@!Mlx+|qtCO0s^tDrpk@g6FBsJk)x=x&N0(f}g-$m?)5Xy{hUYn^JjCR>Zw zT;;wNt)-6d6H-f1Y}Nr43&CB*&{$ujwg_>trhhQcCZtwX6O)QnC@adhwU0a~(FdHo zu2fc>e7Wdd{>)%NS7?bb6t?{eGoNn!hVt?f(SmcMj@w!U&yTDdUsAuh!8`_1^e>;4 ziq?`7DwkX|K{TuVDjEug)}&>)5M@Ye^4n~5rx~etqQhYJygy;+5-OW^zpeh}F3^!q zL?hLPYt!|7shUbRJ3tU>RyRd;_H;USCZjiMS4{nAqf=kcHtEUFS5FNRvJHVma80p{E6024F+ zaNy$pMD!@BkBOnswuoYhe!PTTDHzy4+3yY7g6#8&CMlXm{;SnPU#>}U%_Q;F#EVA- zbp@j{D@0IGAeiCeowA>OnKu(d!rLJvvANfxmirnYG6|1hrcK+A%?Bdm)M)Ix47^pH z|7xa|vKn~pGOXgIk&(3>$hCG#)MKKj$Aqbr!bC7&y8RYRj0>O_UIV*Qhz;{rj9_C~ zH*74AVxxy)IVbvm#nEWWMsQ@O9YK>U z#yo}?r9a&}^FzN@s^fvZpm%1Ap*FK~C-o(`FB-X9=bt{N$t=4@!b^p_I!2AtY& z2Nb|X6;G-&WrmTXT4*#_!+Oh2kbXDC+ zpXiT&S-_G9uZ<{EgBTRoda9HuWo(WQJPG`8HN|#1cQW~Vr2OU&c9$9reBe*24^so@ zelRuICUO5Xb(+PdRK60~Nt|uoPw5v~2li7#Cs{*e!dK5jH2orrwsAIw!Cgt@_%7#r z({)wwBQ4H8Q5hC}-aNrL6xq#O8sgjD6bO}lBY~^i^Z`vB!tj6V= zcz&m-fHiJwH!Q}Jx*%^_0y24ncpDFV#kTGAeG=IC)CQw)bQs@ZWy;5Q0I&q3i7RYM z$9iQES<7CCwb1^oJAI51PtW!n-SPJ7CIl&&AHcHRrhh?EU$U&oQB)UtSQE|{)Lc1; zK&`Q6bDM`X#Tv~D*es(c>3%=bNIcD;H^(Q|`eD>T-Is6Vouwl%7TIK&5*a-aNTJK` zt@$QTa}Y!(<9$Kpxw-SzPgGHM?!>OVNDQLwh$0|mL*j^Hdm4pLI@G$~gSm5py}BO; zDP{$9o4=y_J9M5vBsH9HbNYwRwh5_fu*MD2d4UIYfv@&80`O&{+R5=f@npu zy$2k$(A*`4bgbaLue+9TK;V__Op3_|)!ft?^K2S-24DsSLsmk4Tix6!2hM3(r-#v7_@@mnT9?SFxPwB~3Huu>+ec-p zvVcDU^x)$5=I4X_$tm~p@SbdoJ@&=mJXUY@Q>kF}6wX(t`+c>y>Umv0RznFtxz({F zcWG}l1-&HFM^q7g<^|;$>X>(Vm-ES#n2!^&{Ww}()}ogeKaQRDG{>-yn5bX=gf%a# z!sJ?yuk^_Q!<2)`6;XHM9hr45uhw(Jk%8Y})%dGQrUTNuhJlDhEt??_&>X6X~<>?dtT@sc3tz;ALsUBdIi`C$#BH)l+Va85SFo~ zbF!Td!KmNS9d#pUV)kTy%EBTH)tw1nZVNH1ouTmkNZzxUscH} zZ&1-y1a8+)LGE98>x$1+VkqX~$zC5vO1`H(dj*7PJS&1OQ%Dau&Z}zd3kG^(jF2)T zgqS+7`Ce+=i3migVd~5z?)@#Ri9K9ZfwE9bbg;9>r>ZK54K_8eo->xUg_54_vEQ^b za6nIOE;u97rW}FXQ$GsZL|pg@v%3k=bi8B1AoCw^H;gY(teaVyb5&WSaMSZC=z=*4 zd07;)`*mE{JG*p*U2xm^JJDhTRz|^zUg}(cO{Hr+^+7(=plrT_gVCp0mNixd`9>1+ zEChAaIE|-*{eYf?Nk`FV{oaXe_hN1^RNTEkE}MlA5CQEmfu$!t^QNF={FYUX$tTW0 z8K1j>jX)1(JTW`fU;eI9;3Bl?*=2&s=# zEXI*v6ID>z@XLZeYiQEv7m}ff(d;i09gy!XZD9l5OEhpNC@j3hhyEh0sWx(cGwjC< z(A)iLutvr1-DJVm&aV}UtIX_X@eci#TIJShyJ~+s#a1$QS?RNE_Ec`Y2*)Jzu{|wV zXYLJn{f0!Q*v_JflaJ99Q+)uF$c6x$qK3{V@w6PFtXtNFP!j(Ep-c=2rFL6{a@fnB zAepG<>B%;rdu)WsgZusCluZof!HjJn7PJ@-qXmktDr}~Tu2An3_@{plD2%5z5IT68 zL!sM;qePk`rl^$p00PrGiEGx3R7a;hz506HpZW?rCTqklk}NI%jeMGcg+sA^YzM{H zQ>{#1%WlE3w_TR zOLdG{pv&tehab_F@U!!_@KfNcEo*h{9{|@~*-mznzcbJqeEn70SpE0yY;zoL+A|yn zi{a3D2y`*2_+patx$aECF{i7%x|>b_!$`I5xh*dYnoyI!gC8rp>{02{>2sDgw%PYS zS(t3{B)9Z6X>`OQLM0Hkc z{Sk(ged@T|2-d@_*k6#_;&a)W3JcPLeFN?WjiF|P7x0`9s`=)Gq1A-AZEze5c^GL zqE`?hCQjB&0MuuEBdBHdoCAqzx6D2DfC^*(Y8bPfIvQ(wK)6rES5|@abbOf}Nc>o% z?dGJ*FD0R2%xk`w=fCAa!yOjN4kN2IX?UIdw-q)nfRpLJVXm2h9V_0q|} zbBzcnsa=6yDq+3}E2|&<`Pu#-rkd(6GS#UUt5zOw<_eLb8paF}nA6Woq{`nrT-}2T zPSL$H{Ad`{@t!^&sPS$X^RfNtn@AO`Ui-~-_ZL=-nQo-;=_A4S%q1Gm=|fG3oNo`>7?5p4oT81)nfo-*;uKc?0VQ4G zbqMX|P-al4GQU=aO1`*fuq0$gvkudw?#v%igkk4!9BtA_*^h%8qwL$7(LBez@h;e? z-@9SVEA}#YS-}duEGt;52Lu17!-NZ9r0jaIWn~K&sBcQ-3)4(zW5)wT`xRZ=uciIs zbo`Ihrge|D>3_|;Y6*ejiD-dV_afYMXlSaB2X`MOnhQQAMuJAS&@Fhu_*ijk`&Rez zd$iXjUK`HgL(Ho6ex3R}(fZ6wMbP<@umg8qsSXsZ8AIpV3Rd#495hmE7PRRXfJT2B zuwl%~cSJEqLGd?}aaqA#{1%f~9dv}(@4q9HlMq5{MY6S^T@`bS0<6ILcE?ZgN&f|e zz%ZVqR*k$g^v^v6E4iCGl0kLu?yCe`jRz$YYaBWI-bx5KEL(3-)Fh%#W3z3Au}T^!F2@fJ#GAU0A_KMe9K z%@}9SdS*tKnDe=egW7EgzR8Vz6dk2UqMr5O+d zT0#|0^lZpXK?(zIXY^JALc^Gve=-2ECR-5cGO29ltNC1$9?L`?>a&35yqeUwLgk^> za}nJ->UR{$J}D(Ztn(Sovl*=Pj)@eJ=zjXLnC4LzW&7MPjtS(D@GQGNs)?gp#W=8;uoduWC2} zb2KS;FcHHTXXf&a70)@=g^-WEe}90>jF}N}haTp$?aHI!t6irb>anQ~mHWXw2hD-d4Z0#_lZ!Q*--|K3#cx0DB0YXdz&Q9&%6$cbT@8*S+;$Z z)qryRvbnL;&IWyNEPP};?RCs~A4hSlx(|Rm!Kd>dN+GZbr^Q56_;_lX$g9jhd+K~c zAxWN(=$!N~qXAOPXK@xrQTZh*p9M>@S+Q$9j(zw(xbq%HZ#n>DG0(hOTx=KK|TZGHcHbso+W;|}S zGGRYG1-K8*=y+w&d3c6uD-OFKYuacPpNRA*zl2d$?GYq$e-FZ)O+4)e#u|ONzuKur z`jzc72k5+YB3(C2JStZ#eO-gq%KRV`Q&5=}&Q}@{PSzyS*Dct_cd0}A{s`Z1-p2QZ z!T0MD>4vgg2c{U$jvrML(Wyt1)jfbcMPsPW%9-8|KcH~0;j!{LUuTV+>Tw!tyjp@O zn|xlCaYOH~W5;tZ=<*$Qjp{m*m4GK{$WswD_6&sy|{-KX!XFOo4}c-4gLY4ijH z159Xeg!wVY6p_<9*I#UUz7x=sE7@7v5OKUN&5p?3JkajT@ z6QB1ol?|>F2?$xLYKg4V1(~}Mq?vz6)?5`gS+iYcg2`5@r+9$097@86EV@AxvjZ0c|CTPOnvLd>9xzsq%9bE7VCAY<@{g(( zOQT|c;2f!NT^2p#PJ({u2!)(V(ui8dM-=L&D_B4w2D32smClHB_In%yPV9%wv_l{T zi|?JLevQ+CwyagXJrdD9R&4HL zg4|4Kz@`aZg2JaK?govoNw2wF%AYMtFI4)-hA~qt9qp}7`}e6j^$9aYXgF`H8fmSP znY%d;x6Jq~)K%ERi&bew&c<-r-Dqm>kyeyTJBKvspvCRCuu@HTUdB!cKbjYVyXwYWcpgI25;0QUHm~1{8Z<{UtYyN=|P0iK^7gUPa ztfpGOkf=Y7A+uFMNlm({nDB$>|7(OdbXh*66YwPrM=SZon;AA`a0_fS5p&D5yL`7R z+MkuuL?N_@qfM2sq7RH}p+_r-M9(gAzq&OjAo8YTGCeINOT(BIuL1y<+wvokO4z`t ziZrGqN>X>QbyQzM8Y&Q`10aK4i$kU-^8etDmx6xsqqc-&CknON~0N8cM|~*GG(x;aDa3Auf=CJ z+nL#nS-LU;!nWCB^d=X2+gXv@+({arhB5d4UA;K42B$bMR{x!bF*jKX6iVE?B$j0e zE*KVp^$%S0@T$pcNBs8jq^Ctm(LnA3Z=I*d3a4$b z^pMgNdQS#ELq#Z^1v?&B>^1RNf>J+;6T3Q)o9{qrkE9FJOM^Sv6laIyWeR<6@)df@^+!Uhhe0jjnBLes`- zU`6%RSe8ngN(pbH@?%x`^dl3gr0IB;)ALi~d$FedOsd77DwZN0?~TQ+t>7=C2jzhc z-WCOKj6((EV3l~r0D9c9cQ6!-SVqmSX>JhU{*y-OyL__2$c&%?h^IirGwJUPiI!v` z@$l?29uKLT@^@;EKRaKt3k_3K4IMVmE!ai1YS|2$A#$-uh-P{}a#a1yO3F(ixuxfH zVv}lSX(|a5X8%Eh`sOCp$!t}n#TYq=|Mms?5LKCzk_lw14tQm`^-d2|1RU9l+{2F{ zECq-y-8HQ$THO_|(7SSqMS9nze={zoZzc3?*R|W{`X*dskNUMHj04HSGXh9nz!s_=3kG^s$juV_75vf{>vxVX#&r=p6@2sk;=J~y zZqrNjd2pvb(>b~No=72eE~u^0mF|O+Q27xg>sZVo>GFf^wMXpQ*7@Dd>pIw-e9q!>N;V0w*|s-?XzII1vfE#!uBs1L0asJQ>jBa_Ou+QJd4ZN z@JzKBpZ+z}j6ww~pYpXJiJzrMDt@;Ab-EsBmT!4c-wKY^FZq6)S^ln4V)s&TY4sx^ zRp^RzdBdZNmG7gxtJb2bZD$_8CxRjUU;gR8_%H`K%6bt2yfaDbBT1>rRic5bs2`B~ z?SHj8b)q`-;>R_y;frfhV-wf|5^{T6DQ`Ibr^}}-hf1m^QDp2Se*;NNY~BgdFWcta z=ldyrVEYmg0c(P@UtP^JVC( z_q6xbJ4zkeTY0wOs|UGv_SHLTVkcj{)q$_xQMKv#_eGoRx?IK4R`q-AM7m>YQ2aTZ zios%kF$F|!eDnyZy#6;V6PyM=N`w~iLIlWN>a*8k`mzY7=LZdp=vw{x>Uv^yqA6OT zEqomhl%n4pA3Zz5r7?Qtx!29m6BvZuJ%?Ggrf%8p53(6=bxl6o?w3bu1Jil#${<^b zv7*y_w!@>fnP@mm*_z`!-VrI^N9AjR@^DF5*$-t&XpSF#StOh0pxYZ2d4h{!2hd%Aa|!Zh|NPqi>CBs~-csAOzk>zxMJ?n!QK_NK9sITl zm3f#Yl-+le`I!uh<6eMQJ)biy22w<>428IXekw+u-tXIeKvyWkHt6a<_W?CefE>SS z9$&h}-w)d+rZwk%F&kMbrHVia<6t8YU5V!3b}Rk-dpB*YTRhm4<3T2WAl2qsswDMB zV$}znXB(SbmtWIosm)4pCJ1#ma%u|LG;6Nx^?T-*VJC|cbtL{>_Zaz0ihRP$O5j7lXo~8@a0_m*V!F<#b}9I&Qest| z=RV70^Tv9vYsvj)_`J_a1jgoRyPtjT=YvVVNh~PcZzI0K;O)5eJTU7u*yzNUD3!TC zi}v4_wq0jiJk3v2Nc*Cz96{E`Cf6evmK*g6{p1C#qJF)t*`3gwNL?vLDpFme`lj-I zzzZpm#!3jTF^Muu=x3V^^+bLx{y7~!O&0jR(fPtZ_xjPQDd3f*65iTRy z=Wa3!jh&`u9$s*WW!pR}G7k%sZ3fu@$f!@u=nmo$GOv4g%c%1ZqS*#Y+0-85t8DI; zbMLT9dY~$g^Hn}EvuoR5nmq&zTYb-I3ECV#vRi#GktJNb-<+#JbhJo%9@W0lY7Mq5`#HAONSSH7Bz z?#oepowG#T$F385#*AY$R4{R#NqfkU*<{-@gjeuCR*Jc50%u-;rP}n){7%-We>?-5 z9hhUYIeusB*9o+Xeuhkx=_P$C=05J#k$I@NH67n~xu#%#@SCE&EaIzQOEqd68fFsO zL%$Zu`KzNB>Qw@}(OIHyk6xt2^m&EMrM?OQfg;VyrQp&N-DEte(!|q>KhichuVcli z)n9y)dJ%Z~R&Jc#qhm3H{_6e+^)p>!&e!?08A}Gy3uM$v*Y*WMT^^$f$sJZa`%dcw zrhyW{o2fqm_=g7(Yfoh#cLgWe(sQ)jwEkGwTJ1&*&3gMUH0Z+{lCe~T(QoUovAQ_} z`3e7Ta&4?{V~U%NU)Z_JLHKX8i@q-SwkQesV5Q@KTW0Ldc8>-|BYb`rh@1kCXiO^n zj;w{XNZ(Y1+!bEEw_z0-`H8bt0=2%vsCokKa??h<8Y%g3o8&*?4!{q)H3yGm?&|CQSgAyWhf+wl*#Qhu)yqQxe*8*y-^Z&cGpAtx)-f&=6Tbf_@1rvzrIV0kuDQm*YEER zJre-a;>Sz1-ewI{e_T5L;U2iTwWi|l@)TWI?&+&F_>jn&bo}C0Kb!VA6ks-+!Vte} zlN5&XyqcFL1vgs-rt{Fa9k4TvLGFFt>``U(FX^ zq0#%6rVDDG#%fVjRk$DeQX zti&DkG);lOWbk_*e!Im0F>3An_(YWnM=jR0#&_%O@A_`JX9(*`yE`AO-|-D(hQMtG z9nKfGaSxg1mX|;Q{A(+CK6rEM_cip)Xc4^LLCQ*1_h;Uju`E^apfyr(haS!GSP1Ui z7QnlO6Dx=`_(H#<48r*Lt#cNdQZcDk0M2krD(J_9g9ih3%UW~%J&|FAOx&)6gAsK# zVWp{p*8mh(x!3hb$3L-O@m^HqxO6SA{l0Ykaw8>TjLEq}Oi>rp=Vc1{#SmYEhm-Af z{}n#K-7AZY#A8jj+RtS0^QOg_Ye^vg8Dai`mf^B6f1&+6E|*`|fdAhos|eRMfxyho zs1@0I{CzuYMT)-&Nl)*dL(K?Isz9W zH+w)%pv9U-=~Hw3&e5K9bd)5KcwD1y%mO+ubT{n8@Z%pA<_Secmu%C>)-WapAaD$w zzIJ;;Ps<9ve#*P6^$fwMjXLpkwcyV4mA@Mg`o_oO8QdQ#bGrN(JrwURzuhdQh3-k8 z|Dj0!iK>i#5dYtQygvL0q(YQi&J?Eyf4MxEOlx4b`h8%e*N^8qd{>cm_*dcQpu>?I z^L&nxVMAe;Y`WaQM{n+|<2zS;4#^_F1OK3`fGx=ED=IZ5=j@Mzsgo-B$|^1BOV^== zA%TK*t~{b|o+AbKCKKFkO%fJb%<$oN4MESod6IfU+wD-*)EvL#$=rMdH%V=_b|<-Im86?|FpBOv1dNn`1CDnt?*w{%SLI<@>VZ2sfY*{daGre&C;?})WA*W-JuZ4I z6m;D2VkLwYRQ3QPsYQY}9iREQu}5?1zq2N?&W`ih9W;cM)qR{r@%Z;{WA5|Qv0ISYQK z_R{g+sF=3h=(;zQY~ER!+}Z~uA$}DL1D{}>Mb4rYq1^yUeK-2EZ_VnFv|L!F2Bh> z#;>wM&eo-7d_moQF|dym-0~LvjQ^UyQt{F}+X}W0@M=d}!6(5Rh?_V&U>j|Zisa(6 zei8hBnBVF6K}9LXFt>|z&ZOt&2GUjMegPUaAWDsO6EtIIL$(SxcohZf%s#WM9dNf$d>)` z^T=71NHLYaDzjX(&x+*o^Oanh<5n>_^{#qFNrmnKeQl0E7`1s=vEN&}Lsz-wPUt$z*YD>2m8&a8)JayI8+r9t%}74s*?RtcMQ^ z>;vx4@J<6ufk0Vl*6;0Z*uyZfDB4AG=ecV*?BM=oUp;ktGHgOCi~h0+Q14H+QxJ?c?2} zyBYfTiu!Yy9r(U|Jot~O3b5iXH<=SJJ~J{<#uVoUId2Ygp5SwS_|vXAPYH4wSgLcF z&)I)cB&SH(9T4OcwAOmQ&v{OiC7WTpP&tWeFy69l&v^hQ-HOvA6&jH1S){ufbv7Mu z-U&R)g0r`KY_R3u&=|>Y-T#a7462eYrgEoA%ip*ti0wYiQYmKEDG_s4B82zH=->B^0<=G!eno?~fT zvSHPMvAvmevvv34#!%%+UzfE8pKeBP79J=p3{^qhh0=>yWxA`bx3M@lCV>fqXTfBm z3LyM?wtSMNK~^F($NO5=HHiYBj|v5<_%Z(60gzXo%;J;P(?}umFfEH``~@WB^VZeB z<~~S|{!bNO4rA>ye8Do2q}uFY5~^rqFrZ6Q3)iUK^yHDY_m)U!MMZP`oEID=ltzV?7QRPHsCO!V@qux8;yGa$%G{%Y& zJC9Z-1h}IDB?TF-U5%F{Ez-ZY0Wb-Hl~Q{qQ(NgxuV4wB2!op~P2J^tg9oN|649am zY?`Xs{@2crtX00F#!@keuNUWTz!NfAidS>IzF*MmaP6-3zk8DvwPg7$I*7m0on&I% zD+nlTH~X+oP|7K#hq}^%MhX44kF;if4!fcCxuXV|hF4(|eh|XhjV6U=$NW7qHB8jD zql39!ef~o&e+Iehjwi((?i*P+G17=d7Ji8ME(WJRe|M#1Rr)S%C)oZ*(_TtQv0?2^ z{dOD=S}joq(JJ~|p8JRueZ!bj|HLAjFz%itKv1wdz`PcDtB9L<8h@T%FAQp=bt()` z0V`qScdas~7vg=VB3eBLJ4i3EI9}@Y39}{1UU+wR|zPdw~!Lg5H z`RK;>`Zkr>kX<;yhTxDNM6k({AkWolfPO7p(S?Gk4B4I4)*(0t-lbgEEaat4zB zmdm?3?x*`tCZZn(a9x*qLj0XQ7$#NbKF{lQQG-s_5D$;>FUe6xiKmPMzBbC(E&KxU znW~>9j-AM0t})btjrV0F4mGv!k*f(#BpP$XmdiZIXV~dkdi2@{^bi{}^8NvG$eQ|38&3-D@Rc7Rmm)02f=D-ynY1@f7}uoF*{dRLcoR0-O8MwInT?v@6dO* z5U;w-frvUxVmbC~^2~Y|`s@3B({WnYa9~R#T3|EQySXcr08&h+XxWQAo2_BS)&H_h zm+9M!$tr*h-h`ZUF7$KA9rBezOo%Z{pNM2)&y+mr@+bL=Yh2`uDuRddIadxP! z;5riZudU!$!JE6Kf(eTYczh};>>rH1Gqkkb`F9!VPb8VW^%;sg^VxPni8fBBCfcl` zbi9)9;w2YX!WK#q4qnJ3M9fxTtjUCNusLm1sb1ZS5S@z zUx@H9J5M4zC6izpK%O%UCeN*>x&x16f`q2zH~9o7IWvCNof?l7v8#SXyOe1* z}<;T<`%NkE|olRu|LpxAaRAto#He zK>R%*+I0MI`_&q|VyX$W_z3-0$i?_lO5iB_6c6txJDwc>o1<*Mhj%j%6Srr>mHS+S zZ0HTtcDv8^!)_~!dn7{#ddL@V>{`iH1!^n)^IqzE+9{|7+18$&dKU`gLaf z(%Xa?xuA0gYy4p)wyf))^F&vi`7hQJgT5wzX=2qIoDlQ=#G(3~p6N%_OI9EuPwH2I9d-|8ThTpnlP(sQ($zrK(1rhfBtozl7YN)V%Rxi*fJ01jZ z@d3gXNYDF$_DSzJ0v6HQBNe}im$ri6@mK%a3U28rwl|6#6&5+K28eBN;jOVoPlpAY z9sx7y^12szFzw)08Yon30#B6?jI`Ry*CoTmtF z;ep@fP6crlZY$V60Gih?#s(Yk>~DoFJ$y7RHOCi!<5daQo0b_p{nin^J+dc5H+|!LPY>En{8iY@ zAb_D~d*ugsZoHFWWjkXhC8P^>wnuyyJ&b=~e=inm*9exx<}x$MR^IwA@RJ;)2Zx}y zs0y6KPN#xZd8%i?)As1sYLEC5J$!WvlZPj*oK30jVU?5{kPcpQQ7d`=A8T&{UuAK{ z{UqbNgidGO&+!xw9my3!!Xf^-u@67Yu`y^o7_x-> z{wNj3yJbPGfTs=o$F39TW4*sjv|`y%oSi^8`F_5?{k<3jF=4%j3LoSCviD7VUhqHT zZ=)?<4&^3nkaq16n%I&|ZLJM`|@QyzacL|J&86@2fda3BO834Hx~e2Ace_+xW4_;DigS zGrhZ2KmKw+E;rYB^TY0X8}muGY7*?IG8Rkv*{Ni@GreIO^2U-WDpUT&ow+vgg^f#j zohyql(tqqW;d(Mn?oOuhSGgnKl@zM-VajY5(OB6v(1|tn1D`J1Bhlw&ZvE69FIt7` zG9uG`3*9Pc9yvCIBZQ0GI4j9*c*n&03;%QLY`CODcs)rS_;Zxk2Q8>Ce$2VQ(t|UlOeKXOE8;S|+H(?s0rUA1ADCPn?jW4Hzli9kLn! zI}vW5TVePOA;UZHyUz2w0x$P1Cwnh9PTQ_8t`AMSuEVzv_3Y93$fYSg4v{^}XbJG3 zrv=;0rOjtj0-b7#jNwK-YtTrflND6xmE}X!b6&ol_-gG*49?=IS5-F$Rh15wk2jFQM)^t3^8-l+ra}EDg>Sh<27n1#Y*ewrWZ$m-tFC%j<#Q?c!-3*HH z5vY`hx;7n|Et%_j6i{v{1yaUqZ$`eFKk^sYbbR>!rhq*kRcej`D<0QSjjM-V8jpX$ zvt*RX@{T;~f@xipM`$j0<;~G>rAT_s>@T;oMS>9~CM-YrR;-nPx2fDSeYuy-1GqV? zwR@F~mV`{+vC7oS@S9=kf>698`nItDtUp~X*ng&#ajM$1XN5tkUnjm&_sd_y{joY* zjnG3md5JgiNjz@%j2;;(Qwxh->eb?BafnR6m5k&#Xka#$G~XTPXKf>9_~WJO>k#8c z6)xi_=tz-1Br6xbjRUGwGJx;8G;rzAaSWBE3XWk|c9TFdAVl4YJP}#Hx!?#|_)F34 zcfJ63(7>e^O&ZuTfn&bn4O>T0<4!|=K7dEfI$osD1*nODvQ46PP%4kwy8uK`Bafk$ zyAcDw;S{(ydu^ajVof-hFnkz2j!0y5=7x-Ew0`2Ok)?KaAhgQzf6w_I;#O|1DFB*K065Oe9ZJPllOQQ5%d6EI5xCm9%{ z-eu7*1>@`zV7Pw7j?C-Z^M;*@`mDgkGG3=sG|8(DvfdxN?`PS!2;ilDl)U&e1kRcK$VTd2Nnbzj;vFeC6 zdj0C_=qDf8m@#XKaKjvGm_cDLT9>^?Y1syv#8t2K*Y4b_OcS)2q9S)vAGKP75e`x^q2hp zQzAN{6pOeUbZd66lif6|u|Mkx=I82RIyjue#!U_N*joJ2+2#Y6T)H_D+=+J@yR)(F zc@$i1`fpXiz-MFAPv@Z~-Q$hV$xc{b%(ftIsfHk?MkRrl5 zx!)ebSF#~>gDr=v-v;hrzA>qv>4TQ9I57rl8nex3dQ2D|-vyo%;bML9PD*YM2 zJp?05SS#l(yx)uAE4Z{L&6%Ms|LkEAN-{=*>#$9g6tOldDIFlb7}E8JsbX6OFDViF znfT;a<+7DJi{$Oa`mpjEN#K!%!2FWali~VRn{?XFuUhXs{u%^7W-gwe?w_$~ztPZ_ zTsui2VT~X__vmf&M2@=Tat$3yWQSKxT9p67?pT(FisNI7;lyT*ek^*6MidC;G%^!l; z4zTFI%ha#Z*QhF0Fp?5fHj%ErY^Pvi-JZH4k@5&JzwRt7f@-8&XwrT{)SBq!52Dqo zsi>@95YWeqQluEAuqG{H9c+KvOp&{pzONP+6e~Yo@{DuQN&-5jY9f0pS`r zJqaGZl?jZmVec2{0O=Cpti4flI%a(5=VTNuXs*UjC^fy^h5GT*emq@>8BDBM^HQ>( zZrO=eQKfbo0gK0+FWey+I})9|#0MWdA<(WL@Yk<3XW}C}MVi1JX{f4m2~lzP(&2if zYsdd(1$X^eKeT^+Py1WZzPJ~1L2)57N}wsLL+=>)<>8vw0f3}OFO)V?eex`8!Hc#G zPDDniirn>D;1ge1t36!GM%8cSD~7u4X6k@NxlbjV$i+QsKuv&a<@it8YxYWwrYgfN z&d?jDYOE}bKdkSXKSB)LtOJJbPX~}S9sgI5?uMOYs`kA#A~nMQkfqOe_)r>txX(Ty z?jdt>k`!|%^%qkA#UJrcNu%9ipk9)WpCE)JOuK^h)kOj0)ng?wB`)(Wa;Gh_>W8dj z`F;P-0N8G~e=l-x-4U~g`io{ck6Dl7qxYkoB`Lb}G*pcB5i9|9lbMpINE%H^BzM8Z znVx3=3}$6ELdd^Fjv_akxS605ywiTBIR|W-vZCd!#MEcKXg>=lVqJWWK%!St25t$SDAP>D>~9b)hwMG4>71c&Fl`a zCp9WzVU42A;|7+?vXzq0*2|Tue>Bqql?k8fY4=4RC@r-ORo&)Dp1R0Ws4(koEQpLF zwpO`4(n!OP8x0r*dCfFM_UCL4H!+z?OaV8Qm+~81aI+lEQdYgw@sTO-Kg3$Ysy%nU zzAYLJe4JOx&DHo-SUa)`3sE{uN>3ZkF&jN_OG%P zSfBYv#E7sPDDMBhLz(9*ArpUkK*SiK-Xhl&KsH(p)K1e1vint$GR?d{Ie?rILcZW3 zUmY4LlWxQQBOu+a9=EeM!foqp2iyi*D6MBE-JoRZhi&Y~Om65Dn?4TXiy2I;c?Q$< z!bpsJR3|tu`8I-MFV(z&VMEcI#!C+Cldxp#f0mv_y0}d|S0;X8G@BN^+-1>hbeTyc zvT}eKY7gm=xT+M7$L&}YUpq-ou~F$BW2e*B!tO9jk1u@Dn=q3!cmiZ+FwsNn(($iN zEQ&6*6+PMI^!S_Ssuq)h_iXU^F7|P}G(&LwYKF zpkq*SzDJmbQ{atKfvX4~`jLTCJDY-?AR3SOTory!=)pbGq6uT6cj~Qaf|_Sg^oVOXDSxXo+}bVes0>uY2zk(zx&B&Pdm?km;4?3JQ&Dkb4d5AIK>uMId{qi1`7e zc`c+??)8wX4~Rh8+-7P3shUjzHG0VEkr7CXtUeLQbiAP{Ft$c|xaCz5IG9HKKXC3A zPs3T;bzB?h`A-q-J84#Xi0SGLmnPCPJSTj&7`U{76QJmUCKb}9JKe=Z{BvxHnsnn_ zp&B}it`0cpDP@P9HJsll$YmwkZSojN)dQDJ=*b+Vi+Lh(0I*{v_a`^udCePO;VrvI z5H)R5_YZ2kj2h|lRo3UToAV~k)GWV(b45qd`I&8$lPH&V-ekv%pdb?1P9eAjvFE316p zs5}~}pX)=E)OBAN>sV;jtmcwhr=4+xEu@{DxJHMHC7TpVD!Q>KV&ZW9U znqj>P1ByiwIau_KDaejmXX|VZ_!>Dqy63N9@zXSHOq&;*rkBm9$i%%|hgjssuh;$uU?LgXVy8Ej?yVN?k<)tZSFYkGk(H{DC) z)0I!_5g(RbW-6*WE!S%W9*HY2)!0Y>)Mqd&aj#BCl^VV>Y0p|kiFFzUjC_k+SjEaB zb4#Y6Sbs8~gY_lFuF>wOR7w<)hoE&rB3Zkw(qK99%>KI9gW)yk4C#>xA)Ko}0dkqP z{ZLf@%k&B48&Q%t>n#XpIM!LhxKZweJ*vWU^Gkx_MTp7 zp+NidGBUj{TI^@;fsa8t6JHfwn=oB)my9rW*i?uBH}5k8oAtAZGUy5$++_jS&kSs; z2is?Lq^saqEOH|SMgz?-*3ou6o9?xCKU7~c@w1MJl)k01?Pl3*1sx>z@TJe}8v(=e zo#67yk>;HeC#+H2*;5LPRO(MLOA?^?e7l~0YN8#8lIG@c3yekJne$!;g<-v$)a2EStGvq4Lk48rXhODiMn!w`~BHFji0VU{?){ zlxAR`z$G`*qgecGq#;UG$Sdy(MQ%m1BRLApIC1iSlbG5-Vy0*e<_v^4B1N0T)T?>& z5;M_{;lJG{f}csuhyct>%+Vff(ua}KScxcddkO3(C8k7QGx7dMM@lz|`Alq~G5Z;l zKKG;N$@@mYOk$P*<_`3fJh@Y33^R$jmvv<^sWy8Wp@0P@9q@ZG$-EaoEiQq&3iZ^f z^2%Uax?z|EpuE+M5nN)TbdaI^Q+;C>-_GCuF2W#d$*uvVUK}n8?1U)0O&rV~gdtVN zkXjFR(jgHf4D7G8gWKJsxb&Hhbn z@gD$V#cBGw^aTJ?52z!|NdTdnRmed#GPNjQTu4sKbS$!&x zCM&ZFTL)Xko+nLO5EO=7!4SG%IWdU(vajlk_%LnnC?B$4k`BJ^whxsv&$s50n=0vI z60?W%$31v4l9z7paw*tPw*RA#I3N1o5WSBs@}j2&@?)YmONjvY%qpQ}p1P5}0-v_R zoq7jbvh$FPj;ttp?_%u$~?N?dt{cfXpQ(1*%3wU$R%e zQZ2=4A$R+BB_a4#-k$~Q%+7J&m?(ybhHW~=x9PyOp$uu&cPt`s2qsuSm$?T)Q!9ct zBd)Thvvc6x8Ixe>-(YQF$)f{5$ExC~Ya8J~4XX<_f=5R0Du_K&=SEOA##;QB!Sg7b z2Qa3JRfh@tNRfLcwj^4z#CI=^E!a2pDFzpWCl^wNhaCSp29#=AG^{@dMYC8{om^is zWkL9T!hNYPS-2d8LQwy2dR9oWWu1T%E|!6hv8D$|lE$vno{H(W+nZbl3L>~pZ*VkN z6%_BOqgH=P-3do)eyHU_#6i(fTw|t>B+G;#ZbArH(bbOw@*$*$G%|9j#k4H8`qWHk3#x?lC^tpgN8}8z1;t8`4`)@PWCh@`JEq; zU&TE)fqu}2*QB7DHf3)t7Soe!k$EjDGCZ1HL87_*WGZn!mv$rMJ2HJ6ytQVn{yVON zwoj_*joV{_Jyt1nuxu3-r3Wih{k+O|c9sm_Is8zEhdTrGr=J@NcshRhg+A6~tH#P< zJo_UL6m`ahTPP;zIwo@$J_rkw71-d(2fW!ErALmRb^f zX>*wu^|(#r?+uSww|nr_y|f&V_Bk6X9~q}8ho-gCD-c6u#4f4j5X6xGyy#7SR}xFM z>g$SsCU(oQWD&c8V<}_J7t-Wz^qVR&G-0vY+=)ub#EV{t)Gmg&qgD$voL4UV(7;}Z z&MPU9{da)5YlC91CPm|mNt?R0Udr5;^fBt_-6K**FJ)fy5g+n(oa*a%ch`I&dO*AqdG*-dU=RmFZUd|L9a)2hK6C*j!}L)KP}$o zZt&n+eGt)xoGZzB6w8!nqn3WqiW-BR@Iwi=ufjDoTy5BJBdx{$0nn=iKd&whTg-xU z8cD`pJgA%&E>Xkf3!_h$x+571|4WV97gAq7F05@5wM{s>eNA?D!28!m8V4h&$c=c# zv*0ma#Q3P(l(^q14k@q!`oEp~bNgD_T9O+|CTwN(lzNJCHv;x)|F^T-!Nm3)@X$S@ z&~_{?8FHwj127|%p(-STUGoK5cS5h7tZ&RYcf0A(3oK02zbGQV>Y&6*VO09A4?_-e>E3d@OEld za&>3Hvoa*dbrJiD8I&5ju*3LP&I4}fq4A^&2)b%6l}LTheTK0GJNprfwCs3T1~VRl z89gO}$6kQ`$+X}77WGe>{uw0wWA~-tMPR%iq5Z0wEd3SX=6zW3KJ9M*-dFGV(slEj zu6^V3V!QdR>k_jQHq+0*=VQqW1#TzKnSK>a!4l%GWIO^l0YImARSB zZk@g+71*wcK+9^#Q?Q%vsMF{eTTpjs)r_&_oGV>drIdc|a9>{Q8If*o?vsPtA#=A} z5bU2C9KjivW|7;f9chgoY;+W?hrm9D7@cLXgXy-cCfJ$y?olvXMOY}-z*+AudDep+ zws)jb36`5B)^ri(45Fj@zv^v!EQ-^x?-#|UU1r)xVaAn&9~O<@OIFm>TqAk)Jvr09 zle8#InszZsjo%f`IKF)Q`o6AWg&}zR4w0I>s^(o)^A-9kgN2Bb?Rgrjfu0zpTq13< zQsEpSTo70t&2LTozPWNX7M)hlxFtJADl}5>4>I&J#y$9!mAj!=1Wan*O%K43P{xi8 zfVqDN2Y88rXA_QG!yc~Inj?SGJZ6mJ0VrGYmH7 z)vaDE)^5bB%k=?@Jrln2L*)6VMkL$ZJEy4b#VTBNyS1ayGItlWOb7esVGu*Va4}+8 z9X3h*?v0h*^&T@!Dubk|4uPu; z;{}Z%gvtk5oO6WieXz%%$0Cs`dzEW6%ZL*0!M46C8NCx}al0S$bE0Exo?VmbQqI6t z%l{>+iFvFxkurdlx%neBSOqbjSVdm=1*q`J_)wwh) z{P_NPv$wOyW6v22AGe?Q-}D0u)$+&(%H5Wn5OaxCsp6oA*~l7* zQ!gLb+?|!M-r=>X+a!<(_n-!QnjW3TKpbg$6*Bn=-=TLt7c%!k3O3o^gyBj4bzpyQ zbE-8~jyRi!k2UY9FPzuD5NtE?8}uV(`c60GDLf|QDy1^#s*t_{>UU!b*X#`tjl=?) z0%Cp3eQ^o*>}BG^gOYeGtCm(3l;&+384E#+D$%|F0e{Yu>Cv9^+oj{ZDMlN@x8>Kh zGVF4}WhVaVGXa_hgC^%bbkb=belpasHQ)apet)z(8+Gr@6S7$8nfL?2XC9jp{{^=p z;Fdi@y(`oAGRyZfW}4DEqlrkg9Tx7kv*G;}?Ydlt{$`hFC)d`I+$F!CHNjGHhoj8c z3k59{ubrkPA({l>ZL7JjF>C8b*=br+-W#P-%8svey!u(TXS^-rj}t7|&Gj-n+O45X zL8ga?=Zn3Zvh&3_cj+9>hFKO~4f83WBrL%0@h0J>D~S*Z?n6Vb#c$Id`QW{uzK46} z-PbRgK}xKO){_f}qX?F2s3@t35wbnwe#P2*CUp zH_n5dR2mtq%^JK2F!zyAq5`&Pn@X%(lv~Gkke%te_}F^ePdu(4*gQ&+)|iB~X(wGf zGBI#vEV)Q*F(bHhxHq9BmFSlpO$*aWQ!gh!>BQ1`^A&=lS68W*`ndSZ6b0TdwKSRQ zBpFF9ZClE3cQ@xRUCa{Hd`S!4axJIFl&R`6|3;^yS8!3s?xuk_YEPD<;2ZYP*rCBr z5$ty2UE9mS$#>v9j{Xmg?`B_QDiwy*+lH5scgU=8#RSV|$F_IZN8%k6&s&LZD6>|9 zBxu(Y8E=`>o!YZhnEo--($v*f$|0jRRAOuo%6y)Ew zFR!9DB(dROOmlWKKN-BTC8+)O<@cgX2D=00W-gTS{fJ{CK%=)1GT8{WRI~tME#baG zd0KA)V`7pD8+M}L(?al#8}1+E4;w|Vuy$r99uBjCUJ+4U|L?I9!nD(W*vPLNckS`AG|}_o|)Wxifsi+!xEaEZx`b za1^@;BprXjURo1<-cPiAW*+_c0!#Xl{pfh~zhvg0NPgTog~MZZxpqV1>E&!8s`BT| z^NJm9uj}}YEjW;y=~5d=Ua#c9FVcn&aBmR6FH)0gNo?`8w#TP^Ty?CO!yejdQm@Fb zA8T6AtRseyc|pclLTuU3Eiwf2O^9{9xe|GZV5ddtZBmbR_I zL2icp8eXdVyj9(@2HI-U@wbAH81iiGXQO|0@}thfQm@to#0@2GPt@sMo-MsU#;@L& z1@96^UjFkwKA^N zob@N!#;2Nrt0x>CY^I7e?-n4Yfs%^%O{CV;q&To3tX@NHyXv#TC*b%>IIcQ5uEdx+ zmu^WNrQdl zWj|c;XVM_>yAtj6lu&?WqbydT>Hc=FSF%x@ufb}eOr)mIRbyuU&Gehtg15*tB$j;L z(rgRthz{V7Yyx~%0bKQJ1(<_5xbKOhZ(OiDNofwZXZWUNFJoE#L+SX(NFLm{^wdOa)kx}x=)zoA=)r!*Id>u} z;Zp5$4dkAyVOpY%#WnwwzGnsrk3~av+!H3~&6)oAt&4%@shj$el_2c35g| zUN|)x=BG$1G zEE6AbR%FyO6Le?HO7ZcCM2hKA97PS-X8T1<&~8HZs}~sk!XvT2Z8fN};gP}^;)>kg zJyeyIwcJA;xlN=jBYYlEZX1tK@8XEhWp9;n#b3o1FWlLGi>S@AXRuI5=Y5U%puuba zE8>^eR|yiTp`*B))F8y)BqR73afefu^?$i4>O!TF?L|fg-he}+wa0d->!jg76W{kY z9Shk2PYN9RezAf5Bf6+$9C{V7Jcm|#s2{5%g&BwL^H82c4|u4GtvhmP8c^=@r>&+- z7Dme0Ssbccz=uEqW+xHo>%RFlR#eM3SWyN0$^7Yf`4}nJmT5a?%UATv6WJNH-;##S zF9|HhO#IM)1j31-G720e_ZX3q``hkToCij;vR_ViQ!bfC3guE?yIc0n$lbE+^VDU% zk$t4vSN7KGLisX;+(~!&Qqcutnfo&cGgsk}J1KLQmbpW}QfEV51G?*kFx*ALOb`TmUexfob7411A-2Z;1<$emfw6jH$arI z=sjJpS zO0^cACc%L5^nW^K!i&j0T_R$F#22|U_~2etA$U=k(4L&P`cSUt(TMPuAnWum7|GZW zpFXdO85cGYJLAvvE*h;-@8LH0cuXpaRA7$iAD^d!(N=+6&j>|@dkZTvkP&b@^*JDZ zRX_nhx>+X;eceL>4QsHH^KVBa~yY9MudrUl$ zwqTXCOZhn}VpNGJ3kE5u?W`~7>dRjAaQotE+gcxfs}FrUWEn!hmF}WE2Mlu8ZQTBF zOYI*JmHeDi&DwGeHGyLkbv9C?26)qmopGu%Wv#2?yw>&Poq!aMeL3Vm!)=;tSv3^# zBPn!)uG8qpIL5(y-z!JMQ}V;5N5h0ZiPT_z}a(^)3LC4SDu1?7yfjR_m3z7dMnh3L_|dB-Cl^mWazDvEd~Hw@n~u4+^{j) z?Y^I&!L&?h-Yqnn@(n?9sc$B`|8)RgC1d`U*s{FP+@)NH2gI2zVl8g`eA)Qff%9zG zG|t0x#EEU^IwI)hYs}b~cnsXw)cODa8~s`<{=cXHaZ%Fc|CIj6jDEU~Ja+|o4`jXmHzs_tLz~}K>&VEF^x@_za`$!>PFm<}#Vik>)ATG!tYw-R&GeQs zHCQHjky{7D3FSJ;fa~`|1s(F|!VvUE0Xc4xf+XnK8?@HXVJ6u3LZOR(GFhA zEi`PGqAuyk0Xyms$XD@=s^AnX>%HIVg)QZfR8VPwekyddE|-3)?C#Dj z+5>jZz3%271&Rs+jUXsyQMDlhkJ5curZq<6pO%uzpKy*)={$zgqTG7@6z4v-QcM`6 zse&>)zPF=4Hf>liUW$eRA;qy~3&YhWA{wy*9cUv(nYnoUkm0vgl)Ao;LRKdJdNwk` z#>JR&tUY(MOwCNZ*U-oa1s~Y|rmy|Y5Dgq-uJcnQ?cy_hJEUWVmDp;oD98X>jEt{p zfcr$I8uf3K;Z9|E#SA$cS;=s_GCb)sJi1Ya3Ci$?AOq4%hH=X9Hc4)=tdLCnss|!u zN}OHgeSFXW>sHjzn1A@s^7d2wZu+13{nW#T$Xy>t5ZOtHJRRCV2;HQpzm<^u1`7y7bM#Lf;z=5t(@tOEVr)y`d42r3A z#hZobYujqf!CK3gB-Zy66!TrCTY9C2{784*k?8h>jj*!vW&=oQ+MIC_7m3wEOP0HK5C~gCN{LM{{i9vf^uPG zNKlEJu5{M#!umT_y{9{YsyWjyA^$*e0~T2Pz^D9J;Qn?QnUg5t5UW?+Mb+>|@lGA} zxA>ts(1N=>rEbnA?b`8RaUbDg{3~GhruMb+>V+;>cvIJq>QpBGC2jK!G3rsnC3N8otfAA3iHMFgCs; z6@qDR#pq;^InGQ|3a3@M8wsSRgv;*e*nct@Gw!j6Y$nY~&(xhpsk*yJ0sevLg;};E z>omd7@bEa8fImg>i%D@0`ASZ{H&V$ClKl!SM%fz`yr6O7y+nu%i>BooZZh%BJ5ol| zwz&&$4ke@t#N}M%htVwUqX&I|FgsFSoI{b!_VM)_ZaDO+C5r z7HR5l{Sv1eOiG-_M@Vvqr})r}>4$3Y}~P$ragq0<}jU{eIgi zEaF-25AwP7jNrE+gkcR^U zi6_RjCA|*5^)l2jnYpyFg|k!pyqQ?O!RCv7{QM?$6yIzPMjTEea{*nS5P)=TFyH)c zJ!Mb0m|4%tA~Tj1b{FhaE_KflQCYx+!^z;!k~|gmWQjADDbXA~#Z)`bzXmaZX7t}L zv=0t63_T-1;#|mNlx5zXhC+To?mz zxHCYY1`}yO)~~2-oc>JG`dXu^%mgX5YENhk+KDkQ6aW3M{n*d0emFB1a5ssQJjExQ z_0@XK_Yaz>v9jl2jI~&^1()OgfY-I~+ScH579uy|-AE7HRfWBMyXfjVdA7(kkGW=Q zdLTErXnRWhbbXbEz4B~{Lnc0~r3Y;DgR&80d7#L=9syarFy)W$sLVW<@w{E|T)}hC z;JKf>o85q_Zj@S<6-Y3ljZ z`~hM_aA+o>-mD!wA#WahU-Q z5I!_X!gOBzGS!*t(P%%%m)A8`E;(E%bx)+WJB7q7A^(aqI@$n&T3j)etJpfpVj{~@ z9WeREP~c#RdpAZb(i%)${7#Ey>1O(N%NHV3^+^HD@c{kxGps0E#BcTlK^vhe=LUh< zePW%n+o7JbkDyPp*8t=Gc7*gxpk5>MZ~A|5UdH3{5_LE)Be@>=nPu*yU{7|}vVMSZ ze%Nsmn>Pt(o0Q0GH?)XTx?2}dqN`|$zR`Z=3rq1IYZ8r>b1F?*`m3x|ZHeC*)jKFz z@Qsz1c#xdDHF)~4^f}7N{+6{?c`K&1irV>1FX-1;S?x3Y(Pv=d?Dw$wvZpDv>nM-y zsmFS3r?yDFfhoZWy0`-KNH|lU0{c9&wT+eQ1{t!pPM=41YZXYvlNu|R`S1V0&GA2A zT7mrg46}WP4wzo1)UIaY^ z$R!HcgS;W1$$#f8VZ)ytW(>H>XXt?Mc%^pzz~kGgBfc7uJib>8S^fp;+VCCKSb3c< zyVS}K@%`S$4SyU{W92vxVtcUvJHAzol}Gpt90?-=2e2AI%l2wi<+NBY?Oe^g9iURC zF>J2Autie}lA#xoR)iFbyYd@P-O$MQSh8FnT2^yr5d)Xg0*-0kt|Ut?2^3QQ_{;{C zCl582ao`mwRH5jj>(F=Fcrd?Li9W7KO#RN6&oLyMDqjcpM#?{i*T%|Iefbs2qVl=B zBP4C+o>D69r2jkV->xOpr-G2cxX-S0r9FDlzGCa>U3-=0p+6gF#P~f4RVBWs^co_j z`AP|>zFu$M;)s$uR5fJgFWXvQSFoFgC3kbIjCq?Sa`>1{tw@~)uPrdZ5s7a-9TYF| zmHKvq!tf~1MXD&duq>eDI1hG>RWC+FuB;tv+BN>k^?ocd-AxnMpQXMq*UI658iFgD z6A;^2xw*<}*tbSjKybf%%O{vCy2P;EJ2LT{>>h02-t2vrvaL{zt#o>Bk&ddF&zLi- zCR0Ti33E(?*vufX$+9Pc7c07)5ZcxrWHsBBH98=aHRa=MyQ(|m5?O={1&^Y*+k-y> zc=iI4xpQmyMqh8#*WLZsHq?LnypyadoWR+Ie4~JQ`e7i^wO($`#X+SfY?Sec07pz5 z<=)-r?iS?!k}<{I7v_GHH>%~X4KYE!=VBo>#wWA!HB4SZh=RB`D!U8cz~)E16$OMD zpIvJnWEI~4kwc?>;dcU(J>4fq3eN;NM`nBaoS$QOw=ev>JjhbMQTQbuB!c;`RQNGI zIZ}APAZKm1i_iJ77U=U0FU))7L0b4m;S)Sar0_MY=4Oxd$&tcWkSw;;Wq)9bO3rur zX-^-;*bsAQbF-TOVI)k}v<8O_?TZT}PS=w<#U^<_FbRE$)r& zWgmC0Ze3VJ@2DwmO|-pI-L|AUxvs5dHzsj6*OHtV`2Bdf=e5#wvw9IzB1>0@luTU@ z#f2=y^l;n;JsvTLEtt22S`@4yH`7Z;dZUwV+vw@Jpy3{`7UiOxTPiZCd61v-yQg3vA9UDGst1H2kz6+K})Dx3ape3jvtH_cw$ zU7QM&j7~}@amViM)2j^BSDG|_yz8ABSfYLf0B&>%f{dS9>Eneg9+{(1G=(>Q`7kwJ z6rr4=HGDv;d+9A4eTHWMTFYD^b~%0%<9UUw+>z$-3f+A#<^C2tX1PVo0;gA6u+CP* zm3am>Kl78>ePI1B52l&U1Sn!}nmm5(+owuwtCd!PQO_nS8=-s3=tQbJcq;(1RbZKW z{HTfMl|RscV#z=0Q#dkfu1uqpy06hm(xyR~aKW!~NnW+TPzAIt^kq!G$tq&J#~76> z7CS(NYW}E^(3ki}E0NvlL9y*i)X{FJMEuztvwvkqt?u#5Ow}{ru+t8L8in7zucXZV z5o-E{)I6n6?WkFi=z}eSJh|OEU_gHn#|9*dTdeZLz~$B-J$?N|AIMzg4;@h53Tghe zJMZlui4S{4{6VJMch6;!{Wpd#?ZO(0|upV9DP@a+knM6-1OH z17*Zb*sWN%BoDy z9|U1G0GB1T_)FvrgjA`#UW=;+F$eNfs&iYb1{4*|NF1sj*Zi?jhQ85d0;#&H#Z`wF zwN@P@ECm-c2nX#U`gP7+vmuTEj#v1$%h2EI^ z0E<#FDE!ED#K$o0V6G27tED=*e#nFoM`p%0bN1Z%(2oN#6Mum@W8$o=#kck$zE#IF z5o%pEqwetZm@cWhgJKKDl<;;$B8~GaRW~mCFS?Ao<99;N-D*EnHG#xX9~`IWPTA=) z_&hb)-|*~q*&n5_0ZT2f6gubw);XjPsx+P>OloEECe!!qyYqWoz=0VY$_ZsAZ=AFg z=fdzik~m~VDxXSpG6KMw#QA-_Gut9)a`nGNI!`OA|G6>|%6wX-w)xnIN;#nq7U9%q z66hU%lX{8U_N1Vo#X~Bs6~V%yleJ0rSNlO0C+b612YTN0^t9hkL&+FdUbT(gG7>LZ z2DCew(M4iXVckRx9&4JW51(^9SmA>gBq^|z>S(V$>i4DR7q{>E2>oriL#-2uEX6m+ zGnNvq44JH0=_~3b5-}hNPz?3|>aaPr@x>htce6}=3eDM({sHn%*m*PBv;~r*!g2F- z={)PqJp_|EkCA;*I81)2k6~Z_RQ!@5l8as6(kSJ%jd>L6HC7XaZ<|_lHBBc@VbS9)UqMEXb{WUmm$bl)}{oj#KBWG>{S5xuSkmmpOz#zqmB04z z+Ip|Z#dLxZl^bML$@(U%WP^TG$xVW>N_O*^MhBT}>T?1wu>}`YqQNQ`|8h{V^$dE? zNb6r}R}1Um4?Qt`0ZIiwl6y`L95wagUkvI*Yb1PY{36PdFRg(JEJ@i0BeGXuC;CQn z69%g(=*u=Ai&uKo59bH7&al5rr5N^SRmev%S$8R5+XV%Te+K*F@AyB}^+%bMm@)E% zCH1|p-4~OeS(dbsfPV3-jsm)FMnI#Qp^kpeNlPiTA8#e@zzyDzs*+Un%butH{=jG( zkMJaD{far-of=*&iw2@1%MuDwc8biv$(E%6^A4A%2Et~(5F{?Us{oIS0M=93!wKQ_qh*KjWnvAwwM_LQU^JXr2m4DK$RDWmerDt5M^o3=@CnR~_Nsk}Yoxy1A0n0U zs6N0@sAW}(Lvi>yH4!^fqXSn=;G>@<>b@%s=ta`h+4{Y`nq`k5_tg{Qf zuzF*-V8!@;Zi)u;Onlm}BBOi-HM#nmd;?J$X3E4H4D5)m9lPj=0E~77Y*#$7l=j&A zNU-=8Ds3;o+%?pN7OU$hjeeY{lTHlBiM@tPykUq4qC;qOkR!p49I|HCz#qJox*d87 zSxw&4gQE(tyUL7=33&xbV-M9_>LmUj%LCpDLg0@=cMrNuTA%4TT7Lk~oOn24f7IWi z#>%tzkop6qE$PTPBt!gW((dMcalJ+T~zk#9)O*_uI&% zXv>LyPBBs_C2T^(xK&@3NMGTnGR%Rrl7FwgNi~37VMxG;Vk!cUiN8S>#b1usrMIU# z<(|Y-bwg+nT`Y}=W+c!mZ}ZNSV%vwch3uZFDwFbd@;&ibAw>_8UxQJ$o=v`fI0-n( zK9auOF168aOMcWMT<$m_mhcxl`p|8n9|n(-I${FwZN1J_I#qtU%3%T|j&%r^cC`TksEoIHD^A74N`LNyLG$6xx;u0iQ%^$ zJrfT_H?ZMQ5}WDUa;u*rz)iZ#m=b=gf(Zh>EVv`>)ZMV-HOq3>QhM&ecICyUwTKrT z_rFK&_1TX`j719=xOb}9M`vedP^^cDE*|R!wR+j@M@yFdT%$OBLh8ka>a8p#%pzfz zEmAC7BqDfB+pUI3!QEW)1qzOu=AVQ%dfNRJBD1?2<2umyjn-k4Yez}$IFF7^b&a|P zr%B0NJ2>E6P4%0#9E!hGTL9~rGco}=1%Scnd2%&qv-oDVLaK9P%{8zN3%(|ucMSxo zD`eN>(zFZ0?IW|VNkw>c(tUq8NUUH`$g?6x3g0ib?>$yVzuQb@5h?WEPUH$rZ%qd3 zkC!CZnSB^8<_%WGHnr%dr@&8uS`PuXR&qGK$eJEer+2X)!WhnIO{h^^Pt~DxX8UJI zZP?l!#!i?32KAFla1LHoV5)n28R`|ZahK*O5#8wRWo|^2&cx}V3)lPZcZv0({q>_* zv-6b6_w5ljs%B$N{mI}r?Q&ASJq2CWq&D-JpX8;na&Q0TO4$pk3*pU3C`5d9HzPq_UW)7ZS{*E6 zAjU~qb0&r9zIRTtmiQAtWUd?BgdbW>Kyd{Z#brYUCYOT&4I)G;(e`@T8h za7mBi!G&qqAt%K1Xhu5Yc!^E&xlxPUfYWSr>y%rf;YbB+0g5tlbITZpzpTj&?&a4T zHF3Fw5!gCtZYm40=c5G^scnOm+|%uw?Ja~5gR&j=0BX;r`}?WBrtCwE+`;^zeoH@h zu!Fy;j#I$AA&9=P;%M9KZ#2?hZMj{_eg-o=x|&hHfShJE?^*zBF!LFg)exWP#9;U3)@>Gzm+_t3A(lU5#LdXXkRex{Shw2`#-n4V*0q6xAU%KfiXM5lY- zeq^;A%ap_|^RJz=Rnl?VSA>(UGvs;g!+2xZ!}p zNZj-yiJ-E$G%|naWAx{Xx!Z%BwGl|qJV+BD?v5QX3O)(0QOa9X?d${gk0NcQLXYsu z4UJSZVL!RQnH^_{lqmFAmXCvA8Js1H+>Iw$zbVSCGU)Dw*>oAS|hD~LDZrH@^O5+5kfJ{qSZdkgSDso-;I6lxn8Gnh%Jj?8mbR7xX z?fx@N9M%?erUs1D9l`Ofl$QE3aKpi9vZVwaIi>+i#D*_8Oh!3)EBdIP)%%9wo1bsT znn#;%lfOj>yOtejV9rsCn#=9&<=C`AHh|0ilkrBE2v(Qi75k5#{IRY7LY6vx(@$y8 zR0u7ZxASr~BId)VD)I)^Qhf*|;%7FQoa8+Zq45MErS5mqst6Y}XlgD$)+*l;#5nm% zC#NHo7Vy)>=25@Krb_R*ap|^-*`Cr8N^-w^+K&-s>G&%<1c$7x(Qt{ZPn=?Lv$<_W zz)1JR6p}OXe}5F|=2&T*M>?Gk+~6}#Y;=z_8`x9NN5H75$fX5l!(jHEUBMcH`#FP zzY!@Pv%XLuCEH|RTYnS5(Yy=`1qLaYnUHdA(!h59Dgq|=jGGmJB@Aqg2YYT&1Z;DG zjSs-83~Zk%!jyTFDAVAvj18uwu5ei9fw+ts-CE(a3q~wsf+)c?vYB=}Oc@N@r3LO=f@T z*jhl+{hT~7T+q$it->y@I+RX~NBS_*t5h#j8@A_HCG?!1QM6W#(z}&ex45dZXi@ z?)@(Rb&kGHPo!m}FpsN0z~k_Fsj;IbHKZhak+iABhK7ar3$vSZ7H7|khN#vDc%Xf0 zWOu7Z*-ZR7rpBsRZVi7=llq5y>i42MSo3v9E9u@K39&#@2Px^MAc-PL>Z7ElAgRKV zwpUUMNfv)cbqDv3REKp|G;EN4ACVbVR}FNKwSbGW_h8jz(Kby>Bf}YUnE*{ zbtQ$G%Dji}oA-mSSw-hy!uY zXd%fSZ z?EsJ6la2iOc#_&%E@CKl7c1$tAPIYhq;r+j5+r#+KTb*a2T5MgtCW-@$-VBY+jYlC zbtcs#E>KNcB$_Y1{N7eb^+`O1;@n=}#ip&43~em0JxsJhZPgqElZ5j6Sy2!UZ4!Z~ zqMhF8Zld}apK2_~+vF0{#{|=h+rxs9xD7LIm?+ktV-1G9-C$plH=R*H8;0^W#nMs1 zo0PXF2?h-1E!x0$20?-Ykhh}T?X)gYZCG07x0)V)%+^bm5TY|AL}s#w%IvH>Oh0}5 z>85|N-kSd5DUr6=88*0O-D&!*c*-}uJ#-kK_Uvr!Z~KF_uLd)}%4>)&`jVdS zz1-Q@<)28irRRH3H`iUgt9N|cx_KdeYr)&S#(TS)&Ncr~vwm~|1K}uikb=iM)?}_H z8S(>H#HLTR(&hQ4=z3lP?{}_rqz|Sb6&v)@yEs zfJAD4pAW+p)jeHb8ZJnr1_}`y)%@Dcv0A$sM@cRZIs&jx3=K8|rlkWz~Q$8yH45g>k3$EN>L3OdB4M}SLgx|Wn! zGc}FUH9L+sl(`N(hPKo76PU64@Z5i4_F8Gp_0_Uwd25n2+d2ES4B6|ppg%obFl2*n zm1lp#;&&gFwCaA!O#Gu8eScy^(pH-5O~MQPiTh#O^{4Yq&VRB$9dwrUr-SvQ{&a}I z+x4eitiYf@^|Y6uKXu_H-=DsfSo;3tBPXptZTD%UKb0Xlu5+F6t1s7mh24Wt)1T^3 zh$sE&!@FQL{mHrx#!tKcgc{5DAX{2BDL(4YlBXJFVY;sK468U=)AxhJI`kiTNCyQA zn7{U&;DHBxCn)s!|Igtf|(dp6yeOmA~@e?a=WQ=L1oHtzjhtAPj5QMq#%GXJ281 z!mcExRP5{V!Dci2wPB7$jMiF<`gu1 ztZ9a2>%xp!lcN&7W#V5A)A=KKg+vOO8KT?+Gdaw(a(HJrg*(otV@*za#CJs9ir~BM z|7o{iY?!36ArW>7TVO_W4lp|@zS*^fHntXQzQ@}B(`&rWgPK(d+qlWR5l&Rt`V>z# z@-aNt6SYMw313+nxwVseQmuND48I|bl_^Wvi{(OMS>rdW)Ko;${)(gtMVJeUOf-V! z4Az6){1uE`FJkjOUg#?~k!B;7)KgV%R;oDH7%KjMBl46`QP_Yr+Mtoftm3C2TIV?c zQdR)@WgaByzeQ$1`{chR_~uUOOut%?A2;$%;>U|mt*IF=!p4KFl45rk+nn~EVM3jj6yA+H0!$amD&V@LZvRlCX zojcZc=)Ke?RNC|XK%#APufX@G3w+Dp@RQhP`Ai{zy)0%6iQUDBzM3H`!?I0j&2AlWZENXq-=-Ww%!@v!7Jgk#4N*bpvZV&BQ!g-ZfQ9@I!~v+ot`PO|na?h7v_!f555}npr5ALp`x7EA zN&mIdDHpwoUXs*ote2RMhFv4!Deb%wrJw&G+Cxf(j#-fTba~__c@dg;G4$1O9)2{fr z!7EkxA)f}*;eHB3PikXja(yRxV^v>i?n=s^d{u;DHtjz0G%BX}GCR7^z5N4Z{>1%3 z6BC-Wm2jp?>q2A#L|;!7vuXM$?1c-E{2$6L+LamUMLXFdI%207FnCBm17(G@t#yYT zZrrS=n%o^7_&0F`yhFVhtvGu*OUz>5_hzq#wVTFwo4ns}sz;iV7jY&~1p$<>dSSo( z-m)alXBSf?bAGzLHmntmY@nZS+7de84-)asxL^;e^VHMDZFmY|Fp8C5m59 zq`pYBtl2El{|ng57Wo#SCKFR~UvNdmvP7|yJ>Bvl&@C3*nge>N6o(E!@@sG{Zp%df zRn?DGXJ+>R@ z+<&~xerM)!_`q-o&wC1vLr77`%<`-CX<&9rXDKP}zL;yEGWoABH@jY&1tJFxmAXsz z@&R(S(t}m#JGdK4BkN%4z5|bz=qN_+Y9=R&(i%`bb-kCJi%4OA+Vdo9!Qhy0tshkj zP74O{AC3ye&Z3*BVL)Q)4?gd9K*@#BShPLiH&Wa%H!Kyr+ zDi5(LCtEEXm8dFzXDp47X@nbP0y~ok%IA&{ zyTlh6FY6a$Hf*VgqW!*Qu$qN~F0bR;*@qL)G(Sm=;+%97dPU8^zt?ZZlwpAS6Jxv7 zX)iX@aIwk2^-_L4YX&ZvP+o0kMeU52E)Sj5J&Oy0n*5gX7cX+13`aNr8+3kZ)Ah%u zJt+~f^UJ%wRpa$M=LOtuf@8g~3-^^Ozy>J=8~#It6)uhfO6U!3%o|HeI$fKnC;!SL zGre@(0RO5-i5Svfm*AJo1bw8m(;1f*$Jm6cz?)bB9tkc;zD<;e*s3oo<_t|+lN_Dt zUiumiGhqlh+@8M#@2n*>IzH`d%o3E0`|~Yq4rgbLjK~Ya!~t^<*W`00i`=D@mU}YK zEFKEwWtz%4>>{|oYP$N`)U|d|NoF#)N}agSb?r^Z$3nxjk%Q2JD_fr}6Z)+!{-;a1 zLMIZO^QOB^Oj@K!%z@^Ok(qW^iWw!Yc7)$BTP8rc^q=`EAmd-N)WMXP{GK5or$RH* zHl|iyvpU|2)JkRWkjr=qwcZz?U<>sH6fjr{D3l>e6~%59K~oZde$oh4Rs>@45!X`$ zVnO5Dne|m_*BSbEa^i3l9eliID&Ub-*B-v>bZe;Ky_&7N_P zN#VOjNZ`B#;VaP`Ae~(1@fX_@VeXjlH_Pn=>g*8Dg?#kN%ZGV~r>?bzh3~pCNK$cG zcMXSn<3CssulyoFY}+B)rlC%T%jD9-HDnDCGc4yocj-ZHYhskr7~`h%aZ|*a?1ZFQ ziEn?9p^}HqT}tfQbEy~t=nGI}O)Xi!MUn{zW5_yy}G6XQZEdsSjhXA5Pd zIpL-GD805WE)&{;P;(|4LGr92sU*{WP-;a<3rdb^l?nTrrhKG)q`lyPmc);;7u23R zY`7Ql3JG}?EP3nmfF;G6@gU^tPYC(*ss$kjA&s5)8zwDf_S2=DVIRccAHURjUr@J6 z_w1l<89HF)>&CC*rTaVF0(t2+$xI>L^+75U=_Lcf2n1J>b3);BU5O-K?c^m!`eyr( zhIb`zL2F2SkCgbX!ne$EmN$yC zi0CBpZ0p4eorM6L+;4I6b24_4IAvqav#oJa9q!T-$-?=y+iJ244Qe3GbzQ@mDk}^g zJ4A1p_@qBX!j;sZ?x+9^;ehE2&oHpZ=X3H<9tDjnqePQyH(YVvJ{U3>X; zzvJ3D&2eZX+n^|YZx5vuVE9t7UD4-79uJKhj>YM2WC{)e``;VEtXKqOM)7C8zCx^J z_N)^0NuLD_e(Xk5D|N*6AbD%lA?SGHjON)aQzUex&c1@w<`I$LjHxjFc1sULq5_dv$69+J5~Wd*kbHO~j>;jtZyslujK4dA zi3#sAJTLCBJSIqfL3n4c4Y>FHbtb%tMQ-p~n6GuIP1{elp8A6Nkv~KI4~|JiS3*bR+dqHA0~K-kUESNH^d@abr}j_c+#3~>>1EJU(c8OHL}eSEBy*?3n3 z#3+7`Msd~oGTTvnZ!VyC3r{h|=h3jw&H*Y=+(Dl{E)NLjd9-$IL!IhhqE&}I(Jqr| z+}0M2SJf$n92Ye*DqMA@1e9=TZH)Fwa(7ugUtmd4SSdv3UG#73rH1~X;Nk&hP zAQMK<^X5lcpdl-@o-NVTJV!d!a_c5UYEGtJPVHM$oM-Trw`t5xwhf6jrNo+dY6TYm zQ*`ICiPwsg`H=5{E18A>_TyWTzOO;S-6t@Hj3Ih?z(ZBs8EF7Dwwnf&``lNx)3Fi9 z*Dm^6m%tKRh%gA2<`@#oe5j|&BHDV&3DmpT7|Ms_-++OvGz?`Jn~c_cHqr7O?X`yX z(qm`9-&g||rhYe-LSo6OKF2mQwloi!6*_soFMRUvfF2zbKH>OC!M~PIV`@$qXpff8 zv~I}_wB2OiZ?2R~yr(+E)bBP>%Y-trs)nwOLOc`SE+}*SeeRM9Svzim{m4Nl0%z_j zbshVe5l(we`2|fsiO8_()I#5WizsNsn1#K}sLJv6S?OzQ+S{!T1S5TZ5hGrk<(T|5 zPG3khm?;;4!!@Shy;pn4ggOaBdS52#Zh$zVp;6wf5+>iAYy6%q8EZ&EGrmdghi%gG znZ$U)p24X=RWlAu9oJ>Xa7M@>XdGnDSA8v$0*=ACdT*mN<$o^sKfm`s_5SC4|8uVW zP|M5WA<{VE0ML74Xlf<&(0)>lO5IMWlHf#Jt7(jEe;ILm`%=n$Dc`Q5D`eNnJ+W0G zWl{DXrTlv@;S_Ez*a1~j-Lm0`>XvL}b+H~hXBWujmfTPpn|U8ks20g}cCOqPzxx;Z zZ6BTr`V9u*UmwD&k@Q2+V3mktaXu^ttz(Q@5v2S6GkUitmf#{MDh2g16Sb@{`T9%Q$R@N;fr(Q zS^uy*ic|09p6QT#Z{=>6HMMBy3_KZ(;M-QsVD=$($?g{P7yn;3tp5vk&|;pzg8oil z$Wf?2D!MAxlu^wY9Me)Nebyx^*YzqYns^BwfVtc2%Ve%7QwQe4*rG2J^KsPG?7ah> zjPW^81P(Dn3 zPBkuaul<9jIhszC$J{>@@YnpejT48-ys+E?;F$~dZ%*#((EL(0G_%;N1F?!r`=M7)~QO+KSWHba-vqRLYcgG zhBA?CH##0DL46)PClxnQ?^He=?FlXn#X1Vdg$lP`-2Yj{tncr zt)^+BGSE$!;)WBfhrC>WX+->cgNge^V3whu=|Mw}F|gCFjtsS31h#VkMm>PVJ=l%W zX@}H^`wA1#ok3l6z)ng?ZjDu)Wa+a4A$Y zGo(Ysr_mtdxT={f(-U}4#ig|dcGFcIsW>43^HiMZ!Inj*6h_58DWYiyeK z!!rsrTJ?p?&fPhi3!m_+^!w-Xy(T?P=+&gJ^u#f#Wo0P12uH{a;YRNc~|XnaMAq(OBX9J{vK?7EHXz#SgKS{t+2%7Nw{FV=smTK6ucaf zufbw>Fv>{X1~BuZ#NT;WFw!f9&c_ot&tFKrK3=A6C{Nr67@cFAlK4hLFW|m=)r~N) z533?7$3hQY3BX_#x@52i`|gQIXDy*FH!lG5eR?Mk_Cz`Y21AIa48Y2)w4@*A|9w*g z%=+}nfVtFOKe4w7JP40=Yw9jbxBB&l-Ggb5DqRIv$(=ZApfSz*xL->zJg# zj+3GUbpQWYI}vO9k)Bl z^|)ci7E1^QAsEJPge0A$ZLu%G*co*-#x7yV|NA@jJoi4gJ2CUV@83uId2T(moI2;! zIj2sYsuE}eJ z7lI1=ZTtti?42& z%KkN8*1E>_iA`OFFEpuJp@a&ZZH2-Z(<+gY4fFSg**w>5N;bEqwI$5aL!yc1Av)&f5qt4%ntMlN3euh`-LSB!+rvZlWm^m~ z!@|xq>2BB8d@ZwmEurj1m2B$DeDNE*6<;nGPvWclxWPJg_vNt`dI-<|P!?-Hy-24$?zdBCertlWB9!HdTBars#8oykVu++zeu}Y zxK4eYD^-W$ZjO_ITDX?v;LbDN6-wrZNelrOHy7eaqZ2+E)_qi`K_h z(yNQNK=cR-cc(CrCYsb;SYZf^wpOIO z19`Mhu4avPi=qm_|9{-k5V5k~aI=&4(QDm1S}o$KgWO8o%*}hTHvqGS0GH;C+*iL5 z0mETnWt$g7QK5gQk9Nrz?dx#cKL24y1yVS&f$hY$(^m?_h7k}6la}T9%Sl$2IHBoypU`xKX9}8ZN)}#sHQRFbdt{ct ztHQYSh|K2$IEt{Z3>!3`kKwolK(lG9XXnTKdqnA$bazL8J`6!ie3?Hk6|8|C?cq-gO_9mV2kF-4ehn?Z zlyvxv#tb7ZrAqEQl&$d=qC=zDJq2-Cmy;h+ctnZg; zcS%FP_1Imq+{e02B*{9-sxPnB&}bzP%m!sJ7g$gtJZ_xwHLoF(S=wmH;6@A+@7u?V z6eK_S&3Yx!-;6s|0nFuks!*dUs!%T)ltS-D8|B>&_}GcptJB$r*{k`M{^j3I_hr8M z;Vla6TiL%F^?@%7l`sWdFkb8inNaj8tUZ1TnUxUu1PRuVw0O#EbCD>jjg5 z!GR)0hXk`{_T*jy+|6U?H9S{lMlRpc1u$}OwZ2Ot$oGct3!0YU<_@$5jl(x1FEbRF z{XD;w!82rmA0@BXQ*%yYE2yl_B=>zDv8a~Z19&PsU#3V={>0>~ghXD0t1{qxf%uq=}8EkI}5Su>gQ-kqgemLo+M&;cZY(N7Mb#(FEb$Qu| zm-GATg`$|&oFPhHMKK8Gk?pPrFy}@ThMsj8U~8BXw!I8Prt9@6N!V;t$Pq+pi)SA_ z-7h6t8f9{UL@0-SswFlAgrv>*g9K_>Mi<(YyWg;RgD(~QsNz{ob?#j&9!?8YZm^Zm zn{~5Xd|qW8b|12{47h9B-PNqIF}3}(J-XmK4ODcY${p9c2ho;4CxE}X(Vf6U@R4A!ic<0;i3zCjG(h#ehsf6Fa(4+hOJ)1IX+V)pezmi9D}<;) z2aOP$XkteJt}UM{(#W3_Y?um&OE3YY0U0i+!`|{byv6n*^^uCI^R0(1#2*m9CBM3llJpVz0AGt^b!^8z&#-RX%rOc>M3=TH9FCt^Cwa2nF|%ngQ>U1%uNc z_F`xzTHjC}ixC=&jwZaaC3!Fa{Zu(T^JHe;@~7sg()6;bGk1FV;}My8 ztgdA``+q}^DmASp*7xp+RCI*1`=mkgi2H!eC9p;V2aFTbAr;aow=)!%35;k} z1m9uwP6wL%SFBgUcu~JhxuP_J=qD{iJ~QCQmai}su8o(^j77^3BBUqZYxh__WZe>#OV*%`v2EV;fBo!oe234K9@cA@_ap_Vb^`e9TsTF-kqHd@U_ z>23ZdV_+|Qj4jICH{Lwyb5^W?4evMg0bzmJfUx+-V5|3_)>t-C#ob3Xw~=pky?Co2 zy2M?94zzLUwtR{%@17rFMevW`7ucaesBy%4q9IS|$UZz9c$V`V#aRbs=XCC!y?7b>@G zft(8hk#LxdWeA2m&fK_Uj#SmWkIPp7ZuOrt12aSWbPTmI8;t1(?;~vcn1+@@3C8py zNj*{z%8^C=U{srL@vJ0AiF@B{Evyb;tCI9v9c`k14Q>xc^@A(7N-sQ)Lk9a&VkFxz z6^g4*y)f0Po7WF27(_4*gQ&R=Vd}IO74Ajh5mCv-QAt&!hOHWx?to6u#aYv^SfE$7 zwK}C?WA^_qpb7imA_=hDD=hx|3lPRYgmIRH&+Dp%&knW1$YBDZUk$xrjuQ70o3RYF z*IBZT$qD>x$FBVjmCYFbOgvb-PsjQQm$4PR4)d?;^SXn7-GJ9R|GFWsoB7vDUMu}; zlGnBU>qfkm`PYr3`a5>5GWhbXd)XNN)F=q$-p^zMX=M^sJo{KTuEq9643@(*iMH#> zA-|@2&3!_egEcWKR~scQc^$Fjd?o<8jwf2J#2s1dyJ;WP5RK}ii842Gd$OFf4L`HV z?OuruKrF2ix2?Y3#aB07wRE&UkF}cW=xGn?F&M^H5(?a)8Ye9fvD(v1*G#llLB|YS z&Hl_PK^DnPvjVPRju4@y(D^o!cRts zHJi3eFCEmh4J2tw`hFhtuFx0tb4}szZ}|6Ut$}w9fx346ppzO_%#XV@=7#zP$|N2% z1`8!YYSVMRq0ipw*3fVoVy$?S1;SU?0VV-RU1q+k&&(-mpZo&@Nr5m(46lW3jS9sB zi@0m%o6ze+Zw3QuO=0ao6ret-@EYZuyNsNeL&y>faHwieFI%(e{ivCHeKXNSYZvP6 zTtN9UlqzH^aV1MlgZhb^C$H*fO9M?a;uCB2OsutQ8Q_l?N`6jnZ{$cGS|5>qW);A* zxs_ow+xNg$vzh1o*4xacgb);3J?2l9s;uZ{Gb6$ptTB0%MuQUS9!1Z5TArM=&G~oi z^8p{9dh0d3QAxFr z@JX~?6jq|$1tC6ENy_Ng_sF#Mx?@}4Ynx8db##yKIys3%>@ri3;HC*_wNcj8Gd*}c zoL2+g*B-Gl&6l{%1$vqTE$vT8DgU7VHO2j}%dDjT-^Th644%2HJj1Ha+mx^%gyLTn zc4RgG2Jmk){%x+*CAWC_V|u5`WbOzzT`k91QDs<;FS(QEGA?FC zNG+;AF}Y1uAm2##ri7uP>11#Fu|Uzp7PrQ_V8&x)lzF?q$77Wc0AZ4!?cay74n-iZ zu?HB*&$fZhGFG^Shxz$1KYiZNimPSOo_@33(EbGC%w8ox`%Cr($+HXJCgi_;$JtUs6*MFEsSgF^p3zh*ARLR?|1g^G{Bsw7OTN8> z3w0iluk&7HA?@u@__lriTiZ(8+t9c7%HzM*-j(YX`e(1|-%#J)*@bTt^5523X?wFV z^61}jzuMjjg*uPT*ZCs4k^b#j__jy>+bu_|44*st_P(9-YyDfaPQHKb_Nx9J?c2Mf z@a?wzx8JR_y=VGa|5|^wz43)Q&&=2PmG*uH$wLd@{+R!^@bH!O?=at9zZJH(3H*r$ zOs@N5%&o93L&punMuyQ@+<21-nV;L4+vv7f4%SRh1^ve^N2xeLG~e*}Z54F1?GJS&?&79;XCF?G(Av=t^O{h4|U@ zIiszGr20FGRQ0h z!+5I&-sD}>BOG&r+kyvofo}4F8?ohSz2!}V(%HQl^ z^|qH(0SCcJ7s{8RTjcrO^;))EQu0oSe0W3Q{8$xksY44Rm7H(3VFrEtH{ zakFP#aQhN+EMJ(hXDT=e%T^ISHXxTXbi_-eh{>5{73uDBi(@@pt!0&4$H6cbhACm} zTLe>b%@(`S)L`4DmaF!ze(D%=51(~yOI3g?J~Wvg9JRd+t^@_&{3b*JtNl}H(fv&# z8RuGq;Gk_e_=fgS-m$d(4R?Xj_O42Z+TPo2kudAER&6Y6S_x6sBjEnGEvVApj_~47 z#DONJeP{L8{vcSa{ynUglfR1t{DNglzLd}Ouq9M}lfn=Oh2!YW1No1a=Rfj=QzB|w z>bHCV9!Rw5W~C7v{Y>}9feT67LQi+LVlnVHQ$hs(L4t?g?oBtAD7cfG%MMLtNV1a# zXsM-s;r-$?ygKH~_gHCr0v@Ny7z!_(qcPLQ&T2)8M=bbpTZsJJ`5G13+NK#|XI!et zU6c&sNahrx2DRe0hb|$h%twj&El(6)tB`U{C&rpQ^MI%ya1b@6EIL)&7}XsPKWV97 z-C)OCeh}LOO@4+gyAcs!5-Sts&`tTPaN5694_J}E!aW?m=KgLYx-vYmajmFmE~760 z*>btS9+2#ewYo6iiy;Fxs;QA`3NBV8_m&zQ@e#oJ^99<#geCXX>1I3P*rxMg5T;G&gIV+wKBa>Qm2iK2*mGV`!Q^f9zfxZWr=tL}qvM<1{t3)Ze1y zW)7emS0mbv%1hS&X~>Q?%bSdxv_Q@4n6>aU!zQfUYcKS$HgfD?N$1p5_Ee0j=#cC4 z?IVzC^fcyOd%V?~NTHNR16{^Mi#P2uxdao_iTTqMa zs9mXA9B+dNJ%UhBXb@QFQhN22(1 zcj(J%{!2-eeTI%-jO?X!%vjoy4=!^r`uJNyJERixR7(}~VVi`u*N3T)Ll`Jkrf-@` z-C6ovNcVRHkba}3hl=x9?^Btw0f{JeQ*<9NhW;xR>X|VxrjRUXU5tw%l^s);*O?C} zA(8?}fcUpR$G;s!Q1xqxwzHH5|2IPOlHCTqq*(INCTCg?wowzSdz2Dlbt9*7f%yyt zRV=SZKG%xW;Wvrw)UH+Q)P%5*j-4NonQ!7P*7zQU9I2p-c$1edFWz1^@fIt&oSqfx z{_n)w0?HJLx2L0y8o|uH?J)tkh`0HPDQPv6ISA2-f67>*d5}pAw#Vw}vD(HVn;hXA zukFHFV*bPbrO`PYJF zw{C$;TScyqf0X*iFJIW$|G_`L^pBi9&`>X|(M3aDa)7G0nV+nq-6grRwL^OAsA{y; za6`gCQe#I{-F>G?!+%2yt`VuB+SSRg2_M?+XH2TML_s^*+79|X-{-e0{xok)?%5TJ z+Yb^HQU6kbA3=jY&uqyONH6RfH2YZ8l=iSQwX|8Ka@)u_z*_6doWECU#KJ2wcFrgm zJ6;8})W14gWEgJt&i_fAhhjXHiHxBo=VFiF0cKCT{8x;iZJ85>YqZ_%pX1E_fm9&* zr_wX`i8{AZ3ura#jkka}MU;t2WC867G%@4H);1P>78*a(-QWFdkKC;$x1&Dvqf~BZ zaqu;k0eE71==*c{`jzH9=Y}=;8PKWrD_5g($Jo0&%xCD4+e+&$Tr3vJY0h7Zi)!7; z=iZr(s6K?Z{4Ay*uN4oK_n#zVli7_Jp{`eNIKccT*HA~nf3o88-^Z_)*+AtNu&nFL zA6isC^uP4VucKDs`UDerD!edIbk|6W?iwWya6hqZq#=w&iw`~(9LZt(?G^(zvb_Mz zO0PQ5B0-&r9Bxs=+_jZPt68RRS?buWHDxGw--eDFn(+Z}+Sr-l6`rZ`lb?I2W<)R) zi{{f=Hijk2{1_HrWozHt-1~N-6_Tpk1v=BwJe>by(*}wEhy} zD$Yu?&+^isE_Xa^OQ7m-9(nS|^tG+GIibd4m~FvqRH%%>0>|*d^6pugM4w>xA$cx6 zuB-Rq9cb-_6UXBg_$>8j#Io2fp1&*0W@Hf&@fZ=QdPXV>6}viyzvfmgi9r@^kEl{O z!=~;uU#UAgR;gCL+zG1mMZUTbKFi0)##(zEhUooGKxgk%Y5pk7h#6rP8sFZ0z6LIgU$fvM4@+pj} z>qsku{sY$Mzlc?aU%bR6i!0Nd$tL>N!!KF)q|}&kU3>UR1x5E4fGh1`btgUitFIt+ zOsoPU&aJ9|b755do1e#kQkaCBDk4NZ#6SCjpf|7-j^PgRwZ3#(tX4z(NY%<_tzQ8v z`zc^m_zLblI#z*!l~4sRTZ#Kl@dVlA&T)j9N9{8L65SuI4GZzWLtra@Ei&hV8BYpS zgjqubHt#8Sn`&bSH+W7U$>vk;2359(+H3ReZPX2AfEdGt--{}S3v8iKWc#MXVF;lePENgbkS44tNxYg9T2HEx1v}8e`2c(dl5hg9T}s@J-Ae-I4DD3+vl7DH52@mE z7F1;QCdTwiA=@#+zM((V%>7TQHPL2~@)-dW!oP#M%xD;_K9&iOBZ+yh15nLo z*gzd-^dkFYpQSvgL9JET-%7W~U%Vn398m-@3$~76`(C>pki70%G5yaVK>r(3X;nCA zG)(AVR$~nhMs}M)pcQ6j@Ct3%~KvEb? z>p#^QU}|iszr@$}uywDIN=Ahgs-?avR6~DJu8O9shNGie>W@@`=F|6IE3qP1LX_%c5s^hgoJ>^bF_O9P0yx-DfjFRW^Ch12LXQP9cw}#1pv%I}IO0 zm5&ky;cojgL}WPL!m*3LZJ7V2d$ia#@f#k+*5A_8eeuCL?;gzQE+67h!xp44UL{M8 zF&S%Ei>Z%?CF^pX%;R;e*F;#~eR3m;ZWHF}7T-}WvcbiKliQjPiXFS^W|qY~M@8%C zrYOagPMk>1*S0_v&9%N(TMtNozX*@Fk zOCwVeSd$|~)C50hu+Rp|m)Usolw(4A{No0*a`G`Hd>|y||2^u2Rh3U)Wa)TH z^Ol#~6D$kVp1ctyGH^i(3&d921kXrt0+XIbV{uV2nENvoEcuDFWHwn9KW`7|$NdLp z*Mv(x!X_*waxGGNHo5O%F)k7ly1Qg6>7wEy10$F*myZyLtvy5)cBJ*w@@v^98sM%3 z&WVF3(iA#q_S{%;sl_YGTN+IDtnRs7Sl6VliLJTpe}87e2{ZW_>3V5J6+B6|TxjVVr?Z3H-+Aq}Gip_Q~PdI{bA)8G!9VFWAOs^#((BXU5z#$d<| zRW54_63IpP#t>!8U#(_8N!*B8xms5ETpqVBE!z=cHtHoC8*Y?s^xm=Bke(&(_hB~3 zL$+By+gBJ8`fU*>mMuXxceV%V<@nBNGdeXt(>xm<2D!N>A&ooldPbTyy+nhg3q8K_ z^r$K%gJ6b8vifi){gR|@Cy~XO%Z&RIpNPrftp)kH2p{)}sd+1S2;3nn&2S$aLTuZ6 z{K5p`UO|3#r1euDCAV)cSM!hm(?iGww|?y6InNn?iEZ44>{E-sP9& zLGs7z*B47(uuhQd3}4r9*=?voi)M?6`Eq}Fkm#FE#W}UjpveLNhRu6r2V|2Qd=#@< z%s>$S-EY*VNXKo4^x_?zQ{uK@>xIw^mZJVx`Z2z`XLgLC$W)c=LAQXf)WF{o=h#TV zI}NZunRf#?{qrhKcXc|Zcd+3MjSDcOQ{x{L9dEhLt7#gQ&zn4;v}sUF{qk$1URW<| zQxRLa7?HL2!X|;iCx?YQ-_;g^r`?Iy!4+S_F5Si_Q6Uu$NN8)Zi+q8pYjT%$jNjAsDex`lXlACcY&QkOcXh$ai=7m)^THvZemD z>0*iX2w&WstsRR>7xBACD$}ppEnh~aY;rI>WA!H(Nc{em4En7BhY069vQFE>Qx55y z>dA1))nS31|6m0!h<ge&pN+!}i>p3kT%Bs~e4iUZ&SNja7^Z@A0a@HM zZIl|>R*aHOo--#l{M0Kq5ZX9f7X9zKel-hDMyQ+=kh|z=n0tURH$qSP(MBr-%bNw} z%E={KuQVJ^pRNbXyKR$s@fR}&votLo*a^7JV}j}7ytDbpVESCrm3lxbnEnFq5|Yik z2h-mR(|0tJ`<5*&tg>v=(UB2CVok65Qc4 z&v&|?YWx^=uc&9C2PeExGx6Z8F9qZBg$+~v8$N=v#Dmk7+QRh#97vaZh` zuxGSR@Zmro=71wIA7}^1U?rzUWai5AU&r}Ix@O`_`DL(8&XrBLlP!=VgQ8V(w;^HF z;@&D@9{#w-lwptd5y6FmY{ZcE2}pOJnqDxj-JSHhtpOZsj}e(_YGfTz&6m4hmNFD9 zSL>CGg1^QT|BCQCo@gb^$5}EQvdQ;{b`?oCU{|^|sKm2C9d&j-Ud)ii{OIc&v&m8$@&bj$NhSwEcgBEeAd2D|tH6rX`fb zMLKYU)=PWuzZTCU=ljpFXNC{9(zx1rqrOfhwt7?N+;LH8deJJHaBv6GFKZ^!hm(ud z8R7$8O{EvsHB8--yjwgCaP#>0^w){QpQQG6=Ip214|(zH#9H*zp9#0xxwE9+Dp7A6 z0$b(Q{Mqz){#3Kpxvb>8veXZ6=vOT#jtqae_v<&0t6$^wn^S}^{NU6a7e~zddDU3Z zOuD^}x&~PG6HoB}McKLU=a*G{-glUXEe0Q)7`dq7`;Vu7Ks4N30`WQ)YU@=h@z=L? zh^>#q@l|s1AP{t|@>QA-tE5CHODJp5nvO(cX__-5H`g2sG~q4z9dU+OWf*w#?7;|S zOlppy<2C%?RD23!yWEYDw#9LdI$_w^MW$08fKXAF29l` z{0cc>9erK8uT}g;M7~aV^JPy_eSU+_#-0~0)Y$OAEbwJQ!rLw6|$>IpvI1r1$?<`K&GWIo@{KHt83#PX4Y^T3pEW zrqw)f@d&`G94?-!H)ilO(xhq$H!_~y0FxTU5 z+KXbY?m#hGzCe|PeO>;Pu588s`GRSJt2s|H_ev=0i{)|beltKkZ%a2vSAP(X{D&9; zz-EcNpTBNnorhs+NN3QR*23$+f=wu}x1pt#-fvc*kJjvUNU=2bIGL$FMGnGr{L>paIZc12g zQO}9-4`+^5Ws7<;ZCV;9-@+A<53>DN^B`pSmz%wQiKhfM(=C+javlWuU+UvMTRr}#3K!h-VCHR5 zd*KV~V&&!%lkYVgm40xq3~%feO(&2nXqTrX@R)3HFrogKe|waqW=cPajKVp?$~uf; zH!PdFzWDIt9_o)j>jhe)iyR~&$%cKQ@l5@E_=gV%E{Z!_r zD!88+HhvhI>b!}s7o~#MaOBtmBRh^fwBrQXL?O6^isX}ZJz|dg5VGG(6S-4tN*ORb5wtLrM`?DlF`6>jpTP{t-eY`t% z&GuTD&9l)GpKVfH3d1s-|3Wsmfn9}SkPxoQYQ-28w%y3vs6RU(dRE$>X}&+!3p8rj z3+q|AYxu^%`_quF;B8;ji)G$^J86fm*~*K0@siIrwp(pEKDYzbRvJf;J39dAgCd~2 z;QuuA4){-z+$+E2k4r;a-#1Kkq(=%b>QhJQ?-#SG#7<7PI!=;Q0Fz{r>%veVeEFWC zH~6{CD)O8brbEFj+}I`Qg{x%jrO=F)ZEa%mv8+Qll-TdzW?;`m+x?c(R;N*nTuij$ ztzkaWP}fqwmd|mz5;83%%E7D>c#o*VcYG;}f7+s@?IG3g#HQ5%&U$bTwA{7UDzZDb zCvxfVY66sCE<924%A~TT4b}~f!10Tjv}yye!hqb9_ru$qzkbQ;KuW*mClFHHU$4`W zICZf8rA1+H!-AKC-&>F2_U_X(oM`Q7U?$gY<-}UKw3rHKlf%A`!ADX2AHav>@vU?` z+uL`=vYB(Px6k&MqHI^jvq_Y>kDS%EuqfMKI1McHP>v)P*Vl|I`ZMcI1% zF6QYQphi#g*{aA^jHunuWw~-F1Bnjq@UH*rUcB{Z-IBdM=b4<#Y`lKJ6iFx6n3DE# zl)HzE--G1A{KCi3G$isy=J5|2&zr760tJ*S>-(Tv=-?lN5BATW4FYgE{#Sm$IVAWA9=j@2!y3}?4BcExOF&vq^n126{WTInQ zG&+I@en;_a!S6Vi3=)S8x$TsT)t}$+bh#-E$R-A0$pLyuWS+d0e94>f zQ#cl9KK-{C%h{Ux^nZc^&c}hNjjXIAlxqwag3noE&goa8kHpJO^)&HkciLA;}^ z@rZcC59UjS48#j2gXuSm^bg3<`qhBlLy2`=t9k13>sMXyd9TN3Y<*y*kxZ!jyUf(U zwnZJGIA-GhhWur?0Gq1nS1IS{d?9%Fg02YO{$si!Ibtggt-n*F$Tb9BRjU!t$eNkW zaZY^5=le_~Wq%rW!YPcOZ_}1nzB&%%TMCku7d0w}b!PSwrSr~G_S4GQd@hMESRyqh z9z3}^#n~oh`6kFZk{sohFsxc`wmzmJioIjrUnnQwdWi?GcGRZ@;NHv-bkzXs^YVHv z+ATzPZQ9UXMG$yeZ5P&PFXP6$-04t_FM_@B)PEWG}1Yfw>rTjKpQ1R!!S)w66uu&Xe{a#<*rB~Zl>BU<%`B*4zwfHyDolm5q?@SO_R_j=B zty8fTZTQ*WSTXrMwfN)qpw5?i5>U&FdBf%nH0VVPuWu-g)SSIoR0yv3ZC@GB$_#(1G34QzmRw%lq8~c( z*Vt5dbVOTip5z31)jnd#+$ijPvIpc`Bu{Wum2sSpe>p2=YHUG`uGf2@k=vihh$lKf zT>i(hDf5`0A5L1JVb|{Z%(E%%6?5$|%^n4&`(oda0y(bQ6&cSv=~pnM&TT56G*n&y2y$3RQ`lSX%~mm0{05az>xLrPBfBeUzK%9j(_e^VwE zJnUJ2nT^4F{J<)1=k-MTX=Tk;{*nrQlgd1oTK*jM`mDZq;6W-LgO63WsMwHS66v%r z|4n`jKE+~?AA|EI9FxjS^&QLa{8(GQ;Kt#Z7xf&S)2Z0D7PPH?k8G)*bdGqGtsVQ7 zcfPTAc4&D)D7KIALeU0js`Kwd@d!NS?wVuc>i7P!jXfaxx^EOr%ZYADe-)K-Lqv0S zv1y#zGsx3YpHPd5HoLDl)GA2nWoKKeo&K0frc_%tId4h4(oGo-k`*aM<$01^>QOh# zcY3NPP^61+o5XaH9|0}(m#U%vKbt5_-V{X3WqbKe6v-`4_!W`zIR`LltanjnDPihA zD6?_+f6fy0d1a;pLNKO^MM`hrPz$IQ&0K!|B~oU!U%f7TMppKRd!o#^=#v_D4aqLG z{H&5sutK>#c;vGDi3uQY9IfDpoG`{LFUiebi}pVpd~9ss+CcC1CW6T(MAw{+`IJ9D z;=d?g#UOAC-iXQ{`YYwN{zf=k^5ARKz8&sE6d^G-#$O+Ygu>pd(N{m=;bVzAer>Qw zI@UM4hWo_MSJ~2B-0q{ZfV%to+wS6Z9m! zCYHAiMT{?=$syKY-yQ71s$5I`CI%1uy3RTz=JtnQX=QcG5VqnDGowh0c*d_=lPC8z zJm)T)$RuD!G52+uZzm?3tC;mp*e28&qH;&+U9YTHQogw%`=YaA(^800;%YEuG&d-p znmld%`rMbonx*^jDE^$k8h?gtF5HVJ0_{&{B6yX}q2ejW&!#Ir59gn8wr1^7s_8k- zX?K}fKz~1ndboFQ;CA>$49}xp>YS;QTS6WeggqVYCoS^xId@DJ%P3d-kRrQ6Yz4O=)q4sIY10u zoTy*iJ6athykK>ggxNqM+5V(iJMnYp#A-9AS|iy2qMzj&>vMfn7psg;5MM1MK9$0WWZqx^c(TGM09XG;!8q3iS6P*NY2;Zg7{+)5-9h97JZ>22CfC<@s2aVea%U zS(^87`_!sQoeUN167_9yX4VqGQKV)tLvP|Se0kS6-iv*CC!rfyQtF)N2CxK^Yk>wu z_#Zz3+{@p$dkm0rSGF!b=F+oITOR>%E`Nu(^H&W@&)_Y+wCeoQhpT8PNN!6Rc$Bj< zhqRy9CrEDMe{*gy6@K?@q4VYLk8nBt){&X;qrBo*j02u=@JcZ}r-kr5SX6xCI)dlZ zQw7gw{PpmBz*`)inKK?F$CX>90 zryM;{#5^&snE;~Xvv*PHAsUExH661EW4wA62SieyY9f%00@vCDF?7e#xSF}As37hUS31qt^S zbjgFWe0~gl7te!V>B8+#$9btY%n9x4@)rs{Fd{oi?G&WaQhYB~rS;B4l54u#CbFma z#|i$CI2GzEUa+8Iy3l`;dWSw7G*@_)sa1O3;EvMg012kK0O)#0(9t0Y@BBi`+E4T> zaoIMRo|VNs!D(*bbVQ8n>+Co;FK#fiVrqi zN{8%JUBWFhVbgA#ITi;kYpTllJ31Ht?R*Ej^pEq<)xSD;LC0PX8}z*{Dc*R}k6Qgm zOi}Rnq#t|ey=@pcjs)tEXPSpd>|u|FP$XK7DMLu0Vi|U8AGi21APVa?6P%l_b-PZY z?L}}E5D*Bc!5ezixEG}RxgYR=n0bm#&v|U2)n(1OjJK=y-z#QW*z(iNFk6+Na%+1N zqj$G#XNB2N@?`6L%NqT5vsi8Pl>L}wb8`ez)KRyw!YQ)JrB}uP+)jBndj=Z}^re@r zqAf=t#txph1)mtN=KcY%g}80Khj)*F8jpY~_xwv%|B@h9zuD)D)R#OMQ+?0&+cO5T zA>f8EoA23LzGrK6%Qi90=JE8YX6Bq%HXv4;Az(kUxyJ-jzU7U4T*vlt1Z*z^40xL1 z#dS;@N5sxCOzCP*u}-Vv`6m6?%ibTc_tlK0y>EJPP}|8o~yTrxH`{ElOFBP zOF4yrL|neu?R*jgWqp!X#_zh(0Dfok*~CT(Vxytj;prb&NldwzFXo@ z@9u|Jiof)aJrk`>VvrwuC0fVwlDnNh?l4xPbDQzzNenR?z~0Er8=Srmv{LVFw}A^1 z4~!*ge+Fv#Kmy8Ir}EB7O|*Tgu9KSL(g%%Iq;#TH3-2M-REJ3@5s0~+4oU2W}8xT-od0677Lbl@@4EF6v62kI%h+0o& zAd5(|YV*C#d0PFi=6MCMM7!KzOD{{bZo^BY+&1OC^D6hyvB;S`+q5FI%-)2lte>`;=x*%|VDZ#cNd&DH&X? zBD%MWYX$$yH z-A64_N{R0hdqkNGZq z#nbL*OrCk9@53cKL2*}$gA^987EilGn`W>bNfW1P zC*O{~f!(=6is&z|B)jEdHeYzY4_s=f=Q0edLjPIp&*@mAhryS=#&1br^RgC)UBqG)FfeA z!z`5g#`yX!xCg<+9-2*Vuo?C2@d(3Bz)eR($OaDpwAkP-p1G$PwKjA^O_}>03GScQ zTiHvFWF&16H`g_uqH%i|yYD6Qse5_;K#QXBmYB?1pvJ@Cg505#5Vfl(a1kM;?w*U( zA6d4H4ENGNkaZsFK=X5=#?}K(J3ksHT}e;*oz6HMzfnlk&~>p?0n5VdKV0v(n9@SF}W~+ zFK+B(LW*V8f|AY)*O|b}RI1dNn!S55}_(&L*-q&`9v*b z=ahmlZ0;|mrAyt!NitK)ec347k%Ju5+~U=ljren8`oIaV;<_k+RcI}9yI8w)79|5? zpC~?l?l2fw`wjeLguhY%1!m-25W3yGqu;n8SFx;bQkY!9kyS#5Qgl3w?qX>y8xi!X z9x-qs4*U{yaf*{w1$E27Lu|=hW9u-$8i)n4!SYfuZKNUc-xWToIl9x*1t)>jve}H*Sxy;y< zJCJYg`Dv=fRx%Hfk$;1vDxS@)h&{X(k9*TPE%mRDVjMO1SycKQFFoA9ab(zFz4;N5 zIVu~ZFNJ<4b-9)gv}WcnM`_q+ZPgcb#p7IvtwS#KQ~$ZQ!H}DU6A3DF$1NWLqr!vH z^iTU8%=TQ)y6+`Nsm-WE9cg{gf1Qs-+@bp%+>%3}x=c$jUcfiIcyxY!MPl-+qMYCF zSNOcrSS4MbQ4o2|GH21EW|^ZID0e+j7)s^tv|kipf7XMA;O|o~+)|lP&u>COckRPW zaguZXxW38Yy~&#j{0XKl^%s)Llw(8VtmHtxasLcysbk;bJZsa)Q+`0Tf}{H%r=V^4 zct;5x^YvBR0b2~Z=yb8mt3?-ynu%z9jM8!XgO26!sZ=IsgD*AY)AJ6NMjw?5IM?Ao z84v2+5ZAP|Z1Rw=PEtEamWH*>6qSG}af@&F%O(_2`Sd)T;`5_g&%MLdj-yae`uP2k zd;Cl>c0;V%)mBigEM00Zaa+$SOz#q{99e1Pr#Ki5F0YZ{G@|S~TF9;!}_HSAe zi!>m8EMm?zXM^NFNtJwKVL=wa5BJ5XcF1zS>tuAdYRyPm`(UYQjHKt(S~j_Z8DMcE zX|Ui5jijM{h_+6&^&=^`TBu?=o@gso4ltZbWkL^oqV;N@M>u!DSWE>WmI zVm!2aKK@&X5eTfoS+INd>J_(pwiVE4SRfAjx?)`C*1sY1+O%H^2 z&%6T#Li_nglkIaepz?N4J|a)Hk7w_DRrL&y$r3Y!-dGfqhMand|BI?64MRg{v~S>o z8)%?U)G<@p&;9tbPL#?d7b`iN{Nmm?BaCGCo2t=>@AJP4%@4P4YH!LO5=AqvFhgpy zQ!v7=KqBSF^CuEkNQ>p}9LteQ@gAjr{_n#3MS7>U4S2dIEH9&fP3sl&*R}}xndKu_K-&CzkrXjeg)f@FUDsPtopXbxd|56y4HWlVx z5r&=3nF*9SMTphN1j(6u;z-_WnPlWaeAjT@n`e;RgTKQsFQo}@sO-udV`lWRl&=>cTiDP2Rbo+WIw(KC0go_^EJ)oN6KI0fnpCw$<0bsftLDu zWote^m0=H`QN)!0wbm6t;ta&j=2G{ULwx~yx*{u$F^u8MLtD zU?WT6x@j@!YMa2Ir$HBS@c|e zr1}P?d*=SlKq^#o3)OUXvPq_f0p$#yruq)ebrzCDy;WGa52!qKwvug?ScGE*XzNZOK%%Z=xU}N6qLK~FSHZ6 zAZv-+lXtV2UX-RY${LT{Bq)OxEz1ojp&@a(9jarRLeqp`mS0B3?%7@j0SK;AhuvAN z!2c0{e3CAKALURXLH6H3E`l&Ay$Q^m$1O)ndUG*{*Jf zeXtB4Q1xjp&jeq86g^(KRDvvSPuX}H;m1=dZ;ETaOvkv-34tX5@dIkkg*9DHYAvf# z9tYWV-cR6!!8i1^7B<8<{9%Z(8mT`Rg8JDpPu1zzPu*z5EmsRunMRg}=uD=ufoDT1 z{dtwWcZ4VPWg143o?^7oKUyP8rg5Tw&azZA18x%IpdfwUJiwNE+rHJt*!1(P4jfUkx#JlFsh475D<9RTu1aM(g zZD#?ow2|B1e^!?ZpV!HM{>~4&S9uWGTvuq~>tr}NwPS^7=PHfMO1Lj~RbgBf>96r; zbQQNz>e5DiBQF<4PZQsDxMaZXDf2jWQna~rZ=B|4bqa*Ijg zM?a0T{ix0B7@gCS-W$N=dN1e}y-8lc#IKIPrct41XNWwYkoJ0@HnQuiy(VlfRoMBu zU}#y4YOVPPr;HH^+MMaA6otQj;)~RBYT5MDY^)lL<9XHy7 zh^BZ%rf@PsqV-GqBU`gEHEG^Gde5w-W-5Z(7x%=4*+@wAhFNL6);swsLoD1R$Y5oS z5V2and$=(Ue>D4N9*$XhjEoX@gvI%aoJfa;6q1YB>TDwros4mv?R!celPTjL^D+hY zFieHfflx|6R}d|)w&(2@jy0>Af@N-_4{T`qx-)4jsr0CA%@Y9hBf zT;Y!03;uW<7LG9KpIz`d)8jKX-v>V^Pn~SOgbpHc%*I{k_E^tt#((S`lBZ#29R4QA zqU;Zji7jAa@N*t}JbPjJ)NJ$V@!S^kxvFw!lkeUdV!&*y8~^3!MS!PqhK{-6RA`z_ zK3tS-0~S)m75QwT`FJ~EgRYjRzL4H}HMn&cR=&)@>s=|a(SFgb#`zoISNL*mSYhZkjewzUKA~RA8X>R&(NV%&g zWwD_gt##S@sEwH}^ws$Wl2Ksk&$q;pdEgfwOEvP5bT&_L>C*%iTm=JIqH8{eQim6n zdi=|uHA$;0Y5D`-8e-puNg)6%^6qN$-|2A0^E7DQ{3OOYwzN<~0K5sZ&Se-fYg3DN z)Wky7e*TN>@a6oKRsI7{8@N>WjJ-4PjVEdWNF&@lik~*u44Uh~q6(Njj#>c8D zcZ0b*AxLiEd&sUUnyl&A)hx0gxf;ph$>kJb{fEDTMKi@gQ6>1yA5 zrB3Blz@NY~NRH-j1bowtAtj<|?wJS()+0zJOH(cV*e}Xr{kZQljl2*@zmD1xjjkYh zJb8oK6L-a{xES`|o8oK7ileVCmtDe`)QGU^zn)p(g>rXb_v-sc)#saa8=VA)W|I#U z6A2j%Xx}PJ;;j{TA;jx=H@nrG2K?f7%#6gR|wT+kvtv0ubD5z zTg4je&UR(=En++KMc_#e%{#T)!~M~>%BF=myJBoz8&lCm?Ik8(Dq0r#<0Jiy%9RCd z;ycm0o6(#zcY?c=%11NUwYfoOEZgOow$q`Yr`L9Mdnu=8z8H!hg5Agjd}wcd=&nLv zhO6@eXBROtVgo%JsZd!_T~sIz^kBAuB!zt{Qvwk^3bXIgw5MCc>-q!!6!T0E(eUYU zKlC`+>;{{*0pxSfK(1_Zj}Kzv+U&4bZ{&lA*kbLywMUDe?UC=w3YG2NF&631JGHMq zCtE<|567+$lFKA(|X}c9DjrH<0 zoTlqoa^Kk)sK{%M_qd?#Nw>*RdYJ?zG4AZv-;Kp=OgTV9IMatetAga)GrVY##$5l! z80cmIY!2wsk|3s0Yi*G#9_ekVDBdfZeCN7?Oek0wjep8p7>TUrc{FnQ3$aEjMYQ=h zK&rh{!iiX1GpcMd8>_I~?fbEpVHJ7lJ`lJiAp7$Sk{gD-P{{+Ll96=ZpCDAycZ||a zD$YRFy6K8~m9xTTtnQ6JfXD@&UApqiT#rB5-{G1LfI>io+MTOSpb%7Rn0*PD}R_IH6_iz;o7b`m~a-~xn4`L3uxt2F?^+cbOv!t{gw3$ zq(oa!0hDPoteQ_j!Am28-SHeY`5ccZA;W@s-#T@jYJwRbkv8O+roK}Cht3obK*#dH zsXO`QfrB9IM3eNKZ#ey5WWm zZTma+_nPoLu{=US!8`Cuan|=Br?iR4>Xz0+;7wO35B^%Fe%XCi1^SL-z3m#WSIgaO zbWM=F%l~fvQluXj3zqRD8cj8M1A(*1A9V88KEER*YuXZLkG*W-{(7ML6Goe08wx+N z%jpUCNk1*t=~BCd^7@UQV4Rx`?|D<4J$bFwEfkv?uH5O~o*;Sa)gJ8eF#ayQr!tWt z-s=NDl!{=d_I&fZ9<5ePkZWq4O|DW@{ho0hk7LKp^7KESQZ; z2;zr%?;YZqcfEYh0y4il*{^g_!FAOw6fS~OrX7elB_`VvZ6`1jpxeC#Ziu#F?yewj z@>cWli>nGB8{DP(2yg&e9n@~H!}=vJemHO;`usxO$||TrY}wcxHqnsd)dQh--) z4L?HO+3w4Faq)C;jB>@NgY#N&vbF8$oBnMK$a44H+vveM3y<*1w~;2xi?W>Yo*(gz ze#Gx>3|YT3s^Q$~O(Ejz7WEtPc#)@rx)xmC1t&e!+kG-UOLEs!&^59BDcnd!bQ~Wk zb7`y$0X30e977>-W4Rw86O}m{z;VZx%&_dNu4cwzS4q}%8}DYcJ@IiY_of1{mfYqO zKkzs&jd9-{&JA@}uo1=7R5tnPWrd#c6)4?mA%rQRib&~aJPGH8x0#HoT0LdQRzCGH7m)ym`Cz zOXhvJib7tXg>Gz1Oq&FUG54pO$)H+5aGMg^C0k-#(5pH~oJHo4sEwz-(%>U~!D~H>Q-^_Ht3ijDE#&7mWO6mllXx5N~OYU?+DuV6#D^#s`Rz6?tE9L-wyxGPpygWI>&Ygec=ehoM1O8}5r-nq=}wjF(}0(D*bceMt; zmQbh^Ac;A$349F>!{m*FJi8C_blE}}WtApwW4(hXM~sGboqiAad=0MwSicxxkyB#-=^DzUc)Es#7Zh(5tBq{}OqmaRH|HTg*(0ZhcO+GREs^j~fL4#o-77F#kbKSm_GW!luwbX`2DEuQ z1+)I$e@O6A;l}unl7qG}eoM4H15@&Qlj!%~`7O@MHUAD;Z{t0$Tf||rCOEhGFMb<= zUn2UdQL_Vl3syGVNfhgl3I)v-bN;Y!z^=ifA3n~!Jg>9Y*thC4-wk}5iDL8d*#BAU z-}#3^pj~)RWg-sf#Sz@yAjo+8A8?6RKS-<@+W%FQU!|!0aW*1|DE1vYVMTSh(+*P| zOyq2)LJaoCnil#ZO~1_(F6L2?|KXAN<=C4DmfJ27DJ^_CD&D-F8wv@%>x4wJimio+ z9b&bv;XXFwL^T9g%e5n@JDb)_Wtafxh!M}>jW;)=>e-lj%G@em{BW}9(gsP1KDH?U zTZ>&HWHo5|bRXw?bqK1^A5hS*O`}x@g>2uD6ySYQm#1vQ2yq4XWwHDo&+QPOm8mwr zy8JJQ2DjNgP3$76qj2YQMed&B^7-?W6t7kA_YjDaY~9KW$E`!-whWuQVJd3J;(`4s zvs$S1bj9W=cY}`d!m=g>7smbh|b^*f2aWK zI&7#*PS`SL82L)0{<*)ihc4e%H_Pe>BBJwOy|egf*vYLE`M!xuNXhzdt%cD4`8=h1 zkOj@lRi~$U=MxB~m`|79l^ z?M;n~l1Eik=WCGK>74C0ncCwQrQ>@ZJW zG$GdQsT$g8?a+Ejs)j3<&mD4Red&PfUi3#2+g=Z!1peRmBH$*s~`ebCnrL`0r9;u%PziEi}8#CEBjx zcT4?t1I?M3)yIx`{4HUs2%{1II;BABI#mxdFLzg-qbXQat;SZPjWB;AdvK^9Zhqu9 zOr4dZLd#TRf2;J@pHGwtgVbhK(WoWAKwiEs35(2zug|SAlnH(4%&A@K|9Iz?lRS8aI#@xh)_!YP6m(h4sN?~-FvnGznOll!f3X?JB z6{Zj%VT1%OaU0AP+_r>r$i!4IP_v;6N09~6qJG9qv;>yLWm7F4;0Nw*P;6c<95Ze+ zP308wM>XnGr0PZjU+UN3%O%88&y8HD>^8 zMnJ>yHpkKC$X{zS=FKv9K88WesN9p5M!B%1#Q(RJ)Tnhv%LBnFm6_RXFn+!U3GrF15Y_$(HIKo=BDRI zN`AbMH#FzmsSSc3#*i1NypTTG(vgn(XsSdLr7|}S%Z`Cu2#@P(pLy)r8C^F`DoEOL zciht`Rs2^`V#J>K7ud7INM2PIk$}s-j)^BYBgE$3O$v0Z!9l7=?#U)IlIq~1L zhk-#zGQ%W{mAF-DaTdzUhEtpTVDzS()}YQo2t3)}3jx20<;{b=2KN@xb^GcU#$U9F zB}kUiw$=!L1}^4b`~?z=0NEyjG+HCvda)sAy(ry~bJjD49L`z$C<^o12lTjmHw95T z@h5J9gPd^%2^6I2g4?CaSi-Yse#Fg^D9tmpw*2XeAMgFqs}0tk2)*uub(RfQ_^ZYj z@~a7r+OyM09FCpyj>ekLDp#IYjfW?uGNiw0=~nt&F>I4)ac=BBiB#rvWY}5Au%V3r z36w)e>nXWDW>hLOe57Bi@P|v}qoXM^tA%U;g&5a1fy9NjsZ5uq2Lwa_rUDrf<(!ed%sii&5G6W$Ny$rn}hG2i1Cc8c}5s*vt1ooT3>$n3p|yXDolEk1pOzq6LCHgq}*Y!Sfz{!n$Ir^ zBqVzLlu`-`ZX{4id!C;f7@Pg{rbag*Y$mE9d1cb$2d}b*S?Iv!hUJ+CfYNNSUG)bu zq#6+)@M~L3@%KomL@X==Ml1}(C2qfm)Hz|SqhTTmK${=_i~aDA9jCH>Z17t!fC+@O z;@gTM0y;mSi_g6mGW^d;&mR@0-I#D`KBS-$2au9nlWd>;b2pl7L0u{NCQ?`tkFLv&7MHu>e-A$0Fn3cAAf zrvjbi*Xdu=l}^u}Cm58!W0w$PGKq@>ns9SR9yhu6Xdr|_7k(X;=hq;){yFQFOk(c6 z`~r^6hSri)g658}h1+)wt3_Pr;|AvNVMH*L9Yhap=x1a~$h75q5V9%J z@=d4X0tOhxM-22Zt%!x28eoU3Ht_7w-;dmE?ZGoc5wt6WMGV}!p=YbGb43IYs&p~9 zLe)EiRCa~|Ln$AVG1dbA=w1$nGDB-eo*tmf46DCF27KQiPQ+RO@lAiAp^Z(N4@OA# z3nAn>C7gy5s|O${cSTYH?hhNRqE$!sp6c525V`_MBQ1S0va?8DCMMfToVGM%liR9c zYV#iPZ|CA%*k%`q7_dM9oy#>OT%z?V(JGtl73Gc$v75&h3^9dQe5iA@Rb7}t8jhmK z+mp=@Yma?5Lu~#6vo&T%>1J#6g}=otzV#+kzkiUS+BG=KG)>6TB^ml&Cb#$N7IUnCXN7Q|AUJ+U`96{?O zmbvnnfO|MuXw5gpx-w%~e26<5nkwAdujyNeIG_Dpw5L0i#Z@=p6Fy3Kv-Ba`8399yYbQ4^I270gW7YY{Bawu z4@cz9g|71rTTb$KZvAaaxB>MM!Zb8-7T+<>U_QjlxhG_vNw=54(C(1uQHQdgQ2Pv= z+JQ5QEgoj}gCnEoi1oZ6DYrGHt%_9{8V?BZoi|pbjy+i$_8R%8P#-%(v!wF{cSHry z%V8SvGxEJb4UdfNx{2mq;1%%RWRXcWNFKf+A$*9AktRAq(~SAr$yy*EixAnX%F5oo zE@ji4b`v$%6!6q?$h=7(vM?Uz z&D)cqtA(p%r&5$_eJl0mVR$3h^ee!vRX;Wxe8?XD1K-vn;=Wvp9>WhO~KFy zn0g=K{xgD_7;D}|@yy60hqN{UV}!2JIEWaGXCLz!X72Wo@)h)UUgrz&%g;D00^HV& z@3|w^NsHn9h2?3rY8AV>+r8^L{nM(6)(4R@^yBbuWu8_Uj+JMvqrHlM44Ne=?t5lI zHq~Q^Mk6Np5oM`?wybG%O9j_ew}1o9!pl;}Mu$}}^>&97pe-~T@ZtP&8#Rr1Wkv&s z4;J!nY4A)_6+(-bC^OZxRd$`stC%yK@BNV912$T%z)0Gb#-C9kH?DYJsX4t+Al@jr zLzb*HEQT>?UGKL@gI(!Vboch{4aieKv*TrbsJV>yy@|vkwSB$*PSMK_2Qru7^jYHf zVAef)z}*K>?;26PLSDI$_psGjC?!`I*z-m0k^Ve^!B~{CkUYL#JAcS7RtbET%pG&7 zmS(MhcIet0hRZu^dBX)0fD?*>I}9aE63SfDE;3Z}Fu=zmPIyB5>)HdKO^zH_z(|Ap z`dDECXC1UCGbLlKW|ISB*@n4ix@K#;TEJ!d&VSk1;;_~jTfjBCmYP3I>=d3@yfv_= zxOXDl3o_fA4s=I7@6nCC$e$VznbH5X&TyjKZhCJhoOV(H?_9sl-3Vz zkk?L+ezS0*?+vhy*)%eu`P~wJzkF`)VNxQqY0udELL6ARBl+Xn*G4kS{gxM%_R_`P zIM6s=TSlWP;+D6lEk#90E_mD{4)AP>M2l~ViI60Sc7H!To*(;maB9-e5?zVb7i?UV ziIbUH@s!Y42Aei+dyjZ1YAD(h*wH{yK6EsQb^Q{tP}Emp!iefr8k2iKiT zxQv&CqGW|762jpE0XP0QNbUIu3F+ix{7N^vUr!O*=_%+xLLa8Qnl!;(4jV8Wvi&79 z;y0F}Nniurt<9YOD0SC^oMo3GB)f{>-L2IfPqTC@u-3RIFbr}yULFR~;r0t*DlBLm zwvC&OZKDRbg3{|>tSz$V0+C$>Ke{nxu;1m}6|!H?@fvkl<27`%<$#M-09HA1KYy7A6`A^jjVXI-;^R2dLU>TXS|II4^XsY>i zBWtx^7_%g+NKYq+@hfxW_6BWjm}ng>2;YF|uyvUPKIA{QlBbL*@`ajprc^1;=Q}fA z`o+dwJ?q{&09Ydft6x&^BHwBg#n)O<4-&4%i9zZv(JXye$dPu{&SfNKBl@XV0rw)@ zvYF1q`QzyfN9x~R?W^di_SKG72Nvehu$O{Dbp4|)V~vw%q3zAt(TYw+*$XH#qU}`U zq!_n}8^6X|Refk=_E;DsH89&DPRfi}c!p>po<+pFmkr9AL!cJ}4vvdhG>VYi)cDN(n52_I7vHtXoN_gQ*KBHwM@>sYh0??Ei4nh#bMl6s4S-RAMuYjducPLp?~59I6x^JtCUh1_ z*+O#HyFJ(6qx0vkJ>Fw9g$@_wBG*cHfCd~rvNh#j*ZFe;9bt64JKa|lwCi80U_tv& ziPB&DFX@l=k)CO-d;rEGL>zIF&XF?I{LvDqlsL9Mu}N#?RNZo&8D3{|4brnJSK76; zauwHfvKkgpPb&?Y=j-E6s7Un~TUfx)_Oi;*r=XjxD{wMduZ%$OQP_^BmZ!*&=CsBG=JBnsq*jhP>4D?S_pP-xc z>>}irbg9dZmyVsDJ)5^GA5PDKz46jLeNz(&eri85{{AG}Wt3IJ4kEk$Kb6gd}MN%+}ypUV|@(|Ai5t(sna2vjWG^4dzb(bQ#Zn1Eosi4b#Efw@eV<|h*S9HjP&xHYR z2Ael%*!C35^MH9)&t4)#YP>e>M&&?Mp6zij4Mv$QCVFgVgxKZ?3s`5{_3Fw8!t1Re zc6;9!cBVe~mX?NlT^I^*VGr;OB_Og&nm@BY%Z7oNFZ&D{%gCyFK7n9i(PeF0u#KFWeq` zA}NWhyk23k+%Csy))012-xtx?)hDAK%Gz>QtNSHJi^PUdZTPd+Mte;4Z4^;W-CpP; zs$HRH+RWasgKF6YNa5@)2o*b0rS%$#mxc5AlB_fx_1-YCKBv|Fa6QGdI$i1U-Nb+f zUMOwy{p#VKpM`y^<@o_I9NGno+g*&+6RrJJq#R#CZthJQX$01TvwGX2xR!~&U$>)@ zfqR_Uanu58eBb4=Gi_!fz2>XzQCR%l_5&HW&h9xuDU|R2{3$ZQ1cV?wVvWcJ2bylw zC}Xl2S<6@zAYsJ0B{pFyOc=4;zis#sh||LRH@W{sc>jvBp=W6@%9K#3sgyEOTl3{1 zp6E(HSiG|V#qj6MGa#tp(k1`sPrw@lm!=}KZUn%NmP}lJCAX3nm(Ap+d9~zk;__+S zGh2S3pPwz4GC^`JtmL>)exw1Jxp6wV_bK!Xx_1KyrERpA9Ggj8x@5)?&iU%A2UtUa&MyLgY}g( zq$^1GH@YU;PBnp&Z2E4H^+|WIR@BkoO7&@KV(G&D%oRv+fSNm2Y6_$(w*HQcMtudx zH-S{zW38W=(Y1JdxYECVz>W*1Yt1yME1bSZu1;;LIj^5-UqcOkrq0zRA}1B9V(5e} zvMlKsudD1sX`VLm`y7E3WGvFxSlg9dl4x1RyRjWBO6!Uj_?4PxcyZvU_F&<{3j6w# zz;>!GWfM2x*DH%N-zX1?|EX1y`nuGC2%l*hX{IB18Y(9=)%>m43U`!1Q;imlJSx$w zbKn@Ln~>tygSvwSFY3a;qDiS6`sKG!Q`9jMrN_(5PK%cpQ!;p6kzEpPw_{1$gcOX$L3wr(x!*oS7@+kE5LVqJoa-1h9y@@R}ohsU$vY_RBLv!zW>0)U0L zN=VUS`PE&Xg=Rg4>_D;_zq9U(i7PYA)Q;p2>NzSA^Jj3X%W+jZhO3aPVD$yv9CipZ z??o*_!)z=}A>RgATpG*WKRJ*=LL;#Le$fa$kyse*CDD4NC}pu&sr%-) zyVb^-IqgbV9%O7c&|zdXVo!}WsXJF#dh)H4^z?erG7o$k(CM~OG8Avzgx2iHr6R&M zNGI1PQR;m$*B%9GJ68;l4?)v#60VyT*Cjn-o@EoEJS&%Ji1Kc|h)^D$OZ6zP=UFv+(%y%rn~C;ShgE{8#hdu5)#+_!j>(sW?L~S@X`-Y)bj>h7bAgCq9zRfe zi5EuNnJf6bFf#e{zLeIS9D1-&4qfTx5Jugmnh)2OBN*F$XYkD?hmahFatQ8!%W5e@ ztY!ZTfoJZVV{b8jGpbM#q|1Iv=y4L#gLqNVFFXBBRQ*wpqOq)uMZjjHY4nc2u z{2TdQAkbdp#VFK^XDbZfhd~BcTQ>C@^h1*NUY<#e)g#7ACB`Npxyq!AAkRvCCC?RT z>KK|)73ppd#jH!rvTz;giB&4B8`G^J0DgeW5E4O(1-VJuagpn+r<8?VmtYUjUYpB? zbhjf8B`IdT#*k0n-zSt{=W4aiC?)yUs+fyG`ea^)Yxt#kxs&m+S8|CQZviyjA=LWQ z51UBpehK5+w0&W@)Tu}#c}bo6NlqGlqc8jzCxVRk$nqNl?d$3D_~1(n}i56i8kgB(By@UJm3D(O%eIX%s<@TwRw$ z(Hf6tl&?Qd{c2u?bz~hZd7Tg7m^^}nbn-}kWr!LpFglm#{Dv*fNY1h)4Qt`|MrU_L z8ey|}pT9Yyp6j~U4XiP3H(fw>R;%+Q4{}bU5IXO7kt3FxJ#@?{sgky_u(m=~4=G?( zTVbt8)sQW(t~S|{XeDGqx7%{Kc!QMefjoNd$NKNy3>AwYJDtJBoxG2VDd*4a^*GKy z7H9u0gZBQ>(`=qFXsTO!Ym@}S)w!IGB$@Tw&2%Zsu7>ZpyyGwT`pXr%^vnK~3oX9< z*hoYLkTrX-hq(jI)V;K~3RIV=t;*ZIhJh*jckPNT%HFM=sbdwJI6Z(-N-GNRbHh&9 ze^(=C7isml04D{_YxTRCbW?hQ2r*Ls=f9$6{$@v_gAT~FNZ+r7T zJC5PqtFzgYzXX;uVT!Wf5^E*Wg?rmyn90TWzMKm~#0Gex2x_8tkO)&=mp%Xs=@qL) zmSpH61E1XUwI72@T)!RR5h>xlTvq1dlG?RY^R`FaN2@8+`FRB$bc4K1F@M)P#DZo| zMw*efM`#DLWd;JW#Dq?pKc&N7=5(nzjIpn90q^gUc~UP4fX_Kfir#vU7ElB-DHI~PE$gy_kP9O-(U zr?a^mk2xN`{Pg44-UUoHyI~$|=}R#%NiA0l z7%k(E2Or>}rvEtxWtqJ(5mq?JmuR=sVoZb5$bOY$RibbaXJl4UUn%**Au%{(u4@Y6 z37IjZQ5ejiV_CgiUEW30_pOrqpIFx( zK+?6FC_OW8_Er>}@q3nLBDLw`X!YX8li|-nUwZxw_rm4e$lSZzOQZp8qoSdSiOm8Z zs)hSifUSsGlP8{0=fR!Pgng|ew;^yf&@MB6*OXsQ|JA9TpBNXibr+etc)TWIJ%BM{LILP?sK& zuxs}sCWRMz2u%+&f2CaMBza`Bxq~S9ov!GRCCX#)(D#mG;;1pw3-v2jzuZ?lQOQJH|++B za8y);<*-KpPqVp^p+(L@U+)%M9@$IfKkX=LH-Txa6btEtcsBY~NwXVxFCb~z)X}?! zv|LJ!VcuHii7QCZKdM%D1SJ4ZqE%ohnS0v{O*6g_L_Ac%lEX!Yyo+8rpqi_dadn;4 zl)1aD)s0i}%~!e0%76YZV)VBzcl(hlP06+7Xr+%IlitkBbh3qCX|umEr1Lag8f~Cv z&M4`X<4-L|3CGluF!G+wOiLb6HDYIC#bUN5Zm@oZC+vV7MUSrc6nPI_sKncA-VzVw zUH(=x7QqgA`$U0@*i|>hDyi&T`#36TKFLU9bVsasAGfI9a1t$1N|nmOlTbO(Sgx$Z z2v4+`^%nWFGGxi;U`Y{_srKFN0NFU;emb6HdBTZoymEFpJBapiaEylE0T>pE`%g0H<6Gd}>x%@z*CZtLy2hdaL1{ZD~EG)Tt z)Rsj}*Uq*n>?PX4gn43N|nlCLqh;An6Mv^015^DP=>c!)-wKjiKwsR5k z_HkVhBb6!Q?Js4wQ95}I)dTHCd*MfbEKo;mdqrvq{$GcR`TUqs>jwM;w^Dc}oxJMf z@**~6wBGH(_Kty-y0!cInP_Q%m>%z*-Y#G6S~u=BGA0vdx4tS!7$SvC)s((gwt?nO zt9EtQ^j}hdw-3n|fc!wN$^i)1xcMM@79T{n;b66+5`n1qop~p`6KVNwr}KXGQN1eS z${x>$IDIutAv;ojhJXaD)C5tx1Q9egic*fhU|1EDJh9c8T{*bvLrkbb^$My?{m2NJ zXq&FD&7wKk1e)Y%dc=a=Sbf9e5Y_H7a|FsHFFrV5y)yU5npmE>qGnEN%mz|`3cxrMRo`ot1CcaUtnVz9bT)wZ8C9D|pU^6wxE!ZTEEund=*b#HL z?htn92@D=TOkAcj++ThtyD68fnqGyQ5aOSZ{Sktbnp_dYDSp(Ih&BA5qnEVqTuA7) z-Y4fkEeDn4@ezO=FWt9$NB!W^57iGEwg%)!F_1EM-EWzIzaw#xNhYI|m=`~7TI4Ee zZ_?L>E#nolllf9iMXMx#J3{NVC9~`@qD>cTrDeg(tFWWW?EiwjVUc5~z04%7-G#&8hE9~X;=w+;Y;v?4z6)4|Hmd?Rimfb=n<@*MG#MW}M8kpQ? zA0quWT2rWw7WzXZX51p7As1|nEkRBJ8ue9r#NJuR`N{NAAgxEEiyOyIHA$ldARnHt zaY*;G=@A>)2h;wlrmix+9LHd%6T*|f!o?K}TZPZW*0fq|veofkiC8VQjKgD@rVOzI zWb0`VHe!ibBh%vv&fC?nVd`T$F?wow*VW?3(LH0~Vfd$Y3PYneNNDZCfe|Jwpz;{^ zQnlwLdWph2CSr-T?m-fb4w|2uYz4|fn@`!=cgyri)`QHTFB;fuF-H&k!aIU!vrRee|_Ii9{tAGw+DLzspaTy+uY9|M;m>^ zu2hxZu!b`60Ktl*kkPH5t2i{ODw91ChRE-3Wrp5Od~MDZ?`~O(g0U|*grVgC9Z0@zJt}n~thSlvZsnQ_sn*3#`gOSJZzLz~IF=L)^d^PHo z^oaEP@GFabHz-5Smy@b?>W4XluB`#a7A+f2H&ab<#?5u13hGtqYudQe3|nsbTV>?!D8g#7v z2@A+t>%`Zioc!VDqtnT+_P4un>13&YSC>w{?%z?i@ZA{q7*V|`*W8<8>ZDl`?lUuw z`OY)yKcIOx_SH{gU}nd!&8`Lj6)TK|vpjas` za-%If^E4o{AA7LQWie~WCIZ{UXI5vKZSJ8?ilf{}P+dP$*-n%`Pi7y>B#=oCd_0De z#rq;RKLi_NV9x^Pwu357Pud{I?CL$B(#btN@gU>x_A}B##vT2;G3n&a{_bdZdYz#; z`LP%pBfv?ZfdIbD6MSKwi;|P;OVsJ?gpih&SJ%M`Wj01GynuB@(?VI5nH=tkq2H!_^lrK-x}3ns%ojm_tgCzCz-Ol~Ad4 zh~*)4K69b{q+z}EIi(tmG#p|O^RGW_7{vaBc6~!yz3HP-T2^UyMrjk$bELNbg+rPg ziMSh+o}*;$(8T5};#Pi3x9Xan<28eODpjtu1;znxw2zL=-5zNZlH8%)`JF_GN9TM5 zu!7ZYRxkl2itWc?!lrJ&L#!#zxGdHbPyqf{OXgVi$CwTv;-Oc?z+@?Kn}lGDMsW6K z9&C@xV_?>YKU9m;{`Cg-k*3|5G6H1qM>z0Ty_$@8S$>{p7|FY@FqGvj_X# zqp{qK=Nb)ZxVT2~T#o&!w7{AM$Onsul_9TT^kn^3wfgxXY4r+cWA z<0uVkx==#w35N0_k8;%wv65M5`x#)aBM@x3c`Dt)a%(sow|(uE;gxTN^7QX*7`fUp z_U!aydQ$bGL}o6)h@Or0jL@Hip=$%~>#ExmEzc>Mq=Iu?(hSx`WK~QL^C!xP)$k`pxHv(gS|e|^mGi&nqV8i(vkk4@fliP8gD2Q zWvgf!p!^`a#t+3`#Gyw^I(rX7y~mI(&jVU z$Dn3*bhrnKiT} zRgR3$`}BC3;V0(5%KP8SNM-)?YnG_JjW)}~Id?x^vxl*a<;)&Fdjp;N-Y@>s{C5hI zDVPymIH?Yly3_n8u&@6}Ps@UqcKTu|XH1bQ!*)0C-SzKlhr!k4-t|zA{RN2`r4U%_ z$z+R}Mc;{L8%xmCQVr5r=uMY=LPqHk%a&tOS=*gxeU6mtzFwQ^1j({=atW!`ozn-V zOP=LU>p%mm7hTvdwWy{Ezza*}>XJ_0N#amS^?PNOyg{Jg+7N?f3-|hm1aIJ0MxhGL zVEMUeh2E!I1r2-bMXN8jpy{7(3_?IiND0G z&O7kAn^+A$>U-L;aW7SOB3r?eKeSsl;%J%siBDoLyb!FF@KKQq$~)z7$_kp2jmgTJHh(DEP<-qZoQt<7*qP_(LU)$5HAEWz-2OrY>0l|= znLt_5=?({7*NqXbKIXUMLVi;HMiLUER(|m4nn;)+HOPzShW#a){VQAQJF_!y!0a5 z-_vS?*hf{2-*pUIBe^n))pF6UnTk>EY(Z!S_2+y{{m|E5{sbG>kmm22c;B!K zeDJ`e7^~VcQ!_M5TE4R? zL!!k;FqF^mhTUX!-XrFH#{aEin{E=N_AOnl}8Ht-ikN%X1P&{ z4Gw{X;>gZ*bX@Ithl$XpqTYLKj>pK-1~T#3Wrm2NMNEcMBLao*7%lQxVx3j8HyYW| zU!wc2TXQf9G2BbsARlx^p)aIf zf4OVu>)Nr~rgQxe_H_t=C%7FOiEDZESWMB|d5fj@mt5TS>&YS*$J#JGN1=$=EJ#HZ z`fz*6v>1gN2j?r+hCMQ(OO}Q#`Y<%*G=*)3z7@t6H@0JwfXdM&rDfyx%NFq+ZMmBuIZ9o3t;Oa*^s;^AN>-c0T^5cwV}Jqaa((ZQ>g zdGex?LC$FWkk3P+^;w7+WC{k|^kMW}lxT*}O67uMuoeha_gr^Qv^ML*h{1nX0fS3a zXgoNpvT|r=ahD(3&yzcfn;0AC%K6Z}wwsDuz>~w2n}+u&lVVNYO5NSGhd@mx_+mu; za&g2-lSTY~rc_3+)PG%K32ksGcXW@LE`|C^4@A;nei~L!7 zhB3nCVx!2ZXO}AP(&&8aUhrYa6H6CuVe&Ntrk|Nk{`*C(As1gbfqCCB&46Cvx45gj zGdY__PF>U(?h=9Ecu2;;rUgvsAbhf=Witjoib=2 z&p*i0t5XX)J|5V-xSgWb&gA$cHaD&=o}w+~sRb?X{iJzulcfx|T#Q%T#~WB--?vMR z>O7@nt~y7J+U&eR)@J92uey1E{+WjB=fX9pdGU%uT(yRaQWT)Gg7nkjD4qTKD2cVY zJJpxuM1MKPE<%-<(E<*k+q8M{%0hIfh3E$Lg>FBOuFt~sx5D)AqcGOa?zQ!eEPwTv zMgG#^FK1vcw{0vYb$Ya4tJ;tFbAC9Q8n9oei8AXtQ&-lY5E-l z!~uLcs$HW^153Mfi3u9G>TQrPoo&Q*+cRY;cEQj^8lNuI@$BC%@R{kOTKyo&r^)9} z8i0l(WmMt5K1y6QjV!@eB@xcJg(_l-HQD@V4{d%YLTI{V4m9p9?X@}H6@9fAovDn`KdF61146eH z#j|OrH(>xs+=2x`n>si>>Qh9T23n@1xo4B#Ew-sB`QSi&ywvk%Z{gM7RAfSB2u)%-D)djzL0V+U)08PRczE5?k7WruB{H{B&1*3D7Y;E@-T)R0AP zM9Fj95@(>Udcov_f{ynFm}eMvbN0j`rkJoc)ii@iq5V@EGSuzCZqX49hI?A8DYQW< zoK?9;@Z5tc`wkH6K(o`7caCPilSknG(u@~(!bXc?8gN1TBxZ2-fYFa?ZnQqAx;xmu zJZCGk){fxR<-UqYu%!yCkRB|Pa96{C?)I*iA^4T;5y2sX5qlY=F-cnHzBn{b?3F|E z#QrF}huBwl7_tB2iQP#8rN9e78|gJTq?6|Z!C)=%-L1LdA0{SZ>Kdx-Q$&4cur z80q^OAICA+!@pH5YWxiH4-+jGmK-29&}}9;hFd>Y(Dv?T{HS=jTfxig{L8HiUS92A zmK40a+`n8&WsQ~6$$#3d8V^mX3}z^DuW#Z5*vOQgXtfZandE|AUNK8q4TryPR0gs< zYNC8gFQ|J3wXozopsa40LTv8UGCvL1T&);qa-aNke7BaZYJR&d1tzXzdq|=uL=zeLy)^om@{xRB znCzzKvVAHCh|hJag$Kp_eP)p+3UzZsr->kWx-QYNQ*=O<@YJ~;NACw zSbkRCI-g%MD$qxXsGfxxm`KC__x+w3Z0Ixi$1_odrGEOu=p=rh3@cbzAmTX?529CI z&unAFyCTfXot!UBE>{GIg6X&R`uJjftR3P3pt)u67#9Rpj4gGCA+`fnENqDf&6PqBl>~|L)KhtBa z{f<_rF#FS}H?UGw@i&yeVf+oZH{03o_B`(pJTdB}V-NlDhGLX3D%A7W?=3q%PBvPm zx{V|nw!C>w^+=5|pP^avyhrnzQLpM*8`nTrsZ!}GcGBkzgFZjKAi}jjr))5}vCcQFy zhLvgR1iAr+?&}MB7U(7*o}g8`p$Q(!VfCUnrBBe1N*d($h+}LEgD>CTE5E}+jLmEG zr6Ikl7f_Xu?(pD0zEew>NiE5x_88lx0?K`vuU0vCh4CNBJxxyE?bZHv8}bH9#}%d$Qvmo-Bf zAz`|#hKqW^9Ryr&9z{W`D&}XXeun91I4AH*>CvX7A(gx+UFn8}l&)$*Ft%}cQjx55 zLz~uonrI`uxIGQCw9@ctxIM8O-Z-W>YaEykQ{>J9SY@U!_E!_fu#ApjDe3j$?uA(5!0s=xA{mx}A(oL(sV1r6 zpQ|p&1nM#}UzOVUcUF~`w(9Qg8@4hIYdHP@tZK5$Q^w?R9J}Okd>fZ=_T3qUIAX9X zdcp1sth)~95ln(baI-sUl1Z6TY)(8jXpVfr_AzVr5Yf0)U;P$mhVZN!^Fx^YX3Srh zL;Z@}+vQY18_y8XOUUTKxPOkh7d-<+)**tk2kYm9Z~0O1qiru)(gnS+bJd~X{ztj^b_5T*DHBh?C>jPt&9*D-fTV> zQ-F+Ah!$;Sk1Xbi%qQyCslNrO=Y75i8p}x`|4d^%T61_=w=&5$dgnXA@>SF=@})ST zB|b3=XTWZ`FAg(nt1RL~XgUww)Ic~vVSl7!2dS@R zny8hL0@2iffu-fUjT3F(DGiwepeAC|RKyXJ=BesfGpy>S&MaOg%RUix@|OKh`&8aC zA?e6hn#3tLDobmD7P0BqrfHKVr zE5KySeMQrylPkX7q9~QT;E{6f%jVj4t_$TZbk8d7-W0?;k9hHqli#2lv-BdI8 zA?9q2!h!NmQh(bo zRfQy}=p6M%*W>*Cfxp&u@V^vL_Tm=xxetsUQ6^$x+vZmf-q}mCc@6pkyKXB+&{F@qujcCjEveW6mJ3 zw;EJ9av;2~=YCmuKPjNQ1uD=uQJ*2##1qOWl|z zZ{e-&x|dG6*UhT>E=XRP`k+jihH=vwk^g_e-$VW`R#RHMscGP+B_(=`ruSpKtX>svUW^#2f~2ww z*B8fCl<}P_ddG_nD#QQ}Vt4^NoVq0A#|w4Uos%cxFp~^PFTRETWo{L*73A_VQbS#c z75*t_@u+2W>GTRvPiODvs>zjj(-hC#OnVACJ}eC|c9K4Ag^FgI7tQ?OvY*(9^Nzoy z@1rrcq>((;deW;${mq5YnxsL+vG)I2Im5mki1uNk^<^q5W^{?xHe-9S4X!K=Q;dz8 zYA(D-tb1UP+MnflmXUtcRCA`i!d^bEoKI8dD6iBxd`4Rmi;Z<9$R#z>-HhL!SZ`$4 zYq;wzsLSk+s-Z-UJk3#}Iu~VvYrAg5|7V7>JHwm-8b&qMti4+W;QX5-6;?QpXTQ=s zp1q>1y8b~#uNQzrfbAo2j>ck-66(;EG4)l_poO0l5e-@xA1#H zm3>sICZ#uFUj2y-8!d`Ebd5e;+7n-5#%2Z)JF+p1vNc;s*`2Q$@9MF!309H>cL!_J z!ZN|I3}r&14p}Ny%!eFu$5aUd9~xL@LeP=zKX&fH`_)dKe$iGX_}q;BdPQi1e;Mm{ z*Lp-TSYynyIEfT6EQ30-)QJ+P=#U(|q1O8)CER9&V$ zQwF>1SZWH=NDrg{NjBF$fb!%-B}v}bR(smrrQ_6a>YR`)Ojv1Z*MQ1$uzI)iJ-+o` zd%nthF`P$LPPEDct}us&M){K4*TU<*TI0XY<7hacuaSlDbkre7> zVgh^b0L#hB!=Pq9ky)tLRCBWbuH9PpKyoypuIcNaEd3`w{bEZ$z|vzxJPr0dWWKZ` zjVjQoOj;2Arkvwk5yPe`Zna~aTYtm5sOcI?vcI7xhSZ8$zb%XE6#1?FGk@Q86+s?j z@~8OMERCE=^Ku?A8xV=qcwj8`-B1@9nHB3Pwjhf(+6qwM%%==f%17%SlIWR(N@)(f#yX+E4XuQFbp?(fhILkkNVhyq_wgMcftM|@ocG2u_U!0inS=Rjc1f-U8r{jlHeml zZcy^lpik0Q#z)=cNXvuM$E}C#ttZe`5X6x6#XWAf9=bkn>rw~mGb;zZ>k;)1Hr)Bo zZsCb9=#>5RMdK8pZHSG!t#w|$kC(OKV7J}jq8fGy)h^pGO5qcYRX249b$CsNk2L!3 zhgcmdPBhVEoow^%VX!#G9tbig*(jt5aH)H>QJGVhEE`9yI~*5w2gDKG;fKD&e-$6QX=D5w5i3nGCq!g8!F%YGi~Gq=U=FO1zEq`tJ(?ewLGnfq(ZF6d8F zj$ypEhNw^_+*@D3-cSqSYiAr(Y4qmwFDhUFswBSpFCgs(xpx4TATyt69hFceS9wmM zz2DvOM@IW=OhqWbhp&|}q;w2fc}&Ppg6yoX(l|Lc)!grs zSBv9P5ko1B0I(VdF8AqAi3h`RfC`4=fX+rU?+8BzG@O9^7kp!N0E_xGF$3{+54QJ` zjdTW-pF+_)V=`;j7GJke=$^xSt6JAX3MYGOKFi@vHDCN*s0K>hcKxL-%5Z{(66@X1$jaV59G6BD@W(LQ$6 zi|K%Lm6%}or|;pRV9>f)nA5Ra)|4k&Q@nBu zN`)c$(j_rfcY7r~xoK23b$|VV)J3&0m2GV_`puEqW>ly#j>yup=6#d8FUM) z1_*pEu*0vw)>QM=&Gv9S52M;K*(5T{CVK&@jCzv~%r(Wb^x)=qo5)0cA_Q)#+3qIVv@y|Cvz6W0`{K@YdCR+{z%{N^VT(9V zjRt}Y|F%oZYT`QnA0+C!s>k?~nDMwuiG7)3*NO_|##{Xpn;f7+ryKW%rO}&U8j0=&Nm>u|UGFS%?0P(s9^M{>XsU{OyDDTvcJD0zj$Khvml*R8_`}1wRczA; zYv6`(PtG|bRYCa@GeY}PEv&_8JlK@l+D>)WS(mCz5e;ERw~0q#f(KN-J$zYyMp<~J zBzJ)@W;S}_BxCt~R(O^-Gg^i0OQZcV0;I193XjJf9%d0^`?brMakluVaGM~JL$NV= z6VJ-S1zMi{IW6EWrg-q&@Ed88n0-kGiI)5xj)MA6xj^mX0wzE7gXW1bd1?0YpKL_F zXOx%|hN*e32FrsR&l}+1{!L6+?+mqELhzT8>Kc8P-~BoUQX!C!zOf1+WG}vff}S1c z9kqI2<(q?Robc86EZ;4IK=nMZ+0<| zYJt?{%JE`HSf=s z^cW?*uW?fe=WWnW^{F&RZ6_O0DFd*SX>{Rfth#-?nC|dT^1S-3EpvI=f|0jar+2r^ zV)#>^x4c^+S+rdr+1*Tbd3;1$Mf$>&M4gY>ZAR8AO|D#KBW1(7F+QknPp!4O9rTM>Hb%*ZRht|ockxC^NY^#(>@46k6$Ho{W zY)5!(rM>EQPyx2NUfy?%ixtZ1wym&T+BdcptloxoL&+1ix4*Tz4Vw_l#_G0AwaL}( z5RdJry|6t9m>beJwlnkC0*`I7$M)jMJ+YlpfbAcCta$H;7?{=V0AagNne?XQSD0MF zx{dSLN<6mre;&)m>h`T_ldIb~9^3i7u>DPgW^Lctn)BGkdu+eMI}v7^*$dlc1=xx_ zw)J~q`<1Z0qD*?%O=nAmb(`R^4fWWD^}<$BfbA+j)f#Yr**7*j0?bRU zdXMc14ZxY?izmghF-kt9+T9LLIg)J>?Un!H`b=w{*ept6j9@}9a+c~|kjVZwP zs8<)BIV@Hvt6NgoX7-KkUbA?bRG#Xwy|vovR@MvKYpPAIZh^;kWG`&@1Ln5w8{6m{ zwmD52bgj#s;}L${3*l)62>)IT`b=^~UC-+6D};9{litMit^umvoS8X=m-dm&s5m>bZRFfG zt_>Kn+eN?}ISEar+Ew&IcA=1Em5D5qEaBdSeQYQ?Hy0UQxm5d0hpeVWSq%5O{2gm4 zms9-ZW7Z*fn(8n8{pB*eDtWn;zx;8vJ?-W%kFT<)1N~)*f{zttPwfr$0AwB?(@SV9!CIejQvBJ0dY**S0Nlx1QGUVUuXGn5;QoP)ewLUY41 z@&s8!W%*d0Jq&|XxNk0|F~alfp!h;oqwi|@X2Zr2QanSox{;}$)+W%6%TsGp*zTU$ z=AN#P?|G|uL*4|b-;_Ut7%pN8FtX*Fipdo;?r)be0r=3Hc)oxKLPJG*Zvn-!PP8^6 z2~umk)}CmU>t^a&Euuz1shg|p2_^YVaNRf3p7KOUwC-ZEgahx=cQ#oC?;8zF%QvO| z4Amg*bC6Eo7^JUNqI@G1K!YIabkfxW5-rPhml?8wZ6kkoCHXY1sZF#ozh@VJhlft( zpr_`co7Q}lXtk9X%jej5%GZh3AL%*PW{K8qEEg5`N?%-a_=#8OOVvUr_@yV(fLijk z!Y;SUnH7qVnnzx&jP;bZ3|Qx~$xNc{LBY}6Mn~K7c3Kx`tIST!tK@;PqfHNkmMk*> z4i0=iUT8MF*nxsaQXIlNZFJ3HW-Zuwt^9y&#aMfju@Ow@VIzP)j?YbMIAKuYDK)c6 z1Tk(4z2Eti?|HtNVFzU%fyPd3$(3RN?NQF?3Y^F z(N%)`(@_jq)Fx-Y=Xd9wr5- zXduF8-BA61h%2X=% zN6~rQb|Lw!hC%vnlUphOy=(QKCVLg^H~RE_Qr#w<7>Wi|YR#?$-?iOj6}Zg2chfh9 z4$~0gjrS-GQh*}nI~smgl-v&izOxl1;!+eQ*3+MRjSso(F&etAHtq(31F`?Sj4hz*xc{*W55p*A^;D{<~I zq^C!0!+mwvg?qbCad?BJ?uu{g!gNsN9NLfjDXVo9z*zBEwrOx*duUyeTZ4|0RT;FEKZ$w{khCyJK4*|Km4&p>Z_#q_37FAA5WrY1J=3Xe7& zj@FMz^he4>AJ^?1Zv8q!j&#_$+)mJ2IJGma!2qpO@)2OS>T~$YT|qNNErH!_K+YKG z8utj%7>mrt+#he6cpi1JJc5ibn~n%$=s+MyD4b2tQ@A|&I%@C9LKQimQmU6T2rL!y z|Cz8Q%>PH?HcJ1K@Zo1dfcl7_h;%(u`+S{bkQ<bU@)7@m>0kGBw#%Yf9`}WUuiItz6>E zLeri=TY)CLrEv_lc!77hjvy8U%?p-D12zBaKHir1$|7~<=sYvgAOl4L$_P&E>0VF@ zd0PCR?Ub$(64srmI%PH*;HkCI&M|5s%R_3_iduL*wo86lc!vLhTA#AOk)u|H9Wo^U zXq*yYaQ?!X#Rgu7V=|!$+GqKxkll&Mz~)E(hK>9%1m!WR>63rQKj{s>v4;=s(E8w$ z*az!|FUukL-{8x?Cw#^CgwI#_e=E<(@0mZX9TN0^%fI$}!qfM@SN^c;_kth)J>e&O zPx$)p2|ww3!cYAl;WzR8oYQ)(59Ff8^ycRXUa~TW;(vg@;(Nk-wIFP={~`Zd|5N_M z%~F8a4!2R{dTdxfLQ-q)E^N6ZyIE)b0S!_{G>L%!P`*%J7<@e*n0?9%@B_fnS7#PP z2aNWA;47kZBzSqR@*$9sX*ji%H2w%do)?6B`G#$35@A{#@$<$PH?4WGVUxt8=p~CA zu_Wk4|3<|u#J`^nglCp^eNF+N&C{S@J#Y$v-9Ez0A-V6qjD;x%hQ+@@CTls|^`Fkl z>dS@e&50SWYuv%bC#T+Md>bi+!5#H3+MdRgNI6Ti-67~qa`qo$^Oa$g-VOXm2%DZG z%S+2zEGK@;<{Y!Vw5(k((WU{@-SZTx;w4W<;Ij>UO~rYNX;J&nn2VAk)VurMhyX2L zV5W88yn^4)N=^6XPnNcKKT2%V7 zsG69J{p1ZT!9D*Dbs~;S{7mz$1m5wHDjPbB@MCR!D4H(PJD*buuGsrg!v{3vkw7le4Zz2F5dJy-K0 zpJCu^Vn+g6~P2FF;#YSpEBy#fcJri}`Quos)#^{nqgp+W zF5@1fg?uHaQXfhkqy2erXOC4)aVP9{8?z@pyFPch4pY!y@P`38{9nNYxGHaa!6bye z<1W&czL)xhgZJLKpxhI&jdx}Y(O$pQk`5D66yD+vJ9U1S|@hh84^Qg^knzt_w_#Bn88np_>-S-?+I@JqzRDJ3yiu3X>>#tjQCKKxtp6@PJ>(r&5lOqp%_*YNc^|0#a{@3DkSaEJC?V~uu z{zGvt+jw2YIogV2w6J+y*wUr$%o_O$A6;1n4Iyfk$q~5(K~0=$jULcXF7Yc3z|zCz0gr@$yB_(f_fFd^v3w!&2lp`?Tg&5TjI zLpf@zNw0HJAzH&C&mY(67BxT!Rz^jL9`!F{o=pAggR~DPQODIXV%9BNdpIrN_vB}&4o=wJ!eiK5j?Y~~0e$b+Te!m*D zF8YmlA)+6}_zlI_);za%qL*a0sA`Z{^cL_sD08cdP0$4^e#`uN9N36m_yR#i6B&dr zX`cq^-FkJkj`P&${rf8P;RDxQ=!Z63SD~j8l3QKv1z}6v&xS=a%q;Sc3xb-WCg~u= z{Vxh?R$*~WT!Q;Q#UmDS=Xz{_?9ZUJStFHeUeipS5-sS4@St`EC!WR@l^OBKR8m{k z9FS-^!6)5>E2gYe%d~qxy{)9k=i)4env;J(uw*d$5i-S%dQz=)D_66(dYg)vCBy1qD?yZKq zHQqqeWX9dc8+P2e)hbOG7M6|yE(Z6*CfVTLxU)x|^4+Lc8T(Pj>;?1!DdT5RRCZ*w zc&n_HNm96Yp6WST785p^NvcqBRj_UU9A>4bw=s}qU5~gY9#mtxhwY*!YVInsPStsl zZB@;TSYK?|yhelnu{M?j7YDEQ#{ndh(dUJOky~xMk2I zzXhgYcBubw;g&4AlEyd-__gPwq3n3$u*R_7S>jQ zM2vp*>X6Z`I8(*~A(tRmcaP}I4r*-+b^F?r`%(1r2`KNDpGh0EhHcP;{+oFESE&CW zF+e3T7UF#1OvEwm?(Qg)h%ovpjD;u-f7c?vkEorw2kR%Sk|iEh5Pq`E@1!+V017lI%cSlG9TR@vRgqwCuR9wv}Z_B4_4jx(T`wjuV?4}b0H zg*2jE+CPRT3NiRwwMi_<+!>ZlQ)f6yEF2+EpA9KRm!3dk;XF{OfGVKE9-_>xD+Pu;ZTX)xmt-%+e7_?TPjZMzvTEW(J6qsmPEW`74 zrq^Q=L*$2V;>U)3Rn-Iq)$F?o3PE}_0X@ZquWj~>kdql~__r>8&Llsp4=a(?Yy&N+YSeR0a%`F_?z1>VeyiPmagIu~w3D1` zkOR&C!8Pm_Fz2-POAV-;Sy%Z3{z~0$=meIt*z^Z#AiuM{@nz*t5Q|Jf-jh#?@?Cf! zNW?LP>3ikV84yTECs7c;Ss56DHF_iMiL9}1(M z^gl+Ens8*^j?dhKEPk`Tcq{kaFR*y18*>V>C@D)zV(^*+x#m2)^@Lx{;QJ@-GjaB~ zfN_cbVs2gf>3Da5X$t9N0uo6?w>c&Y&D}*!niFJ@8_|6;_oJSp4Yy6Ls?p#(1yw1e zHLfMwzU=Jn`5$VJOptDoanvgwt>1AQZkJg?DQzfd%Z4x0H#y!J>euuNnU!cIQavqQ zAh!}Nck(i7?esC0`G<{%sUuDZJd2gOakvcRDold7jQO1MJhiVp4=&8pLk{l?G7*E6 z?^2aq5%Ig~S%oKK>8UP`CQGdxJJe}EbC6mhXmDDSv3b7Oyi;4$UD@qk{`*TmyWmoSTG;Kr_@mNzQm7&Ke)O~lPxQfSe;LY_ z48~a561SbnFj)~g6&O=Wh@TsQ4P?TeYe^KzELLsv+ZnH_LZ*(cjl{c*t>iP8Lws}0 zT}wX4&i8}A+Xi%^tX>{sFJ(#HIss2Wu~2CV&*$m{l=Y9sV*zn1LtTX?q(+)V zY_Vso?@E18zW$3H`QqC1Vyd($=dJS!J{TVm!XxNdu~Al`BHYhzvz9x;Ujn z`$fBG5PoKw#U!!l1ks{i29D~k$@=oi@v)Y)kg$*U{xY3B`;<^Zk48cV&EI$tZL`7X z;U#30m(da@UP_l2NNG(ky_|NcM@5i6xreYmQo=8NE^lwj3+sKtmoZ^IRIg01mUCB^ zX$n<>=QyGfjp17wacsxi0}d-*G*+I=tco>p`qNJ0;&C}~{jzm`D+k1uHZU%f*oydS zKFEgRR&uM$%nVVyJhtT=LxJ@O!Q$>zQ%XDGM3aZ)vWI?{rqJOnwAMZ#g}0=C#}Q1AH8H%%;ew6k^Cdt zk@%oOoy-eDb@welGq7_buz~BbFmfsEvG^lIgT}|!(bfunewSM5r+7yYQkN;-I7QZt zrg-ZME@M-?Xm$tJY9)jCJ&gHYZn`lj3o6J+6~sM@40r#x$iITWdDVXjukPa&@y&S8 z`7l50$*Ix$W^Fn-^dvuX+Zw>FRA#d9VsOpgES|DnXWr5jqMoYbzcv7uP2o4$ua0or z)BY=WMt?|@N#3Am4T=)j*u7#iOg^jiV)DK^E84H3Z(k}QM3yZB{qkmOtCQ@)bPti# zolfoqfuUyOj(PK3CYky_FX+l7=*sHdap#(zI37V5+VI>AUUhZ3XHG(PJns!#UVOy# zY4pP@ync9y_0f-3!lD5V)LP=M<634dcw?oUf__p-Y5p~PW~Vp2C~NO-ccNoA;B zooFHWu9$jb?X4h(mbce?h2F_n{w@v@1ixreI#Q2e1X=rVr61l`^p_P0qKymE0~HOH z_>t!cQetIBy?vu8cTG`+6kct-NGEsjoSbM4cw__^5~}PcjC{65CqnhBW8&x@IgV^1 z_N~_)bkJfPcL?1RD+BiqBQktE{Hxf|V8=`@f6@1|`XEIo;e$z@nLG48lYC{pSU+Pp zDspqe560;OcZLW1^9C_6%7y+Pf&~WlIg143_U#riFlvNp!42Wdx8$Zg7Gpv7YVHc>uk^P?zQ0W?r7@a6 znhPfL3l8@}u}aX+D|Nv|cHNI2P9y@IW3FDJlezT`*0A*zJ~KUHz2lJtc;@#3v6bd& z{S|r`?FZ%@WFh4E8opyGT0d|=w2CI90|)n(Be$1g5|v;nFLx_W@TF zg$_De`lOM;&`@=ZCM%Ne$b}|~FAgsguTx}th+BXHriN)(TKaf8Eddn>KiRUTEYY?Z zeA-lV+t12rPje%3*FIy+{F6swbKW{Wb(!a2=2c2fw}zQ%O9DZR8EI%0VoAE={KrRa z9_tCzzQ~Q^W0h%wb(nd0!_#3Vm&CxJSdkkVg8A-ug9rQLrZF(+jlEtC$l(5;>4R|IKdw$iCEj7%)!V8*7JhmJ84{6ynP3b^BIB{-*? zWy~;}Y$d2~)ir&*Y2;lENUSpghRmXdpQYJP6t2C>|27AD1_Z*@ITNkR_G+fcw&}KI zdt=YeqTpP&hb4{- zlH9|5zNXoIWYysfjD#>8akMILYDBoK%mW=U9B_D;lpYQj?Bafk6Bo@p?fzKHY^IVQ zq6THdPnBg@x4^(^`o)^pm}Q3$j8Ns^-O+=+G&h#p5asr*=~dCj1IhPj>{GXT)2mYJ z?HtS94r*9npGE4}!ueK+k^N&}CgQap!maOX^3ZQ$xQ)k}I5=GbU{aQ;d5lPcHDlt7#K5$f$u%l(x& zsjVl?4Z$b{q<-9k?VgC`W?)wW=Dx*bPZ4kbT~A_6{ks&D@6imdTpSqX+V%UCnW~?m6Pz%(^ z>#XS=o&}l?>{-am?6XLM7x|ht$7^bw@~aSRyol(Q%RG@uzB4FR2m`AH%-!vac=RelX%Ht zF-nd0C25MN0<#KHL z!CRrn*z}!Oh%D8gOrJJ3eceoZ)vQ;f%vK5mD5Il|!W=bYBtm@+s-K;Fju@ggH#vV@ z3(Kg|OcJ(__zA_@)EV0&{^O>af7a!y-2H4Gw;j={m|zieY)Z}K_K0q%>b*jw{dq2P znN92WI-DwQrz+;#H^b>Z8us?yuPia+aw)XUA31eDmQGgM)raM>)stiPj%kuRQ%83I z3-FRa1}YV~b&T>*ePkM!pBnmlz0DvLrT%~uV&cP0u*H@G8b=*tt+E-bffS_{%8ggn zt9a+#KmYWe7pY{d!3ViuI!lv?%>%t1ZO6)NrXogw@PTGPpRk9psFG;MHhR%CDabr& z3k6Jrf|i9#-1Cz;wq=upS1HqaeX7RI>G2fFFiLL^Rjo`2((*ZA%l`9@S)-J31>;%; z8QWsGpUCiLB+YXXgc`P?mvW;;zgmrffneP`Gx#9F$AIj!TkazjbTC5Ed1`Y)j`Jt_ zRFN+~1a3;ST_|{on>^?UhTsc+y=|aLVUGU9*z3;1R6rCtGppme57_ZQV#wJ)%R#?)~ zAbpiJcsgw#Mf;)esa#~~t(D8{$~;-u>W=CCIV?dQj!W#ltY24G&b52B? zDIbYOtDh93spi%|!h;jCd<>rS%sC<<$tI_Yu`kWBHz_u-G*4EqFvgc29@$xRH$nZb z%yoYNQ#8+aWKF>5Cef;nFV)*i-BnvjvieGOUE^9VmE_5br^zH|ze2Snj6}O>n33Q* zPAS@cK+0%c`ez@3CtUMbgjQXF^^o|j5LR>j#ZOQOnv*~w9Coy`xiVERonFFOD_w6t z6;E4_Jqh?PaJ*61mz-quw`ipE*8+K1u7Skl;aTY4$isRv0%Ab8s?l26B&4>lp6ykH z%?=hW*j4@A&GlYe5Q6>N32}I(q9XU4bTS|xR8uvw+QdW3GbMbJK ze|#5zwD>q4-DtQVd~@pY%yD|YmGZgSxX@9Uw@1Zfc7+lym##*0P7P8>!D99S0Jdp- z)@1gxdIO8*VLsX%VR(20`gSg zU@D;fxvw?Hcvz7VI5VtBsogi{D^j87^pUjkj8+Q5o~V|H!d6WDSO7VeD>sem*>p7MCBQpKNM$Fk{KCQ8LyA zRYe%h?2j2i{szncxtsyn#Oa?!iZN*zA0(rG6!VNv_R7CIC)+DXh8U9UW}j@EZ6bvl zHhnxcuMCfTutDhO!aoy^^-uQs-|kY(GeI(1lwuC>$qwz3?B*aD4MehSeX@mXB1oI7 zZn`B49b2Rvp%<)^i+aHg@3DMve@TJr}a5ZVN zi8(_e5>lon{O_LxFq9Cfu})&}3=9FA7mNKXjm>pv#kJ+b{e7wKtNneM?vwt$Lict4 zzEbz~{vL8%Ti#&z6t;9!2}l6n?kgkrV#Dx#solfpW)r0Qgl7;95NezqQtf8fC~>f8 z1$qaE6sHo6JJw?}GrF{PM^*I~1!XL`*UGqmb)*bb zdCUzCl1((hyUr)ObzLMGRA4=vP?_k<`ud*{vL^KPqw9eVpIFOe>Mf9^oftvcTK;4# z&KB{^XA2bJ4z!buutzPD*5_mwp55pQ?>2V7v%D3^EFDrWf$h53TJ-I!BSo7-?(~A9 zqq*jZsf-tf%YY2Qr-BMZ{WLnnt*v7?6AecB-U7{-r_gDB3-t11j=Oo*bTh z;a!;+wAPRrtsLiCm1{Y}{rzU};e6L!BShYb+PVA92ul1)DW&l5_dW0>iHM|_Ol3*v z)_O2UMn~l4Z$4{Yq`sZdM%%^Qb=Ec=XeSY4^eeLLZnOY}j!z<{@`&12YI z^aPu^9|W86gzWA7nNA;sK10MrTQRli61Wj#HiD35u~|PKJX?(%&{LS95_A!uR;MPm zzJrH)Jy>VJLj&oPO5ey$waGs>jk>{Bl1K#x&7n6L-7Bw*NQ)UX2iz@!Ss)=)zxPf{ z_VpGKsvFt14U$m?$HTz&jQUZ`I`!$ipj^zwTb^0%1f`ol~?%ECycl$~lZy^uo zzSX9t0na|Kd(ONX99$EGVd{D8=L~kQ*q6cXS^w_hj~)8vlRaaRJu*7RtLC4)NxBXH zWU#+iNs{q#wcMhsbi&Z4$&4l*($6O|#nv@z3)5i?KRH66D48x!rl%CQj+i%bF|4)zH4qwuAz^YxiOC{RIwgExA#$;R)Vi3q(- zS=P)AF-mN?uf<1A*QuJyCcT{#E@erU1XARr@QZdEwF4uCtob=}$r+34U`1kcdte_; z&ZnHBPSy_U1SDG6mC{eC_NXjo9RkAW#^_({Dpsks!TV6}^4y;cecY<&L09OxN?10R zDfIbwqW^2wg|R*xzW{7u!nVm<->&!T1WTnqFUa-2+5WMKu^5@WB?i1AHowvW$bK_M(=-eLv%-1Yj0qJXYOTK2r-)4s# zNQQiXv%ZBfkC|}&#&3hFRRewt15X^}ScD<<&GwTf=4rv$fEv#_uWT{5|0Vu1+h2xqcv-GbVe{)e z=VFk^e(6mL_YCJv0VBU_PX~Ww+sf-yp!vtPgcI*9xy=7M;nyi|+?ztwBK>oM9X0pVDW9hSk^ zuFY(m%>2qkzd>x6ti_$N5Hxf(qcHEp@oUn}RX)?3&Pz)IQVR6cn~B4XHE-V)e{2%f zk*#NSW|XZf!+=1Jq)HgI&8(FK^GbtI&12XAH2p|D!Tscv?;tbUz~$oIS-VM$0uR9P&BWH7~q-*Tz^lF)I zt3H(%f2~;0*(dt>LWiH`n)hx{Z*Q0e!CXX2(!pRSj>V2lvCFcL<%6A8#V_I(Ii#^M-7Kd5jCj7)ybmeHR~4z z0^P)c^7k@BlioOYCKvbIP*luQQI~y({=i;ofd^J6<-Ql?Xs1?DJS)yo%N{L`txGO_ z91f?;)|?hi7S)-)0;X6I_-aXgsT(H;e5felenU_2N*ZQ4&ls61xO$TefZt21@0cDU4fWaUy z&BBi%-{@=5VuT0?h>;hVx^-A4>;_QO{(vh#(@!sA9*<)xN=X24tSrKy1+X^)0QGqQ z4Z5o^l-vKul?{Oa99S3C2~@U>+GH*A2s3;en`pC${nIEwzJ-)_8|&Hrp=pv%^ePu? zrB+i;le`M3InQCOR^`wq?!6?QXz+uz6fGpm5m@t>(n7cRCHIAQ7u=}3s)g|juCZ5I z@I&+yRAd8{MOt?QW>j(fqJCwW<8LI*xqE?=?nhYTrhWSyy#h|EW$zukMk@9 z%wXCb!VTBMY!%BxwH_ow(4%27QAZOYq|2V3ZEoWUAb=K36E5o}Bw9BJy?JbKl-sUySR8e!P3|L7SBe*hBLD>JsrcVqw zR!YWd#T=x&>R5k}0TQXK(54K^Lf)WKtTkw#JWds2$XQUKPgEP4|C>pB)nxl$nr4EY zwRso@k}%3Ue~xf~y4LZlK4JUYxZ(g7$FrjAR=bSkSchu05BkBzG+DeeRxg7lUYgd3Iv}>z-poF> ze1HCr;Qs;qKM?yOFehccu2fodsSENf{<1D{KfwDTOiJm%GBECtyo=)=#qF(f9R&+7MMu{vHCOHvK&!Zt@g#kuKhL zk74?_Y~Og>AN3FzY)cnMjHkfeOq9b@IOmqKvJbD}#2Hj`q44CgFx$>KBd4 zxHApWNJt%W=z1I@Vu(Fxmf_MEY`AE>h_#ZKC-nrYI3NCvQ6iQ*UR=nw=)%qYOBE+K zC~3sV9WoviZzxrJ*u0}TgHE^3V7LVXpeEtw>UTTj-TayJLjCxrP7xr$UMg=vL54@FvFh`}4tk(lN9Q zBQJbvk4zf=l&4Z;;98<_l)G2{E3k%Pv>*&!OAAQXdc8+4*E-_)ok|tIcmwH^>8*U4 z^x?R$tiToEBE>LW(o$)0b=(Z+2JXN(XdQ8h^0P})8d>PQ$H|&mThy{Q!{A+XFSMX0 zObzW^!z4}HgO8>mb@WAZA2NM&l4Y9wG>uYCqx2#RrnkH7vjF?{o0+WoorJ}}>066^ zqXGslcQ7AOEjnn;{c&gLer3@6b)mO;cQj`1-r}woc>~HLCv_~%Y=u0jlhsVYR)$5o zM>IONGEA1^4-L06)MB}0bSuMEyYbbwGJME?%5Rh>(v(?+yENSwcv8KMMAOx&mZcaO zO>9ACa|7&2;I}ADf0rDHaf)_!M=@O*WU&bt<)am;QrL>Ln_Lg+I@-fbq$#u_?bkG zf3ur;HgV@3kqJ7R6};wr?@g~`dy5_+gS15$1e7{4$Zk7F804GI4D!@~kU>`bcm{d- zjXZ-0Z(|Uq1{S@~+{Zf3ie@pg(95$6Z7NxO$x?`G*tJt!)BmvV>!gJ>iha!Z zpv=Jd04DZQbJU5&IQ z0hJjZm`YZeN|kGs8Qx80>QtHPurkSx$~5FFW7R5gy9AZ7x>;qcT7l8DwXe)${i#e< zzA{v)Q+;f@fcC1*oK)Ue3uaTan7mcBWN0^$y*p^9WOUmi(TbT8R{3XNRWdF2U&jr@ zxjroSSC06s_jxf=2E}luC~j0TFIe9x`32@+82Id%^vb+ZR9sv2O8lZ5EamCtNiF@q zKqDa87S&^_UTmJOyE<7-wJ2qFPM}+>rSU5DQ=-S=`YCmTMieo??Y1_ew{5jvhK}c$ zKDO2f9HGX1>`MxE7wrzY!Wwg{87*qOu>Cn#d8{~u+r@5x-MYJvF`l{AU+Q*%+JB5F z*Ut2A8HH?AhyiFd)C)J(Xl5ZBFP7+CQf*!8js%h(%ghLwr|#9JQFGg~|M;!l%iqPK zAk_pSRt@7!*mC-K{kEJHzkj>db(QDT+S7P@s+xR&blhoga>x%!4v61BkbPT|sdn&t z!#eG?Md$3K&2u!hiaUxG^(+clVS72Ojh%msdPsI@+{P2&`te4Nx&Csgzw8UTxnG7n zD7=dOT= z9V093@s@qPjgU=D(2I25eq*HV=AR<_4bCjE-}d!6Co_Lzd|+m*<{M?s;n%w|Xjy+L zkk^)-sZI&K>>&q4BCrNSD>rNky=;mN>fJw>v}|7%0x8VDljWz}QbUy+t2X2JQFLpT zJ)`VTh1m=BMN5V9yZXb`2XgkBH2EoS#{O~5e#r?=j3d7FU`7kfrF1LGg|~>YCs2MZCK$Mck9ev@^Z3ZRIj_ybI@cLV~oO zLgo!lnTclR$N_etK4glLnJqHg&sfJy&ieSw>o!%8e0?v)3C_IKKlHYTHvh1ZZDKOn zKWyB(j)O-|<)Jn+uB--G$@SX;Fso_&OIYcl<0ay=X6s^p>MAda2h z?8vg(%*YCjsj6O$r?%vMet!QrfQ}53)Q|)fwLG43c)9ZXHQ`NbkEae2^vpO*3e*br z_^_n+%OMtoLS%ji9fwjLms3iTRjdA$_ASSqG0 zRR$f-0!Wtp#_gm8Ye7pNm zy}1sUk+7sezGZr_oiiseGE8QUhYE*4g)<>1W8cT)snL2LlG8$V>t#Bkm@M%TLE_FN zLuXzTkZc*7*(oBr07!#7X{rTd+*KD5>|qk@V`dR2Hfy?UXd9eRn`Ldhnq;qn3Z&JU zuxq98N7jnn0OhJvl5Aqe6Okx2QgHsGzU~>oY>+B&O@g^&0MptafN8Wem@mvENi9j- zK0=mdY!V}RJH4wde#vEd`fYBp;G*C6ki=rcB6N9CK?5OO*kv)pO zR!n(Nu{3C%VkEM?Ej^2n1Ki_nJxNlVDOP+U;UOi-%tR_%U8V}QQidw5uozuS?b=qJ z46bEd71B{>*Za!r?b=q}5WKGl-dEc7GhsJew^&{AHX96QXbH-#dc1kE0GVE5Mni=! zGfXjfRgZh^p-GCaEm-TRMPS2N-4HgV%#AWxOdRPR)GsvZQwu8s&%P1iqIKdA;-0~U zW>>f5iF(^gDlB=h;xf0n;PF9~ju5H-(zITEUR&<#?=_H{JJ}fa-Ki0#O8~%KG6RNv z_*^k;uqrxGG6vR^%;`#Um6Bu=rO!k-UVVW(LSN4f0C*C0)_jAMgC#?C#72mmJ6#_H&Tb{Pevvoz-M!ztEM4VTDw0Is6Y0L)3Z8Y z+aWF6pWPdXblj_(?lPXWQGwKgkU6)k`)(a%9tqUk+IVVffe(?NtiqJ2?Dh}XRoxdLVr&`t-y*TipiW>>Sw8JE?AtM4W@|T zh*A!YDl2kZ6R06(R(e^6na2K>2Mv}~kJnwEcg-Y<=IQr?dF~=lSGAb?5AF!JXpA-S z!~XI={&J^XV4yAG9Cw|6>Y2NlA-|jBlcfF2jdJbUd*pZiWmEX_N}{pdZ~V(&`%AsQ z9O*BI`O7G~P|z~A;q?3ZO^M&%*h_AyiQM$oO(QoO>4v?O8)*Sz9NeZ&CQMuXC&I+L zN|=h&l@BI1Q$5s_B%_JxB(nsPaCIc z`1AB;-!p#Mhw(rrNACSh^(Ues2ZZP)tnh5n(XMO@(%n1U-!jnE+b5DTN2a zLXToLF?v>H#I!3*2+`+HPmXg#1mM#xFoA}`$xLenH1gx^H#)}K9fPI<{NuB(7DaUg zn@1M9WNer$_qT{6NV#U43QNL6qh+#y5*xpJe)Tju=|cPC>~TAKGQn zCn&OU$>eDZ`}t{4PT;h@Zzl>Q;J+7UcS$@&v&Y6{dsX5)swirgpTXRH9fKr!fhxt< zWss-e=nP{6rd4XBKA!@e$hZl&Zp&^c?;XyIaGkBB+vF5+T~MP^%$|Pf#|fU4_W^!T zS>rHpMplf@JYG|^V$vCfKqr^1Ul^uuUQR3!EYYFkGcH;6%A~#Wnll&>v0tI=Sq4N^ zk5Aeh?YM=S7pEoEbEnjpUOCZUj`5eV{xZfc^hhhDUOp{GEDqzYyY|Zxe9R|5-rY!6 z>WtOCdnTq;RK^BSr!ktIZ#mbIRJeI7Mp|olppj(+8)-T6aTQ*=*M3-Dyo=D`7Is3QYL8ma)YJ`&sW( z!Y=bQ19J+{(S&io-D}fJYtzrwrrD--py_n{W@D|zFdr6xjqgn#32eiu-ca;5m35~! zaFnLW9$P+EoL6T1XDR{?`}_(VT~3~j4nmHVkOi=j6!cdBoY*CF7`x9>s?5x!xkc7u z4Q3J__c9vCXTHi~Nc?!)GBXt!uMf5UI2fAE71~g_L{{Yd;Gtf)HL8upsCsB{ho502 z?)OQgoytYxgVZu4HArdc*8mXNie0&Hw=ez@X*bG`xy>wF*u2x!Wn~k)z8OgdC5SHw zdc1}tpxx0v**j5aaCpo;YRLkRLx9A+0qzJq;g7*Xi91Mqg+5vsDTe|d!UAcoGSAAkwqS6$1ZcG6*FBX23nr9l`d#3R;>mJ=?wmYV| zGk|y;Z5QR9L*y2rHQ}1j`(nLbVCC}#uJObOxu$tA#CR;aYnw^m=@Ysa96%U%G`M|b zG-MN>M@P|k8)9y#8i~F9;BcC3FYP9iOFz`ta;_jpo*=2;m`-8|18=2E+nWw`Cs!23GQG-EE8|!njMkL{eY{+k zS}-QyNXczJWUtH$M&Kor%5C?aA|@W2W9eTOr^obx2xB4R8l?=BqZ>3zh-sJ4W$qGx zAIr_aUZvAGRA%eLgd68x!5+0vqf>vMhH&PCMR%5(;%_>Q9pGiP`_)qD*fbWZca*DR z@ST4d`PBK##6YpwDiH>dgg#VgRh*5W>Fp-0!e?R~9*Qe(qD?u-P>!{~EQ_QAl#2`1 z@o2X0`ZvYLAG~4vZ5Q=m;DRkk>-Tng3gLFlRN67b9OY=Zqw_{j-=Z$PLfTg;)TNaXX)j{-E7NjF&#;7#x^0 zrYl&+k)YP>NEvBLJJXr6Nq3i6olDr7{qhdlnQD9P9>P* z(EoaUyzK_cqHCJZg$<5_zCUy7aE!fpwvD$O^M-A75cy6;k{M`dA{&7mjs0J>Xwq@X zZ2yaOMj2aJG1?;@#+<(v@k;NJp)pjDaC3R^R&n$%J6z&1aY zg4(ay0Kdj(T}ZQ2W`no{nrYygAB0ZyZEajdlLaH)K`@pI<-=0%Z;UL)+gLhh z3KkfU?jzGMf=K3Kfw5r*#FLivi_w$%W<^vdCp7j`qYZceC58+#?sj0LGnEnNzA%@F zO+~3!2$XHHd&?U*8{Hn!qM#CUPXrmD2MGPl8&mJx);Za{AQ?688A!On$Nkj!09RiWcB*t!*j;V0(!@BR+97#B653;Cl( z{6TY9D@c1d2H4bJWsWbadU|@DT!*QJ<;e-JTSQ1|F#~U#AuW1Irs%M8FT_|x`Bo)Q zzEyw8SQe^QSOaNLhlJOg31=g`ZG_j^QhWvY#Am%?sIM*soeIfpnPw+0(pejsapjz2 zd+{wwfO96b7~D=NW8gvT$&y|+8MnftlH%MbDfAO8UGOm4eMV0UFB~&B!V6M5E(cv* zKMdF;7?&BTZ_%qGdFA#$39=e8j4$PE3SvclEbD}~p$=*wpiF+wRAXoQ@DQAK1FJ^RY16E6d@dq2X$iBnW=1 zfF~;HrQeJ3^LO*~J`OU~-t^)eDZJR}oHvh6q*AFhqk;$~F(J z!W&T$CGH$68xvNc=t$~RVbLVhn-MFo(5F2!xunka8#FRAa5RYRKe}ki$TVH$RQY4V zG1C=R(EuSGHebE?1!n<%?rnmja!+lLpX0L@fJCiVVpG-0FdPsmSrV)H_W#CO@FB6U z%PL0fwM=oP{#$g;*_!TOPl)GQvqpN>;5babU6WqLFyvruH~4J){x?$ZpPycoV&}U9 zZRfkun=BqF2mVVPCkr=kt!ltNFpDBHDn~<=;fpylL*-7M?atX(x}6>I9(AwTtt(M& z_A6wGPW*78HOcA{-<<43%hu}Z4f&}g@`U|Re^T|*^id|QoKW{OWVSeSe6Q5v9n-Jd zNgX>BJ-ujMZ^FLf_q-u5OA*0-nIn3E8$e(U$Xmi{lJ+MNjfRgRqESZ4?zwun-#Ce) z+pl)V6T6oi7sa>}zJWb~KBf8jYYa4(xs7%xJtM|CM5;bkYEJwG$bC1&@!r- zi|!X<4)Tvq@xnjcg#R`@ah?o&+UZ$xTx@;7!XR0tCEJtud6K<(W9MX72gyJW<-VCu zc3+od=LE@M8It{r_;;XXyCge2NJeEy_NY(xn=Z-9gJkF^l3nSOT^}94Srxtm8`tRR z@b8t8=H6M&{m#)KA=*O)_+e5DOT&#PvWaW#CFP!Q9U+j}#D&3guya%Blyp6A z{&sy%ZiPJ5b3D{>VTNqtr$>uKvN>Ra5>18R%Pj4ur!u4Gvu874iVH}l??~m#^ghTg ziBSf{9L-XPR7SO$7@wsnH9OH`B>D;dO%8PCL%L)mtGUU|xDunu#gB+4niTnJh0Tkk zIGwKTTD`nF`PFyojtIclgo#dBFZw*0MxIzPK!TV%N3G$-5Fa1nfXzgQ$qgox0w(a9 za|1IYJJ9LGIuR4P4Vk*k1;)~iGlj_&n)V%{FPYvywabt_3=SIFEQU}fO5?N4_lmPm zI}c`tOcW+n?bG4YzN^O=fRF8x_(T_K+6h3*81wIG!RU~^$P9|NkWy2^{iJ!W_PJ*V zxwQdDligFL{a{-$IeDd#Qrfs>>7Ld)3+G+QUDC(6{7Gl1}txMT6*@ z)EpZkvv&eWwV44w5x`7hM}vz-s!hK)rt1B8Y6Qs-%l3ae$#j8jH*k7+iG4`qKbUh1 z3j@3S-5%Og0}~~+s7Gzp%BkuX3C`E#z=vwrY=2_z07Mv+X^Psa_ot1hNiW30u^EJi zNpu*J!!C7T1L>>QO-lq_FX5@F%RP`!LLdZ3q)#d@t*v@@+Hdhr$5W^I1kaJ6)?6Z5 zNE4K@EG$KnR?$*w**2I`o|PG(Qc62YF(B&~)l_{mZKK-sYpNO=l1YS5r`L145>#xl-WfR+IuU-77|k_gko2+@LOU^por|uN@+y|7F60Fb2BZe zo1V|%1^ey42RQdLQ!|A=#M}FNG;C>?TF?+obq&kV51(j^avm#bOCg ziA#|!ANSd#{VumNvv|o&*wb@fXP6yPsK6A&R+Gy59sQx?uOj&Zde%O%-aD_g@}e2U zQ~GD)iu9n)^O5mck4x<+W;BzyjAQ=1J90aonu3E0o3}?fRPcau@S4sXPe=}~y=>yU zb}1O>)ONYlLSjq-kUc^my94BXk_w16t$H%d_VFLQf`|akB#M`??Mk&YYBUg(IuPsWR)<799s)XqfsU?)ROdUU%_PH@7>`- zmDO)SN7JGISWi6PPtH~O$+?vj==RrrM(e|UkP!w-F@up|!l?wRUPOtaYXA8C*ObyT z>%Jt-Y|3H-@`QlEao)$6%=oF^c-t+Se+xW%%n4%-E?G&GzF&V=g%xs7;_EzO4QTF>U+R~uwAR_B98a_N&Jb;+=gTXsPivn?Ea zs#4>r5}}hleQP$zY$ictsfCeqN%z8SVGbSf{`oc~&NPm|KxVN)y%&puRk@sxbINVxAsG{4F z`nu?S)_UIQ7jkdXPJ~!THP`!U?yNdzPahGRtqGEjTH^PWuR?!7Z$8MX4SvOXC<nIAqlWPsg3~Clvw7q7 z9Ukd0plC@l^>L5t*@Gb6Fc{2D6JcirQWW8b>8%}t%j;HPB{TmsS0EP(iw3!8=ICwJ zbMcw%E!fe5GVI$l8lw7TX6CmMJYqF9Zd>}eL0h`WE+8Sw-YZbRMf5nq!5+rSzZM*c z2*FtoGEz{2VyUG8pKfOy%EX4RuUn{`?7G}+Z%4H97{6eaUNXTnUstU{o`i>x%-o#> zpSS9DHnG)*UbSgh*l3Y|das5RejX)MQXxtQ&`^d6G@5VeSrxFtGoGRbazDdP(A?Bj z`kC!MsgT9M%+x1(AG6>)wGq3H?19QuJGBZ-$H^B)<1`a4HOm zB@lZfzg0OPf728q6%1-f@?kbtY>lB_C`y0o*Fk?ozk~i|?uKe%77Y3tgsVpmHhQu% za=8YpU^}~{<%z_oXUcV%5*KmvrzhouQqJNIiJK4?jpW7yTtKZ~s zDcT+i7@x5pAD!C=u*vH812&n_3kfTVxzjTAgxSQ)_I^dO_Z(g#$fZ=;{1z}8x!o{f z{d3;sEg65)fvD#9P#LR>A#q7+-TG$KYhqgG;;zkpt2rI-X(6hnG7liA<+Hw)nYpU7 zdhu=J_h0R}hgF(33pYGZ<0CM?}%%8M>StI@hF+pley6sdaDLY4?G4*OI38393LtfAL28g z7MOJJS1e!eS9QrG{vLd8I))+BU+mpau$&fHB01yns5b4Vpl25OA5sbkdc8wRboHog z4JvzDYET(>kx)@K8!V)>ozO<@Y>XsF2{tP8Lu+LnOEhMnlI8=(m4D$g!IMFO&26N7 zYjnhC)=vrVU=G@#2M&+KmR4@h+z^P2w`j+r+*^``UH%2(FXpb0Av)3jSWkb(i_E(D z9ddA_qu-f*^q%{PLX<8m&>SR}W3VsV459rz=s=Cq`Vc9eehu=BeJ6^mAR2;`dxM^G?HRN8~H!9)`T5_o@&3I z+_CS=-ILs!bZ8Xm0Kw2I0I`N8NPx&~MT59&-=i5W=xByc^!I(VCN?M@jd2*KFRKFQ z5J|}<#iu8;w|hg+43$a042%>OyL+-@2QegH6;p+stCEHQNCLUSo{aQ*FjeMpH=d&la3@g+P%6|f^?{4$Q+2r5<03j32L5mW zt-x@npho%{Ld$y zp%iR*-TofivD51{Qp51{3^Gd8+|8m{U`^C!m>RFm+*IBw0Ei4icvkU9-WI3Nq7f%6 zVmR~bu)*UO;Id~s-gPyp#bq^8+HEEFg814+0wJ$VQa=r9fja#(s?>V@OcX9MO+!Kt zU09R;cWu?OX*;q8u~zf2b; z`C}Mama(xy8QVylHYVF^VU0}mJ!-OYEc(}DVE-jFku;40U->C^H!NRQ*g{6q?OfF? zwH#hJVmQ*F*+@%=WPRH`@Dmf6d+jok*2qmkBH4uVG^v!UgV#NCPKy2;dki-r|Cbg^ zO!oQ9-bR+!75Zd5>7S2`Qt+J|L?yvYCOlh{ej+4>8o;}_P7A6VPyI>Rtjd`&fq`>^ z=F;%RarnH!9EacTrRMVrW%;Be`?>1yNGZ2p)ZkQHy0DexTEe+(+FmSNpoMJfGGq{s z+2>81zPX86P|epPewC!vLK;qy^sV+RlM$!_g1A$OK%L#@oZYrBacB8=J^eOjTf7B1 zzU@%OrXULF(Q-Jt0YR4S06og`GKWlHw!^DB@vSG$Bp3iHx#N3_(InP9%9&f5Z^h@_ z4LA+kuP^L=BlGW>vrCdQ{;T6*;%&|bwhR#^HUrlrM@(V(7@zfmUe8!vv5~BXspTgz zHd?w!wEsML$5Ms{d<|z`ZnAhOn<2;1(VGlNU!^iCqM@zT3OK$@Va66aOh3GIky!fk zZ&+U;wd1o$KgzaH{_L^kCz+Mj_7A|)>PsK*Cj#^RUVTq% zEXT&mc8~VZSYn|)FqX?S(g;}8Zu=mdu1wuJ?WjlqjQ}m7^b-S+AQKQ6fY<{O1=1KE zsnh6H1nPMss?D+!pR05Nscycq7Lb-RsEPO-H<0hM;urKVx-c5{{Z_m!rJqs^u*>Lp7Rh2vr2CZ~wxY$<7G~vdNFD zg$E}!+Tm7EVN)-+PC|t(U9?y{r*(Uw1M0utfuf~-D1^OZv&Zng!!r{STOF0vPfZAy zy8jqb7X_^9Ck*R@Zr?y&a2ra$!>z{l>@_nM$`-1z5ok(Z!!5r`)f#JoU(5OkXcaTU z-C157T-O+-t_YftFkX9Rb)BJvkH)UJp6p8N5W%n8{4Sc-P2X3((!MjirCQ7E-UJRx zyZ`7BBe2f;LVF11(B{=N3#w3*Q_W78VhQ}V`SF>5lb_IfBAXj9p}UA-pT>Rvd?gs* zOqix#qs29hD`htO7NH21CO z$j0qnRjk(p)$GZHS3qv5Ij`76G)~C5+HKuSM&$j^`i?qGjJH z**im%*;5#aeWNs!5^%9r{;*Rdc1;m;-dwONhNIle7Q2M6Ur{^D^?1}pe-`~Th(>^N6evYqspLWT33LcwV2^gnl)ek;?E*bZ74Wj zP<vaB1ez}{ROk5Mh+a4dlAhmG1l%(cjZ*!WdmaWo1oP}u+d()WKBfwR5Q z?*Kbx1e1`U(mtUH468GLpYxTV7efH%Q;OTeD$$XfEMZ4-1dcr?+)8C#KoNL9CY)xo3xV=Qbq1R2xX&wxvVnYFRCF242fle|_`OU%q z?6y_;GrK9jsoV0$LzKYxP=E+C{*^To7Cb1_(n6=Vp#w$D6Z1Xj934UDPi{6#IL&JX zMg{bb&$>^rSs&K%I@8s^G!iBWj&)Tig;9cTt~%L!fuU9mY8&NIqi2$M=?4mF;JeHs zgGE2&jQj>GU*i9RpNBbH_wblq0-hS8E4(*!wzR=3`O)w;`5t%|=HV@T@yFt4Tk&iFzkT!YCjMx6 z_}Qqh9GT_a;U^7NgKUi=8 zKy7B`LNe8+(a(wy!o*H3E=KvoCVdSpObg^K7%9WYwrgr2?ny81U%qd3uG3ine{>b# znVaBwv5;SW*R8ytK%(yC-JhmsXS#M^30k&1(^}KZ-UhYMuRU6JM8O~3rOQF<^iCpD zh+ill@$YGmO+8TLqZ)uePCnRTY=ivr@OvS@tRb4_$H61qXoK)h&BL4jgYZs~K9JX_ zvLmpyX%|TBdz$VAdJ_upd5DsojXi@2K?i^x(N!4UdN-`xRzhY*C;f3oxBT!6aiY$t zh;%{)46wC|thXY6fCG;6W+RE!gUv)@PF1{{v?lBS0%16O#M*JTaeV6U!6s2G7nPk~j)P+tcJ- zGWYPA2l>p;?CT3es%o+KD3H}|UGjYLlu>0zpJ#56r&4)_D-Q#QE_q(`d0z5VImz`z=_=ym|kW`{=?__yvjGjnxMe70afg| zYk_zA%=0|9_giN3q}1ZnqQL5I3as=u+^CX}7<>5Z_N@c=-;dCXlJ$KFA z*Js}R0xS8dmp3sMUl?Rw7G$>Pu9=IMTEm>{GmrnJFPW)LE7<~HDA}I7W*(%>GoFwn zFLu*$WaKu9dZ;`4L%N^fJRil4BK&gfW=e7mY-TusSR6fTJG@ri@F(qGu<}U~Yy6V>oa)KiUPV)%i1oWSL|_%x3;Z`Yiv=Mq|lj=2(S4F>n0B-_*^RM~V4JRc2N5 zIl*V5BHRr_818fK^@NBYAVJ}7?mqGZSl|R;HYFy6WLwSXyiVk7lDU6+AisXdGOTef+l!YYBJt)`E)k|pP za`QGs$8YF&E%@;I{Y1f;vARKS#7tuS6YvP8Nwapm-Zy%D_8`@F0l?ssUOqfPo=`Ce z5jd^N&Jt<@yBq1O!>jXj^0bdjYKmCb<+otd1_D}I zt_=iM3ge|q;0F$eU)4Myf1d-{O#KwqKHfGQxXH|%R^Z}XC(b4exywFc+pvX#Ft}al z1(o3HcMl6HL#f&ojrRH}Q0TXK5Oc9{+;dwCFzPA)ioGiKV0C$gD!Tw2O{AK3G1pm$ zZhJG6GM$n%za=|AR38Id z1lVz|YLO=BInNYwvS-21O2j5~_p$Iz1hk|9t3YL>OXzChCeiT$UGwynUnY1LmXhfq zdHlP`NZ0#LT$LVjR`~q9f6jmZyMI13{C`uNBm0t7L&Rp_KEKF+KNLKI3y={ z8Ofn{^T`?L&6_p@$kg&ZV7IHe?I82DwoxOWei~~Uti-u^+ixrd3*}%ZQ;AYsNBWmo z={}3tAk?=x?eWnmeX*slK`%$rHLp;~vsFt|c@OvYxY!%*DIR=eTfoeat&D`W8xcn~ z(G5VbpgM!dXVq!qK=B}=0&$C0x$Q#}jLu@XJODy9mvr3P{_|vSHTvJNkam$2G!hv} z8z|t}_FO!@e4=}nKA1lKmRCFLiYI>R6;7imoF@lcvge;rgm%z}n_ik1B=dSH?v0y< zQzOurF^svEAQ=M=)R*(n{yjO84D4g>=Ol9v3#B~vq3x#eIt{JKAn*>mM_$l`)X4Sn z75Qrvre^5fI^hI3>&;a9!yd`@QzE4sk}p_F+f;&NqdbyVbV+u5kjz)PzfU$GTCUY4 zMKbrvE|J1J?9gE{JFusBurtRGDpIg&j>-X6-=6g4I)49>z zDuT->Z1KyH`dWAJu26^Hd=tOVQcjZfDUaZ^y>NP%WNv^}rUmFnQEyO*LH z2)Co-+>m#^Tkod$61QlHlxQ?LOQ7EHUnkrXDQJKSI&%9imH&!tLJ?_*bUyFeTi?a# z2s2f=CYX^yxZ5;q)xkkg{_p6Pkb%5_EKqI4R_-wZ*dW4HFGVmnTK#oUlvWS;9(MUP zkz^={n7cSg=6NILNqXsTBgqi;nEP#z%!|Y89@=|Nkz_`$YLdA-gi=sRn^zS32XZjQ z_4NpUc~>NFv5M$bP(+I_;=sm8GArUOp$LIJ!aw)PTBDelXxtwpt2g<5kSKSkbmVU$ z(5zmUSTY8L;zh~Y#XjZ6QGizN$)t44WshVN+uar6gk6OEp-fx*W=Dm}S_v(c+&^v8 z8m~R2UqkytU6Gzkb&YmSw6fVId^6?GH$Cgm4>jv~%I#n=D-qkgX)p1|96^(GwG~l6 zbzAw&IHCv#_D?-TSKQQ1x7lGy;i=*U$NB`NCrCFOoubtgk0Kavd{ z-Gx-}eFbyqdBe(<^=aLWw>eA)m^@A+)V;Hrk%!K@5s8*x(N~`vOU%7E&1h&IX#1@C zU-GnRp?rDl!6K^sRc|TN{p_#GDlZ`Yjz7=GE ziCKz`K|JLO3{Pev$`r@G18i~o`C>1M6gZmgL9WJS+Yw!7b=L>DO!xZeHPB|Bh|Un$5NheG>UhWOS>``j<`VHT>s3sn^!O7*ae2kx~S zXr(Lj@SmF4xoX=2U!W~(+EYY1J@l`4HOzNDxpTIa`oQY6N>S0hr{VYrLy|QbhD0Dw zL^EKRjaCW98$2_00ZLO`w!gvtvLOQ7s@x{nVD1&mmxBGS(jqOh4fYw8nRyE#j&)vd zaufX&`VL5KyeyOL0ZS8#vmk?y$uyWubUi&LV^4@+V!G=abF74zobK&}kGmv$DM;pZ z^1(v55|Hi=b;;~UdsYN46^OY%k-_z~Iu)Ans&-uai4o{VztMtzkC_8XO;yFJ61%1Y$a~TxqGkx8^&9n0alI{NSjh|Mt=&2K z%KJzQ~e#*VWkEFCr*z=dWT`xde+Ljq*6J?XSY@ik4Idf!L-ALq(VV0MaxQ}SK z&RQ!k5?)Y|3CV|P?{7c%MX3`&n4wYgwo+uiXos#fS+YI?jQn-Tg@4hQ2FAJ(bcKW& zGp5&GG!E_JyRgOm=DS!NpLuupX=K)i?uM{H0}Ly#@hw;s|NR8r*)~M7Usl?C9iLf~ zT4*}Ja-@9@xvwlmh&qIG18!B7yYd|hIOrTnEnI>j#>t;~5~<7auiB2%D=F`D@6k8) zN#tEFTzD`vR@g&8F_ZUs>Y1~N53h}M**il&cZIAv%C!7yTJ9}7**Krk+kAVZB5dAQ z*^aYpA>Tgl4T2S?MUsI+%>9gH?gn4>sx2aA)4j!9sjW^cBt~x1zv0{C|1FMpAFa_v zayP}jNdy@+Xxk|QrN5xOXogmZ%4m;D;?f8zX5z^nbK97K(#ah5UPkMK2b#yW*!|>X z%;8gfi9Nd1szIQh_Fu<--g#(sP@Ju1u94hU82UpO=FVS3OD&a_Cw_^0H{HIt$^H_v z3rjI_%T}vN1Lc{SH=hjFW6zSK#18s}4{9;s#%gh|cmrttq{=Ksy<#wxgo(+&Ch zd=jDYd~b4~-eeQAqkG}*4Mg`dwFX@2dy@s~#IuPLj*qkr zFk&uFGIySVZSx&RntNdZdmOGcdJM%$R z9rG==9`6y+p7IDjNU&nk_^A} zHmo#W$q>#QS7v%$+hQuzC{t?d*R(i8gRmvKtZSjZR z5o+TVkGWB1sRhP~G7R_D%pl+R_eBR))_7aW1e@l;efUL0nsDRA+nL&-@4`Xn)WRzLOTl91B~x zQ~O%DZ)$a;D#S4Ej%qarM7ILn&u>usb$HyLv9A`VAwD+Ogw*M+7@naO&t3>YlLF5y zDkQxKC!M`LRvZBR|8Sci2lS`yOu^GQ?itQ?K$dR4B_d0v=N6k~qwxXxm7&4Y{|;|w z4T}!`C@SVIleP4nz)=I5Sj?B%4l{a^E!Ix=F?K6O4xN9;K1vBXuy8*2@IKz#Xg%t_c5vJJt}COn@Z_mJ*IU=|Hm( zo(;Br815d}!iZ9KbOfL&n7acr3tj|ZnE-AEKsU>0*s%-B)5zeQzNVgNT-^S(>vKE& z@ex`*&;SMe(Sm9Bqt8#2b|{1JF()12BP{Q}jWCis^U8&r|DW)!)}?v)M|?kg;t$1j zc3yj^tpB#38jY?}Kwt{(?pw^^37@WCpIX;5KC{O7^fvp9AT;2coFa*6WScg~v_82L zCmVC}OQ1<~(`e1EyNSAkkrZkXl0!EY6vm(tK0GP786Li=wj12%t=z}}O**HDIlNi+ z2DYe^ajs*E*ml(Km_vB~_aeYYkQOKZ@35eNr&-SfOS=h%gfIN0=3U%gbpHtEwVOv2 zBa7o=ZujkAsXyqeFBL|-im-kQBFnw3u4uun@Yn>eg9_R|KIk* z&A^iG@cmZyo{8oT2-HoiKwJZyM~`vu5K*uqnLS-1EZ1yZiL@sT!U~jhk~HS4ZA9tH z>zvl4@SWwY0+DVUu6s?ca9^EF(|z50GY_CbUW`|Lk@wr#9%D%B{NsF8tBQA*@Xr199X9T?>GHus5n9u<^KbMB(=fss&MtwoU+ zG5{|9o77!s0GLzeG3MozuRiaY>B~N?YBcTBI&m>Y4OVY+Nz4$V;9zheJ20RXs+t1A zQWEQap;9EZVkff2+=FQ!Q0gs=J9s5aqE1Vws%<5FGCShshm>uqTF6I6u{a|s!0Z9` zkjJYL1;-7i<66W$g(% zJjwqB?vwCwp4)|C^$+iVJe>~4*FUsWGPbA&Jvh z+V2OFHMMq=cuFn@H07ReZyn1x)}--jBfVPmfo&7*T_mU=Z5N28m0H`2c#q80D~$B` zQ%ac%UY;jv<~IAFl*XZapqO5qrU!98Zj4a*5LfD zyp}FAah&0egcFa5Bm>Wws}GXVqMi|HQ88jQ@7)~$$L!xW*0hV;(HAsjOay{Wa&4oO zGxQazY2j7T)Wh7riw&(U>msSGJZCnL=~=YIDvh3rS89$VGu~Mw%Vw|vH3pg|AvgI3 zl`A~(<8Fx<+5}F-Tt>ORG1sUhFX?N_PFK2mnMi4#mz&goEqjSa zWC4LdMP>YFR)@1ISMV@!Ma@Hr5o~U|*8sZDB{g5=YSPPV7Om}{T=d<6gaAnil;(aV zVC^f#uT=0K?40-a4M7_d^u zsky)tZCukS5=S~W^>{pvcc*M@1nzN6gbt?n8eju_ShHSUSgTEEt}@7FAz%kvyHPIM3OZMUgJ~~_E_mt?$%W* zb)b(zyR}F2&)j9ckR6_i7-&C(b}p?#{-du(2ch;Q&ZykZW}0l!M3E8eKE{=q`x?F_ zVqg-L_~&uq^Ai7Dq_)@hzxwBq!S^c`=5FVWyI~%TJve0Sz$7W)?-o{7t}avU z&~?4ar5uDas{pZz*xy_l_-TGi+!yi$q_hI_k8hc|GaBISf9Yb6%@+uRc~~*$Y0&G+ zG>1(}+=;!cQQFr>GzQ^aF*j~==+zc93W=fDlYMw~wqDV`-$pXXnsXJ(@QWY=MUdeS z$}opl?svYJw&=z^<;wNhy6?muRAKEOAsK@;ra6h%gc7w?rRF+H+qff+p zq{>j7?1&|Iu(yN(y8~eD59JNMLU=m^PunDYIV!>=hRsPHo07%u8v)qBdFEmM`@7^X z&*y*md-4yWeCjeD)ahAl-Emy&j_cj9Q6?Oq@q? zY$`#0Df>FJOx0`8d;jD4VN6+bRl8aXLO)hHht9VbD0f~Qowl$-K-XG|qW2$Jq<;`fi+A5@yh20nE9om~*ltD^zV>LuOMuV@Tb zY*F1N*kY+-tJvD}Zq-HH0JSx$nM$+w;WR8bp@Q{W?f1CpD}rIcP44omP%?L;hYQ%Z z^Z4~}{Ds$+X$H!yGKfrV@LR@SwnB7L1%Sv`VeUO_f_BV^i9 zkz}fsdsC*`A-=45)C+5qB9DFul2NIF0qo!d%KiBU9oIWL@IV^Rzd}{}tQHc(J%=wwv!RpP^KcZ+Pp7 zDL&upYHsqO>dLq^W~vO1+zQGZefxw zzqw3RKiH~Xkg`jyms?7!^$7*|_fwUQD0o$*THoz%XF#6YJ2bNj`==d|ZInnv-(x+n z-~Yp*vOj~&?N3KkL_z-etoOwvrt=R1DYZO3ll$mOuibe<13a`l6kzKYhi}BMX~YHlXHeGu6m{kwsXgCo zup9)xoB{nbnmmiE*>bkSM_`?nxtB9&Zo-c$)In(X-BEvzsIWmagZneXMe0~7H~wEQ zrSPunHOEsvWtxO)7#^E`fErBfZVpNJ=zH3x2KBCwQ#ZwpQXx+or$_P9n$yynX1>kqPcBNYpvQ%OEJv=>CKAhqW!Yz|*by~*Q-Ni-* zFhZN~19zN&{VfE>wGiHR1`j@{^NV}jar`7#dmWeg9?cx{!{lFo11CGffSjtxm#K+pIrW)A~JNqmj$^HOw{qP zsC`Q-#P2rLiJ#)L%nFR!xDcR!;2=K+f&@!9OjabjIKXFu0ZqwJz0M*ycr6CNnPAHm zX5%(&+DG5R@dejDy~yJ#clBd*G}(}0Pxl4L9m@r4X-Y0YG@lWr%-H0LiqH+m(N=-$ zOaKK)0F5c$8DQLR#^6kMX%^D-?;wped8hXN9i|#G)DZGF9g??q>bNmWyB=Nii;Dsm z$764C%&Ju`#`$C14F}l>)pw31Bg+1 zCb3uh)-iP~><~K>gb}Ho^agi~yBDW55YGKbqyeIGZ%q<+>wk%&coB;Z3_N*m{+2fj zW#eTNPyJ8C#!4=d{AhF;bsla6UnLR^|?;8HNCxw8p&w;8sEXLKeQzR zPPAR3H=^xWBIAsoA#KTzaOWO(MFuE8_>r#;!CZr&f9Q-R8}CKWnRQG<4tXr@dhi( z>NbA3ZZHIn1w|n&V@L>>xWOBX>$J=lYJz_~kmPxl@lKHKuQG`<qoPNvz&I+%+D{YL)7 z1Li>-3vW=7GWXc&GDhH;Cr6Da(oG!_0}(koIrVi(3jzIpH>OALdfWfArrgmcVVcnn z8z<8nB{M%wE|O2q8(7=tDNY zKLBFAMUndLQlakNnc&;YCpANGQ@6V|(3a$fM%~B3P43U|hkLpWPB}VM2Zim`vZL1r zoyWHy{ho4673gs74UcbI0)M;4Ylp#V2O$=W(M(%{bcv8w8<)CQ-e8O?%hT;Ah#T^^ z|7dtK^YGeJ-ve(zp}u?P5jsJ*4I&q(Q}fk=R?AxjV~MeK0YA6MUtSu@6BU$gM}NDN zzDF>mH%q)LnE~Djg7WvMaCDZB7Pdj=tmN^<0D;9;zAb$vI3kv)<(_@WC=ax)1Z`1a zd&Ot9i=yoL2(2ky=$N}C@6`1=S1217@q>hADrgn=_&>xvXg|F}o7R_^8Zym!<Fd+3@9*K>wR!ICq;Fcbffk|zb)s3;EH~mY z7=3jH#CusyQP`f$jHx}l<5!4M;+`Wc1eSpOR|vx6o%4tDIcJWFY=%K)V{WX%9*mh* zDdz_K|7`p~b6d1Vtf{yAwCTU=7rTd);kAHo3h~_$d?9WZ`D6mk7xr;0dB4a1L?oH` zr3?_6gZgAR0vT=ZPrxa0a~!p0{a*h_&JNKuNWJZ}CgJhn7m-=LH>>EjD(AGj(H^HNHZFJ8F z*73*O8*f|9D;B$z(;?tyg#;|%r}(VlluP}GV-_Gc(K*s4b;lN!Bqw7Rikw8092Dsr zrHHlPF=}=wLT;-1EOGKAYuPMr=6HR6m`B0>y zP*2}_pKQA!oeTYYkj&F}s84oYRV0}~n@cj+(^qitf(V0dA^M)jggKlwe6eet27T{{ zD5K8$B}(5=X3cU{fTWEQHpp?kq&^nE!<=IMKg zPxfg==VW&U$vk~`^vUK#p&3PH1<5>p*D{g^w}%FGhW6_qnWygyKH2ueBgqWfaFV$j zIavW9&qM=`jK16dlMhDUvZ+5n-hZnHfY*!=x>sD`@&P3te6%mSm3WZ=<;}IPFJf7WBvTsA_NC*o}DbyY=mFxsAHV z{H(hSb40s0nCI#c?N0d4_W0KMJ`gFC(T#xpfx~k=*JLsHlbOwv>CKXvBj_g&=Skxi zhE#|-t`eDRuxDnD(Q>p#ycP|m5gPMI)6Z3R-zS;29d&4^I_3ycDz`R`DW$Ef+yjR( zI{24sI1eO``5yff#>bxu4&l@{@fjLB(}*@U$qYnLO0b9IOyRYR#|KXg+;Z-}=hA?8 zMjNmbJ#Yu8{W|C&w=tcSYuobwiXdl9`C)?GQey=9Iq2rb7Z9WX-+X_z&90IDOs-ki z>vfX~nD!dgxqEveKI=AL-zjF(K)L!_4DnhS;+gXx>^TH?pIVvBj47_gfvVxGw>8NH zZKvX0$Z&8ktenjJGREX%F(#fJ@ib8l+n^DRnxGNEmroORS$SWIw?cCPEI3U9<xlCx2e;TUNG%_>(1&cI$2Mv+!BC-cH}LY=P4k7G z7%B8s0Bo?(uS+@#ee3yrp}l>f&!9pn^cj7~CWaK$lBVgw^}pb1da zbh5qQCO8@isi6L!o*GFaFhQ(_TD`{it79y-#`Kpfr;0~OJKE8 zLq$!rDp9D5+$Oqc>NP526vR+bP&R-TB)AE%E>ZdsZ!KDCwO&5fVpWQYHX+O1e1q>Fw_0~cpg3Mfq-V-}?l;gC zMI6fdl{By$@^}MC6>a%aYZ}&WMYYj5rOT%u0*s0BRazqbm^%} z)xa3VqBtCJ%dGtYLvszCk{G?P_{mw@Go*RPhmPZ?Cfz_yPNSiO`I#AZhey*q>ahQaxbC!lg*uWf5 zpWn$aa#kp^(48JV1|={c0Q}u%op>W;jPmaAf;S$1;QMz9-U<)Al{UQU=<6!#zX@!r zG70-HePG{oJ@H9_z3JyFQNf-=*v;o`*fAnQj;}(H9AQ_@fzk8<>Gg47f5}W$gBt1$ zLJWDpP=}ROPD9H16SQtUgJX4=D-HAq;Vl3k%q>;W2B66At>6uy2;*~H6iK1SVnvT2 zvBjW?(N=kK=P?~=sF%Yo*pLS+EMUF=BD)(ntR09d-^&dcKgmUVw(SpW*UC_@>j!CEGzrE})d;0^I7-}-h0 zSd3*2ZlQ`?OPtG1o0^gH6wXMjP~?n42L&Q0no&?ntd~5YK=CE25@+3CLq|BdDuJ`g zvuRwy*JoQa3VbJ} z!gk1zk>Kq4?7_3QTX z#Wj!=6YR6SDrRr>%U}`vl>Tv>>IxoPePVH1|EPE}L;tvA%pUqj`}NC1C$d>Dd@Xut zQ}Ah}_{Iro@Gbsp2KcsKy$AT(Gv3jYWIYQNmT|lbri^z%mWWD;wx#qgYd9fnW4wFQ zkx#EZzmVxkJtKO+sJ)%3wCx4vr_S-0IW@^(X!_+u33KtrpoF8Jg)gOI^v8kyw5O{} zT!LQ>C;lZcr?Iq*H#mX{-!tcDQSl%FttyO_T80KV0$Q<|5rOD`w9PzzDZ;)VjC<>X z(Lmhr$~HBSSH36t=)X&ncw5KQwE-M_XC*M@J!VJ)B*@ylFry-Nl*a?sqEUeE214h7 z$C#N#_Y~}pu$rh%h1~!`8nqt@pSTZe9q!6V!xKOpb;@FyoPLc!c_#ct-jkO2RyY&x zLc&1Uu<)yn&xZ}GJ~$nYy)1l*wRo9=gHw2vwwSfm;9rs{UVIVh z5JKD;_Lq+2Na5mU*F+x>V_+;xcA;4JTm|xcEHe`ieQ>5_x^0#^9?JCp>c3@V!#b-U zs<+2O3M=px7Hh$bbOB`W)qoJ7157sk%+xG94qA<7De`2@yiNGjPX9)pdx2Q1pQ&zpe=$V=S4z(Y@CCZz>5 zEe3CW{4sDiKnJ)yG9%qft{URia0>0V$a>+*Q(@VfRvEI7161WU-trKix2p45*8DldpT)L|4?iX%>xuTOJ(9g<{O`xM>I3E^sWYMJa7>D90D!5t@{;r*AKe49f5 zVT;w;jiNu-zj>58)F-ypLC|)#GbF?CtIh` zqpN1JqDK$P=cj-2(&Iexa}el3-+FXsZuQTNMTf>3ae~vtgHo8Q$OB|Pmn^M~lz^U+ ziGlq@ADUi-_;G8^B|w#1Yqi0U!hi9bXB>Z1^!cWv((w&np;U!Of1E1k_uHdyPvZN{ z0)?-Sy`XUBx`fq>TT#VwIFN9kn}j=qz0)Cm9`u2KjvNY`!mn8xDa9|bcYfI(_=$;0 zk2EF^;!y_)tZt4q6siDDZR_(6;Zt6i&W|OR`|#tKd))eQKk{SrAKSqXUwppkZ}Vuv z#Xl`RHL?`t)i0a%(waxUem32WkLde(59}>Is~vn6T(n1glKy({d^JwJ0iLV%2C z?f`0F&SE_}iN}4Y#U`WnVNELC+#T|GJ}5OvdX2OfnPSE#BI#_*z*k{sldAPV39yq& z(U7#QH)V$iLB4f{tDy*%Te;s^sS zBDfP}uQ}2`!JuJHxc~%xT80nr{JCB03u4|5f%?zrZvk?iiM{as04dQn-|w>CKOdmE z{VmD)rCwOllS$V!yCd_5 z^#fGdo_d7WU;2;pKqX&)>E{{nYhpTjgX-UEInAgQ>yQ2@!S#s#go9ygn1U5k;GKn0 z?KO&DdU$;7;oe0UGX}Aitu?YobYB(dmedYS}3?+R1<0k}40@glKqV1mG<@d_+O#FVt;dg|5 z!#+!6Q7=p~Q`cH!U%}f1_}9VP1hr^;YFwM$MGq$V2qn+8cQ+qp2+I=`zJuEDC?BmX zVzGz$h^S@Rb3*GYhOtz|N4%irw@B8@tw|>-Hp%$p&NoZwk*(A>GBY%y%s+GFLar~P zutXd%V=zO;pEIMVZC&H{C#oI`BC$(Fu>nR)X7ii&&4aeAUgwhAQp)WQ=YS5`xbyM9 z9E<=d=qHnXRSz(7gnHU|_Mwb&$?=RwHnn#=+kn7@ z>iSEA66CtaaqSvUgPpt$ZWh)~gk$?`NU$?tzbeV+BY6~w>We5BrftcUt04&b z3)pB&4veKG_rW-qT!0d6TZJ$RM02iJjF~`YRxspn0(zqg@0tldjKXW{w6lTnK{m!7 zeADSq--jI`Ij#Nlzx(+1(*KFGIzoRNoc|X6M_&7%)BpLh%=B;1dLf;cR^8od01=ZN zT3rt`DqQYB3XAA_6^VBsOPnty+8(vC+kW-PhcR5y?uxr%T zvf-OCDp6b0H{w2>hMmR*xdgr8W3pZwPY1mnDCtkaJ}J==eqTH!6Tklmpws(rWO`b^8!bIfaC}*md0TwO zZnSb7-&t_WG|!zfI~$Je0Ka*W=nNpw8<5LTmA$4DnEt_7sos!Mkn5BcLmJ#7%n8h`AXF z;Xw3&bu=LIjYnAO$csHc<5mZJ*h12G;7*Jn9A1K>Oc1Ow%{2ZoG8aF;$sL2o>y1St zyBUjq(+%@Ex{-eAo@xVL|0$XPetzHfQZ^aUM9HGTgZPk6iEAK1u`Y5LrZx0T;CBQ? z%FFLP(fj%h9iX>#@6ETjhu(_@+VnQDwFDDdnt32>1aqbxfyhvv2BQdivX`Joy9tU} z@W?#b)twro077uHNvGyT*l_X$`;q=_5K>t z*PkRM9+MKjeb*6L@A!622;@}bo0pzO?HnzrRB@W7w!bYtG8ZR9BuQtAlL1JqgOdSt z)lP=$GhDv9>Jxc}EW?;$uS@()9F*uo$%ipt0Y;9^<%2l+>^(m=GZHr|iR6UZW=99* z@mH8n(dq|u9^*-fS)9`UL6m?sVorPH@#r&bc}$THOURcVkF-kC8ISZ2+_~bB9>C*3 zM$U`}Wz|`K;n=HYbOq?T!;CHkF`BHO3M4yFoEK9u1;*SNu$5&c)cM}u zNM=bhv$m?t8<-}if3L)yi_1^q(Zyw26&bi})ZNNTT%4}X#OV=kPM@oCwZZ8Vk4|zr zB6Hy)Jr@@2=X3%~!E2Lq;bP8(O%4s%{M9vaB3_Z}L0s{eqaQy7SFFSOgWz}LPIXaF ze`uHeA(^B|0(PbY3I13l0TA0&5r6^X!T?Je(~7t!cR_& z$!QC}4X6DS_(?m%3-Msx%xBfJ0&y;TA%ssiL0B>)=DwyRvdKtAj zQc*UXoQ~0DHS|)MQ?#>DyM|o=K3JD|Z{3+GvpSL@TYdHg@=wq182`+XD_Lum3xoj~ zGM>QmV;2$(2V61m#b)U@Go!Gsvc>0a+eGIv+xC5t>wYV`jGg{>cBJ+F(2=G&9Z8RP zp8jOa+$RG+J`<(k@I%KRH!;=WP05i2+m5UEncDdRnB}r%b=u9pWl9B8DkSB~ zo3CI>B~vOTWysBgm{P@*DoN>cGh%)26WYZem5X;mo9t@5qmEH0?`FQU$;4G4`<|i7 z)*nv=$?)N#q>$W1CoA{lxW-Py35*i3LtF5KlD$L^wd3G zM(rPb_zA~0d8yzH`uB6iU&fM$mA5n6m@l#9r5OM7z2m>2ad?J`l3YUQcoRa$7uuBP z;A-D9bj~`2I2PiLBAX(wjT!Ls@dxdXtk(Ot`tw2TWx(&5ut{h9-wY*u?d2fbxJgR1 z%{i~VeCo--(AOXIMF#vii-<5k(o`4sjXAYQmC*Odhp9tKC*^+lfDgJtFPAcvyR-&t-3|D#>7vv@2dk^y6K(_{x>PJ{NwE zk`lfYaX`DvIu4+>_I_9#LIkykc%W20kluyu zp4)tf6)gs&BO!}USCt!&ymZK)Aw6%vG=IAK_B^5Mz8Okn?s@M{%_y4=C%pRko)dtp z?a#3L+aBYG_T0Hr$FubLEM}X~Yi+H!Ub`hfeLg!$YX)>~uF$$pRY_fMU2;57bIoTt zHHAKzs?JwgA?=rLn}(0cuI3yR%iA(fMVp8k|3OYA(Nk9>CE|z1`@nfnB*&p?-^*cm z032gwCz(2gW!uz+O3m;WezC62OECRwekhe5#>^eQ@@~|=Ep&0lKkEBsdC)t%ZuXTQ zqxL=)fX%%MxsvMGx_^I_KV^y#8O^-wJb7hc?SyKqd;J@U9L+)-JcTTLT3r+&#(>oD z#MkxE*X+34d3KvU9`>S|?{yrwlRy7x920Kap9l-W!Xo4oqwiN>P)NH1g2qr9ZV3*qJK>Lo8JFU=W^LbM!3 zI_*NTZbWDT4U5!u%A{7}owDk29Q`=bF3YpZw4aNdoDNy99Sd?k?#Qm?W3Oi<$7jcZX^*rW-_O=A_(bP_JGl+`R{bIgpGTfLwB91^3^>q#Y)LZ7 z7IH_mF0@Rx@9z)jfPE+9MGwI<&HtUW?^3Nb88hCQq7*DC0YCm?$OM z9`Bt|Ce6M(st+X9Yv1j0yn!tTQ!Z)mVf+DtYE;j-Wzx(4390cu=;(VGfAm+PV;+C% z(cP75+4K0*zsNiOc;HEk_p!nGZ^fH@Y5wQ&CTAT3j5Eah>}mb$)ow~~Q-`a}#?I!6 z85M!kBeDPaXu#yR|M?N}-y1(j<)0c4AHnt|CwdC&itUSoUw|+OYIr$x$q7%#@tG<- zod!cY!qe*zNJZsueT5l8+wq|7(x2kzeD=nSWLsy=MnkrK_sDC9^ry75tLI+m&s?_e zr$6_!UM*w4=(D$OP=b`I0VOomr8BJ&xrz`z_KOpm`hYd5&{uwBK4o$UET5SRS;22EP;{~Um2^pB<6+qCc6wzqxt-6>s3 zrS_~Jg$a<$-uB2(n!dBa`ETjF-Gf{d4l0jdN8=kWJrWpa(06I$P3OI%|Dv4s(tphn z9ihJs&VP&kx19N()Bn9-2k1}bus8Cb-Cp{K2~E4@-v;NuMgQHQ|D67p_U-`vbM}t@ zi#oNJ{%d-5g#I=-|1J98a>jp7|MvoiV)|^K*H$yoy|=UnSyx~1 z^Us-)yG@X@hzi8Y#qq!P*{ACBdLdc)w$31EZJf{7A^(}o$99dSAf(NQl;_%ap7KhD z5@J#Yldcl69e_>1x=%{9b7pffEwhVZ>-ev4)RAau@yl)dGhY^EzZdHo>622IKlACs z0OLqN>$qCv#xp*5;C#PjA_iW0+4fttO;_#RC`t`KS5uPUN6Qj-8TZp6M zVuS=GLTZOQNtUxlT76>t616&7UF2F9t;S-7vm#oJ#fqh7>DN>L40tzR_ly|-CMkA;q}uJ^udG>t?^mux{q%c%;H%MpCTQFm$px19KeV6LA;r zT)1OLJEMG-+RXZ+%jO9rc7Y#Qo?}R_%`DlZtYU)_HDp{d49vvYnsM3;_wX-${DJkg zhw-QJvz+wx@tL2scl?=;SiCmIA88-s&!zVG1LyZ!*aM9=o$==^C&^L{P;6RonU_b| z>ozj@*ef>9;PaQ1!RPNBe17jtQoQsToUS_}spoOZJn^l|GL8xBtVetP6#i{#r=X?1 za^tK!g`>u~XjygzlnkCQ+Q|$xvl`yhKHugV_E2_;^@u)p|z-W*OX3kuup3h*y8NCz854 zUf0A_s7J=ub1S;_Dkgmi9vYEBe$xE0JBde|@h6R+bxH4EL(z%b=MV2sh+OuaN1lzD z2K#q%KZOmB+E39y;1IIu-cO+dL-c+Mz*c7Or&uJJc@O~L)%z)a&otRj5yM@QQxP|( zu5okf(j=$!j)*om75p~IDZd>NAus~G^4k%?ozdjlNL;ZaVvv4h43f3az91RC9wkil z&?{X(28m&t{PVTX|I%*#IJH}w{QFoa?3~wNgQNV3f96XGxkc}(RD-81YWD#S1qjt}mLP*NuzL=0xEurri+m1nNQ@_IvgAxY zYZ5k}CbE#Q7x5(U0S2rg7iCmK>#Tg#{-3WmN;~ymCq=T|`%~`4G{RRO8#7-}`~~H_ z=Hxw0PZ}1qBdUn!<@h!Sshqm*n6`1EaEret7aMXmhTRk!QhZab7i6TOV?#O{C&*gs z#jao+w@ugz(bJ#seMhB#((tPjyTdzwH)=;Q)xq_Mul#9E#aN`I{aC4nLFds%97w|0 zs{N$J20StLik72FZx)K`J&;D-dOX?zL`K~*zO=XXE%j{cGwNgwKe^${sJmM#Z49Ol zFyhS`yN!0P?O(I)+{h@|X^B0t7nwPV0oZYg&9Q?Jza`K1)=Rh3&5S=Vm&}SkE*GzB zg5#9l6xFHuIqZz3t&@!C>Zv-ISdM{&1%-$1#?Ri_2ITKt_v3MIZN+*;;xydZ+}xx8 zf?~55`f=z7?H%7n5TwlGTQA}E<|=)jjSY^{kFN+ij1MnBy~nBeo^tg(K;Q&-`GhxPLds{&w7>gGNrUmAY*V>;#?E0^UteAQvl%myf>tM0lYC$|$nW~$E8H6D!h z=!xgpLEZ5?<0F8bKZ8d;<{NeUgJmTz8(Hh3o4Q0>x)^o*M!<@kSF%uiG1LiPJ{bKZ z7~L5(>fXikikyXfXU20b-gRKWtZT3bvmea*lb1j(x30rCCAVJ*=;K*t&bm(Q%L4)a zKw#BlBhs&i&-thY(86YY&c0V8Ukt1qSp1`P{NUZKoXy9w<)h0$7c)0&_JG~^p7x3O z$mI36@uSZi46 z^>a#QJm<&JXl?)>j9QwIcHg^-49$5bV0%7Sb91um$zAIC{1gp*29}#vVi*J% zHHK~4D?>p50^J#c6PoB(6+;mpu5gZ30w3hJw>b>*O9d5&L}+xm%yQ~cd%OChZRGBtn|Au|>#2Q(9s(8!0cPclnaRPO`I z{&gm1+nWH$FEt=zn16>EKcn@X3cOz{?_D%WVxkgL+pj=pKffH`sZ^)+u#1+ii%bp2 z<(tsq(gvLOT%Xg0+7ME6@?XIQGd2O;w9*BuLzYWJX0#dPKIou_AqcSp%-Fwd=v+9n zO{pGu*mOX3D?=fY3o8l=9|1j;5LcU}3iawvYdhoUv+|S#ayvE%AN!S#Iw%+AHK}3~ z!7RvaY$%|gRL&g8IuvMJ1VwcH1T%gZ;L$P=9~H8`T7=I~LpnQCOA;_ruw;FLhq^ix zM*X_0#D6y%nXpxG0Wa5XgpSI_rvpbEnp=i53(HD3MfOEycqe~mbjAYQWI2MNYs9i| zAmG%#W(_nk#?2pslgWnH&@Eaw;V~qSmFT&6obf{q%1FwWb_)Fjk}@BnDR}~TB`KFe zzo``5NJ@T=oq{eeDQ`O|z+F=2b+PjVb;^0rJ*u9NP6?v8N&!Gp>PsgD07=Rc*p?~} z0Fsp3VA1Q8Y?V?08t9Zvc+vN*M|7icSe+ zN$Y)qpql|a*U&x_2N2Muu<$-wSEqeWYX>uKHR3m7lJb>37_eP zuLAH@I`EY%_#_eVjZTNpB>b-T>F^aO_(Dxq6yF8j6MV+Z1p)NE8Ji)0=!ptU=z=AM zvzg#f@|nVW@f@F1xPZxup7RRl;(;J9alehvFMLQcd1*UO)tDh~Ivy9k20G7JR)eaV zti|}Su}rZ&^o2gEF;5?u=ODp8>_H-z2`(h^@eCw_Otz8WHbjMl>n)HdluW5eNR2?k zFK;>$b6*uC2v?J}eFu>Em0K02$a8&dA-$|#l%RyXC^5l}5}t_?lO2@spixS`B}$Sh z4JD=$C7-2hpEKJ zCvQ4F1sWe@ZnA0sZrl9XmWmH_xfdTMxbeX=@nN!q4<0l=$+yHuGNs|eRN~{4Hyxkh zuPFW?bCb33`?m0j-;ig{*!=-yQXR5mLIA~9@3YMuP<|u~WLw(>f~ik^yy;k8vsz(^%uUwn?||h|wxURmCvD?*rW?OdDt=6Gg2|+Q!0K)@Zi@;;fLfTew`froVS7> zGo|ClCWv2p-gNvvU!n2q1pLn0zE}8VyYb6T#SaM{{IV5(NKWFH?cnFU75tbf9X~cf z{L=HL9h7+AI9>-1z0C;)eteet8N%Bq#C9bMSNC3VzI#jvt#Ke(8DB@f)^G<{F@$sQk(2ZX(6+a|+@Cz#ZketLX=-}tP75tbf9X~cf{L=HL<9AJy#xDr`R&U)a z{6cR0LaF#6!Gm8&;fLfTejx`x=dIw!OzHTs3F4QYHyyuOOErEW;P=Isdxc+(8^4-V z{E*G$Ht<G&PZ`g}Aet8)G5_^YV(9OSKDt^Hf{DKO`NgQPUc=z9sd=K6VP1MOy-q ziNoU|9J9ogt^R7YsC0K^WLbOymV0(bF2oz_c1+7Xi%IZ5V+n@~od_*6QVaxh$S%`%G56fr;7bo4TfMCv@oX0S|F7TX}_1Pld#xy~~N z9DVv;ymVoB3(`iKSgCDMD@1)ZnSEB8u^+=IVU=&((F*bx+ON=#y>|4unYGf4qg0Hg zZwVzqQ0sH9CfKYjGlj?nS+)DeJ#elQfn0p|HoFiYab1*N z)UFV2f8Q>eu}J!kM|2LmSSpdMJC6EGPY zL%R7K&8|SsQl#MKvwns#*>y&Vm5vpG_%%`F}Y2~liQj%qy8Z4FCw52jI(kT z@nyjk%M8}W67&^hkhS7|veuxRk_%q}z%Whk82$d$fYq`*yP8!;aAU zvQfu9hLYGIzwIi%7x}j?L!qr}`SUh^KIG3*{=CAUMqu`KrzS8vqX7IBodJSy(6j1V z@S?gNwOn0~TdS@ozoo7N-j{2;1Ry}Bf+zR|Q}A0+%-^4i_dt-c(r)hTMgESGcWaN4 zA1iW>QP+a&GJNy0XYyRxyPin{VPuu!$uy8B>KO1Ab zeI)q3wZ~f@DRuEO>Ss$M(790GI{rWtxI3@ijkmsm()%|db1pML>u9*q+28KgWY)bL zfx2tR8}ryUBXTgZncK{)m!bC$S=bXYw6XiD=9Ned=WbHTot|QHzW~zz#=06%O(z^! z0{v(!xzmmebmFU=gEhE01@=v$+`P>(*sVU5KG)?<0~KUR1#fLq_~!h}zWGFM(kcMF zWB=9@s<+@OfNk!x!F&vB=mBFMM*y_Mz&+?@oZrU*Kn>-IYmzG3^&Un?PdTU$!+m~Y z5b_}W&VBYL0eAA_aLC;egO$Pr!1$8jK1CEL%JLwHVBK8fR)!VfE_CA!H3Odh7se~2 zRs|g*X(Wi;1^)*AFCuTR;LjKel}Og4V%$wH9%Dor@eig(AQqAD!J(!2hp22^HpX}d zqxT9}Ml12(9GZbenLr@205Nc|cy{Ja!Ztpj_A}(cx35;>A3-psuSY(S4DoQU7OdCz zZb6bUPfCPt9I$-%_%8T2@PAPdKUV~o?}~i1{Ikdx%ir4g&GKFEyq(%&YinfL@|MZ0 z6PMrlW%CWojBd&@>$8WTsn)Vs zR+EXy%958sEaQ(2#=J&|?m(4pEZKl}w{`DzTKC?@Jq?~R(G|sjqPY1zz!St>u$kf} zkTtJ>Y#faL-uNFwK^Y%}kSv9OG%(1qwfgwwZ$&6CE7aqmsdSk55~L;Z4VL05HTUy@ zq2y=PcV7;wQErUdp-2$vITO-jzVUAnpuQBKH$FFwS54zJv*dfDwl}f?@7EwbX7u00 zyBaBi-&yggpb+G1?OE|i7m=@jP`;A(DJCQFx!<70to5-sW_-Q%_Sv%y^NpA!@k2nW zTbDF=y0^Ey8Ly!|4^!5$SLa&qJ-MrOE}N1+(U(TP^IktY5q`xzt(S7pGy8rz|SmJ z$Lm~uU7)WE^|e7?*XipfecgtuIir~Xm@`(Y%T593)?5rwiJS1Vd>62o!5w{_CJtS` zdwN&=55s^8NcdBU@-5nw%l)vfbrvGD;PWk6H z+^`dn81;+P<)1>SIXA#Ul&_!h_@S(K&C(x?nXfQ_Q(}sDxkzS4w_=L(WiCkfBV-@< znD+Gf(CqVpC>VszBc>P%W>yLAZtHSexK}GAAq+_X*=UEihp>Zt)sU>=UUPZ5pw|Lk zM)X?9%jjMWyo~F$j+aQUO}tF)wGCuqk7*Af*=0b+F!~HG7xZTJ(?|4X_0vbAE8sG& zH>;l>f!O0R6~gWhKA};-C|KG6g*B^+RlVueUI1i>rw5k{r00!DLJ)S|huH@?Tj3;= zeKE|why--Uco(Gph)x-1r;K+QgU8*{Im76j+Fq`g`Fnpjy>s#)96Bsry~Hn)e^`yK zp`z8X9|6P3Vn|OXBgeg^$H_16$7W@GFZ~}rgFH+$4_urh6-~@pj22qqRL*ab@?BDr z9qV1SPagrx=P!mT03gZoL7*<>i5F&>n4Qb)l&wS4jEUyM*HN$eb$wI|A}clu`U?S z+7#|%4IlemVD;}$4`*!?r#lwLO1@hhQD}^9;45?NdW*^w4*e*$00>&vwcv#E@2h8i zBfyL`nu||3d+c?$zO-q7^ZSp?tkvf0@0pEX6sS+Qj$JR+^?98e3tY&fh7|ggiDXRV zP8j-Z_}^B3Sr`ZlW%1nzax%4~%-_%m+!qn;zA$5-fr}w7V`0%Hw%OBwBY%q*ONDDY zySWK@CqH8S3$Z;h7qe1)vKuIcDVpdB{~Q8^w$4+)%iqBO_3*)P*#!q?x)2-uTi073VCRE}9ndcWp2I5*>yVNL zG>vwz_q3a<+U2BP=ws^-k~^Q|2F=5y`G~^8f#)yo4GfH&ftLYPo9qt2iw~EVc%@tf zix2faQ(hMr+G%;BkI-Cqw3N5_XgfWr1SJ0vc6uHcK!fIttqWjgP&;*o8gcp-fpFj# zeL>O2Sss9s2YM7QUac6e$=y$(-Oo)iw&&;IxB8TIrv}n{xt3{x&U*4 zXv@H91I&2AiANq32*-0y;-$1<;)!Pc;hk4>#u8pZ%MtSC2VU@IKlMgF>w>~lo0_bl z`|QFAqt+SfVy$XzZN6KPm{ScH1n^8AWY%9>X|5asd4i5vIRw-|XODGm{@h^(ZoKee zTmEM4NM;r1aKCS`X22IK4h{sW`uONHq_t#1gfdQmuvbPi!QCI0iY*=q|1ZcMN81*1&#V1p4x&J z^}VcmV2WPBo)%LjAM_7jD)M)_UZS=A^O zMnw%splYowi#3o>6BNzMNvH~L5I5Dw#(%|T=wKfT(Z4>=jLng~T0DRNjf+Px_C(spVAdsxfeLXjqOnNjB!B4)43tAVJ z??xy9YG6=^v;ZYgMBytoWAmi}KJ?>*)GjsE_r(#JeX%uq1h>JVBM^u@D;E*iCgM{h zBSKJAedAC$J`7y?%4Dca$j}I&8yf^j&PERyS2(3+!1g9B_V`u-PACC&Z0h5E$QHOe zZl=9GV;R|lSs1aR$RBVQM1G~!y$gFPPXBxXxvbqe(r-^)4pV=BBzX8;TUf!dUbdip z#P#tRn~Q|<&*0bua$sIzNUn2mgbbf+3yX0z7FAS2%#GSo+7j^!^b9^7%O{`@q<#sI z(92{fwN8H~3(N4Au=r?v@gC41ClZGdyIz zjNQwqy#-I7El-UxlBrQ>ZO|d(0%TXqHNX!+nAwA)wkpMXgTL0iaF*{S7N^8C%A*5v?>w-`z zQqEVTM0x|#mHbyybgIZjP+%7jyi2HE4J3!40}O|pJ|mwSB*@&k#|{z1H5_YT5~p*7 zUixWP3*Y84sn04Q;brIm7oB8xfM*I@1UbP1!b&FTKJe?|>;t+9KrHonx`DI=UP?ER zHUJsxJFC7gW+3bd8ew(@>0{PTghR74NOrsy1fU%hwCoSYtosEd=@aG2KJkQ9T{GZc z4eS=<%ow`Gd@1Ll8{h$-b_Q<2T84{Hk}O~#^B~0ugNFg(8@kf?=#5|>e8NQP)5ra#7BtmONM~kLsq0q!>cb*8V=IZz%rm&8ryQ_f^8pIy8|}cUZOfYp#gdjCk-aI^SkVk z`r5)OM;|_}^r1p{9u}cV|2awvfFSIBjvnmg(SvzOJ;*@9FjVv6g)SACw|6RVl1Bwr zDHV7{zQ|uCE|9+~d9hXC0uYAEL8-DOqK2pfNibg7{rH|j$7=(wl%`GkO1Vr?fkZl^ z3Va588`+;ElU9L3HAr$L^&b@|rCSfC&N%95y*WZ-uhye@5js&GfI3f}8<@0B0G!G} zwS@xS!e_1WDxmU49iJ3%OY-`typg67aH$`rb`?$SB96YrgjCwF^_?_;9?Qy-`pzEt zm9p!J*lfy)S~KA57bx4~MYfdzkV-DEvU51%QFe=^4Xx}N z^n)ln#Z)T09Bk4=uc3Uql-+A{&}(X~Rl9zq4FP30&ZX?uA0)!|1}+e`H+d0dce_${ zPpj9@sMpWpqLkfuN7-FaIH4@IO3A=n0n1j*j-FHJRaK*bq@JS;P%_;zp!FR2Lz8QY z*nR0Ta7AAq8Aw%fm*Ox%ntoF#rHWzgl7Xa#8&N0p1H^@)7Y5qS) z{_n5(KSdN<3XA&2!J?0>qkgnmw3dqPq8Fgp5O|q-KHLp5Jq2<_HB%9v8#$5Q0?ZkP zzJ!B<)ZkcfroPA6Snw--pKrbSEwJEBR+o5YNwUO3ea{k4==*%@L6m4-W4-b`K$!$Z zs-|4Y`Ck3t!Uf9MoSqAg&e*((+|x7<$F+$A%Rsn_&O@5e>bsJYs{FF}Wf%;12C93O z!APpkh4iw5CS%cjHQudU4ng6!AC0;L(ExK9^9L863d~OpMD{KF{{1kf2CTeH4A#$a zo{70~X<}-A4U%wLGoG(~y!+ zoy@hDAYpiXR7J^_fwQlLk;jHGfGB0MJIwhdqHAW&%K;S8mQF@pD@UH_51np2#%z6+ zD;d#$Bc-hVaPV%e8T|~$TP-gR%|6zA9YufWH1S;?o7TF@ENwBO&#IiA!lhps(Lc#U zUt_SbXh>l2?9MdK#l*g)j~Ux(_Gt>2elo3>U38o-N{@h@ar!&NV>HQsh9l9@A99Vl z4>-uN#aD3y*g6@D4y)N&9LZ;OQk*Xz*Dp~gD;mR!jAaLAr_eP{`h~(dqjnbt zJ5RlzA%Tsq=zN@AuTlF768Uru`B3{Jvrq!&Jk7fqP(s)sdBZ8VchxE*!h$1M5FRF?4qLRL6VE2Y zk`o^LfzV~K<}fCzrOn2yUaYXs`(=GLl*PV6>`@?+J-ojAA!V^I!m*`c&WzqKi?xJH z-!*1!rrztbwye)8ch-G4-(4j#yCNLZCLXREBx#_5% zfDHEna(H197#MeMXy7+aLX&U(j;B*-EoDW%qr$d!eJhtS>S?Qbvef0*D)B72ByNNX zwO*As6l*G*2*~JkuZi7N7dST2g4w6_kdspsQSB$3lBVYlCRQ`|B-P@0b*WO9E7j#v zxkwm&-4I<%Y0Jc6Y%UzzRTkadZPH0lLfwo-*FjS)pJGP0TuFtL-db@Yo2})linG*Z z$2UTP?dq~wT|QHn59C6XSX}}L5TDQsgPKx=6Y~LqR)PpNQc4huy3KD}kEmkx1wD`I z0lB3&3Cg?@eqjc(zS~<{0rlc$Lf_`wJiH88)56%TfOMEg`XMcDBX-(@8krr_0_WH)@pAeM7<1)BRr6M3wq8gX0!>)(=xB!(#`CHneA@!sPBoh zF9%GG&Cgo_8@oKC?p#haWUE4dRV}j@B{4L@rQc56Z+Lz73E+Ma$=jI7ZeD9G*)G(3 zRxT6_;h14RsH43$w4WnfBTBI|8! zXufYC4uISb4+tkdHIQh=RK+U%JIs_TaOZf2Q|%S_&yAVQL>Y@qv|6>Pk7mXdn#Q8b zX_pwaE15$SAVJ3s=ByAgtLZ@w6ryGzY}n3LVU{)-^`cqhW047-Ze5PE4ZC1Jc*&+CDZe)SK>IOj>`xfao`!p5Q0QUjDn(}rtW_FhCNSkU(}o7d76Msz4&)E|D5vFKPCrJEX>v(4ChW(;dk zpBOT!Q0^?2;_z=Q`XXGq+=zBj1&>9+(Cl%A!`L2al+0&IzITv@2JC!8GvXU4N6IglGE|0y6%K9Z@QWD~hbfe5UAKsXJ`Xle({n0@?u$5w ziY}XgqeGAT{Zmv6eW4a?8-yA2MP{x0OW7O1FnvHi7S*T)AZc)ZHe$S5ow$SpY2BBi zHg8dv$#SvjPCBq#g31$(B!v_Aab^{kta~EG5tfI8~is$*^&b+k5;7L~Art(&$8Esn(5o{4&l&vsXrtEc}>no8YAZ39IDQw=UJ znT(Bs+aF5ijcJ$ao5}bF1tgJkORaA(in0`b@|5mW3?tV>fmHHN)E>GJJjzyQni`^+ z$^^dVg;vcIfROPCE(ksF88c^4W(7tbFAP8{{Q%wW0rUd`s(=EN;wRBS14cQe7*QaE zTmTjD1keczP<+rq1G-={2?;>o`CkCa6Km7-*97*x=;kSuwHm?-+2=ibHLJ_Dg-`&o zZo!C4ETBBGzO7&s0H6S$kP4uUs8NjCC#42`E@6zWMthZv)=TwG9DVFl3)LG=Yx1bc zCYkkAl?0`};Ll^!_W_kr1aJWt0f4d#;&rWlT|}FSKD>bS@=X*~s&mK$q{D?73ISZL zzRW;+X0VHF&2W?rE^O-WvWG zP-h6N-DQ&frG9YXV i4?YR_Use${=)QGA6P^u!6JM-cDnhWbQK7EJ5{3OdwQ8d< znN!#xv;i{s_K=$Rd~NIpjOdctgm)NbgA@--@=3?nK2?yc*!o>b7Qb3FU(H?NH5EYY zsbz?&1QfEDXmBR?4ji%a8XYCA@cO{taGX&)j*mRAo9~`*y*n1Wf90K?%tm)0pPKU; zGf%*q6A4>0w-qy@$uYYefGSEJG^gw)zH@`pRSo`4igz z{{{(kV>wN|*0p7D7{N6X>0HJccz2A&ipQKoL$K8no9H7>ZW{Gl|O<{#KQb!XBQx%Rw=T+f<3i^OWgQ0ZS z}qQ!B2i7a z6qU8@rMb2g#@Utv#0(}e)Z$1nt7tw0D8OUJev27B{2Mg`E_sNKS$G@vO;CGUn4pLc1mB;})MVla6hbu01J@AU;02em<}%ZfWhs>(f)>i9o9q&nY2sv9HiB2_O< zDqF~5ic_*K5XtIQv-8;MUomA;$%-yPO0N#*fSo~A^QcG~74iWeQd+mbIpRob&8H;3 z?k7gwbIdE1Z^NCj2$e&l{2BMDied7Vwqj5l52+Y<3I!FzMDP2TK3qm`qx?~8kDkmO5M zDJT1>6j*}xD!WoZ;TU|C%E(U4g1f^SquSp3v4CL7B^F53!2Gdpdk{m|5Zw9LqvvAm zF5)nY(5XfYR^ZyDVv*wW6K7VKFoVDnI9+8N%0(B;Ls%lG$uM4mA>_9<(TU0@fBK2r8UH) zeUtQDyP*B}wX3~hDed+3ws(2k?VYCNMY~c`W#cM}MLwhgMvpBYYq&5fE{RU8dSTLj zqW@#h^03{wG?V-VDSzYa`j!0M|Ht;z%U9l0+jGgEwD+T0$Ft@AxSzT`m;6b4bG+@n z_(1#d^Oc8G{9N)U?H%rIZ}?B$o=g6uy(e&btV`bCzrRiVyz-ZdON#tS{b9R)>sD5s zB7ZQmHWzI-@-UykZ@3U1DlOZnd#TcTxNDTVJP~i!icBGx+(GMlJSgcdWbF^8%vUFc zSUc=nVDt7&-5%U-Pa_+)z6H@ikP7GQY@^!sy=A+)nlL|H2e=z^h>%W6(U90t9 zv@%DBSPO%k z_+Z!P3LCpu(%~afQMG?xsR$|AL1I;_jsy0Fja9nC#t3H3fP3zxS!#!kEkGJ5rx)jF z&QlI@tyjlN*x1VVXqPYmhGAo-jx3lxc9cxhAkvykBE2oB3nE~PF*yu}FuFy#OPX%~ zJ52Ft%hkpmzeDzD%T?8j3q0b}pDuDOK8Yo|lDemH;}yxssp;aVZ68m4n{_xQ z#W69C)x_2{uZp&esSfYCLappQ75>3p;bF-NuQBRy<`|(=dR;n>ACy|7dnz63u5<-G zgM<=4i8vmjEkljkb5Je&Y271yy~kFx9{04e2`9Zew5@bnsV_Jt*Ou~#Gq)6<80VJ1 z`1x*5>}`JAJzHXiWKv0I4`f?SDlbl(RN~W8=rovAX5TF{B{OzXVhF8mkwP?Rnb+_L zHRPcisUoed1Z{K7CLgx0xCf^4?_p5;>04R9x)5pxIvtVrN>MBT+u7%+ItU~dZ|O{w z17G6UfPi@PIO5Tj8x%{ZbZ=Bils(;5@F&b>!7PjE<+frN2F37Amn6wTzFOhyASaqr zQKw54(8U8VpafAF1t^q&jPD*AgUkZOY%f3YHA)Ez+7@jFeV17cBs7 zz#$TvaRDxRQ++)@EU1&<#)bBT`#w)O?o0r!9CvFcqdz4nHq3EIxhuvf%a%#H*E+R9 zy7dK=Pa&PCQ6ZgP_0`m~NMsDJpd#IKih30_1D>DjP;UZAlBC}5D;4#?ZdiEY_aODe zwOh+mEW$);3Y6XiASKJWQbn;n?dEb4sO*;5n}NZZ~EfN$tvm zQYl*SUasgYO4TkqeVMWpAa6)oo=wLqRliyKtugCE&_qJQ-sX*jgdx&M8Y|loMsZT=peWYX10 z((~yOSJj>mdTKoyyH+;9VnfnZcaW|H;aKN%d2!eZQ5Daz^}9-R)3-t2$E=yJi(_ZH zT(E5Uc7TlU3o8qjvhFhx_8D5p?_zzFK^#RK9g07g-$|n{;&B8r&F7@uU zb0PQ#!?I9wypy&wLiWmjOSZ6K&;V>^#{?WjfNS@XZeT*fsGGrZ zu}0c=Rk`wuKs$cu7Q+esM>yAyJvB&wVdVUp0p{(b40b4<3C<#^ms$Ut%GAw|Y$b&0 zR==iLr{)jB^=F#l7#ESaJTUqSC7D4&mf!q5ay({YGNBk;pELT4E{ea_jy^l-r<-^O z@a~z`;XU|I8qfI~(F7T*g651}0nCeT;g(c50GP5eln+d?+<=cx7V$Hfa@P-cA^e*l z+rIy!$cEcZFMv7}EdB`Fg2Fqi>l9E_oFwnx4ydNMpb|nGiym7n1hvfgV@el{E6ke> zLIMgf0`JB73N;dcjLL^tyWT5CMO%J8y)U|Iu(}5dyohX^wV?{UkfbF}5M~`whs5S%Qo-|9W6xT>QL=( znVI5;j;lz8;e;UzLSZB}NKt4YHO84_Ryp|u(PITCv4S`Rf@+Ss`x$LyseN&r<=rb) zw6MQH+dxt1*bL;x10xoFm`nTlpus?G5kO%rm{=P_{XVVkDsYv`by6GsP?_a z-W1Xj(q=CSQ5iaRo{mq_)4itWXk@6pe8gQ<#;L8E>s4qwFXXoKU{ybP8+)d*^MDC< zwL@F35(HDCWoIl~fMiV7h!E7OweB*pGhSXJc19qvLaCiwsCK@IL(osaol91D>yZ~@ z=KE|&;>DE4q?#tWgx)Hrl^<6c07SqIr~y3Kxo}s>JMdZCDfzscz_cLmrtq%Fn)8sN zX+OpfMXodJN8-55sjOgMGlt_c&jw4*#S_QIbEUF!GX?}vgNZ}4gRO7yHt4Vb4@Gk(eCh zM0y-aS1u0VR7tDkhuKtfpizCn?XU4;KIBJz!Rpxu%YB|@9YI|U6_Yp{cw31WD3Glw zkb?jBivQ9VwakLJUMdJz6-xviAe%%-`nioxzBPObzXRo2<=4>!#13==c8ve(4FmJQ z>YMov{AM_XLrL~$=FGDKvs7i}q)i1esI?)y-l8_>Sk;6* zDX-54T{fq55ths~2k@+l>D|o%4KHqM<*tmpCN9ooHMgYDj|<4?KcE5{q)|{z>=h6w z5ek&Rx|>?qFI>8As;uht1HpMrYzU(zt>h@q0}#3(hf)7D*}=H;7kMLwJ@+XXxBlLK zaliXTsWEE?pJV+CtwCV01|Y(&V?$wY4!~Xqcny7_cN3ij2mu*fYJV2f^9PJ7g*6S<9h+3^KP3kgk7KpquN#rE`>T3%_EGzrD z-&8Kvkm&yTh2^|L5H}G!NLz(|w&c0Cuu`7&raF!qcOlBbs8i92wQA3@3?_2CmW)OP zN5S&h#NI5m9k0iuv8>aEYW+d=jbieEp$zC z7ZlB2`c?Jd6l88aIMFqE<9GJpq_z_IIw7vhQ?5zY!y$?hP3|FTzTV@iM=5Co17;qx zIRllBgr=Sl6WsdQ(^NWh^ybI;y4EL@7uf5XgetT5{68Vp)(rSD$`Q+UO%gH?ZpN|@ zZd`-YNf%;p`oQW7Zx~#YfkXpj0GIKi@7yd}PuDb91nC-fhGIdDW`WWx(m&As(a9Kx z;hN4FvwEAF_mLDFuVg$BJ41cJS0S}fBej@Ubh%39${Iju;wOcj$^A33dzZo^ z%trP7P_N!QPr0IeJ<3Y5AZnV4F1b4N8y~q6zPs$6gL*2tQu3thbNRX2kgMcgQhU*y z)S_Kw{S#5qesZOtReR?pELfcI*gOKsosS zJPyg`K#q|h*Xnehnqf_$h?(*gcg#(nL!V(Zj><=?@4a8|Y)yQOZe*=nDt)W7_}P)~ z82Yd43l3=u=EMDAb{swyP0Li51z_$fFoVwrB<70e*#`S;fWy&7z%EZr#7nv?2o7$o zaWkO*yCz+}9{nG5^#8Nm+&E)%CHQV!++ggdEgtmSDvE-=qEUreZgwHYvD~8|7FMgQ zRn1p)$tKci3kSfW+p96j*LkfyYd_T*$Wum!4o_mK9-t#)sDMk_C$DcA4!QL1M)fx?g` z+Sj9c*b+5lKf)|+05Z{3t|6^PaB_yU!HB)4>XGcWPWO1)jai$d$Ocv&a;qLzT{GaQ zX`*__OPAB#kAPl*8-M~nq^3nab&bd$t3K%b&z%a1+EeU>%K0 zIQodN$CM!V;fn&PSG}N{=h}TR(pCcArdXhPK~gC!9}cBpqB~hHyrh-FksN6uHx*_) z=hdlt9uw&%wshi8N>x0$!I?^oDp$@EP9^?`>@u0L?mtLRC7M@aPf|aYidTUz+E$2H zfsjw=UFbX@MA-<^bM9)Cvv3Ae_LKdm95m@C`J6{eI8+#mTX~{Hgq?1kF#ntbH>?=5j9O=m+TN5Rr?bfS~bqT zBy9Ofbc=$T0?UP-_yQy>A=M`~5aGU7S+%62A!p{LzTwOZ6Wz{_H%?jbR+1tHXAV?ugI@jgBvlNqDKV3oAH34bJAk{MC!( zGSA1$=I9=1{xG^@Qsgxj5Cf?Zp>&v09Et{;@3q}pNqa)pFZulj`m@+xIkq}%Fh^~~ zkxh}D#k*SZ2B{DP9?`W-GByH0KK+ePE0@FhjLTBFVAw4ZSYZzpi@!}fG7z~7dCIp= z9K*#6nQPNQg;Sv?k2Yi9ik}Pn4ws{91g#@hr%~1SOO5t%f;MYJ{U9q9EgHZqgF`)Z zD=1~4Ve8$+LjSD9S?DCOti;LeE7@>rC$@qiHevKNg+3Qh z8%H-6$Hyrj0aP(;n&_@k#vLC4`RJ~S>5=HJ3#$)s+$+|5Qe;_i6JAzBkPg&%z}F1+ z5nQzuClBQ@hs(!jHwsRf)*ZcqWI?wt;v4JFOTe~&*yz9@Kd_M4Tg?cFYyM+&*HzVL zC+j{nrEY-W)V*VBTHV7?ccOyS(9~)GM%D9^IJ^xllQB7 zfk_%!D_%j_i(O?uVLqX6907WX{&*GLHOZ*$CN!90)J;W7vaVEmyLoxrZ`0`g&hx0# zqUN^gZPivI=?)~dEq}Ly29Q699ehc~qDSo|ky9B`Rvwxy3AFK*ioi~G${2=62p)$& zh*O>o96THaTW(GR?lb_$5~zM$;i;k7|I0Sem$0g(p?%zXI|6901T9ki;o2Vx{ed9^ z@Tp~=FEpe$UXwgDQq=KU6=yDGk+gWz7MQ3RJ9FZlq%LaOe_&Q4>M{;r%H#3T_2c zV>M0$QBwV(Df;7|Df&YcZ9iZA0W~jb`}dTzXi|UJ>fhEM7x=LCyD4e7j#`|eKQJm# zfBY{#Kkw)dyKY;a?YeFKL6Lbrz3#54+gE?sINXii=c_+5HE8P(HdvP4;NAZ~eVOz} zraEo?!8*U4oJOECS*M@=*b%r9`U6w&yuf7W54(C>e}G2TOvEat>JLrdvoQm)^+)x1 zW6^y}A!gi_nXg7i6o;bB%d+;zbU$%`s1>`3R5rM&a#A`5HH%Qg>u$9Y-33*(Uz>Hh zwZVsz(x}pxbxw2FX}voENrhTfrO5YXwDh#iA`#0$4v?^1t}^ae0mP#_hEA`F?ifs67QKiHq?Q z-EmFEva3OX#1G(^tL&u6`b2M(vo0Txm$UKG9wsu=pK;x?l+!-?tEgsc^O|;Ii zwr0@q14wz~8B`tlTk~fW%6~4*PiWGbU z{|UbC)_`xm;QJ*+%Z=~uYxjV!S`XV?r0o9)mz@P$MBqes-C*2NM;!+{|IDNfcD#^V zuTFuj7=13jLFrkwPmLPbio7JeE^>JNGU{VkgKgg&oKlT->pube8k<)iF{cdZ@8K+s z=4Yb2Cbn7nKv;Rrw>za_+*Xe<7Ts$PPRAu1J|wl_eb8{C97182mID@)!I_r%37A-k zpSv^5m~;+Ol1=!K=zMG>sA_{tF}`e_13yRN5|=u3$!9%Q5AjB=j~;=qi^4x% zL-Py!gcswAt=Vvv;SqHjAE(AAdk0aI$ zq$!UBjV*E3hdIyuLTLkTRH@IkW>6{UU~;9F!SfK3&F&-FK`mA56Uqy(mch%!fo4at zC4FeD8Ry@QrVq_t2`7>upY9GKtD?~QoFXgXM?Rw6W-qc=%lfkpii^QD6!%>{u2EG2 zrG)}I&N|=~ur3C#)GE%mg1N`BO^%T4f)E_r?Qka zPcw^^Y)oKp1O`wjW9cGYPC^&?$ZGww?jkx^M1td-Odp+yg@NPHd8~I-zRrnk%;J<* z>)X{~-zB3J`-0Lj2As#oc)|HPwb)_bCe1!evrkt3gnb*jknx^Xf_AX4i0%2aZ|3@T zuy4j@FZ-mvj_Wb zwX!OuYuzpRq-(Lb>J1)pqQqPw|2$<+pvDD!h9;ZB5?J1zS2#gZMI9D^JhtaA0CnryApkXBcm+V}>$m_2+DQTUMZJIj zRnRJ(+9b4=J}g8?>%+Mth4Hf`pD>=q)5*xyoS|6F;TF67Ue!3)%Z41=rwJkltY^R9 zA=V!3%BdLcJ} z2)AkUsW4f>%?3?V2;^xw$d@aYCiLe8d?L=g;X;G#aG@H2#?agcY?SH6q3I%PIxu3! z!HD@&Vi$U1+J>P90SFE?*cvcj$HCR@-Y_&zqVj46%p5^2DnUavN^znIYwdAdpI3Rz zI6T2(@*)7|X^v%Z%niI;;aIM5tVrUxi4FVV_%nA%)Ih;8@iQ8*^#w1kwdL3c!3Hb| z_#i0lFeIvN1RuW4K`@#`aC6^O1V_=_CxXtvunKt+Rp7Jr(*1e>IfKKCqQH=#qCl~x zK))mf)@7o=F>VU*OvLmm68mxNsW157HEmGj$WShKm0P1mO)6-p+9uU#P>>UQ(YQy&ighW9 zRWu1u1r6SW@xq;Ac z|M=m@%suDK^3J=>JMX+R)43=>%3mdq3W$3$yuZ#}^9^$Lfj8STKpmnW-m3vR3CPmE zFEHp^$Q05j1tq#^3gt32g0T{>wqSrxWj&ddWz|a_N{tDhDYD{}&r_A9)VKA@k{t{g zpg%MMHJceN6>1$V<+qNOipBKNa!r*e&BLV$QJO500i6tw;jlA+IT2_ExgB-2=F6AD z^Yum-9N7$OzFoK$CkR~(#d#7m3<7^}D%qP;Jg(i5i#(%zt_@e={-#T~_S+Xd6xUEu zA@qivWfWD{XXIK>x7J{t8iR5%B^&M{6BteIJ(W#EVFlrW+$;WsQCM%DVYv5DaegXi zqBUm^Y!IUpBa2;wzOMAzav2W}(O!t)!EZT9@+JK5g)Cy2S;7w9xK)_Bzk40UP~(e$ zwqwp#w3QpQ*^&y{y848+V|=uQt8fq6AZUBOeKTll`E;{rllHfawm+TT3)((8a7$=& zy5XC5pMme%cXy`xlc*)spL9IU<#AL)oMJSMs=)fXRD!@zo>I) z`;+f-ozpJrM~7CGz+ob?xbQ;O#5!zX=H=1Mg9{5TP>tH$)Q&!ZHKYq7MPHeKa*n^? zEiZ&n9Y4wtv_r0JwgzF2_6jnjBiD73p&a)SckSS3AyQG`tl4UO!uu!{ZNNCMYXA~Z&VEXR;0thJYZi$ zV)rEE!v}KKj^lgMahsE=mX0u!c=j+IYiXns8vYs=Il>`U44lEN_GbHe`(d`f z#Mx=Cu}2sofHml%KPv)ahU! z*kC;?%ghFoaXORsDkRD2Y;eW)On0pwJ2%9BbI1swW#{Rgw)n zUk=N_m$PTeSp7@vK7=pl&_5XJw&E+UR2Y+01IkjLB48{O`IB2$LrTB#9)>Qi{rh=j zT$m09aG&ApSl1A%ex+Eh7)|Pz@)!2Ku{P&^F1&ec7VFy0s=q@s?rzoJq`&sG>f`v; z`BH4-Zx9BGpB&5T%lOr+M%M34HL;D8uH7ZJ@p7wvPsuyUs^5*}Uyp6X`pRH=Hx+mN zz?|xQ-kFJ!)x8nFQ^(s}f4sd?$JbC2TCOK58hM-l+&?ZJepL+%mo zcf*C}}4Vob0=1 zYvyiNLz}daGDuGv8#Kj z%|_`hp{13aFuvz05umkb)k&2~;X*-D*~NTJL@qIJOB7I;8R=Seg7S4G8%Wivq%g@S z2*ThxL7toWiWH`iRLoShs-QDO;r!<^P&i$y?)A1(SZQGDOVO&*668lrBx%D?I6SyY zp98JB;`f;;tk9~VbS8~KHIycVHLFtj&&P|Qw2x$x$s)^U7?waoPkrF$9AqLG&Nt5y zf_nWXdgE2vTuP}wpP-b=CGrwwck(e2SzzAg`wcBIve+!CZw6h%nzou!d2B2*r6xby z2TEP>W-6tmzOAQ}^f{o^UQ;tuN}*LsiRGY_8sC#r-`hf|6WKjIor`6aQYi@ZDCNa| zV)vK#3c5cKMv#vWo;2n%ykjycfFJotvz$TOk^o9vhInEhtU9;G6tUeD;}tqV<~s3fs?V_3}Ni zN%D7*uwm10b0xJevmU(a&bnAN27&2i$$VnnFAS@g);6G&d9K0 z$;ce7DfPqL$;H7d@|E=kwX;%u-O2kZvB`ehDK%-0L3~_tRKY@>ym!(dn6Yjx>XOZp zqY6rRkAcl0rUNfm>V1uV3jMz=_5Y4@oFsgJ7&}K# z>zbYPHpXN4cW!Xt#mBUrjmka_vv{O+avlk`UX71r(Mhr$?6(jV10RkO*rmXk2qLpA zIPM*$+lq=bTmMlkw+TFmqj>hfr3JaHDmk!yz>cU9Mw4^Y^)#Qf*VK6p-$`S1XUQ~B zoc*RJu!%6h`A3cbG6$K_LLq9-*P1W#YyJ%EBsJc|FUZ`%6uFDBo$id$-gdeQIkM?x>H#kY~6#7M(ll}s8c8JTsONAI(Gqqpib()-T8XQsE8 zql$=XHi#N8^yVc^0lgVM#uM!8C9XcHP4GVG69=yJED~^0!fC+~b#t7Fa4dQf;suDUnB$xpe%((zm7bW* zaefi{2yP@_#Wo`7YF`ZI;wc-9AKLNn`jMTEFSHYvfNf?ObBvQ-te6TYmx8ZX0@3K6 zxrzve2(~kT6Yf0O5DT4alFaEthn*C=g~a;TXC#)&h6txH!pdP+1K#~V z;`u@lVvcjjAH#UwC-fBWCwNBEO-BucqaK%0b-UQghNo(){zLhJsWk&bVjD5F#;I1_ z?mYZ)3P&kXGTFkxY8B!NNT@IkT3=(-+IsUgf%+yYdb)8zXZ>(!_ zO@wZ3A=fT12>rDlgoL3!7-pDGi!LfQ0f3R@F*M9YiX(CJ8@emfV1DO0o34U~;Ym*u zwV^4i;RXT=<M>zDnlF?$I+?~BNR{LfXY|P|mGDm?$dXFbRM5hz##Muxvj|>B zeZ1ijdkef^HFL-|p0zQ(yO-ePOO4cJ_2yU_|6Bs20%X?Yseoc;Pe#6YFksDKR^_XJ z#M_%^O`#)H0FCBq_TD#|=}q!U>65@aSz_QbW!@l;D;Z}MEI?UzH!@T*a?7p$KpfpE z*cRV}5+qixGxIIVJO|?C*cN|3Oqf{Lq*@H{>^!Vz=UaHiY2bpEG@+3-pNh!?mT@f; z1Y2Ti&yv$A#AYDwrpg!8juPZcG@0)l`u9w|nWcO0rQNy4pU?IiIxv7hiX-SZ z1>w>8rU@$XWwnIeLLtY-yVyQker}5+dFT{k;s~fM>8oSmFWFOPpn^ySq)s*rsZ0t}1c&kI(|j z`VIMzQ|(-(=~R_T$7|>I_Kw3qJ<0?IEad><`e4;C&pG#?1$w@dLo@_{S{+ z<1M-oo*e;?C%9JqB-9*6D7GW{O~53QM>d2OM-^-zhVg)x0ONc*0;t{&PL7yaJDCH+ z1mq@M|M~Nl;WEphdCu=K0;RBU3X*ILXA?wx!vL&U4gmH70A<~`AN@ydyvj7bu}`Y3 zN-6X`Mw-nxE*VoOl+%pH|Adeq)&30#o-h=mV<;Kvn%kG&!@eX*t_A=BNj^ZWX(U0N zLVyqm+dKEIWd8|5nREPVt8p=gnzDW)A9>blEcE#HccvLzL|!slz|Ak-){o!BaidYx{L<70rm2nw_gPG=U|OTL2md5eu8^! zL%=2TwhY!d-LanM908aD{K>i$n({=vVGrZS^JxDA7`(#1e|Y=&=W4ID+jLFH zz;M`oTZRG6Ah(k7i8srnG$Qb7=V;gxx3yHJlG1K!d31{}Xp_x&Pw|5MM_geripa2792U zFaQu>$(Pdn0CxN=Hvh!9?hdQ*7>{drp0eakmFKAjl%l)(0?JecWf(x&ygWHrV(i+CEu&msU zXbdxdigi`jWW@G(iyF1`P`1zH(H`mqHUIb!}5@qc6Nga(+{H=Q}4S#98 z^uo9T$(e${4bK39$!~$c1v~!hpW60u()O2qz!)N$we3k;X!|LXGo|fkDa$*t?eDHQ zWrNjlJAQH~nq;_VVjpyzIUp|2`D%5TV3n*YtW3bkn1g^?0fBOz@16z#b6}B1lgAZD z;{(hL<)&;6ClgJSc^>TM;%o)y!4W9mu-^F4L-X%Z1@qJ&eeM9@a>hCbJ>n*0G%s3!iCAaY0XY(^BL0GIyWyl6gHitYIngg(ucH&xC%EXCD)u%EwnU zx}1$-V!c|uYyRH0MC8yzb;)Z1GGO_67#|an;pXikyj4?Dyf_%^a2`oYut)g(@zu!9 zwMUf(b*ahq3QNV?$=)nvGuh4ltURr zi(uB34LO)=H(sy@%OKdJ4o0-h3>m!VjP3r8!5+uKRFhL)8SDWk&r~GhsbEFQbJN&o zgeN!;p2bOyKPv|A>X6A6#*|C0{Wv?S9dPpmf(KlYxs#D+J?kmy*-&{Qd0#VP$Tu2B$|9>Hn~^6-@J-1}C~0-VTRQi%VJnE73Ps<59-yfk3q zAdv?zNI>U+A}f?!%CiUz9&()@Q80une3LGSJLdzz8V|;f{|b#_T3c6k-Z1f1JtUuw zEoNn2pYfBD=e3bXAf%1kK2MvhrXV3)1%G!*)do-xYMHHhP;<6sTFPe$ucbn#5@l%$ zasJ6hJn@Ytk2M&hfPeS>cirwWaKyl~G8BpXbNq1%hU3?@Fl4=jHj{?*5pD+O$S&te zA2^cLuUoVY5=hk&q#&<@#01rJm-CArWmv`aG;@^Uc>QhDA3uS=lgN{VPmDEbyegS7 z8TsZ#^$|JO|3F_5Zlja7p3t07sO|C$prqsz1<(Sh0TJy3nPT&{JkKpCmuJjYLq*6)7`57R`V{lorx6w7bks zP84<#mI|}W@;1XRXK&&V4(Adu2{~W_IUu99BJ}-*K(+pBBUEdn(|L(et-qma-NwbO zLkxz?t}WLPYIys^ap;^3PM~zj&S(E{Xsd*`f0kfh`2=!|vs!{yX; zO4DblwG7>l8V9~dV#TXMRv>~pa-Bavjyn3W4#dudj)vfP=In7dK7OuX_OH1U%?zly z6@LfT+|>Ch(wr%$;qRcD2K?Qo2LR8W(H8(Nd=hPN`#bBaS?c0EFaF$a%1-#ZZOudc zU2~s{;g7Ee*W8A`+tqxxcq)wp(7AU@V*S&iR|&~)u!HGC`#k%Eu!Pf5|h;P)(% zPnuCUoRl(@xRpwg2Y)}TLJr{<;l{u#LJihMyvC*hwWI9#urRWZ{z*T~KH-r}!S=tb zv*=ApBikuYp~pO6Ev=4Ck<4|Zmd|x=T7vQ?vV5#-N2`8UMTBKF;FJT@nbPTP{&$_u zsl_glluqwCL;%Ka6LcM?%7hsWU0-&D9wk(-QD7 z)<;>_QLHQ0wUgC2Wr*-Yu2s)d6y;sRPXyg5s9ARs`9Y)%2L_1Bl1NJg^~r-tA$RPT zW;najKNTJ>d3yLW@DP=eUUouW$$=|Yc&oSiFsKnL1O<`{@s`{in()wJit5YZOQym0 zE$y@#E|B*K`DRM0fMX@EXsX2U8<-KlF`f@knBRHMnY&=hrOgG7j6G0=D#InB*fBzy zv|Y3{JhtXJhw=hkh)4jqT=T5s9qa=>!?`gJ2;e{Fm3PQ1Rsy~)(ogbD-th(zd@qp^ z%kv?d7*dpH{!HK52J4qJwrO{(VU2mC&??mwQX-aBNjHF4XJjW2{4}JOUgII3%}Cer zP{;?b|Gx4>C5j_cqauo=!WYR6y-cgguz5b;3+Lc{As>Xb@E`_V2g#0y5@$6y*c3A! zZ;mGJB^$xNc<&J)KaBu|X#^<7GyFQ&3TF6V&-hdAe5j9l9Ad8i#dqji12XqJ|(vJ9`mc!aSZ>zqQ1T}1V+mER_aqeC7bT+V#A&qQ)h zr=a_Y+AQtw+sErpGV=8Po>e2$0=9aDX|i-ZqG(M zbHg}CV@t(J3a-1CpJQ+s07oJ-YKto_+Kn`btg5L^Ssfi^C&H7=3@VpQo~oG<8$>M* z4ZVmdG!G}*{HMCEL=@-zf^t!$9;7_tzYB-wq@AU|1>2dJkXEuCF(rs;V>_P$`~8$T z9+w$gH`8XX6CNbrE$x%d3{pvR8Ej|mw2UO=<}O%C^cr*t@#p)tvqGyOvf1pf+Rmg) zPuuyeh)hLS;><^5KWpn6k&qdkswW^7X&S34O=FGcGl(-sX(P-d?;uf}dh*+X&^LM4 z%aFl*q6C6v43KdZg&M^lmLu{!=_oHEdaD*itJdTb{%^Q?GdF16#5sxis1EK!`1uCi}pa zPu;&&Y$?rUU`y#ZMmiWcWXtn#-gPFnRA^=A(yt9m3Icje=Z@Wr(>c9r4~`Lb66hr= zd!o@T;B6prC>h#D&V}nR8GF(B^*J&b>+dea&|zY7T-yvII^dh=e2{f2a1Rp5Ymk+X zj0LF2TeG>_Ap-z}^-RH0%pw>4GE$ruayYWHdzIDrK1I>L=jdUn#NVl$QVm$2o*4cU zww8jM8#kO6_Y5g~@#2)WTFEY=2QbMCS^~4*73g}ZZ}CMSr`P{^%!mFnMgJ$WbLc-G zp}r&U4pql&xoDTj8uMuDW2Q6=D_Gu zU&wbMs0bK+>KJ8oEe7_G+C6Ah|1yr#FuNcj#O$oSuI%(Y(Z7tpHTqXu*RU34_;hrt z{@on2_#6Rf^PHoh3e$}YpAjfJp2;Teg;@oj%_ei84j~WBK9pDskWphktM4G@^q7}I zC;1Pe!f+v9>Q8qcF_S#$Y(pHn9P{Zsccu~0^~m4}=rzpj!-duigE9r{^pi(SaF9|! zoA5SY5wy?<=prMaQj#}urwM5IUTM9R*cZ-l749um70JkyCXcrSF;H%1C4f6EuDXXj zCAP1ex)22q5k&$ed`u_HnIRABMyS-2Vr+m}S2k`psyQglA##m|Dls(VEcgdKm2>^0 zpo&qY3tr=y3lDn8`j=?4o>D%X?T3))2s}#*n1+zZMPV+v*5UaGdF{*9NY$!f#VeD zz98$1A-y2$;LlSzuCP~RB_qFS*bImlF31StRKaTqM6z^7dX5P|T*6fX8QCcm2?>)= z6N;OWB`g$2`bB6ARH2CbQ!KtZC!A)~O*Yn7JqfD(2K9#|rAvTZTEH|!d_I!+v+&lO zT2g2vrPxS{l-wfmS%FXda24)9xuTzp9lG3}n z!Kom0XCEm(vu5gl84Q6#Z+a*5K5u##9xl!9p+FgW0qiJi&iDjO7`#Dc_h) z0*NdlmJ6q)93JWbSy6y1RtJ6D^4!cb$EL}@SR6pqEzk%ge;nL^N?X9F;N`AEa}Kpf2)ec-kr$AtM^yV?IM`{tPdMy>*!3 zO*=8e4DaW(iTs>rBB%QaY)a=uFZ0u~Bmtrc$$=K6Ar9apIpEG*<$w-qjYMRgd35yg zM)SCykKlj~)WLts0ab;I4@6Wc zDN~o%-_^JZMmspr5boP&og8=7{fyP&zYEC&4wTeNYE*J#5sBl7qz%5q?45Z2k zSW7>M;SV?KAfT$=)R&@4RDqj0w6p;RVtwI3fE`qGK~5_^vP2n3vV$aA`@;rW9R!{U ze3y#q;9PIkURSo~wlWA@EBRy)U}rO{t3j8@n?o(RjtMwbC?;f zgXGYD*5Zey9^Y_Jsi|*P;_B_x{Q}!n*3og*9$hYzWcbI4K$6xM)S0vpGR;+|Sq1rG zu*@q(d`HibAWZ&J_%Zy(>uQAuWdt5LNf6flxPpi+9Au8}L5 zvF^q}P-qM&H#;~!xrVTt>6cJue?p-0m4tl#QYl$w6vGlOot87VkFEc^7qk&Kcu^;cECOpH zcCnT`ySq6ov$LW!Lo*1~9_0TNY-fo?h&GD@OU6?-)nL0Wz;>M!1!2?Al7W#OV48LK zm=4$Cey|oGB_j>ho|wSrBFi};k7v{Dj4lXi8V1UiJ)W0jQ{`vycs_~^4!wIkv*enr zUJ(;Rr;Jyw%OEC8I84-hRi6;UI()>0YjKyqEr_}F%FQ6=@?=KDNYi~n%t=|jAm(Ol zW!NHOl95-g*bH>9&B_R!$Y&TjI{h;GzXaF-C5BeLDu_!&_7(^o*{E8u2z z-ofGS*lf_>wdrUz)22kEU$z%mDpW|*jdInD3_l6_hxh! zM}^GB!3~#rh~12FaD7v%aUk_=y>TGj4vd4t4gzj6#BeCIDQ2`Fpod|w+xH}!XGXJF zPxQH`a0ikvh~=xqj4nk`rECVF84a@whe^K4;Xa{eKCv2@ zqI`+yACuylZScFK>EC0UaK3f{`5HN-WNgz;R)Y+nn5h>EhieLyp2Mo)m*i_sXX;S( z0ZQBn%!%43F-2WcGSdP?ZFux&1-=$cslvGQ6`_VaicMoIDk`^NEH=Fe7yn#r?}x5B za-t_v84QV|XHr*r^zN~QD!rl3I%`WysC#Vmb=K}FiuIhog%zvUQoSt3%H7G(U3Ys6 zL9*H#Py~*jJT7O0A~}X4OhXjmBPlXFpond>Ri&Y>l-wdkSb55)SQjXCH3c8fIQEF0NgYL=+nb|^ALj|=2h%Pb#3n<$ zi4k5e4_IbErnS)MoT54(Tn{9bzAP<(_U|HE(OMihX5SzW1diF&d_?hP84z^nX_wzd zw|Og+xz2J481?~!UnomPhLn9Hv_|~^RI`G&7J{zII7a}UUy#cbtxD@MC=O##W$KM9 z4hFp~tlD)@g=Ai}`}>6+e{5#e?&E9KP+8CM64VdtQ$a?^XvqQ@u>bKJaG=%jg*e*8o5A84&yrL0B~TGLrHE zb^uAueGk(15a61-K6H5mq+BWb-JQYFrs3aLKDjn)SSEM|L|8Sp~f z4x)zSW*Bfh?r~=jy2pT0-_|prbUUz=x62PRV8D0^tuo%pf&p=(O(O1lFrKqs7;ksU zCydA98PFJbXIj7wTnK3Ro3KTXh^vOb^qF1ARKgRY)Aqn!(lBnZl;RX`f(+4H%eV{JLT1K&czhoi z_x`I=8CUAtdd8KG28?@BgxKjB@1W2s<6a@$DvT>g=)t&$d?k!4H(cm8R~FBJ#uPHB z0uuLOBe>K!Yv&QU&?^fh6))Kwwx3}!BsE}?b@--GxEA+&nrF$#ap!ti&S3Rd0J|B& z*Q9A$`(D6gAz{fB>vzzXzTJ}QM!Ed?u-%d#>u21D{`7Ywa=XufWu0FfVrIZMLLlIW zI-YXj=i7t%-l4zB^71WGf7LiTje0}$4M0-95@xMIbVq>bMSVgv>+lgBuEjl{F12Lj zgL5{6=#Hrw5iL#k3DL_sdqMP|=lX!?-Vl>Or;GzTPjt=vf_zDZ1IPCXF|5N!Ot=@nlh$-%k10VRJ7sPz|Y${?{LlAA6&VesTZndG@AK^Z89vNnQ zWvl3^iFM%`l)3Q8yQ9!6Fy?p9BhQPSKX$uM;1`cn2+mVD;=EjIro>Cd){UopO`@`? z1EMhdnS(^^nkN3hKQ0x{V_N!}m6YhIWMod%;0&s6f{n}T@GXW-lv#GmrvvQl5AEbM zt{?3vr*fYF_x*`j8Xd<)Oq%BXt~Y1hh{Y$b;etUEM`krC0G1gdSv$s!IyRr+%~aUy z8k-hshfQpc;6kvT2#t?!yI85d>&>ZohBeka;r>itY*+ID zUJS0e2YX!-t8t;CjPYK&_UMXz3Mid178?F z#OZ;g@s3Jzr3^L}fz0T>v)_1h7_DLf52h10I)e{!6*6|+;vn;y{q53kYV+;*Yj*dG zc6>co-jq844nfIQP~zWk>w*s~7+Jm=Kv4)l&N`b|^YirVkkeQws4I4WuJbryA zidIyhi?JWFY6gr=4#2z;kp+5+kI2WR5TQ{3i;a$Fdn!k=IUG2HQCl;d>@@8_3fTmN z6HLd!$Y0ypuMyRgh`6cXF>x!1P zS+R53Y;x!k!lnDy>|l4dc_pU3Vwb*c&3>9-#7&e?5wp|!jsL)a%*t?GjRX0y^gEnq z@e^%@t=UCy`gF{VLY}KoUq#$eJ7S4c4u6KEh$sT!B%D?MIO<3{3Px;q_{G$oM|cUV z*X>kQ^7CQ6wnt+M$4ldYyDRG&UVK-7nm2wvQBWz_Yq$_BP7iuXK<0es+RN2WmVpx< z25AaRR!C|W)3lV9@BpFpw#A$JLffg>NAWP|Q7}b2lU3)M0~&y~Fj=(;4|EvKxCZ@^ z2+OY}#RMZ_H0w3!1ih~8yHCVuzEJYXY>yCUz^TU>vyO)60@rX<%7jnc7+`~i!~;5m z0SlA+-Nm^9jL97Rjn8$CE|yH9Y!x39kyp&yVwBY878(+Y5eE9M^-0*A!`f4(IwT>P zKst>9n zFut{O=-2PF{G$l8v01wD4BS&L;J~h8Ug?m3+&d3ONQi7>)1$%$xE<5rdZy@~jL`yX zqaZjX0=1I3Ma{~XvqX9guPXau!q0k?SINoY2-ICq3V3w_zh&BnkULR%Rhodhk@`}2 zRawla8)*X$P1YCYRd!I+ji@u{nH|WhMn95@Y#weOg;uBK>QNIm6(oeF<*dD~Y~F{$ zrl$q|BoQF_vUNV*4 z%g03IKJzvU5Nk(eDG43T6|PjnRYmJUDY>%5o3NKJM7 zIDnhLK?B45yh>%CcUrXD1Jo3RHXqU-?7BqV zjGb77PP|K3kKc&|vbwk9l`~_gbfUj|B}oj`%Y8Gr?dnFfBI5(>Q|L9mb>C-XRWfqf z&-GM0{M_%+;Kr(RQGyyV*Ey$}fIt<V7$Pue5+v_e)4Sj2c9D;(7LH^+T*@V#4!LSXv2w+nntAaY;m5b2U!@R zL!J{Ur<5m4V7QTQ7;dVFRf0xVhLvls#Vg@_s=R4j!LRJn^;UAbosprm%ZmM$KaxYU zWzO(ZtKsXN@EmV7TjpWhdUlFx=Y<9W49Hk{G7k_UI6fTfD?&nd2NabEH2Mc97cNA1 zt;LrX6qYwFTq0Z`_BXnT&5e8^cC1`Oqgr~!yQ-ygq#I?=^Dz;5!Mx4GTQeMqLcnlD zeFYZlVCAAk_G34;+FZ?LdzrQL&J~{K2+cUs&D9;wPu0>=Uy2D(B|XY8;|ObM>2{!{ zpTeC|Jo#9)bP9e0m93ydWq)He?ww0?z}ui(m2jdfgt|Ic%m%bySJw2FsO-0S&5^q4 zSv&(y6Z1$rTA9=Lwi7}~d&38Yq&`0{d9lh>N@lgl1i~p%;QHv_%3!^9Uu5l?tWxe2n>^SfvI_01!j(*yzF;;Ohhg- zZx{IE@jN3i3nVp{7m2_ew*#8pYJr)@_A(31$D{ioFz=t6Dlk&t)(ebuI}n(e{rVs< z3c3o+G2F7I0j_1qxc4!B`z7BRX7hmC>`ZdfzreB-PULF_T(ANv}O zBrlMa#gq%exO7WMMBf&fayPA(kf*3~xpV#yW8(c01|RH_V~|ik%P3y@h1J*u{|$|c zIUF$3-EKCTRSzmAfujD)qy}lb&8_s@PJbW-1qOq?1t%iL?{*51SN5eUo z=T+=)dL!S#8IsC8ua1JjRMw8CE1wJV>FRjT59@6A&aG16CAY2@)SU6bu%#&2pk_dF0ig>lHQSmC_+eBG2 z9}|%l^VY^&MPie|z#K{S6a^J8ExEOG$a1!qS-fh>J;ZLtI=TF;RPmDfwqCph_&~h& z_~A#8O+6|k(Immj!@B#y9F09vcvR+)tI0+o2Sp{a*OhHpCHi%c=)C^#bfMTZ znTgfrU3vz7W%n~q_?K0s5=-jadSXep17cmeiNxB1E>zG{bfI9Qhb|oXa#$C#SWjHK z!z4(VQ*P?0iFfz{sEP`@@QfWZ=t5t6mZF6F1!io{Azr=~iL%A9DMTLF03Po()~vXo z(i75s4TYyF-S<+u4>fO_d|0O%A+3{?7cUD39WGUGt%TOGvCKq&{m4E@=&I9Gi7xeR zJ<+Al0nw*y%q*b_E$IA`)p!&k=OTq%{+{mQsrp;Gc(SY#I|YH6#B*WUX2kQ^RVtnf z*?ywz2|gwwPnx$&{8rW)GIbd7oI^Dtl=|<)a}nFiOsT>n`ar4uPD`bf)VKANl5Pi- zTD74M;;Epgh^Jtqhj`xI9u`j)Q;LOg=_Wr7n<_8g+EYB2Y_~b_ybUE(Jm+}%mYX2> z1tLS2h8H(hSTRv0-r~j)cA^^Q1Vxz93rKO{Q|)oq;#+x@J;q+W_WpsCi|rp+hHuF7 zY)TeB`7_c7TKGg~3YHirkk(im#3c9$-HQVEeJ*UFJTAWGBWITLO(U5!WPG?apFrhA zw`Jd*Cne#aqgw2~c|=oaChoe}Jm$=nY_R73N}r6hF0G24Qv(ml4&^i|qVU1^7QT8& zXltg<2;sX4&-L!(=Coiw=y!A>XM=7dTVIePu-+<30PDtE(qY|xJ#v2{*#PTX^x9;A z^}M5dft3XGU{!ApV3ph1H(}}>^61oe;#ueOZU=rkKW;+^#WmKj-Iwf;S=<)-x?jL* z#>azdhXfx;RrfXhFg*N$E(dpsekisYo~6a@SJ%vsx8s$QkS5X1;dp{sm&bfQ9Y6SE z8oRsKkm@VFLN?A=ahB*)w!69mPrsBW=hKx42Ke!#lwgXKc&Fs3f+h_Hkg(Ai>$(7w z2?kKC=>@wmx<}J@!a%3tWK?iQ7L}YRw;gl|rb?f>C{P*QlAe!zl>|k-$b6oN$@-y# z#=Z5!_52O5H)CNC^L-W@gWi@bFs-fnn8>Yp1CvO>)q{^XU2H}Ls!8TaRqzn%n`C$q z?&ngAe?RnU$yzVobS*530M(KA&4MBCb>x{6azC_w_wIw%6a5(%#>SX-NU95lYxz4d zZvm3v)`L82ZgbsInZsn&4n8ug_DUQ)KN=Tor{egR#5yc{P~y0Jf+jel%&@F@&6E_q1w5Inb|xg=4^6%;Vb ztTix+&^zASnpJa7YL^5Z+NCkuDYl!4Az*usq|z&Ris2JX--*9xuov&rf-&9#N*9W8 z0c9}G&rtc1=(N-YlpS#)h*?140r7wqleTdM;9e;5W9|3~;?nkKY`+q}@r1gvjV&Cg zWa(t4U%69$lPWGu&rr&}7!x_n&7OuV?}ML!<=R6x1Iu+MWQ1kBz=9k2dV}S60*fqy z?9Vy5=nC}JdHfG4;N)=L-oJA(zf*#AlH&-gJJxhdi=ZP+&l zOB?mbF5Z3Ty0ch4mp0n47r7Nf=!j z0-m0oIH5J|ds_V65!3;(bye2l$iH9MRmSr?{C4DbKTtfjysFh{9Ka5)9Jm^mc@aK~M;LrYuuyj^GgV@4kB))v0av;X;oRQ>a{K(}G=c@|Roc)YPj^C3T zwk7N?a-8{{S64P0ZD5lG?SEv7@Ix~4^WLkxJyhk}djwUkF~3pe5nAP5TIGZM0Eo%~ z5bJ(-AH$?cM#zce6JCCGeyjos@IKE@43;4{K}UTQ%=X4;MtmanQ&@sxQ)$QH3dcv= zPMlfnDYP`j_Acmid$&EmD}yC}!M3lfz$N=J+sR zAJ}vrn2l}eYw@~0<@F!6R;3eDhz4J7$y_7+ktaSfHA-X zDS{+Tuo2x|6MoIQh{T$)eh+i(*tCM2teT(MG2o_BkRx6F)1NoO-tAd8TVW__(DM~u z&mV+xkD{wEMR77&w{!ba^nH-@oit9N@8prBt?F+P%8+PD!o8eaL@%= z%B6kh2-M&CfX6;*^`D3Oi`kuWU=iXb%aZT`M20WstemqQPLjwG&M}W|?5->O#WN5y z#8RU@Tuc}Fp`5x{6fQFp-=eJ1cW~>t{FBv&rz{2=?;|!HGX!QDmIy6Q+ zP6cZmoeiM+uhmh^xkR!NDB#8IQ#r1EP_E528`tJ=A+O`scSW4N%I2=oL^HL0tTQ=7#QBynGeu}NJfUt z%>hV2>o4oHcaQ~SgsBw=O<}{vC*pVP?!ZeM={jD5m2fBy%VQ!QmUSn3Uy#$S!8tH0R!Q3 zw1B`Y76fG+NsSGQmSrY^fcx0~EHv@UJcf=+%{$-)`oCEEk9{O4K3MC2l@AHlkDf^V zE4ZH^wutXd6@U?O``G2fcgZ_OVJSnzEu~lnundk^-O1tV_EIkY1>PkdIu*5vQ+N8-f77KfUujhEvbJCkeUG&*8w)--Th`?fgYw zj?Qu~;Nv}Bo}c=Y7TS^DH<)S!2Dd*aE!plm+7?%MCFbD?FR>dMcY2ROSU+LljOPWf zuv@|`+qkm90iPN6g8Luja}=zN{!Mc4r`InTxnzzJ)ElR<>E30uKBf0|oMSjv2%^b> zzs(&4DJ7YII1!t+1_zj7vqfmuJsBJWOyE4WZl~%==;!nCD@8xcezV^Yzp-_YW=_dP z!Pp+tEY)btm*h{i89U z{zPTMkI72?-N(s%Z~YY%;Pt6#_C+b?dOtj_^S)j1`)m2#uQt2Yxk_&?A?3#9^Hez;0^CJP%h5cEagE#SD_sT zR>ijaojqef!BkOZDF!UUK(d^?UJ4z;LQOpj4P~KEyVdHzm_REkZ2Pr)w%_%h)q4^x zzq|edqz&~gKQ)n3>_2PfPsxKB`a6j4gZ_$nYSn*6EYNb7zGu%5vqdH|RR@Us1$Va! zHpJ)1UA>6)k{7AQapKlGbU(3>e^bBMiCYCTiG`A+eVoxUhiDrpe}&t~)r52x;_i&w zw`fM=8cMQVwtF&@0sEs^mWy2+{_n5IhbMp=-KWWi-oF%lPM+Komk1;X@JNVq2+^)T z5_hzH@iD|V`*BW?L&*fEQ5nsjt7M1bPbd2u9@+ooEXL7g?iD0;3Ov@#>(CfrvZ*a9 z*5S*p#BSv;t=`#<@NuuE`galsK@sPQYlrPBb8k<3PNY4*2aE;TUv?*^eg9SJ_bs(A z-wA)bWxdtXKf4`x3xRL^UCaQdG@x&RdDc$knoQ~NhuUlGAIj%}obnww@Y`?fAI3M^ zlQ-mvoaIr_@bX@gecJk5>So2u? zIkN?&*2t%>k%;Bk*VZMm5<3MLN;_=gHoi^gO0SFdi01BQ z>u$Tn9b(5m&TayXM)EXAO8>2yw{WsWXgK`=T(DtKZ$8#!xQzE;F+R(W5zJTGJ}nzN zZeZe{$wzNT@Ih9??tJcU9??B|#Ouf~eT?M#j#Cpa7ovXO2eHcQ&`;FT)`kc07OuXj ze@+Is2lH7;{J}!4i>*C9vhKSq7!NE|3okV@$9rZ*gFlr9FXA_^!3%5lk(bAZUyiQX z9xnj^dkHXzQTD2$Z5gt$i&jjo#`9`H=i~}J$!H~IS(=%+OzAgOY+ZMcSNitwhf=GN z_mE+aFJL?gf2yYhg{~~;i*x-KrBh&Vbmtz3(LQ%VWIteycApY*y$InHa|#da1pN6?L@TH zZkkw{xBo6{z5K}94C2zMFbJ_#yV3~rk~Skd7A8xQ!2_M!Z>32@mp z!NG0`3mGhZ;kLY;PX5Rk%IQDrxFDpXB0;PiDWRJiDkzOVjQNwN$&EwHUte!>jvs z&a%5-A&nV&Q~J#{M|!^n5k(**J4olQ*SpIyx0%o0v7R_I4v|=d9U`4d8wv0rrLEWs zVXx2aZUiY{cgRsx5o{u{r-}W^adwaf#0?Es-?iK`g#i*&31bxF68Tn*81UVtBsz}M zIMjaaD>?Ciko=Gli0UKlH9i2(iOL9zK=mH13cL@BSPdUgG9f1J8~6eC`Eo7Mk(*C3#2#=2&r7jd}lNOj47HQ&Hl zD4wvy3{?TmSeL$4pdgQ93!Xk;@MH9!|7AL~gFc{p`Y{>V@&19RP+b!;3(9q_9!7_0 zy>5~OnJ{Cj0mqPP2xDN}Q zzuFDkt?XaS*avV}rM&-)vXLB$_Xo>+@kA+tu|+9+6;v0azN+lfAFRej%nWC99=WCrGA_r_!I~g>pD!UuFCu zbHK{g9)T%juZc6|Y<9}F+XiqQ7BFJ#wWOG#q&R2U^b%?MQiQx+btM@@mWcGyJ3bWp zY-uR(obri|x0;OBvSl6n6Dg(-Y4ZMn6D=P#v;Q9jkuLM}xlK@N2QVWl(;f`D5@lU0JpnexHnh>LgSj4=~d2tnKz_Acq zQ^^=0N^}pZV04J>PH>Y$eoQuYJzTu84PzjW3JF zq5Q8`eWWJPj30po0APt>?sym;QdV}$i@lTTo zAIt^c`n~2TJJBS>#Iaj5Hu6{XC_6a}PKI+}t`^t+1Vglb$IL>11*NaWhHby9+QA6N zrS$M$tFxbi^74H2ate$C)5{citeLx!b;O@L4Ne5eH`b@&V3V-W{?<;%=Fkk~Crtk* zpH}hoDpL&(MylBGG56QDboQ@+yl^sz4eUklN_ji>W1bZgu}uy=lxJ_nRum(0&yN4g z?p_&bJ!(v!#hHP zt}L9R*EW-H1rziRrB(6(GX|AxYfpsf)V-{8Z8R}cJN70_*@_}38rSEbk=eHryNXJ9 zM_5sE*ly&piuk)SXISCGdYClxB@WS|WX6L|>>?jNMJFoatrbP@fynT8Y>=9}3Ah#e zln*$miqo@LYjM*#@Vc~7odVQo_G&xkz+wW^2EG3+?N$&Rt}aep0x)i5Rco-C{sq7Q zqZ#Z z()H8Nqb?eRDP}PYkP+%RsS~l zzoPr)XyQ%*An_EFX!hUXQ>^HIse)6qS!#Z)CY-v4&oXA5jy2)ogyev|M`FTDPgxXf z9Qy$iQ7+^vTf=6DM27Y3TI$)BFJOnPp^}ZpSKHuw%#&yQ$o6pzJ#e zh$u);6f5FBoJk&kSwS{GGiVD{i%x$H&RI0~Qm8qqZLh`Y)5I5ir2(LtnmMJFzp>&e z_uGlb6hWWcartE%#3?$aVYq5!2L6w{)L_wU=2cyGWP#JH3&NGH&gpN7Y;MzeJ#|IR z?Y?Y2CbF4u4mTOx?U6W321QYcLAJj)6Bn z=SY-x{wA|}89pS3bEKd3+BYRDO6EBCAe)?onl=3aFT?WbX?6XY$JXdjBy~0WbuFJ} z>T30!CnJ#AJquWJ?w^Z3W{h|Il`t3khuuQ-dY}vNa?d)L?*lbH`zL(H5t!gk`Myos zcO4~UDECJR8GqpTu^RqNEP_vYR)-GYm_;>E*I`o?DNM)R!B{6ktvDXHW{3^dtsx=X zvmwE<|B91@PPn3hbsR6$W_Q2pjSE=67={o4j7s!VcemSRWWMS=yvA`e=5_4TY>NBM zaPv7It`UxSTM{__Vq#G2YswAr%CQqSHM_qdE+3M-Fe~157MNmg1zC|mI%PKj(@>Yb zQIVoAC;yVRgipX+wl-}a&&Df#>6%^bxLS*G1gG64M;_Bokn!u2Kfvf*lv1BHa~UxU zwiE`1gA;-=OCnSamof(I4(0(e@NwEjY|^Ta@s%Q{Cg@~o^-<>KA>PX{20=a!`0*8i zA=c{5e_b$mvm~aK>9?)S9%0NrQWQiNnWx8FeziImN`5S_PX_9+UWdNPCX00W`=jug zjEA>L9kETjTmugpdW?eIts`E9Etb$vrLEVD@;vhRjnP9?oOZ#AAqYGxnjFv%+PTn< zeOX*?E&ft`w(oH8^Xs^FY4H1+A@;-*uUVpnhiooC14X#F$9lA|wFj;Pc#z`Dzhwi8wA8eVhF0d`^%ey_BP-m(*i za5W0bC-x)8($(Y$+KmU<+5h6V1Xl@;25R9hh{jvsE>f>jEa?;vsc!omflnDrRHGlDyHK?Tx<#&Z_J$P44J8d3y0CTLak-s#fStY5$D#>b?$FfRd zr>v4xg;q&`RCue8VOg${U?KoVn6>!aT&mlB(M&W^o)gV(34w((o0xlzWEGVLvv?i; ze}?NK_h4|n61;)r7$m8HruwpfA>S)=-Ge1Rec3LKgJw}iaN(&@lhZXRLgI8M!BWro zV=)Aig3r~X4a2pS=b%1RSj@l}YcV5$UCA!? z>;xE@uv+=Pyy;T7MBp@l!HQkGO)!jG;mv=lf~yuqAHrRp$g^Jq@mq;$TL1~m*7J^%!%qZ}(+UPGZ=TEfrN z`3~rN7YKu+8c3fGBsv+!Ut%327FN9y2x-79R+TT&0MHT3(U~t(-W?6L!Am;*2%!w#9^AeD{Ko(yf>AxI+mjm?WQT|Ib>Y`7~d9=KQ1a|NY^Tb&>j1fU^ zQ9E)RuW<%4M;9*PUc;6z^1-B#`1l69<)8UD-8}vwz3|p!YbtQMiuKs5Q4A8+V;@nN zTfW4)QYTG&?^j-Y4W6<)qZsq7$G$S}pF`j4?CcMu0hWQ~1?~j;F|*J(=vL6aN&re5 zuUD%+EFqXSaa&1P%XyR;d^6ZBdS(_P1OQX46{rxuHTFv=+mXGiguT&&87>xUu$=Xh zMANi%mf6|-*&h>9ez0bZV@s%kH2_P73*F;^Z)Z`vwDo`_0j!SQ1hqXx z)pi=cM@UYIajKz;!mPY)#p@gzbmW})9-Mc4*{m<=NE%x4bpOG_7B%-9JPfvG#RiuM zYS}cvZu#M88}4L}gVzR}5A6WX2UbxR!nsSX7y`c+v3`aXn+x)do%mwj*zEQSZas#C z#~_}uP0Obb1lx3i`!{u5gP-l4;2}&ql81LqqT>SUO=omxz#F+`j*P((t$d7Q-C90{ zAhwF6=~6a~Q7;(FxwuWx_!~_IV;pp`x8JDTH2g`JkKoVaXm~B99jH$kIK=iRb;0g{ z{m69KYx@8@t~ZoA0i{&3;qs77RuAh#4G59v45+ZxNvxFK)oU_*CVE#0f_no>&_Apv zcj zEYov;kL-f?*)_g%KBwyfO$n^1$QdAtMpx*f_@Kax*9zlt6vjjaO^{U>j(tz;kFNepj1M==&cn3BU^`jTpW6IAwCeq)$r6e@dEyffZ4 z;`I&R#M|)GdTi~;_=b^19}zL-{^|id+AH(XD!fyZk9>}62Z^=~pU2l=%^%I1FLQApT}d77XHTC_8027Y1To`P0v}!UM81&#&T3c=#KMo4Z8bcDU;6b$ ze2vEcVNdMdZtTR@;k8=>YmO#`(!(d?43>c2FYTPnOIOLNV0C3xTJLa=dTR(LN>)s4 zz$RZQ2I#5>2F51N?}>qE{DOk1(b5hpCcYRfmoOSeu}VIRf8*Eu5gUc|NU!?$6-DoJ zwCw(ybmRuw>4FO|@yNtSewll<4Sey_`HupTJwLN-h zCyvYWJP(L4g$sYQo!Cw8F-ly9pz`+WQZNH%o;a1YxCZAysB7V}ydF|*+!y~~CAH7O ziT{+d?=ngw?A6oI1tfbSadwcGBe73pIrJn3$p?cfMbaMf75caaT zA47+x`#(-2E63JBfzbD@PIiW)fOD(JujQaKW2t4*iz{16=V<9m)zo}Dna)CY!mDpO zd*r&HvoOf0pnT2Ok=I*i|NORUzD=C7a5>wwxG-REwzzk`qE}nwHWj@5TW9YrUe;@i zhe?aH&a=}S9p*P$Ef!NY2A&cuW4&Y-rDy$4xR~N+&6Le5iDP_*#2kb1yepX{f$MEJ z#X%GwLq#7F$j#+TrM0`@1ByYWn6v}gS<|5<@b?(jfw*i;)e^^OdAy#SFaED%xS!LNX5GZ$@ijqPGGotewv| zMN-z;*Q;Wsv%C2z`~CyN3{2Lo?9XLRJe|bkJ$Efx^rmaTa*RCnMrKWe@mcn>?axpz z+0SMoOd#_d^Ee})%6Nb}JXF9=<{*85-8Rw;(j)WnJ`1k4OE5}b%u$+}f|Q!nia9Xm zf0&&&;Cg%1&W)~m-|OC(&XZOR;^ax33$1qv%yGPU0XgZp&>Bnd<`I^~x`ixKPLcqr zz3s%olKVz}LvcHCnHH}z#jVAc53_$yot=NPxBqOFC9Zd>fk_P)JWE7u~yA*|fh#;}y`(75O-50LxE^wF6&X z0ft4?%}#b=q^Wx)W+=&_a2`_U*6xZ1m9>$Wa@V$dzc7Js8<~&RKqV}+@0OXK@P+@~ znY&chY$G7Gvf|tLu$rd2s7@}QSo-MF2XVN2+v4ECDvo_jx3`63TXT;EoMHkE27zJqNU$dU%@a~digK&Y^yI}Tj4QZ zdIEO=oOZ-Rn^}dnSIloh;R3)QH3CHbnY>gr{>EUHu{o>m{1lEy`;b zJxtO1siGY;ek=zHE^PgZx*0VZ(+dC?6o?guxCZUjRh|X*T}9Emw7y|eM`5MUl*||3)+T-+L4X&@#NRkKa0O5Rifd&>K8j#Na!7`!$YDf9CM2zad+$2unba?9x6KiE}JWEcf~J zaI18Ch66I!-a#l(lU5C+O58k<$BOuS=nTx4$&7I*!47p$=e16(nMbqViuPN&pU+(${2@#f~yyzE*8P#q9`Lg?5Z)x5HTc_9;eTGoB0FK(i80zZ$NHaG zi}#==#aw8N8T`iNqnA9hs090tua+jYKh96407#dRxx+QkMX2DU@=>>bFo_sagNvw2d6n%VJaNS`J6h|0U+TLKFCBH1&bZ7iO`IM zj+0u4VWCd7#2 zM-;XLy^2vBl(9t8d*$Xn%+hd>0$y-Ju@N0L)ejB!>NB1c*`!()Kaz@4p;r}n4&?%mXt4_pen4Xc#3oPDrV^$~r{Qb%aLr`gW~4!0T@q=k-( z^&<;L$;gDCYP5Ped)U^D(F+2<0Z}ATOnoQtC1_zY&2EXt@0EMhqD3EbY?eC;JEj;* z8wWj%m+X)%GjpTJL2czb@BR2a#yqXZqXb0|atMwf!lflVl<;Aa)T8xbI}?`ThJo|u zn@iQmd@_M- zdQ>#6MA%KrgnU4 z^)xl|Mm1r=%!c-1LxpSzXohldCJ{a~R8Hx$Ij5_XLtUhS%nhk%OqCpvYLhmZbdE{q zA;n0!011}uWZa)Ws^BUtFI)u+U=|pQ3l6i);V!e}yvU|mdOSulcwHjZZ4ZlSX+a&Z zPWZu3UXV2wr`fHm4HE0k#d>g>I>&uR!%CJfG*sJXt|h34nyCcvHM36SDkr0He!vGP zAXRkCRf${+`5`%952ie$85?~Ow~ECEeIpZz`oGYqX=}-6R^#G9Es7@0QKTQ(#=sQJ zsr{n&&&xwT#=|0(hhmi41t2`+InKWrHDgv_t{Ba;Q~8Le1#fR9 zvm8q&>DDm|IDU-PcsiQJuhCY+;nIJocc$Hc;~B7j!`caVrMxn-4r_Z8(%Dz_@fO%v z4ouoQ$Wq%OQmz6gK~%;SV4F%nm3%%Z`N&LoP*$g=!h`a=nCM_2_6qbWw-zhwqcSj4 z(1l7$VwH27k-G7ex(SrJNn4USL1e=_)H$FhTXnH1pc}6*wCd?$!mo>J_osprkf8Vk znxZdKaO~cqS$|uz#GQqo@D`1MS;fLu{ndDZAO~rx@fd?}Qc37uG`Qm*6yN9VXU3~pTJmy z(UxMb&4C%O_F6Tk$}`rj=g@$8Ep#N+4bpOx+Dwzm7hpX**0$cc6j58&PGhHqJ7mAayJs|#w28e~rH9iq2wB$Od7gLJPcK@4;7%UAUAgQZ3G z0ZV++K*=RiBTM~tnZGXg*A-mh;Xpq%*v05g!RSrF=*=)A{@`m`vyQ zMoVZO#~}8=xS+iBDYGyoG(t#67i?^GTbn&-`-^hJq=AZoKE4k9%XYHdAj)qTik`E8 z%&gMY0@5R@Ks`0$(qf_iQ6#lEMQTyi?Zi`QN3CIMr>G7h!D(Twmi-_(EbaVDSnsHP}JaJId%&4GV_(C_<%I2UYb&@7(z_G9qMr_yE&ij6IhiscrETo#gj5R%gAU;eTD$W z*IiKmtPP43KEH`4As~i6&EJB)hLd9n#cu3;dZ8-#-pifY#3HHtbfyk5*0x`ZK(V$z zi$JMMX@=b4k13Eg>Q)0Xi5q;v|$APtxb8$=3<3mui?`h;j6~3t*>i#hHus%-Pycw(gJI{ z^>}e3!Cuxt5FuRJ2>(3ER^)Qg3hL4EPf{x%JgWg(^ZKtMGpwT(FGrG=JXi6F*7>n) z63Y0_4}L~Fg}fwABpUOr`$OVRFiZ#aAswS69momO%W@>T?TVlm7@N^t25z4urZ`da zg7ZlDy1>MBFAISC6qk%s(=9B_^Klq8E4tiD9(Ji%HxYs@jx{gt8RIa*#l80OvvJ9R zgNIK)T%!e7*@K=&ep^D(i16ci7i#FaKa!&i8x0AS_lC@)rGmOozS@vxU?B@nj)9hN zSKje!D2$qzV~)^<^BXSM4D`TV!2>!`?^{rVW-o}eX!(2UW0XPA%#yLxa5}9K! zSKtOXdwHYevT5aPvl5&bU|juRX}eu#ls;lt=6ktnEUI%P;?h6*$DmQ=2t1rZitCd? z6fyr7CbJmPtw#4N0-2t_@bwzg!v`?6Y)Oub2wa{^q^hwnT?z+IWI{HDR#gfsK#%ufnx>Vq8RF&H!jyQzu5QV>GmfkE1ZFG% zDqRb?VutSHaY6lVvBVm5suU`8(W$sk5%JU7S<|Owgn)#CzBaL8(XP&0rl6(^ zVRN(YfDpN2m31Xun+(`&gWx5Z$~ktsEbP!PGPP+30H9Vy)oxZrStazxdRH-DmTqZv zMSCQvk)x%$FcE~yDGaNRHN2a)qbfu{Ok)>NlSjiw-o6#pOvO-gtWCRwJ+~bfLRd3^ z0)Cvz-KH6 zY?hCYS_AyRUb=Ce)r4GA2NsYwwdMe7LZ>Jg!$@CvF)%>=Y=MI&tWzc;f#7NVWx5qo zZe&(8@toR&Fk z**?U^K#VQa3uR&ZEjHk#hMq2qd6eSOk>o9u70Z`d>b(|*rg;{pBjniyA(x4Lz1Wmm ztFOVc1p|oSU{l@pJ;aa%_-q+ar@4 zk@-vtuI-o(GR}=8Ehv+CruvZ!&UgPL9ACnoWSy_?X^E`PPNloH3E$e1{Aay^a|Kz2 z7>Y7T-WX2y_BhF)!E&!WVsx%h>K*CmWZAFJ+DPw{|JqpZe-E{)AL;k%&0{OKdiCZ^ zpL>vEzkZ8O-3Izj-PS^v`Kt{@S`WTt(X$YRiRAXGFW#H}4(>yHM=zdkB??CFWj*_% z9E89movQ4N^)4_uVpA~LOWakFg-PM9D;8VC?6CZ5@Hmv$&(a->2)#xbdbI#p!>r z`m8GR-r;nl77c?=N|6nx3eMPA1+`Ql^@e6Mc~QEhlNT%ue(;*q(MpDU^g1*2_uGX! z`);hx{vlBE{qw6kQT}?eZ0YC_OI`HpnSZ8{+_{2@p&0#(2p#vm? zoi)Vzg56KWA8F(+9P8_vU6I zp+B-zdeAG@-Ke+PR3YQLvTWTQxgx2d0;bu_H;pb;mEMe--L}DjJq#k#G_a5%mqxB8 zWtaKMIJYu2VQy9lQNhwUNYM(%j*oYO^8zmQu52&y&O1iJl$bP81XuA;aZ_1pc zO^^g8udXQ%>d6X~GN;T|qit&K-_Nf7fDssB{07xk&5laR2e?7RkAWi{afQ&4Bt^&{ zYOGPaj?@b#|3LE>qNoN)k8st?c3okyxLr?@7e?k^jZ)Me*CUstD5uoyu?UZ5*%&@1 z9+jmqWr3xPvOu13ygYw;@3`9^>;P89-B{)6Tx69$9TiG-7gqV-E5s(Yot3diwrO^{ z?^2B^-uj&v?OQii*&HhC!o<6JU?l07b2nDO1qO}ct(_eOSIY_wSlSJm;86!uhW?=> zdGBU62uMryMA$oYZc=ldQCa?zjbP^Wx4Z95$6R`HUAlA^+VY05bZ2w2CUvv4_u(g@ z<@V+-KYn8I%o8P4oX;k)LsqqK92TI?sWYc7yo(Ia&7q@&?v*GkE)i3@@#t&;IUiVW2Fbhlj31xf95o7ZLWJ9c}7Ww?m0Q+lrCufC-$Svbgny#Eny}8x3P-qsK|4EXA^6YfMi)|7Zo&W zKqk*)AA`ikVD+-CjT(EcvYn>pr`AYx7LnSVx{AAuJ=K0(jGtE$o`pHYVK%59T{=nk zvN2c#{V9?~Dwg4ZGBhX6m_}RiyPU#7Qbk%@Sv31hf^|bQ_+_PN-(| z^AEBA{GeAXsj*!1*TW*sVk zO^sJ!7MG|IS12w~@|xsmp0~}mHIxrY%r+o=NWughowwW|@bxA4-_`j+nJgEWAMF@C zP3D0B&MAg2bI>YAF%hM-Tw3%Rt1*m!wYYIIy)lMqTDX+g3xc&A5=!ua+xo3+!Y`62WgAU!BrffOQM@txw}s$H{o`ZTt7(&cy?SHS=Rl8)Yw}QjDuvk44_< zeRD-5 zWDnPY`K~WN$r83E5z`A>jv82Q8o+OpEJA+ zE}3Dt|Czh|)Lllq%gJ_u5(9tX(jle`I?^G8-oXZGwCQ0lBT1i5VG2B*4zb5SISBz_ zN0ax9CHfPHV=)cdv@i%<fM~X>AsakQkuKzk$#3&KdjlVD zO?k4T*{=e)MxxOQn%2kp+jw~TW9gr;D&aPW9IUG3e7I;R5II97Ec3-knX{2J%i73# zhJ;PnVp?gf<35&nRm;TOlFez{nxX`zHvp6ox56$?Ra@N8la>zF$w|M6chigj!c z8S@`4IRW6v2zb@)X*6QG9|+FcSUop(Uypg{Cb4uKlBaHz@tZu&RNh3p0Oj}7wc7~A zLK|r)hlREK2og|gKO@E0UP-+!eg9oo-5_`Qja}sMNe>_>$}4XbHHKQXf-{S^1 zM=O~oXuYpWU!)?LlG&KC*sOGDpd0Iucp_CfpclOQ?3$n+>^4c?UQ9^ zR&Rs~XTQ)b74osyaZ~e}zL6`J6sj*_|A zp-kLE2n&^o(*~yAmrA!yN;S(gE^ZZ{G_NWA_Fe5@b9m=DZbWy!|J-JGb-&v>b@iG{ zHm|GKC_eCdi|cCNZ{O8|P3h{oXE(d6@mo7}_3p8o*VVhVBx)6Vf{3amk)$21`YkNt z_D635Rf{&itBY>w)YT_{(REiN({7NZ`6i2ai8E2z7V#&}LiLSxWudyYh%1owZ?=ev zYvx--XZ6djJ*KPny0M58yVhqPYJZPp*%iY#qR)Qw*KeWEg7Hme3NEq>RUeqHx(icq zNLY1Ora<#@L8+@Q>Mm35(!_K}5p(*=c*fDGku#Q~HK$9B%Fn?KyGr-DZrJRjGE5iO zYiCPy-LUJ~&$J6S%&NvVm&;GKx^cs-l8hTRt3AHfFr2sfHINZYlpuxZEjRr`S)u>tqK`Cd4 z%JDivduL73v5r~6iBrTM^VjW`Qv5r3(0(=%r0BsmlZPnCoUJ~-fs(Hb+XPC!uynI2 z`NfT$DA_#bKcS@dig1)1uU${ml&sw}O5S$Ve?ZAQ>;U!svr<~KD0vr15+!Rlosx;m zawz$M{cK*-FLLE82&OU_zO_HIg+JpxGbwFeZmwkZSkfguXMLMgQUN(Dab|! zNezcG#(Em5VvO|{#9Kw`IIV3XMItR%n`1;6$s#r_jrzIdNh0iA+UgpYtHrT4ZNL8-~q;2&R*NsS;WX;vh>NGW_i8sZai0)WS z!eZ5CSZIB=zUZ-Bv1;cjWMb97JUpbO-zmdQx8=sF>z@=Y=ec@liS#HRtF{(GePng> zgV2btEGtm$Fu-8c%xkba8QRiFnKDGF9h?@W4hLFsf!=wbwe!c&^^8eIR}Qg%UtZJ? z-OpaB%lMU=4wIXzvPC8ex@qx=^F!C;fOa1)h%W=FTDD>GA&4kdiSagL4ysW97zTx{WlS5y1S$5=5z$e^y@Yck%c+P}hZlGE{-zTf*wcSI)`5iAFM9cLj}x3Lre#%@XmB`DC6Fv;E8jXO zC7D~r{ikixa7xtq41a{k9u0@vR)pR4X*kUb>lOs(*NfAG8xMptpGMTXKcU}kY1B%zbW zxu(bDZ7MgApw)02l3Gq<%+j;VFb}jDoqy2GUY3#O)qU%8p4HZW(!6>~r1e7NjxDoZ zxI~>&A(oqHuD?Lt+mDwS_WUcax6@$0h>j8PKv)yYo7W9#+^%_b#gs^50S8?mB-&qp zyB-UgSD)RuWAp0sr);YiXE!g{D*N3qy*t{y8A z%$6hnV}K@~cwsl8Pm_T>uu5L{$8mfe!bc*%4)lRPTR~H zzXnjI#OaS5KY>K?edgOz1dl%X62O9 zrX#C+a(Ye0Dz^hOvp+10+J*AqyRoi$-Ih~+I{%$sec2w?KGo?poPzsx&v7Fh64o1G zvXIcU78xs;tab-wwOg9gu9zXUqkNnCpNl$tyskCVwJ-g>>sqklVtqpoheldzauUGmZzvaX83tbmHy*EgVCk^ zwKIv3yr3n6wJZI^{q`agzkzn4zJ`YWehiiR zi$ndSNb8@t<0&(<1*u!z)6tREew3Gf8m-5y^%0%UZWy3Ptg$Lcz2Y97;~t45sRi!Q z`H@y;Qmn9IkEy%ds6{O<++emAhuYx_Y3Q`xk#|@E| zm4HPx6I_{oda2Xbc{C}~@;on7C-5`4Zj5z&PrE>bEaknTy~}iMUfc7sa*h7oXDVfXx4Z*)*dBN}d~*U~}4 zXQcIM8N@VhD2M_u6?Nov9G>7MdmSdK=NBeV&#F2yzHW~OvTyyF#&lNP+C56+>-K3l zESAtpSY-}v&8A)DW5W8Y&!wyYrU8>8cN_CN0Zw-}u>jC2Z8&{ba0_4mrzW+^#eDDYgY35_}ppGu_QNjJtdm9K-0v&G33Iq5zL zp^5n&?Oyx}_7a zY#KrUR!K0?X!u_ZewCh}@sneVjRe6W)1D9_6K^Z;H_ol&9yz4iogNS;8E=Ts*#Mgz z*`>E$Z8V`?&ZR4&cc-*rKbP*4&f7$0ELJD}EDlzEE>^A)qgi&FUsZ(i-?$J451%W$ zl^{x2iO~+`xSzf3G*y(|Q6f1DQP{&yIr%zWnpxbpo!jkKIv=G)cH77iVg1+MqS^jV zrbQv2M-Ns?f@ki@l{W;UQ9F||EMwni_Lp^1M=8>%Y<97(c4`kpc#3)*3wNAMKvA?6Tc-x@(DdsjJF4l?;1S z!g(|}VH^=YLHEcT>tN3L6p3H|15 zS^K8ja$3iO?XL9_T2Hj?lH2sMOw;W_U)S{gyVLYlnf~JM%yIdh_e*Ctt&~Y6zikDV zN{ub19M7=5ar@@glc(q;gMddmRz#mIsQd$e8wa}Ywy(UKUy z8K|I2o5M}oQ4nq0AHJ7lZNL#+YT5==+NIC?rFvNTFS{HZ=#sX@PHL17EUBqMdgj>G zM!RnF0kLSEBIr*4T3FUX9L|ox$WU3Dph|y=&WBF>>Q8a-A#SBHJoKzD-B&z-LV$m4 zRB;~-X*p~2dtaL~X1UPGfxmFXXNLouNY@9?_OK7!#CrOJapNSZwK16`ZU9liMhUO( zfCIh`er6yjs_xspjLrB}3MStjCO=B8@&84@OkQFh)`MMY#b_bDI{uYUhG6Yk#)+TV zCDyk6-}f{Eyl$6+-{1lrTJ6$jsy(cnrV9kP%KD$bjM1ga3zKLBw*WxbxP9!i^O?My zZof}rAeL}s7-?jXeP$e9Zx(ESBLXYPHw;H#ub>37u)ht+q&P=LgcRMy6gPXo$f}eOGQks_js%DxNJILQa45jNL_9buxOI-C7@`r}%pljRRZ+k)=YlYfcdS`Z8&15^YliY21|tQXhIx32tZ=k1ABp3B2m^)MMNEY;+xFUh7>1;H1# zwUsOR=S;~bt>kwoc{dLi_qm(jJq;wR>~;FitSmSUKJQqwp@U=N%EsqBep8QU1Un1_ z6Fr29oc>S1aa&m;Fb5et%}10L)bFF;L!9cMYenDd1%U6>k?gPT=y|z;km$V^pciy3 z3m(}8&3~Iia&GW-z#&jNJej~rkxmAqIdHWv3;^2-b3sXMVI!7=Y_>U3JVO-^vs@}+|MqtcI3I+U<&Fv#S9Ham^u!b1JnB{KIk zwy)%bw(^dKt<5c6)p$4fDDEMw6c;RD3;sukad5~Va^sDO73bXj)*9{73_RymN+6kK01v+ z7?d+kgZW{?u@cfzV#l%40izI))J44F(3%=9!FY}sO?}PqGs{?Wn}-kWYp1ayS_6-c z0dNeEq6%Kj6We z^WWW#EKqHV@pZw3y(v&UEYUu!dDVvDyDvyAYI;vq_w7I%x`p5jFc|A?f3h46MU-@w ztH#0|WMX4}OMkL0fiUI0_K7sRB|{gT!4uY~C;rZ*2OEOWDhCFBHaQn^tJt=O{F+It zGx+Hyt%%PKEB_!et%4`R%2SccwLG>ezM&^NfKglXySvfe{CBqy!JFSxmp;q_7aZtZ z522)IWU98bQ$n(i?MS4+K|FH#Ql4@5L}Z#an4scb4bWH>Ywgqgcl&2mJpa8d`gYi& z-%btTC4>$2lAc}A%NqGejg0%D8kh(-sahtcsCL_&YWwF@>zg4=+^HGGtrp}^-0&8( zoG5~H@nTGOFHW!*!Ex>~++9B07A~BQb`QBwyvE4#GItC!jJknY-zihvPiwkz1L1uC zz_49ez<9KgS?jmc&#j#K$NodZ77vQTlGZQtgY4U|`F#F=kR~-~g#XdDGCqk#z(YI+ z>7USldQVj`$f4wt6NC~2Z(_B*KO(V6`#?24+b&8^Cr%4J*7TSVh0`4O@Gfre_Optt zKfxfYDA?WC2hbB59x;hiqd!%p{VBL2x60Zu=X~3z!1`L6;Ep4vK1!;^2sejiXjc_1!19C3| zxmTAU8})($2kV-V2KlG%(%~*Mi(stpc2aNo^gYSwi&w1u@Cci|!u~QkyKLEIyKCDP zO)>7PPy7@kvc=l+26oDqR0!Q+&DX+b} zF0I3APsq|?4}wBsyrB+z!|5=}hkG72x7io_qlV5vLA^1tVOaU=QJp?T>`t z@b?WtBIkE9_@(_0#<|NFciAoi{;&L&_y_rrz~kSLUzUgbZ9pr8N#nm*_>VPrgMTL7 z&0uti|3}jJUorB(ivQ97W&H2-!(9CL&H0@S)*SEn-(5P~W#)iQ!vDSErTm=5WOVMt zE%9_np^N^_jbjSEtA3IE5zd;!+ZYnByt(VJ1gMGOF1-*690I(`>C z+Mli+1d^q+iRaT!p^YCnUlKEWk-XwD0L&;uV}cLTx?MMU{>`UoT#f07LEN@gCLVE} z-KXObhZ;{W?sGYhdj!|^>8Yr~P5Wd;6*QY2%!b_sjp7l*f0~X*Ttq46`z}^fiRgiP zk&F({F0Hxt;GC?|U!0RJeSj;yy(|5mUL>Rc^H^W%@(~T`@1QiR^z=;WRei1P$0SCH z=tNh#Zb%m777uwJtsX*tU8eN?uJn1Xbi$S1xl}tC__p^`+uGYYEWLlGbiFG*z?I&` zm2ND~isGw9oD{|DSe15{Sco3d6_G{Yp2rtXSKcR>@?O^7m72_rR2MM2)<`! zwHsBtpW2wgwR?W1cArDrFYu zys6TgIB$XpeGwscEzgcmF@JE4n?JA}Tbot}U@4Oyv5DL25Dt|S5aWpLSlb!J(ghqx zYE(={Z~V}!mBr78YJ~}K_x*luPIEe@JziO{rLpa~{D>t+uyuCypZ)q|xUQgx=Qv(P zx(TX(qZzJ~6l+P(#bs3s6w(fy3~9B6lYQDe!)IwEIBtn(_%h&*S3bUlHT^tN6-#_a z6JZX%T~I2;QYy9DX>PUph@U!zjnCW9)elx6=ppn4@zI0(WP_{s=)j`j_nb(gRRdNW zZ<4w!#^<)2so_V74#2SeS^0rlo#i&4A>QtqWXl$R#O0_GPW>c~(h-?)tdzr&suJ4q z6P&ZTQ{g$fX7>RF3Hv4+< z^fKEN*X@@e9BObAOT-LOV>NP}q^AZ2)8z)0ODebVd3>j79znD$b-rVS zi+D^e%ZaK>-b&94qg^MOqrL_Hp+OL z?UM;yHSVtiTsWn;Ejo3ybj2)(mbT~=|Fc9`^4M{x&6eu$4MD;Z&Y9(G&{&a90i8Av zG}Kf)8JVU<$u(_7)q|H+4}QVIXY3fY-L^WWMZ%*U)@vZba=T|Br%AmP_Cuj6Ch-u_ zaCaqRb+I^4Y=0#%GbDI(Yiz3%44bL5d|Y!OG9ofETSP{sMWn5+B-R6uk4q?FgP%{a z>SRN3%n0+KWVB$(!r)N6n$+&RAtv$x^E@@l5gzdh$?l}L2_9>Lp6pl3_eNc6zNC}? za0k7^e<&BsRiU!ob8%r>_*zgp0IrNlC0m ze3U^E>WI8 zw7LDc^)&0xZCt)(e}1JsY&Ww%_x9XKf3RnMzu9#nlG|_AalMm$w_Zg2ca>35HsUGW zwH*ga#|(0aGiz@dN~e}=;Fz6o6GV#%pwnaFMlVjM9*^9iRF5w-rHWsBw>-7%U{)-7 z2IucJiemljTUjC$a57r^C--f+Y+DsNosy)&u@5{zU*h84rrX7r931BL2z#Y9n(^;Zuoh^zVrQ0D%60Y(c>v_{{gXIJnvD482HC<#0B--Zro6>EKhqxQeNwvfvbi zxgynYh;@^Xs7z+7E&80^a1S>`pZ52~!E$z!uv$UpsE$VoIgcvnxL?}yWN1_Qw=uIi z8X#a^XSe;4b++MGI{3&POQ#8@9W6O;Kuz0`Lt<^0mZx^63Qn^6xU&Dd53eV;nV+4i z+S1`oiIA&&oPr}iA}w#pKgLU|r#dFR+9nmJp5YN2=6yW0edtpie;@iHr`{zvlKe$G zyD&KO>-8IK!_729p)f!IeK-HK9*6J@@M{=Aj3w9$=x9d}7Rc}q`p4(vylZCH@^PI0 zk$WPBUZpGgXN9gNZGY0IZO75|G3Amr{y1sliIX+~L$h$C=nIi!616%z;#baLooYxP zJab9^g5cSGNUF1XkJD4MiY0*Srj{ToExF_c=X&p^Z>ZW+o7Ul6s^wirfx@?*Hjr$ej5|n%e_pD=l6*2?Y3_n=@!`s3! z=U+>ejFP{Q)@!iCbUNW&1X5%MoN%I<)Dv}qV3VwiI8OAb=g?RPTNm zS;p#Fad67+LXWu$H8MOt;UFd*Hc1lFP^pKknqi~z@0rRH2tPQ%K&aB?8$hs0*z|;0 zGWy_KNH@3)UY{R&-pR5bESCBo#85?t02;wYdC7{j$jihw!awL$Tw$WIrprXdWc1wg z-GD0i%QLD^wn2OVL%>CFN4&Dn8ZpFqJh2WUIrdSX(|B%Jt!FORY)Uwi@D|l@n2hdm zoP(IgUM z(f>S+)NIdQ$t;FqQhFUKJ`f(G;|MdlaD+K3jEh8T{Zj|bi|lClF7)~CkBvS>xV%>Wk|9ZWxeW7M%&)-jB@`I8AjP*VJAkZ z?UGTdIx))O=XyrD8mb7+DyKa>ql}DKzVSs4qg08yeAH*?mpP2W^KhxH-%ZFmkc_U0 zr5WX(Ei#PqDb+egDZHv1MtNdMHls+Hnh=xO>ZMa8B!UM(}m zXsdsZG{b1cCWq~@hqvYxm|#ee`>-K6t=z)Fzx@&}oSdtSI_slPH(eh+`9ov21-g8L zGC(jKk9Dh$c6HoT;)gD_j+I%zo($;WuR5of7<;z3^WmcZKHl+_F=SixBmdLTM^h+! zv9oP#Uhmi$-3B`ce=Sl=BCy#(o32krclf(!y2{5gOn2duG}HAFZ(6<1?thbZT70%= zx+oM@!A{!gg3oi9F0GyB@qAOXQ_In5rmN_kVYnVf637P;zgZkU%QD4 z=V?1X2urs+h<2xT9} zT#!xs|GvUGM$D8t&=k%dpTSdi=PR5%{?e!x`v-0b!-dw)q}Uq`=l{sKop7u%&xyLg zJd%9kA&yz<45 z#h91yWRP$M&+1QGpM6$^j7cz220I7;-t`QfjOK;lKN)>@SQGY6E|CsAO-O*0Gtu9V-{zIowT`e%+KHU^s=x3A2!g`T8X?MT+pcAAC= zbI!3vP+XA`IIC8F@U#?(=1*~Of%XuCJxWv_Qpm%?!*@Ph-U$~1Cz$&&80ef|9GUua zXU~n3DGY=R&-udj>47K$$b)wovPA0iWJ z`BE52Mwh+l8TQMEG7S423wW82A6n6>G{erdf{tNJIx%egG|#ZFnk%TG8VoxqWLPGg zcmGffdsfJ>B?63(`b^-t)1;YcXBb@(8S5DHe?LgG=bEoF>{&@cRZ#1J_akW0;NAUvd-`yi9{47%EO6nl2-=TqA^OioIC?N9jGpiB zM_JWyL~Q7bi3NLYpq9SN60bGAOE9PaN2b2dfPzBOZl2MTs_+R4!aXSppGe!b?dpjN zItqjSg^sW`IxOynuwO3ogx&SQ3}KJ`V_Fk^Tf*LMhX-LIzczQP3&O@ax+d%mJkKX= zs5-^5$>^BMG+|5DWe9sN1s!28ZRv)vL+5oStRs#i?2lQnp4vYotRK_o>6^EgY%%NEqW;xmbEgjttg3 z?@2ZO{tT&ZzoQeWQ0v}kWXs^7PBQq_DP9Io1UqUNbz~C@Zk$~nue>3ZLn_46KI-!+ z&$CEn&rQG8y3Qt}?T4pH)vzW*sz)j4di?z5-H>YPpF5Mv;o0gAZuRr^-eJXzsI~DsSGGp~`Qz-im&jW<+)o zOdED~L6y#$@q9Zy2myKwL^yWH(~MgNIaD!rDM2%i=6M!X?0K#L?R!|7DsO+8p~{{V zbX2Ke`wH=QaYvqJT!o*KuNkuis3-+h*fw<|@vz@J`qZg@KVLQ}42d}rq7%_$svL&QO#dCj~r}3J5LK;&e;96L!4oN0_8?XHN`w%A5nlPuqgb7BfgL`nr z;*}%yHZz|rirvp6M=?G+NrG?l$x6PY)qxdhY7PA&L#@jw+crW^0th6oImnc|E9^_IB*avrKJh6nwkf>;EiWe zm;9&;QC=IbeDj}1kjsrAB9oXxHuV?r%K3UHa`aL^%VWvyx4T8zP8RplWJ_haN58Pg z@3Ncw7~ZQ4`SS2$`coXV^jz!JCt#0ty-MIeQdME_F#b}<4dkXJ(Z9@+ht#;y`%yzI zdmvawF1&5_;%!eSd`=jLuR8=Vj{d-dWjaNAO5Fk!IdAx`U_xQw8=Hko#v3#kQBNw}V5U0sqi4NV<+0dro4T(ybbKBhCa4z7x&_9s)74x*R(d+Zt0Z?QIDWR_unkp&RxfF{onJf54;(;VI7|6EUMRTet( z`O6N$=aKb7uLMPotB@LKJ%Z*YC_`8Y<&Cq_O4q!vs$Pk#f*K6G<6cd&J#^R>Z z8m3wPC{UBprbpEK8qOm2PJMCI^vWa^LQL9@Qj;Q}Hk{%&qwo$d|CHn!?$7@YkL{C#zW z4)=b?lZM~!Mr0q=h!^oYMwoZ$9ryB(7nz2; z@@;9%F(Dt82(S|P@Si+)eCSny!<~S)Z^k-?^XRy3XqvpIf1Kf)8>vJU76lJY@_f_r zr(CAF2nVa9Rim>*;2c#Cg*8ssUYiVkEb7~0okZZe$k7OXHb9!dhh+u#2?kEXS+doq;q5B}ge2nFql5Yy`_$3b>T zVlw*Glb(b2Ojn&Od;XR*2Zf#!h*Bz~H@3u*roL%P=>|dQ{hKOo;01!A@yZMIy5T~e zfKM~0edhDXvB;h|h;=yko#op}&Uz-J@$Wj=K<~jHX1L^+)Z@71$_XK=@4>KU&Cng~ zU9>?Rm%9;<^qeMn%fc77Ze550We$s=)7w$HDIOd~lDGdt+|t&kDANHwhw*IZ2a9a# zeo~rb-l=)w)HJWm{3OFGOWz1P@LWT>1Hp@L!X*5kR!w>Kmi&U*E?@WJUI5m#a)nTj zRu8y_sc5r&Zrv? z*TIw!2JNoF6F=bT;D_fa=4SfP_lqATYRfvu54bJtp*#FpX3#1nlGkn(`E&1Z^!@SR zRE=bW$*jwagUN@9B)5>3<*j!B-q+8zBGPaRWi>~t%xtUjE|>C}PE7EqatsyDD$1ou zM%VpXxKtNpxEvN|md33b%Zj?ohr1bt2fx3Q{#qY~nKnY=NyUtqPe2BAP_dCxM;1fLb~1^E>ofW`+ZzHw1_L9of8uyL|ui8g}Oc2unOX;+!dFC;K<34ddDb%!H zz!r$L22q+krMI=BFjPoqeOB+R`I(Lzg7|Adz484y<~aC)L;-8Dgqx(vR%X5nlfy3j zJgW<1OA6tV=KcHiE3*w^_e}BR@W+Hh!KaM+7r*IW5U(8nqD&U+`J+car}LK=7BTcIJ52Xx zp5!3ibu;6ae+KWp1g0JUQ@Qn>BKlC@`95dC5eFI=HHAk!ZD+2`kf;q>!#6I+pk`jgf^AuRP9yda8XfY>0z(xPC<* zzVL`x(|el#i#+^c;=*E{oXV4T3s$k^Skt95S$a%j=WQ1jH$BVG zp4o*M{-3W%XMg{;sv!GqVcy$#&RbBIQ?|(7`jrOOe#8IzYD;=kZAU^6s~WZmA&K+Q z_At`(+DNMwNQLiIz>>xFZuZ1|bcsh=j^Y!05^2@K$?)q!eZ7x=*Pdyihn`3L^A+_s zrFwDCekTv1(rc2#hPXhh9Nt4_Yn0>5dC4Ookzs-| zTUcdJEgUWJ0=pw52lg{%eL%w>JMIWZM@*?wAAG&8=M)w{`CGE}NlBeBMB5m|*9{%F zi!Ih)+hf9xwhs&He(1O@7x($jv)i#vrDZ)7SzSS2ce(#LP^WCR5OsFV;4h&Rda+1irvI|9{rs;1kHtG*|e?h{lEFy3%o;KRQ95b!%* z4)(HF^m7hOQZn&^SW?U<dVkvCZjMBKifh&uH>KmLnD~aLQ zJ2%|N1!n7;aIqAtIBp4|)^2cHf3x~O`YSAUCvuu$F}Sx-Nf!liMHVrvc@tjg_gCsY zJ0*7cUJ6~F)Pirle}TlOu7Tj& zMP%x(m>~2SnNG z@%jzH_6t#c$>?)iWv%Kjf-1ql$K)nBf2C*-=ercgD}$xx4YVq{m56TGofqUUZIe~n zwhMe~UZ(V?`iPn+eWxp3=1Tv=m45MaP3L=k%s$=h|BzL>B~$t$SNdi1M55ze=?6QN zJ}0a6`I*uOxYC!o(kJT$+NhkL>cYim_~91&W3skK1X1+)HVPSWB!!SH3@=frAb9i~ z86y*cXw)}^!?b9Lp=hntNFv%lY)JZo8hd9NIyI}I%8fNNGOMA5B@UZ3G}<*Z(KYmd zUL>QXXJ*l2pujxgFBw|=k1q`^c6Ft9bERADMRZpf#c08LjX6%+6$(v7T1*~H`iHBD z(km8QCzq&GiRe#u6;RP@wvtBm2MbM$-P|3Q!*ug+qq;x zrevL!(TEN1dDZuXw&EX=}+n(8=dl6n@q6$E?M>{Uu4|qw*SSAevZfY=RB_G zaq3e18{S-%^X4?Y+1tH2f4A(as`TbLxjD(QBXZvCtv3_gn{9L6^w%3QdsSw+I-U0K zKm8xx$d}>G?{nTP*PCMZ=E0mdkLyi4?ha)x&3SW+-Y~(uA^7`Zl>h~by{NT(xwVNh%&--RiZM%s|w1KJ|z`gFy+IADqgvsS_x6Smn zo3{r)5-37)xB6@wv0?K{h7sunvz8p$b|9>w6h30(!E{y)iaVq>ffL*5Jv?Ir>Zh`+nM{VtG$BkHr>3I)R zyMZR=w|a63c3cGBbV^X(_%i$aGNTzXCmKdtX8KMIaT-jbD;Fbpa~nS);)(1F)RSn? zTi8+zmp_HUxpT584>yD#?ynDvGas5(u&OV&s-+oGkA%Y5csOK%^j^2u`X{Mcb*pM2 z-O4+^EQdcMQ*Ty3Hg7-HvqcQZ;@F`o%?@=K1ulS1P$T?T5Y#Zbx0`_L4Tkm`X7CNpLwFT&klv_>4@Qwo&-=V2*VG^T4iP-m)PZ zW=+WkC-u$1yi1;QSOqo6-)Wi;oTELQAyNJlc&|waj9eUFWK+eWFz5_%e9Udx@XDhI zZYj)%*E!5`W<9(ww0|?aP2UE;!Sv4X&b!%xmILpS3EA)}X(IT1%N%&U1MeZ-N02Ik zt`q%j%h*mfE7Eeg;D%#Oo(hB8ZqCwPC5BV8Z71j3t;@Rk&}(*|z%ZQpF*ZVI*A zI6x21d4f(<=CMaUKi|;V-Zkq{Cwq6kJ*I#3*xugEAk zc000~(&kmuW*9dN+)<`LynTJ$9*^hoak6`%fmO63u^qNg%YFD$=wYaL%F2K!4wjIQ z5o*+~3~UJoc96)GF|a&3k^Od;Hf*wiz5lNN%)ssnX)v%#-paSVzs1z@N)B9b{bP{v zXzrYZ=gIfmLQ@y~_?KLM+~E&h@?)gM>9bs4DmA;ykL!(jvw5<;n-7h7&A1^BGUn5a z%e|TC#yd+h@5RDP@4e_iL8^lL;M#d$pf`72=;Of}M&Tk!8B zvNkg8bbT)Ww%X55{Cj~t&f;GuFq_7|Tjn&_rNE4bVUIH&&Jmasd3+Rn{4G7w|9K<3 zhn+oA?DhEaT!G=yi5Tv0AuvsM{9hB8tDV5qbIF&bE!`^?6l@57^k+DU|Gg}A;-}90 z+iz)dq)vc z&iVG}6W3p=&K*x^>O;@aD)^Ye(X+Bt6iNoST_Z@J7@Gamo^}DxpxLs!MSoN!Mfn0nq94qtuDRdBe9H`at?{_aQD^@8tt>e; z$r=$b>UzoGQ?)aZ9)0}Ba{S46KDpJ2J{5+imqG;Y+pS6wK{Fyhk0sfGkzq1i3IRx9 z5&qfCO+guU(-cgjjDZ>A4hpVB+bW>0xi_>uZ`@{yvE~)1Z><9YfEu_h9eLfPgqW3;4KDAvEY>#47Bh9!?*WydDHBXsIo7=xL-@VE{1#sh z9nch>PtS1V)JHI;*g_EXyT@41^6hKO%+D|*v+?q-dw+HPb1@W60_D;3V2PaVH>6ZP zq9dt>li>4Hs-~$!L#gsB83sw^@qj*6QvQ&6q+>m1V0Jrg_JqYt|J_ z+(t@${=0;aBhId9Z|H5)(vPsqO6pyw$({Z|u!9D- z9+Ub>%T^fJ7&OB__%ByE|K)xWuW6+$OARTOtL-|&Wj(`6%H$4N=}0o&7$Md22(WYC z?ajNPA68d4_xdc0KUzvHf&TDeMUkoG zWs61Jc5yRF8Wfsmlve3Vr$%xOS!A~towmt-){kd-Kt)>5R$=lxDKC15<==jR^5Tpc z-?vtPyyAmMa;SYRb%d~2#ZX5h#VN)S(nw*32RlAnDwE%phHa{wKNcy%bL6C)x=}D0 zHMC2phTIS)M{()AJZJjHitOgx1`UV#h2i1p@=mX$9k}F!j;B4Yg0qkn=qr3K5Cb9} zeO{Xru74WfghdOzgN{F<9_IE=>!2}>869*xC7cerb(s89^CKCbc03V$o)WKgOoj4z zL;K?fD({S~OH7p*hq_V7Tfs|YWX1r{eun@)u7@7L;3s#$X{?OI_GR(M@X~gtKWwbn zw6a}jX56#PuKwh7m}IGbQ|}6{A(7XT=a&EMeV*kpNdsJ~K}MK69x$^_U5z;Q$$Dh8 z7$_x<3>|EbVb@5|gU8cnl@1ZhG%akWU6?$?L%Oa{)(RQvy8dcB+NrLGc$`;Pa11A0 z`0=(J7#W1NqlSEw7wJ74lnXv1RB{`|8sBuJLa(BW`nvWaH>tL4dTGAA5#O&|DuRTY zY!$I>y}ZDpgtJV8lNOx=z?* zI@hS~lhFx9Art!7vbPyN+)Tt2_G?M3OB8%6~JxZGZT)g zMHtd(-(iEgXFYvpLZ+u%rhD2atEbJYcSr-{c>opdXR9}r2kyG5TVN7jr-Au?7BH7m z!tubQ!!u}aUcF-iq$9(6Bli3mP$qi7<<^{821I1V2jro8sUoB67k{N$CFx zKZiXN;>Sh+zEi=T?s3yXb$LOsbT;_ubbdhwKUz|We$K~_+79_+!jkUs^VH>?@w1P^ z&qw_>ik~aXyTi}PUw$)wf_4UjX>6E(v+vWwM`W(odRbniIurD>*LWw>h1L)~ciaei z{^=tXIs7x-@y`biKPETukKqYai)tZ$P9f8+EBP`0nb%oQ@8|II+*TR<#P!ISARV6m z#i8Bd=io20@namVqQQFOl6lU}2PH+pj!3ppA{hlA=Kp)(gLQCy>{jq$+k7=GR1X&f z*Zv-SeBKEkww~e;A+A~ZdJODjk3;+7_&-;DI4|U9hdA|7CHoUoYAQ1Ia^JAy%D>O; z^)CN~kkM!H9$DgL4~#Yu^;q!I3wB z*1J7g(+WGoZ-(E`g&y1A$(BB=GWv#j$;IsU=HCrDxC_kws<3;^?k1?vAq1xwqDccQ zw!{E9c+Z8G(>5&|Roi(~SxiAguV&jc-y!Lw>$^mf0zpH+Oe5+2pJ$M?2PGVmN)E~( zsdN_D`8Xdt+4_8A{_Zx0kE(+lKAb5tkIU7Fjk3X|T_wfDV!0zBXID{{j1>cJ6HWxl8sU-(y!)I%4h}&%h zzURN!9elrIu*h^pF8-?iL-=N2mJMHtqi>7XD^m`wjSuOx+Cq z_rXvHwbOszL4Ub-2I?wFLzZ{`%c0$2^#=}W3o_TD|4_qY#{S>afB)O1Xq*1~EG^po z#$-hM7)m(N9x;SIg!*r}(|^~1-EY!=uR8sQaz~##t&M`W$*DCx*kUai{o^qjBx&Lb zb5g5(Q}hvgLh1Nky?^H9?%wyZ_c!Ofw@ET9k2(y_I$C}``cR;g(U_i7xhLi-byTvf z5Y%S5bZ4>51tiqW+KqlY71J}L6zDKLT5Avn!~Pcp^v@m6XZfq9|7{W>)c-oZpjHu= zx-bm%8Odom58mN{n~T_1mYMj0%|-Ol4`Y)m*aU1U_$NK4$RB|Fxri#8i+Dje%nkQh z{5da*7tZuyJT&DXQ=2>AkO}lz|9#kWkF=q6PQ43C>twt89PLJ$!7ahy7XB`W;Y$2~ zQTu(pw<^tW*VSbh?vrvt6l3MK!)fVBIAU=z@Qe4{xeUlrwT^jZ9mkZBfIL5#h_st?Ny}!v~B2~ z%aL8qiFFZxwsBB*d?{{_+UEbr&@Vn`oJ_^mDZ*+Y7*jSrw zErJj^&5JMX-Fxj)R0G1uUWgjYEf&iq2X0|2l}nhw0)?R*ZW$Z z_lUI4@a3j8a#NjnA(mK@y=6vZn&sZ2V zMze|pBs)Am!~4cQskzYHH(BvaWSSUNB93aXRg0PJJ0jEU_`A-qnDb!A;4o^cu2>ss zEmEB}_sA?rjb=fl6{_^7$Q_qP3R7|LH+FZ)W15V5AUs1IX8nlqaf7AQ==8?(^js;9 zXlm?;@}77*$jH(fs1yytc7Afol=sui%zaqkE;a5l!d>ohm)q@dy#Q$3rr_sP+NHGn|P? z>0~wX+w^>-w!^{}k3w6fswIobXz;JJy}045jJO>eX~SYtiJxAX;!~~bcWSGnjW(H z%H6|(KQzXzkx!PT0TZA3F)wSAWnzH3vhcv7QdcEHHB_*HV+#dl(xe`PCl>s6OTb6gbsCn;Hr4;rp@Ni%&`YQIlNj{B^9q+Qv#r|K7PJ+8>oV z#e=F!_ano5YA{-Z`Bl^quRLX%rRcV)P=bh;<12%O{j*l)Z}%C-lr?HD)>pxkZz!i< zh68wwpW0?Q{?WpQD}GDMB7fYjEv`pw;55tgoa>{+&B^R6gH?4|i4a~$>||<&drx_j zIlf!&`>5agr)*x~O`{zPNb{|$i@iyCF6BY*{TCrG1qPo_fs!5ltEyt_G9Xx?Tf^-c zY-A8?JG7@K=|r|u0TkJIrJvwqf4hq9TW$VKrG-Yf?L}(Dh>x){;JWb z4saDZuM(8$cAs<$A-*cq!{e$lJ`3<0jR-a19N8@cyl_ues?j42^Zu-&X(z@Rjw1Ws zD}0z*>Pr8@%wT*J!Y}ERwfpTynA_p)g&FA-Mqd>W!dctAQsYvZblk}%oQ6vhjJVc7 zzvcFOM(GOs-L6M-?9sf^c3pd{7RBzHF$M_xo;S%I2;uks!z!(lc7><%O z=V0ae_qxJ#_t-fLaE8)MM)bw&lDmA-Hz7{UD;*_KNg&trEC*TFI(ziBZY8Cm7O3gb zu1BUb2Cq&_f6XN!;m82Dl1RT243T~^3Z3-dzLk@HC*!`U9O-xZz)Qcip^S3Xm)svv zob)@vMfz(n-+tLcQE;rd8=kXLbiG!kFp}07D?ugwH`=p#9>V9;5!drI!n~EBy*h*6 z3HoP|X@l+O-($IQ?o@G!h8O+HF8SqyP3X80>}0{Z2CdlcS@b9 zGJw6mg$^2-1=>p!k5JPwdxR0yhTbI_=qK+gb?upgyhsjv*~-1P1W@+ac=tza0CX1H z{_yb7aUxnb3TbWMjVL77Xb6vkGc`f_Az3!;7oBT07Lb~|#cFMonp2no;-lu4#Wt`* z>>3m3pyv}(YN;de$rZ0WnvI(@V-T4;D!tZ2gYSbi>a|s+GfPhny@vYZ!u3R))1L7b3Jk?9ZnTL?DDl4s*>#3nJ4Vf` zsX2ASmj-yp^s0~_+A)%=XmIG9$QrLW^Y}3rJm8Q zRfk{3Xyp{{TtGHwyizVi+j!*^@lDf8kwfzi#vZVVaWZD1j_09Sc>U(|_+=T7%`9ZU z|4ZimG+yHnYZbxoxYKF_<+=N;aAe91TSe-!OXUb$!zVVk)Y4A9)orH|z8^;TUUT9Y zUsVO0-e*@rQ}}vz>$Rn#R85r2IC$YI7q_keb0u(kc$e3=+&C4pWnkK(2=$-oAHSb? zvg{+~2eHKxe<$B#p!|u#R{o27;V>AiyH)R|Gb9n9 zO$%Lf;c^JKr$Yk``qc^ zi_w*O`YH%ugBdO-=QkfAZdkuaD>w#|Y50R$@i9nC$!d3U2IVvuDS#5=^|U8`gAq+`T~k z3FpBA zp?kB=*>sP+!8YOX1@`eH_;@^TuKhjwGJ=#h55J}H+M&2R^#cP+3o+6gubAz#3jTmwYAMEvYR&Vd68Cvy}Fw1vQvb9krZn?U?}eu<%-v&w=cTWT-mL`o%%M38?fK=ozs84kws z)~unVkS0((JS9eeDu{2nYV;G)vyj4P4^u`P>kYNlh<1JX(K^IbcD5!^_QEUpqT)ew}Wl+%;Pmr1)@Ox(R?sA zz5oZW-5V0(=gO;CpbPwt!eA({aNq$4b;~N74#RHL)0ghYZmbf_*zB#So6WP!h8fzX z%6L@um;Q!=pWs(Cm;)_|R?{#=tBdJ4DCXhPJ_Mz<78lE$PJsx>JyiH{@VgE_j$Yjo zKUTdh{OBMLfuMJcr+&7m09b;K`7|3SY#d5*0p7#}STXH$7CnAy(wz?)wuxD5X2M;du&4~$dQ3n3Uvlp=bH#bGiLt(h1rCMtzk z4l-Qw^VPcs78YLo2C{(dFz^4xkc~3=2pRf$@&<@(p88F)V_G$xh-_qF=L0TUbYx_OS`WYTYjvq79tkSSI8B)qkf99xnpkXdpJUsf+ zke681grNkp#b@Cf>jvs{Ez^~JL~5B%F{M8kE0iO2ELjtXoQ9hiAmqw4_J3GoP^HHi zCp+T|?Okn7)s{ZZ)Z-6C;gK%hHYj{f2^7#Oj|~HBFqVMBg)19OyzDgh)wpw7cCh5_ zKm&JiDu=_KA)khuO81ZRD;x$^2rJKLk=FB|!L8 z2RudrRt56GN+2#)Dvu3^2SjP0!&8UhhIhHbJJxl1cz06@@8+3k$MQpXSxlldkwWQt zid|LD#B%kMv0VM)e2yLG3pMR5vG5eeW2Q5*vOLw>BT(T|c?!;fr!{GK3T~Ht>+&>= z&a}66Ifr-68VR%kp1R!5RlnSzD_gKVL^%{0JVhrA((qI4PT~KCr$X_@8(PEDGaeD1 zR>%i=dJ*1I-;9R^`PFXpYz#<}y}W?R5#f3bsqd1C!Ix|O+Y@`oZ^76xHhU7N&*RHZ zZHQDO*|D)K8H!J2fh6iZjKMpTqRD$Q;aJ^{VE_L$MKYr;#GiUsG>RA_k`Q9`>baMZx&oJq7MzLsz` zH?$FdcMW}pzr6#~jz9%8zG1!X{X57vthfDytwm7}J$M-+N;o#Ci+l0|)Wv9S%+BQ^ z?Cl_rnkjzm!!RJ`G+)Dw(i}*P=jX_GY0-`5(V{6cfCI=?FIAd-3o$e}GAlHk?`bc9 zem1@8fJFc61!0Zc68FhlB})S{&7js$#!w@x`O6_q&G!q|4U#zq|5f`JY{QW)?E?*W z5>Ri)`z*Ehw@Zu7(o`B+)Se)shCzs?1EN6=D5nciB+u!k!;&*R`!}Yt(u?|WOB~>s zWB0;+fZQ@vLFwqyK*K%BxE=4{zFpjQ&xqSlja%z@{Q2nyHzeOEp;mZZ7CGNOv)}A9 zU|g?2!%!Hf;nA0&8)boomz0$iV}mrw-^PxHVL{C_Vvz=IvxdX`T~aO8aKE819hYzu z2G&=fggP&HU+nl;Ub61$6Ut+qb%InP&Dd4JVC)LER~an%IuQ9ML5=Ue0)yi6l2z$+ zPwHdP(&UBgCNyz)>864K6-NLrny7vtYTn zdO+enRHJz!K%W6g^Y$)*X5b+n(efUL9#olGazj*RrcowlTyGfVH64Na6iFZZe5=7aP##SK7BX&a z0BOsqt(Wv6O$n?(K>wFdftiqTb$|G(bbtNT68$R-yuOH>#v`6>|qp1ug7 zSrHqk()p)9b5s*MwM@6m1udwH#UY!o2O`JvmMtWCS9dBot9|6133%sJz@m4+StO$K zotvlI%Ft6n(vo)qkp#Q8ZLM>5)eO|%FU0Pv2V(X2@-Zh|nJMr}xM2y-t+fX1=W5_y8)Ie?=n zxpkM^GO-vTzgk`w7OM&^j?4K{>)PNW6Mhe+ejcBSd0<;+|e4HGTRj5GBp zIZ*#5DTZQWgQeJRgI2DF{bhN=#}91rC20LaZh06ol@}1jwvr()U6&CpR(avzg;;ey zn2`phZSW*U<{P^~-;+&xvbkm8c`}rapM&t3?*3UY<-C6wKGWR~qaWTs8=q?H9B~=# zrIbZ|Wq-|N!tkalgtSLuQqvpKy5oyDs`aSVc?i4MTVAO5MuVZ zfD}|~BLYIhi8lx0M~jXyzb!Um1S4RxlP@yOGzROXIb%lAtdifTJv5&W;***F71ZCj zhFa#g%7XncVgDfxJj7v#AM!xHHCw0>(EbJ5XSKt9$sjE*n8Vgewge)}X{F)^e-w-j zLcXGKcnpf)tzdX8h)=2$;zgY@$IPN$qV?hwikxnOGmM&`GDzjjq ziu^};$;-8%JdK!Sl~cgJ``UD13$Os&TCq@X=9)c#HF85qta!O*44s{jo1AOl=5;K7 zAv^Rgs)1> z)QE!~Kz%#)ZDbw4t=Njp<9Cz5rDY$%E0trZ+Hxl~E*b3msU~2~wAuJVjvBCs_ggs} zSzkil4FdNSfu$63{p5N!54qC7+j8`J(=7r`TjMlO3vjzcu-_6+-duAkvf-y5YtqF? zeykKgrLaeQjTtu4-B3{S)r%Xph`fm+AR|&piWE`5R|^oxLZivDCy^wLG6!sE0l^iT zwA(s73XYm)u{XoCNBJ6*ahe!%tV`;*ZaB85Hn2D-zstA)G7mr~_)rBiSqc{AGe7_! zc3Wrwq;9~nV^<%{OsxkRfnREdCKa*@54SY#mYH^TPZz@_xFksppDo#!WAw)n^1-SP z+Q?_`;5}5jB)&l+Mm;J&ar0sRsu&Feiunq!0rlC>IWW=Mey-H@>FX&5sPjSR>4k*_ORl1p#PyR(z=s{JW z{#EeDUzvkJ0(l8T9jk^BV5l&MOtj@R?$qs-lXNy-_d0+NK@^4b;2|W+Y|0F-=Bx3A zoV6VTMp|^NWQi7Gz4!7K@hSf{6Fxf$KJ;{4)=LMY_oj6GL_BZs0#217t8n@VPTHZ& zT!5Xe%`JXskq-b&>}x!4&*u#+vAk~bDoGnRk3%GL)U*EvIKTj*1=q=Ll(O?9P;w5@ z<(U;YTqSmFKIObdnx3gE-9ewQ{DzN{&&5*WLuPyxss_Uw9ygE<5J>0g*C8o&d>r;d zUWYA|*8zF8G@}dWY4KQyNeX1kXQM6{1Sh0cc*?T%c$}3FdA6TrCrQ~scl-OZ)=_Bd zvkrwe{@a;0^-}1LfB7i11g9AVV`(WgOHjb@PCl_tS3Y5^!1){CvP{)=S)MPc`Z{2?>#=9bJ(F@o#sh*eT`nyR{`5X} z`P(_T?N#{WFM@mF#AZY`VksY#Ct%*8xH1+2hIVBWa((JtVI}XOt95*s8-bhGZC|FN z2=gQ_cwuTBPbUxhvKt&5HojoIXsXC7!2;1bnbts9kz+jVQe_K6(Ab13P^B7F0fhe_ zQe}?Nic~oi_2|(!m3lm}xbBn#;QzO#zuXr*#6HFf}XslI0vb0cu8I zAZoObT*m)7c=E@$j8VGNc``n5FHTeQF%u#Jc8Wl_w5#rHqM(m9fTo0Xg65gHit~Rf zgb;^l3c-=tWsKYLnX$ZBU!GQhfRL}o^6JgcCjIkj^K+&CInn%Ft$$u-ey)?BHU((g zf_oP7Aka4VwR1yEXMSso1#I{mXp6JMr?eN(t9a6JR;BaOIjdmY^abCZt3IZ0kLUgJ zuyMuz3hJOi^vF6A(9ZTMHTlN1qO1pDEGL%1HT6?IigKi$r+tDkp#MyYcX5{lZUS=> zmoY?)54=-49f0@YSk#kzzZtQqzglPxFC!VjYN7KuMuDuz2vSYuol;(MRql;ZUX_FG zcGL(linp>3IG-+CWHL&Fuoi)uS?bh1wHiU^WXRc)8a*@u(t~N)XxGFdNfcVRzT6XV z-H%H^Bwy19QNDTym#s-l%wi~g+6)G#frZt5$VZ|0lvl%mqilM0pF}Ml0nWc+w`P2N zES2TjAfi@cT)S9*7{5?%a0U&dg&5(cf2F@VU!)rM^{j2Dr1GQT*DU}A5sT?z<9|q1*kT|o*O?* zxAqynL<(&sFE*{hTEm+s8KI(FsQe?h{>(bkoGB(yxX{p= zs~tE@uLwprlGbHHYhV-Qp$n4>g5lB!P8321qjlMd{zB+7AvAAe|GnKQ@pzCE^<~n& z9Ki>O=BezHK+nfPYb4@add7#^`Q)1!Vz~3k483H~=!BEl0L7U~b|;S`TXqgiJ5M6a zEtvl;q(_cy>B;KUHJI6soryWLrPlyYJ4mM1N}4NJj*S9`BcUC5>_fUh@fH|X(>T%K zR3n{SCPQ~sE>WFaViFvQ9o_D=4_c7W=T5cXvYC|toWYT8amg3$qhBCN5E(|Pfkos4 z(CDFA;INgP{b^Dmm+8c(E?Ioe&nP~}q>2whirohfkFIniXecEpy2L9)a&E19GA2Sa zUp~OHzd?v5Ag`zma2g?+__h`zz?~{YI2}%esKO^iI!_laJ$tw-M|-8n(Ve?ej!aGu zq9lq|m)J~2&1!zYL&Rg-d5GAbR&}~4c{)1&FV*naBsENY54WUhuNMklDj!A-hak$# zNWp{OA_XnbsYE=pMI!bMxfaueF*58uYfZ;I`vj7VMG2 zg17pl$g!UEm16_|-F+TW9_AHgc=-B)a3)a>Oq1Q7BuaL?3Qpb=_N4bL*hrRllf6qI zBD;%tJ}Tqisuvx4`Nb*JxI2 zpxesohljeXPSv)JJEvhaJ94y5odKv((^w%NSWkB{%o$8#7G9YVFXe-E@x!rax z5+m@|IMBiqq0?I*mJVcgl)z#$8d@5NodfmzBOp!m<{2W9Eqx~S#ot{5^*fp0fqE<% z-j?`*(Q0H%ZlL~W{SC9}|3*`cJ8FU$IiqX@>5L%VDSWX^Vxh|RIX(=}S0#_2fvnJ9 z{j=jH_s&^zlN`WGQpA1p**NM(d#Sq5m9pH5NfKI;nyuPw@0n z^-Mi^gH=mY0K~3=`hx&iA|HR$$wLvgl;Z{O{2{^3=0S=K7I3ha8_!65D1j!|55yTn z#r~2dIi$#z?Anv~CUR1veQB~L6o?(fI~68*CY0ETR}e}eASb<~{9dl0PxCXLce5Oy zFa|Lk$29#&m3Ut1V@3<&ydm+79jB|0-{<%bBS9G+b;C5ri4yH(tAG4mWG4VqgDrn)$B-YFF z3+(Z!BR|qY)?YkXqKA5V&r})e#q&;i)J3&23DqCp%Y^FUzY$eRUJ*AF#Yvnrjubx} zYbZ2Beqx$z6Ttk0y~Gy~5t>VQmC5qey{P#zdL&M4q$XT?bs1If)L;~e7`(2pLl!Vk z9xkntn|lYNn2Qv$xWz>kK});{iZ+8$MyunYtk+}BVDlOX=wb{qO~}nb_!YcTcn_=)$XhP!ljSf_m0h$8f}07 z-{#=GUG;lwRl(7ao!4PKJhH>DN%C`yPNM(yO%iB4sXF#clCSbxKfU0_hCd6ed! zBI}Y`g8(D77R1NMY>5A(y}hZm9(YcT3+M@&Vv<*fh_dj(royn@nvC0`0}9kvjkFFj z_sh~OH`j1sYX8WThg~>&2pn91CvY741(TZ;C+a4GD=~-Fw26Sjq@T+G@W4&_!5|;3 z;BLU`7XvV4+6B1EBOKThZQ)U%_B|X?`RF@w0(284$?O{a5KrI$mCaHGQJtFugb?tF z2aza{BFSdzeT6U3q$?&QWh5Q!P7&k~tJ$Z?;}}r$og9vk1dB3xLiHmsA!9at@C2sH z9$@d{zD2(*`m3J4Ra*civqb)7XCpM$yh`J9=AVEM zOAgb>uPpe8@ccy%+Aw4eG=zyqEj_xyqsqaf8jz3s#6bQ=2W>3`@*v@>wvbnaOOHR2 zki#%QWXf{TB(3?#o4tUyO9K3Iti2)}!RA*uu8n+JMZF2s&m%yeK^22B8hP3*SCYHQ z3Aa|0#FT=a5HFe897>qD%sHO-o!RzVi!f(FRem=|m82|A^oSlQp11r#*BHZ)+4hNt zx|o}rr1d+4X9_DKIDAokij5T#TutCNAW8DHv-UqJ^#6frxwQ0eUT^4sO8b`RzvA#T z^nZPZm;O_3@e9s3T$GlH{uc;9sq}9gnUb|kPyY!;-Zf!D|2f#EL~8~JT)}T;BsJ+j z>>ruwpIDoT{*T?PFJgMkK-pSeg$rjwsnMzj+C@9xqjTg%U`6omD%$A&RYe)t<6 z$P9nKjPQSTlPf>>9S-?jc2@o7; z%#x!dKKv#Q1a3JL3;+hB3QL|1hnuA?#Hfjv^SOK5bf#A$%W{^g%g|)=vrb!S?48o| zGW#jOIGDH&4qPZ_I>CbTEY;3*0{sVqkKfELU7sQG6K$@nLUMMaq@_T3EUR9_eZAz~ zmtDht&dp5jz?w|teoJ!D1QPKwVxm1wFkOwINH*<0EC_4mm{yKp`+dYdAF8TiP?+0U zcqrndZ(wR$=kNLT2=rQ`f%=FmydM0`-zd|qtA4UA3 z2Qn~IYA}(|3GH%@$EczhjA}6LntiiPLIkHY9G1#|+ z@9BNCmDc!*mv0TeM+vw6C0n|Pyr`Ghkb{J&BV5lOL1P5Qc83qqaX(A#&HYc(hEYng&cVoU zodXSD?wk&rc;3*RwM1Z4gHV?eq1KGT#!Fn@JAF*S8Kl5E!V!gtO`Ao5Gv$sz3gm#c zgeMoA0XklSKq(l-s9*?2OPsL7LQ_x?)MI1WSSySTs8QcBG8Iv?bHc2r)UeL^K1D%TURM@z{Y_^!y`o99ZD=2 zni2{+Y9v{v*;>ybI~-8#aBE6H`1&@cWsTA-VxRa?M)jat;GIinw@Br{OPToimZXMJ zdX{T9j%k8l=Nh?{fp{Mw`~uAY&Isz%e0fPzAaV_o3&C;kV?{s8*)ghT1aJ1$!50vh zHBr+>Yfy6us?NO=NBo#CNVuv*{%UUq)liq27yu!f3|`G9fSdsrf;XB?^B6S&s0z6# zBW~=(CqKAMWu9J~fLiu#Yg6?Qo4ZC;{VoNZpZBMa?t(>c*<2p^lp4`7Cj zi2RssI@YfRU}PJl^maZGKcw-;uBf#*6Ls@4Hob~h zxwR%9m9vlVeZKvUGCcq>M_@;VD7h3_iXITLVQz}{Ib6EuK$xFELm#%oBpPaf6rJG$sb{07u4kz7H%G#7HF2k>JuE=BlF2 zT6~4`R(zqCj`%+Iw-&{>;>AqjyGw%}n9&@p+qribnyrZ2G=i!45ifnEZwP;LW$f|98!vy4ih^ylfhE3)3X>5I<{&+lF4lU}p zikM6Ab84vCdJF2H=Hj$F!Czr;1@M(Lnex*v{35W}%gOzC@6qEapym8ilGPGHQ_m~n%U zd&GQ5`)2J1?$VfBKZq*Na;#I1?AIM_i!DKw0oP|?MOtha1bU{f@G@wxcF{JaU68vR zwf7l>jAVkb$R{@hFyh1?1dIrxxq7qlqsAy#z&{hlf&SQU5Ax+Dt=Rgx^onhe4@*-+nY$S-iTM{@+%TV<6bdwVzgq=o)1=v@RNgchTqt%XPUk z!@Je!k86V9*P7RI=`AR(R$(vi0^UCKl$@w1F=ro0E$kiRvxd1I`I`XTb;kknt2da z@iKtTr-iJf0fiWvWjnZxj2fe)v8)}7Vk9%ECo5s;c<`h!qDBO*Q7=P@58Ob-RFl74cyS z`G4z3?{a)L;-3OBV(;-n6rmKRvcY8Zg{3qUK+em`C*+5p5O)d{cY3k1W|lI*3sDfc zuoB9%l8w;2Wy!Thy>v)+O1ubt1!Mi(@y5jvTsx+?800eJ4G?&du)`F%f+~xovDwb{ z-c9CrEYn!4=PRVM?_jnQ4l{5nHKZ)MQZltH{_epVM^^_-*(K(hI91OE5kH`Y!() zvm`Q{ZPvSKQ@vUGG8ktY8w@63;K)0ud5pdff*?|Xw#nDs)r5VvZo?@rdqG@79o6S! zewHO{2x5!~RGH6eLD|tsE_)?ibuYSm-H8-KWUDPQiC{Dc_Uwtz!3;x53&||=TOb1I=kPZ+BgO}&h`k`urceOXr2-67^zppCcTRB| zk3FOV0*IAQZ?v84^gNRg5+{H%MhXiSfKw9VqgGFs!l4pKeW_RfjU+ zjgAA0`5mkGIY`9QA`sh$){1i*32QZw^ z1w`S}$Q}@OE)&Q}T+I+9N=9IcN3Hk@r$StUODL^c9gI?G$IC{VH+!=L<~= zwPF&!z(3d73}c|a9R+sVOXQRe>u?uGDM(_l`0&)oq(4c9^`Y0d7@0h`FjHhwUz-w{ z3;|Rr`4`E5o`)2rBoMzWNrl8DL2rq+2+6@2A^9alND@zDgZ0E#2qOy0&&Wy~xskMD z#@i7NsC>J`RS8~SnYaR<>e@V{>(5f&2`+bjB0jWWvtG;%L&jwNbdn4)jQC&VyJyL7 z<2gY0IrwdAxb_Sz#QH{75+4gqpqt@M*^sG3T`>xTzd(3022KqjOT|FmjpyAs-O_+J zXi?pC_d!o&V#UuBgcYdXik(~*j13QBDzAc3NSLka(=q!M_jo2qued^ML|;9n zihxi6mi>cJ(-&O<}2f^GbDq ze5YQ|;Um^&$IWl-D;7JEyI~_5ug@i4V;ASrS4QC7@i>J7k;!nxBIDp`=}5Iiz`3G) zl%*~_n)V&GJ?;y=LFc;667k`{7A4}#ZeBWzL~KzR={%<)vqTJ)#d#7#iP?0EGrL@_ z#T{E;z&_^%BTImn2`ip@16Nz4OL~Z+EbRSNj$?wQ- zNEYubq1WkP+K7B?D~pvYc_+TD2h6kx*)n4bKRbsl=&3oQAmAwU({9O%A~4yN7JM&M zdr1jPIVW|wzlYUL2n5|9!b3IqS^5=@CqSi2enVT-UVH{49)a7u+J`V z>4Apcynt~a0EU3?j>HN_=#iyxwzQ_uB2hH_&=Y^z1Q*X>FYab}CSRSE0Mh{n-UnT9 z4+N5To%!=vt{dJ5O?W@E54XZ$nF?MF@(hef0u3UOYx~qY1px-OqXQ|>S#le@2Kz~1 zm9IXO6a1tn4LsU2f&NavQIRAUAq8p@;*Xt56(YIGK*sl)0gO48-~dyY6p9^M=Mq2$ z$tNQGNPHl=kywI{Hbqd{^&x_Ku(uOI&5%ZH1hwgNG=H^LJx>J17sI7j*td!k+|^15 zEX(B<@~z|bTdTbh)U!12k@r*zqz`VTA40S`)Z2QEFErm|mf#nIVPzYBo# zgHfap;(65<>*uvn?mAvf&D!3;xQDltLTru?|A}V+DJGafNH2iS9`H8J_=w*mgO&1BLGBmqhsvw#n*pe>f@UJxgxFLvJzD%~rbhh_C z9GG2j0BY^J$WV6*i`)%$8*o6Vp)S1;#R1AD)a_F3rS9TOgu1o8K;0rxHwm9Uv|Knp zhxot@mQ%lR#0bZ8#xT_ITU{{vwLuXvUtbs@{e+OS%)jFg9{5l|ItIeRg4z4{ixR_Q zI9LT7#10-YeZmP?1cQr>K;k%~AsE|%j$YLcHV1%%tZ;$dslt&@tAd@O=IbcC)s!3n zCN;UJ=JM|R6MfhG;uxtcFmt(_UfL-*<)tvXCfL}+?h*+2%3$;t99rFc2L@r6$UNF> z1S|@>V`qTXYjlt#2uYJe>y(=qCS!DLJ1wAg!XB7A%ayWR*{>8J?@|lc(7bQx)*i>X z>Q{E*R&3=C5;SfRAOWZ#9~-KIQ(hya_{ajC0}IDG8{l`wCXnwD1Br6PlZ>)23yJn5 zuc(n5o-i_V5>H<-GIRN8M`k2f<D3}LNB4xxypmL5nIu2lfF1HvM)?7e zu$^`q(INL(QqVVqRTBCK;H1<4lZEsCcU(9VXE|`P{EM<(Xk>ek56<-$5l(Ui@>?AY zmTZ)v$Hm|BeQG`IL-Ag0BA(ZKvKxyP@vdj+vFJf`o;D1+M)!bmRxAh{%g_&p9;<@U zx3E?8gc^jD`bc|h;(02LhI1DyQ&7qOIV6x4T)V4f2-Z}G`Pf%KvJ&k|2y$`0q($B( z0h2|%3`S#Re)C&u>queE0|Bt+a`+REeZqKdosP$Tq*71W^q>&W-LJa|zuCCWqT8IG z*^n&qOS{_3=*{QzJ+Yif=*o9-2%-QczQ8*DiANgGovXO(7zH4ok_Ii75X$aKXp-~r z++VY;Da#1fQgyH(BHBhP-WM0u{MXqIs#y4-jTe#s5rAyY5{d8Ca^EJ6^+16-h1q4^ z0rkolBF>N>8!10!4AbIIkr%iNLx&}exK!qF~6XLqo_n1=!n+Zn}8hR3F7$gnz#mRKWA^5E8 zy3!gTWaa4$9AZxyt;79F%6Zihgbn*IASENrgFIIz$@%L0Gs*dF7idk&#C%9ali*J0 z`4p2wKo3rEGI=iB=esm;2`Hdj>H!4`dNE$v+js%HE#WX* z!?;F9PK^E53k-`*t{Pic@wbtvL>;WKiep#OghJe8eYk6{pdT}|e(Xo$PT9n_wLatv zwP*V`0R_%ZQrZ#G?ynMeyNL{=i`gc}PuAgw3{in%jyh%>9>pj~geH#t7}Sxd7Uj`? zNMWICvhnKVwrKJ-*PQOrRxoY`)A7lqItGmH{z9=6A!Z|U)OSKr6O|N`KTv|1rc$8M zpjNLdgr+Pb?n|jNjY&^5`kqjwT|rOo{F0WQvot+_MPs0+!iT1(p7pTAn60}2Lc%X& zS?shzwkk1%3bPpyDo6D~nW;Gg(V>#}-OYSbY&aUVBoivFlr}O`=~by&Poa_qxY2OW z)K}nKVzg$c(tu9;bdd;<`rg%*VhD3y$$Li;4g|gK{lFL@-cLvNOpfi@U`ZEds={i1y zkD5#;8=~zrgTN~CIw?q86O4QePyaIxWw@J|$1dZ(_TrV-Zc5{ouaT3ep+<2hNQbKB z;8oPW-jm5%DM=UyVH0S#-?N}T30jQqB&iaYoMpJ$GPP_!T!mY9_ z1tX=};{a^)KMk;_cz`{0wgW6zW?@h+I)=wTIMWO34P%7+h<7QDESkVtjw09~EFL-# zU^IvQ{hxyVc_fZlf(q(IrE&6l;0+ffesK(AEjTjFUF5b?g#-biV!nnPnu%ALkcwad zs(QHt`k7^|lCQtO)E}rHvL6!{%IiS~reie#h~2bnb%^oNgN7KxSYvL+L7hiB#Naw6 z4>4Y^^b%u=WTsIeS(6ny*R$eMg0F%LbnsQi;463<+ll8rCMQm7b7oL?ti-9aGpSr( zodE~Y-Q^3R!_eG%F|B|6 zM&Q%_9bqh!&rT{1rxoethe*2}rPu6di91ENU7!iY#0=>mWREbS^i1SAsRC*r#wXfJ z^$I-$x$a$y%_4SXBB9xHm)R9}@wB?%Nd3r_uGAk??nu2IRfAI!AFMmgEB4n{iVfiL zDD}s|>Y!8X0&=AO)+aQj`6ji0JMiLLiFY)gX({x=F!NgjgH>QY{sgA(qxBc0GWp9g z60O)Z(%9JRPN69>nHVSkrGjFE5kXS^Qj)=}eHp))awD>a{N#N(*Ouo) zr(T(BXmijCmo|r;=+MU6a)_YNX7MO5Z7w~-(#9rI9Y8*P#tX>uhEzas1PM{1I(bln zJ3o`O^<7uXxBa>;!6ghy^czh9nzAVj5>d?U0NoDH%26W8N|EVq*`k%bV*JL6EY zPpSe7>yVuL@1DqjZVPsPhlBMBPxdh|lNA~v>xR`2XoE?5SzEgg5CiSJmtJUWk$_=lT30N`$uyt(*_}(WzKQ2B$b!^5WGv zNR#zNXj0uQJ@PvET%m&#ghG{sKT(V9nh~{dQM4kd!%h!2daf!ax&@{!m`>;)DYn zfVg1X3(c)4trlno0Gh;KV6fE{(y!X>7ii4ePR7aA7a9L=(*6!SmZ3AI>NKDb0XuZo z{ATE0beHi>w>J?%xoU6l`8v4o96X6(C(ah;_+rVYT_9kBqBFLCnbZP| zoP^K=ea?)*`I|FLQDUEU3}mV%=w@) z31s(k)$T~!j<1O=lyS59WU5XRj^cjw9R}$KpLLO*7k7|O8mS(5q8I7UPSQx5Spd(- z$@q2Mw>?$K)Ir-LN8uLe0@e#$6m0xZ=0}d&Tn>&R)mp=BWUjg;U$2|4MlRAu4K22g z##TyWFs}H%+S`k^-gGgzv&h`ZRm)BGHlNHdq=7D?r}uYLuXCLS33U%P!AXpV&^gS( z7neVN2*I zO26)gFb?g6Fvb5ew9|wsa|pA)zTpyPKU{DL16+Fuu4QR)ed%_CYY}RYt+5GR@8G&y z60T1j@5Oc834&|EcffT|uVv6ulZ5Xk2VW^w5o;rLD(wT)=F2@K)Mt|EeP+yF1 z%`w&OThQevR|b;kAqs8slL!i2dUOsba>J zXtMch(BwN!lO%e`0S&TW95XKngv-bnn531a+yq;Gi(zK%5_U@);H_P%nP;sSf|Ckp z2ez-nS-aSdLh>m#3JUE7XS3;1ov%YOn%0oACUs}#HGji>q+yIH#aV@zkD;e@x+ zaw6%bU6@+9e5Rr0I@WRn4VFQTIl`eO2SAjsd}Bk-9qOfJuj36Zk!)eI7nt;6sv0xZ z|=*T4G7hh>+mL;2;r4Dz{0{cK&I0nXq#e^H(*{Ol)jKL$z%9g6cmw)#;lIUqs2 z88m@k*R$Mcv@9taeQYY)gM6e$qqW0?JE#KjM$^%CI-18=$j}4`(|_Yng}wz+N--(T zU!08830OVGIVxsG6>poc4|}A_(dnL%+fT$f+O0r+!Wwc=SIkDXL~h~ItW8Mf1sWvJ z7(E(vK+;MdG$BF;rqx*PVOV4$ov<{?VcwvBlHrm(u}^X!$SLaScnCa0oMNWta#a;h zeGmx9-+a_!@pG@~dgKe|-W}?KioYl`Tz~^PVoZO}U}vnW!j$z0+!zTUxv$2^97sd; z((?Gxo;^-)SZsPo97q)aWJrJFI4Opya)79sw+X_tB13#F`(eU@2s6BbeflF_!OneD z{|Z{tfGa-1W((k?2!c_Ud|m@BVLT8-6lEz%qKZ8CB}k$4@+?Qt%Knj3L`NNpji!|D z;7I9JtF@F?QA(?gl>Ye)S4ssEPq|X(`b<*#`Y~EcjiyAAWf&lsTUF8l=`6#4aKb)G zM#uABKU9O_SL4m1G}7;JouI-Tan{O&8+AAC=W zNPVhJ0KIR>4XrSJaB!?brVpqxc(NbjGExcjMy7#;gaB*QU_PBPEGoU-jPUUtY=8i` ziwfCqJny4ZT{Q$!d>(gma5GC?$4pdOXAwL~tD%UtWRkd}&3Li_dl2GFHTHkqK&od4 zu~AKg#h*k5DweHcPlE8xYT185^slT`xU)#W9IKqaM_kHGOu(2@0*I zkKUZ{mUQ%a&Ybo`IwaHQylXSjr|?hPr_cVMXQ0nG1XrNX+zqXw&tv4H#M|PlPTTqidyZS_D`eBhN=J0V~$!GQokBxQE#?8Ei*RK;wSQ%bt1mp%t-44u=&M;vAQ z@mVE|_2A>1PU~LV-C%&QNF&grc1Hl;x%sOk*#8|hu=n-A{$Y^=yG;IgV86G-3;QTZ zJge@6okIaDu}Sj!TnhYM1%75AZ1@Nxr%d$Ue$qJDsvW2&T`c_VYdcKu(u}iro4u6( ze!78v^usRYk8+`x+^Glp&x*a!-*$vZBx^J}UKs7td<%N*Si58N)o6d5Y8BbMW9E}QKHsb4<2h=N3n5Aj%h|L9PEim=-K)tq#}X7b z8EQFQ=qGhV^Ke}XJ zF@;?`_OGizAodUNbgPZi8lr4>o7(+9z?j=k8H4Y$C$e4(5s%3~t35@K%rCJe%rB`$ zcat?7QnDgvKRU>waOu7udLn=vPlR;wql^Ghq4T!7>m!7ajn>!j)8GGC(Av}g-S_B@ z5UQBikq%iEJN=_)Xs3?W0K&Z=WB_5qBNBw{$?oIc?*07-rv67ym50f8tZWde!NjiC z@dajZY}UD&HQ;*cM5~mYBCxa7)-R&Ib|b9;d|=WR<^y)qwzh`ktsBCA<9U7T!9#H~ zhV_K8&(vn}9#ak$Nr-L^#;&D3gEk6zLeNVr00}hqA_ygG0*ze+mdWtpB|isllyY$F z|M`iYJ6A8=M=_KLWinlzT_Q{S1a(8xVlS~dCZX;3s+^L5#IJmVkgnxcgRC&RpiA<0qAEUNb)_(;fFQH;%YgTA~kQp#l zxNC`%>MEuz3!}HCT%`V{9Xn*JFA!Zc-y1HSEPD-Psa@w`2Txugmv ziQEg9XCl?~A|X}mB&gV7NKB);{-F(gjMGeZK)s#$m^0r3)M@8qCQe5D1O>JEL=Z!-x8KnR z*h=#&BVcR+JZd4I-cBu5+hlk8Vt1mb=}iE}DAN;RCDF4hm$abb5aW@s$dt9( z#`#5f=2$#$%^(UDSQpQm`amaqCG+BWFTBx9zUQc>aRdxZY+gWp6Hj2=>~jG%BeI>+1d* z@1(t#B&msm8l~P!w%MuX5seqw`Z;u72;%&AjU~<=6aie~87#)yqLfkiWvKJ`K!-Zj z_q)`YizWzdj=J{}OP$Bnk2?uiaYJz5CP8zFuiYf*cK(3DOxh#}`XbOnVg-7vQq$1u z4T8kibnNGcp6(|j^gj%6pnqtt3;l-G7W&UFcA+me(B~cXRT@TJQkt1jJxGJJjC!+B z40(JFRA!x1jhHkZ3QYZs^f2`YKuG2)R~yrf5`?(i#(*%^5<@KpV35MrCp6pIx}vLCB7J&GxwWjc?-(zFLc2K4S8(7(CJ0X>(mxwhi=0x#sl z_ZQ(rizx?8^=Q@%*M7wW3RfQCGQ2QJGxMr5G5pj0Y%dUE8feMz#a{>7xgL|5gzwuX zKh{F53ApRTOyLWHDQ92EnFV2D4SSZiL!@FycXSUFAamI#!D-e*8|9!#;?m7UF@4rZ&|U?GeZx60+oZxTAe%jj?p4Xc0N$}SLTF)zI`LB<&8&a$!tBzz?Kh%giqIRv`Q9$Tj3p0uvwtUsq~qEt$Xifd`RhlPX5)#RROS_t3^v#kKmLb{kM5V)X7G{RYG z&Z%AX^Gl%gTtn$3`tIC1`rel7rLU|}L;dt2nd$raxtZwuaK6wtx|Fn04s8xD(6kxn z(&loO!GluSq_b?MQ>fjRuszU+I&AXLw8te zo&eE+Ixk%bs=d~Ne8!#qZWieztE3NMu$ss`#Lx5bNfn=MO1tg;6Sf{*PJs?!`Wk9I0j#_ncF8_!#XmqE|>b4Dz#eT06S{fSSalG^==b$FolS_`3-KT9a@7(H|juvfKaaK`)v zlR2a#MM`9rKW3R9P;DfD)KA^XQ*kctjyQu#xE+D~7o$8099MEv3C?&DGr3Y}!{^ z5gTq2GH8O6Z`hw%GT+1-lq$*-w2YX*rnzELrtZI4i%F2LR+Cl|LDiszF=2v7 zI!27nBptnXwbHRGwTANn9=?d=&k=Yi`H)?3N+K(KzMun37@BhCh$ZGtn#=+0EBUtF zfcU}}AapnR^PP~lul0UL6ZmFId&)BQjzYaH z?L(j9Z->x_w9BN4B}2BV5R<+@UxDi&pw_g9*yN;ZQ=9Z|QWx2RJ0%9nOtql}t%s_$i zYf0-^D4w7^Ky}nFeW~nDwiwUDfWmtMkt*nwFS-$hu`EES^IX!qW|Sna+mVyg0*nt8 z1riHWfo`(ZjmWxkDo9wGj)4oWPGz9zJ1l&*nvd<99DW~fWg{s~D6(}!x^}Q%NxI8C ztq-)}Kj@2yA&vFzFxEU(W=Y~!eB+gE&>wweE53oZJ5K70zgQJB$ovk}7vNjs82z&o z_I=jhvIF(lS8Q9NpZ?i((mr^vbD;i5xB+~_Y7&%G^BY!^pweesB1=EmebNEA*ey{1 zs=nPl(10>P4EOV%n4E@Cku5z$c`!TryngJqw2wh&>rZDlf0Jgp!smGX4Y-u@Mp*ys z6qxoc$%29~pk}W%oQH2oT0UtE0PQdd>+g(qk4f9JtKEq_X$~~(iFZ1NUcuiTLoX(F z)R#MP^A8-G{Y2sit`r1iCP9C;bPmnM-!7rMcqKF|u}^Bv?4h)eZ3fSnR}!mN-vi$gC)aE8d{uH--R)b*@e#W!&8b9_r2 zqaOs{-qtq&(;!^))2!2^a{;cGW=&V61=z8Oi3E3ZBemYZ-yMZ!odOMOc{QGQefqb% z2;s6}Pf5Oa@V857P2z6dQa7P~*AR?5$oF(&y1v|9l<4U64MN5e*iwxM2PPelzdZu= zduvKzS>$oJ}xbaKWW{W8P?U%U*>2di7-6Sa9eV_@Avk%o7Tk5Not*@jun)2LIim7X+iUb%#mE;cvUzL#Frix?)+-ga-5N77kot&jJ!SLkaaNkPBlO^wu3}S6mqF z*^Fu5tsPJ(_ExlC^Fn;juALvm<%h9;05}bX8hGaJ(&Xdr`D6IKh8lAz-bU0S!!z-* z{ROB}Q}_(s@odZc5h;nSMLEx_(>$HOW+-V<qU((|W>h9A5UED*i=vB<7H&J?0!d9M_rmvv|rI)Fs7mpYdy z9Lo`Oa)44WyZLE#{*%CIPzr;R@T2xX{;EhdJ7%)OB@+k12!;7nl(>5H$UVQHA_+q7 zWWA(0F<{Z)G3tV_R*J-`Dk+8J?q&$b5HOmwQBg3eUnu5V@&dReNf}elh8Il5Yrfj@ z4tr%?$%^Hi{|WA;I2&Fa?2J#7s9{jUA861b<7Azyma5=FkS6_l)vbKfp@$we+IY}} z?hXw!J)|#4M7COva3{4};K%4`f0C6^e zuv)Q`HsCOD{-kib$Yt+?8gD@ znO-B1#LwRe@6?aAoV6C-9a{rCOhuwKF6sWsH1?>^ z^6dTYK`|{_gIbT)sgD4y?Z$(@AHNCjQ>2;x^5M6s;g8@q;s>oKtzg@Pd9A_kzgqq( zb-X*Bzmnr#;Gn&)l^$@#c<~(d2&RK*KVg@h5Z1w0Mj4PpGn%3-!WBc3Vd&H?lQkib zhfm9BOtu@ZkKXDi{piDu?ef(z->0F4DZ9o_x;hSZYVInRs&gL(MSgW6xwP@z&zc@J znjUiuJtP_gUFP$*21f_GVR=Ae7k4C(qyDj$pgDs8hajf*76dV5$WfcF=EQ=ZfHtDG z1VAJMUu*~oUKm0`mBnM&af&3JZG6w@x5!Wk!>n>d%U$df1H2&pN0*)LRcYm+Xo$^ncOFnxo|0Lr+E6gMOStr& zxvV%C6^vr%n&bxT#1J?_GMTWU3bTV%CbJY-*_$K-)@CjU18H$7EDI`+A7?hcK~6*6 zidA^cv)M5U0~3n|`4UgeN#kayvQ-Z_^m~tnyj^)p*-(#lWrM}I_?+bDx*#~UKg@t-3?m9k6SRgv6aT z{EX6$7dxJb%k9+g{=aTh-#7fWO`S6vrGA(Eu$5<44`$)+4L#l3032CPaGXU52Og2B zHXyr@++YkW1_~4cH((C@nsUWf)ZJqp{6RSXd=AyNS1{VKc5~0H7dtM&Z)~`P=p9v& z=i!oD6}dYW3^rqK-Bq29A*(t~M~do{fHdj%zX?n=`D>UEeeP{{MsL{ZSs!|%ZHNkmBki6BJIbbN$IYD~HZ7^KZ#oBcRiguj9?RVKl|V0!rz&$E}r-B zsb2U|`jDk&DGh&!Ru`LbhnK{4uC#{&djz#VWn{34a#-H-$e9n|^D7KkwX~o<9?>g+7aIgmHj` zMvg4V3Y|wz6p=DodAPt&-M{H4v@hYWcs%>?fMBFU!Oo6R(Qh2UHzvp%)PJ-DyMg0R zqa9cql-0b-ez{eZ60&N?yQkQPwRk=i#z6gJyzasonT+z%Kz*E7sqg~xJ<~xZ<11vl zQaKPKUrf9QUz{;R6p|VX9T<#&GdoLjg3u`$nuF~r=H@ppe#_nR+L5pBP7Xs?Fd z1-x_UR0%G?7Hpth<3M@1*u>1{-^7)=_TFm&u-e)ldrjhk!oj6!$5&I>vecuevmZp- zV>8MwPL;_4XKV5E$>d?@d1aDC5%mW{G<{Tgsn_@b%)$L=!2!ZsG*?_b%vplwmo?l;-3hxJF z(!hJsgI;)hke+XTnhdX6;y~GnP^P74o8YTR1K*M9;Jf`lx(-zP2#TvZI2FEo5F~0U zUUWwq_%g~bq<(acm6#kO$2NfU$;(8uADl;)bG@2?u#8LSG;j08gsEpn3seX}*8CkI zNQ?WyO&kJU0XUxavD=WVX$TN>`|6M}(rWfn^;fp~lm*v6K52b>f7ZN3dk3`8USR5- zZPAySKc~vyD4&n%$mZgCd;0W+fq@$Jv6jEIK9u`wA}OLqo(3wwhKP+fx;_p?P6?jt zlhz)+&?5Z4cn0R9BFRAAeL*Th5noVa5ZVy*DwG(g$of_wvWKjsoU9?&_ST^DWGXrf{?iI{1_K@OfQax7dtSL6 zkRR``CmH@f#-DBC7yJl)T9F2!9zKMKrTX-vRv`2!)ua{t*>GD1{`@ig_Dq9c`*ip{ z;B%0IU;EbJ_faeH+c6V^S!KRMO2weiY~s#N$xBhtYC{4g*45)Xtv@Wa2aAO5O# z(BmmvxRN3;(}%)4DmoJ=3^gj0r2iYV{s(8Dm zyc3q#)lZcRPDn$QCy(~ZisTF~SZAqHoRKQ(^{Z0joxjci0vY3-TeLj@l{_(}lfOv{ zZ<EcbZ-y>w!BVT1+dm=L$#^yue5eT~68+m4` zz#Vja8i9N9C@=R!;0}7rau2%Rg0l&Vvrz?;wPS%9@zyd`a3BGH#AVGg-7_E#O#4`F z{_p+C7)hu3Sz2bo8=t`5cbOOEZqN%=_NGPo_xo2vhF193y&FM^?fKWYwZ4J{9{yva z9&fx+MGlBHuOa_~9{!(^hW{p3@)6^KOTEPCN@5(e))E6|z6Jh+!zS2}up?i+e2ta_ zxDjtD450KZ-bNkF-Z9{h%xsJC#UGUa)6?K@;wm5h3niP*xeg4~3c1smI_M3Hf9vG` z+E&W{^)1T(y_(-G`4gXg{>y2p7@mBrW~L9r4o7-9EE<0D8jE2IE^$2Yf@MZ#7&h5P z`s%_cusE8$OR~p*j9+(;O2sB}Od4$VNW~_y+G5ixevN7+za~#_kzZ|!Uz#L0osA2v92bZ`?gtiY6+itzw<1N|)Up~!`-6+X3`LQcDUf##6RhM{WtvgL$ z@vE)i)za%IYniYc)&T5^U?7t0L!0DnhNNEnIE4O`#vBYT_TnJME%Zt&aJUROB*|N2 zeT(vTYm59ylCae>IP=55pfnBqlMeI3FTwMIRT_Sqf7#8+Um!!x_0#^u%g1VM1b~mA zN%s9qqJNvlD>-T4|K3<$pA7BkgI~hq?_c)A-`9cPoeOZ%MxUyk34NOJN}KF!mE?x} z^d6cH-n$R=(p&87Py=s^`S8oq*w@k50rHIY^$+KZ8YMU6$En7+2Oke6RC{sCrXJV4 zWObmT#SpHAe9^OlajWu0r%VAMwinO-vGLlqk{I$64dw?f#Debs3*)uBCB@^%FH({QzvmA2;wK5u$O?;J ztKy%T4Xuk;CtnLpGmqEWq@PWatMQ{Z*O+dfEU&oGi=KGgxi4DuT43MnQ`5vh*R-Uc ze{6j9l_YQc2(2}?(1*}*GE-+m2nmSRF1HA^aeVc(AZeE4BJh!FrsS>0Fur=>Y9PM7 z@l~7nmz4(H&x|Scq5G4}<5_gY7JatNqT2%huAP?3zb%tn;-6XHoFV>8^2cS8+VQii zARYXjeC(3pU_mS3mvItvS29|{m?7Ag6Vg`v6*wK?4?&XRj|bWkKh2Q5jUS(o zv3x#!Ci&*KC4CWkVf*+{JY;B)s~S?Vx$Y`pQ|iYiC12Ghe3~Tn;>Tz1L21nUlfLOi zF&A@}v+wdd@EV zq!tyiDhy!Bi6Y3DLa9u`bju{*o3TEAd;Uw~D*;}WP7^}rJsHA*k}LAFu;-98Ed0Qv zVLTH}J)gHM%J%4}~AF-EnpV>Y>&tYS{_;f)ZYUoqj=Z`o3lkYaZUEyGI(&gYxu`6!L z^8;8{AD>YFH2N}0W~r^c7XE}5wGAJ&*1;iK0~|8c|FkJSS}l1RKl}^&rGfuH z`+NBz!}$eIZXbSEU({O;^s6od^cmx$Ho>2h2LA60)4;!fD*WFsY!m!HIPiD<-@#uY zsUbi84^9XF8T+Ns|KQ&X|B08jME^ImKEvmF{JT>>MuvK7#b!wA#}9wVklLru(`3@y z%D*1}JYnhodvkvTriL~c!IfF%23I<}AWRf+xlA=_rlD5s^uGXU>}Q=aAJ`^&n0TkGQE{50@)NC*F6KKLa+*P%`DQ=)WytYQu(J&DPY9^a9s z-f(;49SWuy=-^w8^y3E1M@h2B&!BybEcpcN(Y?I_CKF2g{M$09Z2`0DPXwJYPv(5x zPL}}v?TvRfXntm}A9}PWN?Vtq{`5%62l+{mzfT$&eS9x33B)Jm|I3o#_u3SdccUf- z1af=zr#oB>dTeh#;djrE9xQnzKOJ%n*L|YUoS#C6-1(LcnQe{wZU!;UG(Wm;HIPd) zKl(@W7h@%z$@oLkCxvP+pw1yy5r$YM zIdk@fK(3|ztA4k9&XgpKAJ;mAmJio`e7H)kqV5rk>+hD&hCip5&o=qP)skEB1#Q8u+`m z2>-9z{=@$MAL70QKC0^ae*y`F%@-AIL`GwY8U$=m)I^O2MSamwV~dJ=T&hvfq9j0V z&Lg^8bF%y>I5dH%l_=@AJyWn=HMDCSdrRd&eo5-ha0lo~D0r`aOySAWO>ilG`o?<|+IG zr$o5+4`jrO}<{GXZ7{V7pPF*E0wA1GiF;9sJK1xM*T|Ok0E;M zIJF%fwBddTKrMUcje5y~h5h6?u`Th|eu)cLU(Ai?KzSU=hrQ-j`>6?Qt(HypQbrY& zJ>z+R$l3#%oFL?q{z*33-(_z+zXGnaeNNZHYP|#!voqFL68O`H_7Zwju@S`G@p*;% zLA=#?q}hlMwBhayb$2T_OhxmLAW1r}kv|5uag5|3spJ}oYzFetgLNX33gVq>-HFu_ zG@SBzt@^v9rf73Px%@RKeX=ME-QI8H_Eg+H10uP`XgEz8l-dWQL7jmG4GIj^DrtoP zk!v05YH*NlP}lsOu=)&G_NnM{Q8?a~+b84puM4C>_4RXE0g{OZxdsM5XpoL8esXkX zYv$1DGoE~^=70nFdTd;)e{Y7qGK0H))z_K9<#>I)d`J2sGuT>aHey8-8tSMSi~a{n zSE0{#)QrIeaIV6(71knri1RtROOQ=uB zEw19B-V%(*p%(w({-oo9K-wK#@2U3-HQ$BBDdgXm- zmTyl0KeAEepd-c+=Jf<+yQ5EQf_GBUv-PnA_#$6TE|#R5!M63*IIM+Z0-NZKBY7hp z*ryXzL}2m9*YoW9zQK|*AUp+o*d2G@$K3>#&U!o^x^Cs^q9;5rbt8W>z2#HUtHoOw z_$A}t;3qwR2sOHef2Q{}2l?BrMbv|Pp4ORwS}T_%ZjbL5DEhZsQWcn~OL0PgW6@9iQz_%OvU*t8(-ISl{EuRXW7H?s| zpA6r@kH*uU_;v@6_cfRPT!bZT$@D*x4Y~x6jp5I&|C7I8pU~R6>^Jnkem|A|_t;1m z{9CbPtvmhiF@TC*$@TwY58B<(cl=YH@~QY;n!u)}D!(Yr@_7ktZmRm56O`|UKD)fH zq^dvgmWMcypJe)c<$LjEDR0Tjf1JR!q$pQ27A&&m2*{RfH5yW=C%;$sEX=h3ae zU=F^8b;}~gZs3yhUV$0XaRN1>FO3cTg^H3_>-c-RAJN}y^{K#6>v~Rwx!^Ho&z1q; zW(w2UkH{gd4(J&;)_0w=apihiCB9_ zb$?JPb{j*^Dj9M*ZnFRfo4G5H<>k&$Mn}lH>`cIT5n*)xdE_N(KOb0-p8cHIGyAy< z)wq2x>{#tMORP<{076wGg_?OK8=?)&R+vFgByVZhqW=Z^k#SbTo=4cC0Sz#vd5ziD`6W?*@5Yv~K8I66bHF7~d8CGoB`?fXBq-kveYSXCNmc)pSK{%7d?y?aE`B|}EIVkj@~^*K2=oVx#-taV3#My#rr-q^ljqFs9hnTT zA(Rn02M23^qIO8sjqu1<)PJ}FL25TYlFoM_I^W~*_p_+hWh6Z9yZnb%Z(#tGs(eeD z<=5lO$Sz>Isee(L<(m_fPiBAW6O<+WQ{g)$!8<9--<1Ggr~mK`R)jeWz;eOtT z_a6>TP!WN}pTqvFx30kJK-l9y{4#N++x`>}UAOjk-L0ONy0Ir)yya8TD<^?Jnv8$- z3CfZl-NEC1&1HY{uy`+t|1joG58`YLe|$e0e`v>gu_W(*lj8ko{Gmm^pCbP7lE;;F z!Cx7BKbilq@NPFA-Pp&l*U9XLzR!Byx>Wp5H=dW5X8f`_&GNp#xM@TFc0-?Qy|1Lg zck6%R>rdtnj9D39mhdDiKVemR<;Sc}T0Wuw@J*8P>G==4??}Uc$fp0Wu)Zh$!?a@( z`VZ57i}?}9T*QUctq4P4E@FHv=Fsm>kIztO&p=G({@#m9%b91XEPgHmyogOYJcdb! z7HiAV0AxlqS`cSXqVa+;_37FBik{i~Fskjby>IpwhJ2-x-zjO9Z)xxV(@p(>G|N{e zD4)z;Oh{0c{V5f`r3v0iSw55iU#Goad4b2?Kgk>M_Wqaz6%kncx$J#4UI)S+dw+4_ zN_#cNLuc!^r0W?sd0*;A|L^jaPerf11pZ?({>@KNmh|Wj9`9=|ds%pXQhPnFIT5uK z{iF7N>v>7v&rIU7IrxY5Z~FZd_WnIjJudjC#NJP4@0WSJyl(8-JzjsU8~Uz`^QTgb z|69|HzZKpd&x2I*)RJcToIB#{?}k1zy|1K#$M%LLla;^X+4Rbf zOW=Fx`V-pw%;yr4?wwM1V6&w?>fAP_I_OL|B1c7 z2i5l2-nV!QLjY3AZy?R`i)MO&>8AeXG|Nv(P(GQxxFSJW%6lq&D-yhuvV2_ve4Y0G z^x}oo;IDaaIyzWS;3%1=nJc2n1%(B2PD;H$8_2jA%UwYnxfd)CAC z=Ic;xkL}rdZ{c`&UGw9M(k$OT%>zs~^|z*3z9m8VWcqM^g0cztbLhkM)?&O4ggy4`-o%xjl)xM5)*kr1CcPW|R^lz6 zie8o8!oV*X|6Wf}mh|Wjo|`-@=|*2|^4h;{>K`=6Q-3OaeFrjUznC^!Wpi#n+vxe0`Gr5Xt0i+~bMsPiy=p z#E~%U!N29O44b7@1T|zYBp=2-;$6L}I)w0D$}nzP^s@e$smPRYy*)@`lPN~n zm#*!}c=z_aB=pkxvp_Ek;Cb<2$MbIV+q$1Q z%CdhYsPAfLeF>hQ*9|=9?c-=8!TX`T9nZUg*WUwppK;cgpuI<&@T4WbB9_QT;IodJ z)WiOMe4n25_c#4Xy$6rD6*08_#EcwA* z{na84rguov-;XAI3Hm!yPHZlqE-D(`O5)`1PyK|BfSeE3%yEPOGelg4$~mPI%+M-x z`6roXMu$laX=h@{wr=;4O3cXs6!XlkR=bYcWh_++{Zqi5EB~<;4h1CBV-rX&{u#4h zR{C+G0;j+R2Ze{=j%28{-(h z$uqx%kYFRs%w<&Z*6BzYfl71K1X=9;<1WoHW`D-q8e&f*VOBIx$_m^EKWW=|~F~}e@y?jR( zXfcwNWmD>|3)JS1@YP%xS`qxH7hb6ORcOWXojj}7s+;l>JU-u7eJmK5jdE*yq5gr^ z@lKeAf`TJ5tUFP?lDe)HTuWRigzWgtR+`U-mIs$-N|V)>0$A1L1T*aa=fCGUkoRHt2gr;mv#to)PriP8moXst-(5l! zd0*haT;MMU=yiW{kn=Qe7kZhL zbfIcRl&T|a;G&W`ELO}=M0{ux1caY6waI2R_OjclxzqLJA)AD|Ny5W(LBbbsMpG$& z9{L@q=!dTE+)rrK?*#qC6|_1Y$nfD|c5r7#&46aBY4Uc0;$6XS)N^Nm^~>)$KOj|M z2OwAR=U|5bbygePO4b?9I_d5H5Kr*NYCRuyL5mgyJAE}*BP$JwbrQuuYx? z7N99R$q{l7!H{*WGK<$uzsd|vf}(wmcP4Ggp=nc)h(8EOE+!;3BT+1yNW>bc7GW%~ zu*aGb0Hv?{uvH#DIlDZR2?IG9T)pv=@47lxqHBHCSN9^7#t4igYtcBCVOX!X5GnaG z1C0z#vT6=A1ls`}$W=<91zw^6k0Ma=+};GQpBegfj(nsUZRe=Akt@mC{W0ybc0EcX zgUQO?9go|reFsb|50^TCU56JU2s?IJz4rl^571n;dy8j1tugz0#cxwFXd)R@Nw{HC z!RwpxDFDT5NTg9;!opxU5yl?ZY@Xl>!i>y#U_BUZeSZq+KqmsPR1fA;5hgqpn=gYS z>gyP<-(eSkaxJhv=p?U6)5fv6X4e|lQCqH3I-P}^SA%MkRf>BUGLVvq?~2zO!Dd#W zJ)6c68bC0d0G2n7%_}c%onB>zP-zG|e3iyhP1cHdbqlYe$C+#f@IjI^_dzlBX=XDj zJ`Y*u1S(Ez!>>huDyfPLA@6*VW#r9OdxJMO2yZ<7FGJ-MtFXVkSxK^0kt1j++B;qm zu0aD?qgrSRsL)Xk-W$s)0u)$d$B`9y36FBE%jF8H2(DT2a^sc{1sCB2vCmjx(pYcA z9;hy({wg+bm-*dx=G;Q1=;TaoR>s?)dr9d@hR+Bd$;+#^EMiS`DP^})6v%!W$O0?- zJH=LXizr)-re_2IX6uTv)?_6`nzh(k4c0cYn2WWQW}{+lmCf4A-K>R{r8M0q(xg4j zn$gq?AkIZOlE$(6Abou{0Dz9Q35CivHKCr6Fws^D3#}V|C0yNk77sBw8mbx_qeU0B zk(^zvk=wyv`|Wq_9@|0oFO@3bUm|AGHM%u|C69K=$iXad+MbY)55-gP$j6%C`2rm$JdkZqOikT5fxp#V=1CV}@2p|2)(T{m-o1O?FNl z>}Dlcj@|0kKn1I>;|()3INus2Ow$xnMQj}ZU^V9e>@y(eF?I8j2mbq&e9ti3bV?)C zXRR3vT*Ch4IeSC8pmsKX19=JiAD3&0bbJ$K)@S= zoQvn8j~Z&2Q2gf95;L?`cKbtZL=pBo5mxCwo2}X_#L~`KVeM5R-8Z8HWAX!4>dzC+ z#(g@j-V;>K+AN1bTX+C5(RYg18gs<`2>D;(-SE)o110T)#14K#xI)L7zyxPL>)SJ^ z*J(t<{u>S3tZ1WJN}ZBpeRv0P5@kq<0*edSJEp{P$Va6Z3MmEG@eixr zc^#PqL69axwP<0?`!G!3L%7ZGsJYvF0m_k3Op*^UW=J8$R^wexR=N!;2o2;aL{s^% zsUqnIO_IZe{E2~*sRLAWCiXl=8+wA6_Mb@R1z+AM*fOR*eSIGzs|0Er)-A1}4Lx6@O`j z55~*9RaDkE+5}a=RR03JSKgR)4-ds{MsPYC2oK$9w(&DOzR@orhha8l>y}l*Iq)tAOFND^ab=#FvF5tC8DQ~20hDoIRb3rckc(sU$QLhp?noti_u#4b3PV#sH zW2e8hT!`RhuDQHDQ}i8B%C;`RQr2>aWs%t^7zjW*a)9C!VYk<^Nrc}*tQS>wEw_=F z$FJM*>EUJ@K2C?fvf%P;v#Tviq^5U;YyKd^!iD7Tn zHTpDAGQGd%z5jIFgYKHL0=z$g=OSs8@cjRAa)yk7A z>xBW}eI{;Djk)+gZ9nK<_SuWqQ4c{?J$g+iok!$Oy%leDZ19vn6y@`jZ>23XL?oAL zK(_xrcQs@^h{1<-Hs5B1z}?@9yNkTX$)n-Biovy@Nf(p9e98%Q@(eO zeGj6Dg#CZ6Nj~;H@vo4rgwcbnOC72$vKJA2q94R!lNJk`TyB0Dv!7$5aXd5X|4df- zzJNkGf5-sfZG)jF~;(hf|Au|ddiPw`N7f=x7`+He04&`XIottBxn2*+al%(vV{FV!;3u6u?GEx z+7YIv<5_D@f>NvbW(%kro}U4pY_&stYQCAdw`B0311gJWK*KV z;mWbHF);*=B4dtb?_PfCq0|4w^$p@D+@NVAkHux zWkJ|ZGI`>P7=Oa!^4FWkjYUv+7@g$0%`&bE``?+QI|fxH`ig{mrC+dv(2n@5L(ZcZ z0Q5k~b-l&olt50%|CW2TL;Dy@_7ChV zF&Y@`qEAuDr*nGCl}aGEUXoMS=La;9xz@Si@5BeG zpnnXf18^|fSimeAzat$`tIpq#iz&QlmY2)nsFFgh>`ifxJbOYFL8iRR$jb(>Rx*68uh|D{%tKinO(s; zXdDlmk0@R<^Ffkk7B+BqS$E0fu}JWN#qRWATh3#3^k6{~>+@IPNf)qSUT<{xf4c+9 zF?o{tg?7?9xEb*Tz6`Q}90*^}@X3$!F6dGT(J@2l1Y!SeE9u~{xj&1HPM5=}?Tg|8FG2AZ*C0GexnXYr#|7lfJ z81A1K6$Wui>1sk`z#a&{HNKI8k34O{f3tBoMIaH751eBI+2}Vf6fTwVP`t_rK0?{B zLk!1>L?gL*HhgcHu`m8==2d3#S5t3-NE=F|YsxsFWWeNqX7Sh4$C$%6m4!MP39Zf? zAI^kcK(LQLpg0|C{0P}Inyvk9K&*pKQv6?TH&c680_t|0tpT^{#){b7D2Hb2)#!uV z49G!mNQBZ)a0b{b+FJQB6OMXo`b*zdMg?#)*0Z)O)LPcHrYyL%tNb9~!LSRBjz@kT zlqzWNF-lUQ05BSL? zT&4WUvu=Hv##!rJ2!ghgXow-hP-eb0+T8-)2Pk&*&Dz@sBAno{ejb0?n0>734^@P8 zio$0G)kA=Fqt_QAb+fT&Z)4Asfx_woc{jMd{|y(*Go+%=GlE;C=+Gm}o>`~Oju~20 z_T7KY&>QCRExi$i?q7x*!>#hrDl@pMuypPSv+L#f(i_a>k>0F*>R%nTOSmgM^hgfr zfFUM$RSjr*`XsY$RUTU({=afqi^4K`h-XEm4lGyU1qxmTf3hifAkt*^naSu`_`&*; zR}`i5$n_bT=9&aSq{AN@@^$>(3Z5v^Hc%b1)Zw4IcXmav>L?cB@yN@wq;K8k0HJJL ztiC_e*d*GQ)Lx*B3yv);fuq$U>X_;+(0;@#F2j0&FVlEEvIL0ohnkctI?+R20K4?tY*NYIC z+~J$HFGba(aPZ8UdAtC52!WLK5F{#84*qdILW~1soSvHc)6a9wtKap#c=vHqOvS3z zguDyCX&8=e##{)*4={mf+UbB~lnSKib)`fGY*6TeL-bQ{t5S&*&cFsctZv-{|BNKi zhy&OnGS23^uAeH-`qfV0bgfr`#o$BRmhulflz&J+jq?Ob{#$WHF0YZhJacv^6EVOR zDM7fEEGSO>gOve7aEc09$tdS_fJvcUp&443-^$l%;fAONUDemEBs447hfJIR5>8qn zVoaWZNVE$eDTpM-LHn)Ldm=D-e6c`Y#7QAftXKCUU?dnIDUCr=uOWd9rGf-6nc}jH zj0ZQKV(0}5fw2Gc?-`v`>=odIy>gagji1HN93zyrS2GA>a-jhFRd#50iZMH%N)q=l z@JNL}qFijM>L(z=v|q3@nr7EJ#&)NO*K-Hi6dpQUJQ`okAfkX0Ybh3{y1+X#u!s&* zXWFvxn^FP3rx@yVnIR#~@&w(_I`subraZ!4z_*mN)GO^S`o2|4D}lAiZw)Gz{(XCq z9OkJ*Q73xF*O;b7mrm3lG86R&_5%vddK}{=fKLQ~uz$xurLwL2@QHfDD}e`-LKqd< ziOKuVPMP?rW&aT!ug8y&2vK*s6A=ok6M>5A@8>CCvSks5^I^URDXC~2HRPH8zR-xq zQTy^ZDHFZ`(1sO!UJk$~z)K1)STR@5F@4Rifi=s8baDL|dZ*-J00-gRjaTvg9b@() zDO^jgK~-Dj1}X(Av0nJYP@zmM@92ddxySS}3L}&~bV;$BLuf^wxg7~eur-f<0xV)7#6p#wOh9o!7pFM$rw(!#l^rD&UfZe zbc#}52rU_jJ~sLYS2vAhhnZmpmq}@#G5eq33a3+zr!UC45+!QRRSimIjau*Hol)pla#SwdFYYkr90VvBte?RF z%J7Y4lspVj2JS~0k03Go#-ry8;w z9yRLzzCfRT1nh#WnX&$Wg$;bKfa2zR#Tpl1 zi=VaFET$f`KmDiuJ`VTvDS9T&MU+AC-4tUs%1q#E)3NHu<{c`EE=>tdg)sqefs(eb zVBTs#qY;q@=_^UUMSryhtibU8PrMZ#b;(wHqDhR(=bfQ&C+j{ivQssYK$4*qYd5ut@ zKHtJo3AayVV}Z;}kN`QjR!>v}XhD8niaUwkrqwj&$s$p@7IgRFWw(7xPac{M{=F~e z)aQbxq>Uqf6Lad1lt_W?i6w`Z3X?s8M+LPSzR-vf`ey6AQ!yg1TS@fc@TegdEd^M+ zAb+d8N*Hj_sV{PQu~A>-@uFQ{fNu-MM464zg$Rp|c z>#5Jh*g10JTV-*gekfq%m#T%I9Ifakd>+(xB;uB+wBuU=q=> z9cM=W4mgW0K};(Pv2oqP`p_a)q;Y~?zx?8$`QP`UQ`+w7aS z{(^lIi$t)ktjjv;OLWR9=#(CNHb~hssP4sDBPnyQQKWaaGv=+h51{BQ-_&!(oF}S)<0~+Dge(IhOr4o($of1mV=-wkhl*a4%?} z-Xp9Op4lf!I~p1I5^ZSlp6BSym$(USM^EHn^?Ncyzyca3MG7t2B+4l>a>p@zA9 z0BxbOpg-`c^2t(4EyK^DUnRpb%mP$k*4gKL*A>sPW@{6I ze^R40brj`;`b~l$sQ2-&qFQnG&P<@dk!jf9YqLWu!aBG@9sb#lP=^37c0~8{X6xE$ zd%dMS>-&*fEN4M1o2~Kob6a+EaN9or6jsbyD=#?V>=%Rc{T(ql&+kY9XH7$DI9HY0 zbQ!Q2J>^Z?d^yGo;{UBBe>jB$m$p(VLaj|8B(GpR3+gwM`fQ@AX?9A#T@ta$XFUocv zU5#}JokwBGTd;Fj^O%|(HrQ|@C3K_GUiCo7@enPPxrHxr3eFU?^WZ+oXWpW zQWF3bIA5aA@j8ouVntxq(l4TdAMT6^RKG|Hfyxg?1&Y?rrmn6yxP4z~`*26whq>Dh zZXaeeaPAyneK$4+;@A3I)nwI1z@X32DKwd4ktub-|@BA+uYk9@lDopz~;CAvBySWznG1t;hf>?b%Ase#_L z2e8(W{n2l5na3iPJWJ3~5HZ~O+0L$xP*g~Nvi5rq=vn)}Ptm?HTiK`0=-zPa>_MsR zO^8=RGj_}0$ONE>&X3F4v|V)bqY-u;d%-Y7JR%s}7o`Yw0Xj(z2S=6sfr8P)Gtf;! zbm9@)9u0Ji^*OfqvDcgE>Avb=CUw~%(5Gx4wP|Mu7pPVHN}M&YK0HJWQrO?`GxocU z@@*rl_EQKz-feZ?E?@Y zjT!@!5Z0U6LK%lYR#Qar7mWr6iKZ3&KTd@IHBS1&mtjvr`@eU!&q_4_I1?yytqBPr z@HruXi4_rHl|e#q10e{w`H$~9Z!Wd@uiFP(MF@T^4qH?Qz$O;aFgmEP9vfr5RH)tV zpn@BQ(iPShA3+*_7n8;w%EKjYdc@1)sR2~kT|kWlOCb?byx_?Nk7nM0_lT7z*5I{NnmdI z5C}}PzbNm?!TZh!oU|CRG11|33|Js3m4$yb?KV!D60gmEp$MZGI5eFse z{9~1sY@R0?{r`TH5PfBwY}R=w0L-&k9moO9Wqf6iyiqZz%~5wJv_0DaZd{gtvqGMg z@=VcSwUp44aZn33s!@Yg^S>xTVhe$UCIX(&@#`?kS+#!J) zvWdEYg9|5m6_`&vQ1^r1eW3aQ=N7Ha?*r+d#rnZdjqlw*1mEd0$&doyzkS_3zLy=K z@eRH2!1w!2De)D?$@*ptdf3miqnML1gO;ixqh6B(3~ zJf(=iWrzbLQn@D|ZHuCyhjZYU8qUEuKIqrLzqCn!@3_r6iI9(vaVmknnpW+!7wDg? z86dW~K@=4540c1(`>FegHjXl@eNr zqvuxxy&yX2dFxlH=y~=~P0!l*Y>7OD$nMQp?j zOd%&A2D*zE#G+<&utORzXtu;wZt2!2YFf!C21KnKdUrmtIngT}UVkQuKT(!UKBE3a zjf`&G4)#GYuqZ|frl^B?>pO}3iP?-E!pFl};MX?pCF_E7ao#59y<~GS+_KX|`d4Q? zhT9p|BZwth^_OCS@CP|+hzT|4|MM7(cvYMJJLG(5exM|PHxL=lVlyHCZ+RbF0(w4c z+r}sr{WrY>DFAXs!-#pRYQ4>h9<-s8p(!gu0bQG@n+b+u|x+ffmk-06AWRZ)JZN+tOrIa z>R<)(<~R91;$;4|O*y{RS#RSS6Tb}DghwsLEi*I{!Bto<>wt%`BWDwCZz@Df(c67_ zdp2$_aoyhf5T?dBmc)}L*ONE-1Q|K`u^5Ql_7-}~ML3Jb0(j!lU-uEI z;O0W?InFa1-mMYI7IS-_iEUycMYh+~VhGlH;Nr*u$wqrn;260|B~@|A@vtV4;) zNz(Z}@XMy!r0`1p^7wcmqZ_jp*%ZvgyM`(LNQsc`4(VRtecCu8)GR=%E3mwqea0lULBg({^D z>xj$O^Zo09X?l#L9(sE6_1NJ2|H{|%&;RX=r9OiJr2$gN^*mose`1^OW{doFc^NN%H-uWQw_m5yE6FZuq+8M6LM04ILqhCE`bn7YH3(klM zeTH5}7Ix>;gMdou;z=Ry!rOrBX%+l)JJ%|4{UKufg?w7Xr{eaKjC!A}fbdX2j@wx@TsqM6#e%0nNS8$O~o!zg#J zJvfB42B^d0b>P~GK-)${A3gZU_%OQPO2&aR$hAsyLp!|0Th{Bf#S;3$PmZsib zoWKqp2-h(BP>ZKQO&uUKRrCndl3)^E(4$W%0v(hquoln>)eA#&_7=ew9H| zVtj|&8P*HuW%#W5{dZw}_uMXc?Ea;{<9=XmYdJ!*R{sYN01%=M{?C7|hCsQ2l0V^n zHL}=*o2#=f!8Jz~c^p~1$Z}D?f90P!vaoio1s0|Qix~Xj`usvXP)ph>_Xi$zn=3eq zLlj#@ubYrBlnZC4#9_~q4DB;DGqFN9&Fq47D z^h)-+(3>`p*p^hhcKSHk@D_t2*9}&Vf784)vY9*S6F!i zq=)S%2h~774;7FYi)xHiI30l^c(}%#u{?>VLcbUla!|cWqP0-3gHu#E@DV2!WE^um z7Eq*11pt*E6}XR#+(}4o;n(4=n z5$vyCKLRz6D_V;M;qtH+PKeBta`RO2SH`?0#BfV#U>Aa&pNola%fl@P9ARGCAQsp3 zHQU+_k`jUs_9+kF#AW=;Kgu!t?KDFlP`9657J9xcv_Y8n^7K;dD|MO{q%&v|a+ibb zqSQmnM5!kg-!rp>(55UZ{y~20M_{X(Qa3vRotyU19;=K2wjuQ*6x` z5l_m69#SrI+s665g_L1+_*NahltUzf)i~Bvb!)O5(AE*gyxXV@gS$o>4U&7$L8Upw zA||sR@zR!+qiW*qyhgw0cD_HFPAV2f3e?dGRLI>WF`t41mGo2x(?=w2YF#fO+iG<< zQw~C$hQ(Z-BP7Z6Xw=M@MlDC(qES!gNxVkQjA_)ZprP$!bP9QuU0FNDsZrso_^gds zYLTu+1yJdcWzSS(S&|`Sc}x!M`9F#SeN#1chH7e@I+UmugS(Ebne?OE9gs@MUh@fx zFUbKcA7eBu=USj2i|n9Ojb5x8J=bn@yfN=VxDsgosGk5|BURHMb#-!h`koxn;OR!g zJd{@=uAGLca?Qbn!)dsjH|aE-&y#o&htt3%|LkF zQi`}y|B2KP8|rYo2XzvMI`r@V!{-F-DW1dw<{0JBrrLe4NUBwRZ_f2jz+{wjVRwL4 z$7??fz0&J@83Iod|NhwB!l)zVV6#VCmldRe$GR|aLm^3x1wP2EJi|8oUvrHQq`5Mt zJcBFJcD#C}0(IUl0d=k%*!r{sB%~79b*Y%`8^vsM9SO|#l{DL1zLz)7Q7@h;he#P9 zwNADx8E-Tc5p>bLN-%37Gm7;N!K~y>^8Z|(#Pc75S%fDP%w*%cU%2>>!anOltfJ^f zFh7)TLcvrcj+kKL8iM(6yT?3{xW_mK8+i`FEN}?sy)L65gN+qfM3EA(1cI6NU?VFP zx9`K&WoVGQ<5=6| zJZZ12#;5?j@>(3MbET-&st(VnN>=g7qw4%2uI~x%I^USLg(0Qjt_q{!FQlNuXAH`< z9_LJ*8TA*(C*XG4{^H)+#HjI_CoYt&;LcF6?!-bLtD%#G5Re-_=gJ=eG)2s858_3^ z$l^)7HgQ;!7GZ=ka}NvB%9=dx(k5a}_INve!ARShVEuh^!Pxwr^n_33ps0`{W|m>c z%sL_038>(RnKe78aHoR`@49wiOUx{LWBOD`J7zW{6%{`HR;ciS926B&#LT|26}Ti$ ziI)XO%q-xb!dwRx?)j}#NkF80Rxd2VNLNXu9W&!HqNG}}{eMD*x8 zVrHLFrL#x8FS#q!_SXSgesQ{%ISq{Ziupjly3J z3V-Ea#PE0c7wsep@qdda@lpU&VdGzE<6mXtf7`WA{)>_5h1DME;-9vW$W4j=*9w0* zL|#LJOKY9FwOSpXQ-`JM@VFeHLoYEJ#J)R}JwA#e5~Jf?5(%>d1VSlImvk zB1v$L-tid*1|);4@CX)Jwrw!?#OWetp2!K-2^kG5HBvs5u-*7VhJ43a#<11bun54LK>WR3_U|g{%QhlJL z_+Oi6GRE3r2G`~lyIAjsI%7=XWwjg4moM-o~<$ZZ+72UF{<&HjRDF#?!JnJB+zvW&kN(Z8R-r z!Q!pP95v2E__#bY5VL`tfyNKM6f+L_{qcjDRlUA(v( zBU_^0!Fc4Pv*#gYHX8HCYDXYtT2Vsf4O6snQKD{T0I;sG_WzP1Vg}ogSQXo2 zG{#MPfDN2PT!cb6?P35`)woz_i(R)H`f$S6PL1P#QD3gd8wmXea9CkI`vq$c^^L5f z_xt6eVDMo$i!nGRf3f^(m(f|O+k7W00+ZQnxlZ~}j>%zy#7_vsnC?Oh5N%|M(97I5 zFtebX0@+y}desc=gu*OGQiVB->5)K5L3~&D9%Y8UGQWG<#P0tI(e#tZ@3b15%HW$L z{p1-56G*CblcBZH%7_%ABy!8NbjT4PRc_K$?z|@gA~G{bHNpVF|)iJ*tP&nK~j-KkkwR* zVSF7sj*T%E^{w{SRlAtt1xR)dHs(kI;kH#mfZ>~%>~caGb|)D1xvVBCb7fEiI`0@I zE+Bx|0KIQwx`I67^o8&Y8CubY(7`a?z`*nX$)re7g;zXf@lWGMnL zh4E(+BD|8ra+u@hw)~Exc1UND8nhHpO<|G0-lrr>DbOcn^*^f#kHnW3vE&&t6kxk} zf{uu#F4n!`Ni)eYo)K0OSHaf7#Igso2Lg^JmH!FE7U{-hyNH-h6lT5EK`BSx&PY4O ze2rXUj`Kjl1})o5NNhx~JHh(-(OmukhRXUIs#`4gk^DiONO25?M$Tkq1Eex5)2?&v zqbYI{y$s?|d8jVK1toFSzRH?=b3yi{e@Abujb>_4eKOV`C4a!-!tc!xx^l<{RwqO^ z=~R-8RnX%nLLjhlWh8%%*<3(jEZHxxbCgkk9|wemx*Ih^mbuN7Z&G;d7}ra?-YEF=e|r zzlHaqKTgvhDlywQWrBNc%Q;4*>bvP;v+D&_Cb+$y5xhvLmjTXHxLdu6bGNz@=f)R( z(_H>VZ`OYEU(H}wzncuqb4r7{vj>(*U-#j26EKxG9cG4hA?u-rVi%xTPl*Z-9igUj z@#VFyS6K39tZ>o#3s*IHRBR%}p$GC?fe@9*8X~4G3#7O_)XoKCTBS3Gbs6XXsL~H7 zY{s0y($-`Ui2<|vU3?#6Fhc>197$|NXdil?3anW-L^hO%T4|>zDwUN112Q4M(pFVx zLRFpg_n4}J2t!qgU3aLe($VaV(0I%V$GY8mY9ck3=qZRJ@~NF39*OZ8^^{&srgWdR zU3_mQ5P+npYMAH*SyXKeh30MRtkWt&LpiBs9rc;m;ZuB(om47^$R#w?%tyT1M8i)F z6%hEf5(iNBnnWlmP^S!w_Ml1{S>KhPN`JUS9kTz19zYcXmEw~BX%LDexoc6q=w%`g zbhz{^>_6}f^`Q!t8~9LA&>AUZl!R*%rl(o}n<~+lv1ag=2eApNDdt@`+lLX;`Tb=z zfy(c%9HVwt3Q@3dRClB!;!cZx@-UC!;zk~Wt<1twYJ_+53L8`=!fmh&EZC!*LrpP< z-@AAQkFu?`l!Zd?ka-knGc+_Gr>!`p9pY`_l%NbDS1pUVv(p)IJtm}6U;wVrh_)S~ z#lwX_g$jzSN7(|jW@$`eM^_^{Du-mnD$j9No@@25i7rdjdD6&wn>^@$i_iwX&?}1* z!K7m!()|EED;tl1A=g#jKa$nB)>TG2DJ!4f59#<#yne)bKz?3Ttp|J=3sj&dxr9wI zL=BihD|TrxM$`yUR{=~R>0CUrN!l#MAVt>N$)w1#{1)DUX}nX8$m}UcS{l?QZVk`` zofk;PHi{u|*6T70dAo(E(TLC;7BwQs!bfJGw9n__L={l}kh%|JBPRfODccnZc~BsL z!_Fh5LL@}aAs5zbZ*ouo*(wLnY=K{|n89HJn@EKb__;tbqm{#k;>#CU!7R#4H?M&k~u z(pftJLO|um%3~nMoV5jNIT2tfBGA$XR97X7JG{1RUX!(=VJ++Boo>=_l)!ggBqHLK zq^aWkLIni1CYF_4#l@j;he2Cu42_Clkk8VX5|A=_9C=(^*(!IJY58kX@>jQV25uv} zn5HS-Uc_>^CRvFR*)9PGUwA9~k*Av9P0#a;m2m+#DqzO&Js^zQNH(2B#~86Wy@IgC7|nsOMxk&CZj zo7bBMcXi>agiB70d9~cP8|)lv%)2UE&T@@;2dlGvjd{J)**-?Yz8pS+1$mm(Mt!H$ z8I@={`SLKs@=ErvA=y{|wFi=Y#c--On?0!|8swJd5=eF~VHBk$N^=j|5G~9iAAB5z zmZCcyTB%#HjogaGHr7~t&J`njD1j+u&)6J6ybvtJqO-D$NZIo3!jZD!k=Pez!qo!O zHjb8|1Y|9qF=s!y$pLdO44BI>T8{RZF)-Yk4v@%fQdD#+2Ut>VIljb#4>CkSkoMPO zyFl6UPTju6j;*XbB-Lkq`Xy8>v_b_($FO&jiW9piICNC~l!L1Iy02pAf|xLY5w-^* zsIsLogdwxw^BZQyCWs#z+zGLjwRjLg4z+oKUPP6iC#_dW>*T48Bu7zEEHOp_APUO} z!~j-*)KM+AA0@yD5TXU?M->%N3o=ik8mF={RS8FWW@uaF0hmJ^oiv}0q;{I#Bjk(1 zXyui^q-f>UL%V6E<8kz!eT{}`Iz`VEYJ{32pyT#6>Q6zK7iaq!^~b5RpBeR|)mg4l zf2cYeV$}O_mQbX~t|@VHMHNVohJs)!tu%w((~YY!$1gXX@`Vm8t`J9e`qbt|s5_B^ zqDoujrf#9g(UTM=*=;4|JZK4GeMp%Lb{=5VZ&YU>(aY-WK%;)8I`bR#P1Hch2WZsK z5?w?Lq_fC)7coJnz^+Ipu;>gX6=%H2K84ALG@<_)HwJeOmArxnN?ySsM#K5vp`KtT zVE?;<82GdZ#I}J%V}1^*_iTatC2VKTXUCGV&{pZ1JCr({{xfz>NM#H7ix7Cu>fXmj2D1x?M~&32P@zF9G3mQ< zho}gCA+1DZOk_(b0@MseV5?E>e6UqT_Kv$y^@cyEK;ZRZs`s18u!yuUhn&0Lxpd4u zd>$S(DOD@ib=L}XjHd}Ft(5sVKk|)yV0e@-Ra3puR1#d=WReConeK(`LUA3ywWiYB z2IDN!z~+LTLvF_BL)mG&sIzfx)c+4>kt@~X{f+uh)q|nPTgwOI)q^}^UK<4!-CSxw zcYanCM7MvE1@l!w^qL3MgFK@lhxeew0@MMJ6%$8vkGZ_W?Ph&@B9E7EgyT~ocU+1A zjscuIdRvep2#|6i#U~2xJjg(_s=)fQ=q-HH&XyHM9AKX`ksw~BQDarhG(IIER1ncRk!)4d!7(x(2#}MMd z=My_x(u#}`dgf>y#+5-E-;n6XrE)M!IQ3&R)ZkYQT^|;r*b_6FvY8uf%AP{V?CiFP z{V&vkXntc|f0Q9?2d8l_xU07@OLi?Zjwowuh1~>R3-gNvKNsaoaVrVsXW!8S%GVvB zD9?I+1mzWE(ZSn@<%uaTt)xNuMaYI@UHrOG{#wA$$I)4k+b=dQlH&=yHPKQd%;$FU)V}n@}6kdq0WVIP=yXu<`UE{}*cGn`MdFn6BFR z9arfbx?b3rrw)(2qSS`;=!S{(q&;e*+Nm~9|8LLL#sF4U!ref|yfGA$l57!~SHPaK z;O_o2_xHL>zm1Oi@}dS^ps}4EQD&|owhOw2?LCL?S~}U`QNQ~mxyk``g0XAue&nW# zDk){@@LKKRD|7B>G#heRX%hO0_UoSpgloCDri3ek;#F#`W(qX0&wAQLjnoq8S9`t`?vxLS75{$KPo#g z4XE0g@uh^jU5t5_hzhsc;G8|Vg!{YVNx%q0G-~n0`#mSYRB22aXt)aJg6Kc~E`Ntb z5j8jLav?cT85B6ez8dUrY(+c{g5x9@qrMIcdte$MwKE-h$w1=VFb5U?^dO;XpVhRf z=TsUmAPGwv#`4^aE1i2(Nw3m@^N2JW*!&rB<~Ac^-oIH@2|wmhb9Q$P2`10K*KdW^0F{oc$p6%uDBy41j3(=>;-|vvN*?O?8hx~mn)B_~nl02REh+m>udUmghmZUM| z^qT*?jyV3#e)2~mxfhXaT}>pdXVhU^1Ll1Pedt{L=UN|t`QIswp&d6i$C!Of7T~Vi zEGyy=HOYm9sKGQN^bDsI@Ypz!>(wATXG&Ds%)#enb5%Jpn;wAYfd|w}s9)s%C+SR8X&) zhoK+>Y69*aM!Nacq)FKdQZ=&DGx~sZt^g#Eo|zC*HK5jzivO!2&5MWhqF*P2R5cre zR0eb|NH+_K&%j*8Bzz-+M0bxz#Apbd51o*Rq6I<&4W|TFG@LVZaR)`8`c*PGRhuz5 z+esc5oFxj*Jiu9?;OrC<>Tk1!FXU1)fwQY55u6f&Q$gB=Iu4~czg`!2z&R)>oT|+j zoHD)yJDY_HA1LNG@*;fHXTR+4v-ZMbSgx=Q;9fQX#`#?P91EF1?-?wP=|2(T;0go* z5dgxqh2nvd%sOOaG8%@mP-q12t3f%p2_PD%ijvKNlD7j=^i83Q6m6GN7Ok+0lG1^a zf2yL*v7&;BtZ<)V7bUWRk|2xLoW;iNj8_u%26u=Q9V7HeNVLAlwZ1rmY(^xL*hyE$ zMM1Pb*R5oS$DRgo3$l`J-6Y?CQ>lzP?vCBR(s4h+1sSnNXE-12<$6@;eDo4@4HmIn zrw+@oS_xN!)Zs#g!W*6HBwJ8epw_13>i4?1L#URX znOOL>Fxj*X`yXp|HYHz4fzDB|NmF{I1-O9TuvlxI-M;D*%<#pfCRQq8E){Dg4f&v8 z=*(=ZM4Hz2!Da|FnpUuyA)!7U|FMn;K!1-%eA~Ia%DukJnB7K9p&22jm;;s6U9XzO z>y3G{@L=?-0W7B&DMJ>}4+6qLF4uEj!uI(sCZKGqgQHrs&^OU%yo$qr{Gwl#814SN@LSqTkok%HXpAnTV zq+Ss!A&=V%Yx;9y*xKcw){FMK0n@4YzAl$;V|7O+7I5PNYoI@un#&zEPkOh%6zj~G zb~x6R8cVK)Y1mT8u zwnx7jc@YO|rMzM$Eqj?NdjZSdsj44)6Bs@eH=GQ2ujjkS$!j8d(-DI139_CxuLj*% zQT&iNibKIgSoY?ZW5NCvR#-K?uR1(86U+I+&gQ-H_6g+;`R`1O{UJG|n#_1W`ZUj= z`>~Ed@oyr}E4g~rxMev-hG(;xLC9EgKwxK{(XdVgi4sXozGXIPrZThPMPe4zLOKyc0#Y+0eKV1O(Qr%f!Vb2K6C9mbh?%AaGHb^WzxC zlEX`jI+$)88yU7|+;F~d>VG1|YS}Z^dSK^);^R^B6v-T&i=vSjlKn);dJUoC*_=lx zO5+6xYl%8Mra*F%u<7*}3Fqo_MM7&&^-_Ozc=Gp<#@*1*E^+Y6!_$H&zaK*#7Qht_ z)E2y?O;Zo<)OT8V1l22T@>dD@c?-5q%$MvUAgdbvch)FaA#MJ8eO_RlFLgjiV0Kye2rv`npnIcj{~9V8e&f?-$~} zCLa47YG}a`3)e2;&&9GdvI?k*AF~ukJe70Hao&z|{?XT2qfX^K;5ct_oYV2)AC-J1 zD5Jm0nX4hl!%?HJp;ji$#*$si#*n@0=118B;ZF&!we(IHJO#J&$n7aSLr(5_(Q7AebJqF)X$H%=h@zO$_yQN;u%K->QRt1nE zDFEUu?Zbi#VS%hHk_*6OapIaAL#ntffaK)DK$4O(Bkgj;=i(`80KG|74}bxEyO z1t5ClfeUCO+vUvSqz+Z(v5+E9 z75dUb!7ETQL>1zCMl?}~4Emv}Qv5fGZ4T;DLa+uP0Lk@Q7B&i(vu?o4%(-t>|B}+c zLP8hFH7;40gwef2-oZ8d4@XM;mF#!OdFsFERen=K+`wBKVxO1js?p!E zu(s@>$eG&_EDx6!+WVTbtp`r!0|k9#1SA`eF~83&2y}cKoR9hWN<7ADI{WdJ&d2xD zRzx42;d~??W)JShDB){<;zw-3Q6vEJroW;&eppG5IDUJzaQrz6pv@?$*Q>QSO#08gNU&I)N`DUF4mR`GgKcEU2N+m^jz!hla>37R@h^0u8DY4 zflx?Fh3h9nV4Cuaa2_aGJyq~w*D^zAlty0zv%8b1Jiz^bB~c^SMS4&PN0B2oCqf z&=_HiJFvZGpb-wrSsSJW-o(caK25QQr z#JkQ}6}>#OT$X3X&8lqTtO|GUH1z7`)ojOH#ntaNLk6*S*?xO|>+t}68dngvwfe#H za%3G0KT1Ij`|o^7cZCCw?NL`~yk0~{R?vi!bcL%_8BSfH19aOJid69xB8}(@;ZehG zWatrUuC3HWb2#r_)y+XI|5t)}>$<35J{*V%=3q3b1hZFvhhREY-7{kyGWK&NnGRic zxAXDqE)l%h`Di{Lp>wlK6Uh#>m9QM@m)je%Wk)AhRl)?t_SC?l#HMM$E4VE}Oj<`> z8Nn~IhD`>I;b)gRoVWS;;#M_jx2iswTV)#rm|6I)NKs#ZB?6K^1~UK1NqRVJ{b3RT zn+(7%gmJ(o392%jSMXwnzNn<21D_n)Cs2f2@IwpptN8d?U%%_-B4#9F8e5~q^ZeKS=&uF_UfB}Be7hn@7T!|HioG0;Kqh!W=(y#38K=bu>AaUfizaRE5 zkLYe~9!&wPrN7n5y@p18E84@JE$n(upO z=c`Fj^m*)m39G=o_4!e@(r6s@#Zmp`apS1Xa>g1)Mbv4Iv1HVzI4zwECkg)VQdEVi z#s4Kdat;_4u?f&L9)`UY3~vZyGefq!J-pEQ`47waS#UzJLKx?Pl2a8xYo#}iEr67&zknIKy3~9Y;>y39aRsBjhNDx2 zR_N*Sg~l?Vd^Ywrosw6M8WoyNigXZBS(=Derd=HN*8KPqz5w`r&DbV4Iy4yS)OI1+J;I~@ z>8F26eTRW5A@NyLo2c__OqwLvVCz1k{x?z~(xPzn=2_CL)|$bN-V#k=#IQGYwkd6L zInILo3ONT!tt(o|YP)*w8o2reZn`3^ZDnXl$HVYejyl8;_CNEn)`O*^Q|ZCeptQYu zP}QXLAZrhl%&YR~!Q;RIS{&=c!k8ZHGuqaJnQ|t2FhiYE5AH7PxgLy%VSs|cp$G4z zQh=L9YS=nFu^xQoDz6@VXO2eTAVI*b2RHq~)`RcjOzXi7>Xdr0O`ZM-J$QlwC~ZAR zdy$SFeDg||9+VyxGr(zeBex!W=NP322@v$)1rNvT!KbB2cY5%TDCNi3WY{d>s)Y6^7rMMiO< zerx0q9561sgo7K&DT#4e!(^O|#vW_lK!+%xq=3~Hl?kp3_4QU2X%KLv6ggm!Aa>?!d;&vm}bJ0~;?5b%u?Xo2i9@JFxL`7mN>L484t}qwTX`ld5N?3wBplS!OKxiP;9akTQN9})LoNCRTL)B^rxm0{BrdnT=xqtu8OK7f@|BqIh1LVV+RQs?2IV=V(T**SN zfY|iQMX!vI2jZI*sxpp%*soO?rKVLttW+qj0whH^50o6P3aNx}$pT{iRG}*Mwli`v za4^Y7BMi%w0}zDecS^wv)zC~IRbvff8Rza$N(d~yVyHi#?d4BNeo+tF~!SoPR3)P2nPco&_wkR8#R z?|k&E_Um#fLPGd`xnMKw|Ki_TDr<(@#x|u?{D=BzuSyT!(|28HC6VarSf>XCUq`(=w*d;ze(lG7&&d2d#+UJ~)-C^1X zoR1i$wf=OU%-4x3qyU~Y1g?Bk>n+n!eROK7zFfG*HN!9uRsM`pdm<{0{!{d29wa9+ zjN9OfJExzIkDio=USujBT%Cf63}@yzkYK)cI<+T^iHHhOUW>&q=LoA)u2pP4vKET~ ztdCm6D!r!;Z^!`}9s7$H${x7g*i<|zoASFGyIwC?RlI_oyM$@tQ{-}KHnQdX1OmmDhqqL_$b&Rc{0)0W$8c`G8r)`LJ^+v zNK!FZQK?)jk})HnDc3JBITAU>lnFRhL|dFsqCsigHHbPMGk&BP0uQ7dp5UIcf8?(O z=kcr+_xVTbfuR`-!EIwbBA4h0a!&bt^-0hH<3R+E?0qIQFt|{%NCSfl(u_t#ZUR4i ztr=GeL_HlQRdSGXv$M)pwvPIHP~}OiQVE8tQiOw6&>9)5k~6s}>TA-QWfta3%adL> z-pq(F{58YW=UA>%$(BTLgUdv4ebY`=>n@Pl>`82%#@dTfH6V$dmaH;z54Th|`tN_r zB~lCYCCL-H5k;(@-y$|fq>W{Nbxj7 zNU{aTY!-9xmW5s}>snpbwhB#a@#JT#%dpu2A2cXyTdD8&HD=u{?^0~DTw>ezhFXZM zWY)Gt78lF3oT|O7%tfN)_p5S9S}AHR4wD*K+Ck^jW zNF(RKHd^X>>S6s2asm=`RpDbfFve6 z)@aD%H5Wy6_AzE3tseHVAJQ?#lPHxX{DpomRSA_z@~$?}UsJP>F-uYT<+9-F%oz3i zDJm=K_qC}n%Auc7Su%IqRPHCe9*s+v7YMf_7gvndi=}JD2o9C4sclo8)OAu_^%W15 zx59K-zCR0Fytj|kZYq+)qtc{JS{&iYMrjC5`CEKB zo;pjk6SN^oC+rLRC+J5an+cRCXYWNmm(Vz_zDr2M{xi9DFFMJ2MDhUp^ryXQFH9m97;CO;9fxn=T2q2WtqT`OU-VlugqG^2KCgG{!{ zeIX~r^$&`ik~7?vKU{#Ew&B4MAjYf@tdLyWh6{;(Y@4-_>Vb3>YlC(`ZeQQjhAB$Z z%V2V?8}1aEPEv;})Zrp^`1B4w6Xcuzq7u zmwJp810Sgea5&!PgMfOFXUvnVTfrTYVqgb6n188)@M;#Z;JK=nF*kV}>4K{g|PbDltYDm!i01`e9rn(@Bo2nOs>T1Ea1=*v@5S8uxSGa=Y-c zZimWIFpzHrcN}Ci%w)5{&R#~-dFl*H*)GGGuo#~XJehYzS!WotWhm3NLS>jVW*zE$ zb|5eGvtnb;09=lK6>apJc{=l2G2PLMnI|$`5L2OMhIZHy~*XWR~XF=v_hqq+ih#}ceLTJ0z^l9B68_BJo-zNR(AM@q#fE*%Q zxy$)Zb?cAn@CP{{7$iJtco`+2h(4Z3DWkXL|F4`f+FYyn0luN- zM*;-65cv_Qz=g<<$O|q?osxwJgOaSsIc&FXM=vm}27a9X{ulr)4geM;0AT6;KLr49 zFwuq%i8ZX@g*{X=>vnV3Kl5?qSRJpjF|N`CF4BK&ET#Y0SSIN|aK(i}Tz%Rf0zc5W zd zTNINg4c~K>WI zIzgLX-}eLC^s6?7Bn>%ou{)b2X?UOAl53)FdEGvn&7Ik5@v{2Vptc*vEXjw|C9{w; zhOvymGAT(#rAJ7@VbQO3yJhFMh{fyc3I2}|3(E#ETrS(T{pTC;0>LnAWF($jrst{ukhxx5Z`WICg#~J)zD~@D*s(SCK_wxORBlazd_n=mj8tA!l?(uu)-WN8 zHB`~2(ck-Fm)ZROA$2Kc^BqRtk}jR^0_CvGUXq($G*6RSZ7;u%FT!kzVZKjSnM-UM z{dYTCn4t?Av*@QGV2(0CQPZxMF-!ck_zea>745P_M?-%lCmZlMrFJlxS+`#isBrf z)v}HZ{Skepopqvv*HV?{8cll<*s#AfC%)%URwLWEky%66@QLh`wtc0#-E>BjiqHN@ z;ev|4kxhmD1m5nUBS%6K zM!z7N9IPXxY~&`qhY$Ho#cY&(T1LK6tzT%3%%*N_jogfbl_4)!J3`V1zVp0q5=qQN zX$YT4R(&()QtEc790FI6uC_kj^RF(A-(O#f#<#G4nFWnmhw+toeLPTViretjQ`_~G z)9kgfE`H#8N3WVQZ8xG+WQ=2o@Tk9Z_CW!Axd|TltjufFoM;h?VSvTr_MB*Se{Rdj zhzuhVFxFBPkf}K)*73rl{<=G^(#NjG5)jNTH*VXZ!HaS>~iz7%5p z8%3m+SK2|w{3#Axa+vfS;ur;&?dN!kz>+=&I9<6l;A=EI1QpKAnuBA zwzGiE6GGh$?BvR?u#-7&Md05-aOGquf}hiyqU9p^tyPNPQU?gm;x1Z&;7>3$5C|?+ z#S#20QSYuwPe7%vNyCBKk=>R((0pR6y1;7mbeT{cGuet|knP>1lT*h91iiqzgi z6x%-}-}AVK;u73!a^nlu!%bke`W?Mz?kyW^AXnVWQ-u;MO^|&DT)!36Bs`mS0bgxv z6{imFT+IZ>9yhEKQy~S+-+$*6E0(qdz?i)&EV%mCnqYe<{$bw+UXX zH9W|yS;KD(0pV!}Mx%!lYMzwJ+|;)ISueU2(_S@4s+TgS4Z};B6785^G~7tj&CORF zYQ~zeYU~&L81=`XOyn#UEM7l#7}PkTbc~@)XOKS3C_nKo5eRYXZRy;}`6qJLrg|`bM^t+YL;pbLDnVGpqZg2W90b0>H`OKYMmJKYsuJzZbin`}Dp(r|WZluJg8{4*1)0d^^oD zj-2jv<75hW2R8Y*iw{1FJbEMWu_Xd@Xf$xyk(deX<1!@f04 z->C`>`=mu+UUew`mr%(sxCaX072?Jb=2!)DTti?a?hKS?vjm5CAO;Cs4!&%4vEzfqgPq)6^rQ3QOVZc5Zy{gbi$fzk7c(ep(E`Z44(u_Z$n`XMX<{x z>zqzoLz%ldk7e=|yggwvTIzawKm~p=#9gk_)y|Xk`p!nC2-9DYYZbE3m*4E(f&}q9 zF3y&ub=B20x8Yz$6;*CLkH7()ipU3}MNCHGY z%#8i_k{Q}Il9_U4MXZq*Dv5uq0bpZ+dwQ@Sz~r(J3X+Jxl!?3(VTqK(n1;y< zpL0S2v*kPN@*#0K;g4iY6WvU5S5q0knxdV`TgEvg3lQ%q&fZ8JE3czzBZ8wy>CmDiIw3s!b2~4UyAB(P_(ea|57zvHo1@3-v7P3m8t+mJM{ouk-|Y z!{CNo^1Sug==Puw-3Q_fF(o|!D+XY4l~ssOYt}~d6PSE9ON%;>jWbN=fEHECUJTF5%EPOBymm)zdPb9<#;8a9_ z0;%#sw8$kyIPK&nTbBi+2!?jq76c{1XFU`J8` zQVF0+hKISghM6&wNh|m(5`1kC+dT9mtmRo}s;WPWH$!+~`ZH=4owYm8nS6+PM#Ww- z85V`RICDfge0AY2))XQtknA$O+U%|IX- zN!H9Y_DsDuLScLI>BK5m%?j)$C>xU-P?R-1zDF9-&~=_cIUtJ&UB&Xc;x0tT8O%WbNkZ z*2g>#nAIGpMc>m(bVCd%K+sXLx80DiD*FPU1DxG{9V+RE;+_!W-j_0&JL- zJAfb8VC`dBZWgw39FHIho6lveyz5x(Ifv%RRY{?Ev49HKu(ITMD;MYD@?Hw>ou&;gmb8^D#x_xL$gk!JBQyN;=x=m-1M-WrEIliH3To-dRXHL)p?56fqw%pr16Azjn^b59^;1;EijR98l)xiMWq1wTA8x* z8pi-8RC+hK$0AVYh%$SFdk!Ra!ue$G2KSaeT*}?xo}pkCc*KrKBfB3Ueh5sS&3K?> zb1rGj3x$Qoe4ECRLZh;QfqE8)=wz&810ntrIl%ZOn&gCr`oXNPV2(LuLsAEDvlkri zC($GMFR8>_D{Mb~Z1#Pr{7?9|*z*vzD>EiueiZ72Sy^jCozU%5)r_-%(Pk>CXqNr9 z`!$dK3WYxpt*KRqu>FQpuX8%Bft*Lthcq-Ro+y9-BEG0O{x%+uVen;a1r*a&Fk+qb z8GdEguFQeZ#^P*P>{A4A`vr^wm&*J-^f(13y?|%_+ePr43+y8CKiMv#O2F&?^nlw% zpnFD+&t|)(7+}<5h}B==(Cm^wgGDg({f)_$Mk$5QmDVAP>XMVdVhWgz;*UF)9f-d_I5n@K{53=drT|2I@j)r;X9&N{}`4}y#}8*obFK^~!J&u{RX&M|z{Y)sua>|}KX zJ3T$@MAct7=-%I-kKklQr3=?4Tt}W@n!#|}PcQF+y6r(F!_Z(|^QTnF4UarW_eB2U zUST`+)z@*>9B%u9(wnYJS)Qu$u4OhayQ+%9kMv7jt~Oh%Nx=6LHcRsi&4&u;5b+kf zov2NutC^w;hUWkWS~m`~#s&+^DpPouZLOJ$u%G{}#n&VipP&}O?z)mn$CulTPGYYUTZZ&L$yUoh z|A4_tY^NoT3j|79$y(%n!f`c^SsRB*Q|CrW*uiozz4Hgoe6#Ac^Xm$@bctC=B$rb25lygriz2WsRu5120==$V*la^{&VG#~a2k)^vm1aI8rU z&wgN+D{!GmrM=p_DhjopP7&HGM4ZAC->ozvf^yib>Vkrpw|Q+=<|l<0q1H_iLDZXz zI_OYjW1e;x!?mF~6Jmug<`oeVVB8`>^GsBP52#ju#XttOYnvPgX=#&C(!bS-v9)X7!68zY z{#DF^g|jaGtmP}M1Qx)+>h5CaZjg76mAiat4(+m?dTExtWQC4Ly|*1} z4p1X_>YKpiN>~L?neND#9Ss*cMeHn;k{#aOZN*vLJ~=PrmvJ{`&tIi$6>K=<2(&Tk zIt)DRMgWcZJcYMP)$l+i=k^@RS^TvhSD~BIRyuGVK!YC}l4X)W%#d1KO~kt4I52p$RP0gw zO&9)HjudOuba)q(7FXB-`Ghj|k7|W{PF~s=S)eMln~7zF04W~;<%sT zuM+q|&DXXvk@BeZWD=doVxNNllln0t$i|ZDPFCo~3VzWiytyAd{9x?gZLtY2TTgp< zTPD0|d!!)0$ceA+hjw3hpUD)wg%4A^>o9eL%~Vdt?}eB2%h(v;Mu!FHIbiW8gK6hw z{94oIRC#CvVtk@4NK-uEI@#?x;Ma_EM@T~b57jr3}nT~w!GvpKH zKRVMdmuw!X;$uc5h@4a~qQ+846XFU4>#9|)`c~`_4t4?E#3}lCOH?BrF>pb3`q}(3 ze&TVBPy{rm>nhawjEn8@8Sb-=(NGW})gaWGXYY>37xVezY*4Rn!uSY=suQ#@fEcX% z1V9+<$R$7B+Hg3&VmA(Q4$*K1Fg_7U*dr768jr;ztE{h5;M(3om850rk>_Ysmz%{- z(@8D}%Tn@^4oV8E73YoPK4|NZ$_XR`roum3r;&8pYP1j#gyfQ!Jo1uHUf5TeR%HzY z9W@i{)OYtXUO@oW5rFa|MSie6WWW8^x#8QIp4D}ccz3$&r0lo1T(^7q!luJAq{RxS zkHc$gaFY2qp&NI~q}CfZym~qYY&(6C{q~B>502Y2VeXIitE)qm7GABw7me7o%4X&Zkh;03U)jN>W@Q zHaSJuh4>9UZ+h=javrt!X)gg=>vm@0b?x$E?R~1;y)>mJ?V$8of!T-Ah2Y`zsrK~F zbvv_+uf-*_LLJ^SaL>I2LR=PJmHl?}qe_#`OgySoq=EWzbqLa^+}%Xg2B;mY*j~o@ zfCb#RXm6`g=Ob);9H$ju1zNrgWqg7DE6fd1ufZ-;xB#z{tf9kINA8b&hJ1>xjo1t* z2@S?PmtSgDSv{_nup~_qA#9TD8_!4`2B$18h#yY(*Xa;Ey1zJo*m^#QA~O(S8;cC9 zl7!m!7_mSpfEGapek73qT6dbacGmANYxw(~@)(#rjnrWboCRApnTKOSUir*;q>L|N zUSuTr?3v9WBhmnt(mL@YjGs=`GZhfggE*3lr%8AiXPx>chBa{?4(p&$xFtMOe=x(L zqP?RiD{_~`Z}RYiDRNY07g65B9Uzd4AsWboge5CNnn5x@wu5BwrtUq7D&M0oXa5Oj zDG9W~MFwyYbdK~g(OdQZtx5~QF~=LA3gd36L3a98iA^sX?!!W4vIsLj^{kN z=pbw`-IqQO!_}gz5483z)juS_Hzh$6_I7*IrO-K%DK$V#iosjI(%)%-hDc0QVZ7hvK7r}MO>(^$4NKnj*s zN`eiR*;|ZodS5!42rPg+e@t$$&7f|eLC-fjIyaiA8!65W>^QN;GCyr0*Y1}G$+i1o%YIWq5D9ICVfCRV=E41@!sKBb^<0Hbu75^;P7cQcPy!8PzWe83s^1{f-tn5^tMe1hj5n zv~*nkL<%CoO?^}$&SNpnKNUAsIgxV62@%DzK{w`^{QRw&lmLxlP@NTTzSU?T>e-O7sObOJS0AD;AE6 zJK)JlP2e?#!<}@t)XntjTUeK|9`FcAb=EJ(3DFRcoDiKoVRu|{ZEewEXxY~mw8drZ zcq}74XlOq$ds=l%3Of=k2q@V5IKmp(Fk#J5d%3v68iWm*#i>PtzZ~lds~xbFu=>3mLs+#xnZmNt+QZM{7!o^H zWBp_Jqf$AdLb;?r5@A9UHm9)k!WVIvUMV@mJMcjR!mykfkncw~^n!}?(pQBQL z4v$35s!PoqN4p$u1g7Hf;8+~4z#bR$J5(uLK6V|Gx%2B8g<~F3?J6|Sr2`w?SQXgi z61@?O(|P#(;uHL;q$Ux^eBpl%O=Oo;pt5jT2T8ZdOS1ovVh^NT zD)*KMDd5~@9E6<4CyJ2DACqh{4#i!PQTbzX^P2GG$O7^w5m>*olN~l(eO>v4Rx*C-42YRQ)vZ5~!9N=&rgO9mx&Lpp_%-+HsPO?S%hsGtkBD&KQZ z66}0efOd`uW>`|qJvq+)+N|<25QSBbL2VaqjNS|(X1SCTJ*I;&I}2XszOn?N#5#06 z?N{Qn-6}qNwh?@i-Yz}`6Wi1_$!G!4jjHNd?U78};>=;BB{1nKe8oyX5^R5x4hY}- z+%BZ@Djq3jaBu&XA$v5=lap3(RRsh_M9`a$Vx z{L)(^FI7LeHS$9BGv?OF+;V`UO}j-8YKwR>6$+~@;HXm;fYH|$XTH~phSS^LAKo#oPQ{r|%cJJpFTc76!W`GEAOY(;#4*(=xDB&f zi$??8t>KsH5NANmT&w>DY`=N;g?~<-LzdMYX_oOaQsG4}C3=yBwsz=tt9+%DUVVb+ z(ItHQe$vvc`eG#3XXi@``y-X~5E`rsb@jGNUQ@}7Dru`;d0bsRsFHhCGF2rLRC0$( zMyX`DN_2i#tE*-QBT)JdL;q%c#QCImsrDu-k39ZSVM=rrCk;>d1f)^(@2q{?zz9PV zXeXmLmc3iBZ4TzaDAPG20a%H?2O|1G!5&MeRZIhtS#vkH0%13*mNKKaX!-`RzfF;o ztB3>*z@>lE4RDw~og9cq=Nbs)uVib-4%OrUN$eg(&iEcxpz2)P)e=qN2cq(G+pq2E zZ&mwMxu^MJ@ds?E!V}JxH>Ed~5e;YoeRhv48v*5?lQ0g0GP)|~X$_&wq~qbABJc2b zBzOnbIdEynoi5**t2(51%paqH=t~d5K2!%VNX@#B|>N|-h zm`syMvCe#u!YiVIa^^jVf+4Nu9#P>xYQp$B-tX%s_&P^y2@v+zyD{4?CtO+m3=2Qn zpWW$!8RxUjl?JMn>E`h!23&*R7U)>`Y&~mUh=d2{rj~lfKH6Lh66pf%1}YvW?8hCa z%>`So-z-_aR1H|Cfx0Qzi5^EMyV2uQz$Sr7)@p2JCbnrdP|L6{8gJ%G1JzpC93^&{ zyClVJZ^?RQi>fNwoTvJ*YW?cA*Pooi zz~g_(pY&Sm@h9I?{@R~#Z&66=1Z?i&NDH@=Kap~J?=%*Ps9~7{`vwl66cb2wyJHQQ zT*zRI-8o0E8wqxOsg7@WY_L)le1kb4qslrKRtZ$;0n2*u;0%E5Wb4i9EiLw&Ld89GuGeFep`y zayEXU^v^*;FYpQ{d1!qB|LI9N&oq3rFfg11|&*L0^TZNq87%9r`$w zg!`z4;h4;^fp4!+V*?z@!=MgoiahicW40rFA{MM+D#&t9IK;fNlKog!dlZR%B(!Tk zn}zH`-V^HdEynP_(Q7j@elI$jpUBJAY+$OF7lqzmD_uyGdqP>c0 z*-{x_kCpW_7wy1Vquz*}H7RD?@ds-i?ez8yOf6m!-N8A6LBZGt(&s`Ua|0uNP8_ZNg^~IUr(-`V?`U2y-9N4Y%LHq}yHD87* ze?iN9t&HW$l8w-fpU6ONJcf8{WZV_8BS&pHPp$^DDrCqueziRW%K=tweDpO}6~NS2 zp~QTDDMuyuwF;DMlsLA-i=n}XbI6q&)S_F9t00_nDC>;H{u|$5#e_Scir3YEYEC?d zJnEc7`I(-xADG1Lp!`0qI~JRRF$Xo{Uro>VMc4Y)X#aFEvjy2jk*k_}#c3$NdPRisex+M5A_7 z#kvcfsWezrei#E}42nPnedufq6kwX!AE8c_p^V?h4P}T<|0NYS^vaDH;DoG9FF>bd zaBy~U$B>qM@=n~Y>0>}BCQIzW4%n!yXXC<|M6B1hmT)mc#+sr9-mEay%vz5rqb`*- zkJxJ-m>iy`t zmlqaQ|J(jqRXxJ~xu}|lE^CCZxQ%n~+C8<^E%2+}`jERyvdzd^et?J;QHDsHOY$JX zT>PKM9|!^W#f``C8TJi9{D*rORFdXlDBL#HXg~}{b8;SwsWi6$m)=id7NKU?^$lSg zFq2KDP4&Zo{NI~3b+|pjNSd@D8FUwEx;ZJxawY|RW3}E7X>mQ1E3K&ZHM$o6cjU!& z(rhh31&|j62Nf{X#;uO5?BX}%V5Mi|DcEHntk=OL%3bRzNY5NCpZRD1R|Tmk`{ zOaK4X_A!4#+ebuc+gY!Sc006?gc-3Ci5!N*FrcEi(5^3beS-zu&3AKzG z#-aJSHx$1YWnY2_RA?9+-xF6jB)m7g6=$jz40>eOUZ@fWW0ia#pUtUrm_}hgJcSR} z%Bfjj@IhK1EV;n0G>AnCWPMf1cFe+*c^7*_oy57NRdw4?vufA+a8=C<$lIKWh-rA1 z8v2ekIdq?P=7ohZXYZ}a){{=NIq7tHcF7;L1${%0WbZ=Mf>92acKhMc`r%qQeBpiY zuQKmJF;aapx~o9xcgiuY@-JJ0I2ffa8@^uLd3!A^Mm z+IHJ9`sfq&2*U5Q9kZ|ijG{IgIjvybf_kR#U!ja$g{?veE#Ujos;^_`#Tu*|6Jem% z?;UEso%6faSm-13v^Pd$CCTO_mSR1nr8O%4bGviIfQ|K%#Yr4^{6l78R23eD-(B{! z#zQpK(XX{YHP{lZ+)evcKLdTP`pg>g$DZ06Ol0)t*O&Pz$DN|g1&#M)0$ONB0)&A% zoATI==|uK4rr4|1I|?;urvGF$C-igL33~7YlclS#WOGM*&P^6`fuG_uLgum$!r@BL zbk>K7p|V@hZ?`Y5@NDqY=(VQ8cNSX)A;gW+upWSv8*}Bxc_($|dFOPprooJ?vU6k| zyH#*WsO*}ooQw_Q&%=)pe%#ehVuI5{WpJ1rEGWZx1b%=voK%J%0|N8%F;!$ZTeP=; zY|fZ0yCuXQ3LHyf7U2%o0&(%r6?F7v7j#6HX*p%*q_bZSBE|F!=0im!2PQX?YVJ^E zAGnwMEasG5iVrSDZF)<36#d;QvS~oDGMLTY_`7oS@9@|5JPs_2jbFl5u-LpIV^yH! z6H2J^N9zx)tnqKiS4(&#cuB&qiGi^aP^QAhNYVKyds@1UJkU+%P3LC!0}i9m2$l@@)ORYn#N)6Jxu~3)WWcsUa6Lhk=ubCj1#LzN}nbZWmkjXvqA99ko#xY zzBo`)s+e<#9@PM%qs^-9X3_9n$6=lllyx?gb+g2iqg#c_I=SXxU8D#VuY|HQo|c|p z^F7!LTc^phaMS8b@WkpUSJs*xs8K$2yZWRAMU|gInw9tjyIkHWhK4?B&VEhgu~@Q$ zTMAgkoAeN6H!7RFN5*!_E(FzmV3XNGbzt)00O%K(cWxqHgv9#bRN+1;X9ea}W@l6c zN_GM!yK-YfPW+OYNSH{lkY2`&{vHl5^GVD;`7YcZG zxB?rG1xiYA--}&{8LYO8l4kqvxN!@x{Y=^I$vC=eTra85`YWuwiQAx#m{S+~__?lO(Ir?YyrPRiwas?$#mmk*MD(U`TXy@h_^}X#9b3$c(u`H%P z3}RS%w-q@VE5@B9KINpGG6;t5r()CO^b7D1r;2#?ruP~)!eTJuY!Lfo0 zeOEv2hTAwSn;uRD@fp7bB5WQq(1owlZ=;L{N;iqW!k!jo{ZX!lp9VB0SVl;9+}VXB)201HJaerMSQ% z>L;RhoO)&IIlQG=sE~5kT}@QQ@B{YnEzDz6h87Gdt4Wj`4}lkSyKIxKbE9c3=tS5M z6+_iAvva1ZBgM3OYB5<@=U3jP4UrlMay!&bJlz&l!pw-qO zn&*&8J}MzmL_QWcfkntt%{Z8<48E>_APAZ=tf@SXA&ZtA=1X#mPHSPBs$;76Kzg{D zp^{rTXgu3~#tD?xnOjld$3?kgZ@d(kENgrb&q%wA^y|^nEEU(lcu=Zx6R}awxUT5q z#!LhbJ8>eyGByQef`f{;%r6+L95X4kZ<5e!T@-ITjw56NbV$@&lT(_zPuThhAdj15|_* zZlaD1wi>^We&AKspC?gX)((|){S7kt!*qgC^;14eg{(8Z5Zy>#S7M$qrxY0M@+=|NYk;N)p#*ec8%s90ZJdVIc0Bk^)c?+dUb*QJ6BVvXbPGF==L0+f@ z*{=%)`H#q~WsNH{ng1ZekLdTPzRV-DJ_|)=r%TROca;p^44HlI$}Gx$KZbl@zads8 zdF+8g@zvwM?81U|j6^t+v3%SJ{0WrEb{w+d@8OKR;C6P8>1Qvwr|(bWACz60oq^h& zl`2Yl5$dd`7IH99S26kg)lu+ac%dq*v@_);d)_ZEy5EEpPar_a*44fkt4|c;y}br3 zw}ogJP`La?O0n4%Y^-OWq`>4d9Jb0KQr~aX;zk3JY>bHc z87f*yt62jn5bUrgAebO5Db__WdXjn?>(S)5OkThQe7S&@+me?8JWO6C4;j#EAJq8ck@8$H2{F^AfjR8l_@tqV4BO+ zl|zy)qZpyr{7==Xj5Vn0BoG|v&|1cmz~tTS^qrHjY+derYv1W!a58q)eYp?1Ca~Wj69l63DFyr^zOtrL zu_n~X591N~pQvPsB9N+3RZr-~b%lJXH=)2aVW))#xY-BQDh}dR{7Jk}8v}BozHbB#wtJ6G_<~On3*@0+g0aPF}Qadu(hY2XK@>JP|0;C8iQaQlD zpk%oyetl@zil&O1L`_AKPLoY)reQGqK-4IhbP>(W)GVEbkU|gxs?`C5XNn;I)>@--DBbvo9hCJ_#&UTUO>#{AsKPZeFwdAiOcOQ#_-uLP{% zsy8o08MgCQAXvsCE)q%*u=3Q6+GPqTlwpbM)II>EPdO7!$#PA>YMrh(DfyvQ!zfW8 zm=vceQDEh%%QYne3QAVvIxtVwhHyLL4`=lfe>j^-1NOalB0)xrO{qoe=`u@XAxnd*o zXAAtYn;kbNcU!?zkfc6Ydb)^X8I!*yj{BH}5(oA&$qGEMBx@=fypBFZBpSFT(iKwX}is6~+|;H9ZayoO5UK6;-65v+ErE1E#* z(nP*kDh?_z?+b1(8+lFc&6RsJ1v)EvRuhY{V5jA+_b9Z0RTA z-5eCIWJy679UTc_s*4HVVc;yqgfH>}=RxrhWjBVa*B}!}p53)kni?l^MYj|R5JSD< z%*Vfhw+>ADfHMKY=(5r?Zx93+WvYBGhuI^+^ESEVw?fpW39~Pfth@7#@|z`vL>d7z z)$u%bIUXQS)J>LWJzvwvGtxz?$1cbDXm9o9UjF@%vs4JVT29s=*$`r(s*B6sP<1dC z=7~Rr0_e?dBN1)^az82|l5?0{AhKd-%U93nL__s;ej9FkDE6>+-Wb-JB z)wqeB?y>G_1o~t!f&pQGl(m7#t9U|_i_K5DfT1r6^2>p>xu9zTCHZ)GL8M6{I@9C& z6z{f+cXJKCG7#zG3*JG4v+D7JuLz(`5)-^deFnOg6GgxWRUzGXlNQ5Bw134fL_)Jw z@}x?hLShbns0lLYaN}#PNMM+jz7}X$&{*ap_KS;=vmb}BrA0}q_#K1h&!%Usy6KB?)*NmDg2Ib3!M} z9PqaaT?~Wkc6)Ebc6#iyiR-AeNm*NRNrvzDX z86PUvho$jl#rd#w{-)IwXI`#8oT5JL=zIto=R=LwGOQP&-gprz>mW0jLbkHHp)D6( z_^ShvSt1~JPqSP*JK8qpW1>li?9O8^MIwG+e547+aAcoqC?W(!jK@IA46OuA)S-$p z))owr@3}Hjlkb6=7atp{D@WGxK{2Vys1B50i)N8Bt_m^*4wf_3Ek9{JmR<)idIt)L z_6@2PJ?CYh^khm_o0^;#zdW0RviVt|cLB3?Y1L)<2+MF5oBEx? z-*KW;*ck3%&7eh6_#FOlRF+-$XZBdnPOavlaPENWSI|9`6UovGs$k64=;vwHTG`rA zs>68A+I%Scc(4g!A>?9xBUjevDp_qmdx&o?Qa2Y!f;sjbbHYtvX~O~E9`Mye;UL_p z_q-j)+wE{0tE!et{nll~m#p79BR*AYCgppU?6IovL&`WXAq7-w))_-oT?h5q#au@E z#Yf130nXpku=S*Rp@j$tHO{6qsr0^M(!feDj(RUyD1lPkX!L`k zzo6Ql&WF{?wN@|5ME8RRrj)^er2n{F4(Q53tTU3ff#@TTsnN@SrEf>_uFq&cDbkTV zL%yZGQxU=qu{-PfbztTT(|%QcKM0DlXG=sGR?AbVRSU zUKM(*7wRQzEXe>_#ggK%A*Kx`YsXrXEPhL}h)J@DS^X5FK!>cO6j_HUvf6mbdd!tp zIt>wIWl4(u8>R+X!+oW7wUC8z5vecvEsJ(OoI5KxV)I%$CUDI>cs&-+s~`EzB=@#w zAjJjNutTKi50NC6a;H&hAopQOG5W~VAlF~HFMnc6k>65^#H197S$*BFCRrO0aX`7B zwiU8gNfL{!Jdy#j@+C!Y7}ExmmFyvl-;yk1k}P6Yx8Gut)lZR?smMC5Ub2d*OprBI zQrHXA29q^mjVUdDOR|VbvWQu|4X3fYHuus~BCTiJh_q%&5=&ZJDIJitTT*mqGHozf zzpOUN;!5|cq1F{@AF>D^B09gM|;u)8Z2S%V}&rPcWaskFKIRkCC?#;gY5glJ>Ds$c3> zHCWY-Qkk%s&0Yql(o{fAHV4-f)+>^#c8W8Y#e488%b8LxNcj(8T$8{(EBTA_F|j*D zcnNzgro2c8)#>Z=I0miv(#9z9J`4msftNYdn{UTYh*c0RVF)OBe4QbntA5{u`HcQF zIx`;5$qBbaR3g(yWZDQ;3R*qIQ(~zlJ2TL9;9w_uv&evqt4Io~V>)3mWg?^D1${!1 zD>_M`!;iOKYJG<+0ZfXVbDZfOAHUuAt725(4j)IRBb?!W$BrBKa zHUl2bFzMOs$B|KgmaTySF`vjsu$$!wS!ME6^mu0lgIF2wd{&KjR?sYA4i-}WQ!SRQ zybEL5jkN9^^Lbi+JwxxDgp@K2&U!=WO3#xE8#f;lO7ksIx#EtZmW@afbPtU>Vk_{zHQT2*7vvoG=Z zA&PLRqVLSdFt6nX30$9P}SS>0bA8T*PuQHkUwlJIkcQ?XI5tsu;lEyqdillf$( zbYh@KLY)V`zUS8c`!EH;$K7%P%WNieYzT76hV#1;%Zs#Y0F_zXR?CbQVe)wmi; zmn!P0?`p06D7bV-)IOIlrc3&U?iOS@gMq@o*hB9KhSq>7>Rhc=Ue?rs1q#V4T!v#3|@U%r>;;H<;qy`5&atG|K%B^OXRN&%ERyT2i zi@p{~XWE_3jRKLyIB$wwpon6@xP#d;F!5=gL{(DL5|}MbOk4` zau5@kIOR^0m=u_}o(DOV)Fc5e$%IS7UJfL2nueRL;U0G2I%zmm3$UEySLt40wzN3w zKgpVL5zA9QmP*%`|8-45J^89>-TfY_673DrfKs7Us>;mdkYyqUx!_A|ROSpd`p}OK8Hr0sZ3} z;Rrv<##P+13bP`R_0RAU>%~e@5va8Xkzn4VW(CkHO26r5eUW8V$@U#)1rVpHleQYD zRh0#%?|>Mk-_?YK^H|Rm`E}F!T^5OOVJ&fHfC~QVxq!CD7qz?)958Og%d@Dfn~plYc=L_jVTQX zad?+O-^3h_d2Kdehrq<1xD6t4#`=~HCSV5*I8_5atO2Jn6(T=?onci!%~|t&L}227 zIJ{d@a|GayFyW5SaLHnm7z~sYqt#3WE>pw(;=rW@CLX2WQUHe|CMq0uQ#9O2O5pajovq#x)TBuXW%BNI{|Pfm~iOe66vkha2qw;dIg8__anw>mGnmPw6c;a z>@Bbgvw8zl7IOr*WN+8N#CPOZO;@0IHPLbLRVe%$7Bu2ht`-~1?{nhU=5UefXWU5$ z15Hy3__-Pb4OeEP%5{f9>D#H@bVYIgn?4k(u&T!dB z=Rnm&5ku64YWx@RKg9cn6z`mjrGZH+Io6A%Hfky(!ZqbshGP;kVwz;@_8-{B@z26; z;{-~_5e?pHDt&}RzERHXm%(a(2vrMp&|a#JGaGe_>CDi_?y0PzoY~Il(a~(2s2Dvv z;)Psi_ORp3lH|!uHSZ@9yuY({W_zZ_aAy3>c4mYu&Kz1%k28A;4`MhomE8=L-CuHM z+32}L^Qr^nR%P}-71E4UAx+*ShBPQ290#J!vwxa4&-kXJq-KaZM`Vt6K2r%%7jmctVeo8G z?i;!n8dE-Toh|if83vYBh}sxU`EtB3i_&)BDfX!x%3)`{PbJrK+TJxWJNyO9-&pOv zrfTn1?0ByoXng?}g+uI`YgtY*!4C^eT!~izei+=tVJ0{(1l$s$F?J*=nubipHC`^@ zIT`B%lh8Z?#dJXMs5@||dSJ?_g1Z;a_e7P0cD^q8N09b8@+C)nFx67%XP}2FX1-jY zG+SBsQK5R0m9)PhODQNYgcJrSiKGcbijyvqkJyT*IhZ~{)+t!mZ`=bY%%OG*{*n9y z1z#z4u2O8tUerPRfl3D=D%N$8BYV3d3Q3N0)nr-lFo4%0o~ihpp*)5?VW=;nAuZ;Q zN!H+xJ}~*5f6h?LIMhYyb5-SVWqt9Yz}UJU`FY!^mI?Eko+9vAj49>j2A zDm(O6GP}Rz!X~5F&v0SS9pt#MUMpP}mXBuf7odQ&#sscVTqO>a3CnBr!tzXMXq#w()tmKHC@|l)BYhF0Per zY}K~0TiM1NvMV@j7;Hgb@yvW+_~iftPw-yLNeR?1$gfI*0(GIUkMRM~irCl~J#mEEqA?<8r^*FRul zx^<@dtfxwzkp$I_tXslv$)DkO{OEzv*23G3MxSOcTf%&SB(WmiZ#=ray>JQlleKjn z$;>{(A+WHnk5sZuB^8p;TTi1FYL`^sf^kagP({(dBoTh{O#_Z1N!fK>lGOcJBz;}I zn1jY=Dk6HS3QOSdncw`y7@O)j}iC8;#3wyt*B)8#T&)kl$=c~_NRmouu|2n|0 z?@*tOQps16{I5uDz&7O8Qe~5%lKs1c?_Da%bMy9hIbT=5LPb}o&)!za(fVs;fr$U% zuVPssZ`W0~dOfzf2VvaSx>)6sqmr{!a)u;P(yFav_F_x5bu(4>V`aL&x){f1S>Nmw z`FyUD)hbz`l9TJ^9jnM8kC;VH-H)C3n;7G?u2b1up^||rIZq|?B=Oj{*e`EY7^?^?E9YXYn9L<)E@dFFmvSOM%0A%{`UF&5fPPp>dU4Ih=%SRpoG1PVCCz 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 z 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͕dw9ycXewzK!nqJ{Laew~5T*s%Pt`!a?qZoWzWckgg> zmP>m_cS?J`Q<_h|+=^}q$z}3`-ak;h6fcgS3#a9Uy(}Y)SKzuq1#(kUaAd^#I(LvG zSlzq>t4C!Os10HV`U_SvCHii}?FKsWDyY(4%%60tsj!xCV4B_Km;482`X zI690zOkhL(5t;KTV}3UgRP}5b;b2K7M#_xF!Xk*%k2acHH|orwTpP4s`Nh4`o)0iy zm%C=yXqtmfNe1g5V=ccAc+V^SwG7*3*AjoDY=bh?zjbKrV%d^O_8*cfwaqT+ zcKu1e^c}W-WP>l;NVzWo@^YqN7I~3=X8p_tSqRMM!vgif_($Bjlhvy>_(P-8eB>KM zk)~#-DE?H6H~8ty6qt$iF<`ZXZt$faN6Z^!M2;3bR-l=SpF4fIXJ<+Hz(BuLCmy85 zhRo5$RgsZ6{%OyA&c#16ENdUw8dump>{9sBh26G#)ss;L>k1MeQ+8$LzUw;d(a){i zO+CQH>ne+y5Z*U5UVm~EzAbDm{P7cmsd%^)l1m_&m1G%YQS8vaV@QrkM$X+JBee>Y zhNR?WE1!{~A8#=!9pzpb;^K$Ht$xhxpru0hL{%KS>0`9GTYiDuug`WYVdqiy`UKbD z{$GCEs!LWT^WUdki|O?v_Omyg2jFD=NNNG0{B#W_?+*v155PM?S4h%~GRvwG{cR{i zG&9_|k8?j9qYkfKv%$YwdN4zoR+#AT;n@>$BQ^#b@!B;-jX2StcG0;iP4r#%Ed4|L z1p`L=#cr%Wc$`?qypxL(|o^X)LLf0KOvo38%v+5EiQ)?S*lUaPTbRAFlU#tAi` zl>Q0C?s+Nw6KX&y{S#_HbK>6BbzvB^$oh}rv7IvZ*P$ctKD^Ysvv=2SJV~VnG6lm{ zSqU!-pXHXtE+8`UM!$yD+_KaJH*%)=c}4oNB)Mf1qCconUFKtqh74fU|1}2iUP%&h zjdjqu2HZDXl3yU{U9fYc?7ZeueW6QpYy#%$sO$Udc>P5D_TF_v*$JTfQ8pKSPG8jQ z?2Pnh$Oa#B@z|ZrzjbfHru7}8P+#A_$6r%u)p3i{Z#_RlI-~NNCzYX7&+AX+FO1(6 zgZ-(mi?kH#TXJraF>zz{#`-QhjSV!6pT%LxQFGZ6%<9J2>%uE5Wk*gZc9hQ)Wu3 zDILkKFj;+jiI_}zjECYT%KUo8_0RlUpjf~5A~%sR8$SyymFirH0%k1a^pSv+wwrmN zKY8|7nnijhT%kUm+T>PF6<9p6Hbp)LF8)Luo6-2k@Q%smtY${=&CX*;>EltF!z-Sk<;*6hm=!%iIDPlWI?UYQJ=OK* z$8N}kQfP(S`) zE8{Eq<})ZS+od7NzK}z`@jW49liKaH^7=S2VMJP!s@}P4WNfdzwzk`<)+Vab&qt~K zBX$2rd4(-W@7s;-yyYHAe}^p6&wW33qrTBQb`^ezEz+OH=PR#BpHn_`z>06V`|gx` zKw;+NkCbJR{%HKgdxPI>FU}(U{g?#PyJKKQkIWyITGir^{t)f*ze6=$6O6Z(4MdHdw33fce9?b9cZe76q`yKk>6?MKx8 zp6`(v9KQUR7ffPWe%spA=hx{MqUir#AHcHu(=UYN`{jw7u4j0WfTuWFxhz8@*%eZ|XT7m7Jd{ZpSIA)6 zJ%7aSY29yo^8DDsgH%?((fj*t$rpswgJ4!adH*i=h5LFFzy2>)&!r#M^!4G1>Bj?@ zI!0>0L1fb}ZKjT9o#f}zU;q7UYx?!xzt+>v*MI8$X^RDz&A%vd0hl$S)N0Jy!js>R zY3LVbBCDT%|Jhm!sGoiR6~AzaUz^1bqVhUP8i~{s#}S444C0>uo2(~lS>N8wBx%FD zHY-1-KY9PP2?OPx%sarGP&1H?KNm#wQ!n6hLVXf1&`-a=ir;_b3UKwRO!-N>agW*k z1AV*XiBuvrPU^wiy;a0xdiq1K#&4mM_201pnskpwd?Ay5f^VwdBmt`LUO*)8-=u}O z_imCb>BRU#NZ%_sk>luFT&JIT2(@P!Z8vSa^07Y7iDvtcpP%Ke&o2B@%Onz02Z`hmf$%w_dyX_N~`#yXwZ9ZohWxrW-fj zxb>=Sk4&E5q_9)ZPi{&h#|-F6uHSakP8=?Gv2G7;FnNB=?Bnmw!a+^M(^fFza3}jn zdfkJnJp^i2{LKFSx#u4_M}ze)4+8O{1)lRV;Blr%U(%Rq_8a`|$!tR1VkUluDbz2_@CKQal$f!7`D1<5QvB4xhY&Yu@3vKI z<1Mk{-?Q5IPi*+>CFAGR_HznTW8ZZ`II?1zqv)cNQJza@{JR#9&;L-#&y|n-i2Y%UCug6(%YU%c z=i5(e{Qn1vgXPZwif!jmyTL;(r)H`^VI^nn@01Eo4Kf6cx!F{4Z_(^?d`%o`U+&ZN z_>_amc#K&v>@-%hT*UVEEn-n86t`Yi`!(yr{b%LBiKR0^`?@jtiak;y@s!Fci zl{~LC`QnKYsQ>;RhndNVfO;^Vd`W2VGCynDAsgSw5}^2;cG-+xHx!U<=VjO= z{k)uV#CO+wW#;^cf*i|KQKl1|A0Tg#qW3ja6i9^{i2rt z`~Upr`p?|^t?ZqZe_APg-pSW5`yc+k=YGGOP-^J+_>Irn*V_I={>0Ee`)7QrwnAGiS5_#|698Y8kN6U_`^4UEuZ+Y+~p?w@RM&kkIXaV_Zs^8IwVsz z0M`H8(IohW>!uTo%6ek?9*k{j_~u(0CBF2@z6Cgb!(NBumtjO^HVtLJJ6c3V{pV#txjVQgo=Z_IV3++GKOBaoQ+(E^d|0Z)htYS%9uy1!qOxdTjJcUE6Ye_kb>uEkxVLGD#&Q)+%i zs(+GOHSTnZ`zp)@92lurzS@&X6{K$UPR80sI+L`WbOz}>(pjXlNjpfP58a1~$2H_9 z@ftS3gP$)R4%g5%nZ*k}u8oiQV9WS+Jx6%QQ+((kjHMgb3&fipgug(%g)u(T03JNv z&7Z+*@E7tLaaz2fOUXx>92Y~Tdt5GX4PD4^jd(0Blr?zpNT*$+oJ<$?Elpi=ZMsOC zg$IQLMR>CXJ&OZ2;SdJAhor8ptYF*nW%X+|FJ*XywY=E33xq+vfZDa$N0}`mAMslH zkv5Ch+7NWXxBMb4s3-8D2Zw9$tS!N|*>vSE0T2eZO&9hp4Um~fdf+U)@hyMA2xIAi zy^|RpY1_zaw5#KiQG`cYEIf1{D;|6+SF>s9NBDGo33TC+W{V5gmKWs9biubWgncV> zTw9qSjHL%*ktU=8*TzS?I=)!>u>CIa7RJ&BzLg%a3~`Yk+&zoTzG3QCWkKUm;B zvERgWcoE0>v$kdJ3-;hlAAC3~Z>z6v;aPqm?;*DE;8}Xp`GLO02|3CJeI&evN52ja zY-5slNx=fc7M$e=<$<(Xd4i8RfJb=5myX}`t=ud>4`X=PNry+cG`9G@#PDW+H8Jvr zxX&TB@`R0a`f&}9{I8-1w(ziHVdT;|V3Y@(^$(VQ%Rltdrs322R-Z^4-1*`mhd%B( zcwp$K%Mbj!=^=+KU*5uUb|6RjoJkLy&WG8DzNH7{Vh(cX!flkVF~EpFqBna2V}0<_ z9_0xK`&Q<_2xC0EhdwF1zY&jcC|8uBdGHWE?Z8Wq$B|j^(q)cv2hYk0HY{GG&9L#T z{(vEeF3Jqf+FF{2a7d%Y3!3-Ba`C_pWGF*8=%O6Jvoc7>0lw8eXgVA)!de))boS7n zfrm7~z4boND~nI_P(GGl*a0?=aJWX^&4Y*j(_A1I;K4@PgJ)%haDqWohMr zaNwCUdkBy5u6cw*`NE~^-0IB>wNF7fYm@kGf(H-ubo0Uh4<0UEX7+oEG=EDHlMd$s z%OCJ84y47}J?tR;NW103Y@S{*?T*Wkg9Ib4Hhb(BsY@&Sx-nT50Vmk#IhF5%E_?6)2^ z^B%gmFU&)3{ouP~uwda)M@Wx(@GTD5xBeM?IMjuu4`pCu4^V_bz9BacUOK;)W`wgi zK@rZ%R4zSVJb2a)tPOx?=|dbyKX{-v&IJX}$}f=XYss@XpqsWS(51)hnJ&UX2lgx< zxHer&A9!$})(+5@Lf>?8-Aivapl=>Lc!V<#Y;DQp#uJeXhkFV?_pQ1C5phQYJ4H@Q&}IeqAWXZ_@@a=n8*K zxHgaUS>Ft5e7SVtkuLBMKhkR+Jjh_vJb2b`%o4-1#e)YOIHTZMU4mzEfDdQbDB4ci zgMSJF!ueuX{2cM%TO4v3JF^2>+Jle#7`%;=Ab4C`c)4`fh#UC_A0B0v_TX8&-YM6; z;?0hg2N3OP5(5Xt!;Y0P z^iT(8A2ja~K5j?Ihy<`aSbh;-oBRPrc(a+dm5vv3v=>V!WN-)%8PWw_J&$mChp<-8 zzFfn0Bp!U1z8nSL>{xn$!AHHq86VX6>H7rN;3K`zO?&X+;XsiF%NOkB(}Xb4xBJMb z*+H47J^0p6UzVP9 zScFF!;1CvRL)>ZmC~veKYgf>RGdq?qlp7p$%~^V2JMF=@`{fn)&Gin7kHmv-2M*?s9kRhFL zzWAlM5Qnmb48IX@2)|N1_;8jd;Jk;-@|UNOS$metj5C{HBA>8}yj%W2;XuKM96Io5 zlV30JkXhKGbV3gfvW?<_w~B|J)eF*#@t=KXgUs$R=mg?B5sCP;9@@ug;?EY3-)xg1 z{e9v=%|ixn&e9Ay_!eKA{Gher2Tgw5e9ElNY7I?j$5<8pDP*Px3K`-@{X%AApEeP|Zxo*80didDJ^0opAcF&iZOE)$gNJw!2jYax z`Xbz$NFVCMWYD+#rYZES%q%SOf_O}p4sX|xEfx=lu(KqBba}xR!hV`Gt!I65B(l53 z-z)we@vw<-MGi767hEGQwBP`{s~ly9X?tkRdE|5!UJmal;{; zl{>-!qm1CL62(CLnG&E&yxD}kyoU^Bl^>4*Lxypx|AU)utZNQx^#?KKyF8~5iN68{?UkRxq*yM`@(3F6XmuFwwgxQ7Grki)|vosc0NC<9+SWcCg$@{W4n z5?^)xvtAS)jr9?}$U`6Xj`Z}=TiQS&2QAVC&*XCH9I)9mx!rdiA^@*LeiS32R#zyW zM)s|4k@xg(vFX>-wfK=9IJ60rEA(Is^=j!Yx~IT{9C~n(c%%gwHcTJoXKCn_>j8RP zLm#qw4sxUg4ixs$KFucN>H5fDLyoX;xW{n+;J&y@yrs|Dr=>BFo2DIJ!ayH!!lAFm z?=Qk5EYbtH-IJ(Cv^Ct*CW9Q~95|EEcZ*NQkMQ=} z0sD6UBF}J06VeJ9@(f*gD=U*DjQMmJge&q0lP}jahK}{uNF!t@>$#G#1>(_nBaD?3 z!XS<4n@|T5}P@z=;z9RY0( z<*`(})w_j3{$LZ~E)@SL@s=+O109qVY!8Yb5dSP<*hN{?^Uy(g!NJaE@iU|_FlI!d zpl%Tcal(O(>u*a#tcw4h_GCSNMi{%7BDqGIeDSF7 z%fzD%APj6b@)kyd)pZDiyfm|8<&3s$Z3}5XPdv&4c91_fUwj}Qc|g7)M;RJMej0g% zv-o}}2}9XFM|hF=ugLYM#NR8|2xoPU`0IIuv$3+M#_7SmJ|cd*_#yEKXZI4~M_rzXUoF|1fU;G!Y6fg9PLcb{V^WqT>9&Nml zM;OG9_!{|iyl6C?-I6Qu?czJcw+XKUe6b_Z*DW_IPlU7juzWsOcqseliAS355sz?< z(q*!=y-0Kd@n|3T&6n=MJ>MY=JjxVlY~(GR1atL(I)p9!hQS`n6m}2}>2G8UGK8~s z5Xm(%I#2w3@n^vc3vCBwg7B8FMigONi5vDTY$JOnvotizli9U<6y2XhX#&^M)Rqizm}kHm{Xv3-;GR-yO0YYlJdM&dez?VD`7M3@jHOFXZKPo6gqJp0s%L`N1hkJi}m1c@shLPUj4D! z9J${c)Pr*pq)WVnaKYu$bJ>@RPVvh?g@cHjkmm}2vvg#eg&y#=ox%wEHcOjaw(OwON*>Z- zEFMWxrX4oI&_TO~yHNZ^@S^Z;q3?y4>-&V>C-kt;vUuoVJOZRNhPFzCB+jr$J$ z9Vqr9`%OXGaBcSl@_jyv!|UigU;G7f zeKGtg9i78MufX-9j!t>U+j*{d=uS6(mQU!SOyQ8;Kzv0!?!^P*eeq@SNE70?S3K(G zpm@_gEQ-_hmS)(Uu7|F*0qCA5{^8<3Bz`TtBoNPzYoj*rQt6m6_PRhk+BkGU({2>bi^D@7k(lHxs5yg8&14(%1re($gH zg8Og}Zzc^$y_kAVj^{D_9-c@UHPb;_5eD_RRJ^$eOmXd=@9IcsfV%Po!yRbTPcK68 zgMu{(XyV?zZTg5N6oU)!oh6!c^@VUKXMDqN#Vu;$V5X~uFlcY-Ji3QB;mzsRRJ0kD z&c(IMmGUDB5jq=j7@s@3#tV!(`5MQTvAnkhSD=pHt!0A#3x(77-{5_T6a5kH*Z)qB zdu+M*#JT3;c_BF=TDWsZ?E>$_+CxQWl3qso!tKg`F>xp99HadzpVO;!E9o4$lYD7> zX!mgF=TJVE{15dgGn5R{`2T{(?=_2Bt{OQ%BW%l{Iv~jK-7S{lutAX%r6le$E0&%q z7a(g6efBlE5YhukGAoYTmAW3q^*rVOEOo8w%6~?RpAL`f#nhGSjdr~+6@D;v{j1dV zK5ywpix=1Ju^s7iKdq%b9m13JoM?HOT~lgScFsx%J({4mj$`@VF9k%eNU<5 z3)bHbFY+ZqaS{2ETswxN63Pb_>f}Q8cNVpS8;7Gh&I;YfSL85L)@{NkTy-m~8 zj?4m6&smLNP2@&J-o^0Jngl_9u9R`rmvk@py?aQJj&tYwE$Uj8a$2fh_ZNRq+{Lbs!de=utFQQ={eh9f>_{ho@ zVI%yZD}#0%UJl~p53g~Vx%M=S2Ew(Ax5Bu*Sy7u^&q}WK7v9;DKfYZEjd1PadN@V_ zrVDOm0)IX2>(u^79Y_EC24sd_|2CB^$5*!ZT2hdM?wXxJ>iQmct$*}d!`u^sr`IT! zUcg#c$*|hJN#elK1aBeV3I!v<);cd+i#33TNY&h~Y%3LK=`7&V+ZyC4l79 z$pe;03TMKLTwRx?-&azd7i8^q zFh5?T<(0x_ui^|v?yuZAmLJ9Vjr$x$(;>W#M8#J%NvOFQ#xt6cEwx}uGqS8Gjb_Xu zN`*IhoEDP>Cc*74B?4C{%cUi7A>E(YW}-=9l-MkksfBnWJcBRw#>YMv0PKIX&fc@W(4H z|FpGhyN^@Clq^cI-DM(+8pymFndQ%SR68S=&hlrBjLev%85t)H1-USQW;2$hQfv27v1}>S6PMA8*(}mT7~e!enc z^mUPiPH1d1mL>7Vc_@_S^N`j{>}Rf|MaSu+0PlF5OUbO4Psuv0pD&hW(~{MreJZA8 z>9hn0RY&GD=UMh#I^#kvkmb^n(bKdBuFlm04T+jEfzPU~O&E9v~y1WP4+Pw!JWL#~Y|Ex}tw8=+< z_WSO8V1|6UhktPW_g_EyMM;wkLT|*Y>IYuF6w8pjJzxKj{Fm>kotrvlN~yR{{qoUS zY=}EmEW@3n{0A43fAh@`JUIGAu{opaA(1LRqGBkarM&ODnFmUd+7FK3V$rQr>N@9@<&873d7`E{~JMm~ShoA1h zx)fb})gS!e2lhS15|XB~{{MBZ7{*goJHDuQ(Ya4udS3etOCNabF&WUjbz$4x=Zs4i z@O*!BPsA>D(ZlYEHb(RAzI0srcI}4M#(3HmSdQ^h6}rF0AyNTU<&VOcN?ARTbS#Jd z6>WFlFrMoPg7Mkaw*B7Ok&$pb*I|^#Gja(%p6^h`Q~J)@c)r6KSNqqC>vnED%(?MO z)&=8tXIW7+u4n`8io ze>dOYMi=AD@4N55Z@W@*L#{pJkJnMhO&ok|9k+3k4OzzRg5#&f<6B?$R$@>l-D!;hV`Vi7-!O^{Arp>_{&oy_K|jrRRClU;X$Rt^Oa6|9Jgx9@wc2gd{S@{#M zR9ZfywDK~g2VbwW^g7DlpmgF*O2bzvjb5X)^m3&(UhBGGj!RGU7af}J%Vsz_MLIzm z{Yd%UgUmN+_jbiyf3NbA=~dgDop6;t@J?N*)F&<({u{=7pVEV*L8x}i^5GaYQF@Zn z$_CmySK|vvqlYOjU!b(IQo~K^vU+cdxO{=~{ZF(zyX6HMZ_g_=z5WLkmq-tOSn(9g zr}PlD-?LlOH?f)YOr~eG+Am$C)Vp2f-k9R@XVhMmwC7`*4x`>x8ot_1J4|;MX*X#P z=@i4scT<<2Zss?5q~e35RnjSj3yx{LQ=ixLbYHFUcK=TK-Vc=qza*Wf;mXXPcd^=^ zxKHzK!?)l$8oqqG@mU5~h-qFF8%an|zAc;+wid<@T-%>9n*WN?cogBaeA` z^`WOY)00&4&rrOU1z1_6_!%%JE;w27^A&pGnToORFI=!#@iP^A0rgA7{#h#jD8omm zD1NocPgVSS;tKH_3@=pq0CCWzcn7iN7v|yr5EumnTULIC&3+zZE~z=hZ*^}xp;77@ zmyNKG0OIU*wtGjZtpE9cd!DH6v)(&^o}bI+DdMa>=W{f%q_MvDs_gwWUHyYU)A(H? z^2&nC&r|#SEK(EVP!s)IexdfQzsVbDW`FVw&40a053keoaYj$xeDV1vspE;ck~Ybwv|uDSu{9UdY>F#C}+Z@IC2vE@JN;=XRP0u z4kCxai(xadYY2y);|MP%1*iMy(R}|s38*|??;osTD01CR?%(c5s6N))6}e{marTSO zuge`|+9xN(qXJNTa%|D=fq{~od`UPm;Lf(%yE|d+>)kb0P^x2cz){>V#^mU}^m$zQ zJd}1fE}seZU-j;nX7b89?VoHtVLpEUA&vXDxcpM*7xneZ$ziFskMq^`4qOSY9P-|` zFA)v);b7PezMOA6wn+{T-z81Qt-H^9Zch>@r)}RkFeF1i zlSvl(`v=^at7%rou37AlY4466oYOh5r!;m~v1rHM-Mi(7AUWPP zqX_9u=~HeqQpA}nGuKdV>fN4=OcLIAhj4ex@1`7#hy!5b0DJb14eWR9n3akouEON^ z<$o(MRX#GL|9_(b_Q~VPO#>r)EZJj7at36isXnpPD-Vg+ZL_crX8KS`Y^giWBaj{_j;0BuCyE=o zX1Lc{Zrm-Uha~dyuB~lG$LzWD7Ieu{@Fi!R4Qcy~866$7=gc{2-n<117B0Lfr6IxF zXUISS^Wj9fytx%$hxWc4z0DIdh-jbdeYt zWx&bT|EGY56pFrc64iF)A=%Egw|8{d`%Q@2XTjRsxqPQ;!6c6}XWr>_aVbGglFZ5Y z>bZ`GOd!wB&3vKb@lRV@$E?n|b6=sl?UG_dAj+Jlv@?=5|1k{TRS>4%Gzr619gq zLlw=PH@~Y3drY|uOC+ecxzdW><9O88&~rZw9&Rmd;;zAc+VLc>$d;@2&N*M8J!!`h zjcdAd|B1Y~f+RuTRC})YkQm&YKXT#p?vhM9i$Aw;Qdl}O-hwv>n72wh!^*CF=LE8 zYXqpbr>ia!>Dm|WnMlJSSK2|yBg#v_gE8UGl;(kizagb7YOcM#)rCW~;pRujF>l`c z)t;1#hM6thz+bv>uF;}tbfQ!E0(jDH(bUk;7B4>eCoUK@IEeGU}e zlOOMRt^~+l*tIhWH|Hd|pAqhv&YrYU+~tyzlTSVUj8{3H^a7H3DNYG?%4zRWd(xWS z4I@3`;>8sgZsu$$IT(|aoOb&C)I~<2y!ezQXa5pBaqYMf7D_>#e99^AOEs!|&VrNA zc<95IJ#zW-3ohXY3D**|Cz`R&@uay(HL`Jl1u^B>WjOKIwR_4DiQ={fzQlEu!q;jwZS&5^*y+z5t&5 zS~@58;l2!>W64d8MlMa}yN>6&ICNOf{n&K*yMX-u+VP~a*}q7;o;MTI*j>WnW;AD! z@q{IVA$K<{1yAl#*CEP{h@Ne=yg$a_^60rba6N`FwpX#r|cx9>9Dxb)lGhZqjy4cFaC3ZH4=EGD4|&zVFWb=+gR zNS{{u+!up~p3e1$_$54P-fNVHo)cXaZs7&*bUaB2xsLRc_R#TRq=K$(;XgQCl%G_N^lQ>_oc8ad7~vMVkNE5~l_f0!9~F@j^g{?H z_x{5j55KdW3r;@$EdSvbtX$g*UdP-8U8g?eob#7mv}*Ob%QwCQyqR+sE;{whv(JCT zMXN4Z|L9FWcH!nMSR~<=F1u*;x<_xiW&=LVN_yu@y3RP`%rhTy)>#j|RX^6c_Kpf%cwT}EkhGJ*>^nm2oyK0Rqg|{Bn0;=IudDZo54e6r`&ZeTq<#L zc_O^(we!$>dBNk9mPx(q6o;f0QvZ78N2FEKpojXT-VM|zt&sXRQlGR+8f>FJsdp3g zNh_rO&D1BYk_L~bKB@Nv>XTMT{adI{S|tr`r9P?mMCy}PNd4QWPg*4no9V_B@G6sPwMTUK52#2 zAEZ8Ml{DB%eNt~1^+_wF{!^(>S|ttcpgyU$oBE^`QhyKiNvov65cNsDVd|4sNc|G^ zNvov6)2L7CjZmMoLh6rFpR`IEj8UJ|+e>}Y3aNi5^+~Iw!9MDfdixbuNd3ELk2oT( zk_JzwKB@N%h9|9%`p;B;L|P>co<)69@7dHRt&sZT)F-Wy1`+j1y}PMTS|RoCp+0Gq zGXUlUr#@+g)IUId(kf~20_u}`FQh(ch17o$^+~Iw z!HcO+>ir4zNh_rOOQ=s;B@JFmeNyir^+_wF{-08xv`QMhjQXVB%c)OVA@yHDebOpv z@Ji~Fdat5BX@%5(HT6lWq`@KTlX|bAK52#2e=YS%tE9o}s88y>p8BK}QvVIqC#{kO zZ=^n{_a^F-R!IFa^+~Iw!JDanp;GT6>XTMT{T0+Ft&#>8Q=e4!m3P0ZA!&uwUrBw^ zDrvBa`lQ}!>XTMT{Wa7lt&#?pP@mLW%W#(}t&#@o7>?9iuQ(*FkouQVpR`IEY@j}= z_bBRQtt}tlU7Lmfcm6W(qJR?Nxe5ElX_dIPg)`Mw^E<9N*X+d`lQ}t6<0_@QvX`&lZGEw z98M|qexkHY8vK;u|82f&kN$U*R*nBNmHR(eS~1FS;V+c${ZeW8UFuuBN0eVB4L?Fm z8h(_RH2fGbY514Kq~Tu?lZGEBCJjG9Od3{*NyASPlZKxnCJjGLOd5WMm^A!rV$$$$ zh)Ki0B_<7z5|f61M@$-imY6jB95HG5d1BJ=3&f=17ZsOT{#D}26BfAo^uDL{5#FM> zZ20e0FZdPhkp|z_@X>Md4Ifj!|7+z}NW-@8 zpJ@2#?TnZ5D*669lpp<6!}&i`S|JU8PW|7hUGEnR_W;X*G<;BTber0%(60X^V$$%* zip#VU9#$OuQtf(AQ7pSfyZSGa25pL~q)|K5F+*vEH0)69%~V<@4Q45>l18%?`<+TF zq*bP)I?4R}O6B1krQTenWzygz#Z}U1o??H#(h6y~K(V(_X_++WQd}jC7Af`@E3J@* zCzF3%sdozH#AV{(ROOdhj#c9D*UFDhqyBFgj?_P0aqwHx+gT6qR9d0DN_n_M!$tq8 z)H_3||2w4>(kktQ4=BIPaNdK&v>%0R2WOH`d6hVNi1PijlvYT?hbs2YrXFc$S`l;Ohd{RT{Q5p>>^>-+(nw^W)p5LvsLK?1A?5$E-CJk0Au9B8%ze2mg zT-qm%PGY?Cl!k*!y`4&a`C@qr) z3l#^ulvYXo%V>u*+@RQdl+rS3aJk|tY4m8t{uSiYe)LqeA9X497b&ffhKtF+gM6d3 z69#I}+o-fm8f;=bq|ud%{mn`%q~6JDH{7kXOdOn|xJnwGs@U7ZaHQc?YR|h`X_+** zMsbxi+M?Lss0 zRrU+vO)B>uO8uJ^mq~-iE3Uqu@qa*RmHg-l3{QRk7R43P@XOl>sc+d!o|dKH4*U zoARp+ADpf7@GGicC9WD~_~=Qh=Ra9#g*5ys<9&+qz1x)rql}lh%5Xub@+xW6tJvSJ zG&)E1d|zpmcEYb|Jkc2W#Nj_Eze4@6PwiBw@AWGV&!ry2d*>-GQyvU3+?N=R*x#!- z+M)8Ql_&Kpl>37!56-7PX|zZ*C;7A&?qs?iu6%DF=`Q8_ ze?j~RrDgJir!u{?TP2R}px$n!71A>G!#&FPhLn~`gJH$NGL0v^U(;J9ziQaz|HS$# zsh)0zhWFo1e3w%H>7>t~{L6}~q-E-dU)Ow97_Lej zK2!C=e^I&jEX8Hg;Mt0+Mj0*|r{2G+UX|33lwTnYzoGK*Zsi9TY5Kf-XqWOT`TqSX zFH;^ohv7)0dlmc7RazkppQqS+zS8nnSPpErW%7dqDvwsE+`m|9h2gdqi1V;{%aKbFzDcpSLG6`E!$`4r zH`DP|rT*8HR+%2Jtomir;8B#5hTqk6haXaY@MaBPB`wo_^k>Qs?x8;Q{I@VX`4!^u zt;+Y_rnF2Nyq)1mqjx9{zo+T&4=au?*LW(#;XA2k;U2AW?>^<1NrQJW9BK4!#r}Jg zR!GD5D)!!|v`iXID6W!5?^o=9Kxu_E{By^)I*k7j#r~BlFB4aYgO92_+)O)H(av)jp18_z z!PVq5KJR&oqmQYbD&_uPG99GhUooEVYyEm3S6n6yK0$rbsG`{aq|yp$_$kHSrx~91 z%EZBE$R~}iVSbKjywP8)-2WS;71Ho;$={;kE2L%S&pS%Hv{NPy{*HXo=(Du*Ii(fS z@CO=yl{DO{@pz9>S|$x1%k+L;^}R1BEt3Y%S9$P7osB@`Lv&j{aW5`IAa3 zq~X77dcrR$-}|!CGHLJ?#Z}VitBU={soe@`mFbBNC_lVTss94fuc=;zH2ep}-ajfW zlLq%Iu98Ooq}cywr4>@|dd6?|KdiXQ{FW&XddMe@ZcrS4o$*-yUr7EB*)IP@<; z?U#>exZq!@&+t{^@JFie->BiDZ)iCGn@TIBVO6pBEv02r??tLtCXFT(S7@)w@lCi* z`Blaje4F-eBA>WS9Nx!vM;gA1m^6GhF=_Z7Vp5x7^IKU>DHC`)ujjm*k{n_QS=Vzl z#02pc;;u)iyh+Q^ZGzZU3uv&!?RGTpc8~{jiP`+rC&k4`_JXAM1W%+ed55 z3si3VM;#%aoVGZmC9`&xg*3=+*fWHH~0xI*YHP(Z6C0nL#ppzq4J}|!A8a9*Qk8rF^aoi zr?_;T;x29&3M&q*!I^e5%=`b{##TY^egUptKtdbqr@fd(|7P~Dz|<6ytgZ!98&%89g3rp z;?Bd0r-=6xhfh=aG2)1L%R6bG_%QJ#@sj&g-X#ao;p!-{?Z3D4U6gY_zN5r)ShNd& z_}wa>xJz;P9>u{k6nDK>anExU_qEiMxq|36+P>qnx-zyyg8WpLzl9+oGix zD&9{V5l<1zeeTjb@#nOEQ1P^M~M%;#OmX+WD~>KuJVo4nq2dESWO(APA1U@PqTKLG#fScn$}8&?AN(=( zFDIT-T)IN>vY#j}U#-~xnc@lJi1^?&D)0Qc$|s5U6IZuV{}(E+K1T5o;^?u8gI}sV zyg~6TzhZnhDn3qJzFG0n<0>ybL2>kJ#ojFpPaF{M{Ef;Z;`@oK#9Mx=^6*yGuMl@X zQSrL}q;I1Shz}9lzO!8qsJy#R^_R#~3taeA#Q}HhEZw1alDKEL;+?uM*Xtfq z?6>QJ&noc*aj8UmGgRL5G{qI-DdKfJE3-PH@}tB(qtu_N`Um$Z?wqCA+pqWl@zgUF zZ<(#~@YxLCskj^|o+7Ri-!ez#!E>qa78%QP+X2PiNhXpelx=_RQbWTC_dDs*ngYiWs4L~5>F8OZ&&%c#VQZqq4<8{(qYA= zlU3gJPQ}NGyYEvRoucycyA*ews<`_-iYJJp_bLufQ+f6MikF?PIQjs?8~&i;{YzBt zeME8T48>*QDdLHbsr<;9wEt;)BEoiH{R| zzft{Yg@!NvRm~wTb)n+u5)B_MQoM{C_?Ayre2jSFbj9~y%J54RhwF&X zP<))YdbZ;3%T(TTj^e|_72+=4z`!e?r}8Rs*ZGQXd6eo`iL1ojODVrxozie;v>Y~YTDnV@*d(t#Qr5J-*TnO1LDKP zQlH7%is3I;e4N-16d$=-<)teX%eVo}!izRje+%(diYvrjTNIbJs(gyr zdyL|qt&|g2h>sC>KSt%@V>NvFdg5yp`#p;9C-!boyz_CiPkcYIw@u}x>r`GMK1SUA zc$FWzUgcf4D&Eqg_}~*2-%lLfrdY;3t~|n!;crwN^eUbt_O?^LP2~~sB(dK|dp9w@ ze#OU$dj=GjEA;;yHv+_cp~-#0QCQxl`p6#7Bw!x6|G}mD~9l zM~Lm*i!J+A9^R+nJMU5)yhrg7;;#47-qTfnkoXAk6mj=6RNgb8;VZ;t;_hdve2TbC z9KK(}FL{>Ay$>qxe75554=FxGTqf=sr@arW{4lY9g!UqpPku!41abMJikIE3ayw6@ zOkDlA%J<)+ay$R!7;#TU<)!DSyhMCIaqubX->dR6@iF2l;#;1}`2Uvad7k3Q&naH= ze8p45CF1VStGr5FBJMe$;j6?I;+`*R_?{Q2+?!PFy-@MQmlQ|D;g=O3C-%Rp_|S_q zeEDmNm%UhV_dh5;Ok5#e_9rT@+^_OU;_#mo-|`aLBR)!e@LyEE|D`G~eM9k*gNnnd z;={z=w-hh?Q#pntK81J30}eYj;a13Vmt4q^h%XS zJpX2jc4!6XI7B|5Wj^LyG-hD4ry?b9BPjsC?o$!@pK>v5Kj@WdmZil zM&*ZzOTSedyk6yYZcmlChv)dLdxOeL4{G=+;<9X!fR4BFMwNHTb`!weZ&F<8P&`RI zF;j6^R{7K{#m9*!I~5;(v&zeh6!*MEakNJah7MJf;8r}EMY#Yc&&#KDBh zyVj_@`~8X!u2p=DcygWM@&{BtwVvVsoc8V9E@C_PYuR6@e3J45#8bpm#9jZFvh#qC zqd4FH?A%^av9xNI!A1k2>Ej-gWI13tBv3y zIk6d>eG0mF3ON2W^LK*>$Z@j!4D=*9LoSeq$R%>ev&f%21OD6}gHzw2f3kBXxP1V+ zmjQd^)LGP@qfYk7>RZ&Ghn_hHTqKvi4bHs)J^wv$-;3bF#o+WyVD~a`>&w*1IdcAT z=iJ;mQ)Q$Gji$=&1}e;3Yqn>x9R9Q?kU%p;m^N0s<{Zymn?XYN9L=N)kJ zA@CqM)D|{SkWb`+r>lzlid=e}bNW z8C)O-zekz)GxQXHpR%8Lv2k&EPx5cK$H`VV+4IL9w% zEwq3WVdQtmgA3#$ITeBKO@Lk^$0vb%qFjFp*yR_!rdq)sIWY~~UWWY6bZ~*3nE_6f zLobpG93KHaL(Y-2koF*q481De+ z9yw2L8wovsAoPB6=^$`>BjXWcw&QajD(cl8P zpIjt2je%YwcasYpSU)zF{*MOtl8ej11NcH=l}mx;K8k<*#aDm}d6?{MLjLr0mWMn<&XZF!pv#xf`sdR@ za*o_FljS*uIyp;jp9Q^0?kC4jMgI6~=y`GBGmit!z{+7E6TqJwffHMoAyVr7ka)#Ws3-#-v50gve z?l$_*aeZ?B2KwI>dj3YR+6|n%1>8@L-v&7QI6 zH?>3e9)#Xc4t~eG{Q&9@LC=%({ourb(36jWorA!s$H6&rj@)!G^u!kE17we!JOq0B zN6?4Kd2;$t=;}%6L*yhmwHSJqJV-8*lS%0AQ;biJKMhVD20cX{B^=+KSxW!po`8Q0J$3|iZvfmwcAuwyB=iiqha7(adec$Ri{xH%;zh3C z0lh@-A;({Wu8xMTUIu5#@t=U(j)9&h_mQ2~xc;%wv*a|nL>?gLUPu1+W%Tz3cz~RJ z6P!2>dhVyx$(cdwUxl80i#oYPZd=as{0w@YocKAoH3hv$?j>j5h8|l1-Tei)o17t+ z$m$*FUB}ZOxk%3a5_)PS^h6OnNG_7wS3%GG3c45YyWm78bm!OLescUb;I`G!v*bLv zKz2@`|KB2i4>|ceuyTq2jq-VpSzHOQZS4_qWC-lzUG=;{yPA+qyF>L*hF z6Lqpj?pg~y`)BAya_R$c>Llp#5_Pir3-xu-lYa%veR;pXERnm`bN#>w0zLVC=;^880kUcZw_VQl$$4^i8uZpH zxc+o-AK9Hjy%)Mi&XIF7p}SW?&&~qp$N?*dNepnK$|AAsF9=vi`(?A!o7 zzAN-Tvf2&Yek1fOd5G-o4!!3l=*d06>Spqu)X8~r*DZ{<7xd(DWaj|rvHPIs$!T)(KH&it))k&x_a zGB{lTt4(0aT(GWRL8T)$7oU|&@{`6kvMB4^26ze4`pnbgVIv%r~mshmmVK+j(WR=)##-v?*O@yn_Ip82l?=gG;d!0{pIC32pexdwXTJ?NQh!2{&P zP2~6KpWOBbuzNG~K5~}a^hfCG7U(_XGHEONfbR!){SA8RL9p{7`5|zY zTp~LkL3jGOJ~>YI$a!-7@5rwnM*bYR_z2kj2lV2j)B}DD>7@?Gd2xj;^hWO*)zo@fM@E&&gb z6PJQhO^kOLST%z)-v{T(&gJ05DCl|eAlW0gjfP$z=g38JYz%aD1^ji9UGe}qPIkv4 ze}ddiPLd1c6uEUA@~6oea)vxe&XL<%kl!Qsl8a>JLNAd!$WAZH-%obQP2-V2PEL~( zSqDRK`vekJ^?iO_T8G}*lh`VcuoPE2BcaxXb`9rEWULr>m7o&t7n181g! z)8rCa-3~p~3O#WLSWN@x?*b2!Q+Iro-QR*UyMgn60(a~V&i)k~ z+XJjV0{4?j*3gKR8Fuk)6rZ+o6|Q!Ri2Tei}Fv z@N}?qAarL2xQCo2tApr|+)Yl;ME(+4%>s8FjQlzB5IH`Z`XMY2xj;_Lfu1}Rx<~FO zC*#oD7DG?X1$*S;PT=k&^_{^ba$*5EcNqQe0`52*oY)oIv;^$z2JRsz$R%=ePw0J1 zkw3FHICBIzxes`l?CuNhK9ceF1DD9|SHS6`pr^=#Bl&UJvhkAt2$2CTjcc9(&B$lh^aXF2mP z2j|Fn@-SJg;QA@#&yv*&uyZ{0ZgOfB{T~m#uo|2vt2N-nO8Q$1E|HTbfxA{gch`Z3 z$muk=rxSYOWN>UX*duq7vm2lflZ)i86Occ-5qgpAk(2%pfXnwSoC4il!}4^4^W@Cw z;MCWk=g9qJkKA-3^a43eR%c-S0kTVOU5os2a)z8B50ca5wv!m2oF(VUL*&w#h}XXk z`7;@Cd_6dS7Ikv=Y;bEDdh%P~KC(x4PKI72cad}FApamac`mqp1M;i$!2RSLxpgD- z^tYks$no!hTQ@6?*)wa9C+w^ z^#39_cOke)Zn}v2PoTS5aFU!M=U#*ETns(`I{lGzZ-84bfnFeI$;G#zXD)@F{yDhm zGH~K|;KA>MGk*Z*E@%E>aI6>XeN3I4(J_Dj?7I?rmMov^@vq<0A?Q8id>Gt*HFPHm zE|7EN*#L;xSO0J50TSV(7Ucj{!BG^h@2z0=b(G!K62hc ze)k8^b2Z=`IXMm7dn5GhEO6INU^N%qdNX+*I8V-yTW^7$+=)6lJD>h;h3@VGR(;^a zZs0z0c6V_6Ht6|1!2RU(p5V6I=`R5;k)1{0o;#pt$+0`ZYH#Qnvb!(Xy^HzDIdX14 z=!v_b=gB#;M;<1t{gFR=5AtUY0JrD4{=wkbyyPL^4elqWPX@=Igzjtr_mLBu!Cg;5Po4sHo(3mQ1+h@ z3&Dfr^hMy*3(zxJ>g3$TT>nMr-X-7xa{5wm+e^^h%fNl)0=emB==twM&yrJ@gVih0 z<5z&Y$wl%IIoAulqk#OGE5QYF>MC&itI*R|gFSNg8gScBpy#dy=gHo6;MUim=dY(u zPW=F!c%AwUV2|wH2yTCa@yQ-JdlU6Hp(k(V`sDa6;I^MaFOmDm*;}EzgU~a5;2b$e zR&PNskW=LJZOC6BySIZAKSO?x+)qy30X_b6=s9whtnP%a-iDqecawAE5;=7j@~3`* z{E5541+uyaoOlO%k(?)cdFbvhp=a&|_mUI$ft@1Db3eF;oO%GPeg!@ILvS}a`5<_R ztR4b)yo>w=@&GyC554Wz&~p!i`^fo6z^%W5o_`daBj+9iyT65=dK{c3C!YYT-$8e_ zfYamxd5E0%pr?M1{Fxtt2g!*i!R-Q@i9(1*#H7r^O1A%F5k@DSO337q;f^dfnXTzDCJ`v;8o z3b>z~D}Y-|&@-=sd&$Y4fMb7w?z{%hkc;GDa{hJb>A%w78{i>w;!SYsZ_w3G!3DBM zPJGDq2chT5>9@eGA3=}*44fmE$W4ET?)@BkHsH6xv421>`~sXI=iUJile51Br-zY0 zT?7x26Tbp?d<@CKj7bhEmanp87msZ#kK98pk@?uYivJ1z z+i@FIrOCW4uJYt2OxvpxIYV~;jP;A;Bsqc0HkBdsGGFD%F;=Tc?jk!MAi>j!N|0O2 z{L4O-CijqY_mE5EVY2%n*6*l8{v_EWXUMJf^heH;i{xRl^AY@|8jwFh9w4X5@sZGTC9U{`<&Da%>XINA4o$ z$pvze+%_5co&UgJj+`LJra&){GvxfI$gieSCwGyR!ii~s94EK7B7ch9L(YU z?~(h+C9<;NY0SkcSe3Eiu@kAL{7}79)q4EC&+36^fWm|&XGNGf$Z*r z{HhH8GUPaUh@2v~w;_L)+(-7vv0b5;$Z2w-9R3UBEV*qr{ej?j@^+z zN%qJYvV0GPzkhq=3|UoT{ULIKoZJ)nGvt19p4_w-^dh;N?2LfFL2`oJwh;N#u1i zM=p>HDRPeNk&EQkqmkbo1Akd^imZ--o+YQq9@!(8$nLT9 zHx~YS$Vu`LIYVw=hWvSQAGt`59S7YR2Y+dDf;>o0lM`P>{v5fF?2(=2&`abr*=>RU zL2{DZmO}mvxtE+L50i`J)C!i@g+Gs+Ah#Y5Jx$J%bL3%iiJV%A{E6}KH$YC4U{z7E~p6YKYp)n4HEH=xHC(m&ZFC%y^2M9!1l1oFFQLeG#hrj7s-i}!5zKO3*-T^w*h+lmC#cg!Tn@+ z6F7bq^aMFePLWIG61nSYag+o7u$!5%rG%6-AThk6Jc%Y&0PxSyO0 zgFEhpUW|YT$(eF+=050d1-L{`k~{8)?u~#h-vj1vKUD?pAScLqa+)0bA=f9%_kj89 zJJnc!kQ^t+AEfR;?`7>m9B)I7j=&BLi zL-xqS^j{F1UB)Roz z>eqlXR}2>5<*+wY(!9su`|)epf%Rm&OZLd> zZ_x8EL(h;CuYgPBcmbUL5cxgwFgg1w{eJ}A{Rz0~@8HyH;68Gi9Qz0KEICcikv+0U zc88I_K+ceh3jsG(_=5Wh^z=mKC)&=%aOi~n zCi08W!NLC%*3UkE^P07*)~v!id9K&9&3czg`bM!^#f%g43HE2Gx87Oj$NA%%cs*&w znsu|yKgrfo3cVKoAY_$7M|}_)sqA7z)$XFp^bC8*($`x0P0MPDRE5S_Ro1vrRj5I! zUF<3Pn|h-@N9*-^k{%tJ8LA0QG$nJUqCW0e!14H zTeC^Zl~i_8O-L%$s$1brsTBQZWc?=kzeduxirpa=_`gTeX6f0^|EAN@owH|mt=QN# z``Ee1ty#CJbHnNtD?8mYz99kYk|!*-lJ?>nWoIql)De1j-%p8ghsAFYxAxmoG_jdt zLEN~c&2r9NXy@ELctzaKlfNWtW8Qkey2rBQR;d5K;vTD7+46e>#+0=G67g4TMZ2cO ze-Qs{NuMj$!9{pQsX2PQN=)N^-m|s*2TA&Hu_MHSILjpc zKg5~4VB0`n-zE@NS6RmE6MsQ_Ju2xZ#hwuh;=Ls4{~_K^^R|t5w)KU8MaFCT&enJ{ zBt1`TzE}`%Pf7m|@fPg7ZM>c@#*0r!d-jOGpnlg#`bM!^#DaKtOZtC^H+SCWw%mnZ z2$*5KVeuElD?49~cd|F?J>H*GNcp)D}lX)QettE&Rz zb&05^At;9^R1q+*1q+qGPTjRBDm+Q$o8krK> zr9$GIq*uaUZU)+SNc;!!KbCatyGm7x1@Xs8`oG3su=8i}_mtSP{P>N2{0p^-Um@{h ze*BS2t=B8yFFh0SyTpGG|1?RTBi17p#J@z+X1VD;oM-HN@fsZWD?f{0msldPV+(6k zBx9*tv}yFCLN#()wkKG#;6=^{j9V1HLEOJe`V$lLf~|2YByE-*#+5zlvkkp%;QW^d zPR~MpJH&4g_e4pbC3db@P~RIQy=~mrAN+iM{WE&d;#q6#MV6Jd{$=?u`(I==sYo`Y z9?@f@@*y47<+d&VEA$1HU8j@w!qJUNovC-x%dBrAj+%pVl_YLZuE_V48YAY41?AdZ z(*Lbo>(;FO(xUzSv!acV?GjS&Y*REAtkx8)xl+kj%I>0%wKn>3GI5lv$CN|fG5zdS zlD=82Pb?_c1ClmNZo7Uk*gvFS=sbDzinaa$DL-1Bn7puBMN%pg8Y@jyZcm9;DYZ~e z;9QD~J1l;K_Ncf}sVcD=F|(L{DCqx!etr9RpLImpklz!P=r<`o0>3LIy;^L||A*f; z3Gb?it1b_@rYz1}v{T#y-*KFN)kRy&TQBKGu~A}X`Cr<> z?^t}lH~4;&^xLtG-?frnFSg`|g_lXVz{Vv$~ zbABJ8Uw0n%hyHE+J}>E)#0vj|Upb!!eiJH^P+lnEmnB8N&c$2HJ5kb8#HNXv<-hF@ zE2Uur$A0TRYg$*SJpHD(@q4zUFBbd0Sa6(QD`~R?$6YY)430bLcLVozS?hTJd{}*v zB^|Jgbe|8^=?#)rEA=e6QHh<r zD*nv*^DRk#B=)gb5O3tAemM1;Jo=gK`N31x+Rc&lc(KW1 zLHUlL9_$Z~-MxK3y=K$wxu)4t1#7vL8Z`f+%cXxVhSad#Sh-O8<6lWZ^EUosi_0F=dG-=sErs@6t_0x=(5r0Ab zu9EZ*#BLG`;@u-@vut0#ji;?!IR}-Sy~NZmx!ylS{W>OFDpf3{zG_PiO)Vurqdvg* zQ()X-@f*aAU9MEMSglwPw?Wco**+}d+qpS3UQI*=&m3H0uim2>imh73+^q;gIg($M!c1O8}C9Z6Ie>=yn zkot?&iUs8wBWbhPyzbwAJ9n;IB~4(8<&3FzRApTCNMWif!@AxycF+u}#CTowXZEXa zO8UEE7l{S&?xNn#@!hH?K7X7^Fw+jluUL8F2_|aZ^7K7suAxFz7PNX++Y-J(x9Xbm zBP+{vrTm5MCi^fQ9xeUB1p5w4kF{3IiF!}gpYcq2s(a-q5Ni<&%Coy7^N0isc_R!%nyDaQiPX4(I5jS?FQfB!T39ye0zIZY91F>%PPj7M61F8ZDjb~{3-1&iFPryqOSkK*E$bM&K2(cx zCKjPyMJacyyk+Y3k)#j2N~uG|f_i-_X|tqXN4*B$_`-hY*K5%Rv)i>4LkoWyvWlS} zTK>z0c*)`A6iC{C$>8NtNN3^YI=s9J?GbsYSCyq&bxUM_?bxx%s7RSy$5-nG_8vNB zJ9@FM4UN3pirs95V+T)ce$tX!mg$JJ&S=q>$u4Ft{$k}fSo&be9+x-EB{jb*d`82x zveDsC+3m<5nE@#>+75S?$)ORGL&aoXCT$$EoAo{tsXSI@j})qsca3M1|H`LV{1YeS@wcx%04D?gH`sa zRk=*sH-8|uNBZim+aoLK`^6p;3%186k~T}?5p0L_V_&{Kj#zi%y7i~7+q%28c=|nS zi$lb?Z^=pCQh%0HM^r~5ByE}R$g|1FmSEKjdkw`S#XzaL$P zOX>8A^_9xWSgNT`HnCj0kC9Q78C&NVH*xLO`hHc?o5fBO3*ufTX|qh?yv}ca_~qO4 zs10j2b?&`l!-h4T8_Y>8IY#<9V++J)i`k1~s#Y3grs>q>)ULzjWqMR)wGKzdM`VvS z6AL5s_bfBWkR>UT?&h^9@q^?4V@X$DC*>6j$~RHcW-07oUO}40KmHHtJn5wMrLm&9%);8AHP_pX!cAk#hI$ts3ObJC2t`ZB%@t~y5 zat_<)OZpqX981=&S=qVI`t)h0B&lZUa>j^_7wcSJrD_Y7y4>1Y6q);wvucf=rYk~? zG1+ma>J#-|CQkk^w2!)8DOcE(YmB7#5j#jMDA)CpHcP%A+wDUhm)nek{BkXo`w^@5 zUb}wfiBhm=Q6Kh8Z58!7mjAMTTlly3$yK%YL_*qLsGhW1WaKhQ$6^h7g7j3o$`Q%e zn%YrOyDAis-rdn<&U86aW95hGW~orMtTR6{JF-(PmkKeF_5R>(EwcaK1QOHv>6hN*8PC;Ng}y;xA+gC%X2dd|n~Xgln^X46Kq36i&4 zvU8rSYI9ok%lSBJheH+8YsI7@Au%ljks6_}rFC_zLfh3L;Vsm}PwxUq5qwyTtS z)v^~OtV$e-a`xu7mh*l|zb#f23(7h72g+Z9?XvHqUw&L2v2o416U@eu!nPFkE`Hm` z{r}Hl!vjy99}M$$Ys@L>0`u>6AQ}UDQUB~yl&in9BsYMk~AO@jFk| zjx{n?CVRxl$aoo3H0Y&PS!}+vwG(md`tlYz5=O{gVut39DCKx9uaYChT%gD7RvFDS zh)tBkd9^-NE@mc5ZgYGz+e;-??z1zo(yEnXXoZ-0T@o54|D!S$5)R9BgcaStazy3w zYNbxqS*`c7_O}lT-EKvm()zS$n?9tnYQ*f=D7pF{Ehm_Gs9TySxf0t?-6Y$F?O7%1 zQDWo7g7(}?(q?&j2j>H`?aaQH$XU`OxC@(9eaTYqh8kO|rG8U%L|SFE)S}jwa+Zyf z0f@bm?C&jd9-d^4+Il}Yu?pqMO1$8BxJlA?h}|s~l;<%?`{mg|KVizV@0tyrD>q50 z>Jo>`t*QF7y2-8^Qzk>4(Kr^RilER!N1Y42t&m&@R<+cQE3%Tc)>N+sj36VQGI zDQD1rzn1j-Vt*0~>hY1J&GO%lM`^uN{Nph>W3i>` zdT=)J;FQBZ+BRR<$$!JvR|8n(?2i|t8A{U8D)*t z)mGWA4d$j)Z%8lGu8f-_FKK;+64d-`y?gN5!^? z1?~F}Nt>mOw!>k2AK3wS(I?uILZj@xt?AY(iJM8Iob7#E_k&|3y+Ul2SWwQjk~Yg1 z#+jX~*UG^};DUsk7&w4!Fvy%cN9n4aykJ zZAqKu>Fwulwu#5KsY@PUS|zPsmv{$SbxQ4}=V5K7QYWK+?rmGg`Ew<`v)C?TX3=6_ zxUShI&e~4XJ-e#jRqvFU%b9XJIE++={xjS7zgW_jiCytO`d_&s9r*wA_WpD9KP0|l zQclxe|B|%6U8%5G&|cM&Hp>_0SGK9gN^_2rRqLGEYB{aO)qkYHs$?!#YBR>nd&yE@ zybkdf%r9<`^jTu(iUsi=m$X^z9o+A3oqpw*ut-GVr+(^sZ9GtjizD^|(5K{pnxZ-rj5tb+Az%YV5TFSA~;s?^9*Se+l5 zD?@{tn3nBi>+(=#tRm7RGZItvh)`^tmJ5fyte9Np?jghNuw4-|_xMket!$5Nk)L<1 zw5l7+^&CG(xU9CUdTcZnu8_-#UugR=%lfG)x{Qd>enV3JpkEB%CHt$GD;Cu6C`p?o zxF0ohyZaoUuV3dWYy1I5OIG(<7isC|&kgx6M_(jUza#Tu^`FojsZyn$EjwYWj236h zD15wJ6x55oV96k$LAra#48KFsP?Z%8SCv(Tn0@7`>mIoF>|? zT#jnlG_%a;Rq7#gY;q-3ZrK%fG%8(NWw_3&k%zuCe@#!R#2F}WQp)2>k<5OyLDKh$ zJt!8Gcm6#n@0~x!c;NLHK0l87d^?}exhajES4!NHu@C$-WM%A){{PEu|0SpWms>3V zN-xwt9v-3Bj$OH z@9UTosnQ?HRFmAinP^W6mrab;)r4Y^>QL2^y<)ChSB;9*=?Ssvx=Akgd~ecLRc^RB z7OApt)XmXQ)T*qBMx$eEMpllEmdVz=($cqS{g~EcL+5B2zFiTCjg886w2a5Uh4#xz z`vlwjCQ0YT9uN!K?-fa#CD_i}AMg7wK4eix^6CN;|0 z+FZz1%9y4i)+{5Tu&%BtulBpVOH2smo`Z5Y`K{%cCF!`>PGV;H(*BOmC$>&Ek13wA zV(qlq8#^~G-zLzB;6-=r&v(mXC-ZxRS#i5 zS+(7BQ75dIeWY`p89%mULidI~)mA1n-~Zq6sq{%>F>{D{qNn{U+y94g<^Y)nZ?xq3;pD0^*56Zi#BfT+^}iQ z`gQwl*sy-XwAqJ4^~rCJagJKx7+-0|>k;3<`ROi6zaaLCSkMmtmb6)xZb3Wj!TS(f zkMl2!8w70eLT_4ILY5c0So<%};-z^@s7Z~>MAdG)%5hL3dvdux-LA5iSabAwmL=n6 zOU5gaovaiv+8C8buhc7+jL~&U?`~b7b%$TB(s$5q?e}fnZ@wn!lf=?uX8CXXO{Zz7 zC7U+LY|WRpR?2TJadJN5^ovhd(Cjy_N&07E?}!EM^;=1sWzr7jo41V@v{GIAnDuqi z9F|(uBG*{8a#ZR#+^7uW#_!)+zr7{BMC>TBAntjRHp{ZNv7P??i_f3m(o(}sE7qCm z%a&}Y$GRwFWkdHzE|RCQ$CaY$JZq{x*j)5C#YXQIJF-4JdP(InCp`M-dbx)-dWj>G zGhtUc5Se9*Hp}Hi(w?P{l#XSL9%n7Fr~0o)Th)4kIVl`qx`A13GESEita^K0H zbz~PkJ+#61BhUT#$9$Lg4dQl7`uk#6iUo0>lC)XspF!NO^Ex|-yN}%b^k>Fp*5*!J z3eNT~1%C{v{L~t$++s*3A&-nz>f@xts?(LRn7oFi6B`>lJTg;uaN)9$T+BwxWRxZM zaE_Pf-cu%S;u4h8`Qg^>>q>ft*c`E-oO?>zEIU5`9=>?-QrWt7iG5_`*SyeCaxYTd z8ETR4MlSK~QDxO~Ce??)jq(_`NBo*y+-#StBz=q6?P5XP$0co+9mQR}V&f+1*yl;) zMyFs^TTX+V)+c1OnlLI>8)=X!zgj!4kFly6>XiDx3Z4WkT#9%wXP?5tF-bcu{$fHf(HOct%u5L!n4iwxIblIVQ?X*%$xY&E?~& zj|z_%q12xGTXF@dvR9y1ng&9>|8( zYuBGDxm`8Im7lA1&8jL-|4H#>-ZAZXlBB;WcD7j1jyFi!EW!19-*)rXt<$^wIMR7; z6ROd({-C#5mS^2%ZIPk-6wg*akxQPj`Vvd`Sh8WmR+YKH302uTbda@|c^Gr4-LI`l z_O#FV4d@~zy^xnfi2;;pUG=$>zGxyM_o z)Rdyk07~f`Jy-6o&XsdjLwIzk$~+c+w~1qx!c{0wM&h*!oA$a`(l?0RA{LY<_OPE_ z4Y0p^d%J$m%zsORnf)$rJr%vjJQDE-eUDYHrWDH6f8^9SwY;gkNslW(E_Phy2t7{5 zvEyW%>s$FKc@>K_Mzr2gSuUrCMX{*dcaO>_9gi=_D8|RuTW~?hhXIdHSKFj=HcxJVlBG(#y_LzE^*7EDtD*Hs(3dylmA*p5^ zid4vPGD5B`r&wj~C^^zvMw>~hdZ}MX_M1tPHjmMS?DFQYuBwya>WG#G*;YsBo%E&J zT5Ycm9U$c^+<^MTAKALS_LX#p*fO!8K6gsmEKfg<^Y{+y7XEyF%tYO&FRja@9n_`zv${-bXhL1i*Vc*liJ=Y@Pi1dLebl2{>r-#iVl%~p z`fQT4S%Ug3-R}P1XWQo>Y@h#Vvt{n`>$A(54Qfg@tj>REE}B=ekdBCgO?X7WO=Eh^=~f^ky87Cpag#BMTwShcdeLJqOr zGGa5mET-*mWI!@s>Vj6Q|Cx0`!$)QJjlKJ z|G#hDET_fVy=+EkQ)G?)W^`wJ8d^v8?|ZO6IFE1bA0|qAXR$W1pgk{+nv}V3G?}jMs#l#>lKfqcm|{eYl}=bX7yNCX6F?p}s>~r`z-NSyp&wl(Tdn z>NOu7YBK4976lCz~f1rDg7BJJys-&?({m*cU0E*oq@}juYX7E+ziaqI_}%s1I&aDRqCFGwa~{e&=xyEK-`xaYvfEx&Hb^#%p?dYrI*K z-dSuHu^`?)k~Yg1p4;9UZ=3$2F0r3HCnhcWzC<)nIaP<{qHLT@^pA!cm3R^Dniapn z`TS-{-zj#FSP=JNNt@*h*C(Hk%kw$zR85JiVTt>>J5_1M8y0`Tb$8`6@*KEWt(aM~ z*pBY&u|GVq^EAmP7i5k)$1#2~^qUkPf!~y*PZV4Czxl=OLOb3pXPufkmXhLM;Fx;} zRh6|WPyhYmD`=jfiTVg>weIjYIe4(9!&ylZ4pWeA)y%fGNIaSWaCClvco;*qJ zG|CLIw3SSen^^vN`lHMfN zEf$pLK1rKpho4{k>^f(;nac1#_SP8xv6;S}CpKu!8L3(`wklX-%KfplOkUfgVsdIK z50#DduWPF1$>7MOsq^JjHd;Aq*zei*ClP1Za#N4W&q=d;QajA`C^`5Uiny-Y0A7@o%;j6AK>M7yiD`oJI?=q zm+imY3}x9pGGo?Ss!(s*re0P4HC&ZEuwLb#m?NRGQPZo(%k|r$nsEK>O1Tdsr(>z{ z&Jj7qPn8D%r_YyBgLFi*Bg#g#;&>gnyqTQXa}X48t}rLkmAy33!7zP#LjsrLV0ZTl~OlG*AeHN8-yX1B;# zpjoE$9J!9Ix8Kq75TRpFs;rTbp(CFulIlpcs@lw_Kg=D&!=&=2H>{G>vzAD^*3`^1 zmOF?O9ZT-TO_NJB+nHD$ZCtRA z47EpBg-0}sadm$|S#@I6Z7@e^y##);r zr&&kZGozExF8O!Rj@{BuuDoUTzw;%1vDjr|K|AIoZ5EsNJ+{B!yy>*`yaUjXb;@;R^Ib05L} zzHJn9#JXd6&7TcOl7p$2k8T3din_QpZFEZGc56f{7K1VlpS3@W24Wt=O$0Ow2y?W#-!1#W&T=vc9*(K6s5LXOW+%v5%KJU)8GCtadykRy z9I>6mf^u|9+ARN9dmrGpxBuzKz2!8qo7h})s*oEIPfK~sM{i6!$Y4gkpmKtwqH;NE zK1*9`Za#);W%`=u*vXaB@>(7y^_RjB%9)pPxblwK9#2a8Ik6YTf^xnoX|wET-0gp! z7R`lW_w=M1mTNc}=5IUfR_=S;{;zC3Pt26`9I<&~W-;4;N7s*joK5@!3x5~5C1NUG zW@E&gr2p=1{9hpHi^MMZAN>2DR}TEUYPzc)r2h)PY-##0imzZC`jMnV1*M{5L3@pt zv{`oa9M;;^8#l>k4%717h&iA$*2n$?r#^FpnwbkJ*Ic`sj~%{b$tN+*rSMdF21i$q zkZ(D#udysVR3QGHKcGF+63-Df+wUAnUn+KmSWuq3C2f`+J!ch^XMNffCpASr__0Q; zYI(Vu=~*h#D7XFOaZQ;`8ztkT>JjoOnGxkmcBFRQVf+?Yj$w%t6E@|Dyegl66l)O+ z%CT0`W(htow0-}}PkKm$oafK=-tPZ@Qp=R@>|9v2n_azLMjf@0`LfH`%7wEGOXPxk zqRjT}&m(j+O3z5CN^rB?_229$#hcLp5fV}bWK?}Ru-;ok-usgxwhN<7Dc(2 z{%5pfzmzX1|A3_55PM53D1YcDD1VOkOSYef-@GoUL2Ag72K=_Qyje;fQcuX_N>yZ{ zbmQ?cjZ%eXd$J6T!n0hvQf`pMZRtr`!nI}QOu4Ilojkc^K4UA}w1jdcC2mlzRgzvW zwoxo7*F};x%Z{!~)~(;vd8*vg+3auM@-%6v1I3OJJKyvI z=lETLnq9Qjpv+&CMNrIgnNveS%OfMD$dZnf+ww@Xt{B;3m&xM<yWvPdLSYsTHu zHI`dC(mXzVh@6i1wC7p;eag&-s88bct>?$3l3pg35)0~+mb6)J+QD<4TkGQ=&lg(D zE7WWmEXXGaq=6^;4cun#vmIsE{y)yn1Te0uYW(lrd2hB%W+s`WlcY&ANxGzay3&>| zX=zI+l!msHQh}yT)3kI+NLorkAtGP}fhedI6(UPPL@5Z0=m$~x{BR{8U`2rlD2Pa- zq7+5_|IWMbX4;ey{onS?JG11TbN74CcI}fnv;9TWeTaO`{_Q8=&j7yw4Bf-v{~6s@ zA>4km-3H-a+dASA)-4-Dn#)R60Qsem-$I51KK)tG==`M}PXj*}*Z>&%&-&jRf9?l{ z_zUmAo}sPT7pD`ruRH7o?)#2997tGoU3u31SPWqE$gIlJ&7Qh^b9Cy=;0ABSWMbi& z=cI;(ibKOjcvD@JbJ2)+B?^N=8a2*q9-erwGA(0YUVx}DY?oJ%D+{9i86m0sYZK`f)9fQmbwtW?dH?r$*uq zig6+f-h3weA_{=Nd+kVe5mVUvj#o9&BpoN2a7qxW$1=zc`BiXMQ64)_#;Tgd5t%J| zyjXsfc7})0NhKV-sK==y)DH+B=Y>X1Mk$r#55`lKv0-l7!MDFQiVZ?(2v)2g+UfvH zZNF_hQt}4MpW!L}VIBBoz()X6Kc6`yzhWQvq8`^)|4?~?R7$H_ z9=AE(<0<{PDsoF8->T~=!iHa5$4e0!$h=q@%yYtM<3f~#%d=>GnV+!olf?(!h17`j z>ZoTAQ;J2%sJRaA&godSxBC+1(`>XFVpzcroxgS&fDW3vnCSWVEI&9g99x-MR$i7+ z^XZwjR1l}kWDGCFDe#aCjY?Od|63Y%XJhP9MaJ3dDmBBtBT`bD;1 z7lDriY5~)34d9Y?`RDLghS(o&-_X(8VmdS)c+cVSgX2#~9PsL}seK`@JSaMh5DgHB zl{qKU@kFE1tP+9Hn6$*?!YK41A?Ky;e9hN>=(3D>{pri#_X7_ChOh5|OFB+I>C5+a zw(M!!c)oFinui%uU6b|67%C%S#2G18Nb^*UHQ>_=KbNIf4qgL{1`NGP;O|M#m%HxX z*|}kJ%lgw>_RxbAQjT)v%RlPkx_lRrpP9d}2LB}RX~59C3tW;} zH-`FaQ$C!fH|&L4y1mzKlgYuhz8b6Y3piS>c4`w)z!!gpJ;BN(G~EI6HFP7tq|87H zFm#85OFC{IJFc7yeeznGUe{=SpTds83Jou*aaOxeuSsZ-pUeyG;Cq0J0YmR{a7nrB zx;i%O!L&;1l#qioVx#pGWG10awkFbiR$Cn>*?rb(@FrjrVCZ&%OFA@E4>H(KFWR+g z!;bdto)o37O9Z~@3psdbZ+g$l6co(6|}Evi&}N<43QKw;WVb1 zL?mKatDFk*sW0%$|9qD2I`Hj4J7DPcf=hCIdx0yybL_l7gf4q&PBs4{+s%&$czFeV zmsQsnw62P$V@&pJHDy;8SEVuBB!VM}-&-E7P!o!9CSWm4GJ%)STGdWs%zP$v-a8{4 zR{4U`{1C$XxZ_qtg6H4>Y=0dIUI$DEOnH`oOUgCx zv^MY9(6MdL#`V%?)5-h95;4IzoXY5Y2=|*L^CJf#HR7)M{}-YoNxeEv4@te&uMb#Ly9nfk zlQDwb@HlER!qVra=c*75=-eo@x`t_fke?3nGaGy0C1lSCxIxz)OgW73(Q3OIq4TdxYkm$w&(zP8;4c6#0fwI= z;F5B+&k%l0{Rm%~*_C!?I#6Lv?Z#x4S}|NzaI|;bVuuq|jiP0lcYJ>8`?K@T8t@H3 z3t;%!11{+}y`(?>MSi-88O{WkX#5ZrQ?|mfruNv@yKD%?!NfGtJ4t93>RElz%de?K z*GF%Emj1Kg&jbB{q5nF#q~qxO^Z5|^dNQBdXx$h%RyBIir&ssu?D=gu__@Faz=nqG zmoEjE)HgJq#(U6f-++&R7iT2h_?n{J4v<(8qwE3eR?Z0kDuF^w;U}7zSm_8rs1iPw;yr;*f@VuM-7eEy4UxE}GwJ?{SRv&>u3r`zMcxR<4HdAPw4D)l zM)K_)q4@~ElGV@DfY$?y0mH|Q;F6~M>*i4X&{2G>F#Arn!*}WJ@UyPBE1vGX=3USE zY5G9ex*{;2oqcH#`|mL3eVjO>@s*j^>U6)#XCg8m7*dv9{x*A zX(^$XV?Q)V&$nQxx2BIDrADW$TRCxY6mr6!4yjLx#7n1xKD}P@uH_@4_Z;~1K>tzn z%7^+v`}6N0z0GYM?5HpECh|A* zuLR!*T;tP}`uor6p5C@|p%>KBl=O%*QrWf^`&+#}y*~0b^U53Ghk-vGMelvvYinmV z7ME9{SG!W71AhK>uVwr9>EJ7YHGri5sDGmx@d`(YJiUJoMT zi95x(thA5P{p7Br=sphqBjBh14c)DsUc4sRrFxyEQQGduuE^&rVwF~}Pp9N}+4`Fe z-T<5inEuiPF6n*ik^XWl!Bpl1I?Y(G@ zN5uZ4Ct5cnyeLsveq)UJ1-lwUz+jq{EF3(YiSGos9^=$SisRuxexIYBaPmT-6Ng*Y ziRwzcTx~qi#A@A3{k6Ir?eJ;(<+b3q0Jj0A9KQsYWc(c87-9z?`vY0;jxC4NWxwt@ z5?t%4VQQ@D=wNOPiI@Ed#7Oun%Ht#QkWF?3A%U2hx~e!F=Q*+yy5dA*EmR%}`#ck3WLfyh-poz|_Zuhov^M_3`5&a*4tEXxX(|o46pB9_0z5AJby#3%obK z&~Nr@;q<${#5#COfZbon*ubmRt3F2Q&RbqDR zIHN@OKSD~+Y$FkTVkr*8%d5kS`6N1Qm>AVmdmS*El&}O6HVgClKrotOkDE_)SAxwY zV~lKmAB;IMu9&<4X@8iGniq_fB;#UtP}ol_(Qyp?7?CA8Rq*wiKH0EIZJqAqv8Y)^C4^2P1$XYECfJ1<03 z?9hA(4OSX-@1shs2bKD%OBl>YRItqbdBC|}#+0Pq*}C2PXxCZ1mv%oaZ9IVN2{7$` z6}Y6+-e*6!O1JyTClS-5m7$9V;-9n!;^pq6*ep)(30rp+R^n7zMP!SqsGty4TrB#; z5z5`0M3*fQ|4KNti!DD@04Ba6VX7iPpbr`^ET4!)qxpmmf7H7mho_)ZA17jK8jTDV z<{m`6*ASmfVQpEWe#u%%>YwMApYmmRFXjI|_}_tl0jB)J|0uuC#uFGS&qog0y4r*x zUB01no0PrVepH`hCR}glThkHie?K*bBClseH;B)*Gai2x`4>kwV{KC(RP7SfnAE;N z^VI}hGe38N?*T6Hd670ePF~>epE>6ZwgGXjrUUzm5^*;VQK&*uPZfGSG!z|4-=aE; z#F|C|1fRfnQ3=8*{a37b`L@)3lfPrAm_Ku)ki@x0GW$1W6PBFLYF>s6vwiliV>-f#i3Z2p1-&YPpc?lzoLYLkUtCH${@p2{y7oiXCgZwgoJxA5J?cH za-95fj{crs)_{4$%`aaJxG(U_P$GT@H1Nl%kk>-5*{z-RmP668^oeI4;@D}V}6@mWp$sd%h~W& zmXCA5n}N-M;iCgw(x5%f5IM%?j+T}|Hd1w?CWoz=_10IhXe}v2%U8iDpX?McPJDU~ zk)PQ|J_Y^)@DgC?75>Gi=i7ChW_CN) z(-c19q_Kz))v1JMn#g27f*E@?ui}9hMMkLXJRB9{;sAsn_5wA|{=IEaXFfW`ANTNK z+UHX6tAXnP!{E5c7Zbfhld<}jX}*p?S2~mQo5H^$0|Tl6!`CcuNx9CY!WYVt4hi()TQQ_E z4QyklRHm$1J+?Kogvp?k;cM&;@!xV&7>lbDB;T%6H6LBjF?`$tejo54VE9<_w){G` zeCB9AyaqLUxAr^THoN^-0bcG=Z6(&M{yb}Ons}ROOeBKABDIbYT?>aL=gUUIrA?DO zQ=EHZxbNjT?Yu7q5}&bS@-LQ1#7FaI!5T6tW>!iBOXs=sBaw(5L$jM#6`v{=aAMh5 zj6FeF)a4ug<;Nz+@<+-iYuq!vPtq}b@j{~iI73~i9tqla+UirvX7`5v>wev>OZ2e${e>K&zi-}0so|%k6>eh^$0crGGEqU zUon+35R_8NRvZ)A!gzIux79efQu8W zX|^u=aqkHCg!lT2_qyV;m^Ev_wH~0CNAT8>(v?N}%_Jd_{9cujr7g}CjtBH-nmkjw>wG7D*)a5(!kER%7*FGcWn{O8%ZL-#G9oz;wXSn+GoG-;{6Z zhTYqDN%1^)!Z}UWX(?*amCzhZ2QMV)_v!5;zYO_FJANMgPTtx_qfGf$ zw%`(Qp%gLYnE^&tP^n$EwOS6B^8ie)^Qha?CAwwP*}5IAce8Yp;3YsgVCYT;m$W)} z|5>iXZ#3OuvvSVqv#p&Hi*X*Cd8~~@>rlY7KTd7Hb-TiM837;E9LD5{{rwu zz|bxDhey`>v9BL`+PA+k^M@B?ar0Kf^l!zFjWVa3u2*#5&$+l^%n#@ zwk*F#1C|#rWrhqeZYAEUh_Wtk_%zSfu!`7`V+jw>1lPLbl60k(DX_$8xBTOmA z_A#cWV&9gCPVyYc*|1@9E#|BvRVp}xRy>JQyADwhIwOBgoWHMR6{ja`aL*%;fai9f zb_+yT7ovVqwC1@EMrXrQfK!6zY(ab?^YC;8pH^VQl(7$P!u;Jkcqgpg5XW*s)+`&~;9wKEtJx_(zXZZrE%ahfZ2d)xAVXywGY+r`{(uAahtbZ zYVmP$LboPF{9e%o3rM=6|L*lKC%hs1NI^LgUL_ro8ZgveKGiz zz{dc?_Z{GpoE-MyNAoTFL}9yb8MD#M$tBi&gwwZUR3y76iF;s<8WI@85ruFYMVRR2 z-|zD?;M0?FX$81r21o*ipXuO|jDCCQKCji-Y^U3ARh%srwiR3T2!y_?($ON?b+bB~ zn?~aFwJ7oKixDh%%Y_}vFP44AY3eK9Hri@$*Y(o{J+nT168ww69f0BI8{m@6`Y_ZE zk}zDGh=JKG_0m2EhE4~@aNeo!$IFdFs$4LT?-0iUbI7#pSL&Wyp>bnhK-)}UaEc<7c$rPh}}*Kc}z9^2pvm=b{K<&d5t}p zat!!%FCt&lFKz_y0d5Bj-Cl4>=G-u3eVV+fW#jHv2{DRvtffPaqEZ9N12PYcNEBK1 z12zFi#es!(V9blmr#hHa`EEJa!*E)!RzDRA{T;dYy%`okN>au?;yUiSCQ>fh4+WtY8;~qLkz26FccFZv+HFnFBfV0j~_+;%a!I`Y9h2i0` z1dC0A)11RyWYlue9~>uK5iKqVy7}R_JEdqc+lYs4^>rG4;Deg~eeh@c!Pmfl1Uvzl ze((?Q{}2ARW78^OZ1fhnF2%%|03HzG(FcGOtke%E>#Gq_I=amBq8*)#^AA^=&_fia z>fyW;m(86;2M&iq2{*;CW^4$JlBVa6p`#mH;;jGIm9j4(?d5Qy8(8Ef2?o_#KqH zILS;57MxEwG1mXIlZZH5ohYtsiz_@CK~1!P05*=xl?Zm^4CDmU!l9^~c|U}7zd7)d zaNg6U%UKuE<&bjD1wRQ`3Yc;>`rn)R$~?`!?&Omg52?(s%CuEqZ*^l@%=#|@STZUj z_0#Xu*-t)Ze*6;nw}3|hL#IBf`N%OpPHJstF6i(k#ri7)$a|iYm*3h*ed_ze){pbk z_=L;|&o0YQ=q2dZ!uZe6VybeJvS*CMi$zl|{eiuoNdA#iP^mGb5=kOs%O)xz`+%9K z(QqDf^O zx;y;c^z~u8JACT(;UrzU#QJAJHHO`C)}uxdd5QPBcr(Fye0U*F#q|+%$YQ7AhD+GL zv)AXl1Z!|D#VHAv1VboWiIl-vxR{Y$5FF{@WdvoFfDK$%6cslWI-~PN4D9S_5j4~cfv>Hb~HdbTJXoP(;Jz`(dLrSprq`6}ch=DgN+ z_&KTZQ<|Sles*4-1%3*!95DR+3|x}&BRw?4UZu5J^OK#t`t4Wk7j3)Wek}4L+Qj<4 zJnP2dbW~b)q>3g>7R6^&&YT&|+-0K$9w}`}IQh{`6T8@z7tmUxhB3y7q&SSN4UxWz zs!+oAa=mMGEb&a|J8qI}zHAdKD|CbHUK%2{X&JqQV5K6HE)7LuX_OhNs*uAE=eW`` zlq+LHJJ4HpFxfA$|IV@AvN9azyk|T+56uH#4Xg!B`FDa#$|VQW{aZ@E@WKsSxBFYg zbmnw6NF#w#AOaLsN>$j_1L<;AueEd>RkP<|GS-04*F!#C=_gNsKL@-3 z7{1>0zc=%Qd1mK}rE(X7URAs)S!{5U9MbB$IbEewxYbRwi-L&j#Mp9$TBzxFeO}kg ztVFh7G=Q%K&H)VlUw})>wO`crB0ckXiuH&)4H524^_pNOn#aF7Mv8`?U zNoXZ^dfxgeZ!o7TV^)2mbw81LMTI04L-Widil&z`2XuX0p}P%2R;Xw4;cP7``_nYhqknA$GJ<|soQ?V_AK8q zA}OQ;ad8o$6-0!|B{nSBc}(RJbU{XLl=XDPR;-=+CF=+hOx{tx^q z;90=%^}7H4`|;%+5n(RHWlEw)9_Ag~zg>=C*{NY&L~I`!L1bTcrcH8|*R6+660?YD3G4w3KRy2U4gP*`!Vv!#y)LY5Yvb0Y7951U?QG-Air7wzn0Xp-L#MyQ zF?hoqj*C?DkZJmOa%@pK>%R*8Cjm)BEO5RnelN(bxP~xDs$eod@!-ug2^=O!l;|ivbmu;uk?sQt!821J{yjP8j zjPUBQ|2|#LEtI2{Po&;21HT%$4lw0B04`~94*i}fr@3M{RbNY`pRpiiE$XpRC|47l zMGo%?4hdXN$fbvF4f6+9jOAXwUAX)RG5{T#!Q&%TVp}7CYQXTZ1zgfRVIgdpG2Kn>RuQ}4obal0=Mq(0 zl!(=^Qbp|O=*qL)wUJUTj*bosF0FJkk($`V(8;AZL@DQOJGeeDSB-Tu>`NZh<#-4_ z%{ul3_@9Bd0aK1mrG7blJENi@e*3M>3kkp4xeId|FBV05z^?L4eQ#isgvIZVZ13?I z{qCg0c8o%WtiL&xSV_3f#CUIG>U-)AYx7NA?t^~0q#ykd{7K*$z?Az{|9dlT%`-cG&qAX}sde#X^-Lu%WZ{%<^ioJ} z%){(O%wia^O#Y+Q#a@5t@#)uP;dxo%lqW7`KbQ}A{0Te=>Pz^CaydBYi-zy!dQ;~U_T%zdwK z42l2O+04#RB4bg3oYyCN$MwI4yvNVFf^LE{4r02}@d{H1yuuDQG{uQrA5lf)k zjFe$als=XGLxorgpG9!*u@QnHsj7tQ$OBb(VFcY>#4SZjy+mCeBD-?c>3&TtXZydW z>myvAmETo?&jRKGrao>4m-KNzj`{=s)ATE;kIfw$b`W;Lmo`=&ROR<7`=I(vza4?Nqdyy~*VYX@#3W9>HUjewTWacVWUuqxf+SDZ553wnxUs5eU(~Fo33-J30d1 zJ7P+oVBh8ysON`%`75&XVk!7&U>sn|e=)cuWB+q}zh2z2VXH`Q(oF+$R(RQ7U(A%@ zT3=@Z;8thOlX&BM2O2`BsCY6G%;P?iIIDRo9IV4of-;v8iHXG}id~bulO8iK6LZCy zdSZSawlQ+&(?aonWIwr(xyj1>MDzbR{2BS{bKt)PUIz^S$q}0W+jHpITAMxoPnQBT zJ|@!CrWHlrf_^ApYzs#qpeWS=@7a(AtA`CwiS-q0O?a%ELZ32MwW_b!R{KviKWm|v zp}xF*5cnm)Wq{%5%ixkO^7n^Ej(K!{+Q`%_!=X)-|f5Qd1z}p8s952IUKA-V| zoxd0N6T{_k;o&97LLx}KR;q;}ye^14=C&sBqqo^z+E>C>&N5@U+sFxn*HZ0N?L!+BWR zogSO6lC>kKyzr>#@JMYWJjz+4>Swq`p}hQm1k^tRMa7{imcBpQa>Zdr*szj6(|jL< zFEejF3jPG}Gr;iuJ8(&6{vE2n?A)?pleeer;gXVDY(hX5-9o6EMFRvPKoc|@jsIL? zCb=%A-H@9oPjJJ{|;@bjY{IY8-N(W@|^w-og5# zf&a(xTDV6$dGFVc4)3!~{}KkfB8YLvBIS^A6 z<0;pG;QzrEp~jh7Icy}iNjh#N{%eU)UMuHRI`M~X=Yw{mdcmiG54>q=XJb3HZGYUh# z#a#hw7dMO{i^%70)M;#cktkuE${H5NRicEePD+OwT&ZTl|ejJKCzlIW$rS2W+r zQCYr6f{zC#0fz6n;F1R0bBG^9Yuizrr|M@dD7F?iS#Nm;dnGJQ3Goz|<%*k;e>fb0fGBXwd6nZQOm#f-CFeOOuDzt#NJj?V5c@JY7L0L}yq ze??<7fBXIO`P!czdrlwZ&vdiuUiaqMqpscSzU4lO>Sb|nq4iTV=|oy$UmPW@k$BdP z1(P6e+*-@#&t>Z87OCj9c3!+%d~xzHbURnALAD6Ikq=GY83=Q?wvtmj^@D;)7P>saM!w=i!vN za9DU8N3)1~fZep?UVubP22iyXfdi*B1Br{(RJ-=;g*|fWP7tPz!o;^X;r)k@-OG8Jb zfxDFTI@Vci8pC5~+NlU)^CT*-%>~AsXw(Cc=o`@dShd-HHv)VjFa!xglU5S1? z+zWm0<=6CQU9KbKZ~9?k9OnMO2*A)^3N9(vc_&N1eYaQPb!XAoTL`bdl&$1*GBI<; z6QhA}371W?a)gL>%sbkEt4Ik7>G`owbLQHMC8}KGTbi$K=o-H627efM1TcL47F^OU z|2%%qcZbe1re1b+>^-@~W3BNca-LZUgjP^R3=if%pTCsnm?(USofwfm5$Ir{$*FAo zWJdHfEPQ9Gg)X8rof`k5`J6RA%jXL4^*}RV_`C*O();ttjTq8lk7u&){g@;m-1uoj zm~8y3=I;>nP5=5c_`iU_ge-rP!6m(a|Jt;*v%Sr;#!A;cFLp!Iu)JK_tE~NavB>ef zFdUWn^KC8RcQeaZs*F>hkG4eiWUT!Cwdd@L$u>V|tLzud;NyeLAxy zW!rBZ_(oteVA^jtxTM_uYp`6no;GjW$zIQ|z;siuA{hBnbT5BnEXIS~O4L!(i%uuj zftM}L47y%>p=0{di{P&UzXuE-e*^z-_;?Q{K2CU+^eY}4#>81P$FMn!$UIoC zHjz)SPq)4G*=Qm*=Em0(aA7U~+A-y)M!Udi8u1-X>9gz|G!NIqpB zfr-w1FTXyYe*Kgz{WHK@fo*`H|0wvsqn{<7Zg0eN`}F`Xf3SJ^gxwammiC9NyV$%8 z@>k*#x20YOXGvzI{qiY49l2Uh!v~Y6l}1$012(d32H9y=P8i`S5uNX_I&|f z{vt!_psl=pSaNE%JXPQmfhm9~&vI}{x%LHHHtgKgwi&e}E80`C?1ok(ye0SJp)|*^ z0(f$WV}e3nl~Jxlekc!dZ6#is%^d3BgVUPi-whqpu6Kgp4SdC?{qN^v{~WYYn__3I zhKzN$wyl(W`~3U|$ScEpksCy&;RgUD07;U6F29q(bIkS)d)vI7PrcPp58Dz)NMw9i zuSgz5Z}G~}M4qM`yTGpmJ_eZj{1v#Qw|qU@V?*v4>mUwd$0j-2!IxZ5>U!F?PvBdV zuo}9;*3(3ZlmHGgVT3SeE5RBws!kUz4oCMmHGXEWTAdu6&K0wBnL9)pCRc@DZHq%2 zCem~a%vRWs4KEA0qum)a$IG^JwG$j2IEy=Cs_Zj_za;nk%Cl~Iwmc_;uLaHlOnH6? zE~)8xy)S!g$bG}qpM;hf+_s`6xGAdD1g_`@8u}B~V;DGo-Bx$oT12 z0tL8tO+s*bsa=3(V1g%6M*~Z7BB3;zvzfSYiTjrK>ZSv(Q-OPkYgdE{xiNLA_xZ7} zl=gekVb!Uc!lHuT*vT5ZCO;kHHIfeV$~0VKkCO5XU`is-x*6H>p9;PXI1e!8zZhIn zu6cH_{5v*yVTL@3lV{JogTa!=)jbUZh+^?la5>Qu1Cbr6i^xmd(zu9RCgA&R=AizB z=BF2W8R$tregXVV;7@?zXT(g+Pf?EbXOJH{+V%}wcbM~2`~BkGG9QQ`3T)^JShsSd zJxf2fqcl z4KRHE5?s>z)|=0#OfX&c4iU1RAul@c*9t*b;pfoM<5<6St1yjQ&Cw$n7r_A6YhxnE zHs3A4dW+yYNik50M8XJVR3MTcPsH-#A(q(9>S528O!(glOVm_3Z{iRM#xHwr6&QP%cRhtH33h@|Fy_Kjql+ z>ejl)=GLHwKBUSa5kJkr93#d$P|Gt>!Sa5dbIPD2c2|k!qX#-PiPyjX2mA-XPXNQm zVQ`O+9D1!|`M`9}(M|7*k=;Ud zIWC{{=Tgnrtl3$<)`9NTpK(CZIkO>r8^F3%l4-DBSw z@>Db5Qr=^Z_gZ`l=AjM!QS1J2ISRrt)LghWjwnMQ#Z)NX)>sx`Xuw=dASQuXsa;TILuZavNY@eL9jZ9b0fjg^{i zKlx_JSLVq-g1-g4?bDL=K9^tp#+FVTapi>GE_uHci6Vi-U?mw0O_E82KlM_tPp9$3 zZ24NjF9j|KO!*!Mmt^7_9`C2=m(K)|=&|q9z2HUtsJ#U*vW9-wx;&bWinAs+DYL+1 zTmT<6Y4!f}_tbXUIk1BpksKyD- zvcOW0IbM3Ib-iWgX3H}hd@is6Fy&beE-BZ&0)yjkdt2K!&rH;-$7k_2fGt&LyWDqU zojG_9aI!|z-A}%zpL`wsVc-$K&^-kHU(j8?VedxiC`>*w0Syo{zd9IV;w3~_IY~9nSP`}w8m;T{ zQmQtCfT9Ldj0F+AR&>uFD%{z_4sdkdl)kqa3Y(%qnt9HsfGou3^)r+}{m&I1fTZ-Yy!{jr|s>iv1o z=$DS==a}iP*Zy+kQ3;ds{otc$dK-F@R$pE@cUE!TSa_NQV8EoRlnD#hbCd$ea?tm6+1c8%-Iw3jSJ6=q+6(9pEYN?Am2<-dCJD4Y0!9`&iA5@! znu&SwLSjs^i?#{aIMditVjQ*UuZp_A9Ty>6aD!pGN3C4%CaEf^#Kr45|DrLUNR;1`}7B( zW#*U2BF?`+0+1v>{Wtq?L*MTm-U)kOJR^Ten&$U^@-lL{PVh^C4+EzDKLIW&w|sDi zw<)4K44xHJnc+x?#8Zg5vpdcng-+o4{JX5fn5~dsqfh@3`J3|nMd+SnTP|Se&jOd! z;KzmAGQ`6^4lqs70TB3=I>y5+43Klg?{;yA_2@x+R&vKY3C)G}eju%J{n7kFTg z=Y~1N1(1OUoWxaFreU>)QP0h`>?9YU%Rf)(XJ+X7>VhA`@6F&}1a9|ve4qBn^0~Eh zi7!j^8l{&;srU1L?Wp|S#kN%l3_ZIjvS;v|uFdmZ&rveK$6|9P1l`ixA6}EAiIbX>@eNG?rbFW!2Bq z<(aiKTb>o*O~59=l;;j`NyZ+a6{+b#3BI`B=4Io0io_0g9|mbh7m2ug z1)@|eD~9bjp*PFuXo4pK(zP&gHHENarP)Gs5E|LpWSWW&BmUhs=ArU5+VQQ!Q8sf3NIjM`B_ldxU2_rgS|Qa=2yJNN;D}kprsK+DvMRlPsm=j+qDL; z{UhkDa{^UH+j5hn*S3V|mC&|)g0Z^yNw8F{mM!Kv&Q&%wIGdoI?)dQ7(5&bz_B9Qf z--GaD=8^A#KLPvgCRS?DJE<%(gOoCgbQV@O8ksfZ?YVTvG0RmTpf8TC$B5 zrO8^>WDVHESlOoskfb*f`BqZnDSr9M&-A13gZ~8R0}Q*OCd-eM@@F#(107LiG(=^>p{yoq8hs3$1RtE=6<$(Hn^ZIO+48-v_Dq^Mo9=EwM6U^l@ z2=+lL8BIpY@I;d3-r=UGBtfYOv&H1ad*m{%9ru>bgc~o8+wt*b0oMCv>e&F320Qp0 z0_>L(0n|r5EBx|PK2!etz#jy@37GOf0WRra4!^0E3%tvuXzDK8S_WJdAV4`{Y|%vp z1F>i@6pGNHw&E}*DbuLwmMqu#O1~ZlJ{6b=7`o^9-{Yd9@Tb-t>p!_XO;pSyf|!q3Ct-vJ&23_nl#-<$Dn zp62|$qj8X*RB|kC!^;}+&=RqsxLUGp73Jns#+gsAy5V~gkKL-9I;HQA$s~=oauJNzyK`h0*(JwYrjQ)RmH6c!dShs3J z=Mie9vgSO=npJzLhakFjk z=qC}`2(k};OuK##{0`ttfT`affJ-v{?eo6fu<36ezp@xpy*OMyg@a6*@gA_cqY|%9 z_`HOg_4&g5-s5yQf&&SW@-v&6X}+C7@4Qa)Q*wr;C*y4__!M9UVE9?#f1hjod;I9I zY;}*>*g!5Du&slGym(T3!-Wng8IiKHB|^Mj!{ z?xU5nlgpy29c>8V{@7McAReTIRh~f0fTNqlt z=C&PTx`HeD@(rz9n<-_#P0^^R0NS!JQMg#BxbG(rMT3ok7}>oF)&z^N?RAC+aM1Hp z{RYiPa+R)6;Ufb+7MKW_`kv>1Z}>3Jqw9MT^QfBMyRPHWb!FD+y_iF?YRZ-CQ`nS- z^AG}@so3l2v{BRD=jSVQKM#H<@MXZz{a^okL(e=7T`$5n4vD*@p;O-VQgbRJ*6Ce{ zmPA30$6u%ruSnV~pvsfDuiEUcnpDPTqs!+bxjI|^vEb8zS%BeVwf}vte!p3wsxWWp z==vTrbz?EAS&oeE^d8%~%P>>q<_|KXQYj_YA5GLz+^!auGR=Pfhn|rmJq-Q`@Lj<0 zGXO3rmmH~mHyR?ZayFUT!LICd;Bl8L8|dc&rUki7hI}# z-uGL|bGYc4t^$ZHemQ_0hg3>9a^=w6K&+KQ+7(9b?U!jFGzTOWna*V zPEZ%H1~6r&)t7WOR%45%dyst1Jo&%iKLMTu4Bh9!{}Z~4TQuFT*$e0;y$GA2JJq9$ zEUio(@aZNuYr2^=S-Nw<7XXU@Nisfj*+EOZfQvk}>mq$AuXKqftFg)YD#OvUaf{bt z-{#%L6L7;2_for0w+9+#9eWh~Dd1T^C=1=cf=kM!e`;+$Mf`NPZ$Fv`{xqGz!tpzZ2w#j z-Uf66hQE)4OEULf>^ja5eWfQ{JeobJB3$A=g~_blrQ-i0Xh>t9vc4WDiZ@z6Za>9h$%J*;)Ro!6yK9fZ?wJT#^~j=6r4D z-`3_cckUrv;ZeQZX}S^VSyLL`l+}m+Dn*FAR&|~#AVO>;NmN24L{`4KP5N;UH)Kiv z-Ow@f-JRff1786QA72BPl*=DOt_}5hXgrB(YP1>~tu8!OP8OA3!W!`D93dY=r+6Lq z&Oin*bS8mI$~CXHHjBN&&|d4*T{PLT8oSu)5N@uLL!o#SLFZKMt;T-3O_%c`@;Ciq zKlrV{0l?7zI=H04{&3v5S>3VsJz1!~U8F+PdM_s=*TK$l23>SMmnw3?YjoPZY`NE6 z^I?4;TMw1s`T5!;HnMHwr&Syol(l)-<(4 zbAdgg&&NLKnD)2@`~dJJ!0>S&xTM_ezN?)Ou(I9LcPeBu=t)-UD|D)eUcvFMn!it8 zpv!%P{LK6iKgYI)1C@ZGw**|0iPt&QPGKkVIOs|EVKI77i@B=ZeudqZvR3voS8{OK>tyGWu0kTpXs5@}Hef2@dy4;q{NRe2o$r9ugaJ`WD!d<9JLvB($E~-4uV}RNXU@kZ^l_)C> z78A`6ehEACD)+BhUAr~EufdP$U+;nk&aJ_;_$tc%VNy9uGE?;xOxoVp^mkeSIL zYfZg1Q|y{uBH8ogyz9s;f?m_7+vn#i`{;h~SAo|7L-)`A_h$cWo@O3z>+}_?sbpay z&stMwElZ){b0cWmQ{04-ywGp|_1W^B0)94dE@0@igGYB@-k@njNyNiRvRdzpg!g`J426spkgpRlr$* zd@Ac%8@MD>zvgM`xwWlj=Y`%nUVkyuwX+~AH2sIj->e@$0)Gbh1z_k8fJ<_GeZuM?@f*bBy%QOo?1E{5r?7UR?z;lkU3QwF zB-QF1HVhF;4I8eA3Fcx*!Va-#uV4NR+4f%sekO1>VCe4v_vq({JBEC)#q_kyVwQ@T z_*+N~>}N!cMY*FDr@72+ay6n$+0U)ln zFH2c#FcNqS)BJcW!~Qr4^}=$A-Zn~cdoBT(5#!mRD!GZ2i5@8^fq4mh+O| zwz^X@CH3+_-R=i{K7`NjfIklW2rzs;<9~1J!#qvB?A~cOb&}%}N~-0$faCe=VW2|L zcWDGtzfUi-DLc_S=;O-VE1+Ap8=jx-Nq_ zd&*_~_>eB=e)6p)U$6ba?*kqH4Bc;oOUiYxF{{Ux^*cISA)9JkhIzu8cI)9liVJ$^ zXQwHnp0tveYI@<8Y&pxorvftpL$4WJQm%c6&}-(HDaDlV8FqUaPz9ucSX(K@R`?@| z#ip1(q5%jNqhLV-k-<1U92r3@*TP}AQs#x3@vj#Z{A}j}`_r1N)p(iT{_tVO{o~+= zfL{TI&){bL2XlS7?i)k=W4(G|aUEP+s|TE~1P(j)fOE=WhbfSa$NjEI<|Vw27{5v2 zvL?)$5<$#~lS#G9DN96x75Oz4?5EFmuE11IT^Ly4)eiH;hc%yT;ls?&+rhhlD*(gi z-Qbc2<>f>6_p<(XZpWp3iqvS+ZK8gT0TY0c>xEB())P&OJFVcf5{thmQ2;8O{78Nw zfdY~^jKQO-g2$E47<+?SqZvGSx#sT(^bLP`t=Pi=#em_j3jApPHVs)n2Kj?Mr*ZxY z7S2ZNb<7gOs)}`^j2pw8O3C0On%)-jGwt?a@T-Aq0YmQ#;F5CApVFTp+R@_O0x4AM zOIbLpW!io>=%6ET%iNTk9G+(R%`?X>tKO&onxDUnr*{P3!X6MX^z*7=Eq*my}a})?(_T@kCTO(%3!&9yz+VPK`djKJptZKlq!#p8!KI ze7>e<_T9(DhuYeTRm))c8&|L?oIt_pvAAqxXn`;naJb?$!?BKqdzmv+IOy}~Hj5u|++LxQqSCRl0tA$@1j3^;Oc%Smz#A|h&^?yPOuc3la+ z4mb}mbhm*^GW*Y`hxBtSptm-AfsY1tr0J$E8^7nZ^!I8p%&t-^IVID_m=73wC;Q(UI_7x{J)?pjq_^ledILVaZa+VvcL(@Az`cN>_mKa+ zp<|xM(A%{2!mVDEvq6H5LkTwR)AecX$d)e+J_4u$483vw_lAyn9z(C~!j_KB+r3La z2PvL+EX6*bUb~;4l;G_lAyn9zzdW8+IMte%p^FMhn(|OqZ|U&rj(6 z3H%-4UBJ+Dck1#RI_7x{y&WyctFpc2;^U~XKlSM~`uPdHX7KZY9e|;?$N%2YF;7Ep z*A^~M9XuFSR3@#p_1xvi?R5-9hT#~Z%SsyX>GhJInO}bf{ygw&z|eaeT#||7w|K}t zV^hoKmJa_M==9kC<1IOB`v}H@Y^d5PO^Ww-$~mDBfo+f_XO7y-`KZL|dRUXfACt(?|{#b@N2c( zRvwT548K+2Ub*~p&h10$OPXfVG_N--5Hah5VbUsU%Zcv{;Xw+5J~ z#lMrQFW_T6S_u@)71$!?sk1_3!(8qW{VKOA(-dvp_N6##)bk* z(j?~+ES1D*IB&2nBUmcQzeI7;O%;cT?28GD^*h`7gR+y**rrO|YRs0Z)J=ilJvKha zMZ`Mws?nN@i0v--~74SVOAjOK2 z$Js^-fLIJ5+8GrQQ>WtJ)IyVZMdiI44yQ&YOEAf*0^E=;R%loW=IE2DhLKdFy;QZ|GgO(=6PJXy@gBq9f~_|QrL$GP!5nsO$v~%`<$kG z$j?{k{sH_g;BCOrwL3LmhMsvIM|bniqltcUDA9JGUIY1=_B|K;Lf~S+&^rJw$;2_A z_2jYgV6SaET6XR35PD9JU44s9aL!TQ>y=2Scr%fq7O);dlO%2)+WZ!QaD1fa=outT zxd=t)vr8jVB33tuf$NA!zS=oYr2`p{yfyH7T|Y$?DfS^DRmApS0{u~;c|*%BH`f`_@6i1azZ!8pjkiVt_oy!j%T7p+9a zI2-F0$zHx4i4;?0^l_Ep=B8ph4^2oE4{c6NYQ!FQGvNx{H1f?*K^m+4P?|VN^LSqs zo{g?%w)16-_U-R0>`~k7a%Z1XTn98GxWJwhsPWpRA5onkz0{AXzbC?B9S2-ChpVch>zU~f9ulB<1`R+vU`M^Rzl1zC< zFFJHQwIcXymVFXGYqHihSx1Ns7C|5<{=_MV^+Km^pU!?iPZ_`WfPW46I$+B6i2uEz zW1eRGa)Rm5{ZopTEJ}o}wHfOs4iQ`^V_6Bs;E;6Crx)In9S^188K4F*^k#rd8ay}p z_hB1)n+E%#(|&%Nl1=sP5EFYdj!g_pLMMo_cZKrAs#fNJ-~Y+iwBPmMp8-Ax7`pd@ zOEP-rq2=`UOJ3`J)~*a#YkP2&h3;zT;V_3*NO~;-e1|~dl25Ns_Xzo#@gKd&w$i|G zz|fr!E-Bae_ghoz{w^1J*DH2gA)`NF{R+P)ZYm3=**j@}G%>Fs(n6ZJ+chzFI49TD z>f3sOY`ja?!#RqtXK6uHo-u@RZZQ{yFTjbKky<5gu``_y*=MO0 z_PJ`ES3ga6YyKPdX2-<`z_$TyfZ_iha7nrJF@FEi%y--W=XlN}9oKX8T-)zj{gHCo z^GzF_x>PB`9@h36iclAoi?AbHwowI!S2_m#tPBw~riAb7h>gzrxK3TgvDr)YU(x&? zfgjWFq8D@S0jdGR?;LPRx%yr6hMi{Obuu^0}&A-I9ihwj==#B=LWX79$n(^+@-R-IVg>rI!B4Mp- zvepP;xn-J|Re5X@8&JV|X~3u3PQLPy(Cq^MG;kAO=zbksl94mN$EVls z=O^?&489Mz1~BwK<$rJJnCCI{c8ZvNkluCgMQ^~T*H3sskfT&ReObwGUYn+K4Ho=6dLJQsb?g{yLcW_Z$AdZ$h;5l~4U&rhS8=n$B!D@E~ z(@oeNMVp2UpeDN2QU7EPe^8gVf%2I0egJ$M&<2?DUITt~J-=spceAIYo;lz>ZhPmO zIdZ;Rhp7J%1pE@^Ot!bdXd?lkVu4D8klrcxmv%P3Y2DW~KZl@a_<0@tkHA}i;fLxx zhM)KBXPO=DBSe!QqC&X)61gW+N*?RD?;{`?_4srf$=A@`2;Ko)2pGCIgG(~~?LF&Z zizl6<8eY}aFymf!4eR=p^%^%Y=xP|xbwmN=lQfX>s)Il+xavrii2u^xY+vCq@C{ub zuR+)F^-plOi}!%xs}NjLuJzs<2kmXth_{8)))DLKxMMrTMC%5S$d=32CWDey@)4nc zSzmU5Ujgg`485DdC7FAM-thfikLmxNyEtWtGJwEm2lV|yU(=83>!n8UBDpazhSl(+ zTm@)X2e0-XQvPq+!7}?Mc^T`GvHHHL`5J((nSY%R@pgMfF)f4nEP{h5H;pjr+z<@RV4ony{5=nAx?6+}?`7WmAovx)KETku0bEip ze{_#-%VwN1sE%~~$84_KT6YjTJLp2ylZ}lh4EmVB30^*p-_msZ{d|S)o8Zpnv^!wv zo)7NP_2oVNL-pGJr6%3>KU{B1GSYi(xE^)LIo%=aX$&?9!5+(t5fwhUlirEZ23H{w z7#sg#S%gbPb|t{(D*NPDvPLpFF~Jn(soBAp7+?KA&dvlduBv+Y@7;NC_Dm+3>}iro z(hbdK||ZU5Xs zAI<^Z`?zk`PM>dS*R$X+0xtokU2po|n{{nI&HVE8So_eIDU5&%tfdXsgUn?7)dP&u z2zkHLCH;h^SAVYVC!seBd_Hg}VCb#&zc+Nur=hpHl_d3Rcndd40eP??!OBwhwnrI4 z39~QhKC9GZthwr)!W8GH39bJZh%|OU=}l6;6dc)1%k$ zlt2E^ujen)4=;fK0(cED{JjG%Wv4%{bNfN_mlfce4q6trmNr>C&;ZPa3$9E@${n%O zr&oVocKuEVC$7FV7clgW1eY?*m)CONi{<{SO(jze<1zJL+Guq`O5Tc5#7Rm3EhzT+ z^mb66*{|;be-!8j488FAn%+8JPgtL$7inH`>Xx2pO08D%S2`fOM7ckp&b4vJKw4tu24IScXL%oI- z6(eYrlZRk1|dM;HI6!=eo=K<4?uYyY% z>>OX-yb{+OKj5xtQrY?5$2vLZdBw^+uiKH{o~1V#d-rAxdx84_L+=s)dvhPmeOIM@8&|Dfw`#>^)5^9*tr2T!oAoh77m3r; zJZCiLh)>V@dbWK9;6s5CfT1@RT#9)w&y@%0$~DA-kd3aB*bknb_9i|`t)+d$nJ1)U zB`04JGl7KM+CAO+g|_WRc)3rL`&4DT>aE5XbbojF^rZdY0>2OV9$@(S$p7B7|J|JT z8E<#b+M@l(yD+G;%Q`1-mjnuw8`Yr7aSWnUV2x^lh!C`F7QB1`O=neAy@!ODS z6_F{~lVTMzOp#D!LLAiEZPl%;^edXb*Pw6Y&EJ841pEUq{MB5n`7`HL?z}dqRcXVU za(pZ7bC>e?u#HHWaa9&9Bu`7J7VpBFmpH7H<%yZn38pUW$L7)B~NOb-}^V0%7 zvu~XN-VSU73_mx5OELGN+;Lj7LLO;lj-=8XaoS$mA&Slv9TPNoU12M=CiTjY`Hr#}>YPxLqN{Kh)hY@J0pAA6+5-_M%f5*M)F zsb$O+-tw=;<~J0KC*>JvdLqiDmcb*ws%Yw~;(>U~`@@I|x1cN>N7=D2VpgOsWmy~4 zIj%>)<4xT^JK@LNV_yQ_1^fvx{6?9XQp`Oz_nd^^&8=&8XSTy$;$7~ZknEBjc3L7B zE$t0huSJKk8Oe*|)Wq3H3XAe0SSwGB6&AYXjM0gxDb#T`-e#1xw={oCpl`-+9r#w@ zOu+DW1GtpI#t;4m3}3tbgMcW#GW24=IzJXxnM8GTC+f}URJ@FeLghmc^c;7toL4OW z)6~EGbE>IV^Ro+jhM&*DBbVD&9$@&X0sn9OtY~dJgQ4|w&5lm2RpQO+w_*;D?lO{7 z6^5r_?hScR}ntluQoArM>_%>iWVCcUDF2$S|x$80TuZibsu4 zV?&aWL{e3jMWXeL5D$({Vq9`H*NQdnj7WT}`72v<^$F36NGhVLLmc*Hkv#IE^?EWKr4`p>U7Ft2e04$BjN>!lKL>sR z7`}c7E@iNJ#jI~z)Ut}yN#5?1N-u`DQXV~JD}OUjw({{JsBr`0Wj%Y4^!fBN-_Z5T z{x~1}2;eBd&|l_%Z^qAjn*Gu1m4OT-XJbvfw8{Ddw37&mDC}csSF6<=uN{r=>2}}Y z*DG|N0e=N}4KQ@~xl;3G{1aaB?Q64iv+Z8Ic5}-@?5kxuwcB5FWo6AJB82Qv_asE0 zQ-t70stBRv$8+Pe-ZT0zawv0t`1QUvpx%Fg2d*OiCt&((8Mu@dUqA5f)4SVa>^4pVJFM*qhsVw-_&F}^ zB)Kn9_afff7oVkK4&ImuBy^ahV~^5V72=&owtJWEqH{Kj*plOR8K z9=6uVzhqc!vjk>(x#sGLxQK#b>qoT;U*JU zQ@f*FPj$b2oUXQa1oY7ml275+A3|&a#jV(gPYY+_GdhTgeyb7eRAJl{Pz3plX2<;{~QSH$hN-*T*_eM z#C%!Uyn0omX#D4Gkl|`r$UR^)5T7NYr?SpTl@bDswX^R{HOn&*U}P zc~b*E3K$0%K92#HV(dV2=eOJwgiWXMBCG^R`M0zadnl%BAsJZWi9}&q6*EO#0$C{r`pPr241K>{s&jN;@!fQ1@)BJrbofDrByGbGf zkeFS%uETyr2dTWozKp2EOZ)KkDK2Hfp?{S}KR}!taA*kDvE$b1qU&{}IBeRX;fOr-wB{yTVuq5UCE(w?yFT&9-{(`>aXR=p!1;h_$1VQ% zgU!d48(Z6?4XK7UM&FsmCB2jA2qmd-o_CRu9B)NV9xmKmDe|2v=Gs_ij*Z$$m&Si; zKKh_z&_4#~kg^t;uE&;z1_$FZZxCva!V0sg+x$fu0^QT;jmqe-Yr*yc1Qqup@ z?cPOwrrjTd$FJviz|h+VT#9*r+La?eFps<`)MbBe-)q}lcDeU6bT78hBGo-qD&fE| ziQ|wHRYf(&UPSFratYZU+}cop5gAS9s#e14aN}(Ix8|$erz`W~GVtqwn*hVt%l`L+ z%?pv|JjOEH1Dqx)IZe6)*1ND1AqYq{O5bYqIFieQcmy~#S7JvaSqpK%D{#v=N!YPM zcDy!E#FI~qxM^knqxmblLHCRBHwJt>Fwy_p9_5owZEH86-Vp)VlTdCg!!3<>9KYVJ z)M3VBJNOO2&46k5Z@{Gtrl0YSQLo_*SBa4mvE>`y5G0QbuuD4~>!C8q8YTjpbx1mSca3a zf=LE6y*9r-p?4nm<-k>dq4z`o`#sHfZx8ZLnbOQJM24CovmTx46N8$)I1`VOqCQCAzKuDVUdVuI^VKw z;u|gU==X#*zq{ba>^Gl*PrHR&E`Z^;`dgacPyBpsOMbQceTazAE1B~fnwPKhnC`Qm zwm+2UOYQpO+xp`%<^AzN{oCC^@3$xQACLb~YzBG?tV@T`L=slHb}T&HTP8`&j7B3& zN|=~2JT`_@G1-}mS?JXa3DGbTtM)$@@q+7t{yjqImZAzZng2qvmQ;8KwiVS9)RB;x zgs&~6mMMHAL21QoD2A|Ab(wOB-A_Ftxyw7Dgn`Wdn|^9sIoy|(`-)PF!;ZWQx^s&k zw%v#9aA|1YVyOww`XxNY%kP&l--)$ z2gZRP0L%sqAE$szF>%Cm;{&bTa58UjYfL(i#w1Lb?7A+*U@rAqBo zxWXv{uTv+4%E+d`P}{sQ$EqY&S@DP1m_7X-`;&ez-Gey;36!P&6QN4XtK|`STR-D_5lxg=#cD`qSt{ zW-8C)Bk4#vJWJ!nJk%tDkrnPbHvYvj=c*8AJy*Neyb!s}Qjxu^l z(o>47c&Wo7F4vv%P%+o9&Oo28C-1(g`{GB>QQt)#uaepuYb0gWm<*3mAHj zf$y0ffn_9<@9q>o_##EG8Y@$&+Znz?*DLF(96Sxw0fz2G|9d0xn?&Q4q#15;JVfB#;i+IGh?su4 z?R?!;{r)q3Y0dv@@Mrq>1Mt5Cp8$q`>pPnN!QNYQxzEg*z|?KDx`s*mUQW0?^ZDrU=?EWx2LC7UAHeWY^IhHU!OqX!_*k>z^kyB^r{QmMO-bPG zDi(Xs!3Rzl4AEh%;|MaEJYAG|GMPgE#b`7*ciZwLmafzN(*j*H9_NC009OKrub053 zn7A#sKDE32HIT3Vz(&3Hy8+J!;B>Y($NDQ{BPvu8VP)o&;doZ2B<&-vT!q!luw?KA zlwxk_5ay0sg~tn`CC_HXA>JUcgmKyf&c3#YBUbxx&3F1P&6o7&T<}AH!vVwhiT?Ly zJk95qjjPA^GXDnX?Gy**qkwL*o*wS)hrFN3jfrlmQL}{!O0Uny9ndlT_Zax|Ko4N} z7<#wnbFlYw*_{R~#)i-2(7H~3$R(3-=EJ4$L}6IXB{GR7Lsa!7$c(0(>TsCfh|Gga z9~L}h&MXeQBVzPwoSYr`c*@pd5K#>C)rDbJEC1?jR^~Y87`4;3@3A@Z@7LVne^Rge zbu0Xu_FN8rAMicEwC5vmDP}&b%*n?zpgpU3%B44*E_;7ZC-WWUecYh+G!gF?o|rlv z>u)1yB=;OiKM)OXCC=dx{ud9Yq6u6_qg9Tm_3UuH_-^I{h&yF?k0I7X7c)U_ww+sT zwV%D&8EbWo*6nDxC)tZnT|EtF**k&9ylP!kZ$xIFF} zDXTw%VS}uHE!IaJ2^NQVCH4-d;33;NM)UO=bWQ($0RC^_bHMO5@m|fBkzaG=!vTDG zhYask%$0UAyOw9y3+v^S(K3X%WAU;|KgmwO(cEHfBx=+*H z?EC*7mSY#{(-py^wAbDd@wUU3w?!-26}8@^A4D1zt56XDg7QwuBdfUXpcrJJNbVT) z%-opn2rG#?7KNP0Gx=H1BFOhVj2m$Jis(2#*b`XPV}_7rx9s@E7p^2+t2>`5p-_Wl%Yj{?<8$ zOEce-9qGUc$ReG}x@&Cdmvt(4iT+O2(g|si>v#v7?vKAuPv-k}@XLX#0Mn0m`ri*G zpXfW@kqZ~Kh=r4E`{`yRqzdmH_x^G0@AOkKstwWPmWa-Fth0#rwaw7<`~3Qae(XWw zo&m*xp78H{p7$S?IUxeR|v%42ipZx-EXaLiY^tGl8=KL-$<& zdqdBB8oJAfm%rHyL*r@F&l#WAPTW0y{m=UUz106U_&dORfT{oY{`aO{^VwhjL0b{m z34JxU)r%bDQQ2mwFn&HACV|&KLgxVR24F5==*;)OH}#v(emY)CAg}iGv$dml-A|8C z2mig<4{rwF2|Nmz`s*Ij^e^_$fo-|@p4P5mA70JG7}^;-;HH?}8M`^;eOwT@2}9PU zoiXd;@rSb;gu@9EjHwo^Ohtx0B0Pd^;ygQ@&kjk}uflxN&lIWID2md-Bck~zlU-70 z#MB86#(U)2iv7~hy#@nl>j4{8qcwXl(9rqXrH|1w~lZ;<&+CM6quFzVpfsG|0; zU{uU8hbZL*Gx^v>u$YF=Bji5d7P}8YC%lEty z-gIx`F1ECz#JXqV2yUI@Pz;4}gU;hN8VXi==_SO0FQis*{G3V7*hzG91$z2wXF_e& zq!j;xHyM;9sc;e9Jj^*XQk2M3N2^%4mP=w>4RKDuB70154gdYY!LNo&;)T!=U2%L_ zVM|0!atg^PouHoLKxjxvb^~_Ok*W~mlNrcQc(fOxJjFpcR8`;|fMR8VAu<0=5=qaU zF2QoD+(bZR!D6xvh1{x0Xk4hEu+|+Ka%zXWBgzVR&SUOWdH*IsO=%7jZappP4*^B; zcU+w9ZVg5L(* z37GMC5?sn)dKTZ`rOlfWM=~2cudWV^geRi_!+24Ic|2hw#p3KCnUnN<==JG`zn`UF z30@D31q}UTz@-d!P8j;0AkuiQ=v;47M=}+9$aFQCsGm+ISV)qjB08F<4co~RW1EEY zZB7SL1p_hq?`7NhkEYXggzlG4=$d}HAN+^Fj{(Ei2jEhSAJAA|PBQzA?>8g;f`h^< zw&$R5W8fyzt%&{7XOrc{D8sUzgjgflizV9VNx_&%lKiX>X$u=j3-Z2J&FqM2ccRjkm-f&8JKFCVL36u>9& zS8;V4$7Qh^A=GX;O_wM1EwENeN^|uU~)xP<|(ss^F0Lid&i&bWbGLSsLS}x-{x^L{t>x;u>1TUX@0KCCQ27 z9>-~NklLxp4)k}zs8D)O(CzM~U1lHe0e=g42QclP{+MpJxj!wyUv{yClRaG0Li+EIK>CK z^Hf1RKQt`DKMiq-aE@}96a|-_h_o6CiACvuZ07{xiU;2F80$Pqw_`henst6Xcqecx zVA}CGxRk-xkFWLBy2f7d@grXHG)eq~;~sBSi%I;HEDVOiFoAjL3$|h*QQDVj`r*g3 z^oM}&155)9{U3o#G4ZRG_;zzkqXSGK)+c>3WoiZhka>LPWNq4{c|*&!*M1 zPV?E&o$Z&S!A}B~1BTDjz@-ek_aDN%5Idp*&nViFK=?7P9Mx|3232a9E6n{~_nq8|t`S%#988I{Gs z&PYv__2Sc=_GET^4hBCFXa)@3i@>D}_FgAr<2So;E5ou)#%2;wc_elKVh_9j5HvO+ z)NROcoX>7B8Xk?L7iY7@ESvZo!@0Is4(G-HD0P!L4#@AL`{gz0r=c(B!JomMr|2iZ z@V7s>lp;Sat@Xz4=c3QwCLPsuXixH=_KQioCwaH>K8|@Ysr9C}A23lBaQG=08;kk# zL3S`Wh3&hpD5#FGgVA!eiB*{lR7Vg)UF=v>h+gZRX9G5mxs=XRHNV^8$ISO@!0!UO z0K@Mq;8F&g?*ry~(_%DXtAJC1#4>!vdX@F@0YiAJjTR243rSi+?&Zm^)~b#6Y>&_;%~$$|*?yb^J|8#~FnnDAE~Rr2KXZ?-jm^vDglYP=f}E*&;mUE*z34O=w7J@Au;9~t-Gg8u{fH(>a!ds_2r#yxl65PrF6H+!$AO)Fq? zHgLZ1TkpA?;eIn~2%M742=P_%h)tGgviD3PVar-jyS32f0o2{)| zSx+^T%AvrFoDHLe?CVi?Iwrv6EUtvDr4Cy8u^ttEY}I^OKg#YSCE(@25I~A7uH18X z(-|99jHk0U!^bkY3^uNn2dj*Q5$5*U87t%0yTq?U#-j~<6L8vqdX0X-e14(cV>V#S zLCv1Z;L6#a5h46E`t|RmE+hZE0R9s2>VW!l@6Wr{k5AD;U3W49qE5>+F?F-qqnlvC#Pe`W+Z>FLWn3tTIKJo!9vuj`tKMH1rve7L}4X2;|Zb4P>N#$HOB;L zgOtv%>Uq@!pY{AM?br;y6*v?S?ec>ALJAu0aL;pVTFQebOsh>1)EH}|fJOkvC-uOk*-8^-A75*f8~yp#}S%bTn-Q*46rVy3;> z5HuTwuvfZ$y4G{LUYVas@H8+CFmz}7-y3>nKQVOIw3=@3u;0`B@WjiI)RwakZzq+~ zaV(g1b~4EBYh!jSfknh5c7{6N7g^5r+wap6K5hWN8@LZJe7x*`KR6#U^OkMduy(7= zfes>_c!vValv>N%1J;dpDH)8%5YR(~k3p_I%`P0sREpcc8g)&-9M!%}^OgQ-wtuF8 z&jIEEhOevr?+3eAlgnW9?9Hv~*RGhdk1*DFQ4k@o0U>XBU(k9U?+JNF76%&n-((I^ z>|&951sh7V$8sc6H+#H3SNB^IS3hJiu8=E^$VxbZ<1A*tW{9g+$WiUHAPd_4zciE3dJx$1Q_mTm8d3VerFnK&2mM1cd4hr#lYdQ$E zK$y!{Irj$i+FaP7WZ^9bW&bic4N7}!Ve(1VH_ror~ozf51&upszCOQqvW9-MKelcLlBr+)GlS<(*;T9@pU89_5`g z&IL5e8N<)u!ssDtSY7_K*BsPNj**&bU~&*i!uUGQo4iRZyz2YwBhcBEd=?HK0EO*www6TBvjU$|=XB1!P> zZ(F5px7au}em&62w8Vz$j$oTabp3FLedl!sjA7Ol6FJG!*1Rj<;LCe zd0{*mlWrZ8?>J|%Jy{)SuT@vu_Gry_`by1r6MUulll1?o;9Gz*d|qYI-FnZL?`tAo zkmXJb1V z8%VLo9Y@A!I%9t|U%hKPW9%cm`n#^y{m=qEGk#}*e+}5?^C10T_E)pd_3yJ18?kNk z#_<51k+fDOt(wk1hgjspk$_9%}3KEf_R@Ly|C%>utse}4VKiv*~ zCvcZfV^96m_9gwagT|!&dUsKWsn`BF_hKLfNRfI6?8Ffe{{reV^`8XZ z46Gbb|6t?0{!942gUTEHdOHWy`+e|7fhPvkJ2>B_=H2+d$MD_g*B^cmesIB&x0M%HT`)%`1gRFJ})v}gZcT_k8VL|-aw;UH*P*<)fwKz zUY)c)kq};#M!$ZZT>9&;0iOg+0ZhBw!KFC@>bw)FWwMKpWef#(iasG!FEQ#RUPrahm6d+o`|*SFg} zO@agH_;Iu(g*aJawKP~{w85oHEXnm!_3E*%)pQrUlBL@W-U6Hg7`mIm{};O1{AN1D zXiLW0xO;?AO*Z4x?WSHcKVAXql`*`O%J9t1OP3FW~(be6o`EPtRJ05Gm zPXo>X4F4B_OBrn4qLSEcNK&NzwKL-YiFne|MiS4IcT(h;ItotuT%OKfBsXy zIq&}n{t56YVCYZ#rKX=AMBb<$E#!}GZQVR-ytklbEvLK03i$;aH<^~s0HM#wCXW&} zh!B!gLu5)Y!mQ5_SBwxMDo@Oke}mt>)h+(gtQ>wa{J*f3h~(Yh()_l=kD0$WfZqw+ z4H$lZ3od2w{XNUCzXf?5Z-U{+?V3`nrB_*hfMMn)t}K;kH@r<0+;eyj=Zt^{(|xhw)^iE>FaHh zmA7=;)>FK!<*PR2endM7#ComIK(9~#4!?epBX@#70X*gZP0j-&HWgjNcwmQD8 z`~42+n|bmh@Sgxb0}OwE2A49Jd;xC*lvEXx_k6yNHpUB&!0tY%!y)QbE=| zy0Iv_u@J991PcqXld&%mVYt$(-pbse`I+`cw!e-BKM`mK3_oXsOUa!FW;{GUH4-2OljNE>`^O-ta5TMK@Lz?p*2x8WC>wUCFE2E@8vZ-`~|%y8TCz%K=Mw_&$B)~ znHR5vzYF{hF#P=8|K7|C^J(~@f7;fziLNk}u3+sXNymJ0qxCLFUI{k~Y)8aq1fN3P z4OWv+x8YaWepn2C63`47x~<@Q>W7tUSIr}C*g`MuqD;?*17|Tk8?8?f6DnwV9NNs& zay8Yfr^~0ilX}fL(F6Wl;CFzb>%OV!ns={7Ir#@SHm}{p^=~EZ#^?>gynpA(`}Y;L z{H#AaX`PJVc0~Y%v%~X`(!qO(<@svBDWu(9e!X{4hiUH<;LiZh0j9mLg72xHH?-<5 zUg*c~N~O2dlzEf?Ra6X1#1zA&9VvB*uBY+4x;^P%XX#D_p9#zX4BaEZ_e7WeJ)(8< zksH29_x&%W+vn5WLA_}zmVW#W_)mcs0Yf+VmZm$*mq&BuQs}NeedU@~=~C~>X$CJi z2LhvkuK*)}2vBCN>j+q*Mfn{iSWzSz#9%EdheB`&D(`4GiV;SXGp>|W0@G1v;7a90 z%cC`zkKxs*u25vAE3?|~*8SB8UuK+^gSP^k0K@kS;8F&A50-eK8&_#XZsy8D&ixL1 zLXowhCuLzUvtDi3;pe?ypKQX-}duM7AB(v18cnNZvXf*@jnei%qKT#2AM#Lgc(1ZE! z@aoTVYv_nbEJ}E7mxKW*3qyfKL1^W$_&m%lh{Xtm(W;c9or)s_u8DTp_)gd1WKl=> zj0hWGlWHM+z}RSlH&o07OT-Y7&E;hY0&^ zJ!w1N52%l9`vu$Sw8?Arkz>ywuCl_w$ypMJI@1HX^XdQgZr%So=-)KI%ly9!{2Aam z!1RB?Z*>3f|6|?%yMDI&dCdHms5foi3J7(oHm{H8dO!PgPoL{pZCxR2LoLeIAy^rS zy#wMLjK|bI^^zy3h;I_|mx+@+2`W!5V?4(4y+rOQ;rr1+w>VF&bVArCIZxSW{bsB6 zfhPi1=4suICGcs^?Nh-w1E>4E@A>{p3s!92iWurI2QESxt2#rUNNMux-#MWE9`Kie zSNF31W>J}Y)u&DMR)=4I**jVOGvJefDS(v!mH*}a^$+c@zuT{W>wx+@z`p@py_fZ` z=&yfRfBk)a{jUwEzYqK);N!ile`SCDBl_!4|45JTwBKg?rxAQ1a4fJl{j+kd>Hqrv z`WyZFcMPb%3;Y4#p}nksQ-A%V`|EG_>;Ggx{mFN2D+QDQd&B?oHpBne{`$N8`j=2w zlFDQqlOoL81e~^)^?T`sy!ko4zy4mo{+$Ere-Zp8;1_#Y|1`sXCSxU^(c_wYFU$8x z@X^3HU~l?mx~X?k#%l2EZ5dE+JNUW4`FmOKM0!E5*M0i?qs_1X*#Y(Ug8vqHe{bs- zBWAC^r}Wp~>DOQXezsp4z~=(5t;00e=(;$L3!y#Cq0zy6G0{{retQkl&6Ch!%&>bgj|KLnoH%lg;0nfe?0>+kUE5AVwIUk5${7zON2|Eylu>+K#;?=QjM0Dir9^{$pz39sIH87uv)o-bv;&-TXz z@JYbFz+Uu6wl5ZBtVX}ywgL5C41O7K#opB`0)lZ?+L*QuNefSHe*HZI>i-k?hrnO= zx_%;_i<%&9QU76H{T+V&nLlLvG0_`{7LtjwC^zRg}||Z{8i?`GXHy{Z!w?P?Lf?^T*%KFu{LL{3SuDh#J~lz+P6>d z_UYW=*CTWu0e>2J7BF=3{;c^hb_{Rk=;wr3^M&AJ?QN=@vtUrH(V|;C~lS?=j&(`No#9g zz}g@|-VTaa(~zihXi_q3O&EeRUJ;)PTT;@5Vj~jZwH)LBP(<5=!4oeO-;^QpO4kdT z-{c3``+FVuXkZ**_}v#=%3yk>fhr}Z?Sxh=-kL08!179tImWRL8gQ>9U)1#4sn6&O zt^)4_z6BV1_kv3qOpn-4&%5Yp^CxtM*49SrU+C^|WpqN4h?B%xUOi1d-A|}jHUybZ zu@A8Y0m=bGcPzM+r~N#?Id&A|*W)#^$)thnu>Xq2x77Lyy512}6Z?>IJHYGDBA$iP zRd`R`XmdBT8@vjCuG_tp`sEKo{}S+T0@neC{_WsW7JX0OYjf$Z+1PrzM}OG{nH!z< zuW;>3SYK&Z*3tW+;wR~M2rGom&Jlj%td}(1KI(0tUZER6!B+{?0EX@ga4BPds_9zK z?tZWCrz=!@?7!Q*4fWWam{succl9Es4`1QEtmR;7e+g>C;0R2F0z`aUgt^Zt7`{kE zfRU=YVq!{M9fu~}SW=C%ljT?0Rs8dCBoYbofU+OVKWGy(%N|Jz^8@SyoQhB{tYy#( z3V%C&KBXN$1^*@RE5Nkl-~RVzzcHWv`Wev!n(QkLcgcF1O9-noJC*gc!of>TwDWLL z8O2XtL@?_Jxn%4nxgvq9er~HHg$F5(ztsFR{3W~27lI!P90y2|MKt7;&)$GCJaYp+Ul#^NQh4h?b!!VN=0QEzZ9x!$ZO; z#!&$!Qz2>z+=L%ifmv4D>$+c>;K%HLr-PphTmTq;?**4~rLUjPwMXygR}zcJoXb3{ zPzu&fNWgBu%bhm|9Sux68N!VTYbEKiG=P`OP-r-Y1+fI{!uqO%AM$>@_q?I``UJX$ zufmVWe+&!-3||Ytr405?>G8FK2;r+pH?`J_@KoCHkxZja zdAT1-LOZ4uzH;&w7;{6FD983up9-b)o0_i<=o-Gh3;renJChyi9;cRI7Q+ebEIw;uBU+QoSS(~GB#ULcO^PayUiYsxf0@5!_v=Hz zj|Gkg41ew5QU=rSX8Uc~3iuQ0vJ@GDeoOoP_L5Udu-+IB58~p*^8?wRMyPatVG+kK zfi7dQge2k~sxB4I`rgufJqum4pT7zI5%3Sd@OA3nHDB-g`oaTq?E5^v%$ktQtFD)T z_G$g$+>5=;nY}UVW9LvLfI_sZcyA_%P2uDZk)*Kf5A>!Ags|?LTqvy95hiegI@Afw z$wMc2%)!jUKmyBb3E?%QNb)lWy@*lxbr2whC>YKN=I-!dxXc~rDXveP&hOQ{bx%-7 zPi9Jd#ko(ZUPTc1;LElFA3O6PTsi=A&NLJ(uK8mv_dcwwIxI+rFSf3MryO?%RQdtU?J1^fvx?XCWYZg1Sr?=bAi z-Osb;l_zi6wAoK=yNTIY(;GNH_;$eV4ebARfK3J~-FI0oWFf=9lmF!rq-`~07$!Vh zk@|^Ej`gB&qOM?UxT=VNm5G94*={}#5dUx@$D>_r4}m?a{ZE?THuy2)a~}9D!0mwH zx9$_o@7P~!KCkpY&AFxdU5#p6R(4IF+UG-M_o-U%=Y>J<;~UWrc|$m}v%tC~G6_a` z%Hdfp5Y8v1LYN1DLum#|?zqBOrGOPy8Lf(?&KVb9gU0#FJf7kufLHo`AcRTp~z(auPpEtp!7<;VT^FsH} z%2lh0z31&M7b*6ZMRK(B%=Lb>)Tt-A#XQ`0r{ma&U6mMAVV$9vpPr3|BnFtF$gzOT zP3ihr^Hu-PEMGIh4*`w<3|}XMOW8ADn_BqlPvIX&;>azjDl(vliZK|ldE}CxlS5Q(El`iz>gu3sfRsJSZ5zoLxKf0+M(fN*>rqKw%t;@xRj}Me4zfD^`kVZ^WIx^r zelBnUVESvCclsko`u>C0zqR}RM0_jnXoAwv9=EULMc3|e|K`5vimX~?y+)%Wc;D4> z)p$&)Ly)>_S*9`P5LSIC_=4l`2Q0al(@FY&wb8kx?m4=sR=SLT><}_49xcG=OI^g8 z55}Ss`1eFvbTR;d+k9fz%W+>H^{yAG={QbdRI!uhPNWe!P8SpNJkbYCF)gMd0V_O_kqQqG?P>UO92 zM!S%|9T#ZvhQMlwJD$AX>GzZL<9*-{0uTFtlW{Wgz4uJ$4hNlP3e*Q2F z(*xlQGtsjU3rxkJj$UYUn!IYQbe?YCcIcRU@D1QQfky$u$KSxE3@TT(kShHYGgV3( z{||w03Q!J=0usQX#3K=*`9_i!5!-+hN+c{iP$U`*+qO6vGpsxXyX2-r@`|DYDUzfB z#F9G&yU#T8hi2RAOlZCvKGS^3xGVv00oDPA?>qeOjbFv{Iq$S0YAlpH$wJgK-p<%* zKSp>GyVEX~ASH4q=^!;w5=V7$Rp(|RQw>8PH!l<@sF0Ldwb(3%5tERsLm|5$iJTZi z@UIO?NSdLT1PoPE1DBEvUQG?5TK7t4QuA+pp5?y?yb`De4F4ni@6Eh2pJsloC$F>D z>oUb0^jKlJ#J!Ys;EN-W$8k-s+o#t?eHs2F{dEEOt-u|Cq4yrRlt-V^`@kzd+I>G* z(Yj$p^X5&P8Ex+%8QSZ-YrpN-z0Mns_i?EA^X#{slyw%8T4oj-lcIah0HT3{GK?1E zWNu!}A6KaF*tllbgzFKjL!pE0;>u#;2LBC%Th0-7SVLJqF#ghN~8FBU+`nE?NyG zy1n(bvX=0>(47T-1aLH9=pGL)Wti`uwy6B;4!M?WA7W3We^&;LiZh z0fz2N;8GU-4|L^O>5FtP-HmR0scvtXQvLH3mmg~`Fdr~co&iQT1{kH*SzMB@wI?#$usbZ7u2!p|!&$H=6VI1~8Gh+1)BIp7 z-9O(R2Y(KD0Wkc$11@ElFK-xsJhM(WHgk^3qS?H@4OU8$y*`~C)M@sK2f%*_{1`Cp{WZ80)BjicdP>t?zp<_TbfwYV_J{Tpw%u)K zo{&Y>qpTf-sVv~M9}!-p#zqnjxk%-BdewHO*>j}+Or_s$C(F-V@P)u)!0>YkxRe$@ zF6do3advj&2PQqeM5le8-s+DL-Q`(q_0MptlAAQS#3XRM8$&XwQ1#rogLn)|F60>b zQ*l5egIB&Y7PF&}7^I)*kgMj5KrMEaHU6SgYBt31Wt&8l7l#eBjhbNit4Fw4&{@TtIl zfZ=B$xD?|DWb~T5&%3q6QuJ0?EsIQG9*|g;Nv(D-z{wk^$ z*D3KBDhp31T(dC5E&Xa+9pcrFz5Y<$KbcT=KFtL`3OEKZ{G0(UCG7jh@64G`{riw` z({689Vr|=SHa*j)terSUjl!=X;!I{0j3@F7UcQkO{y!mCoD4!Py>yE62JWFgTUKV6 z=IdGLrun1v(_7#l0v`c}uT)s`75C@Qm+&RKwYOaeYaR9tT(LNh@3h68`z+p>-XJmS z3OspTk~(9IK)lJxQ_!95oHSmVtZ4f`z-Fb_^TeCyRt7X|Z+)eeGKP#g8^)dMMSR(-v z()RN=3tY;r#{VnlJ}dIS94pdi-S)oT?)p{lXXpu=QSC*=v$S zoiWbqhFA27GsOF4*c0r}GSi=R$9t^ABwb)$fD0%Q)7ZLuZPg*9toAXQpHAqR^?yJ3 z_kl+N!_U*;QVc)2@;P$m=H|8D%_7w}^T>SbtR}11O{rO;rJG@*1w+`UM_|AH`A`i$ z6c_;*dNaYLZ1>xrORsrzt61B0Ax8pzF8TBv<7`pp|OEL3*TaF)rng1JFMYBW8op$>>o(n;Nx7k0!J!rftT!fB1UbnAXWzm+~Tx3cd4DB(hrv z7|s#>9p2#6Yoop}^+`L=2fqZk95D2*1D7(`d$$C**wDP8Rs7;Ts&zP}3DqlbC&*K! z0it}Q)Hti%r}rB5nR)eR@IK&gJ`JJtg?8zXM&s*8&qHm3@p1F%kV#tSu$g73sKc*! zT0-+F?Km3zIN(IUwBr>2dn1SE>S@=vt|a@?%I3|)bK1CewalDUdJ6t(=h)o6TYWy=F6uS?_fzmUf!_dz?uq%DuWmn{S;qe~^CXw9m^u#aiR?(c7_oaI z7e-!;#9*PP)Oy7p9p*7Z&A~y7c%IHlYOXpRDXN&K&s`E#@l$1&1jhuEHStB~+2IGt z)@%=theNNRL~}{0B`e*nr2&b$tyEKvr;LOuK>toqh<((|gWV|!x4676P#ocD$Sy9p zpZ_pSrkoI>;vWLU(z=CbW_wZKS`|Jibej{uSX-B`D)@_vwnVN7c+qka=UhBrjx!yoX@Z58lRJ|NrRg63?mcukX5>tC};y_;LjXu3j>ND+o82l07 zai4}z`fv02pbeWh$|Tb>`C~qHY4Yn27i7D-2+Tgw_PYg160P*VS@#$`*Uem72!LI~%__T!LVB;nGeReLl(XvLb z`>qH`)(3pX1BocFXI6TDJzl#8(D@fQ3G%Fbpuc_KQu^QF{d>JxH$u->q?Wdg#ZT`s z#gEagMNsVyShwP^UdHrJ@M1(lJRX)ts0KAMJRTV_5j@-#Pr^hg45bwsiw@g2O5xl+ zK=Zd9`WfiUesT@?bHIy$;jccW`RnuFEg#MC<8E7VTJyRsvLy~}4`n_N+U=psZ13Ya z{joFX{dSH1?JVz?+Ruae@ZS~ZPBH^|BvlwwYvM$-$%~iOa%Ubk3FJK4FY2d*j}cpO;{`02=2Pf*L)?5 z2kZmjqkwUM;fwT--oGDgA258uR*I*9LilL2UT|yGOcHMQuYMi?e0uHFm!?LU_g8`6 z1l$T3dJlk0x$?{7`HUBOo7z^cTDQ4bdZHVR$`d@&Gw8$}XVAy77d)h#xCr|V>O|h8 z-;t`V^ufBlR!O$K#o%dRIAG{c2AA@uLHy<0R(NN)zxGm1E4f$4m&IWKIsSbZhzBvf zbMxdOakUz4b@_C+QZF}buiY1dUkzLb7`pd?OEGe1uKXbF7Ru7-%v17~nnxy-b8M7( zAG<`OB&kaw^3Z`id{-4D0+3qke3Qz%4$I#@Nk^ryxOr} zIaKqr9eT1xWFA}(-U-|WnErSIT*{d_aXSn@l8S@KRH%dCst3Dz%<(YO5XDAZ%1I zo$j58{%edLn(;C;BjiV1e*8+E9mBt#ePPZJo<}8Tn~On&q$m%UxDIM%{xFff;k&jo z(!SIq*m$JoufANNy>R1Aff5%KoL+jqzog;9b`n;63JSZvKv|4{hvjt<t!+FsMPaVPwc2?+=k1=+FD85&x72Cw#3Izs{EgoY z=JGFi8x79H=AZ%yOm(M(?4h3JNXRCVik&DHsUI6_`6q^v+uFv=789OgdnOOL z1pSmp$or&Puk`rz`>5a0j|@RC4kQ67@^g=L=WJQsI3N_+c5VnyE2#~6&ab~w>f?7= zFYCZtflUMIH})yH`$+w0uVtD-He{8Mct%L{`StIlE;BEF2L2}S8^HA6zrm&S&(|FJ z!J~3Co2H%>>3!I)76FrM;`C!LF)=t5Mj|Z{F`faGBw~`KA-|M!Y_U4oi&ZA|_bk!l zxu7b`&ob~0z$U=(a|yVV!QSsZej3>y=J|H6ULemy;V4;?gd=3Q9*pkfWrSyXpDQ;I zk2&;=b);(cYG>UXr}=pediDHG`u|Vhfok{z3_rJkOZoH{`n}`&S9gE+@c23CG#z8P zraN%Z69MG>9|gUS+ubKnr_fDt>y}WBswTcH0x~AJW1`{|Em_|ZxK5{#y(Bzz#F3a+ z>~ENNqm{zeK$0f7r0}apX;I0W2^$h||0^a*raF?4IE8d~csBo@btakGHW5ucz`qSR zr{I=QD-{O1+X&{vlwSm-d%S5 z8#XBg_lrMm$I89eUFPdD-CyCFtUNLdd;+i!VEXGoa4GNl^T_Bm%=zo}*K8e0iph)l znQS)6qw?+K0r?erX}%LK<#L-sDkwu1U{7whod&N~-nW}HA05y!^ZG9E2Y{V`;o})_ zDTC>U{CVw}{`T{cN}iHm2oH#4ABQDBWtlTi2Q-;rCQhbV(@&vkA;2G|!c^iKho zvd8^l-nuPbFptuPw|FdX*f^^U;_XBZk4Rwdkw6l|@-di@qoNdx9GO1gY`^3h87Y$h zzxw=$#5hHATdeNXM4{WYT=TgTK8(EdGw`>7-vWlue}GFFOkUFC)z;?w)^yk}^UgsB zZR4XrbK4!6MOV$k17Nx;wPyzA1(4t`BxaY?n^~#(XsFHh*HZ8%U=?8a_!_vB!R~F@ z{chCwe))~X?ydNjB30hPsmG``&gu>Fo9)KK za(z_V(cstLNnL4vmwoIp@NVE~z_jama4CbyrGEcN^y!w>W%ti%;7fsKz|g%7T*@~8-97hyI*{(7=H=^FjT-N#d+4*PK9m@u7x5U+ z#})eHRptHG_#qD@EYzTNPqc>dPCENKhax8p!G9{Ll6Hg$yBTjzIN07*@fV5MF%oP3 zGUTQRf=4OQJ@Sj=F;B{GQr9|ahP{+^)1t?#556<-E&W+AOj*T11z_4W1KewuZ%;DF z`Rw(l-!4%N(We~}@R=Wd(VDX;$}I%}+b@ zSmGW(w}E#74+4gtN5Q2Grg!*~e#T_dV-KEEnFF{PMkbWNTAOu6ET!gSQ-+v1*{hTv znUggi;o;eRcNF*mz#PEvaUr-A6L)Xt&v!pBzl0A7Wdje>dUk~W6Mk_=*akU_&xG_- z6kFSA*xpqTQbfXuq}cMxumC~}MCoz_kgh&+<(8Z3BW;CB% zo%wDk-%BX8Sj@PZ)a6QDWpnilGzVuyZWO+yG_>mW^}@f|A9$9q0ze3mB0u-IPG^g+ z&>YFlmAhEC#ide8qfci6bs9RSfNuac4xsa2FlIVGjDzY{u|(Z zz>HU7q;A__`U8KwJbI(XW4)=Jp&Cx(yn4pQ6$R-AyKKbbA*!Z~{6rYf#fk|&O@7!o za!Z`s0Eww^d~(Gbd`c8IZVgvdUyaG0l}&z!31zefFr{$GSvy|Q@z?WbP=F2%?Zx%O(_ z`8dCIee+hiv~CjO9rjZ1h~(lV-P4W(Zd^iVNvI|0ulC-$x_tUe{Q6~|X#+nS*an#P zclh6%{pCyPi#*Iy-Y7Z^$e&`!OCKQ1^gw=%N1i==i;hs&u+eWn^_%v82>uV?Q^3$q zj?(QPOrPMjU(@%xzO?OLyH(`4Ui|Iir9@_zpyXm)Go2K)$a0&U_0pf|P5$`%^-KFV zfNufL01W+e{qIft&F60Ng z7hvf9)&JhmF`qf~4s6v=7yaZu-kqG)?bDk!TKAvOI~x2r;6%XCTjPIk=$OwOdJ825 zi5cO3qMzjurC*bqb-#A`^$OjefcF5e0EX^c{`ZES`TP>PUuf(3dAoJ345!uP)2$zq zZSP$0Lx3XyLwAY)y`g75bLpPGYE|188+_>(D0lgEJN701 zuTR>0BlvB=oq(bDfd9RrV?J}}EyN*Jgt08ehjypf>(l$huTSVD$7A;ZR04+HaBwMx zj`_@?*NC=aeVeyG_qXx!-6?w2SeesxzqV1YIk(RPzZke2Fm!JMm$GsYJ-2@@H8yV) zIX>06^2i9o*-j7~s7fHZv0QA~_~&?5fb1r`!{Bq!G!0_`Oa4CB{ zm*=G_+$W7ah z%gfN{B#c@P@L_lC0RDaeR+-@mJpDADt@+prO|uVN4t@u4H(>hVH{f3J%zi&Iu>Pp+5?pr zYtX0;$hoia<9gib&8W;){NpnA~@vpNrD|G%!4QqJrm(@ zA?8gj+-?xzouh+A;jh{BL40{KSQO=TsIa;^36ZplCx%JI;X;*KR~SsqL}S;o57(i` zZCv2LXWOO0^5A~>ZlsY)%Yz3i;+yk^QywgixfsC0AL-qsyUz`{=flNhqJSKziZO4V za~PpD=I7z^UWpSzCC2Eylkl2Vm#kyLwDH@4&MdVNlVbiI;h){o827Ge`FY7$ZH@S> z)h1GsnkF7~ClslpE8MTrAo3>=m4W~wQ{r{%5K;}L=#TqsH7e>>@gNgftof8jvgxUU z(Ag(Di}f`q-Uz@D^nshDZBUd#jsr9cR$Cv#yHy+EX&9gVIIe5eBR@n+W?Y}8c%9?u5 z--2d?AQa9}wBTaTR<2HCLg3+ov!7c!8+T50iHA9jd|i%pz=d{TgwX4}R`ZvhlHIST zfiD0K2MmAfz@;4aLp|R=&GD~qlPBpFo)oxp`5D3^VPXO=O0*cvFNDWV$9gVY%7q%` zj6x$W9_pic(+sOwPMs4H_QrD2Iuz!XI}-y(*_?jdv#;0ubwfYR@3No04E_f27GU_> z1ums;kazrni!s$Woe&up+D%p;TJn9lWO?IWCI5Z;27moe&C;6>egtqdVCXFcm-1if zLD;*}_tV@K$)zdvwEJ}Lpx%0Zmv%l1{ygw=z|j2=+$)3V?fTm}QO2Ol{#a+YaK%xC zF$h=}M@pUX-YZvLcmrc`GO0(rY!>-mVzIPBe@{u@r2Apov@AadgD(V@0EVA+;8GU( zcIprM_A5r7S%DPeyXgNv_TB`(s_N?hK4;&1?v#*(1PC%-P-cNJgQ#3_!U2hbh=?X3 zgn$BxBnS>Isnu$&)l_ZkfSNkuP)*fZYf)3RmfEVRT16jQ^H{A`twyVswzj_CwTF9e zLK0&C&-=dr_w)WY{O(=3H(9^6)*jA2`|P3Bzmr{r@-d^8b-g?y7zn*AH(pFjRhUmx zoRp=>qqM$u%l{DiOZY_M@ig));19s@{|Q-AYd8JK>MR4A{j+tChKce6v4YX}r+FlL z9zS^JxDDT%nr!~h$y~P%MP3fdfa5(2S<+$l`guVozw6f2Y<9ahFmLH8U(Z51SgtjE56coj++L4h?2qNMf>lUK|YBZ*ZXI59U_1n5*H5 zta0Hma(3MNjx5W^j*>f!-ObqL^80b*XTWcPv->q(A?68`xW8#k`4+NdY5>Gmjfoj)(nD{Nsuq2XMgn1&NDCNR#P@gV-B?zH|}9Ve}LDo z)O$^p%Ib`9jJH|7tF1oqvl;nk;8EcC9=G2+9`~Njx3Q}7tgiWXMI2wV<>QcODQ5b5 zl0+T@#skMU-G1+Q+`HpjuOA^)S7!K1_Tk)ul9cx(SG2ySFR`!EeF@=dx4aEjulRX2 z@{Qmo;CS!0-#b3{-X*UtMI}Qf_Z8j?5`$@WIxR!t{?4|4RgGg!x)D?rwIpEk?eZuJUp{vka31Ve%2oq#NR;mDGHXv8!NyrXEa2o(1LtXV;PTduLbYa?#1Ij5(<$pG}yi(#888 z>$puDj}7CPY1x4ChI3IdA#IA@J@F z&s9gqW-}Ku&T60H(E($SljA`mFCN5LTbs|+VUGO^2FbUBBkY%x`EDA8`xX_xJLEOq zXX3Wg+9h#&5BX#8DR6dwVZV3ra_=r~biZolnlOLUx-&Xop5;WOB5!)idx=|hv8s^y z7D{hx=CxY>1&3wgwi0;**a#f|rS|&;c7E*cPUAVU56pVKpJFCvrQ2l=>C8n5Z)O9v z!x!?rJSO9*rMhKfy}duOKVxkBg;`lKAv~ON+$1ck!@%RM!pWxrX*%Le5*z4lp z-d#L6A@_*2oQ$;goUDFIQ9*z9cVW}_OE|NU8|Y9}W|`5zksdI-rB<)-u0!4o&IOM5 zBKy7LbMM{q>NdT+yv#3GWeM-V2ANeqhRtp`0y>K8N2)oRzQOXhqF>q?;g27oyndh< zIQ}unlH53VXMWCUtvr-9vm0yV{*1>b^~_w686GEW+OR?9u^f5mNi`eK$PP-$bmmwj zC&#>0t=E{4=h8!&uFN4p`GjYZny>lVt$nqYU+lXG`7-bw;Ox83e(&sZ?=C*o=7Dg! zkQ5d4Vd8L#?K2qnl#|Y>8EnnyC4X%4qYZtopZ_^>^hnk|0mnB0SyFe;;j1ebGT<*y z&J5)w>8}}{%7Yx&Eqe)0DljEA-i74&%r#hWlngjKU@3T@}MafyWy8E ziP$&bDAss`@xa+PA6e1`-HaPmSI)1Noas~_Qr>P(k>%XD5Vz_>!Zu%Ol`1N({2*(sKq0a=PjpsXhkc9);65e49TsDSJW#_v6^GsPgg*oQ2 zk-^{yPeBr_wGQ#9BF=%!Y;2d$p=n_?hl}P};UkqjLn-x`iBoK$u}9)G8hHws0i3;u z+V8uI6ZT3M%1$Lq+gnt6l)fz}@)k6(^G$RD6XMN%0Yl3Na$n#c2((x`8ZD35@gwBN zz!SjP@wWZm)z5}b{iw7ZdSg8zm^Ou_YJb(c&Ge@nEnsk!H_Zl}k6yvL2dV;5!oJp_3HI0iW06Ycko&%Jlxl{`u3hZ$~ywuza(d(f6z-X^P8 z{Cybt=io`;c%QM~cULa;VaodPONKa^}jtun?Do{lfd(g4Jeu8?9dP_g>@&!B2tXeZ+q6 z;_KdBoH@;VO&LzxbHp=Fm+Ut=E>2$^O-Zkmc3h|A6Sn>zpYeAD@)R%wINsy!_iOBR zXqA25<#_dDXqhURX5^OdS7uGYP}xCgStAQM{CWD3?JyRc$pa4B0*;7g7bV%D=qR36 zmWPTXBeh*6Pa3J=zf}(=H`MKV*67LNj z;Yy#GsTyo-p?S+K@4yo>@tBM}6U+gQ_fY%2<8$w6-Wq+}N;(=vY}udimZiMAS!pAs zj&YHRs>o}yd>31N;^#Kxo55|s@ip7;9gll=eCyfdCqt&kGgqX%f3T5A$C1=F%eNbS z?)sFwn7t4{A#i-dkR^3@Uy$aTs=Hb%O1ztBM!6?seJ#&vhPV|41-~%)xW?)e|F$B3 z1AG%WzANqb&M)`w{Htbgr(#uRK*8LT4(&B%8U{hr*87+6?-e_(_WG@RBhG6^i<*r>Q?q(f6Dk-YV`{5>Bwh- zdf<4!YQJ}U?!6mciLM#4!PREw?{~~i`Z<<&r`0RGe?tBMd<-1#7xsI{=iVJJE%OF8 ztz!=%c`%qRNyViv`1EX7F#fP>-@%GKTIAUTRb_@g#U1`%8ow8un5i#okk ze(!kQyW`JhUnw)~GbYsDuWB%%jRDe8W7IeFDrGU@NOcYCVRjn+omRj2|7YZnz^B0R zGi0L6v*UH|J@ZTWi!=P&M-5k(b>vSzZT+|Ug})kk12_{n{;$~Y9j|*&^E12527h%$ zUFPte+7=8nIHNuT)*kf zPW{cQF8HvJvHO&)tMsDLrrw`~Tn*L%$GgRT-<{uf z8bX@1xSjJ6K9q%F(GS_jL(hqLG(KIOM`lO)z`NcL4;0s*HT*4Bzxe$u@>}5V!10e= zZtQdXPj(uwc1IvJ`$O~`h!-RJZ5xw2b9gR1f7+u#-m1}~ruEMY`ke1i&+&%L@3$#0 z{jX@MntJ4@<^79-2){A76GqUnn66G%R|WnS`z*KQd1Ln$>~iBTmm^;bZUD~in~)`4 zZ2Ma-zhr!U(xf#Nb!#S_GWFEe>uM_Mr|FACX@wqzhR+o47|;H41es@4FA5!lfg9L_-7$! z^LJ4mohfCy=PO>PzAJ-)!{+t(B5imLyo1@+P4qOrWOy6U>-@e3`N!a=!0|qUEXkEm z=Xbh%?#bHd54&8JGGA}*KH~a^!E!#Gcpet-&r;WFD|jCJvi1M8j2-(TPX^O~vtt&r zBp3gl{MYwF+W#Aj|GC~C{x|Hh{-ZbTKk@_MA>ep-AWL%ocjTphrv1;b4kqXWEDqBn zv3{zM`6ZE7G6Bf`Gly!ejN83p{V&Umzm7m23nl_*#}s5qJv=wr#7svX#j?=1Udnt? z`4)B;zf6{zB!E}Pu8dr-EZ-LNIlr$!z8?GlIKEqvCG{fS`cN4mOs&D$LdLrz@P&nQ zraE0~p}f6n{A@?BV(@L?c)x=zsr&fWb|2qd@zun)&GPL+pX2)oc{lhMaD0Bn-uTvc&zG0s zYk1B0w*Y;PZzb|tumL!}jmSOwS1tRQozZmxDo7J1e{c96LZ8dW7m;5FZve;l7P6$? zl%LwF%C!}GO-X8|&c{CPGB=YQyG&}Zyd^6$yhkIS3{C}(w*pzx-pfxGtCS#lWKuW} z<_5|xprxEIivD2y-Hu-8?-R(+ffs<|eHmF&FZ?x+nfKB@wOQU|WrlYSaw%8>9Pct@ zNqhA-i`BJHnYM`wLMn&zWLU(@Tx?b~CS5l^?D&K^xu zVH286)zNxVZH9N?stj)l@+@#5aJ(txo_RN~+_bvu(%dhLv(55dj6RpYw zVPr|Y$luL8pN4ylKDxTQMzP_)jh|jshIc4(378HX?`&jAd(Gbtti`EgD9$I_Vx45- zOQeBIFYu054~p)FHw=FR`kmj~kZ%Wf0mpwYvZUVot*-=Sx;Eu-#iv*S#@g63j<;|%&p*L<;CLq?OX{uPx;nj*dG_h2@>xV5X~JtDdp<1C`byq3{9DlP_`i$X z1a1b7|2AYvz3|&jUD1wr*MK!z-gnUJcth2620EM61oR^~TC}RZa*f2c{6fF1pXogh;QDHN&y=ILOgwj@*ZK7Z z@(19r!14YKSyJbCy6)51@fqF?EHBfXSNUarc^}Yye*}*AZDdK^w~HBnS2FaZNiPx7SlIwbTYPT_AkIf=J?)maWNn7`IOOG^3^?9O z>Ip@)e>S|y(=)sake7gyf#W?D`AhR2SF_=e`kM9TH1_gqGf~Iuk{fEcp_b-uO0K0&*<27VSy~*#jb)_}*)$I`_x{$}%vQ%gKel0o%CeuaXdxn4P z8JYTZ6!M8+IdJ@^Axr8_{bKaO8eodu6%v5u+5&FQM#~M_W_68droDdO`j38BzkiMV zGI$L*{x)Puz2RS5r>Ek}R1RDCejpZ%F6&DS+I?>>%-@f|au#qw`Qe-iyN&h-@Xv)~2b_+Lhr)SGrj#=PXXIbG*( z_H})y)a{>L@)|!deka#wc#lM01eO5DyA1iu@TMK_!hlIx29$qj_?yt5gh2e>iQEc) z2OR$^$i3y)2QK$yKuN}cl6LF=hD^DehkOiJ1RVcjWJ#UNUDi0AyTq97%4O(I0-w6n zj16Snmd{YviCU9Bvi_srmHS7KUk85#j{j|BN$$Gc?f6JX_D27c?9mZ3M$%7@l;mB` zk~ogNW2gYtb?W!prqYj%JtZ|6dyYds8Jr57Jr&53dJzvUJ7-l@GHaV~bk|Mw+AVJr zdR-iLAU_5kw_L*L{O@*rB%3X(<5Kch<5#RUqkkmwBrp{?zh)x$(yuj@to6`Y-2L#6 zSMZ79Z9uQ{>uThC!TrGT{sdXlUj56ko=D%f2)Ns;@$&}I4<02T93{~{D{>{Xr5gr$hA0z)B{5NoRyoD^u#iQH$-nA8t{!c=>mYW*i zSIfm&uhf3VNn65R7*PA4(W_p$4*$d0S5lX;?+E1M!HK}xcQUf19^!P$%u~~6MirG- z>&F&-Gk0ny>YYiOEMF7)Ts$5?ei}Rr9N+WElDdsYHXG}HA26fg@q1+pkDPm1iV$h1 zQ~;hVsl{I7KaHOQ>odHQkmrDdfa5&`SyE4a&gq4p$ZbQBgJO~`$!^o1l z_cM#F7k(D}%kZ*qSekbb@+dG4INpiKl6vsdUEj)NPx_wPa?#UldAFd~`P+zmGq@c% z-n)<`Ie)ut*BxtdYChHdI3Ocw^_lT^^gI5$!GVNL-M@8JmP4v z!-(_s=^orKGb2g#zJq?pA8es74~l@}AAl^W7k=yM$tKT>x*afXw7li$b-d>yUji-z zj`s>=NqhCX18esK#swkc?=JK@-hUy-&SsBu;CKs=CH2N%Gg8eW7_%HmSMlx!*qSW= zGW0wCbCE9xR|3cXePl^{_j^zF;?y_YK${FD=gniBuZ?^MY(S)ziQWb#tjl{FJkE~L zIqdZV3W2j@0J5as$AM`fwvSVk>MjagFWH1!^e#ic<3AhuJh0Vr3UhD$&#=~dky2E`R4}1umUw=iG)PrAiHa1n(C(lhfs-(MOxew+hYb#bIPnkLW zRC(q#JNcFFi+Gc@Yxa2=zt2Lx1Y8E3T~{DW>NbD>GpmYIEw1QGlb0`#)?L^BF<%|; zHOEZccERt;-H@-ao*PU6&c4aWl6r{SDKlqD2j)MCU3a}Y&r8LPeOusn_C1XJGGPk^)UVPr{PGJbW*@tFY10vQv(LEa3` z1&)6!vZQX~)ib+vW>*1e+&W|6ynb9CsH}i-j6VsbSCVh++6k|V%Uj6p;1l5N+Knu! z7jdDZqh}!Ni$Hf%N?I*%>ii7vDaaeZM&NkQLYB1Gcx15_r;fz^1vUgp>DIQ{?#&Ty z;!<;g@w)~6&hNEfXU;V^8#w;2AWQ1O@2*+`X_T^Bt#w+S&2^IVrK&cbRh3*>Q?rh` zm(`q^+9*qWmeed@DOhs6`5m4!t;+mbdX~rBB)g$>`S}LXksMEJsOxX{eGu`hv9Ha4 z{B&`sxq$Tr;1b~Ca2c|sZu8-P`zT1&klUTiupYO#jh%+|yrx1Ek6rld;_<1(;X?L5 z2QD6QWJx`g3s+NDtvzdDMYVZYm3mRSALBV}Dg9{sVD$z{TZ#qHN zZsXqtTV|G~=Oz0Y{mohWM}C7jYM=x-zosGY#jh@Nde7_1noQx;OB?4V+55ISt5$Tl za8H{$H@U82Bi~D@@BYHmVEx#Foi0xAApZ^g6F5J&l}&GohlAzC3M%1iW+eW5eEEn=SlJ*52LN{Vv@cV_YTxddCl5a8mI zM3&S;d`_7;C3C;?<*ey;7~3ltXyQ{YHo-5?F>gk`9o%JY>M=h53syC7KMnM3!bWRH zdzKx2zQwtpU?^~L8i6dShd8;GdSTW2#jKFi&+t>fHrE9%Nljdm0NqBpE;R3B{9l7! z=l|D{ZvwXg$9pHTq;AVem#lJ4lz!3>FbTLW<7nwBwqgjNt0-;hU}Hx+JkE|mmonZB z#sX)@1Y}7)_}^7Kwb3+5-M9PYmVXWU9e*S8mEe1pQ<%H;e{ZZ=&ossUCd=2B#kcRb zd9Dej0O#*?WJzDrUzSHzXReRcG{v%KgIp2!76{G8%Mg zy9BV~FPSx&nP0Qba(7)ZZBNrs6W?9f=i)o_a-L&>1A!!Y-FsaBN3G6u>4w?-#};Sb z_mF=8ZUrvBcOXmZA-<=S^x`>NqvdNypW~AU;)B32;P^%&OLB49%Ia<+U;KVUyYF$X}WHfzTkc$^&DzijCs8~*6~ z^RC8rL{Dmj^&h>C_n*j#D|iL~9B(1ABz=`8ll@etM$} z-*)slKX)KM4_*R}?^R?;-TRrv)(bz|EpPI>8Qz)5hk(O@<2?#lQcr$P?}eWYqm7@9 z=yQJFg8VRe6ga-ektKESXBJy8{Hz^gcw^to@D4*B2POi?I|W%%Pkzqmg`eJ7!?y)} z&d*DcZvwXg$9E^Pr0)I9V(W#U?UuJ4y>1?H-uJm4fI-0V4nvmI{XAB^o`#OUJ`Ayo z#eTD!(3M_M(>Tufy9T|^-;0p11m6da_c~-rJ;c|wOc?`cAbK7hWZZnb;eQAHjz72> z84LlAKZz{K#k&(ChpTUxN*xA8@<_ktKbpxa)&Ydk%in{>JZe^gI6Zk*^0o0FM7w zWJzBl?iu!}1YKr2o|bj%m&Xpw=_y^e`07}#-fNs_>}iM3*%P~#IUt}IIC};oOX?vW zr%an>7T))?V7*|H;ai42$F~9bOi*t*gsEGeC@5Q)Za;mX!_Vt-KY(_o@d<97AF%JKsRc_p`*7CPx@dr21zJY$g z#b+S0q#okaVJ5+si%}0{Wtxf4GWcCNy$<|k$N2m&Sk;g3 zC3Rb0x?q)2zf#~v{gxn0gCUc_M$3$t7M@%KM*coC+8Ga6TIU8BWhtbK?(ouG+Mzd!MT& zJSB5XT;74#*){TJ_A>+r0B6_1$dbB^%a^yRICXxxXbz1e6>jPc?TH#E{5OP z_bcQV!7kwJdktAq4{@V}XFb5_eek*)V$ghz*1oZ~WbCU(-VDwK&c3b4lDduGe`sBC z`5S(jo2SH8|;rVfvIYv9NfjRH}MY>sEm%LJ zZXFY|R(1dFl8UwKy8c!;JH?FBTzLlf;vN40!}X`@s5ERsa%>k_z{ef`X8xwtjAq!I zj;rOGF-$gbYO{0R^p;@-^Gx|@CjVXesK1Nn2;eH<%E#5nlJ;H?{!i)XP;magQ95K> znfIiGNZ()j{C&Z6{j{Gxf2;2Ee}h-AEoI6}8|A^3moJbLck}!QxbjknEUAa~DkM(2;oTw1Z^%!P7?4lH^4B4xD1R@> z{!|#1Px+SL=PYFT4fM{Iqp72jP&gds40R6a4GF9H$8Y)keZZ^F+LIjRpNvk9JdSFn zXe2l(8sk{wusM#X{4neP4^5oK|5uP-18w%RZ2v3jIOs(m@Lqu51>R02qqU45TRjE$ zWcC3`BJT^v0GC`Gt83~i&XU`d6lzl5tJ-)Iz?cLt9LG_1&26@N*JSBE3;AsDl`i$_ z+$lwCsrL`G5*&0H&0&Hd+9h+?S6rvVt^Zm2Uq=1|c%uvbY|ph$R{SjHNWy-Q)Oxps z0*(bSIWMna{gdRMl3XLF!sLbd+2<2Z!64OI-qgLBxUWDi1C{nO`8^jeCOp(v$%sPb z8D({w*P7jaOcuN^2N5(_eU1FB+yCWOl1h_mVdk9()Igs z*F7(Jq>0xut4rdw8hI^PpRK=Y^*T0%m}HBivGLA`sf-v=V)bn2Z<72h zdLBXkIe5zIkv6b4(NE8tboR29l<2i;+c^Eh=cPFkj^wj%ec_kpZ{(i&yk%=@Cecn7Lg{9Uu`%jSyD?6eA7$jNCu8j8ml(cf=yQDQkhg%Z0LOPevZVGN_-0I< zK6SRuK&cX6%(HyYX82Mk8or(Ab9}!?eiwWQ9N#C%l3IIgU#8EVG0Wzlt`q4>(VAh@ zYP{r9!<+hPhWA9|O0Whv-u1|mN_+5gYRQ~gQ)bwVG*u&AH=gfIe3IdP2)#-4O8I#P z`M*FLaJ+9JOKRiECY`BRAfn|J=Bxg z(`L_}SzP%zf)$;nl)?c6qmue z%B1Veu8zb_CmY`6&oaC-kq-k$0mpkBvZUr7c&AO9F=P64-MgV_&{va8-FdYmZ^LrK zdo_BK=oNqOLEZs=4jk`O$dXEWi1W-@Q%Z=m%V1rF(sk&yj=bfk7~X;%8Qw9-Gr?To zcvHxd3VQH&%CzZIrx0nE!=@^w>(U>xnNuqa@5Sg%qF4OA5&2&50C2oNMV8di1Mk$C zv!_p+F;Zi`P5N@NPkG62;P0 zcUir{`yTQK;A8ul@VWa1IsE19wN>lrdovOsBLeS6xuZ$n|Fv6vC65|AMc=W=i@;+0 znfTJwsh?lFY2~`LmHI^4%-xeAXo$&OPML{M13KhK(R&5*cfmDQFCVAvJbitw+xS0; znLwWgE4PUu8D~gZeXZti8${nO76Oh+9MAOik@hCmc#owi@{uBdnPX7wz)!+;uNnXplt3M_v!pHcV z-9al{@H3wSmL)6Neebh)c!)$uhR8w(+Yz6UW>7+g1&rqs3k*!~6L}|blDLEu@|R}d zfS+O#XBlz}p73KLm~jTi_`(GyWF-~0UHExsyd@90FX#_ka`9p>Q<Ku1uv>N`{ZTTC2AW9j<`Q9|xdIdAKLn zlm}uMChQ1#q*VU#&@Mf-*v53~!Z1pwTzm+)LgnTQwqYHg( zgQ%Y;q0B^~Jy)_hlrXi5;nSQ@7&lw3-reYM<+k7n=0bwOK$5&R=XTxSUthIeb}}tH zt77B2D%tHaoSMw(1v2K@*hk8wR2B)5`)7t_y@Hjde3iqIM8EiRCUQO4VtM&ET^}o| z>ga;l{Ql9wD}wNsncM8?)*25+%w$X`BQD8)4)3gy5m3pzk6*oWmo^Rrgx_5 z{4)l1_@@g`Ho5=2Jd43o9FW@7q zS3Ym;biLM1=^=|3rfbQyMUtKJpoVDh`&RGRUs5-$-dV^8fP;ZcE)KL8RgC%BM(L9x zm%paf&)-Vj7CXO#d==bv=jA#S_&VsEkw zQRGHx5P{h*A%z(9J41T69Hd)hGtJA@`ns^qOUm zWMEilW7uS)*M5e{$M&arh-~vQ^lQ!q0SVxe%SSn!bYsPaRa2Ffy$SXj37kbSR%_V3xUCGaf>BmxDiPh7XrRN98w}9VXeUcF-WDjKPYq0uu zX6btk`E~Hep7hBuoYD7aw!TKIZ{RZ-eopSkY^SN9N%s=U0n2V6U{B{1lgxHk+&E=h0-FNQYpXPoe{mEeYM1JzQl=7M* zH*j_8QY{bDfzh1~ z7d(0I7+xF7TwIj6Qy7(**S&r3SGwPDInw!OlV>J4HmArl6Dq&R z4D69(`P%ZnY0J{zM7_q%w*0@K%ewAQ+=YA(xX*m1bF54zvQ?~KHFJ8|s)~)9*UHdD z(!1JEdfXmKM?e~7QnS_fPL{q8kUs*SX6ajBp;Z*1qJYz=xxF%f-(vrM?28$DW+Kl4 z2bs_GFS_z$dl5F;sY0v2)%l;L{|V%$z|&pmXS{W-OfWaYUs4!% zXx&C@j@NGWc`s-D?u*>D)SFAeAcy99hH<^frIsM!#INOxR(ky+;k*mPz zS^73qu+Rd##BIF;?1*_0TxXWt$Jm$PuGrku%d4~x=AV-k*DBNcNtarNZD>=t)=9CG zIezjpg^$!^?P-Hsy57rduE|z0GHiz{ymqViVxvR1ch@5~fm^clIy+ggBc(>x zsX$>$_cyrLlYEu(BCU;#ge1=~`O$_BH(vTz|MQCYPK=;zL2Sgl6{i3Qq=YMN`uwghz=Lun~`q=cXqAU+)AR_ zl*p&8YNeb0Cg;ETTOHSrk^ct%*|k3Ich}dVE}Yt5SH_nJfcYl@h{~uj<6+MKS2OkI z2;`%{Li3ppf%AX8IY7dA|1Ksv|4mS3NW`RbO@1|I>1{&38Qk8L-c2m*7Hf_3=j*`< zR{$_AY4x>b>H8FUH~72@eUz(;b@lF^+L(KlRw|Dbq*R%fuGH$C{a+dX7a%VJi_K>p z{NGf!uBu8$HMu|2XrxBmLT5!Pv{*}gWxRzX)mc7~hmE90%hQy_^Dy!w;OAZNtgKsA zzeX-1WtF_@rr*@R=WS%9*6C^Jnu|*w?_niPmrkvgui&+eU*nKxg9FWH`uAMEX84HN zMj1E=7x?^3Fr(hjpQIhVIFKHh%wxydwB%;@N}HAE6`W`C{o*X%Taa%DclF4-v8sA4 zbE>6*H`&z^n5;4lq?4VeA>(Jt^6k#z%l|#+!+=4+CFke*ipn)*>+7n^s2!4x`|5e) zl8x^KQj}fGBUxvPUs#uv2Fp`!bn5!I1^HaCwL6}ATD7ves&%U&lCo0ZeS`6QT~?f3 zjaKhNS$cnq{36)Zo!*UAwd>9@CO#?TBf&A|vkvj0|53kAwhRrkT~30$ zOnRS0!nsjuqZ#n~iYfOES^650uLR%kN*|je){B9rR$ms)ZbwbQlPij;)m%VQR)1TT z{&wWQg1>d4|BR}$I1L5;rY=3rC~Yu_ckLuEwO0SKHdAM$f3XU=8k_;-S&Mx0 zRb)wSou+$Vy}o{uEJT?ko%~vFn_uf4oX=?TAT=lykNKgf9}RI~JW&nSf9|zez83Vk z{>;nBuYx~V4q@tiF0Sy59nb5yN%~k!eQbhua~u85OZ?%=*L~Q6ubTWA``?*yhdIcH zfun%)=Tu}#13R5_oW*0;*AyjF!~NtC8vSj4gG>Y|QbW~n75HJlP$^!ypj0{cyhh94 zg#Ov+mw5gR`7!XM2=eh@DRBPRAWK^Jq_JbgFU)(E|N7P=W5w`R zbz|r`<+rL)&oOymo8KPtp7zIJMGT9g;g{*K$Zv!9fwL?BkH)UuyNo?AzOsj1oP9%3Mz)5(9(gY8w}u}K>9^s}h5JdI z65bpBd^I@sTOYGVg?Gy}e?9{~!=r}=&+x$1A0Fb`TpNDV=V(c_RNdi62PC5L&-~n_ zYL$xS?Yo~`xyDzD)erir)LH$3pIfR?N;<;GRjx?eE7C3MJRA-^Sb zYh1rIMjvCn#5TXVuh*jHg$JovWCYgaM8>GuQ$y4W>d3$#7K_q_h$O})CyDhL)bn8}z}0V8Dz`kx>&n32!Lxj_-#{C#6_ z`s00gzs#Ewnw70IivzY6O1WUYW_Vw92!nzPiFtnRJ~`1yPMrAl=l*|zTBa8GW3_s( z<-5k7R`^`~dIR~-;4i@0^LJ!zPxtM#lvBAv7nPo{Na|9pcYaW$_9vr*fSc$Nl|n(u z_pJYKD^Grwa=8S#3Y-oc-_6L9YHjUNN_*!QUX672nz)Q=5G6$zUi8 z$#TQe?`uR`p?lQm5l-z3fzpg&?nWDJnLynB5 zxQ4tp$*dVv^o8o!f>G3*zKYf&7#j(S>9icAG6Sm(+e|zf;G?zE`Ee!k&0srl_Uu5G z?M|0xKK1p+j@Y}I za*;$n8Y}|Nj=Pa1UGTJtN5il8j7!bN^%eC;tgESz{^Ib)&?Di?Lj>iAfqwgiuivKY z*Gc;IyvsxRnAy_DyC*U{yxmu`BSRx|vGzzF7mQH@B89QVDv!o-CCey-;4wc~p>h&I z&O?5`!TeTI<%OcTrzQ07MCGSJeWIiCLPa!-ha`e{)aP$upqH)w;H&3-|1Lka)-MUJ z@WX3WO|X-OEOm?Z|Gi8;3_%_PCIILEWMoM$AG+vgNxi7DdmVy%R^#70=yQCZBS+s?UJh`4`N+NC zTipfU_p?_wdGl0X{l~ntSibG( zbN=l>{w4S|aD2}p_kyp=tg$W4E}su(`&V+iiRZu%GJN|Z&jNFSMr;m&*m%GZv5MgKF62)A=dyf7&yM+$i3jJ?t*V; zHeZ9~TZ2BwcOLRZ;9J1)U5?xfz9YNfdp4V|-SX{1pX2)r@+V+7aD1O5_kwTrN=xX< z=Zl@nXX*|U&jsz7>*@;RN>B|P-Ld=H^7$vHc+2xmb^1w35e zgx_iW8~ah_`j|pK9xMfp?*U{lRM4! zg!e(TL@npaX8skhc;SeG{6h27Tl%goKZlNRToq2}Lq{-BQwIk9<7$4tpeSJAZhmf% zBTvxhbH5NoV=B%{i23vjgAsT7J~yciO8wQ3=-blx^_!s*)Grlksc_Nq! zoPUQROIl{{uh#u6+dsB6T3xkq+$7l~O84X2{QKy^(vcnZxe_ZfSVf6bJ$ImkzWf7q9g_{96FI$kmSrBm(w#*XdqB>6<*@^j>u!E3FA|=j(gF107B4CyCX7#PQv<_&cv_LG!!bbxed$Nnt0CGM zUfM1H0`$B4i<6O8fO5+z%w4yC!h6zMp432`gfQvd$GfD0hm2oMS$cnr{1DjDE4`&` z!?(81Ji#=&A4GSF)w?@OZ|pOkF@nB8QqT4t!9lb9PJ=H+*!Lc$HOk40s6GM6jW8ae zB|edGc+Hlt7TxZ;v=#Xha2as%Cx$U4d)Vn#cEIWbdnwxt70K@hQ8VSDD~ze;rSbLdx7K2N0zkTFHL>vIBu!)#kOg~Th#fX#}qR!M?I#b z-nNCjKdEWzs*u##52P)tV|;RwR_C=nZ1~I3U&=?qzaIHq&;T6&708l?*!Hy5wy$zs zJfc==gFN(MT;xSPE)w1Qoh#lgDWRF`b|e!-8R2o!9m=>p%Kad?ftu zBY!U3yEFU=WJ&$(ePwoiC{5G1_}l%*e3mRueTvZN>PH}QTktG#5c*%5ZhX=bA@^&AK5+(7%}-4~w1P|!(gWO#Ud zfajgYP4@o&QCb@>j~f1+=y&DoCFEDY?=7b=JO8rp-|A~>j+LV;3ACvoPlbc9eZG*i zddL1f%`E@$7q^`!{Yb!R^Rc+X`UNSOyAcOy31xJAX!~5b|3#XZc>2uJ+ zq|_K*$EhIRFOMOVXkL_l$ko2uE;KroKW6-V2)-nrNWMOY{5E(WID2ycVeBdSgNgIb z-)CPBq+D;>a0c@+HY_>2RvaJM5bOwj5%wE`-vs*Y3H1eAiILU0-Us24bizK9{>P}u znd&yyok`7ey!wbC z?@RA!h#JANf^Ub_2sNuc0C>*MfOji$w_-Gz|q;P0N>=Q;rL&JC);~g8mT!n8F z^S4GD{6r#toT^P|ceduAR+#AfE5F}Tb*73IOBG8!WBf@m!sh&0jC>kc37kJ?AxrAM zJ)@@2XH*=2ijpN1ilM{v@ub$fCm6!Bm|>V1_k&0uMs66%I6$#`fuv^3--3R}--`SP z@JHbI|Bful@pl}5lyU(7p;9s%{GGaq8N;qfy1qRg3}KX57Vw>-7Sp)yCRTS zqrCN5>;LDO>)jIMa!>^v|4)!5b${K1|0vmXUu-C!R_2#)3zz9`QNVcKD3v#o=>WL_ zta;8G8%&O~=J%lef_H9)u2JaKK%B8U{t&x zpBDuA@ex>mh9NFXawLAfcUfcz zBZ0Z}SNh5wOu+M&Gu33RjsAk=Z$Q7xzwaU60`35g|F_7JT>fRZTVu!D{5x^O+RB<$ zQjN*QKkHnKZ?&yv6IRIBe;iBVY#W$Iok%diCeae>*i0=aUQBzs!7#TYUd3G>M zXYBM~uFlvJGB~fxjHMXls-p41sDnmlW%5L>NQbB!18p5~{+;pX9qe^+{x@>s3-*o& z&Yu&JCG{9*J+`TDh>MelP*uOHh8N;cLx?fH(JGH}IG8&zF@JD@%8%#b66JQVl-vHi z4+#dxd1iz(Fer{k;(1c42XoIx1y2M+=}<0GKQd-`wJ#gHo3P9ECm%$99Q+bEyZd+{ zZFi6PpzSsp(aG-S|7pA1cNx2vVVASJ7WrJz0G!=-B1`Jg?nBMpva!5m;bgyL%Vg<~ zvnjw!(fujLff{AQC+%Y*p}76!H7@HO$4S`Zj2WE5O@i0aR{AccIpm!m8?WN5JDe_2BYMMKlS=U%-cJ?9sg1d6_^@DT zJUm<)PzDgDOVin(I997)(RY2#*g0E;ycBkboyQ`d0cwG>^KZzK%KvDt-><#h`8qDw zJ?@C*N!!SV#P|I#;(kNovWR~BC||#Qt(jpw68`HL*E>}h_ z2LZOP*VQhrju%@O74Q%!q5g|mv+-f!3qtC1xx|n1M^G{@2^E~mcLj9i6Pxl!^ea%u z@mTjVx-0z3Wq#3!@M%0j`;NcQxbUSRbp{U+w)_6LSOwqyz#qjB$`5_@PM9u2HC_Et zu{)%<@Tl$m6b;Ku^m)l2uvFa@DqKpTi+#cka{jmd!X2>m+ob!H1tpYpt`;zv;)Xp~e?FpdcApIg9Xt0hD~YBWFo zQ^oe_7aKe(%;L}dv4utIO+~1Ov5DyLL=Y54f*JiHeN-$uETZ-)WK-H$KAWe8;?l5( z<1y8jYaczU246iblMT)e{^2KcLPd*qi+_?*pP4u`;b)Sc zrJOy8{496@xHv=t6NiG=jsM|2`ineTu3S@E!6i~kT3hg&@aqBBpq(-O_B;ReKx%GN zKKqP}R5M~X`syRy(@n&~$?z!kg`y*QS%@3V!x(#55RQc|^rK@#BmC%4>ck|j?$0U; z0W&?KKTtSzz8`lz#^%d*n9$YF=IUbaIcT+oHbB1)(XTg}-|C}( zc*T5ge&7#f^q?`%dn0j}m>oHr-tI~21hO;FpX~Sd^YRLqqY+cbg-_&@c&Pt@1I87o zc;XVD*-|IS*i&Apf3UP5^Fv=QIb(w{gU1G^G7_;cyogfscRw^Ok{i^=F7VZm_^)=h`;&oNb#B15}ro7L#9=RhPcNId-H&VYv5H&N^nZ zsM88ntn#?ru}g#eWOy3eXMe{(b;Hps zRN;W2;`Gv0i%u;WJvFGPDmdVTpknEPqell7CyX6^0CH^X@}OdCzXOg7Do)&Q^ua;J ziqyD~LB(-H#vH*Xvqy~&Dk}CLJu|3SdDua!fc{f#NKmmPIc9!PQ96ChBs2^heKgJW z6gt@49o_DSFIC}#$QbHpgCA@1qo>8DMqg2})1!5<)1sBJ>CqLj1<{4P9|ac1W=7BA z=VOr<$7V$jkIg`y7G1{AC&vzp*6{O@Kz@Ib&L%I}-{jNmcql#2aUAkya2{~^bRV*$ zopxMl;IBHj&pMx$R;=43{r2Ilp-s<){MOL#!uqX5zrNt>w@UrG?{myiqPWJrH*=3r zV{M+i$BrG*QDh2F&kJb5ho}NBb0gGhoe!&W3b}Gc!@&%0eQ14Omg^PmY;chuJ0to{ zOl;oA_!CQH{27Hj6C4PfKeKX;KjC+cAMdnx>CXvfn_=hH$hKj31g{VC+lGC1-s{7p z^WS7NJ@R>i=~$<#MYpNo2kOY1RPalc z7?!xgPvl;wm`o}ss0=(^6|M`u?l0$})Gvsi$ynaCO#0*ofAHvm>T6;3HUlrA@}O*d zhVzGT0ehaWMcS2c3}^0_7eluh5muTT(&m2(C6OeW`D%Zetcryg+775 z**_MSVnLkkSDsLbtNnx;uTtdG??Vhi+~xT1?bsjsMG_6tVc@8@Z;U(o-4zi%OPiuim;F!X-^ z4i#zk6BqI)oa-07&U=A+F%<5L0f#f}CXv99lH65m zVbZv9&-;l;@GHf144IF^R{a#hYy4nbEE*lBUQ)4BqgVU9JnF}09s6WReaAm>o4@2> z-u)l>;ms#s?5`jvma3=KiGTB#FIDHMX!Y;>#Lv_!nQU2gvA-s9<`aJX@d0M;=$ZwzFO`d7Ay}<3MJ;=>mR&a9n*KYniNlr zdd{D!|7ynQ#Hwg}sC1=&ky<$J*p=!U-cDE*A#%kk>F5`^FSp({d6 z6TMi4mq#Z>5?A`eF7XrJ1Uzq(xzZ z;J_kgJLWPgGCCoWb8kB#73CU5xXd-*>bc87WZ5a9thBV9bbklm}T+ zAFD3%)lVU7D>L?74WH`=+>QJQcpNx;{!(D<+4h#PC-p(+_IOoIsT;o^*^qZh(HDLE zhP+?z|3x2ppw^i3w)LICyuvtfDxj|zQj=APdKyiRFjsy=)m zk-RFDzt4bjdcfcHgR%Jmn@##(V@7^x^pN06_FtJCrg@_s&g6yzXfAoVl<&(tz{0X(|IZ7pdS~Ke}&p%%s?S z?IvS1)OJVs`iSKI%Esqm6%6Q(8>&N<>FH6fHZbjg8(<`x`~Kj-amY^l0O z#eW#$W?+Y(|GA7FGaIpA@s(=OD)ldEZqE0I|IXjfd^~2@$i#>@{PB!FPxzf*Vm_QU zY*J$4dwyYY-|zal#W@$MNO3S%m&5k0rku3&&D5(GklzG<2Cke8C^Y3{e>?wu)yv(K z6X}GshaL?+3^5V^lF)}C{oFO~y;d}pOv_Qz!&4bmebuMro)KAC)OR44SBk==ehzEu zms1Mz0s{5*Q0y0e=*NEIICXGvyebO@`TFs`S9^i6w-$TceNO}OMc`Y&*?T#%Bv-$( z$2Y3i)vTN(TSW43oWb&$!;2}&i4PYIVzfj(h%_ zt>3Pf;JigQk1@@bWPV1{doq&bPjzayJgFjMukaj=Tn^3#&YvII?;VfxOWF;)AcV8t zhTQA>&HnX)emn18CT}+R<#Z6#FO|CA_xsZs0&MkJ=(QD=-(I*_Eq)+gt7;z#RlgM+ zpbprU)AzcZ{@ZfY^*Q~OdNb(%RuEhi?f*bL_;H*+yseP2#p&v9R_&HvZ1Q0@cDeDn z+LvIqj!rQNZ z$QulX1IIfOSyJcmzUsC0Yc{Q%#C)B}TWU5=tY&`tp zEIYEsjJ6#oWioXjr*GdvnN;PTM<24w6?As-DE0cY1@QJacl-}2YkV}z-@k0j#o0A*6w~4&gbGdf@fiCxmfMXUGIk~ z7?4{K6#rkOoe6wZ#o7PQnRCv)H~Y;-LRfMMJ0b*R6A;1(PRZ?HuT5FZJwU%1n`u{#NXL3V;K;Qr5^E>Cc zH_1HD>@&|i^9+O8P?tFps)A@xAS*48Plcm=$KfSXi02b zbfGW%hqX7G{I5fPo4zNYUjnZHo4$R}5*otuEE{&4{`=VJ>o=f6*VkE`hV4ISlK7<{ zwb(*^m#HwVbi#hFl)OhaFU~HIRYBlR;0tGrKSQnc&hvX}w$6cVM$UePMhQ}|2qH{b3(ABktp1o#O-NRCNt{``e7X2aw0+XYV5Bm|!@t z@}3MW;r}Z?O~sQQsBAIf49E_;+?d~JgnZzI8Zse(hpOxoF(0jnEz{>MFv;>=f zhuxog?EGt$hAyZ3Ru@4k^)qFwn~q!!$OW8r(p@`^p z4$ixJnPA+NIL^0CJ*g)ybXa;Ee;E2v@c8k?uf;YTCUTmMA8`j2dYDLr@gHate_l7w zDF9u74IRk8kutB<{*>b+Bkoj6-js&%PA3leEdAzc=vuJhIO3Ih(>~%eiKr}$x1mkE z&q2Qce(@i~tE-GiTV+bJJdF2Xn|Ql-_naP}H?ZMo`A{Ky1MLM~PV`~C<-}q0VLkMP z;Ns(mSMq`U4Xd6Ayh;mP8^*h)OQI0DTwu;qk<~bcH!HWD4NjP<~8Jj70IAe45h!yFQIHfS75`@@@4M2QLR#MC+^VYgi{{ITTUD{-Zjt{ zfQ`oy?}RnWk`bfKZ;dz90%kAk59G9Jy(^E{D%R+_?A-_iAv+a5h^qXKGu>9VIme9fc?W~cd ziN0lNS68pX?XP zWtf5=>sV@Gge!Ydonc5F6~_T=)kQhupO%>wJuw;?%65K<%I+K_;_QxP_Y6uheKutK z27RI#{8v^qmruAPmpG!i)X4%54S=~IF5YK zb!Otq4KiUXsCwF6>{eY9S)5O{93Wf#KB+ja6a(6BYAl-t{ryxg=B2pNZ@cjua6i)n zhjc-Tf2|v5#PV-&gDY?*nc)|xXsoBo$;!yf!0$pd#sTuI64b$7YC7u1gvyAFNXcn&$7!(GbeU1bB+0mYTWX+Ay4$o82p>Orn@ANJ@dafUY=_h@*z5EM0w=bW8 zP5%mL2|Gi*%jcn8`Vs1Z(ese_;yUjc_iM${`JbMC{Vw{oD!_oUIl~!rGP=?Xt-Ov$ zhLF+>)zi;LZ-5gBfC<2_+^(y-$iZZOG7DHz(#d%0OBZhs9B0Pn;1904L{j8tPT&xK zy{j-IdQiEKDD@NNe&VV-U3Z|9xYwkw3HcMqFXj6t^xNPaVAJ;}XbJ80TQ+^mRRtcCkf@wrJdPmOm}0E2of@couYF2|JsmWX}_etVjT2DFb!CKXF*G7uV1zNa9pyQ zEMzhGl&lEr-8^+72cI&~@Td81TGYjye3Kj*xzD7pf%xor_fzPXz$?J=`x070dwUtn zuT49iuwJ}5N#!j&D9ifJIQjqZpYm<->IW>EFyr*kwtTcvf06+xw8JF(YO-$&@i2Ti&P2PF5OhC+`3V}MQ9 zY0wgOx7)9?`7Zw6S8kfIepb!;^_7_LknN39<~;uG^`&2vjiBzTG$j^~L^D(9yf-T` zfvbAR@V}k-ZMokM{Zr5cEdS0Y9Gb7zuHEuqRkJ*qtqtzezCLny$quHNPl*Nc?S2o{ zUo3b$++$({MZr&0c|3*c9rJQCx<+($kkgjkVjfwUP4=g;2Tq1|mQ$EyXb-Wa&h&%q z{Inn{8H>nIyXr3ADSO1EqY61~IxdF323!wpIv#Vvr!sXt6 z4?m-O&^e+jaEg}}!)%EQc%(YZr#wICK|4N8ZG~w9Cv3v+AbhP{IRnv&gI>VOH3nM3 zamY1q?Z!2-CMgh^+{8||I9F<}a-Iu%sG`XEV&(0TSt;1I1|B;R54-AT!bd{=kBmH9 z;AiEz2l^54V_@ZZ0b0WG$}^dxEy$D`FQqa0Tv{bv+dJZ)gz}~Yqja!xoPt49hn7%| z_=!n5211vD;lRpq2DF6ZmE-hUq-c?v&*KyL7jdY!h}vI5J#!iPQ}CcI=T+R!nb;$v zfaN&VX`K6i%;ZZ0{A|Ab9Qq~j3b68g2K}GNQ?qPFs~e;ymJc{Va=y#xnn5EF!R~w1lJ2D{3|wUm=`8 zk;$l?SR{VpQHjnk&U2o@7Z;m*T{#gIL#9-jJTX@&^}SeEnyD8X!c3yK3evk_E0e;p zF#2ejaAZU=+(dLNPuc2aNQtIIvsi2QR`>f(^KK*m0pweVd@^o!9?aesC;<{=K07wt z=eP4&+pqK+kd)gDC}O0Jd$ozu3S??j=OH5#Kl_F@1?p&`p^yc z!py?YE^x}9H1gEJ+m`bV=)1tKHu4<3z9r?EBO8~iR$eT6e)`#Gq_eH}#3mFAJ|-f} zlRJ2lqnvJ~W7c`#{M5)*Seh*75zwQ-cpyRY>1gwcw)r%B;Vq`cNo?AS2IZZb6d4wpa z-QnwlI&SUv-L;uW#G&V#{5~R$pUzl7*>Gy6YosJHngUCS&m;rMoJcp7A4gKZXDUN( zdM7e9HQUF~i_W%3G%K1N#e8C-baztmQc{Z<)#{aM5lQQwG5J}G+;%>CBlI2Md%&ja z8E6UZ*KbFvf9#}fsvSZusegMJOX2`vB3CmH^E;d$|$;d%Qb<;&ES zn`)LNi@Ug9m2Fix6T2_auiv@)HC;dV^C1l(8&aJwg26Oa44U|fb4sd`!w)C0X6wcw zJd7+^$BCcZEP87%JzzzXf^|5P#PlpZo5ARs-*@5bfa6N@-4r~oVJoj~VHz+nN ztO6-ambbX<{K{-0xh#leX7J4vR!1?`Eom4`;q;Hc%5eR(Xpo;4?bV&0tUKT7XJk0m zNGV(n(p?otQhW^UsS)Yu0Mgh;PFE*WhsZp>%Z!{_klq~^!JHzCl9fJ#hn!>WqT=c2 zWcVxwqkXYQ@}dDXA)8MH)R2*x*m5~f`05Vs9_QD$K_}LH`B(71(?%9AWa& z+6T7pH`~<%sz8I1=AoP$FtB1B!36juS$i;%D&SL2tS7ecF+Y+L^&)a2;u;q#TGkPJ zjXYKGD-Y$_2z@!Y8d!O*hnDb4J3lS9UQVdxf`(=K0Gm|D26sDNGjg3KF&bDtM12EO z8Rr{nl2h9prl0sMzu!X_j$~{Hmfvg866$|t_R(*B%e*bWb8FVrtXsKs>V~z|@GEJK zH2QlZZgb>OSHD*1=L6=uJIr?vnb+gN-bg-zHRd{N)=)iC@e7$6FTuJw!L=v77<~CA z{avb2**jhWAe4%sN{UIE9L_ z(SOu)e;{V>PSblP9S4we6LQKp6FHfET`&UJbgYJ!u;D243S%6m`$(+^JK!F4KNBB- zFPqo(<~2)y_n7&R^%?z3liZn8=iMr1+!3`3ADdEWo{S6>W-eFWdj92d&7gm^n{&N8 zMvC}cl{zdKPaDT}`4KZOEB~EI$8O|IAg82bFZBNcH9DD&T4)KILc5Wc&|i)%k99I# zwH>9@^roUw&lb5&MN{3w3uNN^sbLy&x)k~=w89ObB;N)58*I72iR@owht*gWeB51hzb9j4}DJGfcm=pRxIX zS=khlk29Q`W7-YQFL+4`>$CBBdKzuEn42Us)ye+YNRFfvtz|A1^L`9wXlx_h{Pgi; z0!m;;0cKjUu~?6umYK*HPw8Sp9;A%-@8G`aV0`vek7KF%6H=z))?q?)0$Sb)0SUXy z_h&Ol^qRyB$Z7nGN!RVjUCU=F-+Q2+08as%u75yF_$q8~)(=vfbWN3X)vIqu^hD|0FB+YYHI-iFBno9*{seI{ z^04x!iL}=l_D=m@jl9#xCi~s_(C30xz{-0aw1izpn?G_I6nU|Qyvlo6j3IxC6?`i4 zq5<0zDPu@1j-3`cAyPnA5AbLE-J&y6CS*(yhpczG>eWyh82sJHvk!g=K1%-m8TxbZ zPhjOyrp4)fQA{H7Bh4OR1- z54{Lf1Iup(v;;eEY0qzl8E|sT#*7z6RnE|2RVvERA;x7uOUS2@cov3yo`-%H{0>+? z3&t5fD?&e=8^ZHPt@T2uD_m^jqw@;moU`6I=iGwF&Q7pzPIWF`!L&77cTVh6^bv)Z z$3$oV?u5nmzuQ>(+$oaD`5l~rbc(F!nVu0H&tf~XguX38UGfx@L~UC=s3ho-8TC1E zB0C|n!WvCP0TB(NZe^xq_KsF8g0=H68Hmcg^CAO-54_k&r}ST@Ja>^UJ3ss>^efR5=cXYpUThxs`_p>qlyxTIsNerPO%wY7) zVd^EzfH8g-wZ|n@9{upf?Adj0Pc_?}aCtQ69M(3`)NZMn3|9Sn2YqJ8#hJp}?#aPu znJvEUo)U~BO%St#IZ^aItFI4hjuD>+Z@W{1 zsq+7CyQc;7qS-=B2qwxZ^KExVaB8&M*|_A|p#}$~om@K2E?w2AEOTd7!;Neh^uTR^tq(?~oC z;*oa!BJ``^bzu4Y23kUgd@9#YsF*YZ*FkOAy>%$N+K^vjLb6?-1U(vz2bSM7XbDGa z*E(JEjK{Uys+z?y(pKj>TU4=+(YzQ5&(Z&XAmmq1e53eA(swWPPrx(4@_Pwd!mQ8^ z^ns@it>1oR9r2UvM(p(PwmUo)wC&BW@Z=j-l=`c_c3nw_UO$OVbbYo8MH0Ouy0KN>zx}H1>{Tz5PltuJ%_MAcc zac1M1725q|t!`smJeIR?%7VN2Ovur9mPvZbI)&+ZB9C|(21Z?^*n_|-6E7Z%B zg?=gQcysz1o%Bg7s@F;K&AF%wGzq2P63_{hfZ^aGFc3T|>IV66A$Wv-ixX5Cl2d4E zymB^EJEM##z==(u<}=^K=GyPX3ahA|z7#iFe2g*84DutH&|}2+jrpS(Q@2!h%TwYB zI(YdzzbNP#O@Ruc8F{0FJKe}KUMF`KGOv3o`))xvLpSlp)zpwfR$8ZcclNOSdBMyu zE)`4+7NCC4rx0;$!^}QCIFkiiCk}T;6sM6Teif5Lo}8%U_!Q?yWh{-|>T-secfA|j zD8FHMoU@l)I3DAIKBzi59?GJ>ixyOD%UK%!I>NbCcefNaA<@;8S2N{N%4g|6eg{2d zD(f3y%j?_F65jo}={F`ncWD0+mKSBkD7jG&lGXb89aq0j*3U`$xlBLrHNW_=(w{!} z^y>`$eAE1@$PBW$SomJBfHlJ?O0bA0*QTOG8Rd^g?>x$fid{(N2Fx+=MuKCU9Ca3T zawgO30e&}?7deetHyX52T~bTRGZ^u_6PR9~-eqWNFj5w^(G*6!Un;dTP=9BL;*2cE zfOTSdH1#z3bAa?G_$>LOrg=^PQh?2$F3=K=Hhy3nvVkixW$jl*jjVFEqrZ+aj&p;2 zY6RO2wo*@J0g>os_*D^~owuxqz6e|jEWhp0655}8wC!if`kLx>OIHkGDX!}9urGth z0}-x^;inUAmX$>u9~fNn9gVW$Jr~b}Iy8j*TZrHC{~Pod;7efn=S@E@{@Ur0=`&tN z4Q{w+9m1W#Y>Bn9!@j$Bn1157{nQ1}4}eF2<^M-$3Aes#>fx?-^R^l5^(jWFkBwg6 zhsEzhiGF73=kJX}hlKvH!+hARKbWsFA7)ZX#}ReDVB1ByRW!SPz8}xYQ!CjvnugYe zbq!V*Yf(>6VP+MlQch44Gx(0)+4-LGuX5FR@8@oWV;qyBEEaV*(9fi=Y(_GDXF#t2 ztAS15CD0O%)*r82KV!`_t`J+Xa;Y5DAe{wOd05uef=rBS7_MFC5790ndt{`Vp21LX zhC0`2>~Huth4D*$ehvD4@F}qTW2YMab{w#8TfgiXG<|+xo0vrm!dm}%cbeMZrmK9^ z+y$Hp`64=Pe{^(Y^gGe?-$e7@iK_k5$-NUr9X(9FBD@+07UWW-j z5c1tkyf(dWLVp1M2rS<}LrXYjdJo}x^aR%qH2GXQE6H~b^cmnBVEHbAmT(;D6%&m~ zE4Y+UC)geo*(2M7Z4Qc@X!!0TUYp+Mp??G32bS*#&=PEV?YjQ3@@>oYNC!gp9C{$6 zA>`k0c9Q>e=nAk9SpH{2OXwioXN_89D_Pr2FF#k?UuILoY|2kp=8!M(l@2oLZyz3AS7htIua0g*zIwJ*dvmprz<%=EEqTsahNc1Nf6u zizVKwAw~|TJUJig0o@x609KAw&=PvJ>o+$Vmy?4xZdg8Q5F2f{pOjVZj5QVZYBDwn zUzVN1TfJ_~`EpR_Gh2zJbHiLJvp!tdGiT3X^P?X&pn1GU`MDSbO!soUXiA7^G#A=& zw!7+MBZkv*l99U+x$L~+Md+8o-cVMlC+)}EL*x}nXX$&tsU8T)dYq*It^=9a$WARb zUEy113~XwVU&9RF($kXjsTt6-!8~B|Ydf@r_Vc+z_)l45^NX&pMXtT$(HQi=o<;m^ zq`I;Nn2#O`3SAL48IgQu#NEtiHivT~>FHwimq>o+Mtd{$8?Ej!{L4ldd0UVtfjlxl zI0*ff$T}}6?_6jJ9hR@;*CaL!q^GVEad~``o|Sxy$P*89B(FFsUS%IuMiJ69(#U-~a@qE=8~Q2m zGhp*Mt-{FNz8^XypIhZ_TP;KRAB!Zk^jh|4Y;-6)E^f5!T~tXZ`|w~u2eJokWS4v_ zJK4y;5cv{(mV93Zy%uZ$R{l$&CA7acpl02=wd>Xonp1NTd0kMxoUvi@+)U>c)HhCE zPlXjDi=09D`9}9FAwJshYa%|IU++P;fDc0+(jMC9Q^<#Hb75#2ZT~@2mJ{6n|Y`VT5{@#v5_Pug#tGfd|)x5@MZuPRuT=O;Nnh$yI zB0bssuFGumI&a#0YFuPo=D66n)N#*8#;MVNkBt6ErTNK9}DvHGlSgxNU%@tFCM1eWy`Gm6q7$6A=fBUB67Q@WA6xh0W0@%XbGc2 zziJC#H|vqL>p2QAb>*s>{)6Ne!-n9@!55!(yz|?c{3l6nP5idL?}gqEJ_MHkN6->%y|?41PIozneson&)_69`J~4Jd(XHIP z{c}{Y>MGqx**B-ROmCoVqp0$g+40Z3NGudUbU(nYc!J&nrqv%g7$4u z2u=mgTwGx3$ao~C8vc#MZ`1uO^o!tSVEMleEy2zkZ2KeKGuF>pyJ5;Ev&zgZ?L9a~ zGRvHGxvG!L;=PX&-w;(HpTdPnK7FCbfHGkDEQ6LXIXo}1Gu-co&&sxZaMd(JTr=&^ zuA07bFVA)Mx%Iv?tU#49kV%%6-LFS_WN1+7BC;p)Ea9s0JjMM*|z2;+^Nk&L$(dN3FUY!^fM{1m?IiL<9g_#kU?{ZeA-Nqd&Y+~CgCM(EF)LHGn0DYG0SfVl;a@h_$h!}DY(9Q0vYmyl4_JBoKug#Z`p?`QzT4E7*2|1+M!qh? zZ-ZODgE2}M=ymLGN)C>ocUMebyGKe|^Dzht7=*~l^O&beUWzpIpQjo5Ho?D)&oUm} z0DTwO1+09pLQCi%Kec>^X6Uz-&R5CF0z_<~klE_9IVnYaXf9?296Q6hn_N68%*F8j zkj4rlXX5OnK6wcAG%yQTIhR69u=?b;LVa?Ze5|OcIbZ5ylRM{GmumPmp6z(8lB-0t zj34T39L)6|1Jpt?@CM}<=cDAlOgyKQ%SgGviO)CkG{R4suH@Su=zZWlVCDH3TEf-s z>;&7$qw}qGnSyEHoc-bt%DLK;%X$a*>dB=UHnDXnQP1 zHW@K4G-99!#VxXtW3Ge zv5{vV{OmgUkI)~3PeU1Gylj82pp6_;rE-*V{;bqlD2E7AeI^KvVZ5WNlKDLu`b@AG z*mSOkmXIFWpZH-tB!1R5GNG0vHn`n%m-;I+HkIyRaC~1J*Q_XDC5%}WHn{j8%<@W8 z$nP?CjqY^)ZeF44r6ZR|by)uJv-$pO=nudjftBa)&=L~u?D~+WrgkOXv{%$Dm0l{h zYB`$s=;AEoKpj`_=Bg#^uLRs?Og@iQl{yymzaihU>LlNJ(2KwlVEL|rmSE?hZRTTk zU141_<(3ZPhJ#*%^I%=)I#)8(NmtN2%1o&BM0R|MN$+mrwds8s`nRA3Sib*+mJkc~ zRc;993%Y!l>-Ef1>k{gK`#1HO*f2hdy<)BufX}&wA*v87l>zF0te_(&sp7Qq=u$D< zKiij%;6~S*7FiW#Tgrs0Wk#;@CCUDv8u~JD6|i!B7g~b7C$X^ku=z{H2CWiCIXi2s zOCj8(^y^8yh4E>Gc%z&c`4*OI@Y>QR-Ybn$4$*EJ&b`4@P(jV#$^p?hY>gXM3rIDu&eljzVe(P4~`#~eH^1KHv zVRx8MyI(sjzruAXm6tmuKlAmSk|p~2ru!@>%BaXuEKe7pE6P+|a7jKJ^}%hf>gyF3 z#;`{2=FiIw@^ZlZ+-O=%oPa&#`im7OlNYGxxc_o=_m)%HxlF_xs#%|FS${)S=-3=5vBvQ4SCdTl zXy{YHTwwWcf|g+K$831!uyVS{UL@C`?(lagR+#BKP*mvV_K~-MqZH{X5C01)7pKxg z@`FxMcW!E~8d8i-Al9uXt^v|0nqRv9{jS@`-|XoJp(vyWar>&-kdw`w8# zp1KQs9K+$6a&hToHCF#O<7~)pH}NI-PSX1V^e@0`!1DVPT0(ohCiQShHMg;uwIF4$ zE5Np(7!_t0Sz2)DCtLMOP2)TR7bHbdP>LRg8^ldlSHI4rchtEie&Ig}dJdQeEdRyf z?`?l?-|&|$*Fi&MtkDN~3yM>n77nN8 z&J&8D+|uC;Yz2ek&Ij=7m79vYeo3d?A)2ceX^u@Hzk1@c z>D&eV6YvbM{5q{XG@W0C`x5YDR9htz3mHGe&ozmLIf|XfF@0tOWVhO?a-0v{hKN&C ztQOKyf13*#R7oa^In1BaG3PdjoxnGRSY9doT6g1!SJ$98+9}PG!(JE)@mE2&Xm`9_ zyBy?o=b)qSq|dc6IF3>up>!m)TxjyIDwJ31$@$P%fNOwF&t2i~t=-gPp&gaYzmrG; zOB9?nvPAhAOB7z2`x$TkAa;CR3-A#l4gpf|G})QW`e^#e=-7iGvl}DN3F94+po(jt|7mlI1%3;d{`!?`dHGi7cli00G4zu{NA%Nf3Z zEOJPwyV%HkJM!51>;2FVfk#6bW&YZJpQo*yGuBVm3#|l_aic0g-xJ1rpiR8d^SK8F zWC97tj(1+oxf@qiuj5Zm+|RfP`A0%i7=Jl&S-F=$*MODB8Gm`ry46G-N9;ITcM^@$ z9LBqgIBfYn4c!EuZxink=b19!lUC7xP^%8?BWCrl0p}8v&(5l(yq%ysgKj{Ag4#+5BdZ!7)X%(IKsGs`{>quCf>@Gp}O&7vUvnKtwU`Xe=Tv@ za=aS)T5x@v_>WPJrf(}HJ4&5V5_dxw@18dC{u=rn@P3N4&m{YW;3 z@%CF|(k}hj5a=mj4Y2*jBjN9D|8L)6KSri8tLQ4Tu73scyh2@`h4g1}<5S@qt{RvB zs2lH+mCv<#!#d@o+|%x^3-Y-rZ%$s8GwQ4^<2W}fKP%PBKI4km5>lgwbQzjIM3wTV z;vKt7eo-(!zfaIN{4C#D6tQ+2rf!IFAK>Mtz8^$hoBw%h*$)D}fK5+7XbJ7hp^cpq zNo%XnCyBYG^BL%JSi!v^i$`t6a-v!)@zm8BzO}?_`CbQo54ay#z7Io7u;mmF=h3b9 z9EWp7QSh$WKSC3fn|0%Q zzFrXG#+A(GnFjMFm;;=-ic*G9ewE?>5%F98|A78CP!}Zm2hbAQr#Bo=2HC}OZt3*F z`OaUN$N069M&>sl4c&LG%eHlF;$Cgz@fb6YsOo zFM(Hp&A(=72}g}zdb<9}p}U~!J1$C&zeLXA1qb7!|1bZh;kSkO=zewm_yP2N;9+3- z{RmpZG5IBj=C(Z3TX|k%_#GrZ%P(U+^B~X}Sbp80kAq)0R2NiTx;TT>HMmYDAa(uq zf0LgfzZJx1>%|q&H-c@z^4ktAp?&!s+TXNpTuP%Wy^2f9O1lp(px!rA?}0O1{g=e( zIJMWBbhZ$$<@*ol&Ko?ZJFt99pe5LLcclL25U$Pct4en;Z9AJH+vUWi4dP7`(B-_U z@c(b*SOFg^#}&{wf^ERcu^n1M$LVj~Xw&I$l=Kf6oC(jm(D(mv^-Gif((A(X6R+j_ z59s2J^z*>-?FTKPqx2ubwb^~fJ4*Unb3yulbZ9;x7v2*NbvGD!YT;+)xd!@XupL-= zz5^|xgM2tk8@jDrbFPdyt+r;#5l34O#%~PMPkff&=g_GadQKLw{Bofs*z_OP@3!TJ zZP{aHug=((r9JFsk<a zEA+E<=rIEj&&;jNo)`m>3sCrf3FWG-56d6EW$=}8@LSM#fbRh-*B)pIdA~OLqn+Ws zEx1!#RkL)%pw-pqhj$^`JJvX-@fTkow-~!0FNB|qce6(KG>ozqaTGaQ4UJ5}mts89 zBYl)RA_($M^T%>#zQE2MyZ(>t2ABRIv1~Y(_ z_jG6p_8gd9k6C$Vu3WRM&8SoF&b9fM?R+6~g-0X((0h&cmqh7~&sCdsY|QU(HT-WU ze%nt!3H>zqS;$ky)Ar+m<=bxnn>lM&uU@M!xR=}R%_nM59L90y-w}z{DGT{Ho0IA6 z0o@Dq0}_N!`}%n_KIP}1E8QjkR1TYR=jvz_E5{N{08FS4`PH`JcN6r@;I{t*zi>fk zm~DeucBF?#v9^SK_O;>jKhU3pgU7{ZoeVu~W(=jIr_^bPmgf&Vi%!Qr@ z<^u^GmyeC#uI!{xc1k7CArZ#k&?f#Tp!a}RfvtZn&=Puu{yU!!-^ua``B?vAjqbIk z3%i$Bq0~X;?22|}tECdxis_MT?_M{Jo@2hh&2>kr2|9NA@9ieN{VqwSw+wm`mEqul%xIT=3OPl!bhTa7p_)p@Wy0T`~vO}3X2a|>{{*T(k|24F_)N>-> zxaF4yO;Qu&T*7%Vn$Z7=-Xn~EI&s$N4jHbJ&j+w|H~*dsracuk@=>KMVGAii?)& zIoHJ&(^6xcxtpOjso6nxdMp}qIg9By_bPVSzA17@i2s+#pMA(<^XGHue}I35GIpFl zVZYHfW6BVsjH}24m5uM7gzza3`Aok&S#PSL*MWJHJL9Vzt&PH zIp8;|&wO?|8{E(Qu);hQI}>ktzf=C?6m}&Z_xx=43>|OnohH4_@Tuh+slT5=e+~S) zq#SW*9YVc%dAJ{Q6giRwQ|H}|C=(zXbgkYK>3rI-{^~H+I=-p~lkWJH$#Uxp zJr67ZmjA`j5-LM~I=wU|6J$KW$y<^C76 zmOE^J*3b80a_jL^1aI*;zU*a+T*`Sog$+5iATmol6<;HJ`O|fDPRmZifBIFPvnAwz zF7yT9LSXq{2`#}7>q*D_CvKjxW|=;x&+TM?<61Hiqd_?@YB3f?mWvoSxc)3FhU460 z%{R${Lsj;5I%K$ zmh!k5`fBhkVCA?CTEbhQKf+_>hsZINAxlc;fcJs>nU;l4=ntVRr-!l(b>~UErMrwA zE$~V3S>*UTbns2qz`)8;04-tXlV-g7}*QEB-f?O=;X;xvpsCr|sb)Vt?5%Jr8<=@c3HRJ=Z{5wHQIA(ul&P}!HP_|>O zaA;p9@s!_h_*N0G<$DSAmEc-n`Q8F8;h20Ghi%hr!~CB1%nyWo_Ytq-h@ktH2gu<@heNgrn&T z!r}4|l|iXi85Fm9R&Uju8-hb#W#{a zDc?d53c3R;*Jx-7kA>$MHiYlw_`oexHS3mFFRf`mv2Va)Ra-GG-l6C92b5EnHc1sQ zuPn@XAprB9f2Z9?u%e3o?G27M2>AJ}y5hnCP7+Hcl}cCExMrR=;Ej6%))5JKOv6% zd7NP2*iE3as`084h!2y`RO(uPaJa=?%&GMJ4nyuo76gw?Io67T(8t zX?Q-R1G(EwcDR7r|4c5R-td{8@}SDxoiSHcs^u(+D+k`Q=`0oSGt+8*yb6S zu8L#1xngrfvE&zy^-qlrr+V$>auF3986QzWT^e6BC|0Is&JE^AaeH5Z!YKj}M~iw2_$$)c~)?zuo2QAFBNRh4WKNQcm=Cx_T9yks1NGY)_{XQYxMIaSHB9j1~T8Q3%L0HJWf!i;+t|7 znH3A-op6%mug%(^D&1I0Rtoj?H5Iwhb;r6ZwG{MsuNb*okSoD=QV$M5e+_VQ*eZ7% zT0(oj;WRkY5{iIq=JZrg;%N!_E+k&Q)qHEA zzXNsvn_pi+OBfsK`8T}XzW#;lU~ZPITnqo=2Crm?$AO5;^z%JezYZw<+Un`o<{hYh zse-A_wsRXPwPM@*5mKAHw8gso>?aktKtm|4_-^g)-U?_RIKg2Cl}ogSjZ!|SVr#<#-y55EMT zC4bN%I_V%ASb2ItOE_l!OyX9wnspmiwhC0cQ_Q!;Av^;+?nGL}>5Djwd#C$z+}TdU zuZ$d3@UiXT8_;#&>X3KG^P4a~k-g0RyX+NHq7Tes zcdY)Q;bgr*URUcpk8^gD1JoYihZ}Cg;{OzBF2Z|HuJJVB3 z7}?|IO!HE2< z%xo_$h~Q{3iuQD@`h`+I^{^cFce(2HV2&2csr$1@M+pWv1S;3$*Z^-SQ=&xr>k@sx{2Y#M_wkCNIrsyNM&-h-IyueFq`sht zNnzAy9PcZaMlfgx-ji-OE~v>yhj=+QiVS2^*-oieE4(vQwZBPSp(5KApSgwr=lS1p z-3tE|951TTL3dRW3{eleZcf2=m07JOIkg8(K2N_r*}vC7UkEM%HlOREC0IR=f7rgz zl9e0g(-o~<*MCs8zVtylq6T(r_1bzTFUevC<1c%3r4KFfPi08vJ~3~bEBj*{P{k=` z=oJoq`ai?+hp+92{tlgf2jd^Ga$N*1VQh;j_gVW7E&u9e%cRe-4zue#)8e<84q+dC zfwcUlZ0EX?zLZ2PQk=jS4kb0s%`S|MiEx5tyUQ)U_qlZ6LxUl>WlH6mh91(K1B%nf zxyLOo-mx29_eX9)>e%3vh{_v_*V2Kh^szm0&O6A%Bh5+tW*Y67^83B(4#_!#`jtDR z)7k0^w_u2Wwt8O$L(e=USZfP7&>n8U9+79`YV${OgPqO+GFWN6-?vhK!q`;%wbW zFQ1FU-oP&`>Z*#xRj=!J&M8uzxy2>YB`3(v0e++~JxI#|{z(jxbW-D0U$xvXbblz4 zF;5GO{9BOE*3-M89|u1LR{lNE670U2EiYS6{RZfqZ0CgneZUQz>12M^$SYm)Q#ns^ zv@=z$^dHfu+c|GW9y{@M>muuLS82EuZVvq6%9-h4v9dx#O0C7Y~ z)Q6Tn0dcx{*SnE%#D5^g$kPD77@wtHKMVZ}@EWl4{2p4uamaJ%6t4x3Bt{}C_miPS z5iL=k7AwEKSi^%*HsM#AZsaTbUQ$0-34J!G23Ee+&=TGX^>RmU{}YxiTc;cUBQEO+ z-Rj@>`cYXb{V`D%oU8o-F7Db1@eIRvH}NL;Ecx;Z^qb(ul2qXV!E7Ccy!8jm6#*dEk887Hz5hqA2XR-VQ|0AIxjK8i; z{M(`L0C)Z;@mFZ|u8IEn*65w4F#eB-YdZWS|Gt8be4o3pfz7`{XbF4ToliZqzD&Y< zlN4Vgi}8m!n0ioFzVDz@k!wk=b%R{TnS_%S;%VffK#8x4crD+}&{u&i!1BEfTEemU zR;*fSMyErVe|{w9#Mh8*__q-MLOx5nKZg!}z`h@_{PXTI{NMd=(~s@`|7n3&HbE3sFm_?slG5XOD)12B|GgRAP|sL?=YA#A@!uREN|x%OM)w)jCE-t?qh)@~ zz*9tr|0vER(&DMnF-2x>jQLDgxrKzt@FmX>9=P4Zx1ZZJ#uZ)twOYS0IDz?cF86sd zrC-EEd{HFG2#Q&XabU^g4lOSd^q|XNm3I+0a@_8^AA4RIGwD%$8ihZAtqMKv0I!SN z#hsb*Q#Wt7%Ub^g{fjjD#fW%CbaUz&CWRT(a@V*gs%5>d^Zbu-Um%xpEu>edP?s@r zctE**#|$3Yb4bC!-R=o#0}A>NjI89(7q#j=%ln&h-$%LHdUpWY-ASDXw%lhxOW0uh z<#zjBW*nbav$SRz1A!E#z1i-Xz2?0>8+Y1GJn0#jx!J8qDo3cgACBxgONGS1DGhqg#(5JM|}; z^z1@jJ1=+&`c?1-u<1#?+ob2IH%)+x5z z6$O|HLyY_@kT1bE(he_yz6sm{to-*vOE^|PS}Wa8`AN8i91e0p#atON>y-0oY9A$c zi50RgD&;tPre7gr_(=5&VKUUnaR5Fdo5&H|!+Hp011m={v;?a!YCpd-{XwhClCm?# zOE*yGI&a{rKzhMa9DGu$z13Mdp1P3l3gYd@H^TRF=$pVT!1BEtTEgz|{)nUSMG3e{ z+r<==j^Xe}F{l_U1;_;NgH#-*kbb#DqsXtwqG+yjRj3awKPgNGW@*g zxU^`jFY~@Gg>r`yJqR0%o!EKIp=;~pSBTsB2bH=-hE=D2cv%0DYZRX)|DJ~aC1?g# z?k}JvJRi2>BhRy1_X+D*2*@$ajLXxI6qVk~X+ycIxPty#T5>PtN4m33$Q7n}S*lYu zi~pX{EcD*<)i-bm!(CX3kw&hvUCDmtZ0Pl16R>jK0WIOX;XHj`JG&N>pIWXq`+&_H z&EKn-Gr#WZSFl&*AZJ6wxh{PMxwzIJpw2`(Y+OVoKRPlwySP)r3%ca!gKXC;`~&pMjJUlLXI-zko@!RMGpiDft9llw1h3;dCObFdU$BLhjLn@s21-lOvJED?XlmJ z9ueil;~c;*LNWIZzeGG2&rw(EVsz@q7&&U;W6NO^s#)V)y3&B_@sZE zM+@xcSDeQD`&+L6wx_Sy)p8`tjNGO7C-ZF*^qF8WuyS7kEurIlGxy3Bl=dgba=~(t zqalk`nNwzT^|>lpZ^dPhgPHLPF6_*d4n)wI73?Z?HB93Zj9h!*n}DyB=ZDaL1_ywZ z>nmsp9m~Z$9np-L3je4> zU%M`A-!EQRy=o&~%adtF<@lxX?le*>9#0YbI+~O3G-M9fS&$d2q(2-P$&L+W-Z?Bb zZa8&&s!Uod-K$M&ckokdSECH3O((6NU+Cj(giCqYZ-xL)8ocBNkUl#ZsB_5$6& z+QFhxV(EHymR#^D_nO9OW_n2Tv$7(1chB)Fy5!|>g>4VIpa)!8(VEaO#pKT>_$T;E z*_}Y2@N6pfuQ8U`()S7=u>Hq?h6I?m0muC-ljQJwlg zeeE*AeALyiUi#VjYbF8o4D_y9!x-^mIhRE`tBly`S~V|MX6LC~tsoug_b$%!gWimW zGt^>EZS;1zSi3LAJR(Qk3?ugzk6fy_MjLbtX-QeEzEa*kUbQ6r}|?e6Bxv}?TMvI_pC~{OEg=&W3f{FKxe1ZG{?xZ z4}J;wNxS+V;r%Fe0a$tRp(S)&Kie7;79=j9&*={Gi}hrO+o;&{7pYL{`ol7q^$%jh zNJs0`&oy#X!KaL`M2<_Lw}Ed1E60P-670OI{rADVn=H5g+1_inQRvq2!r0Mc1M9G$YqR_$K&9fKu=1>gK7M&lU#aiVC@2+yzU2;(G9(+#Ir`pDd`F#um*8a01v2(idwD zymA_H^^Iv{ldP!YnOq0v7qV3K{M6p5vg{tfO!S1*QZX11sk>&=T7Fi9A$J^iLOxkag~LF8+d;&2uY3?f|W5sE`Y8$67=0mXL2V@s<&< z5^nvu(W5;dz7Nfx^@cCoT331d#U)**{mjqFAJ2I*Ph9url0Vt%GIV_z zv2(pV%=ehSFF|vZ0^o^A4>4t_QtZh^iF>;hJvSD+;vD<81;7i)o6F%#fq z%!%UUUax^$5GRvUiUH2?xZVe6@%gG7<`D(>pUVV(KD8*JP@kDlzsSf{_>*Ki8w@=H zj0RS&>Ch5vJ3Dee&89@_7So7g8KbJ4EAw-asDOoB5M^lUswPW32SUE}#B1|o7xZrM zG_ZW%gqHAmc#iDI`%J?3u&t)}Rz{>Mi zXbByU59CkVp>ry|@iP3#Xf@(92!rZ^(W~su(akD*ZBf5y3wS}uscrI-@FZ}~ysY7C!k)sMec0G0p^fvHqVC8rLTEeK%Klfv=9BKcJ zd}y;I!#wj@W1n)3c`-W4jJzRm-a)V;lvvs1&SkzV$g<>`Uem2S#UUVR$qxH}WT*N#^57=t*EYu<~z$mT=5^-a7S>3RZ9CVoVEf zEoiM^gYO>RhL(!1UKtIO!-c*dXJ&T1`gj3M0q#XOsO> zHS{WQ0kCph1ufzEc7CxB9akymR*T8p#B{`n>qP}(G>2kv^{;2n9f8y=sB2&`wCCDDWg@BuAJWKHeFoOmCk-I=^E5F zT|Fza!gNJ~o)xk~a^eW|cpW3xX{uRh)$F0ktZv}S%EB^z~670BjSrT%YO?BM1LDQbBUk}P*gTJ@KCuVgY$^&?oNR^Y&{S*WIS4;HKhJuO zy%5k1Sb6$GOXzrhUb$}b5vS;#51XRbUSRmv60hZZE%a7!E3kYUpe4N9VLO3ua_W20 z<+9t>;5uJ*Hd~Mt0W00!>Jo`3zRvLdh^; z$mYYckj@!ggzPLwUnw%153)km+YP+U21L63rW@16t6Xk@kUW!6exZ@G961tv7CFy@ zUI#7$R?cgoC3HOQpT1^&_41kt)++2pcdd+X3>RM(6)+}<#;FnwGubu>J32Mdamp?- z{F{m2*02AD{u?+5EdTr$41epVzx{dt+4xs$wX|t=?+$eP8Yrjz>HQ+k`^7`JtxdXdkr#6)p-%pg=17``L3xKkVja)0>YwO=;=q=zzVCC8YEuq8qZw{hW z4Pljj0a&D0>W#{IIdLKd({X_PN6Y-zea5p!?lyP>J?v$at>(jm0aVRi|xS$exY0;wwwb}3;Zdb z-LPrC)W}f_A1lWbVqW87h~4DpSxO&u3KHb;i#M&dPpWz>YEBq_4E;> z<^E*%ME_K;n10|g!~X#Bm%~8nXY3{FD(DR?|4L{H8$!PnliT?dGxLS&_3QECWzOX_ zt7|#6N!NS3dDVM+wZ6F}>O9(Gh76OjQW|?Un&*KGk)1G;>8l3CPLAfpP|x|J{2--E zPJyyX*|<62J74sefPjnr(=nv_f;&HC0K3{%KSAZ>j`SCJW1Xt2jU4^%Prs(=XD9v4)z2RrUon03ht2xQ zU3T)1=Bsa+52xs_%Jp-WeuhqFy6O+81ms`LhhPWJi|FLCo%)i#811BD85ZG+`}EpU zRS-+#M#6LaTo=O!_Z-Dl$pw)@jLQoAf=FILj+=7{runtOT5tiE+3II13f2NQBF~J} z4Z-@n4Z+4#m72$A6Y<%>qKHaAJ2(qK<>;sW`|!W=s)CL2PCOU4`LF50v~-D+1z^tP zU`8a8J~xlVut&=*3?>}?%3SOs(Lti#j0BF3lb^NO-QJ}$;eUo%VfJd5&C2>4p=$nLrd5h z+S?o{U)rh|c8Da|gSBdvWwn;1mzE@3OM;dmn{K-`KWeucIU3+o1|Mnvk3l~Jeh#c0 zuR}|i9G-6-)~>&j@=4Abo7_LUa_ycT=5OjXgoE=VsHlB8z2uzA9b)B9U45ATSCaGX z6QGBK(ZKSZ4lQ9rxPCtp-&Pe=lY0=hqCjm>&UZCi{A0kDKJQe;JfgyBxH&9;;+;;s zlHR+Z9|VsA%eM*oSbSSmO^5Kk?}&Vxwi&*$SCjc%2%P}Ef#rK5w1n7E^s!4X+z>W{ z+HbmRwP`H-W4-#RjdGFclu!%HczlcDw~6@5h)>e_E$ExUc3}B^4_ZP8{On||4a3(C zW0<(r@cW4P%7{<+{V#Oz8vDY)^2>pi&;dW)tZX8$ch^caLL;^ho|kYo%OtWnwLI`w4gwRafy?jW?^VzMtx_xj$Qwl5N2 zWtkl8TbP=^=d4CB*l)!5Et@+ftSKz-AXL9b`7S{>%4b>LdieEVEik_8;WF){yv{J6 zp}dczm$&go<=cvG6kX{X{wMdPgK}VeBXF6FZ^rT_PckXx-I8A3#7)X~4!TivrSI?H z7lM_*_%_02GV}OhIu7%+FHe!={#Y4=)o!(&jUfcY%^a}ot^&n;0r6nL?b81KWt>+J z;Sn=~-RH44t<~knCyI~EhxH13>OmPW`4|b8$>igewC6w3-cxqxRxB9_Uaca*`Rck- z6PxdL9f9k9%&UvTF&W?Z_F)rE?>r`Y~$8T2oslzYIXQv;)Zw9vm zlb;9RGMV;hr{5o{^3!BD(BC=C|EO2=SPZ*(&?qsC@372gtIujXkL^-sLvGV8%HMj` zjcbO$_XJhI_>Y0hl=;5Ph3U^>QrlEU$UDbJQBkGNrGrpSKKBXNS|1e=0Uag=IikEo zZdLhMi4U#j)Wa?CJHS1_E5UA8b|ivtL5ZF$hY(xAO_kw@`lSHjta-W z_T{?|ouA11FNF64gMjfJqyODp-!%TFU&=4Dlf9u%eYww_&d%FCmdUvRhyP=Pk9)S~ z`CEJDKijixYftfP&)!>mvN*7(_+0ACRKHG_A0Gx}r~J3V?*dK0W?xAItWNx^(A-cRNk(9m!NCPTMuslHv;2(GhC+3<&}FAGZc10 zB3am0?YA90<0rPU2NaY5{yq3ndkTIp^Y;hn=gyeNWK-Y>Z5pvAM))(UQR`Q| z;l?X5_+)TAkV)#ltH1Z`E5T@B{Puxomj~8LkKLrE5<4l%MyOYv(I@oRY>oB~57G z9q1b0o^LVkfkD9d4uxm$n|f=t>wHYoIewQa?;LbZdoF`72N!Fvo%cs)hOw~mWjdP&-0qcH!0ufzufcx z@$eboRA78hhs(4z!@6Ozy!sYj{^s!{ajTR$Z0> zJjds`-b2LEYkEle&q2SEpUCoF48IDj0>-}qE>oua9+JmN>Mgj$o&T_x$?P_>Jdk{4ayc)ZuZOT&<1Ys7~MsR%_*yfo{w_?(s*JUo(29yxZZe;5%UaeuT@^VZSo> ze|bx}Ty`$iv0{%YzvxG9`Hq910%if@HwP|Lhvj3nHfF;nR0HFGI$Wj>&j-feJ-^>- zPw$31L-H-oxXd%MSkL^s@@+!boDW`vzXsj{#Yj)1`{7z@|;Mqi{vd;UWD(6b{%<;Px zz8>5IjNeAMOeb{|M{;9qqwxJh6PnPcs`1jx^VEnAFvM!&Rm%7E<=qa8Rds+ESM9=ionefv= z4KRL-;4*dCPg!hfXX$KHdOt1xr}9mp8$nl=^DX!XU^_6r|AEVtX z_j?PAPK)-f`r7rK44($#!1z|fv+`Z&xi!$^yE)Cb=@nJpCUnjC_X7M?@Fp<6@4;p2 zaNMQ5-XZ^Xb&-PJ`%sE=-K)yC;v2Vp$HNZ?F<^X;h0Byp`?^E@_44Vo&gArwv<8m8 zrhFUGHT~*A_!D3YFus3>XX|T*dUvVkG1v8Vo){G3hV`p-+u6H{n}1V6G^{> z_NznBlrZRY&72 z{U>!Q`~u6Aa$&udeSgjXe~wtnb@n%u?;LbZIhVsP16Kj#y9zE-HvK1g>U0}&OR}Jj z3fGz6RK6|f8sGoH1K+a-0*r4FT&C_F&HE{D`=`*YDb}spcPhH(I9&uk5Bwe&-;3cg zt;oXH-QyF##hxy&MRAxumvWd|iMLdFo6)UASB{6<;a`F8f${wbE>nl+(c~Ji_eA=< zI{|i7I6uCvd?)_k_Ny82Ge9jczKh{9o!8NNp5yD>qLva}y_gbRF>iQB`6kdc_523> zU*IEPd_RNB)bV(@XaV1^;Vi+p3j@tgB|8fPjtb|Ica?9|4tIWZ4E#he9T?x)aG5%s zA9-#e^GuOm_Dqo+o%;8bZxgyEu6qvtGI$*r-?!m1HFq?RaBm?iul=jsvFpqvUU6p< zj*L~?qI@g<>(=vF_#xm3V0@2;%hX{#n_I{{%P+5aYB~BZ<=23oIc_(=9{`U4bq|L%R|9LzQlInpZO+F z%MYxD;vMM}|3u}h@)vi!I0}9=I2Onx`*G%RN$ymXgWwSF?kBaiYP%ibPn}e!eHzfL z<0tZXxetCnc*x_^JwtqIT)Zagu=!LTHdd3?-+`8?->$zB2ZLTfCRvX3_B5N|*msmH zM{<6m3_h0zEn0snTE*zd{4ann21`Bq+0@hIx#!9+vry_^IN7&~KUM9p*`xn5{8jKq zC-wE0+bI23r61M$-7SAI|9imq0{a4)vTf%B=W(-SvH)K@2DMs$iATQyegjzBNquMC zFxBK+RSL#C?bG7%`4RpOttrVkI&QaXTje)=`*Y5%rk4;29f&?txB!W6B?4`7z`f@MgWL z?nu{9K6OyJ)CpWjpR4w$^7)hF$FcCK;3ObZw&O?ajMHK>7R^aE`*NDUQtLN(^f$u) z3LfmFzJ6S_YKj$zlj2%`2U^8^mhDjHr!1g1kSW{t);q70`M(&8daXYdEu+5#{yVU& zllq4)JZ{EoS@&z2gN`p+1{P-(cMbf)Qc#8&GDywVrbU!S(axpd*PB|Ry|s^gJh~~zH25iCrmDiM#}RxyO|ix?Y0>(P9(}pB zMsCY6m+-S4r_i6|e2=3l#ZA(n_)DG19Je3!fcKW4flN|An||aKZ`4&3)%tO?O#S>0 zegRnS(a)xx%~wII?BC)z)N1_%S`qRokGB^12jF9me&*{qp5ws#-M7kQoi2vesC_DO zU7y3?M}nh)OtPM`@p0oW=Ls6h>2~GRtbOV|KKH@z2M=}9M~CLguPjzZ>y=TfYWE#z zns(`)=eK%+zQB|xn|6`c5j0VQwI_*=L?~aQ{!>53$KqlD_GM{f#oIE!$ zsn%)IMorqM0ZmhH55OM+k9mADw@bLl$#yj^Lqp0?2_V|1U-vNI9Ek4f3pK7)lvs&#_Rp{2+@$eJD zDWKE!mJ(b&WQt=oYM(}r&r|R%;JM%8(#t9tFT-sAHEycxXmTYTCHDz;#i&_2ao-1Zp>-yQ4)OnI_ypOm0t zYqH*2wa*eXmmn&~>jwA@V6Dd|b6k-&zL^=Cnj$|ZqB5t%7vHG%X+hJ(7oifrl?w`i zOme)=JnwJM$Nj1%W%s;@q9IeQ_KTry{LY3i1?T@i_@x9JFN&!2lBr4iCD5+pv#iHY z;r{_&dHgcR8|{~`P0-OSqR3mV+OLwwZAJJj{f>mkz!dcet`6plX?~s=@5}U#$hWG! z>d`XegFI!+uglh7)z`W6t2g*~CE5L~nD*I$t~tMU>*}|9fL(x0vR`C<-tz__uem;T z+9!^t@wpIwF}Uov__PT|wmD`^+GnfBXFL2e@a1px@ifhwrbI2;r?Si~&(ZKHU@GWz zy`=>uZ)>CC?^Hi%Kr@1<>}U7G9|Vtjd@{!+Y5mL_oV;sFV_8w{V|8=O6M+u^gF&au zlNzM77^hn8GY3smo-5$>V3o%wbNrB2o!krv9=nSNlQBM@hr)RljIL+Z<1?!nc99J$_jqx9tQk+cB%uK9TP3 zIJ7@}A~+J*6iki}N5f@GKOeSp-D}pI8S`Zf!ylGLr;nA74#<-izPNcGSi=P?JXS*c zHlS<9zx&|NftP^s{U=-|bKT2a7goNW=LUFO%PSA$A#B|=a(EAqEGGv|!*D@KInikZI@RqA_ge`qrmTsOD(YYo8@(PUR=^_`Vjt8eH%3S)XB@%(%1- z)joH+N$&6l^&mU@IQmQI_Z-Zdi^Y2qFR5uM?bU+^I%X2I#Ui#*~v>!YSrSGWI<}R zPYlgCqVl+&2d@DOJwBPQZ@I@^(j?|w->UP)7$3EM6I!)e|7G~A;0=#{=IdMO`f1m< zmP;4f<44sV-TS!X$7pyJ7z1RI$9Fd4M|z05!dGcUwf+*1{x$GFf+>I)5kzJGZGzti9`N{Np8vZ(o;YT;=~tCn ze+OEoUv=s4x4MGvK&EVuZ*Pd%pbg?$e=1t$_&W=}2rTjFXLI~{L(A*6e!bS;?9qP> z{swrbllpB!$~C5z7;m*tWPn?a{on_Halq75Hs!#_(-b#3Caqe(&ZEBuz82itd3|q` z*C-7l|5N>_1+55~mHp_y@SmmjKsW!{^dqnMExL+gT0e@GY3FJ1Q@~7*em3=!8al3X z9O|@wBU&c^3HVdsS&x3^_{wt}v<(?=*Tt}!v`=_f*JmhvI2Z+FlE*_fKJA8#>y=ZB z_Nn#wTnk?fuJ5Ez`=R2Uj#2S1s@=DtY1(B6{3r0M$0wV1X(vRy+tgcB`%E0Jx4`)BfXmcjoal8ekB%ig zHP4ufj4dWeY#~Sl)&c4(PMdyJ^;5F}CxTOeOglgSCk@*P6z}y#90kt*+NTlC zI6sre?<4TX!BZZec!oGJ>C!e(Y*KBgFA`U{^|%W>0tNz^c77g6IBPCFL#Bqq& zIgZFgv`jmn20tCl@2q~CK=CnM3a)c&pC*sb3-D&}N@so20>uO_by~l8H@6&>@IAoZ zpi}kKHc))h6r@S}EI~7ls64L!2yXyuJU*G@M9*=N7AQU~LpZ*-Q08?TTD4mLC-^Tw z40FqoIZkY&pB5-?aRSAd_KBit#^F=oGeEV+Cw<&^*O@#%>4D-_Q(Kl*r+wCYe4c`D z0nc^TCnaEf&M|4y`r+YjyAOg70mFezS&!%A(*nll-Ey>OpIVR4)$moIp|d{i1dcCi zt74ySe>6?Id;|X;{OIw?s$Eh7$7aVNs`aZzxN+kY`0-#GF!hx=ZuGQ!YT)>?FG_oB z{RXs5-1sp3G4P~EKXcreuAd$_z9Ma`g!ZvUx<38kyMiG=CfV+t@kt3BUvq4DFq&$Q zIcV0QCy)0l;a7t{dVDg+jcv=*CUD%Qz0i+pzintowBJ|oZ@~_aU*>tg$IlbBys7(F zt=6xqboaN%$8@ifKz(xg)BCp`M^z+1qFzd_#{ z<9&!hTP#{m3i+k*cD4tzU6Qwcu8depc;}8bEHB4hgN_ zf>wmg%Hz)7gL|4l7?}KLj_bU~LE8ZGQ&kMBRr^dt)A*bLpAQyv)~DS7@^i;25>)-E z$>Z}1{B`hFXMNfaAit1CG40cRPq$t6fsX-EVCpTac4;SoY}NHvr+rqUY0gvY;2Xdu zU}Gf5k0vWPLlN>d_kQ`u2nm2fG8~yBA!h4&z7HHH+wx`MCC9 zg1+hZe}p%HHQICM^9^m-PW1S-FJcvkRr$7|RZIS5zyBKk9r&+De`<#NY_xjYsPS9X za8a#awU=9eli|mK6M;-SAODm2PrH5Yd&i(w>o=ff>gO-;O<=P}KXd zwf+u|ewV#j{{-EE$$u95DN*B(TEAKAPese*e*t_kSlT)L)Tr@iZIGkdce6+Tb@-d$ z-OlN^6E*&#O*p@3pGcKkj(y-`KooSMo>HR5I)A0}w{fjs=h43r-U!xpPQOjmxEzmq zt>5C&{|WvJ5c_m0|7p?U3a11Ktsh0pwDT$O8KAmz`fa1di*+SYQ?1%(J(_Vo%j5Ye z_!jV-$0u{Vm^>cRqQ#Z|7<$oM)t|!qy5q$V_%KijWRk~o=6EqpKP_6k%yHrQ#oDJ9 zO*7tK4!;Uq>+wk+=iPWQ>60EUUM_1Zq4k?R`k%l*2d$mcPl*z*)J@T<^(*&t+xrOk zBrqAsl;yac9wpXGi%6bohkB3x2KYvBf9Leui4LzxcBq*4*@32Mhc06n|3G(O%8^Ao zq(q0Sv_qZNpNiHJ#AJV60ACE2dh|2LhskzMjSg4)qcU#^t-l#96Cb_-e;c%T^fSk8 zsru>BVS}=YPW!Z?8PPtW16TtDg+L}*p3L+4q>m>QxhdJNnzVilEz_^&z|R0R9{nu( zl{YGEGzKkNzX>ff-fo5e9lYex&*Hr8jS6ou`o#sRy^F`X`orOsU{7G`Cky>HQQ@H;?d8d{!^pDyR}21YTs70B4kz`XGI74trE};nEYps z2i^YPHX6Lw6vL|2K2y;&K1<=}fx6E5v>OdJX{WgMNqBtThyNRV(m9{@qrr{Js9yV2 zjC0%N5cpx>C}8R>i*{)z8r+nuw}kd-K+}vLo8XUwr-6yfw!&pfA4l4W2W3C#Xxph3 zE7HgPc-MC*e19+w7~ctSnL3OIJ+75|v(+>L)Rt5EeOYXHbvC{3E>3aetQPIR5`EL} zZ-cJ~cWcj`&nvWHJMrNC{s;lDD&KarVpz(4FAnls0gwY^lKS&9Tu0REZR5ess_81V z{zSA)yUl{13QqUvr?;0ouS@1XEgpQxF^FsZ^=O&;c>?}4*y_>G-2YsCZ#?*j?s@fE zKYXyO-w!?zQ~*;yS?H(4gO6$bgw~(q(O(X~2wd7Z{nU6cp$uBJ{#K9v$M8?V7oF2@ zCmwuKmxB3e7uAm{C%E-=DEtTz1D&X+lz8xI?GV%Y^&b6u;7wpt=k(jegIn;Z)B3F* z{k%h%`+ySAiTtOvG->@9TBe`Qho1!&cTT@;JosF)8LSrVvl-1enU=@%KjE)| zH$6U?UgkD`_!Rn#*H=b zwcu8dPZr}wdOX-HYpY4?w|Mmb3;$VaAL^DP3;mRM@MYZ;Em}W{mTB*k;M2h@kA4>8 zMtVH>inJ&$&2ci>h?dcR9R4KO0!%w(q2EqC_*$|dL z@NFHawQ8Tr!(E>kd@?v5n0m_ICnX+y*TjRBU2`0<1~lt*eLVty96aUm$s7-+m#0lU z*do1ZwU2d#J5Mc#_XK@_OgoPUlRlnc493R`@Z-Mtb`dJ(w-gxjMqi>a|c8DD5>hBMaf`fpmpDgs-#Dm*0snq&)9{ua# zH-eixt?y}qPgM!xTEE4k{}cQdAdc#6{=FgF=Z-qRx_~oF!b3X0HgWqbWnD%M*_Me_QX(t}sk*v2S?Xw!Csym7Z zqviUzKic&j1D^z@0OLCqE>nl`V2W$U5n;3TZ$RJl`v>3;fycDx&f~$PVLK7wk1`^3 zQmgi{j&b9{-tfL)0FY^CabeP>ZDjbfY{W=+RgZDBO#7V=uLCPQ`swZF#)V0THv3C| z!62sf6KI)wdJFz8c;BO+xgUD&{!8}zyG>bG5P16pu;HQGq zJL{7Y8Lo63qFR5wNB>#)bKu3!>bHpuFVm%9KBRq$k9Es299{|b1f8m{vT1DPSfr^^`e2Y@?qRAzp(E?V)`d(KO@7WAG=yGajF;#*g#}ah0hpo)fEm!pFNl z1K@+eP+-cFl}}2fxY{vk*7|eMGRMco@JqoJ9{sGwk@QHh!7Yc?OSMb0$LA~fw_rzS zecFi_uh&+U+NWx&TVIpm$AJ?;r|K&uVqD`m#I=3{T1ya<{dW`m0r0R#KXbh3>0hZ4 z<4u7m?XC59pk?C4UMCRqfd0VbKXV+HuAd$;HcA_-Mf=3jG(OAW7lBKEqfbi2c#C6W zMdSkuNn6pZ<6YL*7x1sZcOIY2@nYNZw22tkDKF_0*M3zey7T6v;Zwj=Ak)s{MvtE- zY`IUVeqGj~Yfu9R5=&XL5$nkDnOU$o!QSF}a_`D5&4}9<&d^}BYuQZ8i{m4mfIrfJ~ z!9k!?^+Y+mL0%IEby~j;tq5YW-(C;D5!~$2&m2E``jJ1!{X@{TTzXIRM zoy>n~1i48%v}pY(S|+K?s=g?8Il$g2l5I$#}7yKPRD!a!YW?+SnelK7{BPg|kN!@^!=yu-K!v?SM{^vxZ5tn;3L5vK&B4j zPOpzQpn6)m#I$~`NB?s8Rp8oA>!$=%Tcm!S)^A43^sE2CTfw)WbNNpVsJ3Fzr1dLj zxcbMyj|C@y&gr)kP(3G0!MLJ*8azIm;17U@JMEJaP(3dliX*C>cX;%>&*b^HpfBiL zIobqNFRD^lR#f}M(KPLG0sQyiqE7py1ys$(h4DoDZ1wnj0{fyIl*eZ$@l_k2v;gZh z=@#v$`hhju9as9o`-4Hilqb7!B|X5}mTaI}?K8*YvjTnz_(P|CQUa_urAedK--?#$ zXCK2q1z&jdvm58r1FW}`c0TO{Snq19{;FLX&@|)yCiny3 zVUJIC?UE8;wMd6bt-k}U2$`1stK?MXzn}*&<=Dx*%hSI+v&Q#T{^MGIDq1H03*l#j zb3OXm<=;Dj|Ijh0*ZP~$GVT3O_-o)zkA8OT;GMvK z3H)|dOYG~`K6M_S8{v&$-EZ;nG{vWwL!bwc4i%O*5Xn3;zUs0c;8+=cQl6 zWlA4cJlBELR6Fv!$b`sZ9x6&-*e^1l?-+^j4}1k?}`+DW~bOD@h=^BufkL5+OkS$h>BpVV17NYz7hp6h!ud?~m97~kb^ znKITxyRH=cLcUIyl2hj7Yu;7r8|f&2Gx}!;9wllGR{2Qa6Xv5Fck<3;KNlzgGRc17 zPrJ|Uw3-nWLz8W=aOwP6BaS)#$i<7Qm+TigGr}I--#(lA)hvhN3z@EqI&$F=9Sr8W;^^lJ%3` zFaCe2A16Q6?t}AwQOC0MtkwBiLLN*#ZGry{yx_^#|4F+YbL{+i-lnSyMr593s@M4{ zu5t5qGCU4u1DXEM`cqoAmXoa}ou5Weep=z*fFJ&!@?*O9yctVt7B6Ckb#m%YY3?bqxGiZ~`#( z^?#SIv}`r1hK%ccHIfI@jxWOB0Pg~Get91*Q+j*0cfOw)nORdaZ@8!a z^YeYH&PT;UHy=~rbHRLI^05FeQ^xaL@?5i%Tx4;+uOFiN(PsQiy}Sf}6TAmZem;Q9 zw3B+7w)@^Et0@mdT50UGNp{RXsf*|4gk!~iR%EF1t61dv?GK*}rUK)45?rQ?L2yPNWFRQh%D{Qe+30iM>Lay+gKbagUN z7gF!$s5rBF(VUvu&Xi{SjCu1YX+dOo-=Ou29kq5J;P;Dw^IxvEvtrt>`(pQa7zQ5) z4gsdTm%(M4a$l)KUb$brJ2Q!jq0USqIYFRZ_jcwnZ}KJ7OlM+pB2y>oxm;TA-y<9d z21JfOL`F(P@7zN~z#k9=<$-P@kW(1&hl06cir?oSEb_Yty7c6?a`q4Go3l?~_nd?C zecdc;KXI)PW9*A%)~xt&RbSi4pBZPqfd2w~XS?~|6)w}x^PfC6%WFTfYwX${psc2p zyeEY9oLycxROE{(gvhunSuDdJB)9REM@R9HzT4zCDCdGwFmP<4wOnRxVmbNA z3-%CIA`Ei+NG z-Z2K2AtPeWx69GFi=19P-FdxGb@Uf_>u#+Otv>65^1?hCxl|O2J|dsSmY@2FLj;X$ z=h!7e*jLzgenE){^xzn;6ys#KiHP&WD7(MTck?Kf?*#cW3kj>%JGHlP#`}qRFrR7!^9q<$ri(XQ)HIod+7EjKPJBy!&ieFfXVMa;4;0vMdfqg z)9vKQK924^{oQkN^2#i$ zT-;$>(Y=)adi2e4^BDX!@D?!s`R6MCVNa_1y8M}T>J5KWZ>{#t_Lnvz?#;q^dy`Lj zGBW{ds~Et5R4j&zE`C2*$`$+jslQ+e4LXYBs){~Zno}4I1g^KcGM`>Fhef2ZnC=C2Ii8$^J~-%$PU=6fd0yOY1U^XD!aF^a5} z7I!VmAxEqy`AVt6fR8b_k0{|F);_gbNBW!(UjbGE<8!V4cccG^{=PofXLson?ay~- zTr8s25v8IFJv$Jf8HS0jR;~8ghK?Ekzl8q?eg(#-_&inK^m(1`uR0bUGQ!NVODhkh z!*(56WUUlb-2tV!yZL+O2l8_AMNv*pksPIBvN~I}|5Wsi|5@lPKp(E__$}4T^W7x<-GSgyPYwYs;9{%0@!$i-*KtWC+mEvPm$)mUJCjKf- z4p8~1#mD4hCA)5L+&t$W%F2_x}srak(FS7#IaizV?C3v~Ht1KK=3wsYvbi7bp5D zjqS~ha^$3LaSD z_Vd2)D-af*mpJxy@ngb023_Z0_; znapN-h*EK!I4P&Be>iVYspuNwtQHoWL5sA@v8jW@vq=V zGJiYZy_R!+115hH;WDk#$MuKF^RLPuQ$&?LW?ZwK3D-K?d0VO8Mmit5ujPb%jXWXO z+xv*#WVm;biG-h+M)dZ}V4;gR)K`$(I~4MT^70C3q?rFE+pZ9+YjvatQSL3-$}N$N<^)pIk}w z;tFQRbNu~7l&nfLNI_C!f+}Afx@JCn6?`pN2aNCIaG8v+c{jd`jd8PmgLuido9&)2 z*`+wQ2&>O-%!lM0{Qzch<$+*sf3d_4k%-K$5#lJR8=0u`5njP}yYN}|k6qzoz=6Qz z<9N7Cb-Lfi9!u@Ndwso03fH`hZboUR)$&=p*cDkcV{HpU&agp0z z#s!1^!Hof zw}Cr6`sw3fd-_Msm@fllrN2?>w`l!Vv`jnuFZNpnpahtD>gUH)&zQ}3 z;Z)C;5o2k+z4$7k+UsT2t*{5?7K-EL1nd+s&Jp3I?r_z9bI`5iv+Q3>;J1SH!1%rh zm#M4nS8u2FugM%|i{$c6-zIUTy+PPb1Z&RQUd}7wwftF=dMn$&_LB>RQH1 zP%eXgq3EA`hb{X1rw2kqn8chY_To?yYi(bD$1f36`Ags*=O?mWUxj}JJ_9Cyy;rLI z&EBN)weEq`{KaN0SXiBG(DD}hZ}xjKv}*Rh$CBI{kqBD1+cI|UO^BK&awA9fI9wD2 zLt>V=+zys=mkF)PZ!P(ms`Gm({2s6o znEY;o%QWu^mCq^3_+RzEilJw6ajsTQ`HqChTCMl}YG38E>wWjBw_k+wsla(1bd@jH zx=GZBtmBpu$*#7;XHkr*;z+P(a5#n9S1b@QUr#%qg^SRx1W{XUaVSej;%-|U;@gwX zty2B*D*u(2y8ZZY_vH~E|>{AlO3#(C}Q zyk0_F-h~1*1v#Z2E=qIzIhmd$_Q^d!^zx4uyD*;5wF_C%V10|xeXbluSKIz-zS7X% z&tLA#^Huxvd}aOty!WyaC+0XA+(ABN*<`;dxQzW?U@$P{*at3?Ip3J;*Jixo`tbak z5#}l}OI{~$kjuFyM#Qml=~v5_I$Y(CyIhIb3#5M;iZCw8>?xW%EuCX%y@S- zd=+TW-f}!O=h^i0yYin>eP(UVf*A{z(hp)d#;o@l?hcn3KS}9t^XPvG{~COsy*^_$ z7spVqM7`4b6!qPtx>c$5qknMg@fi4gun?GfyaFzhsmJtkRLgp#Fj$n=*`t=RF414U zOii*u%Vb?P3L>Zqdaztz4T@d-C$QAIOCVS5l0!`QXIoGOGR00-;=SNW*8(rxd(;Rk^6z~tj-xJ-NM^NU%>Gx-=luV$et z_pF*+>26!=gZ;z^oOkgDa&m}VupDePYrh8c%=ok(z5#3k#_vh^&ip3Knlsz^%D&Rt zq+w&I9YaTj<7S2`XYp0;eyIq2Fc=1m@4j%EzSVJ3dO7huvu3u_z)9b&JMnGSzAMo+ z^V!b@zXDzC*w zs0g2B|0;r)gWkaS4u#9KN%t>z-AA2|CoEhv!jh5#h0a?>%;w6hE)wqsBt*H zERL$wqJ5X3Yufh`_?6&VV0>?e%ao}wr%=Te3mNbcJw0X$#VV#7guxt z2QYqRaG5f;E4%yV&zhl+-Ptucs)}F3bEGaR!|eo$I>^y!(Y|qXqx?kro&&!GTn>!y z?QoeEwOLnF^-J7MKW4hUU~ct7%F8(UAXkz&)ppxJgy|f{pN7?8Jc)~4&Vk%T9mqW_ z>vG%Q&z_8a%WPE-t@xRK_A9*b8rHvn$wnIx@Q>t7AMhW@v@j?l{y-TMs{O<%qPytoQ|Ha*YL$;A_?U6~V)$xs12Flx4=&R% zecj5RyxykjWm0Xm?CoSjO*!hRlydUHd2&VJ-sGc@e2ga_1*%HQS$RB6oWLc5e!hLt zZ9P@@|7+d$DT4O}1A)oM0dSf2%y7KN77!50j5OMRQ7a+c);hy06|%KZwaX!C?ZN=N zLbi(>U|UX8`B;fhl+UuCG{Dz`dw|Kuvv8R*=HncFVrefUpLU#)<~b@K#jD(Q=>s1E zMgWtKiEx>|Z7Ow0`Z#2&qxJ&A>QdI~8%4slE-xDD4~oL@Zma`2@aQ1BM*zY=|_!72A@cq6zC82`V* zW!jXXAIhjmb;GrE!=4nq*|zR4+l|#iJt*Wc94w&M?eFL`ouSHYt#-%7Vt6^|4UF$l zxJ;SG#WPJ1Q(BuG6rV54Fesu^IZyd6(YmsoFNXgKYzD^nGyU&ozHHvjd_rDwljW_m zd&`;fcAtDbZ&|r@i#VcawCIuhfbd1b`Ju9~@Rj+5f6qJ?NDIrY)uAKa3yv=B@tQqX z%oWvJg3-I|{JZV4yKM2NK-rd{csA&)q>8{(c3ElQ+aO(ZPw}&=1oGc9U**5*I`{k) zgHHt~1C#$5aG5f%2RRYU5I2O1ud$~WSnEWBO)$W^&=xdRV~z4#j~)|5r++*RZw9Xd z0R+{v8^Dm&JlCbsjF4Kkp|ayU-$%YI557G;Mw^m zL#gukWzscgdYLM1IN`V+>gYtzQoar7n)$)K@CU(T!1z81mnpq|J^Q|2^6L zIL}^{+ncOr?HB%&>(?8;JJ=f-zy07cW!~T9apSDic6-z9@*J7Iy~#=}P~}~TJ`)J1 zeQ$x^0qzCHeLXxVO`Z;N%z>UpT!dRorM>y@9n*3}>Nhq4L{-o~hrG z>v`TA=nIVB0Ju!)^=pp5ilIrrWC-W!!F>`4sUGaeSdm4_cMiIyoWF;!04ueZj7u|@ zFS+icFIYt=TErR{QTkD>ztyAv0sJHIY3KBl7p#=SAjcuD^($|1>un-@GMEZXy`2P? zDZSpj{c=?0URm@^N5*Q^zU$F7?e!S^74QZyzVEEsIsVRjhIS$HET- zlYsG`43}wV<=$iWj*DG;w(@I0&y@Eb_)}mjFn-U&Wy)M$uUpo|wc_U}|L~2Dew{o& zmBG7%-s)#g9-4ByI=^6!hs92GTWqaorKE&`x>oDN_?s&7DRpMRXM;H&oyvk#oyqEY z5{GXst1h)xe{;Ff$2An}<*J94=)$?c7%;xT!k#nk- zj5t_+kgEmEVeXbMyZ2{rT!k3n%gfCVuy@PHT!z*0!Il+Ss(iPiTY;`D@4w++f^UKG zwbm-%t~$>8P|u^<@tsnWyne-GI>B_R2f1MIzSFrl6cq;r=$TP5N$h4*Un&)!tIMx_ zWIkrW7l3ns$;T!7-%YvAdrCgccctCj}|$v=Q^+Jea_pR>QDZY z@~Kt*@MraQLwmXSRsEZO`&#|V8II%z^-ulQ2Fk2^Mg88apq@y4I`B$6S6pw4dH!}@ zm<|4D?=^{w0qVbTx#GZA?Z7r$?s4oXe0Ct*musrMM9AMm%-}NiaCs@)E?kS|QQ|N5 zK7p#j(YXiYirvsZBM{2fR#2`vpTTn588x|!U<-4_O}6->%*I$T&)z){3I&3pl3aF; zUFrTjcoDxaJTNR2;ui{8q3ab8x##AxqCRg~;DXSeZ3?nV3d)xk?7;K#nuhvsTCNz$ zO=Dt#e_kMTa^S?!Fh}E3JFwCYUBm&!)`3ffxMZ~M&Q^T2>d%o|+~aB(yb_ECraw)F z%d|c1I=s`L&YZDm)*L!gqfPzu@~yLHw21ZG02L7ug$3d6!B8+y9?@jrd@;bXu2a4Z z=$i5CHu%FJ0gUe}aG7T7eG2RJ`jq24ucqbr z%=u+7b)PNcs9ohtY*`VRY!=q1fsveFb`Ou@HJ>YgdHyargYvqFKK_8*?`s$OIQJ|S zuR9q^+^F(16~BqpiyQ~%!t20Az~pBWT&B3bZkkeWr`9Z>>*&kawBe(w4ewEJXZ~sz zkh40jhy|w*-F9V-$HyKAb~xk*MG-w~Fvn>ySSTXFzT!4vA6mdRnH(bjpM2~@ImmY| zzKKSaPwO_f-b&y-Kp$Z8IS4LOzFzMz}d^ zz495oS^3qXXU6B{@N2+z!1(pesGuKaCzX?v|&|GX3+AN%nLi@bO>7OIaXMG+V z#cu3;t`ilAUg4$UxSWuGxIa)z3w>dWjkeWti^|6ie5T?f+o$+;zts;60wy0@|E%&+ z@wQs$8TgiZck^+e)47wm>E9Z-Iq+q`ZVlYF*O!5ESr22Z%R^)Q3;c4jlJESN!zSX3 zZEkb8MEHYOipV82Q8#f?xR1Eq4(_p)F|+&@f^Zg-*aonH~9VaCjgU{|r+4zuSkcmsPP10UJ)*AM8zl?~stq6uN= zk4pzUUw~& zkT2d6`vu07h4aP4g98-}n;>bVRfd)S3iZ|>V?7$j3=e)?xSu-^IUU3TDZ zJ9L{J+J(i9xY%rqXKdDqw%NYr{@{_Jhi&nP;_z|e$h_C>Lf(q@XZL?Gq;#FopV#IG zCxng?NAo({c~zXN3oQwK{I7TC?+f6Uf-8aPUmM{vJ-YuqZP;!M*ZZ6||JtzZXNf%P{hTqP(9af*J8iLE{%?;F9|}7peH^DI>!a~CCp!Z zCRybsk9+0IHC(PQ;p^6!F7SG+zs}AZ78oXX!G3FtpQUE~)*MH0CAtwl%j5An_zj>D z7~hR>nFhA!J8SWxg|#zg$r*EL@DXUwg|t2}y@y!+<&@+Bc(3deTGovSO4<&LK#b`!gZ z!Tw=lR9_9oz*> zzBa*STGHNl?DQI$u_k+?b3K4ly=^^|H%_dyWu^b#7So--=H+?iXWiwFgZc1T;5=ab zrr)dle*RGP&*!&$`f07)JcD2VMBa|z<9T)>?;n2Wts&sN-6ov3kJQ@^^=}EE^TRFb z4>qcQ`&NCrNd3y^qaV*Jp(bDNE{?Mw5)5_U1PyzBob^iHks?aJA~IuFlNwpgYmO+% zEn$cE!EzQ^BHs0JI?NS+^*`h*6aM^1ZE=r}T|0lUgGFMF2#1dqhck#q!%vHU+sA#x zcp;+9bcH?k-*WsM9WD`bf-^D7Bvy90?|HW0;4DI6&PJu8d{bs`s7X& zUAuP82Zce=XG!3!S8ab81t}BC zReMZeKlY@S^=9r>^t2s#Mh+Wx*XQiOT3_%rhx|={EH)o=8|++e&7&9{2z<%s$y^)j^{K#T zaAiSpfjISD5%{;r@t^v>2)xC=4`&P5EK%a`^`Z#8PUQyzp@VY{>iM<^T;wYdmEoCU z+>avglPC=IS?&v5=o{8UUhwL3y)SUB4|90YmA=5GzM{+IPYUyT9#=r`!1HMlc-;6u z^^Lp`N1wMaej*pI&YcZdf5)VE`RGaJMeQl8BKO7l+N$icy z0ln;!LyAYNwTJ)SUpbk!xzpa`*ZjRMvPXYt@3qn%J-6z+;NIWZRU`JkQdAwY_xP#} zft(A%{PU+`-(&N}3~#Z=99uAEILi`@t+~#?5#QjB>xQ}uLaI)*;;4zPh4_)7a1yXS&`A93$MpJJXiSqCBbgK!XgHB-#{L1iTVfCz<`Lmtt^0g;(!Sgh* zFX#aZYh=BX&zHMQU>xjD%sUGd70N&_#|{SrrA%UTWFD#04YvP6+wNmE22}nU@HcV7 z9q@a=Mqu*S4428Q)xg^a$fmZ0+QzR~p`3_k#j2gd(YxJ>K*rp|}{7d_`ic@cQR+<_i@R<}hcu()OxrGBv1KO-sfJwH~@YyI20JaW8gBS@2_+E%`CYI>eSg(OKD}v z$UN*St$Fe`-~gLc)y+yV?bCpcY5&{cTfqy!_yb6{7tL`O5@I;Stat4g+2(SB zlM>pe2_56}416ni9vGiyxJ>Q(9M9&6*)x`=J6(gDHAdYkS6rm(zxaOlywxARD;NS~ zlI^;#y|}<>*FzVcSiPWz--=L-i1m>#BLAjR>(+X7m%*Gv3zQ z%gkA>3q~!r)#@u}eC@>&Lq35=VSah2JI??RWrhAg9$Rj1v*q>P;$l_49r&2zEB67e ze}cZi>w>F~7k-f|+42=Fi3Cr8hI}Lb+s78en}! z_{;oa7w(^yH+g?6~Opi2bU?cpL4LJ8ot}suvYuE zpcg?;`h5xi0sI7vU*N%x{0^GI)@pC@K5gs9c&Pni=o!CR@Y6vJFn;I2Wy)MWeUM7e z=s9C$3pU!;_joRm_tcLNR5mGIs_HX=o;m;h6aE3%4vb%yhm>FD^~*yiPm-4S5jL+3 zY>;~kOE)lYYLb)2Re^FIp->$emA@~Cm5r&HyL{BU5G(nFbL?JX`1 zSbWcw%GXqUO+TIsKMR}` zq5Y~JcKr^69|MjD#xD-vx!;j<=kvHZS?$qVZKs{()lMAO*|MQ`=kgE&_1#tZ)}t5U zvn=03@F&1C!1%oYmnn1kCOdOgr&~?pIVo~rxSyqfn4BSx5aXP`=B0=7D}KcF8w4K$ zh69;)KK{G&Vt%t2pJJB7^;wMZSL-kF=>GwJEw~Pt^4tuUDRX(`xRX3K_hRQ)lZaa{ zQlg=vKt2{{54qii@AFaR*^Zt$Z~g-BMg-Ff7{ApzqA};qVm-b(poo^ zTNPs2w_ETMI}qBh$Sx`m@u-a)e&rsUM=BKYmnCx5U_fXDzvVwQc!B7_N<$DGR~$k+8%h*&H71_c2)vbCU#D@yJuDzq}w^5+F%xlX87yiZD4#qgv+#N#`)rGJztE^ znl7hrbzHs7EfuqEhLI8C80U|9sU4*JDxY-E>j%KcfkS}tTLYJ=p}qKk`LZrzQvfSo zUd-Lq--B}=0cXB^Efxj2~g*Df4_#uYnS09J?$` ziE6D+^ZPk*O~|qiGy_;d`!%B%K~J`K3;YA{vG&+`d6IYM%josTd?`X|(Yh7SxVmHD zW5IYJQ^&e`OM~i6mlaSU#k;BcUx`K(4VmAY;g5r-fvF#{MR|Ov?~C5^DYfq7w)c@- zjG8lJ-nhB*)%~z+IN9!VHk|yzh7-F<+%259LpJbK5za9=*6MC8 z4hNw8k1KT|H@N$N!m@J4?vHH$K+!!I3Bn zCBLS<&xWr7Hv?0iui!G(zp2U**Y8ew)WZ_wgA&e6D^&l4|3mw6znx$swe$8b_4dBs z`Sg0|aeqFAYb>!oEEvP;aEW-;W{1IB3>{qG4p#VizC?vMnG5XWcoaZhVb8ohxzS$a zlrWj{`ycT0P_q(ntzEz!)xO@Kif4v}@|e%8xBbg)QNtDkI}Y=;_(BAck7a+Aq4*E#L9*`CuV1ewV{#+OD6A@VVaa)281ZHhI!f976QkJ5{f} zG1*<^`c5KfJy&?RI4FM<6TL;;*0{TUfbYQ2M|OylVvV@iFFWFBj;H-qJ#53*)Wf%M z|KI#p4lw!Z372V4v#zi2TW!Dp>CBZU?7!Q@p9#DB1+ zY*WMk>LvG*R}RTb-__pDt~_D&;|Py$(-&;ltt0TBU7=%ADc3Rshn0?{;6 zAYdW3BVxm2ITn!UK}xV-7e$B-yToH}h~?OgQ7j0OeSfpotn8hT!ug;3Joo$Vb0>Mr zo;7RU>GMuq3|>oZ|Fp^Ek^Mm9BGbK|w5CRoKdG#f~Ufe^x((gZhG947k7{uAoF4C+Y1W5m=-+!o!B5fuLX5 zhJ@IIPINmt(P&F$MQmg*&G-xM6;A4wJDv*B-jZ#$#`;51htikK@41397MQ~vw- zZ^{1_z8SE;=9eD>-?{vGrBx+)lr&R#gA~5e3_))~z~+`mR0vX7+`n6M+@nSImch8% zF8$qpl1c~USmkUnd;xHtk}cD$-TpqWa2bNp(y8|xbz-X0p)rC+50qn1IqJ02_4l{+ zDGQ4TV;PH&1vs>zkmDIK^|uYlbLKjgzYZJjm+#-EsE;KGj<^VdkWH@^XB#Om#Z@=U)hoHZ-|)9rsqiNOa{){4Gw{+_ z`=G3OlcVC@vKKcdvx-Z&&I0Ofpw~4}Dz^hZBHQ*4x&2EnJ#qaF*%Zm2GpIjXVdd6A z(A%m@RNY)fEC|Tcxk%KXEVOj3d<`htyOz{I0^o^ z2AU4^1iW#*iFd7CG}&SttW~hvZip>SPMJr!jj8jHhzPekl8{E(x||c%lf8Y%d$&-vZuKVU+c%%WxK0Av~=jKaY}`Z4`$(`)FCexRWbLjuJ5QO?kr_ z{PlP${9<4UV5QHE@X{<*`=GPcJ;NQ82lWB3xCUFJeXmVxV2Evy-Ud$HYl|T`YlB6- zeVlDT)DX6;l(Q_k(3TL|t(W|Du5FaFTT}=;$64o>`|rE6LOI>GPvhPm?G~G3sePgm z9ISva#A^{~1MDGkqn~}FIf6Bh85~i&&$O!qWti+DBZf^#4567!tPH)xm{cZxR%>jE zj2GV1&2X?-(-MyE@I!zRfEA7t;kyn8m#dlKSR#WEBhhMYRX4&xPc=_26v%KyI^twF zP}mqTR1l0f^wu-XaI8j-l|Q$^-w!+tSmAgcUK(qDuvL4rSYAHYatzU08Juja4+dXP z>-LyDzEhA!W80J4o}$@)e?>M$OgN_N-=083@+_UF!Eq7jpY|%p5<*T`a!`5oy!TMUw z6FhLO79VV9j2f&xO9*VT6P0F}na>Bw$1(hr?Wg-4${vseSou5+UYaTDT*(x*52#f> zt357pwYHmV8*Eyw?GDW#3k)2*!4^%Xp~0-RXUXlD)0wB9Xryq6V`2ATCiu8hovX8p zY*%X9Y(t#Ls5ZlQEAp-I)xrM&{0vy(yXIXpe0lrK@;B?NcFN%y#x~u7HIdDBUxZc@ zSsP-IPt9Mig&Mz}HOWrR__fbwkab}Oc?ZiV;?QuM_}G39+X&)6Nwy^dq0g0mNM zZKpUAe8F-Ij7Q0&o%x|Va{L{7wWMdf3tl^n(cg62?hm)*=ISrX|rt4 zYeCt(yHdVd7Cyn=D4WYc45NB#gXqV5YV#R}$1abWA~#}Q$PPgH2X$7Sc%h{7g-Th< z54XWC%?aO~y!y(etj z?V=ziEDh!L1Ui?YXgyB5qc^zQWaBP&C-;bu03+B;ZX2jALI1zW4Bz|6x7yS1;X~i& zt{1=x-$;0A4(>I}&HIYBly6IOq#cXfZ-2!0sa@M||4lQ<*Cv_wDfi|-A-n0@wN#2m z8OQ4e6O8UCY1uYCG%hNF+wAYPg|o*^-muT{s+BY~A8F2M^1KGSF_<5`)eP@y6&_>! z2VVy~4_M)Keqe^z(r>Nx2P3@JdC6KWc7vwXYKI&Kd6>kEAb_WYer*ey!3iODfvd|M zf|t7J6|__CcTCu4pRhAzLdF!W@bQQlSKB9~QaP8bIjK`C~17(&$xWHUdgM)KP#S(z&{Q=rDRBbzw`JhDVg}5DIA%&kJ@0yLwxM_ zw*ley9+uef|ts<$D4xItdcYIttro*)fUN^?7QU5OE>0zp0w@PgbPsjwCq>%Ucx_1-Y4+i0*!zr?-%$k<+W^` zY%4IVMPU6uRr%lNmp2Q35pXtO$;*N7Ql7P?GDhAUqGgA04~U{(V96T?-=#dYKQQ}NEvuU;DB2PfwaJuIgFjZj-3-4TxErwKY=W1@8uzrcUxD?n zsAVf++4EXyPef4{ddT{~f;Bt4q}goBYr;RBpRzvK_dA3ehypBmJ>aFW&Lgxd&zf(| zzE@sZWMo+{f0h~VHz;}8(tm8EybAaWfEvJ(cR9Q?o#va`Vi*&UkiD&hG~TA1Y%$~4 zfPa>}FX4Xxeg-UgzrlAY&)Q-bD6ns9ftg!Pc^RMi<;{aX1IPj_dAaai$}_hy1xkyx zq(#-4a<<@)6|Y_Jdw^E~OU_>SF6H>Q76!^P?&>iLKOQtFdA&dP_Y2AJqk(aNB`+Ob znoj$LfUSk{rYYG_Q%v;0qEfrfjNfYf)A3K1lXdVLfvtcg?>=~GIxUwiTLuFP=D|?msly?yStn_q$!5xS|Z@`il3olKl<zkHrq8Z93W-QWoD86fGM{gf30}F3%?Ke z09oBzw=l(I-(Vwxy^Ox0 z!6uS{mU|S+9yI0E;-A$&JOuwFup6-CJqIsMr+S3Bl_{p|5wmmHuL&s$h*xqyc@K47^$~y!f^fi4S zV9ASwm!{M9#oP)MlYN_6FlFrOH8C0>-=-Vyi$_g)i||j!M#?LKuLdpxEP0o}OVg>m zmN|kp636%@)+>20;h$AbK7juW_zJM(eFra1r+T&8GUV4G#>&LJQlp$~f6R=R_ZxqG zn+`u8SOi#d&VrYw({?jpZXqW7Ml&&$f;3)6Euj4@d)$<}1%Gw?mFf8u{ByudfF<`e zcxgIKPisLY`$;V;lFZxBhs*$}C7EA+pnN`I%Ip2DKb|Atj|avBmb?sjX*!Lk+Da6Y zeX|)yDYKq$`TNL}sd$daR!22D%?kSSGa z!|Ydb#drRC7z;lb7!Fu+li{W5v>vwIdc=anC)z66Zd386$jUEoBr@eb=`uX5#$T)c zuZ6!2xD&AC-VNWS+`z3dtz=GXk-7gVm*LSj_-DzpeNWv7q5w-?5BM(Ssd!quK>}kr zqeY_Ojo81_l$(vemfV%_mjSB*OYSxB$12y_Wf3U%q_%ROHs!vLzgBzj6Z{{*Uw|c7 z{9wxMw4Vyxf)FsWnAOrMpfBz+<;}o9OWs-Vc|ajx$t#AJrc-$>TMhz*%?S|3`}Mm` zc~9V@blyfhu?r`FDHuFGs$H!`oUG-_yOJ^nD4aH6QGH{}ic(O*BO z!OsTf0hYW4@X~b99{A9i7r2{TWkkE&f{V!jtgN0xtrV z+*jeH=~AwLi+N1;0nM06sI`ex0kM*;LWU=xjAu=`y&L^<)8NMf>3}77GQ2ch%JpwK zkI6n{HoM4N&{l5tbEe$2_-n;?3;cHAQNWVB1OAxgT3gU#vTJNveMn-aX%@+;nw7T4 z@NDh#rabYJzZ~^~9|#NuEO{f~rRks?86(A3g=m9p>VvIj_YB$WuCOf>*)N##%J9!B zx2xfA0&W8=dF$ajk*7v*tt1+AC&5NBLfToDM8g~5-DArA27fKNjwaF==m}VI`@pv= zx6Qn?|6(4gqI*A)U%?!mBJbC$w+ROzj0Gn~lGg+?DWKfcpST?t}2sT&~Vp zw%mVU$hGEYTT5N5ZE*z5Pj@r;n4>T=))6vXPQvAsRqJ&`d0#QZbr88$xVrt!nMc3_ zSm7EBFU?W;?oW?1Q_l{ZJokS=-9J@tTrq6;Q?KNf;jbn4O8E7_-GC)`6TCE2)Oyh< z>wZQnJ=#cR`RItbVidMlE+572WnR*_cEBNr6T8`+D!mp_ubJ^~!hcJC#4p_Y0}KEx z`2*plImURmOq#cRKE6%lYn9w={I%p>2wwwSp=1%xmi%v-Z)z{TmbA6owba!#DQVyuoUQZ^wTtz8}DU349A!@_&Svrjz(q@F|bn zO8o*oM~CH}jB)y6y|AQm^eFuzV<{%fSc-86lrdw;&G5Hgg=5Tb{%~Z$UjWnqRyZz) zm!`vX=pqy>#a(7D#RV?Hxv%FMD{8k|T{+Lj@YghJ-&ExvxmNo81t0voLxcfVxT4^t z=_Gy3d(%5jqK<025c7%+8@@#_#rtW|Pq@smx*Mm!#a-vK-wAg8_^IZQXT4*bd}QLFrG3h*!ZAZuel1R#w}mxlKJ zYZKTSzKh1$RwJ}FIG3nb{%7JBOaDfAm%^V1lm_@8)p8HDKiy}sjjBa}ncPnzKzd9+ zZkh(=|91Sc^u?FqUjrHf{MS42zpS#nB|qQS%naSH{0;fj@2>}b5HJjoMy8ACz~9VL zveCHL#0>a80?vsT|_DWhaK|!KM8&+FcXkQ zrcZ5W{s$)fbqK=f%HOrh4>`}X4t^W(I3WF$dcuq9xuqvqRBi#RNVYbD7#C-sO*0;o z9wT8a3sL z{~iAP|KE>m`b|myFBA0lep9*~<;6}%?hZ%KZqCp8^-OoZ+_&cyTzi++bGmb589RGN z$t%2f_0rC@y*>|gs5|Ikr}hMerIxb#MlYwh7gzPtE7ziBd z;S}!z4+3j|d>|d@0W@`YidTTUfs23zfEREBUq(B{Q@|}i2`~#70{FT)#RtHnzzsk# zFasC}{1xRCdx1^BrNBABIG{K1OQci03Ty;c0cQcJKoIa@gj3uPTnNkqh5){Br}zkX z9QZp>0?Y*B0Rem*<`j6r@2^0X+fFXb#*l#C)fI8q}U_Out zH~_ABq`N2GfP7#qz>y>Iw&oPi0qcPafjPiXzzO_YIK?x-dY}?G85j#h0zdfJ8v$$t zQmQJ-Q{>)&qLd}2DHY|pDXNu9smxhiM02@>YnqOBWHhBIi>nF>^2Q!|D{d1Fo>7pfrm>S9cJO)(&NO zj>TbTZup)@mjaDZfBR`?1c>{`xW2ptDS;n)Fg|wCzDMf2B1Y2X<&-ZkEb*t{(ODMY zS|)MF4i=XcWG${RQ|TBo!t!^e+%8v<)hZyJhkK=Z^*?#XdZm*Lw*q82HAB=vQnz(% zMZDwWQEznRUu8%2!jf3dM}zZQ61rn~`6bIbD{Y(rGzwHM)wfk0I@-rTr&Rc&#W}g> znHBt)vKb|Fc}`*F5&~Y~nJ;CfrA3`RFD=Q<@9cSJVJOcp zD9X>R>@vNSv%LKLvV3{7pCRuU(#rCGSx!+^M}f557@JJnuP2t1;+*sH3;43=v5GIP zNXf6x&+V+#SWe1HD>`gAal?Vc7T}Uz9bnHc5XHn%-u$}o{SejB;+JVNYsH}%xrNh?lL)xvbbv}g}MM;*5%EH6K|uvoPhN0&#-6_GFKAV}y2OH+_UNoi4vj`qlK z#Rk%2@T8)+Ge=b=6*&bRrJy0DtaN#*w*xP%e#My8;LGr8Zmi4ZRrOp)y=Kg;nejGz zktKzdORE+q=av?yRF{?~EkP+vsi-U}EIH56Sn2t)N*AA-l0_ewwWQQ&m5iYNC+`&& zmz9>QeC4=nc}2>(l=KxT(@m|oYp=`z8FJIp+taVOp)952nk%1HpQ=QVvB!7e3S;?|omsfgQYiI3hj+X1<{Nm!$W%X4T z%FnTM(yI6wU**jruRBP2D;$;Fa+fbvrekr}l^eM;yZu(y5-0Pidd%o9T@^D<>&j7O zRflavi#TJIqf3vvj($Z^VTX!Yi?G5a=U3%-tQx7DsVH1hmcyJ`XWdzVm$W?pfy-kU zr?m0A({V%_w??DgkqX?}ZQ8L1I`x>G<`;L=(X|N9m+Eg9nXMeB9h+e&=pq{uIwsRi%HgwbdeT+mgeVlH1KP2vm|$UX?a&oWbu;RiscNdx=Mp3x!mn_ z44!r6PeEZd!`%**=9a)0a4%X%gU%L5`NhXpD2j9QOXxGY^e;CjcWIZ|v$(L5kGFRf zPYO(VVTZGAEipKjv>>(4%c|(QDJd$T2zJ>g78cNVb`g4cu9Y}u735TO)if!m$KWB; ziJf<|Qd&{zlCD}g^#1(vj&w6CVU3Yd7xLt6PG`eM%dfor0&8Hbl%LMyk(a-?YDpKe zbIYoZp_=C|?NAA|0*9VWne8&yr870n)J4c-%aT`B+*JWr9(LgwuDWnxuHBOl#?YfH z$3-e#14jk&R)>m|@_e$g%}6A-I1ig7IV+t~oKt9)85Vjl0m(O3FRNTC=c2Q6!Ik-X zK@L9VjnxNNxY~DjUjB;KZrixaEv+ib(@RP#_0q+a$ZZk8i})FeewUvo^uh7fqC?TG zB{M&%mlo(~>ZRo?*!-fa5L4mHD_vsR@p@kVGL$_rEmfbLpI2B_oRpVeQc+mBqUAwa z3zw?TDqVim^HD9&M~$x5b4v2`X`_y>_FJY|mLmf!)nk2FQR#A>acO>ef|zFc6lkj_ zv3aL>WLm+f)YNi<>31__MM)03H}t6m1w^1EcLhGA>N5(LENvUaSw`I2v7O8$Kuh#Y zS26`Mi>fNxaoxVx$ED4iDg{q2Eh#}ED_kbij$v(nOA1&in-Z9M3*@w-J}c1Os8OR^ z-Wl1#wTY539og3ZMYGxlcbYdK3%o6!c~4m6=STVT!>d;?)lt;)Y-H=-v%J+U0fN^_ zxBMltKpkhj(aN?ZNvDk*Y2}xgHqtv%UrO%qN~;1ktHp_|Un$2>LzzP;=92bYF?{%N zN{5_7$TB{;qhsL;w9T(BWY$qOt69aY+8_N~?%~L)Sf1DZV+P~7`JKLR_+L=f{_DAH z*A+TRqr2rrIUswitG+sif7}nv_$VPdF=*F)qP3 zyGu%!m*}}m3(NGvJdbP+Tw-PkB?DOnMRdWsoIXj^%lJN2MLrH`<}Kft)hfb6d6BP6 zOfl*{VKItsex6=fAzQCRyfuBDKX2k}U83-Xq!4 zl;teRuaJ$;;FWpio2{~@Jij8p@~8|sw=!o*R{M`=d5>}~Rp+V-zqP!SO(tDcnJO3h zGSbb6Yel8LjA&WLOm3>cu>9&W>aCIbqpA~J!YojFnR0A7Y2H!2~ zisgmH?O03sH1M=oV`+=&GYZR#m$Ugy&nwNZC>dI*S5%eBNh~%kN{>@0n{v-$e!0}X zT;e}?-3UOytFp4lq9@ab)}LhoeOYM{GVr$bZ{jexD6e>dOBmWvhi_TFDQ}F9O9h{@ zw0MOsXIl6$cAI>s!!)Yo$TWR$HAT)WY5{fGoXrVvL!~ha`B84@*Q761s$^R3rpoE< zvAVpTOE1bVSyD-(qmp-N&a!;cmbXyHb*jvgl45lHvHA!~wJhJ%umCYKidm)u-X8CJJ=mdTAs7`&R&84(22`Is;IWy$Sr_Ab_1tLGMeV1l1@T67XjQ0&oSzQxa zg%In)3Q82^DlflUFRr3$EY6oz_DpYba+>$-qkU=<3YSokZSg86FOOPV(b}`>)XB-o z-s(|pd^AIRl$QaiPUy4D$uBu_olb1VfDybCR=5i5ZStn)oFQ3s5M8~a|<^+8;-J8{7yYCbGq(*DzyE{#-|T~9TA7s1fk zIzsA9IiI>Jf|3g}ny zbft`_p$tebDk+6hH8;J_M{78j$*vXplG4&V8C6UCjGUqZGu=#&RRU3$=ASxyWZEpV zVie-H+=8jHz>J!|;1#82QD|E~G;_!dr^hPs;e$t3rORjIMGy z>sIZrQa#9=X=y3bMy1Ree*%EuNN;!u$mRa z@yN6!+4mV4oTyhBQpfnM%+#jIIR>u+3P}aUNNI{IX`YX*0JPg?bkth7gv%%hS+cko z^}a&24FTn8B~^VS3TNx$)Kb3NCftHqDbu_u(?rU))M1KBJp7XMyAVPGDFVqRr>2^F@2BuYxcyo*&Ejud0G| zWKmsKQ7+YCjH#o`v6Gyw$*L%8Z7G)&?*2|WV5&2?*MY5x-S69j`EHztmIr@tSM6$%$z*6 z^{*BUYW!*QCuL1KZT^I@1~+lalz9_m^<^dBC6I+8F)~k%>I}vuCd;`aIe=gSoG!G2 z20MxAh4WGtSi^CuG%uqmgT?3JRB~533E6>R5iI(XN-|FPF*Xe`qvTbl#~r zQXb&8tp_dYz}1{Pzr0@X(rJYz15 zjyN4zH1_5^ff~nCUs^N`IZ86aVhPF1ugEPgEJFk04qGA4^qj5o+8k&Y78TU-tkROA z75-o4`MJx);JhSS0TZ1nInq@jT}+ue>9pyj-dJ7CoHK2%$t|2XZ;r`Loi}gpJd>R^ z@zja4OqM3bctZxoF!KCDpb423J4K6+&+#6#jq?CsEbZQ;MILVG-qa&fds7?R^rqOw zrQ;bb?|6mRHA@@p7!qGNVsdW=&tKzuye%W} zg};js`9^hEng0!qH#Gkny93_|Ik_DFry^l?_E~Ez86mt8V!ZK_l%e}&nC`=}cORI0 zyY+Np$aVU}5J{R>%Heq1A?PhAUJ!b+>SoxrH48j_gS6BZYlGRF8s230p%q?7IuCsXOj^ z3VTyey4j%g)O5m=T3F(JVIm)Lhc}8FB?oah6qt}oN#6wkF0S*%NWn^ zvxHWEmJqdP<33x6rUKyg{JdH?_FpY*O;?Nm%JlXK<3P?pMH3Yrt!Rd# zCn&m2Go8koJ zTTrwFr`_s*1S@x|l{;Da_W$9FGeVcik0yBD>89M>72w~%l{_rTer^ewI5FaEx*Mt7rL^a+#_ykbT2_eJ%3Vu38~MR6l`g%Me|gHCOxaoDV4Ts!8M4Vk zP5>q-cPra-SHnxfbT?GFTNB{!HOs#MccYcNE$z9h_xpFea<{uZcNsEPrrh4j-5%xc zsQ7Lt{bmTED|er_btmn0=^gG!Bad?DIHypyvp6AcHI$*{e*!7-ZPZDg#qqb!k2-6FX7Hhf1%vvwsj}%b>Iiw zaUgb*a#!5eofW?Kafkb<%H4{#?xejuc&_}LqTF54o;%8&u`O2@dhC3D5P*QfL zPZ{Zr^raxDs3IRa9%r2O62qVg&`9T_1cXSkjta>v~C=8M`W0(u^(3w@50sj4)_T@Pmds zanA_D-(OM=q{!!CdblBPoqeZW=l7#xs(me)JJmkbE}sv}oH%FZ07by$e&zZYm>byzncg^nF-8CE5?ykAsbkB3%$ecHIvgyG5 zy>RA~Q)j3*WK+CKYycZ(iYBH_Lu)mE3DNK5ewxVacOlp?OEod(T>ta>eg}B+S3jTi zyl=n0ni$YG4s4hntH_V-y?^U%{;suYq5){}-=T@QK+A8hCXz=5{B~+$DA4jeF*%Xz zD-+KFOXDSXP6Djw6TP?K!+P%qurxJMns^4Vo{Q~pK+Er~Nn16MvNZ*4xF>Au0>YQs zO%uxi%Y8=3nIW1uC*&Nk;XYIo8vyIMAT03#;i+-)9I&2e@@!?m^K7223V1HUG%*9P z+-DxeLVRcYo>JgUO-j{7ZR(TY)~2@mZ{5j>?nl67+jehj`}}kJPvmk<;sMI(pNT$I zTK#_1Y<-;^YuNe$c;D7fRqpwpi`e5y@o}*;!LwuMTB+aSV1M23q;UPVACcU&?a!m+ zbHP8Qe*e~He9o?0rE;U?bs>VoX$K>NPXf;lo@=&=0gtm|ipb%Tm@;sAOohsAzXNa5 zk|a%(CY6C#C9MLtHePW8c`{K<1Luf>mi)0?_4f28Uz0t_;5)qQylvmFNxm(aC&>rE zBIO-bI;^+-wC#J=6NasZQLVJNMDy!G5mo0qHFy;7(IGc3vl zb##=fr=y{h6>q&S>PFX5@9JiQGwV(VpH-IyZZV;mp_-THi5WKI?rvdS=rFD5u^&>Aq-%)(a`?Trn0qK7&bgSa6=Ysh5Q*n-iN|0_X zQ$u-rU6rW@=%;PUS4~e%JPOEno`8O$cit`4jguw9E(o6gTNIM@?Lg4e*px7Y#F+Eb}W^p|kT%Z?% zEyFY1oBhfvs09C0As**X6Ia@=L~ddC^Sf)}LnD{0_jLwmHE5$kuL;$37e1%xSvrb3 z^Qh9F)sCykkzIX1(c^;l>HB&9x&9@%Y*V?Rmu87{eSchreyZL>jBFl7Z#TPnE;!wn zZuE>#i9Y%{asBnNdVgV0b|%||D>*#bF8b4?8meWV0hAWK&j_%$&p2>KpA7JnK6AlB z=zY&Yi^%SKA$V2atH5jf-UhDidmmVcP!TS8pFd4p!Jm~@!z{hrh?}O{bi3}*oqCWS ztcU2K#8k#pcr(sJA|U;m2%W6>8%xP6K-za^wu#<)aa=z=R;O(0C+JK+COe2_XmS{_ zj7`?fSa#^e(dlo7ymc;g_&R!yCi(y}oc*CA6z_$mE54JrMXGZFE%xcoEO3tVO7I%z z8t}Ew>%rX*#~kh=1*k8xRh^j!Emiy~sDv)w78#l*t^uUGTBro$oquU!D$v#Y`)QAU zQEk$%(BBk)80u4eXYm)*uF+@}Qcec+G{t8_mngoo_iJg79#?JBPUv36{|o9xv7sVff`V`;k`)*C#07&__LDwmMEA#=yclN$`UlUh!uEqSc=vU^wA8LN#)hvWsmyJ<&hTOD^x|EuDzkJH4haT~x};vN9+ zjC(CEO8gb~7kvAsu~!p4a<=DE5ADBaH8|Mo@%9x1y$N1s0K8+tUv2uy=&RcG!Ere$ zaHS)K)^0@q5&bn$-M<>VKgq{fA!E}9-b`*zu|{!6d2yHb5E71fec+~4Un*KqT5}qq z9l3BMeYLODr-}1@>%kqE$mx-kfXE{7`H}ws-xj$OyeslG@EehDgFlG;5Zu0*sm-Lt ztO%;09a|o`9Cs@sSAhQ+vys;ST)kA+L_+-V_>SHW@&*%fPe5vkQIF2X^_+J$fd4E$ zL|=dC191B$BVr08=K6@|!H@QNoId->K2L%lt$VCa6Fcg5fS;<{32xuawa-N}$?BHf zO%spAJW80^Hbr6_83yGHgum4JLa zk&wtano#&Rp)I=VAV!!#yIv61+v3%;0C#2ZmFk@u=;Xoezh4{mLKGTg)QjNPqh1F$ zL>&VE73Bkqq`{QJp-Dr*NtpIRz~>#6&S!(hDZU2kQ+yNi4!+3NdZ9ltY~tNbHZyLU zZDQ2pCZ7TA|Afiw(7WDHZu~E{a4bf#8Z5*a083HgAHbu)+rR;UtTmL$Ind%ZQMkeR zA~mnU`5m~)`75~p;nC-;8LkVENd0yM2*~E+5%iveE*T6q(2f#IPSH_`h#{C0a8@Cz! zaNKjWMF-*z!28X8EUC|TYC%rwUu@7PLC-K(5z*Th<<=u98K%abt>?iP7HvHk|gaIS_*ko+3xwTizUx?b@cpj#Dh$fuv3 z3dnadp{FbUOlXecbD_%>e-ZS0#mo1T_|wFF{8^f7Q12l6tth>lu8ElBm}KTZyobHa zQZ(n%iii8cN%?$VzDj?&ruZL~|2FYIdi+t#hziZCmmE0?V?&Ww`6*fD3 zcd#V%8KvmozOP!!($S)xd6!vcK!)QmwC8&!e;jnK;!B}dDSj*TImI_MYT{?WN`s?) z$A&SEQ;l;%pc15e7xXyA9}gX)`0-E)(oH&4LTCP88h#mhbVc|r;M>C=1V0@96!_`z zr@{5%d%&-RzXIMH{xCD_Q@4+{Xk|$A%!@QByvi{yU@WkdR)MA^@M#%~G z1%ns+a@#FM|6Tvk`P{IKO-<-!l=dq^uK`~lx)yw6=oWBY=yvc!p$~x{3*7elPSr@W-K_fIkiW0{m6zVQ`?i#C4eq|6SLDuXo)5zR|S>T<6*je#rGO z_)*sm@J`nY;1^vlgI{&M4sLKYfcLw;0DtBB8T_Z~PjD;K&4+rC>`ft6Q&X=?4d`sWLvmn!}W=+%m^gWjk3w(CEZj7!2Uqg-7Pb`AKtu(ja7hiw7Z zg*^;@G;9ZWXV~-LJz+0_UkQ61{7%@r;C*5H!283#0Dl$s6Zq#aIsR^KG~p)1(pJut z4N?3s=vc*%hn}eTbm(lwXF|_bd=2!F;sgEH+;%th%N+)ebVq@^yN7{?yS?Bv_ek(@ zZn?5B-aQ38-8}<*vU@gofqNnNEce;qEO#!rz`YzCXeKZ=mmqByLM2FkJM*j(B>yy2 zg5)1y{4PQA`J}xB$(KOOt-Rp3Wp;(`qQsgdd4hWa(ia+`+U4E_|DO9j@UvmhlB#B! zPY9ntYi9Okd&Bp_e`>UK=DNID4)64BXemXS%T9@Px?JE$R}{FrYZ!RA%L`6(jRYU( z8Vw%fIsrW1H6A>{H3>Z3H3NLIYc}{4*D2uBU1x#Mah(G$a8-c?ASK8+I-x;|4}*4B zd{1bM;`>0QOzD0Mbgbgjq0<$g30RQ<|*2>z0YOCvOKdBo-5DxVUmI~P_@;<|fNzV~0KO~YpWu5U?g4L(*bJ_V*ap5YVh8xCh^N8kICM|M9{86c zUI#Zsd;tD9;!|*Yrcj(qTBK+x)bW|Nnbhv3wx!_pw)NnLY!87C*bguoT;N#XAYB}b zz>E7YW{%*N{?gxJ!`wjTV*dM{a#{LRE82cxm;<1>eM5psb|2)dSi*L7egMQ zwbL^xt$h(O4;+WEe~1=#l(bN8v}&kL z>>2v?P>=X_=uhyMC)}D~6CWge1U`}wpFG4dI5|PCI(WNzZK9{QA9#SFX-qiMyZJ*g z8hyhiW;CDC94*djJ_kP3ccO2UI2*0Q(yZH*3-$9HkVIUY*&9!EZ{_udKq%i9d@ zS=+Ogvb-sb^0RmAUi65swtfXJt1GJ`K6Rgf57hk%F7uUj7``wul(~@!;!b;L$moy- zAqPSnt{w#F>8Rtn?e7*HeP#4j(bq-a8SUtv&^@*LsP3hMvd%r@yv668_V)U>?|b{n zw|Bn%{M$kA^n9oPJ7eETe`o4Dr@T}9p`%f6jBgy)II?j}LHXuS9}7caOu!WO5O`YzoHa=Gqe%@vV?z7{@zdc5d2rd zKuY1DcP$oyXbU8wjq(5n@{3%XnJzd#Qte#kp$=74^0eD@q^mg4^oy;1QpC9QI4O>gH(OUyT_T15>tf7kxa zbeSTeDJMr(SH#=@jy*ZV7otA(WJ|k@|_>{CP za824(;0M!ogS}gh+hV035op&0?g=P}@~&YT7 z#NaCO;-;a#5%9^Y=#@0DomMTxtAowHX~L28BlNM&(*pYAqcVYVU{^Y~6B?%YNNAMe zyF-U5emK;t_%!H9#UBSfLGk0EQxrcPIz#a%LuV^K6DmQbZJ^#S*XnYWeF3yc@nz6T z#RtY=BD2zRXV*$_psrCb-o@s9@jLjSka~xyaftqd(JT`Cp9NmrKOcNv|K;En{da-I z0N;T2^p4@45!8q@Pa1fRXAU^qSc}R|T!juYaPyV)Ygcc+54?Tz3$o0P0}q%Xk1B~z*~~; z2X9Y$4E#jWE^vL)9`H*^Z-5(;-UYv(v=6Lp3nKkPw?%-vZR-Wrw+#Ug+m;M&CMV<` zPgxF|(M5cK$=l&M=w{eE;5po8@O)>+=Tv+Ue30UU;W_ALxCwy|QG6(TsN!AlF2%dy z<;Y#i4TBF;d^o%u$xD0IbpVr(gg5sAHnRuNr}hDs*(=bUtL)3cEA1D7SJ_vAFGo*f z=HC7{@M`-S@HO^pz}MOD0{_$g8Mw*r0}tsxoRWWb{~U0Ep@Z)>v~LmDGmcz{>kroB zrh;e0%?4-2Ed-w)cRKjYxHG|L$DIw%in|D06ZZ)CvAE~Kd*a>#zZ>@v_!C1j{3Y&J z_}>lvaENCJ^(cQ^KDp4bG1uR-g9_37nu7iW*9X5GOh`jZ>E*r({Rv#)Ds{;jq@TbA z?ov0r`zNqDvuDnn6oi+CV{gn@W=5Qj?r4r2^~ePJ!;Gkz^gU~%ZUdWp{mfk!(~Mn8 z4Shaf#j_@0cT#4*)B92S`t1N`7<*$gV^2rd)Hfw;!e?_=^VU$bNpojy)7C%X&Haz& zE?ILI0rMQjXlRe2-M$5JLoIo{cG@V#QRWi-w<643Kl?BQ(F;x5n-{$Q+M=_7wgn`YLy3iwyy@CjR_hK%OlGWEq%F>dycqzYF?|;wRGI zPgZ^Y3(!4^m-_;(y@C7St-XO`Xh}{0q(9@J;}tL0rL487XM3U-0@BUP(DxKSu^02X zfV3Zvt}sFA3xWG(w>pYPWBr_W5j5f5y2L<0FLkHBw@Ajae zC|ht)2=#x8K9AbFQom5AN7b(Z_x5CXhKY%uDYT;}d)9iUiW@vP!Qbw=16=Fb*61V|2Y0L@Z*D@8SD}V2m1!2iw~(E zdW!bU(C3FTZ$I?k;HIHIut>NxfjOUq_rM<~90oTh_=cnJjF>WlS;i5wzzK&JH=kh7 zYc4?dbo*j`-9&%i03X_r?;LvA&wbz0SAOUF0h?npYmZ!4_12S{(tCG*`OxpVkEMUP z;=^keT~nWa&AW$B=v)6n`mH}al621ASJK0l+IIBXxi@`maKyIYDgR1e)9>|@t8afh zeP7u6*FB%Vo9>Er+<_l^z<*f0q8QmFd&%Pkf%f#8Z3d;cZ`}Uv2pJW%{V~w+^}V@_(nlwtD(?;@q#& zPYs^)ZrsUVr&pBidM9+)H|ek2M6a*Jx9N{WWghw9op00M?osnw$mZ|TKTJFA`kN}h zPd}~pv%A+#_#yq4kRiqC&L7i@eoNnW+e<&DSDd@};XSJx(@zW9d-eXQKdJiK)M35# z2oEJEnLoxz{4s8GUd1d|Tu>Zk=Ix-j!6Mie%-TxupWwXE{803@sFP`17k6KbR<)%2 zQgBJH5?a0EVn);6*?Zd=8HM%^1yAWSmA-FF-)+pQoYC)0`nz-bWr4@Vj;D{g*f`xb zo@+-%OZ46$tE8}Eb#HPqijNCUJ0RLf}rCVm4hQ{AK7=eRF--{8K(z25z@+YuHX)-5a{Y--rdu!UhYVV8$p8+Jq3*04vyUI=?R z?9;HOFh_WJc(?GW;WNW84}U0pXZSne?}c9$aaF{v5w#H;BQ{0c8}Ves3lT3y%!s@- z^6ALeBlkqjj9wUhIV(Ci=bTZry8og~t@foF5a{C#&xtv5Vr)h&wCpoVZ8h zUWofR?zgz>^_NGaBxWTJN!pzBK+@w$yOUl_+MD!V(x*wcCuexCPmN3SrMfpe=J%*$2^aDmlA2wdfoJ=Ox-uY-5f^JwEbOsrTKn+MqlH( zMYHcPf7h-v>HAY+&7_@b()t@((+ry_FWYC{7*L&T{?1bwV$uJ3${gF9forb+c1bPX z)RT75K0T@Qzme#6))}J;cnPwc);ag;9l>*b>-qW{cD!T zvc}x-&C%z30?(W@Fq)GfWy-Tq5+omZt|n05ZX&IJQ|Ud{O`HJfK5(D5)XA;=|NpH{ z-jN>uf=bt8(Zd7xU3R9EpKzWTmyUGuE78Z-9E(n_(T@Q#U1VCz^i74A=ip@eenSH( z(>EQ^u@78ZmFHG##nZw+dRV_%+b075^Et zqlW=m#&ycKb#8nS|4A`CEi`MVu+Eaxx!vYs^(kp9epo~n4c z9=1gBmqPDQ{A17^ihm0FG$8dfxlZ<+vVQ@(SMlFL?eCcW4}c!8_<7Lt6#qBq2E{)K zeM|9;(BOB?cLzepDSiR8RPk$|_bC2Z=!c5`82Xvw|AO{-&-AAkw4dTfL+2RDdeR&> zJ?DImmOU&ejB!)Hpnl-iBPkbSsIcHL@IhldW!`9D-os#ytl);b=MqX#Dkym<`Bd>|c6B&PL#`vq* z7=MMU@t3^C@vO#`x>hfbmzDFRW!0*4Njs%~&kYm)9~PGv{xQ zUZw1OM%P@!JbGT&T-E%_Sk<)lZOXMxYmQg$I&N={SFU*m&heV-pXS-3z_Z=0XMN>q z=VO`mEz>JmQLk#Xf@+>uy2`^ENINU2!Csd=@JtRXs;OERtEuMPvU%3YTv`23=9$}R znoKJPYv_QiHyxfYqy6Zk+LBSw*@|BZy+rZrpmzeY9ohiB2asdKP0+21uY=wTNLlwo zA60w<^jpO{Xm6aV?Foju6dw-lq4-|VSjCTlo}l<~&wa_h! ze+4R`ZM#KKO+%k$lfbV_q1%CE_y?g60rI`ap-(725q`&4KeAl;0E zj#vBy=)FJ*_V+^{Q1)`{rpIu;273>52p~uCrB{}31%UK3aJ!S?c80b{R%epB++RHj>)ki_SvjNh6C^Sv+HBebkrM;}D zvVKZl*3D6>-W?B>AniYeexrCnJqoOk9o4~ExRdV&?yrz_(b``j>!Pe<(v7TVf%j<0 zdL`{YhFW)O$a*I0lC;l&N|5|E=%b34cN7c1cP0k?%=ilIvcy~PKY2zOSKOX-$xFNm){CWK6;M&1=v3hg=;K#r_2iJr541N*( z%HUVQdk4P-{(SJ~;4cS%3I2NU4`AnzpdqBvkPPsoA(Oz_Lvq2zLrTCe4Bayn-HP3* z8v6ooO<;EgyHnXqnQ#Q0)11THyt(srY4cL}@xJlsfD?QZS~NilL^~#Md@9fC{wL$p ziFW#RpzV3yz&&OEw~b+~`!|kde_Y@=_kXfi&KeiXy>iyLSTHwXot5rr-&{vy=fM4R z$3BiWch;GE>dbv~JA~Xdw;LR|Uv7umvHUGF89x|%l`HL)ln!%@cZK~5_`s2#(>T*> zjr8O#JmyF*!`Nl~31@w+)w1-6^ayHUw4o4lPbq^fB*^JdPr!jJSEA}nMW}n4= z2L3ko2XJHT0q}3Jzk`MDrd^3pr-jSlD~)!j#%PCXjq``XGno24RJAK+i!vLVxoS`5 z)$nUQhvM;V&=B$>W6(+9>_O(bY{dvhcOz~F-#TIk_~{WZfnOQ%CisUDKY@jDR;|gr z=g#Z!vJ>7L1h)1K9uGg>n+`VjZ=3tu53?Txxv3jc(IQj70PDtX&sAxA)7bGf(l-+O z**>Y*89TjK8#}$dTTa-5rnxnFE3J;P!}`o^XKtfaF!m)zHTR*N@T#$;Tqj=Id>+`> z>;r2)ot9%9`@_*ajMKd4E^PDc&3@xd<~P1Zp8n}O(n%X*4;>deMob9J2&JD1oduo~ zIv0GYaV~CGsGOU!&b++_|6ZuwmB{%VIX88gYnN-B*zKx^f7$h_%O+lP+1#UropVIv zM2361J6OzcpX|1aS)3_ya~@{5n;x~*shHQW;fzt(aA7k}Do!*`BwlKq3fmP{&vgdR z7^lBpRHwgQWi)G^M6wwtZzqIjFs8N6+0KGr7=CH^2yq!_lV*vA@HeqBPhyulZ;;F4qZ?%bCTkE&dKi7Hd2y@*i@a(z^>XOAp zb>G*Oh{n2~u=%a-i*1eK%WYq6vx%>_eGC3>+YjJP?A>J-1v_?a;!?-8PPcZQGa{%) zLdIug`FGza}2d{7(;Epso^4!94JaYP&z<5^=(mF7LD z9*x$(?g;{ictXKFJiR9^*`BQNj1yOT zZsr3jw{)nXNZsUtR{F?0`1Y>n0QMq2m{uq(J`OxEei(Q}`~~2P;%^5(68{nS^Z2$c z)jH$sjxcnSCk)->*};FHeF#I#C>yc_{o9lW|Y1wH}A}4JX z{F=1w;CgijjKAG8ZxS75-0nMi%kh-P6Sgd`n_#Q1TS4hMa^y?j*V;F}AK5wD==+O3 zokvuwW$s_Lb}R3rPZL_QW)o@JXz&Tzbnr=9HF$+~5%?1AQjOi6+TY->)UE=r(d0b- zb=nQ!8?~Fjw`jM5*J-arC+;+9rS}+9qQ& z#WoFohHVb~RC}3ygebQ!vpd+G`Zs%U%Z}9R>^5<|{RZ&g)xOkicKQnY`}R=rp}i6N zU+sU`?cz`SA?%OXQ<$mBcGNhCwWA*VjN^51gCp5#Q#YMi_pQ7h6(r2NQN@6p2H3=% z1De4haglM>p4MS;DezA2w7ABe)^Fl| zfIn#5UNpor+~W`<*dZP)F7t>))-#M7g0mABC)z}AVjiV(Nn$a4Nn#m%d16(fU0j@4 z1Al4a=h%Or_#^n2#EeaIR!rJd#GNfQn{EdW+?>3b^6QBYLS zL!6f+ISI%yFflNWfeWp;(u#>`%RxXOK&}cZ;3+j}b(6|U)3#HY;-$^9i`#0_z1?oM z-M`v8-L}3io85LT-TMFLof+i3c;vL~{=fbH|2;7C%slVBb9-l=nR#aBd3G*=y?kdo z?2esR!d}1gSFpQwUJLt%ox5T05hu{^-3j`=Gwz4#d1vb9%}+7y?nUvF^YaD4zNTLNwZ z{?`Gw!hL(d9eCOuaA!cEvM=CXgtbV6``NL z)~pF|+pSYzJM=Ty7vc1^NpV^$fT`C{T<^2q4fjLVBi0eh3s#RcTzSX(fz^zA3Txud z6%wjTlFF0J%HpINw6Lb6WoUVqC%p&vr%8W-{Z*2Zj1%WV7Ey9?kTQKoEn42?JGR0e zw=)H8D|Kfb>=irPV6Vb`2a~d4=QTS6mFsrixYMj`*|`gt`*8Qcq|Dh>9zk+YInf;JG7yvtWU%CrftW8F@XmXs0@i48i#fnHv;ykxG|u1V+AK4gl=S zFZ>Doc&f|J?8`5dXPu1v!oKI87|)Q&!?_%=FYmAieimonGf<3=*q3)G&p`F%9kR1f zjGxc=?u@7Ji;pPJNf~+h?A#RF=c@Y3J?(q0 z$`^l;owvFchSkZ<2T$@E882VT^ytgW_vh@@1%E{Sz_2(KoM$-~hPg8UYlM3#;2Icq z1JswSO0P3q0p2p>S=7c~oH7pSoTV`NGZV1$W5RvI^RSzef&FW<;!qYs>leFa7=*io zOcL;6@H-Bh*3l(_F9s~orM_Mj*b_KKc{K2eKvKTaC9s7Ag@U&c7Bm#L1=0uzoR7R zGJI`#gL0&gRKuS}%tnhp9^s5EH=TY5{55?CT+#U`!TODEe)gE_aBz>^F_xV}W>SGK zu{f~?;<_F(VovUcbL{{x#*EgoDN56{5G79IcPP^}@DjB1VNchxVdrWW!Jebd)lAC8 z`mM@ulTKhJ_Ps74zdl)+*oA3$(8NF`c%nKHyH^v3L0VV%#L;j^PaFf=GBFky>%<8Y zhbW2qnP>aNslaDW%z{0AVt~CTz@*>EoCfJ+4=H_j;hT1JK-=1v`YGt=+S z+868m*~;%P``)C0$MVAskWEBCfaj~rCJM!AYLgQF!&ux$v*1j%S<%3~jls$4GTeac zD@)DTI&uF6^phFZ7t#TaiunUImzp_=zR)J?LlOr&YMy6AX*T1^AM1E632IU>H6EFju$>0Ot$06L6hycLClh+!5cR2g2xa0F1DFN6{G(#r){cRUj$4&@P|`hUr<|5D9^=4la+0wKN&q+ z`Ly3zBS~qQ)Qo?W#zttizY4d<`XOw2zxi)) zhsF)V8Yvt*$7bvePsIup5LsAn~<7GGxclCPGV%u!hx72sfWCMI_v6`Q#Q6Z=Ln3@% zUO~zT+-ZSf>9Vs&?Cuof2{8TvJ9pF#_j`bSc?bcKJUrteIAGY^p78@t#Ru3AKEMHS z&genF!!YceT@N6;W5v>9e1dyM;jBO0`vK)yq=RrDf?;{V_^J+#lXh`T47i`X9Auj+zEiEy4Tg0|KN+~ zQ1QY^p2NQ*pMjsBaw<-gx*LDk@53MV@9>ASMUV)GdNchD9LfTk2m4Z51iP7*!sc@O z*61fIR-4y>?>#?oK1S$k0&j(Vd*C71hXW78emL+E*pCH1276}E&%tGw7gPlM?H~_q zF5lwgpikkp>zd$p1n&#RDGOcVMYK8wYr*%_?_p<#WMYqgR>&;a7ljnUZU||BeK3UG zH+eSXS=d~{<}6*R=E2Z|SU*0iOPkFck~swL>XJ#H)umO=(j@{P3_BQxFuL5;Swm-G z51q?9&K;IN45tN#{S5X~!=8a19Xpa{fh84a9XQ@?-L{#{tL>AUkE?D_!imAl(_BX7Fy#=q*C1sCYj z96#0d3&tLgJszNFy0#8}vdp2M59xa{#3)NJUP**x!%SVi0+)5jr7YYAPAzNk>_pLC z?C)boRF}!cWgv3t3;sz${3|u|o(y0*m4b9>4MT#4fv?v8lmM4L{+%vI`HRr{A*+ef+uE_vn%_Pv~-87kys_j$OGfMT5(v?<-4#OV8vIHTs^2 zI??w;)Jxv?$=E#&HomdD8tk41bKeHY40E%48|=;obF+IJeeY}Zy>rIyov|?N?pfbE zXFuld2D^*q&)p4ne}kpP?r_Mv8|?0yymQv~{)O@WnY@c(yniO|WfL20~y7!%8F8?^@I#24_og#F(<}-ul1z`mc zR1BNT7=J~VX#P&n`@nn{^bzdOfEYVUmX_wJTKE>@vg4Dg3Idnmc5^k z^#PZ?Umw~4_flQzKG$mTke9}aXYll0T~`IyiEzG`zJq+MEx5jeMY^VgD~4PFjJJe* zeioQ%98mPLz~_5uC&|Yugli{Rr0XT&nj;?a(hczp!tm3<@9J71xOSfNy>#*LGr~+4 z&mvtH57+S0UwaEbFFa}3B&=-GbnWP~hRuTe?qPSszE?=yKM41;x}^Pv@XN8L`Bfhs zc8L+^VjYtn!FU)M5$D6cIAT8RUqm=zFTz=4cFMRCc0)un>?FA-=$xoj*gub&1DoskzF$9ayeoPab||FoSa#MpYODpTqPe=x*pji$a4Qxw))NgN?cN9XJ-hFP{lM-6 zupip}5bRIH`QmTjes9mmdoWkl*D)9*@Y5jk?N*#MTY*zUYv^LEpMM$nEA%R+F^%a< z3&I`r*r1`o5m*<`3cfqI2hz_KHCeT*3siRNoaqR7Pu&p0bh}&!Z7xig3)AGn&a^Wv zE==>qn`r&I<`!tFU^*%yp@||B8Yr0l38sC5wg36hIl(keTn=3=2eDpex>=ZJ7N(a) z*UAD7AWZ*9By@c+O&?6p2h;Mw+WbPac&6Fo3TTnI8rmbaKwkvY7Qu8yFijDx7d(L# zH`5NmbVD%B5DN73OvCznE;R8lJv{6-cPq4^9K<@DweYvlzW>a$oj}{vH0YON8abG5 zDW+M9>6N+y8jEg%jv}U^h^^P3hn5a@^IO+Ogw~veTlkkl>%=-}n_#*oHbJArZs?Hc zL0e{$Kbgh|1zH&!pnFk)c0Q(???}X~5e1N2>x8`8F371p0LipZjTjZlB+)WCv`h*u zJ5$PbAe52YM!QEJ8?8i*jM5-A&4JeIgnoLaFPz;dXR@`G=%LZ&KXlXrhZKG7#DPGGY#8JzxG>WEMsHA2VlC8nI>eW2bpPUP%JYo1vvHX zvV3JZVVM$>0jZ<2AbpLUc{lUD%^|1+rJagv?bY zQQD5v4)xGn(F}bGY+c8+I4E)J<-Bx+#O*zM-=Qle4CWO zloTf0lPi+zlIxRKK_0I=`GSeAiC;}rQeIBc&sf`Uuy293%)m*>lO|1ia1y&Ma&*#t zvwCK|e2e1Vu$`TgKC(S=hXbb{6r5LO@{<3yGqIc96>;D!gbTca=O90oX@OV3B`Ai5 zAJ?wecfGai+}%uzJd>fi5d48R7HNZbdz~1WdXr(+9+~0Wn=bOv5G9 zZ^`5@v;B)Ru)2Ejc-G&U4h^P3gXzyuu&<|K53io-&w%D2rZGc7W!~#pz??q6WO_pXG7l& zMLeMaLt>%*Ckyvrrt4!OqY5F490z-boUc5K{+_CwALhXL)n6Nz9PbW>;kHfK6Jf#1 zGded;j&ak6I+P3aF>cn-MMFm^rReV!${&S3vPr`hi18~|=hfXk?A~Fd+}CIP;+kS4 z_iid~T{MJuU@UX>;n?*Z*PaMZj;K&3M%XbuAnFkCPelDbij+SHUf_`EiAor#2F|2JYhzlJxG`s9 z)Jqs+gMH4Jsbhkb^K?#O)Yxc@eU`BokIhhuga-9RxOr1Pwg&hn!AIOTc9L?p&PP-% zgmEysn(te{of^C%HsQSu}MAb(@tT-Dh==RmOu({955W#qqn6F(T*gx(K#w*A=k$@49~%DG%)WE!+pe zSv(u#^+b%nlXjm2d$Jh2^LK|RZ5XxF45Rj8gn4-Pr@IrC&p>5Dln?fNw1_QW2a zG+XMp>D3r4`u|nne*e$)e?C8Eyz%q(+ie$l_59VqAA}w(lXBQg#~b68zY1C~q?Z=3 z+wYm7=i{bZ)&LY?H9{W5{W!$wHA{XL_`b8`Ox%@2Y+iHale)nqjd*BCrgGTp-W<~= z^(v^w*-F4E=E^5E`AOQrw5%NrdngR~@tQH8)TSn>3DalkJ!57(|9PM+xEY6eg%x+} z{xCGRSKr}lL!pUB*8wJH%xR!6ll2+1{}hMs5j6OuIEfMExUbiL4t?^bo}@K=AA#T0 zV>9VX2cR{4m!UspNd!${GZF7uwbP4sFzrx$hMm@D4?@nf*$n&7n2)d-_7uAA{SQBFsVm=dmy9ro?MXSYe&?=^$xwBVE76O>QIJRb87F^`wK63X}QngYHL z$C*pMH{m@)z-WxsbpZ_1wdaEQ4o32&Bu|R*qvSbB#*1WW%@^%u2HFHGz;!u!$_HM9=N}OVRGS^EI1|`aViXxkI0M* z<^dSCU&my^{ShVzG=u50ONEhV>ZQIqDNoUfXG|s>yNk=t*E6|rOrD|wIx!iB$yA&R zQv}lp(+YD9jFe?5WyC3<6HFVZ3+5h}9vG%mQOb>TV!hh|!_MzBxtC0C9J_PB3Wmv} zKLYa+jJ$u(_T!m6#sZjSFfJG-f05~_`5H#SzB!Y*=z?J~7nu$WwvR6F(Ob@9qMee=V;~CSF;u;C=49pRj*I`_v_?|kG zox|jLDA@PTfhmBQ595Mid*MAWzlTvUHyHyX&)(bNX6JC-n42(J06z%R0}64BQ3(xo zJq|D)>BG2Sm`-%Xj`OK$fH|1?{RFTQ-}o}LFPJJADc|r2+@HZ5g<-Pwm1>+Rgeib& zfoX@?2&2>?-!KI*9WYY1Dh{_P0Wb>qv`k;N)RisuWJ?{{Qa`rj;mY&E?5uDj4BMk; zXMoxHUwQ7Ao%fYIS;miL`zCVFMDCZcy%Hv?ipi;B`xR`jg6&VRy$QzKWcve51}3`~ za2Jg75%$Ajo`iV?hV2Q zCO$Ocx1`N_7?sm!=4LdS>4#=#V1@wt(i6>S zH#-mG0Gtb>#|gMhxLtsZwlh4V>t71@*MN-1>*<1ikAh)t4Uo}#=9YAxxtRvm!ve2_ z;tm-zzz+wEgkfPu0iH^SDWm&sB8&@gn{cyn;7Q?T8in5%ZaE&XI2}Xyn84glxY@YC z+%7;iHZZpw515-G*qIHEUk!Mda7&u6hZ&AG2E*Kp<~IsAqy4L4*!`?EfcFUe!+?(o z_kRJt3B$e%8yAMduy`T?6NQ_N6ITj1*PX<}uLq84QDWgY0^Tg#w*YnvHyc~t67GMN zF0W}AOW1hB^sck9rUZuNfsHSB!7%q@fR76|8*|uL^IPCA2mB2T3-cP_8^X=To)j2{ zXJZf>doo#gz}*5b#~&7kjWukXc^ICD0oi!N@QTLA9OjnejgGhTF-LccaYuJo^09}x z+4%Dd80MB^j~=EPd4pl@Qb0ELFt;3k^e|!!Vs17Lv9V{L15-LcHvZrmje^Vc`Z&bG z$gzmI<#@#0a!g`wIUeY4&~<<0$g#14_207reaVhvV+m_-Y&>CO2|IUpAs~|n$M8P` z^d%RLjX5lSCI_xWgl96|*f_-AWno4y0LdJ2fPY~mG{TWc9Ua;URPqgU~V~P zFt;2x^e|%V(A{{}_qQ9GX(N>11@r_2qJ2Gznf4~rk-$uP0sME2u7O{|?yIYJiO|*i zB53l-IH=FnT#Hq#z_xDGDipyD@}OPT%_4?+0J+0bO7FA#nGH_iAT<2X7q>`2x28 zx~QeL>Bi8JN>gYvD5yVr+z(-AAQD>J-$D3qL!lX53Gzcb_%!SiSd~kM6oVV!98xj_ zdqU7WJ>oQ)r+D5GsR?@>xCfosl`ugE z_NHOM%JrwvfxQz?rS|K6c=w)R`(d-)3&cO{F}Q`s>u^W7Lzy0)8;%(Wb~7NiB76gE zC1L``uB?cHh~dgb5p&_bB;r!oB@yKjkOL60BtpfirXHB35$weA)!6&EKzSkJJGlQI zk%uwFTch74BTUKyzcl(if{>4%R->OQaw8iT>=|IU1#|c9 ze}k>uF=PkkTsy3=C+tXsy<~@b$2rQaJ3fGWBX(damE$`Dx<@Q+4*R=Z-@{gR z+jb+K-50>l**z1sb9Wu=hTY3xuh`wO8**WG-v#&GyYGYh{@uUbP0EA24*}DIy&jYD z#_l)a_U!%`_LtcA30F*~)#})@=iNO>7yCf?%Ge2FYp~<6*=`Wp0QQ5hvOR7+Zc?=4 zw&SRi!4g9HeuOI(AV(X)Oeen-cUZqjo)&9elCQO1M8b?vBvRty>lJbJlV+eCcs-@bZWK_kQv}5501J0 zTKl}@-x){7Yh&vXc0QT$+nC!ZQ@-yRWnX$R{uO7GPbFXe-|dX@f7Y11eKOwZ?J%r; z`jQ|1&st-4nqpM<%NxJTJkAwoBT4^?m)GHx2mNZytQ;#N91F z{MCRDd!>5%=hs~P(C`!9`OiGDs_RbckzXYl@T+f{JIS{2q8EQ+z~A@#9d~Zr+i-J< z0sr*+zl>`+bKA!&4fxtQt&VFheC9Vd81VC+yZ_SVBQmeJ+kl^P@$p&bZi;y1X#;-t z=DhT}k8kMuvjP9)c~_kE^xEcEA&61`$?x*@jfZc1_W3K_76bl+y%VA~ho*f#*?_wgswEn2+i_LmL#@n1ap)^*3;{pxcA{($R;-Q9QIcVFoD-sN5Y)3%zx z;zjGuGT`UfA5L@raPaq82K?Od4_>oj?ayww#DG84adv%t%eQYg8}J(sd~o2FLvQcc zXuxl3Z|;1)c-OIA2K@6|yEk4}pYz+t4EX9%;fIeMRe$-m0e}CbN#%3T+V||Y2K?St zD~~+!Zq}BOytut*w}LVfCp;Fh@coGf{EOE%Rc(on-+iG0KkN_6>M!qG_xDl*{*$r8 zuPswQIM`vpKhs%I7xK)(4O!tS=T3o-xZ|adKI(^GwD<8( zTJL0IU*F%FkWI&0r)FIq+ZPG<{!zidU-{gPJ?RE~{lbq|K6g&X#yJLjrR%@o` z%*=7EH{g^1w3i(3#~r@IfZzB-&M#87Rb1U;z)wH0VcX47sW1JP0l&-g-o4kpG3M9b z81S#Ry#3&k!#8{q&MwCH`Bner=++F=y1OPA@O^@KIk|ky5@iKuE4!8Zu-EyZ(gSI4 z4=b+#^O}&@`Y=v{JYjkPw#W27>`zU9fy|bAUH<(tYQbLP3SExrsig1Til?{h+A{t| zmt!^mOGqjOhbi!4*z*HR0##*EAd|boPNbjYi2pPQJR~n(_y<7|%AdgzSAPUY{A>M& zH#^ZDqy(spJ3dy8S3?z>>QJMV>8ItCH~fcFKIA6w(YFoxe~DB66Y#eGxt#JRaMpjc z@+X}42dVw1@yp#2Ba~Ys9*@8-G;R(A;am{oouBx>!aL`3t+^bee->iaphlv^gv2|Lz( zbo~4*Zgt#bWewzhhlT)F%o z+ABzz7-)YbAjm$+o~WE-pKQn3A?zMNa-qI^aI^guxNp^W4^H4t2KG1n+CAX=27lN0 z4Z^TL(0AX!v117^t9INB+pX^&MD4Whga&|}Oy0wKA%Xk>xc~M~+D~|XmuJ^-oRkF@S6p6h;UB% zegW4fuieJ=%{yHjdX{pi%@ue7-2!?9)Gij!1#}DO5m1{ao(rfg<9@gBdnCR{gcHy$ z;Vh2#2){O8gcHyso@+l7@k+da+9e{qc~ckx<~Zh2lK{ z-2!?9)LQs+?NSj=K(~M%0kvO<=K{I~^a!XGi{}Em1@uU~OvlN?xrN^&@vY*031v6| zJpyVaBAkG35#BBQ9s#vQBAkG30X+h0rQ*4OT0Zx?h2JCbWg?t_ZUH?4YUTX7M|>}B zwg@kvN9IrZ<#X|#TR^8s-y{6mViAvkZUMCdffvvt@f89upj$wX^o#IXr3fdWTR@M1 zS`~lp7Wr`szel|9mVN=Xi$r_^YRkD_yG-B(bPMPaP^%Wt1#}DO5m2iU&joZ#zlh&0 zphu>+LWCF4Eucq0Z6$y15#{oT__SK_o_OvS&?)e4Q7(@x-_J#O0o@{;M}`-8kAT`7 z9$s4_(iib-Z6Y3lcMGV^5_s|4Bk^?tFXD3wzgs|$fLgr>C!kw|_sDz{^5ig3d36n?kx zyXEsj9?mVGM?j~jPmheRL&PVbTR@M1+A8r}K(~M%0SiKg>nrPEv5JnqYK-m=6@Cfj zB0En!XZmT`PeSg4&Ux`1;-~eWg!1|3P9DEZPeS>8$2$I8vO^@4&yR`snGQqtlaTvx zR#?2x&h4?Egxsen+XsmMUh!PA8zhwPtD<}|T?ys$BLk$rTRfNS4+-V_uMP0NZGi97 zH9-A#i}+=|N+{De!d5Y#k@$V$eOWIO%IA(w-rg(%A)$QUb0vSy&NH*0gxm*v3;+HT z1VTdjymAA7&dv?9pM>0pqdeE~=Q3Ui<@27y{JG@IN+_Rezv0g>6bK3Bb7v^e|0{wI zDWQDs7|owwES^g!pDP>r^JxMhp?vPVm8UP;m4x!S<8uDK>^Bn1=dLyUxvUon<@25a z-gmD){rj4WKbPNKLK(jiZdUoc*e#$doxkrC_0tP&9KTaUAYqUpLTv;O_Zxwi(DNa$ zw{rzvLc{Bd<5?bVx_BU=^Hq*d5_k!XaUCSY*% zd;V*ljx3ji4uO~DkR{p+hFA|n$FxT)Z!#_8G@d5qJrW`FH%t z?`N#PV}qpsikM%^cqJ6s9vIBvd_ZGBmnfI4ZwZaz6d&)mig8)yM?&NKj@`VT+5I&3 zlTiC3$B*M^MMB~21wB8q{(E1P4j=jN@zMU|YZ7+;$oYqSPeRql_uK4e{rReYkDvMP z9%TM|#5_%oFA~b~4Fp|c{UqC$gaf_T``pL(Q?BRjN5&^%?|Z@#;iLYI;e7cI46^>B z2bum;gG}F7`+04U?N8ar>tE7K3H#NfkMF1X`MyJhlk*b^`=#Rp;T~lBbG^>XxlqI} zVGr?n-3)=3&^W*C8D#ptzMry<=S$Xyg#D_)NBz5ejGxB$dwk3vjp2OyeWd@9pY6{% z$nWo~{#<^p|9riF%+LJ$dSCq||9*1Zl+aj@+I>8nCLTy=4Cl-55bZ?H3nlaw-iVJD z`IP-zLSs0eejnf8=4bhR)t~1cUN20SC;LgreJ5@A{XATpKuPHEbNtZm;P1O18{=QrvNN5P<)9V;4|HnuD z_4rBueDzJ?O#N{Tm9@mzVh$%v;Fvbzti9J1^-I&4J9w^Jal6(gV`xV1S{-gbTKkr}Ef1HD@KR^4QO_Wo%PYL_glMh7tAm7g$t{X?ZXf5jd<5@@E*fO}duovN z=kUS*>6cL-2=^e{pRezyh;v19JdvDHr@vf8E1~mIjvp)V5*pX1 zt~+@+dG1ES9v|bMG5^YD{=SS?Lhn+Z^cm~lCFZH}+@*vk-|%)B`@u(pY(JHQZ2vtz zzF&`@^Y8jWrmu)|dXm2y#I|TiZ`#usH!%4rf{kvc0 z_52eNK*An{e;0?qOK8l$D)w(=yb?M@zn1+~LJ?gr(C*>s#|Vssy#Wjk`F$kX^&{s` z{qiBsAIWp$63Y0EupfOF=cHu35*pw0<##{C%bz3yNa*}6$II_2p)vj*ANwE9yZHOE zJQ5neU(eG#T$V^*Lib}FFVEvjXygOBeC(h0_}TxWeY78&z{~tf*smVN{mujqs2!-EQG}fyz+&}8i`vC&K@e2|W ze01E~4=o(}b2+|srEHg8b^6=7MZ>Y~A5ueOYp1~jSH}CeNiS{G& z*L}h}KhBBX`B4n{YyF0Ym-TNK=}G@b$Go3A4f*{@lt+d)mZ!iFpTpo+MS0}=PD6We zi}J|ltwz5gf5z`)EZ_h3?`14sKYuX4UwI^mL!0m)6aEO{_XvNq@P8!yn(!YLepUEi z6aIeb{fiNrxF;GdV3){8r-1b$f0Y6nvlA`CMF?mUP!n)pAg`xx0o?*_7EsIN{YUOA zd2;!EjRJ>vzj|Nb^923q9WMmlIg^K%=Nmp1_%4B$eCwkE?^?shLAmbxTHt#Gez+*; zF@bj*@F!$=5x>m8k|*TO81DI-1-{^CJfCtNs0zG8&{;{B!UX<^)4Lub1l}X?vb-Y& zKBB}s{%C>MYQ5u$5qMCl91%~m)A^h@t*hKkde!9)x`Q5B~`;X4zemOqW zhjG8Guhs}}f7eLvm+`lX@l=-AW$-&{c=+D-W$b_k|31;~WPEnf-emqfB0uu`_N?Xo zK+gXPF7r;WD}(!G{WuNdoAUwh`DCSNPcnTii@z_^ci+mx%X4tr`TV(DH+zI%w(BDz zed+g9dgn*$=JCn-ZOnczAiQ zvZsOjC7%&WHTA0Q<(qEwey)k>OZ%LN3OFazDL9(^DE=oC*qOqR<<|yQJ$Z8k#UIB)PEj< z*92aI9z%X)c*T(aUi{rWetAw(rt1>n<#&P=U-ELv_$A&c!pnQlGM^ri|6aUE-zCELmP_C@k_g}d_lHvCWyrjbt?-F=P-(|j(1RjqO-y_0HdMv|t3B06>vK$d29wYvU z2ruc34DS|rNjGHqG!c&x?-AkU_#wkPX7P3_>7m5;2!4m`KeC>BM0g|KDe!W4pri3B06l67RW_$0PYY^1CT_ zof_}@4aduS^1a~&UhcEW@2QD+jCi*QFX>5dc!8I6Kz@IRh{uTU5#c3$mf@WOFX@cL z_lWXJ`Y+pyM}#-xwa<8YH9>{Mm-^PJy2w z@UkCh(|G(6FCO;;?hU-0vK>3#;C|U2-G!Vk$?wr4=1aZdgkH$2-zmzciI(BMfxj>F?@Z$5m(M+h_R%B!vV6)1 z-sN%K&;63lc&_q}zvoTw@D7oG`F))Rzb4|B?V-oee%&HInIC5s&wq+2pVQDD-S>K@ z-!;ek`zoToWqv&IJU&TBJgMIG;}GSQ^xyMeJbsy9&->gj>9pfE?w8-w{T27i`gWhk z7_qn0H^oa7w@9h%(SH`dGAHZo2id=zwLCsahn?bk$#F;#`IF&GR&r_8@=t#^Jj(Z6JTZt+~! zuOiAL>+6Vt{yAs!_+)t%5uck0vv3AmiYh^skNR&vORpy_Um>8#vUi=dfTihmM;B{3VA+R&nTA zE&MGU%6$I^{-*~1Qv?6}8Yq69X#%_-!%ING59UzVIwvMTNtxSJ-q@6KS$SjQ@|2%c z)s#1-G?v%bHKjB)*HkU3PHAc^O{u6$DXlF7Cb??K;<}XDlBy*WE9zJ#QlP1~YFYWBr32S>S^46o;qe z{?H;^F-w2Iw5t}El$H+|s%CLhvp?+y9jLmvsl2viz!+=M6zfU{4z{SIv9ZdJE>*jz zs@b2)sVyxjtsJ<(wWZ}tnj1?7?tZo9wW2W&T$aUEOZSmNX9B z<7+EQn_9}t2X0*m*iz?Dgp4o^Tqk}JhT5j86@Gj(w9)3Kfs<@%u12dGFx-;z=K4B6 z2(SoOT-~s=eCfcstZSO&Z-c2XSyDCd7p`x_pfg};P|pKLg&}X?0*G;Oz!XKeN&W^L zm`*m8*OZqITvWg4Pg7L|I^(3`rAz!67I@%ueoSCKGz~oB@TmQ55niGF9R0*Q{uWek zbbgoAzc$}gQ{~4XE{j@j?EVb z4%Fz+h>O9ewA`<`T1#V9b9pgly&~nzlBLac73E9H8%vtY%g!HQa@$lZno-l~1C}ja zyx6~x7!gZr8vPDiTeqy-zrc;ncJF!L09j^V&1;_MBmCmp=9I;CjkP7dNec^ddOFKO zG?kuaGRy*$_0r(1EWNt>E?IKn0lDSHFb4pv`w|AkE-M}M5S*$`ntqNdjkb4ty{8;)sF8q zkqlH;URs5@vd>(}a9ER|2&ZYnGT`FoI^VN%8K}yiKn+Xlntj)*j0&Z!8Zh?=%!^pM#-LR@Hd=0g{F3?dttG z3wW$&(Ps{2fB{ok3^vE{A7cX6Mnn}6{ z$cp4MuZ<$mvXYwKwaAakMj6(C4iGTBDi0rUm@P| zp85IW@yaAta5~{NTjcNf_4#Eqi|QBqRRL_8;cIdrz9MTEUfJ;xzI+MBMl6U@D$84$ z@%f>2UiJXfTs_Qb7cqJW6!-K^Q4h7EZb>=gvY$RjGE{M6d5P~9>lI<&wEg@%pb&CO zIuO-bw7gm0IVdSR4cCzeT7)&xX#%0W>hl(?FtHgSssRcGP5Z_v`q3i_4*1CaThm7Y zVWyj5UI_>#T1Oq(S6o0Hs{u(ZrUrGMsViWJ*+f%JM*{+875#xItG_iNt4O1cM=3P5 z>x?uvQ37?`PAfj7uglausB z3e{26a2E|P<;WP0EdsXwE}Ax*f-2OJw${ojH7u4oEG5()>7)*;lY*>jSRsD2(n<{p zW}-LSt7F<~P`a2mC)ZF|X-rL9joD1gXPN_Pq8gQHC#uV&A$95zM?nq^y)JXZG^(3N zZBv}FH0F6b1!Zd#wIIgs+>834Ahph(nHg8BE~G{)MNFx*=NA$cQ{VzJ-=b0YP8v3I z5@`t({&-nMUAFk zth5)7+0?!;T|;W`Q{YOx5*>|FQN1-TnubPEo0ZHr(qb#sCD6H3)U;Xb!%@?uw7d^a zB!%RZ8j3Rf%|)mZ-V(j#5YWtctY9k7-R-JMGan3QRQJ77(UhnEy<2ntCCn zy-gQbsk)dNQ&5TYvXWwtCyF|doJOSPE~i;mdtB091iflua=jYQk}#)EDof5$ud+uY zVbj`xunDLJ)9r|~k!TfCPoY*TeXcA}N4hB(Z8rew8+RtH zOf(16k(G%>>P=>qLNj7&;%X?+iVxS6M`R`1Xs0GCjn0U1#^F)iK~lNX6{i*KqmC(L zuAtyKojKdcoao%-IGPMYEr~RA&e`Z+@iFAIr+#M zHLRvU%P1P1t&Yr3cC;me{qu$Jy!8S~4|8(YRu&O`K%f8W2{fF3pQBoR%*h zRL`UFbyQ$AhtL-tS#3lq1zXUW4v<-`pzzhr@1Pq5rqGJiN^T)N>PQ-vMe237v{^@K?8fe&lDX9GAS%5k$*C?Ta|){A z06O?AwEWI=N3z|C5GiS}15KHS7{zWi!BsaO~dBd z?`@?zD@CSOW+Lv2HI8QFCp3l38JlV3l+83O0dX!(iO-uG&9d1vhw9cNCgH80L-p%v zWd@zUAf}s!SxJ4-mX>^!hHpfVrbJ#uGS7C|mQ!0b1*cFTD`)j|l+$*1t6tK}^pak7 zvZR|k<4=|}?al%_THKAjrEFJAi(<#?1w|p}B~ViawPZB9enO=wba_B=7n!pck~x7a zx5W1;?`0NJ7ofS{?na_H7ov*j7Z&S9^?VAPr`aZ>Cvv+ehxJ`^YFoVB z7GGHtTR38D(FlCu!Xn*WIbv)Z`?$lVv`5=!*lilA2ZTACdDJnJHO`Jz zXbKllJ9~C(N_N}xeg_dFPo6RU^M=o8Q zjSdsO0o?}?6_NS6dutKhrX-5UW|V^xXHb*rcEr<>Fdkoy+7d9b(2&{Gkb#bF9zyT5 z*Hz|Ba%Og-DlnQ%*Qh0zT2swobZ@}CO!H8Byu)(z{hVvmPfcqA!qDt36j)4cO&74& zhf(-~Sx3v#Ytu|ChR#qIJ!QHwAk?-@!}$D)x>@&7GZK!hp4F-ToQBWoR`b#*>_%z? zegBF=)jBp31*xT^s_U3DRK=ii3v;PJqIz{Y3Jtn3u$GOIf8zN`Z6~W&2bjaeMaq| zrP=1;6g+Rc{d%HovX4tEu+h&_l_oP{Mk;#2RnkP()|0r($awT)jWc(4#>h(qS9r$7So{4fT7RC=8QnI znE}$KVlJeHlRC39|AmDwuyVE+Q%4I8%kHAUofKG&0bw6evM z3S9~MfLQmsVx#NRUG*qUI>ybcq}wPWrP)S}>xyC*+Q&SzEjH6WhMH0}T85Dev@U^` zuA_6a`$W*1-rWE7tzNI^_I-UTO{oUiXQ}tN%F>;!UTHg#cEu+9n6J09bQkn_v7>^L z7j)ZbD5~R{Y555MFl-%}`1y?tu)*Litl zUSH6>EsmLkZ(=}5aa@x}O^HRZXeqEzT`dU?%3n>XR%)9~#Zef8$5U`Z19c=8L?a`O z>H->JE%@R-AnXh=;Ym8Q3X?UxQYv@S*P#BQPNz9G?~RR5Kh!KMG%}@`f)WZF>M;S@ zrp2=TU`{A>UhmQKQ6~rb`WEVTAYMThN~^)#Ekl7rKyJ2qqL7H zR&{F5m`(QSq-`x|U06WviG?Gm*g{$bIZ<^9HL;{7umTQOXRkpp%%m{{=-B`btQkQ| z6Oi{Q%`|j9qf$dFU^9YWZlRUM)LeXwB0k5Yk?Jt)7vsBZrXY|#E9-6{37aROOVYZ4 zd2Q)y?P`2F3ZI%DUA7^4YTnv46qtdwT{!|1xXM_)$czfameybnpie*XO>a+cXOWpf zAR=k#g6;zc@E9Z1arx(<_5 z%C%pUWG8c!YOAL(wFwa=_ znK}Cq>xLk=(YdF5YuBpT^n!Al_lk2bWV7q}m|*9!y21Z70dtBD#*MX|=%_hWPK-0wd}m=!^i*nFO~Kh}OnW|v9IEN@ z)|qTJkG@K@dO8iYBrRm4>JUaDTG8-m9Mx>~)VJm}gIGneLbX|FsfAXoqela+vy9Aj znfYm#VpM(06p%iPg0>dK&r-v>K>cH~3vw_!SeS0N=co%!PXvV7sO57SGdq3l(e2Kp zOKIiI@t6nIqK~e^#Dm&E0B7f<&oXT>4P_IBCDxy^2|#srdI{!=EM-fD8sAC5Ef@zV zxB@n7=9Lz@OrKS}uT&Rps$t(GXaNPkQJF?V_Mn&A$UJXT+GI9_MP*R%lSP@EF0a%m zWDnlYtYuHCB57=PTc+(-)L}Y~V?vMbzbJw&C_PdR~dF)TXjn-*mA_ z8Le1AVRI_&ahff2#^g;l+oZ|1!dkpG7eg5J(xU|;R%&nT8SjHCQn~TL#A9csfSjgqapqj zbdeqBJ;IOYRNW7(WR-KaVU13i`7YBB&DvT zF^Ky;b(_t$aE)y$4Z)Cssa(Pu)SNjroq|_iRbN<{Q#iH8^dTD|>Y57)&3uBGOg)M&A7yU=tfAnac1Siok$ph6`HRGUEb zq$9uRKp_puV4o_;0=B>&5EM-0#?xm?9b+EUVM&T=r@E;VY_E3$2%VJ)m!DEjj33qX3#ew~rq zu?cqV1(XGJ>1BA2vnk-pytTG`3W{2KEOYG|bvv8D*Cf!`ikgx6V`$}83dt?%pum}3 z@NQSDsC5tcTSYr4sI=%2tiOxOKq@dtPQ}s@tEeOzmXePJ7>4{OK@+JqGM(zP=wW3_ zk^OZnU~)mAQC;Z`d1Vbb6vV1}=gr$eja?M_yS#ig0*m;WH8s~$O|BY|mOpE4GMgtZ zuRA+`1~q_iq)?6398Iq;Pi@OLZDidxg^i%d^N8vgEEifRXn&6VD8B6pib%+b&aBOh zqoCC}tXosXdnK{q*2pCkn;3I%=Ii-!WmuK)5h=K|@?ho%AjAg)0t%zYY{H<8 zsTjt?j2a@-Qvm_ZcrliOF@Eff*2ctNs?ks@S{_#AZ!*T!8SmN6W9X%hl@zqGwXza* zZB=tXpTV1IvC#OL`%vR*k-Y&qTFbINa<&?QhEj(qQ^I=dvy(JtKZ9W(( zPg5c?bYEK}sq;qWfpSyOdJ24+0_Sblb2TJ;+b~98f}h5;EofXp(pmAK3EB)=T1+G6 zfyxD~qTqFH>7B7emM;C3u?cxK*JLKsaK?thm{?sk3H7HI6n&Jwi&j2O!B{OMBI#~Z z7LtCgJrdkMT9iO(Eq2@50@L#WVX#-j&Wy8#ZllC&6dWV zfnO7nU5QGYtaVaQBKi&MJ62{2U~E*Dg<0fQ%CSC7%Ohc|hhXleNHmz)(V0a_X=v6X z8UHHKnxqbAGc@z;=xIesIhan4M59VV2sJU9%BRrCahYliYA=PVBQw!{8BKi|DA-a+BT~{S@D?l%&mj68n698~ac63%k#(qoGj3&krf^GA zQf3lfVH3`vc{!NC&ZILFlQ4;*A*Go%Or%&9kecd9a>m049?Q6*eGUrD8VTN9Cf1&m zF%4vPvifE{J`AfRnnGb1#b??w>8LUX^>8n~0oJTqbaawEnngG?B{Ln3DHm&r#4>tB zX`)+JMbgGq3DMCplz?|r@GfP6mkPdjU{-u9S)(N8!UT%I)WSkzENoUl3GuCCD8d42 z0Ay=){06W}SidGq44a#Q5bs-Mp&>KV?b9${&5Z_~O`_)%3+-NIeVyh z%LcukGSGp>mBrh7z0v8t&iKN!(2=8-vm9Z>0P)0}joV0+JAlEXiUdqU7IZhOn~K!* zwzbs$!1(cCqhwQD76s?()Fx^q1xLomqk=H;9FZCmZM$^x+0j%M6_3y3KrQCr5%>px z3$VsJ94uVBg+`@P!#McZGrTq=bp~zfh(uLEqXHrFNoHmc>%`Z$@n}`Y4KW2njYUsD>?zj@!-_7G#ZnjZHi_YjA2Q&jiXVC zX`MCTtwhm-0oJjIKE8lITNX)`2^19t;u{@3D}D`YVnO5bH$_u$6#I_gB4PU2m=JGA zp;%-uDUtD$Thrc0*340k)@VS`KQ*P`O?){z|(2Od#OoOvvLwsa1fN@f10{I;ZDqOavqdn&C!doC>k-L$h|A~K zTE>Ix$y}SRR<3;v>&{fn1zV@Er7Y&dmIZB@T_D+Q>q*T@O2Q{QmwnidY_o-KSXEqO ztM6o!%SzTKgXdN4t*QrAT&TJ>@2#iF)y{ZrZGQZG_q4dF>g)Lp`E>89-1E+(Ak6M^ zDH7~Q4Dnm`Ix%GAQb`?I(P~pBQbz_2&0w1sV?Y7wiZW+7w^3jd==;QpY?WM@0eYxV>^Y#xisTEvP@~iqHc9g8D
    `XX2A!`W~2=zr|+9oS-sy{CIN=^>oaRIpLUrQmvZ5feki85@Tv=rWJk4XtQ}{ zQIZ;#G=t6GhbC6msA1`A)7bcAK7+#NRpx^o``Y;EylwWfni@bu)6@(jo9%Q>XJ@aKOL2@5si}SUhcJ@g<+X%~!z_)GK zgrNlRHW)uSF)Js()0t1Rt(1aSJ0ihIXvXl(R`1B_3JfopU4e5oY#y`2ENdBup(>lc zRc3DjX-&>g&$|ZGL-oTV%y_S#pO1P%>dh0VO}&xSIYf7{F(Oc1kd%IQxgC_#)dBv%&dJ#C)s(9FGdjKf184!sr)X2WG)VAP*R-K(X*ivD*Zi zm5oh}q0D98NEce^D+e|EiUbSqU+E~vf62BB%Qk;rpDDAI}xme+%{Vhei(8qO)IdX$fgi=P9+7- zsj)Ysl$fTwNu8n|!c@=n4OYM)2Vk3l*$%P<`Wb|Y2zX-)=nu%@aI1qtz@$#VNHUIs z60k&K8;YanHDh$9{mEz(caizMW{gJ^)PlZjyD&3Gy)cPF6HT9i4c(B)mMoY|v#*dy z6;`TTfTGW?%)_iNJq};?$wEh2(x^3T(`_jBK&>hYkEso~dSLd%&a6zwngTP)Yzo9y zOg3AMzZOgNCX0|H^BmRw;e6U$#yQS*_ngG*R=dr%9kUNIXR(5#y#!io zSuPN}wT9K^X9{w4U5#y8&Wz43dwNk91#hH~7VHGKOe(qtblqBunL^#BuDnfqw_^gz z{xLq2rC@xtvkaeP+xY0E$T8Rw*fbBEnYXqu&U9-)*g3B;21=&sHvwVsTTFk(0s`yc z;60m7AG5W@g7_`8-1HXuSlAxZQ>HM-7IXkiQ)Xg4k0CCRO$V@7jQqjDrv__QC7|@k zY{l0w4%Y!%UV*7M`@G1H6@1=`X*t_4H)ES^QQ&(RAJ?<_%+2@^bu+dXsvn`B zA=6;B+ydIQv7jss+ls5Z=9+qtt-w_jcvmx~o~m^lW<;rIx>hU&6DZ3HhEjYptC|&7 zOjDcK(hwA|IU_TkLN=n4Po#Emw(3|Xs7@eE%en%x+SKUDt&{U7Q%mY4;B$cf<-EdH z(QJB+9oKo4taYR}Ov5*UBQ7m%hTdeHsLi-CbdYSe@WrIHczU6_jh&eYn#TelcRAyu zLAgfd)6m(b_OPNE1*XrDeJt{FW}ILPZc511;^m zypPO9EyPcsl&{*-k&T)8nMn=#8Y|Y~)co}H|3lu}$HiTr`QFT21AIeBNMs_DFv$#M z!c1f$gG`o58JCGn3YJO1g)EZ=%S2Enh6p4i5Eve8$Occa!4q7`F|FyEwrLZOx~6No z+HJb(Hf__IZta?G-L2i)qdnR-J$1M4)^ohy*N2fueDqy~+1i^)J{kESmtsJ>F_6li9d+5=pa)RUNo%8fAwHCrNaEydZE zOs&!DnCLs=h{W6D*y2ioD(LpkUKZEz)qNS>$tt&WTL$_Lzm)ahnoy!MFG4R!owhlA zZhK;lqzj>dNi?7bVgpdHgV0cfk>kFI?Dz-z76(!e;%WFsEZzpi&E?Az zp7m1OBbz-PpAg4`5YsBisIK>%15#2aw|m6ZrW|Vv^b&&0+)n!C)vO-LIU0_XGz6OA zx0A}3idw|^S$d{C9B`Gnv55N38`sPAP4dU(WA@Q}$vaI=k43J>+AOVyB&aYKy4q8~ zQ#8LqwFYd7J8IN)txA&|N|i|Nmzz<3?+@R->F`x1Dc%}BCN=OvbuCGI>2D%k+ z&dyn66Hl@MhC?fMo`?o~w_wWODfc2v=0Hh*g$PTx-mJ6zPbZ4Kx9e15J)gBzCwmk9 z{k__Y*K}dcs)d_)?wRBnwYN5G1pgWpkH44QzO|G0^uk1%0l-{=b+V|40wO%FQ}5kY zEHyjNMkA^aXY4O3Rq2yOPtif~``oSQD6K%+6~4;o7Up+_hZXdEg$CblJO04fO2qk2o z1+=AH=ls8C)qT$8UW-5#TzQ3OtNNEyy&?{PHYC|YgMsVd0pAbDBeJyVC(>VDGAzI- z*=_eTm+c?3=YzL-lsq1U+^VomJ104qxE&Ned{VXH?Ks=Gq1sgeIIVw@xYMm?0 z!!~i1hWi71H|adeZfl+j3|7i^>VV+w*#`0{BegSH(QjvUW}=dP;Ku&X#V8~x%S&Z< z7maV8YL=blI_)YkuLf&lpY%B8GH@|cF%HD>;T zn<_lKaV`DU^b*kM)D*rSvb##0bVS9cOuyW2iWKf2@dH@gJzmQae8*NOd)w7%rnWDA zW#(d9!^$NlTV^Y)4Sz&dVc4KqeT96h?Uv{?aV8T zgpC(^(@8A%4+OFJ+=}!KKpwh_!a~25b|pi*EV!?LR`rC=Fv zn+%MRryoekqDGf`_2d)=U2~XQloO%o?JidG=`N4SpA^aU)pJs2j!5nkvS?2OLg{LA z2w*VPUIrQ`%l$wkjt82%OX$;2NhjQ)3u`KbqQd?eTmF6cayjLrIz?nJ0FyuTMd|kF z8CIuG+;7>c)7w;vkPMm8)5e5}RQ)*k|qe1J;~VoB3~cm+ah8=Ja6! zleWM&du33u*<`%;)EYH`nb))TS7=87I1(+ zO1;WKzz)MO6m*C>S+^5w4+;r7YA13#J|)|Fq3Oou4*Fc7s5{_Bk$oZ3{9Lo-z8ay+ zUX0=@kou6ME8xu&s=a~g4Ao7h12_oKYr}LNCQsbzkfEsDceC1*8vILTH1$ZO`Y~OD zsVO$lKN;l-;^?EOeHP|%Z9BA}`BX}rXZhBP7enqz-;Xc8-0F6p zTfN?WBKi;FP-eXc%h0~6JLzRyCd$it*OW~vtZ=vX1c%U(+G>D?dnY4vo9A#FgqmaT ztW&m=G=Ctuo#BS-RZh>8J}aX|QoyS0$%KN4Xmg2M)&zDXkZC2S>f{CYiSEyP?{uzv z$vr#^sH7YL!5O%ur$(-;Z}9ehT_3rmei994T{AU1sv;&Aj{0vXL+?$>veUTjA&vUA z^`XK3lMD$DDQ8S1f<3IibJ%k8KcR+Xcd{)Nlu*<^P z@x(w{@HMEli3{a`vYqF$diq1pNv2D3tNKIVwl*MSqYW%}XZ&QaED(ckj(iz>UD8!j z+?DQkM$BiB;7#kn2FBAqX0yMF3ckOLr|n!JE4p-|B0_66PO@jluCy*=FP zje$OZwPoXX={SOIXwRU+F&U-haJrlxm3kbWG5U6g_U~{pu3S`|Nmq!Vc$mAMn(x5e zHavCJJ@0xN%e=!*mhs$t@ZI||>RL1Aw}1TV&CA;KPVeB%ySH7JTyveeNWOPP$YhOiZb(k+m`a<; z4{fFrKyEDIW&U1+1Up^@Ue$B-gO;xe*qL@;pfTMWEm=4X@FpWiWqG|-V(W3j|7L4C{#IPF``#Z`a`)kUGf!o5sZ_C|}7Yi`m}t;bX8Cb_dt zX?0cGly_~qSy+15NkF&JzVaK>t;twJ!_7>*^$H>Z;4E*~rMRLgneZkQS;=jii(w0h3UsA0QtbW)`7G^ zX^?K7`@Fp=JsCrZtbi^dr-yu1t17{FsYT2=TBD)UB+QzWC3{`bD zpZF{E@?ifzfuSN2)goC1f5tS8nNOl=>Vk*(--bVUKdZ&xol^DV14V(2z!pmH+heufGE6U}tkZzkGG!^gR6C23uZ|FTZA#=9mruUr z!a$g*DwB4WV~iva$4Ny z*DyR7@TJzxKvnO60?cG^Bv{%KiJy@1htOW9nT4xVxxh*p>FDl;G1jW~zP8Pc@S0tk zX36yHGnX`OLk_FMvo{lJP&bYG6cHNB{0KwLgaY(FFymTe{2O`FCOJ1zE3aqmoQnlF z`5KZ9<{12~{vsomFh7xDW<`bUpOAqEdJ`ZIcJfNC# z#$RT-*Svuw0bTWrw=Nk?WU>2OBM)`Vr4U@uM|2-E@<#L8MVSGSk_iqr0|lI$4q| zNr#U|&E{rvCPOh#N40Pkta%W>ufqG3E@eD=_hMM0^TPed&7898a)kSg{jAM~1qm^H z4|Bw?fKaA$PzS)@w#}MA+4T$Gh4t=G2(B5DT+i`~A>Svqh0L-U2$dy(gqt!E0OI3u zmOW!JQjCg}4)xDZVS+u-&>BCOWb@)!u|w9pM!rqUKcItc=H+PU)UQ@_fklgm#0^*V3EWz-()w%=UJXN zssI26l_~^@KdsdpIU>QD3=0e3$Ob5zC~3xepZ$#l53ATB*+(d7lXhUyd@BBBF zl$O^+?qNX1B3NHcaSW+YMTrasuPR4Sem&BcjK!Oqx5st(^2(F3=I9m~VYBXOALf_r zQ4OG)WWHtmN!2%(_9f?a0XRC}`v&}afJ4Vr{xKDIQx7#{2= z0{=p<&qW*YUBV7-HtB39=> z*D-K3ns29+XhRCJJzp$&Ar>Ftmm}|fvgzFdeouQAsRilhH#$F{B=4iuDIK)k)v7T| z*E2Yj)FqKZ>19QiA_J4(i##IxS~y~1Nh{i!eU6&+bhI@(aOUZg&CO=Hic~2sNUbSj z%AuhY)+CMFD#M?Io~m31(e@vYc5gSn=%kVrgbYh?;d9)6%x0tZp1sXXlZON6Okgl^ zkdDPQR>vMe*;*?0PXZ+6cLkCI@BW731IME~nxEENy5FNB7^B7u(KM8bP(YqPb*g`_ z2`hOjUa zO*6}2ac1bal7>`s+za-fJ&O9CO6e7jJxZ5xzSxZhj(bX7I%=8AT0-d<@K4{=857#j zI*fZYCL#Xi<|2qPZ0b$p`eVI1`O;R!e>r zf?5LHlVyXU{wWT}H_9I!kR??h6wJp1Ue)gQW4wSr!4sERR*Sm|I1|`I4U}*ZYnxc zlHS}p<1+DRXjc$yFsv8>BZ`tSnlH!=_(4lbC0biS~57|DJ3wK3XIY?d>fdY2!D z(;kXfrYqC&P;5K4sST~+NO;%Yh$|F#$6Akd%f2JBqMC?V?lAs=G)~FfK2Z2Urg&O6 z@ATlt+2+QuQ4tKUXRUO01eN;JYw5~Xl;asNc}LZj)<6jW0a9x%v7KtE8TBMOZk5{! zM6Hpk+Ues1De8>+YOaK3{27=AGE&?)y8#G*tgNOvy0p=g(a^T5jYhJ(+SqCO3zyjX zR7myZq4MjlHW@a)(AIvx7YnGi8cmFD!e;VMS#5M_`&%WcR6MdPrP72#W$nOS-J4Tq zln_eoH$O30l0KpIe_uVGveqS-vZjcTfBqjv^eZNFe z6+q@|v69AbrA8QDVQWMImSH0=PWb}b+c^O92wr)G=Wiw)2@t6fu{ozUJ(-CUZ+$R= z@cHY(l9aN47)8;}bY;iE=7Uh&zEo@K>~KR^JuT~*y&WC&Lz(o|h}V*1)2V1E3K8|6 zv=)m0!eGF;Ze6k@N_^L|NG{Q4B4~i9I*Vm}laiS1pHG2Rc+BNwNh%W6jx8}WbTITK zlF~CTq>?4^lvWbfn{K!G6ttnbY1@SoJWXKJEor9HFK-D|-gtJnH!>d|=bA&cY?O9I6Q`W;RM4e}?u1jw|6A8rw+vY?L z`It|&D$y+IVyh1YsY*EvfMs`~LMUi0(`!_8tgKD53L{YT>Jufc3E13Orc5Mt4j?

    9m%J%eTr7*f=4=gmA<>T~9?%~!i&;@U#&LO4-PR;7TGntteaE3bh zNQL|XzO$`Jty9{4P+jb8f1d@auh3UcXPQYX&&>a#yZ2ly=8o>*sy54jPguaJzI1CO zJ}`A9WxBUxze8;8k!6j^Xvuyt;Gl0OI!%s1st`56)8UAKa@SbMaX6=?HG_KS-oiI>qt? z6tat%VHvi|nlKw|PN!yPb}>7U1Q(%XZAqC1r9k~mXpUk7foM3p+?B2I$Q+YtXK(Mz ztq~k8rqlxioctgGj!+?RxeAz>8$xjiFKSpH2C6etdE0xY1h$J$t$FNd< zABp@xuoW1i8gB*9W_6QwbizQ?1)`?^LqIx$p-Eb{x5}ae!DL8c9(g9KiSjGrn8+Me z=HD)5GRRZ_A)B|!K$W^!Im;ulh8S$>a44XI*IFeNHR)97(#$R<<^~m`0qd5xq&G7j zA?BAk!0~N6yxSmSeV$3Wg4jyAkky!;@;2WS@4%!D0|(Gr(cCYBB}#>>CSA4$g8z9Jbmn26S)_A)3{Jlkv)J@ecF__1@ZF%=%|8jF6r~N#?YQ z9sZW|Z#_!wKvy5d`gtY`#js;LVc^}X7vw!p{mcw1no)?aobz>FM6xGi$Sw}kbh1H~ zA$i;A8N|AJSyXs)WrtZE;|6-Y>E^Q_LAcf(yq8q~DvxWmX;O#6-5wO_ElJd$c}ja- z*UJu^1ob-u&nVC<}{pUD0JQqm?0_NnDJ(C9}|J{zk z;e*omRarTaoMVk5!8qD(jei0@4BKswsRg}yc0M}Bvkm~?JZa9db`4USVwO2wtv<|! z%{4qH^j%rj5{l2sc&9A&2RdYLXMi{<)Plk{kr5&5;55L12%Q7|=4}nFfnWd$m^s+R z5Lr0D*aR>clXR@}U2SGUc4(xl^tIrXw@!8)Q2}abC#Th-Gr_gUGXws6b!7k4hO4jC zg^ppu9Yv`?PUq;-rVPyF8)8~IIs(iF4DQ9j@MimGZTXsn0R<0c*`*BU8;sI-q6Zsd zL8A1k?BB6-!G87I0SE3%_Q$=jPdL`%7Gzj4d$`)u>n#bX&5t1rB~Wt5Uj#qb(e8r~ znyGkn;5=*fAXx(N$i+ioBHfR31cG1-Q10E_xBGxB#$&reKQl;>!?h&_*CB*u56(HA zC0QISrTM#Li8E8f)$Trh*PrNMb-7=Y)Nr%=e(|A1#yH<2cd;W$RX=yy+ z+T?;z;Nf~rq1>gmPmHTklMn5S1uNy&PAO$5h}^D`Yy8-o-O^U9t~>aQ-9i{7s|F1V z6hB&*bS9WH^>{_FpcXYM>aKveAN%_>Vu$z#?Q@b(L+n4c*`iFKYH`cl4Kx|xL?gH9w6q?b%B57-ga(9GpRc3iw@4Pb}LROpV~DfrL~t> zXd!3xOFnZQu*xf2B<}&A`G{nf_M2DGZ?R!u9O={^K|I}8FM%f5MSuwB6F&F0>C3Xe zU2w`7tawvKQJ_@8kk!>=$KP=JLL0?&MX|mVO5xDlAL{zbt=Yt!^PQFPL*giXO*(7E z3k9oKBi(d*jg;@q_)N&V*?B&+VWwl?+=moohVdbS@$`SnYEK6sFvP1kT8K3ptNMkK z&>XaeDk-HN-xwx%k;U@LS{cK9Nla{&JLF;;<=T)vAhtRah?iO9@%zQLbd?fxMtL<(`oHuv_d@j&2h>3KuKY&D# z>j`vB4&Pwu-@TJlx>d%w!|G=z5bW)biOms`Ui~IWI?+(l5$jOFnxsLE$#6zKt!dcfE1n2u@HPiEYBQO3fMug7CTw zBOun1z=)Z!w@xZs@ai=WL{!&xw5&(fW{i#1@Sj=ddqf$OOR;wdL zET!c9TDP$M@p(iVXMHOwy^%`O5sO&SGAs}L;-H|AvVDHX4RURxY-pTyyCWMXlVGP~ z8aOa}jpP>ll0Mo5yy_@k=WEq%%*wgNLGM~PEry}L9&LO#YHk5f%Omntm8M?6u8@g_ zVmQGA$$UC9CyP59j>Qr1uBS!z@7eO-0HsiMEB`PK95RH1u}!*bq_QewaA|5f#X?4e zd>?36i52iq2_p=Iw{BN9lc^veE>D-_{tAn7q1^@QwzYaU99JO?=9XWRnV<0u zQk_vXZL8xOj44xCqA-<(MQ4hMQ&|X4C~Aajv+EN=pz=cRzQoZ@%dP|-?RQb zV>%_ikwv(jVUmw}9AP;~b#jT=scBvfRu77#;{Jheg2TQ^#EBFVMWeJLAbp@;*~|e& zeS)&8oTVI^gd7cm2IE)T0uKnwa4Bc84po346c0C`WgJ47*zdvh;U0yjMoPgolHG7T z#xlRjJs7`Hz4wNRfbfJE;vjaG8l!>#vUpUdI&|X$jk2g%s=*0|EzsWdT-|bPkbfTQ zq5Jm2ETK_o@#>te+8%pV;WQt;tWBasrOLNMh1`CkuKbQakfEluxo9r^-~PU27Je_T zSp`A*4?nodJsbbF*QBqL!tz$ep(*6OSF+JVacOw4JK#KrZ4_t3f=PDqW?O{ELutr0 zV4?uP#X2y;$MsK$bWf!2h6Aj)z3Vku1K%U z?>g2T>NfM{i~W-Q6a*OdwzzRVdLt|=3SVd-p%o*yuZ~BoV{O-~%z*4Y3cNy3{WWAG z<;Q_7uV(ggW_>6?c(yu}Ilte0rsHxvBR%CWWEx`TeuT%TBI)jK$kY=INX&fB5#etC z#ozlgbMM8AGxvJkY7`Iv6l|@8X+n^O3LP6|D`s^Tq~n7aXfSOt&oDrRFwVjNrD`Ky zJtUJU0X+|$*nr7s`2k#BSqsbzf(!Uc4%ZuI zM@9w?%e7r^`G|$iVB}w1Yoc!uX3;}+P+K2vkflXwv!lU0yQw32N|qduea|Cro1;`M z@z=7aQ3mYylQ~IsR^$z-*d@0WI&PGoW!17y2fqcC8T_v*#*KUKfGhj&KzzX>(C2kx zd{}T4&-SP1f*Yp@Y~wc^X;xt%`>VS`(POdb#$76{>@8jg5Ktz*mbCH44{rQsH=yaV zuBU_Bm0ANeF`q`r4dtU@J)zKGEEz-}KMIaC_}FnkTzux?&MRufapb~@=~ys{rTozQ z&yG-drVi@^bxuXj23Vo=e>T|B@L^yb#k@LGCb}(o`>1&8UI@C^Zqa4$sNWJ?Y2u9if(v#t@;s>X z&|`W4Ntw_?$FEbdb7~~VC?<|q!_5&{ei&m|W63b|90gyppNG@`wqrJ^m!pgDqlKeG z3+~x0Bj{ys4Ve;ah$uMSVM4I&v7ZaFF6?~_;6t-xXhfSDT>4N!m@G2>bE>HqjJK`O zI}`uolXXIDkKe zEf8r4MPC_!`p<#0O)8GE*B@8cJU;FKuJ*$fy4=peYn4ck^hUmSgISF=IlqL=&V+1bhKqzC>>h4$3gUm&<^hX=2k2}bdH zxeH|$xfyJtT=38tE|>pogQPgBKM`P9FDg$S$0Gwyo8Ontu%_n&!SqH9kbpc8UTR;Y z@@$yl#*rq^)7(2HANI(`&NMS^YAPIzOa|}K+gX-NnmCr2JsG@koM~5v)28Kb#2Ka| zl%S-GmL?p3D6bFI7^l-2G;aqLddqJjdVddHj*ZIra@!1Pb`gXHMItARJs4@414f^sb|Xl#xA%F8h(PXQ}=-1&;DM z#aRmRf2%nK(Zk<#^r_8vYZHo?NI$?cu=kuG$7NUJ0O>d#@?FF}MG}CVQW+a9W5V4` z${|E$Ktb#$&$l{FnwU>HWM-V?Jth8R{273W?@M-#EO0n27` zTuK22wI@s9a>P418eje+3&+7G+NcM+^x)1bw_QEx+-W)$@eQ8AxQDUI0aDl2P&-;A)DAzi!ewHz?x=w3o+AA!OrpLOodr zUCvon!2$9vB%a+7_AI+1T zhaf}t7pV2vkrL`PR;LSuBJZj*Z@K!-Yrz0hqv-9IAkzg>3>B$UPqtGDL8f1P4oSUMsQxwH^CskH>Kn@jX?8cPHqFx@PeaFt#&B=yF1Xt76jf zA|ltNC}PyM3sTS$!t&&3JSDdh=LgHE4u{Q!FT9rYZCwYM(=3p9O{-VTUcY6jujxwz z+SGv!9|;-v8&RH7lc4`qJ_Vbvlj|BYgRcJVVUkpllg86=Zg6E-KfEqg6Q#~9YZz=G z;{h|JZ0?$}vQs1ytz%l@L8LT*`Q^tK>thpD?o{lfu#bZHl&l;|$iLVc)2B8kP9-)I z!YzaK`C-)tPMzrelk4f+9_1%{>*+6@ zQYB3JqjX>8+3t%nMub$Adh07`Dre|3SnQXzq`slT^Fcc+HeLmO!^0 z2i`o1^ok3QjCV0b6KA(f5;38!>nwordVR_mi8}ctqX6?p8Zk@cAHv%n2DP`kci>X= zk*JGQkWdGrvB6_&dP6Ss^rukObU#nkxiza;c1d$qziW|7rlZL-Q8Eal{QXDwoq3%Q z?{nw*o&B_V#VRIgF6npIdu~6!b6v9e*wZ?QxuiXw*DKrKy>fP2iJB_FpHYXACw{v+ zW>PP%A}nLgDo0$tKoCpz(HCAa`TF;pFO!exCGYS-5V5;$x;afssQ@y0eiZ?ocjENh zj?frPM#)s+?f9+=ZY6bd#0JRHhXy43L9@R%j_IN})RABTdrz#MUL`s8l8x7Zqx~dS zq0o;dzup`-g9jrGW^mxv^+bB)!Um8jTVm!M^4osaS0`618Xc9&8U{zQ+oxnvyA&Kq z1ZE_+<~U8MZ&XM6`L%fcAx zloJ!4L?W7q%3m|q2W*~(?=@()fX)DcS02@8I-p1L(C}OPjXN<+%A5!0>6Oa~v(7lp z4=?K#00O9^I13HGE~b_|8PgjTSJ_884dwDqkuC?qs-vUyyYg-#R_hdk3w+v*4yvF(;9z~{T{EGOVJc-WioAV^Q+y< zt*{5U6>{L8N!y9g-Z>MC!TGKnbW?o`V$Vm5!0*Y~v?H1{nucjfaOGKZA!t?{QyHzW zDfzNa%DlFPZ%5mX=hP5XYc3_tSA0N6Fh>Z#vo?(bUdWIDVwj93bs4qOICf5}T3dj4 zJAp7xrwrO30N);~#rqt;M*CM;e9LyGcd)oTPIR3oTe*i@TFj-uv547}#2az9r`c?z z57sH0!>eX3zFv@pME5)-`f1PNha!XY?gl*>FS+d zQ|2(@shBobEPUm=S+(=M+ODOI3zA6bg0B;~vgy44WixFkIDg4kx>>LCwhbrr``X6& zQ)}X??5%Gaw$6OPR)6NKb;#k8f8SqmhNN2g$Kpwr--qy5IDYkcg*)+GG(~TrJl4MP zM&&sv>;W3NAfsPJh*o2e!$VINQnZJ>FCH$Cp|djj#QVM$xiZ9TNR9s%3kk3bzuN1hSYVxy{Z==OMs4stK<>8AG0f0{AXKz zauOSlTD#g3I*fmxg{v-RG9^#tGw_~jueX`XX@IYzh4gY2EdtqF+bc zD*4F|6as-m^j0{$^4#7guT0sVlDywuF3bYn#qq-%DJ*BUrG5(hJ((0P~!@GV66yL6*97C*LCPwQQ{GrpR+>e=k9 zZ-|vhrhv2pbqkL>D=m|jvlxuG5bK_nK9^rVtdgoVv45D=dCLB$Do$}lF3Frfes%lb zvpRR&no+KBP5TRp4&}CZhu{|oWcG`!s(CYw(=!v>**SkgOMS@JHUsm}W8gWT+1+kE zOu0g){v~@Rp9Qs99vy9`WqFXqTui#Z^ACc(&%FKumvwxHtJXiH2Rhk;@Z@$f2*3A} z%lkaMt75PkTC~_apr4Kp@eLs8uoI=3XMfqYnD525dBYB#~d2N z$acQ|b8bY>EtGZju3VB)SXXd%SkLmm*gi?Ayeh+f!p@T^dyy&9=V~Ai_vLE>3v2t` zW4ce=sD@L#caCc*^G>Z5|BLOHD3h`&iTb`9=a86p> zh;=k-KV#&p0!F`xCd~E`|UQ;hPi=2Jb|Fw z?E;c;I>B`deNO!qhdVs1pa=XZg<_x))@lCG9MYYIKC85=Bs^VG^pz?(Qsvh8Wy?V7< z4;8u4`0$qxgxqMn1>7kG6zK{%x!lbsc}U#e)l|Qj`xYML3c2xhbr5d@-Wi}gTIJlh z9v3GSwxqbBL0_cu`+fpa>SrLW#rOVY!H_I0AN|(l^#AdnrT?#YpPEs7=X#zNSm9mmmE|=|8%HUR%`T$8UKuG^sa6%Tn=mR`BTf@_%G_$w z7D#Trk2Ap%w~rW9H%^s*VJl?_`C;zpk9ChV6>&=7hsno0)*o#8%!*L1 z&srdQ(MkXQpS26+QGw^j>9ODUAT8y0A9S^dwO79>_q}rdY=UyEik7&&J}sZngoS@C zU2ZN2GXI&(3%BUDTXq!44!Xqamb(gEE40H4y)KNgd4)a}`CGG+@RDeS+ zb{qxV>XJX^m|lMMLN22V3z#0VqR_n}$TVY0EGlvn(O2YJ>5}0BMy3d7YMnx|>}m^_ z6Z@tmuhsGVWtKIb+A(hTZ-44j z|0_MNn;hI#Koop2;*X^%WcZR|c{{6cp%Gqf482Ri1%>i;><^FQ-T6bl{|iY)e#ZA& z4}}nN!wLi<(T3#|t)yt*!ZUXlcuDDB$j9fUlr`kU?88EmQaYdxa>R-$Uk18aMXjX# z{U447dAPq^yLa{f!4D`Gy+Mip|NVE|EdQK=RI2c6k&Fe(VG$2sfC-mfdUd{gE&9QS zF6LdO>ObQs4y@3#9C7MW*4fQSyOj`HN1N(Z~+cG zBL&d0(E<{J7Ql6_y`G_ZoFOM8)v#0RCMl`IIn z`&8Dt_4B*?+L(?~`Jdw?|I`xr$S!cXSG(OSmnrW*H=+F^U&|_WvX_nN_t*3Y{I zzPm3Ud9PV|>b;gikhO`llp4!E8c8#US%fk~>nM8R5U#x+oA5*bNtF_CkfyQ1?R7@r zV%8TcgC*#6Ld@vts~enpcN4O6bu+th3tKL#08ekxn(&SG#sbDm6aq=kRyYcR4L|z9 zP$?CFY#|}=8Zq3Z5gk-osM6U1ob7RixxnoWz!9a+Dw3KlY*D;!7b}}&2q1w{t5w;e z#WNKEANAQ<4a)WFw_Z=Wvj7`gr~$-<`?2{@2gpG?mjtK_`|f3&T2j4onMzLXl7%l7 zM<@y}4ZY(x*X0yx4_VJqp-mdK+(jP!%=K6gaVVeCeTQ}}^sYd1iq~oP)GgGIsx3To zSr1Xz7dk z=cqds4*J&FU$p1T2+?R&_yWiXmfjjr5XX@H+vMx}l>IGxe#Dfhr4(!Qm?^b?(@vn< z_#s)={-$1a(YorNfA^{{UcG8XwOSg!jIQ<-R9NgaX2l>xbe68KJ|!z(cg5Y3U&_ex z1V*O_NBXeOg=L$p)1|(-ZkL+Va;n3@aLOf%I>W96S9L~Q7{koTb5Z;2w){=L1V_!= zF|rI*2NwQ7N0-zQ`V$C~H&=5;lDZesMA1;3Z2S5kEfLV z*d6@7unRvQUT;RY{2iu8cPAwS8$sOhhr_NJ>*O7EZx9kfR;z8E;B~Got2ekeD36k% z4H!_mz${j(`@?9tmnx_sbKbZ^CV}-3q!{BJR>o=^D>Ut90q^aY(`w`Zki<8AA(ZHU zP8?6P3L%qw?4JgTDrnNcZyX_ZuDeHdV9a3hjvg7q0d*8u8=FgU&t&V34C5H0JI+3) z^W<;s)}&vK;@e|P{Rt}6EZIbi(w@_*W-qUuZ3a3sMfwy&Dm}FAmV4}{6m@)^*oe16 zxLDGezUX0!PwkvaDqg4U>mu)sf$c^PklSfFHZ8$WehL{|jYs?Y7IODet?B8R# zM9|N?Y(h_B?)8-6g@EH~J!l9s^mqPq)#m*>#}@Y6lK4{65!n^V*R1cRi)K>EDrPXk zYZd6PXV3m)os+|dBEFE^*%Bk1A^$u0(Wo`s0tW>*M$C7pI|$znHWV@^oQ!Z-769e< zd9d&1IX)tnGwtW>Z`txc6Tjvr$=>mYMrxH6n zXrwFJv@(V7{C1Ug5KmcmQnGnc-VjuQLV2kYm|zZ%8ddpvNSEtgTDg$z7&Eg@OX4J1 znfN-PWorlJ3{mgv;e84<7qY?ccAZYm3xBb7l z_N*+XZ8_hkWZI6Kgf-54DLC(tda3NMpzjI}(X2{Ya>#OQ)$#nkjwg=%E86f@TH9hx zgB*jqPq~(2zRcWWy6mNA^2|51Uv=5H>rKguL@OSl_U{AekCq>_Pf0%Jc%7P`#Kek8 z#QvYeW@f_Ry!MZYO@=`T^NwKgAsz&?{Ksue%q=>5_OWTh;RWwAR?Qy!eKyU$o8Vm_5<1_R3PKN*H9{F>_I5uaNAscky^ zi%uu0$txTj_8dgGh0`+J8pMu8JEqJR2$zT*3`^<>12oCR$bpCyRw~mcP@s}*dyXI2 z9|EuVg)Zalhbr$qVSmS-pRs>j@{=au!#qKBWky{OWc>8U)mguocP~cbmHMw;8VGIX z?`ER_Q5`NWW)QPQ|4o1UQPiM>?%!g1q0kkwhFm3G^jHOf3rm6~g>zlLQh8jwjOlyd zfuT-iMx=ctQq(y_l!V++Yc8ZVqv=*{(hOdXpX)SY&EiFn|6w!cHS+*P#Ck80iicX| zBlv7F5ap-omwPWOqH~M(ysS0P!)6w@Xu9wK!=E&t#nJ4rtbACH7;{?I{ZhBq@M6J2 z>zET0)@o~uw*|`j(|R_~K4BBTb>TH;r+BQ>UUNv6KdPsf^5oLb>Xw_cD<0CVYt4gF zY+d&O^AM)RrM&lsD+!Ju9+_<6CD!$;U{yudRz43~`!L}mo=ZA2p3kZ`p)>C_-u^lx z4#muSD5U%~;myFY!n5XatEnUAvl<`-wV$^XD){2&uvU!+e>%IKaCfk@W~0= zuh4Wc6nxV5bFST`J47nAa2i8HDX$ed&WRs!@IhNC2O(OeY}Uw+twV$)@V%%#j92V2 z8|3>Z>^?x5dOD{{4keuA}d4>CidwU-6>H@X11 z!-ntSSHR75sZ65ZPh}+ufhRW+nn3R6zewm{d+bPq1(9mB|3lw>) znHRIF!e@;uVgE;#?RT=^SvFqr>-h_HxA}IK{V&*kbi%6Bx3cJpUyggi2|F+Ph2-30 zLk_mduV_84kPh?uo0Oj));iBYKDsq4`aVr^LK5p*x5jVHg*P9GVj+I?DkC+@5057Svx{Ui9_cfK5}^d%y$3)gZ>$o@rH zB6r*B=ArKS&Bobkf6kF_e)4ud(@Pu8o3f87H5^m7U>QD*{z0-G0s^qqLmmCH^kMl| z9qiJtg=NtbVGYcRiO!59PBT5nHTzGoYu*cX`*E3wk^jspJJoJQ% zKySZ~$Gx0IQQtAWn__Zo0)FwT?qdwI#q0;+2)s$qevHe0%Hi?vAUt&|;qGVFScf&s zGKaH|JiW<#V`%e@N}c8H@pt53I6;;He5oAI7%!1=*>(CJ0whb0F6K}_BtVn>?(&Ca z3?Upkflg!i!m-_fTjVH$2)$10GQZZoJz?AVf;aMyFErTy!Iqz*4bNa4BQb4L*xalA zHG)V;|5y^?xS6nI**ZBov=cS-Q+A9|P4e-a!|c4V4{J;}qVhjDh<~{(FWJnCoV<6; zJn^P{EBlx77b8u4cgo`h`BcJtGS;Y0Ia2s{y=y*7TdmNI zaeuFd*Yy2T#(yc-)~0optud>JoM^3fv|_ipqL!Hji;QEdEKz$8Dl~tNKbF0XsPfA| zNfv`Zc$a~#qrR!F;eCI3Kv&kOTrd;oG9V2L|Pg2FW0D;$F_s* zWlj(*{c^PNn$6-Q@$Fd7S=yF*FQc7~qzraBwvl(YfXzkqjz5v!1q&pvpD_B?bMGTjX?=^!t|cdXAk0jrf-P1h(e-s-E>qH^|TO028K2W&n32`$rv6hh7EEzKnQQtRf`VeAJ>Ld`$eG zRxZ5Hk5`9>m(w|Jl|LKryh1=$jN!YqB6jSSge&E;{1}(wYh%MVf9I6C4wJtxw@zPaU>{YsQzo5t;_vAXe^ANZIF6=xsMd6x{|GgUZ3HwVuT9e| zpp!F_j!pVB<>{j8Nc5bQu&%<2q|=(xVXVc~J+sV;Lg#d1ZKPzH#5`P#j^2~#?VmmY z42k<{o3DRZBY$`y5cZl<f zwNo3*6372JYkr#_k;$$b1~p8C1i^$Ttr~(DbSj8#8utP_*FSI zhNC{ZiVt&^2p$?{mAK#U_^AAHtS7UJQHh58=`T`UIf^p6+`jER0bQH~j=5i-HC~LL ziGSU_3f?gNaDAZ1H1Gl*&6tGRGp<<3EbkA>_^Yhab;l9RKdrtGjt8{~%(22AZ@{-9 z=3f07!$_$RAPTMN zmS1SrD?>#fBiO{-n4Ux!@DhEZGqvRc>BoXwSgEEb^u+)Z>wrRn;G(Vo{<}FvYn+uQ z_^xRPc;g{JI$E4dq~2ZBJ?w5+kDk>Y4!A$HC1aLNyEIohse7&|HcImvW9TQSkN`4J z{yY6;A5!Q60x^WtoaxfqU}7w8#U4+)1SM!PwOL*c7LK$Yiewuyv>sZtH4@LSZ8F(JPg+;Ra>DgZRo7)VPrZ z>edC^nU^EO${+Tl9gg#AcQ`WD7)K#uJfJ)@h7PB_-4>|$i>#ebZ(Q4anI+8%Z`rXH z`R!P6y^LA}W1tidvPVYSF4@OWDO+H|&j-WZz_W8N-Rt_q3N**iV^Irz!Cf$x|Nq39{x4uFD3T`A5Eug8-Cxl{(s61JNC`0Zp|cj)x`t`(ctR z>7TwS;R9{FmI2$hb^x)K&^O0I)UEXvAst3I7dJ(fV44cb<|)Uq`8v%wfyRnRz#C z-HGQhLd1(oR`=oot!0!nnw8-5hv?jPktfsfFPJTonc%5}#&Vu(94YyErt0|H+Txt1 z>932g$(&=QH!}*X*TSlZ&y_x_kT`<9teH@ATUXrvtOX`^nO8^_RYQQI5~f`L{n)f! zxI*u=gwf^CC@aX+t-`4e6Ho9>s}#gj$1_?1WXZ$57RNJlPvB7RABJ*t9;F^xb%T{;oTF9v7XZf$x{ zsQe+>X6^VHXn*Lva&G~2s_>YPQ5Nsefh4F%+-yGYqc#r`S6lP`eYuUsf%M#Jl~ih# zByHBtI$b~^>9lrAJW8&m-P&0TdgnLOyk9+Se~5v1d2Ul0xZ6Ww%GYrYr9p!*Xejd- zc)~Zc>ZZ-LgevLhswR+sHY-SXZHBKz2qDu;FbB8TdFT!35PftOj;zI z?yQ&za>WwMYj+f3n$-^}U)?T`qZ-~&s#~aWs}ETF1?^#{^1gLiY=Z0v+&WS(rfX`g ztSjan?v&*gx(06}O4$n`qZ{_4o?tat&)4E|Rm^>IDXUxy^pSt4TvM`yN#|IOpMX}< z2g@s0oW(~2%H@lC_HWtv5@*M&eDdto?eicP6jlbqv8qk)UdgI8dwoAm4F2@F;Q62a zOZ2Db#qqki;`N^OlI3ft)l7v=Jo1G}pg7(Ie%ii-EN!pLa?;qCw%c@gvY%8cu^VYR z`#YMMQuz+Nn;(FF4XpQA-9lr0prOme*8KODc-|LMSn zEt|LFdDUT_28VzPT+%i9VZ=`Jg0gp09@-M*%zncw$5VBr_}#Ap+-n>_?&@^hCbJoE z8~G&*=%;+%CPydwn z-FBaoq!jA{sSGJ8cux~rQEGZpBZRq$K&zaZ{^=RrFH`H$>b^-e3n$j9Aiaicd8MtG zu#q|nV-XoB!n@}DeM}7vhPl>r&^NVCja)ijaC>V5d)W}Lu0qhDHf#H4Tmj00kgW!@ z(6Ut6)v|cg$?~gZ-HwyY|3g^>*xXL+P~SXgY#x-&>9_-rlxG}0^6haQ3P^7*{|^4M z`Tuhcm}Ok^T;`X&6X}<7kvsrrZJk_y2(4I;>-Jv>FWvY@sN$bXr+klZlxO8ioz^1l zR1}4gyn`2`c^ql^)_AqqI{a_;ktMeVAp;mjQ(K#Zn)(4a>2JW87FR_-E&KOqew~Qi zRjqGfl7CJrhVA|| zrb3iB$FC))1)ShPC@rvc&Nl?fl-i<$nb)oIhl@Yz=;f_o;{V1a``58w<#t{SeCe&s zmm2JkEP!`I=nL1>nda!%!X^5iBM!gK_gP zX~Zr>A5UFwuph85dBgmLssgKPUP!&x06MZ{j`ja#$?GwLlkxqg)sS0%0i^#du|XI@ ze0KxvbZRH=Lz(6ioO;B6os?8x2yIc;VwsKeI$yB%p0M^7b(+0X(OYr3&1a?d%HHSk zc_FQ|X-P`|^E!hd+jns%qMN(={dX?zoHaMe_3hJZhp$7f4qbI+Mq9}z5;(D!x6}60X)!CHn_%oq^uj)@ZGKG(=YJSNRztD3Aecd zg@7s7Irhl)J>PEN@QG#_t6o7Pi+zx`YD0cBMDmg9l664y8ptYyt_+%2btb{|at=%O zVU(SVjzKup;Y8x1W3TN0279@UteoBEfLW%$j(vPSjj^xLJjG&Iq7>jwuIl+Edn<=@ ztCKAkOP-86T({e!mvuV!Y3dYi)2&|4+{t;zzJ+h=TI>2jf-@ijchp-h#p+tDu-Py` z*;&O)<-YRqELiR)A|1GE2#|{?7D%@IY8z1nZpbF3kUnHgDcvNQ*Yn1P-^YM-eLA0 zC93K-d#52_zuDW#-m_Pq3L&=f_%l~`%{%CF@2|!G&i3z=C63dm{(DfI_V{@FETgcb z%dpq;S~{}pX%GxmE_$raWM$MaK<30kN4mge#_az?0o3=pGT4rNajlgxz%wU-QeNcc zG#Su#rONFL)#<=sYNc{d)V8I}08jsSjiz-#PHNE<#md9WcmcL0Apr@F>gqw>tKO-q zX3uNJ8J9(SBKsrz!TL?Z8o9GL@${{)Y}O??Tu7w4jyk|mJ>)EH9>bV1W6QtwUUVCf zu+z$HNQd-y`i6={X5tbe|5pjG`)R95B~(~{l>8BzZ0Rdmfcyz8MtRd$ z=l^70*SPfLYX2Sc z8hNY9LO5D4MfLN;#Dtd-8BdsvX-vdlK|(*2AbM)uCEmI0IHYM7%y&b^nUK*#6p=~> zzbCm5na6#;?brY$bBOFZ2*es}r#&`Mhwx8IiaoqezQ^7FL5LV@jU;6|CP}8EfJI)l z?oFfTWJYd>h9nRIiWd~Apir=C#d^tXi>Z)v8si zRQ;({>-&9X&SlQ-IYImSe%|+w*B03G{XX-|oH=uznR(`!IYZ~YgP!hg+RC^V2LaW< znR5~j4yzuSyKv|{wbq7PR;`@q+lHWl8JO@4_?gmcBNe*iGG%b|De?(b!GBUyagx%j z{4{sQ-_XTnmLS4u09Jr8rNj3RUCQhlH{4(^UkDc|woaCB-zEOV((x2jGF-EhXbDy+ zIgQdRuTdtIxHBHf80f|dazDWC?Cj=+yAF~i;j42>#(h|HS%@pVZZl~&{ty_Qnv-xt zCqeT`C(Xtbq7o0v_iaZTq;|Pn*@at>%Lw&T@{}G?FgfFwt^vm=h;FY}f*2WPJ*KSr z5KFWf*C{UAoZo>_8NTfWe+-|@pbh<_m*+sOy5&MdLk+B7fTgwp3)Id9;s;)xcGLr2 zJ9M4ObEDKdl6z^nqSu}(cnTIwHm_kiH^AXI*5R|H65_Dm7}Z2> z1~l4#uo+zyJJgw&_o6|;erH@vmTCsJg~P`^_`Gq$%dmfWz#^q_(zvatoPOB|k{YOt zzy@9yxp>y{V)iL1-Ad0S8&?Bq?Nm9E3m~NG7CfmWU$7iq0)G!&2n`fwb4*DoTp2i2 z^0App(^LiAX<3l!xk<(i=nlK!49WXJz+>FuSKzgm!$}YbBv^HZe0K8)ZTDsh5DH~ia4xPqvym3dh?5(HcioR6(23Nol zUWee(z0IFf36(XEq0G|7Adk{_v(kU_{$>~kcN+|7v{pKP z&FbJ?Wf!VjvhjZysm=Hd3l8S)=ELM(HD!302H@(dOqbHD;e#smbG2*5x9aBr&;|0l z>$7&>r*r}xbk$`;5h4}QjI!n_y}yJr7Y8X7W!z8hj@Zc2!xxmTP_c5FiTFd0a^xN) z!I`;AR&w4}Wyoik3U5(Ix)nK(SIaY7q!WoR^Tig%N-uNtkoM^}wL z8-K6^K*?Miz-lEwynet0+I@}owt7O>huGGM|2R8k8@!XQqc&RajqfJ{*LkF(|Ka6bYY zl;_LHc~Ds1x4p*sp{p$)&_v%vzkBl3#L7UQTPyzHvBNSoL8m@QUWDeY`O& zzdSEzJ37}6z=KNO&vRGoQhGP+%9*8fAvlR9c@u8rjifziI2tFdt@uXP*9Mf+kzkzf zz)UrejT^Zfjq#i^oKkb#Jf+=78*n1ryPrK(t;kVdx_Prs#~U6-H>MbYNv%ojy#`8Kx{`5@SM!tk>LFtd1oYH;L& z?E!*Mt34B6HS;O?o^_-1a&qvhqtEJ8eK}S1JAvsRzKx;cC}Iz)b}QUZnbmL7b!LM~ zd!pZiH9SDgBl9(U*maPS-EzLtJE(MAsT}3mn(NM4P&yo6WbVKryx4y`b}2@|KJrfX z8cS;!$Ci`hyjRUNx$bdQIZD4j;`V%~>Z($7UCQv1gGr_DB)nhUF0{ZIYHP)g!sgT9 z3Rtln-_5;pCB;PK)qQ&Bs2vv;=AOA*9d+6U>`qeJz9AnZRvgGDtVC&jD^JBzK^8gc z@@fv`qV&p_2#yRDj`S-X8_@xG;e$boFcvMU$NJf8${<9V;o|fi?`QA8Q@>pq>|4={ z#qvrzbR^G>`R#z5QeL?OJzaS@SgsLQL!(`V?wonI{EQ~UxW%>P721da3_N!RGYMUp z#Eh76Evjid&h4zJ@S@@7j-a)S;U!8lYU*e>ug;i3SNo8&wnkigF+-NmtuTVp^8QlXlglEL3H}@jL|U zUzo!kjUsl@J2DcZC}m&+U7<(ASsh~ZI(TYxvbHuGcSh}Fp6VW>-zEI2>#|m2U(ZVF z>P9WsG954s76p03r;nTvv5jv;^x=8qWv9H!)F5xHQQ%XuRn1*=`Vb6(x*QjqPyv{q zqxJSim>8nQ7vO-pkyzV+JLV!qxj%az0ttIxJ$W>a%y|*Z`#h=|(@%KWDyg;OLw-49 zCM*51CWO@#gxcKUX70h}nBef=_RZBrg|0% zKn9e4!DPSn?^QE!_*AF@Zw+h{Uh&&9>h>Q{Ll{uv|9DVpkU9kn z5aRdaBg_w@iTmC~^ZUMy2Bkw<9)?u&idOY?I(GVqO1eCN&;yLCFcuxsqE^s^GpJ<# zabE4656laEegj___=M)*T|-8FOm0_n>3;5vI=%*nT&O$L)-rs=dm!rI670^nVZVD* zP7^*{zfZ{wA^@^P-L|Z(Sl!AGtx$rkF<8`~l5AL_%&yB(${Lh;_)1!XQjHc;wvqlR zbvKQ3E1f~*#1dt0mU3bPzSs^!jUz3gHoqJpjXCts5*%cpUDOdaPES@y2{2B_(lG_R zX$f=iwe_s&IN&b`i>Mr5N8gvHA6O{Kg5K=0l;~*0iIlj@aD6O%n20YN>sI%nN+;!D zh=`^eM5pP-Oig)D07nItsw@Ol%-Gwt0ecDYT6Mmh_DbQcKPtMn>uhWc&cti^23|`< zj~-FJx9f6(@CLtuHyF@>mi_A1cbb*1>yNR68 zM)3G|`Ck3U%esYDODRd7xM5cYsT4g|V{{weaoC!a|FI_HpAU;i&D4(k8 z%e#Jsq2sq11NZ=^q% z<7qeeh5Pt+Ve*{p7Jm?Rze`<#u(^kEja0_J`ftK%=RN(o1%K$8((lI~lKB*Wh}(ca z^qYA7U;0flBul^P&n?=&l!iE6meLbX7|H8@2qPKd3DbGPbs74XuH`?JM!zPW(o>%F zo47aehkolayTL(bA5{jb?xOXy_Z^<2E`&eAorJ10{v#27fy(3mGZ_51P`=o=&qf5= z|J40Q@@ql)?Jm^F4^@todySMYxo{6ZBIN}}$}fLp%JW5kF2pp1{(;oLx;AtFp)S>pP&>Q^m(o5q3>F69 zm=-K1BW|rI7n9*$Yti@OMEeC`PEX7xVv+k9Z z*sE3!_khwTct-_#U|9Kv$v2!n8q*J$A1tK9zmKm#mS=8oA@*x|^9}G^#6Ft*5e}V& zw(=7*&%~UYj#Digv!d$k>Dgst&Q{&Y(fRd9;q&!~UM;UDUr2U~(r4$2jw*M~ z%3TP9A37_Uvy#kOcL8~xl{Mu`2SVY?ui87S%3X%f2Ijiep);{$-?0s)#+hDNE?S*H z#2Jq6I#EHG2#P(jycuihw+zpIU0I7cWPx&oM^ScWFL-$I$l-2vASQ(Bkos5l-|&xo zW$kk6`!QN+=TWxsdSfWpC#V)~pLdW(;SW(H7fuDB&)g66s3S+8ew5O|XDi)23~Z!! zQtw$VH2g^`YG*=M=0>cBV0gLwUZr<}M@ry};(Ry85UkM$pMr64&|NgtjNQCheuu*brA7JPggx6A-y@$S1yZUMxjNuV_oI0L&7u(X|1nt6dsS-E*HMYv%4)2HR0d3e@?hjVYr*zM~7kOKs# z3~hGdi)L!9EQa|p=IrR1@M%Fz)p(5`U9)R{PFPvHQyDN7K`8CnnHRd0=60-B;OIa& zcQ;}zR7!rz%tWDjM;m-F_kV;#W^noNEKJ+5-pITN@AC|d@G>vL3R=yxC~Td&J?B!4;PXnU z)ji}|wDoaPnx#|}=)Z;_0&5 z>}o~bLvp`euMVT@KeKXi=^??}*9{Ru{OVwrwlV~TIJ<-E^N{p?N>=7JmvVPkkoV2# zr!z06fNdJeP@f5odT@TG5Skm{3rQdUc6j?5Ha0%b%VO0OnH)B<|Y@Z`n3JuR69>9-?4IK#oN@%jsK59i2IK9c#S_| zS;-unYn++2DYqjJXOUvZ4vNtA5dI#o+_JvXt=1wEh+KRlvF2T=WRSJzfdKf_KsOr-=K<^LAx)Q1vYo^+_DcjX)XYm zSO$CGwcn)fh85U|E(29X2Ye4`P`ifbz;`kh7Ib*?UcRJ5ADg;l>))wAScg>-tnE`s z8V}@Hhjp|pAN={5FYbrkD9^>x8l37^*Pa7I4t?mxhE%J~lMzo0A0?dIy~pOvci(`O zqp`4in>S@#i_>vCVcpRMz{njtV-vpKGIaU#$qM&OC9_@q7Pcpv_Xq_z46go8eM@ZH zR0_0UhV!tjcb;o3HblS(ZuVooc;4A)+1KIuzQbO2*DL3)&-e%z|3;PItn_)CFvEv4 z|LbnPk?c$tCSGbmC-ph?D*RK3VEF#@(Y2H3A%Hb=IXzQF*@M*uI7?k!2x~z^K96nq zjAijeh{3;<5_g~q@eK}+t%jm&*6&mfBFiq!H*P?{#Lz4}l(GEhD}W8C#()a3Q|C*u zwF1JQqlxcaUs8b(0S_<#7`RH;ArP&RZ)F@!kslSxN<`N{c<^PD5t}qs$<3;uMKNU= zPcczTaY_d5wwfSP)Qc1&$}4g@l||}K#JHgX$}5zGAdbtLtoZTo(ODJ4;R0z=zaj0} zEt9b{I29kEoBnW4o>GOM)5XsR*W)+ZS_QSbsCo3_i* zp385sX|i7~S{Vju?U-^PiY~ad{=tsi2UQ%(&wKcF_uq$w&yLg1q8WDgRLJ&iP;=b= z4L3fZta*-hvnAT;)l_aiTS@G6V=04Pj_YXk?q@A(Hs8&Sh0_J<@OrfIEZQ_o|6y}^ zUA;O_oy_BGGybX!MC9!2u8cb~U8gI(kK@NsD;YN_t`%sF@Iuamt2uL$+KR8uqM;1S z-04!btVfiji>%*gOpVgsP4$@MQG!v22pmuCje0zxyVcz|-WGvr8QlZa+B_0M6Mje} zKhI@Nj!_v;ejZx)x;HQkr$Job3Ca@g4#m*xbR~0$vb#GAAG*KM^+u`s={#lZWAzzl z_ZnD_Xvn{!xhNC%W-FsN(%!@4;7!6msE?U2vb{E{WlBFdz#8c9J`Fia1vyHvTVmkp z>f|c*gerB+UO$Enlcp-m;hfz_z7a%6tj74^QMOT;1$QE5`7Uk>cjll`Y^1O~CG#`o z2#&+4y>2JkkAPQK<|r@VHw6|Brvn9O<8|DVgO_U~ZA6RVWU`IQ9VX* z6T0@|4E}263WWNNM^tiyatmJ45Ag=l@5>-=Vl@Va9fEw(P#L-rD-GCTI`}j4K|TyK z`lxFL;t|#Mp{koKm%3Z!D`hZ&y(?+h^J2GWrgE=KeOr0F8%GM#=S&Q@PoNsDNj2C@`YJ@aqLgJ-kD`W~p*LH8?&{7$p$6nAPr9m=`@uYce*x0;Vp3wJ zI(BdCXs=&W%T4fQ|gy6#sF z;b+&&FwQiXJ9-96@I4;F+1UGex}t1E>M!xyp1VHlE9Gna*o@l#Lhy)&gYY3-Tx<$| z0GaJ1{2_i^3gPzzuWZ9oZ1V)=_Zf9tbKvq3VgX|^rY<=-%anoTN_@G} zAMu}Sm*EE#aZ@!s^{hAD_G)OjZa!(pvr?6Y91I`i1)c+{uB5#aq=;Wnuyal zBy*Qb+0pJ%Z%_-XKEAgW69Tfs?u@(9Il)gwD?!Ky!44?Hu!c<^(Imr%IFl9p%!bU8 zgF|!j)CFO;dYan}SJ=R?(t(hg5~VwV;6%LZ%@{(zjh%>ZW1gkZ?&5zi{MBo7Gp1PW z^%Wba5q1SzX>q>|{(B5Phc3do`kC$Z3pR974P;jGFYqc^&mZkoR&jSUgofd0e7>&R z+p_|DE3l`xAnjkwoCbNCaahP;?5ghl+~>3tq8^5*nw(KepUP$xLH79m%c?A;VYyO< z&2$f8>OH8W8Dk-GKQi{3|8%=G>>g zojhFWjYWxuY?K`{>lt_)Q5pp1#1<;pg@~ITwsD`D`zCG+Q#Z__R;bru_Iee>@O*LH z3mrl*qZtbbGd8$$7S@l+#m+qFLdW1j^wF@(&(FpJNm&(rS`SWZ_*igDZ4*in*}i&^ zvTQl_k5NxQRByo*#gy-A6=#a?R`tc7exf}ny;&R=D zgQ*AZ#p10x1}E8~Dia4W@5P!5I!YuT1*yBSAPw6l0unkY000pj6V~7lh324gaYMP~ zuc-Kb!SYSmrqjC|wxqW@VgEt({e3TBm^ujKDQt(}1sS~PUPKKH5FY};y97}LLhJ`i zW4~@L)4xHMneO=r)uRR{s}JLrD1J+QM}0+o7L9VlOf<$M{wm3Zv87(%0s4p~tp?$H zPEX^J+<>zOmCUQDxvu#hpO*>_S%&DI#zw>m;m!78n1e4SoPwik5vz$1HXkmYnwRk# zT8ZGN_8ietdhCdCxj4XzeDYg2C}mNlPkF^OY?&W~Gr-5b52*NRNSZnU$if!Z)8c?w5&&r6( z-C=x;FMA%|u&fQu{3IMaKh)e{bx6g$p~EZuF=$56biZS+l0T6?q7e-T|itgL$tA$afvArt@sDzL(HxP zQts>y9w?ky7T9#~msLmM!$w&2UXGm#ISUZ?p}vQg9I@3fOgT9V<|}K@RZvTiKB)x z38gbGW-9$&R4WwakDFe4kd}^K+J_X+Bi$-~(!r3m>S_D3C#w}NJ+=KM_=nV`_*NZ` zO&GG4+InWjJ@HP}?x&Sb*aytD5h?_iRhH82!Bdz`HHpG^ z(!mI{2tEM8I^=}IW>bu#01Sd;&9vEF4}U|h0s_`%=q7#St?OLKt>k(4x=Rk4d|6mH`L1Un|iE92|1`h&3XM-+sOKlUc>9LtFa z!K+tS-a-N80RBk>?}XxhPFa+(0|z2B;~CfU|DE;~557XAT)i@cxC3|tU!#VmU|wFX z&Oe#+s3G;zTj&@Cp{x_NkJlZF`;EVR^v~&7m7n7|qD#n9s@CE|bmPb4=yvr8`X8O) zz7D3ri&oLqkFKffot)>dX-=2D)3;qM)MsqoXX8{qmw*v@e=_;l2q{rEmc^f=|% zYV0j~McuIb;uS-&dwlI?MLn$nMt^z@LrC-SPAi zzSDt7UbNc#u;GF7YX&(LJ?8v!WvYh=?+^}qNcgXa(dV+<_3^ffd-GzRJvCdpy=QDHX!o7etji(#=}LUZO)*TsmpQpyRj%k3rw^yLx1GO8CtNBuOG%W z{UIzBzeVRXU9|A?sfJM+{Ws;I>mV8V56S3qyYYKBc=|)-+Yg5n?xr3;TsYAfF~`05 z5`@0np5G%JRZt*s{onnXYw8M@lFh$LizD=~4Syt#gDOB|7wxjA(+ZC%p|kS_ppU8H z8|<;29=$ToP#p@#s$F0MS8yIsnKQ=`ho^DxvtO`U*t z{1g07x#U>1n(w-QDt$jinf~wTQ2sCwwQ>6YZe=LnkQxL-rQV71YkEiDUZ*1R!J}M+ z`Q+&yCtg5G4HAdzehMOp+MWd&`CxUQlg zR8ls@iX=J{1)gMQERe9`8pedO{AMbT_B$9wd6^IZq2PBSv?kz5;vy3lZJ|iAq?lj! z(k_dpST4(qD^nCH8S9(z=J5Xf7fv`I@jO-DHc)qLG@%(Z}6kx-Idj4P^>{QPEbqB*~zXeG)Sh&OqCf$X*G*g=C1tV$!tqoU$% zkz^j!ZUNpSfv6t= zW~gRzsvv z1JlzijkH9f?GZic&yTQ(%uiHDb?TQA)>;8-ay^a5%a;z#0cx^5wTv*BbH#Dx}?77n!OP==O`%&fCL^}5xd9+W!*zeQ4(Vxr2ti-c)*ur^M;yo zzSd|$WOT8NA|r^dE@B65Q1;2urUDXU(PIDvnp&YfpGwVhe?0}{k}HQAfz@`tkA^mtki9Amtp(F+$E(PTkbnmS}E`2H9^MMS_83Oq7H@cdV(W zdeOpJD{7Z4s;pxpjx*uhiPU4Q_O|BbCjv=N8=f3nEb+l8^aUcT*#Qa6ok)#qRs!Ra zWGEV$6OTvZdHG93E%Gb&kHd-!xzdqlSuntf#_N)CG+wK+1_vRb;u49CA#u_h>14H| zOuhUiZjYl0{7OPAVU_U4){Qm=s~0UGy*qn~K7m^~(eTK~?nvdpx(6C1Ls0~nH>Q)Fu8V3Lm< z*GVuR015a`32tplBr&dt!6vdJi%l&$9*wcE3{yw?ngp~(c;7m%#7r8ACIjtw)!Jfg zWeS{V4PXqlBLz)z*c>7#ZmTlEGmkACWY0=?7#1n&keyLx!jV9GwDAn;uiFXL9zoi`k74Y2PdIEIOCD1rVaDU!6DXsS=) zir9A&8T5s{@s{>RPneaKn`zoi>=Q|bUN1lH zoDcG*RhSiPAvQV?F)#X13@r~4ubCDaFv~?}3#XeT*P5VlqmRaoZ%UNWQeZdv;Bey4 z%yiU-2%L*P7M6h}?YTvwf%Kk{o-#j%CKE{dFsrmqpNzPPmV@r@ktOn!%i-g&L(M0v!5`~qPOMP`F1D!B%*0UQ zYYlkgR=GVka&_%6gj~zJRq0yl0?B&naHh_6?-Ru-^`3s!(zp049$)AbO(~>!Rzfo2Z^?bDbwd9`z+`lxRN~%0yMm0(`(Gs zM!#{X6zVvss&p_!admYPDC zKEqiUXE#d}b+llD>^%t-V_*({C&6d}z*ezqPc~Jfsm(PMZ(3v$ko0SY>>UZto!AuW z;B7;DQcG&hG&0F$*zX)zdIIb#i42NPd(2`}8wT=z%$A3=bdGO1^z%| zTaYGSXyJi4wIp_*NoxemP=LKD!MPKIzRD%lq|2ZW zHyKZ|Q|rxQ1bx&4R7E2J7E6Qc1Mx5#2Tf2}_fk30>>wrM>O{T?w%tZRE7OE!a#~7B z#H`icP%D3y9t%I0Cg|dR*d_}@DcOq_h#OMYf4Q6iIfLl+POvc+oZdFx;qhn9rh+8T zUA{JE@WcZ_8ac&lqtVt%*r^DOU?mOQw#PswSVDq>Fp;eoTCs<1K;E9%2NDxXM!i*` z)ojiRv&>E5vf8$FN}(cBOQCl1{B_~ z6HZMR7nOFa!~}hCQJ_*_urX+!+hC>%`j*4=02cxYcAACc4{>&|G9K__o_n3dC46`? zH0NN8PczjK+7$POF}&uDzi_3=1$|XI!pn5iD1QFEtCu*u z)S*Okg2o3>c%j5J206-ZlQ53Z%X_@f%sCh};8P_SoooVc1-a%DZSg=|dmx7O8an}z z&ou#4r9a?r^Cgia5Yry%KP5IE2!$Kl;tA4e2n=nKlA{8tQ(Sy%Ar4 z&9r3$;aIYhbyzrR%ecY3e7L_T*IOJ}x|R3sSy&ezobM5l!4V<3XhsHHNJzLP31lk3 zZV5zQ0=&x#Hnm|?_D=~zEkXf@%g!*f)v;$J4Blmbw5f@WZ!zVJ_SQ%}@6YX+R&Qq% zcYdG5!5CO_g{>B4Vg}ELhnIzI7|hs&0ejbuh2BuVta4Jafcz1xUE&)935?y6>_rJfor`MX zBiQ!1jkeZkv;`g8BhK7HZ)anG^-tI&Hb%}%9a(;}TO4WgUe_cYGT_hXaXYrLEz!x@ zBihWgu==Y5kzk;ejLR=1!l(>gf(=@2CNr8RZ&9b%Gd#0xR*o7O;hJr_+lh?_xI5z$ zCq9&z!)?Zdc1xjT^|U&`JU#QXsd4R;WUxGvhy{G)5h?F5Rg2>2%(D`M1n70N$;I`Z zsYy&uSz~e-N@=dC#x^wFBwHwv)J*i8GS`}k&{xhD(x*!({QexI(RT~mWy^$PY`-nh z7-MRenFBOv<#}I11FN{VhZV0gCBsyF4~EDMGKg6<2Un$m3&m^xRvJMa8ynGWYUV?b z0NP}dT`s|x-uePUN&oexG>56eSTGgE+-IwVQA4f63^2hykx&G%kVVIka-laE^05gU zOx=_sznCqSAU-?B_zNDRH4@BM#ZWjgi%+mSB`($m)5FvGMZ(u4GF;c0fPqWSkNDWQ zGtI1Zyb7yfQ3{1yDvPi~7KtVN#gYXQY~opF)f76W-MT z&#P4ivEr71>1P+GfN^w;a8a{+BpkA0X7DEo#N-y`KW>wmQCmb{MG_V!9~iBxvQP@@ z2`7SV;Q3~966FycTT(y|YF4YkZzYQAn=gJ8u@x7XY7ChDMnXwB>4{@akw#QcNnAA1 z849%e*> zjD00zc!zvctE_OFsTD0Eo)ik^O0Zv3+AU$cLfJJEqABcT|CB&eBL>*RE;h5$bOJp` zLNUh|**_?O{9gIY|L>`&wnF)>ga`S`5G%dJ%!?~PI9E+77HMVPRICv`Aa-6VDw^3t zsW8QKvaeE60!MF8$-fz|!SYlvrp1!2OC_-QO^)AbJ5scW_hwZp%ol*!P6_7Wo9{>f zZ@O;wZwbP>lP_R+xCZ~y%&R(@fL-*n@e)Q&3og2Q(je_24Bcs_52ATdceOymyuMX! zh=!_b^J8t}0g2FTo*;g<%hb{Ye?R)-)e_X`^$yq7MRj~BAweG* z9)uVF%FHbStATO}iUlQxypR|%z9d0pP1XdG&E!=>@9-aq;@)+w)Ke}q^&_aUDIN`b zs>zwA@fTb9WHcy||Fn{NO_W`3(HW$bR;a^VFP*F=~-C_$PV zD8}BFKpIfS*w+$5Iq*W_29N)ZoHL%LPMj(cK?=V`p>{}Epd;YJyobFZVYDKGS{5rr zZ(VI_MytXQN56}a*O*KwLeU&S?mXy_aQ?2hVHxNN2_)+#>e1t4gRV8T5P^QGT7uw( zCHpuZ5gII}ivu`j9g;1X$yHEnq`uX7Q&*@kZd*wzmWw42Sw1a;uBN#TbQ!NOeDzl3vOf;88 zb@k0;aoPP6g^o(F2&ob5^AhX9#2SuT_MVK*>A*wAxV$ooA@FxH14qV?J!auB3deml zvEh3q46i_4EvuCvx_7)A7{szUH<^-JKOAE%HeeCEQ$n?#ImW)1K4-uMo^ZuN_ud$SQFc1M=XuN(y?EsQs`^zi1>3V;g53sBj6}D-+zO6 z@puHY=r*h^O}Wd&2}nkXWg7r%udcC#%IEXffrusy3=@k4+b8J=M)}jC{S54wyG`9( z@MH-HMmf}OfhY@4TO`!MZj*4Dkck*2M2tQq5xl{%Ywt0$fvrZ&289f)ChyO2_ZpNI zNKl9H8}ilh0?sn&e5x5tKiL(8X`z1bpOHg8)~Ga!M~k!N z4jhJI>~@KZ$qGM|h}?-fB@~Xm-^?s5Cu)!g_`WTrxJ2SGLO{TR@Yt}|B_elXGwmWk zHqm&JqI-{iz|6{s``1GIX{27wRzbqjY-toG#`tWf4X3*{9+WhbGek?`ebCHMa)dl5 z!8B+!6ZHALnILx}5wx0~moIi7EOub^-3jM|x0W8!0#G8F)Xh?AK5;5#PozNP3K{c| zSp-~b-p%UhJh;Rtc>WZL=c5$3&&YCP8$_IKlSs1YAq0h8FJb;rU@ivhb=+6Oo|PCZ zm?zMH{YZuGf(?7vEQK#lyV_2WkVsT$sN>`FI*CE@lcUK+5y5m?nWlEc=dhO~kfuV2 zqDZiBBoI2N=coJm%Ohqn0Ml4D1{L={YQlI-p`b6>fv3bZ9dh8j9W3uL`(%wB%05Aov0G#`h!DWZZ^${DrKu2s8EdE=s-2KdeLCsvS%^*9r2`XL7Eb5u{{HA=i4*X zvS{G+h$D@eb)0?eKx1=H95+(*lx=}9!SKZKU_;Kdp8r)nitsYLYA=G|J6*|`e*8mg*22{#P>{ z`FA1|rc^6|dcKh;-_5aCqR77SS+r=Nj}oQti^DjsHO~GmNzGqQ4D(s`8)mk- z6X)WMz<|Wt&Q?fxIO>Oo2KJ)@Hm2+1C` zA?6@lxs(0dhM9{2S%SP{O@LB{`e6e#uc0+5%B=uC$C#1_MpU3GY~6(%ic3p5qbuOx$GAbmK1@{_i_u2+76~_R zDlcDqKvz4^+(N!4k^GM9s58;4Ysg1tj+$o9qqg`IrpAGRE)|9JcUd z`)o8d=stO_Y-i7MG%I4G{%PvsH#Cb}{PnGhPddT(89b7X*O60)*O8x}U6M}J z3YR{+(T1XR($CUyxbBFVbSU*^qHqUS;t8`^w$vQ>(OIW0#oHKrER~yw&5XQxu~$>6 zli>q`KlzhXoE&0&>^}Fil;RPija{FXxFCF&h9|A`f6PSitj>zV8PXJGcSDz0^QD=>)U&}31s!7t?U*8V(pRP$8p6_${5}Z_>fkY7n}UhvXuBAt|5ic~v)K`Y z`zt^jZ}>RjZxV|oZG2KZ@m86yPR_f^n_io_jZRbv+v`NR*`pGbvb|Z$@I2ctE&Izf)sIMNwQXe@^Rk7Z9b0681&M=|zUzTzL;hpltl0ciZ|*?T^yeK`rkE|U z$cVjah#kPDI!(#t76B@xw9879IUvdC`>8Z)%=dCRr5#cle^BDJNC{ty#%;iHaF{=l z?a0T>g?cEXe%Or?X~d^<87*}qj&9Ra8{zG|-`50iQhmArpNzvJq{-mJ%!W)DU3`;A zMCNHU%P?tfwPgLrq>`jtOE_8LxD%fDuo}5Eh2&w68rLmxDN&A^#CA!7_cJtL(YRrX zSzaj?PGe7ySrMeBF_jX-kFyiT^%Og}n5~y!Ep$oKgF{h`>cp~*767A>dz?v}5h9VO zMri?GOZ~DWAk%z3U6c9vurkF=$ux^d@dVnk9j&ZuT1Fg3qL?*F610r2CA>(2wZ(Le zxmIF=P3ZA8{7({Y`hqm_9f{PsWsMow%e)6Z2pJ22EUSLhVDU;GfrlgP!UjX944U}e z22RJL7z|bnUA=W(QVQTTz|HqfI$bH{tfp1Ya^i%gXN?Sa*1Aq{IvN|+N6J2h^BSBr zC2#6%kHMngMoPhb0ZxbHbw~7k>;zTM(V~^R8CknQN=gOw2q;shx%5anzqWAZ3L|kv zedTn+Wkfee9^o}{i{-$8P_LCeL_wzzy}kd_+}{UodIr)!pyYTPz(dRFH2v^I%z zxTsK1TWD>gqM%&;b*+{>wcU8lSVE{VB&2*Leuu%^X<%;{bb4}@H^4S`eGI`81}`Nx z*ayLycdf&?FF3~d!6a`x2=KE>jvHv7T0fp7;K1_}O0IAqjYCRaauC4M3iZ*LWPNiu z3G=9uF-O=J)jX}_6bA`B663&-sHXJ_^x zU?}2}uRBOuw-$5JX@hOsi|`9l^J5zg38}?M{IdpcX{~sus}VbgjS<6+)U%Kjn6%fR zE$MkU0o!AcQd&WMVNjNI=4pOx#!)sIOZ@o;Z_z-LB@El7v-jAGhNM&s8@W+K^c=ay zhAAsGuXoTOpumK0HDDn>O_%@1AV}VT=M1&z*I!i+4Nlla1}PO%P_G)4-bd8pD3G%*Cjx`1^B{kR`25U_%Ogg3=+Fryr3^`d# zs#M-E`?3f*3=}Drf+Y;8bX~g4gNBTyT>9BGtj};gCrO9FE;d-68qES*=Cjvk>jK&O zv($m|?3mY|-7v+yl7ex{ve&W83>C=Wzfth6p@5g6Vail$Za=yl1tX*z{cn|Y8cMA7 zF*jR_Ju1)kWluCKg|=ChXHzU9c4{XQ*;<`EW~h_bCPYKZA#rN>$BTGxjcj87og zdV`nL80^yq>s)7eSklvM<-g0&t|^iU2ODM6P8rmr^q57>(yXyQIuCA-?1@4KBN4wT zW(*L^v*B{G#c^CnAdo!~tpv|v$VmN8ou0-2Do zOw!wNvsr=sc!2V3c$tIJle4^ZCB^00{PaWq^ia9wqYhWOKY5nt7+E^rXZlUyWY8p8 z4Z4BUCWqU2&d}-5Mt-!$5u^2rv6iw5>^n7XPK}r5=Ewi#Lb)wsxg@G`ZRj}!Nv%yR4+hAWZSZj?+<~}YS zF{&;rThB_aI$P0@A?m0X&WoV=o&?c^XfQ)>hLPdzh8Bkme}Inf3?0^zh$!}uuSM%% zkUuRewKoSMls~l`&1;ji2#F0JrWop_dW>DY{Dc{7Gcph@u23J-zGe{AgbaAx@p^%{ zyxu1KjlpFIU5Xm4)FL$QUW2ow)FXMBGFI0tr8U@v25U_n3StGfp6xVfIk85*Wsu?? zi}ib)lp|#c=aM%3Z!=&aU!oHa83fgd0rwrJs}b^UUB1pBNZx?2Fkm5Hs>{D;5F~HF zMdRhUCimmw1>}p(n$raWHcl5)lHG1dNcAJ}-=$~47ZmkHZIMsugu~>+SJT;gL(Dca zA@sB%q*Zc>@cF@0HzZfjhN_{&Bvu*(PopTU3NgeXc8Z%iFhd6l`d?`nF;Oq4aWDUs9-pCy zDqEgp{FwW>$ERLAH}778ZPEJKcS)9Y~(}t`F|>xmyBF2 z^`LFNrrHSL8_fD0OSNH<2pJOA7Dnd)8dFc*G-^}Nl44`(dApGu85oV?2PXc`NG#e_ zaj7&0`GGpBPmt~qb^YTtY%?^7QsD0NHx&`l+~mJzh|mMI5g3=Rm%>_$bf~#ei*!+* zO$T6P;{!+f+uQEN0uJW$CW5^eh%B=}v`j9G@TY5Z`5`(^Rv&gpjiSg;2 z53^A^vdf;LgYqz=^*gimIPlb-r94yW3@yXgf<|jifP!o#yDM8+Z zI0b27p(%z~1v+bKtOY{4X%Zlg-B=_cQuMVa(H^3M?*sNUTPxwlvM}3bha%L5c8Ia- zC6d1`+TmR6K_aw3Z(2oWFG`Xc!SN3yoB%8yf1d(jY}KH&7Md>ONysXDPymt zpi@dqOQx_xDQHniQQ_2L)~DEdqs3E-i`;HDDg`brb{ChGv62+H2zOCBbqbrGf)^J~ zn_5&_%seT$yJ(ubq|nXUQt+~pva%_KWo&Z_UNmLu)Tzbza@|!aL`g|$soRZbcXtXg zWol6&bh+8HDMV3;ySNC-%Glc}O!1U5cS)%mPxI>(2K81pwQw4q>7Wv8HKFcGrn-yD z@MOnH6ve2BW4X#@w5<{QK=`5BdUIVY(PxAa6i>0(L4evzw@%{mZX!^RH{MGmSi|_1 zq$A;PA*adfj zgkwF9_ra`E0&)5lSuYQQ!RfO=r%04HkRXah(=iN8**WQOV-yDoU6zicN!*%_qCGq* zq5KAC)h%SNOCXAeuLXXVir~|WdWrj%nl*y+CB@d4ED7W)c*#m7)EACvvNcweOL`@Y zqI2TdI9tTpB~%>rRmipgTkJy$NF^Figw0Q)K{WA_7_{K}hIr#m+NW2j-LT zHt~I@P6=vE_{G^K9_{$Ui)=~g!X|@jZ8`l|es;e^^Dsdizv#go#MtwxOcHZ5oR!$x z#NJD#aFl*)r-y>L*>|ZNO^;*En6r8KVK+mjnU$r-C2Bl9CqEa;a~489(dPRZk_6gF z65kJ4DnoGLCREexE=f1XbSfs|snk?dg>V(02x57f8U>;h}!^acYsOc68v#~%B z@5Xml7^~B??=!$o`I$wWG$q(J8xY(3OJ}6ZcChv7C}f{bM^~{SGt(5T^0AdEXfz)7 zCg<|gBNxp|OAtUma$Y(-2k=Aba1-D!)8QcCg4t=hs{seo;ig95SEl0ubaXGL!*c)+ zs!UUk&-AkDbT|ljeL7qX`0jMLsS)@m={UaZ%cfPO&((lrG%AjS|GftAV{IaBVfM2cxhQSo%e@rI#KH??2AgA-1>%kP zoREy-y_<~}n0=j!RwG$v4C2Z~zZ-Km_`m|Tlf)KN1^urKOTU@bO~ja@1euwgjwkDt15 z!7>X0V~Eei@dMeZT_o563s0Nj(c@SoMlY8&h|^OR;vC1QKf(TB;draTRx0+*DRL4H zFXNkN?>se)SR$szg5T;FJe~rbB}2N74+w}iDF7$8g&XmTY}H`#ig*pYv`NmvAJv*} z8s4vs!G*MLh4z|{Kdi-o;quVII{^l9 z_+wjRKKj3cj%fUZAo`jDe2^BW78E4nz5;yL-cw2QB2RTxG=!7c_dh0?(B;7ZtucU) z|2DFz;UAG{YHAO+JZJtO6}6Nl`|JnF=1#2R_bfhKP|3gBJREKU>TYiCK?+q7D`HRdAVGTAYljg)E{6^yqTgAcRn8A) zg|C^0ccXd`;kAS!mmE%p%|Dz3a`N;bvnXE1+Irw;Mf~u%K>)V5S)XxSC110bonhQ{-@#h#C-FBi_}zx;bv<1pupn^FCJNFg!oHMJ#%Yo$Y(4zaXKQvV_@J5+D_TcJT!xYuL{-sX3u}I}smL%;?e^MErp}x`TgetWNG!y6 zF+-S=vvV8-M0WU&2(=Wpu){th^qU`kMW)PWyCoLmdIXu6(Z~B+hVJ z04H1(H6|{{Ca$ z3PkmBHJnRGoPp}<_DEz(LS5twNu<&nnGFXQFF8Bm95d6l2%Xd4E+I=JT&j{zMV)c3 zDXHP?eF-xTIx0TT6l_djj^Jy?(neQ0iYd?^By@g)kFQy5lbJr0m>;QzBdj^(<6o@0 zPv+IbEAo+Mpr*(_LerNDfVuSt4U@fW1PF7;&Kgnia zV3W5=Uue)geM1?=z46||$l}k22z5R-0@<7OEHoW_SAfAtAJgI9sm8 zEbe~{AyQ*2GVekc!%%MC;Tv2N`6uH$_79ksxf3lLU&V&j&%uYHe4xPk{lY~D{^Im1 z?6jeCJ87_nW2(cLK7U~4mI#i`xyX`4gGG|7bgmXd5uRIKzR2`doxx!!v;<`#kKD>t z&QF{iP2xBd92!1fAR!YuQy_Xt`8iwn>KKmCYO!cMq%-2asF2LFEv?|QlI#sDDqK4Y zFSdws5VFr&;krPeg?TPX7uA}={Z^{78CA=AZMVo*He>!ckP z4Rtu$mhH7-bN%ccfuKQ96|g10`IS{tpx0Q@1U-VIF5{B) zu}Xf}*-7G>roZsLpDwNto~1Rtc7K&vo!TYI6|>)oE8KW1)mR;FjGxfknP8(Y=NWK? zC9G9kkoAK8kUqyPijbGj zTl#O)aiRZj=>+W@V8{Mit36W@6_zcr#p|&q!Y)XsP-E;-0ZU$=4+X;A3$80I1{$_R ze!*FdLBpt~k~<8Nn`O{cSoVeii!>a}+ildN)+)UM(c7t_Z8>@c4%jh#d^`F& zIYUj~tX7&uF0-S!|6cIFu;Zy#*dOc|;~?4p*s-F<*p%z#;^IY+GmOg+2oXf2Q9ZnQ~iQQl!Ep+D_}dw_w5)A%p+t*vwv%o z>-+>Zp@iUr^05_m{G3*NgyUm7Ml8ro-D9JaQ?ong^Do<-*@FZx^j{AnFc(jgmG8C5 zXMTk3w8Lv~JpWsE1dSm_++?E(&rRIVVh0vko$o*`!g-31*l|RR`kk4Z_8|0kf2l;} z(oW7mya^{?TH5TbJ;|7j?Sr1gEDh`8o6Yi|)5V^FdT%hl8lU=Lx0no$p%)yt5~60# z>Y3LccduJ}R3ly<{zzMI`vH>d6G@7yW>FKXxm`}Ey?Jo&)<@ZM64ex0UBpJ*VIxal zB|?M~jt^!&J6`x)=(J3ze8^6s5)M2%KS7A}z0)QW@(_9PxfArpvm`!b=6%{-W-<(G zahODFr-fgN$0!Ym6)P_@q_m~VV@+=S^ z9N%}Z3FGU-q2w}tjs=d;6epKv-e>Zd%TOlV zd7304ZeSLjgTE>b<}1TDro()p^sO`;a}CS@NBrK*UucJGg=etXj;X_&c)krmQM|Tr z9UZI9Mm?083y+Z;@~8=mx?B?Q1w!;y%k2_HvcgKR#>dPQdU0cHZ#v3nH7}&&T13Oh z$5Zw2p5%fwSQwYT+vB=XS^7k(Hm!@{P2;wnSZ-gs+=Fm6jd)^45@_CDIr^ zxZ0BjQ+N198oJOM6Sc7C>C_xRp>IvFEzhJe{7q#qrx9i+HRzA_iL~)lYZ`5I%Gab( zi_nDOs&6MFO93=&U#f0hLU@-?bL3Ik>>fvUX$bVtXH%8yK@hPt2JhEuc3&C{h13P6kL05;lEgwhzO0UV#brlr##nNNa`ewbZ>y7!L)X~rta6_ zlMR;lH=TqF$Vw$Z=}7KGZEm8wBiJ5^<(%o{c}Jq)y2S80PmHfezAbAMgf{lAcchHr z?;1xDX#~96BE$zFTIR3VFzDgV>#r1V+Db~}=rzkPNLAEal# zYg07Q^egPBIPVLSc9cF^-|Ik9r~HmRhcSEp-)#y~iQ%>|)g5*;AGsf}W2md&Z4TllnIX;{%%v#Q1c9 zJ(Xl<+Yy$r`U7?nu(#S!{_`GbJ}jU754&>lk-6WV5`**0?MOa8KVZku$Z5cbHdz@1 zq-72)AE^JrmK0<4SL`@*xIXwJyIgrvZNz@6orE!Hzu1n|N9B5tcd#cR(SeTt*rpu1 z9y~G@>q&rj+V|N>=p)5{*^zt;y8y~}~6D!;>lqt^P714qUy=a7AgjK&;s5a5sTItNmJ zl7DsJwUNy+|FX-RkNo3~R0(_2mJ{Ru;h)*4)TaQA4kT|Udu>UY2)tv*@cSS6xlL|M z&FMhB9d8WdAGKrkk^F!!Ox3(67h{jAG+68VyBr9kVI@r z8e?hPY2eI377Y=}M=7nCZI=Xe+8k;UfOxQBNH_K#^F|A3dB$Bp_rxlHxF0zBqZ60mwJ-phGJkw4+Rp|V)<5-ybXXetjOk+*L#It+b*jYX zPSknB>vgdcO(yCY2a;Q-4Asn5RxAw8i4Lq}lj05{+#LPZfix`9-y8%qBXn$E`_h?1 zpCt|w+R*3n9%*gp^RCNUlz#%odOXX3*?Q*y`9_yU2On^x%O5}iBI5HQTpFCBTZLw|B&xgqL(q?xrvx3EM%bD||vwAx9A z+oIn&v4%1FyOV@wjYc2kP(;%lEprml?9uL?dCeew=Om?Dq|zZyB_Wd(c4Bp#bgh$s zWRzZalHpeA=%Ee;5N65KBdyz|8xJGJ4O8!OeI+0|YMjhjj zyPSD3SQeq{z>(O}}zr$uhlQ&vCod?^rWS zNvp6*v+YUACatlT;1=mNd(N;&|FGvZYjpf^wgoe7(W&+VnkBlXCswmVu93D`=vHW& zJ`BSS?68-xSeQ5LWvuok zZ;Wj@Bk3mb;MJKb6&#*4Pc3{c6 z{Mnx4*5!z?W|opxVO{3hlah7mwwK`6{C ztV^$Pwpr-bWx74hU(PmrPPZ;M+0&ABdDmWoTbEJeZObLBORxu0w=TE#D8p~yhzZVl zNYA3%SuNcS?+Ko$%H&>&k{8(&o)Lei9pbwm6xD^^x;7~$g zhgy21bxU;TVWjxY997s;PLef>Itju!-0Q@VMLOg}l1<7ha>(AWO5PqMkoBcK&}4p| zcjAdWuGk@WVV&xnXvscZ;Ur_RQ13ZOS#4BNi9>lLD;2WJNISla^{=ZWk%S>&+L^yd zyfv&-TlqT5Z7GML0+xs@%}I_lH#KKD(!$o<=g3RO=3kCN+}cbmbt<7@ZW=1AjJ zd(Dxg*L+BsQ}*^&nma**F$u8 zK#@4YBxFcP;~t5>9X!sY)J+M>mcY>*`Ae2B6d%|LC-Um)t^e+60Yw1pHv<8;7zUgiSBmE(g=OWhOPXm6l(f5{vdt&(`e<}OYsJ;v?4U} zG@i+gKdDObV4nNwb>ivtnf^nbj`dcZZ(e^yC;X&ZwdYg^rFJiNqxM0m4*L3&2yn?> zyACh*4kLm5VmpdIXNZgAGm4FaGDiGN&l!puOxy=tubMCq8s={~g}$>+aQwB-oycEn z?QMN24c6}N8~#NusJWk7KV9UDoFd~{S+ccNy(^72KKebtW9?)Q5ejvJtH zvyBoP>a;Xb8;a+IhJ3xr#mP+2`QlvPvo?gL?=zj^du;kv8X42=BQc#?$#oRiQks^f zAo*uH@Ii5$FtG)fzIZgjPp>LwSM#L&0tXbwIs=i_>@x|&(<5k66=g2O;t4Mw`C&`j zc@i9=gZLhjfHscwonxk?-5+%{59S9FiSXS(3SXOyOYF@On>&$?_etQ~r@VX|<=w%) zb|6poMxv}}u9+_#n?*aN5H-C;g6V`GeD+{awJAwmZ!#JVHL|NEwALF>1T+Qn=b6%2 zLqJy;qi4AgKiIVS_MG^B#k~@Xo;VWKjucZ)GE)h>9^ZJ2#=Y@QR-VqG4x)I^5)u<2 zZAi-YNMIfR^aF0f6Js{i765m zZQ)u8;&1o;5|BHQHv|31xzFqa!v**n$c1VX}lNQKCQLqGy`=NShhRGbeDib^RFrAw`8 z@EuJtU}ozLhLV{0)4+8LhBMUI8`3oy0_qgMNXMqI{>w60fQ~psfeLW$X1+M@kS(>x z>$Nl7*_Ek0f6jOQFZSL%PR^>z8$Y4CH5!p%T%wWJw&Mb64AoV=g+@ry1QI$44HY2J zVx_vey1VS|s-mho3$1`=R5Yk)yP%267(vI3V>FI3#s!UgbVQ@$5}gS~9VNaJ%`l@z z$M<{g_MGRb=aPi@{^tGT*Pjoh?)Q7{x##Zdb1zVSxn*$)mq%vm!+m3T9)WJW&Y-xc z7!TBaz&a<&<#BXzz3UCFF9%tLcI*KM)yqXX|9T^!FF#cc;D;^7Wx?Ke^Yaj>Z&amq zHyGbaQeRAJsHhCXta7p`H|@)f|7d7}bD1I{i^ zsIOU!t1n-TM%7^>rCw+Hv~{VA*YGscPc5MC^efS83r1Y0&IrbE^z9I~yntjc(1H;u zxZ)cb6ZFauimm`tpr3@W zmF1}_J?&-E^BO!e3j^1Lz>La8dUXg4vX?#+A~-s1>mwGubgHVJw6lqM$G8a*Pcd9p z&E@Hj0^pKy>4Xt*K7+t&^zsH)+gGEHH!wOnHTrb}!*Q?C^Co5F@!c$yLP%z6i0%s^ zkWpFql9Kc}%(?nw3nACFOj*iYv#yWc8bZ(nqa=PKgkb^Z=@sdXh15GG|^VkZEXNP&2so2ufdA zOBGA03S+{%B6HN$(y$#(jTb)37%Cj5De(TdU|afE3#UbM-jL*U8u5TEmNmldnEy2{7@iW3^K z^fk4@FkP_O8-`l9JadcVQ5bXjrd=vVQCt#^_jejl4F74x%|^ozPX=^*_zH{RYvW-y z6^Wapb8az`7FDhHwkUc7dX`16GNRna>hiwHLhRe77p>ST1Zj|6SQs%E4Ai-!yqPW3@?7n%nBQz$cd(`lchSCj~#_)y7U+3QbB~8O2RM z{mv*J>ct;vU{x=6$!j8kn2zjqQC#eZV~)QZ?icM@iRuFL_fWINgA6 z4PZN9a9jC%!yk6I@=;S;q}ce#nQa)nbkD1|T^(4qUGi2D>Z3|-b&}c+ zHOt1`Hy*{`bmDB>351{VHlEIw^7bJpy`@~h8#QDyjZb_n%FgwT>` z-`6)1#!ETEtVR!Os8@R^>=qEmo13U(jM;SH! zM!*x^eujPZKm%5NU|^wCMw~d@1p;+oT7U(X>K6dJ^TJ(F zmQ71UDN^u^fCF@wK=G)NlH4aS1057lfs;->x^_&U4xG~!L~aDvK5?3Jq!$X@CPXhV z^I!$GKrvCt*C#94WM@wbk2rg%B#nEhZoC8Pqq=FkkLsj7J}OQ7eN>7L`=}%x_fTCu zG_N~8UR_<(=A$~O&qpQkB6PgM&K|1ysBYTkqdIA)kLsYkJ}N~Ad{jFf@lYL0DA5yd zd`Ay0@KIfq_EDWU!QfGt#(UBps-31iRC)=`_^58$<)b=jpO5OGgFY&SqY?2IrrT-G zl6We$gcka!ZtC?>os{uWX}lNh2`fcgeN>XRd#Ls$w8uwv(|#Y-MTdP<2OalOX_|Lo zyz%Yr)aId*OQ_FBbY|#D>Y!~t3R`nNDoK0esg5N*bihY-(GefjNr~Rr)aY1} zrUgDKMQILR42{&s5I^JQSG$PLv=5qgFdQXJ_`Mpk3#?DqtJg{5}#1$9Txg1^j|&-{g;nI|K+3F zX{(Py|K*{QJ+#M1q5twxopjhorRlhjO3}Qf@d=eoQd>NgUV{G1N1^}nQRu&X6#6e8 zm8P9Os-57Gtn;G@!%_E9P7_fbj8dnoiN(>|)3W_(l^ z?eb9_w9iMS>7b8lr(-@UNpqIRClvaWg+8i_dVN#}WqeeM#(h+hwtA?}CA8f~b<-Xn z)k*t(R0kdQQ7Jm^quOa+UwlHLyJ_=L-PGr!x@gcxbx_SmrD>awYRAznkA)Z?dZ;wU zhd!#Cj`%2y4=;@mE8Rg0d=$oqJ__SQ4~2P3-bZ14=%X+`^idce`luA`^HE7U=%LUP z9rID$G-pM8Lg8W6g+8i-dVLhuH+)n(je97}Q?~l39@_4sx@eD&>Y)8T3hNs_3hNv3 zR0{Kyd6&f|RBA~#wfU${>hn<@H0YyJRP#|u+UB9q6Yca--L%(7bymREiRp z$EQY5k`{OZYAOs+0Ems5Bk$QCL6pQ0P+_R3{zuQE58nqf#`d-xF4n7J4XjH@!Zp zn=(GClg52i2W|CHDcbI%lC&qDYDago-$!-RVIS2=$9+@>&08ItQ0+@n)aIkwsn0{9 zyBYLR-Bj~YowUtIVgBW#F#qyVNjl)6uxWC{M`8Z8CO$Q=EVjT$VSMPL+Ns||p-;*C zs2-a3QC&3SqdI7pk4n=%AJt9=Jrt%e$9z-|%~>0tP@Nbb`lwFo^-*cc_$bW3d=%zi z9twTRb{~cDp^w7&&_|`|u#ak|<31`$^RA3fDD)|9J__?MAJs{NJ}ON$AJtCVd{mNl zdMNZMdwo^YANnYa4+r8?BZcvyheF4Z_E8ug`Y4PKeH6xrJ__SQABFLuheF4( z&qrZ==%X+`^idr&=c@RGN@9HIquQz0M`3&zPbJZ(jQglA+Ulb)KJ-x-ANnY)&-*Bh z4?Pt6l;b|Co90~|n@~xtn6>#R>@WMM6b<^QcB*+OOkuY9D2xw%R2S{_QP^MhQAs-D zq0px!GV!U=)lCb06vl@>s)PD{6vl@>3j51G3gbf$g?Y*@ABFK@Jk{BQ{>wulQ;zv4 z?0>C`O{h-Z|MF3&Umgl6pYc)MH14B1X{(P)({>MqetD0N>Z1KV3jLRl!up1X>OlRv zCO)Bf{^g@^8p}uF{Dy}@hgkDbU9`R0nopj`=98A6^%mP#sH9zkC$x zmxt=a+wus-jh&~D6IAD>WYvD{>KKB|ij`Y5b#_$cgu-4LHpXl)kyDC~dvDC~dvD9pb+6tBThqp*G$Po*(TJ?x{fzTu;=zdRV5Q0XPuU-nQvn1A^wtk3%>)GrT(HHU3J z3gw+9|MF4owB19Y1=!=G zu)pl1Fh2BA7$175B*up?jZdf~=3hPv>+?Pe>+|tc3geBMkHYxSM`3*Eqp*JHp)lS! z;G-};^igR_WMfk!g?Y*X4~51d?W4M=-$!Bo<)bh@^iUX7%=jp*ANnYqKlD%-IUMv+ zSl{qbSl`$XpHQ7CTIiv0VxiYZVSV05VSV05;e4-$LgTRAM`8WYM`8WYM`3^2N1=Xs zs1)i~EvQg#87N% zw4-rY;G?j<;iGW=&_`i>=%LU!O#3LT&-*CUFCT^T8y*Ua7zce+Hy!g)*k8`aCsa53 zFCUepUJr$KBjck`zkC$xmyg2vLl4!7^HDwu^~*=K)8Tk3*^Tx2c&Z&u%DmzDgu>EC zn~%c$%SU1T&_kg~sre}MUp}gXcE(dl9Ch0pPqpKFxC0&vlaV7n3g>$Z@u`u*`9mLt z^M^hP`(GXk4N*RxN_KV9bUf9L(?>Ht3g@GIRFd|^Q^_uj596tJjBSqjDAcc!_=HNL z|B9!Q=qr0Y6q>J$kHY$)kHYxSM`3*Eq0oHo@le>j+wY-z@O_Gp!uehwh5fJ5*n~=A z*wf~tP`?CqS$SeOldl#lbs7}#2;em(szo8%7C}}|(atDTr@c{Vf(}F>Iub!vmBtFy zVjUMuB*ubhu_c#R`4X805fopuPL@lQ7BI)A4LwwQ7L4jR0Rpzf1%cU&7OCP6Wf*Qy{XSI~QZVc&?%~bfhq&dYPaV($N zf=@v=(?UUASx0JSui=a5@;Tg`)Z4(V$<@aw(*Un7Z!%uS8@N@MW;69%wN6{(C|q<~ z$DKU|+TOrk&WT!>EM!+~##MpCw5LJh(!xk?YNDQ9HCn>0c0&_|Y+re}kX7IQ(*6eV zWfPUL+)x1@dD3A)t}U1HV|c$Yk7SbyjtiO9OQCxX~+63WB2mI|Zs!5T8Tu72u`C94axV#sP^Ia6J{S>_M?SBH>(Zj1uEPY?l{@i!Qbc z1hFjBw`x^(rL!X~xPdCJ#;Vr&BE5bAUtgrWa9)SZD2-i*f{MuZRW`z5iQPfbj zf0qE)6{}-Y_&j=F2*Y>4xzRB?7y?lgawR$@u`vWOXCjE@y0KiYl%s_bDojj`PEoIf za+5{eTo^*et3?_QA;s*qMcl-*H3A}tN!lI(R~Kkc2pS#Al{V#Qe;CY7lt<~Xz%pCV zX65O42%0F@i`ligQCKu@GKgDdsx+J{6;RLHB#N4p&EQ4T0KI78?C_uNuizECOe6 z0pnP98CpCxdrmos{FU%DP^i`zU)YFGLRoJFUR$mTWtj-Os-DBOsx%&fS5B3$;Mb~So|!xGO8;hqEB#Y@Kpx@Jp`ulJ&P zl_1({&1|jch1Su*riVbht=02^4c>+9m;9O2Cawc4ZO2MkmnZ)@Wy( zKp$>oD{d^%-Vj+rhtyvj&y7zN=|G6V1-M0Y-&-(DIU)(ZO?OPiJ8_eUV-B?yS+O95 z;Z|+rJ6X;&k-jP`}V$)PDa zD3L-1@t|W8!k7gmwi-lhHIjRwaQBZ*4d*st#6!IywEQxZt4s)*M1M9OLUOo%c&t8F zq^%N05{+e7qf~~#dTyLs_B|o6RN~fXe+VnG!ovc(BDYaDo5uyXs#H@WVhqW6(1-EP z7^nBVS`gK!h;EG9LK1c~+b2=9#i(l&T;nIX2n-5xWwDwY<%rZISQx4nHqkZ-<i&N^7+*X;R zeu7+TEgD7RtdP?Uc^-AYBWuy}wxpdN2;TovXcIhnB9_cL7e(4;c!_rxx3 ze3E(vEGPRJ;J9k4$XC7BE10n3MW-UJnJz4*aZtg;HvTy+%laiH=Z zFn4hlE{j?WiCPxbCXZI8LVJ9oT^$k0{XWTbDk6C}BFR^QnLE8AlE-5t`GT)TJLkPT z9HroTv53mHh#;;m(^rN?qDvB8K~_)4`{&9z7M5*Nre_)xdz1=m=$Cvi$= zXDp5{pM}W9HG3$hVZxo z-*h%@0rplbp^uoch`W}RJ?^q7UkN(FuZhq;3k9iyWqOV<5=y@Y3 z&*|aLbkESpNTFkRI9C`d(87QjN_D2wBZaP>k>T_(z6}JUa%8HW$Gw)6v2JA^BjXl9 z1+A|^P1Dyol~X0cUTk`B@w@X1}1Yz>XVKdGRTO%i(jw!<-#-SV-W7 z8Pv0JIxaBt7!9ZUyjKM=hp1{X+QL|k`oaJWDmSiil+XU?7bjR}&C((%w*hmdT|JIu zp6bEvkWj=XVlKPW`V@~4vBtd?$4e6Y91_ZT6j?JxM+|1~?R5QhI>ky7TX893VTAWF z#6^eg-D&J23M%rNQ=|~3g`|jHzku@_@%RKkFvm~w)HvjP9E){3%}$3|~w=c|GhO4^kj311_x&LMESPX}bmZ>>^6C@rY$UXuq7B-SDyxvBR z^<}~^LJ8E3H*ikd)-bg$wThK(52LFzx+jeC8$)>&m;GVF#PBds)xULg7e@H6kko&4 zT*yx$;yvqd`6kVKwMY?^%gg(yO+Z1V#jY(rKJZXDH8~hdC3}|O@Qa}I>vMg%{8)ju z2|NfWnZ~WHI|YUDA9tyH1vHM^Ky_buK%kK_&uMx@(8E)clUpe9n&_Zf^;)z5c)7NC zbfP?@E_ZEb?`aLH_kq~muibc+1x+O7;j*2Dfu_R{Kd>_shOlh5OKU-nLCX|2U-tp9 z&5Bc~+U3PC$-J#|Q2P?q^%xLkJlY*h>F2yw#b6nR^t4d_M)zU5p-mWpRW}t&9E;vY zk}?{b;C!HQIIKO3V8I9;Mah6*Yxs)&RXlXts(sX^Dm*=@sowI+(u&Q6JZ;z1xr^B2 zd5hJMkOSUhyae~NrrL3EQlm(V%MiKR7&fd91F{C#1X-aT#DWw$|Kr+AKh`5?-tB=b z8;fnxG02vyX86$t9xxy*s81GaHLUDWp99yH>nk=FYuEvIkapLcdsS&87922x1!Aq@ zkWA9bz;;5UsGjXwTgD#QXtjWgb@yse$% zhmAsvhZi{D%8`*87O>J9fH4^!Tk2=I`orMzDYOSDw?NHI@`9=QNYCP2p0`1-#&!z^ zqtj7Vz5hTnfNS+Cp3&JT`kiDq4&UtZQ9ZQJM|IOdABEG6J__Ua*L%#s*DpQ_r-ub4 zvLPekn%br=VlW>)a z0K4$DD@WF06m(pW72cgU_`Gd_CvMKWI>5H$=)J%v3L|(ds*pn%eF8=qQF%>+0^~)@ zNq+3PCcqKyZ__C?RofQDyE+uUQ{XUxFKFH?ATE&lfWiTwc)er;ITS9yNSal zE3UkZW(yYQ2{N<6)YT^yr9^}=RmK?eshZPJ#z2^=Yhc{^!~{o;g|`B5{W}-SN@X$s!$Tje zqZ;vZ7gZ`4)9^EV1H8kl1~wrMojwi#6*5Q=?Dk!TJuo$Y+HZu^E34Xs!xqA!D?CiO z96himjvJy>oY26$H|w|~M<#RXESSdI3_irOG!69`2!62^Qz&V45U7isZ5h5PC zB|g4}AAZKY)4UxERGn4NaZ!vGRhIn?oy*|Y~7Xy`e>hkO66=tzf&Pr(+@%*-2WI27og_h zU|(+H0(3}=>6lQ2W(JKTX5EW%Z^xXOAkeYl>f#W&P>=zE!@s?P2>Sw=5v1^in<@km z@rApj1u1;tB?Li4eBrFQAcZdsfdmopg|o1N6u$5!q97u^I%(cpgQOC^@Fj;JBEE1} zg&+f8n9B-0><3@?3N8o-pZ5wp>?cKeaIqzOF-;3^6S-O)FZxbRsMka)G$S}OZOrC2ZpP=m z@dWJ?_{0d$d-SUI)x-5#o(>8&UzsWnXA8rd@uW+T2En32C*M;)=j{Q->!92zqJgG` z0?&_@mrZQK8uVq{oKP<)HL7D-%1FWXR8N6l@Z|P?JVNkmK8$abcvpv$-yX)T_#Odc zkHU%X593z+u!PeoCw@GPTk(1C2%?X^K{Z0oPg@LWJ@yGM>}xQ}ST8j}ph0uNYzyO7 ze5ZgXaZ;Gm73s@KxHn9(55pV?Gs;s}2m3h^X4sD=5_bhjV8hYNstdvld(lKXOlZ@( zIF$Y{qbyTIK1?VtDlXGuf_*4_CX6c&Ne*IHm|zbI-zRWX+9CCX5iazLgK?RO2wWm8$?cLoeEJ}p7rpF_4UES@;o}Pw%>8%m5bh@*%qoZL{dV55yy{j8xwnvTI z6A|l4BgkabwEYpOj`k%T>0~tF4o9R?$tB(GozY}F9+AS%Z%=1;)UJ8&3g=d5sw34C zHLEQmlgcSNn~iwL!+d7U?s_Ja|ju1@57M5Y#zNvFEIq84q7$h3E*d!h#IjL7uh zy2MCOdm|zp$t6*14n#y!NXCekBN37IWJ6g`Y>y;!Ln&Vnkw`U^?{q{0ZCAvQ{)j|F zna)Q98cOrD5XjXg(S>mpjs!C!gep@*INqi{J6WEqR&k6jBD_lo8+AiCBa$60t9Q@B zRdb&ZHdBe1@DB|;U@$4*O_>20j!Y0eIj83yJia$y9o;R_Rp z_r}01o)Ng16psrSgK}&;v+!1dj^evY>CE%@I+x-cgPw^jR{I5eqy$eJr)qkFRHOZZ z!mLz{|LbG?$dm^}?i* zV5%>k%GNd&F|%cfK`BujRnu0?dujr%){`g`0Jk-OtYN1>Ipk^`qI)HXX|l8EfF!sC zv5F%CeA#4WxPS$0C`r60h_r=Se1X76%Z1HF4lxbTPJQhpu5t3(FT7&WAdlmZH&I@I zBe`*Wa)cLorv=DB6$^W68DJ(#VB#pCNgLaIFnir6cnr$8dT~4s3OG0XvZ-2q1ZRfT zX@p~fLQ%DOYBCPdo%7xxZB*j&HuU5aEsWy&d{}Q3W^u|06zeVelz=Xhm4me?h$03KN;b#Q1%NDp_od-x(*9wWYaK|(QyGm7*p%o zmHjmDZjlfLe!UT=SK9 z5#z`ds;sGBkVVwfp(?)mq|*|5-bkmLlNXKZ5OB-T}+JA9)YREP=wB_ z{er`&u)MKQ-NIRNSl}31;`494J#k#%Y9~{}^X?5&fOUY{q?tCs3>P;RhYK3-6S!)c zH9RO_97wVIBsBq}Goo!_H)_gch0We6a9)lo4db(3fx)ltvJMDP52M)o5rIM!X8^Kj zEGY4TAa?lv5^dOIcDS&S76^R&CQ1uusZg(!Cni>*RO0MKzhG3cG2=<@A_OHG1T!t* zoU1onr4XedmWEw=lxxfUc57{B8Y90lG?Uv6Rfs1nDwyc zKEb2BRO{=;3J7;%_&RK`X9|-!78(>nqj>~Stq0Mp2@*SJl{f|4gv=(^UV~=ZDbU)c zLIJ151aj`8(Y*PLAM+~&TE}4|en|T2DSRJ@!Qkb6I)MUH4#2xUO)yd@bcsJYA{f~~ zCMofuAo-9R6aimrY+Nvw&(J+0QFlYJu(vZlebI zmT?F)2watyA$)U?Ds-eqa2-Z^Ndae&Ez^-q=R$eEP3Yp5mK!r=I2M>_r;o(FMuJk4 zX|?HlK%i>!z`N0OM4+l0#<9y$N_;p-i8Y1E0W{j!*u9#I$O1v337SAVStvmO={2#1 z(sAqxRT0ta2$DNPeD+zOyZ~Vq8h4DT1cv4YUt01*@9k;aurnhlmx*f7vr918C+Cyq z%WC-Wv%Vs=Ds?&ba{c@|<_`+KID)l-)jZTWCeShNe7Q)}XwE+b2?UT&V@41xdQq>y z!p$}M(TpJ73Ip(Qft%5)9+`sMDmc>`0NpN7uB6=baW3u=xT*V)-Y?K${$l5_061Gz zy*eHNRT9tpNDyn)3%3b?y`oA`AF$_*U;(ousar-GR0w~MQy7v398X3G|0CE*#0?p# zb!rN~O)wbwsG`XY*G`GMqLJ)O;?2o!ODbgP;v<%LYsuSk+f7EN4?kJN1<9aGCLmUQL z4SZ={pm9NBRH;TudCYC6G7`)L^`Xd**M@Sp!%y$L~4D>8O zE;OC3=L#uxn1hEi%76hcb0e6*0!$g}W9Vw$E#(dNJ&E!0>=(Z)Fp57Cr7Hk9lfnk9 z4^b>U0t7NBa3%a2Y`@Xw>+S4J-DtmuSI60Lxc+^Bqu7sPuzzO^is9v9)|3uwLU>Qu z9?=ABSq!!o*dX?f!wR6c$i$Kcc&n0cfZwgvG~l0%5r-w;X1F6P4fqJdsqO~+aXWx_ zMIs3spUZfA1c#oB6y6io1NmziPbI@R2@u>B{S1=w?130VHgsp-0Eey9eS~(LV4lN&MI2{p( zny)G~9gT_bGevYYg!>o98}&T%J%A(92sX`ds!{t|g-7IJPLc8U6e^gxVZzp^zfm5- zFy!B(;70NL7;jAa?~fEdoeKiUSlqoAGEn1wGx2 zN3$LBS1Ub{b`A2AjCVEazg_8xX#(D_6h+Dv0{9%`OCni@0Dh$8BLxNWkEj5W5dt3O zzK>&&jwA(qoX-T#M1^Y-e5_=mBN7MTdB&qf8j5aFA+$FtdM6W|jk)%5ru^ja>-q|RBE#vLo5dr~J710&RXqfayCeodaCVdD* zsL9eR1V4?3A7(WTIdH-I8&CvU28s~^ZNk6!WMoi}-)>wK6WZG#5{K^uUQnOTeANB= zEPmOcoLWhuUo;@cfN-~LhKx_X2hMKmI+tA?*0r2nJ?xsw*ITAraxL0ZZ_7{%tncb* zc?I1FnMW0PH3XC}y@AzP-QQ$?e64}HPT`S|>x_F1w`Qtd*i4JU&Tcp{SmTwe#eCJv zI_yK$=qjKQ=$(zwy%E23zm%chhg{7c;DAu_V15rh2QC%BY8-%5xB9-e0eLI?2rQ%T zhTYoIr+yF_>P)3pI7JcANwpLpXA)c}EjKtHF6=QDP+7z4ZCjOi%BJmm*xALN=|224 z2M-qG+aA8Nndt8tu`_|O6?%SgBg(OgbQ@s%dmO*@bP5#K+uS_rd@c-;|8;eo*K)2I zPoLkS%ISIZDQH-v%j{Qu%Fffm^bm)Prp^@8<`2Qyp6s&j7IuTxXDSwBBamZzAZHX&`GUp7LIuveGq zXZ=GEg1+iO1w0xL*8#gI4HfIx;tN82X!t529iSfq>Y6c?wWhrEwoJBg>9FSOaQh2e zT!aEk&>VgTdQMiHjtWzpUYh@rXe<#LJs+ryLP`!XDM>z=d2_OA89QOCqcL%>0 z;w&ZRn_g2UZy#0L0zHHj2UxS zyKBmtKk7_Vq0WoATi~{FQUZ$s1T(CLn-ORwc+>kgk`?xh;vFdt;8&5K-L7Qz<$jgoXB z>ZQBIpOoIU6>6)k1R`vOg71xo_Xrrx>qgz^9*jkQ36#sR)s7Rhcuj*6_XPnOsI3v| z0mMBaiq&QK$;)II^8@IiAt8-B-uDLTM(JGP!Uh#KS_c}C8-WC=qjmskTu5a#w676* zAmmeRfz!WAF%4b&X%PVD3a)^mVSqLzEcS9KI7zP;B9nB@{eg!`8iLCiJxUcp;v251 z5&C5V@`yw@>3A3Q&jA?zl=vD5R12fj{P`eQeKd^D1jK6+M#T%^T}l@UXf)6Fd~g;m z7wDv#BHhq{i~@1?sGS-Vu_+;Du@A>!p8|$yppA~IC%j2G!BP6I^uRU9F@IujJi#`Z z`;0Ha&C3@nn!+0y><5Ef?7kvdn91qxi1%9Ke)8hjwz=fZBhRi$0EjCUn zYkFHoD=kj_Xm3ki9e5fxgQ404&Xr*bXPo$8g-;JpA*U_G2cNh?IJNBPZK=0lf?`AB z*<=+Xsh_ZA5tz>Ts)(PGq&7eyzckZ;+zmukVno`_V%(hXJo={-@LvZ1sOiGRre!b{ zH2;&fCLksc!*?u4Py8B~plmu%^gJd~ooXPXbEAr5k1pBxNFSer>}|m{4K21<_8_dK z@aQZ(Nk3!oV^h#-rrmMiXV@%L33}-J>~a;$^ls1iI&#SD>^&d9)lkn_q)G%%B8{u< z%5yE*{qX>eFbV}TfAx(v$yZ|HrU)T`=%t}4APV>h#n=@bJ0D1>a1 znd3!V=L_^JAMu}3ZA=~DW3Vk|QpD-93C{);khfT*R)O}mVAPL8av_Mn_>&^a2A8yW zWU5wBl@S(~_9HK>GP)fuYyTv^tKk#XbHCAuodb+B+{&Vl#Jb@+>JhRQ+Yp0I0&_K6 zpD?CrA!ne&4UigK9%0{D|6GE#3;(0E(3ad>%+I=q|$(E#2Y2fkK- z>cFTv<@J|X^hy7W;8LBUORmtlz+B8L)CH#vxI#~P03JHAGUX(2@|-W6JD-ULbi#-u zBcdK&%Tx^hKE`>LWdj|x9oJ{WLDW>2@ZSvLKxCj_jbBdNb7UOYw(#9WkVzr^npg`;{w`*u^V5+5>it~#n+wQk!l zyjfKYyyL5aQo%`L1fbkDQ*`%N;xlL5oYz=KZ%b);CL^8Pm4w_pP!Rx5E9%q3H9l`{ zJ7czq50$&XIVLO+0*BP;_p9-7?Ut6XRhm&6Z3~2nRM2%J``|=-4eM&M16SvL(W&FP zz6tK4ZNjL#7x=6_+A!A08Nw%waIwfroFH3`?|>YRj}B0zu9_-L65y-0})oTi53X*(h#i?SVn-u4njg{5sr!Y0bth<<;?!BgC#K4O_C3Lwmb6 z6LMx`(cpt}Nf$?UwTE1(kn8et&X!!X->beG)I^>1bQK`cSm<-sZwB~ROfmWz2V(aP z4#VMEAQU_G{U7}ns4Y7VyyAP@qF|3zFuIgd0aPRUnOOAeKwXHa>UCb7{ecj*82wA2 zR32eR2Jm_7?>`!QF4#v+GcI{oZYp71>TJR2*BoQC6%KFk4VO2SjFSsyp~^RSp=C7K z2DN ze%8WxI_;JLd*QYg=wUn!{TL#hfig3Qc{yM;+j5nqavt3g2fh=a)oG4c|L4CpK#6}t zFm}Zl3zE-aH&V={6CbNrO((bLcq)&FA+9Mcskxc1NJy#+;rTIntiq#<5KiNo^WtPDPZzy&sL&Esk%6@n^4qdEvquQ?oqp^+INYH(?73g)>VValws zAZNdBoGuk6`SY48`a$Q_0A}XPhuTnac;@?a_S9UFnw5?+5OZKRi$< z6$--`0`oCwl?Un z*@21pNvF>giWqh%;O!K>G#}v-h#jJ2@>D}x2(Kp{8sbQ8r{aNAC7sIRhJ9sW*U4L_ zl48xNgr$63b1FV?!zPU5Cv#xoji=;OeKkr2j+Nb(yY-Y5=z4@N^Z0UeT%^Evc4X=M ztneffNmpQc#;;E%^NjE%ry{%>!fNl=t&P(i47Ky1G{Ei!b`tg9SnzR{j;i>A0#kZW ziS366IGDis5S(hO8PxBjD8>f#zXMS?p9QDw{nU|%jJ}^^IdB{?41K;cz?c(Or;%PN zA@$jlnpsW=tpWORDXgxwP{Lmj!U6hFgE0L*DoDxS1lB9B^kN{+M&0nLK>DSmDn|;g z0S?yQwLCswni!@%4IVT;=V1|~Ql#Odk<)8W}wrn98eZH_@9KkR3pr*;?pBfb>}n?x-J<0-@pY@0rm_hJ&Cd8kIlp zw;~{(W%K^_QvuonWwF&U*!9x$IvyLSkEv1pSE%Ezqry)N{So#aoEiI!kcR!3&SS}V ze;oJ&fc(`D>My6o?^utuH_IbaqTdBE(8ygtoX`-?Q_;ObMggA%z+VYKZ4doG%0pab z`Y(hRi~Ykfp?HiHe;SB2M*)}q2S*gk+hS^}LcAJ896q5u1XE8Xd@~D2uurj|3k&xS zROzdL!pQDNgpf|zjH)8^Suj>MMEt@>9AjOspP2QZLbEv=cot*MCN+CO|I$W}|JOi=|j( zL4;N_>1@_Vf^Gn&r)0WLoJTKfKsEtUUl^$J{btr;gS8V;dap#?$~%2H1oL?%UZ~s) z)N0_s6`1(F(Cg-rX9MNtkQ0<%C`B4qGdn@6xbT@FKAo&SsazY24zemGMn(L@Dv_za zTj8>{@zr2_HtY+Z#1-Qn{61D>J@9QQSdpVI3t@{r+=$^?bn5;?5S|fb_)@^AEgb8Y z^3PO%iL0-ZrSt(OAl6)a9X8M#SWC7mZRCSiELUeUOib? z#!5I&z-Sp>;Sa>zi6-6`h{yFxBo|V&b01=}Z5Ylo-RHBru^k-?0$1%fmOlBURnTsS z8fjijnZSja?m$4xpW{=gQ7s-lQ@fk2BAPIW$ru#5n3(i8w^qOImMZrHe5 z-6ckUFMI@O{l7&RYS+n#zY2s6K;j<~IPTuTYC8t6AEV&P1_yo)pgA(Ed%lcZOORcA+!^ja z3t3g?>$D;f7+|2Q0l8AeM^w1FVeqy=hzj_t@$mPgmO9I4al%O-Tbrzn(qZ8(hHh&T zM&PEpsP`q{ZBoS0Hwl_O50!_v(CZ=~zX?eX0(9j_486=MCra8AnuDNl;wG2p&$jAx zRXqGs0Z$3>w|nrNz+Gyq9H5U1QD{)t^zDzqe!yOxU+$oIg7gcZ*cw9qV=7ONgM+_T zg|mmArCeCN(#{Sz!`<4br$4*)q$Tr>lIKw^4!jMZ%|Wb(>&r!v0LYX3{M45~#bp<+ zq#12-X@M&1hj>vI_Oo6(3=3cP|Z2OcLN&?op4fv-=9cPcXIlOMBRDlKS&hSR-KWd z$Iljl*|TR)188G|6D2r7%7yU7vFH^M1x0?Nb-fUUQiahI5Cwe#m=~PjvOz#1U*BA( zH8 z+*z#8*Kd#zu8qTHJC%fY1Kkb?4Lhm=)*|SA>~bIDewtmKmirgD7V-MHZV`T_M6K&D z>@v(HPZGvl#w!(TfY`_@pa8(uzE{wM^dLUj1d4v?>Q6ImD8x$wSt^uR$uqCm?7y@Q^(kp8aI_ z)gf@8t#F3JP-6On?j*~$r(N^9I$oGfx}kwu#yjWgOaqO944ERhw{RHP8g{#2yB|dp zhxFNap1#32A3jhC!*Tl&tCqkcN+ejyN}L5RF7~5zHoL8%av}IRlCTE_UlaoMB$j8P zy%NVrLoar&Vl+4%e;qq*!E3QA0xdRh3p8#`7nB}(V!_Iugy&i)R53Qlx43wFmt|h* z^L)zdGH>!~vcqL$AJ&Tg=VnyzW(#d*xD&s-ymtT9XH@^>3+j}oR9^{cI+c0F_t@uS zp3WR*-!=)|4C%KaYeWeQMyG%AiJZiU=*+ona?+P=b-*GYJepPx5PuZ^;ltUo`xL85d*~M;KkBWyfTVpP?Kv#-92I zEPqfwF;K9XVTX8+KU>=IKkx;`(?SODkx-Wq=71h!|Nk*j{r0OE`}DT_zi>=+A!nal zmo*cWcE4661Cj#MJ75X`V;2Gg# zAs0P0P}q-~S828Y)OQlA?A|{m{nU#=ae`f@9vtS~wf+WVy+Qav8MA3Q(g@WIOh%d)}c`_-9}iflsX9U8Z)yFMC=%o@v0>A)%&$x{D!n^1hCtlRhhhotrAXgS|ZV z<5l;-`$-45v0NOc&z-W5Z?K8-TzsF50a&S6- z!QBF73A=j^ULjEvNJc%}v<*xoBuyOf5r?F%;ChGOFdTRB!k;t|bBV$epTS;YFN>JZ zl$uP`^n=|fT0Fyj0q_|3Viw2E8X4W$>aG3N0HatP*x-%g4i5Ub@j8&Jk7<8j(EbA8 zj{xjNKoBXF>5Tb0ywx~Pq&>|A0<{6KUIYA+xcatggYm-Gj9|7{r;-+M?ytbj3nz=$ z;eYg(kn2g$3@l*JI6!sTvl^g`fLMuITAq#rZwH8F1GJ?)7Zws3eY44j0ND#il=b&9 z5ZvtbWp>(HuQ%0orTs35IQ-cQ0(_0WleOLmy%JDFExk#I^87 zI2Z|lBg`d_p8UW3yxLDc9|F#E5ZZ-+b>wh(NKA%G*obWbff9jb-XTcwQIybCRqvA; zZAR^8Fe3O_<-5WEf3s)<`lRPbJF#M>^7L6iZRlKB6*v?JmZg7n=uOGKLdXW_mtxWH zNEMO6!y(D3YO0&8-v~_tetL_D4f0Rf@;rbxG8X%F4E6`I%w!=j6w*5C;tEt_P+J4WRcmLLUKytE5o8;E*a$l#!}0wZ1Iy2`!=?rBnkEHHP>i zP_{|K=6b}Y=W~i+Q!#=+1$Yd6K8ssXdwJxA09|?Fli|VH2|PT*hmEkHi31<_fih8* zD$FqGHi_xM*&7+sBT*hQ?vN68e4|9f4UqRK0E-^F|DZ3!ZSVK$p+oG#b+s^~hyDnM z8mFzn_U{;-@dD$#u22{s#^Vi71fXx^9KeIE1>M%pw^9PDuprK7D`kB5DBTi8)~VY_ z?*NQbaeV2ovfzVO*`;_jPhB3mn>{K$Jno~Z_uY8=~hS-~wns7j1Tcs~CX4k~HMdu6A4lu~Mfy&)_H+-llht>H4c+L4X-X|yj zR>lXfE`iMeYdHfoj#$YXRzA6|`eNhk*iMIk*=1TBGEZl(J2h@};)qY=0-%$t$ ztv955E~ftt$d(Qzb-tsz7Y8Qjdz}Jq1vp($BA&jFY&8AO6bHd`BJKVF+*(>U;1{H= zHtoI+Zlg{E1pwN=cAwMX6l#ETE0w)Z>JqVEE9X2d3U5KCA z>~OA%C&97?TLEmMjJY+YNmwPq2ehalw1GY8&+6(l&fc_(Z$7oZ-PfB}H4z_3#0fki zF0bla#kaCUs@!YX_AXfRWy#jY_^4i@nK08DrElY3wyn-Un15T1Drz_4 zVJjQnoA5jIDdM{n5dJcdQ|%)Br=O{s%}%N;Bp9P{{&%-=Cm(qtI~)GAe}3Xh`#&^) zj`H7QBwL=T-A`@sse#$>X~Lg{gr%oj1FRwzV~uCD;eVF=dt=qCL>EwN>u3H%AY&)U(;$0-F0g#f3&Fn&RC0otfvjub7DPE>pE)DX7)d82Y+tJf6X=g zuW85Gvs?MmE`>~KWUfOfu?3LTaOhlPTvXFrw7=P{PPfyQQOsPjUIr zl=@SPZy&T+os}0ED+As9?e1gNy^ifRI_ZMbNr4e)vKnqno{pwzXtEj(`82uq!lmUM z@P@<=TAt=NYh-?F(1N@TkkxtgIwAR3j+c zj#1(OAS+*q_~RQFlwF6S{+f-Zxvf@HT>FQ+lE~_Oz^A*>rZe!N7+Lwb7upy;DS?*D zxbE*YXcM+9IZ6|){7xqSHDN)YkxDDyHP3&|SeTTlfOVa4Dm1%x(kh_@rp;tSIch^| zzDQ}}`|j0W;u5$myY$7@rgcCu6yANS8<#e{L__!8+RFEY^Iy|2AlNzPlCWt)BZ1|V zCl+|sy|i3nyf(AfSv&Z-R`r*7H{6z8y37Xfk2-*C5Wqia zWJ4>zr^E_^0gfN*R0DQzagZYpVb0$TlroRg_x8-x7Er}VjqO8CA+V% z7JVNmr|B(0ni}Z7TUz;{GX87&p_Y2!mR7#mLqeFB@I@R7`mvTebW1B=>7k&1)zB|* z3F7ylhJJrbD_<$1q<*HM58m3!cW&@sGpEa}9X3(akPC@2+huC=FCYM9u1m^hlelLG z$gj1`{8oM?SN$c90QT{>@ z3|r}t=y=gsHQQO$ya0;fWxmUUX3hg3Ee@eX3xur2Ems=Lqq@7brr9nHDA5bZ%HJLF z$BzoDzr=Nrvh2Ws)m{fWYX?7j%zw?Bt#&(8q{PbsS@}cGAFmOJ++#I}jmSNtNwjl! zX&I3QW-KVvU4!i54#dYoEHd;*XS zx8)icJ_-Q}xlNZQ&Idq8Z*ird$rPyDL{TvX3dJr|df@TyMhMNGm1>T}#^sCaHB4%X zakNRzAblzEZ5U}|vGiISn_uW?54ZB0-2B(%($_`rh?c3e+5)7ChUgKGX@S{+z)4y3 zM|iWA3|wz5G7XYUU(<-(e(R$)B7dD^dMcKutT8Pwu|_=~C`!lrpkZ62kqxbUWe@+E zMvO1}QBIQuvs?L9M1{Bx(t4r9`OsoRso2n>noLl$gP@E#L4~5k#n5Cm4CJldR{})= zLnCIbP_s}#C}8{=2LCl(t)TqeF>NXtElpZZ#RfimNA4O+2bV-U&@-+y+fn!(6K=aTn`1F4|=Ee+;PZ z4fysq{xc&=zPwpEKMn~M0ACiT{t}<$0E~*=TdXRMB2=MEwu#?#Kx@bN#zIl;9KO=- zf;U+h6c|c;4?;GarPDS%o;1Mgn4986b-SbqRu2CInyiL_tya_19sXHbR&wIgdsPGbINt&>k^U;;Z%eujw2OVUWYm?n($F#wdhYiG$2;5E@*Y zLv{+evH{uP5N~2xy_9$^EV7Bz@;5fI*iIySCCE}9C(qj9ayX_AcEFF-khGeb2Y}An z!M6qSU$dz+v)zgVB{Gn(@*7@bEilteOd##F&W^2-Ed0zg|5*sh;-Fz|`bvj1k0}$Z znr2t_EJ9~YK*9!Hu_h$m0o1yVzRnu97bt1~2L0B5GnemKJNQyV{%dwc(h5-G^YCO< z(CdvVa23 zoiBxS5JFfQn7$1DL>+LArd8a083e*+_G_fY=mER-fKUKwM?Ql+4Q!PS?8Z=oAcfP|Wx!y2#lgq8zPO)LkRZ_*y#n)}y zScDR{!<*H)+v(<}aMljKN>iE0<7H@?-O86`D#TSvD?^FDg(j=v=sRtE%|7<}R=z${ zd1YkQ4(Dvt&4DYst?uT}=(x>qwFqh`AREd9@3LtU)=h~+kg{yc-PWd~THTecPqvfk z-)UqZD07c!WJ53@(vt?40)N&5V%}(?IyZ>w8Bb6#5u>UnXr#r-P~uEL*0u-UXKi$g zlFmjm;olJ0XcB77B}-F_R$pm-x?LTLSZ!>a?ZQ{Btx9cIl3XdV2qm5ez1Frn@A-ex z#%7nY!N8&$R$FUZJ{Yn3x*+#W%B~Mm_6nVjLGCyGf0fojJc86;4Qs6Z4}3(%0}bVC zZw*HT5PAYz!JD%13kah<2XUzcgwDZ1!x}=PYeQ`+Y6y+4t#nN#4WajTQZ)^s9d^)0 zKqyd41LPKsh*{)oG&0~;qHOxE4?;6#dBbUy8 zGDsy(OCX|^FctiNpyW{E{jkQ`fA=SBJWK_z1Qq;*EdXx^AX;-<`I2Gvm$(nQt^|@SX=m$Mj95JY_x)d zRJIqS#N%=N&FWnGd86CRRC@ue&TL0BLXqi{n0L zf?Kr@>g(N{0!C-W>TZtK>W@RpvbTAp>?CxyE0UD>3jA65-OeAkG-7n?M)S6&P~uK@%*TL+(AL_*(R8hb(ANISPHD0lLR)L0=DliG zcZJboC+V}Dn&txhsCLDUp@VkChE9n|2-$RN`8S(>w`i{wXJ(}Qs=%RpcB>2jRW>w! zNr3<2Lc1M8HWWG(F7-D0&1UsFsGWA*O0QFDH)J-9@PyP(_ZT>9W&H71Sg>1HKO zluc7n&TX{^peXS{SY$1^`={2T&*+32b89EfUj-tz^1rDCL{5H3BXeEeQsM`Itjbjd}CUSUKBS+5C{!EyvWq24r>K`EyS$orES^0)jmrO8f=7ttXm%9F5~YINS_bhDwecGz68n&yg<(+Yo9{{DZrHbv^!qu9g`WvIVI2Q*m?5B&16 zYl@5A<!HbN7;u^*>Ezag>=^}0jKiOmuQ-2t{nh1EjK5pp z&&tm|Vk~d^77`6j$of{>l{LKuazHAr{LBddHQxnf)((C`P&wbN1!g+|O1uw{)%k$a zeMsvb3v?T=e%-Eb55`>o2;Ej^b4t^I! z{UyEzw+&_PQ5)JtD7{FNu~vI>ukpNGb5zq0pvh{W-&#$^ZZRg&y9)dai?-kh{8{;y z-&udg^08q5H|p=t@Mq<3`w!!-l;vjQg zb*an2rnf@~#WmOj!%8wB8@ofZW|^ZFCYD%gu&Lj)R|g=M8t&H+CXcR>_>zV&d30tN z2ulqP`Ua$6$I<}dqyQoofD9rAyWi2if~u|N_Oo`p-nK_vrlCYE%e&?-Xf}QXEjFU` zBpcx)+U|e8rFFSE;nMVohQ1|o+AO3XD=z$^u9kMI2U+2uGoGw63`0^EVKe^3kklH| zWH#|IBz@@@j4p0Xkkc5Fy5__{7?L`Ocl;rRA?YS->Kq*+hNSLjG9R^?wZj?^Gya?h zKS->(ZVYaFH96LJCWLGv-Fc=>tn;~2ov&2>eU5+8yltKk8wsp&I7k;7uwo40aj z?FbIGe-RQ^e(Bk^thkD86DwLWeykOXO8Zld%x!feiAB{ zSUKS8eKQXgg(i38)z)!JT+W(|hU7D>1t<2Gg+D8Q|0(#p75=RJhWR$Uw< zMVX5^@b^||vKn@umZrahCaYoKS&!YOW^-J3zN;Ck;3DsWLztBK5<;_~R2Fzb`&S65 zJa<*#XBr7=UGr}=5`;#H-vhEbA9%LW-NeliT7UGWZVBY9xk|rSxPPifR=VCM+8DY_ zac8|vrijzurqapN-_L|zYsv%XNRw2BvL!LvFQ>FQve3VnH5m=}|1Yb_v}@~wbKd-6 zfau2fytqnAdk~xw*FclikX&drm35Fo7iEt71SUppYM$1J$dtyf5={6lfq_5Ptx3}L ze3W<<6j@6u)*_Q8f!#YGW!c>xso+3M;O}GbXXTIj{FzQm#Kk1-d}lc&_Cu4^F!y;T z_zy6Ie|e5!IkgZcaQ!H9xWkcmg1+ z^Uz;e_xaFmb+)|duWR=JbX%P*?KV%$JY~nNL8cf8#lp4#_FUZi1@tngL$`#fpeuC- zl2bubHsw^%ti_0_pg~p!n#xd)j1VUn46@#pizb5vC8f#iLyrX|HPV?hlvJDJLD^|G zN66;4^3$*CFHz@|Gbwie5}R^&=me0HzBg(JlRlRwZ`BYceGcOD;d;{Npm%5~)K>?+ zOGB9SIf!?0;1N~WL0nw`VG+Q7mZZkNfRKF-x?Af)UODJq4I!@_#2p4aBCn!#Uwqid zg+p}DjVa1=VPu_1Q63(uT4hIw_(%hx+mt-?Vw<900}4S=G7e}&l#Cy0WT2Jb;pM+* z_w}F_5aB8BbQ3lNhg6&D?omM(mE4m((V`8BlIaCcvA!#Cx*?hd6#HJPAhyPzoXBwP?>HQarT z)pQm^+FY|* zGCNo;ajl2-LWw$bTb)a-?q=34K3O#p3)&${yaxWP{B0-gueo6bhZ1jxCadAlNo%6S z2jI`jZ@Av1$_XuR<^^nI$=p_ZAwk^g=BJ?B>P+5XQ``(G#fh>LrBe`^ooLt;nD26h z5?@1THWYfP4b6ST!>`2iU(=v%Ef0V9|IqgB@v=_!|IeOh9=4*!eHSuDawwWgC6|nA z+pR{#mM};*Uo!5O;~e9D(rpTLu&ar15GIu45>vzpvE_E;(uhPVSXFcnY&cgP)tj+k=36yQPu(Mnj5w$@bmzF(v^jC|F z=rif)?-t1yZoi*n%0B?nlA2odrWLFfbT8TN^f4J^GRvbbMZQD5aCx9i758EJWXgBL z@!El8*MK0b^#=BJEaEk?Pg$f~pcAqiT4YSmG-PF8rJ}nW*^-qRcUt-i0Nopen?s29 zRSuw?#)X*fES%+=<+bVM@o@OLlh)VM=!yYtT3!Qdokil(7R4rgXf* zB3rSFn9`|~c~}c6OzBk0%vk|pN~iU|FBIKdBGLXx#+C2h8#xRRi&p(VDPpqGq&jYH z4|@kWq)Tv_L4 zo8|SBAp8d)3X~6_pfGx8PHc?3`c`AYg%U+pHAAHp6c{dNOM<(w1rkFN> z1Q{ANGNld&WDg|M=h;-dYcD$13Je!!+$C*Ub`Em|Hvr6r5OZlWx9}T4nJS$^8_u?b z-sAZTEmBqAMV9~>n%J7--4#|~*iF|mHvl4MZjNw=cLQard?s^z1}I`^{&Bj*$^O$q zt>ZM$>`N9};6dR?tT^dGOIc{42brT1pl_$4r#;9N5>g!xTE=p{>_H!}(EM42{iQy# z8`+Tp;|ZTn#b-*uh4F+{5HE26p-~VDGOL4(UMQbMAC(L$sr2jfP4n>gSW{ zF00o!goDh(kf4120@2I-3n){QM8o0tVO=Y!{DmSLZ#@l7=!F}ZwIIb`D;J4WxDimM zs`F^y_CQf{-rlN|w5%mfuafb)G1N$syO?CDd(VP!e+W{bcnK{&2I$ZP-=B{3EW7r9 zv#eR(8=vx!X@+i&1mOt~B4^{$KHPF%X+%$+@T#@E$8-jm$WXkD#ktHHQ7N49immgk z4AkQ~P!p*t5`@1rW(i5{a+383zCS>a0_|T=@G+nWK7VKR84F>2(l+>S3;8>%rsAN8 zA&W7}HaA*e+vmjBn=VV4#&DDH2wz3+w77PqSRUoxZ)#On7Rw@u&~mH9 zXa$RSdrT5+BZbSw#nGx(#?^cft^tU-)P6}nnf(qF7ehPk%5Dfj>wz0sW1CnAO?f{a z#4*!ZNMXN{TN;ru1MdeUY#7$&AB3A38zk@GTG}vX+5Jmh_SOv9HDvd<5HeKgP(X1P z`eI8$>sX7778E(rB5rmOnNfOZf^`{Wz6A*y)1Xn|1wff`+Tum*y=G(3M;u zN?+{lBFKv_-d3F)Mew%ge{9R> zh+lGH_Ka}6@U9X5YZ%G02KTYdGCtrHQFiEQpPRaK!wya>81D%~Z6TSAl_;KH7J&vV z3rpwKy4`2d(#dHMZ{U+7Lf*qADTX^`5j_U85vDV`MqdqSXojh1mUM4NP)>eFGBDO5Trn}O+k4qvW3nPqJ1GZG{Fs6Oi_&`B47NA=*ha- z?Ux(_DgHY7q|c71`nlHwnKQ3|Fm%w7JoH-DQgKQ>R^VVR54xxlgr}R*NIu2CGC#Re z$n`-fy&oAnMZW$N^~4K@J1-bd4^40egojGdqx|H*sAsl#QJ8yYxzM@?f`IPxpoJE? z--Dj8&;zsFo6S#I2pgw5Vf&Yb+TLEO48~7;klFP@jvWtr$tu1)%XR9nTd3xpuQrcc zpg6~ahE|E8y7ye&JQsr0Tu+McKhJiv#&=uAd9w@I*JVbqoQ0a6l-VNz*ZkS~1d|K! zmbWIC-gkj_<*7gmJxF?A^!IF5an}QSbnZ#W@5!ZKo9p`MsJpf!dGO_y%v?nKcZscx z;xQ5?JB)}=0Yx|AEojX{Mc4mEB`e^1zaZSfFbPBDd0~pa4%F!d;c-aw*Y>}ep9vA< z=Z(XrqJdQ0Lp15_+-o|C@&@7ez)j8$xuXkW3$EshUUz=y>kj2SNKn4=A6jmXaJc0H z_J@t-@@x48T5hCbPjT#u?vL}+r1ZGHrxrqj4CNQe^gPhG#561`+~YblWM8r})dFRb zxoPQKAM?7&O>!x}^#41zWj=u1B$xVs`}y)Ckm9e!m-|U=1u6bo?IY!m9k{-J59m?8 zrh0Y;p^iHmLU6ag{F@Dk^7R4q=0cD1!K*AycYZ;5Eu{Es^|gLd4?>E+mR=VrzO?Pt zyD{IpU`qz)VGWERd>RsDXpt%Ewkqo3g;$_Q`SKgR?d+wu#Hy%yk)NdA+p>IRFp;4- zl);o0WzCvBN>tdG8(0MK4nxSMWyQ&)dX2Yb(MMnrEoo+GkvtA_JyLcf$i=;ZhFQYj zJ?d!_!!4YX>gzbPNgyAy@VFOMf*#*IRLa(Yc+X2=Ie7uEDQ=!r%jr&6 zw6@KEIi0$@lPzxAUxW}Xsf{EoaxHbrvP~=h&smF>cNWS0a3k6!1YsFMw50aFghl=9 zKkX6eP;(ylfreW++aDmebSa}Q+63{I&l3M$M3`$q5Towo7Gu<_M+wSmL4$J2dhB8K zw_!D{Ew3t8PhBHDm@Wnr8CuF@tQ?w96Vsl&7HTM}^JK3`x)DO;Y!v$YR$7wh+xslN z*Z$MTHl&Tbt@?MwzAYH^)#XB+o-10q9ijp;JsZ9wQzzPOHGb7m>)?PG{%M)kx?{8BTlC_6-&#h6-} zO*a(THy?Kco*-34lHr|pz~iPb|JuK zf@jBIB13N7KJK0t({*4XL++!jfV-{niyQOJRmi5UvhA%9mBI+r2@!F{Jow{*z?ymf}XPYpX%H zEA%K|>ZjMksw1IC`Oc@OpWpYPNBPcYrmuIU(G&U7#-f+~9Zh75A zXM3aJMs~!k>UkA8$-yHc@d^bQ4ePEOpVj-@QuiQl+LkZT#tS)`6?cG*oq2L5uYC}TP{#j85VR1}f5HA5n{ zIW|&5TUOg{F%pDZASasJQL{y`s*_Q9k?{#BZnU#C(CtpSkaRBD4MOBBZ!Ip79Ue-# zodbRiAqWqF9_3q8>it;i2%{?WC|}%Ws{9UrlT~*v^eEr>0;|ppGpIUjbL-OG%$ouE z&oE6S0K#gXC5kt20AV$+km*$cVKvWE@|9L>RuD@1IK4M=84N{@=A6neEaI9AUymwk z=0SK3gjlY8nSQaSWi@m2v;o{Bj$0P0{%a_=fr$*k4)m0?hN{alvk-z5C{r+e1}Ia( zj#M|X1n1yXp*q?W6i{ncVa4CsTH>}?Ni#{d$&|Zr4%t{C`Ba%-G5~w%E&W0CI3i!% znRb23G1DG=0pOz80w58JEa>jUaBRbU+XmA;GM3yV3;nodTGE zpy9lUr>oqxNmKeIjtY1NLFq|aWB3F;ZdL`ZD}u|kIXl3@Kuu^+A!l3 zd$@4yAJ{#77kZQr_NG}s28yb9`iq4t0~E#lg%<&%L`@}4M-rFR)$Vl=q(FWjQi`Cr zUn^U1?p4Gf{3BGUQvWJTVUI;0rJp-{7E=7Rye~75BaU9TZeD%z?!=P~2DjwE9gAQh zL+)$uglX9|5M#nnB~!F6Q13y3THu_uJ|rk#*^ebQ@#Bu6#pjveX9K8tV*qz{3K43lI^cmZ=7Nb%R) zA+*Zc?zp}TDgIhMlvW)K6cse)PCy=Nk%~j4>l!btE49o{xT;8W1hj@GC=eZENrnp> zF)++a1jxv3l?LH)5TYgJ!)Q?(u?0bI1#Y;3R15l{S3^HEk>vIkz-L&MCEcc{tiW^H zlLz6sCV$Ddb_DY`EfQh3;9%XjHGYzDj)ur1)#QpH${CNb%R)ky7gL zA3&L!B$}01k-TrMz5%)J+R3abwetkaV`t5{hujkymcnO5pu$#&W5v5MQ4 z#H-2RWiF*-CAU;v>A7C9h#uoLFOc+`D>d};h8|0Y97Z@p9d6W z+{u-?U`y>zJ;h(khD@cfWr*L*UuK@kLP**q3+J0GB-NP3qS{Jft-1GId8jQ2Z-*Y` zbF-;ucj3P%c}5RgOT9+>m_?S*Dz1$`4bMrRYebaKRW>vg$tYwiUH8<|u`<-7ALd>^z0`r$U&M}*= z{zAss&snyy!u{g8>^2s`l@(cAf7$IVl6pmv)4U-3A|#ki^F(I1uhm;*am~9N-rQYB zDFy(pHUR1K;4uz$efKdf2~j|ycj4`xsz#yv~c$+ zwCsGy#nHb*WW6UZTChAWpt~6_%xOTGnpE^hK$$9igR)JaOf?n#4N#^!M8kW5GSxbr{*vPg{?nYlLJ+QS zOU&r+K%6UF^zAIy2jFuTkRWOE+ax!7U>bFcRasAY5BZ|CV;OJD*i;y_zFK%n>uf0q zk+%39(wprP2)fUg2I0yOq(JE`3a$ebF^}a0!!9dd6h$-O`+|IL60YcaZ!&fT=Q;8B zSmPp1UN4=WS*-#o7lOc-iu}*vJJbecTdo=F|{>173}_+=9|Vc z$tC!)Pb1vt%kC z8Flw2Tmc)Hcku#RYWMZH0(7%yMk7v&LXYxw)iW*8`N8RFewllqNBJi8!Y6?;mA}yU zL>#EhHhKYaZlRC+6_KWVi+a-Wx~bC=A4Xf3U(55zE(=z#WgE{UKi9HTtHSq#i42uX z$dsDS;58=*QlNAh1vdqX40hHPRCa5N?4n2_%Sdc;%j!t%&S}>WgxiCKx#TXF+>%V% zs@?K+59m?8PQAEWft7Ai9b~Eyq(Fy);mJUmDmPh3S;gTz86#76OZk>;kU0a2RA^8! zb3Ra}Iz+>(OeT`5{DNgO&qUnv4!6=mioXWGq$%d@T$JRCg=_AwQp`?%pTG*P0>4 zUnj36z4R7%oS+{>5~%J$^0n)^-myP{(DUd?Kr=gmCs3JePTm%hLh>@lsJ@6Cf7u$I z_ilhQOztI}Ap9h3r_GJ)eB0yLqXp8KHFm;L=uy6WJw4O?&5t154O0BIeIwb&fr8z8 zh43(oxNk}Dg%-Cq2{K1Oh$Q)&ge-G1P^QW)qUQi*s!BAx1SnIb-_jfzeHQsCjoFcL z+s+KbYe9q(xV3Y1qeZ;WRQ=8(dH1OI4;GoBTP;EOARt=Ophc0Pcb@tK78xPkl^H?!LkLl&c@I@nLuq0Z3o@5NkMfm2ie7jV zP^R+t(OlEO+{RN7-U})I+PHtZc}6`#^>Hwfq4)rqUA)?N|_jH@;U++t3ZA7IyQj=BA18`CDP2xWrWKdzG}=xO?geUQRMQOQ`Eu2prB@+HfzETZ zEM2g$20;pRo~NMkBnF|kypQw91HPK~fKMPy{s-4y;WXcK%!>n#5$i-N0 zOqCJlTaVbC1iX!CEENko|E8tl$f`OLUmi4qB9MQPg46JCd^?xBNy%;H@RlHVXoz;> zunKZxE~S?exw&;seEZ+f#CznqJysFWqkQw_gr1v7@KIe^S2)~}bPqi+!vYye%CC^j zJcmHo9jM!VoJlydg7B|UrAkLt+x8)z3#sV8kaMdb*Eu*(yafp|& zYxOmnDiPstFQs>W%>z1=r&5^DDe8yfL079Mb-P*+=8+whDIi|)0c!^kl7zn{52PfRCp9nrdnA+d#oP9 zZ$gj)&4_|&bGv)`AZ$R7@}0$~C+=Ki&lonLN|niBs-_&A928qnOL*u`KxAkvO{T|z zqOUmL`&OFtJ6I@czheqydlYU2aMubU)de9_clL;_%iDr8Opx)~o48?2yO^vXUhh2( zS53nM|3Fz;^4c==K=`rPq677DSg)FY4}_>vT8^qRN%TfLDW10o6~rwM00k zAWhE7isY6WbTcSA)8kHsK@ffhWF%>jEa{u{(zD0un9qZW4CVLHtW=f>?jYP9dX#Uz zU-VK^hd_$IcKS-41S$SnT&WLN=7*5tuT@Hg7Xf9ewaWDEzXp1g@8lDDZrKxW=Xo2X zvX|#}_k!>)W4$nxR-^S#0QF|*nP-sZuN_K-(Z``Hsr>4+LfU~p9IpmJ3e?u1pzIQ1 zONbk;*&dtGrZT&mb(FMjL(r49P5N+mpiI?gFw;YTqHQm#Lre09M?!}T&9%v7zKRLM zZt{912|U-i$R2>3(SHY2q-cDYR4JFG^nMOK$~V_Z=q<7^rfvHz`8UP_VW_T4rn`W` zE$)OtbT1GW0&cKpPa1@eLV^r!Ws;|3qwY54sh^Jh159Mdtw)=T9vqCT`uJQoD?sGb`k;wDux|KwA=NQ<{NYVx4!5~O0lX-DIkh?3 z3tMWC8Bvq@!a!a}r63GHf#F?BUjLMMATc$F`zJ6BdwNSlkMfi2({s|FdmVv^FmGC` zoAa(VR|OLpI-f}}c_TwN6COQ4kMh+GsF&)3gUnVCq(GB`nF>&*CKat3VdN2oWb1B2C4eY!uzk1$Ca0@9z%0y7FK#( zpr2bVbX0U#94k=7-Zl5l2w_Fj1);*+!GS3|5otM|VPx^5yO5yfzAs(&0SVvc}TFZZ5BGw*zon4_0TEFug%ZX zHFCPB;>w%~^%T=`U?M|#2Qo>gzsSzp?&mqn*8me4T4a*PK&*ry+z?XywY@X*dqf9P z9x3A9NXa#b?V*a$8g+=Q9L6-*ILC9n3lVSDmm1N6aA#1{n)YtAYG0tJQvV{b|FaM( zo=>*2hgk>}uh0pA;$3sQ7izUPriCmv}@Di)cx0 zPq8R9k@zE|_-p$B+HGDnMlC!t+Zp~>2m->l85mgEXDsw&8p2&$DrH&-6rb}T={!0f zbeL`3FL*i1h2H2Ew37c}b40hGkl5u%$MaSS(V?**QR{7@2vSbPv77VI?QT&Qy#Q*r z~YVqQ^U!sEZ&DML}4A z5Oc{LM4OW1^d}(2Uu%?NiM>Eeb~#%>kMfk863^=ea&%YKvsK?0eu;ulyT<(DU7!PAQttn0pqhccGjfJ zerOTTBR{o>ch!k{#C0rJK!~=rj--v^OwUG*Z>mo1quhkZx1C+AjoUc1#G+zUEn$Q@56+h=_H0y|$0!XqKYUt6_)Ql~(t=+ibZmT^(8;oEm0;2E5-uh zZ2o}dmhS|V+;;->{L+uuGusBlBtCr%CNi|hB>R)R=RWR}Vk_NL;56t_elnq_FLucx zBsWyzXsEGVimr!QB?g>8Qvq!~cx)HQ**^Ub)SJ4_~^J_j+7e zI1mKkozSCvF`@S;9VgHJhINe?gik_`@+H-?Q?!Fq`MGCTuRxFT<%Hg|%um|du+AcJ ztY>|6`XXPN%UahsTOEx)NOZk zi52jM;_ym9w5|D5+9(!z`3q7>S>)v}7FE@vME-aJjNF(@{=DAa%`7rb--#VXq zCcmKxIwa04Zm(K=F*>J4;|3wnwq|ie)zP-1|>~RV*M_;w3dq?0*=%J3?5jYk& zS4h_Sh}Js3NCqMntHR>R*hX)=v2Ay)^;4lo`TCT4?!f$yphx-E0D4zLkMf-X^zMKj z<@3Mm9mB4C&d$F;kMiXK^j?7;HvBtLXYzG0rY+Z zJ<7NG>B$S9?ix#6I{`h)cLvbA7kZS>{l1Ssd*t_T=uy5nfZoy@BR)mG-cL`)9yc1{ zR4()=-=bc)0Z^t|cZ&5{S@^mKS3$U~5fp*uT@>66D8@MNT(p@1yZ6_7O(6G#4jFQH zlPP^Wg`K)_fW^&m(4%~XdNQYQQl~(QzXtb^{fE|0?`-qA7ICM&A~T5|nz;HOvc&s| z74W_qc7a9QSHs*Ct@uwa@GgZA^9}we`6sz`gMfNmVUk=Jr|YRVaScSbRJ`FV%EX>PFhy-uWD`y zZhVH%_(T{cpY)j!;y7YY@5Ng*fUx~ZuVjA$T|oX4;NAHc!j33=i0nmH3QGV+Q1%xV z!V*9s**C?aN8jwe-b!Irplb(H>$d6f-tMfa8q{;CK!0U_13e(4+K`D<6p+V$xH9hDp3(fZ+ zd5DhhVX0zvlb8$N!%|2N(kz^g=yS^|ADU^nWWX0H$8p}_N4)W1a`7p?^wjYMD{|NCj zFp(u~zQhvCJs4HJE|Z;w&C(ZU8TmA7!XHRQ%ZB0+c+^eA6iGApl{-eOI-#`{>G zY{lRjSZ10vX25n_1FM~o^ssgBLw2UmF(phx=qeZx**h)Q zLFPUv((p115IzZ%sr*tbR(gi|D&&SHz9_Dbf|59v=U{PK6%ZL3?;(@CP3WCbkUH^R zAu4U%_@ zHiVl3Whz*nmYJR(6<70aSiWt^7@FfjVn1qJ?Z0;!*0@4uPyttSwu^i-Zvli3olh(| zBS43)kSRH&(03*wbd(CoHP7hdd7D9GKObLV&A!*(4>VlhlY4e%d1VR0UEl|nzd=9r zWtu~78QEueOa~c13qxrI@n~PB^Ab$!drT*Ri45&2nP$kjgt&CZyMae_HmFEZTX8C* zZt#r))k2@@3Q&=vIl_pM%EBy6Yex2&(V6wD8M&T%*a?U~{hIkb@?$>D_w_N|L}%PB zGVJ05BtX0y93;2A<`#sH8E)ZhE4LB!PK?NWZbVCl8*+?0MZUNaeIOaQ3pU~&=pQw1m8P5zSa%xF!1HCiPFDr?p7GIH;V6zhZk zyeN}7Js+dTAfyglqy*u<$c?$QnOpKqk{k)iY41n7{fFI0gNY2Sg4q2wn7E_hUkv#z zaFet6LHfi@#u4~#F%X&QrMusWEyIgK30yx4e++JN=08Mk*&kTcwnH*E;dX5t6Ay5c zvoeF+3xLAzx5drK!Ep+(kh8QFxutvXTF-PM$9QsR;^EW<!5R`7h+gTxuU?ZZf$oX&Ca0N~5k-h(+$qU@`)wGjVNzvFx^ja4H!2Gv7AzAArd{ z3VqLJXcfXx|A>?%$t3-*YhOXQ67(n^tkbQRt|yKK`1BR@DBq%9c5|R{OLV<58?SjZWyD>j9@n;a!oA{yP1F%iX03GN&EFDf1gJ<8Wq&mNp&j}?R` zK#ITCRm#k9hbA^z693`PJ%;1jFbL0r9_2gK%gWKMsvg}6!pk8@fz}2LwFN-Ym$$rE zi_F2pf$>LhlQX|Hiz}Pr?tsfrT=nW#@LXLvthLyD%fwiA=0gaJb3rl~ZbsBe(q8+>3QLv?#Ht$`*zG{JpSH}JB0Io-+W z<}ofJ2NM~}U!a@B3)RB09B1tUgBwZc(x6BA{EpN+4yYN)yoVX`CK!e-j_g@;-5sQ` zTH@p-E4$xlzA7cNHGHUSfgRu6ajk2K$QEu{PeBD?4JOc_+D{X%O-TPtj#KGUa z`X2NspWB6c7XgJ{$(fa2qsk+OvMbHct=5<`T?$hvJSyjG6K|3PVG}yccar%>#-T$K zJYp2dl{xN-ZxG%L3Cg!s&wS}(XyX0%SkJjx(j2KzTxt$I%6AfaJ1qrw;V-^@HE!un z?!IrR7zdzjoE9nV9L^6fpT_X(f~ zp*y{|5I=39$=Ujq&Fsb&!hRb)nBB@kcz~j@_XP`K3r?jZjin~}v zJm6DkBRCFrVWW0K z6lwn2+?y44wWT{syF=MF(t6jCo=6a04;?ZTzsmezx4`Z;HVH#J z!KBXBO%v8RuIhyz<%|1vTaeb{<4kO-Z-x9szNC7#QLgz=vQeI=b+rogDBn;$)9QyN zDCHV6Kc0tMc%Vo5<~V&WZ|`1xyp9~%J?)$mF~w|q6loq*J5Uh@vZy&**FTKm(RQ!*Kwk$GNCW)08qxK9K( zIg1DM;g-I8SlcU~80EC^cmWMeWGEd>Uz#p`v5BRxeqm;zD20wahX#rres!I+S#&}S z4}NJ8-3#k0dn>YlB03HY<8CkD(K$qzdzn_qTp^Q+pf8I_LHHc>C|^nFHCbCSdmJt} zz4v?$OEQsfRaxrYqS*CS6^zV2=Fr5AWKxeZoSaA9RBUZ!zCt7kfgAzcy9M zTnOv+E}7jS#a~N@3RieIP^R*S(R#ffh_5E4FU*S)!%gONFp;53rp!-(GSyP_Dxgf| z4wqarcLHUqqUe)AnQAKfCQzn=BUqXhN71At)gT&~%W>R%f6jxc^*t;m?TqXcxy~`BvqbCFRl!f zsq*p6)vR~X6+Aslr?5Qk|8g3dGdm?UHx128L-W%RdM$l*K#agVDG8z1N+E1)|)=vb?W-A4Aa*%K|~?>5R2hPEg5Ei3i3w@qofY|wW+NH#NH z_7u%-0i^t$%QGw&B909@K7|V@|DeOURtiC=o|o{#W~M^s`Yk9TF7M=M`V*_zn(gYx zyx|WigetdxvS!Z&5JFWU`G6+klIKZ!RqTbJ_jW-qL9(m+j4ro`I|vr{OOSDI_V7!& zZoe_Q(rV3c`vr2(N6}3(B#728bOjMg(F)wzBYD#a8wR|-Dw+>&NKFPxh0CFUF~%C_ zFxJeQKCrZ0c##9M3GJZ?{TivMg1ES>foPJ&<^DwUutmJf&HiGMyq*#Z!e;<6-_`{4 zmngo$dreEW5WEAvVnf+Qfoyv!geRo|>HtG+QcY9T-Bi zCy*zA-ZMe@5}y}gCJKipv>C`G#l1k!#f94g#tUz-iMBM)XL+Z-e`Jo)6Z!ImEK36@ zD$u*v{345ZH(6a_5$_pYw|9f^SCAlQ@nUj|pKt}2`bkRYz4j=`Xm>vjlgf%jcY)rG zgSZ49X=YPncB!xP`~_0{wRDLXm5H{+>`hX2MLz_TsYyjY2b8JYrDWI}C{q)HhX-Vr-P_g_#GNqB&IMOog6;lmJ(c~DMaBy(eD-{cR22y_7XxC} zlQbc`11M9ISJ5!pm8ld~`Kx3hJXL3*t8&piH%X zMaMh>G!8SG7=(WVM1lG>A{d!hrCd{vvY(Ij7JcmbT@WHeOPSUN>dm2a%Z`Id5Edap z`R06@`Z=4WceixeBHlrL>6F|KGHw}!5J}26kZhNcxZn48wJH|EP{8*SvWMCXyp8)1 zLhzS&H-%*BdcEuwR%Wbl`707ya`~aVMlL&(rql1)Q!G*~{6S991YsQzO|JZ!rprXd zJN+XjxaShtd6ulA6Uyu_nPG!Q&1Z)C1@6Rj&wT6-WnFX~-v$=i)=(SUNp5^o01yRA zH?c4qEf?3rue`VQpIAADuJPXNkW>Gt8eO@_C|z>Le=}c@s?icIVUcp-lGmjo-fNLD zb#itki(peyWMq4c83kb;5;VA_hNrvtaAOEkp!yq@aLv_Xv%GKQi0R&`G%hp0rKUXO0HSRPbBLH1j>6OqGd-7XxLgPBgup6@Y^gxIRkFj##8x zSjg|6W>yBotSdAj^C_TAH5ACtWkOHMUCD-s}JZ!9<2mKPI(FxqH}D1QQt=_px+4 z0UerH`n{M`n!j*Yr1@*}epZHgP>VvlB~n(dlN&F*pKls>Gr1>FTzTP|KyZ_@{s1j7 z)2*QieztacHB|=_85$4vVfsFZBAW1?8kc5=e1xW zL*vigHYtNBMR_Z&m4ioZfs{QQ;~1POx0$ zYmYNO>& z4gnJx>ItR|2lCUm!9<41eoShUa`&+5A~2Dm_E(n9#tQXtxi6&nYx$|(QZ6z+FZUwi zl>_KezWBF3dW(4W?3i8w6B#=Fn6%H}@)4WEUqXK?@~x-)SfF}tcJNW?QNH?2Z#{f< z8&dqW^!I*JheL|L2G91Ea^7<`d>?w0&pp>iPcBjL#tK=^`x~EEf{6^lKi&z`ea0qX zXib|b2>%N`%GdunZ3`qeyoWjAGVzSTJ>3Yx<#tAE5YEcK{w(7MTfjty+#7wE)F$QbVbg=gPr}elFzG|C zX~lR4Ok`-h*=>_DsZEOXuxarzcw882Z*?38oulw`O|%(@kI^LoM5FlQOAIiuADQaWIh~7j-j@zcEPNg}b73!cgnS zq&6vc51Up86B#Otb=&kkS$R&+Pn&>=47tVoFsV(--NU9`P3eT8kzm?op#Ettn8?r^ z?zTyp)FwrG*mOUb$WU6Mn`z&HY#RA8X2ZhJd{-YPwMn^q*t9E{$dG$?H`8GQ*)#zr zGSvGqsZGk=!=^{UM21d+>4br7T4y)RpM;^hWOwP5No`W3hfOoVM26r!-Arrpx#+a| zrv{kFP<(G6Cbdbqd)Ra{n8+}hV0z-dLHdF}gNY2yT(?ciq&6wi!=_ijM27m(-Avyd zsP2CH6-0qBG?wYZq&6vc51T%>J6fsyJoiNn;F{w?;-NUBE_d+}gLt~Y0oA~L(>CK$XY1STZe}J_9B)wE8irP0HQFrX9gVhH|0XCVp~cdhzsiFp;6tk4bG( z?jAOs1|~ApR`0gylLN)m1enNB{a_y^wMn^q*mMP$$Pld2&9wPIHr)ayGIaVesZGk= z!=?v~pM;_Ip>CUY7|5pQjGu&|x@I3HwMn^q*z}h1lQ0A`x|#MI$fo7?fuDq-(~n7Q zQtlo$tqCSF)Yqa-_L<9eJovBAB=}BZ5N-iI%2(H>p4~5|)b!fM-e4j_{=S)69WvS_e#I$QS!CsZGk=!=_O%k)fGj z`o=&ujf05{rH^&nq)cj)B0X$66-;Evf4rONhXdJkt0|o@RQoZhP0HQFrtH3`J7EYu z(QVTO1KBhRCNk9eF{w?;-NUBS!9<4kdfhf%HIPj|0}~kUv(!q6`DVN#ovyN69D9*AB=7^<6gGp#<5O${)Sp}AQf zCbdbq(>7&p023K1TL@F;4xmg`6@A#`DygQTe>V)03brJ}e}OVpRWv#X43erTng_~M zaVs*c2b8InqFVuFYEscXfiji<92pJ=%2ZL&6AZ7Ua$8gOETBv^75y1drpnt;_9~!E z<+deyvtf`_ThV)gGS%FUvQHRZN!7L|`T|g<%AY41eI2<;D*pwdD*$CGC=*>1C{t}k zKLeDh)(({27ARAVFB07yC{wi^iB^F!RoRK?NkEw@eTnD~fHIZendl`znF@9xdLvM# z+KT=WC{wL5%02~@sm88EUjxci?aM@S2g6=TRdyq~22iF-Um?07P^R*`6WswQQ^6iY z_XEmQThZA-nd&H72g+2iCmAj^43f$#dIM0V%7O-&n}ITwtB~OVpiGq%{X0;mihEHu zsv_1URZ?^rpiGqo4KgbMWvZ&O>jGt}q3C8nnQAJ!Gf<``72OXgQ@Ooq*=(Rp6&3vs zP^QX?{uC%v#r??eOCu|(s-m|6WvZ#@LqM6DRP^sand&I|GEk=S@DWkpv5 z%2a)S%6qNf36s-ox*fHGB8^kSe) z)fBw}C{uMs?*__LL(wOIGSxna_Pzj=sp=s_qeGFKq=LhVE(esU`cXtb2$ZR&qMriF zR7=qffil%rbQCC4!O`U187NbEMfU;9R7ugpfHGB4v<8%^x}x6!%2Y$q37||(Dtb9k zraFqYfHIXkhW1VZWvU@)ka@`PN~)={e+SA`N74TnUPpiGq&oe7kwx}v88WolB<^MNvzJC3pYky8C2$v1<7yCale74PK0Z$| z1>tSbqkQvh+9a0+ZtuRcbvn^6TvxEAKgMF%uo(Ei2D1%TunBJaX^{fl_r|5(8(C>(v% zY0~SaFt`twJIuzOI5*Dw(mhpViUFA!TCgBI8{FiqUfG8`HC~Y0vs<|H9`{woZsDw6 z)rVV05Z+vc`0Z`r_1p>kwX&{2*MW)lQ4A1B(IS;sqE3H1o<^LpN=y5Ij(3q z2*nl5!p2{E0OG$4Hv%Ct6#FsBpyu6=XTBMcVEPD{$k6P^B<}W@dc4ZHA(+SzT-&E~ z8V0PFAlw>yly6_hT97vE&j+U0Iuq_x)3v>_k~*QU@nH@>#Tv~3)}JL4w>ApuhAUmj{wJIo$QH%@IYgLWZb@i-ZcC} z6G`%1iribYOM@+X+(#L1;S6qM;ZC-;j}|7SG+FsD3GUZn`OGY3XhM^6Uz^uGV4`Xq zkXMx;{04ZLOP;yOhjlf^C7!&?&%z%-kMfn9=mFD5c^>%qa^i4hG9Sr;1)fbZL-Z>A zd|OoS`zjY(#NXPu91!!Z{El9dLFvs|I(dvgcaG|N%Y!6(>*)~)TMg{Xr@7U@Ij^^N z7HEM78Na{?EJ+z1++V@^lVL>&Bcnp5+M$Ss#%ks6gTD)tXjM8}r4IJ1jJw25r9aSJ z;)sQ_Ql)OEA>2`|zA-1WU>5GE{*_GIdC&cv*$$FY!>L+of#!M81Gb3sy?dplFY!Gn z5Im^95y5T64dlulO9YABD@{iH59I9mh@&_FM){+ zlXtP{BI$>G!63>t!s2ISMa-;)Ddg z(s7ufn}*;%m68g>X;8{V^qmyaKe^wyFDcr}&MGyB8TErY>wNJ;s8CDwh5dNBb zIXHn{YQI5m$t3UY^o(xsiHta~I?K;4V5!r{QM#Lf)_%PB;4<@mg>*-CKIIPnW(Wgb>W$)Mi_YETJPfu4pqACJgm= z#8d?n85+@IXj@oWWW`epJr_IYoxmyI9O#%6EHsq1H{2Pt*Ktir%CmHbdb;YtpVwptdI^%Yu%#ED$NL zhl))_?Ybp)GDN1)m>4wPa`sm?Xxwr(2wQ*{EY0^ZXrwPfS+wVtUdE62x3!*`MsG{Y zz0C=+yr|(Bg!jX8S{&>~%Vjxu+aW5+Y21QCQq#EKr=i=^&>d;$&NTFgG;~)Qx;qU` zrlEV%&>z##y=myaG<1I&dLRuw=t1Jbg@+UZ_E`e8)6mmtsFQ|XPD8ar9ldm%a}ISa zQ}%M}hq_iS(A+fCNJI0|P%{n9_aJ!+-%3LZ($J&_J&!;{AHVR>!lT>}6R4erp7tP4 znGSQUOrUvbsF{Z5r=eCFT9Ae&)6l{+)J{WBr=d<7dN~c%4o{VFP8zDGp}A?Ok%s1_ zp=KJIpN3j#Xh9m9OhXIPP&*AhorXGT=;bt2J0k5b50Z&t;|Mpu6R4SnT4`u94Ykuy zCk@q(OyyWlLya`lOhc_SG?|9lX{eKiYDcB*@*uMyLKAHq+R-VldKzk^p{57P(AzrNl~JI{G}KN*oitQCCdE}xLya`lOhc_SG?|9l zX{eKiYR9JS@*u8Qj&&;*fu2r7wV5fYxoN1GhVThIUHzEp3L*zzvQtP#D}19)Az35U zkJDv47ev^%;X<7dc4U$e_F9qb zrpjy+(`SXu$5bGNiLvHrPL~0~x<#c#v3`7EtL5!_AUP@hpH1zuGqJ>yDP47UPVG!h zcTI}pH5d@@xs&~rt3En<=qr64@XFO{Iq9u(zXpubD^0tW+ z&)qh*Oy0Upp4xg(o#a_-UMH+UxH;6AOM6erE$MA3oA<0W{ZLU1^p*g-Sc|-=b*i+H zJmYekMbVznLO9^Tqg!t73yj8fj;BjxM+AKWpWk!-{hKuOTMs(gW^wZ|ngtbaIYyrs zWMz`J;21Y8G|%x&jC+uA4WOqzh`TGtq{h{k(-3+gUH6FMoHSHVLvzzmBMr?&{ zG|P4qtKJ871;P%8dO}7MY-ebHED$y-k`Oj3lF^WL z=COtmJ$Vp>C!uw+!>FFjj^ixbW`E~xJWF44t9PzTpxZo18aqnJPM+J-*sDl3V{FAJ zBq5G5PAgU*?9C}8A&wn+4RL{R-c%tzIrhFHY^pyVuDWU;i2G)6(tUcSTL-WPyaE+B zI7Am)WHs$3gYarVbmSx*Do2kPR6%$%r1)z`rOc>4G{LjbL8c8U{#u?Rl@mS#l&Ru3 zx(6icPVe3C*TF=F;^}>uzK`J_r5<+YsN}ea|8#e$^g^#s#5I77K@Nnu+3S-WBB zzFYBM{X|*`Ok~J?lQta-bZFv-WSWI!Y}4+-6ofTEl%MRUcl1&Ty-1jHg`0#s2yX%t z8LHnC3$pxT+3W)I%*q}}%M13uLDvj+vkNajC7ZJUwh$s)%{MVSG(m|Vd=(hz9w!bcRTUy8vaXcqVmC7d14o-QUE|cmvD&i<_;^^F)I1959igc2*xI zjRxiJ5e*N6i43_PbTeJZ6IIi)>Aka2tHRLi$D}qXcMqF31rr%s%5(=DG&Hf%ZQ>`> z<-~F2zWA^Q^e8`>(EH#Il6pjf@HpsEzMat9T)tV!L~g_piJfF(hr*hWh$@eK0ui&DtZD?rb>$b6ev?=MSl&Hsfwb10?JhJ zY})XY;gwW_XxIVDRQ{aqn7@<#*0f@N@e@!QVW{rR6hID7R#M2gLv{xjw7lip zy^D2Ow3ihaF6^~}tay#dQ1RZe+SkhXHhvutZOdOw8+*LcWml`}0MkczIUoqKh6(Duw-dvvRkdJ6gtPazXeT zFp;5oS?~O!ZI+Po@hM#p-UmI(S1zZX4Gb-x1jdN2C^(e3HG2^L159Kn{eor5ZW3qd z0wbP~dO_F2rngL4gdu+=ZA$n+^*HGa!jThES0Z1(s*m2sAQacJ(_0S^<=X@3?EpQ> zx2~Rkeg{I2^0i;}(bHITb^IOZQGRkh_3Q-lU^b9+lX=QU^`e{1&%sU3@^yWWaZy};YeSFnwHqbBc*7%ZjEtA;b~a0|AKTF)UO$$olrLKWH|9tC zSY(lo+uzE(Pgfc}Tq&DZenUJMYP7#~Q=%OGZ4`^V?X1-1SrC2`+~jPu`g7aHszE8e zHnv`336jDt=}=X7Er_r-u=-kF}i@TAXG?td#sgz{d)Mn9>3!j} zM=WXH-Nz$qLMZmOmj4qL@%p9DT4cnPe=Cc49@)VnGn~wB7V(cJ>+1$j5FQU9=9~W$>*x%ih|=4=Gd`xb1ayZ7 z$)oE#y`ws&--Q%*t?0ZgpLu&nbxdCjDQslXw5)Wic-FvfE^F!-Qh3&&kZ}Z{xgNyU zGh3r4D-bqt*r2keXE$8OYuC;*KG?uv#PIYdo?CEUnVqms94*|-uu9a8ywEbD2a*1F zb@Nl?%{pm4ny8!8yxni~k|lBz^u0>}DzI z|4x+VnsjM=)8(1f|J?K?u==p!;sSQDQ!sRheZh-;0yga`X))fgApZ6`YN_L*)^V?n zdRgSpd~2G&@xago-z?$19^TAI*WK*Vf^ZEmk)fSnVxVxL=(gvB@Z->vba5_LuGMdIr?koST>`)hoq z6neC-o?AR?ChbGnJ%K_JJ^Q}0Cz~~|^8z~ac=yOqu4TanKK;NU!Jop(W2@d%I0j5? zoA*-TezrK?{SXIPWNBBxqb#zFLrfsXu5-0_5`)$Uj~m+N`06Jw!Z5i!nM@pbHLO18U=@U`K#%gJ6{u&oEOg>#&WNC{+*^Cx%UV+7AP7GU zCNkt#7N+>AH&pl0QH{qOzUpFHRtn=Tq~$7ssv^ngNyn-j*YN6T6BvZ7S5_ONJ?u-e z?v5G01MR;iyfxHle`|G?!(@o2c)HiyON0HE*I+l_jBS{$f$yH8b?QSn&Ii5MViFZ) zj&pT24jSrTK(H$erGfbmvg#5{x-`_v?6C?vz!X^+8p>psoyT99G5u2zzq$;YM)b72 zYY6O$g77#nks-GRZL&-^rI`4Tpcm73z(j`53|7OBfub62pRHD81-f&#JD~qlD}{%s zv_2~ko-5Ie?8R0J6K<6f2)!$zs9z&?P3UUy(8A_gzNK*2k!tAFOqn~uM26yfEn&*FO11B?YC zU-}gFY|GbKoLJxud{P!ScMZZ5!9<4Er~5F;^uXUVJR5qHFMWo32_K|(`hsx2$xq~S z8&L0NpuMIe92tXf0VF72QoSn|GkPP81KrK%ARAV!X>(7@ z?)AY<&eE3Twv~J}ZAw>i_<872KEGAB-e(t~x1Y&RIf8a2 z5{Iti;Iz|^x@%2tl1u3e?;y9ib_JN%S0;JymbdR9k?GIR??C>{x4gqU$bVX;eFV8N zm*$S|Ah)+!+J6~uOTM|CnZNY;Wp&-uwS9Xb4hMIaW%L%P5g^_J8o48CL}^+7{<34S z)6qqXCAnS1qGXR|MhI}by&2Z68(eyEuVT1`voXffP8rGCCfJ&Ta9uEwq4wozGhMQx z*geMfrfX)$y$QIH<^Zb_1&W+ z2ZEcNwLQr#Lm##=S>~)6`e6I08~LPVjyajPQ%%Rg0A}2z0m)#}>UBr$PKO@lgS}|@ zSwLee>0!QlTrTK%xbm8&+b2`B{S2uT4(VKrj;IQ*5d<%DsWZ1|t6{^W#8UiWbqG$R zK#%gdy~WDDrK7Vkdx9S2D_>>l#N(ry0UN!m1F>m!nb*XpX5)}^+`k7mIVZnH?uURv zuu`Z<+{gPCK>80KS}V)`LZ&D>e{{J$3SQ_13ureb={6*V`V<+|LSLT=2Zejsyu z1t_L%{>kV!ErbVaq|0W$8B1a5&q&C=+d|kyRY>MHqXnIpC5H9%RBl?+t!0rFEiNA< zmM0_SZ4TJ0gPWZBuTPu%Z4OxLAvfkyt+Ec}IS;1J+B9X(J>b+iyCwMJNYzn>D=)nla+#E%s5;1&t~aT?@9M33g)X z-aQC!FxE>x`Jsn$WKnGN6T?m5PFmkW-=lYbac|sp1-Aq$%8JhjI z^rOa7VW^+j&7{+nY1z~P6B)`U^b7HrEY&3VM_;pE8x6Mn|}e0@qimL&);haTnI1L)lWJ<8|K zV)?9{^lq>6Jpnz+=cm+T1qb0P(4&0q2Mh&q#F(znqJ9=|9)|O^-$mmShB}$1q4y!^ zQNA&N-e%CFd}~TQ#s;>1phx-klzOhyKNNbD?@X!3x(dS6p-1`L+4S(mK<%VkZ-X-Z zxt%JXu#!y8e-0_MnUXdv@h9UmGSh1acn>(taq)Ko7h*2YIRD8|_g?-w;D&i$$r{q&+e$$AcrR(SuM85i?gq;m% zr>=Co8~Ti8uw&tDXIdiEr{&_cU;?wQ{a8#$n*MhE@;Q)`bh010)}QNxD$t{R{wIBm z>Y;Ze^eEq&Qt!JOXWxY$eLm|?mZcbb^!0gxFwi6+tS`GDw1CkR zGNwqfX4DBJ!K-R8ipI2m)~7J(*wD2EZ@&q`g@#EOf(!dF$y+SLg)RA2DPhX%Jvu@7 z5}3%4zo-vWI?9A;M494&6;WRs(j#0!xa{{(>q1(b*N1#P2*v$PQ)=Bk-eZAD{<7b+ zH-H{V>lX`o+#bPJ>RT_1@UN?>&x4zs%}Wy81J(IHU?M~L(mpQGSYh`UghxY<@|^+n zz7IXh*MC0!{4O>n7Wv|3)7SeA^eA7yJmIN#SPKsrn}oA|1#L1%0){5oMf94u{KM#p zeDI5eP32@{{F-5xj*K1y-%@5aESx!VOWRkb9`#v-9_53pX_LtkjRtqcvgUcu5MEPJ zNct!YJB(0%zBE0?s14~hJG~KeXH!5iuy_p(JrF3Gm7Bd~g@4@5=MIC+(8P{>soLBC z1{HT`nC;pf=?uc7pu=2(>zJENTd)It&?+)*5g%aouRbt?YOkh#iaF?kzaBFgv;7>~ z#GWMx&oJecoZC0h0`tK~Q!zbi!LwlZ9Xy34R~^E11Bn>%XT75*xS& zNdw^#2*Ros?(P48_{BH@5H5~mp4lg@6fQkd=ot$woT;_07pdyqQx@x9B$Tu*zD ziDb~%j?-%9HO06GiPM7Y%a*I*L7%d&!3{?PPtya&yP?xnt(*&X4H(Nnitf$bNjI-&^Sj2o{YN}M-&KCngmmMQYV`)hjVy83 zfVc%PX5Cg3WH5E(N_I!cp+Mt$e^VUGLlfL~WK+s%YrrxVI^@j#k;RjygsJr@a)ODM zDd9|&LicYQI~~v1o{_t0vQ=w7mhPHqViv2toLiV2Vag|YmuZ81NJ$S6o2y<>xM4k$ z&qaA&PX*%;9GJ+^xK~Oe)xi8Bc@<<>y+FVCudV(VOk`-@N59+v6h>6ELA)*Qo4`WO z#{KWa%EyeA!Z6v7Nj>f+y01cy^6iIMI{DNu4pnR4ArM9kg(S}LVq+5WR$|$u&WvLN z;c^~39f8n0>atR7;a`Z#Q&Ev2Vu)6PIm zFYAqWyqNlU*NN|HrQkdr6~$9<9=rOtWz|=}OlxY-(kh9VdFk+IdeC8Jq{Y)X4?5Hu ziXgg?5p$-DBgYr^CS(pUK@qkSO1?NE{bEi9Fkb*QEv&vwOLyBiraH;{tib8khLgQd z0hmX$$Pjm#a<3{Y!~DEi+6`pCYZaTb3QMjkW9*yD*&=#U-?vh&S#B5eBP+#H3p_|} z*u!;tjMJ?2w3zW}Pb=Yv8J~uq*?fel_1T3H_S#}9Vq`z=o6>p*B|9UWqQXNZuirtsZO5(9%Y~v@*p)ByAE`i2-7rv|f?AiHuu@Cb-udnW~Cg zF5htp!iS+p`C4WekphjZ)ah&9eR~4Eo`&8?LvN;`w>(JtKDbl+KB;+hI|sAo1wv=R z_LY@t#+;93B82{<3qmnVDP%N-lod(($^>leE5>VFyxt6ojTGEfUn@e7^38~~B^?o5ppkwDcEDp7P?txbMhkzW zf8~v*vhwrRkuf*xFg>AXl5`3qDiDNg!6cfJTbxBPXS{|c+LD!X0UKEmZu$Rsd+)%w zit7z@q+Qw47JJt=YZ+4(34>@sbkju(h7ckWNDQHfZV101AOvFw2tvRlBq#|GCpaKV zzz~Wc6o_u6Kpsd;EcX&YbU?nKSLo+_`swqkW&^ zY@PjOCLHd=6v^+j|~2VV--Des377rqp%DtjpoKzu2< zT!k+Mb0XsT1HKfjRx+dFOTpzTd?~nGg)aq{tMH{@Rmr1_!8!hiEslee{A8{8V&Dq*@rLj-Bp+*nsP#))VE3 z4Y(dmhzh%HRdq(e4z|{+k_s&eRMQ$9{oE716%Qg#)CZOfT6%-;s7thnIEEvg(KjNL za@FEM_0y>Ih)~o@;!*9T)6u!8*v!c5-EBJ6Us0N@qh@!GiGRYyVSBt{qUL;H&dHZe|xN zJ~nT7X}qg)qmr1!eW(p};G7^;RB!mXph= zRxo0vF5zv7eXXB_w111*$>r3pxuyIuPw1!7c44 zp2KdN`y57)nEiCYyEx*)da99{{EQ3^iPY+)Xdc5hT~)S%CEKdq`f+G(w@8evgJ1`_i{rC^3wm?(Fi07HHNVxTK@}SD8#=b#Rlj|2w1S z=7dk~@av4*ft#GA-AB*OX?i5?eQddfb6}6rbL+ROG+OWz)NF8*v;BKz+_N+i;rnvk zdLJ^jEg7ET?jg9zIY{nuoVFZ83VuQ;{L)Ok`-E72^S&dbp6|^XkCSzP~EYpYArCkNm{G|A?^U2o(@LFtSUY zA3Z(7^2&ucDUYkL8{cIW3AF56@&Mw5`)sPFM)6rNvrR#sZf3ieHY-G$PDPcE^vZZb zKByLa*})!@fHvHQt!!&2wdy`HtewkWE2lA}RzylY)6d6J>aG@+`m2;t0@2|7MLw7u z_NEO{YL>Rt9n%Li1o3UT6L7TeJ}L&MeP?OQ)_%4G!jL<Xwy4mV__Vy-zglA+4&vt*z)sfAACtZ6xKk!S?#>4j89I)Osj=dGsBnWVf!KG< zVF~28I&9EyX|t(tPGz%`Y`RZicG9N) zaS%^?f}gUoBWR?nF`oMwaFcW3L~_f9Yo_0m*ysfX4K9V0)lIsAf1ku8UI8~bb0@`f z%j2*hoT$$IF1X1#bPBm`TSYSw2Z+0q<;J~gDjZkd=f=#JMj^y~rxzq`y8CJv7umGy zRKbRu9;^_{!H9+HIxQ^Zuo9K$FTQTpqi%-T;VicnxXC$mR>%zpVC%@T^HLi2iRCIx z>*XqRUaI8d#N2N-%#Nn?;DNc!y}6bXq`#ZQmbS)Hnt@-kR5H_cd-n~0ve)oBxj8m@ z9_?>&(ZAtd@|(zwx%B?3=G<&ZjRt7+9}*XjFFm*YkQ;O9K6~`J@%WZ?3))u(eb~Oo zAUEdH)63lC(>61-la)VP)w*djR`#Y5ayuQlF_*qyk3KiX#;jY>_uUcJx_QWrxs-l0 z`rH^%*OuFr$c?#l|5kFVKITSP+aEDO^EU?Ri7GBLdfCNlJ&yDVjTA53KE zI&WE+#{3a;lQ6XZZdsV7f{6@+%fz%cn8?sKZ&}K;HJHfI^ZR9C+8s<}==#I5FdYsi zGIXE6EKH|>i448-mxXB_n8?ug$7Nx<7EEL)U9c=n_koEF{TB)okBgQT?j$8h33icH z&yHo;3+DL|=9I-K5lhl_5lbZDg%63`qirl&L2y@gGE`G;Zy-13(tmM`Cu?H**p^!u zikGn5m9IY7&7r?D#7HLmrou`WU@jDfZZf$`Nj`Kn^_#$oslAs+mDr35oOe2)wSHRJ}_i~oN zo~#9zdF>5S7pZXX!RJjmeXfqrb6Fnv*V1K$OZfbJ_;^eDsYE1bujyGbN3L}w8D;*~MD5w4j{ z1&;Qm7@SFL1}mm^{dr_|llVTYnA%rnrKh**EMNAcfTO*+YB;;%MkxE4z|p=l24@mi zz>2ATu~rY+GDvFI)iGtzvik$4SAnB_$2HY(ewXS!Ynd?KH#eT3VjzK7% zod8GsQh&Al7*3kRR>0A|=elY*U(W9VNBfTJYsVc49PK;*5`&YwL5==-ojw`y59odd zCNgy0uq;e{U?M~BjWJAegDIFAD=z@b1QT8Wyb0Xo?7S(4Tl*c)98KaOTRX8gH;;@n ziGRY1sRJ=q{<15#VEP7X1HZw8ETQql${GW6dP z!&Ldgoc04>rmx#F2}A#_F-(>3XbF>l%xw|}S|(xWyDf&P@`bYzYImBgoiKFW9>b)q z?jKE@4;<|~?})+GzEExErsVlIZy z#lGjR7@U^VUmaN)INEpots2gkb7SCWZ|<%g_buRP-(MBy*S>>o{lvceo@)8|@jnMR z+V|WWgVS)0qk-XCcw}@An8?s|UksCa*w3$514sML`(tq0qAWQ}5T1(O3nnt;7R4}W z3CLs;gTT=~_dpD;rjh+W%Onf~aZDqWp!pK?YO(KsFs1}@y4qNAw;_D-a8odmq35A$ zOq>zCH+>JD2_`ahK3t87BYPyKW5Gm*;v?0V^q^AbJ71>Xf{6@+aZKu8hV~|L6>zj4 zc(hsxw3o}zy@vNY{sty83_KRYB#-19_2NK-JmmDfm6r>`dnt=8w{Z3i#BggbU@1-F z9pGr+^LVW|UL5eX1sG1*_;X-?K_^ShT}LhiTS|M-aK0k$5CYxHvmWbQXH=0+rqeb z0vzpo7RTf_0`65?Ke6xrdkn5}U66hrt_yX4!U`h{?a#$9X|Lw!H;Lteqy11-oZm@p z3>@uC&sWQjhxsP48*sEQy%2+|T!-YrdGO>>qVq7~n`OC$bKu2g;Fbs8OMj}_gWQ-) z-%ByM=`86zFb_D|_r4s1)0X1=!P~obPoX14sK(Rh(a8CR~OV7W=_hV)B#6pTXYlM@e}gs)s;wK3S}I{24yN zS{u1Bm%&$Ka+AkXBYmiVZHLzpEt4?hUK`FtEAG&m_4*24Py~+lU2!-$YYB1x2ORDD zV{rJ^9ITjXULUzsIFW%BQ*&?7Dmv&Z@rn997 z$`qZu@!f9vvoScYTLK*I`^#_#gs+q0pbsAy@dteqE{CfGFjxkx%+L?^b%3LN?k!e1 zuAsi7e;qj5cT~msAbUUHXx}{w-0{HCzHbz`dBD+rpeoL9q^<*w_U7N!{Ne+bM}eb# zdsQ5VJKl}}j`m$uao(R}7oekweSaLTa=DW4F@>L1YylG)%-bzQC*%72n!B>dvyoh;f*jI>F2RTWH z;>eeB=*42X=QPnI=v(0%ASY?@ozZ*Kx61)wB12~!llE7Sn*$u}d#d96F#Zj2wC^7U z?pokzKR6291HjQf_il`*w0^#vuL4K=jyT*>`m6WU=U^g3cN~+Jz)zHgE73c}zAp|} z)5n=M0uvbqmWk=RU?PJVit%PmWtt5pGPK7rsaJf@{~d6&?<~XVhl~{G!-l^CNBbV) z#zf1%i%&4b7Kd@hVgP8^Pe4NisLaSu`vFJ$ zu2J9$S79L*``)TJzYuQ%9PLY0ao#WA2afhbRdIegIvzOMw|@}h&!tRkT$fB@9+=3` z9miDDLVO39$j~3h^i>z)S3pkEp*Zrdx)5ishBt+@_~Gci>D#3ZOl0VcW73Ju<8}a! z_B~Z`e%?3$INJA*0(Tm4v>zM=?h@c=pZh4rQ(8Y?&bxu5eMcN_DgD)ZY7k6h=#FF3 z68M?qOW==N#Z@UsBvI zAgi0t*ZXSwf$DxRk)it&)}@R|4kkuSxYzFl?$6B)YVm_}&N!+@iGZ&jQh#-{*B`_d?I7XU~5 zp;6!#0!RDe7ctGC_4DO?5;)p-#^Gx6@V~)ChMqVkErFjX8?Hz16#M=-Tut%Ds$e3+ z;4(4o046fz{ukrTn#y!2n8?r($E05I^UvwP(SAU2QRKqUo7NTsT>>UD^nb~^lrjAV z6Dsw<^vLq8)*weQ6Z91AwFb&?s=H0!RB|-EfCi`o+gU z^MRv%XH}fr4023KXaZEMEK>q_18B8+92bCS6wisyT8_~;zv?GrEtHwavgPf$@ zapX(!rf-+M!9<3>I411}9(OEov>&L7^TYU8z|r0`#Q0qE^SG;kqka1*aQ6d8`>s*o zUIC8wy>YmjJp4JB$WV%7(i;1Ta`H{+onk)}hpQ>x*aS>uD2|Eoc}+}vf{6^B%fxgd zn8?r*$E05I^Ur+XXrCL)xu>Id#mDn!`}iN?Mqd0 zerP`h9PNjy;=Etp1CI6`sThA&PD&%hK;>dM8`0n|2 z;AlTI3f#WH(Y~0Daf{~XW1!=KqkU&poNxBu0Z03usyM%9UJD%UOL4f$<{KdfS_CFC zm`qHKYl?y11QQuL;+QHsLTxe7*uSEe329Fp`B#mB)&x08`{T%$;!WQ!9bh8EU>uY7 zACLPUaJ0{5V_HFRei;7{INEoN0{3&^Xx}{w+$F%#zHbz`+kvC~Kpd_n4?hJaGMI7I zJmn|K{{Tn(_BdQkkxTj(EDgfYwMS`@}W zPXb6lR~fJ}L%+!U2RPdIR>k=ksNq&Lme`l7;{0G=5jffpjRLnZaI`Pxt2xx?w>xmO z@2raRG0+jf(Y~iD&UePSz|p?HD$Wn>i-Dv4U{##2-<`nGzI{TBUn(c15n`afgNY11 zaZHsi*Vm~+v+}gm=J~uJOEt;Q?fp!Fr_8nDmzS$23 zj`rPEaemGG32?OUkHb|q-v}|#d0-;LP#jZDG0;t5B18M67~fTPgxX@Dr$J8A?l|(V z8Urn{-W1ZlIP#@<)3?jG+p*RQ!$2I9_8*U%1|03paxuPBoFB$p07v`wQQ&3*NBgc( z;En>0_PwLP{Q@}Jm*Q|WdH7;5kzpu~Nj>E!%3Fb>eX$VZ;hJKgzk`Vkoy)}ZDVWI6 zvrJ6O-+_5j82aOw)GL1enGPK7J0{aBQ4GY-;?@=e?Exk-48$>M45Zv6#6aC(BEyg} zMKO@#v@Sjd`W0}rFE+C-5$@Eo`#{5Dpeq0*ptB5EnW0}~?gftaJymf&26`Dd+V@w* z`N94vaI_yB1#Z%vSk%NmH)XhED(mO-+YmU~cT~ms7-(1EXy08G=R4yOz|p?1D$Wn> zxxmqWpeoMS?{eU1UtB)MFO`$h2rHU*CM?NxEU+4lsF_FYwRe$6}vINJBc;VPSNgc#^oU?Rg{ z98*m(P(PT+P+TF#ca;+hyEcSnGwM6vw3f z$KzH9j`l-Uaef$g07v`ciZMRd{5)=7;Ar1D3f%F)(Y|LCxO0J{eSaLTCJ$c&CNd1h zF=>tcMEL-4w9l;+QqQ3t{M9CZ?}}i41*lOzIUs|Lh7J?Mr1i z{<6SrzBwjk|!O zeNR=KA0RIPNBjO!;FbVK`@vD*rreG0DfYQyHNW_HV?*F*-%%Ck8~!`M(Z0JX&JUw* z;Ar1h73clg3mol-;&7D{zzFfi)nFn+$0{+Ns$6Dji#GW?Tf9|JnZxPH*mD?90jiNUQASC-xG(c$-^yR zB13;1lX}<>?X7^L{a_rfrWJBOFp(j*YK-q{VmcK}WawBXrpv%YhVD2f^@<-c_X9_J zGmUkLP6-|z)hA3o1QQwh;+XW5K)FXaC0O}B%o@VbzS{6I=`Y(KgWRfqKY2?qk-@AU z!=zMj$Luw%mW3-R>uXOt{R05KS;+m{~l=mv) z%i7BD44BA}TPuc1%c9(s{k8rrFp;5?Oo{pjF$;^-wT|#7mxC5V>HB(ND>+#2G<&xk z@(272|0SnJHeLE_VGTCosGGm8_LU+m$l3Qbmc86+BUmwYa9vvM0Bzm;E$J)!6EbdW zuX9(Fy-Dl{3)&B?$CBTlafY*6zCoz8_@5(OgMKW`e~5J^n8?tzK^fBwW#U))J6i~C zDC5@Ilm;eo7`VyVvk|$^s&g0A@B=&y+>;yZ;0oTM?&L2#&G4F&Kn5>#>W8?JQr($a z$nqkMP~FqO!lHC+%pytt-I`lDlU9zNHHmYIcqg+zWR&iESV8zt-t?7Wb zFzQgWU}Q?r6pYOBQniDL3?(v^mCEme{dzM4INA>>&X%BVey7%XA6PN9*umPAS=Ijt zR!r@oRpKOQDfLq;@3?5wCC-HvQwL+Mu7MR(bK9^S_7{=s=JVr>4f>%;PHd+BufWm1 zi@3x+&{FE(j^3B<7yihz?JMYO_-RFMmy-6Ylu?hQ3cmws>mWS+JCIL0+DyeZSZwf{ z8mnyLnmgwW_B+98!cP>wV!4HLh};byLt8hW!^E$@)R@HQu%LbE>-3oYg62p#Uzetb z(J#clID>ULeu^ttN6YOG$mAO_E&mr0Ww+!%K8Up)Ok^-SlSzNYnqOCKuzm`>qWdm2 zkQK14<+@9`Vr&3za`ursmg)K5NhyV?IbixGn8;94ra!M{%XE{BgN8$3gn`-E!cV3) z93E+MsxgTpp(4Xz9FtClWI{{_9PN9)!IoNK^MlQGDgQ>|gou=6G%RfnkuE2`Gz`OB&%1qepZ2t9Qpd*|h6S%=v1%c5jn-+vYF%4ru;mb(0?5 z7~nnwj`p4Vv)t8jO^+f!u^))TT{+p+rLkoUYbPbh1tn+(6B#-Wh$%tm&xJ`Rp4}r& z@Y!qO4p;8gZ7GFwFpj&F74D-s&5cmXjle{Pt^;FAIf8$;1CI8CaX6VWgVC#gw2j2KWJB!+V&Fm01YD=CPX}W!PJsp}L z0ub-!TFSi}w$m?wVJ<_5Ft>TkO+ygLziSlvOCJpS$@vj&v+tF%tOW~{cqELI`T%3u z1`mz#f932U3uIBFK<+`7?*D6$8*>?$_5XElw<9;^(tB9Vxz#l5J_v4d77vf%7B2-O z;L9jV3fk>i5TPeGdrwL$g|Xy6V8mPo<8rHPrJ8E;F1X3r{{zwrLO~@ql_$D`w=ylv2wntPd|o;K^O*qC`^fF zXesp_N&e`pw}J{0!RA+#o30hoBu18v!-VV zv%y4$($OqI8IzvLDtG0XY~mMSB16|PWQu$@U&>?>m%@sv#UG7qHB#hsJ8-n`D8n&; zH;JcV#ni4?t9NY~By~uwqB>tWD({UMz^o|@gU7NqWlZWl$}-jO046eYlc|0;%P-QPYWKJ07pZf$pb$y ziP*qTv?NIz_G9C=_$Rt2rs~Z=Ww!#bTH;j=_aTQMa(DzH=KJ96>#0Z+tka7lO`B$A z5-&r=@|oY!qi;bQaQ`R51>EA%@LX*OMr0VAS5{*j_;L15$}h8bXek;_O55zXQRlBO zc_;HRQV;~_kEwIgY-nn7F2W&z-;aHcGO;Y(^I4{|qT_4-}#Yiguvzc6Z1UcFp2cz=I2fqx2`5w-#A;>3HmHUI)v*y5#`R~? zGRYGnRnJKtcygqg8>mi;RK0;}ZlszQsD2Zv`c7)$Pv#_Tw1Gk_I7x>eRSPRsiz-!% z1C^amY#jp?C#pbYXC_$94bJ@SIUrOxU}GaC?E#Z5SD=z##F^2e9jC0R80`8 zm6yLifN8;x!1Lf1wtC-vY<=5JP=bCx$0kKps#KvvXwk(AtzWJ}Q>#imgLW-fp%Kef zXt8otf2FGARdN`XT5b3c3m+d`i(0d`y^AOcP_Cw(gkCa{oH#s{@3VjJBPQD8*`qamBbXre-6sbN5RR4`sOXm0?FOy8q30@_W z%-le=-L{UtH&DsEGcQodywg{yT2QI#4^;M<3`)N+P>p%QsY-#$t`x9Z6sTlc8wga{ z2)H;<$xJsGsAL^}Gf?Fs;838F`EW^~lKHUbMDMRJqsVIRi7k6Akj2AZ2|!VMD^>FX z)x;>r{u8x>CuOE91*#PytARk(8mR^YRhyJPP;nxtoEv&8Regb~UCI@xWNr;7D7#xg z9m5GqrrU6W5>+@si7K3+q=mu>N_-zqP&N)hj+mf0)RJ3AMGYpX$q$c)KkRxGn8?tXIEJ~EEfN}v@|kPH-qDkHAJOsDJv!HfpD zzJ&$71qEdRi)lI`j!6%*WSt1(@q55ThE8R&=U4s^%p@L%6;n%DIz}QjJipcYy$C}z z;S4`9NfXZWHlmrO8hIY1#jHH_o`)IS^$hm92HmzWYm;~ld9!e49Gy}Yk;y&YW(1?VfmNSD*- zU~_J_9k6NFU57~=f!vtO0COwf7uul5ace)cfrRUs+6H!^hsNh-5+{J0oW%)jgE$Y6 z8$VkK9PPWS;#dNc_ycgXFIC0){1yO5`>u)A%E{hi61MM3wxb7l>nCix*TGHBQXIFA12SO_ z0gm>)%`s&f0XOC;Y)i!6OsO3=893VKMuA%!INEoQ0=E@#wC`D&ZEg>Vu)ckHlFp_{ zIm|)~Mdu{#Bn&HTxH;OB+yB_9dIKw2Q4wkB6|`vDTCkL9>pLhGi_=x4`z%#(E+z+j z&6<6K&3<@SIA?;>_^!~<1!~xYlg5EiF_+vbHRq=LHF^YB$-qR0qB6zRmtl=boCzH5 z`>W#o?}lFp9PK+=Sn|01Jnlx|Xg@Ft+ylVTzNeM>l}&**dpAV2g=KLr>T+!o&w_~z zeXGVWEoGS}Hv$GQkzr_>FePPC4$^!?rqb#w?XFKb{&@uGGk9yjY+HsYUW#9gZbO_vu-{IZ-eCD zsDqyQ2jRZt-&~P@P)5n$k2#ZA6ZtdWPR+lp-{>^z{Wcvq+V_kCHv>4@x39_imgTnx zj9lw--_Gl}VL#myMr7!WW73k734w?$x!9NDa5V%u2s^+;hQT-{ErFj?ehwV%b8E%; zUV!i7FE(8-9hIXl$X#rsHez3sG>qc!YJ_x!7M&#`JCb{jbRyUtBnm<>d#w6|rj`pRh zI8I9@@jP&}H@n5;C&vZB{V`ea{DYVV+0_TN`yi@s@ceiENzMc9{@7u9q?xW7llT-c zmZb07F(s0Tp)m-JmVXwjhS;0$RKxLcl}T(09PN9*E4ZXBJo@7APSzkQ$pt9b6UozF z%<7Z)$Usy$g;UiY$N>%SSI&mA_7rdWhi?rsQiI!gwfI-gmDkWRo5Y^To3-lu9&2aM z{M|&LD@3%_xPyz4Jk9t1Wk{9NlTwrTf%Uj>w(m)9S+)FY4(=Vo+H%vI%u7lyh))eG+HgaPwo!^(-8m!-fjjL4EpKY1Mg}~9?{FtS*8K5^^;%{pt zKj$7RQCj!${S z5d@+i!7g|VRJq^^eI@FOYXPKEw$M7wcg|Xpq7`|F?e`Fk+ct4&?EaQ zRSN>u_=pQbOo1}a7Y3?n(fm^iRPy8;15ttYF%xneI9_j8bEAZT$UO*EbLUj3=2faN zHp_tvD^-gsRT!=clug&0bNqHnR7)yV7{QEgxHX$ssajB}!k{h(E(%n(b>W=FC-`!S z3gcXhDyk)wDqJg2tI1KLg@ao5hvA^MyCdWn4r)<_gIZMKpcYj)s6`bHYEgxQT2ym` z;VPU)Y)S|+ES_ieLaM!C`6%Ku|!q6|b3U#WXouJdSTuE&V};!!D;z6$pj@RWQ=#~N z;~o1*nnKv^e9=l&#BjH^Z?PP2`Guk5k1rWfbJW-eJb3+^+Bm!c#pUZ+~gdLB)hVGQ5|* zIhe>$x+JEQH8Fh)Ol0W2bXk}V023KH{}jWdZRgwk$H37(cUd(YA0U{-8NkurTpoj~ z+_lOcHMm10Pxg!YXwM|h2RAtf;<)93NwEKvqp4iQ(Ui~4B(4TGIeQnxlw1A8zy~MJ zz|p?*ifT9>j+w+0z|lT;Wi_17?-k%^KTs9tpX@KO^%MKPKgZ-(={tEw?+@`zBKsWX zI$`L(Duzjp`hr%FXY`(l&*;NeD1w`u?N`TekI)M114sLzQQ*D~9PRtBsXf2FfTMla zwYB4p29EZ{{@QV807v`o>tb-S&1uv#L4WeXS<58mfr$*A*T*m|WsdUajaPt)44r?8 zVUowEK|hekr$IlE$EUs@@J?9x5bh3}o8;1QLriY}A3nYuK>p0v+!&L;_Dt{Ze*j1O z(kO5r0!RD)n_}{lgYZU;5Jzh9zq$mS>Z?e`7G zt+f=~FMy+c_x;30r`Y=HPfh!f%fLj2_6K8_bRVMJBkV)&v}F>8QW;Y>pFh-8rf0!K zhTOx$%cM+NCe@5krvHG641HxxCylC1sTUDf2}AoM!^@;hS|-(uP^M{MB15T+X;Zd& zO@7)OOl0VPbaZEoPCj>kV~KD02Of*MsmPh^v^c0`T455mOp{MzSuI%Yh- zu4OXTf@ImZA<)K*`)D{=Ssu~6tOav!T6qv9sjJJbiobfEkzErK{a47Y2Z^ymA+;%_ zTyxrf9|5hXUi{sbu1dQ1&UV0V9r0ly^<7A9Q_?m9210+-xYC zC;y3Uai&W*bstOHl;xT}-<2Y#rAVC(KzsFkFNpGG8>i1fC$4X8R{0W_UZgkEmpi$Q zvdP$dSjz05A$%$wq>#D=(#$DBsrqzO)sB6%TUom{k#YkNnkWBJ#I)4=3z^f>RqOpv zi?3eq_hE*y#(J965?hEV>05C+h<4gpKAfG7>>6p8{(J?8o5}Qse>i{fd$j2f*R=8q zDmS_G;t$2%WNbc9OYO2*q;`r>$gT=$OED}otq-Xo*^r-(zwG6W`3d}Ioyl*9l#9ha z<5TKQ>bpo8GbMcp{-82%u&{?YxnAWXoSdX=G8RY1reh$Ct#8WD!QZCyqkgxl&n96~ zzeGw#v(b4g$|k9DluaXLld(85=Kl!cIVs_*NzZ?X$zLBNZR}H;O#a>=WsFaOQx*p) zTlkce$-j-1ZKNK7yMXyJNNM+&q{&bCr^nn=?~|sQ{Ax&Ixjze%wl?|A0@VCEkII_- zt^w)@pEAMZ4+ua*0ceuR|2P264YFF>zaU5odKlbyT|gL&lreB@ zkn;0@ZZaGj&@BuacX>EAKt0pot987|*S+eU6u7S*jztRl%MgOs3|#+m$aLCUrslQ#KZ1Sz)!ZdlpmFGLbsJt#sWW`O{7 zUjSOg_HcfbU?FKR!r0HRvmAnfxzdr?{=p#Ww1BW+@-GF1Zw7=bnf&_!>f!)}33JTr-nrrAf*!LxlIX&h z0@O5<|5|_=2uiqx$!{B=J|FAddnLy2_X60wU`}c=`5y$ZQsCb%lRr5?ofV+a)qWeG z-U?8Mn*4$Q)gP=Zr=c9T2e2hU+Bq1hPXuY@+!lOO+v z_wYSI(&i@LiX?jYvmohYlb;@-27F*Mt`T|rp=G6ez8~6ij(y;;R^uUYTnEaUm zD(r6?W4#Jc=LCVyHSpr~0qm*qzNIfm+Wi5pl=EqWh=X20+Vm;ucku^t(7Tt^8~b1S z11C4HD<7Lrf8ykJ4W2U=ccob85^vgwl+I&B`fjZeX>K`(=iEm8KWfD{tqy!cWBtUn z@OQcO60Qo%aa(e()FHbwQvWGME=<}N(jAgCDPyHeL`oe50XsAMi8J^_16lia2sR`> zu(x)k$R7=XSq=mP6w$;_f~0Qmek{Fb1SuUp1xx&|k+P3`K0Ta*8%^puBq4scKO%tQ zG0(JpYL9qbPh^`OgMxTn@&?p!hmTpU z-6K-u)Y}jmr=&k|Mn;4EFPyA_ugO?DQs(Rbg=^=+AN12YlbVDSG|A=LyE3qjY5Tjj zCKwXY%-RIIpkX*lq9>N_dc>~M@mt*Na{NKa2+n@C`j8I z>evc;dW$1telrLxSui5Uo7DD5!M0C!yh?BH#Dbm|V$=5aYkg}QufC?g4Oo3^ht_@{ zC(ls%5GQx?7LduxcHh>m4_mH zSeBcF)MkGoCCx&!s%{;(0`L?4K@daM@vPto|Dc=o)M)%IEO~Y>(D7=U8Ml87x!UJX zf`zs~u*e})JTpk@%lcM4+~m(i(q>mi-V7G9ded|{Qn05_-GslG^tdKoIHuL$ynZPCFhCnK)7<9vQ9|H<-R~_^JMJ*iWvEdhHd}fPC+B7g&SWf(EaTR(!uW+uoU{$( zpNcdoW2IRlrFMmY88bSaF?u>vv4~kaQe^iI7)<_fNNn5wAWE5Pvd1FnUCFADIt|iS zIKBN1VD+u>r?=<0^s1+~_gp2zvi$Vc9!FyS)Rpc+$JfqZK~CT3Q&Ws(gua;8Kn@Z9Xhzei{UJmtcR2X?0zszzz0o zTl9TTe~xp5_WeIQIj8atzq0AgKe|TR_ePgquHO-(~oN ztXlh}xEZUbRo14iCrO3WwUAI_`}zYQoPs4nYGkiU-|Q%x4t4W0*9zyj*C0$B&lPdJJ}Mdau}fgd#uu-PYU!8K zNzLzstX66eqwK1IVDjrhnjuLkzfLxo)Hjh*kK<$er&T*k`YpHUAW(T@@TSJcHxb z>yXxdedMNvXGR22_mjCHhiCnX-{StL>{VC({HMV4tIP`m4^1;o_3zpTo@4W4@pnu4;kYn7#r|$8 zlHiP|PIb=Ujo|b?r#NS@#%cRuA?z0X=ELGh*|fIHC!OB_e~*=X76f~$@0t7zB$2%@ zX#Pni_Z=iPPo61_MF$KPYF&R0wRj9f{6W8^E7GSrxl!exJ6ZQrCS!5thRDsivmrE3 z*7~0579-R5X|1hrF7Ui()E|VVUpGw`At~87ZqgO_>j%D-7D(>dn;<+cLLv1aq<)OV z7x6coTHbJS^XWH9q26|K``Ye?vIJsNp z6`VXy$_6n$Q?wNotc3j4}EY~+<_ zUFa1%IY`MXzU35)>fWKJ_H>HDIu7piK~6DL_qChFmq$6p-1@&zaiUYqtACz~jhD08 zE~vj-+R0>WJF(Srr^CK^@_o!vI?%nfP6MfVz++XPy^?Elb?E}AgOJ_i`dvO6VoN@| zd{Sda&E4hjKV+>0e?+F%(e@1RSoW+((Kpqh|8jCp<&T|QWHe|p7ROvu_3ydLO2EVo zQ+g8As4VxRCS&c`BKZ{|Bo;>X>Zss-D`9!!$oM%tSgkWq|i+HMtR?+rcpwXtS7xmo2OIk~tG?JwNP+P4i*j!wDS zPrOa|PH^_q6@R*uJKiiw`dLo)1Mob^!v^4wrdh?@y7lf8#Hq+J(Hab|J_iYg*A-6D zU#FYIYn@_Yovui?ImK;Wai3F^>bSK}KjajPyy9u681Un5&?yG%K4Mkw!Rni6eY1`$ zO8PBl@h`9V#3|nLip2XC@^7yg=M-;y#qv(^AFr6^6z|k+E5Cf5Zg+}zy~Wl}G31NB zi&HGA<6@Qmo>TPHYb&k2hI4YgI%q#<(Oa)E;4G(DP_GSnlvDJ3#T=(t=oLLqQSyqP zImIHc_@z?}c*VI+vAF&+HufK#Vz8d=VluYl9w5Cx^=BkwhLQMA%NE6VdMIEr){b2~ z`&S4*kp5aoJz$fjq+f#vF!;60tbxe`EuqupWt>XGaJ~8yIgu#mhwT66Ro{}K0p3;LF|LotZp+x zPIMOiUa=AmgzYk`E-+~yT$IYr4U&UK1Ke%SXp#bR%9nNz&r75z>z=oL3P#j9RX za*8*-;#=*uV8O7z-&q91{xPR`$B*)-oFW+ZgHAEzCx*A2;zK{lec%+qJn*?w^wg_A z4r{jMm|MRyU0C;_RrLCqBAWH))gMWVCTG#-r;Z6uv7r7qT1;_@{(5b>Rh(jB{p5RP zN?#{ZB-f{6L#J5c6`MyE4cfnUNZW$l<`vsGi&BFQmv1=5qJ~{a`W>ejYS008@dlRT zy#}t4>3yBWk_Mdx4tI*4F{(JmDdvt*$jMI8J4VCoUpmFSF`CQyPBDLs7X5Ok=o_OY zy~ZgPjJcF0y~!ySdyA4&40^?bPVwd#U3~V&WRPeb8k6D7`J}Vx8#_f5CS!*(2X^*l zBu~{D=`Bdpr^t+>b3rgAp8PMPE72 z%I%a*#^%c@q-hBR++}TQ`pEuGH?3y>CR6#1@RyKbj~kZjK+437{XeIPrX4K^Bs1~1 zp)Qfy2Y)fk*nRMGi>KBmuo2I1yfWN@%Ai2!R-YeHR z+0V;2IoXFycR9JpywlgUIlK-g zEyuiu&xOO}SA=F?$zooxd)v-r+mUpHBo$IyLz+D$ZTAAGB_Zi7rUER0|F~NU^~%at z&b>?7eh3Sz&-yI%+T*P3YxzykqU|?h`s?mmW4n%m@4EC2Ro=(R)Ai8d-&u>_Ob6Qj zE`4(yR?(BuEi`?{qP5>r<-?r)Rw^Iugf)XD+={(@${anW=KG zOYhp2^_%bHS%*^olasq?Z!*@;^m_Ih2y}HJdk3U1#Ic3cycm z1p(f<_=Enf0m%hUZdCb7C+AeY(aFs!-{IsUWs|xW3Pf>b@spgGYkkspxG2rf4nH~3 zmc!2uPe;70aoT=V4qR_H|2~le91yCu?O)#@aEL>|~_gAXyett3kp;tZ0q!f#QY{g&zJz-7BXNel*WC zs~jDu`)4LwJA4~A0O@Zyxm{=D-JLw0c$3`+3igCT{$NPl!S@D-bWJ98B$BY`{nagM zW-kuhBV2%?B|2i5_YcUzF2NlUoS}&68JL zBonK&)y=gYt7O*&el0;4Qd>bnE$p|D(7iPbiEer{s@raN)3e@gN!#BWK{xDUDWd&O zQTID1x|<^H>LG|_^DHzwd;qwGiIv$9eSo(=S4*xG60FC|3^~FC;cTSllR_RTk#u~+sznj$N zP~fpic^8MInC$A;DR~`$W zJ+{VCn*BfEd6HDf9}8)l2O|gc1itCPwX{c(hKjZP*ExU%O|R`_-z#ivibY-1H+JdG z>@_B}Efff!#6fCz#-zyWLW6QN+$f=CJdXho!; z`s+A^HfnlfC+qX0^j1!;XQQWQI60y69!^fGypNOpzT*%l`%Oi+lgHBDWNbO+O8xV5 zAWVN)+C8`^Tr{a)AqmYe(G7MVu||i8!E+#MM~dtP5Ka)jLh2ewSk@#8_&?F7Z-*LV zR^{j|p4=-;j~?v%Wi49PeK`2tR*P@b`K0My5aP~Zb}{~b%G~qsL1G?D-us>()ffH` z?^iT^Va)oEL^WR&Ty@>fq*g)_YCiU-uJ6!u>2;w-M`i1#H*m7Q@D@dBx;mST1%hkvcL2rZyf2lNi=Kt@vfihi%S+bI^N>67%sPH~%8Jna;v z^u;87E>cX@-RVD_V$oDx$=`H}fvM_<_ncz!)H}%Wxl;^H{T~$#|8v{w*5x0Ux{Py* zC9N$~Eawz+SLK|UZgGm)KR)!N#HD$#n+s{9F9 zliv*{YfGtu*IXJ*?hvFjPu2r?2`8?oHJr%L2L23T?g<`M<870(kwoIMc>5A0v4%ZC zuf*b$`>QLFuAWk&^J^~AgTNEr6F#@7Gfgic&A#yZKK>$Lof_Rw(Gv*!#YuE^on|uD zj&0SH`qIrgsaE{OxLzNBu+ZGVW|;2eMwPd6vfmOMw!F3Xt7FFUuo0VfhJcdg_rhP! zKf$Vu-`G0{DT8?CV!sZ9e6{y)R9|Nct@7qh&av^+9Zv4l-tkQ*@9yO(mT#uYd%5&3 z?U7NqGE39inD zey`ZdDHeLgPEJv(*KYAGr�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

    -nCTg730s7fI<-VP@(cuL5@1n7+i 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≠qh~)0g3STk|~I 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

    5VwTlDecQ+fpY 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 Date: Thu, 26 May 2016 17:12:20 +0200 Subject: [PATCH 0436/1435] Update README Related to https://github.com/texane/stlink/issues/356 --- README | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README b/README index 8fc282bc5..fc2231854 100644 --- a/README +++ b/README @@ -236,6 +236,21 @@ STLink v2-1 (as found on the Nucleo boards), known working targets: Please report any and all known working combinations so I can update this! +## Known bugs + +### Sometimes flashing only works after a mass erase + +There is seen a problem sometimes where a flash loader run error occurs and is resolved after mass-erase +of the flash: + +``` +2015-12-09T22:01:57 INFO src/stlink-common.c: Successfully loaded flash loader in sram +2015-12-09T22:02:18 ERROR src/stlink-common.c: flash loader run error +2015-12-09T22:02:18 ERROR src/stlink-common.c: run_flash_loader(0x8000000) failed! == -1 +``` + +Issue(s): [#356](https://github.com/texane/stlink/issues/356) + ## Contributing and versioning * The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) From 113f3e3507bdfb1a656f38e90ab0381f27f56f26 Mon Sep 17 00:00:00 2001 From: Jean-Marie Lemetayer Date: Thu, 2 Jun 2016 17:41:15 +0200 Subject: [PATCH 0437/1435] Fix multiple warnings - Replace 'typedef reg' by 'struct stlink_reg' - Prefix the 'sl' global variable with a 'g' - Rename 'j' -> 'k' and 'i' -> 'j' variables - Rename 'hex' variable into 'hextmp' - Fix unused parameter - Use a correct printf format for gsize - Use correct MAX macro - Use correct data casting - Do not use 'GTK_STOCK_*' anymore - Do not use 'gtk_tree_view_set_rules_hint' - Remove unused functions - Explicitly cast data type - Enable Werror --- CMakeLists.txt | 2 +- include/stlink.h | 14 ++++---- include/stlink/backend.h | 10 +++--- include/stlink/sg.h | 2 +- src/common.c | 62 ++++++++++++--------------------- src/flash_loader.c | 10 ++++-- src/gdbserver/gdb-remote.c | 2 +- src/gdbserver/gdb-server.c | 71 +++++++++++++++++++------------------- src/sg.c | 6 ++-- src/tools/flash.c | 22 ++++++------ src/tools/gui/stlink-gui.c | 41 +++++++++++++--------- src/tools/term.c | 54 ++++++++++++++--------------- src/usb.c | 63 ++++++++++++++++----------------- tests/usb.c | 2 +- 14 files changed, 179 insertions(+), 182 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d61a0aee3..7846cb175 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,7 +109,7 @@ if(NOT MINGW) endif() if(gtk_FOUND) - include_directories(${gtk_INCLUDE_DIRS}) + include_directories(SYSTEM ${gtk_INCLUDE_DIRS}) set(GUI_SOURCES src/tools/gui/stlink-gui.c src/tools/gui/stlink-gui.h) diff --git a/include/stlink.h b/include/stlink.h index 72eebb70f..c93086219 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -67,7 +67,7 @@ extern "C" { STLINK_FLASH_TYPE_L4 }; - typedef struct { + struct stlink_reg { uint32_t r[16]; uint32_t s[32]; uint32_t xpsr; @@ -80,7 +80,7 @@ extern "C" { uint8_t basepri; uint8_t primask; uint32_t fpscr; - } reg; + }; typedef uint32_t stm32_addr_t; @@ -166,11 +166,11 @@ typedef struct flash_loader { int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_read_all_regs(stlink_t *sl, reg *regp); - int stlink_read_all_unsupported_regs(stlink_t *sl, reg *regp); - int stlink_read_reg(stlink_t *sl, int r_idx, reg *regp); - int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp); - int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, reg *regp); + int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp); + int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); + int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); + int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); + int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, struct stlink_reg *regp); int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); int stlink_step(stlink_t *sl); int stlink_current_mode(stlink_t *sl); diff --git a/include/stlink/backend.h b/include/stlink/backend.h index 20b1c7132..d1b7648e4 100644 --- a/include/stlink/backend.h +++ b/include/stlink/backend.h @@ -18,11 +18,11 @@ int (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); int (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); int (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); - int (*read_all_regs) (stlink_t *sl, reg * regp); - int (*read_reg) (stlink_t *sl, int r_idx, reg * regp); - int (*read_all_unsupported_regs) (stlink_t *sl, reg *regp); - int (*read_unsupported_reg) (stlink_t *sl, int r_idx, reg *regp); - int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, reg *regp); + int (*read_all_regs) (stlink_t *sl, struct stlink_reg * regp); + int (*read_reg) (stlink_t *sl, int r_idx, struct stlink_reg * regp); + int (*read_all_unsupported_regs) (stlink_t *sl, struct stlink_reg *regp); + int (*read_unsupported_reg) (stlink_t *sl, int r_idx, struct stlink_reg *regp); + int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, struct stlink_reg *regp); int (*write_reg) (stlink_t *sl, uint32_t reg, int idx); int (*step) (stlink_t * stl); int (*current_mode) (stlink_t * stl); diff --git a/include/stlink/sg.h b/include/stlink/sg.h index 56780f4c4..057f996a2 100644 --- a/include/stlink/sg.h +++ b/include/stlink/sg.h @@ -60,7 +60,7 @@ extern "C" { // obsolete, this was fed to the scsi tools unsigned char sense_buf[SENSE_BUF_LEN]; - reg reg; + struct stlink_reg reg; }; stlink_t* stlink_v1_open(const int verbose, int reset); diff --git a/src/common.c b/src/common.c index 2899f298d..90725c64b 100644 --- a/src/common.c +++ b/src/common.c @@ -170,18 +170,6 @@ static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { return rdp & 0xff; } -static inline uint32_t read_flash_wrpr(stlink_t *sl) { - uint32_t wrpr; - stlink_read_debug32(sl, FLASH_WRPR, &wrpr); - return wrpr; -} - -static inline uint32_t read_flash_obr(stlink_t *sl) { - uint32_t obr; - stlink_read_debug32(sl, FLASH_OBR, &obr); - return obr; -} - static inline uint32_t read_flash_cr(stlink_t *sl) { uint32_t reg, res; @@ -366,12 +354,6 @@ static void set_flash_cr_strt(stlink_t *sl) { stlink_write_debug32(sl, cr_reg, val); } -static inline uint32_t read_flash_acr(stlink_t *sl) { - uint32_t acr; - stlink_read_debug32(sl, FLASH_ACR, &acr); - return acr; -} - static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res, sr_reg; @@ -767,12 +749,12 @@ int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { return sl->backend->write_mem8(sl, addr, len); } -int stlink_read_all_regs(stlink_t *sl, reg *regp) { +int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { DLOG("*** stlink_read_all_regs ***\n"); return sl->backend->read_all_regs(sl, regp); } -int stlink_read_all_unsupported_regs(stlink_t *sl, reg *regp) { +int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { DLOG("*** stlink_read_all_unsupported_regs ***\n"); return sl->backend->read_all_unsupported_regs(sl, regp); } @@ -782,7 +764,7 @@ int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) { return sl->backend->write_reg(sl, reg, idx); } -int stlink_read_reg(stlink_t *sl, int r_idx, reg *regp) { +int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { DLOG("*** stlink_read_reg\n"); DLOG(" (%d) ***\n", r_idx); @@ -794,7 +776,7 @@ int stlink_read_reg(stlink_t *sl, int r_idx, reg *regp) { return sl->backend->read_reg(sl, r_idx, regp); } -int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { +int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { int r_convert; DLOG("*** stlink_read_unsupported_reg\n"); @@ -815,7 +797,7 @@ int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { return sl->backend->read_unsupported_reg(sl, r_convert, regp); } -int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg *regp) { +int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, struct stlink_reg *regp) { int r_convert; DLOG("*** stlink_write_unsupported_reg\n"); @@ -1016,7 +998,7 @@ static int check_file(stlink_t* sl, mapped_file_t* mf, stm32_addr_t addr) { if (aligned_size & (4 - 1)) aligned_size = (cmp_size + 4) & ~(4 - 1); - stlink_read_mem32(sl, addr + off, aligned_size); + stlink_read_mem32(sl, addr + (uint32_t) off, aligned_size); if (memcmp(sl->q_buf, mf->base + off, cmp_size)) return -1; @@ -1075,12 +1057,12 @@ int stlink_fwrite_sram if (size & 3) size += 2; - stlink_write_mem32(sl, addr + off, size); + stlink_write_mem32(sl, addr + (uint32_t) off, size); } if(mf.len > len) { memcpy(sl->q_buf, mf.base + len, mf.len - len); - stlink_write_mem8(sl, addr + len, mf.len - len); + stlink_write_mem8(sl, addr + (uint32_t) len, mf.len - len); } /* check the file ha been written */ @@ -1134,7 +1116,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) if (aligned_size & (4 - 1)) aligned_size = (cmp_size + 4) & ~(4 - 1); - stlink_read_mem32(sl, addr + off, aligned_size); + stlink_read_mem32(sl, addr + (uint32_t) off, aligned_size); if (write(fd, sl->q_buf, sl->q_len) != (ssize_t) aligned_size) { fprintf(stderr, "write() != aligned_size\n"); @@ -1161,7 +1143,7 @@ int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, s } if (rem) { memcpy(sl->q_buf, buf+chunk, rem); - stlink_write_mem8(sl, (fl->buf_addr)+chunk, rem); + stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t) chunk, rem); } return 0; } @@ -1197,7 +1179,7 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); flashaddr -= STM32_FLASH_BASE; if (flashopt & (1lu << STM32L4_FLASH_OPTR_DUALBANK)) { - uint32_t banksize = sl->flash_size / 2; + uint32_t banksize = (uint32_t) sl->flash_size / 2; if (flashaddr >= banksize) { flashaddr -= banksize; bker = 0x100; @@ -1226,7 +1208,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ else if(sector<5) sl->flash_pgsz=0x20000; else sl->flash_pgsz=0x40000; } - return (sl->flash_pgsz); + return (uint32_t) sl->flash_pgsz; } /** @@ -1385,10 +1367,10 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) int stlink_erase_flash_mass(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_L0) { /* erase each page */ - int i = 0, num_pages = sl->flash_size/sl->flash_pgsz; + int i = 0, num_pages = (int) sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { /* addr must be an addr inside the page */ - stm32_addr_t addr = sl->flash_base + i * sl->flash_pgsz; + stm32_addr_t addr = (stm32_addr_t) sl->flash_base + i * (stm32_addr_t) sl->flash_pgsz; if (stlink_erase_flash_page(sl, addr) == -1) { WLOG("Failed to erase_flash_page(%#zx) == -1\n", addr); return -1; @@ -1460,7 +1442,7 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, if (aligned_size & (4 - 1)) aligned_size = (cmp_size + 4) & ~(4 - 1); - stlink_read_mem32(sl, address + off, aligned_size); + stlink_read_mem32(sl, address + (uint32_t) off, aligned_size); if (memcmp(sl->q_buf, data + off, cmp_size)) { ELOG("Verification of flash failed at offset: %zd\n", off); @@ -1563,9 +1545,9 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t stlink_core_id(sl); /* erase each page */ int page_count = 0; - for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + off)) { + for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + (uint32_t) off)) { /* addr must be an addr inside the page */ - if (stlink_erase_flash_page(sl, addr + off) == -1) { + if (stlink_erase_flash_page(sl, addr + (uint32_t) off) == -1) { ELOG("Failed to erase_flash_page(%#zx) == -1\n", addr + off); return -1; } @@ -1628,7 +1610,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t printf("size: %zu\n", size); - if (stlink_flash_loader_run(sl, &fl, addr + off, base + off, size) == -1) { + if (stlink_flash_loader_run(sl, &fl, addr + (uint32_t) off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); return -1; } @@ -1701,7 +1683,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); - stlink_write_debug32(sl, addr + off, data); + stlink_write_debug32(sl, addr + (uint32_t) off, data); /* wait for sr.busy to be cleared */ do { @@ -1734,7 +1716,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t unlock_flash_if(sl); set_flash_cr_pg(sl); DLOG("Finished setting flash cr pg, running loader!\n"); - if (stlink_flash_loader_run(sl, &fl, addr + off, base + off, size) == -1) { + if (stlink_flash_loader_run(sl, &fl, addr + (uint32_t) off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); return -1; } @@ -1779,7 +1761,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { else erased_pattern = 0xff; - index = mf.len; + index = (unsigned int) mf.len; for(num_empty = 0; num_empty != mf.len; ++num_empty) { if (mf.base[--index] != erased_pattern) { break; @@ -1790,7 +1772,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { if(num_empty != 0) { ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); } - err = stlink_write_flash(sl, addr, mf.base, num_empty == mf.len? mf.len : mf.len - num_empty, num_empty == mf.len); + err = stlink_write_flash(sl, addr, mf.base, (num_empty == mf.len) ? (uint32_t) mf.len : (uint32_t) mf.len - num_empty, num_empty == mf.len); /* set stack*/ stlink_read_debug32(sl, addr, &val); stlink_write_reg(sl, val, 13); diff --git a/src/flash_loader.c b/src/flash_loader.c index eaba6d3c5..6ea324485 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -1,5 +1,9 @@ #include "stlink.h" +#include +#include +#include + /* from openocd, contrib/loaders/flash/stm32.s */ static const uint8_t loader_code_stm32vl[] = { 0x08, 0x4c, /* ldr r4, STM32_FLASH_BASE */ @@ -181,7 +185,7 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) } /* allocate a one page buffer in sram right after loader */ - fl->buf_addr = fl->loader_addr + size; + fl->buf_addr = fl->loader_addr + (uint32_t) size; ILOG("Successfully loaded flash loader in sram\n"); return 0; @@ -253,7 +257,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { - reg rr; + struct stlink_reg rr; int i = 0; size_t count = 0; @@ -282,7 +286,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe /* setup core */ stlink_write_reg(sl, fl->buf_addr, 0); /* source */ stlink_write_reg(sl, target, 1); /* target */ - stlink_write_reg(sl, count, 2); /* count */ + stlink_write_reg(sl, (uint32_t) count, 2); /* count */ stlink_write_reg(sl, 0, 3); /* flash bank 0 (input), only used on F0, but armless fopr others */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ diff --git a/src/gdbserver/gdb-remote.c b/src/gdbserver/gdb-remote.c index 2f61b93ac..73a157d34 100644 --- a/src/gdbserver/gdb-remote.c +++ b/src/gdbserver/gdb-remote.c @@ -18,7 +18,7 @@ static const char hex[] = "0123456789abcdef"; int gdb_send_packet(int fd, char* data) { - unsigned int data_length = strlen(data); + unsigned int data_length = (unsigned int) strlen(data); int length = data_length + 4; char* packet = malloc(length); /* '$' data (hex) '#' cksum (hex) */ diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index c50e5be32..5884b1e51 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -30,7 +30,7 @@ //Allways update the FLASH_PAGE before each use, by calling stlink_calculate_pagesize #define FLASH_PAGE (sl->flash_pgsz) -stlink_t *connected_stlink = NULL; +static stlink_t *connected_stlink = NULL; static const char hex[] = "0123456789abcdef"; @@ -485,7 +485,7 @@ struct code_hw_watchpoint { enum watchfun fun; }; -struct code_hw_watchpoint data_watches[DATA_WATCH_NUM]; +static struct code_hw_watchpoint data_watches[DATA_WATCH_NUM]; static void init_data_watchpoints(stlink_t *sl) { uint32_t data; @@ -569,8 +569,8 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) return -1; } -int code_break_num; -int code_lit_num; +static int code_break_num; +static int code_lit_num; #define CODE_BREAK_NUM_MAX 15 #define CODE_BREAK_LOW 0x01 #define CODE_BREAK_HIGH 0x02 @@ -580,7 +580,7 @@ struct code_hw_breakpoint { int type; }; -struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM_MAX]; +static struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM_MAX]; static void init_code_breakpoints(stlink_t *sl) { unsigned int val; @@ -753,7 +753,7 @@ static int flash_go(stlink_t *sl) { stlink_calculate_pagesize(sl, page); DLOG("flash_do: page %08x\n", page); - unsigned send = length > FLASH_PAGE ? FLASH_PAGE : length; + unsigned send = (length > FLASH_PAGE) ? (unsigned) FLASH_PAGE : length; if(stlink_write_flash(sl, page, fb->data + (page - fb->addr), send, 0) < 0) goto error; @@ -1001,7 +1001,7 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("recv: %s\n", packet); char* reply = NULL; - reg regp; + struct stlink_reg regp; switch(packet[0]) { case 'q': { @@ -1017,7 +1017,7 @@ int serve(stlink_t *sl, st_state_t *st) { params = separator + 1; } - unsigned queryNameLength = (separator - &packet[1]); + unsigned queryNameLength = (unsigned) (separator - &packet[1]); char* queryName = calloc(queryNameLength + 1, 1); strncpy(queryName, &packet[1], queryNameLength); @@ -1043,8 +1043,8 @@ int serve(stlink_t *sl, st_state_t *st) { __s_addr = strsep(&tok, ","); s_length = tok; - unsigned addr = strtoul(__s_addr, NULL, 16), - length = strtoul(s_length, NULL, 16); + unsigned addr = (unsigned) strtoul(__s_addr, NULL, 16), + length = (unsigned) strtoul(s_length, NULL, 16); DLOG("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", type, op, annex, addr, length); @@ -1058,7 +1058,7 @@ int serve(stlink_t *sl, st_state_t *st) { data = target_description_F4; if(data) { - unsigned data_length = strlen(data); + unsigned data_length = (unsigned) strlen(data); if(addr + length > data_length) length = data_length - addr; @@ -1072,7 +1072,8 @@ int serve(stlink_t *sl, st_state_t *st) { } } else if(!strncmp(queryName, "Rcmd,",4)) { // Rcmd uses the wrong separator - char *separator = strstr(packet, ","), *params = ""; + separator = strstr(packet, ","); + params = ""; if(separator == NULL) { separator = packet + strlen(packet); } else { @@ -1136,8 +1137,8 @@ int serve(stlink_t *sl, st_state_t *st) { __s_addr = strsep(&tok, ","); s_length = tok; - unsigned addr = strtoul(__s_addr, NULL, 16), - length = strtoul(s_length, NULL, 16); + unsigned addr = (unsigned) strtoul(__s_addr, NULL, 16), + length = (unsigned) strtoul(s_length, NULL, 16); DLOG("FlashErase: addr:%08x,len:%04x\n", addr, length); @@ -1154,8 +1155,8 @@ int serve(stlink_t *sl, st_state_t *st) { __s_addr = strsep(&tok, ":"); data = tok; - unsigned addr = strtoul(__s_addr, NULL, 16); - unsigned data_length = status - (data - packet); + unsigned addr = (unsigned) strtoul(__s_addr, NULL, 16); + unsigned data_length = status - (unsigned) (data - packet); // Length of decoded data cannot be more than // encoded, as escapes are removed. @@ -1205,7 +1206,7 @@ int serve(stlink_t *sl, st_state_t *st) { stlink_run(sl); while(1) { - int status = gdb_check_for_interrupt(client); + status = gdb_check_for_interrupt(client); if(status < 0) { ELOG("cannot check for int: %d\n", status); #ifdef __MINGW32__ @@ -1256,7 +1257,7 @@ int serve(stlink_t *sl, st_state_t *st) { break; case 'p': { - unsigned id = strtoul(&packet[1], NULL, 16); + unsigned id = (unsigned) strtoul(&packet[1], NULL, 16); unsigned myreg = 0xDEADDEAD; if(id < 16) { @@ -1303,8 +1304,8 @@ int serve(stlink_t *sl, st_state_t *st) { char* s_reg = &packet[1]; char* s_value = strstr(&packet[1], "=") + 1; - unsigned reg = strtoul(s_reg, NULL, 16); - unsigned value = strtoul(s_value, NULL, 16); + unsigned reg = (unsigned) strtoul(s_reg, NULL, 16); + unsigned value = (unsigned) strtoul(s_value, NULL, 16); if(reg < 16) { stlink_write_reg(sl, ntohl(value), reg); @@ -1341,7 +1342,7 @@ int serve(stlink_t *sl, st_state_t *st) { for(int i = 0; i < 16; i++) { char str[9] = {0}; strncpy(str, &packet[1 + i * 8], 8); - uint32_t reg = strtoul(str, NULL, 16); + uint32_t reg = (uint32_t) strtoul(str, NULL, 16); stlink_write_reg(sl, ntohl(reg), i); } @@ -1352,13 +1353,13 @@ int serve(stlink_t *sl, st_state_t *st) { char* s_start = &packet[1]; char* s_count = strstr(&packet[1], ",") + 1; - stm32_addr_t start = strtoul(s_start, NULL, 16); - unsigned count = strtoul(s_count, NULL, 16); + stm32_addr_t start = (stm32_addr_t) strtoul(s_start, NULL, 16); + unsigned count = (unsigned) strtoul(s_count, NULL, 16); unsigned adj_start = start % 4; unsigned count_rnd = (count + adj_start + 4 - 1) / 4 * 4; if (count_rnd > sl->flash_pgsz) - count_rnd = sl->flash_pgsz; + count_rnd = (unsigned) sl->flash_pgsz; if (count_rnd > 0x1800) count_rnd = 0x1800; if (count_rnd < count) @@ -1380,15 +1381,15 @@ int serve(stlink_t *sl, st_state_t *st) { char* s_count = strstr(&packet[1], ",") + 1; char* hexdata = strstr(packet, ":") + 1; - stm32_addr_t start = strtoul(s_start, NULL, 16); - unsigned count = strtoul(s_count, NULL, 16); + stm32_addr_t start = (stm32_addr_t) strtoul(s_start, NULL, 16); + unsigned count = (unsigned) strtoul(s_count, NULL, 16); if(start % 4) { unsigned align_count = 4 - start % 4; if (align_count > count) align_count = count; for(unsigned int i = 0; i < align_count; i ++) { - char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; - uint8_t byte = strtoul(hex, NULL, 16); + char hextmp[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; + uint8_t byte = strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; } stlink_write_mem8(sl, start, align_count); @@ -1402,8 +1403,8 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned aligned_count = count - count % 4; for(unsigned int i = 0; i < aligned_count; i ++) { - char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; - uint8_t byte = strtoul(hex, NULL, 16); + char hextmp[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; + uint8_t byte = strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; } stlink_write_mem32(sl, start, aligned_count); @@ -1415,8 +1416,8 @@ int serve(stlink_t *sl, st_state_t *st) { if(count) { for(unsigned int i = 0; i < count; i ++) { - char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; - uint8_t byte = strtoul(hex, NULL, 16); + char hextmp[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; + uint8_t byte = strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; } stlink_write_mem8(sl, start, count); @@ -1428,8 +1429,8 @@ int serve(stlink_t *sl, st_state_t *st) { case 'Z': { char *endptr; - stm32_addr_t addr = strtoul(&packet[3], &endptr, 16); - stm32_addr_t len = strtoul(&endptr[1], NULL, 16); + stm32_addr_t addr = (stm32_addr_t) strtoul(&packet[3], &endptr, 16); + stm32_addr_t len = (stm32_addr_t) strtoul(&endptr[1], NULL, 16); switch (packet[1]) { case '1': @@ -1467,7 +1468,7 @@ int serve(stlink_t *sl, st_state_t *st) { } case 'z': { char *endptr; - stm32_addr_t addr = strtoul(&packet[3], &endptr, 16); + stm32_addr_t addr = (stm32_addr_t) strtoul(&packet[3], &endptr, 16); //stm32_addr_t len = strtoul(&endptr[1], NULL, 16); switch (packet[1]) { diff --git a/src/sg.c b/src/sg.c index 646091aac..22464bc1b 100644 --- a/src/sg.c +++ b/src/sg.c @@ -584,7 +584,7 @@ int _stlink_sg_force_debug(stlink_t *sl) { // Read all arm-core registers. -int _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { +int _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -626,7 +626,7 @@ int _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 -int _stlink_sg_read_reg(stlink_t *sl, int r_idx, reg *regp) { +int _stlink_sg_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READREG; @@ -907,7 +907,7 @@ int _stlink_sg_exit_debug_mode(stlink_t *stl) // 4) the device driver is now ready for a switch to jtag/swd mode // TODO thinking, better error handling, wait until the kernel driver stops reseting the plugged-in device -stlink_backend_t _stlink_sg_backend = { +static stlink_backend_t _stlink_sg_backend = { _stlink_sg_close, _stlink_sg_exit_debug_mode, _stlink_sg_enter_swd_mode, diff --git a/src/tools/flash.c b/src/tools/flash.c index 7bebd82f9..50ad64092 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -14,7 +14,7 @@ #define DEBUG_LOG_LEVEL 100 #define STND_LOG_LEVEL 50 -stlink_t *connected_stlink = NULL; +static stlink_t *connected_stlink = NULL; static void cleanup(int signal __attribute__((unused))) { if (connected_stlink) { @@ -84,18 +84,19 @@ static int get_opts(struct opts* o, int ac, char** av) { ac--; av++; - int i=strlen(av[0]); - if(i%2 != 0){ + /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ + int j = (int) strlen(av[0]); + if(j%2 != 0){ puts("no valid hex value, length must be multiple of 2\n"); return -1; } - int j=0; - while(i>=0 && j<=13){ + int k=0; + while(j>=0 && k<=13){ char buffer[3]={0}; - memcpy(buffer,&av[0][i],2); - o->serial[12-j] = (char)strtol((const char*)buffer,NULL, 16); - j++; - i-=2; + memcpy(buffer,&av[0][j],2); + o->serial[12-k] = (char)strtol((const char*)buffer,NULL, 16); + k++; + j-=2; } ac--; av++; @@ -154,7 +155,8 @@ static int get_opts(struct opts* o, int ac, char** av) } o->filename = av[i + 1]; - o->addr = strtoul(av[i + 2], NULL, 16); + /** @todo This is a little evil as strtoul could return 0 and is of type unsigned long int */ + o->addr = (uint32_t) strtoul(av[i + 2], NULL, 16); return 0; } diff --git a/src/tools/gui/stlink-gui.c b/src/tools/gui/stlink-gui.c index 247373e9d..a56a2c34c 100644 --- a/src/tools/gui/stlink-gui.c +++ b/src/tools/gui/stlink-gui.c @@ -178,8 +178,8 @@ hexstr_to_guint32 (const gchar *str, GError **err) guint32 val; gchar *end_ptr; - val = strtoul (str, &end_ptr, 16); - if ((errno == ERANGE && val == LONG_MAX) || (errno != 0 && val == 0)) { + val = (guint32) strtoul (str, &end_ptr, 16); + if ((errno == ERANGE && val == UINT_MAX) || (errno != 0 && val == 0)) { g_set_error (err, g_quark_from_string ("hextou32"), 1, @@ -208,7 +208,7 @@ stlink_gui_update_mem_view (STlinkGUI *gui, struct mem_t *mem, GtkTreeView *view &iter, mem->base, mem->memory, - mem->size); + (gint) mem->size); gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); gtk_progress_bar_set_fraction (gui->progress.bar, 0); @@ -245,7 +245,7 @@ stlink_gui_populate_devmem_view (STlinkGUI *gui) guint n_read = MEM_READ_SIZE; if (off + MEM_READ_SIZE > gui->sl->flash_size) { - n_read = gui->sl->flash_size - off; + n_read = (guint) gui->sl->flash_size - off; /* align if needed */ if (n_read & 3) { @@ -316,11 +316,11 @@ stlink_gui_populate_filemem_view (STlinkGUI *gui) gui->file_mem.size = g_file_info_get_size (file_info); gui->file_mem.memory = g_malloc (gui->file_mem.size); - for (off = 0; off < gui->file_mem.size; off += MEM_READ_SIZE) { + for (off = 0; off < (gint) gui->file_mem.size; off += MEM_READ_SIZE) { guint n_read = MEM_READ_SIZE; - if (off + MEM_READ_SIZE > gui->file_mem.size) { - n_read = gui->file_mem.size - off; + if (off + MEM_READ_SIZE > (gint) gui->file_mem.size) { + n_read = (guint) gui->file_mem.size - off; } if (g_input_stream_read (G_INPUT_STREAM (input_stream), @@ -373,12 +373,11 @@ static void mem_jmp (GtkTreeView *view, do { guint32 addr; GValue value = G_VALUE_INIT; - GError *err = NULL; gtk_tree_model_get_value (model, &iter, 0, &value); if (G_VALUE_HOLDS_STRING (&value)) { - addr = hexstr_to_guint32 (g_value_get_string (&value), &err); - if (!err) { + addr = hexstr_to_guint32 (g_value_get_string (&value), err); + if (!*err) { if (addr == (jmp_addr & 0xFFFFFFF0)) { GtkTreeSelection *selection; GtkTreePath *path; @@ -407,6 +406,7 @@ devmem_jmp_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; GError *err = NULL; + (void) widget; gui = STLINK_GUI (data); @@ -427,6 +427,7 @@ filemem_jmp_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; GError *err = NULL; + (void) widget; gui = STLINK_GUI (data); @@ -448,7 +449,6 @@ static gchar * dev_format_chip_id (guint32 chip_id) { const struct stlink_chipid_params *params; - gint i; params = stlink_chipid_get_params(chip_id); if (!params) @@ -460,7 +460,7 @@ dev_format_chip_id (guint32 chip_id) static gchar * dev_format_mem_size (gsize flash_size) { - return g_strdup_printf ("%u kB", flash_size / 1024); + return g_strdup_printf ("%zu kB", flash_size / 1024); } @@ -522,6 +522,7 @@ connect_button_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; gint i; + (void) widget; gui = STLINK_GUI (data); @@ -573,6 +574,7 @@ static void disconnect_button_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; + (void) widget; gui = STLINK_GUI (data); @@ -595,8 +597,8 @@ stlink_gui_open_file (STlinkGUI *gui) dialog = gtk_file_chooser_dialog_new ("Open file", gui->window, GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + "_Cancel", GTK_RESPONSE_CANCEL, + "_Open", GTK_RESPONSE_ACCEPT, NULL); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { @@ -621,6 +623,7 @@ static void open_button_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; + (void) widget; gui = STLINK_GUI (data); @@ -658,6 +661,7 @@ flash_button_cb (GtkWidget *widget, gpointer data) guint32 address; gint result; GError *err = NULL; + (void) widget; gui = STLINK_GUI (data); g_return_if_fail (gui->sl != NULL); @@ -712,6 +716,8 @@ notebook_switch_page_cb (GtkNotebook *notebook, gpointer data) { STlinkGUI *gui; + (void) notebook; + (void) widget; gui = STLINK_GUI (data); @@ -738,6 +744,9 @@ dnd_received_cb (GtkWidget *widget, STlinkGUI *gui = STLINK_GUI (data); GtkListStore *store; GtkTreeIter iter; + (void) widget; + (void) x; + (void) y; if (selection_data != NULL && gtk_selection_data_get_length (selection_data) > 0) { @@ -837,7 +846,6 @@ stlink_gui_build_ui (STlinkGUI *gui) { gui->devmem_treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "devmem_treeview")); - gtk_tree_view_set_rules_hint (gui->devmem_treeview, TRUE); mem_view_init_headers (gui->devmem_treeview); devmem_store = gtk_list_store_new (5, G_TYPE_STRING, @@ -850,7 +858,6 @@ stlink_gui_build_ui (STlinkGUI *gui) { gui->filemem_treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "filemem_treeview")); - gtk_tree_view_set_rules_hint (gui->filemem_treeview, TRUE); mem_view_init_headers (gui->filemem_treeview); filemem_store = gtk_list_store_new (5, G_TYPE_STRING, @@ -910,7 +917,7 @@ stlink_gui_build_ui (STlinkGUI *gui) { gui->infobar = GTK_INFO_BAR (gtk_builder_get_object (builder, "infobar")); - gtk_info_bar_add_button (gui->infobar, GTK_STOCK_OK, GTK_RESPONSE_OK); + gtk_info_bar_add_button (gui->infobar, "_OK", GTK_RESPONSE_OK); gui->infolabel = GTK_LABEL (gtk_label_new ("")); gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (gui->infobar)), GTK_WIDGET (gui->infolabel)); diff --git a/src/tools/term.c b/src/tools/term.c index 9b46e2a4c..c07fcc70f 100644 --- a/src/tools/term.c +++ b/src/tools/term.c @@ -41,8 +41,8 @@ struct stlinky { | buf[2] << 16 \ | buf[3] << 24)) -static stlink_t* sl; -sigset_t sig_mask; +static stlink_t* gsl; +static sigset_t sig_mask; struct stlinky { stlink_t *sl; @@ -53,11 +53,11 @@ struct stlinky { void nonblock(int state); static void cleanup(int signal __attribute__((unused))) { - if (sl) { + if (gsl) { /* Switch back to mass storage mode before closing. */ - stlink_run(sl); - stlink_exit_debug_mode(sl); - stlink_close(sl); + stlink_run(gsl); + stlink_exit_debug_mode(gsl); + stlink_close(gsl); } printf("\n"); @@ -158,7 +158,7 @@ size_t stlinky_rx(struct stlinky *st, char* buffer) stlinky_read_buff(st, st->off + RX_BUFF_OFFSET + tail, head - tail, buffer); size_read += head - tail; } else if(head < tail){ - stlinky_read_buff(st, st->off + RX_BUFF_OFFSET + tail, st->bufsize - tail, buffer); + stlinky_read_buff(st, st->off + RX_BUFF_OFFSET + tail, (uint32_t) st->bufsize - tail, buffer); size_read += st->bufsize - tail; stlinky_read_buff(st, st->off + RX_BUFF_OFFSET, head, buffer + size_read); @@ -193,17 +193,17 @@ size_t stlinky_tx(struct stlinky *st, char* buffer, size_t siz) return 0; //copy in data (take care of possible split) - int first_chunk = head + siz >= st->bufsize ? st->bufsize - head : siz; - int second_chunk = siz - first_chunk; + int first_chunk = (head + siz >= st->bufsize) ? (int) st->bufsize - (int) head : (int) siz; + int second_chunk = (int) siz - first_chunk; //copy data - stlinky_write_buf(st, st->off + TX_BUFF_OFFSET(st->bufsize) + head, first_chunk, buffer); + stlinky_write_buf(st, st->off + (uint32_t) TX_BUFF_OFFSET(st->bufsize) + head, first_chunk, buffer); if (second_chunk > 0) - stlinky_write_buf(st, st->off + TX_BUFF_OFFSET(st->bufsize), + stlinky_write_buf(st, st->off + (uint32_t) TX_BUFF_OFFSET(st->bufsize), second_chunk, buffer + first_chunk); //increment head pointer - head = (head + siz) % st->bufsize; + head = (head + siz) % (uint32_t) st->bufsize; memcpy(st->sl->q_buf, &head, sizeof(head)); stlink_write_mem32(st->sl, st->off + TX_Q_OFFSET + sizeof(tail), sizeof(head)); @@ -252,37 +252,37 @@ int main(int ac, char** av) { sig_init(); - sl = stlink_open_usb(10, 1, NULL); - if (sl != NULL) { + gsl = stlink_open_usb(10, 1, NULL); + if (gsl != NULL) { printf("ST-Linky proof-of-concept terminal :: Created by Necromant for lulz\n"); - stlink_version(sl); - stlink_enter_swd_mode(sl); - printf("chip id: %#x\n", sl->chip_id); - printf("core_id: %#x\n", sl->core_id); + stlink_version(gsl); + stlink_enter_swd_mode(gsl); + printf("chip id: %#x\n", gsl->chip_id); + printf("core_id: %#x\n", gsl->core_id); cortex_m3_cpuid_t cpuid; - stlink_cpu_id(sl, &cpuid); + stlink_cpu_id(gsl, &cpuid); printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); - stlink_reset(sl); - stlink_force_debug(sl); - stlink_run(sl); - stlink_status(sl); + stlink_reset(gsl); + stlink_force_debug(gsl); + stlink_run(gsl); + stlink_status(gsl); /* wait for device to boot */ /* TODO: Make timeout adjustable via command line */ sleep(1); if(ac == 1){ - st = stlinky_detect(sl); + st = stlinky_detect(gsl); }else if(ac == 2){ st = malloc(sizeof(struct stlinky)); - st->sl = sl; + st->sl = gsl; st->off = (int)strtol(av[1], NULL, 16); printf("using stlinky at 0x%x\n", st->off); - stlink_read_mem32(sl, st->off + 4, 4); - st->bufsize = READ_UINT32_LE(sl->q_buf); + stlink_read_mem32(gsl, st->off + 4, 4); + st->bufsize = READ_UINT32_LE(gsl->q_buf); printf("stlinky buffer size 0x%zu \n", st->bufsize); }else{ cleanup(0); diff --git a/src/usb.c b/src/usb.c index 3a72035ab..1a41d6544 100644 --- a/src/usb.c +++ b/src/usb.c @@ -36,7 +36,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, if (libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, - txsize, + (int) txsize, &res, 3000)) return -1; @@ -44,7 +44,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, if (rxsize != 0) { if (libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, - rxsize, + (int) rxsize, &res, 3000)) return -1; @@ -69,7 +69,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, static inline int send_only (struct stlink_libusb* handle, int terminate, unsigned char* txbuf, size_t txsize) { - return send_recv(handle, terminate, txbuf, txsize, NULL, 0); + return (int) send_recv(handle, terminate, txbuf, txsize, NULL, 0); } @@ -107,7 +107,7 @@ int _stlink_usb_version(stlink_t *sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } return 0; @@ -155,7 +155,7 @@ int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } *data = read_uint32(rdata, 4); return 0; @@ -176,7 +176,7 @@ int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } return 0; @@ -279,9 +279,9 @@ int _stlink_usb_status(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } - sl->q_len = (size_t) size; + sl->q_len = (int) size; return 0; } @@ -299,7 +299,7 @@ int _stlink_usb_force_debug(stlink_t *sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } return 0; @@ -319,7 +319,7 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } return 0; @@ -337,7 +337,7 @@ int _stlink_usb_exit_dfu_mode(stlink_t* sl) { size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } return 0; @@ -361,7 +361,7 @@ int _stlink_usb_reset(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } return 0; @@ -383,7 +383,7 @@ int _stlink_usb_jtag_reset(stlink_t * sl, int value) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } return 0; @@ -404,7 +404,7 @@ int _stlink_usb_step(stlink_t* sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } return 0; @@ -428,7 +428,7 @@ int _stlink_usb_run(stlink_t* sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } return 0; @@ -446,7 +446,7 @@ int _stlink_usb_exit_debug_mode(stlink_t *sl) { size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { printf("[!] send_only\n"); - return size; + return (int) size; } return 0; @@ -467,16 +467,16 @@ int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } - sl->q_len = (size_t) size; + sl->q_len = (int) size; stlink_print_data(sl); return 0; } -int _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { +int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; unsigned char* const data = sl->q_buf; @@ -489,9 +489,9 @@ int _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } - sl->q_len = (size_t) size; + sl->q_len = (int) size; stlink_print_data(sl); for(i=0; i<16; i++) regp->r[i]= read_uint32(sl->q_buf, i*4); @@ -512,7 +512,7 @@ int _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { return 0; } -int _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { +int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -527,9 +527,9 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } - sl->q_len = (size_t) size; + sl->q_len = (int) size; stlink_print_data(sl); r = read_uint32(sl->q_buf, 0); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); @@ -558,7 +558,7 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { } /* See section C1.6 of the ARMv7-M Architecture Reference Manual */ -int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { +int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { uint32_t r; int ret; @@ -596,7 +596,7 @@ int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { return 0; } -int _stlink_usb_read_all_unsupported_regs(stlink_t *sl, reg *regp) { +int _stlink_usb_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { int ret; ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); @@ -617,7 +617,7 @@ int _stlink_usb_read_all_unsupported_regs(stlink_t *sl, reg *regp) { } /* See section C1.6 of the ARMv7-M Architecture Reference Manual */ -int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg *regp) { +int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, struct stlink_reg *regp) { int ret; if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ @@ -675,15 +675,15 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return size; + return (int) size; } - sl->q_len = (size_t) size; +sl->q_len = (int) size; stlink_print_data(sl); return 0; } -stlink_backend_t _stlink_usb_backend = { +static stlink_backend_t _stlink_usb_backend = { _stlink_usb_close, _stlink_usb_exit_debug_mode, _stlink_usb_enter_swd_mode, @@ -737,7 +737,8 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 } libusb_device **list; - int cnt = libusb_get_device_list(slu->libusb_ctx, &list); + /** @todo We should use ssize_t and use it as a counter if > 0. As per libusb API: ssize_t libusb_get_device_list (libusb_context *ctx, libusb_device ***list) */ + int cnt = (int) libusb_get_device_list(slu->libusb_ctx, &list); struct libusb_device_descriptor desc; int devBus =0; int devAddr=0; diff --git a/tests/usb.c b/tests/usb.c index 1ae6442c1..06fd73429 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -7,7 +7,7 @@ int main(int ac, char** av) (void)av; stlink_t* sl; - reg regs; + struct stlink_reg regs; sl = stlink_open_usb(10, 1, NULL); if (sl != NULL) { From 3d438166ce02689867fe599ace62be9607a69660 Mon Sep 17 00:00:00 2001 From: Greg Alexander Date: Sat, 4 Jun 2016 15:50:33 -0400 Subject: [PATCH 0438/1435] Don't read the target voltage on startup, because it crashes STM32F100. --- src/gdbserver/gdb-server.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index c50e5be32..55e0763ac 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -159,8 +159,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { int main(int argc, char** argv) { - int32_t voltage; - stlink_t *sl = NULL; st_state_t state; @@ -193,11 +191,6 @@ int main(int argc, char** argv) { ILOG("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); - voltage = stlink_target_voltage(sl); - if (voltage != -1) { - ILOG("Target voltage is %d mV.\n", voltage); - } - sl->verbose=0; current_memory_map = make_memory_map(sl); From 8924c51d9eb140c35158cd7938b5cc9c2b7128af Mon Sep 17 00:00:00 2001 From: Greg Alexander Date: Sun, 5 Jun 2016 08:31:10 -0400 Subject: [PATCH 0439/1435] Provide more detailed error messages when send_recv() fails. --- src/usb.c | 67 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/src/usb.c b/src/usb.c index 1a41d6544..856185f3e 100644 --- a/src/usb.c +++ b/src/usb.c @@ -33,32 +33,47 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, unsigned char* rxbuf, size_t rxsize) { /* note: txbuf and rxbuf can point to the same area */ int res = 0; + int t; - if (libusb_bulk_transfer(handle->usb_handle, handle->ep_req, + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, (int) txsize, &res, - 3000)) + 3000); + if (t) { + printf("[!] send_recv send request failed: %s\n", libusb_error_name(t)); return -1; + } else if ((size_t)res != txsize) { + printf("[!] send_recv send request wrote %d bytes (instead of %d).\n", + res, txsize); + } if (rxsize != 0) { - if (libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int) rxsize, &res, - 3000)) + 3000); + if (t) { + printf("[!] send_recv read reply failed: %s\n", + libusb_error_name(t)); return -1; + } } if ((handle->protocoll == 1) && terminate) { /* Read the SG reply */ unsigned char sg_buf[13]; - if (libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, sg_buf, 13, &res, - 3000)) + 3000); + if (t) { + printf("[!] send_recv read storage failed: %s\n", + libusb_error_name(t)); return -1; + } /* The STLink doesn't seem to evaluate the sequence number */ handle->sg_transfer_idx++; } @@ -106,7 +121,7 @@ int _stlink_usb_version(stlink_t *sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_GET_VERSION\n"); return (int) size; } @@ -127,10 +142,10 @@ int32_t _stlink_usb_target_voltage(stlink_t *sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_GET_TARGET_VOLTAGE\n"); return -1; } else if (size != 8) { - printf("[!] wrong length\n"); + printf("[!] wrong length STLINK_GET_TARGET_VOLTAGE\n"); return -1; } @@ -154,7 +169,7 @@ int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { write_uint32(&cmd[i], addr); size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_JTAG_READDEBUG_32BIT\n"); return (int) size; } *data = read_uint32(rdata, 4); @@ -175,7 +190,7 @@ int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { write_uint32(&cmd[i + 4], data); size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_JTAG_WRITEDEBUG_32BIT\n"); return (int) size; } @@ -238,7 +253,7 @@ int _stlink_usb_current_mode(stlink_t * sl) { 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"); + printf("[!] send_recv STLINK_GET_CURRENT_MODE\n"); return -1; } return sl->q_buf[0]; @@ -257,7 +272,7 @@ int _stlink_usb_core_id(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_DEBUG_READCOREID\n"); return -1; } @@ -278,7 +293,7 @@ int _stlink_usb_status(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_DEBUG_GETSTATUS\n"); return (int) size; } sl->q_len = (int) size; @@ -298,7 +313,7 @@ int _stlink_usb_force_debug(stlink_t *sl) { cmd[i++] = STLINK_DEBUG_FORCEDEBUG; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_DEBUG_FORCEDEBUG\n"); return (int) size; } @@ -318,7 +333,7 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_DEBUG_ENTER\n"); return (int) size; } @@ -336,7 +351,7 @@ int _stlink_usb_exit_dfu_mode(stlink_t* sl) { size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_DFU_EXIT\n"); return (int) size; } @@ -360,7 +375,7 @@ int _stlink_usb_reset(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_DEBUG_RESETSYS\n"); return (int) size; } @@ -382,7 +397,7 @@ int _stlink_usb_jtag_reset(stlink_t * sl, int value) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_JTAG_DRIVE_NRST\n"); return (int) size; } @@ -403,7 +418,7 @@ int _stlink_usb_step(stlink_t* sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_DEBUG_STEPCORE\n"); return (int) size; } @@ -427,7 +442,7 @@ int _stlink_usb_run(stlink_t* sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_DEBUG_RUNCORE\n"); return (int) size; } @@ -445,7 +460,7 @@ int _stlink_usb_exit_debug_mode(stlink_t *sl) { size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { - printf("[!] send_only\n"); + printf("[!] send_only STLINK_DEBUG_EXIT\n"); return (int) size; } @@ -466,7 +481,7 @@ int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_DEBUG_READMEM_32BIT\n"); return (int) size; } @@ -488,7 +503,7 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { cmd[i++] = STLINK_DEBUG_READALLREGS; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { - printf("[!] send_recv\n"); + printf("[!] send_recv STLINK_DEBUG_READALLREGS\n"); return (int) size; } sl->q_len = (int) size; @@ -526,7 +541,7 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { 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"); + printf("[!] send_recv STLINK_DEBUG_READREG\n"); return (int) size; } sl->q_len = (int) size; @@ -674,7 +689,7 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int 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"); + printf("[!] send_recv STLINK_DEBUG_WRITEREG\n"); return (int) size; } sl->q_len = (int) size; From ac43cfdfef8f3dc8d95cd31548b4786646f81c4c Mon Sep 17 00:00:00 2001 From: andrey Date: Tue, 7 Jun 2016 09:21:14 -0700 Subject: [PATCH 0440/1435] Do a JTAG reset prior to reading CPU information. This is needed when a CPU is in deep sleep mode, and its debug interface is switched off. --- src/usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/usb.c b/src/usb.c index 856185f3e..6ec93bd56 100644 --- a/src/usb.c +++ b/src/usb.c @@ -877,6 +877,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 } if (reset) { + stlink_jtag_reset(sl, 2); stlink_reset(sl); usleep(10000); } From d67d39f237c6449a3967193ad6e286eb2cf148ad Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 10 Jun 2016 14:44:30 +0200 Subject: [PATCH 0441/1435] Update README Add notice about broken stlink firmware V2.J16.S0 on STM32 L1 Discovery board --- README | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/README b/README index fc2231854..efffa2cda 100644 --- a/README +++ b/README @@ -251,6 +251,79 @@ of the flash: Issue(s): [#356](https://github.com/texane/stlink/issues/356) +### Stlink serial corrupts after one probe + +`lsusb -v` before `st-info --probe` with STM32 L1 Discovery board. With stlink firmware `V2.J16.S0`: + +``` +Bus 001 Device 004: ID 0483:3748 STMicroelectronics ST-LINK/V2 +Device Descriptor: + bLength 18 + bDescriptorType 1 + bcdUSB 2.00 + bDeviceClass 0 (Defined at Interface level) + bDeviceSubClass 0 + bDeviceProtocol 0 + bMaxPacketSize0 64 + idVendor 0x0483 STMicroelectronics + idProduct 0x3748 ST-LINK/V2 + bcdDevice 1.00 + iManufacturer 1 STMicroelectronics + iProduct 2 STM32 STLink + iSerial 3 Pÿk^FPgRUB1^C Date: Fri, 10 Jun 2016 15:12:23 +0200 Subject: [PATCH 0442/1435] src/usb.c: Dont crash when libusb_open fails, check return value --- src/usb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/usb.c b/src/usb.c index 856185f3e..c75476d6a 100644 --- a/src/usb.c +++ b/src/usb.c @@ -790,7 +790,10 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) || (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO)) { struct libusb_device_handle *handle; - libusb_open(list[cnt], &handle); + ret = libusb_open(list[cnt], &handle); + if (ret) + continue; + sl->serial_size = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial)); libusb_close(handle); From 3daa3f15cc5f3fe6f33f4bc33b3b61dbcc0c6ce7 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 18 Jun 2016 09:41:32 +0200 Subject: [PATCH 0443/1435] Initial support for STM32F7x7x, for nucleo-144, STM32F767ZI issue #433 --- include/stlink/chipid.h | 1 + src/chipid.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index a5012e38f..72094a733 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -52,6 +52,7 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_L0_CAT5 = 0x447, STLINK_CHIPID_STM32_F0_CAN = 0x448, STLINK_CHIPID_STM32_F7 = 0x449, + STLINK_CHIPID_STM32_F7XXXX = 0x451, STLINK_CHIPID_STM32_F410 = 0x458 }; diff --git a/src/chipid.c b/src/chipid.c index c3f1a9278..546e2384e 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -2,6 +2,17 @@ #include "stlink/chipid.h" static const struct stlink_chipid_params devices[] = { + { + //RM0410 document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_F7XXXX, + .description = "F76xxx device", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1ff0f442, // section 45.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x5C000, // "SRAM" byte size in hex from + .bootrom_base = 0x00200000, //! "System memory" starting address from + .bootrom_size = 0xEDC0 //! @todo "System memory" byte size in hex from + }, { //RM0385 and DS10916 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F7, From 1c04e4f54664836b8446d75302458331d3c45477 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 18 Jun 2016 09:46:54 +0200 Subject: [PATCH 0444/1435] TravisCI: Disable clang 3.8 builds (disabled apt repo), remove autotools --- .travis.yml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0fae3aaeb..3ae4a6333 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,31 +3,17 @@ language: c addons: apt: sources: - - llvm-toolchain-precise-3.8 - ubuntu-toolchain-r-test packages: - - clang-3.8 - g++-5 - gcc-5 script: - ./.travis.sh matrix: include: - - os: linux - compiler: gcc - env: "BUILD_SYSTEM=autotools" - - os: linux - compiler: clang - env: "BUILD_SYSTEM=autotools" - os: linux compiler: gcc-5 env: "BUILD_SYSTEM=cmake" - - os: linux - compiler: clang-3.8 - env: "BUILD_SYSTEM=cmake" - os: osx compiler: clang env: "BUILD_SYSTEM=cmake" - - os: osx - compiler: clang - env: "BUILD_SYSTEM=autotools" From 2563f43965a06e0fc2c7a09cd908478656076429 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 18 Jun 2016 09:49:39 +0200 Subject: [PATCH 0445/1435] TravisCI: Revert clang cmake build for linux --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 3ae4a6333..55a23fb12 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,10 +7,14 @@ addons: packages: - g++-5 - gcc-5 + - clang script: - ./.travis.sh matrix: include: + - os: linux + compiler: clang-3.8 + env: "BUILD_SYSTEM=cmake" - os: linux compiler: gcc-5 env: "BUILD_SYSTEM=cmake" From dfeb5a4e6f253a586543e7f72753ab96391dce2c Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 18 Jun 2016 19:40:27 +0200 Subject: [PATCH 0446/1435] flash_loader.c: Add STLINK_CHIPID_STM32_F7XXXX --- src/flash_loader.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/flash_loader.c b/src/flash_loader.c index 6ea324485..2e237c406 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -231,7 +231,8 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32f4_lv; loader_size = sizeof(loader_code_stm32f4_lv); } - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7){ + } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || + sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { loader_code = loader_code_stm32f7; loader_size = sizeof(loader_code_stm32f7); } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || sl->chip_id == STLINK_CHIPID_STM32_F04 || sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || sl->chip_id == STLINK_CHIPID_STM32_F0_SMALL || sl->chip_id == STLINK_CHIPID_STM32_F09X) { From 5a06869797992f3892c276a7163dedb679a8a5ea Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 18 Jun 2016 19:53:31 +0200 Subject: [PATCH 0447/1435] Add flash loader core id and chipid for STM32F767ZI with nucleo-144 --- include/stlink.h | 1 + src/flash_loader.c | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index c93086219..d1bf4815c 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -51,6 +51,7 @@ extern "C" { /* cortex core ids */ // TODO clean this up... #define STM32VL_CORE_ID 0x1ba01477 +#define STM32F7_CORE_ID 0x5ba02477 // Constant STM32 memory map figures #define STM32_FLASH_BASE 0x08000000 diff --git a/src/flash_loader.c b/src/flash_loader.c index 2e237c406..eee961808 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -202,7 +202,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* || sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); - } else if (sl->core_id == STM32VL_CORE_ID + } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F3 || sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL || sl->chip_id == STLINK_CHIPID_STM32_F303_HIGH @@ -231,7 +231,8 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32f4_lv; loader_size = sizeof(loader_code_stm32f4_lv); } - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || + } else if (sl->core_id == STM32F7_CORE_ID || + sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { loader_code = loader_code_stm32f7; loader_size = sizeof(loader_code_stm32f7); @@ -242,7 +243,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); } else { - ELOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); + ELOG("unknown coreid, not sure what flash loader to use, aborting! coreid: %x, chipid: %x\n", sl->core_id, sl->chip_id); return -1; } From 72fbf6a2c828ff9dc01e4fe0d46e5edf3b0fb13a Mon Sep 17 00:00:00 2001 From: texane Date: Mon, 20 Jun 2016 20:36:51 +0200 Subject: [PATCH 0448/1435] Fix zu missing on Windows toolchains. Use unsigned int casts instead. --- src/common.c | 13 +++++++------ src/flash_loader.c | 2 +- src/tools/gui/stlink-gui.c | 2 +- src/tools/info.c | 8 +++++--- src/tools/term.c | 4 ++-- src/usb.c | 4 ++-- 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/common.c b/src/common.c index 90725c64b..011bc08ac 100644 --- a/src/common.c +++ b/src/common.c @@ -611,9 +611,9 @@ int stlink_load_device_params(stlink_t *sl) { ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); // TODO make note of variable page size here..... - ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %zd bytes\n", + ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %u bytes\n", sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, - sl->flash_pgsz); + (unsigned int)sl->flash_pgsz); return 0; } @@ -1445,7 +1445,7 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, stlink_read_mem32(sl, address + (uint32_t) off, aligned_size); if (memcmp(sl->q_buf, data + off, cmp_size)) { - ELOG("Verification of flash failed at offset: %zd\n", off); + ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); return -1; } } @@ -1608,7 +1608,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t for(off = 0; off < len;) { size_t size = len - off > 0x8000 ? 0x8000 : len - off; - printf("size: %zu\n", size); + printf("size: %u\n", (unsigned int)size); if (stlink_flash_loader_run(sl, &fl, addr + (uint32_t) off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); @@ -1677,8 +1677,9 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t fprintf(stdout, "\r"); if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) { - fprintf(stdout, "\r%3zd/%3zd pages written", - off/sl->flash_pgsz, len/sl->flash_pgsz); + fprintf(stdout, "\r%3u/%3u pages written", + (unsigned int)(off/sl->flash_pgsz), + (unsigned int)(len/sl->flash_pgsz)); fflush(stdout); } diff --git a/src/flash_loader.c b/src/flash_loader.c index eee961808..2939af94f 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -263,7 +263,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe int i = 0; size_t count = 0; - DLOG("Running flash loader, write address:%#x, size: %zd\n", target, size); + DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); // FIXME This can never return -1 if (write_buffer_to_sram(sl, fl, buf, size) == -1) { // IMPOSSIBLE! diff --git a/src/tools/gui/stlink-gui.c b/src/tools/gui/stlink-gui.c index a56a2c34c..535f9bb33 100644 --- a/src/tools/gui/stlink-gui.c +++ b/src/tools/gui/stlink-gui.c @@ -460,7 +460,7 @@ dev_format_chip_id (guint32 chip_id) static gchar * dev_format_mem_size (gsize flash_size) { - return g_strdup_printf ("%zu kB", flash_size / 1024); + return g_strdup_printf ("%u kB", (unsigned int)(flash_size / 1024)); } diff --git a/src/tools/info.c b/src/tools/info.c index 0d0b82393..d3a315150 100644 --- a/src/tools/info.c +++ b/src/tools/info.c @@ -49,8 +49,10 @@ static void stlink_print_info(stlink_t *sl) printf("openocd: "); stlink_print_serial(sl, true); - printf(" flash: %zu (pagesize: %zu)\n", sl->flash_size, sl->flash_pgsz); - printf(" sram: %zu\n", sl->sram_size); + printf(" flash: %u (pagesize: %u)\n", + (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz); + + printf(" sram: %u\n", (unsigned int)sl->sram_size); printf(" chipid: 0x%.4x\n", sl->chip_id); params = stlink_chipid_get_params(sl->chip_id); @@ -65,7 +67,7 @@ static void stlink_probe(void) size = stlink_probe_usb(&stdevs); - printf("Found %zu stlink programmers\n", size); + printf("Found %u stlink programmers\n", (unsigned int)size); for (size_t n = 0; n < size; n++) stlink_print_info(stdevs[n]); diff --git a/src/tools/term.c b/src/tools/term.c index c07fcc70f..3f3517f9e 100644 --- a/src/tools/term.c +++ b/src/tools/term.c @@ -103,7 +103,7 @@ struct stlinky* stlinky_detect(stlink_t* sl) st->off = sram_base + off; stlink_read_mem32(sl, st->off + 4, 4); st->bufsize = READ_UINT32_LE(sl->q_buf); - printf("stlinky buffer size 0x%zu \n", st->bufsize); + printf("stlinky buffer size 0x%u \n", (unsigned int)st->bufsize); multiple++; } } @@ -283,7 +283,7 @@ int main(int ac, char** av) { printf("using stlinky at 0x%x\n", st->off); stlink_read_mem32(gsl, st->off + 4, 4); st->bufsize = READ_UINT32_LE(gsl->q_buf); - printf("stlinky buffer size 0x%zu \n", st->bufsize); + printf("stlinky buffer size 0x%u \n", (unsigned int)st->bufsize); }else{ cleanup(0); } diff --git a/src/usb.c b/src/usb.c index c75476d6a..6dcd7c913 100644 --- a/src/usb.c +++ b/src/usb.c @@ -44,8 +44,8 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, printf("[!] send_recv send request failed: %s\n", libusb_error_name(t)); return -1; } else if ((size_t)res != txsize) { - printf("[!] send_recv send request wrote %d bytes (instead of %d).\n", - res, txsize); + printf("[!] send_recv send request wrote %u bytes (instead of %u).\n", + (unsigned int)res, (unsigned int)txsize); } if (rxsize != 0) { From 471e7bbbd1efe221215c221ee2a54d831b63b81a Mon Sep 17 00:00:00 2001 From: Dave Flogeras Date: Tue, 21 Jun 2016 19:29:07 -0300 Subject: [PATCH 0449/1435] Fix a regression introduced in 71535104. Since STLINK V1 cannot read voltage, and attempting to do so breaks the USB communications, this patch will revert the behaviour to just blindly doing 32-bit writes on these programmers. --- src/common.c | 26 ++++++++++++++++---------- src/flash_loader.c | 23 +++++++++++++++-------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/common.c b/src/common.c index 011bc08ac..d804a4d7f 100644 --- a/src/common.c +++ b/src/common.c @@ -1578,17 +1578,23 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t /* TODO: Check that Voltage range is 2.7 - 3.6 V */ if (sl->chip_id != STLINK_CHIPID_STM32_L4) { - /* set parallelisim to 32 bit*/ - int voltage = stlink_target_voltage(sl); - if (voltage == -1) { - printf("Failed to read Target voltage\n"); - return voltage; - } else if (voltage > 2700) { - printf("enabling 32-bit flash writes\n"); + if( sl->version.stlink_v == 1 ) { + printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes on F4 devices\n"); write_flash_cr_psiz(sl, 2); - } else { - printf("Target voltage (%d mV) too low for 32-bit flash, using 8-bit flash writes\n", voltage); - write_flash_cr_psiz(sl, 0); + } + else { + /* set parallelisim to 32 bit*/ + int voltage = stlink_target_voltage(sl); + if (voltage == -1) { + printf("Failed to read Target voltage\n"); + return voltage; + } else if (voltage > 2700) { + printf("enabling 32-bit flash writes\n"); + write_flash_cr_psiz(sl, 2); + } else { + printf("Target voltage (%d mV) too low for 32-bit flash, using 8-bit flash writes\n", voltage); + write_flash_cr_psiz(sl, 0); + } } } else { /* L4 does not have a byte-write mode */ diff --git a/src/flash_loader.c b/src/flash_loader.c index 2939af94f..e05f35ae5 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -220,16 +220,23 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_F411RE || sl->chip_id == STLINK_CHIPID_STM32_F446 ) { - int voltage = stlink_target_voltage(sl); - if (voltage == -1) { - printf("Failed to read Target voltage\n"); - return voltage; - } else if (voltage > 2700) { + if( sl->version.stlink_v == 1 ) { + printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes on F4 devices\n"); loader_code = loader_code_stm32f4; loader_size = sizeof(loader_code_stm32f4); - } else { - loader_code = loader_code_stm32f4_lv; - loader_size = sizeof(loader_code_stm32f4_lv); + } + else { + int voltage = stlink_target_voltage(sl); + if (voltage == -1) { + printf("Failed to read Target voltage\n"); + return voltage; + } else if (voltage > 2700) { + loader_code = loader_code_stm32f4; + loader_size = sizeof(loader_code_stm32f4); + } else { + loader_code = loader_code_stm32f4_lv; + loader_size = sizeof(loader_code_stm32f4_lv); + } } } else if (sl->core_id == STM32F7_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F7 || From c61f160d691fa52acd8347f7ab4ead064693aa71 Mon Sep 17 00:00:00 2001 From: Chris Date: Sat, 25 Jun 2016 13:29:39 +0800 Subject: [PATCH 0450/1435] Fix an erase error in stm32f030 device. I run into flashing error with stm32f030. With some debugging I find out that the mass erase bit was dropped when flash programming bit already set on FLASH_CR. This cause erase and write error with my stm32f030 board. Mass erase never need the programming bit. Turn off the programming bit make stlink flash stm32f030 successfully. --- src/common.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 90725c64b..9dc1c0f27 100644 --- a/src/common.c +++ b/src/common.c @@ -298,20 +298,29 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { } static void set_flash_cr_mer(stlink_t *sl) { - uint32_t val, cr_reg, cr_mer; + uint32_t val, cr_reg, cr_mer, cr_pg; if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_mer = 1 << FLASH_CR_MER; + cr_pg = 1 << FLASH_CR_PG; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); + cr_pg = 1 << STM32L4_FLASH_CR_PG; } else { cr_reg = FLASH_CR; cr_mer = 1 << FLASH_CR_MER; + cr_pg = 1 << FLASH_CR_PG; } stlink_read_debug32(sl, cr_reg, &val); + if (val & cr_pg) { + /* STM32F030 will drop MER bit if PG was set */ + val &= ~cr_pg; + stlink_write_debug32(sl, cr_reg, val); + } + val |= cr_mer; stlink_write_debug32(sl, cr_reg, val); } From 3de5a547270a5280e346bed1ac09f8a0badf871f Mon Sep 17 00:00:00 2001 From: Jerome Lambourg Date: Tue, 19 Jul 2016 10:46:40 +0200 Subject: [PATCH 0451/1435] Fix gdb and flash support for the STM32F769I-Disco board. --- src/common.c | 8 ++++---- src/gdbserver/gdb-server.c | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/common.c b/src/common.c index 2ebe1e624..ebc1f8e51 100644 --- a/src/common.c +++ b/src/common.c @@ -1163,7 +1163,7 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ if (flashaddr >= 0x100000) { offset = 12; flashaddr -= 0x100000; - } + } if (flashaddr<0x4000) return (offset + 0); else if(flashaddr<0x8000) return(offset + 1); else if(flashaddr<0xc000) return(offset + 2); @@ -1211,7 +1211,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ else if(sector<5) sl->flash_pgsz=0x10000; else sl->flash_pgsz=0x20000; } - else if (sl->chip_id == STLINK_CHIPID_STM32_F7) { + else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { uint32_t sector=calculate_F7_sectornum(flashaddr); if (sector<4) sl->flash_pgsz=0x8000; else if(sector<5) sl->flash_pgsz=0x20000; @@ -1243,7 +1243,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", page, stlink_calculate_pagesize(sl, flashaddr)); write_flash_cr_bker_pnb(sl, page); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7) { + } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { // calculate the actual page from the address uint32_t sector=calculate_F7_sectornum(flashaddr); @@ -1255,7 +1255,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) uint32_t sector=calculate_F4_sectornum(flashaddr); fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, stlink_calculate_pagesize(sl, flashaddr)); - + //the SNB values for flash sectors in the second bank do not directly follow the values for the first bank on 2mb devices... if (sector >= 12) sector += 4; diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 702098d45..efe97e406 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -429,7 +429,7 @@ char* make_memory_map(stlink_t *sl) { if(sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F446) { strcpy(map, memory_map_template_F4); - } else if(sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F7) { + } else if(sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->core_id==STM32F7_CORE_ID) { strcpy(map, memory_map_template_F7); } else if(sl->chip_id==STLINK_CHIPID_STM32_F4_HD) { strcpy(map, memory_map_template_F4_HD); @@ -601,7 +601,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { return -1; } - if (sl->chip_id==STLINK_CHIPID_STM32_F7) { + if (sl->core_id==STM32F7_CORE_ID) { fpb_addr = addr; } else { fpb_addr = addr & ~0x3; @@ -625,7 +625,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { brk->addr = fpb_addr; - if (sl->chip_id==STLINK_CHIPID_STM32_F7) { + if (sl->core_id==STM32F7_CORE_ID) { if(set) brk->type = type; else brk->type = 0; @@ -751,7 +751,7 @@ static int flash_go(stlink_t *sl) { send, 0) < 0) goto error; length -= send; - + } } @@ -835,7 +835,7 @@ static void init_cache (stlink_t *sl) { int i; /* Assume only F7 has a cache. */ - if(sl->chip_id!=STLINK_CHIPID_STM32_F7) + if(sl->core_id!=STM32F7_CORE_ID) return; stlink_read_debug32(sl, CLIDR, &clidr); @@ -916,7 +916,7 @@ static void cache_sync(stlink_t *sl) { unsigned ccr; - if(sl->chip_id!=STLINK_CHIPID_STM32_F7) + if(sl->core_id!=STM32F7_CORE_ID) return; if (!cache_modified) return; @@ -1019,7 +1019,7 @@ int serve(stlink_t *sl, st_state_t *st) { if(!strcmp(queryName, "Supported")) { if(sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F4_HD - || sl->chip_id==STLINK_CHIPID_STM32_F7) { + || sl->core_id==STM32F7_CORE_ID) { reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); } else { From cb7533394a29f19a5b3df4feca79ecbbf38296db Mon Sep 17 00:00:00 2001 From: toniokroeger Date: Fri, 22 Jul 2016 18:53:15 +0200 Subject: [PATCH 0452/1435] Update udev path in README --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index efffa2cda..7d6f8ef3b 100644 --- a/README +++ b/README @@ -137,7 +137,7 @@ for GDB. ## Setting up udev rules For convenience, you may install udev rules file, 49-stlinkv*.rules, located -in the root of repository. You will need to copy it to /etc/udev/rules.d, +in etc/udev/rules.d (from root of repository). You will need to copy it to /etc/udev/rules.d, and then either reboot or execute ``` From 57cf59a86930b37d0d408fc58b6f13b44c8a431a Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Wed, 3 Aug 2016 11:04:20 +0200 Subject: [PATCH 0453/1435] cmake: Add proper detection of sys/mman.h. Fixes #450 Signed-off-by: Jerry Jacobs --- CMakeLists.txt | 6 ++++++ include/stlink/mmap.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7846cb175..ca46074da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ project(stlink C) cmake_minimum_required(VERSION 2.8.7) include(CheckCCompilerFlag) +include(CheckIncludeFile) find_package(PkgConfig) set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") @@ -47,6 +48,11 @@ elseif() add_cflag_if_supported("-O2") endif() +CHECK_INCLUDE_FILE(sys/mman.h STLINK_HAVE_SYS_MMAN_H) +if (STLINK_HAVE_SYS_MMAN_H) + add_definitions(-DSTLINK_HAVE_SYS_MMAN_H) +endif() + set(STLINK_HEADERS include/stlink.h include/stlink/usb.h diff --git a/include/stlink/mmap.h b/include/stlink/mmap.h index 71de819fa..ab94fb7d4 100644 --- a/include/stlink/mmap.h +++ b/include/stlink/mmap.h @@ -1,7 +1,7 @@ #ifndef STLINK_MMAP_H #define STLINK_MMAP_H -#ifdef HAVE_SYS_MMAN_H +#ifdef STLINK_HAVE_SYS_MMAN_H #include #else From 9aac78d18496f3c14dda52434142c9edd08c7098 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 18 Jun 2016 16:19:09 +0200 Subject: [PATCH 0454/1435] Deprecate autotools --- .appveyor.yml | 20 ++ .travis.sh | 21 +-- .travis.yml | 14 +- .version | 1 + ACKNOWLEDGMENTS | 2 - AUTHORS | 19 -- CMakeLists.txt | 92 ++++++++- COPYING | 27 --- ChangeLog | 9 + INSTALL.mingw | 44 ----- Makefile.am | 59 ------ NEWS | 0 README | 335 --------------------------------- README.md | 253 ++++++++++++++++++++++++- TODO.md | 11 -- autogen.sh | 2 - cmake/modules/Find7Zip.cmake | 5 + cmake/modules/FindLibUSB.cmake | 61 ++++-- configure.ac | 59 ------ doc/build_mingw.md | 23 +++ doc/release.md | 10 + scripts/appveyor-mingw.sh | 21 +++ scripts/mingw64-build.bat | 12 ++ src/common.c | 2 +- src/gdbserver/gdb-remote.c | 4 +- src/gdbserver/gdb-server.c | 4 +- src/tools/gui/Makefile.am | 30 --- src/usb.c | 2 +- 28 files changed, 505 insertions(+), 637 deletions(-) create mode 100644 .appveyor.yml create mode 100644 .version delete mode 100644 ACKNOWLEDGMENTS delete mode 100644 AUTHORS delete mode 100644 COPYING delete mode 100644 INSTALL.mingw delete mode 100644 Makefile.am delete mode 100644 NEWS delete mode 100644 README mode change 120000 => 100644 README.md delete mode 100644 TODO.md delete mode 100755 autogen.sh create mode 100644 cmake/modules/Find7Zip.cmake delete mode 100644 configure.ac create mode 100644 doc/build_mingw.md create mode 100644 doc/release.md create mode 100644 scripts/appveyor-mingw.sh create mode 100644 scripts/mingw64-build.bat delete mode 100644 src/tools/gui/Makefile.am diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 000000000..9e53a07bc --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,20 @@ +version: '{build}' +environment: + matrix: + - GENERATOR: "MSYS Makefiles" + ARCH: i686 # this is for 32-bit MinGW-w64 + - GENERATOR: "MSYS Makefiles" + ARCH: 64 +cache: + - i686-4.9.2-release-win32-sjlj-rt_v3-rev1.7z + - x86_64-4.9.2-release-win32-seh-rt_v3-rev1.7z +build_script: +- ps: | + mkdir build + cd build + if ($env:GENERATOR -ne "MSYS Makefiles") { + cmake .. -G"$env:GENERATOR" + cmake --build . --config Debug + } +- cmd: | + if "%GENERATOR%"=="MSYS Makefiles" (C:\MinGW\msys\1.0\bin\sh --login /c/projects/stlink/scripts/appveyor-mingw.sh) diff --git a/.travis.sh b/.travis.sh index 9e28d3ca1..9fa519dad 100755 --- a/.travis.sh +++ b/.travis.sh @@ -5,24 +5,15 @@ ls -1 /usr/bin/clang* ls -1 /usr/bin/scan-build* echo "----" -if [ "$TRAVIS_OS_NAME" != "osx" ]; then +if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq || true sudo apt-get install -qq -y --no-install-recommends libusb-1.0.0-dev libgtk-3-dev else brew install libusb fi -if [ "$BUILD_SYSTEM" == "cmake" ]; then - mkdir build - cd build - cmake .. - make -else - ./autogen.sh - if [ "$TRAVIS_OS_NAME" == "osx" ]; then - ./configure - else - ./configure --with-gtk-gui - fi - make -fi +echo "=== Building Debug" +mkdir -p build/Debug && cd build/Debug && cmake -DCMAKE_BUILD_TYPE=Debug ../../ && make && make package && cd - + +echo "=== Building Release" +mkdir -p build/Release && cd build/Release && cmake -DCMAKE_BUILD_TYPE=Release ../../ && make && make package && cd - diff --git a/.travis.yml b/.travis.yml index 55a23fb12..543c0edec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,21 +3,25 @@ language: c addons: apt: sources: +# - llvm-toolchain-precise-3.8 - ubuntu-toolchain-r-test packages: + - clang +# - clang-3.8 - g++-5 - gcc-5 - - clang script: - ./.travis.sh matrix: include: - os: linux - compiler: clang-3.8 - env: "BUILD_SYSTEM=cmake" + compiler: clang +# - os: linux +# compiler: clang-3.8 - os: linux compiler: gcc-5 - env: "BUILD_SYSTEM=cmake" + compiler: gcc-5 +# - os: linux +# compiler: clang-3.8 - os: osx compiler: clang - env: "BUILD_SYSTEM=cmake" diff --git a/.version b/.version new file mode 100644 index 000000000..d72f26267 --- /dev/null +++ b/.version @@ -0,0 +1 @@ +2.0.0-dev diff --git a/ACKNOWLEDGMENTS b/ACKNOWLEDGMENTS deleted file mode 100644 index acd89e3ea..000000000 --- a/ACKNOWLEDGMENTS +++ /dev/null @@ -1,2 +0,0 @@ -The development team wants to acknowledge the following people: -- STMicroelectronics discovery kit team for their low cost boards and for their help in development process. \ No newline at end of file diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index aae9e2963..000000000 --- a/AUTHORS +++ /dev/null @@ -1,19 +0,0 @@ -m@capitanio.org -spen@spen-soft.co.uk -texane@gmail.com -whitequark@whitequark.org -grestm@galexander.org -karlp@tweak.net.au -h0rr0rrdrag@gmail.com -mstempin@com1.fr -bon@elektron.ikp.physik.tu-darmstadt.de -nelsonjm@macpod.neta -ned@bike-nomad.com -csamuelson@swingpal.com -bravikov@gmail.com -jnosky - codegrinder69@hotmail.com -marpe@mimuw.edu.pl -marco.cassinerio@gmail.com -jserv@0xlab.org -michael@pratt.im -jerry.jacobs@xor-gate.org diff --git a/CMakeLists.txt b/CMakeLists.txt index ca46074da..cf18e0228 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,14 +1,58 @@ -project(stlink C) cmake_minimum_required(VERSION 2.8.7) +project(stlink C) include(CheckCCompilerFlag) include(CheckIncludeFile) find_package(PkgConfig) +if (POLICY CMP0042) + # Newer cmake on MacOS should use @rpath + cmake_policy (SET CMP0042 NEW) +endif () + set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") +# Determine package version. +find_package (Git QUIET) +if (DEFINED ENV{TRAVIS_TAG} AND NOT "$ENV{TRAVIS_TAG}" STREQUAL "") + set (STLINK_PACKAGE_VERSION "$ENV{TRAVIS_TAG}") +elseif (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") + # Working off a git repo, using git versioning + + # Check if HEAD is pointing to a tag + execute_process ( + COMMAND "${GIT_EXECUTABLE}" describe --always + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + OUTPUT_VARIABLE STLINK_PACKAGE_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + + # If the sources have been changed locally, add -dirty to the version. + execute_process ( + COMMAND "${GIT_EXECUTABLE}" diff --quiet + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + RESULT_VARIABLE res) + + if (res EQUAL 1) + set (STLINK_PACKAGE_VERSION "${STLINK_PACKAGE_VERSION}-dirty") + endif() +elseif (EXISTS ${PROJECT_SOURCE_DIR}/.version) + # If git is not available (e.g. when building from source package) + # we can extract the package version from .version file. + file (STRINGS .version STLINK_PACKAGE_VERSION) +else () + set (STLINK_PACKAGE_VERSION "Unknown") +endif() + +if(WIN32) + find_package(7Zip REQUIRED) + message(STATUS "7Zip Location: " ${ZIP_LOCATION}) +endif() + find_package(LibUSB REQUIRED) -pkg_check_modules(gtk gtk+-3.0) +if (NOT APPLE AND NOT WIN32) + find_package(PkgConfig) + pkg_check_modules(gtk gtk+-3.0) +endif () function(add_cflag_if_supported flag) string(REPLACE "-" "_" flagclean ${flag}) @@ -38,12 +82,19 @@ add_cflag_if_supported("-Wshorten-64-to-32") add_cflag_if_supported("-Wimplicit-function-declaration") add_cflag_if_supported("-Wredundant-decls") add_cflag_if_supported("-Wundef") -add_cflag_if_supported("-fPIC") +if (NOT MSYS OR MINGW) + add_cflag_if_supported("-fPIC") +endif () + +if (CMAKE_BUILD_TYPE STREQUAL "") + set (CMAKE_BUILD_TYPE "Debug") +endif () if(${CMAKE_BUILD_TYPE} MATCHES "Debug") include(CTest) add_cflag_if_supported("-ggdb") add_cflag_if_supported("-O0") + #set (STLINK_PACKAGE_VERSION "${STLINK_PACKAGE_VERSION}-debug") elseif() add_cflag_if_supported("-O2") endif() @@ -53,6 +104,8 @@ if (STLINK_HAVE_SYS_MMAN_H) add_definitions(-DSTLINK_HAVE_SYS_MMAN_H) endif() +message("Building ${PROJECT_NAME} ${STLINK_PACKAGE_VERSION}") + set(STLINK_HEADERS include/stlink.h include/stlink/usb.h @@ -72,6 +125,10 @@ set(STLINK_SOURCE src/flash_loader.c ) +if (WIN32 OR MSYS OR MINGW) + set (STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") # TODO +endif () + include_directories(${LIBUSB_INCLUDE_DIR}) include_directories(include) include_directories(src/mingw) @@ -86,7 +143,7 @@ if (APPLE) find_library(CoreFoundation CoreFoundation) find_library(IOKit IOKit) target_link_libraries(${PROJECT_NAME} ${CoreFoundation} ${IOKit} ${ObjC}) -endif() +endif () add_executable(st-flash src/tools/flash.c) target_link_libraries(st-flash ${PROJECT_NAME}) @@ -98,7 +155,11 @@ add_executable(st-util src/gdbserver/gdb-remote.c src/gdbserver/gdb-remote.h src/gdbserver/gdb-server.c src/gdbserver/gdb-server.h) -target_link_libraries(st-util ${PROJECT_NAME}) +if (WIN32 OR MSYS OR MINGW) + target_link_libraries(st-util ${PROJECT_NAME} wsock32 ws2_32) +else () + target_link_libraries(st-util ${PROJECT_NAME}) +endif () install(TARGETS ${PROJECT_NAME} st-flash st-util st-info RUNTIME DESTINATION bin @@ -114,20 +175,22 @@ if(NOT MINGW) RUNTIME DESTINATION bin) endif() -if(gtk_FOUND) +if (NOT APPLE AND gtk_FOUND) include_directories(SYSTEM ${gtk_INCLUDE_DIRS}) set(GUI_SOURCES src/tools/gui/stlink-gui.c src/tools/gui/stlink-gui.h) + # TODO REMOVE whole stlink-gui-local target, fixup auto-search of ui file in implementation add_executable(stlink-gui-local ${GUI_SOURCES}) set_target_properties(stlink-gui-local PROPERTIES COMPILE_FLAGS -DSTLINK_UI_DIR=\\"${CMAKE_CURRENT_SOURCE_DIR}/gui\\") target_link_libraries(stlink-gui-local stlink ${gtk_LDFLAGS}) - set(INSTALLED_UI_DIR ${CMAKE_INSTALL_PREFIX}/share) + set(INSTALLED_UI_DIR share/stlink) add_executable(stlink-gui ${GUI_SOURCES}) + # TODO REMOVE, fixup auto-search of ui file in implementation set_target_properties(stlink-gui PROPERTIES - COMPILE_FLAGS -DSTLINK_UI_DIR=\\"${INSTALLED_UI_DIR}\\") + COMPILE_FLAGS -DSTLINK_UI_DIR=\\"${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}\\") target_link_libraries(stlink-gui stlink ${gtk_LDFLAGS}) install(TARGETS stlink-gui @@ -137,3 +200,16 @@ if(gtk_FOUND) endif() add_subdirectory(tests) + +set (CPACK_PACKAGE_NAME ${PROJECT_NAME}) +set (CPACK_PACKAGE_VERSION ${STLINK_PACKAGE_VERSION}) +set (CPACK_SOURCE_GENERATOR "TBZ2;ZIP") +set (CPACK_SOURCE_IGNORE_FILES "/build/;/.git/;~$;${CPACK_SOURCE_IGNORE_FILES}") +set (CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${STLINK_PACKAGE_VERSION}") +if (APPLE) + set(CPACK_GENERATOR "ZIP") + file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/osx") + set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/osx") +endif () +add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source) +include (CPack) diff --git a/COPYING b/COPYING deleted file mode 100644 index 37b124eba..000000000 --- a/COPYING +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2011 The "Capt'ns Missing Link" Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Martin Capitanio nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ChangeLog b/ChangeLog index 00d82ee9f..355ba08ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,15 @@ Stlink ChangeLog ================ +v2.0.0 +====== + +Ongoing development + +Major changes: + +* Deprecation of autotools (autoconf, automake) + v1.2.0 ====== diff --git a/INSTALL.mingw b/INSTALL.mingw deleted file mode 100644 index c8df0fd70..000000000 --- a/INSTALL.mingw +++ /dev/null @@ -1,44 +0,0 @@ -from dandev37: - -Here's a step by step from a clean install to successfully setup MinGW and build -libusb-1.0 and stlink for MS Windows. Hopefully this helps someone. - -1. Install MinGW and MSYS to C:\MinGW with the graphical installer from -http://sourceforge.net/projects/mingw/files/Installer/mingw-get-setup.exe/download -and add these packages: -mingw32-base -mingw-developer-toolkit - -2. Add C:\MinGW\bin to your path. -Note: a user reports she had to use c:\MinGW\msys\1.0\bin - -3. Create the C:\MinGW\msys\1.0\etc\fstab file to mount C:\MinGW as /mingw as per -http://www.mingw.org/wiki/MSYS: - -#Win32_Path Mount_Point -c:/mingw /mingw - -4. Download these three glib, pkg-config, pkg-config-dev archives and extract -contents to C:\MinGW -http://win32builder.gnome.org/packages/3.6/glib_2.34.3-1_win32.zip -http://win32builder.gnome.org/packages/3.6/pkg-config_0.28-1_win32.zip -http://win32builder.gnome.org/packages/3.6/pkg-config-dev_0.28-1_win32.zip - -5. Download latest libusb-1.0 source from -https://github.com/libusb/libusb (newer repo, includes USB 3.0 hub support) -OR the old git://git.libusb.org/libusb.git (original repo, NO USB 3.0 support) -and build (prefix as per http://www.mingw.org/wiki/MSYS) - -./autogen.sh -./configure --prefix=/mingw -make -make install - -6. Repeat for stlink source from https://github.com/texane/stlink - -./autogen.sh -./configure --prefix=/mingw -make -make install - -7. Enjoy the fruits of the stlink developers. diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 79ce10c22..000000000 --- a/Makefile.am +++ /dev/null @@ -1,59 +0,0 @@ -# Makefile.am -- Process this file with automake to produce Makefile.in - -SUBDIRS = . $(STLINK_HAS_GUI) - -AUTOMAKE_OPTIONS = subdir-objects - -if MINGW -bin_PROGRAMS = st-flash st-util st-info -else -bin_PROGRAMS = st-flash st-util st-term st-info -endif - -noinst_LIBRARIES = libstlink.a - -st_flash_SOURCES = src/tools/flash.c -st_term_SOURCES = src/tools/term.c -st_info_SOURCES = src/tools/info.c -st_util_SOURCES = src/gdbserver/gdb-remote.c src/gdbserver/gdb-remote.h src/gdbserver/gdb-server.c src/mingw/mingw.c src/mingw/mingw.h - -CFILES = \ - src/chipid.c \ - src/common.c \ - src/usb.c \ - src/sg.c \ - src/logging.c \ - src/flash_loader.c - -if !MINGW -CFILES += src/tools/term.c -endif - -HFILES = \ - include/stlink.h \ - include/stlink/chipid.h \ - include/stlink/usb.h \ - include/stlink/flash_loader.h \ - include/stlink/commands.h \ - include/stlink/sg.h \ - include/stlink/logging.h \ - include/stlink/mmap.h - -libstlink_a_SOURCES = $(CFILES) $(HFILES) - -libstlink_a_LIBADD = $(LIBOBJS) -libstlink_a_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/include - -st_flash_LDADD = libstlink.a -st_flash_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/include -I$(top_srcdir)/src/mingw - -st_util_LDADD = libstlink.a -st_util_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/include -I$(top_srcdir)/src/mingw - -st_term_LDADD = libstlink.a -st_term_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/include -I$(top_srcdir)/src/mingw - -st_info_LDADD = libstlink.a -st_info_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/include -I$(top_srcdir)/src/mingw - -EXTRA_DIST = autogen.sh diff --git a/NEWS b/NEWS deleted file mode 100644 index e69de29bb..000000000 diff --git a/README b/README deleted file mode 100644 index 7d6f8ef3b..000000000 --- a/README +++ /dev/null @@ -1,335 +0,0 @@ -Open source version of the STMicroelectronics Stlink Tools -========================================================== - -[![Build Status](https://travis-ci.org/texane/stlink.svg?branch=master)](https://travis-ci.org/texane/stlink) - -## HOWTO - -First, you have to know there are several boards supported by the software. -Those boards use a chip to translate from USB to JTAG commands. The chip is -called stlink and there are 2 versions: - -* STLINKv1, present on STM32VL discovery kits, -* STLINKv2, present on STM32L discovery and later kits. - -Two different transport layers are used: - -* STLINKv1 uses SCSI passthru commands over USB -* STLINKv2 uses raw USB commands. - -## Common requirements - -* Debian based distros (debian, ubuntu) - * `build-essential` - -* `pkg-config` -* `intltool` -* `cmake` or (`autoconf` && `automake` && `autogen`) -* `libusb-1.0` (plus development headers for building, on debian based distros `libusb-1.0.0-dev` package) -* (optional) for `stlink-gui` we need libgtk-3-dev - -## For STLINKv1 - -The STLINKv1's SCSI emulation is very broken, so the best thing to do -is tell your operating system to completely ignore it. - -Options (do one of these before you plug it in) - -* `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` -* or 1. `echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.conf` -* 2. `modprobe -r usb-storage && modprobe usb-storage` -* or 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` -* 2. `modprobe -r usb-storage && modprobe usb-storage` - -## For STLINKv2 - -You're ready to go :) - -## Build from sources - -### Autotools - -This project was converted to Autotools by a well meaning individual. The -following steps will build the project for you. - -``` -$ ./autogen.sh -$ ./configure --with-gtk-gui -$ make -``` - -### CMake - -``` -$ mkdir build && cd build -$ cmake -DCMAKE_BUILD_TYPE=Debug .. -$ make -``` - -## Using the gdb server - -To run the gdb server: (you do not need sudo if you have set up -permissions correctly) - -``` -$ make && [sudo] ./st-util - -There are a few options: - -./st-util - usage: - - -h, --help Print this help - -vXX, --verbose=XX Specify a specific verbosity level (0..99) - -v, --verbose Specify generally verbose logging - -s X, --stlink_version=X - Choose what version of stlink to use, (defaults to 2) - -1, --stlinkv1 Force stlink version 1 - -p 4242, --listen_port=1234 - Set the gdb server listen port. (default port: 4242) - -m, --multi - Set gdb server to extended mode. - st-util will continue listening for connections after disconnect. - -n, --no-reset - Do not reset board on connection. -``` - -The STLINKv2 device to use can be specified in the environment -variable STLINK_DEVICE on the format `:`. - -Then, in your project directory, someting like this... -(remember, you need to run an _ARM_ gdb, not an x86 gdb) - -``` -$ arm-none-eabi-gdb fancyblink.elf -... -(gdb) tar extended-remote :4242 -... -(gdb) load -Loading section .text, size 0x458 lma 0x8000000 -Loading section .data, size 0x8 lma 0x8000458 -Start address 0x80001c1, load size 1120 -Transfer rate: 1 KB/sec, 560 bytes/write. -(gdb) -... -(gdb) continue -``` - -Have fun! - -## Resetting the chip from GDB - -You may reset the chip using GDB if you want. You'll need to use `target -extended-remote' command like in this session: - -``` -(gdb) target extended-remote localhost:4242 -Remote debugging using localhost:4242 -0x080007a8 in _startup () -(gdb) kill -Kill the program being debugged? (y or n) y -(gdb) run -Starting program: /home/whitequark/ST/apps/bally/firmware.elf -``` - -Remember that you can shorten the commands. `tar ext :4242' is good enough -for GDB. - -## Setting up udev rules - -For convenience, you may install udev rules file, 49-stlinkv*.rules, located -in etc/udev/rules.d (from root of repository). You will need to copy it to /etc/udev/rules.d, -and then either reboot or execute - -``` -$ udevadm control --reload-rules -$ udevadm trigger -``` - -Udev will now create a /dev/stlinkv2_XX or /dev/stlinkv1_XX file, with the appropriate permissions. -This is currently all the device is for, (only one stlink of each version is supported at -any time presently) - -## Running programs from SRAM - -You can run your firmware directly from SRAM if you want to. Just link -it at 0x20000000 and do - -``` -(gdb) load firmware.elf -``` - -It will be loaded, and pc will be adjusted to point to start of the -code, if it is linked correctly (i.e. ELF has correct entry point). - -## Writing to flash - -The GDB stub ships with a correct memory map, including the flash area. -If you would link your executable to 0x08000000 and then do -(gdb) load firmware.elf -then it would be written to the memory. - -## FAQ - -Q: My breakpoints do not work at all or only work once. - -A: Optimizations can cause severe instruction reordering. For example, -if you are doing something like `REG = 0x100;' in a loop, the code may -be split into two parts: loading 0x100 into some intermediate register -and moving that value to REG. When you set up a breakpoint, GDB will -hook to the first instruction, which may be called only once if there are -enough unused registers. In my experience, -O3 causes that frequently. - -Q: At some point I use GDB command `next', and it hangs. - -A: Sometimes when you will try to use GDB `next' command to skip a loop, -it will use a rather inefficient single-stepping way of doing that. -Set up a breakpoint manually in that case and do `continue'. - -Q: Load command does not work in GDB. - -A: Some people report XML/EXPAT is not enabled by default when compiling -GDB. Memory map parsing thus fail. Use --enable-expat. - -## Currently known working combinations of programmer and target - -STLink v1 (as found on the 32VL Discovery board) - -Known working targets: - -* STM32F100xx (Medium Density VL) -* STM32F103 (according to jpa- on ##stm32) - -No information: - -* everything else! - -STLink v2 (as found on the 32L and F4 Discovery boards), known working targets: - -* STM32F030F4P6 (custom board) -* STM32F0Discovery (STM32F0 Discovery board) -* STM32F100xx (Medium Density VL, as on the 32VL Discovery board) -* STM32L1xx (STM32L Discovery board) -* STM32F103VC, STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on custom boards - from [UweBonnes/wiki_fuer_alex](https://github.com/UweBonnes/wiki_fuer_alex/tree/master/layout) -* STM32F103VET6 (HY-STM32 board) -* STM32F105RCT6 (DecaWave EVB1000 board) -* STM32F303xx (STM32F3 Discovery board) -* STM32F407xx (STM32F4 Discovery board) -* STM32F429I-DISCO (STM32F4 Discovery board with LCD) -* STM32F439VIT6 (discovery board reseated CPU) -* STM32L052K8T6 (custom board) -* STM32L151CB (custom board) -* STM32L152RB (STM32L-Discovery board, custom board) -* STM32F051R8T6 (STM320518-EVAL board) - -STLink v2-1 (as found on the Nucleo boards), known working targets: - -* STM32F401xx (STM32 Nucleo-F401RE board) -* STM32F030R8T6 (STM32 Nucleo-F030R8 board) -* STM32F072RBT6 (STM32 Nucleo-F072RB board) -* STM32F103RB (STM32 Nucleo-F103RB board) -* STM32F303RET6 (STM32 Nucleo-F303RE board) -* STM32F334R8 (STM32 Nucleo-F334R8 board) -* STM32F411RET6 (STM32 Nucleo-F411RE board) -* STM32F756NGHx (STMF7 evaluation board) -* STM32L053R8 (STM32 Nucleo-L053R8 board) - -Please report any and all known working combinations so I can update this! - -## Known bugs - -### Sometimes flashing only works after a mass erase - -There is seen a problem sometimes where a flash loader run error occurs and is resolved after mass-erase -of the flash: - -``` -2015-12-09T22:01:57 INFO src/stlink-common.c: Successfully loaded flash loader in sram -2015-12-09T22:02:18 ERROR src/stlink-common.c: flash loader run error -2015-12-09T22:02:18 ERROR src/stlink-common.c: run_flash_loader(0x8000000) failed! == -1 -``` - -Issue(s): [#356](https://github.com/texane/stlink/issues/356) - -### Stlink serial corrupts after one probe - -`lsusb -v` before `st-info --probe` with STM32 L1 Discovery board. With stlink firmware `V2.J16.S0`: - -``` -Bus 001 Device 004: ID 0483:3748 STMicroelectronics ST-LINK/V2 -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 2.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x0483 STMicroelectronics - idProduct 0x3748 ST-LINK/V2 - bcdDevice 1.00 - iManufacturer 1 STMicroelectronics - iProduct 2 STM32 STLink - iSerial 3 Pÿk^FPgRUB1^C> /etc/modprobe.conf` +* 2. `modprobe -r usb-storage && modprobe usb-storage` +* or 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` +* 2. `modprobe -r usb-storage && modprobe usb-storage` + +## For STLINKv2 + +You're ready to go :) + +## Build from sources + +``` +$ mkdir build && cd build +$ cmake -DCMAKE_BUILD_TYPE=Debug .. +$ make +``` + +## Using the gdb server + +To run the gdb server: (you do not need sudo if you have set up +permissions correctly) + +``` +$ make && [sudo] ./st-util + +There are a few options: + +./st-util - usage: + + -h, --help Print this help + -vXX, --verbose=XX Specify a specific verbosity level (0..99) + -v, --verbose Specify generally verbose logging + -s X, --stlink_version=X + Choose what version of stlink to use, (defaults to 2) + -1, --stlinkv1 Force stlink version 1 + -p 4242, --listen_port=1234 + Set the gdb server listen port. (default port: 4242) + -m, --multi + Set gdb server to extended mode. + st-util will continue listening for connections after disconnect. + -n, --no-reset + Do not reset board on connection. +``` + +The STLINKv2 device to use can be specified in the environment +variable STLINK_DEVICE on the format `:`. + +Then, in your project directory, someting like this... +(remember, you need to run an _ARM_ gdb, not an x86 gdb) + +``` +$ arm-none-eabi-gdb fancyblink.elf +... +(gdb) tar extended-remote :4242 +... +(gdb) load +Loading section .text, size 0x458 lma 0x8000000 +Loading section .data, size 0x8 lma 0x8000458 +Start address 0x80001c1, load size 1120 +Transfer rate: 1 KB/sec, 560 bytes/write. +(gdb) +... +(gdb) continue +``` + +Have fun! + +## Resetting the chip from GDB + +You may reset the chip using GDB if you want. You'll need to use `target +extended-remote' command like in this session: + +``` +(gdb) target extended-remote localhost:4242 +Remote debugging using localhost:4242 +0x080007a8 in _startup () +(gdb) kill +Kill the program being debugged? (y or n) y +(gdb) run +Starting program: /home/whitequark/ST/apps/bally/firmware.elf +``` + +Remember that you can shorten the commands. `tar ext :4242' is good enough +for GDB. + +## Setting up udev rules + +For convenience, you may install udev rules file, 49-stlinkv*.rules, located +in the root of repository. You will need to copy it to /etc/udev/rules.d, +and then either reboot or execute + +``` +$ udevadm control --reload-rules +$ udevadm trigger +``` + +Udev will now create a /dev/stlinkv2_XX or /dev/stlinkv1_XX file, with the appropriate permissions. +This is currently all the device is for, (only one stlink of each version is supported at +any time presently) + +## Running programs from SRAM + +You can run your firmware directly from SRAM if you want to. Just link +it at 0x20000000 and do + +``` +(gdb) load firmware.elf +``` + +It will be loaded, and pc will be adjusted to point to start of the +code, if it is linked correctly (i.e. ELF has correct entry point). + +## Writing to flash + +The GDB stub ships with a correct memory map, including the flash area. +If you would link your executable to 0x08000000 and then do +(gdb) load firmware.elf +then it would be written to the memory. + +## FAQ + +Q: My breakpoints do not work at all or only work once. + +A: Optimizations can cause severe instruction reordering. For example, +if you are doing something like `REG = 0x100;' in a loop, the code may +be split into two parts: loading 0x100 into some intermediate register +and moving that value to REG. When you set up a breakpoint, GDB will +hook to the first instruction, which may be called only once if there are +enough unused registers. In my experience, -O3 causes that frequently. + +Q: At some point I use GDB command `next', and it hangs. + +A: Sometimes when you will try to use GDB `next' command to skip a loop, +it will use a rather inefficient single-stepping way of doing that. +Set up a breakpoint manually in that case and do `continue'. + +Q: Load command does not work in GDB. + +A: Some people report XML/EXPAT is not enabled by default when compiling +GDB. Memory map parsing thus fail. Use --enable-expat. + +## Currently known working combinations of programmer and target + +STLink v1 (as found on the 32VL Discovery board) + +Known working targets: + +* STM32F100xx (Medium Density VL) +* STM32F103 (according to jpa- on ##stm32) + +No information: + +* everything else! + +STLink v2 (as found on the 32L and F4 Discovery boards), known working targets: + +* STM32F030F4P6 (custom board) +* STM32F0Discovery (STM32F0 Discovery board) +* STM32F100xx (Medium Density VL, as on the 32VL Discovery board) +* STM32L1xx (STM32L Discovery board) +* STM32F103VC, STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on custom boards + from [UweBonnes/wiki_fuer_alex](https://github.com/UweBonnes/wiki_fuer_alex/tree/master/layout) +* STM32F103VET6 (HY-STM32 board) +* STM32F105RCT6 (DecaWave EVB1000 board) +* STM32F303xx (STM32F3 Discovery board) +* STM32F407xx (STM32F4 Discovery board) +* STM32F429I-DISCO (STM32F4 Discovery board with LCD) +* STM32F439VIT6 (discovery board reseated CPU) +* STM32L052K8T6 (custom board) +* STM32L151CB (custom board) +* STM32L152RB (STM32L-Discovery board, custom board) +* STM32F051R8T6 (STM320518-EVAL board) + +STLink v2-1 (as found on the Nucleo boards), known working targets: + +* STM32F401xx (STM32 Nucleo-F401RE board) +* STM32F030R8T6 (STM32 Nucleo-F030R8 board) +* STM32F072RBT6 (STM32 Nucleo-F072RB board) +* STM32F103RB (STM32 Nucleo-F103RB board) +* STM32F303RET6 (STM32 Nucleo-F303RE board) +* STM32F334R8 (STM32 Nucleo-F334R8 board) +* STM32F411RET6 (STM32 Nucleo-F411RE board) +* STM32F756NGHx (STMF7 evaluation board) +* STM32L053R8 (STM32 Nucleo-L053R8 board) + +Please report any and all known working combinations so I can update this! + +## Known bugs + +### Sometimes flashing only works after a mass erase + +There is seen a problem sometimes where a flash loader run error occurs and is resolved after mass-erase +of the flash: + +``` +2015-12-09T22:01:57 INFO src/stlink-common.c: Successfully loaded flash loader in sram +2015-12-09T22:02:18 ERROR src/stlink-common.c: flash loader run error +2015-12-09T22:02:18 ERROR src/stlink-common.c: run_flash_loader(0x8000000) failed! == -1 +``` + +Issue(s): [#356](https://github.com/texane/stlink/issues/356) + +## Contributing and versioning + +* The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) +* When creating a pull request, please open first a issue for discussion of new features +* TODO: Enforcement of coding style (linux codestyle + checkpatch) + +## License + +The stlink library and tools are licensed under the [BSD license](LICENSE). With +some exceptions on external components. diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 9c5059a49..000000000 --- a/TODO.md +++ /dev/null @@ -1,11 +0,0 @@ -# flash tool - -- improve flash writing, still use word fast write... too slow - -# documentation - -- make README points to doc/tutorial - -# testing - -- compile and test a realtime kernel (e.g ChibiOS) diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index 2af5ccdac..000000000 --- a/autogen.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -autoreconf --install --force --verbose diff --git a/cmake/modules/Find7Zip.cmake b/cmake/modules/Find7Zip.cmake new file mode 100644 index 000000000..c264d12f7 --- /dev/null +++ b/cmake/modules/Find7Zip.cmake @@ -0,0 +1,5 @@ +find_program(ZIP_LOCATION NAMES 7z.exe + HINTS + "C:\\Program Files\\7-Zip\\" + "C:\\Program Files (x86)\\7-Zip\\" +) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index 7f14ca125..99e872c3e 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -6,28 +6,61 @@ # LIBUSB_LIBRARY - The libraries needed to use libusb # LIBUSB_DEFINITIONS - Compiler switches required for using libusb -FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h - HINTS - /usr - /usr/local - /opt - PATH_SUFFIXES libusb-1.0 - ) +if(WIN32 OR MINGW OR MSYS) + set(LIBUSB_WIN_VERSION "1.0.20") + set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) + set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) + set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/libusb-${LIBUSB_WIN_VERSION}) -if (APPLE) - set(LIBUSB_NAME libusb-1.0.a) -else() - set(LIBUSB_NAME usb-1.0) + if (EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) + message(STATUS "libusb archive already in build folder") + else () + message(STATUS "libusb downloading ${LIBUSB_WIN_VERSION}") + file(DOWNLOAD + https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download + ${LIBUSB_WIN_ARCHIVE_PATH} + SHOW_PROGRESS) + endif () + + execute_process(COMMAND ${ZIP_LOCATION} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER}) endif() -FIND_LIBRARY(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} +find_path(LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr /usr/local /opt + ${LIBUSB_WIN_OUTPUT_FOLDER}/include + PATH_SUFFIXES libusb-1.0 ) -INCLUDE(FindPackageHandleStandardArgs) +if (APPLE) + set(LIBUSB_NAME libusb-1.0.a) +elseif(MSYS OR MINGW) + set(LIBUSB_NAME usb-1.0) +elseif(WIN32) + set(LIBUSB_NAME libusb-1.0.lib) +else() + set(LIBUSB_NAME usb-1.0) +endif() + +if (MSYS OR MINGW) + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/static) + else () + find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static) + endif () +else () + find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS + /usr + /usr/local + /opt) +endif () + +include(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) -MARK_AS_ADVANCED(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) +mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) diff --git a/configure.ac b/configure.ac deleted file mode 100644 index 7a101d55d..000000000 --- a/configure.ac +++ /dev/null @@ -1,59 +0,0 @@ -# -*- Autoconf -*- -# Process this file with autoconf to produce a configure script. - -AC_PREREQ(2.61) -AC_INIT([stlink],[1.2.0],[davem@devkitpro.org]) -AC_CONFIG_SRCDIR([src/common.c]) -AC_CONFIG_LIBOBJ_DIR([src]) -AM_INIT_AUTOMAKE([1.10]) - - -# Checks for programs. -AC_PROG_CC -AC_PROG_INSTALL -AC_CANONICAL_HOST -AC_CANONICAL_BUILD -AC_PROG_RANLIB -AM_PROG_CC_C_O - -AC_CHECK_HEADERS(sys/mman.h) -AC_CHECK_HEADERS(sys/poll.h) -AC_REPLACE_FUNCS(mmap) - -if ! hash pkg-config; then - echo "ERROR: pkg-config is needed..." - exit 1 -fi - -# Checks for libraries. -PKG_CHECK_MODULES(USB, libusb-1.0 >= 1.0.0,, - AC_MSG_ERROR([*** Required libusb-1.0 >= 1.0.0 not installed ***])) -AC_CHECK_LIB([usbpath],[usb_path2devnum],,,-lusb) - -LIBS="$LIBS $USB_LIBS" -CFLAGS="$CFLAGS $USB_CFLAGS" - -case "${host}" in - *-mingw32*) - LIBS="$LIBS -lws2_32" - CPPFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CPPFLAGS" - AC_DEFINE_UNQUOTED(MINGW,1,[This is a MinGW system]) - AM_CONDITIONAL(MINGW, true) - ;; - *) - AM_CONDITIONAL(MINGW, false) -esac - -STLINK_HAS_GUI= -AC_ARG_WITH([gtk_gui], AS_HELP_STRING([--with-gtk-gui], [enable GTK3+ gui])) -if test "x$with_gtk_gui" = "xyes"; then - PKG_CHECK_MODULES([GTK3], [gtk+-3.0]) - PKG_CHECK_MODULES([GLIB], [glib-2.0 > 2.32.0]) - STLINK_HAS_GUI=src/tools/gui - AC_CONFIG_FILES([src/tools/gui/Makefile]) -fi -AC_SUBST([STLINK_HAS_GUI]) - -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT - diff --git a/doc/build_mingw.md b/doc/build_mingw.md new file mode 100644 index 000000000..6327b57c6 --- /dev/null +++ b/doc/build_mingw.md @@ -0,0 +1,23 @@ +Building with MinGW under Windows +================================= + +## Prequistes + +* 7Zip +* CMake 2.8 or higher +* MinGW64 GCC toolchain (5.3.0) + +## Installation + +1. Install 7Zip from http://www.7-zip.org +2. Install CMake from https://cmake.org/download +3. Install MinGW64 from https://sourceforge.net/projects/mingw-w64 (mingw-w64-install.exe) +4. Git clone or download stlink sourcefiles zip +5. Create build folder in source + +# Building + +Check and execute `\scripts\mingw64-build.bat` + +NOTE: when installing different toolchains make sure you edit the path in the `mingw64-build.bat` + the build script uses currently `C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin` diff --git a/doc/release.md b/doc/release.md new file mode 100644 index 000000000..c2dca87b2 --- /dev/null +++ b/doc/release.md @@ -0,0 +1,10 @@ +Release +======= + +This document describes the steps takes for developers to create a release + +1. Update `.version` with semantic version: `x.x.x` +2. Update `README.md` with semantic version `x.x.x` in commits badge +2. Create and push git tag and commits `git tag x.x.x` +3. Create source tarball/zipfile with `make dist` +4. Create binary package with `make package` diff --git a/scripts/appveyor-mingw.sh b/scripts/appveyor-mingw.sh new file mode 100644 index 000000000..4842410ba --- /dev/null +++ b/scripts/appveyor-mingw.sh @@ -0,0 +1,21 @@ +#!/bin/sh +set -e +cd `dirname "$0"`/.. +if [ "$ARCH" = "i686" ]; then + f=i686-4.9.2-release-win32-sjlj-rt_v3-rev1.7z + if ! [ -e $f ]; then + curl -LsSO http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.2/threads-win32/sjlj/$f + fi + 7z x $f > /dev/null + mv mingw32 /MinGW +else + f=x86_64-4.9.2-release-win32-seh-rt_v3-rev1.7z + if ! [ -e $f ]; then + curl -LsSO http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.2/threads-win32/seh/$f + fi + 7z x $f > /dev/null + mv mingw64 /MinGW +fi +cd build +cmake .. -G"$GENERATOR" +cmake --build . --config RelWithDebInfo diff --git a/scripts/mingw64-build.bat b/scripts/mingw64-build.bat new file mode 100644 index 000000000..18397f0e0 --- /dev/null +++ b/scripts/mingw64-build.bat @@ -0,0 +1,12 @@ +### +# MinGW64 build helper for windows +# * Sets the correct PATH to compiler and tools +# * Generates MinGW Makefile with CMake +# * Build binaries with mingw32-make +# +# Read documentation about this file in doc/build_mingw.md +### +@echo off +set PATH=C:\Program Files (x86)\CMake\bin;C:\Program Files\CMake\bin;C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin;%PATH% +cmake -G "MinGW Makefiles" .. +mingw32-make diff --git a/src/common.c b/src/common.c index ebc1f8e51..47c6e35be 100644 --- a/src/common.c +++ b/src/common.c @@ -15,7 +15,7 @@ #include "stlink/logging.h" #ifndef _WIN32 -#define O_BINARY 0 +#define O_BINARY 0 //! @todo get rid of this OH MY (@xor-gate) #endif /* todo: stm32l15xxx flash memory, pm0062 manual */ diff --git a/src/gdbserver/gdb-remote.c b/src/gdbserver/gdb-remote.c index 73a157d34..a5d3f4c03 100644 --- a/src/gdbserver/gdb-remote.c +++ b/src/gdbserver/gdb-remote.c @@ -7,11 +7,11 @@ #include #include #include -#include #include #ifdef __MINGW32__ -#include "mingw.h" +#include #else +#include #include #endif diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index efe97e406..5a85d0f0b 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -9,11 +9,11 @@ #include #include #include -#include #include #ifdef __MINGW32__ -#include "mingw.h" +#include #else +#include #include #include #include diff --git a/src/tools/gui/Makefile.am b/src/tools/gui/Makefile.am deleted file mode 100644 index 23e582fa8..000000000 --- a/src/tools/gui/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -bin_PROGRAMS = stlink-gui - -stlink_gui_SOURCES = \ - stlink-gui.c \ - stlink-gui.h - -stlink_gui_CPPFLAGS = \ - -I$(top_srcdir)/include \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir)/src \ - @GTK3_CFLAGS@ - -stlink_gui_CFLAGS = \ - $(WARN_CFLAGS) \ - $(AM_CFLAGS) \ - -DSTLINK_UI_DIR="\"$(uidir)\"" - -stlink_gui_LDFLAGS = \ - $(AM_LDFLAGS) - -stlink_gui_LDADD = \ - $(INTLLIBS) \ - $(top_builddir)/libstlink.a \ - @GTK3_LIBS@ - -uidir = $(pkgdatadir)/ui -ui_DATA = stlink-gui.ui -EXTRA_DIST = $(ui_DATA) - --include $(top_srcdir)/git.mk diff --git a/src/usb.c b/src/usb.c index 6dcd7c913..7054fa1a4 100644 --- a/src/usb.c +++ b/src/usb.c @@ -45,7 +45,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, return -1; } else if ((size_t)res != txsize) { printf("[!] send_recv send request wrote %u bytes (instead of %u).\n", - (unsigned int)res, (unsigned int)txsize); + (unsigned int)res, (unsigned int)txsize); } if (rxsize != 0) { From a17b4079ca6128b07774873ac2bbdbc181ec5ff7 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Wed, 3 Aug 2016 20:27:30 +0200 Subject: [PATCH 0455/1435] Reorganise aux files, add sg test to CMakeLists --- .cproject | 593 ------------------------------------ .gitignore | 32 -- ChangeLog | 64 ---- ChangeLog.md | 65 +++- tests/CMakeLists.txt | 1 + tests/{stlink_sg.c => sg.c} | 12 +- 6 files changed, 66 insertions(+), 701 deletions(-) delete mode 100644 .cproject delete mode 100644 ChangeLog mode change 120000 => 100644 ChangeLog.md rename tests/{stlink_sg.c => sg.c} (95%) diff --git a/.cproject b/.cproject deleted file mode 100644 index ff034aaae..000000000 --- a/.cproject +++ /dev/null @@ -1,593 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -make -all -true -true -true - - -make -clean -true -true -true - - -make - -CONFIG_USE_LIBSG=0 -true -true -true - - -make -clean CONFIG_USE_LIBSG=0 -true -true -true - - -make -CONFIG_STM32F4_DISCOVERY=1 -true -true -true - - -make -clean CONFIG_STM32F4_DISCOVERY=1 -true -true -true - - -make - -all -true -true -true - - -make - -clean -true -true -false - - -make - -all -true -true -true - - -make - -clean -true -true -true - - -make - -all -true -true -true - - -make - -clean -true -true -true - - -make -CONFIG_STM32F4_DISCOVERY=1 -true -true -true - - -make -clean -true -true -true - - -make -CONFIG_STM32F4_DISCOVERY=1 -true -true -true - - -make -clean CONFIG_STM32F4_DISCOVERY=1 -true -true -true - - -make -CONFIG_STM32F4_DISCOVERY=1 -true -true -true - - -make -clean CONFIG_STM32F4_DISCOVERY=1 -true -true -true - - -make -CONFIGURE_USE_LIBSG=0 -true -true -true - - -make - -clean CONFIG_USE_LIBSG=0 -true -true -true - - -make - -CONFIG_STM32F4_DISCOVERY=1 -true -true -true - - -make - -clean -true -true -true - - -make -all -true -true -true - - -make -clean -true -true -true - - -make - -CONFIG_USE_LIBSG=0 -true -true -true - - -make -clean -true -true -true - - -make -all -true -true -true - - -make -clean -true -true -true - - -make -CONFIG_STM32F4_DISCOVERY=1 -true -true -true - - -make -clean CONFIG_STM32F4_DISCOVERY=1 -true -true -true - - -make -CONFIG_STM32F4_DISCOVERY=1 -true -true -true - - -make -clean CONFIG_STM32F4_DISCOVERY=1 -true -true -true - - -make - -all -true -true -true - - -make - -clean -true -true -false - - -make - -all -true -true -true - - -make - -clean -true -true -true - - -make -all -true -true -true - - -make -clean -true -true -true - - -make -all -true -true -true - - -make - -all -true -true -true - - -make - -clean -true -true -true - - -make - -CONFIG_STM32F4_DISCOVERY=1 -true -true -true - - -make - -clean CONFIG_STM32F4_DISCOVERY=1 -true -true -true - - - - - - - - - diff --git a/.gitignore b/.gitignore index 1c8296454..378eac25d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,33 +1 @@ build -INSTALL -Makefile.in -aclocal.m4 -autom4te.cache -config.guess -config.sub -configure -depcomp -install-sh -ltmain.sh -missing -*.bz2 -*.lo -*.o -.libs -libtool -*.la -config.log -config.status -compile -st-flash -st-util -st-term -st-info -test_usb -test_sg -*.deps* -*.dirstamp -*.a -Makefile -*.exe -example/blink/*.elf diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index 355ba08ab..000000000 --- a/ChangeLog +++ /dev/null @@ -1,64 +0,0 @@ -Stlink ChangeLog -================ - -v2.0.0 -====== - -Ongoing development - -Major changes: - -* Deprecation of autotools (autoconf, automake) - -v1.2.0 -====== - -Release date: 16 may 2016 - -Features added: - -* Add multiple stlink probing (`st-info --probe`, `st-info --hla-serial`) with printing serial in hex and OpenOCD `hla_serial` format (Jerry Jacobs) -* Add stlink usb probe API functions (Jerry Jacobs) -* Added parameter to specify one stlink v2 of many (Georg von Zengen) - -Changes: - -* Refactoring/fixes of flash loader (Maxime Coquelin) - -Updates and fixes: - -* Synchronize cache for stm32f7 (Tristan Gingold) -* Allow flashing of STM32L4 down to 1.71 V (Greg Meiste) -* Fix on stm32l4 to clear flash mass erase flags on CR (Bruno Dal Bo) -* Proper writing of page 0 of second bank for stm32l476xe (Tobias Badertscher) -* Trace the read data in stlink_read_debug32 and not the address of the variable (Tobias Badertscher) -* Mac OS X El Capitan platform support confirmation (Nikolay) -* Do not send a NUL at end of packets to gdb (Tristan Gingold) -* Correctly compute flash write size for partial pages (Dave Vandervies) -* _stlink_usb_reset use hardreset (mlundinse) -* Make sure MCU is halted before running RAM based flashloaders (mlundinse) -* Could not flash STM32_F3_SMALL (Max Chen) -* STM32F4 8-bit support for 1.8v operation (Andy Isaacson) -* Fix F2 memory map (Nicolas Schodet) -* Memory map for stm32f42xxx and stm32f43xxx devices (Craig Lilley) -* Stm32l0x flash loader (Robin Kreis) - -Chip support added for: - -* STM32L053R8 (Jean-Luc Béchennec) -* STM32F7 Support (mlundinse) -* Add STM32L4 to CHIPID #defines and devices[], flash driver and loaded (Dave Vandervies) -* Basic support for F446 (Pavel Kirienko) -* STM32F303 High Density -* STM32L1xx Cat.2 devices (Nicolas Schodet) - -Board support added for: - -* Nucleo-F303RE (Kyle Manna) -* Nucleo-F411RE (texane) - -Build system: - -* Travis: Initial support for Travis continues integration on Linux & Mac OS X (Jerry Jacobs) -* CMake: Document in README.md and add extra strict compiler flags (Jerry Jacobs) -* CMake: First stab at a cmake build (Josh Bialkowski) diff --git a/ChangeLog.md b/ChangeLog.md deleted file mode 120000 index b0936e8d0..000000000 --- a/ChangeLog.md +++ /dev/null @@ -1 +0,0 @@ -ChangeLog \ No newline at end of file diff --git a/ChangeLog.md b/ChangeLog.md new file mode 100644 index 000000000..355ba08ab --- /dev/null +++ b/ChangeLog.md @@ -0,0 +1,64 @@ +Stlink ChangeLog +================ + +v2.0.0 +====== + +Ongoing development + +Major changes: + +* Deprecation of autotools (autoconf, automake) + +v1.2.0 +====== + +Release date: 16 may 2016 + +Features added: + +* Add multiple stlink probing (`st-info --probe`, `st-info --hla-serial`) with printing serial in hex and OpenOCD `hla_serial` format (Jerry Jacobs) +* Add stlink usb probe API functions (Jerry Jacobs) +* Added parameter to specify one stlink v2 of many (Georg von Zengen) + +Changes: + +* Refactoring/fixes of flash loader (Maxime Coquelin) + +Updates and fixes: + +* Synchronize cache for stm32f7 (Tristan Gingold) +* Allow flashing of STM32L4 down to 1.71 V (Greg Meiste) +* Fix on stm32l4 to clear flash mass erase flags on CR (Bruno Dal Bo) +* Proper writing of page 0 of second bank for stm32l476xe (Tobias Badertscher) +* Trace the read data in stlink_read_debug32 and not the address of the variable (Tobias Badertscher) +* Mac OS X El Capitan platform support confirmation (Nikolay) +* Do not send a NUL at end of packets to gdb (Tristan Gingold) +* Correctly compute flash write size for partial pages (Dave Vandervies) +* _stlink_usb_reset use hardreset (mlundinse) +* Make sure MCU is halted before running RAM based flashloaders (mlundinse) +* Could not flash STM32_F3_SMALL (Max Chen) +* STM32F4 8-bit support for 1.8v operation (Andy Isaacson) +* Fix F2 memory map (Nicolas Schodet) +* Memory map for stm32f42xxx and stm32f43xxx devices (Craig Lilley) +* Stm32l0x flash loader (Robin Kreis) + +Chip support added for: + +* STM32L053R8 (Jean-Luc Béchennec) +* STM32F7 Support (mlundinse) +* Add STM32L4 to CHIPID #defines and devices[], flash driver and loaded (Dave Vandervies) +* Basic support for F446 (Pavel Kirienko) +* STM32F303 High Density +* STM32L1xx Cat.2 devices (Nicolas Schodet) + +Board support added for: + +* Nucleo-F303RE (Kyle Manna) +* Nucleo-F411RE (texane) + +Build system: + +* Travis: Initial support for Travis continues integration on Linux & Mac OS X (Jerry Jacobs) +* CMake: Document in README.md and add extra strict compiler flags (Jerry Jacobs) +* CMake: First stab at a cmake build (Josh Bialkowski) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6f20fa922..5d114a608 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,5 +1,6 @@ set(TESTS usb + sg ) foreach(test ${TESTS}) diff --git a/tests/stlink_sg.c b/tests/sg.c similarity index 95% rename from tests/stlink_sg.c rename to tests/sg.c index db7eed325..d12f6ba43 100644 --- a/tests/stlink_sg.c +++ b/tests/sg.c @@ -7,8 +7,7 @@ #include #include #include -#include "stlink-common.h" -#include "uglylogging.h" +#include static void __attribute__((unused)) mark_buf(stlink_t *sl) { memset(sl->q_buf, 0, sizeof(sl->q_buf)); @@ -165,15 +164,6 @@ int main(int argc, char *argv[]) { stlink_read_mem32(sl, 0x20000000, 1024 * 6); stlink_read_mem32(sl, 0x20000000 + 1024 * 6, 1024 * 2); #endif -#if 1 - reg regs; - stlink_read_all_regs(sl, ®s); - stlink_step(sl); - fputs("++++++++++ write r0 = 0x12345678\n", stderr); - stlink_write_reg(sl, 0x12345678, 0); - stlink_read_reg(sl, 0, ®s); - stlink_read_all_regs(sl, ®s); -#endif #if 0 stlink_run(sl); stlink_status(sl); From ee2681ecebc8b2284cab02e1dd40536dfb91fc51 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Wed, 3 Aug 2016 20:59:21 +0200 Subject: [PATCH 0456/1435] Update README.md Remove appveyor build badge --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 1e47e4df4..1fef34665 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ Open source version of the STMicroelectronics Stlink Tools [![GitHub release](https://img.shields.io/github/release/texane/stlink.svg?maxAge=2592000)](https://github.com/texane/stlink/releases/latest) [![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.2.0.svg?maxAge=2592000)](https://github.com/texane/stlink/compare/1.2.0...master) [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) -[![Windows Status](https://ci.appveyor.com/api/projects/status/o659serc9m21n22n/branch/appveyor-integration?svg=true)](https://ci.appveyor.com/project/xor-gate/stlink) [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) ## HOWTO From 1f3aa3c64898fc5a3c4f470aa1e488c87dd964be Mon Sep 17 00:00:00 2001 From: Fabien Chouteau Date: Tue, 9 Aug 2016 15:53:22 +0200 Subject: [PATCH 0457/1435] Unhexify GDB monitor commands (qRcmd) It improves readability and will allow parsing of more complex monitor commands. --- src/gdbserver/gdb-server.c | 41 ++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 5a85d0f0b..b8ee66eb5 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -927,6 +927,21 @@ static void cache_sync(stlink_t *sl) cache_flush(sl, ccr); } +static size_t unhexify(const char *in, char *out, size_t out_count) +{ + size_t i; + unsigned int c; + + for (i = 0; i < out_count; i++) { + if (sscanf(in + (2 * i), "%02x", &c) != 1) { + return i; + } + out[i] = (char)c; + } + + return i; +} + int serve(stlink_t *sl, st_state_t *st) { int sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0) { @@ -1073,20 +1088,34 @@ int serve(stlink_t *sl, st_state_t *st) { params = separator + 1; } + size_t hex_len = strlen(params); + size_t alloc_size = (hex_len / 2) + 1; + size_t cmd_len; + char *cmd = malloc(alloc_size); - if (!strncmp(params,"726573756d65",12)) {// resume + if (cmd == NULL) { + DLOG("Rcmd unhexify allocation error\n"); + break; + } + + cmd_len = unhexify(params, cmd, alloc_size - 1); + cmd[cmd_len] = 0; + + DLOG("unhexified Rcmd: '%s'\n", cmd); + + if (!strncmp(cmd, "resume", 6)) {// resume DLOG("Rcmd: resume\n"); cache_sync(sl); stlink_run(sl); reply = strdup("OK"); - } else if (!strncmp(params,"68616c74",8)) { //halt + } else if (!strncmp(cmd, "halt", 4)) { //halt reply = strdup("OK"); stlink_force_debug(sl); DLOG("Rcmd: halt\n"); - } else if (!strncmp(params,"6a7461675f7265736574",20)) { //jtag_reset + } else if (!strncmp(cmd, "jtag_reset", 10)) { //jtag_reset reply = strdup("OK"); stlink_jtag_reset(sl, 0); @@ -1094,7 +1123,7 @@ int serve(stlink_t *sl, st_state_t *st) { stlink_force_debug(sl); DLOG("Rcmd: jtag_reset\n"); - } else if (!strncmp(params,"7265736574",10)) { //reset + } else if (!strncmp(cmd, "reset", 5)) { //reset reply = strdup("OK"); stlink_force_debug(sl); @@ -1104,9 +1133,9 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("Rcmd: reset\n"); } else { - DLOG("Rcmd: %s\n", params); + DLOG("Rcmd: %s\n", cmd); } - + free(cmd); } if(reply == NULL) From 1f938b239d430d673374f2d3902341123d4d19e0 Mon Sep 17 00:00:00 2001 From: "fabien.lementec" Date: Wed, 10 Aug 2016 12:16:38 +0200 Subject: [PATCH 0458/1435] add STM32F769NI to working targets --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1fef34665..d9388c12e 100644 --- a/README.md +++ b/README.md @@ -221,6 +221,7 @@ STLink v2-1 (as found on the Nucleo boards), known working targets: * STM32F411RET6 (STM32 Nucleo-F411RE board) * STM32F756NGHx (STMF7 evaluation board) * STM32L053R8 (STM32 Nucleo-L053R8 board) +* STM32F769NI (STM32F7 discovery board) Please report any and all known working combinations so I can update this! From d0910c66d7c98c0448e4d9a3805986519848c255 Mon Sep 17 00:00:00 2001 From: Fabien Chouteau Date: Mon, 8 Aug 2016 19:52:43 +0200 Subject: [PATCH 0459/1435] Prototype of ARM semihosting support --- CMakeLists.txt | 4 +- src/gdbserver/gdb-server.c | 91 ++++++++++++++++++++++++- src/gdbserver/semihosting.c | 128 ++++++++++++++++++++++++++++++++++++ src/gdbserver/semihosting.h | 34 ++++++++++ 4 files changed, 255 insertions(+), 2 deletions(-) create mode 100644 src/gdbserver/semihosting.c create mode 100644 src/gdbserver/semihosting.h diff --git a/CMakeLists.txt b/CMakeLists.txt index cf18e0228..fc0127dda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,7 +154,9 @@ target_link_libraries(st-info ${PROJECT_NAME}) add_executable(st-util src/gdbserver/gdb-remote.c src/gdbserver/gdb-remote.h src/gdbserver/gdb-server.c - src/gdbserver/gdb-server.h) + src/gdbserver/gdb-server.h + src/gdbserver/semihosting.c + src/gdbserver/semihosting.h) if (WIN32 OR MSYS OR MINGW) target_link_libraries(st-util ${PROJECT_NAME} wsock32 ws2_32) else () diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index b8ee66eb5..53f4fd962 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -24,13 +24,18 @@ #include "gdb-remote.h" #include "gdb-server.h" +#include "semihosting.h" #define FLASH_BASE 0x08000000 +/* Semihosting doesn't have a short option, we define a value to identify it */ +#define SEMIHOSTING_OPTION 128 + //Allways update the FLASH_PAGE before each use, by calling stlink_calculate_pagesize #define FLASH_PAGE (sl->flash_pgsz) static stlink_t *connected_stlink = NULL; +bool semihosting = false; static const char hex[] = "0123456789abcdef"; @@ -72,6 +77,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { {"listen_port", required_argument, NULL, 'p'}, {"multi", optional_argument, NULL, 'm'}, {"no-reset", optional_argument, NULL, 'n'}, + {"semihosting", no_argument, NULL, SEMIHOSTING_OPTION}, {0, 0, 0, 0}, }; const char * help_str = "%s - usage:\n\n" @@ -89,6 +95,8 @@ int parse_options(int argc, char** argv, st_state_t *st) { "\t\t\tst-util will continue listening for connections after disconnect.\n" " -n, --no-reset\n" "\t\t\tDo not reset board on connection.\n" + " --semihosting\n" + "\t\t\tEnable semihosting support.\n" "\n" "The STLINKv2 device to use can be specified in the environment\n" "variable STLINK_DEVICE on the format :.\n" @@ -145,6 +153,9 @@ int parse_options(int argc, char** argv, st_state_t *st) { case 'n': st->reset = 0; break; + case SEMIHOSTING_OPTION: + semihosting = true; + break; } } @@ -591,6 +602,16 @@ static void init_code_breakpoints(stlink_t *sl) { } } +static int has_breakpoint(stm32_addr_t addr) +{ + for(int i = 0; i < code_break_num; i++) { + if (code_breaks[i].addr == addr) { + return 1; + } + } + return 0; +} + static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { stm32_addr_t fpb_addr; uint32_t mask; @@ -1132,6 +1153,28 @@ int serve(stlink_t *sl, st_state_t *st) { init_data_watchpoints(sl); DLOG("Rcmd: reset\n"); + } else if (!strncmp(cmd, "semihosting ", 12)) { + DLOG("Rcmd: got semihosting cmd '%s'", cmd); + char *arg = cmd + 12; + + /* Skip whitespaces */ + while (isspace(*arg)) { + arg++; + } + + if (!strncmp(arg, "enable", 6) + || !strncmp(arg, "1", 1)) + { + semihosting = true; + reply = strdup("OK"); + } else if (!strncmp(arg, "disable", 7) + || !strncmp(arg, "0", 1)) + { + semihosting = false; + reply = strdup("OK"); + } else { + DLOG("Rcmd: unknown semihosting arg: '%s'\n", arg); + } } else { DLOG("Rcmd: %s\n", cmd); } @@ -1244,7 +1287,53 @@ int serve(stlink_t *sl, st_state_t *st) { stlink_status(sl); if(sl->core_stat == STLINK_CORE_HALTED) { - break; + struct stlink_reg reg; + int ret; + stm32_addr_t pc; + stm32_addr_t addr; + int offset = 0; + uint16_t insn; + + if (!semihosting) { + break; + } + + stlink_read_all_regs (sl, ®); + + /* Read PC */ + pc = reg.r[15]; + + /* Compute aligned value */ + offset = pc % 4; + addr = pc - offset; + + /* Read instructions (address and length must be + * aligned). + */ + ret = stlink_read_mem32(sl, addr, (offset > 2 ? 8 : 4)); + + if (ret != 0) { + DLOG("Semihost: cannot read instructions at: " + "0x%08x\n", addr); + break; + } + + memcpy(&insn, &sl->q_buf[offset], sizeof(insn)); + + if (insn == 0xBEAB && !has_breakpoint(addr)) { + DLOG("Do semihosting...\n"); + + do_semihosting (sl, reg.r[0], reg.r[1], ®.r[0]); + + /* Jump over the break instruction */ + stlink_write_reg(sl, reg.r[15] + 2, 15); + + /* continue execution */ + cache_sync(sl); + stlink_run(sl); + } else { + break; + } } usleep(100000); diff --git a/src/gdbserver/semihosting.c b/src/gdbserver/semihosting.c new file mode 100644 index 000000000..74d5fa398 --- /dev/null +++ b/src/gdbserver/semihosting.c @@ -0,0 +1,128 @@ +#include +#include + +#include "semihosting.h" + +#include +#include + +static int mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) +{ + int offset = addr % 4; + int len = 4; + + if (sl == NULL || data == NULL) { + return -1; + } + + /* Read address and length must be aligned */ + if (stlink_read_mem32(sl, addr - offset, len) != 0) { + return -1; + } + + *data = sl->q_buf[offset]; + return 0; +} + +#ifdef UNUSED +static int mem_read_u16(stlink_t *sl, uint32_t addr, uint16_t *data) +{ + int offset = addr % 4; + int len = (offset > 2 ? 8 : 4); + + if (sl == NULL || data == NULL) { + return -1; + } + + /* Read address and length must be aligned */ + if (stlink_read_mem32(sl, addr - offset, len) != 0) { + return -1; + } + + memcpy(data, &sl->q_buf[offset], sizeof(*data)); + return 0; +} + +static int mem_read_u32(stlink_t *sl, uint32_t addr, uint32_t *data) +{ + int offset = addr % 4; + int len = (offset > 0 ? 8 : 4); + + if (sl == NULL || data == NULL) { + return -1; + } + + /* Read address and length must be aligned */ + if (stlink_read_mem32(sl, addr - offset, len) != 0) { + return -1; + } + + memcpy(data, &sl->q_buf[offset], sizeof(*data)); + return 0; +} +#endif + +static int mem_read(stlink_t *sl, uint32_t addr, uint8_t *data, uint16_t len) +{ + int offset = addr % 4; + int read_len = len + offset; + + if (sl == NULL || data == NULL) { + return -1; + } + + /* Align read size */ + if ((read_len % 4) != 0) { + read_len += 4 - (read_len % 4); + } + + /* Read address and length must be aligned */ + if (stlink_read_mem32(sl, addr - offset, read_len) != 0) { + return -1; + } + + memcpy(data, &sl->q_buf[offset], len); + return 0; +} + +#define WRITE0_BUFFER_SIZE 64 + +int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { + + if (sl == NULL || ret == NULL) { + return -1; + } + + switch (r0) { + case SYS_WRITEC: + { + uint8_t c; + if (mem_read_u8(sl, r1, &c) == 0) { + fprintf(stderr, "%c", c); + } + break; + } + case SYS_WRITE0: + { + uint8_t buf[WRITE0_BUFFER_SIZE]; + + while (true) { + if (mem_read(sl, r1, buf, WRITE0_BUFFER_SIZE) != 0 ) { + return -1; + } + for (int i = 0; i < WRITE0_BUFFER_SIZE; i++) { + if (buf[i] == 0) { + return 0; + } + fprintf(stderr, "%c", buf[i]); + } + r1 += WRITE0_BUFFER_SIZE; + } + break; + } + default: + fprintf(stderr, "semihosting: unsupported call 0x%#x\n", r0); + return -1; + } + return 0; +} diff --git a/src/gdbserver/semihosting.h b/src/gdbserver/semihosting.h new file mode 100644 index 000000000..392d31f7d --- /dev/null +++ b/src/gdbserver/semihosting.h @@ -0,0 +1,34 @@ +#ifndef _SEMIHOSTING_H_ +#define _SEMIHOSTING_H_ + +#include + +#define SYS_OPEN 0x01 +#define SYS_CLOSE 0x02 +#define SYS_WRITEC 0x03 +#define SYS_WRITE0 0x04 +#define SYS_WRITE 0x05 +#define SYS_READ 0x06 +#define SYS_READC 0x07 +#define SYS_ISERROR 0x08 +#define SYS_ISTTY 0x09 +#define SYS_SEEK 0x0A + +#define SYS_FLEN 0x0C +#define SYS_TMPNAM 0x0D +#define SYS_REMOVE 0x0E +#define SYS_RENAME 0x0E +#define SYS_CLOCK 0x10 +#define SYS_TIME 0x11 + +#define SYS_ERRNO 0x13 + +#define SYS_GET_CMD 0x15 +#define SYS_HEAPINFO 0x16 + +#define SYS_ELAPSED 0x30 +#define SYS_TICKFREQ 0x31 + +int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret); + +#endif /* ! _SEMIHOSTING_H_ */ From 3a1ab6e3e097a89f8cad37e68c4a1a8714f27462 Mon Sep 17 00:00:00 2001 From: Fabien Chouteau Date: Fri, 12 Aug 2016 15:54:07 +0200 Subject: [PATCH 0460/1435] Improve ARM semi-hosting support This patch adds the following operations: - SYS_OPEN - SYS_CLOSE - SYS_WRITE - SYS_READ - SYS_ERRNO - SYS_REMOVE - SYS_SEEK The use of utility functions mem_read() and mem_write() add an unnecessary memcpy() call. All buffer transfer could be done directly in the sl->q_buf data instead of using a temporary transfer buffer. However, given the relative slowness of target memory transfer, I don't think that this has a big impact on performances --- src/gdbserver/gdb-server.c | 4 +- src/gdbserver/semihosting.c | 363 +++++++++++++++++++++++++++++++++++- 2 files changed, 363 insertions(+), 4 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 53f4fd962..c6746fb7a 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -1321,10 +1321,12 @@ int serve(stlink_t *sl, st_state_t *st) { memcpy(&insn, &sl->q_buf[offset], sizeof(insn)); if (insn == 0xBEAB && !has_breakpoint(addr)) { - DLOG("Do semihosting...\n"); do_semihosting (sl, reg.r[0], reg.r[1], ®.r[0]); + /* Write return value */ + stlink_write_reg(sl, reg.r[0], 0); + /* Jump over the break instruction */ stlink_write_reg(sl, reg.r[15] + 2, 15); diff --git a/src/gdbserver/semihosting.c b/src/gdbserver/semihosting.c index 74d5fa398..4ea6ccf5c 100644 --- a/src/gdbserver/semihosting.c +++ b/src/gdbserver/semihosting.c @@ -1,5 +1,9 @@ #include #include +#include +#include +#include +#include #include "semihosting.h" @@ -62,7 +66,7 @@ static int mem_read_u32(stlink_t *sl, uint32_t addr, uint32_t *data) } #endif -static int mem_read(stlink_t *sl, uint32_t addr, uint8_t *data, uint16_t len) +static int mem_read(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { int offset = addr % 4; int read_len = len + offset; @@ -76,7 +80,7 @@ static int mem_read(stlink_t *sl, uint32_t addr, uint8_t *data, uint16_t len) read_len += 4 - (read_len % 4); } - /* Read address and length must be aligned */ + /* Address and length must be aligned */ if (stlink_read_mem32(sl, addr - offset, read_len) != 0) { return -1; } @@ -85,20 +89,371 @@ static int mem_read(stlink_t *sl, uint32_t addr, uint8_t *data, uint16_t len) return 0; } +static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) +{ + int offset = addr % 4; + int write_len = len + offset; + + if (sl == NULL || data == NULL) { + return -1; + } + + /* Align read size */ + if ((write_len % 4) != 0) { + write_len += 4 - (write_len % 4); + } + + memcpy(&sl->q_buf[offset], data, len); + + /* Address and length must be aligned */ + if (stlink_write_mem32(sl, addr - offset, write_len) != 0) { + return -1; + } + + return 0; +} + +/* For the SYS_WRITE0 call, we don't know the size of the null-terminated buffer + * in the target memory. Instead of reading one byte at a time, we read by + * chunks of WRITE0_BUFFER_SIZE bytes. + */ #define WRITE0_BUFFER_SIZE 64 +/* Define a maximum size for buffers transmitted by semihosting. There is no + * limit in the ARM specification but this is a safety net. + * We remove 4 byte from Q_BUF_LEN to handle alignment correction. + */ +#define MAX_BUFFER_SIZE (Q_BUF_LEN - 4) + +/* Flags for Open syscall */ + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +static int open_mode_flags[12] = { + O_RDONLY, + O_RDONLY | O_BINARY, + O_RDWR, + O_RDWR | O_BINARY, + O_WRONLY | O_CREAT | O_TRUNC, + O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, + O_RDWR | O_CREAT | O_TRUNC, + O_RDWR | O_CREAT | O_TRUNC | O_BINARY, + O_WRONLY | O_CREAT | O_APPEND, + O_WRONLY | O_CREAT | O_APPEND | O_BINARY, + O_RDWR | O_CREAT | O_APPEND, + O_RDWR | O_CREAT | O_APPEND | O_BINARY +}; + +static int saved_errno = 0; + int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (sl == NULL || ret == NULL) { return -1; } + DLOG("Do semihosting R0=0x%08x R1=0x%08x\n", r0, r1); + switch (r0) { + case SYS_OPEN: + { + uint32_t args[3]; + uint32_t name_address; + uint32_t mode; + uint32_t name_len; + char *name; + + if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + DLOG("Semihosting SYS_OPEN error: " + "cannot read args from target memory\n"); + *ret = -1; + return -1; + } + + name_address = args[0]; + mode = args[1]; + name_len = args[2]; + + if (mode > 12) { + /* Invalid mode */ + DLOG("Semihosting SYS_OPEN error: invalid mode %d\n", mode); + *ret = -1; + return -1; + } + + /* Add the trailing zero that is not counted in the length argument (see + * ARM semihosting specification) + */ + name_len += 1; + + if (name_len > MAX_BUFFER_SIZE) { + DLOG("Semihosting SYS_OPEN error: name buffer size is too big %d\n", + name_len); + *ret = -1; + return -1; + } + name = malloc(name_len); + + if (name == NULL) { + DLOG("Semihosting SYS_OPEN error: cannot allocate name buffer\n"); + *ret = -1; + return -1; + } + + if (mem_read(sl, name_address, name, name_len) != 0 ) { + free(name); + *ret = -1; + DLOG("Semihosting SYS_OPEN error: " + "cannot read name from target memory\n"); + return -1; + } + + DLOG("Semihosting: open('%s', (SH open mode)%d, 0644)\n", name, mode); + + *ret = (uint32_t)open(name, open_mode_flags[mode], 0644); + saved_errno = errno; + + DLOG("Semihosting: return %d\n", *ret); + + free(name); + break; + } + case SYS_CLOSE: + { + uint32_t args[1]; + int fd; + + if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + DLOG("Semihosting SYS_CLOSE error: " + "cannot read args from target memory\n"); + *ret = -1; + return -1; + } + + fd = (int)args[0]; + + DLOG("Semihosting: close(%d)\n", fd); + + *ret = (uint32_t)close(fd); + saved_errno = errno; + + DLOG("Semihosting: return %d\n", *ret); + break; + } + case SYS_WRITE: + { + uint32_t args[3]; + uint32_t buffer_address; + int fd; + size_t buffer_len; + void *buffer; + + if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + DLOG("Semihosting SYS_WRITE error: " + "cannot read args from target memory\n"); + *ret = -1; + return -1; + } + + fd = (int)args[0]; + buffer_address = args[1]; + buffer_len = (size_t)args[2]; + + if (buffer_len > MAX_BUFFER_SIZE) { + DLOG("Semihosting SYS_WRITE error: buffer size is too big %d\n", + buffer_len); + *ret = buffer_len; + return -1; + } + + buffer = malloc(buffer_len); + + if (buffer == NULL) { + DLOG("Semihosting SYS_WRITE error: cannot allocate buffer\n"); + *ret = buffer_len; + return -1; + } + + if (mem_read(sl, buffer_address, buffer, buffer_len) != 0 ) { + DLOG("Semihosting SYS_WRITE error: " + "cannot read buffer from target memory\n"); + free(buffer); + *ret = buffer_len; + return -1; + } + + DLOG("Semihosting: write(%d, target_addr:0x%08x, %zu)\n", fd, + buffer_address, buffer_len); + + *ret = (uint32_t)write(fd, buffer, buffer_len); + saved_errno = errno; + + if (*ret == (uint32_t)-1) { + *ret = buffer_len; + } else { + *ret -= buffer_len; + } + + DLOG("Semihosting: return %d\n", *ret); + free(buffer); + break; + } + case SYS_READ: + { + uint32_t args[3]; + uint32_t buffer_address; + int fd; + size_t buffer_len; + void *buffer; + + if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + DLOG("Semihosting SYS_READ error: " + "cannot read args from target memory\n"); + *ret = -1; + return -1; + } + + fd = (int)args[0]; + buffer_address = args[1]; + buffer_len = (size_t)args[2]; + + if (buffer_len > MAX_BUFFER_SIZE) { + DLOG("Semihosting SYS_READ error: buffer size is too big %d\n", + buffer_len); + *ret = buffer_len; + return -1; + } + + buffer = malloc(buffer_len); + + if (buffer == NULL) { + DLOG("Semihosting SYS_READ error: cannot allocatebuffer\n"); + *ret = buffer_len; + return -1; + } + + DLOG("Semihosting: read(%d, target_addr:0x%08x, %zu)\n", fd, + buffer_address, buffer_len); + + *ret = (uint32_t)read(fd, buffer, buffer_len); + saved_errno = errno; + + if (*ret == (uint32_t)-1) { + *ret = buffer_len; + } else { + if (mem_write(sl, buffer_address, buffer, *ret) != 0 ) { + DLOG("Semihosting SYS_READ error: " + "cannot write buffer to target memory\n"); + free(buffer); + *ret = buffer_len; + return -1; + } else { + *ret -= buffer_len; + } + } + + DLOG("Semihosting: return %d\n", *ret); + free(buffer); + break; + } + case SYS_ERRNO: + { + *ret = (uint32_t)saved_errno; + DLOG("Semihosting: Errno return %d\n", *ret); + break; + } + case SYS_REMOVE: + { + uint32_t args[2]; + uint32_t name_address; + uint32_t name_len; + char *name; + + if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + DLOG("Semihosting SYS_REMOVE error: " + "cannot read args from target memory\n"); + *ret = -1; + return -1; + } + + name_address = args[0]; + name_len = args[1]; + + /* Add the trailing zero that is not counted in the length argument (see + * ARM semihosting specification) + */ + name_len += 1; + + if (name_len > MAX_BUFFER_SIZE) { + DLOG("Semihosting SYS_REMOVE error: " + "name buffer size is too big %d\n", name_len); + *ret = -1; + return -1; + } + name = malloc(name_len); + + if (name == NULL) { + DLOG("Semihosting SYS_REMOVE error: cannot allocate name buffer\n"); + *ret = -1; + return -1; + } + + if (mem_read(sl, name_address, name, name_len) != 0 ) { + free(name); + *ret = -1; + DLOG("Semihosting SYS_REMOVE error: " + "cannot read name from target memory\n"); + return -1; + } + + DLOG("Semihosting: unlink('%s')\n", name); + + *ret = (uint32_t)unlink(name); + saved_errno = errno; + + DLOG("Semihosting: return %d\n", *ret); + + free(name); + break; + } + case SYS_SEEK: + { + uint32_t args[2]; + int fd; + off_t offset; + + if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + DLOG("Semihosting SYS_SEEK error: " + "cannot read args from target memory\n"); + *ret = -1; + return -1; + } + + fd = (int)args[0]; + offset = (off_t)args[1]; + + DLOG("Semihosting: lseek(%d, %d, SEEK_SET)\n", fd, offset); + + *ret = (uint32_t)lseek(fd, offset, SEEK_SET); + saved_errno = errno; + + if (*ret != (uint32_t)-1) { + /* Success */ + *ret = 0; + } + DLOG("Semihosting: return %d\n", *ret); + break; + } case SYS_WRITEC: { uint8_t c; if (mem_read_u8(sl, r1, &c) == 0) { fprintf(stderr, "%c", c); + } else { + DLOG("Semihosting WRITEC: " + "cannot read target memory at 0x%08x\n", r1); } break; } @@ -108,6 +463,8 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { while (true) { if (mem_read(sl, r1, buf, WRITE0_BUFFER_SIZE) != 0 ) { + DLOG("Semihosting WRITE0: " + "cannot read target memory at 0x%08x\n", r1); return -1; } for (int i = 0; i < WRITE0_BUFFER_SIZE; i++) { @@ -121,7 +478,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { break; } default: - fprintf(stderr, "semihosting: unsupported call 0x%#x\n", r0); + fprintf(stderr, "semihosting: unsupported call %#x\n", r0); return -1; } return 0; From 1118f8ed498a1c0eff280d36c97a14248b91b73b Mon Sep 17 00:00:00 2001 From: Andrea Mucignat Date: Mon, 15 Aug 2016 11:11:51 -0700 Subject: [PATCH 0461/1435] Fix memory map for STM32F Also: - fixed a typo in an if statement condition in make_memory_map - cleaned up usage of '4096' in favor of const size_t sz = 4096. --- src/chipid.c | 2 +- src/gdbserver/gdb-server.c | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/chipid.c b/src/chipid.c index 546e2384e..7f8bbd3f9 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -9,7 +9,7 @@ static const struct stlink_chipid_params devices[] = { .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1ff0f442, // section 45.2 .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x5C000, // "SRAM" byte size in hex from + .sram_size = 0x80000, // "SRAM" byte size in hex from .bootrom_base = 0x00200000, //! "System memory" starting address from .bootrom_size = 0xEDC0 //! @todo "System memory" byte size in hex from }, diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index c6746fb7a..15f837908 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -416,7 +416,7 @@ static const char* const memory_map_template_F7 = "" " " // ITCM ram 16kB " " // ITCM flash - " " // sram + " " // sram " " // Sectors 0..3 " 0x8000" // 32kB " " @@ -435,26 +435,28 @@ static const char* const memory_map_template_F7 = char* make_memory_map(stlink_t *sl) { /* This will be freed in serve() */ - char* map = malloc(4096); + const size_t sz = 4096; + char* map = malloc(sz); map[0] = '\0'; if(sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F446) { strcpy(map, memory_map_template_F4); - } else if(sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->core_id==STM32F7_CORE_ID) { - strcpy(map, memory_map_template_F7); + } else if(sl->core_id==STM32F7_CORE_ID) { + snprintf(map, sz, memory_map_template_F7, + sl->sram_size); } else if(sl->chip_id==STLINK_CHIPID_STM32_F4_HD) { strcpy(map, memory_map_template_F4_HD); } else if(sl->chip_id==STLINK_CHIPID_STM32_F2) { - snprintf(map, 4096, memory_map_template_F2, + snprintf(map, sz, memory_map_template_F2, sl->flash_size, sl->sram_size, sl->flash_size - 0x20000, sl->sys_base, sl->sys_size); } else if(sl->chip_id==STLINK_CHIPID_STM32_L4) { - snprintf(map, 4096, memory_map_template_L4, + snprintf(map, sz, memory_map_template_L4, sl->flash_size, sl->flash_size); } else { - snprintf(map, 4096, memory_map_template, + snprintf(map, sz, memory_map_template, sl->flash_size, sl->sram_size, sl->flash_size, sl->flash_pgsz, @@ -1054,7 +1056,7 @@ int serve(stlink_t *sl, st_state_t *st) { if(!strcmp(queryName, "Supported")) { if(sl->chip_id==STLINK_CHIPID_STM32_F4 - || sl->chip_id==STLINK_CHIPID_STM32_F4_HD + || sl->chip_id==STLINK_CHIPID_STM32_F4_HD || sl->core_id==STM32F7_CORE_ID) { reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); } From a35cc23525f985b6bd494a315189c326b33d29cd Mon Sep 17 00:00:00 2001 From: Andrew Andrianov Date: Sat, 9 Jul 2016 23:07:50 +0300 Subject: [PATCH 0462/1435] CMakeLists.txt: Add shared library build and debian packaging Signed-off-by: Andrew Andrianov --- CMakeLists.txt | 84 +++++++++++++++++++++++++++++++--- debian/changelog | 5 ++ debian/compat | 1 + debian/control | 34 ++++++++++++++ debian/libstlink-dev.dirs | 2 + debian/libstlink-dev.install | 3 ++ debian/libstlink.dirs | 1 + debian/libstlink.install | 1 + debian/rules | 28 ++++++++++++ debian/source/format | 1 + debian/stlink-gui.dirs | 2 + debian/stlink-gui.install | 2 + debian/stlink-tools.dirs | 2 + debian/stlink-tools.install | 1 + doc/app-example/CMakeLists.txt | 28 ++++++++++++ doc/app-example/README.md | 2 + doc/app-example/main.c | 29 ++++++++++++ pkg-config.pc.cmake | 11 +++++ scripts/run_clang_analyze.sh | 8 ++++ 19 files changed, 239 insertions(+), 6 deletions(-) create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/libstlink-dev.dirs create mode 100644 debian/libstlink-dev.install create mode 100644 debian/libstlink.dirs create mode 100644 debian/libstlink.install create mode 100755 debian/rules create mode 100644 debian/source/format create mode 100644 debian/stlink-gui.dirs create mode 100644 debian/stlink-gui.install create mode 100644 debian/stlink-tools.dirs create mode 100644 debian/stlink-tools.install create mode 100644 doc/app-example/CMakeLists.txt create mode 100644 doc/app-example/README.md create mode 100644 doc/app-example/main.c create mode 100644 pkg-config.pc.cmake create mode 100755 scripts/run_clang_analyze.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index fc0127dda..27aa9cd33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,6 @@ cmake_minimum_required(VERSION 2.8.7) +project(stlink C) +set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics Stlink Tools") project(stlink C) include(CheckCCompilerFlag) @@ -18,7 +20,6 @@ if (DEFINED ENV{TRAVIS_TAG} AND NOT "$ENV{TRAVIS_TAG}" STREQUAL "") set (STLINK_PACKAGE_VERSION "$ENV{TRAVIS_TAG}") elseif (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") # Working off a git repo, using git versioning - # Check if HEAD is pointing to a tag execute_process ( COMMAND "${GIT_EXECUTABLE}" describe --always @@ -40,9 +41,23 @@ elseif (EXISTS ${PROJECT_SOURCE_DIR}/.version) # we can extract the package version from .version file. file (STRINGS .version STLINK_PACKAGE_VERSION) else () - set (STLINK_PACKAGE_VERSION "Unknown") + set (STLINK_PACKAGE_VERSION "999.99.99-unknown") endif() +# We shall use STLINK_PACKAGE_VERSION* variables to set soversion and other stuff +# Since these numbers will appear in .so names, e.g. libstlink.so.1.2.0 +# We can't just use STLINK_PACKAGE_VERSION here +# (Well, we can, but that breaks all the existing conventions) +# We can't as well use PROJECT_VERSION* variables here, since they are managed +# by project() directive and the whole version detection relies on PROJECT_SOURCE_DIR + +string(REPLACE "." ";" STLINK_PACKAGE_VERSION_ARRAY ${STLINK_PACKAGE_VERSION}) +string(REPLACE "-" ";" STLINK_PACKAGE_VERSION_ARRAY "${STLINK_PACKAGE_VERSION_ARRAY}") +list(GET STLINK_PACKAGE_VERSION_ARRAY 0 STLINK_PACKAGE_VERSION_MAJOR) +list(GET STLINK_PACKAGE_VERSION_ARRAY 1 STLINK_PACKAGE_VERSION_MINOR) +list(GET STLINK_PACKAGE_VERSION_ARRAY 2 STLINK_PACKAGE_VERSION_PATCH) +list(GET STLINK_PACKAGE_VERSION_ARRAY 3 STLINK_PACKAGE_VERSION_TAG) + if(WIN32) find_package(7Zip REQUIRED) message(STATUS "7Zip Location: " ${ZIP_LOCATION}) @@ -133,11 +148,30 @@ include_directories(${LIBUSB_INCLUDE_DIR}) include_directories(include) include_directories(src/mingw) -add_library(${PROJECT_NAME} STATIC +set(STLINK_LIB_STATIC ${PROJECT_NAME}-static) + +add_library(${PROJECT_NAME} SHARED ${STLINK_HEADERS} # header files for ide projects generated by cmake ${STLINK_SOURCE}) target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARY}) +if (WIN32 OR MSYS OR MINGW) + set(STLINK_SHARED_VERSION + ${STLINK_PACKAGE_VERSION_MAJOR}.${STLINK_PACKAGE_VERSION_MINOR}) +else() + set(STLINK_SHARED_VERSION + ${STLINK_PACKAGE_VERSION_MAJOR}.${STLINK_PACKAGE_VERSION_MINOR}.${STLINK_PACKAGE_VERSION_PATCH}) +endif() + +set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION ${STLINK_PACKAGE_VERSION_MAJOR} +VERSION ${STLINK_SHARED_VERSION}) + +add_library(${STLINK_LIB_STATIC} STATIC + ${STLINK_HEADERS} # header files for ide projects generated by cmake + ${STLINK_SOURCE}) +target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY}) +set_target_properties(${STLINK_LIB_STATIC} PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) + if (APPLE) find_library(ObjC objc) find_library(CoreFoundation CoreFoundation) @@ -163,11 +197,49 @@ else () target_link_libraries(st-util ${PROJECT_NAME}) endif () -install(TARGETS ${PROJECT_NAME} st-flash st-util st-info +install(TARGETS ${PROJECT_NAME} ${STLINK_LIB_STATIC} st-flash st-util st-info RUNTIME DESTINATION bin - ARCHIVE DESTINATION lib + ARCHIVE DESTINATION lib/${CMAKE_LIBRARY_PATH} + LIBRARY DESTINATION lib/${CMAKE_LIBRARY_PATH} +) +# Now, install the development headers +file(GLOB STLINK_HEADERS + "${CMAKE_SOURCE_DIR}/include/stlink/*.h" ) +install(FILES ${CMAKE_SOURCE_DIR}/include/stlink.h + DESTINATION include/${CMAKE_LIBRARY_PATH}/stlink-${STLINK_PACKAGE_VERSION}/) + +install(FILES ${STLINK_HEADERS} + DESTINATION include/${CMAKE_LIBRARY_PATH}/stlink-${STLINK_PACKAGE_VERSION}/stlink) + +if (NOT APPLE AND NOT WIN32) + set(PKG_CONFIG_LIBDIR + "\${prefix}/lib/\${deb_host_multiarch}" + ) + set(PKG_CONFIG_INCLUDEDIR + "\${prefix}/include/\${deb_host_multiarch}/${PROJECT_NAME}-${STLINK_PACKAGE_VERSION}" + ) + set(PKG_CONFIG_LIBS + "-L\${libdir} -l:libstlink.so.${STLINK_PACKAGE_VERSION}" + ) + set(PKG_CONFIG_CFLAGS + "-I\${includedir}" + ) + + set(PKG_CONFIG_REQUIRES + "libusb-1.0" + ) + + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + ) + + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + DESTINATION lib/${CMAKE_LIBRARY_PATH}/pkgconfig/) +endif() + if(NOT MINGW) list(APPEND STLINK_SOURCE src/tools/term.c) add_executable(st-term src/tools/term.c) @@ -212,6 +284,6 @@ if (APPLE) set(CPACK_GENERATOR "ZIP") file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/osx") set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/osx") -endif () +endif() add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source) include (CPack) diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000000000..d0471cb7d --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +libstlink (1.2.1) unstable; urgency=low + + * Initial Debian-Packaged Release. + + -- Andrew 'Necromant' Andrianov Sat, 09 Jul 2016 23:16:07 +0300 diff --git a/debian/compat b/debian/compat new file mode 100644 index 000000000..ec635144f --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..b9beac2fc --- /dev/null +++ b/debian/control @@ -0,0 +1,34 @@ +Source: libstlink +Priority: optional +Maintainer: Andrew 'Necromant' Andrianov +Build-Depends: debhelper (>= 9), cmake, libusb-1.0-0-dev, libgtk-3-dev +Standards-Version: 3.9.5 +Section: libs +Homepage: +Vcs-Git: https://github.com/texane/stlink.git +Vcs-Browser: https://github.com/texane/stlink + +Package: libstlink-dev +Section: libdevel +Architecture: any +Depends: libstlink (= ${binary:Version}), ${misc:Depends} +Description: OpenSource ST-Link tools replacement. Development headers. + This package contains development headers for libstlink. + +Package: libstlink +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: OpenSource ST-Link tools replacement. Shared library. + This package libstlink shared library. + +Package: stlink-tools +Section: libdevel +Architecture: any +Depends: libstlink (= ${binary:Version}), ${misc:Depends} +Description: OpenSource ST-Link tools replacement. Commandline Utilities. + +Package: stlink-gui +Section: libdevel +Architecture: any +Depends: libstlink (= ${binary:Version}), ${misc:Depends} +Description: OpenSource ST-Link tools replacement. GUI Tool. diff --git a/debian/libstlink-dev.dirs b/debian/libstlink-dev.dirs new file mode 100644 index 000000000..44188162e --- /dev/null +++ b/debian/libstlink-dev.dirs @@ -0,0 +1,2 @@ +usr/lib +usr/include diff --git a/debian/libstlink-dev.install b/debian/libstlink-dev.install new file mode 100644 index 000000000..1eff3299c --- /dev/null +++ b/debian/libstlink-dev.install @@ -0,0 +1,3 @@ +usr/include/* +usr/lib/*/lib*.a +usr/lib/*/pkgconfig/* diff --git a/debian/libstlink.dirs b/debian/libstlink.dirs new file mode 100644 index 000000000..68457717b --- /dev/null +++ b/debian/libstlink.dirs @@ -0,0 +1 @@ +usr/lib diff --git a/debian/libstlink.install b/debian/libstlink.install new file mode 100644 index 000000000..703ad8b31 --- /dev/null +++ b/debian/libstlink.install @@ -0,0 +1 @@ +usr/lib/*/lib*.so* diff --git a/debian/rules b/debian/rules new file mode 100755 index 000000000..4979b59d7 --- /dev/null +++ b/debian/rules @@ -0,0 +1,28 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +#DH_VERBOSE = 1 + +# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* +DPKG_EXPORT_BUILDFLAGS = 1 +include /usr/share/dpkg/default.mk + +# see FEATURE AREAS in dpkg-buildflags(1) +#export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +# see ENVIRONMENT in dpkg-buildflags(1) +# package maintainers to append CFLAGS +#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic +# package maintainers to append LDFLAGS +#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed + + +# main packaging script based on dh7 syntax +%: + dh $@ + +# debmake generated override targets +# This is example for Cmake (See http://bugs.debian.org/641051 ) +override_dh_auto_configure: + dh_auto_configure -- \ + -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 000000000..89ae9db8f --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/debian/stlink-gui.dirs b/debian/stlink-gui.dirs new file mode 100644 index 000000000..d080ed407 --- /dev/null +++ b/debian/stlink-gui.dirs @@ -0,0 +1,2 @@ +/usr/bin +/usr/share/ diff --git a/debian/stlink-gui.install b/debian/stlink-gui.install new file mode 100644 index 000000000..eedcd7172 --- /dev/null +++ b/debian/stlink-gui.install @@ -0,0 +1,2 @@ +/usr/bin/stlink-gui* +/usr/share/* diff --git a/debian/stlink-tools.dirs b/debian/stlink-tools.dirs new file mode 100644 index 000000000..377c76613 --- /dev/null +++ b/debian/stlink-tools.dirs @@ -0,0 +1,2 @@ +/usr/bin + diff --git a/debian/stlink-tools.install b/debian/stlink-tools.install new file mode 100644 index 000000000..4fa1125bf --- /dev/null +++ b/debian/stlink-tools.install @@ -0,0 +1 @@ +/usr/bin/st-* diff --git a/doc/app-example/CMakeLists.txt b/doc/app-example/CMakeLists.txt new file mode 100644 index 000000000..0e91bed6f --- /dev/null +++ b/doc/app-example/CMakeLists.txt @@ -0,0 +1,28 @@ +# Warning: This example assumes that you are building on a host +# with pkg-config available (e.g. linux). The logic required to +# build under windows/mingw and/or mac was intentionally omitted +# to keep this CMakeLists as small as possible + +cmake_minimum_required(VERSION 2.8) + +project(st-hello) +set(PROJECT_VERSION 0.1) +set(SRCS main.c) + +find_package(PkgConfig) +pkg_check_modules(STLINK REQUIRED stlink) + +set(CMAKE_C_FLAGS " ${STLINK_CFLAGS_OTHER} -Wall -Werror") + +include_directories( + ${STLINK_INCLUDE_DIRS} +) + +add_executable(${PROJECT_NAME} ${SRCS}) + +target_link_libraries(${PROJECT_NAME} + ${STLINK_LIBRARIES} +) + +install(TARGETS ${PROJECT_NAME} + DESTINATION bin) diff --git a/doc/app-example/README.md b/doc/app-example/README.md new file mode 100644 index 000000000..683056171 --- /dev/null +++ b/doc/app-example/README.md @@ -0,0 +1,2 @@ +This is a simple standalone application example that uses libstlink. +You can use this as a boilerplate for your own app development diff --git a/doc/app-example/main.c b/doc/app-example/main.c new file mode 100644 index 000000000..12621434a --- /dev/null +++ b/doc/app-example/main.c @@ -0,0 +1,29 @@ +#include +#include +#include + +static stlink_t *stlink_open_first(void) +{ + stlink_t* sl = NULL; + sl = stlink_v1_open(0, 1); + if (sl == NULL) + sl = stlink_open_usb(0, 1, NULL); + + return sl; +} + + +int main() +{ + stlink_t* sl = NULL; + sl = stlink_open_first(); + + if (sl == NULL) { + fprintf(stderr, "Failed to open stlink device ;(\n"); + exit(1); + } + + fprintf(stderr, "STlink device opened, that's cool!\n"); + stlink_close(sl); + return 0; +} diff --git a/pkg-config.pc.cmake b/pkg-config.pc.cmake new file mode 100644 index 000000000..4170bf84b --- /dev/null +++ b/pkg-config.pc.cmake @@ -0,0 +1,11 @@ +deb_host_multiarch=${CMAKE_LIBRARY_PATH} +Name: ${PROJECT_NAME} +Description: ${PROJECT_DESCRIPTION} +Version: ${PROJECT_VERSION} +Requires: ${PKG_CONFIG_REQUIRES} +prefix=${CMAKE_INSTALL_PREFIX} +includedir=${PKG_CONFIG_INCLUDEDIR} +libdir=${PKG_CONFIG_LIBDIR} +Libs: ${PKG_CONFIG_LIBS} +Cflags: ${PKG_CONFIG_CFLAGS} + diff --git a/scripts/run_clang_analyze.sh b/scripts/run_clang_analyze.sh new file mode 100755 index 000000000..8d5c5a988 --- /dev/null +++ b/scripts/run_clang_analyze.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# Run this hacky script in project root directory to start +# clang static analysis. Adjust ccc-analyzer path if nesesary +CCC_ANALYZER=/usr/share/clang/scan-build-3.5/ccc-analyzer +mkdir -p build-clang-analyze/reports +cd build-clang-analyze +cmake -DCMAKE_C_COMPILER=${CCC_ANALYZER} $* .. +scan-build -o ./reports --keep-empty make From c37848583b633cf9cb8ff896ec620dd9b0aafc26 Mon Sep 17 00:00:00 2001 From: Anatoli Date: Tue, 6 Sep 2016 00:04:59 +0200 Subject: [PATCH 0463/1435] Implement parser of ihex --- include/stlink.h | 4 +- src/common.c | 223 ++++++++++++++++++++++++++++++++++++++++++---- src/tools/flash.c | 4 +- 3 files changed, 210 insertions(+), 21 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index d1bf4815c..86e53f060 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -180,7 +180,9 @@ typedef struct flash_loader { int stlink_erase_flash_mass(stlink_t* sl); int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); - int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); + uint8_t stlink_parse_hex(const char* hex); + int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); + int stlink_fwrite_flash(stlink_t *sl, const char* path, bool is_ihex, 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); diff --git a/src/common.c b/src/common.c index 47c6e35be..95bbf9ee2 100644 --- a/src/common.c +++ b/src/common.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -1753,6 +1754,173 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t return stlink_verify_write_flash(sl, addr, base, len); } +// note: length not checked +uint8_t stlink_parse_hex(const char* hex) { + uint8_t d[2]; + for(int i = 0; i < 2; ++i) { + char c = *(hex + i); + if(c >= '0' && c <= '9') d[i] = c - '0'; + else if(c >= 'A' && c <= 'F') d[i] = c - 'A' + 10; + else if(c >= 'a' && c <= 'f') d[i] = c - 'a' + 10; + else return 0; // error + } + return (d[0] << 4) | (d[1]); +} + +int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin) { + int res = 0; + *begin = UINT32_MAX; + uint8_t* data = NULL; + uint32_t end = 0; + bool eof_found = false; + + for(int scan = 0; (res == 0) && (scan < 2); ++scan) { // parse file two times - first to find memory range, second - to fill it + if(scan == 1) { + if(!eof_found) { + ELOG("No EoF recond\n"); + res = -1; + break; + } + + if(*begin >= end) { + ELOG("No data found in file\n"); + res = -1; + break; + } + + *size = (end - *begin) + 1; + data = calloc(*size, 1); // use calloc to get NULL if out of memory + if(!data) { + ELOG("Cannot allocate %d bytes\n", *size); + res = -1; + break; + } + + memset(data, erased_pattern, *size); + } + + FILE* file = fopen(path, "r"); + if(!file) { + ELOG("Cannot open file\n"); + res = -1; + break; + } + + uint32_t lba = 0; + + char line[1 + 5*2 + 255*2 + 2]; + while(fgets(line, sizeof(line), file)) { + if(line[0] == '\n' || line[0] == '\r') continue; // skip empty lines + if(line[0] != ':') { // no marker - wrong file format + ELOG("Wrong file format - no marker\n"); + res = -1; + break; + } + + size_t l = strlen(line); + while(l > 0 && (line[l-1] == '\n' || line[l-1] == '\r')) --l; // trim EoL + if((l < 11) || (l == (sizeof(line)-1))) { // line too short or long - wrong file format + ELOG("Wrong file format - wrong line length\n"); + res = -1; + break; + } + + // check sum + uint8_t chksum = 0; + for(size_t i = 1; i < l; i += 2) { + chksum += stlink_parse_hex(line + i); + } + if(chksum != 0) { + ELOG("Wrong file format - checksum mismatch\n"); + res = -1; + break; + } + + uint8_t reclen = stlink_parse_hex(line + 1); + if(((uint32_t)reclen + 5)*2 + 1 != l) { + ELOG("Wrong file format - record length mismatch\n"); + res = -1; + break; + } + + uint16_t offset = ((uint16_t)stlink_parse_hex(line + 3) << 8) | ((uint16_t)stlink_parse_hex(line + 5)); + uint8_t rectype = stlink_parse_hex(line + 7); + + switch(rectype) { + case 0: // data + if(scan == 0) { + uint32_t b = lba + offset; + uint32_t e = b + reclen - 1; + if(b < *begin) *begin = b; + if(e > end) end = e; + } + else { + for(size_t i = 0; i < reclen; ++i) { + uint8_t b = stlink_parse_hex(line + 9 + i*2); + uint32_t addr = lba + offset + i; + if(addr >= *begin && addr <= end) { + data[addr - *begin] = b; + } + } + } + break; + + case 1: // EoF + eof_found = true; + break; + + case 2: // Extended Segment Address, unexpected + res = -1; + break; + + case 3: // Start Segment Address, unexpected + res = -1; + break; + + case 4: // Extended Linear Address + if(reclen == 2) { + lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | ((uint32_t)stlink_parse_hex(line + 11) << 16); + } + else { + ELOG("Wrong file format - wrong LBA length\n"); + res = -1; + } + break; + + case 5: // Start Linear Address - expected, but ignore + break; + + default: + ELOG("Wrong file format - unexpected record type %d\n", rectype); + res = -1; + } + if(res != 0) break; + } + + fclose(file); + } + + if(res == 0) { + *mem = data; + } + else { + free(data); + } + + return res; +} + +// FIXME remove +void dumpMem(uint8_t const * mem, size_t len) { + for(size_t i = 0; i < len; ++i) { + if(i > 0 && i % 16 == 0) printf("\n"); + else if(i > 0 && i % 8 == 0) printf(" "); + if(i % 16 == 0) printf("%08zx ", i); + printf("%02x ", mem[i]); + } + printf("\n"); +} + /** * Write the given binary file into flash at address "addr" * @param sl @@ -1760,35 +1928,49 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t * @param addr where to start writing * @return 0 on success, -ve on failure. */ -int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { +int stlink_fwrite_flash(stlink_t *sl, const char* path, bool is_ihex, stm32_addr_t addr) { /* write the file in flash at addr */ int err; unsigned int num_empty, index, val; unsigned char erased_pattern; mapped_file_t mf = MAPPED_FILE_INITIALIZER; - - if (map_file(&mf, path) == -1) { - ELOG("map_file() == -1\n"); - return -1; - } + uint8_t * mem; + size_t size; + bool eraseonly = false; if (sl->flash_type == STLINK_FLASH_TYPE_L0) erased_pattern = 0x00; else erased_pattern = 0xff; - index = (unsigned int) mf.len; - for(num_empty = 0; num_empty != mf.len; ++num_empty) { - if (mf.base[--index] != erased_pattern) { - break; - } - } - /* Round down to words */ - num_empty -= (num_empty & 3); - if(num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); - } - err = stlink_write_flash(sl, addr, mf.base, (num_empty == mf.len) ? (uint32_t) mf.len : (uint32_t) mf.len - num_empty, num_empty == mf.len); + if(is_ihex) { + uint32_t begin; + if(0 != stlink_parse_ihex(path, 0xFF, &mem, &size, &begin)) + return -1; + addr = begin; + } + else { + if (map_file(&mf, path) == -1) { + ELOG("map_file() == -1\n"); + return -1; + } + + index = (unsigned int) mf.len; + for(num_empty = 0; num_empty != mf.len; ++num_empty) { + if (mf.base[--index] != erased_pattern) { + break; + } + } + /* Round down to words */ + num_empty -= (num_empty & 3); + if(num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); + } + mem = mf.base; + size = (num_empty == mf.len) ? (uint32_t) mf.len : (uint32_t) mf.len - num_empty; + eraseonly = (num_empty == mf.len); + } + err = stlink_write_flash(sl, addr, mem, size, eraseonly); /* set stack*/ stlink_read_debug32(sl, addr, &val); stlink_write_reg(sl, val, 13); @@ -1796,6 +1978,9 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { stlink_read_debug32(sl, addr + 4, &val); stlink_write_reg(sl, val, 15); stlink_run(sl); - unmap_file(&mf); + if(is_ihex) + free(mem); + else + unmap_file(&mf); return err; } diff --git a/src/tools/flash.c b/src/tools/flash.c index 50ad64092..f26472d45 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -34,6 +34,7 @@ struct opts const char* devname; char *serial; const char* filename; + bool is_ihex; stm32_addr_t addr; size_t size; int reset; @@ -157,6 +158,7 @@ static int get_opts(struct opts* o, int ac, char** av) o->filename = av[i + 1]; /** @todo This is a little evil as strtoul could return 0 and is of type unsigned long int */ o->addr = (uint32_t) strtoul(av[i + 2], NULL, 16); + o->is_ihex = (0 == strcmp(".hex", o->filename + (strlen(o->filename) - 4))); // ends with .hex return 0; } @@ -246,7 +248,7 @@ int main(int ac, char** av) { if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { - err = stlink_fwrite_flash(sl, o.filename, o.addr); + err = stlink_fwrite_flash(sl, o.filename, o.is_ihex, o.addr); if (err == -1) { printf("stlink_fwrite_flash() == -1\n"); From 7c99eb050300b76bfd64b380d7c8693476d540e2 Mon Sep 17 00:00:00 2001 From: Anatoli Date: Tue, 6 Sep 2016 22:56:54 +0200 Subject: [PATCH 0464/1435] re-desing of command line parsing for st-flash; unit-tests for it; implement read into ihex; --- CMakeLists.txt | 5 +- include/stlink.h | 9 +- include/stlink/tools/flash.h | 28 ++ src/common.c | 568 +++++++++++++++++++++-------------- src/tools/flash.c | 171 ++--------- src/tools/flash_opts.c | 156 ++++++++++ tests/CMakeLists.txt | 5 + tests/flash.c | 111 +++++++ 8 files changed, 681 insertions(+), 372 deletions(-) create mode 100644 include/stlink/tools/flash.h create mode 100644 src/tools/flash_opts.c create mode 100644 tests/flash.c diff --git a/CMakeLists.txt b/CMakeLists.txt index fc0127dda..f1ade75d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -145,8 +145,11 @@ if (APPLE) target_link_libraries(${PROJECT_NAME} ${CoreFoundation} ${IOKit} ${ObjC}) endif () +add_library(stflash STATIC + src/tools/flash_opts.c) +target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARY}) add_executable(st-flash src/tools/flash.c) -target_link_libraries(st-flash ${PROJECT_NAME}) +target_link_libraries(st-flash ${PROJECT_NAME} stflash) add_executable(st-info src/tools/info.c) target_link_libraries(st-info ${PROJECT_NAME}) diff --git a/include/stlink.h b/include/stlink.h index 86e53f060..5151cc166 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -180,9 +180,10 @@ typedef struct flash_loader { int stlink_erase_flash_mass(stlink_t* sl); int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); - uint8_t stlink_parse_hex(const char* hex); - int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); - int stlink_fwrite_flash(stlink_t *sl, const char* path, bool is_ihex, stm32_addr_t addr); + int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); + uint8_t stlink_get_erased_pattern(stlink_t *sl); + int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); + 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); @@ -201,7 +202,7 @@ typedef struct flash_loader { bool stlink_is_core_halted(stlink_t *sl); int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); - int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size); + int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); int stlink_load_device_params(stlink_t *sl); #include "stlink/sg.h" diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h new file mode 100644 index 000000000..10e6ffac4 --- /dev/null +++ b/include/stlink/tools/flash.h @@ -0,0 +1,28 @@ +#ifndef STLINK_TOOLS_FLASH_H_ +#define STLINK_TOOLS_FLASH_H_ + +#include +#include + +#define DEBUG_LOG_LEVEL 100 +#define STND_LOG_LEVEL 50 + +enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3}; +enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1}; +struct flash_opts +{ + enum flash_cmd cmd; + const char* devname; + uint8_t serial[16]; + const char* filename; + stm32_addr_t addr; + size_t size; + int reset; + int log_level; + enum flash_format format; +}; + +int flash_get_opts(struct flash_opts* o, int ac, char** av); + +#endif // STLINK_FLASH_H_ + diff --git a/src/common.c b/src/common.c index 95bbf9ee2..51c92bac3 100644 --- a/src/common.c +++ b/src/common.c @@ -1096,17 +1096,11 @@ int stlink_fwrite_sram return error; } -int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) { - /* read size bytes from addr to file */ +typedef bool (*save_block_fn)(void* arg, uint8_t* block, ssize_t len); - int error = -1; - size_t off; +static int stlink_read(stlink_t* sl, stm32_addr_t addr, size_t size, save_block_fn fn, void* fn_arg) { - const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); - if (fd == -1) { - fprintf(stderr, "open(%s) == -1\n", path); - return -1; - } + int error = -1; if (size <1) size = sl->flash_size; @@ -1115,7 +1109,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) size = sl->flash_size; size_t cmp_size = (sl->flash_pgsz > 0x1800)? 0x1800:sl->flash_pgsz; - for (off = 0; off < size; off += cmp_size) { + for (size_t off = 0; off < size; off += cmp_size) { size_t aligned_size; /* adjust last page size */ @@ -1128,8 +1122,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) stlink_read_mem32(sl, addr + (uint32_t) off, aligned_size); - if (write(fd, sl->q_buf, sl->q_len) != (ssize_t) aligned_size) { - fprintf(stderr, "write() != aligned_size\n"); + if (!fn(fn_arg, sl->q_buf, aligned_size)) { goto on_error; } } @@ -1138,6 +1131,134 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) error = 0; on_error: + return error; +} + +struct stlink_fread_worker_arg { + int fd; +}; + +static bool stlink_fread_worker(void* arg, uint8_t* block, ssize_t len) { + struct stlink_fread_worker_arg* the_arg = (struct stlink_fread_worker_arg*)arg; + if (write(the_arg->fd, block, len) != len) { + fprintf(stderr, "write() != aligned_size\n"); + return false; + } + else { + return true; + } +} + +struct stlink_fread_ihex_worker_arg { + FILE* file; + uint32_t addr; + uint32_t lba; + uint8_t buf[16]; + uint8_t buf_pos; +}; + +static bool stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg* the_arg) { + uint32_t addr = the_arg->addr; + uint8_t sum = 2 + 4 + (uint8_t)((addr & 0xFF000000) >> 24) + (uint8_t)((addr & 0x00FF0000) >> 16); + if(17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", (addr & 0xFFFF0000) >> 16, (uint8_t)(0x100 - sum))) + return false; + + the_arg->lba = (addr & 0xFFFF0000); + + return true; +} + +static bool stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg* the_arg) { + uint8_t count = the_arg->buf_pos; + if(count == 0) return true; + + uint32_t addr = the_arg->addr; + + if(the_arg->lba != (addr & 0xFFFF0000)) { // segment changed + if(!stlink_fread_ihex_newsegment(the_arg)) return false; + } + + uint8_t sum = count + (uint8_t)((addr & 0x0000FF00) >> 8) + (uint8_t)(addr & 0x000000FF); + if(9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) + return false; + + for(uint8_t i = 0; i < count; ++i) { + uint8_t b = the_arg->buf[i]; + sum += b; + if(2 != fprintf(the_arg->file, "%02X", b)) + return false; + } + + if(4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) + return false; + + the_arg->addr += count; + the_arg->buf_pos = 0; + + return true; +} + +static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg* the_arg, int fd, stm32_addr_t addr) { + the_arg->file = fdopen(fd, "w"); + the_arg->addr = addr; + the_arg->lba = 0; + the_arg->buf_pos = 0; + + return (the_arg->file != NULL); +} + +static bool stlink_fread_ihex_worker(void* arg, uint8_t* block, ssize_t len) { + struct stlink_fread_ihex_worker_arg* the_arg = (struct stlink_fread_ihex_worker_arg*)arg; + + for(ssize_t i = 0; i < len; ++i) { + if(the_arg->buf_pos == sizeof(the_arg->buf)) { // line is full + if(!stlink_fread_ihex_writeline(the_arg)) return false; + } + + the_arg->buf[the_arg->buf_pos++] = block[i]; + } + + return true; +} + +static bool stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg* the_arg) { + if(!stlink_fread_ihex_writeline(the_arg)) return false; + + // FIXME do we need the Start Linear Address? + + if(13 != fprintf(the_arg->file, ":00000001FF\r\n")) // EoF + return false; + + return (0 == fclose(the_arg->file)); +} + +int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size) { + /* read size bytes from addr to file */ + + int error; + + int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); + if (fd == -1) { + fprintf(stderr, "open(%s) == -1\n", path); + return -1; + } + + if(is_ihex) { + struct stlink_fread_ihex_worker_arg arg; + if(stlink_fread_ihex_init(&arg, fd, addr)) { + error = stlink_read(sl, addr, size, &stlink_fread_ihex_worker, &arg); + if(!stlink_fread_ihex_finalize(&arg)) + error = -1; + } + else { + error = -1; + } + } + else { + struct stlink_fread_worker_arg arg = { fd }; + error = stlink_read(sl, addr, size, &stlink_fread_worker, &arg); + } + close(fd); return error; @@ -1755,170 +1876,199 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } // note: length not checked -uint8_t stlink_parse_hex(const char* hex) { - uint8_t d[2]; - for(int i = 0; i < 2; ++i) { - char c = *(hex + i); - if(c >= '0' && c <= '9') d[i] = c - '0'; - else if(c >= 'A' && c <= 'F') d[i] = c - 'A' + 10; - else if(c >= 'a' && c <= 'f') d[i] = c - 'a' + 10; - else return 0; // error - } - return (d[0] << 4) | (d[1]); +static uint8_t stlink_parse_hex(const char* hex) { + uint8_t d[2]; + for(int i = 0; i < 2; ++i) { + char c = *(hex + i); + if(c >= '0' && c <= '9') d[i] = c - '0'; + else if(c >= 'A' && c <= 'F') d[i] = c - 'A' + 10; + else if(c >= 'a' && c <= 'f') d[i] = c - 'a' + 10; + else return 0; // error + } + return (d[0] << 4) | (d[1]); } int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin) { - int res = 0; - *begin = UINT32_MAX; - uint8_t* data = NULL; - uint32_t end = 0; - bool eof_found = false; - - for(int scan = 0; (res == 0) && (scan < 2); ++scan) { // parse file two times - first to find memory range, second - to fill it - if(scan == 1) { - if(!eof_found) { - ELOG("No EoF recond\n"); - res = -1; - break; - } - - if(*begin >= end) { - ELOG("No data found in file\n"); - res = -1; - break; - } - - *size = (end - *begin) + 1; - data = calloc(*size, 1); // use calloc to get NULL if out of memory - if(!data) { - ELOG("Cannot allocate %d bytes\n", *size); - res = -1; - break; - } - - memset(data, erased_pattern, *size); - } - - FILE* file = fopen(path, "r"); - if(!file) { - ELOG("Cannot open file\n"); - res = -1; - break; - } - - uint32_t lba = 0; - - char line[1 + 5*2 + 255*2 + 2]; - while(fgets(line, sizeof(line), file)) { - if(line[0] == '\n' || line[0] == '\r') continue; // skip empty lines - if(line[0] != ':') { // no marker - wrong file format - ELOG("Wrong file format - no marker\n"); - res = -1; - break; - } - - size_t l = strlen(line); - while(l > 0 && (line[l-1] == '\n' || line[l-1] == '\r')) --l; // trim EoL - if((l < 11) || (l == (sizeof(line)-1))) { // line too short or long - wrong file format - ELOG("Wrong file format - wrong line length\n"); - res = -1; - break; - } - - // check sum - uint8_t chksum = 0; - for(size_t i = 1; i < l; i += 2) { - chksum += stlink_parse_hex(line + i); - } - if(chksum != 0) { - ELOG("Wrong file format - checksum mismatch\n"); - res = -1; - break; - } - - uint8_t reclen = stlink_parse_hex(line + 1); - if(((uint32_t)reclen + 5)*2 + 1 != l) { - ELOG("Wrong file format - record length mismatch\n"); - res = -1; - break; - } - - uint16_t offset = ((uint16_t)stlink_parse_hex(line + 3) << 8) | ((uint16_t)stlink_parse_hex(line + 5)); - uint8_t rectype = stlink_parse_hex(line + 7); - - switch(rectype) { - case 0: // data - if(scan == 0) { - uint32_t b = lba + offset; - uint32_t e = b + reclen - 1; - if(b < *begin) *begin = b; - if(e > end) end = e; - } - else { - for(size_t i = 0; i < reclen; ++i) { - uint8_t b = stlink_parse_hex(line + 9 + i*2); - uint32_t addr = lba + offset + i; - if(addr >= *begin && addr <= end) { - data[addr - *begin] = b; - } - } - } - break; - - case 1: // EoF - eof_found = true; - break; - - case 2: // Extended Segment Address, unexpected - res = -1; - break; - - case 3: // Start Segment Address, unexpected - res = -1; - break; - - case 4: // Extended Linear Address - if(reclen == 2) { - lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | ((uint32_t)stlink_parse_hex(line + 11) << 16); - } - else { - ELOG("Wrong file format - wrong LBA length\n"); - res = -1; - } - break; - - case 5: // Start Linear Address - expected, but ignore - break; - - default: - ELOG("Wrong file format - unexpected record type %d\n", rectype); - res = -1; - } - if(res != 0) break; - } - - fclose(file); - } - - if(res == 0) { - *mem = data; - } - else { - free(data); - } - - return res; -} - -// FIXME remove -void dumpMem(uint8_t const * mem, size_t len) { - for(size_t i = 0; i < len; ++i) { - if(i > 0 && i % 16 == 0) printf("\n"); - else if(i > 0 && i % 8 == 0) printf(" "); - if(i % 16 == 0) printf("%08zx ", i); - printf("%02x ", mem[i]); - } - printf("\n"); + int res = 0; + *begin = UINT32_MAX; + uint8_t* data = NULL; + uint32_t end = 0; + bool eof_found = false; + + for(int scan = 0; (res == 0) && (scan < 2); ++scan) { // parse file two times - first to find memory range, second - to fill it + if(scan == 1) { + if(!eof_found) { + ELOG("No EoF recond\n"); + res = -1; + break; + } + + if(*begin >= end) { + ELOG("No data found in file\n"); + res = -1; + break; + } + + *size = (end - *begin) + 1; + data = calloc(*size, 1); // use calloc to get NULL if out of memory + if(!data) { + ELOG("Cannot allocate %d bytes\n", *size); + res = -1; + break; + } + + memset(data, erased_pattern, *size); + } + + FILE* file = fopen(path, "r"); + if(!file) { + ELOG("Cannot open file\n"); + res = -1; + break; + } + + uint32_t lba = 0; + + char line[1 + 5*2 + 255*2 + 2]; + while(fgets(line, sizeof(line), file)) { + if(line[0] == '\n' || line[0] == '\r') continue; // skip empty lines + if(line[0] != ':') { // no marker - wrong file format + ELOG("Wrong file format - no marker\n"); + res = -1; + break; + } + + size_t l = strlen(line); + while(l > 0 && (line[l-1] == '\n' || line[l-1] == '\r')) --l; // trim EoL + if((l < 11) || (l == (sizeof(line)-1))) { // line too short or long - wrong file format + ELOG("Wrong file format - wrong line length\n"); + res = -1; + break; + } + + // check sum + uint8_t chksum = 0; + for(size_t i = 1; i < l; i += 2) { + chksum += stlink_parse_hex(line + i); + } + if(chksum != 0) { + ELOG("Wrong file format - checksum mismatch\n"); + res = -1; + break; + } + + uint8_t reclen = stlink_parse_hex(line + 1); + if(((uint32_t)reclen + 5)*2 + 1 != l) { + ELOG("Wrong file format - record length mismatch\n"); + res = -1; + break; + } + + uint16_t offset = ((uint16_t)stlink_parse_hex(line + 3) << 8) | ((uint16_t)stlink_parse_hex(line + 5)); + uint8_t rectype = stlink_parse_hex(line + 7); + + switch(rectype) { + case 0: // data + if(scan == 0) { + uint32_t b = lba + offset; + uint32_t e = b + reclen - 1; + if(b < *begin) *begin = b; + if(e > end) end = e; + } + else { + for(size_t i = 0; i < reclen; ++i) { + uint8_t b = stlink_parse_hex(line + 9 + i*2); + uint32_t addr = lba + offset + i; + if(addr >= *begin && addr <= end) { + data[addr - *begin] = b; + } + } + } + break; + + case 1: // EoF + eof_found = true; + break; + + case 2: // Extended Segment Address, unexpected + res = -1; + break; + + case 3: // Start Segment Address, unexpected + res = -1; + break; + + case 4: // Extended Linear Address + if(reclen == 2) { + lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | ((uint32_t)stlink_parse_hex(line + 11) << 16); + } + else { + ELOG("Wrong file format - wrong LBA length\n"); + res = -1; + } + break; + + case 5: // Start Linear Address - expected, but ignore + break; + + default: + ELOG("Wrong file format - unexpected record type %d\n", rectype); + res = -1; + } + if(res != 0) break; + } + + fclose(file); + } + + if(res == 0) { + *mem = data; + } + else { + free(data); + } + + return res; +} + +static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { + unsigned int val; + /* set stack*/ + stlink_read_debug32(sl, addr, &val); + stlink_write_reg(sl, val, 13); + /* Set PC to the reset routine*/ + stlink_read_debug32(sl, addr + 4, &val); + stlink_write_reg(sl, val, 15); + stlink_run(sl); +} + +uint8_t stlink_get_erased_pattern(stlink_t *sl) { + if (sl->flash_type == STLINK_FLASH_TYPE_L0) + return 0x00; + else + return 0xff; +} + +int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr) { + /* write the block in flash at addr */ + int err; + unsigned int num_empty, index; + uint8_t erased_pattern = stlink_get_erased_pattern(sl); + + index = (unsigned int)length; + for(num_empty = 0; num_empty != length; ++num_empty) { + if (data[--index] != erased_pattern) { + break; + } + } + /* Round down to words */ + num_empty -= (num_empty & 3); + if(num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); + } + err = stlink_write_flash(sl, addr, data, (num_empty == length) ? (uint32_t) length : (uint32_t) length - num_empty, num_empty == length); + stlink_fwrite_finalize(sl, addr); + return err; } /** @@ -1928,59 +2078,31 @@ void dumpMem(uint8_t const * mem, size_t len) { * @param addr where to start writing * @return 0 on success, -ve on failure. */ -int stlink_fwrite_flash(stlink_t *sl, const char* path, bool is_ihex, stm32_addr_t addr) { +int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { /* write the file in flash at addr */ int err; - unsigned int num_empty, index, val; - unsigned char erased_pattern; + unsigned int num_empty, index; + uint8_t erased_pattern = stlink_get_erased_pattern(sl); mapped_file_t mf = MAPPED_FILE_INITIALIZER; - uint8_t * mem; - size_t size; - bool eraseonly = false; - if (sl->flash_type == STLINK_FLASH_TYPE_L0) - erased_pattern = 0x00; - else - erased_pattern = 0xff; - - if(is_ihex) { - uint32_t begin; - if(0 != stlink_parse_ihex(path, 0xFF, &mem, &size, &begin)) - return -1; - addr = begin; - } - else { - if (map_file(&mf, path) == -1) { - ELOG("map_file() == -1\n"); - return -1; - } - - index = (unsigned int) mf.len; - for(num_empty = 0; num_empty != mf.len; ++num_empty) { - if (mf.base[--index] != erased_pattern) { - break; - } - } - /* Round down to words */ - num_empty -= (num_empty & 3); - if(num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); - } - mem = mf.base; - size = (num_empty == mf.len) ? (uint32_t) mf.len : (uint32_t) mf.len - num_empty; - eraseonly = (num_empty == mf.len); - } - err = stlink_write_flash(sl, addr, mem, size, eraseonly); - /* set stack*/ - stlink_read_debug32(sl, addr, &val); - stlink_write_reg(sl, val, 13); - /* Set PC to the reset routine*/ - stlink_read_debug32(sl, addr + 4, &val); - stlink_write_reg(sl, val, 15); - stlink_run(sl); - if(is_ihex) - free(mem); - else - unmap_file(&mf); + if (map_file(&mf, path) == -1) { + ELOG("map_file() == -1\n"); + return -1; + } + + index = (unsigned int) mf.len; + for(num_empty = 0; num_empty != mf.len; ++num_empty) { + if (mf.base[--index] != erased_pattern) { + break; + } + } + /* Round down to words */ + num_empty -= (num_empty & 3); + if(num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); + } + err = stlink_write_flash(sl, addr, mf.base, (num_empty == mf.len) ? (uint32_t) mf.len : (uint32_t) mf.len - num_empty, num_empty == mf.len); + stlink_fwrite_finalize(sl, addr); + unmap_file(&mf); return err; } diff --git a/src/tools/flash.c b/src/tools/flash.c index f26472d45..676606db9 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -10,9 +10,7 @@ #include #include - -#define DEBUG_LOG_LEVEL 100 -#define STND_LOG_LEVEL 50 +#include static stlink_t *connected_stlink = NULL; @@ -27,153 +25,24 @@ static void cleanup(int signal __attribute__((unused))) { exit(1); } -enum st_cmds {DO_WRITE = 0, DO_READ = 1, DO_ERASE = 2}; -struct opts -{ - enum st_cmds cmd; - const char* devname; - char *serial; - const char* filename; - bool is_ihex; - stm32_addr_t addr; - size_t size; - int reset; - int log_level; -}; - static void usage(void) { - puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--serial ] {read|write} /dev/sgX path addr "); + puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--format ] {read|write} /dev/sgX "); puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); - puts("stlinkv2 command line: ./st-flash [--debug] [--reset] [--serial ] {read|write} path addr "); - puts("stlinkv2 command line: ./st-flash [--debug] [--serial ] erase"); - puts(" use hex format for addr, and "); -} - -static int get_opts(struct opts* o, int ac, char** av) -{ - /* stlinkv1 command line: ./st-flash {read|write} /dev/sgX path addr */ - /* stlinkv2 command line: ./st-flash {read|write} path addr */ - - unsigned int i = 0; - - if (ac < 1) return -1; - - if (strcmp(av[0], "--debug") == 0) - { - o->log_level = DEBUG_LOG_LEVEL; - ac--; - av++; - } - else - { - o->log_level = STND_LOG_LEVEL; - } - - if (strcmp(av[0], "--reset") == 0) - { - o->reset = 1; - ac--; - av++; - } - else - { - o->reset = 0; - } - - if (strcmp(av[0], "--serial") == 0) - { - ac--; - av++; - /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ - int j = (int) strlen(av[0]); - if(j%2 != 0){ - puts("no valid hex value, length must be multiple of 2\n"); - return -1; - } - int k=0; - while(j>=0 && k<=13){ - char buffer[3]={0}; - memcpy(buffer,&av[0][j],2); - o->serial[12-k] = (char)strtol((const char*)buffer,NULL, 16); - k++; - j-=2; - } - ac--; - av++; - } - else - { - o->serial = NULL; - } - - if (ac < 1) return -1; - - /* stlinkv2 */ - o->devname = NULL; - - if (strcmp(av[0], "erase") == 0) - { - o->cmd = DO_ERASE; - - /* stlinkv1 mode */ - if (ac == 2) - { - o->devname = av[1]; - i = 1; - } - } - else { - if (ac < 3) return -1; - if (strcmp(av[0], "read") == 0) - { - o->cmd = DO_READ; - - /* stlinkv1 mode */ - if (ac == 5) - { - o->devname = av[1]; - i = 1; - } - if (ac > 3) - o->size = strtoul(av[i + 3], NULL, 16); - } - else if (strcmp(av[0], "write") == 0) - { - o->cmd = DO_WRITE; - - /* stlinkv1 mode */ - if (ac == 4) - { - o->devname = av[1]; - i = 1; - } - } - else - { - return -1; - } - } - - o->filename = av[i + 1]; - /** @todo This is a little evil as strtoul could return 0 and is of type unsigned long int */ - o->addr = (uint32_t) strtoul(av[i + 2], NULL, 16); - o->is_ihex = (0 == strcmp(".hex", o->filename + (strlen(o->filename) - 4))); // ends with .hex - - return 0; + puts("stlinkv2 command line: ./st-flash [--debug] [--reset] [--serial ] [--format ] {read|write} "); + puts("stlinkv2 command line: ./st-flash [--debug] [--serial ] erase"); + puts(" Use hex format for addr, and ."); + puts(" Format may be 'binary' (default) or 'ihex', although must be specified for binary format only."); } - int main(int ac, char** av) { stlink_t* sl = NULL; - struct opts o; - char serial_buffer[13] = {0}; - o.serial = serial_buffer; + struct flash_opts o; int err = -1; o.size = 0; - if (get_opts(&o, ac - 1, av + 1) == -1) + if (flash_get_opts(&o, ac - 1, av + 1) == -1) { printf("invalid command line\n"); usage(); @@ -183,7 +52,7 @@ int main(int ac, char** av) if (o.devname != NULL) /* stlinkv1 */ sl = stlink_v1_open(o.log_level, 1); else /* stlinkv2 */ - sl = stlink_open_usb(o.log_level, 1, o.serial); + sl = stlink_open_usb(o.log_level, 1, (char *)o.serial); if (sl == NULL) return -1; @@ -244,11 +113,25 @@ int main(int ac, char** av) goto on_error; } - if (o.cmd == DO_WRITE) /* write */ + if (o.cmd == FLASH_CMD_WRITE) /* write */ { + uint8_t * mem = NULL; + size_t size = 0; + + if(o.format == FLASH_FORMAT_IHEX) { + err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr); + if (err == -1) { + printf("Cannot parse %s as Intel-HEX file\n", o.filename); + goto on_error; + } + } + if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { - err = stlink_fwrite_flash(sl, o.filename, o.is_ihex, o.addr); + if(o.format == FLASH_FORMAT_IHEX) + err = stlink_mwrite_flash(sl, mem, size, o.addr); + else + err = stlink_fwrite_flash(sl, o.filename, o.addr); if (err == -1) { printf("stlink_fwrite_flash() == -1\n"); @@ -264,7 +147,7 @@ int main(int ac, char** av) goto on_error; } } - } else if (o.cmd == DO_ERASE) + } else if (o.cmd == FLASH_CMD_ERASE) { err = stlink_erase_flash_mass(sl); if (err == -1) @@ -281,7 +164,7 @@ int main(int ac, char** av) else if ((o.addr >= sl->sram_base) && (o.size == 0) && (o.addr < sl->sram_base + sl->sram_size)) o.size = sl->sram_size; - err = stlink_fread(sl, o.filename, o.addr, o.size); + err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); if (err == -1) { printf("stlink_fread() == -1\n"); diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c new file mode 100644 index 000000000..7de2ecde8 --- /dev/null +++ b/src/tools/flash_opts.c @@ -0,0 +1,156 @@ +#include + +#include +#include +#include + +static bool starts_with(const char * str, const char * prefix) { + size_t n = strlen(prefix); + if(strlen(str) < n) return false; + + return (0 == strncmp(str, prefix, n)); +} + +int flash_get_opts(struct flash_opts* o, int ac, char** av) +{ + bool serial_specified = false; + + // defaults + + memset(o, 0, sizeof(*o)); + o->log_level = STND_LOG_LEVEL; + + // options + + while(ac >= 1) { + if (strcmp(av[0], "--debug") == 0) { + o->log_level = DEBUG_LOG_LEVEL; + } + else if (strcmp(av[0], "--reset") == 0) { + o->reset = 1; + } + else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) { + const char * serial; + if(strcmp(av[0], "--serial") == 0) { + ac--; + av++; + if (ac < 1) return -1; + serial = av[0]; + } + else { + serial = av[0] + strlen("--serial="); + } + + /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ + int j = (int)strlen(serial); + if(j % 2 != 0) return -1; + + for(size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { + char buffer[3] = {0}; + memcpy(buffer, serial + j, 2); + o->serial[12 - k] = (uint8_t)strtol(buffer, NULL, 16); + } + + serial_specified = true; + } + else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { + const char * format; + if(strcmp(av[0], "--format") == 0) { + ac--; + av++; + if (ac < 1) return -1; + format = av[0]; + } + else { + format = av[0] + strlen("--format="); + } + + if (strcmp(format, "binary") == 0) + o->format = FLASH_FORMAT_BINARY; + else if (strcmp(format, "ihex") == 0) + o->format = FLASH_FORMAT_IHEX; + else + return -1; + } + else { + break; // non-option found + } + + ac--; + av++; + } + + // command and (optional) device name + + while(ac >= 1) { // looks like for stlinkv1 the device name and command may be swaped - check both positions in all cases + if (strcmp(av[0], "erase") == 0) { + if (o->cmd != FLASH_CMD_NONE) return -1; + o->cmd = FLASH_CMD_ERASE; + } + else if (strcmp(av[0], "read") == 0) { + if (o->cmd != FLASH_CMD_NONE) return -1; + o->cmd = FLASH_CMD_READ; + } + else if (strcmp(av[0], "write") == 0) { + if (o->cmd != FLASH_CMD_NONE) return -1; + o->cmd = FLASH_CMD_WRITE; + } + else if(starts_with(av[0], "/dev/")) { + if (o->devname) return -1; + o->devname = av[0]; + } + else { + break; + } + + ac--; + av++; + } + + char * tail; + switch(o->cmd) { + case FLASH_CMD_NONE: // no command found + return -1; + + case FLASH_CMD_ERASE: // no more arguments expected + if(ac != 0) return -1; + break; + + case FLASH_CMD_READ: // expect filename, addr and size + if (ac != 3) return -1; + + o->filename = av[0]; + o->addr = (uint32_t) strtoul(av[1], &tail, 16); + if(tail[0] != '\0') return -1; + + o->size = strtoul(av[2], &tail, 16); + if(tail[0] != '\0') return -1; + + break; + + case FLASH_CMD_WRITE: + if(o->format == FLASH_FORMAT_BINARY) { // expect filename and addr + if (ac != 2) return -1; + + o->filename = av[0]; + o->addr = (uint32_t) strtoul(av[1], &tail, 16); + if(tail[0] != '\0') return -1; + } + else if(o->format == FLASH_FORMAT_IHEX) { // expect filename + if (ac != 1) return -1; + + o->filename = av[0]; + } + else { + return -1; + } + break; + } + + // some constistence checks + + if(serial_specified && o->devname != NULL) return -1; // serial not supported for v1 + + return 0; +} + diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5d114a608..94e3fb2c5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,3 +8,8 @@ foreach(test ${TESTS}) add_dependencies(${test} ${PROJECT_NAME}) target_link_libraries(${test} ${PROJECT_NAME}) endforeach() + +add_executable(flash flash.c) +add_dependencies(flash stflash) +target_link_libraries(flash stflash) + diff --git a/tests/flash.c b/tests/flash.c new file mode 100644 index 000000000..4e089f2b8 --- /dev/null +++ b/tests/flash.c @@ -0,0 +1,111 @@ +#include +#include +#include + +#include +#include + +struct Test { + const char * cmd_line; + int res; + struct flash_opts opts; +}; + +static bool cmp_strings(const char * s1, const char * s2) { + if(s1 == NULL || s2 == NULL) return (s1 == s2); + else return (0 == strcmp(s1, s2)); +} + +static bool cmp_mem(const uint8_t * s1, const uint8_t * s2, size_t size) { + if(s1 == NULL || s2 == NULL) return (s1 == s2); + else return (0 == memcmp(s1, s2, size)); +} + +static bool execute_test(const struct Test * test) { + int ac = 0; + char* av[32]; + + // parse (tokenize) the test command line + char cmd_line[strlen(test->cmd_line)]; + strcpy(cmd_line, test->cmd_line); + + for(char * tok = strtok(cmd_line, " "); tok; tok = strtok(NULL, " ")) { + if((size_t)ac >= sizeof(av)/sizeof(av[0])) return false; + + av[ac] = tok; + ++ac; + } + + // call + struct flash_opts opts; + int res = flash_get_opts(&opts, ac, av); + + // compare results + bool ret = (res == test->res); + + if(ret && (res == 0)) { + ret &= (opts.cmd == test->opts.cmd); + ret &= cmp_strings(opts.devname, test->opts.devname); + ret &= cmp_mem(opts.serial, test->opts.serial, sizeof(opts.serial)); + ret &= cmp_strings(opts.filename, test->opts.filename); + ret &= (opts.addr == test->opts.addr); + ret &= (opts.size == test->opts.size); + ret &= (opts.reset == test->opts.reset); + ret &= (opts.log_level == test->opts.log_level); + ret &= (opts.format == test->opts.format); + } + + printf("[%s] (%d) %s\n", ret ? "OK" : "ERROR", res, test->cmd_line); + return ret; +} + +struct Test tests[] = { + { "", -1, + {} }, + { "--debug --reset read /dev/sg0 test.bin 0x80000000 0x1000", 0, + { .cmd = FLASH_CMD_READ, .devname = "/dev/sg0", .serial = {}, .filename = "test.bin", + .addr = 0x80000000, .size = 0x1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { "--debug --reset write /dev/sg0 test.bin 0x80000000", 0, + { .cmd = FLASH_CMD_WRITE, .devname = "/dev/sg0", .serial = {}, .filename = "test.bin", + .addr = 0x80000000, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { "--serial A1020304 /dev/sg0 erase", -1, + {} }, + { "/dev/sg0 erase", 0, + { .cmd = FLASH_CMD_ERASE, .devname = "/dev/sg0", .serial = {}, .filename = NULL, + .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { "--debug --reset read test.bin 0x80000000 0x1000", 0, + { .cmd = FLASH_CMD_READ, .devname = NULL, .serial = {}, .filename = "test.bin", + .addr = 0x80000000, .size = 0x1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { "--debug --reset write test.bin 0x80000000", 0, + { .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = {}, .filename = "test.bin", + .addr = 0x80000000, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { "erase", 0, + { .cmd = FLASH_CMD_ERASE, .devname = NULL, .serial = {}, .filename = NULL, + .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { "--debug --reset --format=ihex write test.hex", 0, + { .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = {}, .filename = "test.hex", + .addr = 0, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_IHEX } }, + { "--debug --reset --format=binary write test.hex", -1, + {} }, + { "--debug --reset --format=ihex write test.hex 0x80000000", -1, + {} }, + { "--debug --reset write test.hex sometext", -1, + {} }, + { "--serial A1020304 erase", 0, + { .cmd = FLASH_CMD_ERASE, .devname = NULL, .serial = "\0\0\0\0\0\0\0\0\xA1\x02\x03\x04", .filename = NULL, + .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { "--serial=A1020304 erase", 0, + { .cmd = FLASH_CMD_ERASE, .devname = NULL, .serial = "\0\0\0\0\0\0\0\0\xA1\x02\x03\x04", .filename = NULL, + .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, +}; + +int main() +{ + bool allOk = true; + for(size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) { + if(!execute_test(&tests[i])) allOk = false; + } + + return (allOk ? 0 : 1); +} + From 6c80b8c6b652291d5ddd04c98782fc4a7b0b5b04 Mon Sep 17 00:00:00 2001 From: Anatoli Date: Tue, 6 Sep 2016 23:09:41 +0200 Subject: [PATCH 0465/1435] add write ihex to RAM --- include/stlink.h | 1 + src/common.c | 92 +++++++++++++++++++++++++++++++++++------------ src/tools/flash.c | 13 +++++-- 3 files changed, 82 insertions(+), 24 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 5151cc166..0f032614e 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -184,6 +184,7 @@ typedef struct flash_loader { uint8_t stlink_get_erased_pattern(stlink_t *sl); int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); + int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, 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); diff --git a/src/common.c b/src/common.c index 51c92bac3..24944132f 100644 --- a/src/common.c +++ b/src/common.c @@ -1017,16 +1017,81 @@ static int check_file(stlink_t* sl, mapped_file_t* mf, stm32_addr_t addr) { return 0; } -int stlink_fwrite_sram -(stlink_t * sl, const char* path, stm32_addr_t addr) { +static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { + unsigned int val; + /* set stack*/ + stlink_read_debug32(sl, addr, &val); + stlink_write_reg(sl, val, 13); + /* Set PC to the reset routine*/ + stlink_read_debug32(sl, addr + 4, &val); + stlink_write_reg(sl, val, 15); + stlink_run(sl); +} + +int stlink_mwrite_sram(stlink_t * sl, uint8_t* data, uint32_t length, stm32_addr_t addr) { /* write the file in sram at addr */ int error = -1; size_t off; size_t len; - mapped_file_t mf = MAPPED_FILE_INITIALIZER; - uint32_t val; + /* check addr range is inside the sram */ + if (addr < sl->sram_base) { + fprintf(stderr, "addr too low\n"); + goto on_error; + } else if ((addr + length) < addr) { + fprintf(stderr, "addr overruns\n"); + goto on_error; + } else if ((addr + length) > (sl->sram_base + sl->sram_size)) { + fprintf(stderr, "addr too high\n"); + goto on_error; + } else if (addr & 3) { + /* todo */ + fprintf(stderr, "unaligned addr\n"); + goto on_error; + } + + len = length; + + if(len & 3) { + len -= len & 3; + } + + /* do the copy by 1k blocks */ + for (off = 0; off < len; off += 1024) { + size_t size = 1024; + if ((off + size) > len) + size = len - off; + + memcpy(sl->q_buf, data + off, size); + + /* round size if needed */ + if (size & 3) + size += 2; + + stlink_write_mem32(sl, addr + (uint32_t) off, size); + } + + if(length > len) { + memcpy(sl->q_buf, data + len, length - len); + stlink_write_mem8(sl, addr + (uint32_t) len, length - len); + } + + /* success */ + error = 0; + stlink_fwrite_finalize(sl, addr); + +on_error: + return error; +} + +int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { + /* write the file in sram at addr */ + + int error = -1; + size_t off; + size_t len; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { fprintf(stderr, "map_file() == -1\n"); @@ -1083,13 +1148,7 @@ int stlink_fwrite_sram /* success */ error = 0; - /* set stack*/ - stlink_read_debug32(sl, addr, &val); - stlink_write_reg(sl, val, 13); - /* Set PC to the reset routine*/ - stlink_read_debug32(sl, addr + 4, &val); - stlink_write_reg(sl, val, 15); - stlink_run(sl); + stlink_fwrite_finalize(sl, addr); on_error: unmap_file(&mf); @@ -2031,17 +2090,6 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, return res; } -static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { - unsigned int val; - /* set stack*/ - stlink_read_debug32(sl, addr, &val); - stlink_write_reg(sl, val, 13); - /* Set PC to the reset routine*/ - stlink_read_debug32(sl, addr + 4, &val); - stlink_write_reg(sl, val, 15); - stlink_run(sl); -} - uint8_t stlink_get_erased_pattern(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_L0) return 0x00; diff --git a/src/tools/flash.c b/src/tools/flash.c index 676606db9..d619e63a1 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -40,6 +40,7 @@ int main(int ac, char** av) stlink_t* sl = NULL; struct flash_opts o; int err = -1; + uint8_t * mem = NULL; o.size = 0; if (flash_get_opts(&o, ac - 1, av + 1) == -1) @@ -115,7 +116,6 @@ int main(int ac, char** av) if (o.cmd == FLASH_CMD_WRITE) /* write */ { - uint8_t * mem = NULL; size_t size = 0; if(o.format == FLASH_FORMAT_IHEX) { @@ -140,13 +140,21 @@ int main(int ac, char** av) } else if ((o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { - err = stlink_fwrite_sram(sl, o.filename, o.addr); + if(o.format == FLASH_FORMAT_IHEX) + err = stlink_mwrite_sram(sl, mem, size, o.addr); + else + err = stlink_fwrite_sram(sl, o.filename, o.addr); if (err == -1) { printf("stlink_fwrite_sram() == -1\n"); goto on_error; } } + else { + err = -1; + printf("Unknown memory region\n"); + goto on_error; + } } else if (o.cmd == FLASH_CMD_ERASE) { err = stlink_erase_flash_mass(sl); @@ -183,6 +191,7 @@ int main(int ac, char** av) on_error: stlink_exit_debug_mode(sl); stlink_close(sl); + free(mem); return err; } From 21c970f1391830b8e3176330bb8dd32f8bd55ab9 Mon Sep 17 00:00:00 2001 From: "fabien.lementec" Date: Wed, 7 Sep 2016 07:06:43 +0200 Subject: [PATCH 0466/1435] warning, add FLASH_OPTS_INITIALIZER --- include/stlink/tools/flash.h | 4 ++++ tests/flash.c | 15 +++++---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index 10e6ffac4..dbc9ad881 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -22,6 +22,10 @@ struct flash_opts enum flash_format format; }; + +#define FLASH_OPTS_INITIALIZER {0, } + + int flash_get_opts(struct flash_opts* o, int ac, char** av); #endif // STLINK_FLASH_H_ diff --git a/tests/flash.c b/tests/flash.c index 4e089f2b8..27fd437f6 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -60,16 +60,14 @@ static bool execute_test(const struct Test * test) { } struct Test tests[] = { - { "", -1, - {} }, + { "", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset read /dev/sg0 test.bin 0x80000000 0x1000", 0, { .cmd = FLASH_CMD_READ, .devname = "/dev/sg0", .serial = {}, .filename = "test.bin", .addr = 0x80000000, .size = 0x1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset write /dev/sg0 test.bin 0x80000000", 0, { .cmd = FLASH_CMD_WRITE, .devname = "/dev/sg0", .serial = {}, .filename = "test.bin", .addr = 0x80000000, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, - { "--serial A1020304 /dev/sg0 erase", -1, - {} }, + { "--serial A1020304 /dev/sg0 erase", -1, FLASH_OPTS_INITIALIZER }, { "/dev/sg0 erase", 0, { .cmd = FLASH_CMD_ERASE, .devname = "/dev/sg0", .serial = {}, .filename = NULL, .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, @@ -85,12 +83,9 @@ struct Test tests[] = { { "--debug --reset --format=ihex write test.hex", 0, { .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = {}, .filename = "test.hex", .addr = 0, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_IHEX } }, - { "--debug --reset --format=binary write test.hex", -1, - {} }, - { "--debug --reset --format=ihex write test.hex 0x80000000", -1, - {} }, - { "--debug --reset write test.hex sometext", -1, - {} }, + { "--debug --reset --format=binary write test.hex", -1, FLASH_OPTS_INITIALIZER }, + { "--debug --reset --format=ihex write test.hex 0x80000000", -1, FLASH_OPTS_INITIALIZER }, + { "--debug --reset write test.hex sometext", -1, FLASH_OPTS_INITIALIZER }, { "--serial A1020304 erase", 0, { .cmd = FLASH_CMD_ERASE, .devname = NULL, .serial = "\0\0\0\0\0\0\0\0\xA1\x02\x03\x04", .filename = NULL, .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, From 1cffc453c5b9316251027da24542bf9493f6629c Mon Sep 17 00:00:00 2001 From: Christophe Levantis Date: Wed, 7 Sep 2016 11:11:45 +0100 Subject: [PATCH 0467/1435] Add memory map for stm32f401xe Trying to load a elf image on a stm32f401xe can result in a problem of flash write if a section does not start on a flash sector because the memory map given to gdb was wrong. --- src/gdbserver/gdb-server.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 15f837908..f99f3e7ce 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -433,6 +433,30 @@ static const char* const memory_map_template_F7 = " " // option byte area ""; + +static const char* const memory_map_template_F4_DE = + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // sram + " " //Sectors 0..3 + " 0x4000" //16kB + " " + " " //Sector 4 + " 0x10000" //64kB + " " + " " //Sectors 5..7 + " 0x20000" //128kB + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + " " // otp + " " // option byte area + ""; + char* make_memory_map(stlink_t *sl) { /* This will be freed in serve() */ const size_t sz = 4096; @@ -441,6 +465,8 @@ char* make_memory_map(stlink_t *sl) { if(sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F446) { strcpy(map, memory_map_template_F4); + } else if(sl->chip_id==STLINK_CHIPID_STM32_F4_DE) { + strcpy(map, memory_map_template_F4_DE); } else if(sl->core_id==STM32F7_CORE_ID) { snprintf(map, sz, memory_map_template_F7, sl->sram_size); From fca819f8f99b922f189a7c58075188d50a463725 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 8 Sep 2016 16:16:39 +0200 Subject: [PATCH 0468/1435] cmake/modules/FindLibUSB.cmake: Fix build on FreeBSD --- cmake/modules/FindLibUSB.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index 99e872c3e..ecf3cd25b 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -31,7 +31,7 @@ find_path(LIBUSB_INCLUDE_DIR NAMES libusb.h /usr/local /opt ${LIBUSB_WIN_OUTPUT_FOLDER}/include - PATH_SUFFIXES libusb-1.0 +# PATH_SUFFIXES libusb-1.0 ) if (APPLE) @@ -41,7 +41,7 @@ elseif(MSYS OR MINGW) elseif(WIN32) set(LIBUSB_NAME libusb-1.0.lib) else() - set(LIBUSB_NAME usb-1.0) + set(LIBUSB_NAME usb) endif() if (MSYS OR MINGW) From 4ad75ead7808a4275b4112f33344be91b565fc5b Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 8 Sep 2016 14:31:08 +0200 Subject: [PATCH 0469/1435] cmake/modules/FindLibUSB.cmake: Use correct FindLibUSB.cmake --- cmake/modules/FindLibUSB.cmake | 61 ++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index ecf3cd25b..3b15339e4 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -1,4 +1,4 @@ -# FindLibUSB.cmake - Try to find the Hiredis library +# FindLibUSB.cmake # Once done this will define # # LIBUSB_FOUND - System has libusb @@ -6,42 +6,51 @@ # LIBUSB_LIBRARY - The libraries needed to use libusb # LIBUSB_DEFINITIONS - Compiler switches required for using libusb -if(WIN32 OR MINGW OR MSYS) - set(LIBUSB_WIN_VERSION "1.0.20") +if(WIN32 OR CMAKE_VS_PLATFORM_NAME) + set(LIBUSB_WIN_VERSION 1.0.20) set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) - set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/libusb-${LIBUSB_WIN_VERSION}) + set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3thparty/libusb-${LIBUSB_WIN_VERSION}) - if (EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) + if(EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) message(STATUS "libusb archive already in build folder") - else () - message(STATUS "libusb downloading ${LIBUSB_WIN_VERSION}") + else() + message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download ${LIBUSB_WIN_ARCHIVE_PATH} - SHOW_PROGRESS) - endif () - + ) + endif() execute_process(COMMAND ${ZIP_LOCATION} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER}) endif() -find_path(LIBUSB_INCLUDE_DIR NAMES libusb.h +# FreeBSD +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS + /usr/include + ) +else () + FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr /usr/local /opt ${LIBUSB_WIN_OUTPUT_FOLDER}/include -# PATH_SUFFIXES libusb-1.0 -) + PATH_SUFFIXES libusb-1.0 + ) +endif() + +message(STATUS "LIBUSB_INCLUDE_DIR: ${LIBUSB_INCLUDE_DIR}") if (APPLE) set(LIBUSB_NAME libusb-1.0.a) -elseif(MSYS OR MINGW) - set(LIBUSB_NAME usb-1.0) -elseif(WIN32) +elseif(WIN32 OR CMAKE_VS_PLATFORM_NAME) set(LIBUSB_NAME libusb-1.0.lib) -else() +elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") set(LIBUSB_NAME usb) +else() + set(LIBUSB_NAME usb-1.0) endif() if (MSYS OR MINGW) @@ -52,12 +61,20 @@ if (MSYS OR MINGW) find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static) endif () -else () +elseif(CMAKE_VS_PLATFORM_NAME) + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/static) + else () + find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/static) + endif () +else() find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS - /usr - /usr/local - /opt) + HINTS + /usr + /usr/local + /opt) endif () include(FindPackageHandleStandardArgs) From bd5dd332232bd451b8fbe728a70434dac5a4d0f9 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 8 Sep 2016 16:32:32 +0200 Subject: [PATCH 0470/1435] tests: Enable make test with CTest using add_test. Remove unnecessary library building for st-flash arg parser --- CMakeLists.txt | 6 ++---- tests/CMakeLists.txt | 8 ++++---- tests/sg.c | 12 +++--------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fcaf9ec94..c321cc48b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,11 +179,9 @@ if (APPLE) target_link_libraries(${PROJECT_NAME} ${CoreFoundation} ${IOKit} ${ObjC}) endif () -add_library(stflash STATIC - src/tools/flash_opts.c) target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARY}) -add_executable(st-flash src/tools/flash.c) -target_link_libraries(st-flash ${PROJECT_NAME} stflash) +add_executable(st-flash src/tools/flash.c src/tools/flash_opts.c) +target_link_libraries(st-flash ${PROJECT_NAME}) add_executable(st-info src/tools/info.c) target_link_libraries(st-info ${PROJECT_NAME}) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 94e3fb2c5..fc51433bd 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -7,9 +7,9 @@ foreach(test ${TESTS}) add_executable(${test} ${test}.c) add_dependencies(${test} ${PROJECT_NAME}) target_link_libraries(${test} ${PROJECT_NAME}) + add_test(${test} ${CMAKE_CURRENT_BINARY_DIR}/${test}) endforeach() -add_executable(flash flash.c) -add_dependencies(flash stflash) -target_link_libraries(flash stflash) - +add_executable(flash flash.c "${CMAKE_SOURCE_DIR}/src/tools/flash_opts.c") +target_link_libraries(flash ${PROJECT_NAME}) +add_test(flash ${CMAKE_CURRENT_BINARY_DIR}/flash) diff --git a/tests/sg.c b/tests/sg.c index d12f6ba43..5426b6ff3 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -25,13 +25,11 @@ static void __attribute__((unused)) mark_buf(stlink_t *sl) { } -int main(int argc, char *argv[]) { +int main(void) +{ /* Avoid unused parameter warning */ - (void)argv; // set scpi lib debug level: 0 for no debug info, 10 for lots - switch (argc) { - case 1: fputs( "\nUsage: stlink-access-test [anything at all] ...\n" "\n*** Notice: The stlink firmware violates the USB standard.\n" @@ -40,14 +38,10 @@ int main(int argc, char *argv[]) { "*** Unplug the stlink and execute once as root:\n" "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n\n", stderr); - return EXIT_FAILURE; - default: - break; - } stlink_t *sl = stlink_v1_open(99, 1); if (sl == NULL) - return EXIT_FAILURE; + return 0; // we are in mass mode, go to swd stlink_enter_swd_mode(sl); From cc1cb00d734e4581cd142c6f0a781d6789a9eab6 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 8 Sep 2016 17:07:09 +0200 Subject: [PATCH 0471/1435] Fix variable shadow warnings (brk, signal). Disable redundant-decl flag on OpenBSD --- CMakeLists.txt | 16 +++++++++++++--- src/common.c | 14 +++++++------- src/gdbserver/gdb-server.c | 35 ++++++++++++++++++----------------- src/tools/flash.c | 4 +++- src/tools/term.c | 6 +++--- 5 files changed, 44 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c321cc48b..b8c13b261 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,8 @@ endif () set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") +message(STATUS "Building on ${CMAKE_SYSTEM_NAME}") + # Determine package version. find_package (Git QUIET) if (DEFINED ENV{TRAVIS_TAG} AND NOT "$ENV{TRAVIS_TAG}" STREQUAL "") @@ -95,7 +97,16 @@ add_cflag_if_supported("-Wmaybe-uninitialized") add_cflag_if_supported("-Wmissing-variable-declarations") add_cflag_if_supported("-Wshorten-64-to-32") add_cflag_if_supported("-Wimplicit-function-declaration") -add_cflag_if_supported("-Wredundant-decls") + +## +# On OpenBSD the system headers suck so we need to disable redundant declaration check +# /usr/include/unistd.h:429: warning: redundant redeclaration of 'truncate' +# /usr/include/sys/types.h:218: warning: previous declaration of 'truncate' was here +## +if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") + add_cflag_if_supported("-Wredundant-decls") +endif () + add_cflag_if_supported("-Wundef") if (NOT MSYS OR MINGW) add_cflag_if_supported("-fPIC") @@ -106,10 +117,9 @@ if (CMAKE_BUILD_TYPE STREQUAL "") endif () if(${CMAKE_BUILD_TYPE} MATCHES "Debug") - include(CTest) add_cflag_if_supported("-ggdb") add_cflag_if_supported("-O0") - #set (STLINK_PACKAGE_VERSION "${STLINK_PACKAGE_VERSION}-debug") + include(CTest) elseif() add_cflag_if_supported("-O2") endif() diff --git a/src/common.c b/src/common.c index 24944132f..74fa1043e 100644 --- a/src/common.c +++ b/src/common.c @@ -871,7 +871,7 @@ int stlink_current_mode(stlink_t *sl) { // const int i = 1; // #define is_bigendian() ( (*(char*)&i) == 0 ) -inline unsigned int is_bigendian(void) { +unsigned int is_bigendian(void) { static volatile const unsigned int i = 1; return *(volatile const char*) &i == 0; } @@ -2100,12 +2100,12 @@ uint8_t stlink_get_erased_pattern(stlink_t *sl) { int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr) { /* write the block in flash at addr */ int err; - unsigned int num_empty, index; + unsigned int num_empty, idx; uint8_t erased_pattern = stlink_get_erased_pattern(sl); - index = (unsigned int)length; + idx = (unsigned int)length; for(num_empty = 0; num_empty != length; ++num_empty) { - if (data[--index] != erased_pattern) { + if (data[--idx] != erased_pattern) { break; } } @@ -2129,7 +2129,7 @@ int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { /* write the file in flash at addr */ int err; - unsigned int num_empty, index; + unsigned int num_empty, idx; uint8_t erased_pattern = stlink_get_erased_pattern(sl); mapped_file_t mf = MAPPED_FILE_INITIALIZER; @@ -2138,9 +2138,9 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { return -1; } - index = (unsigned int) mf.len; + idx = (unsigned int) mf.len; for(num_empty = 0; num_empty != mf.len; ++num_empty) { - if (mf.base[--index] != erased_pattern) { + if (mf.base[--idx] != erased_pattern) { break; } } diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index f99f3e7ce..4d52d0cba 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -3,7 +3,7 @@ * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ - +#include #include #include #include @@ -55,7 +55,9 @@ int serve(stlink_t *sl, st_state_t *st); char* make_memory_map(stlink_t *sl); static void init_cache (stlink_t *sl); -static void cleanup(int signal __attribute__((unused))) { +static void cleanup(int signum) { + (void)signum; + if (connected_stlink) { /* Switch back to mass storage mode before closing. */ stlink_run(connected_stlink); @@ -670,29 +672,29 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { else return 0; // Breakpoint is already removed } - struct code_hw_breakpoint* brk = &code_breaks[id]; + struct code_hw_breakpoint* bp = &code_breaks[id]; - brk->addr = fpb_addr; + bp->addr = fpb_addr; if (sl->core_id==STM32F7_CORE_ID) { - if(set) brk->type = type; - else brk->type = 0; + if(set) bp->type = type; + else bp->type = 0; - mask = (brk->addr) | 1; + mask = (bp->addr) | 1; } else { - if(set) brk->type |= type; - else brk->type &= ~type; + if(set) bp->type |= type; + else bp->type &= ~type; - mask = (brk->addr) | 1 | (brk->type << 30); + mask = (bp->addr) | 1 | (bp->type << 30); } - if(brk->type == 0) { + if(bp->type == 0) { DLOG("clearing hw break %d\n", id); stlink_write_debug32(sl, 0xe0002008 + id * 4, 0); } else { DLOG("setting hw break %d at %08x (%d)\n", - id, brk->addr, brk->type); + id, bp->addr, bp->type); DLOG("reg %08x \n", mask); @@ -795,12 +797,11 @@ static int flash_go(stlink_t *sl) { stlink_calculate_pagesize(sl, page); DLOG("flash_do: page %08x\n", page); - unsigned send = (length > FLASH_PAGE) ? (unsigned) FLASH_PAGE : length; - if(stlink_write_flash(sl, page, fb->data + (page - fb->addr), - send, 0) < 0) + unsigned len = (length > FLASH_PAGE) ? (unsigned) FLASH_PAGE : length; + int ret = stlink_write_flash(sl, page, fb->data + (page - fb->addr), len, 0); + if (ret < 0) goto error; - length -= send; - + length -= len; } } diff --git a/src/tools/flash.c b/src/tools/flash.c index d619e63a1..2dde37d06 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -14,7 +14,9 @@ static stlink_t *connected_stlink = NULL; -static void cleanup(int signal __attribute__((unused))) { +static void cleanup(int signum) { + (void)signum; + if (connected_stlink) { /* Switch back to mass storage mode before closing. */ stlink_run(connected_stlink); diff --git a/src/tools/term.c b/src/tools/term.c index 3f3517f9e..ffbbb1a9f 100644 --- a/src/tools/term.c +++ b/src/tools/term.c @@ -1,10 +1,8 @@ #include #include -/* According to POSIX.1-2001 */ #include #include #include -#include #include #include #include @@ -52,7 +50,9 @@ struct stlinky { void nonblock(int state); -static void cleanup(int signal __attribute__((unused))) { +static void cleanup(int signum) { + (void)signum; + if (gsl) { /* Switch back to mass storage mode before closing. */ stlink_run(gsl); From 1d19a84b5fe2ba816e8671fd2ddc12ef71a78d0b Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 8 Sep 2016 15:25:24 +0200 Subject: [PATCH 0472/1435] Update README.md Add jenkins.ncrmnt.org build badge status --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d9388c12e..3671fbf3f 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ Open source version of the STMicroelectronics Stlink Tools [![GitHub release](https://img.shields.io/github/release/texane/stlink.svg?maxAge=2592000)](https://github.com/texane/stlink/releases/latest) [![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.2.0.svg?maxAge=2592000)](https://github.com/texane/stlink/compare/1.2.0...master) [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) +[![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/stlink) [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) ## HOWTO From 3fd0f099782506532198473b24f643a3f68d5ff9 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 8 Sep 2016 15:43:27 +0200 Subject: [PATCH 0473/1435] Remove hacky st-term (which needed special undocumented firmware from https://github.com/nekromant/antares/tree/master/src/lib/stlinky ) as we now have arm semihosting with a well defined interface --- CMakeLists.txt | 9 -- src/tools/term.c | 322 ----------------------------------------------- 2 files changed, 331 deletions(-) delete mode 100644 src/tools/term.c diff --git a/CMakeLists.txt b/CMakeLists.txt index b8c13b261..24c4f51d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -251,15 +251,6 @@ if (NOT APPLE AND NOT WIN32) DESTINATION lib/${CMAKE_LIBRARY_PATH}/pkgconfig/) endif() -if(NOT MINGW) - list(APPEND STLINK_SOURCE src/tools/term.c) - add_executable(st-term src/tools/term.c) - target_link_libraries(st-term ${PROJECT_NAME}) - - install(TARGETS st-term - RUNTIME DESTINATION bin) -endif() - if (NOT APPLE AND gtk_FOUND) include_directories(SYSTEM ${gtk_INCLUDE_DIRS}) set(GUI_SOURCES src/tools/gui/stlink-gui.c diff --git a/src/tools/term.c b/src/tools/term.c deleted file mode 100644 index ffbbb1a9f..000000000 --- a/src/tools/term.c +++ /dev/null @@ -1,322 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* STLinky structure on STM chip - -struct stlinky { - uint32_t magic; - uint32_t bufsize; - uint32_t up_tail; - uint32_t up_head; - uint32_t dw_tail; - uint32_t dw_head; - char upbuf[CONFIG_LIB_STLINKY_BSIZE]; - char dwbuf[CONFIG_LIB_STLINKY_BSIZE]; -} __attribute__ ((packed)); -*/ - - -#define STLINKY_MAGIC 0xDEADF00D - -#define ST_TERM_MAX_BUFF_SIZE (1024*1024) //1Mb - -#define RX_Q_OFFSET 8 -#define RX_BUFF_OFFSET 24 -#define TX_Q_OFFSET 16 -#define TX_BUFF_OFFSET(bufsize) (24 + bufsize) - -#define READ_UINT32_LE(buf) ((uint32_t) ( buf[0] \ - | buf[1] << 8 \ - | buf[2] << 16 \ - | buf[3] << 24)) - -static stlink_t* gsl; -static sigset_t sig_mask; - -struct stlinky { - stlink_t *sl; - uint32_t off; - size_t bufsize; -}; - -void nonblock(int state); - -static void cleanup(int signum) { - (void)signum; - - if (gsl) { - /* Switch back to mass storage mode before closing. */ - stlink_run(gsl); - stlink_exit_debug_mode(gsl); - stlink_close(gsl); - } - - printf("\n"); - nonblock(0); - exit(1); -} - -void sig_init() { - sigemptyset(&sig_mask); - sigaddset(&sig_mask, SIGINT); - sigaddset(&sig_mask, SIGTERM); - signal(SIGINT, &cleanup); - signal(SIGTERM, &cleanup); - sigprocmask(SIG_BLOCK, &sig_mask, NULL); -} - -void sig_process() { - sigset_t pending; - sigpending(&pending); - if (sigismember(&pending, SIGINT) || sigismember(&pending, SIGTERM)) { - sigprocmask(SIG_UNBLOCK, &sig_mask, NULL); - sigsuspend(&pending); - sigprocmask(SIG_BLOCK, &sig_mask, NULL); - } -} - -/* Detects stlinky in RAM, returns handler */ -struct stlinky* stlinky_detect(stlink_t* sl) -{ - static const uint32_t sram_base = 0x20000000; - struct stlinky* st = malloc(sizeof(struct stlinky)); - int multiple=0; - st->sl = sl; - printf("sram: 0x%x bytes @ 0x%zx\n", sl->sram_base, sl->sram_size); - uint32_t off; - for (off = 0; off < sl->sram_size; off += 4) { - if (off % 1024 == 0) sig_process(); - stlink_read_mem32(sl, sram_base + off, 4); - if (STLINKY_MAGIC == READ_UINT32_LE(sl->q_buf)) - { - if (multiple > 0) printf("WARNING: another "); - printf("stlinky detected at 0x%x\n", sram_base + off); - st->off = sram_base + off; - stlink_read_mem32(sl, st->off + 4, 4); - st->bufsize = READ_UINT32_LE(sl->q_buf); - printf("stlinky buffer size 0x%u \n", (unsigned int)st->bufsize); - multiple++; - } - } - if (multiple > 0) { - if (multiple > 1) { - printf("Using last stlinky structure detected\n"); - } - return st; - } - return NULL; -} - -static void stlinky_read_buff(struct stlinky *st, uint32_t off, uint32_t size, char *buffer) -{ - int aligned_size; - - if (size == 0) - return; - - //Read from device with 4-byte alignment - aligned_size = (size & 0xFFFFFFFC) + 8; - stlink_read_mem32(st->sl, off & 0xFFFFFFFC, aligned_size); - - //copy to local buffer - memcpy(buffer, st->sl->q_buf + (off & 0x3), size); - - return; -} - -static void stlinky_write_buf(struct stlinky *st, uint32_t off, uint32_t size, char *buffer) -{ - memcpy(st->sl->q_buf, buffer, size); - stlink_write_mem8(st->sl, off, size); - return; -} - -size_t stlinky_rx(struct stlinky *st, char* buffer) -{ - //read head and tail values - uint32_t tail, head; - stlink_read_mem32(st->sl, st->off + RX_Q_OFFSET, sizeof(tail) + sizeof(head)); - memcpy(&tail, &st->sl->q_buf[0], sizeof(tail)); - memcpy(&head, &st->sl->q_buf[sizeof(tail)], sizeof(head)); - - //return if empty - if(head == tail) - return 0; - - //read data - int size_read = 0; - if(head > tail){ - stlinky_read_buff(st, st->off + RX_BUFF_OFFSET + tail, head - tail, buffer); - size_read += head - tail; - } else if(head < tail){ - stlinky_read_buff(st, st->off + RX_BUFF_OFFSET + tail, (uint32_t) st->bufsize - tail, buffer); - size_read += st->bufsize - tail; - - stlinky_read_buff(st, st->off + RX_BUFF_OFFSET, head, buffer + size_read); - size_read += head; - } - - //move tail - tail = (tail + size_read) % st->bufsize; - - //write tail - memcpy(st->sl->q_buf, &tail, sizeof(tail)); - stlink_write_mem32(st->sl, st->off + RX_Q_OFFSET, sizeof(tail)); - - return size_read; -} - -size_t stlinky_tx(struct stlinky *st, char* buffer, size_t siz) -{ - //read head and tail values - uint32_t tail, head; - stlink_read_mem32(st->sl, st->off + TX_Q_OFFSET, sizeof(tail) + sizeof(head)); - memcpy(&tail, &st->sl->q_buf[0], sizeof(tail)); - memcpy(&head, &st->sl->q_buf[sizeof(tail)], sizeof(head)); - - //Figure out buffer usage - int usage = head - tail; - if (usage < 0) - usage += st->bufsize; - - //check if new data will fit - if (usage + siz >= st->bufsize) - return 0; - - //copy in data (take care of possible split) - int first_chunk = (head + siz >= st->bufsize) ? (int) st->bufsize - (int) head : (int) siz; - int second_chunk = (int) siz - first_chunk; - - //copy data - stlinky_write_buf(st, st->off + (uint32_t) TX_BUFF_OFFSET(st->bufsize) + head, first_chunk, buffer); - if (second_chunk > 0) - stlinky_write_buf(st, st->off + (uint32_t) TX_BUFF_OFFSET(st->bufsize), - second_chunk, buffer + first_chunk); - - //increment head pointer - head = (head + siz) % (uint32_t) st->bufsize; - memcpy(st->sl->q_buf, &head, sizeof(head)); - stlink_write_mem32(st->sl, st->off + TX_Q_OFFSET + sizeof(tail), sizeof(head)); - - return siz; -} - -int kbhit() -{ - struct timeval tv; - fd_set fds; - tv.tv_sec = 0; - tv.tv_usec = 0; - FD_ZERO(&fds); - FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0 - select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); - return FD_ISSET(STDIN_FILENO, &fds); -} - -void nonblock(int state) -{ - struct termios ttystate; - - //get the terminal state - tcgetattr(STDIN_FILENO, &ttystate); - - if (state==1) - { - //turn off canonical mode - ttystate.c_lflag &= ~ICANON; - ttystate.c_lflag &= ~ECHO; - //minimum of number input read. - ttystate.c_cc[VMIN] = 1; - } - else if (state==0) - { - //turn on canonical mode - ttystate.c_lflag |= ICANON | ECHO; - } - //set the terminal attributes. - tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); - -} - -int main(int ac, char** av) { - struct stlinky *st=NULL; - - sig_init(); - - gsl = stlink_open_usb(10, 1, NULL); - if (gsl != NULL) { - printf("ST-Linky proof-of-concept terminal :: Created by Necromant for lulz\n"); - stlink_version(gsl); - stlink_enter_swd_mode(gsl); - printf("chip id: %#x\n", gsl->chip_id); - printf("core_id: %#x\n", gsl->core_id); - - cortex_m3_cpuid_t cpuid; - stlink_cpu_id(gsl, &cpuid); - printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); - printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); - - stlink_reset(gsl); - stlink_force_debug(gsl); - stlink_run(gsl); - stlink_status(gsl); - - /* wait for device to boot */ - /* TODO: Make timeout adjustable via command line */ - sleep(1); - - if(ac == 1){ - st = stlinky_detect(gsl); - }else if(ac == 2){ - st = malloc(sizeof(struct stlinky)); - st->sl = gsl; - st->off = (int)strtol(av[1], NULL, 16); - printf("using stlinky at 0x%x\n", st->off); - stlink_read_mem32(gsl, st->off + 4, 4); - st->bufsize = READ_UINT32_LE(gsl->q_buf); - printf("stlinky buffer size 0x%u \n", (unsigned int)st->bufsize); - }else{ - cleanup(0); - } - if (st == NULL) - { - printf("stlinky magic not found in sram :(\n"); - cleanup(0); - } - if (st->bufsize > ST_TERM_MAX_BUFF_SIZE){ - printf("stlinky buffer size too big\n"); - cleanup(0); - } - char* rxbuf = malloc(st->bufsize); - char* txbuf = malloc(st->bufsize); - size_t tmp; - nonblock(1); - int fd = fileno(stdin); - int saved_flags = fcntl(fd, F_GETFL); - fcntl(fd, F_SETFL, saved_flags & ~O_NONBLOCK); - printf("Entering interactive terminal. CTRL+C to exit\n\n\n"); - while(1) { - sig_process(); - tmp = stlinky_rx(st, rxbuf); - if(tmp > 0) - { - fwrite(rxbuf,tmp,1,stdout); - fflush(stdout); - } - if (kbhit()) { - tmp = read(fd, txbuf, st->bufsize); - stlinky_tx(st,txbuf,tmp); - } - } - } - return 0; -} From 77df02bf92612520478e014ad1a6f257aade714f Mon Sep 17 00:00:00 2001 From: Andrew Andrianov Date: Wed, 14 Sep 2016 16:55:06 +0300 Subject: [PATCH 0474/1435] CMakeLists.txt: Fix linker command in generated .pc file Signed-off-by: Andrew Andrianov --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 24c4f51d1..6b6c7b306 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -232,7 +232,7 @@ if (NOT APPLE AND NOT WIN32) "\${prefix}/include/\${deb_host_multiarch}/${PROJECT_NAME}-${STLINK_PACKAGE_VERSION}" ) set(PKG_CONFIG_LIBS - "-L\${libdir} -l:libstlink.so.${STLINK_PACKAGE_VERSION}" + "-L\${libdir} -l:libstlink.so.${STLINK_PACKAGE_VERSION_MAJOR}" ) set(PKG_CONFIG_CFLAGS "-I\${includedir}" From 6dfb8bafdb95e244271cf232ed2da8dbedbad08c Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Wed, 14 Sep 2016 17:11:47 +0200 Subject: [PATCH 0475/1435] Update changelog for upcomming v1.3.0 release --- .version | 2 +- ChangeLog.md | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/.version b/.version index d72f26267..b6bb93f7c 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.0.0-dev +1.3.0-dev diff --git a/ChangeLog.md b/ChangeLog.md index 355ba08ab..fead8b8ec 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,14 +1,31 @@ Stlink ChangeLog ================ -v2.0.0 +v1.3.0 ====== -Ongoing development +Release date: ongoing Major changes: -* Deprecation of autotools (autoconf, automake) +* Deprecation of autotools (autoconf, automake) (Jerry Jacobs) +* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature (Jerry Jacobs) +* Add debian packaging (nekromant) +* Add intel hex file reading for `st-flash` (pull-request #459) (dev26th) + +Chip support added for: + +* STM32F410 (Jerry Jacobs) +* L0x Category 5 devices (gluedig) +* Add L0 Category 2 device (chip id: 0x425) (Áron RADICS) + +Updates and fixes: + +* Fix memory map for STM32F4 (zulusw) +* Fix STM32L-problem with flash loader (issue #390) (Tom de Boer) +* `st-util` don't read target voltage on startup as it crashes STM32F100 (probably stlink/v1) (Greg Alexander) +* Do a JTAG reset prior to reading CPU information when processor is in deep sleep (andyg24) +* Redesign of `st-flash` commandline options parsing (pull-request #459) (dev26th) v1.2.0 ====== From ddbe285dad875ea90bd663641d74a0cf8156c356 Mon Sep 17 00:00:00 2001 From: "Daniel Campoverde [alx741]" Date: Wed, 14 Sep 2016 21:58:49 -0500 Subject: [PATCH 0476/1435] Add man page installation to Cmake rules --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b6c7b306..bfa752d6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,6 +150,11 @@ set(STLINK_SOURCE src/flash_loader.c ) +set(STLINK_MANPAGES + doc/man/stlink.1 +) + + if (WIN32 OR MSYS OR MINGW) set (STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") # TODO endif () @@ -224,6 +229,9 @@ install(FILES ${CMAKE_SOURCE_DIR}/include/stlink.h install(FILES ${STLINK_HEADERS} DESTINATION include/${CMAKE_LIBRARY_PATH}/stlink-${STLINK_PACKAGE_VERSION}/stlink) +install(FILES ${STLINK_MANPAGES} + DESTINATION share/man/man1) + if (NOT APPLE AND NOT WIN32) set(PKG_CONFIG_LIBDIR "\${prefix}/lib/\${deb_host_multiarch}" From b0df7049dd119a2c8cace2cd75b5084313b227c8 Mon Sep 17 00:00:00 2001 From: "Daniel Campoverde [alx741]" Date: Wed, 14 Sep 2016 22:15:53 -0500 Subject: [PATCH 0477/1435] Add st-util man page --- doc/man/.gitignore | 1 + doc/man/Makefile | 11 ++++++++ doc/man/st-util.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 doc/man/.gitignore create mode 100644 doc/man/Makefile create mode 100644 doc/man/st-util.md diff --git a/doc/man/.gitignore b/doc/man/.gitignore new file mode 100644 index 000000000..f7e585b87 --- /dev/null +++ b/doc/man/.gitignore @@ -0,0 +1 @@ +*.1 diff --git a/doc/man/Makefile b/doc/man/Makefile new file mode 100644 index 000000000..8871c6331 --- /dev/null +++ b/doc/man/Makefile @@ -0,0 +1,11 @@ +MAN1 = +MAN1 += st-util.md + +all: $(patsubst %.md, %.1, $(MAN1)) + +%.1: %.md + pandoc -s -t man $< -o $@ + tail --line=+3 $@ > tmp && mv tmp $@ + +clean: + rm *.1 diff --git a/doc/man/st-util.md b/doc/man/st-util.md new file mode 100644 index 000000000..8f015c806 --- /dev/null +++ b/doc/man/st-util.md @@ -0,0 +1,68 @@ +% ST-UTIL(1) Open Source STMicroelectronics Stlink Tools | STLINK +% +% Sep 2016 + + +# NAME +st-util - Run GDB server to interact with STM32 device + + +# SYNOPSIS +*st-util* \[\...] + + +# DESCRIPTION +Start a GDB server to interact with a STM32 device +Run the main binary of the local package (src/main.rs). + +If a port number is not specified using the **--listen_port** option, the +default **4242** port will be used. + +Stlink version 2 is used by default unless the option **--stlinkv1** is given. + +The STLINKv2 device to use can be specified in the environment +variable STLINK_DEVICE on the format :. + + +# OPTIONS + +-h, --help +: Print this message. + +-v *XX*, --verbose=XX +: Specify a specific verbosity level (0..99) + +-v, --verbose +: Specify generally verbose logging + +-s *X*, --stlink_version=X +: Choose what version of stlink to use, (defaults to 2) + +-1, --stlinkv1 +: Force stlink version 1 + +-p *4242*, --listen_port=1234 +: Set the gdb server listen port. (default port: 4242) + +-m, --multi +: Set gdb server to extended mode. st-util will continue listening for connections after disconnect. + +-n, --no-reset +: Do not reset board on connection. + + +# EXAMPLES +Run GDB server on port 4500 and connect to it + + $ st-util -p 4500 + $ gdb + (gdb) target extended-remote localhost:4500 + + +# SEE ALSO +st-flash(1), st-info(1), st-term(1) + + +# COPYRIGHT +This work is copyrighted. Stlink contributors. +See *LICENSE* file in the stlink source distribution. From d50bd3705eee029a1af7129854c4f100c98b2b36 Mon Sep 17 00:00:00 2001 From: "fabien.lementec" Date: Thu, 15 Sep 2016 08:04:12 +0200 Subject: [PATCH 0478/1435] fix: add missing st-util.1 until proper solution --- doc/man/st-util.1 | 80 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 doc/man/st-util.1 diff --git a/doc/man/st-util.1 b/doc/man/st-util.1 new file mode 100644 index 000000000..674b0dbef --- /dev/null +++ b/doc/man/st-util.1 @@ -0,0 +1,80 @@ +.PP +st-util - Run GDB server to interact with STM32 device +.SH SYNOPSIS +.PP +\f[I]st-util\f[] [...] +.SH DESCRIPTION +.PP +Start a GDB server to interact with a STM32 device Run the main binary +of the local package (src/main.rs). +.PP +If a port number is not specified using the \f[B]--listen_port\f[] +option, the default \f[B]4242\f[] port will be used. +.PP +Stlink version 2 is used by default unless the option +\f[B]--stlinkv1\f[] is given. +.PP +The STLINKv2 device to use can be specified in the environment variable +STLINK_DEVICE on the format :. +.SH OPTIONS +.TP +.B -h, --help +Print this message. +.RS +.RE +.TP +.B -v \f[I]XX\f[], --verbose=XX +Specify a specific verbosity level (0..99) +.RS +.RE +.TP +.B -v, --verbose +Specify generally verbose logging +.RS +.RE +.TP +.B -s \f[I]X\f[], --stlink_version=X +Choose what version of stlink to use, (defaults to 2) +.RS +.RE +.TP +.B -1, --stlinkv1 +Force stlink version 1 +.RS +.RE +.TP +.B -p \f[I]4242\f[], --listen_port=1234 +Set the gdb server listen port. +(default port: 4242) +.RS +.RE +.TP +.B -m, --multi +Set gdb server to extended mode. +st-util will continue listening for connections after disconnect. +.RS +.RE +.TP +.B -n, --no-reset +Do not reset board on connection. +.RS +.RE +.SH EXAMPLES +.PP +Run GDB server on port 4500 and connect to it +.IP +.nf +\f[C] +$\ st-util\ -p\ 4500 +$\ gdb +(gdb)\ target\ extended-remote\ localhost:4500 +\f[] +.fi +.SH SEE ALSO +.PP +st-flash(1), st-info(1), st-term(1) +.SH COPYRIGHT +.PP +This work is copyrighted. +Stlink contributors. +See \f[I]LICENSE\f[] file in the stlink source distribution. From c3f6fd0516503ffa56cc8e5c936eea5a1a8140ad Mon Sep 17 00:00:00 2001 From: "fabien.lementec" Date: Thu, 15 Sep 2016 08:06:34 +0200 Subject: [PATCH 0479/1435] fix: cmake, st-util.1 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bfa752d6b..d2e0acda8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -151,7 +151,7 @@ set(STLINK_SOURCE ) set(STLINK_MANPAGES - doc/man/stlink.1 + doc/man/st-util.1 ) From 1ade678f9cb04898324a6b75ac7396b7b3b73ca7 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 15 Sep 2016 10:44:01 +0200 Subject: [PATCH 0480/1435] Refactor main CMakeLists.txt. Generate manpages when pandoc is present in Debug builds. Add top level Makefile --- CMakeLists.txt | 20 +- Makefile | 45 ++++ cmake/modules/pandocology.cmake | 373 ++++++++++++++++++++++++++++++++ doc/man/CMakeLists.txt | 28 +++ doc/man/Makefile | 11 - include/CMakeLists.txt | 8 + 6 files changed, 456 insertions(+), 29 deletions(-) create mode 100644 Makefile create mode 100644 cmake/modules/pandocology.cmake create mode 100644 doc/man/CMakeLists.txt delete mode 100644 doc/man/Makefile create mode 100644 include/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index d2e0acda8..a75bf2219 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,11 +150,6 @@ set(STLINK_SOURCE src/flash_loader.c ) -set(STLINK_MANPAGES - doc/man/st-util.1 -) - - if (WIN32 OR MSYS OR MINGW) set (STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") # TODO endif () @@ -218,19 +213,6 @@ install(TARGETS ${PROJECT_NAME} ${STLINK_LIB_STATIC} st-flash st-util st-info ARCHIVE DESTINATION lib/${CMAKE_LIBRARY_PATH} LIBRARY DESTINATION lib/${CMAKE_LIBRARY_PATH} ) -# Now, install the development headers -file(GLOB STLINK_HEADERS - "${CMAKE_SOURCE_DIR}/include/stlink/*.h" -) - -install(FILES ${CMAKE_SOURCE_DIR}/include/stlink.h - DESTINATION include/${CMAKE_LIBRARY_PATH}/stlink-${STLINK_PACKAGE_VERSION}/) - -install(FILES ${STLINK_HEADERS} - DESTINATION include/${CMAKE_LIBRARY_PATH}/stlink-${STLINK_PACKAGE_VERSION}/stlink) - -install(FILES ${STLINK_MANPAGES} - DESTINATION share/man/man1) if (NOT APPLE AND NOT WIN32) set(PKG_CONFIG_LIBDIR @@ -283,6 +265,8 @@ if (NOT APPLE AND gtk_FOUND) DESTINATION ${INSTALLED_UI_DIR}) endif() +add_subdirectory(include) +add_subdirectory(doc/man) add_subdirectory(tests) set (CPACK_PACKAGE_NAME ${PROJECT_NAME}) diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..d93c4b181 --- /dev/null +++ b/Makefile @@ -0,0 +1,45 @@ +## +# This Makefile is used to drive building of Debug and Release +# targets of CMake +## +MAKEFLAGS += -s + +all: debug +ci: lint debug release test + +help: + @echo " release: Run a release build" + @echo " debug: Run a debug build" + @echo " lint: Lint check all source-code" + @echo " test: Build and run tests" + @echo " clean: Clean all build output" + @echo "rebuild_cache: Rebuild all CMake caches" + +rebuild_cache: build/Debug build/Release + @$(MAKE) -C build/Debug rebuild_cache + @$(MAKE) -C build/Release rebuild_cache + +debug: build/Debug + @echo "[DEBUG]" + @$(MAKE) -C build/Debug + +release: build/Release + @echo "[RELEASE]" + @$(MAKE) -C build/Release + +test: build/Debug + @$(MAKE) -C build/Debug test + +build/Debug: + @mkdir -p $@ + @cd $@ && cmake -DCMAKE_BUILD_TYPE=Debug ../../ + +build/Release: + @mkdir -p $@ + @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release ../../ + +clean: + @echo "[CLEAN]" + @rm -Rf build + +.PHONY: clean diff --git a/cmake/modules/pandocology.cmake b/cmake/modules/pandocology.cmake new file mode 100644 index 000000000..2a49cf573 --- /dev/null +++ b/cmake/modules/pandocology.cmake @@ -0,0 +1,373 @@ +################################################################################ +## +## Provide Pandoc compilation support for the CMake build system +## +## Version: 0.0.1-dirty +## Author: Jeet Sukumatan (jeetsukumaran@gmail.com) +## Jerry Jacobs (jerry.jacobs@xor-gate.org) +## +## Copyright 2015 Jeet Sukumaran. +## Copyright 2016 Jerry Jacobs +## +## This software is released under the BSD 3-Clause License. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## +## 1. Redistributions of source code must retain the above copyright notice, +## this list of conditions and the following disclaimer. +## +## 2. Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## +## 3. Neither the name of the copyright holder nor the names of its +## contributors may be used to endorse or promote products derived from this +## software without specific prior written permission. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +## IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +## LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +## NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +## SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## +################################################################################ + +include(CMakeParseArguments) + +if(NOT EXISTS ${PANDOC_EXECUTABLE}) + #find_program(PANDOC_EXECUTABLE pandoc) + #mark_as_advanced(PANDOC_EXECUTABLE) +endif() + +############################################################################### +# Based on code from UseLATEX +# Author: Kenneth Moreland +# Copyright 2004 Sandia Corporation. +# Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive +# license for use of this work by or on behalf of the +# U.S. Government. Redistribution and use in source and binary forms, with +# or without modification, are permitted provided that this Notice and any +# statement of authorship are reproduced on all copies. + +# Adds command to copy file from the source directory to the destination +# directory: used to move source files from source directory into build +# directory before main build +function(pandocology_add_input_file source_path dest_dir dest_filelist_var) + set(dest_filelist) + file(GLOB globbed_source_paths "${source_path}") + foreach(globbed_source_path ${globbed_source_paths}) + # MESSAGE(FATAL_ERROR "${globbed_source_path}") + get_filename_component(filename ${globbed_source_path} NAME) + get_filename_component(absolute_dest_path ${dest_dir}/${filename} ABSOLUTE) + file(RELATIVE_PATH relative_dest_path ${CMAKE_CURRENT_BINARY_DIR} ${absolute_dest_path}) + list(APPEND dest_filelist ${absolute_dest_path}) + ADD_CUSTOM_COMMAND( + OUTPUT ${relative_dest_path} + COMMAND ${CMAKE_COMMAND} -E copy ${globbed_source_path} ${dest_dir}/${filename} + DEPENDS ${globbed_source_path} + ) + set(${dest_filelist_var} ${${dest_filelist_var}} ${dest_filelist} PARENT_SCOPE) + endforeach() +endfunction() + +# A version of GET_FILENAME_COMPONENT that treats extensions after the last +# period rather than the first. +function(pandocology_get_file_stemname varname filename) + SET(result) + GET_FILENAME_COMPONENT(name ${filename} NAME) + STRING(REGEX REPLACE "\\.[^.]*\$" "" result "${name}") + SET(${varname} "${result}" PARENT_SCOPE) +endfunction() + +function(pandocology_get_file_extension varname filename) + SET(result) + GET_FILENAME_COMPONENT(name ${filename} NAME) + STRING(REGEX MATCH "\\.[^.]*\$" result "${name}") + SET(${varname} "${result}" PARENT_SCOPE) +endfunction() +############################################################################### + +function(pandocology_add_input_dir source_dir dest_parent_dir dir_dest_filelist_var) + set(dir_dest_filelist) + get_filename_component(dir_name ${source_dir} NAME) + get_filename_component(absolute_dest_dir ${dest_parent_dir}/${dir_name} ABSOLUTE) + file(RELATIVE_PATH relative_dest_dir ${CMAKE_CURRENT_BINARY_DIR} ${absolute_dest_dir}) + add_custom_command( + OUTPUT ${relative_dest_dir} + COMMAND ${CMAKE_COMMAND} -E make_directory ${absolute_dest_dir} + DEPENDS ${source_dir} + ) + file(GLOB source_files "${source_dir}/*") + foreach(source_file ${source_files}) + # get_filename_component(absolute_source_path ${CMAKE_CURRENT_SOURCE_DIR}/${source_file} ABSOLUTE) + pandocology_add_input_file(${source_file} ${absolute_dest_dir} dir_dest_filelist) + endforeach() + set(${dir_dest_filelist_var} ${${dir_dest_filelist_var}} ${dir_dest_filelist} PARENT_SCOPE) +endfunction() + +function(add_to_make_clean filepath) + get_directory_property(make_clean_files ADDITIONAL_MAKE_CLEAN_FILES) + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${make_clean_files};${filepath}") +endfunction() + +function(disable_insource_build) + IF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE ) + MESSAGE(FATAL_ERROR "The build directory must be different from the main project source " +"directory. Please create a directory such as '${CMAKE_SOURCE_DIR}/build', " +"and run CMake from there, passing the path to this source directory as " +"the path argument. E.g.: + $ cd ${CMAKE_SOURCE_DIR} + $ mkdir build + $ cd build + $ cmake .. && make && sudo make install +This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. +Please delete them: + $ rm -r CMakeFiles/ CmakeCache.txt +") + ENDIF() +endfunction() + +# This builds a document +# +# Usage: +# +# +# INCLUDE(pandocology) +# +# add_document( +# figures.tex +# SOURCES figures.md +# RESOURCE_DIRS figs +# PANDOC_DIRECTIVES -t latex +# NO_EXPORT_PRODUCT +# ) +# +# add_document( +# opus.pdf +# SOURCES opus.md +# RESOURCE_FILES opus.bib systbiol.template.latex systematic-biology.csl +# RESOURCE_DIRS figs +# PANDOC_DIRECTIVES -t latex +# --smart +# --template systbiol.template.latex +# --filter pandoc-citeproc +# --csl systematic-biology.csl +# --bibliography opus.bib +# --include-after-body=figures.tex +# DEPENDS figures.tex +# EXPORT_ARCHIVE +# ) +# +function(add_document target_name) + if (NOT PANDOC_EXECUTABLE) + message(WARNING "Pandoc not found. Install Pandoc (http://johnmacfarlane.net/pandoc/) or set cache variable PANDOC_EXECUTABLE.") + return() + endif() + + set(options EXPORT_ARCHIVE NO_EXPORT_PRODUCT EXPORT_PDF DIRECT_TEX_TO_PDF VERBOSE) + set(oneValueArgs PRODUCT_DIRECTORY) + set(multiValueArgs SOURCES RESOURCE_FILES RESOURCE_DIRS PANDOC_DIRECTIVES DEPENDS) + cmake_parse_arguments(ADD_DOCUMENT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + + # this is because `make clean` will dangerously clean up source files + disable_insource_build() + + # get the stem of the target name + pandocology_get_file_stemname(target_stemname ${target_name}) + pandocology_get_file_extension(target_extension ${target_name}) + if (${ADD_DOCUMENT_EXPORT_PDF}) + if (NOT "${target_extension}" STREQUAL ".tex" AND NOT "${target_extension}" STREQUAL ".latex") + # if (NOT "${target_extension}" STREQUAL ".tex") + MESSAGE(FATAL_ERROR "Target '${target_name}': Cannot use 'EXPORT_PDF' for target of type '${target_extension}': target type must be '.tex' or '.latex'") + endif() + endif() + if (${ADD_DOCUMENT_DIRECT_TEX_TO_PDF}) + list(LENGTH ${ADD_DOCUMENT_SOURCES} SOURCE_LEN) + if (SOURCE_LEN GREATER 1) + MESSAGE(FATAL_ERROR "Target '${target_name}': Only one source can be specified when using the 'DIRECT_TEX_TO_PDF' option") + endif() + # set(ADD_DOCUMENT_SOURCES, list(GET ${ADD_DOCUMENT_SOURCES} 1)) + pandocology_get_file_stemname(source_stemname ${ADD_DOCUMENT_SOURCES}) + pandocology_get_file_extension(source_extension ${ADD_DOCUMENT_SOURCES}) + if (NOT "${source_extension}" STREQUAL ".tex" AND NOT "${source_extension}" STREQUAL ".latex") + MESSAGE(FATAL_ERROR "Target '${target_name}': Cannot use 'DIRECT_TEX_TO_PDF' for source of type '${source_extension}': source type must be '.tex' or '.latex'") + endif() + SET(check_target ${source_stemname}.pdf) + IF (NOT ${check_target} STREQUAL ${target_name}) + MESSAGE(FATAL_ERROR "Target '${target_name}': Must use target name of '${check_target}' if using 'DIRECT_TEX_TO_PDF'") + endif() + endif() + + ## set up output directory + if ("${ADD_DOCUMENT_PRODUCT_DIRECTORY}" STREQUAL "") + set(ADD_DOCUMENT_PRODUCT_DIRECTORY "product") + endif() + get_filename_component(product_directory ${CMAKE_BINARY_DIR}/${ADD_DOCUMENT_PRODUCT_DIRECTORY} ABSOLUTE) + # get_filename_component(absolute_product_path ${product_directory}/${target_name} ABSOLUTE) + + ## get primary source + set(build_sources) + foreach(input_file ${ADD_DOCUMENT_SOURCES} ) + pandocology_add_input_file(${CMAKE_CURRENT_SOURCE_DIR}/${input_file} ${CMAKE_CURRENT_BINARY_DIR} build_sources) + endforeach() + + ## get resource files + set(build_resources) + foreach(resource_file ${ADD_DOCUMENT_RESOURCE_FILES}) + pandocology_add_input_file(${CMAKE_CURRENT_SOURCE_DIR}/${resource_file} ${CMAKE_CURRENT_BINARY_DIR} build_resources) + endforeach() + + ## get resource dirs + set(exported_resources) + foreach(resource_dir ${ADD_DOCUMENT_RESOURCE_DIRS}) + pandocology_add_input_dir(${CMAKE_CURRENT_SOURCE_DIR}/${resource_dir} ${CMAKE_CURRENT_BINARY_DIR} build_resources) + if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) + pandocology_add_input_dir(${CMAKE_CURRENT_SOURCE_DIR}/${resource_dir} ${product_directory} exported_resources) + endif() + endforeach() + + ## primary command + if (${ADD_DOCUMENT_DIRECT_TEX_TO_PDF}) + if (${ADD_DOCUMENT_VERBOSE}) + add_custom_command( + OUTPUT ${target_name} # note that this is in the build directory + DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS} + # WORKING_DIRECTORY ${working_directory} + COMMAND ${CMAKE_COMMAND} -E make_directory ${product_directory} + # we produce the target in the source directory, in case other build targets require it as a source + COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${build_sources} + ) + else() + add_custom_command( + OUTPUT ${target_name} # note that this is in the build directory + DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS} + # WORKING_DIRECTORY ${working_directory} + COMMAND ${CMAKE_COMMAND} -E make_directory ${product_directory} + # we produce the target in the source directory, in case other build targets require it as a source + COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${build_sources} 2>/dev/null >/dev/null || (grep --no-messages -A8 ".*:[0-9]*:.*" ${target_stemname}.log && false) + ) + endif() + add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_name}) + else() + add_custom_command( + OUTPUT ${target_name} # note that this is in the build directory + DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS} + # WORKING_DIRECTORY ${working_directory} + COMMAND ${CMAKE_COMMAND} -E make_directory ${product_directory} + # we produce the target in the source directory, in case other build targets require it as a source + COMMAND ${PANDOC_EXECUTABLE} ${build_sources} ${ADD_DOCUMENT_PANDOC_DIRECTIVES} -o ${target_name} + ) + add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_name}) + endif() + + ## figure out what all is going to be produced by this build set, and set + ## those as dependencies of the primary target + set(primary_target_dependencies) + set(primary_target_dependencies ${primary_target_dependencies} ${CMAKE_CURRENT_BINARY_DIR}/${target_name}) + if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT}) + set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_name}) + endif() + if (${ADD_DOCUMENT_EXPORT_PDF}) + set(primary_target_dependencies ${primary_target_dependencies} ${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf) + set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_stemname}.pdf) + endif() + if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) + set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_stemname}.tbz) + endif() + + ## primary target + # # target cannot have same (absolute name) as dependencies: + # # http://www.cmake.org/pipermail/cmake/2011-March/043378.html + add_custom_target( + ${target_name} + ALL + DEPENDS ${primary_target_dependencies} ${ADD_DOCUMENT_DEPENDS} + ) + + # run post-pdf + if (${ADD_DOCUMENT_EXPORT_PDF}) + # get_filename_component(target_stemname ${target_name} NAME_WE) + add_custom_command( + OUTPUT ${product_directory}/${target_stemname}.pdf ${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf + DEPENDS ${target_name} ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS} + + # Does not work: custom template used to generate tex is ignored + # COMMAND ${PANDOC_EXECUTABLE} ${target_name} -f latex -o ${target_stemname}.pdf + + # (1) Apparently, both nonstopmode and batchmode produce an output file + # even if there was an error. This tricks latexmk into believing + # the file is actually up-to-date. + # So we use `-halt-on-error` or `-interaction=errorstopmode` + # instead. + # (2) `grep` returns a non-zero error code if the pattern is not + # found. So, in our scheme below to filter the output of + # `pdflatex`, it is precisely when there is NO error that + # grep returns a non-zero code, which fools CMake into thinking + # tex'ing failed. + # Hence the need for `| grep ...| cat` or `| grep || true`. + # But we can go better: + # latexmk .. || (grep .. && false) + # So we can have our cake and eat it too: here we want to + # re-raise the error after a successful grep if there was an + # error in `latexmk`. + # COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${target_name} 2>&1 | grep -A8 ".*:[0-9]*:.*" || true + COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${target_name} 2>/dev/null >/dev/null || (grep --no-messages -A8 ".*:[0-9]*:.*" ${target_stemname}.log && false) + + COMMAND ${CMAKE_COMMAND} -E copy ${target_stemname}.pdf ${product_directory} + ) + add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf) + add_to_make_clean(${product_directory}/${target_stemname}.pdf) + endif() + + ## copy products + if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT}) + add_custom_command( + OUTPUT ${product_directory}/${target_name} + DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS} + COMMAND ${CMAKE_COMMAND} -E copy ${target_name} ${product_directory} + ) + add_to_make_clean(${product_directory}/${target_name}) + endif() + + ## copy resources + if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) + # get_filename_component(target_stemname ${target_name} NAME_WE) + # add_custom_command( + # TARGET ${target_name} POST_BUILD + # DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS} + # # COMMAND cp ${build_resources} ${ADD_DOCUMENT_DEPENDS} ${product_directory} + # COMMAND ${CMAKE_COMMAND} -E tar cjf ${product_directory}/${target_stemname}.tbz ${target_name} ${build_resources} ${ADD_DOCUMENT_DEPENDS} + # ) + add_custom_command( + OUTPUT ${product_directory}/${target_stemname}.tbz + DEPENDS ${target_name} + # COMMAND cp ${build_resources} ${ADD_DOCUMENT_DEPENDS} ${product_directory} + COMMAND ${CMAKE_COMMAND} -E tar cjf ${product_directory}/${target_stemname}.tbz ${target_name} ${build_resources} ${ADD_DOCUMENT_DEPENDS} + ) + add_to_make_clean(${product_directory}/${target_stemname}.tbz) + # add_custom_target( + # ${target_stemname}.ARCHIVE + # ALL + # DEPENDS ${product_directory}/${target_stemname}.tbz + # ) + endif() + +endfunction(add_document) + +function(add_tex_document) + add_document(${ARGV} DIRECT_TEX_TO_PDF) +endfunction() + +# LEGACY SUPPORT +function(add_pandoc_document) + add_document(${ARGV}) +endfunction() + diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt new file mode 100644 index 000000000..956b76af7 --- /dev/null +++ b/doc/man/CMakeLists.txt @@ -0,0 +1,28 @@ +set(MANPAGES + st-util +) + +# Only generate manpages with pandoc in Debug builds +if(${CMAKE_BUILD_TYPE} MATCHES "Debug") + include(pandocology) + + foreach(manpage ${MANPAGES}) + add_document( + ${manpage}.1 + SOURCES ${manpage}.md + PANDOC_DIRECTIVES -s -t man + PRODUCT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1 + DESTINATION share/man/man1 + ) + endforeach() +else() + # TODO(xor-gate): we should generate a install list for Release and Debug targets + foreach(manpage ${MANPAGES}) + install(FILES ${manpage}.1 + DESTINATION share/man/man1 + ) + endforeach() +endif() diff --git a/doc/man/Makefile b/doc/man/Makefile deleted file mode 100644 index 8871c6331..000000000 --- a/doc/man/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -MAN1 = -MAN1 += st-util.md - -all: $(patsubst %.md, %.1, $(MAN1)) - -%.1: %.md - pandoc -s -t man $< -o $@ - tail --line=+3 $@ > tmp && mv tmp $@ - -clean: - rm *.1 diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt new file mode 100644 index 000000000..5f603df8c --- /dev/null +++ b/include/CMakeLists.txt @@ -0,0 +1,8 @@ +file(GLOB STLINK_HEADERS + "stlink/*.h" +) + +install(FILES ${CMAKE_SOURCE_DIR}/include/stlink.h + DESTINATION include/${CMAKE_LIBRARY_PATH}) +install(FILES ${STLINK_HEADERS} + DESTINATION include/${CMAKE_LIBRARY_PATH}/stlink) From 10f965e45dbf87cc4d9d81320ab9c871055214bf Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 15 Sep 2016 10:46:13 +0200 Subject: [PATCH 0481/1435] cmake/modules/pandocology.cmake: Uncomment search of pandoc, due to previous local testing --- cmake/modules/pandocology.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/pandocology.cmake b/cmake/modules/pandocology.cmake index 2a49cf573..f39f8d952 100644 --- a/cmake/modules/pandocology.cmake +++ b/cmake/modules/pandocology.cmake @@ -43,8 +43,8 @@ include(CMakeParseArguments) if(NOT EXISTS ${PANDOC_EXECUTABLE}) - #find_program(PANDOC_EXECUTABLE pandoc) - #mark_as_advanced(PANDOC_EXECUTABLE) + find_program(PANDOC_EXECUTABLE pandoc) + mark_as_advanced(PANDOC_EXECUTABLE) endif() ############################################################################### From c42de25204b886da7e9c8758cab56a79c4afb62e Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 15 Sep 2016 14:55:18 +0200 Subject: [PATCH 0482/1435] cmake: Fix building with MinGw64 --- CMakeLists.txt | 3 +-- cmake/modules/FindLibUSB.cmake | 5 ++++- scripts/mingw64-build.bat | 10 +--------- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a75bf2219..f4d7ef552 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 2.8.7) project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics Stlink Tools") -project(stlink C) include(CheckCCompilerFlag) include(CheckIncludeFile) find_package(PkgConfig) @@ -108,7 +107,7 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") endif () add_cflag_if_supported("-Wundef") -if (NOT MSYS OR MINGW) +if (NOT WIN32) add_cflag_if_supported("-fPIC") endif () diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index 3b15339e4..006ab6976 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -6,7 +6,7 @@ # LIBUSB_LIBRARY - The libraries needed to use libusb # LIBUSB_DEFINITIONS - Compiler switches required for using libusb -if(WIN32 OR CMAKE_VS_PLATFORM_NAME) +if(WIN32 OR CMAKE_VS_PLATFORM_NAME OR MINGW OR MSYS) set(LIBUSB_WIN_VERSION 1.0.20) set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) @@ -21,6 +21,7 @@ if(WIN32 OR CMAKE_VS_PLATFORM_NAME) ${LIBUSB_WIN_ARCHIVE_PATH} ) endif() + file(MAKE_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) execute_process(COMMAND ${ZIP_LOCATION} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER}) endif() @@ -45,6 +46,8 @@ message(STATUS "LIBUSB_INCLUDE_DIR: ${LIBUSB_INCLUDE_DIR}") if (APPLE) set(LIBUSB_NAME libusb-1.0.a) +elseif(MSYS OR MINGW) + set(LIBUSB_NAME usb-1.0) elseif(WIN32 OR CMAKE_VS_PLATFORM_NAME) set(LIBUSB_NAME libusb-1.0.lib) elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") diff --git a/scripts/mingw64-build.bat b/scripts/mingw64-build.bat index 18397f0e0..52c6fffb1 100644 --- a/scripts/mingw64-build.bat +++ b/scripts/mingw64-build.bat @@ -1,12 +1,4 @@ -### -# MinGW64 build helper for windows -# * Sets the correct PATH to compiler and tools -# * Generates MinGW Makefile with CMake -# * Build binaries with mingw32-make -# -# Read documentation about this file in doc/build_mingw.md -### @echo off set PATH=C:\Program Files (x86)\CMake\bin;C:\Program Files\CMake\bin;C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin;%PATH% cmake -G "MinGW Makefiles" .. -mingw32-make +mingw32-make \ No newline at end of file From 3b47efcb011af415666faf72798c2b3f97f40648 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 15 Sep 2016 15:05:00 +0200 Subject: [PATCH 0483/1435] cmake: WIN32: Fix linking with winsock --- CMakeLists.txt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f4d7ef552..9195e3345 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,7 +188,12 @@ if (APPLE) target_link_libraries(${PROJECT_NAME} ${CoreFoundation} ${IOKit} ${ObjC}) endif () -target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARY}) +if(WIN32 OR MSYS OR MINGW) + target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARY} wsock32 ws2_32) +else() + target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARY}) +endif() + add_executable(st-flash src/tools/flash.c src/tools/flash_opts.c) target_link_libraries(st-flash ${PROJECT_NAME}) @@ -201,11 +206,8 @@ add_executable(st-util src/gdbserver/gdb-remote.c src/gdbserver/gdb-server.h src/gdbserver/semihosting.c src/gdbserver/semihosting.h) -if (WIN32 OR MSYS OR MINGW) - target_link_libraries(st-util ${PROJECT_NAME} wsock32 ws2_32) -else () - target_link_libraries(st-util ${PROJECT_NAME}) -endif () + +target_link_libraries(st-util ${PROJECT_NAME}) install(TARGETS ${PROJECT_NAME} ${STLINK_LIB_STATIC} st-flash st-util st-info RUNTIME DESTINATION bin From c6fb84884c17a622ddc386d6a6cc4dda04d3a5d9 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 15 Sep 2016 15:20:51 +0200 Subject: [PATCH 0484/1435] appveyor: Cache libusb 7z archive between builds --- .appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.appveyor.yml b/.appveyor.yml index 9e53a07bc..0aa97effc 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -8,6 +8,7 @@ environment: cache: - i686-4.9.2-release-win32-sjlj-rt_v3-rev1.7z - x86_64-4.9.2-release-win32-seh-rt_v3-rev1.7z + - libusb-*.7z build_script: - ps: | mkdir build From 07f181c7f8998e3458dad67287aa13e9869ac60b Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 15 Sep 2016 15:25:28 +0200 Subject: [PATCH 0485/1435] appveyor: Cache libusb-1.0.20.7z instead of non-allowed wildcard --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index 0aa97effc..10c0e935a 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -8,7 +8,7 @@ environment: cache: - i686-4.9.2-release-win32-sjlj-rt_v3-rev1.7z - x86_64-4.9.2-release-win32-seh-rt_v3-rev1.7z - - libusb-*.7z + - libusb-1.0.20.7z build_script: - ps: | mkdir build From 408632ad6c010aad50262500f0306613063e17e9 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 15 Sep 2016 15:26:37 +0200 Subject: [PATCH 0486/1435] Update README.md Add appveyor MinGW64 build badge from xor-gate/stlink --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3671fbf3f..a63955235 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ Open source version of the STMicroelectronics Stlink Tools [![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.2.0.svg?maxAge=2592000)](https://github.com/texane/stlink/compare/1.2.0...master) [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) [![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/stlink) +[![Build status](https://ci.appveyor.com/api/projects/status/wrcie05d4jmut0te?svg=true)](https://ci.appveyor.com/project/xor-gate/stlink) [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) ## HOWTO From c4d7e50c6d76c447c003c8b33bc246a9ad51bcd7 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 15 Sep 2016 15:37:43 +0200 Subject: [PATCH 0487/1435] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a63955235..2846a53d4 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Open source version of the STMicroelectronics Stlink Tools [![GitHub release](https://img.shields.io/github/release/texane/stlink.svg?maxAge=2592000)](https://github.com/texane/stlink/releases/latest) [![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.2.0.svg?maxAge=2592000)](https://github.com/texane/stlink/compare/1.2.0...master) [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) -[![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/stlink) +[![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/job/stlink/) [![Build status](https://ci.appveyor.com/api/projects/status/wrcie05d4jmut0te?svg=true)](https://ci.appveyor.com/project/xor-gate/stlink) [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) From 3268ea1250da16d682704ab2e3b9f9fef4f625bb Mon Sep 17 00:00:00 2001 From: "Daniel Campoverde [alx741]" Date: Thu, 15 Sep 2016 18:18:27 -0500 Subject: [PATCH 0488/1435] Add st-flash man page --- doc/man/CMakeLists.txt | 1 + doc/man/st-flash.md | 70 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 doc/man/st-flash.md diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 956b76af7..baf482ea8 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -1,5 +1,6 @@ set(MANPAGES st-util + st-flash ) # Only generate manpages with pandoc in Debug builds diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md new file mode 100644 index 000000000..88ba5870a --- /dev/null +++ b/doc/man/st-flash.md @@ -0,0 +1,70 @@ +% ST-FLASH(1) Open Source STMicroelectronics Stlink Tools | STLINK +% +% Sep 2016 + + +# NAME +st-flash - Flash binary files to STM32 device + + +# SYNOPSIS +*st-flash* \[*OPTIONS*\] \{read|write|erase\} \[*FILE*\] \ \ + + +# DESCRIPTION +Flash binary files to arbitrary sections of memory, or read arbitrary addresses +of memory out to a binary file. + +You can use this instead of st-util(1) if you prefer, but remember to use the +**.bin** image, rather than the **.elf** file. + +Use hexadecimal format for the *ADDR* and *SIZE*. + + +# COMMANDS + +write *FILE* *ADDR* +: Write firmware *FILE* to device starting from *ADDR* + +read *FILE* *ADDR* *SIZE* +: Read firmware from device starting from *ADDR* up to *SIZE* bytes to *FILE* + +erase +: Perform a mass erasing of the device firmware + + +# OPTIONS + +--debug +: TODO + +--reset +: TODO + +--serial *iSerial* +: TODO + + +# EXAMPLES +Flash `firmware.bin` to device + + $ st-flash write firmware.bin 0x8000000 + + +Read firmware from device (4096 bytes) + + $ st-flash read firmware.bin 0x8000000 4096 + + +Erase firmware from device + + $ st-flash erase + + +# SEE ALSO +st-util(1), st-info(1), st-term(1) + + +# COPYRIGHT +This work is copyrighted. Stlink contributors. +See *LICENSE* file in the stlink source distribution. From 759f423987b89610546f55bb053db4c30c600543 Mon Sep 17 00:00:00 2001 From: "Daniel Campoverde [alx741]" Date: Thu, 15 Sep 2016 18:18:45 -0500 Subject: [PATCH 0489/1435] Add st-info man page --- doc/man/CMakeLists.txt | 1 + doc/man/st-info.md | 58 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 doc/man/st-info.md diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index baf482ea8..795b6fa8d 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -1,6 +1,7 @@ set(MANPAGES st-util st-flash + st-info ) # Only generate manpages with pandoc in Debug builds diff --git a/doc/man/st-info.md b/doc/man/st-info.md new file mode 100644 index 000000000..9cc48e9f1 --- /dev/null +++ b/doc/man/st-info.md @@ -0,0 +1,58 @@ +% ST-INFO(1) Open Source STMicroelectronics Stlink Tools | STLINK +% +% Sep 2016 + + +# NAME +st-info - Provides information about connected STLINK and STM32 devices + + +# SYNOPSIS +*st-info* \[*OPTIONS*\] + + +# DESCRIPTION +Provides information about connected STLINK programmers and STM32 devices: +Serial code, openocd, flash, sram, page size, chipid, description. + + +# OPTIONS + +--flash +: Display amount of flash memory available in the device + +--sram +: Display amount of sram memory available in device + +--descr +: Display textual description of the device + +--pagesize +: Display the page size of the device + +--chipid +: Display the chip ID of the device + +--serial +: Display the serial code of the device + +--hla-serial +: Display the hex escaped serial code of the device + +--probe +: Display the summarized information of the connected programmers and devices + + +# EXAMPLES +Display information about connected programmers and devices + + $ st-info --probe + + +# SEE ALSO +st-util(1), st-flash(1), st-term(1) + + +# COPYRIGHT +This work is copyrighted. Stlink contributors. +See *LICENSE* file in the stlink source distribution. From 3c28cf15a79b50d273fa8147b93eb7c09c770f0b Mon Sep 17 00:00:00 2001 From: "Daniel Campoverde [alx741]" Date: Thu, 15 Sep 2016 18:52:58 -0500 Subject: [PATCH 0490/1435] Add st-term man page --- doc/man/CMakeLists.txt | 1 + doc/man/st-term.md | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 doc/man/st-term.md diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 795b6fa8d..96e1734d8 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -2,6 +2,7 @@ set(MANPAGES st-util st-flash st-info + st-term ) # Only generate manpages with pandoc in Debug builds diff --git a/doc/man/st-term.md b/doc/man/st-term.md new file mode 100644 index 000000000..e9b635e5c --- /dev/null +++ b/doc/man/st-term.md @@ -0,0 +1,36 @@ +% ST-TERM(1) Open Source STMicroelectronics Stlink Tools | STLINK +% +% Sep 2016 + + +# NAME +st-term - Serial terminal interface for debugging using STLink device only + + +# SYNOPSIS +*st-term* + + +# DESCRIPTION +Provides a serial terminal that works through the STLink device, allowing to do +the kind of debugging you would do using the UART of the STM32 device without +having to connect a UART-USB serial adapter dongle. + +It works by having a magic number in sram of the MCU within a structure that +serves as IO buffer. + +The required setup consist of some code that establishes the magic number, +buffer structure and helper functions for actual data transmission between host +and MCU. + +`stlinky.h` and `stlinky.c` are available in the Antares build system libraries +source: https://github.com/nekromant/antares/tree/master/include/lib + + +# SEE ALSO +st-util(1), st-info(1), st-term(1) + + +# COPYRIGHT +This work is copyrighted. Stlink contributors. +See *LICENSE* file in the stlink source distribution. From c23732c8329a244d7b083b3af771edd8143f4000 Mon Sep 17 00:00:00 2001 From: "Daniel Campoverde [alx741]" Date: Thu, 15 Sep 2016 18:53:10 -0500 Subject: [PATCH 0491/1435] Use 'STLink' in man pages --- doc/man/st-info.md | 4 ++-- doc/man/st-util.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/man/st-info.md b/doc/man/st-info.md index 9cc48e9f1..34192b9d6 100644 --- a/doc/man/st-info.md +++ b/doc/man/st-info.md @@ -4,7 +4,7 @@ # NAME -st-info - Provides information about connected STLINK and STM32 devices +st-info - Provides information about connected STLink and STM32 devices # SYNOPSIS @@ -12,7 +12,7 @@ st-info - Provides information about connected STLINK and STM32 devices # DESCRIPTION -Provides information about connected STLINK programmers and STM32 devices: +Provides information about connected STLink programmers and STM32 devices: Serial code, openocd, flash, sram, page size, chipid, description. diff --git a/doc/man/st-util.md b/doc/man/st-util.md index 8f015c806..2b68a56fd 100644 --- a/doc/man/st-util.md +++ b/doc/man/st-util.md @@ -20,7 +20,7 @@ default **4242** port will be used. Stlink version 2 is used by default unless the option **--stlinkv1** is given. -The STLINKv2 device to use can be specified in the environment +The STLinkV2 device to use can be specified in the environment variable STLINK_DEVICE on the format :. From 4209e4b924165dc46a8f6c0cf4338f4d321ee08b Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 15 Sep 2016 22:29:59 +0200 Subject: [PATCH 0492/1435] cmake: Refactor into seperate files, fix project version detection when everything fails (travis) --- .travis.sh | 4 +- .travis.yml | 4 +- CMakeLists.txt | 254 ++++-------------- cmake/CFlags.cmake | 49 ++++ cmake/CPackConfig.cmake | 11 + cmake/Version.cmake | 50 ++++ cmake/modules/Find7Zip.cmake | 8 +- cmake/modules/FindLibUSB.cmake | 2 + doc/man/CMakeLists.txt | 27 +- include/CMakeLists.txt | 12 +- include/stlink.h | 1 + include/stlink/version.h.in | 9 + src/gdbserver/CMakeLists.txt | 10 + src/gdbserver/gdb-server.c | 5 +- src/logging.c | 2 +- src/tools/flash.c | 2 + src/tools/gui/CMakeLists.txt | 24 ++ src/tools/info.c | 1 + usr/lib/pkgconfig/CMakeLists.txt | 14 + .../lib/pkgconfig/pkg-config.pc.cmake | 0 20 files changed, 268 insertions(+), 221 deletions(-) create mode 100644 cmake/CFlags.cmake create mode 100644 cmake/CPackConfig.cmake create mode 100644 cmake/Version.cmake create mode 100644 include/stlink/version.h.in create mode 100644 src/gdbserver/CMakeLists.txt create mode 100644 src/tools/gui/CMakeLists.txt create mode 100644 usr/lib/pkgconfig/CMakeLists.txt rename pkg-config.pc.cmake => usr/lib/pkgconfig/pkg-config.pc.cmake (100%) diff --git a/.travis.sh b/.travis.sh index 9fa519dad..82c1fd862 100755 --- a/.travis.sh +++ b/.travis.sh @@ -13,7 +13,7 @@ else fi echo "=== Building Debug" -mkdir -p build/Debug && cd build/Debug && cmake -DCMAKE_BUILD_TYPE=Debug ../../ && make && make package && cd - +mkdir -p build/Debug && cd build/Debug && cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ && make && make package && cd - echo "=== Building Release" -mkdir -p build/Release && cd build/Release && cmake -DCMAKE_BUILD_TYPE=Release ../../ && make && make package && cd - +mkdir -p build/Release && cd build/Release && cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ && make && make package && cd - diff --git a/.travis.yml b/.travis.yml index 543c0edec..2bf170d2b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,9 @@ addons: - g++-5 - gcc-5 script: + - git fetch --tags + - printenv + - cmake --version - ./.travis.sh matrix: include: @@ -20,7 +23,6 @@ matrix: # compiler: clang-3.8 - os: linux compiler: gcc-5 - compiler: gcc-5 # - os: linux # compiler: clang-3.8 - os: osx diff --git a/CMakeLists.txt b/CMakeLists.txt index 9195e3345..2d5a03170 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,9 +2,7 @@ cmake_minimum_required(VERSION 2.8.7) project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics Stlink Tools") -include(CheckCCompilerFlag) include(CheckIncludeFile) -find_package(PkgConfig) if (POLICY CMP0042) # Newer cmake on MacOS should use @rpath @@ -12,123 +10,30 @@ if (POLICY CMP0042) endif () set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") +include(cmake/Version.cmake) +include(cmake/CFlags.cmake) -message(STATUS "Building on ${CMAKE_SYSTEM_NAME}") - -# Determine package version. -find_package (Git QUIET) -if (DEFINED ENV{TRAVIS_TAG} AND NOT "$ENV{TRAVIS_TAG}" STREQUAL "") - set (STLINK_PACKAGE_VERSION "$ENV{TRAVIS_TAG}") -elseif (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") - # Working off a git repo, using git versioning - # Check if HEAD is pointing to a tag - execute_process ( - COMMAND "${GIT_EXECUTABLE}" describe --always - WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" - OUTPUT_VARIABLE STLINK_PACKAGE_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE) - - # If the sources have been changed locally, add -dirty to the version. - execute_process ( - COMMAND "${GIT_EXECUTABLE}" diff --quiet - WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" - RESULT_VARIABLE res) - - if (res EQUAL 1) - set (STLINK_PACKAGE_VERSION "${STLINK_PACKAGE_VERSION}-dirty") - endif() -elseif (EXISTS ${PROJECT_SOURCE_DIR}/.version) - # If git is not available (e.g. when building from source package) - # we can extract the package version from .version file. - file (STRINGS .version STLINK_PACKAGE_VERSION) -else () - set (STLINK_PACKAGE_VERSION "999.99.99-unknown") -endif() - -# We shall use STLINK_PACKAGE_VERSION* variables to set soversion and other stuff -# Since these numbers will appear in .so names, e.g. libstlink.so.1.2.0 -# We can't just use STLINK_PACKAGE_VERSION here -# (Well, we can, but that breaks all the existing conventions) -# We can't as well use PROJECT_VERSION* variables here, since they are managed -# by project() directive and the whole version detection relies on PROJECT_SOURCE_DIR - -string(REPLACE "." ";" STLINK_PACKAGE_VERSION_ARRAY ${STLINK_PACKAGE_VERSION}) -string(REPLACE "-" ";" STLINK_PACKAGE_VERSION_ARRAY "${STLINK_PACKAGE_VERSION_ARRAY}") -list(GET STLINK_PACKAGE_VERSION_ARRAY 0 STLINK_PACKAGE_VERSION_MAJOR) -list(GET STLINK_PACKAGE_VERSION_ARRAY 1 STLINK_PACKAGE_VERSION_MINOR) -list(GET STLINK_PACKAGE_VERSION_ARRAY 2 STLINK_PACKAGE_VERSION_PATCH) -list(GET STLINK_PACKAGE_VERSION_ARRAY 3 STLINK_PACKAGE_VERSION_TAG) - -if(WIN32) - find_package(7Zip REQUIRED) - message(STATUS "7Zip Location: " ${ZIP_LOCATION}) -endif() - +### +# Dependencies +### find_package(LibUSB REQUIRED) if (NOT APPLE AND NOT WIN32) find_package(PkgConfig) pkg_check_modules(gtk gtk+-3.0) endif () -function(add_cflag_if_supported flag) - string(REPLACE "-" "_" flagclean ${flag}) - string(REPLACE "=" "_" flagclean ${flagclean}) - string(REPLACE "+" "_" flagclean ${flagclean}) - string(REPLACE "," "_" flagclean ${flagclean}) - string(TOUPPER ${flagclean} flagclean) - - check_c_compiler_flag(${flag} C_SUPPORTS${flagclean}) - - if (C_SUPPORTS${flagclean}) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE) - endif() -endfunction() - -add_cflag_if_supported("-std=gnu99") -add_cflag_if_supported("-Wall") -add_cflag_if_supported("-Wextra") -add_cflag_if_supported("-Wshadow") -add_cflag_if_supported("-D_FORTIFY_SOURCE=2") -add_cflag_if_supported("-fstrict-aliasing") -add_cflag_if_supported("-Wformat") -add_cflag_if_supported("-Wformat-security") -add_cflag_if_supported("-Wmaybe-uninitialized") -add_cflag_if_supported("-Wmissing-variable-declarations") -add_cflag_if_supported("-Wshorten-64-to-32") -add_cflag_if_supported("-Wimplicit-function-declaration") - -## -# On OpenBSD the system headers suck so we need to disable redundant declaration check -# /usr/include/unistd.h:429: warning: redundant redeclaration of 'truncate' -# /usr/include/sys/types.h:218: warning: previous declaration of 'truncate' was here -## -if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") - add_cflag_if_supported("-Wredundant-decls") -endif () - -add_cflag_if_supported("-Wundef") -if (NOT WIN32) - add_cflag_if_supported("-fPIC") -endif () - -if (CMAKE_BUILD_TYPE STREQUAL "") - set (CMAKE_BUILD_TYPE "Debug") -endif () - -if(${CMAKE_BUILD_TYPE} MATCHES "Debug") - add_cflag_if_supported("-ggdb") - add_cflag_if_supported("-O0") - include(CTest) -elseif() - add_cflag_if_supported("-O2") -endif() - CHECK_INCLUDE_FILE(sys/mman.h STLINK_HAVE_SYS_MMAN_H) if (STLINK_HAVE_SYS_MMAN_H) add_definitions(-DSTLINK_HAVE_SYS_MMAN_H) endif() -message("Building ${PROJECT_NAME} ${STLINK_PACKAGE_VERSION}") +if (CMAKE_BUILD_TYPE STREQUAL "") + set(CMAKE_BUILD_TYPE "Debug") +endif() + +if (${CMAKE_BUILD_TYPE} MATCHES "Debug") + include(CTest) +endif() set(STLINK_HEADERS include/stlink.h @@ -155,31 +60,26 @@ endif () include_directories(${LIBUSB_INCLUDE_DIR}) include_directories(include) +include_directories(${PROJECT_BINARY_DIR}/include) include_directories(src/mingw) -set(STLINK_LIB_STATIC ${PROJECT_NAME}-static) - +# Shared library add_library(${PROJECT_NAME} SHARED - ${STLINK_HEADERS} # header files for ide projects generated by cmake - ${STLINK_SOURCE}) + ${STLINK_HEADERS} # header files for ide projects generated by cmake + ${STLINK_SOURCE} +) target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARY}) if (WIN32 OR MSYS OR MINGW) - set(STLINK_SHARED_VERSION - ${STLINK_PACKAGE_VERSION_MAJOR}.${STLINK_PACKAGE_VERSION_MINOR}) + set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}) else() - set(STLINK_SHARED_VERSION - ${STLINK_PACKAGE_VERSION_MAJOR}.${STLINK_PACKAGE_VERSION_MINOR}.${STLINK_PACKAGE_VERSION_PATCH}) + set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) endif() -set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION ${STLINK_PACKAGE_VERSION_MAJOR} -VERSION ${STLINK_SHARED_VERSION}) - -add_library(${STLINK_LIB_STATIC} STATIC - ${STLINK_HEADERS} # header files for ide projects generated by cmake - ${STLINK_SOURCE}) -target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY}) -set_target_properties(${STLINK_LIB_STATIC} PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) +set_target_properties(${PROJECT_NAME} + PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} + VERSION ${STLINK_SHARED_VERSION} +) if (APPLE) find_library(ObjC objc) @@ -194,91 +94,49 @@ else() target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARY}) endif() -add_executable(st-flash src/tools/flash.c src/tools/flash_opts.c) -target_link_libraries(st-flash ${PROJECT_NAME}) - -add_executable(st-info src/tools/info.c) -target_link_libraries(st-info ${PROJECT_NAME}) - -add_executable(st-util src/gdbserver/gdb-remote.c - src/gdbserver/gdb-remote.h - src/gdbserver/gdb-server.c - src/gdbserver/gdb-server.h - src/gdbserver/semihosting.c - src/gdbserver/semihosting.h) - -target_link_libraries(st-util ${PROJECT_NAME}) - -install(TARGETS ${PROJECT_NAME} ${STLINK_LIB_STATIC} st-flash st-util st-info - RUNTIME DESTINATION bin - ARCHIVE DESTINATION lib/${CMAKE_LIBRARY_PATH} - LIBRARY DESTINATION lib/${CMAKE_LIBRARY_PATH} +install(TARGETS ${PROJECT_NAME} + LIBRARY DESTINATION lib/${CMAKE_LIBRARY_PATH} ) -if (NOT APPLE AND NOT WIN32) - set(PKG_CONFIG_LIBDIR - "\${prefix}/lib/\${deb_host_multiarch}" - ) - set(PKG_CONFIG_INCLUDEDIR - "\${prefix}/include/\${deb_host_multiarch}/${PROJECT_NAME}-${STLINK_PACKAGE_VERSION}" - ) - set(PKG_CONFIG_LIBS - "-L\${libdir} -l:libstlink.so.${STLINK_PACKAGE_VERSION_MAJOR}" - ) - set(PKG_CONFIG_CFLAGS - "-I\${includedir}" - ) - - set(PKG_CONFIG_REQUIRES - "libusb-1.0" - ) +### +# Static library +### +set(STLINK_LIB_STATIC ${PROJECT_NAME}-static) - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" - ) +add_library(${STLINK_LIB_STATIC} STATIC + ${STLINK_HEADERS} # header files for ide projects generated by cmake + ${STLINK_SOURCE} +) +target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY}) +set_target_properties(${STLINK_LIB_STATIC} PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" - DESTINATION lib/${CMAKE_LIBRARY_PATH}/pkgconfig/) -endif() +install(TARGETS ${STLINK_LIB_STATIC} + ARCHIVE DESTINATION lib/${CMAKE_LIBRARY_PATH} +) -if (NOT APPLE AND gtk_FOUND) - include_directories(SYSTEM ${gtk_INCLUDE_DIRS}) - set(GUI_SOURCES src/tools/gui/stlink-gui.c - src/tools/gui/stlink-gui.h) +### +# Tools +### +add_executable(st-flash src/tools/flash.c src/tools/flash_opts.c) +target_link_libraries(st-flash ${PROJECT_NAME}) - # TODO REMOVE whole stlink-gui-local target, fixup auto-search of ui file in implementation - add_executable(stlink-gui-local ${GUI_SOURCES}) - set_target_properties(stlink-gui-local PROPERTIES - COMPILE_FLAGS -DSTLINK_UI_DIR=\\"${CMAKE_CURRENT_SOURCE_DIR}/gui\\") - target_link_libraries(stlink-gui-local stlink ${gtk_LDFLAGS}) +add_executable(st-info src/tools/info.c) +target_link_libraries(st-info ${PROJECT_NAME}) - set(INSTALLED_UI_DIR share/stlink) - add_executable(stlink-gui ${GUI_SOURCES}) - # TODO REMOVE, fixup auto-search of ui file in implementation - set_target_properties(stlink-gui PROPERTIES - COMPILE_FLAGS -DSTLINK_UI_DIR=\\"${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}\\") - target_link_libraries(stlink-gui stlink ${gtk_LDFLAGS}) +install(TARGETS st-flash st-info + RUNTIME DESTINATION bin +) - install(TARGETS stlink-gui - RUNTIME DESTINATION bin) - install(FILES src/tools/gui/stlink-gui.ui - DESTINATION ${INSTALLED_UI_DIR}) -endif() +add_subdirectory(src/gdbserver) +add_subdirectory(src/tools/gui) +### +# Others +### +add_subdirectory(usr/lib/pkgconfig) add_subdirectory(include) add_subdirectory(doc/man) add_subdirectory(tests) -set (CPACK_PACKAGE_NAME ${PROJECT_NAME}) -set (CPACK_PACKAGE_VERSION ${STLINK_PACKAGE_VERSION}) -set (CPACK_SOURCE_GENERATOR "TBZ2;ZIP") -set (CPACK_SOURCE_IGNORE_FILES "/build/;/.git/;~$;${CPACK_SOURCE_IGNORE_FILES}") -set (CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${STLINK_PACKAGE_VERSION}") -if (APPLE) - set(CPACK_GENERATOR "ZIP") - file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/osx") - set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/osx") -endif() -add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source) -include (CPack) +include(cmake/CPackConfig.cmake) +include(CPack) diff --git a/cmake/CFlags.cmake b/cmake/CFlags.cmake new file mode 100644 index 000000000..b17463707 --- /dev/null +++ b/cmake/CFlags.cmake @@ -0,0 +1,49 @@ +include(CheckCCompilerFlag) + +function(add_cflag_if_supported flag) + string(REPLACE "-" "_" flagclean ${flag}) + string(REPLACE "=" "_" flagclean ${flagclean}) + string(REPLACE "+" "_" flagclean ${flagclean}) + string(REPLACE "," "_" flagclean ${flagclean}) + string(TOUPPER ${flagclean} flagclean) + + check_c_compiler_flag(${flag} C_SUPPORTS${flagclean}) + + if (C_SUPPORTS${flagclean}) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE) + endif() +endfunction() + +add_cflag_if_supported("-std=gnu99") +add_cflag_if_supported("-Wall") +add_cflag_if_supported("-Wextra") +add_cflag_if_supported("-Wshadow") +add_cflag_if_supported("-D_FORTIFY_SOURCE=2") +add_cflag_if_supported("-fstrict-aliasing") +add_cflag_if_supported("-Wundef") +add_cflag_if_supported("-Wformat") +add_cflag_if_supported("-Wformat-security") +add_cflag_if_supported("-Wmaybe-uninitialized") +add_cflag_if_supported("-Wmissing-variable-declarations") +add_cflag_if_supported("-Wshorten-64-to-32") +add_cflag_if_supported("-Wimplicit-function-declaration") + +## +# On OpenBSD the system headers suck so we need to disable redundant declaration check +# /usr/include/unistd.h:429: warning: redundant redeclaration of 'truncate' +# /usr/include/sys/types.h:218: warning: previous declaration of 'truncate' was here +## +if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") + add_cflag_if_supported("-Wredundant-decls") +endif () + +if (NOT WIN32) + add_cflag_if_supported("-fPIC") +endif () + +if(${CMAKE_BUILD_TYPE} MATCHES "Debug") + add_cflag_if_supported("-ggdb") + add_cflag_if_supported("-O0") +elseif() + add_cflag_if_supported("-O2") +endif() diff --git a/cmake/CPackConfig.cmake b/cmake/CPackConfig.cmake new file mode 100644 index 000000000..4e851efae --- /dev/null +++ b/cmake/CPackConfig.cmake @@ -0,0 +1,11 @@ +set (CPACK_PACKAGE_NAME ${PROJECT_NAME}) +set (CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) +set (CPACK_SOURCE_GENERATOR "TBZ2;ZIP") +set (CPACK_SOURCE_IGNORE_FILES "/build/;/.git/;~$;${CPACK_SOURCE_IGNORE_FILES}") +set (CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}") +if (APPLE) + set(CPACK_GENERATOR "ZIP") + file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/osx") + set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/osx") +endif() +add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source) diff --git a/cmake/Version.cmake b/cmake/Version.cmake new file mode 100644 index 000000000..957e29ca4 --- /dev/null +++ b/cmake/Version.cmake @@ -0,0 +1,50 @@ +# Determine project version +# * Using Git +# * Local .version file +find_package (Git QUIET) +if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") + # Working off a git repo, using git versioning + # Check if HEAD is pointing to a tag + execute_process ( + COMMAND "${GIT_EXECUTABLE}" describe --always + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + OUTPUT_VARIABLE PROJECT_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + + # If the sources have been changed locally, add -dirty to the version. + execute_process ( + COMMAND "${GIT_EXECUTABLE}" diff --quiet + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + RESULT_VARIABLE res) + + if (res EQUAL 1) + set (PROJECT_VERSION "${PROJECT_VERSION}-dirty") + endif() +endif() + +string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" + "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) +list(LENGTH PROJECT_VERSION_LIST len) +if(len EQUAL 3) + list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) + list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) + list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) +elseif(EXISTS ${PROJECT_SOURCE_DIR}/.version) + # If git is not available (e.g. when building from source package) + # we can extract the package version from .version file. + file (STRINGS .version PROJECT_VERSION) + + # TODO create function to extract semver from file or string and check if it is correct instead of copy-pasting + string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" + "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) + list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) + list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) + list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) +else() + message(FATAL_ERROR "Unable to determine project version") +endif() + +if (${CMAKE_BUILD_TYPE} MATCHES "Debug") + message(STATUS "stlink version: ${PROJECT_VERSION}") + message(STATUS " Major ${PROJECT_VERSION_MAJOR} Minor ${PROJECT_VERSION_MINOR} Patch ${PROJECT_VERSION_PATCH}") +endif() diff --git a/cmake/modules/Find7Zip.cmake b/cmake/modules/Find7Zip.cmake index c264d12f7..3448a2856 100644 --- a/cmake/modules/Find7Zip.cmake +++ b/cmake/modules/Find7Zip.cmake @@ -1,5 +1,5 @@ -find_program(ZIP_LOCATION NAMES 7z.exe - HINTS - "C:\\Program Files\\7-Zip\\" - "C:\\Program Files (x86)\\7-Zip\\" +find_program(ZIP_EXECUTABLE NAMES 7z.exe + HINTS + "C:\\Program Files\\7-Zip\\" + "C:\\Program Files (x86)\\7-Zip\\" ) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index 006ab6976..90aafb3a2 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -7,6 +7,8 @@ # LIBUSB_DEFINITIONS - Compiler switches required for using libusb if(WIN32 OR CMAKE_VS_PLATFORM_NAME OR MINGW OR MSYS) + find_package(7Zip REQUIRED) + set(LIBUSB_WIN_VERSION 1.0.20) set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 96e1734d8..4ea25e797 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -16,16 +16,21 @@ if(${CMAKE_BUILD_TYPE} MATCHES "Debug") PANDOC_DIRECTIVES -s -t man PRODUCT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1 - DESTINATION share/man/man1 - ) - endforeach() -else() - # TODO(xor-gate): we should generate a install list for Release and Debug targets - foreach(manpage ${MANPAGES}) - install(FILES ${manpage}.1 - DESTINATION share/man/man1 - ) endforeach() endif() + +# Install from output folder or this folder +foreach(manpage ${MANPAGES}) + if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1) + set(f "${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1") + elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") + set(f "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") + else() + message(AUTHOR_WARNING "Manpage ${manpage} not generated") + endif() + + if (f) + install(FILES ${f} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1) + unset(f) + endif() +endforeach() diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 5f603df8c..0b5a443c0 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,8 +1,14 @@ +configure_file( + "${PROJECT_SOURCE_DIR}/include/stlink/version.h.in" + "${CMAKE_BINARY_DIR}/include/stlink/version.h" +) file(GLOB STLINK_HEADERS "stlink/*.h" + "${CMAKE_BINARY_DIR}/include/stlink/*.h" ) - install(FILES ${CMAKE_SOURCE_DIR}/include/stlink.h - DESTINATION include/${CMAKE_LIBRARY_PATH}) + DESTINATION include/${CMAKE_LIBRARY_PATH} +) install(FILES ${STLINK_HEADERS} - DESTINATION include/${CMAKE_LIBRARY_PATH}/stlink) + DESTINATION include/${CMAKE_LIBRARY_PATH}/stlink +) diff --git a/include/stlink.h b/include/stlink.h index 0f032614e..674aa3b28 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -212,6 +212,7 @@ typedef struct flash_loader { #include "stlink/commands.h" #include "stlink/chipid.h" #include "stlink/flash_loader.h" +#include "stlink/version.h" #ifdef __cplusplus } diff --git a/include/stlink/version.h.in b/include/stlink/version.h.in new file mode 100644 index 000000000..4ce2a5cac --- /dev/null +++ b/include/stlink/version.h.in @@ -0,0 +1,9 @@ +#ifndef STLINK_VERSION_H_ +#define STLINK_VERSION_H_ + +#define STLINK_VERSION "@PROJECT_VERSION@" +#define STLINK_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ +#define STLINK_VERSION_MINOR @PROJECT_VERSION_MINOR@ +#define STLINK_VERSION_PATCH @PROJECT_VERSION_PATCH@ + +#endif /* STLINK_VERSION_ */ diff --git a/src/gdbserver/CMakeLists.txt b/src/gdbserver/CMakeLists.txt new file mode 100644 index 000000000..c6114f6d6 --- /dev/null +++ b/src/gdbserver/CMakeLists.txt @@ -0,0 +1,10 @@ +add_executable(st-util gdb-remote.c + gdb-remote.h + gdb-server.c + gdb-server.h + semihosting.c + semihosting.h) +target_link_libraries(st-util ${PROJECT_NAME}) +install(TARGETS st-util + RUNTIME DESTINATION bin +) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 4d52d0cba..6015ed00b 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -176,12 +176,16 @@ int main(int argc, char** argv) { st_state_t state; memset(&state, 0, sizeof(state)); + + printf("st-util %s (%s)\n", STLINK_VERSION); + // set defaults... state.stlink_version = 2; state.logging_level = DEFAULT_LOGGING_LEVEL; state.listen_port = DEFAULT_GDB_LISTEN_PORT; state.reset = 1; /* By default, reset board */ parse_options(argc, argv, &state); + switch (state.stlink_version) { case 2: sl = stlink_open_usb(state.logging_level, state.reset, NULL); @@ -205,7 +209,6 @@ int main(int argc, char** argv) { ILOG("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); sl->verbose=0; - current_memory_map = make_memory_map(sl); #ifdef __MINGW32__ diff --git a/src/logging.c b/src/logging.c index 4969c4400..1f51900b5 100644 --- a/src/logging.c +++ b/src/logging.c @@ -11,7 +11,7 @@ #include "stlink/logging.h" -static int max_level; +static int max_level = UINFO; int ugly_init(int maximum_threshold) { max_level = maximum_threshold; diff --git a/src/tools/flash.c b/src/tools/flash.c index 2dde37d06..6ebfcc2fb 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -52,6 +52,8 @@ int main(int ac, char** av) return -1; } + printf("st-flash %s (%s)\n", STLINK_VERSION); + if (o.devname != NULL) /* stlinkv1 */ sl = stlink_v1_open(o.log_level, 1); else /* stlinkv2 */ diff --git a/src/tools/gui/CMakeLists.txt b/src/tools/gui/CMakeLists.txt new file mode 100644 index 000000000..e217af03a --- /dev/null +++ b/src/tools/gui/CMakeLists.txt @@ -0,0 +1,24 @@ +if (NOT gtk_FOUND) + return() +endif() + +set(GUI_SOURCES stlink-gui.c stlink-gui.h) +set(INSTALLED_UI_DIR share/stlink) + +include_directories(SYSTEM ${gtk_INCLUDE_DIRS}) + +add_executable(stlink-gui-local ${GUI_SOURCES}) +set_target_properties(stlink-gui-local PROPERTIES + COMPILE_FLAGS -DSTLINK_UI_DIR=\\"${CMAKE_CURRENT_SOURCE_DIR}/gui\\") +target_link_libraries(stlink-gui-local stlink ${gtk_LDFLAGS}) + + +add_executable(stlink-gui ${GUI_SOURCES}) +set_target_properties(stlink-gui PROPERTIES + COMPILE_FLAGS -DSTLINK_UI_DIR=\\"${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}\\") +target_link_libraries(stlink-gui stlink ${gtk_LDFLAGS}) + +install(TARGETS stlink-gui + RUNTIME DESTINATION bin) +install(FILES stlink-gui.ui + DESTINATION ${INSTALLED_UI_DIR}) diff --git a/src/tools/info.c b/src/tools/info.c index d3a315150..58e34718a 100644 --- a/src/tools/info.c +++ b/src/tools/info.c @@ -145,6 +145,7 @@ int main(int ac, char** av) return -1; } + printf("st-info %s (%s)\n", STLINK_VERSION); err = print_data(av); return err; diff --git a/usr/lib/pkgconfig/CMakeLists.txt b/usr/lib/pkgconfig/CMakeLists.txt new file mode 100644 index 000000000..5ddc500ca --- /dev/null +++ b/usr/lib/pkgconfig/CMakeLists.txt @@ -0,0 +1,14 @@ +set(PKG_CONFIG_LIBDIR "\${prefix}/lib/\${deb_host_multiarch}") +set(PKG_CONFIG_INCLUDEDIR "\${prefix}/include/\${deb_host_multiarch}/${PROJECT_NAME}-${PROJECT_VERSION}") +set(PKG_CONFIG_LIBS "-L\${libdir} -l:libstlink.so.${PROJECT_VERSION_MAJOR}") +set(PKG_CONFIG_CFLAGS "-I\${includedir}") +set(PKG_CONFIG_REQUIRES "libusb-1.0") + +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" +) + +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + DESTINATION lib/${CMAKE_LIBRARY_PATH}/pkgconfig/ +) diff --git a/pkg-config.pc.cmake b/usr/lib/pkgconfig/pkg-config.pc.cmake similarity index 100% rename from pkg-config.pc.cmake rename to usr/lib/pkgconfig/pkg-config.pc.cmake From 6f26487f83353d607a80f1516dadaf4019989994 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sun, 18 Sep 2016 11:17:25 +0200 Subject: [PATCH 0493/1435] Add --version commandline argument flag. Fixes #470 --- doc/man/st-flash.md | 3 +++ doc/man/st-info.md | 3 +++ doc/man/st-util.md | 3 +++ src/gdbserver/gdb-server.c | 21 ++++++++++----------- src/tools/flash.c | 3 ++- src/tools/flash_opts.c | 6 +++++- src/tools/info.c | 5 ++++- 7 files changed, 30 insertions(+), 14 deletions(-) diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md index 88ba5870a..981bf3cd6 100644 --- a/doc/man/st-flash.md +++ b/doc/man/st-flash.md @@ -35,6 +35,9 @@ erase # OPTIONS +--version +: Print version information + --debug : TODO diff --git a/doc/man/st-info.md b/doc/man/st-info.md index 34192b9d6..d34d5b2b0 100644 --- a/doc/man/st-info.md +++ b/doc/man/st-info.md @@ -18,6 +18,9 @@ Serial code, openocd, flash, sram, page size, chipid, description. # OPTIONS +--version +: Print version information + --flash : Display amount of flash memory available in the device diff --git a/doc/man/st-util.md b/doc/man/st-util.md index 2b68a56fd..5bd93a46b 100644 --- a/doc/man/st-util.md +++ b/doc/man/st-util.md @@ -29,6 +29,9 @@ variable STLINK_DEVICE on the format :. -h, --help : Print this message. +--version +: Print version information + -v *XX*, --verbose=XX : Specify a specific verbosity level (0..99) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 6015ed00b..339cd1130 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -35,7 +35,7 @@ #define FLASH_PAGE (sl->flash_pgsz) static stlink_t *connected_stlink = NULL; -bool semihosting = false; +static bool semihosting = false; static const char hex[] = "0123456789abcdef"; @@ -79,11 +79,13 @@ int parse_options(int argc, char** argv, st_state_t *st) { {"listen_port", required_argument, NULL, 'p'}, {"multi", optional_argument, NULL, 'm'}, {"no-reset", optional_argument, NULL, 'n'}, + {"version", no_argument, NULL, 'V'}, {"semihosting", no_argument, NULL, SEMIHOSTING_OPTION}, {0, 0, 0, 0}, }; const char * help_str = "%s - usage:\n\n" " -h, --help\t\tPrint this help\n" + " -V, --version\t\tPrint the version\n" " -vXX, --verbose=XX\tSpecify a specific verbosity level (0..99)\n" " -v, --verbose\t\tSpecify generally verbose logging\n" " -s X, --stlink_version=X\n" @@ -112,12 +114,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { while ((c = getopt_long(argc, argv, "hv::s:1p:mn", long_options, &option_index)) != -1) { switch (c) { case 0: - printf("XXXXX Shouldn't really normally come here, only if there's no corresponding option\n"); - printf("option %s", long_options[option_index].name); - if (optarg) { - printf(" with arg %s", optarg); - } - printf("\n"); break; case 'h': printf(help_str, argv[0]); @@ -155,6 +151,9 @@ int parse_options(int argc, char** argv, st_state_t *st) { case 'n': st->reset = 0; break; + case 'V': + printf("v%s\n", STLINK_VERSION); + exit(EXIT_SUCCESS); case SEMIHOSTING_OPTION: semihosting = true; break; @@ -170,15 +169,11 @@ int parse_options(int argc, char** argv, st_state_t *st) { return 0; } - int main(int argc, char** argv) { stlink_t *sl = NULL; - st_state_t state; memset(&state, 0, sizeof(state)); - printf("st-util %s (%s)\n", STLINK_VERSION); - // set defaults... state.stlink_version = 2; state.logging_level = DEFAULT_LOGGING_LEVEL; @@ -186,6 +181,8 @@ int main(int argc, char** argv) { state.reset = 1; /* By default, reset board */ parse_options(argc, argv, &state); + printf("st-util %s\n", STLINK_VERSION); + switch (state.stlink_version) { case 2: sl = stlink_open_usb(state.logging_level, state.reset, NULL); @@ -206,6 +203,8 @@ int main(int argc, char** argv) { stlink_reset(sl); } + + ILOG("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); sl->verbose=0; diff --git a/src/tools/flash.c b/src/tools/flash.c index 6ebfcc2fb..5cedb3815 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -35,6 +35,7 @@ static void usage(void) puts("stlinkv2 command line: ./st-flash [--debug] [--serial ] erase"); puts(" Use hex format for addr, and ."); puts(" Format may be 'binary' (default) or 'ihex', although must be specified for binary format only."); + puts(" ./st-flash [--version]"); } int main(int ac, char** av) @@ -52,7 +53,7 @@ int main(int ac, char** av) return -1; } - printf("st-flash %s (%s)\n", STLINK_VERSION); + printf("st-flash %s\n", STLINK_VERSION); if (o.devname != NULL) /* stlinkv1 */ sl = stlink_v1_open(o.log_level, 1); diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 7de2ecde8..1a0d0cd9b 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -23,7 +23,11 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) // options while(ac >= 1) { - if (strcmp(av[0], "--debug") == 0) { + if (strcmp(av[0], "--version") == 0) { + printf("v%s\n", STLINK_VERSION); + exit(EXIT_SUCCESS); + } + else if (strcmp(av[0], "--debug") == 0) { o->log_level = DEBUG_LOG_LEVEL; } else if (strcmp(av[0], "--reset") == 0) { diff --git a/src/tools/info.c b/src/tools/info.c index 58e34718a..2e3efc64d 100644 --- a/src/tools/info.c +++ b/src/tools/info.c @@ -7,6 +7,7 @@ static void usage(void) { + puts("st-info --version"); puts("st-info --flash"); puts("st-info --sram"); puts("st-info --descr"); @@ -93,6 +94,9 @@ static int print_data(char **av) if (strcmp(av[1], "--probe") == 0) { stlink_probe(); return 0; + } else if (strcmp(av[1], "--version") == 0) { + printf("v%s\n", STLINK_VERSION); + return 0; } sl = stlink_open_first(); @@ -145,7 +149,6 @@ int main(int ac, char** av) return -1; } - printf("st-info %s (%s)\n", STLINK_VERSION); err = print_data(av); return err; From 043a928d8fd2b8c8a520471c67bf28d0487e3d17 Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 18 Sep 2016 16:12:10 +0200 Subject: [PATCH 0494/1435] add generated manpages --- doc/man/st-flash.1 | 88 ++++++++++++++++++++++++++++++++++++++++++++++ doc/man/st-info.1 | 76 +++++++++++++++++++++++++++++++++++++++ doc/man/st-term.1 | 32 +++++++++++++++++ doc/man/st-util.1 | 9 ++++- 4 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 doc/man/st-flash.1 create mode 100644 doc/man/st-info.1 create mode 100644 doc/man/st-term.1 diff --git a/doc/man/st-flash.1 b/doc/man/st-flash.1 new file mode 100644 index 000000000..252ffcba8 --- /dev/null +++ b/doc/man/st-flash.1 @@ -0,0 +1,88 @@ +.TH ST-FLASH 1 "Sep 2016" "Open Source STMicroelectronics Stlink Tools" "STLINK" +.SH NAME +.PP +st-flash - Flash binary files to STM32 device +.SH SYNOPSIS +.PP +\f[I]st-flash\f[] [\f[I]OPTIONS\f[]] {read|write|erase} [\f[I]FILE\f[]] + +.SH DESCRIPTION +.PP +Flash binary files to arbitrary sections of memory, or read arbitrary +addresses of memory out to a binary file. +.PP +You can use this instead of st-util(1) if you prefer, but remember to +use the \f[B]\&.bin\f[] image, rather than the \f[B]\&.elf\f[] file. +.PP +Use hexadecimal format for the \f[I]ADDR\f[] and \f[I]SIZE\f[]. +.SH COMMANDS +.TP +.B write \f[I]FILE\f[] \f[I]ADDR\f[] +Write firmware \f[I]FILE\f[] to device starting from \f[I]ADDR\f[] +.RS +.RE +.TP +.B read \f[I]FILE\f[] \f[I]ADDR\f[] \f[I]SIZE\f[] +Read firmware from device starting from \f[I]ADDR\f[] up to +\f[I]SIZE\f[] bytes to \f[I]FILE\f[] +.RS +.RE +.TP +.B erase +Perform a mass erasing of the device firmware +.RS +.RE +.SH OPTIONS +.TP +.B --version +Print version information +.RS +.RE +.TP +.B --debug +TODO +.RS +.RE +.TP +.B --reset +TODO +.RS +.RE +.TP +.B --serial \f[I]iSerial\f[] +TODO +.RS +.RE +.SH EXAMPLES +.PP +Flash \f[C]firmware.bin\f[] to device +.IP +.nf +\f[C] +$\ st-flash\ write\ firmware.bin\ 0x8000000 +\f[] +.fi +.PP +Read firmware from device (4096 bytes) +.IP +.nf +\f[C] +$\ st-flash\ read\ firmware.bin\ 0x8000000\ 4096 +\f[] +.fi +.PP +Erase firmware from device +.IP +.nf +\f[C] +$\ st-flash\ erase +\f[] +.fi +.SH SEE ALSO +.PP +st-util(1), st-info(1), st-term(1) +.SH COPYRIGHT +.PP +This work is copyrighted. +Stlink contributors. +See \f[I]LICENSE\f[] file in the stlink source distribution. diff --git a/doc/man/st-info.1 b/doc/man/st-info.1 new file mode 100644 index 000000000..8576d39e4 --- /dev/null +++ b/doc/man/st-info.1 @@ -0,0 +1,76 @@ +.TH ST-INFO 1 "Sep 2016" "Open Source STMicroelectronics Stlink Tools" "STLINK" +.SH NAME +.PP +st-info - Provides information about connected STLink and STM32 devices +.SH SYNOPSIS +.PP +\f[I]st-info\f[] [\f[I]OPTIONS\f[]] +.SH DESCRIPTION +.PP +Provides information about connected STLink programmers and STM32 +devices: Serial code, openocd, flash, sram, page size, chipid, +description. +.SH OPTIONS +.TP +.B --version +Print version information +.RS +.RE +.TP +.B --flash +Display amount of flash memory available in the device +.RS +.RE +.TP +.B --sram +Display amount of sram memory available in device +.RS +.RE +.TP +.B --descr +Display textual description of the device +.RS +.RE +.TP +.B --pagesize +Display the page size of the device +.RS +.RE +.TP +.B --chipid +Display the chip ID of the device +.RS +.RE +.TP +.B --serial +Display the serial code of the device +.RS +.RE +.TP +.B --hla-serial +Display the hex escaped serial code of the device +.RS +.RE +.TP +.B --probe +Display the summarized information of the connected programmers and +devices +.RS +.RE +.SH EXAMPLES +.PP +Display information about connected programmers and devices +.IP +.nf +\f[C] +$\ st-info\ --probe +\f[] +.fi +.SH SEE ALSO +.PP +st-util(1), st-flash(1), st-term(1) +.SH COPYRIGHT +.PP +This work is copyrighted. +Stlink contributors. +See \f[I]LICENSE\f[] file in the stlink source distribution. diff --git a/doc/man/st-term.1 b/doc/man/st-term.1 new file mode 100644 index 000000000..e6512540c --- /dev/null +++ b/doc/man/st-term.1 @@ -0,0 +1,32 @@ +.TH ST-TERM 1 "Sep 2016" "Open Source STMicroelectronics Stlink Tools" "STLINK" +.SH NAME +.PP +st-term - Serial terminal interface for debugging using STLink device +only +.SH SYNOPSIS +.PP +\f[I]st-term\f[] +.SH DESCRIPTION +.PP +Provides a serial terminal that works through the STLink device, +allowing to do the kind of debugging you would do using the UART of the +STM32 device without having to connect a UART-USB serial adapter dongle. +.PP +It works by having a magic number in sram of the MCU within a structure +that serves as IO buffer. +.PP +The required setup consist of some code that establishes the magic +number, buffer structure and helper functions for actual data +transmission between host and MCU. +.PP +\f[C]stlinky.h\f[] and \f[C]stlinky.c\f[] are available in the Antares +build system libraries source: +https://github.com/nekromant/antares/tree/master/include/lib +.SH SEE ALSO +.PP +st-util(1), st-info(1), st-term(1) +.SH COPYRIGHT +.PP +This work is copyrighted. +Stlink contributors. +See \f[I]LICENSE\f[] file in the stlink source distribution. diff --git a/doc/man/st-util.1 b/doc/man/st-util.1 index 674b0dbef..8fb791221 100644 --- a/doc/man/st-util.1 +++ b/doc/man/st-util.1 @@ -1,3 +1,5 @@ +.TH ST-UTIL 1 "Sep 2016" "Open Source STMicroelectronics Stlink Tools" "STLINK" +.SH NAME .PP st-util - Run GDB server to interact with STM32 device .SH SYNOPSIS @@ -14,7 +16,7 @@ option, the default \f[B]4242\f[] port will be used. Stlink version 2 is used by default unless the option \f[B]--stlinkv1\f[] is given. .PP -The STLINKv2 device to use can be specified in the environment variable +The STLinkV2 device to use can be specified in the environment variable STLINK_DEVICE on the format :. .SH OPTIONS .TP @@ -23,6 +25,11 @@ Print this message. .RS .RE .TP +.B --version +Print version information +.RS +.RE +.TP .B -v \f[I]XX\f[], --verbose=XX Specify a specific verbosity level (0..99) .RS From e407d9e5a9cb76767dba6539c7a9cf0a7b87ea24 Mon Sep 17 00:00:00 2001 From: Denis Osterland Date: Sun, 18 Sep 2016 10:52:03 +0200 Subject: [PATCH 0495/1435] deb: Fix broken install rules. Override dh_auto_install to use *.install files as they are. The debian/*.install could contain source to destination format too, but that would be much more difficult to handle with multi-arch. Add debian copyright file. Add stlink-tools manpages. Insert homepage link. Add library dependencies to binaries. Add howto debuild to README. Install udev rules. Install modprobe config for usb module. Configure cmake with /usr prefix and compile release variant. --- Makefile | 8 ++++---- README.md | 8 ++++++++ debian/control | 6 +++--- debian/copyright | 12 ++++++++++++ debian/libstlink.install | 2 ++ debian/rules | 37 ++++++++++++++++++++++++++++++++---- debian/stlink-tools.manpages | 1 + 7 files changed, 63 insertions(+), 11 deletions(-) create mode 100644 debian/copyright create mode 100644 debian/stlink-tools.manpages diff --git a/Makefile b/Makefile index d93c4b181..fca19d603 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ ## MAKEFLAGS += -s -all: debug +all: release ci: lint debug release test help: @@ -27,16 +27,16 @@ release: build/Release @echo "[RELEASE]" @$(MAKE) -C build/Release -test: build/Debug +test: debug @$(MAKE) -C build/Debug test build/Debug: @mkdir -p $@ - @cd $@ && cmake -DCMAKE_BUILD_TYPE=Debug ../../ + @cd $@ && cmake -DCMAKE_BUILD_TYPE=Debug $(CMAKEFLAGS) ../../ build/Release: @mkdir -p $@ - @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release ../../ + @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) ../../ clean: @echo "[CLEAN]" diff --git a/README.md b/README.md index 2846a53d4..c3345910a 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,14 @@ $ cmake -DCMAKE_BUILD_TYPE=Debug .. $ make ``` +### Build Debian Package +To build debian package you need debuild. + +``` +$ git archive --prefix=$(git describe)/ HEAD | bzip2 --stdout > ../libstlink_$(sed -En -e "s/.*\((.*)\).*/\1/" -e "1,1 p" debian/changelog).orig.tar.bz2 +$ debuild -uc -us +``` + ## Using the gdb server To run the gdb server: (you do not need sudo if you have set up diff --git a/debian/control b/debian/control index b9beac2fc..41c8e87a3 100644 --- a/debian/control +++ b/debian/control @@ -4,7 +4,7 @@ Maintainer: Andrew 'Necromant' Andrianov Build-Depends: debhelper (>= 9), cmake, libusb-1.0-0-dev, libgtk-3-dev Standards-Version: 3.9.5 Section: libs -Homepage: +Homepage: https://github.com/texane/stlink Vcs-Git: https://github.com/texane/stlink.git Vcs-Browser: https://github.com/texane/stlink @@ -24,11 +24,11 @@ Description: OpenSource ST-Link tools replacement. Shared library. Package: stlink-tools Section: libdevel Architecture: any -Depends: libstlink (= ${binary:Version}), ${misc:Depends} +Depends: libstlink (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: OpenSource ST-Link tools replacement. Commandline Utilities. Package: stlink-gui Section: libdevel Architecture: any -Depends: libstlink (= ${binary:Version}), ${misc:Depends} +Depends: libstlink (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: OpenSource ST-Link tools replacement. GUI Tool. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 000000000..e28d7e1bb --- /dev/null +++ b/debian/copyright @@ -0,0 +1,12 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: libstlink +Upstream-Contact: Andrew 'Necromant' Andrianov +Source: https://github.com/texane/stlink + +Files: * +Copyright: (c) 2011 The stlink project (github.com/texane/stlink) contributors. +License: BSD-3-clause + +Files: * +Copyright: (c) 2011 The "Capt'ns Missing Link" Authors. All rights reserved. +License: BSD-3-clause diff --git a/debian/libstlink.install b/debian/libstlink.install index 703ad8b31..9f7f9316b 100644 --- a/debian/libstlink.install +++ b/debian/libstlink.install @@ -1 +1,3 @@ usr/lib/*/lib*.so* +lib/udev/rules.d/*.rules +lib/modprobe.d/*.conf diff --git a/debian/rules b/debian/rules index 4979b59d7..419ce1e4d 100755 --- a/debian/rules +++ b/debian/rules @@ -21,8 +21,37 @@ include /usr/share/dpkg/default.mk %: dh $@ -# debmake generated override targets -# This is example for Cmake (See http://bugs.debian.org/641051 ) + +OUTDIR=build/Release +ROOTDIR=debian/tmp +DSTDIR=$(ROOTDIR)/usr +BINDIR=$(DSTDIR)/bin +SHAREDIR=$(DSTDIR)/share/stlink +LIBDIR=$(DSTDIR)/lib/$(if $(DEB_TARGET_MULTIARCH),$(DEB_TARGET_MULTIARCH),$(DEB_BUILD_MULTIARCH)) +UDEVDIR=$(ROOTDIR)/lib/udev/rules.d/ +MODDIR=$(ROOTDIR)/lib/modprobe.d/ + +export CMAKEFLAGS = \ + -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) \ + -DCMAKE_INSTALL_PREFIX=/usr \ + + override_dh_auto_configure: - dh_auto_configure -- \ - -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) + +override_dh_auto_install: + install -d $(DSTDIR)/include/stlink/tools + install -d $(LIBDIR)/pkgconfig + install -d $(BINDIR) + install -d $(SHAREDIR) + install -d $(UDEVDIR) + install -d $(MODDIR) + install -m644 $(wildcard include/*.h) $(DSTDIR)/include + install -m644 $(wildcard include/stlink/*.h) $(DSTDIR)/include/stlink + install -m644 $(wildcard include/stlink/tools/*.h) $(DSTDIR)/include/stlink/tools + install -m755 $(wildcard $(OUTDIR)/st-* $(OUTDIR)/src/gdbserver/st-* $(OUTDIR)/src/tools/gui/stlink-gui*) $(BINDIR) + cp -d $(wildcard $(OUTDIR)/libstlink.*) $(LIBDIR) + install -m644 $(OUTDIR)/usr/lib/pkgconfig/stlink.pc $(LIBDIR)/pkgconfig + install -m644 src/tools/gui/stlink-gui.ui $(SHAREDIR) + install -m644 etc/udev/rules.d/*.rules $(UDEVDIR) + install -m644 etc/modprobe.d/*.conf $(MODDIR) + diff --git a/debian/stlink-tools.manpages b/debian/stlink-tools.manpages new file mode 100644 index 000000000..6a461c09e --- /dev/null +++ b/debian/stlink-tools.manpages @@ -0,0 +1 @@ +doc/man/st-*.1 From 4bf6cb387f98e4b562f8e964af1deb32f7d40be0 Mon Sep 17 00:00:00 2001 From: Dave Flogeras Date: Wed, 21 Sep 2016 11:44:38 -0300 Subject: [PATCH 0496/1435] Do not issue JTAG reset on stlink-v1 --- src/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/usb.c b/src/usb.c index 11e8dfe44..f32b2e04c 100644 --- a/src/usb.c +++ b/src/usb.c @@ -880,7 +880,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 } if (reset) { - stlink_jtag_reset(sl, 2); + if( sl->version.stlink_v > 1 ) stlink_jtag_reset(sl, 2); stlink_reset(sl); usleep(10000); } From 823079ad4dfeaa63bd8c1e1c0fc7d055a1c09c46 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 22 Sep 2016 21:06:35 +0200 Subject: [PATCH 0497/1435] Update README.md Update badge caching --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c3345910a..78934eee8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ Open source version of the STMicroelectronics Stlink Tools ========================================================== -[![GitHub release](https://img.shields.io/github/release/texane/stlink.svg?maxAge=2592000)](https://github.com/texane/stlink/releases/latest) -[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.2.0.svg?maxAge=2592000)](https://github.com/texane/stlink/compare/1.2.0...master) +[![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) +[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.2.0.svg)](https://github.com/texane/stlink/compare/1.2.0...master) [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) [![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/job/stlink/) [![Build status](https://ci.appveyor.com/api/projects/status/wrcie05d4jmut0te?svg=true)](https://ci.appveyor.com/project/xor-gate/stlink) From ee3f7a1cf111b481b76e7c9e1dd1739daea3c273 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 24 Sep 2016 23:57:25 +0200 Subject: [PATCH 0498/1435] Update README.md Update udev rules paragraph. --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 78934eee8..f54764b1b 100644 --- a/README.md +++ b/README.md @@ -134,9 +134,9 @@ for GDB. ## Setting up udev rules -For convenience, you may install udev rules file, 49-stlinkv*.rules, located -in the root of repository. You will need to copy it to /etc/udev/rules.d, -and then either reboot or execute +For convenience, you may install udev rule files, located +in the `etc/udev/rules.d` directory. You will need to copy it to /etc/udev/rules.d, +and then either execute as root (or reboot your machine): ``` $ udevadm control --reload-rules @@ -144,8 +144,6 @@ $ udevadm trigger ``` Udev will now create a /dev/stlinkv2_XX or /dev/stlinkv1_XX file, with the appropriate permissions. -This is currently all the device is for, (only one stlink of each version is supported at -any time presently) ## Running programs from SRAM From 650a88aa2c9feaee482d5ed6130fea15c6d3929e Mon Sep 17 00:00:00 2001 From: Andrew Andrianov Date: Fri, 23 Sep 2016 12:54:43 +0300 Subject: [PATCH 0499/1435] debian: Remove all useless stuff from debian/rules, force cmake buildsystem The top-level makefile that was used to drive cmake broke the autodetection of the used buildsystem by debhelper. This commit fixes it and moves most of the installation stuff to CMakeLists.txt to keep debian/ folder contents to the bare minimum. Signed-off-by: Andrew Andrianov --- CMakeLists.txt | 8 ++++++++ Makefile | 4 ++++ cmake/CPackConfig.cmake | 2 ++ debian/libstlink-dev.install | 2 ++ debian/libstlink.install | 4 ++-- debian/rules | 40 +++++------------------------------- debian/stlink-gui.install | 2 +- 7 files changed, 24 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d5a03170..f648843a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,6 +127,14 @@ install(TARGETS st-flash st-info RUNTIME DESTINATION bin ) +if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + file(GLOB RULES_FILES etc/udev/rules.d/*.rules) + install(FILES etc/modprobe.d/stlink_v1.conf + DESTINATION /etc) + install(FILES ${RULES_FILES} + DESTINATION /lib/udev/rules.d/) +endif() + add_subdirectory(src/gdbserver) add_subdirectory(src/tools/gui) diff --git a/Makefile b/Makefile index fca19d603..2ddfceee8 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,10 @@ release: build/Release @echo "[RELEASE]" @$(MAKE) -C build/Release +package: build/Release + @echo "[PACKAGE] Release" + @$(MAKE) -C build/Release package + test: debug @$(MAKE) -C build/Debug test diff --git a/cmake/CPackConfig.cmake b/cmake/CPackConfig.cmake index 4e851efae..1dfd376be 100644 --- a/cmake/CPackConfig.cmake +++ b/cmake/CPackConfig.cmake @@ -3,6 +3,8 @@ set (CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) set (CPACK_SOURCE_GENERATOR "TBZ2;ZIP") set (CPACK_SOURCE_IGNORE_FILES "/build/;/.git/;~$;${CPACK_SOURCE_IGNORE_FILES}") set (CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}") +set (CPACK_SET_DESTDIR "ON") +set (CPACK_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/cpack/staging") if (APPLE) set(CPACK_GENERATOR "ZIP") file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/osx") diff --git a/debian/libstlink-dev.install b/debian/libstlink-dev.install index 1eff3299c..0c3543cd9 100644 --- a/debian/libstlink-dev.install +++ b/debian/libstlink-dev.install @@ -1,3 +1,5 @@ usr/include/* usr/lib/*/lib*.a usr/lib/*/pkgconfig/* +usr/lib/*/lib*.so + diff --git a/debian/libstlink.install b/debian/libstlink.install index 9f7f9316b..08981406e 100644 --- a/debian/libstlink.install +++ b/debian/libstlink.install @@ -1,3 +1,3 @@ -usr/lib/*/lib*.so* +usr/lib/*/lib*.so.* lib/udev/rules.d/*.rules -lib/modprobe.d/*.conf +etc/modprobe.d/*.conf diff --git a/debian/rules b/debian/rules index 419ce1e4d..2b826772b 100755 --- a/debian/rules +++ b/debian/rules @@ -16,42 +16,12 @@ include /usr/share/dpkg/default.mk # package maintainers to append LDFLAGS #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed - # main packaging script based on dh7 syntax %: - dh $@ - - -OUTDIR=build/Release -ROOTDIR=debian/tmp -DSTDIR=$(ROOTDIR)/usr -BINDIR=$(DSTDIR)/bin -SHAREDIR=$(DSTDIR)/share/stlink -LIBDIR=$(DSTDIR)/lib/$(if $(DEB_TARGET_MULTIARCH),$(DEB_TARGET_MULTIARCH),$(DEB_BUILD_MULTIARCH)) -UDEVDIR=$(ROOTDIR)/lib/udev/rules.d/ -MODDIR=$(ROOTDIR)/lib/modprobe.d/ - -export CMAKEFLAGS = \ - -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) \ - -DCMAKE_INSTALL_PREFIX=/usr \ - + dh $@ --buildsystem cmake +# debmake generated override targets +# This is example for Cmake (See http://bugs.debian.org/641051 ) override_dh_auto_configure: - -override_dh_auto_install: - install -d $(DSTDIR)/include/stlink/tools - install -d $(LIBDIR)/pkgconfig - install -d $(BINDIR) - install -d $(SHAREDIR) - install -d $(UDEVDIR) - install -d $(MODDIR) - install -m644 $(wildcard include/*.h) $(DSTDIR)/include - install -m644 $(wildcard include/stlink/*.h) $(DSTDIR)/include/stlink - install -m644 $(wildcard include/stlink/tools/*.h) $(DSTDIR)/include/stlink/tools - install -m755 $(wildcard $(OUTDIR)/st-* $(OUTDIR)/src/gdbserver/st-* $(OUTDIR)/src/tools/gui/stlink-gui*) $(BINDIR) - cp -d $(wildcard $(OUTDIR)/libstlink.*) $(LIBDIR) - install -m644 $(OUTDIR)/usr/lib/pkgconfig/stlink.pc $(LIBDIR)/pkgconfig - install -m644 src/tools/gui/stlink-gui.ui $(SHAREDIR) - install -m644 etc/udev/rules.d/*.rules $(UDEVDIR) - install -m644 etc/modprobe.d/*.conf $(MODDIR) - + dh_auto_configure -- \ + -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) diff --git a/debian/stlink-gui.install b/debian/stlink-gui.install index eedcd7172..d18d2cec4 100644 --- a/debian/stlink-gui.install +++ b/debian/stlink-gui.install @@ -1,2 +1,2 @@ /usr/bin/stlink-gui* -/usr/share/* +/usr/share/stlink/stlink-gui.ui From e3975598fa20d7636c6827c562bcf8424cbb98d2 Mon Sep 17 00:00:00 2001 From: Geoffrey Brown Date: Sat, 15 Oct 2016 14:33:41 -0400 Subject: [PATCH 0500/1435] stm32l432 support --- include/stlink/chipid.h | 4 ++++ src/chipid.c | 16 ++++++++++++++++ src/common.c | 6 ++++-- src/flash_loader.c | 4 +++- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 72094a733..7d25fc5ef 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -34,6 +34,7 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F37x = 0x432, STLINK_CHIPID_STM32_F4_DE = 0x433, STLINK_CHIPID_STM32_F4_DSI = 0x434, + STLINK_CHIPID_STM32_L43X = 0x435, /* * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" * and some that are called "High". 0x427 is assigned to the other "Medium- @@ -54,6 +55,9 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F7 = 0x449, STLINK_CHIPID_STM32_F7XXXX = 0x451, STLINK_CHIPID_STM32_F410 = 0x458 + + + }; /** diff --git a/src/chipid.c b/src/chipid.c index 7f8bbd3f9..8a2f5ec94 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -406,6 +406,22 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) .bootrom_size = 0x7000 // 28k (per bank), same source as base }, + { + // STLINK_CHIPID_STM32_L43X + // From RM0392. + .chip_id = STLINK_CHIPID_STM32_L43X, + .description = "L4 device", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) + .flash_pagesize = 0x800, // 2K (sec 3.2, page 74; also appears in sec 3.3.1 and tables 7-8 on pages 75-76) + // SRAM1 is "up to" 64k in the standard Cortex-M memory map; + // SRAM2 is 16k mapped at at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) + .sram_size = 0xc000, + .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000 // 28k (per bank), same source as base + }, + }; diff --git a/src/common.c b/src/common.c index 74fa1043e..e8cdf3ba9 100644 --- a/src/common.c +++ b/src/common.c @@ -1417,7 +1417,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) unlock_flash_if(sl); /* select the page to erase */ - if (sl->chip_id == STLINK_CHIPID_STM32_L4) { + if (sl->chip_id == STLINK_CHIPID_STM32_L4 || sl->chip_id == STLINK_CHIPID_STM32_L43X) { // calculate the actual bank+page from the address uint32_t page = calculate_L4_page(sl, flashaddr); @@ -1767,7 +1767,9 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t unlock_flash_if(sl); /* TODO: Check that Voltage range is 2.7 - 3.6 V */ - if (sl->chip_id != STLINK_CHIPID_STM32_L4) { + if ((sl->chip_id != STLINK_CHIPID_STM32_L4) && + (sl->chip_id != STLINK_CHIPID_STM32_L43X)) + { if( sl->version.stlink_v == 1 ) { printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes on F4 devices\n"); write_flash_cr_psiz(sl, 2); diff --git a/src/flash_loader.c b/src/flash_loader.c index e05f35ae5..77ebd95eb 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -246,7 +246,9 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || sl->chip_id == STLINK_CHIPID_STM32_F04 || sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || sl->chip_id == STLINK_CHIPID_STM32_F0_SMALL || sl->chip_id == STLINK_CHIPID_STM32_F09X) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); - } else if (sl->chip_id == STLINK_CHIPID_STM32_L4) { + } else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || + (sl->chip_id == STLINK_CHIPID_STM32_L43X)) + { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); } else { From 97052483cf016be9a45e1af9a8feb9e0429eb8db Mon Sep 17 00:00:00 2001 From: Geoffrey Brown Date: Sat, 15 Oct 2016 14:47:30 -0400 Subject: [PATCH 0501/1435] fixed formatting, description --- include/stlink/chipid.h | 3 --- src/chipid.c | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 7d25fc5ef..18f02782c 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -55,9 +55,6 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F7 = 0x449, STLINK_CHIPID_STM32_F7XXXX = 0x451, STLINK_CHIPID_STM32_F410 = 0x458 - - - }; /** diff --git a/src/chipid.c b/src/chipid.c index 8a2f5ec94..c6bcf70bb 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -410,7 +410,7 @@ static const struct stlink_chipid_params devices[] = { // STLINK_CHIPID_STM32_L43X // From RM0392. .chip_id = STLINK_CHIPID_STM32_L43X, - .description = "L4 device", + .description = "L43x device", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) .flash_pagesize = 0x800, // 2K (sec 3.2, page 74; also appears in sec 3.3.1 and tables 7-8 on pages 75-76) From cde9cb147bb4d35d207aaa85b02043b6d5a2a524 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 22 Oct 2016 09:25:43 +0200 Subject: [PATCH 0502/1435] doc: Remove remaining st-term man page --- doc/man/CMakeLists.txt | 1 - doc/man/st-flash.md | 2 +- doc/man/st-info.md | 2 +- doc/man/st-term.1 | 32 -------------------------------- doc/man/st-term.md | 36 ------------------------------------ doc/man/st-util.md | 2 +- 6 files changed, 3 insertions(+), 72 deletions(-) delete mode 100644 doc/man/st-term.1 delete mode 100644 doc/man/st-term.md diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 4ea25e797..55b419361 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -2,7 +2,6 @@ set(MANPAGES st-util st-flash st-info - st-term ) # Only generate manpages with pandoc in Debug builds diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md index 981bf3cd6..d294f05d1 100644 --- a/doc/man/st-flash.md +++ b/doc/man/st-flash.md @@ -65,7 +65,7 @@ Erase firmware from device # SEE ALSO -st-util(1), st-info(1), st-term(1) +st-util(1), st-info(1) # COPYRIGHT diff --git a/doc/man/st-info.md b/doc/man/st-info.md index d34d5b2b0..62d7c5ce1 100644 --- a/doc/man/st-info.md +++ b/doc/man/st-info.md @@ -53,7 +53,7 @@ Display information about connected programmers and devices # SEE ALSO -st-util(1), st-flash(1), st-term(1) +st-util(1), st-flash(1) # COPYRIGHT diff --git a/doc/man/st-term.1 b/doc/man/st-term.1 deleted file mode 100644 index e6512540c..000000000 --- a/doc/man/st-term.1 +++ /dev/null @@ -1,32 +0,0 @@ -.TH ST-TERM 1 "Sep 2016" "Open Source STMicroelectronics Stlink Tools" "STLINK" -.SH NAME -.PP -st-term - Serial terminal interface for debugging using STLink device -only -.SH SYNOPSIS -.PP -\f[I]st-term\f[] -.SH DESCRIPTION -.PP -Provides a serial terminal that works through the STLink device, -allowing to do the kind of debugging you would do using the UART of the -STM32 device without having to connect a UART-USB serial adapter dongle. -.PP -It works by having a magic number in sram of the MCU within a structure -that serves as IO buffer. -.PP -The required setup consist of some code that establishes the magic -number, buffer structure and helper functions for actual data -transmission between host and MCU. -.PP -\f[C]stlinky.h\f[] and \f[C]stlinky.c\f[] are available in the Antares -build system libraries source: -https://github.com/nekromant/antares/tree/master/include/lib -.SH SEE ALSO -.PP -st-util(1), st-info(1), st-term(1) -.SH COPYRIGHT -.PP -This work is copyrighted. -Stlink contributors. -See \f[I]LICENSE\f[] file in the stlink source distribution. diff --git a/doc/man/st-term.md b/doc/man/st-term.md deleted file mode 100644 index e9b635e5c..000000000 --- a/doc/man/st-term.md +++ /dev/null @@ -1,36 +0,0 @@ -% ST-TERM(1) Open Source STMicroelectronics Stlink Tools | STLINK -% -% Sep 2016 - - -# NAME -st-term - Serial terminal interface for debugging using STLink device only - - -# SYNOPSIS -*st-term* - - -# DESCRIPTION -Provides a serial terminal that works through the STLink device, allowing to do -the kind of debugging you would do using the UART of the STM32 device without -having to connect a UART-USB serial adapter dongle. - -It works by having a magic number in sram of the MCU within a structure that -serves as IO buffer. - -The required setup consist of some code that establishes the magic number, -buffer structure and helper functions for actual data transmission between host -and MCU. - -`stlinky.h` and `stlinky.c` are available in the Antares build system libraries -source: https://github.com/nekromant/antares/tree/master/include/lib - - -# SEE ALSO -st-util(1), st-info(1), st-term(1) - - -# COPYRIGHT -This work is copyrighted. Stlink contributors. -See *LICENSE* file in the stlink source distribution. diff --git a/doc/man/st-util.md b/doc/man/st-util.md index 5bd93a46b..fd744d825 100644 --- a/doc/man/st-util.md +++ b/doc/man/st-util.md @@ -63,7 +63,7 @@ Run GDB server on port 4500 and connect to it # SEE ALSO -st-flash(1), st-info(1), st-term(1) +st-flash(1), st-info(1) # COPYRIGHT From 68b0f3bddc3c4aaffe34caa6a3201029edd8ad56 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 22 Oct 2016 09:44:37 +0200 Subject: [PATCH 0503/1435] Initial work to fix cygwin builds --- CMakeLists.txt | 5 +++-- Makefile | 2 +- cmake/modules/FindLibUSB.cmake | 2 -- doc/man/CMakeLists.txt | 4 +++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f648843a7..04717e0a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.7) project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics Stlink Tools") -include(CheckIncludeFile) +option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) if (POLICY CMP0042) # Newer cmake on MacOS should use @rpath @@ -22,6 +22,7 @@ if (NOT APPLE AND NOT WIN32) pkg_check_modules(gtk gtk+-3.0) endif () +include(CheckIncludeFile) CHECK_INCLUDE_FILE(sys/mman.h STLINK_HAVE_SYS_MMAN_H) if (STLINK_HAVE_SYS_MMAN_H) add_definitions(-DSTLINK_HAVE_SYS_MMAN_H) @@ -95,7 +96,7 @@ else() endif() install(TARGETS ${PROJECT_NAME} - LIBRARY DESTINATION lib/${CMAKE_LIBRARY_PATH} + DESTINATION lib/${CMAKE_LIBRARY_PATH} ) ### diff --git a/Makefile b/Makefile index 2ddfceee8..7f81488bb 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ MAKEFLAGS += -s all: release -ci: lint debug release test +ci: debug release test help: @echo " release: Run a release build" diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index 90aafb3a2..45472b96e 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -44,8 +44,6 @@ else () ) endif() -message(STATUS "LIBUSB_INCLUDE_DIR: ${LIBUSB_INCLUDE_DIR}") - if (APPLE) set(LIBUSB_NAME libusb-1.0.a) elseif(MSYS OR MINGW) diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 55b419361..83bb008cf 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -5,7 +5,7 @@ set(MANPAGES ) # Only generate manpages with pandoc in Debug builds -if(${CMAKE_BUILD_TYPE} MATCHES "Debug") +if(${STLINK_GENERATE_MANPAGES}) include(pandocology) foreach(manpage ${MANPAGES}) @@ -16,6 +16,8 @@ if(${CMAKE_BUILD_TYPE} MATCHES "Debug") PRODUCT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) endforeach() +else() + message(STATUS "Manpage generation disabled") endif() # Install from output folder or this folder From 09b8775328bff5119e5b3179d6a592ef1ac46779 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 22 Oct 2016 09:50:12 +0200 Subject: [PATCH 0504/1435] .github/ISSUE_TEMPLATE.md: Correct typos. Fixes #503 --- .github/ISSUE_TEMPLATE.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 932e9387f..63c6c4505 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -2,15 +2,16 @@ Thank you for giving feedback to the stlink project. Take some time to fill out check boxes with a X in the following items so developers and other people can try to - to find out what is going on. And add/remove what is appropiate to your problem. + to find out what is going on. And add/remove what is appropriate to your problem. -When submitting a feature request, try to reuse the list and add/remove what is appropiate. +When submitting a feature request, try to reuse the list and add/remove what is appropriate. + Place a `X` between the brackets `[X]` to mark the list item. - [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard - [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 - [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) - [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 -- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` +- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` - [ ] Target chip (and optional board): e.g STM32F402VG (STM32Fxxx Discovery) A as-detailed description possible of the problem with debug output when available. From 9eb84d9f045a994d66a0271d4b92dd4d786552d1 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 22 Oct 2016 10:18:33 +0200 Subject: [PATCH 0505/1435] README.md: Refactor compilation and udev notes into seperate document. Fixes #486 --- README.md | 72 ++++++++++++------------------------------------ doc/compiling.md | 65 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 54 deletions(-) create mode 100644 doc/compiling.md diff --git a/README.md b/README.md index f54764b1b..267cf765a 100644 --- a/README.md +++ b/README.md @@ -22,52 +22,27 @@ Two different transport layers are used: * STLINKv1 uses SCSI passthru commands over USB * STLINKv2 uses raw USB commands. -## Common requirements +## Installation -* Debian based distros (debian, ubuntu) - * `build-essential` +Currently there are no binaries for windows available. + It is known to compile and work with MinGW/Cygwin. -* `cmake` -* `libusb-1.0` (plus development headers for building, on debian based distros `libusb-1.0.0-dev` package) -* (optional) for `stlink-gui` we need libgtk-3-dev +For debian linux based distros there is also no package available + in the standard repositories so you need to compile yourself. -## For STLINKv1 +Arch Linux users can install from the [repository](https://www.archlinux.org/packages/community/x86_64/stlink) -The STLINKv1's SCSI emulation is very broken, so the best thing to do -is tell your operating system to completely ignore it. +FreeBSD users can install from [freshports](https://www.freshports.org/devel/stlink) -Options (do one of these before you plug it in) +**Compilation from source (advanced users)** -* `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` -* or 1. `echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.conf` -* 2. `modprobe -r usb-storage && modprobe usb-storage` -* or 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` -* 2. `modprobe -r usb-storage && modprobe usb-storage` - -## For STLINKv2 - -You're ready to go :) - -## Build from sources - -``` -$ mkdir build && cd build -$ cmake -DCMAKE_BUILD_TYPE=Debug .. -$ make -``` - -### Build Debian Package -To build debian package you need debuild. - -``` -$ git archive --prefix=$(git describe)/ HEAD | bzip2 --stdout > ../libstlink_$(sed -En -e "s/.*\((.*)\).*/\1/" -e "1,1 p" debian/changelog).orig.tar.bz2 -$ debuild -uc -us -``` +When there is no executable available for your platform or you need the latest + (possible unstable) version you need to compile yourself. This is explained in + the [compiling manual](doc/compiling.md). ## Using the gdb server -To run the gdb server: (you do not need sudo if you have set up -permissions correctly) +To run the gdb server: ``` $ make && [sudo] ./st-util @@ -92,7 +67,7 @@ There are a few options: ``` The STLINKv2 device to use can be specified in the environment -variable STLINK_DEVICE on the format `:`. +variable `STLINK_DEVICE` on the format `:`. Then, in your project directory, someting like this... (remember, you need to run an _ARM_ gdb, not an x86 gdb) @@ -112,8 +87,6 @@ Transfer rate: 1 KB/sec, 560 bytes/write. (gdb) continue ``` -Have fun! - ## Resetting the chip from GDB You may reset the chip using GDB if you want. You'll need to use `target @@ -132,19 +105,6 @@ Starting program: /home/whitequark/ST/apps/bally/firmware.elf Remember that you can shorten the commands. `tar ext :4242' is good enough for GDB. -## Setting up udev rules - -For convenience, you may install udev rule files, located -in the `etc/udev/rules.d` directory. You will need to copy it to /etc/udev/rules.d, -and then either execute as root (or reboot your machine): - -``` -$ udevadm control --reload-rules -$ udevadm trigger -``` - -Udev will now create a /dev/stlinkv2_XX or /dev/stlinkv1_XX file, with the appropriate permissions. - ## Running programs from SRAM You can run your firmware directly from SRAM if you want to. Just link @@ -160,8 +120,12 @@ code, if it is linked correctly (i.e. ELF has correct entry point). ## Writing to flash The GDB stub ships with a correct memory map, including the flash area. -If you would link your executable to 0x08000000 and then do +If you would link your executable to `0x08000000` and then do + +``` (gdb) load firmware.elf +``` + then it would be written to the memory. ## FAQ diff --git a/doc/compiling.md b/doc/compiling.md new file mode 100644 index 000000000..7021058fa --- /dev/null +++ b/doc/compiling.md @@ -0,0 +1,65 @@ +# Compiling + +## Build from sources + + + +* CMake +* C compiler (gcc, clang, mingw) +* Libusb 1.0 +* (optional) pandoc for generating manpages from markdown + +``` +$ mkdir build && cd build +$ cmake -DCMAKE_BUILD_TYPE=Debug .. +$ make +``` + +## Linux + +## Common requirements + +* Debian based distros (debian, ubuntu) + * `build-essential` +* `cmake` +* `libusb-1.0` (plus development headers for building, on debian based distros `libusb-1.0.0-dev` package) +* (optional) for `stlink-gui` we need libgtk-3-dev + +## Permissions with udev + +Make sure you install udev files which are necessary to run the tools without root + permissions. By default most distributions don't allow access to USB devices. The + udev rules create devices nodes and set the group of this to `stlink. + +The rules are located in the `etc/udev/rules.d` directory. You will need to copy it +to /etc/udev/rules.d, and then either execute as root (or reboot your machine): + +``` +$ udevadm control --reload-rules +$ udevadm trigger +``` + +Udev will now create device node files `/dev/stlinkv2_XX`, `/dev/stlinkv1_XX`. You must + make sure the `stlink` group exists and the user who is trying to access is added + to this group. + +### Note for STLINKv1 usage + +The STLINKv1's SCSI emulation is very broken, so the best thing to do +is tell your operating system to completely ignore it. + +Options (do one of these before you plug it in) + +* `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` +* or 1. `echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.conf` +* 2. `modprobe -r usb-storage && modprobe usb-storage` +* or 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` +* 2. `modprobe -r usb-storage && modprobe usb-storage` + +### Build Debian Package +To build debian package you need debuild. + +``` +$ git archive --prefix=$(git describe)/ HEAD | bzip2 --stdout > ../libstlink_$(sed -En -e "s/.*\((.*)\).*/\1/" -e "1,1 p" debian/changelog).orig.tar.bz2 +$ debuild -uc -us +``` From 7b359e2b95bbc439b18ec0a6ed8e084e8ed3ffbd Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 22 Oct 2016 10:22:44 +0200 Subject: [PATCH 0506/1435] doc/compiling.md: Add note on compiling for Mac OS X. Refs #499 --- doc/compiling.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/doc/compiling.md b/doc/compiling.md index 7021058fa..7ce1bfcc5 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -2,8 +2,6 @@ ## Build from sources - - * CMake * C compiler (gcc, clang, mingw) * Libusb 1.0 @@ -63,3 +61,21 @@ To build debian package you need debuild. $ git archive --prefix=$(git describe)/ HEAD | bzip2 --stdout > ../libstlink_$(sed -En -e "s/.*\((.*)\).*/\1/" -e "1,1 p" debian/changelog).orig.tar.bz2 $ debuild -uc -us ``` + +## Mac OS X + +When compiling on a mac you need the following: + +* A compiler toolchain (XCode) +* CMake +* Libusb 1.0 + +The best way is to install [homebrew](http://brew.sh) which is a package manager + for opensource software which is missing from the Apple App Store. Then install + the dependencies: + +``` +brew install libusb cmake +``` + +Compile as described in the first section of this document. From 78e849f0100694c45bc1ca255698bdb7f7a47f88 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 22 Oct 2016 10:24:24 +0200 Subject: [PATCH 0507/1435] README.md: Add not how to install on a mac with homebrew. Refs #499 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 267cf765a..a404e4204 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,8 @@ Arch Linux users can install from the [repository](https://www.archlinux.org/pac FreeBSD users can install from [freshports](https://www.freshports.org/devel/stlink) +Mac OS X users can install from [homebrew](http://brewformulas.org/Stlink) + **Compilation from source (advanced users)** When there is no executable available for your platform or you need the latest From 49248f598564dc81af23811201cbe2ea3bb65456 Mon Sep 17 00:00:00 2001 From: Christian Mauderer Date: Wed, 26 Oct 2016 20:40:25 +0200 Subject: [PATCH 0508/1435] Fix install locations for modprobe config and udev rules (#502) * cmake: Fix location of modprobe.d config. * cmake: Use cmake variables for install locations. This commit add the following two Cmake variables to change the install location of the udev and modprobe configuration files: - STLINK_UDEV_RULES_DIR - STLINK_MODPROBED_DIR * doc/compiling.md: Add info about new CMAKE variables. * debian: Use CMAKE variables for build. --- CMakeLists.txt | 6 ++++-- debian/rules | 3 ++- doc/compiling.md | 10 ++++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 04717e0a6..4aac51c05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required(VERSION 2.8.7) project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics Stlink Tools") +set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "Udev rules directory") +set(STLINK_MODPROBED_DIR "/etc/modprobe.d" CACHE PATH "modprobe.d directory") option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) @@ -131,9 +133,9 @@ install(TARGETS st-flash st-info if (CMAKE_SYSTEM_NAME STREQUAL "Linux") file(GLOB RULES_FILES etc/udev/rules.d/*.rules) install(FILES etc/modprobe.d/stlink_v1.conf - DESTINATION /etc) + DESTINATION ${STLINK_MODPROBED_DIR}/) install(FILES ${RULES_FILES} - DESTINATION /lib/udev/rules.d/) + DESTINATION ${STLINK_UDEV_RULES_DIR}/) endif() add_subdirectory(src/gdbserver) diff --git a/debian/rules b/debian/rules index 2b826772b..2ff7e59a8 100755 --- a/debian/rules +++ b/debian/rules @@ -24,4 +24,5 @@ include /usr/share/dpkg/default.mk # This is example for Cmake (See http://bugs.debian.org/641051 ) override_dh_auto_configure: dh_auto_configure -- \ - -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) + -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) \ + -DSTLINK_UDEV_RULES_DIR='/lib/udev/rules.d' diff --git a/doc/compiling.md b/doc/compiling.md index 7ce1bfcc5..c8a06dc86 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -79,3 +79,13 @@ brew install libusb cmake ``` Compile as described in the first section of this document. + +## Build using different directories for udev and modprobe + +To put the udev or the modprobe configuration files into a different directory +during installation you can use the following cmake options: + +``` +$ cmake -DSTLINK_UDEV_RULES_DIR="/usr/lib/udev/rules.d" \ + -DSTLINK_MODPROBED_DIR="/usr/lib/modprobe.d" .. +``` From be66bbf200c718904514b044ba84d64a36456218 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 29 Oct 2016 12:03:58 +0200 Subject: [PATCH 0509/1435] doc/compiling.md: Add note about installation and ldconfig. Fixes #478 --- doc/compiling.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/compiling.md b/doc/compiling.md index c8a06dc86..ff9e178b1 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -23,6 +23,10 @@ $ make * `libusb-1.0` (plus development headers for building, on debian based distros `libusb-1.0.0-dev` package) * (optional) for `stlink-gui` we need libgtk-3-dev +### Fixing cannot open shared object file + +When installing system-wide (`sudo make install`) the dynamic library cache needs to be updated with the command `ldconfig`. + ## Permissions with udev Make sure you install udev files which are necessary to run the tools without root From 76196d22c7fe0ad96c0eb81104400e37c322285a Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 29 Oct 2016 12:08:39 +0200 Subject: [PATCH 0510/1435] doc/compilation.md: Add note for user folder or system wide installation after compilation. Fixes #497 --- doc/compiling.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/doc/compiling.md b/doc/compiling.md index ff9e178b1..a102be1bd 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -7,12 +7,35 @@ * Libusb 1.0 * (optional) pandoc for generating manpages from markdown +Run from the root of the source directory: + +``` +$ make release +$ make debug +``` + +The debug target should only be necessary for people who want + to modify the sources and run under a debugger. +The top level Makefile is just a handy wrapper for: + ``` $ mkdir build && cd build $ cmake -DCMAKE_BUILD_TYPE=Debug .. $ make ``` +You could install to a user folder e.g `$HOME`: + +``` +$ cd release; make install DESTDIR=$HOME +``` + +Or system wide: + +``` +$ cd release; sudo make install +``` + ## Linux ## Common requirements From 9c0583756657047176b6b319ac0b470c4d418fd3 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 29 Oct 2016 12:20:10 +0200 Subject: [PATCH 0511/1435] README.md: Add missing features --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index a404e4204..177cb03b3 100644 --- a/README.md +++ b/README.md @@ -199,6 +199,13 @@ STLink v2-1 (as found on the Nucleo boards), known working targets: Please report any and all known working combinations so I can update this! +## Missing features + +* Control programming speed (See [#462](https://github.com/texane/stlink/issues/462)) +* OTP area programming (See [#202](https://github.com/texane/stlink/issues/202)) +* EEPROM area programming (See [#318](https://github.com/texane/stlink/issues/218)) +* Protection bits area reading (See [#346](https://github.com/texane/stlink/issues/346)) + ## Known bugs ### Sometimes flashing only works after a mass erase From 7ab464527e210264919e67fd67c68fd2d23e9803 Mon Sep 17 00:00:00 2001 From: Georg von Zengen Date: Thu, 3 Nov 2016 22:56:33 +0100 Subject: [PATCH 0512/1435] flash: added easy way to reset the target (#505) * flash: added easy way to reset the target st-flash does now have a 'reset' command makes it easy to reset the Target * Doc: added man page entry for reset command of st-flash --- doc/man/st-flash.md | 2 ++ include/stlink/tools/flash.h | 2 +- src/tools/flash.c | 12 ++++++++++++ src/tools/flash_opts.c | 4 ++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md index d294f05d1..4eacb7a07 100644 --- a/doc/man/st-flash.md +++ b/doc/man/st-flash.md @@ -32,6 +32,8 @@ read *FILE* *ADDR* *SIZE* erase : Perform a mass erasing of the device firmware +reset +: Reset the target # OPTIONS diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index dbc9ad881..bb7bd739e 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -7,7 +7,7 @@ #define DEBUG_LOG_LEVEL 100 #define STND_LOG_LEVEL 50 -enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3}; +enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3, CMD_RESET = 4}; enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1}; struct flash_opts { diff --git a/src/tools/flash.c b/src/tools/flash.c index 5cedb3815..1b6c7a7da 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -33,6 +33,7 @@ static void usage(void) puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); puts("stlinkv2 command line: ./st-flash [--debug] [--reset] [--serial ] [--format ] {read|write} "); puts("stlinkv2 command line: ./st-flash [--debug] [--serial ] erase"); + puts("stlinkv2 command line: ./st-flash [--debug] [--serial ] reset"); puts(" Use hex format for addr, and ."); puts(" Format may be 'binary' (default) or 'ihex', although must be specified for binary format only."); puts(" ./st-flash [--version]"); @@ -168,6 +169,17 @@ int main(int ac, char** av) printf("stlink_erase_flash_mass() == -1\n"); goto on_error; } + } else if (o.cmd == CMD_RESET) + { + if (stlink_jtag_reset(sl, 2)) { + printf("Failed to reset JTAG\n"); + goto on_error; + } + + if (stlink_reset(sl)) { + printf("Failed to reset device\n"); + goto on_error; + } } else /* read */ { diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 1a0d0cd9b..1ccf55334 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -99,6 +99,10 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) if (o->cmd != FLASH_CMD_NONE) return -1; o->cmd = FLASH_CMD_WRITE; } + else if (strcmp(av[0], "reset") == 0) { + if (o->cmd != FLASH_CMD_NONE) return -1; + o->cmd = CMD_RESET; + } else if(starts_with(av[0], "/dev/")) { if (o->devname) return -1; o->devname = av[0]; From 470fc2b309be91b7e0ee9e01bfb60128ec5ae5be Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Mon, 7 Nov 2016 11:49:16 +0200 Subject: [PATCH 0513/1435] fix cmake wrong libusb extract command for windows (fixes #511) --- cmake/modules/FindLibUSB.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index 45472b96e..84020b98b 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -24,7 +24,7 @@ if(WIN32 OR CMAKE_VS_PLATFORM_NAME OR MINGW OR MSYS) ) endif() file(MAKE_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) - execute_process(COMMAND ${ZIP_LOCATION} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER}) + execute_process(COMMAND ${ZIP_EXECUTABLE} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER}) endif() # FreeBSD From 3de5cf05619926e09e885f8980478a0c128a0f08 Mon Sep 17 00:00:00 2001 From: "fabien.lementec" Date: Tue, 22 Nov 2016 07:45:55 +0100 Subject: [PATCH 0514/1435] README.md: Add STM32F411E-DISCO --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 177cb03b3..b68731844 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,7 @@ STLink v2 (as found on the 32L and F4 Discovery boards), known working targets: * STM32L151CB (custom board) * STM32L152RB (STM32L-Discovery board, custom board) * STM32F051R8T6 (STM320518-EVAL board) +* STM32F411E-DISCO (STM32F4 Discovery board with gyro, audio) STLink v2-1 (as found on the Nucleo boards), known working targets: From 0c63a2cffc7b7fca817d4c7fb896dbe696341ea3 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Mon, 5 Dec 2016 17:36:37 +0100 Subject: [PATCH 0515/1435] cmake/Version.cmake: Fix version detection when building from zipfile (non-git tree). Fixes #523 --- cmake/Version.cmake | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/cmake/Version.cmake b/cmake/Version.cmake index 957e29ca4..bb01315ab 100644 --- a/cmake/Version.cmake +++ b/cmake/Version.cmake @@ -20,15 +20,15 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") if (res EQUAL 1) set (PROJECT_VERSION "${PROJECT_VERSION}-dirty") endif() -endif() -string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" - "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) -list(LENGTH PROJECT_VERSION_LIST len) -if(len EQUAL 3) - list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) - list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) - list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) + string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" + "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) + list(LENGTH PROJECT_VERSION_LIST len) + if(len EQUAL 3) + list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) + list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) + list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) + endif() elseif(EXISTS ${PROJECT_SOURCE_DIR}/.version) # If git is not available (e.g. when building from source package) # we can extract the package version from .version file. @@ -44,7 +44,5 @@ else() message(FATAL_ERROR "Unable to determine project version") endif() -if (${CMAKE_BUILD_TYPE} MATCHES "Debug") - message(STATUS "stlink version: ${PROJECT_VERSION}") - message(STATUS " Major ${PROJECT_VERSION_MAJOR} Minor ${PROJECT_VERSION_MINOR} Patch ${PROJECT_VERSION_PATCH}") -endif() +message(STATUS "stlink version: ${PROJECT_VERSION}") +message(STATUS " Major ${PROJECT_VERSION_MAJOR} Minor ${PROJECT_VERSION_MINOR} Patch ${PROJECT_VERSION_PATCH}") From 0879af2edc06e66813f2bddef04bc8640f2aeb56 Mon Sep 17 00:00:00 2001 From: Greg Alexander Date: Sat, 10 Dec 2016 14:01:59 -0500 Subject: [PATCH 0516/1435] don't return stale value from gdb-server "read memory" command if the underlying transport fails, and return an error code if the gdb-server "write memory" command fails --- src/gdbserver/gdb-server.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 339cd1130..dd9f34daf 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -1509,7 +1509,10 @@ int serve(stlink_t *sl, st_state_t *st) { if (count_rnd < count) count = count_rnd; - stlink_read_mem32(sl, start - adj_start, count_rnd); + if (stlink_read_mem32(sl, start - adj_start, count_rnd) != 0) { + /* read failed somehow, don't return stale buffer */ + count = 0; + } reply = calloc(count * 2 + 1, 1); for(unsigned int i = 0; i < count; i++) { @@ -1527,6 +1530,7 @@ int serve(stlink_t *sl, st_state_t *st) { stm32_addr_t start = (stm32_addr_t) strtoul(s_start, NULL, 16); unsigned count = (unsigned) strtoul(s_count, NULL, 16); + int err = 0; if(start % 4) { unsigned align_count = 4 - start % 4; @@ -1536,7 +1540,7 @@ int serve(stlink_t *sl, st_state_t *st) { uint8_t byte = strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; } - stlink_write_mem8(sl, start, align_count); + err |= stlink_write_mem8(sl, start, align_count); cache_change(start, align_count); start += align_count; count -= align_count; @@ -1551,7 +1555,7 @@ int serve(stlink_t *sl, st_state_t *st) { uint8_t byte = strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; } - stlink_write_mem32(sl, start, aligned_count); + err |= stlink_write_mem32(sl, start, aligned_count); cache_change(start, aligned_count); count -= aligned_count; start += aligned_count; @@ -1564,10 +1568,10 @@ int serve(stlink_t *sl, st_state_t *st) { uint8_t byte = strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; } - stlink_write_mem8(sl, start, count); + err |= stlink_write_mem8(sl, start, count); cache_change(start, count); } - reply = strdup("OK"); + reply = strdup(err ? "E00" : "OK"); break; } From 98044163ab34bf5159f121d1c49ffb3550321ca0 Mon Sep 17 00:00:00 2001 From: Greg Alexander Date: Sat, 10 Dec 2016 15:45:11 -0500 Subject: [PATCH 0517/1435] Add 'k' (kill) command to gdb-server, which completely resets the connection. --- src/gdbserver/gdb-server.c | 49 ++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 339cd1130..8a808f10d 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -69,6 +69,19 @@ static void cleanup(int signum) { } +static stlink_t* do_connect(st_state_t *st) { + stlink_t *ret = NULL; + switch (st->stlink_version) { + case 2: + ret = stlink_open_usb(st->logging_level, st->reset, NULL); + break; + case 1: + ret = stlink_v1_open(st->logging_level, st->reset); + break; + } + return ret; +} + int parse_options(int argc, char** argv, st_state_t *st) { static struct option long_options[] = { @@ -183,16 +196,8 @@ int main(int argc, char** argv) { printf("st-util %s\n", STLINK_VERSION); - switch (state.stlink_version) { - case 2: - sl = stlink_open_usb(state.logging_level, state.reset, NULL); - if(sl == NULL) return 1; - break; - case 1: - sl = stlink_v1_open(state.logging_level, state.reset); - if(sl == NULL) return 1; - break; - } + sl = do_connect(&state); + if(sl == NULL) return 1; connected_stlink = sl; signal(SIGINT, &cleanup); @@ -224,6 +229,9 @@ int main(int argc, char** argv) { sleep (1); // don't go bezurk if serve returns with error } + /* in case serve() changed the connection */ + sl = connected_stlink; + /* Continue */ stlink_run(sl); } while (state.persistent); @@ -1667,6 +1675,27 @@ int serve(stlink_t *sl, st_state_t *st) { break; } + case 'k': + /* Kill request - reset the connection itself */ + stlink_run(sl); + stlink_exit_debug_mode(sl); + stlink_close(sl); + + sl = do_connect(st); + if(sl == NULL) cleanup(0); + connected_stlink = sl; + + if (st->reset) { + stlink_reset(sl); + } + stlink_force_debug(sl); + init_cache(sl); + init_code_breakpoints(sl); + init_data_watchpoints(sl); + + reply = NULL; /* no response */ + + break; default: reply = strdup(""); From c06a7737bd13556d9a4e22862766e152a1a9f37e Mon Sep 17 00:00:00 2001 From: Peter Mortensen Date: Sun, 11 Dec 2016 13:18:48 +0100 Subject: [PATCH 0518/1435] Update README.md Copy edited (e.g. ref. and ) --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b68731844..1c66d9308 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Open source version of the STMicroelectronics Stlink Tools First, you have to know there are several boards supported by the software. Those boards use a chip to translate from USB to JTAG commands. The chip is -called stlink and there are 2 versions: +called stlink and there are two versions: * STLINKv1, present on STM32VL discovery kits, * STLINKv2, present on STM32L discovery and later kits. @@ -24,10 +24,10 @@ Two different transport layers are used: ## Installation -Currently there are no binaries for windows available. +Currently there are no binaries for Windows available. It is known to compile and work with MinGW/Cygwin. -For debian linux based distros there is also no package available +For Debian Linux based distributions there is also no package available in the standard repositories so you need to compile yourself. Arch Linux users can install from the [repository](https://www.archlinux.org/packages/community/x86_64/stlink) @@ -69,7 +69,7 @@ There are a few options: ``` The STLINKv2 device to use can be specified in the environment -variable `STLINK_DEVICE` on the format `:`. +variable `STLINK_DEVICE` in the format `:`. Then, in your project directory, someting like this... (remember, you need to run an _ARM_ gdb, not an x86 gdb) From 8efa16bdd525618999d3e6a583edeb3d7c6ba4bb Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 11 Dec 2016 13:48:55 +0100 Subject: [PATCH 0519/1435] remove warning --- src/tools/flash_opts.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 1ccf55334..46c0d853c 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -153,6 +153,8 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) return -1; } break; + + default: break ; } // some constistence checks From c44182465a7f5676dc30d4b99110919f8000a6fe Mon Sep 17 00:00:00 2001 From: jkhax0r Date: Fri, 30 Dec 2016 05:00:27 -0600 Subject: [PATCH 0520/1435] Set SWDCLK and fix jtag_reset bug (#534) * - Fixed bug where stlink_jtag_reset in stlink_open_usb() was never being called because the STLINK version was being checked before it had been initialized - Added support for stlink_set_swdclk() to adjust the SWD clock speed. For example, to set at 4Mhz, 1.8Mhz, 900Khz, etc similar to in the official ST-LINK utility. NOTE: The default when STLINK is powered appears to be 1.8Mhz (looked at scope traces) but it retains whatever was set before. * Fixed tab->space --- include/stlink.h | 19 +++++++++++++++++++ include/stlink/backend.h | 1 + src/common.c | 5 +++++ src/usb.c | 40 ++++++++++++++++++++++++++++++++++++++-- 4 files changed, 63 insertions(+), 2 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 674aa3b28..813086e15 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -48,6 +48,8 @@ extern "C" { #define STLINK_JTAG_READDEBUG_32BIT 0x36 #define STLINK_JTAG_DRIVE_NRST 0x3c +#define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43 + /* cortex core ids */ // TODO clean this up... #define STM32VL_CORE_ID 0x1ba01477 @@ -57,6 +59,22 @@ extern "C" { #define STM32_FLASH_BASE 0x08000000 #define STM32_SRAM_BASE 0x20000000 +// Baud rate divisors for SWDCLK +#define STLINK_SWDCLK_4MHZ_DIVISOR 0 +#define STLINK_SWDCLK_1P8MHZ_DIVISOR 1 +#define STLINK_SWDCLK_1P2MHZ_DIVISOR 2 +#define STLINK_SWDCLK_950KHZ_DIVISOR 3 +#define STLINK_SWDCLK_480KHZ_DIVISOR 7 +#define STLINK_SWDCLK_240KHZ_DIVISOR 15 +#define STLINK_SWDCLK_125KHZ_DIVISOR 31 +#define STLINK_SWDCLK_100KHZ_DIVISOR 40 +#define STLINK_SWDCLK_50KHZ_DIVISOR 79 +#define STLINK_SWDCLK_25KHZ_DIVISOR 158 +#define STLINK_SWDCLK_15KHZ_DIVISOR 265 +#define STLINK_SWDCLK_5KHZ_DIVISOR 798 + + + /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ #define C_BUF_LEN 32 @@ -177,6 +195,7 @@ typedef struct flash_loader { int stlink_current_mode(stlink_t *sl); int stlink_force_debug(stlink_t *sl); int stlink_target_voltage(stlink_t *sl); + int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); int stlink_erase_flash_mass(stlink_t* sl); int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); diff --git a/include/stlink/backend.h b/include/stlink/backend.h index d1b7648e4..42d12d4ac 100644 --- a/include/stlink/backend.h +++ b/include/stlink/backend.h @@ -28,6 +28,7 @@ int (*current_mode) (stlink_t * stl); int (*force_debug) (stlink_t *sl); int32_t (*target_voltage) (stlink_t *sl); + int (*set_swdclk) (stlink_t * stl, uint16_t divisor); } stlink_backend_t; #endif /* STLINK_BACKEND_H_ */ diff --git a/src/common.c b/src/common.c index e8cdf3ba9..7a47ac813 100644 --- a/src/common.c +++ b/src/common.c @@ -642,6 +642,11 @@ int stlink_run(stlink_t *sl) { return sl->backend->run(sl); } +int stlink_set_swdclk(stlink_t *sl, uint16_t divisor) { + DLOG("*** set_swdclk ***\n"); + return sl->backend->set_swdclk(sl, divisor); +} + int stlink_status(stlink_t *sl) { int ret; diff --git a/src/usb.c b/src/usb.c index f32b2e04c..4b57ed98f 100644 --- a/src/usb.c +++ b/src/usb.c @@ -449,6 +449,36 @@ int _stlink_usb_run(stlink_t* sl) { return 0; } + +int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + int rep_len = 2; + int i; + + // clock speed only supported by stlink/v2 and for firmware >= 22 + if (sl->version.stlink_v >= 2 && sl->version.jtag_v >= 22) { + i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_APIV2_SWD_SET_FREQ; + cmd[i++] = clk_divisor & 0xFF; + cmd[i++] = (clk_divisor >> 8) & 0xFF; + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { + printf("[!] send_recv STLINK_DEBUG_APIV2_SWD_SET_FREQ\n"); + return (int) size; + } + + return 0; + } else { + return -1; + } +} + int _stlink_usb_exit_debug_mode(stlink_t *sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; @@ -724,7 +754,8 @@ static stlink_backend_t _stlink_usb_backend = { _stlink_usb_step, _stlink_usb_current_mode, _stlink_usb_force_debug, - _stlink_usb_target_voltage + _stlink_usb_target_voltage, + _stlink_usb_set_swdclk }; stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16]) @@ -878,6 +909,9 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } + + // Initialize stlink version (sl->version) + stlink_version(sl); if (reset) { if( sl->version.stlink_v > 1 ) stlink_jtag_reset(sl, 2); @@ -885,9 +919,11 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 usleep(10000); } - stlink_version(sl); ret = stlink_load_device_params(sl); + // Set the stlink clock speed (default is 1800kHz) + stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); + on_libusb_error: if (ret == -1) { stlink_close(sl); From e761a47fc405c6617d180371f1d1993564a45037 Mon Sep 17 00:00:00 2001 From: night-ghost Date: Fri, 30 Dec 2016 16:15:20 +0500 Subject: [PATCH 0521/1435] Reset flash MER bit after mass erase Otherwise all subsequent erases before turning off the power will be mass erases (#489) --- src/common.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/common.c b/src/common.c index 7a47ac813..f104a1629 100644 --- a/src/common.c +++ b/src/common.c @@ -298,7 +298,7 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { stlink_write_debug32(sl, FLASH_CR, n); } -static void set_flash_cr_mer(stlink_t *sl) { +static void set_flash_cr_mer(stlink_t *sl, bool v) { uint32_t val, cr_reg, cr_mer, cr_pg; if (sl->flash_type == STLINK_FLASH_TYPE_F4) { @@ -322,7 +322,10 @@ static void set_flash_cr_mer(stlink_t *sl) { stlink_write_debug32(sl, cr_reg, val); } - val |= cr_mer; + if(v) + val |= cr_mer; + else + val &= ~cr_mer; stlink_write_debug32(sl, cr_reg, val); } @@ -1582,7 +1585,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { unlock_flash_if(sl); /* set the mass erase bit */ - set_flash_cr_mer(sl); + set_flash_cr_mer(sl,1); /* start erase operation, reset by hw with bsy bit */ set_flash_cr_strt(sl); @@ -1593,6 +1596,9 @@ int stlink_erase_flash_mass(stlink_t *sl) { /* relock the flash */ lock_flash(sl); + /* reset the mass erase bit */ + set_flash_cr_mer(sl,0); + /* todo: verify the erased memory */ } return 0; From 980962dcedf153f55d7746f01fb8b8d216245357 Mon Sep 17 00:00:00 2001 From: texane Date: Fri, 30 Dec 2016 14:29:19 +0100 Subject: [PATCH 0522/1435] add Nucleo-L152RE board --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1c66d9308..bf5c23831 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,7 @@ STLink v2-1 (as found on the Nucleo boards), known working targets: * STM32F756NGHx (STMF7 evaluation board) * STM32L053R8 (STM32 Nucleo-L053R8 board) * STM32F769NI (STM32F7 discovery board) +* Nucleo-L152RE board Please report any and all known working combinations so I can update this! From 01b9e1682104386a0dc092f9f2481a13d599ca93 Mon Sep 17 00:00:00 2001 From: Andreas Date: Tue, 3 Jan 2017 01:00:56 +0400 Subject: [PATCH 0523/1435] Add support for STM32F412 (#538) --- include/stlink/chipid.h | 1 + src/chipid.c | 14 +++++++++++++- src/flash_loader.c | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 18f02782c..36fb73c62 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -46,6 +46,7 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F334 = 0x438, STLINK_CHIPID_STM32_F3_SMALL = 0x439, STLINK_CHIPID_STM32_F0 = 0x440, + STLINK_CHIPID_STM32_F412 = 0x441, STLINK_CHIPID_STM32_F09X = 0x442, STLINK_CHIPID_STM32_F0_SMALL = 0x444, STLINK_CHIPID_STM32_F04 = 0x445, diff --git a/src/chipid.c b/src/chipid.c index c6bcf70bb..13307a99e 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -286,7 +286,19 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 }, - { + { + // RM0402 document was used to find these parameters + // Table 4. + .chip_id = STLINK_CHIPID_STM32_F412, + .description = "F4 device", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) + .flash_pagesize = 0x4000, // Table 5. Flash module organization ? + .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 + .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 + .bootrom_size = 0x7800 // "System memory" byte size in hex from Table 4 + }, + { .chip_id = STLINK_CHIPID_STM32_F09X, .description = "F09X device", .flash_type = STLINK_FLASH_TYPE_F0, diff --git a/src/flash_loader.c b/src/flash_loader.c index 77ebd95eb..f4d81cbab 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -218,6 +218,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || sl->chip_id == STLINK_CHIPID_STM32_F410 || sl->chip_id == STLINK_CHIPID_STM32_F411RE || + sl->chip_id == STLINK_CHIPID_STM32_F412 || sl->chip_id == STLINK_CHIPID_STM32_F446 ) { if( sl->version.stlink_v == 1 ) { From 55fddc2e55629a6d588976f087d5abbfb2f7b88f Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 5 Jan 2017 22:57:01 +0100 Subject: [PATCH 0524/1435] Update README.md Add note about windows binaries (refs #166) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bf5c23831..880083a68 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Two different transport layers are used: ## Installation -Currently there are no binaries for Windows available. +Currently there are no binaries for Windows available (see issue [#166](https://github.com/texane/stlink/issues/166)). It is known to compile and work with MinGW/Cygwin. For Debian Linux based distributions there is also no package available From ba898b1c9c75800b566e8b1983ff7643e104a994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torstein=20Huseb=C3=B8?= Date: Mon, 9 Jan 2017 16:13:16 +0100 Subject: [PATCH 0525/1435] after 4c69cae257e317e9297f5a89eed940313b9c25c2 a compile produces the (#539) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit following warning: warning: missing initializer for field ‘set_swdclk’ of ‘stlink_backend_t {aka struct _stlink_backend}’ [-Wmissing-field-initializers] silence the warning and expand comment --- src/sg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sg.c b/src/sg.c index 22464bc1b..541ef5550 100644 --- a/src/sg.c +++ b/src/sg.c @@ -933,7 +933,8 @@ static stlink_backend_t _stlink_sg_backend = { _stlink_sg_step, _stlink_sg_current_mode, _stlink_sg_force_debug, - NULL + NULL, /* target_voltage */ + NULL /* set_swdclk */ }; static stlink_t* stlink_open(const int verbose) { From 0106c53821e144828a81b21b162a976302561265 Mon Sep 17 00:00:00 2001 From: GagoSoft Date: Tue, 10 Jan 2017 17:18:59 +0100 Subject: [PATCH 0526/1435] Support serial numbers in st-util and st-flash (#541) Support multiple stlink programmers by passing the serial number as a commandline argument. Fixes #318. --- src/gdbserver/gdb-server.c | 26 +++++++++++++++++++++++++- src/tools/flash_opts.c | 3 ++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index d71d8c9a6..fddf48fcf 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -30,12 +30,15 @@ /* Semihosting doesn't have a short option, we define a value to identify it */ #define SEMIHOSTING_OPTION 128 +#define SERIAL_OPTION 127 //Allways update the FLASH_PAGE before each use, by calling stlink_calculate_pagesize #define FLASH_PAGE (sl->flash_pgsz) static stlink_t *connected_stlink = NULL; static bool semihosting = false; +static bool serial_specified = false; +static char serialnumber[28] = {0}; static const char hex[] = "0123456789abcdef"; @@ -73,7 +76,12 @@ static stlink_t* do_connect(st_state_t *st) { stlink_t *ret = NULL; switch (st->stlink_version) { case 2: - ret = stlink_open_usb(st->logging_level, st->reset, NULL); + if(serial_specified){ + ret = stlink_open_usb(st->logging_level, st->reset, serialnumber); + } + else{ + ret = stlink_open_usb(st->logging_level, st->reset, NULL); + } break; case 1: ret = stlink_v1_open(st->logging_level, st->reset); @@ -94,6 +102,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { {"no-reset", optional_argument, NULL, 'n'}, {"version", no_argument, NULL, 'V'}, {"semihosting", no_argument, NULL, SEMIHOSTING_OPTION}, + {"serial", required_argument, NULL, SERIAL_OPTION}, {0, 0, 0, 0}, }; const char * help_str = "%s - usage:\n\n" @@ -114,6 +123,8 @@ int parse_options(int argc, char** argv, st_state_t *st) { "\t\t\tDo not reset board on connection.\n" " --semihosting\n" "\t\t\tEnable semihosting support.\n" + " --serial \n" + "\t\t\tUse a specific serial number.\n" "\n" "The STLINKv2 device to use can be specified in the environment\n" "variable STLINK_DEVICE on the format :.\n" @@ -170,6 +181,19 @@ int parse_options(int argc, char** argv, st_state_t *st) { case SEMIHOSTING_OPTION: semihosting = true; break; + case SERIAL_OPTION: + printf("use serial %s\n",optarg); + /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ + int j = (int)strlen(optarg); + int length = j / 2; //the length of the destination-array + if(j % 2 != 0) return -1; + for(size_t k = 0; j >= 0 && k < sizeof(serialnumber); ++k, j -= 2) { + char buffer[3] = {0}; + memcpy(buffer, optarg + j, 2); + serialnumber[length - k] = (uint8_t)strtol(buffer, NULL, 16); + } + serial_specified = true; + break; } } diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 46c0d853c..c98424348 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -47,12 +47,13 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ int j = (int)strlen(serial); + int length = j / 2; //the length of the destination-array if(j % 2 != 0) return -1; for(size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { char buffer[3] = {0}; memcpy(buffer, serial + j, 2); - o->serial[12 - k] = (uint8_t)strtol(buffer, NULL, 16); + o->serial[length - k] = (uint8_t)strtol(buffer, NULL, 16); } serial_specified = true; From 8253cf1b882314aafb466d85b1a7c9eb6334b61f Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 14 Jan 2017 15:02:36 +0100 Subject: [PATCH 0527/1435] Add tested NUCLEO-L476RG board. Fixes #521 --- README.md | 47 +-------------------------------------- doc/tested-boards.md | 52 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 46 deletions(-) create mode 100644 doc/tested-boards.md diff --git a/README.md b/README.md index 880083a68..c22ef3651 100644 --- a/README.md +++ b/README.md @@ -154,52 +154,7 @@ GDB. Memory map parsing thus fail. Use --enable-expat. ## Currently known working combinations of programmer and target -STLink v1 (as found on the 32VL Discovery board) - -Known working targets: - -* STM32F100xx (Medium Density VL) -* STM32F103 (according to jpa- on ##stm32) - -No information: - -* everything else! - -STLink v2 (as found on the 32L and F4 Discovery boards), known working targets: - -* STM32F030F4P6 (custom board) -* STM32F0Discovery (STM32F0 Discovery board) -* STM32F100xx (Medium Density VL, as on the 32VL Discovery board) -* STM32L1xx (STM32L Discovery board) -* STM32F103VC, STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on custom boards - from [UweBonnes/wiki_fuer_alex](https://github.com/UweBonnes/wiki_fuer_alex/tree/master/layout) -* STM32F103VET6 (HY-STM32 board) -* STM32F105RCT6 (DecaWave EVB1000 board) -* STM32F303xx (STM32F3 Discovery board) -* STM32F407xx (STM32F4 Discovery board) -* STM32F429I-DISCO (STM32F4 Discovery board with LCD) -* STM32F439VIT6 (discovery board reseated CPU) -* STM32L052K8T6 (custom board) -* STM32L151CB (custom board) -* STM32L152RB (STM32L-Discovery board, custom board) -* STM32F051R8T6 (STM320518-EVAL board) -* STM32F411E-DISCO (STM32F4 Discovery board with gyro, audio) - -STLink v2-1 (as found on the Nucleo boards), known working targets: - -* STM32F401xx (STM32 Nucleo-F401RE board) -* STM32F030R8T6 (STM32 Nucleo-F030R8 board) -* STM32F072RBT6 (STM32 Nucleo-F072RB board) -* STM32F103RB (STM32 Nucleo-F103RB board) -* STM32F303RET6 (STM32 Nucleo-F303RE board) -* STM32F334R8 (STM32 Nucleo-F334R8 board) -* STM32F411RET6 (STM32 Nucleo-F411RE board) -* STM32F756NGHx (STMF7 evaluation board) -* STM32L053R8 (STM32 Nucleo-L053R8 board) -* STM32F769NI (STM32F7 discovery board) -* Nucleo-L152RE board - -Please report any and all known working combinations so I can update this! +See [doc/tested-boards.md](doc/tested-boards.md) ## Missing features diff --git a/doc/tested-boards.md b/doc/tested-boards.md new file mode 100644 index 000000000..7c16062dd --- /dev/null +++ b/doc/tested-boards.md @@ -0,0 +1,52 @@ +Stlink tested and compatible boards +=================================== + +STLink v1 (as found on the 32VL Discovery board) + +Known working targets: + +* STM32F100xx (Medium Density VL) +* STM32F103 (according to jpa- on ##stm32) + +No information: + +* everything else! + +STLink v2 (as found on the 32L and F4 Discovery boards), known working targets: + +* STM32F030F4P6 (custom board) +* STM32F0Discovery (STM32F0 Discovery board) +* STM32F100xx (Medium Density VL, as on the 32VL Discovery board) +* STM32L1xx (STM32L Discovery board) +* STM32F103VC, STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on custom boards + from [UweBonnes/wiki_fuer_alex](https://github.com/UweBonnes/wiki_fuer_alex/tree/master/layout) +* STM32F103VET6 (HY-STM32 board) +* STM32F105RCT6 (DecaWave EVB1000 board) +* STM32F303xx (STM32F3 Discovery board) +* STM32F407xx (STM32F4 Discovery board) +* STM32F429I-DISCO (STM32F4 Discovery board with LCD) +* STM32F439VIT6 (discovery board reseated CPU) +* STM32L052K8T6 (custom board) +* STM32L151CB (custom board) +* STM32L152RB (STM32L-Discovery board, custom board) +* STM32F051R8T6 (STM320518-EVAL board) +* STM32F411E-DISCO (STM32F4 Discovery board with gyro, audio) + +STLink v2-1 (as found on the Nucleo boards), known working targets: + +* STM32F401xx (STM32 Nucleo-F401RE board) +* STM32F030R8T6 (STM32 Nucleo-F030R8 board) +* STM32F072RBT6 (STM32 Nucleo-F072RB board) +* STM32F103RB (STM32 Nucleo-F103RB board) +* STM32F303RET6 (STM32 Nucleo-F303RE board) +* STM32F334R8 (STM32 Nucleo-F334R8 board) +* STM32F411RET6 (STM32 Nucleo-F411RE board) +* STM32F756NGHx (STMF7 evaluation board) +* STM32L053R8 (STM32 Nucleo-L053R8 board) +* STM32F769NI (STM32F7 discovery board) +* Nucleo-L152RE board +* [Nucleo-L476RG board](http://www.st.com/en/evaluation-tools/nucleo-l476rg.html) + +Please report any and all known working combinations so I can update this! + + From 2cb33d45a84179ccc0d13725c93e010e0042f866 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 14 Jan 2017 15:05:26 +0100 Subject: [PATCH 0528/1435] Add note about debhelper for compiling the debian package. Fixes #520 --- doc/compiling.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/compiling.md b/doc/compiling.md index a102be1bd..3a3a38826 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -82,7 +82,8 @@ Options (do one of these before you plug it in) * 2. `modprobe -r usb-storage && modprobe usb-storage` ### Build Debian Package -To build debian package you need debuild. + +To build the debian package you need the following extra packages: `debuild debhelper`. ``` $ git archive --prefix=$(git describe)/ HEAD | bzip2 --stdout > ../libstlink_$(sed -En -e "s/.*\((.*)\).*/\1/" -e "1,1 p" debian/changelog).orig.tar.bz2 From e45451500c8eba96323a76d0a4a75b27c018589d Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 14 Jan 2017 15:08:54 +0100 Subject: [PATCH 0529/1435] README.md: Add missing feature of MCU hotplug. Refs #449 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c22ef3651..a6f126445 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,7 @@ See [doc/tested-boards.md](doc/tested-boards.md) * OTP area programming (See [#202](https://github.com/texane/stlink/issues/202)) * EEPROM area programming (See [#318](https://github.com/texane/stlink/issues/218)) * Protection bits area reading (See [#346](https://github.com/texane/stlink/issues/346)) +* MCU hotplug (See [#449](https://github.com/texane/stlink/issues/449)) ## Known bugs From 77acc50705b6f692721f8a1b22ef684ac4143483 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 14 Jan 2017 15:48:22 +0100 Subject: [PATCH 0530/1435] README.md: Improve first-time user documentation --- README.md | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a6f126445..45a5de82d 100644 --- a/README.md +++ b/README.md @@ -20,15 +20,15 @@ called stlink and there are two versions: Two different transport layers are used: * STLINKv1 uses SCSI passthru commands over USB -* STLINKv2 uses raw USB commands. +* STLINKv2 and STLINKv2-1 (seen on nucleo boards) uses raw USB commands. ## Installation Currently there are no binaries for Windows available (see issue [#166](https://github.com/texane/stlink/issues/166)). - It is known to compile and work with MinGW/Cygwin. + It is known to compile and work with MinGW(64)/Cygwin environment. Building with Visual Studio is not supported because the project uses POSIX APIs and probably will never change. -For Debian Linux based distributions there is also no package available - in the standard repositories so you need to compile yourself. +For Debian Linux based distributions there is no package available + in the standard repositories so you need to install [from source](doc/compiling.md) yourself. Arch Linux users can install from the [repository](https://www.archlinux.org/packages/community/x86_64/stlink) @@ -36,7 +36,9 @@ FreeBSD users can install from [freshports](https://www.freshports.org/devel/stl Mac OS X users can install from [homebrew](http://brewformulas.org/Stlink) -**Compilation from source (advanced users)** +OpenBSD users need to install [from source](doc/compiling.md). + +## Installation from source (advanced users) When there is no executable available for your platform or you need the latest (possible unstable) version you need to compile yourself. This is explained in @@ -156,13 +158,19 @@ GDB. Memory map parsing thus fail. Use --enable-expat. See [doc/tested-boards.md](doc/tested-boards.md) -## Missing features +## Known missing features + +Some features are missing from the `texane/stlink` project and we would like you to + help us out if you want to get involved: * Control programming speed (See [#462](https://github.com/texane/stlink/issues/462)) * OTP area programming (See [#202](https://github.com/texane/stlink/issues/202)) * EEPROM area programming (See [#318](https://github.com/texane/stlink/issues/218)) * Protection bits area reading (See [#346](https://github.com/texane/stlink/issues/346)) * MCU hotplug (See [#449](https://github.com/texane/stlink/issues/449)) +* Writing options bytes (region) (See [#458](https://github.com/texane/stlink/issues/458)) +* Instrumentation Trace Macro (ITM) Cell (See [#136](https://github.com/texane/stlink/issues/136)) +* Writing external memory connected to an STM32 controller (e.g Quad SPI NOR flash) (See [#412](https://github.com/texane/stlink/issues/412)) ## Known bugs @@ -177,15 +185,14 @@ of the flash: 2015-12-09T22:02:18 ERROR src/stlink-common.c: run_flash_loader(0x8000000) failed! == -1 ``` -Issue(s): [#356](https://github.com/texane/stlink/issues/356) +Issue related to this bug: [#356](https://github.com/texane/stlink/issues/356) ## Contributing and versioning * The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) -* When creating a pull request, please open first a issue for discussion of new features -* TODO: Enforcement of coding style (linux codestyle + checkpatch) +* When creating a pull request, please open first a issue for discussion of new features. Bugfixes don't need a discussion. ## License The stlink library and tools are licensed under the [BSD license](LICENSE). With -some exceptions on external components. +some exceptions on external components (e.g flashloaders). From bf1b81b93077ae1c3eadc5d5accc47293ff7f375 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 28 Jan 2017 10:12:53 +0100 Subject: [PATCH 0531/1435] Prepare for v1.3.0 release, update ChangeLog.md --- .version | 2 +- ChangeLog.md | 36 ++++++++++++++++++++++++------------ cmake/CPackConfig.cmake | 8 ++++---- doc/compiling.md | 4 ++-- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/.version b/.version index b6bb93f7c..f0bb29e76 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.3.0-dev +1.3.0 diff --git a/ChangeLog.md b/ChangeLog.md index fead8b8ec..32c733b03 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -4,28 +4,40 @@ Stlink ChangeLog v1.3.0 ====== -Release date: ongoing +Release date: 2017-01-28 -Major changes: +Major changes and added features: -* Deprecation of autotools (autoconf, automake) (Jerry Jacobs) -* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature (Jerry Jacobs) -* Add debian packaging (nekromant) -* Add intel hex file reading for `st-flash` (pull-request #459) (dev26th) +* Deprecation of autotools (autoconf, automake) (@xor-gate) +* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#3fd0f09](https://github.com/texane/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) +* Add support for native debian packaging ([#444](https://github.com/texane/stlink/pull/444), [#485](https://github.com/texane/stlink/pull/485)) +* Add intel hex file reading for `st-flash` ([#459](https://github.com/texane/stlink/pull/541)) +* Add `--reset` command to `st-flash` ([#505](https://github.com/texane/stlink/pull/505)) +* Support serial numbers argument for `st-util` and `st-flash` for multi-programmer setups ([#541](https://github.com/texane/stlink/pull/541)) +* Add kill ('k') command to gdb-server for `st-util` ([#9804416](https://github.com/texane/stlink/commit/98044163ab34bf5159f121d1c49ffb3550321ca0)) +* Add manpages (generated with pandoc from Markdown) ([#464](https://github.com/texane/stlink/pull/464)) +* Rewrite commandline parsing for `st-flash` ([#459](https://github.com/texane/stlink/pull/459)) +* Add support for ARM semihosting to `st-util` ([#454](https://github.com/texane/stlink/pull/454), [#455](https://github.com/texane/stlink/pull/455)) Chip support added for: -* STM32F410 (Jerry Jacobs) -* L0x Category 5 devices (gluedig) -* Add L0 Category 2 device (chip id: 0x425) (Áron RADICS) +* STM32L432 ([#501](https://github.com/texane/stlink/pull/501)) +* STM32F412 ([#538](https://github.com/texane/stlink/pull/538)) +* STM32F410 ([#9c635e4](https://github.com/texane/stlink/commit/9c635e419deca697ff823000aad2e39d47ec8d6c)) +* Add memory map for STM32F401XE ([#460](https://github.com/texane/stlink/pull/460)) +* L0x Category 5 devices ([#406](https://github.com/texane/stlink/pull/406)) +* Add L0 Category 2 device (chip id: 0x425) ([#72b8e5e](https://github.com/texane/stlink/commit/72b8e5ec87e4fa386a8e94fe68df29467d4354ce)) Updates and fixes: -* Fix memory map for STM32F4 (zulusw) +* Fixed STM32F030 erase error ([#442](https://github.com/texane/stlink/pull/442)) +* Fixed Cygwin build ([#68b0f3b](https://github.com/texane/stlink/commit/68b0f3bddc3c4aaffe34caa6a3201029edd8ad56)) +* Reset flash mass erase (MER) bit after mass erase for safety ([#489](https://github.com/texane/stlink/pull/489)) +* Fix memory map for STM32F4 (@zulusw) * Fix STM32L-problem with flash loader (issue #390) (Tom de Boer) * `st-util` don't read target voltage on startup as it crashes STM32F100 (probably stlink/v1) (Greg Alexander) -* Do a JTAG reset prior to reading CPU information when processor is in deep sleep (andyg24) -* Redesign of `st-flash` commandline options parsing (pull-request #459) (dev26th) +* Do a JTAG reset prior to reading CPU information when processor is in deep sleep (@andyg24) +* Redesign of `st-flash` commandline options parsing (pull-request #459) (@dev26th) v1.2.0 ====== diff --git a/cmake/CPackConfig.cmake b/cmake/CPackConfig.cmake index 1dfd376be..fb6bb1a5c 100644 --- a/cmake/CPackConfig.cmake +++ b/cmake/CPackConfig.cmake @@ -1,13 +1,13 @@ set (CPACK_PACKAGE_NAME ${PROJECT_NAME}) set (CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) -set (CPACK_SOURCE_GENERATOR "TBZ2;ZIP") -set (CPACK_SOURCE_IGNORE_FILES "/build/;/.git/;~$;${CPACK_SOURCE_IGNORE_FILES}") -set (CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}") set (CPACK_SET_DESTDIR "ON") set (CPACK_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/cpack/staging") if (APPLE) set(CPACK_GENERATOR "ZIP") file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/osx") set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/osx") +elseif (WIN32) + set(CPACK_GENERATOR "ZIP") + file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/windows") + set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/windows") endif() -add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source) diff --git a/doc/compiling.md b/doc/compiling.md index 3a3a38826..5bac6144a 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -2,9 +2,9 @@ ## Build from sources -* CMake +* CMake (minimal v2.8.7) * C compiler (gcc, clang, mingw) -* Libusb 1.0 +* Libusb 1.0 (minimal v1.0.9) * (optional) pandoc for generating manpages from markdown Run from the root of the source directory: From 0f9e4990ba0cdc295875b219b354fdf42f30a9aa Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 28 Jan 2017 10:16:20 +0100 Subject: [PATCH 0532/1435] README.md: Add note about write protected flash. Fixes #545 --- README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/README.md b/README.md index 45a5de82d..e0e805828 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,37 @@ of the flash: Issue related to this bug: [#356](https://github.com/texane/stlink/issues/356) +### Flash size is detected as zero bytes size + +It is possible that the STM32 flash is write protected, the st-flash tool will show something like this: + +``` +st-flash write prog.bin 0x8000000 +2017-01-24T18:44:14 INFO src/stlink-common.c: Loading device parameters.... +2017-01-24T18:44:14 INFO src/stlink-common.c: Device connected is: F1 High-density device, id 0x10036414 +2017-01-24T18:44:14 INFO src/stlink-common.c: SRAM size: 0x10000 bytes (64 KiB), Flash: 0 bytes (0 KiB) in pages of 2048 bytes +``` + +As you can see, it gives out something unexpected like +``` +Flash: 0 bytes (0 KiB) in pages of 2048 bytes +``` + +``` +st-info --probe +Found 1 stlink programmers + serial: 303030303030303030303031 +openocd: "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x31" + flash: 0 (pagesize: 2048) + sram: 65536 + chipid: 0x0414 + descr: F1 High-density device +``` + +Try to remove the write protection (probably only possible with ST Link Utility from ST itself). + +Issue related to this bug: [#545](https://github.com/texane/stlink/issues/545) + ## Contributing and versioning * The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) From e05ad17253c26ffbeb10fe576af4bb3b51094d45 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 28 Jan 2017 10:21:48 +0100 Subject: [PATCH 0533/1435] Update doc/tutorial.md with latest commandline arguments. Fixes #543. --- doc/tutorial.md | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 937e2da28..52ed0bc9b 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -33,31 +33,30 @@ identical. Before continuing, the following dependencies must be met: - libusb-1.0 -- pkg-config -- autotools +- cmake STLINK should run on any system meeting the above constraints. The STLINK software source code is retrieved using: ``` -$> git clone https://github.com/texane/stlink stlink.git +$> git clone https://github.com/texane/stlink.git ``` Everything can be built from the top directory: ``` -$> cd stlink.git -$> ./autogen.sh -$> ./configure +$> cd stlink $> make +$> cd build/Release && make install DESTDIR=_install ``` It includes: -- a communication library (stlink.git/libstlink.a), -- a GDB server (stlink.git/st-util), -- a flash manipulation tool (stlink.git/st-flash). +- a communication library (libstlink.a), +- a GDB server (st-util), +- a flash manipulation tool (st-flash). +- a programmer and chip information tool (st-info) Using the GDB server ==================== @@ -134,20 +133,25 @@ memory, or read arbitary addresses of memory out to a binary file, use the st-flash tool, as shown below: ``` - # stlinkv1 command to read 4096 from flash into out.bin -$> ./st-flash read v1 out.bin 0x8000000 4096 +$> ./st-flash read out.bin 0x8000000 4096 # stlinkv2 command $> ./st-flash read out.bin 0x8000000 4096 # stlinkv1 command to write the file in.bin into flash -$> ./st-flash write v1 in.bin 0x8000000 +$> ./st-flash write in.bin 0x8000000 # stlinkv2 command $> ./st-flash write in.bin 0x8000000 ``` +It is also possible to write a hexfile which is more convinient: + +``` +$> ./st-flash --format ihex write myapp.hex +``` + #### Of course, you can use this instead of the gdb server, if you prefer. From 4868a62fbf8bc45d14feeadc155857fd18810a30 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 28 Jan 2017 11:30:30 +0100 Subject: [PATCH 0534/1435] Prepare for win64 static executable builds --- CMakeLists.txt | 44 ++++++++++++++++++++++++++++-------- cmake/CPackConfig.cmake | 5 ++-- doc/build_mingw.md | 23 ------------------- doc/compiling.md | 22 ++++++++++++++++++ doc/man/CMakeLists.txt | 2 +- scripts/mingw64-build.bat | 4 +++- src/gdbserver/CMakeLists.txt | 7 +++++- src/gdbserver/Makefile | 20 ---------------- tests/CMakeLists.txt | 6 ++--- 9 files changed, 72 insertions(+), 61 deletions(-) delete mode 100644 doc/build_mingw.md delete mode 100644 src/gdbserver/Makefile diff --git a/CMakeLists.txt b/CMakeLists.txt index 4aac51c05..9a3e06355 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,12 +66,16 @@ include_directories(include) include_directories(${PROJECT_BINARY_DIR}/include) include_directories(src/mingw) +### # Shared library -add_library(${PROJECT_NAME} SHARED +### +set(STLINK_LIB_SHARED ${PROJECT_NAME}-shared) + +add_library(${STLINK_LIB_SHARED} SHARED ${STLINK_HEADERS} # header files for ide projects generated by cmake ${STLINK_SOURCE} ) -target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARY}) +target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY}) if (WIN32 OR MSYS OR MINGW) set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}) @@ -79,25 +83,27 @@ else() set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) endif() -set_target_properties(${PROJECT_NAME} +set_target_properties(${STLINK_LIB_SHARED} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} VERSION ${STLINK_SHARED_VERSION} ) +# Link shared library with apple OS libraries if (APPLE) find_library(ObjC objc) find_library(CoreFoundation CoreFoundation) find_library(IOKit IOKit) - target_link_libraries(${PROJECT_NAME} ${CoreFoundation} ${IOKit} ${ObjC}) + target_link_libraries(${STLINK_LIB_SHARED} ${CoreFoundation} ${IOKit} ${ObjC}) endif () -if(WIN32 OR MSYS OR MINGW) - target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARY} wsock32 ws2_32) +# Link +if (WIN32 OR MSYS OR MINGW) + target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} wsock32 ws2_32) else() - target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARY}) + target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY}) endif() -install(TARGETS ${PROJECT_NAME} +install(TARGETS ${STLINK_LIB_SHARED} DESTINATION lib/${CMAKE_LIBRARY_PATH} ) @@ -110,7 +116,17 @@ add_library(${STLINK_LIB_STATIC} STATIC ${STLINK_HEADERS} # header files for ide projects generated by cmake ${STLINK_SOURCE} ) + target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY}) + +# Link shared library with apple OS libraries +if (APPLE) + find_library(ObjC objc) + find_library(CoreFoundation CoreFoundation) + find_library(IOKit IOKit) + target_link_libraries(${STLINK_LIB_STATIC} ${CoreFoundation} ${IOKit} ${ObjC}) +endif () + set_target_properties(${STLINK_LIB_STATIC} PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) install(TARGETS ${STLINK_LIB_STATIC} @@ -121,10 +137,18 @@ install(TARGETS ${STLINK_LIB_STATIC} # Tools ### add_executable(st-flash src/tools/flash.c src/tools/flash_opts.c) -target_link_libraries(st-flash ${PROJECT_NAME}) +if (WIN32 OR APPLE) + target_link_libraries(st-flash ${STLINK_LIB_STATIC}) +else() + target_link_libraries(st-flash ${STLINK_LIB_SHARED}) +endif() add_executable(st-info src/tools/info.c) -target_link_libraries(st-info ${PROJECT_NAME}) +if (WIN32 OR APPLE) + target_link_libraries(st-info ${STLINK_LIB_STATIC}) +else() + target_link_libraries(st-info ${STLINK_LIB_SHARED}) +endif() install(TARGETS st-flash st-info RUNTIME DESTINATION bin diff --git a/cmake/CPackConfig.cmake b/cmake/CPackConfig.cmake index fb6bb1a5c..3dc2b6a3a 100644 --- a/cmake/CPackConfig.cmake +++ b/cmake/CPackConfig.cmake @@ -1,13 +1,14 @@ set (CPACK_PACKAGE_NAME ${PROJECT_NAME}) set (CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) set (CPACK_SET_DESTDIR "ON") -set (CPACK_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/cpack/staging") if (APPLE) set(CPACK_GENERATOR "ZIP") file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/osx") + set (CPACK_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/cpack/staging") set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/osx") elseif (WIN32) set(CPACK_GENERATOR "ZIP") file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/windows") + set (CPACK_INSTALL_PREFIX "") set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/windows") -endif() +endif() \ No newline at end of file diff --git a/doc/build_mingw.md b/doc/build_mingw.md deleted file mode 100644 index 6327b57c6..000000000 --- a/doc/build_mingw.md +++ /dev/null @@ -1,23 +0,0 @@ -Building with MinGW under Windows -================================= - -## Prequistes - -* 7Zip -* CMake 2.8 or higher -* MinGW64 GCC toolchain (5.3.0) - -## Installation - -1. Install 7Zip from http://www.7-zip.org -2. Install CMake from https://cmake.org/download -3. Install MinGW64 from https://sourceforge.net/projects/mingw-w64 (mingw-w64-install.exe) -4. Git clone or download stlink sourcefiles zip -5. Create build folder in source - -# Building - -Check and execute `\scripts\mingw64-build.bat` - -NOTE: when installing different toolchains make sure you edit the path in the `mingw64-build.bat` - the build script uses currently `C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin` diff --git a/doc/compiling.md b/doc/compiling.md index 5bac6144a..30f23b63a 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -117,3 +117,25 @@ during installation you can use the following cmake options: $ cmake -DSTLINK_UDEV_RULES_DIR="/usr/lib/udev/rules.d" \ -DSTLINK_MODPROBED_DIR="/usr/lib/modprobe.d" .. ``` + +## Windows (MinGW64) + +### Prequistes + +* 7Zip +* CMake 2.8 or higher +* MinGW64 GCC toolchain (5.3.0) + +### Installation + +1. Install 7Zip from +2. Install CMake from +3. Install MinGW64 from (mingw-w64-install.exe) +4. Git clone or download stlink sourcefiles zip + +### Building + +Check and execute (in the script folder) `\scripts\mingw64-build.bat` + +NOTE: when installing different toolchains make sure you edit the path in the `mingw64-build.bat` + the build script uses currently `C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin` diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 83bb008cf..949cd2fcf 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -30,7 +30,7 @@ foreach(manpage ${MANPAGES}) message(AUTHOR_WARNING "Manpage ${manpage} not generated") endif() - if (f) + if (f AND NOT WIN32) install(FILES ${f} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1) unset(f) endif() diff --git a/scripts/mingw64-build.bat b/scripts/mingw64-build.bat index 52c6fffb1..3f92ae8e0 100644 --- a/scripts/mingw64-build.bat +++ b/scripts/mingw64-build.bat @@ -1,4 +1,6 @@ @echo off set PATH=C:\Program Files (x86)\CMake\bin;C:\Program Files\CMake\bin;C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin;%PATH% cmake -G "MinGW Makefiles" .. -mingw32-make \ No newline at end of file +mingw32-make +mingw32-make install DESTDIR=_install +mingw32-make package diff --git a/src/gdbserver/CMakeLists.txt b/src/gdbserver/CMakeLists.txt index c6114f6d6..a41890c70 100644 --- a/src/gdbserver/CMakeLists.txt +++ b/src/gdbserver/CMakeLists.txt @@ -4,7 +4,12 @@ add_executable(st-util gdb-remote.c gdb-server.h semihosting.c semihosting.h) -target_link_libraries(st-util ${PROJECT_NAME}) +if (WIN32 OR APPLE) + target_link_libraries(st-util ${STLINK_LIB_STATIC}) +else() + target_link_libraries(st-util ${STLINK_LIB_SHARED}) +endif() + install(TARGETS st-util RUNTIME DESTINATION bin ) diff --git a/src/gdbserver/Makefile b/src/gdbserver/Makefile deleted file mode 100644 index bd5c73dbc..000000000 --- a/src/gdbserver/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -PRG := st-util -OBJS = gdb-remote.o gdb-server.o - -CFLAGS+=-g -Wall -Werror -std=gnu99 -I../src -LDFLAGS=-L.. -lstlink - -# libusb location -LDFLAGS+=`pkg-config --libs libusb-1.0` -CFLAGS+=`pkg-config --cflags libusb-1.0` - -all: $(PRG) - -$(PRG): $(OBJS) ../libstlink.a - $(CC) -o $@ $^ $(LDFLAGS) - -clean: - rm -rf $(OBJS) - rm -rf $(PRG) - -.PHONY: clean all diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fc51433bd..8df28ce7e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,11 +5,11 @@ set(TESTS foreach(test ${TESTS}) add_executable(${test} ${test}.c) - add_dependencies(${test} ${PROJECT_NAME}) - target_link_libraries(${test} ${PROJECT_NAME}) + add_dependencies(${test} ${STLINK_LIB_STATIC}) + target_link_libraries(${test} ${STLINK_LIB_STATIC}) add_test(${test} ${CMAKE_CURRENT_BINARY_DIR}/${test}) endforeach() add_executable(flash flash.c "${CMAKE_SOURCE_DIR}/src/tools/flash_opts.c") -target_link_libraries(flash ${PROJECT_NAME}) +target_link_libraries(flash ${STLINK_LIB_STATIC}) add_test(flash ${CMAKE_CURRENT_BINARY_DIR}/flash) From 1b36565d7d94cb0198be742848e86bd28791ad01 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 28 Jan 2017 11:49:06 +0100 Subject: [PATCH 0535/1435] CMakeLists.txt: Fix last piece to compile static on windows --- CMakeLists.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a3e06355..254751b42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,7 @@ set(STLINK_SOURCE ) if (WIN32 OR MSYS OR MINGW) - set (STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") # TODO + set (STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") endif () include_directories(${LIBUSB_INCLUDE_DIR}) @@ -94,9 +94,8 @@ if (APPLE) find_library(CoreFoundation CoreFoundation) find_library(IOKit IOKit) target_link_libraries(${STLINK_LIB_SHARED} ${CoreFoundation} ${IOKit} ${ObjC}) -endif () +endif() -# Link if (WIN32 OR MSYS OR MINGW) target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} wsock32 ws2_32) else() @@ -117,15 +116,19 @@ add_library(${STLINK_LIB_STATIC} STATIC ${STLINK_SOURCE} ) -target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY}) - # Link shared library with apple OS libraries if (APPLE) find_library(ObjC objc) find_library(CoreFoundation CoreFoundation) find_library(IOKit IOKit) target_link_libraries(${STLINK_LIB_STATIC} ${CoreFoundation} ${IOKit} ${ObjC}) -endif () +endif() + +if (WIN32 OR MSYS OR MINGW) + target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} wsock32 ws2_32) +else() + target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY}) +endif() set_target_properties(${STLINK_LIB_STATIC} PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) From ca4ff46b5a053e1660b207524c677e7de6f6ac7d Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 28 Jan 2017 11:55:48 +0100 Subject: [PATCH 0536/1435] README.md: Prepare for v1.3.0 release --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e0e805828..3fc467abd 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Open source version of the STMicroelectronics Stlink Tools ========================================================== [![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) -[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.2.0.svg)](https://github.com/texane/stlink/compare/1.2.0...master) +[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.3.0.svg)](https://github.com/texane/stlink/compare/1.3.0...master) [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) [![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/job/stlink/) [![Build status](https://ci.appveyor.com/api/projects/status/wrcie05d4jmut0te?svg=true)](https://ci.appveyor.com/project/xor-gate/stlink) From f546110bafa07185c399f2556f702a932bc63c3e Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 28 Jan 2017 12:09:37 +0100 Subject: [PATCH 0537/1435] cmake/CPackConfig.cmake: Fixup OSX zip filename --- cmake/CPackConfig.cmake | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/CPackConfig.cmake b/cmake/CPackConfig.cmake index 3dc2b6a3a..ac3cc6f7e 100644 --- a/cmake/CPackConfig.cmake +++ b/cmake/CPackConfig.cmake @@ -3,12 +3,13 @@ set (CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) set (CPACK_SET_DESTDIR "ON") if (APPLE) set(CPACK_GENERATOR "ZIP") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-macosx-amd64") file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/osx") - set (CPACK_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/cpack/staging") + set (CPACK_INSTALL_PREFIX "") set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/osx") elseif (WIN32) set(CPACK_GENERATOR "ZIP") file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/windows") set (CPACK_INSTALL_PREFIX "") set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/windows") -endif() \ No newline at end of file +endif() From ed813270e3b73feaa2e92b6f96384df31c52d49c Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 28 Jan 2017 13:08:30 +0100 Subject: [PATCH 0538/1435] README.md: Add downloads counter badge --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3fc467abd..e3358c5b3 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,12 @@ Open source version of the STMicroelectronics Stlink Tools ========================================================== [![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) +[![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) [![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.3.0.svg)](https://github.com/texane/stlink/compare/1.3.0...master) +[![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/texane/stlink/releases) [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) [![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/job/stlink/) [![Build status](https://ci.appveyor.com/api/projects/status/wrcie05d4jmut0te?svg=true)](https://ci.appveyor.com/project/xor-gate/stlink) -[![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) ## HOWTO From eea16d762979fcfc28937c784c480c8346247a3a Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sun, 29 Jan 2017 09:20:20 +0100 Subject: [PATCH 0539/1435] Update README.md Add note for windows and mac binaries with release v1.3.0 --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e3358c5b3..d2bd2330b 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,9 @@ Two different transport layers are used: ## Installation -Currently there are no binaries for Windows available (see issue [#166](https://github.com/texane/stlink/issues/166)). - It is known to compile and work with MinGW(64)/Cygwin environment. Building with Visual Studio is not supported because the project uses POSIX APIs and probably will never change. +Windows users can [download v1.3.0](https://github.com/texane/stlink/releases/tag/1.3.0) from the releases page. + +Mac OS X users can install from [homebrew](http://brewformulas.org/Stlink) or [download v1.3.0](https://github.com/texane/stlink/releases/tag/1.3.0) from the releases page. For Debian Linux based distributions there is no package available in the standard repositories so you need to install [from source](doc/compiling.md) yourself. @@ -35,8 +36,6 @@ Arch Linux users can install from the [repository](https://www.archlinux.org/pac FreeBSD users can install from [freshports](https://www.freshports.org/devel/stlink) -Mac OS X users can install from [homebrew](http://brewformulas.org/Stlink) - OpenBSD users need to install [from source](doc/compiling.md). ## Installation from source (advanced users) From 4f460ecab288a5f8186469c86b55142ad0ea7296 Mon Sep 17 00:00:00 2001 From: m-schwerin Date: Mon, 30 Jan 2017 01:06:25 -0500 Subject: [PATCH 0540/1435] Add support for STM32F413 target (#549) Add support for STM32F413 target. Fixes #550. --- include/stlink/chipid.h | 3 ++- src/chipid.c | 12 ++++++++++++ src/flash_loader.c | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 36fb73c62..84aff7f80 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -55,7 +55,8 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F0_CAN = 0x448, STLINK_CHIPID_STM32_F7 = 0x449, STLINK_CHIPID_STM32_F7XXXX = 0x451, - STLINK_CHIPID_STM32_F410 = 0x458 + STLINK_CHIPID_STM32_F410 = 0x458, + STLINK_CHIPID_STM32_F413 = 0x463 }; /** diff --git a/src/chipid.c b/src/chipid.c index 13307a99e..4318db787 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -298,6 +298,18 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 .bootrom_size = 0x7800 // "System memory" byte size in hex from Table 4 }, + { + // RM0430 DocID029473 Rev 2 document was used to find these parameters + // Figure 2, Table 4, Table 5, Section 35.2 + .chip_id = STLINK_CHIPID_STM32_F413, + .description = "F4 device", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 + .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector sizes, but 0x4000 is smallest) + .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 only says 0x40000) + .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 + .bootrom_size = 0x7800 // "System memory" byte size in hex from Table 4 + }, { .chip_id = STLINK_CHIPID_STM32_F09X, .description = "F09X device", diff --git a/src/flash_loader.c b/src/flash_loader.c index f4d81cbab..0b05f4ab6 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -219,6 +219,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_F410 || sl->chip_id == STLINK_CHIPID_STM32_F411RE || sl->chip_id == STLINK_CHIPID_STM32_F412 || + sl->chip_id == STLINK_CHIPID_STM32_F413 || sl->chip_id == STLINK_CHIPID_STM32_F446 ) { if( sl->version.stlink_v == 1 ) { From e71a2417c31aeee685a1a6ea22c7b53f6fbd48f8 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Mon, 30 Jan 2017 23:16:36 +0100 Subject: [PATCH 0541/1435] Compilation fixes (errors / warnings) (#552) --- include/stlink/tools/flash.h | 4 +--- src/common.c | 2 +- src/gdbserver/semihosting.c | 8 ++++---- src/tools/flash.c | 4 ++-- src/tools/gui/CMakeLists.txt | 4 ++-- tests/flash.c | 2 +- 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index bb7bd739e..6a7b05484 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -22,9 +22,7 @@ struct flash_opts enum flash_format format; }; - -#define FLASH_OPTS_INITIALIZER {0, } - +#define FLASH_OPTS_INITIALIZER {0, NULL, {}, NULL, 0, 0, 0, 0, 0 } int flash_get_opts(struct flash_opts* o, int ac, char** av); diff --git a/src/common.c b/src/common.c index f104a1629..ccbbbe248 100644 --- a/src/common.c +++ b/src/common.c @@ -2048,7 +2048,7 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, if(e > end) end = e; } else { - for(size_t i = 0; i < reclen; ++i) { + for(uint8_t i = 0; i < reclen; ++i) { uint8_t b = stlink_parse_hex(line + 9 + i*2); uint32_t addr = lba + offset + i; if(addr >= *begin && addr <= end) { diff --git a/src/gdbserver/semihosting.c b/src/gdbserver/semihosting.c index 4ea6ccf5c..4be8090f5 100644 --- a/src/gdbserver/semihosting.c +++ b/src/gdbserver/semihosting.c @@ -247,7 +247,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint32_t args[3]; uint32_t buffer_address; int fd; - size_t buffer_len; + uint32_t buffer_len; void *buffer; if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { @@ -259,7 +259,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { fd = (int)args[0]; buffer_address = args[1]; - buffer_len = (size_t)args[2]; + buffer_len = args[2]; if (buffer_len > MAX_BUFFER_SIZE) { DLOG("Semihosting SYS_WRITE error: buffer size is too big %d\n", @@ -305,7 +305,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint32_t args[3]; uint32_t buffer_address; int fd; - size_t buffer_len; + uint32_t buffer_len; void *buffer; if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { @@ -317,7 +317,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { fd = (int)args[0]; buffer_address = args[1]; - buffer_len = (size_t)args[2]; + buffer_len = args[2]; if (buffer_len > MAX_BUFFER_SIZE) { DLOG("Semihosting SYS_READ error: buffer size is too big %d\n", diff --git a/src/tools/flash.c b/src/tools/flash.c index 1b6c7a7da..f2c186e95 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -135,7 +135,7 @@ int main(int ac, char** av) if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { if(o.format == FLASH_FORMAT_IHEX) - err = stlink_mwrite_flash(sl, mem, size, o.addr); + err = stlink_mwrite_flash(sl, mem, (uint32_t)size, o.addr); else err = stlink_fwrite_flash(sl, o.filename, o.addr); if (err == -1) @@ -147,7 +147,7 @@ int main(int ac, char** av) else if ((o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { if(o.format == FLASH_FORMAT_IHEX) - err = stlink_mwrite_sram(sl, mem, size, o.addr); + err = stlink_mwrite_sram(sl, mem, (uint32_t)size, o.addr); else err = stlink_fwrite_sram(sl, o.filename, o.addr); if (err == -1) diff --git a/src/tools/gui/CMakeLists.txt b/src/tools/gui/CMakeLists.txt index e217af03a..53d1d862d 100644 --- a/src/tools/gui/CMakeLists.txt +++ b/src/tools/gui/CMakeLists.txt @@ -10,13 +10,13 @@ include_directories(SYSTEM ${gtk_INCLUDE_DIRS}) add_executable(stlink-gui-local ${GUI_SOURCES}) set_target_properties(stlink-gui-local PROPERTIES COMPILE_FLAGS -DSTLINK_UI_DIR=\\"${CMAKE_CURRENT_SOURCE_DIR}/gui\\") -target_link_libraries(stlink-gui-local stlink ${gtk_LDFLAGS}) +target_link_libraries(stlink-gui-local ${STLINK_LIB_STATIC} ${gtk_LDFLAGS}) add_executable(stlink-gui ${GUI_SOURCES}) set_target_properties(stlink-gui PROPERTIES COMPILE_FLAGS -DSTLINK_UI_DIR=\\"${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}\\") -target_link_libraries(stlink-gui stlink ${gtk_LDFLAGS}) +target_link_libraries(stlink-gui ${STLINK_LIB_STATIC} ${gtk_LDFLAGS}) install(TARGETS stlink-gui RUNTIME DESTINATION bin) diff --git a/tests/flash.c b/tests/flash.c index 27fd437f6..fd55fdfc1 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -59,7 +59,7 @@ static bool execute_test(const struct Test * test) { return ret; } -struct Test tests[] = { +static struct Test tests[] = { { "", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset read /dev/sg0 test.bin 0x80000000 0x1000", 0, { .cmd = FLASH_CMD_READ, .devname = "/dev/sg0", .serial = {}, .filename = "test.bin", From f62895b2cf3ccbbc87be1d8525e9dc51645f2516 Mon Sep 17 00:00:00 2001 From: Fabien Chouteau Date: Tue, 31 Jan 2017 07:29:44 +0100 Subject: [PATCH 0542/1435] Semihosting: Add support of SYS_READC (#546) --- src/gdbserver/semihosting.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gdbserver/semihosting.c b/src/gdbserver/semihosting.c index 4be8090f5..34591d120 100644 --- a/src/gdbserver/semihosting.c +++ b/src/gdbserver/semihosting.c @@ -457,6 +457,12 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { } break; } + case SYS_READC: + { + uint8_t c = getchar(); + *ret = c; + break; + } case SYS_WRITE0: { uint8_t buf[WRITE0_BUFFER_SIZE]; From 7b314c954199d8b2b1439eab55925a943f9a2395 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Wed, 1 Feb 2017 19:04:09 +0100 Subject: [PATCH 0543/1435] Update README.md Remove appveyor MinGW64 build badge (broken) --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index d2bd2330b..bec30c119 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ Open source version of the STMicroelectronics Stlink Tools [![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/texane/stlink/releases) [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) [![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/job/stlink/) -[![Build status](https://ci.appveyor.com/api/projects/status/wrcie05d4jmut0te?svg=true)](https://ci.appveyor.com/project/xor-gate/stlink) ## HOWTO From cd1ba149903c57df8d24ee7d60b69af290611b89 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Wed, 1 Feb 2017 23:12:39 +0100 Subject: [PATCH 0544/1435] README.md: Add Alpine Linux for installation --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e3358c5b3..7e4667516 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,8 @@ For Debian Linux based distributions there is no package available Arch Linux users can install from the [repository](https://www.archlinux.org/packages/community/x86_64/stlink) +Alpine Linux users can install from the [repository](https://pkgs.alpinelinux.org/packages?name=stlink) + FreeBSD users can install from [freshports](https://www.freshports.org/devel/stlink) Mac OS X users can install from [homebrew](http://brewformulas.org/Stlink) From 2c0ab7f0eb6cfda5cfbdc08bb9f6760d27c2b667 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Tue, 14 Feb 2017 19:51:24 +0100 Subject: [PATCH 0545/1435] logging: Don't print absolute path to source file. Fixes #548 --- CMakeLists.txt | 5 +++++ include/stlink/logging.h | 15 ++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 254751b42..285b5c713 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,11 @@ if (${CMAKE_BUILD_TYPE} MATCHES "Debug") include(CTest) endif() +# fixup __FILE__ absolute paths in logging module +# see: https://cmake.org/pipermail/cmake-developers/2015-January/024202.html +string(LENGTH "${CMAKE_SOURCE_DIR}/" CMAKE_SOURCE_DIR_LENGTH) +add_definitions(-DCMAKE_SOURCE_DIR_LENGTH=${CMAKE_SOURCE_DIR_LENGTH}) + set(STLINK_HEADERS include/stlink.h include/stlink/usb.h diff --git a/include/stlink/logging.h b/include/stlink/logging.h index 81e5f598c..9a98a6bc5 100644 --- a/include/stlink/logging.h +++ b/include/stlink/logging.h @@ -20,17 +20,22 @@ enum ugly_loglevel { int ugly_init(int maximum_threshold); int ugly_log(int level, const char *tag, const char *format, ...); +#ifndef CMAKE_SOURCE_DIR_LENGTH +#define CMAKE_SOURCE_DIR_LENGTH 0 +#endif +#define UGLY_LOG_FILE (__FILE__+CMAKE_SOURCE_DIR_LENGTH) + /** @todo we need to write this in a more generic way, for now this should compile on visual studio (See http://stackoverflow.com/a/8673872/1836746) */ -#define DLOG_HELPER(format, ...) ugly_log(UDEBUG, __FILE__, format, __VA_ARGS__) +#define DLOG_HELPER(format, ...) ugly_log(UDEBUG, UGLY_LOG_FILE, format, __VA_ARGS__) #define DLOG(...) DLOG_HELPER(__VA_ARGS__, "") -#define ILOG_HELPER(format, ...) ugly_log(UINFO, __FILE__, format, __VA_ARGS__) +#define ILOG_HELPER(format, ...) ugly_log(UINFO, UGLY_LOG_FILE, format, __VA_ARGS__) #define ILOG(...) ILOG_HELPER(__VA_ARGS__, "") -#define WLOG_HELPER(format, ...) ugly_log(UWARN, __FILE__, format, __VA_ARGS__) +#define WLOG_HELPER(format, ...) ugly_log(UWARN, UGLY_LOG_FILE, format, __VA_ARGS__) #define WLOG(...) WLOG_HELPER(__VA_ARGS__, "") -#define ELOG_HELPER(format, ...) ugly_log(UERROR, __FILE__, format, __VA_ARGS__) +#define ELOG_HELPER(format, ...) ugly_log(UERROR, UGLY_LOG_FILE, format, __VA_ARGS__) #define ELOG(...) ELOG_HELPER(__VA_ARGS__, "") -#define fatal_helper(format, ...) ugly_log(UFATAL, __FILE__, format, __VA_ARGS__) +#define fatal_helper(format, ...) ugly_log(UFATAL, UGLY_LOG_FILE, format, __VA_ARGS__) #define fatal(...) fatal_helper(__VA_ARGS__, "") #ifdef __cplusplus From 67eba4badb38b31d8363ef04c1da3275aa5f5342 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Tue, 14 Feb 2017 20:11:40 +0100 Subject: [PATCH 0546/1435] chipid: Add support for STM32L011 (NUCLEO-L011K4 --- include/stlink/chipid.h | 1 + src/chipid.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 84aff7f80..6a078aa1b 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -55,6 +55,7 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F0_CAN = 0x448, STLINK_CHIPID_STM32_F7 = 0x449, STLINK_CHIPID_STM32_F7XXXX = 0x451, + STLINK_CHIPID_STM32_L011 = 0x457, STLINK_CHIPID_STM32_F410 = 0x458, STLINK_CHIPID_STM32_F413 = 0x463 }; diff --git a/src/chipid.c b/src/chipid.c index 4318db787..049b77979 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -445,6 +445,17 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) .bootrom_size = 0x7000 // 28k (per bank), same source as base }, + { + // STM32L011 + .chip_id = STLINK_CHIPID_STM32_L011, + .description = "L011 device", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x4000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x1000 + }, }; From fc4fd76a7564428289f79d88ab75b2a094882510 Mon Sep 17 00:00:00 2001 From: Joost Rijneveld Date: Mon, 20 Feb 2017 18:45:07 +0100 Subject: [PATCH 0547/1435] Fix incorrect release folder name in docs (#560) --- doc/compiling.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/compiling.md b/doc/compiling.md index 30f23b63a..296d64b17 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -27,13 +27,13 @@ $ make You could install to a user folder e.g `$HOME`: ``` -$ cd release; make install DESTDIR=$HOME +$ cd build/Release; make install DESTDIR=$HOME ``` Or system wide: ``` -$ cd release; sudo make install +$ cd build/Release; sudo make install ``` ## Linux From 28a15598c022b72448fa54aa845120d44bfcb182 Mon Sep 17 00:00:00 2001 From: Joost Rijneveld Date: Tue, 21 Feb 2017 11:03:58 +0100 Subject: [PATCH 0548/1435] Fix compilation when path includes spaces (#561) --- src/tools/gui/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/gui/CMakeLists.txt b/src/tools/gui/CMakeLists.txt index 53d1d862d..4ab9975da 100644 --- a/src/tools/gui/CMakeLists.txt +++ b/src/tools/gui/CMakeLists.txt @@ -9,13 +9,13 @@ include_directories(SYSTEM ${gtk_INCLUDE_DIRS}) add_executable(stlink-gui-local ${GUI_SOURCES}) set_target_properties(stlink-gui-local PROPERTIES - COMPILE_FLAGS -DSTLINK_UI_DIR=\\"${CMAKE_CURRENT_SOURCE_DIR}/gui\\") + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}/gui") target_link_libraries(stlink-gui-local ${STLINK_LIB_STATIC} ${gtk_LDFLAGS}) add_executable(stlink-gui ${GUI_SOURCES}) set_target_properties(stlink-gui PROPERTIES - COMPILE_FLAGS -DSTLINK_UI_DIR=\\"${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}\\") + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}") target_link_libraries(stlink-gui ${STLINK_LIB_STATIC} ${gtk_LDFLAGS}) install(TARGETS stlink-gui From 6f24bde1aefde8f543861cab8c205e564cb7fb36 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 25 Feb 2017 17:45:21 +0100 Subject: [PATCH 0549/1435] Prepare for v1.3.1 bugfix release --- .version | 2 +- ChangeLog.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.version b/.version index f0bb29e76..3a3cd8cc8 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.3.0 +1.3.1 diff --git a/ChangeLog.md b/ChangeLog.md index 32c733b03..b8f5b78de 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,6 +1,24 @@ Stlink ChangeLog ================ +v1.3.1 +====== + +Release date: 2017-02-25 + +Major changes and added features: + +* Add preliminary support for STM32L011 to see it after probe (chipid `0x457`) (@xor-gate) +* Strip full paths to source files in log (commit [#2c0ab7f](https://github.com/texane/stlink/commit/2c0ab7f0eb6cfda5cfbdc08bb9f6760d27c2b667)) +* Add support for STM32F413 target ([#549](https://github.com/texane/stlink/pull/549)) +* Add support for Semihosting `SYS_READC` ([#546](https://github.com/texane/stlink/pull/546)) + +Updates and fixes: + +* Update documentation markdown files +* Compilation fixes ([#552](https://github.com/texane/stlink/pull/552)) +* Fix compilation when path includes spaces ([#561](https://github.com/texane/stlink/pull/561)) + v1.3.0 ====== From c816cb4732582996758d46bd14745087c834b51b Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 25 Feb 2017 17:50:55 +0100 Subject: [PATCH 0550/1435] README.md: Update badges to 1.3.1 release --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eb45a8ff2..3c6f48a0d 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Open source version of the STMicroelectronics Stlink Tools [![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) -[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.3.0.svg)](https://github.com/texane/stlink/compare/1.3.0...master) +[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.3.1.svg)](https://github.com/texane/stlink/compare/1.3.1...master) [![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/texane/stlink/releases) [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) [![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/job/stlink/) From 5b69f25198a1a8f34e2ee48d1ad20f79447e3d55 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Tue, 28 Feb 2017 20:09:46 +0100 Subject: [PATCH 0551/1435] cmake/CPackConfig.cmake: Allow building of debian package with CPack --- cmake/CPackConfig.cmake | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cmake/CPackConfig.cmake b/cmake/CPackConfig.cmake index ac3cc6f7e..20768453b 100644 --- a/cmake/CPackConfig.cmake +++ b/cmake/CPackConfig.cmake @@ -12,4 +12,16 @@ elseif (WIN32) file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/windows") set (CPACK_INSTALL_PREFIX "") set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/windows") +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND EXISTS "/etc/debian_version") + message(STATUS "Debian-based Linux OS detected") + set(CPACK_GENERATOR "DEB") + + if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") + set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}-amd64" ) + endif() + + set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/texane/stlink") + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Jerry Jacobs") + set(CPACK_PACKAGE_CONTACT "jerry.jacobs@xor-gate.org") + set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "STM32 stlink programmer tools") endif() From 1adaedbdbc311674c9412e40ba363251171acd25 Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Wed, 1 Mar 2017 20:56:24 +0200 Subject: [PATCH 0552/1435] Update libusb to 1.0.21 under windows (#562) * fix wrong libusb extract command * update libusb to 1.0.21 under windows --- cmake/modules/FindLibUSB.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index 84020b98b..b106018d2 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -9,7 +9,7 @@ if(WIN32 OR CMAKE_VS_PLATFORM_NAME OR MINGW OR MSYS) find_package(7Zip REQUIRED) - set(LIBUSB_WIN_VERSION 1.0.20) + set(LIBUSB_WIN_VERSION 1.0.21) set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3thparty/libusb-${LIBUSB_WIN_VERSION}) From 9d08810c68da4aa7233add53b4a570abff78df44 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Wed, 1 Mar 2017 20:08:08 +0100 Subject: [PATCH 0553/1435] Update ChangeLog.md --- ChangeLog.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index b8f5b78de..f12d176f6 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,6 +1,15 @@ Stlink ChangeLog ================ +v1.3.2 +====== + +Release date: ongoing + +Updates and fixes: + +* Update libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) + v1.3.1 ====== From bc48e99b194dba002628a3b841fd18cb4dd2762e Mon Sep 17 00:00:00 2001 From: zulusw Date: Tue, 14 Mar 2017 10:54:02 -0700 Subject: [PATCH 0554/1435] Fixing low-voltage flashing on STM32F7 parts. (#567) * fixing low voltage flashing for STM32F7 * Refactoring duplicated code --- flashloaders/stm32f7.s | 33 +++++++++++++++ flashloaders/stm32f7lv.s | 34 +++++++++++++++ src/flash_loader.c | 90 +++++++++++++++++++++++++++++++--------- 3 files changed, 138 insertions(+), 19 deletions(-) create mode 100644 flashloaders/stm32f7.s create mode 100644 flashloaders/stm32f7lv.s diff --git a/flashloaders/stm32f7.s b/flashloaders/stm32f7.s new file mode 100644 index 000000000..0334c80a0 --- /dev/null +++ b/flashloaders/stm32f7.s @@ -0,0 +1,33 @@ +.global start +.syntax unified + +@ r0 = source +@ r1 = target +@ r2 = wordcount +@ r3 = flash_base +@ r4 = temp + +start: + ldr r3, flash_base +next: + cbz r2, done + ldr r4, [r0] + str r4, [r1] + dsb sy + +wait: + ldrh r4, [r3, #0x0e] + tst.w r4, #1 + bne wait + + add r0, #4 + add r1, #4 + sub r2, #1 + b next +done: + bkpt + +.align 2 + +flash_base: + .word 0x40023c00 diff --git a/flashloaders/stm32f7lv.s b/flashloaders/stm32f7lv.s new file mode 100644 index 000000000..650922719 --- /dev/null +++ b/flashloaders/stm32f7lv.s @@ -0,0 +1,34 @@ +.global start +.syntax unified + +@ r0 = source +@ r1 = target +@ r2 = wordcount +@ r3 = flash_base +@ r4 = temp + +start: + lsls r2, r2, #2 + ldr r3, flash_base +next: + cbz r2, done + ldrb r4, [r0] + strb r4, [r1] + dsb sy + +wait: + ldrh r4, [r3, #0x0e] + tst.w r4, #1 + bne wait + + add r0, #1 + add r1, #1 + sub r2, #1 + b next +done: + bkpt + +.align 2 + +flash_base: + .word 0x40023c00 diff --git a/src/flash_loader.c b/src/flash_loader.c index 0b05f4ab6..ed53a0c6b 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -156,6 +156,7 @@ static const uint8_t loader_code_stm32vl[] = { }; static const uint8_t loader_code_stm32f7[] = { + // flashloaders/stm32f7.s 0x08, 0x4b, 0x72, 0xb1, 0x04, 0x68, @@ -172,6 +173,30 @@ static const uint8_t loader_code_stm32vl[] = { 0x00, 0x3c, 0x02, 0x40, }; + static const uint8_t loader_code_stm32f7_lv[] = { + // flashloaders/stm32f7lv.s + 0x92, 0x00, // lsls r2, r2, #2 + 0x09, 0x4b, // ldr r3, [pc, #36] ; (0x20000028 ) + // next: + 0x72, 0xb1, // cbz r2, 24 + 0x04, 0x78, // ldrb r4, [r0, #0] + 0x0c, 0x70, // strb r4, [r1, #0] + 0xbf, 0xf3, 0x4f, 0x8f, // dsb sy + // wait: + 0xdc, 0x89, // ldrh r4, [r3, #14] + 0x14, 0xf0, 0x01, 0x0f, // tst.w r4, #1 + 0xfb, 0xd1, // bne.n e + 0x00, 0xf1, 0x01, 0x00, // add r0, r0, #1 + 0x01, 0xf1, 0x01, 0x01, // add r1, r1, #1 + 0xa2, 0xf1, 0x01, 0x02, // sub r2, r2, #1 + 0xef, 0xe7, // b next + // done: + 0x00, 0xbe, // bkpt + 0x00, 0xbf, // nop + // flash_base: + 0x00, 0x3c, 0x02, 0x40 // .word 0x40023c00 + }; + int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) @@ -191,6 +216,37 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) return 0; } +static int loader_v_dependent_assignment(stlink_t *sl, + const uint8_t **loader_code, size_t *loader_size, + const uint8_t *high_v_loader, size_t high_v_loader_size, + const uint8_t *low_v_loader, size_t low_v_loader_size) +{ + int retval = 0; + + if( sl->version.stlink_v == 1 ) { + printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes\n"); + *loader_code = high_v_loader; + *loader_size = high_v_loader_size; + } + else { + int voltage = stlink_target_voltage(sl); + if (voltage == -1) { + retval = -1; + printf("Failed to read Target voltage\n"); + } + else { + if (voltage > 2700) { + *loader_code = high_v_loader; + *loader_size = high_v_loader_size; + } else { + *loader_code = low_v_loader; + *loader_size = low_v_loader_size; + } + } + } + return retval; +} + int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { const uint8_t* loader_code; @@ -222,29 +278,25 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_F413 || sl->chip_id == STLINK_CHIPID_STM32_F446 ) { - if( sl->version.stlink_v == 1 ) { - printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes on F4 devices\n"); - loader_code = loader_code_stm32f4; - loader_size = sizeof(loader_code_stm32f4); - } - else { - int voltage = stlink_target_voltage(sl); - if (voltage == -1) { - printf("Failed to read Target voltage\n"); - return voltage; - } else if (voltage > 2700) { - loader_code = loader_code_stm32f4; - loader_size = sizeof(loader_code_stm32f4); - } else { - loader_code = loader_code_stm32f4_lv; - loader_size = sizeof(loader_code_stm32f4_lv); - } + int retval; + retval = loader_v_dependent_assignment(sl, + &loader_code, &loader_size, + loader_code_stm32f4, sizeof(loader_code_stm32f4), + loader_code_stm32f4_lv, sizeof(loader_code_stm32f4_lv)); + if (retval == -1) { + return retval; } } else if (sl->core_id == STM32F7_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { - loader_code = loader_code_stm32f7; - loader_size = sizeof(loader_code_stm32f7); + int retval; + retval = loader_v_dependent_assignment(sl, + &loader_code, &loader_size, + loader_code_stm32f7, sizeof(loader_code_stm32f7), + loader_code_stm32f7_lv, sizeof(loader_code_stm32f7_lv)); + if (retval == -1) { + return retval; + } } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || sl->chip_id == STLINK_CHIPID_STM32_F04 || sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || sl->chip_id == STLINK_CHIPID_STM32_F0_SMALL || sl->chip_id == STLINK_CHIPID_STM32_F09X) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); From f73ec11abc53b6c5627456077995a6006515a5be Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 14 Mar 2017 18:54:56 +0100 Subject: [PATCH 0555/1435] Fix stlink on mingw64 (#569) --- src/gdbserver/gdb-server.c | 24 ++++++++++++------------ src/tools/info.c | 6 +++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index fddf48fcf..09e80f32a 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -393,20 +393,20 @@ static const char* const memory_map_template_F2 = "" "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram + " " // code = sram, bootrom or flash; flash is bigger + " " // sram " " //Sectors 0..3 " 0x4000" //16kB " " " " //Sector 4 " 0x10000" //64kB " " - " " //Sectors 5.. + " " //Sectors 5.. " 0x20000" //128kB " " " " // peripheral regs " " // cortex regs - " " // bootrom + " " // bootrom " " // option byte area ""; @@ -415,10 +415,10 @@ static const char* const memory_map_template_L4 = "" "" - " " // code = sram, bootrom or flash; flash is bigger + " " // code = sram, bootrom or flash; flash is bigger " " // SRAM2 (32 KB) " " // SRAM1 (96 KB) - " " + " " " 0x800" " " " " // peripheral regs @@ -434,14 +434,14 @@ static const char* const memory_map_template = "" "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram 8k - " " - " 0x%zx" + " " // code = sram, bootrom or flash; flash is bigger + " " // sram 8k + " " + " 0x%x" " " " " // peripheral regs " " // cortex regs - " " // bootrom + " " // bootrom " " // option byte area ""; @@ -452,7 +452,7 @@ static const char* const memory_map_template_F7 = "" " " // ITCM ram 16kB " " // ITCM flash - " " // sram + " " // sram " " // Sectors 0..3 " 0x8000" // 32kB " " diff --git a/src/tools/info.c b/src/tools/info.c index 2e3efc64d..54e6ec87c 100644 --- a/src/tools/info.c +++ b/src/tools/info.c @@ -114,11 +114,11 @@ static int print_data(char **av) stlink_enter_swd_mode(sl); if (strcmp(av[1], "--flash") == 0) - printf("0x%zx\n", sl->flash_size); + printf("0x%x\n", sl->flash_size); else if (strcmp(av[1], "--sram") == 0) - printf("0x%zx\n", sl->sram_size); + printf("0x%x\n", sl->sram_size); else if (strcmp(av[1], "--pagesize") == 0) - printf("0x%zx\n", sl->flash_pgsz); + printf("0x%x\n", sl->flash_pgsz); else if (strcmp(av[1], "--chipid") == 0) printf("0x%.4x\n", sl->chip_id); else if (strcmp(av[1], "--serial") == 0) From 8efd3adc8ae70ecea387ec5dfea9db04c1aaf1aa Mon Sep 17 00:00:00 2001 From: thebaron06 Date: Wed, 15 Mar 2017 12:58:37 +0100 Subject: [PATCH 0556/1435] Fix possible memory leak (#571) fixes #570 --- src/usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/usb.c b/src/usb.c index 4b57ed98f..03ac1ab3c 100644 --- a/src/usb.c +++ b/src/usb.c @@ -855,6 +855,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 if (ret != 0) { WLOG("Error %d (%s) opening ST-Link/V2 device %03d:%03d\n", ret, strerror (errno), libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); + libusb_free_device_list(list, 1); goto on_error; } } From dc9055362c88aca4dba18d0133758c649d1bcbad Mon Sep 17 00:00:00 2001 From: Zach Fredin Date: Wed, 15 Mar 2017 15:53:15 -0500 Subject: [PATCH 0557/1435] fixed support for STM32L011 (#572) --- src/chipid.c | 6 +++--- src/common.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/chipid.c b/src/chipid.c index 049b77979..15b2f563a 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -452,9 +452,9 @@ static const struct stlink_chipid_params devices[] = { .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, - .sram_size = 0x4000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000 + .sram_size = 0x2000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x2000 }, diff --git a/src/common.c b/src/common.c index ccbbbe248..c55bff54a 100644 --- a/src/common.c +++ b/src/common.c @@ -1467,7 +1467,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) uint32_t val; uint32_t flash_regs_base; - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || sl->chip_id == STLINK_CHIPID_STM32_L011) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; } else { flash_regs_base = STM32L_FLASH_REGS_ADDR; @@ -1663,7 +1663,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uin uint32_t flash_regs_base; flash_loader_t fl; - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || sl->chip_id == STLINK_CHIPID_STM32_L011) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; } else { flash_regs_base = STM32L_FLASH_REGS_ADDR; @@ -1838,7 +1838,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t uint32_t flash_regs_base; uint32_t pagesize; - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || sl->chip_id == STLINK_CHIPID_STM32_L011) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; pagesize = L0_WRITE_BLOCK_SIZE; } else { From c04df7fe61a0cab8c555ae0890744e7586c114d5 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Wed, 15 Mar 2017 22:50:38 +0100 Subject: [PATCH 0558/1435] Revert "Fix stlink on mingw64" (#573) * Revert "fixed support for STM32L011 (#572)" This reverts commit dc9055362c88aca4dba18d0133758c649d1bcbad. * Revert "Fix possible memory leak (#571)" This reverts commit 8efd3adc8ae70ecea387ec5dfea9db04c1aaf1aa. * Revert "Fix stlink on mingw64 (#569)" This reverts commit f73ec11abc53b6c5627456077995a6006515a5be. --- src/gdbserver/gdb-server.c | 24 ++++++++++++------------ src/tools/info.c | 6 +++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 09e80f32a..fddf48fcf 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -393,20 +393,20 @@ static const char* const memory_map_template_F2 = "" "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram + " " // code = sram, bootrom or flash; flash is bigger + " " // sram " " //Sectors 0..3 " 0x4000" //16kB " " " " //Sector 4 " 0x10000" //64kB " " - " " //Sectors 5.. + " " //Sectors 5.. " 0x20000" //128kB " " " " // peripheral regs " " // cortex regs - " " // bootrom + " " // bootrom " " // option byte area ""; @@ -415,10 +415,10 @@ static const char* const memory_map_template_L4 = "" "" - " " // code = sram, bootrom or flash; flash is bigger + " " // code = sram, bootrom or flash; flash is bigger " " // SRAM2 (32 KB) " " // SRAM1 (96 KB) - " " + " " " 0x800" " " " " // peripheral regs @@ -434,14 +434,14 @@ static const char* const memory_map_template = "" "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram 8k - " " - " 0x%x" + " " // code = sram, bootrom or flash; flash is bigger + " " // sram 8k + " " + " 0x%zx" " " " " // peripheral regs " " // cortex regs - " " // bootrom + " " // bootrom " " // option byte area ""; @@ -452,7 +452,7 @@ static const char* const memory_map_template_F7 = "" " " // ITCM ram 16kB " " // ITCM flash - " " // sram + " " // sram " " // Sectors 0..3 " 0x8000" // 32kB " " diff --git a/src/tools/info.c b/src/tools/info.c index 54e6ec87c..2e3efc64d 100644 --- a/src/tools/info.c +++ b/src/tools/info.c @@ -114,11 +114,11 @@ static int print_data(char **av) stlink_enter_swd_mode(sl); if (strcmp(av[1], "--flash") == 0) - printf("0x%x\n", sl->flash_size); + printf("0x%zx\n", sl->flash_size); else if (strcmp(av[1], "--sram") == 0) - printf("0x%x\n", sl->sram_size); + printf("0x%zx\n", sl->sram_size); else if (strcmp(av[1], "--pagesize") == 0) - printf("0x%x\n", sl->flash_pgsz); + printf("0x%zx\n", sl->flash_pgsz); else if (strcmp(av[1], "--chipid") == 0) printf("0x%.4x\n", sl->chip_id); else if (strcmp(av[1], "--serial") == 0) From 9775689196a0d6f4f29677a54deb5875c292259e Mon Sep 17 00:00:00 2001 From: Warren Gay Date: Fri, 24 Mar 2017 18:10:05 -0400 Subject: [PATCH 0559/1435] Added --flash=n[k][m] command line option to override device model (#576) * Added --flash=xxxx to st-flash command line --- doc/man/st-flash.1 | 8 ++++++++ doc/man/st-flash.md | 4 ++++ include/stlink/tools/flash.h | 3 ++- src/tools/flash.c | 10 ++++++++-- src/tools/flash_opts.c | 25 ++++++++++++++++++++++++- 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/doc/man/st-flash.1 b/doc/man/st-flash.1 index 252ffcba8..77a8bb550 100644 --- a/doc/man/st-flash.1 +++ b/doc/man/st-flash.1 @@ -53,6 +53,14 @@ TODO TODO .RS .RE +.TP +.B --flash=\f[I]size\f[] +Override the device's normal flash size, where size is the flash size in bytes. +It can be specified in decimal, octal or hexadecimal. +The size argument can optionally be followed by 'k' for KB or 'm' for MB. +Examples --flash=128k or --flash=0x080k. +.RS +.RE .SH EXAMPLES .PP Flash \f[C]firmware.bin\f[] to device diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md index 4eacb7a07..d1844976c 100644 --- a/doc/man/st-flash.md +++ b/doc/man/st-flash.md @@ -49,6 +49,10 @@ reset --serial *iSerial* : TODO +--flash=fsize +: Where fsize is the size in decimal, octal, or hex followed by an optional multiplier +'k' for KB, or 'm' for MB. +Use a leading "0x" to specify hexadecimal, or a leading zero for octal. # EXAMPLES Flash `firmware.bin` to device diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index 6a7b05484..35b3a4251 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -20,9 +20,10 @@ struct flash_opts int reset; int log_level; enum flash_format format; + size_t flash_size; /* --flash=n[k][m] */ }; -#define FLASH_OPTS_INITIALIZER {0, NULL, {}, NULL, 0, 0, 0, 0, 0 } +#define FLASH_OPTS_INITIALIZER {0, NULL, {}, NULL, 0, 0, 0, 0, 0, 0 } int flash_get_opts(struct flash_opts* o, int ac, char** av); diff --git a/src/tools/flash.c b/src/tools/flash.c index f2c186e95..6fe365f88 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -29,12 +29,13 @@ static void cleanup(int signum) { static void usage(void) { - puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--format ] {read|write} /dev/sgX "); + puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--format ] [--flash=] {read|write} /dev/sgX "); puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); - puts("stlinkv2 command line: ./st-flash [--debug] [--reset] [--serial ] [--format ] {read|write} "); + puts("stlinkv2 command line: ./st-flash [--debug] [--reset] [--serial ] [--format ] [--flash=] {read|write} "); puts("stlinkv2 command line: ./st-flash [--debug] [--serial ] erase"); puts("stlinkv2 command line: ./st-flash [--debug] [--serial ] reset"); puts(" Use hex format for addr, and ."); + puts(" fsize: Use decimal, octal or hex by prefix 0xXXX for hex, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); puts(" Format may be 'binary' (default) or 'ihex', although must be specified for binary format only."); puts(" ./st-flash [--version]"); } @@ -64,6 +65,11 @@ int main(int ac, char** av) if (sl == NULL) return -1; + if ( o.flash_size != 0u && o.flash_size != sl->flash_size ) { + sl->flash_size = o.flash_size; + printf("Forcing flash size: --flash=0x%08zX\n",sl->flash_size); + } + sl->verbose = o.log_level; connected_stlink = sl; diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index c98424348..4fa39de4c 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -77,7 +77,30 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) else return -1; } - else { + else if ( starts_with(av[0], "--flash=") ) { + const char *arg = av[0] + strlen("--flash="); + char *ep = 0; + + o->flash_size = (uint32_t)strtoul(arg,&ep,0); + while ( *ep ) { + switch ( *ep++ ) { + case 0: + break; + case 'k': + case 'K': + o->flash_size *= 1024u; + break; + case 'm': + case 'M': + o->flash_size *= 1024u * 1024u; + break; + default: + fprintf(stderr,"Invalid --flash=%s\n",arg); + return -1; + } + } + } + else { break; // non-option found } From 78ced6a325b174626959baef6e3b014e72cfcf0e Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 24 Mar 2017 23:11:09 +0100 Subject: [PATCH 0560/1435] Don't use `%zx` because it's unsupported on mingw64 (#578) * Don't use `%zx` because it's unsupported on mingw64 * Also check that no warnings happen on travis * Prefer `unsigned int` over `unsigned` * Install libusb through the travis whitelist instead of manually * Test stlink against clang and gcc through the travis "compiler" flag instead of a manual matrix * Re-add osx * Fix warning on gcc --- .travis.sh | 2 +- .travis.yml | 19 ++++------ cmake/CFlags.cmake | 3 +- src/gdbserver/gdb-server.c | 74 +++++++++++++++++++------------------- src/tools/gui/stlink-gui.c | 4 +-- src/tools/info.c | 6 ++-- 6 files changed, 52 insertions(+), 56 deletions(-) diff --git a/.travis.sh b/.travis.sh index 82c1fd862..06e95ef80 100755 --- a/.travis.sh +++ b/.travis.sh @@ -7,7 +7,7 @@ echo "----" if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq || true - sudo apt-get install -qq -y --no-install-recommends libusb-1.0.0-dev libgtk-3-dev + sudo apt-get install -qq -y --no-install-recommends libgtk-3-dev else brew install libusb fi diff --git a/.travis.yml b/.travis.yml index 2bf170d2b..25d1859f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,11 @@ sudo: true language: c +compiler: + - gcc + - clang +os: + - linux + - osx addons: apt: sources: @@ -10,20 +16,9 @@ addons: # - clang-3.8 - g++-5 - gcc-5 + - libusb-1.0.0-dev script: - git fetch --tags - printenv - cmake --version - ./.travis.sh -matrix: - include: - - os: linux - compiler: clang -# - os: linux -# compiler: clang-3.8 - - os: linux - compiler: gcc-5 -# - os: linux -# compiler: clang-3.8 - - os: osx - compiler: clang diff --git a/cmake/CFlags.cmake b/cmake/CFlags.cmake index b17463707..b76856d24 100644 --- a/cmake/CFlags.cmake +++ b/cmake/CFlags.cmake @@ -44,6 +44,7 @@ endif () if(${CMAKE_BUILD_TYPE} MATCHES "Debug") add_cflag_if_supported("-ggdb") add_cflag_if_supported("-O0") -elseif() +else() add_cflag_if_supported("-O2") + add_cflag_if_supported("-Werror") endif() diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index fddf48fcf..4d4a9cfce 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -393,20 +393,20 @@ static const char* const memory_map_template_F2 = "" "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram + " " // code = sram, bootrom or flash; flash is bigger + " " // sram " " //Sectors 0..3 " 0x4000" //16kB " " " " //Sector 4 " 0x10000" //64kB " " - " " //Sectors 5.. + " " //Sectors 5.. " 0x20000" //128kB " " " " // peripheral regs " " // cortex regs - " " // bootrom + " " // bootrom " " // option byte area ""; @@ -415,10 +415,10 @@ static const char* const memory_map_template_L4 = "" "" - " " // code = sram, bootrom or flash; flash is bigger + " " // code = sram, bootrom or flash; flash is bigger " " // SRAM2 (32 KB) " " // SRAM1 (96 KB) - " " + " " " 0x800" " " " " // peripheral regs @@ -434,14 +434,14 @@ static const char* const memory_map_template = "" "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram 8k - " " - " 0x%zx" + " " // code = sram, bootrom or flash; flash is bigger + " " // sram 8k + " " + " 0x%x" " " " " // peripheral regs " " // cortex regs - " " // bootrom + " " // bootrom " " // option byte area ""; @@ -452,7 +452,7 @@ static const char* const memory_map_template_F7 = "" " " // ITCM ram 16kB " " // ITCM flash - " " // sram + " " // sram " " // Sectors 0..3 " 0x8000" // 32kB " " @@ -505,24 +505,24 @@ char* make_memory_map(stlink_t *sl) { strcpy(map, memory_map_template_F4_DE); } else if(sl->core_id==STM32F7_CORE_ID) { snprintf(map, sz, memory_map_template_F7, - sl->sram_size); + (unsigned int)sl->sram_size); } else if(sl->chip_id==STLINK_CHIPID_STM32_F4_HD) { strcpy(map, memory_map_template_F4_HD); } else if(sl->chip_id==STLINK_CHIPID_STM32_F2) { snprintf(map, sz, memory_map_template_F2, - sl->flash_size, - sl->sram_size, - sl->flash_size - 0x20000, - sl->sys_base, sl->sys_size); + (unsigned int)sl->flash_size, + (unsigned int)sl->sram_size, + (unsigned int)sl->flash_size - 0x20000, + (unsigned int)sl->sys_base, (unsigned int)sl->sys_size); } else if(sl->chip_id==STLINK_CHIPID_STM32_L4) { snprintf(map, sz, memory_map_template_L4, - sl->flash_size, sl->flash_size); + (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); } else { snprintf(map, sz, memory_map_template, - sl->flash_size, - sl->sram_size, - sl->flash_size, sl->flash_pgsz, - sl->sys_base, sl->sys_size); + (unsigned int)sl->flash_size, + (unsigned int)sl->sram_size, + (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz, + (unsigned int)sl->sys_base, (unsigned int)sl->sys_size); } return map; } @@ -831,7 +831,7 @@ static int flash_go(stlink_t *sl) { stlink_calculate_pagesize(sl, page); DLOG("flash_do: page %08x\n", page); - unsigned len = (length > FLASH_PAGE) ? (unsigned) FLASH_PAGE : length; + unsigned len = (length > FLASH_PAGE) ? (unsigned int) FLASH_PAGE : length; int ret = stlink_write_flash(sl, page, fb->data + (page - fb->addr), len, 0); if (ret < 0) goto error; @@ -1109,7 +1109,7 @@ int serve(stlink_t *sl, st_state_t *st) { params = separator + 1; } - unsigned queryNameLength = (unsigned) (separator - &packet[1]); + unsigned queryNameLength = (unsigned int) (separator - &packet[1]); char* queryName = calloc(queryNameLength + 1, 1); strncpy(queryName, &packet[1], queryNameLength); @@ -1135,8 +1135,8 @@ int serve(stlink_t *sl, st_state_t *st) { __s_addr = strsep(&tok, ","); s_length = tok; - unsigned addr = (unsigned) strtoul(__s_addr, NULL, 16), - length = (unsigned) strtoul(s_length, NULL, 16); + unsigned addr = (unsigned int) strtoul(__s_addr, NULL, 16), + length = (unsigned int) strtoul(s_length, NULL, 16); DLOG("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", type, op, annex, addr, length); @@ -1150,7 +1150,7 @@ int serve(stlink_t *sl, st_state_t *st) { data = target_description_F4; if(data) { - unsigned data_length = (unsigned) strlen(data); + unsigned data_length = (unsigned int) strlen(data); if(addr + length > data_length) length = data_length - addr; @@ -1265,8 +1265,8 @@ int serve(stlink_t *sl, st_state_t *st) { __s_addr = strsep(&tok, ","); s_length = tok; - unsigned addr = (unsigned) strtoul(__s_addr, NULL, 16), - length = (unsigned) strtoul(s_length, NULL, 16); + unsigned addr = (unsigned int) strtoul(__s_addr, NULL, 16), + length = (unsigned int) strtoul(s_length, NULL, 16); DLOG("FlashErase: addr:%08x,len:%04x\n", addr, length); @@ -1283,8 +1283,8 @@ int serve(stlink_t *sl, st_state_t *st) { __s_addr = strsep(&tok, ":"); data = tok; - unsigned addr = (unsigned) strtoul(__s_addr, NULL, 16); - unsigned data_length = status - (unsigned) (data - packet); + unsigned addr = (unsigned int) strtoul(__s_addr, NULL, 16); + unsigned data_length = status - (unsigned int) (data - packet); // Length of decoded data cannot be more than // encoded, as escapes are removed. @@ -1433,7 +1433,7 @@ int serve(stlink_t *sl, st_state_t *st) { break; case 'p': { - unsigned id = (unsigned) strtoul(&packet[1], NULL, 16); + unsigned id = (unsigned int) strtoul(&packet[1], NULL, 16); unsigned myreg = 0xDEADDEAD; if(id < 16) { @@ -1480,8 +1480,8 @@ int serve(stlink_t *sl, st_state_t *st) { char* s_reg = &packet[1]; char* s_value = strstr(&packet[1], "=") + 1; - unsigned reg = (unsigned) strtoul(s_reg, NULL, 16); - unsigned value = (unsigned) strtoul(s_value, NULL, 16); + unsigned reg = (unsigned int) strtoul(s_reg, NULL, 16); + unsigned value = (unsigned int) strtoul(s_value, NULL, 16); if(reg < 16) { stlink_write_reg(sl, ntohl(value), reg); @@ -1530,12 +1530,12 @@ int serve(stlink_t *sl, st_state_t *st) { char* s_count = strstr(&packet[1], ",") + 1; stm32_addr_t start = (stm32_addr_t) strtoul(s_start, NULL, 16); - unsigned count = (unsigned) strtoul(s_count, NULL, 16); + unsigned count = (unsigned int) strtoul(s_count, NULL, 16); unsigned adj_start = start % 4; unsigned count_rnd = (count + adj_start + 4 - 1) / 4 * 4; if (count_rnd > sl->flash_pgsz) - count_rnd = (unsigned) sl->flash_pgsz; + count_rnd = (unsigned int) sl->flash_pgsz; if (count_rnd > 0x1800) count_rnd = 0x1800; if (count_rnd < count) @@ -1561,7 +1561,7 @@ int serve(stlink_t *sl, st_state_t *st) { char* hexdata = strstr(packet, ":") + 1; stm32_addr_t start = (stm32_addr_t) strtoul(s_start, NULL, 16); - unsigned count = (unsigned) strtoul(s_count, NULL, 16); + unsigned count = (unsigned int) strtoul(s_count, NULL, 16); int err = 0; if(start % 4) { diff --git a/src/tools/gui/stlink-gui.c b/src/tools/gui/stlink-gui.c index 535f9bb33..d45db6ff2 100644 --- a/src/tools/gui/stlink-gui.c +++ b/src/tools/gui/stlink-gui.c @@ -735,7 +735,7 @@ dnd_received_cb (GtkWidget *widget, gint y, GtkSelectionData *selection_data, guint target_type, - guint time, + guint timestamp, gpointer data) { GFile *file_uri; @@ -783,7 +783,7 @@ dnd_received_cb (GtkWidget *widget, gtk_drag_finish (context, TRUE, gdk_drag_context_get_suggested_action (context) == GDK_ACTION_MOVE, - time); + timestamp); } void diff --git a/src/tools/info.c b/src/tools/info.c index 2e3efc64d..2ad8f2c09 100644 --- a/src/tools/info.c +++ b/src/tools/info.c @@ -114,11 +114,11 @@ static int print_data(char **av) stlink_enter_swd_mode(sl); if (strcmp(av[1], "--flash") == 0) - printf("0x%zx\n", sl->flash_size); + printf("0x%x\n", (unsigned int)sl->flash_size); else if (strcmp(av[1], "--sram") == 0) - printf("0x%zx\n", sl->sram_size); + printf("0x%x\n", (unsigned int)sl->sram_size); else if (strcmp(av[1], "--pagesize") == 0) - printf("0x%zx\n", sl->flash_pgsz); + printf("0x%x\n", (unsigned int)sl->flash_pgsz); else if (strcmp(av[1], "--chipid") == 0) printf("0x%.4x\n", sl->chip_id); else if (strcmp(av[1], "--serial") == 0) From 6902f473fc94c06c2633a9b92bd9479d65bc7108 Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Tue, 4 Apr 2017 00:05:06 +0300 Subject: [PATCH 0561/1435] fix few -Wformat warnings (#582) * fix wrong libusb extract command * update libusb to 1.0.21 under windows * fix few -Wformat warnings * add usleep realisation for win32 under mingw --- src/common.c | 4 ++-- src/mingw/mingw.c | 12 ++++++++++++ src/mingw/mingw.h | 1 + src/tools/flash.c | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/common.c b/src/common.c index c55bff54a..74b96f5da 100644 --- a/src/common.c +++ b/src/common.c @@ -1753,7 +1753,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t return -1; } fprintf(stdout,"\rFlash page at addr: 0x%08lx erased", - (unsigned long)addr + off); + (unsigned long)(addr + off)); fflush(stdout); page_count++; } @@ -1934,7 +1934,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t if (sl->verbose >= 1) { /* show progress. writing procedure is slow and previous errors are misleading */ - fprintf(stdout, "\r%3u/%lu pages written", write_block_count++, (unsigned long)len/sl->flash_pgsz); + fprintf(stdout, "\r%3u/%lu pages written", write_block_count++, (unsigned long)(len/sl->flash_pgsz)); fflush(stdout); } } diff --git a/src/mingw/mingw.c b/src/mingw/mingw.c index 3c5d025a3..ee0515972 100644 --- a/src/mingw/mingw.c +++ b/src/mingw/mingw.c @@ -265,6 +265,18 @@ char *win32_strsep (char **stringp, const char *delim) /* NOTREACHED */ } +void usleep(DWORD waitTime) +{ + LARGE_INTEGER perf_cnt, start, now; + + QueryPerformanceFrequency(&perf_cnt); + QueryPerformanceCounter(&start); + + do { + QueryPerformanceCounter((LARGE_INTEGER*) &now); + } while ((now.QuadPart - start.QuadPart) / (float)perf_cnt.QuadPart * 1000 * 1000 < waitTime); +} + #endif diff --git a/src/mingw/mingw.h b/src/mingw/mingw.h index cb333016c..242c8eb98 100644 --- a/src/mingw/mingw.h +++ b/src/mingw/mingw.h @@ -66,5 +66,6 @@ ssize_t win32_read_socket(SOCKET fd, void *buf, int n); ssize_t win32_write_socket(SOCKET fd, void *buf, int n); static inline void sleep(unsigned ms) { Sleep(ms); } +void usleep(DWORD waitTime); #endif diff --git a/src/tools/flash.c b/src/tools/flash.c index 6fe365f88..508c4aa84 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -67,7 +67,7 @@ int main(int ac, char** av) if ( o.flash_size != 0u && o.flash_size != sl->flash_size ) { sl->flash_size = o.flash_size; - printf("Forcing flash size: --flash=0x%08zX\n",sl->flash_size); + printf("Forcing flash size: --flash=0x%08X\n",(unsigned int)sl->flash_size); } sl->verbose = o.log_level; From 47ab2901b9d6d2819117775179a1d0fb8cc3df72 Mon Sep 17 00:00:00 2001 From: Karol Szuster Date: Wed, 5 Apr 2017 20:48:07 +0200 Subject: [PATCH 0562/1435] Fix installation path for shared objects (#581) On 64bit linux all shared objects should go to /usr/lib64. With this path package maintainters should be able to override library path by setting STLINK_LIBRARY_PATH. --- CMakeLists.txt | 5 +++-- usr/lib/pkgconfig/CMakeLists.txt | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 285b5c713..626ba34a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics Stlink Tools") set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "Udev rules directory") set(STLINK_MODPROBED_DIR "/etc/modprobe.d" CACHE PATH "modprobe.d directory") +set(STLINK_LIBRARY_PATH "lib/${CMAKE_LIBRARY_PATH}" CACHE PATH "Target lib directory") option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) @@ -108,7 +109,7 @@ else() endif() install(TARGETS ${STLINK_LIB_SHARED} - DESTINATION lib/${CMAKE_LIBRARY_PATH} + DESTINATION ${STLINK_LIBRARY_PATH} ) ### @@ -138,7 +139,7 @@ endif() set_target_properties(${STLINK_LIB_STATIC} PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) install(TARGETS ${STLINK_LIB_STATIC} - ARCHIVE DESTINATION lib/${CMAKE_LIBRARY_PATH} + ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH} ) ### diff --git a/usr/lib/pkgconfig/CMakeLists.txt b/usr/lib/pkgconfig/CMakeLists.txt index 5ddc500ca..1d7bcd1dc 100644 --- a/usr/lib/pkgconfig/CMakeLists.txt +++ b/usr/lib/pkgconfig/CMakeLists.txt @@ -10,5 +10,5 @@ configure_file( ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" - DESTINATION lib/${CMAKE_LIBRARY_PATH}/pkgconfig/ + DESTINATION ${STLINK_LIBRARY_PATH}/pkgconfig/ ) From eb03b7c2903307410da97b897662b24c730b1014 Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Thu, 6 Apr 2017 22:16:54 +0300 Subject: [PATCH 0563/1435] Get rid of unused defines in mingw.h (#583) * Get rid of unused defines in mingw.h --- src/mingw/mingw.h | 9 --------- src/mmap.c | 4 +++- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/mingw/mingw.h b/src/mingw/mingw.h index 242c8eb98..cd1441073 100644 --- a/src/mingw/mingw.h +++ b/src/mingw/mingw.h @@ -5,15 +5,6 @@ #define _USE_W32_SOCKETS 1 #include -#define ENOTCONN WSAENOTCONN -#define EWOULDBLOCK WSAEWOULDBLOCK -#define ENOBUFS WSAENOBUFS -#define ECONNRESET WSAECONNRESET -#define ESHUTDOWN WSAESHUTDOWN -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#define EPROTONOSUPPORT WSAEPROTONOSUPPORT -#define EINPROGRESS WSAEINPROGRESS -#define EISCONN WSAEISCONN /* winsock doesn't feature poll(), so there is a version implemented * in terms of select() in mingw.c. The following definitions diff --git a/src/mmap.c b/src/mmap.c index bee0dcece..cc5346f18 100644 --- a/src/mmap.c +++ b/src/mmap.c @@ -19,15 +19,17 @@ void *mmap (void *addr, size_t len, int prot, int flags, int fd, long long offs count = read(fd, buf, len); - if (count != len) { + if (count != (ssize_t)len) { free (buf); return MAP_FAILED; } return buf; + (void)flags; } int munmap (void *addr, size_t len) { free (addr); return 0; + (void)len; } From 3d24377c2878fc328fb09b67cdfbda529d209417 Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Fri, 7 Apr 2017 20:17:46 +0300 Subject: [PATCH 0564/1435] Now able build by MinGW. All warnings were fixed. (#584) * fix wrong libusb extract command * update libusb to 1.0.21 under windows * fix few -Wformat warnings * add usleep realisation for win32 * Get rid of unused defines in mimgw.h * fix format warning for mingw * Add prefix SEMIXOST_ to semihost defines. Fix redefine warnings of mingw. --- src/gdbserver/gdb-server.c | 2 +- src/gdbserver/semihosting.c | 20 +++++++-------- src/gdbserver/semihosting.h | 50 ++++++++++++++++++------------------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 4d4a9cfce..e2a70e9ea 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -1428,7 +1428,7 @@ int serve(stlink_t *sl, st_state_t *st) { reply = calloc(8 * 16 + 1, 1); for(int i = 0; i < 16; i++) - sprintf(&reply[i * 8], "%08x", htonl(regp.r[i])); + sprintf(&reply[i * 8], "%08x", (uint32_t)htonl(regp.r[i])); break; diff --git a/src/gdbserver/semihosting.c b/src/gdbserver/semihosting.c index 34591d120..312b1517e 100644 --- a/src/gdbserver/semihosting.c +++ b/src/gdbserver/semihosting.c @@ -157,7 +157,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { DLOG("Do semihosting R0=0x%08x R1=0x%08x\n", r0, r1); switch (r0) { - case SYS_OPEN: + case SEMIHOST_SYS_OPEN: { uint32_t args[3]; uint32_t name_address; @@ -220,7 +220,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { free(name); break; } - case SYS_CLOSE: + case SEMIHOST_SYS_CLOSE: { uint32_t args[1]; int fd; @@ -242,7 +242,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { DLOG("Semihosting: return %d\n", *ret); break; } - case SYS_WRITE: + case SEMIHOST_SYS_WRITE: { uint32_t args[3]; uint32_t buffer_address; @@ -300,7 +300,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { free(buffer); break; } - case SYS_READ: + case SEMIHOST_SYS_READ: { uint32_t args[3]; uint32_t buffer_address; @@ -358,13 +358,13 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { free(buffer); break; } - case SYS_ERRNO: + case SEMIHOST_SYS_ERRNO: { *ret = (uint32_t)saved_errno; DLOG("Semihosting: Errno return %d\n", *ret); break; } - case SYS_REMOVE: + case SEMIHOST_SYS_REMOVE: { uint32_t args[2]; uint32_t name_address; @@ -418,7 +418,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { free(name); break; } - case SYS_SEEK: + case SEMIHOST_SYS_SEEK: { uint32_t args[2]; int fd; @@ -446,7 +446,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { DLOG("Semihosting: return %d\n", *ret); break; } - case SYS_WRITEC: + case SEMIHOST_SYS_WRITEC: { uint8_t c; if (mem_read_u8(sl, r1, &c) == 0) { @@ -457,13 +457,13 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { } break; } - case SYS_READC: + case SEMIHOST_SYS_READC: { uint8_t c = getchar(); *ret = c; break; } - case SYS_WRITE0: + case SEMIHOST_SYS_WRITE0: { uint8_t buf[WRITE0_BUFFER_SIZE]; diff --git a/src/gdbserver/semihosting.h b/src/gdbserver/semihosting.h index 392d31f7d..8157df9df 100644 --- a/src/gdbserver/semihosting.h +++ b/src/gdbserver/semihosting.h @@ -3,31 +3,31 @@ #include -#define SYS_OPEN 0x01 -#define SYS_CLOSE 0x02 -#define SYS_WRITEC 0x03 -#define SYS_WRITE0 0x04 -#define SYS_WRITE 0x05 -#define SYS_READ 0x06 -#define SYS_READC 0x07 -#define SYS_ISERROR 0x08 -#define SYS_ISTTY 0x09 -#define SYS_SEEK 0x0A - -#define SYS_FLEN 0x0C -#define SYS_TMPNAM 0x0D -#define SYS_REMOVE 0x0E -#define SYS_RENAME 0x0E -#define SYS_CLOCK 0x10 -#define SYS_TIME 0x11 - -#define SYS_ERRNO 0x13 - -#define SYS_GET_CMD 0x15 -#define SYS_HEAPINFO 0x16 - -#define SYS_ELAPSED 0x30 -#define SYS_TICKFREQ 0x31 +#define SEMIHOST_SYS_OPEN 0x01 +#define SEMIHOST_SYS_CLOSE 0x02 +#define SEMIHOST_SYS_WRITEC 0x03 +#define SEMIHOST_SYS_WRITE0 0x04 +#define SEMIHOST_SYS_WRITE 0x05 +#define SEMIHOST_SYS_READ 0x06 +#define SEMIHOST_SYS_READC 0x07 +#define SEMIHOST_SYS_ISERROR 0x08 +#define SEMIHOST_SYS_ISTTY 0x09 +#define SEMIHOST_SYS_SEEK 0x0A + +#define SEMIHOST_SYS_FLEN 0x0C +#define SEMIHOST_SYS_TMPNAM 0x0D +#define SEMIHOST_SYS_REMOVE 0x0E +#define SEMIHOST_SYS_RENAME 0x0E +#define SEMIHOST_SYS_CLOCK 0x10 +#define SEMIHOST_SYS_TIME 0x11 + +#define SEMIHOST_SYS_ERRNO 0x13 + +#define SEMIHOST_SYS_GET_CMD 0x15 +#define SEMIHOST_SYS_HEAPINFO 0x16 + +#define SEMIHOST_SYS_ELAPSED 0x30 +#define SEMIHOST_SYS_TICKFREQ 0x31 int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret); From cc3a5705099019e01dc59f7907d0c5b1b85878d8 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Fri, 5 May 2017 12:16:38 +0200 Subject: [PATCH 0565/1435] skip GTK detection if we're cross-compiling (#588) It seems that stlink cannot use CMake's standard mechanism to find GTK3. Cmake's GTK3 detection supports only Unix at the moment. Therefore, stlink uses pkg-config to find GTK3. The downside of this is that Cmake's cross-compiler settings are not taken into account. Even if we're cross-compiling, CMake will find a local installation of GTK3 and compilation of the GUI fails. As a simple fix, we skip the GTK3 detection if we're cross-compiling. (In the long run, we should use a more advanced mechanism to find GTK3.) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 626ba34a6..afa7fdeff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ include(cmake/CFlags.cmake) # Dependencies ### find_package(LibUSB REQUIRED) -if (NOT APPLE AND NOT WIN32) +if (NOT APPLE AND NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) find_package(PkgConfig) pkg_check_modules(gtk gtk+-3.0) endif () From 5c10d4b83a4703edb492c76f1427c4a4e1a568b1 Mon Sep 17 00:00:00 2001 From: Anton Guda Date: Mon, 8 May 2017 17:00:02 +0300 Subject: [PATCH 0566/1435] Fix compilation warning for GCC 7, fixes #590 --- src/gdbserver/gdb-server.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index e2a70e9ea..223514a3c 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -1640,6 +1640,7 @@ int serve(stlink_t *sl, st_state_t *st) { break; } } + break; default: reply = strdup(""); @@ -1662,6 +1663,7 @@ int serve(stlink_t *sl, st_state_t *st) { case '4' : // remove access watchpoint if(delete_data_watchpoint(sl, addr) < 0) { reply = strdup("E00"); + break; } else { reply = strdup("OK"); break; From 0498621a46e1d2638d4a4c1771fbc84cdb9b4cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Mellstr=C3=B6m?= Date: Sun, 14 May 2017 12:42:14 +0200 Subject: [PATCH 0567/1435] Added support for flashing second bank on STM32F10x_XL (#592) --- include/stlink.h | 3 +- src/chipid.c | 2 +- src/common.c | 88 ++++++++++++++++++++++++++++++++++++++++++---- src/flash_loader.c | 12 +++++-- 4 files changed, 95 insertions(+), 10 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 813086e15..ac0bfe190 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -83,7 +83,8 @@ extern "C" { STLINK_FLASH_TYPE_F0, STLINK_FLASH_TYPE_L0, STLINK_FLASH_TYPE_F4, - STLINK_FLASH_TYPE_L4 + STLINK_FLASH_TYPE_L4, + STLINK_FLASH_TYPE_F1_XL, }; struct stlink_reg { diff --git a/src/chipid.c b/src/chipid.c index 15b2f563a..808a23c52 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -255,7 +255,7 @@ static const struct stlink_chipid_params devices[] = { { .chip_id = STLINK_CHIPID_STM32_F1_XL, .description = "F1 XL-density device", - .flash_type = STLINK_FLASH_TYPE_F0, + .flash_type = STLINK_FLASH_TYPE_F1_XL, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, .sram_size = 0x18000, diff --git a/src/common.c b/src/common.c index 74b96f5da..b2a5db55f 100644 --- a/src/common.c +++ b/src/common.c @@ -35,6 +35,13 @@ #define FLASH_OBR (FLASH_REGS_ADDR + 0x1c) #define FLASH_WRPR (FLASH_REGS_ADDR + 0x20) +// STM32F10x_XL has two flash memory banks with separate registers to control the second bank. +#define FLASH_KEYR2 (FLASH_REGS_ADDR + 0x44) +#define FLASH_SR2 (FLASH_REGS_ADDR + 0x4c) +#define FLASH_CR2 (FLASH_REGS_ADDR + 0x50) +#define FLASH_AR2 (FLASH_REGS_ADDR + 0x54) +#define FLASH_BANK2_START_ADDR 0x08080000 + // For STM32F05x, the RDPTR_KEY may be wrong, but as it is not used anywhere... #define FLASH_RDPTR_KEY 0x00a5 #define FLASH_KEY1 0x45670123 @@ -189,6 +196,15 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { return res; } +static inline uint32_t read_flash_cr2(stlink_t *sl) { + uint32_t res; + stlink_read_debug32(sl, FLASH_CR2, &res); +#if DEBUG_FLASH + fprintf(stdout, "CR2:0x%x\n", res); +#endif + return res; +} + static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ uint32_t cr_lock_shift, cr = read_flash_cr(sl); @@ -219,6 +235,11 @@ static void unlock_flash(stlink_t *sl) { stlink_write_debug32(sl, key_reg, FLASH_KEY1); stlink_write_debug32(sl, key_reg, FLASH_KEY2); + + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + stlink_write_debug32(sl, FLASH_KEYR2, FLASH_KEY1); + stlink_write_debug32(sl, FLASH_KEYR2, FLASH_KEY2); + } } static int unlock_flash_if(stlink_t *sl) { @@ -251,6 +272,11 @@ static void lock_flash(stlink_t *sl) { n = read_flash_cr(sl) | (1 << cr_lock_shift); stlink_write_debug32(sl, cr_reg, n); + + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + n = read_flash_cr2(sl) | (1 << cr_lock_shift); + stlink_write_debug32(sl, FLASH_CR2, n); + } } @@ -293,6 +319,11 @@ static void set_flash_cr_per(stlink_t *sl) { stlink_write_debug32(sl, FLASH_CR, n); } +static void set_flash_cr2_per(stlink_t *sl) { + const uint32_t n = 1 << FLASH_CR_PER; + stlink_write_debug32(sl, FLASH_CR2, n); +} + static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PER); stlink_write_debug32(sl, FLASH_CR, n); @@ -367,6 +398,14 @@ static void set_flash_cr_strt(stlink_t *sl) { stlink_write_debug32(sl, cr_reg, val); } +static void set_flash_cr2_strt(stlink_t *sl) { + uint32_t val; + + stlink_read_debug32(sl, FLASH_CR2, &val); + val |= 1 << FLASH_CR_STRT; + stlink_write_debug32(sl, FLASH_CR2, val); +} + static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res, sr_reg; @@ -382,8 +421,15 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { return res; } +static inline uint32_t read_flash_sr2(stlink_t *sl) { + uint32_t res; + stlink_read_debug32(sl, FLASH_SR2, &res); + return res; +} + static inline unsigned int is_flash_busy(stlink_t *sl) { uint32_t sr_busy_shift; + unsigned int res; if (sl->flash_type == STLINK_FLASH_TYPE_F4) sr_busy_shift = FLASH_F4_SR_BSY; @@ -392,7 +438,13 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { else sr_busy_shift = FLASH_SR_BSY; - return read_flash_sr(sl) & (1 << sr_busy_shift); + res = read_flash_sr(sl) & (1 << sr_busy_shift); + + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + res |= read_flash_sr2(sl) & (1 << sr_busy_shift); + } + + return res; } static void wait_flash_busy(stlink_t *sl) { @@ -435,6 +487,10 @@ static inline void write_flash_ar(stlink_t *sl, uint32_t n) { stlink_write_debug32(sl, FLASH_AR, n); } +static inline void write_flash_ar2(stlink_t *sl, uint32_t n) { + stlink_write_debug32(sl, FLASH_AR2, n); +} + static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n) { uint32_t x = read_flash_cr(sl); x &= ~(0x03 << 8); @@ -1531,7 +1587,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_F0) { + } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr < FLASH_BANK2_START_ADDR))) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1550,6 +1606,27 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) /* wait for completion */ wait_flash_busy(sl); + /* relock the flash */ + lock_flash(sl); + } else if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr >= FLASH_BANK2_START_ADDR)) { + /* wait for ongoing op to finish */ + wait_flash_busy(sl); + + /* unlock if locked */ + unlock_flash_if(sl); + + /* set the page erase bit */ + set_flash_cr2_per(sl); + + /* select the page to erase */ + write_flash_ar2(sl, flashaddr); + + /* start erase operation, reset by hw with bsy bit */ + set_flash_cr2_strt(sl); + + /* wait for completion */ + wait_flash_busy(sl); + /* relock the flash */ lock_flash(sl); } else { @@ -1908,8 +1985,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_F0) { - ILOG("Starting Flash write for VL/F0/F3 core id\n"); + } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + ILOG("Starting Flash write for VL/F0/F3/F1_XL core id\n"); /* flash loader initialization */ if (stlink_flash_loader_init(sl, &fl) == -1) { ELOG("stlink_flash_loader_init() == -1\n"); @@ -1924,8 +2001,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t /* unlock and set programming mode */ unlock_flash_if(sl); - set_flash_cr_pg(sl); - DLOG("Finished setting flash cr pg, running loader!\n"); + DLOG("Finished unlocking flash, running loader!\n"); if (stlink_flash_loader_run(sl, &fl, addr + (uint32_t) off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); return -1; diff --git a/src/flash_loader.c b/src/flash_loader.c index ed53a0c6b..96084ab27 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -4,6 +4,9 @@ #include #include +#define FLASH_REGS_BANK2_OFS 0x40 +#define FLASH_BANK2_START_ADDR 0x08080000 + /* from openocd, contrib/loaders/flash/stm32.s */ static const uint8_t loader_code_stm32vl[] = { 0x08, 0x4c, /* ldr r4, STM32_FLASH_BASE */ @@ -325,6 +328,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe struct stlink_reg rr; int i = 0; size_t count = 0; + uint32_t flash_base = 0; DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); // FIXME This can never return -1 @@ -334,7 +338,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe return -1; } - if (sl->flash_type == STLINK_FLASH_TYPE_F0) { + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { count = size / sizeof(uint16_t); if (size % sizeof(uint16_t)) ++count; @@ -348,11 +352,15 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe ++count; } + if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (target >= FLASH_BANK2_START_ADDR)) { + flash_base = FLASH_REGS_BANK2_OFS; + } + /* setup core */ stlink_write_reg(sl, fl->buf_addr, 0); /* source */ stlink_write_reg(sl, target, 1); /* target */ stlink_write_reg(sl, (uint32_t) count, 2); /* count */ - stlink_write_reg(sl, 0, 3); /* flash bank 0 (input), only used on F0, but armless fopr others */ + stlink_write_reg(sl, flash_base, 3); /* flash register base, only used on VL/F1_XL, but harmless for others */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ /* run loader */ From 55c057296ad15fa6de9909206098bd4eed8f6311 Mon Sep 17 00:00:00 2001 From: Sai Kalidindi Date: Thu, 18 May 2017 04:10:22 -0700 Subject: [PATCH 0568/1435] fix flashing to 'f0 device' targets (#595) Fixes #594. Pull request #592 (0498621) accidentally deleted the call to `set_flash_cr_pg`. --- src/common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common.c b/src/common.c index b2a5db55f..21285bbfb 100644 --- a/src/common.c +++ b/src/common.c @@ -2001,6 +2001,9 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t /* unlock and set programming mode */ unlock_flash_if(sl); + if (sl->flash_type != STLINK_FLASH_TYPE_F1_XL) { + set_flash_cr_pg(sl); + } DLOG("Finished unlocking flash, running loader!\n"); if (stlink_flash_loader_run(sl, &fl, addr + (uint32_t) off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); From 79d91786f7b3fc5b461246bf5a6be3626bb06572 Mon Sep 17 00:00:00 2001 From: orinem Date: Fri, 16 Jun 2017 23:05:47 -0700 Subject: [PATCH 0569/1435] Stop the sulk with GPL2016 on Windows (#602) * Fixes for VS2017. * Added a getopt implementation. * Added a unistd.h. * Corrected closing of sockets for Windows versions. * Fixed gdbserver CMakeLists.txt to play nice with VS2017. * Fixed include of getopt.h and unistd.h for WIN32. * Added a unistd.h. * Corrected closing of sockets for Windows versions. * Fixed gdbserver CMakeLists.txt to play nice with VS2017. * Override /MD to /MT for MSVC to match libusb's builds. * MSVC settings should be if (MSVC). * Don't busy-wait for long periods in usleep(). * Dynamic link to MSVC libusb binaries. * Added Visual Studio section to compiling.md. * Added -D_CRT_NONSTDC_NO_WARNINGS to MSVC flags. * Prevented some more warnings under MSVC. --- CMakeLists.txt | 7 ++ cmake/c_flag_overrides.cmake | 7 ++ cmake/modules/FindLibUSB.cmake | 4 +- doc/compiling.md | 31 +++++ include/stlink/sg.h | 8 ++ include/stlink/tools/flash.h | 2 +- src/common.c | 3 + src/gdbserver/CMakeLists.txt | 21 +++- src/gdbserver/gdb-remote.c | 2 +- src/gdbserver/gdb-server.c | 32 +++-- src/getopt/LICENSE.txt | 24 ++++ src/getopt/README.md | 21 ++++ src/getopt/getopt.c | 206 +++++++++++++++++++++++++++++++++ src/getopt/getopt.h | 38 ++++++ src/mingw/mingw.c | 28 ++++- src/mingw/mingw.h | 21 +++- src/usb.c | 10 ++ src/win32/unistd.h | 60 ++++++++++ tests/flash.c | 21 ++-- tests/sg.c | 4 + 20 files changed, 515 insertions(+), 35 deletions(-) create mode 100644 cmake/c_flag_overrides.cmake create mode 100644 src/getopt/LICENSE.txt create mode 100644 src/getopt/README.md create mode 100644 src/getopt/getopt.c create mode 100644 src/getopt/getopt.h create mode 100644 src/win32/unistd.h diff --git a/CMakeLists.txt b/CMakeLists.txt index afa7fdeff..d0660cf05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 2.8.7) +set(CMAKE_USER_MAKE_RULES_OVERRIDE cmake/c_flag_overrides.cmake) project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics Stlink Tools") set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "Udev rules directory") @@ -71,6 +72,12 @@ include_directories(${LIBUSB_INCLUDE_DIR}) include_directories(include) include_directories(${PROJECT_BINARY_DIR}/include) include_directories(src/mingw) +if (MSVC) + include_directories(src/win32) + include_directories(src/getopt) + # Use string.h rather than strings.h and disable annoying warnings + add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) +endif () ### # Shared library diff --git a/cmake/c_flag_overrides.cmake b/cmake/c_flag_overrides.cmake new file mode 100644 index 000000000..663e08175 --- /dev/null +++ b/cmake/c_flag_overrides.cmake @@ -0,0 +1,7 @@ +if(MSVC) + message(STATUS "MSVC C Flags override to /MT") + set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") + set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") + set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") + set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") +endif() diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index b106018d2..844f3dc54 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -67,10 +67,10 @@ if (MSYS OR MINGW) elseif(CMAKE_VS_PLATFORM_NAME) if (CMAKE_SIZEOF_VOID_P EQUAL 8) find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/static) + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll) else () find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/static) + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll) endif () else() find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} diff --git a/doc/compiling.md b/doc/compiling.md index 296d64b17..3518d1079 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -139,3 +139,34 @@ Check and execute (in the script folder) `\scripts\mingw64-build.bat NOTE: when installing different toolchains make sure you edit the path in the `mingw64-build.bat` the build script uses currently `C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin` + +## Windows (Visual Studio) + +### Prerequisites + +* 7Zip +* CMake (tested with version 3.9.0-rc2) +* Visual Studio 2017 Community (other versions will likely work but are untested; the Community edition is free for open source +development) + +### Installation + +1. Install 7Zip from +2. Install CMake from +3. Git clone or download stlink sourcefiles zip + +### Building + +These instructions are for a 32bit version. + +In a command prompt, change directory to the folder where the stlink files were cloned (or unzipped). +Make sure the build folder exists (`mkdir build` if not). +From the build folder, run cmake (`cd build; cmake ..`). + +This will create a solution (stlink.sln) in the build folder. Open it in Visual Studio, select the Solution Configuration (Debug or +Release) and build the solution normally (F7). + +NOTES: This solution will link to the dll version of libusb-1.0. To debug or run the executable, the dll version of libusb-1.0 must +be either on the path, or in the same folder as the executable. It can be copied from here: +`build\3thparty\libusb-1.0.21\MS32\dll\libusb-1.0.dll`. + diff --git a/include/stlink/sg.h b/include/stlink/sg.h index 057f996a2..e521ba217 100644 --- a/include/stlink/sg.h +++ b/include/stlink/sg.h @@ -8,7 +8,15 @@ #ifndef STLINK_SG_H #define STLINK_SG_H +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4200 4255 4668 4820) #include +#pragma warning(pop) +#else +#include +#endif + #include "stlink.h" #ifdef __cplusplus diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index 35b3a4251..3d1375aa2 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -23,7 +23,7 @@ struct flash_opts size_t flash_size; /* --flash=n[k][m] */ }; -#define FLASH_OPTS_INITIALIZER {0, NULL, {}, NULL, 0, 0, 0, 0, 0, 0 } +#define FLASH_OPTS_INITIALIZER {0, NULL, { 0 }, NULL, 0, 0, 0, 0, 0, 0 } int flash_get_opts(struct flash_opts* o, int ac, char** av); diff --git a/src/common.c b/src/common.c index 21285bbfb..2297eee47 100644 --- a/src/common.c +++ b/src/common.c @@ -18,6 +18,9 @@ #ifndef _WIN32 #define O_BINARY 0 //! @todo get rid of this OH MY (@xor-gate) #endif +#ifdef _MSC_VER +#define __attribute__(x) +#endif /* todo: stm32l15xxx flash memory, pm0062 manual */ diff --git a/src/gdbserver/CMakeLists.txt b/src/gdbserver/CMakeLists.txt index a41890c70..2393690ce 100644 --- a/src/gdbserver/CMakeLists.txt +++ b/src/gdbserver/CMakeLists.txt @@ -1,9 +1,18 @@ -add_executable(st-util gdb-remote.c - gdb-remote.h - gdb-server.c - gdb-server.h - semihosting.c - semihosting.h) +set(STUTIL_SOURCE + gdb-remote.c + gdb-remote.h + gdb-server.c + gdb-server.h + semihosting.c + semihosting.h) + +if (MSVC) + # We need a getopt from somewhere... + set(STUTIL_SOURCE "${STUTIL_SOURCE};../getopt/getopt.c") +endif() + +add_executable(st-util ${STUTIL_SOURCE}) + if (WIN32 OR APPLE) target_link_libraries(st-util ${STLINK_LIB_STATIC}) else() diff --git a/src/gdbserver/gdb-remote.c b/src/gdbserver/gdb-remote.c index a5d3f4c03..83c5e093a 100644 --- a/src/gdbserver/gdb-remote.c +++ b/src/gdbserver/gdb-remote.c @@ -8,7 +8,7 @@ #include #include #include -#ifdef __MINGW32__ +#if defined(__MINGW32__) || defined(_MSC_VER) #include #else #include diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 223514a3c..d7da544fa 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -10,7 +10,11 @@ #include #include #include -#ifdef __MINGW32__ +#if defined(_MSC_VER) +#include +#define __attribute__(x) +#endif +#if defined(__MINGW32__) || defined(_MSC_VER) #include #else #include @@ -239,7 +243,7 @@ int main(int argc, char** argv) { sl->verbose=0; current_memory_map = make_memory_map(sl); -#ifdef __MINGW32__ +#if defined(__MINGW32__) || defined(_MSC_VER) WSADATA wsadata; if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0 ) { goto winsock_error; @@ -260,7 +264,7 @@ int main(int argc, char** argv) { stlink_run(sl); } while (state.persistent); -#ifdef __MINGW32__ +#if defined(__MINGW32__) || defined(_MSC_VER) winsock_error: WSACleanup(); #endif @@ -1061,7 +1065,11 @@ int serve(stlink_t *sl, st_state_t *st) { return 1; } - close(sock); +#if defined(__MINGW32__) || defined(_MSC_VER) + win32_close_socket(sock); +#else + close(sock); +#endif stlink_force_debug(sl); if (st->reset) { @@ -1084,8 +1092,8 @@ int serve(stlink_t *sl, st_state_t *st) { int status = gdb_recv_packet(client, &packet); if(status < 0) { ELOG("cannot recv: %d\n", status); -#ifdef __MINGW32__ - win32_close_socket(sock); +#if defined(__MINGW32__) || defined(_MSC_VER) + win32_close_socket(client); #endif return 1; } @@ -1337,8 +1345,8 @@ int serve(stlink_t *sl, st_state_t *st) { status = gdb_check_for_interrupt(client); if(status < 0) { ELOG("cannot check for int: %d\n", status); -#ifdef __MINGW32__ - win32_close_socket(sock); +#if defined(__MINGW32__) || defined(_MSC_VER) + win32_close_socket(client); #endif return 1; } @@ -1739,8 +1747,8 @@ int serve(stlink_t *sl, st_state_t *st) { ELOG("cannot send: %d\n", result); free(reply); free(packet); -#ifdef __MINGW32__ - win32_close_socket(sock); +#if defined(__MINGW32__) || defined(_MSC_VER) + win32_close_socket(client); #endif return 1; } @@ -1751,8 +1759,8 @@ int serve(stlink_t *sl, st_state_t *st) { free(packet); } -#ifdef __MINGW32__ - win32_close_socket(sock); +#if defined(__MINGW32__) || defined(_MSC_VER) + win32_close_socket(client); #endif return 0; diff --git a/src/getopt/LICENSE.txt b/src/getopt/LICENSE.txt new file mode 100644 index 000000000..340303a96 --- /dev/null +++ b/src/getopt/LICENSE.txt @@ -0,0 +1,24 @@ +Copyright (c) 2012, Kim Gräsman +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Kim Gräsman nor the + names of contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/getopt/README.md b/src/getopt/README.md new file mode 100644 index 000000000..9bf81fa73 --- /dev/null +++ b/src/getopt/README.md @@ -0,0 +1,21 @@ +getopt_port +=========== + +[Kim Gräsman](http://grundlig.wordpress.com) +[@kimgr](http://twitter.com/kimgr) + +An original implementation of `getopt` and `getopt_long` with limited GNU extensions. Provided under the BSD license, to allow non-GPL projects to use `getopt`-style command-line parsing. + +So far only built with Visual C++, but has no inherently non-portable constructs. + +Intended to be embedded into your code tree -- `getopt.h` and `getopt.c` are self-contained and should work in any context. + +Comes with a reasonable unit test suite. + +See also: + + * [Full Win32 getopt port](http://www.codeproject.com/Articles/157001/Full-getopt-Port-for-Unicode-and-Multibyte-Microso) -- LGPL licensed. + * [XGetOpt](http://www.codeproject.com/Articles/1940/XGetopt-A-Unix-compatible-getopt-for-MFC-and-Win32) -- No `getopt_long` support. + * [Free Getopt](https://sourceforge.net/projects/freegetopt/) -- No `getopt_long` support. + +For license terms, see LICENSE.txt. \ No newline at end of file diff --git a/src/getopt/getopt.c b/src/getopt/getopt.c new file mode 100644 index 000000000..72dce14d6 --- /dev/null +++ b/src/getopt/getopt.c @@ -0,0 +1,206 @@ +#include "getopt.h" + +#include +#include + +#if !defined(_MSC_VER) +const int no_argument = 0; +const int required_argument = 1; +const int optional_argument = 2; +#endif + +char* optarg; +int optopt; +/* The variable optind [...] shall be initialized to 1 by the system. */ +int optind = 1; +int opterr; + +static char* optcursor = NULL; + +/* Implemented based on [1] and [2] for optional arguments. + optopt is handled FreeBSD-style, per [3]. + Other GNU and FreeBSD extensions are purely accidental. + +[1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html +[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html +[3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE +*/ +int getopt(int argc, char* const argv[], const char* optstring) { + int optchar = -1; + const char* optdecl = NULL; + + optarg = NULL; + opterr = 0; + optopt = 0; + + /* Unspecified, but we need it to avoid overrunning the argv bounds. */ + if (optind >= argc) + goto no_more_optchars; + + /* If, when getopt() is called argv[optind] is a null pointer, getopt() + shall return -1 without changing optind. */ + if (argv[optind] == NULL) + goto no_more_optchars; + + /* If, when getopt() is called *argv[optind] is not the character '-', + getopt() shall return -1 without changing optind. */ + if (*argv[optind] != '-') + goto no_more_optchars; + + /* If, when getopt() is called argv[optind] points to the string "-", + getopt() shall return -1 without changing optind. */ + if (strcmp(argv[optind], "-") == 0) + goto no_more_optchars; + + /* If, when getopt() is called argv[optind] points to the string "--", + getopt() shall return -1 after incrementing optind. */ + if (strcmp(argv[optind], "--") == 0) { + ++optind; + goto no_more_optchars; + } + + if (optcursor == NULL || *optcursor == '\0') + optcursor = argv[optind] + 1; + + optchar = *optcursor; + + /* FreeBSD: The variable optopt saves the last known option character + returned by getopt(). */ + optopt = optchar; + + /* The getopt() function shall return the next option character (if one is + found) from argv that matches a character in optstring, if there is + one that matches. */ + optdecl = strchr(optstring, optchar); + if (optdecl) { + /* [I]f a character is followed by a colon, the option takes an + argument. */ + if (optdecl[1] == ':') { + optarg = ++optcursor; + if (*optarg == '\0') { + /* GNU extension: Two colons mean an option takes an + optional arg; if there is text in the current argv-element + (i.e., in the same word as the option name itself, for example, + "-oarg"), then it is returned in optarg, otherwise optarg is set + to zero. */ + if (optdecl[2] != ':') { + /* If the option was the last character in the string pointed to by + an element of argv, then optarg shall contain the next element + of argv, and optind shall be incremented by 2. If the resulting + value of optind is greater than argc, this indicates a missing + option-argument, and getopt() shall return an error indication. + + Otherwise, optarg shall point to the string following the + option character in that element of argv, and optind shall be + incremented by 1. + */ + if (++optind < argc) { + optarg = argv[optind]; + } else { + /* If it detects a missing option-argument, it shall return the + colon character ( ':' ) if the first character of optstring + was a colon, or a question-mark character ( '?' ) otherwise. + */ + optarg = NULL; + optchar = (optstring[0] == ':') ? ':' : '?'; + } + } else { + optarg = NULL; + } + } + + optcursor = NULL; + } + } else { + /* If getopt() encounters an option character that is not contained in + optstring, it shall return the question-mark ( '?' ) character. */ + optchar = '?'; + } + + if (optcursor == NULL || *++optcursor == '\0') + ++optind; + + return optchar; + +no_more_optchars: + optcursor = NULL; + return -1; +} + +/* Implementation based on [1]. + +[1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html +*/ +int getopt_long(int argc, char* const argv[], const char* optstring, + const struct option* longopts, int* longindex) { + const struct option* o = longopts; + const struct option* match = NULL; + int num_matches = 0; + size_t argument_name_length = 0; + const char* current_argument = NULL; + int retval = -1; + + optarg = NULL; + optopt = 0; + + if (optind >= argc) + return -1; + + if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0) + return getopt(argc, argv, optstring); + + /* It's an option; starts with -- and is longer than two chars. */ + current_argument = argv[optind] + 2; + argument_name_length = strcspn(current_argument, "="); + for (; o->name; ++o) { + if (strncmp(o->name, current_argument, argument_name_length) == 0) { + match = o; + ++num_matches; + } + } + + if (num_matches == 1) { + /* If longindex is not NULL, it points to a variable which is set to the + index of the long option relative to longopts. */ + if (longindex) + *longindex = (match - longopts); + + /* If flag is NULL, then getopt_long() shall return val. + Otherwise, getopt_long() returns 0, and flag shall point to a variable + which shall be set to val if the option is found, but left unchanged if + the option is not found. */ + if (match->flag) + *(match->flag) = match->val; + + retval = match->flag ? 0 : match->val; + + if (match->has_arg != no_argument) { + optarg = strchr(argv[optind], '='); + if (optarg != NULL) + ++optarg; + + if (match->has_arg == required_argument) { + /* Only scan the next argv for required arguments. Behavior is not + specified, but has been observed with Ubuntu and Mac OSX. */ + if (optarg == NULL && ++optind < argc) { + optarg = argv[optind]; + } + + if (optarg == NULL) + retval = ':'; + } + } else if (strchr(argv[optind], '=')) { + /* An argument was provided to a non-argument option. + I haven't seen this specified explicitly, but both GNU and BSD-based + implementations show this behavior. + */ + retval = '?'; + } + } else { + /* Unknown option or ambiguous match. */ + retval = '?'; + } + + ++optind; + return retval; +} diff --git a/src/getopt/getopt.h b/src/getopt/getopt.h new file mode 100644 index 000000000..bc189b9d4 --- /dev/null +++ b/src/getopt/getopt.h @@ -0,0 +1,38 @@ +#ifndef INCLUDED_GETOPT_PORT_H +#define INCLUDED_GETOPT_PORT_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(_MSC_VER) +// These may be used to initialize structures and it fails with MSVC +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 +#else +extern const int no_argument; +extern const int required_argument; +extern const int optional_argument; +#endif + +extern char* optarg; +extern int optind, opterr, optopt; + +struct option { + const char* name; + int has_arg; + int* flag; + int val; +}; + +int getopt(int argc, char* const argv[], const char* optstring); + +int getopt_long(int argc, char* const argv[], + const char* optstring, const struct option* longopts, int* longindex); + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_GETOPT_PORT_H diff --git a/src/mingw/mingw.c b/src/mingw/mingw.c index ee0515972..b342e7db2 100644 --- a/src/mingw/mingw.c +++ b/src/mingw/mingw.c @@ -1,4 +1,4 @@ -#ifdef __MINGW32__ +#if defined(__MINGW32__) || defined(_MSC_VER) #include "mingw.h" @@ -18,6 +18,9 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) unsigned int i, rc; /* Set up the file-descriptor sets in ifds, ofds and efds. */ +#ifdef _MSC_VER +#pragma warning(disable: 4548) +#endif FD_ZERO(&ifds); FD_ZERO(&ofds); FD_ZERO(&efds); @@ -33,6 +36,9 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) } FD_SET(fds[i].fd, &efds); } +#ifdef _MSC_VER +#pragma warning(default: 4548) +#endif /* Set up the timeval structure for the timeout parameter */ if(timo < 0) { @@ -143,7 +149,7 @@ win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len) SOCKET newfd = accept(fd, addr, addr_len); if(newfd == INVALID_SOCKET) { set_socket_errno(WSAGetLastError()); - newfd = -1; + newfd = (SOCKET)-1; } return newfd; } @@ -267,6 +273,24 @@ char *win32_strsep (char **stringp, const char *delim) void usleep(DWORD waitTime) { +#ifdef _MSC_VER + if (waitTime >= 1000) + { + // Don't do long busy-waits. + // However much it seems like the QPC code would be more accurate, + // you can and probably will lose your time slice at any point during the wait, + // so we might as well voluntarily give up the CPU with a WaitForSingleObject. + HANDLE timer; + LARGE_INTEGER dueTime; + dueTime.QuadPart = -10 * (LONGLONG)waitTime; + + timer = CreateWaitableTimer(NULL, TRUE, NULL); + SetWaitableTimer(timer, &dueTime, 0, NULL, NULL, 0); + WaitForSingleObject(timer, INFINITE); + CloseHandle(timer); + return; + } +#endif LARGE_INTEGER perf_cnt, start, now; QueryPerformanceFrequency(&perf_cnt); diff --git a/src/mingw/mingw.h b/src/mingw/mingw.h index cd1441073..4b5cf5380 100644 --- a/src/mingw/mingw.h +++ b/src/mingw/mingw.h @@ -1,16 +1,28 @@ -#ifdef __MINGW32__ - -#include +#if defined(__MINGW32__) || defined(_MSC_VER) #define _USE_W32_SOCKETS 1 -#include +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4255 4668 4820) +#endif + +#include +#include +#pragma comment(lib, "ws2_32.lib") +#include + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif /* winsock doesn't feature poll(), so there is a version implemented * in terms of select() in mingw.c. The following definitions * are copied from linux man pages. A poll() macro is defined to * call the version in mingw.c. */ +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0600) + #define POLLIN 0x0001 /* There is data to read */ #define POLLPRI 0x0002 /* There is urgent data to read */ #define POLLOUT 0x0004 /* Writing now will not block */ @@ -22,6 +34,7 @@ struct pollfd { short events; /* requested events */ short revents; /* returned events */ }; +#endif #define poll(x, y, z) win32_poll(x, y, z) /* These wrappers do nothing special except set the global errno variable if diff --git a/src/usb.c b/src/usb.c index 03ac1ab3c..299de8740 100644 --- a/src/usb.c +++ b/src/usb.c @@ -2,9 +2,19 @@ #include #include #include +#if !defined(_MSC_VER) #include +#endif #include +#if defined(_MSC_VER) +#include +#pragma warning(push) +#pragma warning(disable: 4200 4255 4668 4820) #include +#pragma warning(pop) +#else +#include +#endif #include #include diff --git a/src/win32/unistd.h b/src/win32/unistd.h new file mode 100644 index 000000000..0b175fc07 --- /dev/null +++ b/src/win32/unistd.h @@ -0,0 +1,60 @@ +#ifndef _UNISTD_H +#define _UNISTD_H 1 + +/* This file intended to serve as a drop-in replacement for + * unistd.h on Windows + * Please add functionality as neeeded + */ + +#include +#include +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4820) +#endif +#include +#if defined(_MSC_VER) +#pragma warning(pop) +#endif +#include /* getopt at: https://gist.github.com/ashelly/7776712 */ +#include /* for getpid() and the exec..() family */ +#include /* for _getcwd() and _chdir() */ + +#define srandom srand +#define random rand + +/* Values for the second argument to access. + These may be OR'd together. */ +#define R_OK 4 /* Test for read permission. */ +#define W_OK 2 /* Test for write permission. */ +//#define X_OK 1 /* execute permission - unsupported in windows*/ +#define F_OK 0 /* Test for existence. */ + +#define access _access +#define dup2 _dup2 +#define execve _execve +#define ftruncate _chsize +#define unlink _unlink +#define fileno _fileno +#define getcwd _getcwd +#define chdir _chdir +#define isatty _isatty +#define lseek _lseek +/* read, write, and close are NOT being #defined here, because while there are file handle specific versions for Windows, they probably don't work for sockets. You need to look at your app and consider whether to call e.g. closesocket(). */ + +#define ssize_t int + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +/* should be in some equivalent to */ +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; + +#endif /* unistd.h */ diff --git a/tests/flash.c b/tests/flash.c index fd55fdfc1..6c8b8ed9b 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -4,6 +4,9 @@ #include #include +#if defined(_MSC_VER) +#include +#endif struct Test { const char * cmd_line; @@ -26,7 +29,11 @@ static bool execute_test(const struct Test * test) { char* av[32]; // parse (tokenize) the test command line +#if defined(_MSC_VER) + char *cmd_line = alloca(strlen(test->cmd_line)); +#else char cmd_line[strlen(test->cmd_line)]; +#endif strcpy(cmd_line, test->cmd_line); for(char * tok = strtok(cmd_line, " "); tok; tok = strtok(NULL, " ")) { @@ -62,26 +69,26 @@ static bool execute_test(const struct Test * test) { static struct Test tests[] = { { "", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset read /dev/sg0 test.bin 0x80000000 0x1000", 0, - { .cmd = FLASH_CMD_READ, .devname = "/dev/sg0", .serial = {}, .filename = "test.bin", + { .cmd = FLASH_CMD_READ, .devname = "/dev/sg0", .serial = { 0 }, .filename = "test.bin", .addr = 0x80000000, .size = 0x1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset write /dev/sg0 test.bin 0x80000000", 0, - { .cmd = FLASH_CMD_WRITE, .devname = "/dev/sg0", .serial = {}, .filename = "test.bin", + { .cmd = FLASH_CMD_WRITE, .devname = "/dev/sg0", .serial = { 0 }, .filename = "test.bin", .addr = 0x80000000, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, { "--serial A1020304 /dev/sg0 erase", -1, FLASH_OPTS_INITIALIZER }, { "/dev/sg0 erase", 0, - { .cmd = FLASH_CMD_ERASE, .devname = "/dev/sg0", .serial = {}, .filename = NULL, + { .cmd = FLASH_CMD_ERASE, .devname = "/dev/sg0", .serial = { 0 }, .filename = NULL, .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset read test.bin 0x80000000 0x1000", 0, - { .cmd = FLASH_CMD_READ, .devname = NULL, .serial = {}, .filename = "test.bin", + { .cmd = FLASH_CMD_READ, .devname = NULL, .serial = { 0 }, .filename = "test.bin", .addr = 0x80000000, .size = 0x1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset write test.bin 0x80000000", 0, - { .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = {}, .filename = "test.bin", + { .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = { 0 }, .filename = "test.bin", .addr = 0x80000000, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, { "erase", 0, - { .cmd = FLASH_CMD_ERASE, .devname = NULL, .serial = {}, .filename = NULL, + { .cmd = FLASH_CMD_ERASE, .devname = NULL, .serial = { 0 }, .filename = NULL, .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset --format=ihex write test.hex", 0, - { .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = {}, .filename = "test.hex", + { .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = { 0 }, .filename = "test.hex", .addr = 0, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_IHEX } }, { "--debug --reset --format=binary write test.hex", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset --format=ihex write test.hex 0x80000000", -1, FLASH_OPTS_INITIALIZER }, diff --git a/tests/sg.c b/tests/sg.c index 5426b6ff3..a014717d7 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -9,6 +9,10 @@ #include #include +#if defined(_MSC_VER) +#define __attribute__(x) +#endif + static void __attribute__((unused)) mark_buf(stlink_t *sl) { memset(sl->q_buf, 0, sizeof(sl->q_buf)); sl->q_buf[0] = 0xaa; From 438344a0da777da79d29925fe00181e8fec209fa Mon Sep 17 00:00:00 2001 From: kilroy42 Date: Sat, 17 Jun 2017 23:16:38 +0200 Subject: [PATCH 0570/1435] Fix wrong counting logline when flashing (#605) --- src/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 2297eee47..e40f2d42a 100644 --- a/src/common.c +++ b/src/common.c @@ -2016,7 +2016,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t if (sl->verbose >= 1) { /* show progress. writing procedure is slow and previous errors are misleading */ - fprintf(stdout, "\r%3u/%lu pages written", write_block_count++, (unsigned long)(len/sl->flash_pgsz)); + fprintf(stdout, "\r%3u/%lu pages written", ++write_block_count, (unsigned long)((len+sl->flash_pgsz-1)/sl->flash_pgsz)); fflush(stdout); } } From dc8eb3e739c334440f340b39db46c8d530daa1e0 Mon Sep 17 00:00:00 2001 From: "Zhang, Chi" Date: Mon, 26 Jun 2017 16:57:14 -0500 Subject: [PATCH 0571/1435] Fix gitignore and add support for STM32L452 (#608) * update gitignore for debian * add/update support for L43x/44x/45x/46x, partially thanks to @vatsaltrivedi86, should close texane/stlink#603 --- .gitignore | 1 + debian/.gitignore | 10 ++++++++++ doc/tested-boards.md | 3 ++- include/stlink/chipid.h | 5 +++++ src/chipid.c | 24 +++++++++++++++++++----- src/flash_loader.c | 3 ++- 6 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 debian/.gitignore diff --git a/.gitignore b/.gitignore index 378eac25d..89cda6de8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ build +obj-* diff --git a/debian/.gitignore b/debian/.gitignore new file mode 100644 index 000000000..7624d1c9b --- /dev/null +++ b/debian/.gitignore @@ -0,0 +1,10 @@ +.debhelper +files +debhelper-build-stamp +*.log +*.substvars +libstlink-dev +libstlink +stlink-gui +stlink-tools +tmp diff --git a/doc/tested-boards.md b/doc/tested-boards.md index 7c16062dd..7087ef9fe 100644 --- a/doc/tested-boards.md +++ b/doc/tested-boards.md @@ -34,7 +34,7 @@ STLink v2 (as found on the 32L and F4 Discovery boards), known working targets: STLink v2-1 (as found on the Nucleo boards), known working targets: -* STM32F401xx (STM32 Nucleo-F401RE board) +* STM32F401xx (STM32 Nucleo-F401RE board) * STM32F030R8T6 (STM32 Nucleo-F030R8 board) * STM32F072RBT6 (STM32 Nucleo-F072RB board) * STM32F103RB (STM32 Nucleo-F103RB board) @@ -46,6 +46,7 @@ STLink v2-1 (as found on the Nucleo boards), known working targets: * STM32F769NI (STM32F7 discovery board) * Nucleo-L152RE board * [Nucleo-L476RG board](http://www.st.com/en/evaluation-tools/nucleo-l476rg.html) +* STM32L452RET6 (STM32 Nucleo-L452RE board) Please report any and all known working combinations so I can update this! diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 6a078aa1b..6a11ab823 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -34,7 +34,12 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F37x = 0x432, STLINK_CHIPID_STM32_F4_DE = 0x433, STLINK_CHIPID_STM32_F4_DSI = 0x434, + /* + * 0x435 covers STM32L43xxx and STM32L44xxx devices + * 0x462 covers STM32L45xxx and STM32L46xxx devices + */ STLINK_CHIPID_STM32_L43X = 0x435, + STLINK_CHIPID_STM32_L46X = 0x462, /* * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" * and some that are called "High". 0x427 is assigned to the other "Medium- diff --git a/src/chipid.c b/src/chipid.c index 808a23c52..059afba1b 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -430,21 +430,35 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) .bootrom_size = 0x7000 // 28k (per bank), same source as base }, - { - // STLINK_CHIPID_STM32_L43X + { + // STLINK_CHIPID_STM32_L43X // From RM0392. - .chip_id = STLINK_CHIPID_STM32_L43X, - .description = "L43x device", + .chip_id = STLINK_CHIPID_STM32_L43X, + .description = "L43x/L44x device", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) .flash_pagesize = 0x800, // 2K (sec 3.2, page 74; also appears in sec 3.3.1 and tables 7-8 on pages 75-76) // SRAM1 is "up to" 64k in the standard Cortex-M memory map; - // SRAM2 is 16k mapped at at 0x10000000 (sec 2.3, page 73 for + // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for // sizes; table 2, page 74 for SRAM2 location) .sram_size = 0xc000, .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) .bootrom_size = 0x7000 // 28k (per bank), same source as base }, + { + // STLINK_CHIPID_STM32_L46X + // From RM0394 (updated version of RM0392?). + .chip_id = STLINK_CHIPID_STM32_L46X, + .description = "L45x/46x device", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) + .flash_pagesize = 0x800, // 2K (sec 3.2, page 73; also appears in sec 3.3.1 and tables 7 on pages 73-74) + // SRAM1 is 128k at 0x20000000; + // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, page 68, also fig 2 on page 63) + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system memory, also fig 2 on page 63) + .bootrom_size = 0x7000 // 28k (per bank), same source as base + }, { // STM32L011 .chip_id = STLINK_CHIPID_STM32_L011, diff --git a/src/flash_loader.c b/src/flash_loader.c index 96084ab27..1fc0388de 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -304,7 +304,8 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); } else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || - (sl->chip_id == STLINK_CHIPID_STM32_L43X)) + (sl->chip_id == STLINK_CHIPID_STM32_L43X) || + (sl->chip_id == STLINK_CHIPID_STM32_L46X)) { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); From bf5870050fad788822f8ad4b4c55d82722186020 Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Thu, 29 Jun 2017 22:33:31 +0300 Subject: [PATCH 0572/1435] Fix mingw build (#610) * fix compilation for mingw * add *.user to ignor --- .gitignore | 1 + CMakeLists.txt | 13 +++++++++---- src/mingw/mingw.c | 4 ++-- src/mingw/mingw.h | 6 +++++- src/usb.c | 2 +- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 89cda6de8..3a3a5f38a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build obj-* +*.user* diff --git a/CMakeLists.txt b/CMakeLists.txt index d0660cf05..46790de91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,11 @@ if (STLINK_HAVE_SYS_MMAN_H) add_definitions(-DSTLINK_HAVE_SYS_MMAN_H) endif() +CHECK_INCLUDE_FILE(unistd.h STLINK_HAVE_UNISTD_H) +if (STLINK_HAVE_UNISTD_H) + add_definitions(-DSTLINK_HAVE_UNISTD_H) +endif() + if (CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE "Debug") endif() @@ -73,10 +78,10 @@ include_directories(include) include_directories(${PROJECT_BINARY_DIR}/include) include_directories(src/mingw) if (MSVC) - include_directories(src/win32) - include_directories(src/getopt) - # Use string.h rather than strings.h and disable annoying warnings - add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) + include_directories(src/win32) + include_directories(src/getopt) + # Use string.h rather than strings.h and disable annoying warnings + add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) endif () ### diff --git a/src/mingw/mingw.c b/src/mingw/mingw.c index b342e7db2..8cf289f93 100644 --- a/src/mingw/mingw.c +++ b/src/mingw/mingw.c @@ -271,9 +271,9 @@ char *win32_strsep (char **stringp, const char *delim) /* NOTREACHED */ } +#ifdef STLINK_HAVE_SYS_MMAN_H void usleep(DWORD waitTime) { -#ifdef _MSC_VER if (waitTime >= 1000) { // Don't do long busy-waits. @@ -290,7 +290,6 @@ void usleep(DWORD waitTime) CloseHandle(timer); return; } -#endif LARGE_INTEGER perf_cnt, start, now; QueryPerformanceFrequency(&perf_cnt); @@ -300,6 +299,7 @@ void usleep(DWORD waitTime) QueryPerformanceCounter((LARGE_INTEGER*) &now); } while ((now.QuadPart - start.QuadPart) / (float)perf_cnt.QuadPart * 1000 * 1000 < waitTime); } +#endif #endif diff --git a/src/mingw/mingw.h b/src/mingw/mingw.h index 4b5cf5380..dd82a8f99 100644 --- a/src/mingw/mingw.h +++ b/src/mingw/mingw.h @@ -9,7 +9,9 @@ #include #include +#if defined(_MSC_VER) #pragma comment(lib, "ws2_32.lib") +#endif #include #if defined(_MSC_VER) @@ -69,7 +71,9 @@ char *win32_strsep(char **stringp, const char *delim); ssize_t win32_read_socket(SOCKET fd, void *buf, int n); ssize_t win32_write_socket(SOCKET fd, void *buf, int n); +#ifdef STLINK_HAVE_SYS_MMAN_H static inline void sleep(unsigned ms) { Sleep(ms); } void usleep(DWORD waitTime); - #endif + +#endif //defined(__MINGW32__) || defined(_MSC_VER) diff --git a/src/usb.c b/src/usb.c index 299de8740..92a0a6ef4 100644 --- a/src/usb.c +++ b/src/usb.c @@ -6,8 +6,8 @@ #include #endif #include -#if defined(_MSC_VER) #include +#if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable: 4200 4255 4668 4820) #include From 28bfddacff47bd29329a58699056bc86a31f0d8c Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Thu, 29 Jun 2017 23:42:13 +0300 Subject: [PATCH 0573/1435] use correct macros for switch usleep realisation (#611) --- src/mingw/mingw.c | 2 +- src/mingw/mingw.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mingw/mingw.c b/src/mingw/mingw.c index 8cf289f93..aee288d88 100644 --- a/src/mingw/mingw.c +++ b/src/mingw/mingw.c @@ -271,7 +271,7 @@ char *win32_strsep (char **stringp, const char *delim) /* NOTREACHED */ } -#ifdef STLINK_HAVE_SYS_MMAN_H +#ifndef STLINK_HAVE_UNISTD_H void usleep(DWORD waitTime) { if (waitTime >= 1000) diff --git a/src/mingw/mingw.h b/src/mingw/mingw.h index dd82a8f99..04907f7d6 100644 --- a/src/mingw/mingw.h +++ b/src/mingw/mingw.h @@ -71,7 +71,7 @@ char *win32_strsep(char **stringp, const char *delim); ssize_t win32_read_socket(SOCKET fd, void *buf, int n); ssize_t win32_write_socket(SOCKET fd, void *buf, int n); -#ifdef STLINK_HAVE_SYS_MMAN_H +#ifndef STLINK_HAVE_UNISTD_H static inline void sleep(unsigned ms) { Sleep(ms); } void usleep(DWORD waitTime); #endif From 773d05a3b585642d85dcc4a7454c26716e2c3e2c Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 1 Jul 2017 16:41:54 +0200 Subject: [PATCH 0574/1435] Prepare v1.4.0 release --- .version | 2 +- ChangeLog.md | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.version b/.version index 3a3cd8cc8..88c5fb891 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.3.1 +1.4.0 diff --git a/ChangeLog.md b/ChangeLog.md index f12d176f6..a6c4cca89 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,13 +1,27 @@ Stlink ChangeLog ================ -v1.3.2 +v1.4.0 ====== -Release date: ongoing +Release date: 2017-07-01 + +Major changes and added features: + +* Add support for STM32L452 target ([#608](https://github.com/texane/stlink/pull/608)) +* Initial support to compile with Microsoft Visual Studio 2017 ([#602](https://github.com/texane/stlink/pull/602)) +* Added support for flashing second bank on STM32F10x_XL ([#592](https://github.com/texane/stlink/pull/592)) +* Add support for STM32L011 target ([#572](https://github.com/texane/stlink/pull/572)) +* Allow building of debian package with CPack (@xor-gate) Updates and fixes: +* Fix compilation with GCC 7 ([#590](https://github.com/texane/stlink/pull/590)) +* Skip GTK detection if we're cross-compiling ([#588](https://github.com/texane/stlink/pull/588)) +* Fix possible memory leak ([#570](https://github.com/texane/stlink/pull/570)) +* Fix building with mingw64 ([#569](https://github.com/texane/stlink/pull/569), [#610](https://github.com/texane/stlink/pull/610)) +* Update libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) +* Fixing low-voltage flashing on STM32F7 parts. ([#567](https://github.com/texane/stlink/pull/567)) * Update libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) v1.3.1 From 5e740a8434a06ab154d0da8cc0a3e0d29399a25c Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 1 Jul 2017 16:44:47 +0200 Subject: [PATCH 0575/1435] README.md: Update version badge to v1.4.0 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3c6f48a0d..17a62a9f1 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Open source version of the STMicroelectronics Stlink Tools [![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) -[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.3.1.svg)](https://github.com/texane/stlink/compare/1.3.1...master) +[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.4.0.svg)](https://github.com/texane/stlink/compare/1.4.0...master) [![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/texane/stlink/releases) [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) [![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/job/stlink/) From 0c84c29e590e6d038114b84dac628d755607d64c Mon Sep 17 00:00:00 2001 From: Viallard Anthony Date: Fri, 14 Jul 2017 16:19:49 +0200 Subject: [PATCH 0576/1435] Add support of STM32L496xx/4A6xx devices (#615) --- include/stlink/chipid.h | 2 ++ src/chipid.c | 14 ++++++++++++++ src/flash_loader.c | 3 ++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 6a11ab823..36a327c8e 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -36,9 +36,11 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F4_DSI = 0x434, /* * 0x435 covers STM32L43xxx and STM32L44xxx devices + * 0x461 covers STM32L496xx and STM32L4A6xx devices * 0x462 covers STM32L45xxx and STM32L46xxx devices */ STLINK_CHIPID_STM32_L43X = 0x435, + STLINK_CHIPID_STM32_L496X = 0x461, STLINK_CHIPID_STM32_L46X = 0x462, /* * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" diff --git a/src/chipid.c b/src/chipid.c index 059afba1b..c84638b01 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -445,6 +445,20 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) .bootrom_size = 0x7000 // 28k (per bank), same source as base }, + { + // STLINK_CHIPID_STM32_L496X + // Support based on en.DM00083560.pdf (RM0351) document rev 5. + .chip_id = STLINK_CHIPID_STM32_L496X, + .description = "L496x/L4A6x device", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) + .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) + // SRAM1 is 256k at 0x20000000 + // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) + .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) + .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) + .bootrom_size = 0x7000 // 28k (per bank), same source as base + }, { // STLINK_CHIPID_STM32_L46X // From RM0394 (updated version of RM0392?). diff --git a/src/flash_loader.c b/src/flash_loader.c index 1fc0388de..9abda5835 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -305,7 +305,8 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_size = sizeof(loader_code_stm32f0); } else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || (sl->chip_id == STLINK_CHIPID_STM32_L43X) || - (sl->chip_id == STLINK_CHIPID_STM32_L46X)) + (sl->chip_id == STLINK_CHIPID_STM32_L46X) || + (sl->chip_id == STLINK_CHIPID_STM32_L496X)) { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); From 691a2d5026296fd70b51148e22c5f2d8c559d9cf Mon Sep 17 00:00:00 2001 From: rdlim Date: Sat, 15 Jul 2017 11:29:55 -0700 Subject: [PATCH 0577/1435] Fix verification of flash error for STM32L496x device (#617) (#618) There were missing chipid checks of STM32L496xx and STM32L46x devices. --- src/common.c | 11 ++++++++--- src/gdbserver/gdb-server.c | 5 ++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/common.c b/src/common.c index e40f2d42a..a55613b22 100644 --- a/src/common.c +++ b/src/common.c @@ -1484,7 +1484,10 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) unlock_flash_if(sl); /* select the page to erase */ - if (sl->chip_id == STLINK_CHIPID_STM32_L4 || sl->chip_id == STLINK_CHIPID_STM32_L43X) { + if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || + (sl->chip_id == STLINK_CHIPID_STM32_L43X) || + (sl->chip_id == STLINK_CHIPID_STM32_L46X) || + (sl->chip_id == STLINK_CHIPID_STM32_L496X)) { // calculate the actual bank+page from the address uint32_t page = calculate_L4_page(sl, flashaddr); @@ -1859,8 +1862,10 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t /* TODO: Check that Voltage range is 2.7 - 3.6 V */ if ((sl->chip_id != STLINK_CHIPID_STM32_L4) && - (sl->chip_id != STLINK_CHIPID_STM32_L43X)) - { + (sl->chip_id != STLINK_CHIPID_STM32_L43X) && + (sl->chip_id != STLINK_CHIPID_STM32_L46X) && + (sl->chip_id != STLINK_CHIPID_STM32_L496X)) { + if( sl->version.stlink_v == 1 ) { printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes on F4 devices\n"); write_flash_cr_psiz(sl, 2); diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index d7da544fa..b6776107c 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -518,7 +518,10 @@ char* make_memory_map(stlink_t *sl) { (unsigned int)sl->sram_size, (unsigned int)sl->flash_size - 0x20000, (unsigned int)sl->sys_base, (unsigned int)sl->sys_size); - } else if(sl->chip_id==STLINK_CHIPID_STM32_L4) { + } else if((sl->chip_id==STLINK_CHIPID_STM32_L4) || + (sl->chip_id==STLINK_CHIPID_STM32_L43X) || + (sl->chip_id==STLINK_CHIPID_STM32_L46X) || + (sl->chip_id==STLINK_CHIPID_STM32_L496X)) { snprintf(map, sz, memory_map_template_L4, (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); } else { From 47ce70d6cfbd7c97e1ef36768afabc7bc2613e61 Mon Sep 17 00:00:00 2001 From: dflogeras Date: Thu, 27 Jul 2017 09:14:35 -0300 Subject: [PATCH 0578/1435] Add note about availability in Gentoo package manager (#622) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 17a62a9f1..75d421452 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,8 @@ Arch Linux users can install from the [repository](https://www.archlinux.org/pac Alpine Linux users can install from the [repository](https://pkgs.alpinelinux.org/packages?name=stlink) +Gentoo Linux users can install from the official portage [repository](https://packages.gentoo.org/packages/dev-embedded/stlink) + FreeBSD users can install from [freshports](https://www.freshports.org/devel/stlink) OpenBSD users need to install [from source](doc/compiling.md). From 4e28e303b5931e12e46b9896e9c02d562af94757 Mon Sep 17 00:00:00 2001 From: yaofei zheng Date: Fri, 25 Aug 2017 03:06:21 -0500 Subject: [PATCH 0579/1435] update debian package version (#630) * update debian package version --- debian/changelog | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/debian/changelog b/debian/changelog index d0471cb7d..0f3edb222 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,68 @@ +libstlink (1.4.0) unstable; urgency=low + + * Major changes and added features + - Add support for STM32L452 target (#608) + - Initial support to compile with Microsoft Visual Studio 2017 (#602) + - Added support for flashing second bank on STM32F10x_XL (#592) + - Add support for STM32L011 target (#572) + - Allow building of debian package with CPack (@xor-gate) + * Updates and fixes + - Fix compilation with GCC 7 (#590) + - Skip GTK detection if we're cross-compiling (#588) + - Fix possible memory leak (#570) + - Fix building with mingw64 (#569, #610) + - Update libusb to 1.0.21 for Windows (#562) + - Fixing low-voltage flashing on STM32F7 parts. (#567) + - Update libusb to 1.0.21 for Windows (#562) + + -- Andrew 'Necromant' Andrianov Sat, 01 Jul 2017 00:00:00 +0000 + +libstlink (1.3.1) unstable; urgency=low + + * Major changes and added features: + - Add preliminary support for STM32L011 to see it after probe (chipid 0x457) (@xor-gate) + - Strip full paths to source files in log (commit #2c0ab7f) + - Add support for STM32F413 target (#549) + - Add support for Semihosting SYS_READC (#546) + * Updates and fixes: + - Update documentation markdown files + - Compilation fixes (#552) + - Fix compilation when path includes spaces (#561) + + -- Andrew 'Necromant' Andrianov Sat, 25 Feb 2017 00:00:00 +0000 + +libstlink (1.3.0) unstable; urgency=low + + * Major changes and added features: + - Deprecation of autotools (autoconf, automake) (@xor-gate) + - Removal of undocumented st-term utility, which is now replaced by st-util ARM semihosting feature (#3fd0f09) + - Add support for native debian packaging (#444, #485) + - Add intel hex file reading for st-flash (#459) + - Add --reset command to st-flash (#505) + - Support serial numbers argument for st-util and st-flash for multi-programmer setups (#541) + - Add kill ('k') command to gdb-server for st-util (#9804416) + - Add manpages (generated with pandoc from Markdown) (#464) + - Rewrite commandline parsing for st-flash (#459) + - Add support for ARM semihosting to st-util (#454, #455) + * Chip support added for: + - STM32L432 (#501) + - STM32F412 (#538) + - STM32F410 (#9c635e4) + - Add memory map for STM32F401XE (#460) + - L0x Category 5 devices (#406) + - Add L0 Category 2 device (chip id: 0x425) (#72b8e5e) + * Updates and fixes: + - Fixed STM32F030 erase error (#442) + - Fixed Cygwin build (#68b0f3b) + - Reset flash mass erase (MER) bit after mass erase for safety (#489) + - Fix memory map for STM32F4 (@zulusw) + - Fix STM32L-problem with flash loader (issue #390) (Tom de Boer) + - st-util don't read target voltage on startup as it crashes STM32F100 (probably stlink/v1) (Greg Alexander) + - Do a JTAG reset prior to reading CPU information when processor is in deep sleep (@andyg24) + - Redesign of st-flash commandline options parsing (pull-request #459) (@dev26th) + + -- Andrew 'Necromant' Andrianov Sat, 28 Jan 2017 00:00:00 +0000 + libstlink (1.2.1) unstable; urgency=low * Initial Debian-Packaged Release. From 7b7a5c102c36d0833876c3cb57173cbac4d401f2 Mon Sep 17 00:00:00 2001 From: Lyle Cheatham Date: Sun, 27 Aug 2017 05:51:59 -0400 Subject: [PATCH 0580/1435] Minor formatting fix in FAQ section of README.md (#631) Fixup single quotes instead of back ticks --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 75d421452..7ea63280e 100644 --- a/README.md +++ b/README.md @@ -148,9 +148,9 @@ enough unused registers. In my experience, -O3 causes that frequently. Q: At some point I use GDB command `next', and it hangs. -A: Sometimes when you will try to use GDB `next' command to skip a loop, +A: Sometimes when you will try to use GDB `next` command to skip a loop, it will use a rather inefficient single-stepping way of doing that. -Set up a breakpoint manually in that case and do `continue'. +Set up a breakpoint manually in that case and do `continue`. Q: Load command does not work in GDB. From 3d8ca68dcaaeba0ed9db9a1d478c6284fe7aba8a Mon Sep 17 00:00:00 2001 From: Vasiliy Glazov Date: Thu, 7 Sep 2017 13:59:49 +0300 Subject: [PATCH 0581/1435] README.md: Added information about Fedora and RedHat/CentOS packages. (#635) --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 7ea63280e..d062abdc6 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,10 @@ Arch Linux users can install from the [repository](https://www.archlinux.org/pac Alpine Linux users can install from the [repository](https://pkgs.alpinelinux.org/packages?name=stlink) +Fedora users can install from [repository](https://src.fedoraproject.org/rpms/stlink) + +RedHat/CentOS 7 users can install from EPEL [repository](https://src.fedoraproject.org/rpms/stlink/branch/epel7) + Gentoo Linux users can install from the official portage [repository](https://packages.gentoo.org/packages/dev-embedded/stlink) FreeBSD users can install from [freshports](https://www.freshports.org/devel/stlink) From 1700e6a4712d3cfb229b3d9b6bc709ec12edc0bd Mon Sep 17 00:00:00 2001 From: Vasiliy Glazov Date: Fri, 8 Sep 2017 15:00:45 +0300 Subject: [PATCH 0582/1435] Added LIB_INSTALL_DIR to correct libs install on 64-bit systems (#636) * Added LIB_INSTALL_DIR to correct libs install on 64-bit systems * Add description for using LIB_INSTALL_DIR parameter. --- CMakeLists.txt | 3 ++- doc/compiling.md | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 46790de91..da99b6ea7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,8 @@ project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics Stlink Tools") set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "Udev rules directory") set(STLINK_MODPROBED_DIR "/etc/modprobe.d" CACHE PATH "modprobe.d directory") -set(STLINK_LIBRARY_PATH "lib/${CMAKE_LIBRARY_PATH}" CACHE PATH "Target lib directory") +set(LIB_INSTALL_DIR "lib" CACHE PATH "Main library directory") +set(STLINK_LIBRARY_PATH "${LIB_INSTALL_DIR}/${CMAKE_LIBRARY_PATH}" CACHE PATH "Target lib directory") option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) diff --git a/doc/compiling.md b/doc/compiling.md index 3518d1079..41d1fb7f9 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -118,6 +118,15 @@ $ cmake -DSTLINK_UDEV_RULES_DIR="/usr/lib/udev/rules.d" \ -DSTLINK_MODPROBED_DIR="/usr/lib/modprobe.d" .. ``` +## Build using different directory for shared libs + +To put the compiled shared libs into a different directory during installation +you can use the following cmake option: + +``` +$ cmake -DLIB_INSTALL_DIR:PATH="/usr/lib64" .. +``` + ## Windows (MinGW64) ### Prequistes From 6511a7e86185aaf3bafe0d8ae2252a83f4fb0c5b Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Sat, 16 Sep 2017 20:37:42 +0200 Subject: [PATCH 0583/1435] fix write for microcontroler with RAM size less or equal to 32K (#637) --- src/common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index a55613b22..0658114d8 100644 --- a/src/common.c +++ b/src/common.c @@ -1899,8 +1899,9 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t /* set programming mode */ set_flash_cr_pg(sl); + size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; for(off = 0; off < len;) { - size_t size = len - off > 0x8000 ? 0x8000 : len - off; + size_t size = len - off > buf_size ? buf_size : len - off; printf("size: %u\n", (unsigned int)size); From 04dc7ead42f99d80696cd12496ee2299428675e7 Mon Sep 17 00:00:00 2001 From: Mateusz Krawiec Date: Fri, 29 Sep 2017 11:07:23 +0200 Subject: [PATCH 0584/1435] Fix memory map for stm32l496xx boards. (#639) --- src/gdbserver/gdb-server.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index b6776107c..f5afa73b4 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -433,6 +433,25 @@ static const char* const memory_map_template_L4 = " " // option byte area ""; +static const char* const memory_map_template_L496 = + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // SRAM2 (64 KB) + " " // SRAM1 (256 KB) + " " + " 0x800" + " " + " " // peripheral regs + " " // AHB3 Peripherals + " " // cortex regs + " " // bootrom + " " // option byte area + " " // option byte area + ""; + static const char* const memory_map_template = "" "sys_base, (unsigned int)sl->sys_size); } else if((sl->chip_id==STLINK_CHIPID_STM32_L4) || (sl->chip_id==STLINK_CHIPID_STM32_L43X) || - (sl->chip_id==STLINK_CHIPID_STM32_L46X) || - (sl->chip_id==STLINK_CHIPID_STM32_L496X)) { + (sl->chip_id==STLINK_CHIPID_STM32_L46X)) { snprintf(map, sz, memory_map_template_L4, (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); + } else if(sl->chip_id==STLINK_CHIPID_STM32_L496X) { + snprintf(map, sz, memory_map_template_L496, + (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); } else { snprintf(map, sz, memory_map_template, (unsigned int)sl->flash_size, From a2a707e4f75fd8aafce3fa6095dc34206c5bb801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BCdiger=20Fortanier?= Date: Tue, 10 Oct 2017 13:44:26 +0200 Subject: [PATCH 0585/1435] Add unknown chip output (#641) --- include/stlink/chipid.h | 2 ++ src/chipid.c | 11 +++++++++++ src/common.c | 3 ++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 36a327c8e..0e09d989f 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -11,6 +11,8 @@ extern "C" { * stm32 chipids, only lower 12 bits.. */ enum stlink_stm32_chipids { + STLINK_CHIPID_UNKNOWN = 0x000, + STLINK_CHIPID_STM32_F1_MEDIUM = 0x410, STLINK_CHIPID_STM32_F2 = 0x411, STLINK_CHIPID_STM32_F1_LOW = 0x412, diff --git a/src/chipid.c b/src/chipid.c index c84638b01..b81ff3544 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -484,6 +484,17 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1ff00000, .bootrom_size = 0x2000 }, + { + // unknown + .chip_id = STLINK_CHIPID_UNKNOWN, + .description = "unknown device", + .flash_type = STLINK_FLASH_TYPE_UNKNOWN, + .flash_size_reg = 0x0, + .flash_pagesize = 0x0, + .sram_size = 0x0, + .bootrom_base = 0x0, + .bootrom_size = 0x0 + }, }; diff --git a/src/common.c b/src/common.c index 0658114d8..b9b738203 100644 --- a/src/common.c +++ b/src/common.c @@ -644,7 +644,8 @@ int stlink_load_device_params(stlink_t *sl) { if (params->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { WLOG("Invalid flash type, please check device declaration\n"); - return -1; + sl->flash_size = 0; + return 0; } // These are fixed... From 95b6e03ed0c0ee40256a33f04eedf702005a9d8b Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Wed, 25 Oct 2017 22:48:43 +0300 Subject: [PATCH 0586/1435] fix __FILE__ base name extraction, #628 (#648) --- CMakeLists.txt | 5 ----- include/stlink/logging.h | 6 ++---- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index da99b6ea7..d2be523bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,11 +46,6 @@ if (${CMAKE_BUILD_TYPE} MATCHES "Debug") include(CTest) endif() -# fixup __FILE__ absolute paths in logging module -# see: https://cmake.org/pipermail/cmake-developers/2015-January/024202.html -string(LENGTH "${CMAKE_SOURCE_DIR}/" CMAKE_SOURCE_DIR_LENGTH) -add_definitions(-DCMAKE_SOURCE_DIR_LENGTH=${CMAKE_SOURCE_DIR_LENGTH}) - set(STLINK_HEADERS include/stlink.h include/stlink/usb.h diff --git a/include/stlink/logging.h b/include/stlink/logging.h index 9a98a6bc5..a6632a730 100644 --- a/include/stlink/logging.h +++ b/include/stlink/logging.h @@ -20,10 +20,8 @@ enum ugly_loglevel { int ugly_init(int maximum_threshold); int ugly_log(int level, const char *tag, const char *format, ...); -#ifndef CMAKE_SOURCE_DIR_LENGTH -#define CMAKE_SOURCE_DIR_LENGTH 0 -#endif -#define UGLY_LOG_FILE (__FILE__+CMAKE_SOURCE_DIR_LENGTH) +#define UGLY_LOG_FILE (strstr(__FILE__, "/") != NULL ? \ + strrchr(__FILE__, '/') + 1 : strrchr(__FILE__, '\\') + 1) /** @todo we need to write this in a more generic way, for now this should compile on visual studio (See http://stackoverflow.com/a/8673872/1836746) */ From 19691485359afef1a256964afcbb8dcf4b733209 Mon Sep 17 00:00:00 2001 From: texane Date: Thu, 16 Nov 2017 22:46:12 +0100 Subject: [PATCH 0587/1435] STM32F72xx73xx support, from bob.feretich@rafresearch.com --- include/stlink/chipid.h | 3 ++- src/chipid.c | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 0e09d989f..7cf5b4881 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -62,8 +62,9 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F303_HIGH = 0x446, STLINK_CHIPID_STM32_L0_CAT5 = 0x447, STLINK_CHIPID_STM32_F0_CAN = 0x448, - STLINK_CHIPID_STM32_F7 = 0x449, + STLINK_CHIPID_STM32_F7 = 0x449, /* This ID is found on the NucleoF746ZG board */ STLINK_CHIPID_STM32_F7XXXX = 0x451, + STLINK_CHIPID_STM32_F72XXX = 0x452, /* This ID is found on the NucleoF722ZE board */ STLINK_CHIPID_STM32_L011 = 0x457, STLINK_CHIPID_STM32_F410 = 0x458, STLINK_CHIPID_STM32_F413 = 0x463 diff --git a/src/chipid.c b/src/chipid.c index b81ff3544..7cf83218d 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -24,6 +24,17 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 .bootrom_size = 0xEDC0 // "System memory" byte size in hex from DS Fig 18 }, + { + //RM0431 and DS document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_F72XXX, + .description = "F72 device", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1ff07a22, // section 35.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 + .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 + .bootrom_size = 0xEDC0 // "System memory" byte size in hex from DS Fig 24 + }, { // table 2, PM0063 .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, .description = "F1 Medium-density device", From fbd55d9f1b00b84512d1144dfbbe507a3e5e10c0 Mon Sep 17 00:00:00 2001 From: Kirill Kolyshkin Date: Tue, 6 Feb 2018 05:45:57 -0800 Subject: [PATCH 0588/1435] debian/triggers: add (to run ldconfig) (#664) After installing the deb package, st-util fails to start: > $ st-util > st-util: error while loading shared libraries: libstlink-shared.so.1: > cannot open shared object file: No such file or directory The reason is, no one ran `ldconfig` upon installing the library. The solution, as per latest Debian recommendations [1], is to add an ldconfig trigger in debian/triggers, which is what this commit does. [1] https://www.debian.org/doc/debian-policy/#ldconfig Signed-off-by: Kir Kolyshkin --- debian/triggers | 1 + 1 file changed, 1 insertion(+) create mode 100644 debian/triggers diff --git a/debian/triggers b/debian/triggers new file mode 100644 index 000000000..dd8660367 --- /dev/null +++ b/debian/triggers @@ -0,0 +1 @@ +activate-noawait ldconfig From 247b7eb9ba7a96275425469c1d433868cb6d45d5 Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Thu, 15 Feb 2018 20:18:05 +0200 Subject: [PATCH 0589/1435] Try to fix #666 issue (#667) --- src/tools/gui/stlink-gui.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/gui/stlink-gui.c b/src/tools/gui/stlink-gui.c index d45db6ff2..c9e68af4f 100644 --- a/src/tools/gui/stlink-gui.c +++ b/src/tools/gui/stlink-gui.c @@ -224,11 +224,14 @@ stlink_gui_update_devmem_view (STlinkGUI *gui) static void -stlink_gui_populate_devmem_view (STlinkGUI *gui) +stlink_gui_populate_devmem_view (gpointer data) { guint off; stm32_addr_t addr; + g_return_if_fail (STLINK_IS_GUI (data)); + STlinkGUI *gui = (STlinkGUI *)data; + g_return_if_fail (gui != NULL); g_return_if_fail (gui->sl != NULL); From d9a114a6411345d5e27d3458b1ec7f970dab162b Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Fri, 16 Feb 2018 14:01:08 +0200 Subject: [PATCH 0590/1435] Try to fix 666 issue (#668) * try to fix #666 issue * has fixed few function's signatures for match g_thread_new expectations. * fix check in stlink_gui_populate_filemem_view * fix gcc-8 warnings * fix g_return* for proper one --- src/tools/gui/stlink-gui.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/tools/gui/stlink-gui.c b/src/tools/gui/stlink-gui.c index c9e68af4f..34afb2c51 100644 --- a/src/tools/gui/stlink-gui.c +++ b/src/tools/gui/stlink-gui.c @@ -223,17 +223,18 @@ stlink_gui_update_devmem_view (STlinkGUI *gui) } -static void + +static gpointer stlink_gui_populate_devmem_view (gpointer data) { guint off; stm32_addr_t addr; - g_return_if_fail (STLINK_IS_GUI (data)); + g_return_val_if_fail (STLINK_IS_GUI (data), NULL); STlinkGUI *gui = (STlinkGUI *)data; - g_return_if_fail (gui != NULL); - g_return_if_fail (gui->sl != NULL); + g_return_val_if_fail ((gui != NULL), NULL); + g_return_val_if_fail ((gui->sl != NULL), NULL); addr = gui->sl->flash_base; @@ -261,12 +262,14 @@ stlink_gui_populate_devmem_view (gpointer data) stlink_gui_set_info_error_message (gui, "Failed to read memory"); g_free (gui->flash_mem.memory); gui->flash_mem.memory = NULL; - return; + return NULL; } memcpy (gui->flash_mem.memory + off, gui->sl->q_buf, n_read); gui->progress.fraction = (gdouble) (off + n_read) / gui->sl->flash_size; } g_idle_add ((GSourceFunc) stlink_gui_update_devmem_view, gui); + + return NULL; } static gboolean @@ -286,7 +289,7 @@ stlink_gui_update_filemem_view (STlinkGUI *gui) } static gpointer -stlink_gui_populate_filemem_view (STlinkGUI *gui) +stlink_gui_populate_filemem_view (gpointer data) { guchar buffer[MEM_READ_SIZE]; GFile *file; @@ -295,6 +298,9 @@ stlink_gui_populate_filemem_view (STlinkGUI *gui) gint off; GError *err = NULL; + g_return_val_if_fail (STLINK_IS_GUI (data), NULL); + STlinkGUI *gui = (STlinkGUI *)data; + g_return_val_if_fail (gui != NULL, NULL); g_return_val_if_fail (gui->filename != NULL, NULL); @@ -643,17 +649,21 @@ stlink_gui_write_flash_update (STlinkGUI *gui) return FALSE; } -static void -stlink_gui_write_flash (STlinkGUI *gui) +static gpointer +stlink_gui_write_flash (gpointer data) { - g_return_if_fail (gui->sl != NULL); - g_return_if_fail (gui->filename != NULL); + g_return_val_if_fail (STLINK_IS_GUI (data), NULL); + STlinkGUI *gui = (STlinkGUI *)data; + + g_return_val_if_fail ((gui->sl != NULL), NULL); + g_return_val_if_fail ((gui->filename != NULL), NULL); if (stlink_fwrite_flash(gui->sl, gui->filename, gui->sl->flash_base) < 0) { stlink_gui_set_info_error_message (gui, "Failed to write to flash"); } g_idle_add ((GSourceFunc) stlink_gui_write_flash_update, gui); + return NULL; } static void From ddf60b48998e160e94845ad732768b8d4a0ca8c2 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 16 Feb 2018 13:06:36 +0100 Subject: [PATCH 0591/1435] Update ChangeLog.md Prepare for 1.5.0 release --- ChangeLog.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index a6c4cca89..ec397ece6 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,6 +1,24 @@ Stlink ChangeLog ================ +v1.5.0 +====== + +Release date: 2018-02-16 + +Major changes and added features: + +* STM32F72xx73xx support ([#1969148](https://github.com/texane/stlink/commit/19691485359afef1a256964afcbb8dcf4b733209)) +* Add support of STM32L496xx/4A6xx devices ([#615](https://github.com/texane/stlink/pull/615)) + +Fixes: + +* Fix memory map for stm32l496xx boards ([#639](https://github.com/texane/stlink/pull/639)) +* Fix write for microcontroler with RAM size less or equal to 32K ([#637](https://github.com/texane/stlink/pull/637)) +* Added LIB_INSTALL_DIR to correct libs install on 64-bit systems ([#636](https://github.com/texane/stlink/pull/636)) +* Fix verification of flash error for STM32L496x device ([#618](https://github.com/texane/stlink/pull/618)) +* Fix build on Fedora with GCC 8 ([#666](https://github.com/texane/stlink/pull/668)) + v1.4.0 ====== From 954a64917a2143b56841d70d7e70f3280156ce17 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Fri, 16 Feb 2018 13:08:54 +0100 Subject: [PATCH 0592/1435] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d062abdc6..6e23356af 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Open source version of the STMicroelectronics Stlink Tools [![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) -[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.4.0.svg)](https://github.com/texane/stlink/compare/1.4.0...master) +[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.5.0.svg)](https://github.com/texane/stlink/compare/1.4.0...master) [![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/texane/stlink/releases) [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) [![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/job/stlink/) From c0d759dc41d6ed4fc697f337028ea43e8c32c241 Mon Sep 17 00:00:00 2001 From: texane Date: Sun, 18 Feb 2018 08:01:58 +0100 Subject: [PATCH 0593/1435] STM32F042K6 Nucleo-32 Board reported to work, by frank@bauernoeppel.de --- doc/tested-boards.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/tested-boards.md b/doc/tested-boards.md index 7087ef9fe..27d09cc34 100644 --- a/doc/tested-boards.md +++ b/doc/tested-boards.md @@ -47,6 +47,7 @@ STLink v2-1 (as found on the Nucleo boards), known working targets: * Nucleo-L152RE board * [Nucleo-L476RG board](http://www.st.com/en/evaluation-tools/nucleo-l476rg.html) * STM32L452RET6 (STM32 Nucleo-L452RE board) +* STM32F042K6 (STM32 Nucleo-32 Board) Please report any and all known working combinations so I can update this! From af4d2eb510de44e99bd9894d0e29f5256f7539bb Mon Sep 17 00:00:00 2001 From: Anatol Pomozov Date: Mon, 19 Feb 2018 11:00:29 -0800 Subject: [PATCH 0594/1435] Update .version file to match release number (#670) --- .version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.version b/.version index 88c5fb891..bc80560fa 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.4.0 +1.5.0 From 4e27060689d22d337a6f953f3cfdb6399542947c Mon Sep 17 00:00:00 2001 From: Jared Szechy Date: Wed, 28 Feb 2018 07:23:45 -0500 Subject: [PATCH 0595/1435] Fix missing flash_loader for L011 (#675) Fixes #654 flash loader on L011 --- src/flash_loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flash_loader.c b/src/flash_loader.c index 9abda5835..a9eafcda3 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -257,7 +257,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* if (sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2 || sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS || sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH - || sl->chip_id == STLINK_CHIPID_STM32_L152_RE + || sl->chip_id == STLINK_CHIPID_STM32_L152_RE || sl->chip_id == STLINK_CHIPID_STM32_L011 || sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); From c8dbc0adb3a5788c498ab45cd04bee40ed3fd060 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 1 Mar 2018 11:40:10 +0100 Subject: [PATCH 0596/1435] doc/man: Fix reference to non-exisiting st-term tool. Fixes #676. --- doc/man/st-flash.1 | 44 ++++++++++++++++++++++++++------------------ doc/man/st-flash.md | 4 ++-- doc/man/st-info.1 | 32 ++++++++++++++++++-------------- doc/man/st-info.md | 5 ++--- doc/man/st-util.1 | 39 +++++++++++++++++++++------------------ doc/man/st-util.md | 4 ++-- 6 files changed, 71 insertions(+), 57 deletions(-) diff --git a/doc/man/st-flash.1 b/doc/man/st-flash.1 index 77a8bb550..5a36354e9 100644 --- a/doc/man/st-flash.1 +++ b/doc/man/st-flash.1 @@ -1,18 +1,21 @@ -.TH ST-FLASH 1 "Sep 2016" "Open Source STMicroelectronics Stlink Tools" "STLINK" +.\" Automatically generated by Pandoc 2.1.1 +.\" +.TH "st\-flash" "1" "Feb 2018" "Open Source STMicroelectronics Stlink Tools" "stlink" +.hy .SH NAME .PP -st-flash - Flash binary files to STM32 device +st\-flash \- Flash binary files to STM32 device .SH SYNOPSIS .PP -\f[I]st-flash\f[] [\f[I]OPTIONS\f[]] {read|write|erase} [\f[I]FILE\f[]] +\f[I]st\-flash\f[] [\f[I]OPTIONS\f[]] {read|write|erase} [\f[I]FILE\f[]] .SH DESCRIPTION .PP Flash binary files to arbitrary sections of memory, or read arbitrary addresses of memory out to a binary file. .PP -You can use this instead of st-util(1) if you prefer, but remember to -use the \f[B]\&.bin\f[] image, rather than the \f[B]\&.elf\f[] file. +You can use this instead of st\-util(1) if you prefer, but remember to +use the \f[B].bin\f[] image, rather than the \f[B].elf\f[] file. .PP Use hexadecimal format for the \f[I]ADDR\f[] and \f[I]SIZE\f[]. .SH COMMANDS @@ -32,33 +35,38 @@ Read firmware from device starting from \f[I]ADDR\f[] up to Perform a mass erasing of the device firmware .RS .RE +.TP +.B reset +Reset the target +.RS +.RE .SH OPTIONS .TP -.B --version +.B \[en]version Print version information .RS .RE .TP -.B --debug +.B \[en]debug TODO .RS .RE .TP -.B --reset +.B \[en]reset TODO .RS .RE .TP -.B --serial \f[I]iSerial\f[] +.B \[en]serial \f[I]iSerial\f[] TODO .RS .RE .TP -.B --flash=\f[I]size\f[] -Override the device's normal flash size, where size is the flash size in bytes. -It can be specified in decimal, octal or hexadecimal. -The size argument can optionally be followed by 'k' for KB or 'm' for MB. -Examples --flash=128k or --flash=0x080k. +.B \[en]flash=fsize +Where fsize is the size in decimal, octal, or hex followed by an +optional multiplier `k' for KB, or `m' for MB. +Use a leading \[lq]0x\[rq] to specify hexadecimal, or a leading zero for +octal. .RS .RE .SH EXAMPLES @@ -67,7 +75,7 @@ Flash \f[C]firmware.bin\f[] to device .IP .nf \f[C] -$\ st-flash\ write\ firmware.bin\ 0x8000000 +$\ st\-flash\ write\ firmware.bin\ 0x8000000 \f[] .fi .PP @@ -75,7 +83,7 @@ Read firmware from device (4096 bytes) .IP .nf \f[C] -$\ st-flash\ read\ firmware.bin\ 0x8000000\ 4096 +$\ st\-flash\ read\ firmware.bin\ 0x8000000\ 4096 \f[] .fi .PP @@ -83,12 +91,12 @@ Erase firmware from device .IP .nf \f[C] -$\ st-flash\ erase +$\ st\-flash\ erase \f[] .fi .SH SEE ALSO .PP -st-util(1), st-info(1), st-term(1) +st\-util(1), st\-info(1) .SH COPYRIGHT .PP This work is copyrighted. diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md index d1844976c..0ac9b111f 100644 --- a/doc/man/st-flash.md +++ b/doc/man/st-flash.md @@ -1,6 +1,6 @@ -% ST-FLASH(1) Open Source STMicroelectronics Stlink Tools | STLINK +% st-flash(1) Open Source STMicroelectronics Stlink Tools | stlink % -% Sep 2016 +% Feb 2018 # NAME diff --git a/doc/man/st-info.1 b/doc/man/st-info.1 index 8576d39e4..a774d3ade 100644 --- a/doc/man/st-info.1 +++ b/doc/man/st-info.1 @@ -1,10 +1,14 @@ -.TH ST-INFO 1 "Sep 2016" "Open Source STMicroelectronics Stlink Tools" "STLINK" +.\" Automatically generated by Pandoc 2.1.1 +.\" +.TH "st\-flash" "1" "Feb 2018" "Open Source STMicroelectronics Stlink Tools" "stlink" +.hy .SH NAME .PP -st-info - Provides information about connected STLink and STM32 devices +st\-info \- Provides information about connected STLink and STM32 +devices .SH SYNOPSIS .PP -\f[I]st-info\f[] [\f[I]OPTIONS\f[]] +\f[I]st\-info\f[] [\f[I]OPTIONS\f[]] .SH DESCRIPTION .PP Provides information about connected STLink programmers and STM32 @@ -12,47 +16,47 @@ devices: Serial code, openocd, flash, sram, page size, chipid, description. .SH OPTIONS .TP -.B --version +.B \[en]version Print version information .RS .RE .TP -.B --flash +.B \[en]flash Display amount of flash memory available in the device .RS .RE .TP -.B --sram +.B \[en]sram Display amount of sram memory available in device .RS .RE .TP -.B --descr +.B \[en]descr Display textual description of the device .RS .RE .TP -.B --pagesize +.B \[en]pagesize Display the page size of the device .RS .RE .TP -.B --chipid +.B \[en]chipid Display the chip ID of the device .RS .RE .TP -.B --serial +.B \[en]serial Display the serial code of the device .RS .RE .TP -.B --hla-serial +.B \[en]hla\-serial Display the hex escaped serial code of the device .RS .RE .TP -.B --probe +.B \[en]probe Display the summarized information of the connected programmers and devices .RS @@ -63,12 +67,12 @@ Display information about connected programmers and devices .IP .nf \f[C] -$\ st-info\ --probe +$\ st\-info\ \-\-probe \f[] .fi .SH SEE ALSO .PP -st-util(1), st-flash(1), st-term(1) +st\-util(1), st\-flash(1) .SH COPYRIGHT .PP This work is copyrighted. diff --git a/doc/man/st-info.md b/doc/man/st-info.md index 62d7c5ce1..1a0773e74 100644 --- a/doc/man/st-info.md +++ b/doc/man/st-info.md @@ -1,7 +1,6 @@ -% ST-INFO(1) Open Source STMicroelectronics Stlink Tools | STLINK +% st-flash(1) Open Source STMicroelectronics Stlink Tools | stlink % -% Sep 2016 - +% Feb 2018 # NAME st-info - Provides information about connected STLink and STM32 devices diff --git a/doc/man/st-util.1 b/doc/man/st-util.1 index 8fb791221..6796bda23 100644 --- a/doc/man/st-util.1 +++ b/doc/man/st-util.1 @@ -1,68 +1,71 @@ -.TH ST-UTIL 1 "Sep 2016" "Open Source STMicroelectronics Stlink Tools" "STLINK" +.\" Automatically generated by Pandoc 2.1.1 +.\" +.TH "st\-util" "1" "Feb 2018" "Open Source STMicroelectronics Stlink Tools" "stlink" +.hy .SH NAME .PP -st-util - Run GDB server to interact with STM32 device +st\-util \- Run GDB server to interact with STM32 device .SH SYNOPSIS .PP -\f[I]st-util\f[] [...] +\f[I]st\-util\f[] [\&...] .SH DESCRIPTION .PP Start a GDB server to interact with a STM32 device Run the main binary of the local package (src/main.rs). .PP -If a port number is not specified using the \f[B]--listen_port\f[] +If a port number is not specified using the \f[B]\[en]listen_port\f[] option, the default \f[B]4242\f[] port will be used. .PP Stlink version 2 is used by default unless the option -\f[B]--stlinkv1\f[] is given. +\f[B]\[en]stlinkv1\f[] is given. .PP The STLinkV2 device to use can be specified in the environment variable STLINK_DEVICE on the format :. .SH OPTIONS .TP -.B -h, --help +.B \-h, \[en]help Print this message. .RS .RE .TP -.B --version +.B \[en]version Print version information .RS .RE .TP -.B -v \f[I]XX\f[], --verbose=XX +.B \-v \f[I]XX\f[], \[en]verbose=XX Specify a specific verbosity level (0..99) .RS .RE .TP -.B -v, --verbose +.B \-v, \[en]verbose Specify generally verbose logging .RS .RE .TP -.B -s \f[I]X\f[], --stlink_version=X +.B \-s \f[I]X\f[], \[en]stlink_version=X Choose what version of stlink to use, (defaults to 2) .RS .RE .TP -.B -1, --stlinkv1 +.B \-1, \[en]stlinkv1 Force stlink version 1 .RS .RE .TP -.B -p \f[I]4242\f[], --listen_port=1234 +.B \-p \f[I]4242\f[], \[en]listen_port=1234 Set the gdb server listen port. (default port: 4242) .RS .RE .TP -.B -m, --multi +.B \-m, \[en]multi Set gdb server to extended mode. -st-util will continue listening for connections after disconnect. +st\-util will continue listening for connections after disconnect. .RS .RE .TP -.B -n, --no-reset +.B \-n, \[en]no\-reset Do not reset board on connection. .RS .RE @@ -72,14 +75,14 @@ Run GDB server on port 4500 and connect to it .IP .nf \f[C] -$\ st-util\ -p\ 4500 +$\ st\-util\ \-p\ 4500 $\ gdb -(gdb)\ target\ extended-remote\ localhost:4500 +(gdb)\ target\ extended\-remote\ localhost:4500 \f[] .fi .SH SEE ALSO .PP -st-flash(1), st-info(1), st-term(1) +st\-flash(1), st\-info(1) .SH COPYRIGHT .PP This work is copyrighted. diff --git a/doc/man/st-util.md b/doc/man/st-util.md index fd744d825..325f84206 100644 --- a/doc/man/st-util.md +++ b/doc/man/st-util.md @@ -1,6 +1,6 @@ -% ST-UTIL(1) Open Source STMicroelectronics Stlink Tools | STLINK +% st-util(1) Open Source STMicroelectronics Stlink Tools | stlink % -% Sep 2016 +% Feb 2018 # NAME From 1f18a18a8594853c30acaae04c0569536b20e55b Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 1 Mar 2018 11:51:26 +0100 Subject: [PATCH 0597/1435] doc/man: Add semihosting parameter documentation, fix styling issue with double dashhes. Fixes #674. --- doc/man/st-flash.1 | 10 +++++----- doc/man/st-flash.md | 24 +++++++++++------------- doc/man/st-util.1 | 23 ++++++++++++++--------- doc/man/st-util.md | 31 ++++++++++++++++--------------- 4 files changed, 46 insertions(+), 42 deletions(-) diff --git a/doc/man/st-flash.1 b/doc/man/st-flash.1 index 5a36354e9..1ee272957 100644 --- a/doc/man/st-flash.1 +++ b/doc/man/st-flash.1 @@ -42,27 +42,27 @@ Reset the target .RE .SH OPTIONS .TP -.B \[en]version +.B \f[C]\-\-version\f[] Print version information .RS .RE .TP -.B \[en]debug +.B \f[C]\-\-debug\f[] TODO .RS .RE .TP -.B \[en]reset +.B \f[C]\-\-reset\f[] TODO .RS .RE .TP -.B \[en]serial \f[I]iSerial\f[] +.B \f[C]\-\-serial\f[] \f[I]iSerial\f[] TODO .RS .RE .TP -.B \[en]flash=fsize +.B \f[C]\-\-flash=fsize\f[] Where fsize is the size in decimal, octal, or hex followed by an optional multiplier `k' for KB, or `m' for MB. Use a leading \[lq]0x\[rq] to specify hexadecimal, or a leading zero for diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md index 0ac9b111f..e617e4305 100644 --- a/doc/man/st-flash.md +++ b/doc/man/st-flash.md @@ -2,16 +2,16 @@ % % Feb 2018 - # NAME -st-flash - Flash binary files to STM32 device +st-flash - Flash binary files to STM32 device # SYNOPSIS -*st-flash* \[*OPTIONS*\] \{read|write|erase\} \[*FILE*\] \ \ +*st-flash* \[*OPTIONS*\] \{read|write|erase\} \[*FILE*\] \ \ # DESCRIPTION + Flash binary files to arbitrary sections of memory, or read arbitrary addresses of memory out to a binary file. @@ -20,7 +20,6 @@ You can use this instead of st-util(1) if you prefer, but remember to use the Use hexadecimal format for the *ADDR* and *SIZE*. - # COMMANDS write *FILE* *ADDR* @@ -37,43 +36,42 @@ reset # OPTIONS ---version +`--version` : Print version information ---debug +`--debug` : TODO ---reset +`--reset` : TODO ---serial *iSerial* +`--serial` *iSerial* : TODO ---flash=fsize +`--flash=fsize` : Where fsize is the size in decimal, octal, or hex followed by an optional multiplier 'k' for KB, or 'm' for MB. Use a leading "0x" to specify hexadecimal, or a leading zero for octal. # EXAMPLES + Flash `firmware.bin` to device $ st-flash write firmware.bin 0x8000000 - Read firmware from device (4096 bytes) $ st-flash read firmware.bin 0x8000000 4096 - Erase firmware from device $ st-flash erase - # SEE ALSO -st-util(1), st-info(1) +st-util(1), st-info(1) # COPYRIGHT + This work is copyrighted. Stlink contributors. See *LICENSE* file in the stlink source distribution. diff --git a/doc/man/st-util.1 b/doc/man/st-util.1 index 6796bda23..a7b2eb6cf 100644 --- a/doc/man/st-util.1 +++ b/doc/man/st-util.1 @@ -23,52 +23,57 @@ The STLinkV2 device to use can be specified in the environment variable STLINK_DEVICE on the format :. .SH OPTIONS .TP -.B \-h, \[en]help +.B \-h, \f[C]\-\-help\f[] Print this message. .RS .RE .TP -.B \[en]version +.B \f[C]\-\-version\f[] Print version information .RS .RE .TP -.B \-v \f[I]XX\f[], \[en]verbose=XX +.B \-v \f[I]XX\f[], \f[C]\-\-verbose=XX\f[] Specify a specific verbosity level (0..99) .RS .RE .TP -.B \-v, \[en]verbose +.B \-v, \f[C]\-\-verbose\f[] Specify generally verbose logging .RS .RE .TP -.B \-s \f[I]X\f[], \[en]stlink_version=X +.B \-s \f[I]X\f[], \f[C]\-\-stlink_version=X\f[] Choose what version of stlink to use, (defaults to 2) .RS .RE .TP -.B \-1, \[en]stlinkv1 +.B \-1, \f[C]\-\-stlinkv1\f[] Force stlink version 1 .RS .RE .TP -.B \-p \f[I]4242\f[], \[en]listen_port=1234 +.B \-p \f[I]4242\f[], \f[C]\-\-listen_port=1234\f[] Set the gdb server listen port. (default port: 4242) .RS .RE .TP -.B \-m, \[en]multi +.B \-m, \f[C]\-\-multi\f[] Set gdb server to extended mode. st\-util will continue listening for connections after disconnect. .RS .RE .TP -.B \-n, \[en]no\-reset +.B \-n, \f[C]\-\-no\-reset\f[] Do not reset board on connection. .RS .RE +.TP +.B \f[C]\-\-semihosting\f[] +Enable ARM Semihosting output on stdout +.RS +.RE .SH EXAMPLES .PP Run GDB server on port 4500 and connect to it diff --git a/doc/man/st-util.md b/doc/man/st-util.md index 325f84206..b141091f9 100644 --- a/doc/man/st-util.md +++ b/doc/man/st-util.md @@ -2,14 +2,13 @@ % % Feb 2018 - # NAME -st-util - Run GDB server to interact with STM32 device +st-util - Run GDB server to interact with STM32 device # SYNOPSIS -*st-util* \[\...] +*st-util* \[\...] # DESCRIPTION Start a GDB server to interact with a STM32 device @@ -23,49 +22,51 @@ Stlink version 2 is used by default unless the option **--stlinkv1** is given. The STLinkV2 device to use can be specified in the environment variable STLINK_DEVICE on the format :. - # OPTIONS --h, --help +-h, `--help` : Print this message. ---version +`--version` : Print version information --v *XX*, --verbose=XX +-v *XX*, `--verbose=XX` : Specify a specific verbosity level (0..99) --v, --verbose +-v, `--verbose` : Specify generally verbose logging --s *X*, --stlink_version=X +-s *X*, `--stlink_version=X` : Choose what version of stlink to use, (defaults to 2) --1, --stlinkv1 +-1, `--stlinkv1` : Force stlink version 1 --p *4242*, --listen_port=1234 +-p *4242*, `--listen_port=1234` : Set the gdb server listen port. (default port: 4242) --m, --multi +-m, `--multi` : Set gdb server to extended mode. st-util will continue listening for connections after disconnect. --n, --no-reset +-n, `--no-reset` : Do not reset board on connection. +`--semihosting` +: Enable ARM Semihosting output on stdout # EXAMPLES + Run GDB server on port 4500 and connect to it $ st-util -p 4500 $ gdb (gdb) target extended-remote localhost:4500 - # SEE ALSO -st-flash(1), st-info(1) +st-flash(1), st-info(1) # COPYRIGHT + This work is copyrighted. Stlink contributors. See *LICENSE* file in the stlink source distribution. From b69c1d51b03a4345c4d478ac1d8c2088002cd36a Mon Sep 17 00:00:00 2001 From: ZogFluff Date: Tue, 6 Mar 2018 12:38:44 -0800 Subject: [PATCH 0598/1435] fix serial name size mismatch with stlink_open_usb() (#680) --- src/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/usb.c b/src/usb.c index 92a0a6ef4..dbacfee83 100644 --- a/src/usb.c +++ b/src/usb.c @@ -1002,7 +1002,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { continue; struct libusb_device_handle* handle; - char serial[13]; + char serial[16]; memset(serial, 0, sizeof(serial)); ret = libusb_open(dev, &handle); From e9fe4e51452133b1bd9a563a8f40953391bb2175 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Fri, 16 Mar 2018 15:41:07 +0000 Subject: [PATCH 0599/1435] Debian packaging, CMake and README.md fixes (#683) * Use https for debian/copyright * Update dates and fix stanzas in debian/copyright No need to have 2 stanzas for the same license * Add BSD-3-clause body in debian/copyright * Remove generated boilerplate from debian/rules * Enable compiler hardening flags in debian/rules * Fix source package name according to repo and docs * Set source package section to electronics See https://packages.debian.org/unstable/electronics/ for a full list * Add long descriptions to packages * Add gbp.conf file * Update changelog for 1.5.0 release * Remove dirs files, not needed anymore * Rename library package to match SONAME As per Debian policy, shared library packages must be named after their SONAME version. * libstlink0: break+replace libstlink since it took over its files * Remove triggers, not needed anymore debhelper tools will generate the triggers file automatically since the package name was corrected * List GPL2+ in debian/copyright for flashloaders * Do not append -shared to shared library on *NIX Only on Windows it's necessary to have different file names, on *NIX the extension is what disambiguates between a static library (.a) and a shared library (.so). * Clarify license of flashloaders in README.md Fixes #682 * List all individual authors in debian/copyright The Debian FTP masters nowadays require that all authors are listed in debian/copyright. Print the list of authors from git. * Move modprobe and udev files from shared library package to tools package Multiple versions of a shared library might be installed on the same system. Do not ship unversioned files in their packages, or they will conflict and fail to install. * stlink-tools: break+replace libstlink It took ownership of udev and modprobe files from libstlink * Fix pkgconfig include dir: remove project version The headers are installed in /usr/include/stlink without a version number. * Add libstlink1 symbols file Generated with: dpkg-gensymbols -P/tmp -v1.5.0 -V -e/tmp/libstlink.so.1.5.0 -plibstlink1 -Odebian/libstlink1.symbols * Bump Standards-Version to 4.1.3 Main changes are shared library rename and files moved, and HTTPS URLs. https://www.debian.org/doc/packaging-manuals/upgrading-checklist.txt * Add debian/watch file for notifications The Debian package tracker can automatically notify when a new version is out. --- CMakeLists.txt | 4 + README.md | 4 +- debian/changelog | 59 +++++++++++ debian/control | 49 ++++++--- debian/copyright | 174 +++++++++++++++++++++++++++++-- debian/gbp.conf | 7 ++ debian/libstlink-dev.dirs | 2 - debian/libstlink.dirs | 1 - debian/libstlink.install | 3 - debian/libstlink1.install | 1 + debian/libstlink1.symbols | 125 ++++++++++++++++++++++ debian/rules | 11 +- debian/stlink-gui.dirs | 2 - debian/stlink-tools.dirs | 2 - debian/stlink-tools.install | 2 + debian/triggers | 1 - debian/watch | 3 + usr/lib/pkgconfig/CMakeLists.txt | 2 +- 18 files changed, 407 insertions(+), 45 deletions(-) create mode 100644 debian/gbp.conf delete mode 100644 debian/libstlink-dev.dirs delete mode 100644 debian/libstlink.dirs delete mode 100644 debian/libstlink.install create mode 100644 debian/libstlink1.install create mode 100644 debian/libstlink1.symbols delete mode 100644 debian/stlink-gui.dirs delete mode 100644 debian/stlink-tools.dirs delete mode 100644 debian/triggers create mode 100644 debian/watch diff --git a/CMakeLists.txt b/CMakeLists.txt index d2be523bf..6ed84bd3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,7 +83,11 @@ endif () ### # Shared library ### +if (NOT WIN32) +set(STLINK_LIB_SHARED ${PROJECT_NAME}) +else () set(STLINK_LIB_SHARED ${PROJECT_NAME}-shared) +endif() add_library(${STLINK_LIB_SHARED} SHARED ${STLINK_HEADERS} # header files for ide projects generated by cmake diff --git a/README.md b/README.md index 6e23356af..bdb2351a6 100644 --- a/README.md +++ b/README.md @@ -232,5 +232,5 @@ Issue related to this bug: [#545](https://github.com/texane/stlink/issues/545) ## License -The stlink library and tools are licensed under the [BSD license](LICENSE). With -some exceptions on external components (e.g flashloaders). +The stlink library and tools are licensed under the [BSD license](LICENSE). +The flashloaders/stm32l0x.s and flashloaders/stm32lx.s source files are licensed under the GPL-2+. diff --git a/debian/changelog b/debian/changelog index 0f3edb222..ac18fd872 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,62 @@ +stlink (1.5.0) unstable; urgency=medium + + [ Jerry Jacobs ] + * README.md: Update version badge to v1.4.0 + + [ Viallard Anthony ] + * Add support of STM32L496xx/4A6xx devices (#615) + + [ rdlim ] + * Fix verification of flash error for STM32L496x device (#617) (#618) + + [ dflogeras ] + * Add note about availability in Gentoo package manager (#622) + + [ yaofei zheng ] + * update debian package version (#630) + + [ Lyle Cheatham ] + * Minor formatting fix in FAQ section of README.md (#631) + + [ Vasiliy Glazov ] + * README.md: Added information about Fedora and RedHat/CentOS packages. + (#635) + * Added LIB_INSTALL_DIR to correct libs install on 64-bit systems (#636) + + [ Gwenhael Goavec-Merou ] + * fix write for microcontroler with RAM size less or equal to 32K (#637) + + [ Mateusz Krawiec ] + * Fix memory map for stm32l496xx boards. (#639) + + [ Rüdiger Fortanier ] + * Add unknown chip output (#641) + + [ Slyshyk Oleksiy ] + * fix __FILE__ base name extraction, #628 (#648) + + [ texane ] + * STM32F72xx73xx support, from bob.feretich@rafresearch.com + + [ Kirill Kolyshkin ] + * debian/triggers: add (to run ldconfig) (#664) + + [ Slyshyk Oleksiy ] + * Try to fix #666 issue (#667) + * Try to fix 666 issue (#668) + + [ Jerry Jacobs ] + * Update ChangeLog.md + * Update README.md + + [ texane ] + * STM32F042K6 Nucleo-32 Board reported to work, by frank@bauernoeppel.de + + [ Anatol Pomozov ] + * Update .version file to match release number (#670) + + -- Anatol Pomozov Mon, 19 Feb 2018 11:00:29 -0800 + libstlink (1.4.0) unstable; urgency=low * Major changes and added features diff --git a/debian/control b/debian/control index 41c8e87a3..e33fc757c 100644 --- a/debian/control +++ b/debian/control @@ -1,9 +1,9 @@ -Source: libstlink +Source: stlink Priority: optional Maintainer: Andrew 'Necromant' Andrianov Build-Depends: debhelper (>= 9), cmake, libusb-1.0-0-dev, libgtk-3-dev -Standards-Version: 3.9.5 -Section: libs +Standards-Version: 4.1.3 +Section: electronics Homepage: https://github.com/texane/stlink Vcs-Git: https://github.com/texane/stlink.git Vcs-Browser: https://github.com/texane/stlink @@ -11,24 +11,43 @@ Vcs-Browser: https://github.com/texane/stlink Package: libstlink-dev Section: libdevel Architecture: any -Depends: libstlink (= ${binary:Version}), ${misc:Depends} -Description: OpenSource ST-Link tools replacement. Development headers. - This package contains development headers for libstlink. +Depends: libstlink1 (= ${binary:Version}), ${misc:Depends} +Description: OpenSource ST-Link tools replacement. + Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers + STLINKv1 and STLINKv2 are supported. + . + This package contains the development files for stlink. -Package: libstlink +Package: libstlink1 +Section: libs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} -Description: OpenSource ST-Link tools replacement. Shared library. - This package libstlink shared library. +Breaks: libstlink +Replaces: libstlink +Description: OpenSource ST-Link tools replacement. + Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers + STLINKv1 and STLINKv2 are supported. + . + This package contains the shared library for stlink. Package: stlink-tools -Section: libdevel Architecture: any -Depends: libstlink (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} -Description: OpenSource ST-Link tools replacement. Commandline Utilities. +Depends: libstlink1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} +Breaks: libstlink +Replaces: libstlink +Description: OpenSource ST-Link tools replacement. + Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers + STLINKv1 and STLINKv2 are supported. + . + This package contains commandline utilities for stlink, and modprobe and + udev rules. Package: stlink-gui -Section: libdevel Architecture: any -Depends: libstlink (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} -Description: OpenSource ST-Link tools replacement. GUI Tool. +Depends: libstlink1 (= ${binary:Version}), stlink-tools (= ${binary:Version}), + ${shlibs:Depends}, ${misc:Depends} +Description: OpenSource ST-Link tools replacement. + Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers + STLINKv1 and STLINKv2 are supported. + . + This package contains a GUI tool for stlink. diff --git a/debian/copyright b/debian/copyright index e28d7e1bb..941a4a011 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,12 +1,174 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: libstlink +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: stlink Upstream-Contact: Andrew 'Necromant' Andrianov Source: https://github.com/texane/stlink Files: * -Copyright: (c) 2011 The stlink project (github.com/texane/stlink) contributors. +Copyright: 2011-2018 agpanarin + 2011-2018 Alexey Cherevatenko + 2011-2018 Anatoli + 2011-2018 Andrea Mucignat + 2011-2018 Andrew 'Necromant' Andrianov + 2011-2018 Andrey Yurovsky + 2011-2018 Andy Isaacson + 2011-2018 Áron RADICS + 2011-2018 A Sheaff + 2011-2018 Björn Hauffe + 2011-2018 bob + 2011-2018 Breton M. Saunders + 2011-2018 Bruno Dal Bo + 2011-2018 Burns + 2011-2018 Chris Dew + 2011-2018 Chris Hiszpanski + 2011-2018 Chris Li + 2011-2018 Chris Samuelson + 2011-2018 Christophe Levantis + 2011-2018 Craig Lilley + 2011-2018 dandev37 + 2011-2018 Dan Hepler + 2011-2018 Daniel Campoverde [alx741] + 2011-2018 Daniel O'Connor + 2011-2018 Dave Flogeras + 2011-2018 Dave Murphy + 2011-2018 Dave Vandervies + 2011-2018 Denis Fokin + 2011-2018 Denis Osterland + 2011-2018 Dmitry Bravikov + 2011-2018 Efe Can İçöz + 2011-2018 Ethan Zonca + 2011-2018 Fabien Chouteau + 2011-2018 Fabien Le Mentec + 2011-2018 fhars + 2011-2018 Friedrich Beckmann + 2011-2018 Geoffrey Brown + 2011-2018 George Talusan + 2011-2018 Georg von Zengen + 2011-2018 giuseppe barba + 2011-2018 Greg Alexander + 2011-2018 Greg Meiste + 2011-2018 Hakkavélin + 2011-2018 htk + 2011-2018 Ian Griffiths <6thimage@gmail.com> + 2011-2018 Jack Peel + 2011-2018 Jakub Tyszkowski + 2011-2018 Jan Sarenik + 2011-2018 Jean-Luc Béchennec + 2011-2018 Jean-Marie Lemetayer + 2011-2018 Jeff Kent + 2011-2018 Jeffrey Nelson + 2011-2018 Jens Hoffmann + 2011-2018 Jerome Lambourg + 2011-2018 Jerry Jacobs + 2011-2018 Jim Paris + 2011-2018 Jiří Netolický + 2011-2018 jnosky + 2011-2018 jnosky + 2011-2018 JohannesTaelman + 2011-2018 Jonas Danielsson + 2011-2018 Jonas Norling + 2011-2018 Josh Bialkowski + 2011-2018 Karl Palsson + 2011-2018 kevin + 2011-2018 Kyle Manna + 2011-2018 Lari Lehtomäki + 2011-2018 le mentec fabien + 2011-2018 Martin Nowak + 2011-2018 Matteo Collina + 2011-2018 Max Chen + 2011-2018 Maxime Coquelin + 2011-2018 Maxime Vincent + 2011-2018 Michael Pratt + 2011-2018 Michael Sparmann + 2011-2018 Mike Szczys + 2011-2018 mlundinse + 2011-2018 mux + 2011-2018 Ned Konz + 2011-2018 Nic McDonald + 2011-2018 Nicolas Schodet + 2011-2018 Nikolay + 2011-2018 nullsub + 2011-2018 Olivier Croquette + 2011-2018 Olivier Gay + 2011-2018 Onno Kortmann + 2011-2018 orangeudav + 2011-2018 Pavel Kirienko + 2011-2018 Pekka Nikander + 2011-2018 Pete + 2011-2018 Peter Zotov + 2011-2018 Petteri Aimonen + 2011-2018 Piotr Haber + 2011-2018 Rene Hopf + 2011-2018 Robin Kreis + 2011-2018 Rob Spanton + 2011-2018 Rytis Karpuska + 2011-2018 Sean Simmons + 2011-2018 Sergey Alirzaev + 2011-2018 Simon Wright + 2011-2018 Stany MARCEL + 2011-2018 Stefan Misik + 2011-2018 Sven Wegener + 2011-2018 Tectu + 2011-2018 tekaikko + 2011-2018 texane + 2011-2018 Theodore A. Roth + 2011-2018 Thomas Gärtner + 2011-2018 Tobias Badertscher + 2011-2018 Tom de Boer + 2011-2018 Tristan Gingold + 2011-2018 Uli Köhler + 2011-2018 Uwe Bonnes + 2011-2018 Vadim Kaushan + 2011-2018 Vegard Storheil Eriksen + 2011-2018 Viacheslav Dobromyslov + 2011-2018 Victor Mayoral Vilches + 2011-2018 Wojciech A. Koszek + 2011-2018 Woodrow Douglass + 2011-2018 The "Capt'ns Missing Link" Authors. License: BSD-3-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + . + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -Files: * -Copyright: (c) 2011 The "Capt'ns Missing Link" Authors. All rights reserved. -License: BSD-3-clause +Files: flashloaders/stm32l0x.s + flashloaders/stm32lx.s +Copyright: 2010 Spencer Oliver + 2011 Øyvind Harboe + 2011 Clement Burin des Roziers +License: GPL-2+ + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see + . + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". diff --git a/debian/gbp.conf b/debian/gbp.conf new file mode 100644 index 000000000..418e536e9 --- /dev/null +++ b/debian/gbp.conf @@ -0,0 +1,7 @@ +[buildpackage] +upstream-tag = %(version)s +debian-branch = debian + +[dch] +git-log = --first-parent +customizations = /usr/share/doc/git-buildpackage/examples/wrap_cl.py diff --git a/debian/libstlink-dev.dirs b/debian/libstlink-dev.dirs deleted file mode 100644 index 44188162e..000000000 --- a/debian/libstlink-dev.dirs +++ /dev/null @@ -1,2 +0,0 @@ -usr/lib -usr/include diff --git a/debian/libstlink.dirs b/debian/libstlink.dirs deleted file mode 100644 index 68457717b..000000000 --- a/debian/libstlink.dirs +++ /dev/null @@ -1 +0,0 @@ -usr/lib diff --git a/debian/libstlink.install b/debian/libstlink.install deleted file mode 100644 index 08981406e..000000000 --- a/debian/libstlink.install +++ /dev/null @@ -1,3 +0,0 @@ -usr/lib/*/lib*.so.* -lib/udev/rules.d/*.rules -etc/modprobe.d/*.conf diff --git a/debian/libstlink1.install b/debian/libstlink1.install new file mode 100644 index 000000000..3ddde5841 --- /dev/null +++ b/debian/libstlink1.install @@ -0,0 +1 @@ +usr/lib/*/lib*.so.* diff --git a/debian/libstlink1.symbols b/debian/libstlink1.symbols new file mode 100644 index 000000000..51fa9bdb1 --- /dev/null +++ b/debian/libstlink1.symbols @@ -0,0 +1,125 @@ +libstlink.so.1 libstlink1 #MINVER# + _parse_version@Base 1.5.0 + _stlink_sg_close@Base 1.5.0 + _stlink_sg_core_id@Base 1.5.0 + _stlink_sg_current_mode@Base 1.5.0 + _stlink_sg_enter_jtag_mode@Base 1.5.0 + _stlink_sg_enter_swd_mode@Base 1.5.0 + _stlink_sg_exit_debug_mode@Base 1.5.0 + _stlink_sg_exit_dfu_mode@Base 1.5.0 + _stlink_sg_force_debug@Base 1.5.0 + _stlink_sg_jtag_reset@Base 1.5.0 + _stlink_sg_read_all_regs@Base 1.5.0 + _stlink_sg_read_debug32@Base 1.5.0 + _stlink_sg_read_mem32@Base 1.5.0 + _stlink_sg_read_reg@Base 1.5.0 + _stlink_sg_reset@Base 1.5.0 + _stlink_sg_run@Base 1.5.0 + _stlink_sg_status@Base 1.5.0 + _stlink_sg_step@Base 1.5.0 + _stlink_sg_version@Base 1.5.0 + _stlink_sg_write_debug32@Base 1.5.0 + _stlink_sg_write_mem32@Base 1.5.0 + _stlink_sg_write_mem8@Base 1.5.0 + _stlink_sg_write_reg@Base 1.5.0 + _stlink_usb_close@Base 1.5.0 + _stlink_usb_core_id@Base 1.5.0 + _stlink_usb_current_mode@Base 1.5.0 + _stlink_usb_enter_swd_mode@Base 1.5.0 + _stlink_usb_exit_debug_mode@Base 1.5.0 + _stlink_usb_exit_dfu_mode@Base 1.5.0 + _stlink_usb_force_debug@Base 1.5.0 + _stlink_usb_jtag_reset@Base 1.5.0 + _stlink_usb_read_all_regs@Base 1.5.0 + _stlink_usb_read_all_unsupported_regs@Base 1.5.0 + _stlink_usb_read_debug32@Base 1.5.0 + _stlink_usb_read_mem32@Base 1.5.0 + _stlink_usb_read_reg@Base 1.5.0 + _stlink_usb_read_unsupported_reg@Base 1.5.0 + _stlink_usb_reset@Base 1.5.0 + _stlink_usb_run@Base 1.5.0 + _stlink_usb_set_swdclk@Base 1.5.0 + _stlink_usb_status@Base 1.5.0 + _stlink_usb_step@Base 1.5.0 + _stlink_usb_target_voltage@Base 1.5.0 + _stlink_usb_version@Base 1.5.0 + _stlink_usb_write_debug32@Base 1.5.0 + _stlink_usb_write_mem32@Base 1.5.0 + _stlink_usb_write_mem8@Base 1.5.0 + _stlink_usb_write_reg@Base 1.5.0 + _stlink_usb_write_unsupported_reg@Base 1.5.0 + calculate_F4_sectornum@Base 1.5.0 + calculate_F7_sectornum@Base 1.5.0 + calculate_L4_page@Base 1.5.0 + is_bigendian@Base 1.5.0 + read_uint16@Base 1.5.0 + read_uint32@Base 1.5.0 + send_recv@Base 1.5.0 + send_usb_data_only@Base 1.5.0 + send_usb_mass_storage_command@Base 1.5.0 + stlink_calculate_pagesize@Base 1.5.0 + stlink_chip_id@Base 1.5.0 + stlink_chipid_get_params@Base 1.5.0 + stlink_close@Base 1.5.0 + stlink_clr_hw_bp@Base 1.5.0 + stlink_core_id@Base 1.5.0 + stlink_core_stat@Base 1.5.0 + stlink_cpu_id@Base 1.5.0 + stlink_current_mode@Base 1.5.0 + stlink_enter_swd_mode@Base 1.5.0 + stlink_erase_flash_mass@Base 1.5.0 + stlink_erase_flash_page@Base 1.5.0 + stlink_exit_debug_mode@Base 1.5.0 + stlink_exit_dfu_mode@Base 1.5.0 + stlink_fcheck_flash@Base 1.5.0 + stlink_flash_loader_init@Base 1.5.0 + stlink_flash_loader_run@Base 1.5.0 + stlink_flash_loader_write_to_sram@Base 1.5.0 + stlink_force_debug@Base 1.5.0 + stlink_fread@Base 1.5.0 + stlink_fwrite_flash@Base 1.5.0 + stlink_fwrite_sram@Base 1.5.0 + stlink_get_erased_pattern@Base 1.5.0 + stlink_is_core_halted@Base 1.5.0 + stlink_jtag_reset@Base 1.5.0 + stlink_load_device_params@Base 1.5.0 + stlink_mwrite_flash@Base 1.5.0 + stlink_mwrite_sram@Base 1.5.0 + stlink_open_usb@Base 1.5.0 + stlink_parse_ihex@Base 1.5.0 + stlink_print_data@Base 1.5.0 + stlink_probe_usb@Base 1.5.0 + stlink_probe_usb_free@Base 1.5.0 + stlink_q@Base 1.5.0 + stlink_read_all_regs@Base 1.5.0 + stlink_read_all_unsupported_regs@Base 1.5.0 + stlink_read_debug32@Base 1.5.0 + stlink_read_mem32@Base 1.5.0 + stlink_read_reg@Base 1.5.0 + stlink_read_unsupported_reg@Base 1.5.0 + stlink_reset@Base 1.5.0 + stlink_run@Base 1.5.0 + stlink_run_at@Base 1.5.0 + stlink_set_hw_bp@Base 1.5.0 + stlink_set_swdclk@Base 1.5.0 + stlink_stat@Base 1.5.0 + stlink_status@Base 1.5.0 + stlink_step@Base 1.5.0 + stlink_target_voltage@Base 1.5.0 + stlink_v1_open@Base 1.5.0 + stlink_v1_open_inner@Base 1.5.0 + stlink_verify_write_flash@Base 1.5.0 + stlink_version@Base 1.5.0 + stlink_write_debug32@Base 1.5.0 + stlink_write_dreg@Base 1.5.0 + stlink_write_flash@Base 1.5.0 + stlink_write_mem32@Base 1.5.0 + stlink_write_mem8@Base 1.5.0 + stlink_write_reg@Base 1.5.0 + stlink_write_unsupported_reg@Base 1.5.0 + stm32l1_write_half_pages@Base 1.5.0 + ugly_init@Base 1.5.0 + ugly_log@Base 1.5.0 + write_buffer_to_sram@Base 1.5.0 + write_uint16@Base 1.5.0 + write_uint32@Base 1.5.0 diff --git a/debian/rules b/debian/rules index 2ff7e59a8..c4e9e2afd 100755 --- a/debian/rules +++ b/debian/rules @@ -8,20 +8,11 @@ DPKG_EXPORT_BUILDFLAGS = 1 include /usr/share/dpkg/default.mk # see FEATURE AREAS in dpkg-buildflags(1) -#export DEB_BUILD_MAINT_OPTIONS = hardening=+all +export DEB_BUILD_MAINT_OPTIONS = hardening=+all -# see ENVIRONMENT in dpkg-buildflags(1) -# package maintainers to append CFLAGS -#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic -# package maintainers to append LDFLAGS -#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed - -# main packaging script based on dh7 syntax %: dh $@ --buildsystem cmake -# debmake generated override targets -# This is example for Cmake (See http://bugs.debian.org/641051 ) override_dh_auto_configure: dh_auto_configure -- \ -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) \ diff --git a/debian/stlink-gui.dirs b/debian/stlink-gui.dirs deleted file mode 100644 index d080ed407..000000000 --- a/debian/stlink-gui.dirs +++ /dev/null @@ -1,2 +0,0 @@ -/usr/bin -/usr/share/ diff --git a/debian/stlink-tools.dirs b/debian/stlink-tools.dirs deleted file mode 100644 index 377c76613..000000000 --- a/debian/stlink-tools.dirs +++ /dev/null @@ -1,2 +0,0 @@ -/usr/bin - diff --git a/debian/stlink-tools.install b/debian/stlink-tools.install index 4fa1125bf..ca875a0e6 100644 --- a/debian/stlink-tools.install +++ b/debian/stlink-tools.install @@ -1 +1,3 @@ /usr/bin/st-* +lib/udev/rules.d/*.rules +etc/modprobe.d/*.conf diff --git a/debian/triggers b/debian/triggers deleted file mode 100644 index dd8660367..000000000 --- a/debian/triggers +++ /dev/null @@ -1 +0,0 @@ -activate-noawait ldconfig diff --git a/debian/watch b/debian/watch new file mode 100644 index 000000000..cc653ca9f --- /dev/null +++ b/debian/watch @@ -0,0 +1,3 @@ +version=3 +opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/-$1\.tar\.gz/ \ + https://github.com/texane/stlink/tags .*/v?(\d\S+)\.tar\.gz diff --git a/usr/lib/pkgconfig/CMakeLists.txt b/usr/lib/pkgconfig/CMakeLists.txt index 1d7bcd1dc..a656ff623 100644 --- a/usr/lib/pkgconfig/CMakeLists.txt +++ b/usr/lib/pkgconfig/CMakeLists.txt @@ -1,5 +1,5 @@ set(PKG_CONFIG_LIBDIR "\${prefix}/lib/\${deb_host_multiarch}") -set(PKG_CONFIG_INCLUDEDIR "\${prefix}/include/\${deb_host_multiarch}/${PROJECT_NAME}-${PROJECT_VERSION}") +set(PKG_CONFIG_INCLUDEDIR "\${prefix}/include/\${deb_host_multiarch}/${PROJECT_NAME}") set(PKG_CONFIG_LIBS "-L\${libdir} -l:libstlink.so.${PROJECT_VERSION_MAJOR}") set(PKG_CONFIG_CFLAGS "-I\${includedir}") set(PKG_CONFIG_REQUIRES "libusb-1.0") From 64ef6a8a237d438ecfb3c92d92be0fba84af4e3a Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 13 Mar 2018 00:27:55 +0000 Subject: [PATCH 0600/1435] Change format to non-native, set myself as maintainer --- debian/changelog | 6 ++++++ debian/control | 6 +++--- debian/source/format | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index ac18fd872..d55b32837 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +stlink (1.5.0-1) UNRELEASED; urgency=medium + + * Upload to unstable. (Closes: #869421) + + -- Luca Boccassi Tue, 13 Mar 2018 00:26:52 +0000 + stlink (1.5.0) unstable; urgency=medium [ Jerry Jacobs ] diff --git a/debian/control b/debian/control index e33fc757c..db6f9e7e0 100644 --- a/debian/control +++ b/debian/control @@ -1,12 +1,12 @@ Source: stlink Priority: optional -Maintainer: Andrew 'Necromant' Andrianov +Maintainer: Luca Boccassi Build-Depends: debhelper (>= 9), cmake, libusb-1.0-0-dev, libgtk-3-dev Standards-Version: 4.1.3 Section: electronics Homepage: https://github.com/texane/stlink -Vcs-Git: https://github.com/texane/stlink.git -Vcs-Browser: https://github.com/texane/stlink +Vcs-Git: https://github.com/bluca/stlink.git +Vcs-Browser: https://github.com/bluca/stlink Package: libstlink-dev Section: libdevel diff --git a/debian/source/format b/debian/source/format index 89ae9db8f..163aaf8d8 100644 --- a/debian/source/format +++ b/debian/source/format @@ -1 +1 @@ -3.0 (native) +3.0 (quilt) From 848839034573498ed80e3290e119e1fcaa031dcc Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Fri, 16 Mar 2018 16:13:53 +0000 Subject: [PATCH 0601/1435] Repack tarball to remove debian/ and stlinkv1_macosx_driver/ --- debian/changelog | 2 +- debian/copyright | 5 +++++ debian/watch | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index d55b32837..3439e586c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -stlink (1.5.0-1) UNRELEASED; urgency=medium +stlink (1.5.0+ds-1) UNRELEASED; urgency=medium * Upload to unstable. (Closes: #869421) diff --git a/debian/copyright b/debian/copyright index 941a4a011..d56807ca5 100644 --- a/debian/copyright +++ b/debian/copyright @@ -2,6 +2,11 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: stlink Upstream-Contact: Andrew 'Necromant' Andrianov Source: https://github.com/texane/stlink +Comment: Upstream tarball has been repackaged to remove binary OSX kernel + drivers that are of unknown license and of no use to Debian. + Upstream's debian directory is also removed. +Files-Excluded: stlinkv1_macosx_driver + debian Files: * Copyright: 2011-2018 agpanarin diff --git a/debian/watch b/debian/watch index cc653ca9f..921dc8f0d 100644 --- a/debian/watch +++ b/debian/watch @@ -1,3 +1,3 @@ version=3 -opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/-$1\.tar\.gz/ \ +opts=dversionmangle=s/\+ds$//,repacksuffix=+ds,filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/-$1\.tar\.gz/ \ https://github.com/texane/stlink/tags .*/v?(\d\S+)\.tar\.gz From abdf4ce070b01586d82740922e86a16bb0206ba5 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Fri, 16 Mar 2018 16:20:26 +0000 Subject: [PATCH 0602/1435] Remove breaks and replaces, not applicable to Debian --- debian/control | 4 ---- 1 file changed, 4 deletions(-) diff --git a/debian/control b/debian/control index db6f9e7e0..3427359c6 100644 --- a/debian/control +++ b/debian/control @@ -22,8 +22,6 @@ Package: libstlink1 Section: libs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} -Breaks: libstlink -Replaces: libstlink Description: OpenSource ST-Link tools replacement. Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers STLINKv1 and STLINKv2 are supported. @@ -33,8 +31,6 @@ Description: OpenSource ST-Link tools replacement. Package: stlink-tools Architecture: any Depends: libstlink1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} -Breaks: libstlink -Replaces: libstlink Description: OpenSource ST-Link tools replacement. Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers STLINKv1 and STLINKv2 are supported. From ef9d527eb74231d1818ade3495f003b85bec5325 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Fri, 16 Mar 2018 16:56:19 +0000 Subject: [PATCH 0603/1435] Update changelog for 1.5.0+ds-1 release --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 3439e586c..798093c9e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -stlink (1.5.0+ds-1) UNRELEASED; urgency=medium +stlink (1.5.0+ds-1) unstable; urgency=medium * Upload to unstable. (Closes: #869421) - -- Luca Boccassi Tue, 13 Mar 2018 00:26:52 +0000 + -- Luca Boccassi Fri, 16 Mar 2018 16:56:17 +0000 stlink (1.5.0) unstable; urgency=medium From 334fde7648402ffc7c869a9bebe606826a323506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Boudinet?= Date: Mon, 26 Mar 2018 13:11:23 +0200 Subject: [PATCH 0604/1435] gui: Adding button to export stm32 flash memory to a file (#691) --- src/tools/gui/stlink-gui.c | 53 +++++++++++++++++++++++++++++++++++++ src/tools/gui/stlink-gui.h | 2 ++ src/tools/gui/stlink-gui.ui | 14 ++++++++++ 3 files changed, 69 insertions(+) diff --git a/src/tools/gui/stlink-gui.c b/src/tools/gui/stlink-gui.c index 34afb2c51..2be97ef10 100644 --- a/src/tools/gui/stlink-gui.c +++ b/src/tools/gui/stlink-gui.c @@ -92,6 +92,8 @@ stlink_gui_set_sensitivity (STlinkGUI *gui, gboolean sensitivity) if (sensitivity && gui->sl && gui->filename) gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), sensitivity); + + gtk_widget_set_sensitive (GTK_WIDGET (gui->export_button), sensitivity && (gui->sl != NULL)); } static void @@ -575,6 +577,7 @@ static void stlink_gui_set_disconnected (STlinkGUI *gui) gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), FALSE); gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->export_button), FALSE); gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), FALSE); gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), TRUE); } @@ -712,6 +715,51 @@ flash_button_cb (GtkWidget *widget, gpointer data) } } +int export_to_file(const char*filename, const struct mem_t flash_mem) +{ + printf("%s\n", filename); + FILE * f=fopen(filename, "w"); + if(f==NULL) + return -1; + for(gsize i=0;iwindow, + GTK_FILE_CHOOSER_ACTION_SAVE, + "_Cancel", + GTK_RESPONSE_CANCEL, + "_Open", + GTK_RESPONSE_ACCEPT, + NULL); + GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog); + gtk_file_chooser_set_do_overwrite_confirmation (chooser, TRUE); + gint res = gtk_dialog_run (GTK_DIALOG (dialog)); + if (res == GTK_RESPONSE_ACCEPT) + { + char *filename; + + filename = gtk_file_chooser_get_filename (chooser); + if(export_to_file (filename, gui->flash_mem)!=0) + stlink_gui_set_info_error_message(gui, "Failed to export flash"); + else + stlink_gui_set_info_error_message(gui, "Export successful"); + g_free (filename); + } + + gtk_widget_destroy (dialog); +} + static gboolean progress_pulse_timeout (STlinkGUI *gui) { if (gui->progress.activity_mode) { @@ -857,6 +905,11 @@ stlink_gui_build_ui (STlinkGUI *gui) { g_signal_connect (G_OBJECT (gui->flash_button), "clicked", G_CALLBACK (flash_button_cb), gui); + gui->export_button = + GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "export_button")); + g_signal_connect (G_OBJECT (gui->export_button), "clicked", + G_CALLBACK (export_button_cb), gui); + gui->devmem_treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "devmem_treeview")); mem_view_init_headers (gui->devmem_treeview); diff --git a/src/tools/gui/stlink-gui.h b/src/tools/gui/stlink-gui.h index 0c90648a4..30c503fd3 100644 --- a/src/tools/gui/stlink-gui.h +++ b/src/tools/gui/stlink-gui.h @@ -64,6 +64,7 @@ struct _STlinkGUI GtkToolButton *connect_button; GtkToolButton *disconnect_button; GtkToolButton *flash_button; + GtkToolButton *export_button; GtkToolButton *open_button; /* flash dialog */ @@ -89,5 +90,6 @@ struct _STlinkGUIClass }; GType stlink_gui_get_type (void); +int export_to_file(const char*filename, const struct mem_t flash_mem); #endif diff --git a/src/tools/gui/stlink-gui.ui b/src/tools/gui/stlink-gui.ui index 193925ce1..aa0051b07 100644 --- a/src/tools/gui/stlink-gui.ui +++ b/src/tools/gui/stlink-gui.ui @@ -173,6 +173,20 @@ True + + + True + False + Export device memory + __glade_unnamed_9 + True + gtk-save + + + False + True + + True From 389fda244385a60fe26aac9922750b66d88add06 Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Wed, 28 Mar 2018 10:49:14 +0300 Subject: [PATCH 0605/1435] Update libusb to v1.0.22 (#695) * Will not download libusb if it found. * Checking CMAKE_LIBRARY_PATH before setting as STLINK_LIBRARY_PATH. --- CMakeLists.txt | 17 +++++++- cmake/modules/FindLibUSB.cmake | 77 +++++++++++++++++++++++----------- 2 files changed, 67 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ed84bd3e..d844183d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,17 @@ set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics Stlink To set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "Udev rules directory") set(STLINK_MODPROBED_DIR "/etc/modprobe.d" CACHE PATH "modprobe.d directory") set(LIB_INSTALL_DIR "lib" CACHE PATH "Main library directory") -set(STLINK_LIBRARY_PATH "${LIB_INSTALL_DIR}/${CMAKE_LIBRARY_PATH}" CACHE PATH "Target lib directory") + +if(IS_DIRECTORY CMAKE_LIBRARY_PATH) +else() + set(CMAKE_LIBRARY_PATH "lib") +endif() + +if (WIN32) + set(STLINK_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} CACHE PATH "Target lib directory") +else() + set(STLINK_LIBRARY_PATH "${LIB_INSTALL_DIR}/${CMAKE_LIBRARY_PATH}" CACHE PATH "Target lib directory") +endif(WIN32) option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) @@ -16,7 +26,9 @@ endif () set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") include(cmake/Version.cmake) -include(cmake/CFlags.cmake) +if(NOT MSVC) + include(cmake/CFlags.cmake) +endif() ### # Dependencies @@ -120,6 +132,7 @@ else() target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY}) endif() + install(TARGETS ${STLINK_LIB_SHARED} DESTINATION ${STLINK_LIBRARY_PATH} ) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index 844f3dc54..e9a5944f6 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -6,27 +6,6 @@ # LIBUSB_LIBRARY - The libraries needed to use libusb # LIBUSB_DEFINITIONS - Compiler switches required for using libusb -if(WIN32 OR CMAKE_VS_PLATFORM_NAME OR MINGW OR MSYS) - find_package(7Zip REQUIRED) - - set(LIBUSB_WIN_VERSION 1.0.21) - set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) - set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) - set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3thparty/libusb-${LIBUSB_WIN_VERSION}) - - if(EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) - message(STATUS "libusb archive already in build folder") - else() - message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") - file(DOWNLOAD - https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download - ${LIBUSB_WIN_ARCHIVE_PATH} - ) - endif() - file(MAKE_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) - execute_process(COMMAND ${ZIP_EXECUTABLE} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER}) -endif() - # FreeBSD if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h @@ -39,7 +18,6 @@ else () /usr /usr/local /opt - ${LIBUSB_WIN_OUTPUT_FOLDER}/include PATH_SUFFIXES libusb-1.0 ) endif() @@ -48,7 +26,7 @@ if (APPLE) set(LIBUSB_NAME libusb-1.0.a) elseif(MSYS OR MINGW) set(LIBUSB_NAME usb-1.0) -elseif(WIN32 OR CMAKE_VS_PLATFORM_NAME) +elseif(MSVC) set(LIBUSB_NAME libusb-1.0.lib) elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") set(LIBUSB_NAME usb) @@ -64,10 +42,10 @@ if (MSYS OR MINGW) find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static) endif () -elseif(CMAKE_VS_PLATFORM_NAME) +elseif(MSVC) if (CMAKE_SIZEOF_VOID_P EQUAL 8) find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll) + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll) else () find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll) @@ -84,3 +62,52 @@ include(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) + +if(NOT LIBUSB_FOUND) + if(WIN32 OR MSVC OR MINGW OR MSYS) + find_package(7Zip REQUIRED) + + set(LIBUSB_WIN_VERSION 1.0.22) + set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) + set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) + set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3thparty/libusb-${LIBUSB_WIN_VERSION}) + + if(EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) + message(STATUS "libusb archive already in build folder") + else() + message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") + file(DOWNLOAD + https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download + ${LIBUSB_WIN_ARCHIVE_PATH} + ) + endif() + file(MAKE_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) + execute_process(COMMAND ${ZIP_EXECUTABLE} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER}) + + FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/include + PATH_SUFFIXES libusb-1.0 + ) + + if (MSYS OR MINGW) + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/static) + else () + find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static) + endif () + elseif(MSVC) + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll) + else () + find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll) + endif () + endif () + FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + endif() +else() + message(STATUS "found USB") +endif() From 2ee6edc9ae0f3d16a43b8609e4565a30dd94d0c3 Mon Sep 17 00:00:00 2001 From: Vasiliy Glazov Date: Wed, 28 Mar 2018 10:54:40 +0300 Subject: [PATCH 0606/1435] Add desktop file for linux gtk GUI application (#688) * Add desktop file for linux * installing desktop file to /usr/../share/applications * Move desktop file to gui subdirectory. --- CMakeLists.txt | 2 ++ src/tools/gui/stlink.desktop | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 src/tools/gui/stlink.desktop diff --git a/CMakeLists.txt b/CMakeLists.txt index d844183d6..c4f4e217c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -194,6 +194,8 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux") DESTINATION ${STLINK_MODPROBED_DIR}/) install(FILES ${RULES_FILES} DESTINATION ${STLINK_UDEV_RULES_DIR}/) + #desktop file for linux launcher + install(FILES src/tools/gui/stlink.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) endif() add_subdirectory(src/gdbserver) diff --git a/src/tools/gui/stlink.desktop b/src/tools/gui/stlink.desktop new file mode 100644 index 000000000..54cb40349 --- /dev/null +++ b/src/tools/gui/stlink.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=stlink +GenericName=Stlink Tools +Comment=STM32 discovery line Linux programmer +Exec=stlink-gui +Icon=stlink-gui +Terminal=false +Type=Application +Categories=Development;Electronics; From 7ec1fb78baaa3d4bd7b36cc042248e24d5f481fe Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Wed, 28 Mar 2018 11:03:38 +0300 Subject: [PATCH 0607/1435] remove exit() from lib. fix #634 (#696) * remove exit() from lib. fix #634 * remove the UFATAL loglevel completely. --- include/stlink/logging.h | 11 ++++------- src/logging.c | 6 ------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/include/stlink/logging.h b/include/stlink/logging.h index a6632a730..16ed948a4 100644 --- a/include/stlink/logging.h +++ b/include/stlink/logging.h @@ -10,11 +10,10 @@ extern "C" { #endif enum ugly_loglevel { - UDEBUG = 90, - UINFO = 50, - UWARN = 30, - UERROR = 20, - UFATAL = 10 + UDEBUG = 90, + UINFO = 50, + UWARN = 30, + UERROR = 20 }; int ugly_init(int maximum_threshold); @@ -33,8 +32,6 @@ int ugly_log(int level, const char *tag, const char *format, ...); #define WLOG(...) WLOG_HELPER(__VA_ARGS__, "") #define ELOG_HELPER(format, ...) ugly_log(UERROR, UGLY_LOG_FILE, format, __VA_ARGS__) #define ELOG(...) ELOG_HELPER(__VA_ARGS__, "") -#define fatal_helper(format, ...) ugly_log(UFATAL, UGLY_LOG_FILE, format, __VA_ARGS__) -#define fatal(...) fatal_helper(__VA_ARGS__, "") #ifdef __cplusplus } diff --git a/src/logging.c b/src/logging.c index 1f51900b5..b5e423a3a 100644 --- a/src/logging.c +++ b/src/logging.c @@ -41,12 +41,6 @@ int ugly_log(int level, const char *tag, const char *format, ...) { case UERROR: fprintf(stderr, "ERROR %s: ", tag); break; - case UFATAL: - fprintf(stderr, "FATAL %s: ", tag); - vfprintf(stderr, format, args); - exit(EXIT_FAILURE); - // NEVER GETS HERE!!! - break; default: fprintf(stderr, "%d %s: ", level, tag); break; From d9d17f4cfe274eadec8b5f537bcfcdbcbd44fbb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Boudinet?= Date: Wed, 28 Mar 2018 15:04:20 +0200 Subject: [PATCH 0608/1435] Icons for stlink gui (#697) * Adding icon for ui * renaming icons from stlinkgui to stlink-gui * moving icons from art to src/tools/gui/art --- CMakeLists.txt | 1 + src/tools/gui/art/stlink-gui_48.png | Bin 0 -> 2704 bytes src/tools/gui/art/stlink-gui_icon.svg | 126 ++++++++++++++++++++++++++ src/tools/gui/stlink-gui.ui | 1 + 4 files changed, 128 insertions(+) create mode 100644 src/tools/gui/art/stlink-gui_48.png create mode 100644 src/tools/gui/art/stlink-gui_icon.svg diff --git a/CMakeLists.txt b/CMakeLists.txt index c4f4e217c..a7e88b4a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -196,6 +196,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux") DESTINATION ${STLINK_UDEV_RULES_DIR}/) #desktop file for linux launcher install(FILES src/tools/gui/stlink.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) + install(FILES src/tools/gui/art/stlink-gui_48.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps RENAME stlink-gui.png) endif() add_subdirectory(src/gdbserver) diff --git a/src/tools/gui/art/stlink-gui_48.png b/src/tools/gui/art/stlink-gui_48.png new file mode 100644 index 0000000000000000000000000000000000000000..0428ffdd48abb16317afab232c3b357723149ab7 GIT binary patch literal 2704 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 + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + ST + link + + diff --git a/src/tools/gui/stlink-gui.ui b/src/tools/gui/stlink-gui.ui index aa0051b07..e954af300 100644 --- a/src/tools/gui/stlink-gui.ui +++ b/src/tools/gui/stlink-gui.ui @@ -107,6 +107,7 @@ STlink GUI 550 480 + stlink-gui True From 095ef918188352da7d81fb01c51ba40309b50830 Mon Sep 17 00:00:00 2001 From: Matt Mills Date: Thu, 29 Mar 2018 02:18:09 -0700 Subject: [PATCH 0609/1435] Add support for STM32L4R9 (#699) --- include/stlink/chipid.h | 3 ++- src/chipid.c | 14 +++++++++++++- src/flash_loader.c | 3 ++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 7cf5b4881..bf03703c7 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -67,7 +67,8 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F72XXX = 0x452, /* This ID is found on the NucleoF722ZE board */ STLINK_CHIPID_STM32_L011 = 0x457, STLINK_CHIPID_STM32_F410 = 0x458, - STLINK_CHIPID_STM32_F413 = 0x463 + STLINK_CHIPID_STM32_F413 = 0x463, + STLINK_CHIPID_STM32_L4R9 = 0x470 // taken from the STM32L4R9I-DISCO board }; /** diff --git a/src/chipid.c b/src/chipid.c index 7cf83218d..705245f60 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -432,7 +432,7 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L4, .description = "L4 device", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1671) + .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) .flash_pagesize = 0x800, // 2K (sec 3.2, page 78; also appears in sec 3.3.1 and tables 4-6 on pages 79-81) // SRAM1 is "up to" 96k in the standard Cortex-M memory map; // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for @@ -441,6 +441,18 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) .bootrom_size = 0x7000 // 28k (per bank), same source as base }, + { + // STM32L4R9 (maybe others in the L4Rx series too) + // From DM00310109.pdf + .chip_id = STLINK_CHIPID_STM32_L4R9, + .description = "L4R9 device", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 52.2, page 2049) + .flash_pagesize = 0x1000, // 4k, section 3.3, pg 97 + .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 + .bootrom_base = 0x1fff0000, // 3.3.1, pg 99 + .bootrom_size = 0x7000 // 28k (per bank), same source as base (pg 99) + }, { // STLINK_CHIPID_STM32_L43X // From RM0392. diff --git a/src/flash_loader.c b/src/flash_loader.c index a9eafcda3..ed96144a6 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -306,7 +306,8 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* } else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || (sl->chip_id == STLINK_CHIPID_STM32_L43X) || (sl->chip_id == STLINK_CHIPID_STM32_L46X) || - (sl->chip_id == STLINK_CHIPID_STM32_L496X)) + (sl->chip_id == STLINK_CHIPID_STM32_L4R9) || + (sl->chip_id == STLINK_CHIPID_STM32_L496X)) { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); From aaf8e92075811e6b78cd7f68b636c642f27749bf Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Sun, 1 Apr 2018 20:16:49 +0300 Subject: [PATCH 0610/1435] Fix libusb function deprecation used for stlinkv1 Fixes #703 --- src/sg.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sg.c b/src/sg.c index 541ef5550..90a144184 100644 --- a/src/sg.c +++ b/src/sg.c @@ -944,6 +944,10 @@ static stlink_t* stlink_open(const int verbose) { struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg)); if (sl == NULL || slsg == NULL) { WLOG("Couldn't malloc stlink and stlink_sg structures out of memory!\n"); + if(sl != NULL) + free(sl); + if(slsg != NULL) + free(slsg); return NULL; } @@ -954,7 +958,11 @@ static stlink_t* stlink_open(const int verbose) { return NULL; } +#if LIBUSBX_API_VERSION < 0x01000106 libusb_set_debug(slsg->libusb_ctx, 3); +#else + libusb_set_option(slsg->libusb_ctx, LIBUSB_OPTION_LOG_LEVEL, 3); +#endif slsg->usb_handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, STLINK_USB_VID_ST, STLINK_USB_PID_STLINK); if (slsg->usb_handle == NULL) { From d76e3c7c542a115760d9bc3395c9ca90395ba3ae Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 9 Apr 2018 20:25:14 +0200 Subject: [PATCH 0611/1435] rename STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX (#706) --- include/stlink/chipid.h | 2 +- src/chipid.c | 10 +++++----- src/flash_loader.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index bf03703c7..004fa2e80 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -68,7 +68,7 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_L011 = 0x457, STLINK_CHIPID_STM32_F410 = 0x458, STLINK_CHIPID_STM32_F413 = 0x463, - STLINK_CHIPID_STM32_L4R9 = 0x470 // taken from the STM32L4R9I-DISCO board + STLINK_CHIPID_STM32_L4RX = 0x470 // taken from the STM32L4R9I-DISCO board }; /** diff --git a/src/chipid.c b/src/chipid.c index 705245f60..6f93af112 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -10,8 +10,8 @@ static const struct stlink_chipid_params devices[] = { .flash_size_reg = 0x1ff0f442, // section 45.2 .flash_pagesize = 0x800, // No flash pages .sram_size = 0x80000, // "SRAM" byte size in hex from - .bootrom_base = 0x00200000, //! "System memory" starting address from - .bootrom_size = 0xEDC0 //! @todo "System memory" byte size in hex from + .bootrom_base = 0x00200000, //! "System memory" starting address from + .bootrom_size = 0xEDC0 //! @todo "System memory" byte size in hex from }, { //RM0385 and DS10916 document was used to find these paramaters @@ -442,10 +442,10 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000 // 28k (per bank), same source as base }, { - // STM32L4R9 (maybe others in the L4Rx series too) + // STM32L4RX // From DM00310109.pdf - .chip_id = STLINK_CHIPID_STM32_L4R9, - .description = "L4R9 device", + .chip_id = STLINK_CHIPID_STM32_L4RX, + .description = "L4Rx device", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 52.2, page 2049) .flash_pagesize = 0x1000, // 4k, section 3.3, pg 97 diff --git a/src/flash_loader.c b/src/flash_loader.c index ed96144a6..599b2459a 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -219,7 +219,7 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) return 0; } -static int loader_v_dependent_assignment(stlink_t *sl, +static int loader_v_dependent_assignment(stlink_t *sl, const uint8_t **loader_code, size_t *loader_size, const uint8_t *high_v_loader, size_t high_v_loader_size, const uint8_t *low_v_loader, size_t low_v_loader_size) @@ -236,7 +236,7 @@ static int loader_v_dependent_assignment(stlink_t *sl, if (voltage == -1) { retval = -1; printf("Failed to read Target voltage\n"); - } + } else { if (voltage > 2700) { *loader_code = high_v_loader; @@ -306,7 +306,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* } else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || (sl->chip_id == STLINK_CHIPID_STM32_L43X) || (sl->chip_id == STLINK_CHIPID_STM32_L46X) || - (sl->chip_id == STLINK_CHIPID_STM32_L4R9) || + (sl->chip_id == STLINK_CHIPID_STM32_L4RX) || (sl->chip_id == STLINK_CHIPID_STM32_L496X)) { loader_code = loader_code_stm32l4; From 88935336f8f810e3524a5bb9baee30ed07af6c2e Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Mon, 16 Apr 2018 21:54:03 +0300 Subject: [PATCH 0612/1435] fix #700 (#701) * first try to fix #700 Use CMAKE_INSTALL_PREFIX for install paths * check IS_DIRECTORY LIB_INSTALL_DIR * fix incorrect VAR usage in condition * changed debian/rules according to @bluca patch --- CMakeLists.txt | 18 +++++++++++------- debian/rules | 2 +- include/CMakeLists.txt | 4 ++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a7e88b4a6..1d1f6f72b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,18 +4,22 @@ project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics Stlink Tools") set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "Udev rules directory") set(STLINK_MODPROBED_DIR "/etc/modprobe.d" CACHE PATH "modprobe.d directory") -set(LIB_INSTALL_DIR "lib" CACHE PATH "Main library directory") -if(IS_DIRECTORY CMAKE_LIBRARY_PATH) +if( IS_DIRECTORY ${LIB_INSTALL_DIR}) + set(LIB_INSTALL_DIR ${LIB_INSTALL_DIR} CACHE PATH "Main library directory") + set(STLINK_LIBRARY_PATH "${LIB_INSTALL_DIR}") else() - set(CMAKE_LIBRARY_PATH "lib") + set(LIB_INSTALL_DIR "lib" CACHE PATH "Main library directory") + set(STLINK_LIBRARY_PATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}" ) endif() -if (WIN32) - set(STLINK_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} CACHE PATH "Target lib directory") +if( IS_DIRECTORY ${INCLUDE_INSTALL_DIR}) + set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_DIR} CACHE PATH "Main include directory") + set(STLINK_INCLUDE_PATH "${INCLUDE_INSTALL_DIR}" ) else() - set(STLINK_LIBRARY_PATH "${LIB_INSTALL_DIR}/${CMAKE_LIBRARY_PATH}" CACHE PATH "Target lib directory") -endif(WIN32) + set(INCLUDE_INSTALL_DIR "include" CACHE PATH "Main include directory") + set(STLINK_INCLUDE_PATH "${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_DIR}") +endif() option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) diff --git a/debian/rules b/debian/rules index c4e9e2afd..e228a7087 100755 --- a/debian/rules +++ b/debian/rules @@ -15,5 +15,5 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all override_dh_auto_configure: dh_auto_configure -- \ - -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) \ + -DLIB_INSTALL_DIR=/usr/lib/$(DEB_HOST_MULTIARCH) \ -DSTLINK_UDEV_RULES_DIR='/lib/udev/rules.d' diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 0b5a443c0..a0c649532 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -7,8 +7,8 @@ file(GLOB STLINK_HEADERS "${CMAKE_BINARY_DIR}/include/stlink/*.h" ) install(FILES ${CMAKE_SOURCE_DIR}/include/stlink.h - DESTINATION include/${CMAKE_LIBRARY_PATH} + DESTINATION ${STLINK_INCLUDE_PATH} ) install(FILES ${STLINK_HEADERS} - DESTINATION include/${CMAKE_LIBRARY_PATH}/stlink + DESTINATION ${STLINK_INCLUDE_PATH}/stlink ) From b1b2a2f0a8af583bc7152a33b39fbfaeafe94aef Mon Sep 17 00:00:00 2001 From: Vasiliy Glazov Date: Tue, 17 Apr 2018 11:30:31 +0300 Subject: [PATCH 0613/1435] Disable static library installation by default (#702) * Disable static library installation by default * Added parameter for not install static lib * Rename and move to top parameter for install static libs. --- CMakeLists.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d1f6f72b..54ddd3990 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics Stlink Tools") set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "Udev rules directory") set(STLINK_MODPROBED_DIR "/etc/modprobe.d" CACHE PATH "modprobe.d directory") +set(STLINK_STATIC_LIB ON CACHE BOOL "Install static lib") if( IS_DIRECTORY ${LIB_INSTALL_DIR}) set(LIB_INSTALL_DIR ${LIB_INSTALL_DIR} CACHE PATH "Main library directory") @@ -167,9 +168,11 @@ endif() set_target_properties(${STLINK_LIB_STATIC} PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) -install(TARGETS ${STLINK_LIB_STATIC} - ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH} -) +if (STLINK_STATIC_LIB) + install(TARGETS ${STLINK_LIB_STATIC} + ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH} + ) +endif() ### # Tools From 0af68c0801f8413d26e70564a4adccc3f4187eae Mon Sep 17 00:00:00 2001 From: joede Date: Sat, 5 May 2018 08:01:41 +0200 Subject: [PATCH 0614/1435] Add svg icon for .desktop file (#708) * add SVG icon and .desktop file to Debian package. Renamed icon and .desktop file to package name. --- CMakeLists.txt | 3 - debian/stlink-gui.install | 2 + src/tools/gui/CMakeLists.txt | 9 + src/tools/gui/art/export-icons.sh | 38 ++++ .../art/hicolor/128x128/apps/stlink-gui.png | Bin 0 -> 7123 bytes .../gui/art/hicolor/16x16/apps/stlink-gui.png | Bin 0 -> 781 bytes .../gui/art/hicolor/22x22/apps/stlink-gui.png | Bin 0 -> 1134 bytes .../gui/art/hicolor/24x24/apps/stlink-gui.png | Bin 0 -> 1253 bytes .../art/hicolor/256x256/apps/stlink-gui.png | Bin 0 -> 14568 bytes .../gui/art/hicolor/32x32/apps/stlink-gui.png | Bin 0 -> 1756 bytes .../gui/art/hicolor/48x48/apps/stlink-gui.png | Bin 0 -> 2707 bytes .../gui/art/hicolor/64x64/apps/stlink-gui.png | Bin 0 -> 3497 bytes src/tools/gui/art/stlink-gui.png | Bin 0 -> 1756 bytes src/tools/gui/art/stlink-gui.svg | 130 ++++++++++++ src/tools/gui/art/stlink-gui.xpm | 200 ++++++++++++++++++ src/tools/gui/art/stlink-gui_icon.svg | 126 ----------- .../{stlink.desktop => stlink-gui.desktop} | 0 17 files changed, 379 insertions(+), 129 deletions(-) create mode 100755 src/tools/gui/art/export-icons.sh create mode 100644 src/tools/gui/art/hicolor/128x128/apps/stlink-gui.png create mode 100644 src/tools/gui/art/hicolor/16x16/apps/stlink-gui.png create mode 100644 src/tools/gui/art/hicolor/22x22/apps/stlink-gui.png create mode 100644 src/tools/gui/art/hicolor/24x24/apps/stlink-gui.png create mode 100644 src/tools/gui/art/hicolor/256x256/apps/stlink-gui.png create mode 100644 src/tools/gui/art/hicolor/32x32/apps/stlink-gui.png create mode 100644 src/tools/gui/art/hicolor/48x48/apps/stlink-gui.png create mode 100644 src/tools/gui/art/hicolor/64x64/apps/stlink-gui.png create mode 100644 src/tools/gui/art/stlink-gui.png create mode 100644 src/tools/gui/art/stlink-gui.svg create mode 100644 src/tools/gui/art/stlink-gui.xpm delete mode 100644 src/tools/gui/art/stlink-gui_icon.svg rename src/tools/gui/{stlink.desktop => stlink-gui.desktop} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54ddd3990..395848b0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -201,9 +201,6 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux") DESTINATION ${STLINK_MODPROBED_DIR}/) install(FILES ${RULES_FILES} DESTINATION ${STLINK_UDEV_RULES_DIR}/) - #desktop file for linux launcher - install(FILES src/tools/gui/stlink.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) - install(FILES src/tools/gui/art/stlink-gui_48.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps RENAME stlink-gui.png) endif() add_subdirectory(src/gdbserver) diff --git a/debian/stlink-gui.install b/debian/stlink-gui.install index d18d2cec4..b419ac054 100644 --- a/debian/stlink-gui.install +++ b/debian/stlink-gui.install @@ -1,2 +1,4 @@ /usr/bin/stlink-gui* /usr/share/stlink/stlink-gui.ui +/usr/share/applications/stlink-gui.desktop +/usr/share/icons/hicolor/scalable/apps/stlink-gui.svg diff --git a/src/tools/gui/CMakeLists.txt b/src/tools/gui/CMakeLists.txt index 4ab9975da..ceb862c33 100644 --- a/src/tools/gui/CMakeLists.txt +++ b/src/tools/gui/CMakeLists.txt @@ -22,3 +22,12 @@ install(TARGETS stlink-gui RUNTIME DESTINATION bin) install(FILES stlink-gui.ui DESTINATION ${INSTALLED_UI_DIR}) +if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + # Install desktop entry + install(FILES stlink-gui.desktop + DESTINATION share/applications) + # Install icon + install(FILES art/stlink-gui.svg + DESTINATION share/icons/hicolor/scalable/apps) +endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + diff --git a/src/tools/gui/art/export-icons.sh b/src/tools/gui/art/export-icons.sh new file mode 100755 index 000000000..9d61719b9 --- /dev/null +++ b/src/tools/gui/art/export-icons.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# +# create the XPM icon and all resolutions below hicolor as PNG + +APPNAME="stlink-gui" +ORIGIN="stlink-gui_icon.svg" +OUTDIR="hicolor" + +## possible size options are --export-dpi / --export-width / --export-height +OPTS="-z --export-id-only" +ID="scalable-icon" +RESOLUTIONS="16 22 24 32 48 64 128 256" + + if ! [ -d $OUTDIR ]; then + echo "output directory missing. Create it..." + mkdir $OUTDIR + for RES in $RESOLUTIONS; do + mkdir -p $OUTDIR/${RES}x${RES}/apps + done + fi + + # create single app icon + inkscape $OPTS --export-width=32 --export-id=$ID --export-png=$APPNAME.png $ORIGIN + if [ $? != 0 ]; then exit 1; fi + convert $APPNAME.png $APPNAME.xpm + + # create all the resolutions + ALL="" + for RES in $RESOLUTIONS; do + inkscape $OPTS --export-width=$RES --export-id=$ID --export-png=$OUTDIR/${RES}x${RES}/apps/$APPNAME.png $ORIGIN + ALL="$ALL $OUTDIR/${RES}x${RES}/apps/$APPNAME.png" + done + + # this is for windows... + #echo "build Windows icon from $ALL" + #convert $ALL $APPNAME.ico + +exit 0 diff --git a/src/tools/gui/art/hicolor/128x128/apps/stlink-gui.png b/src/tools/gui/art/hicolor/128x128/apps/stlink-gui.png new file mode 100644 index 0000000000000000000000000000000000000000..c56988e305fcceb87ccdd7bb49fc48be31540a9f GIT binary patch literal 7123 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 C&&16D literal 0 HcmV?d00001 diff --git a/src/tools/gui/art/hicolor/16x16/apps/stlink-gui.png b/src/tools/gui/art/hicolor/16x16/apps/stlink-gui.png new file mode 100644 index 0000000000000000000000000000000000000000..00c7c9c61423f5c8a86b96bfbc92c0bed5a661e4 GIT binary patch literal 781 zcmV+o1M>WdP)m0F}lqCp}U z?aFo)MXN*?wUB~@7D+7vqjm)?0(U`JN^1UQ!lY#8Pfe+5Iyy7XjCbbFZE>#-)6NeL z=i}p?_j}KIU!kS7U3vdu2ml23mFv$`qwgR7%qOLdte9^!R4Ak;oALOA4BD5NcE)h= zcr=1eRGYN0f3ee((ukqI6A=JifE(w`oUAHfeAdn4st?1?5{kjZwiIH+<>uC|xHIfr!oKD7P9CSJJAt_%40F8n9 zAf2x!D9Ev3f8D~zj&d3-qo50@g*w93dMykp0}%nx$qa0jQG0)mk_!(Qm|Wo5y(=Vm zXTlA;M^D6?niLOB$-Q`@a&SpT{5ukkrDc4^1Ca~_?dM&9y&V{h$Wh6hE=eTYn!>{G zKU{nK7Jp*-9>AmLFPT}{gu=W?1|eAnpM&nT61safAvh1#LNM9Fg=sl-g;F8T0RcBe z#fFy{4EpH1lTWTVO@n2cru0S73z4(xAxh$6-*+m#kCd~(7N2pl@S(X`*QyFut5pOo^0kq$|%8S7mCUk6lWk5!*lVv0{ODOpGpHqZ$n7R_l?7*-k5XOI#2 zOI*;!baEaic78E#P9i1fCe`c2KiZFQ`)-Hw=3QUdDEr9uHP!qBZV=$6!rKJY00000 LNkvXXu0mjfG>TN4 literal 0 HcmV?d00001 diff --git a/src/tools/gui/art/hicolor/22x22/apps/stlink-gui.png b/src/tools/gui/art/hicolor/22x22/apps/stlink-gui.png new file mode 100644 index 0000000000000000000000000000000000000000..2afb2af23de884af7aa692f5817b8280e109f329 GIT binary patch literal 1134 zcmV-!1d;oRP)e?6ynSh-W1p;RC!xDGMkAaTNCMm9wq z`(UPvW?m+Vmj$zn#yKNn9~NUK#-K5hF--&$=LZQ9&6Wu=n2?nzwag39l>u>FN(FkL zrEvVvQd%xXe3R$oB+vW&p8xxQ-jk!KuWyhqUTOmX1?#VW%dN2JL2?nf+Vj+$ zDyOg@4*O$ zjxym9h}J2{Oo;-8j7Ny!nWOI`2m*r7P16@OIGs*jIDQ6|E*j623-tLQ1sW-r{E5?y zu_gO%I`}-RJ+-^7RJ~Ok%`yd_=0k;DbEGwQ+ zm}zWo;lTdAwBD9T-Iw3;+n|fy2@ON>#et%w2p^e|E0v1C(u_<028k>_X7sRd;3%xYM8$UY7~w~zaCx2{$k z`ar@4A?xFDNq&fmgXtlPrB=o#-3W;(++#A(KkBB-ToQnUmLE%ZBj!zNI)Cn9p&&OX zT(Jy}QF{6M<0_J(L|F84=;<;}lt0Oqc#*=bcX8pPlcWu{g^nyElVd&4SI1vr%Hv_o zQiv#u5jQgODk%u58X9-gpw6fEQa1*Jfn<#w0&mO8py5OX2P)sCHLny|r(5Wr zF#D%-2sz%!{GuG_zcfrhl4enB)R^K7h(0M)zsibGt1!h&r;!zMqzJ$^ILw~6PV?cL zM|ile9bs-Justt-+dI~4J^V4?m{4u`DYN4{@FM_4fR3 zqda3X%F-o0CCXlUU7AdAIh;-g<`RFD@i8F#(6e zL2GLppY7Pg$Bkh`bB^tAzlsnHkdn zC@9{>(a=1Q1h8LXYt26X2~DOaDwQ`HdcE=&Pcie(KQNh0lx+W=pAG3C0TUN^Pr)BR z0Aw9q-F5&LJep2L)tA_MwVV%`M5plqFPH>K2Jh+U7)gt))q3+T;bqYWAdUcpMpC)Y ziq+c0D=*Ba;oB09fAc0E%@1eBl`^Ek3qAwG>`#GjqCbG>y*#O($9>P0a&OKemb|`} zj*d?9pL~q{UvJ_LM~zo*m<2!MLJ)wfBESLe9&C}bsUe5;Cnhsv;WpNlY(>UOAdUF=WKXl|c{aZXiXfA`hi#-s3qeed%eMo0~b= z)WW!=nV8MD({ko4)=sCd{enesjT-m>bYX1Sv!A*n%NZN3Coz63zx-~ccta__wJZD? zKS!-BNxZkEobo+&*xTD7<$4hafF_id&>UI>pxXuQmp~H-`nw=8h=&PN*(FW&e$UMC z0S7dJ43H$BCSIwasY}m=i0Mq}`kYXmmP3YFUOOQWIet11LRfV9Pox_FG3 z?ne409jnQ)yj6XgS@{KwPf1}yq((Ihu44zNTwBEAHS5@UitcDvC@g6h4ZbTd`eHT*5Wf?<%rr4~5B{<4#&@!+CmY$$q_?9NkY`}=^QF8a&XPWJOf^hu*YqoHE& zUi5k$81AOu9YOBWRW!BQAOQySQ9QA%n5H%xOoV282iZ%Da6}t9Y@R`8!3yHW#1M7X z%D^}yLSbQ{vZlNm;#1XIQ3yD1^zLLMh4;@w&dSO{6xEsfPbkTP#bV)KHydbU=R#&% P00000NkvXXu0mjf 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 DCPrX> literal 0 HcmV?d00001 diff --git a/src/tools/gui/art/hicolor/32x32/apps/stlink-gui.png b/src/tools/gui/art/hicolor/32x32/apps/stlink-gui.png new file mode 100644 index 0000000000000000000000000000000000000000..72fac7bf4e0eb8bbc306ef13ea4607fd3386a503 GIT binary patch literal 1756 zcmV<21|#{2P)9Kkw~t*k!YTfST!qn*hFqfM>K{f)n1;En5|g`j$kAv|0Xzc&9l4u81l67eNRku)01P_Ucx#!iujI%FZ(_At zLs9$vT)A?ErK>hlKW-W(Zyh(P%hBm{VsaJrb1k%sM2D_L1tXmt9(d;#j~>(OepgJzPFl8B9s1>n}LTOj~^-o7E0LjVXt zp|^p&+-wX615T%toP{Mc8W*8x$HCd##LIug?0tn^j}In6r#XvxtKS%;*z5Q=`(J&Y zWy_WV@ObV*G*jjbg+P-Q1;8B!26{=EFdhJh!$BWrl=x|&(SZm~(T-CEcv?XOcgkGc z;@lylx<7=hI3{H>O}3K2n2Mo!!vKgOZ?UP={Ou|LQ>RX4_vUA?d-syw_&SL#N1^K) z2r`(GLybi+92(l_^FjgWEnK?Z!KIqN0I*_NF<+iP#m$=2oZbHduh<=A)NMu8eLdWu zitw}(h`jo!07Pg>dX7b_wz9nBc`jc397&Q8MG>3L#v4EX370QcFr&8;e9myAk@EhY z7!U!Sk=qm3al9pm#T!qM`S@aH<$jyJ2Mz&XG#Yv9wNf5vyKwgq2oc6dfDPM(cpYF) z2U7}N<|TBgpg|a5(>q7Vn3&4^!UC*TE3y5pblnFALILm|Vw zM_TFx;!H-GZ?{rc-$<+GAv$LL5JVx|s9M91U*E~L{YL=s2%38YAZqZX=F%kQ(j)@- zz}X4yUWl0m(=E{rioiE!Q)itWIq&ZVAm;XGAc9|K!9T%{*!?f`y*ELCeq#!fF+IAm z5e~(#ZlG_k3+P&skuo0}y$%@kIyM(2Q1P<@9_%^?B8=<)Grugc^5MpLB)6Tt`-+D3 z_~sgR7EY#OO#u`BQ8l(gG;`)m^7Hc$)!IR6cXv0Pot?u%G{!D~-JVT;ejW%B_DaM( zaHj=Rr%j#0%e%`1-zn1rO6}L7r!DZF_#mRsMS}AheR?zQ$##f~kDLu6AbH_h_29T7 z%b^U6R7g@<*!5Bo$F_W*H2*CSA+4#3BP%Aer!aw-Q$J#TMmOiTzexEDg*^JFebCh$ zxfV!XQcvyR!0a@3K5Qnj>OBNe9323_f(7$gvgA7(2PpZhv zdxB4o9wg;*dDvf3@_9)8=og&Wv4wfx%H{3jE6gy~kE`j8p6>7+k0gRfrN4sqrPSrEzDC=B%U^dReEg4Iuj$LEU*e)E>C zh@!~eU2l?9c@U5zr{TRY5F!&J$cE`&zS+QnbW%xtoU`nphgREiQw;n{+@tLZvc}8JY66KFBdUJFvh`v z7u><~p;`@zXtJP`-{5~`%e-Ivu`)~=3 yHqYC literal 0 HcmV?d00001 diff --git a/src/tools/gui/art/hicolor/48x48/apps/stlink-gui.png b/src/tools/gui/art/hicolor/48x48/apps/stlink-gui.png new file mode 100644 index 0000000000000000000000000000000000000000..8f9f9d61e89f910584e52f97a8dc1374a09092f6 GIT binary patch literal 2707 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 literal 0 HcmV?d00001 diff --git a/src/tools/gui/art/stlink-gui.png b/src/tools/gui/art/stlink-gui.png new file mode 100644 index 0000000000000000000000000000000000000000..72fac7bf4e0eb8bbc306ef13ea4607fd3386a503 GIT binary patch literal 1756 zcmV<21|#{2P)9Kkw~t*k!YTfST!qn*hFqfM>K{f)n1;En5|g`j$kAv|0Xzc&9l4u81l67eNRku)01P_Ucx#!iujI%FZ(_At zLs9$vT)A?ErK>hlKW-W(Zyh(P%hBm{VsaJrb1k%sM2D_L1tXmt9(d;#j~>(OepgJzPFl8B9s1>n}LTOj~^-o7E0LjVXt zp|^p&+-wX615T%toP{Mc8W*8x$HCd##LIug?0tn^j}In6r#XvxtKS%;*z5Q=`(J&Y zWy_WV@ObV*G*jjbg+P-Q1;8B!26{=EFdhJh!$BWrl=x|&(SZm~(T-CEcv?XOcgkGc z;@lylx<7=hI3{H>O}3K2n2Mo!!vKgOZ?UP={Ou|LQ>RX4_vUA?d-syw_&SL#N1^K) z2r`(GLybi+92(l_^FjgWEnK?Z!KIqN0I*_NF<+iP#m$=2oZbHduh<=A)NMu8eLdWu zitw}(h`jo!07Pg>dX7b_wz9nBc`jc397&Q8MG>3L#v4EX370QcFr&8;e9myAk@EhY z7!U!Sk=qm3al9pm#T!qM`S@aH<$jyJ2Mz&XG#Yv9wNf5vyKwgq2oc6dfDPM(cpYF) z2U7}N<|TBgpg|a5(>q7Vn3&4^!UC*TE3y5pblnFALILm|Vw zM_TFx;!H-GZ?{rc-$<+GAv$LL5JVx|s9M91U*E~L{YL=s2%38YAZqZX=F%kQ(j)@- zz}X4yUWl0m(=E{rioiE!Q)itWIq&ZVAm;XGAc9|K!9T%{*!?f`y*ELCeq#!fF+IAm z5e~(#ZlG_k3+P&skuo0}y$%@kIyM(2Q1P<@9_%^?B8=<)Grugc^5MpLB)6Tt`-+D3 z_~sgR7EY#OO#u`BQ8l(gG;`)m^7Hc$)!IR6cXv0Pot?u%G{!D~-JVT;ejW%B_DaM( zaHj=Rr%j#0%e%`1-zn1rO6}L7r!DZF_#mRsMS}AheR?zQ$##f~kDLu6AbH_h_29T7 z%b^U6R7g@<*!5Bo$F_W*H2*CSA+4#3BP%Aer!aw-Q$J#TMmOiTzexEDg*^JFebCh$ zxfV!XQcvyR!0a@3K5Qnj>OBNe9323_f(7$gvgA7(2PpZhv zdxB4o9wg;*dDvf3@_9)8=og&Wv4wfx%H{3jE6gy~kE`j8p6>7+k0gRfrN4sqrPSrEzDC=B%U^dReEg4Iuj$LEU*e)E>C zh@!~eU2l?9c@U5zr{TRY5F!&J$cE`&zS+QnbW%xtoU`nphgREiQw;n{+@tLZvc}8JY66KFBdUJFvh`v z7u><~p;`@zXtJP`-{5~`%e-Ivu`)~=3 yHqYC literal 0 HcmV?d00001 diff --git a/src/tools/gui/art/stlink-gui.svg b/src/tools/gui/art/stlink-gui.svg new file mode 100644 index 000000000..30729ae03 --- /dev/null +++ b/src/tools/gui/art/stlink-gui.svg @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + ST + link + + + diff --git a/src/tools/gui/art/stlink-gui.xpm b/src/tools/gui/art/stlink-gui.xpm new file mode 100644 index 000000000..b3e49b882 --- /dev/null +++ b/src/tools/gui/art/stlink-gui.xpm @@ -0,0 +1,200 @@ +/* XPM */ +static char *stlink_gui[] = { +/* columns rows colors chars-per-pixel */ +"32 32 162 2 ", +" c #010303", +". c #030608", +"X c #050A0E", +"o c #0C0D0F", +"O c #0A1016", +"+ c #141C24", +"@ c #162226", +"# c #172837", +"$ c #1F383F", +"% c #222B2E", +"& c #25313A", +"* c #002341", +"= c #102841", +"- c #1E2C43", +"; c #1C2E4B", +": c #1B3A45", +"> c #1C3349", +", c #153848", +"< c #16394D", +"1 c #1D3A4B", +"2 c #172D55", +"3 c #1C3C52", +"4 c #193A55", +"5 c #232E42", +"6 c #213145", +"7 c #2C3B46", +"8 c #24364B", +"9 c #24394B", +"0 c #2E3A4C", +"q c #333D4A", +"w c #0E3562", +"e c #003D6F", +"r c #133666", +"t c #163D65", +"y c #183B61", +"u c #12376C", +"i c #0C3A76", +"p c #17434D", +"a c #1D4049", +"s c #184455", +"d c #184851", +"f c #27404C", +"g c #2D444D", +"h c #34434F", +"j c #3C4649", +"k c #384250", +"l c #0F4463", +"z c #164265", +"x c #184261", +"c c #144964", +"v c #184A62", +"b c #144E69", +"n c #135369", +"m c #0A4177", +"M c #00417F", +"N c #0A5277", +"B c #424D55", +"V c #444E5A", +"C c #4A5059", +"Z c #4D5A5E", +"A c #4E5562", +"S c #515B63", +"D c #565E69", +"F c #58646B", +"G c #5D686F", +"H c #5D6670", +"J c #5F6D72", +"K c #656C77", +"L c #676C78", +"P c #6B737C", +"I c #063C84", +"U c #01378C", +"Y c #033295", +"T c #013E98", +"R c #0034A0", +"E c #0036A9", +"W c #003CAF", +"Q c #003CBF", +"! c #004581", +"~ c #074587", +"^ c #004C81", +"/ c #005286", +"( c #005C85", +") c #004297", +"_ c #044D91", +"` c #034B99", +"' c #025A90", +"] c #005898", +"[ c #006382", +"{ c #076988", +"} c #07758F", +"| c #02689C", +" . c #0042A3", +".. c #004CA8", +"X. c #0051A0", +"o. c #0055AB", +"O. c #005BAF", +"+. c #0045B4", +"@. c #0049B9", +"#. c #0052B6", +"$. c #0054BD", +"%. c #005ABC", +"&. c #0060A6", +"*. c #0069A6", +"=. c #0065AC", +"-. c #006FA9", +";. c #0072A6", +":. c #007DA6", +">. c #0073AF", +",. c #006EB3", +"<. c #0065B9", +"1. c #006ABF", +"2. c #0076B0", +"3. c #007EB2", +"4. c #757B83", +"5. c #0036C0", +"6. c #003AC0", +"7. c #0044C0", +"8. c #004CC0", +"9. c #0053C0", +"0. c #005BC0", +"q. c #0064C0", +"w. c #006CC0", +"e. c #0074C0", +"r. c #007CC0", +"t. c #0085A6", +"y. c #0088A6", +"u. c #0082AA", +"i. c #0093A6", +"p. c #0093AE", +"a. c #0087B8", +"s. c #008BB8", +"d. c #0090B1", +"f. c #009EBE", +"g. c #00A3BE", +"h. c #0083C0", +"j. c #008BC0", +"k. c #0093C0", +"l. c #00A2C0", +"z. c #84868A", +"x. c #858B90", +"c. c #8C8E92", +"v. c #919192", +"b. c #94989E", +"n. c #9B9C9C", +"m. c #9D9EA1", +"M. c #9FA1A3", +"N. c #A1A1A1", +"B. c #A6ABAD", +"V. c #A9A9A9", +"C. c #ADB2B4", +"Z. c #B7B7B8", +"A. c #BBBBBC", +"S. c #C2C2C3", +"D. c #C6C7C8", +"F. c #CBCCCC", +"G. c #D2D2D2", +"H. c #DBDBDB", +"J. c #E1E1E1", +"K. c #ECECEC", +"L. c #F4F4F4", +"P. c #FEFEFE", +/* pixels */ +"G.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.J.", +"N. X . X X X X X X X X . X X X X X X X X X X X X X X X X X N.", +"N.. Q 5.5.E 2 ; 0 0 0 > u T 8.i ; > ; ; > > > > - > 1 , r.1.. M.", +"N.. Q 5.Y q G.P.P.P.P.L.F.5 9.; L.P.P.P.P.P.P.P.P.P.P.h e.1.. N.", +"N.. 6.6.5 L.P.J.c.4.m.F.P.8 $.8 H.H.H.J.L.P.P.H.H.H.J.7 e.e.. N.", +"N.. 6.R L P.K.5 Y T U r 5 # 9.~ y y y = V.P.P.+ z x x z r.r.. N.", +"N.. 6.Y z.P.H.2 @.8.9.9.9...0.0.%.0.q.! V.P.P.1 e.e.e.e.r.r.. N.", +"M.. 6.W A P.P.V.k 6 r ) $.9.0.0.q.q.q.! V.P.P.1 e.e.e.r.r.3.. N.", +"M.. Q @.; F.P.P.P.P.F.4.6 ` %.0.q.q.w.! V.P.P.: e.e.r.r.r.h.. N.", +"M.. 7.7.+.2 D S.P.P.P.P.L.q O.q.q.q.q.! V.P.P.> e.r.r.r.r.h.. N.", +"N.. 7.8.8.8. .u > q m.P.P.S.m q.w.q.w.^ V.P.P.1 r.r.r.r.h.h.. N.", +"N.. 7.+. .8.9.9.9.$.w Z.P.K.3 q.w.w.w.^ V.P.P.1 r.r.r.h.h.a.. N.", +"N.. 8. .+ 5 U #.0.0.w Z.P.J.4 w.w.w.w.^ V.P.P.1 r.h.h.h.h.h.. N.", +"M.. 8. .L K.c.V q k b.P.P.x._ w.w.w.e.^ V.P.P.1 r.h.h.h.j.j.. N.", +"M.. @. .C K.P.P.P.P.P.P.A.> 1.w.w.e.e.^ V.P.P.1 h.h.h.h.j.j.. N.", +"N.. 8.$.I 4 q B H P S 7 t <.1.w.e.e.e./ & h h < h.h.j.j.j.j.. N.", +"N.. 9.9.9.0.%.%.o.X.O.q.q.w.w.e.e.e.e.r.r.r.h.h.h.h.j.j.j.k.. N.", +"N.. i i ~ 0.` i m ` w.q.w.w.e.w.e.e.r.r.r.| N N { j.j.j.k.k.. N.", +"N.o z.A.6 0.t N.Z.1 w.w.w.e.e.e.e.r.r.r.r.b n.A.1 j.j.j.k.k.. N.", +"N.o A.P.8 q.t v.V.1 w.w.w.e.e.3.r.r.r.r.h.c G.P.1 j.k.k.k.k.. N.", +"N.o A.P.9 q.M * * e w.] ^ ^ &.' z N >.h.h.b G.P.1 k.f.N [ N X M.", +"N.o A.P.8 q.t v.V.> w.3 N.v.O 4.G.A.7 ;.h.b G.P.1 s.: m.v.@ . M.", +"N.o A.P.8 q.z G.L.4 w.3 L.H.z.F x.P.J.s j.n G.P.$ : D.H.& i.. M.", +"N.o A.P.9 q.z H.P.1 e.3 L.P.7 -.l S.P.f j.b G.P.O D.G.: p.g.. M.", +"N.o A.P.9 w.z H.P.1 e.3 L.K.s r.( V.P.g s.n G.P.A.L.@ p.f.l.. N.", +"N.o A.P.9 w.t H.L.4 e.3 L.H.v h.( N.P.g j.n G.P.j P.C.p f.l.. N.", +"N.o A.P.9 w.x H.L.9 3.3 L.H.v h.( m.P.g k.n G.P.O B P.B.d g.. N.", +"N.o A.P.9 e.z G.P.4 r.s L.H.v a.( N.P.g k.n G.P.a } Z P.B.d . N.", +"N.o B H - e.c S G , r.< G S c j.[ k K # k.n Z J a g.} j J % o m.", +"N.. &.&.=.1.,.*.-.>.h.2.;.;.3.s.a.:.u.t.f.d.y.y.p.g.g.i.i.i.. m.", +"N. X X X X X X X X X X X X X X X X X X X X X X X X X X o o N.", +"J.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.V.J." +}; diff --git a/src/tools/gui/art/stlink-gui_icon.svg b/src/tools/gui/art/stlink-gui_icon.svg deleted file mode 100644 index 92f7e5f11..000000000 --- a/src/tools/gui/art/stlink-gui_icon.svg +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - ST - link - - diff --git a/src/tools/gui/stlink.desktop b/src/tools/gui/stlink-gui.desktop similarity index 100% rename from src/tools/gui/stlink.desktop rename to src/tools/gui/stlink-gui.desktop From 065a4751cb405232fdac21e2b9416324d9d56cb0 Mon Sep 17 00:00:00 2001 From: dacodas Date: Sat, 19 May 2018 09:03:02 +0300 Subject: [PATCH 0615/1435] st-util: send memory map for STM32F411RE (#709) --- src/gdbserver/gdb-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index f5afa73b4..7bf3a275f 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -522,7 +522,7 @@ char* make_memory_map(stlink_t *sl) { char* map = malloc(sz); map[0] = '\0'; - if(sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F446) { + if(sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F446 || sl->chip_id==STLINK_CHIPID_STM32_F411RE) { strcpy(map, memory_map_template_F4); } else if(sl->chip_id==STLINK_CHIPID_STM32_F4_DE) { strcpy(map, memory_map_template_F4_DE); From 6f74f4a29ce079b991dbb41866c7ce54e6728ee0 Mon Sep 17 00:00:00 2001 From: trent Date: Thu, 31 May 2018 14:41:26 -0400 Subject: [PATCH 0616/1435] Fixed flash memory map for F72XXX chip_id (#711) --- src/common.c | 2 +- src/flash_loader.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/common.c b/src/common.c index b9b738203..878eba4c1 100644 --- a/src/common.c +++ b/src/common.c @@ -1451,7 +1451,7 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || (sl->chip_id == STLINK_CHIPID_STM32_F4) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || (sl->chip_id == STLINK_CHIPID_STM32_F411RE) || - (sl->chip_id == STLINK_CHIPID_STM32_F446) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI)) { + (sl->chip_id == STLINK_CHIPID_STM32_F446) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || (sl->chip_id == STLINK_CHIPID_STM32_F72XXX)) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector>= 12) { sector -= 12; diff --git a/src/flash_loader.c b/src/flash_loader.c index 599b2459a..7684680a7 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -289,9 +289,11 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* if (retval == -1) { return retval; } - } else if (sl->core_id == STM32F7_CORE_ID || - sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { + } else if (sl->core_id == STM32F7_CORE_ID || + sl->chip_id == STLINK_CHIPID_STM32_F7 || + sl->chip_id == STLINK_CHIPID_STM32_F7XXXX || + sl->chip_id == STLINK_CHIPID_STM32_F72XXX + ) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, From 6db0fc243ffb90aed314ef1d59811486e9214883 Mon Sep 17 00:00:00 2001 From: Timothy Lee Date: Fri, 1 Jun 2018 04:51:35 +1000 Subject: [PATCH 0617/1435] Reset through AIRCR (#540) (#712) In addition to asserting the NRST line, also request system reset through the Application Interrupt and Reset Control Register (AIRCR). --- include/stlink/reg.h | 5 +++++ src/sg.c | 5 +++++ src/usb.c | 9 ++++----- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/include/stlink/reg.h b/include/stlink/reg.h index 917325fb6..765ac9525 100644 --- a/include/stlink/reg.h +++ b/include/stlink/reg.h @@ -12,4 +12,9 @@ #define STLINK_REG_DCRSR 0xe000edf4 #define STLINK_REG_DCRDR 0xe000edf8 +/* Application Interrupt and Reset Control Register */ +#define STLINK_REG_AIRCR 0xe000ed0c +#define STLINK_REG_AIRCR_VECTKEY 0x05fa0000 +#define STLINK_REG_AIRCR_SYSRESETREQ 0x00000004 + #endif /* STLINK_REG_H_ */ diff --git a/src/sg.c b/src/sg.c index 90a144184..fd3e7e881 100644 --- a/src/sg.c +++ b/src/sg.c @@ -535,6 +535,11 @@ int _stlink_sg_reset(stlink_t *sl) { if (stlink_q(sl)) return -1; + // Reset through AIRCR so NRST does not need to be connected + if (stlink_write_debug32(sl, STLINK_REG_AIRCR, + STLINK_REG_AIRCR_VECTKEY | STLINK_REG_AIRCR_SYSRESETREQ)) + return -1; + stlink_stat(sl, "core reset"); return 0; } diff --git a/src/usb.c b/src/usb.c index dbacfee83..3e0596f18 100644 --- a/src/usb.c +++ b/src/usb.c @@ -368,10 +368,7 @@ int _stlink_usb_exit_dfu_mode(stlink_t* sl) { return 0; } -/** - * TODO - not convinced this does anything... - * @param sl - */ + int _stlink_usb_reset(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; @@ -389,7 +386,9 @@ int _stlink_usb_reset(stlink_t * sl) { return (int) size; } - return 0; + // Reset through AIRCR so NRST does not need to be connected + return stlink_write_debug32(sl, STLINK_REG_AIRCR, + STLINK_REG_AIRCR_VECTKEY | STLINK_REG_AIRCR_SYSRESETREQ); } From 1ec89bf7a20b060b45dbc5e1fd96b26c02c4d0a2 Mon Sep 17 00:00:00 2001 From: Anatoli Klassen Date: Wed, 27 Jun 2018 17:16:25 +0200 Subject: [PATCH 0618/1435] implement IHEX for the GUI (#718) * implement IHEX for the GUI * use already loaded file's content to write into the flash * fix clang casting --- src/tools/gui/stlink-gui.c | 114 ++++++++++++++++++++++++------------- 1 file changed, 73 insertions(+), 41 deletions(-) diff --git a/src/tools/gui/stlink-gui.c b/src/tools/gui/stlink-gui.c index 2be97ef10..c1cf26b76 100644 --- a/src/tools/gui/stlink-gui.c +++ b/src/tools/gui/stlink-gui.c @@ -306,49 +306,81 @@ stlink_gui_populate_filemem_view (gpointer data) g_return_val_if_fail (gui != NULL, NULL); g_return_val_if_fail (gui->filename != NULL, NULL); - file = g_file_new_for_path (gui->filename); - input_stream = G_INPUT_STREAM (g_file_read (file, NULL, &err)); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out; - } - - file_info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (input_stream), - G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, &err); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out_input; - } - if (gui->file_mem.memory) { - g_free (gui->file_mem.memory); - } - gui->file_mem.size = g_file_info_get_size (file_info); - gui->file_mem.memory = g_malloc (gui->file_mem.size); - - for (off = 0; off < (gint) gui->file_mem.size; off += MEM_READ_SIZE) { - guint n_read = MEM_READ_SIZE; - - if (off + MEM_READ_SIZE > (gint) gui->file_mem.size) { - n_read = (guint) gui->file_mem.size - off; - } - - if (g_input_stream_read (G_INPUT_STREAM (input_stream), - &buffer, n_read, NULL, &err) == -1) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out_input; - } - memcpy (gui->file_mem.memory + off, buffer, n_read); - gui->progress.fraction = (gdouble) (off + n_read) / gui->file_mem.size; - } - g_idle_add ((GSourceFunc) stlink_gui_update_filemem_view, gui); + if (g_str_has_suffix (gui->filename, ".hex")) { + // If the file has prefix .hex - try to interpret it as Intel-HEX. + // It's difficult to merge the world of standard functions and GLib, + // so do it simple - load whole file into buffer and copy the data + // to the destination afterwards. + // We loose meanwhile the displaying of the progress and need + // double memory. + + uint8_t* mem = NULL; + size_t size = 0; + uint32_t begin = 0; + int res = stlink_parse_ihex (gui->filename, 0, &mem, &size, &begin); + + if (res == 0) { + if (gui->file_mem.memory) { + g_free (gui->file_mem.memory); + } + gui->file_mem.size = size; + gui->file_mem.memory = g_malloc (size); + gui->file_mem.base = begin; + + memcpy (gui->file_mem.memory, mem, size); + } + else { + stlink_gui_set_info_error_message (gui, "Cannot interpret the file as Intel-HEX"); + } + + free(mem); + } + else { + file = g_file_new_for_path (gui->filename); + input_stream = G_INPUT_STREAM (g_file_read (file, NULL, &err)); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out; + } + + file_info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (input_stream), + G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, &err); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out_input; + } + if (gui->file_mem.memory) { + g_free (gui->file_mem.memory); + } + gui->file_mem.size = g_file_info_get_size (file_info); + gui->file_mem.memory = g_malloc (gui->file_mem.size); + + for (off = 0; off < (gint) gui->file_mem.size; off += MEM_READ_SIZE) { + guint n_read = MEM_READ_SIZE; + + if (off + MEM_READ_SIZE > (gint) gui->file_mem.size) { + n_read = (guint) gui->file_mem.size - off; + } + + if (g_input_stream_read (G_INPUT_STREAM (input_stream), + &buffer, n_read, NULL, &err) == -1) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out_input; + } + memcpy (gui->file_mem.memory + off, buffer, n_read); + gui->progress.fraction = (gdouble) (off + n_read) / gui->file_mem.size; + } out_input: - g_object_unref (input_stream); + g_object_unref (input_stream); out: - g_object_unref (file); + g_object_unref (file); + } + + g_idle_add ((GSourceFunc) stlink_gui_update_filemem_view, gui); return NULL; } @@ -661,7 +693,7 @@ stlink_gui_write_flash (gpointer data) g_return_val_if_fail ((gui->sl != NULL), NULL); g_return_val_if_fail ((gui->filename != NULL), NULL); - if (stlink_fwrite_flash(gui->sl, gui->filename, gui->sl->flash_base) < 0) { + if (stlink_mwrite_flash(gui->sl, gui->file_mem.memory, (uint32_t)gui->file_mem.size, gui->sl->flash_base) < 0) { stlink_gui_set_info_error_message (gui, "Failed to write to flash"); } From e147a8ea3863cbfa64eb22ff6113800e3eb01261 Mon Sep 17 00:00:00 2001 From: Deomid Ryabkov Date: Sat, 7 Jul 2018 15:52:37 +0300 Subject: [PATCH 0619/1435] Proper flash page size calculation for F412 (#721) --- src/common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 878eba4c1..40a689c7e 100644 --- a/src/common.c +++ b/src/common.c @@ -1451,7 +1451,8 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || (sl->chip_id == STLINK_CHIPID_STM32_F4) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || (sl->chip_id == STLINK_CHIPID_STM32_F411RE) || - (sl->chip_id == STLINK_CHIPID_STM32_F446) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || (sl->chip_id == STLINK_CHIPID_STM32_F72XXX)) { + (sl->chip_id == STLINK_CHIPID_STM32_F446) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || (sl->chip_id == STLINK_CHIPID_STM32_F72XXX) || + (sl->chip_id == STLINK_CHIPID_STM32_F412)) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector>= 12) { sector -= 12; From 79306cc5d8720fd578e8102a0f5e94d39cc68ed0 Mon Sep 17 00:00:00 2001 From: Bez <9039899+fkarg@users.noreply.github.com> Date: Tue, 10 Jul 2018 19:43:48 +0200 Subject: [PATCH 0620/1435] Update tutorial.md (#722) --- doc/tutorial.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/tutorial.md b/doc/tutorial.md index 52ed0bc9b..35c607ac0 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -35,6 +35,8 @@ Before continuing, the following dependencies must be met: - libusb-1.0 - cmake +Also make sure `gtk+` version 3.0 is installed. (`sudo apt-get install gtk+-3.0` or similiar) + STLINK should run on any system meeting the above constraints. The STLINK software source code is retrieved using: From ca6ecc4cfdab84a4968fd9444378f4f445981bc7 Mon Sep 17 00:00:00 2001 From: donmr Date: Thu, 26 Jul 2018 09:42:45 -0700 Subject: [PATCH 0621/1435] semihosting: Use local variable for read_result instead of *ret, and fix calculation of *ret for EOF case (#727) --- src/gdbserver/semihosting.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gdbserver/semihosting.c b/src/gdbserver/semihosting.c index 312b1517e..75fc6b1ef 100644 --- a/src/gdbserver/semihosting.c +++ b/src/gdbserver/semihosting.c @@ -307,6 +307,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { int fd; uint32_t buffer_len; void *buffer; + int read_result; if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { DLOG("Semihosting SYS_READ error: " @@ -337,7 +338,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { DLOG("Semihosting: read(%d, target_addr:0x%08x, %zu)\n", fd, buffer_address, buffer_len); - *ret = (uint32_t)read(fd, buffer, buffer_len); + read_result = (uint32_t)read(fd, buffer, buffer_len); saved_errno = errno; if (*ret == (uint32_t)-1) { @@ -350,7 +351,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { *ret = buffer_len; return -1; } else { - *ret -= buffer_len; + *ret = buffer_len - read_result; } } From 07a76b01ee4932130fa23dac7b8021ff915b38f0 Mon Sep 17 00:00:00 2001 From: donmr Date: Sat, 28 Jul 2018 02:45:09 -0700 Subject: [PATCH 0622/1435] Fixes to SYS_READ changes in PR #727 per review. (#729) * Use local variable for read_result instead of *ret, and fix calculation of *ret for EOF case. * Found a problem when reading an odd (%4) number of bytes at the end of a file. fread (on stm32) get them (say 3 bytes), then askes for more. do_semihosting gets a read return of 0 and tries to write that. mem_write alters the address to be aligned and overwrites then 3 bytes from the last read. This change simply tells mem_write to do nothing if len is 0. * Fix Issues from Fabien-Chouteau's review of my previous patch in isue #727. * Revert change to mem_write() so it does not confuse fixes to do_semihosting(). * Add cast to avoid warning. --- src/gdbserver/semihosting.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gdbserver/semihosting.c b/src/gdbserver/semihosting.c index 75fc6b1ef..5fd0d669f 100644 --- a/src/gdbserver/semihosting.c +++ b/src/gdbserver/semihosting.c @@ -307,7 +307,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { int fd; uint32_t buffer_len; void *buffer; - int read_result; + ssize_t read_result; if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { DLOG("Semihosting SYS_READ error: " @@ -338,20 +338,20 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { DLOG("Semihosting: read(%d, target_addr:0x%08x, %zu)\n", fd, buffer_address, buffer_len); - read_result = (uint32_t)read(fd, buffer, buffer_len); + read_result = read(fd, buffer, buffer_len); saved_errno = errno; - if (*ret == (uint32_t)-1) { + if (read_result == (uint32_t)-1) { *ret = buffer_len; } else { - if (mem_write(sl, buffer_address, buffer, *ret) != 0 ) { + if (mem_write(sl, buffer_address, buffer, read_result) != 0 ) { DLOG("Semihosting SYS_READ error: " "cannot write buffer to target memory\n"); free(buffer); *ret = buffer_len; return -1; } else { - *ret = buffer_len - read_result; + *ret = buffer_len - (uint32_t)read_result; } } From ea98ab7bf2064f90afd32326a24c893256a19477 Mon Sep 17 00:00:00 2001 From: donmr Date: Wed, 1 Aug 2018 02:03:35 -0700 Subject: [PATCH 0623/1435] Fix to cast in changes for SYS_READ. (#731) * Remove cast of "-1" to uint32_t. It's now compared to a ssize_t and the compiler should be fine with that without any cast. --- src/gdbserver/semihosting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gdbserver/semihosting.c b/src/gdbserver/semihosting.c index 5fd0d669f..e0249a980 100644 --- a/src/gdbserver/semihosting.c +++ b/src/gdbserver/semihosting.c @@ -341,7 +341,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { read_result = read(fd, buffer, buffer_len); saved_errno = errno; - if (read_result == (uint32_t)-1) { + if (read_result == -1) { *ret = buffer_len; } else { if (mem_write(sl, buffer_address, buffer, read_result) != 0 ) { From 27ce268a78b4850c5d786bae23315b4bca009245 Mon Sep 17 00:00:00 2001 From: donmr Date: Wed, 1 Aug 2018 02:05:31 -0700 Subject: [PATCH 0624/1435] Mem write odd (#730) * Use local variable for read_result instead of *ret, and fix calculation of *ret for EOF case. * Found a problem when reading an odd (%4) number of bytes at the end of a file. fread (on stm32) get them (say 3 bytes), then askes for more. do_semihosting gets a read return of 0 and tries to write that. mem_write alters the address to be aligned and overwrites then 3 bytes from the last read. This change simply tells mem_write to do nothing if len is 0. * Fix Issues from Fabien-Chouteau's review of my previous patch in isue #727. * Revert change to mem_write() so it does not confuse fixes to do_semihosting(). * Add cast to avoid warning. * Restore change to mem_write to return immeadiately if len == 0. Add more comments on further possible issues and ways to handle them. Using a branch to separate this change from others as it may need more discussion and go on for a while... * Remove cast of "-1" to uint32_t. It's now compared to a ssize_t and the compiler should be fine with that without any cast. --- src/gdbserver/semihosting.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/gdbserver/semihosting.c b/src/gdbserver/semihosting.c index e0249a980..b7792007f 100644 --- a/src/gdbserver/semihosting.c +++ b/src/gdbserver/semihosting.c @@ -91,6 +91,19 @@ static int mem_read(stlink_t *sl, uint32_t addr, void *data, uint16_t len) static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { + // Note: this function can write more than it is asked to! + // If addr is not an even 32 bit boundary, or len is not a multiple of 4. + // + // If only 32 bit values can be written to the target, + // then this function should read the target memory at the + // start and end of the buffer where it will write more that + // the requested bytes. (perhaps reading the whole area is faster??). + // + // If 16 and 8 bit writes are available, then they could be used instead. + + // Just return when the length is zero avoiding unneeded work. + if (len == 0) return 0; + int offset = addr % 4; int write_len = len + offset; From ae717b945dea2ca46c2e3ed0c97cb4bfc4fa7252 Mon Sep 17 00:00:00 2001 From: Luc Hondareyte <26144323+lhondareyte@users.noreply.github.com> Date: Thu, 2 Aug 2018 13:00:16 +0200 Subject: [PATCH 0625/1435] FreeBSD define LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION. (#733) --- src/sg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sg.c b/src/sg.c index fd3e7e881..285e2bd90 100644 --- a/src/sg.c +++ b/src/sg.c @@ -963,6 +963,9 @@ static stlink_t* stlink_open(const int verbose) { return NULL; } +#if defined (__FreeBSD__) + #define LIBUSBX_API_VERSION LIBUSB_API_VERSION +#endif #if LIBUSBX_API_VERSION < 0x01000106 libusb_set_debug(slsg->libusb_ctx, 3); #else From 5edb9e1bb24d162f7ff9db57a874c40f251981a9 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 13 Sep 2018 22:14:22 +0200 Subject: [PATCH 0626/1435] Update .version --- .version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.version b/.version index bc80560fa..26ca59460 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.5.0 +1.5.1 From 3eab7b960ff180df5f3678def13dceb4cf7ced93 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 13 Sep 2018 22:20:46 +0200 Subject: [PATCH 0627/1435] Update ChangeLog.md --- ChangeLog.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index ec397ece6..4602d70bd 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,6 +1,27 @@ Stlink ChangeLog ================ +v1.5.1 +====== + +Release date: 2018-09-13 + +Major changes and added features: + +* Implement intel hex support for GTK GUI +* Update libusb to 1.0.22 +* Add memory map for STM32F411RE target +* Add support for STM32L4R9 target + +Fixes: + +* FreeBSD define LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION +* Proper flash page size calculation for F412 target +* Fix flash memory map for F72xxx target +* Return correct value on EOF for Semihosting SYS_READ + +For a complete list of changes see [the milestone](https://github.com/texane/stlink/milestone/6?closed=1) + v1.5.0 ====== From 7fafee24a57c4cfa24df56383546d5c04866b512 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Thu, 13 Sep 2018 22:23:08 +0200 Subject: [PATCH 0628/1435] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bdb2351a6..a95698bdd 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Open source version of the STMicroelectronics Stlink Tools [![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) -[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.5.0.svg)](https://github.com/texane/stlink/compare/1.4.0...master) +[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.5.1.svg)](https://github.com/texane/stlink/compare/1.5.1...master) [![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/texane/stlink/releases) [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) [![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/job/stlink/) From 66e5e3ac806c7c54ba2b7f9ecb24c037c95c98be Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Fri, 28 Sep 2018 10:27:24 +0100 Subject: [PATCH 0629/1435] Mark packages as linux-any, other systems not supported. --- debian/control | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/control b/debian/control index 3427359c6..da8f69203 100644 --- a/debian/control +++ b/debian/control @@ -10,7 +10,7 @@ Vcs-Browser: https://github.com/bluca/stlink Package: libstlink-dev Section: libdevel -Architecture: any +Architecture: linux-any Depends: libstlink1 (= ${binary:Version}), ${misc:Depends} Description: OpenSource ST-Link tools replacement. Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers @@ -20,7 +20,7 @@ Description: OpenSource ST-Link tools replacement. Package: libstlink1 Section: libs -Architecture: any +Architecture: linux-any Depends: ${shlibs:Depends}, ${misc:Depends} Description: OpenSource ST-Link tools replacement. Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers @@ -29,7 +29,7 @@ Description: OpenSource ST-Link tools replacement. This package contains the shared library for stlink. Package: stlink-tools -Architecture: any +Architecture: linux-any Depends: libstlink1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: OpenSource ST-Link tools replacement. Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers @@ -39,7 +39,7 @@ Description: OpenSource ST-Link tools replacement. udev rules. Package: stlink-gui -Architecture: any +Architecture: linux-any Depends: libstlink1 (= ${binary:Version}), stlink-tools (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: OpenSource ST-Link tools replacement. From acd192fea0e440ee91a643321417a7665ad7f248 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Fri, 28 Sep 2018 10:26:46 +0100 Subject: [PATCH 0630/1435] Update changelog for 1.5.1+ds-1 release --- debian/changelog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/debian/changelog b/debian/changelog index 798093c9e..b0c877388 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +stlink (1.5.1+ds-1) unstable; urgency=medium + + * Merge tag 'v1.5.1' into debian. See upstream changelog for info: + https://github.com/texane/stlink/releases/tag/v1.5.1 + * Mark packages as linux-any, other systems not supported. + + -- Luca Boccassi Fri, 28 Sep 2018 10:26:39 +0100 + stlink (1.5.0+ds-1) unstable; urgency=medium * Upload to unstable. (Closes: #869421) From 8a07f1276901e71a1df7ad0e664f80e73290048d Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Fri, 28 Sep 2018 18:48:04 +0100 Subject: [PATCH 0631/1435] Mark library packages as Multi-Arch: same. --- debian/control | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/control b/debian/control index da8f69203..1499dcf1a 100644 --- a/debian/control +++ b/debian/control @@ -11,6 +11,7 @@ Vcs-Browser: https://github.com/bluca/stlink Package: libstlink-dev Section: libdevel Architecture: linux-any +Multi-Arch: same Depends: libstlink1 (= ${binary:Version}), ${misc:Depends} Description: OpenSource ST-Link tools replacement. Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers @@ -21,6 +22,7 @@ Description: OpenSource ST-Link tools replacement. Package: libstlink1 Section: libs Architecture: linux-any +Multi-Arch: same Depends: ${shlibs:Depends}, ${misc:Depends} Description: OpenSource ST-Link tools replacement. Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers From 8c46827f543375a4edb362e893b2fa26afcbe511 Mon Sep 17 00:00:00 2001 From: Gabriel Arjones Date: Wed, 24 Oct 2018 14:33:02 -0300 Subject: [PATCH 0632/1435] Make udev rules and modprobe conf installation optional (#741) --- CMakeLists.txt | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 395848b0a..a36803ee0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,8 @@ else() endif() option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) +option(STLINK_INSTALL_UDEV_RULES "Install udev rules files" ON) +option(STLINK_INSTALL_MODPROBE_CONF "Install modprobe conf files" ON) if (POLICY CMP0042) # Newer cmake on MacOS should use @rpath @@ -196,11 +198,15 @@ install(TARGETS st-flash st-info ) if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - file(GLOB RULES_FILES etc/udev/rules.d/*.rules) - install(FILES etc/modprobe.d/stlink_v1.conf - DESTINATION ${STLINK_MODPROBED_DIR}/) - install(FILES ${RULES_FILES} - DESTINATION ${STLINK_UDEV_RULES_DIR}/) + if (STLINK_INSTALL_MODPROBE_CONF) + install(FILES etc/modprobe.d/stlink_v1.conf + DESTINATION ${STLINK_MODPROBED_DIR}/) + endif() + if (STLINK_INSTALL_UDEV_RULES) + file(GLOB RULES_FILES etc/udev/rules.d/*.rules) + install(FILES ${RULES_FILES} + DESTINATION ${STLINK_UDEV_RULES_DIR}/) + endif() endif() add_subdirectory(src/gdbserver) From e059ea7a5579bc41b88bdada376cfeed5e4ca988 Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Tue, 30 Oct 2018 18:56:36 +0200 Subject: [PATCH 0633/1435] Fix case when __FILE__ don't contain "/" nor "\\". (#745) --- include/stlink/logging.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/stlink/logging.h b/include/stlink/logging.h index 16ed948a4..da5f7d19d 100644 --- a/include/stlink/logging.h +++ b/include/stlink/logging.h @@ -20,7 +20,8 @@ int ugly_init(int maximum_threshold); int ugly_log(int level, const char *tag, const char *format, ...); #define UGLY_LOG_FILE (strstr(__FILE__, "/") != NULL ? \ - strrchr(__FILE__, '/') + 1 : strrchr(__FILE__, '\\') + 1) + strrchr(__FILE__, '/') + 1 : strstr(__FILE__, "\\") != NULL ? \ + strrchr(__FILE__, '\\') + 1 : __FILE__) /** @todo we need to write this in a more generic way, for now this should compile on visual studio (See http://stackoverflow.com/a/8673872/1836746) */ From f87076fcbfbaef80edc5fc54e179a6b4a9629159 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Mon, 19 Nov 2018 20:45:50 +0100 Subject: [PATCH 0634/1435] doc/man: Fix double dash issue (fixes #746) --- doc/man/st-flash.1 | 64 ++++++++++++++++----------------------------- doc/man/st-flash.md | 10 +++---- doc/man/st-info.1 | 44 +++++++++---------------------- doc/man/st-info.md | 18 ++++++------- doc/man/st-util.1 | 60 ++++++++++++++---------------------------- doc/man/st-util.md | 20 +++++++------- 6 files changed, 80 insertions(+), 136 deletions(-) diff --git a/doc/man/st-flash.1 b/doc/man/st-flash.1 index 1ee272957..6bd206069 100644 --- a/doc/man/st-flash.1 +++ b/doc/man/st-flash.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pandoc 2.1.1 +.\" Automatically generated by Pandoc 2.4 .\" .TH "st\-flash" "1" "Feb 2018" "Open Source STMicroelectronics Stlink Tools" "stlink" .hy @@ -7,92 +7,74 @@ st\-flash \- Flash binary files to STM32 device .SH SYNOPSIS .PP -\f[I]st\-flash\f[] [\f[I]OPTIONS\f[]] {read|write|erase} [\f[I]FILE\f[]] - +\f[I]st\-flash\f[R] [\f[I]OPTIONS\f[R]] {read|write|erase} +[\f[I]FILE\f[R]] .SH DESCRIPTION .PP Flash binary files to arbitrary sections of memory, or read arbitrary addresses of memory out to a binary file. .PP You can use this instead of st\-util(1) if you prefer, but remember to -use the \f[B].bin\f[] image, rather than the \f[B].elf\f[] file. +use the \f[B].bin\f[R] image, rather than the \f[B].elf\f[R] file. .PP -Use hexadecimal format for the \f[I]ADDR\f[] and \f[I]SIZE\f[]. +Use hexadecimal format for the \f[I]ADDR\f[R] and \f[I]SIZE\f[R]. .SH COMMANDS .TP -.B write \f[I]FILE\f[] \f[I]ADDR\f[] -Write firmware \f[I]FILE\f[] to device starting from \f[I]ADDR\f[] -.RS -.RE +.B write \f[I]FILE\f[R] \f[I]ADDR\f[R] +Write firmware \f[I]FILE\f[R] to device starting from \f[I]ADDR\f[R] .TP -.B read \f[I]FILE\f[] \f[I]ADDR\f[] \f[I]SIZE\f[] -Read firmware from device starting from \f[I]ADDR\f[] up to -\f[I]SIZE\f[] bytes to \f[I]FILE\f[] -.RS -.RE +.B read \f[I]FILE\f[R] \f[I]ADDR\f[R] \f[I]SIZE\f[R] +Read firmware from device starting from \f[I]ADDR\f[R] up to +\f[I]SIZE\f[R] bytes to \f[I]FILE\f[R] .TP .B erase Perform a mass erasing of the device firmware -.RS -.RE .TP .B reset Reset the target -.RS -.RE .SH OPTIONS .TP -.B \f[C]\-\-version\f[] +.B \-\-version Print version information -.RS -.RE .TP -.B \f[C]\-\-debug\f[] +.B \-\-debug TODO -.RS -.RE .TP -.B \f[C]\-\-reset\f[] +.B \-\-reset TODO -.RS -.RE .TP -.B \f[C]\-\-serial\f[] \f[I]iSerial\f[] +.B \-\-serial \f[I]iSerial\f[R] TODO -.RS -.RE .TP -.B \f[C]\-\-flash=fsize\f[] +.B \-\-flash=fsize Where fsize is the size in decimal, octal, or hex followed by an optional multiplier `k' for KB, or `m' for MB. Use a leading \[lq]0x\[rq] to specify hexadecimal, or a leading zero for octal. -.RS -.RE .SH EXAMPLES .PP -Flash \f[C]firmware.bin\f[] to device +Flash \f[C]firmware.bin\f[R] to device .IP .nf \f[C] -$\ st\-flash\ write\ firmware.bin\ 0x8000000 -\f[] +$ st\-flash write firmware.bin 0x8000000 +\f[R] .fi .PP Read firmware from device (4096 bytes) .IP .nf \f[C] -$\ st\-flash\ read\ firmware.bin\ 0x8000000\ 4096 -\f[] +$ st\-flash read firmware.bin 0x8000000 4096 +\f[R] .fi .PP Erase firmware from device .IP .nf \f[C] -$\ st\-flash\ erase -\f[] +$ st\-flash erase +\f[R] .fi .SH SEE ALSO .PP @@ -101,4 +83,4 @@ st\-util(1), st\-info(1) .PP This work is copyrighted. Stlink contributors. -See \f[I]LICENSE\f[] file in the stlink source distribution. +See \f[I]LICENSE\f[R] file in the stlink source distribution. diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md index e617e4305..ae6c88f46 100644 --- a/doc/man/st-flash.md +++ b/doc/man/st-flash.md @@ -36,19 +36,19 @@ reset # OPTIONS -`--version` +\--version : Print version information -`--debug` +\--debug : TODO -`--reset` +\--reset : TODO -`--serial` *iSerial* +\--serial *iSerial* : TODO -`--flash=fsize` +\--flash=fsize : Where fsize is the size in decimal, octal, or hex followed by an optional multiplier 'k' for KB, or 'm' for MB. Use a leading "0x" to specify hexadecimal, or a leading zero for octal. diff --git a/doc/man/st-info.1 b/doc/man/st-info.1 index a774d3ade..a0380f851 100644 --- a/doc/man/st-info.1 +++ b/doc/man/st-info.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pandoc 2.1.1 +.\" Automatically generated by Pandoc 2.4 .\" .TH "st\-flash" "1" "Feb 2018" "Open Source STMicroelectronics Stlink Tools" "stlink" .hy @@ -8,7 +8,7 @@ st\-info \- Provides information about connected STLink and STM32 devices .SH SYNOPSIS .PP -\f[I]st\-info\f[] [\f[I]OPTIONS\f[]] +\f[I]st\-info\f[R] [\f[I]OPTIONS\f[R]] .SH DESCRIPTION .PP Provides information about connected STLink programmers and STM32 @@ -18,57 +18,39 @@ description. .TP .B \[en]version Print version information -.RS -.RE .TP -.B \[en]flash +.B \-\-flash Display amount of flash memory available in the device -.RS -.RE .TP -.B \[en]sram +.B \-\-sram Display amount of sram memory available in device -.RS -.RE .TP -.B \[en]descr +.B \-\-descr Display textual description of the device -.RS -.RE .TP -.B \[en]pagesize +.B \-\-pagesize Display the page size of the device -.RS -.RE .TP -.B \[en]chipid +.B \-\-chipid Display the chip ID of the device -.RS -.RE .TP -.B \[en]serial +.B \-\-serial Display the serial code of the device -.RS -.RE .TP -.B \[en]hla\-serial +.B \-\-hla\-serial Display the hex escaped serial code of the device -.RS -.RE .TP -.B \[en]probe +.B \-\-probe Display the summarized information of the connected programmers and devices -.RS -.RE .SH EXAMPLES .PP Display information about connected programmers and devices .IP .nf \f[C] -$\ st\-info\ \-\-probe -\f[] +$ st\-info \-\-probe +\f[R] .fi .SH SEE ALSO .PP @@ -77,4 +59,4 @@ st\-util(1), st\-flash(1) .PP This work is copyrighted. Stlink contributors. -See \f[I]LICENSE\f[] file in the stlink source distribution. +See \f[I]LICENSE\f[R] file in the stlink source distribution. diff --git a/doc/man/st-info.md b/doc/man/st-info.md index 1a0773e74..67d9373d7 100644 --- a/doc/man/st-info.md +++ b/doc/man/st-info.md @@ -17,31 +17,31 @@ Serial code, openocd, flash, sram, page size, chipid, description. # OPTIONS ---version +\--version : Print version information ---flash +\--flash : Display amount of flash memory available in the device ---sram +\--sram : Display amount of sram memory available in device ---descr +\--descr : Display textual description of the device ---pagesize +\--pagesize : Display the page size of the device ---chipid +\--chipid : Display the chip ID of the device ---serial +\--serial : Display the serial code of the device ---hla-serial +\--hla-serial : Display the hex escaped serial code of the device ---probe +\--probe : Display the summarized information of the connected programmers and devices diff --git a/doc/man/st-util.1 b/doc/man/st-util.1 index a7b2eb6cf..9b46b4d65 100644 --- a/doc/man/st-util.1 +++ b/doc/man/st-util.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pandoc 2.1.1 +.\" Automatically generated by Pandoc 2.4 .\" .TH "st\-util" "1" "Feb 2018" "Open Source STMicroelectronics Stlink Tools" "stlink" .hy @@ -7,83 +7,63 @@ st\-util \- Run GDB server to interact with STM32 device .SH SYNOPSIS .PP -\f[I]st\-util\f[] [\&...] +\f[I]st\-util\f[R] [\&...] .SH DESCRIPTION .PP Start a GDB server to interact with a STM32 device Run the main binary of the local package (src/main.rs). .PP -If a port number is not specified using the \f[B]\[en]listen_port\f[] -option, the default \f[B]4242\f[] port will be used. +If a port number is not specified using the \f[B]\[en]listen_port\f[R] +option, the default \f[B]4242\f[R] port will be used. .PP Stlink version 2 is used by default unless the option -\f[B]\[en]stlinkv1\f[] is given. +\f[B]\[en]stlinkv1\f[R] is given. .PP The STLinkV2 device to use can be specified in the environment variable STLINK_DEVICE on the format :. .SH OPTIONS .TP -.B \-h, \f[C]\-\-help\f[] +.B \-h, \-\-help Print this message. -.RS -.RE .TP -.B \f[C]\-\-version\f[] +.B \-\-version Print version information -.RS -.RE .TP -.B \-v \f[I]XX\f[], \f[C]\-\-verbose=XX\f[] +.B \-v \f[I]XX\f[R], \-\-verbose=XX Specify a specific verbosity level (0..99) -.RS -.RE .TP -.B \-v, \f[C]\-\-verbose\f[] +.B \-v, \-\-verbose Specify generally verbose logging -.RS -.RE .TP -.B \-s \f[I]X\f[], \f[C]\-\-stlink_version=X\f[] +.B \-s \f[I]X\f[R], \-\-stlink_version=X Choose what version of stlink to use, (defaults to 2) -.RS -.RE .TP -.B \-1, \f[C]\-\-stlinkv1\f[] +.B \-1, \-\-stlinkv1 Force stlink version 1 -.RS -.RE .TP -.B \-p \f[I]4242\f[], \f[C]\-\-listen_port=1234\f[] +.B \-p \f[I]4242\f[R], \-\-listen_port=1234 Set the gdb server listen port. (default port: 4242) -.RS -.RE .TP -.B \-m, \f[C]\-\-multi\f[] +.B \-m, \-\-multi Set gdb server to extended mode. st\-util will continue listening for connections after disconnect. -.RS -.RE .TP -.B \-n, \f[C]\-\-no\-reset\f[] +.B \-n, \-\-no\-reset Do not reset board on connection. -.RS -.RE .TP -.B \f[C]\-\-semihosting\f[] +.B \-\-semihosting Enable ARM Semihosting output on stdout -.RS -.RE .SH EXAMPLES .PP Run GDB server on port 4500 and connect to it .IP .nf \f[C] -$\ st\-util\ \-p\ 4500 -$\ gdb -(gdb)\ target\ extended\-remote\ localhost:4500 -\f[] +$ st\-util \-p 4500 +$ gdb +(gdb) target extended\-remote localhost:4500 +\f[R] .fi .SH SEE ALSO .PP @@ -92,4 +72,4 @@ st\-flash(1), st\-info(1) .PP This work is copyrighted. Stlink contributors. -See \f[I]LICENSE\f[] file in the stlink source distribution. +See \f[I]LICENSE\f[R] file in the stlink source distribution. diff --git a/doc/man/st-util.md b/doc/man/st-util.md index b141091f9..e62261213 100644 --- a/doc/man/st-util.md +++ b/doc/man/st-util.md @@ -24,34 +24,34 @@ variable STLINK_DEVICE on the format :. # OPTIONS --h, `--help` +-h, \--help : Print this message. -`--version` +\--version : Print version information --v *XX*, `--verbose=XX` +-v *XX*, \--verbose=*XX* : Specify a specific verbosity level (0..99) --v, `--verbose` +-v, \--verbose : Specify generally verbose logging --s *X*, `--stlink_version=X` +-s *X*, \--stlink_version=*X* : Choose what version of stlink to use, (defaults to 2) --1, `--stlinkv1` +-1, \--stlinkv1 : Force stlink version 1 --p *4242*, `--listen_port=1234` +-p *4242*, \--listen_port=1234 : Set the gdb server listen port. (default port: 4242) --m, `--multi` +-m, \--multi : Set gdb server to extended mode. st-util will continue listening for connections after disconnect. --n, `--no-reset` +-n, \--no-reset : Do not reset board on connection. -`--semihosting` +\--semihosting : Enable ARM Semihosting output on stdout # EXAMPLES From a201d3e5bd4a52a6e2a7f89947688f580c2b3554 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sun, 2 Dec 2018 21:25:02 +0100 Subject: [PATCH 0635/1435] Update compiling.md Fixes #748 --- doc/compiling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/compiling.md b/doc/compiling.md index 41d1fb7f9..e613965a3 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -43,7 +43,7 @@ $ cd build/Release; sudo make install * Debian based distros (debian, ubuntu) * `build-essential` * `cmake` -* `libusb-1.0` (plus development headers for building, on debian based distros `libusb-1.0.0-dev` package) +* `libusb-1.0` (plus development headers for building, on debian based distros `libusb-1.0-0-dev` package) * (optional) for `stlink-gui` we need libgtk-3-dev ### Fixing cannot open shared object file From 0a2b7a4ff076b877155a76d5000be14a73bf524b Mon Sep 17 00:00:00 2001 From: Dave Hylands Date: Fri, 14 Dec 2018 14:31:23 -0500 Subject: [PATCH 0636/1435] Only do bank calculation on STM32L4 devices with dual banked flash (#751) * Only do bank calculatio on SRM32L4 devices with dual banked flash RM0394 covers the STM32L41xx, 42xx, 43xx, 44xx, 45xx, and 46xx. These devices are all employ single banked flash and have chip id's of 0x464 for the 41xx/42xx, 0x435 for 43xx/44xx, and 0x462 for 45xx/46xx It's also worth noting that bit 21 of the FLASH_OPTR register is marked as resevred for these chips, and isn't an indicator of dual banked flash. RM0392 covers the STM32L4x1, cpu_id 0x415 and can be dual banked. RM0351 covers the STM32L4x5/4x6, cpu_ids 0x415 & 0x461 and can be dual banked RM0432 covers the STM32L4Rx/4Sx, cpu_id 0x470 and can be dual banked. This PR modifies the calculate_L4_page functio to only factor bank calculations for the devices above which can support dual banked flash. * Converted tabs to spaces on added line --- include/stlink/chipid.h | 2 ++ src/common.c | 16 +++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 004fa2e80..d28527aba 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -40,10 +40,12 @@ enum stlink_stm32_chipids { * 0x435 covers STM32L43xxx and STM32L44xxx devices * 0x461 covers STM32L496xx and STM32L4A6xx devices * 0x462 covers STM32L45xxx and STM32L46xxx devices + * 0x464 covers STM32L41xxx and STM32L42xxx devices */ STLINK_CHIPID_STM32_L43X = 0x435, STLINK_CHIPID_STM32_L496X = 0x461, STLINK_CHIPID_STM32_L46X = 0x462, + STLINK_CHIPID_STM32_L41X = 0x464, /* * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" * and some that are called "High". 0x427 is assigned to the other "Medium- diff --git a/src/common.c b/src/common.c index 40a689c7e..fa2a4607a 100644 --- a/src/common.c +++ b/src/common.c @@ -1436,13 +1436,19 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { uint32_t flashopt; stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); flashaddr -= STM32_FLASH_BASE; - if (flashopt & (1lu << STM32L4_FLASH_OPTR_DUALBANK)) { - uint32_t banksize = (uint32_t) sl->flash_size / 2; - if (flashaddr >= banksize) { - flashaddr -= banksize; - bker = 0x100; + if (sl->chip_id == STLINK_CHIPID_STM32_L4 || + sl->chip_id == STLINK_CHIPID_STM32_L496X || + sl->chip_id == STLINK_CHIPID_STM32_L4RX) { + // This chip use dual banked flash + if (flashopt & (1lu << STM32L4_FLASH_OPTR_DUALBANK)) { + uint32_t banksize = (uint32_t) sl->flash_size / 2; + if (flashaddr >= banksize) { + flashaddr -= banksize; + bker = 0x100; + } } } + // For 1MB chips without the dual-bank option set, the page address will // overflow into the BKER bit, which gives us the correct bank:page value. return bker | flashaddr/sl->flash_pgsz; From 358a91395d957ad626390fbbfcaec065cb49c532 Mon Sep 17 00:00:00 2001 From: Jiri Bilek Date: Fri, 21 Dec 2018 12:54:56 +0100 Subject: [PATCH 0637/1435] Add O_BINARY option to open file. (#753) See issue #752. --- src/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index fa2a4607a..0a74bb2af 100644 --- a/src/common.c +++ b/src/common.c @@ -1364,7 +1364,7 @@ int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr int error; - int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700); + int fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); if (fd == -1) { fprintf(stderr, "open(%s) == -1\n", path); return -1; From 7651d2116fd74c7803ea00ab1da7cf3d00faf44c Mon Sep 17 00:00:00 2001 From: Victor Lamoine Date: Thu, 3 Jan 2019 21:10:47 +0100 Subject: [PATCH 0638/1435] Add support for CS32 micro-controller (#757) --- include/stlink.h | 1 + src/flash_loader.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/stlink.h b/include/stlink.h index ac0bfe190..4d321133d 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -53,6 +53,7 @@ extern "C" { /* cortex core ids */ // TODO clean this up... #define STM32VL_CORE_ID 0x1ba01477 +#define CS32_CORE_ID 0x2ba01477 #define STM32F7_CORE_ID 0x5ba02477 // Constant STM32 memory map figures diff --git a/src/flash_loader.c b/src/flash_loader.c index 7684680a7..25c11e465 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -262,6 +262,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID + || sl->core_id == CS32_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F3 || sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL || sl->chip_id == STLINK_CHIPID_STM32_F303_HIGH From 6a9d390a729f381ecec45f212354bfe98e27790f Mon Sep 17 00:00:00 2001 From: WRansohoff Date: Sun, 13 Jan 2019 00:04:21 -0800 Subject: [PATCH 0639/1435] Update STM32F3xx chip ID that covers a few different devices. (#758) --- src/chipid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/chipid.c b/src/chipid.c index 6f93af112..f1dbb633f 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -403,10 +403,10 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x1000 }, { - // STM32F334 - // RM0364 document was used to find these parameters + // STM32F334, STM32F303x6/8, and STM32F328 + // From RM0364 and RM0316 .chip_id = STLINK_CHIPID_STM32_F334, - .description = "F334 device", + .description = "F3xx medium density device", // (RM0316 sec 33.6.1) .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, From 0f1fc5042986b3f65ded2e1599434f7cc5a77e24 Mon Sep 17 00:00:00 2001 From: WRansohoff Date: Thu, 24 Jan 2019 12:25:25 -0800 Subject: [PATCH 0640/1435] Add preliminary support for some STM32G0 chips. (closes #759) (#760) * Add preliminary support for some STM32G0 chips. * Fix a bug in the 'which page to erase' logic. When I flashed a program with more than one page, I noticed that this logic did not un-set previously-set 'PNG' bits. So it would erase page 1, then page 3, then page 3... --- include/stlink.h | 1 + include/stlink/chipid.h | 3 +- src/chipid.c | 11 ++++ src/common.c | 118 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 131 insertions(+), 2 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 4d321133d..0f2f5bb51 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -86,6 +86,7 @@ extern "C" { STLINK_FLASH_TYPE_F4, STLINK_FLASH_TYPE_L4, STLINK_FLASH_TYPE_F1_XL, + STLINK_FLASH_TYPE_G0, }; struct stlink_reg { diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index d28527aba..dda437ce7 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -70,7 +70,8 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_L011 = 0x457, STLINK_CHIPID_STM32_F410 = 0x458, STLINK_CHIPID_STM32_F413 = 0x463, - STLINK_CHIPID_STM32_L4RX = 0x470 // taken from the STM32L4R9I-DISCO board + STLINK_CHIPID_STM32_L4RX = 0x470, // taken from the STM32L4R9I-DISCO board + STLINK_CHIPID_STM32_G0X1 = 0x460 }; /** diff --git a/src/chipid.c b/src/chipid.c index f1dbb633f..4e04f00cc 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -507,6 +507,17 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1ff00000, .bootrom_size = 0x2000 }, + { + // STM32G071/081 (from RM0444) + .chip_id = STLINK_CHIPID_STM32_G0X1, + .description = "G071/G081 device", + .flash_type = STLINK_FLASH_TYPE_G0, + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2K (sec 3.2) + .sram_size = 0x9000, // 36K (sec 2.3) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 // 30K (table 2) + }, { // unknown .chip_id = STLINK_CHIPID_UNKNOWN, diff --git a/src/common.c b/src/common.c index 0a74bb2af..38047d0d8 100644 --- a/src/common.c +++ b/src/common.c @@ -74,6 +74,23 @@ #define FLASH_L1_FPRG 10 #define FLASH_L1_PROG 3 +// G0 (RM0444 Table 1, sec 3.7) +#define STM32G0_FLASH_REGS_ADDR ((uint32_t)0x40022000) +#define STM32G0_FLASH_ACR (STM32G0_FLASH_REGS_ADDR + 0x00) +#define STM32G0_FLASH_KEYR (STM32G0_FLASH_REGS_ADDR + 0x08) +#define STM32G0_FLASH_OPTKEYR (STM32G0_FLASH_REGS_ADDR + 0x0c) +#define STM32G0_FLASH_SR (STM32G0_FLASH_REGS_ADDR + 0x10) +#define STM32G0_FLASH_CR (STM32G0_FLASH_REGS_ADDR + 0x14) +#define STM32G0_FLASH_ECCR (STM32G0_FLASH_REGS_ADDR + 0x18) +#define STM32G0_FLASH_OPTR (STM32G0_FLASH_REGS_ADDR + 0x20) +#define STM32G0_FLASH_PCROP1ASR (STM32G0_FLASH_REGS_ADDR + 0x24) +#define STM32G0_FLASH_PCROP1AER (STM32G0_FLASH_REGS_ADDR + 0x28) +#define STM32G0_FLASH_WRP1AR (STM32G0_FLASH_REGS_ADDR + 0x2C) +#define STM32G0_FLASH_WRP1BR (STM32G0_FLASH_REGS_ADDR + 0x30) +#define STM32G0_FLASH_PCROP1BSR (STM32G0_FLASH_REGS_ADDR + 0x34) +#define STM32G0_FLASH_PCROP1BER (STM32G0_FLASH_REGS_ADDR + 0x38) +#define STM32G0_FLASH_SECR (STM32G0_FLASH_REGS_ADDR + 0x80) + //32L4 register base is at FLASH_REGS_ADDR (0x40022000) #define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) #define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) @@ -1601,6 +1618,47 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + uint32_t val; + /* check if the locks are set */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + if ((val & (1<<31))) { + /* disable flash write protection. */ + stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0x45670123); + stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0xCDEF89AB); + /* check that the lock is no longer set. */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + if ((val & (1 << 31))) { + WLOG("pecr.pelock not clear (%#x)\n", val); + return -1; + } + } + /* Set PER (erase) bit. */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + val |= 0x00000002; + stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + /* Set the page to erase. */ + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. + val = ((flash_page & 0x3F) << 3) | (2); + stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + /* Set the 'start' bit. */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + val |= (1 << 16); + stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + /* Wait for 'busy' bit in FLASH_SR to clear. */ + do { + stlink_read_debug32(sl, STM32G0_FLASH_SR, &val); + } while ((val & (1 << 16)) != 0); + /* Clear PER ('erase enable') bit. */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + val &= ~(0x00000002); + stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + /* Re-lock the flash. */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + val |= 0x80000000; + stlink_write_debug32(sl, STM32G0_FLASH_CR, val); } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr < FLASH_BANK2_START_ADDR))) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1654,7 +1712,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } int stlink_erase_flash_mass(stlink_t *sl) { - if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + /* TODO: User MER bit to mass-erase G0 series. */ + if (sl->flash_type == STLINK_FLASH_TYPE_L0 || sl->flash_type == STLINK_FLASH_TYPE_G0) { /* erase each page */ int i = 0, num_pages = (int) sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -1925,7 +1984,64 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t lock_flash(sl); } //STM32F4END + else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + uint32_t val; + /* Unlock flash. */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + if ((val & (1<<31))) { + /* disable flash write protection. */ + stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0x45670123); + stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0xCDEF89AB); + /* check that the lock is no longer set. */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + if ((val & (1 << 31))) { + WLOG("pecr.pelock not clear (%#x)\n", val); + return -1; + } + } + /* Set PG 'allow programming' bit. */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + val |= 0x00000001; + stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + /* Write all words. */ + off = 0; + for ( ; off < len; off += sizeof(uint32_t)) { + uint32_t data; + if (off > 254) + fprintf(stdout, "\r"); + if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) { + fprintf(stdout, "\r%3u/%3u pages written", + (unsigned int)(off/sl->flash_pgsz), + (unsigned int)(len/sl->flash_pgsz)); + fflush(stdout); + } + write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); + stlink_write_debug32(sl, addr + (uint32_t) off, data); + /* Wait for 'busy' bit in FLASH_SR to clear. */ + do { + stlink_read_debug32(sl, STM32G0_FLASH_SR, &val); + } while ((val & (1 << 16)) != 0); + } + /* Do we need a dummy write? See sec 3.3.8 of RM0444. */ + /* (Flash writes happen 2 words at a time.) */ + if ((off / sizeof(uint32_t)) % 2 != 0) { + /* Write a single word of zeros. */ + stlink_write_debug32(sl, addr + (uint32_t) off, 0); + /* Wait for 'busy' bit in FLASH_SR to clear. */ + do { + stlink_read_debug32(sl, STM32G0_FLASH_SR, &val); + } while ((val & (1 << 16)) != 0); + } + /* Reset PG bit. */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + val &= ~(0x00000001); + stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + /* Re-lock flash. */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + val |= 0x80000000; + stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { /* use fast word write. todo: half page. */ uint32_t val; From af325bb989e3072984abd905059a7790afe965b2 Mon Sep 17 00:00:00 2001 From: Thomas Cenova Date: Thu, 24 Jan 2019 15:27:08 -0500 Subject: [PATCH 0641/1435] This fixes the versioning when compiling from the repo checked out with git. (#762) --- cmake/Version.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmake/Version.cmake b/cmake/Version.cmake index bb01315ab..e74d775d6 100644 --- a/cmake/Version.cmake +++ b/cmake/Version.cmake @@ -6,7 +6,7 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") # Working off a git repo, using git versioning # Check if HEAD is pointing to a tag execute_process ( - COMMAND "${GIT_EXECUTABLE}" describe --always + COMMAND "${GIT_EXECUTABLE}" describe --always --tag WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" OUTPUT_VARIABLE PROJECT_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) @@ -21,6 +21,9 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") set (PROJECT_VERSION "${PROJECT_VERSION}-dirty") endif() + # strip a leading v off of the version as proceeding code expectes just the version numbering. + string(REGEX REPLACE "^v" "" PROJECT_VERSION ${PROJECT_VERSION}) + string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) list(LENGTH PROJECT_VERSION_LIST len) From 30de1b30e7a96974ae764d0508c151eadb1addd1 Mon Sep 17 00:00:00 2001 From: Jicksaw Date: Thu, 24 Jan 2019 22:29:59 +0200 Subject: [PATCH 0642/1435] Fix "unkown chip id", piped output and st-util -v (#763) * Set SWD clock before using SWD (#107, #568 ?) * Make st-util -v print more than default * Flush output streams explicitly. Fix #665 On Win32 redirecting streams makes them buffered, therefore without flushing there would be no output before exit. Stdout and stderr are also often buffered differently, making them disordered. --- src/gdbserver/gdb-server.c | 2 +- src/logging.c | 5 +++++ src/usb.c | 6 +++--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 7bf3a275f..6e64dd073 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -151,7 +151,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { if (optarg) { st->logging_level = atoi(optarg); } else { - st->logging_level = DEFAULT_LOGGING_LEVEL; + st->logging_level = DEBUG_LOGGING_LEVEL; } break; case '1': diff --git a/src/logging.c b/src/logging.c index b5e423a3a..d4fb96b2e 100644 --- a/src/logging.c +++ b/src/logging.c @@ -22,6 +22,10 @@ int ugly_log(int level, const char *tag, const char *format, ...) { if (level > max_level) { return 0; } + + // Flush to maintain order of streams + fflush(stdout); + va_list args; va_start(args, format); time_t mytt = time(NULL); @@ -46,6 +50,7 @@ int ugly_log(int level, const char *tag, const char *format, ...) { break; } vfprintf(stderr, format, args); + fflush(stderr); va_end(args); return 1; } diff --git a/src/usb.c b/src/usb.c index 3e0596f18..66f065ab8 100644 --- a/src/usb.c +++ b/src/usb.c @@ -923,6 +923,9 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 // Initialize stlink version (sl->version) stlink_version(sl); + // Set the stlink clock speed (default is 1800kHz) + stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); + if (reset) { if( sl->version.stlink_v > 1 ) stlink_jtag_reset(sl, 2); stlink_reset(sl); @@ -931,9 +934,6 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 ret = stlink_load_device_params(sl); - // Set the stlink clock speed (default is 1800kHz) - stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); - on_libusb_error: if (ret == -1) { stlink_close(sl); From 8186d854bac19c530e2d392d86d9c0b5870175a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Mellstr=C3=B6m?= Date: Sat, 9 Feb 2019 11:10:15 +0100 Subject: [PATCH 0643/1435] Add support for mass erasing second bank on STM32F10x_XL (#767) --- src/common.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/common.c b/src/common.c index 38047d0d8..df3837c0e 100644 --- a/src/common.c +++ b/src/common.c @@ -380,6 +380,20 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { stlink_write_debug32(sl, cr_reg, val); } +static void set_flash_cr2_mer(stlink_t *sl, bool v) { + const uint32_t cr_pg = 1 << FLASH_CR_PER; + const uint32_t cr_mer = 1 << FLASH_CR_MER; + uint32_t val; + + stlink_read_debug32(sl, FLASH_CR2, &val); + val &= ~cr_pg; + if (v) + val |= cr_mer; + else + val &= ~cr_mer; + stlink_write_debug32(sl, FLASH_CR2, val); +} + static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { uint32_t val, cr_reg, cr_mer; @@ -1740,6 +1754,14 @@ int stlink_erase_flash_mass(stlink_t *sl) { /* start erase operation, reset by hw with bsy bit */ set_flash_cr_strt(sl); + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + /* set the mass erase bit in bank 2 */ + set_flash_cr2_mer(sl,1); + + /* start erase operation in bank 2 */ + set_flash_cr2_strt(sl); + } + /* wait for completion */ wait_flash_busy_progress(sl); @@ -1749,6 +1771,11 @@ int stlink_erase_flash_mass(stlink_t *sl) { /* reset the mass erase bit */ set_flash_cr_mer(sl,0); + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + /* reset the mass erase bit in bank 2 */ + set_flash_cr2_mer(sl,0); + } + /* todo: verify the erased memory */ } return 0; From b9c315d990abfde3008a917e767c63d2c1c1ddf2 Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Sat, 9 Feb 2019 13:11:43 +0300 Subject: [PATCH 0644/1435] win32: move usleep definition to unistd.h (#765) --- src/gdbserver/gdb-server.c | 4 ++-- src/mingw/mingw.c | 6 ++++-- src/mingw/mingw.h | 5 ----- src/win32/unistd.h | 4 ++++ 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 6e64dd073..8566b792e 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -254,8 +254,8 @@ int main(int argc, char** argv) { do { if (serve(sl, &state)) { - sleep (1); // don't go bezurk if serve returns with error - } + usleep (1 * 1000); // don't go bezurk if serve returns with error + } /* in case serve() changed the connection */ sl = connected_stlink; diff --git a/src/mingw/mingw.c b/src/mingw/mingw.c index aee288d88..bfdd3dcff 100644 --- a/src/mingw/mingw.c +++ b/src/mingw/mingw.c @@ -272,7 +272,7 @@ char *win32_strsep (char **stringp, const char *delim) } #ifndef STLINK_HAVE_UNISTD_H -void usleep(DWORD waitTime) +int usleep(unsigned int waitTime) { if (waitTime >= 1000) { @@ -288,7 +288,7 @@ void usleep(DWORD waitTime) SetWaitableTimer(timer, &dueTime, 0, NULL, NULL, 0); WaitForSingleObject(timer, INFINITE); CloseHandle(timer); - return; + return 0; } LARGE_INTEGER perf_cnt, start, now; @@ -298,6 +298,8 @@ void usleep(DWORD waitTime) do { QueryPerformanceCounter((LARGE_INTEGER*) &now); } while ((now.QuadPart - start.QuadPart) / (float)perf_cnt.QuadPart * 1000 * 1000 < waitTime); + + return 0; } #endif diff --git a/src/mingw/mingw.h b/src/mingw/mingw.h index 04907f7d6..2efd1ab34 100644 --- a/src/mingw/mingw.h +++ b/src/mingw/mingw.h @@ -71,9 +71,4 @@ char *win32_strsep(char **stringp, const char *delim); ssize_t win32_read_socket(SOCKET fd, void *buf, int n); ssize_t win32_write_socket(SOCKET fd, void *buf, int n); -#ifndef STLINK_HAVE_UNISTD_H -static inline void sleep(unsigned ms) { Sleep(ms); } -void usleep(DWORD waitTime); -#endif - #endif //defined(__MINGW32__) || defined(_MSC_VER) diff --git a/src/win32/unistd.h b/src/win32/unistd.h index 0b175fc07..4c94aed34 100644 --- a/src/win32/unistd.h +++ b/src/win32/unistd.h @@ -57,4 +57,8 @@ typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; +#ifndef STLINK_HAVE_UNISTD_H +int usleep(unsigned int waitTime); +#endif + #endif /* unistd.h */ From 3295ab4e5cf05cb546856414f1d40b5deedcf219 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Tue, 12 Feb 2019 21:07:35 +0100 Subject: [PATCH 0645/1435] Revert "Add support for CS32 micro-controller (#757)" (fixes #761) This reverts commit 7651d2116fd74c7803ea00ab1da7cf3d00faf44c. --- include/stlink.h | 1 - src/flash_loader.c | 1 - 2 files changed, 2 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 0f2f5bb51..abacd127e 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -53,7 +53,6 @@ extern "C" { /* cortex core ids */ // TODO clean this up... #define STM32VL_CORE_ID 0x1ba01477 -#define CS32_CORE_ID 0x2ba01477 #define STM32F7_CORE_ID 0x5ba02477 // Constant STM32 memory map figures diff --git a/src/flash_loader.c b/src/flash_loader.c index 25c11e465..7684680a7 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -262,7 +262,6 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID - || sl->core_id == CS32_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F3 || sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL || sl->chip_id == STLINK_CHIPID_STM32_F303_HIGH From 1165cf712713af48c61c4782ad5c9477c4574708 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Sat, 16 Feb 2019 23:38:37 +0200 Subject: [PATCH 0646/1435] gui: Fix relative path to the UI files needed by stlink-gui-local (#771) --- src/tools/gui/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/gui/CMakeLists.txt b/src/tools/gui/CMakeLists.txt index ceb862c33..c619a0547 100644 --- a/src/tools/gui/CMakeLists.txt +++ b/src/tools/gui/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories(SYSTEM ${gtk_INCLUDE_DIRS}) add_executable(stlink-gui-local ${GUI_SOURCES}) set_target_properties(stlink-gui-local PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}/gui") + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}") target_link_libraries(stlink-gui-local ${STLINK_LIB_STATIC} ${gtk_LDFLAGS}) From d13f946468663fb101227c3f03f271037cfc2c2c Mon Sep 17 00:00:00 2001 From: aoand Date: Thu, 7 Mar 2019 14:41:38 +0300 Subject: [PATCH 0647/1435] doc/compiling.md: fix package name "devscripts" (#775) the command 'debuild' is (and always was) part of the devscripts package --- doc/compiling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/compiling.md b/doc/compiling.md index e613965a3..74a8a34f5 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -83,7 +83,7 @@ Options (do one of these before you plug it in) ### Build Debian Package -To build the debian package you need the following extra packages: `debuild debhelper`. +To build the debian package you need the following extra packages: `devscripts debhelper`. ``` $ git archive --prefix=$(git describe)/ HEAD | bzip2 --stdout > ../libstlink_$(sed -En -e "s/.*\((.*)\).*/\1/" -e "1,1 p" debian/changelog).orig.tar.bz2 From 522188db496db059bfa8ae90b6d8417bbc08bb51 Mon Sep 17 00:00:00 2001 From: Ronny Majani Date: Thu, 7 Mar 2019 22:42:39 +1100 Subject: [PATCH 0648/1435] Added call to clear PG bit after Writing to Flash (#773) --- src/common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index df3837c0e..dab9a33c0 100644 --- a/src/common.c +++ b/src/common.c @@ -320,7 +320,7 @@ static void set_flash_cr_pg(stlink_t *sl) { stlink_write_debug32(sl, cr_reg, x); } -static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) { +static void clear_flash_cr_pg(stlink_t *sl) { uint32_t cr_reg, n; if (sl->flash_type == STLINK_FLASH_TYPE_F4) @@ -2008,6 +2008,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } /* Relock flash */ + clear_flash_cr_pg(sl); lock_flash(sl); } //STM32F4END From c9e09457555cd4462549b37d57005aad4ef9e614 Mon Sep 17 00:00:00 2001 From: Cerem Cem ASLAN Date: Fri, 15 Mar 2019 13:09:06 +0300 Subject: [PATCH 0649/1435] Added howto for sending NRST signal through GDB (#776) See https://github.com/texane/stlink/issues/774 --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a95698bdd..e30965277 100644 --- a/README.md +++ b/README.md @@ -113,9 +113,15 @@ Kill the program being debugged? (y or n) y Starting program: /home/whitequark/ST/apps/bally/firmware.elf ``` -Remember that you can shorten the commands. `tar ext :4242' is good enough +Remember that you can shorten the commands. `tar ext :4242` is good enough for GDB. +If you need to send a hard reset signal through `NRST` pin, you can use the following command: +`` +(gdb) monitor jtag_reset +``` + + ## Running programs from SRAM You can run your firmware directly from SRAM if you want to. Just link From 18ec7e239bb3e83a7888b19d984aa4f4e8830390 Mon Sep 17 00:00:00 2001 From: Cerem Cem ASLAN Date: Fri, 15 Mar 2019 21:34:39 +0300 Subject: [PATCH 0650/1435] fix typo (#779) --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e30965277..4b8ed96dd 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,8 @@ Remember that you can shorten the commands. `tar ext :4242` is good enough for GDB. If you need to send a hard reset signal through `NRST` pin, you can use the following command: -`` + +``` (gdb) monitor jtag_reset ``` From c6836b4ac9ff12c97ce909bc9a5a6784e1e97437 Mon Sep 17 00:00:00 2001 From: Manuel Dipolt Date: Wed, 20 Mar 2019 14:01:11 +0100 Subject: [PATCH 0651/1435] Added support to write option bytes for the STM32G0 (#778) * poc worked, writting stm32G070 option bytes * Update README.md adjust layout * code review changes --- README.md | 8 +++ include/stlink.h | 14 ++--- include/stm32.h | 19 +++++++ src/common.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++ src/tools/flash.c | 8 +++ 5 files changed, 166 insertions(+), 11 deletions(-) create mode 100644 include/stm32.h diff --git a/README.md b/README.md index 4b8ed96dd..d711d323f 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,14 @@ If you would link your executable to `0x08000000` and then do then it would be written to the memory. +## Writing Option Bytes + +Example to read and write option bytes (currently writing only supported for STM32G0) +``` +./st-flash --debug --reset --format binary --flash=128k read option_bytes_dump.bin 0x1FFF7800 4 +./st-flash --debug --reset --format binary --flash=128k write option_bytes_dump.bin 0x1FFF7800 +``` + ## FAQ Q: My breakpoints do not work at all or only work once. diff --git a/include/stlink.h b/include/stlink.h index abacd127e..fedeb1bf4 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -11,6 +11,8 @@ #include #include +#include "stm32.h" + #ifdef __cplusplus extern "C" { #endif @@ -50,15 +52,6 @@ extern "C" { #define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43 - /* cortex core ids */ - // TODO clean this up... -#define STM32VL_CORE_ID 0x1ba01477 -#define STM32F7_CORE_ID 0x5ba02477 - - // Constant STM32 memory map figures -#define STM32_FLASH_BASE 0x08000000 -#define STM32_SRAM_BASE 0x20000000 - // Baud rate divisors for SWDCLK #define STLINK_SWDCLK_4MHZ_DIVISOR 0 #define STLINK_SWDCLK_1P8MHZ_DIVISOR 1 @@ -73,8 +66,6 @@ extern "C" { #define STLINK_SWDCLK_15KHZ_DIVISOR 265 #define STLINK_SWDCLK_5KHZ_DIVISOR 798 - - /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ #define C_BUF_LEN 32 @@ -205,6 +196,7 @@ typedef struct flash_loader { uint8_t stlink_get_erased_pattern(stlink_t *sl); int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); + int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, 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); diff --git a/include/stm32.h b/include/stm32.h new file mode 100644 index 000000000..f5dbe4b2d --- /dev/null +++ b/include/stm32.h @@ -0,0 +1,19 @@ +/* + * File: stm32.h + * + * STM32 specific defines + */ + +#ifndef STM32_H +#define STM32_H + +// cortex core ids +#define STM32VL_CORE_ID 0x1ba01477 +#define STM32F7_CORE_ID 0x5ba02477 + +// Constant STM32 memory map figures +#define STM32_FLASH_BASE ((uint32_t)0x08000000) +#define STM32_SRAM_BASE ((uint32_t)0x20000000) +#define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) + +#endif /* STM32_H */ diff --git a/src/common.c b/src/common.c index dab9a33c0..9bb2c2c4e 100644 --- a/src/common.c +++ b/src/common.c @@ -91,6 +91,20 @@ #define STM32G0_FLASH_PCROP1BER (STM32G0_FLASH_REGS_ADDR + 0x38) #define STM32G0_FLASH_SECR (STM32G0_FLASH_REGS_ADDR + 0x80) +// GO FLASH control register +#define STM32G0_FLASH_CR_PG 0 /* Program */ +#define STM32G0_FLASH_CR_PER 1 /* Page erase */ +#define STM32G0_FLASH_CR_MER1 2 /* Mass erase */ +#define STM32G0_FLASH_CR_PNB 3 /* Page number (5 bits) */ +#define STM32G0_FLASH_CR_STRT 16 /* Start */ +#define STM32G0_FLASH_CR_OPTSTRT 17 /* Start of modification of option bytes */ +#define STM32G0_FLASH_CR_FSTPG 18 /* Fast programming */ +#define STM32G0_FLASH_CR_EOPIE 24 /* End of operation interrupt enable */ +#define STM32G0_FLASH_CR_ERRIE 25 /* Error interrupt enable */ +#define STM32G0_FLASH_CR_OBL_LAUNCH 27 /* Forces the option byte loading */ +#define STM32G0_FLASH_CR_OPTLOCK 30 /* Options Lock */ +#define STM32G0_FLASH_CR_LOCK 31 /* FLASH_CR Lock*/ + //32L4 register base is at FLASH_REGS_ADDR (0x40022000) #define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) #define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) @@ -2407,3 +2421,117 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { unmap_file(&mf); return err; } + +/** + * Write option bytes + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { + + uint32_t val; + + if(len != 4) { + ELOG("Wrong length for writting option bytes, must be 4 is %d\n", len); + return -1; + } + + // Make sure we've loaded the context with the chip details + stlink_core_id(sl); + + /* Check if chip is supported and for correct address */ + if((sl->chip_id != STLINK_CHIPID_STM32_G0X1) || (addr != STM32_G0_OPTION_BYTES_BASE)) { + ELOG("Option bytes writing is currently only supported for the STM32G0\n"); + return -1; + } + + /* Unlock flash if necessary (ref manuel page 52) */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + if ((val & (1 << STM32G0_FLASH_CR_LOCK))) { + + /* disable flash write protection. */ + stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0x45670123); + stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0xCDEF89AB); + + // check that the lock is no longer set. + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + if ((val & (1 << STM32G0_FLASH_CR_LOCK))) { + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + } + + /* Unlock option bytes if necessary (ref manuel page 61) */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + if ((val & (1 << STM32G0_FLASH_CR_OPTLOCK))) { + + /* disable option byte write protection. */ + stlink_write_debug32(sl, STM32G0_FLASH_OPTKEYR, 0x08192A3B); + stlink_write_debug32(sl, STM32G0_FLASH_OPTKEYR, 0x4C5D6E7F); + + /* check that the lock is no longer set. */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + if ((val & (1 << STM32G0_FLASH_CR_OPTLOCK))) { + ELOG("Options bytes unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + } + + /* Write options bytes */ + uint32_t data; + write_uint32((unsigned char*) &data, *(uint32_t*) (base)); + WLOG("Writing option bytes 0x%04x\n", data); + //stlink_write_debug32(sl, addr, data); + stlink_write_debug32(sl, STM32G0_FLASH_OPTR, data); + + /* Set Options Start bit */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + val |= (1 << STM32G0_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + + /* Wait for 'busy' bit in FLASH_SR to clear. */ + do { + stlink_read_debug32(sl, STM32G0_FLASH_SR, &val); + } while ((val & (1 << 16)) != 0); + + /* apply options bytes immediate */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + val |= (1 << STM32G0_FLASH_CR_OBL_LAUNCH); + stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + + /* Re-lock option bytes */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + val |= (1 << STM32G0_FLASH_CR_OPTLOCK); + stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + /* Re-lock flash. */ + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + val |= (1 << STM32G0_FLASH_CR_LOCK); + stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + + return 0; +} + +/** + * Write the given binary file with option bytes + * @param sl + * @param path readable file path, should be binary image + * @param addr of the memory mapped option bytes + * @return 0 on success, -ve on failure. + */ +int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr) { + /* write the file in flash at addr */ + int err; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; + + if (map_file(&mf, path) == -1) { + ELOG("map_file() == -1\n"); + return -1; + } + + err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t) mf.len); + stlink_fwrite_finalize(sl, addr); + unmap_file(&mf); + return err; +} diff --git a/src/tools/flash.c b/src/tools/flash.c index 508c4aa84..768e9834f 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -162,6 +162,14 @@ int main(int ac, char** av) goto on_error; } } + else if (o.addr == STM32_G0_OPTION_BYTES_BASE) { + err = stlink_fwrite_option_bytes(sl, o.filename, o.addr); + if (err == -1) + { + printf("stlink_fwrite_option_bytes() == -1\n"); + goto on_error; + } + } else { err = -1; printf("Unknown memory region\n"); From d85cd81e2e7b0938018224382f2a9485b3cdad3d Mon Sep 17 00:00:00 2001 From: William Ransohoff <> Date: Mon, 25 Mar 2019 18:45:53 -0700 Subject: [PATCH 0652/1435] Add simple read/write support for STM32WB55 chips. --- include/stlink.h | 1 + include/stlink/chipid.h | 3 +- src/chipid.c | 11 +++ src/common.c | 161 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 175 insertions(+), 1 deletion(-) diff --git a/include/stlink.h b/include/stlink.h index fedeb1bf4..d5e8270ac 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -77,6 +77,7 @@ extern "C" { STLINK_FLASH_TYPE_L4, STLINK_FLASH_TYPE_F1_XL, STLINK_FLASH_TYPE_G0, + STLINK_FLASH_TYPE_WB }; struct stlink_reg { diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index dda437ce7..a4f4be4c0 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -71,7 +71,8 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F410 = 0x458, STLINK_CHIPID_STM32_F413 = 0x463, STLINK_CHIPID_STM32_L4RX = 0x470, // taken from the STM32L4R9I-DISCO board - STLINK_CHIPID_STM32_G0X1 = 0x460 + STLINK_CHIPID_STM32_G0X1 = 0x460, + STLINK_CHIPID_STM32_WB55 = 0x495 }; /** diff --git a/src/chipid.c b/src/chipid.c index 4e04f00cc..88d727377 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -518,6 +518,17 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 // 30K (table 2) }, + { + // STM32WB55 (from RM0434) + .chip_id = STLINK_CHIPID_STM32_WB55, + .description = "WB55 device", + .flash_type = STLINK_FLASH_TYPE_WB, + .flash_size_reg = 0x1FFF75E0, + .flash_pagesize = 0x1000, // 4K + .sram_size = 0x40000, + .bootrom_base = 0x1fff0000, // See the memory map + .bootrom_size = 0x7000 + }, { // unknown .chip_id = STLINK_CHIPID_UNKNOWN, diff --git a/src/common.c b/src/common.c index 9bb2c2c4e..867284cc2 100644 --- a/src/common.c +++ b/src/common.c @@ -105,6 +105,28 @@ #define STM32G0_FLASH_CR_OPTLOCK 30 /* Options Lock */ #define STM32G0_FLASH_CR_LOCK 31 /* FLASH_CR Lock*/ +// WB (RM0434) +#define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) +#define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) +#define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) +#define STM32WB_FLASH_OPT_KEYR (STM32WB_FLASH_REGS_ADDR + 0x0C) +#define STM32WB_FLASH_SR (STM32WB_FLASH_REGS_ADDR + 0x10) +#define STM32WB_FLASH_CR (STM32WB_FLASH_REGS_ADDR + 0x14) +#define STM32WB_FLASH_ECCR (STM32WB_FLASH_REGS_ADDR + 0x18) +#define STM32WB_FLASH_OPTR (STM32WB_FLASH_REGS_ADDR + 0x20) +#define STM32WB_FLASH_PCROP1ASR (STM32WB_FLASH_REGS_ADDR + 0x24) +#define STM32WB_FLASH_PCROP1AER (STM32WB_FLASH_REGS_ADDR + 0x28) +#define STM32WB_FLASH_WRP1AR (STM32WB_FLASH_REGS_ADDR + 0x2C) +#define STM32WB_FLASH_WRP1BR (STM32WB_FLASH_REGS_ADDR + 0x30) +#define STM32WB_FLASH_PCROP1BSR (STM32WB_FLASH_REGS_ADDR + 0x34) +#define STM32WB_FLASH_PCROP1BER (STM32WB_FLASH_REGS_ADDR + 0x38) +#define STM32WB_FLASH_IPCCBR (STM32WB_FLASH_REGS_ADDR + 0x3C) +#define STM32WB_FLASH_C2ACR (STM32WB_FLASH_REGS_ADDR + 0x5C) +#define STM32WB_FLASH_C2SR (STM32WB_FLASH_REGS_ADDR + 0x60) +#define STM32WB_FLASH_C2CR (STM32WB_FLASH_REGS_ADDR + 0x64) +#define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) +#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) + //32L4 register base is at FLASH_REGS_ADDR (0x40022000) #define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) #define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) @@ -1687,6 +1709,49 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); val |= 0x80000000; stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + // TODO: So far, this looks identical to the G0 logic, and the + // core registers also have the same offsets. + uint32_t val; + /* check if the locks are set */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + if ((val & (1<<31))) { + /* disable flash write protection. */ + stlink_write_debug32(sl, STM32WB_FLASH_KEYR, 0x45670123); + stlink_write_debug32(sl, STM32WB_FLASH_KEYR, 0xCDEF89AB); + /* check that the lock is no longer set. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + if ((val & (1 << 31))) { + WLOG("pecr.pelock not clear (%#x)\n", val); + return -1; + } + } + /* Set PER (erase) bit. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + val |= (1 << 1); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + /* Set the page to erase. */ + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + // sec 3.10.5 - PNB[7:0] is offset by 3. PER is 0x2. + val = ((flash_page & 0xFF) << 3) | (2); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + /* Set the 'start' bit. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + val |= (1 << 16); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + /* Wait for 'busy' bit in FLASH_SR to clear. */ + do { + stlink_read_debug32(sl, STM32WB_FLASH_SR, &val); + } while ((val & (1 << 16)) != 0); + /* Clear PER ('erase enable') bit. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + val &= ~(1 << 1); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + /* Re-lock the flash. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + val |= (1 << 31); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr < FLASH_BANK2_START_ADDR))) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1755,6 +1820,41 @@ int stlink_erase_flash_mass(stlink_t *sl) { fflush(stdout); } fprintf(stdout, "\n"); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + uint32_t val; + /* check if the locks are set */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + if ((val & (1<<31))) { + /* disable flash write protection. */ + stlink_write_debug32(sl, STM32WB_FLASH_KEYR, 0x45670123); + stlink_write_debug32(sl, STM32WB_FLASH_KEYR, 0xCDEF89AB); + /* check that the lock is no longer set. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + if ((val & (1 << 31))) { + WLOG("pecr.pelock not clear (%#x)\n", val); + return -1; + } + } + /* Set MER (mass erase) bit. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + val |= (1 << 2); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + /* Set the 'start' bit. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + val |= (1 << 16); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + /* Wait for 'busy' bit in FLASH_SR to clear. */ + do { + stlink_read_debug32(sl, STM32WB_FLASH_SR, &val); + } while ((val & (1 << 16)) != 0); + /* Clear MER bit. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + val &= ~(1 << 2); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + /* Re-lock the flash. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + val |= (1 << 31); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); } else { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -2084,6 +2184,67 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t val |= 0x80000000; stlink_write_debug32(sl, STM32G0_FLASH_CR, val); } + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + fprintf(stdout, "Writing\r\n"); + fflush(stdout); + uint32_t val; + /* Unlock flash. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + if ((val & (1 << 31))) { + /* disable flash write protection. */ + stlink_write_debug32(sl, STM32WB_FLASH_KEYR, 0x45670123); + stlink_write_debug32(sl, STM32WB_FLASH_KEYR, 0xCDEF89AB); + /* check that the lock is no longer set. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + if ((val & (1 << 31))) { + WLOG("pecr.pelock not clear (%#x)\n", val); + return -1; + } + } + /* Set PG 'allow programming' bit. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + val |= (1 << 0); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + /* Write all words. */ + off = 0; + fprintf(stdout, "Starting %3u page write\r\n", (unsigned int)(len/sl->flash_pgsz)); + fflush(stdout); + for ( ; off < len; off += sizeof(uint32_t)) { + uint32_t data; + if (off > 254) + fprintf(stdout, "\r"); + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) { + fprintf(stdout, "\r%3u/%3u pages written", + (unsigned int)(off/sl->flash_pgsz), + (unsigned int)(len/sl->flash_pgsz)); + fflush(stdout); + } + write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); + stlink_write_debug32(sl, addr + (uint32_t) off, data); + /* Wait for 'busy' bit in FLASH_SR to clear. */ + do { + stlink_read_debug32(sl, STM32WB_FLASH_SR, &val); + } while ((val & (1 << 16)) != 0); + } + /* (Flash writes happen 2 words at a time.) */ + if ((off / sizeof(uint32_t)) % 2 != 0) { + /* Write a single word of zeros. */ + stlink_write_debug32(sl, addr + (uint32_t) off, 0); + /* Wait for 'busy' bit in FLASH_SR to clear. */ + do { + stlink_read_debug32(sl, STM32WB_FLASH_SR, &val); + } while ((val & (1 << 16)) != 0); + } + /* Reset PG bit. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + val &= ~(1 << 0); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + /* Re-lock flash. */ + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + val |= (1 << 31); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { /* use fast word write. todo: half page. */ uint32_t val; From d21471650543cc9071ed3821298bcd8c35f5a603 Mon Sep 17 00:00:00 2001 From: William Ransohoff <> Date: Sun, 31 Mar 2019 09:28:45 -0700 Subject: [PATCH 0653/1435] Clean up and unify G0/WB erase/program operations. --- src/common.c | 352 +++++++++++++++++++-------------------------------- 1 file changed, 133 insertions(+), 219 deletions(-) diff --git a/src/common.c b/src/common.c index 867284cc2..b46b6ea87 100644 --- a/src/common.c +++ b/src/common.c @@ -103,7 +103,9 @@ #define STM32G0_FLASH_CR_ERRIE 25 /* Error interrupt enable */ #define STM32G0_FLASH_CR_OBL_LAUNCH 27 /* Forces the option byte loading */ #define STM32G0_FLASH_CR_OPTLOCK 30 /* Options Lock */ -#define STM32G0_FLASH_CR_LOCK 31 /* FLASH_CR Lock*/ +#define STM32G0_FLASH_CR_LOCK 31 /* FLASH_CR Lock */ +// GO FLASH status register +#define STM32G0_FLASH_SR_BSY 16 /* FLASH_SR Busy */ // WB (RM0434) #define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) @@ -127,6 +129,12 @@ #define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) #define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) +// WB Flash control register. +#define STM32WB_FLASH_CR_STRT (16) /* FLASH_CR Start */ +#define STM32WB_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ +// WB Flash status register. +#define STM32WB_FLASH_SR_BSY (16) /* FLASH_SR Busy */ + //32L4 register base is at FLASH_REGS_ADDR (0x40022000) #define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) #define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) @@ -241,6 +249,10 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { reg = FLASH_F4_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) reg = STM32L4_FLASH_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0) + reg = STM32G0_FLASH_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + reg = STM32WB_FLASH_CR; else reg = FLASH_CR; @@ -269,6 +281,10 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { cr_lock_shift = FLASH_F4_CR_LOCK; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) cr_lock_shift = STM32L4_FLASH_CR_LOCK; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0) + cr_lock_shift = STM32G0_FLASH_CR_LOCK; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + cr_lock_shift = STM32WB_FLASH_CR_LOCK; else cr_lock_shift = FLASH_CR_LOCK; @@ -286,6 +302,10 @@ static void unlock_flash(stlink_t *sl) { key_reg = FLASH_F4_KEYR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) key_reg = STM32L4_FLASH_KEYR; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0) + key_reg = STM32G0_FLASH_KEYR; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + key_reg = STM32WB_FLASH_KEYR; else key_reg = FLASH_KEYR; @@ -321,6 +341,12 @@ static void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + cr_reg = STM32G0_FLASH_CR; + cr_lock_shift = STM32G0_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_lock_shift = STM32WB_FLASH_CR_LOCK; } else { cr_reg = FLASH_CR; cr_lock_shift = FLASH_CR_LOCK; @@ -348,6 +374,12 @@ static void set_flash_cr_pg(stlink_t *sl) { cr_reg = STM32L4_FLASH_CR; x &= ~STM32L4_FLASH_CR_OPBITS; x |= 1 << STM32L4_FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + cr_reg = STM32G0_FLASH_CR; + x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + x |= (1 << FLASH_CR_PG); } else { cr_reg = FLASH_CR; x = 1 << FLASH_CR_PG; @@ -363,6 +395,10 @@ static void clear_flash_cr_pg(stlink_t *sl) { cr_reg = FLASH_F4_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) cr_reg = STM32L4_FLASH_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0) + cr_reg = STM32G0_FLASH_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + cr_reg = STM32WB_FLASH_CR; else cr_reg = FLASH_CR; @@ -371,8 +407,18 @@ static void clear_flash_cr_pg(stlink_t *sl) { } static void set_flash_cr_per(stlink_t *sl) { - const uint32_t n = 1 << FLASH_CR_PER; - stlink_write_debug32(sl, FLASH_CR, n); + uint32_t cr_reg, val; + + if (sl->flash_type == STLINK_FLASH_TYPE_G0) + cr_reg = STM32G0_FLASH_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + cr_reg = STM32WB_FLASH_CR; + else + cr_reg = FLASH_CR; + + stlink_read_debug32(sl, cr_reg, &val); + val |= (1 << FLASH_CR_PER); + stlink_write_debug32(sl, cr_reg, val); } static void set_flash_cr2_per(stlink_t *sl) { @@ -380,9 +426,18 @@ static void set_flash_cr2_per(stlink_t *sl) { stlink_write_debug32(sl, FLASH_CR2, n); } -static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { +static void clear_flash_cr_per(stlink_t *sl) { + uint32_t cr_reg; + + if (sl->flash_type == STLINK_FLASH_TYPE_G0) + cr_reg = STM32G0_FLASH_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + cr_reg = STM32WB_FLASH_CR; + else + cr_reg = FLASH_CR; + const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PER); - stlink_write_debug32(sl, FLASH_CR, n); + stlink_write_debug32(sl, cr_reg, n); } static void set_flash_cr_mer(stlink_t *sl, bool v) { @@ -396,6 +451,14 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); cr_pg = 1 << STM32L4_FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + cr_reg = STM32G0_FLASH_CR; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); } else { cr_reg = FLASH_CR; cr_mer = 1 << FLASH_CR_MER; @@ -458,6 +521,12 @@ static void set_flash_cr_strt(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_strt = 1 << STM32L4_FLASH_CR_STRT; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + cr_reg = STM32G0_FLASH_CR; + cr_strt = 1 << STM32G0_FLASH_CR_STRT; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_strt = 1 << STM32WB_FLASH_CR_STRT; } else { cr_reg = FLASH_CR; cr_strt = 1 << FLASH_CR_STRT; @@ -483,6 +552,10 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { sr_reg = FLASH_F4_SR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) sr_reg = STM32L4_FLASH_SR; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0) + sr_reg = STM32G0_FLASH_SR; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + sr_reg = STM32WB_FLASH_SR; else sr_reg = FLASH_SR; @@ -505,6 +578,10 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { sr_busy_shift = FLASH_F4_SR_BSY; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) sr_busy_shift = STM32L4_FLASH_SR_BSY; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0) + sr_busy_shift = STM32G0_FLASH_SR_BSY; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + sr_busy_shift = STM32WB_FLASH_SR_BSY; else sr_busy_shift = FLASH_SR_BSY; @@ -1668,90 +1745,39 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { - uint32_t val; - /* check if the locks are set */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - if ((val & (1<<31))) { - /* disable flash write protection. */ - stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0x45670123); - stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0xCDEF89AB); - /* check that the lock is no longer set. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - if ((val & (1 << 31))) { - WLOG("pecr.pelock not clear (%#x)\n", val); - return -1; - } - } - /* Set PER (erase) bit. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= 0x00000002; - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); - /* Set the page to erase. */ - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. - val = ((flash_page & 0x3F) << 3) | (2); - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); - /* Set the 'start' bit. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= (1 << 16); - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); - /* Wait for 'busy' bit in FLASH_SR to clear. */ - do { - stlink_read_debug32(sl, STM32G0_FLASH_SR, &val); - } while ((val & (1 << 16)) != 0); - /* Clear PER ('erase enable') bit. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val &= ~(0x00000002); - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); - /* Re-lock the flash. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= 0x80000000; - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - // TODO: So far, this looks identical to the G0 logic, and the - // core registers also have the same offsets. + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0) { uint32_t val; - /* check if the locks are set */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - if ((val & (1<<31))) { - /* disable flash write protection. */ - stlink_write_debug32(sl, STM32WB_FLASH_KEYR, 0x45670123); - stlink_write_debug32(sl, STM32WB_FLASH_KEYR, 0xCDEF89AB); - /* check that the lock is no longer set. */ + // Wait for any ongoing Flash operation to finish. + wait_flash_busy(sl); + // Unlock Flash if necessary. + unlock_flash_if(sl); + // Set the 'enable Flash erase' bit. + set_flash_cr_per(sl); + + // Set the page to erase. + if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - if ((val & (1 << 31))) { - WLOG("pecr.pelock not clear (%#x)\n", val); - return -1; - } + // sec 3.10.5 - PNB[7:0] is offset by 3. + val |= ((flash_page & 0xFF) << 3); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); + stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. + val |= ((flash_page & 0x3F) << 3); + stlink_write_debug32(sl, STM32G0_FLASH_CR, val); } - /* Set PER (erase) bit. */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - val |= (1 << 1); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - /* Set the page to erase. */ - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - // sec 3.10.5 - PNB[7:0] is offset by 3. PER is 0x2. - val = ((flash_page & 0xFF) << 3) | (2); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - /* Set the 'start' bit. */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - val |= (1 << 16); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - /* Wait for 'busy' bit in FLASH_SR to clear. */ - do { - stlink_read_debug32(sl, STM32WB_FLASH_SR, &val); - } while ((val & (1 << 16)) != 0); - /* Clear PER ('erase enable') bit. */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - val &= ~(1 << 1); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - /* Re-lock the flash. */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - val |= (1 << 31); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + + // Set the 'start operation' bit. + set_flash_cr_strt(sl); + // Wait for the 'busy' bit to clear. + wait_flash_busy(sl); + // Clear the 'enable page erase' bit. + clear_flash_cr_per(sl); + // Re-lock the flash. + lock_flash(sl); } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr < FLASH_BANK2_START_ADDR))) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1805,8 +1831,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } int stlink_erase_flash_mass(stlink_t *sl) { - /* TODO: User MER bit to mass-erase G0 series. */ - if (sl->flash_type == STLINK_FLASH_TYPE_L0 || sl->flash_type == STLINK_FLASH_TYPE_G0) { + /* TODO: User MER bit to mass-erase G0, WB series. */ + if (sl->flash_type == STLINK_FLASH_TYPE_L0 || sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_WB) { /* erase each page */ int i = 0, num_pages = (int) sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -1820,41 +1846,6 @@ int stlink_erase_flash_mass(stlink_t *sl) { fflush(stdout); } fprintf(stdout, "\n"); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - uint32_t val; - /* check if the locks are set */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - if ((val & (1<<31))) { - /* disable flash write protection. */ - stlink_write_debug32(sl, STM32WB_FLASH_KEYR, 0x45670123); - stlink_write_debug32(sl, STM32WB_FLASH_KEYR, 0xCDEF89AB); - /* check that the lock is no longer set. */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - if ((val & (1 << 31))) { - WLOG("pecr.pelock not clear (%#x)\n", val); - return -1; - } - } - /* Set MER (mass erase) bit. */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - val |= (1 << 2); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - /* Set the 'start' bit. */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - val |= (1 << 16); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - /* Wait for 'busy' bit in FLASH_SR to clear. */ - do { - stlink_read_debug32(sl, STM32WB_FLASH_SR, &val); - } while ((val & (1 << 16)) != 0); - /* Clear MER bit. */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - val &= ~(1 << 2); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - /* Re-lock the flash. */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - val |= (1 << 31); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); } else { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -2126,86 +2117,17 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t lock_flash(sl); } //STM32F4END - else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { - uint32_t val; - /* Unlock flash. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - if ((val & (1<<31))) { - /* disable flash write protection. */ - stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0x45670123); - stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0xCDEF89AB); - /* check that the lock is no longer set. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - if ((val & (1 << 31))) { - WLOG("pecr.pelock not clear (%#x)\n", val); - return -1; - } - } - /* Set PG 'allow programming' bit. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= 0x00000001; - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); - /* Write all words. */ - off = 0; - for ( ; off < len; off += sizeof(uint32_t)) { - uint32_t data; - if (off > 254) - fprintf(stdout, "\r"); - - if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) { - fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off/sl->flash_pgsz), - (unsigned int)(len/sl->flash_pgsz)); - fflush(stdout); - } - write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); - stlink_write_debug32(sl, addr + (uint32_t) off, data); - /* Wait for 'busy' bit in FLASH_SR to clear. */ - do { - stlink_read_debug32(sl, STM32G0_FLASH_SR, &val); - } while ((val & (1 << 16)) != 0); - } - /* Do we need a dummy write? See sec 3.3.8 of RM0444. */ - /* (Flash writes happen 2 words at a time.) */ - if ((off / sizeof(uint32_t)) % 2 != 0) { - /* Write a single word of zeros. */ - stlink_write_debug32(sl, addr + (uint32_t) off, 0); - /* Wait for 'busy' bit in FLASH_SR to clear. */ - do { - stlink_read_debug32(sl, STM32G0_FLASH_SR, &val); - } while ((val & (1 << 16)) != 0); - } - /* Reset PG bit. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val &= ~(0x00000001); - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); - /* Re-lock flash. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= 0x80000000; - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); - } - else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0) { fprintf(stdout, "Writing\r\n"); fflush(stdout); - uint32_t val; - /* Unlock flash. */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - if ((val & (1 << 31))) { - /* disable flash write protection. */ - stlink_write_debug32(sl, STM32WB_FLASH_KEYR, 0x45670123); - stlink_write_debug32(sl, STM32WB_FLASH_KEYR, 0xCDEF89AB); - /* check that the lock is no longer set. */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - if ((val & (1 << 31))) { - WLOG("pecr.pelock not clear (%#x)\n", val); - return -1; - } - } - /* Set PG 'allow programming' bit. */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - val |= (1 << 0); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - /* Write all words. */ + // Wait for any ongoing operations to finish. + wait_flash_busy(sl); + // Unlock flash if necessary. + unlock_flash_if(sl); + // Set PG 'allow programming' bit. + set_flash_cr_pg(sl); + // Write all words. off = 0; fprintf(stdout, "Starting %3u page write\r\n", (unsigned int)(len/sl->flash_pgsz)); fflush(stdout); @@ -2222,28 +2144,20 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); stlink_write_debug32(sl, addr + (uint32_t) off, data); - /* Wait for 'busy' bit in FLASH_SR to clear. */ - do { - stlink_read_debug32(sl, STM32WB_FLASH_SR, &val); - } while ((val & (1 << 16)) != 0); + // Wait for 'busy' bit in FLASH_SR to clear. + wait_flash_busy(sl); } - /* (Flash writes happen 2 words at a time.) */ + // (Flash writes happen 2 words at a time.) if ((off / sizeof(uint32_t)) % 2 != 0) { - /* Write a single word of zeros. */ + // Write a single word of zeros. stlink_write_debug32(sl, addr + (uint32_t) off, 0); - /* Wait for 'busy' bit in FLASH_SR to clear. */ - do { - stlink_read_debug32(sl, STM32WB_FLASH_SR, &val); - } while ((val & (1 << 16)) != 0); + // Wait for 'busy' bit in FLASH_SR to clear. + wait_flash_busy(sl); } - /* Reset PG bit. */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - val &= ~(1 << 0); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - /* Re-lock flash. */ - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - val |= (1 << 31); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + // Reset PG bit. + clear_flash_cr_pg(sl); + // Re-lock flash. + lock_flash(sl); } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { /* use fast word write. todo: half page. */ From 4ff515ef6881cd0466004ae5673f041c9a060c58 Mon Sep 17 00:00:00 2001 From: WRansohoff Date: Sun, 31 Mar 2019 09:41:57 -0700 Subject: [PATCH 0654/1435] Add simple read/write support for STM32WB55 chips. (#786) * Add simple read/write support for STM32WB55 chips. * Clean up and unify G0/WB erase/program operations. --- include/stlink.h | 1 + include/stlink/chipid.h | 3 +- src/chipid.c | 11 ++ src/common.c | 243 ++++++++++++++++++++++++++-------------- 4 files changed, 173 insertions(+), 85 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index fedeb1bf4..d5e8270ac 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -77,6 +77,7 @@ extern "C" { STLINK_FLASH_TYPE_L4, STLINK_FLASH_TYPE_F1_XL, STLINK_FLASH_TYPE_G0, + STLINK_FLASH_TYPE_WB }; struct stlink_reg { diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index dda437ce7..a4f4be4c0 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -71,7 +71,8 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F410 = 0x458, STLINK_CHIPID_STM32_F413 = 0x463, STLINK_CHIPID_STM32_L4RX = 0x470, // taken from the STM32L4R9I-DISCO board - STLINK_CHIPID_STM32_G0X1 = 0x460 + STLINK_CHIPID_STM32_G0X1 = 0x460, + STLINK_CHIPID_STM32_WB55 = 0x495 }; /** diff --git a/src/chipid.c b/src/chipid.c index 4e04f00cc..88d727377 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -518,6 +518,17 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 // 30K (table 2) }, + { + // STM32WB55 (from RM0434) + .chip_id = STLINK_CHIPID_STM32_WB55, + .description = "WB55 device", + .flash_type = STLINK_FLASH_TYPE_WB, + .flash_size_reg = 0x1FFF75E0, + .flash_pagesize = 0x1000, // 4K + .sram_size = 0x40000, + .bootrom_base = 0x1fff0000, // See the memory map + .bootrom_size = 0x7000 + }, { // unknown .chip_id = STLINK_CHIPID_UNKNOWN, diff --git a/src/common.c b/src/common.c index 9bb2c2c4e..b46b6ea87 100644 --- a/src/common.c +++ b/src/common.c @@ -103,7 +103,37 @@ #define STM32G0_FLASH_CR_ERRIE 25 /* Error interrupt enable */ #define STM32G0_FLASH_CR_OBL_LAUNCH 27 /* Forces the option byte loading */ #define STM32G0_FLASH_CR_OPTLOCK 30 /* Options Lock */ -#define STM32G0_FLASH_CR_LOCK 31 /* FLASH_CR Lock*/ +#define STM32G0_FLASH_CR_LOCK 31 /* FLASH_CR Lock */ +// GO FLASH status register +#define STM32G0_FLASH_SR_BSY 16 /* FLASH_SR Busy */ + +// WB (RM0434) +#define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) +#define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) +#define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) +#define STM32WB_FLASH_OPT_KEYR (STM32WB_FLASH_REGS_ADDR + 0x0C) +#define STM32WB_FLASH_SR (STM32WB_FLASH_REGS_ADDR + 0x10) +#define STM32WB_FLASH_CR (STM32WB_FLASH_REGS_ADDR + 0x14) +#define STM32WB_FLASH_ECCR (STM32WB_FLASH_REGS_ADDR + 0x18) +#define STM32WB_FLASH_OPTR (STM32WB_FLASH_REGS_ADDR + 0x20) +#define STM32WB_FLASH_PCROP1ASR (STM32WB_FLASH_REGS_ADDR + 0x24) +#define STM32WB_FLASH_PCROP1AER (STM32WB_FLASH_REGS_ADDR + 0x28) +#define STM32WB_FLASH_WRP1AR (STM32WB_FLASH_REGS_ADDR + 0x2C) +#define STM32WB_FLASH_WRP1BR (STM32WB_FLASH_REGS_ADDR + 0x30) +#define STM32WB_FLASH_PCROP1BSR (STM32WB_FLASH_REGS_ADDR + 0x34) +#define STM32WB_FLASH_PCROP1BER (STM32WB_FLASH_REGS_ADDR + 0x38) +#define STM32WB_FLASH_IPCCBR (STM32WB_FLASH_REGS_ADDR + 0x3C) +#define STM32WB_FLASH_C2ACR (STM32WB_FLASH_REGS_ADDR + 0x5C) +#define STM32WB_FLASH_C2SR (STM32WB_FLASH_REGS_ADDR + 0x60) +#define STM32WB_FLASH_C2CR (STM32WB_FLASH_REGS_ADDR + 0x64) +#define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) +#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) + +// WB Flash control register. +#define STM32WB_FLASH_CR_STRT (16) /* FLASH_CR Start */ +#define STM32WB_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ +// WB Flash status register. +#define STM32WB_FLASH_SR_BSY (16) /* FLASH_SR Busy */ //32L4 register base is at FLASH_REGS_ADDR (0x40022000) #define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) @@ -219,6 +249,10 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { reg = FLASH_F4_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) reg = STM32L4_FLASH_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0) + reg = STM32G0_FLASH_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + reg = STM32WB_FLASH_CR; else reg = FLASH_CR; @@ -247,6 +281,10 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { cr_lock_shift = FLASH_F4_CR_LOCK; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) cr_lock_shift = STM32L4_FLASH_CR_LOCK; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0) + cr_lock_shift = STM32G0_FLASH_CR_LOCK; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + cr_lock_shift = STM32WB_FLASH_CR_LOCK; else cr_lock_shift = FLASH_CR_LOCK; @@ -264,6 +302,10 @@ static void unlock_flash(stlink_t *sl) { key_reg = FLASH_F4_KEYR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) key_reg = STM32L4_FLASH_KEYR; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0) + key_reg = STM32G0_FLASH_KEYR; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + key_reg = STM32WB_FLASH_KEYR; else key_reg = FLASH_KEYR; @@ -299,6 +341,12 @@ static void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + cr_reg = STM32G0_FLASH_CR; + cr_lock_shift = STM32G0_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_lock_shift = STM32WB_FLASH_CR_LOCK; } else { cr_reg = FLASH_CR; cr_lock_shift = FLASH_CR_LOCK; @@ -326,6 +374,12 @@ static void set_flash_cr_pg(stlink_t *sl) { cr_reg = STM32L4_FLASH_CR; x &= ~STM32L4_FLASH_CR_OPBITS; x |= 1 << STM32L4_FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + cr_reg = STM32G0_FLASH_CR; + x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + x |= (1 << FLASH_CR_PG); } else { cr_reg = FLASH_CR; x = 1 << FLASH_CR_PG; @@ -341,6 +395,10 @@ static void clear_flash_cr_pg(stlink_t *sl) { cr_reg = FLASH_F4_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) cr_reg = STM32L4_FLASH_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0) + cr_reg = STM32G0_FLASH_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + cr_reg = STM32WB_FLASH_CR; else cr_reg = FLASH_CR; @@ -349,8 +407,18 @@ static void clear_flash_cr_pg(stlink_t *sl) { } static void set_flash_cr_per(stlink_t *sl) { - const uint32_t n = 1 << FLASH_CR_PER; - stlink_write_debug32(sl, FLASH_CR, n); + uint32_t cr_reg, val; + + if (sl->flash_type == STLINK_FLASH_TYPE_G0) + cr_reg = STM32G0_FLASH_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + cr_reg = STM32WB_FLASH_CR; + else + cr_reg = FLASH_CR; + + stlink_read_debug32(sl, cr_reg, &val); + val |= (1 << FLASH_CR_PER); + stlink_write_debug32(sl, cr_reg, val); } static void set_flash_cr2_per(stlink_t *sl) { @@ -358,9 +426,18 @@ static void set_flash_cr2_per(stlink_t *sl) { stlink_write_debug32(sl, FLASH_CR2, n); } -static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { +static void clear_flash_cr_per(stlink_t *sl) { + uint32_t cr_reg; + + if (sl->flash_type == STLINK_FLASH_TYPE_G0) + cr_reg = STM32G0_FLASH_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + cr_reg = STM32WB_FLASH_CR; + else + cr_reg = FLASH_CR; + const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PER); - stlink_write_debug32(sl, FLASH_CR, n); + stlink_write_debug32(sl, cr_reg, n); } static void set_flash_cr_mer(stlink_t *sl, bool v) { @@ -374,6 +451,14 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); cr_pg = 1 << STM32L4_FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + cr_reg = STM32G0_FLASH_CR; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); } else { cr_reg = FLASH_CR; cr_mer = 1 << FLASH_CR_MER; @@ -436,6 +521,12 @@ static void set_flash_cr_strt(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_strt = 1 << STM32L4_FLASH_CR_STRT; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + cr_reg = STM32G0_FLASH_CR; + cr_strt = 1 << STM32G0_FLASH_CR_STRT; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_strt = 1 << STM32WB_FLASH_CR_STRT; } else { cr_reg = FLASH_CR; cr_strt = 1 << FLASH_CR_STRT; @@ -461,6 +552,10 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { sr_reg = FLASH_F4_SR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) sr_reg = STM32L4_FLASH_SR; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0) + sr_reg = STM32G0_FLASH_SR; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + sr_reg = STM32WB_FLASH_SR; else sr_reg = FLASH_SR; @@ -483,6 +578,10 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { sr_busy_shift = FLASH_F4_SR_BSY; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) sr_busy_shift = STM32L4_FLASH_SR_BSY; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0) + sr_busy_shift = STM32G0_FLASH_SR_BSY; + else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + sr_busy_shift = STM32WB_FLASH_SR_BSY; else sr_busy_shift = FLASH_SR_BSY; @@ -1646,47 +1745,39 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0) { uint32_t val; - /* check if the locks are set */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - if ((val & (1<<31))) { - /* disable flash write protection. */ - stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0x45670123); - stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0xCDEF89AB); - /* check that the lock is no longer set. */ + // Wait for any ongoing Flash operation to finish. + wait_flash_busy(sl); + // Unlock Flash if necessary. + unlock_flash_if(sl); + // Set the 'enable Flash erase' bit. + set_flash_cr_per(sl); + + // Set the page to erase. + if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + // sec 3.10.5 - PNB[7:0] is offset by 3. + val |= ((flash_page & 0xFF) << 3); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - if ((val & (1 << 31))) { - WLOG("pecr.pelock not clear (%#x)\n", val); - return -1; - } + // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. + val |= ((flash_page & 0x3F) << 3); + stlink_write_debug32(sl, STM32G0_FLASH_CR, val); } - /* Set PER (erase) bit. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= 0x00000002; - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); - /* Set the page to erase. */ - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. - val = ((flash_page & 0x3F) << 3) | (2); - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); - /* Set the 'start' bit. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= (1 << 16); - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); - /* Wait for 'busy' bit in FLASH_SR to clear. */ - do { - stlink_read_debug32(sl, STM32G0_FLASH_SR, &val); - } while ((val & (1 << 16)) != 0); - /* Clear PER ('erase enable') bit. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val &= ~(0x00000002); - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); - /* Re-lock the flash. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= 0x80000000; - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + + // Set the 'start operation' bit. + set_flash_cr_strt(sl); + // Wait for the 'busy' bit to clear. + wait_flash_busy(sl); + // Clear the 'enable page erase' bit. + clear_flash_cr_per(sl); + // Re-lock the flash. + lock_flash(sl); } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr < FLASH_BANK2_START_ADDR))) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1740,8 +1831,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } int stlink_erase_flash_mass(stlink_t *sl) { - /* TODO: User MER bit to mass-erase G0 series. */ - if (sl->flash_type == STLINK_FLASH_TYPE_L0 || sl->flash_type == STLINK_FLASH_TYPE_G0) { + /* TODO: User MER bit to mass-erase G0, WB series. */ + if (sl->flash_type == STLINK_FLASH_TYPE_L0 || sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_WB) { /* erase each page */ int i = 0, num_pages = (int) sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -2026,27 +2117,20 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t lock_flash(sl); } //STM32F4END - else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { - uint32_t val; - /* Unlock flash. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - if ((val & (1<<31))) { - /* disable flash write protection. */ - stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0x45670123); - stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0xCDEF89AB); - /* check that the lock is no longer set. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - if ((val & (1 << 31))) { - WLOG("pecr.pelock not clear (%#x)\n", val); - return -1; - } - } - /* Set PG 'allow programming' bit. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= 0x00000001; - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); - /* Write all words. */ + else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0) { + fprintf(stdout, "Writing\r\n"); + fflush(stdout); + // Wait for any ongoing operations to finish. + wait_flash_busy(sl); + // Unlock flash if necessary. + unlock_flash_if(sl); + // Set PG 'allow programming' bit. + set_flash_cr_pg(sl); + // Write all words. off = 0; + fprintf(stdout, "Starting %3u page write\r\n", (unsigned int)(len/sl->flash_pgsz)); + fflush(stdout); for ( ; off < len; off += sizeof(uint32_t)) { uint32_t data; if (off > 254) @@ -2060,29 +2144,20 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); stlink_write_debug32(sl, addr + (uint32_t) off, data); - /* Wait for 'busy' bit in FLASH_SR to clear. */ - do { - stlink_read_debug32(sl, STM32G0_FLASH_SR, &val); - } while ((val & (1 << 16)) != 0); + // Wait for 'busy' bit in FLASH_SR to clear. + wait_flash_busy(sl); } - /* Do we need a dummy write? See sec 3.3.8 of RM0444. */ - /* (Flash writes happen 2 words at a time.) */ + // (Flash writes happen 2 words at a time.) if ((off / sizeof(uint32_t)) % 2 != 0) { - /* Write a single word of zeros. */ + // Write a single word of zeros. stlink_write_debug32(sl, addr + (uint32_t) off, 0); - /* Wait for 'busy' bit in FLASH_SR to clear. */ - do { - stlink_read_debug32(sl, STM32G0_FLASH_SR, &val); - } while ((val & (1 << 16)) != 0); + // Wait for 'busy' bit in FLASH_SR to clear. + wait_flash_busy(sl); } - /* Reset PG bit. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val &= ~(0x00000001); - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); - /* Re-lock flash. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= 0x80000000; - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + // Reset PG bit. + clear_flash_cr_pg(sl); + // Re-lock flash. + lock_flash(sl); } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { /* use fast word write. todo: half page. */ From 224f6eee2a9044b87bffdbc746a3ecba9a07ff34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20M=C3=A1rton?= Date: Wed, 3 Apr 2019 13:00:18 +0200 Subject: [PATCH 0655/1435] Add STLink V3SET VID:PIDs to the udev rules (#789) --- etc/udev/rules.d/49-stlinkv3.rules | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 etc/udev/rules.d/49-stlinkv3.rules diff --git a/etc/udev/rules.d/49-stlinkv3.rules b/etc/udev/rules.d/49-stlinkv3.rules new file mode 100644 index 000000000..5161947a9 --- /dev/null +++ b/etc/udev/rules.d/49-stlinkv3.rules @@ -0,0 +1,29 @@ +# STLink V3SET in Dual CDC mode +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3752", \ + MODE:="0666", \ + SYMLINK+="stlinkv3_%n" + +# STLink V3SET in Dual CDC mode +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3753", \ + MODE:="0666", \ + SYMLINK+="stlinkv3_%n" + +# STLink V3SET +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374d", \ + MODE:="0666", \ + SYMLINK+="stlinkv3_%n" + +# STLink V3SET +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374e", \ + MODE:="0666", \ + SYMLINK+="stlinkv3_%n" + +# STLink V3SET in normal mode +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374f", \ + MODE:="0666", \ + SYMLINK+="stlinkv3_%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. From feb86618fa3e45c3e15851863fce20ee14cd76d9 Mon Sep 17 00:00:00 2001 From: Kirill Zhumarin Date: Sat, 13 Apr 2019 13:07:58 +0300 Subject: [PATCH 0656/1435] Support for "STM32+Audio" v2-1 firmware (#790) * Add pid for "STM32+Audio" v2-1 firmware * Add support for "STM32+Audio" v2-1 firmware,. * Add udev rules for "STM32+Audio" firmware --- etc/udev/rules.d/49-stlinkv2-1.rules | 4 ++++ include/stlink/usb.h | 9 +++++---- src/usb.c | 8 +++++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/etc/udev/rules.d/49-stlinkv2-1.rules b/etc/udev/rules.d/49-stlinkv2-1.rules index a5a79b91c..15a797a05 100644 --- a/etc/udev/rules.d/49-stlinkv2-1.rules +++ b/etc/udev/rules.d/49-stlinkv2-1.rules @@ -2,6 +2,10 @@ # ie, STM32F0, STM32F4. # STM32VL has st/linkv1, which is quite different +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374a", \ + MODE:="0666", \ + SYMLINK+="stlinkv2-1_%n" + SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", \ MODE:="0666", \ SYMLINK+="stlinkv2-1_%n" diff --git a/include/stlink/usb.h b/include/stlink/usb.h index 46e7419cf..9e27db156 100644 --- a/include/stlink/usb.h +++ b/include/stlink/usb.h @@ -18,10 +18,11 @@ extern "C" { #endif -#define STLINK_USB_VID_ST 0x0483 -#define STLINK_USB_PID_STLINK 0x3744 -#define STLINK_USB_PID_STLINK_32L 0x3748 -#define STLINK_USB_PID_STLINK_NUCLEO 0x374b +#define STLINK_USB_VID_ST 0x0483 +#define STLINK_USB_PID_STLINK 0x3744 +#define STLINK_USB_PID_STLINK_32L 0x3748 +#define STLINK_USB_PID_STLINK_32L_AUDIO 0x374a +#define STLINK_USB_PID_STLINK_NUCLEO 0x374b #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 diff --git a/src/usb.c b/src/usb.c index 66f065ab8..c4d39ac5f 100644 --- a/src/usb.c +++ b/src/usb.c @@ -827,7 +827,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 } } - if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) || (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO)) { + if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) || (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) || (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO)) { struct libusb_device_handle *handle; ret = libusb_open(list[cnt], &handle); @@ -901,7 +901,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16 // TODO - could use the scanning techniq from stm8 code here... slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; - if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) { + if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO || desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO) { slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; } else { slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; @@ -973,6 +973,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { } if (desc.idProduct != STLINK_USB_PID_STLINK_32L && + desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO) continue; @@ -996,7 +997,8 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { break; } - if (desc.idProduct != STLINK_USB_PID_STLINK_32L && + if (desc.idProduct != STLINK_USB_PID_STLINK_32L && + desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO) continue; From 2117226105187d75ce05a3a8ebed9e2a42793b17 Mon Sep 17 00:00:00 2001 From: William Ransohoff <> Date: Thu, 25 Apr 2019 22:14:23 -0700 Subject: [PATCH 0657/1435] Fix apparent issue with STM32G0 flashing. --- src/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index b46b6ea87..63de8415c 100644 --- a/src/common.c +++ b/src/common.c @@ -1766,7 +1766,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. - val |= ((flash_page & 0x3F) << 3); + val = ((flash_page & 0x3F) << 3) | ( 1 << FLASH_CR_PER ); stlink_write_debug32(sl, STM32G0_FLASH_CR, val); } From cf677803d0fdfcb001a55ca04f8ee36a5836d3f1 Mon Sep 17 00:00:00 2001 From: WRansohoff Date: Thu, 25 Apr 2019 23:00:30 -0700 Subject: [PATCH 0658/1435] Fix apparent STM32G0 flashing issue. (#797) * Add simple read/write support for STM32WB55 chips. * Clean up and unify G0/WB erase/program operations. * Fix apparent issue with STM32G0 flashing. --- src/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index b46b6ea87..63de8415c 100644 --- a/src/common.c +++ b/src/common.c @@ -1766,7 +1766,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. - val |= ((flash_page & 0x3F) << 3); + val = ((flash_page & 0x3F) << 3) | ( 1 << FLASH_CR_PER ); stlink_write_debug32(sl, STM32G0_FLASH_CR, val); } From 189f253ce3f9a6a39d0ebf7b2b5c23defddd757c Mon Sep 17 00:00:00 2001 From: Eli Krumholz Date: Mon, 6 May 2019 12:36:26 -0500 Subject: [PATCH 0659/1435] initial support for STM32L41X (#799) --- src/chipid.c | 14 ++++++++++++++ src/flash_loader.c | 1 + 2 files changed, 15 insertions(+) diff --git a/src/chipid.c b/src/chipid.c index 88d727377..d627849a3 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -453,6 +453,20 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, // 3.3.1, pg 99 .bootrom_size = 0x7000 // 28k (per bank), same source as base (pg 99) }, + { + // STLINK_CHIPID_STM32_L41X + // From RM0394 Rev 4 and DS12469 Rev 5 + .chip_id = STLINK_CHIPID_STM32_L41X, + .description = "L41x device", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, sec 47.2, page 1586) + .flash_pagesize = 0x800, // 2K (DS12469, sec 3.4, page 17) + // SRAM1 is 32k at 0x20000000 + // SRAM2 is 8k at 0x10000000 and 0x20008000 (DS12469, sec 3.5, page 18) + .sram_size = 0xa000, // 40K (DS12469, sec 3.5, page 18) + .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) + .bootrom_size = 0x7000 // 28k, same source as base + }, { // STLINK_CHIPID_STM32_L43X // From RM0392. diff --git a/src/flash_loader.c b/src/flash_loader.c index 7684680a7..f2e636751 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -306,6 +306,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); } else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || + (sl->chip_id == STLINK_CHIPID_STM32_L41X) || (sl->chip_id == STLINK_CHIPID_STM32_L43X) || (sl->chip_id == STLINK_CHIPID_STM32_L46X) || (sl->chip_id == STLINK_CHIPID_STM32_L4RX) || From a3cb1a1569f2e0eea5e558924db8155c759cbc86 Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Sat, 11 May 2019 20:41:57 +0300 Subject: [PATCH 0660/1435] build wor windows under Debian/Ubuntu (#802) --- CMakeLists.txt | 1 + cmake/linux-mingw32.cmake | 25 +++++++++++++++++++++++++ cmake/linux-mingw64.cmake | 25 +++++++++++++++++++++++++ cmake/modules/Find7Zip.cmake | 2 +- cmake/modules/FindLibUSB.cmake | 29 ++++++++++++++++++++++++----- doc/compiling.md | 21 +++++++++++++++++++++ src/mingw/mingw.h | 2 +- 7 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 cmake/linux-mingw32.cmake create mode 100644 cmake/linux-mingw64.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index a36803ee0..b0eef1189 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,7 @@ set(STLINK_SOURCE if (WIN32 OR MSYS OR MINGW) set (STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") + set (STLINK_HEADERS "${STLINK_HEADERS};src/mingw/mingw.h") endif () include_directories(${LIBUSB_INCLUDE_DIR}) diff --git a/cmake/linux-mingw32.cmake b/cmake/linux-mingw32.cmake new file mode 100644 index 000000000..2044a7e22 --- /dev/null +++ b/cmake/linux-mingw32.cmake @@ -0,0 +1,25 @@ +# Sample toolchain file for building for Windows from an Debian/Ubuntu Linux system. +# +# Typical usage: +# *) install cross compiler: `sudo apt-get install mingw-w64` +# *) cd build +# *) cmake -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake .. + +set(CMAKE_SYSTEM_NAME Windows) +set(TOOLCHAIN_PREFIX i686-w64-mingw32) + +# cross compilers to use for C and C++ +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) +set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) + +# target environment on the build host system +# set 1st to dir with the cross compiler's C/C++ headers/libs +set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) + +# modify default behavior of FIND_XXX() commands to +# search for headers/libs in the target environment and +# search for programs in the build host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) \ No newline at end of file diff --git a/cmake/linux-mingw64.cmake b/cmake/linux-mingw64.cmake new file mode 100644 index 000000000..db4bd70d0 --- /dev/null +++ b/cmake/linux-mingw64.cmake @@ -0,0 +1,25 @@ +# Sample toolchain file for building for Windows from an Ubuntu Linux system. +# +# Typical usage: +# *) install cross compiler: `sudo apt-get install mingw-w64` +# *) cd build +# *) cmake -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw64.cmake .. + +set(CMAKE_SYSTEM_NAME Windows) +set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) + +# cross compilers to use for C and C++ +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) +set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) + +# target environment on the build host system +# set 1st to dir with the cross compiler's C/C++ headers/libs +set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) + +# modify default behavior of FIND_XXX() commands to +# search for headers/libs in the target environment and +# search for programs in the build host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) \ No newline at end of file diff --git a/cmake/modules/Find7Zip.cmake b/cmake/modules/Find7Zip.cmake index 3448a2856..e4d33dfce 100644 --- a/cmake/modules/Find7Zip.cmake +++ b/cmake/modules/Find7Zip.cmake @@ -1,4 +1,4 @@ -find_program(ZIP_EXECUTABLE NAMES 7z.exe +find_program(ZIP_EXECUTABLE NAMES 7z.exe p7zip HINTS "C:\\Program Files\\7-Zip\\" "C:\\Program Files (x86)\\7-Zip\\" diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index e9a5944f6..5233e489d 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -82,28 +82,47 @@ if(NOT LIBUSB_FOUND) ) endif() file(MAKE_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) - execute_process(COMMAND ${ZIP_EXECUTABLE} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER}) + + if(${ZIP_EXECUTABLE} MATCHES "p7zip") + execute_process(COMMAND ${ZIP_EXECUTABLE} -d --keep -f ${LIBUSB_WIN_ARCHIVE_PATH} WORKING_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) + else() + execute_process(COMMAND ${ZIP_EXECUTABLE} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER}) + endif() FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/include PATH_SUFFIXES libusb-1.0 + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH ) if (MSYS OR MINGW) if (CMAKE_SIZEOF_VOID_P EQUAL 8) find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/static) + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/static + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) else () find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static) + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) endif () elseif(MSVC) if (CMAKE_SIZEOF_VOID_P EQUAL 8) find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll) + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) else () find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll) + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) endif () endif () FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) diff --git a/doc/compiling.md b/doc/compiling.md index 74a8a34f5..555dce487 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -179,3 +179,24 @@ NOTES: This solution will link to the dll version of libusb-1.0. To debug or ru be either on the path, or in the same folder as the executable. It can be copied from here: `build\3thparty\libusb-1.0.21\MS32\dll\libusb-1.0.dll`. +## Linux (MinGW64) + +### Prequistes + +* 7Zip +* CMake 2.8 or higher +* MinGW64 GCC toolchain (5.3.0) + +### Installation (Debian / Ubuntu) + +sudo apt install p7zip mingw-w64 + +### Building + +These instructions are for a 32bit version. + +```sh +cd +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -S . -B ./build/linux-mingw32 +cmake --build ./build/linux-mingw32 --target all +``` diff --git a/src/mingw/mingw.h b/src/mingw/mingw.h index 2efd1ab34..4fe07e611 100644 --- a/src/mingw/mingw.h +++ b/src/mingw/mingw.h @@ -8,7 +8,7 @@ #endif #include -#include +#include #if defined(_MSC_VER) #pragma comment(lib, "ws2_32.lib") #endif From d040db5585d33dc36bd8ae093c024583ef1b4f74 Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Mon, 13 May 2019 17:58:30 +0300 Subject: [PATCH 0661/1435] fixed few potential memory/resource leaks (#803) also few cppcheck warnings --- src/common.c | 14 +++--- src/gdbserver/gdb-remote.c | 15 +++++- src/gdbserver/gdb-server.c | 93 ++++++++++++++++++------------------- src/gdbserver/semihosting.c | 2 +- src/mingw/mingw.c | 3 +- src/mingw/mingw.h | 2 +- src/mmap.c | 6 ++- src/sg.c | 2 +- src/usb.c | 2 +- 9 files changed, 78 insertions(+), 61 deletions(-) diff --git a/src/common.c b/src/common.c index 63de8415c..19cfd4f87 100644 --- a/src/common.c +++ b/src/common.c @@ -288,7 +288,7 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { else cr_lock_shift = FLASH_CR_LOCK; - return cr & (1 << cr_lock_shift); + return cr & (1u << cr_lock_shift); } static void unlock_flash(stlink_t *sl) { @@ -352,11 +352,11 @@ static void lock_flash(stlink_t *sl) { cr_lock_shift = FLASH_CR_LOCK; } - n = read_flash_cr(sl) | (1 << cr_lock_shift); + n = read_flash_cr(sl) | (1u << cr_lock_shift); stlink_write_debug32(sl, cr_reg, n); if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - n = read_flash_cr2(sl) | (1 << cr_lock_shift); + n = read_flash_cr2(sl) | (1u << cr_lock_shift); stlink_write_debug32(sl, FLASH_CR2, n); } } @@ -2524,7 +2524,7 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui /* Unlock flash if necessary (ref manuel page 52) */ stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - if ((val & (1 << STM32G0_FLASH_CR_LOCK))) { + if ((val & (1u << STM32G0_FLASH_CR_LOCK))) { /* disable flash write protection. */ stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0x45670123); @@ -2532,7 +2532,7 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui // check that the lock is no longer set. stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - if ((val & (1 << STM32G0_FLASH_CR_LOCK))) { + if ((val & (1u << STM32G0_FLASH_CR_LOCK))) { ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); return -1; } @@ -2578,11 +2578,11 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui /* Re-lock option bytes */ stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= (1 << STM32G0_FLASH_CR_OPTLOCK); + val |= (1u << STM32G0_FLASH_CR_OPTLOCK); stlink_write_debug32(sl, STM32G0_FLASH_CR, val); /* Re-lock flash. */ stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= (1 << STM32G0_FLASH_CR_LOCK); + val |= (1u << STM32G0_FLASH_CR_LOCK); stlink_write_debug32(sl, STM32G0_FLASH_CR, val); return 0; diff --git a/src/gdbserver/gdb-remote.c b/src/gdbserver/gdb-remote.c index 83c5e093a..e4aad312d 100644 --- a/src/gdbserver/gdb-remote.c +++ b/src/gdbserver/gdb-remote.c @@ -64,8 +64,12 @@ int gdb_recv_packet(int fd, char** buffer) { char* packet_buffer = malloc(packet_size); unsigned state; + if(packet_buffer == NULL) + return -2; + start: state = 0; + packet_idx = 0; /* * 0: waiting $ * 1: data, waiting # @@ -77,6 +81,7 @@ int gdb_recv_packet(int fd, char** buffer) { char c; while(state != 4) { if(read(fd, &c, 1) != 1) { + free(packet_buffer); return -2; } @@ -98,7 +103,13 @@ int gdb_recv_packet(int fd, char** buffer) { if(packet_idx == packet_size) { packet_size += ALLOC_STEP; - packet_buffer = realloc(packet_buffer, packet_size); + void* p = realloc(packet_buffer, packet_size); + if(p != NULL) + packet_buffer = p; + else { + free(packet_buffer); + return -2; + } } } break; @@ -119,6 +130,7 @@ int gdb_recv_packet(int fd, char** buffer) { if(recv_cksum_int != cksum) { char nack = '-'; if(write(fd, &nack, 1) != 1) { + free(packet_buffer); return -2; } @@ -126,6 +138,7 @@ int gdb_recv_packet(int fd, char** buffer) { } else { char ack = '+'; if(write(fd, &ack, 1) != 1) { + free(packet_buffer); return -2; } } diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 8566b792e..bdfeb703d 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -14,7 +14,7 @@ #include #define __attribute__(x) #endif -#if defined(__MINGW32__) || defined(_MSC_VER) +#if defined(_WIN32) #include #else #include @@ -44,6 +44,15 @@ static bool semihosting = false; static bool serial_specified = false; static char serialnumber[28] = {0}; +#if defined(_WIN32) +#define close_socket win32_close_socket +#define IS_SOCK_VALID(__sock) ((__sock) != INVALID_SOCKET) +#else +#define close_socket close +#define SOCKET int +#define IS_SOCK_VALID(__sock) ((__sock) > 0) +#endif + static const char hex[] = "0123456789abcdef"; static const char* current_memory_map = NULL; @@ -106,7 +115,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { {"no-reset", optional_argument, NULL, 'n'}, {"version", no_argument, NULL, 'V'}, {"semihosting", no_argument, NULL, SEMIHOSTING_OPTION}, - {"serial", required_argument, NULL, SERIAL_OPTION}, + {"serial", required_argument, NULL, SERIAL_OPTION}, {0, 0, 0, 0}, }; const char * help_str = "%s - usage:\n\n" @@ -863,7 +872,6 @@ static int flash_go(stlink_t *sl) { int ret = stlink_write_flash(sl, page, fb->data + (page - fb->addr), len, 0); if (ret < 0) goto error; - length -= len; } } @@ -989,29 +997,27 @@ static void init_cache (stlink_t *sl) { } static void cache_flush(stlink_t *sl, unsigned ccr) { - int level; - - if (ccr & CCR_DC) - for (level = cache_desc.louu - 1; level >= 0; level--) - { - struct cache_level_desc *desc = &cache_desc.dcache[level]; - unsigned addr; - unsigned max_addr = 1 << desc->width; - unsigned way_sh = 32 - desc->log2_nways; - - /* D-cache clean by set-ways. */ - for (addr = (level << 1); addr < max_addr; addr += cache_desc.dminline) - { - unsigned int way; - - for (way = 0; way < desc->nways; way++) - stlink_write_debug32(sl, DCCSW, addr | (way << way_sh)); - } - } - - /* Invalidate all I-cache to oPU. */ - if (ccr & CCR_IC) - stlink_write_debug32(sl, ICIALLU, 0); + int level; + + if (ccr & CCR_DC) + for (level = cache_desc.louu - 1; level >= 0; level--) { + struct cache_level_desc *desc = &cache_desc.dcache[level]; + unsigned addr; + unsigned max_addr = 1 << desc->width; + unsigned way_sh = 32 - desc->log2_nways; + + /* D-cache clean by set-ways. */ + for (addr = (level << 1); addr < max_addr; addr += cache_desc.dminline) { + unsigned int way; + + for (way = 0; way < desc->nways; way++) + stlink_write_debug32(sl, DCCSW, addr | (way << way_sh)); + } + } + + /* Invalidate all I-cache to oPU. */ + if (ccr & CCR_IC) + stlink_write_debug32(sl, ICIALLU, 0); } static int cache_modified; @@ -1055,8 +1061,8 @@ static size_t unhexify(const char *in, char *out, size_t out_count) } int serve(stlink_t *sl, st_state_t *st) { - int sock = socket(AF_INET, SOCK_STREAM, 0); - if(sock < 0) { + SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); + if(!IS_SOCK_VALID(sock)) { perror("socket"); return 1; } @@ -1072,28 +1078,27 @@ int serve(stlink_t *sl, st_state_t *st) { if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { perror("bind"); + close_socket(sock); return 1; } if(listen(sock, 5) < 0) { perror("listen"); + close_socket(sock); return 1; } ILOG("Listening at *:%d...\n", st->listen_port); - int client = accept(sock, NULL, NULL); + SOCKET client = accept(sock, NULL, NULL); //signal (SIGINT, SIG_DFL); - if(client < 0) { + if(!IS_SOCK_VALID(client)) { perror("accept"); + close_socket(sock); return 1; } -#if defined(__MINGW32__) || defined(_MSC_VER) - win32_close_socket(sock); -#else - close(sock); -#endif + close_socket(sock); stlink_force_debug(sl); if (st->reset) { @@ -1116,9 +1121,7 @@ int serve(stlink_t *sl, st_state_t *st) { int status = gdb_recv_packet(client, &packet); if(status < 0) { ELOG("cannot recv: %d\n", status); -#if defined(__MINGW32__) || defined(_MSC_VER) - win32_close_socket(client); -#endif + close_socket(client); return 1; } @@ -1343,6 +1346,8 @@ int serve(stlink_t *sl, st_state_t *st) { } else { reply = strdup("OK"); } + + free(decoded); } else if(!strcmp(cmdName, "FlashDone")) { if(flash_go(sl) < 0) { reply = strdup("E00"); @@ -1369,9 +1374,7 @@ int serve(stlink_t *sl, st_state_t *st) { status = gdb_check_for_interrupt(client); if(status < 0) { ELOG("cannot check for int: %d\n", status); -#if defined(__MINGW32__) || defined(_MSC_VER) - win32_close_socket(client); -#endif + close_socket(client); return 1; } @@ -1771,9 +1774,7 @@ int serve(stlink_t *sl, st_state_t *st) { ELOG("cannot send: %d\n", result); free(reply); free(packet); -#if defined(__MINGW32__) || defined(_MSC_VER) - win32_close_socket(client); -#endif + close_socket(client); return 1; } @@ -1783,9 +1784,7 @@ int serve(stlink_t *sl, st_state_t *st) { free(packet); } -#if defined(__MINGW32__) || defined(_MSC_VER) - win32_close_socket(client); -#endif + close_socket(client); return 0; } diff --git a/src/gdbserver/semihosting.c b/src/gdbserver/semihosting.c index b7792007f..9e92cf3bd 100644 --- a/src/gdbserver/semihosting.c +++ b/src/gdbserver/semihosting.c @@ -320,7 +320,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { int fd; uint32_t buffer_len; void *buffer; - ssize_t read_result; + ssize_t read_result; if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { DLOG("Semihosting SYS_READ error: " diff --git a/src/mingw/mingw.c b/src/mingw/mingw.c index bfdd3dcff..4cb917ac4 100644 --- a/src/mingw/mingw.c +++ b/src/mingw/mingw.c @@ -15,7 +15,8 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) { struct timeval timeout, *toptr; fd_set ifds, ofds, efds, *ip, *op; - unsigned int i, rc; + unsigned int i; + int rc; /* Set up the file-descriptor sets in ifds, ofds and efds. */ #ifdef _MSC_VER diff --git a/src/mingw/mingw.h b/src/mingw/mingw.h index 4fe07e611..e3a7267a9 100644 --- a/src/mingw/mingw.h +++ b/src/mingw/mingw.h @@ -60,7 +60,7 @@ SOCKET win32_socket(int, int, int); int win32_connect(SOCKET, struct sockaddr*, socklen_t); SOCKET win32_accept(SOCKET, struct sockaddr*, socklen_t *); int win32_shutdown(SOCKET, int); -int win32_close_socket(SOCKET fd); +int win32_close_socket(SOCKET fd); #define strtok_r(x, y, z) win32_strtok_r(x, y, z) #define strsep(x,y) win32_strsep(x,y) diff --git a/src/mmap.c b/src/mmap.c index cc5346f18..90ae5fc17 100644 --- a/src/mmap.c +++ b/src/mmap.c @@ -15,7 +15,11 @@ void *mmap (void *addr, size_t len, int prot, int flags, int fd, long long offs buf = malloc(len); if ( NULL == buf ) return MAP_FAILED; - if (lseek(fd,offset,SEEK_SET) != offset) return MAP_FAILED; + if (lseek(fd,offset,SEEK_SET) != offset) { + free(buf); + return MAP_FAILED; + } + count = read(fd, buf, len); diff --git a/src/sg.c b/src/sg.c index 285e2bd90..e7ff5d14e 100644 --- a/src/sg.c +++ b/src/sg.c @@ -945,7 +945,6 @@ static stlink_backend_t _stlink_sg_backend = { static stlink_t* stlink_open(const int verbose) { stlink_t *sl = malloc(sizeof (stlink_t)); - memset(sl, 0, sizeof(stlink_t)); struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg)); if (sl == NULL || slsg == NULL) { WLOG("Couldn't malloc stlink and stlink_sg structures out of memory!\n"); @@ -955,6 +954,7 @@ static stlink_t* stlink_open(const int verbose) { free(slsg); return NULL; } + memset(sl, 0, sizeof(stlink_t)); if (libusb_init(&(slsg->libusb_ctx))) { WLOG("failed to init libusb context, wrong version of libraries?\n"); diff --git a/src/usb.c b/src/usb.c index c4d39ac5f..34586640e 100644 --- a/src/usb.c +++ b/src/usb.c @@ -625,7 +625,7 @@ int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg if (ret == -1) return ret; - _stlink_usb_read_mem32(sl, STLINK_REG_DCRDR, 4); + ret = _stlink_usb_read_mem32(sl, STLINK_REG_DCRDR, 4); if (ret == -1) return ret; From df3c2b02867db03fb82f6faaad71300398965e85 Mon Sep 17 00:00:00 2001 From: Michael DL6AKU Date: Thu, 6 Jun 2019 19:50:22 +0200 Subject: [PATCH 0662/1435] Allow for 64 Bytes serials (#809) --- include/stlink.h | 4 +++- include/stlink/tools/flash.h | 2 +- include/stlink/usb.h | 2 +- src/usb.c | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index d5e8270ac..96be91033 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -66,6 +66,8 @@ extern "C" { #define STLINK_SWDCLK_15KHZ_DIVISOR 265 #define STLINK_SWDCLK_5KHZ_DIVISOR 798 +#define STLINK_SERIAL_MAX_SIZE 64 + /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ #define C_BUF_LEN 32 @@ -144,7 +146,7 @@ typedef struct flash_loader { uint32_t chip_id; int core_stat; - char serial[16]; + char serial[STLINK_SERIAL_MAX_SIZE]; int serial_size; enum stlink_flash_type flash_type; diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index 3d1375aa2..af82198f2 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -13,7 +13,7 @@ struct flash_opts { enum flash_cmd cmd; const char* devname; - uint8_t serial[16]; + uint8_t serial[STLINK_SERIAL_MAX_SIZE]; const char* filename; stm32_addr_t addr; size_t size; diff --git a/include/stlink/usb.h b/include/stlink/usb.h index 9e27db156..621695ea4 100644 --- a/include/stlink/usb.h +++ b/include/stlink/usb.h @@ -45,7 +45,7 @@ extern "C" { * @retval NULL Error while opening the stlink * @retval !NULL Stlink found and ready to use */ - stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16]); + stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE]); size_t stlink_probe_usb(stlink_t **stdevs[]); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); diff --git a/src/usb.c b/src/usb.c index 34586640e..7f5c21283 100644 --- a/src/usb.c +++ b/src/usb.c @@ -767,7 +767,7 @@ static stlink_backend_t _stlink_usb_backend = { _stlink_usb_set_swdclk }; -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16]) +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE]) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; @@ -1003,7 +1003,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { continue; struct libusb_device_handle* handle; - char serial[16]; + char serial[STLINK_SERIAL_MAX_SIZE]; memset(serial, 0, sizeof(serial)); ret = libusb_open(dev, &handle); From 84f63d25bd77d61f8feccf08dd24d0d11895ef32 Mon Sep 17 00:00:00 2001 From: Vasiliy Zasukhin <50801920+Humanoid0@users.noreply.github.com> Date: Thu, 6 Jun 2019 20:53:03 +0300 Subject: [PATCH 0663/1435] Add support for CS32F103C8T6 (#805) CS32F103C8T6 is clone of STM32F103C8T6 but with incorrect core_id number. --- src/flash_loader.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/flash_loader.c b/src/flash_loader.c index f2e636751..73db427a7 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -262,6 +262,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID + || sl->chip_id == STLINK_CHIPID_STM32_F1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_F3 || sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL || sl->chip_id == STLINK_CHIPID_STM32_F303_HIGH From 625f4cd57242c974ea9e53de801b6fd53708926f Mon Sep 17 00:00:00 2001 From: eupn <36292692+eupn@users.noreply.github.com> Date: Sun, 14 Jul 2019 16:02:42 +0700 Subject: [PATCH 0664/1435] WB55: fix flash verification error (#816) * Clear previously written page number (if any) * Remove unrelated change --- src/common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common.c b/src/common.c index 19cfd4f87..b4741a585 100644 --- a/src/common.c +++ b/src/common.c @@ -1759,8 +1759,11 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) if (sl->flash_type == STLINK_FLASH_TYPE_WB) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + // sec 3.10.5 - PNB[7:0] is offset by 3. + val &= ~(0xFF << 3); // Clear previously set page number (if any) val |= ((flash_page & 0xFF) << 3); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); From 728049b244d7a7f7c2e7415af4a6a5001cbe928a Mon Sep 17 00:00:00 2001 From: Benjamin Henrion Date: Fri, 26 Jul 2019 13:19:32 +0200 Subject: [PATCH 0665/1435] Add stlink-tools link for Debian and Ubuntu Add stlink-tools link for Debian and Ubuntu --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d711d323f..285c3f751 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,9 @@ Windows users can [download v1.3.0](https://github.com/texane/stlink/releases/ta Mac OS X users can install from [homebrew](http://brewformulas.org/Stlink) or [download v1.3.0](https://github.com/texane/stlink/releases/tag/1.3.0) from the releases page. -For Debian Linux based distributions there is no package available - in the standard repositories so you need to install [from source](doc/compiling.md) yourself. +Debian Linux users can install it via the ```stlink-tool``` package [repository](https://packages.debian.org/buster/stlink-tools) + +Ubuntu Linux users can install it via the ```stlink-tool``` package [repository](https://packages.ubuntu.com/cosmic/stlink-tools) Arch Linux users can install from the [repository](https://www.archlinux.org/packages/community/x86_64/stlink) From 8c8285f47e183d8e7e93bce0ce31d2f13590a701 Mon Sep 17 00:00:00 2001 From: William Ransohoff <> Date: Fri, 26 Jul 2019 20:31:24 -0700 Subject: [PATCH 0666/1435] Add support for STM32G4 series --- include/stlink.h | 1 + include/stlink/chipid.h | 2 + src/chipid.c | 13 ++- src/common.c | 197 +++++++++++++++++++++++----------------- 4 files changed, 130 insertions(+), 83 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 96be91033..c664e2e66 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -79,6 +79,7 @@ extern "C" { STLINK_FLASH_TYPE_L4, STLINK_FLASH_TYPE_F1_XL, STLINK_FLASH_TYPE_G0, + STLINK_FLASH_TYPE_G4, STLINK_FLASH_TYPE_WB }; diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index a4f4be4c0..e9cb48167 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -72,6 +72,8 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F413 = 0x463, STLINK_CHIPID_STM32_L4RX = 0x470, // taken from the STM32L4R9I-DISCO board STLINK_CHIPID_STM32_G0X1 = 0x460, + STLINK_CHIPID_STM32_G4_CAT2 = 0x468, // See: RM 0440 s46.6.1 "MCU device ID code". + STLINK_CHIPID_STM32_G4_CAT3 = 0x469, STLINK_CHIPID_STM32_WB55 = 0x495 }; diff --git a/src/chipid.c b/src/chipid.c index d627849a3..938cc1f30 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -530,7 +530,18 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, // 2K (sec 3.2) .sram_size = 0x9000, // 36K (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 // 30K (table 2) + .bootrom_size = 0x7000 // 28K (table 2) + }, + { + // STM32G431/441 (from RM0440) + .chip_id = STLINK_CHIPID_STM32_G4_CAT2, + .description = "G4 Category-2 device", + .flash_type = STLINK_FLASH_TYPE_G4, + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = 0x800, // 2K (sec 3.3.1) + .sram_size = 0x8000, // 32K (sec 2.4) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000 // 28K (table 2) }, { // STM32WB55 (from RM0434) diff --git a/src/common.c b/src/common.c index b4741a585..d253e2b24 100644 --- a/src/common.c +++ b/src/common.c @@ -74,15 +74,20 @@ #define FLASH_L1_FPRG 10 #define FLASH_L1_PROG 3 +// Flash registers common to STM32G0 and STM32G4 series. +#define STM32Gx_FLASH_REGS_ADDR ((uint32_t)0x40022000) +#define STM32Gx_FLASH_ACR (STM32G0_FLASH_REGS_ADDR + 0x00) +#define STM32Gx_FLASH_KEYR (STM32G0_FLASH_REGS_ADDR + 0x08) +#define STM32Gx_FLASH_OPTKEYR (STM32G0_FLASH_REGS_ADDR + 0x0c) +#define STM32Gx_FLASH_SR (STM32G0_FLASH_REGS_ADDR + 0x10) +#define STM32Gx_FLASH_CR (STM32G0_FLASH_REGS_ADDR + 0x14) +#define STM32Gx_FLASH_ECCR (STM32G0_FLASH_REGS_ADDR + 0x18) +#define STM32Gx_FLASH_OPTR (STM32G0_FLASH_REGS_ADDR + 0x20) + // G0 (RM0444 Table 1, sec 3.7) -#define STM32G0_FLASH_REGS_ADDR ((uint32_t)0x40022000) -#define STM32G0_FLASH_ACR (STM32G0_FLASH_REGS_ADDR + 0x00) -#define STM32G0_FLASH_KEYR (STM32G0_FLASH_REGS_ADDR + 0x08) -#define STM32G0_FLASH_OPTKEYR (STM32G0_FLASH_REGS_ADDR + 0x0c) -#define STM32G0_FLASH_SR (STM32G0_FLASH_REGS_ADDR + 0x10) -#define STM32G0_FLASH_CR (STM32G0_FLASH_REGS_ADDR + 0x14) -#define STM32G0_FLASH_ECCR (STM32G0_FLASH_REGS_ADDR + 0x18) -#define STM32G0_FLASH_OPTR (STM32G0_FLASH_REGS_ADDR + 0x20) +// Mostly the same as G4 chips, but the notation +// varies a bit after the 'OPTR' register. +#define STM32G0_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) #define STM32G0_FLASH_PCROP1ASR (STM32G0_FLASH_REGS_ADDR + 0x24) #define STM32G0_FLASH_PCROP1AER (STM32G0_FLASH_REGS_ADDR + 0x28) #define STM32G0_FLASH_WRP1AR (STM32G0_FLASH_REGS_ADDR + 0x2C) @@ -91,21 +96,39 @@ #define STM32G0_FLASH_PCROP1BER (STM32G0_FLASH_REGS_ADDR + 0x38) #define STM32G0_FLASH_SECR (STM32G0_FLASH_REGS_ADDR + 0x80) -// GO FLASH control register -#define STM32G0_FLASH_CR_PG 0 /* Program */ -#define STM32G0_FLASH_CR_PER 1 /* Page erase */ -#define STM32G0_FLASH_CR_MER1 2 /* Mass erase */ -#define STM32G0_FLASH_CR_PNB 3 /* Page number (5 bits) */ -#define STM32G0_FLASH_CR_STRT 16 /* Start */ -#define STM32G0_FLASH_CR_OPTSTRT 17 /* Start of modification of option bytes */ -#define STM32G0_FLASH_CR_FSTPG 18 /* Fast programming */ -#define STM32G0_FLASH_CR_EOPIE 24 /* End of operation interrupt enable */ -#define STM32G0_FLASH_CR_ERRIE 25 /* Error interrupt enable */ -#define STM32G0_FLASH_CR_OBL_LAUNCH 27 /* Forces the option byte loading */ -#define STM32G0_FLASH_CR_OPTLOCK 30 /* Options Lock */ -#define STM32G0_FLASH_CR_LOCK 31 /* FLASH_CR Lock */ -// GO FLASH status register -#define STM32G0_FLASH_SR_BSY 16 /* FLASH_SR Busy */ +// G4 (RM0440 Table 17, sec 3.7.19) +// Mostly the same as STM32G0 chips, but there are a few extra +// registers because 'cat 3' devices can have two Flash banks. +#define STM32G4_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) +#define STM32G4_FLASH_PDKEYR (STM32G4_FLASH_REGS_ADDR + 0x04) +#define STM32G4_FLASH_PCROP1SR (STM32G4_FLASH_REGS_ADDR + 0x24) +#define STM32G4_FLASH_PCROP1ER (STM32G4_FLASH_REGS_ADDR + 0x28) +#define STM32G4_FLASH_WRP1AR (STM32G4_FLASH_REGS_ADDR + 0x2C) +#define STM32G4_FLASH_WRP1BR (STM32G4_FLASH_REGS_ADDR + 0x30) +#define STM32G4_FLASH_PCROP2SR (STM32G4_FLASH_REGS_ADDR + 0x44) +#define STM32G4_FLASH_PCROP2ER (STM32G4_FLASH_REGS_ADDR + 0x48) +#define STM32G4_FLASH_WRP2AR (STM32G4_FLASH_REGS_ADDR + 0x4C) +#define STM32G4_FLASH_WRP2BR (STM32G4_FLASH_REGS_ADDR + 0x50) +#define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70) +#define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74) + +// G0/G4 FLASH control register +#define STM32Gx_FLASH_CR_PG (0) /* Program */ +#define STM32Gx_FLASH_CR_PER (1) /* Page erase */ +#define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */ +#define STM32Gx_FLASH_CR_PNB (3) /* Page number */ +#define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ +#define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ +#define STM32Gx_FLASH_CR_STRT (16) /* Start */ +#define STM32Gx_FLASH_CR_OPTSTRT (17) /* Start of modification of option bytes */ +#define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ +#define STM32Gx_FLASH_CR_EOPIE (24) /* End of operation interrupt enable */ +#define STM32Gx_FLASH_CR_ERRIE (25) /* Error interrupt enable */ +#define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ +#define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ +#define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ +// G0/G4 FLASH status register +#define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ // WB (RM0434) #define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) @@ -249,8 +272,8 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { reg = FLASH_F4_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) reg = STM32L4_FLASH_CR; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0) - reg = STM32G0_FLASH_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + reg = STM32Gx_FLASH_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) reg = STM32WB_FLASH_CR; else @@ -281,8 +304,8 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { cr_lock_shift = FLASH_F4_CR_LOCK; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) cr_lock_shift = STM32L4_FLASH_CR_LOCK; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0) - cr_lock_shift = STM32G0_FLASH_CR_LOCK; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + cr_lock_shift = STM32Gx_FLASH_CR_LOCK; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) cr_lock_shift = STM32WB_FLASH_CR_LOCK; else @@ -302,8 +325,8 @@ static void unlock_flash(stlink_t *sl) { key_reg = FLASH_F4_KEYR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) key_reg = STM32L4_FLASH_KEYR; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0) - key_reg = STM32G0_FLASH_KEYR; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + key_reg = STM32Gx_FLASH_KEYR; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) key_reg = STM32WB_FLASH_KEYR; else @@ -341,9 +364,9 @@ static void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { - cr_reg = STM32G0_FLASH_CR; - cr_lock_shift = STM32G0_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_lock_shift = STM32Gx_FLASH_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; @@ -374,8 +397,8 @@ static void set_flash_cr_pg(stlink_t *sl) { cr_reg = STM32L4_FLASH_CR; x &= ~STM32L4_FLASH_CR_OPBITS; x |= 1 << STM32L4_FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { - cr_reg = STM32G0_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; x |= (1 << FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; @@ -395,8 +418,8 @@ static void clear_flash_cr_pg(stlink_t *sl) { cr_reg = FLASH_F4_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) cr_reg = STM32L4_FLASH_CR; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0) - cr_reg = STM32G0_FLASH_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + cr_reg = STM32Gx_FLASH_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) cr_reg = STM32WB_FLASH_CR; else @@ -409,8 +432,8 @@ static void clear_flash_cr_pg(stlink_t *sl) { static void set_flash_cr_per(stlink_t *sl) { uint32_t cr_reg, val; - if (sl->flash_type == STLINK_FLASH_TYPE_G0) - cr_reg = STM32G0_FLASH_CR; + if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + cr_reg = STM32Gx_FLASH_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) cr_reg = STM32WB_FLASH_CR; else @@ -429,8 +452,8 @@ static void set_flash_cr2_per(stlink_t *sl) { static void clear_flash_cr_per(stlink_t *sl) { uint32_t cr_reg; - if (sl->flash_type == STLINK_FLASH_TYPE_G0) - cr_reg = STM32G0_FLASH_CR; + if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + cr_reg = STM32Gx_FLASH_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) cr_reg = STM32WB_FLASH_CR; else @@ -451,8 +474,8 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); cr_pg = 1 << STM32L4_FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { - cr_reg = STM32G0_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; cr_mer = (1 << FLASH_CR_MER); cr_pg = (1 << FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { @@ -521,9 +544,9 @@ static void set_flash_cr_strt(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_strt = 1 << STM32L4_FLASH_CR_STRT; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { - cr_reg = STM32G0_FLASH_CR; - cr_strt = 1 << STM32G0_FLASH_CR_STRT; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_strt = 1 << STM32Gx_FLASH_CR_STRT; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_strt = 1 << STM32WB_FLASH_CR_STRT; @@ -552,8 +575,8 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { sr_reg = FLASH_F4_SR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) sr_reg = STM32L4_FLASH_SR; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0) - sr_reg = STM32G0_FLASH_SR; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + sr_reg = STM32Gx_FLASH_SR; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) sr_reg = STM32WB_FLASH_SR; else @@ -578,8 +601,8 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { sr_busy_shift = FLASH_F4_SR_BSY; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) sr_busy_shift = STM32L4_FLASH_SR_BSY; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0) - sr_busy_shift = STM32G0_FLASH_SR_BSY; + else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + sr_busy_shift = STM32Gx_FLASH_SR_BSY; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) sr_busy_shift = STM32WB_FLASH_SR_BSY; else @@ -1746,7 +1769,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0) { + sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { uint32_t val; // Wait for any ongoing Flash operation to finish. wait_flash_busy(sl); @@ -1767,10 +1791,18 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) stlink_write_debug32(sl, STM32WB_FLASH_CR, val); } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. - val = ((flash_page & 0x3F) << 3) | ( 1 << FLASH_CR_PER ); - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + val &= ~(0x3F << 3); + val |= ((flash_page & 0x3F) << 3) | ( 1 << FLASH_CR_PER ); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G4) { + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. + val &= ~(0x7F << 3); + val |= ((flash_page & 0x7F) << 3) | ( 1 << FLASH_CR_PER ); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); } // Set the 'start operation' bit. @@ -1834,8 +1866,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } int stlink_erase_flash_mass(stlink_t *sl) { - /* TODO: User MER bit to mass-erase G0, WB series. */ - if (sl->flash_type == STLINK_FLASH_TYPE_L0 || sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_WB) { + /* TODO: User MER bit to mass-erase G0, G4, WB series. */ + if (sl->flash_type == STLINK_FLASH_TYPE_L0 || sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4 || sl->flash_type == STLINK_FLASH_TYPE_WB) { /* erase each page */ int i = 0, num_pages = (int) sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -2121,7 +2153,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } //STM32F4END else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0) { + sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { fprintf(stdout, "Writing\r\n"); fflush(stdout); // Wait for any ongoing operations to finish. @@ -2526,32 +2559,32 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui } /* Unlock flash if necessary (ref manuel page 52) */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - if ((val & (1u << STM32G0_FLASH_CR_LOCK))) { + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + if ((val & (1u << STM32Gx_FLASH_CR_LOCK))) { /* disable flash write protection. */ - stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0x45670123); - stlink_write_debug32(sl, STM32G0_FLASH_KEYR, 0xCDEF89AB); + stlink_write_debug32(sl, STM32Gx_FLASH_KEYR, 0x45670123); + stlink_write_debug32(sl, STM32Gx_FLASH_KEYR, 0xCDEF89AB); // check that the lock is no longer set. - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - if ((val & (1u << STM32G0_FLASH_CR_LOCK))) { + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + if ((val & (1u << STM32Gx_FLASH_CR_LOCK))) { ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); return -1; } } /* Unlock option bytes if necessary (ref manuel page 61) */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - if ((val & (1 << STM32G0_FLASH_CR_OPTLOCK))) { + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + if ((val & (1 << STM32Gx_FLASH_CR_OPTLOCK))) { /* disable option byte write protection. */ - stlink_write_debug32(sl, STM32G0_FLASH_OPTKEYR, 0x08192A3B); - stlink_write_debug32(sl, STM32G0_FLASH_OPTKEYR, 0x4C5D6E7F); + stlink_write_debug32(sl, STM32Gx_FLASH_OPTKEYR, 0x08192A3B); + stlink_write_debug32(sl, STM32Gx_FLASH_OPTKEYR, 0x4C5D6E7F); /* check that the lock is no longer set. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - if ((val & (1 << STM32G0_FLASH_CR_OPTLOCK))) { + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + if ((val & (1 << STM32Gx_FLASH_CR_OPTLOCK))) { ELOG("Options bytes unlock failed! System reset required to be able to unlock it again!\n"); return -1; } @@ -2562,31 +2595,31 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui write_uint32((unsigned char*) &data, *(uint32_t*) (base)); WLOG("Writing option bytes 0x%04x\n", data); //stlink_write_debug32(sl, addr, data); - stlink_write_debug32(sl, STM32G0_FLASH_OPTR, data); + stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); /* Set Options Start bit */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= (1 << STM32G0_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); /* Wait for 'busy' bit in FLASH_SR to clear. */ do { - stlink_read_debug32(sl, STM32G0_FLASH_SR, &val); + stlink_read_debug32(sl, STM32Gx_FLASH_SR, &val); } while ((val & (1 << 16)) != 0); /* apply options bytes immediate */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= (1 << STM32G0_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); /* Re-lock option bytes */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= (1u << STM32G0_FLASH_CR_OPTLOCK); - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + val |= (1u << STM32Gx_FLASH_CR_OPTLOCK); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); /* Re-lock flash. */ - stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); - val |= (1u << STM32G0_FLASH_CR_LOCK); - stlink_write_debug32(sl, STM32G0_FLASH_CR, val); + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + val |= (1u << STM32Gx_FLASH_CR_LOCK); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); return 0; } From 44aab55ddc291c381b6c1ab3544cda57638511fc Mon Sep 17 00:00:00 2001 From: MFaehling <53976201+MFaehling@users.noreply.github.com> Date: Sat, 10 Aug 2019 19:46:01 +0200 Subject: [PATCH 0667/1435] Add aliased SRAM2 region in the L496 memory map The SRAM2 on the L496 devices is aliased at 0x2004000. With this change, it's possible to read the SRAM2 contents at the aliased addresses. --- src/gdbserver/gdb-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index bdfeb703d..a874a81da 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -449,7 +449,7 @@ static const char* const memory_map_template_L496 = "" " " // code = sram, bootrom or flash; flash is bigger " " // SRAM2 (64 KB) - " " // SRAM1 (256 KB) + " " // SRAM1 + aliased SRAM2 (256+64=320 KB) " " " 0x800" " " From 156871d55efc1b53a8efceafb64318198d819252 Mon Sep 17 00:00:00 2001 From: WRR <-@-> Date: Mon, 12 Aug 2019 11:37:00 -0700 Subject: [PATCH 0668/1435] Add support for STM32G031 and STM32G041 chips. Including the 8-pin STM32G031J6 :D --- include/stlink/chipid.h | 3 ++- src/chipid.c | 13 ++++++++++++- src/common.c | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index a4f4be4c0..9ff8c814f 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -71,7 +71,8 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F410 = 0x458, STLINK_CHIPID_STM32_F413 = 0x463, STLINK_CHIPID_STM32_L4RX = 0x470, // taken from the STM32L4R9I-DISCO board - STLINK_CHIPID_STM32_G0X1 = 0x460, + STLINK_CHIPID_STM32_G0_CAT1 = 0x466, // G031/041 + STLINK_CHIPID_STM32_G0_CAT2 = 0x460, // G071/081 STLINK_CHIPID_STM32_WB55 = 0x495 }; diff --git a/src/chipid.c b/src/chipid.c index d627849a3..7b7bc88d0 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -521,9 +521,20 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1ff00000, .bootrom_size = 0x2000 }, + { + // STM32G031/041 (from RM0444) + .chip_id = STLINK_CHIPID_STM32_G0_CAT1, + .description = "G031/G041 device", + .flash_type = STLINK_FLASH_TYPE_G0, + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2K (sec 3.2) + .sram_size = 0x2000, // 8K (sec 2.3) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 // 30K (table 3) + }, { // STM32G071/081 (from RM0444) - .chip_id = STLINK_CHIPID_STM32_G0X1, + .chip_id = STLINK_CHIPID_STM32_G0_CAT2, .description = "G071/G081 device", .flash_type = STLINK_FLASH_TYPE_G0, .flash_size_reg = 0x1FFF75E0, // Section 38.2 diff --git a/src/common.c b/src/common.c index b4741a585..f974d77ab 100644 --- a/src/common.c +++ b/src/common.c @@ -2520,7 +2520,7 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui stlink_core_id(sl); /* Check if chip is supported and for correct address */ - if((sl->chip_id != STLINK_CHIPID_STM32_G0X1) || (addr != STM32_G0_OPTION_BYTES_BASE)) { + if((sl->chip_id != STLINK_CHIPID_STM32_G0_CAT2 && sl->chip_id != STLINK_CHIPID_STM32_G0_CAT1) || (addr != STM32_G0_OPTION_BYTES_BASE)) { ELOG("Option bytes writing is currently only supported for the STM32G0\n"); return -1; } From 4909dd808ad316439a7932c1381fc195100c6cf2 Mon Sep 17 00:00:00 2001 From: Jerry Jacobs Date: Sat, 17 Aug 2019 10:42:14 +0200 Subject: [PATCH 0669/1435] README.md: Add notice of wanted project maintainer --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d711d323f..9aa7e6b4e 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ Open source version of the STMicroelectronics Stlink Tools [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) [![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/job/stlink/) +**NOTICE: The project has currently not an active maintainer. Feel free to contribute and discus in issue [#826](https://github.com/texane/stlink/issues/826)** + ## HOWTO First, you have to know there are several boards supported by the software. From 738e48eed576d4d36aa5ea8950f2c274ddc54777 Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Mon, 2 Sep 2019 14:35:35 +0200 Subject: [PATCH 0670/1435] Do not issue JTAG reset on stlink-v1 --- src/tools/flash.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/tools/flash.c b/src/tools/flash.c index 768e9834f..b926a8f9a 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -92,9 +92,11 @@ int main(int ac, char** av) } if (o.reset){ - if (stlink_jtag_reset(sl, 2)) { - printf("Failed to reset JTAG\n"); - goto on_error; + if (sl->version.stlink_v > 1) { + if (stlink_jtag_reset(sl, 2)) { + printf("Failed to reset JTAG\n"); + goto on_error; + } } if (stlink_reset(sl)) { @@ -185,9 +187,11 @@ int main(int ac, char** av) } } else if (o.cmd == CMD_RESET) { - if (stlink_jtag_reset(sl, 2)) { - printf("Failed to reset JTAG\n"); - goto on_error; + if (sl->version.stlink_v > 1) { + if (stlink_jtag_reset(sl, 2)) { + printf("Failed to reset JTAG\n"); + goto on_error; + } } if (stlink_reset(sl)) { @@ -212,7 +216,7 @@ int main(int ac, char** av) } if (o.reset){ - stlink_jtag_reset(sl,2); + if (sl->version.stlink_v > 1) stlink_jtag_reset(sl, 2); stlink_reset(sl); } From 32e082619506f585475d76c495b585194e68333c Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Mon, 2 Sep 2019 17:47:34 +0200 Subject: [PATCH 0671/1435] Fix flash size of stm32discovery vl --- src/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index b4741a585..4f1a3d698 100644 --- a/src/common.c +++ b/src/common.c @@ -800,7 +800,7 @@ int stlink_load_device_params(stlink_t *sl) { flash_size = flash_size >>16; flash_size = flash_size & 0xffff; - if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS) && ( flash_size == 0 )) { + if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW || sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS) && ( flash_size == 0 )) { sl->flash_size = 128 * 1024; } else if (sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2) { sl->flash_size = (flash_size & 0xff) * 1024; From e56de83ec50e2e1c7f9c9f19b69c543deb2d6d21 Mon Sep 17 00:00:00 2001 From: Adrian Imboden Date: Fri, 6 Sep 2019 18:23:37 +0200 Subject: [PATCH 0672/1435] added support for writing option bytes on STM32L0 --- README.md | 2 +- include/stm32.h | 1 + src/common.c | 99 +++++++++++++++++++++++++++++++++++++++++------ src/tools/flash.c | 2 +- 4 files changed, 91 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 9aa7e6b4e..1146cf28a 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ then it would be written to the memory. ## Writing Option Bytes -Example to read and write option bytes (currently writing only supported for STM32G0) +Example to read and write option bytes (currently writing only supported for STM32G0 and STM32L0) ``` ./st-flash --debug --reset --format binary --flash=128k read option_bytes_dump.bin 0x1FFF7800 4 ./st-flash --debug --reset --format binary --flash=128k write option_bytes_dump.bin 0x1FFF7800 diff --git a/include/stm32.h b/include/stm32.h index f5dbe4b2d..a19707bc2 100644 --- a/include/stm32.h +++ b/include/stm32.h @@ -15,5 +15,6 @@ #define STM32_FLASH_BASE ((uint32_t)0x08000000) #define STM32_SRAM_BASE ((uint32_t)0x20000000) #define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) +#define STM32_L0_CAT2_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) #endif /* STM32_H */ diff --git a/src/common.c b/src/common.c index 4f1a3d698..25900abdd 100644 --- a/src/common.c +++ b/src/common.c @@ -165,6 +165,9 @@ //same as 32L1 above // RM0090 - DM00031020.pdf #define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) +#define STM32L0_FLASH_PELOCK_BIT (1u << 0) +#define STM32L0_FLASH_OPTLOCK_BIT (1u << 2) +#define STM32L0_FLASH_OBL_LAUNCH_BIT (1u << 18) #define FLASH_ACR_OFF ((uint32_t) 0x00) #define FLASH_PECR_OFF ((uint32_t) 0x04) #define FLASH_PDKEYR_OFF ((uint32_t) 0x08) @@ -2507,7 +2510,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { * @param base option bytes to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { +static int stlink_write_option_bytes_g0x1(stlink_t *sl, uint8_t* base, uint32_t len) { uint32_t val; @@ -2516,15 +2519,6 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui return -1; } - // Make sure we've loaded the context with the chip details - stlink_core_id(sl); - - /* Check if chip is supported and for correct address */ - if((sl->chip_id != STLINK_CHIPID_STM32_G0X1) || (addr != STM32_G0_OPTION_BYTES_BASE)) { - ELOG("Option bytes writing is currently only supported for the STM32G0\n"); - return -1; - } - /* Unlock flash if necessary (ref manuel page 52) */ stlink_read_debug32(sl, STM32G0_FLASH_CR, &val); if ((val & (1u << STM32G0_FLASH_CR_LOCK))) { @@ -2561,7 +2555,6 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui uint32_t data; write_uint32((unsigned char*) &data, *(uint32_t*) (base)); WLOG("Writing option bytes 0x%04x\n", data); - //stlink_write_debug32(sl, addr, data); stlink_write_debug32(sl, STM32G0_FLASH_OPTR, data); /* Set Options Start bit */ @@ -2591,6 +2584,90 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui return 0; } + +/** + * Write option bytes + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_l0_cat2(stlink_t *sl, uint8_t* base, uint32_t len) { + + uint32_t val; + + if(len != 4) { + ELOG("Wrong length for writting option bytes, must be 4 is %d\n", len); + return -1; + } + stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); + if (val & STM32L0_FLASH_PELOCK_BIT) { + WLOG("Unlocking flash\n"); + //Unlock data EEPROM and the FLASH_PECR register (reference page 74) + stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PEKEYR_OFF, 0x89ABCDEF); + stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PEKEYR_OFF, 0x02030405); + + stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); + if (val & STM32L0_FLASH_PELOCK_BIT) { + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + } + + stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); + if ((val & (STM32L0_FLASH_OPTLOCK_BIT))) { + WLOG("Unlocking options\n"); + //Unlock the Option bytes area (reference page 76) + stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_OPTKEYR_OFF, 0xFBEAD9C8); + stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_OPTKEYR_OFF, 0x24252627); + + stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); + if (val & STM32L0_FLASH_OPTLOCK_BIT) { + ELOG("Options unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + } + + /* Write options bytes */ + uint32_t data; + write_uint32((unsigned char*) &data, *(uint32_t*) (base)); + WLOG("Writing option bytes 0x%04x\n", data); + stlink_write_debug32(sl, STM32_L0_CAT2_OPTION_BYTES_BASE, data); + + /* Reload options */ + stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); + val |= (STM32L0_FLASH_OBL_LAUNCH_BIT); + stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, val); + + return 0; +} + +/** + * Write option bytes + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { + + // Make sure we've loaded the context with the chip details + stlink_core_id(sl); + + /* Check if chip is supported and for correct address */ + if((sl->chip_id == STLINK_CHIPID_STM32_G0X1) && (addr == STM32_G0_OPTION_BYTES_BASE)) { + return stlink_write_option_bytes_g0x1(sl, base, len); + } + else if((sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) && (addr == STM32_L0_CAT2_OPTION_BYTES_BASE)) { + return stlink_write_option_bytes_l0_cat2(sl, base, len); + } + else { + ELOG("Option bytes writing is currently only supported for the STM32G0 and STM32L0\n"); + return -1; + } + +} + /** * Write the given binary file with option bytes * @param sl diff --git a/src/tools/flash.c b/src/tools/flash.c index b926a8f9a..1a02b4fb4 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -164,7 +164,7 @@ int main(int ac, char** av) goto on_error; } } - else if (o.addr == STM32_G0_OPTION_BYTES_BASE) { + else if (o.addr == STM32_G0_OPTION_BYTES_BASE || o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE) { err = stlink_fwrite_option_bytes(sl, o.filename, o.addr); if (err == -1) { From bc01701a8d58a68fe78f6823813293fb3192d46a Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 29 Sep 2019 12:42:14 +0100 Subject: [PATCH 0673/1435] Apply cross.patch to fix cross-compiling the GUI. Thanks Helmut for the patch! (Closes: #941320) Gbp-Dch: full --- debian/patches/cross.patch | 15 +++++++++++++++ debian/patches/series | 1 + 2 files changed, 16 insertions(+) create mode 100644 debian/patches/cross.patch create mode 100644 debian/patches/series diff --git a/debian/patches/cross.patch b/debian/patches/cross.patch new file mode 100644 index 000000000..92084238b --- /dev/null +++ b/debian/patches/cross.patch @@ -0,0 +1,15 @@ +Author: Helmut Grohne +Description: do not stop the GUI from being cross-compiled +Bug-Debian: 941320 +Forwarded: yes +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -39,7 +39,7 @@ + # Dependencies + ### + find_package(LibUSB REQUIRED) +-if (NOT APPLE AND NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) ++if (NOT APPLE AND NOT WIN32) + find_package(PkgConfig) + pkg_check_modules(gtk gtk+-3.0) + endif () diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 000000000..def274a02 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1 @@ +cross.patch From ecfb5becd0e091000ea8dc6058a214305b1b319b Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 29 Sep 2019 12:44:22 +0100 Subject: [PATCH 0674/1435] Vcs-Git: add -b debian --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 1499dcf1a..5994ea084 100644 --- a/debian/control +++ b/debian/control @@ -5,7 +5,7 @@ Build-Depends: debhelper (>= 9), cmake, libusb-1.0-0-dev, libgtk-3-dev Standards-Version: 4.1.3 Section: electronics Homepage: https://github.com/texane/stlink -Vcs-Git: https://github.com/bluca/stlink.git +Vcs-Git: https://github.com/bluca/stlink.git -b debian Vcs-Browser: https://github.com/bluca/stlink Package: libstlink-dev From 52189af7a2274b7a57b4ae36454df62bf9e06b5d Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 29 Sep 2019 12:45:57 +0100 Subject: [PATCH 0675/1435] Set Rules-Requires-Root: no --- debian/control | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/control b/debian/control index 5994ea084..e38a046fd 100644 --- a/debian/control +++ b/debian/control @@ -3,6 +3,7 @@ Priority: optional Maintainer: Luca Boccassi Build-Depends: debhelper (>= 9), cmake, libusb-1.0-0-dev, libgtk-3-dev Standards-Version: 4.1.3 +Rules-Requires-Root: no Section: electronics Homepage: https://github.com/texane/stlink Vcs-Git: https://github.com/bluca/stlink.git -b debian From 4f29ef92bf5095f3152564319a2be4bda1d1d7df Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 29 Sep 2019 12:48:53 +0100 Subject: [PATCH 0676/1435] Bump Standards-Version to 4.4.0 --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index e38a046fd..c541d5bef 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: stlink Priority: optional Maintainer: Luca Boccassi Build-Depends: debhelper (>= 9), cmake, libusb-1.0-0-dev, libgtk-3-dev -Standards-Version: 4.1.3 +Standards-Version: 4.4.0 Rules-Requires-Root: no Section: electronics Homepage: https://github.com/texane/stlink From 0b629606aaa7608656487eccf7dd55c647743e4e Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 29 Sep 2019 12:51:05 +0100 Subject: [PATCH 0677/1435] Update changelog for 1.5.1+ds-2 release --- debian/changelog | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/debian/changelog b/debian/changelog index b0c877388..5d132ca55 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,14 @@ +stlink (1.5.1+ds-2) unstable; urgency=medium + + * Mark library packages as Multi-Arch: same. + * Apply cross.patch to fix cross-compiling the GUI. Thanks Helmut for + the patch! (Closes: #941320) + * Vcs-Git: add -b debian + * Set Rules-Requires-Root: no + * Bump Standards-Version to 4.4.0 + + -- Luca Boccassi Sun, 29 Sep 2019 12:50:58 +0100 + stlink (1.5.1+ds-1) unstable; urgency=medium * Merge tag 'v1.5.1' into debian. See upstream changelog for info: From 4eec4d8cb9ace920bbce8f023c5f39dbcb35e770 Mon Sep 17 00:00:00 2001 From: orie Date: Mon, 7 Oct 2019 14:46:36 +0900 Subject: [PATCH 0678/1435] Add Option Byte Write command for STM32F2 series. --- include/stlink.h | 1 + include/stlink/tools/flash.h | 5 ++- include/stm32.h | 2 +- src/common.c | 87 +++++++++++++++++++++++++++++++++++- src/tools/flash.c | 13 ++++-- src/tools/flash_opts.c | 30 ++++++++++++- 6 files changed, 131 insertions(+), 7 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 96be91033..50f86c11b 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -200,6 +200,7 @@ typedef struct flash_loader { int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); + int stlink_fwrite_option_bytes_32bit(stlink_t *sl,uint32_t val); int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, 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); diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index af82198f2..8ca1eddf9 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -9,6 +9,7 @@ enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3, CMD_RESET = 4}; enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1}; +enum flash_area {FLASH_MAIN_MEMORY = 0, FLASH_SYSTEM_MEMORY = 1,FLASH_OTP = 2, FLASH_OPTION_BYTES = 3}; struct flash_opts { enum flash_cmd cmd; @@ -20,10 +21,12 @@ struct flash_opts int reset; int log_level; enum flash_format format; + enum flash_area area; + uint32_t val; size_t flash_size; /* --flash=n[k][m] */ }; -#define FLASH_OPTS_INITIALIZER {0, NULL, { 0 }, NULL, 0, 0, 0, 0, 0, 0 } +#define FLASH_OPTS_INITIALIZER {0, NULL, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0 } int flash_get_opts(struct flash_opts* o, int ac, char** av); diff --git a/include/stm32.h b/include/stm32.h index a19707bc2..8f8e7eba1 100644 --- a/include/stm32.h +++ b/include/stm32.h @@ -16,5 +16,5 @@ #define STM32_SRAM_BASE ((uint32_t)0x20000000) #define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_L0_CAT2_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) - +#define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) #endif /* STM32_H */ diff --git a/src/common.c b/src/common.c index 25900abdd..bf1aba64c 100644 --- a/src/common.c +++ b/src/common.c @@ -194,6 +194,23 @@ #define FLASH_F4_CR_SNB_MASK 0xf8 #define FLASH_F4_SR_BSY 16 +//STM32F2 +#define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F2_KEYR (FLASH_F2_REGS_ADDR + 0x04) +#define FLASH_F2_OPT_KEYR (FLASH_F2_REGS_ADDR + 0x08) +#define FLASH_F2_SR (FLASH_F2_REGS_ADDR + 0x0c) +#define FLASH_F2_CR (FLASH_F2_REGS_ADDR + 0x10) +#define FLASH_F2_OPT_CR (FLASH_F2_REGS_ADDR + 0x14) +#define FLASH_F2_OPT_LOCK_BIT (1u << 0) +#define FLASH_F2_CR_STRT 16 +#define FLASH_F2_CR_LOCK 31 + +#define FLASH_F2_CR_SER 1 +#define FLASH_F2_CR_SNB 3 +#define FLASH_F2_CR_SNB_MASK 0x78 +#define FLASH_F2_SR_BSY 16 + + #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 @@ -2642,6 +2659,56 @@ static int stlink_write_option_bytes_l0_cat2(stlink_t *sl, uint8_t* base, uint32 return 0; } +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_f2(stlink_t *sl, uint32_t option_byte) { + uint32_t val; + + stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); + if (val & FLASH_F2_OPT_LOCK_BIT) { + WLOG("Unlocking option flash\n"); + //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) + //https://www.st.com/resource/en/programming_manual/cd00233952.pdf + stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, 0x08192A3B); + stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, 0x4C5D6E7F); + + stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); + if (val & FLASH_F2_OPT_LOCK_BIT) { + ELOG("Option flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + } + + stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); + WLOG("option bytes CR = %x\n",val); + + stlink_write_debug32(sl, FLASH_F2_OPT_CR, option_byte & 0x0FFFFFFC); + + stlink_write_debug32(sl, FLASH_F2_OPT_CR, (option_byte & 0x0FFFFFFC)|0x00000002); + + + stlink_read_debug32(sl, FLASH_F2_SR, &val); + WLOG("wait BSY flag to be 0\n"); + + while(val & 0x00010000){ + stlink_read_debug32(sl, FLASH_F2_SR, &val); + } + WLOG("BSY flag is 0\n"); + + stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); + WLOG("option bytes CR = %x\n",val); + WLOG("Option flash re-lock\n"); + stlink_write_debug32(sl, FLASH_F2_OPT_CR, val | 0x00000001); + + DLOG("STM32 F2 option bytes are written\n"); + + return 0; +} + /** * Write option bytes * @param sl @@ -2662,7 +2729,7 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui return stlink_write_option_bytes_l0_cat2(sl, base, len); } else { - ELOG("Option bytes writing is currently only supported for the STM32G0 and STM32L0\n"); + ELOG("Option bytes writing is currently only supported for the STM32F2, STM32G0 and STM32L0\n"); return -1; } @@ -2690,3 +2757,21 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr unmap_file(&mf); return err; } + +/** + * Write the given 32-bit value with option byte + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_fwrite_option_bytes_32bit(stlink_t *sl, uint32_t val) { + + if(sl->chip_id == STLINK_CHIPID_STM32_F2){ + return stlink_write_option_bytes_f2(sl, val); + } + else + { + ELOG("Option bytes writing is currently only supported for the STM32F2, STM32G0 and STM32L0\n"); + return -1; + } +} diff --git a/src/tools/flash.c b/src/tools/flash.c index 1a02b4fb4..91fa1c6d6 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -38,6 +38,7 @@ static void usage(void) puts(" fsize: Use decimal, octal or hex by prefix 0xXXX for hex, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); puts(" Format may be 'binary' (default) or 'ihex', although must be specified for binary format only."); puts(" ./st-flash [--version]"); + puts("example write option byte: ./st-flash --debug --reset --area=option write 0xXXXXXXXX"); } int main(int ac, char** av) @@ -131,7 +132,6 @@ int main(int ac, char** av) if (o.cmd == FLASH_CMD_WRITE) /* write */ { size_t size = 0; - if(o.format == FLASH_FORMAT_IHEX) { err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr); if (err == -1) { @@ -139,7 +139,6 @@ int main(int ac, char** av) goto on_error; } } - if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { if(o.format == FLASH_FORMAT_IHEX) @@ -164,7 +163,7 @@ int main(int ac, char** av) goto on_error; } } - else if (o.addr == STM32_G0_OPTION_BYTES_BASE || o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE) { + else if (o.addr == STM32_G0_OPTION_BYTES_BASE || o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE){ err = stlink_fwrite_option_bytes(sl, o.filename, o.addr); if (err == -1) { @@ -172,6 +171,14 @@ int main(int ac, char** av) goto on_error; } } + else if (o.area == FLASH_OPTION_BYTES){ + err = stlink_fwrite_option_bytes_32bit(sl, o.val); + if (err == -1) + { + printf("stlink_fwrite_option_bytes() == -1\n"); + goto on_error; + } + } else { err = -1; printf("Unknown memory region\n"); diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 4fa39de4c..ab066de0a 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -58,6 +58,29 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) serial_specified = true; } + else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { + const char * area; + if(strcmp(av[0], "--area") == 0) { + ac--; + av++; + if (ac < 1) return -1; + area = av[0]; + } + else { + area = av[0] + strlen("--area="); + } + if (strcmp(area, "main") == 0) + o->area = FLASH_MAIN_MEMORY; + else if (strcmp(area, "system") == 0) + o->area = FLASH_SYSTEM_MEMORY; + else if (strcmp(area, "otp") == 0) + o->area = FLASH_OTP; + else if (strcmp(area, "option") == 0) + o->area = FLASH_OPTION_BYTES; + else + return -1; + + } else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { const char * format; if(strcmp(av[0], "--format") == 0) { @@ -161,7 +184,12 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) break; case FLASH_CMD_WRITE: - if(o->format == FLASH_FORMAT_BINARY) { // expect filename and addr + if(o->area == FLASH_OPTION_BYTES){ + if(ac != 1) return -1; + + o->val = (uint32_t)strtoul(av[0], &tail, 16); + } + else if(o->format == FLASH_FORMAT_BINARY) { // expect filename and addr if (ac != 2) return -1; o->filename = av[0]; From 94aef4557071a3f6b8bf91cd3196db8527fb9f3b Mon Sep 17 00:00:00 2001 From: Orie22 Date: Mon, 7 Oct 2019 18:50:59 +0900 Subject: [PATCH 0679/1435] Add read Option-bytes command for STM32F2 series --- include/stlink.h | 1 + src/common.c | 33 +++++++++++++++++++++++++++++++++ src/tools/flash.c | 21 +++++++++++++++++---- src/tools/flash_opts.c | 1 + 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 50f86c11b..0715166e5 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -222,6 +222,7 @@ typedef struct flash_loader { int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); int stlink_load_device_params(stlink_t *sl); + int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte); #include "stlink/sg.h" #include "stlink/usb.h" diff --git a/src/common.c b/src/common.c index bf1aba64c..207be3d8a 100644 --- a/src/common.c +++ b/src/common.c @@ -2709,6 +2709,39 @@ static int stlink_write_option_bytes_f2(stlink_t *sl, uint32_t option_byte) { return 0; } +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { + uint32_t val; + + stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); + if (val & FLASH_F2_OPT_LOCK_BIT) { + WLOG("Unlocking option flash\n"); + //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) + //https://www.st.com/resource/en/programming_manual/cd00233952.pdf + stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, 0x08192A3B); + stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, 0x4C5D6E7F); + + stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); + if (val & FLASH_F2_OPT_LOCK_BIT) { + ELOG("Option flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + } + + stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); + WLOG("option bytes CR = %x\n",option_byte); + + WLOG("Option flash re-lock\n"); + stlink_write_debug32(sl, FLASH_F2_OPT_CR, val | 0x00000001); + + return 0; +} + /** * Write option bytes * @param sl diff --git a/src/tools/flash.c b/src/tools/flash.c index 91fa1c6d6..8bdddc566 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -39,6 +39,7 @@ static void usage(void) puts(" Format may be 'binary' (default) or 'ihex', although must be specified for binary format only."); puts(" ./st-flash [--version]"); puts("example write option byte: ./st-flash --debug --reset --area=option write 0xXXXXXXXX"); + puts("example read option byte: ./st-flash --debug --reset --area=option read > option_byte"); } int main(int ac, char** av) @@ -208,13 +209,25 @@ int main(int ac, char** av) } else /* read */ { - if ((o.addr >= sl->flash_base) && (o.size == 0) && - (o.addr < sl->flash_base + sl->flash_size)) + if(o.area == FLASH_OPTION_BYTES){ + if(sl->chip_id == STLINK_CHIPID_STM32_F2){ + uint32_t option_byte = 0; + err = stlink_read_option_bytes_f2(sl,&option_byte); + printf("%x\n",option_byte); + }else{ + printf("This format is available for STM32F2 Only\n"); + } + } + else if ((o.addr >= sl->flash_base) && (o.size == 0) && + (o.addr < sl->flash_base + sl->flash_size)){ o.size = sl->flash_size; + err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); + } else if ((o.addr >= sl->sram_base) && (o.size == 0) && - (o.addr < sl->sram_base + sl->sram_size)) + (o.addr < sl->sram_base + sl->sram_size)){ o.size = sl->sram_size; - err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); + err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); + } if (err == -1) { printf("stlink_fread() == -1\n"); diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index ab066de0a..3f74ac057 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -172,6 +172,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) break; case FLASH_CMD_READ: // expect filename, addr and size + if((o->area == FLASH_OPTION_BYTES) &&(ac == 0)) break; if (ac != 3) return -1; o->filename = av[0]; From 4a32157143547755cab260e58d1b00f8ddaa7780 Mon Sep 17 00:00:00 2001 From: Orie22 Date: Wed, 9 Oct 2019 11:25:53 +0900 Subject: [PATCH 0680/1435] bug fix: normal read operation was not executed --- src/tools/flash.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tools/flash.c b/src/tools/flash.c index 8bdddc566..33e1c8dc0 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -217,15 +217,15 @@ int main(int ac, char** av) }else{ printf("This format is available for STM32F2 Only\n"); } - } - else if ((o.addr >= sl->flash_base) && (o.size == 0) && - (o.addr < sl->flash_base + sl->flash_size)){ - o.size = sl->flash_size; - err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); - } - else if ((o.addr >= sl->sram_base) && (o.size == 0) && - (o.addr < sl->sram_base + sl->sram_size)){ - o.size = sl->sram_size; + }else{ + if ((o.addr >= sl->flash_base) && (o.size == 0) && + (o.addr < sl->flash_base + sl->flash_size)){ + o.size = sl->flash_size; + } + else if ((o.addr >= sl->sram_base) && (o.size == 0) && + (o.addr < sl->sram_base + sl->sram_size)){ + o.size = sl->sram_size; + } err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); } if (err == -1) From 9e44de25a8d24aae12a17b2205317c94fcded04f Mon Sep 17 00:00:00 2001 From: Brad Natelborg Date: Fri, 11 Oct 2019 13:08:34 -0400 Subject: [PATCH 0681/1435] Adding full support for STLINK CHIP ID L4RX --- src/common.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/common.c b/src/common.c index 207be3d8a..bfcbe715f 100644 --- a/src/common.c +++ b/src/common.c @@ -1659,7 +1659,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || (sl->chip_id == STLINK_CHIPID_STM32_L43X) || (sl->chip_id == STLINK_CHIPID_STM32_L46X) || - (sl->chip_id == STLINK_CHIPID_STM32_L496X)) { + (sl->chip_id == STLINK_CHIPID_STM32_L496X) || + (sl->chip_id == STLINK_CHIPID_STM32_L4RX)) { // calculate the actual bank+page from the address uint32_t page = calculate_L4_page(sl, flashaddr); @@ -1779,11 +1780,11 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) if (sl->flash_type == STLINK_FLASH_TYPE_WB) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - + // sec 3.10.5 - PNB[7:0] is offset by 3. val &= ~(0xFF << 3); // Clear previously set page number (if any) val |= ((flash_page & 0xFF) << 3); - + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); @@ -2086,7 +2087,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t if ((sl->chip_id != STLINK_CHIPID_STM32_L4) && (sl->chip_id != STLINK_CHIPID_STM32_L43X) && (sl->chip_id != STLINK_CHIPID_STM32_L46X) && - (sl->chip_id != STLINK_CHIPID_STM32_L496X)) { + (sl->chip_id != STLINK_CHIPID_STM32_L496X) && + (sl->chip_id != STLINK_CHIPID_STM32_L4RX)) { if( sl->version.stlink_v == 1 ) { printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes on F4 devices\n"); From 0948cd19b27b0f66e12145dbf1c911f50c31d039 Mon Sep 17 00:00:00 2001 From: Davey Struijk Date: Fri, 25 Oct 2019 14:32:36 +0200 Subject: [PATCH 0682/1435] Allow writing option bytes to STM32F4 devices --- include/stlink.h | 1 + src/common.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++- src/tools/flash.c | 6 +++- 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 0715166e5..5defe4e98 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -223,6 +223,7 @@ typedef struct flash_loader { int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); int stlink_load_device_params(stlink_t *sl); int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte); + int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte); #include "stlink/sg.h" #include "stlink/usb.h" diff --git a/src/common.c b/src/common.c index bfcbe715f..99bd7a842 100644 --- a/src/common.c +++ b/src/common.c @@ -187,6 +187,7 @@ #define FLASH_F4_SR (FLASH_F4_REGS_ADDR + 0x0c) #define FLASH_F4_CR (FLASH_F4_REGS_ADDR + 0x10) #define FLASH_F4_OPT_CR (FLASH_F4_REGS_ADDR + 0x14) +#define FLASH_F4_OPT_LOCK_BIT (1u << 0) #define FLASH_F4_CR_STRT 16 #define FLASH_F4_CR_LOCK 31 #define FLASH_F4_CR_SER 1 @@ -2711,6 +2712,56 @@ static int stlink_write_option_bytes_f2(stlink_t *sl, uint32_t option_byte) { return 0; } +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_f4(stlink_t *sl, uint32_t option_byte) { + uint32_t val; + + stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); + if (val & FLASH_F4_OPT_LOCK_BIT) { + WLOG("Unlocking option flash\n"); + //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) + //https://www.st.com/resource/en/programming_manual/cd00233952.pdf + stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, 0x08192A3B); + stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, 0x4C5D6E7F); + + stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); + if (val & FLASH_F4_OPT_LOCK_BIT) { + ELOG("Option flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + } + + stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); + WLOG("option bytes CR = %x\n",val); + + stlink_write_debug32(sl, FLASH_F4_OPT_CR, option_byte & 0x0FFFFFFC); + + stlink_write_debug32(sl, FLASH_F4_OPT_CR, (option_byte & 0x0FFFFFFC)|0x00000002); + + + stlink_read_debug32(sl, FLASH_F4_SR, &val); + WLOG("wait BSY flag to be 0\n"); + + while(val & 0x00010000){ + stlink_read_debug32(sl, FLASH_F4_SR, &val); + } + WLOG("BSY flag is 0\n"); + + stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); + WLOG("option bytes CR = %x\n",val); + WLOG("Option flash re-lock\n"); + stlink_write_debug32(sl, FLASH_F4_OPT_CR, val | 0x00000001); + + DLOG("STM32 F4 option bytes are written\n"); + + return 0; +} + /** * Read option bytes * @param sl @@ -2744,6 +2795,39 @@ int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { return 0; } +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { + uint32_t val; + + stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); + if (val & FLASH_F4_OPT_LOCK_BIT) { + WLOG("Unlocking option flash\n"); + //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) + //https://www.st.com/resource/en/programming_manual/cd00233952.pdf + stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, 0x08192A3B); + stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, 0x4C5D6E7F); + + stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); + if (val & FLASH_F4_OPT_LOCK_BIT) { + ELOG("Option flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + } + + stlink_read_debug32(sl, FLASH_F4_OPT_CR, option_byte); + WLOG("option bytes CR = %x\n",option_byte); + + WLOG("Option flash re-lock\n"); + stlink_write_debug32(sl, FLASH_F4_OPT_CR, val | 0x00000001); + + return 0; +} + /** * Write option bytes * @param sl @@ -2803,10 +2887,12 @@ int stlink_fwrite_option_bytes_32bit(stlink_t *sl, uint32_t val) { if(sl->chip_id == STLINK_CHIPID_STM32_F2){ return stlink_write_option_bytes_f2(sl, val); + }else if(sl->chip_id == STLINK_CHIPID_STM32_F446){ + return stlink_write_option_bytes_f4(sl, val); } else { - ELOG("Option bytes writing is currently only supported for the STM32F2, STM32G0 and STM32L0\n"); + ELOG("Option bytes writing is currently only supported for the STM32F2, STM32F4, STM32G0 and STM32L0\n"); return -1; } } diff --git a/src/tools/flash.c b/src/tools/flash.c index 33e1c8dc0..f5fd1a386 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -214,8 +214,12 @@ int main(int ac, char** av) uint32_t option_byte = 0; err = stlink_read_option_bytes_f2(sl,&option_byte); printf("%x\n",option_byte); + }else if(sl->chip_id == STLINK_CHIPID_STM32_F446){ + uint32_t option_byte = 0; + err = stlink_read_option_bytes_f4(sl,&option_byte); + printf("%x\n",option_byte); }else{ - printf("This format is available for STM32F2 Only\n"); + printf("This format is available for STM32F2 and STM32F4 Only\n"); } }else{ if ((o.addr >= sl->flash_base) && (o.size == 0) && From 302dc872f4b73f13a94ff2e9f0359c4195f6279c Mon Sep 17 00:00:00 2001 From: zx81a Date: Tue, 5 Nov 2019 10:24:22 +0100 Subject: [PATCH 0683/1435] Support for STM31L4, SM32L1 option bytes write. --- debian/rules | 2 +- include/stm32.h | 3 + src/common.c | 191 +++++++++++++++++++++++++++++++++++++++++++++- src/tools/flash.c | 2 +- 4 files changed, 194 insertions(+), 4 deletions(-) diff --git a/debian/rules b/debian/rules index e228a7087..e183fffb7 100755 --- a/debian/rules +++ b/debian/rules @@ -1,7 +1,7 @@ #!/usr/bin/make -f # See debhelper(7) (uncomment to enable) # output every command that modifies files on the build system. -#DH_VERBOSE = 1 +DH_VERBOSE = 1 # see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* DPKG_EXPORT_BUILDFLAGS = 1 diff --git a/include/stm32.h b/include/stm32.h index 8f8e7eba1..9a01baaf4 100644 --- a/include/stm32.h +++ b/include/stm32.h @@ -17,4 +17,7 @@ #define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_L0_CAT2_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) #define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) +#define STM32_L496X_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) +#define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) + #endif /* STM32_H */ diff --git a/src/common.c b/src/common.c index 99bd7a842..4d976f49f 100644 --- a/src/common.c +++ b/src/common.c @@ -137,6 +137,7 @@ //32L4 register base is at FLASH_REGS_ADDR (0x40022000) #define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) +#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) #define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) #define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) #define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) @@ -145,13 +146,16 @@ #define STM32L4_FLASH_SR_ERRMASK 0x3f8 /* SR [9:3] */ #define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ +#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ #define STM32L4_FLASH_CR_PG 0 /* Program */ #define STM32L4_FLASH_CR_PER 1 /* Page erase */ #define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ #define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ #define STM32L4_FLASH_CR_STRT 16 /* Start command */ +#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ #define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ #define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ +#define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ // Bits requesting flash operations (useful when we want to clear them) #define STM32L4_FLASH_CR_OPBITS \ ((1lu<chip_id,addr); + /* Check if chip is supported and for correct address */ if((sl->chip_id == STLINK_CHIPID_STM32_G0X1) && (addr == STM32_G0_OPTION_BYTES_BASE)) { return stlink_write_option_bytes_g0x1(sl, base, len); @@ -2847,8 +3027,15 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui else if((sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) && (addr == STM32_L0_CAT2_OPTION_BYTES_BASE)) { return stlink_write_option_bytes_l0_cat2(sl, base, len); } + else if((sl->chip_id == STLINK_CHIPID_STM32_L496X) && (addr == STM32_L496X_OPTION_BYTES_BASE)) { + return stlink_write_option_bytes_l496x(sl, base, len); + } + else if( ( (sl->chip_id == STLINK_CHIPID_STM32_L152_RE) || (sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH) ) + && ( (addr == STM32_L1_OPTION_BYTES_BASE) || (addr == STM32_L1_OPTION_BYTES_BASE+4) ) ) { + return stlink_write_option_bytes_l1(sl, base, addr, len); + } else { - ELOG("Option bytes writing is currently only supported for the STM32F2, STM32G0 and STM32L0\n"); + ELOG("Option bytes writing is currently only supported for the STM32F2, STM32G0, STM32L496x/L4A6x, STM32L1 and STM32L0\n"); return -1; } diff --git a/src/tools/flash.c b/src/tools/flash.c index f5fd1a386..1b63b1696 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -164,7 +164,7 @@ int main(int ac, char** av) goto on_error; } } - else if (o.addr == STM32_G0_OPTION_BYTES_BASE || o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE){ + else if (o.addr == STM32_G0_OPTION_BYTES_BASE || o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE || o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE + 4){ err = stlink_fwrite_option_bytes(sl, o.filename, o.addr); if (err == -1) { From 8f6314078b6fe3221008518888474aa008cfda3d Mon Sep 17 00:00:00 2001 From: Mark Odell Date: Mon, 23 Dec 2019 14:25:37 -0500 Subject: [PATCH 0684/1435] Improved support for STM32G0xx series parts - Now properly distinguish between the smaller and larger variants - Added support for the smaller variants, 'G030, 'G031, and 'G041 - Now flashes and debugs STM32G031K8 MCU --- include/stlink/chipid.h | 3 ++- src/chipid.c | 17 ++++++++++++++--- src/common.c | 4 ++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index a4f4be4c0..ae665efd3 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -71,7 +71,8 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F410 = 0x458, STLINK_CHIPID_STM32_F413 = 0x463, STLINK_CHIPID_STM32_L4RX = 0x470, // taken from the STM32L4R9I-DISCO board - STLINK_CHIPID_STM32_G0X1 = 0x460, + STLINK_CHIPID_STM32_G07X = 0x460, // Actually, 'G070 and 'G071/081 + STLINK_CHIPID_STM32_G03X = 0x466, // Actually, 'G030 and 'G031/041 STLINK_CHIPID_STM32_WB55 = 0x495 }; diff --git a/src/chipid.c b/src/chipid.c index d627849a3..2fd860223 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -522,9 +522,9 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x2000 }, { - // STM32G071/081 (from RM0444) - .chip_id = STLINK_CHIPID_STM32_G0X1, - .description = "G071/G081 device", + // STM32G071/081 (from RM0454 & RM0444) + .chip_id = STLINK_CHIPID_STM32_G07X, + .description = "G070/G071/G081 device", .flash_type = STLINK_FLASH_TYPE_G0, .flash_size_reg = 0x1FFF75E0, // Section 38.2 .flash_pagesize = 0x800, // 2K (sec 3.2) @@ -532,6 +532,17 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 // 30K (table 2) }, + { + // STM32G031/041 (from RM0454 & RM0444) + .chip_id = STLINK_CHIPID_STM32_G03X, + .description = "G030/G031/G041 device", + .flash_type = STLINK_FLASH_TYPE_G0, + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2K (sec 3.2) + .sram_size = 0x2000, // 8K (sec 2.3) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x2000 // 8k (table 2) + }, { // STM32WB55 (from RM0434) .chip_id = STLINK_CHIPID_STM32_WB55, diff --git a/src/common.c b/src/common.c index 99bd7a842..ee65018ba 100644 --- a/src/common.c +++ b/src/common.c @@ -2535,7 +2535,7 @@ static int stlink_write_option_bytes_g0x1(stlink_t *sl, uint8_t* base, uint32_t uint32_t val; if(len != 4) { - ELOG("Wrong length for writting option bytes, must be 4 is %d\n", len); + ELOG("Wrong length for writing option bytes, must be 4 is %d\n", len); return -1; } @@ -2841,7 +2841,7 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui stlink_core_id(sl); /* Check if chip is supported and for correct address */ - if((sl->chip_id == STLINK_CHIPID_STM32_G0X1) && (addr == STM32_G0_OPTION_BYTES_BASE)) { + if (((sl->chip_id == STLINK_CHIPID_STM32_G07X) || (sl->chip_id == STLINK_CHIPID_STM32_G03X)) && (addr == STM32_G0_OPTION_BYTES_BASE)) { return stlink_write_option_bytes_g0x1(sl, base, len); } else if((sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) && (addr == STM32_L0_CAT2_OPTION_BYTES_BASE)) { From f070345249800a5436dbfdd9f29fbca8f00744f7 Mon Sep 17 00:00:00 2001 From: kraus Date: Sat, 4 Jan 2020 15:05:22 +0100 Subject: [PATCH 0685/1435] added several comments on the stlink software structure --- doc/developer.txt | 398 ++++++++++++++++++++++++++++++++++++++++++++++ include/stlink.h | 24 +-- src/common.c | 7 +- 3 files changed, 417 insertions(+), 12 deletions(-) create mode 100644 doc/developer.txt diff --git a/doc/developer.txt b/doc/developer.txt new file mode 100644 index 000000000..2d05b9312 --- /dev/null +++ b/doc/developer.txt @@ -0,0 +1,398 @@ + +=== Target Identification === + +The following information is available about the target: +- chip id: 0xE0042000 or 0x40015800, primary information to derive flash and sram architection +- core id: Result from the STLINK_DEBUGREADCOREID call, additionally used for flash/sram architection +- cpu id: 0xE000ED00 (CMSIS System Control Block CPU ID), not used in stlink + + +=== Backend === + +The "backend" implements the interface to the adapter hardware. +There are two backends for two different adapters: "sg" (stlink v1?) and "usb" (stlink v2?). + + + +Include stlink/backend.h + typedef struct _stlink_backend { + void (*close) (stlink_t * sl); + int (*exit_debug_mode) (stlink_t * sl); + int (*enter_swd_mode) (stlink_t * sl); + int (*enter_jtag_mode) (stlink_t * stl); + int (*exit_dfu_mode) (stlink_t * stl); + int (*core_id) (stlink_t * stl); + int (*reset) (stlink_t * stl); + int (*jtag_reset) (stlink_t * stl, int value); + int (*run) (stlink_t * stl); + int (*status) (stlink_t * stl); + int (*version) (stlink_t *sl); + int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); + int (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); + int (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); + int (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); + int (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); + int (*read_all_regs) (stlink_t *sl, struct stlink_reg * regp); + int (*read_reg) (stlink_t *sl, int r_idx, struct stlink_reg * regp); + int (*read_all_unsupported_regs) (stlink_t *sl, struct stlink_reg *regp); + int (*read_unsupported_reg) (stlink_t *sl, int r_idx, struct stlink_reg *regp); + int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, struct stlink_reg *regp); + int (*write_reg) (stlink_t *sl, uint32_t reg, int idx); + int (*step) (stlink_t * stl); + int (*current_mode) (stlink_t * stl); + int (*force_debug) (stlink_t *sl); + int32_t (*target_voltage) (stlink_t *sl); + int (*set_swdclk) (stlink_t * stl, uint16_t divisor); + } stlink_backend_t; + +Descriptions below describe the actions of the usb.h backend: + +void (*close) (stlink_t * sl); +int (*exit_debug_mode) (stlink_t * sl); + __stlink_usb_exit_debug_mode: Send STLINK_DEBUG_EXIT + returns -1 or 0 + +int (*enter_swd_mode) (stlink_t * sl); + _stlink_usb_enter_swd_mode: Send STLINK_DEBUG_ENTER+STLINK_DEBUG_ENTER_SWD + returns -1 or 0 + +int (*enter_jtag_mode) (stlink_t * stl); + +int (*exit_dfu_mode) (stlink_t * stl); + _stlink_usb_exit_dfu_mode: Send STLINK_DFU_EXIT + returns -1 or 0 + +int (*core_id) (stlink_t * stl); + _stlink_usb_core_id: Assign the result from STLINK_DEBUG_READCOREID to stl->core_id + returns -1 or 0 + +int (*reset) (stlink_t * stl); + _stlink_usb_reset: Send STLINK_DEBUG_RESETSYS and reset via AIRCR + AIRCR is part of the CMSIS System Control Block (SCB), which is located in + the System Control Space at 0xE000ED0C + returns -1 or 0 ? + +int (*jtag_reset) (stlink_t * stl, int value); + _stlink_usb_jtag_reset: Send STLINK_JTAG_DRIVE_NRST. + "value" is sent as argument for STLINK_JTAG_DRIVE_NRST and probably contains + the status of the NRST line (0: low, 1: high). Also the value 2 is used in the software. + returns -1 or 0 + +int (*run) (stlink_t * stl); + _stlink_usb_run: Send STLINK_DEBUG_RUNCORE + returns -1 or 0 + +int (*status) (stlink_t * stl); + _stlink_usb_status: Assign the result from STLINK_DEBUG_GETSTATUS to stl->q_len + returns -1 or 0 + +int (*version) (stlink_t *sl); + _stlink_usb_version: Read version with STLINK_GET_VERSION. + Result is stored in sl->q_buf (6 bytes????) + returns -1 or 0 + +int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); + _stlink_usb_read_debug32: Send STLINK_JTAG_READDEBUG_32BIT + to read 32 bits from "addr". The result data is stored at "*data". + returns -1 or 0 + +int (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); + _stlink_usb_read_mem32: Use STLINK_DEBUG_READMEM_32BIT + to read "len" bytes from "addr" + Result is returned in sl->q_buf, sl->q_len returns the size of the data (should be + equal to "len"???). + returns -1 or 0 + +int (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); + _stlink_usb_write_debug32: Use STLINK_JTAG_WRITEDEBUG_32BIT + to store "data" at "addr" + returns -1 or 0 + +int (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); + _stlink_usb_write_mem32: Use STLINK_DEBUG_WRITEMEM_32BIT to + send data stored in sl->q_buf to the target at "addr". + "len" is the size data (???? not clear whether this are bytes ) + returns -1 or 0 + +int (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); + _stlink_usb_write_mem8: Use STLINK_DEBUG_WRITEMEM_8BIT to + send data stored in sl->q_buf to the target at "addr". + "len" is the size in bytes (probably). + returns -1 or 0 + +int (*read_all_regs) (stlink_t *sl, struct stlink_reg * regp); + _stlink_usb_read_all_regs: Send STLINK_DEBUG_READALLREGS to read + all register values and store them into *regp; + returns -1 or 0 + +int (*read_reg) (stlink_t *sl, int r_idx, struct stlink_reg * regp); + _stlink_usb_read_reg: Send STLINK_DEBUG_READREG to read specific register "r_idx". + The result is then stored in *regp in the correct register. + Example if "r_idx" is 18, then the result is stored in regp->process_sp + returns -1 or 0 + +int (*read_all_unsupported_regs) (stlink_t *sl, struct stlink_reg *regp); + _stlink_usb_read_all_unsupported_regs: Calls "_stlink_usb_read_unsupported_reg" + (see below) to read all registers. + returns -1 or 0 + +int (*read_unsupported_reg) (stlink_t *sl, int r_idx, struct stlink_reg *regp); + _stlink_usb_read_unsupported_reg Use DCRSR and DCRDR to access some + of the internal registers (primask, basepri, faultmask, control, fpscr). + Also will fill regp->s (???) for some specific "r_idx" values. + WARNING: Some r_idx values may lead to a out of array bound problem in C. + returns -1 or 0 + +int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, struct stlink_reg *regp); + _stlink_usb_write_unsupported_reg: + Updates one of the following registers: + primask (idx=0x1c), basepri (idx=0x1d), faultmask (idx=0x1e), control (idx=0x1f) + The new value is given as "value" as fn argument. + Corresponding values are refreshed in regp, however the old value for is kept in regp: + If basepri has to be updated (idx=0x1d), then all register values are fetched and + basepri is updated in the core, but not in *regp (BUG???). + returns -1 or 0 + +int (*write_reg) (stlink_t *sl, uint32_t reg, int idx); + _stlink_usb_write_reg: Use STLINK_DEBUG_WRITEREG to update register "idx" + with value "reg". + returns -1 or 0 + +int (*step) (stlink_t * stl); + _stlink_usb_step: Send STLINK_DEBUG_STEPCORE + returns -1 or 0 + +int (*current_mode) (stlink_t * stl); + _stlink_usb_current_mode: Send STLINK_GET_CURRENT_MODE and return + the current mode. + returns -1 or the value for the current mode. + Modes probably are: + STLINK_DEV_DFU_MODE 0x00 + STLINK_DEV_MASS_MODE 0x01 + STLINK_DEV_DEBUG_MODE 0x02 + +int (*force_debug) (stlink_t *sl); + _stlink_usb_force_debug: Sends STLINK_DEBUG_FORCEDEBUG. No other side effects + returns -1 or 0 + +int32_t (*target_voltage) (stlink_t *sl); + _stlink_usb_target_voltage: Send STLINK_GET_TARGET_VOLTAGE + returns -1 or the target voltage. (??? dimension is not clear...) + +int (*set_swdclk) (stlink_t * stl, uint16_t divisor); + _stlink_usb_set_swdclk: Send STLINK_DEBUG_APIV2_SWD_SET_FREQ and "divisor" value + returns -1 or 0 + + +=== Other Functions === + + +Include: stlink.h + + +Prototype: void stlink_close(stlink_t *sl); +Include: inc/stlink.h +Definition: src/common.c +Description: + Calls the backend "close" procedure and frees 'sl' +Backend: "close" +Arguments: + sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() +Return: - + +Include: inc/stlink.h +Prototype: int stlink_core_id(stlink_t *sl); +Definition: src/common.c +Description: + Calls the backend "core_id", calls stlink_print_data() on higher verbose levels. + Assigns the core id returned by STLINK_DEBUGREADCOREID to sl->core_id + Only some specific core ids are used: See include/stm32.h + Usage includes the selection of the correct flash algorithm. +Backend: "core_id" +Arguments: + sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() +Return: -1 for error. 0 for success. + +Include: inc/stlink.h +Prototype: int stlink_reset(stlink_t *sl); +Definition: src/common.c +Description: + Just calls the backend "reset" procedure (reset via STLINK_DEBUG_RESETSYS + and reset via AIRCR register at 0xE000ED0C) +Backend: "reset" +Arguments: + sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() +Return: -1 for error. 0 for success. + +Include: inc/stlink.h +Prototype: int stlink_jtag_reset(stlink_t *sl, int value); +Definition: src/common.c +Description: + Just calls the backend "jtag_reset" procedure +Backend: "jtag_reset" +Arguments: + sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() + value: 0: drive low, 1: drive high, 2: ???? +Return: -1 for error. 0 for success. + + +Include: inc/stlink.h +Prototype: int stlink_run(stlink_t *sl); +Definition: src/common.c +Description: + Just calls the backend "run" procedure. +Backend: "run" +Arguments: + sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() +Return: -1 for error. 0 for success. + +Include: inc/stlink.h +Prototype: int stlink_status(stlink_t *sl); +Definition: src/common.c +Description: + Calls the backend "status" procedure and the procedure "stlink_core_stat()" to + store the status in "sl->core_stat". Possible value for "sl->core_stat" are: + STLINK_CORE_RUNNING + STLINK_CORE_HALTED + STLINK_CORE_STAT_UNKNOWN +Backend: "status" +Arguments: + sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() +Return: -1 for error. 0 for success. + + +Include: inc/stlink.h +Prototype: int stlink_version(stlink_t *sl); +Definition: src/common.c +Description: + Calls the backend "version" procedure, parses the result and puts the result into sl->version + This version probably refers to the version of the adapter. +Backend: "version" +Arguments: + sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() +Return: -1 for error. 0 for success. + + + int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); + int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); + int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); + int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); + int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); + int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp); + int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); + int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); + int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); + int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, struct stlink_reg *regp); + int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); + int stlink_step(stlink_t *sl); + int stlink_current_mode(stlink_t *sl); + int stlink_force_debug(stlink_t *sl); + int stlink_target_voltage(stlink_t *sl); + int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); + + int stlink_erase_flash_mass(stlink_t* sl); + int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); + int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); + uint8_t stlink_get_erased_pattern(stlink_t *sl); + int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); + int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); + int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); + int stlink_fwrite_option_bytes_32bit(stlink_t *sl,uint32_t val); + int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, 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); + +Include: inc/stlink.h +Prototype: int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); +Definition: src/common.c +Description: + Tries to read out the chip id via memory read from the device. + Note: sl->chip_id is NOT updated by this procedure. Instead this happens in stlink_load_device_params(): + Do not call this function, but instead call stlink_load_device_params() +Backend: - +Arguments: + sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() + chip_id: Pointer. Result is stored via this pointer. +Return: -1 for error. 0 for success. + + +Include: inc/stlink.h +Prototype: int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); +Definition: src/common.c +Description: + Reads the CPU id from STLINK_REG_CM3_CPUID (0xE000ED00, first value of + the SCB, system control block) and splits this into + cpuid->implementer_id + cpuid->variant + cpuid->part + cpuid->revision + The result is not used in the tools, but only in the usb test program. +Backend: - +Arguments: + sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() + cpuid: Pointer. Result is stored via this pointer. +Return: -1 for error. 0 for success. + + + + + int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); + uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); + uint16_t read_uint16(const unsigned char *c, const int pt); + void stlink_core_stat(stlink_t *sl); + + +Include: inc/stlink.h +Prototype: void stlink_print_data(stlink_t *sl); +Definition: src/common.c +Description: + If debug logging is enabled: Print the HEX content of the q_buf array. + q_buf will contain the result of the last "backend" command. +Backend: - +Arguments: + sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() +Return: - + + + unsigned int is_bigendian(void); + uint32_t read_uint32(const unsigned char *c, const int pt); + void write_uint32(unsigned char* buf, uint32_t ui); + void write_uint16(unsigned char* buf, uint16_t ui); + bool stlink_is_core_halted(stlink_t *sl); + int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); + int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); + int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); + + +Include: inc/stlink.h +Prototype: int stlink_load_device_params(stlink_t *sl); +Definition: src/common.c +Description: + This is one of the most important procedures. It will get all the device info + and store the results in the "sl" structure. Many other procedures will depend + on this information. + The identification is based on the stlink_chip_id() result and the flash_size register value +Backend: - +Arguments: + sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() +Return: -1 for error. 0 for success. + + int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte); + int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte); + + +Include "flash_loader.h" + +int stlink_flash_loader_init(stlink_t *sl, flash_loader_t* fl); +int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); +int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size); + + +Inlcude "sg.h" +stlink_t* stlink_v1_open(const int verbose, int reset); + +Include "usb.h" + +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE]); +size_t stlink_probe_usb(stlink_t **stdevs[]); +void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); diff --git a/include/stlink.h b/include/stlink.h index 5defe4e98..d4170c7a7 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -142,25 +142,27 @@ typedef struct flash_loader { // transport layer verboseness: 0 for no debug info, 10 for lots int verbose; - uint32_t core_id; - uint32_t chip_id; - int core_stat; + uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID + uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram + int core_stat; // set by stlink_status(), values STLINK_CORE_xxxxx char serial[STLINK_SERIAL_MAX_SIZE]; int serial_size; - enum stlink_flash_type flash_type; - stm32_addr_t flash_base; - size_t flash_size; - size_t flash_pgsz; + enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx + stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() + size_t flash_size; // calculated by stlink_load_device_params() + size_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() /* sram settings */ - stm32_addr_t sram_base; - size_t sram_size; + stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() + size_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() // bootloader - stm32_addr_t sys_base; - size_t sys_size; + // sys_base and sys_size are not used by the tools, but are only there to + // download the bootloader code (see tests/sg.c) + stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() + size_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() struct stlink_version_ version; }; diff --git a/src/common.c b/src/common.c index 99bd7a842..9a3098114 100644 --- a/src/common.c +++ b/src/common.c @@ -748,6 +748,8 @@ int stlink_core_id(stlink_t *sl) { return ret; } +// stlink_chip_id() is called by stlink_load_device_params() +// do not call this procedure directly. int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { int ret; @@ -801,7 +803,7 @@ int stlink_load_device_params(stlink_t *sl) { sl->chip_id = 0x413; } - params = stlink_chipid_get_params(sl->chip_id); + params = stlink_chipid_get_params(sl->chip_id); // chipid.c if (params == NULL) { WLOG("unknown chip id! %#x\n", chip_id); return -1; @@ -1134,6 +1136,9 @@ void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { usleep(3000000); } + +// this function is called by stlink_status() +// do not call stlink_core_stat() directly, always use stlink_status() void stlink_core_stat(stlink_t *sl) { if (sl->q_len <= 0) return; From 2cad920e543bace68a3176532cf6c8da8cf207b7 Mon Sep 17 00:00:00 2001 From: piccaso Date: Tue, 7 Jan 2020 17:02:34 +0100 Subject: [PATCH 0686/1435] Fix dead link in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c7f24c847..b0cad5618 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Mac OS X users can install from [homebrew](http://brewformulas.org/Stlink) or [d Debian Linux users can install it via the ```stlink-tool``` package [repository](https://packages.debian.org/buster/stlink-tools) -Ubuntu Linux users can install it via the ```stlink-tool``` package [repository](https://packages.ubuntu.com/cosmic/stlink-tools) +Ubuntu Linux users can install it via the ```stlink-tool``` package [repository](https://packages.ubuntu.com/stlink-tools) Arch Linux users can install from the [repository](https://www.archlinux.org/packages/community/x86_64/stlink) From 1ec9173a902dd87a300e28dbc29931574f1d5476 Mon Sep 17 00:00:00 2001 From: "Yuriy M. Kaminskiy" Date: Wed, 29 Jan 2020 15:57:39 +0300 Subject: [PATCH 0687/1435] Fix st-flash manpage read example Size must be specified as hexdecimal number (as per both documentation and implementation) --- doc/man/st-flash.1 | 2 +- doc/man/st-flash.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/man/st-flash.1 b/doc/man/st-flash.1 index 6bd206069..36df7daa8 100644 --- a/doc/man/st-flash.1 +++ b/doc/man/st-flash.1 @@ -65,7 +65,7 @@ Read firmware from device (4096 bytes) .IP .nf \f[C] -$ st\-flash read firmware.bin 0x8000000 4096 +$ st\-flash read firmware.bin 0x8000000 0x1000 \f[R] .fi .PP diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md index ae6c88f46..1860a8c72 100644 --- a/doc/man/st-flash.md +++ b/doc/man/st-flash.md @@ -61,7 +61,7 @@ Flash `firmware.bin` to device Read firmware from device (4096 bytes) - $ st-flash read firmware.bin 0x8000000 4096 + $ st-flash read firmware.bin 0x8000000 0x1000 Erase firmware from device From 2d8d4dce5ecb426c215839088990b34af7470641 Mon Sep 17 00:00:00 2001 From: Pierre Ducroquet Date: Fri, 14 Feb 2020 19:51:39 +0100 Subject: [PATCH 0688/1435] Fix installation by also including the stm32.h file --- include/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index a0c649532..a5121aee5 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -9,6 +9,9 @@ file(GLOB STLINK_HEADERS install(FILES ${CMAKE_SOURCE_DIR}/include/stlink.h DESTINATION ${STLINK_INCLUDE_PATH} ) +install(FILES ${CMAKE_SOURCE_DIR}/include/stm32.h + DESTINATION ${STLINK_INCLUDE_PATH} +) install(FILES ${STLINK_HEADERS} DESTINATION ${STLINK_INCLUDE_PATH}/stlink ) From 0f293fd6e8b2ee5804ebc6afa272e63d36d7716c Mon Sep 17 00:00:00 2001 From: Pierre Ducroquet Date: Fri, 14 Feb 2020 19:55:06 +0100 Subject: [PATCH 0689/1435] Add support for the STLink-2.1 when flash with no mass storage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since STLink 2.33.25, it is possible to flash the STLink in two modes: - STM32 Debug + VCP - STM32 Debug + Mass storage + VCP When flashed in the first mode, the device id changes, but the behaviour remains the same. This commit thus introduces support for this new device id. --- include/stlink/usb.h | 1 + src/usb.c | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/stlink/usb.h b/include/stlink/usb.h index 621695ea4..fd32a0731 100644 --- a/include/stlink/usb.h +++ b/include/stlink/usb.h @@ -23,6 +23,7 @@ extern "C" { #define STLINK_USB_PID_STLINK_32L 0x3748 #define STLINK_USB_PID_STLINK_32L_AUDIO 0x374a #define STLINK_USB_PID_STLINK_NUCLEO 0x374b +#define STLINK_USB_PID_STLINK_NO_UMS 0x3752 #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 diff --git a/src/usb.c b/src/usb.c index 7f5c21283..d3a541774 100644 --- a/src/usb.c +++ b/src/usb.c @@ -827,7 +827,10 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST } } - if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) || (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) || (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO)) { + if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) || + (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) || + (desc.idProduct == STLINK_USB_PID_STLINK_NO_UMS) || + (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO)) { struct libusb_device_handle *handle; ret = libusb_open(list[cnt], &handle); @@ -901,7 +904,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST // TODO - could use the scanning techniq from stm8 code here... slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; - if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO || desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO) { + if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO || desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO || desc.idProduct == STLINK_USB_PID_STLINK_NO_UMS) { slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; } else { slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; @@ -974,6 +977,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { if (desc.idProduct != STLINK_USB_PID_STLINK_32L && desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && + desc.idProduct != STLINK_USB_PID_STLINK_NO_UMS && desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO) continue; @@ -999,6 +1003,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { if (desc.idProduct != STLINK_USB_PID_STLINK_32L && desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && + desc.idProduct != STLINK_USB_PID_STLINK_NO_UMS && desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO) continue; From f45b8791f1f01457f436e11b5daf7b00f804ded2 Mon Sep 17 00:00:00 2001 From: Nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 19 Feb 2020 11:53:37 +0100 Subject: [PATCH 0690/1435] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 38 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..dd84ea782 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..bbcbbe7d6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From a0de0d0594b7755ae6d47dd7beaaffa45f8d8741 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 19 Feb 2020 18:33:30 +0100 Subject: [PATCH 0691/1435] Fixes #859. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b0cad5618..c57bdee91 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Open source version of the STMicroelectronics Stlink Tools [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) [![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/job/stlink/) -**NOTICE: The project has currently not an active maintainer. Feel free to contribute and discus in issue [#826](https://github.com/texane/stlink/issues/826)** +**NOTICE: The project has currently not an active maintainer. Feel free to contribute and discus in issue [#826](https://github.com/texane/stlink/issues/826)** ## HOWTO @@ -30,9 +30,9 @@ Windows users can [download v1.3.0](https://github.com/texane/stlink/releases/ta Mac OS X users can install from [homebrew](http://brewformulas.org/Stlink) or [download v1.3.0](https://github.com/texane/stlink/releases/tag/1.3.0) from the releases page. -Debian Linux users can install it via the ```stlink-tool``` package [repository](https://packages.debian.org/buster/stlink-tools) +Debian Linux users can install it via the ```stlink-tools``` package [repository](https://packages.debian.org/buster/stlink-tools) -Ubuntu Linux users can install it via the ```stlink-tool``` package [repository](https://packages.ubuntu.com/stlink-tools) +Ubuntu Linux users can install it via the ```stlink-tools``` package [repository](https://packages.ubuntu.com/stlink-tools) Arch Linux users can install from the [repository](https://www.archlinux.org/packages/community/x86_64/stlink) From 4416a24b5da7179291d64b371d8d37c7b6ce8d6f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 19 Feb 2020 21:20:10 +0100 Subject: [PATCH 0692/1435] General project update: - Updated README & CHANGELOG. - Updated issue templates. - Fixes in travis.yml --- .github/ISSUE_TEMPLATE.md | 29 -------- .github/ISSUE_TEMPLATE/bug_report.md | 70 +++++++++--------- .github/ISSUE_TEMPLATE/feature_request.md | 42 +++++++---- .github/ISSUE_TEMPLATE/support_question.md | 32 +++++++++ .travis.yml | 3 +- ChangeLog.md => CHANGELOG.md | 84 +++++++++++----------- README.md | 70 +++++++++--------- 7 files changed, 172 insertions(+), 158 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/ISSUE_TEMPLATE/support_question.md rename ChangeLog.md => CHANGELOG.md (53%) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 63c6c4505..000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,29 +0,0 @@ -**NOTICE: The issue may be closed without notice when not enough information is provided!** - -Thank you for giving feedback to the stlink project. Take some time to fill out - check boxes with a X in the following items so developers and other people can try to - to find out what is going on. And add/remove what is appropriate to your problem. - -When submitting a feature request, try to reuse the list and add/remove what is appropriate. - Place a `X` between the brackets `[X]` to mark the list item. - -- [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard -- [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 -- [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) -- [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 -- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` -- [ ] Target chip (and optional board): e.g STM32F402VG (STM32Fxxx Discovery) - -A as-detailed description possible of the problem with debug output when available. - -Output: - -``` -OUTPUT/ERROR of the commandline tool(s) -``` - -Expected/description: -`short description of the expected value` - -Thank you, -The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd84ea782..821b406bc 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,38 +1,32 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] - -**Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] - -**Additional context** -Add any other context about the problem here. +# Bug Report + +Thank you for giving feedback to the stlink project. + +In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out the check boxes below by setting a 'x' into the checkboxes ( [x] ) and edit each item appropriate to your specific problem. + +- [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard +- [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 +- [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) +- [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 +- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` +- [ ] Target chip (and optional board): e.g STM32F402VG (STM32Fxxx Discovery) + +Futher we kindly ask you to describe the detected problem as detailled as possible and to add debug output if available, by using the following template: + +Commandline-Output: + +``` +OUTPUT/ERROR of the commandline tool(s) +``` + +Expected/description: + +`short description of the expected value` + + +**NOTICE: The bug report may be closed without notice when not enough information is provided!** + + +Thank you for your support. + +The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7d6..bf626eb97 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,20 +1,32 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' +# Feature Request ---- +Thank you for giving feedback to the stlink project. -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] +In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out the check boxes below by setting a 'x' into the checkboxes ( [x] ) and edit each item appropriate to your specific problem. -**Describe the solution you'd like** -A clear and concise description of what you want to happen. +- [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard +- [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 +- [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) +- [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 +- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` +- [ ] Target chip (and optional board): e.g STM32F402VG (STM32Fxxx Discovery) -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. +Futher we kindly ask you to describe the detected problem as detailled as possible and to add debug output if available, by using the following template: -**Additional context** -Add any other context or screenshots about the feature request here. +Commandline-Output: + +``` +OUTPUT/ERROR of the commandline tool(s) +``` + +Expected/description: + +`short description of the expected value` + + +**NOTICE: This feature request may be closed without notice when not enough information is provided!** + + +Thank you for your support. + +The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/support_question.md b/.github/ISSUE_TEMPLATE/support_question.md new file mode 100644 index 000000000..795c13a6e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/support_question.md @@ -0,0 +1,32 @@ +# Support question + +Thank you for giving feedback to the stlink project. + +In order to allow developers and other contributors to help you with your question, please take some time to fill out the check boxes below by setting a 'x' into the checkboxes ( [x] ) and edit each item appropriate to your specific problem. + +- [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard +- [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 +- [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) +- [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 +- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` +- [ ] Target chip (and optional board): e.g STM32F402VG (STM32Fxxx Discovery) + +Futher we kindly ask you to describe the detected problem as detailled as possible and to add debug output if available, by using the following template: + +Commandline-Output: + +``` +OUTPUT/ERROR of the commandline tool(s) +``` + +Expected/description: + +`short description of the expected value` + + +**NOTICE: This support question may be closed without notice when not enough information is provided!** + + +Thank you for your support. + +The stlink project maintainers diff --git a/.travis.yml b/.travis.yml index 25d1859f7..c878be799 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,3 @@ -sudo: true language: c compiler: - gcc @@ -10,7 +9,7 @@ addons: apt: sources: # - llvm-toolchain-precise-3.8 - - ubuntu-toolchain-r-test + - sourceline: 'ppa:ubuntu-toolchain-r/test' packages: - clang # - clang-3.8 diff --git a/ChangeLog.md b/CHANGELOG.md similarity index 53% rename from ChangeLog.md rename to CHANGELOG.md index 4602d70bd..68b90c29e 100644 --- a/ChangeLog.md +++ b/CHANGELOG.md @@ -8,16 +8,16 @@ Release date: 2018-09-13 Major changes and added features: -* Implement intel hex support for GTK GUI -* Update libusb to 1.0.22 -* Add memory map for STM32F411RE target +* Implemented intel hex support for GTK GUI +* Updated libusb to 1.0.22 +* Added memory map for STM32F411RE target * Add support for STM32L4R9 target Fixes: -* FreeBSD define LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION +* FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION * Proper flash page size calculation for F412 target -* Fix flash memory map for F72xxx target +* Fixed flash memory map for F72xxx target * Return correct value on EOF for Semihosting SYS_READ For a complete list of changes see [the milestone](https://github.com/texane/stlink/milestone/6?closed=1) @@ -30,15 +30,15 @@ Release date: 2018-02-16 Major changes and added features: * STM32F72xx73xx support ([#1969148](https://github.com/texane/stlink/commit/19691485359afef1a256964afcbb8dcf4b733209)) -* Add support of STM32L496xx/4A6xx devices ([#615](https://github.com/texane/stlink/pull/615)) +* Added support of STM32L496xx/4A6xx devices ([#615](https://github.com/texane/stlink/pull/615)) Fixes: -* Fix memory map for stm32l496xx boards ([#639](https://github.com/texane/stlink/pull/639)) -* Fix write for microcontroler with RAM size less or equal to 32K ([#637](https://github.com/texane/stlink/pull/637)) +* Fixed memory map for stm32l496xx boards ([#639](https://github.com/texane/stlink/pull/639)) +* Fixed write for microcontroller with RAM size less or equal to 32K ([#637](https://github.com/texane/stlink/pull/637)) * Added LIB_INSTALL_DIR to correct libs install on 64-bit systems ([#636](https://github.com/texane/stlink/pull/636)) -* Fix verification of flash error for STM32L496x device ([#618](https://github.com/texane/stlink/pull/618)) -* Fix build on Fedora with GCC 8 ([#666](https://github.com/texane/stlink/pull/668)) +* Fixed verification of flash error for STM32L496x device ([#618](https://github.com/texane/stlink/pull/618)) +* Fixed build on Fedora with GCC 8 ([#666](https://github.com/texane/stlink/pull/668)) v1.4.0 ====== @@ -47,21 +47,21 @@ Release date: 2017-07-01 Major changes and added features: -* Add support for STM32L452 target ([#608](https://github.com/texane/stlink/pull/608)) +* Added support for STM32L452 target ([#608](https://github.com/texane/stlink/pull/608)) * Initial support to compile with Microsoft Visual Studio 2017 ([#602](https://github.com/texane/stlink/pull/602)) * Added support for flashing second bank on STM32F10x_XL ([#592](https://github.com/texane/stlink/pull/592)) -* Add support for STM32L011 target ([#572](https://github.com/texane/stlink/pull/572)) +* Added support for STM32L011 target ([#572](https://github.com/texane/stlink/pull/572)) * Allow building of debian package with CPack (@xor-gate) Updates and fixes: -* Fix compilation with GCC 7 ([#590](https://github.com/texane/stlink/pull/590)) -* Skip GTK detection if we're cross-compiling ([#588](https://github.com/texane/stlink/pull/588)) -* Fix possible memory leak ([#570](https://github.com/texane/stlink/pull/570)) -* Fix building with mingw64 ([#569](https://github.com/texane/stlink/pull/569), [#610](https://github.com/texane/stlink/pull/610)) -* Update libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) -* Fixing low-voltage flashing on STM32F7 parts. ([#567](https://github.com/texane/stlink/pull/567)) -* Update libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) +* Fixed compilation with GCC 7 ([#590](https://github.com/texane/stlink/pull/590)) +* Skipped GTK detection if we're cross-compiling ([#588](https://github.com/texane/stlink/pull/588)) +* Fixed possible memory leak ([#570](https://github.com/texane/stlink/pull/570)) +* Fixed building with mingw64 ([#569](https://github.com/texane/stlink/pull/569), [#610](https://github.com/texane/stlink/pull/610)) +* Updated libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) +* Fixed low-voltage flashing on STM32F7 parts. ([#567](https://github.com/texane/stlink/pull/567)) +* Updated libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) v1.3.1 ====== @@ -70,16 +70,16 @@ Release date: 2017-02-25 Major changes and added features: -* Add preliminary support for STM32L011 to see it after probe (chipid `0x457`) (@xor-gate) -* Strip full paths to source files in log (commit [#2c0ab7f](https://github.com/texane/stlink/commit/2c0ab7f0eb6cfda5cfbdc08bb9f6760d27c2b667)) -* Add support for STM32F413 target ([#549](https://github.com/texane/stlink/pull/549)) -* Add support for Semihosting `SYS_READC` ([#546](https://github.com/texane/stlink/pull/546)) +* Added preliminary support for STM32L011 to see it after probe (chipid `0x457`) (@xor-gate) +* Stripped full paths to source files in log (commit [#2c0ab7f](https://github.com/texane/stlink/commit/2c0ab7f0eb6cfda5cfbdc08bb9f6760d27c2b667)) +* Added support for STM32F413 target ([#549](https://github.com/texane/stlink/pull/549)) +* Added support for Semihosting `SYS_READC` ([#546](https://github.com/texane/stlink/pull/546)) Updates and fixes: -* Update documentation markdown files +* Updated documentation markdown files * Compilation fixes ([#552](https://github.com/texane/stlink/pull/552)) -* Fix compilation when path includes spaces ([#561](https://github.com/texane/stlink/pull/561)) +* Fixed compilation when path includes spaces ([#561](https://github.com/texane/stlink/pull/561)) v1.3.0 ====== @@ -90,31 +90,31 @@ Major changes and added features: * Deprecation of autotools (autoconf, automake) (@xor-gate) * Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#3fd0f09](https://github.com/texane/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) -* Add support for native debian packaging ([#444](https://github.com/texane/stlink/pull/444), [#485](https://github.com/texane/stlink/pull/485)) -* Add intel hex file reading for `st-flash` ([#459](https://github.com/texane/stlink/pull/541)) -* Add `--reset` command to `st-flash` ([#505](https://github.com/texane/stlink/pull/505)) +* Added support for native debian packaging ([#444](https://github.com/texane/stlink/pull/444), [#485](https://github.com/texane/stlink/pull/485)) +* Added intel hex file reading for `st-flash` ([#459](https://github.com/texane/stlink/pull/541)) +* Added `--reset` command to `st-flash` ([#505](https://github.com/texane/stlink/pull/505)) * Support serial numbers argument for `st-util` and `st-flash` for multi-programmer setups ([#541](https://github.com/texane/stlink/pull/541)) -* Add kill ('k') command to gdb-server for `st-util` ([#9804416](https://github.com/texane/stlink/commit/98044163ab34bf5159f121d1c49ffb3550321ca0)) -* Add manpages (generated with pandoc from Markdown) ([#464](https://github.com/texane/stlink/pull/464)) -* Rewrite commandline parsing for `st-flash` ([#459](https://github.com/texane/stlink/pull/459)) -* Add support for ARM semihosting to `st-util` ([#454](https://github.com/texane/stlink/pull/454), [#455](https://github.com/texane/stlink/pull/455)) +* Added kill ('k') command to gdb-server for `st-util` ([#9804416](https://github.com/texane/stlink/commit/98044163ab34bf5159f121d1c49ffb3550321ca0)) +* Added manpages (generated with pandoc from Markdown) ([#464](https://github.com/texane/stlink/pull/464)) +* Rewritten commandline parsing for `st-flash` ([#459](https://github.com/texane/stlink/pull/459)) +* Added support for ARM semihosting to `st-util` ([#454](https://github.com/texane/stlink/pull/454), [#455](https://github.com/texane/stlink/pull/455)) Chip support added for: * STM32L432 ([#501](https://github.com/texane/stlink/pull/501)) * STM32F412 ([#538](https://github.com/texane/stlink/pull/538)) * STM32F410 ([#9c635e4](https://github.com/texane/stlink/commit/9c635e419deca697ff823000aad2e39d47ec8d6c)) -* Add memory map for STM32F401XE ([#460](https://github.com/texane/stlink/pull/460)) +* Added memory map for STM32F401XE ([#460](https://github.com/texane/stlink/pull/460)) * L0x Category 5 devices ([#406](https://github.com/texane/stlink/pull/406)) -* Add L0 Category 2 device (chip id: 0x425) ([#72b8e5e](https://github.com/texane/stlink/commit/72b8e5ec87e4fa386a8e94fe68df29467d4354ce)) +* Added L0 Category 2 device (chip id: 0x425) ([#72b8e5e](https://github.com/texane/stlink/commit/72b8e5ec87e4fa386a8e94fe68df29467d4354ce)) Updates and fixes: * Fixed STM32F030 erase error ([#442](https://github.com/texane/stlink/pull/442)) * Fixed Cygwin build ([#68b0f3b](https://github.com/texane/stlink/commit/68b0f3bddc3c4aaffe34caa6a3201029edd8ad56)) * Reset flash mass erase (MER) bit after mass erase for safety ([#489](https://github.com/texane/stlink/pull/489)) -* Fix memory map for STM32F4 (@zulusw) -* Fix STM32L-problem with flash loader (issue #390) (Tom de Boer) +* Fixed memory map for STM32F4 (@zulusw) +* Fixed STM32L-problem with flash loader (issue #390) (Tom de Boer) * `st-util` don't read target voltage on startup as it crashes STM32F100 (probably stlink/v1) (Greg Alexander) * Do a JTAG reset prior to reading CPU information when processor is in deep sleep (@andyg24) * Redesign of `st-flash` commandline options parsing (pull-request #459) (@dev26th) @@ -122,12 +122,12 @@ Updates and fixes: v1.2.0 ====== -Release date: 16 may 2016 +Release date: 2016-05-16 Features added: -* Add multiple stlink probing (`st-info --probe`, `st-info --hla-serial`) with printing serial in hex and OpenOCD `hla_serial` format (Jerry Jacobs) -* Add stlink usb probe API functions (Jerry Jacobs) +* Added multiple stlink probing (`st-info --probe`, `st-info --hla-serial`) with printing serial in hex and OpenOCD `hla_serial` format (Jerry Jacobs) +* Added stlink usb probe API functions (Jerry Jacobs) * Added parameter to specify one stlink v2 of many (Georg von Zengen) Changes: @@ -136,7 +136,7 @@ Changes: Updates and fixes: -* Synchronize cache for stm32f7 (Tristan Gingold) +* Synchronized cache for stm32f7 (Tristan Gingold) * Allow flashing of STM32L4 down to 1.71 V (Greg Meiste) * Fix on stm32l4 to clear flash mass erase flags on CR (Bruno Dal Bo) * Proper writing of page 0 of second bank for stm32l476xe (Tobias Badertscher) @@ -148,7 +148,7 @@ Updates and fixes: * Make sure MCU is halted before running RAM based flashloaders (mlundinse) * Could not flash STM32_F3_SMALL (Max Chen) * STM32F4 8-bit support for 1.8v operation (Andy Isaacson) -* Fix F2 memory map (Nicolas Schodet) +* Fixed F2 memory map (Nicolas Schodet) * Memory map for stm32f42xxx and stm32f43xxx devices (Craig Lilley) * Stm32l0x flash loader (Robin Kreis) @@ -156,7 +156,7 @@ Chip support added for: * STM32L053R8 (Jean-Luc Béchennec) * STM32F7 Support (mlundinse) -* Add STM32L4 to CHIPID #defines and devices[], flash driver and loaded (Dave Vandervies) +* Added STM32L4 to CHIPID #defines and devices[], flash driver and loader (Dave Vandervies) * Basic support for F446 (Pavel Kirienko) * STM32F303 High Density * STM32L1xx Cat.2 devices (Nicolas Schodet) diff --git a/README.md b/README.md index c57bdee91..757412878 100644 --- a/README.md +++ b/README.md @@ -3,26 +3,29 @@ Open source version of the STMicroelectronics Stlink Tools [![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) -[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/1.5.1.svg)](https://github.com/texane/stlink/compare/1.5.1...master) +[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/v1.5.1.svg)](https://github.com/texane/stlink/releases/master) [![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/texane/stlink/releases) + [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) -[![Build Status](https://jenkins.ncrmnt.org/buildStatus/icon?job=GithubCI/stlink)](https://jenkins.ncrmnt.org/job/GithubCI/job/stlink/) +[![macOS Status](https://img.shields.io/travis/texane/stlink/master.svg?label=osx)](https://travis-ci.org/texane/stlink) -**NOTICE: The project has currently not an active maintainer. Feel free to contribute and discus in issue [#826](https://github.com/texane/stlink/issues/826)** ## HOWTO -First, you have to know there are several boards supported by the software. -Those boards use a chip to translate from USB to JTAG commands. The chip is -called stlink and there are two versions: - -* STLINKv1, present on STM32VL discovery kits, -* STLINKv2, present on STM32L discovery and later kits. +This StLink toolset supports several so called stlink programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG. These programmer boards are available in four versions: -Two different transport layers are used: +* **STLINKv1:** + - transport layer: SCSI passthru commands over USB + - present on STM32VL discovery kits +* **STLINKv2:** + * transport layer: raw USB commands + * present on STM32L discovery and nucleo and later kits +* **STLINKv2-1:** + * transport layer: raw USB commands + * present on some STM32 nucleo boards +* **STLINKv3:** + * _currently not supported by this toolset_ -* STLINKv1 uses SCSI passthru commands over USB -* STLINKv2 and STLINKv2-1 (seen on nucleo boards) uses raw USB commands. ## Installation @@ -48,11 +51,11 @@ FreeBSD users can install from [freshports](https://www.freshports.org/devel/stl OpenBSD users need to install [from source](doc/compiling.md). + ## Installation from source (advanced users) -When there is no executable available for your platform or you need the latest - (possible unstable) version you need to compile yourself. This is explained in - the [compiling manual](doc/compiling.md). +When there is no executable available for your platform or you need the latest (possible unstable) version you need to compile yourself. This is explained in the [compiling manual](doc/compiling.md). + ## Using the gdb server @@ -101,6 +104,7 @@ Transfer rate: 1 KB/sec, 560 bytes/write. (gdb) continue ``` + ## Resetting the chip from GDB You may reset the chip using GDB if you want. You'll need to use `target @@ -138,6 +142,7 @@ it at 0x20000000 and do It will be loaded, and pc will be adjusted to point to start of the code, if it is linked correctly (i.e. ELF has correct entry point). + ## Writing to flash The GDB stub ships with a correct memory map, including the flash area. @@ -149,6 +154,7 @@ If you would link your executable to `0x08000000` and then do then it would be written to the memory. + ## Writing Option Bytes Example to read and write option bytes (currently writing only supported for STM32G0 and STM32L0) @@ -157,36 +163,34 @@ Example to read and write option bytes (currently writing only supported for STM ./st-flash --debug --reset --format binary --flash=128k write option_bytes_dump.bin 0x1FFF7800 ``` + ## FAQ Q: My breakpoints do not work at all or only work once. -A: Optimizations can cause severe instruction reordering. For example, -if you are doing something like `REG = 0x100;' in a loop, the code may -be split into two parts: loading 0x100 into some intermediate register -and moving that value to REG. When you set up a breakpoint, GDB will -hook to the first instruction, which may be called only once if there are -enough unused registers. In my experience, -O3 causes that frequently. +A: Optimizations can cause severe instruction reordering. For example, if you are doing something like `REG = 0x100;' in a loop, the code may be split into two parts: loading 0x100 into some intermediate register and moving that value to REG. When you set up a breakpoint, GDB will hook to the first instruction, which may be called only once if there are enough unused registers. In my experience, -O3 causes that frequently. Q: At some point I use GDB command `next', and it hangs. -A: Sometimes when you will try to use GDB `next` command to skip a loop, -it will use a rather inefficient single-stepping way of doing that. -Set up a breakpoint manually in that case and do `continue`. +A: Sometimes when you will try to use GDB `next` command to skip a loop, it will use a rather inefficient single-stepping way of doing that. Set up a breakpoint manually in that case and do `continue`. Q: Load command does not work in GDB. -A: Some people report XML/EXPAT is not enabled by default when compiling -GDB. Memory map parsing thus fail. Use --enable-expat. +A: Some people report XML/EXPAT is not enabled by default when compiling GDB. Memory map parsing thus fail. Use --enable-expat. + ## Currently known working combinations of programmer and target See [doc/tested-boards.md](doc/tested-boards.md) +## Changelog + +The [Changelog](CHANGELOG) for the StLink Tools. + + ## Known missing features -Some features are missing from the `texane/stlink` project and we would like you to - help us out if you want to get involved: +Some features are missing from the `texane/stlink` project and we would like you to help us out if you want to get involved: * Control programming speed (See [#462](https://github.com/texane/stlink/issues/462)) * OTP area programming (See [#202](https://github.com/texane/stlink/issues/202)) @@ -197,12 +201,11 @@ Some features are missing from the `texane/stlink` project and we would like you * Instrumentation Trace Macro (ITM) Cell (See [#136](https://github.com/texane/stlink/issues/136)) * Writing external memory connected to an STM32 controller (e.g Quad SPI NOR flash) (See [#412](https://github.com/texane/stlink/issues/412)) -## Known bugs +## Known bugs ### Sometimes flashing only works after a mass erase -There is seen a problem sometimes where a flash loader run error occurs and is resolved after mass-erase -of the flash: +There is seen a problem sometimes where a flash loader run error occurs and is resolved after mass-erase of the flash: ``` 2015-12-09T22:01:57 INFO src/stlink-common.c: Successfully loaded flash loader in sram @@ -212,6 +215,7 @@ of the flash: Issue related to this bug: [#356](https://github.com/texane/stlink/issues/356) + ### Flash size is detected as zero bytes size It is possible that the STM32 flash is write protected, the st-flash tool will show something like this: @@ -243,6 +247,7 @@ Try to remove the write protection (probably only possible with ST Link Utility Issue related to this bug: [#545](https://github.com/texane/stlink/issues/545) + ## Contributing and versioning * The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) @@ -251,4 +256,5 @@ Issue related to this bug: [#545](https://github.com/texane/stlink/issues/545) ## License The stlink library and tools are licensed under the [BSD license](LICENSE). -The flashloaders/stm32l0x.s and flashloaders/stm32lx.s source files are licensed under the GPL-2+. + +The flashloaders/stm32l0x.s and flashloaders/stm32lx.s source files are licensed under the GPLv2+. From 9970b67fa95f026ae562e3931feaabd1c3bae651 Mon Sep 17 00:00:00 2001 From: Nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 20 Feb 2020 00:24:18 +0100 Subject: [PATCH 0693/1435] Create CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..b0623068a --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at texane@gmail.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq From 5f1264787c16aaf47e21e3566f8d9024e28b959a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 20 Feb 2020 00:37:04 +0100 Subject: [PATCH 0694/1435] Archived page from github project wiki. --- LICENSE => LICENSE.md | 0 README.md | 6 +-- doc/wiki_old.md | 108 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 3 deletions(-) rename LICENSE => LICENSE.md (100%) create mode 100644 doc/wiki_old.md diff --git a/LICENSE b/LICENSE.md similarity index 100% rename from LICENSE rename to LICENSE.md diff --git a/README.md b/README.md index 757412878..f1e2760c6 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Open source version of the STMicroelectronics Stlink Tools ## HOWTO -This StLink toolset supports several so called stlink programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG. These programmer boards are available in four versions: +This stlink toolset supports several so called stlink programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG. These programmer boards are available in four versions: * **STLINKv1:** - transport layer: SCSI passthru commands over USB @@ -185,7 +185,7 @@ See [doc/tested-boards.md](doc/tested-boards.md) ## Changelog -The [Changelog](CHANGELOG) for the StLink Tools. +The [Changelog](CHANGELOG.md) for the StLink Tools. ## Known missing features @@ -255,6 +255,6 @@ Issue related to this bug: [#545](https://github.com/texane/stlink/issues/545) ## License -The stlink library and tools are licensed under the [BSD license](LICENSE). +The stlink library and tools are licensed under the [BSD license](LICENSE.md). The flashloaders/stm32l0x.s and flashloaders/stm32lx.s source files are licensed under the GPLv2+. diff --git a/doc/wiki_old.md b/doc/wiki_old.md new file mode 100644 index 000000000..81e70a277 --- /dev/null +++ b/doc/wiki_old.md @@ -0,0 +1,108 @@ +Welcome to the stlink wiki! (Archived: 2014-08-11) + +Misc: +Windows pre-compiled binaries are available at http://www.emb4fun.de/archive/stlink/index.html + +FAQ: +Q: Where can I get help? Is there a forum or maybe a mailing list? + +A: todo + +Q: How can I install stlink and flash binaries on Mac OS X ? + +A: **20140811: ** installed on Mac OS X 10.9.4 with ports method, however STlink v2 does not seem to work with libusb if you upgrade to the newest firmware !! Only older firmware on STlink v2 works. + +[https://coderwall.com/p/oznj_q](https://coderwall.com/p/oznj_q) + +`sudo port install libusb automake autoconf pkgconfig` + +`aclocal --force -I /opt/local/share/aclocal` + +`git clone https://github.com/texane/stlink.git stlink-utility` + +`cd stlink-utility` + +`./autogen.sh` + +`./configure` + +`make` + + +Then trying to flash the image with STLINK v2 : + +`./st-flash write ~/Downloads/irq.bin 0x8000000` + +> libusb_handle_events() timeout +> +> [!] send_recv + +After downgrading the firmware, flashing works +ST-Link/V2 debugger with downgraded V2.14.3 firmware: + +https://drive.google.com/folderview?id=0Bzv7UpKpOQhnbXJVVEg4VUo2M1k + +as described here: + +http://community.spark.io/t/how-to-flash-a-brand-new-freshly-soldered-stm32f103-chip/3906 + +`./st-flash write ~/Downloads/irq.bin 0x8000000` + +> 2014-08-11T23:14:52 INFO src/stlink-common.c: Loading device parameters.... +> +> 2014-08-11T23:14:52 INFO src/stlink-common.c: Device connected is: F1 Medium-density device, id 0x20036410 +> +> 2014-08-11T23:14:52 INFO src/stlink-common.c: SRAM size: 0x5000 bytes (20 KiB), Flash: 0x20000 bytes (128 KiB) in +> pages of 1024 bytes +> +> 2014-08-11T23:14:52 INFO src/stlink-common.c: Attempting to write 24904 (0x6148) bytes to stm32 address: 134217728 +> (0x8000000) +> +> Flash page at addr: 0x08006000 erased +> +> 2014-08-11T23:14:53 INFO src/stlink-common.c: Finished erasing 25 pages of 1024 (0x400) bytes +> +> 2014-08-11T23:14:53 INFO src/stlink-common.c: Starting Flash write for VL/F0 core id +> +> 2014-08-11T23:14:53 INFO src/stlink-common.c: Successfully loaded flash loader in sram 24/24 pages written +> +> 2014-08-11T23:14:54 INFO src/stlink-common.c: Starting verification of write complete +> +> 2014-08-11T23:14:54 INFO src/stlink-common.c: Flash written and verified! jolly good! + + +Installation of openOCD on Mac OS X with STlink-v2 has been successful: + +`sudo port install openocd +jlink +stlink +ft2232` + +`/opt/local/bin/openocd --version` + +> Open On-Chip Debugger 0.7.0 (2014-08-11-22:12) + +`openocd -f /opt/local/share/openocd/scripts/interface/stlink-v2.cfg -f /opt/local/share/openocd/scripts/target/stm32f1x_stlink.cfg ` + +> Open On-Chip Debugger 0.8.0 (2014-08-11-15:36) +> +> Licensed under GNU GPL v2 +> +> For bug reports, read http://openocd.sourceforge.net/doc/doxygen/bugs.html +> +> Info : This adapter doesn't support configurable speed +> +> Info : STLINK v2 JTAG v21 API v2 SWIM v4 VID 0x0483 PID 0x3748 +> +> Info : using stlink api v2 +> +> Info : Target voltage: 3.244269 +> +> Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints + +and connecting to the server through telnet yields a successful installation + +`telnet localhost 4444` + +> Connected to localhost. +> +> Escape character is '^]'. +> +> Open On-Chip Debugger From 3f9ae02d8020786f605c3f9c09d9ace9c38a7c4e Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 20 Feb 2020 01:56:53 +0100 Subject: [PATCH 0695/1435] Updated CHANGELOG.md for upcoming release. --- CHANGELOG.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68b90c29e..20d242a1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,57 @@ Stlink ChangeLog ================ +v1.6.0 +====== + +Release date: 2020-02-20 + +Major changes and added features: + +* Added O_BINARY option to open file ([#753](https://github.com/texane/stlink/pull/753)) +* Added preliminary support for some STM32G0 chips ([#759](https://github.com/texane/stlink/pull/759)) ([#760](https://github.com/texane/stlink/pull/760)) +* Added support for mass erasing second bank on STM32F10x_XL ([#767](https://github.com/texane/stlink/pull/767)) +* Added call to clear PG bit after writing to flash ([#773](https://github.com/texane/stlink/pull/773)) +* Added howto for sending NRST signal through GDB ([#776](https://github.com/texane/stlink/pull/776)) +* Added support to write option bytes for the STM32G0 ([#778](https://github.com/texane/stlink/pull/778)) +* Added simple read/write support for STM32WB55 chips ([#786](https://github.com/texane/stlink/pull/786)) +* Added STLink V3SET VID:PIDs to the udev rules ([#789](https://github.com/texane/stlink/pull/789)) +* Support for "STM32+Audio" v2-1 firmware ([#790](https://github.com/texane/stlink/pull/790)) +* Initial support for STM32L41X ([#799](https://github.com/texane/stlink/pull/799)) +* Build for Windows under Debian/Ubuntu ([#802](https://github.com/texane/stlink/pull/802)) +* Allow for 64 bytes serials ([#809](https://github.com/texane/stlink/pull/809)) +* Added support to read and write option bytes for STM32F2 series (Orie22) +* Added full support for STLINK CHIP ID L4RX (Brad Natelborg) +* Added support to write option bytes to STM32F4 devices (Davey Struijk) + +Updates and fixes: + +* Make udev rules and modprobe conf installation optional ([#741](https://github.com/texane/stlink/pull/741)) +* Fixed case when __FILE__ don't contain "/" nor "\\". ([#745](https://github.com/texane/stlink/pull/745)) +* Fixed double dash issue in doc/man ([#746](https://github.com/texane/stlink/pull/746)) +* Fixed Debug error on line 123 in CMakeLists.txt (@xor-gate) +* Only do bank calculation on STM32L4 devices with dual banked flash ([#751](https://github.com/texane/stlink/pull/751)) +* Updated STM32F3xx chip ID that covers a few different devices ([#758](https://github.com/texane/stlink/pull/758)) +* Fixed versioning when compiling from the checked out git-repo ([#762](https://github.com/texane/stlink/pull/762)) +* Fixed "unkown chip id", piped output and st-util -v ([#763](https://github.com/texane/stlink/pull/763)) +* win32: move usleep definition to unistd.h ([#765](https://github.com/texane/stlink/pull/765)) +* Fixed relative path to the UI files needed by stlink-gui-local (GUI) ([#771](https://github.com/texane/stlink/pull/771)) +* Fixed package name "devscripts" in doc/compiling.md ([#775](https://github.com/texane/stlink/pull/775)) +* Fixed apparent STM32G0 flashing issue ([#797](https://github.com/texane/stlink/pull/797)) +* Fixed few potential memory/resource leaks ([#803](https://github.com/texane/stlink/pull/803)) +* Fixed flash verification error on STM32WB55RG ([#810](https://github.com/texane/stlink/pull/810)) ([#816](https://github.com/texane/stlink/pull/816)) +* Do not issue JTAG reset on stlink-v1 (Gwenhael Goavec-Merou) +* Fixed flash size of STM32 Discovery vl (Gwenhael Goavec-Merou) +* Added support for writing option bytes on STM32L0 (Adrian Imboden) +* Updated documentation on software structure ([#851](https://github.com/texane/stlink/pull/851)) + +General project updates: + +* Updated issue templates, README.md and CHANGELOG.md (Nightwalker-87) +* Added CODE_OF_CONDUCT (Nightwalker-87) +* Fixed travis build config file (Nightwalker-87) +* Archived page from github project wiki to doc/wiki_old.md (Nightwalker-87) + v1.5.1 ====== From 393310fc9925907c239f0ad7fac1e8d0565d65c0 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 20 Feb 2020 02:08:49 +0100 Subject: [PATCH 0696/1435] Release v1.6.0 --- .version | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.version b/.version index 26ca59460..dc1e644a1 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.5.1 +1.6.0 diff --git a/README.md b/README.md index f1e2760c6..5d98f0e7e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Open source version of the STMicroelectronics Stlink Tools [![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) -[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/v1.5.1.svg)](https://github.com/texane/stlink/releases/master) +[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/v1.6.0.svg)](https://github.com/texane/stlink/releases/master) [![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/texane/stlink/releases) [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) From 1de2e4b0f8c1d1ff3805e3b5e9424008207b9575 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 20 Feb 2020 12:25:23 +0100 Subject: [PATCH 0697/1435] Added status messages to CMakeLists.txt --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b0eef1189..90378f9ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,6 +121,10 @@ else() set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) endif() +message(STATUS "STLINK_LIB_SHARED: ${STLINK_LIB_SHARED}") +message(STATUS "PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}") +message(STATUS "VERSION: ${STLINK_SHARED_VERSION}") + set_target_properties(${STLINK_LIB_SHARED} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} VERSION ${STLINK_SHARED_VERSION} @@ -162,7 +166,7 @@ if (APPLE) find_library(IOKit IOKit) target_link_libraries(${STLINK_LIB_STATIC} ${CoreFoundation} ${IOKit} ${ObjC}) endif() - + if (WIN32 OR MSYS OR MINGW) target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} wsock32 ws2_32) else() From bc068a34b3722cbac6d108c3ecb5bd1bbb698b33 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 21 Feb 2020 00:09:51 +0100 Subject: [PATCH 0698/1435] Added support for G031/G041 chips (#825) --- include/stlink/chipid.h | 5 ++- src/chipid.c | 15 ++++++- src/common.c | 98 +++++++++++++++++++++++++++++------------ src/flash_loader.c | 65 +++++++++++++++------------ 4 files changed, 125 insertions(+), 58 deletions(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index e9cb48167..368e157a7 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -69,11 +69,12 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F72XXX = 0x452, /* This ID is found on the NucleoF722ZE board */ STLINK_CHIPID_STM32_L011 = 0x457, STLINK_CHIPID_STM32_F410 = 0x458, + STLINK_CHIPID_STM32_G0_CAT2 = 0x460, // G071/081 STLINK_CHIPID_STM32_F413 = 0x463, - STLINK_CHIPID_STM32_L4RX = 0x470, // taken from the STM32L4R9I-DISCO board - STLINK_CHIPID_STM32_G0X1 = 0x460, + STLINK_CHIPID_STM32_G0_CAT1 = 0x466, // G031/041 STLINK_CHIPID_STM32_G4_CAT2 = 0x468, // See: RM 0440 s46.6.1 "MCU device ID code". STLINK_CHIPID_STM32_G4_CAT3 = 0x469, + STLINK_CHIPID_STM32_L4RX = 0x470, // taken from the STM32L4R9I-DISCO board STLINK_CHIPID_STM32_WB55 = 0x495 }; diff --git a/src/chipid.c b/src/chipid.c index 938cc1f30..ebb5a9027 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -521,16 +521,27 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1ff00000, .bootrom_size = 0x2000 }, + { + // STM32G031/041 (from RM0444) + .chip_id = STLINK_CHIPID_STM32_G0_CAT1, + .description = "G031/G041 device", + .flash_type = STLINK_FLASH_TYPE_G0, + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2K (sec 3.2) + .sram_size = 0x2000, // 8K (sec 2.3) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x2000 // 8K (sec 2.2.2 table 3) + }, { // STM32G071/081 (from RM0444) - .chip_id = STLINK_CHIPID_STM32_G0X1, + .chip_id = STLINK_CHIPID_STM32_G0_CAT2, .description = "G071/G081 device", .flash_type = STLINK_FLASH_TYPE_G0, .flash_size_reg = 0x1FFF75E0, // Section 38.2 .flash_pagesize = 0x800, // 2K (sec 3.2) .sram_size = 0x9000, // 36K (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000 // 28K (table 2) + .bootrom_size = 0x7000 // 28K (sec 2.2.2 table 2) }, { // STM32G431/441 (from RM0440) diff --git a/src/common.c b/src/common.c index e7d4dc934..bcce965aa 100644 --- a/src/common.c +++ b/src/common.c @@ -293,7 +293,8 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { reg = FLASH_F4_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) reg = STM32L4_FLASH_CR; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) reg = STM32Gx_FLASH_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) reg = STM32WB_FLASH_CR; @@ -325,7 +326,8 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { cr_lock_shift = FLASH_F4_CR_LOCK; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) cr_lock_shift = STM32L4_FLASH_CR_LOCK; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) cr_lock_shift = STM32Gx_FLASH_CR_LOCK; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) cr_lock_shift = STM32WB_FLASH_CR_LOCK; @@ -346,7 +348,8 @@ static void unlock_flash(stlink_t *sl) { key_reg = FLASH_F4_KEYR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) key_reg = STM32L4_FLASH_KEYR; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) key_reg = STM32Gx_FLASH_KEYR; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) key_reg = STM32WB_FLASH_KEYR; @@ -385,7 +388,8 @@ static void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_lock_shift = STM32Gx_FLASH_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { @@ -418,7 +422,8 @@ static void set_flash_cr_pg(stlink_t *sl) { cr_reg = STM32L4_FLASH_CR; x &= ~STM32L4_FLASH_CR_OPBITS; x |= 1 << STM32L4_FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; x |= (1 << FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { @@ -439,7 +444,8 @@ static void clear_flash_cr_pg(stlink_t *sl) { cr_reg = FLASH_F4_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) cr_reg = STM32L4_FLASH_CR; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) cr_reg = STM32Gx_FLASH_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) cr_reg = STM32WB_FLASH_CR; @@ -453,7 +459,8 @@ static void clear_flash_cr_pg(stlink_t *sl) { static void set_flash_cr_per(stlink_t *sl) { uint32_t cr_reg, val; - if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) cr_reg = STM32Gx_FLASH_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) cr_reg = STM32WB_FLASH_CR; @@ -473,7 +480,8 @@ static void set_flash_cr2_per(stlink_t *sl) { static void clear_flash_cr_per(stlink_t *sl) { uint32_t cr_reg; - if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) cr_reg = STM32Gx_FLASH_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) cr_reg = STM32WB_FLASH_CR; @@ -495,7 +503,8 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); cr_pg = 1 << STM32L4_FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_mer = (1 << FLASH_CR_MER); cr_pg = (1 << FLASH_CR_PG); @@ -565,7 +574,8 @@ static void set_flash_cr_strt(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_strt = 1 << STM32L4_FLASH_CR_STRT; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_strt = 1 << STM32Gx_FLASH_CR_STRT; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { @@ -596,7 +606,8 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { sr_reg = FLASH_F4_SR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) sr_reg = STM32L4_FLASH_SR; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) sr_reg = STM32Gx_FLASH_SR; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) sr_reg = STM32WB_FLASH_SR; @@ -622,7 +633,8 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { sr_busy_shift = FLASH_F4_SR_BSY; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) sr_busy_shift = STM32L4_FLASH_SR_BSY; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) + else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) sr_busy_shift = STM32Gx_FLASH_SR_BSY; else if (sl->flash_type == STLINK_FLASH_TYPE_WB) sr_busy_shift = STM32WB_FLASH_SR_BSY; @@ -846,8 +858,10 @@ int stlink_load_device_params(stlink_t *sl) { flash_size = flash_size >>16; flash_size = flash_size & 0xffff; - if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW || sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS) && ( flash_size == 0 )) { - sl->flash_size = 128 * 1024; + if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || + sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW || + sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS) && ( flash_size == 0 )) { + sl->flash_size = 128 * 1024; } else if (sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2) { sl->flash_size = (flash_size & 0xff) * 1024; } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_HIGH) { @@ -1648,9 +1662,15 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ - if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || (sl->chip_id == STLINK_CHIPID_STM32_F4) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || (sl->chip_id == STLINK_CHIPID_STM32_F411RE) || - (sl->chip_id == STLINK_CHIPID_STM32_F446) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || (sl->chip_id == STLINK_CHIPID_STM32_F72XXX) || + if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || + (sl->chip_id == STLINK_CHIPID_STM32_F4) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || + (sl->chip_id == STLINK_CHIPID_STM32_F411RE) || + (sl->chip_id == STLINK_CHIPID_STM32_F446) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || + (sl->chip_id == STLINK_CHIPID_STM32_F72XXX) || (sl->chip_id == STLINK_CHIPID_STM32_F412)) { uint32_t sector=calculate_F4_sectornum(flashaddr); if (sector>= 12) { @@ -1660,7 +1680,8 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ else if(sector<5) sl->flash_pgsz=0x10000; else sl->flash_pgsz=0x20000; } - else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { + else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || + sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { uint32_t sector=calculate_F7_sectornum(flashaddr); if (sector<4) sl->flash_pgsz=0x8000; else if(sector<5) sl->flash_pgsz=0x20000; @@ -1677,7 +1698,8 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_L4) { + if (sl->flash_type == STLINK_FLASH_TYPE_F4 || + sl->flash_type == STLINK_FLASH_TYPE_L4) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1696,7 +1718,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", page, stlink_calculate_pagesize(sl, flashaddr)); write_flash_cr_bker_pnb(sl, page); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { + } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || + sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { // calculate the actual page from the address uint32_t sector=calculate_F7_sectornum(flashaddr); @@ -1731,7 +1754,10 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) uint32_t val; uint32_t flash_regs_base; - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || sl->chip_id == STLINK_CHIPID_STM32_L011) { + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || + sl->chip_id == STLINK_CHIPID_STM32_L011) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; } else { flash_regs_base = STM32L_FLASH_REGS_ADDR; @@ -1840,7 +1866,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) clear_flash_cr_per(sl); // Re-lock the flash. lock_flash(sl); - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr < FLASH_BANK2_START_ADDR))) { + } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr < FLASH_BANK2_START_ADDR))) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -1894,7 +1921,10 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) int stlink_erase_flash_mass(stlink_t *sl) { /* TODO: User MER bit to mass-erase G0, G4, WB series. */ - if (sl->flash_type == STLINK_FLASH_TYPE_L0 || sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4 || sl->flash_type == STLINK_FLASH_TYPE_WB) { + if (sl->flash_type == STLINK_FLASH_TYPE_L0 || + sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4 || + sl->flash_type == STLINK_FLASH_TYPE_WB) { /* erase each page */ int i = 0, num_pages = (int) sl->flash_size/sl->flash_pgsz; for (i = 0; i < num_pages; i++) { @@ -2007,7 +2037,10 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uin uint32_t flash_regs_base; flash_loader_t fl; - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || sl->chip_id == STLINK_CHIPID_STM32_L011) { + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || + sl->chip_id == STLINK_CHIPID_STM32_L011) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; } else { flash_regs_base = STM32L_FLASH_REGS_ADDR; @@ -2568,7 +2601,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_g0x1(stlink_t *sl, uint8_t* base, uint32_t len) { +static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t len) { uint32_t val; @@ -2577,6 +2610,16 @@ static int stlink_write_option_bytes_g0x1(stlink_t *sl, uint8_t* base, uint32_t return -1; } + // Make sure we've loaded the context with the chip details + stlink_core_id(sl); + + /* Check if chip is supported and for correct address */ + if(sl->chip_id != STLINK_CHIPID_STM32_G0_CAT1 && + sl->chip_id != STLINK_CHIPID_STM32_G0_CAT2) { + ELOG("Option bytes writing is currently only supported for the STM32G0\n"); + return -1; + } + /* Unlock flash if necessary (ref manuel page 52) */ stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); if ((val & (1u << STM32Gx_FLASH_CR_LOCK))) { @@ -2880,8 +2923,9 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui stlink_core_id(sl); /* Check if chip is supported and for correct address */ - if((sl->chip_id == STLINK_CHIPID_STM32_G0X1) && (addr == STM32_G0_OPTION_BYTES_BASE)) { - return stlink_write_option_bytes_g0x1(sl, base, len); + if(((sl->chip_id == STLINK_CHIPID_STM32_G0_CAT1) || + (sl->chip_id == STLINK_CHIPID_STM32_G0_CAT2)) && (addr == STM32_G0_OPTION_BYTES_BASE)) { + return stlink_write_option_bytes_g0x(sl, base, len); } else if((sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) && (addr == STM32_L0_CAT2_OPTION_BYTES_BASE)) { return stlink_write_option_bytes_l0_cat2(sl, base, len); diff --git a/src/flash_loader.c b/src/flash_loader.c index 73db427a7..7479e05bb 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -255,32 +255,37 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* const uint8_t* loader_code; size_t loader_size; - if (sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2 - || sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS || sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH - || sl->chip_id == STLINK_CHIPID_STM32_L152_RE || sl->chip_id == STLINK_CHIPID_STM32_L011 - || sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { /* stm32l */ + if (sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || + sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2 || + sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS || + sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH || + sl->chip_id == STLINK_CHIPID_STM32_L152_RE || + sl->chip_id == STLINK_CHIPID_STM32_L011 || + sl->chip_id == STLINK_CHIPID_STM32_L0 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); - } else if (sl->core_id == STM32VL_CORE_ID - || sl->chip_id == STLINK_CHIPID_STM32_F1_MEDIUM - || sl->chip_id == STLINK_CHIPID_STM32_F3 - || sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL - || sl->chip_id == STLINK_CHIPID_STM32_F303_HIGH - || sl->chip_id == STLINK_CHIPID_STM32_F37x - || sl->chip_id == STLINK_CHIPID_STM32_F334) { + } else if (sl->core_id == STM32VL_CORE_ID || + sl->chip_id == STLINK_CHIPID_STM32_F1_MEDIUM || + sl->chip_id == STLINK_CHIPID_STM32_F3 || + sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL || + sl->chip_id == STLINK_CHIPID_STM32_F303_HIGH || + sl->chip_id == STLINK_CHIPID_STM32_F37x || + sl->chip_id == STLINK_CHIPID_STM32_F334) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 || - sl->chip_id == STLINK_CHIPID_STM32_F4 || - sl->chip_id == STLINK_CHIPID_STM32_F4_DE || - sl->chip_id == STLINK_CHIPID_STM32_F4_LP || - sl->chip_id == STLINK_CHIPID_STM32_F4_HD || - sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || - sl->chip_id == STLINK_CHIPID_STM32_F410 || - sl->chip_id == STLINK_CHIPID_STM32_F411RE || - sl->chip_id == STLINK_CHIPID_STM32_F412 || - sl->chip_id == STLINK_CHIPID_STM32_F413 || - sl->chip_id == STLINK_CHIPID_STM32_F446 + } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 || + sl->chip_id == STLINK_CHIPID_STM32_F4 || + sl->chip_id == STLINK_CHIPID_STM32_F4_DE || + sl->chip_id == STLINK_CHIPID_STM32_F4_LP || + sl->chip_id == STLINK_CHIPID_STM32_F4_HD || + sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || + sl->chip_id == STLINK_CHIPID_STM32_F410 || + sl->chip_id == STLINK_CHIPID_STM32_F411RE || + sl->chip_id == STLINK_CHIPID_STM32_F412 || + sl->chip_id == STLINK_CHIPID_STM32_F413 || + sl->chip_id == STLINK_CHIPID_STM32_F446 ) { int retval; retval = loader_v_dependent_assignment(sl, @@ -290,8 +295,8 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* if (retval == -1) { return retval; } - } else if (sl->core_id == STM32F7_CORE_ID || - sl->chip_id == STLINK_CHIPID_STM32_F7 || + } else if (sl->core_id == STM32F7_CORE_ID || + sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX || sl->chip_id == STLINK_CHIPID_STM32_F72XXX ) { @@ -303,7 +308,11 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* if (retval == -1) { return retval; } - } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || sl->chip_id == STLINK_CHIPID_STM32_F04 || sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || sl->chip_id == STLINK_CHIPID_STM32_F0_SMALL || sl->chip_id == STLINK_CHIPID_STM32_F09X) { + } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || + sl->chip_id == STLINK_CHIPID_STM32_F04 || + sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || + sl->chip_id == STLINK_CHIPID_STM32_F0_SMALL || + sl->chip_id == STLINK_CHIPID_STM32_F09X) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); } else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || @@ -345,11 +354,13 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe return -1; } - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { count = size / sizeof(uint16_t); if (size % sizeof(uint16_t)) ++count; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4 || + sl->flash_type == STLINK_FLASH_TYPE_L0) { count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; From 6692fdc57cd087be84dbf831e85730cab58c7bf9 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 21 Feb 2020 00:50:50 +0100 Subject: [PATCH 0699/1435] Restored support for STM32-Clones -> CKS devices with Core ID 0x2ba01477 (Closes #756 #757 #761 #766 #769 #805) --- include/stm32.h | 1 + src/common.c | 5 ++++- src/flash_loader.c | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/stm32.h b/include/stm32.h index 8f8e7eba1..9fb3e45da 100644 --- a/include/stm32.h +++ b/include/stm32.h @@ -9,6 +9,7 @@ // cortex core ids #define STM32VL_CORE_ID 0x1ba01477 +#define CS32VL_CORE_ID 0x2ba01477 #define STM32F7_CORE_ID 0x5ba02477 // Constant STM32 memory map figures diff --git a/src/common.c b/src/common.c index bcce965aa..19155f774 100644 --- a/src/common.c +++ b/src/common.c @@ -2262,7 +2262,10 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t uint32_t flash_regs_base; uint32_t pagesize; - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || sl->chip_id == STLINK_CHIPID_STM32_L011) { + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || + sl->chip_id == STLINK_CHIPID_STM32_L011) { flash_regs_base = STM32L0_FLASH_REGS_ADDR; pagesize = L0_WRITE_BLOCK_SIZE; } else { diff --git a/src/flash_loader.c b/src/flash_loader.c index 7479e05bb..1e125e926 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -267,6 +267,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || + sl->core_id == CS32VL_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_F3 || sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL || From 751da606cac4882494bb6b764c2ad9619427eb48 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 21 Feb 2020 01:07:52 +0100 Subject: [PATCH 0700/1435] Merge branch 'pr-847/zx81a/master' into develop. --- debian/rules | 2 +- include/stm32.h | 3 + src/common.c | 191 +++++++++++++++++++++++++++++++++++++++++++++- src/tools/flash.c | 2 +- 4 files changed, 194 insertions(+), 4 deletions(-) diff --git a/debian/rules b/debian/rules index e228a7087..e183fffb7 100755 --- a/debian/rules +++ b/debian/rules @@ -1,7 +1,7 @@ #!/usr/bin/make -f # See debhelper(7) (uncomment to enable) # output every command that modifies files on the build system. -#DH_VERBOSE = 1 +DH_VERBOSE = 1 # see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* DPKG_EXPORT_BUILDFLAGS = 1 diff --git a/include/stm32.h b/include/stm32.h index 9fb3e45da..858d2b22a 100644 --- a/include/stm32.h +++ b/include/stm32.h @@ -18,4 +18,7 @@ #define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_L0_CAT2_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) #define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) +#define STM32_L496X_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) +#define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) + #endif /* STM32_H */ diff --git a/src/common.c b/src/common.c index 19155f774..73c8e51ad 100644 --- a/src/common.c +++ b/src/common.c @@ -160,6 +160,7 @@ //32L4 register base is at FLASH_REGS_ADDR (0x40022000) #define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) +#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) #define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) #define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) #define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) @@ -168,13 +169,16 @@ #define STM32L4_FLASH_SR_ERRMASK 0x3f8 /* SR [9:3] */ #define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ +#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ #define STM32L4_FLASH_CR_PG 0 /* Program */ #define STM32L4_FLASH_CR_PER 1 /* Page erase */ #define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ #define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ #define STM32L4_FLASH_CR_STRT 16 /* Start command */ +#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ #define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ #define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ +#define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ // Bits requesting flash operations (useful when we want to clear them) #define STM32L4_FLASH_CR_OPBITS \ ((1lu<chip_id,addr); + /* Check if chip is supported and for correct address */ if(((sl->chip_id == STLINK_CHIPID_STM32_G0_CAT1) || (sl->chip_id == STLINK_CHIPID_STM32_G0_CAT2)) && (addr == STM32_G0_OPTION_BYTES_BASE)) { @@ -2933,8 +3113,15 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui else if((sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) && (addr == STM32_L0_CAT2_OPTION_BYTES_BASE)) { return stlink_write_option_bytes_l0_cat2(sl, base, len); } + else if((sl->chip_id == STLINK_CHIPID_STM32_L496X) && (addr == STM32_L496X_OPTION_BYTES_BASE)) { + return stlink_write_option_bytes_l496x(sl, base, len); + } + else if( ( (sl->chip_id == STLINK_CHIPID_STM32_L152_RE) || (sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH) ) + && ( (addr == STM32_L1_OPTION_BYTES_BASE) || (addr == STM32_L1_OPTION_BYTES_BASE+4) ) ) { + return stlink_write_option_bytes_l1(sl, base, addr, len); + } else { - ELOG("Option bytes writing is currently only supported for the STM32F2, STM32G0 and STM32L0\n"); + ELOG("Option bytes writing is currently only supported for the STM32F2, STM32G0, STM32L496x/L4A6x, STM32L1 and STM32L0\n"); return -1; } diff --git a/src/tools/flash.c b/src/tools/flash.c index f5fd1a386..1b63b1696 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -164,7 +164,7 @@ int main(int ac, char** av) goto on_error; } } - else if (o.addr == STM32_G0_OPTION_BYTES_BASE || o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE){ + else if (o.addr == STM32_G0_OPTION_BYTES_BASE || o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE || o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE + 4){ err = stlink_fwrite_option_bytes(sl, o.filename, o.addr); if (err == -1) { From 90997ed65b902e7f19523002feb84c43ec2d5b40 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 21 Feb 2020 02:22:19 +0100 Subject: [PATCH 0701/1435] Updated list with tested-boards. --- README.md | 2 +- doc/tested-boards.md | 56 ++++++++++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 5d98f0e7e..c8955a521 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Open source version of the STMicroelectronics Stlink Tools [![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) -[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/v1.6.0.svg)](https://github.com/texane/stlink/releases/master) +[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/v1.6.0.svg)](https://github.com/texane/stlink/releases/develop) [![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/texane/stlink/releases) [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) diff --git a/doc/tested-boards.md b/doc/tested-boards.md index 27d09cc34..b28163a30 100644 --- a/doc/tested-boards.md +++ b/doc/tested-boards.md @@ -7,6 +7,7 @@ Known working targets: * STM32F100xx (Medium Density VL) * STM32F103 (according to jpa- on ##stm32) +* CKS32F103 (chinese STM32F103-Clone) No information: @@ -14,41 +15,44 @@ No information: STLink v2 (as found on the 32L and F4 Discovery boards), known working targets: -* STM32F030F4P6 (custom board) -* STM32F0Discovery (STM32F0 Discovery board) -* STM32F100xx (Medium Density VL, as on the 32VL Discovery board) -* STM32L1xx (STM32L Discovery board) +* STM32F0 (STM32F0 Discovery board) +* STM32F030F4P6 (custom board) +* STM32F051R8T6 (STM320518-EVAL board) +* STM32F100xx (Medium Density VL, as on the 32VL Discovery board) +* STM32F103VET6 (HY-STM32 board) +* STM32F105RCT6 (DecaWave EVB1000 board) +* STM32F303xx (STM32F3 Discovery board) +* STM32F407xx (STM32F4 Discovery board) +* STM32F411E-DISCO (STM32F4 Discovery board with gyro, audio) +* STM32F429I-DISCO (STM32F4 Discovery board with LCD) +* STM32F439VIT6 (Discovery board reseated CPU) +* STM32L052K8T6 (custom board) +* STM32L1xx (STM32L Discovery board) +* STM32L151CB (custom board) +* STM32L152RB (STM32L-Discovery board, custom board) +* STM32L496ZG (STM32-Nucleo-L496ZG board) + + * STM32F103VC, STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on custom boards from [UweBonnes/wiki_fuer_alex](https://github.com/UweBonnes/wiki_fuer_alex/tree/master/layout) -* STM32F103VET6 (HY-STM32 board) -* STM32F105RCT6 (DecaWave EVB1000 board) -* STM32F303xx (STM32F3 Discovery board) -* STM32F407xx (STM32F4 Discovery board) -* STM32F429I-DISCO (STM32F4 Discovery board with LCD) -* STM32F439VIT6 (discovery board reseated CPU) -* STM32L052K8T6 (custom board) -* STM32L151CB (custom board) -* STM32L152RB (STM32L-Discovery board, custom board) -* STM32F051R8T6 (STM320518-EVAL board) -* STM32F411E-DISCO (STM32F4 Discovery board with gyro, audio) + STLink v2-1 (as found on the Nucleo boards), known working targets: -* STM32F401xx (STM32 Nucleo-F401RE board) * STM32F030R8T6 (STM32 Nucleo-F030R8 board) +* STM32F042K6 (STM32 Nucleo-32 Board) * STM32F072RBT6 (STM32 Nucleo-F072RB board) -* STM32F103RB (STM32 Nucleo-F103RB board) +* STM32F103RB (STM32 Nucleo-F103RB board) * STM32F303RET6 (STM32 Nucleo-F303RE board) -* STM32F334R8 (STM32 Nucleo-F334R8 board) +* STM32F334R8 (STM32 Nucleo-F334R8 board) +* STM32F401xx (STM32 Nucleo-F401RE board) * STM32F411RET6 (STM32 Nucleo-F411RE board) -* STM32F756NGHx (STMF7 evaluation board) -* STM32L053R8 (STM32 Nucleo-L053R8 board) -* STM32F769NI (STM32F7 discovery board) -* Nucleo-L152RE board -* [Nucleo-L476RG board](http://www.st.com/en/evaluation-tools/nucleo-l476rg.html) +* STM32F756NGHx (STM32F7 evaluation board) +* STM32F769NI (STM32F7 discovery board) +* STM32L053R8 (STM32 Nucleo-L053R8 board) +* STM32L152RE (STM32-Nucleo-L152RE board * STM32L452RET6 (STM32 Nucleo-L452RE board) -* STM32F042K6 (STM32 Nucleo-32 Board) - -Please report any and all known working combinations so I can update this! +* STM32L476RG (STM32 Nucleo-L476RG board) +Please report any and all known working combinations so I can update this! From 7c0ebda0b514fb4c707205259ab221bd90f4cf78 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 21 Feb 2020 02:38:56 +0100 Subject: [PATCH 0702/1435] Improved support for STM32G0xx series. Fix for (#850 #857) (identical to #825) --- src/chipid.c | 6 +++--- src/common.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/chipid.c b/src/chipid.c index ebb5a9027..df07d524f 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -522,9 +522,9 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x2000 }, { - // STM32G031/041 (from RM0444) + // STM32GG030/031/041 (from RM0444) .chip_id = STLINK_CHIPID_STM32_G0_CAT1, - .description = "G031/G041 device", + .description = "G030/G031/G041 device", .flash_type = STLINK_FLASH_TYPE_G0, .flash_size_reg = 0x1FFF75E0, // Section 38.2 .flash_pagesize = 0x800, // 2K (sec 3.2) @@ -535,7 +535,7 @@ static const struct stlink_chipid_params devices[] = { { // STM32G071/081 (from RM0444) .chip_id = STLINK_CHIPID_STM32_G0_CAT2, - .description = "G071/G081 device", + .description = "G070/G071/G081 device", .flash_type = STLINK_FLASH_TYPE_G0, .flash_size_reg = 0x1FFF75E0, // Section 38.2 .flash_pagesize = 0x800, // 2K (sec 3.2) diff --git a/src/common.c b/src/common.c index 73c8e51ad..018e01c4c 100644 --- a/src/common.c +++ b/src/common.c @@ -2617,7 +2617,7 @@ static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t l uint32_t val; if(len != 4) { - ELOG("Wrong length for writting option bytes, must be 4 is %d\n", len); + ELOG("Wrong length for writing option bytes, must be 4 is %d\n", len); return -1; } @@ -2811,7 +2811,7 @@ static int stlink_write_option_bytes_l1(stlink_t *sl, uint8_t* base, stm32_addr_ if( data != val ) { WLOG("Writing option bytes 0x%04x\n", data); stlink_write_debug32(sl, addr, data); - + stlink_read_debug32(sl, addr, &val); WLOG("Option bytes is 0x%08x\n",val); } @@ -2829,11 +2829,11 @@ static int stlink_write_option_bytes_l1(stlink_t *sl, uint8_t* base, stm32_addr_ if( data != val ) { WLOG("Writing 2nd option bytes 0x%04x\n", data); stlink_write_debug32(sl, addr+4, data); - + stlink_read_debug32(sl, addr+4, &val); WLOG("2nd option bytes is 0x%08x\n",val); } - } + } /* Reload options */ stlink_read_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); @@ -3116,7 +3116,7 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui else if((sl->chip_id == STLINK_CHIPID_STM32_L496X) && (addr == STM32_L496X_OPTION_BYTES_BASE)) { return stlink_write_option_bytes_l496x(sl, base, len); } - else if( ( (sl->chip_id == STLINK_CHIPID_STM32_L152_RE) || (sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH) ) + else if( ( (sl->chip_id == STLINK_CHIPID_STM32_L152_RE) || (sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH) ) && ( (addr == STM32_L1_OPTION_BYTES_BASE) || (addr == STM32_L1_OPTION_BYTES_BASE+4) ) ) { return stlink_write_option_bytes_l1(sl, base, addr, len); } From 5a5c3d71d7568070bc108e7501ff977ad94d653c Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Fri, 21 Feb 2020 06:53:28 +0200 Subject: [PATCH 0703/1435] --- --- src/common.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/common.c b/src/common.c index bef3a5e3d..018e01c4c 100644 --- a/src/common.c +++ b/src/common.c @@ -2631,15 +2631,6 @@ static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t l return -1; } - // Make sure we've loaded the context with the chip details - stlink_core_id(sl); - - /* Check if chip is supported and for correct address */ - if((sl->chip_id != STLINK_CHIPID_STM32_G0_CAT2 && sl->chip_id != STLINK_CHIPID_STM32_G0_CAT1) || (addr != STM32_G0_OPTION_BYTES_BASE)) { - ELOG("Option bytes writing is currently only supported for the STM32G0\n"); - return -1; - } - /* Unlock flash if necessary (ref manuel page 52) */ stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); if ((val & (1u << STM32Gx_FLASH_CR_LOCK))) { From d312ca267f33ddbe055d36e8a2cf74a123de4174 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 21 Feb 2020 17:51:22 +0100 Subject: [PATCH 0704/1435] Updated CHANGELOG.md for Release v1.5.1 --- CHANGELOG.md | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20d242a1a..f122e77ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,7 @@ Major changes and added features: Updates and fixes: -* Make udev rules and modprobe conf installation optional ([#741](https://github.com/texane/stlink/pull/741)) +* Made udev rules and modprobe conf installation optional ([#741](https://github.com/texane/stlink/pull/741)) * Fixed case when __FILE__ don't contain "/" nor "\\". ([#745](https://github.com/texane/stlink/pull/745)) * Fixed double dash issue in doc/man ([#746](https://github.com/texane/stlink/pull/746)) * Fixed Debug error on line 123 in CMakeLists.txt (@xor-gate) @@ -59,19 +59,29 @@ Release date: 2018-09-13 Major changes and added features: -* Implemented intel hex support for GTK GUI -* Updated libusb to 1.0.22 -* Added memory map for STM32F411RE target -* Add support for STM32L4R9 target +* Added button to export stm32 flash memory to a file ([#691](https://github.com/texane/stlink/pull/691)) +* Updated libusb to 1.0.22 ([#695](https://github.com/texane/stlink/pull/695)) +* Added desktop file for linux ([#688](https://github.com/texane/stlink/pull/688)) +* Added icons for stlink GUI ([#697](https://github.com/texane/stlink/pull/697)) +* Added support for STM32L4R9 target ([#694](https://github.com/texane/stlink/pull/694), [#699](https://github.com/texane/stlink/pull/699) +* Added creation of icons for .desktop file ([#708](https://github.com/texane/stlink/pull/708)) +* Added memory map for STM32F411RE target ([#709](https://github.com/texane/stlink/pull/709)) +* Added reset through AIRCR ([#540](https://github.com/texane/stlink/pull/540), [#712](https://github.com/texane/stlink/pull/712) +* Implemented intel hex support for GTK GUI ([#718](https://github.com/texane/stlink/pull/718)) Fixes: -* FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION -* Proper flash page size calculation for F412 target -* Fixed flash memory map for F72xxx target -* Return correct value on EOF for Semihosting SYS_READ - -For a complete list of changes see [the milestone](https://github.com/texane/stlink/milestone/6?closed=1) +* Fixed missing flash_loader for L011 ([#675](https://github.com/texane/stlink/pull/675)) +* Fixed serial number size mismatch with stlink_open_usb() ([#680](https://github.com/texane/stlink/pull/680)) +* Debian packaging, CMake and README.md fixes ([#683](https://github.com/texane/stlink/pull/683)) +* Fix for stlink library calls exit() or _exit() ([#634](https://github.com/texane/stlink/pull/634), [#696](https://github.com/texane/stlink/pull/696) +* Fix for libusb deprecation ([#703](https://github.com/texane/stlink/pull/703), [#704](https://github.com/texane/stlink/pull/704) +* Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX ([#706](https://github.com/texane/stlink/pull/706)) +* Fixed flash memory map for F72XXX target ([#711](https://github.com/texane/stlink/pull/711)) +* Proper flash page size calculation for F412 target ([#721](https://github.com/texane/stlink/pull/721)) +* Return correct value on EOF for Semihosting SYS_READ ([#725](https://github.com/texane/stlink/pull/725), [#726](https://github.com/texane/stlink/pull/726, [#729](https://github.com/texane/stlink/pull/729, [#731](https://github.com/texane/stlink/pull/731) +* Fix for mem_write() ([#730](https://github.com/texane/stlink/pull/730)) +* FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION ([#733](https://github.com/texane/stlink/pull/733)) v1.5.0 ====== From e06daedccfdf043191821d9fbf8d1664542912de Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 21 Feb 2020 22:51:29 +0100 Subject: [PATCH 0705/1435] Minor corrections in CHANGELOG.md --- CHANGELOG.md | 6 +++--- src/flash_loader.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20d242a1a..213d26358 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,9 @@ Major changes and added features: * Added O_BINARY option to open file ([#753](https://github.com/texane/stlink/pull/753)) * Added preliminary support for some STM32G0 chips ([#759](https://github.com/texane/stlink/pull/759)) ([#760](https://github.com/texane/stlink/pull/760)) -* Added support for mass erasing second bank on STM32F10x_XL ([#767](https://github.com/texane/stlink/pull/767)) +* Added support for mass erasing second bank on STM32F10x_XL ([#767](https://github.com/texane/stlink/pull/767), [#768](https://github.com/texane/stlink/pull/768)) * Added call to clear PG bit after writing to flash ([#773](https://github.com/texane/stlink/pull/773)) -* Added howto for sending NRST signal through GDB ([#776](https://github.com/texane/stlink/pull/776)) +* Added howto for sending NRST signal through GDB ([#774](https://github.com/texane/stlink/pull/774), [#776](https://github.com/texane/stlink/pull/776)) * Added support to write option bytes for the STM32G0 ([#778](https://github.com/texane/stlink/pull/778)) * Added simple read/write support for STM32WB55 chips ([#786](https://github.com/texane/stlink/pull/786)) * Added STLink V3SET VID:PIDs to the udev rules ([#789](https://github.com/texane/stlink/pull/789)) @@ -35,7 +35,7 @@ Updates and fixes: * Fixed versioning when compiling from the checked out git-repo ([#762](https://github.com/texane/stlink/pull/762)) * Fixed "unkown chip id", piped output and st-util -v ([#763](https://github.com/texane/stlink/pull/763)) * win32: move usleep definition to unistd.h ([#765](https://github.com/texane/stlink/pull/765)) -* Fixed relative path to the UI files needed by stlink-gui-local (GUI) ([#771](https://github.com/texane/stlink/pull/771)) +* Fixed relative path to the UI files needed by stlink-gui-local (GUI) ([#770](https://github.com/texane/stlink/pull/770), [#771](https://github.com/texane/stlink/pull/771)) * Fixed package name "devscripts" in doc/compiling.md ([#775](https://github.com/texane/stlink/pull/775)) * Fixed apparent STM32G0 flashing issue ([#797](https://github.com/texane/stlink/pull/797)) * Fixed few potential memory/resource leaks ([#803](https://github.com/texane/stlink/pull/803)) diff --git a/src/flash_loader.c b/src/flash_loader.c index 1e125e926..9f6e3a79d 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -317,11 +317,11 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); } else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || - (sl->chip_id == STLINK_CHIPID_STM32_L41X) || - (sl->chip_id == STLINK_CHIPID_STM32_L43X) || - (sl->chip_id == STLINK_CHIPID_STM32_L46X) || - (sl->chip_id == STLINK_CHIPID_STM32_L4RX) || - (sl->chip_id == STLINK_CHIPID_STM32_L496X)) + (sl->chip_id == STLINK_CHIPID_STM32_L41X) || + (sl->chip_id == STLINK_CHIPID_STM32_L43X) || + (sl->chip_id == STLINK_CHIPID_STM32_L46X) || + (sl->chip_id == STLINK_CHIPID_STM32_L4RX) || + (sl->chip_id == STLINK_CHIPID_STM32_L496X)) { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); From ee20ab091e9c4b81b6b0ef74d5c6bbf88fe7353d Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 22 Feb 2020 01:24:49 +0100 Subject: [PATCH 0706/1435] Updated README.md --- README.md | 203 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 104 insertions(+), 99 deletions(-) diff --git a/README.md b/README.md index 5d98f0e7e..594e0fae9 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,21 @@ Open source version of the STMicroelectronics Stlink Tools ========================================================== -[![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) +[![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) [![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/v1.6.0.svg)](https://github.com/texane/stlink/releases/master) [![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/texane/stlink/releases) - [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) [![macOS Status](https://img.shields.io/travis/texane/stlink/master.svg?label=osx)](https://travis-ci.org/texane/stlink) +Recent new features and bugfixes can be found in the [Changelog](CHANGELOG.md) of this software project. + + +## Introduction -## HOWTO +This stlink toolset supports several so called stlink programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG. -This stlink toolset supports several so called stlink programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG. These programmer boards are available in four versions: +These programmer boards are available in four versions: * **STLINKv1:** - transport layer: SCSI passthru commands over USB @@ -24,39 +27,122 @@ This stlink toolset supports several so called stlink programmer boards (and clo * transport layer: raw USB commands * present on some STM32 nucleo boards * **STLINKv3:** - * _currently not supported by this toolset_ + * _not yet supported by this toolset (but planned)_ + + +## Supported hardware combinations + +Currently known working combinations of programmers and targets are listed in [doc/tested-boards.md](doc/tested-boards.md). ## Installation -Windows users can [download v1.3.0](https://github.com/texane/stlink/releases/tag/1.3.0) from the releases page. +**Windows**: download [v1.6.0](https://github.com/texane/stlink/releases/tag/v1.6.0) from the releases page. + +**macOS**: install [from homebrew](http://brewformulas.org/Stlink) or download [v1.6.0](https://github.com/texane/stlink/releases/tag/v1.6.0) from the releases page. -Mac OS X users can install from [homebrew](http://brewformulas.org/Stlink) or [download v1.3.0](https://github.com/texane/stlink/releases/tag/1.3.0) from the releases page. +**Linux**: -Debian Linux users can install it via the ```stlink-tools``` package [repository](https://packages.debian.org/buster/stlink-tools) +We recommend to install `stlink-tools` from the package repository of the used distribution: -Ubuntu Linux users can install it via the ```stlink-tools``` package [repository](https://packages.ubuntu.com/stlink-tools) +* Debian Linux: [(Link)](https://packages.debian.org/buster/stlink-tools) +* Ubuntu Linux: [(Link)](https://packages.ubuntu.com/stlink-tools) +* Arch Linux: [(Link)](https://www.archlinux.org/packages/community/x86_64/stlink) +* Alpine Linux: [(Link)](https://pkgs.alpinelinux.org/packages?name=stlink) +* Fedora: [(Link)](https://src.fedoraproject.org/rpms/stlink) +* Gentoo Linux: [(Link)](https://packages.gentoo.org/packages/dev-embedded/stlink) -Arch Linux users can install from the [repository](https://www.archlinux.org/packages/community/x86_64/stlink) +**Other Operating Systems**: -Alpine Linux users can install from the [repository](https://pkgs.alpinelinux.org/packages?name=stlink) +* RedHat/CentOS 7: Users can install [from EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel7) +* FreeBSD: Users can install [from freshports](https://www.freshports.org/devel/stlink) +* OpenBSD: Users need to install [from source](doc/compiling.md). -Fedora users can install from [repository](https://src.fedoraproject.org/rpms/stlink) -RedHat/CentOS 7 users can install from EPEL [repository](https://src.fedoraproject.org/rpms/stlink/branch/epel7) +## Installation from source (advanced users) -Gentoo Linux users can install from the official portage [repository](https://packages.gentoo.org/packages/dev-embedded/stlink) +When there is no executable available for your platform or you need the latest (possible unstable) version you need to compile the toolset yourself. This procedure is explained in the [compiling manual](doc/compiling.md). -FreeBSD users can install from [freshports](https://www.freshports.org/devel/stlink) -OpenBSD users need to install [from source](doc/compiling.md). +## Contributing and versioning +* The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) +* Before creating a pull request, please _ALWAYS_ open a new issue for the discussion of the intended new features. Bugfixes don't require a discussion via a ticket-issue. However they should always be described in a few words as soon as they appear to help others as well. +* Contributors and/or maintainers may submit comments or request changes to patch-proposals and/or pull-requests. -## Installation from source (advanced users) -When there is no executable available for your platform or you need the latest (possible unstable) version you need to compile yourself. This is explained in the [compiling manual](doc/compiling.md). +## License + +The stlink library and tools are licensed under the [BSD license](LICENSE.md). + +The flashloaders/stm32l0x.s and flashloaders/stm32lx.s source files are licensed under the GPLv2+. +# Current state of the project + +## Known missing features + +Some features are currently missing from the `texane/stlink` toolset. +Here we would appreciate any help and would love to welcome new contributors who want to get involved: + +* Instrumentation Trace Macro (ITM) Cell ([#136](https://github.com/texane/stlink/issues/136)) +* OTP area programming ([#202](https://github.com/texane/stlink/issues/202)) +* EEPROM area programming ([#318](https://github.com/texane/stlink/issues/218)) +* Protection bits area reading ([#346](https://github.com/texane/stlink/issues/346)) +* Writing external memory connected to an STM32 controller (e.g Quad SPI NOR flash) ([#412](https://github.com/texane/stlink/issues/412)) +* MCU hotplug ([#449](https://github.com/texane/stlink/issues/449)) +* Writing options bytes (region) ([#458](https://github.com/texane/stlink/issues/458)) +* Control programming speed ([#462](https://github.com/texane/stlink/issues/462)) +* Support for STLINKv3 programmer ([#820](https://github.com/texane/stlink/issues/820)) + + +## Known bugs +### Sometimes flashing only works after a mass erase + +There is seen a problem sometimes where a flash loader run error occurs and is resolved after mass-erase of the flash: + +``` +2015-12-09T22:01:57 INFO src/stlink-common.c: Successfully loaded flash loader in sram +2015-12-09T22:02:18 ERROR src/stlink-common.c: flash loader run error +2015-12-09T22:02:18 ERROR src/stlink-common.c: run_flash_loader(0x8000000) failed! == -1 +``` + +Issue related to this bug: [#356](https://github.com/texane/stlink/issues/356) + + +### Flash size is detected as zero bytes size + +It is possible that the STM32 flash is write protected, the st-flash tool will show something like this: + +``` +st-flash write prog.bin 0x8000000 +2017-01-24T18:44:14 INFO src/stlink-common.c: Loading device parameters.... +2017-01-24T18:44:14 INFO src/stlink-common.c: Device connected is: F1 High-density device, id 0x10036414 +2017-01-24T18:44:14 INFO src/stlink-common.c: SRAM size: 0x10000 bytes (64 KiB), Flash: 0 bytes (0 KiB) in pages of 2048 bytes +``` + +As you can see, it gives out something unexpected like +``` +Flash: 0 bytes (0 KiB) in pages of 2048 bytes +``` + +``` +st-info --probe +Found 1 stlink programmers + serial: 303030303030303030303031 +openocd: "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x31" + flash: 0 (pagesize: 2048) + sram: 65536 + chipid: 0x0414 + descr: F1 High-density device +``` + +Try to remove the write protection (probably only possible with ST Link Utility from ST itself). + +Issue related to this bug: [#545](https://github.com/texane/stlink/issues/545) + + +# HOWTO ## Using the gdb server To run the gdb server: @@ -177,84 +263,3 @@ A: Sometimes when you will try to use GDB `next` command to skip a loop, it will Q: Load command does not work in GDB. A: Some people report XML/EXPAT is not enabled by default when compiling GDB. Memory map parsing thus fail. Use --enable-expat. - - -## Currently known working combinations of programmer and target - -See [doc/tested-boards.md](doc/tested-boards.md) - -## Changelog - -The [Changelog](CHANGELOG.md) for the StLink Tools. - - -## Known missing features - -Some features are missing from the `texane/stlink` project and we would like you to help us out if you want to get involved: - -* Control programming speed (See [#462](https://github.com/texane/stlink/issues/462)) -* OTP area programming (See [#202](https://github.com/texane/stlink/issues/202)) -* EEPROM area programming (See [#318](https://github.com/texane/stlink/issues/218)) -* Protection bits area reading (See [#346](https://github.com/texane/stlink/issues/346)) -* MCU hotplug (See [#449](https://github.com/texane/stlink/issues/449)) -* Writing options bytes (region) (See [#458](https://github.com/texane/stlink/issues/458)) -* Instrumentation Trace Macro (ITM) Cell (See [#136](https://github.com/texane/stlink/issues/136)) -* Writing external memory connected to an STM32 controller (e.g Quad SPI NOR flash) (See [#412](https://github.com/texane/stlink/issues/412)) - - -## Known bugs -### Sometimes flashing only works after a mass erase - -There is seen a problem sometimes where a flash loader run error occurs and is resolved after mass-erase of the flash: - -``` -2015-12-09T22:01:57 INFO src/stlink-common.c: Successfully loaded flash loader in sram -2015-12-09T22:02:18 ERROR src/stlink-common.c: flash loader run error -2015-12-09T22:02:18 ERROR src/stlink-common.c: run_flash_loader(0x8000000) failed! == -1 -``` - -Issue related to this bug: [#356](https://github.com/texane/stlink/issues/356) - - -### Flash size is detected as zero bytes size - -It is possible that the STM32 flash is write protected, the st-flash tool will show something like this: - -``` -st-flash write prog.bin 0x8000000 -2017-01-24T18:44:14 INFO src/stlink-common.c: Loading device parameters.... -2017-01-24T18:44:14 INFO src/stlink-common.c: Device connected is: F1 High-density device, id 0x10036414 -2017-01-24T18:44:14 INFO src/stlink-common.c: SRAM size: 0x10000 bytes (64 KiB), Flash: 0 bytes (0 KiB) in pages of 2048 bytes -``` - -As you can see, it gives out something unexpected like -``` -Flash: 0 bytes (0 KiB) in pages of 2048 bytes -``` - -``` -st-info --probe -Found 1 stlink programmers - serial: 303030303030303030303031 -openocd: "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x31" - flash: 0 (pagesize: 2048) - sram: 65536 - chipid: 0x0414 - descr: F1 High-density device -``` - -Try to remove the write protection (probably only possible with ST Link Utility from ST itself). - -Issue related to this bug: [#545](https://github.com/texane/stlink/issues/545) - - -## Contributing and versioning - -* The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) -* When creating a pull request, please open first a issue for discussion of new features. Bugfixes don't need a discussion. - -## License - -The stlink library and tools are licensed under the [BSD license](LICENSE.md). - -The flashloaders/stm32l0x.s and flashloaders/stm32lx.s source files are licensed under the GPLv2+. From afaded2782ca193841198a5451b2bec89998a7e3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 22 Feb 2020 17:50:31 +0100 Subject: [PATCH 0707/1435] General Project Update - Formatting fixes in CHANGELOG.md - Added comment in .travis.sh - Update for .travis.yml: gcc/g++ v5->v6 --- .travis.sh | 2 +- .travis.yml | 13 ++++++++----- CHANGELOG.md | 14 +++++++------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/.travis.sh b/.travis.sh index 06e95ef80..05568d37d 100755 --- a/.travis.sh +++ b/.travis.sh @@ -8,7 +8,7 @@ echo "----" if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq || true sudo apt-get install -qq -y --no-install-recommends libgtk-3-dev -else +else #("$TRAVIS_OS_NAME" == "osx") brew install libusb fi diff --git a/.travis.yml b/.travis.yml index c878be799..b0f985012 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,21 +1,24 @@ -language: c + compiler: - gcc - clang + +language: c + os: - linux - osx + addons: apt: sources: -# - llvm-toolchain-precise-3.8 - sourceline: 'ppa:ubuntu-toolchain-r/test' packages: - clang -# - clang-3.8 - - g++-5 - - gcc-5 + - g++-6 + - gcc-6 - libusb-1.0.0-dev + script: - git fetch --tags - printenv diff --git a/CHANGELOG.md b/CHANGELOG.md index f122e77ec..25abd0a54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ Release date: 2020-02-20 Major changes and added features: * Added O_BINARY option to open file ([#753](https://github.com/texane/stlink/pull/753)) -* Added preliminary support for some STM32G0 chips ([#759](https://github.com/texane/stlink/pull/759)) ([#760](https://github.com/texane/stlink/pull/760)) +* Added preliminary support for some STM32G0 chips ([#759](https://github.com/texane/stlink/pull/759), [#760](https://github.com/texane/stlink/pull/760)) * Added support for mass erasing second bank on STM32F10x_XL ([#767](https://github.com/texane/stlink/pull/767)) * Added call to clear PG bit after writing to flash ([#773](https://github.com/texane/stlink/pull/773)) * Added howto for sending NRST signal through GDB ([#776](https://github.com/texane/stlink/pull/776)) @@ -39,7 +39,7 @@ Updates and fixes: * Fixed package name "devscripts" in doc/compiling.md ([#775](https://github.com/texane/stlink/pull/775)) * Fixed apparent STM32G0 flashing issue ([#797](https://github.com/texane/stlink/pull/797)) * Fixed few potential memory/resource leaks ([#803](https://github.com/texane/stlink/pull/803)) -* Fixed flash verification error on STM32WB55RG ([#810](https://github.com/texane/stlink/pull/810)) ([#816](https://github.com/texane/stlink/pull/816)) +* Fixed flash verification error on STM32WB55RG ([#810](https://github.com/texane/stlink/pull/810), [#816](https://github.com/texane/stlink/pull/816)) * Do not issue JTAG reset on stlink-v1 (Gwenhael Goavec-Merou) * Fixed flash size of STM32 Discovery vl (Gwenhael Goavec-Merou) * Added support for writing option bytes on STM32L0 (Adrian Imboden) @@ -63,10 +63,10 @@ Major changes and added features: * Updated libusb to 1.0.22 ([#695](https://github.com/texane/stlink/pull/695)) * Added desktop file for linux ([#688](https://github.com/texane/stlink/pull/688)) * Added icons for stlink GUI ([#697](https://github.com/texane/stlink/pull/697)) -* Added support for STM32L4R9 target ([#694](https://github.com/texane/stlink/pull/694), [#699](https://github.com/texane/stlink/pull/699) +* Added support for STM32L4R9 target ([#694](https://github.com/texane/stlink/pull/694), [#699](https://github.com/texane/stlink/pull/699)) * Added creation of icons for .desktop file ([#708](https://github.com/texane/stlink/pull/708)) * Added memory map for STM32F411RE target ([#709](https://github.com/texane/stlink/pull/709)) -* Added reset through AIRCR ([#540](https://github.com/texane/stlink/pull/540), [#712](https://github.com/texane/stlink/pull/712) +* Added reset through AIRCR ([#540](https://github.com/texane/stlink/pull/540), [#712](https://github.com/texane/stlink/pull/712)) * Implemented intel hex support for GTK GUI ([#718](https://github.com/texane/stlink/pull/718)) Fixes: @@ -74,12 +74,12 @@ Fixes: * Fixed missing flash_loader for L011 ([#675](https://github.com/texane/stlink/pull/675)) * Fixed serial number size mismatch with stlink_open_usb() ([#680](https://github.com/texane/stlink/pull/680)) * Debian packaging, CMake and README.md fixes ([#683](https://github.com/texane/stlink/pull/683)) -* Fix for stlink library calls exit() or _exit() ([#634](https://github.com/texane/stlink/pull/634), [#696](https://github.com/texane/stlink/pull/696) -* Fix for libusb deprecation ([#703](https://github.com/texane/stlink/pull/703), [#704](https://github.com/texane/stlink/pull/704) +* Fix for stlink library calls exit() or _exit() ([#634](https://github.com/texane/stlink/pull/634), [#696](https://github.com/texane/stlink/pull/696)) +* Fix for libusb deprecation ([#703](https://github.com/texane/stlink/pull/703), [#704](https://github.com/texane/stlink/pull/704)) * Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX ([#706](https://github.com/texane/stlink/pull/706)) * Fixed flash memory map for F72XXX target ([#711](https://github.com/texane/stlink/pull/711)) * Proper flash page size calculation for F412 target ([#721](https://github.com/texane/stlink/pull/721)) -* Return correct value on EOF for Semihosting SYS_READ ([#725](https://github.com/texane/stlink/pull/725), [#726](https://github.com/texane/stlink/pull/726, [#729](https://github.com/texane/stlink/pull/729, [#731](https://github.com/texane/stlink/pull/731) +* Return correct value on EOF for Semihosting SYS_READ ([#725](https://github.com/texane/stlink/pull/725), [#726](https://github.com/texane/stlink/pull/726), [#729](https://github.com/texane/stlink/pull/729), [#731](https://github.com/texane/stlink/pull/731)) * Fix for mem_write() ([#730](https://github.com/texane/stlink/pull/730)) * FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION ([#733](https://github.com/texane/stlink/pull/733)) From 3af8048356f3b4663750aa35dda53829846b6df3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 23 Feb 2020 03:08:08 +0100 Subject: [PATCH 0708/1435] General Project Update - Corrected CHANGELOG.md - Added comment in .travis.sh - Update for .travis.yml: gcc/g++ v5->v6 --- .travis.sh | 2 +- .travis.yml | 13 ++++++++----- CHANGELOG.md | 14 +++++++------- stlinkv1_macosx_driver/README.md | 18 ++++++------------ 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/.travis.sh b/.travis.sh index 06e95ef80..05568d37d 100755 --- a/.travis.sh +++ b/.travis.sh @@ -8,7 +8,7 @@ echo "----" if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq || true sudo apt-get install -qq -y --no-install-recommends libgtk-3-dev -else +else #("$TRAVIS_OS_NAME" == "osx") brew install libusb fi diff --git a/.travis.yml b/.travis.yml index c878be799..b0f985012 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,21 +1,24 @@ -language: c + compiler: - gcc - clang + +language: c + os: - linux - osx + addons: apt: sources: -# - llvm-toolchain-precise-3.8 - sourceline: 'ppa:ubuntu-toolchain-r/test' packages: - clang -# - clang-3.8 - - g++-5 - - gcc-5 + - g++-6 + - gcc-6 - libusb-1.0.0-dev + script: - git fetch --tags - printenv diff --git a/CHANGELOG.md b/CHANGELOG.md index f122e77ec..ba4c46d08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ Release date: 2020-02-20 Major changes and added features: * Added O_BINARY option to open file ([#753](https://github.com/texane/stlink/pull/753)) -* Added preliminary support for some STM32G0 chips ([#759](https://github.com/texane/stlink/pull/759)) ([#760](https://github.com/texane/stlink/pull/760)) +* Added preliminary support for some STM32G0 chips ([#759](https://github.com/texane/stlink/pull/759), [#760](https://github.com/texane/stlink/pull/760)) * Added support for mass erasing second bank on STM32F10x_XL ([#767](https://github.com/texane/stlink/pull/767)) * Added call to clear PG bit after writing to flash ([#773](https://github.com/texane/stlink/pull/773)) * Added howto for sending NRST signal through GDB ([#776](https://github.com/texane/stlink/pull/776)) @@ -39,7 +39,7 @@ Updates and fixes: * Fixed package name "devscripts" in doc/compiling.md ([#775](https://github.com/texane/stlink/pull/775)) * Fixed apparent STM32G0 flashing issue ([#797](https://github.com/texane/stlink/pull/797)) * Fixed few potential memory/resource leaks ([#803](https://github.com/texane/stlink/pull/803)) -* Fixed flash verification error on STM32WB55RG ([#810](https://github.com/texane/stlink/pull/810)) ([#816](https://github.com/texane/stlink/pull/816)) +* Fixed flash verification error on STM32WB55RG ([#810](https://github.com/texane/stlink/pull/810), [#816](https://github.com/texane/stlink/pull/816)) * Do not issue JTAG reset on stlink-v1 (Gwenhael Goavec-Merou) * Fixed flash size of STM32 Discovery vl (Gwenhael Goavec-Merou) * Added support for writing option bytes on STM32L0 (Adrian Imboden) @@ -63,10 +63,10 @@ Major changes and added features: * Updated libusb to 1.0.22 ([#695](https://github.com/texane/stlink/pull/695)) * Added desktop file for linux ([#688](https://github.com/texane/stlink/pull/688)) * Added icons for stlink GUI ([#697](https://github.com/texane/stlink/pull/697)) -* Added support for STM32L4R9 target ([#694](https://github.com/texane/stlink/pull/694), [#699](https://github.com/texane/stlink/pull/699) +* Added support for STM32L4R9 target ([#694](https://github.com/texane/stlink/pull/694), [#699](https://github.com/texane/stlink/pull/699)) * Added creation of icons for .desktop file ([#708](https://github.com/texane/stlink/pull/708)) * Added memory map for STM32F411RE target ([#709](https://github.com/texane/stlink/pull/709)) -* Added reset through AIRCR ([#540](https://github.com/texane/stlink/pull/540), [#712](https://github.com/texane/stlink/pull/712) +* Added reset through AIRCR ([#540](https://github.com/texane/stlink/pull/540), [#712](https://github.com/texane/stlink/pull/712)) * Implemented intel hex support for GTK GUI ([#718](https://github.com/texane/stlink/pull/718)) Fixes: @@ -74,12 +74,12 @@ Fixes: * Fixed missing flash_loader for L011 ([#675](https://github.com/texane/stlink/pull/675)) * Fixed serial number size mismatch with stlink_open_usb() ([#680](https://github.com/texane/stlink/pull/680)) * Debian packaging, CMake and README.md fixes ([#683](https://github.com/texane/stlink/pull/683)) -* Fix for stlink library calls exit() or _exit() ([#634](https://github.com/texane/stlink/pull/634), [#696](https://github.com/texane/stlink/pull/696) -* Fix for libusb deprecation ([#703](https://github.com/texane/stlink/pull/703), [#704](https://github.com/texane/stlink/pull/704) +* Fix for stlink library calls exit() or _exit() ([#634](https://github.com/texane/stlink/pull/634), [#696](https://github.com/texane/stlink/pull/696)) +* Fix for libusb deprecation ([#703](https://github.com/texane/stlink/pull/703), [#704](https://github.com/texane/stlink/pull/704)) * Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX ([#706](https://github.com/texane/stlink/pull/706)) * Fixed flash memory map for F72XXX target ([#711](https://github.com/texane/stlink/pull/711)) * Proper flash page size calculation for F412 target ([#721](https://github.com/texane/stlink/pull/721)) -* Return correct value on EOF for Semihosting SYS_READ ([#725](https://github.com/texane/stlink/pull/725), [#726](https://github.com/texane/stlink/pull/726, [#729](https://github.com/texane/stlink/pull/729, [#731](https://github.com/texane/stlink/pull/731) +* Return correct value on EOF for Semihosting SYS_READ ([#726](https://github.com/texane/stlink/pull/726), [#729](https://github.com/texane/stlink/pull/729), [#731](https://github.com/texane/stlink/pull/731)) * Fix for mem_write() ([#730](https://github.com/texane/stlink/pull/730)) * FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION ([#733](https://github.com/texane/stlink/pull/733)) diff --git a/stlinkv1_macosx_driver/README.md b/stlinkv1_macosx_driver/README.md index 4e6b8c6a0..b2a68442c 100644 --- a/stlinkv1_macosx_driver/README.md +++ b/stlinkv1_macosx_driver/README.md @@ -4,18 +4,14 @@ to: texane@gmail.com Hi, -i managed to get the stlink v1 working under os x and i would like to share the solution so maybe you can -add it in your package. +i managed to get the stlink v1 working under os x and i would like to share the solution so maybe you can add it in your package. The problem is that os x claims the device as scsi and libusb won't be able to connect to it. -I've created what is called a codeless driver which claims the device and has a higher priority then the -default apple mass storage driver, so the device can be accessed through libusb. +I've created what is called a codeless driver which claims the device and has a higher priority then the default apple mass storage driver, so the device can be accessed through libusb. -I tested this codeless driver under OS X 10.6.8 and 10.7.2. I assume it works with any 10.6.x and 10.7.x -version as well. +I tested this codeless driver under OS X 10.6.8 and 10.7.2. +I assume it works with any 10.6.x and 10.7.x version as well. -Attached to this mail you'll find the osx folder with the source code of the driver, both drivers (for -10.6.x and 10.7.x), an install.sh script and the modified Makefile, i only added a line at the end which -invoke the `install.sh`. +Attached to this mail you'll find the osx folder with the source code of the driver, both drivers (for 10.6.x and 10.7.x), an install.sh script and the modified Makefile, i only added a line at the end which invoke the `install.sh`. First, unpack the `osx.tar.gz` contents: ```bash @@ -41,13 +37,11 @@ P.S. If error `OS X version not supported` occurs. For the latest versions of Ma For OS X 10.10 Yosemite you must force the system to load unsigned kernelextensions ```bash -sudo nvram boot-args="kext-dev-mode=1“ +sudo nvram boot-args="kext-dev-mode=1" ``` reboot the system! ### OS X 10.11 El Capitan -(Update from another user) - For OS X 10.11 El Capitan: the Yosemite kext seems to work (tested on 10.11.04). From a69634c1128dcd08ab9fbb931dfb687ab5d90765 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 24 Feb 2020 22:55:29 +0100 Subject: [PATCH 0709/1435] Updated README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 594e0fae9..7a95a0bde 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ When there is no executable available for your platform or you need the latest ( * The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) * Before creating a pull request, please _ALWAYS_ open a new issue for the discussion of the intended new features. Bugfixes don't require a discussion via a ticket-issue. However they should always be described in a few words as soon as they appear to help others as well. * Contributors and/or maintainers may submit comments or request changes to patch-proposals and/or pull-requests. +* **ATTENTION: _NEVER EVER_ use the '#' character to count-up single points within a listing as '#' is _exclusively_ reserved for referencing github issues and pull-requests. Otherwise you accidentally introduce false cross references within the project.** ## License From 5020ba7f921d456ec821e35d0797e5bb88d1bfcc Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 24 Feb 2020 23:11:51 +0100 Subject: [PATCH 0710/1435] Resolved conflicts with develop branch. --- .travis.sh | 2 +- .travis.yml | 13 +- CHANGELOG.md | 36 ++++-- README.md | 205 ++++++++++++++++--------------- include/stlink.h | 8 ++ include/stlink/commands.h | 1 + include/stlink/usb.h | 16 +-- src/common.c | 43 ++++--- src/tools/flash.c | 10 +- src/usb.c | 199 +++++++++++++++++++++++++----- stlinkv1_macosx_driver/README.md | 18 +-- 11 files changed, 360 insertions(+), 191 deletions(-) diff --git a/.travis.sh b/.travis.sh index 06e95ef80..05568d37d 100755 --- a/.travis.sh +++ b/.travis.sh @@ -8,7 +8,7 @@ echo "----" if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq || true sudo apt-get install -qq -y --no-install-recommends libgtk-3-dev -else +else #("$TRAVIS_OS_NAME" == "osx") brew install libusb fi diff --git a/.travis.yml b/.travis.yml index c878be799..b0f985012 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,21 +1,24 @@ -language: c + compiler: - gcc - clang + +language: c + os: - linux - osx + addons: apt: sources: -# - llvm-toolchain-precise-3.8 - sourceline: 'ppa:ubuntu-toolchain-r/test' packages: - clang -# - clang-3.8 - - g++-5 - - gcc-5 + - g++-6 + - gcc-6 - libusb-1.0.0-dev + script: - git fetch --tags - printenv diff --git a/CHANGELOG.md b/CHANGELOG.md index 213d26358..10f12f81b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ Release date: 2020-02-20 Major changes and added features: * Added O_BINARY option to open file ([#753](https://github.com/texane/stlink/pull/753)) -* Added preliminary support for some STM32G0 chips ([#759](https://github.com/texane/stlink/pull/759)) ([#760](https://github.com/texane/stlink/pull/760)) +* Added preliminary support for some STM32G0 chips ([#759](https://github.com/texane/stlink/pull/759), [#760](https://github.com/texane/stlink/pull/760)) * Added support for mass erasing second bank on STM32F10x_XL ([#767](https://github.com/texane/stlink/pull/767), [#768](https://github.com/texane/stlink/pull/768)) * Added call to clear PG bit after writing to flash ([#773](https://github.com/texane/stlink/pull/773)) * Added howto for sending NRST signal through GDB ([#774](https://github.com/texane/stlink/pull/774), [#776](https://github.com/texane/stlink/pull/776)) @@ -26,7 +26,7 @@ Major changes and added features: Updates and fixes: -* Make udev rules and modprobe conf installation optional ([#741](https://github.com/texane/stlink/pull/741)) +* Made udev rules and modprobe conf installation optional ([#741](https://github.com/texane/stlink/pull/741)) * Fixed case when __FILE__ don't contain "/" nor "\\". ([#745](https://github.com/texane/stlink/pull/745)) * Fixed double dash issue in doc/man ([#746](https://github.com/texane/stlink/pull/746)) * Fixed Debug error on line 123 in CMakeLists.txt (@xor-gate) @@ -39,7 +39,7 @@ Updates and fixes: * Fixed package name "devscripts" in doc/compiling.md ([#775](https://github.com/texane/stlink/pull/775)) * Fixed apparent STM32G0 flashing issue ([#797](https://github.com/texane/stlink/pull/797)) * Fixed few potential memory/resource leaks ([#803](https://github.com/texane/stlink/pull/803)) -* Fixed flash verification error on STM32WB55RG ([#810](https://github.com/texane/stlink/pull/810)) ([#816](https://github.com/texane/stlink/pull/816)) +* Fixed flash verification error on STM32WB55RG ([#810](https://github.com/texane/stlink/pull/810), [#816](https://github.com/texane/stlink/pull/816)) * Do not issue JTAG reset on stlink-v1 (Gwenhael Goavec-Merou) * Fixed flash size of STM32 Discovery vl (Gwenhael Goavec-Merou) * Added support for writing option bytes on STM32L0 (Adrian Imboden) @@ -59,19 +59,29 @@ Release date: 2018-09-13 Major changes and added features: -* Implemented intel hex support for GTK GUI -* Updated libusb to 1.0.22 -* Added memory map for STM32F411RE target -* Add support for STM32L4R9 target +* Added button to export stm32 flash memory to a file ([#691](https://github.com/texane/stlink/pull/691)) +* Updated libusb to 1.0.22 ([#695](https://github.com/texane/stlink/pull/695)) +* Added desktop file for linux ([#688](https://github.com/texane/stlink/pull/688)) +* Added icons for stlink GUI ([#697](https://github.com/texane/stlink/pull/697)) +* Added support for STM32L4R9 target ([#694](https://github.com/texane/stlink/pull/694), [#699](https://github.com/texane/stlink/pull/699)) +* Added creation of icons for .desktop file ([#708](https://github.com/texane/stlink/pull/708)) +* Added memory map for STM32F411RE target ([#709](https://github.com/texane/stlink/pull/709)) +* Added reset through AIRCR ([#540](https://github.com/texane/stlink/pull/540), [#712](https://github.com/texane/stlink/pull/712)) +* Implemented intel hex support for GTK GUI ([#718](https://github.com/texane/stlink/pull/718)) Fixes: -* FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION -* Proper flash page size calculation for F412 target -* Fixed flash memory map for F72xxx target -* Return correct value on EOF for Semihosting SYS_READ - -For a complete list of changes see [the milestone](https://github.com/texane/stlink/milestone/6?closed=1) +* Fixed missing flash_loader for L011 ([#675](https://github.com/texane/stlink/pull/675)) +* Fixed serial number size mismatch with stlink_open_usb() ([#680](https://github.com/texane/stlink/pull/680)) +* Debian packaging, CMake and README.md fixes ([#683](https://github.com/texane/stlink/pull/683)) +* Fix for stlink library calls exit() or _exit() ([#634](https://github.com/texane/stlink/pull/634), [#696](https://github.com/texane/stlink/pull/696)) +* Fix for libusb deprecation ([#703](https://github.com/texane/stlink/pull/703), [#704](https://github.com/texane/stlink/pull/704)) +* Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX ([#706](https://github.com/texane/stlink/pull/706)) +* Fixed flash memory map for F72XXX target ([#711](https://github.com/texane/stlink/pull/711)) +* Proper flash page size calculation for F412 target ([#721](https://github.com/texane/stlink/pull/721)) +* Return correct value on EOF for Semihosting SYS_READ ([#726](https://github.com/texane/stlink/pull/726), [#729](https://github.com/texane/stlink/pull/729), [#731](https://github.com/texane/stlink/pull/731)) +* Fix for mem_write() ([#730](https://github.com/texane/stlink/pull/730)) +* FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION ([#733](https://github.com/texane/stlink/pull/733)) v1.5.0 ====== diff --git a/README.md b/README.md index c8955a521..594e0fae9 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,21 @@ Open source version of the STMicroelectronics Stlink Tools ========================================================== -[![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) -[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/v1.6.0.svg)](https://github.com/texane/stlink/releases/develop) +[![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) +[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/v1.6.0.svg)](https://github.com/texane/stlink/releases/master) [![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/texane/stlink/releases) - [![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) [![macOS Status](https://img.shields.io/travis/texane/stlink/master.svg?label=osx)](https://travis-ci.org/texane/stlink) +Recent new features and bugfixes can be found in the [Changelog](CHANGELOG.md) of this software project. + + +## Introduction -## HOWTO +This stlink toolset supports several so called stlink programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG. -This stlink toolset supports several so called stlink programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG. These programmer boards are available in four versions: +These programmer boards are available in four versions: * **STLINKv1:** - transport layer: SCSI passthru commands over USB @@ -24,39 +27,122 @@ This stlink toolset supports several so called stlink programmer boards (and clo * transport layer: raw USB commands * present on some STM32 nucleo boards * **STLINKv3:** - * _currently not supported by this toolset_ + * _not yet supported by this toolset (but planned)_ + + +## Supported hardware combinations + +Currently known working combinations of programmers and targets are listed in [doc/tested-boards.md](doc/tested-boards.md). ## Installation -Windows users can [download v1.3.0](https://github.com/texane/stlink/releases/tag/1.3.0) from the releases page. +**Windows**: download [v1.6.0](https://github.com/texane/stlink/releases/tag/v1.6.0) from the releases page. + +**macOS**: install [from homebrew](http://brewformulas.org/Stlink) or download [v1.6.0](https://github.com/texane/stlink/releases/tag/v1.6.0) from the releases page. -Mac OS X users can install from [homebrew](http://brewformulas.org/Stlink) or [download v1.3.0](https://github.com/texane/stlink/releases/tag/1.3.0) from the releases page. +**Linux**: -Debian Linux users can install it via the ```stlink-tools``` package [repository](https://packages.debian.org/buster/stlink-tools) +We recommend to install `stlink-tools` from the package repository of the used distribution: -Ubuntu Linux users can install it via the ```stlink-tools``` package [repository](https://packages.ubuntu.com/stlink-tools) +* Debian Linux: [(Link)](https://packages.debian.org/buster/stlink-tools) +* Ubuntu Linux: [(Link)](https://packages.ubuntu.com/stlink-tools) +* Arch Linux: [(Link)](https://www.archlinux.org/packages/community/x86_64/stlink) +* Alpine Linux: [(Link)](https://pkgs.alpinelinux.org/packages?name=stlink) +* Fedora: [(Link)](https://src.fedoraproject.org/rpms/stlink) +* Gentoo Linux: [(Link)](https://packages.gentoo.org/packages/dev-embedded/stlink) -Arch Linux users can install from the [repository](https://www.archlinux.org/packages/community/x86_64/stlink) +**Other Operating Systems**: -Alpine Linux users can install from the [repository](https://pkgs.alpinelinux.org/packages?name=stlink) +* RedHat/CentOS 7: Users can install [from EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel7) +* FreeBSD: Users can install [from freshports](https://www.freshports.org/devel/stlink) +* OpenBSD: Users need to install [from source](doc/compiling.md). -Fedora users can install from [repository](https://src.fedoraproject.org/rpms/stlink) -RedHat/CentOS 7 users can install from EPEL [repository](https://src.fedoraproject.org/rpms/stlink/branch/epel7) +## Installation from source (advanced users) -Gentoo Linux users can install from the official portage [repository](https://packages.gentoo.org/packages/dev-embedded/stlink) +When there is no executable available for your platform or you need the latest (possible unstable) version you need to compile the toolset yourself. This procedure is explained in the [compiling manual](doc/compiling.md). -FreeBSD users can install from [freshports](https://www.freshports.org/devel/stlink) -OpenBSD users need to install [from source](doc/compiling.md). +## Contributing and versioning +* The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) +* Before creating a pull request, please _ALWAYS_ open a new issue for the discussion of the intended new features. Bugfixes don't require a discussion via a ticket-issue. However they should always be described in a few words as soon as they appear to help others as well. +* Contributors and/or maintainers may submit comments or request changes to patch-proposals and/or pull-requests. -## Installation from source (advanced users) -When there is no executable available for your platform or you need the latest (possible unstable) version you need to compile yourself. This is explained in the [compiling manual](doc/compiling.md). +## License + +The stlink library and tools are licensed under the [BSD license](LICENSE.md). + +The flashloaders/stm32l0x.s and flashloaders/stm32lx.s source files are licensed under the GPLv2+. +# Current state of the project + +## Known missing features + +Some features are currently missing from the `texane/stlink` toolset. +Here we would appreciate any help and would love to welcome new contributors who want to get involved: + +* Instrumentation Trace Macro (ITM) Cell ([#136](https://github.com/texane/stlink/issues/136)) +* OTP area programming ([#202](https://github.com/texane/stlink/issues/202)) +* EEPROM area programming ([#318](https://github.com/texane/stlink/issues/218)) +* Protection bits area reading ([#346](https://github.com/texane/stlink/issues/346)) +* Writing external memory connected to an STM32 controller (e.g Quad SPI NOR flash) ([#412](https://github.com/texane/stlink/issues/412)) +* MCU hotplug ([#449](https://github.com/texane/stlink/issues/449)) +* Writing options bytes (region) ([#458](https://github.com/texane/stlink/issues/458)) +* Control programming speed ([#462](https://github.com/texane/stlink/issues/462)) +* Support for STLINKv3 programmer ([#820](https://github.com/texane/stlink/issues/820)) + + +## Known bugs +### Sometimes flashing only works after a mass erase + +There is seen a problem sometimes where a flash loader run error occurs and is resolved after mass-erase of the flash: + +``` +2015-12-09T22:01:57 INFO src/stlink-common.c: Successfully loaded flash loader in sram +2015-12-09T22:02:18 ERROR src/stlink-common.c: flash loader run error +2015-12-09T22:02:18 ERROR src/stlink-common.c: run_flash_loader(0x8000000) failed! == -1 +``` + +Issue related to this bug: [#356](https://github.com/texane/stlink/issues/356) + + +### Flash size is detected as zero bytes size + +It is possible that the STM32 flash is write protected, the st-flash tool will show something like this: + +``` +st-flash write prog.bin 0x8000000 +2017-01-24T18:44:14 INFO src/stlink-common.c: Loading device parameters.... +2017-01-24T18:44:14 INFO src/stlink-common.c: Device connected is: F1 High-density device, id 0x10036414 +2017-01-24T18:44:14 INFO src/stlink-common.c: SRAM size: 0x10000 bytes (64 KiB), Flash: 0 bytes (0 KiB) in pages of 2048 bytes +``` + +As you can see, it gives out something unexpected like +``` +Flash: 0 bytes (0 KiB) in pages of 2048 bytes +``` + +``` +st-info --probe +Found 1 stlink programmers + serial: 303030303030303030303031 +openocd: "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x31" + flash: 0 (pagesize: 2048) + sram: 65536 + chipid: 0x0414 + descr: F1 High-density device +``` + +Try to remove the write protection (probably only possible with ST Link Utility from ST itself). + +Issue related to this bug: [#545](https://github.com/texane/stlink/issues/545) + + +# HOWTO ## Using the gdb server To run the gdb server: @@ -177,84 +263,3 @@ A: Sometimes when you will try to use GDB `next` command to skip a loop, it will Q: Load command does not work in GDB. A: Some people report XML/EXPAT is not enabled by default when compiling GDB. Memory map parsing thus fail. Use --enable-expat. - - -## Currently known working combinations of programmer and target - -See [doc/tested-boards.md](doc/tested-boards.md) - -## Changelog - -The [Changelog](CHANGELOG.md) for the StLink Tools. - - -## Known missing features - -Some features are missing from the `texane/stlink` project and we would like you to help us out if you want to get involved: - -* Control programming speed (See [#462](https://github.com/texane/stlink/issues/462)) -* OTP area programming (See [#202](https://github.com/texane/stlink/issues/202)) -* EEPROM area programming (See [#318](https://github.com/texane/stlink/issues/218)) -* Protection bits area reading (See [#346](https://github.com/texane/stlink/issues/346)) -* MCU hotplug (See [#449](https://github.com/texane/stlink/issues/449)) -* Writing options bytes (region) (See [#458](https://github.com/texane/stlink/issues/458)) -* Instrumentation Trace Macro (ITM) Cell (See [#136](https://github.com/texane/stlink/issues/136)) -* Writing external memory connected to an STM32 controller (e.g Quad SPI NOR flash) (See [#412](https://github.com/texane/stlink/issues/412)) - - -## Known bugs -### Sometimes flashing only works after a mass erase - -There is seen a problem sometimes where a flash loader run error occurs and is resolved after mass-erase of the flash: - -``` -2015-12-09T22:01:57 INFO src/stlink-common.c: Successfully loaded flash loader in sram -2015-12-09T22:02:18 ERROR src/stlink-common.c: flash loader run error -2015-12-09T22:02:18 ERROR src/stlink-common.c: run_flash_loader(0x8000000) failed! == -1 -``` - -Issue related to this bug: [#356](https://github.com/texane/stlink/issues/356) - - -### Flash size is detected as zero bytes size - -It is possible that the STM32 flash is write protected, the st-flash tool will show something like this: - -``` -st-flash write prog.bin 0x8000000 -2017-01-24T18:44:14 INFO src/stlink-common.c: Loading device parameters.... -2017-01-24T18:44:14 INFO src/stlink-common.c: Device connected is: F1 High-density device, id 0x10036414 -2017-01-24T18:44:14 INFO src/stlink-common.c: SRAM size: 0x10000 bytes (64 KiB), Flash: 0 bytes (0 KiB) in pages of 2048 bytes -``` - -As you can see, it gives out something unexpected like -``` -Flash: 0 bytes (0 KiB) in pages of 2048 bytes -``` - -``` -st-info --probe -Found 1 stlink programmers - serial: 303030303030303030303031 -openocd: "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x31" - flash: 0 (pagesize: 2048) - sram: 65536 - chipid: 0x0414 - descr: F1 High-density device -``` - -Try to remove the write protection (probably only possible with ST Link Utility from ST itself). - -Issue related to this bug: [#545](https://github.com/texane/stlink/issues/545) - - -## Contributing and versioning - -* The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) -* When creating a pull request, please open first a issue for discussion of new features. Bugfixes don't need a discussion. - -## License - -The stlink library and tools are licensed under the [BSD license](LICENSE.md). - -The flashloaders/stm32l0x.s and flashloaders/stm32lx.s source files are licensed under the GPLv2+. diff --git a/include/stlink.h b/include/stlink.h index 69b6ae31c..a69e357b5 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -52,6 +52,11 @@ extern "C" { #define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43 +#define STLINK_APIV3_SET_COM_FREQ 0x61 +#define STLINK_APIV3_GET_COM_FREQ 0x62 + +#define STLINK_APIV3_GET_VERSION_EX 0xFB + // Baud rate divisors for SWDCLK #define STLINK_SWDCLK_4MHZ_DIVISOR 0 #define STLINK_SWDCLK_1P8MHZ_DIVISOR 1 @@ -68,6 +73,9 @@ extern "C" { #define STLINK_SERIAL_MAX_SIZE 64 +#define STLINK_V3_MAX_FREQ_NB 10 + + /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ #define C_BUF_LEN 32 diff --git a/include/stlink/commands.h b/include/stlink/commands.h index 9ff5a8fb9..acf664cb1 100644 --- a/include/stlink/commands.h +++ b/include/stlink/commands.h @@ -20,6 +20,7 @@ enum stlink_debug_commands { STLINK_DEBUG_ENTER = 0x20, STLINK_DEBUG_EXIT = 0x21, STLINK_DEBUG_READCOREID = 0x22, + STLINK_DEBUG_APIV2_ENTER = 0x30, STLINK_DEBUG_ENTER_SWD = 0xa3 }; diff --git a/include/stlink/usb.h b/include/stlink/usb.h index fd32a0731..4bf28c355 100644 --- a/include/stlink/usb.h +++ b/include/stlink/usb.h @@ -18,12 +18,15 @@ extern "C" { #endif -#define STLINK_USB_VID_ST 0x0483 -#define STLINK_USB_PID_STLINK 0x3744 -#define STLINK_USB_PID_STLINK_32L 0x3748 -#define STLINK_USB_PID_STLINK_32L_AUDIO 0x374a -#define STLINK_USB_PID_STLINK_NUCLEO 0x374b -#define STLINK_USB_PID_STLINK_NO_UMS 0x3752 +#define STLINK_USB_VID_ST 0x0483 +#define STLINK_USB_PID_STLINK 0x3744 +#define STLINK_USB_PID_STLINK_32L 0x3748 +#define STLINK_USB_PID_STLINK_32L_AUDIO 0x374a +#define STLINK_USB_PID_STLINK_NUCLEO 0x374b +#define STLINK_USB_PID_STLINK_V3_USBLOADER 0x374d +#define STLINK_USB_PID_STLINK_V3E_PID 0x374e +#define STLINK_USB_PID_STLINK_V3S_PID 0x374f +#define STLINK_USB_PID_STLINK_V3_2VCP_PID 0x3753 #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 @@ -55,4 +58,3 @@ extern "C" { #endif #endif /* STLINK_USB_H */ - diff --git a/src/common.c b/src/common.c index 018e01c4c..6226c893b 100644 --- a/src/common.c +++ b/src/common.c @@ -938,22 +938,33 @@ int stlink_status(stlink_t *sl) { * @param slv output parsed version object */ void _parse_version(stlink_t *sl, stlink_version_t *slv) { - uint32_t b0 = sl->q_buf[0]; //lsb - uint32_t b1 = sl->q_buf[1]; - uint32_t b2 = sl->q_buf[2]; - uint32_t b3 = sl->q_buf[3]; - uint32_t b4 = sl->q_buf[4]; - uint32_t b5 = sl->q_buf[5]; //msb - - // b0 b1 || b2 b3 | b4 b5 - // 4b | 6b | 6b || 2B | 2B - // stlink_v | jtag_v | swim_v || st_vid | stlink_pid - - slv->stlink_v = (b0 & 0xf0) >> 4; - slv->jtag_v = ((b0 & 0x0f) << 2) | ((b1 & 0xc0) >> 6); - slv->swim_v = b1 & 0x3f; - slv->st_vid = (b3 << 8) | b2; - slv->stlink_pid = (b5 << 8) | b4; + if (sl->version.stlink_v < 3) { + uint32_t b0 = sl->q_buf[0]; //lsb + uint32_t b1 = sl->q_buf[1]; + uint32_t b2 = sl->q_buf[2]; + uint32_t b3 = sl->q_buf[3]; + uint32_t b4 = sl->q_buf[4]; + uint32_t b5 = sl->q_buf[5]; //msb + + // b0 b1 || b2 b3 | b4 b5 + // 4b | 6b | 6b || 2B | 2B + // stlink_v | jtag_v | swim_v || st_vid | stlink_pid + + slv->stlink_v = (b0 & 0xf0) >> 4; + slv->jtag_v = ((b0 & 0x0f) << 2) | ((b1 & 0xc0) >> 6); + slv->swim_v = b1 & 0x3f; + slv->st_vid = (b3 << 8) | b2; + slv->stlink_pid = (b5 << 8) | b4; + } else { + // V3 uses different version format, for reference see OpenOCD source + // (that was written from docs available from ST under NDA): + // https://github.com/ntfreak/openocd/blob/a6dacdff58ef36fcdac00c53ec27f19de1fbce0d/src/jtag/drivers/stlink_usb.c#L965 + slv->stlink_v = sl->q_buf[0]; + slv->swim_v = sl->q_buf[1]; + slv->jtag_v = sl->q_buf[2]; + slv->st_vid = (uint32_t)((sl->q_buf[9] << 8) | sl->q_buf[8]); + slv->stlink_pid = (uint32_t)((sl->q_buf[11] << 8) | sl->q_buf[10]); + } return; } diff --git a/src/tools/flash.c b/src/tools/flash.c index 1b63b1696..f87b65940 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -29,11 +29,11 @@ static void cleanup(int signum) { static void usage(void) { - puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--format ] [--flash=] {read|write} /dev/sgX "); - puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); - puts("stlinkv2 command line: ./st-flash [--debug] [--reset] [--serial ] [--format ] [--flash=] {read|write} "); - puts("stlinkv2 command line: ./st-flash [--debug] [--serial ] erase"); - puts("stlinkv2 command line: ./st-flash [--debug] [--serial ] reset"); + puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--format ] [--flash=] {read|write} /dev/sgX "); + puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); + puts("stlinkv2/3 command line: ./st-flash [--debug] [--reset] [--serial ] [--format ] [--flash=] {read|write} "); + puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] erase"); + puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] reset"); puts(" Use hex format for addr, and ."); puts(" fsize: Use decimal, octal or hex by prefix 0xXXX for hex, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); puts(" Format may be 'binary' (default) or 'ihex', although must be specified for binary format only."); diff --git a/src/usb.c b/src/usb.c index d3a541774..9df9d7296 100644 --- a/src/usb.c +++ b/src/usb.c @@ -22,6 +22,53 @@ enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80}; +static inline uint32_t le_to_h_u32(const uint8_t* buf) +{ + return (uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24); +} + +static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, uint32_t khz) +{ + unsigned int i; + int speed_index = -1; + int speed_diff = INT_MAX; + int last_valid_speed = -1; + bool match = true; + + for (i = 0; i < map_size; i++) { + if (!map[i]) + continue; + last_valid_speed = i; + if (khz == map[i]) { + speed_index = i; + break; + } else { + int current_diff = khz - map[i]; + /* get abs value for comparison */ + current_diff = (current_diff > 0) ? current_diff : -current_diff; + if ((current_diff < speed_diff) && khz >= map[i]) { + speed_diff = current_diff; + speed_index = i; + } + } + } + + if (speed_index == -1) { + /* this will only be here if we cannot match the slow speed. + * use the slowest speed we support.*/ + speed_index = last_valid_speed; + match = false; + } else if (i == map_size) + match = false; + + if (!match) { + ILOG("Unable to match requested speed %d kHz, using %d kHz\n", \ + khz, map[speed_index]); + } + + return speed_index; +} + void _stlink_usb_close(stlink_t* sl) { if (!sl) return; @@ -135,6 +182,19 @@ int _stlink_usb_version(stlink_t *sl) { return (int) size; } + /* STLINK-V3 requires a specific command */ + if (sl->version.stlink_v == 3) { + rep_len = 12; + i = fill_command(sl, SG_DXFER_FROM_DEV, 16); + cmd[i++] = STLINK_APIV3_GET_VERSION_EX; + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size != rep_len) { + printf("[!] send_recv STLINK_APIV3_GET_VERSION_EX\n"); + return (int) size; + } + } + return 0; } @@ -334,17 +394,23 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; ssize_t size; - const int rep_len = 0; + unsigned char* const data = sl->q_buf; + const uint32_t rep_len = sl->version.stlink_v > 1 ? 2 : 0; int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_ENTER; + cmd[i++] = sl->version.stlink_v > 1? STLINK_DEBUG_APIV2_ENTER : STLINK_DEBUG_ENTER; cmd[i++] = STLINK_DEBUG_ENTER_SWD; - size = send_only(slu, 1, cmd, slu->cmd_len); + + if (rep_len == 0) { + size = send_only(slu, 1, cmd, slu->cmd_len); + } else { + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + } if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_ENTER\n"); - return (int) size; + printf("[!] send_recv STLINK_DEBUG_ENTER\n"); + return (int) size; } return 0; @@ -466,9 +532,8 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { ssize_t size; int rep_len = 2; int i; - // clock speed only supported by stlink/v2 and for firmware >= 22 - if (sl->version.stlink_v >= 2 && sl->version.jtag_v >= 22) { + if (sl->version.stlink_v == 2 && sl->version.jtag_v >= 22) { i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; @@ -483,9 +548,55 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { } return 0; - } else { - return -1; + } else if (sl->version.stlink_v == 3) { + int speed_index; + uint32_t map[STLINK_V3_MAX_FREQ_NB]; + i = fill_command(sl, SG_DXFER_FROM_DEV, 16); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_APIV3_GET_COM_FREQ; + cmd[i++] = 0; // SWD mode + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, 52); + if (size == -1) { + printf("[!] send_recv STLINK_APIV3_GET_COM_FREQ\n"); + return (int) size; + } + + int speeds_size = data[8]; + + if (speeds_size > STLINK_V3_MAX_FREQ_NB) + speeds_size = STLINK_V3_MAX_FREQ_NB; + + for (i = 0; i < speeds_size; i++) + map[i] = le_to_h_u32(&data[12 + 4 * i]); + + /* set to zero all the next entries */ + for (i = speeds_size; i < STLINK_V3_MAX_FREQ_NB; i++) + map[i] = 0; + + speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), 1800); + + i = fill_command(sl, SG_DXFER_FROM_DEV, 16); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_APIV3_SET_COM_FREQ; + cmd[i++] = 0; // SWD mode + cmd[i++] = 0; + cmd[i++] = (uint8_t)((map[speed_index] >> 0) & 0xFF); + cmd[i++] = (uint8_t)((map[speed_index] >> 8) & 0xFF); + cmd[i++] = (uint8_t)((map[speed_index] >> 16) & 0xFF); + cmd[i++] = (uint8_t)((map[speed_index] >> 24) & 0xFF); + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8); + if (size == -1) { + printf("[!] send_recv STLINK_APIV3_SET_COM_FREQ\n"); + return (int) size; + } + + return 0; } + return -1; } int _stlink_usb_exit_debug_mode(stlink_t *sl) { @@ -827,34 +938,49 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST } } - if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) || - (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) || - (desc.idProduct == STLINK_USB_PID_STLINK_NO_UMS) || - (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO)) { + if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) || + (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) || + (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO) || + (desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER) || + (desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID) || + (desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID) || + (desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID)) { struct libusb_device_handle *handle; ret = libusb_open(list[cnt], &handle); if (ret) - continue; + continue; sl->serial_size = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial)); libusb_close(handle); + if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) + || (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) + || (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO)) { + sl->version.stlink_v = 2; + } else if ((desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER) + || (desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID) + || (desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID) + || (desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID)) { + sl->version.stlink_v = 3; + } + if ((serial == NULL) || (*serial == 0)) - break; + break; if (sl->serial_size < 0) - continue; + continue; if (memcmp(serial, &sl->serial, sl->serial_size) == 0) - break; + break; continue; } if (desc.idProduct == STLINK_USB_PID_STLINK) { slu->protocoll = 1; + sl->version.stlink_v = 1; break; } } @@ -904,7 +1030,12 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST // TODO - could use the scanning techniq from stm8 code here... slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; - if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO || desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO || desc.idProduct == STLINK_USB_PID_STLINK_NO_UMS) { + if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO || + desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO || + desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER || + desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID || + desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID || + desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID) { slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; } else { slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; @@ -914,21 +1045,23 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST // TODO - never used at the moment, always CMD_SIZE slu->cmd_len = (slu->protocoll == 1)? STLINK_SG_SIZE: STLINK_CMD_SIZE; + // Initialize stlink version (sl->version) + stlink_version(sl); + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { ILOG("-- exit_dfu_mode\n"); stlink_exit_dfu_mode(sl); } + // set the speed before entering the mode + // as the chip discovery phase should be done at this speed too + // Set the stlink clock speed (default is 1800kHz) + stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { - stlink_enter_swd_mode(sl); + stlink_enter_swd_mode(sl); } - - // Initialize stlink version (sl->version) - stlink_version(sl); - // Set the stlink clock speed (default is 1800kHz) - stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); - if (reset) { if( sl->version.stlink_v > 1 ) stlink_jtag_reset(sl, 2); stlink_reset(sl); @@ -976,9 +1109,12 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { } if (desc.idProduct != STLINK_USB_PID_STLINK_32L && - desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && - desc.idProduct != STLINK_USB_PID_STLINK_NO_UMS && - desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO) + desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && + desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO && + desc.idProduct != STLINK_USB_PID_STLINK_V3_USBLOADER && + desc.idProduct != STLINK_USB_PID_STLINK_V3E_PID && + desc.idProduct != STLINK_USB_PID_STLINK_V3S_PID && + desc.idProduct != STLINK_USB_PID_STLINK_V3_2VCP_PID) continue; slcnt++; @@ -1001,9 +1137,8 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { break; } - if (desc.idProduct != STLINK_USB_PID_STLINK_32L && - desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && - desc.idProduct != STLINK_USB_PID_STLINK_NO_UMS && + if (desc.idProduct != STLINK_USB_PID_STLINK_32L && + desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO) continue; @@ -1024,7 +1159,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { libusb_close(handle); stlink_t *sl = NULL; - sl = stlink_open_usb(0, 1, serial); + sl = stlink_open_usb(0, 1, serial); if (!sl) continue; diff --git a/stlinkv1_macosx_driver/README.md b/stlinkv1_macosx_driver/README.md index 4e6b8c6a0..b2a68442c 100644 --- a/stlinkv1_macosx_driver/README.md +++ b/stlinkv1_macosx_driver/README.md @@ -4,18 +4,14 @@ to: texane@gmail.com Hi, -i managed to get the stlink v1 working under os x and i would like to share the solution so maybe you can -add it in your package. +i managed to get the stlink v1 working under os x and i would like to share the solution so maybe you can add it in your package. The problem is that os x claims the device as scsi and libusb won't be able to connect to it. -I've created what is called a codeless driver which claims the device and has a higher priority then the -default apple mass storage driver, so the device can be accessed through libusb. +I've created what is called a codeless driver which claims the device and has a higher priority then the default apple mass storage driver, so the device can be accessed through libusb. -I tested this codeless driver under OS X 10.6.8 and 10.7.2. I assume it works with any 10.6.x and 10.7.x -version as well. +I tested this codeless driver under OS X 10.6.8 and 10.7.2. +I assume it works with any 10.6.x and 10.7.x version as well. -Attached to this mail you'll find the osx folder with the source code of the driver, both drivers (for -10.6.x and 10.7.x), an install.sh script and the modified Makefile, i only added a line at the end which -invoke the `install.sh`. +Attached to this mail you'll find the osx folder with the source code of the driver, both drivers (for 10.6.x and 10.7.x), an install.sh script and the modified Makefile, i only added a line at the end which invoke the `install.sh`. First, unpack the `osx.tar.gz` contents: ```bash @@ -41,13 +37,11 @@ P.S. If error `OS X version not supported` occurs. For the latest versions of Ma For OS X 10.10 Yosemite you must force the system to load unsigned kernelextensions ```bash -sudo nvram boot-args="kext-dev-mode=1“ +sudo nvram boot-args="kext-dev-mode=1" ``` reboot the system! ### OS X 10.11 El Capitan -(Update from another user) - For OS X 10.11 El Capitan: the Yosemite kext seems to work (tested on 10.11.04). From 14c2cbe0c6e15429fb8f02919c94ed976fbf371e Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 25 Feb 2020 22:08:24 +0000 Subject: [PATCH 0711/1435] Bump Standards-Version to 4.5.0, no changes. --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index c541d5bef..4382cdcd5 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: stlink Priority: optional Maintainer: Luca Boccassi Build-Depends: debhelper (>= 9), cmake, libusb-1.0-0-dev, libgtk-3-dev -Standards-Version: 4.4.0 +Standards-Version: 4.5.0 Rules-Requires-Root: no Section: electronics Homepage: https://github.com/texane/stlink From d3021e569f2a151ba415d75a8984db17307b1170 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 25 Feb 2020 22:10:41 +0000 Subject: [PATCH 0712/1435] Add d/s/options to ignore repacked files Gbp-Dch: ignore --- debian/source/options | 1 + 1 file changed, 1 insertion(+) create mode 100644 debian/source/options diff --git a/debian/source/options b/debian/source/options new file mode 100644 index 000000000..7022977a9 --- /dev/null +++ b/debian/source/options @@ -0,0 +1 @@ +extend-diff-ignore=stlinkv1_macosx_driver From 00441133fa59e09ac8da87d25ee2bdabb2c6e720 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 25 Feb 2020 22:13:51 +0000 Subject: [PATCH 0713/1435] Update libstlink1 symbols file for 1.6.0. --- debian/libstlink1.symbols | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/debian/libstlink1.symbols b/debian/libstlink1.symbols index 51fa9bdb1..4518989a1 100644 --- a/debian/libstlink1.symbols +++ b/debian/libstlink1.symbols @@ -78,6 +78,8 @@ libstlink.so.1 libstlink1 #MINVER# stlink_force_debug@Base 1.5.0 stlink_fread@Base 1.5.0 stlink_fwrite_flash@Base 1.5.0 + stlink_fwrite_option_bytes@Base 1.6.0 + stlink_fwrite_option_bytes_32bit@Base 1.6.0 stlink_fwrite_sram@Base 1.5.0 stlink_get_erased_pattern@Base 1.5.0 stlink_is_core_halted@Base 1.5.0 @@ -95,6 +97,8 @@ libstlink.so.1 libstlink1 #MINVER# stlink_read_all_unsupported_regs@Base 1.5.0 stlink_read_debug32@Base 1.5.0 stlink_read_mem32@Base 1.5.0 + stlink_read_option_bytes_f2@Base 1.6.0 + stlink_read_option_bytes_f4@Base 1.6.0 stlink_read_reg@Base 1.5.0 stlink_read_unsupported_reg@Base 1.5.0 stlink_reset@Base 1.5.0 @@ -115,6 +119,7 @@ libstlink.so.1 libstlink1 #MINVER# stlink_write_flash@Base 1.5.0 stlink_write_mem32@Base 1.5.0 stlink_write_mem8@Base 1.5.0 + stlink_write_option_bytes@Base 1.6.0 stlink_write_reg@Base 1.5.0 stlink_write_unsupported_reg@Base 1.5.0 stm32l1_write_half_pages@Base 1.5.0 From f92878df5e2761cf38fc4719b18e288a0a1fa61e Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 25 Feb 2020 22:08:48 +0000 Subject: [PATCH 0714/1435] Update changelog for 1.6.0+ds-1 release --- debian/changelog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/debian/changelog b/debian/changelog index 5d132ca55..0ad68fed3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +stlink (1.6.0+ds-1) unstable; urgency=medium + + * Merge tag 'v1.6.0' into debian + * Bump Standards-Version to 4.5.0, no changes. + * Update libstlink1 symbols file for 1.6.0. + + -- Luca Boccassi Tue, 25 Feb 2020 22:08:33 +0000 + stlink (1.5.1+ds-2) unstable; urgency=medium * Mark library packages as Multi-Arch: same. From 2f9748e52f4739354668bc77bd208ca471cc528b Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 26 Feb 2020 20:32:55 +0100 Subject: [PATCH 0715/1435] General Project Update - Fixes in CHANGELOG.md - Added note in README.md - Updated package requirements. --- CHANGELOG.md | 12 +++++++----- README.md | 2 +- doc/compiling.md | 15 ++++++++------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10f12f81b..2832464a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ Major changes and added features: Updates and fixes: +* Build failure when platform is 32 bit, but stuct stat.st_size is 64 bit. ([#629](https://github.com/texane/stlink/pull/629)) * Made udev rules and modprobe conf installation optional ([#741](https://github.com/texane/stlink/pull/741)) * Fixed case when __FILE__ don't contain "/" nor "\\". ([#745](https://github.com/texane/stlink/pull/745)) * Fixed double dash issue in doc/man ([#746](https://github.com/texane/stlink/pull/746)) @@ -33,7 +34,7 @@ Updates and fixes: * Only do bank calculation on STM32L4 devices with dual banked flash ([#751](https://github.com/texane/stlink/pull/751)) * Updated STM32F3xx chip ID that covers a few different devices ([#758](https://github.com/texane/stlink/pull/758)) * Fixed versioning when compiling from the checked out git-repo ([#762](https://github.com/texane/stlink/pull/762)) -* Fixed "unkown chip id", piped output and st-util -v ([#763](https://github.com/texane/stlink/pull/763)) +* Fixed "unkown chip id", piped output and st-util -v ([#107](https://github.com/texane/stlink/pull/107), [#763](https://github.com/texane/stlink/pull/763)) * win32: move usleep definition to unistd.h ([#765](https://github.com/texane/stlink/pull/765)) * Fixed relative path to the UI files needed by stlink-gui-local (GUI) ([#770](https://github.com/texane/stlink/pull/770), [#771](https://github.com/texane/stlink/pull/771)) * Fixed package name "devscripts" in doc/compiling.md ([#775](https://github.com/texane/stlink/pull/775)) @@ -149,10 +150,10 @@ Release date: 2017-01-28 Major changes and added features: -* Deprecation of autotools (autoconf, automake) (@xor-gate) +* Deprecation of autotools (autoconf, automake) ([#83](https://github.com/texane/stlink/pull/83), [#431](https://github.com/texane/stlink/pull/431), [#434](https://github.com/texane/stlink/pull/434)) * Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#3fd0f09](https://github.com/texane/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) * Added support for native debian packaging ([#444](https://github.com/texane/stlink/pull/444), [#485](https://github.com/texane/stlink/pull/485)) -* Added intel hex file reading for `st-flash` ([#459](https://github.com/texane/stlink/pull/541)) +* Added intel hex file reading for `st-flash` ([#110](https://github.com/texane/stlink/pull/110), [#157](https://github.com/texane/stlink/pull/157), [#200](https://github.com/texane/stlink/pull/200), [#239](https://github.com/texane/stlink/pull/239), [#457](https://github.com/texane/stlink/pull/547), [#459](https://github.com/texane/stlink/pull/549)) * Added `--reset` command to `st-flash` ([#505](https://github.com/texane/stlink/pull/505)) * Support serial numbers argument for `st-util` and `st-flash` for multi-programmer setups ([#541](https://github.com/texane/stlink/pull/541)) * Added kill ('k') command to gdb-server for `st-util` ([#9804416](https://github.com/texane/stlink/commit/98044163ab34bf5159f121d1c49ffb3550321ca0)) @@ -171,14 +172,15 @@ Chip support added for: Updates and fixes: +* Set SWDCLK and fixed jtag_reset bug ([#254](https://github.com/texane/stlink/pull/254), [#291](https://github.com/texane/stlink/pull/291), [#475](https://github.com/texane/stlink/pull/475), [#533](https://github.com/texane/stlink/pull/533), [#534](https://github.com/texane/stlink/pull/534)) * Fixed STM32F030 erase error ([#442](https://github.com/texane/stlink/pull/442)) * Fixed Cygwin build ([#68b0f3b](https://github.com/texane/stlink/commit/68b0f3bddc3c4aaffe34caa6a3201029edd8ad56)) * Reset flash mass erase (MER) bit after mass erase for safety ([#489](https://github.com/texane/stlink/pull/489)) * Fixed memory map for STM32F4 (@zulusw) -* Fixed STM32L-problem with flash loader (issue #390) (Tom de Boer) +* Fixed STM32L-problem with flash loader ([#390](https://github.com/texane/stlink/pull/390)) * `st-util` don't read target voltage on startup as it crashes STM32F100 (probably stlink/v1) (Greg Alexander) * Do a JTAG reset prior to reading CPU information when processor is in deep sleep (@andyg24) -* Redesign of `st-flash` commandline options parsing (pull-request #459) (@dev26th) +* Redesign of `st-flash` commandline options parsing ([#459](https://github.com/texane/stlink/pull/459)) v1.2.0 ====== diff --git a/README.md b/README.md index 594e0fae9..df7fbfc05 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ When there is no executable available for your platform or you need the latest ( * The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) * Before creating a pull request, please _ALWAYS_ open a new issue for the discussion of the intended new features. Bugfixes don't require a discussion via a ticket-issue. However they should always be described in a few words as soon as they appear to help others as well. * Contributors and/or maintainers may submit comments or request changes to patch-proposals and/or pull-requests. - +* Please start new forks from the develop branch if possible as pull requests will go into this branch as well. ## License diff --git a/doc/compiling.md b/doc/compiling.md index 555dce487..61bb12e6e 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -1,10 +1,11 @@ -# Compiling +# Compiling from sources -## Build from sources +## Package requirements -* CMake (minimal v2.8.7) -* C compiler (gcc, clang, mingw) -* Libusb 1.0 (minimal v1.0.9) +* CMake (v2.8.7 or later) +* C compiler (gcc, clang or mingw) +* libusb 1.0 (v1.0.13 or later) +* libusb-dev 1.0 (v1.0.13 or later) * (optional) pandoc for generating manpages from markdown Run from the root of the source directory: @@ -127,7 +128,7 @@ you can use the following cmake option: $ cmake -DLIB_INSTALL_DIR:PATH="/usr/lib64" .. ``` -## Windows (MinGW64) +## Windows (MinGW64) ### Prequistes @@ -149,7 +150,7 @@ Check and execute (in the script folder) `\scripts\mingw64-build.bat NOTE: when installing different toolchains make sure you edit the path in the `mingw64-build.bat` the build script uses currently `C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin` -## Windows (Visual Studio) +## Windows (Visual Studio) ### Prerequisites From f5d0454ab0a18f209ad5b7d0d51f3945b27dd892 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 27 Feb 2020 01:56:59 +0100 Subject: [PATCH 0716/1435] Hotfix: Reverts commit 6692fdc. CKS32-Clone-Patch broke flashing on STM32 F3xx, F4xx and L1xx. (#761) --- include/stm32.h | 1 - src/flash_loader.c | 1 - 2 files changed, 2 deletions(-) diff --git a/include/stm32.h b/include/stm32.h index 858d2b22a..9a01baaf4 100644 --- a/include/stm32.h +++ b/include/stm32.h @@ -9,7 +9,6 @@ // cortex core ids #define STM32VL_CORE_ID 0x1ba01477 -#define CS32VL_CORE_ID 0x2ba01477 #define STM32F7_CORE_ID 0x5ba02477 // Constant STM32 memory map figures diff --git a/src/flash_loader.c b/src/flash_loader.c index 9f6e3a79d..f88a42eca 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -267,7 +267,6 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || - sl->core_id == CS32VL_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_F3 || sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL || From 83a31a09b358021a3b6b65962f7ea4c6550f0289 Mon Sep 17 00:00:00 2001 From: Slyshyk Oleksiy Date: Sat, 29 Feb 2020 16:23:22 +0200 Subject: [PATCH 0717/1435] Add win32 travis build (#2) * add mingw64 build to travis CI * Make .travis-lin-mingw.sh executable * .travis-lin-mingw.sh: make build dir * show $PWD in travis-lin-mingw * update .travis-lin-mingw.sh * --- * update .travis-lin-mingw.sh * update p7zip cmd * fix sign/unsign comparioson in usb.c * revert call .travis.sh * clean up .travis-lin-mingw.sh --- .travis-lin-mingw.sh | 14 ++++++++++++++ .travis.yml | 3 +++ cmake/modules/FindLibUSB.cmake | 3 ++- src/usb.c | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100755 .travis-lin-mingw.sh diff --git a/.travis-lin-mingw.sh b/.travis-lin-mingw.sh new file mode 100755 index 000000000..0422a06f6 --- /dev/null +++ b/.travis-lin-mingw.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DIR=$PWD + +if [ "$TRAVIS_OS_NAME" == "linux" ]; then + echo "WORK DIR:$DIR" + mkdir -p $DIR/build/linux-mingw32-release + cd $DIR/build/linux-mingw32-release + echo "cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR" + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR + echo "make" + make +fi + diff --git a/.travis.yml b/.travis.yml index b0f985012..b1832d57f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,9 +18,12 @@ addons: - g++-6 - gcc-6 - libusb-1.0.0-dev + - p7zip + - mingw-w64 script: - git fetch --tags - printenv - cmake --version - ./.travis.sh + - ./.travis-lin-mingw.sh diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index 5233e489d..2ad35b3d8 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -84,7 +84,8 @@ if(NOT LIBUSB_FOUND) file(MAKE_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) if(${ZIP_EXECUTABLE} MATCHES "p7zip") - execute_process(COMMAND ${ZIP_EXECUTABLE} -d --keep -f ${LIBUSB_WIN_ARCHIVE_PATH} WORKING_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) + #execute_process(COMMAND ${ZIP_EXECUTABLE} -d --keep -f ${LIBUSB_WIN_ARCHIVE_PATH} WORKING_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) + execute_process(COMMAND ${ZIP_EXECUTABLE} -d ${LIBUSB_WIN_ARCHIVE_PATH} WORKING_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) else() execute_process(COMMAND ${ZIP_EXECUTABLE} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER}) endif() diff --git a/src/usb.c b/src/usb.c index 9df9d7296..81bd7ae2c 100644 --- a/src/usb.c +++ b/src/usb.c @@ -189,7 +189,7 @@ int _stlink_usb_version(stlink_t *sl) { cmd[i++] = STLINK_APIV3_GET_VERSION_EX; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); - if (size != rep_len) { + if (size != (ssize_t)rep_len) { printf("[!] send_recv STLINK_APIV3_GET_VERSION_EX\n"); return (int) size; } From 4d55b6b3bf2bfecab3251fbe966c86eaad4e027a Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sun, 1 Mar 2020 18:47:59 +0200 Subject: [PATCH 0718/1435] make Version.cmake more error-resistant. fix #772 --- cmake/Version.cmake | 103 +++++++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 34 deletions(-) diff --git a/cmake/Version.cmake b/cmake/Version.cmake index e74d775d6..e5ce9f4c6 100644 --- a/cmake/Version.cmake +++ b/cmake/Version.cmake @@ -1,7 +1,11 @@ # Determine project version # * Using Git # * Local .version file -find_package (Git QUIET) + +set(__detect_version 0) + +find_package (Git) + if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") # Working off a git repo, using git versioning # Check if HEAD is pointing to a tag @@ -9,43 +13,74 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") COMMAND "${GIT_EXECUTABLE}" describe --always --tag WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" OUTPUT_VARIABLE PROJECT_VERSION + RESULT_VARIABLE GIT_DESCRIBE_RESULT + ERROR_VARIABLE GIT_DESCRIBE_ERROR OUTPUT_STRIP_TRAILING_WHITESPACE) - # If the sources have been changed locally, add -dirty to the version. - execute_process ( - COMMAND "${GIT_EXECUTABLE}" diff --quiet - WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" - RESULT_VARIABLE res) - - if (res EQUAL 1) - set (PROJECT_VERSION "${PROJECT_VERSION}-dirty") - endif() - - # strip a leading v off of the version as proceeding code expectes just the version numbering. - string(REGEX REPLACE "^v" "" PROJECT_VERSION ${PROJECT_VERSION}) - - string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" - "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) - list(LENGTH PROJECT_VERSION_LIST len) - if(len EQUAL 3) - list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) - list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) - list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) - endif() -elseif(EXISTS ${PROJECT_SOURCE_DIR}/.version) - # If git is not available (e.g. when building from source package) - # we can extract the package version from .version file. - file (STRINGS .version PROJECT_VERSION) - - # TODO create function to extract semver from file or string and check if it is correct instead of copy-pasting - string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" - "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) - list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) - list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) - list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) + if(GIT_DESCRIBE_RESULT EQUAL 0) + # If the sources have been changed locally, add -dirty to the version. + execute_process ( + COMMAND "${GIT_EXECUTABLE}" diff --quiet + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + RESULT_VARIABLE res) + + if (res EQUAL 1) + set (PROJECT_VERSION "${PROJECT_VERSION}-dirty") + endif() + + # strip a leading v off of the version as proceeding code expectes just the version numbering. + string(REGEX REPLACE "^v" "" PROJECT_VERSION ${PROJECT_VERSION}) + + string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" + "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) + list(LENGTH PROJECT_VERSION_LIST len) + if(len EQUAL 3) + list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) + list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) + list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) + set(__detect_version 1) + else() + message(STATUS "Fail to extract version's parts from \"${PROJECT_VERSION}\"") + endif() + + else(GIT_DESCRIBE_RESULT EQUAL 0) + message(WARNING "git describe failed.") + message(WARNING "${GIT_DESCRIBE_ERROR}") + endif(GIT_DESCRIBE_RESULT EQUAL 0) else() - message(FATAL_ERROR "Unable to determine project version") + message(STATUS "Git or repo not found.") endif() + + +if(NOT __detect_version) + message(STATUS "Try to detect version from \"${PROJECT_SOURCE_DIR}/.version\" file.") + if(EXISTS ${PROJECT_SOURCE_DIR}/.version) + # If git is not available (e.g. when building from source package) + # we can extract the package version from .version file. + file (STRINGS .version PROJECT_VERSION) + + # TODO create function to extract semver from file or string and check if it is correct instead of copy-pasting + string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" + "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) + list(LENGTH PROJECT_VERSION_LIST len) + if(len EQUAL 3) + list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) + list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) + list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) + set(__detect_version 1) + else() + message(STATUS "Fail to extract version's parts from \"${PROJECT_VERSION}\"") + endif() + else() + message(STATUS "File \"${PROJECT_SOURCE_DIR}/.version\" did not exists.") + endif() +endif() + +if(NOT __detect_version) + message(FATAL_ERROR "Unable to determine project version") +endif() + + message(STATUS "stlink version: ${PROJECT_VERSION}") message(STATUS " Major ${PROJECT_VERSION_MAJOR} Minor ${PROJECT_VERSION_MINOR} Patch ${PROJECT_VERSION_PATCH}") From ecf86c735bdcdb82b098de52b5656c0d8ca94302 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sun, 1 Mar 2020 22:39:43 +0200 Subject: [PATCH 0719/1435] compare git version with .version --- .version | 2 +- cmake/Version.cmake | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.version b/.version index dc1e644a1..ce6a70b9d 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.6.0 +1.6.0 \ No newline at end of file diff --git a/cmake/Version.cmake b/cmake/Version.cmake index e5ce9f4c6..2ca1c0ff8 100644 --- a/cmake/Version.cmake +++ b/cmake/Version.cmake @@ -39,6 +39,15 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) set(__detect_version 1) + set(__version_str "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") + if(EXISTS "${PROJECT_SOURCE_DIR}/.version") + file(READ "${PROJECT_SOURCE_DIR}/.version" __version_file) + if(NOT __version_str STREQUAL __version_file) + message(STATUS "Rewrite ${PROJECT_SOURCE_DIR}/.version with ${__version_str}") + endif() + else() + file(WRITE "${PROJECT_SOURCE_DIR}/.version" ${__version_str}) + endif() else() message(STATUS "Fail to extract version's parts from \"${PROJECT_VERSION}\"") endif() From 268313bcabec25086eb7be51abd0012722bd0d48 Mon Sep 17 00:00:00 2001 From: Lutz Freitag Date: Sun, 15 Mar 2020 11:19:03 +0100 Subject: [PATCH 0720/1435] clear the PG bit before setting the PER bit after the flash loader ran the PG bit is still set in the CR register. in order to program the next page that page needs to be erased first and to get that working the PG bit has to be cleared so the flash controller knows what to do. this fixes #579 --- src/common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common.c b/src/common.c index 6226c893b..95e504f9e 100644 --- a/src/common.c +++ b/src/common.c @@ -1893,6 +1893,9 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) /* unlock if locked */ unlock_flash_if(sl); + /* clear the pg bit */ + clear_flash_cr_pg(sl); + /* set the page erase bit */ set_flash_cr_per(sl); From b40c2436b68a35544a1eae10f4b6a3de7648a566 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 27 Feb 2020 01:56:59 +0100 Subject: [PATCH 0721/1435] Hotfix: Reverts commit 6692fdc. CKS32-Clone-Patch broke flashing on STM32 F3xx, F4xx and L1xx. (#761) --- include/stm32.h | 1 - src/flash_loader.c | 1 - 2 files changed, 2 deletions(-) diff --git a/include/stm32.h b/include/stm32.h index 858d2b22a..9a01baaf4 100644 --- a/include/stm32.h +++ b/include/stm32.h @@ -9,7 +9,6 @@ // cortex core ids #define STM32VL_CORE_ID 0x1ba01477 -#define CS32VL_CORE_ID 0x2ba01477 #define STM32F7_CORE_ID 0x5ba02477 // Constant STM32 memory map figures diff --git a/src/flash_loader.c b/src/flash_loader.c index 9f6e3a79d..f88a42eca 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -267,7 +267,6 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || - sl->core_id == CS32VL_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_F3 || sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL || From 01ab4a979102d4812d11d037ec0041cdcce981b1 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 16 Mar 2020 12:15:23 +0100 Subject: [PATCH 0722/1435] Merged PR #825 Added support for G031/G041 chips. Closes #825. --- src/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 6226c893b..0b80035f4 100644 --- a/src/common.c +++ b/src/common.c @@ -2637,7 +2637,7 @@ static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t l /* Check if chip is supported and for correct address */ if(sl->chip_id != STLINK_CHIPID_STM32_G0_CAT1 && - sl->chip_id != STLINK_CHIPID_STM32_G0_CAT2) { + sl->chip_id != STLINK_CHIPID_STM32_G0_CAT2) { ELOG("Option bytes writing is currently only supported for the STM32G0\n"); return -1; } From 5e70eb3dae66046d5e7b8a7e433480ed5e06c46f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 16 Mar 2020 12:57:38 +0100 Subject: [PATCH 0723/1435] Removed duplicated chip IDs. --- include/stlink/chipid.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index c0b0f3e13..368e157a7 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -75,8 +75,6 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_G4_CAT2 = 0x468, // See: RM 0440 s46.6.1 "MCU device ID code". STLINK_CHIPID_STM32_G4_CAT3 = 0x469, STLINK_CHIPID_STM32_L4RX = 0x470, // taken from the STM32L4R9I-DISCO board - STLINK_CHIPID_STM32_G0_CAT1 = 0x466, // G031/041 - STLINK_CHIPID_STM32_G0_CAT2 = 0x460, // G071/081 STLINK_CHIPID_STM32_WB55 = 0x495 }; From 1873ec70ffeb997ad355561070c87b270d31e674 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 16 Mar 2020 13:34:17 +0100 Subject: [PATCH 0724/1435] Removed duplicated chip IDs. --- include/stlink/chipid.h | 6 ++---- src/chipid.c | 13 +------------ 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index be5836990..f179db779 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -69,14 +69,12 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F72XXX = 0x452, /* This ID is found on the NucleoF722ZE board */ STLINK_CHIPID_STM32_L011 = 0x457, STLINK_CHIPID_STM32_F410 = 0x458, - STLINK_CHIPID_STM32_G0_CAT2 = 0x460, // G071/081 + STLINK_CHIPID_STM32_G0_CAT2 = 0x460, // G070/G071/081 STLINK_CHIPID_STM32_F413 = 0x463, - STLINK_CHIPID_STM32_G0_CAT1 = 0x466, // G031/041 + STLINK_CHIPID_STM32_G0_CAT1 = 0x466, // G030/G031/041 STLINK_CHIPID_STM32_G4_CAT2 = 0x468, // See: RM 0440 s46.6.1 "MCU device ID code". STLINK_CHIPID_STM32_G4_CAT3 = 0x469, STLINK_CHIPID_STM32_L4RX = 0x470, // taken from the STM32L4R9I-DISCO board - STLINK_CHIPID_STM32_G07X = 0x460, // Actually, 'G070 and 'G071/081 - STLINK_CHIPID_STM32_G03X = 0x466, // Actually, 'G030 and 'G031/041 STLINK_CHIPID_STM32_WB55 = 0x495 }; diff --git a/src/chipid.c b/src/chipid.c index f595a7bf3..a978d91ef 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -522,7 +522,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x2000 }, { - // STM32GG030/031/041 (from RM0444) + // STM32G030/031/041 (from RM0454 & RM0444) .chip_id = STLINK_CHIPID_STM32_G0_CAT1, .description = "G030/G031/G041 device", .flash_type = STLINK_FLASH_TYPE_G0, @@ -554,17 +554,6 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7000 // 28K (table 2) }, - { - // STM32G031/041 (from RM0454 & RM0444) - .chip_id = STLINK_CHIPID_STM32_G03X, - .description = "G030/G031/G041 device", - .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2K (sec 3.2) - .sram_size = 0x2000, // 8K (sec 2.3) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x2000 // 8k (table 2) - }, { // STM32WB55 (from RM0434) .chip_id = STLINK_CHIPID_STM32_WB55, From 44e2c375766f71f9a051ffaa5f2ba5b68af2ad86 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 16 Mar 2020 19:01:19 +0100 Subject: [PATCH 0725/1435] Whitespace cleanup. --- src/sg.c | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/src/sg.c b/src/sg.c index e7ff5d14e..8fa351cf6 100644 --- a/src/sg.c +++ b/src/sg.c @@ -109,8 +109,7 @@ void _stlink_sg_close(stlink_t *sl) { } } -static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t endpoint, uint32_t *tag) -{ +static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t endpoint, uint32_t *tag) { unsigned char csw[13]; memset(csw, 0, sizeof(csw)); int transferred; @@ -229,9 +228,7 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint * @param endpoint_in * @param endpoint_out */ - static void -get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out) -{ +static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out) { DLOG("Fetching sense...\n"); uint8_t cdb[16]; memset(cdb, 0, sizeof(cdb)); @@ -324,7 +321,6 @@ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, return real_transferred; } - int stlink_q(stlink_t *sl) { struct stlink_libsg* sg = sl->backend_data; //uint8_t cdb_len = 6; // FIXME varies!!! @@ -385,7 +381,6 @@ int stlink_q(stlink_t *sl) { } // TODO thinking, cleanup - void stlink_stat(stlink_t *stl, char *txt) { if (stl->q_len <= 0) return; @@ -404,7 +399,6 @@ void stlink_stat(stlink_t *stl, char *txt) { } } - int _stlink_sg_version(stlink_t *stl) { struct stlink_libsg *sl = stl->backend_data; clear_cdb(sl); @@ -417,7 +411,6 @@ int _stlink_sg_version(stlink_t *stl) { // Get stlink mode: // STLINK_DEV_DFU_MODE || STLINK_DEV_MASS_MODE || STLINK_DEV_DEBUG_MODE // usb dfu || usb mass || jtag or swd - int _stlink_sg_current_mode(stlink_t *stl) { struct stlink_libsg *sl = stl->backend_data; clear_cdb(sl); @@ -431,7 +424,6 @@ int _stlink_sg_current_mode(stlink_t *stl) { } // Exit the mass mode and enter the swd debug mode. - int _stlink_sg_enter_swd_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -443,7 +435,6 @@ int _stlink_sg_enter_swd_mode(stlink_t *sl) { // Exit the mass mode and enter the jtag debug mode. // (jtag is disabled in the discovery's stlink firmware) - int _stlink_sg_enter_jtag_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_enter_jtag_mode ***\n"); @@ -525,7 +516,6 @@ int _stlink_sg_core_id(stlink_t *sl) { } // Arm-core reset -> halted state. - int _stlink_sg_reset(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -545,7 +535,6 @@ int _stlink_sg_reset(stlink_t *sl) { } // Arm-core reset -> halted state. - int _stlink_sg_jtag_reset(stlink_t *sl, int value) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -562,7 +551,6 @@ int _stlink_sg_jtag_reset(stlink_t *sl, int value) { } // Arm-core status: halted or running. - int _stlink_sg_status(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -573,7 +561,6 @@ int _stlink_sg_status(stlink_t *sl) { } // Force the core into the debug mode -> halted state. - int _stlink_sg_force_debug(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -588,7 +575,6 @@ int _stlink_sg_force_debug(stlink_t *sl) { } // Read all arm-core registers. - int _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { struct stlink_libsg *sg = sl->backend_data; @@ -696,7 +682,6 @@ int _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) { // Write a register of the debug module of the core. // XXX ?(atomic writes) // TODO test - void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_write_dreg ***\n"); @@ -713,7 +698,6 @@ void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { } // Force the core exit the debug mode. - int _stlink_sg_run(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -729,7 +713,6 @@ int _stlink_sg_run(stlink_t *sl) { } // Step the arm-core. - int _stlink_sg_step(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -764,7 +747,6 @@ void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) { } // TODO test - // TODO make delegate! void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) { struct stlink_libsg *sg = sl->backend_data; @@ -779,7 +761,6 @@ void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) { } // Read a "len" bytes to the sl->q_buf from the memory, max 6kB (6144 bytes) - int _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -804,7 +785,6 @@ int _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { } // Write a "len" bytes from the sl->q_buf to the memory, max 64 Bytes. - int _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; int ret; @@ -833,7 +813,6 @@ int _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { } // Write a "len" bytes from the sl->q_buf to the memory, max Q_BUF_LEN bytes. - int _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; int ret; @@ -862,7 +841,6 @@ int _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { } // Write one DWORD data to memory - int _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -875,7 +853,6 @@ int _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { } // Read one DWORD data from memory - int _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -891,9 +868,7 @@ int _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { } // Exit the jtag or swd mode and enter the mass mode. - -int _stlink_sg_exit_debug_mode(stlink_t *stl) -{ +int _stlink_sg_exit_debug_mode(stlink_t *stl) { if (stl) { struct stlink_libsg* sl = stl->backend_data; clear_cdb(sl); @@ -905,7 +880,6 @@ int _stlink_sg_exit_debug_mode(stlink_t *stl) return 0; } - // 1) open a sg device, switch the stlink from dfu to mass mode // 2) wait 5s until the kernel driver stops reseting the broken device // 3) reopen the device @@ -943,7 +917,6 @@ static stlink_backend_t _stlink_sg_backend = { }; static stlink_t* stlink_open(const int verbose) { - stlink_t *sl = malloc(sizeof (stlink_t)); struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg)); if (sl == NULL || slsg == NULL) { @@ -965,7 +938,7 @@ static stlink_t* stlink_open(const int verbose) { #if defined (__FreeBSD__) #define LIBUSBX_API_VERSION LIBUSB_API_VERSION -#endif +#endif #if LIBUSBX_API_VERSION < 0x01000106 libusb_set_debug(slsg->libusb_ctx, 3); #else @@ -984,7 +957,6 @@ static stlink_t* stlink_open(const int verbose) { // TODO // Could read the interface config descriptor, and assert lots of the assumptions - // assumption: numInterfaces is always 1... if (libusb_kernel_driver_active(slsg->usb_handle, 0) == 1) { int r = libusb_detach_kernel_driver(slsg->usb_handle, 0); From 946f8638c1e5cf0e0f487c04ab3d1d2e69a70322 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 17 Mar 2020 20:48:45 +0100 Subject: [PATCH 0726/1435] Updated CHANGELOG.md for Release v1.3.0 --- CHANGELOG.md | 57 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2832464a2..022701580 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -117,13 +117,13 @@ Major changes and added features: Updates and fixes: +* Fixed gdb-server: L0xx has no FP_CTRL register for breakpoints ([#273](https://github.com/texane/stlink/pull/273)) * Fixed compilation with GCC 7 ([#590](https://github.com/texane/stlink/pull/590)) * Skipped GTK detection if we're cross-compiling ([#588](https://github.com/texane/stlink/pull/588)) * Fixed possible memory leak ([#570](https://github.com/texane/stlink/pull/570)) * Fixed building with mingw64 ([#569](https://github.com/texane/stlink/pull/569), [#610](https://github.com/texane/stlink/pull/610)) * Updated libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) * Fixed low-voltage flashing on STM32F7 parts. ([#567](https://github.com/texane/stlink/pull/567)) -* Updated libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) v1.3.1 ====== @@ -151,36 +151,48 @@ Release date: 2017-01-28 Major changes and added features: * Deprecation of autotools (autoconf, automake) ([#83](https://github.com/texane/stlink/pull/83), [#431](https://github.com/texane/stlink/pull/431), [#434](https://github.com/texane/stlink/pull/434)) -* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#3fd0f09](https://github.com/texane/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) -* Added support for native debian packaging ([#444](https://github.com/texane/stlink/pull/444), [#485](https://github.com/texane/stlink/pull/485)) * Added intel hex file reading for `st-flash` ([#110](https://github.com/texane/stlink/pull/110), [#157](https://github.com/texane/stlink/pull/157), [#200](https://github.com/texane/stlink/pull/200), [#239](https://github.com/texane/stlink/pull/239), [#457](https://github.com/texane/stlink/pull/547), [#459](https://github.com/texane/stlink/pull/549)) -* Added `--reset` command to `st-flash` ([#505](https://github.com/texane/stlink/pull/505)) -* Support serial numbers argument for `st-util` and `st-flash` for multi-programmer setups ([#541](https://github.com/texane/stlink/pull/541)) -* Added kill ('k') command to gdb-server for `st-util` ([#9804416](https://github.com/texane/stlink/commit/98044163ab34bf5159f121d1c49ffb3550321ca0)) -* Added manpages (generated with pandoc from Markdown) ([#464](https://github.com/texane/stlink/pull/464)) -* Rewritten commandline parsing for `st-flash` ([#459](https://github.com/texane/stlink/pull/459)) +* Added manpages (generated with pandoc from Markdown) ([#208](https://github.com/texane/stlink/pull/208), [#464](https://github.com/texane/stlink/pull/464), [#466](https://github.com/texane/stlink/pull/466), [#467](https://github.com/texane/stlink/pull/467)) +* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#228](https://github.com/texane/stlink/pull/228), ([#507](https://github.com/texane/stlink/pull/507), commit [#2c0ab7f](https://github.com/texane/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) +* Support serial numbers argument for `st-util` and `st-flash` to probe and control multiple connected programmers ([#318](https://github.com/texane/stlink/pull/318), [#398](https://github.com/texane/stlink/pull/398), [#541](https://github.com/texane/stlink/pull/541)) +* Merge st-probe tool into st-info ([#398](https://github.com/texane/stlink/pull/398)) +* Added support for native debian packaging ([#444](https://github.com/texane/stlink/pull/444), [#472](https://github.com/texane/stlink/pull/472), [#473](https://github.com/texane/stlink/pull/473), [#482](https://github.com/texane/stlink/pull/482), [#483](https://github.com/texane/stlink/pull/483), [#484](https://github.com/texane/stlink/pull/484), [#485](https://github.com/texane/stlink/pull/485)) * Added support for ARM semihosting to `st-util` ([#454](https://github.com/texane/stlink/pull/454), [#455](https://github.com/texane/stlink/pull/455)) +* Rewritten commandline parsing for `st-flash` ([#459](https://github.com/texane/stlink/pull/459)) +* Added `--reset` command to `st-flash` ([#505](https://github.com/texane/stlink/pull/505)) +* st-util should detect when USB commands fail ([#525](https://github.com/texane/stlink/pull/525), ([#527](https://github.com/texane/stlink/pull/527), ([#528](https://github.com/texane/stlink/pull/528)) + Chip support added for: -* STM32L432 ([#501](https://github.com/texane/stlink/pull/501)) -* STM32F412 ([#538](https://github.com/texane/stlink/pull/538)) -* STM32F410 ([#9c635e4](https://github.com/texane/stlink/commit/9c635e419deca697ff823000aad2e39d47ec8d6c)) -* Added memory map for STM32F401XE ([#460](https://github.com/texane/stlink/pull/460)) -* L0x Category 5 devices ([#406](https://github.com/texane/stlink/pull/406)) -* Added L0 Category 2 device (chip id: 0x425) ([#72b8e5e](https://github.com/texane/stlink/commit/72b8e5ec87e4fa386a8e94fe68df29467d4354ce)) +* STM32F401XE: Added memory map for device ([#460](https://github.com/texane/stlink/pull/460)) +* STM32F410RBTx ([#418](https://github.com/texane/stlink/pull/418)) +* STM32F412 ([#537](https://github.com/texane/stlink/pull/537), [#538](https://github.com/texane/stlink/pull/538)) +* STM32F7xx ([#324](https://github.com/texane/stlink/pull/324), [#326](https://github.com/texane/stlink/pull/326), [#327](https://github.com/texane/stlink/pull/327), [#337](https://github.com/texane/stlink/pull/337)) +* STM32F767ZI ([#509](https://github.com/texane/stlink/pull/509)) +* STM32L0xx Cat2 devices (chip id: 0x425) ([#414](https://github.com/texane/stlink/pull/414)) +* STM32L0xx Cat5 devices (chip id: 0x447) ([#406](https://github.com/texane/stlink/pull/406)) +* STM32L4xx ([#321](https://github.com/texane/stlink/pull/321)) +* STM32L432 ([#500](https://github.com/texane/stlink/pull/500), [#501](https://github.com/texane/stlink/pull/501)) + Updates and fixes: * Set SWDCLK and fixed jtag_reset bug ([#254](https://github.com/texane/stlink/pull/254), [#291](https://github.com/texane/stlink/pull/291), [#475](https://github.com/texane/stlink/pull/475), [#533](https://github.com/texane/stlink/pull/533), [#534](https://github.com/texane/stlink/pull/534)) -* Fixed STM32F030 erase error ([#442](https://github.com/texane/stlink/pull/442)) -* Fixed Cygwin build ([#68b0f3b](https://github.com/texane/stlink/commit/68b0f3bddc3c4aaffe34caa6a3201029edd8ad56)) -* Reset flash mass erase (MER) bit after mass erase for safety ([#489](https://github.com/texane/stlink/pull/489)) -* Fixed memory map for STM32F4 (@zulusw) +* Fixed "unaligned addr or size" when trying to write a program in RAM ([#323](https://github.com/texane/stlink/pull/323)) +* Fixed flashing on STM32_F3_SMALL ([#325](https://github.com/texane/stlink/pull/325)) * Fixed STM32L-problem with flash loader ([#390](https://github.com/texane/stlink/pull/390)) -* `st-util` don't read target voltage on startup as it crashes STM32F100 (probably stlink/v1) (Greg Alexander) -* Do a JTAG reset prior to reading CPU information when processor is in deep sleep (@andyg24) +* Don't read the target voltage on startup, because it crashes STM32F100 ([#423](https://github.com/texane/stlink/pull/423), [#424](https://github.com/texane/stlink/pull/424)) +* Added a useful error message instead of "[!] send_recv" ([#425](https://github.com/texane/stlink/pull/425), [#426](https://github.com/texane/stlink/pull/426)) +* Do a JTAG reset prior to reading CPU information when processor is in deep sleep ([#428](https://github.com/texane/stlink/pull/428), [#430](https://github.com/texane/stlink/pull/430), [#451](https://github.com/texane/stlink/pull/451)) +* Fixed STM32F030 erase error ([#442](https://github.com/texane/stlink/pull/442)) +* Fixed memory map for STM32F7xx ([#453](https://github.com/texane/stlink/pull/453), [#456](https://github.com/texane/stlink/pull/456)) * Redesign of `st-flash` commandline options parsing ([#459](https://github.com/texane/stlink/pull/459)) +* Fixed Release target to generate the man-pages with pandoc ([#479](https://github.com/texane/stlink/pull/479)) +* Fixed Cygwin build ([#487](https://github.com/texane/stlink/pull/487), ([#506](https://github.com/texane/stlink/pull/506)) +* Reset flash mass erase (MER) bit after mass erase for safety ([#489](https://github.com/texane/stlink/pull/489)) +* Wrong extract command in FindLibUSB.cmake ([#510](https://github.com/texane/stlink/pull/510), [#511](https://github.com/texane/stlink/pull/511)) + v1.2.0 ====== @@ -193,12 +205,9 @@ Features added: * Added stlink usb probe API functions (Jerry Jacobs) * Added parameter to specify one stlink v2 of many (Georg von Zengen) -Changes: - -* Refactoring/fixes of flash loader (Maxime Coquelin) - Updates and fixes: +* Refactoring/fixes of flash loader (Maxime Coquelin) * Synchronized cache for stm32f7 (Tristan Gingold) * Allow flashing of STM32L4 down to 1.71 V (Greg Meiste) * Fix on stm32l4 to clear flash mass erase flags on CR (Bruno Dal Bo) From 35fff921f572d520359c89966dbc0212218b9666 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 18 Mar 2020 00:27:40 +0100 Subject: [PATCH 0727/1435] Updated CHANGELOG.md for Release v1.3.1 --- CHANGELOG.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 022701580..3d453a2d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -132,15 +132,17 @@ Release date: 2017-02-25 Major changes and added features: -* Added preliminary support for STM32L011 to see it after probe (chipid `0x457`) (@xor-gate) -* Stripped full paths to source files in log (commit [#2c0ab7f](https://github.com/texane/stlink/commit/2c0ab7f0eb6cfda5cfbdc08bb9f6760d27c2b667)) -* Added support for STM32F413 target ([#549](https://github.com/texane/stlink/pull/549)) * Added support for Semihosting `SYS_READC` ([#546](https://github.com/texane/stlink/pull/546)) +* Added support for STM32F413 ([#549](https://github.com/texane/stlink/pull/549), [#550](https://github.com/texane/stlink/pull/550)) +* Added preliminary support for STM32L011 to see it after probe (chipid `0x457`) ([#558](https://github.com/texane/stlink/pull/558)) Updates and fixes: -* Updated documentation markdown files -* Compilation fixes ([#552](https://github.com/texane/stlink/pull/552)) +* cmake/CPackConfig.cmake: Fixup OSX zip filename +* Updated source repositories in README.md: Windows, macOS, Alpine Linux +* Stripped full paths to source files in log ([#548](https://github.com/texane/stlink/pull/548)) +* Compilation fixes ([#551](https://github.com/texane/stlink/pull/551), [#552](https://github.com/texane/stlink/pull/552)) +* Fixed incorrect release folder name in docs ([#560](https://github.com/texane/stlink/pull/560)) * Fixed compilation when path includes spaces ([#561](https://github.com/texane/stlink/pull/561)) v1.3.0 @@ -162,7 +164,6 @@ Major changes and added features: * Added `--reset` command to `st-flash` ([#505](https://github.com/texane/stlink/pull/505)) * st-util should detect when USB commands fail ([#525](https://github.com/texane/stlink/pull/525), ([#527](https://github.com/texane/stlink/pull/527), ([#528](https://github.com/texane/stlink/pull/528)) - Chip support added for: * STM32F401XE: Added memory map for device ([#460](https://github.com/texane/stlink/pull/460)) @@ -175,7 +176,6 @@ Chip support added for: * STM32L4xx ([#321](https://github.com/texane/stlink/pull/321)) * STM32L432 ([#500](https://github.com/texane/stlink/pull/500), [#501](https://github.com/texane/stlink/pull/501)) - Updates and fixes: * Set SWDCLK and fixed jtag_reset bug ([#254](https://github.com/texane/stlink/pull/254), [#291](https://github.com/texane/stlink/pull/291), [#475](https://github.com/texane/stlink/pull/475), [#533](https://github.com/texane/stlink/pull/533), [#534](https://github.com/texane/stlink/pull/534)) From ff8334f0ee34243834327da08e0432890b0a8920 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 18 Mar 2020 11:46:37 +0100 Subject: [PATCH 0728/1435] Updated CHANGELOG.md for Release v1.4.0 --- CHANGELOG.md | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d453a2d6..f1d45ce2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ General project updates: * Fixed travis build config file (Nightwalker-87) * Archived page from github project wiki to doc/wiki_old.md (Nightwalker-87) + v1.5.1 ====== @@ -84,6 +85,7 @@ Fixes: * Fix for mem_write() ([#730](https://github.com/texane/stlink/pull/730)) * FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION ([#733](https://github.com/texane/stlink/pull/733)) + v1.5.0 ====== @@ -102,6 +104,7 @@ Fixes: * Fixed verification of flash error for STM32L496x device ([#618](https://github.com/texane/stlink/pull/618)) * Fixed build on Fedora with GCC 8 ([#666](https://github.com/texane/stlink/pull/668)) + v1.4.0 ====== @@ -109,21 +112,28 @@ Release date: 2017-07-01 Major changes and added features: -* Added support for STM32L452 target ([#608](https://github.com/texane/stlink/pull/608)) -* Initial support to compile with Microsoft Visual Studio 2017 ([#602](https://github.com/texane/stlink/pull/602)) +* Allow building of debian package with CPack ([#554](https://github.com/texane/stlink/pull/554), commit [#2c0ab7f](https://github.com/texane/stlink/commit/5b69f25198a1a8f34e2ee48d1ad20f79447e3d55)) +* Added support for STM32L011 target ([#564](https://github.com/texane/stlink/pull/564), [#565](https://github.com/texane/stlink/pull/565), [#572](https://github.com/texane/stlink/pull/572)) * Added support for flashing second bank on STM32F10x_XL ([#592](https://github.com/texane/stlink/pull/592)) -* Added support for STM32L011 target ([#572](https://github.com/texane/stlink/pull/572)) -* Allow building of debian package with CPack (@xor-gate) +* Initial support to compile with Microsoft Visual Studio 2017 ([#602](https://github.com/texane/stlink/pull/602)) +* Added support for STM32L452 target ([#603](https://github.com/texane/stlink/pull/603), [#608](https://github.com/texane/stlink/pull/608)) Updates and fixes: * Fixed gdb-server: L0xx has no FP_CTRL register for breakpoints ([#273](https://github.com/texane/stlink/pull/273)) -* Fixed compilation with GCC 7 ([#590](https://github.com/texane/stlink/pull/590)) -* Skipped GTK detection if we're cross-compiling ([#588](https://github.com/texane/stlink/pull/588)) -* Fixed possible memory leak ([#570](https://github.com/texane/stlink/pull/570)) -* Fixed building with mingw64 ([#569](https://github.com/texane/stlink/pull/569), [#610](https://github.com/texane/stlink/pull/610)) * Updated libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) -* Fixed low-voltage flashing on STM32F7 parts. ([#567](https://github.com/texane/stlink/pull/567)) +* Fixed low-voltage flashing on STM32F7 devices ([#566](https://github.com/texane/stlink/pull/566), [#567](https://github.com/texane/stlink/pull/567)) +* Fixed building with mingw64 ([#569](https://github.com/texane/stlink/pull/569), [#573](https://github.com/texane/stlink/pull/573), [#578](https://github.com/texane/stlink/pull/578), [#584](https://github.com/texane/stlink/pull/584), [#610](https://github.com/texane/stlink/pull/610)) +* Fixed possible memory leak ([#570](https://github.com/texane/stlink/pull/570), [#571](https://github.com/texane/stlink/pull/571)) +* Added --flash=n[k][m] command line option to override device model ([#576](https://github.com/texane/stlink/pull/576)) +* Fixed installation path for shared objects ([#581](https://github.com/texane/stlink/pull/581)) +* Fixed a few -Wformat warnings ([#582](https://github.com/texane/stlink/pull/582)) +* Removed unused defines in mimgw.h ([#583](https://github.com/texane/stlink/pull/583)) +* Skip GTK detection when cross-compiling ([#588](https://github.com/texane/stlink/pull/588)) +* Fixed compilation with GCC 7 ([#590](https://github.com/texane/stlink/pull/590), [#591](https://github.com/texane/stlink/pull/591)) +* Fixed flashing to 'f0 device' targets ([#594](https://github.com/texane/stlink/pull/594), [#595](https://github.com/texane/stlink/pull/595)) +* Fix wrong counting when flashing ([#605](https://github.com/texane/stlink/pull/605)) + v1.3.1 ====== @@ -134,17 +144,18 @@ Major changes and added features: * Added support for Semihosting `SYS_READC` ([#546](https://github.com/texane/stlink/pull/546)) * Added support for STM32F413 ([#549](https://github.com/texane/stlink/pull/549), [#550](https://github.com/texane/stlink/pull/550)) -* Added preliminary support for STM32L011 to see it after probe (chipid `0x457`) ([#558](https://github.com/texane/stlink/pull/558)) +* Added preliminary support for STM32L011 to see it after probe (chipid `0x457`) ([#558](https://github.com/texane/stlink/pull/558), [#598](https://github.com/texane/stlink/pull/598)) Updates and fixes: * cmake/CPackConfig.cmake: Fixup OSX zip filename * Updated source repositories in README.md: Windows, macOS, Alpine Linux +* Compilation fixes ([#547](https://github.com/texane/stlink/pull/547), [#551](https://github.com/texane/stlink/pull/551), [#552](https://github.com/texane/stlink/pull/552)) * Stripped full paths to source files in log ([#548](https://github.com/texane/stlink/pull/548)) -* Compilation fixes ([#551](https://github.com/texane/stlink/pull/551), [#552](https://github.com/texane/stlink/pull/552)) * Fixed incorrect release folder name in docs ([#560](https://github.com/texane/stlink/pull/560)) * Fixed compilation when path includes spaces ([#561](https://github.com/texane/stlink/pull/561)) + v1.3.0 ====== From b1f143ad30547e694010aa52bd34e0aeff2dbe26 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 18 Mar 2020 14:19:41 +0100 Subject: [PATCH 0729/1435] Updated CHANGELOG.md for Release v1.5.0 --- CHANGELOG.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1d45ce2c..7079f8b15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -93,17 +93,21 @@ Release date: 2018-02-16 Major changes and added features: -* STM32F72xx73xx support ([#1969148](https://github.com/texane/stlink/commit/19691485359afef1a256964afcbb8dcf4b733209)) * Added support of STM32L496xx/4A6xx devices ([#615](https://github.com/texane/stlink/pull/615)) +* Added unknown chip dummy to obtain the serial of the ST-link by a call to st-info --probe ([#641](https://github.com/texane/stlink/pull/641)) +* Added support for STM32F72xx (chip id: 0x452) devices (commit [#1969148](https://github.com/texane/stlink/commit/19691485359afef1a256964afcbb8dcf4b733209)) -Fixes: +Updates and fixes: -* Fixed memory map for stm32l496xx boards ([#639](https://github.com/texane/stlink/pull/639)) +* Fixed verification of flash error for STM32L496x device ([#617](https://github.com/texane/stlink/pull/617), [#618](https://github.com/texane/stlink/pull/618)) +* Updated Linux source repositories in README.md: Gentoo, Fedora and RedHat/CentOS ([#622](https://github.com/texane/stlink/pull/622), [#635](https://github.com/texane/stlink/pull/635)) +* Updated changelog in debian package ([#630](https://github.com/texane/stlink/pull/630)) +* Added LIB_INSTALL_DIR to correct libs install on 64-bit systems ([#633](https://github.com/texane/stlink/pull/633), [#636](https://github.com/texane/stlink/pull/636)) * Fixed write for microcontroller with RAM size less or equal to 32K ([#637](https://github.com/texane/stlink/pull/637)) -* Added LIB_INSTALL_DIR to correct libs install on 64-bit systems ([#636](https://github.com/texane/stlink/pull/636)) -* Fixed verification of flash error for STM32L496x device ([#618](https://github.com/texane/stlink/pull/618)) -* Fixed build on Fedora with GCC 8 ([#666](https://github.com/texane/stlink/pull/668)) - +* Fixed memory map for stm32l496xx boards ([#639](https://github.com/texane/stlink/pull/639)) +* Fixed __FILE__ base name extraction ([#624](https://github.com/texane/stlink/pull/624), [#628](https://github.com/texane/stlink/pull/628), [#648](https://github.com/texane/stlink/pull/648)) +* Added debian/triggers to run ldconfig ([#664](https://github.com/texane/stlink/pull/664)) +* Fixed build on Fedora with GCC 8 ([#666](https://github.com/texane/stlink/pull/666), [#667](https://github.com/texane/stlink/pull/667), [#668](https://github.com/texane/stlink/pull/668)) v1.4.0 ====== From 975fcb06728927ae9428f5babe727724f09c8c69 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 18 Mar 2020 19:27:04 +0100 Subject: [PATCH 0730/1435] Updated CHANGELOG.md for Release v1.5.1 --- CHANGELOG.md | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7079f8b15..f19a443b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,28 +61,31 @@ Release date: 2018-09-13 Major changes and added features: +* Added reset through AIRCR ([#540](https://github.com/texane/stlink/pull/540), [#712](https://github.com/texane/stlink/pull/712)) +* Added creation of icons for .desktop file ([#684](https://github.com/texane/stlink/pull/684), [#708](https://github.com/texane/stlink/pull/708)) +* Added desktop file for linux ([#688](https://github.com/texane/stlink/pull/688)) * Added button to export stm32 flash memory to a file ([#691](https://github.com/texane/stlink/pull/691)) * Updated libusb to 1.0.22 ([#695](https://github.com/texane/stlink/pull/695)) -* Added desktop file for linux ([#688](https://github.com/texane/stlink/pull/688)) * Added icons for stlink GUI ([#697](https://github.com/texane/stlink/pull/697)) * Added support for STM32L4R9 target ([#694](https://github.com/texane/stlink/pull/694), [#699](https://github.com/texane/stlink/pull/699)) -* Added creation of icons for .desktop file ([#708](https://github.com/texane/stlink/pull/708)) * Added memory map for STM32F411RE target ([#709](https://github.com/texane/stlink/pull/709)) -* Added reset through AIRCR ([#540](https://github.com/texane/stlink/pull/540), [#712](https://github.com/texane/stlink/pull/712)) -* Implemented intel hex support for GTK GUI ([#718](https://github.com/texane/stlink/pull/718)) +* Implemented intel hex support for GTK GUI ([#713](https://github.com/texane/stlink/pull/713), [#718](https://github.com/texane/stlink/pull/718)) -Fixes: +Updates and fixes: -* Fixed missing flash_loader for L011 ([#675](https://github.com/texane/stlink/pull/675)) -* Fixed serial number size mismatch with stlink_open_usb() ([#680](https://github.com/texane/stlink/pull/680)) -* Debian packaging, CMake and README.md fixes ([#683](https://github.com/texane/stlink/pull/683)) +* Fixed missing flash_loader for L011 ([#356](https://github.com/texane/stlink/pull/356), [#654](https://github.com/texane/stlink/pull/654), [#675](https://github.com/texane/stlink/pull/675)) * Fix for stlink library calls exit() or _exit() ([#634](https://github.com/texane/stlink/pull/634), [#696](https://github.com/texane/stlink/pull/696)) +* Added semihosting parameter documentation in doc/man ([#674](https://github.com/texane/stlink/pull/674)) +* Fixed reference to non-exisiting st-term tool in doc/man ([#676](https://github.com/texane/stlink/pull/676)) +* Fixed serial number size mismatch with stlink_open_usb() ([#680](https://github.com/texane/stlink/pull/680)) +* Debian packaging, CMake and README.md fixes ([#682](https://github.com/texane/stlink/pull/682), [#683](https://github.com/texane/stlink/pull/683)) +* Disabled static library installation by default ([#702](https://github.com/texane/stlink/pull/702)) * Fix for libusb deprecation ([#703](https://github.com/texane/stlink/pull/703), [#704](https://github.com/texane/stlink/pull/704)) * Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX ([#706](https://github.com/texane/stlink/pull/706)) -* Fixed flash memory map for F72XXX target ([#711](https://github.com/texane/stlink/pull/711)) -* Proper flash page size calculation for F412 target ([#721](https://github.com/texane/stlink/pull/721)) -* Return correct value on EOF for Semihosting SYS_READ ([#726](https://github.com/texane/stlink/pull/726), [#729](https://github.com/texane/stlink/pull/729), [#731](https://github.com/texane/stlink/pull/731)) -* Fix for mem_write() ([#730](https://github.com/texane/stlink/pull/730)) +* Regression: stlink installation under Linux (Debian 9) is broken since #695 ([#700](https://github.com/texane/stlink/pull/700), [#701](https://github.com/texane/stlink/pull/701), [#707](https://github.com/texane/stlink/pull/707)) +* Fixed flash memory map for F72xxx target ([#711](https://github.com/texane/stlink/pull/711)) +* Proper flash page size calculation for F412xx target ([#721](https://github.com/texane/stlink/pull/721)) +* Return correct value on EOF for Semihosting SYS_READ ([#726](https://github.com/texane/stlink/pull/726), [#727](https://github.com/texane/stlink/pull/727), [#729](https://github.com/texane/stlink/pull/729), [#730](https://github.com/texane/stlink/pull/730), [#731](https://github.com/texane/stlink/pull/731)) * FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION ([#733](https://github.com/texane/stlink/pull/733)) @@ -109,6 +112,7 @@ Updates and fixes: * Added debian/triggers to run ldconfig ([#664](https://github.com/texane/stlink/pull/664)) * Fixed build on Fedora with GCC 8 ([#666](https://github.com/texane/stlink/pull/666), [#667](https://github.com/texane/stlink/pull/667), [#668](https://github.com/texane/stlink/pull/668)) + v1.4.0 ====== From bc423e2e26a6b9de843a2170bfd78fd70464fec4 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 18 Mar 2020 23:00:51 +0100 Subject: [PATCH 0731/1435] Added missing tickets to CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f19a443b6..30cd219f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -85,7 +85,7 @@ Updates and fixes: * Regression: stlink installation under Linux (Debian 9) is broken since #695 ([#700](https://github.com/texane/stlink/pull/700), [#701](https://github.com/texane/stlink/pull/701), [#707](https://github.com/texane/stlink/pull/707)) * Fixed flash memory map for F72xxx target ([#711](https://github.com/texane/stlink/pull/711)) * Proper flash page size calculation for F412xx target ([#721](https://github.com/texane/stlink/pull/721)) -* Return correct value on EOF for Semihosting SYS_READ ([#726](https://github.com/texane/stlink/pull/726), [#727](https://github.com/texane/stlink/pull/727), [#729](https://github.com/texane/stlink/pull/729), [#730](https://github.com/texane/stlink/pull/730), [#731](https://github.com/texane/stlink/pull/731)) +* Return correct value on EOF for Semihosting SYS_READ ([#726](https://github.com/texane/stlink/pull/726), [#727](https://github.com/texane/stlink/pull/727), [#728](https://github.com/texane/stlink/pull/728), [#729](https://github.com/texane/stlink/pull/729), [#730](https://github.com/texane/stlink/pull/730), [#731](https://github.com/texane/stlink/pull/731), [#732](https://github.com/texane/stlink/pull/732)) * FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION ([#733](https://github.com/texane/stlink/pull/733)) @@ -211,6 +211,7 @@ Updates and fixes: * Fixed Cygwin build ([#487](https://github.com/texane/stlink/pull/487), ([#506](https://github.com/texane/stlink/pull/506)) * Reset flash mass erase (MER) bit after mass erase for safety ([#489](https://github.com/texane/stlink/pull/489)) * Wrong extract command in FindLibUSB.cmake ([#510](https://github.com/texane/stlink/pull/510), [#511](https://github.com/texane/stlink/pull/511)) +* Fixed compilation error on Ubuntu 16.10 ([#514](https://github.com/texane/stlink/pull/514), [#525](https://github.com/texane/stlink/pull/525)) v1.2.0 From 116f4e58f62c15e24fd7c48613873c483ec9b968 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 18 Mar 2020 23:11:46 +0100 Subject: [PATCH 0732/1435] Removed CKS32F103 in tested-boards.md --- doc/tested-boards.md | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/tested-boards.md b/doc/tested-boards.md index b28163a30..ebc47c2ac 100644 --- a/doc/tested-boards.md +++ b/doc/tested-boards.md @@ -7,7 +7,6 @@ Known working targets: * STM32F100xx (Medium Density VL) * STM32F103 (according to jpa- on ##stm32) -* CKS32F103 (chinese STM32F103-Clone) No information: From 13c62114393f12a9b4d3cfc574cfabedfed50d5c Mon Sep 17 00:00:00 2001 From: "R.E. Wolff" Date: Thu, 19 Mar 2020 15:21:27 +0100 Subject: [PATCH 0733/1435] changed text for F72/F73 --- src/chipid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chipid.c b/src/chipid.c index df07d524f..f04c3eaa6 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -27,7 +27,7 @@ static const struct stlink_chipid_params devices[] = { { //RM0431 and DS document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F72XXX, - .description = "F72 device", + .description = "F72/F73 device", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1ff07a22, // section 35.2 .flash_pagesize = 0x800, // No flash pages From b8813fab9734521a1857189aab5dbf2a30d37ea4 Mon Sep 17 00:00:00 2001 From: "R.E. Wolff" Date: Thu, 19 Mar 2020 17:47:34 +0100 Subject: [PATCH 0734/1435] Fixed long wait when the loader refuses to run. Fixes #290 --- src/flash_loader.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/flash_loader.c b/src/flash_loader.c index f88a42eca..9c24ff9e8 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -384,10 +384,20 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe /* run loader */ stlink_run(sl); -#define WAIT_ROUNDS 10000 +// This piece of code used to try to spin for .1 second by waiting +// doing 10000 rounds of 10 microseconds. But because this usually runs +// on Unix-like OSes, the 10 microseconds get rounded up to the "tick" +// (actually almost two ticks) of the system. 1 milisecond. Thus, the +// ten thousand attempts, when "something goes wrong" that requires +// the error message "flash loader run error" would wait for something +// like 20 seconds before coming up with the error. +// by increasing the sleep-per-round to the same order-of-magnitude as +// the tick-rounding that the OS uses, the wait until the error message is +// reduced to the same order of magnitude as what was intended. -- REW. +#define WAIT_ROUNDS 100 /* wait until done (reaches breakpoint) */ for (i = 0; i < WAIT_ROUNDS; i++) { - usleep(10); + usleep(1000); if (stlink_is_core_halted(sl)) break; } From 60db4e56dcded849b453c74e9d00aa8dd070bce6 Mon Sep 17 00:00:00 2001 From: petertorelli Date: Fri, 20 Mar 2020 08:43:58 -0700 Subject: [PATCH 0735/1435] Added more error info to WLOGs during probe. --- src/usb.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/usb.c b/src/usb.c index 9df9d7296..ad062735d 100644 --- a/src/usb.c +++ b/src/usb.c @@ -1102,9 +1102,9 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { /* Count stlink */ while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; - int r = libusb_get_device_descriptor(dev, &desc); - if (r < 0) { - WLOG("failed to get libusb device descriptor\n"); + ret = libusb_get_device_descriptor(dev, &desc); + if (ret < 0) { + WLOG("failed to get libusb device descriptor (libusb error: %d)\n", ret); break; } @@ -1133,7 +1133,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { struct libusb_device_descriptor desc; ret = libusb_get_device_descriptor(dev, &desc); if (ret < 0) { - WLOG("failed to get libusb device descriptor\n"); + WLOG("failed to get libusb device descriptor (libusb error: %d)\n", ret); break; } @@ -1148,7 +1148,11 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { ret = libusb_open(dev, &handle); if (ret < 0) { - WLOG("failed to get libusb device descriptor\n"); + if (ret == LIBUSB_ERROR_ACCESS) { + WLOG("failed to open USB device (LIBUSB_ERROR_ACCESS), try running as root?\n"); + } else { + WLOG("failed to open USB device (libusb error: %d)\n", ret); + } break; } @@ -1159,7 +1163,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { libusb_close(handle); stlink_t *sl = NULL; - sl = stlink_open_usb(0, 1, serial); + sl = stlink_open_usb(0, 1, serial); if (!sl) continue; From c9efcba111171c8e03beeec81e93f55075204722 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 21 Mar 2020 00:26:59 +0100 Subject: [PATCH 0736/1435] Updated CHANGELOG.md for Release v1.6.0 --- CHANGELOG.md | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30cd219f5..3e3824a01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,49 +8,47 @@ Release date: 2020-02-20 Major changes and added features: -* Added O_BINARY option to open file ([#753](https://github.com/texane/stlink/pull/753)) -* Added preliminary support for some STM32G0 chips ([#759](https://github.com/texane/stlink/pull/759), [#760](https://github.com/texane/stlink/pull/760)) +* Initial support for STM32L41X ([#754](https://github.com/texane/stlink/pull/754), [#799](https://github.com/texane/stlink/pull/799)) +* Added preliminary support for some STM32G0 chips ([#759](https://github.com/texane/stlink/pull/759), [#760](https://github.com/texane/stlink/pull/760), [#797](https://github.com/texane/stlink/pull/797)) * Added support for mass erasing second bank on STM32F10x_XL ([#767](https://github.com/texane/stlink/pull/767), [#768](https://github.com/texane/stlink/pull/768)) * Added call to clear PG bit after writing to flash ([#773](https://github.com/texane/stlink/pull/773)) -* Added howto for sending NRST signal through GDB ([#774](https://github.com/texane/stlink/pull/774), [#776](https://github.com/texane/stlink/pull/776)) * Added support to write option bytes for the STM32G0 ([#778](https://github.com/texane/stlink/pull/778)) -* Added simple read/write support for STM32WB55 chips ([#786](https://github.com/texane/stlink/pull/786)) +* Added support for STM32WB55 chips ([#786](https://github.com/texane/stlink/pull/786), [#810](https://github.com/texane/stlink/pull/810), [#816](https://github.com/texane/stlink/pull/816)) * Added STLink V3SET VID:PIDs to the udev rules ([#789](https://github.com/texane/stlink/pull/789)) * Support for "STM32+Audio" v2-1 firmware ([#790](https://github.com/texane/stlink/pull/790)) -* Initial support for STM32L41X ([#799](https://github.com/texane/stlink/pull/799)) * Build for Windows under Debian/Ubuntu ([#802](https://github.com/texane/stlink/pull/802)) * Allow for 64 bytes serials ([#809](https://github.com/texane/stlink/pull/809)) -* Added support to read and write option bytes for STM32F2 series (Orie22) -* Added full support for STLINK CHIP ID L4RX (Brad Natelborg) -* Added support to write option bytes to STM32F4 devices (Davey Struijk) +* Added full support for STLINK CHIP ID L4RX ([#814](https://github.com/texane/stlink/pull/814), [#839](https://github.com/texane/stlink/pull/839)) +* Added support for writing option bytes on STM32L0 ([#830](https://github.com/texane/stlink/pull/830)) +* Added support to read and write option bytes for STM32F2 series ([#836](https://github.com/texane/stlink/pull/836), [#837](https://github.com/texane/stlink/pull/837)) +* Added support to read and write option bytes for STM32F446 ([#843](https://github.com/texane/stlink/pull/843)) Updates and fixes: -* Build failure when platform is 32 bit, but stuct stat.st_size is 64 bit. ([#629](https://github.com/texane/stlink/pull/629)) +* Updated STM32F3xx chip ID that covers a few different devices ([#685](https://github.com/texane/stlink/pull/685), [#758](https://github.com/texane/stlink/pull/758)) * Made udev rules and modprobe conf installation optional ([#741](https://github.com/texane/stlink/pull/741)) -* Fixed case when __FILE__ don't contain "/" nor "\\". ([#745](https://github.com/texane/stlink/pull/745)) -* Fixed double dash issue in doc/man ([#746](https://github.com/texane/stlink/pull/746)) -* Fixed Debug error on line 123 in CMakeLists.txt (@xor-gate) -* Only do bank calculation on STM32L4 devices with dual banked flash ([#751](https://github.com/texane/stlink/pull/751)) -* Updated STM32F3xx chip ID that covers a few different devices ([#758](https://github.com/texane/stlink/pull/758)) +* Fixed case when __FILE__ don't contain "/" nor "\\" ([#745](https://github.com/texane/stlink/pull/745)) +* Fixed double dash issue in doc/man ([#746](https://github.com/texane/stlink/pull/746), [#747](https://github.com/texane/stlink/pull/747)) +* Compiling documentation: package is called libusb-1.0-0-dev on Debian ([#748](https://github.com/texane/stlink/pull/748)) +* Only do bank calculation on STM32L4 devices with dual banked flash / Added chip ID 0x464 for STM32L41xxx/L42xxx devices ([#751](https://github.com/texane/stlink/pull/751)) +* Added O_BINARY option to open file ([#753](https://github.com/texane/stlink/pull/753)) * Fixed versioning when compiling from the checked out git-repo ([#762](https://github.com/texane/stlink/pull/762)) -* Fixed "unkown chip id", piped output and st-util -v ([#107](https://github.com/texane/stlink/pull/107), [#763](https://github.com/texane/stlink/pull/763)) +* Fixed "unkown chip id", piped output and st-util -v ([#107](https://github.com/texane/stlink/pull/107), [#665](https://github.com/texane/stlink/pull/665), [#763](https://github.com/texane/stlink/pull/763)) * win32: move usleep definition to unistd.h ([#765](https://github.com/texane/stlink/pull/765)) * Fixed relative path to the UI files needed by stlink-gui-local (GUI) ([#770](https://github.com/texane/stlink/pull/770), [#771](https://github.com/texane/stlink/pull/771)) +* Added howto for sending NRST signal through GDB ([#774](https://github.com/texane/stlink/pull/774), [#776](https://github.com/texane/stlink/pull/776), [#779](https://github.com/texane/stlink/pull/779)) * Fixed package name "devscripts" in doc/compiling.md ([#775](https://github.com/texane/stlink/pull/775)) -* Fixed apparent STM32G0 flashing issue ([#797](https://github.com/texane/stlink/pull/797)) * Fixed few potential memory/resource leaks ([#803](https://github.com/texane/stlink/pull/803)) -* Fixed flash verification error on STM32WB55RG ([#810](https://github.com/texane/stlink/pull/810), [#816](https://github.com/texane/stlink/pull/816)) -* Do not issue JTAG reset on stlink-v1 (Gwenhael Goavec-Merou) -* Fixed flash size of STM32 Discovery vl (Gwenhael Goavec-Merou) -* Added support for writing option bytes on STM32L0 (Adrian Imboden) +* Do not issue JTAG reset on stlink-v1 ([#828](https://github.com/texane/stlink/pull/828)) +* Fixed flash size of STM32 Discovery vl ([#829](https://github.com/texane/stlink/pull/829)) +* Updated Linux source repositories in README.md: Debian and Ubuntu ([#821](https://github.com/texane/stlink/pull/821), [#835](https://github.com/texane/stlink/pull/835), [#859](https://github.com/texane/stlink/pull/859)) * Updated documentation on software structure ([#851](https://github.com/texane/stlink/pull/851)) General project updates: -* Updated issue templates, README.md and CHANGELOG.md (Nightwalker-87) -* Added CODE_OF_CONDUCT (Nightwalker-87) +* Updated README.md, CHANGELOG.md and issue templates (Nightwalker-87) * Fixed travis build config file (Nightwalker-87) +* Added CODE_OF_CONDUCT (Nightwalker-87) * Archived page from github project wiki to doc/wiki_old.md (Nightwalker-87) @@ -140,7 +138,7 @@ Updates and fixes: * Skip GTK detection when cross-compiling ([#588](https://github.com/texane/stlink/pull/588)) * Fixed compilation with GCC 7 ([#590](https://github.com/texane/stlink/pull/590), [#591](https://github.com/texane/stlink/pull/591)) * Fixed flashing to 'f0 device' targets ([#594](https://github.com/texane/stlink/pull/594), [#595](https://github.com/texane/stlink/pull/595)) -* Fix wrong counting when flashing ([#605](https://github.com/texane/stlink/pull/605)) +* Fixed wrong counting when flashing ([#605](https://github.com/texane/stlink/pull/605)) v1.3.1 @@ -171,7 +169,7 @@ Release date: 2017-01-28 Major changes and added features: -* Deprecation of autotools (autoconf, automake) ([#83](https://github.com/texane/stlink/pull/83), [#431](https://github.com/texane/stlink/pull/431), [#434](https://github.com/texane/stlink/pull/434)) +* Deprecation of autotools (autoconf, automake) and fixed build with MinGW ([#83](https://github.com/texane/stlink/pull/83), [#431](https://github.com/texane/stlink/pull/431), [#434](https://github.com/texane/stlink/pull/434), [#465](https://github.com/texane/stlink/pull/465)) * Added intel hex file reading for `st-flash` ([#110](https://github.com/texane/stlink/pull/110), [#157](https://github.com/texane/stlink/pull/157), [#200](https://github.com/texane/stlink/pull/200), [#239](https://github.com/texane/stlink/pull/239), [#457](https://github.com/texane/stlink/pull/547), [#459](https://github.com/texane/stlink/pull/549)) * Added manpages (generated with pandoc from Markdown) ([#208](https://github.com/texane/stlink/pull/208), [#464](https://github.com/texane/stlink/pull/464), [#466](https://github.com/texane/stlink/pull/466), [#467](https://github.com/texane/stlink/pull/467)) * Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#228](https://github.com/texane/stlink/pull/228), ([#507](https://github.com/texane/stlink/pull/507), commit [#2c0ab7f](https://github.com/texane/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) From c8a2f133f0703a434da05e89148526806225e364 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 21 Mar 2020 01:59:05 +0100 Subject: [PATCH 0737/1435] General Project Update - Minor documentation fixes - HOWTO and FAQ --> tutorial.md --- CHANGELOG.md | 2 +- README.md | 123 ------------------------------------------ doc/release.md | 2 +- doc/tutorial.md | 138 +++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 134 insertions(+), 131 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e3824a01..e6356caf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,9 +39,9 @@ Updates and fixes: * Added howto for sending NRST signal through GDB ([#774](https://github.com/texane/stlink/pull/774), [#776](https://github.com/texane/stlink/pull/776), [#779](https://github.com/texane/stlink/pull/779)) * Fixed package name "devscripts" in doc/compiling.md ([#775](https://github.com/texane/stlink/pull/775)) * Fixed few potential memory/resource leaks ([#803](https://github.com/texane/stlink/pull/803)) +* Updated Linux source repositories in README.md: Debian and Ubuntu ([#821](https://github.com/texane/stlink/pull/821), [#835](https://github.com/texane/stlink/pull/835), [#859](https://github.com/texane/stlink/pull/859)) * Do not issue JTAG reset on stlink-v1 ([#828](https://github.com/texane/stlink/pull/828)) * Fixed flash size of STM32 Discovery vl ([#829](https://github.com/texane/stlink/pull/829)) -* Updated Linux source repositories in README.md: Debian and Ubuntu ([#821](https://github.com/texane/stlink/pull/821), [#835](https://github.com/texane/stlink/pull/835), [#859](https://github.com/texane/stlink/pull/859)) * Updated documentation on software structure ([#851](https://github.com/texane/stlink/pull/851)) General project updates: diff --git a/README.md b/README.md index 3bc6c2c80..6a6fd4ae3 100644 --- a/README.md +++ b/README.md @@ -142,126 +142,3 @@ openocd: "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x31" Try to remove the write protection (probably only possible with ST Link Utility from ST itself). Issue related to this bug: [#545](https://github.com/texane/stlink/issues/545) - - -# HOWTO -## Using the gdb server - -To run the gdb server: - -``` -$ make && [sudo] ./st-util - -There are a few options: - -./st-util - usage: - - -h, --help Print this help - -vXX, --verbose=XX Specify a specific verbosity level (0..99) - -v, --verbose Specify generally verbose logging - -s X, --stlink_version=X - Choose what version of stlink to use, (defaults to 2) - -1, --stlinkv1 Force stlink version 1 - -p 4242, --listen_port=1234 - Set the gdb server listen port. (default port: 4242) - -m, --multi - Set gdb server to extended mode. - st-util will continue listening for connections after disconnect. - -n, --no-reset - Do not reset board on connection. -``` - -The STLINKv2 device to use can be specified in the environment -variable `STLINK_DEVICE` in the format `:`. - -Then, in your project directory, someting like this... -(remember, you need to run an _ARM_ gdb, not an x86 gdb) - -``` -$ arm-none-eabi-gdb fancyblink.elf -... -(gdb) tar extended-remote :4242 -... -(gdb) load -Loading section .text, size 0x458 lma 0x8000000 -Loading section .data, size 0x8 lma 0x8000458 -Start address 0x80001c1, load size 1120 -Transfer rate: 1 KB/sec, 560 bytes/write. -(gdb) -... -(gdb) continue -``` - - -## Resetting the chip from GDB - -You may reset the chip using GDB if you want. You'll need to use `target -extended-remote' command like in this session: - -``` -(gdb) target extended-remote localhost:4242 -Remote debugging using localhost:4242 -0x080007a8 in _startup () -(gdb) kill -Kill the program being debugged? (y or n) y -(gdb) run -Starting program: /home/whitequark/ST/apps/bally/firmware.elf -``` - -Remember that you can shorten the commands. `tar ext :4242` is good enough -for GDB. - -If you need to send a hard reset signal through `NRST` pin, you can use the following command: - -``` -(gdb) monitor jtag_reset -``` - - -## Running programs from SRAM - -You can run your firmware directly from SRAM if you want to. Just link -it at 0x20000000 and do - -``` -(gdb) load firmware.elf -``` - -It will be loaded, and pc will be adjusted to point to start of the -code, if it is linked correctly (i.e. ELF has correct entry point). - - -## Writing to flash - -The GDB stub ships with a correct memory map, including the flash area. -If you would link your executable to `0x08000000` and then do - -``` -(gdb) load firmware.elf -``` - -then it would be written to the memory. - - -## Writing Option Bytes - -Example to read and write option bytes (currently writing only supported for STM32G0 and STM32L0) -``` -./st-flash --debug --reset --format binary --flash=128k read option_bytes_dump.bin 0x1FFF7800 4 -./st-flash --debug --reset --format binary --flash=128k write option_bytes_dump.bin 0x1FFF7800 -``` - - -## FAQ - -Q: My breakpoints do not work at all or only work once. - -A: Optimizations can cause severe instruction reordering. For example, if you are doing something like `REG = 0x100;' in a loop, the code may be split into two parts: loading 0x100 into some intermediate register and moving that value to REG. When you set up a breakpoint, GDB will hook to the first instruction, which may be called only once if there are enough unused registers. In my experience, -O3 causes that frequently. - -Q: At some point I use GDB command `next', and it hangs. - -A: Sometimes when you will try to use GDB `next` command to skip a loop, it will use a rather inefficient single-stepping way of doing that. Set up a breakpoint manually in that case and do `continue`. - -Q: Load command does not work in GDB. - -A: Some people report XML/EXPAT is not enabled by default when compiling GDB. Memory map parsing thus fail. Use --enable-expat. diff --git a/doc/release.md b/doc/release.md index c2dca87b2..ae8b864ee 100644 --- a/doc/release.md +++ b/doc/release.md @@ -1,7 +1,7 @@ Release ======= -This document describes the steps takes for developers to create a release +This document describes the steps it takes for developers to create a release 1. Update `.version` with semantic version: `x.x.x` 2. Update `README.md` with semantic version `x.x.x` in commits badge diff --git a/doc/tutorial.md b/doc/tutorial.md index 35c607ac0..af4bae849 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -37,7 +37,7 @@ Before continuing, the following dependencies must be met: Also make sure `gtk+` version 3.0 is installed. (`sudo apt-get install gtk+-3.0` or similiar) -STLINK should run on any system meeting the above constraints. +STLINK should run on any system meeting the above constraints. The STLINK software source code is retrieved using: @@ -62,7 +62,6 @@ It includes: Using the GDB server ==================== - This assumes you have got the libopencm3 project downloaded in `ocm3`. The libopencm3 project has some good, reliable examples for each of the @@ -85,11 +84,11 @@ the discovery kit you are using, you must run one of the 2 commands: $> ./st-util --stlinkv1 # STM32L or STM32F4 discovery kit (onboard ST-link/V2) -$> ./st-util +$> ./st-util # Full help for other options (listen port, version) $> ./st-util --help -``` +``` Then, GDB can be used to interact with the kit: @@ -113,7 +112,7 @@ command line, now we can simply “load” the target: ``` (gdb) load -``` +``` st-util will load all sections into their appropriate addresses, and “correctly” set the PC register. So, to run your freshly loaded program, @@ -127,6 +126,7 @@ Your program should now be running, and, if you used one of the blinking examples from libopencm3, the LEDs on the board should be blinking for you. + Building and flashing a program =============================== @@ -154,7 +154,7 @@ It is also possible to write a hexfile which is more convinient: $> ./st-flash --format ihex write myapp.hex ``` -#### +#### Of course, you can use this instead of the gdb server, if you prefer. Just remember to use the “.bin” image, rather than the .elf file. @@ -167,6 +167,132 @@ $> [sudo] ./st-flash write fancy_blink.bin 0x08000000 Upon reset, the board LEDs should be blinking. + +HOWTO +===== +## Using the gdb server + +To run the gdb server: + +``` +$ make && [sudo] ./st-util + +There are a few options: + +./st-util - usage: + + -h, --help Print this help + -vXX, --verbose=XX Specify a specific verbosity level (0..99) + -v, --verbose Specify generally verbose logging + -s X, --stlink_version=X + Choose what version of stlink to use, (defaults to 2) + -1, --stlinkv1 Force stlink version 1 + -p 4242, --listen_port=1234 + Set the gdb server listen port. (default port: 4242) + -m, --multi + Set gdb server to extended mode. + st-util will continue listening for connections after disconnect. + -n, --no-reset + Do not reset board on connection. +``` + +The STLINKv2 device to use can be specified in the environment +variable `STLINK_DEVICE` in the format `:`. + +Then, in your project directory, someting like this... +(remember, you need to run an _ARM_ gdb, not an x86 gdb) + +``` +$ arm-none-eabi-gdb fancyblink.elf +... +(gdb) tar extended-remote :4242 +... +(gdb) load +Loading section .text, size 0x458 lma 0x8000000 +Loading section .data, size 0x8 lma 0x8000458 +Start address 0x80001c1, load size 1120 +Transfer rate: 1 KB/sec, 560 bytes/write. +(gdb) +... +(gdb) continue +``` + + +## Resetting the chip from GDB + +You may reset the chip using GDB if you want. You'll need to use `target +extended-remote' command like in this session: + +``` +(gdb) target extended-remote localhost:4242 +Remote debugging using localhost:4242 +0x080007a8 in _startup () +(gdb) kill +Kill the program being debugged? (y or n) y +(gdb) run +Starting program: /home/whitequark/ST/apps/bally/firmware.elf +``` + +Remember that you can shorten the commands. `tar ext :4242` is good enough +for GDB. + +If you need to send a hard reset signal through `NRST` pin, you can use the following command: + +``` +(gdb) monitor jtag_reset +``` + + +## Running programs from SRAM + +You can run your firmware directly from SRAM if you want to. Just link +it at 0x20000000 and do + +``` +(gdb) load firmware.elf +``` + +It will be loaded, and pc will be adjusted to point to start of the +code, if it is linked correctly (i.e. ELF has correct entry point). + + +## Writing to flash + +The GDB stub ships with a correct memory map, including the flash area. +If you would link your executable to `0x08000000` and then do + +``` +(gdb) load firmware.elf +``` + +then it would be written to the memory. + + +## Writing Option Bytes + +Example to read and write option bytes (currently writing only supported for STM32G0 and STM32L0) +``` +./st-flash --debug --reset --format binary --flash=128k read option_bytes_dump.bin 0x1FFF7800 4 +./st-flash --debug --reset --format binary --flash=128k write option_bytes_dump.bin 0x1FFF7800 +``` + + +FAQ +=== + +Q: My breakpoints do not work at all or only work once. + +A: Optimizations can cause severe instruction reordering. For example, if you are doing something like `REG = 0x100;' in a loop, the code may be split into two parts: loading 0x100 into some intermediate register and moving that value to REG. When you set up a breakpoint, GDB will hook to the first instruction, which may be called only once if there are enough unused registers. In my experience, -O3 causes that frequently. + +Q: At some point I use GDB command `next', and it hangs. + +A: Sometimes when you will try to use GDB `next` command to skip a loop, it will use a rather inefficient single-stepping way of doing that. Set up a breakpoint manually in that case and do `continue`. + +Q: Load command does not work in GDB. + +A: Some people report XML/EXPAT is not enabled by default when compiling GDB. Memory map parsing thus fail. Use --enable-expat. + + Notes ===== From 784fdde0ae238bcb385be4d13850c3b78bbe602f Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 21 Mar 2020 14:48:40 +0200 Subject: [PATCH 0738/1435] check if app's need for libssp. --- CMakeLists.txt | 29 +++++++++++++++++++---------- src/gdbserver/CMakeLists.txt | 4 ++-- src/tools/gui/CMakeLists.txt | 4 ++-- tests/CMakeLists.txt | 4 ++-- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 90378f9ed..d9e2bf6bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,15 @@ if (STLINK_HAVE_UNISTD_H) add_definitions(-DSTLINK_HAVE_UNISTD_H) endif() +include(CheckLibraryExists) +CHECK_LIBRARY_EXISTS(ssp __stack_chk_fail "" _stack_chk_fail_exists) + +if(_stack_chk_fail_exists) + set(SSP_LIB ssp) +else() + set(SSP_LIB "") +endif() + if (CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE "Debug") endif() @@ -135,13 +144,13 @@ if (APPLE) find_library(ObjC objc) find_library(CoreFoundation CoreFoundation) find_library(IOKit IOKit) - target_link_libraries(${STLINK_LIB_SHARED} ${CoreFoundation} ${IOKit} ${ObjC}) + target_link_libraries(${STLINK_LIB_SHARED} ${CoreFoundation} ${IOKit} ${ObjC} ${SSP_LIB}) endif() if (WIN32 OR MSYS OR MINGW) - target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} wsock32 ws2_32) + target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} wsock32 ws2_32 ${SSP_LIB}) else() - target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY}) + target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB}) endif() @@ -164,13 +173,13 @@ if (APPLE) find_library(ObjC objc) find_library(CoreFoundation CoreFoundation) find_library(IOKit IOKit) - target_link_libraries(${STLINK_LIB_STATIC} ${CoreFoundation} ${IOKit} ${ObjC}) + target_link_libraries(${STLINK_LIB_STATIC} ${CoreFoundation} ${IOKit} ${ObjC} ${SSP_LIB}) endif() if (WIN32 OR MSYS OR MINGW) - target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} wsock32 ws2_32) + target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} wsock32 ws2_32 ${SSP_LIB}) else() - target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY}) + target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB}) endif() set_target_properties(${STLINK_LIB_STATIC} PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) @@ -186,16 +195,16 @@ endif() ### add_executable(st-flash src/tools/flash.c src/tools/flash_opts.c) if (WIN32 OR APPLE) - target_link_libraries(st-flash ${STLINK_LIB_STATIC}) + target_link_libraries(st-flash ${STLINK_LIB_STATIC} ${SSP_LIB}) else() - target_link_libraries(st-flash ${STLINK_LIB_SHARED}) + target_link_libraries(st-flash ${STLINK_LIB_SHARED} ${SSP_LIB}) endif() add_executable(st-info src/tools/info.c) if (WIN32 OR APPLE) - target_link_libraries(st-info ${STLINK_LIB_STATIC}) + target_link_libraries(st-info ${STLINK_LIB_STATIC} ${SSP_LIB}) else() - target_link_libraries(st-info ${STLINK_LIB_SHARED}) + target_link_libraries(st-info ${STLINK_LIB_SHARED} ${SSP_LIB}) endif() install(TARGETS st-flash st-info diff --git a/src/gdbserver/CMakeLists.txt b/src/gdbserver/CMakeLists.txt index 2393690ce..b4674ebbb 100644 --- a/src/gdbserver/CMakeLists.txt +++ b/src/gdbserver/CMakeLists.txt @@ -14,9 +14,9 @@ endif() add_executable(st-util ${STUTIL_SOURCE}) if (WIN32 OR APPLE) - target_link_libraries(st-util ${STLINK_LIB_STATIC}) + target_link_libraries(st-util ${STLINK_LIB_STATIC} ${SSP_LIB}) else() - target_link_libraries(st-util ${STLINK_LIB_SHARED}) + target_link_libraries(st-util ${STLINK_LIB_SHARED} ${SSP_LIB}) endif() install(TARGETS st-util diff --git a/src/tools/gui/CMakeLists.txt b/src/tools/gui/CMakeLists.txt index c619a0547..91aabc53b 100644 --- a/src/tools/gui/CMakeLists.txt +++ b/src/tools/gui/CMakeLists.txt @@ -10,13 +10,13 @@ include_directories(SYSTEM ${gtk_INCLUDE_DIRS}) add_executable(stlink-gui-local ${GUI_SOURCES}) set_target_properties(stlink-gui-local PROPERTIES COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}") -target_link_libraries(stlink-gui-local ${STLINK_LIB_STATIC} ${gtk_LDFLAGS}) +target_link_libraries(stlink-gui-local ${STLINK_LIB_STATIC} ${gtk_LDFLAGS} ${SSP_LIB}) add_executable(stlink-gui ${GUI_SOURCES}) set_target_properties(stlink-gui PROPERTIES COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}") -target_link_libraries(stlink-gui ${STLINK_LIB_STATIC} ${gtk_LDFLAGS}) +target_link_libraries(stlink-gui ${STLINK_LIB_STATIC} ${gtk_LDFLAGS} ${SSP_LIB}) install(TARGETS stlink-gui RUNTIME DESTINATION bin) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8df28ce7e..9d0bdffaf 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -6,10 +6,10 @@ set(TESTS foreach(test ${TESTS}) add_executable(${test} ${test}.c) add_dependencies(${test} ${STLINK_LIB_STATIC}) - target_link_libraries(${test} ${STLINK_LIB_STATIC}) + target_link_libraries(${test} ${STLINK_LIB_STATIC} ${SSP_LIB}) add_test(${test} ${CMAKE_CURRENT_BINARY_DIR}/${test}) endforeach() add_executable(flash flash.c "${CMAKE_SOURCE_DIR}/src/tools/flash_opts.c") -target_link_libraries(flash ${STLINK_LIB_STATIC}) +target_link_libraries(flash ${STLINK_LIB_STATIC} ${SSP_LIB}) add_test(flash ${CMAKE_CURRENT_BINARY_DIR}/flash) From e75a5d22ef50c2cd6bd49e77b83c4ebd5b0b81ac Mon Sep 17 00:00:00 2001 From: Rogier Wolff Date: Sat, 21 Mar 2020 16:08:09 +0100 Subject: [PATCH 0739/1435] reduce clutter in output messages --- src/chipid.c | 96 +++++++++++++++++++------------------- src/common.c | 12 ++++- src/gdbserver/gdb-server.c | 5 +- src/usb.c | 4 +- 4 files changed, 65 insertions(+), 52 deletions(-) diff --git a/src/chipid.c b/src/chipid.c index f04c3eaa6..f296f2509 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -5,7 +5,7 @@ static const struct stlink_chipid_params devices[] = { { //RM0410 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F7XXXX, - .description = "F76xxx device", + .description = "F76xxx", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1ff0f442, // section 45.2 .flash_pagesize = 0x800, // No flash pages @@ -16,7 +16,7 @@ static const struct stlink_chipid_params devices[] = { { //RM0385 and DS10916 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F7, - .description = "F7 device", + .description = "F7xx", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1ff0f442, // section 41.2 .flash_pagesize = 0x800, // No flash pages @@ -27,7 +27,7 @@ static const struct stlink_chipid_params devices[] = { { //RM0431 and DS document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F72XXX, - .description = "F72/F73 device", + .description = "F72x/F73x", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1ff07a22, // section 35.2 .flash_pagesize = 0x800, // No flash pages @@ -37,7 +37,7 @@ static const struct stlink_chipid_params devices[] = { }, { // table 2, PM0063 .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, - .description = "F1 Medium-density device", + .description = "F1xx Medium-density", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, @@ -47,7 +47,7 @@ static const struct stlink_chipid_params devices[] = { }, { // table 1, PM0059 .chip_id = STLINK_CHIPID_STM32_F2, - .description = "F2 device", + .description = "F2xx", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1fff7a22, /* As in RM0033 Rev 5*/ .flash_pagesize = 0x20000, @@ -67,7 +67,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F4, - .description = "F4 device", + .description = "F4xx", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ .flash_pagesize = 0x4000, @@ -77,7 +77,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F4_DSI, - .description = "F46x and F47x device", + .description = "F46x/F47x", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ .flash_pagesize = 0x4000, @@ -87,7 +87,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F4_HD, - .description = "F42x and F43x device", + .description = "F42x/F43x", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ .flash_pagesize = 0x4000, @@ -97,7 +97,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F4_LP, - .description = "F4 device (low power)", + .description = "F4xx (low power)", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, @@ -107,7 +107,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F411RE, - .description = "F4 device (low power) - stm32f411re", + .description = "stm32f411re", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, @@ -117,7 +117,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F4_DE, - .description = "F4 device (Dynamic Efficency)", + .description = "F4xx (Dynamic Efficency)", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, @@ -127,7 +127,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F1_HIGH, - .description = "F1 High-density device", + .description = "F1xx High-density", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -139,7 +139,7 @@ static const struct stlink_chipid_params devices[] = { // This ignores the EEPROM! (and uses the page erase size, // not the sector write protection...) .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM, - .description = "L1 Med-density device", + .description = "L1xx Medium-density", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8004c, .flash_pagesize = 0x100, @@ -149,7 +149,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_L1_CAT2, - .description = "L1 Cat.2 device", + .description = "L1xx Cat.2", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8004c, .flash_pagesize = 0x100, @@ -159,7 +159,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM_PLUS, - .description = "L1 Medium-Plus-density device", + .description = "L1xx Medium-Plus-density", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, .flash_pagesize = 0x100, @@ -169,7 +169,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_L1_HIGH, - .description = "L1 High-density device", + .description = "L1xx High-density", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, .flash_pagesize = 0x100, @@ -189,7 +189,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F1_CONN, - .description = "F1 Connectivity line device", + .description = "F1 Connectivity line", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -199,7 +199,7 @@ static const struct stlink_chipid_params devices[] = { }, {//Low and Medium density VL have same chipid. RM0041 25.6.1 .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, - .description = "F1 Medium/Low-density Value Line device", + .description = "F1xx Value Line", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, @@ -210,7 +210,7 @@ static const struct stlink_chipid_params devices[] = { { // STM32F446x family. Support based on DM00135183.pdf (RM0390) document. .chip_id = STLINK_CHIPID_STM32_F446, - .description = "F446 device", + .description = "F446", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1fff7a22, .flash_pagesize = 0x20000, @@ -221,7 +221,7 @@ static const struct stlink_chipid_params devices[] = { { // STM32F410 MCUs. Support based on DM00180366.pdf (RM0401) document. .chip_id = STLINK_CHIPID_STM32_F410, - .description = "F410 device", + .description = "F410", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1fff7a22, .flash_pagesize = 0x4000, @@ -233,7 +233,7 @@ static const struct stlink_chipid_params devices[] = { // This is STK32F303VCT6 device from STM32 F3 Discovery board. // Support based on DM00043574.pdf (RM0316) document. .chip_id = STLINK_CHIPID_STM32_F3, - .description = "F3 device", + .description = "F3xx", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, @@ -245,7 +245,7 @@ static const struct stlink_chipid_params devices[] = { // This is STK32F373VCT6 device from STM32 F373 eval board // Support based on 303 above (37x and 30x have same memory map) .chip_id = STLINK_CHIPID_STM32_F37x, - .description = "F3 device", + .description = "F3xx", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, @@ -255,7 +255,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F1_VL_HIGH, - .description = "F1 High-density value line device", + .description = "F1xx High-density value line", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -265,7 +265,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F1_XL, - .description = "F1 XL-density device", + .description = "F1xx XL-density", .flash_type = STLINK_FLASH_TYPE_F1_XL, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -277,7 +277,7 @@ static const struct stlink_chipid_params devices[] = { //Use this as an example for mapping future chips: //RM0091 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F0_CAN, - .description = "F07x device", + .description = "F07x", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x800, // Page sizes listed in Table 4 @@ -289,7 +289,7 @@ static const struct stlink_chipid_params devices[] = { //Use this as an example for mapping future chips: //RM0091 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F0, - .description = "F0 device", + .description = "F0xx", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 @@ -301,7 +301,7 @@ static const struct stlink_chipid_params devices[] = { // RM0402 document was used to find these parameters // Table 4. .chip_id = STLINK_CHIPID_STM32_F412, - .description = "F4 device", + .description = "F412", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) .flash_pagesize = 0x4000, // Table 5. Flash module organization ? @@ -313,7 +313,7 @@ static const struct stlink_chipid_params devices[] = { // RM0430 DocID029473 Rev 2 document was used to find these parameters // Figure 2, Table 4, Table 5, Section 35.2 .chip_id = STLINK_CHIPID_STM32_F413, - .description = "F4 device", + .description = "F413", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector sizes, but 0x4000 is smallest) @@ -323,7 +323,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F09X, - .description = "F09X device", + .description = "F09X", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) @@ -335,7 +335,7 @@ static const struct stlink_chipid_params devices[] = { //Use this as an example for mapping future chips: //RM0091 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F04, - .description = "F04x device", + .description = "F04x", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 @@ -347,7 +347,7 @@ static const struct stlink_chipid_params devices[] = { //Use this as an example for mapping future chips: //RM0091 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F0_SMALL, - .description = "F0 small device", + .description = "F0xx small", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 @@ -358,7 +358,7 @@ static const struct stlink_chipid_params devices[] = { { // STM32F30x .chip_id = STLINK_CHIPID_STM32_F3_SMALL, - .description = "F3 small device", + .description = "F3xx small", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, @@ -370,7 +370,7 @@ static const struct stlink_chipid_params devices[] = { // STM32L0x // RM0367,RM0377 documents was used to find these parameters .chip_id = STLINK_CHIPID_STM32_L0, - .description = "L0x3 device", + .description = "L0x3", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, @@ -382,7 +382,7 @@ static const struct stlink_chipid_params devices[] = { // STM32L0x Category 5 // RM0367,RM0377 documents was used to find these parameters .chip_id = STLINK_CHIPID_STM32_L0_CAT5, - .description = "L0x Category 5 device", + .description = "L0xx Category 5", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, @@ -394,7 +394,7 @@ static const struct stlink_chipid_params devices[] = { // STM32L0x Category 2 // RM0367,RM0377 documents was used to find these parameters .chip_id = STLINK_CHIPID_STM32_L0_CAT2, - .description = "L0x Category 2 device", + .description = "L0xx Category 2", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, @@ -406,7 +406,7 @@ static const struct stlink_chipid_params devices[] = { // STM32F334, STM32F303x6/8, and STM32F328 // From RM0364 and RM0316 .chip_id = STLINK_CHIPID_STM32_F334, - .description = "F3xx medium density device", // (RM0316 sec 33.6.1) + .description = "F334 medium density", // (RM0316 sec 33.6.1) .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, @@ -418,7 +418,7 @@ static const struct stlink_chipid_params devices[] = { // This is STK32F303RET6 device from STM32 F3 Nucelo board. // Support based on DM00043574.pdf (RM0316) document rev 5. .chip_id = STLINK_CHIPID_STM32_F303_HIGH, - .description = "F303 high density device", + .description = "F303 high density", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register .flash_pagesize = 0x800, // 4.2.1 Flash memory organization @@ -430,7 +430,7 @@ static const struct stlink_chipid_params devices[] = { // STM32L4x6 // From RM0351. .chip_id = STLINK_CHIPID_STM32_L4, - .description = "L4 device", + .description = "L4xx", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) .flash_pagesize = 0x800, // 2K (sec 3.2, page 78; also appears in sec 3.3.1 and tables 4-6 on pages 79-81) @@ -445,7 +445,7 @@ static const struct stlink_chipid_params devices[] = { // STM32L4RX // From DM00310109.pdf .chip_id = STLINK_CHIPID_STM32_L4RX, - .description = "L4Rx device", + .description = "L4Rx", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 52.2, page 2049) .flash_pagesize = 0x1000, // 4k, section 3.3, pg 97 @@ -457,7 +457,7 @@ static const struct stlink_chipid_params devices[] = { // STLINK_CHIPID_STM32_L41X // From RM0394 Rev 4 and DS12469 Rev 5 .chip_id = STLINK_CHIPID_STM32_L41X, - .description = "L41x device", + .description = "L41x", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, sec 47.2, page 1586) .flash_pagesize = 0x800, // 2K (DS12469, sec 3.4, page 17) @@ -471,7 +471,7 @@ static const struct stlink_chipid_params devices[] = { // STLINK_CHIPID_STM32_L43X // From RM0392. .chip_id = STLINK_CHIPID_STM32_L43X, - .description = "L43x/L44x device", + .description = "L43x/L44x", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) .flash_pagesize = 0x800, // 2K (sec 3.2, page 74; also appears in sec 3.3.1 and tables 7-8 on pages 75-76) @@ -486,7 +486,7 @@ static const struct stlink_chipid_params devices[] = { // STLINK_CHIPID_STM32_L496X // Support based on en.DM00083560.pdf (RM0351) document rev 5. .chip_id = STLINK_CHIPID_STM32_L496X, - .description = "L496x/L4A6x device", + .description = "L496x/L4A6x", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) @@ -500,7 +500,7 @@ static const struct stlink_chipid_params devices[] = { // STLINK_CHIPID_STM32_L46X // From RM0394 (updated version of RM0392?). .chip_id = STLINK_CHIPID_STM32_L46X, - .description = "L45x/46x device", + .description = "L45x/46x", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) .flash_pagesize = 0x800, // 2K (sec 3.2, page 73; also appears in sec 3.3.1 and tables 7 on pages 73-74) @@ -513,7 +513,7 @@ static const struct stlink_chipid_params devices[] = { { // STM32L011 .chip_id = STLINK_CHIPID_STM32_L011, - .description = "L011 device", + .description = "L011", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, @@ -524,7 +524,7 @@ static const struct stlink_chipid_params devices[] = { { // STM32GG030/031/041 (from RM0444) .chip_id = STLINK_CHIPID_STM32_G0_CAT1, - .description = "G030/G031/G041 device", + .description = "G030/G031/G041", .flash_type = STLINK_FLASH_TYPE_G0, .flash_size_reg = 0x1FFF75E0, // Section 38.2 .flash_pagesize = 0x800, // 2K (sec 3.2) @@ -535,7 +535,7 @@ static const struct stlink_chipid_params devices[] = { { // STM32G071/081 (from RM0444) .chip_id = STLINK_CHIPID_STM32_G0_CAT2, - .description = "G070/G071/G081 device", + .description = "G070/G071/G081", .flash_type = STLINK_FLASH_TYPE_G0, .flash_size_reg = 0x1FFF75E0, // Section 38.2 .flash_pagesize = 0x800, // 2K (sec 3.2) @@ -546,7 +546,7 @@ static const struct stlink_chipid_params devices[] = { { // STM32G431/441 (from RM0440) .chip_id = STLINK_CHIPID_STM32_G4_CAT2, - .description = "G4 Category-2 device", + .description = "G4 Category-2", .flash_type = STLINK_FLASH_TYPE_G4, .flash_size_reg = 0x1FFF75E0, // Section 47.2 .flash_pagesize = 0x800, // 2K (sec 3.3.1) @@ -557,7 +557,7 @@ static const struct stlink_chipid_params devices[] = { { // STM32WB55 (from RM0434) .chip_id = STLINK_CHIPID_STM32_WB55, - .description = "WB55 device", + .description = "WB55", .flash_type = STLINK_FLASH_TYPE_WB, .flash_size_reg = 0x1FFF75E0, .flash_pagesize = 0x1000, // 4K diff --git a/src/common.c b/src/common.c index 6226c893b..a6d60c552 100644 --- a/src/common.c +++ b/src/common.c @@ -830,7 +830,9 @@ int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { * @return 0 for success, or -1 for unsupported core type. */ int stlink_load_device_params(stlink_t *sl) { - ILOG("Loading device parameters....\n"); + // This seems to normally work so is unnecessary info for a normal + // user. Demoted to debug. -- REW + DLOG("Loading device parameters....\n"); const struct stlink_chipid_params *params = NULL; stlink_core_id(sl); uint32_t chip_id; @@ -894,11 +896,19 @@ int stlink_load_device_params(stlink_t *sl) { sl->sram_size = 0x1000; } +#if 0 + // Old code -- REW ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); // TODO make note of variable page size here..... ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %u bytes\n", sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, (unsigned int)sl->flash_pgsz); +#else + ILOG("%s: %d KiB SRAM, %d KiB flash in %d %s pages.\n", + params->description, sl->sram_size / 1024, sl->flash_size / 1024, + (sl->flash_pgsz < 1024)? sl->flash_pgsz : sl->flash_pgsz/1024, + (sl->flash_pgsz < 1024)? "byte" : "KiB"); +#endif return 0; } diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index a874a81da..72f676bb2 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -246,8 +246,9 @@ int main(int argc, char** argv) { } - - ILOG("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); + // This is low-level information for debugging, not useful for normal use. + // So: Demoted to a debug meesage. -- REW + DLOG("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); sl->verbose=0; current_memory_map = make_memory_map(sl); diff --git a/src/usb.c b/src/usb.c index 9df9d7296..85f5727a4 100644 --- a/src/usb.c +++ b/src/usb.c @@ -1049,7 +1049,9 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST stlink_version(sl); if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { - ILOG("-- exit_dfu_mode\n"); + // This seems to work, and is unnecessary information for the user. + // Demoted to debug -- REW + DLOG("-- exit_dfu_mode\n"); stlink_exit_dfu_mode(sl); } From d439956cb2ce5222fa8cfaa7992a90f4cef98eae Mon Sep 17 00:00:00 2001 From: Rogier Wolff Date: Sat, 21 Mar 2020 17:34:54 +0100 Subject: [PATCH 0740/1435] now return error in probe when things go bad. --- src/usb.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/usb.c b/src/usb.c index 9df9d7296..8c932e71e 100644 --- a/src/usb.c +++ b/src/usb.c @@ -1069,15 +1069,17 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST } ret = stlink_load_device_params(sl); - -on_libusb_error: if (ret == -1) { - stlink_close(sl); - return NULL; + // This one didn't have any message. + goto on_libusb_error; } - return sl; +on_libusb_error: + stlink_close(sl); + return NULL; + + on_error: if (slu->libusb_ctx) libusb_exit(slu->libusb_ctx); From e49ad2770ede3377cd4865210c6f88a42ce48378 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 21 Mar 2020 21:31:12 +0200 Subject: [PATCH 0741/1435] fix intendation in Version.cmake --- cmake/Version.cmake | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cmake/Version.cmake b/cmake/Version.cmake index 2ca1c0ff8..71859015c 100644 --- a/cmake/Version.cmake +++ b/cmake/Version.cmake @@ -7,15 +7,15 @@ set(__detect_version 0) find_package (Git) if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") - # Working off a git repo, using git versioning - # Check if HEAD is pointing to a tag - execute_process ( - COMMAND "${GIT_EXECUTABLE}" describe --always --tag - WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" - OUTPUT_VARIABLE PROJECT_VERSION + # Working off a git repo, using git versioning + # Check if HEAD is pointing to a tag + execute_process ( + COMMAND "${GIT_EXECUTABLE}" describe --always --tag + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + OUTPUT_VARIABLE PROJECT_VERSION RESULT_VARIABLE GIT_DESCRIBE_RESULT ERROR_VARIABLE GIT_DESCRIBE_ERROR - OUTPUT_STRIP_TRAILING_WHITESPACE) + OUTPUT_STRIP_TRAILING_WHITESPACE) if(GIT_DESCRIBE_RESULT EQUAL 0) # If the sources have been changed locally, add -dirty to the version. From 4df1caf4f4f463b69276136b648c693586896ba1 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 22 Mar 2020 00:47:39 +0100 Subject: [PATCH 0742/1435] Minor fixes in CHANGELOG.md --- CHANGELOG.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6356caf3..586e44206 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ Major changes and added features: * Build for Windows under Debian/Ubuntu ([#802](https://github.com/texane/stlink/pull/802)) * Allow for 64 bytes serials ([#809](https://github.com/texane/stlink/pull/809)) * Added full support for STLINK CHIP ID L4RX ([#814](https://github.com/texane/stlink/pull/814), [#839](https://github.com/texane/stlink/pull/839)) -* Added support for writing option bytes on STM32L0 ([#830](https://github.com/texane/stlink/pull/830)) +* Added support for writing option bytes on STM32L0xx ([#830](https://github.com/texane/stlink/pull/830)) * Added support to read and write option bytes for STM32F2 series ([#836](https://github.com/texane/stlink/pull/836), [#837](https://github.com/texane/stlink/pull/837)) * Added support to read and write option bytes for STM32F446 ([#843](https://github.com/texane/stlink/pull/843)) @@ -62,16 +62,16 @@ Major changes and added features: * Added reset through AIRCR ([#540](https://github.com/texane/stlink/pull/540), [#712](https://github.com/texane/stlink/pull/712)) * Added creation of icons for .desktop file ([#684](https://github.com/texane/stlink/pull/684), [#708](https://github.com/texane/stlink/pull/708)) * Added desktop file for linux ([#688](https://github.com/texane/stlink/pull/688)) -* Added button to export stm32 flash memory to a file ([#691](https://github.com/texane/stlink/pull/691)) +* Added button to export STM32 flash memory to a file ([#691](https://github.com/texane/stlink/pull/691)) * Updated libusb to 1.0.22 ([#695](https://github.com/texane/stlink/pull/695)) -* Added icons for stlink GUI ([#697](https://github.com/texane/stlink/pull/697)) +* Added icons for STLink GUI ([#697](https://github.com/texane/stlink/pull/697)) * Added support for STM32L4R9 target ([#694](https://github.com/texane/stlink/pull/694), [#699](https://github.com/texane/stlink/pull/699)) * Added memory map for STM32F411RE target ([#709](https://github.com/texane/stlink/pull/709)) * Implemented intel hex support for GTK GUI ([#713](https://github.com/texane/stlink/pull/713), [#718](https://github.com/texane/stlink/pull/718)) Updates and fixes: -* Fixed missing flash_loader for L011 ([#356](https://github.com/texane/stlink/pull/356), [#654](https://github.com/texane/stlink/pull/654), [#675](https://github.com/texane/stlink/pull/675)) +* Fixed missing flash_loader for STM32L011 ([#356](https://github.com/texane/stlink/pull/356), [#654](https://github.com/texane/stlink/pull/654), [#675](https://github.com/texane/stlink/pull/675)) * Fix for stlink library calls exit() or _exit() ([#634](https://github.com/texane/stlink/pull/634), [#696](https://github.com/texane/stlink/pull/696)) * Added semihosting parameter documentation in doc/man ([#674](https://github.com/texane/stlink/pull/674)) * Fixed reference to non-exisiting st-term tool in doc/man ([#676](https://github.com/texane/stlink/pull/676)) @@ -81,8 +81,8 @@ Updates and fixes: * Fix for libusb deprecation ([#703](https://github.com/texane/stlink/pull/703), [#704](https://github.com/texane/stlink/pull/704)) * Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX ([#706](https://github.com/texane/stlink/pull/706)) * Regression: stlink installation under Linux (Debian 9) is broken since #695 ([#700](https://github.com/texane/stlink/pull/700), [#701](https://github.com/texane/stlink/pull/701), [#707](https://github.com/texane/stlink/pull/707)) -* Fixed flash memory map for F72xxx target ([#711](https://github.com/texane/stlink/pull/711)) -* Proper flash page size calculation for F412xx target ([#721](https://github.com/texane/stlink/pull/721)) +* Fixed flash memory map for STM32F72xxx target ([#711](https://github.com/texane/stlink/pull/711)) +* Proper flash page size calculation for STM32F412xx target ([#721](https://github.com/texane/stlink/pull/721)) * Return correct value on EOF for Semihosting SYS_READ ([#726](https://github.com/texane/stlink/pull/726), [#727](https://github.com/texane/stlink/pull/727), [#728](https://github.com/texane/stlink/pull/728), [#729](https://github.com/texane/stlink/pull/729), [#730](https://github.com/texane/stlink/pull/730), [#731](https://github.com/texane/stlink/pull/731), [#732](https://github.com/texane/stlink/pull/732)) * FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION ([#733](https://github.com/texane/stlink/pull/733)) @@ -105,7 +105,7 @@ Updates and fixes: * Updated changelog in debian package ([#630](https://github.com/texane/stlink/pull/630)) * Added LIB_INSTALL_DIR to correct libs install on 64-bit systems ([#633](https://github.com/texane/stlink/pull/633), [#636](https://github.com/texane/stlink/pull/636)) * Fixed write for microcontroller with RAM size less or equal to 32K ([#637](https://github.com/texane/stlink/pull/637)) -* Fixed memory map for stm32l496xx boards ([#639](https://github.com/texane/stlink/pull/639)) +* Fixed memory map for STM32L496xx boards ([#639](https://github.com/texane/stlink/pull/639)) * Fixed __FILE__ base name extraction ([#624](https://github.com/texane/stlink/pull/624), [#628](https://github.com/texane/stlink/pull/628), [#648](https://github.com/texane/stlink/pull/648)) * Added debian/triggers to run ldconfig ([#664](https://github.com/texane/stlink/pull/664)) * Fixed build on Fedora with GCC 8 ([#666](https://github.com/texane/stlink/pull/666), [#667](https://github.com/texane/stlink/pull/667), [#668](https://github.com/texane/stlink/pull/668)) @@ -126,7 +126,7 @@ Major changes and added features: Updates and fixes: -* Fixed gdb-server: L0xx has no FP_CTRL register for breakpoints ([#273](https://github.com/texane/stlink/pull/273)) +* Fixed gdb-server: STM32L0xx has no FP_CTRL register for breakpoints ([#273](https://github.com/texane/stlink/pull/273)) * Updated libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) * Fixed low-voltage flashing on STM32F7 devices ([#566](https://github.com/texane/stlink/pull/566), [#567](https://github.com/texane/stlink/pull/567)) * Fixed building with mingw64 ([#569](https://github.com/texane/stlink/pull/569), [#573](https://github.com/texane/stlink/pull/573), [#578](https://github.com/texane/stlink/pull/578), [#584](https://github.com/texane/stlink/pull/584), [#610](https://github.com/texane/stlink/pull/610)) @@ -226,9 +226,9 @@ Features added: Updates and fixes: * Refactoring/fixes of flash loader (Maxime Coquelin) -* Synchronized cache for stm32f7 (Tristan Gingold) +* Synchronized cache for STM32F7 (Tristan Gingold) * Allow flashing of STM32L4 down to 1.71 V (Greg Meiste) -* Fix on stm32l4 to clear flash mass erase flags on CR (Bruno Dal Bo) +* Fix on STM32L4 to clear flash mass erase flags on CR (Bruno Dal Bo) * Proper writing of page 0 of second bank for stm32l476xe (Tobias Badertscher) * Trace the read data in stlink_read_debug32 and not the address of the variable (Tobias Badertscher) * Mac OS X El Capitan platform support confirmation (Nikolay) @@ -238,8 +238,8 @@ Updates and fixes: * Make sure MCU is halted before running RAM based flashloaders (mlundinse) * Could not flash STM32_F3_SMALL (Max Chen) * STM32F4 8-bit support for 1.8v operation (Andy Isaacson) -* Fixed F2 memory map (Nicolas Schodet) -* Memory map for stm32f42xxx and stm32f43xxx devices (Craig Lilley) +* Fixed STM32F2xx memory map (Nicolas Schodet) +* Memory map for STM32F42xxx and STM32F43xxx devices (Craig Lilley) * Stm32l0x flash loader (Robin Kreis) Chip support added for: @@ -247,7 +247,7 @@ Chip support added for: * STM32L053R8 (Jean-Luc Béchennec) * STM32F7 Support (mlundinse) * Added STM32L4 to CHIPID #defines and devices[], flash driver and loader (Dave Vandervies) -* Basic support for F446 (Pavel Kirienko) +* Basic support for STM32F446 (Pavel Kirienko) * STM32F303 High Density * STM32L1xx Cat.2 devices (Nicolas Schodet) From 10ae5294cd03aacfc07312010f026d3cb12ea56c Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 23 Mar 2020 19:11:18 +0100 Subject: [PATCH 0743/1435] Updated /doc/compiling.md (Closes #113) - Added note on correct libusb version. - Formatting improvements - Corrections to grammar and wording --- doc/compiling.md | 151 +++++++++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 65 deletions(-) diff --git a/doc/compiling.md b/doc/compiling.md index 61bb12e6e..2728c153b 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -1,12 +1,11 @@ # Compiling from sources +## General package requirements -## Package requirements - -* CMake (v2.8.7 or later) +* cmake (v2.8.7 or later) * C compiler (gcc, clang or mingw) -* libusb 1.0 (v1.0.13 or later) -* libusb-dev 1.0 (v1.0.13 or later) -* (optional) pandoc for generating manpages from markdown +* libusb-1.0 (v1.0.13 or later) +* libusb-dev-1.0 (v1.0.13 or later) +* pandoc _(optional; for generating manpages from markdown)_ Run from the root of the source directory: @@ -15,8 +14,7 @@ $ make release $ make debug ``` -The debug target should only be necessary for people who want - to modify the sources and run under a debugger. +The debug target should only be necessary for people who want to modify the sources and run under a debugger. The top level Makefile is just a handy wrapper for: ``` @@ -25,83 +23,100 @@ $ cmake -DCMAKE_BUILD_TYPE=Debug .. $ make ``` -You could install to a user folder e.g `$HOME`: +You may install to a user folder e.g `$HOME`: ``` $ cd build/Release; make install DESTDIR=$HOME ``` -Or system wide: +Or system-wide: ``` $ cd build/Release; sudo make install ``` -## Linux +## Linux / Unix ## Common requirements -* Debian based distros (debian, ubuntu) - * `build-essential` +* `build-essential` * `cmake` -* `libusb-1.0` (plus development headers for building, on debian based distros `libusb-1.0-0-dev` package) -* (optional) for `stlink-gui` we need libgtk-3-dev +* `libusb-1.0` +* `libusb-1.0-0-dev` (development headers for building, _only on debian based distros_) +* `libgtk-3-dev` _(optional; required for `stlink-gui`)_ + +As of today several distributions namely: + +- CentOS 6, 7, 8 +- Debian 8, 9, 10, sid +- Fedora 30, 31, Rawhide +- NetBSD 7.2, 8.1, 9.0 +- openSUSE Leap 15.1, Leap 15.2 +- Ubuntu 14.04 LTS, 16.04 LTS, 18.04 LTS, 19.10 + +provide packages for libusb 0.1 and libusb 1.0. + +**Please ensure that the correct version 1.0 is installed.** +Other relevant distributions appear to have packages named _libusb-compat-0.1_ or alike to distinguish from libusb packages based on version 1.0.x. + ### Fixing cannot open shared object file When installing system-wide (`sudo make install`) the dynamic library cache needs to be updated with the command `ldconfig`. + ## Permissions with udev -Make sure you install udev files which are necessary to run the tools without root - permissions. By default most distributions don't allow access to USB devices. The - udev rules create devices nodes and set the group of this to `stlink. +Make sure you install udev files which are necessary to run the tools without root permissions. +By default most distributions don't allow access to USB devices. +The udev rules create devices nodes and set the group of this to `stlink`. -The rules are located in the `etc/udev/rules.d` directory. You will need to copy it -to /etc/udev/rules.d, and then either execute as root (or reboot your machine): +The rules are located in the `etc/udev/rules.d` directory. +You will need to copy it to /etc/udev/rules.d, and then either execute as root (or reboot your machine): ``` $ udevadm control --reload-rules $ udevadm trigger ``` -Udev will now create device node files `/dev/stlinkv2_XX`, `/dev/stlinkv1_XX`. You must - make sure the `stlink` group exists and the user who is trying to access is added - to this group. +Udev will now create device node files `/dev/stlinkv2_XX`, `/dev/stlinkv1_XX`. +**You need to make sure the `stlink` group exists and the user, who is trying to access, is added to this group.** + ### Note for STLINKv1 usage -The STLINKv1's SCSI emulation is very broken, so the best thing to do -is tell your operating system to completely ignore it. +The STLINKv1's SCSI emulation is corrupted, so the best thing to do is tell your operating system to completely ignore it. Options (do one of these before you plug it in) -* `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` -* or 1. `echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.conf` -* 2. `modprobe -r usb-storage && modprobe usb-storage` -* or 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` -* 2. `modprobe -r usb-storage && modprobe usb-storage` +* `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` or + 1. `echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.conf` + 2. `modprobe -r usb-storage && modprobe usb-storage` +* or + 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` + 2. `modprobe -r usb-storage && modprobe usb-storage` + ### Build Debian Package -To build the debian package you need the following extra packages: `devscripts debhelper`. +To build the debian package you need the additional packages `devscripts` and `debhelper`. ``` $ git archive --prefix=$(git describe)/ HEAD | bzip2 --stdout > ../libstlink_$(sed -En -e "s/.*\((.*)\).*/\1/" -e "1,1 p" debian/changelog).orig.tar.bz2 $ debuild -uc -us ``` -## Mac OS X + +## macOS +### Prerequisites When compiling on a mac you need the following: * A compiler toolchain (XCode) -* CMake -* Libusb 1.0 +* cmake +* **libusb 1.0** -The best way is to install [homebrew](http://brew.sh) which is a package manager - for opensource software which is missing from the Apple App Store. Then install - the dependencies: +The best way is to install [homebrew](http://brew.sh) which is a package manager for opensource software which is missing from the Apple App Store. Then install the dependencies: ``` brew install libusb cmake @@ -109,92 +124,98 @@ brew install libusb cmake Compile as described in the first section of this document. + ## Build using different directories for udev and modprobe -To put the udev or the modprobe configuration files into a different directory -during installation you can use the following cmake options: +To put the udev or the modprobe configuration files into a different directory during installation use the following cmake options: ``` $ cmake -DSTLINK_UDEV_RULES_DIR="/usr/lib/udev/rules.d" \ -DSTLINK_MODPROBED_DIR="/usr/lib/modprobe.d" .. ``` + ## Build using different directory for shared libs -To put the compiled shared libs into a different directory during installation -you can use the following cmake option: +To put the compiled shared libs into a different directory during installation you can use the following cmake option: ``` -$ cmake -DLIB_INSTALL_DIR:PATH="/usr/lib64" .. +$ cmake -DLIB_INSTALL_DIR:PATH="/usr/lib64" .. ``` -## Windows (MinGW64) -### Prequistes +## Windows (MinGW64) +### Prerequisites -* 7Zip -* CMake 2.8 or higher +* 7zip +* cmake 2.8 or higher * MinGW64 GCC toolchain (5.3.0) + ### Installation -1. Install 7Zip from +1. Install 7zip from 2. Install CMake from 3. Install MinGW64 from (mingw-w64-install.exe) 4. Git clone or download stlink sourcefiles zip + ### Building Check and execute (in the script folder) `\scripts\mingw64-build.bat` -NOTE: when installing different toolchains make sure you edit the path in the `mingw64-build.bat` - the build script uses currently `C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin` +**NOTE:** when installing different toolchains make sure you edit the path in the `mingw64-build.bat`. +The build script currently uses `C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin` -## Windows (Visual Studio) +## Windows (Visual Studio) ### Prerequisites -* 7Zip -* CMake (tested with version 3.9.0-rc2) -* Visual Studio 2017 Community (other versions will likely work but are untested; the Community edition is free for open source +* 7zip +* cmake (tested with version 3.9.0-rc2) +* Visual Studio 2017 Community Edition (other versions will likely work but are untested; the Community Edition is free for open source development) + ### Installation -1. Install 7Zip from +1. Install 7zip from 2. Install CMake from 3. Git clone or download stlink sourcefiles zip + ### Building -These instructions are for a 32bit version. +These instructions are for a 32-bit version. In a command prompt, change directory to the folder where the stlink files were cloned (or unzipped). Make sure the build folder exists (`mkdir build` if not). From the build folder, run cmake (`cd build; cmake ..`). -This will create a solution (stlink.sln) in the build folder. Open it in Visual Studio, select the Solution Configuration (Debug or -Release) and build the solution normally (F7). +This will create a solution (stlink.sln) in the build folder. +Open it in Visual Studio, select the Solution Configuration (_Debug_ or _Release_) and build the solution normally (F7). -NOTES: This solution will link to the dll version of libusb-1.0. To debug or run the executable, the dll version of libusb-1.0 must -be either on the path, or in the same folder as the executable. It can be copied from here: -`build\3thparty\libusb-1.0.21\MS32\dll\libusb-1.0.dll`. +NOTES: This solution will link to the dll version of libusb-1.0. +To debug or run the executable, the dll version of libusb-1.0 must be either on the path, or in the same folder as the executable. +It can be copied from here: `build\3thparty\libusb-1.0.21\MS32\dll\libusb-1.0.dll`. -## Linux (MinGW64) -### Prequistes +## Linux (MinGW64) +### Prerequisites -* 7Zip -* CMake 2.8 or higher +* 7zip +* cmake 2.8 or higher * MinGW64 GCC toolchain (5.3.0) + ### Installation (Debian / Ubuntu) sudo apt install p7zip mingw-w64 + ### Building -These instructions are for a 32bit version. +These instructions are for a 32-bit version. ```sh cd From e3c76aa67315db32bd303303023d6c74c51e900b Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 24 Mar 2020 02:21:03 +0100 Subject: [PATCH 0744/1435] Removed deprecated LIBUSBX_API Closes #211 #782. See also #733. --- src/sg.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/sg.c b/src/sg.c index 8fa351cf6..8633b1d4d 100644 --- a/src/sg.c +++ b/src/sg.c @@ -936,15 +936,6 @@ static stlink_t* stlink_open(const int verbose) { return NULL; } -#if defined (__FreeBSD__) - #define LIBUSBX_API_VERSION LIBUSB_API_VERSION -#endif -#if LIBUSBX_API_VERSION < 0x01000106 - libusb_set_debug(slsg->libusb_ctx, 3); -#else - libusb_set_option(slsg->libusb_ctx, LIBUSB_OPTION_LOG_LEVEL, 3); -#endif - slsg->usb_handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, STLINK_USB_VID_ST, STLINK_USB_PID_STLINK); if (slsg->usb_handle == NULL) { WLOG("Failed to find an stlink v1 by VID:PID\n"); From c3f2b6b9714493b7d1d7a078b180b90db586c7a9 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 24 Mar 2020 13:33:32 +0100 Subject: [PATCH 0745/1435] Update for README.md - Updated "known missing features" - Removed section "known bugs" Note: Users should use the github ticket system to submit failures instead, otherwise they may not be fixed. --- README.md | 50 +------------------------------------------------- 1 file changed, 1 insertion(+), 49 deletions(-) diff --git a/README.md b/README.md index 6a6fd4ae3..0219d0d7f 100644 --- a/README.md +++ b/README.md @@ -88,57 +88,9 @@ Some features are currently missing from the `texane/stlink` toolset. Here we would appreciate any help and would love to welcome new contributors who want to get involved: * Instrumentation Trace Macro (ITM) Cell ([#136](https://github.com/texane/stlink/issues/136)) -* OTP area programming ([#202](https://github.com/texane/stlink/issues/202)) -* EEPROM area programming ([#318](https://github.com/texane/stlink/issues/218)) +* OTP & EEPROM area programming ([#202](https://github.com/texane/stlink/issues/202), [#333](https://github.com/texane/stlink/issues/333), [#686](https://github.com/texane/stlink/issues/686)) * Protection bits area reading ([#346](https://github.com/texane/stlink/issues/346)) * Writing external memory connected to an STM32 controller (e.g Quad SPI NOR flash) ([#412](https://github.com/texane/stlink/issues/412)) * MCU hotplug ([#449](https://github.com/texane/stlink/issues/449)) * Writing options bytes (region) ([#458](https://github.com/texane/stlink/issues/458)) -* Control programming speed ([#462](https://github.com/texane/stlink/issues/462)) * Support for STLINKv3 programmer ([#820](https://github.com/texane/stlink/issues/820)) - - -## Known bugs -### Sometimes flashing only works after a mass erase - -There is seen a problem sometimes where a flash loader run error occurs and is resolved after mass-erase of the flash: - -``` -2015-12-09T22:01:57 INFO src/stlink-common.c: Successfully loaded flash loader in sram -2015-12-09T22:02:18 ERROR src/stlink-common.c: flash loader run error -2015-12-09T22:02:18 ERROR src/stlink-common.c: run_flash_loader(0x8000000) failed! == -1 -``` - -Issue related to this bug: [#356](https://github.com/texane/stlink/issues/356) - - -### Flash size is detected as zero bytes size - -It is possible that the STM32 flash is write protected, the st-flash tool will show something like this: - -``` -st-flash write prog.bin 0x8000000 -2017-01-24T18:44:14 INFO src/stlink-common.c: Loading device parameters.... -2017-01-24T18:44:14 INFO src/stlink-common.c: Device connected is: F1 High-density device, id 0x10036414 -2017-01-24T18:44:14 INFO src/stlink-common.c: SRAM size: 0x10000 bytes (64 KiB), Flash: 0 bytes (0 KiB) in pages of 2048 bytes -``` - -As you can see, it gives out something unexpected like -``` -Flash: 0 bytes (0 KiB) in pages of 2048 bytes -``` - -``` -st-info --probe -Found 1 stlink programmers - serial: 303030303030303030303031 -openocd: "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x31" - flash: 0 (pagesize: 2048) - sram: 65536 - chipid: 0x0414 - descr: F1 High-density device -``` - -Try to remove the write protection (probably only possible with ST Link Utility from ST itself). - -Issue related to this bug: [#545](https://github.com/texane/stlink/issues/545) From c783d0e777ccc83a7a8be26a4f4d3414e0478560 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 24 Mar 2020 17:09:14 +0100 Subject: [PATCH 0746/1435] Refactoring for tool "st-info" - Resorted cmds to the order they appear. --- doc/man/st-info.md | 30 +++++++++++++++--------------- src/tools/info.c | 38 +++++++++++++++++++------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/doc/man/st-info.md b/doc/man/st-info.md index 67d9373d7..ca2579785 100644 --- a/doc/man/st-info.md +++ b/doc/man/st-info.md @@ -12,7 +12,7 @@ st-info - Provides information about connected STLink and STM32 devices # DESCRIPTION Provides information about connected STLink programmers and STM32 devices: -Serial code, openocd, flash, sram, page size, chipid, description. +Serial code, OpenOCD hla-serial, flash, page size, sram, chipid, description. # OPTIONS @@ -20,29 +20,29 @@ Serial code, openocd, flash, sram, page size, chipid, description. \--version : Print version information -\--flash -: Display amount of flash memory available in the device +\--probe +: Display the summarized information of the connected programmers and devices -\--sram -: Display amount of sram memory available in device +\--serial +: Display the serial code of the device -\--descr -: Display textual description of the device +\--hla-serial +: Display the hex escaped serial code of the device + +\--flash +: Display amount of flash memory available in the device \--pagesize : Display the page size of the device +\--sram +: Display amount of sram memory available in device + \--chipid : Display the chip ID of the device -\--serial -: Display the serial code of the device - -\--hla-serial -: Display the hex escaped serial code of the device - -\--probe -: Display the summarized information of the connected programmers and devices +\--descr +: Display textual description of the device # EXAMPLES diff --git a/src/tools/info.c b/src/tools/info.c index 2ad8f2c09..3ebbba8de 100644 --- a/src/tools/info.c +++ b/src/tools/info.c @@ -8,14 +8,14 @@ static void usage(void) { puts("st-info --version"); + puts("st-info --probe"); + puts("st-info --serial"); + puts("st-info --hla-serial"); puts("st-info --flash"); - puts("st-info --sram"); - puts("st-info --descr"); puts("st-info --pagesize"); + puts("st-info --sram"); puts("st-info --chipid"); - puts("st-info --serial"); - puts("st-info --hla-serial"); - puts("st-info --probe"); + puts("st-info --descr"); } /* Print normal or OpenOCD hla_serial with newline */ @@ -45,20 +45,20 @@ static void stlink_print_info(stlink_t *sl) if (!sl) return; - printf(" serial: "); + printf(" serial: "); stlink_print_serial(sl, false); - printf("openocd: "); + printf(" hla-serial: "); stlink_print_serial(sl, true); - printf(" flash: %u (pagesize: %u)\n", - (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz); + printf(" flash: %u (pagesize: %u)\n", + (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz); - printf(" sram: %u\n", (unsigned int)sl->sram_size); - printf(" chipid: 0x%.4x\n", sl->chip_id); + printf(" sram: %u\n", (unsigned int)sl->sram_size); + printf(" chipid: 0x%.4x\n", sl->chip_id); params = stlink_chipid_get_params(sl->chip_id); if (params) - printf(" descr: %s\n", params->description); + printf(" descr: %s\n", params->description); } static void stlink_probe(void) @@ -113,18 +113,18 @@ static int print_data(char **av) if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); - if (strcmp(av[1], "--flash") == 0) + if (strcmp(av[1], "--serial") == 0) + stlink_print_serial(sl, false); + else if (strcmp(av[1], "--hla-serial") == 0) + stlink_print_serial(sl, true); + else if (strcmp(av[1], "--flash") == 0) printf("0x%x\n", (unsigned int)sl->flash_size); - else if (strcmp(av[1], "--sram") == 0) - printf("0x%x\n", (unsigned int)sl->sram_size); else if (strcmp(av[1], "--pagesize") == 0) printf("0x%x\n", (unsigned int)sl->flash_pgsz); + else if (strcmp(av[1], "--sram") == 0) + printf("0x%x\n", (unsigned int)sl->sram_size); else if (strcmp(av[1], "--chipid") == 0) printf("0x%.4x\n", sl->chip_id); - else if (strcmp(av[1], "--serial") == 0) - stlink_print_serial(sl, false); - else if (strcmp(av[1], "--hla-serial") == 0) - stlink_print_serial(sl, true); else if (strcmp(av[1], "--descr") == 0) { const struct stlink_chipid_params *params = stlink_chipid_get_params(sl->chip_id); if (params == NULL) From 562cd2496e696dbd22950925866aac662d81ee5f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 24 Mar 2020 19:00:49 +0100 Subject: [PATCH 0747/1435] Refactoring for tool "st-flash" - Fixed formatting for options display. --- src/tools/flash.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/tools/flash.c b/src/tools/flash.c index f87b65940..82b5c349e 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -29,17 +29,17 @@ static void cleanup(int signum) { static void usage(void) { - puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--format ] [--flash=] {read|write} /dev/sgX "); - puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); - puts("stlinkv2/3 command line: ./st-flash [--debug] [--reset] [--serial ] [--format ] [--flash=] {read|write} "); - puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] erase"); - puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] reset"); - puts(" Use hex format for addr, and ."); - puts(" fsize: Use decimal, octal or hex by prefix 0xXXX for hex, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); - puts(" Format may be 'binary' (default) or 'ihex', although must be specified for binary format only."); - puts(" ./st-flash [--version]"); + puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--format ] [--flash=] {read|write} /dev/sgX "); + puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); + puts("stlinkv2/3 command line: ./st-flash [--debug] [--reset] [--serial ] [--format ] [--flash=] {read|write} "); + puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] erase"); + puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] reset"); + puts(" , and : Use hex format."); + puts(" : Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); + puts(" : Can be 'binary' (default) or 'ihex', although must be specified for binary format only."); + puts("print tool version info: ./st-flash [--version]"); puts("example write option byte: ./st-flash --debug --reset --area=option write 0xXXXXXXXX"); - puts("example read option byte: ./st-flash --debug --reset --area=option read > option_byte"); + puts("example read option byte: ./st-flash --debug --reset --area=option read > option_byte"); } int main(int ac, char** av) From a09ef54cf53f0e8c194ef33c49dfe96622e5c127 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 24 Mar 2020 21:11:38 +0100 Subject: [PATCH 0748/1435] General Project Update - Whitespace cleanup - Recycled content of old wiki page. --- README.md | 1 + doc/tutorial.md | 98 +++++++++++++++++++++++++++++++ doc/wiki_old.md | 108 ----------------------------------- include/stlink/tools/flash.h | 1 - src/common.c | 10 ++-- src/tools/flash.c | 6 +- src/tools/flash_opts.c | 22 +------ 7 files changed, 111 insertions(+), 135 deletions(-) delete mode 100644 doc/wiki_old.md diff --git a/README.md b/README.md index 0219d0d7f..b26a147e9 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ Currently known working combinations of programmers and targets are listed in [d **Windows**: download [v1.6.0](https://github.com/texane/stlink/releases/tag/v1.6.0) from the releases page. +Windows pre-compiled binaries are available at http://www.emb4fun.de/archive/stlink/index.html (outdated, not recommended for use) **macOS**: install [from homebrew](http://brewformulas.org/Stlink) or download [v1.6.0](https://github.com/texane/stlink/releases/tag/v1.6.0) from the releases page. diff --git a/doc/tutorial.md b/doc/tutorial.md index af4bae849..100d9a641 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -276,6 +276,42 @@ Example to read and write option bytes (currently writing only supported for STM ./st-flash --debug --reset --format binary --flash=128k write option_bytes_dump.bin 0x1FFF7800 ``` +## Installation of openOCD on Mac OS X with STlink-v2: + +`sudo port install openocd +jlink +stlink +ft2232` + +`/opt/local/bin/openocd --version` + +> Open On-Chip Debugger 0.7.0 (2014-08-11-22:12) + +`openocd -f /opt/local/share/openocd/scripts/interface/stlink-v2.cfg -f /opt/local/share/openocd/scripts/target/stm32f1x_stlink.cfg ` + +> Open On-Chip Debugger 0.8.0 (2014-08-11-15:36) +> +> Licensed under GNU GPL v2 +> +> For bug reports, read http://openocd.sourceforge.net/doc/doxygen/bugs.html +> +> Info : This adapter doesn't support configurable speed +> +> Info : STLINK v2 JTAG v21 API v2 SWIM v4 VID 0x0483 PID 0x3748 +> +> Info : using stlink api v2 +> +> Info : Target voltage: 3.244269 +> +> Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints + +and connecting to the server through telnet yields a successful installation + +`telnet localhost 4444` + +> Connected to localhost. +> +> Escape character is '^]'. +> +> Open On-Chip Debugger + FAQ === @@ -292,6 +328,68 @@ Q: Load command does not work in GDB. A: Some people report XML/EXPAT is not enabled by default when compiling GDB. Memory map parsing thus fail. Use --enable-expat. +Q: How can I install stlink and flash binaries on Mac OS X ? + +A: Installed on Mac OS X 10.9.4 with ports method, + however STlink v2 does not seem to work with libusb if you upgrade to the newest firmware !! + Only older firmware on STlink v2 works. + +[https://coderwall.com/p/oznj_q](https://coderwall.com/p/oznj_q) + +`sudo port install libusb automake autoconf pkgconfig` + +`aclocal --force -I /opt/local/share/aclocal` + +`git clone https://github.com/texane/stlink.git stlink-utility` + +`cd stlink-utility` + +`./autogen.sh` + +`./configure` + +`make` + +Then trying to flash the image with STLINK v2 : + +`./st-flash write ~/Downloads/irq.bin 0x8000000` + +> libusb_handle_events() timeout +> +> [!] send_recv + +ST-Link/V2 debugger with downgraded V2.14.3 firmware: + +https://drive.google.com/folderview?id=0Bzv7UpKpOQhnbXJVVEg4VUo2M1k + +After downgrading the firmware, flashing works as described here: + +http://community.spark.io/t/how-to-flash-a-brand-new-freshly-soldered-stm32f103-chip/3906 + +`./st-flash write ~/Downloads/irq.bin 0x8000000` + +> 2014-08-11T23:14:52 INFO src/stlink-common.c: Loading device parameters.... +> +> 2014-08-11T23:14:52 INFO src/stlink-common.c: Device connected is: F1 Medium-density device, id 0x20036410 +> +> 2014-08-11T23:14:52 INFO src/stlink-common.c: SRAM size: 0x5000 bytes (20 KiB), Flash: 0x20000 bytes (128 KiB) in +> pages of 1024 bytes +> +> 2014-08-11T23:14:52 INFO src/stlink-common.c: Attempting to write 24904 (0x6148) bytes to stm32 address: 134217728 +> (0x8000000) +> +> Flash page at addr: 0x08006000 erased +> +> 2014-08-11T23:14:53 INFO src/stlink-common.c: Finished erasing 25 pages of 1024 (0x400) bytes +> +> 2014-08-11T23:14:53 INFO src/stlink-common.c: Starting Flash write for VL/F0 core id +> +> 2014-08-11T23:14:53 INFO src/stlink-common.c: Successfully loaded flash loader in sram 24/24 pages written +> +> 2014-08-11T23:14:54 INFO src/stlink-common.c: Starting verification of write complete +> +> 2014-08-11T23:14:54 INFO src/stlink-common.c: Flash written and verified! jolly good! + Notes ===== diff --git a/doc/wiki_old.md b/doc/wiki_old.md deleted file mode 100644 index 81e70a277..000000000 --- a/doc/wiki_old.md +++ /dev/null @@ -1,108 +0,0 @@ -Welcome to the stlink wiki! (Archived: 2014-08-11) - -Misc: -Windows pre-compiled binaries are available at http://www.emb4fun.de/archive/stlink/index.html - -FAQ: -Q: Where can I get help? Is there a forum or maybe a mailing list? - -A: todo - -Q: How can I install stlink and flash binaries on Mac OS X ? - -A: **20140811: ** installed on Mac OS X 10.9.4 with ports method, however STlink v2 does not seem to work with libusb if you upgrade to the newest firmware !! Only older firmware on STlink v2 works. - -[https://coderwall.com/p/oznj_q](https://coderwall.com/p/oznj_q) - -`sudo port install libusb automake autoconf pkgconfig` - -`aclocal --force -I /opt/local/share/aclocal` - -`git clone https://github.com/texane/stlink.git stlink-utility` - -`cd stlink-utility` - -`./autogen.sh` - -`./configure` - -`make` - - -Then trying to flash the image with STLINK v2 : - -`./st-flash write ~/Downloads/irq.bin 0x8000000` - -> libusb_handle_events() timeout -> -> [!] send_recv - -After downgrading the firmware, flashing works -ST-Link/V2 debugger with downgraded V2.14.3 firmware: - -https://drive.google.com/folderview?id=0Bzv7UpKpOQhnbXJVVEg4VUo2M1k - -as described here: - -http://community.spark.io/t/how-to-flash-a-brand-new-freshly-soldered-stm32f103-chip/3906 - -`./st-flash write ~/Downloads/irq.bin 0x8000000` - -> 2014-08-11T23:14:52 INFO src/stlink-common.c: Loading device parameters.... -> -> 2014-08-11T23:14:52 INFO src/stlink-common.c: Device connected is: F1 Medium-density device, id 0x20036410 -> -> 2014-08-11T23:14:52 INFO src/stlink-common.c: SRAM size: 0x5000 bytes (20 KiB), Flash: 0x20000 bytes (128 KiB) in -> pages of 1024 bytes -> -> 2014-08-11T23:14:52 INFO src/stlink-common.c: Attempting to write 24904 (0x6148) bytes to stm32 address: 134217728 -> (0x8000000) -> -> Flash page at addr: 0x08006000 erased -> -> 2014-08-11T23:14:53 INFO src/stlink-common.c: Finished erasing 25 pages of 1024 (0x400) bytes -> -> 2014-08-11T23:14:53 INFO src/stlink-common.c: Starting Flash write for VL/F0 core id -> -> 2014-08-11T23:14:53 INFO src/stlink-common.c: Successfully loaded flash loader in sram 24/24 pages written -> -> 2014-08-11T23:14:54 INFO src/stlink-common.c: Starting verification of write complete -> -> 2014-08-11T23:14:54 INFO src/stlink-common.c: Flash written and verified! jolly good! - - -Installation of openOCD on Mac OS X with STlink-v2 has been successful: - -`sudo port install openocd +jlink +stlink +ft2232` - -`/opt/local/bin/openocd --version` - -> Open On-Chip Debugger 0.7.0 (2014-08-11-22:12) - -`openocd -f /opt/local/share/openocd/scripts/interface/stlink-v2.cfg -f /opt/local/share/openocd/scripts/target/stm32f1x_stlink.cfg ` - -> Open On-Chip Debugger 0.8.0 (2014-08-11-15:36) -> -> Licensed under GNU GPL v2 -> -> For bug reports, read http://openocd.sourceforge.net/doc/doxygen/bugs.html -> -> Info : This adapter doesn't support configurable speed -> -> Info : STLINK v2 JTAG v21 API v2 SWIM v4 VID 0x0483 PID 0x3748 -> -> Info : using stlink api v2 -> -> Info : Target voltage: 3.244269 -> -> Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints - -and connecting to the server through telnet yields a successful installation - -`telnet localhost 4444` - -> Connected to localhost. -> -> Escape character is '^]'. -> -> Open On-Chip Debugger diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index 8ca1eddf9..a73d7aee4 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -31,4 +31,3 @@ struct flash_opts int flash_get_opts(struct flash_opts* o, int ac, char** av); #endif // STLINK_FLASH_H_ - diff --git a/src/common.c b/src/common.c index 134921341..913d70e35 100644 --- a/src/common.c +++ b/src/common.c @@ -904,9 +904,9 @@ int stlink_load_device_params(stlink_t *sl) { sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, (unsigned int)sl->flash_pgsz); #else - ILOG("%s: %d KiB SRAM, %d KiB flash in %d %s pages.\n", - params->description, sl->sram_size / 1024, sl->flash_size / 1024, - (sl->flash_pgsz < 1024)? sl->flash_pgsz : sl->flash_pgsz/1024, + ILOG("%s: %d KiB SRAM, %d KiB flash in %d %s pages.\n", + params->description, sl->sram_size / 1024, sl->flash_size / 1024, + (sl->flash_pgsz < 1024)? sl->flash_pgsz : sl->flash_pgsz/1024, (sl->flash_pgsz < 1024)? "byte" : "KiB"); #endif return 0; @@ -1905,7 +1905,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) /* clear the pg bit */ clear_flash_cr_pg(sl); - + /* set the page erase bit */ set_flash_cr_per(sl); @@ -2855,7 +2855,7 @@ static int stlink_write_option_bytes_l1(stlink_t *sl, uint8_t* base, stm32_addr_ stlink_read_debug32(sl, addr+4, &val); WLOG("2nd option bytes is 0x%08x\n",val); } - } + } /* Reload options */ stlink_read_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); diff --git a/src/tools/flash.c b/src/tools/flash.c index 82b5c349e..e1e9f41f6 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -164,7 +164,9 @@ int main(int ac, char** av) goto on_error; } } - else if (o.addr == STM32_G0_OPTION_BYTES_BASE || o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE || o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE + 4){ + else if (o.addr == STM32_G0_OPTION_BYTES_BASE || + o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE || + o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE + 4){ err = stlink_fwrite_option_bytes(sl, o.filename, o.addr); if (err == -1) { @@ -219,7 +221,7 @@ int main(int ac, char** av) err = stlink_read_option_bytes_f4(sl,&option_byte); printf("%x\n",option_byte); }else{ - printf("This format is available for STM32F2 and STM32F4 Only\n"); + printf("This format is available for STM32F2 and STM32F4 only\n"); } }else{ if ((o.addr >= sl->flash_base) && (o.size == 0) && diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 3f74ac057..ef41601a5 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -6,22 +6,19 @@ static bool starts_with(const char * str, const char * prefix) { size_t n = strlen(prefix); - if(strlen(str) < n) return false; + if (strlen(str) < n) return false; return (0 == strncmp(str, prefix, n)); } -int flash_get_opts(struct flash_opts* o, int ac, char** av) -{ +int flash_get_opts(struct flash_opts* o, int ac, char** av) { bool serial_specified = false; // defaults - memset(o, 0, sizeof(*o)); o->log_level = STND_LOG_LEVEL; // options - while(ac >= 1) { if (strcmp(av[0], "--version") == 0) { printf("v%s\n", STLINK_VERSION); @@ -44,18 +41,15 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) else { serial = av[0] + strlen("--serial="); } - /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ int j = (int)strlen(serial); - int length = j / 2; //the length of the destination-array + int length = j / 2; // the length of the destination-array if(j % 2 != 0) return -1; - for(size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { char buffer[3] = {0}; memcpy(buffer, serial + j, 2); o->serial[length - k] = (uint8_t)strtol(buffer, NULL, 16); } - serial_specified = true; } else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { @@ -92,7 +86,6 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) else { format = av[0] + strlen("--format="); } - if (strcmp(format, "binary") == 0) o->format = FLASH_FORMAT_BINARY; else if (strcmp(format, "ihex") == 0) @@ -132,7 +125,6 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) } // command and (optional) device name - while(ac >= 1) { // looks like for stlinkv1 the device name and command may be swaped - check both positions in all cases if (strcmp(av[0], "erase") == 0) { if (o->cmd != FLASH_CMD_NONE) return -1; @@ -174,32 +166,26 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) case FLASH_CMD_READ: // expect filename, addr and size if((o->area == FLASH_OPTION_BYTES) &&(ac == 0)) break; if (ac != 3) return -1; - o->filename = av[0]; o->addr = (uint32_t) strtoul(av[1], &tail, 16); if(tail[0] != '\0') return -1; - o->size = strtoul(av[2], &tail, 16); if(tail[0] != '\0') return -1; - break; case FLASH_CMD_WRITE: if(o->area == FLASH_OPTION_BYTES){ if(ac != 1) return -1; - o->val = (uint32_t)strtoul(av[0], &tail, 16); } else if(o->format == FLASH_FORMAT_BINARY) { // expect filename and addr if (ac != 2) return -1; - o->filename = av[0]; o->addr = (uint32_t) strtoul(av[1], &tail, 16); if(tail[0] != '\0') return -1; } else if(o->format == FLASH_FORMAT_IHEX) { // expect filename if (ac != 1) return -1; - o->filename = av[0]; } else { @@ -211,9 +197,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) } // some constistence checks - if(serial_specified && o->devname != NULL) return -1; // serial not supported for v1 return 0; } - From 49f887d5247fdd28f163b6317790c4f087e652cc Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Wed, 25 Mar 2020 11:55:44 +0200 Subject: [PATCH 0749/1435] setting up a libusb log level accordingly to verbosity. --- include/stlink.h | 5 +++-- include/stlink/logging.h | 1 + src/logging.c | 21 +++++++++++++++++++++ src/sg.c | 6 ++++++ src/usb.c | 6 ++++++ 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index a69e357b5..f7eb9c69a 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -168,8 +168,8 @@ typedef struct flash_loader { size_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() // bootloader - // sys_base and sys_size are not used by the tools, but are only there to - // download the bootloader code (see tests/sg.c) + // sys_base and sys_size are not used by the tools, but are only there to + // download the bootloader code (see tests/sg.c) stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() size_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() @@ -243,6 +243,7 @@ typedef struct flash_loader { #include "stlink/chipid.h" #include "stlink/flash_loader.h" #include "stlink/version.h" +#include "stlink/logging.h" #ifdef __cplusplus } diff --git a/include/stlink/logging.h b/include/stlink/logging.h index da5f7d19d..1083b2c55 100644 --- a/include/stlink/logging.h +++ b/include/stlink/logging.h @@ -18,6 +18,7 @@ enum ugly_loglevel { int ugly_init(int maximum_threshold); int ugly_log(int level, const char *tag, const char *format, ...); +int ugly_libusb_log_level(enum ugly_loglevel v); #define UGLY_LOG_FILE (strstr(__FILE__, "/") != NULL ? \ strrchr(__FILE__, '/') + 1 : strstr(__FILE__, "\\") != NULL ? \ diff --git a/src/logging.c b/src/logging.c index d4fb96b2e..59c2ea298 100644 --- a/src/logging.c +++ b/src/logging.c @@ -54,3 +54,24 @@ int ugly_log(int level, const char *tag, const char *format, ...) { va_end(args); return 1; } + + +/* + * Log message levels. + * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default) + * - LIBUSB_LOG_LEVEL_ERROR (1) : error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to stderr + * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stderr +*/ +int ugly_libusb_log_level(enum ugly_loglevel v) +{ + switch (v) { + case UDEBUG: return 4; + case UINFO: return 3; + case UWARN: return 2; + case UERROR: return 1; + }; + + return 2; +} diff --git a/src/sg.c b/src/sg.c index 8633b1d4d..d1ee5aea1 100644 --- a/src/sg.c +++ b/src/sg.c @@ -936,6 +936,12 @@ static stlink_t* stlink_open(const int verbose) { return NULL; } +#if LIBUSB_API_VERSION < 0x01000106 + libusb_set_debug(slsg->libusb_ctx, ugly_libusb_log_level(verbose)); +#else + libusb_set_option(slsg->libusb_ctx, LIBUSB_OPTION_LOG_LEVEL, ugly_libusb_log_level(verbose)); +#endif + slsg->usb_handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, STLINK_USB_VID_ST, STLINK_USB_PID_STLINK); if (slsg->usb_handle == NULL) { WLOG("Failed to find an stlink v1 by VID:PID\n"); diff --git a/src/usb.c b/src/usb.c index 7832612cf..b99e04b27 100644 --- a/src/usb.c +++ b/src/usb.c @@ -902,6 +902,12 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST goto on_error; } +#if LIBUSB_API_VERSION < 0x01000106 + libusb_set_debug(slu->libusb_ctx, ugly_libusb_log_level(verbose)); +#else + libusb_set_option(slu->libusb_ctx, LIBUSB_OPTION_LOG_LEVEL, ugly_libusb_log_level(verbose)); +#endif + libusb_device **list; /** @todo We should use ssize_t and use it as a counter if > 0. As per libusb API: ssize_t libusb_get_device_list (libusb_context *ctx, libusb_device ***list) */ int cnt = (int) libusb_get_device_list(slu->libusb_ctx, &list); From c27b8f4616c335ed32ff58a2749c0f167a9ce657 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Wed, 25 Mar 2020 12:16:52 +0200 Subject: [PATCH 0750/1435] update libusb to 1.0.23 --- cmake/modules/FindLibUSB.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index 2ad35b3d8..fb122db3e 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -67,7 +67,7 @@ if(NOT LIBUSB_FOUND) if(WIN32 OR MSVC OR MINGW OR MSYS) find_package(7Zip REQUIRED) - set(LIBUSB_WIN_VERSION 1.0.22) + set(LIBUSB_WIN_VERSION 1.0.23) set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3thparty/libusb-${LIBUSB_WIN_VERSION}) From eb4175e4fb43870c1553cb6a4bc6b53c166e049f Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 28 Mar 2020 20:41:41 +0200 Subject: [PATCH 0751/1435] include for INT_MAX --- src/usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/usb.c b/src/usb.c index 7832612cf..d373f1997 100644 --- a/src/usb.c +++ b/src/usb.c @@ -2,6 +2,7 @@ #include #include #include +#include #if !defined(_MSC_VER) #include #endif From 18735deb1b96c37ce73a89b625e6020726dd45bb Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 28 Mar 2020 21:00:30 +0200 Subject: [PATCH 0752/1435] check LIBUSB_API_VERSION --- CMakeLists.txt | 1 + include/stlink/sg.h | 48 ++++++++++++++++---------------------- include/stlink/stlinkusb.h | 38 ++++++++++++++++++++++++++++++ include/stlink/usb.h | 2 +- src/usb.c | 8 ------- 5 files changed, 60 insertions(+), 37 deletions(-) create mode 100644 include/stlink/stlinkusb.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d9e2bf6bd..c319bda4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,7 @@ set(STLINK_HEADERS include/stlink/mmap.h include/stlink/chipid.h include/stlink/flash_loader.h + include/stlink/stlinkusb.h ) set(STLINK_SOURCE diff --git a/include/stlink/sg.h b/include/stlink/sg.h index e521ba217..98efd4e58 100644 --- a/include/stlink/sg.h +++ b/include/stlink/sg.h @@ -6,20 +6,12 @@ */ #ifndef STLINK_SG_H -#define STLINK_SG_H - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable: 4200 4255 4668 4820) -#include -#pragma warning(pop) -#else -#include -#endif +#define STLINK_SG_H +#include "stlinkusb.h" #include "stlink.h" -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -49,29 +41,29 @@ extern "C" { - struct stlink_libsg { - libusb_context* libusb_ctx; - libusb_device_handle *usb_handle; - unsigned ep_rep; - unsigned ep_req; +struct stlink_libsg { + libusb_context* libusb_ctx; + libusb_device_handle *usb_handle; + unsigned ep_rep; + unsigned ep_req; - int sg_fd; - int do_scsi_pt_err; + int sg_fd; + int do_scsi_pt_err; - unsigned char cdb_cmd_blk[CDB_SL]; + unsigned char cdb_cmd_blk[CDB_SL]; - int q_data_dir; // Q_DATA_IN, Q_DATA_OUT - // the start of the query data in the device memory space - uint32_t q_addr; + int q_data_dir; // Q_DATA_IN, Q_DATA_OUT + // the start of the query data in the device memory space + uint32_t q_addr; - // Sense (error information) data - // obsolete, this was fed to the scsi tools - unsigned char sense_buf[SENSE_BUF_LEN]; + // Sense (error information) data + // obsolete, this was fed to the scsi tools + unsigned char sense_buf[SENSE_BUF_LEN]; - struct stlink_reg reg; - }; + struct stlink_reg reg; +}; - stlink_t* stlink_v1_open(const int verbose, int reset); +stlink_t* stlink_v1_open(const int verbose, int reset); #ifdef __cplusplus } diff --git a/include/stlink/stlinkusb.h b/include/stlink/stlinkusb.h new file mode 100644 index 000000000..a5d664472 --- /dev/null +++ b/include/stlink/stlinkusb.h @@ -0,0 +1,38 @@ +#ifndef STLINKUSB_H +#define STLINKUSB_H + +#include + +/* + + libusb ver | LIBUSB_API_VERSION +-------------+-------------------- + v1.0.13 | 0x01000100 + v1.0.14 | 0x010000FF + v1.0.15 | 0x01000101 + v1.0.16 | 0x01000102 < MINIMAL_API_VERSION + v1.0.17 | 0x01000102 + v1.0.18 | 0x01000102 + v1.0.19 | 0x01000103 + v1.0.20 | 0x01000104 + v1.0.21 | 0x01000105 + v1.0.22 | 0x01000106 + v1.0.23 | 0x01000107 + +*/ + +#if !defined ( LIBUSBX_API_VERSION ) +#if defined (__FreeBSD__) +#define LIBUSBX_API_VVERSION LIBUSB_API_VERSION +#elif !defined (LIBUSB_API_VERSION) +#error unsupported libusb version +#endif +#endif + +#define MINIMAL_API_VERSION 0x01000102 + +#if ( LIBUSB_API_VERSION < MINIMAL_API_VERSION ) +#error unsupported libusb version +#endif + +#endif // STLINKUSB_H diff --git a/include/stlink/usb.h b/include/stlink/usb.h index 4bf28c355..2d5ff731c 100644 --- a/include/stlink/usb.h +++ b/include/stlink/usb.h @@ -9,9 +9,9 @@ #define STLINK_USB_H #include -#include #include "stlink.h" +#include "stlinkusb.h" #include "stlink/logging.h" #ifdef __cplusplus diff --git a/src/usb.c b/src/usb.c index d373f1997..bfa5fd2f4 100644 --- a/src/usb.c +++ b/src/usb.c @@ -8,14 +8,6 @@ #endif #include #include -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable: 4200 4255 4668 4820) -#include -#pragma warning(pop) -#else -#include -#endif #include #include From cefcb7316c8987f705c6b08d1ac4f5b1c2cb468f Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 28 Mar 2020 21:16:32 +0200 Subject: [PATCH 0753/1435] check MD5 while download libusb --- cmake/modules/FindLibUSB.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index fb122db3e..9569fe133 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -79,6 +79,7 @@ if(NOT LIBUSB_FOUND) file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download ${LIBUSB_WIN_ARCHIVE_PATH} + EXPECTED_MD5 750e64b45aca94fafbdff07171004d03 ) endif() file(MAKE_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) From 04630e4302d7447aa6e981f7fe1a38d0f21e3017 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 28 Mar 2020 21:31:44 +0200 Subject: [PATCH 0754/1435] fix intendation --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c319bda4d..306d3d6ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,7 @@ set(STLINK_HEADERS include/stlink/mmap.h include/stlink/chipid.h include/stlink/flash_loader.h - include/stlink/stlinkusb.h + include/stlink/stlinkusb.h ) set(STLINK_SOURCE From f36d45ab922c0ccf80472205fd6f17dd478fd833 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 28 Mar 2020 21:57:08 +0200 Subject: [PATCH 0755/1435] specify correct MD5 for libusb-1.0.23.7z --- cmake/modules/FindLibUSB.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index 9569fe133..f88556205 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -79,7 +79,7 @@ if(NOT LIBUSB_FOUND) file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download ${LIBUSB_WIN_ARCHIVE_PATH} - EXPECTED_MD5 750e64b45aca94fafbdff07171004d03 + EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 ) endif() file(MAKE_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) From 085ccae6a3e75368b75a14cd3553efcd70f27d70 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sun, 29 Mar 2020 08:28:38 +0300 Subject: [PATCH 0756/1435] fix typo --- include/stlink/stlinkusb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/stlink/stlinkusb.h b/include/stlink/stlinkusb.h index a5d664472..5e1220c34 100644 --- a/include/stlink/stlinkusb.h +++ b/include/stlink/stlinkusb.h @@ -23,7 +23,7 @@ #if !defined ( LIBUSBX_API_VERSION ) #if defined (__FreeBSD__) -#define LIBUSBX_API_VVERSION LIBUSB_API_VERSION +#define LIBUSBX_API_VERSION LIBUSB_API_VERSION #elif !defined (LIBUSB_API_VERSION) #error unsupported libusb version #endif From 61de93ff76aa32b300c8d0f0d2506b8872b950a4 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 30 Mar 2020 02:11:38 +0200 Subject: [PATCH 0757/1435] Update for CHANGELOG.md & minor fixes --- CHANGELOG.md | 29 +++++++----- doc/tested-boards.md | 2 +- doc/wiki_old.md | 108 ------------------------------------------- 3 files changed, 18 insertions(+), 121 deletions(-) delete mode 100644 doc/wiki_old.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 586e44206..d88d83098 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Release date: 2020-02-20 Major changes and added features: * Initial support for STM32L41X ([#754](https://github.com/texane/stlink/pull/754), [#799](https://github.com/texane/stlink/pull/799)) +* Working support for CKS32F103C8T6 and related CKS devices with Core-ID 0x2ba01477 ([#756](https://github.com/texane/stlink/pull/756), [#757](https://github.com/texane/stlink/pull/757), [#805](https://github.com/texane/stlink/pull/805), [#834](https://github.com/texane/stlink/pull/834), Regression-Fixes: [#761](https://github.com/texane/stlink/pull/761), [#766](https://github.com/texane/stlink/pull/766)) * Added preliminary support for some STM32G0 chips ([#759](https://github.com/texane/stlink/pull/759), [#760](https://github.com/texane/stlink/pull/760), [#797](https://github.com/texane/stlink/pull/797)) * Added support for mass erasing second bank on STM32F10x_XL ([#767](https://github.com/texane/stlink/pull/767), [#768](https://github.com/texane/stlink/pull/768)) * Added call to clear PG bit after writing to flash ([#773](https://github.com/texane/stlink/pull/773)) @@ -30,9 +31,9 @@ Updates and fixes: * Fixed case when __FILE__ don't contain "/" nor "\\" ([#745](https://github.com/texane/stlink/pull/745)) * Fixed double dash issue in doc/man ([#746](https://github.com/texane/stlink/pull/746), [#747](https://github.com/texane/stlink/pull/747)) * Compiling documentation: package is called libusb-1.0-0-dev on Debian ([#748](https://github.com/texane/stlink/pull/748)) -* Only do bank calculation on STM32L4 devices with dual banked flash / Added chip ID 0x464 for STM32L41xxx/L42xxx devices ([#751](https://github.com/texane/stlink/pull/751)) +* Only do bank calculation on STM32L4 devices with dual banked flash / Added chip-ID 0x464 for STM32L41xxx/L42xxx devices ([#751](https://github.com/texane/stlink/pull/751)) * Added O_BINARY option to open file ([#753](https://github.com/texane/stlink/pull/753)) -* Fixed versioning when compiling from the checked out git-repo ([#762](https://github.com/texane/stlink/pull/762)) +* Fixed versioning when compiling from the checked out git-repo ([#762](https://github.com/texane/stlink/pull/762), [#772](https://github.com/texane/stlink/pull/772)) * Fixed "unkown chip id", piped output and st-util -v ([#107](https://github.com/texane/stlink/pull/107), [#665](https://github.com/texane/stlink/pull/665), [#763](https://github.com/texane/stlink/pull/763)) * win32: move usleep definition to unistd.h ([#765](https://github.com/texane/stlink/pull/765)) * Fixed relative path to the UI files needed by stlink-gui-local (GUI) ([#770](https://github.com/texane/stlink/pull/770), [#771](https://github.com/texane/stlink/pull/771)) @@ -71,7 +72,7 @@ Major changes and added features: Updates and fixes: -* Fixed missing flash_loader for STM32L011 ([#356](https://github.com/texane/stlink/pull/356), [#654](https://github.com/texane/stlink/pull/654), [#675](https://github.com/texane/stlink/pull/675)) +* Fixed missing flash_loader for STM32L011 ([#654](https://github.com/texane/stlink/pull/654), [#675](https://github.com/texane/stlink/pull/675)) * Fix for stlink library calls exit() or _exit() ([#634](https://github.com/texane/stlink/pull/634), [#696](https://github.com/texane/stlink/pull/696)) * Added semihosting parameter documentation in doc/man ([#674](https://github.com/texane/stlink/pull/674)) * Fixed reference to non-exisiting st-term tool in doc/man ([#676](https://github.com/texane/stlink/pull/676)) @@ -94,9 +95,9 @@ Release date: 2018-02-16 Major changes and added features: -* Added support of STM32L496xx/4A6xx devices ([#615](https://github.com/texane/stlink/pull/615)) +* Added support of STM32L496xx/4A6xx devices ([#615](https://github.com/texane/stlink/pull/615), [#657](https://github.com/texane/stlink/pull/657)) * Added unknown chip dummy to obtain the serial of the ST-link by a call to st-info --probe ([#641](https://github.com/texane/stlink/pull/641)) -* Added support for STM32F72xx (chip id: 0x452) devices (commit [#1969148](https://github.com/texane/stlink/commit/19691485359afef1a256964afcbb8dcf4b733209)) +* Added support for STM32F72xx (chip-ID: 0x452) devices (commit [#1969148](https://github.com/texane/stlink/commit/19691485359afef1a256964afcbb8dcf4b733209)) Updates and fixes: @@ -118,7 +119,7 @@ Release date: 2017-07-01 Major changes and added features: -* Allow building of debian package with CPack ([#554](https://github.com/texane/stlink/pull/554), commit [#2c0ab7f](https://github.com/texane/stlink/commit/5b69f25198a1a8f34e2ee48d1ad20f79447e3d55)) +* Allow building of debian package with CPack ([#554](https://github.com/texane/stlink/pull/554), commit [#5b69f25](https://github.com/texane/stlink/commit/5b69f25198a1a8f34e2ee48d1ad20f79447e3d55)) * Added support for STM32L011 target ([#564](https://github.com/texane/stlink/pull/564), [#565](https://github.com/texane/stlink/pull/565), [#572](https://github.com/texane/stlink/pull/572)) * Added support for flashing second bank on STM32F10x_XL ([#592](https://github.com/texane/stlink/pull/592)) * Initial support to compile with Microsoft Visual Studio 2017 ([#602](https://github.com/texane/stlink/pull/602)) @@ -150,7 +151,7 @@ Major changes and added features: * Added support for Semihosting `SYS_READC` ([#546](https://github.com/texane/stlink/pull/546)) * Added support for STM32F413 ([#549](https://github.com/texane/stlink/pull/549), [#550](https://github.com/texane/stlink/pull/550)) -* Added preliminary support for STM32L011 to see it after probe (chipid `0x457`) ([#558](https://github.com/texane/stlink/pull/558), [#598](https://github.com/texane/stlink/pull/598)) +* Added preliminary support for STM32L011 to see it after probe (chip-ID 0x457) ([#558](https://github.com/texane/stlink/pull/558), [#598](https://github.com/texane/stlink/pull/598)) Updates and fixes: @@ -171,12 +172,12 @@ Major changes and added features: * Deprecation of autotools (autoconf, automake) and fixed build with MinGW ([#83](https://github.com/texane/stlink/pull/83), [#431](https://github.com/texane/stlink/pull/431), [#434](https://github.com/texane/stlink/pull/434), [#465](https://github.com/texane/stlink/pull/465)) * Added intel hex file reading for `st-flash` ([#110](https://github.com/texane/stlink/pull/110), [#157](https://github.com/texane/stlink/pull/157), [#200](https://github.com/texane/stlink/pull/200), [#239](https://github.com/texane/stlink/pull/239), [#457](https://github.com/texane/stlink/pull/547), [#459](https://github.com/texane/stlink/pull/549)) +* Added support for ARM semihosting to `st-util` ([#147](https://github.com/texane/stlink/pull/147), [#227](https://github.com/texane/stlink/pull/227), [#454](https://github.com/texane/stlink/pull/454), [#455](https://github.com/texane/stlink/pull/455)) * Added manpages (generated with pandoc from Markdown) ([#208](https://github.com/texane/stlink/pull/208), [#464](https://github.com/texane/stlink/pull/464), [#466](https://github.com/texane/stlink/pull/466), [#467](https://github.com/texane/stlink/pull/467)) -* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#228](https://github.com/texane/stlink/pull/228), ([#507](https://github.com/texane/stlink/pull/507), commit [#2c0ab7f](https://github.com/texane/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) +* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#228](https://github.com/texane/stlink/pull/228), ([#507](https://github.com/texane/stlink/pull/507), commit [#3fd0f09](https://github.com/texane/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) * Support serial numbers argument for `st-util` and `st-flash` to probe and control multiple connected programmers ([#318](https://github.com/texane/stlink/pull/318), [#398](https://github.com/texane/stlink/pull/398), [#541](https://github.com/texane/stlink/pull/541)) * Merge st-probe tool into st-info ([#398](https://github.com/texane/stlink/pull/398)) * Added support for native debian packaging ([#444](https://github.com/texane/stlink/pull/444), [#472](https://github.com/texane/stlink/pull/472), [#473](https://github.com/texane/stlink/pull/473), [#482](https://github.com/texane/stlink/pull/482), [#483](https://github.com/texane/stlink/pull/483), [#484](https://github.com/texane/stlink/pull/484), [#485](https://github.com/texane/stlink/pull/485)) -* Added support for ARM semihosting to `st-util` ([#454](https://github.com/texane/stlink/pull/454), [#455](https://github.com/texane/stlink/pull/455)) * Rewritten commandline parsing for `st-flash` ([#459](https://github.com/texane/stlink/pull/459)) * Added `--reset` command to `st-flash` ([#505](https://github.com/texane/stlink/pull/505)) * st-util should detect when USB commands fail ([#525](https://github.com/texane/stlink/pull/525), ([#527](https://github.com/texane/stlink/pull/527), ([#528](https://github.com/texane/stlink/pull/528)) @@ -188,14 +189,13 @@ Chip support added for: * STM32F412 ([#537](https://github.com/texane/stlink/pull/537), [#538](https://github.com/texane/stlink/pull/538)) * STM32F7xx ([#324](https://github.com/texane/stlink/pull/324), [#326](https://github.com/texane/stlink/pull/326), [#327](https://github.com/texane/stlink/pull/327), [#337](https://github.com/texane/stlink/pull/337)) * STM32F767ZI ([#509](https://github.com/texane/stlink/pull/509)) -* STM32L0xx Cat2 devices (chip id: 0x425) ([#414](https://github.com/texane/stlink/pull/414)) -* STM32L0xx Cat5 devices (chip id: 0x447) ([#406](https://github.com/texane/stlink/pull/406)) +* STM32L0xx Cat2 devices (chip-ID: 0x425) ([#414](https://github.com/texane/stlink/pull/414)) +* STM32L0xx Cat5 devices (chip-ID: 0x447) ([#406](https://github.com/texane/stlink/pull/406)) * STM32L4xx ([#321](https://github.com/texane/stlink/pull/321)) * STM32L432 ([#500](https://github.com/texane/stlink/pull/500), [#501](https://github.com/texane/stlink/pull/501)) Updates and fixes: -* Set SWDCLK and fixed jtag_reset bug ([#254](https://github.com/texane/stlink/pull/254), [#291](https://github.com/texane/stlink/pull/291), [#475](https://github.com/texane/stlink/pull/475), [#533](https://github.com/texane/stlink/pull/533), [#534](https://github.com/texane/stlink/pull/534)) * Fixed "unaligned addr or size" when trying to write a program in RAM ([#323](https://github.com/texane/stlink/pull/323)) * Fixed flashing on STM32_F3_SMALL ([#325](https://github.com/texane/stlink/pull/325)) * Fixed STM32L-problem with flash loader ([#390](https://github.com/texane/stlink/pull/390)) @@ -205,6 +205,8 @@ Updates and fixes: * Fixed STM32F030 erase error ([#442](https://github.com/texane/stlink/pull/442)) * Fixed memory map for STM32F7xx ([#453](https://github.com/texane/stlink/pull/453), [#456](https://github.com/texane/stlink/pull/456)) * Redesign of `st-flash` commandline options parsing ([#459](https://github.com/texane/stlink/pull/459)) +* Set SWDCLK and fixed jtag_reset bug ([#475](https://github.com/texane/stlink/pull/475), [#534](https://github.com/texane/stlink/pull/534)) +* doc/compiling.md: Add note about installation and ldconfig ([#478](https://github.com/texane/stlink/pull/478), commit [#be66bbf](https://github.com/texane/stlink/commit/be66bbf200c718904514b044ba84d64a36456218)) * Fixed Release target to generate the man-pages with pandoc ([#479](https://github.com/texane/stlink/pull/479)) * Fixed Cygwin build ([#487](https://github.com/texane/stlink/pull/487), ([#506](https://github.com/texane/stlink/pull/506)) * Reset flash mass erase (MER) bit after mass erase for safety ([#489](https://github.com/texane/stlink/pull/489)) @@ -241,6 +243,8 @@ Updates and fixes: * Fixed STM32F2xx memory map (Nicolas Schodet) * Memory map for STM32F42xxx and STM32F43xxx devices (Craig Lilley) * Stm32l0x flash loader (Robin Kreis) +* Send F4 memory-map and features for STM32F429 ([#188](https://github.com/texane/stlink/pull/188), [#196](https://github.com/texane/stlink/pull/196), [#250](https://github.com/texane/stlink/pull/250), [#251](https://github.com/texane/stlink/pull/251)) (Release v1.1.0) +* Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/texane/stlink/pull/218), [#288](https://github.com/texane/stlink/pull/288)) (Release v1.1.0) Chip support added for: @@ -250,6 +254,7 @@ Chip support added for: * Basic support for STM32F446 (Pavel Kirienko) * STM32F303 High Density * STM32L1xx Cat.2 devices (Nicolas Schodet) +* STM32L1xx (chip-ID 0x427) ([#152](https://github.com/texane/stlink/pull/152), [#163](https://github.com/texane/stlink/pull/163), [#165](https://github.com/texane/stlink/pull/165)) (Release v1.0.0) Board support added for: diff --git a/doc/tested-boards.md b/doc/tested-boards.md index ebc47c2ac..a9fa2f1c6 100644 --- a/doc/tested-boards.md +++ b/doc/tested-boards.md @@ -18,7 +18,7 @@ STLink v2 (as found on the 32L and F4 Discovery boards), known working targets: * STM32F030F4P6 (custom board) * STM32F051R8T6 (STM320518-EVAL board) * STM32F100xx (Medium Density VL, as on the 32VL Discovery board) -* STM32F103VET6 (HY-STM32 board) +* STM32F103VET6 (HY-STM32 board) ([#149](https://github.com/texane/stlink/pull/149)) * STM32F105RCT6 (DecaWave EVB1000 board) * STM32F303xx (STM32F3 Discovery board) * STM32F407xx (STM32F4 Discovery board) diff --git a/doc/wiki_old.md b/doc/wiki_old.md deleted file mode 100644 index 81e70a277..000000000 --- a/doc/wiki_old.md +++ /dev/null @@ -1,108 +0,0 @@ -Welcome to the stlink wiki! (Archived: 2014-08-11) - -Misc: -Windows pre-compiled binaries are available at http://www.emb4fun.de/archive/stlink/index.html - -FAQ: -Q: Where can I get help? Is there a forum or maybe a mailing list? - -A: todo - -Q: How can I install stlink and flash binaries on Mac OS X ? - -A: **20140811: ** installed on Mac OS X 10.9.4 with ports method, however STlink v2 does not seem to work with libusb if you upgrade to the newest firmware !! Only older firmware on STlink v2 works. - -[https://coderwall.com/p/oznj_q](https://coderwall.com/p/oznj_q) - -`sudo port install libusb automake autoconf pkgconfig` - -`aclocal --force -I /opt/local/share/aclocal` - -`git clone https://github.com/texane/stlink.git stlink-utility` - -`cd stlink-utility` - -`./autogen.sh` - -`./configure` - -`make` - - -Then trying to flash the image with STLINK v2 : - -`./st-flash write ~/Downloads/irq.bin 0x8000000` - -> libusb_handle_events() timeout -> -> [!] send_recv - -After downgrading the firmware, flashing works -ST-Link/V2 debugger with downgraded V2.14.3 firmware: - -https://drive.google.com/folderview?id=0Bzv7UpKpOQhnbXJVVEg4VUo2M1k - -as described here: - -http://community.spark.io/t/how-to-flash-a-brand-new-freshly-soldered-stm32f103-chip/3906 - -`./st-flash write ~/Downloads/irq.bin 0x8000000` - -> 2014-08-11T23:14:52 INFO src/stlink-common.c: Loading device parameters.... -> -> 2014-08-11T23:14:52 INFO src/stlink-common.c: Device connected is: F1 Medium-density device, id 0x20036410 -> -> 2014-08-11T23:14:52 INFO src/stlink-common.c: SRAM size: 0x5000 bytes (20 KiB), Flash: 0x20000 bytes (128 KiB) in -> pages of 1024 bytes -> -> 2014-08-11T23:14:52 INFO src/stlink-common.c: Attempting to write 24904 (0x6148) bytes to stm32 address: 134217728 -> (0x8000000) -> -> Flash page at addr: 0x08006000 erased -> -> 2014-08-11T23:14:53 INFO src/stlink-common.c: Finished erasing 25 pages of 1024 (0x400) bytes -> -> 2014-08-11T23:14:53 INFO src/stlink-common.c: Starting Flash write for VL/F0 core id -> -> 2014-08-11T23:14:53 INFO src/stlink-common.c: Successfully loaded flash loader in sram 24/24 pages written -> -> 2014-08-11T23:14:54 INFO src/stlink-common.c: Starting verification of write complete -> -> 2014-08-11T23:14:54 INFO src/stlink-common.c: Flash written and verified! jolly good! - - -Installation of openOCD on Mac OS X with STlink-v2 has been successful: - -`sudo port install openocd +jlink +stlink +ft2232` - -`/opt/local/bin/openocd --version` - -> Open On-Chip Debugger 0.7.0 (2014-08-11-22:12) - -`openocd -f /opt/local/share/openocd/scripts/interface/stlink-v2.cfg -f /opt/local/share/openocd/scripts/target/stm32f1x_stlink.cfg ` - -> Open On-Chip Debugger 0.8.0 (2014-08-11-15:36) -> -> Licensed under GNU GPL v2 -> -> For bug reports, read http://openocd.sourceforge.net/doc/doxygen/bugs.html -> -> Info : This adapter doesn't support configurable speed -> -> Info : STLINK v2 JTAG v21 API v2 SWIM v4 VID 0x0483 PID 0x3748 -> -> Info : using stlink api v2 -> -> Info : Target voltage: 3.244269 -> -> Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints - -and connecting to the server through telnet yields a successful installation - -`telnet localhost 4444` - -> Connected to localhost. -> -> Escape character is '^]'. -> -> Open On-Chip Debugger From f57954ab87d27a96183782b9e72633943e6fc597 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Tue, 31 Mar 2020 14:52:45 +0200 Subject: [PATCH 0758/1435] add usb pid for st-link v2.1, found on nucleo l432kc and nucleo l552ze. --- include/stlink/usb.h | 1 + src/usb.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/stlink/usb.h b/include/stlink/usb.h index 4bf28c355..239c5b4ef 100644 --- a/include/stlink/usb.h +++ b/include/stlink/usb.h @@ -23,6 +23,7 @@ extern "C" { #define STLINK_USB_PID_STLINK_32L 0x3748 #define STLINK_USB_PID_STLINK_32L_AUDIO 0x374a #define STLINK_USB_PID_STLINK_NUCLEO 0x374b +#define STLINK_USB_PID_STLINK_V2_1 0x3752 #define STLINK_USB_PID_STLINK_V3_USBLOADER 0x374d #define STLINK_USB_PID_STLINK_V3E_PID 0x374e #define STLINK_USB_PID_STLINK_V3S_PID 0x374f diff --git a/src/usb.c b/src/usb.c index 7832612cf..c5a314d45 100644 --- a/src/usb.c +++ b/src/usb.c @@ -941,6 +941,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) || (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) || (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO) || + (desc.idProduct == STLINK_USB_PID_STLINK_V2_1) || (desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER) || (desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID) || (desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID) || @@ -957,7 +958,8 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) || (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) - || (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO)) { + || (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO) + || (desc.idProduct == STLINK_USB_PID_STLINK_V2_1)) { sl->version.stlink_v = 2; } else if ((desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER) || (desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID) @@ -1032,6 +1034,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO || desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO || + desc.idProduct == STLINK_USB_PID_STLINK_V2_1 || desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER || desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID || desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID || @@ -1115,6 +1118,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { if (desc.idProduct != STLINK_USB_PID_STLINK_32L && desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO && + desc.idProduct != STLINK_USB_PID_STLINK_V2_1 && desc.idProduct != STLINK_USB_PID_STLINK_V3_USBLOADER && desc.idProduct != STLINK_USB_PID_STLINK_V3E_PID && desc.idProduct != STLINK_USB_PID_STLINK_V3S_PID && From 140a03e7fd230798806328fe05bea5cda614a047 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Tue, 31 Mar 2020 15:26:27 +0200 Subject: [PATCH 0759/1435] update udev rules for stlinkv2-1 --- etc/udev/rules.d/49-stlinkv2-1.rules | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/etc/udev/rules.d/49-stlinkv2-1.rules b/etc/udev/rules.d/49-stlinkv2-1.rules index 15a797a05..b89b84012 100644 --- a/etc/udev/rules.d/49-stlinkv2-1.rules +++ b/etc/udev/rules.d/49-stlinkv2-1.rules @@ -10,6 +10,10 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", \ MODE:="0666", \ SYMLINK+="stlinkv2-1_%n" +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3752", \ + 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 From ac4775623df9ef74b3bd86c2939482c99cf01f80 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Tue, 31 Mar 2020 09:43:50 +0200 Subject: [PATCH 0760/1435] add stm32g4 cat3 (dual flash bank) devices. --- src/chipid.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/chipid.c b/src/chipid.c index 75448e01b..4659a55c9 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -554,6 +554,20 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7000 // 28K (table 2) }, + { + // STM32G471/473/474/483/484 (from RM0440) + .chip_id = STLINK_CHIPID_STM32_G4_CAT3, + .description = "G4 Category-3", + .flash_type = STLINK_FLASH_TYPE_G4, + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = 0x800, // 2K (sec 3.3.1) + // SRAM1 is 80k at 0x20000000 + // SRAM2 is 16k at 0x20014000 + // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 + .sram_size = 0x18000, // 128K (sec 2.4) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000 // 28K (table 2) + }, { // STM32WB55 (from RM0434) .chip_id = STLINK_CHIPID_STM32_WB55, From 0cd94a9adcce03406db887842badd6ac82c71e1b Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Tue, 31 Mar 2020 09:43:03 +0200 Subject: [PATCH 0761/1435] stm32g0431/441: update doc --- src/chipid.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/chipid.c b/src/chipid.c index 4659a55c9..426780cf7 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -550,6 +550,9 @@ static const struct stlink_chipid_params devices[] = { .flash_type = STLINK_FLASH_TYPE_G4, .flash_size_reg = 0x1FFF75E0, // Section 47.2 .flash_pagesize = 0x800, // 2K (sec 3.3.1) + // SRAM1 is 16k at 0x20000000 + // SRAM2 is 6k at 0x20014000 + // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 .sram_size = 0x8000, // 32K (sec 2.4) .bootrom_base = 0x1fff0000, .bootrom_size = 0x7000 // 28K (table 2) From db6e93e52aa86add8ff0453ca2d26ca13310fa8e Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Wed, 1 Apr 2020 20:40:34 +0300 Subject: [PATCH 0762/1435] set minimal LIBUSBX_API_VERSION to depend on OS --- include/stlink/stlinkusb.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/include/stlink/stlinkusb.h b/include/stlink/stlinkusb.h index 5e1220c34..4d904b0c5 100644 --- a/include/stlink/stlinkusb.h +++ b/include/stlink/stlinkusb.h @@ -10,7 +10,7 @@ v1.0.13 | 0x01000100 v1.0.14 | 0x010000FF v1.0.15 | 0x01000101 - v1.0.16 | 0x01000102 < MINIMAL_API_VERSION + v1.0.16 | 0x01000102 v1.0.17 | 0x01000102 v1.0.18 | 0x01000102 v1.0.19 | 0x01000103 @@ -21,15 +21,23 @@ */ -#if !defined ( LIBUSBX_API_VERSION ) #if defined (__FreeBSD__) +#if !defined ( LIBUSBX_API_VERSION ) #define LIBUSBX_API_VERSION LIBUSB_API_VERSION #elif !defined (LIBUSB_API_VERSION) #error unsupported libusb version #endif #endif +#if defined (__FreeBSD__) #define MINIMAL_API_VERSION 0x01000102 +#elif defined (__linux__) +#define MINIMAL_API_VERSION 0x01000104 +#elif defined (__APPLE__) +#define MINIMAL_API_VERSION 0x01000104 +#elif defined (_WIN32) +#define MINIMAL_API_VERSION 0x01000106 +#endif #if ( LIBUSB_API_VERSION < MINIMAL_API_VERSION ) #error unsupported libusb version From a76f468587713ee7bc1cf959d50c55446918a878 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 2 Apr 2020 02:18:49 +0200 Subject: [PATCH 0763/1435] [doc] Updated list of supported devices --- README.md | 2 +- doc/devices_boards.md | 258 ++++++++++++++++++++++++++++++++++++++++ doc/tested-boards.md | 57 --------- include/stlink/chipid.h | 32 ++--- 4 files changed, 269 insertions(+), 80 deletions(-) create mode 100644 doc/devices_boards.md delete mode 100644 doc/tested-boards.md diff --git a/README.md b/README.md index b26a147e9..5c601f36c 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ These programmer boards are available in four versions: ## Supported hardware combinations -Currently known working combinations of programmers and targets are listed in [doc/tested-boards.md](doc/tested-boards.md). +Currently known working combinations of programmers and targets are listed in [doc/devices_boards.md](doc/tested-boards.md). ## Installation diff --git a/doc/devices_boards.md b/doc/devices_boards.md new file mode 100644 index 000000000..d9e106503 --- /dev/null +++ b/doc/devices_boards.md @@ -0,0 +1,258 @@ +Boards supported by the STlink toolset +====================================== + +The following devices are supported by the STlink tools. + +All Boards are expected to work with ST-Link-v2 programmers. + + +**STM32F0 / ARM Cortex M0 / Core-ID: 0x0bb11477 (STM32F0_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x440 | STM32F0**30**x**8** | +| 0x442 | STM32F0**30**x**C** | +| 0x444 | STM32F0**3**xx**4** | +| 0x444 | STM32F0**3**xx**6** | +| 0x445 | STM32F0**4**xxx | +| 0x440 | STM32F0**5**xxx | +| 0x445 | STM32F0**70**x**6** | +| 0x448 | STM32F0**70**x**B** | +| 0x448 | STM32F0**71**xx | +| 0x448 | STM32F0**72**xx | +| 0x442 | STM32F0**9**xxx | + +Tested boards [incl. STLink programmers]: +* Nucleo-F030R8 [v2-1] +* Nucleo-32 [v2-1] +* STM32F0-Discovery [v2] +* STM320518-EVAL +* Nucleo-F072RB [v2-1] +* Nucleo-F091RC [v2-1] + + +**STM32F1 / ARM Cortex M3 / Core-ID: 0x1ba01477 (STM32F1_CORE_ID)** + +| Product-Code | Product Line | +| --- | --- | +| STM32F10**0**yyxx | Value line (V) | +| STM32F10**1**yyxx | Access line (A) | +| STM32F10**2**yyxx | USB Access line (USB-A) | +| STM32F10**3**yyxx | Performance line (P) | +| STM32F10**5**yyxx | Connectivity line (C) | +| STM32F10**7**yyxx | Connectivity line (C) | + +| Chip-ID | Product Line | Code (yy) | V | A | USB-A | P | C | +| --- | --- | --- | --- | --- | --- | --- | --- | +| 0x412 | Low-Density | x4 x6 | F100 | F101 | F102 | F103 | | +| 0x410 | Medium Density | x8 xB | | F101 | F102 | F103 | | +| 0x414 | High density | xC xD xE | | F101 | F103 | | | +| 0x418 | STM32F105xx/107xx | x8 xB xC | | | | | F105
    F107 | +| 0x420 | Medium density value | x8 xB | F100 | | | | | +| 0x428 | High density Value | xC xD xE | F100 | | | | | +| 0x430 | XL-Density | xF XG | | F101 | | F103 | | + +Tested boards [incl. STLink programmers]: +* 32VL-Discovery (STM32F100RBT6) with STLink-v1 [v1, v2] +* STM32F103-Bluepill: C8Tx & R8xx [v2] +* Nucleo-F103RB [v2-1] +* HY-STM32 (STM32F103VETx) [v1, v2] +* DecaWave EVB1000 (STM32F105RCTx) [v1, v2] + + +**STM32F2 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32F2_CORE_ID)** + +| Chip-ID | Product-Code | Product Line | +| --- | --- | --- | +| 0x411 | STM32F2yyxx | (all devices) | + + +**STM32F1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM3F1c_CORE_ID)** + +| Product-Code | Chip-ID | STLink
    Programmer | Boards | +| --- | --- | --- | --- | +| CKS32F103C8Tx | 0x410 | v2 | "STM32"-Bluepill ( _**Fake-Marking !**_ )
    STM32F103C8T6 clone from China Key Systems (CKS) | +| CKS32F103C8Tx | 0x410 | v2 | CKS32-Bluepill (Clone)
    STM32F103C8T6 clone from China Key Systems (CKS) | + + +**STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3_CORE_ID)** + +| Product-Code | Product Line | +| --- | --- | +| STM32F3**01**yyxx | Access line (A) | +| STM32F3**02**yyxx | USB & CAN line (USB/CAN) | +| STM32F3**03**yyxx | Performance line (P) | +| STM32F3**34**yy | Digital Power line (DP) | +| STM32F3**73**yy | Precision Measurement line (PM) 64k/16k / 128k/24k / 265k/32k | +| STM32F3**18**yy | General Purpose line (GP) 64k/16k | +| STM32F3**28**yy | General Purpose line (GP) 64k/16k | +| STM32F3**58**yy | General Purpose line (GP) 265k/48k | +| STM32F3**78**yy | Precision Measurement line (PM) 265k/32k | +| STM32F3**98**yy | General Purpose line (GP) 512k/80k | + +| Chip-ID | Product Line | Code (yy) | A | USB/CAN | P | others | +| --- | --- | --- | --- | --- | --- | --- | +| 0x422 | _N/A_ | xB xC | | F302 | F303 | | +| 0x422 | _N/A_ | - | | | | F358 | +| 0x432 | _N/A_ | - | | | | F373
    F378 | +| 0x438 | _N/A_ | x4 x6 x8 | | | F303 | | +| 0x438 | _N/A_ | - | | | | F334
    F328 | +| 0x439 | _N/A_ | x4 x6 x8 | F301 | F302 | | | +| 0x439 | _N/A_ | - | | | | F318 | +| 0x446 | _N/A_ | xD xE | | F302 | F303 | | +| 0x446 | _N/A_ | - | | | | F398 | + +Tested boards [incl. STLink programmers]: +* Nucleo-F302K8 [v2-1] +* Nucleo-F303K8 [v2-1] +* STM32F3348-Discovery [v2-1] +* Nucleo-F334R8 [v2-1] +* STM32F303-Discovery [v2] +* Nucleo-F303RE [v2-1] + + +**STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3c_CORE_ID)** + +| Product-Code | Chip-ID | STLink
    Programmer | Boards | +| --- | --- | --- | --- | +| GD32F303VGT6 | 0x430 | _N/A_ | STM32F303 clone from GigaDevice GD)
    _unsupported_ | + + +**STM32F4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F4_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x413 | STM32F4**0**xxx | +| 0x413 | STM32F4**1**xxx | +| 0x419 | STM32F4**2**xxx | +| 0x419 | STM32F4**3**xxx | +| 0x423 | STM32F4**01**x**B** | +| 0x423 | STM32F4**01**x**C** | +| 0x433 | STM32F4**01**x**D** | +| 0x433 | STM32F4**01**x**E** | +| 0x458 | STM32F4**10**xx | +| 0x431 | STM32F4**11**xx | +| 0x441 | STM32F4**12**xx | +| 0x421 | STM32F4**46**xx | +| 0x434 | STM32F4**69**xx | +| 0x434 | STM32F4**79**xx | +| 0x463 | STM32F4**13**xx | +| 0x463 | STM32F4**23**xx | + +Tested boards [incl. STLink programmers]: +* STM32F407-Discovery [v2] +* 32F411E-Discovery with gyro, audio [v2] +* 32F429I-Discovery with LCD [v2] +* 32F439VIT6-Discovery [v2] (reseated MCU) +* Nucleo-F401RE [v2-1] +* Nucleo-F411RE [v2-1] +* 32F413H-Discovery [v2-1] + + +**STM32F7 / ARM Cortex M7F / Core-ID: 0x5ba02477 (STM32F7_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x452 | STM32F7**2**xxx | +| 0x452 | STM32F7**3**xxx | +| 0x449 | STM32F7**4**xxx | +| 0x449 | STM32F7**5**xxx | +| 0x451 | STM32F7**6**xxx | +| 0x451 | STM32F7**7**xxx | + +Tested boards [incl. STLink programmers]: +* STM32F756NGHx evaluation board [v2-1] +* 32F769I-Discovery [v2-1] +* Nucleo-F722ZE [v2-1] +* Nucleo-F746ZG [v2-1] + + +**STM32G0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32G0_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x466 | STM32G0**3**xxx | +| 0x466 | STM32G0**4**xxx | +| 0x460 | STM32G0**7**xxx | +| 0x460 | STM32G0**8**xxx | + + +**STM32G4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32G4_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x468 | STM32G4**31**xx | +| 0x468 | STM32G4**41**xx | +| 0x469 | STM32G4**7**xxx | +| 0x469 | STM32G4**8**xxx | + + +**STM32L0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32L0_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x457 | STM32L0**1**xxx | +| 0x457 | STM32L0**2**xxx | +| 0x425 | STM32L0**31**xx | +| 0x425 | STM32L0**41**xx | +| 0x417 | STM32L0**5**xxx | +| 0x417 | STM32L0**6**xxx | +| 0x447 | STM32L0**7**xxx | +| 0x447 | STM32L0**8**xxx | + +Tested boards [incl. STLink programmers]: +* Nucleo-L053R8 [v2-1] + + +**STM32L1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32L1_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x416 | STM32L1xxx**6** | +| 0x416 | STM32L1xxx**8** | +| 0x416 | STM32L1xxx**B** | +| 0x429 | STM32L1xxx**6A** | +| 0x429 | STM32L1xxx**8A** | +| 0x429 | STM32L1xxx**BA** | +| 0x427 | STM32L1xxx**C** | +| 0x436 | STM32L1xxx**D** | +| 0x437 | STM32L1xxx**E** | + +Tested boards [incl. STLink programmers]: +* Nucleo-L152RE [v2-1] +* 32L152C-Discovery [v2] + + +**STM32L4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32L4_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x464 | STM32L4**12**xx | +| 0x464 | STM32L4**22**xx | +| 0x435 | STM32L4**3**xxx | +| 0x435 | STM32L4**4**xxx | +| 0x462 | STM32L4**5**xxx | +| 0x462 | STM32L4**6**xxx | +| 0x415 | STM32L4**7**xxx | +| 0x415 | STM32L4**8**xxx | +| 0x461 | STM32L4**96**xx | +| 0x461 | STM32L4**A6**xx | +| 0x470 | STM32L4**R**xx | +| 0x470 | STM32L4**S**xx | +| 0x471 | STM32L4**P5**xx | +| 0x471 | STM32L4**Q5**xx | + +Tested boards [incl. STLink programmers]: +* Nucleo-L452RE [v2-1] +* Nucleo-L476RG [v2-1] +* Nucleo-L496ZG [v2-1] +* 32L4R9I-Discovery [v2-1] + + +**STM32W / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32W_CORE_ID)** + +| Chip-ID | Product-Code | +| --- | --- | +| 0x495 | STM32WB**50**xx | +| 0x495 | STM32WB**55**xx | +| 0x497 | STM32WLE**5**xx | diff --git a/doc/tested-boards.md b/doc/tested-boards.md deleted file mode 100644 index ebc47c2ac..000000000 --- a/doc/tested-boards.md +++ /dev/null @@ -1,57 +0,0 @@ -Stlink tested and compatible boards -=================================== - -STLink v1 (as found on the 32VL Discovery board) - -Known working targets: - -* STM32F100xx (Medium Density VL) -* STM32F103 (according to jpa- on ##stm32) - -No information: - -* everything else! - -STLink v2 (as found on the 32L and F4 Discovery boards), known working targets: - -* STM32F0 (STM32F0 Discovery board) -* STM32F030F4P6 (custom board) -* STM32F051R8T6 (STM320518-EVAL board) -* STM32F100xx (Medium Density VL, as on the 32VL Discovery board) -* STM32F103VET6 (HY-STM32 board) -* STM32F105RCT6 (DecaWave EVB1000 board) -* STM32F303xx (STM32F3 Discovery board) -* STM32F407xx (STM32F4 Discovery board) -* STM32F411E-DISCO (STM32F4 Discovery board with gyro, audio) -* STM32F429I-DISCO (STM32F4 Discovery board with LCD) -* STM32F439VIT6 (Discovery board reseated CPU) -* STM32L052K8T6 (custom board) -* STM32L1xx (STM32L Discovery board) -* STM32L151CB (custom board) -* STM32L152RB (STM32L-Discovery board, custom board) -* STM32L496ZG (STM32-Nucleo-L496ZG board) - - -* STM32F103VC, STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on custom boards - from [UweBonnes/wiki_fuer_alex](https://github.com/UweBonnes/wiki_fuer_alex/tree/master/layout) - - -STLink v2-1 (as found on the Nucleo boards), known working targets: - -* STM32F030R8T6 (STM32 Nucleo-F030R8 board) -* STM32F042K6 (STM32 Nucleo-32 Board) -* STM32F072RBT6 (STM32 Nucleo-F072RB board) -* STM32F103RB (STM32 Nucleo-F103RB board) -* STM32F303RET6 (STM32 Nucleo-F303RE board) -* STM32F334R8 (STM32 Nucleo-F334R8 board) -* STM32F401xx (STM32 Nucleo-F401RE board) -* STM32F411RET6 (STM32 Nucleo-F411RE board) -* STM32F756NGHx (STM32F7 evaluation board) -* STM32F769NI (STM32F7 discovery board) -* STM32L053R8 (STM32 Nucleo-L053R8 board) -* STM32L152RE (STM32-Nucleo-L152RE board -* STM32L452RET6 (STM32 Nucleo-L452RE board) -* STM32L476RG (STM32 Nucleo-L476RG board) - - -Please report any and all known working combinations so I can update this! diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index f179db779..8895cd4f8 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -28,7 +28,7 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F3 = 0x422, STLINK_CHIPID_STM32_F4_LP = 0x423, STLINK_CHIPID_STM32_L0_CAT2 = 0x425, - STLINK_CHIPID_STM32_L1_MEDIUM_PLUS = 0x427, + STLINK_CHIPID_STM32_L1_MEDIUM_PLUS = 0x427, /* assigned to some L1 "Medium-plus" chips */ STLINK_CHIPID_STM32_F1_VL_HIGH = 0x428, STLINK_CHIPID_STM32_L1_CAT2 = 0x429, STLINK_CHIPID_STM32_F1_XL = 0x430, @@ -36,23 +36,11 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F37x = 0x432, STLINK_CHIPID_STM32_F4_DE = 0x433, STLINK_CHIPID_STM32_F4_DSI = 0x434, - /* - * 0x435 covers STM32L43xxx and STM32L44xxx devices - * 0x461 covers STM32L496xx and STM32L4A6xx devices - * 0x462 covers STM32L45xxx and STM32L46xxx devices - * 0x464 covers STM32L41xxx and STM32L42xxx devices - */ - STLINK_CHIPID_STM32_L43X = 0x435, - STLINK_CHIPID_STM32_L496X = 0x461, - STLINK_CHIPID_STM32_L46X = 0x462, - STLINK_CHIPID_STM32_L41X = 0x464, - /* - * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" - * and some that are called "High". 0x427 is assigned to the other "Medium- - * plus" chips. To make it a bit simpler we just call 427 MEDIUM_PLUS and - * 0x436 HIGH. - */ - STLINK_CHIPID_STM32_L1_HIGH = 0x436, + STLINK_CHIPID_STM32_L43X = 0x435, /* covers STM32L43xxx and STM32L44xxx devices */ + STLINK_CHIPID_STM32_L496X = 0x461, /* covers STM32L496xx and STM32L4A6xx devices */ + STLINK_CHIPID_STM32_L46X = 0x462, /* covers STM32L45xxx and STM32L46xxx devices */ + STLINK_CHIPID_STM32_L41X = 0x464, /* covers STM32L41xxx and STM32L42xxx devices */ + STLINK_CHIPID_STM32_L1_HIGH = 0x436, /* assigned to some L1 chips called "Medium-Plus" and to some called "High" */ STLINK_CHIPID_STM32_L152_RE = 0x437, STLINK_CHIPID_STM32_F334 = 0x438, STLINK_CHIPID_STM32_F3_SMALL = 0x439, @@ -69,12 +57,12 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F72XXX = 0x452, /* This ID is found on the NucleoF722ZE board */ STLINK_CHIPID_STM32_L011 = 0x457, STLINK_CHIPID_STM32_F410 = 0x458, - STLINK_CHIPID_STM32_G0_CAT2 = 0x460, // G070/G071/081 + STLINK_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/081 */ STLINK_CHIPID_STM32_F413 = 0x463, - STLINK_CHIPID_STM32_G0_CAT1 = 0x466, // G030/G031/041 - STLINK_CHIPID_STM32_G4_CAT2 = 0x468, // See: RM 0440 s46.6.1 "MCU device ID code". + STLINK_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/041 */ + STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* See: RM 0440 s46.6.1 "MCU device ID code" */ STLINK_CHIPID_STM32_G4_CAT3 = 0x469, - STLINK_CHIPID_STM32_L4RX = 0x470, // taken from the STM32L4R9I-DISCO board + STLINK_CHIPID_STM32_L4RX = 0x470, /* taken from the STM32L4R9I-DISCO board */ STLINK_CHIPID_STM32_WB55 = 0x495 }; From cda2215327987c67e44ffbcaf04a8bc82b86bf24 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 2 Apr 2020 15:53:21 +0200 Subject: [PATCH 0764/1435] Update issue templates --- .github/ISSUE_TEMPLATE/bug-report.md | 38 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature-request.md | 39 +++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug-report.md create mode 100644 .github/ISSUE_TEMPLATE/feature-request.md diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 000000000..2d565a3f7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,38 @@ +--- +name: Bug Report +about: Create a report to help us improve +title: "[Your device name]: [Title]" +labels: bug/needs-investigation +assignees: '' + +--- + +Thank you for giving feedback to the stlink project. + +In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out each of the following items appropriate to your specific problem: + +- Programmer/board type: [enter here] (e.g Stlink /v1, /v2, /v2-clone, /v2-1) +- Programmer firmware version: [enter here] (e.g STSW-LINK007 2.27.15) +- Operating system and version: [enter here] (e.g Linux, Mac OS X, Windows) +- **Stlink tools version** and/or git commit hash: [enter here] (e.g v1.1.0/git-c722056) +- Stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-util`) +- Target chip (and board if applicable): [enter here] (e.g STM32F402VG) + +Futher we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: + +Commandline-Output: + +``` +OUTPUT/ERROR of the commandline tool(s) +``` + +Expected/description: + +`short description of the expected value` + + +**NOTICE: This bug report may be closed without further notice, if not enough information is provided!** + +Thank you for your support. + +The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md new file mode 100644 index 000000000..2aa7a5c7f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -0,0 +1,39 @@ +--- +name: Feature Request +about: Suggest an idea for this project +title: "[feature] " +labels: code/feature-request +assignees: '' + +--- + +Thank you for giving feedback to the stlink project. + +In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out the check boxes below by setting a 'x' into the checkboxes ( [x] ) and edit each item appropriate to your specific problem. + +- [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard +- [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 +- [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) +- [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 +- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` +- [ ] Target chip (and optional board): e.g STM32F402VG (STM32Fxxx Discovery) + +Futher we kindly ask you to describe the detected problem as detailled as possible and to add debug output if available, by using the following template: + +Commandline-Output: + +``` +OUTPUT/ERROR of the commandline tool(s) +``` + +Expected/description: + +`short description of the expected value` + + +**NOTICE: This feature request may be closed without notice when not enough information is provided!** + + +Thank you for your support. + +The stlink project maintainers From d3c11fbef6d8205742152f646b223323dc4c0913 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 2 Apr 2020 20:55:27 +0200 Subject: [PATCH 0765/1435] General Project Update - [doc] Updated list of supported devices - [doc] verify udev-rules (Closes #764) - Removed old issue-templates. - Updated BSD-3 license file. --- .github/ISSUE_TEMPLATE/bug_report.md | 32 -------------- .github/ISSUE_TEMPLATE/feature_request.md | 32 -------------- .github/ISSUE_TEMPLATE/support_question.md | 32 -------------- LICENSE.md | 48 ++++++++++----------- doc/devices_boards.md | 1 + doc/tutorial.md | 49 ++++++++++++++++++++++ 6 files changed, 74 insertions(+), 120 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 .github/ISSUE_TEMPLATE/support_question.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 821b406bc..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,32 +0,0 @@ -# Bug Report - -Thank you for giving feedback to the stlink project. - -In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out the check boxes below by setting a 'x' into the checkboxes ( [x] ) and edit each item appropriate to your specific problem. - -- [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard -- [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 -- [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) -- [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 -- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` -- [ ] Target chip (and optional board): e.g STM32F402VG (STM32Fxxx Discovery) - -Futher we kindly ask you to describe the detected problem as detailled as possible and to add debug output if available, by using the following template: - -Commandline-Output: - -``` -OUTPUT/ERROR of the commandline tool(s) -``` - -Expected/description: - -`short description of the expected value` - - -**NOTICE: The bug report may be closed without notice when not enough information is provided!** - - -Thank you for your support. - -The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index bf626eb97..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,32 +0,0 @@ -# Feature Request - -Thank you for giving feedback to the stlink project. - -In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out the check boxes below by setting a 'x' into the checkboxes ( [x] ) and edit each item appropriate to your specific problem. - -- [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard -- [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 -- [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) -- [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 -- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` -- [ ] Target chip (and optional board): e.g STM32F402VG (STM32Fxxx Discovery) - -Futher we kindly ask you to describe the detected problem as detailled as possible and to add debug output if available, by using the following template: - -Commandline-Output: - -``` -OUTPUT/ERROR of the commandline tool(s) -``` - -Expected/description: - -`short description of the expected value` - - -**NOTICE: This feature request may be closed without notice when not enough information is provided!** - - -Thank you for your support. - -The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/support_question.md b/.github/ISSUE_TEMPLATE/support_question.md deleted file mode 100644 index 795c13a6e..000000000 --- a/.github/ISSUE_TEMPLATE/support_question.md +++ /dev/null @@ -1,32 +0,0 @@ -# Support question - -Thank you for giving feedback to the stlink project. - -In order to allow developers and other contributors to help you with your question, please take some time to fill out the check boxes below by setting a 'x' into the checkboxes ( [x] ) and edit each item appropriate to your specific problem. - -- [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard -- [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 -- [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) -- [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 -- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` -- [ ] Target chip (and optional board): e.g STM32F402VG (STM32Fxxx Discovery) - -Futher we kindly ask you to describe the detected problem as detailled as possible and to add debug output if available, by using the following template: - -Commandline-Output: - -``` -OUTPUT/ERROR of the commandline tool(s) -``` - -Expected/description: - -`short description of the expected value` - - -**NOTICE: This support question may be closed without notice when not enough information is provided!** - - -Thank you for your support. - -The stlink project maintainers diff --git a/LICENSE.md b/LICENSE.md index 3d464ca1e..0a3ddd1f7 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,29 +1,29 @@ -Copyright (c) 2011 The stlink project (github.com/texane/stlink) contributors. - All rights reserved. -Copyright (c) 2011 The "Capt'ns Missing Link" Authors. All rights reserved. +BSD 3-Clause License + +Copyright (c) 2020, The stlink project (github.com/texane/stlink) & "Capt'ns Missing Link" authors. +All rights reserved. Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of Martin Capitanio nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/doc/devices_boards.md b/doc/devices_boards.md index d9e106503..00acdd2cf 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -243,6 +243,7 @@ Tested boards [incl. STLink programmers]: | 0x471 | STM32L4**Q5**xx | Tested boards [incl. STLink programmers]: +* Nucleo-L432KC [v2-1] * Nucleo-L452RE [v2-1] * Nucleo-L476RG [v2-1] * Nucleo-L496ZG [v2-1] diff --git a/doc/tutorial.md b/doc/tutorial.md index 100d9a641..4d870d11b 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -170,6 +170,55 @@ Upon reset, the board LEDs should be blinking. HOWTO ===== + +## Verify if udev rules are set correctly (by Dave Hylands) + +To investigate, start by plugging your STLINK device into the usb port. Then run lsusb. You should see an entry something like the following: + +``` +Bus 005 Device 017: ID 0483:374b STMicroelectronics ST-LINK/V2.1 (Nucleo-F103RB) +``` + +Note the bus number (005) and the Device (017). You should then do: +`ls -l /dev/bus/usb/005/017` (replacing 005 and 017 appropriately). + +On my system I see the following: + +``` +crw-rw-rw- 1 root root 189, 528 Jan 24 17:52 /dev/bus/usb/005/017 +``` + +which is world writable (this is from the MODE:="0666" below). I have several files in my `/etc/udev/rules.d` directory. In this particular case, the `49-stlinkv2-1.rules` file contains the following: + +``` +# 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. +``` + +and the idVendor of 0483 and idProduct of 374b matches the vendor id from the lsusb output. + +Make sure that you have all 3 files from here: https://github.com/texane/stlink/tree/master/etc/udev/rules.d in your `/etc/udev/rules.d` directory. After copying new files or editing excisting files in `/etc/udev/ruled.d` you should run the following: + +``` +sudo udevadm control --reload-rules +sudo udevadm trigger +``` + +to ensure that the rules actually take effect. Using the trigger command means that you shouldn't need to unplug and replug the device, but you might want to try that for good measure as well. + +If the VID:PID of your device doesn't match those in any of the 3 files, then you may need to create a custom rule file to match your VID:PID. + + ## Using the gdb server To run the gdb server: From 7d4822d03ba758bc4013cf74e91ba44070b6b81c Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 2 Apr 2020 21:29:02 +0200 Subject: [PATCH 0766/1435] [doc] Added st-flash --flash CL option (Closes #902) --- doc/tutorial.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/doc/tutorial.md b/doc/tutorial.md index 4d870d11b..1d48eaa38 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1,3 +1,20 @@ +stlink Tools Tutorial +===================== + +## Useful tool options +### st-flash + +#### --flash=n[k][m] + +(since v1.4.0) + +You can specify `--flash=128k` for example, to override the STM32F103C8T6 to assume 128k of flash instead of the default of 64k. +This option accepts decimal (128k), octal 0200k, or hex 0x80k. +Obviously leaving the multiplier out is equally valid, for example: `--flash=0x20000`. +The size may be followed by an optional "k" or "m" to multiply the given value by 1k (1024) or 1M respectively. + +------ + Using STM32 discovery kits with open source tools ======== From 3bc5e6f69944cef9f44e3c56b31beb2609f67722 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 3 Apr 2020 11:49:31 +0200 Subject: [PATCH 0767/1435] [doc] Added reference to tutorial --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5c601f36c..1f9771982 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,12 @@ These programmer boards are available in four versions: ## Supported hardware combinations -Currently known working combinations of programmers and targets are listed in [doc/devices_boards.md](doc/tested-boards.md). +Currently known working combinations of programmers and targets are listed in [devices_boards.md](doc/devices_boards.md). + + +## Tutorial & HOWTO + +Our [tutorial.md](doc/tutorial.md may help you along with some advanced tasks and additional info. ## Installation @@ -77,7 +82,7 @@ When there is no executable available for your platform or you need the latest ( ## License -The stlink library and tools are licensed under the [BSD license](LICENSE.md). +The stlink library and tools are licensed under the [BSD-3 license](LICENSE.md). The flashloaders/stm32l0x.s and flashloaders/stm32lx.s source files are licensed under the GPLv2+. From 27aa88821197d3ffe82baff4e971c3488ec39899 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 4 Apr 2020 13:03:22 +0200 Subject: [PATCH 0768/1435] Updated compiling doc & version support - Added info on version support - Updated compiling instructions - Updated minGW-w64 gcc-TC to v8.1.0 - Minor formatting fixes (Closes #896, #897, #899) --- cmake/modules/FindLibUSB.cmake | 8 +- doc/compiling.md | 284 +++++++++++++++------------------ doc/version_support.md | 82 ++++++++++ include/stlink/stlinkusb.h | 20 +-- scripts/mingw64-build.bat | 2 +- 5 files changed, 230 insertions(+), 166 deletions(-) create mode 100644 doc/version_support.md diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index f88556205..c8f467902 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -6,13 +6,13 @@ # LIBUSB_LIBRARY - The libraries needed to use libusb # LIBUSB_DEFINITIONS - Compiler switches required for using libusb -# FreeBSD -if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr/include ) -else () +else () # other OS FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr @@ -22,6 +22,8 @@ else () ) endif() + +# macOS if (APPLE) set(LIBUSB_NAME libusb-1.0.a) elseif(MSYS OR MINGW) diff --git a/doc/compiling.md b/doc/compiling.md index 2728c153b..0133981b1 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -1,224 +1,204 @@ # Compiling from sources -## General package requirements -* cmake (v2.8.7 or later) -* C compiler (gcc, clang or mingw) -* libusb-1.0 (v1.0.13 or later) -* libusb-dev-1.0 (v1.0.13 or later) -* pandoc _(optional; for generating manpages from markdown)_ +## Microsoft Windows (10, 8.1) +### Common Requirements -Run from the root of the source directory: +On Windows users should ensure that the following software is installed: -``` -$ make release -$ make debug -``` - -The debug target should only be necessary for people who want to modify the sources and run under a debugger. -The top level Makefile is just a handy wrapper for: +* `7zip` +* `git` +* `cmake` (3.17.0 or later) +* `MinGW-w64` (7.0.0 or later) with GCC toolchain 8.1.0 -``` -$ mkdir build && cd build -$ cmake -DCMAKE_BUILD_TYPE=Debug .. -$ make -``` -You may install to a user folder e.g `$HOME`: +### Installation -``` -$ cd build/Release; make install DESTDIR=$HOME -``` +1. Install `7zip` from +2. Install `git` from +3. Install `cmake` from +4. Install + - _EITHER_: **MinGW-w64** from (mingw-w64-install.exe)
    + Ensure that you add MinGW to the $PATH system variable when following the instructions by the setup assistant.
    + - _OR_: **Visual Studio 2017 CE** (other versions will likely work as well, but are untested; the Community edition is free for open source + development) +5. Create a new destination folder at a place of your choice +6. Open the command-line (cmd.exe) and execute `cd C:\$Path-to-your-destination-folder$\` +7. Fetch the project sourcefiles by running `git clone https://github.com/texane/stlink.git`from the command-line (cmd.exe)
    + or download the stlink zip-sourcefolder from the Release page on GitHub -Or system-wide: -``` -$ cd build/Release; sudo make install -``` +### Building +#### MinGW64 +1. Use the command-line to move to the `scripts` directory within the source-folder: `cd stlink\scripts\` +2. Execute `./mingw64-build.bat` -## Linux / Unix -## Common requirements +NOTE:
    +Per default the build script (currently) uses `C:\Program Files\mingw-w64\x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0\mingw64\bin`.
    +When installing different toolchains make sure to update the path in the `mingw64-build.bat`.
    +This can be achieved by opening the .bat file with a common text editor. -* `build-essential` -* `cmake` -* `libusb-1.0` -* `libusb-1.0-0-dev` (development headers for building, _only on debian based distros_) -* `libgtk-3-dev` _(optional; required for `stlink-gui`)_ -As of today several distributions namely: +#### Visual Studio (32 bit) -- CentOS 6, 7, 8 -- Debian 8, 9, 10, sid -- Fedora 30, 31, Rawhide -- NetBSD 7.2, 8.1, 9.0 -- openSUSE Leap 15.1, Leap 15.2 -- Ubuntu 14.04 LTS, 16.04 LTS, 18.04 LTS, 19.10 +1. In a command prompt, change the directory to the folder where the stlink files were cloned (or unzipped) to. +2. Make sure the build folder exists (`mkdir build` if not). +3. From the build folder, run cmake (`cd build; cmake ..`). -provide packages for libusb 0.1 and libusb 1.0. +This will create a solution (stlink.sln) in the build folder. Open it in Visual Studio, select the Solution Configuration (Debug or +Release) and build the solution normally (F7). -**Please ensure that the correct version 1.0 is installed.** -Other relevant distributions appear to have packages named _libusb-compat-0.1_ or alike to distinguish from libusb packages based on version 1.0.x. +NOTE:
    +This solution will link to the dll version of libusb-1.0.y
    +To debug or run the executable, the dll version of libusb-1.0 must be either on the path, or in the same folder as the executable.
    +It can be copied from here: `build\3thparty\libusb-1.0.21\MS32\dll\libusb-1.0.dll`. +## Linux +### Common requirements -### Fixing cannot open shared object file +Install the following packages from your package repository: -When installing system-wide (`sudo make install`) the dynamic library cache needs to be updated with the command `ldconfig`. +* `gcc` or `clang` or `mingw32-gcc` or `mingw64-gcc` (C-compiler; very likely gcc is already present) +* `build-essential` (on Debian based distros (debian, ubuntu)) +* `cmake` (3.4.2 or later, use the latest version available from the repository) +* `libusb-1.0` +* `libusb-1.0-0-dev` (development headers for building) +* `libgtk-3-dev` (_optional_, needed for `stlink-gui`) +* `pandoc` (_optional_, needed for generating manpages from markdown) +or execute (Debian-based systems only): `apt-get install gcc build-essential cmake libusb-1.0 libusb-1.0-0-dev libgtk-3-dev pandoc` -## Permissions with udev +(Replace gcc with the intended C-compiler if necessary or leave out any optional package not needed.) -Make sure you install udev files which are necessary to run the tools without root permissions. -By default most distributions don't allow access to USB devices. -The udev rules create devices nodes and set the group of this to `stlink`. -The rules are located in the `etc/udev/rules.d` directory. -You will need to copy it to /etc/udev/rules.d, and then either execute as root (or reboot your machine): - -``` -$ udevadm control --reload-rules -$ udevadm trigger -``` - -Udev will now create device node files `/dev/stlinkv2_XX`, `/dev/stlinkv1_XX`. -**You need to make sure the `stlink` group exists and the user, who is trying to access, is added to this group.** - - -### Note for STLINKv1 usage +### Installation -The STLINKv1's SCSI emulation is corrupted, so the best thing to do is tell your operating system to completely ignore it. +1. Open a new terminal console +2. Create a new destination folder at a place of your choice e.g. at `~/git`: `mkdir $HOME/git` +3. Change to this directory: `cd ~/git` +4. Fetch the project sourcefiles by running `git clone https://github.com/texane/stlink.git` -Options (do one of these before you plug it in) -* `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` or - 1. `echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.conf` - 2. `modprobe -r usb-storage && modprobe usb-storage` -* or - 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` - 2. `modprobe -r usb-storage && modprobe usb-storage` +### Building +1. Change into the project source directory: `cd stlink` +2. Run `make release` to create the _Release_ target +3. Run `make debug` to create the _Debug_ target (_optional_)
    + The debug target is only necessary in order to modify the sources and to run under a debugger. -### Build Debian Package +The top level Makefile is just a handy wrapper for: -To build the debian package you need the additional packages `devscripts` and `debhelper`. +##### MinGW64: +```sh +$ mkdir build && cd build +$ cmake -DCMAKE_BUILD_TYPE=release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw64.cmake -S .. +$ make ``` -$ git archive --prefix=$(git describe)/ HEAD | bzip2 --stdout > ../libstlink_$(sed -En -e "s/.*\((.*)\).*/\1/" -e "1,1 p" debian/changelog).orig.tar.bz2 -$ debuild -uc -us -``` - -## macOS -### Prerequisites +##### MinGW32: -When compiling on a mac you need the following: - -* A compiler toolchain (XCode) -* cmake -* **libusb 1.0** - -The best way is to install [homebrew](http://brew.sh) which is a package manager for opensource software which is missing from the Apple App Store. Then install the dependencies: - -``` -brew install libusb cmake +```sh +$ mkdir build && cd build +$ cmake -DCMAKE_BUILD_TYPE=release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -S .. +$ make ``` -Compile as described in the first section of this document. - - -## Build using different directories for udev and modprobe +As an alternative you may also install +- to a user folder e.g `$HOME` with `cd build/Release && make install DESTDIR=$HOME` +- or system wide with `cd build/Release && sudo make install`. -To put the udev or the modprobe configuration files into a different directory during installation use the following cmake options: - -``` -$ cmake -DSTLINK_UDEV_RULES_DIR="/usr/lib/udev/rules.d" \ - -DSTLINK_MODPROBED_DIR="/usr/lib/modprobe.d" .. -``` +When installing system-wide, the dynamic library cache needs to be updated with the command `ldconfig`. -## Build using different directory for shared libs +### Build a Debian Package -To put the compiled shared libs into a different directory during installation you can use the following cmake option: +To build the debian package you need the following extra packages: `devscripts debhelper`. +```sh +$ git archive --prefix=$(git describe)/ HEAD | bzip2 --stdout > ../libstlink_$(sed -En -e "s/.*\((.*)\).*/\1/" -e "1,1 p" debian/changelog).orig.tar.bz2 +$ debuild -uc -us ``` -$ cmake -DLIB_INSTALL_DIR:PATH="/usr/lib64" .. -``` - -## Windows (MinGW64) -### Prerequisites -* 7zip -* cmake 2.8 or higher -* MinGW64 GCC toolchain (5.3.0) +### Set permissions with udev +By default most distributions don't allow access to USB devices. +Therefore make sure you install udev files which are necessary to run the tools without root permissions. +udev rules create devices nodes and set the group of these to `stlink`. -### Installation - -1. Install 7zip from -2. Install CMake from -3. Install MinGW64 from (mingw-w64-install.exe) -4. Git clone or download stlink sourcefiles zip +The rules are located in the subdirectory `etc/udev/rules.d` within the sourcefolder. +Copy them to the directory path `/etc/udev/rules.d` and subsequently reload the udev rules: +```sh +$ cp etc/udev/rules.d /etc/udev/rules.d +$ udevadm control --reload-rules +$ udevadm trigger +``` -### Building +Udev will now create device node files `/dev/stlinkv2_XX`, `/dev/stlinkv1_XX`. +You need to ensure that the group `stlink` exists and the user who is trying to access these devices is a member of this group. -Check and execute (in the script folder) `\scripts\mingw64-build.bat` -**NOTE:** when installing different toolchains make sure you edit the path in the `mingw64-build.bat`. -The build script currently uses `C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin` +### Note on the use of STLink-v1 programmers: +At the time of writing the STLink-v1 has mostly been replaced with the newer generation STLink-v2 programmers and thus is only rarely used. +As there are some caveats as well, we recommend to use the STLink-v2 programmers if possible. -## Windows (Visual Studio) -### Prerequisites +To be more precise, the STLINKv1's SCSI emulation is somehow broken, so the best advice possibly is to tell your operating system to completely ignore it. -* 7zip -* cmake (tested with version 3.9.0-rc2) -* Visual Studio 2017 Community Edition (other versions will likely work but are untested; the Community Edition is free for open source -development) +Choose on of the following options _before_ connecting the device to your computer: +* `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` +* _OR_ + 1. `echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.conf` + 2. `modprobe -r usb-storage && modprobe usb-storage` +* _OR_ + 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` + 2. `modprobe -r usb-storage && modprobe usb-storage` -### Installation -1. Install 7zip from -2. Install CMake from -3. Git clone or download stlink sourcefiles zip +Author: nightwalker-87 +----- -### Building +---- **The following content is outdated and unrevised!** ---- -These instructions are for a 32-bit version. +## Mac OS X -In a command prompt, change directory to the folder where the stlink files were cloned (or unzipped). -Make sure the build folder exists (`mkdir build` if not). -From the build folder, run cmake (`cd build; cmake ..`). +When compiling on a mac you need the following: -This will create a solution (stlink.sln) in the build folder. -Open it in Visual Studio, select the Solution Configuration (_Debug_ or _Release_) and build the solution normally (F7). +* A compiler toolchain (XCode) +* CMake +* Libusb 1.0 -NOTES: This solution will link to the dll version of libusb-1.0. -To debug or run the executable, the dll version of libusb-1.0 must be either on the path, or in the same folder as the executable. -It can be copied from here: `build\3thparty\libusb-1.0.21\MS32\dll\libusb-1.0.dll`. +The best way is to install [homebrew](http://brew.sh) which is a package manager + for opensource software which is missing from the Apple App Store. Then install + the dependencies: +``` +brew install libusb cmake +``` -## Linux (MinGW64) -### Prerequisites +Compile as described in the first section of this document. -* 7zip -* cmake 2.8 or higher -* MinGW64 GCC toolchain (5.3.0) +## Build using different directories for udev and modprobe -### Installation (Debian / Ubuntu) +To put the udev or the modprobe configuration files into a different directory +during installation you can use the following cmake options: -sudo apt install p7zip mingw-w64 +``` +$ cmake -DSTLINK_UDEV_RULES_DIR="/usr/lib/udev/rules.d" \ + -DSTLINK_MODPROBED_DIR="/usr/lib/modprobe.d" .. +``` -### Building +## Build using different directory for shared libs -These instructions are for a 32-bit version. +To put the compiled shared libs into a different directory during installation +you can use the following cmake option: -```sh -cd -cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -S . -B ./build/linux-mingw32 -cmake --build ./build/linux-mingw32 --target all +``` +$ cmake -DLIB_INSTALL_DIR:PATH="/usr/lib64" .. ``` diff --git a/doc/version_support.md b/doc/version_support.md new file mode 100644 index 000000000..963ca2988 --- /dev/null +++ b/doc/version_support.md @@ -0,0 +1,82 @@ + +Sources: [pkgs.org - libusb](https://pkgs.org/search/?q=libusb) & [pkgs.org - cmake](https://pkgs.org/search/?q=cmake) (as of Mar 2020): + + +## Supported Operating Systems + +### Microsoft Windows + +On Windows users should ensure that cmake 3.17.0 is installed.
    +Up on compiling c-make will check **automatically**, whether `libusb` 1.0.20 or later is present.
    +If this is not the case, the installation routine will download the latest version (1.0.23 at the time of writing).
    +Thus no user interaction regarding libusb is necessary. + +* Windows 10 +* Windows 8.1 + +### Apple macOS + +On macOS users should ensure that cmake 3.17.0 is installed. + +--> libusb Installation routine: (TBD) Work in progress... + +* macOS 10.15 Catalina +* macOS 10.14 Mojave +* macOS 10.13 High Sierra + +### Linux-/Unix-based: + +| Operating System | libusb
    version | cmake
    version | Notes | +| --- | --- | --- | --- | +| Alpine Edge | 1.0.23 | 3.17.0 | | +| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | | +| Arch Linux | 1.0.23 | 3.17.0 | | +| Fedora Rawhide | 1.0.23 | 3.17.0 | named `libusbx`, but `libusb`-codebase is used | +| KaOS | 1.0.23 | 3.17.0 | | +| OpenMandriva Cooker | 1.0.23 | 3.17.0 | | +| PCLinuxOS | 1.0.23 | 3.17.0 | named `lib64usb1.0_0-1.0.23-1pclos2019.x86_64` | +| Slackware Current | 1.0.23 | 3.17.0 | | +| Solus | 1.0.23 | 3.16.5 | | +| Debian Sid | 1.0.23 | 3.16.3 | | +| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | | +| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | | +| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | | +| Alpine 3.11 | 1.0.23 | 3.15.5 | | +| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | | +| Mageia Cauldron | 1.0.22 | 3.17.0 | | +| NetBSD 9.0 | 1.0.22 | 3.16.1 | | +| NetBSD 8.1 | 1.0.22 | 3.16.1 | | +| NetBSD 7.2 | 1.0.22 | 3.16.1 | | +| Alpine 3.10 | 1.0.22 | 3.14.5 | | +| Fedora 31 | 1.0.22 | 3.14.5 | named `libusbx`, but `libusb`-codebase is used | +| Mageia 7.1 | 1.0.22 | 3.14.3 | | +| Fedora 30 | 1.0.22 | 3.14.2 | named `libusbx`, but `libusb`-codebase is used | +| Debian 10 (Buster) | 1.0.22 | 3.13.4 | | +| Alpine 3.9 | 1.0.22 | 3.13.0 | | +| CentOS 8 | 1.0.22 | 3.11.4 | named `libusbx`, but `libusb`-codebase is used | +| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | | +| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | | +| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | | +| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | | +| Slackware 14.2 | **1.0.20** | 3.5.2 | | +| Ubuntu 16.04 LTS (Xenial Xerus) | **1.0.20** | 3.5.1 | | +| OpenMandriva Lx 3.0 | **1.0.20** | **3.4.2** | | +| FreeBSD 13 | **1.0.16** - 1.0.18 | 3.15.5 | linux_libusb-13.0r358841 (integrated) | +| FreeBSD 12 | **1.0.16** - 1.0.18 | 3.15.5 | linux_libusb-11.0r261448_4 (integrated) | +| FreeBSD 11 | **1.0.16** - 1.0.18 | 3.15.5 | linux_libusb-11.0r261448_4 (integrated) | + + +## Unsupported Operating Systems as of Release 1.6.1 (2020) + +| Operating System | libusb
    version | cmake
    version | End of OS-Support | Notes | +| --- | --- | --- | --- | --- | +| CentOS 7 | 1.0.21 | **2.8.12.2** | | named `libusbx`, but `libusb`-codebase is used | +| Debian 8 (Jessie) | 1.0.**19** | 3.0.2 | Jun 2020 | +| Ubuntu 14.04 LTS (Trusty Tahr) | 1.0.**17** | **2.8.12.2** | Apr 2019 | +| CentOS 6 | 1.0.**9** | **2.8.12.2** | Dec 2020 | named `libusbx`, but `libusb`-codebase is used | +| Slackware 14.1 | 1.0.**9** | **2.8.12** | | +| Slackware 14.0 | 1.0.**9** | **2.8.8** | | + +_All other operating systems which are not listed are unsupported._ + +Author: nightwalker-87 diff --git a/include/stlink/stlinkusb.h b/include/stlink/stlinkusb.h index 4d904b0c5..633d82bd0 100644 --- a/include/stlink/stlinkusb.h +++ b/include/stlink/stlinkusb.h @@ -22,25 +22,25 @@ */ #if defined (__FreeBSD__) -#if !defined ( LIBUSBX_API_VERSION ) -#define LIBUSBX_API_VERSION LIBUSB_API_VERSION -#elif !defined (LIBUSB_API_VERSION) -#error unsupported libusb version -#endif + #if !defined ( LIBUSBX_API_VERSION ) + #define LIBUSBX_API_VERSION LIBUSB_API_VERSION + #elif !defined (LIBUSB_API_VERSION) + #error unsupported libusb version + #endif #endif #if defined (__FreeBSD__) -#define MINIMAL_API_VERSION 0x01000102 + #define MINIMAL_API_VERSION 0x01000102 // v1.0.16 #elif defined (__linux__) -#define MINIMAL_API_VERSION 0x01000104 + #define MINIMAL_API_VERSION 0x01000104 // v1.0.20 #elif defined (__APPLE__) -#define MINIMAL_API_VERSION 0x01000104 + #define MINIMAL_API_VERSION 0x01000104 // v1.0.20 #elif defined (_WIN32) -#define MINIMAL_API_VERSION 0x01000106 + #define MINIMAL_API_VERSION 0x01000104 // v1.0.20 #endif #if ( LIBUSB_API_VERSION < MINIMAL_API_VERSION ) -#error unsupported libusb version + #error unsupported libusb version #endif #endif // STLINKUSB_H diff --git a/scripts/mingw64-build.bat b/scripts/mingw64-build.bat index 3f92ae8e0..773195410 100644 --- a/scripts/mingw64-build.bat +++ b/scripts/mingw64-build.bat @@ -1,5 +1,5 @@ @echo off -set PATH=C:\Program Files (x86)\CMake\bin;C:\Program Files\CMake\bin;C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin;%PATH% +set PATH=C:\Program Files (x86)\CMake\bin;C:\Program Files\CMake\bin;C:\Program Files\mingw-w64\x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0\mingw64\bin;%PATH% cmake -G "MinGW Makefiles" .. mingw32-make mingw32-make install DESTDIR=_install From 587fb48ce4db923cf683b7e9d58471d8166457d3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 5 Apr 2020 14:25:45 +0200 Subject: [PATCH 0769/1435] Updated cmake configuration - Alligned formatting - Updated version requirement - Updated pkg-maintainer - [doc] Added note in compiling manual - Fixed install paths in build script - Updated C-flag -std=gnu99 to gnu11 --- .gitignore | 1 + CMakeLists.txt | 173 ++++++++++++------------- cmake/CPackConfig.cmake | 27 ---- cmake/c_flag_overrides.cmake | 2 +- cmake/{CFlags.cmake => c_flags.cmake} | 12 +- cmake/cpack_config.cmake | 28 ++++ cmake/linux-mingw32.cmake | 6 +- cmake/linux-mingw64.cmake | 6 +- cmake/modules/Find7Zip.cmake | 7 +- cmake/modules/FindLibUSB.cmake | 88 +++++++------ cmake/modules/pandocology.cmake | 2 +- cmake/{Version.cmake => version.cmake} | 7 +- doc/app-example/CMakeLists.txt | 22 ++-- doc/compiling.md | 6 +- doc/man/CMakeLists.txt | 50 +++---- include/CMakeLists.txt | 23 +--- scripts/mingw64-build.bat | 5 +- src/gdbserver/CMakeLists.txt | 7 +- src/tools/gui/CMakeLists.txt | 29 +++-- tests/CMakeLists.txt | 12 +- usr/lib/pkgconfig/CMakeLists.txt | 13 +- 21 files changed, 259 insertions(+), 267 deletions(-) delete mode 100644 cmake/CPackConfig.cmake rename cmake/{CFlags.cmake => c_flags.cmake} (86%) create mode 100644 cmake/cpack_config.cmake rename cmake/{Version.cmake => version.cmake} (94%) diff --git a/.gitignore b/.gitignore index 3a3a5f38a..23e7ddc07 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build +build-mingw obj-* *.user* diff --git a/CMakeLists.txt b/CMakeLists.txt index 306d3d6ff..4c53f05ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,78 +1,81 @@ -cmake_minimum_required(VERSION 2.8.7) +cmake_minimum_required(VERSION 3.4.2) set(CMAKE_USER_MAKE_RULES_OVERRIDE cmake/c_flag_overrides.cmake) + project(stlink C) -set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics Stlink Tools") +set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics ST-LINK Tools") set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "Udev rules directory") set(STLINK_MODPROBED_DIR "/etc/modprobe.d" CACHE PATH "modprobe.d directory") set(STLINK_STATIC_LIB ON CACHE BOOL "Install static lib") -if( IS_DIRECTORY ${LIB_INSTALL_DIR}) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +if (IS_DIRECTORY ${LIB_INSTALL_DIR}) set(LIB_INSTALL_DIR ${LIB_INSTALL_DIR} CACHE PATH "Main library directory") set(STLINK_LIBRARY_PATH "${LIB_INSTALL_DIR}") -else() +else () set(LIB_INSTALL_DIR "lib" CACHE PATH "Main library directory") set(STLINK_LIBRARY_PATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}" ) -endif() +endif () -if( IS_DIRECTORY ${INCLUDE_INSTALL_DIR}) +if (IS_DIRECTORY ${INCLUDE_INSTALL_DIR}) set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_DIR} CACHE PATH "Main include directory") set(STLINK_INCLUDE_PATH "${INCLUDE_INSTALL_DIR}" ) -else() +else () set(INCLUDE_INSTALL_DIR "include" CACHE PATH "Main include directory") set(STLINK_INCLUDE_PATH "${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_DIR}") -endif() +endif () option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) option(STLINK_INSTALL_UDEV_RULES "Install udev rules files" ON) option(STLINK_INSTALL_MODPROBE_CONF "Install modprobe conf files" ON) -if (POLICY CMP0042) - # Newer cmake on MacOS should use @rpath - cmake_policy (SET CMP0042 NEW) -endif () +# cmake (3.0+) on MacOS should use @rpath +cmake_policy(SET CMP0042 NEW) set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") -include(cmake/Version.cmake) -if(NOT MSVC) - include(cmake/CFlags.cmake) -endif() +include(cmake/version.cmake) +if (NOT MSVC) + include(cmake/c_flags.cmake) +endif () ### # Dependencies ### find_package(LibUSB REQUIRED) if (NOT APPLE AND NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) - find_package(PkgConfig) - pkg_check_modules(gtk gtk+-3.0) + find_package(PkgConfig) + pkg_check_modules(gtk gtk+-3.0) endif () include(CheckIncludeFile) CHECK_INCLUDE_FILE(sys/mman.h STLINK_HAVE_SYS_MMAN_H) if (STLINK_HAVE_SYS_MMAN_H) - add_definitions(-DSTLINK_HAVE_SYS_MMAN_H) -endif() + add_definitions(-DSTLINK_HAVE_SYS_MMAN_H) +endif () CHECK_INCLUDE_FILE(unistd.h STLINK_HAVE_UNISTD_H) if (STLINK_HAVE_UNISTD_H) - add_definitions(-DSTLINK_HAVE_UNISTD_H) -endif() + add_definitions(-DSTLINK_HAVE_UNISTD_H) +endif () include(CheckLibraryExists) CHECK_LIBRARY_EXISTS(ssp __stack_chk_fail "" _stack_chk_fail_exists) -if(_stack_chk_fail_exists) +if (_stack_chk_fail_exists) set(SSP_LIB ssp) -else() +else () set(SSP_LIB "") -endif() +endif () if (CMAKE_BUILD_TYPE STREQUAL "") - set(CMAKE_BUILD_TYPE "Debug") -endif() + set(CMAKE_BUILD_TYPE "Debug") +endif () if (${CMAKE_BUILD_TYPE} MATCHES "Debug") - include(CTest) -endif() + include(CTest) +endif () set(STLINK_HEADERS include/stlink.h @@ -82,7 +85,6 @@ set(STLINK_HEADERS include/stlink/mmap.h include/stlink/chipid.h include/stlink/flash_loader.h - include/stlink/stlinkusb.h ) set(STLINK_SOURCE @@ -95,8 +97,8 @@ set(STLINK_SOURCE ) if (WIN32 OR MSYS OR MINGW) - set (STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") - set (STLINK_HEADERS "${STLINK_HEADERS};src/mingw/mingw.h") + set (STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") + set (STLINK_HEADERS "${STLINK_HEADERS};src/mingw/mingw.h") endif () include_directories(${LIBUSB_INCLUDE_DIR}) @@ -104,55 +106,56 @@ include_directories(include) include_directories(${PROJECT_BINARY_DIR}/include) include_directories(src/mingw) if (MSVC) - include_directories(src/win32) - include_directories(src/getopt) - # Use string.h rather than strings.h and disable annoying warnings - add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) + include_directories(src/win32) + include_directories(src/getopt) + # Use string.h rather than strings.h and disable annoying warnings + add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) endif () ### # Shared library ### if (NOT WIN32) -set(STLINK_LIB_SHARED ${PROJECT_NAME}) + set(STLINK_LIB_SHARED ${PROJECT_NAME}) else () -set(STLINK_LIB_SHARED ${PROJECT_NAME}-shared) -endif() + set(STLINK_LIB_SHARED ${PROJECT_NAME}-shared) +endif () -add_library(${STLINK_LIB_SHARED} SHARED - ${STLINK_HEADERS} # header files for ide projects generated by cmake - ${STLINK_SOURCE} -) -target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY}) +add_library( + ${STLINK_LIB_SHARED} SHARED + ${STLINK_HEADERS} # header files for ide projects generated by cmake + ${STLINK_SOURCE} + ) +target_link_libraries( + ${STLINK_LIB_SHARED} + ${LIBUSB_LIBRARY} + ) + +set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) -if (WIN32 OR MSYS OR MINGW) - set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}) -else() - set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) -endif() message(STATUS "STLINK_LIB_SHARED: ${STLINK_LIB_SHARED}") message(STATUS "PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}") message(STATUS "VERSION: ${STLINK_SHARED_VERSION}") set_target_properties(${STLINK_LIB_SHARED} - PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} - VERSION ${STLINK_SHARED_VERSION} -) + PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} + VERSION ${STLINK_SHARED_VERSION} + ) # Link shared library with apple OS libraries if (APPLE) - find_library(ObjC objc) - find_library(CoreFoundation CoreFoundation) - find_library(IOKit IOKit) + find_library(ObjC objc) + find_library(CoreFoundation CoreFoundation) + find_library(IOKit IOKit) target_link_libraries(${STLINK_LIB_SHARED} ${CoreFoundation} ${IOKit} ${ObjC} ${SSP_LIB}) -endif() +endif () if (WIN32 OR MSYS OR MINGW) target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} wsock32 ws2_32 ${SSP_LIB}) -else() +else () target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB}) -endif() +endif () install(TARGETS ${STLINK_LIB_SHARED} @@ -165,31 +168,29 @@ install(TARGETS ${STLINK_LIB_SHARED} set(STLINK_LIB_STATIC ${PROJECT_NAME}-static) add_library(${STLINK_LIB_STATIC} STATIC - ${STLINK_HEADERS} # header files for ide projects generated by cmake - ${STLINK_SOURCE} -) + ${STLINK_HEADERS} # header files for ide projects generated by cmake + ${STLINK_SOURCE} + ) # Link shared library with apple OS libraries if (APPLE) - find_library(ObjC objc) - find_library(CoreFoundation CoreFoundation) - find_library(IOKit IOKit) + find_library(ObjC objc) + find_library(CoreFoundation CoreFoundation) + find_library(IOKit IOKit) target_link_libraries(${STLINK_LIB_STATIC} ${CoreFoundation} ${IOKit} ${ObjC} ${SSP_LIB}) endif() if (WIN32 OR MSYS OR MINGW) target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} wsock32 ws2_32 ${SSP_LIB}) -else() +else () target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB}) -endif() +endif () set_target_properties(${STLINK_LIB_STATIC} PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) if (STLINK_STATIC_LIB) - install(TARGETS ${STLINK_LIB_STATIC} - ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH} - ) -endif() + install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH}) +endif () ### # Tools @@ -197,32 +198,28 @@ endif() add_executable(st-flash src/tools/flash.c src/tools/flash_opts.c) if (WIN32 OR APPLE) target_link_libraries(st-flash ${STLINK_LIB_STATIC} ${SSP_LIB}) -else() +else () target_link_libraries(st-flash ${STLINK_LIB_SHARED} ${SSP_LIB}) -endif() +endif () add_executable(st-info src/tools/info.c) if (WIN32 OR APPLE) target_link_libraries(st-info ${STLINK_LIB_STATIC} ${SSP_LIB}) -else() +else () target_link_libraries(st-info ${STLINK_LIB_SHARED} ${SSP_LIB}) -endif() +endif () -install(TARGETS st-flash st-info - RUNTIME DESTINATION bin -) +install(TARGETS st-flash st-info RUNTIME DESTINATION bin) if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - if (STLINK_INSTALL_MODPROBE_CONF) - install(FILES etc/modprobe.d/stlink_v1.conf - DESTINATION ${STLINK_MODPROBED_DIR}/) - endif() - if (STLINK_INSTALL_UDEV_RULES) - file(GLOB RULES_FILES etc/udev/rules.d/*.rules) - install(FILES ${RULES_FILES} - DESTINATION ${STLINK_UDEV_RULES_DIR}/) - endif() -endif() + if (STLINK_INSTALL_MODPROBE_CONF) + install(FILES etc/modprobe.d/stlink_v1.conf DESTINATION ${STLINK_MODPROBED_DIR}/) + endif () + if (STLINK_INSTALL_UDEV_RULES) + file(GLOB RULES_FILES etc/udev/rules.d/*.rules) + install(FILES ${RULES_FILES} DESTINATION ${STLINK_UDEV_RULES_DIR}/) + endif () +endif () add_subdirectory(src/gdbserver) add_subdirectory(src/tools/gui) @@ -235,5 +232,5 @@ add_subdirectory(include) add_subdirectory(doc/man) add_subdirectory(tests) -include(cmake/CPackConfig.cmake) +include(cmake/cpack_config.cmake) include(CPack) diff --git a/cmake/CPackConfig.cmake b/cmake/CPackConfig.cmake deleted file mode 100644 index 20768453b..000000000 --- a/cmake/CPackConfig.cmake +++ /dev/null @@ -1,27 +0,0 @@ -set (CPACK_PACKAGE_NAME ${PROJECT_NAME}) -set (CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) -set (CPACK_SET_DESTDIR "ON") -if (APPLE) - set(CPACK_GENERATOR "ZIP") - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-macosx-amd64") - file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/osx") - set (CPACK_INSTALL_PREFIX "") - set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/osx") -elseif (WIN32) - set(CPACK_GENERATOR "ZIP") - file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/windows") - set (CPACK_INSTALL_PREFIX "") - set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/windows") -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND EXISTS "/etc/debian_version") - message(STATUS "Debian-based Linux OS detected") - set(CPACK_GENERATOR "DEB") - - if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") - set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}-amd64" ) - endif() - - set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/texane/stlink") - set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Jerry Jacobs") - set(CPACK_PACKAGE_CONTACT "jerry.jacobs@xor-gate.org") - set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "STM32 stlink programmer tools") -endif() diff --git a/cmake/c_flag_overrides.cmake b/cmake/c_flag_overrides.cmake index 663e08175..c15815e17 100644 --- a/cmake/c_flag_overrides.cmake +++ b/cmake/c_flag_overrides.cmake @@ -1,6 +1,6 @@ if(MSVC) message(STATUS "MSVC C Flags override to /MT") - set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") + set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") diff --git a/cmake/CFlags.cmake b/cmake/c_flags.cmake similarity index 86% rename from cmake/CFlags.cmake rename to cmake/c_flags.cmake index b76856d24..fbadd6d9e 100644 --- a/cmake/CFlags.cmake +++ b/cmake/c_flags.cmake @@ -14,7 +14,7 @@ function(add_cflag_if_supported flag) endif() endfunction() -add_cflag_if_supported("-std=gnu99") +add_cflag_if_supported("-std=gnu11") add_cflag_if_supported("-Wall") add_cflag_if_supported("-Wextra") add_cflag_if_supported("-Wshadow") @@ -34,17 +34,17 @@ add_cflag_if_supported("-Wimplicit-function-declaration") # /usr/include/sys/types.h:218: warning: previous declaration of 'truncate' was here ## if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") - add_cflag_if_supported("-Wredundant-decls") + add_cflag_if_supported("-Wredundant-decls") endif () if (NOT WIN32) - add_cflag_if_supported("-fPIC") + add_cflag_if_supported("-fPIC") endif () if(${CMAKE_BUILD_TYPE} MATCHES "Debug") - add_cflag_if_supported("-ggdb") - add_cflag_if_supported("-O0") + add_cflag_if_supported("-ggdb") + add_cflag_if_supported("-O0") else() - add_cflag_if_supported("-O2") + add_cflag_if_supported("-O2") add_cflag_if_supported("-Werror") endif() diff --git a/cmake/cpack_config.cmake b/cmake/cpack_config.cmake new file mode 100644 index 000000000..72a98a821 --- /dev/null +++ b/cmake/cpack_config.cmake @@ -0,0 +1,28 @@ +set (CPACK_PACKAGE_NAME ${PROJECT_NAME}) +set (CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) +set (CPACK_SET_DESTDIR "ON") + +if (APPLE) + set(CPACK_GENERATOR "ZIP") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-macosx-amd64") + file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/osx") + set (CPACK_INSTALL_PREFIX "") + set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/osx") +elseif (WIN32) + set(CPACK_GENERATOR "ZIP") + file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/windows") + set (CPACK_INSTALL_PREFIX "") + set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/windows") +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND EXISTS "/etc/debian_version") + message(STATUS "Debian-based Linux OS detected") + set(CPACK_GENERATOR "DEB") + + if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") + set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}-amd64" ) + endif() + + set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/texane/stlink") + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Luca Boccassi") + set(CPACK_PACKAGE_CONTACT "bluca@debian.org") + set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "STM32 STlink programmer tools") +endif() diff --git a/cmake/linux-mingw32.cmake b/cmake/linux-mingw32.cmake index 2044a7e22..2b4799037 100644 --- a/cmake/linux-mingw32.cmake +++ b/cmake/linux-mingw32.cmake @@ -1,4 +1,4 @@ -# Sample toolchain file for building for Windows from an Debian/Ubuntu Linux system. +# Sample toolchain file for building for Windows from a Debian/Ubuntu Linux system. # # Typical usage: # *) install cross compiler: `sudo apt-get install mingw-w64` @@ -14,7 +14,7 @@ set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) # target environment on the build host system -# set 1st to dir with the cross compiler's C/C++ headers/libs +# set 1st to dir with the cross compiler's C/C++ headers/libs set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) # modify default behavior of FIND_XXX() commands to @@ -22,4 +22,4 @@ set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) # search for programs in the build host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) \ No newline at end of file +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/cmake/linux-mingw64.cmake b/cmake/linux-mingw64.cmake index db4bd70d0..f8b523965 100644 --- a/cmake/linux-mingw64.cmake +++ b/cmake/linux-mingw64.cmake @@ -1,4 +1,4 @@ -# Sample toolchain file for building for Windows from an Ubuntu Linux system. +# Sample toolchain file for building for Windows from a Debian/Ubuntu Linux system. # # Typical usage: # *) install cross compiler: `sudo apt-get install mingw-w64` @@ -14,7 +14,7 @@ set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) # target environment on the build host system -# set 1st to dir with the cross compiler's C/C++ headers/libs +# set 1st to dir with the cross compiler's C/C++ headers/libs set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) # modify default behavior of FIND_XXX() commands to @@ -22,4 +22,4 @@ set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) # search for programs in the build host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) \ No newline at end of file +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/cmake/modules/Find7Zip.cmake b/cmake/modules/Find7Zip.cmake index e4d33dfce..c462f73de 100644 --- a/cmake/modules/Find7Zip.cmake +++ b/cmake/modules/Find7Zip.cmake @@ -1,5 +1,4 @@ -find_program(ZIP_EXECUTABLE NAMES 7z.exe p7zip - HINTS - "C:\\Program Files\\7-Zip\\" - "C:\\Program Files (x86)\\7-Zip\\" +find_program( + ZIP_EXECUTABLE NAMES 7z.exe p7zip + HINTS "C:\\Program Files\\7-Zip\\" "C:\\Program Files (x86)\\7-Zip\\" ) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index c8f467902..a8b65cba3 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -8,56 +8,60 @@ if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD - FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h - HINTS - /usr/include - ) + FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS + /usr/include + ) else () # other OS - FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h - HINTS - /usr - /usr/local - /opt - PATH_SUFFIXES libusb-1.0 - ) + FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS + /usr + /usr/local + /opt + PATH_SUFFIXES libusb-1.0 + ) endif() # macOS if (APPLE) - set(LIBUSB_NAME libusb-1.0.a) + set(LIBUSB_NAME libusb-1.0.a) elseif(MSYS OR MINGW) - set(LIBUSB_NAME usb-1.0) + set(LIBUSB_NAME usb-1.0) elseif(MSVC) - set(LIBUSB_NAME libusb-1.0.lib) + set(LIBUSB_NAME libusb-1.0.lib) elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") - set(LIBUSB_NAME usb) + set(LIBUSB_NAME usb) else() - set(LIBUSB_NAME usb-1.0) + set(LIBUSB_NAME usb-1.0) endif() if (MSYS OR MINGW) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/static) - else () - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static) - endif () -elseif(MSVC) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/static) + else () + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static) + endif () +elseif (MSVC) + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll) - else () - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll) - endif () + else () + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll) + endif () else() - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS - /usr - /usr/local - /opt) + find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS + /usr + /usr/local + /opt) endif () include(FindPackageHandleStandardArgs) @@ -72,7 +76,7 @@ if(NOT LIBUSB_FOUND) set(LIBUSB_WIN_VERSION 1.0.23) set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) - set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3thparty/libusb-${LIBUSB_WIN_VERSION}) + set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3rdparty/libusb-${LIBUSB_WIN_VERSION}) if(EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) message(STATUS "libusb archive already in build folder") @@ -102,13 +106,15 @@ if(NOT LIBUSB_FOUND) if (MSYS OR MINGW) if (CMAKE_SIZEOF_VOID_P EQUAL 8) - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/static NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) else () - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH @@ -116,13 +122,15 @@ if(NOT LIBUSB_FOUND) endif () elseif(MSVC) if (CMAKE_SIZEOF_VOID_P EQUAL 8) - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) else () - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH diff --git a/cmake/modules/pandocology.cmake b/cmake/modules/pandocology.cmake index f39f8d952..763eae558 100644 --- a/cmake/modules/pandocology.cmake +++ b/cmake/modules/pandocology.cmake @@ -93,6 +93,7 @@ function(pandocology_get_file_extension varname filename) STRING(REGEX MATCH "\\.[^.]*\$" result "${name}") SET(${varname} "${result}" PARENT_SCOPE) endfunction() + ############################################################################### function(pandocology_add_input_dir source_dir dest_parent_dir dir_dest_filelist_var) @@ -370,4 +371,3 @@ endfunction() function(add_pandoc_document) add_document(${ARGV}) endfunction() - diff --git a/cmake/Version.cmake b/cmake/version.cmake similarity index 94% rename from cmake/Version.cmake rename to cmake/version.cmake index 71859015c..bdfe95ace 100644 --- a/cmake/Version.cmake +++ b/cmake/version.cmake @@ -60,8 +60,6 @@ else() message(STATUS "Git or repo not found.") endif() - - if(NOT __detect_version) message(STATUS "Try to detect version from \"${PROJECT_SOURCE_DIR}/.version\" file.") if(EXISTS ${PROJECT_SOURCE_DIR}/.version) @@ -71,7 +69,7 @@ if(NOT __detect_version) # TODO create function to extract semver from file or string and check if it is correct instead of copy-pasting string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" - "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) + "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) list(LENGTH PROJECT_VERSION_LIST len) if(len EQUAL 3) list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) @@ -90,6 +88,5 @@ if(NOT __detect_version) message(FATAL_ERROR "Unable to determine project version") endif() - message(STATUS "stlink version: ${PROJECT_VERSION}") -message(STATUS " Major ${PROJECT_VERSION_MAJOR} Minor ${PROJECT_VERSION_MINOR} Patch ${PROJECT_VERSION_PATCH}") +message(STATUS "Major ${PROJECT_VERSION_MAJOR} Minor ${PROJECT_VERSION_MINOR} Patch ${PROJECT_VERSION_PATCH}") diff --git a/doc/app-example/CMakeLists.txt b/doc/app-example/CMakeLists.txt index 0e91bed6f..a7697720c 100644 --- a/doc/app-example/CMakeLists.txt +++ b/doc/app-example/CMakeLists.txt @@ -1,12 +1,11 @@ -# Warning: This example assumes that you are building on a host -# with pkg-config available (e.g. linux). The logic required to -# build under windows/mingw and/or mac was intentionally omitted -# to keep this CMakeLists as small as possible +# Warning: This example assumes that you are building on a host with pkg-config available (e.g. linux). +# The logic required to build under windows/mingw and/or mac was intentionally omitted to keep this +# CMakeLists as small as possible. -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.4.2) project(st-hello) -set(PROJECT_VERSION 0.1) +set(PROJECT_VERSION 0.1) set(SRCS main.c) find_package(PkgConfig) @@ -14,15 +13,10 @@ pkg_check_modules(STLINK REQUIRED stlink) set(CMAKE_C_FLAGS " ${STLINK_CFLAGS_OTHER} -Wall -Werror") -include_directories( - ${STLINK_INCLUDE_DIRS} -) +include_directories(${STLINK_INCLUDE_DIRS}) add_executable(${PROJECT_NAME} ${SRCS}) -target_link_libraries(${PROJECT_NAME} - ${STLINK_LIBRARIES} -) +target_link_libraries(${PROJECT_NAME} ${STLINK_LIBRARIES}) -install(TARGETS ${PROJECT_NAME} - DESTINATION bin) +install(TARGETS ${PROJECT_NAME} DESTINATION bin) diff --git a/doc/compiling.md b/doc/compiling.md index 0133981b1..bcaf7d567 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -15,10 +15,10 @@ On Windows users should ensure that the following software is installed: 1. Install `7zip` from 2. Install `git` from -3. Install `cmake` from +3. Install `cmake` from
    + Ensure that you add cmake to the $PATH system variable when following the instructions by the setup assistant. 4. Install - _EITHER_: **MinGW-w64** from (mingw-w64-install.exe)
    - Ensure that you add MinGW to the $PATH system variable when following the instructions by the setup assistant.
    - _OR_: **Visual Studio 2017 CE** (other versions will likely work as well, but are untested; the Community edition is free for open source development) 5. Create a new destination folder at a place of your choice @@ -51,7 +51,7 @@ Release) and build the solution normally (F7). NOTE:
    This solution will link to the dll version of libusb-1.0.y
    To debug or run the executable, the dll version of libusb-1.0 must be either on the path, or in the same folder as the executable.
    -It can be copied from here: `build\3thparty\libusb-1.0.21\MS32\dll\libusb-1.0.dll`. +It can be copied from here: `build\3rdparty\libusb-1.0.21\MS32\dll\libusb-1.0.dll`. ## Linux ### Common requirements diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 949cd2fcf..dce8fbfa6 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -1,37 +1,37 @@ set(MANPAGES - st-util - st-flash - st-info -) + st-util + st-flash + st-info + ) # Only generate manpages with pandoc in Debug builds if(${STLINK_GENERATE_MANPAGES}) - include(pandocology) + include(pandocology) - foreach(manpage ${MANPAGES}) - add_document( - ${manpage}.1 - SOURCES ${manpage}.md - PANDOC_DIRECTIVES -s -t man - PRODUCT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) - endforeach() + foreach(manpage ${MANPAGES}) + add_document( + ${manpage}.1 + SOURCES ${manpage}.md + PANDOC_DIRECTIVES -s -t man + PRODUCT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + endforeach() else() - message(STATUS "Manpage generation disabled") + message(STATUS "Manpage generation disabled") endif() # Install from output folder or this folder foreach(manpage ${MANPAGES}) - if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1) - set(f "${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1") - elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") - set(f "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") - else() - message(AUTHOR_WARNING "Manpage ${manpage} not generated") - endif() + if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1) + set(f "${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1") + elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") + set(f "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") + else() + message(AUTHOR_WARNING "Manpage ${manpage} not generated") + endif() - if (f AND NOT WIN32) - install(FILES ${f} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1) - unset(f) - endif() + if (f AND NOT WIN32) + install(FILES ${f} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1) + unset(f) + endif() endforeach() diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index a5121aee5..94df89958 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,17 +1,8 @@ configure_file( - "${PROJECT_SOURCE_DIR}/include/stlink/version.h.in" - "${CMAKE_BINARY_DIR}/include/stlink/version.h" -) -file(GLOB STLINK_HEADERS - "stlink/*.h" - "${CMAKE_BINARY_DIR}/include/stlink/*.h" -) -install(FILES ${CMAKE_SOURCE_DIR}/include/stlink.h - DESTINATION ${STLINK_INCLUDE_PATH} -) -install(FILES ${CMAKE_SOURCE_DIR}/include/stm32.h - DESTINATION ${STLINK_INCLUDE_PATH} -) -install(FILES ${STLINK_HEADERS} - DESTINATION ${STLINK_INCLUDE_PATH}/stlink -) + "${PROJECT_SOURCE_DIR}/include/stlink/version.h.in" + "${CMAKE_BINARY_DIR}/include/stlink/version.h" + ) +file(GLOB STLINK_HEADERS "stlink/*.h" "${CMAKE_BINARY_DIR}/include/stlink/*.h") +install(FILES ${CMAKE_SOURCE_DIR}/include/stlink.h DESTINATION ${STLINK_INCLUDE_PATH}) +install(FILES ${CMAKE_SOURCE_DIR}/include/stm32.h DESTINATION ${STLINK_INCLUDE_PATH}) +install(FILES ${STLINK_HEADERS} DESTINATION ${STLINK_INCLUDE_PATH}/stlink) diff --git a/scripts/mingw64-build.bat b/scripts/mingw64-build.bat index 773195410..15ec21cd0 100644 --- a/scripts/mingw64-build.bat +++ b/scripts/mingw64-build.bat @@ -1,5 +1,8 @@ @echo off -set PATH=C:\Program Files (x86)\CMake\bin;C:\Program Files\CMake\bin;C:\Program Files\mingw-w64\x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0\mingw64\bin;%PATH% +cd .. +mkdir build-mingw +cd build-mingw +set PATH=C:\Program Files (x86)\CMake\bin;C:\Program Files\CMake\bin;C:\Program Files\mingw-w64\x86_64-8.1.0-win32-sjlj-rt_v6-rev0\mingw64\bin;%PATH% cmake -G "MinGW Makefiles" .. mingw32-make mingw32-make install DESTDIR=_install diff --git a/src/gdbserver/CMakeLists.txt b/src/gdbserver/CMakeLists.txt index b4674ebbb..5fb0c1ab8 100644 --- a/src/gdbserver/CMakeLists.txt +++ b/src/gdbserver/CMakeLists.txt @@ -4,7 +4,8 @@ set(STUTIL_SOURCE gdb-server.c gdb-server.h semihosting.c - semihosting.h) + semihosting.h + ) if (MSVC) # We need a getopt from somewhere... @@ -19,6 +20,4 @@ else() target_link_libraries(st-util ${STLINK_LIB_SHARED} ${SSP_LIB}) endif() -install(TARGETS st-util - RUNTIME DESTINATION bin -) +install(TARGETS st-util RUNTIME DESTINATION bin) diff --git a/src/tools/gui/CMakeLists.txt b/src/tools/gui/CMakeLists.txt index 91aabc53b..850f483a9 100644 --- a/src/tools/gui/CMakeLists.txt +++ b/src/tools/gui/CMakeLists.txt @@ -1,5 +1,6 @@ if (NOT gtk_FOUND) - return() + message(STATUS "gtk not found!") + return() endif() set(GUI_SOURCES stlink-gui.c stlink-gui.h) @@ -8,26 +9,26 @@ set(INSTALLED_UI_DIR share/stlink) include_directories(SYSTEM ${gtk_INCLUDE_DIRS}) add_executable(stlink-gui-local ${GUI_SOURCES}) -set_target_properties(stlink-gui-local PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}") +set_target_properties( + stlink-gui-local PROPERTIES + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}" + ) target_link_libraries(stlink-gui-local ${STLINK_LIB_STATIC} ${gtk_LDFLAGS} ${SSP_LIB}) add_executable(stlink-gui ${GUI_SOURCES}) -set_target_properties(stlink-gui PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}") +set_target_properties( + stlink-gui PROPERTIES + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}" + ) target_link_libraries(stlink-gui ${STLINK_LIB_STATIC} ${gtk_LDFLAGS} ${SSP_LIB}) -install(TARGETS stlink-gui - RUNTIME DESTINATION bin) -install(FILES stlink-gui.ui - DESTINATION ${INSTALLED_UI_DIR}) +install(TARGETS stlink-gui RUNTIME DESTINATION bin) +install(FILES stlink-gui.ui DESTINATION ${INSTALLED_UI_DIR}) + if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") # Install desktop entry - install(FILES stlink-gui.desktop - DESTINATION share/applications) + install(FILES stlink-gui.desktop DESTINATION share/applications) # Install icon - install(FILES art/stlink-gui.svg - DESTINATION share/icons/hicolor/scalable/apps) + install(FILES art/stlink-gui.svg DESTINATION share/icons/hicolor/scalable/apps) endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9d0bdffaf..e8ec5fec0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,13 +1,13 @@ set(TESTS - usb - sg -) + usb + sg + ) foreach(test ${TESTS}) - add_executable(${test} ${test}.c) - add_dependencies(${test} ${STLINK_LIB_STATIC}) + add_executable(${test} ${test}.c) + add_dependencies(${test} ${STLINK_LIB_STATIC}) target_link_libraries(${test} ${STLINK_LIB_STATIC} ${SSP_LIB}) - add_test(${test} ${CMAKE_CURRENT_BINARY_DIR}/${test}) + add_test(${test} ${CMAKE_CURRENT_BINARY_DIR}/${test}) endforeach() add_executable(flash flash.c "${CMAKE_SOURCE_DIR}/src/tools/flash_opts.c") diff --git a/usr/lib/pkgconfig/CMakeLists.txt b/usr/lib/pkgconfig/CMakeLists.txt index a656ff623..5a8227125 100644 --- a/usr/lib/pkgconfig/CMakeLists.txt +++ b/usr/lib/pkgconfig/CMakeLists.txt @@ -5,10 +5,11 @@ set(PKG_CONFIG_CFLAGS "-I\${includedir}") set(PKG_CONFIG_REQUIRES "libusb-1.0") configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" -) + "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + ) -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" - DESTINATION ${STLINK_LIBRARY_PATH}/pkgconfig/ -) +install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + DESTINATION ${STLINK_LIBRARY_PATH}/pkgconfig/ + ) From 1818d9375d324cb4c02809e9204abe419805be30 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 5 Apr 2020 14:57:59 +0200 Subject: [PATCH 0770/1435] Fixed indentation & whitespace. --- CMakeLists.txt | 103 +++++++++++++++++-------------- doc/man/CMakeLists.txt | 59 ++++++++---------- include/CMakeLists.txt | 4 +- src/gdbserver/CMakeLists.txt | 6 +- src/tools/gui/CMakeLists.txt | 10 +-- tests/CMakeLists.txt | 15 ++--- usr/lib/pkgconfig/CMakeLists.txt | 6 +- 7 files changed, 103 insertions(+), 100 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c53f05ea..5d5dab72e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,9 +40,11 @@ if (NOT MSVC) include(cmake/c_flags.cmake) endif () + ### # Dependencies ### + find_package(LibUSB REQUIRED) if (NOT APPLE AND NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) find_package(PkgConfig) @@ -78,27 +80,27 @@ if (${CMAKE_BUILD_TYPE} MATCHES "Debug") endif () set(STLINK_HEADERS - include/stlink.h - include/stlink/usb.h - include/stlink/sg.h - include/stlink/logging.h - include/stlink/mmap.h - include/stlink/chipid.h - include/stlink/flash_loader.h -) + include/stlink.h + include/stlink/usb.h + include/stlink/sg.h + include/stlink/logging.h + include/stlink/mmap.h + include/stlink/chipid.h + include/stlink/flash_loader.h + ) set(STLINK_SOURCE - src/chipid.c - src/common.c - src/usb.c - src/sg.c - src/logging.c - src/flash_loader.c -) + src/chipid.c + src/common.c + src/usb.c + src/sg.c + src/logging.c + src/flash_loader.c + ) if (WIN32 OR MSYS OR MINGW) set (STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") - set (STLINK_HEADERS "${STLINK_HEADERS};src/mingw/mingw.h") + set (STLINK_HEADERS "${STLINK_HEADERS};src/mingw/mingw.h") endif () include_directories(${LIBUSB_INCLUDE_DIR}) @@ -106,15 +108,17 @@ include_directories(include) include_directories(${PROJECT_BINARY_DIR}/include) include_directories(src/mingw) if (MSVC) - include_directories(src/win32) - include_directories(src/getopt) - # Use string.h rather than strings.h and disable annoying warnings - add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) + include_directories(src/win32) + include_directories(src/getopt) + # Use string.h rather than strings.h and disable annoying warnings + add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) endif () + ### # Shared library ### + if (NOT WIN32) set(STLINK_LIB_SHARED ${PROJECT_NAME}) else () @@ -123,8 +127,8 @@ endif () add_library( ${STLINK_LIB_SHARED} SHARED - ${STLINK_HEADERS} # header files for ide projects generated by cmake - ${STLINK_SOURCE} + ${STLINK_HEADERS} # header files for ide projects generated by cmake + ${STLINK_SOURCE} ) target_link_libraries( ${STLINK_LIB_SHARED} @@ -133,21 +137,21 @@ target_link_libraries( set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) - message(STATUS "STLINK_LIB_SHARED: ${STLINK_LIB_SHARED}") message(STATUS "PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}") message(STATUS "VERSION: ${STLINK_SHARED_VERSION}") -set_target_properties(${STLINK_LIB_SHARED} +set_target_properties( + ${STLINK_LIB_SHARED} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} - VERSION ${STLINK_SHARED_VERSION} + VERSION ${STLINK_SHARED_VERSION} ) # Link shared library with apple OS libraries if (APPLE) - find_library(ObjC objc) - find_library(CoreFoundation CoreFoundation) - find_library(IOKit IOKit) + find_library(ObjC objc) + find_library(CoreFoundation CoreFoundation) + find_library(IOKit IOKit) target_link_libraries(${STLINK_LIB_SHARED} ${CoreFoundation} ${IOKit} ${ObjC} ${SSP_LIB}) endif () @@ -157,28 +161,31 @@ else () target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB}) endif () +install( + TARGETS ${STLINK_LIB_SHARED} + DESTINATION ${STLINK_LIBRARY_PATH} + ) -install(TARGETS ${STLINK_LIB_SHARED} - DESTINATION ${STLINK_LIBRARY_PATH} -) ### # Static library ### + set(STLINK_LIB_STATIC ${PROJECT_NAME}-static) -add_library(${STLINK_LIB_STATIC} STATIC - ${STLINK_HEADERS} # header files for ide projects generated by cmake - ${STLINK_SOURCE} - ) +add_library( + ${STLINK_LIB_STATIC} STATIC + ${STLINK_HEADERS} # header files for ide projects generated by cmake + ${STLINK_SOURCE} +) # Link shared library with apple OS libraries if (APPLE) - find_library(ObjC objc) - find_library(CoreFoundation CoreFoundation) - find_library(IOKit IOKit) + find_library(ObjC objc) + find_library(CoreFoundation CoreFoundation) + find_library(IOKit IOKit) target_link_libraries(${STLINK_LIB_STATIC} ${CoreFoundation} ${IOKit} ${ObjC} ${SSP_LIB}) -endif() +endif () if (WIN32 OR MSYS OR MINGW) target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} wsock32 ws2_32 ${SSP_LIB}) @@ -192,9 +199,11 @@ if (STLINK_STATIC_LIB) install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH}) endif () + ### # Tools ### + add_executable(st-flash src/tools/flash.c src/tools/flash_opts.c) if (WIN32 OR APPLE) target_link_libraries(st-flash ${STLINK_LIB_STATIC} ${SSP_LIB}) @@ -212,21 +221,23 @@ endif () install(TARGETS st-flash st-info RUNTIME DESTINATION bin) if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - if (STLINK_INSTALL_MODPROBE_CONF) - install(FILES etc/modprobe.d/stlink_v1.conf DESTINATION ${STLINK_MODPROBED_DIR}/) - endif () - if (STLINK_INSTALL_UDEV_RULES) - file(GLOB RULES_FILES etc/udev/rules.d/*.rules) - install(FILES ${RULES_FILES} DESTINATION ${STLINK_UDEV_RULES_DIR}/) - endif () + if (STLINK_INSTALL_MODPROBE_CONF) + install(FILES etc/modprobe.d/stlink_v1.conf DESTINATION ${STLINK_MODPROBED_DIR}/) + endif () + if (STLINK_INSTALL_UDEV_RULES) + file(GLOB RULES_FILES etc/udev/rules.d/*.rules) + install(FILES ${RULES_FILES} DESTINATION ${STLINK_UDEV_RULES_DIR}/) + endif () endif () add_subdirectory(src/gdbserver) add_subdirectory(src/tools/gui) + ### # Others ### + add_subdirectory(usr/lib/pkgconfig) add_subdirectory(include) add_subdirectory(doc/man) diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index dce8fbfa6..5b435c022 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -1,37 +1,32 @@ -set(MANPAGES - st-util - st-flash - st-info - ) +set(MANPAGES st-util st-flash st-info) # Only generate manpages with pandoc in Debug builds -if(${STLINK_GENERATE_MANPAGES}) - include(pandocology) - - foreach(manpage ${MANPAGES}) - add_document( - ${manpage}.1 - SOURCES ${manpage}.md - PANDOC_DIRECTIVES -s -t man - PRODUCT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) - endforeach() -else() - message(STATUS "Manpage generation disabled") -endif() +if (${STLINK_GENERATE_MANPAGES}) + include(pandocology) + foreach (manpage ${MANPAGES}) + add_document( + ${manpage}.1 + SOURCES ${manpage}.md + PANDOC_DIRECTIVES -s -t man + PRODUCT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + endforeach () +else () + message(STATUS "Manpage generation disabled") +endif () # Install from output folder or this folder -foreach(manpage ${MANPAGES}) - if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1) - set(f "${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1") - elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") - set(f "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") - else() - message(AUTHOR_WARNING "Manpage ${manpage} not generated") - endif() +foreach (manpage ${MANPAGES}) + if (EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1) + set(f "${CMAKE_CURRENT_BINARY_DIR}/${manpage}.1") + elseif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") + set(f "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") + else() + message(AUTHOR_WARNING "Manpage ${manpage} not generated") + endif() - if (f AND NOT WIN32) - install(FILES ${f} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1) - unset(f) - endif() -endforeach() + if (f AND NOT WIN32) + install(FILES ${f} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1) + unset(f) + endif () +endforeach () diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 94df89958..6e5e3c279 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,6 +1,6 @@ configure_file( - "${PROJECT_SOURCE_DIR}/include/stlink/version.h.in" - "${CMAKE_BINARY_DIR}/include/stlink/version.h" + "${PROJECT_SOURCE_DIR}/include/stlink/version.h.in" + "${CMAKE_BINARY_DIR}/include/stlink/version.h" ) file(GLOB STLINK_HEADERS "stlink/*.h" "${CMAKE_BINARY_DIR}/include/stlink/*.h") install(FILES ${CMAKE_SOURCE_DIR}/include/stlink.h DESTINATION ${STLINK_INCLUDE_PATH}) diff --git a/src/gdbserver/CMakeLists.txt b/src/gdbserver/CMakeLists.txt index 5fb0c1ab8..ff9bde165 100644 --- a/src/gdbserver/CMakeLists.txt +++ b/src/gdbserver/CMakeLists.txt @@ -10,14 +10,14 @@ set(STUTIL_SOURCE if (MSVC) # We need a getopt from somewhere... set(STUTIL_SOURCE "${STUTIL_SOURCE};../getopt/getopt.c") -endif() +endif () add_executable(st-util ${STUTIL_SOURCE}) if (WIN32 OR APPLE) target_link_libraries(st-util ${STLINK_LIB_STATIC} ${SSP_LIB}) -else() +else () target_link_libraries(st-util ${STLINK_LIB_SHARED} ${SSP_LIB}) -endif() +endif () install(TARGETS st-util RUNTIME DESTINATION bin) diff --git a/src/tools/gui/CMakeLists.txt b/src/tools/gui/CMakeLists.txt index 850f483a9..d7add834b 100644 --- a/src/tools/gui/CMakeLists.txt +++ b/src/tools/gui/CMakeLists.txt @@ -1,7 +1,7 @@ if (NOT gtk_FOUND) message(STATUS "gtk not found!") - return() -endif() + return() +endif () set(GUI_SOURCES stlink-gui.c stlink-gui.h) set(INSTALLED_UI_DIR share/stlink) @@ -12,7 +12,7 @@ add_executable(stlink-gui-local ${GUI_SOURCES}) set_target_properties( stlink-gui-local PROPERTIES COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}" - ) + ) target_link_libraries(stlink-gui-local ${STLINK_LIB_STATIC} ${gtk_LDFLAGS} ${SSP_LIB}) @@ -20,7 +20,7 @@ add_executable(stlink-gui ${GUI_SOURCES}) set_target_properties( stlink-gui PROPERTIES COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}" - ) + ) target_link_libraries(stlink-gui ${STLINK_LIB_STATIC} ${gtk_LDFLAGS} ${SSP_LIB}) install(TARGETS stlink-gui RUNTIME DESTINATION bin) @@ -31,4 +31,4 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") install(FILES stlink-gui.desktop DESTINATION share/applications) # Install icon install(FILES art/stlink-gui.svg DESTINATION share/icons/hicolor/scalable/apps) -endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") +endif () diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e8ec5fec0..c6b04ddb3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,14 +1,11 @@ -set(TESTS - usb - sg - ) +set(TESTS usb sg) -foreach(test ${TESTS}) - add_executable(${test} ${test}.c) - add_dependencies(${test} ${STLINK_LIB_STATIC}) +foreach (test ${TESTS}) + add_executable(${test} ${test}.c) + add_dependencies(${test} ${STLINK_LIB_STATIC}) target_link_libraries(${test} ${STLINK_LIB_STATIC} ${SSP_LIB}) - add_test(${test} ${CMAKE_CURRENT_BINARY_DIR}/${test}) -endforeach() + add_test(${test} ${CMAKE_CURRENT_BINARY_DIR}/${test}) +endforeach () add_executable(flash flash.c "${CMAKE_SOURCE_DIR}/src/tools/flash_opts.c") target_link_libraries(flash ${STLINK_LIB_STATIC} ${SSP_LIB}) diff --git a/usr/lib/pkgconfig/CMakeLists.txt b/usr/lib/pkgconfig/CMakeLists.txt index 5a8227125..02e80cb72 100644 --- a/usr/lib/pkgconfig/CMakeLists.txt +++ b/usr/lib/pkgconfig/CMakeLists.txt @@ -5,11 +5,11 @@ set(PKG_CONFIG_CFLAGS "-I\${includedir}") set(PKG_CONFIG_REQUIRES "libusb-1.0") configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" ) install( FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" - DESTINATION ${STLINK_LIBRARY_PATH}/pkgconfig/ + DESTINATION ${STLINK_LIBRARY_PATH}/pkgconfig/ ) From e7ed76bd12ab6cb022b4c011fa706eae69ad77f8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 5 Apr 2020 18:01:49 +0200 Subject: [PATCH 0771/1435] Added cmake uninstall target (Fixes #619) --- CMakeLists.txt | 15 +++++++++++++++ cmake_uninstall.cmake.in | 21 +++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 cmake_uninstall.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d5dab72e..df5033f7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -245,3 +245,18 @@ add_subdirectory(tests) include(cmake/cpack_config.cmake) include(CPack) + + +### +# Uninstall target +### + +if (NOT TARGET uninstall) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY + ) + add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) +endif () diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in new file mode 100644 index 000000000..ed17c45cd --- /dev/null +++ b/cmake_uninstall.cmake.in @@ -0,0 +1,21 @@ +if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") +endif() + +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach (file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if (IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program("@CMAKE_COMMAND@" + ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if (NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif () + else (IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif () +endforeach () From 41f8417eaa196a7f8247b52f604bf8eb946e5f30 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 5 Apr 2020 18:12:39 +0200 Subject: [PATCH 0772/1435] Integrated module GNUInstallDirs.cmake (Fixes #557) --- CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index df5033f7e..f46a5f591 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,8 +3,9 @@ set(CMAKE_USER_MAKE_RULES_OVERRIDE cmake/c_flag_overrides.cmake) project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics ST-LINK Tools") -set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "Udev rules directory") -set(STLINK_MODPROBED_DIR "/etc/modprobe.d" CACHE PATH "modprobe.d directory") +include(GNUInstallDirs) +set(STLINK_UDEV_RULES_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/udev/rules.d" CACHE PATH "Udev rules directory") +set(STLINK_MODPROBED_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/modprobe.d" CACHE PATH "modprobe.d directory") set(STLINK_STATIC_LIB ON CACHE BOOL "Install static lib") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) From 7158df1de436ba7bec96181bc853e685ca27062a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 5 Apr 2020 22:02:47 +0200 Subject: [PATCH 0773/1435] Update for CHANGELOG.md & minor fixes --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d88d83098..c33bcbb47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,7 +72,7 @@ Major changes and added features: Updates and fixes: -* Fixed missing flash_loader for STM32L011 ([#654](https://github.com/texane/stlink/pull/654), [#675](https://github.com/texane/stlink/pull/675)) +* Fixed missing flash_loader for STM32L0x ([#269](https://github.com/texane/stlink/pull/269), [#274](https://github.com/texane/stlink/pull/274), [#654](https://github.com/texane/stlink/pull/654), [#675](https://github.com/texane/stlink/pull/675)) * Fix for stlink library calls exit() or _exit() ([#634](https://github.com/texane/stlink/pull/634), [#696](https://github.com/texane/stlink/pull/696)) * Added semihosting parameter documentation in doc/man ([#674](https://github.com/texane/stlink/pull/674)) * Fixed reference to non-exisiting st-term tool in doc/man ([#676](https://github.com/texane/stlink/pull/676)) @@ -128,11 +128,11 @@ Major changes and added features: Updates and fixes: * Fixed gdb-server: STM32L0xx has no FP_CTRL register for breakpoints ([#273](https://github.com/texane/stlink/pull/273)) +* Added --flash=n[k][m] command line option to override device model ([#305](https://github.com/texane/stlink/pull/305), [#516](https://github.com/texane/stlink/pull/516), [#576](https://github.com/texane/stlink/pull/576)) * Updated libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) * Fixed low-voltage flashing on STM32F7 devices ([#566](https://github.com/texane/stlink/pull/566), [#567](https://github.com/texane/stlink/pull/567)) * Fixed building with mingw64 ([#569](https://github.com/texane/stlink/pull/569), [#573](https://github.com/texane/stlink/pull/573), [#578](https://github.com/texane/stlink/pull/578), [#584](https://github.com/texane/stlink/pull/584), [#610](https://github.com/texane/stlink/pull/610)) * Fixed possible memory leak ([#570](https://github.com/texane/stlink/pull/570), [#571](https://github.com/texane/stlink/pull/571)) -* Added --flash=n[k][m] command line option to override device model ([#576](https://github.com/texane/stlink/pull/576)) * Fixed installation path for shared objects ([#581](https://github.com/texane/stlink/pull/581)) * Fixed a few -Wformat warnings ([#582](https://github.com/texane/stlink/pull/582)) * Removed unused defines in mimgw.h ([#583](https://github.com/texane/stlink/pull/583)) @@ -150,7 +150,7 @@ Release date: 2017-02-25 Major changes and added features: * Added support for Semihosting `SYS_READC` ([#546](https://github.com/texane/stlink/pull/546)) -* Added support for STM32F413 ([#549](https://github.com/texane/stlink/pull/549), [#550](https://github.com/texane/stlink/pull/550)) +* Added support for STM32F413 ([#549](https://github.com/texane/stlink/pull/549), [#550](https://github.com/texane/stlink/pull/550), [#758](https://github.com/texane/stlink/pull/758)) * Added preliminary support for STM32L011 to see it after probe (chip-ID 0x457) ([#558](https://github.com/texane/stlink/pull/558), [#598](https://github.com/texane/stlink/pull/598)) Updates and fixes: From e9c8135675d701198f2df22e50bc3062242fcb09 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Mon, 6 Apr 2020 19:20:04 +0800 Subject: [PATCH 0774/1435] Fix int length issues --- src/common.c | 11 +++++++++-- src/usb.c | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/common.c b/src/common.c index 6226c893b..ffc6057bb 100644 --- a/src/common.c +++ b/src/common.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -1257,8 +1258,14 @@ static int map_file(mapped_file_t* mf, const char* path) { fprintf(stderr, "fstat() == -1\n"); goto on_error; } - - mf->base = (uint8_t*) mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (sizeof(st.st_size) != sizeof(size_t)) { + /* On 32 bit systems, check if there is an overflow */ + if (st.st_size > (off_t)UINT32_MAX) { + fprintf(stderr, "mmap() size_t overflow\n"); + goto on_error; + } + } + mf->base = (uint8_t*) mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); if (mf->base == MAP_FAILED) { fprintf(stderr, "mmap() == MAP_FAILED\n"); goto on_error; diff --git a/src/usb.c b/src/usb.c index 9df9d7296..81bd7ae2c 100644 --- a/src/usb.c +++ b/src/usb.c @@ -189,7 +189,7 @@ int _stlink_usb_version(stlink_t *sl) { cmd[i++] = STLINK_APIV3_GET_VERSION_EX; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); - if (size != rep_len) { + if (size != (ssize_t)rep_len) { printf("[!] send_recv STLINK_APIV3_GET_VERSION_EX\n"); return (int) size; } From 46bf0abf77cca47133d3839460cc7679e0f78714 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 3 Apr 2020 16:13:35 +0200 Subject: [PATCH 0775/1435] add dual bank flash configuration info to chipid database. add a 'has_dual_bank' info to flash param, helping handling a couple of cases - selecting over dual bank specific code path without handling multiple chip id all over the code. - handling dual bank mode dynamic configuration --- include/stlink.h | 2 ++ include/stlink/chipid.h | 1 + src/common.c | 2 ++ 3 files changed, 5 insertions(+) diff --git a/include/stlink.h b/include/stlink.h index a69e357b5..ba7ef6196 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -159,6 +159,8 @@ typedef struct flash_loader { int serial_size; enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx + bool has_dual_bank; + stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() size_t flash_size; // calculated by stlink_load_device_params() size_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 8895cd4f8..d23596c0d 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -73,6 +73,7 @@ struct stlink_chipid_params { uint32_t chip_id; char *description; enum stlink_flash_type flash_type; + bool has_dual_bank; uint32_t flash_size_reg; uint32_t flash_pagesize; uint32_t sram_size; diff --git a/src/common.c b/src/common.c index b6496c00c..5ccfcf0bb 100644 --- a/src/common.c +++ b/src/common.c @@ -885,7 +885,9 @@ int stlink_load_device_params(stlink_t *sl) { } else { sl->flash_size = flash_size * 1024; } + sl->flash_type = params->flash_type; + sl->has_dual_bank = params->has_dual_bank; sl->flash_pgsz = params->flash_pagesize; sl->sram_size = params->sram_size; sl->sys_base = params->bootrom_base; From 804c38ead8aef3e4a1640a82a9b9c01f4f60eed1 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Mon, 6 Apr 2020 11:18:09 +0200 Subject: [PATCH 0776/1435] stm32g4: read flash optr to get flash bank mode on cat3 devices. g4 cat3 devices can be configured in two mode via option bytes: - dual bank, 2x256kib, 2KiB pages. - single bank, 1x512KiB, 4KiB pages. in anycase, these have two banks, and need to be handled with more care. -> read optr after loading flash params to patch page size. -> in single bank mode, mass erase _must_ be triggered by applying MER1 and MER2 bits. erasing half of the flash will lead to a pgserr. --- src/chipid.c | 1 + src/common.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/chipid.c b/src/chipid.c index 426780cf7..b9d3933f0 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -562,6 +562,7 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_G4_CAT3, .description = "G4 Category-3", .flash_type = STLINK_FLASH_TYPE_G4, + .has_dual_bank = true, .flash_size_reg = 0x1FFF75E0, // Section 47.2 .flash_pagesize = 0x800, // 2K (sec 3.3.1) // SRAM1 is 80k at 0x20000000 diff --git a/src/common.c b/src/common.c index 5ccfcf0bb..8cfbece35 100644 --- a/src/common.c +++ b/src/common.c @@ -128,9 +128,13 @@ #define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ #define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ #define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ + // G0/G4 FLASH status register #define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ +// G4 FLASH option register +#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ + // WB (RM0434) #define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) #define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) @@ -899,6 +903,14 @@ int stlink_load_device_params(stlink_t *sl) { sl->sram_size = 0x1000; } + if (sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3) { + uint32_t flash_optr; + stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); + if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { + sl->flash_pgsz <<= 1; + } + } + #if 0 // Old code -- REW ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); From 55ca316cd61a959746d809e1d9b20fa485ec39d8 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Mon, 6 Apr 2020 11:09:26 +0200 Subject: [PATCH 0777/1435] stm32g4: handle mass erase. toggle proper MER bits, taking in account dual bank mode enabled or not. --- src/common.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 8cfbece35..b1461c419 100644 --- a/src/common.c +++ b/src/common.c @@ -120,6 +120,7 @@ #define STM32Gx_FLASH_CR_PNB (3) /* Page number */ #define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ #define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ +#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ #define STM32Gx_FLASH_CR_STRT (16) /* Start */ #define STM32Gx_FLASH_CR_OPTSTRT (17) /* Start of modification of option bytes */ #define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ @@ -519,7 +520,10 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; - cr_mer = (1 << FLASH_CR_MER); + cr_mer = (1 << STM32Gx_FLASH_CR_MER1); + if (sl->has_dual_bank) { + cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); + } cr_pg = (1 << FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; From 6a2bf1cbe21cf3409926c24f360210ba14d469ff Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 3 Apr 2020 14:50:55 +0200 Subject: [PATCH 0778/1435] stm32g4: allow mass erase. --- src/common.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common.c b/src/common.c index b1461c419..601660360 100644 --- a/src/common.c +++ b/src/common.c @@ -1980,7 +1980,6 @@ int stlink_erase_flash_mass(stlink_t *sl) { /* TODO: User MER bit to mass-erase G0, G4, WB series. */ if (sl->flash_type == STLINK_FLASH_TYPE_L0 || sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4 || sl->flash_type == STLINK_FLASH_TYPE_WB) { /* erase each page */ int i = 0, num_pages = (int) sl->flash_size/sl->flash_pgsz; From 98cd484854b8842452759f8752dea5ca2e98c6ea Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Mon, 6 Apr 2020 14:00:54 +0200 Subject: [PATCH 0779/1435] common: add flash error check. use it for mass erase. only implement it for g0/g4 for now, but this is most probably a must for all chips. --- src/common.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/common.c b/src/common.c index 601660360..fd73c1614 100644 --- a/src/common.c +++ b/src/common.c @@ -131,7 +131,9 @@ #define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ // G0/G4 FLASH status register +#define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) #define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ +#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ // G4 FLASH option register #define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ @@ -688,6 +690,22 @@ static void wait_flash_busy_progress(stlink_t *sl) { fprintf(stdout, "\n"); } +static int check_flash_error(stlink_t *sl) +{ + uint32_t res = 0; + if ((sl->flash_type == STLINK_FLASH_TYPE_G0) || + (sl->flash_type == STLINK_FLASH_TYPE_G4)) { + res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK; + } + + if (res) { + ELOG("Flash programming error : %#010x\n", res); + return -1; + } + + return 0; +} + static inline unsigned int is_flash_eop(stlink_t *sl) { return read_flash_sr(sl) & (1 << FLASH_SR_EOP); } @@ -2018,6 +2036,8 @@ int stlink_erase_flash_mass(stlink_t *sl) { /* wait for completion */ wait_flash_busy_progress(sl); + check_flash_error(sl); + /* relock the flash */ lock_flash(sl); From 4437314d3383798d4518fe169c7de9db9ac39dc5 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Mon, 6 Apr 2020 16:45:26 +0200 Subject: [PATCH 0780/1435] enable mass erase for g0, worksforme --- src/common.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common.c b/src/common.c index fd73c1614..26202fcef 100644 --- a/src/common.c +++ b/src/common.c @@ -1997,7 +1997,6 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) int stlink_erase_flash_mass(stlink_t *sl) { /* TODO: User MER bit to mass-erase G0, G4, WB series. */ if (sl->flash_type == STLINK_FLASH_TYPE_L0 || - sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_WB) { /* erase each page */ int i = 0, num_pages = (int) sl->flash_size/sl->flash_pgsz; From be6aafddd1dc6eab29038b0010a582de060cfedd Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 7 Apr 2020 12:12:34 +0200 Subject: [PATCH 0781/1435] Minor fixes - Updated CentOS repo in README.md - Whitespace fixes --- Makefile | 47 +++++++++++++++++++++--------------------- README.md | 2 +- doc/version_support.md | 3 ++- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 7f81488bb..a94ec598b 100644 --- a/Makefile +++ b/Makefile @@ -1,49 +1,48 @@ ## -# This Makefile is used to drive building of Debug and Release -# targets of CMake +# This Makefile is used to drive building of Debug and Release targets of CMake ## MAKEFLAGS += -s all: release -ci: debug release test +ci: debug release test help: - @echo " release: Run a release build" - @echo " debug: Run a debug build" - @echo " lint: Lint check all source-code" - @echo " test: Build and run tests" - @echo " clean: Clean all build output" - @echo "rebuild_cache: Rebuild all CMake caches" + @echo " release: Run a release build" + @echo " debug: Run a debug build" + @echo " lint: Lint check all source-code" + @echo " test: Build and run tests" + @echo " clean: Clean all build output" + @echo "rebuild_cache: Rebuild all CMake caches" rebuild_cache: build/Debug build/Release - @$(MAKE) -C build/Debug rebuild_cache - @$(MAKE) -C build/Release rebuild_cache + @$(MAKE) -C build/Debug rebuild_cache + @$(MAKE) -C build/Release rebuild_cache debug: build/Debug - @echo "[DEBUG]" - @$(MAKE) -C build/Debug + @echo "[DEBUG]" + @$(MAKE) -C build/Debug release: build/Release - @echo "[RELEASE]" - @$(MAKE) -C build/Release + @echo "[RELEASE]" + @$(MAKE) -C build/Release package: build/Release - @echo "[PACKAGE] Release" - @$(MAKE) -C build/Release package + @echo "[PACKAGE] Release" + @$(MAKE) -C build/Release package test: debug - @$(MAKE) -C build/Debug test + @$(MAKE) -C build/Debug test build/Debug: - @mkdir -p $@ - @cd $@ && cmake -DCMAKE_BUILD_TYPE=Debug $(CMAKEFLAGS) ../../ + @mkdir -p $@ + @cd $@ && cmake -DCMAKE_BUILD_TYPE=Debug $(CMAKEFLAGS) ../../ build/Release: - @mkdir -p $@ - @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) ../../ + @mkdir -p $@ + @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) ../../ clean: - @echo "[CLEAN]" - @rm -Rf build + @echo "[CLEAN]" + @rm -Rf build .PHONY: clean diff --git a/README.md b/README.md index b26a147e9..807449594 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ We recommend to install `stlink-tools` from the package repository of the used d **Other Operating Systems**: -* RedHat/CentOS 7: Users can install [from EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel7) +* RedHat/CentOS 8: Users can install [from EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel8) * FreeBSD: Users can install [from freshports](https://www.freshports.org/devel/stlink) * OpenBSD: Users need to install [from source](doc/compiling.md). diff --git a/doc/version_support.md b/doc/version_support.md index 963ca2988..5c8f65841 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -3,7 +3,6 @@ Sources: [pkgs.org - libusb](https://pkgs.org/search/?q=libusb) & [pkgs.org - cm ## Supported Operating Systems - ### Microsoft Windows On Windows users should ensure that cmake 3.17.0 is installed.
    @@ -14,6 +13,7 @@ Thus no user interaction regarding libusb is necessary. * Windows 10 * Windows 8.1 + ### Apple macOS On macOS users should ensure that cmake 3.17.0 is installed. @@ -24,6 +24,7 @@ On macOS users should ensure that cmake 3.17.0 is installed. * macOS 10.14 Mojave * macOS 10.13 High Sierra + ### Linux-/Unix-based: | Operating System | libusb
    version | cmake
    version | Notes | From a8c1f41f1b1c9dd1314f99a1d42de1008f5a4f74 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 7 Apr 2020 16:10:55 +0200 Subject: [PATCH 0782/1435] Refactoring for libusb detection --- cmake/modules/FindLibUSB.cmake | 219 ++++++++++++++++----------------- 1 file changed, 106 insertions(+), 113 deletions(-) diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index a8b65cba3..dc90bcc32 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -6,139 +6,132 @@ # LIBUSB_LIBRARY - The libraries needed to use libusb # LIBUSB_DEFINITIONS - Compiler switches required for using libusb +if (NOT (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")) # all OS apart from FreeBSD + FIND_PATH( + LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS /usr /usr/local /opt + PATH_SUFFIXES libusb-1.0 + ) +endif () -if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD - FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h - HINTS - /usr/include - ) -else () # other OS - FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h - HINTS - /usr - /usr/local - /opt - PATH_SUFFIXES libusb-1.0 - ) -endif() +if (APPLE) # macOS + set(LIBUSB_NAME libusb-1.0.a) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS /usr /usr/local /opt + ) +elseif (MINGW OR MSYS) # Windows with MinGW or MSYS + set(LIBUSB_NAME usb-1.0) -# macOS -if (APPLE) - set(LIBUSB_NAME libusb-1.0.a) -elseif(MSYS OR MINGW) - set(LIBUSB_NAME usb-1.0) -elseif(MSVC) - set(LIBUSB_NAME libusb-1.0.lib) -elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") - set(LIBUSB_NAME usb) -else() - set(LIBUSB_NAME usb-1.0) -endif() + if (CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/static + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) + else () # 32-bit + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) + endif () -if (MSYS OR MINGW) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/static) - else () - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static) - endif () -elseif (MSVC) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll) - else () - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll) - endif () -else() - find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS - /usr - /usr/local - /opt) -endif () +elseif (MSVC) # Windows with MSVC + set(LIBUSB_NAME libusb-1.0.lib) + if (CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) + else () # 32-bit + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) + endif () + +elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD + # libusb is integrated into FreeBSD + FIND_PATH( + LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS /usr/include + ) + + set(LIBUSB_NAME usb) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS /usr /usr/local /opt + ) + +else () # all other OS + set(LIBUSB_NAME usb-1.0) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS /usr /usr/local /opt + ) +endif() include(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) - mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) -if(NOT LIBUSB_FOUND) - if(WIN32 OR MSVC OR MINGW OR MSYS) - find_package(7Zip REQUIRED) +if (NOT LIBUSB_FOUND) + if (WIN32 OR MINGW OR MSYS OR MSVC) # Windows - set(LIBUSB_WIN_VERSION 1.0.23) + # Preparations for installing libusb library + find_package(7Zip REQUIRED) + set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version to 1.0.23 (latest as of Apr 2020) set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3rdparty/libusb-${LIBUSB_WIN_VERSION}) - if(EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) + # Get libusb package + if (EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) # ... should the package be already there (for whatever reason) message(STATUS "libusb archive already in build folder") - else() + else () # ... download the package (1.0.23 as of Apr 2020) message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download - ${LIBUSB_WIN_ARCHIVE_PATH} - EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 - ) - endif() + ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 + ) + endif () + file(MAKE_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) - if(${ZIP_EXECUTABLE} MATCHES "p7zip") - #execute_process(COMMAND ${ZIP_EXECUTABLE} -d --keep -f ${LIBUSB_WIN_ARCHIVE_PATH} WORKING_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) - execute_process(COMMAND ${ZIP_EXECUTABLE} -d ${LIBUSB_WIN_ARCHIVE_PATH} WORKING_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) - else() - execute_process(COMMAND ${ZIP_EXECUTABLE} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER}) - endif() + # Extract libusb package + if (${ZIP_EXECUTABLE} MATCHES "p7zip") + execute_process( + COMMAND ${ZIP_EXECUTABLE} -d ${LIBUSB_WIN_ARCHIVE_PATH} + WORKING_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER} + ) + else () + execute_process( + COMMAND ${ZIP_EXECUTABLE} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o ${LIBUSB_WIN_OUTPUT_FOLDER} + ) + endif () - FIND_PATH(LIBUSB_INCLUDE_DIR NAMES libusb.h - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/include - PATH_SUFFIXES libusb-1.0 - NO_DEFAULT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) + # Find path to libusb library + FIND_PATH( + LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/include + PATH_SUFFIXES libusb-1.0 + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) - if (MSYS OR MINGW) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/static - NO_DEFAULT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) - else () - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static - NO_DEFAULT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) - endif () - elseif(MSVC) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll - NO_DEFAULT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) - else () - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll - NO_DEFAULT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) - endif () - endif () FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) - endif() -else() - message(STATUS "found USB") -endif() + message(STATUS "installed libusb library") + else () # all other OS + message(FATAL_ERROR "libusb library not found on your system! Compilation terminated.") + endif () +else (NOT LIBUSB_FOUND) + message(STATUS "found libusb library") +endif () From 23c071edea45f6e8852fef52d884a680973d6d8f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 7 Apr 2020 17:01:26 +0200 Subject: [PATCH 0783/1435] Updated documentation - Compiling manual - Updated version support for macOS --- README.md | 21 +++++++++++----- doc/compiling.md | 57 +++++++++++++++++++++--------------------- doc/version_support.md | 11 +++----- 3 files changed, 47 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 807449594..343dbd39c 100644 --- a/README.md +++ b/README.md @@ -37,11 +37,20 @@ Currently known working combinations of programmers and targets are listed in [d ## Installation -**Windows**: download [v1.6.0](https://github.com/texane/stlink/releases/tag/v1.6.0) from the releases page. +**Windows**: -Windows pre-compiled binaries are available at http://www.emb4fun.de/archive/stlink/index.html (outdated, not recommended for use) +Please compile and install from source as described in our [compiling manual](doc/compiling.md#Windows). -**macOS**: install [from homebrew](http://brewformulas.org/Stlink) or download [v1.6.0](https://github.com/texane/stlink/releases/tag/v1.6.0) from the releases page. +Long awaited binaries will be available soon... + +**macOS**: + +We recommend to install from: + +* [homebrew](https://formulae.brew.sh/formula/stlink) or +* [MacPorts](https://ports.macports.org/port/stlink) + +Alternatively one can compile and install from source as described in our [compiling manual](doc/compiling.md#macOS). **Linux**: @@ -56,9 +65,9 @@ We recommend to install `stlink-tools` from the package repository of the used d **Other Operating Systems**: -* RedHat/CentOS 8: Users can install [from EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel8) -* FreeBSD: Users can install [from freshports](https://www.freshports.org/devel/stlink) -* OpenBSD: Users need to install [from source](doc/compiling.md). +* RedHat/CentOS 8: Users can install from [EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel8) +* FreeBSD: Users can install from [freshports](https://www.freshports.org/devel/stlink) +* OpenBSD: Users need to compile and install from source as described in our [compiling manual](doc/compiling.md). ## Installation from source (advanced users) diff --git a/doc/compiling.md b/doc/compiling.md index bcaf7d567..64f4de466 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -28,7 +28,7 @@ On Windows users should ensure that the following software is installed: ### Building -#### MinGW64 +#### MinGW-w64 1. Use the command-line to move to the `scripts` directory within the source-folder: `cd stlink\scripts\` 2. Execute `./mingw64-build.bat` @@ -158,47 +158,46 @@ Choose on of the following options _before_ connecting the device to your comput 2. `modprobe -r usb-storage && modprobe usb-storage` -Author: nightwalker-87 +## macOS +### Common requirements ------ +The best way is to install a package manager for open source software, +either [homebrew](https://brew.sh) or [MacPorts](https://www.macports.org/). ----- **The following content is outdated and unrevised!** ---- +Then install the following dependencies from the package repository: -## Mac OS X +* `git` +* `cmake` +* `libusb` -When compiling on a mac you need the following: +To do this with only one simple command, type: -* A compiler toolchain (XCode) -* CMake -* Libusb 1.0 +* for homebrew: `sudo brew install git cmake libusb` or +* for MacPorts:`sudo port install git cmake libusb` -The best way is to install [homebrew](http://brew.sh) which is a package manager - for opensource software which is missing from the Apple App Store. Then install - the dependencies: +Additionally we recommend to install Xcode which delivers the necessary C-compiler toolchain Clang (LLVM). -``` -brew install libusb cmake -``` -Compile as described in the first section of this document. +### Installation + +1. Open a new terminal window +2. Create a new destination folder at a place of your choice e.g. at `~/git`: `mkdir $HOME/git` +3. Change to this directory: `cd ~/git` +4. Fetch the project sourcefiles by running `git clone https://github.com/texane/stlink.git` -## Build using different directories for udev and modprobe +### Building -To put the udev or the modprobe configuration files into a different directory -during installation you can use the following cmake options: +1. Change into the project source directory: `cd stlink` +2. Run `make release` to create the _Release_ target +3. Run `make debug` to create the _Debug_ target (_optional_)
    + The debug target is only necessary in order to modify the sources and to run under a debugger. -``` -$ cmake -DSTLINK_UDEV_RULES_DIR="/usr/lib/udev/rules.d" \ - -DSTLINK_MODPROBED_DIR="/usr/lib/modprobe.d" .. -``` +## Build using a different directory for shared libs -## Build using different directory for shared libs +To put the compiled shared libs into a different directory during installation, +you can use the cmake option `cmake -DLIB_INSTALL_DIR:PATH="/usr/lib64" ..`. -To put the compiled shared libs into a different directory during installation -you can use the following cmake option: -``` -$ cmake -DLIB_INSTALL_DIR:PATH="/usr/lib64" .. -``` +Author: nightwalker-87 diff --git a/doc/version_support.md b/doc/version_support.md index 5c8f65841..8b1a9b92d 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -16,13 +16,10 @@ Thus no user interaction regarding libusb is necessary. ### Apple macOS -On macOS users should ensure that cmake 3.17.0 is installed. - ---> libusb Installation routine: (TBD) Work in progress... - -* macOS 10.15 Catalina -* macOS 10.14 Mojave -* macOS 10.13 High Sierra +| Package Repository | libusb
    version | cmake
    version | Supported macOS versions | +| --- | --- | --- | --- | +| homebrew | 1.0.23 | 3.17.0 | 10.12 (Sierra)- 10.15 (Catalina) | +| MacPorts | 1.0.23 | 3.17.0 | 10.6 (Snow Leopard) - 10.15 (Catalina) | ### Linux-/Unix-based: From af1570ffe971752e25dbe0d6bfcb59ff1bc46391 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 7 Apr 2020 17:11:45 +0200 Subject: [PATCH 0784/1435] Minor formatting fixes --- CMakeLists.txt | 2 +- cmake/version.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f46a5f591..1f0b46449 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ set(CMAKE_USER_MAKE_RULES_OVERRIDE cmake/c_flag_overrides.cmake) project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics ST-LINK Tools") include(GNUInstallDirs) -set(STLINK_UDEV_RULES_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/udev/rules.d" CACHE PATH "Udev rules directory") +set(STLINK_UDEV_RULES_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/udev/rules.d" CACHE PATH "udev rules directory") set(STLINK_MODPROBED_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/modprobe.d" CACHE PATH "modprobe.d directory") set(STLINK_STATIC_LIB ON CACHE BOOL "Install static lib") diff --git a/cmake/version.cmake b/cmake/version.cmake index bdfe95ace..e9e2f7a05 100644 --- a/cmake/version.cmake +++ b/cmake/version.cmake @@ -4,7 +4,7 @@ set(__detect_version 0) -find_package (Git) +find_package(Git) if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") # Working off a git repo, using git versioning From 59c5cfd7ec5c7f2a035944ecc5ca01d3d7b31170 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 7 Apr 2020 18:30:26 +0200 Subject: [PATCH 0785/1435] [doc] macOS ST-Link-v1 detection Added documentation on how to solve a failed detection of the ST-Link-v1 programmer in macOS v10.11 and later. (Closes #574, #587) --- doc/tutorial.md | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/doc/tutorial.md b/doc/tutorial.md index 1d48eaa38..9c1f7f26d 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -13,6 +13,70 @@ This option accepts decimal (128k), octal 0200k, or hex 0x80k. Obviously leaving the multiplier out is equally valid, for example: `--flash=0x20000`. The size may be followed by an optional "k" or "m" to multiply the given value by 1k (1024) or 1M respectively. + +## Solution to common problems +### ST-Link-v1 driver: Issue with Kernel Extension (kext) (macOS 10.11 and later only) +#### Problem: + +st-util fails to detect a ST-Link-v1 device: + +``` +st-util -1 +st-util $VERSION-STRING$ +WARN src/sg.c: Failed to find an stlink v1 by VID:PID +ERROR src/sg.c: Could not open stlink device +``` + +#### Solution (clean setup): + +1) Configure System Integrity Protection (SIP) + +The root of this problem is a system security setting introduced by Apple with OS X El Capitan (10.11) in 2015. +The so called System Integrity Protection (SIP) is active per default +and prevents the operating system amongst other things to load unsigned Kernel Extension Modules (kext). +Thus the ST-Link-v1 driver supplied with the tools, which installs as a kext, remains not functional, +while SIP is fully activated (as is per default). + +Action needs to be taken here by booting into the recovery mode where a terminal console window needs to be opened. + +Here it is **NOT RECOMMEND to disable SIP completely as with the command** `csrutil disable`, +**because this leaves the system more vulnerable to common threats. +Instead there is a more adequate and reasonable option implemented by Apple. +Running** `csrutil enable --without kext`, **allows to load unsigned kernel extensions +while leaving SIP active with all other security features.** +So who ever intends to run the ST-Link-v1 programmer on macOS please take this into account. + +Further details can be found here: https://forums.developer.apple.com/thread/17452 + +2) Install the ST-Link-v1 driver from the subdirectory `/stlinkv1_macosx_driver` + by referring to the instructions in the README file available there. + +3) Move the $OS_VERSION$.kext file to `/System/Library/Extensions`. + +4) Load the Kernel Extension (kext): `$ sudo kextload -v /System/Library/Extensions/stlink_shield10_x.kext` + +``` +Requesting load of /System/Library/Extensions/stlink_shield10_x.kext. +/System/Library/Extensions/stlink_shield10_x.kext loaded successfully (or already loaded). +``` + +5) Enter the command `$ sudo touch /System/Library/Extensions` + + +7) Verify correct detection of the ST-Link-v1 device with the following input: `st-util -1` + +You should then see a similar output like in this example: + +``` +INFO common.c: Loading device parameters.... +INFO common.c: Device connected is: F1 High-density device, id 0x10036414 +INFO common.c: SRAM size: 0x10000 bytes (64 KiB), Flash: 0x80000 bytes (512 KiB) in pages of 2048 bytes +INFO sg.c: Successfully opened a stlink v1 debugger +INFO gdb-server.c: Chip ID is 00000414, Core ID is 1ba01477. +INFO gdb-server.c: Listening at *:4242... +``` + + ------ Using STM32 discovery kits with open source tools From 97484422008df0f75c978627054776f35842a075 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 8 Apr 2020 00:12:36 +0200 Subject: [PATCH 0786/1435] Deprecated old appveyor-mingw script --- scripts/appveyor-mingw.sh | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 scripts/appveyor-mingw.sh diff --git a/scripts/appveyor-mingw.sh b/scripts/appveyor-mingw.sh deleted file mode 100644 index 4842410ba..000000000 --- a/scripts/appveyor-mingw.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -set -e -cd `dirname "$0"`/.. -if [ "$ARCH" = "i686" ]; then - f=i686-4.9.2-release-win32-sjlj-rt_v3-rev1.7z - if ! [ -e $f ]; then - curl -LsSO http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.2/threads-win32/sjlj/$f - fi - 7z x $f > /dev/null - mv mingw32 /MinGW -else - f=x86_64-4.9.2-release-win32-seh-rt_v3-rev1.7z - if ! [ -e $f ]; then - curl -LsSO http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.2/threads-win32/seh/$f - fi - 7z x $f > /dev/null - mv mingw64 /MinGW -fi -cd build -cmake .. -G"$GENERATOR" -cmake --build . --config RelWithDebInfo From 17511a6fed8f012e86acebb925ea1977c4798381 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 8 Apr 2020 01:58:59 +0200 Subject: [PATCH 0787/1435] Update for CHANGELOG.md --- CHANGELOG.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c33bcbb47..1401843a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ Major changes and added features: Updates and fixes: +* Fixed "unkown chip id", piped output and st-util -v ([#107](https://github.com/texane/stlink/pull/107), [#665](https://github.com/texane/stlink/pull/665), [#763](https://github.com/texane/stlink/pull/763)) +* Fixed an issue with versioning stuck at 1.4.0 for versions cloned with git ([#563](https://github.com/texane/stlink/pull/563), [#762](https://github.com/texane/stlink/pull/762), [#772](https://github.com/texane/stlink/pull/772)) * Updated STM32F3xx chip ID that covers a few different devices ([#685](https://github.com/texane/stlink/pull/685), [#758](https://github.com/texane/stlink/pull/758)) * Made udev rules and modprobe conf installation optional ([#741](https://github.com/texane/stlink/pull/741)) * Fixed case when __FILE__ don't contain "/" nor "\\" ([#745](https://github.com/texane/stlink/pull/745)) @@ -34,7 +36,6 @@ Updates and fixes: * Only do bank calculation on STM32L4 devices with dual banked flash / Added chip-ID 0x464 for STM32L41xxx/L42xxx devices ([#751](https://github.com/texane/stlink/pull/751)) * Added O_BINARY option to open file ([#753](https://github.com/texane/stlink/pull/753)) * Fixed versioning when compiling from the checked out git-repo ([#762](https://github.com/texane/stlink/pull/762), [#772](https://github.com/texane/stlink/pull/772)) -* Fixed "unkown chip id", piped output and st-util -v ([#107](https://github.com/texane/stlink/pull/107), [#665](https://github.com/texane/stlink/pull/665), [#763](https://github.com/texane/stlink/pull/763)) * win32: move usleep definition to unistd.h ([#765](https://github.com/texane/stlink/pull/765)) * Fixed relative path to the UI files needed by stlink-gui-local (GUI) ([#770](https://github.com/texane/stlink/pull/770), [#771](https://github.com/texane/stlink/pull/771)) * Added howto for sending NRST signal through GDB ([#774](https://github.com/texane/stlink/pull/774), [#776](https://github.com/texane/stlink/pull/776), [#779](https://github.com/texane/stlink/pull/779)) @@ -190,7 +191,7 @@ Chip support added for: * STM32F7xx ([#324](https://github.com/texane/stlink/pull/324), [#326](https://github.com/texane/stlink/pull/326), [#327](https://github.com/texane/stlink/pull/327), [#337](https://github.com/texane/stlink/pull/337)) * STM32F767ZI ([#509](https://github.com/texane/stlink/pull/509)) * STM32L0xx Cat2 devices (chip-ID: 0x425) ([#414](https://github.com/texane/stlink/pull/414)) -* STM32L0xx Cat5 devices (chip-ID: 0x447) ([#406](https://github.com/texane/stlink/pull/406)) +* STM32L0xx Cat5 devices (chip-ID: 0x447) ([#387](https://github.com/texane/stlink/pull/387), [#406](https://github.com/texane/stlink/pull/406)) * STM32L4xx ([#321](https://github.com/texane/stlink/pull/321)) * STM32L432 ([#500](https://github.com/texane/stlink/pull/500), [#501](https://github.com/texane/stlink/pull/501)) @@ -198,7 +199,7 @@ Updates and fixes: * Fixed "unaligned addr or size" when trying to write a program in RAM ([#323](https://github.com/texane/stlink/pull/323)) * Fixed flashing on STM32_F3_SMALL ([#325](https://github.com/texane/stlink/pull/325)) -* Fixed STM32L-problem with flash loader ([#390](https://github.com/texane/stlink/pull/390)) +* Fixed STM32L-problem with flash loader ([#390](https://github.com/texane/stlink/pull/390), [#407](https://github.com/texane/stlink/pull/407),[#408](https://github.com/texane/stlink/pull/408)) * Don't read the target voltage on startup, because it crashes STM32F100 ([#423](https://github.com/texane/stlink/pull/423), [#424](https://github.com/texane/stlink/pull/424)) * Added a useful error message instead of "[!] send_recv" ([#425](https://github.com/texane/stlink/pull/425), [#426](https://github.com/texane/stlink/pull/426)) * Do a JTAG reset prior to reading CPU information when processor is in deep sleep ([#428](https://github.com/texane/stlink/pull/428), [#430](https://github.com/texane/stlink/pull/430), [#451](https://github.com/texane/stlink/pull/451)) @@ -253,6 +254,7 @@ Chip support added for: * Added STM32L4 to CHIPID #defines and devices[], flash driver and loader (Dave Vandervies) * Basic support for STM32F446 (Pavel Kirienko) * STM32F303 High Density +* STM32F469/STM32F479 ([#345](https://github.com/texane/stlink/pull/345), [#555](https://github.com/texane/stlink/pull/555)) (Release v1.2.0) * STM32L1xx Cat.2 devices (Nicolas Schodet) * STM32L1xx (chip-ID 0x427) ([#152](https://github.com/texane/stlink/pull/152), [#163](https://github.com/texane/stlink/pull/163), [#165](https://github.com/texane/stlink/pull/165)) (Release v1.0.0) From 9f2cad2c978a55a4125e6b8c4c656a59e7f9448c Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 8 Apr 2020 12:45:10 +0200 Subject: [PATCH 0788/1435] Avoid re-define of O_BINARY on Windows (Fixes #788) --- src/common.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/common.c b/src/common.c index 26202fcef..4e04a33a5 100644 --- a/src/common.c +++ b/src/common.c @@ -16,9 +16,12 @@ #include "stlink/mmap.h" #include "stlink/logging.h" -#ifndef _WIN32 -#define O_BINARY 0 //! @todo get rid of this OH MY (@xor-gate) +#ifdef _WIN32 +#ifndef O_BINARY +#define O_BINARY 0 #endif +#endif + #ifdef _MSC_VER #define __attribute__(x) #endif From ad06dace83d2f6deefcef10b504c250a4a918e89 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 8 Apr 2020 14:10:01 +0200 Subject: [PATCH 0789/1435] Removed old tested-boards list. --- doc/tested-boards.md | 57 -------------------------------------------- 1 file changed, 57 deletions(-) delete mode 100644 doc/tested-boards.md diff --git a/doc/tested-boards.md b/doc/tested-boards.md deleted file mode 100644 index a9fa2f1c6..000000000 --- a/doc/tested-boards.md +++ /dev/null @@ -1,57 +0,0 @@ -Stlink tested and compatible boards -=================================== - -STLink v1 (as found on the 32VL Discovery board) - -Known working targets: - -* STM32F100xx (Medium Density VL) -* STM32F103 (according to jpa- on ##stm32) - -No information: - -* everything else! - -STLink v2 (as found on the 32L and F4 Discovery boards), known working targets: - -* STM32F0 (STM32F0 Discovery board) -* STM32F030F4P6 (custom board) -* STM32F051R8T6 (STM320518-EVAL board) -* STM32F100xx (Medium Density VL, as on the 32VL Discovery board) -* STM32F103VET6 (HY-STM32 board) ([#149](https://github.com/texane/stlink/pull/149)) -* STM32F105RCT6 (DecaWave EVB1000 board) -* STM32F303xx (STM32F3 Discovery board) -* STM32F407xx (STM32F4 Discovery board) -* STM32F411E-DISCO (STM32F4 Discovery board with gyro, audio) -* STM32F429I-DISCO (STM32F4 Discovery board with LCD) -* STM32F439VIT6 (Discovery board reseated CPU) -* STM32L052K8T6 (custom board) -* STM32L1xx (STM32L Discovery board) -* STM32L151CB (custom board) -* STM32L152RB (STM32L-Discovery board, custom board) -* STM32L496ZG (STM32-Nucleo-L496ZG board) - - -* STM32F103VC, STM32F107RC, STM32L151RB, STM32F205RE and STM32F405RE on custom boards - from [UweBonnes/wiki_fuer_alex](https://github.com/UweBonnes/wiki_fuer_alex/tree/master/layout) - - -STLink v2-1 (as found on the Nucleo boards), known working targets: - -* STM32F030R8T6 (STM32 Nucleo-F030R8 board) -* STM32F042K6 (STM32 Nucleo-32 Board) -* STM32F072RBT6 (STM32 Nucleo-F072RB board) -* STM32F103RB (STM32 Nucleo-F103RB board) -* STM32F303RET6 (STM32 Nucleo-F303RE board) -* STM32F334R8 (STM32 Nucleo-F334R8 board) -* STM32F401xx (STM32 Nucleo-F401RE board) -* STM32F411RET6 (STM32 Nucleo-F411RE board) -* STM32F756NGHx (STM32F7 evaluation board) -* STM32F769NI (STM32F7 discovery board) -* STM32L053R8 (STM32 Nucleo-L053R8 board) -* STM32L152RE (STM32-Nucleo-L152RE board -* STM32L452RET6 (STM32 Nucleo-L452RE board) -* STM32L476RG (STM32 Nucleo-L476RG board) - - -Please report any and all known working combinations so I can update this! From 34c0a31204d33fd15a1186709e3f60d186bcda3e Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Wed, 8 Apr 2020 20:33:23 +0800 Subject: [PATCH 0790/1435] Fix dead loop after an unexpected unplug * Fix by adding error handler in gdb-server * Enhance logs for functions with return values --- src/gdbserver/gdb-server.c | 222 ++++++++++++++++++++++++++++--------- 1 file changed, 167 insertions(+), 55 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 72f676bb2..3aa769e02 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -1115,8 +1115,13 @@ int serve(stlink_t *sl, st_state_t *st) { * emulate attaching and detaching to target. */ unsigned int attached = 1; - + /* + * If a critical error is detected, break from the loop + */ + int critical_error = 0; + int ret; while(1) { + ret = 0; char* packet; int status = gdb_recv_packet(client, &packet); @@ -1226,32 +1231,75 @@ int serve(stlink_t *sl, st_state_t *st) { if (!strncmp(cmd, "resume", 6)) {// resume DLOG("Rcmd: resume\n"); cache_sync(sl); - stlink_run(sl); + ret = stlink_run(sl); + if (ret) { + DLOG("Rcmd: resume failed\n"); + reply = strdup("E00"); + + } else { + reply = strdup("OK"); + } - reply = strdup("OK"); } else if (!strncmp(cmd, "halt", 4)) { //halt - reply = strdup("OK"); + ret = stlink_force_debug(sl); + if (ret) { + DLOG("Rcmd: halt failed\n"); + reply = strdup("E00"); - stlink_force_debug(sl); + } else { + reply = strdup("OK"); + DLOG("Rcmd: halt\n"); + } - DLOG("Rcmd: halt\n"); } else if (!strncmp(cmd, "jtag_reset", 10)) { //jtag_reset reply = strdup("OK"); - stlink_jtag_reset(sl, 0); - stlink_jtag_reset(sl, 1); - stlink_force_debug(sl); + ret = stlink_jtag_reset(sl, 0); + if (ret) { + DLOG("Rcmd: jtag_reset failed with jtag_reset\n"); + reply = strdup("E00"); + + } + + ret = stlink_jtag_reset(sl, 1); + if (ret) { + DLOG("Rcmd: jtag_reset failed with jtag_reset\n"); + reply = strdup("E00"); + + } - DLOG("Rcmd: jtag_reset\n"); + ret = stlink_force_debug(sl); + if (ret) { + DLOG("Rcmd: jtag_reset failed with force_debug\n"); + reply = strdup("E00"); + + } + if (strcmp(reply, "E00")) { + // no errors have been found + DLOG("Rcmd: jtag_reset\n"); + } } else if (!strncmp(cmd, "reset", 5)) { //reset - reply = strdup("OK"); - stlink_force_debug(sl); - stlink_reset(sl); + ret = stlink_force_debug(sl); + if (ret) { + DLOG("Rcmd: reset failed with force_debug\n"); + reply = strdup("E00"); + } + + ret = stlink_reset(sl); + if (ret) { + DLOG("Rcmd: reset failed with reset\n"); + reply = strdup("E00"); + } + init_code_breakpoints(sl); init_data_watchpoints(sl); - DLOG("Rcmd: reset\n"); + if (reply == NULL) { + reply = strdup("OK"); + DLOG("Rcmd: reset\n"); + } + } else if (!strncmp(cmd, "semihosting ", 12)) { DLOG("Rcmd: got semihosting cmd '%s'", cmd); char *arg = cmd + 12; @@ -1369,7 +1417,10 @@ int serve(stlink_t *sl, st_state_t *st) { case 'c': cache_sync(sl); - stlink_run(sl); + ret = stlink_run(sl); + if (ret) { + DLOG("Semihost: run failed\n"); + } while(1) { status = gdb_check_for_interrupt(client); @@ -1384,10 +1435,12 @@ int serve(stlink_t *sl, st_state_t *st) { break; } - stlink_status(sl); + ret = stlink_status(sl); + if (ret) { + DLOG("Semihost: status failed\n"); + } if(sl->core_stat == STLINK_CORE_HALTED) { struct stlink_reg reg; - int ret; stm32_addr_t pc; stm32_addr_t addr; int offset = 0; @@ -1397,7 +1450,10 @@ int serve(stlink_t *sl, st_state_t *st) { break; } - stlink_read_all_regs (sl, ®); + ret = stlink_read_all_regs (sl, ®); + if (ret) { + DLOG("Semihost: read_all_regs failed\n"); + } /* Read PC */ pc = reg.r[15]; @@ -1421,17 +1477,29 @@ int serve(stlink_t *sl, st_state_t *st) { if (insn == 0xBEAB && !has_breakpoint(addr)) { - do_semihosting (sl, reg.r[0], reg.r[1], ®.r[0]); + ret = do_semihosting (sl, reg.r[0], reg.r[1], ®.r[0]); + if (ret) { + DLOG("Semihost: do_semihosting failed\n"); + } /* Write return value */ - stlink_write_reg(sl, reg.r[0], 0); + ret = stlink_write_reg(sl, reg.r[0], 0); + if (ret) { + DLOG("Semihost: write_reg failed for return value\n"); + } /* Jump over the break instruction */ - stlink_write_reg(sl, reg.r[15] + 2, 15); + ret = stlink_write_reg(sl, reg.r[15] + 2, 15); + if (ret) { + DLOG("Semihost: write_reg failed for jumping over break\n"); + } /* continue execution */ cache_sync(sl); - stlink_run(sl); + ret = stlink_run(sl); + if (ret) { + DLOG("Semihost: continue execution failed with stlink_run\n"); + } } else { break; } @@ -1444,10 +1512,17 @@ int serve(stlink_t *sl, st_state_t *st) { break; case 's': - cache_sync(sl); - stlink_step(sl); + cache_sync(sl); + ret = stlink_step(sl); + if (ret) { + // have problem sending step packet + ELOG("Step: cannot send step request\n"); + reply = strdup("E00"); + critical_error = 1; // absolutely critical + } else { + reply = strdup("S05"); // TRAP + } - reply = strdup("S05"); // TRAP break; case '?': @@ -1460,7 +1535,10 @@ int serve(stlink_t *sl, st_state_t *st) { break; case 'g': - stlink_read_all_regs(sl, ®p); + ret = stlink_read_all_regs(sl, ®p); + if (ret) { + DLOG("g packet: read_all_regs failed\n"); + } reply = calloc(8 * 16 + 1, 1); for(int i = 0; i < 16; i++) @@ -1473,41 +1551,48 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned myreg = 0xDEADDEAD; if(id < 16) { - stlink_read_reg(sl, id, ®p); + ret = stlink_read_reg(sl, id, ®p); myreg = htonl(regp.r[id]); } else if(id == 0x19) { - stlink_read_reg(sl, 16, ®p); + ret = stlink_read_reg(sl, 16, ®p); myreg = htonl(regp.xpsr); } else if(id == 0x1A) { - stlink_read_reg(sl, 17, ®p); + ret = stlink_read_reg(sl, 17, ®p); myreg = htonl(regp.main_sp); } else if(id == 0x1B) { - stlink_read_reg(sl, 18, ®p); + ret = stlink_read_reg(sl, 18, ®p); myreg = htonl(regp.process_sp); } else if(id == 0x1C) { - stlink_read_unsupported_reg(sl, id, ®p); + ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.control); } else if(id == 0x1D) { - stlink_read_unsupported_reg(sl, id, ®p); + ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.faultmask); } else if(id == 0x1E) { - stlink_read_unsupported_reg(sl, id, ®p); + ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.basepri); } else if(id == 0x1F) { - stlink_read_unsupported_reg(sl, id, ®p); + ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.primask); } else if(id >= 0x20 && id < 0x40) { - stlink_read_unsupported_reg(sl, id, ®p); + ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.s[id-0x20]); } else if(id == 0x40) { - stlink_read_unsupported_reg(sl, id, ®p); + ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.fpscr); } else { + ret = 1; reply = strdup("E00"); } + if (ret) { + DLOG("p packet: stlink_read_unsupported_reg failed with id %u\n", id); + } - reply = calloc(8 + 1, 1); - sprintf(reply, "%08x", myreg); + if (reply == NULL) { + // if reply is set to "E00", skip + reply = calloc(8 + 1, 1); + sprintf(reply, "%08x", myreg); + } break; } @@ -1519,31 +1604,36 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned reg = (unsigned int) strtoul(s_reg, NULL, 16); unsigned value = (unsigned int) strtoul(s_value, NULL, 16); + if(reg < 16) { - stlink_write_reg(sl, ntohl(value), reg); + ret = stlink_write_reg(sl, ntohl(value), reg); } else if(reg == 0x19) { - stlink_write_reg(sl, ntohl(value), 16); + ret = stlink_write_reg(sl, ntohl(value), 16); } else if(reg == 0x1A) { - stlink_write_reg(sl, ntohl(value), 17); + ret = stlink_write_reg(sl, ntohl(value), 17); } else if(reg == 0x1B) { - stlink_write_reg(sl, ntohl(value), 18); + ret = stlink_write_reg(sl, ntohl(value), 18); } else if(reg == 0x1C) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); } else if(reg == 0x1D) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); } else if(reg == 0x1E) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); } else if(reg == 0x1F) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); } else if(reg >= 0x20 && reg < 0x40) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); } else if(reg == 0x40) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); } else { + ret = 1; reply = strdup("E00"); } - - if(!reply) { + if (ret) { + DLOG("P packet: stlink_write_unsupported_reg failed with reg %u\n", reg); + } + if(reply == NULL) { + // note that NULL may not be zero reply = strdup("OK"); } @@ -1555,7 +1645,10 @@ int serve(stlink_t *sl, st_state_t *st) { char str[9] = {0}; strncpy(str, &packet[1 + i * 8], 8); uint32_t reg = (uint32_t) strtoul(str, NULL, 16); - stlink_write_reg(sl, ntohl(reg), i); + ret = stlink_write_reg(sl, ntohl(reg), i); + if (ret) { + DLOG("G packet: stlink_write_reg failed"); + } } reply = strdup("OK"); @@ -1729,9 +1822,13 @@ int serve(stlink_t *sl, st_state_t *st) { } case 'R': { + /* Reset the core. */ - stlink_reset(sl); + ret = stlink_reset(sl); + if (ret) { + DLOG("R packet : stlink_reset failed\n"); + } init_code_breakpoints(sl); init_data_watchpoints(sl); @@ -1743,8 +1840,15 @@ int serve(stlink_t *sl, st_state_t *st) { } case 'k': /* Kill request - reset the connection itself */ - stlink_run(sl); - stlink_exit_debug_mode(sl); + ret = stlink_run(sl); + if (ret) { + DLOG("Kill: stlink_run failed\n"); + } + + ret = stlink_exit_debug_mode(sl); + if (ret) { + DLOG("Kill: stlink_exit_debug_mode failed\n"); + } stlink_close(sl); sl = do_connect(st); @@ -1754,7 +1858,10 @@ int serve(stlink_t *sl, st_state_t *st) { if (st->reset) { stlink_reset(sl); } - stlink_force_debug(sl); + ret = stlink_force_debug(sl); + if (ret) { + DLOG("Kill: stlink_force_debug failed\n"); + } init_cache(sl); init_code_breakpoints(sl); init_data_watchpoints(sl); @@ -1782,6 +1889,11 @@ int serve(stlink_t *sl, st_state_t *st) { free(reply); } + if (critical_error) { + close_socket(client); + return 1; + } + free(packet); } From c6753e3bdbcc23b2665373af389abe04cdbd150a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 8 Apr 2020 15:29:01 +0200 Subject: [PATCH 0791/1435] Fixed compilation errors (Regression) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -> error: ‘O_BINARY’ undeclared -> tabspaces in Makefile --- Makefile | 44 ++++++++++++++++++++++---------------------- src/common.c | 5 +++-- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index a94ec598b..df9099a9e 100644 --- a/Makefile +++ b/Makefile @@ -4,45 +4,45 @@ MAKEFLAGS += -s all: release -ci: debug release test +ci: debug release test help: - @echo " release: Run a release build" - @echo " debug: Run a debug build" - @echo " lint: Lint check all source-code" - @echo " test: Build and run tests" - @echo " clean: Clean all build output" - @echo "rebuild_cache: Rebuild all CMake caches" + @echo " release: Run a release build" + @echo " debug: Run a debug build" + @echo " lint: Lint check all source-code" + @echo " test: Build and run tests" + @echo " clean: Clean all build output" + @echo "rebuild_cache: Rebuild all CMake caches" rebuild_cache: build/Debug build/Release - @$(MAKE) -C build/Debug rebuild_cache - @$(MAKE) -C build/Release rebuild_cache + @$(MAKE) -C build/Debug rebuild_cache + @$(MAKE) -C build/Release rebuild_cache debug: build/Debug - @echo "[DEBUG]" - @$(MAKE) -C build/Debug + @echo "[DEBUG]" + @$(MAKE) -C build/Debug release: build/Release - @echo "[RELEASE]" - @$(MAKE) -C build/Release + @echo "[RELEASE]" + @$(MAKE) -C build/Release package: build/Release - @echo "[PACKAGE] Release" - @$(MAKE) -C build/Release package + @echo "[PACKAGE] Release" + @$(MAKE) -C build/Release package test: debug - @$(MAKE) -C build/Debug test + @$(MAKE) -C build/Debug test build/Debug: - @mkdir -p $@ - @cd $@ && cmake -DCMAKE_BUILD_TYPE=Debug $(CMAKEFLAGS) ../../ + @mkdir -p $@ + @cd $@ && cmake -DCMAKE_BUILD_TYPE=Debug $(CMAKEFLAGS) ../../ build/Release: - @mkdir -p $@ - @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) ../../ + @mkdir -p $@ + @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) ../../ clean: - @echo "[CLEAN]" - @rm -Rf build + @echo "[CLEAN]" + @rm -Rf build .PHONY: clean diff --git a/src/common.c b/src/common.c index 913d70e35..27db09fa2 100644 --- a/src/common.c +++ b/src/common.c @@ -15,9 +15,10 @@ #include "stlink/mmap.h" #include "stlink/logging.h" -#ifndef _WIN32 -#define O_BINARY 0 //! @todo get rid of this OH MY (@xor-gate) +#ifndef O_BINARY +#define O_BINARY 0 #endif + #ifdef _MSC_VER #define __attribute__(x) #endif From 6f941b22eb00844eca7d17ebe3168d34276ef6b3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 8 Apr 2020 15:34:10 +0200 Subject: [PATCH 0792/1435] Fixed compilation errors (Regression) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -> error: ‘O_BINARY’ undeclared -> tabspaces in Makefile --- Makefile | 45 ++++++++++++++++++++++----------------------- src/common.c | 2 -- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/Makefile b/Makefile index 7f81488bb..0636eb9bd 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,5 @@ ## -# This Makefile is used to drive building of Debug and Release -# targets of CMake +# This Makefile is used to drive building of Debug and Release targets of CMake ## MAKEFLAGS += -s @@ -8,42 +7,42 @@ all: release ci: debug release test help: - @echo " release: Run a release build" - @echo " debug: Run a debug build" - @echo " lint: Lint check all source-code" - @echo " test: Build and run tests" - @echo " clean: Clean all build output" - @echo "rebuild_cache: Rebuild all CMake caches" + @echo " release: Run a release build" + @echo " debug: Run a debug build" + @echo " lint: Lint check all source-code" + @echo " test: Build and run tests" + @echo " clean: Clean all build output" + @echo "rebuild_cache: Rebuild all CMake caches" rebuild_cache: build/Debug build/Release - @$(MAKE) -C build/Debug rebuild_cache - @$(MAKE) -C build/Release rebuild_cache + @$(MAKE) -C build/Debug rebuild_cache + @$(MAKE) -C build/Release rebuild_cache debug: build/Debug - @echo "[DEBUG]" - @$(MAKE) -C build/Debug + @echo "[DEBUG]" + @$(MAKE) -C build/Debug release: build/Release - @echo "[RELEASE]" - @$(MAKE) -C build/Release + @echo "[RELEASE]" + @$(MAKE) -C build/Release package: build/Release - @echo "[PACKAGE] Release" - @$(MAKE) -C build/Release package + @echo "[PACKAGE] Release" + @$(MAKE) -C build/Release package test: debug - @$(MAKE) -C build/Debug test + @$(MAKE) -C build/Debug test build/Debug: - @mkdir -p $@ - @cd $@ && cmake -DCMAKE_BUILD_TYPE=Debug $(CMAKEFLAGS) ../../ + @mkdir -p $@ + @cd $@ && cmake -DCMAKE_BUILD_TYPE=Debug $(CMAKEFLAGS) ../../ build/Release: - @mkdir -p $@ - @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) ../../ + @mkdir -p $@ + @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) ../../ clean: - @echo "[CLEAN]" - @rm -Rf build + @echo "[CLEAN]" + @rm -Rf build .PHONY: clean diff --git a/src/common.c b/src/common.c index 4e04a33a5..f432cf5a1 100644 --- a/src/common.c +++ b/src/common.c @@ -16,11 +16,9 @@ #include "stlink/mmap.h" #include "stlink/logging.h" -#ifdef _WIN32 #ifndef O_BINARY #define O_BINARY 0 #endif -#endif #ifdef _MSC_VER #define __attribute__(x) From 38c8b8b499f1d9e87db214e9fb2c144e593c8a08 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 8 Apr 2020 23:44:51 +0200 Subject: [PATCH 0793/1435] Cleanup - Whitespace fixes - Removed old appveyor-mingw script - travis-lin-mingw.sh -> .gitignore --- .appveyor.yml | 21 ---------------- .gitignore | 2 ++ cmake/version.cmake | 61 ++++++++++++++++++++++----------------------- src/win32/unistd.h | 31 ++++++++++++----------- 4 files changed, 48 insertions(+), 67 deletions(-) delete mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 10c0e935a..000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,21 +0,0 @@ -version: '{build}' -environment: - matrix: - - GENERATOR: "MSYS Makefiles" - ARCH: i686 # this is for 32-bit MinGW-w64 - - GENERATOR: "MSYS Makefiles" - ARCH: 64 -cache: - - i686-4.9.2-release-win32-sjlj-rt_v3-rev1.7z - - x86_64-4.9.2-release-win32-seh-rt_v3-rev1.7z - - libusb-1.0.20.7z -build_script: -- ps: | - mkdir build - cd build - if ($env:GENERATOR -ne "MSYS Makefiles") { - cmake .. -G"$env:GENERATOR" - cmake --build . --config Debug - } -- cmd: | - if "%GENERATOR%"=="MSYS Makefiles" (C:\MinGW\msys\1.0\bin\sh --login /c/projects/stlink/scripts/appveyor-mingw.sh) diff --git a/.gitignore b/.gitignore index 23e7ddc07..d2dde3a25 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ build build-mingw obj-* *.user* + +.travis-lin-mingw.sh diff --git a/cmake/version.cmake b/cmake/version.cmake index e9e2f7a05..fe778c419 100644 --- a/cmake/version.cmake +++ b/cmake/version.cmake @@ -15,78 +15,77 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") OUTPUT_VARIABLE PROJECT_VERSION RESULT_VARIABLE GIT_DESCRIBE_RESULT ERROR_VARIABLE GIT_DESCRIBE_ERROR - OUTPUT_STRIP_TRAILING_WHITESPACE) + OUTPUT_STRIP_TRAILING_WHITESPACE + ) - if(GIT_DESCRIBE_RESULT EQUAL 0) + if (GIT_DESCRIBE_RESULT EQUAL 0) # If the sources have been changed locally, add -dirty to the version. execute_process ( - COMMAND "${GIT_EXECUTABLE}" diff --quiet - WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" - RESULT_VARIABLE res) + COMMAND "${GIT_EXECUTABLE}" diff --quiet + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + RESULT_VARIABLE res + ) if (res EQUAL 1) set (PROJECT_VERSION "${PROJECT_VERSION}-dirty") - endif() + endif () # strip a leading v off of the version as proceeding code expectes just the version numbering. string(REGEX REPLACE "^v" "" PROJECT_VERSION ${PROJECT_VERSION}) string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" - "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) + "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) list(LENGTH PROJECT_VERSION_LIST len) - if(len EQUAL 3) + if (len EQUAL 3) list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) set(__detect_version 1) set(__version_str "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") - if(EXISTS "${PROJECT_SOURCE_DIR}/.version") + if (EXISTS "${PROJECT_SOURCE_DIR}/.version") file(READ "${PROJECT_SOURCE_DIR}/.version" __version_file) - if(NOT __version_str STREQUAL __version_file) + if (NOT __version_str STREQUAL __version_file) message(STATUS "Rewrite ${PROJECT_SOURCE_DIR}/.version with ${__version_str}") - endif() - else() + endif () + else () file(WRITE "${PROJECT_SOURCE_DIR}/.version" ${__version_str}) - endif() - else() - message(STATUS "Fail to extract version's parts from \"${PROJECT_VERSION}\"") - endif() + endif () + else () + message(STATUS "Fail to extract version parts from \"${PROJECT_VERSION}\"") + endif () else(GIT_DESCRIBE_RESULT EQUAL 0) message(WARNING "git describe failed.") message(WARNING "${GIT_DESCRIBE_ERROR}") endif(GIT_DESCRIBE_RESULT EQUAL 0) -else() +else () message(STATUS "Git or repo not found.") -endif() +endif () -if(NOT __detect_version) +if (NOT __detect_version) message(STATUS "Try to detect version from \"${PROJECT_SOURCE_DIR}/.version\" file.") - if(EXISTS ${PROJECT_SOURCE_DIR}/.version) + if (EXISTS ${PROJECT_SOURCE_DIR}/.version) # If git is not available (e.g. when building from source package) # we can extract the package version from .version file. - file (STRINGS .version PROJECT_VERSION) + file(STRINGS .version PROJECT_VERSION) # TODO create function to extract semver from file or string and check if it is correct instead of copy-pasting string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) list(LENGTH PROJECT_VERSION_LIST len) - if(len EQUAL 3) + if (len EQUAL 3) list(GET PROJECT_VERSION_LIST 0 PROJECT_VERSION_MAJOR) list(GET PROJECT_VERSION_LIST 1 PROJECT_VERSION_MINOR) list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) set(__detect_version 1) - else() - message(STATUS "Fail to extract version's parts from \"${PROJECT_VERSION}\"") - endif() - else() + else () + message(STATUS "Fail to extract version parts from \"${PROJECT_VERSION}\"") + endif () + else () message(STATUS "File \"${PROJECT_SOURCE_DIR}/.version\" did not exists.") - endif() -endif() - -if(NOT __detect_version) + endif () message(FATAL_ERROR "Unable to determine project version") -endif() +endif () message(STATUS "stlink version: ${PROJECT_VERSION}") message(STATUS "Major ${PROJECT_VERSION_MAJOR} Minor ${PROJECT_VERSION_MINOR} Patch ${PROJECT_VERSION_PATCH}") diff --git a/src/win32/unistd.h b/src/win32/unistd.h index 4c94aed34..5b2798b41 100644 --- a/src/win32/unistd.h +++ b/src/win32/unistd.h @@ -1,9 +1,9 @@ #ifndef _UNISTD_H #define _UNISTD_H 1 -/* This file intended to serve as a drop-in replacement for - * unistd.h on Windows - * Please add functionality as neeeded +/* + * This file intended to serve as a drop-in replacement for unistd.h on Windows + * Please add functionality as neeeded. */ #include @@ -16,19 +16,18 @@ #if defined(_MSC_VER) #pragma warning(pop) #endif -#include /* getopt at: https://gist.github.com/ashelly/7776712 */ -#include /* for getpid() and the exec..() family */ -#include /* for _getcwd() and _chdir() */ +#include // getopt at: https://gist.github.com/ashelly/7776712 +#include // for getpid() and the exec..() family +#include // for _getcwd() and _chdir() #define srandom srand #define random rand -/* Values for the second argument to access. - These may be OR'd together. */ -#define R_OK 4 /* Test for read permission. */ -#define W_OK 2 /* Test for write permission. */ -//#define X_OK 1 /* execute permission - unsupported in windows*/ -#define F_OK 0 /* Test for existence. */ +/* Values for the second argument to access. These may be OR'd together. */ +#define R_OK 4 // Test for read permission +#define W_OK 2 // Test for write permission +// #define X_OK 1 // execute permission - unsupported in windows +#define F_OK 0 // Test for existence #define access _access #define dup2 _dup2 @@ -40,7 +39,9 @@ #define chdir _chdir #define isatty _isatty #define lseek _lseek -/* read, write, and close are NOT being #defined here, because while there are file handle specific versions for Windows, they probably don't work for sockets. You need to look at your app and consider whether to call e.g. closesocket(). */ +/* read, write, and close are NOT being defined here, + * because while there are file handle specific versions for Windows, they probably don't work for sockets. + * You need to look at your app and consider whether to call e.g. closesocket(). */ #define ssize_t int @@ -49,7 +50,7 @@ #define STDERR_FILENO 2 /* should be in some equivalent to */ typedef __int8 int8_t; -typedef __int16 int16_t; +typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int8 uint8_t; @@ -61,4 +62,4 @@ typedef unsigned __int64 uint64_t; int usleep(unsigned int waitTime); #endif -#endif /* unistd.h */ +#endif /* unistd.h */ From 12faa5332ccc02f47c18d2c4ec2c0c0489f7e741 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Fri, 10 Apr 2020 22:07:52 +0800 Subject: [PATCH 0794/1435] Fix memory overlap --- tests/flash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/flash.c b/tests/flash.c index 6c8b8ed9b..b17aa99ae 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -30,9 +30,9 @@ static bool execute_test(const struct Test * test) { // parse (tokenize) the test command line #if defined(_MSC_VER) - char *cmd_line = alloca(strlen(test->cmd_line)); + char *cmd_line = alloca(strlen(test->cmd_line) + 1); #else - char cmd_line[strlen(test->cmd_line)]; + char cmd_line[strlen(test->cmd_line) + 1]; #endif strcpy(cmd_line, test->cmd_line); From 90081dd1f3b31574e76bd068e0814e7015420089 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 10 Apr 2020 14:34:51 +0200 Subject: [PATCH 0795/1435] usb.h: define some stlink usb pid macros, stop copypasting. ease v1/v2/v2.1/v3 identification and supported devices filtering --- include/stlink/usb.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/stlink/usb.h b/include/stlink/usb.h index 9357c248e..1448481be 100644 --- a/include/stlink/usb.h +++ b/include/stlink/usb.h @@ -29,6 +29,24 @@ extern "C" { #define STLINK_USB_PID_STLINK_V3S_PID 0x374f #define STLINK_USB_PID_STLINK_V3_2VCP_PID 0x3753 +#define STLINK_V1_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK ) + +#define STLINK_V2_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK_32L || \ + (pid) == STLINK_USB_PID_STLINK_32L_AUDIO || \ + (pid) == STLINK_USB_PID_STLINK_NUCLEO) + +#define STLINK_V2_1_USB_PID(pid) ( (pid) == STLINK_USB_PID_STLINK_V2_1 ) + +#define STLINK_V3_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK_V3_USBLOADER || \ + (pid) == STLINK_USB_PID_STLINK_V3E_PID || \ + (pid) == STLINK_USB_PID_STLINK_V3S_PID || \ + (pid) == STLINK_USB_PID_STLINK_V3_2VCP_PID ) + +#define STLINK_SUPPORTED_USB_PID(pid) ( STLINK_V1_USB_PID(pid) || \ + STLINK_V2_USB_PID(pid) || \ + STLINK_V2_1_USB_PID(pid) || \ + STLINK_V3_USB_PID(pid)) + #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 From 8fba7ab9fe9647957763be5f00443cb2192f8a28 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 10 Apr 2020 11:51:27 +0200 Subject: [PATCH 0796/1435] usb.c: align probe code. actually open all counted devices - the two vid check need to be aligned. also now display if some st device has been skipped. --- src/usb.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/usb.c b/src/usb.c index f9d141745..7ebd58b1a 100644 --- a/src/usb.c +++ b/src/usb.c @@ -1114,15 +1114,13 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { break; } - if (desc.idProduct != STLINK_USB_PID_STLINK_32L && - desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && - desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO && - desc.idProduct != STLINK_USB_PID_STLINK_V2_1 && - desc.idProduct != STLINK_USB_PID_STLINK_V3_USBLOADER && - desc.idProduct != STLINK_USB_PID_STLINK_V3E_PID && - desc.idProduct != STLINK_USB_PID_STLINK_V3S_PID && - desc.idProduct != STLINK_USB_PID_STLINK_V3_2VCP_PID) - continue; + if (desc.idVendor != STLINK_USB_VID_ST) + continue; + + if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { + WLOG("skipping ST device : %#04x:%#04x)\n", desc.idVendor, desc.idProduct); + continue; + } slcnt++; } @@ -1144,10 +1142,9 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { break; } - if (desc.idProduct != STLINK_USB_PID_STLINK_32L && - desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && - desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO) + if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { continue; + } struct libusb_device_handle* handle; char serial[STLINK_SERIAL_MAX_SIZE]; From 6b03c7f9ed4c65139aa05900e288bd5228d62024 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 10 Apr 2020 11:55:03 +0200 Subject: [PATCH 0797/1435] usb.c: rework probe loop to _not_ free all stuff without closing if _one_ probe failed. we return count and list of successfully probed devices, no need to free everything if some libusb call of the last probe attempt failed. --- src/usb.c | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/src/usb.c b/src/usb.c index 7ebd58b1a..e3b2a453c 100644 --- a/src/usb.c +++ b/src/usb.c @@ -1101,14 +1101,13 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { stlink_t **_sldevs; libusb_device *dev; int i = 0; - int ret = 0; size_t slcnt = 0; size_t slcur = 0; /* Count stlink */ while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; - ret = libusb_get_device_descriptor(dev, &desc); + int ret = libusb_get_device_descriptor(dev, &desc); if (ret < 0) { WLOG("failed to get libusb device descriptor (libusb error: %d)\n", ret); break; @@ -1136,7 +1135,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { i = 0; while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; - ret = libusb_get_device_descriptor(dev, &desc); + int ret = libusb_get_device_descriptor(dev, &desc); if (ret < 0) { WLOG("failed to get libusb device descriptor (libusb error: %d)\n", ret); break; @@ -1146,40 +1145,32 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { continue; } - struct libusb_device_handle* handle; - char serial[STLINK_SERIAL_MAX_SIZE]; - memset(serial, 0, sizeof(serial)); + struct libusb_device_handle* handle; + char serial[STLINK_SERIAL_MAX_SIZE] = {0,}; - ret = libusb_open(dev, &handle); - if (ret < 0) { - if (ret == LIBUSB_ERROR_ACCESS) { + ret = libusb_open(dev, &handle); + if (ret < 0) { + if (ret == LIBUSB_ERROR_ACCESS) { WLOG("failed to open USB device (LIBUSB_ERROR_ACCESS), try running as root?\n"); } else { WLOG("failed to open USB device (libusb error: %d)\n", ret); - } - break; - } + } + break; + } + + ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial)); - ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial)); - if (ret < 0) - *serial = 0; + libusb_close(handle); - libusb_close(handle); + if (ret < 0) { + continue; + } - stlink_t *sl = NULL; - sl = stlink_open_usb(0, 1, serial); + stlink_t *sl = stlink_open_usb(0, 1, serial); if (!sl) continue; - _sldevs[slcur] = sl; - slcur++; - } - - /* Something went wrong */ - if (ret < 0) { - free(_sldevs); - *sldevs = NULL; - return 0; + _sldevs[slcur++] = sl; } *sldevs = _sldevs; From aff1df29adfb945983e8938807fd58aa2222b5bf Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 10 Apr 2020 11:58:28 +0200 Subject: [PATCH 0798/1435] stlink_probe_usb_devs: return number of successfully opened devices, not number of probed devices. --- src/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/usb.c b/src/usb.c index e3b2a453c..6000e1b4b 100644 --- a/src/usb.c +++ b/src/usb.c @@ -1174,7 +1174,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { } *sldevs = _sldevs; - return slcnt; + return slcur; } size_t stlink_probe_usb(stlink_t **stdevs[]) { From 512999da56107e783e1982a459d3197b4959bb9d Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 10 Apr 2020 15:04:51 +0200 Subject: [PATCH 0799/1435] stlink_open_usb: use macros for stlink pid filtering --- src/usb.c | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/src/usb.c b/src/usb.c index 6000e1b4b..d1c7e6484 100644 --- a/src/usb.c +++ b/src/usb.c @@ -937,14 +937,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST } } - if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) || - (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) || - (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO) || - (desc.idProduct == STLINK_USB_PID_STLINK_V2_1) || - (desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER) || - (desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID) || - (desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID) || - (desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID)) { + if (STLINK_V2_USB_PID(desc.idProduct) || STLINK_V2_1_USB_PID(desc.idProduct) || STLINK_V3_USB_PID(desc.idProduct)) { struct libusb_device_handle *handle; ret = libusb_open(list[cnt], &handle); @@ -955,15 +948,9 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST (unsigned char *)sl->serial, sizeof(sl->serial)); libusb_close(handle); - if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) - || (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) - || (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO) - || (desc.idProduct == STLINK_USB_PID_STLINK_V2_1)) { - sl->version.stlink_v = 2; - } else if ((desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER) - || (desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID) - || (desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID) - || (desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID)) { + if (STLINK_V2_USB_PID(desc.idProduct) || STLINK_V2_1_USB_PID(desc.idProduct)) { + sl->version.stlink_v = 2; + } else if (STLINK_V3_USB_PID(desc.idProduct)) { sl->version.stlink_v = 3; } @@ -977,9 +964,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST break; continue; - } - - if (desc.idProduct == STLINK_USB_PID_STLINK) { + } else if (STLINK_V1_USB_PID(desc.idProduct)) { slu->protocoll = 1; sl->version.stlink_v = 1; break; From 395eee53dfa65302466cd46296b3f2681f3a3f0a Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 10 Apr 2020 17:25:20 +0200 Subject: [PATCH 0800/1435] stlink_open_usb: fix serial lookup mecanism when a v1 device is connected. serial match was not done for v1 device, resulting in attempting to open it systematically, leading to some libusb device claim call failure. Lookup device serial for all chips, compare it if needed, and continue. --- src/usb.c | 56 +++++++++++++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/src/usb.c b/src/usb.c index d1c7e6484..850ae18a1 100644 --- a/src/usb.c +++ b/src/usb.c @@ -926,6 +926,8 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST } while (cnt--) { + struct libusb_device_handle *handle; + libusb_get_device_descriptor( list[cnt], &desc ); if (desc.idVendor != STLINK_USB_VID_ST) continue; @@ -937,48 +939,44 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST } } - if (STLINK_V2_USB_PID(desc.idProduct) || STLINK_V2_1_USB_PID(desc.idProduct) || STLINK_V3_USB_PID(desc.idProduct)) { - struct libusb_device_handle *handle; - - ret = libusb_open(list[cnt], &handle); - if (ret) - continue; + ret = libusb_open(list[cnt], &handle); - sl->serial_size = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, - (unsigned char *)sl->serial, sizeof(sl->serial)); - libusb_close(handle); + /* could not open device, continue */ + if (ret) + continue; - if (STLINK_V2_USB_PID(desc.idProduct) || STLINK_V2_1_USB_PID(desc.idProduct)) { - sl->version.stlink_v = 2; - } else if (STLINK_V3_USB_PID(desc.idProduct)) { - sl->version.stlink_v = 3; - } + sl->serial_size = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, + (unsigned char *)sl->serial, sizeof(sl->serial)); - if ((serial == NULL) || (*serial == 0)) - break; + libusb_close(handle); - if (sl->serial_size < 0) - continue; + /* could not read serial, continue */ + if (sl->serial_size < 0) + continue; - if (memcmp(serial, &sl->serial, sl->serial_size) == 0) - break; + /* if no serial provided, or if serial match device, fixup version and protocol */ + if (((serial == NULL) || (*serial == 0)) || (memcmp(serial, &sl->serial, sl->serial_size) == 0)) { + if (STLINK_V1_USB_PID(desc.idProduct)) { + slu->protocoll = 1; + sl->version.stlink_v = 1; + } else if (STLINK_V2_USB_PID(desc.idProduct) || STLINK_V2_1_USB_PID(desc.idProduct)) { + sl->version.stlink_v = 2; + } else if (STLINK_V3_USB_PID(desc.idProduct)) { + sl->version.stlink_v = 3; + } - continue; - } else if (STLINK_V1_USB_PID(desc.idProduct)) { - slu->protocoll = 1; - sl->version.stlink_v = 1; - break; - } + break; + } } if (cnt < 0) { - WLOG ("Couldn't find %s ST-Link/V2 devices\n",(devBus && devAddr)?"matched":"any"); + WLOG ("Couldn't find %s ST-Link devices\n", (devBus && devAddr) ? "matched":"any"); goto on_error; } else { ret = libusb_open(list[cnt], &slu->usb_handle); if (ret != 0) { - WLOG("Error %d (%s) opening ST-Link/V2 device %03d:%03d\n", - ret, strerror (errno), libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); + WLOG("Error %d (%s) opening ST-Link v%d device %03d:%03d\n", + ret, strerror (errno), sl->version.stlink_v, libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); libusb_free_device_list(list, 1); goto on_error; } From cec61aaea33fbe7a07887867dda9149ea74c16a0 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 10 Apr 2020 17:26:15 +0200 Subject: [PATCH 0801/1435] stlink_open_usb: remove wrong comment, we do handle protocoll (?) v1 for stlinkv1 --- src/usb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/usb.c b/src/usb.c index 850ae18a1..970d3ee81 100644 --- a/src/usb.c +++ b/src/usb.c @@ -1027,8 +1027,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST } slu->sg_transfer_idx = 0; - // TODO - never used at the moment, always CMD_SIZE - slu->cmd_len = (slu->protocoll == 1)? STLINK_SG_SIZE: STLINK_CMD_SIZE; + slu->cmd_len = (slu->protocoll == 1) ? STLINK_SG_SIZE: STLINK_CMD_SIZE; // Initialize stlink version (sl->version) stlink_version(sl); From 99a8aaab253a1cda634291b6a975d1560bb89c0a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 10 Apr 2020 23:38:17 +0200 Subject: [PATCH 0802/1435] General Project Update - Updated CHANGELOG.md - README.md: Edited note on licensing. - Formatting in tutorial.md Temporarily removed travis-lin-mingw script for clean travis builds. --- .gitignore | 2 - .travis-lin-mingw.sh | 14 ------ CHANGELOG.md | 6 ++- README.md | 16 +++--- doc/tutorial.md | 115 ++++++++++++++++++++++--------------------- 5 files changed, 71 insertions(+), 82 deletions(-) delete mode 100755 .travis-lin-mingw.sh diff --git a/.gitignore b/.gitignore index d2dde3a25..23e7ddc07 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,3 @@ build build-mingw obj-* *.user* - -.travis-lin-mingw.sh diff --git a/.travis-lin-mingw.sh b/.travis-lin-mingw.sh deleted file mode 100755 index 0422a06f6..000000000 --- a/.travis-lin-mingw.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -DIR=$PWD - -if [ "$TRAVIS_OS_NAME" == "linux" ]; then - echo "WORK DIR:$DIR" - mkdir -p $DIR/build/linux-mingw32-release - cd $DIR/build/linux-mingw32-release - echo "cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR" - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR - echo "make" - make -fi - diff --git a/CHANGELOG.md b/CHANGELOG.md index 1401843a9..9e31aaf47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ Major changes and added features: * Build for Windows under Debian/Ubuntu ([#802](https://github.com/texane/stlink/pull/802)) * Allow for 64 bytes serials ([#809](https://github.com/texane/stlink/pull/809)) * Added full support for STLINK CHIP ID L4RX ([#814](https://github.com/texane/stlink/pull/814), [#839](https://github.com/texane/stlink/pull/839)) +* Added support for the STLink-v2.1 when flashed with no mass storage (PID 0x3752) ([#819](https://github.com/texane/stlink/pull/819), [#861](https://github.com/texane/stlink/pull/861)) * Added support for writing option bytes on STM32L0xx ([#830](https://github.com/texane/stlink/pull/830)) * Added support to read and write option bytes for STM32F2 series ([#836](https://github.com/texane/stlink/pull/836), [#837](https://github.com/texane/stlink/pull/837)) * Added support to read and write option bytes for STM32F446 ([#843](https://github.com/texane/stlink/pull/843)) @@ -65,7 +66,7 @@ Major changes and added features: * Added creation of icons for .desktop file ([#684](https://github.com/texane/stlink/pull/684), [#708](https://github.com/texane/stlink/pull/708)) * Added desktop file for linux ([#688](https://github.com/texane/stlink/pull/688)) * Added button to export STM32 flash memory to a file ([#691](https://github.com/texane/stlink/pull/691)) -* Updated libusb to 1.0.22 ([#695](https://github.com/texane/stlink/pull/695)) +* Updated libusb to 1.0.22 ([#695](https://github.com/texane/stlink/pull/695)) - (related Bugs: [#438](https://github.com/texane/stlink/pull/438), [#632](https://github.com/texane/stlink/pull/632)) * Added icons for STLink GUI ([#697](https://github.com/texane/stlink/pull/697)) * Added support for STM32L4R9 target ([#694](https://github.com/texane/stlink/pull/694), [#699](https://github.com/texane/stlink/pull/699)) * Added memory map for STM32F411RE target ([#709](https://github.com/texane/stlink/pull/709)) @@ -132,7 +133,7 @@ Updates and fixes: * Added --flash=n[k][m] command line option to override device model ([#305](https://github.com/texane/stlink/pull/305), [#516](https://github.com/texane/stlink/pull/516), [#576](https://github.com/texane/stlink/pull/576)) * Updated libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) * Fixed low-voltage flashing on STM32F7 devices ([#566](https://github.com/texane/stlink/pull/566), [#567](https://github.com/texane/stlink/pull/567)) -* Fixed building with mingw64 ([#569](https://github.com/texane/stlink/pull/569), [#573](https://github.com/texane/stlink/pull/573), [#578](https://github.com/texane/stlink/pull/578), [#584](https://github.com/texane/stlink/pull/584), [#610](https://github.com/texane/stlink/pull/610)) +* Fixed building with mingw64 ([#569](https://github.com/texane/stlink/pull/569), [#573](https://github.com/texane/stlink/pull/573), [#578](https://github.com/texane/stlink/pull/578), [#582](https://github.com/texane/stlink/pull/582), [#584](https://github.com/texane/stlink/pull/584), [#610](https://github.com/texane/stlink/pull/610), [#846](https://github.com/texane/stlink/pull/846)) * Fixed possible memory leak ([#570](https://github.com/texane/stlink/pull/570), [#571](https://github.com/texane/stlink/pull/571)) * Fixed installation path for shared objects ([#581](https://github.com/texane/stlink/pull/581)) * Fixed a few -Wformat warnings ([#582](https://github.com/texane/stlink/pull/582)) @@ -246,6 +247,7 @@ Updates and fixes: * Stm32l0x flash loader (Robin Kreis) * Send F4 memory-map and features for STM32F429 ([#188](https://github.com/texane/stlink/pull/188), [#196](https://github.com/texane/stlink/pull/196), [#250](https://github.com/texane/stlink/pull/250), [#251](https://github.com/texane/stlink/pull/251)) (Release v1.1.0) * Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/texane/stlink/pull/218), [#288](https://github.com/texane/stlink/pull/288)) (Release v1.1.0) +* Corrected flash size register address for STM32F2 devices ([#278](https://github.com/texane/stlink/pull/278)) (Release v1.0.0) Chip support added for: diff --git a/README.md b/README.md index 4b1195166..e6de34dab 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Open source version of the STMicroelectronics Stlink Tools +Open source version of the STMicroelectronics STlink Tools ========================================================== [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) @@ -11,6 +11,13 @@ Open source version of the STMicroelectronics Stlink Tools Recent new features and bugfixes can be found in the [Changelog](CHANGELOG.md) of this software project. +#### License + +The stlink library and tools are licensed under the **[BSD-3 License](LICENSE.md)**.
    +The source files **stm32l0x.s** and **stm32lx.s** found in the subdirectory `/flashloaders/` +are licensed under the **General Public License (GPL v2+)**. + + ## Introduction This stlink toolset supports several so called stlink programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG. @@ -89,13 +96,6 @@ When there is no executable available for your platform or you need the latest ( * Please start new forks from the develop branch if possible as pull requests will go into this branch as well. -## License - -The stlink library and tools are licensed under the [BSD-3 license](LICENSE.md). - -The flashloaders/stm32l0x.s and flashloaders/stm32lx.s source files are licensed under the GPLv2+. - - # Current state of the project ## Known missing features diff --git a/doc/tutorial.md b/doc/tutorial.md index 9c1f7f26d..66bed0382 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -2,6 +2,7 @@ stlink Tools Tutorial ===================== ## Useful tool options + ### st-flash #### --flash=n[k][m] @@ -14,8 +15,8 @@ Obviously leaving the multiplier out is equally valid, for example: `--flash=0x2 The size may be followed by an optional "k" or "m" to multiply the given value by 1k (1024) or 1M respectively. -## Solution to common problems -### ST-Link-v1 driver: Issue with Kernel Extension (kext) (macOS 10.11 and later only) +## Solutions to common problems +### a) ST-Link-v1 driver: Issue with Kernel Extension (kext) (macOS 10.11 and later only) #### Problem: st-util fails to detect a ST-Link-v1 device: @@ -39,11 +40,13 @@ while SIP is fully activated (as is per default). Action needs to be taken here by booting into the recovery mode where a terminal console window needs to be opened. -Here it is **NOT RECOMMEND to disable SIP completely as with the command** `csrutil disable`, -**because this leaves the system more vulnerable to common threats. +For macOS 10.11 - 10.13 it is not recommended to disable SIP completely as with the command `csrutil disable`, +because this leaves the system more vulnerable to common threats. Instead there is a more adequate and reasonable option implemented by Apple. -Running** `csrutil enable --without kext`, **allows to load unsigned kernel extensions -while leaving SIP active with all other security features.** +Running `csrutil enable --without kext`, allows to load unsigned kernel extensions +while leaving SIP active with all other security features. +Unfortunately this option has been removed in macOS 10.14, which leaves the only option to disable SIP completely. + So who ever intends to run the ST-Link-v1 programmer on macOS please take this into account. Further details can be found here: https://forums.developer.apple.com/thread/17452 @@ -76,8 +79,56 @@ INFO gdb-server.c: Chip ID is 00000414, Core ID is 1ba01477. INFO gdb-server.c: Listening at *:4242... ``` +### b) Verify if udev rules are set correctly (by Dave Hylands) + +To investigate, start by plugging your STLINK device into the usb port. Then run lsusb. You should see an entry something like the following: + +``` +Bus 005 Device 017: ID 0483:374b STMicroelectronics ST-LINK/V2.1 (Nucleo-F103RB) +``` + +Note the bus number (005) and the Device (017). You should then do: +`ls -l /dev/bus/usb/005/017` (replacing 005 and 017 appropriately). + +On my system I see the following: + +``` +crw-rw-rw- 1 root root 189, 528 Jan 24 17:52 /dev/bus/usb/005/017 +``` + +which is world writable (this is from the MODE:="0666" below). I have several files in my `/etc/udev/rules.d` directory. In this particular case, the `49-stlinkv2-1.rules` file contains the following: + +``` +# 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. +``` + +and the idVendor of 0483 and idProduct of 374b matches the vendor id from the lsusb output. + +Make sure that you have all 3 files from here: https://github.com/texane/stlink/tree/master/etc/udev/rules.d in your `/etc/udev/rules.d` directory. After copying new files or editing excisting files in `/etc/udev/ruled.d` you should run the following: + +``` +sudo udevadm control --reload-rules +sudo udevadm trigger +``` + +to ensure that the rules actually take effect. Using the trigger command means that you shouldn't need to unplug and replug the device, but you might want to try that for good measure as well. + +If the VID:PID of your device doesn't match those in any of the 3 files, then you may need to create a custom rule file to match your VID:PID. + ------ +( Content below is currently unrevised and may be outdated as of Apr 2020. ) Using STM32 discovery kits with open source tools ======== @@ -249,56 +300,8 @@ $> [sudo] ./st-flash write fancy_blink.bin 0x08000000 Upon reset, the board LEDs should be blinking. -HOWTO -===== - -## Verify if udev rules are set correctly (by Dave Hylands) - -To investigate, start by plugging your STLINK device into the usb port. Then run lsusb. You should see an entry something like the following: - -``` -Bus 005 Device 017: ID 0483:374b STMicroelectronics ST-LINK/V2.1 (Nucleo-F103RB) -``` - -Note the bus number (005) and the Device (017). You should then do: -`ls -l /dev/bus/usb/005/017` (replacing 005 and 017 appropriately). - -On my system I see the following: - -``` -crw-rw-rw- 1 root root 189, 528 Jan 24 17:52 /dev/bus/usb/005/017 -``` - -which is world writable (this is from the MODE:="0666" below). I have several files in my `/etc/udev/rules.d` directory. In this particular case, the `49-stlinkv2-1.rules` file contains the following: - -``` -# 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. -``` - -and the idVendor of 0483 and idProduct of 374b matches the vendor id from the lsusb output. - -Make sure that you have all 3 files from here: https://github.com/texane/stlink/tree/master/etc/udev/rules.d in your `/etc/udev/rules.d` directory. After copying new files or editing excisting files in `/etc/udev/ruled.d` you should run the following: - -``` -sudo udevadm control --reload-rules -sudo udevadm trigger -``` - -to ensure that the rules actually take effect. Using the trigger command means that you shouldn't need to unplug and replug the device, but you might want to try that for good measure as well. - -If the VID:PID of your device doesn't match those in any of the 3 files, then you may need to create a custom rule file to match your VID:PID. - +HOWTO (old) +=========== ## Using the gdb server From 7e4540aa7ddf478fca44aad140c3af04bfbaee5a Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Sat, 11 Apr 2020 12:11:08 +0800 Subject: [PATCH 0803/1435] Fix code style alignment --- src/tools/flash_opts.c | 48 +++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index ef41601a5..a6633d973 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -93,30 +93,30 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { else return -1; } - else if ( starts_with(av[0], "--flash=") ) { - const char *arg = av[0] + strlen("--flash="); - char *ep = 0; - - o->flash_size = (uint32_t)strtoul(arg,&ep,0); - while ( *ep ) { - switch ( *ep++ ) { - case 0: - break; - case 'k': - case 'K': - o->flash_size *= 1024u; - break; - case 'm': - case 'M': - o->flash_size *= 1024u * 1024u; - break; - default: - fprintf(stderr,"Invalid --flash=%s\n",arg); - return -1; - } - } - } - else { + else if ( starts_with(av[0], "--flash=") ) { + const char *arg = av[0] + strlen("--flash="); + char *ep = 0; + + o->flash_size = (uint32_t)strtoul(arg,&ep,0); + while ( *ep ) { + switch ( *ep++ ) { + case 0: + break; + case 'k': + case 'K': + o->flash_size *= 1024u; + break; + case 'm': + case 'M': + o->flash_size *= 1024u * 1024u; + break; + default: + fprintf(stderr,"Invalid --flash=%s\n",arg); + return -1; + } + } + } + else { break; // non-option found } From cc27e61e9d5bd45e3d9d78f972649bec01f26707 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Sat, 11 Apr 2020 13:46:59 +0800 Subject: [PATCH 0804/1435] Fix 0xFF optimization bug --- include/stlink.h | 1 + include/stlink/tools/flash.h | 4 ++- src/common.c | 56 ++++++++++++++++++++++++------------ src/tools/flash.c | 5 ++-- src/tools/flash_opts.c | 3 ++ 5 files changed, 47 insertions(+), 22 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 94e980435..508b50f7d 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -151,6 +151,7 @@ typedef struct flash_loader { // transport layer verboseness: 0 for no debug info, 10 for lots int verbose; + int opt; uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram int core_stat; // set by stlink_status(), values STLINK_CORE_xxxxx diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index a73d7aee4..659c17f28 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -6,6 +6,7 @@ #define DEBUG_LOG_LEVEL 100 #define STND_LOG_LEVEL 50 +#define ENABLE_OPT 1 enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3, CMD_RESET = 4}; enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1}; @@ -24,9 +25,10 @@ struct flash_opts enum flash_area area; uint32_t val; size_t flash_size; /* --flash=n[k][m] */ + int opt; }; -#define FLASH_OPTS_INITIALIZER {0, NULL, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0 } +#define FLASH_OPTS_INITIALIZER {0, NULL, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0} int flash_get_opts(struct flash_opts* o, int ac, char** av); diff --git a/src/common.c b/src/common.c index f432cf5a1..c5506c061 100644 --- a/src/common.c +++ b/src/common.c @@ -2621,17 +2621,30 @@ int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr unsigned int num_empty, idx; uint8_t erased_pattern = stlink_get_erased_pattern(sl); - idx = (unsigned int)length; - for(num_empty = 0; num_empty != length; ++num_empty) { - if (data[--idx] != erased_pattern) { - break; + /* + * This optimization may cause unexpected garbage data remaining + * Turned off by default + */ + if (sl->opt) { + idx = (unsigned int)length; + for(num_empty = 0; num_empty != length; ++num_empty) { + if (data[--idx] != erased_pattern) { + break; + } } + /* Round down to words */ + num_empty -= (num_empty & 3); + if(num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); + } + } else { + num_empty = 0; } - /* Round down to words */ - num_empty -= (num_empty & 3); - if(num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); - } + /* + * a kind of weird behaviour here: + * if the file is identified to be all-empty and four-bytes aligned, + * still flash the whole file even if ignoring message is printed + */ err = stlink_write_flash(sl, addr, data, (num_empty == length) ? (uint32_t) length : (uint32_t) length - num_empty, num_empty == length); stlink_fwrite_finalize(sl, addr); return err; @@ -2655,18 +2668,23 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { ELOG("map_file() == -1\n"); return -1; } - - idx = (unsigned int) mf.len; - for(num_empty = 0; num_empty != mf.len; ++num_empty) { - if (mf.base[--idx] != erased_pattern) { - break; + + if (sl->opt) { + idx = (unsigned int) mf.len; + for(num_empty = 0; num_empty != mf.len; ++num_empty) { + if (mf.base[--idx] != erased_pattern) { + break; + } } + /* Round down to words */ + num_empty -= (num_empty & 3); + if(num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); + } + } else { + num_empty = 0; } - /* Round down to words */ - num_empty -= (num_empty & 3); - if(num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); - } + err = stlink_write_flash(sl, addr, mf.base, (num_empty == mf.len) ? (uint32_t) mf.len : (uint32_t) mf.len - num_empty, num_empty == mf.len); stlink_fwrite_finalize(sl, addr); unmap_file(&mf); diff --git a/src/tools/flash.c b/src/tools/flash.c index e1e9f41f6..67e03c62b 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -29,9 +29,9 @@ static void cleanup(int signum) { static void usage(void) { - puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--format ] [--flash=] {read|write} /dev/sgX "); + puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--opt] [--format ] [--flash=] {read|write} /dev/sgX "); puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); - puts("stlinkv2/3 command line: ./st-flash [--debug] [--reset] [--serial ] [--format ] [--flash=] {read|write} "); + puts("stlinkv2/3 command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] {read|write} "); puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] erase"); puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] reset"); puts(" , and : Use hex format."); @@ -73,6 +73,7 @@ int main(int ac, char** av) } sl->verbose = o.log_level; + sl->opt = o.opt; connected_stlink = sl; signal(SIGINT, &cleanup); diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index a6633d973..d409603f9 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -27,6 +27,9 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { else if (strcmp(av[0], "--debug") == 0) { o->log_level = DEBUG_LOG_LEVEL; } + else if (strcmp(av[0], "--opt") == 0) { + o->opt = ENABLE_OPT; + } else if (strcmp(av[0], "--reset") == 0) { o->reset = 1; } From e97eaa329a43dde694851cf27b55aa3891f9e85e Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Sat, 11 Apr 2020 14:06:38 +0800 Subject: [PATCH 0805/1435] Add man documentation about --opt --- doc/man/st-flash.1 | 39 +++++++++++++++++++++------------------ doc/man/st-flash.md | 3 +++ 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/doc/man/st-flash.1 b/doc/man/st-flash.1 index 36df7daa8..c2654f280 100644 --- a/doc/man/st-flash.1 +++ b/doc/man/st-flash.1 @@ -1,52 +1,55 @@ -.\" Automatically generated by Pandoc 2.4 +.\" Automatically generated by Pandoc 2.9 .\" -.TH "st\-flash" "1" "Feb 2018" "Open Source STMicroelectronics Stlink Tools" "stlink" +.TH "st-flash" "1" "Feb 2018" "Open Source STMicroelectronics Stlink Tools" "stlink" .hy .SH NAME .PP -st\-flash \- Flash binary files to STM32 device +st-flash - Flash binary files to STM32 device .SH SYNOPSIS .PP -\f[I]st\-flash\f[R] [\f[I]OPTIONS\f[R]] {read|write|erase} +\f[I]st-flash\f[R] [\f[I]OPTIONS\f[R]] {read|write|erase} [\f[I]FILE\f[R]] .SH DESCRIPTION .PP Flash binary files to arbitrary sections of memory, or read arbitrary addresses of memory out to a binary file. .PP -You can use this instead of st\-util(1) if you prefer, but remember to +You can use this instead of st-util(1) if you prefer, but remember to use the \f[B].bin\f[R] image, rather than the \f[B].elf\f[R] file. .PP Use hexadecimal format for the \f[I]ADDR\f[R] and \f[I]SIZE\f[R]. .SH COMMANDS .TP -.B write \f[I]FILE\f[R] \f[I]ADDR\f[R] +write \f[I]FILE\f[R] \f[I]ADDR\f[R] Write firmware \f[I]FILE\f[R] to device starting from \f[I]ADDR\f[R] .TP -.B read \f[I]FILE\f[R] \f[I]ADDR\f[R] \f[I]SIZE\f[R] +read \f[I]FILE\f[R] \f[I]ADDR\f[R] \f[I]SIZE\f[R] Read firmware from device starting from \f[I]ADDR\f[R] up to \f[I]SIZE\f[R] bytes to \f[I]FILE\f[R] .TP -.B erase +erase Perform a mass erasing of the device firmware .TP -.B reset +reset Reset the target .SH OPTIONS .TP -.B \-\-version +--version Print version information .TP -.B \-\-debug +--debug TODO .TP -.B \-\-reset +--reset TODO .TP -.B \-\-serial \f[I]iSerial\f[R] +--opt +Enable ignore ending empty bytes optimization +.TP +--serial \f[I]iSerial\f[R] TODO .TP -.B \-\-flash=fsize +--flash=fsize Where fsize is the size in decimal, octal, or hex followed by an optional multiplier `k' for KB, or `m' for MB. Use a leading \[lq]0x\[rq] to specify hexadecimal, or a leading zero for @@ -57,7 +60,7 @@ Flash \f[C]firmware.bin\f[R] to device .IP .nf \f[C] -$ st\-flash write firmware.bin 0x8000000 +$ st-flash write firmware.bin 0x8000000 \f[R] .fi .PP @@ -65,7 +68,7 @@ Read firmware from device (4096 bytes) .IP .nf \f[C] -$ st\-flash read firmware.bin 0x8000000 0x1000 +$ st-flash read firmware.bin 0x8000000 0x1000 \f[R] .fi .PP @@ -73,12 +76,12 @@ Erase firmware from device .IP .nf \f[C] -$ st\-flash erase +$ st-flash erase \f[R] .fi .SH SEE ALSO .PP -st\-util(1), st\-info(1) +st-util(1), st-info(1) .SH COPYRIGHT .PP This work is copyrighted. diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md index 1860a8c72..b787e8dd7 100644 --- a/doc/man/st-flash.md +++ b/doc/man/st-flash.md @@ -45,6 +45,9 @@ reset \--reset : TODO +\--opt +: Enable ignore ending empty bytes optimization + \--serial *iSerial* : TODO From 12637a47f52a6595417b672963bf47cbe026b272 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Sat, 11 Apr 2020 16:44:25 +0800 Subject: [PATCH 0806/1435] Indent with four spaces --- .travis-lin-mingw.sh | 14 ------------ src/tools/flash_opts.c | 48 +++++++++++++++++++++--------------------- 2 files changed, 24 insertions(+), 38 deletions(-) delete mode 100755 .travis-lin-mingw.sh diff --git a/.travis-lin-mingw.sh b/.travis-lin-mingw.sh deleted file mode 100755 index 0422a06f6..000000000 --- a/.travis-lin-mingw.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -DIR=$PWD - -if [ "$TRAVIS_OS_NAME" == "linux" ]; then - echo "WORK DIR:$DIR" - mkdir -p $DIR/build/linux-mingw32-release - cd $DIR/build/linux-mingw32-release - echo "cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR" - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR - echo "make" - make -fi - diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index d409603f9..a24bde1be 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -96,30 +96,30 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { else return -1; } - else if ( starts_with(av[0], "--flash=") ) { - const char *arg = av[0] + strlen("--flash="); - char *ep = 0; - - o->flash_size = (uint32_t)strtoul(arg,&ep,0); - while ( *ep ) { - switch ( *ep++ ) { - case 0: - break; - case 'k': - case 'K': - o->flash_size *= 1024u; - break; - case 'm': - case 'M': - o->flash_size *= 1024u * 1024u; - break; - default: - fprintf(stderr,"Invalid --flash=%s\n",arg); - return -1; - } - } - } - else { + else if ( starts_with(av[0], "--flash=") ) { + const char *arg = av[0] + strlen("--flash="); + char *ep = 0; + + o->flash_size = (uint32_t)strtoul(arg,&ep,0); + while ( *ep ) { + switch ( *ep++ ) { + case 0: + break; + case 'k': + case 'K': + o->flash_size *= 1024u; + break; + case 'm': + case 'M': + o->flash_size *= 1024u * 1024u; + break; + default: + fprintf(stderr,"Invalid --flash=%s\n",arg); + return -1; + } + } + } + else { break; // non-option found } From 11156bc66b7b3473654def392cccca9f0c3222d7 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Sat, 11 Apr 2020 20:02:03 +0800 Subject: [PATCH 0807/1435] Add TODO tag in source code --- src/common.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index c5506c061..af9a87a8a 100644 --- a/src/common.c +++ b/src/common.c @@ -2641,6 +2641,7 @@ int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr num_empty = 0; } /* + * TODO: investigate: * a kind of weird behaviour here: * if the file is identified to be all-empty and four-bytes aligned, * still flash the whole file even if ignoring message is printed @@ -2684,7 +2685,12 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { } else { num_empty = 0; } - + /* + * TODO: investigate: + * a kind of weird behaviour here: + * if the file is identified to be all-empty and four-bytes aligned, + * still flash the whole file even if ignoring message is printed + */ err = stlink_write_flash(sl, addr, mf.base, (num_empty == mf.len) ? (uint32_t) mf.len : (uint32_t) mf.len - num_empty, num_empty == mf.len); stlink_fwrite_finalize(sl, addr); unmap_file(&mf); From 734bfdaa4754d6a6dd9ac974670ec7c0b9096347 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Sat, 11 Apr 2020 20:24:08 +0800 Subject: [PATCH 0808/1435] Remove .travis-lin-mingw.sh in travis.yml --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b1832d57f..d88bf1036 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,4 +26,3 @@ script: - printenv - cmake --version - ./.travis.sh - - ./.travis-lin-mingw.sh From 2979df40480be52678f41e20c3ed1893888ea0dc Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Sat, 11 Apr 2020 22:24:33 +0800 Subject: [PATCH 0809/1435] Fix 32 bit build on develop branch --- src/common.c | 22 +++++++++++----------- src/gdbserver/gdb-server.c | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/common.c b/src/common.c index af9a87a8a..b44c1e692 100644 --- a/src/common.c +++ b/src/common.c @@ -190,10 +190,10 @@ #define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ // Bits requesting flash operations (useful when we want to clear them) #define STM32L4_FLASH_CR_OPBITS \ - ((1lu<chip_id == STLINK_CHIPID_STM32_L496X || sl->chip_id == STLINK_CHIPID_STM32_L4RX) { // This chip use dual banked flash - if (flashopt & (1lu << STM32L4_FLASH_OPTR_DUALBANK)) { + if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { uint32_t banksize = (uint32_t) sl->flash_size / 2; if (flashaddr >= banksize) { flashaddr -= banksize; @@ -1731,7 +1731,7 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { // For 1MB chips without the dual-bank option set, the page address will // overflow into the BKER bit, which gives us the correct bank:page value. - return bker | flashaddr/sl->flash_pgsz; + return bker | flashaddr/(uint32_t)sl->flash_pgsz; } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ @@ -1907,7 +1907,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) // Set the page to erase. if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); // sec 3.10.5 - PNB[7:0] is offset by 3. @@ -1916,14 +1916,14 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) stlink_write_debug32(sl, STM32WB_FLASH_CR, val); } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. val &= ~(0x3F << 3); val |= ((flash_page & 0x3F) << 3) | ( 1 << FLASH_CR_PER ); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); } else if (sl->flash_type == STLINK_FLASH_TYPE_G4) { - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. val &= ~(0x7F << 3); @@ -2000,7 +2000,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_L0 || sl->flash_type == STLINK_FLASH_TYPE_WB) { /* erase each page */ - int i = 0, num_pages = (int) sl->flash_size/sl->flash_pgsz; + int i = 0, num_pages = (int)(sl->flash_size/sl->flash_pgsz); for (i = 0; i < num_pages; i++) { /* addr must be an addr inside the page */ stm32_addr_t addr = (stm32_addr_t) sl->flash_base + i * (stm32_addr_t) sl->flash_pgsz; diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 3aa769e02..9cff5f917 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -862,7 +862,7 @@ static int flash_go(stlink_t *sl) { for(struct flash_block* fb = flash_root; fb; fb = fb->next) { DLOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length); - for(stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += FLASH_PAGE) { + for(stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += (uint32_t)FLASH_PAGE) { unsigned length = fb->length - (page - fb->addr); //Update FLASH_PAGE From 067639ff8cb6fb23a00c9122822e542560f9a4ee Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Sun, 12 Apr 2020 21:02:42 +0800 Subject: [PATCH 0810/1435] Enhance error log with file path for map_file() --- src/common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common.c b/src/common.c index b44c1e692..813151f67 100644 --- a/src/common.c +++ b/src/common.c @@ -1302,19 +1302,19 @@ static int map_file(mapped_file_t* mf, const char* path) { } if (fstat(fd, &st) == -1) { - fprintf(stderr, "fstat() == -1\n"); + fprintf(stderr, "fstat(%s) == -1\n", path); goto on_error; } if (sizeof(st.st_size) != sizeof(size_t)) { /* On 32 bit systems, check if there is an overflow */ if (st.st_size > (off_t)UINT32_MAX) { - fprintf(stderr, "mmap() size_t overflow\n"); + fprintf(stderr, "mmap() size_t overflow for file %s\n", path); goto on_error; } } mf->base = (uint8_t*) mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); if (mf->base == MAP_FAILED) { - fprintf(stderr, "mmap() == MAP_FAILED\n"); + fprintf(stderr, "mmap() == MAP_FAILED for file %s\n", path); goto on_error; } From cadfa941621cef85205622d6af0f87648d2a31c7 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 12 Apr 2020 18:26:46 +0200 Subject: [PATCH 0811/1435] General Project Update - Updated travis CI build configuration - Updated project references - Minor formatting fixes --- .travis.yml | 109 ++++++++++++++++++++++++++++++++------- CMakeLists.txt | 18 ++++--- README.md | 10 ++-- cmake/cpack_config.cmake | 3 +- 4 files changed, 106 insertions(+), 34 deletions(-) diff --git a/.travis.yml b/.travis.yml index d88bf1036..079888765 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,25 +1,96 @@ - -compiler: - - gcc - - clang - language: c -os: - - linux - - osx +matrix: + include: + ### 64-bit builds ### + - os: linux + arch: x64 + compiler: gcc-5 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['gcc-5', 'libusb-1.0.0-dev'] + - os: linux + arch: x64 + compiler: gcc-7 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['gcc-7', 'libusb-1.0.0-dev'] + - os: linux + arch: x64 + compiler: gcc-9 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['gcc-9', 'libusb-1.0.0-dev'] + - os: linux + arch: x64 + compiler: clang-3.7 + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-3.7'] + packages: ['clang-3.7', 'libusb-1.0.0-dev'] + - os: linux + arch: x64 + compiler: clang-6.0 + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] + packages: ['clang-6.0', 'libusb-1.0.0-dev'] + + ### 32-bit builds ### + - os: linux + arch: x86 + compiler: gcc-5 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['gcc-5', 'libusb-1.0.0-dev'] + - os: linux + arch: x86 + compiler: gcc-6 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['gcc-6', 'libusb-1.0.0-dev'] + - os: linux + arch: x86 + compiler: gcc-7 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['gcc-7', 'libusb-1.0.0-dev'] + - os: linux + arch: x86 + compiler: clang-3.7 + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-3.7'] + packages: ['clang-3.7', 'libusb-1.0.0-dev'] + - os: linux + arch: x86 + compiler: clang-6.0 + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] + packages: ['clang-6.0', 'libusb-1.0.0-dev'] -addons: - apt: - sources: - - sourceline: 'ppa:ubuntu-toolchain-r/test' - packages: - - clang - - g++-6 - - gcc-6 - - libusb-1.0.0-dev - - p7zip - - mingw-w64 + ### macOS ### + - os: osx + compiler: gcc + addons: + homebrew: + packages: + - libusb + - gcc + - os: osx + compiler: clang + addons: + homebrew: + packages: + - libusb + - clang script: - git fetch --tags diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f0b46449..8a282f550 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,12 +17,12 @@ if (IS_DIRECTORY ${LIB_INSTALL_DIR}) set(STLINK_LIBRARY_PATH "${LIB_INSTALL_DIR}") else () set(LIB_INSTALL_DIR "lib" CACHE PATH "Main library directory") - set(STLINK_LIBRARY_PATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}" ) + set(STLINK_LIBRARY_PATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}") endif () if (IS_DIRECTORY ${INCLUDE_INSTALL_DIR}) set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_DIR} CACHE PATH "Main include directory") - set(STLINK_INCLUDE_PATH "${INCLUDE_INSTALL_DIR}" ) + set(STLINK_INCLUDE_PATH "${INCLUDE_INSTALL_DIR}") else () set(INCLUDE_INSTALL_DIR "include" CACHE PATH "Main include directory") set(STLINK_INCLUDE_PATH "${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_DIR}") @@ -148,7 +148,7 @@ set_target_properties( VERSION ${STLINK_SHARED_VERSION} ) -# Link shared library with apple OS libraries +# Link shared library with Apple macOS libraries if (APPLE) find_library(ObjC objc) find_library(CoreFoundation CoreFoundation) @@ -178,9 +178,9 @@ add_library( ${STLINK_LIB_STATIC} STATIC ${STLINK_HEADERS} # header files for ide projects generated by cmake ${STLINK_SOURCE} -) + ) -# Link shared library with apple OS libraries +# Link shared library with Apple macOS libraries if (APPLE) find_library(ObjC objc) find_library(CoreFoundation CoreFoundation) @@ -257,7 +257,9 @@ if (NOT TARGET uninstall) "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY - ) - add_custom_target(uninstall - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) + ) + add_custom_target( + uninstall COMMAND ${CMAKE_COMMAND} + -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake + ) endif () diff --git a/README.md b/README.md index e6de34dab..29d1ef766 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,11 @@ Open source version of the STMicroelectronics STlink Tools ========================================================== [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) -[![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/texane/stlink/releases/latest) -[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/v1.6.0.svg)](https://github.com/texane/stlink/releases/master) -[![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/texane/stlink/releases) -[![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/texane/stlink) -[![macOS Status](https://img.shields.io/travis/texane/stlink/master.svg?label=osx)](https://travis-ci.org/texane/stlink) +[![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/stlink-org/stlink/releases/latest) +[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/v1.6.0.svg)](https://github.com/stlink-org/stlink/releases/master) +[![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/stlink-org/stlink/releases) +[![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/stlink-org/stlink) +[![macOS Status](https://img.shields.io/travis/texane/stlink/master.svg?label=osx)](https://travis-ci.org/stlink-org/stlink) Recent new features and bugfixes can be found in the [Changelog](CHANGELOG.md) of this software project. diff --git a/cmake/cpack_config.cmake b/cmake/cpack_config.cmake index 72a98a821..b8d4be186 100644 --- a/cmake/cpack_config.cmake +++ b/cmake/cpack_config.cmake @@ -16,12 +16,11 @@ elseif (WIN32) elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND EXISTS "/etc/debian_version") message(STATUS "Debian-based Linux OS detected") set(CPACK_GENERATOR "DEB") - if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}-amd64" ) endif() - set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/texane/stlink") + set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/stlink-org/stlink") set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Luca Boccassi") set(CPACK_PACKAGE_CONTACT "bluca@debian.org") set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "STM32 STlink programmer tools") From 79676cdf793eedcfa210147098e621926d1cb222 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Mon, 13 Apr 2020 17:12:58 +0800 Subject: [PATCH 0812/1435] Add md5 checksum for binary file --- CMakeLists.txt | 1 + src/common.c | 23 +++- src/md5.c | 339 +++++++++++++++++++++++++++++++++++++++++++++++++ src/md5.h | 100 +++++++++++++++ 4 files changed, 462 insertions(+), 1 deletion(-) create mode 100755 src/md5.c create mode 100755 src/md5.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f0b46449..7dd8c4d0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,6 +97,7 @@ set(STLINK_SOURCE src/sg.c src/logging.c src/flash_loader.c + src/md5.c ) if (WIN32 OR MSYS OR MINGW) diff --git a/src/common.c b/src/common.c index 813151f67..43cec756d 100644 --- a/src/common.c +++ b/src/common.c @@ -15,6 +15,7 @@ #include "stlink.h" #include "stlink/mmap.h" #include "stlink/logging.h" +#include "md5.h" #ifndef O_BINARY #define O_BINARY 0 @@ -1365,6 +1366,20 @@ static int check_file(stlink_t* sl, mapped_file_t* mf, stm32_addr_t addr) { return 0; } +static void md5_calculate(mapped_file_t *mf, const char *path) { + /* calculate md5 checksum of given binary file */ + Md5Context md5Context; + MD5_HASH md5Hash; + Md5Initialise(&md5Context); + Md5Update(&md5Context, mf->base, (uint32_t)mf->len); + Md5Finalise(&md5Context, &md5Hash); + printf("file %s md5 checksum: ",path); + for(int i = 0; i < (int) sizeof(md5Hash); i++) { + printf("%x", md5Hash.bytes[i]); + } + printf("\n"); +} + static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { unsigned int val; /* set stack*/ @@ -1446,6 +1461,8 @@ int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { return -1; } + md5_calculate(&mf, path); + /* check addr range is inside the sram */ if (addr < sl->sram_base) { fprintf(stderr, "addr too low\n"); @@ -2669,7 +2686,9 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { ELOG("map_file() == -1\n"); return -1; } - + + md5_calculate(&mf, path); + if (sl->opt) { idx = (unsigned int) mf.len; for(num_empty = 0; num_empty != mf.len; ++num_empty) { @@ -3234,6 +3253,8 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr return -1; } + md5_calculate(&mf, path); + err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t) mf.len); stlink_fwrite_finalize(sl, addr); unmap_file(&mf); diff --git a/src/md5.c b/src/md5.c new file mode 100755 index 000000000..ff7d2d76e --- /dev/null +++ b/src/md5.c @@ -0,0 +1,339 @@ +/* + * Retrieved from https://github.com/WaterJuice/WjCryptLib + */ + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// WjCryptLib_Md5 +// +// Implementation of MD5 hash function. Originally written by Alexander Peslyak. Modified by WaterJuice retaining +// Public Domain license. +// +// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "md5.h" +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// INTERNAL FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// F, G, H, I +// +// The basic MD5 functions. F and G are optimised compared to their RFC 1321 definitions for architectures that lack +// an AND-NOT instruction, just like in Colin Plumb's implementation. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define F( x, y, z ) ( (z) ^ ((x) & ((y) ^ (z))) ) +#define G( x, y, z ) ( (y) ^ ((z) & ((x) ^ (y))) ) +#define H( x, y, z ) ( (x) ^ (y) ^ (z) ) +#define I( x, y, z ) ( (y) ^ ((x) | ~(z)) ) + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// STEP +// +// The MD5 transformation for all four rounds. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define STEP( f, a, b, c, d, x, t, s ) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TransformFunction +// +// This processes one or more 64-byte data blocks, but does NOT update the bit counters. There are no alignment +// requirements. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static +void* + TransformFunction + ( + Md5Context* ctx, + void const* data, + uintmax_t size + ) +{ + uint8_t* ptr; + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; + uint32_t saved_a; + uint32_t saved_b; + uint32_t saved_c; + uint32_t saved_d; + + #define GET(n) (ctx->block[(n)]) + #define SET(n) (ctx->block[(n)] = \ + ((uint32_t)ptr[(n)*4 + 0] << 0 ) \ + | ((uint32_t)ptr[(n)*4 + 1] << 8 ) \ + | ((uint32_t)ptr[(n)*4 + 2] << 16) \ + | ((uint32_t)ptr[(n)*4 + 3] << 24) ) + + ptr = (uint8_t*)data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do + { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + + // Round 1 + STEP( F, a, b, c, d, SET(0), 0xd76aa478, 7 ) + STEP( F, d, a, b, c, SET(1), 0xe8c7b756, 12 ) + STEP( F, c, d, a, b, SET(2), 0x242070db, 17 ) + STEP( F, b, c, d, a, SET(3), 0xc1bdceee, 22 ) + STEP( F, a, b, c, d, SET(4), 0xf57c0faf, 7 ) + STEP( F, d, a, b, c, SET(5), 0x4787c62a, 12 ) + STEP( F, c, d, a, b, SET(6), 0xa8304613, 17 ) + STEP( F, b, c, d, a, SET(7), 0xfd469501, 22 ) + STEP( F, a, b, c, d, SET(8 ), 0x698098d8, 7 ) + STEP( F, d, a, b, c, SET(9 ), 0x8b44f7af, 12 ) + STEP( F, c, d, a, b, SET(10 ), 0xffff5bb1, 17 ) + STEP( F, b, c, d, a, SET(11 ), 0x895cd7be, 22 ) + STEP( F, a, b, c, d, SET(12 ), 0x6b901122, 7 ) + STEP( F, d, a, b, c, SET(13 ), 0xfd987193, 12 ) + STEP( F, c, d, a, b, SET(14 ), 0xa679438e, 17 ) + STEP( F, b, c, d, a, SET(15 ), 0x49b40821, 22 ) + + // Round 2 + STEP( G, a, b, c, d, GET(1), 0xf61e2562, 5 ) + STEP( G, d, a, b, c, GET(6), 0xc040b340, 9 ) + STEP( G, c, d, a, b, GET(11), 0x265e5a51, 14 ) + STEP( G, b, c, d, a, GET(0), 0xe9b6c7aa, 20 ) + STEP( G, a, b, c, d, GET(5), 0xd62f105d, 5 ) + STEP( G, d, a, b, c, GET(10), 0x02441453, 9 ) + STEP( G, c, d, a, b, GET(15), 0xd8a1e681, 14 ) + STEP( G, b, c, d, a, GET(4), 0xe7d3fbc8, 20 ) + STEP( G, a, b, c, d, GET(9), 0x21e1cde6, 5 ) + STEP( G, d, a, b, c, GET(14), 0xc33707d6, 9 ) + STEP( G, c, d, a, b, GET(3), 0xf4d50d87, 14 ) + STEP( G, b, c, d, a, GET(8), 0x455a14ed, 20 ) + STEP( G, a, b, c, d, GET(13), 0xa9e3e905, 5 ) + STEP( G, d, a, b, c, GET(2), 0xfcefa3f8, 9 ) + STEP( G, c, d, a, b, GET(7), 0x676f02d9, 14 ) + STEP( G, b, c, d, a, GET(12), 0x8d2a4c8a, 20 ) + + // Round 3 + STEP( H, a, b, c, d, GET(5), 0xfffa3942, 4 ) + STEP( H, d, a, b, c, GET(8), 0x8771f681, 11 ) + STEP( H, c, d, a, b, GET(11), 0x6d9d6122, 16 ) + STEP( H, b, c, d, a, GET(14), 0xfde5380c, 23 ) + STEP( H, a, b, c, d, GET(1), 0xa4beea44, 4 ) + STEP( H, d, a, b, c, GET(4), 0x4bdecfa9, 11 ) + STEP( H, c, d, a, b, GET(7), 0xf6bb4b60, 16 ) + STEP( H, b, c, d, a, GET(10), 0xbebfbc70, 23 ) + STEP( H, a, b, c, d, GET(13), 0x289b7ec6, 4 ) + STEP( H, d, a, b, c, GET(0), 0xeaa127fa, 11 ) + STEP( H, c, d, a, b, GET(3), 0xd4ef3085, 16 ) + STEP( H, b, c, d, a, GET(6), 0x04881d05, 23 ) + STEP( H, a, b, c, d, GET(9), 0xd9d4d039, 4 ) + STEP( H, d, a, b, c, GET(12), 0xe6db99e5, 11 ) + STEP( H, c, d, a, b, GET(15), 0x1fa27cf8, 16 ) + STEP( H, b, c, d, a, GET(2), 0xc4ac5665, 23 ) + + // Round 4 + STEP( I, a, b, c, d, GET(0), 0xf4292244, 6 ) + STEP( I, d, a, b, c, GET(7), 0x432aff97, 10 ) + STEP( I, c, d, a, b, GET(14), 0xab9423a7, 15 ) + STEP( I, b, c, d, a, GET(5), 0xfc93a039, 21 ) + STEP( I, a, b, c, d, GET(12), 0x655b59c3, 6 ) + STEP( I, d, a, b, c, GET(3), 0x8f0ccc92, 10 ) + STEP( I, c, d, a, b, GET(10), 0xffeff47d, 15 ) + STEP( I, b, c, d, a, GET(1), 0x85845dd1, 21 ) + STEP( I, a, b, c, d, GET(8), 0x6fa87e4f, 6 ) + STEP( I, d, a, b, c, GET(15), 0xfe2ce6e0, 10 ) + STEP( I, c, d, a, b, GET(6), 0xa3014314, 15 ) + STEP( I, b, c, d, a, GET(13), 0x4e0811a1, 21 ) + STEP( I, a, b, c, d, GET(4), 0xf7537e82, 6 ) + STEP( I, d, a, b, c, GET(11), 0xbd3af235, 10 ) + STEP( I, c, d, a, b, GET(2), 0x2ad7d2bb, 15 ) + STEP( I, b, c, d, a, GET(9), 0xeb86d391, 21 ) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while( size -= 64 ); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + + #undef GET + #undef SET + + return ptr; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// EXPORTED FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Initialise +// +// Initialises an MD5 Context. Use this to initialise/reset a context. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Initialise + ( + Md5Context* Context // [out] + ) +{ + Context->a = 0x67452301; + Context->b = 0xefcdab89; + Context->c = 0x98badcfe; + Context->d = 0x10325476; + + Context->lo = 0; + Context->hi = 0; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Update +// +// Adds data to the MD5 context. This will process the data and update the internal state of the context. Keep on +// calling this function until all the data has been added. Then call Md5Finalise to calculate the hash. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Update + ( + Md5Context* Context, // [in out] + void const* Buffer, // [in] + uint32_t BufferSize // [in] + ) +{ + uint32_t saved_lo; + uint32_t used; + uint32_t free; + + saved_lo = Context->lo; + if( (Context->lo = (saved_lo + BufferSize) & 0x1fffffff) < saved_lo ) + { + Context->hi++; + } + Context->hi += (uint32_t)( BufferSize >> 29 ); + + used = saved_lo & 0x3f; + + if( used ) + { + free = 64 - used; + + if( BufferSize < free ) + { + memcpy( &Context->buffer[used], Buffer, BufferSize ); + return; + } + + memcpy( &Context->buffer[used], Buffer, free ); + Buffer = (uint8_t*)Buffer + free; + BufferSize -= free; + TransformFunction(Context, Context->buffer, 64); + } + + if( BufferSize >= 64 ) + { + Buffer = TransformFunction( Context, Buffer, BufferSize & ~(unsigned long)0x3f ); + BufferSize &= 0x3f; + } + + memcpy( Context->buffer, Buffer, BufferSize ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Finalise +// +// Performs the final calculation of the hash and returns the digest (16 byte buffer containing 128bit hash). After +// calling this, Md5Initialised must be used to reuse the context. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Finalise + ( + Md5Context* Context, // [in out] + MD5_HASH* Digest // [in] + ) +{ + uint32_t used; + uint32_t free; + + used = Context->lo & 0x3f; + + Context->buffer[used++] = 0x80; + + free = 64 - used; + + if(free < 8) + { + memset( &Context->buffer[used], 0, free ); + TransformFunction( Context, Context->buffer, 64 ); + used = 0; + free = 64; + } + + memset( &Context->buffer[used], 0, free - 8 ); + + Context->lo <<= 3; + Context->buffer[56] = (uint8_t)( Context->lo ); + Context->buffer[57] = (uint8_t)( Context->lo >> 8 ); + Context->buffer[58] = (uint8_t)( Context->lo >> 16 ); + Context->buffer[59] = (uint8_t)( Context->lo >> 24 ); + Context->buffer[60] = (uint8_t)( Context->hi ); + Context->buffer[61] = (uint8_t)( Context->hi >> 8 ); + Context->buffer[62] = (uint8_t)( Context->hi >> 16 ); + Context->buffer[63] = (uint8_t)( Context->hi >> 24 ); + + TransformFunction( Context, Context->buffer, 64 ); + + Digest->bytes[0] = (uint8_t)( Context->a ); + Digest->bytes[1] = (uint8_t)( Context->a >> 8 ); + Digest->bytes[2] = (uint8_t)( Context->a >> 16 ); + Digest->bytes[3] = (uint8_t)( Context->a >> 24 ); + Digest->bytes[4] = (uint8_t)( Context->b ); + Digest->bytes[5] = (uint8_t)( Context->b >> 8 ); + Digest->bytes[6] = (uint8_t)( Context->b >> 16 ); + Digest->bytes[7] = (uint8_t)( Context->b >> 24 ); + Digest->bytes[8] = (uint8_t)( Context->c ); + Digest->bytes[9] = (uint8_t)( Context->c >> 8 ); + Digest->bytes[10] = (uint8_t)( Context->c >> 16 ); + Digest->bytes[11] = (uint8_t)( Context->c >> 24 ); + Digest->bytes[12] = (uint8_t)( Context->d ); + Digest->bytes[13] = (uint8_t)( Context->d >> 8 ); + Digest->bytes[14] = (uint8_t)( Context->d >> 16 ); + Digest->bytes[15] = (uint8_t)( Context->d >> 24 ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Calculate +// +// Combines Md5Initialise, Md5Update, and Md5Finalise into one function. Calculates the MD5 hash of the buffer. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Calculate + ( + void const* Buffer, // [in] + uint32_t BufferSize, // [in] + MD5_HASH* Digest // [in] + ) +{ + Md5Context context; + + Md5Initialise( &context ); + Md5Update( &context, Buffer, BufferSize ); + Md5Finalise( &context, Digest ); +} diff --git a/src/md5.h b/src/md5.h new file mode 100755 index 000000000..5ef252221 --- /dev/null +++ b/src/md5.h @@ -0,0 +1,100 @@ +/* + * Retrieved from https://github.com/WaterJuice/WjCryptLib + */ + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// WjCryptLib_Md5 +// +// Implementation of MD5 hash function. Originally written by Alexander Peslyak. Modified by WaterJuice retaining +// Public Domain license. +// +// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TYPES +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Md5Context - This must be initialised using Md5Initialised. Do not modify the contents of this structure directly. +typedef struct +{ + uint32_t lo; + uint32_t hi; + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; + uint8_t buffer[64]; + uint32_t block[16]; +} Md5Context; + +#define MD5_HASH_SIZE ( 128 / 8 ) + +typedef struct +{ + uint8_t bytes [MD5_HASH_SIZE]; +} MD5_HASH; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PUBLIC FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Initialise +// +// Initialises an MD5 Context. Use this to initialise/reset a context. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Initialise + ( + Md5Context* Context // [out] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Update +// +// Adds data to the MD5 context. This will process the data and update the internal state of the context. Keep on +// calling this function until all the data has been added. Then call Md5Finalise to calculate the hash. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Update + ( + Md5Context* Context, // [in out] + void const* Buffer, // [in] + uint32_t BufferSize // [in] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Finalise +// +// Performs the final calculation of the hash and returns the digest (16 byte buffer containing 128bit hash). After +// calling this, Md5Initialised must be used to reuse the context. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Finalise + ( + Md5Context* Context, // [in out] + MD5_HASH* Digest // [in] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Md5Calculate +// +// Combines Md5Initialise, Md5Update, and Md5Finalise into one function. Calculates the MD5 hash of the buffer. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + Md5Calculate + ( + void const* Buffer, // [in] + uint32_t BufferSize, // [in] + MD5_HASH* Digest // [in] + ); From 42c5fd7e69ae7205befb37fac8868b1fd5965ad7 Mon Sep 17 00:00:00 2001 From: Simon Derr Date: Mon, 13 Apr 2020 10:46:56 +0200 Subject: [PATCH 0813/1435] st-flash: minor usage fix, and make cmdline parsing more user friendly Somewhat fix the help message that showed some parameters as mandatory, when in reality they depend on the operation type and file format. Try to show explicit error messages for the most common mistakes. --- src/tools/flash.c | 2 +- src/tools/flash_opts.c | 27 ++++++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/tools/flash.c b/src/tools/flash.c index 67e03c62b..b9cc86d45 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -31,7 +31,7 @@ static void usage(void) { puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--opt] [--format ] [--flash=] {read|write} /dev/sgX "); puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); - puts("stlinkv2/3 command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] {read|write} "); + puts("stlinkv2/3 command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] {read|write} [addr] [size]"); puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] erase"); puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] reset"); puts(" , and : Use hex format."); diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index a24bde1be..261d8b524 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -11,6 +11,18 @@ static bool starts_with(const char * str, const char * prefix) { return (0 == strncmp(str, prefix, n)); } +static int invalid_args(const char *expected) +{ + fprintf(stderr, "*** Error: Expected args for this command: %s\n", expected); + return -1; +} + +static int bad_arg(const char *arg) +{ + fprintf(stderr, "*** Error: Invalid value for %s\n", arg); + return -1; +} + int flash_get_opts(struct flash_opts* o, int ac, char** av) { bool serial_specified = false; @@ -94,7 +106,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { else if (strcmp(format, "ihex") == 0) o->format = FLASH_FORMAT_IHEX; else - return -1; + return bad_arg("format"); } else if ( starts_with(av[0], "--flash=") ) { const char *arg = av[0] + strlen("--flash="); @@ -168,12 +180,13 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { case FLASH_CMD_READ: // expect filename, addr and size if((o->area == FLASH_OPTION_BYTES) &&(ac == 0)) break; + if (ac != 3) return invalid_args("read "); if (ac != 3) return -1; o->filename = av[0]; o->addr = (uint32_t) strtoul(av[1], &tail, 16); - if(tail[0] != '\0') return -1; + if(tail[0] != '\0') return bad_arg("addr"); o->size = strtoul(av[2], &tail, 16); - if(tail[0] != '\0') return -1; + if(tail[0] != '\0') return bad_arg("size"); break; case FLASH_CMD_WRITE: @@ -182,17 +195,17 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { o->val = (uint32_t)strtoul(av[0], &tail, 16); } else if(o->format == FLASH_FORMAT_BINARY) { // expect filename and addr - if (ac != 2) return -1; + if (ac != 2) return invalid_args("write "); o->filename = av[0]; o->addr = (uint32_t) strtoul(av[1], &tail, 16); - if(tail[0] != '\0') return -1; + if(tail[0] != '\0') return bad_arg("addr"); } else if(o->format == FLASH_FORMAT_IHEX) { // expect filename - if (ac != 1) return -1; + if (ac != 1) return invalid_args("write "); o->filename = av[0]; } else { - return -1; + return -1; // should have been caught during format parsing } break; From eb243044338b9a1f312a92b7dbc5c2b61fc0360a Mon Sep 17 00:00:00 2001 From: Simon Derr Date: Mon, 13 Apr 2020 11:55:39 +0200 Subject: [PATCH 0814/1435] src/tools/flash_opts.c: fix style issues --- src/tools/flash_opts.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 261d8b524..5f6417bac 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -11,16 +11,14 @@ static bool starts_with(const char * str, const char * prefix) { return (0 == strncmp(str, prefix, n)); } -static int invalid_args(const char *expected) -{ - fprintf(stderr, "*** Error: Expected args for this command: %s\n", expected); - return -1; +static int invalid_args(const char *expected) { + fprintf(stderr, "*** Error: Expected args for this command: %s\n", expected); + return -1; } -static int bad_arg(const char *arg) -{ - fprintf(stderr, "*** Error: Invalid value for %s\n", arg); - return -1; +static int bad_arg(const char *arg) { + fprintf(stderr, "*** Error: Invalid value for %s\n", arg); + return -1; } int flash_get_opts(struct flash_opts* o, int ac, char** av) { From 35cbe57f4f6c2e2052b32c4c2431a578c6344a10 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Mon, 13 Apr 2020 18:30:44 +0800 Subject: [PATCH 0815/1435] Add st official checksum for binary file --- src/common.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/common.c b/src/common.c index 43cec756d..d3944eec5 100644 --- a/src/common.c +++ b/src/common.c @@ -1380,6 +1380,16 @@ static void md5_calculate(mapped_file_t *mf, const char *path) { printf("\n"); } +static void stlink_checksum(mapped_file_t *mp, const char* path) { + /* checksum that backward compatible with official ST tools */ + uint32_t sum = 0; + uint8_t *mp_byte = (uint8_t *)mp->base; + for (size_t i = 0; i < mp->len; ++i) { + sum += mp_byte[i]; + } + printf("file %s stlink checksum: 0x%08x\n", path, sum); +} + static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { unsigned int val; /* set stack*/ @@ -1462,6 +1472,7 @@ int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { } md5_calculate(&mf, path); + stlink_checksum(&mf, path); /* check addr range is inside the sram */ if (addr < sl->sram_base) { @@ -2688,6 +2699,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { } md5_calculate(&mf, path); + stlink_checksum(&mf, path); if (sl->opt) { idx = (unsigned int) mf.len; @@ -3254,6 +3266,7 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr } md5_calculate(&mf, path); + stlink_checksum(&mf, path); err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t) mf.len); stlink_fwrite_finalize(sl, addr); From 6eb9103a235dcf24c86e39553f807a987b533aa0 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 13 Apr 2020 15:02:43 +0200 Subject: [PATCH 0816/1435] Updated build-settings - Added new build configs for Travis - Refactoring for cmake modules - Updated Travis build script - Makefile: binary build for Windows --- .travis.sh | 38 ++++++-- .travis.yml | 8 ++ Makefile | 14 ++- cmake/modules/FindLibUSB.cmake | 155 ++++++++++++++++++--------------- cmake/version.cmake | 61 +++++++------ 5 files changed, 176 insertions(+), 100 deletions(-) diff --git a/.travis.sh b/.travis.sh index 05568d37d..3d6da055f 100755 --- a/.travis.sh +++ b/.travis.sh @@ -5,15 +5,43 @@ ls -1 /usr/bin/clang* ls -1 /usr/bin/scan-build* echo "----" +echo "WORK DIR:$DIR" +DIR=$PWD + if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq || true sudo apt-get install -qq -y --no-install-recommends libgtk-3-dev + + echo "--> Building Debug..." + mkdir -p build/Debug && cd build/Debug + echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install" + cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ + make && make package && cd - + + echo "--> Building Release..." + mkdir -p build/Release && cd build/Release + echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install" + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ + make && make package && cd - + + echo "--> Building Binary..." + mkdir -p build/Binary && cd build/Binary + cho "-DCMAKE_BUILD_TYPE=Binary -DCMAKE_INSTALL_PREFIX=$PWD/_install" + cmake -DCMAKE_BUILD_TYPE=Binary -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ + make && make package && cd - + else #("$TRAVIS_OS_NAME" == "osx") brew install libusb -fi -echo "=== Building Debug" -mkdir -p build/Debug && cd build/Debug && cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ && make && make package && cd - + echo "--> Building Debug..." + mkdir -p build/Debug && cd build/Debug + echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install" + cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ + make && make package && cd - -echo "=== Building Release" -mkdir -p build/Release && cd build/Release && cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ && make && make package && cd - + echo "--> Building Release..." + mkdir -p build/Release && cd build/Release + echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install" + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ + make && make package && cd - +fi diff --git a/.travis.yml b/.travis.yml index 079888765..221e8ece7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,6 +38,14 @@ matrix: apt: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] packages: ['clang-6.0', 'libusb-1.0.0-dev'] + - os: linux + arch: x64 + compiler: clang-6.0 + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] + packages: ['clang-6.0', 'libusb-1.0.0-dev'] + env: CFLAGS=-m32 LDFLAGS=-m32 ### 32-bit builds ### - os: linux diff --git a/Makefile b/Makefile index 0636eb9bd..6b44bd70c 100644 --- a/Makefile +++ b/Makefile @@ -4,11 +4,12 @@ MAKEFLAGS += -s all: release -ci: debug release test +ci: debug release binary test help: - @echo " release: Run a release build" @echo " debug: Run a debug build" + @echo " release: Run a release build" + @echo " binary: Build Windows-Binary" @echo " lint: Lint check all source-code" @echo " test: Build and run tests" @echo " clean: Clean all build output" @@ -17,6 +18,7 @@ help: rebuild_cache: build/Debug build/Release @$(MAKE) -C build/Debug rebuild_cache @$(MAKE) -C build/Release rebuild_cache + @$(MAKE) -C build/Binary rebuild_cache debug: build/Debug @echo "[DEBUG]" @@ -26,6 +28,10 @@ release: build/Release @echo "[RELEASE]" @$(MAKE) -C build/Release +binary: build/Binary + @echo "[BINARY]" + @$(MAKE) -C build/Binary + package: build/Release @echo "[PACKAGE] Release" @$(MAKE) -C build/Release package @@ -41,6 +47,10 @@ build/Release: @mkdir -p $@ @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) ../../ +build/Binary: + @mkdir -p $@ + @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Binary $(CMAKEFLAGS) ../../ + clean: @echo "[CLEAN]" @rm -Rf build diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index dc90bcc32..b583b8491 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -1,102 +1,90 @@ # FindLibUSB.cmake # Once done this will define # -# LIBUSB_FOUND - System has libusb -# LIBUSB_INCLUDE_DIR - The libusb include directory -# LIBUSB_LIBRARY - The libraries needed to use libusb -# LIBUSB_DEFINITIONS - Compiler switches required for using libusb +# LIBUSB_FOUND libusb present on system +# LIBUSB_INCLUDE_DIR the libusb include directory +# LIBUSB_LIBRARY the libraries needed to use libusb +# LIBUSB_DEFINITIONS compiler switches required for using libusb -if (NOT (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")) # all OS apart from FreeBSD +include(FindPackageHandleStandardArgs) + +if (APPLE) # macOS FIND_PATH( LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr /usr/local /opt PATH_SUFFIXES libusb-1.0 ) -endif () - -if (APPLE) # macOS set(LIBUSB_NAME libusb-1.0.a) find_library( LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS /usr /usr/local /opt ) - -elseif (MINGW OR MSYS) # Windows with MinGW or MSYS - set(LIBUSB_NAME usb-1.0) - - if (CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/static - NO_DEFAULT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) - else () # 32-bit - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW32/static - NO_DEFAULT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) + if (NOT LIBUSB_FOUND) + message(FATAL_ERROR "No libusb library found on your system! Install libusb-1.0 from Homebrew or MacPorts") endif () -elseif (MSVC) # Windows with MSVC - set(LIBUSB_NAME libusb-1.0.lib) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll - NO_DEFAULT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) - else () # 32-bit - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll - NO_DEFAULT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) - endif () - -elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD - # libusb is integrated into FreeBSD +elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated into the system FIND_PATH( LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr/include ) - set(LIBUSB_NAME usb) find_library( LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS /usr /usr/local /opt ) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) + if (NOT LIBUSB_FOUND) + message(FATAL_ERROR "Expected libusb library not found on your system! Verify your system integrity.") + endif () -else () # all other OS - set(LIBUSB_NAME usb-1.0) - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS /usr /usr/local /opt - ) -endif() +elseif (WIN32 OR (EXISTS "/etc/debian_version" AND ${CMAKE_BUILD_TYPE} MATCHES "Binary")) + # Windows & Windows-Binary-Build on Debian/Ubuntu -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) -mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) + # for MinGW/MSYS/MSVC: 64-bit or 32-bit? + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(ARCH 64) + else () + set(ARCH 32) + endif () -if (NOT LIBUSB_FOUND) - if (WIN32 OR MINGW OR MSYS OR MSVC) # Windows + if (NOT EXISTS "/etc/debian_version") + FIND_PATH( + LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS /usr /usr/local /opt + PATH_SUFFIXES libusb-1.0 + ) + if (MINGW OR MSYS) + set(LIBUSB_NAME usb-1.0) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW${ARCH}/static + ) + else (MSVC) + set(LIBUSB_NAME libusb-1.0.lib) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS${ARCH}/dll + ) + endif () + endif () + + if (NOT LIBUSB_FOUND OR EXISTS "/etc/debian_version") # Preparations for installing libusb library find_package(7Zip REQUIRED) - set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version to 1.0.23 (latest as of Apr 2020) + set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3rdparty/libusb-${LIBUSB_WIN_VERSION}) # Get libusb package - if (EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) # ... should the package be already there (for whatever reason) + if (EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) # ... should the package be already there (for whatever reason) message(STATUS "libusb archive already in build folder") - else () # ... download the package (1.0.23 as of Apr 2020) + else () # ... download the package message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download @@ -127,11 +115,42 @@ if (NOT LIBUSB_FOUND) NO_CMAKE_FIND_ROOT_PATH ) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) - message(STATUS "installed libusb library") - else () # all other OS - message(FATAL_ERROR "libusb library not found on your system! Compilation terminated.") + if (MINGW OR MSYS) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW${ARCH}/static + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) + + else (MSVC) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS${ARCH}/dll + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) + endif () + message(STATUS "Missing libusb library has been installed") + endif () + FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) + +else () # all other OS (unix-based) + FIND_PATH( + LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS /usr /usr/local /opt + PATH_SUFFIXES libusb-1.0 + ) + set(LIBUSB_NAME usb-1.0) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS /usr /usr/local /opt + ) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) + + if (NOT LIBUSB_FOUND) + message(FATAL_ERROR "libusb library not found on your system! Install libusb 1.0.x from your package repository.") endif () -else (NOT LIBUSB_FOUND) - message(STATUS "found libusb library") endif () diff --git a/cmake/version.cmake b/cmake/version.cmake index fe778c419..38254409f 100644 --- a/cmake/version.cmake +++ b/cmake/version.cmake @@ -5,9 +5,11 @@ set(__detect_version 0) find_package(Git) +set(ERROR_FLAG "0") if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") # Working off a git repo, using git versioning + # Check if HEAD is pointing to a tag execute_process ( COMMAND "${GIT_EXECUTABLE}" describe --always --tag @@ -17,22 +19,22 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") ERROR_VARIABLE GIT_DESCRIBE_ERROR OUTPUT_STRIP_TRAILING_WHITESPACE ) - if (GIT_DESCRIBE_RESULT EQUAL 0) + # If the sources have been changed locally, add -dirty to the version. execute_process ( COMMAND "${GIT_EXECUTABLE}" diff --quiet WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" RESULT_VARIABLE res ) - if (res EQUAL 1) - set (PROJECT_VERSION "${PROJECT_VERSION}-dirty") + set(PROJECT_VERSION "${PROJECT_VERSION}-dirty") endif () - # strip a leading v off of the version as proceeding code expectes just the version numbering. + # Strip a leading v off of the version as proceeding code expects just the version numbering. string(REGEX REPLACE "^v" "" PROJECT_VERSION ${PROJECT_VERSION}) + # Read version string string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) list(LENGTH PROJECT_VERSION_LIST len) @@ -42,34 +44,46 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") list(GET PROJECT_VERSION_LIST 2 PROJECT_VERSION_PATCH) set(__detect_version 1) set(__version_str "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") + + # Compare git-Version with version read from .version file in source folder if (EXISTS "${PROJECT_SOURCE_DIR}/.version") + + # Local .version file found, read version string... file(READ "${PROJECT_SOURCE_DIR}/.version" __version_file) + + # ...the version does not match with git-version string if (NOT __version_str STREQUAL __version_file) - message(STATUS "Rewrite ${PROJECT_SOURCE_DIR}/.version with ${__version_str}") + message(STATUS "Rewrite ${PROJECT_SOURCE_DIR}/.version with ${__version_str}.") endif () - else () + + else (EXISTS "${PROJECT_SOURCE_DIR}/.version") + + # No local .version file found: Create a new one... file(WRITE "${PROJECT_SOURCE_DIR}/.version" ${__version_str}) + endif () - else () - message(STATUS "Fail to extract version parts from \"${PROJECT_VERSION}\"") - endif () - else(GIT_DESCRIBE_RESULT EQUAL 0) - message(WARNING "git describe failed.") - message(WARNING "${GIT_DESCRIBE_ERROR}") + message(STATUS "stlink version: ${PROJECT_VERSION}") + message(STATUS "Major ${PROJECT_VERSION_MAJOR} Minor ${PROJECT_VERSION_MINOR} Patch ${PROJECT_VERSION_PATCH}") + + else (len EQUAL 3) + message(STATUS "Failed to extract version parts from \"${PROJECT_VERSION}\"") + set(ERROR_FLAG "1") + endif (len EQUAL 3) + + else (GIT_DESCRIBE_RESULT EQUAL 0) + message(WARNING "git describe failed: ${GIT_DESCRIBE_ERROR}") + set(ERROR_FLAG "1") endif(GIT_DESCRIBE_RESULT EQUAL 0) -else () - message(STATUS "Git or repo not found.") endif () -if (NOT __detect_version) - message(STATUS "Try to detect version from \"${PROJECT_SOURCE_DIR}/.version\" file.") +if (ERROR_FLAG EQUAL 1) + message(STATUS "Git and/or repository not found.") # e.g. when building from source package + message(STATUS "Try to detect version from \"${PROJECT_SOURCE_DIR}/.version\" file instead...") if (EXISTS ${PROJECT_SOURCE_DIR}/.version) - # If git is not available (e.g. when building from source package) - # we can extract the package version from .version file. file(STRINGS .version PROJECT_VERSION) - # TODO create function to extract semver from file or string and check if it is correct instead of copy-pasting + # Read version string string(REGEX REPLACE "^(0|[1-9][0-9]*)[.](0|[1-9][0-9]*)[.](0|[1-9][0-9]*)(-[.0-9A-Za-z-]+)?([+][.0-9A-Za-z-]+)?$" "\\1;\\2;\\3" PROJECT_VERSION_LIST ${PROJECT_VERSION}) list(LENGTH PROJECT_VERSION_LIST len) @@ -81,11 +95,8 @@ if (NOT __detect_version) else () message(STATUS "Fail to extract version parts from \"${PROJECT_VERSION}\"") endif () - else () - message(STATUS "File \"${PROJECT_SOURCE_DIR}/.version\" did not exists.") + else (EXISTS ${PROJECT_SOURCE_DIR}/.version) + message(STATUS "File \"${PROJECT_SOURCE_DIR}/.version\" does not exist.") + message(FATAL_ERROR "Unable to determine project version") endif () - message(FATAL_ERROR "Unable to determine project version") endif () - -message(STATUS "stlink version: ${PROJECT_VERSION}") -message(STATUS "Major ${PROJECT_VERSION_MAJOR} Minor ${PROJECT_VERSION_MINOR} Patch ${PROJECT_VERSION_PATCH}") From 6515e57b9ea4db69de3f66ba8db709163ab22456 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Mon, 13 Apr 2020 21:20:20 +0800 Subject: [PATCH 0817/1435] Adjust output format for better formating --- src/common.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/common.c b/src/common.c index d3944eec5..e719c6031 100644 --- a/src/common.c +++ b/src/common.c @@ -1373,11 +1373,11 @@ static void md5_calculate(mapped_file_t *mf, const char *path) { Md5Initialise(&md5Context); Md5Update(&md5Context, mf->base, (uint32_t)mf->len); Md5Finalise(&md5Context, &md5Hash); - printf("file %s md5 checksum: ",path); + printf("md5 checksum: "); for(int i = 0; i < (int) sizeof(md5Hash); i++) { printf("%x", md5Hash.bytes[i]); } - printf("\n"); + printf(", "); } static void stlink_checksum(mapped_file_t *mp, const char* path) { @@ -1387,7 +1387,7 @@ static void stlink_checksum(mapped_file_t *mp, const char* path) { for (size_t i = 0; i < mp->len; ++i) { sum += mp_byte[i]; } - printf("file %s stlink checksum: 0x%08x\n", path, sum); + printf("stlink checksum: 0x%08x\n", sum); } static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { @@ -1470,7 +1470,7 @@ int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { fprintf(stderr, "map_file() == -1\n"); return -1; } - + printf("file %s "); md5_calculate(&mf, path); stlink_checksum(&mf, path); @@ -2698,6 +2698,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { return -1; } + printf("file %s "); md5_calculate(&mf, path); stlink_checksum(&mf, path); @@ -3265,6 +3266,7 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr return -1; } + printf("file %s "); md5_calculate(&mf, path); stlink_checksum(&mf, path); From 1047fdd44063d26e25974704ef23ef9ee8595e3e Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Mon, 13 Apr 2020 21:26:16 +0800 Subject: [PATCH 0818/1435] Add documentation about the checksum --- doc/tutorial.md | 5 +++++ src/common.c | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 66bed0382..f19a6ecd9 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -539,6 +539,11 @@ want to disassemble the code at 0x20000000, use:\ (gdb) disassemble 0x20000001 ``` +Checksum of binary file +----------------------- + +When flashing a file, the checksum of which is calculated, both in md5 and the sum algorithm used by ST's official tool. The detail of sum algorithm can be found in [https://www.st.com/resource/en/user_manual/cd00262073-stm32-stlink-utility-software-description-stmicroelectronics.pdf](https://www.st.com/resource/en/user_manual/cd00262073-stm32-stlink-utility-software-description-stmicroelectronics.pdf). + References ========== diff --git a/src/common.c b/src/common.c index e719c6031..d04644071 100644 --- a/src/common.c +++ b/src/common.c @@ -1366,7 +1366,7 @@ static int check_file(stlink_t* sl, mapped_file_t* mf, stm32_addr_t addr) { return 0; } -static void md5_calculate(mapped_file_t *mf, const char *path) { +static void md5_calculate(mapped_file_t *mf) { /* calculate md5 checksum of given binary file */ Md5Context md5Context; MD5_HASH md5Hash; @@ -1380,7 +1380,7 @@ static void md5_calculate(mapped_file_t *mf, const char *path) { printf(", "); } -static void stlink_checksum(mapped_file_t *mp, const char* path) { +static void stlink_checksum(mapped_file_t *mp) { /* checksum that backward compatible with official ST tools */ uint32_t sum = 0; uint8_t *mp_byte = (uint8_t *)mp->base; @@ -1470,9 +1470,9 @@ int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { fprintf(stderr, "map_file() == -1\n"); return -1; } - printf("file %s "); - md5_calculate(&mf, path); - stlink_checksum(&mf, path); + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); /* check addr range is inside the sram */ if (addr < sl->sram_base) { @@ -2698,9 +2698,9 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { return -1; } - printf("file %s "); - md5_calculate(&mf, path); - stlink_checksum(&mf, path); + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); if (sl->opt) { idx = (unsigned int) mf.len; @@ -3266,9 +3266,9 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr return -1; } - printf("file %s "); - md5_calculate(&mf, path); - stlink_checksum(&mf, path); + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t) mf.len); stlink_fwrite_finalize(sl, addr); From fc507fd4842cd9b4719378d0ee79a6a123eecae3 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Sun, 12 Apr 2020 15:58:17 +0200 Subject: [PATCH 0819/1435] flash.c: stlink_open_usb is actually able to open v1 and v2 (and v3 ..) devices. no need to check that _not used_ o.devname .. no need to specify devname in commandline get rid of the devname cmdline stuff, and update comments --- src/tools/flash.c | 13 ++++--------- src/tools/flash_opts.c | 11 +---------- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/tools/flash.c b/src/tools/flash.c index b9cc86d45..f703bc813 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -29,11 +29,9 @@ static void cleanup(int signum) { static void usage(void) { - puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--opt] [--format ] [--flash=] {read|write} /dev/sgX "); - puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); - puts("stlinkv2/3 command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] {read|write} [addr] [size]"); - puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] erase"); - puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] reset"); + puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] {read|write} [addr] [size]"); + puts("command line: ./st-flash [--debug] [--serial ] erase"); + puts("command line: ./st-flash [--debug] [--serial ] reset"); puts(" , and : Use hex format."); puts(" : Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); puts(" : Can be 'binary' (default) or 'ihex', although must be specified for binary format only."); @@ -59,10 +57,7 @@ int main(int ac, char** av) printf("st-flash %s\n", STLINK_VERSION); - if (o.devname != NULL) /* stlinkv1 */ - sl = stlink_v1_open(o.log_level, 1); - else /* stlinkv2 */ - sl = stlink_open_usb(o.log_level, 1, (char *)o.serial); + sl = stlink_open_usb(o.log_level, 1, (char *)o.serial); if (sl == NULL) return -1; diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 5f6417bac..c139977ce 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -22,7 +22,6 @@ static int bad_arg(const char *arg) { } int flash_get_opts(struct flash_opts* o, int ac, char** av) { - bool serial_specified = false; // defaults memset(o, 0, sizeof(*o)); @@ -63,7 +62,6 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { memcpy(buffer, serial + j, 2); o->serial[length - k] = (uint8_t)strtol(buffer, NULL, 16); } - serial_specified = true; } else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { const char * area; @@ -138,7 +136,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } // command and (optional) device name - while(ac >= 1) { // looks like for stlinkv1 the device name and command may be swaped - check both positions in all cases + while(ac >= 1) { if (strcmp(av[0], "erase") == 0) { if (o->cmd != FLASH_CMD_NONE) return -1; o->cmd = FLASH_CMD_ERASE; @@ -155,10 +153,6 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { if (o->cmd != FLASH_CMD_NONE) return -1; o->cmd = CMD_RESET; } - else if(starts_with(av[0], "/dev/")) { - if (o->devname) return -1; - o->devname = av[0]; - } else { break; } @@ -210,8 +204,5 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { default: break ; } - // some constistence checks - if(serial_specified && o->devname != NULL) return -1; // serial not supported for v1 - return 0; } From 308fccb04875c51dcfcf0730872ca0de37929bc8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 14 Apr 2020 21:01:52 +0200 Subject: [PATCH 0820/1435] General Project Update - Updated CHANGELOG.md - Updated links to project repository - Improved project description - Minor revision for tutorial.md - Formatting fixes --- CHANGELOG.md | 6 +-- README.md | 37 ++++++++----- doc/compiling.md | 6 +-- doc/tutorial.md | 133 +++++++++++++---------------------------------- 4 files changed, 67 insertions(+), 115 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e31aaf47..99d307f9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -173,7 +173,7 @@ Release date: 2017-01-28 Major changes and added features: * Deprecation of autotools (autoconf, automake) and fixed build with MinGW ([#83](https://github.com/texane/stlink/pull/83), [#431](https://github.com/texane/stlink/pull/431), [#434](https://github.com/texane/stlink/pull/434), [#465](https://github.com/texane/stlink/pull/465)) -* Added intel hex file reading for `st-flash` ([#110](https://github.com/texane/stlink/pull/110), [#157](https://github.com/texane/stlink/pull/157), [#200](https://github.com/texane/stlink/pull/200), [#239](https://github.com/texane/stlink/pull/239), [#457](https://github.com/texane/stlink/pull/547), [#459](https://github.com/texane/stlink/pull/549)) +* Added intel hex file reading for `st-flash` ([#110](https://github.com/texane/stlink/pull/110), [#157](https://github.com/texane/stlink/pull/157), [#457](https://github.com/texane/stlink/pull/547), [#459](https://github.com/texane/stlink/pull/549)) * Added support for ARM semihosting to `st-util` ([#147](https://github.com/texane/stlink/pull/147), [#227](https://github.com/texane/stlink/pull/227), [#454](https://github.com/texane/stlink/pull/454), [#455](https://github.com/texane/stlink/pull/455)) * Added manpages (generated with pandoc from Markdown) ([#208](https://github.com/texane/stlink/pull/208), [#464](https://github.com/texane/stlink/pull/464), [#466](https://github.com/texane/stlink/pull/466), [#467](https://github.com/texane/stlink/pull/467)) * Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#228](https://github.com/texane/stlink/pull/228), ([#507](https://github.com/texane/stlink/pull/507), commit [#3fd0f09](https://github.com/texane/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) @@ -190,7 +190,7 @@ Chip support added for: * STM32F410RBTx ([#418](https://github.com/texane/stlink/pull/418)) * STM32F412 ([#537](https://github.com/texane/stlink/pull/537), [#538](https://github.com/texane/stlink/pull/538)) * STM32F7xx ([#324](https://github.com/texane/stlink/pull/324), [#326](https://github.com/texane/stlink/pull/326), [#327](https://github.com/texane/stlink/pull/327), [#337](https://github.com/texane/stlink/pull/337)) -* STM32F767ZI ([#509](https://github.com/texane/stlink/pull/509)) +* STM32F7x7x ([#433](https://github.com/texane/stlink/pull/433), [#435](https://github.com/texane/stlink/pull/435), [#436](https://github.com/texane/stlink/pull/436), [#509](https://github.com/texane/stlink/pull/509)) * STM32L0xx Cat2 devices (chip-ID: 0x425) ([#414](https://github.com/texane/stlink/pull/414)) * STM32L0xx Cat5 devices (chip-ID: 0x447) ([#387](https://github.com/texane/stlink/pull/387), [#406](https://github.com/texane/stlink/pull/406)) * STM32L4xx ([#321](https://github.com/texane/stlink/pull/321)) @@ -207,7 +207,7 @@ Updates and fixes: * Fixed STM32F030 erase error ([#442](https://github.com/texane/stlink/pull/442)) * Fixed memory map for STM32F7xx ([#453](https://github.com/texane/stlink/pull/453), [#456](https://github.com/texane/stlink/pull/456)) * Redesign of `st-flash` commandline options parsing ([#459](https://github.com/texane/stlink/pull/459)) -* Set SWDCLK and fixed jtag_reset bug ([#475](https://github.com/texane/stlink/pull/475), [#534](https://github.com/texane/stlink/pull/534)) +* Set SWDCLK and fixed jtag_reset bug ([#462](https://github.com/texane/stlink/pull/462), [#475](https://github.com/texane/stlink/pull/475), [#534](https://github.com/texane/stlink/pull/534)) * doc/compiling.md: Add note about installation and ldconfig ([#478](https://github.com/texane/stlink/pull/478), commit [#be66bbf](https://github.com/texane/stlink/commit/be66bbf200c718904514b044ba84d64a36456218)) * Fixed Release target to generate the man-pages with pandoc ([#479](https://github.com/texane/stlink/pull/479)) * Fixed Cygwin build ([#487](https://github.com/texane/stlink/pull/487), ([#506](https://github.com/texane/stlink/pull/506)) diff --git a/README.md b/README.md index 29d1ef766..b2ff03d54 100644 --- a/README.md +++ b/README.md @@ -20,21 +20,32 @@ are licensed under the **General Public License (GPL v2+)**. ## Introduction -This stlink toolset supports several so called stlink programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG. +STLink is an open source toolset to program and debug STM32 devices and boards manufactured by STMicroelectronics. +It supports several so called STLINK programmer boards (and clones thereof) which use a microcontroller chip +to translate commands from USB to JTAG/SWD. There are four generations available on the market: -These programmer boards are available in four versions: - -* **STLINKv1:** +* **STLINK/v1** _(obsolete as of 21-11-2019)_ - transport layer: SCSI passthru commands over USB - - present on STM32VL discovery kits -* **STLINKv2:** - * transport layer: raw USB commands - * present on STM32L discovery and nucleo and later kits -* **STLINKv2-1:** - * transport layer: raw USB commands - * present on some STM32 nucleo boards -* **STLINKv3:** - * _not yet supported by this toolset (but planned)_ + - stand-alone programmer and present on STM32VL Discovery boards +* **STLINK/v2** + - transport layer: raw USB commands + - stand-alone programmer and present on STM32L Discovery and Nucleo boards +* **STLINK/v2-1** + - transport layer: raw USB commands + - present on some STM32 Nucleo boards +* **STLINK/v3** + - transport layer: raw USB commands + - stand-alone programmer + +On the user level there is no difference in handling or operation between these different revisions. + +The STlink toolset includes: + +* a communication library (libstlink.a), +* a programmer and chip information tool (st-info), +* a flash manipulation tool (st-flash), +* a GDB server (st-util) and +* a GUI-Interface (stlink-gui) _[optional]_ ## Supported hardware combinations diff --git a/doc/compiling.md b/doc/compiling.md index 64f4de466..59685ef17 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -23,7 +23,7 @@ On Windows users should ensure that the following software is installed: development) 5. Create a new destination folder at a place of your choice 6. Open the command-line (cmd.exe) and execute `cd C:\$Path-to-your-destination-folder$\` -7. Fetch the project sourcefiles by running `git clone https://github.com/texane/stlink.git`from the command-line (cmd.exe)
    +7. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git`from the command-line (cmd.exe)
    or download the stlink zip-sourcefolder from the Release page on GitHub @@ -76,7 +76,7 @@ or execute (Debian-based systems only): `apt-get install gcc build-essential cma 1. Open a new terminal console 2. Create a new destination folder at a place of your choice e.g. at `~/git`: `mkdir $HOME/git` 3. Change to this directory: `cd ~/git` -4. Fetch the project sourcefiles by running `git clone https://github.com/texane/stlink.git` +4. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git` ### Building @@ -183,7 +183,7 @@ Additionally we recommend to install Xcode which delivers the necessary C-compil 1. Open a new terminal window 2. Create a new destination folder at a place of your choice e.g. at `~/git`: `mkdir $HOME/git` 3. Change to this directory: `cd ~/git` -4. Fetch the project sourcefiles by running `git clone https://github.com/texane/stlink.git` +4. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git` ### Building diff --git a/doc/tutorial.md b/doc/tutorial.md index f19a6ecd9..75e03f1bc 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -14,12 +14,17 @@ This option accepts decimal (128k), octal 0200k, or hex 0x80k. Obviously leaving the multiplier out is equally valid, for example: `--flash=0x20000`. The size may be followed by an optional "k" or "m" to multiply the given value by 1k (1024) or 1M respectively. +#### Checksum for binary files + +When flashing a file, a checksum is calculated for the binary file, both in md5 and the sum algorithm. +The latter is also used by the official ST-Link utility tool from STMicroelectronics as described in the document: [`UM0892 - User manual - STM32 ST-LINK utility software description`](https://www.st.com/resource/en/user_manual/cd00262073-stm32-stlink-utility-software-description-stmicroelectronics.pdf). + ## Solutions to common problems -### a) ST-Link-v1 driver: Issue with Kernel Extension (kext) (macOS 10.11 and later only) +### a) STLINK/v1 driver: Issue with Kernel Extension (kext) (macOS 10.11 and later only) #### Problem: -st-util fails to detect a ST-Link-v1 device: +st-util fails to detect a STLINK/v1 device: ``` st-util -1 @@ -35,7 +40,7 @@ ERROR src/sg.c: Could not open stlink device The root of this problem is a system security setting introduced by Apple with OS X El Capitan (10.11) in 2015. The so called System Integrity Protection (SIP) is active per default and prevents the operating system amongst other things to load unsigned Kernel Extension Modules (kext). -Thus the ST-Link-v1 driver supplied with the tools, which installs as a kext, remains not functional, +Thus the STLINK/v1 driver supplied with the tools, which installs as a kext, remains not functional, while SIP is fully activated (as is per default). Action needs to be taken here by booting into the recovery mode where a terminal console window needs to be opened. @@ -47,7 +52,7 @@ Running `csrutil enable --without kext`, allows to load unsigned kernel extensio while leaving SIP active with all other security features. Unfortunately this option has been removed in macOS 10.14, which leaves the only option to disable SIP completely. -So who ever intends to run the ST-Link-v1 programmer on macOS please take this into account. +So who ever intends to run the STLINK/v1 programmer on macOS please take this into account. Further details can be found here: https://forums.developer.apple.com/thread/17452 @@ -66,7 +71,7 @@ Requesting load of /System/Library/Extensions/stlink_shield10_x.kext. 5) Enter the command `$ sudo touch /System/Library/Extensions` -7) Verify correct detection of the ST-Link-v1 device with the following input: `st-util -1` +7) Verify correct detection of the STLINK/v1 device with the following input: `st-util -1` You should then see a similar output like in this example: @@ -81,7 +86,7 @@ INFO gdb-server.c: Listening at *:4242... ### b) Verify if udev rules are set correctly (by Dave Hylands) -To investigate, start by plugging your STLINK device into the usb port. Then run lsusb. You should see an entry something like the following: +To investigate, start by plugging your STLINK device into the usb port. Then run `lsusb`. You should see an entry something like the following: ``` Bus 005 Device 017: ID 0483:374b STMicroelectronics ST-LINK/V2.1 (Nucleo-F103RB) @@ -96,7 +101,7 @@ On my system I see the following: crw-rw-rw- 1 root root 189, 528 Jan 24 17:52 /dev/bus/usb/005/017 ``` -which is world writable (this is from the MODE:="0666" below). I have several files in my `/etc/udev/rules.d` directory. In this particular case, the `49-stlinkv2-1.rules` file contains the following: +which is world writable (this is from the `MODE:="0666"` below). I have several files in my `/etc/udev/rules.d` directory. In this particular case, the `49-stlinkv2-1.rules` file contains the following: ``` # stm32 nucleo boards, with onboard st/linkv2-1 @@ -113,9 +118,9 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", \ # GROUP:="somegroupname" and mange access using standard unix groups. ``` -and the idVendor of 0483 and idProduct of 374b matches the vendor id from the lsusb output. +and the `idVendor` of `0483` and `idProduct` of `374b` matches the vendor id from the `lsusb` output. -Make sure that you have all 3 files from here: https://github.com/texane/stlink/tree/master/etc/udev/rules.d in your `/etc/udev/rules.d` directory. After copying new files or editing excisting files in `/etc/udev/ruled.d` you should run the following: +Make sure that you have all 3 files from here: https://github.com/stlink-org/stlink/tree/master/etc/udev/rules.d in your `/etc/udev/rules.d` directory. After copying new files or editing excisting files in `/etc/udev/ruled.d` you should run the following: ``` sudo udevadm control --reload-rules @@ -135,8 +140,7 @@ Using STM32 discovery kits with open source tools This guide details the use of STMicroelectronics STM32 discovery kits in an open source environment. -Installing a GNU toolchain -========================== +## Installing a GNU toolchain Any toolchain supporting the cortex m3 should do. You can find the necessary to install such a toolchain here: @@ -149,51 +153,7 @@ Details for the installation are provided in the topmost `README` file. This documentation assumes the toolchains is installed in a `$TOOLCHAIN_PATH`. -Installing STLINK -================= - -STLINK is open source software to program and debug ST’s STM32 Discovery -kits. Those kits have an onboard chip that translates USB commands sent -by the host PC into JTAG/SWD commands. This chip is called STLINK, (yes, -isn’t that confusing? suggest a better name!) and comes in 2 versions -(STLINK v1 and v2). From a software point of view, those versions differ -only in the transport layer used to communicate (v1 uses SCSI passthru -commands, while v2 uses raw USB). From a user point of view, they are -identical. - - -Before continuing, the following dependencies must be met: - -- libusb-1.0 -- cmake - -Also make sure `gtk+` version 3.0 is installed. (`sudo apt-get install gtk+-3.0` or similiar) - -STLINK should run on any system meeting the above constraints. - -The STLINK software source code is retrieved using: - -``` -$> git clone https://github.com/texane/stlink.git -``` - -Everything can be built from the top directory: - -``` -$> cd stlink -$> make -$> cd build/Release && make install DESTDIR=_install -``` - -It includes: - -- a communication library (libstlink.a), -- a GDB server (st-util), -- a flash manipulation tool (st-flash). -- a programmer and chip information tool (st-info) - -Using the GDB server -==================== +## Using the GDB server This assumes you have got the libopencm3 project downloaded in `ocm3`. The libopencm3 project has some good, reliable examples for each of the @@ -259,8 +219,7 @@ examples from libopencm3, the LEDs on the board should be blinking for you. -Building and flashing a program -=============================== +## Building and flashing a program If you want to simply flash binary files to arbitrary sections of memory, or read arbitary addresses of memory out to a binary file, use @@ -300,9 +259,6 @@ $> [sudo] ./st-flash write fancy_blink.bin 0x08000000 Upon reset, the board LEDs should be blinking. -HOWTO (old) -=========== - ## Using the gdb server To run the gdb server: @@ -376,6 +332,16 @@ If you need to send a hard reset signal through `NRST` pin, you can use the foll ``` +## Disassembling THUMB code in GDB + +By default, the disassemble command in GDB operates in ARM mode. The programs running on CORTEX-M3 are compiled in THUMB mode. +To correctly disassemble them under GDB, uses an odd address. For instance, if you want to disassemble the code at 0x20000000, use: + +``` +(gdb) disassemble 0x20000001 +``` + + ## Running programs from SRAM You can run your firmware directly from SRAM if you want to. Just link @@ -469,19 +435,15 @@ A: Installed on Mac OS X 10.9.4 with ports method, [https://coderwall.com/p/oznj_q](https://coderwall.com/p/oznj_q) -`sudo port install libusb automake autoconf pkgconfig` - -`aclocal --force -I /opt/local/share/aclocal` - -`git clone https://github.com/texane/stlink.git stlink-utility` - -`cd stlink-utility` - -`./autogen.sh` - -`./configure` - -`make` +``` +sudo port install libusb automake autoconf pkgconfig +aclocal --force -I /opt/local/share/aclocal +git clone https://github.com/stlink-org/stlink.git stlink-utility +cd stlink-utility +./autogen.sh +./configure +make +``` Then trying to flash the image with STLINK v2 : @@ -524,26 +486,6 @@ http://community.spark.io/t/how-to-flash-a-brand-new-freshly-soldered-stm32f103- > 2014-08-11T23:14:54 INFO src/stlink-common.c: Flash written and verified! jolly good! -Notes -===== - -Disassembling THUMB code in GDB -------------------------------- - -By default, the disassemble command in GDB operates in ARM mode. The -programs running on CORTEX-M3 are compiled in THUMB mode. To correctly -disassemble them under GDB, uses an odd address. For instance, if you -want to disassemble the code at 0x20000000, use:\ - -``` -(gdb) disassemble 0x20000001 -``` - -Checksum of binary file ------------------------ - -When flashing a file, the checksum of which is calculated, both in md5 and the sum algorithm used by ST's official tool. The detail of sum algorithm can be found in [https://www.st.com/resource/en/user_manual/cd00262073-stm32-stlink-utility-software-description-stmicroelectronics.pdf](https://www.st.com/resource/en/user_manual/cd00262073-stm32-stlink-utility-software-description-stmicroelectronics.pdf). - References ========== @@ -554,5 +496,4 @@ References documentation related to the STM32L discovery kit - - libopencm3, a project providing a firmware library, with solid - examples for Cortex M3, M4 and M0 processors from any vendor. + libopencm3, a project providing a firmware library, with solid examples for Cortex M3, M4 and M0 processors from any vendor. From 6f934a396ef320ee5ade3de95135818e1683aefd Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 15 Apr 2020 16:20:17 +0200 Subject: [PATCH 0821/1435] Whitespace cleanup --- CMakeLists.txt | 4 +- cmake/c_flag_overrides.cmake | 4 +- cmake/c_flags.cmake | 6 +- cmake/cpack_config.cmake | 14 +- cmake/modules/FindLibUSB.cmake | 2 +- cmake/modules/pandocology.cmake | 40 +++--- cmake/version.cmake | 4 +- cmake_uninstall.cmake.in | 4 +- doc/man/CMakeLists.txt | 2 +- src/common.c | 166 +++++++++++----------- src/flash_loader.c | 2 +- src/gdbserver/gdb-remote.c | 36 ++--- src/gdbserver/gdb-server.c | 234 ++++++++++++++++---------------- src/gdbserver/semihosting.c | 22 +-- src/md5.c | 14 +- src/mingw/mingw.c | 30 ++-- src/sg.c | 4 +- src/tools/flash.c | 16 +-- src/tools/flash_opts.c | 32 ++--- src/tools/gui/stlink-gui.c | 14 +- src/usb.c | 6 +- tests/flash.c | 14 +- 22 files changed, 335 insertions(+), 335 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 45e332b10..3572c2a15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,8 +101,8 @@ set(STLINK_SOURCE ) if (WIN32 OR MSYS OR MINGW) - set (STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") - set (STLINK_HEADERS "${STLINK_HEADERS};src/mingw/mingw.h") + set(STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") + set(STLINK_HEADERS "${STLINK_HEADERS};src/mingw/mingw.h") endif () include_directories(${LIBUSB_INCLUDE_DIR}) diff --git a/cmake/c_flag_overrides.cmake b/cmake/c_flag_overrides.cmake index c15815e17..1a1d163fb 100644 --- a/cmake/c_flag_overrides.cmake +++ b/cmake/c_flag_overrides.cmake @@ -1,7 +1,7 @@ -if(MSVC) +if (MSVC) message(STATUS "MSVC C Flags override to /MT") set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") -endif() +endif () diff --git a/cmake/c_flags.cmake b/cmake/c_flags.cmake index fbadd6d9e..c7954bf54 100644 --- a/cmake/c_flags.cmake +++ b/cmake/c_flags.cmake @@ -11,7 +11,7 @@ function(add_cflag_if_supported flag) if (C_SUPPORTS${flagclean}) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE) - endif() + endif () endfunction() add_cflag_if_supported("-std=gnu11") @@ -41,10 +41,10 @@ if (NOT WIN32) add_cflag_if_supported("-fPIC") endif () -if(${CMAKE_BUILD_TYPE} MATCHES "Debug") +if (${CMAKE_BUILD_TYPE} MATCHES "Debug") add_cflag_if_supported("-ggdb") add_cflag_if_supported("-O0") else() add_cflag_if_supported("-O2") add_cflag_if_supported("-Werror") -endif() +endif () diff --git a/cmake/cpack_config.cmake b/cmake/cpack_config.cmake index b8d4be186..c70cf3a63 100644 --- a/cmake/cpack_config.cmake +++ b/cmake/cpack_config.cmake @@ -1,27 +1,27 @@ -set (CPACK_PACKAGE_NAME ${PROJECT_NAME}) -set (CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) -set (CPACK_SET_DESTDIR "ON") +set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) +set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) +set(CPACK_SET_DESTDIR "ON") if (APPLE) set(CPACK_GENERATOR "ZIP") set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-macosx-amd64") file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/osx") - set (CPACK_INSTALL_PREFIX "") + set(CPACK_INSTALL_PREFIX "") set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/osx") elseif (WIN32) set(CPACK_GENERATOR "ZIP") file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/windows") - set (CPACK_INSTALL_PREFIX "") + set(CPACK_INSTALL_PREFIX "") set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/windows") elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND EXISTS "/etc/debian_version") message(STATUS "Debian-based Linux OS detected") set(CPACK_GENERATOR "DEB") if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}-amd64" ) - endif() + endif () set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/stlink-org/stlink") set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Luca Boccassi") set(CPACK_PACKAGE_CONTACT "bluca@debian.org") set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "STM32 STlink programmer tools") -endif() +endif () diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/FindLibUSB.cmake index dc90bcc32..1fd465e4b 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/FindLibUSB.cmake @@ -77,7 +77,7 @@ else () # all other OS LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS /usr /usr/local /opt ) -endif() +endif () include(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) diff --git a/cmake/modules/pandocology.cmake b/cmake/modules/pandocology.cmake index 763eae558..ff9053197 100644 --- a/cmake/modules/pandocology.cmake +++ b/cmake/modules/pandocology.cmake @@ -42,10 +42,10 @@ include(CMakeParseArguments) -if(NOT EXISTS ${PANDOC_EXECUTABLE}) +if (NOT EXISTS ${PANDOC_EXECUTABLE}) find_program(PANDOC_EXECUTABLE pandoc) mark_as_advanced(PANDOC_EXECUTABLE) -endif() +endif () ############################################################################### # Based on code from UseLATEX @@ -133,7 +133,7 @@ This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. Please delete them: $ rm -r CMakeFiles/ CmakeCache.txt ") - ENDIF() + ENDif () endfunction() # This builds a document @@ -171,7 +171,7 @@ function(add_document target_name) if (NOT PANDOC_EXECUTABLE) message(WARNING "Pandoc not found. Install Pandoc (http://johnmacfarlane.net/pandoc/) or set cache variable PANDOC_EXECUTABLE.") return() - endif() + endif () set(options EXPORT_ARCHIVE NO_EXPORT_PRODUCT EXPORT_PDF DIRECT_TEX_TO_PDF VERBOSE) set(oneValueArgs PRODUCT_DIRECTORY) @@ -188,29 +188,29 @@ function(add_document target_name) if (NOT "${target_extension}" STREQUAL ".tex" AND NOT "${target_extension}" STREQUAL ".latex") # if (NOT "${target_extension}" STREQUAL ".tex") MESSAGE(FATAL_ERROR "Target '${target_name}': Cannot use 'EXPORT_PDF' for target of type '${target_extension}': target type must be '.tex' or '.latex'") - endif() - endif() + endif () + endif () if (${ADD_DOCUMENT_DIRECT_TEX_TO_PDF}) list(LENGTH ${ADD_DOCUMENT_SOURCES} SOURCE_LEN) if (SOURCE_LEN GREATER 1) MESSAGE(FATAL_ERROR "Target '${target_name}': Only one source can be specified when using the 'DIRECT_TEX_TO_PDF' option") - endif() + endif () # set(ADD_DOCUMENT_SOURCES, list(GET ${ADD_DOCUMENT_SOURCES} 1)) pandocology_get_file_stemname(source_stemname ${ADD_DOCUMENT_SOURCES}) pandocology_get_file_extension(source_extension ${ADD_DOCUMENT_SOURCES}) if (NOT "${source_extension}" STREQUAL ".tex" AND NOT "${source_extension}" STREQUAL ".latex") MESSAGE(FATAL_ERROR "Target '${target_name}': Cannot use 'DIRECT_TEX_TO_PDF' for source of type '${source_extension}': source type must be '.tex' or '.latex'") - endif() + endif () SET(check_target ${source_stemname}.pdf) IF (NOT ${check_target} STREQUAL ${target_name}) MESSAGE(FATAL_ERROR "Target '${target_name}': Must use target name of '${check_target}' if using 'DIRECT_TEX_TO_PDF'") - endif() - endif() + endif () + endif () ## set up output directory if ("${ADD_DOCUMENT_PRODUCT_DIRECTORY}" STREQUAL "") set(ADD_DOCUMENT_PRODUCT_DIRECTORY "product") - endif() + endif () get_filename_component(product_directory ${CMAKE_BINARY_DIR}/${ADD_DOCUMENT_PRODUCT_DIRECTORY} ABSOLUTE) # get_filename_component(absolute_product_path ${product_directory}/${target_name} ABSOLUTE) @@ -232,7 +232,7 @@ function(add_document target_name) pandocology_add_input_dir(${CMAKE_CURRENT_SOURCE_DIR}/${resource_dir} ${CMAKE_CURRENT_BINARY_DIR} build_resources) if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) pandocology_add_input_dir(${CMAKE_CURRENT_SOURCE_DIR}/${resource_dir} ${product_directory} exported_resources) - endif() + endif () endforeach() ## primary command @@ -255,7 +255,7 @@ function(add_document target_name) # we produce the target in the source directory, in case other build targets require it as a source COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${build_sources} 2>/dev/null >/dev/null || (grep --no-messages -A8 ".*:[0-9]*:.*" ${target_stemname}.log && false) ) - endif() + endif () add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_name}) else() add_custom_command( @@ -267,7 +267,7 @@ function(add_document target_name) COMMAND ${PANDOC_EXECUTABLE} ${build_sources} ${ADD_DOCUMENT_PANDOC_DIRECTIVES} -o ${target_name} ) add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_name}) - endif() + endif () ## figure out what all is going to be produced by this build set, and set ## those as dependencies of the primary target @@ -275,14 +275,14 @@ function(add_document target_name) set(primary_target_dependencies ${primary_target_dependencies} ${CMAKE_CURRENT_BINARY_DIR}/${target_name}) if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT}) set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_name}) - endif() + endif () if (${ADD_DOCUMENT_EXPORT_PDF}) set(primary_target_dependencies ${primary_target_dependencies} ${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf) set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_stemname}.pdf) - endif() + endif () if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_stemname}.tbz) - endif() + endif () ## primary target # # target cannot have same (absolute name) as dependencies: @@ -326,7 +326,7 @@ function(add_document target_name) ) add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf) add_to_make_clean(${product_directory}/${target_stemname}.pdf) - endif() + endif () ## copy products if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT}) @@ -336,7 +336,7 @@ function(add_document target_name) COMMAND ${CMAKE_COMMAND} -E copy ${target_name} ${product_directory} ) add_to_make_clean(${product_directory}/${target_name}) - endif() + endif () ## copy resources if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) @@ -359,7 +359,7 @@ function(add_document target_name) # ALL # DEPENDS ${product_directory}/${target_stemname}.tbz # ) - endif() + endif () endfunction(add_document) diff --git a/cmake/version.cmake b/cmake/version.cmake index fe778c419..d27b43515 100644 --- a/cmake/version.cmake +++ b/cmake/version.cmake @@ -27,7 +27,7 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") ) if (res EQUAL 1) - set (PROJECT_VERSION "${PROJECT_VERSION}-dirty") + set(PROJECT_VERSION "${PROJECT_VERSION}-dirty") endif () # strip a leading v off of the version as proceeding code expectes just the version numbering. @@ -57,7 +57,7 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") else(GIT_DESCRIBE_RESULT EQUAL 0) message(WARNING "git describe failed.") message(WARNING "${GIT_DESCRIBE_ERROR}") - endif(GIT_DESCRIBE_RESULT EQUAL 0) + endif (GIT_DESCRIBE_RESULT EQUAL 0) else () message(STATUS "Git or repo not found.") endif () diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in index ed17c45cd..0c9f6a437 100644 --- a/cmake_uninstall.cmake.in +++ b/cmake_uninstall.cmake.in @@ -1,6 +1,6 @@ -if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") +if (NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") -endif() +endif () file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) string(REGEX REPLACE "\n" ";" files "${files}") diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 5b435c022..090a2237e 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -23,7 +23,7 @@ foreach (manpage ${MANPAGES}) set(f "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") else() message(AUTHOR_WARNING "Manpage ${manpage} not generated") - endif() + endif () if (f AND NOT WIN32) install(FILES ${f} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1) diff --git a/src/common.c b/src/common.c index d04644071..e94240351 100644 --- a/src/common.c +++ b/src/common.c @@ -546,7 +546,7 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { stlink_write_debug32(sl, cr_reg, val); } - if(v) + if (v) val |= cr_mer; else val &= ~cr_mer; @@ -905,7 +905,7 @@ int stlink_load_device_params(stlink_t *sl) { sl->flash_size = (flash_size & 0xff) * 1024; } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_HIGH) { // 0 is 384k and 1 is 256k - if ( flash_size == 0 ) { + if ( flash_size == 0){ sl->flash_size = 384 * 1024; } else { sl->flash_size = 256 * 1024; @@ -923,7 +923,7 @@ int stlink_load_device_params(stlink_t *sl) { //medium and low devices have the same chipid. ram size depends on flash size. //STM32F100xx datasheet Doc ID 16455 Table 2 - if(sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW && sl->flash_size < 64 * 1024){ + if (sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW && sl->flash_size < 64 * 1024){ sl->sram_size = 0x1000; } @@ -1091,7 +1091,7 @@ int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem8 ***\n"); - if (len > 0x40 ) { // !!! never ever: Writing more then 0x40 bytes gives unexpected behaviour + if (len > 0x40){ // !!! never ever: Writing more then 0x40 bytes gives unexpected behaviour fprintf(stderr, "Error: Data length > 64: +%d byte.\n", len); abort(); @@ -1374,7 +1374,7 @@ static void md5_calculate(mapped_file_t *mf) { Md5Update(&md5Context, mf->base, (uint32_t)mf->len); Md5Finalise(&md5Context, &md5Hash); printf("md5 checksum: "); - for(int i = 0; i < (int) sizeof(md5Hash); i++) { + for (int i = 0; i < (int) sizeof(md5Hash); i++) { printf("%x", md5Hash.bytes[i]); } printf(", "); @@ -1426,7 +1426,7 @@ int stlink_mwrite_sram(stlink_t * sl, uint8_t* data, uint32_t length, stm32_addr len = length; - if(len & 3) { + if (len & 3) { len -= len & 3; } @@ -1445,7 +1445,7 @@ int stlink_mwrite_sram(stlink_t * sl, uint8_t* data, uint32_t length, stm32_addr stlink_write_mem32(sl, addr + (uint32_t) off, size); } - if(length > len) { + if (length > len) { memcpy(sl->q_buf, data + len, length - len); stlink_write_mem8(sl, addr + (uint32_t) len, length - len); } @@ -1492,7 +1492,7 @@ int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { len = mf.len; - if(len & 3) { + if (len & 3) { len -= len & 3; } @@ -1511,7 +1511,7 @@ int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { stlink_write_mem32(sl, addr + (uint32_t) off, size); } - if(mf.len > len) { + if (mf.len > len) { memcpy(sl->q_buf, mf.base + len, mf.len - len); stlink_write_mem8(sl, addr + (uint32_t) len, mf.len - len); } @@ -1595,7 +1595,7 @@ struct stlink_fread_ihex_worker_arg { static bool stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg* the_arg) { uint32_t addr = the_arg->addr; uint8_t sum = 2 + 4 + (uint8_t)((addr & 0xFF000000) >> 24) + (uint8_t)((addr & 0x00FF0000) >> 16); - if(17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", (addr & 0xFFFF0000) >> 16, (uint8_t)(0x100 - sum))) + if (17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", (addr & 0xFFFF0000) >> 16, (uint8_t)(0x100 - sum))) return false; the_arg->lba = (addr & 0xFFFF0000); @@ -1605,26 +1605,26 @@ static bool stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg* th static bool stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg* the_arg) { uint8_t count = the_arg->buf_pos; - if(count == 0) return true; + if (count == 0) return true; uint32_t addr = the_arg->addr; - if(the_arg->lba != (addr & 0xFFFF0000)) { // segment changed - if(!stlink_fread_ihex_newsegment(the_arg)) return false; + if (the_arg->lba != (addr & 0xFFFF0000)) { // segment changed + if (!stlink_fread_ihex_newsegment(the_arg)) return false; } uint8_t sum = count + (uint8_t)((addr & 0x0000FF00) >> 8) + (uint8_t)(addr & 0x000000FF); - if(9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) + if (9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) return false; - for(uint8_t i = 0; i < count; ++i) { + for (uint8_t i = 0; i < count; ++i) { uint8_t b = the_arg->buf[i]; sum += b; - if(2 != fprintf(the_arg->file, "%02X", b)) + if (2 != fprintf(the_arg->file, "%02X", b)) return false; } - if(4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) + if (4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) return false; the_arg->addr += count; @@ -1645,9 +1645,9 @@ static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg* the_arg, static bool stlink_fread_ihex_worker(void* arg, uint8_t* block, ssize_t len) { struct stlink_fread_ihex_worker_arg* the_arg = (struct stlink_fread_ihex_worker_arg*)arg; - for(ssize_t i = 0; i < len; ++i) { - if(the_arg->buf_pos == sizeof(the_arg->buf)) { // line is full - if(!stlink_fread_ihex_writeline(the_arg)) return false; + for (ssize_t i = 0; i < len; ++i) { + if (the_arg->buf_pos == sizeof(the_arg->buf)) { // line is full + if (!stlink_fread_ihex_writeline(the_arg)) return false; } the_arg->buf[the_arg->buf_pos++] = block[i]; @@ -1657,11 +1657,11 @@ static bool stlink_fread_ihex_worker(void* arg, uint8_t* block, ssize_t len) { } static bool stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg* the_arg) { - if(!stlink_fread_ihex_writeline(the_arg)) return false; + if (!stlink_fread_ihex_writeline(the_arg)) return false; // FIXME do we need the Start Linear Address? - if(13 != fprintf(the_arg->file, ":00000001FF\r\n")) // EoF + if (13 != fprintf(the_arg->file, ":00000001FF\r\n")) // EoF return false; return (0 == fclose(the_arg->file)); @@ -1678,11 +1678,11 @@ int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr return -1; } - if(is_ihex) { + if (is_ihex) { struct stlink_fread_ihex_worker_arg arg; - if(stlink_fread_ihex_init(&arg, fd, addr)) { + if (stlink_fread_ihex_init(&arg, fd, addr)) { error = stlink_read(sl, addr, size, &stlink_fread_ihex_worker, &arg); - if(!stlink_fread_ihex_finalize(&arg)) + if (!stlink_fread_ihex_finalize(&arg)) error = -1; } else { @@ -1722,18 +1722,18 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ flashaddr -= 0x100000; } if (flashaddr<0x4000) return (offset + 0); - else if(flashaddr<0x8000) return(offset + 1); - else if(flashaddr<0xc000) return(offset + 2); - else if(flashaddr<0x10000) return(offset + 3); - else if(flashaddr<0x20000) return(offset + 4); + else if (flashaddr<0x8000) return(offset + 1); + else if (flashaddr<0xc000) return(offset + 2); + else if (flashaddr<0x10000) return(offset + 3); + else if (flashaddr<0x20000) return(offset + 4); else return offset + (flashaddr/0x20000) +4; } uint32_t calculate_F7_sectornum(uint32_t flashaddr){ flashaddr &= ~STM32_FLASH_BASE; //Page now holding the actual flash address - if(flashaddr<0x20000) return(flashaddr/0x8000); - else if(flashaddr<0x40000) return(4); + if (flashaddr<0x20000) return(flashaddr/0x8000); + else if (flashaddr<0x40000) return(4); else return(flashaddr/0x40000) +4; } @@ -1778,14 +1778,14 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ sector -= 12; } if (sector<4) sl->flash_pgsz=0x4000; - else if(sector<5) sl->flash_pgsz=0x10000; + else if (sector<5) sl->flash_pgsz=0x10000; else sl->flash_pgsz=0x20000; } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { uint32_t sector=calculate_F7_sectornum(flashaddr); if (sector<4) sl->flash_pgsz=0x8000; - else if(sector<5) sl->flash_pgsz=0x20000; + else if (sector<5) sl->flash_pgsz=0x20000; else sl->flash_pgsz=0x40000; } return (uint32_t) sl->flash_pgsz; @@ -1866,7 +1866,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) /* check if the locks are set */ stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if((val & (1<<0))||(val & (1<<1))) { + if ((val & (1<<0))||(val & (1<<1))) { /* disable pecr protection */ stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x89abcdef); stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x02030405); @@ -1903,7 +1903,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) */ do { stlink_read_debug32(sl, STM32L_FLASH_SR, &val) - } while((val & (1 << 0)) != 0); + } while ((val & (1 << 0)) != 0); #endif /* fix_to_be_confirmed */ @@ -2265,7 +2265,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t (sl->chip_id != STLINK_CHIPID_STM32_L496X) && (sl->chip_id != STLINK_CHIPID_STM32_L4RX)) { - if( sl->version.stlink_v == 1 ) { + if ( sl->version.stlink_v == 1){ printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes on F4 devices\n"); write_flash_cr_psiz(sl, 2); } @@ -2299,7 +2299,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t set_flash_cr_pg(sl); size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; - for(off = 0; off < len;) { + for (off = 0; off < len;) { size_t size = len - off > buf_size ? buf_size : len - off; printf("size: %u\n", (unsigned int)size); @@ -2483,11 +2483,11 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t // note: length not checked static uint8_t stlink_parse_hex(const char* hex) { uint8_t d[2]; - for(int i = 0; i < 2; ++i) { + for (int i = 0; i < 2; ++i) { char c = *(hex + i); - if(c >= '0' && c <= '9') d[i] = c - '0'; - else if(c >= 'A' && c <= 'F') d[i] = c - 'A' + 10; - else if(c >= 'a' && c <= 'f') d[i] = c - 'a' + 10; + if (c >= '0' && c <= '9') d[i] = c - '0'; + else if (c >= 'A' && c <= 'F') d[i] = c - 'A' + 10; + else if (c >= 'a' && c <= 'f') d[i] = c - 'a' + 10; else return 0; // error } return (d[0] << 4) | (d[1]); @@ -2500,15 +2500,15 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, uint32_t end = 0; bool eof_found = false; - for(int scan = 0; (res == 0) && (scan < 2); ++scan) { // parse file two times - first to find memory range, second - to fill it - if(scan == 1) { - if(!eof_found) { + for (int scan = 0; (res == 0) && (scan < 2); ++scan) { // parse file two times - first to find memory range, second - to fill it + if (scan == 1) { + if (!eof_found) { ELOG("No EoF recond\n"); res = -1; break; } - if(*begin >= end) { + if (*begin >= end) { ELOG("No data found in file\n"); res = -1; break; @@ -2516,7 +2516,7 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, *size = (end - *begin) + 1; data = calloc(*size, 1); // use calloc to get NULL if out of memory - if(!data) { + if (!data) { ELOG("Cannot allocate %d bytes\n", *size); res = -1; break; @@ -2526,7 +2526,7 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, } FILE* file = fopen(path, "r"); - if(!file) { + if (!file) { ELOG("Cannot open file\n"); res = -1; break; @@ -2535,17 +2535,17 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, uint32_t lba = 0; char line[1 + 5*2 + 255*2 + 2]; - while(fgets(line, sizeof(line), file)) { - if(line[0] == '\n' || line[0] == '\r') continue; // skip empty lines - if(line[0] != ':') { // no marker - wrong file format + while (fgets(line, sizeof(line), file)) { + if (line[0] == '\n' || line[0] == '\r') continue; // skip empty lines + if (line[0] != ':') { // no marker - wrong file format ELOG("Wrong file format - no marker\n"); res = -1; break; } size_t l = strlen(line); - while(l > 0 && (line[l-1] == '\n' || line[l-1] == '\r')) --l; // trim EoL - if((l < 11) || (l == (sizeof(line)-1))) { // line too short or long - wrong file format + while (l > 0 && (line[l-1] == '\n' || line[l-1] == '\r')) --l; // trim EoL + if ((l < 11) || (l == (sizeof(line)-1))) { // line too short or long - wrong file format ELOG("Wrong file format - wrong line length\n"); res = -1; break; @@ -2553,17 +2553,17 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, // check sum uint8_t chksum = 0; - for(size_t i = 1; i < l; i += 2) { + for (size_t i = 1; i < l; i += 2) { chksum += stlink_parse_hex(line + i); } - if(chksum != 0) { + if (chksum != 0) { ELOG("Wrong file format - checksum mismatch\n"); res = -1; break; } uint8_t reclen = stlink_parse_hex(line + 1); - if(((uint32_t)reclen + 5)*2 + 1 != l) { + if (((uint32_t)reclen + 5)*2 + 1 != l) { ELOG("Wrong file format - record length mismatch\n"); res = -1; break; @@ -2574,17 +2574,17 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, switch(rectype) { case 0: // data - if(scan == 0) { + if (scan == 0) { uint32_t b = lba + offset; uint32_t e = b + reclen - 1; - if(b < *begin) *begin = b; - if(e > end) end = e; + if (b < *begin) *begin = b; + if (e > end) end = e; } else { - for(uint8_t i = 0; i < reclen; ++i) { + for (uint8_t i = 0; i < reclen; ++i) { uint8_t b = stlink_parse_hex(line + 9 + i*2); uint32_t addr = lba + offset + i; - if(addr >= *begin && addr <= end) { + if (addr >= *begin && addr <= end) { data[addr - *begin] = b; } } @@ -2604,7 +2604,7 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, break; case 4: // Extended Linear Address - if(reclen == 2) { + if (reclen == 2) { lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | ((uint32_t)stlink_parse_hex(line + 11) << 16); } else { @@ -2620,13 +2620,13 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, ELOG("Wrong file format - unexpected record type %d\n", rectype); res = -1; } - if(res != 0) break; + if (res != 0) break; } fclose(file); } - if(res == 0) { + if (res == 0) { *mem = data; } else { @@ -2655,14 +2655,14 @@ int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr */ if (sl->opt) { idx = (unsigned int)length; - for(num_empty = 0; num_empty != length; ++num_empty) { + for (num_empty = 0; num_empty != length; ++num_empty) { if (data[--idx] != erased_pattern) { break; } } /* Round down to words */ num_empty -= (num_empty & 3); - if(num_empty != 0) { + if (num_empty != 0) { ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); } } else { @@ -2704,14 +2704,14 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { if (sl->opt) { idx = (unsigned int) mf.len; - for(num_empty = 0; num_empty != mf.len; ++num_empty) { + for (num_empty = 0; num_empty != mf.len; ++num_empty) { if (mf.base[--idx] != erased_pattern) { break; } } /* Round down to words */ num_empty -= (num_empty & 3); - if(num_empty != 0) { + if (num_empty != 0) { ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); } } else { @@ -2740,7 +2740,7 @@ static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t l uint32_t val; - if(len != 4) { + if (len != 4) { ELOG("Wrong length for writing option bytes, must be 4 is %d\n", len); return -1; } @@ -2749,7 +2749,7 @@ static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t l stlink_core_id(sl); /* Check if chip is supported and for correct address */ - if(sl->chip_id != STLINK_CHIPID_STM32_G0_CAT1 && + if (sl->chip_id != STLINK_CHIPID_STM32_G0_CAT1 && sl->chip_id != STLINK_CHIPID_STM32_G0_CAT2) { ELOG("Option bytes writing is currently only supported for the STM32G0\n"); return -1; @@ -2833,7 +2833,7 @@ static int stlink_write_option_bytes_l0_cat2(stlink_t *sl, uint8_t* base, uint32 uint32_t val; - if(len != 4) { + if (len != 4) { ELOG("Wrong length for writting option bytes, must be 4 is %d\n", len); return -1; } @@ -2891,7 +2891,7 @@ static int stlink_write_option_bytes_l1(stlink_t *sl, uint8_t* base, stm32_addr_ uint32_t val; uint32_t data; - if(len != 4 && len != 8) { + if (len != 4 && len != 8) { ELOG("Wrong length for writting option bytes, must be 4 or 8 is %d\n", len); return -1; } @@ -2932,7 +2932,7 @@ static int stlink_write_option_bytes_l1(stlink_t *sl, uint8_t* base, stm32_addr_ /* Write options bytes */ write_uint32((unsigned char*) &data, *(uint32_t*) (base)); - if( data != val ) { + if ( data != val ) { WLOG("Writing option bytes 0x%04x\n", data); stlink_write_debug32(sl, addr, data); stlink_read_debug32(sl, addr, &val); @@ -2940,7 +2940,7 @@ static int stlink_write_option_bytes_l1(stlink_t *sl, uint8_t* base, stm32_addr_ } - if(len==8) { + if (len==8) { /* Clear errors */ stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_SR_OFF, 0x00003F00); @@ -2949,7 +2949,7 @@ static int stlink_write_option_bytes_l1(stlink_t *sl, uint8_t* base, stm32_addr_ /* Write options bytes */ write_uint32((unsigned char*) &data, *(uint32_t*) (base+4)); - if( data != val ) { + if ( data != val ) { WLOG("Writing 2nd option bytes 0x%04x\n", data); stlink_write_debug32(sl, addr+4, data); stlink_read_debug32(sl, addr+4, &val); @@ -2976,7 +2976,7 @@ static int stlink_write_option_bytes_l496x(stlink_t *sl, uint8_t* base, uint32_t uint32_t val; - if(len != 4) { + if (len != 4) { ELOG("Wrong length for writting option bytes, must be 4 is %d\n", len); return -1; } @@ -3082,7 +3082,7 @@ static int stlink_write_option_bytes_f2(stlink_t *sl, uint32_t option_byte) { stlink_read_debug32(sl, FLASH_F2_SR, &val); WLOG("wait BSY flag to be 0\n"); - while(val & 0x00010000){ + while (val & 0x00010000){ stlink_read_debug32(sl, FLASH_F2_SR, &val); } WLOG("BSY flag is 0\n"); @@ -3132,7 +3132,7 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint32_t option_byte) { stlink_read_debug32(sl, FLASH_F4_SR, &val); WLOG("wait BSY flag to be 0\n"); - while(val & 0x00010000){ + while (val & 0x00010000){ stlink_read_debug32(sl, FLASH_F4_SR, &val); } WLOG("BSY flag is 0\n"); @@ -3228,17 +3228,17 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui WLOG("Option bytes write chip_id 0x%08x addr 0x%08x\n",sl->chip_id,addr); /* Check if chip is supported and for correct address */ - if(((sl->chip_id == STLINK_CHIPID_STM32_G0_CAT1) || + if (((sl->chip_id == STLINK_CHIPID_STM32_G0_CAT1) || (sl->chip_id == STLINK_CHIPID_STM32_G0_CAT2)) && (addr == STM32_G0_OPTION_BYTES_BASE)) { return stlink_write_option_bytes_g0x(sl, base, len); } - else if((sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) && (addr == STM32_L0_CAT2_OPTION_BYTES_BASE)) { + else if ((sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) && (addr == STM32_L0_CAT2_OPTION_BYTES_BASE)) { return stlink_write_option_bytes_l0_cat2(sl, base, len); } - else if((sl->chip_id == STLINK_CHIPID_STM32_L496X) && (addr == STM32_L496X_OPTION_BYTES_BASE)) { + else if ((sl->chip_id == STLINK_CHIPID_STM32_L496X) && (addr == STM32_L496X_OPTION_BYTES_BASE)) { return stlink_write_option_bytes_l496x(sl, base, len); } - else if(((sl->chip_id == STLINK_CHIPID_STM32_L152_RE) || (sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH) ) && + else if (((sl->chip_id == STLINK_CHIPID_STM32_L152_RE) || (sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH) ) && ((addr == STM32_L1_OPTION_BYTES_BASE) || (addr == STM32_L1_OPTION_BYTES_BASE+4))) { return stlink_write_option_bytes_l1(sl, base, addr, len); } @@ -3284,9 +3284,9 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr */ int stlink_fwrite_option_bytes_32bit(stlink_t *sl, uint32_t val) { - if(sl->chip_id == STLINK_CHIPID_STM32_F2){ + if (sl->chip_id == STLINK_CHIPID_STM32_F2){ return stlink_write_option_bytes_f2(sl, val); - }else if(sl->chip_id == STLINK_CHIPID_STM32_F446){ + } else if (sl->chip_id == STLINK_CHIPID_STM32_F446){ return stlink_write_option_bytes_f4(sl, val); } else diff --git a/src/flash_loader.c b/src/flash_loader.c index 9c24ff9e8..a1c9c3757 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -226,7 +226,7 @@ static int loader_v_dependent_assignment(stlink_t *sl, { int retval = 0; - if( sl->version.stlink_v == 1 ) { + if ( sl->version.stlink_v == 1){ printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes\n"); *loader_code = high_v_loader; *loader_size = high_v_loader_size; diff --git a/src/gdbserver/gdb-remote.c b/src/gdbserver/gdb-remote.c index e4aad312d..3b1794f3e 100644 --- a/src/gdbserver/gdb-remote.c +++ b/src/gdbserver/gdb-remote.c @@ -27,7 +27,7 @@ int gdb_send_packet(int fd, char* data) { packet[0] = '$'; uint8_t cksum = 0; - for(unsigned int i = 0; i < data_length; i++) { + for (unsigned int i = 0; i < data_length; i++) { packet[i + 1] = data[i]; cksum += data[i]; } @@ -36,19 +36,19 @@ int gdb_send_packet(int fd, char* data) { packet[length - 2] = hex[cksum >> 4]; packet[length - 1] = hex[cksum & 0xf]; - while(1) { - if(write(fd, packet, length) != length) { + while (1) { + if (write(fd, packet, length) != length) { free(packet); return -2; } char ack; - if(read(fd, &ack, 1) != 1) { + if (read(fd, &ack, 1) != 1) { free(packet); return -2; } - if(ack == '+') { + if (ack == '+') { free(packet); return 0; } @@ -64,7 +64,7 @@ int gdb_recv_packet(int fd, char** buffer) { char* packet_buffer = malloc(packet_size); unsigned state; - if(packet_buffer == NULL) + if (packet_buffer == NULL) return -2; start: @@ -79,15 +79,15 @@ int gdb_recv_packet(int fd, char** buffer) { */ char c; - while(state != 4) { - if(read(fd, &c, 1) != 1) { + while (state != 4) { + if (read(fd, &c, 1) != 1) { free(packet_buffer); return -2; } switch(state) { case 0: - if(c != '$') { + if (c != '$') { // ignore } else { state = 1; @@ -95,16 +95,16 @@ int gdb_recv_packet(int fd, char** buffer) { break; case 1: - if(c == '#') { + if (c == '#') { state = 2; } else { packet_buffer[packet_idx++] = c; cksum += c; - if(packet_idx == packet_size) { + if (packet_idx == packet_size) { packet_size += ALLOC_STEP; void* p = realloc(packet_buffer, packet_size); - if(p != NULL) + if (p != NULL) packet_buffer = p; else { free(packet_buffer); @@ -127,9 +127,9 @@ int gdb_recv_packet(int fd, char** buffer) { } uint8_t recv_cksum_int = strtoul(recv_cksum, NULL, 16); - if(recv_cksum_int != cksum) { + if (recv_cksum_int != cksum) { char nack = '-'; - if(write(fd, &nack, 1) != 1) { + if (write(fd, &nack, 1) != 1) { free(packet_buffer); return -2; } @@ -137,7 +137,7 @@ int gdb_recv_packet(int fd, char** buffer) { goto start; } else { char ack = '+'; - if(write(fd, &ack, 1) != 1) { + if (write(fd, &ack, 1) != 1) { free(packet_buffer); return -2; } @@ -157,13 +157,13 @@ int gdb_check_for_interrupt(int fd) { pfd.fd = fd; pfd.events = POLLIN; - if(poll(&pfd, 1, 0) != 0) { + if (poll(&pfd, 1, 0) != 0) { char c; - if(read(fd, &c, 1) != 1) + if (read(fd, &c, 1) != 1) return -2; - if(c == '\x03') // ^C + if (c == '\x03') // ^C return 1; } diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 9cff5f917..1c45c2538 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -89,10 +89,10 @@ static stlink_t* do_connect(st_state_t *st) { stlink_t *ret = NULL; switch (st->stlink_version) { case 2: - if(serial_specified){ + if (serial_specified){ ret = stlink_open_usb(st->logging_level, st->reset, serialnumber); } - else{ + else { ret = stlink_open_usb(st->logging_level, st->reset, NULL); } break; @@ -199,8 +199,8 @@ int parse_options(int argc, char** argv, st_state_t *st) { /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ int j = (int)strlen(optarg); int length = j / 2; //the length of the destination-array - if(j % 2 != 0) return -1; - for(size_t k = 0; j >= 0 && k < sizeof(serialnumber); ++k, j -= 2) { + if (j % 2 != 0) return -1; + for (size_t k = 0; j >= 0 && k < sizeof(serialnumber); ++k, j -= 2) { char buffer[3] = {0}; memcpy(buffer, optarg + j, 2); serialnumber[length - k] = (uint8_t)strtol(buffer, NULL, 16); @@ -234,7 +234,7 @@ int main(int argc, char** argv) { printf("st-util %s\n", STLINK_VERSION); sl = do_connect(&state); - if(sl == NULL) return 1; + if (sl == NULL) return 1; connected_stlink = sl; signal(SIGINT, &cleanup); @@ -255,7 +255,7 @@ int main(int argc, char** argv) { #if defined(__MINGW32__) || defined(_MSC_VER) WSADATA wsadata; - if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0 ) { + if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0){ goto winsock_error; } #endif @@ -532,27 +532,27 @@ char* make_memory_map(stlink_t *sl) { char* map = malloc(sz); map[0] = '\0'; - if(sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F446 || sl->chip_id==STLINK_CHIPID_STM32_F411RE) { + if (sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F446 || sl->chip_id==STLINK_CHIPID_STM32_F411RE) { strcpy(map, memory_map_template_F4); - } else if(sl->chip_id==STLINK_CHIPID_STM32_F4_DE) { + } else if (sl->chip_id==STLINK_CHIPID_STM32_F4_DE) { strcpy(map, memory_map_template_F4_DE); - } else if(sl->core_id==STM32F7_CORE_ID) { + } else if (sl->core_id==STM32F7_CORE_ID) { snprintf(map, sz, memory_map_template_F7, (unsigned int)sl->sram_size); - } else if(sl->chip_id==STLINK_CHIPID_STM32_F4_HD) { + } else if (sl->chip_id==STLINK_CHIPID_STM32_F4_HD) { strcpy(map, memory_map_template_F4_HD); - } else if(sl->chip_id==STLINK_CHIPID_STM32_F2) { + } else if (sl->chip_id==STLINK_CHIPID_STM32_F2) { snprintf(map, sz, memory_map_template_F2, (unsigned int)sl->flash_size, (unsigned int)sl->sram_size, (unsigned int)sl->flash_size - 0x20000, (unsigned int)sl->sys_base, (unsigned int)sl->sys_size); - } else if((sl->chip_id==STLINK_CHIPID_STM32_L4) || + } else if ((sl->chip_id==STLINK_CHIPID_STM32_L4) || (sl->chip_id==STLINK_CHIPID_STM32_L43X) || (sl->chip_id==STLINK_CHIPID_STM32_L46X)) { snprintf(map, sz, memory_map_template_L4, (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); - } else if(sl->chip_id==STLINK_CHIPID_STM32_L496X) { + } else if (sl->chip_id==STLINK_CHIPID_STM32_L496X) { snprintf(map, sz, memory_map_template_L496, (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); } else { @@ -603,7 +603,7 @@ static void init_data_watchpoints(stlink_t *sl) { stlink_write_debug32(sl, 0xE000EDFC, data); // make sure all watchpoints are cleared - for(int i = 0; i < DATA_WATCH_NUM; i++) { + for (int i = 0; i < DATA_WATCH_NUM; i++) { data_watches[i].fun = WATCHDISABLED; stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); } @@ -620,15 +620,15 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, mask = -1; i = len; - while(i) { + while (i) { i >>= 1; mask++; } - if((mask != (uint32_t)-1) && (mask < 16)) { - for(i = 0; i < DATA_WATCH_NUM; i++) { + if ((mask != (uint32_t)-1) && (mask < 16)) { + for (i = 0; i < DATA_WATCH_NUM; i++) { // is this an empty slot ? - if(data_watches[i].fun == WATCHDISABLED) { + if (data_watches[i].fun == WATCHDISABLED) { DLOG("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len); data_watches[i].fun = wf; @@ -659,8 +659,8 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { int i; - for(i = 0 ; i < DATA_WATCH_NUM; i++) { - if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) { + for (i = 0 ; i < DATA_WATCH_NUM; i++) { + if ((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) { DLOG("delete watchpoint %d addr %x\n", i, addr); data_watches[i].fun = WATCHDISABLED; @@ -698,7 +698,7 @@ static void init_code_breakpoints(stlink_t *sl) { ILOG("Found %i hw breakpoint registers\n", code_break_num); - for(int i = 0; i < code_break_num; i++) { + for (int i = 0; i < code_break_num; i++) { code_breaks[i].type = 0; stlink_write_debug32(sl, STLINK_REG_CM3_FP_COMP0 + i * 4, 0); } @@ -706,7 +706,7 @@ static void init_code_breakpoints(stlink_t *sl) { static int has_breakpoint(stm32_addr_t addr) { - for(int i = 0; i < code_break_num; i++) { + for (int i = 0; i < code_break_num; i++) { if (code_breaks[i].addr == addr) { return 1; } @@ -719,7 +719,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { uint32_t mask; int type = (addr & 0x2) ? CODE_BREAK_HIGH : CODE_BREAK_LOW; - if(addr & 1) { + if (addr & 1) { ELOG("update_code_breakpoint: unaligned address %08x\n", addr); return -1; } @@ -731,16 +731,16 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { } int id = -1; - for(int i = 0; i < code_break_num; i++) { - if(fpb_addr == code_breaks[i].addr || + for (int i = 0; i < code_break_num; i++) { + if (fpb_addr == code_breaks[i].addr || (set && code_breaks[i].type == 0)) { id = i; break; } } - if(id == -1) { - if(set) return -1; // Free slot not found + if (id == -1) { + if (set) return -1; // Free slot not found else return 0; // Breakpoint is already removed } @@ -749,18 +749,18 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { bp->addr = fpb_addr; if (sl->core_id==STM32F7_CORE_ID) { - if(set) bp->type = type; + if (set) bp->type = type; else bp->type = 0; mask = (bp->addr) | 1; } else { - if(set) bp->type |= type; + if (set) bp->type |= type; else bp->type &= ~type; mask = (bp->addr) | 1 | (bp->type << 30); } - if(bp->type == 0) { + if (bp->type == 0) { DLOG("clearing hw break %d\n", id); stlink_write_debug32(sl, 0xe0002008 + id * 4, 0); @@ -789,13 +789,13 @@ static struct flash_block* flash_root; static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { - if(addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) { + if (addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) { ELOG("flash_add_block: incorrect bounds\n"); return -1; } stlink_calculate_pagesize(sl, addr); - if(addr % FLASH_PAGE != 0 || length % FLASH_PAGE != 0) { + if (addr % FLASH_PAGE != 0 || length % FLASH_PAGE != 0) { ELOG("flash_add_block: unaligned block\n"); return -1; } @@ -815,7 +815,7 @@ static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { unsigned int fit_blocks = 0, fit_length = 0; - for(struct flash_block* fb = flash_root; fb; fb = fb->next) { + for (struct flash_block* fb = flash_root; fb; fb = fb->next) { /* Block: ------X------Y-------- * Data: a-----b * a--b @@ -826,7 +826,7 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { unsigned X = fb->addr, Y = fb->addr + fb->length; unsigned a = addr, b = addr + length; - if(a < Y && b > X) { + if (a < Y && b > X) { // from start of the block unsigned start = (a > X ? a : X) - X; unsigned end = (b > Y ? Y : b) - X; @@ -838,12 +838,12 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { } } - if(fit_blocks == 0) { + if (fit_blocks == 0) { ELOG("Unfit data block %08x -> %04x\n", addr, length); return -1; } - if(fit_length != length) { + if (fit_length != length) { WLOG("data block %08x -> %04x truncated to %04x\n", addr, length, fit_length); WLOG("(this is not an error, just a GDB glitch)\n"); @@ -859,10 +859,10 @@ static int flash_go(stlink_t *sl) { stlink_reset(sl); stlink_force_debug(sl); - for(struct flash_block* fb = flash_root; fb; fb = fb->next) { + for (struct flash_block* fb = flash_root; fb; fb = fb->next) { DLOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length); - for(stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += (uint32_t)FLASH_PAGE) { + for (stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += (uint32_t)FLASH_PAGE) { unsigned length = fb->length - (page - fb->addr); //Update FLASH_PAGE @@ -881,7 +881,7 @@ static int flash_go(stlink_t *sl) { error = 0; error: - for(struct flash_block* fb = flash_root, *next; fb; fb = next) { + for (struct flash_block* fb = flash_root, *next; fb; fb = next) { next = fb->next; free(fb->data); free(fb); @@ -956,7 +956,7 @@ static void init_cache (stlink_t *sl) { int i; /* Assume only F7 has a cache. */ - if(sl->core_id!=STM32F7_CORE_ID) + if (sl->core_id!=STM32F7_CORE_ID) return; stlink_read_debug32(sl, CLIDR, &clidr); @@ -972,14 +972,14 @@ static void init_cache (stlink_t *sl) { (clidr >> 27) & 7, (clidr >> 24) & 7, (clidr >> 21) & 7); ILOG(" cache: ctr: %08x, DminLine: %u bytes, IminLine: %u bytes\n", ctr, cache_desc.dminline, cache_desc.iminline); - for(i = 0; i < 7; i++) + for (i = 0; i < 7; i++) { unsigned int ct = (clidr >> (3 * i)) & 0x07; cache_desc.dcache[i].width = 0; cache_desc.icache[i].width = 0; - if(ct == 2 || ct == 3 || ct == 4) + if (ct == 2 || ct == 3 || ct == 4) { /* Data. */ stlink_write_debug32(sl, CSSELR, i << 1); @@ -987,7 +987,7 @@ static void init_cache (stlink_t *sl) { read_cache_level_desc(sl, &cache_desc.dcache[i]); } - if(ct == 1 || ct == 3) + if (ct == 1 || ct == 3) { /* Instruction. */ stlink_write_debug32(sl, CSSELR, (i << 1) | 1); @@ -1035,7 +1035,7 @@ static void cache_sync(stlink_t *sl) { unsigned ccr; - if(sl->core_id!=STM32F7_CORE_ID) + if (sl->core_id!=STM32F7_CORE_ID) return; if (!cache_modified) return; @@ -1063,7 +1063,7 @@ static size_t unhexify(const char *in, char *out, size_t out_count) int serve(stlink_t *sl, st_state_t *st) { SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); - if(!IS_SOCK_VALID(sock)) { + if (!IS_SOCK_VALID(sock)) { perror("socket"); return 1; } @@ -1077,13 +1077,13 @@ int serve(stlink_t *sl, st_state_t *st) { serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(st->listen_port); - if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { + if (bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { perror("bind"); close_socket(sock); return 1; } - if(listen(sock, 5) < 0) { + if (listen(sock, 5) < 0) { perror("listen"); close_socket(sock); return 1; @@ -1093,7 +1093,7 @@ int serve(stlink_t *sl, st_state_t *st) { SOCKET client = accept(sock, NULL, NULL); //signal (SIGINT, SIG_DFL); - if(!IS_SOCK_VALID(client)) { + if (!IS_SOCK_VALID(client)) { perror("accept"); close_socket(sock); return 1; @@ -1120,12 +1120,12 @@ int serve(stlink_t *sl, st_state_t *st) { */ int critical_error = 0; int ret; - while(1) { + while (1) { ret = 0; char* packet; int status = gdb_recv_packet(client, &packet); - if(status < 0) { + if (status < 0) { ELOG("cannot recv: %d\n", status); close_socket(client); return 1; @@ -1138,13 +1138,13 @@ int serve(stlink_t *sl, st_state_t *st) { switch(packet[0]) { case 'q': { - if(packet[1] == 'P' || packet[1] == 'C' || packet[1] == 'L') { + if (packet[1] == 'P' || packet[1] == 'C' || packet[1] == 'L') { reply = strdup(""); break; } char *separator = strstr(packet, ":"), *params = ""; - if(separator == NULL) { + if (separator == NULL) { separator = packet + strlen(packet); } else { params = separator + 1; @@ -1156,8 +1156,8 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("query: %s;%s\n", queryName, params); - if(!strcmp(queryName, "Supported")) { - if(sl->chip_id==STLINK_CHIPID_STM32_F4 + if (!strcmp(queryName, "Supported")) { + if (sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F4_HD || sl->core_id==STM32F7_CORE_ID) { reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); @@ -1165,7 +1165,7 @@ int serve(stlink_t *sl, st_state_t *st) { else { reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); } - } else if(!strcmp(queryName, "Xfer")) { + } else if (!strcmp(queryName, "Xfer")) { char *type, *op, *__s_addr, *s_length; char *tok = params; char *annex __attribute__((unused)); @@ -1184,18 +1184,18 @@ int serve(stlink_t *sl, st_state_t *st) { const char* data = NULL; - if(!strcmp(type, "memory-map") && !strcmp(op, "read")) + if (!strcmp(type, "memory-map") && !strcmp(op, "read")) data = current_memory_map; - if(!strcmp(type, "features") && !strcmp(op, "read")) + if (!strcmp(type, "features") && !strcmp(op, "read")) data = target_description_F4; - if(data) { + if (data) { unsigned data_length = (unsigned int) strlen(data); - if(addr + length > data_length) + if (addr + length > data_length) length = data_length - addr; - if(length == 0) { + if (length == 0) { reply = strdup("l"); } else { reply = calloc(length + 2, 1); @@ -1203,11 +1203,11 @@ int serve(stlink_t *sl, st_state_t *st) { strncpy(&reply[1], data, length); } } - } else if(!strncmp(queryName, "Rcmd,",4)) { + } else if (!strncmp(queryName, "Rcmd,",4)) { // Rcmd uses the wrong separator separator = strstr(packet, ","); params = ""; - if(separator == NULL) { + if (separator == NULL) { separator = packet + strlen(packet); } else { params = separator + 1; @@ -1328,7 +1328,7 @@ int serve(stlink_t *sl, st_state_t *st) { free(cmd); } - if(reply == NULL) + if (reply == NULL) reply = strdup(""); free(queryName); @@ -1342,7 +1342,7 @@ int serve(stlink_t *sl, st_state_t *st) { cmdName++; // vCommand -> Command - if(!strcmp(cmdName, "FlashErase")) { + if (!strcmp(cmdName, "FlashErase")) { char *__s_addr, *s_length; char *tok = params; @@ -1355,12 +1355,12 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("FlashErase: addr:%08x,len:%04x\n", addr, length); - if(flash_add_block(addr, length, sl) < 0) { + if (flash_add_block(addr, length, sl) < 0) { reply = strdup("E00"); } else { reply = strdup("OK"); } - } else if(!strcmp(cmdName, "FlashWrite")) { + } else if (!strcmp(cmdName, "FlashWrite")) { char *__s_addr, *data; char *tok = params; @@ -1375,8 +1375,8 @@ int serve(stlink_t *sl, st_state_t *st) { // Additional byte is reserved for alignment fix. uint8_t *decoded = calloc(data_length + 1, 1); unsigned dec_index = 0; - for(unsigned int i = 0; i < data_length; i++) { - if(data[i] == 0x7d) { + for (unsigned int i = 0; i < data_length; i++) { + if (data[i] == 0x7d) { i++; decoded[dec_index++] = data[i] ^ 0x20; } else { @@ -1385,31 +1385,31 @@ int serve(stlink_t *sl, st_state_t *st) { } // Fix alignment - if(dec_index % 2 != 0) + if (dec_index % 2 != 0) dec_index++; DLOG("binary packet %d -> %d\n", data_length, dec_index); - if(flash_populate(addr, decoded, dec_index) < 0) { + if (flash_populate(addr, decoded, dec_index) < 0) { reply = strdup("E00"); } else { reply = strdup("OK"); } free(decoded); - } else if(!strcmp(cmdName, "FlashDone")) { - if(flash_go(sl) < 0) { + } else if (!strcmp(cmdName, "FlashDone")) { + if (flash_go(sl) < 0) { reply = strdup("E00"); } else { reply = strdup("OK"); } - } else if(!strcmp(cmdName, "Kill")) { + } else if (!strcmp(cmdName, "Kill")) { attached = 0; reply = strdup("OK"); } - if(reply == NULL) + if (reply == NULL) reply = strdup(""); break; @@ -1422,15 +1422,15 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("Semihost: run failed\n"); } - while(1) { + while (1) { status = gdb_check_for_interrupt(client); - if(status < 0) { + if (status < 0) { ELOG("cannot check for int: %d\n", status); close_socket(client); return 1; } - if(status == 1) { + if (status == 1) { stlink_force_debug(sl); break; } @@ -1439,7 +1439,7 @@ int serve(stlink_t *sl, st_state_t *st) { if (ret) { DLOG("Semihost: status failed\n"); } - if(sl->core_stat == STLINK_CORE_HALTED) { + if (sl->core_stat == STLINK_CORE_HALTED) { struct stlink_reg reg; stm32_addr_t pc; stm32_addr_t addr; @@ -1526,7 +1526,7 @@ int serve(stlink_t *sl, st_state_t *st) { break; case '?': - if(attached) { + if (attached) { reply = strdup("S05"); // TRAP } else { /* Stub shall reply OK if not attached. */ @@ -1541,7 +1541,7 @@ int serve(stlink_t *sl, st_state_t *st) { } reply = calloc(8 * 16 + 1, 1); - for(int i = 0; i < 16; i++) + for (int i = 0; i < 16; i++) sprintf(&reply[i * 8], "%08x", (uint32_t)htonl(regp.r[i])); break; @@ -1550,34 +1550,34 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned id = (unsigned int) strtoul(&packet[1], NULL, 16); unsigned myreg = 0xDEADDEAD; - if(id < 16) { + if (id < 16) { ret = stlink_read_reg(sl, id, ®p); myreg = htonl(regp.r[id]); - } else if(id == 0x19) { + } else if (id == 0x19) { ret = stlink_read_reg(sl, 16, ®p); myreg = htonl(regp.xpsr); - } else if(id == 0x1A) { + } else if (id == 0x1A) { ret = stlink_read_reg(sl, 17, ®p); myreg = htonl(regp.main_sp); - } else if(id == 0x1B) { + } else if (id == 0x1B) { ret = stlink_read_reg(sl, 18, ®p); myreg = htonl(regp.process_sp); - } else if(id == 0x1C) { + } else if (id == 0x1C) { ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.control); - } else if(id == 0x1D) { + } else if (id == 0x1D) { ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.faultmask); - } else if(id == 0x1E) { + } else if (id == 0x1E) { ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.basepri); - } else if(id == 0x1F) { + } else if (id == 0x1F) { ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.primask); - } else if(id >= 0x20 && id < 0x40) { + } else if (id >= 0x20 && id < 0x40) { ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.s[id-0x20]); - } else if(id == 0x40) { + } else if (id == 0x40) { ret = stlink_read_unsupported_reg(sl, id, ®p); myreg = htonl(regp.fpscr); } else { @@ -1605,25 +1605,25 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned value = (unsigned int) strtoul(s_value, NULL, 16); - if(reg < 16) { + if (reg < 16) { ret = stlink_write_reg(sl, ntohl(value), reg); - } else if(reg == 0x19) { + } else if (reg == 0x19) { ret = stlink_write_reg(sl, ntohl(value), 16); - } else if(reg == 0x1A) { + } else if (reg == 0x1A) { ret = stlink_write_reg(sl, ntohl(value), 17); - } else if(reg == 0x1B) { + } else if (reg == 0x1B) { ret = stlink_write_reg(sl, ntohl(value), 18); - } else if(reg == 0x1C) { + } else if (reg == 0x1C) { ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x1D) { + } else if (reg == 0x1D) { ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x1E) { + } else if (reg == 0x1E) { ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x1F) { + } else if (reg == 0x1F) { ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg >= 0x20 && reg < 0x40) { + } else if (reg >= 0x20 && reg < 0x40) { ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x40) { + } else if (reg == 0x40) { ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); } else { ret = 1; @@ -1632,7 +1632,7 @@ int serve(stlink_t *sl, st_state_t *st) { if (ret) { DLOG("P packet: stlink_write_unsupported_reg failed with reg %u\n", reg); } - if(reply == NULL) { + if (reply == NULL) { // note that NULL may not be zero reply = strdup("OK"); } @@ -1641,7 +1641,7 @@ int serve(stlink_t *sl, st_state_t *st) { } case 'G': - for(int i = 0; i < 16; i++) { + for (int i = 0; i < 16; i++) { char str[9] = {0}; strncpy(str, &packet[1 + i * 8], 8); uint32_t reg = (uint32_t) strtoul(str, NULL, 16); @@ -1676,7 +1676,7 @@ int serve(stlink_t *sl, st_state_t *st) { } reply = calloc(count * 2 + 1, 1); - for(unsigned int i = 0; i < count; i++) { + for (unsigned int i = 0; i < count; i++) { reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4]; reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf]; } @@ -1693,10 +1693,10 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned count = (unsigned int) strtoul(s_count, NULL, 16); int err = 0; - if(start % 4) { + if (start % 4) { unsigned align_count = 4 - start % 4; if (align_count > count) align_count = count; - for(unsigned int i = 0; i < align_count; i ++) { + for (unsigned int i = 0; i < align_count; i ++) { char hextmp[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; uint8_t byte = strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; @@ -1708,10 +1708,10 @@ int serve(stlink_t *sl, st_state_t *st) { hexdata += 2*align_count; } - if(count - count % 4) { + if (count - count % 4) { unsigned aligned_count = count - count % 4; - for(unsigned int i = 0; i < aligned_count; i ++) { + for (unsigned int i = 0; i < aligned_count; i ++) { char hextmp[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; uint8_t byte = strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; @@ -1723,8 +1723,8 @@ int serve(stlink_t *sl, st_state_t *st) { hexdata += 2*aligned_count; } - if(count) { - for(unsigned int i = 0; i < count; i ++) { + if (count) { + for (unsigned int i = 0; i < count; i ++) { char hextmp[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; uint8_t byte = strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; @@ -1743,7 +1743,7 @@ int serve(stlink_t *sl, st_state_t *st) { switch (packet[1]) { case '1': - if(update_code_breakpoint(sl, addr, 1) < 0) { + if (update_code_breakpoint(sl, addr, 1) < 0) { reply = strdup("E00"); } else { reply = strdup("OK"); @@ -1754,15 +1754,15 @@ int serve(stlink_t *sl, st_state_t *st) { case '3': // insert read watchpoint case '4': { // insert access watchpoint enum watchfun wf; - if(packet[1] == '2') { + if (packet[1] == '2') { wf = WATCHWRITE; - } else if(packet[1] == '3') { + } else if (packet[1] == '3') { wf = WATCHREAD; } else { wf = WATCHACCESS; } - if(add_data_watchpoint(sl, wf, addr, len) < 0) { + if (add_data_watchpoint(sl, wf, addr, len) < 0) { reply = strdup("E00"); } else { reply = strdup("OK"); @@ -1790,7 +1790,7 @@ int serve(stlink_t *sl, st_state_t *st) { case '2' : // remove write watchpoint case '3' : // remove read watchpoint case '4' : // remove access watchpoint - if(delete_data_watchpoint(sl, addr) < 0) { + if (delete_data_watchpoint(sl, addr) < 0) { reply = strdup("E00"); break; } else { @@ -1852,7 +1852,7 @@ int serve(stlink_t *sl, st_state_t *st) { stlink_close(sl); sl = do_connect(st); - if(sl == NULL) cleanup(0); + if (sl == NULL) cleanup(0); connected_stlink = sl; if (st->reset) { @@ -1874,11 +1874,11 @@ int serve(stlink_t *sl, st_state_t *st) { reply = strdup(""); } - if(reply) { + if (reply) { DLOG("send: %s\n", reply); int result = gdb_send_packet(client, reply); - if(result != 0) { + if (result != 0) { ELOG("cannot send: %d\n", result); free(reply); free(packet); diff --git a/src/gdbserver/semihosting.c b/src/gdbserver/semihosting.c index 9e92cf3bd..40758b61d 100644 --- a/src/gdbserver/semihosting.c +++ b/src/gdbserver/semihosting.c @@ -178,7 +178,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint32_t name_len; char *name; - if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + if (mem_read(sl, r1, args, sizeof (args)) != 0){ DLOG("Semihosting SYS_OPEN error: " "cannot read args from target memory\n"); *ret = -1; @@ -215,7 +215,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { return -1; } - if (mem_read(sl, name_address, name, name_len) != 0 ) { + if (mem_read(sl, name_address, name, name_len) != 0){ free(name); *ret = -1; DLOG("Semihosting SYS_OPEN error: " @@ -238,7 +238,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint32_t args[1]; int fd; - if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + if (mem_read(sl, r1, args, sizeof (args)) != 0){ DLOG("Semihosting SYS_CLOSE error: " "cannot read args from target memory\n"); *ret = -1; @@ -263,7 +263,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint32_t buffer_len; void *buffer; - if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + if (mem_read(sl, r1, args, sizeof (args)) != 0){ DLOG("Semihosting SYS_WRITE error: " "cannot read args from target memory\n"); *ret = -1; @@ -289,7 +289,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { return -1; } - if (mem_read(sl, buffer_address, buffer, buffer_len) != 0 ) { + if (mem_read(sl, buffer_address, buffer, buffer_len) != 0){ DLOG("Semihosting SYS_WRITE error: " "cannot read buffer from target memory\n"); free(buffer); @@ -322,7 +322,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { void *buffer; ssize_t read_result; - if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + if (mem_read(sl, r1, args, sizeof (args)) != 0){ DLOG("Semihosting SYS_READ error: " "cannot read args from target memory\n"); *ret = -1; @@ -357,7 +357,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (read_result == -1) { *ret = buffer_len; } else { - if (mem_write(sl, buffer_address, buffer, read_result) != 0 ) { + if (mem_write(sl, buffer_address, buffer, read_result) != 0){ DLOG("Semihosting SYS_READ error: " "cannot write buffer to target memory\n"); free(buffer); @@ -385,7 +385,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint32_t name_len; char *name; - if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + if (mem_read(sl, r1, args, sizeof (args)) != 0){ DLOG("Semihosting SYS_REMOVE error: " "cannot read args from target memory\n"); *ret = -1; @@ -414,7 +414,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { return -1; } - if (mem_read(sl, name_address, name, name_len) != 0 ) { + if (mem_read(sl, name_address, name, name_len) != 0){ free(name); *ret = -1; DLOG("Semihosting SYS_REMOVE error: " @@ -438,7 +438,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { int fd; off_t offset; - if (mem_read(sl, r1, args, sizeof (args)) != 0 ) { + if (mem_read(sl, r1, args, sizeof (args)) != 0){ DLOG("Semihosting SYS_SEEK error: " "cannot read args from target memory\n"); *ret = -1; @@ -482,7 +482,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint8_t buf[WRITE0_BUFFER_SIZE]; while (true) { - if (mem_read(sl, r1, buf, WRITE0_BUFFER_SIZE) != 0 ) { + if (mem_read(sl, r1, buf, WRITE0_BUFFER_SIZE) != 0){ DLOG("Semihosting WRITE0: " "cannot read target memory at 0x%08x\n", r1); return -1; diff --git a/src/md5.c b/src/md5.c index ff7d2d76e..e2b526c7d 100755 --- a/src/md5.c +++ b/src/md5.c @@ -70,7 +70,7 @@ void* #define GET(n) (ctx->block[(n)]) #define SET(n) (ctx->block[(n)] = \ - ((uint32_t)ptr[(n)*4 + 0] << 0 ) \ + ((uint32_t)ptr[(n)*4 + 0] << 0) \ | ((uint32_t)ptr[(n)*4 + 1] << 8 ) \ | ((uint32_t)ptr[(n)*4 + 2] << 16) \ | ((uint32_t)ptr[(n)*4 + 3] << 24) ) @@ -167,7 +167,7 @@ void* d += saved_d; ptr += 64; - } while( size -= 64 ); + } while ( size -= 64 ); ctx->a = a; ctx->b = b; @@ -223,7 +223,7 @@ void uint32_t free; saved_lo = Context->lo; - if( (Context->lo = (saved_lo + BufferSize) & 0x1fffffff) < saved_lo ) + if ( (Context->lo = (saved_lo + BufferSize) & 0x1fffffff) < saved_lo ) { Context->hi++; } @@ -231,11 +231,11 @@ void used = saved_lo & 0x3f; - if( used ) + if ( used ) { free = 64 - used; - if( BufferSize < free ) + if ( BufferSize < free ) { memcpy( &Context->buffer[used], Buffer, BufferSize ); return; @@ -247,7 +247,7 @@ void TransformFunction(Context, Context->buffer, 64); } - if( BufferSize >= 64 ) + if ( BufferSize >= 64 ) { Buffer = TransformFunction( Context, Buffer, BufferSize & ~(unsigned long)0x3f ); BufferSize &= 0x3f; @@ -278,7 +278,7 @@ void free = 64 - used; - if(free < 8) + if (free < 8) { memset( &Context->buffer[used], 0, free ); TransformFunction( Context, Context->buffer, 64 ); diff --git a/src/mingw/mingw.c b/src/mingw/mingw.c index 4cb917ac4..646fca238 100644 --- a/src/mingw/mingw.c +++ b/src/mingw/mingw.c @@ -27,11 +27,11 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) FD_ZERO(&efds); for (i = 0, op = ip = 0; i < nfds; ++i) { fds[i].revents = 0; - if(fds[i].events & (POLLIN|POLLPRI)) { + if (fds[i].events & (POLLIN|POLLPRI)) { ip = &ifds; FD_SET(fds[i].fd, ip); } - if(fds[i].events & POLLOUT) { + if (fds[i].events & POLLOUT) { op = &ofds; FD_SET(fds[i].fd, op); } @@ -42,7 +42,7 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) #endif /* Set up the timeval structure for the timeout parameter */ - if(timo < 0) { + if (timo < 0) { toptr = 0; } else { toptr = &timeout; @@ -59,17 +59,17 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) printf("Exiting select rc=%d\n", rc); #endif - if(rc <= 0) + if (rc <= 0) return rc; - if(rc > 0) { + if (rc > 0) { for ( i = 0; i < nfds; ++i) { int fd = fds[i].fd; - if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) + if (fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) fds[i].revents |= POLLIN; - if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) + if (fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) fds[i].revents |= POLLOUT; - if(FD_ISSET(fd, &efds)) + if (FD_ISSET(fd, &efds)) /* Some error was detected ... should be some way to know. */ fds[i].revents |= POLLHUP; #ifdef DEBUG_POLL @@ -118,7 +118,7 @@ SOCKET win32_socket(int domain, int type, int protocol) { SOCKET fd = socket(domain, type, protocol); - if(fd == INVALID_SOCKET) { + if (fd == INVALID_SOCKET) { set_socket_errno(WSAGetLastError()); } return fd; @@ -133,7 +133,7 @@ win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len) { int rc = connect(fd, addr, addr_len); assert(rc == 0 || rc == SOCKET_ERROR); - if(rc == SOCKET_ERROR) { + if (rc == SOCKET_ERROR) { set_connect_errno(WSAGetLastError()); } return rc; @@ -148,7 +148,7 @@ SOCKET win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len) { SOCKET newfd = accept(fd, addr, addr_len); - if(newfd == INVALID_SOCKET) { + if (newfd == INVALID_SOCKET) { set_socket_errno(WSAGetLastError()); newfd = (SOCKET)-1; } @@ -165,7 +165,7 @@ win32_shutdown(SOCKET fd, int mode) { int rc = shutdown(fd, mode); assert(rc == 0 || rc == SOCKET_ERROR); - if(rc == SOCKET_ERROR) { + if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } return rc; @@ -174,7 +174,7 @@ win32_shutdown(SOCKET fd, int mode) int win32_close_socket(SOCKET fd) { int rc = closesocket(fd); - if(rc == SOCKET_ERROR) { + if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } return rc; @@ -183,7 +183,7 @@ int win32_close_socket(SOCKET fd) ssize_t win32_write_socket(SOCKET fd, void *buf, int n) { int rc = send(fd, buf, n, 0); - if(rc == SOCKET_ERROR) { + if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } return rc; @@ -192,7 +192,7 @@ ssize_t win32_write_socket(SOCKET fd, void *buf, int n) ssize_t win32_read_socket(SOCKET fd, void *buf, int n) { int rc = recv(fd, buf, n, 0); - if(rc == SOCKET_ERROR) { + if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } return rc; diff --git a/src/sg.c b/src/sg.c index d1ee5aea1..031cc64e5 100644 --- a/src/sg.c +++ b/src/sg.c @@ -921,9 +921,9 @@ static stlink_t* stlink_open(const int verbose) { struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg)); if (sl == NULL || slsg == NULL) { WLOG("Couldn't malloc stlink and stlink_sg structures out of memory!\n"); - if(sl != NULL) + if (sl != NULL) free(sl); - if(slsg != NULL) + if (slsg != NULL) free(slsg); return NULL; } diff --git a/src/tools/flash.c b/src/tools/flash.c index f703bc813..f39b6c6e4 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -129,7 +129,7 @@ int main(int ac, char** av) if (o.cmd == FLASH_CMD_WRITE) /* write */ { size_t size = 0; - if(o.format == FLASH_FORMAT_IHEX) { + if (o.format == FLASH_FORMAT_IHEX) { err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr); if (err == -1) { printf("Cannot parse %s as Intel-HEX file\n", o.filename); @@ -138,7 +138,7 @@ int main(int ac, char** av) } if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { - if(o.format == FLASH_FORMAT_IHEX) + if (o.format == FLASH_FORMAT_IHEX) err = stlink_mwrite_flash(sl, mem, (uint32_t)size, o.addr); else err = stlink_fwrite_flash(sl, o.filename, o.addr); @@ -150,7 +150,7 @@ int main(int ac, char** av) } else if ((o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { - if(o.format == FLASH_FORMAT_IHEX) + if (o.format == FLASH_FORMAT_IHEX) err = stlink_mwrite_sram(sl, mem, (uint32_t)size, o.addr); else err = stlink_fwrite_sram(sl, o.filename, o.addr); @@ -207,19 +207,19 @@ int main(int ac, char** av) } else /* read */ { - if(o.area == FLASH_OPTION_BYTES){ - if(sl->chip_id == STLINK_CHIPID_STM32_F2){ + if (o.area == FLASH_OPTION_BYTES){ + if (sl->chip_id == STLINK_CHIPID_STM32_F2){ uint32_t option_byte = 0; err = stlink_read_option_bytes_f2(sl,&option_byte); printf("%x\n",option_byte); - }else if(sl->chip_id == STLINK_CHIPID_STM32_F446){ + } else if (sl->chip_id == STLINK_CHIPID_STM32_F446){ uint32_t option_byte = 0; err = stlink_read_option_bytes_f4(sl,&option_byte); printf("%x\n",option_byte); - }else{ + } else { printf("This format is available for STM32F2 and STM32F4 only\n"); } - }else{ + } else { if ((o.addr >= sl->flash_base) && (o.size == 0) && (o.addr < sl->flash_base + sl->flash_size)){ o.size = sl->flash_size; diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index c139977ce..085d278db 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -28,7 +28,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { o->log_level = STND_LOG_LEVEL; // options - while(ac >= 1) { + while (ac >= 1) { if (strcmp(av[0], "--version") == 0) { printf("v%s\n", STLINK_VERSION); exit(EXIT_SUCCESS); @@ -44,7 +44,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) { const char * serial; - if(strcmp(av[0], "--serial") == 0) { + if (strcmp(av[0], "--serial") == 0) { ac--; av++; if (ac < 1) return -1; @@ -56,8 +56,8 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ int j = (int)strlen(serial); int length = j / 2; // the length of the destination-array - if(j % 2 != 0) return -1; - for(size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { + if (j % 2 != 0) return -1; + for (size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { char buffer[3] = {0}; memcpy(buffer, serial + j, 2); o->serial[length - k] = (uint8_t)strtol(buffer, NULL, 16); @@ -65,7 +65,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { const char * area; - if(strcmp(av[0], "--area") == 0) { + if (strcmp(av[0], "--area") == 0) { ac--; av++; if (ac < 1) return -1; @@ -88,7 +88,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { const char * format; - if(strcmp(av[0], "--format") == 0) { + if (strcmp(av[0], "--format") == 0) { ac--; av++; if (ac < 1) return -1; @@ -136,7 +136,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } // command and (optional) device name - while(ac >= 1) { + while (ac >= 1) { if (strcmp(av[0], "erase") == 0) { if (o->cmd != FLASH_CMD_NONE) return -1; o->cmd = FLASH_CMD_ERASE; @@ -167,32 +167,32 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { return -1; case FLASH_CMD_ERASE: // no more arguments expected - if(ac != 0) return -1; + if (ac != 0) return -1; break; case FLASH_CMD_READ: // expect filename, addr and size - if((o->area == FLASH_OPTION_BYTES) &&(ac == 0)) break; + if ((o->area == FLASH_OPTION_BYTES) &&(ac == 0)) break; if (ac != 3) return invalid_args("read "); if (ac != 3) return -1; o->filename = av[0]; o->addr = (uint32_t) strtoul(av[1], &tail, 16); - if(tail[0] != '\0') return bad_arg("addr"); + if (tail[0] != '\0') return bad_arg("addr"); o->size = strtoul(av[2], &tail, 16); - if(tail[0] != '\0') return bad_arg("size"); + if (tail[0] != '\0') return bad_arg("size"); break; case FLASH_CMD_WRITE: - if(o->area == FLASH_OPTION_BYTES){ - if(ac != 1) return -1; + if (o->area == FLASH_OPTION_BYTES){ + if (ac != 1) return -1; o->val = (uint32_t)strtoul(av[0], &tail, 16); } - else if(o->format == FLASH_FORMAT_BINARY) { // expect filename and addr + else if (o->format == FLASH_FORMAT_BINARY) { // expect filename and addr if (ac != 2) return invalid_args("write "); o->filename = av[0]; o->addr = (uint32_t) strtoul(av[1], &tail, 16); - if(tail[0] != '\0') return bad_arg("addr"); + if (tail[0] != '\0') return bad_arg("addr"); } - else if(o->format == FLASH_FORMAT_IHEX) { // expect filename + else if (o->format == FLASH_FORMAT_IHEX) { // expect filename if (ac != 1) return invalid_args("write "); o->filename = av[0]; } diff --git a/src/tools/gui/stlink-gui.c b/src/tools/gui/stlink-gui.c index c1cf26b76..0dc8bd723 100644 --- a/src/tools/gui/stlink-gui.c +++ b/src/tools/gui/stlink-gui.c @@ -142,7 +142,7 @@ mem_view_add_as_hex (GtkListStore *store, gchar *hex_str; hex_str = g_strdup_printf ("0x%08X", value); - gtk_list_store_set (store, iter, column, hex_str, -1); + gtk_list_store_set(store, iter, column, hex_str, -1); g_free (hex_str); } @@ -439,7 +439,7 @@ static void mem_jmp (GtkTreeView *view, } } } - g_value_unset (&value); + g_value_unset(&value); } while (gtk_tree_model_iter_next (model, &iter)); } } @@ -751,10 +751,10 @@ int export_to_file(const char*filename, const struct mem_t flash_mem) { printf("%s\n", filename); FILE * f=fopen(filename, "w"); - if(f==NULL) + if (f==NULL) return -1; - for(gsize i=0;iflash_mem)!=0) + if (export_to_file (filename, gui->flash_mem)!=0) stlink_gui_set_info_error_message(gui, "Failed to export flash"); else stlink_gui_set_info_error_message(gui, "Export successful"); @@ -886,7 +886,7 @@ stlink_gui_init_dnd (STlinkGUI *gui) { "text/uri-list", 0, TARGET_FILENAME }, }; - gtk_drag_dest_set (GTK_WIDGET (gui->window), + gtk_drag_dest_set(GTK_WIDGET (gui->window), GTK_DEST_DEFAULT_ALL, target_list, G_N_ELEMENTS (target_list), diff --git a/src/usb.c b/src/usb.c index 970d3ee81..206600f14 100644 --- a/src/usb.c +++ b/src/usb.c @@ -144,7 +144,7 @@ static int fill_command unsigned char* const cmd = sl->c_buf; int i = 0; memset(cmd, 0, sizeof (sl->c_buf)); - if(slu->protocoll == 1) { + if (slu->protocoll == 1) { cmd[i++] = 'U'; cmd[i++] = 'S'; cmd[i++] = 'B'; @@ -651,7 +651,7 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { } sl->q_len = (int) size; stlink_print_data(sl); - for(i=0; i<16; i++) + 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); @@ -1049,7 +1049,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST } if (reset) { - if( sl->version.stlink_v > 1 ) stlink_jtag_reset(sl, 2); + if ( sl->version.stlink_v > 1)stlink_jtag_reset(sl, 2); stlink_reset(sl); usleep(10000); } diff --git a/tests/flash.c b/tests/flash.c index b17aa99ae..d193666ff 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -15,12 +15,12 @@ struct Test { }; static bool cmp_strings(const char * s1, const char * s2) { - if(s1 == NULL || s2 == NULL) return (s1 == s2); + if (s1 == NULL || s2 == NULL) return (s1 == s2); else return (0 == strcmp(s1, s2)); } static bool cmp_mem(const uint8_t * s1, const uint8_t * s2, size_t size) { - if(s1 == NULL || s2 == NULL) return (s1 == s2); + if (s1 == NULL || s2 == NULL) return (s1 == s2); else return (0 == memcmp(s1, s2, size)); } @@ -36,8 +36,8 @@ static bool execute_test(const struct Test * test) { #endif strcpy(cmd_line, test->cmd_line); - for(char * tok = strtok(cmd_line, " "); tok; tok = strtok(NULL, " ")) { - if((size_t)ac >= sizeof(av)/sizeof(av[0])) return false; + for (char * tok = strtok(cmd_line, " "); tok; tok = strtok(NULL, " ")) { + if ((size_t)ac >= sizeof(av)/sizeof(av[0])) return false; av[ac] = tok; ++ac; @@ -50,7 +50,7 @@ static bool execute_test(const struct Test * test) { // compare results bool ret = (res == test->res); - if(ret && (res == 0)) { + if (ret && (res == 0)) { ret &= (opts.cmd == test->opts.cmd); ret &= cmp_strings(opts.devname, test->opts.devname); ret &= cmp_mem(opts.serial, test->opts.serial, sizeof(opts.serial)); @@ -104,8 +104,8 @@ static struct Test tests[] = { int main() { bool allOk = true; - for(size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) { - if(!execute_test(&tests[i])) allOk = false; + for (size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) { + if (!execute_test(&tests[i])) allOk = false; } return (allOk ? 0 : 1); From ee4a52288a68126f3c74fee7d3413fa5ee9900bd Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Mon, 6 Apr 2020 14:32:34 +0200 Subject: [PATCH 0822/1435] st-flash: print proper error in case of option byte read error. User could get a wrong "stlink_fread()" error in case of bad stlink_read_option_foo.. --- src/tools/flash.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/tools/flash.c b/src/tools/flash.c index f39b6c6e4..6e7b37103 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -218,6 +218,10 @@ int main(int ac, char** av) printf("%x\n",option_byte); } else { printf("This format is available for STM32F2 and STM32F4 only\n"); + if (err == -1) + { + printf("could not read option bytes\n"); + goto on_error; } } else { if ((o.addr >= sl->flash_base) && (o.size == 0) && @@ -229,11 +233,12 @@ int main(int ac, char** av) o.size = sl->sram_size; } err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); - } - if (err == -1) - { - printf("stlink_fread() == -1\n"); - goto on_error; + + if (err == -1) + { + printf("stlink_fread() == -1\n"); + goto on_error; + } } } From 8430a6e6fa7d507fa5a19ef2552f3ae5422aa24e Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Mon, 6 Apr 2020 14:01:35 +0200 Subject: [PATCH 0823/1435] add read, write option byte for g4 and g0 use g0 code, same logic with different base address. also cleanup some duplicate lock/unlock code. --- include/stlink.h | 1 + include/stm32.h | 1 + src/common.c | 57 +++++++++++++++++++++++++++-------------------- src/tools/flash.c | 9 +++++--- 4 files changed, 41 insertions(+), 27 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 508b50f7d..a21874454 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -236,6 +236,7 @@ typedef struct flash_loader { int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); int stlink_load_device_params(stlink_t *sl); + int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte); int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte); int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte); diff --git a/include/stm32.h b/include/stm32.h index 9a01baaf4..890d11254 100644 --- a/include/stm32.h +++ b/include/stm32.h @@ -15,6 +15,7 @@ #define STM32_FLASH_BASE ((uint32_t)0x08000000) #define STM32_SRAM_BASE ((uint32_t)0x20000000) #define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) +#define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) #define STM32_L0_CAT2_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) #define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) #define STM32_L496X_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) diff --git a/src/common.c b/src/common.c index e94240351..332b9125d 100644 --- a/src/common.c +++ b/src/common.c @@ -2736,7 +2736,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t len) { +static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, uint32_t len) { uint32_t val; @@ -2750,25 +2750,16 @@ static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t l /* Check if chip is supported and for correct address */ if (sl->chip_id != STLINK_CHIPID_STM32_G0_CAT1 && - sl->chip_id != STLINK_CHIPID_STM32_G0_CAT2) { - ELOG("Option bytes writing is currently only supported for the STM32G0\n"); + sl->chip_id != STLINK_CHIPID_STM32_G0_CAT2 && + sl->chip_id != STLINK_CHIPID_STM32_G4_CAT2 && + sl->chip_id != STLINK_CHIPID_STM32_G4_CAT3) { + ELOG("Option bytes writing is currently only supported for the STM32G0/G4\n"); return -1; } - /* Unlock flash if necessary (ref manuel page 52) */ - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - if ((val & (1u << STM32Gx_FLASH_CR_LOCK))) { - - /* disable flash write protection. */ - stlink_write_debug32(sl, STM32Gx_FLASH_KEYR, 0x45670123); - stlink_write_debug32(sl, STM32Gx_FLASH_KEYR, 0xCDEF89AB); - - // check that the lock is no longer set. - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - if ((val & (1u << STM32Gx_FLASH_CR_LOCK))) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; } /* Unlock option bytes if necessary (ref manuel page 61) */ @@ -2802,7 +2793,9 @@ static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t l /* Wait for 'busy' bit in FLASH_SR to clear. */ do { stlink_read_debug32(sl, STM32Gx_FLASH_SR, &val); - } while ((val & (1 << 16)) != 0); + } while ((val & (1 << STM32Gx_FLASH_SR_BSY)) != 0); + + check_flash_error(sl); /* apply options bytes immediate */ stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); @@ -2813,10 +2806,9 @@ static int stlink_write_option_bytes_g0x(stlink_t *sl, uint8_t* base, uint32_t l stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); val |= (1u << STM32Gx_FLASH_CR_OPTLOCK); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + /* Re-lock flash. */ - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1u << STM32Gx_FLASH_CR_LOCK); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + lock_flash(sl); return 0; } @@ -3147,6 +3139,19 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint32_t option_byte) { return 0; } +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) +{ + uint32_t ret = stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); + WLOG("option bytes CR = %#010x\n", *option_byte); + return ret; +} + /** * Read option bytes * @param sl @@ -3183,7 +3188,7 @@ int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { /** * Read option bytes * @param sl - * @param option_byte value to write + * @param option_byte value to read * @return 0 on success, -ve on failure. */ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { @@ -3230,9 +3235,13 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui /* Check if chip is supported and for correct address */ if (((sl->chip_id == STLINK_CHIPID_STM32_G0_CAT1) || (sl->chip_id == STLINK_CHIPID_STM32_G0_CAT2)) && (addr == STM32_G0_OPTION_BYTES_BASE)) { - return stlink_write_option_bytes_g0x(sl, base, len); + return stlink_write_option_bytes_gx(sl, base, len); + } + else if (((sl->chip_id == STLINK_CHIPID_STM32_G4_CAT2) || + (sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3)) && (addr == STM32_G4_OPTION_BYTES_BASE)) { + return stlink_write_option_bytes_gx(sl, base, len); } - else if ((sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) && (addr == STM32_L0_CAT2_OPTION_BYTES_BASE)) { + else if((sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) && (addr == STM32_L0_CAT2_OPTION_BYTES_BASE)) { return stlink_write_option_bytes_l0_cat2(sl, base, len); } else if ((sl->chip_id == STLINK_CHIPID_STM32_L496X) && (addr == STM32_L496X_OPTION_BYTES_BASE)) { diff --git a/src/tools/flash.c b/src/tools/flash.c index 6e7b37103..e211a2e81 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -208,16 +208,19 @@ int main(int ac, char** av) else /* read */ { if (o.area == FLASH_OPTION_BYTES){ + uint32_t option_byte = 0; if (sl->chip_id == STLINK_CHIPID_STM32_F2){ - uint32_t option_byte = 0; err = stlink_read_option_bytes_f2(sl,&option_byte); printf("%x\n",option_byte); } else if (sl->chip_id == STLINK_CHIPID_STM32_F446){ - uint32_t option_byte = 0; err = stlink_read_option_bytes_f4(sl,&option_byte); printf("%x\n",option_byte); + }else if(sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { + err = stlink_read_option_bytes_Gx(sl,&option_byte); + printf("%x\n",option_byte); } else { - printf("This format is available for STM32F2 and STM32F4 only\n"); + printf("This format is only available for STM32F2, STM32F4, STM32G0 and STM32G4\n"); + } if (err == -1) { printf("could not read option bytes\n"); From 1801fb1f005a93756ea566cb0cdb658611982f99 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Tue, 14 Apr 2020 15:03:19 +0200 Subject: [PATCH 0824/1435] flash.c: move device specific read option stuff to common.c --- include/stlink.h | 9 ++++----- src/common.c | 20 ++++++++++++++++++++ src/tools/flash.c | 26 ++++++++------------------ 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index a21874454..078251cf8 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -213,8 +213,6 @@ typedef struct flash_loader { uint8_t stlink_get_erased_pattern(stlink_t *sl); int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); - int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); - int stlink_fwrite_option_bytes_32bit(stlink_t *sl,uint32_t val); int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, 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); @@ -236,9 +234,10 @@ typedef struct flash_loader { int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); int stlink_load_device_params(stlink_t *sl); - int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte); - int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte); - int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte); + + int stlink_read_option_bytes(stlink_t *sl, uint32_t* option_byte); + int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); + int stlink_fwrite_option_bytes_32bit(stlink_t *sl,uint32_t val); #include "stlink/sg.h" #include "stlink/usb.h" diff --git a/src/common.c b/src/common.c index 332b9125d..00d982593 100644 --- a/src/common.c +++ b/src/common.c @@ -3218,6 +3218,26 @@ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { return 0; } +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes(stlink_t *sl, uint32_t* option_byte) { + int err = -1; + if (sl->chip_id == STLINK_CHIPID_STM32_F2){ + err = stlink_read_option_bytes_f2(sl, option_byte); + }else if(sl->chip_id == STLINK_CHIPID_STM32_F446){ + err = stlink_read_option_bytes_f4(sl, option_byte); + }else if(sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { + err = stlink_read_option_bytes_Gx(sl, option_byte); + }else{ + ELOG("This format is only available for STM32F2, STM32F4, STM32G0 and STM32G4\n"); + } + return err; +} + /** * Write option bytes * @param sl diff --git a/src/tools/flash.c b/src/tools/flash.c index e211a2e81..06256823c 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -207,26 +207,16 @@ int main(int ac, char** av) } else /* read */ { - if (o.area == FLASH_OPTION_BYTES){ - uint32_t option_byte = 0; - if (sl->chip_id == STLINK_CHIPID_STM32_F2){ - err = stlink_read_option_bytes_f2(sl,&option_byte); + if(o.area == FLASH_OPTION_BYTES){ + uint32_t option_byte; + err = stlink_read_option_bytes(sl, &option_byte); + if (err == -1) { + printf("could not read option bytes (%d)\n", err); + goto on_error; + } else { printf("%x\n",option_byte); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F446){ - err = stlink_read_option_bytes_f4(sl,&option_byte); - printf("%x\n",option_byte); - }else if(sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { - err = stlink_read_option_bytes_Gx(sl,&option_byte); - printf("%x\n",option_byte); - } else { - printf("This format is only available for STM32F2, STM32F4, STM32G0 and STM32G4\n"); - } - if (err == -1) - { - printf("could not read option bytes\n"); - goto on_error; } - } else { + }else{ if ((o.addr >= sl->flash_base) && (o.size == 0) && (o.addr < sl->flash_base + sl->flash_size)){ o.size = sl->flash_size; From 2aeae8d85f74b00aeb64cfcf5c4d644f8fbecf08 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Tue, 14 Apr 2020 16:30:58 +0200 Subject: [PATCH 0825/1435] chipid: add option bytes info to chip db --- include/stlink.h | 4 ++++ include/stlink/chipid.h | 2 ++ src/common.c | 2 ++ 3 files changed, 8 insertions(+) diff --git a/include/stlink.h b/include/stlink.h index 078251cf8..f22abbb42 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -170,6 +170,10 @@ typedef struct flash_loader { stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() size_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() + /* option settings */ + stm32_addr_t option_base; + size_t option_size; + // bootloader // sys_base and sys_size are not used by the tools, but are only there to // download the bootloader code (see tests/sg.c) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index d23596c0d..64227962b 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -79,6 +79,8 @@ struct stlink_chipid_params { uint32_t sram_size; uint32_t bootrom_base; uint32_t bootrom_size; + uint32_t option_base; + uint32_t option_size; }; const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); diff --git a/src/common.c b/src/common.c index 00d982593..4525d0222 100644 --- a/src/common.c +++ b/src/common.c @@ -920,6 +920,8 @@ int stlink_load_device_params(stlink_t *sl) { sl->sram_size = params->sram_size; sl->sys_base = params->bootrom_base; sl->sys_size = params->bootrom_size; + sl->option_base = params->option_base; + sl->option_size = params->option_size; //medium and low devices have the same chipid. ram size depends on flash size. //STM32F100xx datasheet Doc ID 16455 Table 2 From 92ceb7f35a667637b574924be9d43f70e6073eb3 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Tue, 14 Apr 2020 16:33:15 +0200 Subject: [PATCH 0826/1435] chipid: insert data for supported chips, from common.c --- src/chipid.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/chipid.c b/src/chipid.c index b9d3933f0..5d43c3ab0 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -175,7 +175,9 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x100, .sram_size = 0xC000, /*Not completely clear if there are some with 32K*/ .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 + .bootrom_size = 0x1000, + .option_base = STM32_L1_OPTION_BYTES_BASE, + .option_size = 8, }, { .chip_id = STLINK_CHIPID_STM32_L152_RE, @@ -400,7 +402,9 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x80, .sram_size = 0x2000, .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000 + .bootrom_size = 0x1000, + .option_base = STM32_L0_CAT2_OPTION_BYTES_BASE, + .option_size = 4, }, { // STM32F334, STM32F303x6/8, and STM32F328 @@ -494,7 +498,9 @@ static const struct stlink_chipid_params devices[] = { // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) - .bootrom_size = 0x7000 // 28k (per bank), same source as base + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L496X_OPTION_BYTES_BASE, + .option_size = 4, }, { // STLINK_CHIPID_STM32_L46X @@ -530,7 +536,9 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, // 2K (sec 3.2) .sram_size = 0x2000, // 8K (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x2000 // 8K (sec 2.2.2 table 3) + .bootrom_size = 0x2000, // 8K (sec 2.2.2 table 3) + .option_base = STM32_G4_OPTION_BYTES_BASE, + .option_size = 4, }, { // STM32G071/081 (from RM0444) @@ -541,7 +549,9 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, // 2K (sec 3.2) .sram_size = 0x9000, // 36K (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000 // 28K (sec 2.2.2 table 2) + .bootrom_size = 0x7000, // 28K (sec 2.2.2 table 2) + .option_base = STM32_G0_OPTION_BYTES_BASE, + .option_size = 4, }, { // STM32G431/441 (from RM0440) @@ -555,7 +565,10 @@ static const struct stlink_chipid_params devices[] = { // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 .sram_size = 0x8000, // 32K (sec 2.4) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000 // 28K (table 2) + .bootrom_size = 0x7000, // 28K (table 2) + .option_base = STM32_G4_OPTION_BYTES_BASE, + .option_size = 4*4, + }, { // STM32G471/473/474/483/484 (from RM0440) @@ -570,7 +583,9 @@ static const struct stlink_chipid_params devices[] = { // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 .sram_size = 0x18000, // 128K (sec 2.4) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000 // 28K (table 2) + .bootrom_size = 0x7000, // 28K (table 2) + .option_base = STM32_G4_OPTION_BYTES_BASE, + .option_size = 4*4, }, { // STM32WB55 (from RM0434) From 6f0795d931500d556420e27e2d62683a336c1fd2 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Tue, 14 Apr 2020 17:35:15 +0200 Subject: [PATCH 0827/1435] chipid: add some l0 and l4 option info to allow option byte read --- include/stlink/chipid.h | 2 +- include/stm32.h | 4 ++-- src/chipid.c | 26 +++++++++++++++++--------- src/common.c | 2 +- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 64227962b..98164a8fc 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -57,7 +57,7 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F72XXX = 0x452, /* This ID is found on the NucleoF722ZE board */ STLINK_CHIPID_STM32_L011 = 0x457, STLINK_CHIPID_STM32_F410 = 0x458, - STLINK_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/081 */ + STLINK_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/081 */ STLINK_CHIPID_STM32_F413 = 0x463, STLINK_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/041 */ STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* See: RM 0440 s46.6.1 "MCU device ID code" */ diff --git a/include/stm32.h b/include/stm32.h index 890d11254..c71718653 100644 --- a/include/stm32.h +++ b/include/stm32.h @@ -16,9 +16,9 @@ #define STM32_SRAM_BASE ((uint32_t)0x20000000) #define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) -#define STM32_L0_CAT2_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) +#define STM32_L0_CATx_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) #define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) -#define STM32_L496X_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) +#define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) #endif /* STM32_H */ diff --git a/src/chipid.c b/src/chipid.c index 5d43c3ab0..bc3d37567 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -378,7 +378,9 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x80, .sram_size = 0x2000, .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000 + .bootrom_size = 0x1000, + .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, + .option_size = 4, }, { // STM32L0x Category 5 @@ -390,7 +392,9 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x80, .sram_size = 0x5000, .bootrom_base = 0x1ff0000, - .bootrom_size = 0x2000 + .bootrom_size = 0x2000, + .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, + .option_size = 4, }, { // STM32L0x Category 2 @@ -403,7 +407,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x2000, .bootrom_base = 0x1ff0000, .bootrom_size = 0x1000, - .option_base = STM32_L0_CAT2_OPTION_BYTES_BASE, + .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, .option_size = 4, }, { @@ -443,7 +447,9 @@ static const struct stlink_chipid_params devices[] = { // sizes; table 2, page 74 for SRAM2 location) .sram_size = 0x18000, .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000 // 28k (per bank), same source as base + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, }, { // STM32L4RX @@ -484,7 +490,9 @@ static const struct stlink_chipid_params devices[] = { // sizes; table 2, page 74 for SRAM2 location) .sram_size = 0xc000, .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000 // 28k (per bank), same source as base + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, }, { // STLINK_CHIPID_STM32_L496X @@ -499,7 +507,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L496X_OPTION_BYTES_BASE, + .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, }, { @@ -537,8 +545,8 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x2000, // 8K (sec 2.3) .bootrom_base = 0x1fff0000, .bootrom_size = 0x2000, // 8K (sec 2.2.2 table 3) - .option_base = STM32_G4_OPTION_BYTES_BASE, - .option_size = 4, + .option_base = STM32_G0_OPTION_BYTES_BASE, + .option_size = 8*4, }, { // STM32G071/081 (from RM0444) @@ -551,7 +559,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7000, // 28K (sec 2.2.2 table 2) .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 4, + .option_size = 8*4, }, { // STM32G431/441 (from RM0440) diff --git a/src/common.c b/src/common.c index 4525d0222..351c74497 100644 --- a/src/common.c +++ b/src/common.c @@ -2863,7 +2863,7 @@ static int stlink_write_option_bytes_l0_cat2(stlink_t *sl, uint8_t* base, uint32 uint32_t data; write_uint32((unsigned char*) &data, *(uint32_t*) (base)); WLOG("Writing option bytes 0x%04x\n", data); - stlink_write_debug32(sl, STM32_L0_CAT2_OPTION_BYTES_BASE, data); + stlink_write_debug32(sl, STM32_L0_CATx_OPTION_BYTES_BASE, data); /* Reload options */ stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); From 72cfd5ee20658cbd9a4cefd01e0099b461018822 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Tue, 14 Apr 2020 15:32:47 +0200 Subject: [PATCH 0828/1435] option: refactor option flash code. unify option bytes read/write, interface, use chipid db to store size and base to provide some write sanity check and generic option read code. --- include/stlink.h | 6 +- src/chipid.c | 8 +- src/common.c | 195 +++++++++++++++++++++++++--------------------- src/tools/flash.c | 12 +-- 4 files changed, 119 insertions(+), 102 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index f22abbb42..db737acb0 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -239,9 +239,11 @@ typedef struct flash_loader { int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); int stlink_load_device_params(stlink_t *sl); - int stlink_read_option_bytes(stlink_t *sl, uint32_t* option_byte); + int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); + int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); + + int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); - int stlink_fwrite_option_bytes_32bit(stlink_t *sl,uint32_t val); #include "stlink/sg.h" #include "stlink/usb.h" diff --git a/src/chipid.c b/src/chipid.c index bc3d37567..60d0787e9 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -546,7 +546,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, .bootrom_size = 0x2000, // 8K (sec 2.2.2 table 3) .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 8*4, + .option_size = 4, }, { // STM32G071/081 (from RM0444) @@ -559,7 +559,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7000, // 28K (sec 2.2.2 table 2) .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 8*4, + .option_size = 4, }, { // STM32G431/441 (from RM0440) @@ -575,7 +575,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7000, // 28K (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, - .option_size = 4*4, + .option_size = 4, }, { @@ -593,7 +593,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, .bootrom_size = 0x7000, // 28K (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, - .option_size = 4*4, + .option_size = 4, }, { // STM32WB55 (from RM0434) diff --git a/src/common.c b/src/common.c index 351c74497..66d21b2b4 100644 --- a/src/common.c +++ b/src/common.c @@ -2738,26 +2738,12 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, uint32_t len) { +static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { uint32_t val; - if (len != 4) { - ELOG("Wrong length for writing option bytes, must be 4 is %d\n", len); - return -1; - } - - // Make sure we've loaded the context with the chip details - stlink_core_id(sl); - - /* Check if chip is supported and for correct address */ - if (sl->chip_id != STLINK_CHIPID_STM32_G0_CAT1 && - sl->chip_id != STLINK_CHIPID_STM32_G0_CAT2 && - sl->chip_id != STLINK_CHIPID_STM32_G4_CAT2 && - sl->chip_id != STLINK_CHIPID_STM32_G4_CAT3) { - ELOG("Option bytes writing is currently only supported for the STM32G0/G4\n"); - return -1; - } + (void) addr; + (void) len; if (unlock_flash_if(sl)) { ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); @@ -2783,7 +2769,7 @@ static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, uint32_t le /* Write options bytes */ uint32_t data; write_uint32((unsigned char*) &data, *(uint32_t*) (base)); - WLOG("Writing option bytes 0x%04x\n", data); + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); //stlink_write_debug32(sl, addr, data); stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); @@ -2823,14 +2809,12 @@ static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, uint32_t le * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l0_cat2(stlink_t *sl, uint8_t* base, uint32_t len) { +static int stlink_write_option_bytes_l0_cat2(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { uint32_t val; + (void) addr; + (void) len; - if (len != 4) { - ELOG("Wrong length for writting option bytes, must be 4 is %d\n", len); - return -1; - } stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); if (val & STM32L0_FLASH_PELOCK_BIT) { WLOG("Unlocking flash\n"); @@ -2885,10 +2869,6 @@ static int stlink_write_option_bytes_l1(stlink_t *sl, uint8_t* base, stm32_addr_ uint32_t val; uint32_t data; - if (len != 4 && len != 8) { - ELOG("Wrong length for writting option bytes, must be 4 or 8 is %d\n", len); - return -1; - } stlink_read_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); if (val & STM32L1_FLASH_PELOCK_BIT) { WLOG("Unlocking flash\n"); @@ -2966,14 +2946,12 @@ static int stlink_write_option_bytes_l1(stlink_t *sl, uint8_t* base, stm32_addr_ * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l496x(stlink_t *sl, uint8_t* base, uint32_t len) { +static int stlink_write_option_bytes_l496x(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { uint32_t val; - if (len != 4) { - ELOG("Wrong length for writting option bytes, must be 4 is %d\n", len); - return -1; - } + (void) addr; + (void) len; /* Unlock flash if necessary */ stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); @@ -3047,8 +3025,18 @@ static int stlink_write_option_bytes_l496x(stlink_t *sl, uint8_t* base, uint32_t * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f2(stlink_t *sl, uint32_t option_byte) { +static int stlink_write_option_bytes_f2(stlink_t *sl, uint8_t *base, stm32_addr_t addr, size_t len) { uint32_t val; + uint32_t option_byte; + + (void) addr; /* todo: add sanitary check */ + + if(len != 4) { + ELOG("Wrong length for writting option bytes, must be 4 is %d\n", len); + return -1; + } + + option_byte = *(uint32_t*) (base); stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); if (val & FLASH_F2_OPT_LOCK_BIT) { @@ -3097,8 +3085,18 @@ static int stlink_write_option_bytes_f2(stlink_t *sl, uint32_t option_byte) { * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f4(stlink_t *sl, uint32_t option_byte) { +static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { uint32_t val; + uint32_t option_byte; + + (void) addr; /* todo: add sanitary check */ + + if(len != 4) { + ELOG("Wrong length for writing option bytes, must be 4 is %d\n", len); + return -1; + } + + option_byte = *(uint32_t*) (base); stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); if (val & FLASH_F4_OPT_LOCK_BIT) { @@ -3219,25 +3217,54 @@ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { return 0; } +/** +* Read first option bytes +* @param sl +* @param option_byte option value +* @return 0 on success, -ve on failure. +*/ +int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) +{ + return stlink_read_debug32(sl, sl->option_base, option_byte); +} /** * Read option bytes * @param sl - * @param option_byte value to read + * @param option_byte option value * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes(stlink_t *sl, uint32_t* option_byte) { - int err = -1; - if (sl->chip_id == STLINK_CHIPID_STM32_F2){ - err = stlink_read_option_bytes_f2(sl, option_byte); - }else if(sl->chip_id == STLINK_CHIPID_STM32_F446){ - err = stlink_read_option_bytes_f4(sl, option_byte); - }else if(sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { - err = stlink_read_option_bytes_Gx(sl, option_byte); - }else{ - ELOG("This format is only available for STM32F2, STM32F4, STM32G0 and STM32G4\n"); +int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) +{ + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F2: + return stlink_read_option_bytes_f2(sl, option_byte); + case STLINK_CHIPID_STM32_F446: + return stlink_read_option_bytes_f4(sl, option_byte); + case STLINK_CHIPID_STM32_G0_CAT1: + case STLINK_CHIPID_STM32_G0_CAT2: + case STLINK_CHIPID_STM32_G4_CAT2: + case STLINK_CHIPID_STM32_G4_CAT3: + return stlink_read_option_bytes_Gx(sl, option_byte); + default: + return stlink_read_option_bytes_generic(sl, option_byte); } - return err; +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) +{ + WLOG("About to write option byte %#10x to target.\n", option_byte); + return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *) &option_byte, 4); } /** @@ -3247,34 +3274,42 @@ int stlink_read_option_bytes(stlink_t *sl, uint32_t* option_byte) { * @param base option bytes to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) +{ + if (sl->option_base == 0) { + ELOG("Option bytes writing is currently not supported for connected chip\n"); + return -1; + } - // Make sure we've loaded the context with the chip details - stlink_core_id(sl); + if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { + ELOG("Option bytes start address out of Option bytes range\n"); + return -1; + } - WLOG("Option bytes write chip_id 0x%08x addr 0x%08x\n",sl->chip_id,addr); + if (addr + len > sl->option_base + sl->option_size) { + ELOG("Option bytes data too long\n"); + return -1; + } - /* Check if chip is supported and for correct address */ - if (((sl->chip_id == STLINK_CHIPID_STM32_G0_CAT1) || - (sl->chip_id == STLINK_CHIPID_STM32_G0_CAT2)) && (addr == STM32_G0_OPTION_BYTES_BASE)) { - return stlink_write_option_bytes_gx(sl, base, len); - } - else if (((sl->chip_id == STLINK_CHIPID_STM32_G4_CAT2) || - (sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3)) && (addr == STM32_G4_OPTION_BYTES_BASE)) { - return stlink_write_option_bytes_gx(sl, base, len); - } - else if((sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) && (addr == STM32_L0_CAT2_OPTION_BYTES_BASE)) { - return stlink_write_option_bytes_l0_cat2(sl, base, len); - } - else if ((sl->chip_id == STLINK_CHIPID_STM32_L496X) && (addr == STM32_L496X_OPTION_BYTES_BASE)) { - return stlink_write_option_bytes_l496x(sl, base, len); - } - else if (((sl->chip_id == STLINK_CHIPID_STM32_L152_RE) || (sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH) ) && - ((addr == STM32_L1_OPTION_BYTES_BASE) || (addr == STM32_L1_OPTION_BYTES_BASE+4))) { + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F2: + return stlink_write_option_bytes_f2(sl, base, addr, len); + case STLINK_CHIPID_STM32_F446: + return stlink_write_option_bytes_f4(sl, base, addr, len); + case STLINK_CHIPID_STM32_L0_CAT2: + return stlink_write_option_bytes_l0_cat2(sl, base, addr, len); + case STLINK_CHIPID_STM32_L496X: + return stlink_write_option_bytes_l496x(sl, base, addr, len); + case STLINK_CHIPID_STM32_L152_RE: + case STLINK_CHIPID_STM32_L1_HIGH: return stlink_write_option_bytes_l1(sl, base, addr, len); - } - else { - ELOG("Option bytes writing is currently only supported for the STM32F2, STM32G0, STM32L496x/L4A6x, STM32L1 and STM32L0\n"); + case STLINK_CHIPID_STM32_G0_CAT1: + case STLINK_CHIPID_STM32_G0_CAT2: + case STLINK_CHIPID_STM32_G4_CAT2: + case STLINK_CHIPID_STM32_G4_CAT3: + return stlink_write_option_bytes_gx(sl, base, addr, len); + default: + ELOG("Option bytes writing is currently not implemented for connected chip\n"); return -1; } @@ -3306,23 +3341,3 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr unmap_file(&mf); return err; } - -/** - * Write the given 32-bit value with option byte - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_fwrite_option_bytes_32bit(stlink_t *sl, uint32_t val) { - - if (sl->chip_id == STLINK_CHIPID_STM32_F2){ - return stlink_write_option_bytes_f2(sl, val); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F446){ - return stlink_write_option_bytes_f4(sl, val); - } - else - { - ELOG("Option bytes writing is currently only supported for the STM32F2, STM32F4, STM32G0 and STM32L0\n"); - return -1; - } -} diff --git a/src/tools/flash.c b/src/tools/flash.c index 06256823c..20fbacd9a 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -160,9 +160,8 @@ int main(int ac, char** av) goto on_error; } } - else if (o.addr == STM32_G0_OPTION_BYTES_BASE || - o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE || - o.addr == STM32_L0_CAT2_OPTION_BYTES_BASE + 4){ + else if ((o.addr >= sl->option_base) && + (o.addr < sl->option_base + sl->option_size)) { err = stlink_fwrite_option_bytes(sl, o.filename, o.addr); if (err == -1) { @@ -171,10 +170,11 @@ int main(int ac, char** av) } } else if (o.area == FLASH_OPTION_BYTES){ - err = stlink_fwrite_option_bytes_32bit(sl, o.val); + // XXX some sanity check should be done here to check o.val parsing. + err = stlink_write_option_bytes32(sl, o.val); if (err == -1) { - printf("stlink_fwrite_option_bytes() == -1\n"); + printf("stlink_write_option_bytes32() == -1\n"); goto on_error; } } @@ -209,7 +209,7 @@ int main(int ac, char** av) { if(o.area == FLASH_OPTION_BYTES){ uint32_t option_byte; - err = stlink_read_option_bytes(sl, &option_byte); + err = stlink_read_option_bytes32(sl, &option_byte); if (err == -1) { printf("could not read option bytes (%d)\n", err); goto on_error; From e146a28a67cdfea1d4e9b5bf76471e05fe692494 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Tue, 14 Apr 2020 19:01:05 +0200 Subject: [PATCH 0829/1435] st-flash: add sanity check to option flash. current opt parse code can make bad cmdline parameter attempt to flash bad flash option. ie: calling st-flash write --area=option a_file.bin will make parser attempt to translate "a_file.bon" to an uint32 and will return 0.., --- src/tools/flash.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tools/flash.c b/src/tools/flash.c index 20fbacd9a..e91001659 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -170,7 +170,11 @@ int main(int ac, char** av) } } else if (o.area == FLASH_OPTION_BYTES){ - // XXX some sanity check should be done here to check o.val parsing. + if (o.val == 0) { + printf("attempting to set option byte to 0, abort.\n"); + goto on_error; + } + err = stlink_write_option_bytes32(sl, o.val); if (err == -1) { From 3aaec273da217faf54601c02480ce990baa09894 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Thu, 16 Apr 2020 15:12:40 +0200 Subject: [PATCH 0830/1435] common.c: fix define - use Gx Base for Gx defines avoid some potential issues later. --- src/common.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/common.c b/src/common.c index 66d21b2b4..0ccdeccdb 100644 --- a/src/common.c +++ b/src/common.c @@ -79,13 +79,13 @@ // Flash registers common to STM32G0 and STM32G4 series. #define STM32Gx_FLASH_REGS_ADDR ((uint32_t)0x40022000) -#define STM32Gx_FLASH_ACR (STM32G0_FLASH_REGS_ADDR + 0x00) -#define STM32Gx_FLASH_KEYR (STM32G0_FLASH_REGS_ADDR + 0x08) -#define STM32Gx_FLASH_OPTKEYR (STM32G0_FLASH_REGS_ADDR + 0x0c) -#define STM32Gx_FLASH_SR (STM32G0_FLASH_REGS_ADDR + 0x10) -#define STM32Gx_FLASH_CR (STM32G0_FLASH_REGS_ADDR + 0x14) -#define STM32Gx_FLASH_ECCR (STM32G0_FLASH_REGS_ADDR + 0x18) -#define STM32Gx_FLASH_OPTR (STM32G0_FLASH_REGS_ADDR + 0x20) +#define STM32Gx_FLASH_ACR (STM32Gx_FLASH_REGS_ADDR + 0x00) +#define STM32Gx_FLASH_KEYR (STM32Gx_FLASH_REGS_ADDR + 0x08) +#define STM32Gx_FLASH_OPTKEYR (STM32Gx_FLASH_REGS_ADDR + 0x0c) +#define STM32Gx_FLASH_SR (STM32Gx_FLASH_REGS_ADDR + 0x10) +#define STM32Gx_FLASH_CR (STM32Gx_FLASH_REGS_ADDR + 0x14) +#define STM32Gx_FLASH_ECCR (STM32Gx_FLASH_REGS_ADDR + 0x18) +#define STM32Gx_FLASH_OPTR (STM32Gx_FLASH_REGS_ADDR + 0x20) // G0 (RM0444 Table 1, sec 3.7) // Mostly the same as G4 chips, but the notation From 977576215e64b9b138fff890f8fbf52d17572e4d Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 16 Apr 2020 21:00:30 +0200 Subject: [PATCH 0831/1435] Partial project restructuring - Updated travis CI build config - Refactoring of cmake build config - Alligned coding style for GUI - Whitespace cleanup for GUI - Moved source code for GUI --- .travis.sh | 13 +- .travis.yml | 24 +- CMakeLists.txt | 48 +- cmake/c_flag_overrides.cmake | 7 - {usr/lib => debian}/pkgconfig/CMakeLists.txt | 0 .../pkgconfig/pkg-config.pc.cmake | 0 src/{tools/gui => stlink-gui}/CMakeLists.txt | 21 +- .../gui/stlink-gui.c => stlink-gui/gui.c} | 625 +++++++----------- .../gui/stlink-gui.h => stlink-gui/gui.h} | 6 +- .../gui/stlink-gui.ui => stlink-gui/gui.ui} | 0 src/stlink-gui/icons/export-icons.sh | 40 ++ .../hicolor/128x128/apps/stlink-gui.png | Bin .../icons}/hicolor/16x16/apps/stlink-gui.png | Bin .../icons}/hicolor/22x22/apps/stlink-gui.png | Bin .../icons}/hicolor/24x24/apps/stlink-gui.png | Bin .../hicolor/256x256/apps/stlink-gui.png | Bin .../icons}/hicolor/32x32/apps/stlink-gui.png | Bin .../icons}/hicolor/48x48/apps/stlink-gui.png | Bin .../icons}/hicolor/64x64/apps/stlink-gui.png | Bin .../art => stlink-gui/icons}/stlink-gui.png | Bin .../art => stlink-gui/icons}/stlink-gui.svg | 0 .../art => stlink-gui/icons}/stlink-gui.xpm | 0 .../icons}/stlink-gui_48.png | Bin .../gui => stlink-gui}/stlink-gui.desktop | 0 src/tools/gui/art/export-icons.sh | 38 -- 25 files changed, 324 insertions(+), 498 deletions(-) delete mode 100644 cmake/c_flag_overrides.cmake rename {usr/lib => debian}/pkgconfig/CMakeLists.txt (100%) rename {usr/lib => debian}/pkgconfig/pkg-config.pc.cmake (100%) rename src/{tools/gui => stlink-gui}/CMakeLists.txt (55%) rename src/{tools/gui/stlink-gui.c => stlink-gui/gui.c} (62%) rename src/{tools/gui/stlink-gui.h => stlink-gui/gui.h} (98%) rename src/{tools/gui/stlink-gui.ui => stlink-gui/gui.ui} (100%) create mode 100644 src/stlink-gui/icons/export-icons.sh rename src/{tools/gui/art => stlink-gui/icons}/hicolor/128x128/apps/stlink-gui.png (100%) rename src/{tools/gui/art => stlink-gui/icons}/hicolor/16x16/apps/stlink-gui.png (100%) rename src/{tools/gui/art => stlink-gui/icons}/hicolor/22x22/apps/stlink-gui.png (100%) rename src/{tools/gui/art => stlink-gui/icons}/hicolor/24x24/apps/stlink-gui.png (100%) rename src/{tools/gui/art => stlink-gui/icons}/hicolor/256x256/apps/stlink-gui.png (100%) rename src/{tools/gui/art => stlink-gui/icons}/hicolor/32x32/apps/stlink-gui.png (100%) rename src/{tools/gui/art => stlink-gui/icons}/hicolor/48x48/apps/stlink-gui.png (100%) rename src/{tools/gui/art => stlink-gui/icons}/hicolor/64x64/apps/stlink-gui.png (100%) rename src/{tools/gui/art => stlink-gui/icons}/stlink-gui.png (100%) rename src/{tools/gui/art => stlink-gui/icons}/stlink-gui.svg (100%) rename src/{tools/gui/art => stlink-gui/icons}/stlink-gui.xpm (100%) rename src/{tools/gui/art => stlink-gui/icons}/stlink-gui_48.png (100%) rename src/{tools/gui => stlink-gui}/stlink-gui.desktop (100%) delete mode 100755 src/tools/gui/art/export-icons.sh diff --git a/.travis.sh b/.travis.sh index 3d6da055f..5291ec95b 100755 --- a/.travis.sh +++ b/.travis.sh @@ -24,13 +24,12 @@ if [ "$TRAVIS_OS_NAME" == "linux" ]; then cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ make && make package && cd - - echo "--> Building Binary..." - mkdir -p build/Binary && cd build/Binary - cho "-DCMAKE_BUILD_TYPE=Binary -DCMAKE_INSTALL_PREFIX=$PWD/_install" - cmake -DCMAKE_BUILD_TYPE=Binary -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ - make && make package && cd - - -else #("$TRAVIS_OS_NAME" == "osx") +# echo "--> Building Binary..." +# mkdir -p build/Binary && cd build/Binary +# cho "-DCMAKE_BUILD_TYPE=Binary -DCMAKE_INSTALL_PREFIX=$PWD/_install" +# cmake -DCMAKE_BUILD_TYPE=Binary -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ +# make && make package && cd - +else [ "$TRAVIS_OS_NAME" == "osx" ]; brew install libusb echo "--> Building Debug..." diff --git a/.travis.yml b/.travis.yml index 221e8ece7..542a25d98 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,14 +38,14 @@ matrix: apt: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] packages: ['clang-6.0', 'libusb-1.0.0-dev'] - - os: linux - arch: x64 - compiler: clang-6.0 - addons: - apt: - sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] - packages: ['clang-6.0', 'libusb-1.0.0-dev'] - env: CFLAGS=-m32 LDFLAGS=-m32 +# - os: linux +# arch: x64 +# compiler: clang-6.0 +# addons: +# apt: +# sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] +# packages: ['clang-6.0', 'libusb-1.0.0-dev'] +# env: CFLAGS=-m32 LDFLAGS=-m32 ### 32-bit builds ### - os: linux @@ -57,18 +57,18 @@ matrix: packages: ['gcc-5', 'libusb-1.0.0-dev'] - os: linux arch: x86 - compiler: gcc-6 + compiler: gcc-7 addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-6', 'libusb-1.0.0-dev'] + packages: ['gcc-7', 'libusb-1.0.0-dev'] - os: linux arch: x86 - compiler: gcc-7 + compiler: gcc-9 addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-7', 'libusb-1.0.0-dev'] + packages: ['gcc-9', 'libusb-1.0.0-dev'] - os: linux arch: x86 compiler: clang-3.7 diff --git a/CMakeLists.txt b/CMakeLists.txt index 3572c2a15..87bd47aac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,24 @@ cmake_minimum_required(VERSION 3.4.2) -set(CMAKE_USER_MAKE_RULES_OVERRIDE cmake/c_flag_overrides.cmake) +cmake_policy(SET CMP0042 NEW) +set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") +include(GNUInstallDirs) project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics ST-LINK Tools") -include(GNUInstallDirs) + set(STLINK_UDEV_RULES_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/udev/rules.d" CACHE PATH "udev rules directory") set(STLINK_MODPROBED_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/modprobe.d" CACHE PATH "modprobe.d directory") set(STLINK_STATIC_LIB ON CACHE BOOL "Install static lib") -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +option(STLINK_INSTALL_UDEV_RULES "Install udev rules files" ON) +option(STLINK_INSTALL_MODPROBE_CONF "Install modprobe conf files" ON) +option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) + +# ==== + +#set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) if (IS_DIRECTORY ${LIB_INSTALL_DIR}) set(LIB_INSTALL_DIR ${LIB_INSTALL_DIR} CACHE PATH "Main library directory") @@ -28,17 +36,16 @@ else () set(STLINK_INCLUDE_PATH "${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_DIR}") endif () -option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) -option(STLINK_INSTALL_UDEV_RULES "Install udev rules files" ON) -option(STLINK_INSTALL_MODPROBE_CONF "Install modprobe conf files" ON) - -# cmake (3.0+) on MacOS should use @rpath -cmake_policy(SET CMP0042 NEW) - -set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") include(cmake/version.cmake) + if (NOT MSVC) include(cmake/c_flags.cmake) +else () + message(STATUS "MSVC C Flags override to /MT") + set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") + set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") + set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") + set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") endif () @@ -207,16 +214,13 @@ endif () ### add_executable(st-flash src/tools/flash.c src/tools/flash_opts.c) -if (WIN32 OR APPLE) - target_link_libraries(st-flash ${STLINK_LIB_STATIC} ${SSP_LIB}) -else () - target_link_libraries(st-flash ${STLINK_LIB_SHARED} ${SSP_LIB}) -endif () - add_executable(st-info src/tools/info.c) + if (WIN32 OR APPLE) + target_link_libraries(st-flash ${STLINK_LIB_STATIC} ${SSP_LIB}) target_link_libraries(st-info ${STLINK_LIB_STATIC} ${SSP_LIB}) else () + target_link_libraries(st-flash ${STLINK_LIB_SHARED} ${SSP_LIB}) target_link_libraries(st-info ${STLINK_LIB_SHARED} ${SSP_LIB}) endif () @@ -233,14 +237,14 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux") endif () add_subdirectory(src/gdbserver) -add_subdirectory(src/tools/gui) +add_subdirectory(src/stlink-gui) ### # Others ### -add_subdirectory(usr/lib/pkgconfig) +add_subdirectory(debian/pkgconfig) add_subdirectory(include) add_subdirectory(doc/man) add_subdirectory(tests) @@ -248,6 +252,8 @@ add_subdirectory(tests) include(cmake/cpack_config.cmake) include(CPack) +# ==== + ### # Uninstall target diff --git a/cmake/c_flag_overrides.cmake b/cmake/c_flag_overrides.cmake deleted file mode 100644 index 1a1d163fb..000000000 --- a/cmake/c_flag_overrides.cmake +++ /dev/null @@ -1,7 +0,0 @@ -if (MSVC) - message(STATUS "MSVC C Flags override to /MT") - set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") - set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") - set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") - set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") -endif () diff --git a/usr/lib/pkgconfig/CMakeLists.txt b/debian/pkgconfig/CMakeLists.txt similarity index 100% rename from usr/lib/pkgconfig/CMakeLists.txt rename to debian/pkgconfig/CMakeLists.txt diff --git a/usr/lib/pkgconfig/pkg-config.pc.cmake b/debian/pkgconfig/pkg-config.pc.cmake similarity index 100% rename from usr/lib/pkgconfig/pkg-config.pc.cmake rename to debian/pkgconfig/pkg-config.pc.cmake diff --git a/src/tools/gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt similarity index 55% rename from src/tools/gui/CMakeLists.txt rename to src/stlink-gui/CMakeLists.txt index d7add834b..bb6465481 100644 --- a/src/tools/gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -3,32 +3,31 @@ if (NOT gtk_FOUND) return() endif () -set(GUI_SOURCES stlink-gui.c stlink-gui.h) -set(INSTALLED_UI_DIR share/stlink) +set(GUI_SOURCES gui.c gui.h) +set(INSTALLED_UI_DIR share/stlink) ### TODO: Check Path include_directories(SYSTEM ${gtk_INCLUDE_DIRS}) +# stlink-gui-local add_executable(stlink-gui-local ${GUI_SOURCES}) set_target_properties( stlink-gui-local PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}" + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}" ### TODO: Check Path ) target_link_libraries(stlink-gui-local ${STLINK_LIB_STATIC} ${gtk_LDFLAGS} ${SSP_LIB}) - +# stlink-gui add_executable(stlink-gui ${GUI_SOURCES}) set_target_properties( stlink-gui PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}" + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}" ### TODO: Check Path ) target_link_libraries(stlink-gui ${STLINK_LIB_STATIC} ${gtk_LDFLAGS} ${SSP_LIB}) -install(TARGETS stlink-gui RUNTIME DESTINATION bin) -install(FILES stlink-gui.ui DESTINATION ${INSTALLED_UI_DIR}) +install(TARGETS stlink-gui RUNTIME DESTINATION bin) ### TODO: Check Path +install(FILES gui.ui DESTINATION ${INSTALLED_UI_DIR}) ### TODO: Check Path if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - # Install desktop entry - install(FILES stlink-gui.desktop DESTINATION share/applications) - # Install icon - install(FILES art/stlink-gui.svg DESTINATION share/icons/hicolor/scalable/apps) + install(FILES stlink-gui.desktop DESTINATION share/applications) # Install desktop entry + install(FILES icons/stlink-gui.svg DESTINATION share/icons/hicolor/scalable/apps) # Install icon endif () diff --git a/src/tools/gui/stlink-gui.c b/src/stlink-gui/gui.c similarity index 62% rename from src/tools/gui/stlink-gui.c rename to src/stlink-gui/gui.c index 0dc8bd723..f90196c06 100644 --- a/src/tools/gui/stlink-gui.c +++ b/src/stlink-gui/gui.c @@ -1,11 +1,11 @@ -#include -#include #include +#include +#include #include #include #include -#include "stlink-gui.h" +#include "gui.h" #define MEM_READ_SIZE 1024 @@ -15,30 +15,21 @@ G_DEFINE_TYPE (STlinkGUI, stlink_gui, G_TYPE_OBJECT); -static void -stlink_gui_dispose (GObject *gobject) -{ +static void stlink_gui_dispose (GObject *gobject) { G_OBJECT_CLASS (stlink_gui_parent_class)->dispose (gobject); } -static void -stlink_gui_finalize (GObject *gobject) -{ +static void stlink_gui_finalize (GObject *gobject) { G_OBJECT_CLASS (stlink_gui_parent_class)->finalize (gobject); } -static void -stlink_gui_class_init (STlinkGUIClass *klass) -{ +static void stlink_gui_class_init (STlinkGUIClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - gobject_class->dispose = stlink_gui_dispose; gobject_class->finalize = stlink_gui_finalize; } -static void -stlink_gui_init (STlinkGUI *self) -{ +static void stlink_gui_init (STlinkGUI *self) { self->sl = NULL; self->filename = NULL; @@ -54,9 +45,7 @@ stlink_gui_init (STlinkGUI *self) self->file_mem.base = 0; } -static gboolean -set_info_error_message_idle (STlinkGUI *gui) -{ +static gboolean set_info_error_message_idle (STlinkGUI *gui) { if (gui->error_message != NULL) { gchar *markup; @@ -72,40 +61,31 @@ set_info_error_message_idle (STlinkGUI *gui) return FALSE; } -static void -stlink_gui_set_info_error_message (STlinkGUI *gui, const gchar *message) -{ +static void stlink_gui_set_info_error_message (STlinkGUI *gui, const gchar *message) { gui->error_message = g_strdup (message); g_idle_add ((GSourceFunc) set_info_error_message_idle, gui); } -static void -stlink_gui_set_sensitivity (STlinkGUI *gui, gboolean sensitivity) -{ +static void stlink_gui_set_sensitivity (STlinkGUI *gui, gboolean sensitivity) { gtk_widget_set_sensitive (GTK_WIDGET (gui->open_button), sensitivity); - if (sensitivity && gui->sl) gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), sensitivity); - if (sensitivity && !gui->sl) gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), sensitivity); - if (sensitivity && gui->sl && gui->filename) gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), sensitivity); - gtk_widget_set_sensitive (GTK_WIDGET (gui->export_button), sensitivity && (gui->sl != NULL)); } -static void -mem_view_init_headers (GtkTreeView *view) -{ +static void mem_view_init_headers (GtkTreeView *view) { GtkCellRenderer *renderer; gint i; g_return_if_fail (view != NULL); renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_insert_column_with_attributes (view, + gtk_tree_view_insert_column_with_attributes ( + view, -1, "Address", renderer, @@ -133,12 +113,11 @@ mem_view_init_headers (GtkTreeView *view) } } -static void -mem_view_add_as_hex (GtkListStore *store, - GtkTreeIter *iter, - gint column, - guint32 value) -{ +static void mem_view_add_as_hex ( + GtkListStore *store, + GtkTreeIter *iter, + gint column, + guint32 value) { gchar *hex_str; hex_str = g_strdup_printf ("0x%08X", value); @@ -146,13 +125,12 @@ mem_view_add_as_hex (GtkListStore *store, g_free (hex_str); } -static void -mem_view_add_buffer (GtkListStore *store, - GtkTreeIter *iter, - guint32 address, - guchar *buffer, - gint len) -{ +static void mem_view_add_buffer ( + GtkListStore *store, + GtkTreeIter *iter, + guint32 address, + guchar *buffer, + gint len) { guint32 *word; gint i, step; gint column = 0; @@ -174,61 +152,41 @@ mem_view_add_buffer (GtkListStore *store, } } -static guint32 -hexstr_to_guint32 (const gchar *str, GError **err) -{ +static guint32 hexstr_to_guint32 (const gchar *str, GError **err) { guint32 val; gchar *end_ptr; val = (guint32) strtoul (str, &end_ptr, 16); if ((errno == ERANGE && val == UINT_MAX) || (errno != 0 && val == 0)) { - g_set_error (err, - g_quark_from_string ("hextou32"), - 1, - "Invalid hexstring"); + g_set_error (err, g_quark_from_string ("hextou32"), 1, "Invalid hexstring"); return UINT32_MAX; } if (end_ptr == str) { - g_set_error (err, - g_quark_from_string ("hextou32"), - 2, - "Invalid hexstring"); + g_set_error (err, g_quark_from_string ("hextou32"), 2, "Invalid hexstring"); return UINT32_MAX; } return val; } - -static void -stlink_gui_update_mem_view (STlinkGUI *gui, struct mem_t *mem, GtkTreeView *view) { +static void stlink_gui_update_mem_view (STlinkGUI *gui, struct mem_t *mem, GtkTreeView *view) { GtkListStore *store; GtkTreeIter iter; store = GTK_LIST_STORE (gtk_tree_view_get_model (view)); - mem_view_add_buffer (store, - &iter, - mem->base, - mem->memory, - (gint) mem->size); + mem_view_add_buffer (store, &iter, mem->base, mem->memory, (gint) mem->size); gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); gtk_progress_bar_set_fraction (gui->progress.bar, 0); stlink_gui_set_sensitivity (gui, TRUE); } -static gboolean -stlink_gui_update_devmem_view (STlinkGUI *gui) -{ +static gboolean stlink_gui_update_devmem_view (STlinkGUI *gui) { stlink_gui_update_mem_view (gui, &gui->flash_mem, gui->devmem_treeview); return FALSE; } - - -static gpointer -stlink_gui_populate_devmem_view (gpointer data) -{ +static gpointer stlink_gui_populate_devmem_view (gpointer data) { guint off; stm32_addr_t addr; @@ -240,23 +198,21 @@ stlink_gui_populate_devmem_view (gpointer data) addr = gui->sl->flash_base; - if (gui->flash_mem.memory) { + if (gui->flash_mem.memory) g_free (gui->flash_mem.memory); - } gui->flash_mem.memory = g_malloc (gui->sl->flash_size); gui->flash_mem.size = gui->sl->flash_size; gui->flash_mem.base = gui->sl->flash_base; for (off = 0; off < gui->sl->flash_size; off += MEM_READ_SIZE) { - guint n_read = MEM_READ_SIZE; + guint n_read = MEM_READ_SIZE; if (off + MEM_READ_SIZE > gui->sl->flash_size) { n_read = (guint) gui->sl->flash_size - off; /* align if needed */ - if (n_read & 3) { + if (n_read & 3) n_read = (n_read + 4) & ~(3); - } } /* reads to sl->q_buf */ stlink_read_mem32(gui->sl, addr + off, n_read); @@ -270,29 +226,22 @@ stlink_gui_populate_devmem_view (gpointer data) gui->progress.fraction = (gdouble) (off + n_read) / gui->sl->flash_size; } g_idle_add ((GSourceFunc) stlink_gui_update_devmem_view, gui); - return NULL; } -static gboolean -stlink_gui_update_filemem_view (STlinkGUI *gui) -{ +static gboolean stlink_gui_update_filemem_view (STlinkGUI *gui) { gchar *basename; basename = g_path_get_basename (gui->filename); gtk_notebook_set_tab_label_text (gui->notebook, - GTK_WIDGET (gtk_notebook_get_nth_page (gui->notebook, 1)), - basename); + GTK_WIDGET (gtk_notebook_get_nth_page (gui->notebook, 1)), basename); g_free (basename); stlink_gui_update_mem_view (gui, &gui->file_mem, gui->filemem_treeview); - return FALSE; } -static gpointer -stlink_gui_populate_filemem_view (gpointer data) -{ +static gpointer stlink_gui_populate_filemem_view (gpointer data) { guchar buffer[MEM_READ_SIZE]; GFile *file; GFileInfo *file_info; @@ -306,81 +255,73 @@ stlink_gui_populate_filemem_view (gpointer data) g_return_val_if_fail (gui != NULL, NULL); g_return_val_if_fail (gui->filename != NULL, NULL); - if (g_str_has_suffix (gui->filename, ".hex")) { - // If the file has prefix .hex - try to interpret it as Intel-HEX. - // It's difficult to merge the world of standard functions and GLib, - // so do it simple - load whole file into buffer and copy the data - // to the destination afterwards. - // We loose meanwhile the displaying of the progress and need - // double memory. - - uint8_t* mem = NULL; - size_t size = 0; - uint32_t begin = 0; - int res = stlink_parse_ihex (gui->filename, 0, &mem, &size, &begin); - - if (res == 0) { - if (gui->file_mem.memory) { - g_free (gui->file_mem.memory); - } - gui->file_mem.size = size; - gui->file_mem.memory = g_malloc (size); - gui->file_mem.base = begin; - - memcpy (gui->file_mem.memory, mem, size); - } - else { - stlink_gui_set_info_error_message (gui, "Cannot interpret the file as Intel-HEX"); - } - - free(mem); - } - else { - file = g_file_new_for_path (gui->filename); - input_stream = G_INPUT_STREAM (g_file_read (file, NULL, &err)); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out; - } - - file_info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (input_stream), - G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, &err); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out_input; - } - if (gui->file_mem.memory) { - g_free (gui->file_mem.memory); - } - gui->file_mem.size = g_file_info_get_size (file_info); - gui->file_mem.memory = g_malloc (gui->file_mem.size); - - for (off = 0; off < (gint) gui->file_mem.size; off += MEM_READ_SIZE) { - guint n_read = MEM_READ_SIZE; - - if (off + MEM_READ_SIZE > (gint) gui->file_mem.size) { - n_read = (guint) gui->file_mem.size - off; - } - - if (g_input_stream_read (G_INPUT_STREAM (input_stream), - &buffer, n_read, NULL, &err) == -1) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out_input; - } - memcpy (gui->file_mem.memory + off, buffer, n_read); - gui->progress.fraction = (gdouble) (off + n_read) / gui->file_mem.size; - } - -out_input: - g_object_unref (input_stream); -out: - g_object_unref (file); - } - - g_idle_add ((GSourceFunc) stlink_gui_update_filemem_view, gui); + if (g_str_has_suffix (gui->filename, ".hex")) { + // If the file has prefix .hex - try to interpret it as Intel-HEX. + // It's difficult to merge the world of standard functions and GLib, + // so do it simple - load whole file into buffer and copy the data to the + // destination afterwards. + // We loose meanwhile the displaying of the progress and need double memory. + + uint8_t* mem = NULL; + size_t size = 0; + uint32_t begin = 0; + int res = stlink_parse_ihex (gui->filename, 0, &mem, &size, &begin); + + if (res == 0) { + if (gui->file_mem.memory) + g_free (gui->file_mem.memory); + gui->file_mem.size = size; + gui->file_mem.memory = g_malloc (size); + gui->file_mem.base = begin; + + memcpy (gui->file_mem.memory, mem, size); + } else { + stlink_gui_set_info_error_message (gui, "Cannot interpret the file as Intel-HEX"); + } + + free(mem); + } else { + file = g_file_new_for_path (gui->filename); + input_stream = G_INPUT_STREAM (g_file_read (file, NULL, &err)); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out; + } + + file_info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (input_stream), + G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, &err); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out_input; + } + if (gui->file_mem.memory) + g_free (gui->file_mem.memory); + gui->file_mem.size = g_file_info_get_size (file_info); + gui->file_mem.memory = g_malloc (gui->file_mem.size); + + for (off = 0; off < (gint) gui->file_mem.size; off += MEM_READ_SIZE) { + guint n_read = MEM_READ_SIZE; + + if (off + MEM_READ_SIZE > (gint) gui->file_mem.size) + n_read = (guint) gui->file_mem.size - off; + + if (g_input_stream_read (G_INPUT_STREAM (input_stream), + &buffer, n_read, NULL, &err) == -1) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out_input; + } + memcpy (gui->file_mem.memory + off, buffer, n_read); + gui->progress.fraction = (gdouble) (off + n_read) / gui->file_mem.size; + } + + out_input: g_object_unref (input_stream); + out: g_object_unref (file); + } + + g_idle_add ((GSourceFunc) stlink_gui_update_filemem_view, gui); return NULL; } @@ -388,29 +329,23 @@ static void mem_jmp (GtkTreeView *view, GtkEntry *entry, guint32 base_addr, gsize size, - GError **err) -{ + GError **err) { GtkTreeModel *model; guint32 jmp_addr; GtkTreeIter iter; jmp_addr = hexstr_to_guint32 (gtk_entry_get_text (entry), err); - if (err && *err) { + if (err && *err) return; - } if (jmp_addr < base_addr || jmp_addr > base_addr + size) { - g_set_error (err, - g_quark_from_string ("mem_jmp"), - 1, - "Invalid address"); + g_set_error (err, g_quark_from_string ("mem_jmp"), 1, "Invalid address"); return; } model = gtk_tree_view_get_model (view); - if (!model) { + if (!model) return; - } if (gtk_tree_model_get_iter_first (model, &iter)) { do { @@ -429,12 +364,7 @@ static void mem_jmp (GtkTreeView *view, path = gtk_tree_model_get_path (model, &iter); gtk_tree_selection_select_iter (selection, &iter); - gtk_tree_view_scroll_to_cell (view, - path, - NULL, - TRUE, - 0.0, - 0.0); + gtk_tree_view_scroll_to_cell (view, path, NULL, TRUE, 0.0, 0.0); gtk_tree_path_free (path); } } @@ -444,9 +374,7 @@ static void mem_jmp (GtkTreeView *view, } } -static void -devmem_jmp_cb (GtkWidget *widget, gpointer data) -{ +static void devmem_jmp_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; GError *err = NULL; (void) widget; @@ -465,9 +393,7 @@ devmem_jmp_cb (GtkWidget *widget, gpointer data) } } -static void -filemem_jmp_cb (GtkWidget *widget, gpointer data) -{ +static void filemem_jmp_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; GError *err = NULL; (void) widget; @@ -488,9 +414,7 @@ filemem_jmp_cb (GtkWidget *widget, gpointer data) } } -static gchar * -dev_format_chip_id (guint32 chip_id) -{ +static gchar *dev_format_chip_id (guint32 chip_id) { const struct stlink_chipid_params *params; params = stlink_chipid_get_params(chip_id); @@ -500,31 +424,25 @@ dev_format_chip_id (guint32 chip_id) return g_strdup (params->description); } -static gchar * -dev_format_mem_size (gsize flash_size) -{ +static gchar *dev_format_mem_size (gsize flash_size) { return g_strdup_printf ("%u kB", (unsigned int)(flash_size / 1024)); } -static void -stlink_gui_set_connected (STlinkGUI *gui) -{ +static void stlink_gui_set_connected (STlinkGUI *gui) { gchar *tmp_str; GtkListStore *store; GtkTreeIter iter; gtk_statusbar_push (gui->statusbar, - gtk_statusbar_get_context_id (gui->statusbar, "conn"), - "Connected"); + gtk_statusbar_get_context_id (gui->statusbar, "conn"), "Connected"); gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), TRUE); gtk_widget_set_sensitive (GTK_WIDGET (gui->devmem_box), TRUE); gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), FALSE); - if (gui->filename) { + if (gui->filename) gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), TRUE); - } tmp_str = dev_format_chip_id (gui->sl->chip_id); gtk_label_set_text (gui->chip_id_label, tmp_str); @@ -548,9 +466,8 @@ stlink_gui_set_connected (STlinkGUI *gui) g_free (tmp_str); store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) gtk_list_store_clear (store); - } stlink_gui_set_sensitivity (gui, FALSE); gtk_notebook_set_current_page (gui->notebook, PAGE_DEVMEM); @@ -560,9 +477,7 @@ stlink_gui_set_connected (STlinkGUI *gui) g_thread_new ("devmem", (GThreadFunc) stlink_gui_populate_devmem_view, gui); } -static void -connect_button_cb (GtkWidget *widget, gpointer data) -{ +static void connect_button_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; gint i; (void) widget; @@ -574,11 +489,11 @@ connect_button_cb (GtkWidget *widget, gpointer data) /* try version 1 then version 2 */ gui->sl = stlink_v1_open(0, 1); + if (gui->sl == NULL) + gui->sl = stlink_open_usb(0, 1, NULL); if (gui->sl == NULL) { - gui->sl = stlink_open_usb(0, 1, NULL); - } - if (gui->sl == NULL) { - stlink_gui_set_info_error_message (gui, "Failed to connect to STLink."); return; + stlink_gui_set_info_error_message (gui, "Failed to connect to STLink."); + return; } /* code below taken from flash/main.c, refactoring might be in order */ @@ -601,8 +516,7 @@ connect_button_cb (GtkWidget *widget, gpointer data) stlink_gui_set_connected (gui); } -static void stlink_gui_set_disconnected (STlinkGUI *gui) -{ +static void stlink_gui_set_disconnected (STlinkGUI *gui) { gtk_statusbar_push (gui->statusbar, gtk_statusbar_get_context_id (gui->statusbar, "conn"), "Disconnected"); @@ -614,9 +528,7 @@ static void stlink_gui_set_disconnected (STlinkGUI *gui) gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), TRUE); } -static void -disconnect_button_cb (GtkWidget *widget, gpointer data) -{ +static void disconnect_button_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; (void) widget; @@ -631,9 +543,7 @@ disconnect_button_cb (GtkWidget *widget, gpointer data) } -static void -stlink_gui_open_file (STlinkGUI *gui) -{ +static void stlink_gui_open_file (STlinkGUI *gui) { GtkWidget *dialog; GtkListStore *store; GtkTreeIter iter; @@ -646,13 +556,11 @@ stlink_gui_open_file (STlinkGUI *gui) NULL); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { - gui->filename = - gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + gui->filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->filemem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) gtk_list_store_clear (store); - } stlink_gui_set_sensitivity (gui, FALSE); gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); @@ -663,37 +571,30 @@ stlink_gui_open_file (STlinkGUI *gui) gtk_widget_destroy (dialog); } -static void -open_button_cb (GtkWidget *widget, gpointer data) -{ +static void open_button_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; (void) widget; gui = STLINK_GUI (data); - stlink_gui_open_file (gui); } -static gboolean -stlink_gui_write_flash_update (STlinkGUI *gui) -{ +static gboolean stlink_gui_write_flash_update (STlinkGUI *gui) { stlink_gui_set_sensitivity (gui, TRUE); gui->progress.activity_mode = FALSE; gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); - return FALSE; } -static gpointer -stlink_gui_write_flash (gpointer data) -{ +static gpointer stlink_gui_write_flash (gpointer data) { g_return_val_if_fail (STLINK_IS_GUI (data), NULL); STlinkGUI *gui = (STlinkGUI *)data; g_return_val_if_fail ((gui->sl != NULL), NULL); g_return_val_if_fail ((gui->filename != NULL), NULL); - if (stlink_mwrite_flash(gui->sl, gui->file_mem.memory, (uint32_t)gui->file_mem.size, gui->sl->flash_base) < 0) { + if (stlink_mwrite_flash(gui->sl, gui->file_mem.memory, + (uint32_t)gui->file_mem.size, gui->sl->flash_base) < 0) { stlink_gui_set_info_error_message (gui, "Failed to write to flash"); } @@ -701,9 +602,7 @@ stlink_gui_write_flash (gpointer data) return NULL; } -static void -flash_button_cb (GtkWidget *widget, gpointer data) -{ +static void flash_button_cb (GtkWidget *widget, gpointer data) { STlinkGUI *gui; gchar *tmp_str; guint32 address; @@ -722,47 +621,38 @@ flash_button_cb (GtkWidget *widget, gpointer data) result = gtk_dialog_run (gui->flash_dialog); if (result == GTK_RESPONSE_OK) { - address = hexstr_to_guint32 (gtk_entry_get_text (gui->flash_dialog_entry), - &err); + address = hexstr_to_guint32 (gtk_entry_get_text (gui->flash_dialog_entry), &err); if (err) { stlink_gui_set_info_error_message (gui, err->message); } else { - if (address > gui->sl->flash_base + gui->sl->flash_size || - address < gui->sl->flash_base) { + if (address > gui->sl->flash_base + gui->sl->flash_size || address < gui->sl->flash_base) { stlink_gui_set_info_error_message (gui, "Invalid address"); - } - else if (address + gui->file_mem.size > - gui->sl->flash_base + gui->sl->flash_size) { + } else if (address + gui->file_mem.size > gui->sl->flash_base + gui->sl->flash_size) { stlink_gui_set_info_error_message (gui, "Binary overwrites flash"); } else { stlink_gui_set_sensitivity (gui, FALSE); - gtk_progress_bar_set_text (gui->progress.bar, - "Writing to flash"); + gtk_progress_bar_set_text (gui->progress.bar, "Writing to flash"); gui->progress.activity_mode = TRUE; gtk_widget_show (GTK_WIDGET (gui->progress.bar)); - g_thread_new ("flash", - (GThreadFunc) stlink_gui_write_flash, gui); + g_thread_new ("flash", (GThreadFunc) stlink_gui_write_flash, gui); } } } } -int export_to_file(const char*filename, const struct mem_t flash_mem) -{ +int export_to_file(const char*filename, const struct mem_t flash_mem) { printf("%s\n", filename); FILE * f=fopen(filename, "w"); - if (f==NULL) + if (f == NULL) return -1; for (gsize i=0;iflash_mem)!=0) + if (export_to_file (filename, gui->flash_mem) != 0) { stlink_gui_set_info_error_message(gui, "Failed to export flash"); - else + } else { stlink_gui_set_info_error_message(gui, "Export successful"); + } g_free (filename); } gtk_widget_destroy (dialog); } -static gboolean -progress_pulse_timeout (STlinkGUI *gui) { +static gboolean progress_pulse_timeout (STlinkGUI *gui) { if (gui->progress.activity_mode) { gtk_progress_bar_pulse (gui->progress.bar); } else { @@ -802,12 +691,11 @@ progress_pulse_timeout (STlinkGUI *gui) { return TRUE; } -static void -notebook_switch_page_cb (GtkNotebook *notebook, - GtkWidget *widget, - guint page_num, - gpointer data) -{ +static void notebook_switch_page_cb ( + GtkNotebook *notebook, + GtkWidget *widget, + guint page_num, + gpointer data) { STlinkGUI *gui; (void) notebook; (void) widget; @@ -815,22 +703,20 @@ notebook_switch_page_cb (GtkNotebook *notebook, gui = STLINK_GUI (data); if (page_num == 1) { - if (gui->filename == NULL) { + if (gui->filename == NULL) stlink_gui_open_file (gui); - } } } -static void -dnd_received_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint target_type, - guint timestamp, - gpointer data) -{ +static void dnd_received_cb ( + GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint target_type, + guint timestamp, + gpointer data) { GFile *file_uri; gchar **file_list; const guchar *file_data; @@ -841,14 +727,12 @@ dnd_received_cb (GtkWidget *widget, (void) x; (void) y; - if (selection_data != NULL && - gtk_selection_data_get_length (selection_data) > 0) { + if (selection_data != NULL && gtk_selection_data_get_length (selection_data) > 0) { switch (target_type) { case TARGET_FILENAME: - if (gui->filename) { + if (gui->filename) g_free (gui->filename); - } file_data = gtk_selection_data_get_data (selection_data); file_list = g_strsplit ((gchar *)file_data, "\r\n", 0); @@ -859,11 +743,9 @@ dnd_received_cb (GtkWidget *widget, g_strfreev (file_list); g_object_unref (file_uri); - store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) gtk_list_store_clear (store); - } stlink_gui_set_sensitivity (gui, FALSE); gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); @@ -873,39 +755,34 @@ dnd_received_cb (GtkWidget *widget, break; } } - gtk_drag_finish (context, - TRUE, - gdk_drag_context_get_suggested_action (context) == GDK_ACTION_MOVE, - timestamp); + gtk_drag_finish ( + context, + TRUE, + gdk_drag_context_get_suggested_action (context) == GDK_ACTION_MOVE, + timestamp); } -void -stlink_gui_init_dnd (STlinkGUI *gui) -{ - GtkTargetEntry target_list[] = { - { "text/uri-list", 0, TARGET_FILENAME }, - }; - - gtk_drag_dest_set(GTK_WIDGET (gui->window), - GTK_DEST_DEFAULT_ALL, - target_list, - G_N_ELEMENTS (target_list), - GDK_ACTION_COPY); - - g_signal_connect (gui->window, "drag-data-received", - G_CALLBACK (dnd_received_cb), gui); +void stlink_gui_init_dnd (STlinkGUI *gui) { + GtkTargetEntry target_list[] = { { "text/uri-list", 0, TARGET_FILENAME }, }; + + gtk_drag_dest_set( + GTK_WIDGET (gui->window), + GTK_DEST_DEFAULT_ALL, + target_list, + G_N_ELEMENTS (target_list), + GDK_ACTION_COPY); + + g_signal_connect (gui->window, "drag-data-received", G_CALLBACK (dnd_received_cb), gui); } -static void -stlink_gui_build_ui (STlinkGUI *gui) { +static void stlink_gui_build_ui (STlinkGUI *gui) { GtkBuilder *builder; GtkListStore *devmem_store; GtkListStore *filemem_store; - gchar *ui_file = STLINK_UI_DIR "/stlink-gui.ui"; + gchar *ui_file = STLINK_UI_DIR "/gui.ui"; - if (!g_file_test (ui_file, G_FILE_TEST_EXISTS)) { - ui_file = "stlink-gui.ui"; - } + if (!g_file_test (ui_file, G_FILE_TEST_EXISTS)) + ui_file = "gui.ui"; builder = gtk_builder_new (); if (!gtk_builder_add_from_file (builder, ui_file, NULL)) { g_printerr ("Failed to load UI file: %s\n", ui_file); @@ -913,37 +790,25 @@ stlink_gui_build_ui (STlinkGUI *gui) { } gui->window = GTK_WINDOW (gtk_builder_get_object (builder, "window")); - g_signal_connect (G_OBJECT (gui->window), "destroy", - G_CALLBACK (gtk_main_quit), NULL); + g_signal_connect (G_OBJECT (gui->window), "destroy", G_CALLBACK (gtk_main_quit), NULL); /* set up toolutton clicked callbacks */ - gui->open_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "open_button")); - g_signal_connect (G_OBJECT (gui->open_button), "clicked", - G_CALLBACK (open_button_cb), gui); - - gui->connect_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "connect_button")); - g_signal_connect (G_OBJECT (gui->connect_button), "clicked", - G_CALLBACK (connect_button_cb), gui); - - gui->disconnect_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "disconnect_button")); - g_signal_connect (G_OBJECT (gui->disconnect_button), "clicked", - G_CALLBACK (disconnect_button_cb), gui); - - gui->flash_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "flash_button")); - g_signal_connect (G_OBJECT (gui->flash_button), "clicked", - G_CALLBACK (flash_button_cb), gui); - - gui->export_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "export_button")); - g_signal_connect (G_OBJECT (gui->export_button), "clicked", - G_CALLBACK (export_button_cb), gui); - - gui->devmem_treeview = - GTK_TREE_VIEW (gtk_builder_get_object (builder, "devmem_treeview")); + gui->open_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "open_button")); + g_signal_connect (G_OBJECT (gui->open_button), "clicked", G_CALLBACK (open_button_cb), gui); + + gui->connect_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "connect_button")); + g_signal_connect (G_OBJECT (gui->connect_button), "clicked", G_CALLBACK (connect_button_cb), gui); + + gui->disconnect_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "disconnect_button")); + g_signal_connect (G_OBJECT (gui->disconnect_button), "clicked", G_CALLBACK (disconnect_button_cb), gui); + + gui->flash_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "flash_button")); + g_signal_connect (G_OBJECT (gui->flash_button), "clicked", G_CALLBACK (flash_button_cb), gui); + + gui->export_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "export_button")); + g_signal_connect (G_OBJECT (gui->export_button), "clicked", G_CALLBACK (export_button_cb), gui); + + gui->devmem_treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "devmem_treeview")); mem_view_init_headers (gui->devmem_treeview); devmem_store = gtk_list_store_new (5, G_TYPE_STRING, @@ -954,8 +819,7 @@ stlink_gui_build_ui (STlinkGUI *gui) { gtk_tree_view_set_model (gui->devmem_treeview, GTK_TREE_MODEL (devmem_store)); g_object_unref (devmem_store); - gui->filemem_treeview = - GTK_TREE_VIEW (gtk_builder_get_object (builder, "filemem_treeview")); + gui->filemem_treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "filemem_treeview")); mem_view_init_headers (gui->filemem_treeview); filemem_store = gtk_list_store_new (5, G_TYPE_STRING, @@ -966,75 +830,43 @@ stlink_gui_build_ui (STlinkGUI *gui) { gtk_tree_view_set_model (gui->filemem_treeview, GTK_TREE_MODEL (filemem_store)); g_object_unref (filemem_store); - gui->core_id_label = - GTK_LABEL (gtk_builder_get_object (builder, "core_id_value")); - - gui->chip_id_label = - GTK_LABEL (gtk_builder_get_object (builder, "chip_id_value")); + gui->core_id_label = GTK_LABEL (gtk_builder_get_object (builder, "core_id_value")); + gui->chip_id_label = GTK_LABEL (gtk_builder_get_object (builder, "chip_id_value")); + gui->flash_size_label = GTK_LABEL (gtk_builder_get_object (builder, "flash_size_value")); + gui->ram_size_label = GTK_LABEL (gtk_builder_get_object (builder, "ram_size_value")); + gui->device_frame = GTK_FRAME (gtk_builder_get_object (builder, "device_frame")); - gui->flash_size_label = - GTK_LABEL (gtk_builder_get_object (builder, "flash_size_value")); + gui->notebook = GTK_NOTEBOOK (gtk_builder_get_object (builder, "mem_notebook")); + g_signal_connect (gui->notebook, "switch-page", G_CALLBACK (notebook_switch_page_cb), gui); - gui->ram_size_label = - GTK_LABEL (gtk_builder_get_object (builder, "ram_size_value")); + gui->devmem_box = GTK_BOX (gtk_builder_get_object (builder, "devmem_box")); + gui->filemem_box = GTK_BOX (gtk_builder_get_object (builder, "filemem_box")); - gui->device_frame = - GTK_FRAME (gtk_builder_get_object (builder, "device_frame")); + gui->devmem_jmp_entry = GTK_ENTRY (gtk_builder_get_object (builder, "devmem_jmp_entry")); + g_signal_connect (gui->devmem_jmp_entry, "activate", G_CALLBACK (devmem_jmp_cb), gui); - gui->notebook = - GTK_NOTEBOOK (gtk_builder_get_object (builder, "mem_notebook")); - g_signal_connect (gui->notebook, "switch-page", - G_CALLBACK (notebook_switch_page_cb), gui); - - gui->devmem_box = - GTK_BOX (gtk_builder_get_object (builder, "devmem_box")); - - gui->filemem_box = - GTK_BOX (gtk_builder_get_object (builder, "filemem_box")); - - gui->devmem_jmp_entry = - GTK_ENTRY (gtk_builder_get_object (builder, "devmem_jmp_entry")); - g_signal_connect (gui->devmem_jmp_entry, "activate", - G_CALLBACK (devmem_jmp_cb), gui); - - gui->filemem_jmp_entry = - GTK_ENTRY (gtk_builder_get_object (builder, "filemem_jmp_entry")); - g_signal_connect (gui->filemem_jmp_entry, "activate", - G_CALLBACK (filemem_jmp_cb), gui); + gui->filemem_jmp_entry = GTK_ENTRY (gtk_builder_get_object (builder, "filemem_jmp_entry")); + g_signal_connect (gui->filemem_jmp_entry, "activate", G_CALLBACK (filemem_jmp_cb), gui); gtk_editable_set_editable (GTK_EDITABLE (gui->filemem_jmp_entry), TRUE); - gui->progress.bar = - GTK_PROGRESS_BAR (gtk_builder_get_object (builder, "progressbar")); + gui->progress.bar = GTK_PROGRESS_BAR (gtk_builder_get_object (builder, "progressbar")); gtk_progress_bar_set_show_text (gui->progress.bar, TRUE); - gui->progress.timer = g_timeout_add (100, - (GSourceFunc) progress_pulse_timeout, - gui); + gui->progress.timer = g_timeout_add (100, (GSourceFunc) progress_pulse_timeout, gui); - gui->statusbar = - GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")); + gui->statusbar = GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")); - gui->infobar = - GTK_INFO_BAR (gtk_builder_get_object (builder, "infobar")); + gui->infobar = GTK_INFO_BAR (gtk_builder_get_object (builder, "infobar")); gtk_info_bar_add_button (gui->infobar, "_OK", GTK_RESPONSE_OK); gui->infolabel = GTK_LABEL (gtk_label_new ("")); - gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (gui->infobar)), - GTK_WIDGET (gui->infolabel)); + gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (gui->infobar)), GTK_WIDGET (gui->infolabel)); g_signal_connect (gui->infobar, "response", G_CALLBACK (gtk_widget_hide), NULL); /* flash dialog */ - gui->flash_dialog = - GTK_DIALOG (gtk_builder_get_object (builder, "flash_dialog")); - g_signal_connect_swapped (gui->flash_dialog, "response", - G_CALLBACK (gtk_widget_hide), gui->flash_dialog); - - gui->flash_dialog_ok = - GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_ok_button")); - - gui->flash_dialog_cancel = - GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_cancel_button")); - - gui->flash_dialog_entry = - GTK_ENTRY (gtk_builder_get_object (builder, "flash_dialog_entry")); + gui->flash_dialog = GTK_DIALOG (gtk_builder_get_object (builder, "flash_dialog")); + g_signal_connect_swapped (gui->flash_dialog, "response", G_CALLBACK (gtk_widget_hide), gui->flash_dialog); + gui->flash_dialog_ok = GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_ok_button")); + gui->flash_dialog_cancel = GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_cancel_button")); + gui->flash_dialog_entry = GTK_ENTRY (gtk_builder_get_object (builder, "flash_dialog_entry")); /* make it so */ gtk_widget_show_all (GTK_WIDGET (gui->window)); @@ -1044,9 +876,7 @@ stlink_gui_build_ui (STlinkGUI *gui) { stlink_gui_set_disconnected (gui); } -int -main (int argc, char **argv) -{ +int main (int argc, char **argv) { STlinkGUI *gui; gtk_init (&argc, &argv); @@ -1056,6 +886,5 @@ main (int argc, char **argv) stlink_gui_init_dnd (gui); gtk_main (); - return 0; } diff --git a/src/tools/gui/stlink-gui.h b/src/stlink-gui/gui.h similarity index 98% rename from src/tools/gui/stlink-gui.h rename to src/stlink-gui/gui.h index 30c503fd3..c83e638f6 100644 --- a/src/tools/gui/stlink-gui.h +++ b/src/stlink-gui/gui.h @@ -39,8 +39,7 @@ struct mem_t { guint32 base; }; -struct _STlinkGUI -{ +struct _STlinkGUI { GObject parent_instance; /*< private >*/ @@ -82,8 +81,7 @@ struct _STlinkGUI stlink_t *sl; }; -struct _STlinkGUIClass -{ +struct _STlinkGUIClass { GObjectClass parent_class; /* class members */ diff --git a/src/tools/gui/stlink-gui.ui b/src/stlink-gui/gui.ui similarity index 100% rename from src/tools/gui/stlink-gui.ui rename to src/stlink-gui/gui.ui diff --git a/src/stlink-gui/icons/export-icons.sh b/src/stlink-gui/icons/export-icons.sh new file mode 100644 index 000000000..f36cb5598 --- /dev/null +++ b/src/stlink-gui/icons/export-icons.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# +# create the XPM icon and all resolutions below hicolor as PNG + +APPNAME="stlink-gui" +ORIGIN="stlink-gui_icon.svg" +OUTDIR="hicolor" + +# possible size options are --export-dpi / --export-width / --export-height +OPTS="-z --export-id-only" +ID="scalable-icon" +RESOLUTIONS="16 22 24 32 48 64 128 256" + +if ! [ -d $OUTDIR ]; then + echo "output directory missing. Create it..." + mkdir $OUTDIR + for RES in $RESOLUTIONS; do + mkdir -p $OUTDIR/${RES}x${RES}/apps + done +fi + +# create single app icon +inkscape $OPTS --export-width=32 --export-id=$ID --export-png=$APPNAME.png $ORIGIN +if [ $? != 0 ]; then + exit 1; +fi +convert $APPNAME.png $APPNAME.xpm + +# create all the resolutions +ALL="" +for RES in $RESOLUTIONS; do + inkscape $OPTS --export-width=$RES --export-id=$ID --export-png=$OUTDIR/${RES}x${RES}/apps/$APPNAME.png $ORIGIN + ALL="$ALL $OUTDIR/${RES}x${RES}/apps/$APPNAME.png" +done + +# this is for windows... +#echo "build Windows icon from $ALL" +#convert $ALL $APPNAME.ico + +exit 0 diff --git a/src/tools/gui/art/hicolor/128x128/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/128x128/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/128x128/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/128x128/apps/stlink-gui.png diff --git a/src/tools/gui/art/hicolor/16x16/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/16x16/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/16x16/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/16x16/apps/stlink-gui.png diff --git a/src/tools/gui/art/hicolor/22x22/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/22x22/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/22x22/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/22x22/apps/stlink-gui.png diff --git a/src/tools/gui/art/hicolor/24x24/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/24x24/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/24x24/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/24x24/apps/stlink-gui.png diff --git a/src/tools/gui/art/hicolor/256x256/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/256x256/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/256x256/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/256x256/apps/stlink-gui.png diff --git a/src/tools/gui/art/hicolor/32x32/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/32x32/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/32x32/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/32x32/apps/stlink-gui.png diff --git a/src/tools/gui/art/hicolor/48x48/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/48x48/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/48x48/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/48x48/apps/stlink-gui.png diff --git a/src/tools/gui/art/hicolor/64x64/apps/stlink-gui.png b/src/stlink-gui/icons/hicolor/64x64/apps/stlink-gui.png similarity index 100% rename from src/tools/gui/art/hicolor/64x64/apps/stlink-gui.png rename to src/stlink-gui/icons/hicolor/64x64/apps/stlink-gui.png diff --git a/src/tools/gui/art/stlink-gui.png b/src/stlink-gui/icons/stlink-gui.png similarity index 100% rename from src/tools/gui/art/stlink-gui.png rename to src/stlink-gui/icons/stlink-gui.png diff --git a/src/tools/gui/art/stlink-gui.svg b/src/stlink-gui/icons/stlink-gui.svg similarity index 100% rename from src/tools/gui/art/stlink-gui.svg rename to src/stlink-gui/icons/stlink-gui.svg diff --git a/src/tools/gui/art/stlink-gui.xpm b/src/stlink-gui/icons/stlink-gui.xpm similarity index 100% rename from src/tools/gui/art/stlink-gui.xpm rename to src/stlink-gui/icons/stlink-gui.xpm diff --git a/src/tools/gui/art/stlink-gui_48.png b/src/stlink-gui/icons/stlink-gui_48.png similarity index 100% rename from src/tools/gui/art/stlink-gui_48.png rename to src/stlink-gui/icons/stlink-gui_48.png diff --git a/src/tools/gui/stlink-gui.desktop b/src/stlink-gui/stlink-gui.desktop similarity index 100% rename from src/tools/gui/stlink-gui.desktop rename to src/stlink-gui/stlink-gui.desktop diff --git a/src/tools/gui/art/export-icons.sh b/src/tools/gui/art/export-icons.sh deleted file mode 100755 index 9d61719b9..000000000 --- a/src/tools/gui/art/export-icons.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh -# -# create the XPM icon and all resolutions below hicolor as PNG - -APPNAME="stlink-gui" -ORIGIN="stlink-gui_icon.svg" -OUTDIR="hicolor" - -## possible size options are --export-dpi / --export-width / --export-height -OPTS="-z --export-id-only" -ID="scalable-icon" -RESOLUTIONS="16 22 24 32 48 64 128 256" - - if ! [ -d $OUTDIR ]; then - echo "output directory missing. Create it..." - mkdir $OUTDIR - for RES in $RESOLUTIONS; do - mkdir -p $OUTDIR/${RES}x${RES}/apps - done - fi - - # create single app icon - inkscape $OPTS --export-width=32 --export-id=$ID --export-png=$APPNAME.png $ORIGIN - if [ $? != 0 ]; then exit 1; fi - convert $APPNAME.png $APPNAME.xpm - - # create all the resolutions - ALL="" - for RES in $RESOLUTIONS; do - inkscape $OPTS --export-width=$RES --export-id=$ID --export-png=$OUTDIR/${RES}x${RES}/apps/$APPNAME.png $ORIGIN - ALL="$ALL $OUTDIR/${RES}x${RES}/apps/$APPNAME.png" - done - - # this is for windows... - #echo "build Windows icon from $ALL" - #convert $ALL $APPNAME.ico - -exit 0 From c2c480846a493ae5493a5aecda41ad53f0b83bb2 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 17 Apr 2020 00:37:03 +0200 Subject: [PATCH 0832/1435] Project cleanup - Updated old project references - Alligned code style in /tests - Added note on OS support to README.md --- CHANGELOG.md | 272 +++++++++++++++++++++++------------------------ LICENSE.md | 2 +- README.md | 30 +++--- debian/control | 8 +- debian/copyright | 4 +- debian/watch | 2 +- tests/flash.c | 154 ++++++++++++++++++++------- tests/sg.c | 67 ++++++------ tests/usb.c | 19 ++-- 9 files changed, 319 insertions(+), 239 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99d307f9a..8cf102910 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,44 +8,44 @@ Release date: 2020-02-20 Major changes and added features: -* Initial support for STM32L41X ([#754](https://github.com/texane/stlink/pull/754), [#799](https://github.com/texane/stlink/pull/799)) -* Working support for CKS32F103C8T6 and related CKS devices with Core-ID 0x2ba01477 ([#756](https://github.com/texane/stlink/pull/756), [#757](https://github.com/texane/stlink/pull/757), [#805](https://github.com/texane/stlink/pull/805), [#834](https://github.com/texane/stlink/pull/834), Regression-Fixes: [#761](https://github.com/texane/stlink/pull/761), [#766](https://github.com/texane/stlink/pull/766)) -* Added preliminary support for some STM32G0 chips ([#759](https://github.com/texane/stlink/pull/759), [#760](https://github.com/texane/stlink/pull/760), [#797](https://github.com/texane/stlink/pull/797)) -* Added support for mass erasing second bank on STM32F10x_XL ([#767](https://github.com/texane/stlink/pull/767), [#768](https://github.com/texane/stlink/pull/768)) -* Added call to clear PG bit after writing to flash ([#773](https://github.com/texane/stlink/pull/773)) -* Added support to write option bytes for the STM32G0 ([#778](https://github.com/texane/stlink/pull/778)) -* Added support for STM32WB55 chips ([#786](https://github.com/texane/stlink/pull/786), [#810](https://github.com/texane/stlink/pull/810), [#816](https://github.com/texane/stlink/pull/816)) -* Added STLink V3SET VID:PIDs to the udev rules ([#789](https://github.com/texane/stlink/pull/789)) -* Support for "STM32+Audio" v2-1 firmware ([#790](https://github.com/texane/stlink/pull/790)) -* Build for Windows under Debian/Ubuntu ([#802](https://github.com/texane/stlink/pull/802)) -* Allow for 64 bytes serials ([#809](https://github.com/texane/stlink/pull/809)) -* Added full support for STLINK CHIP ID L4RX ([#814](https://github.com/texane/stlink/pull/814), [#839](https://github.com/texane/stlink/pull/839)) -* Added support for the STLink-v2.1 when flashed with no mass storage (PID 0x3752) ([#819](https://github.com/texane/stlink/pull/819), [#861](https://github.com/texane/stlink/pull/861)) -* Added support for writing option bytes on STM32L0xx ([#830](https://github.com/texane/stlink/pull/830)) -* Added support to read and write option bytes for STM32F2 series ([#836](https://github.com/texane/stlink/pull/836), [#837](https://github.com/texane/stlink/pull/837)) -* Added support to read and write option bytes for STM32F446 ([#843](https://github.com/texane/stlink/pull/843)) +* Initial support for STM32L41X ([#754](https://github.com/stlink-org/stlink/pull/754), [#799](https://github.com/stlink-org/stlink/pull/799)) +* Working support for CKS32F103C8T6 and related CKS devices with Core-ID 0x2ba01477 ([#756](https://github.com/stlink-org/stlink/pull/756), [#757](https://github.com/stlink-org/stlink/pull/757), [#805](https://github.com/stlink-org/stlink/pull/805), [#834](https://github.com/stlink-org/stlink/pull/834), Regression-Fixes: [#761](https://github.com/stlink-org/stlink/pull/761), [#766](https://github.com/stlink-org/stlink/pull/766)) +* Added preliminary support for some STM32G0 chips ([#759](https://github.com/stlink-org/stlink/pull/759), [#760](https://github.com/stlink-org/stlink/pull/760), [#797](https://github.com/stlink-org/stlink/pull/797)) +* Added support for mass erasing second bank on STM32F10x_XL ([#767](https://github.com/stlink-org/stlink/pull/767), [#768](https://github.com/stlink-org/stlink/pull/768)) +* Added call to clear PG bit after writing to flash ([#773](https://github.com/stlink-org/stlink/pull/773)) +* Added support to write option bytes for the STM32G0 ([#778](https://github.com/stlink-org/stlink/pull/778)) +* Added support for STM32WB55 chips ([#786](https://github.com/stlink-org/stlink/pull/786), [#810](https://github.com/stlink-org/stlink/pull/810), [#816](https://github.com/stlink-org/stlink/pull/816)) +* Added STLink V3SET VID:PIDs to the udev rules ([#789](https://github.com/stlink-org/stlink/pull/789)) +* Support for "STM32+Audio" v2-1 firmware ([#790](https://github.com/stlink-org/stlink/pull/790)) +* Build for Windows under Debian/Ubuntu ([#802](https://github.com/stlink-org/stlink/pull/802)) +* Allow for 64 bytes serials ([#809](https://github.com/stlink-org/stlink/pull/809)) +* Added full support for STLINK CHIP ID L4RX ([#814](https://github.com/stlink-org/stlink/pull/814), [#839](https://github.com/stlink-org/stlink/pull/839)) +* Added support for the STLink-v2.1 when flashed with no mass storage (PID 0x3752) ([#819](https://github.com/stlink-org/stlink/pull/819), [#861](https://github.com/stlink-org/stlink/pull/861)) +* Added support for writing option bytes on STM32L0xx ([#830](https://github.com/stlink-org/stlink/pull/830)) +* Added support to read and write option bytes for STM32F2 series ([#836](https://github.com/stlink-org/stlink/pull/836), [#837](https://github.com/stlink-org/stlink/pull/837)) +* Added support to read and write option bytes for STM32F446 ([#843](https://github.com/stlink-org/stlink/pull/843)) Updates and fixes: -* Fixed "unkown chip id", piped output and st-util -v ([#107](https://github.com/texane/stlink/pull/107), [#665](https://github.com/texane/stlink/pull/665), [#763](https://github.com/texane/stlink/pull/763)) -* Fixed an issue with versioning stuck at 1.4.0 for versions cloned with git ([#563](https://github.com/texane/stlink/pull/563), [#762](https://github.com/texane/stlink/pull/762), [#772](https://github.com/texane/stlink/pull/772)) -* Updated STM32F3xx chip ID that covers a few different devices ([#685](https://github.com/texane/stlink/pull/685), [#758](https://github.com/texane/stlink/pull/758)) -* Made udev rules and modprobe conf installation optional ([#741](https://github.com/texane/stlink/pull/741)) -* Fixed case when __FILE__ don't contain "/" nor "\\" ([#745](https://github.com/texane/stlink/pull/745)) -* Fixed double dash issue in doc/man ([#746](https://github.com/texane/stlink/pull/746), [#747](https://github.com/texane/stlink/pull/747)) -* Compiling documentation: package is called libusb-1.0-0-dev on Debian ([#748](https://github.com/texane/stlink/pull/748)) -* Only do bank calculation on STM32L4 devices with dual banked flash / Added chip-ID 0x464 for STM32L41xxx/L42xxx devices ([#751](https://github.com/texane/stlink/pull/751)) -* Added O_BINARY option to open file ([#753](https://github.com/texane/stlink/pull/753)) -* Fixed versioning when compiling from the checked out git-repo ([#762](https://github.com/texane/stlink/pull/762), [#772](https://github.com/texane/stlink/pull/772)) -* win32: move usleep definition to unistd.h ([#765](https://github.com/texane/stlink/pull/765)) -* Fixed relative path to the UI files needed by stlink-gui-local (GUI) ([#770](https://github.com/texane/stlink/pull/770), [#771](https://github.com/texane/stlink/pull/771)) -* Added howto for sending NRST signal through GDB ([#774](https://github.com/texane/stlink/pull/774), [#776](https://github.com/texane/stlink/pull/776), [#779](https://github.com/texane/stlink/pull/779)) -* Fixed package name "devscripts" in doc/compiling.md ([#775](https://github.com/texane/stlink/pull/775)) -* Fixed few potential memory/resource leaks ([#803](https://github.com/texane/stlink/pull/803)) -* Updated Linux source repositories in README.md: Debian and Ubuntu ([#821](https://github.com/texane/stlink/pull/821), [#835](https://github.com/texane/stlink/pull/835), [#859](https://github.com/texane/stlink/pull/859)) -* Do not issue JTAG reset on stlink-v1 ([#828](https://github.com/texane/stlink/pull/828)) -* Fixed flash size of STM32 Discovery vl ([#829](https://github.com/texane/stlink/pull/829)) -* Updated documentation on software structure ([#851](https://github.com/texane/stlink/pull/851)) +* Fixed "unkown chip id", piped output and st-util -v ([#107](https://github.com/stlink-org/stlink/pull/107), [#665](https://github.com/stlink-org/stlink/pull/665), [#763](https://github.com/stlink-org/stlink/pull/763)) +* Fixed an issue with versioning stuck at 1.4.0 for versions cloned with git ([#563](https://github.com/stlink-org/stlink/pull/563), [#762](https://github.com/stlink-org/stlink/pull/762), [#772](https://github.com/stlink-org/stlink/pull/772)) +* Updated STM32F3xx chip ID that covers a few different devices ([#685](https://github.com/stlink-org/stlink/pull/685), [#758](https://github.com/stlink-org/stlink/pull/758)) +* Made udev rules and modprobe conf installation optional ([#741](https://github.com/stlink-org/stlink/pull/741)) +* Fixed case when __FILE__ don't contain "/" nor "\\" ([#745](https://github.com/stlink-org/stlink/pull/745)) +* Fixed double dash issue in doc/man ([#746](https://github.com/stlink-org/stlink/pull/746), [#747](https://github.com/stlink-org/stlink/pull/747)) +* Compiling documentation: package is called libusb-1.0-0-dev on Debian ([#748](https://github.com/stlink-org/stlink/pull/748)) +* Only do bank calculation on STM32L4 devices with dual banked flash / Added chip-ID 0x464 for STM32L41xxx/L42xxx devices ([#751](https://github.com/stlink-org/stlink/pull/751)) +* Added O_BINARY option to open file ([#753](https://github.com/stlink-org/stlink/pull/753)) +* Fixed versioning when compiling from the checked out git-repo ([#762](https://github.com/stlink-org/stlink/pull/762), [#772](https://github.com/stlink-org/stlink/pull/772)) +* win32: move usleep definition to unistd.h ([#765](https://github.com/stlink-org/stlink/pull/765)) +* Fixed relative path to the UI files needed by stlink-gui-local (GUI) ([#770](https://github.com/stlink-org/stlink/pull/770), [#771](https://github.com/stlink-org/stlink/pull/771)) +* Added howto for sending NRST signal through GDB ([#774](https://github.com/stlink-org/stlink/pull/774), [#776](https://github.com/stlink-org/stlink/pull/776), [#779](https://github.com/stlink-org/stlink/pull/779)) +* Fixed package name "devscripts" in doc/compiling.md ([#775](https://github.com/stlink-org/stlink/pull/775)) +* Fixed few potential memory/resource leaks ([#803](https://github.com/stlink-org/stlink/pull/803)) +* Updated Linux source repositories in README.md: Debian and Ubuntu ([#821](https://github.com/stlink-org/stlink/pull/821), [#835](https://github.com/stlink-org/stlink/pull/835), [#859](https://github.com/stlink-org/stlink/pull/859)) +* Do not issue JTAG reset on stlink-v1 ([#828](https://github.com/stlink-org/stlink/pull/828)) +* Fixed flash size of STM32 Discovery vl ([#829](https://github.com/stlink-org/stlink/pull/829)) +* Updated documentation on software structure ([#851](https://github.com/stlink-org/stlink/pull/851)) General project updates: @@ -62,32 +62,32 @@ Release date: 2018-09-13 Major changes and added features: -* Added reset through AIRCR ([#540](https://github.com/texane/stlink/pull/540), [#712](https://github.com/texane/stlink/pull/712)) -* Added creation of icons for .desktop file ([#684](https://github.com/texane/stlink/pull/684), [#708](https://github.com/texane/stlink/pull/708)) -* Added desktop file for linux ([#688](https://github.com/texane/stlink/pull/688)) -* Added button to export STM32 flash memory to a file ([#691](https://github.com/texane/stlink/pull/691)) -* Updated libusb to 1.0.22 ([#695](https://github.com/texane/stlink/pull/695)) - (related Bugs: [#438](https://github.com/texane/stlink/pull/438), [#632](https://github.com/texane/stlink/pull/632)) -* Added icons for STLink GUI ([#697](https://github.com/texane/stlink/pull/697)) -* Added support for STM32L4R9 target ([#694](https://github.com/texane/stlink/pull/694), [#699](https://github.com/texane/stlink/pull/699)) -* Added memory map for STM32F411RE target ([#709](https://github.com/texane/stlink/pull/709)) -* Implemented intel hex support for GTK GUI ([#713](https://github.com/texane/stlink/pull/713), [#718](https://github.com/texane/stlink/pull/718)) +* Added reset through AIRCR ([#540](https://github.com/stlink-org/stlink/pull/540), [#712](https://github.com/stlink-org/stlink/pull/712)) +* Added creation of icons for .desktop file ([#684](https://github.com/stlink-org/stlink/pull/684), [#708](https://github.com/stlink-org/stlink/pull/708)) +* Added desktop file for linux ([#688](https://github.com/stlink-org/stlink/pull/688)) +* Added button to export STM32 flash memory to a file ([#691](https://github.com/stlink-org/stlink/pull/691)) +* Updated libusb to 1.0.22 ([#695](https://github.com/stlink-org/stlink/pull/695)) - (related Bugs: [#438](https://github.com/stlink-org/stlink/pull/438), [#632](https://github.com/stlink-org/stlink/pull/632)) +* Added icons for STLink GUI ([#697](https://github.com/stlink-org/stlink/pull/697)) +* Added support for STM32L4R9 target ([#694](https://github.com/stlink-org/stlink/pull/694), [#699](https://github.com/stlink-org/stlink/pull/699)) +* Added memory map for STM32F411RE target ([#709](https://github.com/stlink-org/stlink/pull/709)) +* Implemented intel hex support for GTK GUI ([#713](https://github.com/stlink-org/stlink/pull/713), [#718](https://github.com/stlink-org/stlink/pull/718)) Updates and fixes: -* Fixed missing flash_loader for STM32L0x ([#269](https://github.com/texane/stlink/pull/269), [#274](https://github.com/texane/stlink/pull/274), [#654](https://github.com/texane/stlink/pull/654), [#675](https://github.com/texane/stlink/pull/675)) -* Fix for stlink library calls exit() or _exit() ([#634](https://github.com/texane/stlink/pull/634), [#696](https://github.com/texane/stlink/pull/696)) -* Added semihosting parameter documentation in doc/man ([#674](https://github.com/texane/stlink/pull/674)) -* Fixed reference to non-exisiting st-term tool in doc/man ([#676](https://github.com/texane/stlink/pull/676)) -* Fixed serial number size mismatch with stlink_open_usb() ([#680](https://github.com/texane/stlink/pull/680)) -* Debian packaging, CMake and README.md fixes ([#682](https://github.com/texane/stlink/pull/682), [#683](https://github.com/texane/stlink/pull/683)) -* Disabled static library installation by default ([#702](https://github.com/texane/stlink/pull/702)) -* Fix for libusb deprecation ([#703](https://github.com/texane/stlink/pull/703), [#704](https://github.com/texane/stlink/pull/704)) -* Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX ([#706](https://github.com/texane/stlink/pull/706)) -* Regression: stlink installation under Linux (Debian 9) is broken since #695 ([#700](https://github.com/texane/stlink/pull/700), [#701](https://github.com/texane/stlink/pull/701), [#707](https://github.com/texane/stlink/pull/707)) -* Fixed flash memory map for STM32F72xxx target ([#711](https://github.com/texane/stlink/pull/711)) -* Proper flash page size calculation for STM32F412xx target ([#721](https://github.com/texane/stlink/pull/721)) -* Return correct value on EOF for Semihosting SYS_READ ([#726](https://github.com/texane/stlink/pull/726), [#727](https://github.com/texane/stlink/pull/727), [#728](https://github.com/texane/stlink/pull/728), [#729](https://github.com/texane/stlink/pull/729), [#730](https://github.com/texane/stlink/pull/730), [#731](https://github.com/texane/stlink/pull/731), [#732](https://github.com/texane/stlink/pull/732)) -* FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION ([#733](https://github.com/texane/stlink/pull/733)) +* Fixed missing flash_loader for STM32L0x ([#269](https://github.com/stlink-org/stlink/pull/269), [#274](https://github.com/stlink-org/stlink/pull/274), [#654](https://github.com/stlink-org/stlink/pull/654), [#675](https://github.com/stlink-org/stlink/pull/675)) +* Fix for stlink library calls exit() or _exit() ([#634](https://github.com/stlink-org/stlink/pull/634), [#696](https://github.com/stlink-org/stlink/pull/696)) +* Added semihosting parameter documentation in doc/man ([#674](https://github.com/stlink-org/stlink/pull/674)) +* Fixed reference to non-exisiting st-term tool in doc/man ([#676](https://github.com/stlink-org/stlink/pull/676)) +* Fixed serial number size mismatch with stlink_open_usb() ([#680](https://github.com/stlink-org/stlink/pull/680)) +* Debian packaging, CMake and README.md fixes ([#682](https://github.com/stlink-org/stlink/pull/682), [#683](https://github.com/stlink-org/stlink/pull/683)) +* Disabled static library installation by default ([#702](https://github.com/stlink-org/stlink/pull/702)) +* Fix for libusb deprecation ([#703](https://github.com/stlink-org/stlink/pull/703), [#704](https://github.com/stlink-org/stlink/pull/704)) +* Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX ([#706](https://github.com/stlink-org/stlink/pull/706)) +* Regression: stlink installation under Linux (Debian 9) is broken since #695 ([#700](https://github.com/stlink-org/stlink/pull/700), [#701](https://github.com/stlink-org/stlink/pull/701), [#707](https://github.com/stlink-org/stlink/pull/707)) +* Fixed flash memory map for STM32F72xxx target ([#711](https://github.com/stlink-org/stlink/pull/711)) +* Proper flash page size calculation for STM32F412xx target ([#721](https://github.com/stlink-org/stlink/pull/721)) +* Return correct value on EOF for Semihosting SYS_READ ([#726](https://github.com/stlink-org/stlink/pull/726), [#727](https://github.com/stlink-org/stlink/pull/727), [#728](https://github.com/stlink-org/stlink/pull/728), [#729](https://github.com/stlink-org/stlink/pull/729), [#730](https://github.com/stlink-org/stlink/pull/730), [#731](https://github.com/stlink-org/stlink/pull/731), [#732](https://github.com/stlink-org/stlink/pull/732)) +* FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION ([#733](https://github.com/stlink-org/stlink/pull/733)) v1.5.0 @@ -97,21 +97,21 @@ Release date: 2018-02-16 Major changes and added features: -* Added support of STM32L496xx/4A6xx devices ([#615](https://github.com/texane/stlink/pull/615), [#657](https://github.com/texane/stlink/pull/657)) -* Added unknown chip dummy to obtain the serial of the ST-link by a call to st-info --probe ([#641](https://github.com/texane/stlink/pull/641)) -* Added support for STM32F72xx (chip-ID: 0x452) devices (commit [#1969148](https://github.com/texane/stlink/commit/19691485359afef1a256964afcbb8dcf4b733209)) +* Added support of STM32L496xx/4A6xx devices ([#615](https://github.com/stlink-org/stlink/pull/615), [#657](https://github.com/stlink-org/stlink/pull/657)) +* Added unknown chip dummy to obtain the serial of the ST-link by a call to st-info --probe ([#641](https://github.com/stlink-org/stlink/pull/641)) +* Added support for STM32F72xx (chip-ID: 0x452) devices (commit [#1969148](https://github.com/stlink-org/stlink/commit/19691485359afef1a256964afcbb8dcf4b733209)) Updates and fixes: -* Fixed verification of flash error for STM32L496x device ([#617](https://github.com/texane/stlink/pull/617), [#618](https://github.com/texane/stlink/pull/618)) -* Updated Linux source repositories in README.md: Gentoo, Fedora and RedHat/CentOS ([#622](https://github.com/texane/stlink/pull/622), [#635](https://github.com/texane/stlink/pull/635)) -* Updated changelog in debian package ([#630](https://github.com/texane/stlink/pull/630)) -* Added LIB_INSTALL_DIR to correct libs install on 64-bit systems ([#633](https://github.com/texane/stlink/pull/633), [#636](https://github.com/texane/stlink/pull/636)) -* Fixed write for microcontroller with RAM size less or equal to 32K ([#637](https://github.com/texane/stlink/pull/637)) -* Fixed memory map for STM32L496xx boards ([#639](https://github.com/texane/stlink/pull/639)) -* Fixed __FILE__ base name extraction ([#624](https://github.com/texane/stlink/pull/624), [#628](https://github.com/texane/stlink/pull/628), [#648](https://github.com/texane/stlink/pull/648)) -* Added debian/triggers to run ldconfig ([#664](https://github.com/texane/stlink/pull/664)) -* Fixed build on Fedora with GCC 8 ([#666](https://github.com/texane/stlink/pull/666), [#667](https://github.com/texane/stlink/pull/667), [#668](https://github.com/texane/stlink/pull/668)) +* Fixed verification of flash error for STM32L496x device ([#617](https://github.com/stlink-org/stlink/pull/617), [#618](https://github.com/stlink-org/stlink/pull/618)) +* Updated Linux source repositories in README.md: Gentoo, Fedora and RedHat/CentOS ([#622](https://github.com/stlink-org/stlink/pull/622), [#635](https://github.com/stlink-org/stlink/pull/635)) +* Updated changelog in debian package ([#630](https://github.com/stlink-org/stlink/pull/630)) +* Added LIB_INSTALL_DIR to correct libs install on 64-bit systems ([#633](https://github.com/stlink-org/stlink/pull/633), [#636](https://github.com/stlink-org/stlink/pull/636)) +* Fixed write for microcontroller with RAM size less or equal to 32K ([#637](https://github.com/stlink-org/stlink/pull/637)) +* Fixed memory map for STM32L496xx boards ([#639](https://github.com/stlink-org/stlink/pull/639)) +* Fixed __FILE__ base name extraction ([#624](https://github.com/stlink-org/stlink/pull/624), [#628](https://github.com/stlink-org/stlink/pull/628), [#648](https://github.com/stlink-org/stlink/pull/648)) +* Added debian/triggers to run ldconfig ([#664](https://github.com/stlink-org/stlink/pull/664)) +* Fixed build on Fedora with GCC 8 ([#666](https://github.com/stlink-org/stlink/pull/666), [#667](https://github.com/stlink-org/stlink/pull/667), [#668](https://github.com/stlink-org/stlink/pull/668)) v1.4.0 @@ -121,27 +121,27 @@ Release date: 2017-07-01 Major changes and added features: -* Allow building of debian package with CPack ([#554](https://github.com/texane/stlink/pull/554), commit [#5b69f25](https://github.com/texane/stlink/commit/5b69f25198a1a8f34e2ee48d1ad20f79447e3d55)) -* Added support for STM32L011 target ([#564](https://github.com/texane/stlink/pull/564), [#565](https://github.com/texane/stlink/pull/565), [#572](https://github.com/texane/stlink/pull/572)) -* Added support for flashing second bank on STM32F10x_XL ([#592](https://github.com/texane/stlink/pull/592)) -* Initial support to compile with Microsoft Visual Studio 2017 ([#602](https://github.com/texane/stlink/pull/602)) -* Added support for STM32L452 target ([#603](https://github.com/texane/stlink/pull/603), [#608](https://github.com/texane/stlink/pull/608)) +* Allow building of debian package with CPack ([#554](https://github.com/stlink-org/stlink/pull/554), commit [#5b69f25](https://github.com/stlink-org/stlink/commit/5b69f25198a1a8f34e2ee48d1ad20f79447e3d55)) +* Added support for STM32L011 target ([#564](https://github.com/stlink-org/stlink/pull/564), [#565](https://github.com/stlink-org/stlink/pull/565), [#572](https://github.com/stlink-org/stlink/pull/572)) +* Added support for flashing second bank on STM32F10x_XL ([#592](https://github.com/stlink-org/stlink/pull/592)) +* Initial support to compile with Microsoft Visual Studio 2017 ([#602](https://github.com/stlink-org/stlink/pull/602)) +* Added support for STM32L452 target ([#603](https://github.com/stlink-org/stlink/pull/603), [#608](https://github.com/stlink-org/stlink/pull/608)) Updates and fixes: -* Fixed gdb-server: STM32L0xx has no FP_CTRL register for breakpoints ([#273](https://github.com/texane/stlink/pull/273)) -* Added --flash=n[k][m] command line option to override device model ([#305](https://github.com/texane/stlink/pull/305), [#516](https://github.com/texane/stlink/pull/516), [#576](https://github.com/texane/stlink/pull/576)) -* Updated libusb to 1.0.21 for Windows ([#562](https://github.com/texane/stlink/pull/562)) -* Fixed low-voltage flashing on STM32F7 devices ([#566](https://github.com/texane/stlink/pull/566), [#567](https://github.com/texane/stlink/pull/567)) -* Fixed building with mingw64 ([#569](https://github.com/texane/stlink/pull/569), [#573](https://github.com/texane/stlink/pull/573), [#578](https://github.com/texane/stlink/pull/578), [#582](https://github.com/texane/stlink/pull/582), [#584](https://github.com/texane/stlink/pull/584), [#610](https://github.com/texane/stlink/pull/610), [#846](https://github.com/texane/stlink/pull/846)) -* Fixed possible memory leak ([#570](https://github.com/texane/stlink/pull/570), [#571](https://github.com/texane/stlink/pull/571)) -* Fixed installation path for shared objects ([#581](https://github.com/texane/stlink/pull/581)) -* Fixed a few -Wformat warnings ([#582](https://github.com/texane/stlink/pull/582)) -* Removed unused defines in mimgw.h ([#583](https://github.com/texane/stlink/pull/583)) -* Skip GTK detection when cross-compiling ([#588](https://github.com/texane/stlink/pull/588)) -* Fixed compilation with GCC 7 ([#590](https://github.com/texane/stlink/pull/590), [#591](https://github.com/texane/stlink/pull/591)) -* Fixed flashing to 'f0 device' targets ([#594](https://github.com/texane/stlink/pull/594), [#595](https://github.com/texane/stlink/pull/595)) -* Fixed wrong counting when flashing ([#605](https://github.com/texane/stlink/pull/605)) +* Fixed gdb-server: STM32L0xx has no FP_CTRL register for breakpoints ([#273](https://github.com/stlink-org/stlink/pull/273)) +* Added --flash=n[k][m] command line option to override device model ([#305](https://github.com/stlink-org/stlink/pull/305), [#516](https://github.com/stlink-org/stlink/pull/516), [#576](https://github.com/stlink-org/stlink/pull/576)) +* Updated libusb to 1.0.21 for Windows ([#562](https://github.com/stlink-org/stlink/pull/562)) +* Fixed low-voltage flashing on STM32F7 devices ([#566](https://github.com/stlink-org/stlink/pull/566), [#567](https://github.com/stlink-org/stlink/pull/567)) +* Fixed building with mingw64 ([#569](https://github.com/stlink-org/stlink/pull/569), [#573](https://github.com/stlink-org/stlink/pull/573), [#578](https://github.com/stlink-org/stlink/pull/578), [#582](https://github.com/stlink-org/stlink/pull/582), [#584](https://github.com/stlink-org/stlink/pull/584), [#610](https://github.com/stlink-org/stlink/pull/610), [#846](https://github.com/stlink-org/stlink/pull/846)) +* Fixed possible memory leak ([#570](https://github.com/stlink-org/stlink/pull/570), [#571](https://github.com/stlink-org/stlink/pull/571)) +* Fixed installation path for shared objects ([#581](https://github.com/stlink-org/stlink/pull/581)) +* Fixed a few -Wformat warnings ([#582](https://github.com/stlink-org/stlink/pull/582)) +* Removed unused defines in mimgw.h ([#583](https://github.com/stlink-org/stlink/pull/583)) +* Skip GTK detection when cross-compiling ([#588](https://github.com/stlink-org/stlink/pull/588)) +* Fixed compilation with GCC 7 ([#590](https://github.com/stlink-org/stlink/pull/590), [#591](https://github.com/stlink-org/stlink/pull/591)) +* Fixed flashing to 'f0 device' targets ([#594](https://github.com/stlink-org/stlink/pull/594), [#595](https://github.com/stlink-org/stlink/pull/595)) +* Fixed wrong counting when flashing ([#605](https://github.com/stlink-org/stlink/pull/605)) v1.3.1 @@ -151,18 +151,18 @@ Release date: 2017-02-25 Major changes and added features: -* Added support for Semihosting `SYS_READC` ([#546](https://github.com/texane/stlink/pull/546)) -* Added support for STM32F413 ([#549](https://github.com/texane/stlink/pull/549), [#550](https://github.com/texane/stlink/pull/550), [#758](https://github.com/texane/stlink/pull/758)) -* Added preliminary support for STM32L011 to see it after probe (chip-ID 0x457) ([#558](https://github.com/texane/stlink/pull/558), [#598](https://github.com/texane/stlink/pull/598)) +* Added support for Semihosting `SYS_READC` ([#546](https://github.com/stlink-org/stlink/pull/546)) +* Added support for STM32F413 ([#549](https://github.com/stlink-org/stlink/pull/549), [#550](https://github.com/stlink-org/stlink/pull/550), [#758](https://github.com/stlink-org/stlink/pull/758)) +* Added preliminary support for STM32L011 to see it after probe (chip-ID 0x457) ([#558](https://github.com/stlink-org/stlink/pull/558), [#598](https://github.com/stlink-org/stlink/pull/598)) Updates and fixes: * cmake/CPackConfig.cmake: Fixup OSX zip filename * Updated source repositories in README.md: Windows, macOS, Alpine Linux -* Compilation fixes ([#547](https://github.com/texane/stlink/pull/547), [#551](https://github.com/texane/stlink/pull/551), [#552](https://github.com/texane/stlink/pull/552)) -* Stripped full paths to source files in log ([#548](https://github.com/texane/stlink/pull/548)) -* Fixed incorrect release folder name in docs ([#560](https://github.com/texane/stlink/pull/560)) -* Fixed compilation when path includes spaces ([#561](https://github.com/texane/stlink/pull/561)) +* Compilation fixes ([#547](https://github.com/stlink-org/stlink/pull/547), [#551](https://github.com/stlink-org/stlink/pull/551), [#552](https://github.com/stlink-org/stlink/pull/552)) +* Stripped full paths to source files in log ([#548](https://github.com/stlink-org/stlink/pull/548)) +* Fixed incorrect release folder name in docs ([#560](https://github.com/stlink-org/stlink/pull/560)) +* Fixed compilation when path includes spaces ([#561](https://github.com/stlink-org/stlink/pull/561)) v1.3.0 @@ -172,48 +172,48 @@ Release date: 2017-01-28 Major changes and added features: -* Deprecation of autotools (autoconf, automake) and fixed build with MinGW ([#83](https://github.com/texane/stlink/pull/83), [#431](https://github.com/texane/stlink/pull/431), [#434](https://github.com/texane/stlink/pull/434), [#465](https://github.com/texane/stlink/pull/465)) -* Added intel hex file reading for `st-flash` ([#110](https://github.com/texane/stlink/pull/110), [#157](https://github.com/texane/stlink/pull/157), [#457](https://github.com/texane/stlink/pull/547), [#459](https://github.com/texane/stlink/pull/549)) -* Added support for ARM semihosting to `st-util` ([#147](https://github.com/texane/stlink/pull/147), [#227](https://github.com/texane/stlink/pull/227), [#454](https://github.com/texane/stlink/pull/454), [#455](https://github.com/texane/stlink/pull/455)) -* Added manpages (generated with pandoc from Markdown) ([#208](https://github.com/texane/stlink/pull/208), [#464](https://github.com/texane/stlink/pull/464), [#466](https://github.com/texane/stlink/pull/466), [#467](https://github.com/texane/stlink/pull/467)) -* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#228](https://github.com/texane/stlink/pull/228), ([#507](https://github.com/texane/stlink/pull/507), commit [#3fd0f09](https://github.com/texane/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) -* Support serial numbers argument for `st-util` and `st-flash` to probe and control multiple connected programmers ([#318](https://github.com/texane/stlink/pull/318), [#398](https://github.com/texane/stlink/pull/398), [#541](https://github.com/texane/stlink/pull/541)) -* Merge st-probe tool into st-info ([#398](https://github.com/texane/stlink/pull/398)) -* Added support for native debian packaging ([#444](https://github.com/texane/stlink/pull/444), [#472](https://github.com/texane/stlink/pull/472), [#473](https://github.com/texane/stlink/pull/473), [#482](https://github.com/texane/stlink/pull/482), [#483](https://github.com/texane/stlink/pull/483), [#484](https://github.com/texane/stlink/pull/484), [#485](https://github.com/texane/stlink/pull/485)) -* Rewritten commandline parsing for `st-flash` ([#459](https://github.com/texane/stlink/pull/459)) -* Added `--reset` command to `st-flash` ([#505](https://github.com/texane/stlink/pull/505)) -* st-util should detect when USB commands fail ([#525](https://github.com/texane/stlink/pull/525), ([#527](https://github.com/texane/stlink/pull/527), ([#528](https://github.com/texane/stlink/pull/528)) +* Deprecation of autotools (autoconf, automake) and fixed build with MinGW ([#83](https://github.com/stlink-org/stlink/pull/83), [#431](https://github.com/stlink-org/stlink/pull/431), [#434](https://github.com/stlink-org/stlink/pull/434), [#465](https://github.com/stlink-org/stlink/pull/465)) +* Added intel hex file reading for `st-flash` ([#110](https://github.com/stlink-org/stlink/pull/110), [#157](https://github.com/stlink-org/stlink/pull/157), [#457](https://github.com/stlink-org/stlink/pull/547), [#459](https://github.com/stlink-org/stlink/pull/549)) +* Added support for ARM semihosting to `st-util` ([#147](https://github.com/stlink-org/stlink/pull/147), [#227](https://github.com/stlink-org/stlink/pull/227), [#454](https://github.com/stlink-org/stlink/pull/454), [#455](https://github.com/stlink-org/stlink/pull/455)) +* Added manpages (generated with pandoc from Markdown) ([#208](https://github.com/stlink-org/stlink/pull/208), [#464](https://github.com/stlink-org/stlink/pull/464), [#466](https://github.com/stlink-org/stlink/pull/466), [#467](https://github.com/stlink-org/stlink/pull/467)) +* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#228](https://github.com/stlink-org/stlink/pull/228), ([#507](https://github.com/stlink-org/stlink/pull/507), commit [#3fd0f09](https://github.com/stlink-org/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) +* Support serial numbers argument for `st-util` and `st-flash` to probe and control multiple connected programmers ([#318](https://github.com/stlink-org/stlink/pull/318), [#398](https://github.com/stlink-org/stlink/pull/398), [#541](https://github.com/stlink-org/stlink/pull/541)) +* Merge st-probe tool into st-info ([#398](https://github.com/stlink-org/stlink/pull/398)) +* Added support for native debian packaging ([#444](https://github.com/stlink-org/stlink/pull/444), [#472](https://github.com/stlink-org/stlink/pull/472), [#473](https://github.com/stlink-org/stlink/pull/473), [#482](https://github.com/stlink-org/stlink/pull/482), [#483](https://github.com/stlink-org/stlink/pull/483), [#484](https://github.com/stlink-org/stlink/pull/484), [#485](https://github.com/stlink-org/stlink/pull/485)) +* Rewritten commandline parsing for `st-flash` ([#459](https://github.com/stlink-org/stlink/pull/459)) +* Added `--reset` command to `st-flash` ([#505](https://github.com/stlink-org/stlink/pull/505)) +* st-util should detect when USB commands fail ([#525](https://github.com/stlink-org/stlink/pull/525), ([#527](https://github.com/stlink-org/stlink/pull/527), ([#528](https://github.com/stlink-org/stlink/pull/528)) Chip support added for: -* STM32F401XE: Added memory map for device ([#460](https://github.com/texane/stlink/pull/460)) -* STM32F410RBTx ([#418](https://github.com/texane/stlink/pull/418)) -* STM32F412 ([#537](https://github.com/texane/stlink/pull/537), [#538](https://github.com/texane/stlink/pull/538)) -* STM32F7xx ([#324](https://github.com/texane/stlink/pull/324), [#326](https://github.com/texane/stlink/pull/326), [#327](https://github.com/texane/stlink/pull/327), [#337](https://github.com/texane/stlink/pull/337)) -* STM32F7x7x ([#433](https://github.com/texane/stlink/pull/433), [#435](https://github.com/texane/stlink/pull/435), [#436](https://github.com/texane/stlink/pull/436), [#509](https://github.com/texane/stlink/pull/509)) -* STM32L0xx Cat2 devices (chip-ID: 0x425) ([#414](https://github.com/texane/stlink/pull/414)) -* STM32L0xx Cat5 devices (chip-ID: 0x447) ([#387](https://github.com/texane/stlink/pull/387), [#406](https://github.com/texane/stlink/pull/406)) -* STM32L4xx ([#321](https://github.com/texane/stlink/pull/321)) -* STM32L432 ([#500](https://github.com/texane/stlink/pull/500), [#501](https://github.com/texane/stlink/pull/501)) +* STM32F401XE: Added memory map for device ([#460](https://github.com/stlink-org/stlink/pull/460)) +* STM32F410RBTx ([#418](https://github.com/stlink-org/stlink/pull/418)) +* STM32F412 ([#537](https://github.com/stlink-org/stlink/pull/537), [#538](https://github.com/stlink-org/stlink/pull/538)) +* STM32F7xx ([#324](https://github.com/stlink-org/stlink/pull/324), [#326](https://github.com/stlink-org/stlink/pull/326), [#327](https://github.com/stlink-org/stlink/pull/327), [#337](https://github.com/stlink-org/stlink/pull/337)) +* STM32F7x7x ([#433](https://github.com/stlink-org/stlink/pull/433), [#435](https://github.com/stlink-org/stlink/pull/435), [#436](https://github.com/stlink-org/stlink/pull/436), [#509](https://github.com/stlink-org/stlink/pull/509)) +* STM32L0xx Cat2 devices (chip-ID: 0x425) ([#414](https://github.com/stlink-org/stlink/pull/414)) +* STM32L0xx Cat5 devices (chip-ID: 0x447) ([#387](https://github.com/stlink-org/stlink/pull/387), [#406](https://github.com/stlink-org/stlink/pull/406)) +* STM32L4xx ([#321](https://github.com/stlink-org/stlink/pull/321)) +* STM32L432 ([#500](https://github.com/stlink-org/stlink/pull/500), [#501](https://github.com/stlink-org/stlink/pull/501)) Updates and fixes: -* Fixed "unaligned addr or size" when trying to write a program in RAM ([#323](https://github.com/texane/stlink/pull/323)) -* Fixed flashing on STM32_F3_SMALL ([#325](https://github.com/texane/stlink/pull/325)) -* Fixed STM32L-problem with flash loader ([#390](https://github.com/texane/stlink/pull/390), [#407](https://github.com/texane/stlink/pull/407),[#408](https://github.com/texane/stlink/pull/408)) -* Don't read the target voltage on startup, because it crashes STM32F100 ([#423](https://github.com/texane/stlink/pull/423), [#424](https://github.com/texane/stlink/pull/424)) -* Added a useful error message instead of "[!] send_recv" ([#425](https://github.com/texane/stlink/pull/425), [#426](https://github.com/texane/stlink/pull/426)) -* Do a JTAG reset prior to reading CPU information when processor is in deep sleep ([#428](https://github.com/texane/stlink/pull/428), [#430](https://github.com/texane/stlink/pull/430), [#451](https://github.com/texane/stlink/pull/451)) -* Fixed STM32F030 erase error ([#442](https://github.com/texane/stlink/pull/442)) -* Fixed memory map for STM32F7xx ([#453](https://github.com/texane/stlink/pull/453), [#456](https://github.com/texane/stlink/pull/456)) -* Redesign of `st-flash` commandline options parsing ([#459](https://github.com/texane/stlink/pull/459)) -* Set SWDCLK and fixed jtag_reset bug ([#462](https://github.com/texane/stlink/pull/462), [#475](https://github.com/texane/stlink/pull/475), [#534](https://github.com/texane/stlink/pull/534)) -* doc/compiling.md: Add note about installation and ldconfig ([#478](https://github.com/texane/stlink/pull/478), commit [#be66bbf](https://github.com/texane/stlink/commit/be66bbf200c718904514b044ba84d64a36456218)) -* Fixed Release target to generate the man-pages with pandoc ([#479](https://github.com/texane/stlink/pull/479)) -* Fixed Cygwin build ([#487](https://github.com/texane/stlink/pull/487), ([#506](https://github.com/texane/stlink/pull/506)) -* Reset flash mass erase (MER) bit after mass erase for safety ([#489](https://github.com/texane/stlink/pull/489)) -* Wrong extract command in FindLibUSB.cmake ([#510](https://github.com/texane/stlink/pull/510), [#511](https://github.com/texane/stlink/pull/511)) -* Fixed compilation error on Ubuntu 16.10 ([#514](https://github.com/texane/stlink/pull/514), [#525](https://github.com/texane/stlink/pull/525)) +* Fixed "unaligned addr or size" when trying to write a program in RAM ([#323](https://github.com/stlink-org/stlink/pull/323)) +* Fixed flashing on STM32_F3_SMALL ([#325](https://github.com/stlink-org/stlink/pull/325)) +* Fixed STM32L-problem with flash loader ([#390](https://github.com/stlink-org/stlink/pull/390), [#407](https://github.com/stlink-org/stlink/pull/407),[#408](https://github.com/stlink-org/stlink/pull/408)) +* Don't read the target voltage on startup, because it crashes STM32F100 ([#423](https://github.com/stlink-org/stlink/pull/423), [#424](https://github.com/stlink-org/stlink/pull/424)) +* Added a useful error message instead of "[!] send_recv" ([#425](https://github.com/stlink-org/stlink/pull/425), [#426](https://github.com/stlink-org/stlink/pull/426)) +* Do a JTAG reset prior to reading CPU information when processor is in deep sleep ([#428](https://github.com/stlink-org/stlink/pull/428), [#430](https://github.com/stlink-org/stlink/pull/430), [#451](https://github.com/stlink-org/stlink/pull/451)) +* Fixed STM32F030 erase error ([#442](https://github.com/stlink-org/stlink/pull/442)) +* Fixed memory map for STM32F7xx ([#453](https://github.com/stlink-org/stlink/pull/453), [#456](https://github.com/stlink-org/stlink/pull/456)) +* Redesign of `st-flash` commandline options parsing ([#459](https://github.com/stlink-org/stlink/pull/459)) +* Set SWDCLK and fixed jtag_reset bug ([#462](https://github.com/stlink-org/stlink/pull/462), [#475](https://github.com/stlink-org/stlink/pull/475), [#534](https://github.com/stlink-org/stlink/pull/534)) +* doc/compiling.md: Add note about installation and ldconfig ([#478](https://github.com/stlink-org/stlink/pull/478), commit [#be66bbf](https://github.com/stlink-org/stlink/commit/be66bbf200c718904514b044ba84d64a36456218)) +* Fixed Release target to generate the man-pages with pandoc ([#479](https://github.com/stlink-org/stlink/pull/479)) +* Fixed Cygwin build ([#487](https://github.com/stlink-org/stlink/pull/487), ([#506](https://github.com/stlink-org/stlink/pull/506)) +* Reset flash mass erase (MER) bit after mass erase for safety ([#489](https://github.com/stlink-org/stlink/pull/489)) +* Wrong extract command in FindLibUSB.cmake ([#510](https://github.com/stlink-org/stlink/pull/510), [#511](https://github.com/stlink-org/stlink/pull/511)) +* Fixed compilation error on Ubuntu 16.10 ([#514](https://github.com/stlink-org/stlink/pull/514), [#525](https://github.com/stlink-org/stlink/pull/525)) v1.2.0 @@ -245,9 +245,9 @@ Updates and fixes: * Fixed STM32F2xx memory map (Nicolas Schodet) * Memory map for STM32F42xxx and STM32F43xxx devices (Craig Lilley) * Stm32l0x flash loader (Robin Kreis) -* Send F4 memory-map and features for STM32F429 ([#188](https://github.com/texane/stlink/pull/188), [#196](https://github.com/texane/stlink/pull/196), [#250](https://github.com/texane/stlink/pull/250), [#251](https://github.com/texane/stlink/pull/251)) (Release v1.1.0) -* Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/texane/stlink/pull/218), [#288](https://github.com/texane/stlink/pull/288)) (Release v1.1.0) -* Corrected flash size register address for STM32F2 devices ([#278](https://github.com/texane/stlink/pull/278)) (Release v1.0.0) +* Send F4 memory-map and features for STM32F429 ([#188](https://github.com/stlink-org/stlink/pull/188), [#196](https://github.com/stlink-org/stlink/pull/196), [#250](https://github.com/stlink-org/stlink/pull/250), [#251](https://github.com/stlink-org/stlink/pull/251)) (Release v1.1.0) +* Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/stlink-org/stlink/pull/218), [#288](https://github.com/stlink-org/stlink/pull/288)) (Release v1.1.0) +* Corrected flash size register address for STM32F2 devices ([#278](https://github.com/stlink-org/stlink/pull/278)) (Release v1.0.0) Chip support added for: @@ -256,9 +256,9 @@ Chip support added for: * Added STM32L4 to CHIPID #defines and devices[], flash driver and loader (Dave Vandervies) * Basic support for STM32F446 (Pavel Kirienko) * STM32F303 High Density -* STM32F469/STM32F479 ([#345](https://github.com/texane/stlink/pull/345), [#555](https://github.com/texane/stlink/pull/555)) (Release v1.2.0) +* STM32F469/STM32F479 ([#345](https://github.com/stlink-org/stlink/pull/345), [#555](https://github.com/stlink-org/stlink/pull/555)) (Release v1.2.0) * STM32L1xx Cat.2 devices (Nicolas Schodet) -* STM32L1xx (chip-ID 0x427) ([#152](https://github.com/texane/stlink/pull/152), [#163](https://github.com/texane/stlink/pull/163), [#165](https://github.com/texane/stlink/pull/165)) (Release v1.0.0) +* STM32L1xx (chip-ID 0x427) ([#152](https://github.com/stlink-org/stlink/pull/152), [#163](https://github.com/stlink-org/stlink/pull/163), [#165](https://github.com/stlink-org/stlink/pull/165)) (Release v1.0.0) Board support added for: diff --git a/LICENSE.md b/LICENSE.md index 0a3ddd1f7..9c3b59f0f 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2020, The stlink project (github.com/texane/stlink) & "Capt'ns Missing Link" authors. +Copyright (c) 2020, The stlink project (github.com/stlink-org/stlink) & "Capt'ns Missing Link" authors. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.md b/README.md index b2ff03d54..86be05c8f 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,11 @@ Open source version of the STMicroelectronics STlink Tools ========================================================== [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) -[![GitHub release](https://img.shields.io/github/release/texane/stlink.svg)](https://github.com/stlink-org/stlink/releases/latest) -[![GitHub commits](https://img.shields.io/github/commits-since/texane/stlink/v1.6.0.svg)](https://github.com/stlink-org/stlink/releases/master) -[![Downloads](https://img.shields.io/github/downloads/texane/stlink/total.svg)](https://github.com/stlink-org/stlink/releases) -[![Linux Status](https://img.shields.io/travis/texane/stlink/master.svg?label=linux)](https://travis-ci.org/stlink-org/stlink) -[![macOS Status](https://img.shields.io/travis/texane/stlink/master.svg?label=osx)](https://travis-ci.org/stlink-org/stlink) +[![GitHub release](https://img.shields.io/github/release/stlink-org/stlink.svg)](https://github.com/stlink-org/stlink/releases/latest) +[![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.0.svg)](https://github.com/stlink-org/stlink/releases/master) +[![Downloads](https://img.shields.io/github/downloads/stlink-org/stlink/total.svg)](https://github.com/stlink-org/stlink/releases) +[![Linux Status](https://img.shields.io/travis/stlink-org/stlink/master.svg?label=linux)](https://travis-ci.org/stlink-org/stlink) +[![macOS Status](https://img.shields.io/travis/stlink-org/stlink/master.svg?label=osx)](https://travis-ci.org/stlink-org/stlink) Recent new features and bugfixes can be found in the [Changelog](CHANGELOG.md) of this software project. @@ -48,10 +48,12 @@ The STlink toolset includes: * a GUI-Interface (stlink-gui) _[optional]_ -## Supported hardware combinations +## Supported operating systems and hardware combinations Currently known working combinations of programmers and targets are listed in [devices_boards.md](doc/devices_boards.md). +Supported operating systems are listed in [version_support.md](doc/version_support.md). + ## Tutorial & HOWTO @@ -110,13 +112,13 @@ When there is no executable available for your platform or you need the latest ( # Current state of the project ## Known missing features -Some features are currently missing from the `texane/stlink` toolset. +Some features are currently missing from the `stlink-org/stlink` toolset. Here we would appreciate any help and would love to welcome new contributors who want to get involved: -* Instrumentation Trace Macro (ITM) Cell ([#136](https://github.com/texane/stlink/issues/136)) -* OTP & EEPROM area programming ([#202](https://github.com/texane/stlink/issues/202), [#333](https://github.com/texane/stlink/issues/333), [#686](https://github.com/texane/stlink/issues/686)) -* Protection bits area reading ([#346](https://github.com/texane/stlink/issues/346)) -* Writing external memory connected to an STM32 controller (e.g Quad SPI NOR flash) ([#412](https://github.com/texane/stlink/issues/412)) -* MCU hotplug ([#449](https://github.com/texane/stlink/issues/449)) -* Writing options bytes (region) ([#458](https://github.com/texane/stlink/issues/458)) -* Support for STLINKv3 programmer ([#820](https://github.com/texane/stlink/issues/820)) +* Instrumentation Trace Macro (ITM) Cell ([#136](https://github.com/stlink-org/stlink/issues/136)) +* OTP & EEPROM area programming ([#202](https://github.com/stlink-org/stlink/issues/202), [#333](https://github.com/stlink-org/stlink/issues/333), [#686](https://github.com/stlink-org/stlink/issues/686)) +* Protection bits area reading ([#346](https://github.com/stlink-org/stlink/issues/346)) +* Writing external memory connected to an STM32 controller (e.g Quad SPI NOR flash) ([#412](https://github.com/stlink-org/stlink/issues/412)) +* MCU hotplug ([#449](https://github.com/stlink-org/stlink/issues/449)) +* Writing options bytes (region) ([#458](https://github.com/stlink-org/stlink/issues/458)) +* Support for STLINKv3 programmer ([#820](https://github.com/stlink-org/stlink/issues/820)) diff --git a/debian/control b/debian/control index e33fc757c..3c1e9700f 100644 --- a/debian/control +++ b/debian/control @@ -1,12 +1,12 @@ Source: stlink Priority: optional -Maintainer: Andrew 'Necromant' Andrianov +Maintainer: Luca Bocassi Build-Depends: debhelper (>= 9), cmake, libusb-1.0-0-dev, libgtk-3-dev Standards-Version: 4.1.3 Section: electronics -Homepage: https://github.com/texane/stlink -Vcs-Git: https://github.com/texane/stlink.git -Vcs-Browser: https://github.com/texane/stlink +Homepage: https://github.com/stlink-org/stlink +Vcs-Git: https://github.com/stlink-org/stlink.git +Vcs-Browser: https://github.com/stlink-org/stlink Package: libstlink-dev Section: libdevel diff --git a/debian/copyright b/debian/copyright index 941a4a011..7a6d585c5 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,7 +1,7 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: stlink -Upstream-Contact: Andrew 'Necromant' Andrianov -Source: https://github.com/texane/stlink +Upstream-Contact: Luca Bocassi +Source: https://github.com/stlink-org/stlink Files: * Copyright: 2011-2018 agpanarin diff --git a/debian/watch b/debian/watch index cc653ca9f..20ad1260e 100644 --- a/debian/watch +++ b/debian/watch @@ -1,3 +1,3 @@ version=3 opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/-$1\.tar\.gz/ \ - https://github.com/texane/stlink/tags .*/v?(\d\S+)\.tar\.gz + https://github.com/stlink-org/stlink/tags .*/v?(\d\S+)\.tar\.gz diff --git a/tests/flash.c b/tests/flash.c index d193666ff..27391b244 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -4,8 +4,9 @@ #include #include + #if defined(_MSC_VER) -#include + #include #endif struct Test { @@ -15,39 +16,46 @@ struct Test { }; static bool cmp_strings(const char * s1, const char * s2) { - if (s1 == NULL || s2 == NULL) return (s1 == s2); - else return (0 == strcmp(s1, s2)); + if (s1 == NULL || s2 == NULL) { + return (s1 == s2); + } else { + return (0 == strcmp(s1, s2)); + } } static bool cmp_mem(const uint8_t * s1, const uint8_t * s2, size_t size) { - if (s1 == NULL || s2 == NULL) return (s1 == s2); - else return (0 == memcmp(s1, s2, size)); + if (s1 == NULL || s2 == NULL) { + return (s1 == s2); + } else { + return (0 == memcmp(s1, s2, size)); + } } static bool execute_test(const struct Test * test) { int ac = 0; char* av[32]; - // parse (tokenize) the test command line -#if defined(_MSC_VER) - char *cmd_line = alloca(strlen(test->cmd_line) + 1); -#else - char cmd_line[strlen(test->cmd_line) + 1]; -#endif + /* parse (tokenize) the test command line */ + #if defined(_MSC_VER) + char *cmd_line = alloca(strlen(test->cmd_line) + 1); + #else + char cmd_line[strlen(test->cmd_line) + 1]; + #endif + strcpy(cmd_line, test->cmd_line); for (char * tok = strtok(cmd_line, " "); tok; tok = strtok(NULL, " ")) { - if ((size_t)ac >= sizeof(av)/sizeof(av[0])) return false; - + if ((size_t)ac >= sizeof(av)/sizeof(av[0])) + return false; av[ac] = tok; ++ac; } - // call + /* call */ struct flash_opts opts; int res = flash_get_opts(&opts, ac, av); - // compare results + /* compare results */ bool ret = (res == test->res); if (ret && (res == 0)) { @@ -69,45 +77,115 @@ static bool execute_test(const struct Test * test) { static struct Test tests[] = { { "", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset read /dev/sg0 test.bin 0x80000000 0x1000", 0, - { .cmd = FLASH_CMD_READ, .devname = "/dev/sg0", .serial = { 0 }, .filename = "test.bin", - .addr = 0x80000000, .size = 0x1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { .cmd = FLASH_CMD_READ, + .devname = "/dev/sg0", + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0x1000, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .format = FLASH_FORMAT_BINARY } + }, { "--debug --reset write /dev/sg0 test.bin 0x80000000", 0, - { .cmd = FLASH_CMD_WRITE, .devname = "/dev/sg0", .serial = { 0 }, .filename = "test.bin", - .addr = 0x80000000, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { .cmd = FLASH_CMD_WRITE, + .devname = "/dev/sg0", + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .format = FLASH_FORMAT_BINARY } + }, { "--serial A1020304 /dev/sg0 erase", -1, FLASH_OPTS_INITIALIZER }, { "/dev/sg0 erase", 0, - { .cmd = FLASH_CMD_ERASE, .devname = "/dev/sg0", .serial = { 0 }, .filename = NULL, - .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { .cmd = FLASH_CMD_ERASE, + .devname = "/dev/sg0", + .serial = { 0 }, + .filename = NULL, + .addr = 0, + .size = 0, + .reset = 0, + .log_level = STND_LOG_LEVEL, + .format = FLASH_FORMAT_BINARY } + }, { "--debug --reset read test.bin 0x80000000 0x1000", 0, - { .cmd = FLASH_CMD_READ, .devname = NULL, .serial = { 0 }, .filename = "test.bin", - .addr = 0x80000000, .size = 0x1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { .cmd = FLASH_CMD_READ, + .devname = NULL, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0x1000, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .format = FLASH_FORMAT_BINARY } + }, { "--debug --reset write test.bin 0x80000000", 0, - { .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = { 0 }, .filename = "test.bin", - .addr = 0x80000000, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { .cmd = FLASH_CMD_WRITE, + .devname = NULL, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .format = FLASH_FORMAT_BINARY } + }, { "erase", 0, - { .cmd = FLASH_CMD_ERASE, .devname = NULL, .serial = { 0 }, .filename = NULL, - .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { .cmd = FLASH_CMD_ERASE, + .devname = NULL, + .serial = { 0 }, + .filename = NULL, + .addr = 0, + .size = 0, + .reset = 0, + .log_level = STND_LOG_LEVEL, + .format = FLASH_FORMAT_BINARY } + }, { "--debug --reset --format=ihex write test.hex", 0, - { .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = { 0 }, .filename = "test.hex", - .addr = 0, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_IHEX } }, + { .cmd = FLASH_CMD_WRITE, + .devname = NULL, + .serial = { 0 }, + .filename = "test.hex", + .addr = 0, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .format = FLASH_FORMAT_IHEX } + }, { "--debug --reset --format=binary write test.hex", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset --format=ihex write test.hex 0x80000000", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset write test.hex sometext", -1, FLASH_OPTS_INITIALIZER }, { "--serial A1020304 erase", 0, - { .cmd = FLASH_CMD_ERASE, .devname = NULL, .serial = "\0\0\0\0\0\0\0\0\xA1\x02\x03\x04", .filename = NULL, - .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { .cmd = FLASH_CMD_ERASE, + .devname = NULL, + .serial = "\0\0\0\0\0\0\0\0\xA1\x02\x03\x04", + .filename = NULL, + .addr = 0, + .size = 0, + .reset = 0, + .log_level = STND_LOG_LEVEL, + .format = FLASH_FORMAT_BINARY } + }, { "--serial=A1020304 erase", 0, - { .cmd = FLASH_CMD_ERASE, .devname = NULL, .serial = "\0\0\0\0\0\0\0\0\xA1\x02\x03\x04", .filename = NULL, - .addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { .cmd = FLASH_CMD_ERASE, + .devname = NULL, + .serial = "\0\0\0\0\0\0\0\0\xA1\x02\x03\x04", + .filename = NULL, + .addr = 0, + .size = 0, + .reset = 0, + .log_level = STND_LOG_LEVEL, + .format = FLASH_FORMAT_BINARY } + }, }; -int main() -{ +int main() { bool allOk = true; for (size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) { - if (!execute_test(&tests[i])) allOk = false; + if (!execute_test(&tests[i])) + allOk = false; } - return (allOk ? 0 : 1); } - diff --git a/tests/sg.c b/tests/sg.c index a014717d7..32ef55b69 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -1,6 +1,6 @@ -/* +/* * File: test_main.c - * + * * main() ripped out of old stlink-hw.c */ @@ -10,7 +10,7 @@ #include #if defined(_MSC_VER) -#define __attribute__(x) + #define __attribute__(x) #endif static void __attribute__((unused)) mark_buf(stlink_t *sl) { @@ -24,24 +24,22 @@ static void __attribute__((unused)) mark_buf(stlink_t *sl) { sl->q_buf[16] = 0x33; sl->q_buf[63] = 0x44; sl->q_buf[64] = 0x69; - sl->q_buf[1024 * 6 - 1] = 0x42; //6kB - sl->q_buf[1024 * 8 - 1] = 0x42; //8kB + sl->q_buf[1024 * 6 - 1] = 0x42; // 6kB + sl->q_buf[1024 * 8 - 1] = 0x42; // 8kB } -int main(void) -{ +int main(void) { /* Avoid unused parameter warning */ // set scpi lib debug level: 0 for no debug info, 10 for lots - - fputs( - "\nUsage: stlink-access-test [anything at all] ...\n" - "\n*** Notice: The stlink firmware violates the USB standard.\n" - "*** Because we just use libusb, we can just tell the kernel's\n" - "*** driver to simply ignore the device...\n" - "*** Unplug the stlink and execute once as root:\n" - "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n\n", - stderr); + fputs( + "\nUsage: stlink-access-test [anything at all] ...\n" + "\n*** Notice: The stlink firmware violates the USB standard.\n" + "*** Because we just use libusb, we can just tell the kernel's\n" + "*** driver to simply ignore the device...\n" + "*** Unplug the stlink and execute once as root:\n" + "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n\n", + stderr); stlink_t *sl = stlink_v1_open(99, 1); if (sl == NULL) @@ -51,8 +49,6 @@ int main(void) stlink_enter_swd_mode(sl); stlink_current_mode(sl); stlink_core_id(sl); - //---------------------------------------------------------------------- - stlink_status(sl); //stlink_force_debug(sl); stlink_reset(sl); @@ -67,19 +63,19 @@ int main(void) #if 0 stlink_read_mem32(sl, 0xe000edf0, 4); DD(sl, "DHCSR = 0x%08x", read_uint32(sl->q_buf, 0)); - stlink_read_mem32(sl, 0x4001100c, 4); DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); #endif + #if 0 - // happy new year 2011: let blink all the leds + // let blink all the leds // see "RM0041 Reference manual - STM32F100xx advanced ARM-based 32-bit MCUs" -#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) // pin 8 -#define LED_GREEN (1<<9) // pin 9 + #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) // pin 8 + #define LED_GREEN (1<<9) // pin 9 stlink_read_mem32(sl, GPIOC_CRH, 4); uint32_t io_conf = read_uint32(sl->q_buf, 0); DLOG("GPIOC_CRH = 0x%08x\n", io_conf); @@ -92,8 +88,8 @@ int main(void) for (int i = 0; i < 100; i++) { write_uint32(sl->q_buf, LED_BLUE | LED_GREEN); stlink_write_mem32(sl, GPIOC_ODR, 4); - /* stlink_read_mem32(sl, 0x4001100c, 4); */ - /* DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); */ + //stlink_read_mem32(sl, 0x4001100c, 4); + //DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); usleep(100 * 1000); memset(sl->q_buf, 0, sizeof(sl->q_buf)); @@ -101,8 +97,8 @@ int main(void) usleep(100 * 1000); } write_uint32(sl->q_buf, io_conf); // set old state - #endif + #if 0 // TODO rtfm: stlink doesn't have flash write routines // writing to the flash area confuses the fw for the next read access @@ -119,18 +115,19 @@ int main(void) stlink_read_mem32(sl, 0x08000c00, 256); stlink_read_mem32(sl, 0x08000c00, 256); #endif + #if 0 // sram 0x20000000 8kB fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); mark_buf(sl); //stlink_write_mem8(sl, 0x20000000, 16); - //stlink_write_mem8(sl, 0x20000000, 1); //stlink_write_mem8(sl, 0x20000001, 1); stlink_write_mem8(sl, 0x2000000b, 3); stlink_read_mem32(sl, 0x20000000, 16); #endif + #if 0 // a not aligned mem32 access doesn't work indeed fputs("\n++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); @@ -149,6 +146,7 @@ int main(void) stlink_write_mem32(sl, 0x20000000, 17); stlink_read_mem32(sl, 0x20000000, 32); #endif + #if 0 // sram 0x20000000 8kB fputs("++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++\n", stderr); @@ -162,26 +160,30 @@ int main(void) stlink_read_mem32(sl, 0x20000000, 1024 * 6); stlink_read_mem32(sl, 0x20000000 + 1024 * 6, 1024 * 2); #endif + #if 0 stlink_run(sl); stlink_status(sl); - stlink_force_debug(sl); stlink_status(sl); #endif + #if 0 /* read the system bootloader */ fputs("\n++++++++++ reading bootloader ++++++++++++++++\n\n", stderr); stlink_fread(sl, "/tmp/barfoo", sl->sys_base, sl->sys_size); #endif + #if 0 /* read the flash memory */ fputs("\n+++++++ read flash memory\n\n", stderr); /* mark_buf(sl); */ stlink_read_mem32(sl, 0x08000000, 4); #endif + #if 0 /* flash programming */ fputs("\n+++++++ program flash memory\n\n", stderr); stlink_fwrite_flash(sl, "/tmp/foobar", 0x08000000); #endif + #if 0 /* check file contents */ fputs("\n+++++++ check flash memory\n\n", stderr); { @@ -189,6 +191,7 @@ int main(void) printf("_____ stlink_fcheck_flash() == %d\n", res); } #endif + #if 0 fputs("\n+++++++ sram write and execute\n\n", stderr); stlink_fwrite_sram(sl, "/tmp/foobar", sl->sram_base); @@ -198,13 +201,13 @@ int main(void) #if 0 stlink_run(sl); stlink_status(sl); - //---------------------------------------------------------------------- // back to mass mode, just in case ... stlink_exit_debug_mode(sl); stlink_current_mode(sl); stlink_close(sl); #endif - //fflush(stderr); fflush(stdout); + //fflush(stderr); + //fflush(stdout); return EXIT_SUCCESS; } diff --git a/tests/usb.c b/tests/usb.c index 06fd73429..082c8583b 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -1,10 +1,9 @@ #include #include -int main(int ac, char** av) -{ - (void)ac; - (void)av; +int main(int ac, char** av) { + (void)ac; + (void)av; stlink_t* sl; struct stlink_reg regs; @@ -43,12 +42,12 @@ int main(int ac, char** av) printf("FP_CTRL\n"); stlink_read_mem32(sl, STLINK_REG_CM3_FP_CTRL, 4); - // no idea what reg this is.. */ - // stlink_read_mem32(sl, 0xe000ed90, 4); + // no idea what reg this is... + //stlink_read_mem32(sl, 0xe000ed90, 4); // no idea what register this is... - // stlink_read_mem32(sl, 0xe000edf0, 4); + //stlink_read_mem32(sl, 0xe000edf0, 4); // offset 0xC into TIM11 register? TIMx_DIER? - // stlink_read_mem32(sl, 0x4001100c, 4); */ + //stlink_read_mem32(sl, 0x4001100c, 4); /* Test 32 bit Write */ write_uint32(sl->q_buf,0x01234567); @@ -72,14 +71,13 @@ int main(int ac, char** av) printf("-- reset\n"); stlink_reset(sl); stlink_force_debug(sl); - /* Test reg write*/ + /* Test reg write */ stlink_write_reg(sl, 0x01234567, 3); stlink_write_reg(sl, 0x89abcdef, 4); stlink_write_reg(sl, 0x12345678, 15); for (off = 0; off < 21; off += 1) stlink_read_reg(sl, off, ®s); - stlink_read_all_regs(sl, ®s); printf("-- status\n"); @@ -96,6 +94,5 @@ int main(int ac, char** av) stlink_close(sl); } - return 0; } From aa38587e3c357b6c09934409baa9d685994a09f9 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 17 Apr 2020 12:54:43 +0200 Subject: [PATCH 0833/1435] Restored functionality of make test builds (Fixes #926) --- include/stlink/tools/flash.h | 3 +-- tests/flash.c | 30 +++++------------------------- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index 659c17f28..15e020b35 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -14,7 +14,6 @@ enum flash_area {FLASH_MAIN_MEMORY = 0, FLASH_SYSTEM_MEMORY = 1,FLASH_OTP = 2, F struct flash_opts { enum flash_cmd cmd; - const char* devname; uint8_t serial[STLINK_SERIAL_MAX_SIZE]; const char* filename; stm32_addr_t addr; @@ -28,7 +27,7 @@ struct flash_opts int opt; }; -#define FLASH_OPTS_INITIALIZER {0, NULL, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0} int flash_get_opts(struct flash_opts* o, int ac, char** av); diff --git a/tests/flash.c b/tests/flash.c index 27391b244..53032474a 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -60,7 +60,6 @@ static bool execute_test(const struct Test * test) { if (ret && (res == 0)) { ret &= (opts.cmd == test->opts.cmd); - ret &= cmp_strings(opts.devname, test->opts.devname); ret &= cmp_mem(opts.serial, test->opts.serial, sizeof(opts.serial)); ret &= cmp_strings(opts.filename, test->opts.filename); ret &= (opts.addr == test->opts.addr); @@ -76,9 +75,8 @@ static bool execute_test(const struct Test * test) { static struct Test tests[] = { { "", -1, FLASH_OPTS_INITIALIZER }, - { "--debug --reset read /dev/sg0 test.bin 0x80000000 0x1000", 0, + { "--debug --reset read test.bin 0x80000000 0x1000", 0, { .cmd = FLASH_CMD_READ, - .devname = "/dev/sg0", .serial = { 0 }, .filename = "test.bin", .addr = 0x80000000, @@ -87,9 +85,8 @@ static struct Test tests[] = { .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, - { "--debug --reset write /dev/sg0 test.bin 0x80000000", 0, + { "--debug --reset write test.bin 0x80000000", 0, { .cmd = FLASH_CMD_WRITE, - .devname = "/dev/sg0", .serial = { 0 }, .filename = "test.bin", .addr = 0x80000000, @@ -98,21 +95,8 @@ static struct Test tests[] = { .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, - { "--serial A1020304 /dev/sg0 erase", -1, FLASH_OPTS_INITIALIZER }, - { "/dev/sg0 erase", 0, - { .cmd = FLASH_CMD_ERASE, - .devname = "/dev/sg0", - .serial = { 0 }, - .filename = NULL, - .addr = 0, - .size = 0, - .reset = 0, - .log_level = STND_LOG_LEVEL, - .format = FLASH_FORMAT_BINARY } - }, { "--debug --reset read test.bin 0x80000000 0x1000", 0, { .cmd = FLASH_CMD_READ, - .devname = NULL, .serial = { 0 }, .filename = "test.bin", .addr = 0x80000000, @@ -123,7 +107,6 @@ static struct Test tests[] = { }, { "--debug --reset write test.bin 0x80000000", 0, { .cmd = FLASH_CMD_WRITE, - .devname = NULL, .serial = { 0 }, .filename = "test.bin", .addr = 0x80000000, @@ -134,7 +117,6 @@ static struct Test tests[] = { }, { "erase", 0, { .cmd = FLASH_CMD_ERASE, - .devname = NULL, .serial = { 0 }, .filename = NULL, .addr = 0, @@ -145,7 +127,6 @@ static struct Test tests[] = { }, { "--debug --reset --format=ihex write test.hex", 0, { .cmd = FLASH_CMD_WRITE, - .devname = NULL, .serial = { 0 }, .filename = "test.hex", .addr = 0, @@ -157,10 +138,10 @@ static struct Test tests[] = { { "--debug --reset --format=binary write test.hex", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset --format=ihex write test.hex 0x80000000", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset write test.hex sometext", -1, FLASH_OPTS_INITIALIZER }, + { "--serial A1020304 erase sometext", -1, FLASH_OPTS_INITIALIZER }, { "--serial A1020304 erase", 0, { .cmd = FLASH_CMD_ERASE, - .devname = NULL, - .serial = "\0\0\0\0\0\0\0\0\xA1\x02\x03\x04", + .serial = "\xA1\x02\x03\x04", .filename = NULL, .addr = 0, .size = 0, @@ -170,8 +151,7 @@ static struct Test tests[] = { }, { "--serial=A1020304 erase", 0, { .cmd = FLASH_CMD_ERASE, - .devname = NULL, - .serial = "\0\0\0\0\0\0\0\0\xA1\x02\x03\x04", + .serial = "\xA1\x02\x03\x04", .filename = NULL, .addr = 0, .size = 0, From 07c5e324a805a21763416e1a419764dd5185effa Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 17 Apr 2020 13:21:07 +0200 Subject: [PATCH 0834/1435] Updated CHANGELOG for upcoming release --- CHANGELOG.md | 61 ++++++++++++++++++++++++++++++++++- CMakeLists.txt | 22 ++++++------- src/stlink-gui/CMakeLists.txt | 2 +- 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cf102910..ce2a9e595 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,65 @@ -Stlink ChangeLog +stlink ChangeLog ================ +v1.6.1 +====== + +Release date: (TBD) + +This release drops support for some older operating systems. Check project README for details. + +Features: + +- Support for STM32L1, SM32L4 option bytes write (#596, #844, #847) +- CMake now creates an uninstall target (#619, #907) +- Support for STM32G4 (#822) +- Add aliased SRAM2 region in the L496 memory map (#824) +- Improved support for STM32G0 (#825, #850, #856, #857) +- Added usb PID and udev rules for STlink v2.1 found on Nucleo-L432KC and Nucleo-L552ze boards (#900) +- STM32G0/G4 improvements (#910) + - Enable mass erase with a flash programming check + - Handle G4 Cat3 devices with configurable dual bank flash by using a helper +- Calculate checksums for flash operations (#862, #924) + +Updates & changes: + +- Improved argument parsing for CLI tools (#378, #922) +- [doc] Updated tutorial: macOS ST-Link-v1 detection (#574, #587) +- Define libusb version compatibility for supported operating systems via LIBUSB_API_VERSION (#211, #782, #895) +- [doc] Verify correct udev configuration for device access (#764) +- Added more error info to WLOGs during probe (#883) +- Added travis build for win32 (#870) +- Added check for libssp during compilation (#885) +- Silence unnecessary messages (#886) +- Set up a libusb log level accordingly to verbosity (commit 49f887d5247fdd28f163b6317790c4f087e652cc) +- [doc] Define libusb & cmake version compatibility (#896, #897, #899, commit 27aa88821197d3ffe82baff4e971c3488ec39899) +- Update for STM32G471/473/474/483/484 devices (#901) +- [doc] st-flash --flash=n[k][m] command line option to override device model (#902) +- [doc] Update compiling instructions (#113, commit 10ae5294cd03aacfc07312010f026d3cb12ea56c) +- [doc] Defined version compatibility and installation instructions for macOS (commit 23c071edea45f6e8852fef52d884a680973d6d8f) +- Deprecated old appveyor-mingw script (commit 97484422008df0f75c978627054776f35842a075) +- Enhanced error log with file path for map_file() (#650, #879, #921) + +Fixes: + +- Fixed wait-loop for flash_loader_run() (#290) +- Clear the PG bit before setting the PER bit (#579, #876) +- Fixed compilation issues with int length on 32-bit platforms (#629, #908) +- Fixed st-info --probe mechanism (#679, #918) +- Fixed sign-compare (size != rep_len) in usb.c (Regression) (#772, #869, #872, #891) +- Avoid re-define of O_BINARY on Windows (#788) +- Fixed st-flash manpage read example (#858) +- Fixed stlink support with no mass storage (#861) +- Make Version.cmake more error-resistant (#872) +- Error return in failed probe (#887, #890) +- Fixed formatting for options display in st-flash & st-info (commits c783d0e777ccc83a7a8be26a4f4d3414e0478560 and 562cd2496e696dbd22950925866aac662d81ee5f) +- Fixed dead loop after an unexpected unplug (#780, #812, #913) +- Fixed broken build on 32-bit systems (#919, #920) +- st-flash: minor usage fix and make cmdline parsing more user friendly (#925) +- Better argument parsing for CLI tools: stlink_open_usb can address v1, v2, v3 (#378, #922) +- Restored functionality of make test builds (Regression) (#926) + + v1.6.0 ====== diff --git a/CMakeLists.txt b/CMakeLists.txt index 87bd47aac..421ec7c6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,7 +107,7 @@ set(STLINK_SOURCE src/md5.c ) -if (WIN32 OR MSYS OR MINGW) +if (WIN32 OR MINGW OR MSYS) set(STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") set(STLINK_HEADERS "${STLINK_HEADERS};src/mingw/mingw.h") endif () @@ -116,6 +116,7 @@ include_directories(${LIBUSB_INCLUDE_DIR}) include_directories(include) include_directories(${PROJECT_BINARY_DIR}/include) include_directories(src/mingw) + if (MSVC) include_directories(src/win32) include_directories(src/getopt) @@ -130,7 +131,7 @@ endif () if (NOT WIN32) set(STLINK_LIB_SHARED ${PROJECT_NAME}) -else () +else (WIN32) set(STLINK_LIB_SHARED ${PROJECT_NAME}-shared) endif () @@ -164,16 +165,13 @@ if (APPLE) target_link_libraries(${STLINK_LIB_SHARED} ${CoreFoundation} ${IOKit} ${ObjC} ${SSP_LIB}) endif () -if (WIN32 OR MSYS OR MINGW) +if (WIN32 OR MINGW OR MSYS) target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} wsock32 ws2_32 ${SSP_LIB}) else () target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB}) endif () -install( - TARGETS ${STLINK_LIB_SHARED} - DESTINATION ${STLINK_LIBRARY_PATH} - ) +install(TARGETS ${STLINK_LIB_SHARED} DESTINATION ${STLINK_LIBRARY_PATH}) ### TODO: Check path ### @@ -188,7 +186,7 @@ add_library( ${STLINK_SOURCE} ) -# Link shared library with Apple macOS libraries +# Link static library with Apple macOS libraries if (APPLE) find_library(ObjC objc) find_library(CoreFoundation CoreFoundation) @@ -196,7 +194,7 @@ if (APPLE) target_link_libraries(${STLINK_LIB_STATIC} ${CoreFoundation} ${IOKit} ${ObjC} ${SSP_LIB}) endif () -if (WIN32 OR MSYS OR MINGW) +if (WIN32 OR MINGW OR MSYS) ### TODO: MinGW OR MSYS on Linux target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} wsock32 ws2_32 ${SSP_LIB}) else () target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB}) @@ -205,7 +203,7 @@ endif () set_target_properties(${STLINK_LIB_STATIC} PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) if (STLINK_STATIC_LIB) - install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH}) + install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH}) ### TODO: Check path endif () @@ -224,7 +222,7 @@ else () target_link_libraries(st-info ${STLINK_LIB_SHARED} ${SSP_LIB}) endif () -install(TARGETS st-flash st-info RUNTIME DESTINATION bin) +install(TARGETS st-flash st-info RUNTIME DESTINATION bin) ### TODO: Check path if (CMAKE_SYSTEM_NAME STREQUAL "Linux") if (STLINK_INSTALL_MODPROBE_CONF) @@ -245,7 +243,7 @@ add_subdirectory(src/stlink-gui) ### add_subdirectory(debian/pkgconfig) -add_subdirectory(include) +add_subdirectory(include) ### TODO: Check path add_subdirectory(doc/man) add_subdirectory(tests) diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index bb6465481..64aba11a5 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -28,6 +28,6 @@ install(TARGETS stlink-gui RUNTIME DESTINATION bin) install(FILES gui.ui DESTINATION ${INSTALLED_UI_DIR}) ### TODO: Check Path if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - install(FILES stlink-gui.desktop DESTINATION share/applications) # Install desktop entry + install(FILES stlink-gui.desktop DESTINATION share/applications) # Install desktop entry install(FILES icons/stlink-gui.svg DESTINATION share/icons/hicolor/scalable/apps) # Install icon endif () From 264417e4b3159cc7664768c26015a9246c828c8c Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 17 Apr 2020 14:41:48 +0200 Subject: [PATCH 0835/1435] Fix for version string read without git --- CMakeLists.txt | 13 +++++++------ cmake/version.cmake | 9 ++++++++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 421ec7c6f..5ea53e114 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,12 +54,14 @@ endif () ### find_package(LibUSB REQUIRED) + if (NOT APPLE AND NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) find_package(PkgConfig) pkg_check_modules(gtk gtk+-3.0) endif () include(CheckIncludeFile) + CHECK_INCLUDE_FILE(sys/mman.h STLINK_HAVE_SYS_MMAN_H) if (STLINK_HAVE_SYS_MMAN_H) add_definitions(-DSTLINK_HAVE_SYS_MMAN_H) @@ -71,8 +73,8 @@ if (STLINK_HAVE_UNISTD_H) endif () include(CheckLibraryExists) -CHECK_LIBRARY_EXISTS(ssp __stack_chk_fail "" _stack_chk_fail_exists) +CHECK_LIBRARY_EXISTS(ssp __stack_chk_fail "" _stack_chk_fail_exists) if (_stack_chk_fail_exists) set(SSP_LIB ssp) else () @@ -151,11 +153,10 @@ message(STATUS "STLINK_LIB_SHARED: ${STLINK_LIB_SHARED}") message(STATUS "PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}") message(STATUS "VERSION: ${STLINK_SHARED_VERSION}") -set_target_properties( - ${STLINK_LIB_SHARED} - PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} - VERSION ${STLINK_SHARED_VERSION} - ) +set_target_properties(${STLINK_LIB_SHARED} PROPERTIES + SOVERSION ${PROJECT_VERSION_MAJOR} + VERSION ${STLINK_SHARED_VERSION} + ) # Link shared library with Apple macOS libraries if (APPLE) diff --git a/cmake/version.cmake b/cmake/version.cmake index 38254409f..da9d76eba 100644 --- a/cmake/version.cmake +++ b/cmake/version.cmake @@ -77,7 +77,14 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") endif(GIT_DESCRIBE_RESULT EQUAL 0) endif () -if (ERROR_FLAG EQUAL 1) +# Failure to read version via git +# Possible cases: +# -> git is not found or +# -> /.git does not exist or +# -> GIT_DESCRIBE failed or +# -> version string is of invalid format + +if (NOT GIT_FOUND OR NOT EXISTS "${PROJECT_SOURCE_DIR}/.git" OR ERROR_FLAG EQUAL 1) message(STATUS "Git and/or repository not found.") # e.g. when building from source package message(STATUS "Try to detect version from \"${PROJECT_SOURCE_DIR}/.version\" file instead...") if (EXISTS ${PROJECT_SOURCE_DIR}/.version) From 155439230a042e24812b505ab5d1f6c7e5a49c3a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 17 Apr 2020 15:43:35 +0200 Subject: [PATCH 0836/1435] Unified naming for cmake modules & paths --- CMakeLists.txt | 4 ++-- cmake/modules/{Find7Zip.cmake => Find7zip.cmake} | 4 ++++ cmake/modules/{FindLibUSB.cmake => Findlibusb.cmake} | 4 ++-- debian/libstlink-dev.install | 3 +-- debian/{pkgconfig => pkg-config}/CMakeLists.txt | 2 +- debian/{pkgconfig => pkg-config}/pkg-config.pc.cmake | 1 - src/stlink-gui/CMakeLists.txt | 2 +- 7 files changed, 11 insertions(+), 9 deletions(-) rename cmake/modules/{Find7Zip.cmake => Find7zip.cmake} (57%) rename cmake/modules/{FindLibUSB.cmake => Findlibusb.cmake} (99%) rename debian/{pkgconfig => pkg-config}/CMakeLists.txt (91%) rename debian/{pkgconfig => pkg-config}/pkg-config.pc.cmake (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ea53e114..a8daa6e62 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,7 @@ endif () # Dependencies ### -find_package(LibUSB REQUIRED) +find_package(libusb REQUIRED) if (NOT APPLE AND NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) find_package(PkgConfig) @@ -243,7 +243,7 @@ add_subdirectory(src/stlink-gui) # Others ### -add_subdirectory(debian/pkgconfig) +add_subdirectory(debian/pkg-config) add_subdirectory(include) ### TODO: Check path add_subdirectory(doc/man) add_subdirectory(tests) diff --git a/cmake/modules/Find7Zip.cmake b/cmake/modules/Find7zip.cmake similarity index 57% rename from cmake/modules/Find7Zip.cmake rename to cmake/modules/Find7zip.cmake index c462f73de..0ccd23a50 100644 --- a/cmake/modules/Find7Zip.cmake +++ b/cmake/modules/Find7zip.cmake @@ -1,3 +1,7 @@ +# Find7zip.cmake +# Detect 7zip file archiver on Windows systems to extract (zip-)archives + + find_program( ZIP_EXECUTABLE NAMES 7z.exe p7zip HINTS "C:\\Program Files\\7-Zip\\" "C:\\Program Files (x86)\\7-Zip\\" diff --git a/cmake/modules/FindLibUSB.cmake b/cmake/modules/Findlibusb.cmake similarity index 99% rename from cmake/modules/FindLibUSB.cmake rename to cmake/modules/Findlibusb.cmake index b583b8491..5b3e80fe6 100644 --- a/cmake/modules/FindLibUSB.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -1,4 +1,4 @@ -# FindLibUSB.cmake +# Findlibusb.cmake # Once done this will define # # LIBUSB_FOUND libusb present on system @@ -75,7 +75,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND ${CMAKE_BUILD_TYPE} MATCHES " if (NOT LIBUSB_FOUND OR EXISTS "/etc/debian_version") # Preparations for installing libusb library - find_package(7Zip REQUIRED) + find_package(7zip REQUIRED) set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) diff --git a/debian/libstlink-dev.install b/debian/libstlink-dev.install index 0c3543cd9..18fd98b03 100644 --- a/debian/libstlink-dev.install +++ b/debian/libstlink-dev.install @@ -1,5 +1,4 @@ usr/include/* usr/lib/*/lib*.a -usr/lib/*/pkgconfig/* +usr/lib/*/pkg-config/* usr/lib/*/lib*.so - diff --git a/debian/pkgconfig/CMakeLists.txt b/debian/pkg-config/CMakeLists.txt similarity index 91% rename from debian/pkgconfig/CMakeLists.txt rename to debian/pkg-config/CMakeLists.txt index 02e80cb72..a31e27e50 100644 --- a/debian/pkgconfig/CMakeLists.txt +++ b/debian/pkg-config/CMakeLists.txt @@ -11,5 +11,5 @@ configure_file( install( FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" - DESTINATION ${STLINK_LIBRARY_PATH}/pkgconfig/ + DESTINATION ${STLINK_LIBRARY_PATH}/pkg-config/ ) diff --git a/debian/pkgconfig/pkg-config.pc.cmake b/debian/pkg-config/pkg-config.pc.cmake similarity index 99% rename from debian/pkgconfig/pkg-config.pc.cmake rename to debian/pkg-config/pkg-config.pc.cmake index 4170bf84b..c00eb070e 100644 --- a/debian/pkgconfig/pkg-config.pc.cmake +++ b/debian/pkg-config/pkg-config.pc.cmake @@ -8,4 +8,3 @@ includedir=${PKG_CONFIG_INCLUDEDIR} libdir=${PKG_CONFIG_LIBDIR} Libs: ${PKG_CONFIG_LIBS} Cflags: ${PKG_CONFIG_CFLAGS} - diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index 64aba11a5..c51cf56af 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -1,6 +1,6 @@ if (NOT gtk_FOUND) message(STATUS "gtk not found!") - return() + return() # no GTK present => no GUI build endif () set(GUI_SOURCES gui.c gui.h) From ccd167379059b9db53d4e788fdca866b409669a1 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 17 Apr 2020 17:01:36 +0200 Subject: [PATCH 0837/1435] Enable pkg_check for gtk on macOS --- CMakeLists.txt | 2 +- doc/compiling.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a8daa6e62..ee74227fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,7 @@ endif () find_package(libusb REQUIRED) -if (NOT APPLE AND NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) +if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) find_package(PkgConfig) pkg_check_modules(gtk gtk+-3.0) endif () diff --git a/doc/compiling.md b/doc/compiling.md index 59685ef17..a228817a8 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -61,6 +61,7 @@ Install the following packages from your package repository: * `gcc` or `clang` or `mingw32-gcc` or `mingw64-gcc` (C-compiler; very likely gcc is already present) * `build-essential` (on Debian based distros (debian, ubuntu)) * `cmake` (3.4.2 or later, use the latest version available from the repository) +* `pkg-config` * `libusb-1.0` * `libusb-1.0-0-dev` (development headers for building) * `libgtk-3-dev` (_optional_, needed for `stlink-gui`) @@ -168,6 +169,7 @@ Then install the following dependencies from the package repository: * `git` * `cmake` +* `pkg-config` * `libusb` To do this with only one simple command, type: From 9fd9045fdb6c1776ebbeaf634c57739f3e53c826 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 17 Apr 2020 18:13:23 +0200 Subject: [PATCH 0838/1435] General Project Update - Added gtk-package to travis build config - Added gtk to version_support.md (GUI) - Minor correction for CHANGELOG.md - README: Removed reference to OpenBSD --- .travis.yml | 28 ++++++++++++++------------- CHANGELOG.md | 1 - README.md | 1 - doc/version_support.md | 44 +++++++++++++++++++++--------------------- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/.travis.yml b/.travis.yml index 542a25d98..b7ff93ff9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,42 +9,42 @@ matrix: addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-5', 'libusb-1.0.0-dev'] + packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux arch: x64 compiler: gcc-7 addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-7', 'libusb-1.0.0-dev'] + packages: ['gcc-7', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux arch: x64 compiler: gcc-9 addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-9', 'libusb-1.0.0-dev'] + packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux arch: x64 compiler: clang-3.7 addons: apt: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-3.7'] - packages: ['clang-3.7', 'libusb-1.0.0-dev'] + packages: ['clang-3.7', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux arch: x64 compiler: clang-6.0 addons: apt: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] - packages: ['clang-6.0', 'libusb-1.0.0-dev'] + packages: ['clang-6.0', 'libusb-1.0.0-dev', 'libgtk-3-dev'] # - os: linux # arch: x64 # compiler: clang-6.0 # addons: # apt: # sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] -# packages: ['clang-6.0', 'libusb-1.0.0-dev'] +# packages: ['clang-6.0', 'libusb-1.0.0-dev', 'libgtk-3-dev'] # env: CFLAGS=-m32 LDFLAGS=-m32 ### 32-bit builds ### @@ -54,35 +54,35 @@ matrix: addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-5', 'libusb-1.0.0-dev'] + packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux arch: x86 compiler: gcc-7 addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-7', 'libusb-1.0.0-dev'] + packages: ['gcc-7', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux arch: x86 compiler: gcc-9 addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-9', 'libusb-1.0.0-dev'] + packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux arch: x86 compiler: clang-3.7 addons: apt: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-3.7'] - packages: ['clang-3.7', 'libusb-1.0.0-dev'] + packages: ['clang-3.7', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux arch: x86 compiler: clang-6.0 addons: apt: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] - packages: ['clang-6.0', 'libusb-1.0.0-dev'] + packages: ['clang-6.0', 'libusb-1.0.0-dev', 'libgtk-3-dev'] ### macOS ### - os: osx @@ -90,15 +90,17 @@ matrix: addons: homebrew: packages: - - libusb - gcc + - libusb + - gtk+3 - os: osx compiler: clang addons: homebrew: packages: - - libusb - clang + - libusb + - gtk+3 script: - git fetch --tags diff --git a/CHANGELOG.md b/CHANGELOG.md index ce2a9e595..9c6060434 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,6 @@ Updates & changes: - Define libusb version compatibility for supported operating systems via LIBUSB_API_VERSION (#211, #782, #895) - [doc] Verify correct udev configuration for device access (#764) - Added more error info to WLOGs during probe (#883) -- Added travis build for win32 (#870) - Added check for libssp during compilation (#885) - Silence unnecessary messages (#886) - Set up a libusb log level accordingly to verbosity (commit 49f887d5247fdd28f163b6317790c4f087e652cc) diff --git a/README.md b/README.md index 86be05c8f..a0147ed14 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,6 @@ We recommend to install `stlink-tools` from the package repository of the used d * RedHat/CentOS 8: Users can install from [EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel8) * FreeBSD: Users can install from [freshports](https://www.freshports.org/devel/stlink) -* OpenBSD: Users need to compile and install from source as described in our [compiling manual](doc/compiling.md). ## Installation from source (advanced users) diff --git a/doc/version_support.md b/doc/version_support.md index 8b1a9b92d..81d1cc98c 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -16,52 +16,52 @@ Thus no user interaction regarding libusb is necessary. ### Apple macOS -| Package Repository | libusb
    version | cmake
    version | Supported macOS versions | -| --- | --- | --- | --- | -| homebrew | 1.0.23 | 3.17.0 | 10.12 (Sierra)- 10.15 (Catalina) | -| MacPorts | 1.0.23 | 3.17.0 | 10.6 (Snow Leopard) - 10.15 (Catalina) | +| Package Repository | libusb
    version | cmake
    version | gtk
    version | Supported macOS versions | +| --- | --- | --- | --- | --- | +| homebrew | 1.0.23 | 3.17.0 | 3.24.18
    gtk+3 | 10.12 (Sierra)- 10.15 (Catalina) | +| MacPorts | 1.0.23 | 3.17.0 | _N/A_ | 10.6 (Snow Leopard) - 10.15 (Catalina) | ### Linux-/Unix-based: -| Operating System | libusb
    version | cmake
    version | Notes | -| --- | --- | --- | --- | +| Operating System | libusb
    version | cmake
    version | gtk
    version | Notes | +| --- | --- | --- | --- | --- | | Alpine Edge | 1.0.23 | 3.17.0 | | | ALT Linux Sisyphus | 1.0.23 | 3.17.0 | | | Arch Linux | 1.0.23 | 3.17.0 | | -| Fedora Rawhide | 1.0.23 | 3.17.0 | named `libusbx`, but `libusb`-codebase is used | +| Fedora Rawhide | 1.0.23 | 3.17.0 | | named `libusbx`, but `libusb`-codebase is used | | KaOS | 1.0.23 | 3.17.0 | | | OpenMandriva Cooker | 1.0.23 | 3.17.0 | | -| PCLinuxOS | 1.0.23 | 3.17.0 | named `lib64usb1.0_0-1.0.23-1pclos2019.x86_64` | +| PCLinuxOS | 1.0.23 | 3.17.0 | | named `lib64usb1.0_0-1.0.23-1pclos2019.x86_64` | | Slackware Current | 1.0.23 | 3.17.0 | | | Solus | 1.0.23 | 3.16.5 | | -| Debian Sid | 1.0.23 | 3.16.3 | | +| Debian Sid | 1.0.23 | 3.16.3 | 3.24.18
    libgtk-3-dev | | | OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | | -| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | | +| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | 3.24.17
    libgtk-3-dev | | | openSUSE Tumbleweed | 1.0.23 | 3.16.2 | | | Alpine 3.11 | 1.0.23 | 3.15.5 | | -| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | | +| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | 3.24.12
    libgtk-3-dev | | | Mageia Cauldron | 1.0.22 | 3.17.0 | | | NetBSD 9.0 | 1.0.22 | 3.16.1 | | | NetBSD 8.1 | 1.0.22 | 3.16.1 | | | NetBSD 7.2 | 1.0.22 | 3.16.1 | | | Alpine 3.10 | 1.0.22 | 3.14.5 | | -| Fedora 31 | 1.0.22 | 3.14.5 | named `libusbx`, but `libusb`-codebase is used | +| Fedora 31 | 1.0.22 | 3.14.5 | | named `libusbx`, but `libusb`-codebase is used | | Mageia 7.1 | 1.0.22 | 3.14.3 | | -| Fedora 30 | 1.0.22 | 3.14.2 | named `libusbx`, but `libusb`-codebase is used | -| Debian 10 (Buster) | 1.0.22 | 3.13.4 | | +| Fedora 30 | 1.0.22 | 3.14.2 | | named `libusbx`, but `libusb`-codebase is used | +| Debian 10 (Buster) | 1.0.22 | 3.13.4 | 3.24.5
    libgtk-3-dev | | | Alpine 3.9 | 1.0.22 | 3.13.0 | | -| CentOS 8 | 1.0.22 | 3.11.4 | named `libusbx`, but `libusb`-codebase is used | +| CentOS 8 | 1.0.22 | 3.11.4 | | named `libusbx`, but `libusb`-codebase is used | | openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | | | openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | | -| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | | -| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | | +| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | 3.22.30
    libgtk-3-dev | | +| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | 3.22.11
    libgtk-3-dev | | | Slackware 14.2 | **1.0.20** | 3.5.2 | | -| Ubuntu 16.04 LTS (Xenial Xerus) | **1.0.20** | 3.5.1 | | +| Ubuntu 16.04 LTS (Xenial Xerus) | **1.0.20** | 3.5.1 | 3.18.9
    libgtk-3-dev | | | OpenMandriva Lx 3.0 | **1.0.20** | **3.4.2** | | -| FreeBSD 13 | **1.0.16** - 1.0.18 | 3.15.5 | linux_libusb-13.0r358841 (integrated) | -| FreeBSD 12 | **1.0.16** - 1.0.18 | 3.15.5 | linux_libusb-11.0r261448_4 (integrated) | -| FreeBSD 11 | **1.0.16** - 1.0.18 | 3.15.5 | linux_libusb-11.0r261448_4 (integrated) | +| FreeBSD 13 | **1.0.16** - 1.0.18 | 3.15.5 | | linux_libusb-13.0r358841 (integrated) | +| FreeBSD 12 | **1.0.16** - 1.0.18 | 3.15.5 | | linux_libusb-11.0r261448_4 (integrated) | +| FreeBSD 11 | **1.0.16** - 1.0.18 | 3.15.5 | | linux_libusb-11.0r261448_4 (integrated) | ## Unsupported Operating Systems as of Release 1.6.1 (2020) @@ -69,7 +69,7 @@ Thus no user interaction regarding libusb is necessary. | Operating System | libusb
    version | cmake
    version | End of OS-Support | Notes | | --- | --- | --- | --- | --- | | CentOS 7 | 1.0.21 | **2.8.12.2** | | named `libusbx`, but `libusb`-codebase is used | -| Debian 8 (Jessie) | 1.0.**19** | 3.0.2 | Jun 2020 | +| Debian 8 (Jessie) | 1.0.**19** | 3.**0.2** | Jun 2020 | | Ubuntu 14.04 LTS (Trusty Tahr) | 1.0.**17** | **2.8.12.2** | Apr 2019 | | CentOS 6 | 1.0.**9** | **2.8.12.2** | Dec 2020 | named `libusbx`, but `libusb`-codebase is used | | Slackware 14.1 | 1.0.**9** | **2.8.12** | | From e98c7d4926ec129e272209552d802a839c743230 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 17 Apr 2020 20:45:33 +0200 Subject: [PATCH 0839/1435] Updated cmake settings from GTK to GTK3 --- CMakeLists.txt | 2 +- src/stlink-gui/CMakeLists.txt | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ee74227fa..e8da6c45c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,7 @@ find_package(libusb REQUIRED) if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) find_package(PkgConfig) - pkg_check_modules(gtk gtk+-3.0) + pkg_check_modules(GTK3 gtk+-3.0) endif () include(CheckIncludeFile) diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index c51cf56af..dee6cc258 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -1,12 +1,14 @@ -if (NOT gtk_FOUND) - message(STATUS "gtk not found!") - return() # no GTK present => no GUI build +if (NOT GTK3_FOUND) + message(STATUS "GTK3 not found!") + return() # no GTK3 present => no GUI build +else (GTK3_FOUND) + message(STATUS "Found GTK3: -I${GTK3_INCLUDE_DIRS}, ${GTK3_LIBRARIES}") endif () set(GUI_SOURCES gui.c gui.h) set(INSTALLED_UI_DIR share/stlink) ### TODO: Check Path -include_directories(SYSTEM ${gtk_INCLUDE_DIRS}) +include_directories(SYSTEM ${GTK3_INCLUDE_DIRS}) # stlink-gui-local add_executable(stlink-gui-local ${GUI_SOURCES}) @@ -14,7 +16,7 @@ set_target_properties( stlink-gui-local PROPERTIES COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}" ### TODO: Check Path ) -target_link_libraries(stlink-gui-local ${STLINK_LIB_STATIC} ${gtk_LDFLAGS} ${SSP_LIB}) +target_link_libraries(stlink-gui-local ${STLINK_LIB_STATIC} ${GTK3_LDFLAGS} ${SSP_LIB}) # stlink-gui add_executable(stlink-gui ${GUI_SOURCES}) @@ -22,7 +24,7 @@ set_target_properties( stlink-gui PROPERTIES COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}" ### TODO: Check Path ) -target_link_libraries(stlink-gui ${STLINK_LIB_STATIC} ${gtk_LDFLAGS} ${SSP_LIB}) +target_link_libraries(stlink-gui ${STLINK_LIB_STATIC} ${GTK3_LDFLAGS} ${SSP_LIB}) install(TARGETS stlink-gui RUNTIME DESTINATION bin) ### TODO: Check Path install(FILES gui.ui DESTINATION ${INSTALLED_UI_DIR}) ### TODO: Check Path From f48914512ceb75790abf40fb8df9ed592ab901e1 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 17 Apr 2020 21:09:05 +0200 Subject: [PATCH 0840/1435] [doc] Updated package requirements - Added info on GTK3 libs & versioning - Updated compiling instructions for macOS --- doc/compiling.md | 15 ++++++---- doc/version_support.md | 68 +++++++++++++++++++++--------------------- 2 files changed, 44 insertions(+), 39 deletions(-) diff --git a/doc/compiling.md b/doc/compiling.md index a228817a8..15d8b4fc2 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -58,6 +58,7 @@ It can be copied from here: `build\3rdparty\libusb-1.0.21\MS32\dll\libusb-1.0.dl Install the following packages from your package repository: +* `git` * `gcc` or `clang` or `mingw32-gcc` or `mingw64-gcc` (C-compiler; very likely gcc is already present) * `build-essential` (on Debian based distros (debian, ubuntu)) * `cmake` (3.4.2 or later, use the latest version available from the repository) @@ -162,22 +163,26 @@ Choose on of the following options _before_ connecting the device to your comput ## macOS ### Common requirements -The best way is to install a package manager for open source software, +The best and recommended way is to install a package manager for open source software, either [homebrew](https://brew.sh) or [MacPorts](https://www.macports.org/). Then install the following dependencies from the package repository: * `git` +* `gcc` or `llvm` (for clang) (C-compiler) * `cmake` * `pkg-config` * `libusb` +* `gtk+3` or `gtk3` (_optional_, needed for `stlink-gui`) To do this with only one simple command, type: -* for homebrew: `sudo brew install git cmake libusb` or -* for MacPorts:`sudo port install git cmake libusb` - -Additionally we recommend to install Xcode which delivers the necessary C-compiler toolchain Clang (LLVM). +* for homebrew: + - with gcc: `sudo brew install git gcc cmake libusb gtk+3` or + - with clang: `sudo brew install git llvm cmake libusb gtk+3` or +* for MacPorts: + - with gcc: `sudo port install git llvm-9.0 cmake libusb gtk3` or + - with clang: `sudo port install git gcc9 cmake libusb gtk3` ### Installation diff --git a/doc/version_support.md b/doc/version_support.md index 81d1cc98c..75def2e66 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -1,5 +1,5 @@ -Sources: [pkgs.org - libusb](https://pkgs.org/search/?q=libusb) & [pkgs.org - cmake](https://pkgs.org/search/?q=cmake) (as of Mar 2020): +_Source:_ pkgs.org - [libusb](https://pkgs.org/search/?q=libusb); [cmake](https://pkgs.org/search/?q=cmake); [gtk](https://pkgs.org/search/?q=gtk) (as of Apr 2020) ## Supported Operating Systems @@ -16,55 +16,55 @@ Thus no user interaction regarding libusb is necessary. ### Apple macOS -| Package Repository | libusb
    version | cmake
    version | gtk
    version | Supported macOS versions | +| Package Repository | libusb
    version | cmake
    version | gtk-3
    version | Supported macOS versions | | --- | --- | --- | --- | --- | | homebrew | 1.0.23 | 3.17.0 | 3.24.18
    gtk+3 | 10.12 (Sierra)- 10.15 (Catalina) | -| MacPorts | 1.0.23 | 3.17.0 | _N/A_ | 10.6 (Snow Leopard) - 10.15 (Catalina) | +| MacPorts | 1.0.23 | 3.17.0 | 3.24.18
    gtk3 | 10.6 (Snow Leopard) - 10.15 (Catalina) | ### Linux-/Unix-based: -| Operating System | libusb
    version | cmake
    version | gtk
    version | Notes | +| Operating System | libusb
    version | cmake
    version | gtk-3
    version | Notes | | --- | --- | --- | --- | --- | -| Alpine Edge | 1.0.23 | 3.17.0 | | -| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | | -| Arch Linux | 1.0.23 | 3.17.0 | | -| Fedora Rawhide | 1.0.23 | 3.17.0 | | named `libusbx`, but `libusb`-codebase is used | -| KaOS | 1.0.23 | 3.17.0 | | -| OpenMandriva Cooker | 1.0.23 | 3.17.0 | | -| PCLinuxOS | 1.0.23 | 3.17.0 | | named `lib64usb1.0_0-1.0.23-1pclos2019.x86_64` | -| Slackware Current | 1.0.23 | 3.17.0 | | -| Solus | 1.0.23 | 3.16.5 | | +| Alpine Edge | 1.0.23 | 3.17.0 | 3.24.18
    gtk+3.0-dev | | +| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | 3.24.18
    libgtk+3-devel | | +| Arch Linux | 1.0.23 | 3.17.0 | 3.24.18
    gtk3 | | +| Fedora Rawhide | 1.0.23 | 3.17.0 | 3.24.18
    gtk3-devel | | named `libusbx`, but
    `libusb`-codebase is used | +| KaOS | 1.0.23 | 3.17.0 | 3.24.18
    gtk3 | | +| OpenMandriva Cooker | 1.0.23 | 3.17.0 | 3.24.18
    libgtk+3.0-devel
    lib64gtk+3.0-devel | | +| PCLinuxOS | 1.0.23
    lib64usb1.0 | 3.17.0 | 3.24.18
    lib64gtk+3.0-devel | | +| Slackware Current | 1.0.23 | 3.17.0 | 3.24.18
    gtk+3 | | +| Solus | 1.0.23 | 3.16.5 | 3.24.16
    libgtk-3-devel | | | Debian Sid | 1.0.23 | 3.16.3 | 3.24.18
    libgtk-3-dev | | -| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | | +| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | 3.24.13
    libgtk+3.0-devel
    lib64gtk+3.0-devel | | | Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | 3.24.17
    libgtk-3-dev | | -| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | | -| Alpine 3.11 | 1.0.23 | 3.15.5 | | +| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | 3.24.16
    gtk3-devel | | +| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.13
    gtk+3.0-dev | | | Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | 3.24.12
    libgtk-3-dev | | -| Mageia Cauldron | 1.0.22 | 3.17.0 | | -| NetBSD 9.0 | 1.0.22 | 3.16.1 | | -| NetBSD 8.1 | 1.0.22 | 3.16.1 | | -| NetBSD 7.2 | 1.0.22 | 3.16.1 | | -| Alpine 3.10 | 1.0.22 | 3.14.5 | | -| Fedora 31 | 1.0.22 | 3.14.5 | | named `libusbx`, but `libusb`-codebase is used | -| Mageia 7.1 | 1.0.22 | 3.14.3 | | -| Fedora 30 | 1.0.22 | 3.14.2 | | named `libusbx`, but `libusb`-codebase is used | +| Mageia Cauldron | 1.0.22 | 3.17.0 | 3.24.18
    libgtk+3.0-devel
    lib64gtk+3.0-devel | | +| NetBSD 9.0 | 1.0.22 | 3.16.1 | 3.24.12
    gtk+3 | | +| NetBSD 8.1 | 1.0.22 | 3.16.1 | 3.24.12
    gtk+3 | | +| NetBSD 7.2 | 1.0.22 | 3.16.1 | _N/A_ | | +| Alpine 3.10 | 1.0.22 | 3.14.5 | 3.24.8
    gtk+3.0-dev | | +| Fedora 31 | 1.0.22 | 3.14.5 | 3.24.12
    gtk3-devel | named `libusbx`, but
    `libusb`-codebase is used | +| Mageia 7.1 | 1.0.22 | 3.14.3 | 3.24.8
    libgtk+3.0-devel
    lib64gtk+3.0-devel | | +| Fedora 30 | 1.0.22 | 3.14.2 | 3.24.8
    gtk3-devel | named `libusbx`, but
    `libusb`-codebase is used | | Debian 10 (Buster) | 1.0.22 | 3.13.4 | 3.24.5
    libgtk-3-dev | | -| Alpine 3.9 | 1.0.22 | 3.13.0 | | -| CentOS 8 | 1.0.22 | 3.11.4 | | named `libusbx`, but `libusb`-codebase is used | -| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | | -| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | | +| Alpine 3.9 | 1.0.22 | 3.13.0 | 3.24.1
    gtk+3.0-dev | | +| CentOS 8 | 1.0.22 | 3.11.4 | 3.22.30
    gtk3-devel | named `libusbx`, but
    `libusb`-codebase is used | +| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | 3.24.14
    gtk3-devel | | +| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | 3.22.30
    gtk3-devel | | | Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | 3.22.30
    libgtk-3-dev | | | Debian 9 (Stretch) | 1.0.21 | 3.7.2 | 3.22.11
    libgtk-3-dev | | -| Slackware 14.2 | **1.0.20** | 3.5.2 | | +| Slackware 14.2 | **1.0.20** | 3.5.2 | 3.18.9
    gtk+3 | | | Ubuntu 16.04 LTS (Xenial Xerus) | **1.0.20** | 3.5.1 | 3.18.9
    libgtk-3-dev | | -| OpenMandriva Lx 3.0 | **1.0.20** | **3.4.2** | | -| FreeBSD 13 | **1.0.16** - 1.0.18 | 3.15.5 | | linux_libusb-13.0r358841 (integrated) | -| FreeBSD 12 | **1.0.16** - 1.0.18 | 3.15.5 | | linux_libusb-11.0r261448_4 (integrated) | -| FreeBSD 11 | **1.0.16** - 1.0.18 | 3.15.5 | | linux_libusb-11.0r261448_4 (integrated) | +| OpenMandriva Lx 3.0 | **1.0.20** | **3.4.2** | 3.18.9
    libgtk+3.0-devel
    lib64gtk+3.0-devel | | +| FreeBSD 13 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
    gtk3 | linux_libusb-13.0r358841
    (integrated) | +| FreeBSD 12 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
    gtk3 | linux_libusb-11.0r261448_4
    (integrated) | +| FreeBSD 11 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
    gtk3 | linux_libusb-11.0r261448_4
    (integrated) | -## Unsupported Operating Systems as of Release 1.6.1 (2020) +## Unsupported Operating Systems (as of Release v1.6.1) | Operating System | libusb
    version | cmake
    version | End of OS-Support | Notes | | --- | --- | --- | --- | --- | From 68fdd3927d9e2ae9fce662458d2be530832c946f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 18 Apr 2020 16:45:05 +0200 Subject: [PATCH 0841/1435] Reconfigured cmake packaging - Refactoring for package config & build - deb-pkg: postinst script with depmod -a (Fixes #845) --- CHANGELOG.md | 2 +- CMakeLists.txt | 60 +++-- Makefile | 11 +- cmake/cpack_config.cmake | 27 --- cmake/linux-mingw32.cmake | 25 -- cmake/linux-mingw64.cmake | 25 -- .../{Find7zip.cmake => Find_7zip.cmake} | 3 +- .../{Findlibusb.cmake => Find_libusb.cmake} | 6 +- cmake/{ => modules}/c_flags.cmake | 12 +- .../get_version.cmake} | 0 cmake/packaging/CMakeLists.txt | 4 + cmake/packaging/cpack_config.cmake | 85 +++++++ cmake/packaging/debian/CMakeLists.txt | 0 cmake/packaging/debian/changelog | 226 ++++++++++++++++++ {debian => cmake/packaging/debian}/copyright | 0 cmake/packaging/debian/postinst | 4 + cmake/packaging/fedora/CMakeLists.txt | 0 cmake/packaging/opensuse/CMakeLists.txt | 0 cmake/packaging/windows/CMakeLists.txt | 0 debian/changelog | 129 ---------- debian/pkg-config/CMakeLists.txt | 26 +- src/stlink-gui/CMakeLists.txt | 2 +- 22 files changed, 385 insertions(+), 262 deletions(-) delete mode 100644 cmake/cpack_config.cmake delete mode 100644 cmake/linux-mingw32.cmake delete mode 100644 cmake/linux-mingw64.cmake rename cmake/modules/{Find7zip.cmake => Find_7zip.cmake} (91%) rename cmake/modules/{Findlibusb.cmake => Find_libusb.cmake} (99%) rename cmake/{ => modules}/c_flags.cmake (88%) rename cmake/{version.cmake => modules/get_version.cmake} (100%) create mode 100644 cmake/packaging/CMakeLists.txt create mode 100644 cmake/packaging/cpack_config.cmake create mode 100644 cmake/packaging/debian/CMakeLists.txt create mode 100644 cmake/packaging/debian/changelog rename {debian => cmake/packaging/debian}/copyright (100%) create mode 100644 cmake/packaging/debian/postinst create mode 100644 cmake/packaging/fedora/CMakeLists.txt create mode 100644 cmake/packaging/opensuse/CMakeLists.txt create mode 100644 cmake/packaging/windows/CMakeLists.txt delete mode 100644 debian/changelog diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c6060434..d0b920f71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -258,7 +258,7 @@ Updates and fixes: * Fixed "unaligned addr or size" when trying to write a program in RAM ([#323](https://github.com/stlink-org/stlink/pull/323)) * Fixed flashing on STM32_F3_SMALL ([#325](https://github.com/stlink-org/stlink/pull/325)) -* Fixed STM32L-problem with flash loader ([#390](https://github.com/stlink-org/stlink/pull/390), [#407](https://github.com/stlink-org/stlink/pull/407),[#408](https://github.com/stlink-org/stlink/pull/408)) +* Fixed STM32L-problem with flash loader ([#390](https://github.com/stlink-org/stlink/pull/390), [#407](https://github.com/stlink-org/stlink/pull/407), [#408](https://github.com/stlink-org/stlink/pull/408)) * Don't read the target voltage on startup, because it crashes STM32F100 ([#423](https://github.com/stlink-org/stlink/pull/423), [#424](https://github.com/stlink-org/stlink/pull/424)) * Added a useful error message instead of "[!] send_recv" ([#425](https://github.com/stlink-org/stlink/pull/425), [#426](https://github.com/stlink-org/stlink/pull/426)) * Do a JTAG reset prior to reading CPU information when processor is in deep sleep ([#428](https://github.com/stlink-org/stlink/pull/428), [#430](https://github.com/stlink-org/stlink/pull/430), [#451](https://github.com/stlink-org/stlink/pull/451)) diff --git a/CMakeLists.txt b/CMakeLists.txt index e8da6c45c..ccb5fefa9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,21 @@ +### +# General cmake settings +### + cmake_minimum_required(VERSION 3.4.2) cmake_policy(SET CMP0042 NEW) set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) + +# Define GNU standard installation directories include(GNUInstallDirs) + +### +# General project settings +### + project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics ST-LINK Tools") @@ -14,10 +27,23 @@ option(STLINK_INSTALL_UDEV_RULES "Install udev rules files" ON) option(STLINK_INSTALL_MODPROBE_CONF "Install modprobe conf files" ON) option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) +# Determine project version +include(${CMAKE_MODULE_PATH}/get_version.cmake) + +# Set C build flags +if (NOT MSVC) + include(${CMAKE_MODULE_PATH}/c_flags.cmake) +else () + message(STATUS "MSVC C Flags override to /MT") + set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") + set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") + set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") + set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") +endif () + + # ==== -#set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) #set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) if (IS_DIRECTORY ${LIB_INSTALL_DIR}) @@ -36,24 +62,12 @@ else () set(STLINK_INCLUDE_PATH "${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_DIR}") endif () -include(cmake/version.cmake) - -if (NOT MSVC) - include(cmake/c_flags.cmake) -else () - message(STATUS "MSVC C Flags override to /MT") - set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") - set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") - set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") - set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") -endif () - ### # Dependencies ### -find_package(libusb REQUIRED) +find_package(_libusb REQUIRED) if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) find_package(PkgConfig) @@ -243,17 +257,21 @@ add_subdirectory(src/stlink-gui) # Others ### -add_subdirectory(debian/pkg-config) add_subdirectory(include) ### TODO: Check path add_subdirectory(doc/man) add_subdirectory(tests) -include(cmake/cpack_config.cmake) -include(CPack) - # ==== +### +# Package build +### + +add_subdirectory(cmake/packaging) +include(cmake/packaging/cpack_config.cmake) + + ### # Uninstall target ### @@ -261,11 +279,11 @@ include(CPack) if (NOT TARGET uninstall) configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" IMMEDIATE @ONLY ) add_custom_target( uninstall COMMAND ${CMAKE_COMMAND} - -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake + -P ${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake ) endif () diff --git a/Makefile b/Makefile index 6b44bd70c..c3bd59c52 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,6 @@ help: rebuild_cache: build/Debug build/Release @$(MAKE) -C build/Debug rebuild_cache @$(MAKE) -C build/Release rebuild_cache - @$(MAKE) -C build/Binary rebuild_cache debug: build/Debug @echo "[DEBUG]" @@ -28,10 +27,6 @@ release: build/Release @echo "[RELEASE]" @$(MAKE) -C build/Release -binary: build/Binary - @echo "[BINARY]" - @$(MAKE) -C build/Binary - package: build/Release @echo "[PACKAGE] Release" @$(MAKE) -C build/Release package @@ -45,11 +40,7 @@ build/Debug: build/Release: @mkdir -p $@ - @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) ../../ - -build/Binary: - @mkdir -p $@ - @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Binary $(CMAKEFLAGS) ../../ + @cd $@ && cmake -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) -Wno-dev ../../ clean: @echo "[CLEAN]" diff --git a/cmake/cpack_config.cmake b/cmake/cpack_config.cmake deleted file mode 100644 index c70cf3a63..000000000 --- a/cmake/cpack_config.cmake +++ /dev/null @@ -1,27 +0,0 @@ -set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) -set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) -set(CPACK_SET_DESTDIR "ON") - -if (APPLE) - set(CPACK_GENERATOR "ZIP") - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-macosx-amd64") - file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/osx") - set(CPACK_INSTALL_PREFIX "") - set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/osx") -elseif (WIN32) - set(CPACK_GENERATOR "ZIP") - file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/dist/windows") - set(CPACK_INSTALL_PREFIX "") - set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist/windows") -elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND EXISTS "/etc/debian_version") - message(STATUS "Debian-based Linux OS detected") - set(CPACK_GENERATOR "DEB") - if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") - set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}-amd64" ) - endif () - - set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/stlink-org/stlink") - set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Luca Boccassi") - set(CPACK_PACKAGE_CONTACT "bluca@debian.org") - set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "STM32 STlink programmer tools") -endif () diff --git a/cmake/linux-mingw32.cmake b/cmake/linux-mingw32.cmake deleted file mode 100644 index 2b4799037..000000000 --- a/cmake/linux-mingw32.cmake +++ /dev/null @@ -1,25 +0,0 @@ -# Sample toolchain file for building for Windows from a Debian/Ubuntu Linux system. -# -# Typical usage: -# *) install cross compiler: `sudo apt-get install mingw-w64` -# *) cd build -# *) cmake -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake .. - -set(CMAKE_SYSTEM_NAME Windows) -set(TOOLCHAIN_PREFIX i686-w64-mingw32) - -# cross compilers to use for C and C++ -set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) -set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) -set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) - -# target environment on the build host system -# set 1st to dir with the cross compiler's C/C++ headers/libs -set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) - -# modify default behavior of FIND_XXX() commands to -# search for headers/libs in the target environment and -# search for programs in the build host environment -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/cmake/linux-mingw64.cmake b/cmake/linux-mingw64.cmake deleted file mode 100644 index f8b523965..000000000 --- a/cmake/linux-mingw64.cmake +++ /dev/null @@ -1,25 +0,0 @@ -# Sample toolchain file for building for Windows from a Debian/Ubuntu Linux system. -# -# Typical usage: -# *) install cross compiler: `sudo apt-get install mingw-w64` -# *) cd build -# *) cmake -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw64.cmake .. - -set(CMAKE_SYSTEM_NAME Windows) -set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) - -# cross compilers to use for C and C++ -set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) -set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) -set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) - -# target environment on the build host system -# set 1st to dir with the cross compiler's C/C++ headers/libs -set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) - -# modify default behavior of FIND_XXX() commands to -# search for headers/libs in the target environment and -# search for programs in the build host environment -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/cmake/modules/Find7zip.cmake b/cmake/modules/Find_7zip.cmake similarity index 91% rename from cmake/modules/Find7zip.cmake rename to cmake/modules/Find_7zip.cmake index 0ccd23a50..c75cf1150 100644 --- a/cmake/modules/Find7zip.cmake +++ b/cmake/modules/Find_7zip.cmake @@ -1,7 +1,6 @@ -# Find7zip.cmake +# Find_7zip.cmake # Detect 7zip file archiver on Windows systems to extract (zip-)archives - find_program( ZIP_EXECUTABLE NAMES 7z.exe p7zip HINTS "C:\\Program Files\\7-Zip\\" "C:\\Program Files (x86)\\7-Zip\\" diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Find_libusb.cmake similarity index 99% rename from cmake/modules/Findlibusb.cmake rename to cmake/modules/Find_libusb.cmake index 5b3e80fe6..e46c6d46e 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Find_libusb.cmake @@ -1,4 +1,4 @@ -# Findlibusb.cmake +# Find_libusb.cmake # Once done this will define # # LIBUSB_FOUND libusb present on system @@ -75,7 +75,9 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND ${CMAKE_BUILD_TYPE} MATCHES " if (NOT LIBUSB_FOUND OR EXISTS "/etc/debian_version") # Preparations for installing libusb library - find_package(7zip REQUIRED) + + find_package(_7zip REQUIRED) + set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) diff --git a/cmake/c_flags.cmake b/cmake/modules/c_flags.cmake similarity index 88% rename from cmake/c_flags.cmake rename to cmake/modules/c_flags.cmake index c7954bf54..d6b12403b 100644 --- a/cmake/c_flags.cmake +++ b/cmake/modules/c_flags.cmake @@ -34,17 +34,17 @@ add_cflag_if_supported("-Wimplicit-function-declaration") # /usr/include/sys/types.h:218: warning: previous declaration of 'truncate' was here ## if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") - add_cflag_if_supported("-Wredundant-decls") + add_cflag_if_supported("-Wredundant-decls") endif () if (NOT WIN32) - add_cflag_if_supported("-fPIC") + add_cflag_if_supported("-fPIC") endif () if (${CMAKE_BUILD_TYPE} MATCHES "Debug") - add_cflag_if_supported("-ggdb") - add_cflag_if_supported("-O0") -else() - add_cflag_if_supported("-O2") + add_cflag_if_supported("-ggdb") + add_cflag_if_supported("-O0") +else () + add_cflag_if_supported("-O2") add_cflag_if_supported("-Werror") endif () diff --git a/cmake/version.cmake b/cmake/modules/get_version.cmake similarity index 100% rename from cmake/version.cmake rename to cmake/modules/get_version.cmake diff --git a/cmake/packaging/CMakeLists.txt b/cmake/packaging/CMakeLists.txt new file mode 100644 index 000000000..e831f611f --- /dev/null +++ b/cmake/packaging/CMakeLists.txt @@ -0,0 +1,4 @@ +add_subdirectory(debian) +add_subdirectory(fedora) +add_subdirectory(opensuse) +add_subdirectory(windows) diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake new file mode 100644 index 000000000..522fb7f11 --- /dev/null +++ b/cmake/packaging/cpack_config.cmake @@ -0,0 +1,85 @@ +### +# Configure package +### + +set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) +set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) +set(CPACK_SET_DESTDIR "ON") +set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist") + +if (APPLE) + set(CPACK_GENERATOR "ZIP") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-macosx-amd64") + set(CPACK_INSTALL_PREFIX "") +elseif (WIN32) ### TODO: Binary build config for windows... + set(CPACK_GENERATOR "ZIP") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-win32") + set(CPACK_INSTALL_PREFIX "") + + # Sample toolchain file for building for Windows from a Debian/Ubuntu Linux system. + # Typical usage: + # *) install cross compiler: `sudo apt-get install mingw-w64` + # *) cd build + # *) cmake -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw64.cmake .. + # *) cmake -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake .. + + #set(CMAKE_SYSTEM_NAME Windows) + #set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) + #set(TOOLCHAIN_PREFIX i686-w64-mingw32) + + # cross compilers to use for C and C++ + #set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) + #set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) + #set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) + + # target environment on the build host system + # set 1st to dir with the cross compiler's C/C++ headers/libs + #set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) + + # modify default behavior of FIND_XXX() commands to + # search for headers/libs in the target environment and + # search for programs in the build host environment + #set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + #set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + #set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND EXISTS "/etc/debian_version") + message(STATUS "Debian-based Linux OS detected") + + ### Debian-specific + set(CPACK_GENERATOR "DEB") + set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "Open source STM32 MCU programming toolset") + set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/stlink-org/stlink") + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Luca Boccassi") + set(CPACK_PACKAGE_CONTACT "bluca@debian.org") + + ## Set debian_revision number + # Convention: Restart the debian_revision at 1 each time the upstream_version is increased. + set(CPACK_DEBIAN_PACKAGE_RELEASE "0") + + ## Debian package name + # CPack DEB generator generates package file name in deb format: + # _-_.deb + set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) + + ## Add CHANGELOG in Debian-specific format + ### TODO + + ## Add license file + ### TODO + + # Include a postinst-script + set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/cmake/packaging/debian/postinst") + + ### rpm-specific ### TODO: Package config for opensuse should go here... + +else () + ### TODO: Package config for fedora should go here... +endif () + + +### +# Build package +### + +include(CPack) diff --git a/cmake/packaging/debian/CMakeLists.txt b/cmake/packaging/debian/CMakeLists.txt new file mode 100644 index 000000000..e69de29bb diff --git a/cmake/packaging/debian/changelog b/cmake/packaging/debian/changelog new file mode 100644 index 000000000..b4e942d7c --- /dev/null +++ b/cmake/packaging/debian/changelog @@ -0,0 +1,226 @@ +stlink (1.6.0) unstable; urgency=medium + +Release date: 2020-02-20 + +Major changes and added features: + +* Initial support for STM32L41X +* Working support for CKS32F103C8T6 and related CKS devices with Core-ID 0x2ba01477 +* Added preliminary support for some STM32G0 chips +* Added support for mass erasing second bank on STM32F10x_XL +* Added call to clear PG bit after writing to flash +* Added support to write option bytes for the STM32G0 +* Added support for STM32WB55 chips +* Added STLink V3SET VID:PIDs to the udev rules +* Support for "STM32+Audio" v2-1 firmware +* Build for Windows under Debian/Ubuntu +* Allow for 64 bytes serials +* Added full support for STLINK CHIP ID L4RX +* Added support for the STLink-v2.1 when flashed with no mass storage (PID 0x3752) +* Added support for writing option bytes on STM32L0xx +* Added support to read and write option bytes for STM32F2 series +* Added support to read and write option bytes for STM32F446 + +Updates and fixes: + +* Fixed "unkown chip id", piped output and st-util -v +* Fixed an issue with versioning stuck at 1.4.0 for versions cloned with git +* Updated STM32F3xx chip ID that covers a few different devices +* Made udev rules and modprobe conf installation optional +* Fixed case when __FILE__ don't contain "/" nor "\\" +* Fixed double dash issue in doc/man +* Compiling documentation: package is called libusb-1.0-0-dev on Debian +* Only do bank calculation on STM32L4 devices with dual banked flash / Added chip-ID 0x464 for STM32L41xxx/L42xxx devices +* Added O_BINARY option to open file +* Fixed versioning when compiling from the checked out git-repo +* win32: move usleep definition to unistd.h +* Fixed relative path to the UI files needed by stlink-gui-local (GUI) +* Added howto for sending NRST signal through GDB +* Fixed package name "devscripts" in doc/compiling.md +* Fixed few potential memory/resource leaks +* Updated Linux source repositories in README.md: Debian and Ubuntu +* Do not issue JTAG reset on stlink-v1 +* Fixed flash size of STM32 Discovery vl +* Updated documentation on software structure + +General project updates: + +* Updated README.md, CHANGELOG.md and issue templates +* Fixed travis build config file +* Added CODE_OF_CONDUCT +* Archived page from github project wiki to doc/wiki_old.md + +-- Luca Boccassi Tue, 25 Feb 2020 22:08:33 +0000 + + +stlink (1.5.1) unstable; urgency=medium + +Release date: 2018-09-13 + +Major changes and added features: + +* Added reset through AIRCR +* Added creation of icons for .desktop file +* Added desktop file for linux +* Added button to export STM32 flash memory to a file +* Updated libusb to 1.0.22 +* Added icons for STLink GUI +* Added support for STM32L4R9 target +* Added memory map for STM32F411RE target +* Implemented intel hex support for GTK GUI + +Updates and fixes: + +* Fixed missing flash_loader for STM32L0x +* Fix for stlink library calls exit() or _exit() +* Added semihosting parameter documentation in doc/man +* Fixed reference to non-exisiting st-term tool in doc/man +* Fixed serial number size mismatch with stlink_open_usb() +* Debian packaging, CMake and README.md fixes +* Disabled static library installation by default +* Fix for libusb deprecation +* Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX +* Regression: stlink installation under Linux (Debian 9) is broken since #695 +* Fixed flash memory map for STM32F72xxx target +* Proper flash page size calculation for STM32F412xx target +* Return correct value on EOF for Semihosting SYS_READ +* FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION + +-- Luca Boccassi Fri, 28 Sep 2018 10:26:39 +0100 + + +stlink (1.5.0) unstable; urgency=medium + +Release date: 2018-02-16 + +Major changes and added features: + +* Added support of STM32L496xx/4A6xx devices +* Added unknown chip dummy to obtain the serial of the ST-link by a call to st-info --probe +* Added support for STM32F72xx (chip-ID: 0x452) devices + +Updates and fixes: + +* Fixed verification of flash error for STM32L496x device +* Updated Linux source repositories in README.md: Gentoo, Fedora and RedHat/CentOS +* Updated changelog in debian package +* Added LIB_INSTALL_DIR to correct libs install on 64-bit systems +* Fixed write for microcontroller with RAM size less or equal to 32K +* Fixed memory map for STM32L496xx boards +* Fixed __FILE__ base name extraction +* Added debian/triggers to run ldconfig +* Fixed build on Fedora with GCC 8 + +-- Luca Boccassi Fri, 16 Mar 2018 16:56:17 +0000 + + +stlink (1.4.0) unstable; urgency=low + +Release date: 2017-07-01 + +Major changes and added features: + +* Allow building of debian package with CPack +* Added support for STM32L011 target +* Added support for flashing second bank on STM32F10x_XL +* Initial support to compile with Microsoft Visual Studio 2017 +* Added support for STM32L452 target + +Updates and fixes: + +* Fixed gdb-server: STM32L0xx has no FP_CTRL register for breakpoints +* Added --flash=n[k][m] command line option to override device model +* Updated libusb to 1.0.21 for Windows +* Fixed low-voltage flashing on STM32F7 devices +* Fixed building with mingw64 +* Fixed possible memory leak +* Fixed installation path for shared objects +* Fixed a few -Wformat warnings +* Removed unused defines in mimgw.h +* Skip GTK detection when cross-compiling +* Fixed compilation with GCC 7 +* Fixed flashing to 'f0 device' targets +* Fixed wrong counting when flashing + +-- Andrew 'Necromant' Andrianov Sat, 01 Jul 2017 00:00:00 +0000 + + +stlink (1.3.1) unstable; urgency=low + +Release date: 2017-02-25 + +Major changes and added features: + +* Added support for Semihosting `SYS_READC` +* Added support for STM32F413 +* Added preliminary support for STM32L011 to see it after probe (chip-ID 0x457) + +Updates and fixes: + +* cmake/CPackConfig.cmake: Fixup OSX zip filename +* Updated source repositories in README.md: Windows, macOS, Alpine Linux +* Compilation fixes +* Stripped full paths to source files in log +* Fixed incorrect release folder name in docs +* Fixed compilation when path includes spaces + +-- Andrew 'Necromant' Andrianov Sat, 25 Feb 2017 00:00:00 +0000 + + +stlink (1.3.0) unstable; urgency=low + +Release date: 2017-01-28 + +Major changes and added features: + +* Deprecation of autotools (autoconf, automake) and fixed build with MinGW +* Added intel hex file reading for `st-flash` +* Added support for ARM semihosting to `st-util` +* Added manpages (generated with pandoc from Markdown) +* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature +* Support serial numbers argument for `st-util` and `st-flash` to probe and control multiple connected programmers +* Merge st-probe tool into st-info +* Added support for native debian packaging +* Rewritten commandline parsing for `st-flash` +* Added `--reset` command to `st-flash` +* st-util should detect when USB commands fail + +Chip support added for: + +* STM32F401XE: Added memory map for device +* STM32F410RBTx +* STM32F412 +* STM32F7xx +* STM32F7x7x +* STM32L0xx Cat2 devices (chip-ID: 0x425) +* STM32L0xx Cat5 devices (chip-ID: 0x447) +* STM32L4xx +* STM32L432 + +Updates and fixes: + +* Fixed "unaligned addr or size" when trying to write a program in RAM +* Fixed flashing on STM32_F3_SMALL +* Fixed STM32L-problem with flash loader +* Don't read the target voltage on startup, because it crashes STM32F100 +* Added a useful error message instead of "[!] send_recv" +* Do a JTAG reset prior to reading CPU information when processor is in deep sleep +* Fixed STM32F030 erase error +* Fixed memory map for STM32F7xx +* Redesign of `st-flash` commandline options parsing +* Set SWDCLK and fixed jtag_reset bug +* doc/compiling.md: Add note about installation and ldconfig +* Fixed Release target to generate the man-pages with pandoc +* Fixed Cygwin build +* Reset flash mass erase (MER) bit after mass erase for safety +* Wrong extract command in FindLibUSB.cmake +* Fixed compilation error on Ubuntu 16.10 + +-- Andrew 'Necromant' Andrianov Sat, 28 Jan 2017 00:00:00 +0000 + + +libstlink (1.2.1) unstable; urgency=low + +* Initial Debian-packaged release. + +-- Andrew 'Necromant' Andrianov Sat, 09 Jul 2016 23:16:07 +0300 diff --git a/debian/copyright b/cmake/packaging/debian/copyright similarity index 100% rename from debian/copyright rename to cmake/packaging/debian/copyright diff --git a/cmake/packaging/debian/postinst b/cmake/packaging/debian/postinst new file mode 100644 index 000000000..bc74428ae --- /dev/null +++ b/cmake/packaging/debian/postinst @@ -0,0 +1,4 @@ +#!/bin/bash +# This `DEBIAN/postinst` script is run post-installation + +depmod -a diff --git a/cmake/packaging/fedora/CMakeLists.txt b/cmake/packaging/fedora/CMakeLists.txt new file mode 100644 index 000000000..e69de29bb diff --git a/cmake/packaging/opensuse/CMakeLists.txt b/cmake/packaging/opensuse/CMakeLists.txt new file mode 100644 index 000000000..e69de29bb diff --git a/cmake/packaging/windows/CMakeLists.txt b/cmake/packaging/windows/CMakeLists.txt new file mode 100644 index 000000000..e69de29bb diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index ac18fd872..000000000 --- a/debian/changelog +++ /dev/null @@ -1,129 +0,0 @@ -stlink (1.5.0) unstable; urgency=medium - - [ Jerry Jacobs ] - * README.md: Update version badge to v1.4.0 - - [ Viallard Anthony ] - * Add support of STM32L496xx/4A6xx devices (#615) - - [ rdlim ] - * Fix verification of flash error for STM32L496x device (#617) (#618) - - [ dflogeras ] - * Add note about availability in Gentoo package manager (#622) - - [ yaofei zheng ] - * update debian package version (#630) - - [ Lyle Cheatham ] - * Minor formatting fix in FAQ section of README.md (#631) - - [ Vasiliy Glazov ] - * README.md: Added information about Fedora and RedHat/CentOS packages. - (#635) - * Added LIB_INSTALL_DIR to correct libs install on 64-bit systems (#636) - - [ Gwenhael Goavec-Merou ] - * fix write for microcontroler with RAM size less or equal to 32K (#637) - - [ Mateusz Krawiec ] - * Fix memory map for stm32l496xx boards. (#639) - - [ Rüdiger Fortanier ] - * Add unknown chip output (#641) - - [ Slyshyk Oleksiy ] - * fix __FILE__ base name extraction, #628 (#648) - - [ texane ] - * STM32F72xx73xx support, from bob.feretich@rafresearch.com - - [ Kirill Kolyshkin ] - * debian/triggers: add (to run ldconfig) (#664) - - [ Slyshyk Oleksiy ] - * Try to fix #666 issue (#667) - * Try to fix 666 issue (#668) - - [ Jerry Jacobs ] - * Update ChangeLog.md - * Update README.md - - [ texane ] - * STM32F042K6 Nucleo-32 Board reported to work, by frank@bauernoeppel.de - - [ Anatol Pomozov ] - * Update .version file to match release number (#670) - - -- Anatol Pomozov Mon, 19 Feb 2018 11:00:29 -0800 - -libstlink (1.4.0) unstable; urgency=low - - * Major changes and added features - - Add support for STM32L452 target (#608) - - Initial support to compile with Microsoft Visual Studio 2017 (#602) - - Added support for flashing second bank on STM32F10x_XL (#592) - - Add support for STM32L011 target (#572) - - Allow building of debian package with CPack (@xor-gate) - * Updates and fixes - - Fix compilation with GCC 7 (#590) - - Skip GTK detection if we're cross-compiling (#588) - - Fix possible memory leak (#570) - - Fix building with mingw64 (#569, #610) - - Update libusb to 1.0.21 for Windows (#562) - - Fixing low-voltage flashing on STM32F7 parts. (#567) - - Update libusb to 1.0.21 for Windows (#562) - - -- Andrew 'Necromant' Andrianov Sat, 01 Jul 2017 00:00:00 +0000 - -libstlink (1.3.1) unstable; urgency=low - - * Major changes and added features: - - Add preliminary support for STM32L011 to see it after probe (chipid 0x457) (@xor-gate) - - Strip full paths to source files in log (commit #2c0ab7f) - - Add support for STM32F413 target (#549) - - Add support for Semihosting SYS_READC (#546) - * Updates and fixes: - - Update documentation markdown files - - Compilation fixes (#552) - - Fix compilation when path includes spaces (#561) - - -- Andrew 'Necromant' Andrianov Sat, 25 Feb 2017 00:00:00 +0000 - -libstlink (1.3.0) unstable; urgency=low - - * Major changes and added features: - - Deprecation of autotools (autoconf, automake) (@xor-gate) - - Removal of undocumented st-term utility, which is now replaced by st-util ARM semihosting feature (#3fd0f09) - - Add support for native debian packaging (#444, #485) - - Add intel hex file reading for st-flash (#459) - - Add --reset command to st-flash (#505) - - Support serial numbers argument for st-util and st-flash for multi-programmer setups (#541) - - Add kill ('k') command to gdb-server for st-util (#9804416) - - Add manpages (generated with pandoc from Markdown) (#464) - - Rewrite commandline parsing for st-flash (#459) - - Add support for ARM semihosting to st-util (#454, #455) - * Chip support added for: - - STM32L432 (#501) - - STM32F412 (#538) - - STM32F410 (#9c635e4) - - Add memory map for STM32F401XE (#460) - - L0x Category 5 devices (#406) - - Add L0 Category 2 device (chip id: 0x425) (#72b8e5e) - * Updates and fixes: - - Fixed STM32F030 erase error (#442) - - Fixed Cygwin build (#68b0f3b) - - Reset flash mass erase (MER) bit after mass erase for safety (#489) - - Fix memory map for STM32F4 (@zulusw) - - Fix STM32L-problem with flash loader (issue #390) (Tom de Boer) - - st-util don't read target voltage on startup as it crashes STM32F100 (probably stlink/v1) (Greg Alexander) - - Do a JTAG reset prior to reading CPU information when processor is in deep sleep (@andyg24) - - Redesign of st-flash commandline options parsing (pull-request #459) (@dev26th) - - -- Andrew 'Necromant' Andrianov Sat, 28 Jan 2017 00:00:00 +0000 - -libstlink (1.2.1) unstable; urgency=low - - * Initial Debian-Packaged Release. - - -- Andrew 'Necromant' Andrianov Sat, 09 Jul 2016 23:16:07 +0300 diff --git a/debian/pkg-config/CMakeLists.txt b/debian/pkg-config/CMakeLists.txt index a31e27e50..fa3a326a8 100644 --- a/debian/pkg-config/CMakeLists.txt +++ b/debian/pkg-config/CMakeLists.txt @@ -1,15 +1,15 @@ -set(PKG_CONFIG_LIBDIR "\${prefix}/lib/\${deb_host_multiarch}") -set(PKG_CONFIG_INCLUDEDIR "\${prefix}/include/\${deb_host_multiarch}/${PROJECT_NAME}") -set(PKG_CONFIG_LIBS "-L\${libdir} -l:libstlink.so.${PROJECT_VERSION_MAJOR}") -set(PKG_CONFIG_CFLAGS "-I\${includedir}") -set(PKG_CONFIG_REQUIRES "libusb-1.0") +#set(PKG_CONFIG_LIBDIR "\${prefix}/lib/\${deb_host_multiarch}") +#set(PKG_CONFIG_INCLUDEDIR "\${prefix}/include/\${deb_host_multiarch}/${PROJECT_NAME}") +#set(PKG_CONFIG_LIBS "-L\${libdir} -l:libstlink.so.${PROJECT_VERSION_MAJOR}") +#set(PKG_CONFIG_CFLAGS "-I\${includedir}") +#set(PKG_CONFIG_REQUIRES "libusb-1.0") -configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" - ) +#configure_file( +# "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.cmake" +# "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" +# ) -install( - FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" - DESTINATION ${STLINK_LIBRARY_PATH}/pkg-config/ - ) +#install( +# FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" +# DESTINATION ${STLINK_LIBRARY_PATH}/debian/ +# ) diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index dee6cc258..74b71cecd 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -1,6 +1,6 @@ if (NOT GTK3_FOUND) message(STATUS "GTK3 not found!") - return() # no GTK3 present => no GUI build + return() # no GTK3 present => no GUI build else (GTK3_FOUND) message(STATUS "Found GTK3: -I${GTK3_INCLUDE_DIRS}, ${GTK3_LIBRARIES}") endif () From 1986173163cdff574abc3cadd30f59744731b6e3 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Sun, 12 Apr 2020 14:45:41 +0200 Subject: [PATCH 0842/1435] stlink_open_usb: load device param returning -1 is not an usb issue. do not abort in case of load device param "error" : this is supposed to return -1 if device is "unknown" or not detected, which is not reaaally an error. we want probe to tell us what is the connected device even if we can not operate it we want probe to tell us that it can not operate it, not to hide the connected stlink --- src/usb.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/usb.c b/src/usb.c index 206600f14..68c484ddd 100644 --- a/src/usb.c +++ b/src/usb.c @@ -1054,11 +1054,8 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST usleep(10000); } - ret = stlink_load_device_params(sl); - if (ret == -1) { - // This one didn't have any message. - goto on_libusb_error; - } + stlink_load_device_params(sl); + return sl; on_libusb_error: From 784ea36bdc3f0a71d67590a64424f2249e8e14cc Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Sun, 12 Apr 2020 16:06:15 +0200 Subject: [PATCH 0843/1435] usb.c: indent, make error use ELOG, and add trace --- src/usb.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/usb.c b/src/usb.c index 68c484ddd..c9ea7039a 100644 --- a/src/usb.c +++ b/src/usb.c @@ -1045,7 +1045,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { - stlink_enter_swd_mode(sl); + stlink_enter_swd_mode(sl); } if (reset) { @@ -1130,9 +1130,9 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { ret = libusb_open(dev, &handle); if (ret < 0) { if (ret == LIBUSB_ERROR_ACCESS) { - WLOG("failed to open USB device (LIBUSB_ERROR_ACCESS), try running as root?\n"); - } else { - WLOG("failed to open USB device (libusb error: %d)\n", ret); + ELOG("Could not open USB device %#06x:%#06x, access error.\n", desc.idVendor, desc.idProduct, ret); + } else { + ELOG("Failed to open USB device %#06x:%#06x, libusb error: %d)\n", desc.idVendor, desc.idProduct, ret); } break; } @@ -1146,8 +1146,10 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { } stlink_t *sl = stlink_open_usb(0, 1, serial); - if (!sl) + if (!sl) { + ELOG("Failed to open USB device %#06x:%#06x\n", desc.idVendor, desc.idProduct); continue; + } _sldevs[slcur++] = sl; } From 5aa001cfab6eb70e697691915c8754553bc83b92 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Sun, 12 Apr 2020 16:31:49 +0200 Subject: [PATCH 0844/1435] flash.c: stlink_open_usb can now return a sl with no, or unknown target. check flash type before attempting to continue flash operations --- src/tools/flash.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tools/flash.c b/src/tools/flash.c index f39b6c6e4..a08581094 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -59,8 +59,14 @@ int main(int ac, char** av) sl = stlink_open_usb(o.log_level, 1, (char *)o.serial); - if (sl == NULL) + if (sl == NULL) { return -1; + } + + if (sl->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { + printf("Failed to connect to target\n"); + return -1; + } if ( o.flash_size != 0u && o.flash_size != sl->flash_size ) { sl->flash_size = o.flash_size; From 8f778b2e4c33d8e5916ea3f19bf4b06f50566537 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Thu, 16 Apr 2020 16:46:27 +0200 Subject: [PATCH 0845/1435] st-util: open usb can return sl pointer with no target connected. Check if connected target chip id is known. Some more info regarding connected chip should be set in chipid to know if debugging / attach is possible, but not yet. some more checks should be done to generate flash map / handle flashing if flash type is not supported.. --- src/gdbserver/gdb-server.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 1c45c2538..2b5b1d3cb 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -234,7 +234,14 @@ int main(int argc, char** argv) { printf("st-util %s\n", STLINK_VERSION); sl = do_connect(&state); - if (sl == NULL) return 1; + if (sl == NULL) { + return 1; + } + + if (sl->chip_id == STLINK_CHIPID_UNKNOWN) { + ELOG("Unsupported Target (Chip ID is %#010x, Core ID is %#010x).\n", sl->chip_id, sl->core_id); + return 1; + } connected_stlink = sl; signal(SIGINT, &cleanup); @@ -245,10 +252,7 @@ int main(int argc, char** argv) { stlink_reset(sl); } - - // This is low-level information for debugging, not useful for normal use. - // So: Demoted to a debug meesage. -- REW - DLOG("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); + DLOG("Chip ID is %#010x, Core ID is %#08x.\n", sl->chip_id, sl->core_id); sl->verbose=0; current_memory_map = make_memory_map(sl); @@ -1852,7 +1856,8 @@ int serve(stlink_t *sl, st_state_t *st) { stlink_close(sl); sl = do_connect(st); - if (sl == NULL) cleanup(0); + if (sl == NULL || sl->chip_id == STLINK_CHIPID_UNKNOWN) + cleanup(0); connected_stlink = sl; if (st->reset) { From 15f1c81b08a8109f314157c79416b9f3037220ac Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Thu, 16 Apr 2020 16:37:19 +0200 Subject: [PATCH 0846/1435] st-util: remove v1/v2 stlink version stuff, useless --- src/gdbserver/gdb-server.c | 42 ++++++++------------------------------ 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 1c45c2538..fdea6246c 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -59,7 +59,6 @@ static const char* current_memory_map = NULL; typedef struct _st_state_t { // things from command line, bleh - int stlink_version; int logging_level; int listen_port; int persistent; @@ -86,21 +85,13 @@ static void cleanup(int signum) { static stlink_t* do_connect(st_state_t *st) { - stlink_t *ret = NULL; - switch (st->stlink_version) { - case 2: - if (serial_specified){ - ret = stlink_open_usb(st->logging_level, st->reset, serialnumber); - } - else { - ret = stlink_open_usb(st->logging_level, st->reset, NULL); - } - break; - case 1: - ret = stlink_v1_open(st->logging_level, st->reset); - break; + stlink_t *sl = NULL; + if (serial_specified) { + sl = stlink_open_usb(st->logging_level, st->reset, serialnumber); + } else { + sl = stlink_open_usb(st->logging_level, st->reset, NULL); } - return ret; + return sl; } @@ -108,8 +99,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"verbose", optional_argument, NULL, 'v'}, - {"stlink_version", required_argument, NULL, 's'}, - {"stlinkv1", no_argument, NULL, '1'}, {"listen_port", required_argument, NULL, 'p'}, {"multi", optional_argument, NULL, 'm'}, {"no-reset", optional_argument, NULL, 'n'}, @@ -123,7 +112,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { " -V, --version\t\tPrint the version\n" " -vXX, --verbose=XX\tSpecify a specific verbosity level (0..99)\n" " -v, --verbose\t\tSpecify generally verbose logging\n" - " -s X, --stlink_version=X\n" "\t\t\tChoose what version of stlink to use, (defaults to 2)\n" " -1, --stlinkv1\tForce stlink version 1\n" " -p 4242, --listen_port=1234\n" @@ -139,7 +127,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { " --serial \n" "\t\t\tUse a specific serial number.\n" "\n" - "The STLINKv2 device to use can be specified in the environment\n" + "The STLINK device to use can be specified in the environment\n" "variable STLINK_DEVICE on the format :.\n" "\n" ; @@ -148,7 +136,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { int option_index = 0; int c; int q; - while ((c = getopt_long(argc, argv, "hv::s:1p:mn", long_options, &option_index)) != -1) { + while ((c = getopt_long(argc, argv, "hv::p:mn", long_options, &option_index)) != -1) { switch (c) { case 0: break; @@ -163,17 +151,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { st->logging_level = DEBUG_LOGGING_LEVEL; } break; - case '1': - st->stlink_version = 1; - break; - case 's': - sscanf(optarg, "%i", &q); - if (q < 0 || q > 2) { - fprintf(stderr, "stlink version %d unknown!\n", q); - exit(EXIT_FAILURE); - } - st->stlink_version = q; - break; case 'p': sscanf(optarg, "%i", &q); if (q < 0) { @@ -225,13 +202,12 @@ int main(int argc, char** argv) { memset(&state, 0, sizeof(state)); // set defaults... - state.stlink_version = 2; state.logging_level = DEFAULT_LOGGING_LEVEL; state.listen_port = DEFAULT_GDB_LISTEN_PORT; state.reset = 1; /* By default, reset board */ parse_options(argc, argv, &state); - printf("st-util %s\n", STLINK_VERSION); + printf("st-util\n"); sl = do_connect(&state); if (sl == NULL) return 1; From 19facc978911790e4f363e4466e7a9d22e7c519a Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 17 Apr 2020 11:41:37 +0200 Subject: [PATCH 0847/1435] indent --- src/common.c | 132 +++++++++++++++++++++++++-------------------------- 1 file changed, 65 insertions(+), 67 deletions(-) diff --git a/src/common.c b/src/common.c index 0ccdeccdb..9694a8b8e 100644 --- a/src/common.c +++ b/src/common.c @@ -696,7 +696,7 @@ static int check_flash_error(stlink_t *sl) { uint32_t res = 0; if ((sl->flash_type == STLINK_FLASH_TYPE_G0) || - (sl->flash_type == STLINK_FLASH_TYPE_G4)) { + (sl->flash_type == STLINK_FLASH_TYPE_G4)) { res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK; } @@ -1172,13 +1172,13 @@ int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, struct s bool stlink_is_core_halted(stlink_t *sl) { - bool ret = false; + bool ret = false; - stlink_status(sl); - if (sl->q_buf[0] == STLINK_CORE_HALTED) - ret = true; + stlink_status(sl); + if (sl->q_buf[0] == STLINK_CORE_HALTED) + ret = true; - return ret; + return ret; } int stlink_step(stlink_t *sl) { @@ -1204,8 +1204,6 @@ int stlink_current_mode(stlink_t *sl) { } - - // End of delegates.... Common code below here... // Endianness @@ -2915,19 +2913,20 @@ static int stlink_write_option_bytes_l1(stlink_t *sl, uint8_t* base, stm32_addr_ if (len==8) { - /* Clear errors */ - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_SR_OFF, 0x00003F00); + /* Clear errors */ + stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_SR_OFF, 0x00003F00); stlink_read_debug32(sl, addr+4, &val); WLOG("2nd option bytes 0x%08x is 0x%08x\n",addr,val); /* Write options bytes */ - write_uint32((unsigned char*) &data, *(uint32_t*) (base+4)); - if ( data != val ) { - WLOG("Writing 2nd option bytes 0x%04x\n", data); - stlink_write_debug32(sl, addr+4, data); - stlink_read_debug32(sl, addr+4, &val); - WLOG("2nd option bytes is 0x%08x\n",val); + write_uint32((unsigned char*) &data, *(uint32_t*) (base+4)); + + if ( data != val ) { + WLOG("Writing 2nd option bytes 0x%04x\n", data); + stlink_write_debug32(sl, addr+4, data); + stlink_read_debug32(sl, addr+4, &val); + WLOG("2nd option bytes is 0x%08x\n",val); } } @@ -3120,7 +3119,6 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_ stlink_write_debug32(sl, FLASH_F4_OPT_CR, (option_byte & 0x0FFFFFFC)|0x00000002); - stlink_read_debug32(sl, FLASH_F4_SR, &val); WLOG("wait BSY flag to be 0\n"); @@ -3210,7 +3208,7 @@ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { } stlink_read_debug32(sl, FLASH_F4_OPT_CR, option_byte); - WLOG("option bytes CR = %x\n",option_byte); + WLOG("option bytes CR = %x\n", option_byte); WLOG("Option flash re-lock\n"); stlink_write_debug32(sl, FLASH_F4_OPT_CR, val | 0x00000001); @@ -3236,23 +3234,23 @@ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) */ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) { - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); - return -1; - } - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F2: - return stlink_read_option_bytes_f2(sl, option_byte); - case STLINK_CHIPID_STM32_F446: - return stlink_read_option_bytes_f4(sl, option_byte); - case STLINK_CHIPID_STM32_G0_CAT1: - case STLINK_CHIPID_STM32_G0_CAT2: - case STLINK_CHIPID_STM32_G4_CAT2: - case STLINK_CHIPID_STM32_G4_CAT3: - return stlink_read_option_bytes_Gx(sl, option_byte); - default: - return stlink_read_option_bytes_generic(sl, option_byte); - } + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F2: + return stlink_read_option_bytes_f2(sl, option_byte); + case STLINK_CHIPID_STM32_F446: + return stlink_read_option_bytes_f4(sl, option_byte); + case STLINK_CHIPID_STM32_G0_CAT1: + case STLINK_CHIPID_STM32_G0_CAT2: + case STLINK_CHIPID_STM32_G4_CAT2: + case STLINK_CHIPID_STM32_G4_CAT3: + return stlink_read_option_bytes_Gx(sl, option_byte); + default: + return stlink_read_option_bytes_generic(sl, option_byte); + } } /** @@ -3276,43 +3274,43 @@ int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) */ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { - if (sl->option_base == 0) { - ELOG("Option bytes writing is currently not supported for connected chip\n"); - return -1; - } - - if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { - ELOG("Option bytes start address out of Option bytes range\n"); - return -1; - } + if (sl->option_base == 0) { + ELOG("Option bytes writing is currently not supported for connected chip\n"); + return -1; + } - if (addr + len > sl->option_base + sl->option_size) { - ELOG("Option bytes data too long\n"); - return -1; - } + if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { + ELOG("Option bytes start address out of Option bytes range\n"); + return -1; + } - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F2: - return stlink_write_option_bytes_f2(sl, base, addr, len); - case STLINK_CHIPID_STM32_F446: - return stlink_write_option_bytes_f4(sl, base, addr, len); - case STLINK_CHIPID_STM32_L0_CAT2: - return stlink_write_option_bytes_l0_cat2(sl, base, addr, len); - case STLINK_CHIPID_STM32_L496X: - return stlink_write_option_bytes_l496x(sl, base, addr, len); - case STLINK_CHIPID_STM32_L152_RE: - case STLINK_CHIPID_STM32_L1_HIGH: - return stlink_write_option_bytes_l1(sl, base, addr, len); - case STLINK_CHIPID_STM32_G0_CAT1: - case STLINK_CHIPID_STM32_G0_CAT2: - case STLINK_CHIPID_STM32_G4_CAT2: - case STLINK_CHIPID_STM32_G4_CAT3: - return stlink_write_option_bytes_gx(sl, base, addr, len); - default: - ELOG("Option bytes writing is currently not implemented for connected chip\n"); + if (addr + len > sl->option_base + sl->option_size) { + ELOG("Option bytes data too long\n"); return -1; } + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F2: + return stlink_write_option_bytes_f2(sl, base, addr, len); + case STLINK_CHIPID_STM32_F446: + return stlink_write_option_bytes_f4(sl, base, addr, len); + case STLINK_CHIPID_STM32_L0_CAT2: + return stlink_write_option_bytes_l0_cat2(sl, base, addr, len); + case STLINK_CHIPID_STM32_L496X: + return stlink_write_option_bytes_l496x(sl, base, addr, len); + case STLINK_CHIPID_STM32_L152_RE: + case STLINK_CHIPID_STM32_L1_HIGH: + return stlink_write_option_bytes_l1(sl, base, addr, len); + case STLINK_CHIPID_STM32_G0_CAT1: + case STLINK_CHIPID_STM32_G0_CAT2: + case STLINK_CHIPID_STM32_G4_CAT2: + case STLINK_CHIPID_STM32_G4_CAT3: + return stlink_write_option_bytes_gx(sl, base, addr, len); + default: + ELOG("Option bytes writing is currently not implemented for connected chip\n"); + return -1; + } + } /** From 2cccbd91beda0145fe89ba70af8d675029191d4d Mon Sep 17 00:00:00 2001 From: Jochen Wilhelmy Date: Sun, 19 Apr 2020 14:18:32 +0200 Subject: [PATCH 0848/1435] Add CMAKEFLAGS and install target --- Makefile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6b44bd70c..9bdea88a9 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,9 @@ ## # This Makefile is used to drive building of Debug and Release targets of CMake ## -MAKEFLAGS += -s + +# additional flags for cmake, e.g. install path -DCMAKE_INSTALL_PREFIX=$(HOME)/.local +CMAKEFLAGS += all: release ci: debug release binary test @@ -10,6 +12,8 @@ help: @echo " debug: Run a debug build" @echo " release: Run a release build" @echo " binary: Build Windows-Binary" + @echo " install: Install release build" + @echo " package: Package release build" @echo " lint: Lint check all source-code" @echo " test: Build and run tests" @echo " clean: Clean all build output" @@ -32,6 +36,10 @@ binary: build/Binary @echo "[BINARY]" @$(MAKE) -C build/Binary +install: build/Release + @echo "[INSTALL] Release" + @$(MAKE) -C build/Release install + package: build/Release @echo "[PACKAGE] Release" @$(MAKE) -C build/Release package From e93c51691e4541ea3fa62b2c1022280f54e3231c Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 19 Apr 2020 21:19:06 +0200 Subject: [PATCH 0849/1435] Removed unused build target --- Makefile | 10 ---------- cmake/modules/Findlibusb.cmake | 4 +--- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 9bdea88a9..a35400617 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,6 @@ ci: debug release binary test help: @echo " debug: Run a debug build" @echo " release: Run a release build" - @echo " binary: Build Windows-Binary" @echo " install: Install release build" @echo " package: Package release build" @echo " lint: Lint check all source-code" @@ -22,7 +21,6 @@ help: rebuild_cache: build/Debug build/Release @$(MAKE) -C build/Debug rebuild_cache @$(MAKE) -C build/Release rebuild_cache - @$(MAKE) -C build/Binary rebuild_cache debug: build/Debug @echo "[DEBUG]" @@ -32,10 +30,6 @@ release: build/Release @echo "[RELEASE]" @$(MAKE) -C build/Release -binary: build/Binary - @echo "[BINARY]" - @$(MAKE) -C build/Binary - install: build/Release @echo "[INSTALL] Release" @$(MAKE) -C build/Release install @@ -55,10 +49,6 @@ build/Release: @mkdir -p $@ @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) ../../ -build/Binary: - @mkdir -p $@ - @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Binary $(CMAKEFLAGS) ../../ - clean: @echo "[CLEAN]" @rm -Rf build diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index 5b3e80fe6..c5366377e 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -41,9 +41,7 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated message(FATAL_ERROR "Expected libusb library not found on your system! Verify your system integrity.") endif () -elseif (WIN32 OR (EXISTS "/etc/debian_version" AND ${CMAKE_BUILD_TYPE} MATCHES "Binary")) - # Windows & Windows-Binary-Build on Debian/Ubuntu - +elseif (WIN32) # Windows # for MinGW/MSYS/MSVC: 64-bit or 32-bit? if (CMAKE_SIZEOF_VOID_P EQUAL 8) set(ARCH 64) From 145ca6d64a44ed867a59229db403ec121086d511 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 19 Apr 2020 23:39:40 +0200 Subject: [PATCH 0850/1435] General Project Update - Updated github branch template - Updated project CHANGELOG.md --- CHANGELOG.md | 8 ++++++-- README.md | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0b920f71..a5cf843c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,14 +12,16 @@ Features: - Support for STM32L1, SM32L4 option bytes write (#596, #844, #847) - CMake now creates an uninstall target (#619, #907) +- Added CMAKEFLAGS and install target (#804, #935) - Support for STM32G4 (#822) - Add aliased SRAM2 region in the L496 memory map (#824) - Improved support for STM32G0 (#825, #850, #856, #857) +- Added postinst script with 'depmod -a' for 'make package' (#845, #931) +- Calculate checksums for flash operations (#862, #924) - Added usb PID and udev rules for STlink v2.1 found on Nucleo-L432KC and Nucleo-L552ze boards (#900) - STM32G0/G4 improvements (#910) - Enable mass erase with a flash programming check - Handle G4 Cat3 devices with configurable dual bank flash by using a helper -- Calculate checksums for flash operations (#862, #924) Updates & changes: @@ -38,6 +40,8 @@ Updates & changes: - [doc] Defined version compatibility and installation instructions for macOS (commit 23c071edea45f6e8852fef52d884a680973d6d8f) - Deprecated old appveyor-mingw script (commit 97484422008df0f75c978627054776f35842a075) - Enhanced error log with file path for map_file() (#650, #879, #921) +- Refactoring: Overall option code rework (#927) +- Refactoring: Build settings / GUI-Build on UNIX-based systems if GTK3 is detected (#929) Fixes: @@ -56,7 +60,7 @@ Fixes: - Fixed broken build on 32-bit systems (#919, #920) - st-flash: minor usage fix and make cmdline parsing more user friendly (#925) - Better argument parsing for CLI tools: stlink_open_usb can address v1, v2, v3 (#378, #922) -- Restored functionality of make test builds (Regression) (#926) +- Restored functionality of make test builds (Regression) (#926, #929) v1.6.0 diff --git a/README.md b/README.md index a0147ed14..735712329 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Open source version of the STMicroelectronics STlink Tools [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/stlink-org/stlink.svg)](https://github.com/stlink-org/stlink/releases/latest) -[![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.0.svg)](https://github.com/stlink-org/stlink/releases/master) +[![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.0.svg)](https://github.com/stlink-org/stlink/releases/develop) [![Downloads](https://img.shields.io/github/downloads/stlink-org/stlink/total.svg)](https://github.com/stlink-org/stlink/releases) [![Linux Status](https://img.shields.io/travis/stlink-org/stlink/master.svg?label=linux)](https://travis-ci.org/stlink-org/stlink) [![macOS Status](https://img.shields.io/travis/stlink-org/stlink/master.svg?label=osx)](https://travis-ci.org/stlink-org/stlink) From c7874f805c63c60285f2b190f6589da8ae5e47fa Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 20 Apr 2020 01:28:29 +0200 Subject: [PATCH 0851/1435] Fixes to prevent merge conflict --- CMakeLists.txt | 2 +- Makefile | 3 ++- cmake/modules/{Find7zip.cmake => Find_7zip.cmake} | 3 +-- cmake/modules/{Findlibusb.cmake => Find_libusb.cmake} | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) rename cmake/modules/{Find7zip.cmake => Find_7zip.cmake} (91%) rename cmake/modules/{Findlibusb.cmake => Find_libusb.cmake} (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index e8da6c45c..19a3e24c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,7 @@ endif () # Dependencies ### -find_package(libusb REQUIRED) +find_package(_libusb REQUIRED) if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) find_package(PkgConfig) diff --git a/Makefile b/Makefile index a35400617..5272c74d2 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ ## # This Makefile is used to drive building of Debug and Release targets of CMake ## +MAKEFLAGS += -s # additional flags for cmake, e.g. install path -DCMAKE_INSTALL_PREFIX=$(HOME)/.local CMAKEFLAGS += @@ -47,7 +48,7 @@ build/Debug: build/Release: @mkdir -p $@ - @cd $@ && cmake -Wno-dev -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) ../../ + @cd $@ && cmake -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) -Wno-dev ../../ clean: @echo "[CLEAN]" diff --git a/cmake/modules/Find7zip.cmake b/cmake/modules/Find_7zip.cmake similarity index 91% rename from cmake/modules/Find7zip.cmake rename to cmake/modules/Find_7zip.cmake index 0ccd23a50..c75cf1150 100644 --- a/cmake/modules/Find7zip.cmake +++ b/cmake/modules/Find_7zip.cmake @@ -1,7 +1,6 @@ -# Find7zip.cmake +# Find_7zip.cmake # Detect 7zip file archiver on Windows systems to extract (zip-)archives - find_program( ZIP_EXECUTABLE NAMES 7z.exe p7zip HINTS "C:\\Program Files\\7-Zip\\" "C:\\Program Files (x86)\\7-Zip\\" diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Find_libusb.cmake similarity index 99% rename from cmake/modules/Findlibusb.cmake rename to cmake/modules/Find_libusb.cmake index c5366377e..d9dd706c8 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Find_libusb.cmake @@ -1,4 +1,4 @@ -# Findlibusb.cmake +# Find_libusb.cmake # Once done this will define # # LIBUSB_FOUND libusb present on system @@ -73,7 +73,7 @@ elseif (WIN32) # Windows if (NOT LIBUSB_FOUND OR EXISTS "/etc/debian_version") # Preparations for installing libusb library - find_package(7zip REQUIRED) + find_package(_7zip REQUIRED) set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) From 48a9db00be3fe6fa3682fbb538d2db03fb78a899 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 20 Apr 2020 01:45:19 +0200 Subject: [PATCH 0852/1435] Removed remnants of unused build target --- Makefile | 1 - cmake/modules/Find_libusb.cmake | 6 +----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/Makefile b/Makefile index c3bd59c52..354f114fc 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,6 @@ ci: debug release binary test help: @echo " debug: Run a debug build" @echo " release: Run a release build" - @echo " binary: Build Windows-Binary" @echo " lint: Lint check all source-code" @echo " test: Build and run tests" @echo " clean: Clean all build output" diff --git a/cmake/modules/Find_libusb.cmake b/cmake/modules/Find_libusb.cmake index e46c6d46e..d9dd706c8 100644 --- a/cmake/modules/Find_libusb.cmake +++ b/cmake/modules/Find_libusb.cmake @@ -41,9 +41,7 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated message(FATAL_ERROR "Expected libusb library not found on your system! Verify your system integrity.") endif () -elseif (WIN32 OR (EXISTS "/etc/debian_version" AND ${CMAKE_BUILD_TYPE} MATCHES "Binary")) - # Windows & Windows-Binary-Build on Debian/Ubuntu - +elseif (WIN32) # Windows # for MinGW/MSYS/MSVC: 64-bit or 32-bit? if (CMAKE_SIZEOF_VOID_P EQUAL 8) set(ARCH 64) @@ -75,9 +73,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND ${CMAKE_BUILD_TYPE} MATCHES " if (NOT LIBUSB_FOUND OR EXISTS "/etc/debian_version") # Preparations for installing libusb library - find_package(_7zip REQUIRED) - set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) From bc869d75e56d3878e2db3e5941b971c548f0ae22 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 20 Apr 2020 01:46:26 +0200 Subject: [PATCH 0853/1435] Fixes to prevent merge conflict --- Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile b/Makefile index 354f114fc..b6d2a2a31 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,8 @@ ci: debug release binary test help: @echo " debug: Run a debug build" @echo " release: Run a release build" + @echo " install: Install release build" + @echo " package: Package release build" @echo " lint: Lint check all source-code" @echo " test: Build and run tests" @echo " clean: Clean all build output" @@ -26,6 +28,10 @@ release: build/Release @echo "[RELEASE]" @$(MAKE) -C build/Release +install: build/Release + @echo "[INSTALL] Release" + @$(MAKE) -C build/Release install + package: build/Release @echo "[PACKAGE] Release" @$(MAKE) -C build/Release package From 5f983a60958c8476b40260c851eb50bd95b86c83 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Mon, 20 Apr 2020 14:39:00 +0800 Subject: [PATCH 0854/1435] Fix uninitialized cpuid --- src/common.c | 8 ++++++-- tests/usb.c | 10 +++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/common.c b/src/common.c index 6226c893b..0bd914828 100644 --- a/src/common.c +++ b/src/common.c @@ -814,9 +814,13 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { uint32_t raw; - if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &raw)) + if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &raw)) { + cpuid->implementer_id = 0; + cpuid->variant = 0; + cpuid->part = 0; + cpuid->revision = 0; return -1; - + } cpuid->implementer_id = (raw >> 24) & 0x7f; cpuid->variant = (raw >> 20) & 0xf; cpuid->part = (raw >> 4) & 0xfff; diff --git a/tests/usb.c b/tests/usb.c index 06fd73429..4558c8d69 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -30,9 +30,13 @@ int main(int ac, char** av) printf("-- core_id: %#x\n", sl->core_id); cortex_m3_cpuid_t cpuid; - stlink_cpu_id(sl, &cpuid); - printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); - printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); + if (stlink_cpu_id(sl, &cpuid)) { + printf("Failed reading stlink_cpu_id\n"); + } else { + printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); + printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); + } + printf("-- read_sram\n"); static const uint32_t sram_base = STM32_SRAM_BASE; From 629314c44f801f82d478fe49e7b409cdb7364077 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 20 Apr 2020 14:46:36 +0200 Subject: [PATCH 0855/1435] Corrections in cmake build - Name pattern for libusb detection - Include of GNUInstallDirs module - Removed old ci-leftover in Makefile (Fixes #936) --- CMakeLists.txt | 4 +--- Makefile | 2 +- cmake/modules/Find_libusb.cmake | 8 ++++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ccb5fefa9..2a923be5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,9 +8,6 @@ set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -# Define GNU standard installation directories -include(GNUInstallDirs) - ### # General project settings @@ -18,6 +15,7 @@ include(GNUInstallDirs) project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics ST-LINK Tools") +include(GNUInstallDirs) # Define GNU standard installation directories set(STLINK_UDEV_RULES_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/udev/rules.d" CACHE PATH "udev rules directory") set(STLINK_MODPROBED_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/modprobe.d" CACHE PATH "modprobe.d directory") diff --git a/Makefile b/Makefile index 5272c74d2..444f1920b 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ MAKEFLAGS += -s CMAKEFLAGS += all: release -ci: debug release binary test +ci: debug release test help: @echo " debug: Run a debug build" diff --git a/cmake/modules/Find_libusb.cmake b/cmake/modules/Find_libusb.cmake index d9dd706c8..a44e02236 100644 --- a/cmake/modules/Find_libusb.cmake +++ b/cmake/modules/Find_libusb.cmake @@ -19,7 +19,7 @@ if (APPLE) # macOS LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS /usr /usr/local /opt ) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(_libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) if (NOT LIBUSB_FOUND) message(FATAL_ERROR "No libusb library found on your system! Install libusb-1.0 from Homebrew or MacPorts") @@ -35,7 +35,7 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS /usr /usr/local /opt ) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(_libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) if (NOT LIBUSB_FOUND) message(FATAL_ERROR "Expected libusb library not found on your system! Verify your system integrity.") @@ -131,7 +131,7 @@ elseif (WIN32) # Windows endif () message(STATUS "Missing libusb library has been installed") endif () - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(_libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) else () # all other OS (unix-based) @@ -145,7 +145,7 @@ else () # all other OS (unix-based) LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS /usr /usr/local /opt ) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(_libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) if (NOT LIBUSB_FOUND) From e8503fb9b0a54483ab7d5dfc9f4989973711f1ef Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 17 Apr 2020 15:36:47 +0200 Subject: [PATCH 0856/1435] stlink.h: document a bit flash types. f1 xl should probably merged back into f0, with dual bank bit set. --- include/stlink.h | 10 +++++----- src/common.c | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index db737acb0..87d708ef3 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -81,11 +81,11 @@ extern "C" { enum stlink_flash_type { STLINK_FLASH_TYPE_UNKNOWN = 0, - STLINK_FLASH_TYPE_F0, - STLINK_FLASH_TYPE_L0, - STLINK_FLASH_TYPE_F4, - STLINK_FLASH_TYPE_L4, - STLINK_FLASH_TYPE_F1_XL, + STLINK_FLASH_TYPE_F0, /* used by f0, f1 (except f1xl),f3. */ + STLINK_FLASH_TYPE_F1_XL, /* f0 flash with dual bank, apparently */ + STLINK_FLASH_TYPE_F4, /* used by f2, f4, f7 */ + STLINK_FLASH_TYPE_L0, /* l0, l1 */ + STLINK_FLASH_TYPE_L4, /* l4, l4+ */ STLINK_FLASH_TYPE_G0, STLINK_FLASH_TYPE_G4, STLINK_FLASH_TYPE_WB diff --git a/src/common.c b/src/common.c index 9694a8b8e..7ca017eb4 100644 --- a/src/common.c +++ b/src/common.c @@ -3238,6 +3238,7 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) ELOG("Option bytes read is currently not supported for connected chip\n"); return -1; } + switch (sl->chip_id) { case STLINK_CHIPID_STM32_F2: return stlink_read_option_bytes_f2(sl, option_byte); @@ -3289,6 +3290,7 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui return -1; } + /* filter out on chip_id, until complete flash family are handled */ switch (sl->chip_id) { case STLINK_CHIPID_STM32_F2: return stlink_write_option_bytes_f2(sl, base, addr, len); From 498de0cc8cb44c30ca401afdf7d36f9cbda5c5e8 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 17 Apr 2020 11:38:54 +0200 Subject: [PATCH 0857/1435] option write : remove size check, this has already been done earlier --- src/common.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/common.c b/src/common.c index 7ca017eb4..9fda97cdf 100644 --- a/src/common.c +++ b/src/common.c @@ -3028,12 +3028,8 @@ static int stlink_write_option_bytes_f2(stlink_t *sl, uint8_t *base, stm32_addr_ uint32_t val; uint32_t option_byte; - (void) addr; /* todo: add sanitary check */ - - if(len != 4) { - ELOG("Wrong length for writting option bytes, must be 4 is %d\n", len); - return -1; - } + (void) addr; + (void) len; option_byte = *(uint32_t*) (base); @@ -3088,12 +3084,8 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_ uint32_t val; uint32_t option_byte; - (void) addr; /* todo: add sanitary check */ - - if(len != 4) { - ELOG("Wrong length for writing option bytes, must be 4 is %d\n", len); - return -1; - } + (void) addr; + (void) len; option_byte = *(uint32_t*) (base); From 598af1c1aff066a61494b611d41ad62b35f0be92 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 17 Apr 2020 11:41:10 +0200 Subject: [PATCH 0858/1435] use constant for optkey --- src/common.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/common.c b/src/common.c index 9fda97cdf..afeb6106a 100644 --- a/src/common.c +++ b/src/common.c @@ -53,6 +53,9 @@ #define FLASH_KEY1 0x45670123 #define FLASH_KEY2 0xcdef89ab +#define FLASH_OPTKEY1 0x08192A3B +#define FLASH_OPTKEY2 0x4C5D6E7F + #define FLASH_SR_BSY 0 #define FLASH_SR_EOP 5 @@ -2753,8 +2756,8 @@ static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, stm32_addr_ if ((val & (1 << STM32Gx_FLASH_CR_OPTLOCK))) { /* disable option byte write protection. */ - stlink_write_debug32(sl, STM32Gx_FLASH_OPTKEYR, 0x08192A3B); - stlink_write_debug32(sl, STM32Gx_FLASH_OPTKEYR, 0x4C5D6E7F); + stlink_write_debug32(sl, STM32Gx_FLASH_OPTKEYR, FLASH_OPTKEY1); + stlink_write_debug32(sl, STM32Gx_FLASH_OPTKEYR, FLASH_OPTKEY2); /* check that the lock is no longer set. */ stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); @@ -2973,8 +2976,8 @@ static int stlink_write_option_bytes_l496x(stlink_t *sl, uint8_t* base, stm32_ad if ((val & (1 << STM32L4_FLASH_CR_OPTLOCK))) { /* disable option byte write protection. */ - stlink_write_debug32(sl, STM32L4_FLASH_OPTKEYR, 0x08192A3B); - stlink_write_debug32(sl, STM32L4_FLASH_OPTKEYR, 0x4C5D6E7F); + stlink_write_debug32(sl, STM32L4_FLASH_OPTKEYR, FLASH_OPTKEY1); + stlink_write_debug32(sl, STM32L4_FLASH_OPTKEYR, FLASH_OPTKEY2); /* check that the lock is no longer set. */ stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); @@ -3038,8 +3041,8 @@ static int stlink_write_option_bytes_f2(stlink_t *sl, uint8_t *base, stm32_addr_ WLOG("Unlocking option flash\n"); //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) //https://www.st.com/resource/en/programming_manual/cd00233952.pdf - stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, 0x08192A3B); - stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, 0x4C5D6E7F); + stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, FLASH_OPTKEY1); + stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, FLASH_OPTKEY2); stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); if (val & FLASH_F2_OPT_LOCK_BIT) { @@ -3094,8 +3097,8 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_ WLOG("Unlocking option flash\n"); //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) //https://www.st.com/resource/en/programming_manual/cd00233952.pdf - stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, 0x08192A3B); - stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, 0x4C5D6E7F); + stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, FLASH_OPTKEY1); + stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, FLASH_OPTKEY2); stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); if (val & FLASH_F4_OPT_LOCK_BIT) { @@ -3156,8 +3159,8 @@ int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { WLOG("Unlocking option flash\n"); //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) //https://www.st.com/resource/en/programming_manual/cd00233952.pdf - stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, 0x08192A3B); - stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, 0x4C5D6E7F); + stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, FLASH_OPTKEY1); + stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, FLASH_OPTKEY2); stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); if (val & FLASH_F2_OPT_LOCK_BIT) { @@ -3189,8 +3192,8 @@ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { WLOG("Unlocking option flash\n"); //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) //https://www.st.com/resource/en/programming_manual/cd00233952.pdf - stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, 0x08192A3B); - stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, 0x4C5D6E7F); + stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, FLASH_OPTKEY1); + stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, FLASH_OPTKEY2); stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); if (val & FLASH_F4_OPT_LOCK_BIT) { From 7640daae4c0ade48a4179b3a7750272471b8c8e5 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 20 Apr 2020 18:34:12 +0200 Subject: [PATCH 0859/1435] Fixed compilation error on windows Extraction of downloaded libusb archive failed due to wrong command option formatting since commit a8c1f41f1b1c9dd1314f99a1d42de1008f5a4f74. --- cmake/modules/Find_libusb.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/modules/Find_libusb.cmake b/cmake/modules/Find_libusb.cmake index a44e02236..8da0090d8 100644 --- a/cmake/modules/Find_libusb.cmake +++ b/cmake/modules/Find_libusb.cmake @@ -73,7 +73,7 @@ elseif (WIN32) # Windows if (NOT LIBUSB_FOUND OR EXISTS "/etc/debian_version") # Preparations for installing libusb library - find_package(_7zip REQUIRED) + find_package(7zip REQUIRED) set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) @@ -100,8 +100,8 @@ elseif (WIN32) # Windows ) else () execute_process( - COMMAND ${ZIP_EXECUTABLE} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o ${LIBUSB_WIN_OUTPUT_FOLDER} - ) + COMMAND ${ZIP_EXECUTABLE} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER} + ) # <-- Note the absence of a space character following the -o option! endif () # Find path to libusb library From a7568d3cf93c00705b1809186e069fc52210445f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 20 Apr 2020 20:00:12 +0200 Subject: [PATCH 0860/1435] Fixed package name in Find_libusb module Regression from previous commit 7640daae4c0ade48a4179b3a7750272471b8c8e5. --- cmake/modules/Find_libusb.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/Find_libusb.cmake b/cmake/modules/Find_libusb.cmake index 8da0090d8..57e0fa8cf 100644 --- a/cmake/modules/Find_libusb.cmake +++ b/cmake/modules/Find_libusb.cmake @@ -73,7 +73,7 @@ elseif (WIN32) # Windows if (NOT LIBUSB_FOUND OR EXISTS "/etc/debian_version") # Preparations for installing libusb library - find_package(7zip REQUIRED) + find_package(_7zip REQUIRED) set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) From d7e1e6a11e439256abe36a02663d065320cbc4df Mon Sep 17 00:00:00 2001 From: Glaeqen Date: Tue, 21 Apr 2020 00:13:49 +0200 Subject: [PATCH 0861/1435] Added compilation guideline for MSVC toolchain --- doc/compiling.md | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/doc/compiling.md b/doc/compiling.md index 15d8b4fc2..7296af650 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -19,13 +19,27 @@ On Windows users should ensure that the following software is installed: Ensure that you add cmake to the $PATH system variable when following the instructions by the setup assistant. 4. Install - _EITHER_: **MinGW-w64** from (mingw-w64-install.exe)
    - - _OR_: **Visual Studio 2017 CE** (other versions will likely work as well, but are untested; the Community edition is free for open source - development) + - _OR_: **MSVC toolchain** from Visual Studio Build Tools 2019 5. Create a new destination folder at a place of your choice 6. Open the command-line (cmd.exe) and execute `cd C:\$Path-to-your-destination-folder$\` 7. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git`from the command-line (cmd.exe)
    or download the stlink zip-sourcefolder from the Release page on GitHub +#### MSVC toolchain - minimal installation + +Visual Studio IDE is not necessary, only Windows SDK & build tools are required (~3,3GB). + +1. Open +2. Navigate through menus as follows (might change overtime) + + `All downloads > Tools for Visual Studio 2019 > Build Tools for Visual Studio 2019 > Download` +3. Start downloaded executable. After Visual Studio Installer bootstraps and main window pops up, open `Individual Components` tab, and pick + - latest build tools (eg. `MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.25)`) + - latest Windows SDK (eg. `Windows 10 SDK (10.0.18362.0)`) +4. After installation finishes, you can press `Launch` button in Visual Studio Installer's main menu. + - Thus you can open `Developer Command Prompt for VS 2019`. It is `cmd.exe` instance with adjusted PATHs including eg. `msbuild`. + - Alternatively, you can use `Developer Powershell for VS 2019` which is the same thing for `powershell.exe`. Both are available from Start menu. + - Another option is to add `msbuild` to PATH manually. Its location should be `C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin`. Then, it should be available from any `powershell.exe` or `cmd.exe` session. ### Building #### MinGW-w64 @@ -39,19 +53,32 @@ When installing different toolchains make sure to update the path in the `mingw6 This can be achieved by opening the .bat file with a common text editor. -#### Visual Studio (32 bit) +#### MSVC toolchain 1. In a command prompt, change the directory to the folder where the stlink files were cloned (or unzipped) to. 2. Make sure the build folder exists (`mkdir build` if not). 3. From the build folder, run cmake (`cd build; cmake ..`). -This will create a solution (stlink.sln) in the build folder. Open it in Visual Studio, select the Solution Configuration (Debug or -Release) and build the solution normally (F7). +This will create a solution file `stlink.sln` in the build folder. +Now, you can build whole `stlink` suite using following command: +``` +msbuild /m /p:Configuration=Release stlink.sln +``` +Options: +- `/m` - compilation runs in parallel utilizing multiple cores +- `/p:Configuration=Release` - generates *Release*, optimized build. + +Directory `\build\Release` contains final executables. +(`st-util.exe` is located in `\build\src\gdbserver\Release`). -NOTE:
    -This solution will link to the dll version of libusb-1.0.y
    -To debug or run the executable, the dll version of libusb-1.0 must be either on the path, or in the same folder as the executable.
    -It can be copied from here: `build\3rdparty\libusb-1.0.21\MS32\dll\libusb-1.0.dll`. +**NOTE 1:** + +Executables link against libusb.dll library. It has to be placed in the same directory as binaries or in PATH. +It can be copied from: `\build\3rdparty\libusb-{version}\MS{arch}\dll\libusb-1.0.dll`. + +**NOTE 2:** + +[ST-LINK drivers](https://www.st.com/en/development-tools/stsw-link009.html) are required for `stlink` to work. ## Linux ### Common requirements From abaa8f5782df7b8cfe4e3171b168d373bd680fa8 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Tue, 21 Apr 2020 09:50:50 +0800 Subject: [PATCH 0862/1435] Add cleanroom document --rebased --- flashloaders/cleanroom.md | 232 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 flashloaders/cleanroom.md diff --git a/flashloaders/cleanroom.md b/flashloaders/cleanroom.md new file mode 100644 index 000000000..594e7191a --- /dev/null +++ b/flashloaders/cleanroom.md @@ -0,0 +1,232 @@ +English version can be found below. + +# 净室工程文档 + +代码位于的section:`.text` +编译制导添加`.syntax unified` + +传入参数约定: + +参数全部通过寄存器传递 + +`r0`: 拷贝源点起始地址 +`r1`: 拷贝终点起始地址 +`r2`: 拷贝word(4字节)数(存在例外) + +程序功能:将数据从源点拷贝到终点,在拷贝完毕后触发断点以结束执行,结束时`r2`值需清零表明传输完毕。 + +限制:不可使用栈,可自由使用的临时寄存器为`R3`到`R12`。`R13`为`sp`(stack pointer),`R14`为lr(一般用于储存跳转地址),`R15`为`pc`(program counter)。 + +要求:每完成一次拷贝,需等待flash完成写入,单次拷贝宽度、检查写入完成的方式见每个文件的具体要求。 + +特殊地址`flash_base`存放地址需2字节对齐。 + +## stm32f0.s + +例外:`r2`:拷贝half word(2字节)数 + +特殊地址定义:`flash_base`:定义为0x40022000 + +`FLASH_CR`: 相对`flash_base`的offset为16 + +`FLASH_SR`: 相对`flash_base`的offset为12 + +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h) +[https://www.st.com/resource/en/reference_manual/dm00031936-stm32f0x1stm32f0x2stm32f0x8-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00031936-stm32f0x1stm32f0x2stm32f0x8-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) + +特殊要求: +每次拷贝开始前需要读出FLASH_CR处的4字节内容,将其最低bit设置为1,写回FLASH_CR。 + +每次写入数据宽度为2字节(半字)。 + +每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_SR处4字节内容,若取值为1,则说明写入尚未完成,需继续轮询等待;否则需要检查FLASH_SR处值是否为4,若是4,则应直接准备退出。 + +退出:全部拷贝执行完毕后触发断点前,将FLASH_CR处4字节内容最低bit清为0,写回FLASH_CR。 + + + +## stm32f4.s + +特殊地址定义: `flash_base`:定义为0x40023c00 + +`FLASH_SR`:相对flash_base的offset为0xe(14) + +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) +[https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf](https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf) + +特殊要求: + +每次写入的数据宽度为4字节(字)。 + +每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_SR处2字节内容,若取值为1,则说明写入尚未完成,需继续轮询等待。 + +## stm32f4lv.s + +特殊地址定义:`flash_base`:定义为0x40023c00 + +`FLASH_SR`:相对`flash_base`的offset为0xe (14) + +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) +[https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf](https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf) + +特殊要求: + +每次写入的数据宽度为1字节(1/4字)。 + +每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_SR处2字节内容,若取值为1,则说明写入尚未完成,需继续轮询等待。 + +## stm32f7.s + +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) +[https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) + +要求同stm32f4.s,额外要求在每次拷贝执行完毕、flash写入成功检测前,执行`dsb sy`指令以建立内存屏障。 + + +## stm32f7lv.s + +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) +[https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) +要求基本同stm32f7.s,差异要求为每次写入的数据宽度为1字节(1/4字)。 + +## stm32l0x.s + +特殊要求: + +每次写入的数据宽度为4字节(字) + +无需实现检查flash写入完成功能 + +## stm32l4.s + +例外:`r2`: 拷贝双字(8字节)数 + +特殊地址定义:`flash_base`: 0x40022000 + +`FLASH_BSY`:相对flash_base的offset为0x12 + +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h) +[https://www.st.com/resource/en/reference_manual/dm00310109-stm32l4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00310109-stm32l4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) + +拷贝方式:一次性拷贝连续的8个字节(使用两个连续寄存器作中转)并写入 + +每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_BSY处半字(2字节),若其最低位非1,可继续拷贝。 + +## stm32lx.s + +要求与stm32l0x.s相同 + +# Clean Room Documentation English Version + +Code is situated in section `.text` + +Shall add a compile directive at the head: `.syntax unified` + +**Calling convention**: + +All parameters would be passed over registers + +`r0`: the base address of the copy source +`r1`: the base address of the copy destination +`r2`: the total word (4 bytes) count to be copied (with expeptions) + +**What the program is expected to do**: + +Copy data from source to destination, after which trigger a breakpint to exit. Before exit, `r2` must be cleared to zero to indicate that the copy is done. + +**Limitation**: No stack operations are permitted. Registers ranging from `r3` to `r12` are free to use. Note that `r13` is `sp`(stack pointer), `r14` is `lr`(commonly used to store jump address), `r15` is `pc`(program counter). + +**Requirement**: After every single copy, wait until the flash finishes. The detailed single copy length and the way to check can be found below. Address of `flash_base` shall be two-bytes aligned. + +## stm32f0.s + +**Exception**: `r2` stores the total half word (2 bytes) count to be copied + +`flash_base`: 0x40022000 + +`FLASH_CR`: offset from `flash_base` is 16 + +`FLASH_SR`: offset from `flash_base` is 12 + +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h) +[https://www.st.com/resource/en/reference_manual/dm00031936-stm32f0x1stm32f0x2stm32f0x8-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00031936-stm32f0x1stm32f0x2stm32f0x8-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) + +**Special requirements**: + +Before every copy, read a word from FLASH_CR, set the lowest bit to 1 and write back. Copy one half word each time. + +How to wait for the write process: read a word from FLASH_SR, loop until the content is not 1. After that, check FLASH_SR, proceed if the content is not 4, otherwise exit. + +Exit: after the copying process and before triggering the breakpoint, clear the lowest bit in FLASH_CR. + +## stm32f4.s + +`flash_base`: 0x40023c00 + +`FLASH_SR`: offset from `flash_base` is 0xe (14) + +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) +[https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf](https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf) + + +**Special requirements**: + +Copy one word each time. +How to wait for the write process: read a half word from FLASH_SR, loop until the content is not 1. + +## stm32f4lv.s + +`flash_base`: 0x40023c00 + +`FLASH_SR`: offset from `flash_base` is 0xe (14) + +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) +[https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf](https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf) + +**Special Requirements**: + +Copy one byte each time. + +How to wait from the write process: read a half word from FLASH_SR, loop until the content is not 1. + +## stm32f7.s + +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) +[https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) + +Mostly same with `stm32f4.s`. Require establishing a memory barrier after every copy and before checking for finished writing by `dsb sy` + +## stm32f7lv.s + +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) +[https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) + +**Special Requirements**: + +Mostly same with `stm32f7.s`. Copy one byte each time. + +## stm32l0x.s + +**Special Requirements**: + +Copy one word each time. No wait for write. + +## stm32l4.s + +**Exception**: r2 stores the double word count to be copied. + +`flash_base`: 0x40022000 +`FLASH_BSY`: offset from `flash_base` is 0x12 + +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h) +[https://www.st.com/resource/en/reference_manual/dm00310109-stm32l4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00310109-stm32l4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) + +**Special Requirements**: + +Copy one double word each time (More than one registers are allowed). + +How to wait for the write process: read a half word from `FLASH_BSY`, loop until the lowest bit turns non-1. + +## stm32lx.s + +Same with stm32l0x.s. \ No newline at end of file From 9b19f9225460472af9d98959b7217d0a840ee972 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 21 Apr 2020 14:49:25 +0200 Subject: [PATCH 0863/1435] Fixed compilation errors - Moved include of GNUInstallDirs module in cmake-routine - Removed old ci-leftover in Makefile - cmake: Fixed name pattern for libusb module (Fixes #940) - Wrong command option formatting for 7zip (Fixes #936) Extraction of downloaded libusb archive on Windows failed since commit a8c1f41f1b1c9dd1314f99a1d42de1008f5a4f74. --- CMakeLists.txt | 6 ++---- Makefile | 2 +- .../modules/{Find_7zip.cmake => Find7zip.cmake} | 2 +- .../{Find_libusb.cmake => Findlibusb.cmake} | 16 ++++++++-------- 4 files changed, 12 insertions(+), 14 deletions(-) rename cmake/modules/{Find_7zip.cmake => Find7zip.cmake} (91%) rename cmake/modules/{Find_libusb.cmake => Findlibusb.cmake} (92%) diff --git a/CMakeLists.txt b/CMakeLists.txt index ccb5fefa9..fd79ac10e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,9 +8,6 @@ set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -# Define GNU standard installation directories -include(GNUInstallDirs) - ### # General project settings @@ -18,6 +15,7 @@ include(GNUInstallDirs) project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics ST-LINK Tools") +include(GNUInstallDirs) # Define GNU standard installation directories set(STLINK_UDEV_RULES_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/udev/rules.d" CACHE PATH "udev rules directory") set(STLINK_MODPROBED_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/modprobe.d" CACHE PATH "modprobe.d directory") @@ -67,7 +65,7 @@ endif () # Dependencies ### -find_package(_libusb REQUIRED) +find_package(libusb REQUIRED) if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) find_package(PkgConfig) diff --git a/Makefile b/Makefile index 5272c74d2..444f1920b 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ MAKEFLAGS += -s CMAKEFLAGS += all: release -ci: debug release binary test +ci: debug release test help: @echo " debug: Run a debug build" diff --git a/cmake/modules/Find_7zip.cmake b/cmake/modules/Find7zip.cmake similarity index 91% rename from cmake/modules/Find_7zip.cmake rename to cmake/modules/Find7zip.cmake index c75cf1150..83eb912d4 100644 --- a/cmake/modules/Find_7zip.cmake +++ b/cmake/modules/Find7zip.cmake @@ -1,4 +1,4 @@ -# Find_7zip.cmake +# Find7zip.cmake # Detect 7zip file archiver on Windows systems to extract (zip-)archives find_program( diff --git a/cmake/modules/Find_libusb.cmake b/cmake/modules/Findlibusb.cmake similarity index 92% rename from cmake/modules/Find_libusb.cmake rename to cmake/modules/Findlibusb.cmake index d9dd706c8..13f70d7b7 100644 --- a/cmake/modules/Find_libusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -1,4 +1,4 @@ -# Find_libusb.cmake +# Findlibusb.cmake # Once done this will define # # LIBUSB_FOUND libusb present on system @@ -19,7 +19,7 @@ if (APPLE) # macOS LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS /usr /usr/local /opt ) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) if (NOT LIBUSB_FOUND) message(FATAL_ERROR "No libusb library found on your system! Install libusb-1.0 from Homebrew or MacPorts") @@ -35,7 +35,7 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS /usr /usr/local /opt ) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) if (NOT LIBUSB_FOUND) message(FATAL_ERROR "Expected libusb library not found on your system! Verify your system integrity.") @@ -73,7 +73,7 @@ elseif (WIN32) # Windows if (NOT LIBUSB_FOUND OR EXISTS "/etc/debian_version") # Preparations for installing libusb library - find_package(_7zip REQUIRED) + find_package(7zip REQUIRED) set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) @@ -100,8 +100,8 @@ elseif (WIN32) # Windows ) else () execute_process( - COMMAND ${ZIP_EXECUTABLE} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o ${LIBUSB_WIN_OUTPUT_FOLDER} - ) + COMMAND ${ZIP_EXECUTABLE} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER} + ) # <-- Note the absence of a space character following the -o option! endif () # Find path to libusb library @@ -131,7 +131,7 @@ elseif (WIN32) # Windows endif () message(STATUS "Missing libusb library has been installed") endif () - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) else () # all other OS (unix-based) @@ -145,7 +145,7 @@ else () # all other OS (unix-based) LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS /usr /usr/local /opt ) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) if (NOT LIBUSB_FOUND) From 9373f133935e967182518bbdfa9501d7ebbcc2d8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 21 Apr 2020 15:47:56 +0200 Subject: [PATCH 0864/1435] Updated CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5cf843c9..9ad6b6497 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ Features: - STM32G0/G4 improvements (#910) - Enable mass erase with a flash programming check - Handle G4 Cat3 devices with configurable dual bank flash by using a helper +- Display programmer serial when no target is connected (#432, #933, #943) Updates & changes: @@ -42,6 +43,7 @@ Updates & changes: - Enhanced error log with file path for map_file() (#650, #879, #921) - Refactoring: Overall option code rework (#927) - Refactoring: Build settings / GUI-Build on UNIX-based systems if GTK3 is detected (#929) +- Reconfiguration of package build process (#931, #936, #940, commit 9b19f9225460472af9d98959b7217d0a840ee972) Fixes: @@ -61,6 +63,7 @@ Fixes: - st-flash: minor usage fix and make cmdline parsing more user friendly (#925) - Better argument parsing for CLI tools: stlink_open_usb can address v1, v2, v3 (#378, #922) - Restored functionality of make test builds (Regression) (#926, #929) +- Fixed compilation error due to uninitialized cpuid (#937, #938) v1.6.0 From 09ea99aea51f741ce9c8c0e2ad755d40b3d86021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20M=C3=A1rton?= Date: Mon, 24 Feb 2020 21:34:36 +0100 Subject: [PATCH 0865/1435] Add support for STLink V3 Flash programming is broken --- include/stlink.h | 68 ++++++- include/stlink/commands.h | 48 +++-- include/stlink/tools/flash.h | 2 +- include/stlink/usb.h | 14 +- src/common.c | 100 ++++++---- src/flash_loader.c | 4 +- src/gdbserver/gdb-server.c | 2 +- src/logging.c | 2 +- src/sg.c | 20 +- src/tools/flash.c | 10 +- src/usb.c | 368 ++++++++++++++++++++++++++++------- 11 files changed, 479 insertions(+), 159 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index d4170c7a7..f9de94fd4 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -24,10 +24,17 @@ extern "C" { //#define Q_BUF_LEN 96 #define Q_BUF_LEN (1024 * 100) - // STLINK_DEBUG_RESETSYS, etc: +// STLINK_DEBUG_RESETSYS, etc: +enum target_state { + TARGET_UNKNOWN = 0, + TARGET_RUNNING = 1, + TARGET_HALTED = 2, + TARGET_RESET = 3, + TARGET_DEBUG_RUNNING = 4, +}; + #define STLINK_CORE_RUNNING 0x80 #define STLINK_CORE_HALTED 0x81 -#define STLINK_CORE_STAT_UNKNOWN -1 #define STLINK_GET_VERSION 0xf1 #define STLINK_GET_CURRENT_MODE 0xf5 @@ -52,6 +59,11 @@ extern "C" { #define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43 +#define STLINK_APIV3_SET_COM_FREQ 0x61 +#define STLINK_APIV3_GET_COM_FREQ 0x62 + +#define STLINK_APIV3_GET_VERSION_EX 0xFB + // Baud rate divisors for SWDCLK #define STLINK_SWDCLK_4MHZ_DIVISOR 0 #define STLINK_SWDCLK_1P8MHZ_DIVISOR 1 @@ -68,7 +80,45 @@ extern "C" { #define STLINK_SERIAL_MAX_SIZE 64 - /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ +#define STLINK_V3_MAX_FREQ_NB 10 + +/* Cortex Debug Control Block */ +#define DCB_DHCSR 0xE000EDF0 +#define DCB_DCRSR 0xE000EDF4 +#define DCB_DCRDR 0xE000EDF8 +#define DCB_DEMCR 0xE000EDFC + +/* DCB_DHCSR bit and field definitions */ +#define DBGKEY (0xA05F << 16) +#define C_DEBUGEN (1 << 0) +#define C_HALT (1 << 1) +#define C_STEP (1 << 2) +#define C_MASKINTS (1 << 3) +#define S_REGRDY (1 << 16) +#define S_HALT (1 << 17) +#define S_SLEEP (1 << 18) +#define S_LOCKUP (1 << 19) +#define S_RETIRE_ST (1 << 24) +#define S_RESET_ST (1 << 25) + + +/* + * Map the relevant features, quirks and workaround for specific firmware + * version of stlink + */ +#define STLINK_F_HAS_TRACE (1<<0) +#define STLINK_F_HAS_SWD_SET_FREQ (1<<1) +#define STLINK_F_HAS_JTAG_SET_FREQ (1<<2) +#define STLINK_F_HAS_MEM_16BIT (1<<3) +#define STLINK_F_HAS_GETLASTRWSTATUS2 (1<<4) +#define STLINK_F_HAS_DAP_REG (1<<5) +#define STLINK_F_QUIRK_JTAG_DP_READ (1<<6) +#define STLINK_F_HAS_AP_INIT (1<<7) +#define STLINK_F_HAS_DPBANKSEL (1<<8) +#define STLINK_F_HAS_RW8_512BYTES (1<<9) + + +/* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ #define C_BUF_LEN 32 enum stlink_flash_type { @@ -111,12 +161,22 @@ typedef struct flash_loader { uint8_t revision; } cortex_m3_cpuid_t; + enum stlink_jtag_api_version { + STLINK_JTAG_API_V1 = 1, + STLINK_JTAG_API_V2, + STLINK_JTAG_API_V3, + }; + typedef struct stlink_version_ { uint32_t stlink_v; uint32_t jtag_v; uint32_t swim_v; uint32_t st_vid; uint32_t stlink_pid; + /** jtag api version supported */ + enum stlink_jtag_api_version jtag_api; + /** one bit for each feature supported. See macros STLINK_F_* */ + uint32_t flags; } stlink_version_t; enum transport_type { @@ -144,7 +204,7 @@ typedef struct flash_loader { int verbose; uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram - int core_stat; // set by stlink_status(), values STLINK_CORE_xxxxx + enum target_state core_stat; // set by stlink_status() char serial[STLINK_SERIAL_MAX_SIZE]; int serial_size; diff --git a/include/stlink/commands.h b/include/stlink/commands.h index 9ff5a8fb9..a6830ff26 100644 --- a/include/stlink/commands.h +++ b/include/stlink/commands.h @@ -2,25 +2,35 @@ #define STLINK_COMMANDS_H_ enum stlink_debug_commands { - STLINK_DEBUG_ENTER_JTAG = 0x00, - STLINK_DEBUG_GETSTATUS = 0x01, - STLINK_DEBUG_FORCEDEBUG = 0x02, - STLINK_DEBUG_RESETSYS = 0x03, - STLINK_DEBUG_READALLREGS = 0x04, - STLINK_DEBUG_READREG = 0x05, - STLINK_DEBUG_WRITEREG = 0x06, - STLINK_DEBUG_READMEM_32BIT = 0x07, - STLINK_DEBUG_WRITEMEM_32BIT = 0x08, - STLINK_DEBUG_RUNCORE = 0x09, - STLINK_DEBUG_STEPCORE = 0x0a, - STLINK_DEBUG_SETFP = 0x0b, - STLINK_DEBUG_WRITEMEM_8BIT = 0x0d, - STLINK_DEBUG_CLEARFP = 0x0e, - STLINK_DEBUG_WRITEDEBUGREG = 0x0f, - STLINK_DEBUG_ENTER = 0x20, - STLINK_DEBUG_EXIT = 0x21, - STLINK_DEBUG_READCOREID = 0x22, - STLINK_DEBUG_ENTER_SWD = 0xa3 + STLINK_DEBUG_ENTER_JTAG = 0x00, + STLINK_DEBUG_GETSTATUS = 0x01, + STLINK_DEBUG_FORCEDEBUG = 0x02, + STLINK_DEBUG_APIV1_RESETSYS = 0x03, + STLINK_DEBUG_APIV1_READALLREGS = 0x04, + STLINK_DEBUG_APIV1_READREG = 0x05, + STLINK_DEBUG_APIV1_WRITEREG = 0x06, + STLINK_DEBUG_READMEM_32BIT = 0x07, + STLINK_DEBUG_WRITEMEM_32BIT = 0x08, + STLINK_DEBUG_RUNCORE = 0x09, + STLINK_DEBUG_STEPCORE = 0x0a, + STLINK_DEBUG_APIV1_SETFP = 0x0b, + STLINK_DEBUG_WRITEMEM_8BIT = 0x0d, + STLINK_DEBUG_APIV1_CLEARFP = 0x0e, + STLINK_DEBUG_APIV1_WRITEDEBUGREG = 0x0f, + STLINK_DEBUG_APIV1_ENTER = 0x20, + STLINK_DEBUG_EXIT = 0x21, + STLINK_DEBUG_READCOREID = 0x22, + STLINK_DEBUG_APIV2_ENTER = 0x30, + STLINK_DEBUG_APIV2_READ_IDCODES = 0x31, + STLINK_DEBUG_APIV2_RESETSYS = 0x32, + STLINK_DEBUG_APIV2_READREG = 0x33, + STLINK_DEBUG_APIV2_WRITEREG = 0x34, + STLINK_DEBUG_APIV2_WRITEDEBUGREG = 0x35, + STLINK_DEBUG_APIV2_READDEBUGREG = 0x36, + STLINK_DEBUG_APIV2_READALLREGS = 0x3A, + STLINK_DEBUG_APIV2_GETLASTRWSTATUS = 0x3B, + STLINK_DEBUG_APIV2_GETLASTRWSTATUS2 = 0x3E, + STLINK_DEBUG_ENTER_SWD = 0xa3 }; #endif /* STLINK_COMMANDS_H_ */ diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index 8ca1eddf9..6851ede8b 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -5,7 +5,7 @@ #include #define DEBUG_LOG_LEVEL 100 -#define STND_LOG_LEVEL 50 +#define STND_LOG_LEVEL 100 enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3, CMD_RESET = 4}; enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1}; diff --git a/include/stlink/usb.h b/include/stlink/usb.h index 621695ea4..a69101c1f 100644 --- a/include/stlink/usb.h +++ b/include/stlink/usb.h @@ -18,11 +18,15 @@ extern "C" { #endif -#define STLINK_USB_VID_ST 0x0483 -#define STLINK_USB_PID_STLINK 0x3744 -#define STLINK_USB_PID_STLINK_32L 0x3748 -#define STLINK_USB_PID_STLINK_32L_AUDIO 0x374a -#define STLINK_USB_PID_STLINK_NUCLEO 0x374b +#define STLINK_USB_VID_ST 0x0483 +#define STLINK_USB_PID_STLINK 0x3744 +#define STLINK_USB_PID_STLINK_32L 0x3748 +#define STLINK_USB_PID_STLINK_32L_AUDIO 0x374a +#define STLINK_USB_PID_STLINK_NUCLEO 0x374b +#define STLINK_USB_PID_STLINK_V3_USBLOADER 0x374d +#define STLINK_USB_PID_STLINK_V3E_PID 0x374e +#define STLINK_USB_PID_STLINK_V3S_PID 0x374f +#define STLINK_USB_PID_STLINK_V3_2VCP_PID 0x3753 #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 diff --git a/src/common.c b/src/common.c index 9a3098114..db0ab445e 100644 --- a/src/common.c +++ b/src/common.c @@ -892,23 +892,48 @@ int stlink_status(stlink_t *sl) { * @param sl stlink context, assumed to contain valid data in the buffer * @param slv output parsed version object */ -void _parse_version(stlink_t *sl, stlink_version_t *slv) { - uint32_t b0 = sl->q_buf[0]; //lsb - uint32_t b1 = sl->q_buf[1]; - uint32_t b2 = sl->q_buf[2]; - uint32_t b3 = sl->q_buf[3]; - uint32_t b4 = sl->q_buf[4]; - uint32_t b5 = sl->q_buf[5]; //msb - - // b0 b1 || b2 b3 | b4 b5 - // 4b | 6b | 6b || 2B | 2B - // stlink_v | jtag_v | swim_v || st_vid | stlink_pid - - slv->stlink_v = (b0 & 0xf0) >> 4; - slv->jtag_v = ((b0 & 0x0f) << 2) | ((b1 & 0xc0) >> 6); - slv->swim_v = b1 & 0x3f; - slv->st_vid = (b3 << 8) | b2; - slv->stlink_pid = (b5 << 8) | b4; +void _parse_version(stlink_t *sl, stlink_version_t *slv) +{ + sl->version.flags = 0; + if (sl->version.stlink_v < 3) { + uint32_t b0 = sl->q_buf[0]; //lsb + uint32_t b1 = sl->q_buf[1]; + uint32_t b2 = sl->q_buf[2]; + uint32_t b3 = sl->q_buf[3]; + uint32_t b4 = sl->q_buf[4]; + uint32_t b5 = sl->q_buf[5]; //msb + + // b0 b1 || b2 b3 | b4 b5 + // 4b | 6b | 6b || 2B | 2B + // stlink_v | jtag_v | swim_v || st_vid | stlink_pid + + slv->stlink_v = (b0 & 0xf0) >> 4; + slv->jtag_v = ((b0 & 0x0f) << 2) | ((b1 & 0xc0) >> 6); + slv->swim_v = b1 & 0x3f; + slv->st_vid = (b3 << 8) | b2; + slv->stlink_pid = (b5 << 8) | b4; + /* ST-LINK/V1 from J11 switch to api-v2 (and support SWD) */ + if (slv->stlink_v == 1) + slv->jtag_api = slv->jtag_v > 11? STLINK_JTAG_API_V2 : STLINK_JTAG_API_V1; + else { + slv->jtag_api = STLINK_JTAG_API_V2; + /* preferred API to get last R/W status from J15 */ + if (sl->version.jtag_v >= 15) + sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; + } + } else { + // V3 uses different version format, for reference see OpenOCD source + // (that was written from docs available from ST under NDA): + // https://github.com/ntfreak/openocd/blob/a6dacdff58ef36fcdac00c53ec27f19de1fbce0d/src/jtag/drivers/stlink_usb.c#L965 + slv->stlink_v = sl->q_buf[0]; + slv->swim_v = sl->q_buf[1]; + slv->jtag_v = sl->q_buf[2]; + slv->st_vid = (uint32_t)((sl->q_buf[9] << 8) | sl->q_buf[8]); + slv->stlink_pid = (uint32_t)((sl->q_buf[11] << 8) | sl->q_buf[10]); + slv->jtag_api = STLINK_JTAG_API_V3; + /* preferred API to get last R/W status */ + sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; + } return; } @@ -1065,13 +1090,8 @@ int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, struct s bool stlink_is_core_halted(stlink_t *sl) { - bool ret = false; - - stlink_status(sl); - if (sl->q_buf[0] == STLINK_CORE_HALTED) - ret = true; - - return ret; + stlink_status(sl); + return sl->core_stat == TARGET_HALTED; } int stlink_step(stlink_t *sl) { @@ -1140,21 +1160,21 @@ void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { // this function is called by stlink_status() // do not call stlink_core_stat() directly, always use stlink_status() void stlink_core_stat(stlink_t *sl) { - if (sl->q_len <= 0) - return; - - switch (sl->q_buf[0]) { - case STLINK_CORE_RUNNING: - sl->core_stat = STLINK_CORE_RUNNING; + switch (sl->core_stat ) { + case TARGET_RUNNING: DLOG(" core status: running\n"); return; - case STLINK_CORE_HALTED: - sl->core_stat = STLINK_CORE_HALTED; + case TARGET_HALTED: DLOG(" core status: halted\n"); return; + case TARGET_RESET: + DLOG(" core status: reset\n"); + return; + case TARGET_DEBUG_RUNNING: + DLOG(" core status: debug running\n"); + return; default: - sl->core_stat = STLINK_CORE_STAT_UNKNOWN; - fprintf(stderr, " core status: unknown\n"); + DLOG(" core status: unknown\n"); } } @@ -1162,7 +1182,7 @@ void stlink_print_data(stlink_t * sl) { if (sl->q_len <= 0 || sl->verbose < UDEBUG) return; if (sl->verbose > 2) - fprintf(stdout, "data_len = %d 0x%x\n", sl->q_len, sl->q_len); + DLOG("data_len = %d 0x%x\n", sl->q_len, sl->q_len); for (int i = 0; i < sl->q_len; i++) { if (i % 16 == 0) { @@ -1173,9 +1193,9 @@ void stlink_print_data(stlink_t * sl) { fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); */ } - fprintf(stdout, " %02x", (unsigned int) sl->q_buf[i]); + DLOG(" %02x", (unsigned int) sl->q_buf[i]); } - fputs("\n\n", stdout); + DLOG("\n\n"); } /* memory mapped file */ @@ -2059,17 +2079,15 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t /* erase each page */ int page_count = 0; for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + (uint32_t) off)) { - /* addr must be an addr inside the page */ + // addr must be an addr inside the page if (stlink_erase_flash_page(sl, addr + (uint32_t) off) == -1) { ELOG("Failed to erase_flash_page(%#zx) == -1\n", addr + off); return -1; } - fprintf(stdout,"\rFlash page at addr: 0x%08lx erased", + ILOG("Flash page at addr: 0x%08lx erased\n", (unsigned long)(addr + off)); - fflush(stdout); page_count++; } - fprintf(stdout,"\n"); ILOG("Finished erasing %d pages of %d (%#x) bytes\n", page_count, sl->flash_pgsz, sl->flash_pgsz); diff --git a/src/flash_loader.c b/src/flash_loader.c index 73db427a7..eaf81019e 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -321,7 +321,9 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* } memcpy(sl->q_buf, loader_code, loader_size); - stlink_write_mem32(sl, sl->sram_base, loader_size); + int ret = stlink_write_mem32(sl, sl->sram_base, loader_size); + if (ret) + return ret; *addr = sl->sram_base; *size = loader_size; diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index bdfeb703d..2dfbc7454 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -1384,7 +1384,7 @@ int serve(stlink_t *sl, st_state_t *st) { } stlink_status(sl); - if(sl->core_stat == STLINK_CORE_HALTED) { + if(sl->core_stat == TARGET_HALTED) { struct stlink_reg reg; int ret; stm32_addr_t pc; diff --git a/src/logging.c b/src/logging.c index d4fb96b2e..d2ca11f2a 100644 --- a/src/logging.c +++ b/src/logging.c @@ -11,7 +11,7 @@ #include "stlink/logging.h" -static int max_level = UINFO; +static int max_level = UDEBUG; int ugly_init(int maximum_threshold) { max_level = maximum_threshold; diff --git a/src/sg.c b/src/sg.c index e7ff5d14e..4e8349bc2 100644 --- a/src/sg.c +++ b/src/sg.c @@ -435,7 +435,7 @@ int _stlink_sg_current_mode(stlink_t *stl) { int _stlink_sg_enter_swd_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_SWD; sl->q_len = 0; // >0 -> aboard return stlink_q(sl); @@ -448,7 +448,7 @@ int _stlink_sg_enter_jtag_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_enter_jtag_mode ***\n"); clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_JTAG; sl->q_len = 0; return stlink_q(sl); @@ -529,7 +529,7 @@ int _stlink_sg_core_id(stlink_t *sl) { int _stlink_sg_reset(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_RESETSYS; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_RESETSYS; sl->q_len = 2; sg->q_addr = 0; if (stlink_q(sl)) @@ -593,7 +593,7 @@ int _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_READALLREGS; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_READALLREGS; sl->q_len = 84; sg->q_addr = 0; if (stlink_q(sl)) @@ -634,7 +634,7 @@ int _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { int _stlink_sg_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_READREG; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_READREG; sg->cdb_cmd_blk[2] = r_idx; sl->q_len = 4; sg->q_addr = 0; @@ -679,7 +679,7 @@ int _stlink_sg_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { int _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEREG; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_WRITEREG; // 2: reg index // 3-6: reg content sg->cdb_cmd_blk[2] = idx; @@ -701,7 +701,7 @@ void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_write_dreg ***\n"); clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEDEBUGREG; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_WRITEDEBUGREG; // 2-5: address of reg of the debug module // 6-9: reg content write_uint32(sg->cdb_cmd_blk + 2, addr); @@ -750,7 +750,7 @@ void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) { DLOG("\n*** stlink_set_hw_bp ***\n"); struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_SETFP; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_SETFP; // 2:The number of the flash patch used to set the breakpoint // 3-6: Address of the breakpoint (LSB) // 7: FP_ALL (0x02) / FP_UPPER (0x01) / FP_LOWER (0x00) @@ -770,7 +770,7 @@ void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_clr_hw_bp ***\n"); clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_DEBUG_CLEARFP; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_CLEARFP; sg->cdb_cmd_blk[2] = fp_nr; sl->q_len = 2; @@ -1045,7 +1045,7 @@ static stlink_t* stlink_open(const int verbose) { sl->backend_data = slsg; sl->backend = &_stlink_sg_backend; - sl->core_stat = STLINK_CORE_STAT_UNKNOWN; + sl->core_stat = TARGET_UNKNOWN; slsg->q_addr = 0; return sl; diff --git a/src/tools/flash.c b/src/tools/flash.c index f5fd1a386..a8d937930 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -29,11 +29,11 @@ static void cleanup(int signum) { static void usage(void) { - puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--format ] [--flash=] {read|write} /dev/sgX "); - puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); - puts("stlinkv2 command line: ./st-flash [--debug] [--reset] [--serial ] [--format ] [--flash=] {read|write} "); - puts("stlinkv2 command line: ./st-flash [--debug] [--serial ] erase"); - puts("stlinkv2 command line: ./st-flash [--debug] [--serial ] reset"); + puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--format ] [--flash=] {read|write} /dev/sgX "); + puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase"); + puts("stlinkv2/3 command line: ./st-flash [--debug] [--reset] [--serial ] [--format ] [--flash=] {read|write} "); + puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] erase"); + puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial ] reset"); puts(" Use hex format for addr, and ."); puts(" fsize: Use decimal, octal or hex by prefix 0xXXX for hex, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); puts(" Format may be 'binary' (default) or 'ihex', although must be specified for binary format only."); diff --git a/src/usb.c b/src/usb.c index 7f5c21283..12945d6d2 100644 --- a/src/usb.c +++ b/src/usb.c @@ -22,6 +22,53 @@ enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80}; +static inline uint32_t le_to_h_u32(const uint8_t* buf) +{ + return (uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24); +} + +static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, uint32_t khz) +{ + unsigned int i; + int speed_index = -1; + int speed_diff = INT_MAX; + int last_valid_speed = -1; + bool match = true; + + for (i = 0; i < map_size; i++) { + if (!map[i]) + continue; + last_valid_speed = i; + if (khz == map[i]) { + speed_index = i; + break; + } else { + int current_diff = khz - map[i]; + /* get abs value for comparison */ + current_diff = (current_diff > 0) ? current_diff : -current_diff; + if ((current_diff < speed_diff) && khz >= map[i]) { + speed_diff = current_diff; + speed_index = i; + } + } + } + + if (speed_index == -1) { + /* this will only be here if we cannot match the slow speed. + * use the slowest speed we support.*/ + speed_index = last_valid_speed; + match = false; + } else if (i == map_size) + match = false; + + if (!match) { + ILOG("Unable to match requested speed %d kHz, using %d kHz\n", \ + khz, map[speed_index]); + } + + return speed_index; +} + void _stlink_usb_close(stlink_t* sl) { if (!sl) return; @@ -39,34 +86,34 @@ void _stlink_usb_close(stlink_t* sl) { } ssize_t send_recv(struct stlink_libusb* handle, int terminate, - unsigned char* txbuf, size_t txsize, - unsigned char* rxbuf, size_t rxsize) { + 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; int t; t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, - txbuf, - (int) txsize, - &res, - 3000); + txbuf, + (int) txsize, + &res, + 3000); if (t) { printf("[!] send_recv send request failed: %s\n", libusb_error_name(t)); return -1; } else if ((size_t)res != txsize) { printf("[!] send_recv send request wrote %u bytes (instead of %u).\n", - (unsigned int)res, (unsigned int)txsize); + (unsigned int)res, (unsigned int)txsize); } if (rxsize != 0) { t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, - rxbuf, - (int) rxsize, - &res, - 3000); + rxbuf, + (int) rxsize, + &res, + 3000); if (t) { printf("[!] send_recv read reply failed: %s\n", - libusb_error_name(t)); + libusb_error_name(t)); return -1; } } @@ -75,13 +122,13 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, /* Read the SG reply */ unsigned char sg_buf[13]; t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, - sg_buf, - 13, - &res, - 3000); + sg_buf, + 13, + &res, + 3000); if (t) { printf("[!] send_recv read storage failed: %s\n", - libusb_error_name(t)); + libusb_error_name(t)); return -1; } /* The STLink doesn't seem to evaluate the sequence number */ @@ -135,6 +182,19 @@ int _stlink_usb_version(stlink_t *sl) { return (int) size; } + /* STLINK-V3 requires a specific command */ + if (sl->version.stlink_v == 3) { + rep_len = 12; + i = fill_command(sl, SG_DXFER_FROM_DEV, 16); + cmd[i++] = STLINK_APIV3_GET_VERSION_EX; + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size != rep_len) { + printf("[!] send_recv STLINK_APIV3_GET_VERSION_EX\n"); + return (int) size; + } + } + return 0; } @@ -207,6 +267,30 @@ int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { return 0; } +int _stlink_usb_get_rw_status(stlink_t *sl) +{ + if (sl->version.jtag_api == STLINK_JTAG_API_V1) + return -1; + + unsigned char* const rdata = sl->q_buf; + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const cmd = sl->c_buf; + int i, ret = 0; + + i = fill_command(sl, SG_DXFER_FROM_DEV, 12); + cmd[i++] = STLINK_DEBUG_COMMAND; + if (sl->version.flags & STLINK_F_HAS_GETLASTRWSTATUS2) { + cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS2; + ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 12); + } else { + cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS; + ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 2); + } + if (ret < 0) + return -1; + return 0; +} + int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; @@ -221,12 +305,11 @@ int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { ret = send_only(slu, 0, cmd, slu->cmd_len); if (ret == -1) return ret; - - ret = send_only(slu, 1, data, len); + ret = send_only(slu, 0, data, len); if (ret == -1) return ret; - return 0; + return _stlink_usb_get_rw_status(sl); } int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { @@ -274,11 +357,14 @@ int _stlink_usb_core_id(stlink_t * sl) { unsigned char* const cmd = sl->c_buf; unsigned char* const data = sl->q_buf; ssize_t size; - int rep_len = 4; + int rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 12; int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_READCOREID; + if (sl->version.jtag_api == STLINK_JTAG_API_V1) + cmd[i++] = STLINK_DEBUG_READCOREID; + else + cmd[i++] = STLINK_DEBUG_APIV2_READ_IDCODES; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { @@ -286,11 +372,39 @@ int _stlink_usb_core_id(stlink_t * sl) { return -1; } - sl->core_id = read_uint32(data, 0); + if (sl->version.jtag_api == STLINK_JTAG_API_V1) + sl->core_id = read_uint32(data, 0); + else + sl->core_id = read_uint32(data, 4); return 0; } +int _stlink_usb_status_v2(stlink_t *sl) +{ + int result; + uint32_t status; + + result = _stlink_usb_read_debug32(sl, DCB_DHCSR, &status); + DLOG("core status: %08X\n", status); + if (result != 0) { + sl->core_stat = TARGET_UNKNOWN; + } else { + if (status & S_HALT) { + sl->core_stat = TARGET_HALTED; + } else if (status & S_RESET_ST) { + sl->core_stat = TARGET_RESET; + } else { + sl->core_stat = TARGET_RUNNING; + } + } + + return result; +} int _stlink_usb_status(stlink_t * sl) { + if (sl->version.jtag_api != STLINK_JTAG_API_V1) { + return _stlink_usb_status_v2(sl); + } + struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -307,6 +421,14 @@ int _stlink_usb_status(stlink_t * sl) { return (int) size; } sl->q_len = (int) size; + if (sl->q_len > 1) { + if (sl->q_buf[0] == STLINK_CORE_RUNNING) + sl->core_stat = TARGET_RUNNING; + else if (sl->q_buf[0] == STLINK_CORE_HALTED) + sl->core_stat = TARGET_HALTED; + else + sl->core_stat = TARGET_UNKNOWN; + } return 0; } @@ -334,14 +456,19 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; ssize_t size; - const int rep_len = 0; + unsigned char* const data = sl->q_buf; + const uint32_t rep_len = sl->version.stlink_v > 1 ? 2 : 0; int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_ENTER; + cmd[i++] = sl->version.jtag_api == STLINK_JTAG_API_V1 ? STLINK_DEBUG_APIV1_ENTER : STLINK_DEBUG_APIV2_ENTER; cmd[i++] = STLINK_DEBUG_ENTER_SWD; - size = send_only(slu, 1, cmd, slu->cmd_len); + if (rep_len == 0) { + size = send_only(slu, 1, cmd, slu->cmd_len); + } else { + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + } if (size == -1) { printf("[!] send_recv STLINK_DEBUG_ENTER\n"); return (int) size; @@ -378,7 +505,10 @@ int _stlink_usb_reset(stlink_t * sl) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_RESETSYS; + if (sl->version.jtag_api == STLINK_JTAG_API_V1) + cmd[i++] = STLINK_DEBUG_APIV1_RESETSYS; + else + cmd[i++] = STLINK_DEBUG_APIV2_RESETSYS; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { @@ -388,7 +518,7 @@ int _stlink_usb_reset(stlink_t * sl) { // Reset through AIRCR so NRST does not need to be connected return stlink_write_debug32(sl, STLINK_REG_AIRCR, - STLINK_REG_AIRCR_VECTKEY | STLINK_REG_AIRCR_SYSRESETREQ); + STLINK_REG_AIRCR_VECTKEY | STLINK_REG_AIRCR_SYSRESETREQ); } @@ -440,6 +570,14 @@ int _stlink_usb_step(stlink_t* sl) { */ int _stlink_usb_run(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; + + int res; + if (sl->version.jtag_api != STLINK_JTAG_API_V1) { + res = _stlink_usb_write_debug32(sl, DCB_DHCSR, DBGKEY|C_DEBUGEN); + return res; + } + + unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; @@ -466,9 +604,8 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { ssize_t size; int rep_len = 2; int i; - // clock speed only supported by stlink/v2 and for firmware >= 22 - if (sl->version.stlink_v >= 2 && sl->version.jtag_v >= 22) { + if (sl->version.stlink_v == 2 && sl->version.jtag_v >= 22) { i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; @@ -483,9 +620,55 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { } return 0; - } else { - return -1; + } else if (sl->version.stlink_v == 3) { + int speed_index; + uint32_t map[STLINK_V3_MAX_FREQ_NB]; + i = fill_command(sl, SG_DXFER_FROM_DEV, 16); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_APIV3_GET_COM_FREQ; + cmd[i++] = 0; // SWD mode + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, 52); + if (size == -1) { + printf("[!] send_recv STLINK_APIV3_GET_COM_FREQ\n"); + return (int) size; + } + + int speeds_size = data[8]; + + if (speeds_size > STLINK_V3_MAX_FREQ_NB) + speeds_size = STLINK_V3_MAX_FREQ_NB; + + for (i = 0; i < speeds_size; i++) + map[i] = le_to_h_u32(&data[12 + 4 * i]); + + /* set to zero all the next entries */ + for (i = speeds_size; i < STLINK_V3_MAX_FREQ_NB; i++) + map[i] = 0; + + speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), 1800); + + i = fill_command(sl, SG_DXFER_FROM_DEV, 16); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_APIV3_SET_COM_FREQ; + cmd[i++] = 0; // SWD mode + cmd[i++] = 0; + cmd[i++] = (uint8_t)((map[speed_index] >> 0) & 0xFF); + cmd[i++] = (uint8_t)((map[speed_index] >> 8) & 0xFF); + cmd[i++] = (uint8_t)((map[speed_index] >> 16) & 0xFF); + cmd[i++] = (uint8_t)((map[speed_index] >> 24) & 0xFF); + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8); + if (size == -1) { + printf("[!] send_recv STLINK_APIV3_SET_COM_FREQ\n"); + return (int) size; + } + + return 0; } + return -1; } int _stlink_usb_exit_debug_mode(stlink_t *sl) { @@ -535,33 +718,40 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { unsigned char* const cmd = sl->c_buf; unsigned char* const data = sl->q_buf; ssize_t size; - uint32_t rep_len = 84; + uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 84 : 88; int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_READALLREGS; + if (sl->version.jtag_api == STLINK_JTAG_API_V1) + cmd[i++] = STLINK_DEBUG_APIV1_READALLREGS; + else + cmd[i++] = STLINK_DEBUG_APIV2_READALLREGS; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_DEBUG_READALLREGS\n"); return (int) size; } + + /* V1: regs data from offset 0 */ + /* V2: status at offset 0, regs data from offset 4 */ + int reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; sl->q_len = (int) size; stlink_print_data(sl); - for(i=0; i<16; i++) + for(i=reg_offset; 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); + regp->xpsr = read_uint32(sl->q_buf, reg_offset + 64); + regp->main_sp = read_uint32(sl->q_buf, reg_offset + 68); + regp->process_sp = read_uint32(sl->q_buf, reg_offset + 72); + regp->rw = read_uint32(sl->q_buf, reg_offset + 76); + regp->rw2 = read_uint32(sl->q_buf, reg_offset + 80); if (sl->verbose < 2) return 0; - DLOG("xpsr = 0x%08x\n", read_uint32(sl->q_buf, 64)); - DLOG("main_sp = 0x%08x\n", read_uint32(sl->q_buf, 68)); - DLOG("process_sp = 0x%08x\n", read_uint32(sl->q_buf, 72)); - DLOG("rw = 0x%08x\n", read_uint32(sl->q_buf, 76)); - DLOG("rw2 = 0x%08x\n", read_uint32(sl->q_buf, 80)); + DLOG("xpsr = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 64)); + DLOG("main_sp = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 68)); + DLOG("process_sp = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 72)); + DLOG("rw = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 76)); + DLOG("rw2 = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 80)); return 0; } @@ -572,11 +762,15 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t r; - uint32_t rep_len = 4; + uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 8; + int reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_READREG; + if (sl->version.jtag_api == STLINK_JTAG_API_V1) + cmd[i++] = STLINK_DEBUG_APIV1_READREG; + else + cmd[i++] = STLINK_DEBUG_APIV2_READREG; cmd[i++] = (uint8_t) r_idx; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { @@ -585,7 +779,7 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { } sl->q_len = (int) size; stlink_print_data(sl); - r = read_uint32(sl->q_buf, 0); + r = read_uint32(sl->q_buf, reg_offset); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); switch (r_idx) { @@ -723,7 +917,10 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_WRITEREG; + if (sl->version.jtag_api == STLINK_JTAG_API_V1) + cmd[i++] = STLINK_DEBUG_APIV1_WRITEREG; + else + cmd[i++] = STLINK_DEBUG_APIV2_WRITEREG; cmd[i++] = idx; write_uint32(&cmd[i], reg); size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); @@ -731,7 +928,7 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { printf("[!] send_recv STLINK_DEBUG_WRITEREG\n"); return (int) size; } -sl->q_len = (int) size; + sl->q_len = (int) size; stlink_print_data(sl); return 0; @@ -785,7 +982,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST sl->backend = &_stlink_usb_backend; sl->backend_data = slu; - sl->core_stat = STLINK_CORE_STAT_UNKNOWN; + sl->core_stat = TARGET_UNKNOWN; if (libusb_init(&(slu->libusb_ctx))) { WLOG("failed to init libusb context, wrong version of libraries?\n"); goto on_error; @@ -822,36 +1019,54 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST if (devBus && devAddr) { if ((libusb_get_bus_number(list[cnt]) != devBus) - || (libusb_get_device_address(list[cnt]) != devAddr)) { + || (libusb_get_device_address(list[cnt]) != devAddr)) { continue; } } - if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) || (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) || (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO)) { + if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) + || (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) + || (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO) + || (desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER) + || (desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID) + || (desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID) + || (desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID)) { struct libusb_device_handle *handle; ret = libusb_open(list[cnt], &handle); if (ret) - continue; + continue; sl->serial_size = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial)); libusb_close(handle); + if ((desc.idProduct == STLINK_USB_PID_STLINK_32L) + || (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO) + || (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO)) { + sl->version.stlink_v = 2; + } else if ((desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER) + || (desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID) + || (desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID) + || (desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID)) { + sl->version.stlink_v = 3; + } + if ((serial == NULL) || (*serial == 0)) - break; + break; if (sl->serial_size < 0) - continue; + continue; if (memcmp(serial, &sl->serial, sl->serial_size) == 0) - break; + break; continue; } if (desc.idProduct == STLINK_USB_PID_STLINK) { slu->protocoll = 1; + sl->version.stlink_v = 1; break; } } @@ -901,7 +1116,12 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST // TODO - could use the scanning techniq from stm8 code here... slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; - if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO || desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO) { + if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO + || desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO + || desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER + || desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID + || desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID + || desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID) { slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; } else { slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; @@ -911,21 +1131,23 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST // TODO - never used at the moment, always CMD_SIZE slu->cmd_len = (slu->protocoll == 1)? STLINK_SG_SIZE: STLINK_CMD_SIZE; + // Initialize stlink version (sl->version) + stlink_version(sl); + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { ILOG("-- exit_dfu_mode\n"); stlink_exit_dfu_mode(sl); } + // set the speed before entering the mode + // as the chip discovery phase should be done at this speed too + // Set the stlink clock speed (default is 1800kHz) + stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } - - // Initialize stlink version (sl->version) - stlink_version(sl); - // Set the stlink clock speed (default is 1800kHz) - stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); - if (reset) { if( sl->version.stlink_v > 1 ) stlink_jtag_reset(sl, 2); stlink_reset(sl); @@ -972,9 +1194,13 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { break; } - if (desc.idProduct != STLINK_USB_PID_STLINK_32L && - desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && - desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO) + if (desc.idProduct != STLINK_USB_PID_STLINK_32L + && desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO + && desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO + && desc.idProduct != STLINK_USB_PID_STLINK_V3_USBLOADER + && desc.idProduct != STLINK_USB_PID_STLINK_V3E_PID + && desc.idProduct != STLINK_USB_PID_STLINK_V3S_PID + && desc.idProduct != STLINK_USB_PID_STLINK_V3_2VCP_PID) continue; slcnt++; @@ -997,9 +1223,9 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { break; } - if (desc.idProduct != STLINK_USB_PID_STLINK_32L && - desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && - desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO) + if (desc.idProduct != STLINK_USB_PID_STLINK_32L && + desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO && + desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO) continue; struct libusb_device_handle* handle; @@ -1014,7 +1240,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial)); if (ret < 0) - *serial = 0; + *serial = 0; libusb_close(handle); From 1752c123b4633521e0c04baa4c60ea59c61228a5 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Wed, 22 Apr 2020 14:54:42 +0800 Subject: [PATCH 0866/1435] Fix issue 663 with enhanced error output --- src/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common.c b/src/common.c index 0dc6bc967..50f87f42c 100644 --- a/src/common.c +++ b/src/common.c @@ -949,7 +949,7 @@ int stlink_load_device_params(stlink_t *sl) { sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, (unsigned int)sl->flash_pgsz); #else - ILOG("%s: %d KiB SRAM, %d KiB flash in %d %s pages.\n", + ILOG("%s: %zd KiB SRAM, %zd KiB flash in at least %zd %s pages.\n", params->description, sl->sram_size / 1024, sl->flash_size / 1024, (sl->flash_pgsz < 1024)? sl->flash_pgsz : sl->flash_pgsz/1024, (sl->flash_pgsz < 1024)? "byte" : "KiB"); @@ -2223,7 +2223,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t WLOG("unaligned len 0x%x -- padding with zero\n", len); len += 1; } else if (addr & (sl->flash_pgsz - 1)) { - ELOG("addr not a multiple of pagesize, not supported\n"); + ELOG("addr not a multiple of current pagesize (%zd bytes), not supported\n", sl->flash_pgsz); return -1; } From 4a2881413af584bc53a19789c4e317d0ec2be9a2 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 17 Apr 2020 11:20:29 +0200 Subject: [PATCH 0867/1435] common: add some flash option lock/unlock helpers --- src/common.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 174 insertions(+), 6 deletions(-) diff --git a/src/common.c b/src/common.c index afeb6106a..2f226f016 100644 --- a/src/common.c +++ b/src/common.c @@ -1,5 +1,4 @@ #define DEBUG_FLASH 0 - #include #include #include @@ -35,6 +34,7 @@ #define FLASH_ACR (FLASH_REGS_ADDR + 0x00) #define FLASH_KEYR (FLASH_REGS_ADDR + 0x04) +#define FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x08) #define FLASH_SR (FLASH_REGS_ADDR + 0x0c) #define FLASH_CR (FLASH_REGS_ADDR + 0x10) #define FLASH_AR (FLASH_REGS_ADDR + 0x14) @@ -56,6 +56,12 @@ #define FLASH_OPTKEY1 0x08192A3B #define FLASH_OPTKEY2 0x4C5D6E7F +#define FLASH_F0_OPTKEY1 0x45670123 +#define FLASH_F0_OPTKEY2 0xCDEF89AB + +#define FLASH_L0_OPTKEY1 0xFBEAD9C8 +#define FLASH_L0_OPTKEY2 0x24252627 + #define FLASH_SR_BSY 0 #define FLASH_SR_EOP 5 @@ -64,6 +70,7 @@ #define FLASH_CR_MER 2 #define FLASH_CR_STRT 6 #define FLASH_CR_LOCK 7 +#define FLASH_CR_OPTWRE 9 //32L = 32F1 same CoreID as 32F4! @@ -167,6 +174,7 @@ // WB Flash control register. #define STM32WB_FLASH_CR_STRT (16) /* FLASH_CR Start */ +#define STM32WB_FLASH_CR_OPTLOCK (30) /* FLASH_CR Option Lock */ #define STM32WB_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ // WB Flash status register. #define STM32WB_FLASH_SR_BSY (16) /* FLASH_SR Busy */ @@ -230,8 +238,9 @@ #define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08) #define FLASH_F4_SR (FLASH_F4_REGS_ADDR + 0x0c) #define FLASH_F4_CR (FLASH_F4_REGS_ADDR + 0x10) -#define FLASH_F4_OPT_CR (FLASH_F4_REGS_ADDR + 0x14) -#define FLASH_F4_OPT_LOCK_BIT (1u << 0) +#define FLASH_F4_OPTCR (FLASH_F4_REGS_ADDR + 0x14) +#define FLASH_F4_OPTCR_LOCK 0 +#define FLASH_F4_OPTCR_START 1 #define FLASH_F4_CR_STRT 16 #define FLASH_F4_CR_LOCK 31 #define FLASH_F4_CR_SER 1 @@ -301,6 +310,19 @@ uint32_t read_uint32(const unsigned char *c, const int pt) { return ui; } +static uint32_t get_stm32l0_flash_base(stlink_t *sl) +{ + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_L1_CAT2: + case STLINK_CHIPID_STM32_L1_MEDIUM: + case STLINK_CHIPID_STM32_L1_MEDIUM_PLUS: + case STLINK_CHIPID_STM32_L1_HIGH: + return STM32L1_FLASH_REGS_ADDR; + default: + return STM32L0_FLASH_REGS_ADDR; + } +} + static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { uint32_t rdp; stlink_read_debug32(sl, FLASH_WRPR, &rdp); @@ -386,9 +408,8 @@ static void unlock_flash(stlink_t *sl) { } } +/* unlock flash if already locked */ static int unlock_flash_if(stlink_t *sl) { - /* unlock flash if already locked */ - if (is_flash_locked(sl)) { unlock_flash(sl); if (is_flash_locked(sl)) { @@ -430,6 +451,154 @@ static void lock_flash(stlink_t *sl) { } } +static bool is_flash_option_locked(stlink_t *sl) { + uint32_t optlock_shift, optcr_reg; + int active_bit_level = 1; + uint32_t n; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; + optlock_shift = FLASH_CR_OPTWRE; + active_bit_level = 0; /* bit is "option write enable", not lock */ + break; + case STLINK_FLASH_TYPE_F4: + optcr_reg = FLASH_F4_OPTCR; + optlock_shift = FLASH_F4_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_L0: + optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + optlock_shift = STM32L0_FLASH_OPTLOCK; + break; + case STLINK_FLASH_TYPE_L4: + optcr_reg = STM32L4_FLASH_CR; + optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_WB: + optcr_reg = STM32WB_FLASH_CR; + optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + break; + default: + return -1; + } + + stlink_read_debug32(sl, optcr_reg, &n); + + if (active_bit_level == 0) + return !(n & (1u << optlock_shift)); + return n & (1u << optlock_shift); + +} + +static int lock_flash_option(stlink_t *sl) { + uint32_t optlock_shift, optcr_reg, n; + int active_bit_level = 1; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; + optlock_shift = FLASH_CR_OPTWRE; + active_bit_level = 0; + break; + case STLINK_FLASH_TYPE_F4: + optcr_reg = FLASH_F4_OPTCR; + optlock_shift = FLASH_F4_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_L0: + optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + optlock_shift = STM32L0_FLASH_OPTLOCK; + break; + case STLINK_FLASH_TYPE_L4: + optcr_reg = STM32L4_FLASH_CR; + optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_WB: + optcr_reg = STM32WB_FLASH_CR; + optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + break; + + default: + return -1; + } + + stlink_read_debug32(sl, optcr_reg, &n); + if (active_bit_level == 0) + n &= ~(1u << optlock_shift); + else + n |= (1u << optlock_shift); + stlink_write_debug32(sl, optcr_reg, n); + + return 0; +} + +static int unlock_flash_option(stlink_t *sl) +{ + uint32_t optkey_reg; + uint32_t optkey1 = FLASH_OPTKEY1; + uint32_t optkey2 = FLASH_OPTKEY2; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optkey_reg = FLASH_OPTKEYR; + optkey1 = FLASH_F0_OPTKEY1; + optkey2 = FLASH_F0_OPTKEY2; + break; + case STLINK_FLASH_TYPE_F4: + optkey_reg = FLASH_F4_OPT_KEYR; + break; + case STLINK_FLASH_TYPE_L0: + optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; + optkey1 = FLASH_L0_OPTKEY1; + optkey2 = FLASH_L0_OPTKEY2; + break; + case STLINK_FLASH_TYPE_L4: + optkey_reg = STM32L4_FLASH_OPTKEYR; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optkey_reg = STM32Gx_FLASH_OPTKEYR; + break; + case STLINK_FLASH_TYPE_WB: + optkey_reg = STM32WB_FLASH_OPT_KEYR; + break; + + default: + return -1; + } + + stlink_write_debug32(sl, optkey_reg, optkey1); + stlink_write_debug32(sl, optkey_reg, optkey2); + + return 0; +} + +static int unlock_flash_option_if(stlink_t *sl) { + if (is_flash_option_locked(sl)) { + if (unlock_flash_option(sl)) { + ELOG("Could not unlock flash option!\n"); + return -1; + } + if (is_flash_option_locked(sl)) { + ELOG("Failed to unlock flash option!\n"); + return -1; + } + } + DLOG("Successfully unlocked flash option\n"); + return 0; +} static void set_flash_cr_pg(stlink_t *sl) { uint32_t cr_reg, x; @@ -3307,7 +3476,6 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui ELOG("Option bytes writing is currently not implemented for connected chip\n"); return -1; } - } /** From 29cfb7deb6d5c253f93c10c27965aa3bd1aa3912 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Mon, 20 Apr 2020 17:40:30 +0200 Subject: [PATCH 0868/1435] common: add some l0/l1 support in helpers give l0/l1 some love - l0/l1 are a bit specific regarding keys, bits, and lock registers. Also make handling of f0/f1 explicit: ultimate goal is to have some sanity check and clear codepath in that code in case some new target is added - and that the whole code uses these helpers. some work should be done to refactor a bit the flash register mapping based on family, but not yet. lo lock --- src/common.c | 101 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 28 deletions(-) diff --git a/src/common.c b/src/common.c index 2f226f016..6281d5332 100644 --- a/src/common.c +++ b/src/common.c @@ -53,6 +53,12 @@ #define FLASH_KEY1 0x45670123 #define FLASH_KEY2 0xcdef89ab +#define FLASH_L0_PRGKEY1 0x8c9daebf +#define FLASH_L0_PRGKEY2 0x13141516 + +#define FLASH_L0_PEKEY1 0x89abcdef +#define FLASH_L0_PEKEY2 0x02030405 + #define FLASH_OPTKEY1 0x08192A3B #define FLASH_OPTKEY2 0x4C5D6E7F @@ -363,48 +369,74 @@ static inline uint32_t read_flash_cr2(stlink_t *sl) { static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ - uint32_t cr_lock_shift, cr = read_flash_cr(sl); + uint32_t cr_lock_shift; + uint32_t cr_reg; + uint32_t n; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; cr_lock_shift = FLASH_F4_CR_LOCK; - else if (sl->flash_type == STLINK_FLASH_TYPE_L4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + cr_lock_shift = STM32L0_FLASH_PELOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; cr_lock_shift = STM32Gx_FLASH_CR_LOCK; - else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; - else - cr_lock_shift = FLASH_CR_LOCK; + } else { + return -1; + } - return cr & (1u << cr_lock_shift); + stlink_read_debug32(sl, cr_reg, &n); + return n & (1u << cr_lock_shift); } static void unlock_flash(stlink_t *sl) { uint32_t key_reg; + uint32_t flash_key1 = FLASH_KEY1; + uint32_t flash_key2 = FLASH_KEY2; /* the unlock sequence consists of 2 write cycles where 2 key values are written to the FLASH_KEYR register. an invalid sequence results in a definitive lock of the FPEC block until next reset. */ - if (sl->flash_type == STLINK_FLASH_TYPE_F4) + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + key_reg = FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { key_reg = FLASH_F4_KEYR; - else if (sl->flash_type == STLINK_FLASH_TYPE_L4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; + flash_key1 = FLASH_L0_PEKEY1; + flash_key2 = FLASH_L0_PEKEY2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { key_reg = STM32L4_FLASH_KEYR; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { key_reg = STM32Gx_FLASH_KEYR; - else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { key_reg = STM32WB_FLASH_KEYR; - else - key_reg = FLASH_KEYR; + } else { + return; + } - stlink_write_debug32(sl, key_reg, FLASH_KEY1); - stlink_write_debug32(sl, key_reg, FLASH_KEY2); + stlink_write_debug32(sl, key_reg, flash_key1); + stlink_write_debug32(sl, key_reg, flash_key2); if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - stlink_write_debug32(sl, FLASH_KEYR2, FLASH_KEY1); - stlink_write_debug32(sl, FLASH_KEYR2, FLASH_KEY2); + stlink_write_debug32(sl, FLASH_KEYR2, flash_key1); + stlink_write_debug32(sl, FLASH_KEYR2, flash_key2); } } @@ -424,9 +456,16 @@ static int unlock_flash_if(stlink_t *sl) { static void lock_flash(stlink_t *sl) { uint32_t cr_lock_shift, cr_reg, n; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + if (sl->flash_type == STLINK_FLASH_TYPE_F0 || + sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_lock_shift = FLASH_F4_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + cr_lock_shift = STM32L0_FLASH_PELOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; @@ -438,11 +477,11 @@ static void lock_flash(stlink_t *sl) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; } else { - cr_reg = FLASH_CR; - cr_lock_shift = FLASH_CR_LOCK; + return; } - n = read_flash_cr(sl) | (1u << cr_lock_shift); + stlink_read_debug32(sl, cr_reg, &n); + n |= (1u << cr_lock_shift); stlink_write_debug32(sl, cr_reg, n); if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { @@ -795,7 +834,11 @@ static void set_flash_cr2_strt(stlink_t *sl) { static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res, sr_reg; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) + sr_reg = FLASH_SR; + else if (sl->flash_type == STLINK_FLASH_TYPE_L0) + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + else if (sl->flash_type == STLINK_FLASH_TYPE_F4) sr_reg = FLASH_F4_SR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) sr_reg = STM32L4_FLASH_SR; @@ -805,7 +848,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { else if (sl->flash_type == STLINK_FLASH_TYPE_WB) sr_reg = STM32WB_FLASH_SR; else - sr_reg = FLASH_SR; + return -1; stlink_read_debug32(sl, sr_reg, &res); @@ -822,7 +865,9 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { uint32_t sr_busy_shift; unsigned int res; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_L0)) + sr_busy_shift = FLASH_SR_BSY; + else if (sl->flash_type == STLINK_FLASH_TYPE_F4) sr_busy_shift = FLASH_F4_SR_BSY; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) sr_busy_shift = STM32L4_FLASH_SR_BSY; @@ -832,7 +877,7 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { else if (sl->flash_type == STLINK_FLASH_TYPE_WB) sr_busy_shift = STM32WB_FLASH_SR_BSY; else - sr_busy_shift = FLASH_SR_BSY; + return -1; res = read_flash_sr(sl) & (1 << sr_busy_shift); From 2cff67a59bf959a4c1dea9863b47401748ec0e5e Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Mon, 20 Apr 2020 15:57:48 +0200 Subject: [PATCH 0869/1435] update f2 and f4 option read/write code routines 1) no need to unlock option flash to read it. "The option byte are always read-accessible and write-protected by default." current device specific option read code now only differs from generic read code by reading option bytes in the flash option byte register instead of option base. 2) f4 and f2 have similar registers : use the same write code, with flash/option lock helpers. add flash busy wait and relock at end of access. 3) add f446 option info to chip id --- src/chipid.c | 4 +- src/common.c | 168 +++++++-------------------------------------------- 2 files changed, 26 insertions(+), 146 deletions(-) diff --git a/src/chipid.c b/src/chipid.c index 60d0787e9..ee85aaf65 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -218,7 +218,9 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x20000, .sram_size = 0x20000, .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .bootrom_size = 0x7800, + .option_base = 0x1FFFC000, + .option_size = 4, }, { // STM32F410 MCUs. Support based on DM00180366.pdf (RM0401) document. diff --git a/src/common.c b/src/common.c index 6281d5332..6770aca3f 100644 --- a/src/common.c +++ b/src/common.c @@ -3235,62 +3235,6 @@ static int stlink_write_option_bytes_l496x(stlink_t *sl, uint8_t* base, stm32_ad } -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_f2(stlink_t *sl, uint8_t *base, stm32_addr_t addr, size_t len) { - uint32_t val; - uint32_t option_byte; - - (void) addr; - (void) len; - - option_byte = *(uint32_t*) (base); - - stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); - if (val & FLASH_F2_OPT_LOCK_BIT) { - WLOG("Unlocking option flash\n"); - //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) - //https://www.st.com/resource/en/programming_manual/cd00233952.pdf - stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, FLASH_OPTKEY1); - stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, FLASH_OPTKEY2); - - stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); - if (val & FLASH_F2_OPT_LOCK_BIT) { - ELOG("Option flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } - - stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); - WLOG("option bytes CR = %x\n",val); - - stlink_write_debug32(sl, FLASH_F2_OPT_CR, option_byte & 0x0FFFFFFC); - - stlink_write_debug32(sl, FLASH_F2_OPT_CR, (option_byte & 0x0FFFFFFC)|0x00000002); - - - stlink_read_debug32(sl, FLASH_F2_SR, &val); - WLOG("wait BSY flag to be 0\n"); - - while (val & 0x00010000){ - stlink_read_debug32(sl, FLASH_F2_SR, &val); - } - WLOG("BSY flag is 0\n"); - - stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); - WLOG("option bytes CR = %x\n",val); - WLOG("Option flash re-lock\n"); - stlink_write_debug32(sl, FLASH_F2_OPT_CR, val | 0x00000001); - - DLOG("STM32 F2 option bytes are written\n"); - - return 0; -} - /** * Write option bytes * @param sl @@ -3298,52 +3242,37 @@ static int stlink_write_option_bytes_f2(stlink_t *sl, uint8_t *base, stm32_addr_ * @return 0 on success, -ve on failure. */ static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - uint32_t val; uint32_t option_byte; (void) addr; (void) len; - option_byte = *(uint32_t*) (base); - - stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); - if (val & FLASH_F4_OPT_LOCK_BIT) { - WLOG("Unlocking option flash\n"); - //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) - //https://www.st.com/resource/en/programming_manual/cd00233952.pdf - stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, FLASH_OPTKEY1); - stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, FLASH_OPTKEY2); + wait_flash_busy(sl); - stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); - if (val & FLASH_F4_OPT_LOCK_BIT) { - ELOG("Option flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; } - stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); - WLOG("option bytes CR = %x\n",val); - - stlink_write_debug32(sl, FLASH_F4_OPT_CR, option_byte & 0x0FFFFFFC); + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } + write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); - stlink_write_debug32(sl, FLASH_F4_OPT_CR, (option_byte & 0x0FFFFFFC)|0x00000002); + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F4_OPTCR, (option_byte & ~(1 << FLASH_F4_OPTCR_LOCK)) | (1 << FLASH_F4_OPTCR_START)); - stlink_read_debug32(sl, FLASH_F4_SR, &val); - WLOG("wait BSY flag to be 0\n"); + wait_flash_busy(sl); - while (val & 0x00010000){ - stlink_read_debug32(sl, FLASH_F4_SR, &val); - } - WLOG("BSY flag is 0\n"); + check_flash_error(sl); - stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); - WLOG("option bytes CR = %x\n",val); - WLOG("Option flash re-lock\n"); - stlink_write_debug32(sl, FLASH_F4_OPT_CR, val | 0x00000001); + /* option bytes are reloaded at reset only, no obl. */ - DLOG("STM32 F4 option bytes are written\n"); + lock_flash_option(sl); + lock_flash(sl); - return 0; + return 0; } /** @@ -3352,11 +3281,8 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_ * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) -{ - uint32_t ret = stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); - WLOG("option bytes CR = %#010x\n", *option_byte); - return ret; +int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) { + return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); } /** @@ -3366,30 +3292,7 @@ int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) * @return 0 on success, -ve on failure. */ int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { - uint32_t val; - - stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); - if (val & FLASH_F2_OPT_LOCK_BIT) { - WLOG("Unlocking option flash\n"); - //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) - //https://www.st.com/resource/en/programming_manual/cd00233952.pdf - stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, FLASH_OPTKEY1); - stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, FLASH_OPTKEY2); - - stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); - if (val & FLASH_F2_OPT_LOCK_BIT) { - ELOG("Option flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } - - stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); - WLOG("option bytes CR = %x\n",option_byte); - - WLOG("Option flash re-lock\n"); - stlink_write_debug32(sl, FLASH_F2_OPT_CR, val | 0x00000001); - - return 0; + return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); } /** @@ -3399,39 +3302,15 @@ int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { * @return 0 on success, -ve on failure. */ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { - uint32_t val; - - stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); - if (val & FLASH_F4_OPT_LOCK_BIT) { - WLOG("Unlocking option flash\n"); - //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) - //https://www.st.com/resource/en/programming_manual/cd00233952.pdf - stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, FLASH_OPTKEY1); - stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, FLASH_OPTKEY2); - - stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val); - if (val & FLASH_F4_OPT_LOCK_BIT) { - ELOG("Option flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } - - stlink_read_debug32(sl, FLASH_F4_OPT_CR, option_byte); - WLOG("option bytes CR = %x\n", option_byte); - - WLOG("Option flash re-lock\n"); - stlink_write_debug32(sl, FLASH_F4_OPT_CR, val | 0x00000001); - - return 0; + return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); } /** -* Read first option bytes + * Read first option bytes * @param sl * @param option_byte option value * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) -{ +int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { return stlink_read_debug32(sl, sl->option_base, option_byte); } @@ -3502,7 +3381,6 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui /* filter out on chip_id, until complete flash family are handled */ switch (sl->chip_id) { case STLINK_CHIPID_STM32_F2: - return stlink_write_option_bytes_f2(sl, base, addr, len); case STLINK_CHIPID_STM32_F446: return stlink_write_option_bytes_f4(sl, base, addr, len); case STLINK_CHIPID_STM32_L0_CAT2: From 9e53550d24a9434c4c01754cb5fd69f1f3fc705d Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Mon, 20 Apr 2020 15:57:40 +0200 Subject: [PATCH 0870/1435] update l4 option code to use helpers, based on l496. use generic unlock for l4, rename l496 to l4x, add wait flash busy, complete chip id for l476 (and other) --- src/chipid.c | 4 +++- src/common.c | 56 ++++++++++++++-------------------------------------- 2 files changed, 18 insertions(+), 42 deletions(-) diff --git a/src/chipid.c b/src/chipid.c index ee85aaf65..17cb4d546 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -53,7 +53,9 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x20000, .sram_size = 0x20000, .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .bootrom_size = 0x7800, + .option_base = 0x1FFFC000, + .option_size = 4, }, { // PM0063 .chip_id = STLINK_CHIPID_STM32_F1_LOW, diff --git a/src/common.c b/src/common.c index 6770aca3f..79d346e46 100644 --- a/src/common.c +++ b/src/common.c @@ -78,8 +78,6 @@ #define FLASH_CR_LOCK 7 #define FLASH_CR_OPTWRE 9 - -//32L = 32F1 same CoreID as 32F4! #define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00) #define STM32L_FLASH_ACR (STM32L_FLASH_REGS_ADDR + 0x00) #define STM32L_FLASH_PECR (STM32L_FLASH_REGS_ADDR + 0x04) @@ -3162,43 +3160,23 @@ static int stlink_write_option_bytes_l1(stlink_t *sl, uint8_t* base, stm32_addr_ * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l496x(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { +static int stlink_write_option_bytes_l4(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { uint32_t val; (void) addr; (void) len; - /* Unlock flash if necessary */ - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - if ((val & (1u << STM32L4_FLASH_CR_LOCK))) { - - /* disable flash write protection. */ - stlink_write_debug32(sl, STM32L4_FLASH_KEYR, 0x45670123); - stlink_write_debug32(sl, STM32L4_FLASH_KEYR, 0xCDEF89AB); + wait_flash_busy(sl); - // check that the lock is no longer set. - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - if ((val & (1u << STM32L4_FLASH_CR_LOCK))) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; } - /* Unlock option bytes if necessary (ref manuel page 61) */ - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - if ((val & (1 << STM32L4_FLASH_CR_OPTLOCK))) { - - /* disable option byte write protection. */ - stlink_write_debug32(sl, STM32L4_FLASH_OPTKEYR, FLASH_OPTKEY1); - stlink_write_debug32(sl, STM32L4_FLASH_OPTKEYR, FLASH_OPTKEY2); - - /* check that the lock is no longer set. */ - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - if ((val & (1 << STM32L4_FLASH_CR_OPTLOCK))) { - ELOG("Options bytes unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; } /* Write options bytes */ @@ -3213,23 +3191,18 @@ static int stlink_write_option_bytes_l496x(stlink_t *sl, uint8_t* base, stm32_ad stlink_write_debug32(sl, STM32L4_FLASH_CR, val); /* Wait for 'busy' bit in FLASH_SR to clear. */ - do { - stlink_read_debug32(sl, STM32L4_FLASH_SR, &val); - } while ((val & (1 << 16)) != 0); + wait_flash_busy(sl); + + check_flash_error(sl); /* apply options bytes immediate */ stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - /* Re-lock option bytes */ - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1u << STM32L4_FLASH_CR_OPTLOCK); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); /* Re-lock flash. */ - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1u << STM32L4_FLASH_CR_LOCK); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + lock_flash_option(sl); + lock_flash(sl); return 0; } @@ -3386,7 +3359,8 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui case STLINK_CHIPID_STM32_L0_CAT2: return stlink_write_option_bytes_l0_cat2(sl, base, addr, len); case STLINK_CHIPID_STM32_L496X: - return stlink_write_option_bytes_l496x(sl, base, addr, len); + case STLINK_CHIPID_STM32_L4: + return stlink_write_option_bytes_l4(sl, base, addr, len); case STLINK_CHIPID_STM32_L152_RE: case STLINK_CHIPID_STM32_L1_HIGH: return stlink_write_option_bytes_l1(sl, base, addr, len); From 70043c426cc8f590ace5b4997759721161bfa88c Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Mon, 20 Apr 2020 15:31:37 +0200 Subject: [PATCH 0871/1435] update gx option code: use helpers. --- src/common.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/common.c b/src/common.c index 79d346e46..0a29a5716 100644 --- a/src/common.c +++ b/src/common.c @@ -2958,25 +2958,16 @@ static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, stm32_addr_ (void) addr; (void) len; + wait_flash_busy(sl); + if (unlock_flash_if(sl)) { ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); return -1; } - /* Unlock option bytes if necessary (ref manuel page 61) */ - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - if ((val & (1 << STM32Gx_FLASH_CR_OPTLOCK))) { - - /* disable option byte write protection. */ - stlink_write_debug32(sl, STM32Gx_FLASH_OPTKEYR, FLASH_OPTKEY1); - stlink_write_debug32(sl, STM32Gx_FLASH_OPTKEYR, FLASH_OPTKEY2); - - /* check that the lock is no longer set. */ - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - if ((val & (1 << STM32Gx_FLASH_CR_OPTLOCK))) { - ELOG("Options bytes unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; } /* Write options bytes */ @@ -3003,12 +2994,8 @@ static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, stm32_addr_ val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - /* Re-lock option bytes */ - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1u << STM32Gx_FLASH_CR_OPTLOCK); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - /* Re-lock flash. */ + lock_flash_option(sl); lock_flash(sl); return 0; From f23de8741a27ed46ccff4b9fa7806fc278b5961e Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Mon, 20 Apr 2020 16:06:54 +0200 Subject: [PATCH 0872/1435] update l0/l1 option code: merge l0/l1, code is the same except flash base, add wait states and relock --- src/common.c | 168 ++++++++++++--------------------------------------- 1 file changed, 39 insertions(+), 129 deletions(-) diff --git a/src/common.c b/src/common.c index 0a29a5716..147fee1ea 100644 --- a/src/common.c +++ b/src/common.c @@ -24,8 +24,6 @@ #define __attribute__(x) #endif -/* todo: stm32l15xxx flash memory, pm0062 manual */ - /* stm32f FPEC flash controller interface, pm0063 manual */ // TODO - all of this needs to be abstracted out.... // STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, August 2012) @@ -213,13 +211,14 @@ #define STM32L4_FLASH_OPTR_DUALBANK 21 -//STM32L0x flash register base and offsets -//same as 32L1 above -// RM0090 - DM00031020.pdf +//STM32L0x flash register base and offsets RM0090 - DM00031020.pdf #define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) -#define STM32L0_FLASH_PELOCK_BIT (1u << 0) -#define STM32L0_FLASH_OPTLOCK_BIT (1u << 2) -#define STM32L0_FLASH_OBL_LAUNCH_BIT (1u << 18) +#define STM32L1_FLASH_REGS_ADDR ((uint32_t)0x40023c00) + +#define STM32L0_FLASH_PELOCK (0) +#define STM32L0_FLASH_OPTLOCK (2) +#define STM32L0_FLASH_OBL_LAUNCH (18) + #define FLASH_ACR_OFF ((uint32_t) 0x00) #define FLASH_PECR_OFF ((uint32_t) 0x04) #define FLASH_PDKEYR_OFF ((uint32_t) 0x08) @@ -230,12 +229,6 @@ #define FLASH_OBR_OFF ((uint32_t) 0x1c) #define FLASH_WRPR_OFF ((uint32_t) 0x20) -//STM32L1 -#define STM32L1_FLASH_REGS_ADDR ((uint32_t)0x40023c00) -#define STM32L1_FLASH_PELOCK_BIT (1u << 0) -#define STM32L1_FLASH_OPTLOCK_BIT (1u << 2) -#define STM32L1_FLASH_OBL_LAUNCH_BIT (1u << 18) - //STM32F4 #define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) @@ -268,7 +261,6 @@ #define FLASH_F2_CR_SNB_MASK 0x78 #define FLASH_F2_SR_BSY 16 - #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 @@ -3001,62 +2993,6 @@ static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, stm32_addr_ return 0; } - -/** - * Write option bytes - * @param sl - * @param addr of the memory mapped option bytes - * @param base option bytes to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_l0_cat2(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - - uint32_t val; - (void) addr; - (void) len; - - stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if (val & STM32L0_FLASH_PELOCK_BIT) { - WLOG("Unlocking flash\n"); - //Unlock data EEPROM and the FLASH_PECR register (reference page 74) - stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PEKEYR_OFF, 0x89ABCDEF); - stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PEKEYR_OFF, 0x02030405); - - stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if (val & STM32L0_FLASH_PELOCK_BIT) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } - - stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if ((val & (STM32L0_FLASH_OPTLOCK_BIT))) { - WLOG("Unlocking options\n"); - //Unlock the Option bytes area (reference page 76) - stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_OPTKEYR_OFF, 0xFBEAD9C8); - stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_OPTKEYR_OFF, 0x24252627); - - stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if (val & STM32L0_FLASH_OPTLOCK_BIT) { - ELOG("Options unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - } - - /* Write options bytes */ - uint32_t data; - write_uint32((unsigned char*) &data, *(uint32_t*) (base)); - WLOG("Writing option bytes 0x%04x\n", data); - stlink_write_debug32(sl, STM32_L0_CATx_OPTION_BYTES_BASE, data); - - /* Reload options */ - stlink_read_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - val |= (STM32L0_FLASH_OBL_LAUNCH_BIT); - stlink_write_debug32(sl, STM32L0_FLASH_REGS_ADDR + FLASH_PECR_OFF, val); - - return 0; -} - /** * Write option bytes * @param sl @@ -3064,78 +3000,51 @@ static int stlink_write_option_bytes_l0_cat2(stlink_t *sl, uint8_t* base, stm32_ * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l1(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - +static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) +{ + uint32_t flash_base = get_stm32l0_flash_base(sl); uint32_t val; uint32_t data; - stlink_read_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if (val & STM32L1_FLASH_PELOCK_BIT) { - WLOG("Unlocking flash\n"); - //Unlock data EEPROM and the FLASH_PECR register (reference page 74) - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PEKEYR_OFF, 0x89ABCDEF); - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PEKEYR_OFF, 0x02030405); + wait_flash_busy(sl); - stlink_read_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if (val & STM32L1_FLASH_PELOCK_BIT) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; } - stlink_read_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if ((val & (STM32L1_FLASH_OPTLOCK_BIT))) { - WLOG("Unlocking options\n"); - //Unlock the Option bytes area (reference page 76) - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_OPTKEYR_OFF, 0xFBEAD9C8); - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_OPTKEYR_OFF, 0x24252627); - - stlink_read_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - if (val & STM32L1_FLASH_OPTLOCK_BIT) { - ELOG("Options unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; } - /* Clear errors */ - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_SR_OFF, 0x00003F00); + stlink_write_debug32(sl, flash_base + FLASH_SR_OFF, STM32L0_FLASH_REGS_ADDR); - stlink_read_debug32(sl, addr, &val); - WLOG("Option bytes 0x%08x is 0x%08x\n",addr,val); + while (len != 0) { + /* Write options bytes */ + write_uint32((unsigned char*) &data, *(uint32_t*) (base)); - /* Write options bytes */ - write_uint32((unsigned char*) &data, *(uint32_t*) (base)); - if ( data != val ) { - WLOG("Writing option bytes 0x%04x\n", data); + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); stlink_write_debug32(sl, addr, data); - stlink_read_debug32(sl, addr, &val); - WLOG("Option bytes is 0x%08x\n",val); - } - - if (len==8) { - /* Clear errors */ - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_SR_OFF, 0x00003F00); - - stlink_read_debug32(sl, addr+4, &val); - WLOG("2nd option bytes 0x%08x is 0x%08x\n",addr,val); + wait_flash_busy(sl); - /* Write options bytes */ - write_uint32((unsigned char*) &data, *(uint32_t*) (base+4)); + if (check_flash_error(sl)) + break; - if ( data != val ) { - WLOG("Writing 2nd option bytes 0x%04x\n", data); - stlink_write_debug32(sl, addr+4, data); - stlink_read_debug32(sl, addr+4, &val); - WLOG("2nd option bytes is 0x%08x\n",val); - } + len-=4; + addr+=4; + base+=4; } /* Reload options */ - stlink_read_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, &val); - val |= (STM32L1_FLASH_OBL_LAUNCH_BIT); - stlink_write_debug32(sl, STM32L1_FLASH_REGS_ADDR + FLASH_PECR_OFF, val); + stlink_read_debug32(sl, flash_base + FLASH_PECR_OFF, &val); + val |= (1 << STM32L0_FLASH_OBL_LAUNCH); + stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); + + lock_flash_option(sl); + lock_flash(sl); return 0; } @@ -3218,6 +3127,7 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_ ELOG("Flash option unlock failed!\n"); return -1; } + write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); /* write option byte, ensuring we dont lock opt, and set strt bit */ @@ -3344,13 +3254,13 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui case STLINK_CHIPID_STM32_F446: return stlink_write_option_bytes_f4(sl, base, addr, len); case STLINK_CHIPID_STM32_L0_CAT2: - return stlink_write_option_bytes_l0_cat2(sl, base, addr, len); + case STLINK_CHIPID_STM32_L0_CAT5: + case STLINK_CHIPID_STM32_L152_RE: + case STLINK_CHIPID_STM32_L1_HIGH: + return stlink_write_option_bytes_l0(sl, base, addr, len); case STLINK_CHIPID_STM32_L496X: case STLINK_CHIPID_STM32_L4: return stlink_write_option_bytes_l4(sl, base, addr, len); - case STLINK_CHIPID_STM32_L152_RE: - case STLINK_CHIPID_STM32_L1_HIGH: - return stlink_write_option_bytes_l1(sl, base, addr, len); case STLINK_CHIPID_STM32_G0_CAT1: case STLINK_CHIPID_STM32_G0_CAT2: case STLINK_CHIPID_STM32_G4_CAT2: From c4d9936976032cd863b7bce23ef2f25813ab2370 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Fri, 17 Apr 2020 16:23:47 +0200 Subject: [PATCH 0873/1435] common: implement flash check error for l0 and f0 --- src/common.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/common.c b/src/common.c index 147fee1ea..461e74a75 100644 --- a/src/common.c +++ b/src/common.c @@ -67,11 +67,16 @@ #define FLASH_L0_OPTKEY2 0x24252627 #define FLASH_SR_BSY 0 +#define FLASH_SR_PG_ERR 2 +#define FLASH_SR_WRPRT_ERR 4 #define FLASH_SR_EOP 5 +#define FLASH_SR_ERROR_MASK ((1 << FLASH_SR_PG_ERR) | (1 << FLASH_SR_WRPRT_ERR)) + #define FLASH_CR_PG 0 #define FLASH_CR_PER 1 #define FLASH_CR_MER 2 +#define FLASH_CR_OPTPG 4 #define FLASH_CR_STRT 6 #define FLASH_CR_LOCK 7 #define FLASH_CR_OPTWRE 9 @@ -219,6 +224,8 @@ #define STM32L0_FLASH_OPTLOCK (2) #define STM32L0_FLASH_OBL_LAUNCH (18) +#define STM32L0_FLASH_SR_ERROR_MASK 0x00003F00 + #define FLASH_ACR_OFF ((uint32_t) 0x00) #define FLASH_PECR_OFF ((uint32_t) 0x04) #define FLASH_PDKEYR_OFF ((uint32_t) 0x08) @@ -902,10 +909,19 @@ static void wait_flash_busy_progress(stlink_t *sl) { static int check_flash_error(stlink_t *sl) { uint32_t res = 0; - if ((sl->flash_type == STLINK_FLASH_TYPE_G0) || - (sl->flash_type == STLINK_FLASH_TYPE_G4)) { - res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK; - } + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + res = read_flash_sr(sl) & FLASH_SR_ERROR_MASK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK; + break; + case STLINK_FLASH_TYPE_L0: + res = read_flash_sr(sl) & STM32L0_FLASH_SR_ERROR_MASK; + default: + break; + } if (res) { ELOG("Flash programming error : %#010x\n", res); From a69a6fb68153e74bc93b397137be018c8dd0bb02 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Mon, 20 Apr 2020 18:35:45 +0200 Subject: [PATCH 0874/1435] use defines --- src/common.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/common.c b/src/common.c index 461e74a75..019e21756 100644 --- a/src/common.c +++ b/src/common.c @@ -2091,8 +2091,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); if ((val & (1<<0))||(val & (1<<1))) { /* disable pecr protection */ - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x89abcdef); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x02030405); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY2); /* check pecr.pelock is cleared */ stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -2102,8 +2102,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) } /* unlock program memory */ - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, 0x8c9daebf); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, 0x13141516); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY2); /* check pecr.prglock is cleared */ stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -2603,8 +2603,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t /* todo: check write operation */ /* disable pecr protection */ - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x89abcdef); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, 0x02030405); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY2); /* check pecr.pelock is cleared */ stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -2614,8 +2614,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t } /* unlock program memory */ - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, 0x8c9daebf); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, 0x13141516); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY2); /* check pecr.prglock is cleared */ stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); From 853468d1744d0c116bffa017e01f6d29ae735fdf Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Tue, 21 Apr 2020 10:27:40 +0200 Subject: [PATCH 0875/1435] common: whitespace fixes --- src/common.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/common.c b/src/common.c index 019e21756..e0c5fde2a 100644 --- a/src/common.c +++ b/src/common.c @@ -734,8 +734,8 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { cr_reg = STM32Gx_FLASH_CR; cr_mer = (1 << STM32Gx_FLASH_CR_MER1); if (sl->has_dual_bank) { - cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); - } + cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); + } cr_pg = (1 << FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; @@ -1100,7 +1100,7 @@ int stlink_load_device_params(stlink_t *sl) { sl->chip_id = 0x413; } - params = stlink_chipid_get_params(sl->chip_id); // chipid.c + params = stlink_chipid_get_params(sl->chip_id); if (params == NULL) { WLOG("unknown chip id! %#x\n", chip_id); return -1; @@ -1166,12 +1166,12 @@ int stlink_load_device_params(stlink_t *sl) { // TODO make note of variable page size here..... ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %u bytes\n", sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, - (unsigned int)sl->flash_pgsz); + (unsigned int)sl->flash_pgsz); #else ILOG("%s: %d KiB SRAM, %d KiB flash in %d %s pages.\n", - params->description, sl->sram_size / 1024, sl->flash_size / 1024, - (sl->flash_pgsz < 1024)? sl->flash_pgsz : sl->flash_pgsz/1024, - (sl->flash_pgsz < 1024)? "byte" : "KiB"); + params->description, sl->sram_size / 1024, sl->flash_size / 1024, + (sl->flash_pgsz < 1024)? sl->flash_pgsz : sl->flash_pgsz/1024, + (sl->flash_pgsz < 1024)? "byte" : "KiB"); #endif return 0; } @@ -1285,9 +1285,9 @@ int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { ret = sl->backend->read_debug32(sl, addr, data); if (!ret) - DLOG("*** stlink_read_debug32 %x is %#x\n", *data, addr); + DLOG("*** stlink_read_debug32 %x is %#x\n", *data, addr); - return ret; + return ret; } int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { @@ -1955,7 +1955,7 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ uint32_t calculate_F7_sectornum(uint32_t flashaddr){ flashaddr &= ~STM32_FLASH_BASE; //Page now holding the actual flash address - if (flashaddr<0x20000) return(flashaddr/0x8000); + if (flashaddr<0x20000) return(flashaddr/0x8000); else if (flashaddr<0x40000) return(4); else return(flashaddr/0x40000) +4; @@ -2347,7 +2347,7 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, stlink_read_mem32(sl, address + (uint32_t) off, aligned_size); if (memcmp(sl->q_buf, data + off, cmp_size)) { - ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); + ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); return -1; } } @@ -2521,7 +2521,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t /* set programming mode */ set_flash_cr_pg(sl); - size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; + size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; for (off = 0; off < len;) { size_t size = len - off > buf_size ? buf_size : len - off; @@ -2642,7 +2642,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) { fprintf(stdout, "\r%3u/%3u pages written", (unsigned int)(off/sl->flash_pgsz), - (unsigned int)(len/sl->flash_pgsz)); + (unsigned int)(len/sl->flash_pgsz)); fflush(stdout); } @@ -3236,8 +3236,8 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) */ int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { - WLOG("About to write option byte %#10x to target.\n", option_byte); - return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *) &option_byte, 4); + WLOG("About to write option byte %#10x to target.\n", option_byte); + return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *) &option_byte, 4); } /** From f29e1a6a03733cc8839f297d264a5168bd4e0361 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Tue, 21 Apr 2020 10:49:00 +0200 Subject: [PATCH 0876/1435] common: warn on unsupported access. should only happen currently after adding a new flash family. --- src/common.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/common.c b/src/common.c index e0c5fde2a..c124e6091 100644 --- a/src/common.c +++ b/src/common.c @@ -391,6 +391,7 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; } else { + ELOG("unsupported flash method, abort\n"); return -1; } @@ -425,6 +426,7 @@ static void unlock_flash(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { key_reg = STM32WB_FLASH_KEYR; } else { + ELOG("unsupported flash method, abort\n"); return; } @@ -474,6 +476,7 @@ static void lock_flash(stlink_t *sl) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; } else { + ELOG("unsupported flash method, abort\n"); return; } @@ -521,6 +524,7 @@ static bool is_flash_option_locked(stlink_t *sl) { optlock_shift = STM32WB_FLASH_CR_OPTLOCK; break; default: + ELOG("unsupported flash method, abort\n"); return -1; } @@ -564,8 +568,8 @@ static int lock_flash_option(stlink_t *sl) { optcr_reg = STM32WB_FLASH_CR; optlock_shift = STM32WB_FLASH_CR_OPTLOCK; break; - default: + ELOG("unsupported flash method, abort\n"); return -1; } @@ -612,6 +616,7 @@ static int unlock_flash_option(stlink_t *sl) break; default: + ELOG("unsupported flash method, abort\n"); return -1; } @@ -831,21 +836,23 @@ static void set_flash_cr2_strt(stlink_t *sl) { static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res, sr_reg; - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { sr_reg = FLASH_SR; - else if (sl->flash_type == STLINK_FLASH_TYPE_L0) + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; - else if (sl->flash_type == STLINK_FLASH_TYPE_F4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { sr_reg = FLASH_F4_SR; - else if (sl->flash_type == STLINK_FLASH_TYPE_L4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { sr_reg = STM32L4_FLASH_SR; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { sr_reg = STM32Gx_FLASH_SR; - else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_reg = STM32WB_FLASH_SR; - else + } else { + ELOG("unsupported flash method, abort"); return -1; + } stlink_read_debug32(sl, sr_reg, &res); @@ -862,19 +869,21 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { uint32_t sr_busy_shift; unsigned int res; - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_L0)) + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_L0)) { sr_busy_shift = FLASH_SR_BSY; - else if (sl->flash_type == STLINK_FLASH_TYPE_F4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { sr_busy_shift = FLASH_F4_SR_BSY; - else if (sl->flash_type == STLINK_FLASH_TYPE_L4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { sr_busy_shift = STM32L4_FLASH_SR_BSY; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { sr_busy_shift = STM32Gx_FLASH_SR_BSY; - else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_busy_shift = STM32WB_FLASH_SR_BSY; - else + } else { + ELOG("unsupported flash method, abort"); return -1; + } res = read_flash_sr(sl) & (1 << sr_busy_shift); From 8e69625531ec8f6def7a50a60a21f2aeffcd272a Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Tue, 21 Apr 2020 10:52:52 +0200 Subject: [PATCH 0877/1435] write option byte: final refactor now that all flash family methods are aligned, refactor main method to avoid duplicated lock/unlock, add info traces, and map methods based on familly instead of a small subset of selected devices. nb1: f0/f1 support is still missing nb2: option read/write is still conditioned by presence of option_base and option_size in chipid.c, but adding more chips should only be a matter of adding these two informations. --- src/common.c | 152 +++++++++++++++++++-------------------------------- 1 file changed, 55 insertions(+), 97 deletions(-) diff --git a/src/common.c b/src/common.c index c124e6091..f6cf08e2f 100644 --- a/src/common.c +++ b/src/common.c @@ -2971,27 +2971,14 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { uint32_t val; - - (void) addr; + int ret = 0; (void) len; - wait_flash_busy(sl); - - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; - } - /* Write options bytes */ uint32_t data; write_uint32((unsigned char*) &data, *(uint32_t*) (base)); WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - //stlink_write_debug32(sl, addr, data); + stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); /* Set Options Start bit */ @@ -2999,23 +2986,16 @@ static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, stm32_addr_ val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - /* Wait for 'busy' bit in FLASH_SR to clear. */ - do { - stlink_read_debug32(sl, STM32Gx_FLASH_SR, &val); - } while ((val & (1 << STM32Gx_FLASH_SR_BSY)) != 0); + wait_flash_busy(sl); - check_flash_error(sl); + ret = check_flash_error(sl); - /* apply options bytes immediate */ + /* Reload options */ stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); - - return 0; + return ret; } /** @@ -3030,18 +3010,7 @@ static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t* base, stm32_addr_ uint32_t flash_base = get_stm32l0_flash_base(sl); uint32_t val; uint32_t data; - - wait_flash_busy(sl); - - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; - } + int ret = 0; /* Clear errors */ stlink_write_debug32(sl, flash_base + FLASH_SR_OFF, STM32L0_FLASH_REGS_ADDR); @@ -3055,7 +3024,7 @@ static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t* base, stm32_addr_ wait_flash_busy(sl); - if (check_flash_error(sl)) + if ((ret = check_flash_error(sl))) break; len-=4; @@ -3068,10 +3037,7 @@ static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t* base, stm32_addr_ val |= (1 << STM32L0_FLASH_OBL_LAUNCH); stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); - lock_flash_option(sl); - lock_flash(sl); - - return 0; + return ret; } /** @@ -3084,22 +3050,11 @@ static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t* base, stm32_addr_ static int stlink_write_option_bytes_l4(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { uint32_t val; + int ret = 0; (void) addr; (void) len; - wait_flash_busy(sl); - - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; - } - /* Write options bytes */ uint32_t data; write_uint32((unsigned char*) &data, *(uint32_t*) (base)); @@ -3114,18 +3069,14 @@ static int stlink_write_option_bytes_l4(stlink_t *sl, uint8_t* base, stm32_addr_ /* Wait for 'busy' bit in FLASH_SR to clear. */ wait_flash_busy(sl); - check_flash_error(sl); + ret = check_flash_error(sl); /* apply options bytes immediate */ stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); - - return 0; + return ret; } @@ -3137,22 +3088,11 @@ static int stlink_write_option_bytes_l4(stlink_t *sl, uint8_t* base, stm32_addr_ */ static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { uint32_t option_byte; + int ret = 0; (void) addr; (void) len; - wait_flash_busy(sl); - - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } - - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; - } - write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); /* write option byte, ensuring we dont lock opt, and set strt bit */ @@ -3160,14 +3100,11 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_ wait_flash_busy(sl); - check_flash_error(sl); + ret = check_flash_error(sl); /* option bytes are reloaded at reset only, no obl. */ - lock_flash_option(sl); - lock_flash(sl); - - return 0; + return ret; } /** @@ -3258,6 +3195,8 @@ int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) */ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { + int ret = -1; + if (sl->option_base == 0) { ELOG("Option bytes writing is currently not supported for connected chip\n"); return -1; @@ -3273,28 +3212,47 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui return -1; } - /* filter out on chip_id, until complete flash family are handled */ - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F2: - case STLINK_CHIPID_STM32_F446: - return stlink_write_option_bytes_f4(sl, base, addr, len); - case STLINK_CHIPID_STM32_L0_CAT2: - case STLINK_CHIPID_STM32_L0_CAT5: - case STLINK_CHIPID_STM32_L152_RE: - case STLINK_CHIPID_STM32_L1_HIGH: - return stlink_write_option_bytes_l0(sl, base, addr, len); - case STLINK_CHIPID_STM32_L496X: - case STLINK_CHIPID_STM32_L4: - return stlink_write_option_bytes_l4(sl, base, addr, len); - case STLINK_CHIPID_STM32_G0_CAT1: - case STLINK_CHIPID_STM32_G0_CAT2: - case STLINK_CHIPID_STM32_G4_CAT2: - case STLINK_CHIPID_STM32_G4_CAT3: - return stlink_write_option_bytes_gx(sl, base, addr, len); + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F4: + ret = stlink_write_option_bytes_f4(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_L0: + ret = stlink_write_option_bytes_l0(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_L4: + ret = stlink_write_option_bytes_l4(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + ret = stlink_write_option_bytes_gx(sl, base, addr, len); + break; default: ELOG("Option bytes writing is currently not implemented for connected chip\n"); - return -1; + break; } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; } /** From e9facddc3cd2243f663a69d429432a1695ab1051 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Wed, 22 Apr 2020 14:54:42 +0800 Subject: [PATCH 0878/1435] Add more note about flash page size --- src/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 50f87f42c..a833ab0ea 100644 --- a/src/common.c +++ b/src/common.c @@ -2223,7 +2223,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t WLOG("unaligned len 0x%x -- padding with zero\n", len); len += 1; } else if (addr & (sl->flash_pgsz - 1)) { - ELOG("addr not a multiple of current pagesize (%zd bytes), not supported\n", sl->flash_pgsz); + ELOG("addr not a multiple of current pagesize (%zd bytes), not supported, check page start address and compare with flash module organisation in related ST reference manual of your device.\n", sl->flash_pgsz); return -1; } From ad0e52540e4003f05b7f6fa488e91c1d52c78df2 Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Wed, 22 Apr 2020 10:57:45 +0200 Subject: [PATCH 0879/1435] doc: update doc to mention STLINK_DEVICE and --probe parameters if applicable in all man files --- doc/man/st-flash.md | 3 +++ doc/man/st-info.md | 3 +++ doc/man/st-util.md | 5 ++--- doc/tutorial.md | 4 ++-- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md index b787e8dd7..d5565e923 100644 --- a/doc/man/st-flash.md +++ b/doc/man/st-flash.md @@ -20,6 +20,9 @@ You can use this instead of st-util(1) if you prefer, but remember to use the Use hexadecimal format for the *ADDR* and *SIZE*. +The STLink device to use can be specified using the --serial parameter, or via +the environment variable STLINK_DEVICE on the format :. + # COMMANDS write *FILE* *ADDR* diff --git a/doc/man/st-info.md b/doc/man/st-info.md index ca2579785..94a430000 100644 --- a/doc/man/st-info.md +++ b/doc/man/st-info.md @@ -11,9 +11,12 @@ st-info - Provides information about connected STLink and STM32 devices # DESCRIPTION + Provides information about connected STLink programmers and STM32 devices: Serial code, OpenOCD hla-serial, flash, page size, sram, chipid, description. +The STLink device to probe can be specified via the environment variable +STLINK_DEVICE on the format :. # OPTIONS diff --git a/doc/man/st-util.md b/doc/man/st-util.md index e62261213..3582bc06d 100644 --- a/doc/man/st-util.md +++ b/doc/man/st-util.md @@ -18,9 +18,8 @@ If a port number is not specified using the **--listen_port** option, the default **4242** port will be used. Stlink version 2 is used by default unless the option **--stlinkv1** is given. - -The STLinkV2 device to use can be specified in the environment -variable STLINK_DEVICE on the format :. +The STLink device to use can be specified using the --serial parameter, or via +the environment variable STLINK_DEVICE on the format :. # OPTIONS diff --git a/doc/tutorial.md b/doc/tutorial.md index 75e03f1bc..2ff0188ce 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -285,8 +285,8 @@ There are a few options: Do not reset board on connection. ``` -The STLINKv2 device to use can be specified in the environment -variable `STLINK_DEVICE` in the format `:`. +The STLink device to use can be specified using the --serial parameter, or via +the environment variable STLINK_DEVICE on the format :. Then, in your project directory, someting like this... (remember, you need to run an _ARM_ gdb, not an x86 gdb) From 5e0fd8b61c81f47f40592f9844b0f4507069137d Mon Sep 17 00:00:00 2001 From: Guillaume Revaillot Date: Wed, 22 Apr 2020 11:00:27 +0200 Subject: [PATCH 0880/1435] doc: remove stlink version parameter selectors doc and examples --- doc/man/st-util.md | 7 ------- doc/tutorial.md | 25 ++++++------------------- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/doc/man/st-util.md b/doc/man/st-util.md index 3582bc06d..9a54fb309 100644 --- a/doc/man/st-util.md +++ b/doc/man/st-util.md @@ -17,7 +17,6 @@ Run the main binary of the local package (src/main.rs). If a port number is not specified using the **--listen_port** option, the default **4242** port will be used. -Stlink version 2 is used by default unless the option **--stlinkv1** is given. The STLink device to use can be specified using the --serial parameter, or via the environment variable STLINK_DEVICE on the format :. @@ -35,12 +34,6 @@ the environment variable STLINK_DEVICE on the format :. -v, \--verbose : Specify generally verbose logging --s *X*, \--stlink_version=*X* -: Choose what version of stlink to use, (defaults to 2) - --1, \--stlinkv1 -: Force stlink version 1 - -p *4242*, \--listen_port=1234 : Set the gdb server listen port. (default port: 4242) diff --git a/doc/tutorial.md b/doc/tutorial.md index 2ff0188ce..929aa3250 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -168,18 +168,14 @@ will help you verify that: - Your arm-none-eabi-gdb is functional - Your board is functional -A GDB server must be started to interact with the STM32. Depending on -the discovery kit you are using, you must run one of the 2 commands: +A GDB server must be started to interact with the STM32 by running +st-util tool : ``` -# STM32VL discovery kit (onboard ST-link) -$> ./st-util --stlinkv1 - -# STM32L or STM32F4 discovery kit (onboard ST-link/V2) -$> ./st-util +$> st-util # Full help for other options (listen port, version) -$> ./st-util --help +$> st-util --help ``` Then, GDB can be used to interact with the kit: @@ -226,16 +222,10 @@ memory, or read arbitary addresses of memory out to a binary file, use the st-flash tool, as shown below: ``` -# stlinkv1 command to read 4096 from flash into out.bin -$> ./st-flash read out.bin 0x8000000 4096 - -# stlinkv2 command +# stlink command to read 4096 from flash into out.bin $> ./st-flash read out.bin 0x8000000 4096 -# stlinkv1 command to write the file in.bin into flash -$> ./st-flash write in.bin 0x8000000 - -# stlinkv2 command +# stlinkv command to write the file in.bin into flash $> ./st-flash write in.bin 0x8000000 ``` @@ -273,9 +263,6 @@ There are a few options: -h, --help Print this help -vXX, --verbose=XX Specify a specific verbosity level (0..99) -v, --verbose Specify generally verbose logging - -s X, --stlink_version=X - Choose what version of stlink to use, (defaults to 2) - -1, --stlinkv1 Force stlink version 1 -p 4242, --listen_port=1234 Set the gdb server listen port. (default port: 4242) -m, --multi From 5db2dc4c0410ace65308cddcc03d1c0cfa4855cf Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 23 Apr 2020 11:03:15 +0200 Subject: [PATCH 0881/1435] cmake replaces 7zip for package extraction The exctraction of the libusb library archive on windows no longer requires an external unarchiver. --- cmake/modules/Find7zip.cmake | 7 ------- cmake/modules/Findlibusb.cmake | 17 +++++------------ 2 files changed, 5 insertions(+), 19 deletions(-) delete mode 100644 cmake/modules/Find7zip.cmake diff --git a/cmake/modules/Find7zip.cmake b/cmake/modules/Find7zip.cmake deleted file mode 100644 index 83eb912d4..000000000 --- a/cmake/modules/Find7zip.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# Find7zip.cmake -# Detect 7zip file archiver on Windows systems to extract (zip-)archives - -find_program( - ZIP_EXECUTABLE NAMES 7z.exe p7zip - HINTS "C:\\Program Files\\7-Zip\\" "C:\\Program Files (x86)\\7-Zip\\" -) diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index 13f70d7b7..898820033 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -73,7 +73,6 @@ elseif (WIN32) # Windows if (NOT LIBUSB_FOUND OR EXISTS "/etc/debian_version") # Preparations for installing libusb library - find_package(7zip REQUIRED) set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) @@ -92,17 +91,11 @@ elseif (WIN32) # Windows file(MAKE_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) - # Extract libusb package - if (${ZIP_EXECUTABLE} MATCHES "p7zip") - execute_process( - COMMAND ${ZIP_EXECUTABLE} -d ${LIBUSB_WIN_ARCHIVE_PATH} - WORKING_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER} - ) - else () - execute_process( - COMMAND ${ZIP_EXECUTABLE} x -y ${LIBUSB_WIN_ARCHIVE_PATH} -o${LIBUSB_WIN_OUTPUT_FOLDER} - ) # <-- Note the absence of a space character following the -o option! - endif () + # Extract libusb package with cmake + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar xv ${LIBUSB_WIN_ARCHIVE_PATH} + WORKING_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER} + ) # Find path to libusb library FIND_PATH( From 39f22639ef461d5cd082e07df67d16de3082d9e3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 23 Apr 2020 11:04:38 +0200 Subject: [PATCH 0882/1435] Updated license file for deb package --- LICENSE.md | 2 +- cmake/packaging/debian/copyright | 321 +++++++++++++++---------------- 2 files changed, 153 insertions(+), 170 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index 9c3b59f0f..4cb795b18 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2020, The stlink project (github.com/stlink-org/stlink) & "Capt'ns Missing Link" authors. +Copyright (c) 2020, stlink-org All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cmake/packaging/debian/copyright b/cmake/packaging/debian/copyright index 7a6d585c5..4a7b110ae 100644 --- a/cmake/packaging/debian/copyright +++ b/cmake/packaging/debian/copyright @@ -2,173 +2,156 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: stlink Upstream-Contact: Luca Bocassi Source: https://github.com/stlink-org/stlink - -Files: * -Copyright: 2011-2018 agpanarin - 2011-2018 Alexey Cherevatenko - 2011-2018 Anatoli - 2011-2018 Andrea Mucignat - 2011-2018 Andrew 'Necromant' Andrianov - 2011-2018 Andrey Yurovsky - 2011-2018 Andy Isaacson - 2011-2018 Áron RADICS - 2011-2018 A Sheaff - 2011-2018 Björn Hauffe - 2011-2018 bob - 2011-2018 Breton M. Saunders - 2011-2018 Bruno Dal Bo - 2011-2018 Burns - 2011-2018 Chris Dew - 2011-2018 Chris Hiszpanski - 2011-2018 Chris Li - 2011-2018 Chris Samuelson - 2011-2018 Christophe Levantis - 2011-2018 Craig Lilley - 2011-2018 dandev37 - 2011-2018 Dan Hepler - 2011-2018 Daniel Campoverde [alx741] - 2011-2018 Daniel O'Connor - 2011-2018 Dave Flogeras - 2011-2018 Dave Murphy - 2011-2018 Dave Vandervies - 2011-2018 Denis Fokin - 2011-2018 Denis Osterland - 2011-2018 Dmitry Bravikov - 2011-2018 Efe Can İçöz - 2011-2018 Ethan Zonca - 2011-2018 Fabien Chouteau - 2011-2018 Fabien Le Mentec - 2011-2018 fhars - 2011-2018 Friedrich Beckmann - 2011-2018 Geoffrey Brown - 2011-2018 George Talusan - 2011-2018 Georg von Zengen - 2011-2018 giuseppe barba - 2011-2018 Greg Alexander - 2011-2018 Greg Meiste - 2011-2018 Hakkavélin - 2011-2018 htk - 2011-2018 Ian Griffiths <6thimage@gmail.com> - 2011-2018 Jack Peel - 2011-2018 Jakub Tyszkowski - 2011-2018 Jan Sarenik - 2011-2018 Jean-Luc Béchennec - 2011-2018 Jean-Marie Lemetayer - 2011-2018 Jeff Kent - 2011-2018 Jeffrey Nelson - 2011-2018 Jens Hoffmann - 2011-2018 Jerome Lambourg - 2011-2018 Jerry Jacobs - 2011-2018 Jim Paris - 2011-2018 Jiří Netolický - 2011-2018 jnosky - 2011-2018 jnosky - 2011-2018 JohannesTaelman - 2011-2018 Jonas Danielsson - 2011-2018 Jonas Norling - 2011-2018 Josh Bialkowski - 2011-2018 Karl Palsson - 2011-2018 kevin - 2011-2018 Kyle Manna - 2011-2018 Lari Lehtomäki - 2011-2018 le mentec fabien - 2011-2018 Martin Nowak - 2011-2018 Matteo Collina - 2011-2018 Max Chen - 2011-2018 Maxime Coquelin - 2011-2018 Maxime Vincent - 2011-2018 Michael Pratt - 2011-2018 Michael Sparmann - 2011-2018 Mike Szczys - 2011-2018 mlundinse - 2011-2018 mux - 2011-2018 Ned Konz - 2011-2018 Nic McDonald - 2011-2018 Nicolas Schodet - 2011-2018 Nikolay - 2011-2018 nullsub - 2011-2018 Olivier Croquette - 2011-2018 Olivier Gay - 2011-2018 Onno Kortmann - 2011-2018 orangeudav - 2011-2018 Pavel Kirienko - 2011-2018 Pekka Nikander - 2011-2018 Pete - 2011-2018 Peter Zotov - 2011-2018 Petteri Aimonen - 2011-2018 Piotr Haber - 2011-2018 Rene Hopf - 2011-2018 Robin Kreis - 2011-2018 Rob Spanton - 2011-2018 Rytis Karpuska - 2011-2018 Sean Simmons - 2011-2018 Sergey Alirzaev - 2011-2018 Simon Wright - 2011-2018 Stany MARCEL - 2011-2018 Stefan Misik - 2011-2018 Sven Wegener - 2011-2018 Tectu - 2011-2018 tekaikko - 2011-2018 texane - 2011-2018 Theodore A. Roth - 2011-2018 Thomas Gärtner - 2011-2018 Tobias Badertscher - 2011-2018 Tom de Boer - 2011-2018 Tristan Gingold - 2011-2018 Uli Köhler - 2011-2018 Uwe Bonnes - 2011-2018 Vadim Kaushan - 2011-2018 Vegard Storheil Eriksen - 2011-2018 Viacheslav Dobromyslov - 2011-2018 Victor Mayoral Vilches - 2011-2018 Wojciech A. Koszek - 2011-2018 Woodrow Douglass - 2011-2018 The "Capt'ns Missing Link" Authors. +Disclaimer: +Comment: License: BSD-3-clause - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - . - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - . - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Files: flashloaders/stm32l0x.s - flashloaders/stm32lx.s -Copyright: 2010 Spencer Oliver - 2011 Øyvind Harboe - 2011 Clement Burin des Roziers -License: GPL-2+ - This package is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see - . - On Debian systems, the complete text of the GNU General - Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Files: * +Copyright: 2011-2020 stlink-org + Martin Capitanio [capnm] + Fabien Le Mentec [texane] + Jerry Jacobs [xor-gate] + [Nightwalker-87] + . + Alexey Cherevatenko + Alexey Panarin + Anatoli Klassen [dev26th] + Andrea Mucignat + Andrew Andrianov [necromant] + Andrey Yurovsky + Andy Isaacson + Áron Radics + A. Sheaff + Björn Hauffe + Ihor Bobalo + Breton M. Saunders + Bruno Dal Bo + Burns Fisher + Chris Dew + Chris Hiszpanski + Chris Li + Chris Samuelson + Christian Deussen [nullsub] + Christophe Levantis + Craig Lilley + Dan Dev + Dan Hepler + Daniel Campoverde [alx741] + Daniel O'Connor + Dave Flogeras + Dave Murphy [WinterMute] + Dave Vandervies [dj3vande] + Denis Fokin + Denis Osterland + Dmitry Bravikov [bravikov] + Efe Can İçöz + Ethan Zonca + Fabien Chouteau + Florian Hars + Friedrich Beckmann + Geoffrey Brown + George Talusan [gtalusan] + Georg von Zengen + Giuseppe Barba + Greg Alexander [galexander1] + Greg Meiste [meisteg] + Guillaume Revaillot [grevaillot] + Hakkavélin + Halt Hammerzeit + htk + Ian Griffiths + Jack Peel + Jakub Tyszkowski + Jan Sarenik + Jean-Luc Béchennec + Jean-Marie Lemetayer + Jeff Kent + Jeffrey Nelson + Jens Hoffmann + Jerome Lambourg + Jim Paris + Jiří Netolický + Jerry Nosky [jnosky] + Johannes Taelman + Jonas Danielsson + Jonas Norling + Josh Bialkowski + Karl Palsson [karlp] + Kevlar Harness + Kyle Manna + Lari Lehtomäki + Martin Nowak + Matteo Collina + Max Chen + Maxime Coquelin [mcoquelin-stm32] + Maxime Vincent + Michael Pratt [prattmic] + Michael Sparmann + Mike Szczys + Magnus Lundin [mlu] + mux + Ned Konz + Nic McDonald + Nicolas Schodet + Oleksiy Slyshyk [slyshykO] + Olivier Croquette + Olivier Gay + Onno Kortmann + orangeudav + Pavel Kirienko + Pekka Nikander + Pete Nelson + Peter Zotov + Petteri Aimonen + Piotr Haber + Rene Hopf [rene-dev] + Robin Kreis + Roger Wolff [rewolff] + Rob Spanton + Rytis Karpuska + Sean Simmons + Sergey Alirzaev + Simon Wright + Stany Marcel + Stefan Misik + Sven Wegener + Joel Bodenmann [Tectu] + Tuomo Kaikkonen + Theodore A. Roth + Thomas Gärtner + Tobias Badertscher + Tom de Boer + Tristan Gingold + Uli Köhler + Uwe Bonnes [UweBonnes] + Vadim Kaushan + Vasiliy Glazov [Vascom] + Vegard Storheil Eriksen + Viacheslav Dobromyslov + Victor Mayoral Vilches + William Ransohoff [WRansohoff] + Wojciech A. Koszek + Woodrow Douglass + Xim [chenguokai] + ... and others From 3e3f782e5e4e98570c41e9f139e8d07c743e311a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 23 Apr 2020 22:52:00 +0200 Subject: [PATCH 0883/1435] Updated pkgconfig (Closes #944) --- CMakeLists.txt | 2 +- cmake/pkgconfig/CMakeLists.txt | 15 +++++++++++++++ .../pkgconfig/pkgconfig.pc.cmake | 9 +++++---- debian/pkg-config/CMakeLists.txt | 15 --------------- 4 files changed, 21 insertions(+), 20 deletions(-) create mode 100644 cmake/pkgconfig/CMakeLists.txt rename debian/pkg-config/pkg-config.pc.cmake => cmake/pkgconfig/pkgconfig.pc.cmake (99%) delete mode 100644 debian/pkg-config/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index fd79ac10e..3ec381239 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,7 @@ endif () find_package(libusb REQUIRED) if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) + add_subdirectory(cmake/pkgconfig) find_package(PkgConfig) pkg_check_modules(GTK3 gtk+-3.0) endif () @@ -269,7 +270,6 @@ add_subdirectory(tests) add_subdirectory(cmake/packaging) include(cmake/packaging/cpack_config.cmake) - ### # Uninstall target ### diff --git a/cmake/pkgconfig/CMakeLists.txt b/cmake/pkgconfig/CMakeLists.txt new file mode 100644 index 000000000..53870fee4 --- /dev/null +++ b/cmake/pkgconfig/CMakeLists.txt @@ -0,0 +1,15 @@ +set(PKG_CONFIG_LIBDIR "\${prefix}/lib/\${deb_host_multiarch}") +set(PKG_CONFIG_INCLUDEDIR "\${prefix}/include/\${deb_host_multiarch}/${PROJECT_NAME}") +set(PKG_CONFIG_LIBS "-L\${libdir} -l:libstlink.so.${PROJECT_VERSION_MAJOR}") +set(PKG_CONFIG_CFLAGS "-I\${includedir}") +set(PKG_CONFIG_REQUIRES "libusb-1.0") + +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig.pc.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + ) + +install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + DESTINATION ${STLINK_LIBRARY_PATH}/pkgconfig + ) diff --git a/debian/pkg-config/pkg-config.pc.cmake b/cmake/pkgconfig/pkgconfig.pc.cmake similarity index 99% rename from debian/pkg-config/pkg-config.pc.cmake rename to cmake/pkgconfig/pkgconfig.pc.cmake index c00eb070e..4f881daec 100644 --- a/debian/pkg-config/pkg-config.pc.cmake +++ b/cmake/pkgconfig/pkgconfig.pc.cmake @@ -1,10 +1,11 @@ +prefix=${CMAKE_INSTALL_PREFIX} deb_host_multiarch=${CMAKE_LIBRARY_PATH} +libdir=${PKG_CONFIG_LIBDIR} +includedir=${PKG_CONFIG_INCLUDEDIR} + Name: ${PROJECT_NAME} Description: ${PROJECT_DESCRIPTION} Version: ${PROJECT_VERSION} -Requires: ${PKG_CONFIG_REQUIRES} -prefix=${CMAKE_INSTALL_PREFIX} -includedir=${PKG_CONFIG_INCLUDEDIR} -libdir=${PKG_CONFIG_LIBDIR} Libs: ${PKG_CONFIG_LIBS} Cflags: ${PKG_CONFIG_CFLAGS} +Requires: ${PKG_CONFIG_REQUIRES} diff --git a/debian/pkg-config/CMakeLists.txt b/debian/pkg-config/CMakeLists.txt deleted file mode 100644 index fa3a326a8..000000000 --- a/debian/pkg-config/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -#set(PKG_CONFIG_LIBDIR "\${prefix}/lib/\${deb_host_multiarch}") -#set(PKG_CONFIG_INCLUDEDIR "\${prefix}/include/\${deb_host_multiarch}/${PROJECT_NAME}") -#set(PKG_CONFIG_LIBS "-L\${libdir} -l:libstlink.so.${PROJECT_VERSION_MAJOR}") -#set(PKG_CONFIG_CFLAGS "-I\${includedir}") -#set(PKG_CONFIG_REQUIRES "libusb-1.0") - -#configure_file( -# "${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.cmake" -# "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" -# ) - -#install( -# FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" -# DESTINATION ${STLINK_LIBRARY_PATH}/debian/ -# ) From 22f44856abe4f272f33c48a31c7167e3b45dd0ab Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 24 Apr 2020 01:08:02 +0200 Subject: [PATCH 0884/1435] Updated compiling manual - Removed requirement for 7zip on Windows - Added note on GNUInstallDir presets (#557) --- doc/compiling.md | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/doc/compiling.md b/doc/compiling.md index 15d8b4fc2..38e680f03 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -5,25 +5,23 @@ On Windows users should ensure that the following software is installed: -* `7zip` -* `git` +* `git` (_optional, but recommended_) * `cmake` (3.17.0 or later) * `MinGW-w64` (7.0.0 or later) with GCC toolchain 8.1.0 ### Installation -1. Install `7zip` from -2. Install `git` from -3. Install `cmake` from
    +1. Install `git` from +2. Install `cmake` from
    Ensure that you add cmake to the $PATH system variable when following the instructions by the setup assistant. -4. Install +3. Install - _EITHER_: **MinGW-w64** from (mingw-w64-install.exe)
    - _OR_: **Visual Studio 2017 CE** (other versions will likely work as well, but are untested; the Community edition is free for open source development) -5. Create a new destination folder at a place of your choice -6. Open the command-line (cmd.exe) and execute `cd C:\$Path-to-your-destination-folder$\` -7. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git`from the command-line (cmd.exe)
    +4. Create a new destination folder at a place of your choice +5. Open the command-line (cmd.exe) and execute `cd C:\$Path-to-your-destination-folder$\` +6. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git`from the command-line (cmd.exe)
    or download the stlink zip-sourcefolder from the Release page on GitHub @@ -201,10 +199,22 @@ To do this with only one simple command, type: The debug target is only necessary in order to modify the sources and to run under a debugger. -## Build using a different directory for shared libs +## Build options +### Build using a different directory for shared libs To put the compiled shared libs into a different directory during installation, you can use the cmake option `cmake -DLIB_INSTALL_DIR:PATH="/usr/lib64" ..`. +### Standard installation directories + +The cmake build system of this toolset includes `GNUInstallDirs` to define GNU standard installation directories. +This module provides install directory variables as defined by the GNU Coding Standards. + +Below are the preset default cmake options, which apply if none of these options are redefined: + +* `-DCMAKE_INSTALL_SYSCONFDIR=/etc` +* `-DCMAKE_INSTALL_PREFIX=/usr/local` + + Author: nightwalker-87 From 44e2a4fdbd3ad4398ab483c27275ea86540c31b6 Mon Sep 17 00:00:00 2001 From: xp Date: Fri, 24 Apr 2020 13:45:00 +0800 Subject: [PATCH 0885/1435] rewrite as clean room doc --- flashloaders/stm32f0.s | 85 +++++++++++++++++++++++++--------------- flashloaders/stm32f4.s | 53 +++++++++++++------------ flashloaders/stm32f4lv.s | 54 +++++++++++++------------ flashloaders/stm32f7.s | 65 ++++++++++++++++-------------- flashloaders/stm32f7lv.s | 66 ++++++++++++++++--------------- flashloaders/stm32l0x.s | 74 +++++++--------------------------- flashloaders/stm32l4.s | 60 ++++++++++++++-------------- flashloaders/stm32lx.s | 70 +++++++-------------------------- 8 files changed, 238 insertions(+), 289 deletions(-) diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index fe12f90f3..885353912 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -1,32 +1,53 @@ -/* Adopted from STM AN4065 stm32f0xx_flash.c:FLASH_ProgramWord */ - -write: - ldr r4, STM32_FLASH_BASE - mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ - mov r6, #4 /* PGERR */ -write_half_word: - ldr r3, [r4, #16] /* FLASH->CR */ - orr r3, r5 - str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ - ldrh r3, [r0] /* r3 = *sram */ - strh r3, [r1] /* *flash = r3 */ -busy: - ldr r3, [r4, #12] /* FLASH->SR */ - tst r3, r5 /* FLASH_SR_BUSY */ - beq busy - - tst r3, r6 /* PGERR */ - bne exit - - add r0, r0, #2 /* sram += 2 */ - add r1, r1, #2 /* flash += 2 */ - sub r2, r2, #0x01 /* count-- */ - cmp r2, #0 - bne write_half_word -exit: - ldr r3, [r4, #16] /* FLASH->CR */ - bic r3, r5 - str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ - bkpt #0x00 - -STM32_FLASH_BASE: .word 0x40022000 + .syntax unified + .text + + .global mycopy +mycopy: + ldr r12, flash_base + ldr r11, flash_off_cr + add r11, r11, r12 + ldr r10, flash_off_sr + add r10, r10, r12 + +myloop: + # FLASH_CR ^= 1 + ldr r3, [r11] + orr r3, r3, #0x1 + str r3, [r11] + + # copy 2 bytes + ldrh r3, [r0] + strh r3, [r1] + + add r0, r0, #2 + add r1, r1, #2 + + # wait if FLASH_SR == 1 +mywait: + ldr r3, [r10] + tst r3, #0x1 + beq mywait + + # exit if FLASH_SR == 4 + tst r3, #0x4 + beq myexit + + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne myloop + +myexit: + # FLASH_CR &= ~1 + ldr r3, [r11] + bic r3, r3, #0x1 + str r3, [r11] + + bkpt + +flash_base: + .word 0x40022000 +flash_off_cr: + .word 0x10 +flash_off_sr: + .word 0x0c diff --git a/flashloaders/stm32f4.s b/flashloaders/stm32f4.s index 21f5a8f7f..a47054dae 100644 --- a/flashloaders/stm32f4.s +++ b/flashloaders/stm32f4.s @@ -1,32 +1,35 @@ -.global start -.syntax unified + .syntax unified + .text -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp + .global mycopy +mycopy: + ldr r12, flash_base + ldr r10, flash_off_sr + add r10, r10, r12 -start: - ldr r3, flash_base -next: - cbz r2, done - ldr r4, [r0] - str r4, [r1] +myloop: + # copy 4 bytes + ldr r3, [r0] + str r3, [r1] -wait: - ldrh r4, [r3, #0x0e] - tst.w r4, #1 - bne wait + add r0, r0, #4 + add r1, r1, #4 - add r0, #4 - add r1, #4 - sub r2, #1 - b next -done: - bkpt + # wait if FLASH_SR == 1 +mywait: + ldrh r3, [r10] + tst r3, #0x1 + beq mywait + + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne myloop -.align 2 +myexit: + bkpt flash_base: - .word 0x40023c00 + .word 0x40023c00 +flash_off_sr: + .word 0x0e diff --git a/flashloaders/stm32f4lv.s b/flashloaders/stm32f4lv.s index f60ee8797..cfbbe8520 100644 --- a/flashloaders/stm32f4lv.s +++ b/flashloaders/stm32f4lv.s @@ -1,33 +1,35 @@ -.global start -.syntax unified + .syntax unified + .text -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp + .global mycopy +mycopy: + ldr r12, flash_base + ldr r10, flash_off_sr + add r10, r10, r12 -start: - lsls r2, r2, #2 - ldr r3, flash_base -next: - cbz r2, done - ldrb r4, [r0] - strb r4, [r1] +myloop: + # copy 1 bytes + ldrb r3, [r0] + strb r3, [r1] -wait: - ldrh r4, [r3, #0x0e] - tst.w r4, #1 - bne wait + add r0, r0, #1 + add r1, r1, #1 - add r0, #1 - add r1, #1 - sub r2, #1 - b next -done: - bkpt + # wait if FLASH_SR == 1 +mywait: + ldrh r3, [r10] + tst r3, #0x1 + beq mywait + + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne myloop -.align 2 +myexit: + bkpt flash_base: - .word 0x40023c00 + .word 0x40023c00 +flash_off_sr: + .word 0x0e diff --git a/flashloaders/stm32f7.s b/flashloaders/stm32f7.s index 0334c80a0..f873f0ebd 100644 --- a/flashloaders/stm32f7.s +++ b/flashloaders/stm32f7.s @@ -1,33 +1,38 @@ -.global start -.syntax unified - -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp - -start: - ldr r3, flash_base -next: - cbz r2, done - ldr r4, [r0] - str r4, [r1] - dsb sy - -wait: - ldrh r4, [r3, #0x0e] - tst.w r4, #1 - bne wait - - add r0, #4 - add r1, #4 - sub r2, #1 - b next -done: - bkpt + .syntax unified + .text + + .global mycopy +mycopy: + ldr r12, flash_base + ldr r10, flash_off_sr + add r10, r10, r12 + +myloop: + # copy 4 bytes + ldr r3, [r0] + str r3, [r1] + + add r0, r0, #4 + add r1, r1, #4 -.align 2 + # memory barrier + dsb sy + + # wait if FLASH_SR == 1 +mywait: + ldrh r3, [r10] + tst r3, #0x1 + beq mywait + + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne myloop + +myexit: + bkpt flash_base: - .word 0x40023c00 + .word 0x40023c00 +flash_off_sr: + .word 0x0e diff --git a/flashloaders/stm32f7lv.s b/flashloaders/stm32f7lv.s index 650922719..fe5be0529 100644 --- a/flashloaders/stm32f7lv.s +++ b/flashloaders/stm32f7lv.s @@ -1,34 +1,38 @@ -.global start -.syntax unified - -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp - -start: - lsls r2, r2, #2 - ldr r3, flash_base -next: - cbz r2, done - ldrb r4, [r0] - strb r4, [r1] - dsb sy - -wait: - ldrh r4, [r3, #0x0e] - tst.w r4, #1 - bne wait - - add r0, #1 - add r1, #1 - sub r2, #1 - b next -done: - bkpt + .syntax unified + .text + + .global mycopy +mycopy: + ldr r12, flash_base + ldr r10, flash_off_sr + add r10, r10, r12 + +myloop: + # copy 1 byte + ldrb r3, [r0] + strb r3, [r1] + + add r0, r0, #1 + add r1, r1, #1 -.align 2 + # memory barrier + dsb sy + + # wait if FLASH_SR == 1 +mywait: + ldrh r3, [r10] + tst r3, #0x1 + beq mywait + + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne myloop + +myexit: + bkpt flash_base: - .word 0x40023c00 + .word 0x40023c00 +flash_off_sr: + .word 0x0e diff --git a/flashloaders/stm32l0x.s b/flashloaders/stm32l0x.s index fcbd06e39..1ce7dd144 100644 --- a/flashloaders/stm32l0x.s +++ b/flashloaders/stm32l0x.s @@ -1,64 +1,20 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2011 Clement Burin des Roziers * - * clement.burin-des-roziers@hikob.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - - -// Build : arm-eabi-gcc -c stm32lx.S - .text .syntax unified - .cpu cortex-m0plus - .thumb - .thumb_func - .global write - -/* - r0 - source address - r1 - destination address - r2 - count -*/ + .text - // Go to compare - b test_done + .global mycopy +mycopy: +myloop: + # copy 4 bytes + ldr r3, [r0] + str r3, [r1] -write_word: - // Load one word from address in r0, increment by 4 - ldr r4, [r0] - // Store the word to address in r1, increment by 4 - str r4, [r1] - // Decrement r2 - subs r2, #1 - adds r1, #4 - // does not matter, only first addr is important - // next 15 bytes are in sequnce RM0367 page 66 - adds r0, #4 + add r0, r0, #4 + add r1, r1, #4 -test_done: - // Test r2 - cmp r2, #0 - // Loop if not zero - bcc.n write_word + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne myloop - // Set breakpoint to exit - bkpt #0x00 +myexit: + bkpt diff --git a/flashloaders/stm32l4.s b/flashloaders/stm32l4.s index 6aa2be050..0a68b687a 100644 --- a/flashloaders/stm32l4.s +++ b/flashloaders/stm32l4.s @@ -1,39 +1,37 @@ -.global start -.syntax unified + .syntax unified + .text -@ Adapted from stm32f4.s -@ STM32L4's flash controller expects double-word writes, has the flash -@ controller mapped in a different location with the registers we care about -@ moved down from the base address, and has BSY moved to bit 16 of SR. -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp -@ r5 = temp + .global mycopy +mycopy: + ldr r12, flash_base + ldr r10, flash_off_bsy + add r10, r10, r12 -start: - ldr r3, flash_base -next: - cbz r2, done - ldr r4, [r0] /* copy doubleword from source to target */ - ldr r5, [r0, #4] - str r4, [r1] - str r5, [r1, #4] +myloop: + # copy 8 bytes + ldr r3, [r0] + ldr r3, [r0, #4] + str r3, [r1] + str r3, [r1, #4] -wait: - ldrh r4, [r3, #0x12] /* high half of status register */ - tst r4, #1 /* BSY = bit 16 */ - bne wait + add r0, r0, #8 + add r1, r1, #8 - add r0, #8 - add r1, #8 - sub r2, #1 - b next -done: - bkpt + # wait if FLASH_BSY[0b] == 1 +mywait: + ldrh r3, [r10] + tst r3, #0x1 + beq mywait + + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne myloop -.align 2 +myexit: + bkpt flash_base: .word 0x40022000 +flash_off_bsy: + .word 0x12 diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index 10e5644bf..1ce7dd144 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -1,60 +1,20 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2011 Clement Burin des Roziers * - * clement.burin-des-roziers@hikob.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - - -// Build : arm-eabi-gcc -c stm32lx.s - .text .syntax unified - .cpu cortex-m3 - .thumb - .thumb_func - .global write - -/* - r0 - source address - r1 - destination address - r2 - output, remaining word count -*/ + .text - // Go to compare - b test_done + .global mycopy +mycopy: +myloop: + # copy 4 bytes + ldr r3, [r0] + str r3, [r1] -write_word: - // Load one word from address in r0, increment by 4 - ldr.w ip, [r0], #4 - // Store the word to address in r1, increment by 4 - str.w ip, [r1], #4 - // Decrement r2 - subs r2, #1 + add r0, r0, #4 + add r1, r1, #4 -test_done: - // Test r2 - cmp r2, #0 - // Loop if not zero - bhi write_word + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne myloop - // Set breakpoint to exit - bkpt #0x00 +myexit: + bkpt From 14518803dd2dbdaf15a1cd3e9216b6f0a919aeeb Mon Sep 17 00:00:00 2001 From: xp Date: Fri, 24 Apr 2020 14:31:52 +0800 Subject: [PATCH 0886/1435] bugfix --- flashloaders/stm32l4.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flashloaders/stm32l4.s b/flashloaders/stm32l4.s index 0a68b687a..79abac0d4 100644 --- a/flashloaders/stm32l4.s +++ b/flashloaders/stm32l4.s @@ -10,9 +10,9 @@ mycopy: myloop: # copy 8 bytes ldr r3, [r0] - ldr r3, [r0, #4] + ldr r4, [r0, #4] str r3, [r1] - str r3, [r1, #4] + str r4, [r1, #4] add r0, r0, #8 add r1, r1, #8 From 43085438f2c674d2fa3506dcb698930b87b71432 Mon Sep 17 00:00:00 2001 From: xp Date: Fri, 24 Apr 2020 16:39:56 +0800 Subject: [PATCH 0887/1435] update --- flashloaders/stm32f0.s | 58 +++++++++++++++++++++++----------------- flashloaders/stm32f4.s | 11 ++++---- flashloaders/stm32f4lv.s | 11 ++++---- flashloaders/stm32f7.s | 11 ++++---- flashloaders/stm32f7lv.s | 11 ++++---- flashloaders/stm32l0x.s | 8 +++--- flashloaders/stm32l4.s | 15 ++++++----- flashloaders/stm32lx.s | 8 +++--- 8 files changed, 76 insertions(+), 57 deletions(-) diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index 885353912..1adeada05 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -1,53 +1,63 @@ .syntax unified .text +flash_base: + .align 2 + .word 0x40022000 +flash_off_cr: + .word 0x10 +flash_off_sr: + .word 0x0c + .global mycopy mycopy: - ldr r12, flash_base - ldr r11, flash_off_cr - add r11, r11, r12 - ldr r10, flash_off_sr - add r10, r10, r12 + ldr r7, =flash_base + ldr r4, [r7] + ldr r7, =flash_off_cr + ldr r6, [r7] + adds r6, r6, r4 + ldr r7, =flash_off_sr + ldr r5, [r7] + adds r5, r5, r4 myloop: # FLASH_CR ^= 1 - ldr r3, [r11] - orr r3, r3, #0x1 - str r3, [r11] + ldr r7, =0x1 + ldr r3, [r6] + orrs r3, r3, r7 + str r3, [r6] # copy 2 bytes ldrh r3, [r0] strh r3, [r1] - add r0, r0, #2 - add r1, r1, #2 + ldr r7, =2 + adds r0, r0, r7 + adds r1, r1, r7 # wait if FLASH_SR == 1 mywait: - ldr r3, [r10] - tst r3, #0x1 + ldr r7, =0x1 + ldr r3, [r5] + tst r3, r7 beq mywait # exit if FLASH_SR == 4 - tst r3, #0x4 + ldr r7, =0x4 + tst r3, r7 beq myexit # loop if r2 != 0 - sub r2, r2, #1 + ldr r7, =0x1 + subs r2, r2, r7 cmp r2, #0 bne myloop myexit: # FLASH_CR &= ~1 - ldr r3, [r11] - bic r3, r3, #0x1 - str r3, [r11] + ldr r7, =0x1 + ldr r3, [r6] + bics r3, r3, r7 + str r3, [r6] bkpt - -flash_base: - .word 0x40022000 -flash_off_cr: - .word 0x10 -flash_off_sr: - .word 0x0c diff --git a/flashloaders/stm32f4.s b/flashloaders/stm32f4.s index a47054dae..938ca8401 100644 --- a/flashloaders/stm32f4.s +++ b/flashloaders/stm32f4.s @@ -1,6 +1,12 @@ .syntax unified .text +flash_base: + .align 2 + .word 0x40023c00 +flash_off_sr: + .word 0x0e + .global mycopy mycopy: ldr r12, flash_base @@ -28,8 +34,3 @@ mywait: myexit: bkpt - -flash_base: - .word 0x40023c00 -flash_off_sr: - .word 0x0e diff --git a/flashloaders/stm32f4lv.s b/flashloaders/stm32f4lv.s index cfbbe8520..fa8bedbaa 100644 --- a/flashloaders/stm32f4lv.s +++ b/flashloaders/stm32f4lv.s @@ -1,6 +1,12 @@ .syntax unified .text +flash_base: + .align 2 + .word 0x40023c00 +flash_off_sr: + .word 0x0e + .global mycopy mycopy: ldr r12, flash_base @@ -28,8 +34,3 @@ mywait: myexit: bkpt - -flash_base: - .word 0x40023c00 -flash_off_sr: - .word 0x0e diff --git a/flashloaders/stm32f7.s b/flashloaders/stm32f7.s index f873f0ebd..604ab0465 100644 --- a/flashloaders/stm32f7.s +++ b/flashloaders/stm32f7.s @@ -1,6 +1,12 @@ .syntax unified .text +flash_base: + .align 2 + .word 0x40023c00 +flash_off_sr: + .word 0x0e + .global mycopy mycopy: ldr r12, flash_base @@ -31,8 +37,3 @@ mywait: myexit: bkpt - -flash_base: - .word 0x40023c00 -flash_off_sr: - .word 0x0e diff --git a/flashloaders/stm32f7lv.s b/flashloaders/stm32f7lv.s index fe5be0529..157347542 100644 --- a/flashloaders/stm32f7lv.s +++ b/flashloaders/stm32f7lv.s @@ -1,6 +1,12 @@ .syntax unified .text +flash_base: + .algin 2 + .word 0x40023c00 +flash_off_sr: + .word 0x0e + .global mycopy mycopy: ldr r12, flash_base @@ -31,8 +37,3 @@ mywait: myexit: bkpt - -flash_base: - .word 0x40023c00 -flash_off_sr: - .word 0x0e diff --git a/flashloaders/stm32l0x.s b/flashloaders/stm32l0x.s index 1ce7dd144..893aa6f9b 100644 --- a/flashloaders/stm32l0x.s +++ b/flashloaders/stm32l0x.s @@ -8,11 +8,13 @@ myloop: ldr r3, [r0] str r3, [r1] - add r0, r0, #4 - add r1, r1, #4 + ldr r7, =4 + add r0, r0, r7 + add r1, r1, r7 # loop if r2 != 0 - sub r2, r2, #1 + ldr r7, =1 + subs r2, r2, r7 cmp r2, #0 bne myloop diff --git a/flashloaders/stm32l4.s b/flashloaders/stm32l4.s index 0a68b687a..b136e59e7 100644 --- a/flashloaders/stm32l4.s +++ b/flashloaders/stm32l4.s @@ -1,6 +1,12 @@ .syntax unified .text +flash_base: + .align 2 + .word 0x40022000 +flash_off_bsy: + .word 0x12 + .global mycopy mycopy: ldr r12, flash_base @@ -10,9 +16,9 @@ mycopy: myloop: # copy 8 bytes ldr r3, [r0] - ldr r3, [r0, #4] + ldr r4, [r0, #4] str r3, [r1] - str r3, [r1, #4] + str r4, [r1, #4] add r0, r0, #8 add r1, r1, #8 @@ -30,8 +36,3 @@ mywait: myexit: bkpt - -flash_base: - .word 0x40022000 -flash_off_bsy: - .word 0x12 diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index 1ce7dd144..893aa6f9b 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -8,11 +8,13 @@ myloop: ldr r3, [r0] str r3, [r1] - add r0, r0, #4 - add r1, r1, #4 + ldr r7, =4 + add r0, r0, r7 + add r1, r1, r7 # loop if r2 != 0 - sub r2, r2, #1 + ldr r7, =1 + subs r2, r2, r7 cmp r2, #0 bne myloop From 8aaf95abf6dedef3f5de1f6659aecfb0e7eb60eb Mon Sep 17 00:00:00 2001 From: xp Date: Fri, 24 Apr 2020 16:59:47 +0800 Subject: [PATCH 0888/1435] rewrite flashloaders as clean room doc --- flashloaders/stm32f0.s | 95 ++++++++++++++++++++++++++-------------- flashloaders/stm32f4.s | 54 ++++++++++++----------- flashloaders/stm32f4lv.s | 55 ++++++++++++----------- flashloaders/stm32f7.s | 66 +++++++++++++++------------- flashloaders/stm32f7lv.s | 67 +++++++++++++++------------- flashloaders/stm32l0x.s | 76 +++++++------------------------- flashloaders/stm32l4.s | 61 +++++++++++++------------- flashloaders/stm32lx.s | 72 +++++++----------------------- 8 files changed, 257 insertions(+), 289 deletions(-) diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index fe12f90f3..8eaf81905 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -1,32 +1,63 @@ -/* Adopted from STM AN4065 stm32f0xx_flash.c:FLASH_ProgramWord */ - -write: - ldr r4, STM32_FLASH_BASE - mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ - mov r6, #4 /* PGERR */ -write_half_word: - ldr r3, [r4, #16] /* FLASH->CR */ - orr r3, r5 - str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ - ldrh r3, [r0] /* r3 = *sram */ - strh r3, [r1] /* *flash = r3 */ -busy: - ldr r3, [r4, #12] /* FLASH->SR */ - tst r3, r5 /* FLASH_SR_BUSY */ - beq busy - - tst r3, r6 /* PGERR */ - bne exit - - add r0, r0, #2 /* sram += 2 */ - add r1, r1, #2 /* flash += 2 */ - sub r2, r2, #0x01 /* count-- */ - cmp r2, #0 - bne write_half_word -exit: - ldr r3, [r4, #16] /* FLASH->CR */ - bic r3, r5 - str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ - bkpt #0x00 - -STM32_FLASH_BASE: .word 0x40022000 + .syntax unified + .text + + .global mycopy +mycopy: + ldr r7, =flash_base + ldr r4, [r7] + ldr r7, =flash_off_cr + ldr r6, [r7] + adds r6, r6, r4 + ldr r7, =flash_off_sr + ldr r5, [r7] + adds r5, r5, r4 + +myloop: + # FLASH_CR ^= 1 + ldr r7, =0x1 + ldr r3, [r6] + orrs r3, r3, r7 + str r3, [r6] + + # copy 2 bytes + ldrh r3, [r0] + strh r3, [r1] + + ldr r7, =2 + adds r0, r0, r7 + adds r1, r1, r7 + + # wait if FLASH_SR == 1 +mywait: + ldr r7, =0x1 + ldr r3, [r5] + tst r3, r7 + beq mywait + + # exit if FLASH_SR == 4 + ldr r7, =0x4 + tst r3, r7 + beq myexit + + # loop if r2 != 0 + ldr r7, =0x1 + subs r2, r2, r7 + cmp r2, #0 + bne myloop + +myexit: + # FLASH_CR &= ~1 + ldr r7, =0x1 + ldr r3, [r6] + bics r3, r3, r7 + str r3, [r6] + + bkpt + +flash_base: + .align 2 + .word 0x40022000 +flash_off_cr: + .word 0x10 +flash_off_sr: + .word 0x0c diff --git a/flashloaders/stm32f4.s b/flashloaders/stm32f4.s index 21f5a8f7f..085e6870c 100644 --- a/flashloaders/stm32f4.s +++ b/flashloaders/stm32f4.s @@ -1,32 +1,36 @@ -.global start -.syntax unified + .syntax unified + .text -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp + .global mycopy +mycopy: + ldr r12, flash_base + ldr r10, flash_off_sr + add r10, r10, r12 -start: - ldr r3, flash_base -next: - cbz r2, done - ldr r4, [r0] - str r4, [r1] +myloop: + # copy 4 bytes + ldr r3, [r0] + str r3, [r1] -wait: - ldrh r4, [r3, #0x0e] - tst.w r4, #1 - bne wait + add r0, r0, #4 + add r1, r1, #4 - add r0, #4 - add r1, #4 - sub r2, #1 - b next -done: - bkpt + # wait if FLASH_SR == 1 +mywait: + ldrh r3, [r10] + tst r3, #0x1 + beq mywait + + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne myloop -.align 2 +myexit: + bkpt flash_base: - .word 0x40023c00 + .align 2 + .word 0x40023c00 +flash_off_sr: + .word 0x0e diff --git a/flashloaders/stm32f4lv.s b/flashloaders/stm32f4lv.s index f60ee8797..f0adfd208 100644 --- a/flashloaders/stm32f4lv.s +++ b/flashloaders/stm32f4lv.s @@ -1,33 +1,36 @@ -.global start -.syntax unified + .syntax unified + .text -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp + .global mycopy +mycopy: + ldr r12, flash_base + ldr r10, flash_off_sr + add r10, r10, r12 -start: - lsls r2, r2, #2 - ldr r3, flash_base -next: - cbz r2, done - ldrb r4, [r0] - strb r4, [r1] +myloop: + # copy 1 bytes + ldrb r3, [r0] + strb r3, [r1] -wait: - ldrh r4, [r3, #0x0e] - tst.w r4, #1 - bne wait + add r0, r0, #1 + add r1, r1, #1 - add r0, #1 - add r1, #1 - sub r2, #1 - b next -done: - bkpt + # wait if FLASH_SR == 1 +mywait: + ldrh r3, [r10] + tst r3, #0x1 + beq mywait + + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne myloop -.align 2 +myexit: + bkpt flash_base: - .word 0x40023c00 + .align 2 + .word 0x40023c00 +flash_off_sr: + .word 0x0e diff --git a/flashloaders/stm32f7.s b/flashloaders/stm32f7.s index 0334c80a0..5d87515be 100644 --- a/flashloaders/stm32f7.s +++ b/flashloaders/stm32f7.s @@ -1,33 +1,39 @@ -.global start -.syntax unified - -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp - -start: - ldr r3, flash_base -next: - cbz r2, done - ldr r4, [r0] - str r4, [r1] - dsb sy - -wait: - ldrh r4, [r3, #0x0e] - tst.w r4, #1 - bne wait - - add r0, #4 - add r1, #4 - sub r2, #1 - b next -done: - bkpt + .syntax unified + .text + + .global mycopy +mycopy: + ldr r12, flash_base + ldr r10, flash_off_sr + add r10, r10, r12 + +myloop: + # copy 4 bytes + ldr r3, [r0] + str r3, [r1] + + add r0, r0, #4 + add r1, r1, #4 -.align 2 + # memory barrier + dsb sy + + # wait if FLASH_SR == 1 +mywait: + ldrh r3, [r10] + tst r3, #0x1 + beq mywait + + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne myloop + +myexit: + bkpt flash_base: - .word 0x40023c00 + .align 2 + .word 0x40023c00 +flash_off_sr: + .word 0x0e diff --git a/flashloaders/stm32f7lv.s b/flashloaders/stm32f7lv.s index 650922719..70cd948bd 100644 --- a/flashloaders/stm32f7lv.s +++ b/flashloaders/stm32f7lv.s @@ -1,34 +1,39 @@ -.global start -.syntax unified - -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp - -start: - lsls r2, r2, #2 - ldr r3, flash_base -next: - cbz r2, done - ldrb r4, [r0] - strb r4, [r1] - dsb sy - -wait: - ldrh r4, [r3, #0x0e] - tst.w r4, #1 - bne wait - - add r0, #1 - add r1, #1 - sub r2, #1 - b next -done: - bkpt + .syntax unified + .text + + .global mycopy +mycopy: + ldr r12, flash_base + ldr r10, flash_off_sr + add r10, r10, r12 + +myloop: + # copy 1 byte + ldrb r3, [r0] + strb r3, [r1] + + add r0, r0, #1 + add r1, r1, #1 -.align 2 + # memory barrier + dsb sy + + # wait if FLASH_SR == 1 +mywait: + ldrh r3, [r10] + tst r3, #0x1 + beq mywait + + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne myloop + +myexit: + bkpt flash_base: - .word 0x40023c00 + .algin 2 + .word 0x40023c00 +flash_off_sr: + .word 0x0e diff --git a/flashloaders/stm32l0x.s b/flashloaders/stm32l0x.s index fcbd06e39..893aa6f9b 100644 --- a/flashloaders/stm32l0x.s +++ b/flashloaders/stm32l0x.s @@ -1,64 +1,22 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2011 Clement Burin des Roziers * - * clement.burin-des-roziers@hikob.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - - -// Build : arm-eabi-gcc -c stm32lx.S - .text .syntax unified - .cpu cortex-m0plus - .thumb - .thumb_func - .global write - -/* - r0 - source address - r1 - destination address - r2 - count -*/ + .text - // Go to compare - b test_done + .global mycopy +mycopy: +myloop: + # copy 4 bytes + ldr r3, [r0] + str r3, [r1] -write_word: - // Load one word from address in r0, increment by 4 - ldr r4, [r0] - // Store the word to address in r1, increment by 4 - str r4, [r1] - // Decrement r2 - subs r2, #1 - adds r1, #4 - // does not matter, only first addr is important - // next 15 bytes are in sequnce RM0367 page 66 - adds r0, #4 + ldr r7, =4 + add r0, r0, r7 + add r1, r1, r7 -test_done: - // Test r2 - cmp r2, #0 - // Loop if not zero - bcc.n write_word + # loop if r2 != 0 + ldr r7, =1 + subs r2, r2, r7 + cmp r2, #0 + bne myloop - // Set breakpoint to exit - bkpt #0x00 +myexit: + bkpt diff --git a/flashloaders/stm32l4.s b/flashloaders/stm32l4.s index 6aa2be050..5b5252a54 100644 --- a/flashloaders/stm32l4.s +++ b/flashloaders/stm32l4.s @@ -1,39 +1,38 @@ -.global start -.syntax unified + .syntax unified + .text -@ Adapted from stm32f4.s -@ STM32L4's flash controller expects double-word writes, has the flash -@ controller mapped in a different location with the registers we care about -@ moved down from the base address, and has BSY moved to bit 16 of SR. -@ r0 = source -@ r1 = target -@ r2 = wordcount -@ r3 = flash_base -@ r4 = temp -@ r5 = temp + .global mycopy +mycopy: + ldr r12, flash_base + ldr r10, flash_off_bsy + add r10, r10, r12 -start: - ldr r3, flash_base -next: - cbz r2, done - ldr r4, [r0] /* copy doubleword from source to target */ - ldr r5, [r0, #4] - str r4, [r1] - str r5, [r1, #4] +myloop: + # copy 8 bytes + ldr r3, [r0] + ldr r4, [r0, #4] + str r3, [r1] + str r4, [r1, #4] -wait: - ldrh r4, [r3, #0x12] /* high half of status register */ - tst r4, #1 /* BSY = bit 16 */ - bne wait + add r0, r0, #8 + add r1, r1, #8 - add r0, #8 - add r1, #8 - sub r2, #1 - b next -done: - bkpt + # wait if FLASH_BSY[0b] == 1 +mywait: + ldrh r3, [r10] + tst r3, #0x1 + beq mywait + + # loop if r2 != 0 + sub r2, r2, #1 + cmp r2, #0 + bne myloop -.align 2 +myexit: + bkpt flash_base: + .align 2 .word 0x40022000 +flash_off_bsy: + .word 0x12 diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index 10e5644bf..893aa6f9b 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -1,60 +1,22 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2011 Clement Burin des Roziers * - * clement.burin-des-roziers@hikob.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - - -// Build : arm-eabi-gcc -c stm32lx.s - .text .syntax unified - .cpu cortex-m3 - .thumb - .thumb_func - .global write - -/* - r0 - source address - r1 - destination address - r2 - output, remaining word count -*/ + .text - // Go to compare - b test_done + .global mycopy +mycopy: +myloop: + # copy 4 bytes + ldr r3, [r0] + str r3, [r1] -write_word: - // Load one word from address in r0, increment by 4 - ldr.w ip, [r0], #4 - // Store the word to address in r1, increment by 4 - str.w ip, [r1], #4 - // Decrement r2 - subs r2, #1 + ldr r7, =4 + add r0, r0, r7 + add r1, r1, r7 -test_done: - // Test r2 - cmp r2, #0 - // Loop if not zero - bhi write_word + # loop if r2 != 0 + ldr r7, =1 + subs r2, r2, r7 + cmp r2, #0 + bne myloop - // Set breakpoint to exit - bkpt #0x00 +myexit: + bkpt From 8bbedab02055519312445b9d95bff1b52becc172 Mon Sep 17 00:00:00 2001 From: xp Date: Fri, 24 Apr 2020 17:21:32 +0800 Subject: [PATCH 0889/1435] fix typo --- flashloaders/stm32f7lv.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flashloaders/stm32f7lv.s b/flashloaders/stm32f7lv.s index 70cd948bd..c144205f2 100644 --- a/flashloaders/stm32f7lv.s +++ b/flashloaders/stm32f7lv.s @@ -33,7 +33,7 @@ myexit: bkpt flash_base: - .algin 2 + .align 2 .word 0x40023c00 flash_off_sr: .word 0x0e From 5a1efc01f705e60bbec4a328b169e528106bb8f7 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 24 Apr 2020 15:01:28 +0200 Subject: [PATCH 0890/1435] Updated cmake settings - Distinguish test binaries from binaries - Build all binaries to /bin subfolder - Added comments to explain settings - Moved header files for logging and mmap --- CMakeLists.txt | 35 +++++++++++++------------------ Makefile | 1 + include/stlink.h | 2 +- include/stlink/usb.h | 2 +- src/common.c | 24 ++++++++++----------- src/gdbserver/gdb-server.c | 2 +- src/gdbserver/semihosting.c | 4 ++-- src/logging.c | 2 +- {include/stlink => src}/logging.h | 0 src/mmap.c | 2 +- {include/stlink => src}/mmap.h | 0 src/sg.c | 2 +- tests/CMakeLists.txt | 18 ++++++++-------- 13 files changed, 45 insertions(+), 49 deletions(-) rename {include/stlink => src}/logging.h (100%) rename {include/stlink => src}/mmap.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ec381239..8e6501dc9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ cmake_policy(SET CMP0042 NEW) set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) ### @@ -25,10 +26,10 @@ option(STLINK_INSTALL_UDEV_RULES "Install udev rules files" ON) option(STLINK_INSTALL_MODPROBE_CONF "Install modprobe conf files" ON) option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) -# Determine project version +## Determine project version include(${CMAKE_MODULE_PATH}/get_version.cmake) -# Set C build flags +## Set C build flags if (NOT MSVC) include(${CMAKE_MODULE_PATH}/c_flags.cmake) else () @@ -39,11 +40,7 @@ else () set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") endif () - -# ==== - -#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) - +## Set installation directories for libraries if (IS_DIRECTORY ${LIB_INSTALL_DIR}) set(LIB_INSTALL_DIR ${LIB_INSTALL_DIR} CACHE PATH "Main library directory") set(STLINK_LIBRARY_PATH "${LIB_INSTALL_DIR}") @@ -52,6 +49,7 @@ else () set(STLINK_LIBRARY_PATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}") endif () +## Set installation directories for header files if (IS_DIRECTORY ${INCLUDE_INSTALL_DIR}) set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_DIR} CACHE PATH "Main include directory") set(STLINK_INCLUDE_PATH "${INCLUDE_INSTALL_DIR}") @@ -67,12 +65,14 @@ endif () find_package(libusb REQUIRED) +## Package configuration (pkg-config) on unix-based systems if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) add_subdirectory(cmake/pkgconfig) find_package(PkgConfig) pkg_check_modules(GTK3 gtk+-3.0) endif () +## Check for system-specific additional header files and libraries include(CheckIncludeFile) CHECK_INCLUDE_FILE(sys/mman.h STLINK_HAVE_SYS_MMAN_H) @@ -94,20 +94,13 @@ else () set(SSP_LIB "") endif () -if (CMAKE_BUILD_TYPE STREQUAL "") - set(CMAKE_BUILD_TYPE "Debug") -endif () -if (${CMAKE_BUILD_TYPE} MATCHES "Debug") - include(CTest) -endif () +# ==== set(STLINK_HEADERS include/stlink.h include/stlink/usb.h include/stlink/sg.h - include/stlink/logging.h - include/stlink/mmap.h include/stlink/chipid.h include/stlink/flash_loader.h ) @@ -115,11 +108,11 @@ set(STLINK_HEADERS set(STLINK_SOURCE src/chipid.c src/common.c - src/usb.c - src/sg.c - src/logging.c src/flash_loader.c + src/logging.c src/md5.c + src/sg.c + src/usb.c ) if (WIN32 OR MINGW OR MSYS) @@ -139,6 +132,10 @@ if (MSVC) add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) endif () +# Include test execution for test-targets for target Debug +if (${CMAKE_BUILD_TYPE} MATCHES "Debug") + include(CTest) +endif () ### # Shared library @@ -236,8 +233,6 @@ else () target_link_libraries(st-info ${STLINK_LIB_SHARED} ${SSP_LIB}) endif () -install(TARGETS st-flash st-info RUNTIME DESTINATION bin) ### TODO: Check path - if (CMAKE_SYSTEM_NAME STREQUAL "Linux") if (STLINK_INSTALL_MODPROBE_CONF) install(FILES etc/modprobe.d/stlink_v1.conf DESTINATION ${STLINK_MODPROBED_DIR}/) diff --git a/Makefile b/Makefile index 444f1920b..57043ac97 100644 --- a/Makefile +++ b/Makefile @@ -40,6 +40,7 @@ package: build/Release @$(MAKE) -C build/Release package test: debug + @echo "[TEST]" @$(MAKE) -C build/Debug test build/Debug: diff --git a/include/stlink.h b/include/stlink.h index db737acb0..c311a527b 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -252,7 +252,7 @@ typedef struct flash_loader { #include "stlink/chipid.h" #include "stlink/flash_loader.h" #include "stlink/version.h" -#include "stlink/logging.h" +#include "../src/logging.h" #ifdef __cplusplus } diff --git a/include/stlink/usb.h b/include/stlink/usb.h index 1448481be..88a9a981a 100644 --- a/include/stlink/usb.h +++ b/include/stlink/usb.h @@ -12,7 +12,7 @@ #include "stlink.h" #include "stlinkusb.h" -#include "stlink/logging.h" +#include "../src/logging.h" #ifdef __cplusplus extern "C" { diff --git a/src/common.c b/src/common.c index 0dc6bc967..9dff4e768 100644 --- a/src/common.c +++ b/src/common.c @@ -13,8 +13,8 @@ #include #include "stlink.h" -#include "stlink/mmap.h" -#include "stlink/logging.h" +#include "mmap.h" +#include "logging.h" #include "md5.h" #ifndef O_BINARY @@ -2672,12 +2672,12 @@ int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr } else { num_empty = 0; } - /* + /* * TODO: investigate: - * a kind of weird behaviour here: + * a kind of weird behaviour here: * if the file is identified to be all-empty and four-bytes aligned, - * still flash the whole file even if ignoring message is printed - */ + * still flash the whole file even if ignoring message is printed + */ err = stlink_write_flash(sl, addr, data, (num_empty == length) ? (uint32_t) length : (uint32_t) length - num_empty, num_empty == length); stlink_fwrite_finalize(sl, addr); return err; @@ -2721,12 +2721,12 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { } else { num_empty = 0; } - /* + /* * TODO: investigate: - * a kind of weird behaviour here: + * a kind of weird behaviour here: * if the file is identified to be all-empty and four-bytes aligned, - * still flash the whole file even if ignoring message is printed - */ + * still flash the whole file even if ignoring message is printed + */ err = stlink_write_flash(sl, addr, mf.base, (num_empty == mf.len) ? (uint32_t) mf.len : (uint32_t) mf.len - num_empty, num_empty == mf.len); stlink_fwrite_finalize(sl, addr); unmap_file(&mf); @@ -3258,9 +3258,9 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) } /** - * Write option bytes + * Write option bytes * @param sl - * @param option_byte value to write + * @param option_byte value to write * @return 0 on success, -ve on failure. */ int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) diff --git a/src/gdbserver/gdb-server.c b/src/gdbserver/gdb-server.c index 2b5b1d3cb..219c3424b 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/gdbserver/gdb-server.c @@ -24,7 +24,7 @@ #endif #include -#include +#include "../logging.h" #include "gdb-remote.h" #include "gdb-server.h" diff --git a/src/gdbserver/semihosting.c b/src/gdbserver/semihosting.c index 40758b61d..d41a83246 100644 --- a/src/gdbserver/semihosting.c +++ b/src/gdbserver/semihosting.c @@ -8,7 +8,7 @@ #include "semihosting.h" #include -#include +#include "../logging.h" static int mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) { @@ -100,7 +100,7 @@ static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) // the requested bytes. (perhaps reading the whole area is faster??). // // If 16 and 8 bit writes are available, then they could be used instead. - + // Just return when the length is zero avoiding unneeded work. if (len == 0) return 0; diff --git a/src/logging.c b/src/logging.c index 59c2ea298..4ad89a5ed 100644 --- a/src/logging.c +++ b/src/logging.c @@ -9,7 +9,7 @@ #include #include -#include "stlink/logging.h" +#include "logging.h" static int max_level = UINFO; diff --git a/include/stlink/logging.h b/src/logging.h similarity index 100% rename from include/stlink/logging.h rename to src/logging.h diff --git a/src/mmap.c b/src/mmap.c index 90ae5fc17..b76e4ad64 100644 --- a/src/mmap.c +++ b/src/mmap.c @@ -3,7 +3,7 @@ #include #include -#include "stlink/mmap.h" +#include "mmap.h" void *mmap (void *addr, size_t len, int prot, int flags, int fd, long long offset) { diff --git a/include/stlink/mmap.h b/src/mmap.h similarity index 100% rename from include/stlink/mmap.h rename to src/mmap.h diff --git a/src/sg.c b/src/sg.c index 031cc64e5..eee6be498 100644 --- a/src/sg.c +++ b/src/sg.c @@ -83,7 +83,7 @@ #include #include "stlink.h" -#include "stlink/logging.h" +#include "logging.h" #define STLINK_OK 0x80 #define STLINK_FALSE 0x81 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c6b04ddb3..d6fe9fdd5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,12 +1,12 @@ -set(TESTS usb sg) +set(TESTEXEC usb sg) -foreach (test ${TESTS}) - add_executable(${test} ${test}.c) - add_dependencies(${test} ${STLINK_LIB_STATIC}) - target_link_libraries(${test} ${STLINK_LIB_STATIC} ${SSP_LIB}) - add_test(${test} ${CMAKE_CURRENT_BINARY_DIR}/${test}) +foreach (test ${TESTEXEC}) + add_executable(test-${test} ${test}.c) + add_dependencies(test-${test} ${STLINK_LIB_STATIC}) + target_link_libraries(test-${test} ${STLINK_LIB_STATIC} ${SSP_LIB}) + add_test(test-${test} ${CMAKE_BINARY_DIR}/bin/test-${test}) endforeach () -add_executable(flash flash.c "${CMAKE_SOURCE_DIR}/src/tools/flash_opts.c") -target_link_libraries(flash ${STLINK_LIB_STATIC} ${SSP_LIB}) -add_test(flash ${CMAKE_CURRENT_BINARY_DIR}/flash) +add_executable(test-flash flash.c "${CMAKE_SOURCE_DIR}/src/tools/flash_opts.c") +target_link_libraries(test-flash ${STLINK_LIB_STATIC} ${SSP_LIB}) +add_test(test-flash ${CMAKE_BINARY_DIR}/bin/test-flash) From 15e2e1d811a384421aa78bcf5f9a28e91214a770 Mon Sep 17 00:00:00 2001 From: xp Date: Sat, 25 Apr 2020 14:08:58 +0800 Subject: [PATCH 0891/1435] fix align --- flashloaders/stm32f0.s | 2 +- flashloaders/stm32f4.s | 2 +- flashloaders/stm32f4lv.s | 2 +- flashloaders/stm32f7.s | 2 +- flashloaders/stm32f7lv.s | 2 +- flashloaders/stm32l4.s | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index 8eaf81905..489e30672 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -54,8 +54,8 @@ myexit: bkpt -flash_base: .align 2 +flash_base: .word 0x40022000 flash_off_cr: .word 0x10 diff --git a/flashloaders/stm32f4.s b/flashloaders/stm32f4.s index 085e6870c..836f6e1f2 100644 --- a/flashloaders/stm32f4.s +++ b/flashloaders/stm32f4.s @@ -29,8 +29,8 @@ mywait: myexit: bkpt -flash_base: .align 2 +flash_base: .word 0x40023c00 flash_off_sr: .word 0x0e diff --git a/flashloaders/stm32f4lv.s b/flashloaders/stm32f4lv.s index f0adfd208..ef9f3a0bb 100644 --- a/flashloaders/stm32f4lv.s +++ b/flashloaders/stm32f4lv.s @@ -29,8 +29,8 @@ mywait: myexit: bkpt -flash_base: .align 2 +flash_base: .word 0x40023c00 flash_off_sr: .word 0x0e diff --git a/flashloaders/stm32f7.s b/flashloaders/stm32f7.s index 5d87515be..3f02e75f8 100644 --- a/flashloaders/stm32f7.s +++ b/flashloaders/stm32f7.s @@ -32,8 +32,8 @@ mywait: myexit: bkpt -flash_base: .align 2 +flash_base: .word 0x40023c00 flash_off_sr: .word 0x0e diff --git a/flashloaders/stm32f7lv.s b/flashloaders/stm32f7lv.s index c144205f2..99eb37d88 100644 --- a/flashloaders/stm32f7lv.s +++ b/flashloaders/stm32f7lv.s @@ -32,8 +32,8 @@ mywait: myexit: bkpt -flash_base: .align 2 +flash_base: .word 0x40023c00 flash_off_sr: .word 0x0e diff --git a/flashloaders/stm32l4.s b/flashloaders/stm32l4.s index 5b5252a54..16c6d1063 100644 --- a/flashloaders/stm32l4.s +++ b/flashloaders/stm32l4.s @@ -31,8 +31,8 @@ mywait: myexit: bkpt -flash_base: .align 2 +flash_base: .word 0x40022000 flash_off_bsy: .word 0x12 From 36bb77dd6f9aa3f4c2cb99845c827c75810047c6 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Sat, 25 Apr 2020 15:25:27 +0800 Subject: [PATCH 0892/1435] Cleanroom for flashloaders done --- flashloaders/Makefile | 38 ++++++ flashloaders/linker.ld | 9 ++ src/flash_loader.c | 273 +++++++++++++++++++---------------------- 3 files changed, 175 insertions(+), 145 deletions(-) create mode 100644 flashloaders/Makefile create mode 100644 flashloaders/linker.ld diff --git a/flashloaders/Makefile b/flashloaders/Makefile new file mode 100644 index 000000000..7b17cb2a0 --- /dev/null +++ b/flashloaders/Makefile @@ -0,0 +1,38 @@ +# Note that according to the original GPLed code, compiling is noted to be +# as simple as gcc -c, this fails with my tests where this will lead to a wrong +# address read by the program. +# This makefile will save your time from dealing with compile errors +# Adjust CC if needed + +CC = /opt/local/gcc-arm-none-eabi-8-2018-q4-major/bin/arm-none-eabi-gcc + +CFLAGS_thumb1 = -mcpu=Cortex-M0 -Tlinker.ld -ffreestanding -nostdlib +CFLAGS_thumb2 = -mcpu=Cortex-M3 -Tlinker.ld -ffreestanding -nostdlib + +all: stm32vl.o stm32f0.o stm32l.o stm32f4.o stm32f4_lv.o stm32l4.o stm32f7.o stm32f7_lv.o + +stm32vl.o: stm32f0.s + $(CC) stm32f0.s $(CFLAGS_thumb2) -o stm32vl.o +stm32f0.o: stm32f0.s + $(CC) stm32f0.s $(CFLAGS_thumb1) -o stm32f0.o +stm32l.o: stm32lx.s + $(CC) stm32lx.s $(CFLAGS_thumb2) -o stm32l.o +stm32f4.o: stm32f4.s + $(CC) stm32f4.s $(CFLAGS_thumb2) -o stm32f4.o +stm32f4_lv.o: stm32f4lv.s + $(CC) stm32f4lv.s $(CFLAGS_thumb2) -o stm32f4_lv.o +stm32l4.o: stm32l4.s + $(CC) stm32l4.s $(CFLAGS_thumb2) -o stm32l4.o +stm32f7.o: stm32f7.s + $(CC) stm32f7.s $(CFLAGS_thumb2) -o stm32f7.o +stm32f7_lv.o: stm32f7lv.s + $(CC) stm32f7lv.s $(CFLAGS_thumb2) -o stm32f7_lv.o + +clean: + rm *.o + + + + + + diff --git a/flashloaders/linker.ld b/flashloaders/linker.ld new file mode 100644 index 000000000..5bc738966 --- /dev/null +++ b/flashloaders/linker.ld @@ -0,0 +1,9 @@ +/*. Entry Point *./ +ENTRY( mycopy ) + + +/*. Specify the memory areas .*/ +MEMORY +{ + RAM ( xrw) : ORIGIN = 0x20000000 , LENGTH = 64K +} \ No newline at end of file diff --git a/src/flash_loader.c b/src/flash_loader.c index a1c9c3757..cee2aaba1 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -7,26 +7,34 @@ #define FLASH_REGS_BANK2_OFS 0x40 #define FLASH_BANK2_START_ADDR 0x08080000 -/* from openocd, contrib/loaders/flash/stm32.s */ -static const uint8_t loader_code_stm32vl[] = { - 0x08, 0x4c, /* ldr r4, STM32_FLASH_BASE */ - 0x1c, 0x44, /* add r4, r3 */ - /* write_half_word: */ - 0x01, 0x23, /* movs r3, #0x01 */ - 0x23, 0x61, /* str r3, [r4, #STM32_FLASH_CR_OFFSET] */ - 0x30, 0xf8, 0x02, 0x3b, /* ldrh r3, [r0], #0x02 */ - 0x21, 0xf8, 0x02, 0x3b, /* strh r3, [r1], #0x02 */ - /* busy: */ - 0xe3, 0x68, /* ldr r3, [r4, #STM32_FLASH_SR_OFFSET] */ - 0x13, 0xf0, 0x01, 0x0f, /* tst r3, #0x01 */ - 0xfb, 0xd0, /* beq busy */ - 0x13, 0xf0, 0x14, 0x0f, /* tst r3, #0x14 */ - 0x01, 0xd1, /* bne exit */ - 0x01, 0x3a, /* subs r2, r2, #0x01 */ - 0xf0, 0xd1, /* bne write_half_word */ - /* exit: */ - 0x00, 0xbe, /* bkpt #0x00 */ - 0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */ + /* flashloaders/stm32f0.s -- compiled with thumb2 */ + static const uint8_t loader_code_stm32vl[] = { + 0x16, 0x4f, 0x3c, 0x68, + 0x16, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x16, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x4f, 0xf0, 0x01, 0x07, + 0x33, 0x68, 0x3b, 0x43, + 0x33, 0x60, 0x03, 0x88, + 0x0b, 0x80, 0x4f, 0xf0, + 0x02, 0x07, 0xc0, 0x19, + 0xc9, 0x19, 0x4f, 0xf0, + 0x01, 0x07, 0x2b, 0x68, + 0x3b, 0x42, 0xfa, 0xd0, + 0x4f, 0xf0, 0x04, 0x07, + 0x3b, 0x42, 0x04, 0xd0, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xe6, 0xd1, 0x4f, 0xf0, + 0x01, 0x07, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x20, + 0x54, 0x00, 0x00, 0x20, + 0x58, 0x00, 0x00, 0x20 }; /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ @@ -47,157 +55,132 @@ static const uint8_t loader_code_stm32vl[] = { 0x00, 0x30, // nop /* add r0,#0 */ 0x00, 0x30, // nop /* add r0,#0 */ #endif - 0x0A, 0x4C, // ldr r4, STM32_FLASH_BASE - 0x01, 0x25, // mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ - 0x04, 0x26, // mov r6, #4 /* PGERR */ - // write_half_word: - 0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */ - 0x2B, 0x43, // orr r3, r5 - 0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ - 0x03, 0x88, // ldrh r3, [r0] /* r3 = *sram */ - 0x0B, 0x80, // strh r3, [r1] /* *flash = r3 */ - // busy: - 0xE3, 0x68, // ldr r3, [r4, #12] /* FLASH->SR */ - 0x2B, 0x42, // tst r3, r5 /* FLASH_SR_BUSY */ - 0xFC, 0xD0, // beq busy - - 0x33, 0x42, // tst r3, r6 /* PGERR */ - 0x04, 0xD1, // bne exit - - 0x02, 0x30, // add r0, r0, #2 /* sram += 2 */ - 0x02, 0x31, // add r1, r1, #2 /* flash += 2 */ - 0x01, 0x3A, // sub r2, r2, #0x01 /* count-- */ - 0x00, 0x2A, // cmp r2, #0 - 0xF0, 0xD1, // bne write_half_word - // exit: - 0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */ - 0xAB, 0x43, // bic r3, r5 - 0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ - 0x00, 0xBE, // bkpt #0x00 - 0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */ + 0x13, 0x4f, 0x3c, 0x68, + 0x13, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x13, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x12, 0x4f, 0x33, 0x68, + 0x3b, 0x43, 0x33, 0x60, + 0x03, 0x88, 0x0b, 0x80, + 0x10, 0x4f, 0xc0, 0x19, + 0xc9, 0x19, 0x0e, 0x4f, + 0x2b, 0x68, 0x3b, 0x42, + 0xfb, 0xd0, 0x0e, 0x4f, + 0x3b, 0x42, 0x03, 0xd0, + 0x0a, 0x4f, 0xd2, 0x1b, + 0x00, 0x2a, 0xeb, 0xd1, + 0x08, 0x4f, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0xc0, 0x46, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x20, + 0x48, 0x00, 0x00, 0x20, + 0x4c, 0x00, 0x00, 0x20, + 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32l[] = { // flashloaders/stm32lx.s - 0x04, 0xe0, // b test_done ; Go to compare - // write_word: - 0x04, 0x68, // ldr r4, [r0] ; Load one word from address in r0 - 0x0c, 0x60, // str r4, [r1] ; Store the word to address in r1 - 0x04, 0x30, // adds r0, #4 ; Increment r0 - 0x04, 0x31, // adds r1, #4 ; Increment r1 - 0x01, 0x3a, // subs r2, #1 ; Decrement r2 - // test_done: - 0x00, 0x2a, // cmp r2, #0 ; Compare r2 to 0 - 0xf8, 0xd8, // bhi write_word ; Loop if above 0 - 0x00, 0xbe, // bkpt #0x00 ; Set breakpoint to exit - 0x00, 0x00 + 0x03, 0x68, 0x0b, 0x60, + 0x4f, 0xf0, 0x04, 0x07, + 0x38, 0x44, 0x39, 0x44, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xf4, 0xd1, 0x00, 0xbe, }; static const uint8_t loader_code_stm32f4[] = { // flashloaders/stm32f4.s - 0x07, 0x4b, - - 0x62, 0xb1, - 0x04, 0x68, - 0x0c, 0x60, - - 0xdc, 0x89, - 0x14, 0xf0, 0x01, 0x0f, - 0xfb, 0xd1, - 0x00, 0xf1, 0x04, 0x00, - 0x01, 0xf1, 0x04, 0x01, - 0xa2, 0xf1, 0x01, 0x02, - 0xf1, 0xe7, - - 0x00, 0xbe, - - 0x00, 0x3c, 0x02, 0x40, + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32f4_lv[] = { // flashloaders/stm32f4lv.s - 0x92, 0x00, - - 0x08, 0x4b, - 0x62, 0xb1, - 0x04, 0x78, - 0x0c, 0x70, - - 0xdc, 0x89, - 0x14, 0xf0, 0x01, 0x0f, - 0xfb, 0xd1, - 0x00, 0xf1, 0x01, 0x00, - 0x01, 0xf1, 0x01, 0x01, - 0xa2, 0xf1, 0x01, 0x02, - 0xf1, 0xe7, - - 0x00, 0xbe, - 0x00, 0xbf, - - 0x00, 0x3c, 0x02, 0x40, + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32l4[] = { // flashloaders/stm32l4.s - 0x08, 0x4b, // start: ldr r3, [pc, #32] ; - 0x72, 0xb1, // next: cbz r2, - 0x04, 0x68, // ldr r4, [r0, #0] - 0x45, 0x68, // ldr r5, [r0, #4] - 0x0c, 0x60, // str r4, [r1, #0] - 0x4d, 0x60, // str r5, [r1, #4] - 0x5c, 0x8a, // wait: ldrh r4, [r3, #18] - 0x14, 0xf0, 0x01, 0x0f, // tst.w r4, #1 - 0xfb, 0xd1, // bne.n - 0x00, 0xf1, 0x08, 0x00, // add.w r0, r0, #8 - 0x01, 0xf1, 0x08, 0x01, // add.w r1, r1, #8 - 0xa2, 0xf1, 0x01, 0x02, // sub.w r2, r2, #1 - 0xef, 0xe7, // b.n - 0x00, 0xbe, // done: bkpt 0x0000 - 0x00, 0x20, 0x02, 0x40 // flash_base: .word 0x40022000 + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x44, 0x68, 0x0b, 0x60, + 0x4c, 0x60, 0x00, 0xf1, + 0x08, 0x00, 0x01, 0xf1, + 0x08, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x12, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32f7[] = { // flashloaders/stm32f7.s - 0x08, 0x4b, - 0x72, 0xb1, - 0x04, 0x68, - 0x0c, 0x60, - 0xbf, 0xf3, 0x4f, 0x8f, // DSB Memory barrier for in order flash write - 0xdc, 0x89, - 0x14, 0xf0, 0x01, 0x0f, - 0xfb, 0xd1, - 0x00, 0xf1, 0x04, 0x00, - 0x01, 0xf1, 0x04, 0x01, - 0xa2, 0xf1, 0x01, 0x02, - 0xef, 0xe7, - 0x00, 0xbe, // bkpt #0x00 - 0x00, 0x3c, 0x02, 0x40, + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32f7_lv[] = { // flashloaders/stm32f7lv.s - 0x92, 0x00, // lsls r2, r2, #2 - 0x09, 0x4b, // ldr r3, [pc, #36] ; (0x20000028 ) - // next: - 0x72, 0xb1, // cbz r2, 24 - 0x04, 0x78, // ldrb r4, [r0, #0] - 0x0c, 0x70, // strb r4, [r1, #0] - 0xbf, 0xf3, 0x4f, 0x8f, // dsb sy - // wait: - 0xdc, 0x89, // ldrh r4, [r3, #14] - 0x14, 0xf0, 0x01, 0x0f, // tst.w r4, #1 - 0xfb, 0xd1, // bne.n e - 0x00, 0xf1, 0x01, 0x00, // add r0, r0, #1 - 0x01, 0xf1, 0x01, 0x01, // add r1, r1, #1 - 0xa2, 0xf1, 0x01, 0x02, // sub r2, r2, #1 - 0xef, 0xe7, // b next - // done: - 0x00, 0xbe, // bkpt - 0x00, 0xbf, // nop - // flash_base: - 0x00, 0x3c, 0x02, 0x40 // .word 0x40023c00 + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 }; From 489a37e3c72858ca5fdcdcfb3af09decc397cbb6 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Sat, 25 Apr 2020 18:13:08 +0800 Subject: [PATCH 0893/1435] Document error fix --- flashloaders/cleanroom.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flashloaders/cleanroom.md b/flashloaders/cleanroom.md index 594e7191a..1bae4535d 100644 --- a/flashloaders/cleanroom.md +++ b/flashloaders/cleanroom.md @@ -39,7 +39,7 @@ English version can be found below. 每次写入数据宽度为2字节(半字)。 -每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_SR处4字节内容,若取值为1,则说明写入尚未完成,需继续轮询等待;否则需要检查FLASH_SR处值是否为4,若是4,则应直接准备退出。 +每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_SR处4字节内容,若取值为1,则说明写入尚未完成,需继续轮询等待;否则需要检查FLASH_SR处值是否为4,若非4,则应直接准备退出。 退出:全部拷贝执行完毕后触发断点前,将FLASH_CR处4字节内容最低bit清为0,写回FLASH_CR。 @@ -155,7 +155,7 @@ Copy data from source to destination, after which trigger a breakpint to exit. B Before every copy, read a word from FLASH_CR, set the lowest bit to 1 and write back. Copy one half word each time. -How to wait for the write process: read a word from FLASH_SR, loop until the content is not 1. After that, check FLASH_SR, proceed if the content is not 4, otherwise exit. +How to wait for the write process: read a word from FLASH_SR, loop until the content is not 1. After that, check FLASH_SR, proceed if the content is 4, otherwise exit. Exit: after the copying process and before triggering the breakpoint, clear the lowest bit in FLASH_CR. From 9096984a8361c05b0d7b6205e212651c616f65cb Mon Sep 17 00:00:00 2001 From: xp Date: Sat, 25 Apr 2020 19:52:51 +0800 Subject: [PATCH 0894/1435] fix stm32f0 loop condition --- flashloaders/stm32f0.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index 489e30672..3dd0ae6e8 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -34,10 +34,10 @@ mywait: tst r3, r7 beq mywait - # exit if FLASH_SR == 4 + # exit if FLASH_SR != 4 ldr r7, =0x4 tst r3, r7 - beq myexit + bne myexit # loop if r2 != 0 ldr r7, =0x1 From b0971737c89e872bce134fb1c38cdf819fb963de Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Sat, 25 Apr 2020 19:55:35 +0800 Subject: [PATCH 0895/1435] Sync flashloader.c with stm32f0.s --- src/flash_loader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flash_loader.c b/src/flash_loader.c index cee2aaba1..ba12b0b64 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -22,7 +22,7 @@ 0x01, 0x07, 0x2b, 0x68, 0x3b, 0x42, 0xfa, 0xd0, 0x4f, 0xf0, 0x04, 0x07, - 0x3b, 0x42, 0x04, 0xd0, + 0x3b, 0x42, 0x04, 0xd1, 0x4f, 0xf0, 0x01, 0x07, 0xd2, 0x1b, 0x00, 0x2a, 0xe6, 0xd1, 0x4f, 0xf0, @@ -66,7 +66,7 @@ 0xc9, 0x19, 0x0e, 0x4f, 0x2b, 0x68, 0x3b, 0x42, 0xfb, 0xd0, 0x0e, 0x4f, - 0x3b, 0x42, 0x03, 0xd0, + 0x3b, 0x42, 0x03, 0xd1, 0x0a, 0x4f, 0xd2, 0x1b, 0x00, 0x2a, 0xeb, 0xd1, 0x08, 0x4f, 0x33, 0x68, From 8b77d027d37fe21ea3fce1db6d63ae3042eb9a35 Mon Sep 17 00:00:00 2001 From: xp Date: Sat, 25 Apr 2020 20:21:13 +0800 Subject: [PATCH 0896/1435] fix: stm32-lv r2(4) and copy(1) has different data unit size --- flashloaders/stm32f4lv.s | 12 +++++++++--- flashloaders/stm32f7lv.s | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/flashloaders/stm32f4lv.s b/flashloaders/stm32f4lv.s index ef9f3a0bb..92f70facc 100644 --- a/flashloaders/stm32f4lv.s +++ b/flashloaders/stm32f4lv.s @@ -8,12 +8,18 @@ mycopy: add r10, r10, r12 myloop: - # copy 1 bytes + # copy 1 byte each time and 4 times as one group ldrb r3, [r0] + ldrb r4, [r0, #1] + ldrb r5, [r0, #2] + ldrb r6, [r0, #3] strb r3, [r1] + strb r4, [r1, #1] + strb r5, [r1, #2] + strb r6, [r1, #3] - add r0, r0, #1 - add r1, r1, #1 + add r0, r0, #4 + add r1, r1, #4 # wait if FLASH_SR == 1 mywait: diff --git a/flashloaders/stm32f7lv.s b/flashloaders/stm32f7lv.s index 99eb37d88..013b56f87 100644 --- a/flashloaders/stm32f7lv.s +++ b/flashloaders/stm32f7lv.s @@ -8,12 +8,18 @@ mycopy: add r10, r10, r12 myloop: - # copy 1 byte + # copy 1 byte each time and 4 times as one group ldrb r3, [r0] + ldrb r4, [r0, #1] + ldrb r5, [r0, #2] + ldrb r6, [r0, #3] strb r3, [r1] + strb r4, [r1, #1] + strb r5, [r1, #2] + strb r6, [r1, #3] - add r0, r0, #1 - add r1, r1, #1 + add r0, r0, #4 + add r1, r1, #4 # memory barrier dsb sy From 09b40ca7bcb8e30df0cf374946327f858771f456 Mon Sep 17 00:00:00 2001 From: xp Date: Sat, 25 Apr 2020 20:37:26 +0800 Subject: [PATCH 0897/1435] update --- flashloaders/stm32f4lv.s | 18 +++++++++--------- flashloaders/stm32f7lv.o | Bin 0 -> 792 bytes flashloaders/stm32f7lv.s | 18 +++++++++--------- 3 files changed, 18 insertions(+), 18 deletions(-) create mode 100644 flashloaders/stm32f7lv.o diff --git a/flashloaders/stm32f4lv.s b/flashloaders/stm32f4lv.s index 92f70facc..c338b984a 100644 --- a/flashloaders/stm32f4lv.s +++ b/flashloaders/stm32f4lv.s @@ -7,19 +7,19 @@ mycopy: ldr r10, flash_off_sr add r10, r10, r12 + # original r2 indicates the count of 4 bytes need to copy, + # but we can only copy one byte each time. + # as we have no flash larger than 1GB, we do a little trick here. + ldr r3, =4 + mul r2, r2, r3 + myloop: - # copy 1 byte each time and 4 times as one group + # copy 1 byte ldrb r3, [r0] - ldrb r4, [r0, #1] - ldrb r5, [r0, #2] - ldrb r6, [r0, #3] strb r3, [r1] - strb r4, [r1, #1] - strb r5, [r1, #2] - strb r6, [r1, #3] - add r0, r0, #4 - add r1, r1, #4 + add r0, r0, #1 + add r1, r1, #1 # wait if FLASH_SR == 1 mywait: diff --git a/flashloaders/stm32f7lv.o b/flashloaders/stm32f7lv.o new file mode 100644 index 0000000000000000000000000000000000000000..f71d5e6366b415ff04a5340db3c4e011bef88b53 GIT binary patch literal 792 zcmah{y-EW?5dQWqQG-8;T56*P3_%ZtfPyI^sFfk$3&cHhA%TQDaw{g4kD$Gc_!t)I zBgD>5@BzeV6SQ$Acbi-aabV{AX7}5<*_*vQJU$XaK$}1YqYQWnl6Y<)$Y2VScJ542RLe&berkQfu3RXob3Cs3+vm#hbw~drkAnZ%L@4FE z7DCPt3;7Bm>&!4$A!^_~wsrC;^8a)jfyN^k7}w)jXw&r=qf@@7yi3mg@@%=k6nTPN cf0HOq>EIrd&~!b1Z&BS1ZH(SSa7RA!3p%Ax&;S4c literal 0 HcmV?d00001 diff --git a/flashloaders/stm32f7lv.s b/flashloaders/stm32f7lv.s index 013b56f87..55c9add1a 100644 --- a/flashloaders/stm32f7lv.s +++ b/flashloaders/stm32f7lv.s @@ -7,19 +7,19 @@ mycopy: ldr r10, flash_off_sr add r10, r10, r12 + # original r2 indicates the count of 4 bytes need to copy, + # but we can only copy one byte each time. + # as we have no flash larger than 1GB, we do a little trick here. + ldr r3, =4 + mul r2, r2, r3 + myloop: - # copy 1 byte each time and 4 times as one group + # copy 1 byte ldrb r3, [r0] - ldrb r4, [r0, #1] - ldrb r5, [r0, #2] - ldrb r6, [r0, #3] strb r3, [r1] - strb r4, [r1, #1] - strb r5, [r1, #2] - strb r6, [r1, #3] - add r0, r0, #4 - add r1, r1, #4 + add r0, r0, #1 + add r1, r1, #1 # memory barrier dsb sy From a4fec73a27516f787fa0853b1fab9ecaa7225f61 Mon Sep 17 00:00:00 2001 From: xp Date: Sat, 25 Apr 2020 20:53:05 +0800 Subject: [PATCH 0898/1435] update --- flashloaders/stm32f4lv.s | 10 +++++----- flashloaders/stm32f7lv.o | Bin 792 -> 0 bytes flashloaders/stm32f7lv.s | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) delete mode 100644 flashloaders/stm32f7lv.o diff --git a/flashloaders/stm32f4lv.s b/flashloaders/stm32f4lv.s index c338b984a..4ba351faa 100644 --- a/flashloaders/stm32f4lv.s +++ b/flashloaders/stm32f4lv.s @@ -7,11 +7,11 @@ mycopy: ldr r10, flash_off_sr add r10, r10, r12 - # original r2 indicates the count of 4 bytes need to copy, - # but we can only copy one byte each time. - # as we have no flash larger than 1GB, we do a little trick here. - ldr r3, =4 - mul r2, r2, r3 + # tip 1: original r2 indicates the count of 4 bytes need to copy, + # but we can only copy one byte each time. + # as we have no flash larger than 1GB, we do a little trick here. + # tip 2: r2 is always a power of 2 + mov r2, r2, lsl#2 myloop: # copy 1 byte diff --git a/flashloaders/stm32f7lv.o b/flashloaders/stm32f7lv.o deleted file mode 100644 index f71d5e6366b415ff04a5340db3c4e011bef88b53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 792 zcmah{y-EW?5dQWqQG-8;T56*P3_%ZtfPyI^sFfk$3&cHhA%TQDaw{g4kD$Gc_!t)I zBgD>5@BzeV6SQ$Acbi-aabV{AX7}5<*_*vQJU$XaK$}1YqYQWnl6Y<)$Y2VScJ542RLe&berkQfu3RXob3Cs3+vm#hbw~drkAnZ%L@4FE z7DCPt3;7Bm>&!4$A!^_~wsrC;^8a)jfyN^k7}w)jXw&r=qf@@7yi3mg@@%=k6nTPN cf0HOq>EIrd&~!b1Z&BS1ZH(SSa7RA!3p%Ax&;S4c diff --git a/flashloaders/stm32f7lv.s b/flashloaders/stm32f7lv.s index 55c9add1a..d82726eeb 100644 --- a/flashloaders/stm32f7lv.s +++ b/flashloaders/stm32f7lv.s @@ -7,11 +7,11 @@ mycopy: ldr r10, flash_off_sr add r10, r10, r12 - # original r2 indicates the count of 4 bytes need to copy, - # but we can only copy one byte each time. - # as we have no flash larger than 1GB, we do a little trick here. - ldr r3, =4 - mul r2, r2, r3 + # tip 1: original r2 indicates the count in 4 bytes need to copy, + # but we can only copy one byte each time. + # as we have no flash larger than 1GB, we do a little trick here. + # tip 2: r2 is always a power of 2 + mov r2, r2, lsl#2 myloop: # copy 1 byte From 65ca384008ed8516d3f582b22ef7cd4a39c8ed6a Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Sat, 25 Apr 2020 21:01:21 +0800 Subject: [PATCH 0899/1435] Sync flashloader.c with commit a4fec73a27516f787fa0853b1fab9ecaa7225f61 --- src/flash_loader.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/flash_loader.c b/src/flash_loader.c index ba12b0b64..a3fd2cefd 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -114,9 +114,10 @@ static const uint8_t loader_code_stm32f4_lv[] = { // flashloaders/stm32f4lv.s - 0xdf, 0xf8, 0x28, 0xc0, - 0xdf, 0xf8, 0x28, 0xa0, - 0xe2, 0x44, 0x03, 0x78, + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, 0x0b, 0x70, 0x00, 0xf1, 0x01, 0x00, 0x01, 0xf1, 0x01, 0x01, 0xba, 0xf8, @@ -167,9 +168,10 @@ static const uint8_t loader_code_stm32f7_lv[] = { // flashloaders/stm32f7lv.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x78, + 0xdf, 0xf8, 0x30, 0xc0, + 0xdf, 0xf8, 0x30, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, 0x0b, 0x70, 0x00, 0xf1, 0x01, 0x00, 0x01, 0xf1, 0x01, 0x01, 0xbf, 0xf3, From f82700623127538c8cf5cddbbeba6afc12d3adbf Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 25 Apr 2020 22:34:18 +0200 Subject: [PATCH 0900/1435] Refactoring for cmake build settings - Moved additional header files to /src - Simplified header-paths - Added missing license title for getopt - Added comments and sections to CMakeLists - Improved file structure (partially) - Co-build st-util with st-info & st-flash - GUI: Renamed .ui file to match executable - Added install targets for executables - Added missing "uninstall" cmd to Makefile --- CMakeLists.txt | 126 +++++++++++------- Makefile | 5 + cmake/packaging/CMakeLists.txt | 2 + doc/man/CMakeLists.txt | 4 + include/CMakeLists.txt | 1 + include/stlink.h | 18 +-- include/stlink/flash_loader.h | 2 +- include/stlink/tools/flash.h | 1 + src/chipid.c | 7 +- src/common.c | 2 +- src/flash_loader.c | 18 +-- src/gdbserver/CMakeLists.txt | 23 ---- src/getopt/LICENSE.txt | 2 + src/getopt/getopt.c | 38 +++--- .../stlinkusb.h => src/libusb_settings.h | 4 +- src/md5.c | 3 +- src/sg.c | 2 +- {include/stlink => src}/sg.h | 7 +- src/{gdbserver => st-util}/gdb-remote.c | 4 +- src/{gdbserver => st-util}/gdb-remote.h | 0 src/{gdbserver => st-util}/gdb-server.c | 4 +- src/{gdbserver => st-util}/gdb-server.h | 0 src/{gdbserver => st-util}/semihosting.c | 5 +- src/{gdbserver => st-util}/semihosting.h | 0 src/stlink-gui/CMakeLists.txt | 28 ++-- src/stlink-gui/gui.c | 4 +- src/stlink-gui/{gui.ui => stlink-gui.ui} | 0 src/tools/flash.c | 3 +- src/tools/flash_opts.c | 4 +- src/usb.c | 6 +- {include/stlink => src}/usb.h | 8 +- tests/CMakeLists.txt | 4 + tests/flash.c | 2 +- tests/sg.c | 1 + tests/usb.c | 2 +- 35 files changed, 185 insertions(+), 155 deletions(-) delete mode 100644 src/gdbserver/CMakeLists.txt rename include/stlink/stlinkusb.h => src/libusb_settings.h (91%) rename {include/stlink => src}/sg.h (95%) rename src/{gdbserver => st-util}/gdb-remote.c (99%) rename src/{gdbserver => st-util}/gdb-remote.h (100%) rename src/{gdbserver => st-util}/gdb-server.c (99%) rename src/{gdbserver => st-util}/gdb-server.h (100%) rename src/{gdbserver => st-util}/semihosting.c (99%) rename src/{gdbserver => st-util}/semihosting.h (100%) rename src/stlink-gui/{gui.ui => stlink-gui.ui} (100%) rename {include/stlink => src}/usb.h (96%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e6501dc9..95e27d215 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,36 +95,51 @@ else () endif () +### +# Main build process +### + +## Define include directories to avoid absolute paths for header defines +include_directories(${LIBUSB_INCLUDE_DIR}) + # ==== +include_directories(include) ### TODO: Clean this up... +include_directories(${PROJECT_BINARY_DIR}/include/stlink) +include_directories(include/stlink) +include_directories(include/stlink/tools) +# ==== + +include_directories(src) set(STLINK_HEADERS - include/stlink.h - include/stlink/usb.h - include/stlink/sg.h - include/stlink/chipid.h - include/stlink/flash_loader.h - ) + include/stlink.h + include/stlink/backend.h + include/stlink/chipid.h + include/stlink/commands.h + include/stlink/flash_loader.h + include/stlink/reg.h + src/logging.h + src/md5.h + src/sg.h + src/usb.h + ) set(STLINK_SOURCE - src/chipid.c - src/common.c - src/flash_loader.c - src/logging.c - src/md5.c - src/sg.c - src/usb.c - ) + src/common.c + src/chipid.c + src/flash_loader.c + src/logging.c + src/md5.c + src/sg.c + src/usb.c + ) if (WIN32 OR MINGW OR MSYS) + include_directories(src/mingw) set(STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") - set(STLINK_HEADERS "${STLINK_HEADERS};src/mingw/mingw.h") + set(STLINK_HEADERS "${STLINK_HEADERS};src/mmap.h;src/mingw/mingw.h") endif () -include_directories(${LIBUSB_INCLUDE_DIR}) -include_directories(include) -include_directories(${PROJECT_BINARY_DIR}/include) -include_directories(src/mingw) - if (MSVC) include_directories(src/win32) include_directories(src/getopt) @@ -132,11 +147,12 @@ if (MSVC) add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) endif () -# Include test execution for test-targets for target Debug +## Include test execution for test-targets for target Debug if (${CMAKE_BUILD_TYPE} MATCHES "Debug") include(CTest) endif () + ### # Shared library ### @@ -148,14 +164,15 @@ else (WIN32) endif () add_library( - ${STLINK_LIB_SHARED} SHARED - ${STLINK_HEADERS} # header files for ide projects generated by cmake - ${STLINK_SOURCE} - ) + ${STLINK_LIB_SHARED} SHARED + ${STLINK_HEADERS} # header files for ide projects generated by cmake + ${STLINK_SOURCE} + ) + target_link_libraries( - ${STLINK_LIB_SHARED} - ${LIBUSB_LIBRARY} - ) + ${STLINK_LIB_SHARED} + ${LIBUSB_LIBRARY} + ) set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) @@ -163,7 +180,8 @@ message(STATUS "STLINK_LIB_SHARED: ${STLINK_LIB_SHARED}") message(STATUS "PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}") message(STATUS "VERSION: ${STLINK_SHARED_VERSION}") -set_target_properties(${STLINK_LIB_SHARED} PROPERTIES +set_target_properties( + ${STLINK_LIB_SHARED} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} VERSION ${STLINK_SHARED_VERSION} ) @@ -182,7 +200,7 @@ else () target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB}) endif () -install(TARGETS ${STLINK_LIB_SHARED} DESTINATION ${STLINK_LIBRARY_PATH}) ### TODO: Check path +install(TARGETS ${STLINK_LIB_SHARED} DESTINATION ${STLINK_LIBRARY_PATH}) ### @@ -197,6 +215,11 @@ add_library( ${STLINK_SOURCE} ) +set_target_properties( + ${STLINK_LIB_STATIC} PROPERTIES + OUTPUT_NAME ${PROJECT_NAME} + ) + # Link static library with Apple macOS libraries if (APPLE) find_library(ObjC objc) @@ -205,32 +228,40 @@ if (APPLE) target_link_libraries(${STLINK_LIB_STATIC} ${CoreFoundation} ${IOKit} ${ObjC} ${SSP_LIB}) endif () -if (WIN32 OR MINGW OR MSYS) ### TODO: MinGW OR MSYS on Linux +if (WIN32 OR MINGW OR MSYS) target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} wsock32 ws2_32 ${SSP_LIB}) else () target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB}) endif () -set_target_properties(${STLINK_LIB_STATIC} PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) - if (STLINK_STATIC_LIB) - install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH}) ### TODO: Check path + install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH}) endif () ### -# Tools +# Build toolset executables ### +set(ST-UTIL_SOURCES src/st-util/gdb-remote.c src/st-util/gdb-server.c src/st-util/semihosting.c) + +if (MSVC) + # Add getopt to sources + set(ST-UTIL_SOURCES "${ST-UTIL_SOURCES};src/getopt/getopt.c") +endif () + add_executable(st-flash src/tools/flash.c src/tools/flash_opts.c) add_executable(st-info src/tools/info.c) +add_executable(st-util ${ST-UTIL_SOURCES}) if (WIN32 OR APPLE) target_link_libraries(st-flash ${STLINK_LIB_STATIC} ${SSP_LIB}) target_link_libraries(st-info ${STLINK_LIB_STATIC} ${SSP_LIB}) + target_link_libraries(st-util ${STLINK_LIB_STATIC} ${SSP_LIB}) else () target_link_libraries(st-flash ${STLINK_LIB_SHARED} ${SSP_LIB}) target_link_libraries(st-info ${STLINK_LIB_SHARED} ${SSP_LIB}) + target_link_libraries(st-util ${STLINK_LIB_SHARED} ${SSP_LIB}) endif () if (CMAKE_SYSTEM_NAME STREQUAL "Linux") @@ -243,27 +274,24 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux") endif () endif () -add_subdirectory(src/gdbserver) -add_subdirectory(src/stlink-gui) - +install(TARGETS st-flash DESTINATION bin) +install(TARGETS st-info DESTINATION bin) +install(TARGETS st-util DESTINATION bin) ### -# Others +# Additional build tasks ### -add_subdirectory(include) ### TODO: Check path -add_subdirectory(doc/man) -add_subdirectory(tests) - +# ==== +add_subdirectory(include) # contains subordinate CMakeLists for version config and old header includes + ### TODO: Clean this up ... # ==== +add_subdirectory(src/stlink-gui) # contains subordinate CMakeLists to build GUI +add_subdirectory(tests) # contains subordinate CMakeLists to build test executables +add_subdirectory(doc/man) # contains subordinate CMakeLists to generate manpages +add_subdirectory(cmake/packaging) # contains subordinate CMakeLists to build packages -### -# Package build -### - -add_subdirectory(cmake/packaging) -include(cmake/packaging/cpack_config.cmake) ### # Uninstall target diff --git a/Makefile b/Makefile index 57043ac97..74a4fece5 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ help: @echo " debug: Run a debug build" @echo " release: Run a release build" @echo " install: Install release build" + @echo " uninstall: Uninstall release build" @echo " package: Package release build" @echo " lint: Lint check all source-code" @echo " test: Build and run tests" @@ -35,6 +36,10 @@ install: build/Release @echo "[INSTALL] Release" @$(MAKE) -C build/Release install +uninstall: build/Release + @echo "[UNINSTALL] Release" + @$(MAKE) -C build/Release uninstall + package: build/Release @echo "[PACKAGE] Release" @$(MAKE) -C build/Release package diff --git a/cmake/packaging/CMakeLists.txt b/cmake/packaging/CMakeLists.txt index e831f611f..431c85d2d 100644 --- a/cmake/packaging/CMakeLists.txt +++ b/cmake/packaging/CMakeLists.txt @@ -2,3 +2,5 @@ add_subdirectory(debian) add_subdirectory(fedora) add_subdirectory(opensuse) add_subdirectory(windows) + +include(cpack_config.cmake) diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 090a2237e..221c84d7b 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -1,3 +1,7 @@ +### +# Generate manpages +### + set(MANPAGES st-util st-flash st-info) # Only generate manpages with pandoc in Debug builds diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 6e5e3c279..6cf397659 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -2,6 +2,7 @@ configure_file( "${PROJECT_SOURCE_DIR}/include/stlink/version.h.in" "${CMAKE_BINARY_DIR}/include/stlink/version.h" ) + file(GLOB STLINK_HEADERS "stlink/*.h" "${CMAKE_BINARY_DIR}/include/stlink/*.h") install(FILES ${CMAKE_SOURCE_DIR}/include/stlink.h DESTINATION ${STLINK_INCLUDE_PATH}) install(FILES ${CMAKE_SOURCE_DIR}/include/stm32.h DESTINATION ${STLINK_INCLUDE_PATH}) diff --git a/include/stlink.h b/include/stlink.h index a28b60116..74c366d1c 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -137,7 +137,7 @@ typedef struct flash_loader { typedef struct _stlink stlink_t; -#include "stlink/backend.h" +#include struct _stlink { struct _stlink_backend *backend; @@ -245,14 +245,14 @@ typedef struct flash_loader { int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); -#include "stlink/sg.h" -#include "stlink/usb.h" -#include "stlink/reg.h" -#include "stlink/commands.h" -#include "stlink/chipid.h" -#include "stlink/flash_loader.h" -#include "stlink/version.h" -#include "../src/logging.h" +#include +#include +#include +#include +#include +#include +#include +#include #ifdef __cplusplus } diff --git a/include/stlink/flash_loader.h b/include/stlink/flash_loader.h index 95042f7b6..5f4526114 100644 --- a/include/stlink/flash_loader.h +++ b/include/stlink/flash_loader.h @@ -10,7 +10,7 @@ #include #include -#include "stlink.h" +#include #ifdef __cplusplus extern "C" { diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index 15e020b35..8c3f7d766 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -2,6 +2,7 @@ #define STLINK_TOOLS_FLASH_H_ #include + #include #define DEBUG_LOG_LEVEL 100 diff --git a/src/chipid.c b/src/chipid.c index 17cb4d546..fcc1c55eb 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -1,5 +1,5 @@ -#include "stlink.h" -#include "stlink/chipid.h" +#include +#include static const struct stlink_chipid_params devices[] = { { @@ -580,7 +580,6 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28K (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, .option_size = 4, - }, { // STM32G471/473/474/483/484 (from RM0440) @@ -621,8 +620,6 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x0, .bootrom_size = 0x0 }, - - }; const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) diff --git a/src/common.c b/src/common.c index 99cc0b513..9d21624f8 100644 --- a/src/common.c +++ b/src/common.c @@ -11,7 +11,7 @@ #include #include -#include "stlink.h" +#include #include "mmap.h" #include "logging.h" #include "md5.h" diff --git a/src/flash_loader.c b/src/flash_loader.c index a1c9c3757..ed253f92b 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -1,9 +1,9 @@ -#include "stlink.h" - #include #include #include +#include + #define FLASH_REGS_BANK2_OFS 0x40 #define FLASH_BANK2_START_ADDR 0x08080000 @@ -384,16 +384,16 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe /* run loader */ stlink_run(sl); -// This piece of code used to try to spin for .1 second by waiting +// This piece of code used to try to spin for .1 second by waiting // doing 10000 rounds of 10 microseconds. But because this usually runs -// on Unix-like OSes, the 10 microseconds get rounded up to the "tick" +// on Unix-like OSes, the 10 microseconds get rounded up to the "tick" // (actually almost two ticks) of the system. 1 milisecond. Thus, the -// ten thousand attempts, when "something goes wrong" that requires -// the error message "flash loader run error" would wait for something -// like 20 seconds before coming up with the error. -// by increasing the sleep-per-round to the same order-of-magnitude as +// ten thousand attempts, when "something goes wrong" that requires +// the error message "flash loader run error" would wait for something +// like 20 seconds before coming up with the error. +// by increasing the sleep-per-round to the same order-of-magnitude as // the tick-rounding that the OS uses, the wait until the error message is -// reduced to the same order of magnitude as what was intended. -- REW. +// reduced to the same order of magnitude as what was intended. -- REW. #define WAIT_ROUNDS 100 /* wait until done (reaches breakpoint) */ for (i = 0; i < WAIT_ROUNDS; i++) { diff --git a/src/gdbserver/CMakeLists.txt b/src/gdbserver/CMakeLists.txt deleted file mode 100644 index ff9bde165..000000000 --- a/src/gdbserver/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -set(STUTIL_SOURCE - gdb-remote.c - gdb-remote.h - gdb-server.c - gdb-server.h - semihosting.c - semihosting.h - ) - -if (MSVC) - # We need a getopt from somewhere... - set(STUTIL_SOURCE "${STUTIL_SOURCE};../getopt/getopt.c") -endif () - -add_executable(st-util ${STUTIL_SOURCE}) - -if (WIN32 OR APPLE) - target_link_libraries(st-util ${STLINK_LIB_STATIC} ${SSP_LIB}) -else () - target_link_libraries(st-util ${STLINK_LIB_SHARED} ${SSP_LIB}) -endif () - -install(TARGETS st-util RUNTIME DESTINATION bin) diff --git a/src/getopt/LICENSE.txt b/src/getopt/LICENSE.txt index 340303a96..4e4ed8bd5 100644 --- a/src/getopt/LICENSE.txt +++ b/src/getopt/LICENSE.txt @@ -1,3 +1,5 @@ +BSD 3-Clause License + Copyright (c) 2012, Kim Gräsman All rights reserved. diff --git a/src/getopt/getopt.c b/src/getopt/getopt.c index 72dce14d6..5dd45bff7 100644 --- a/src/getopt/getopt.c +++ b/src/getopt/getopt.c @@ -1,8 +1,8 @@ -#include "getopt.h" - #include #include +#include "getopt.h" + #if !defined(_MSC_VER) const int no_argument = 0; const int required_argument = 1; @@ -19,8 +19,8 @@ static char* optcursor = NULL; /* Implemented based on [1] and [2] for optional arguments. optopt is handled FreeBSD-style, per [3]. - Other GNU and FreeBSD extensions are purely accidental. - + Other GNU and FreeBSD extensions are purely accidental. + [1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html [2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html [3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE @@ -37,22 +37,22 @@ int getopt(int argc, char* const argv[], const char* optstring) { if (optind >= argc) goto no_more_optchars; - /* If, when getopt() is called argv[optind] is a null pointer, getopt() + /* If, when getopt() is called argv[optind] is a null pointer, getopt() shall return -1 without changing optind. */ if (argv[optind] == NULL) goto no_more_optchars; - /* If, when getopt() is called *argv[optind] is not the character '-', + /* If, when getopt() is called *argv[optind] is not the character '-', getopt() shall return -1 without changing optind. */ if (*argv[optind] != '-') goto no_more_optchars; - /* If, when getopt() is called argv[optind] points to the string "-", + /* If, when getopt() is called argv[optind] points to the string "-", getopt() shall return -1 without changing optind. */ if (strcmp(argv[optind], "-") == 0) goto no_more_optchars; - /* If, when getopt() is called argv[optind] points to the string "--", + /* If, when getopt() is called argv[optind] points to the string "--", getopt() shall return -1 after incrementing optind. */ if (strcmp(argv[optind], "--") == 0) { ++optind; @@ -64,12 +64,12 @@ int getopt(int argc, char* const argv[], const char* optstring) { optchar = *optcursor; - /* FreeBSD: The variable optopt saves the last known option character + /* FreeBSD: The variable optopt saves the last known option character returned by getopt(). */ optopt = optchar; - /* The getopt() function shall return the next option character (if one is - found) from argv that matches a character in optstring, if there is + /* The getopt() function shall return the next option character (if one is + found) from argv that matches a character in optstring, if there is one that matches. */ optdecl = strchr(optstring, optchar); if (optdecl) { @@ -79,15 +79,15 @@ int getopt(int argc, char* const argv[], const char* optstring) { optarg = ++optcursor; if (*optarg == '\0') { /* GNU extension: Two colons mean an option takes an - optional arg; if there is text in the current argv-element - (i.e., in the same word as the option name itself, for example, + optional arg; if there is text in the current argv-element + (i.e., in the same word as the option name itself, for example, "-oarg"), then it is returned in optarg, otherwise optarg is set to zero. */ if (optdecl[2] != ':') { /* If the option was the last character in the string pointed to by an element of argv, then optarg shall contain the next element of argv, and optind shall be incremented by 2. If the resulting - value of optind is greater than argc, this indicates a missing + value of optind is greater than argc, this indicates a missing option-argument, and getopt() shall return an error indication. Otherwise, optarg shall point to the string following the @@ -97,7 +97,7 @@ int getopt(int argc, char* const argv[], const char* optstring) { if (++optind < argc) { optarg = argv[optind]; } else { - /* If it detects a missing option-argument, it shall return the + /* If it detects a missing option-argument, it shall return the colon character ( ':' ) if the first character of optstring was a colon, or a question-mark character ( '?' ) otherwise. */ @@ -112,7 +112,7 @@ int getopt(int argc, char* const argv[], const char* optstring) { optcursor = NULL; } } else { - /* If getopt() encounters an option character that is not contained in + /* If getopt() encounters an option character that is not contained in optstring, it shall return the question-mark ( '?' ) character. */ optchar = '?'; } @@ -131,7 +131,7 @@ int getopt(int argc, char* const argv[], const char* optstring) { [1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html */ -int getopt_long(int argc, char* const argv[], const char* optstring, +int getopt_long(int argc, char* const argv[], const char* optstring, const struct option* longopts, int* longindex) { const struct option* o = longopts; const struct option* match = NULL; @@ -165,7 +165,7 @@ int getopt_long(int argc, char* const argv[], const char* optstring, if (longindex) *longindex = (match - longopts); - /* If flag is NULL, then getopt_long() shall return val. + /* If flag is NULL, then getopt_long() shall return val. Otherwise, getopt_long() returns 0, and flag shall point to a variable which shall be set to val if the option is found, but left unchanged if the option is not found. */ @@ -190,7 +190,7 @@ int getopt_long(int argc, char* const argv[], const char* optstring, retval = ':'; } } else if (strchr(argv[optind], '=')) { - /* An argument was provided to a non-argument option. + /* An argument was provided to a non-argument option. I haven't seen this specified explicitly, but both GNU and BSD-based implementations show this behavior. */ diff --git a/include/stlink/stlinkusb.h b/src/libusb_settings.h similarity index 91% rename from include/stlink/stlinkusb.h rename to src/libusb_settings.h index 633d82bd0..c2e2df923 100644 --- a/include/stlink/stlinkusb.h +++ b/src/libusb_settings.h @@ -1,5 +1,5 @@ -#ifndef STLINKUSB_H -#define STLINKUSB_H +#ifndef LIBUSB_SETTINGS_H +#define LIBUSB_SETTINGS_H #include diff --git a/src/md5.c b/src/md5.c index e2b526c7d..521c52969 100755 --- a/src/md5.c +++ b/src/md5.c @@ -15,9 +15,10 @@ // IMPORTS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include "md5.h" #include +#include "md5.h" + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // INTERNAL FUNCTIONS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/sg.c b/src/sg.c index eee6be498..a0790f3c7 100644 --- a/src/sg.c +++ b/src/sg.c @@ -82,7 +82,7 @@ #include #include -#include "stlink.h" +#include #include "logging.h" #define STLINK_OK 0x80 diff --git a/include/stlink/sg.h b/src/sg.h similarity index 95% rename from include/stlink/sg.h rename to src/sg.h index 98efd4e58..3a8a7a239 100644 --- a/include/stlink/sg.h +++ b/src/sg.h @@ -1,5 +1,5 @@ /* - * File: stlink/sg.h + * File: sg.h * Author: karl * * Created on October 1, 2011, 11:29 PM @@ -8,8 +8,8 @@ #ifndef STLINK_SG_H #define STLINK_SG_H -#include "stlinkusb.h" -#include "stlink.h" +#include "libusb_settings.h" +#include #ifdef __cplusplus extern "C" { @@ -70,4 +70,3 @@ stlink_t* stlink_v1_open(const int verbose, int reset); #endif #endif /* STLINK_SG_H */ - diff --git a/src/gdbserver/gdb-remote.c b/src/st-util/gdb-remote.c similarity index 99% rename from src/gdbserver/gdb-remote.c rename to src/st-util/gdb-remote.c index 3b1794f3e..24636e8c9 100644 --- a/src/gdbserver/gdb-remote.c +++ b/src/st-util/gdb-remote.c @@ -8,6 +8,7 @@ #include #include #include + #if defined(__MINGW32__) || defined(_MSC_VER) #include #else @@ -15,6 +16,8 @@ #include #endif +#include "gdb-remote.h" + static const char hex[] = "0123456789abcdef"; int gdb_send_packet(int fd, char* data) { @@ -169,4 +172,3 @@ int gdb_check_for_interrupt(int fd) { return 0; } - diff --git a/src/gdbserver/gdb-remote.h b/src/st-util/gdb-remote.h similarity index 100% rename from src/gdbserver/gdb-remote.h rename to src/st-util/gdb-remote.h diff --git a/src/gdbserver/gdb-server.c b/src/st-util/gdb-server.c similarity index 99% rename from src/gdbserver/gdb-server.c rename to src/st-util/gdb-server.c index ce9f6eef7..a3839cfc8 100644 --- a/src/gdbserver/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -14,6 +14,7 @@ #include #define __attribute__(x) #endif + #if defined(_WIN32) #include #else @@ -24,8 +25,7 @@ #endif #include -#include "../logging.h" - +#include #include "gdb-remote.h" #include "gdb-server.h" #include "semihosting.h" diff --git a/src/gdbserver/gdb-server.h b/src/st-util/gdb-server.h similarity index 100% rename from src/gdbserver/gdb-server.h rename to src/st-util/gdb-server.h diff --git a/src/gdbserver/semihosting.c b/src/st-util/semihosting.c similarity index 99% rename from src/gdbserver/semihosting.c rename to src/st-util/semihosting.c index d41a83246..fed66ab60 100644 --- a/src/gdbserver/semihosting.c +++ b/src/st-util/semihosting.c @@ -5,10 +5,9 @@ #include #include -#include "semihosting.h" - #include -#include "../logging.h" +#include +#include "semihosting.h" static int mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) { diff --git a/src/gdbserver/semihosting.h b/src/st-util/semihosting.h similarity index 100% rename from src/gdbserver/semihosting.h rename to src/st-util/semihosting.h diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index 74b71cecd..b5ef99df9 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -1,35 +1,41 @@ +### +# Build GUI +### + +## GUI-Building requires the presence of a GTK3 toolset if (NOT GTK3_FOUND) message(STATUS "GTK3 not found!") - return() # no GTK3 present => no GUI build + return() # no GTK3 present => no GUI build else (GTK3_FOUND) message(STATUS "Found GTK3: -I${GTK3_INCLUDE_DIRS}, ${GTK3_LIBRARIES}") endif () -set(GUI_SOURCES gui.c gui.h) -set(INSTALLED_UI_DIR share/stlink) ### TODO: Check Path - include_directories(SYSTEM ${GTK3_INCLUDE_DIRS}) -# stlink-gui-local +set(GUI_SOURCES gui.c gui.h) + +## stlink-gui-local add_executable(stlink-gui-local ${GUI_SOURCES}) set_target_properties( stlink-gui-local PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}" ### TODO: Check Path + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}" + # Note: ${CMAKE_CURRENT_SOURCE_DIR} is src/stlink-gui ) target_link_libraries(stlink-gui-local ${STLINK_LIB_STATIC} ${GTK3_LDFLAGS} ${SSP_LIB}) -# stlink-gui +## stlink-gui add_executable(stlink-gui ${GUI_SOURCES}) set_target_properties( stlink-gui PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/${INSTALLED_UI_DIR}" ### TODO: Check Path + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/bin" + # Note: ${CMAKE_INSTALL_PREFIX} defaults to /usr/local ) target_link_libraries(stlink-gui ${STLINK_LIB_STATIC} ${GTK3_LDFLAGS} ${SSP_LIB}) -install(TARGETS stlink-gui RUNTIME DESTINATION bin) ### TODO: Check Path -install(FILES gui.ui DESTINATION ${INSTALLED_UI_DIR}) ### TODO: Check Path +install(TARGETS stlink-gui DESTINATION bin) +install(FILES stlink-gui.ui DESTINATION bin) if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - install(FILES stlink-gui.desktop DESTINATION share/applications) # Install desktop entry + install(FILES stlink-gui.desktop DESTINATION share/applications) # Install desktop application entry install(FILES icons/stlink-gui.svg DESTINATION share/icons/hicolor/scalable/apps) # Install icon endif () diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index f90196c06..5d5a422d5 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -779,10 +779,10 @@ static void stlink_gui_build_ui (STlinkGUI *gui) { GtkBuilder *builder; GtkListStore *devmem_store; GtkListStore *filemem_store; - gchar *ui_file = STLINK_UI_DIR "/gui.ui"; + gchar *ui_file = STLINK_UI_DIR "/stlink-gui.ui"; if (!g_file_test (ui_file, G_FILE_TEST_EXISTS)) - ui_file = "gui.ui"; + ui_file = "stlink-gui.ui"; builder = gtk_builder_new (); if (!gtk_builder_add_from_file (builder, ui_file, NULL)) { g_printerr ("Failed to load UI file: %s\n", ui_file); diff --git a/src/stlink-gui/gui.ui b/src/stlink-gui/stlink-gui.ui similarity index 100% rename from src/stlink-gui/gui.ui rename to src/stlink-gui/stlink-gui.ui diff --git a/src/tools/flash.c b/src/tools/flash.c index 3a9cc3674..841b93c3c 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -2,7 +2,6 @@ // TODO - this should be done as just a simple flag to the st-util command line... - #include #include #include @@ -10,7 +9,7 @@ #include #include -#include +#include static stlink_t *connected_stlink = NULL; diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 085d278db..544d4ad90 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -1,9 +1,9 @@ -#include - #include #include #include +#include + static bool starts_with(const char * str, const char * prefix) { size_t n = strlen(prefix); if (strlen(str) < n) return false; diff --git a/src/usb.c b/src/usb.c index c9ea7039a..4e7a2983f 100644 --- a/src/usb.c +++ b/src/usb.c @@ -7,11 +7,13 @@ #include #endif #include -#include #include #include -#include "stlink.h" +#if defined(__MINGW32__) || defined(_MSC_VER) +#include +#endif +#include enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80}; diff --git a/include/stlink/usb.h b/src/usb.h similarity index 96% rename from include/stlink/usb.h rename to src/usb.h index 88a9a981a..968f38ba4 100644 --- a/include/stlink/usb.h +++ b/src/usb.h @@ -1,5 +1,5 @@ /* - * File: stlink/usb.h + * File: usb.h * Author: karl * * Created on October 1, 2011, 11:29 PM @@ -10,9 +10,9 @@ #include -#include "stlink.h" -#include "stlinkusb.h" -#include "../src/logging.h" +#include +#include "libusb_settings.h" +#include "logging.h" #ifdef __cplusplus extern "C" { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d6fe9fdd5..40d2203db 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,3 +1,7 @@ +### +# Build test executables +### + set(TESTEXEC usb sg) foreach (test ${TESTEXEC}) diff --git a/tests/flash.c b/tests/flash.c index 53032474a..903370cc3 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -3,7 +3,7 @@ #include #include -#include +#include #if defined(_MSC_VER) #include diff --git a/tests/sg.c b/tests/sg.c index 32ef55b69..1af177174 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -7,6 +7,7 @@ #include #include #include + #include #if defined(_MSC_VER) diff --git a/tests/usb.c b/tests/usb.c index a2c3ef8cd..d4098834d 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -1,4 +1,5 @@ #include + #include int main(int ac, char** av) { @@ -35,7 +36,6 @@ int main(int ac, char** av) { printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); } - printf("-- read_sram\n"); static const uint32_t sram_base = STM32_SRAM_BASE; From 6a768d36f5c95ded5fb5ebc203d0ef2fa4a28802 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Mon, 27 Apr 2020 14:41:01 +0800 Subject: [PATCH 0901/1435] Add a documentation about flashloaders and adjust clean room document version order --- doc/flashloaders.md | 54 ++++++++++ flashloaders/cleanroom.md | 211 +++++++++++++++++++------------------- 2 files changed, 160 insertions(+), 105 deletions(-) create mode 100644 doc/flashloaders.md diff --git a/doc/flashloaders.md b/doc/flashloaders.md new file mode 100644 index 000000000..6a7cb3504 --- /dev/null +++ b/doc/flashloaders.md @@ -0,0 +1,54 @@ +# Flashloaders + +## What do flashloaders do + +The on-chip FLASH of STM32 needs to be written once a byte/half word/word/double word, which would lead to a unbearably long flashing time if the process is solely done by `stlink` from the host side. Flashloaders are introduced to cooperate with `stlink` so that the flashing process is divided into two stages. In the first stage, `stlink` loads flashloaders and flash data to SRAM where busy check is not applied. In the second stage, flashloaders are kick-started, writing data from SRAM to FLASH, where a busy check is applied. Thus the write-check\_if\_busy cycle of flashing is done solely by STM32 chip, which saves considerable time in communications between `stlink` and STM32. + +As SRAM is usually less in size than FLASH, `stlink` only flashes one page (may be less if SRAM is insufficient) at a time. The whole flashing process may consist of server launches of flashloaders. + +## The flahsing process + +1. `st-flash` loads compiled binary of corresponding flashloader to SRAM by calling `stlink_flash_loader_init` in `src/flash_loader.c` +2. `st-flash` erases corresponding flash page by calling `stlink_erase_flash_page` in `common.c`. +3. `st-flash` calls `stlink_flash_loader_run` in `flash_loader.c`. In this function + + buffer of one flash page is written to SRAM following the flashloader + + the buffer start address (in SRAM) is written to register `r0` + + the target start address (in FLASH, page aligned) is written to register `r1` + + the buffer size is written to register `r2` + + the start address (for now 0x20000000) of flash loader is written to `r15` (`pc`) + + After that, launching the flashloader and waiting for a halted core (triggered by our flashloader) and confirming that flashing is completed with a zeroed `r2` +4. flashloader part: much like a `memcpy` with busy check + + copy a single unit of data from SRAM to FLASH + + (for most devices) wait until flash is not busy + + trigger a breakpoint which halts the core when finished + +## Constraints + +Thus for developers who want to modify flashloaders, the following constraints should be satisfied. + +* only thumb-1 (for stm32f0 etc) or (thumb-1 and thumb-2) (for stm32f1 etc) instructions can be used, no ARM instructions. +* no stack, since it may overwrite buffer data. +* for most devices, after writing a single unit data, wait until FLASH is not busy. +* for some devices, check if there are any errors during flashing process. +* respect unit size of a single copy. +* after flashing, trigger a breakpint to halt the core. +* a sucessful run ends with `r2` set to zero when halted. +* be sure that flashloaders are at least be capable of running at 0x20000000 (the base address of SRAM) + + +For devices that need to wait until the flash is not busy, check FLASH_SR_BUSY bit. For devices that need to check if there is any errors during flash, check FLASH\_SR\_(X)ERR where `X` can be any error state + +FLASH_SR related offset and copy unit size may be found in ST official reference manuals and/or some header files in other open source projects. Clean room document provides some of them. + + +## Debug tricks + +If you find some flashloaders to be broken or you need to write a new flashloader for new devices, the following tricks may help. + +1. Modify `WAIT_ROUNDS` marco to a bigger value so that you will have time to kill st-flash when it is waiting for a halted core. +2. run `st-flash` and kill it after the flashloader is loaded to SRAM +3. launch `st-util` and `gdb`/`lldb` +4. set a breakpoint at the base address of SRAM +5. jump to the base address and start your debug + +The tricks work because by this means, most work (flash unlock, flash erase, load flashloader to SRAM) would have been done automatically, saving time to construct a debug environment. \ No newline at end of file diff --git a/flashloaders/cleanroom.md b/flashloaders/cleanroom.md index 1bae4535d..a468efe49 100644 --- a/flashloaders/cleanroom.md +++ b/flashloaders/cleanroom.md @@ -1,232 +1,233 @@ -English version can be found below. +Original Chinese version can be found below. -# 净室工程文档 +# Clean Room Documentation English Version -代码位于的section:`.text` -编译制导添加`.syntax unified` +Code is situated in section `.text` -传入参数约定: +Shall add a compile directive at the head: `.syntax unified` -参数全部通过寄存器传递 +**Calling convention**: -`r0`: 拷贝源点起始地址 -`r1`: 拷贝终点起始地址 -`r2`: 拷贝word(4字节)数(存在例外) +All parameters would be passed over registers -程序功能:将数据从源点拷贝到终点,在拷贝完毕后触发断点以结束执行,结束时`r2`值需清零表明传输完毕。 +`r0`: the base address of the copy source +`r1`: the base address of the copy destination +`r2`: the total word (4 bytes) count to be copied (with expeptions) -限制:不可使用栈,可自由使用的临时寄存器为`R3`到`R12`。`R13`为`sp`(stack pointer),`R14`为lr(一般用于储存跳转地址),`R15`为`pc`(program counter)。 +**What the program is expected to do**: -要求:每完成一次拷贝,需等待flash完成写入,单次拷贝宽度、检查写入完成的方式见每个文件的具体要求。 +Copy data from source to destination, after which trigger a breakpint to exit. Before exit, `r2` must be cleared to zero to indicate that the copy is done. -特殊地址`flash_base`存放地址需2字节对齐。 +**Limitation**: No stack operations are permitted. Registers ranging from `r3` to `r12` are free to use. Note that `r13` is `sp`(stack pointer), `r14` is `lr`(commonly used to store jump address), `r15` is `pc`(program counter). + +**Requirement**: After every single copy, wait until the flash finishes. The detailed single copy length and the way to check can be found below. Address of `flash_base` shall be two-bytes aligned. ## stm32f0.s -例外:`r2`:拷贝half word(2字节)数 +**Exception**: `r2` stores the total half word (2 bytes) count to be copied -特殊地址定义:`flash_base`:定义为0x40022000 +`flash_base`: 0x40022000 -`FLASH_CR`: 相对`flash_base`的offset为16 +`FLASH_CR`: offset from `flash_base` is 16 -`FLASH_SR`: 相对`flash_base`的offset为12 +`FLASH_SR`: offset from `flash_base` is 12 -参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h) +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h) [https://www.st.com/resource/en/reference_manual/dm00031936-stm32f0x1stm32f0x2stm32f0x8-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00031936-stm32f0x1stm32f0x2stm32f0x8-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) -特殊要求: -每次拷贝开始前需要读出FLASH_CR处的4字节内容,将其最低bit设置为1,写回FLASH_CR。 - -每次写入数据宽度为2字节(半字)。 - -每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_SR处4字节内容,若取值为1,则说明写入尚未完成,需继续轮询等待;否则需要检查FLASH_SR处值是否为4,若非4,则应直接准备退出。 +**Special requirements**: -退出:全部拷贝执行完毕后触发断点前,将FLASH_CR处4字节内容最低bit清为0,写回FLASH_CR。 +Before every copy, read a word from FLASH_CR, set the lowest bit to 1 and write back. Copy one half word each time. +How to wait for the write process: read a word from FLASH_SR, loop until the content is not 1. After that, check FLASH_SR, proceed if the content is 4, otherwise exit. +Exit: after the copying process and before triggering the breakpoint, clear the lowest bit in FLASH_CR. ## stm32f4.s -特殊地址定义: `flash_base`:定义为0x40023c00 +`flash_base`: 0x40023c00 -`FLASH_SR`:相对flash_base的offset为0xe(14) +`FLASH_SR`: offset from `flash_base` is 0xe (14) -参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) [https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf](https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf) -特殊要求: -每次写入的数据宽度为4字节(字)。 +**Special requirements**: -每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_SR处2字节内容,若取值为1,则说明写入尚未完成,需继续轮询等待。 +Copy one word each time. +How to wait for the write process: read a half word from FLASH_SR, loop until the content is not 1. ## stm32f4lv.s -特殊地址定义:`flash_base`:定义为0x40023c00 +`flash_base`: 0x40023c00 -`FLASH_SR`:相对`flash_base`的offset为0xe (14) +`FLASH_SR`: offset from `flash_base` is 0xe (14) -参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) [https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf](https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf) -特殊要求: +**Special Requirements**: -每次写入的数据宽度为1字节(1/4字)。 +Copy one byte each time. -每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_SR处2字节内容,若取值为1,则说明写入尚未完成,需继续轮询等待。 +How to wait from the write process: read a half word from FLASH_SR, loop until the content is not 1. ## stm32f7.s -参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) [https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) -要求同stm32f4.s,额外要求在每次拷贝执行完毕、flash写入成功检测前,执行`dsb sy`指令以建立内存屏障。 - +Mostly same with `stm32f4.s`. Require establishing a memory barrier after every copy and before checking for finished writing by `dsb sy` ## stm32f7lv.s -参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) [https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) -要求基本同stm32f7.s,差异要求为每次写入的数据宽度为1字节(1/4字)。 -## stm32l0x.s +**Special Requirements**: -特殊要求: +Mostly same with `stm32f7.s`. Copy one byte each time. -每次写入的数据宽度为4字节(字) +## stm32l0x.s -无需实现检查flash写入完成功能 +**Special Requirements**: -## stm32l4.s +Copy one word each time. No wait for write. -例外:`r2`: 拷贝双字(8字节)数 +## stm32l4.s -特殊地址定义:`flash_base`: 0x40022000 +**Exception**: r2 stores the double word count to be copied. -`FLASH_BSY`:相对flash_base的offset为0x12 +`flash_base`: 0x40022000 +`FLASH_BSY`: offset from `flash_base` is 0x12 -参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h) +**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h) [https://www.st.com/resource/en/reference_manual/dm00310109-stm32l4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00310109-stm32l4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) -拷贝方式:一次性拷贝连续的8个字节(使用两个连续寄存器作中转)并写入 +**Special Requirements**: -每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_BSY处半字(2字节),若其最低位非1,可继续拷贝。 +Copy one double word each time (More than one registers are allowed). + +How to wait for the write process: read a half word from `FLASH_BSY`, loop until the lowest bit turns non-1. ## stm32lx.s -要求与stm32l0x.s相同 +Same with stm32l0x.s. -# Clean Room Documentation English Version -Code is situated in section `.text` +# 净室工程文档-原始中文版 -Shall add a compile directive at the head: `.syntax unified` +代码位于的section:`.text` +编译制导添加`.syntax unified` -**Calling convention**: +传入参数约定: -All parameters would be passed over registers +参数全部通过寄存器传递 -`r0`: the base address of the copy source -`r1`: the base address of the copy destination -`r2`: the total word (4 bytes) count to be copied (with expeptions) +`r0`: 拷贝源点起始地址 +`r1`: 拷贝终点起始地址 +`r2`: 拷贝word(4字节)数(存在例外) -**What the program is expected to do**: +程序功能:将数据从源点拷贝到终点,在拷贝完毕后触发断点以结束执行,结束时`r2`值需清零表明传输完毕。 -Copy data from source to destination, after which trigger a breakpint to exit. Before exit, `r2` must be cleared to zero to indicate that the copy is done. +限制:不可使用栈,可自由使用的临时寄存器为`R3`到`R12`。`R13`为`sp`(stack pointer),`R14`为lr(一般用于储存跳转地址),`R15`为`pc`(program counter)。 -**Limitation**: No stack operations are permitted. Registers ranging from `r3` to `r12` are free to use. Note that `r13` is `sp`(stack pointer), `r14` is `lr`(commonly used to store jump address), `r15` is `pc`(program counter). +要求:每完成一次拷贝,需等待flash完成写入,单次拷贝宽度、检查写入完成的方式见每个文件的具体要求。 -**Requirement**: After every single copy, wait until the flash finishes. The detailed single copy length and the way to check can be found below. Address of `flash_base` shall be two-bytes aligned. +特殊地址`flash_base`存放地址需2字节对齐。 ## stm32f0.s -**Exception**: `r2` stores the total half word (2 bytes) count to be copied +例外:`r2`:拷贝half word(2字节)数 -`flash_base`: 0x40022000 +特殊地址定义:`flash_base`:定义为0x40022000 -`FLASH_CR`: offset from `flash_base` is 16 +`FLASH_CR`: 相对`flash_base`的offset为16 -`FLASH_SR`: offset from `flash_base` is 12 +`FLASH_SR`: 相对`flash_base`的offset为12 -**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h) +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f0.h) [https://www.st.com/resource/en/reference_manual/dm00031936-stm32f0x1stm32f0x2stm32f0x8-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00031936-stm32f0x1stm32f0x2stm32f0x8-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) -**Special requirements**: +特殊要求: +每次拷贝开始前需要读出FLASH_CR处的4字节内容,将其最低bit设置为1,写回FLASH_CR。 -Before every copy, read a word from FLASH_CR, set the lowest bit to 1 and write back. Copy one half word each time. +每次写入数据宽度为2字节(半字)。 + +每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_SR处4字节内容,若取值为1,则说明写入尚未完成,需继续轮询等待;否则需要检查FLASH_SR处值是否为4,若非4,则应直接准备退出。 + +退出:全部拷贝执行完毕后触发断点前,将FLASH_CR处4字节内容最低bit清为0,写回FLASH_CR。 -How to wait for the write process: read a word from FLASH_SR, loop until the content is not 1. After that, check FLASH_SR, proceed if the content is 4, otherwise exit. -Exit: after the copying process and before triggering the breakpoint, clear the lowest bit in FLASH_CR. ## stm32f4.s -`flash_base`: 0x40023c00 +特殊地址定义: `flash_base`:定义为0x40023c00 -`FLASH_SR`: offset from `flash_base` is 0xe (14) +`FLASH_SR`:相对flash_base的offset为0xe(14) -**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) [https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf](https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf) +特殊要求: -**Special requirements**: +每次写入的数据宽度为4字节(字)。 -Copy one word each time. -How to wait for the write process: read a half word from FLASH_SR, loop until the content is not 1. +每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_SR处2字节内容,若取值为1,则说明写入尚未完成,需继续轮询等待。 ## stm32f4lv.s -`flash_base`: 0x40023c00 +特殊地址定义:`flash_base`:定义为0x40023c00 -`FLASH_SR`: offset from `flash_base` is 0xe (14) +`FLASH_SR`:相对`flash_base`的offset为0xe (14) -**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f4.h) [https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf](https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf) -**Special Requirements**: +特殊要求: -Copy one byte each time. +每次写入的数据宽度为1字节(1/4字)。 -How to wait from the write process: read a half word from FLASH_SR, loop until the content is not 1. +每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_SR处2字节内容,若取值为1,则说明写入尚未完成,需继续轮询等待。 ## stm32f7.s -**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) [https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) -Mostly same with `stm32f4.s`. Require establishing a memory barrier after every copy and before checking for finished writing by `dsb sy` +要求同stm32f4.s,额外要求在每次拷贝执行完毕、flash写入成功检测前,执行`dsb sy`指令以建立内存屏障。 + ## stm32f7lv.s -**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32f7.h) [https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) - -**Special Requirements**: - -Mostly same with `stm32f7.s`. Copy one byte each time. +要求基本同stm32f7.s,差异要求为每次写入的数据宽度为1字节(1/4字)。 ## stm32l0x.s -**Special Requirements**: +特殊要求: -Copy one word each time. No wait for write. +每次写入的数据宽度为4字节(字) + +无需实现检查flash写入完成功能 ## stm32l4.s -**Exception**: r2 stores the double word count to be copied. +例外:`r2`: 拷贝双字(8字节)数 -`flash_base`: 0x40022000 -`FLASH_BSY`: offset from `flash_base` is 0x12 +特殊地址定义:`flash_base`: 0x40022000 -**Reference**: [https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h) -[https://www.st.com/resource/en/reference_manual/dm00310109-stm32l4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00310109-stm32l4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) +`FLASH_BSY`:相对flash_base的offset为0x12 -**Special Requirements**: +参考:[https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/chip/stm32/registers-stm32l4.h) +[https://www.st.com/resource/en/reference_manual/dm00310109-stm32l4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf](https://www.st.com/resource/en/reference_manual/dm00310109-stm32l4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) -Copy one double word each time (More than one registers are allowed). +拷贝方式:一次性拷贝连续的8个字节(使用两个连续寄存器作中转)并写入 -How to wait for the write process: read a half word from `FLASH_BSY`, loop until the lowest bit turns non-1. +每完成一次写入,需等待flash完成写入,检查方式为读取FLASH_BSY处半字(2字节),若其最低位非1,可继续拷贝。 ## stm32lx.s -Same with stm32l0x.s. \ No newline at end of file +要求与stm32l0x.s相同 \ No newline at end of file From e87bdff95b946ebfbfed7d5157d6e3bcd32e6f67 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 27 Apr 2020 20:20:50 +0200 Subject: [PATCH 0902/1435] General Project Update - Updated project README - Updated .gitignore - Updated project contributors - Added contribution guidelines --- .gitignore | 1 + .travis.yml | 12 ++++++++ CMakeLists.txt | 1 + CONTRIBUTING.md | 49 ++++++++++++++++++++++++++++++++ README.md | 16 +++++++---- cmake/packaging/debian/copyright | 2 +- 6 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/.gitignore b/.gitignore index 23e7ddc07..09b9b33de 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ build build-mingw obj-* *.user* +.project diff --git a/.travis.yml b/.travis.yml index b7ff93ff9..3e015dd07 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ matrix: include: ### 64-bit builds ### - os: linux + env: BADGE=linux arch: x64 compiler: gcc-5 addons: @@ -11,6 +12,7 @@ matrix: sources: ['ubuntu-toolchain-r-test'] packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux + env: BADGE=linux arch: x64 compiler: gcc-7 addons: @@ -18,6 +20,7 @@ matrix: sources: ['ubuntu-toolchain-r-test'] packages: ['gcc-7', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux + env: BADGE=linux arch: x64 compiler: gcc-9 addons: @@ -25,6 +28,7 @@ matrix: sources: ['ubuntu-toolchain-r-test'] packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux + env: BADGE=linux arch: x64 compiler: clang-3.7 addons: @@ -32,6 +36,7 @@ matrix: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-3.7'] packages: ['clang-3.7', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux + env: BADGE=linux arch: x64 compiler: clang-6.0 addons: @@ -49,6 +54,7 @@ matrix: ### 32-bit builds ### - os: linux + env: BADGE=linux arch: x86 compiler: gcc-5 addons: @@ -56,6 +62,7 @@ matrix: sources: ['ubuntu-toolchain-r-test'] packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux + env: BADGE=linux arch: x86 compiler: gcc-7 addons: @@ -63,6 +70,7 @@ matrix: sources: ['ubuntu-toolchain-r-test'] packages: ['gcc-7', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux + env: BADGE=linux arch: x86 compiler: gcc-9 addons: @@ -70,6 +78,7 @@ matrix: sources: ['ubuntu-toolchain-r-test'] packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux + env: BADGE=linux arch: x86 compiler: clang-3.7 addons: @@ -77,6 +86,7 @@ matrix: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-3.7'] packages: ['clang-3.7', 'libusb-1.0.0-dev', 'libgtk-3-dev'] - os: linux + env: BADGE=linux arch: x86 compiler: clang-6.0 addons: @@ -86,6 +96,7 @@ matrix: ### macOS ### - os: osx + env: BADGE=osx compiler: gcc addons: homebrew: @@ -94,6 +105,7 @@ matrix: - libusb - gtk+3 - os: osx + env: BADGE=osx compiler: clang addons: homebrew: diff --git a/CMakeLists.txt b/CMakeLists.txt index 95e27d215..b5301fb0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -278,6 +278,7 @@ install(TARGETS st-flash DESTINATION bin) install(TARGETS st-info DESTINATION bin) install(TARGETS st-util DESTINATION bin) + ### # Additional build tasks ### diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..a9bb02661 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,49 @@ +# Contribution guidelines + +## Contributing to the stlink project +We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: + +- Reporting a bug +- Discussing the current state of the code +- Submitting a fix +- Proposing new features +- Assistance with maintaining + +We use GitHub to host code, to track issues and feature requests, as well as accept pull requests. +Report a bug by [opening a new issue]() with one of the available templates. It's that easy! + + +## Coding conventions +To read code written by other contributors can turn out to be quite demanding - a variable which seems to self-explaining, may appear cryptic to other readers. If you plan to contribute, please take this into account and feel encouraged to help others understand your code. In order to help you along, we have composed some contribution guidelines for this project. As this project already has a history you may find parts in the codebase that do not seem to comply with these guidelines, but we are trying to improve continuosly. However we can do even better, if every contributor considers the following points: + +* Naming of all source code elements as well as comments should exclusively be written in English. +* All functions and global variables should be fully explained. This includes a short description on _what_ the respective function does (but not necessarily _how_ this is achieved), an explantion of transfer parameters and/or return values (if applicable). +* Use [fixed width integer types](http://en.cppreference.com/w/c/types/integer) wherever possible and size-appropiate datatypes. +* Only make use of the datatype `char` for specific characters, otherwise use `int8_t` or `uint8_t` respectively. + + +### Coding Style +* Use 4 spaces for indentation rather than tabs (the latter results in inconsistent appearance on different platforms) +* Use `/* your comment */` formatting for multi-line comments or section titles and `// your comment` for inline comments. +* Please try to avoid special characters where possible, as they are interpreted differently on particular platforms and systems. Otherwise these may result in mojibake within the sourcecode or cause translation errors when compiling. +* Use state-of-the-art UTF-8 encoding whereever possible. + + +## Github Flow +We Use [Github Flow](https://guides.github.com/introduction/flow/index.html) which implies that all code changes happen through Pull Requests (PRs). +They are the best way to propose changes to the codebase and we actively welcome your own ones: + +1. PRs should focus on _one_ single topic. +2. Fork the repo and create your branch from `develop`. +3. Begin to implement your changes on a local or personal branch. +4. Take a look at existing PR and check if these target the same part of the codebase. + Should this be the case, you are encouraged to get in touch with the respective author and discuss on how to proceed. +5. Keep your personal feature-branch up to date with the current development branch, by merging in recent changes regularly. +6. Don't open a PR unless your contribution has evolved to a somehow completed set of changes. +7. If you've changed major features, update the documentation. +8. Ensure your PR passes our travis CI tests. +9. Issue that pull request! + + +## License +When you submit code changes, your submissions are understood to be under the same [BSD-3 License](LICENSE.md) that covers this project.
    Feel free to contact the project maintainers should there be any related questions. diff --git a/README.md b/README.md index 735712329..4bf663e34 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,12 @@ Open source version of the STMicroelectronics STlink Tools [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/stlink-org/stlink.svg)](https://github.com/stlink-org/stlink/releases/latest) -[![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.0.svg)](https://github.com/stlink-org/stlink/releases/develop) -[![Downloads](https://img.shields.io/github/downloads/stlink-org/stlink/total.svg)](https://github.com/stlink-org/stlink/releases) -[![Linux Status](https://img.shields.io/travis/stlink-org/stlink/master.svg?label=linux)](https://travis-ci.org/stlink-org/stlink) -[![macOS Status](https://img.shields.io/travis/stlink-org/stlink/master.svg?label=osx)](https://travis-ci.org/stlink-org/stlink) +[![Downloads](https://img.shields.io/github/downloads/stlink-org/stlink/total)](https://github.com/stlink-org/stlink/releases/latest) +![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.0/develop) +![GitHub activity](https://img.shields.io/github/commit-activity/m/stlink-org/stlink) +![GitHub contributors](https://img.shields.io/github/contributors/stlink-org/stlink) +[![Linux Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=linux&label=linux)](https://travis-ci.org/stlink-org/stlink) +[![macOS Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=osx&label=osx)](https://travis-ci.org/stlink-org/stlink) Recent new features and bugfixes can be found in the [Changelog](CHANGELOG.md) of this software project. @@ -104,8 +106,10 @@ When there is no executable available for your platform or you need the latest ( * The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) * Before creating a pull request, please _ALWAYS_ open a new issue for the discussion of the intended new features. Bugfixes don't require a discussion via a ticket-issue. However they should always be described in a few words as soon as they appear to help others as well. * Contributors and/or maintainers may submit comments or request changes to patch-proposals and/or pull-requests. -* **ATTENTION: _NEVER EVER_ use the '#' character to count-up single points within a listing as '#' is _exclusively_ reserved for referencing github issues and pull-requests. Otherwise you accidentally introduce false cross references within the project.** -* Please start new forks from the develop branch if possible as pull requests will go into this branch as well. +* **ATTENTION: _NEVER EVER_ use the '#' character to count-up single points within a listing as '#' is _exclusively_ reserved for referencing GitHub issues and pull-requests. Otherwise you accidentally introduce false cross references within the project.** +* Please start new forks from the develop branch, as pull requests will go into this branch as well. + +Please also refer to our [Contribution Guidelines](CONTRIBUTING.md). # Current state of the project diff --git a/cmake/packaging/debian/copyright b/cmake/packaging/debian/copyright index 4a7b110ae..4e58490f6 100644 --- a/cmake/packaging/debian/copyright +++ b/cmake/packaging/debian/copyright @@ -48,6 +48,7 @@ Copyright: 2011-2020 stlink-org Breton M. Saunders Bruno Dal Bo Burns Fisher + Cheng Guokai (Xim) [chenguokai] Chris Dew Chris Hiszpanski Chris Li @@ -153,5 +154,4 @@ Copyright: 2011-2020 stlink-org William Ransohoff [WRansohoff] Wojciech A. Koszek Woodrow Douglass - Xim [chenguokai] ... and others From 38a5c14877964e7ea272565b372576d61710790f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 27 Apr 2020 23:29:01 +0200 Subject: [PATCH 0903/1435] Updated CHANGELOG.md --- CHANGELOG.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ad6b6497..f79cd846c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,9 +26,10 @@ Features: Updates & changes: +- Define libusb version compatibility for supported operating systems via LIBUSB_API_VERSION (#211, #782, #895) - Improved argument parsing for CLI tools (#378, #922) - [doc] Updated tutorial: macOS ST-Link-v1 detection (#574, #587) -- Define libusb version compatibility for supported operating systems via LIBUSB_API_VERSION (#211, #782, #895) +- Enhanced output for error msg "addr not a multiple of pagesize, not supported" (#663, #945) - [doc] Verify correct udev configuration for device access (#764) - Added more error info to WLOGs during probe (#883) - Added check for libssp during compilation (#885) @@ -41,9 +42,15 @@ Updates & changes: - [doc] Defined version compatibility and installation instructions for macOS (commit 23c071edea45f6e8852fef52d884a680973d6d8f) - Deprecated old appveyor-mingw script (commit 97484422008df0f75c978627054776f35842a075) - Enhanced error log with file path for map_file() (#650, #879, #921) -- Refactoring: Overall option code rework (#927) -- Refactoring: Build settings / GUI-Build on UNIX-based systems if GTK3 is detected (#929) -- Reconfiguration of package build process (#931, #936, #940, commit 9b19f9225460472af9d98959b7217d0a840ee972) +- [refactoring] Overall option code rework (#927) +- [refactoring] Build settings / GUI-Build on UNIX-based systems if GTK3 is detected (#929) +- [refactoring] Reconfiguration of package build process (#931, #936, #940, commit 9b19f9225460472af9d98959b7217d0a840ee972) +- [refactoring] st-util: Removed now useless v1/v2 STLink version stuff (#934) +- [refactoring] Cleanup for option bytes and flash settings (#941) +- Added compilation guideline for MSVC toolchain (#942) +- st-util: Removal of useless v1/v2 stlink version stuff (#934) +- libusb package extraction no longer requires 7zip as an external unarchiver (commit 5db2dc4c0410ace65308cddcc03d1c0cfa4855cf) +- [refactoring] Cleanup of cmake build process (#944, #946, #947) Fixes: @@ -60,7 +67,7 @@ Fixes: - Fixed formatting for options display in st-flash & st-info (commits c783d0e777ccc83a7a8be26a4f4d3414e0478560 and 562cd2496e696dbd22950925866aac662d81ee5f) - Fixed dead loop after an unexpected unplug (#780, #812, #913) - Fixed broken build on 32-bit systems (#919, #920) -- st-flash: minor usage fix and make cmdline parsing more user friendly (#925) +- st-flash: Minor usage fix and make cmdline parsing more user friendly (#925) - Better argument parsing for CLI tools: stlink_open_usb can address v1, v2, v3 (#378, #922) - Restored functionality of make test builds (Regression) (#926, #929) - Fixed compilation error due to uninitialized cpuid (#937, #938) From ce6ffe70303cc75b663b91b0f2905821f3235a17 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 29 Apr 2020 16:24:14 +0200 Subject: [PATCH 0904/1435] Refactoring for package distribution - New cpack package-config for DEB and RPM - Toolchain file for cross-building - Script to automate MinGW cross-building - Added file headers for .cmake files - Added dpkg and rpm to required pkgs --- .travis.yml | 20 ++-- Makefile | 2 +- cmake/modules/Findlibusb.cmake | 25 +++-- cmake/modules/c_flags.cmake | 3 + cmake/modules/get_version.cmake | 8 +- cmake/modules/set_toolchain.cmake | 20 ++++ cmake/packaging/cpack_config.cmake | 108 +++++++++++-------- cmake/packaging/windows/generate_binaries.sh | 26 +++++ debian/.gitignore | 10 -- doc/compiling.md | 2 + 10 files changed, 148 insertions(+), 76 deletions(-) create mode 100644 cmake/modules/set_toolchain.cmake create mode 100644 cmake/packaging/windows/generate_binaries.sh delete mode 100644 debian/.gitignore diff --git a/.travis.yml b/.travis.yml index 3e015dd07..a66777f5f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ matrix: addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev'] + packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - os: linux env: BADGE=linux arch: x64 @@ -18,7 +18,7 @@ matrix: addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-7', 'libusb-1.0.0-dev', 'libgtk-3-dev'] + packages: ['gcc-7', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - os: linux env: BADGE=linux arch: x64 @@ -26,7 +26,7 @@ matrix: addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev'] + packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - os: linux env: BADGE=linux arch: x64 @@ -34,7 +34,7 @@ matrix: addons: apt: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-3.7'] - packages: ['clang-3.7', 'libusb-1.0.0-dev', 'libgtk-3-dev'] + packages: ['clang-3.7', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - os: linux env: BADGE=linux arch: x64 @@ -42,7 +42,7 @@ matrix: addons: apt: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] - packages: ['clang-6.0', 'libusb-1.0.0-dev', 'libgtk-3-dev'] + packages: ['clang-6.0', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] # - os: linux # arch: x64 # compiler: clang-6.0 @@ -60,7 +60,7 @@ matrix: addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev'] + packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - os: linux env: BADGE=linux arch: x86 @@ -68,7 +68,7 @@ matrix: addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-7', 'libusb-1.0.0-dev', 'libgtk-3-dev'] + packages: ['gcc-7', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - os: linux env: BADGE=linux arch: x86 @@ -76,7 +76,7 @@ matrix: addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev'] + packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - os: linux env: BADGE=linux arch: x86 @@ -84,7 +84,7 @@ matrix: addons: apt: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-3.7'] - packages: ['clang-3.7', 'libusb-1.0.0-dev', 'libgtk-3-dev'] + packages: ['clang-3.7', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - os: linux env: BADGE=linux arch: x86 @@ -92,7 +92,7 @@ matrix: addons: apt: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] - packages: ['clang-6.0', 'libusb-1.0.0-dev', 'libgtk-3-dev'] + packages: ['clang-6.0', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] ### macOS ### - os: osx diff --git a/Makefile b/Makefile index 74a4fece5..7f373ebcd 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ package: build/Release @$(MAKE) -C build/Release package test: debug - @echo "[TEST]" + @echo "[TEST] Debug" @$(MAKE) -C build/Debug test build/Debug: diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index 898820033..bc613779d 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -1,4 +1,6 @@ # Findlibusb.cmake +# Find and install external libusb library + # Once done this will define # # LIBUSB_FOUND libusb present on system @@ -8,7 +10,7 @@ include(FindPackageHandleStandardArgs) -if (APPLE) # macOS +if (APPLE) # macOS FIND_PATH( LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr /usr/local /opt @@ -25,7 +27,7 @@ if (APPLE) # macOS message(FATAL_ERROR "No libusb library found on your system! Install libusb-1.0 from Homebrew or MacPorts") endif () -elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated into the system +elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated into the system FIND_PATH( LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr/include @@ -41,7 +43,7 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated message(FATAL_ERROR "Expected libusb library not found on your system! Verify your system integrity.") endif () -elseif (WIN32) # Windows +elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-toolchain on Debian # for MinGW/MSYS/MSVC: 64-bit or 32-bit? if (CMAKE_SIZEOF_VOID_P EQUAL 8) set(ARCH 64) @@ -49,7 +51,7 @@ elseif (WIN32) # Windows set(ARCH 32) endif () - if (NOT EXISTS "/etc/debian_version") + if (WIN32 AND NOT EXISTS "/etc/debian_version") # Skip this for Debian... FIND_PATH( LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr /usr/local /opt @@ -71,12 +73,17 @@ elseif (WIN32) # Windows endif () endif () - if (NOT LIBUSB_FOUND OR EXISTS "/etc/debian_version") + if (NOT LIBUSB_FOUND) # Preparations for installing libusb library set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) - set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) - set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3rdparty/libusb-${LIBUSB_WIN_VERSION}) + if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems + set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) + set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3rdparty/libusb-${LIBUSB_WIN_VERSION}) + else (EXISTS "/etc/debian_version" AND MINGW) # ... only for cross-building on Debian + set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_SOURCE_DIR}/build-mingw/${LIBUSB_WIN_ARCHIVE}) + set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_SOURCE_DIR}/build-mingw/3rdparty/libusb-${LIBUSB_WIN_VERSION}) + endif () # Get libusb package if (EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) # ... should the package be already there (for whatever reason) @@ -107,6 +114,7 @@ elseif (WIN32) # Windows ) if (MINGW OR MSYS) + set(LIBUSB_NAME usb-1.0) find_library( LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW${ARCH}/static @@ -115,6 +123,7 @@ elseif (WIN32) # Windows ) else (MSVC) + set(LIBUSB_NAME libusb-1.0.lib) find_library( LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS${ARCH}/dll @@ -127,7 +136,7 @@ elseif (WIN32) # Windows FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) -else () # all other OS (unix-based) +else () # all other OS (unix-based) FIND_PATH( LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr /usr/local /opt diff --git a/cmake/modules/c_flags.cmake b/cmake/modules/c_flags.cmake index d6b12403b..520182e37 100644 --- a/cmake/modules/c_flags.cmake +++ b/cmake/modules/c_flags.cmake @@ -1,3 +1,6 @@ +# c_flags.cmake +# Configure C compiler flags + include(CheckCCompilerFlag) function(add_cflag_if_supported flag) diff --git a/cmake/modules/get_version.cmake b/cmake/modules/get_version.cmake index da9d76eba..b80f0c9db 100644 --- a/cmake/modules/get_version.cmake +++ b/cmake/modules/get_version.cmake @@ -1,6 +1,5 @@ -# Determine project version -# * Using Git -# * Local .version file +# get_version.cmake +# Determine project version by using Git or a local .version file set(__detect_version 0) @@ -77,13 +76,14 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") endif(GIT_DESCRIBE_RESULT EQUAL 0) endif () +## # Failure to read version via git # Possible cases: # -> git is not found or # -> /.git does not exist or # -> GIT_DESCRIBE failed or # -> version string is of invalid format - +## if (NOT GIT_FOUND OR NOT EXISTS "${PROJECT_SOURCE_DIR}/.git" OR ERROR_FLAG EQUAL 1) message(STATUS "Git and/or repository not found.") # e.g. when building from source package message(STATUS "Try to detect version from \"${PROJECT_SOURCE_DIR}/.version\" file instead...") diff --git a/cmake/modules/set_toolchain.cmake b/cmake/modules/set_toolchain.cmake new file mode 100644 index 000000000..3c40e917e --- /dev/null +++ b/cmake/modules/set_toolchain.cmake @@ -0,0 +1,20 @@ +# set_toolchain.cmake +# Toolchain file for cross-building on a Debian/Ubuntu Linux system + +### +# Set toolchain and configure target environment on the build host system +### + +# Set cross compilers to use for C and C++ +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) +set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) + +# Set path to directory with headers and libraries of the cross compiler +set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) + +# Modify default behavior of FIND_XXX() commands to search for headers and libraries +# in the target environment and search for programs in the build host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake index 522fb7f11..c81362896 100644 --- a/cmake/packaging/cpack_config.cmake +++ b/cmake/packaging/cpack_config.cmake @@ -1,67 +1,68 @@ +# cpack_config.cmake +# Configure and generate packages for distribution + ### # Configure package ### set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) +set(CPACK_PACKAGE_DESCRIPTION "Open source STM32 MCU programming toolset") +set(CPACK_PACKAGE_VENDOR "stlink-org") +set(CMAKE_PROJECT_HOMEPAGE_URL "https://github.com/stlink-org/stlink") + set(CPACK_SET_DESTDIR "ON") set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist") -if (APPLE) +if (APPLE) # macOS set(CPACK_GENERATOR "ZIP") set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-macosx-amd64") set(CPACK_INSTALL_PREFIX "") -elseif (WIN32) ### TODO: Binary build config for windows... + +elseif (WIN32 AND NOT EXISTS "/etc/debian_version") # Windows set(CPACK_GENERATOR "ZIP") set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-win32") set(CPACK_INSTALL_PREFIX "") - # Sample toolchain file for building for Windows from a Debian/Ubuntu Linux system. - # Typical usage: - # *) install cross compiler: `sudo apt-get install mingw-w64` - # *) cd build - # *) cmake -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw64.cmake .. - # *) cmake -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake .. - - #set(CMAKE_SYSTEM_NAME Windows) - #set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) - #set(TOOLCHAIN_PREFIX i686-w64-mingw32) - - # cross compilers to use for C and C++ - #set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) - #set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) - #set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) - - # target environment on the build host system - # set 1st to dir with the cross compiler's C/C++ headers/libs - #set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) - - # modify default behavior of FIND_XXX() commands to - # search for headers/libs in the target environment and - # search for programs in the build host environment - #set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - #set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) - #set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - -elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND EXISTS "/etc/debian_version") +elseif (WIN32) # Windows cross-build on Debian/Ubuntu + set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_SOURCE_DIR}/build/Release/dist") + set(CPACK_GENERATOR "ZIP") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-${TOOLCHAIN_PREFIX}") + set(CPACK_INSTALL_PREFIX "") + +elseif (EXISTS "/etc/debian_version") # Package-build is available on Debian/Ubuntu only message(STATUS "Debian-based Linux OS detected") - ### Debian-specific - set(CPACK_GENERATOR "DEB") - set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "Open source STM32 MCU programming toolset") - set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/stlink-org/stlink") - set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Luca Boccassi") - set(CPACK_PACKAGE_CONTACT "bluca@debian.org") + set(CPACK_GENERATOR "DEB;RPM") # RPM requires package `rpm` - ## Set debian_revision number - # Convention: Restart the debian_revision at 1 each time the upstream_version is increased. - set(CPACK_DEBIAN_PACKAGE_RELEASE "0") + ### + # Debian (DEB) + ### + + # CPACK_DEB_PACKAGE_NAME --> Default: CPACK_PACKAGE_NAME - ## Debian package name + ## DEB package file name # CPack DEB generator generates package file name in deb format: # _-_.deb set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) + # CPACK_DEBIAN_PACKAGE_VERSION --> Default: CPACK_PACKAGE_VERSION + + ## Set debian_revision number + # Convention: Restart the debian_revision at 1 each time the upstream_version is increased. + set(CPACK_DEBIAN_PACKAGE_RELEASE "1") + + # CPACK_DEBIAN_PACKAGE_ARCHITECTURE --> Default: Output of dpkg --print-architecture + set(CPACK_DEBIAN_PACKAGE_DEPENDS "pkg-config, build-essential, debhelper (>=9), cmake (>= 3.4.2), libusb-1.0-0-dev (>= 1.0.20)") + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Luca Boccassi ") + # CPACK_DEBIAN_PACKAGE_DESCRIPTION --> Default: CPACK_DEBIAN_PACKAGE_DESCRIPTION (as it is set) + # CPACK_DEBIAN_PACKAGE_SECTION --> Default: “devel” + # CPACK_DEBIAN_ARCHIVE_TYPE --> Default: “gnutar” + # CPACK_DEBIAN_COMPRESSION_TYPE --> Default: “gzip” + # CPACK_DEBIAN_PACKAGE_PRIORITY --> Default: “optional” + # CPACK_DEBIAN_PACKAGE_HOMEPAGE --> Default: CMAKE_PROJECT_HOMEPAGE_URL + set(CPACK_DEBIAN_PACKAGE_SUGGESTS "libgtk-3-dev, pandoc") + ## Add CHANGELOG in Debian-specific format ### TODO @@ -71,15 +72,36 @@ elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND EXISTS "/etc/debian_version") # Include a postinst-script set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/cmake/packaging/debian/postinst") - ### rpm-specific ### TODO: Package config for opensuse should go here... + ### + # Slackware & Redhat (RPM) + ### + + # CPACK_RPM_PACKAGE_SUMMARY --> Default: CPACK_PACKAGE_DESCRIPTION_SUMMARY + # CPACK_RPM_PACKAGE_NAME --> Default: CPACK_PACKAGE_NAME + + ## RPM package file name + # Allow rpmbuild to generate package file name + set(CPACK_RPM_FILE_NAME RPM-DEFAULT) + + # CPACK_RPM_PACKAGE_VERSION --> Default: CPACK_PACKAGE_VERSION + # CPACK_RPM_PACKAGE_ARCHITECTURE --> Default: Native architecture output by uname -m + + ## Set rpm revision number + # Convention: Restart the debian_revision at 1 each time the upstream_version is increased. + set(CPACK_RPM_PACKAGE_RELEASE "1") + set(CPACK_RPM_PACKAGE_LICENSE "BSD-3") + # CPACK_RPM_PACKAGE_GROUP --> Default: “unknown” (RPM Groups are deprecated on Fedora) + # CPACK_RPM_PACKAGE_VENDOR --> Default: CPACK_PACKAGE_VENDOR (as it is set) + # CPACK_RPM_PACKAGE_URL --> Default: CMAKE_PROJECT_HOMEPAGE_URL + set(CPACK_RPM_PACKAGE_DESCRIPTION CPACK_DEBIAN_PACKAGE_DESCRIPTION) else () - ### TODO: Package config for fedora should go here... + # No package configuration on other platforms ... endif () ### -# Build package +# Build packages ### include(CPack) diff --git a/cmake/packaging/windows/generate_binaries.sh b/cmake/packaging/windows/generate_binaries.sh new file mode 100644 index 000000000..ba5b965f5 --- /dev/null +++ b/cmake/packaging/windows/generate_binaries.sh @@ -0,0 +1,26 @@ +### +# Build package with binaries for Windows +### + +# Install this cross-compiler toolchain: +#sudo apt-get install mingw-w64 + +# x86_64 +mkdir build-mingw +cd build-mingw +cmake -DCMAKE_SYSTEM_NAME=Windows \ + -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=./cmake/modules/set_toolchain.cmake .. +make package +cd .. +rm -rf build-mingw + +# i686 +mkdir build-mingw +cd build-mingw +cmake -DCMAKE_SYSTEM_NAME=Windows \ + -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=./cmake/modules/set_toolchain.cmake .. +make package +cd .. +rm -rf build-mingw diff --git a/debian/.gitignore b/debian/.gitignore deleted file mode 100644 index 7624d1c9b..000000000 --- a/debian/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.debhelper -files -debhelper-build-stamp -*.log -*.substvars -libstlink-dev -libstlink -stlink-gui -stlink-tools -tmp diff --git a/doc/compiling.md b/doc/compiling.md index 65d2510d0..3c8b78d73 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -87,6 +87,8 @@ Install the following packages from your package repository: * `gcc` or `clang` or `mingw32-gcc` or `mingw64-gcc` (C-compiler; very likely gcc is already present) * `build-essential` (on Debian based distros (debian, ubuntu)) * `cmake` (3.4.2 or later, use the latest version available from the repository) +* `dpkg` +* `rpm` * `pkg-config` * `libusb-1.0` * `libusb-1.0-0-dev` (development headers for building) From 06a5d716b82b2e897c1c54682866c1dbef55e848 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Wed, 29 Apr 2020 22:40:06 +0800 Subject: [PATCH 0905/1435] Remove all 'my' in tag name --- flashloaders/linker.ld | 2 +- flashloaders/stm32f0.s | 12 ++++++------ flashloaders/stm32f4.s | 10 +++++----- flashloaders/stm32f4lv.s | 10 +++++----- flashloaders/stm32f7.s | 10 +++++----- flashloaders/stm32f7lv.s | 10 +++++----- flashloaders/stm32l0x.s | 10 +++++----- flashloaders/stm32l4.s | 10 +++++----- flashloaders/stm32lx.s | 10 +++++----- src/flash_loader.c | 2 ++ 10 files changed, 44 insertions(+), 42 deletions(-) diff --git a/flashloaders/linker.ld b/flashloaders/linker.ld index 5bc738966..4d06433ea 100644 --- a/flashloaders/linker.ld +++ b/flashloaders/linker.ld @@ -1,5 +1,5 @@ /*. Entry Point *./ -ENTRY( mycopy ) +ENTRY( copy ) /*. Specify the memory areas .*/ diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index 3dd0ae6e8..6c4b8588f 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -1,8 +1,8 @@ .syntax unified .text - .global mycopy -mycopy: + .global copy +copy: ldr r7, =flash_base ldr r4, [r7] ldr r7, =flash_off_cr @@ -12,7 +12,7 @@ mycopy: ldr r5, [r7] adds r5, r5, r4 -myloop: +loop: # FLASH_CR ^= 1 ldr r7, =0x1 ldr r3, [r6] @@ -37,15 +37,15 @@ mywait: # exit if FLASH_SR != 4 ldr r7, =0x4 tst r3, r7 - bne myexit + bne exit # loop if r2 != 0 ldr r7, =0x1 subs r2, r2, r7 cmp r2, #0 - bne myloop + bne loop -myexit: +exit: # FLASH_CR &= ~1 ldr r7, =0x1 ldr r3, [r6] diff --git a/flashloaders/stm32f4.s b/flashloaders/stm32f4.s index 836f6e1f2..b4e0f4913 100644 --- a/flashloaders/stm32f4.s +++ b/flashloaders/stm32f4.s @@ -1,13 +1,13 @@ .syntax unified .text - .global mycopy -mycopy: + .global copy +copy: ldr r12, flash_base ldr r10, flash_off_sr add r10, r10, r12 -myloop: +loop: # copy 4 bytes ldr r3, [r0] str r3, [r1] @@ -24,9 +24,9 @@ mywait: # loop if r2 != 0 sub r2, r2, #1 cmp r2, #0 - bne myloop + bne loop -myexit: +exit: bkpt .align 2 diff --git a/flashloaders/stm32f4lv.s b/flashloaders/stm32f4lv.s index 4ba351faa..f5cc29841 100644 --- a/flashloaders/stm32f4lv.s +++ b/flashloaders/stm32f4lv.s @@ -1,8 +1,8 @@ .syntax unified .text - .global mycopy -mycopy: + .global copy +copy: ldr r12, flash_base ldr r10, flash_off_sr add r10, r10, r12 @@ -13,7 +13,7 @@ mycopy: # tip 2: r2 is always a power of 2 mov r2, r2, lsl#2 -myloop: +loop: # copy 1 byte ldrb r3, [r0] strb r3, [r1] @@ -30,9 +30,9 @@ mywait: # loop if r2 != 0 sub r2, r2, #1 cmp r2, #0 - bne myloop + bne loop -myexit: +exit: bkpt .align 2 diff --git a/flashloaders/stm32f7.s b/flashloaders/stm32f7.s index 3f02e75f8..8694d864e 100644 --- a/flashloaders/stm32f7.s +++ b/flashloaders/stm32f7.s @@ -1,13 +1,13 @@ .syntax unified .text - .global mycopy -mycopy: + .global copy +copy: ldr r12, flash_base ldr r10, flash_off_sr add r10, r10, r12 -myloop: +loop: # copy 4 bytes ldr r3, [r0] str r3, [r1] @@ -27,9 +27,9 @@ mywait: # loop if r2 != 0 sub r2, r2, #1 cmp r2, #0 - bne myloop + bne loop -myexit: +exit: bkpt .align 2 diff --git a/flashloaders/stm32f7lv.s b/flashloaders/stm32f7lv.s index d82726eeb..b48e40f0d 100644 --- a/flashloaders/stm32f7lv.s +++ b/flashloaders/stm32f7lv.s @@ -1,8 +1,8 @@ .syntax unified .text - .global mycopy -mycopy: + .global copy +copy: ldr r12, flash_base ldr r10, flash_off_sr add r10, r10, r12 @@ -13,7 +13,7 @@ mycopy: # tip 2: r2 is always a power of 2 mov r2, r2, lsl#2 -myloop: +loop: # copy 1 byte ldrb r3, [r0] strb r3, [r1] @@ -33,9 +33,9 @@ mywait: # loop if r2 != 0 sub r2, r2, #1 cmp r2, #0 - bne myloop + bne loop -myexit: +exit: bkpt .align 2 diff --git a/flashloaders/stm32l0x.s b/flashloaders/stm32l0x.s index 893aa6f9b..f9c257e2e 100644 --- a/flashloaders/stm32l0x.s +++ b/flashloaders/stm32l0x.s @@ -1,9 +1,9 @@ .syntax unified .text - .global mycopy -mycopy: -myloop: + .global copy +copy: +loop: # copy 4 bytes ldr r3, [r0] str r3, [r1] @@ -16,7 +16,7 @@ myloop: ldr r7, =1 subs r2, r2, r7 cmp r2, #0 - bne myloop + bne loop -myexit: +exit: bkpt diff --git a/flashloaders/stm32l4.s b/flashloaders/stm32l4.s index 16c6d1063..c68198bfa 100644 --- a/flashloaders/stm32l4.s +++ b/flashloaders/stm32l4.s @@ -1,13 +1,13 @@ .syntax unified .text - .global mycopy -mycopy: + .global copy +copy: ldr r12, flash_base ldr r10, flash_off_bsy add r10, r10, r12 -myloop: +loop: # copy 8 bytes ldr r3, [r0] ldr r4, [r0, #4] @@ -26,9 +26,9 @@ mywait: # loop if r2 != 0 sub r2, r2, #1 cmp r2, #0 - bne myloop + bne loop -myexit: +exit: bkpt .align 2 diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index 893aa6f9b..f9c257e2e 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -1,9 +1,9 @@ .syntax unified .text - .global mycopy -mycopy: -myloop: + .global copy +copy: +loop: # copy 4 bytes ldr r3, [r0] str r3, [r1] @@ -16,7 +16,7 @@ myloop: ldr r7, =1 subs r2, r2, r7 cmp r2, #0 - bne myloop + bne loop -myexit: +exit: bkpt diff --git a/src/flash_loader.c b/src/flash_loader.c index a3fd2cefd..80f5c262c 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -7,6 +7,8 @@ #define FLASH_REGS_BANK2_OFS 0x40 #define FLASH_BANK2_START_ADDR 0x08080000 +/* DO NOT MODIFY SOURCECODE DIRECTLY, EDIT ASSEMBLY FILES INSTEAD */ + /* flashloaders/stm32f0.s -- compiled with thumb2 */ static const uint8_t loader_code_stm32vl[] = { 0x16, 0x4f, 0x3c, 0x68, From 1f9724e8216ecc8205dffde900767f39659ce0db Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 29 Apr 2020 17:08:41 +0200 Subject: [PATCH 0906/1435] Removed deprecated debian pkg config settings --- {debian => cmake/packaging/debian}/rules | 0 debian/compat | 1 - debian/control | 53 ---------- debian/gbp.conf | 7 -- debian/libstlink-dev.install | 4 - debian/libstlink1.install | 1 - debian/libstlink1.symbols | 125 ----------------------- debian/source/format | 1 - debian/stlink-gui.install | 4 - debian/stlink-tools.install | 3 - debian/stlink-tools.manpages | 1 - debian/watch | 3 - 12 files changed, 203 deletions(-) rename {debian => cmake/packaging/debian}/rules (100%) delete mode 100644 debian/compat delete mode 100644 debian/control delete mode 100644 debian/gbp.conf delete mode 100644 debian/libstlink-dev.install delete mode 100644 debian/libstlink1.install delete mode 100644 debian/libstlink1.symbols delete mode 100644 debian/source/format delete mode 100644 debian/stlink-gui.install delete mode 100644 debian/stlink-tools.install delete mode 100644 debian/stlink-tools.manpages delete mode 100644 debian/watch diff --git a/debian/rules b/cmake/packaging/debian/rules similarity index 100% rename from debian/rules rename to cmake/packaging/debian/rules diff --git a/debian/compat b/debian/compat deleted file mode 100644 index ec635144f..000000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/debian/control b/debian/control deleted file mode 100644 index 3c1e9700f..000000000 --- a/debian/control +++ /dev/null @@ -1,53 +0,0 @@ -Source: stlink -Priority: optional -Maintainer: Luca Bocassi -Build-Depends: debhelper (>= 9), cmake, libusb-1.0-0-dev, libgtk-3-dev -Standards-Version: 4.1.3 -Section: electronics -Homepage: https://github.com/stlink-org/stlink -Vcs-Git: https://github.com/stlink-org/stlink.git -Vcs-Browser: https://github.com/stlink-org/stlink - -Package: libstlink-dev -Section: libdevel -Architecture: any -Depends: libstlink1 (= ${binary:Version}), ${misc:Depends} -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. - . - This package contains the development files for stlink. - -Package: libstlink1 -Section: libs -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Breaks: libstlink -Replaces: libstlink -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. - . - This package contains the shared library for stlink. - -Package: stlink-tools -Architecture: any -Depends: libstlink1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} -Breaks: libstlink -Replaces: libstlink -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. - . - This package contains commandline utilities for stlink, and modprobe and - udev rules. - -Package: stlink-gui -Architecture: any -Depends: libstlink1 (= ${binary:Version}), stlink-tools (= ${binary:Version}), - ${shlibs:Depends}, ${misc:Depends} -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. - . - This package contains a GUI tool for stlink. diff --git a/debian/gbp.conf b/debian/gbp.conf deleted file mode 100644 index 418e536e9..000000000 --- a/debian/gbp.conf +++ /dev/null @@ -1,7 +0,0 @@ -[buildpackage] -upstream-tag = %(version)s -debian-branch = debian - -[dch] -git-log = --first-parent -customizations = /usr/share/doc/git-buildpackage/examples/wrap_cl.py diff --git a/debian/libstlink-dev.install b/debian/libstlink-dev.install deleted file mode 100644 index 18fd98b03..000000000 --- a/debian/libstlink-dev.install +++ /dev/null @@ -1,4 +0,0 @@ -usr/include/* -usr/lib/*/lib*.a -usr/lib/*/pkg-config/* -usr/lib/*/lib*.so diff --git a/debian/libstlink1.install b/debian/libstlink1.install deleted file mode 100644 index 3ddde5841..000000000 --- a/debian/libstlink1.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/*/lib*.so.* diff --git a/debian/libstlink1.symbols b/debian/libstlink1.symbols deleted file mode 100644 index 51fa9bdb1..000000000 --- a/debian/libstlink1.symbols +++ /dev/null @@ -1,125 +0,0 @@ -libstlink.so.1 libstlink1 #MINVER# - _parse_version@Base 1.5.0 - _stlink_sg_close@Base 1.5.0 - _stlink_sg_core_id@Base 1.5.0 - _stlink_sg_current_mode@Base 1.5.0 - _stlink_sg_enter_jtag_mode@Base 1.5.0 - _stlink_sg_enter_swd_mode@Base 1.5.0 - _stlink_sg_exit_debug_mode@Base 1.5.0 - _stlink_sg_exit_dfu_mode@Base 1.5.0 - _stlink_sg_force_debug@Base 1.5.0 - _stlink_sg_jtag_reset@Base 1.5.0 - _stlink_sg_read_all_regs@Base 1.5.0 - _stlink_sg_read_debug32@Base 1.5.0 - _stlink_sg_read_mem32@Base 1.5.0 - _stlink_sg_read_reg@Base 1.5.0 - _stlink_sg_reset@Base 1.5.0 - _stlink_sg_run@Base 1.5.0 - _stlink_sg_status@Base 1.5.0 - _stlink_sg_step@Base 1.5.0 - _stlink_sg_version@Base 1.5.0 - _stlink_sg_write_debug32@Base 1.5.0 - _stlink_sg_write_mem32@Base 1.5.0 - _stlink_sg_write_mem8@Base 1.5.0 - _stlink_sg_write_reg@Base 1.5.0 - _stlink_usb_close@Base 1.5.0 - _stlink_usb_core_id@Base 1.5.0 - _stlink_usb_current_mode@Base 1.5.0 - _stlink_usb_enter_swd_mode@Base 1.5.0 - _stlink_usb_exit_debug_mode@Base 1.5.0 - _stlink_usb_exit_dfu_mode@Base 1.5.0 - _stlink_usb_force_debug@Base 1.5.0 - _stlink_usb_jtag_reset@Base 1.5.0 - _stlink_usb_read_all_regs@Base 1.5.0 - _stlink_usb_read_all_unsupported_regs@Base 1.5.0 - _stlink_usb_read_debug32@Base 1.5.0 - _stlink_usb_read_mem32@Base 1.5.0 - _stlink_usb_read_reg@Base 1.5.0 - _stlink_usb_read_unsupported_reg@Base 1.5.0 - _stlink_usb_reset@Base 1.5.0 - _stlink_usb_run@Base 1.5.0 - _stlink_usb_set_swdclk@Base 1.5.0 - _stlink_usb_status@Base 1.5.0 - _stlink_usb_step@Base 1.5.0 - _stlink_usb_target_voltage@Base 1.5.0 - _stlink_usb_version@Base 1.5.0 - _stlink_usb_write_debug32@Base 1.5.0 - _stlink_usb_write_mem32@Base 1.5.0 - _stlink_usb_write_mem8@Base 1.5.0 - _stlink_usb_write_reg@Base 1.5.0 - _stlink_usb_write_unsupported_reg@Base 1.5.0 - calculate_F4_sectornum@Base 1.5.0 - calculate_F7_sectornum@Base 1.5.0 - calculate_L4_page@Base 1.5.0 - is_bigendian@Base 1.5.0 - read_uint16@Base 1.5.0 - read_uint32@Base 1.5.0 - send_recv@Base 1.5.0 - send_usb_data_only@Base 1.5.0 - send_usb_mass_storage_command@Base 1.5.0 - stlink_calculate_pagesize@Base 1.5.0 - stlink_chip_id@Base 1.5.0 - stlink_chipid_get_params@Base 1.5.0 - stlink_close@Base 1.5.0 - stlink_clr_hw_bp@Base 1.5.0 - stlink_core_id@Base 1.5.0 - stlink_core_stat@Base 1.5.0 - stlink_cpu_id@Base 1.5.0 - stlink_current_mode@Base 1.5.0 - stlink_enter_swd_mode@Base 1.5.0 - stlink_erase_flash_mass@Base 1.5.0 - stlink_erase_flash_page@Base 1.5.0 - stlink_exit_debug_mode@Base 1.5.0 - stlink_exit_dfu_mode@Base 1.5.0 - stlink_fcheck_flash@Base 1.5.0 - stlink_flash_loader_init@Base 1.5.0 - stlink_flash_loader_run@Base 1.5.0 - stlink_flash_loader_write_to_sram@Base 1.5.0 - stlink_force_debug@Base 1.5.0 - stlink_fread@Base 1.5.0 - stlink_fwrite_flash@Base 1.5.0 - stlink_fwrite_sram@Base 1.5.0 - stlink_get_erased_pattern@Base 1.5.0 - stlink_is_core_halted@Base 1.5.0 - stlink_jtag_reset@Base 1.5.0 - stlink_load_device_params@Base 1.5.0 - stlink_mwrite_flash@Base 1.5.0 - stlink_mwrite_sram@Base 1.5.0 - stlink_open_usb@Base 1.5.0 - stlink_parse_ihex@Base 1.5.0 - stlink_print_data@Base 1.5.0 - stlink_probe_usb@Base 1.5.0 - stlink_probe_usb_free@Base 1.5.0 - stlink_q@Base 1.5.0 - stlink_read_all_regs@Base 1.5.0 - stlink_read_all_unsupported_regs@Base 1.5.0 - stlink_read_debug32@Base 1.5.0 - stlink_read_mem32@Base 1.5.0 - stlink_read_reg@Base 1.5.0 - stlink_read_unsupported_reg@Base 1.5.0 - stlink_reset@Base 1.5.0 - stlink_run@Base 1.5.0 - stlink_run_at@Base 1.5.0 - stlink_set_hw_bp@Base 1.5.0 - stlink_set_swdclk@Base 1.5.0 - stlink_stat@Base 1.5.0 - stlink_status@Base 1.5.0 - stlink_step@Base 1.5.0 - stlink_target_voltage@Base 1.5.0 - stlink_v1_open@Base 1.5.0 - stlink_v1_open_inner@Base 1.5.0 - stlink_verify_write_flash@Base 1.5.0 - stlink_version@Base 1.5.0 - stlink_write_debug32@Base 1.5.0 - stlink_write_dreg@Base 1.5.0 - stlink_write_flash@Base 1.5.0 - stlink_write_mem32@Base 1.5.0 - stlink_write_mem8@Base 1.5.0 - stlink_write_reg@Base 1.5.0 - stlink_write_unsupported_reg@Base 1.5.0 - stm32l1_write_half_pages@Base 1.5.0 - ugly_init@Base 1.5.0 - ugly_log@Base 1.5.0 - write_buffer_to_sram@Base 1.5.0 - write_uint16@Base 1.5.0 - write_uint32@Base 1.5.0 diff --git a/debian/source/format b/debian/source/format deleted file mode 100644 index 89ae9db8f..000000000 --- a/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (native) diff --git a/debian/stlink-gui.install b/debian/stlink-gui.install deleted file mode 100644 index b419ac054..000000000 --- a/debian/stlink-gui.install +++ /dev/null @@ -1,4 +0,0 @@ -/usr/bin/stlink-gui* -/usr/share/stlink/stlink-gui.ui -/usr/share/applications/stlink-gui.desktop -/usr/share/icons/hicolor/scalable/apps/stlink-gui.svg diff --git a/debian/stlink-tools.install b/debian/stlink-tools.install deleted file mode 100644 index ca875a0e6..000000000 --- a/debian/stlink-tools.install +++ /dev/null @@ -1,3 +0,0 @@ -/usr/bin/st-* -lib/udev/rules.d/*.rules -etc/modprobe.d/*.conf diff --git a/debian/stlink-tools.manpages b/debian/stlink-tools.manpages deleted file mode 100644 index 6a461c09e..000000000 --- a/debian/stlink-tools.manpages +++ /dev/null @@ -1 +0,0 @@ -doc/man/st-*.1 diff --git a/debian/watch b/debian/watch deleted file mode 100644 index 20ad1260e..000000000 --- a/debian/watch +++ /dev/null @@ -1,3 +0,0 @@ -version=3 -opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/-$1\.tar\.gz/ \ - https://github.com/stlink-org/stlink/tags .*/v?(\d\S+)\.tar\.gz From 9b478a04e0d105f037cda2c29617409dc1f55a36 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 29 Apr 2020 19:20:47 +0200 Subject: [PATCH 0907/1435] Simplified subdir structure for packaging --- cmake/packaging/CMakeLists.txt | 5 ++--- cmake/packaging/{debian => deb}/CMakeLists.txt | 0 cmake/packaging/{debian => deb}/changelog | 0 cmake/packaging/{debian => deb}/copyright | 0 cmake/packaging/{debian => deb}/postinst | 0 cmake/packaging/{debian => deb}/rules | 0 cmake/packaging/opensuse/CMakeLists.txt | 0 cmake/packaging/{fedora => rpm}/CMakeLists.txt | 0 doc/compiling.md | 5 ++--- 9 files changed, 4 insertions(+), 6 deletions(-) rename cmake/packaging/{debian => deb}/CMakeLists.txt (100%) rename cmake/packaging/{debian => deb}/changelog (100%) rename cmake/packaging/{debian => deb}/copyright (100%) rename cmake/packaging/{debian => deb}/postinst (100%) rename cmake/packaging/{debian => deb}/rules (100%) delete mode 100644 cmake/packaging/opensuse/CMakeLists.txt rename cmake/packaging/{fedora => rpm}/CMakeLists.txt (100%) diff --git a/cmake/packaging/CMakeLists.txt b/cmake/packaging/CMakeLists.txt index 431c85d2d..1cf640552 100644 --- a/cmake/packaging/CMakeLists.txt +++ b/cmake/packaging/CMakeLists.txt @@ -1,6 +1,5 @@ -add_subdirectory(debian) -add_subdirectory(fedora) -add_subdirectory(opensuse) +add_subdirectory(deb) +add_subdirectory(rpm) add_subdirectory(windows) include(cpack_config.cmake) diff --git a/cmake/packaging/debian/CMakeLists.txt b/cmake/packaging/deb/CMakeLists.txt similarity index 100% rename from cmake/packaging/debian/CMakeLists.txt rename to cmake/packaging/deb/CMakeLists.txt diff --git a/cmake/packaging/debian/changelog b/cmake/packaging/deb/changelog similarity index 100% rename from cmake/packaging/debian/changelog rename to cmake/packaging/deb/changelog diff --git a/cmake/packaging/debian/copyright b/cmake/packaging/deb/copyright similarity index 100% rename from cmake/packaging/debian/copyright rename to cmake/packaging/deb/copyright diff --git a/cmake/packaging/debian/postinst b/cmake/packaging/deb/postinst similarity index 100% rename from cmake/packaging/debian/postinst rename to cmake/packaging/deb/postinst diff --git a/cmake/packaging/debian/rules b/cmake/packaging/deb/rules similarity index 100% rename from cmake/packaging/debian/rules rename to cmake/packaging/deb/rules diff --git a/cmake/packaging/opensuse/CMakeLists.txt b/cmake/packaging/opensuse/CMakeLists.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/cmake/packaging/fedora/CMakeLists.txt b/cmake/packaging/rpm/CMakeLists.txt similarity index 100% rename from cmake/packaging/fedora/CMakeLists.txt rename to cmake/packaging/rpm/CMakeLists.txt diff --git a/doc/compiling.md b/doc/compiling.md index 3c8b78d73..e20cbca83 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -85,10 +85,9 @@ Install the following packages from your package repository: * `git` * `gcc` or `clang` or `mingw32-gcc` or `mingw64-gcc` (C-compiler; very likely gcc is already present) -* `build-essential` (on Debian based distros (debian, ubuntu)) +* `build-essential` (on Debian based distros (Debian, Ubuntu)) * `cmake` (3.4.2 or later, use the latest version available from the repository) -* `dpkg` -* `rpm` +* `rpm` (on Debian based distros (Debian, Ubuntu), needed for package build with `make package`) * `pkg-config` * `libusb-1.0` * `libusb-1.0-0-dev` (development headers for building) From e952bcdb339cb0e65dc3af65d559a1a304152dab Mon Sep 17 00:00:00 2001 From: Rafael Lee Date: Wed, 29 Apr 2020 01:16:06 +0800 Subject: [PATCH 0908/1435] Add function to get number from char* like 0xff, 12, 1k, 1M, 0b1001 --- src/tools/flash_opts.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 544d4ad90..f635fa04c 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -11,6 +11,45 @@ static bool starts_with(const char * str, const char * prefix) { return (0 == strncmp(str, prefix, n)); } +// support positive integer from 0 to 0x7fffffff +// support decimal, hexadecimal, octal, binary format like 0xff 12 1k 1M, 0b1001 +// negative numbers are not supported +static int32_t get_integer_from_char_array (const char * const str) { + int32_t value; + char *tail; + + // hexadecimal + if ((strncmp ("0x", str, 2) == 0) || (strncmp ("0X", str, 2) == 0)) { + value = strtoul (str + 2, &tail, 16); + } + // binary + else if ((strncmp ("0b", str, 2) == 0) || (strncmp ("0B", str, 2) == 0)) { + value = strtoul (str + 2, &tail, 2); + } + // octal + else if ((strncmp ("0", str, 1) == 0) || (strncmp ("0", str, 1) == 0)) { + value = strtoul (str + 1, &tail, 8); + } + // decimal + else { + value = strtoul (str, &tail, 10); + } + + if (((tail[0] == 'k') || (tail[0] == 'K')) && (tail[1] == '\0')) { + return value * 1024; + } + else if (((tail[0] == 'm') || (tail[0] == 'M')) && (tail[1] == '\0')) { + return value * 1024 * 1024; + } + else if (tail[0] == '\0') { + return value; + } + else { + return -1; + } + return value; +} + static int invalid_args(const char *expected) { fprintf(stderr, "*** Error: Expected args for this command: %s\n", expected); return -1; @@ -22,6 +61,7 @@ static int bad_arg(const char *arg) { } int flash_get_opts(struct flash_opts* o, int ac, char** av) { + bool serial_specified = false; // defaults memset(o, 0, sizeof(*o)); From 9fdcc0cc3d1bc47734f28082496e1123409411d7 Mon Sep 17 00:00:00 2001 From: Rafael Lee Date: Wed, 29 Apr 2020 02:11:24 +0800 Subject: [PATCH 0909/1435] Modify strtoul with only one encoding to more user friendly interface --- src/tools/flash_opts.c | 49 +++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index f635fa04c..781188905 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -61,7 +61,6 @@ static int bad_arg(const char *arg) { } int flash_get_opts(struct flash_opts* o, int ac, char** av) { - bool serial_specified = false; // defaults memset(o, 0, sizeof(*o)); @@ -146,26 +145,10 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } else if ( starts_with(av[0], "--flash=") ) { const char *arg = av[0] + strlen("--flash="); - char *ep = 0; - - o->flash_size = (uint32_t)strtoul(arg,&ep,0); - while ( *ep ) { - switch ( *ep++ ) { - case 0: - break; - case 'k': - case 'K': - o->flash_size *= 1024u; - break; - case 'm': - case 'M': - o->flash_size *= 1024u * 1024u; - break; - default: - fprintf(stderr,"Invalid --flash=%s\n",arg); - return -1; - } - } + + int32_t flash_size = get_integer_from_char_array(arg); + if (flash_size < 0) return bad_arg("--flash"); + else o->flash_size = (size_t) flash_size; } else { break; // non-option found @@ -201,7 +184,6 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { av++; } - char * tail; switch(o->cmd) { case FLASH_CMD_NONE: // no command found return -1; @@ -215,22 +197,31 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { if (ac != 3) return invalid_args("read "); if (ac != 3) return -1; o->filename = av[0]; - o->addr = (uint32_t) strtoul(av[1], &tail, 16); - if (tail[0] != '\0') return bad_arg("addr"); - o->size = strtoul(av[2], &tail, 16); - if (tail[0] != '\0') return bad_arg("size"); + int32_t address = get_integer_from_char_array(av[1]); + if(address < 0) return bad_arg("addr"); + else o->addr = (stm32_addr_t) address; + + int32_t size = get_integer_from_char_array(av[2]); + if(size < 0) return bad_arg("size"); + else o->size = (size_t) size; + break; case FLASH_CMD_WRITE: if (o->area == FLASH_OPTION_BYTES){ if (ac != 1) return -1; - o->val = (uint32_t)strtoul(av[0], &tail, 16); + + int32_t val = get_integer_from_char_array(av[0]); + if(val < 0) return bad_arg("val"); + else o->val = (uint32_t) val; + } else if (o->format == FLASH_FORMAT_BINARY) { // expect filename and addr if (ac != 2) return invalid_args("write "); o->filename = av[0]; - o->addr = (uint32_t) strtoul(av[1], &tail, 16); - if (tail[0] != '\0') return bad_arg("addr"); + int32_t addr = get_integer_from_char_array(av[1]); + if(addr < 0) return bad_arg("addr"); + else o->addr = (stm32_addr_t) addr; } else if (o->format == FLASH_FORMAT_IHEX) { // expect filename if (ac != 1) return invalid_args("write "); From af8807bc3dffb6e4f536fe942d33e65dddf2a55f Mon Sep 17 00:00:00 2001 From: Rafael Lee Date: Thu, 30 Apr 2020 01:37:12 +0800 Subject: [PATCH 0910/1435] Add range checking in converting string to integer --- src/tools/flash_opts.c | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 781188905..5baea2a9d 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -11,11 +11,12 @@ static bool starts_with(const char * str, const char * prefix) { return (0 == strncmp(str, prefix, n)); } -// support positive integer from 0 to 0x7fffffff +// support positive integer from 0 to INT64_MAX +// INT64_MAX+1 to UINT64_MAX are not supported // support decimal, hexadecimal, octal, binary format like 0xff 12 1k 1M, 0b1001 // negative numbers are not supported -static int32_t get_integer_from_char_array (const char * const str) { - int32_t value; +static int64_t get_long_integer_from_char_array (const char * const str) { + uint64_t value; char *tail; // hexadecimal @@ -36,18 +37,43 @@ static int32_t get_integer_from_char_array (const char * const str) { } if (((tail[0] == 'k') || (tail[0] == 'K')) && (tail[1] == '\0')) { - return value * 1024; + value = value * 1024; } else if (((tail[0] == 'm') || (tail[0] == 'M')) && (tail[1] == '\0')) { - return value * 1024 * 1024; + value = value * 1024 * 1024; } else if (tail[0] == '\0') { - return value; + // value not change } else { return -1; } - return value; + if (value >= INT64_MAX) { + fprintf (stderr, "*** Error: Integer greater than INT64_MAX\n"); + return -1l; + } + else { + return (int64_t)value; + } +} + +// support positive integer from 0 to INT32_MAX +// INT32_MAX+1 to UINT32_MAX are not supported +// support decimal, hexadecimal, octal, binary format like 0xff 12 1k 1M, 0b1001 +// negative numbers are not supported +static int32_t get_integer_from_char_array (const char * const str) { + int64_t v = get_long_integer_from_char_array (str); + if (v < 0) { + return (int32_t)v; + } + else if (v >= INT32_MAX) { + fprintf(stderr, "*** Error: Integer greater than INT32_MAX, \ +cannot convert to int32_t\n"); + return -1; + } + else { + return (int32_t)v; + } } static int invalid_args(const char *expected) { From 2f50899fb8bd03dece4b66382d46e84da613d6cc Mon Sep 17 00:00:00 2001 From: Rafael Lee Date: Fri, 1 May 2020 02:09:12 +0800 Subject: [PATCH 0911/1435] Modify get_integer_from_char_array to support unsigned integer --- src/tools/flash_opts.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 5baea2a9d..d3a39299b 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -11,11 +11,11 @@ static bool starts_with(const char * str, const char * prefix) { return (0 == strncmp(str, prefix, n)); } -// support positive integer from 0 to INT64_MAX -// INT64_MAX+1 to UINT64_MAX are not supported +// support positive integer from 0 to UINT64_MAX // support decimal, hexadecimal, octal, binary format like 0xff 12 1k 1M, 0b1001 // negative numbers are not supported -static int64_t get_long_integer_from_char_array (const char * const str) { +// return 0 if success else return -1 +static int get_long_integer_from_char_array (const char *const str, uint64_t *read_value) { uint64_t value; char *tail; @@ -48,31 +48,28 @@ static int64_t get_long_integer_from_char_array (const char * const str) { else { return -1; } - if (value >= INT64_MAX) { - fprintf (stderr, "*** Error: Integer greater than INT64_MAX\n"); - return -1l; - } - else { - return (int64_t)value; - } + *read_value = value; + return 0; } -// support positive integer from 0 to INT32_MAX -// INT32_MAX+1 to UINT32_MAX are not supported +// support positive integer from 0 to UINT32_MAX // support decimal, hexadecimal, octal, binary format like 0xff 12 1k 1M, 0b1001 // negative numbers are not supported -static int32_t get_integer_from_char_array (const char * const str) { - int64_t v = get_long_integer_from_char_array (str); - if (v < 0) { - return (int32_t)v; +// return 0 if success else return -1 +static int get_integer_from_char_array (const char *const str, uint32_t *read_value) { + uint64_t value; + int result = get_long_integer_from_char_array (str, &value); + if (result != 0) { + return result; } - else if (v >= INT32_MAX) { - fprintf(stderr, "*** Error: Integer greater than INT32_MAX, \ + else if (value > UINT32_MAX) { + fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, \ cannot convert to int32_t\n"); return -1; } else { - return (int32_t)v; + *read_value = value; + return 0; } } From fc964c81d0b34a6cbc391251397162f0f43c6772 Mon Sep 17 00:00:00 2001 From: Rafael Lee Date: Fri, 1 May 2020 02:10:44 +0800 Subject: [PATCH 0912/1435] Modify function calls --- src/tools/flash_opts.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index d3a39299b..f83956e45 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -90,6 +90,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { o->log_level = STND_LOG_LEVEL; // options + int result; while (ac >= 1) { if (strcmp(av[0], "--version") == 0) { printf("v%s\n", STLINK_VERSION); @@ -169,8 +170,9 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { else if ( starts_with(av[0], "--flash=") ) { const char *arg = av[0] + strlen("--flash="); - int32_t flash_size = get_integer_from_char_array(arg); - if (flash_size < 0) return bad_arg("--flash"); + uint32_t flash_size; + result = get_integer_from_char_array(arg, &flash_size); + if (result != 0) return bad_arg ("--flash"); else o->flash_size = (size_t) flash_size; } else { @@ -220,12 +222,14 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { if (ac != 3) return invalid_args("read "); if (ac != 3) return -1; o->filename = av[0]; - int32_t address = get_integer_from_char_array(av[1]); - if(address < 0) return bad_arg("addr"); + uint32_t address; + result = get_integer_from_char_array(av[1], &address); + if (result != 0) return bad_arg ("addr"); else o->addr = (stm32_addr_t) address; - int32_t size = get_integer_from_char_array(av[2]); - if(size < 0) return bad_arg("size"); + uint32_t size; + result = get_integer_from_char_array(av[2], &size); + if (result != 0) return bad_arg ("size"); else o->size = (size_t) size; break; @@ -234,16 +238,18 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { if (o->area == FLASH_OPTION_BYTES){ if (ac != 1) return -1; - int32_t val = get_integer_from_char_array(av[0]); - if(val < 0) return bad_arg("val"); + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) return bad_arg ("val"); else o->val = (uint32_t) val; } else if (o->format == FLASH_FORMAT_BINARY) { // expect filename and addr if (ac != 2) return invalid_args("write "); o->filename = av[0]; - int32_t addr = get_integer_from_char_array(av[1]); - if(addr < 0) return bad_arg("addr"); + uint32_t addr; + result = get_integer_from_char_array(av[1], &addr); + if (result != 0) return bad_arg ("addr"); else o->addr = (stm32_addr_t) addr; } else if (o->format == FLASH_FORMAT_IHEX) { // expect filename From 0f1bf6e3410200a351aa5d9b000cbf7354b2ddd9 Mon Sep 17 00:00:00 2001 From: Rafael Lee Date: Fri, 1 May 2020 02:24:52 +0800 Subject: [PATCH 0913/1435] Add test cases for new syntax --- tests/flash.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/flash.c b/tests/flash.c index 903370cc3..96a43a2c3 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -95,16 +95,36 @@ static struct Test tests[] = { .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, - { "--debug --reset read test.bin 0x80000000 0x1000", 0, + { "--debug --reset read test.bin 0x80000000 1000", 0, { .cmd = FLASH_CMD_READ, .serial = { 0 }, .filename = "test.bin", .addr = 0x80000000, - .size = 0x1000, + .size = 1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } }, + { "--debug --reset read test.bin 0x80000000 1k", 0, + { .cmd = FLASH_CMD_READ, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 1024, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --reset read test.bin 0x80000000 1M", 0, + { .cmd = FLASH_CMD_READ, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 1048576, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .format = FLASH_FORMAT_BINARY } + }, { "--debug --reset write test.bin 0x80000000", 0, { .cmd = FLASH_CMD_WRITE, .serial = { 0 }, From f160c5ef3b74bdf5f6ad1a751dffaa68daad414a Mon Sep 17 00:00:00 2001 From: Rafael Lee Date: Fri, 1 May 2020 02:34:42 +0800 Subject: [PATCH 0914/1435] Modify strncmp to starts_with --- src/tools/flash_opts.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index f83956e45..147f56366 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -20,15 +20,15 @@ static int get_long_integer_from_char_array (const char *const str, uint64_t *re char *tail; // hexadecimal - if ((strncmp ("0x", str, 2) == 0) || (strncmp ("0X", str, 2) == 0)) { + if (starts_with (str, "0x") || starts_with (str, "0X")) { value = strtoul (str + 2, &tail, 16); } // binary - else if ((strncmp ("0b", str, 2) == 0) || (strncmp ("0B", str, 2) == 0)) { + else if (starts_with (str, "0b") || starts_with (str, "0B")) { value = strtoul (str + 2, &tail, 2); } // octal - else if ((strncmp ("0", str, 1) == 0) || (strncmp ("0", str, 1) == 0)) { + else if (starts_with (str, "0")) { value = strtoul (str + 1, &tail, 8); } // decimal From cb777ce57654f187f235c70a95d347d6c8b9c3b8 Mon Sep 17 00:00:00 2001 From: Rafael Lee Date: Fri, 1 May 2020 09:49:55 +0800 Subject: [PATCH 0915/1435] Fix CI, cast variable explicitly --- src/tools/flash_opts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 147f56366..044527a8b 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -68,7 +68,7 @@ cannot convert to int32_t\n"); return -1; } else { - *read_value = value; + *read_value = (uint32_t)value; return 0; } } From 2ad60ff0718b6886f4a2b59452ca5d7a84f2bbd5 Mon Sep 17 00:00:00 2001 From: Paul Gallagher Date: Sat, 2 May 2020 15:41:27 +0800 Subject: [PATCH 0916/1435] Fix: tutorial.md should be correctly linked from readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4bf663e34..12052a7a8 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Supported operating systems are listed in [version_support.md](doc/version_suppo ## Tutorial & HOWTO -Our [tutorial.md](doc/tutorial.md may help you along with some advanced tasks and additional info. +Our [tutorial.md](doc/tutorial.md) may help you along with some advanced tasks and additional info. ## Installation From 5e0e29984c562bf42f1c7edb04bb0e4d1030950a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 6 May 2020 19:48:21 +0200 Subject: [PATCH 0917/1435] Updated travis CI test-builds - Added builds for clang -m32 on arch: AMD64 - Corrected invalid config settings - Added clang-9 builds for linux - Moved scripts to root directory - Added MinGW cross-test-build for linux --- .travis.sh | 95 ++++++++++++------- .travis.yml | 87 ++++++++++------- doc/version_support.md | 4 +- .../mingw64-build.bat => mingw64-build.bat | 4 +- ...n_clang_analyze.sh => run_clang_analyze.sh | 0 5 files changed, 117 insertions(+), 73 deletions(-) rename scripts/mingw64-build.bat => mingw64-build.bat (91%) rename scripts/run_clang_analyze.sh => run_clang_analyze.sh (100%) diff --git a/.travis.sh b/.travis.sh index 5291ec95b..e61098f89 100755 --- a/.travis.sh +++ b/.travis.sh @@ -8,39 +8,64 @@ echo "----" echo "WORK DIR:$DIR" DIR=$PWD -if [ "$TRAVIS_OS_NAME" == "linux" ]; then - sudo apt-get update -qq || true - sudo apt-get install -qq -y --no-install-recommends libgtk-3-dev - - echo "--> Building Debug..." - mkdir -p build/Debug && cd build/Debug - echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install" - cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ - make && make package && cd - - - echo "--> Building Release..." - mkdir -p build/Release && cd build/Release - echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install" - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ - make && make package && cd - - -# echo "--> Building Binary..." -# mkdir -p build/Binary && cd build/Binary -# cho "-DCMAKE_BUILD_TYPE=Binary -DCMAKE_INSTALL_PREFIX=$PWD/_install" -# cmake -DCMAKE_BUILD_TYPE=Binary -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ -# make && make package && cd - -else [ "$TRAVIS_OS_NAME" == "osx" ]; - brew install libusb - - echo "--> Building Debug..." - mkdir -p build/Debug && cd build/Debug - echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install" - cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ - make && make package && cd - - - echo "--> Building Release..." - mkdir -p build/Release && cd build/Release - echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install" - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ - make && make package && cd - +if [ "$TRAVIS_JOB_NAME" == "linux-mingw" ]; then + echo "--> Building Release for Windows (x86-64) ..." + mkdir -p build-mingw && cd build-mingw + echo "-DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR" + cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR + make && rm -rf build-mingw && cd - + + echo "--> Building Release for Windows (i686) ..." + mkdir -p build-mingw && cd build-mingw + echo "-DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR" + cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR + make && rm -rf build-mingw && cd - + +elif [ "$TRAVIS_OS_NAME" == "linux" ]; then + sudo apt-get update -qq || true + sudo apt-get install -qq -y --no-install-recommends libgtk-3-dev + + echo "--> Building Debug..." + mkdir -p build/Debug && cd build/Debug + echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install" + cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR + make && make package && cd - + + echo "--> Building Release..." + mkdir -p build/Release && cd build/Release + echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install" + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR + make && make package && cd - + +elif [ "$TRAVIS_OS_NAME" == "osx" ]; then + brew install libusb + + echo "--> Building Debug..." + mkdir -p build/Debug && cd build/Debug + echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install" + cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR + make && make package && cd - + + echo "--> Building Release..." + mkdir -p build/Release && cd build/Release + echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install" + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR + make && make package && cd - + +else # local test-build + echo "--> Building Debug..." + mkdir -p build/Debug && cd build/Debug + echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install" + cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ + make && make package && cd - + + echo "--> Building Release..." + mkdir -p build/Release && cd build/Release + echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install" + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ + make && make package && cd - fi diff --git a/.travis.yml b/.travis.yml index a66777f5f..17db35765 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,98 +1,111 @@ language: c -matrix: +jobs: include: - ### 64-bit builds ### + ### 64-bit builds on AMD64 ### - os: linux + dist: bionic env: BADGE=linux - arch: x64 compiler: gcc-5 addons: apt: sources: ['ubuntu-toolchain-r-test'] packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - os: linux + dist: bionic env: BADGE=linux - arch: x64 - compiler: gcc-7 - addons: - apt: - sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-7', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - - os: linux - env: BADGE=linux - arch: x64 compiler: gcc-9 addons: apt: sources: ['ubuntu-toolchain-r-test'] packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - os: linux + dist: xenial env: BADGE=linux - arch: x64 compiler: clang-3.7 addons: apt: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-3.7'] packages: ['clang-3.7', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - os: linux + dist: bionic env: BADGE=linux - arch: x64 compiler: clang-6.0 addons: apt: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] packages: ['clang-6.0', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] -# - os: linux -# arch: x64 -# compiler: clang-6.0 -# addons: -# apt: -# sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] -# packages: ['clang-6.0', 'libusb-1.0.0-dev', 'libgtk-3-dev'] -# env: CFLAGS=-m32 LDFLAGS=-m32 - - ### 32-bit builds ### - os: linux + dist: bionic env: BADGE=linux - arch: x86 - compiler: gcc-5 + compiler: clang-9 addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + packages: ['clang-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + + - os: linux + dist: bionic + env: BADGE=linux-mingw + name: linux-mingw + compiler: gcc-9 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm', 'mingw-w64'] + + ### 32-bit builds on AMD64 ### - os: linux + dist: bionic env: BADGE=linux - arch: x86 - compiler: gcc-7 + compiler: gcc-5 addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-7', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - os: linux + dist: bionic env: BADGE=linux - arch: x86 compiler: gcc-9 addons: apt: sources: ['ubuntu-toolchain-r-test'] packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - os: linux + dist: xenial env: BADGE=linux - arch: x86 compiler: clang-3.7 addons: apt: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-3.7'] packages: ['clang-3.7', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - os: linux + dist: bionic env: BADGE=linux - arch: x86 compiler: clang-6.0 addons: apt: sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] packages: ['clang-6.0', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + - os: linux + dist: bionic + env: BADGE=linux + compiler: clang-9 + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['clang-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + ### macOS ### - os: osx @@ -114,8 +127,14 @@ matrix: - libusb - gtk+3 + ### Windows ### +# - os: windows +# env: BADGE=windows +# compiler: gcc + script: - git fetch --tags - printenv - cmake --version - - ./.travis.sh + - if [[ "$TRAVIS_OS_NAME" == "linux" ]] || [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis.sh; fi +# - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then cmd.exe /C 'mingw64-build.bat'; fi diff --git a/doc/version_support.md b/doc/version_support.md index 75def2e66..f889fbc32 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -68,10 +68,10 @@ Thus no user interaction regarding libusb is necessary. | Operating System | libusb
    version | cmake
    version | End of OS-Support | Notes | | --- | --- | --- | --- | --- | -| CentOS 7 | 1.0.21 | **2.8.12.2** | | named `libusbx`, but `libusb`-codebase is used | +| CentOS 7 | 1.0.21 | **2.8.12.2** | | named `libusbx`, but
    `libusb`-codebase is used | | Debian 8 (Jessie) | 1.0.**19** | 3.**0.2** | Jun 2020 | | Ubuntu 14.04 LTS (Trusty Tahr) | 1.0.**17** | **2.8.12.2** | Apr 2019 | -| CentOS 6 | 1.0.**9** | **2.8.12.2** | Dec 2020 | named `libusbx`, but `libusb`-codebase is used | +| CentOS 6 | 1.0.**9** | **2.8.12.2** | Dec 2020 | named `libusbx`, but
    `libusb`-codebase is used | | Slackware 14.1 | 1.0.**9** | **2.8.12** | | | Slackware 14.0 | 1.0.**9** | **2.8.8** | | diff --git a/scripts/mingw64-build.bat b/mingw64-build.bat similarity index 91% rename from scripts/mingw64-build.bat rename to mingw64-build.bat index 15ec21cd0..9d5cf4d06 100644 --- a/scripts/mingw64-build.bat +++ b/mingw64-build.bat @@ -1,5 +1,5 @@ -@echo off -cd .. +@echo on + mkdir build-mingw cd build-mingw set PATH=C:\Program Files (x86)\CMake\bin;C:\Program Files\CMake\bin;C:\Program Files\mingw-w64\x86_64-8.1.0-win32-sjlj-rt_v6-rev0\mingw64\bin;%PATH% diff --git a/scripts/run_clang_analyze.sh b/run_clang_analyze.sh similarity index 100% rename from scripts/run_clang_analyze.sh rename to run_clang_analyze.sh From e11b077da3aba4470f0a66815d262100e2ff630c Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Thu, 7 May 2020 18:16:07 +0800 Subject: [PATCH 0918/1435] Fix https://github.com/stlink-org/stlink/issues/893 * Add --freq argument for st-flash --- include/stlink.h | 2 ++ include/stlink/tools/flash.h | 3 +- src/st-util/gdb-server.c | 4 +-- src/stlink-gui/gui.c | 2 +- src/tools/flash.c | 8 +++--- src/tools/flash_opts.c | 50 +++++++++++++++++++++++++++++++++ src/tools/info.c | 2 +- src/usb.c | 47 +++++++++++++++++++++++++++++-- src/usb.h | 2 +- tests/flash.c | 54 ++++++++++++++++++++++++++++++++++++ tests/usb.c | 2 +- 11 files changed, 162 insertions(+), 14 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 74c366d1c..ffa65b332 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -159,6 +159,8 @@ typedef struct flash_loader { char serial[STLINK_SERIAL_MAX_SIZE]; int serial_size; + int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR + enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx bool has_dual_bank; diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index 8c3f7d766..b8954af65 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -26,9 +26,10 @@ struct flash_opts uint32_t val; size_t flash_size; /* --flash=n[k][m] */ int opt; + int freq; }; -#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} int flash_get_opts(struct flash_opts* o, int ac, char** av); diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index a3839cfc8..20954821b 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -87,9 +87,9 @@ static void cleanup(int signum) { static stlink_t* do_connect(st_state_t *st) { stlink_t *sl = NULL; if (serial_specified) { - sl = stlink_open_usb(st->logging_level, st->reset, serialnumber); + sl = stlink_open_usb(st->logging_level, st->reset, serialnumber, 0); } else { - sl = stlink_open_usb(st->logging_level, st->reset, NULL); + sl = stlink_open_usb(st->logging_level, st->reset, NULL, 0); } return sl; } diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index 5d5a422d5..6e9d59b1e 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -490,7 +490,7 @@ static void connect_button_cb (GtkWidget *widget, gpointer data) { /* try version 1 then version 2 */ gui->sl = stlink_v1_open(0, 1); if (gui->sl == NULL) - gui->sl = stlink_open_usb(0, 1, NULL); + gui->sl = stlink_open_usb(0, 1, NULL, 0); if (gui->sl == NULL) { stlink_gui_set_info_error_message (gui, "Failed to connect to STLink."); return; diff --git a/src/tools/flash.c b/src/tools/flash.c index 841b93c3c..3a83daf8a 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -28,9 +28,9 @@ static void cleanup(int signum) { static void usage(void) { - puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] {read|write} [addr] [size]"); - puts("command line: ./st-flash [--debug] [--serial ] erase"); - puts("command line: ./st-flash [--debug] [--serial ] reset"); + puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] {read|write} [addr] [size]"); + puts("command line: ./st-flash [--debug] [--freq=] [--serial ] erase"); + puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); puts(" , and : Use hex format."); puts(" : Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); puts(" : Can be 'binary' (default) or 'ihex', although must be specified for binary format only."); @@ -56,7 +56,7 @@ int main(int ac, char** av) printf("st-flash %s\n", STLINK_VERSION); - sl = stlink_open_usb(o.log_level, 1, (char *)o.serial); + sl = stlink_open_usb(o.log_level, 1, (char *)o.serial, o.freq); if (sl == NULL) { return -1; diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 044527a8b..a5c9d287f 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -149,6 +149,56 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { return -1; } + else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) { + const char* freq; + if (strcmp(av[0], "--freq") == 0) { + ac--; + av++; + if (ac < 1) return -1; + freq = av[0]; + } + else { + freq = av[0] + strlen("--freq="); + } + if (strcmp(freq, "5K") == 0 || strcmp(freq, "5k") == 0) { + o->freq = 5; + } + else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) { + o->freq = 15; + } + else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) { + o->freq = 25; + } + else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) { + o->freq = 50; + } + else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) { + o->freq = 100; + } + else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) { + o->freq = 125; + } + else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) { + o->freq = 240; + } + else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) { + o->freq = 480; + } + else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) { + o->freq = 950; + } + else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) { + o->freq = 1200; + } + else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) { + o->freq = 1800; + } + else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) { + o->freq = 4000; + } + else + return -1; + } else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { const char * format; if (strcmp(av[0], "--format") == 0) { diff --git a/src/tools/info.c b/src/tools/info.c index 3ebbba8de..45d484270 100644 --- a/src/tools/info.c +++ b/src/tools/info.c @@ -81,7 +81,7 @@ static stlink_t *stlink_open_first(void) stlink_t* sl = NULL; sl = stlink_v1_open(0, 1); if (sl == NULL) - sl = stlink_open_usb(0, 1, NULL); + sl = stlink_open_usb(0, 1, NULL, 0); return sl; } diff --git a/src/usb.c b/src/usb.c index 4e7a2983f..ef3743c78 100644 --- a/src/usb.c +++ b/src/usb.c @@ -873,7 +873,7 @@ static stlink_backend_t _stlink_usb_backend = { _stlink_usb_set_swdclk }; -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE]) +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; @@ -1041,10 +1041,51 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST stlink_exit_dfu_mode(sl); } + + sl->opt = freq; // set the speed before entering the mode // as the chip discovery phase should be done at this speed too // Set the stlink clock speed (default is 1800kHz) - stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); + DLOG("JTAG/SWD freq set to %d\n", freq); + switch (freq) { + case 5: + stlink_set_swdclk(sl, STLINK_SWDCLK_5KHZ_DIVISOR); + break; + case 15: + stlink_set_swdclk(sl, STLINK_SWDCLK_15KHZ_DIVISOR); + break; + case 25: + stlink_set_swdclk(sl, STLINK_SWDCLK_25KHZ_DIVISOR); + break; + case 50: + stlink_set_swdclk(sl, STLINK_SWDCLK_50KHZ_DIVISOR); + break; + case 100: + stlink_set_swdclk(sl, STLINK_SWDCLK_100KHZ_DIVISOR); + break; + case 125: + stlink_set_swdclk(sl, STLINK_SWDCLK_125KHZ_DIVISOR); + break; + case 240: + stlink_set_swdclk(sl, STLINK_SWDCLK_240KHZ_DIVISOR); + break; + case 480: + stlink_set_swdclk(sl, STLINK_SWDCLK_480KHZ_DIVISOR); + break; + case 950: + stlink_set_swdclk(sl, STLINK_SWDCLK_950KHZ_DIVISOR); + break; + case 1200: + stlink_set_swdclk(sl, STLINK_SWDCLK_1P2MHZ_DIVISOR); + break; + case 0: case 1800: + stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); + break; + case 4000: + stlink_set_swdclk(sl, STLINK_SWDCLK_4MHZ_DIVISOR); + break; + } + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); @@ -1147,7 +1188,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { continue; } - stlink_t *sl = stlink_open_usb(0, 1, serial); + stlink_t *sl = stlink_open_usb(0, 1, serial, 0); if (!sl) { ELOG("Failed to open USB device %#06x:%#06x\n", desc.idVendor, desc.idProduct); continue; diff --git a/src/usb.h b/src/usb.h index 968f38ba4..061042e8d 100644 --- a/src/usb.h +++ b/src/usb.h @@ -68,7 +68,7 @@ extern "C" { * @retval NULL Error while opening the stlink * @retval !NULL Stlink found and ready to use */ - stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE]); + stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq); size_t stlink_probe_usb(stlink_t **stdevs[]); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); diff --git a/tests/flash.c b/tests/flash.c index 96a43a2c3..3166e72b5 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -83,6 +83,7 @@ static struct Test tests[] = { .size = 0x1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset write test.bin 0x80000000", 0, @@ -93,6 +94,51 @@ static struct Test tests[] = { .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --freq 5k --reset write test.bin 0x80000000", 0, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 5, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --freq 15K --reset write test.bin 0x80000000", 0, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 15, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --freq=5k --reset write test.bin 0x80000000", 0, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --freq=6k --reset write test.bin 0x80000000", -1, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 6, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset read test.bin 0x80000000 1000", 0, @@ -103,6 +149,7 @@ static struct Test tests[] = { .size = 1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset read test.bin 0x80000000 1k", 0, @@ -113,6 +160,7 @@ static struct Test tests[] = { .size = 1024, .reset = 1, .log_level = DEBUG_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset read test.bin 0x80000000 1M", 0, @@ -123,6 +171,7 @@ static struct Test tests[] = { .size = 1048576, .reset = 1, .log_level = DEBUG_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset write test.bin 0x80000000", 0, @@ -133,6 +182,7 @@ static struct Test tests[] = { .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, { "erase", 0, @@ -143,6 +193,7 @@ static struct Test tests[] = { .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset --format=ihex write test.hex", 0, @@ -153,6 +204,7 @@ static struct Test tests[] = { .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_IHEX } }, { "--debug --reset --format=binary write test.hex", -1, FLASH_OPTS_INITIALIZER }, @@ -167,6 +219,7 @@ static struct Test tests[] = { .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, { "--serial=A1020304 erase", 0, @@ -177,6 +230,7 @@ static struct Test tests[] = { .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, }; diff --git a/tests/usb.c b/tests/usb.c index d4098834d..5165ea563 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -9,7 +9,7 @@ int main(int ac, char** av) { stlink_t* sl; struct stlink_reg regs; - sl = stlink_open_usb(10, 1, NULL); + sl = stlink_open_usb(10, 1, NULL, 0); if (sl != NULL) { printf("-- version\n"); stlink_version(sl); From 931141869e17f72a01dc14ebd27cca8f86348c32 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Thu, 7 May 2020 18:52:34 +0800 Subject: [PATCH 0919/1435] Fix missing cmp and wrong expected value for freq --- tests/flash.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/flash.c b/tests/flash.c index 3166e72b5..d47b3564d 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -66,6 +66,7 @@ static bool execute_test(const struct Test * test) { ret &= (opts.size == test->opts.size); ret &= (opts.reset == test->opts.reset); ret &= (opts.log_level == test->opts.log_level); + ret &= (opts.freq == test->opts.freq); ret &= (opts.format == test->opts.format); } @@ -127,7 +128,7 @@ static struct Test tests[] = { .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, - .freq = 0, + .freq = 5, .format = FLASH_FORMAT_BINARY } }, { "--debug --freq=6k --reset write test.bin 0x80000000", -1, From 6c6f27b0f55fdd482ece7d223293ddc3e9a7a90b Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Fri, 8 May 2020 15:40:29 +0800 Subject: [PATCH 0920/1435] Add documentation of --freq and --opt --- doc/tutorial.md | 11 +++++++++++ include/stlink.h | 2 +- include/stlink/tools/flash.h | 4 ++-- src/usb.c | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 929aa3250..ad64a8db8 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -19,6 +19,17 @@ The size may be followed by an optional "k" or "m" to multiply the given value b When flashing a file, a checksum is calculated for the binary file, both in md5 and the sum algorithm. The latter is also used by the official ST-Link utility tool from STMicroelectronics as described in the document: [`UM0892 - User manual - STM32 ST-LINK utility software description`](https://www.st.com/resource/en/user_manual/cd00262073-stm32-stlink-utility-software-description-stmicroelectronics.pdf). +#### --freq=n[k][m] + +(since v1.6.1) + +You can specify the frequency of SWD/JTAG interface, to override the default 1800KHz configuration. This option accpets decimal only (5K or 1.8M). `Hz` is left out in this option. Valid frequencies are `5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)` + +#### --opt + +(since v1.6.1, optional; enabled by default from v1.0.0 to v1.6.0) + +You can enable the optimization to skip flashing empty (0x00 or 0xff) bytes at the end of binary file. May cause some garbage data left after a flash. ## Solutions to common problems ### a) STLINK/v1 driver: Issue with Kernel Extension (kext) (macOS 10.11 and later only) diff --git a/include/stlink.h b/include/stlink.h index ffa65b332..b8080fd5e 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -151,7 +151,7 @@ typedef struct flash_loader { // transport layer verboseness: 0 for no debug info, 10 for lots int verbose; - int opt; + int opt; // set by main() in tools/flash.c, empty tail bytes drop optimization uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram int core_stat; // set by stlink_status(), values STLINK_CORE_xxxxx diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index b8954af65..a912a14aa 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -25,8 +25,8 @@ struct flash_opts enum flash_area area; uint32_t val; size_t flash_size; /* --flash=n[k][m] */ - int opt; - int freq; + int opt; /* enable empty tail data drop optimization */ + int freq; /* --freq=n[k][m] frequency of JTAG/SWD */ }; #define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} diff --git a/src/usb.c b/src/usb.c index ef3743c78..148ad7652 100644 --- a/src/usb.c +++ b/src/usb.c @@ -1042,7 +1042,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST } - sl->opt = freq; + sl->freq = freq; // set the speed before entering the mode // as the chip discovery phase should be done at this speed too // Set the stlink clock speed (default is 1800kHz) From f6e9cb1be385494a4dda45f03f58d7109ae971ea Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 9 May 2020 21:28:59 +0200 Subject: [PATCH 0921/1435] Additional fixes for #863 - Comment for selection of API-Version (#271) - Whitespace cleanup - Fixed casting (-Wshorten-64-to-32) --- include/stlink.h | 466 +++++++++++++++++++++++------------------------ src/usb.c | 22 +-- 2 files changed, 238 insertions(+), 250 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 4e7fedc66..3aca9d8ee 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -1,9 +1,10 @@ /* - * File: stlink.h + * File: stlink.h * - * This should contain all the common top level stlink interfaces, regardless - * of how the backend does the work.... + * This should contain all the common top level stlink interfaces, + * regardless of how the backend does the work.... */ + #ifndef STLINK_H #define STLINK_H @@ -19,10 +20,10 @@ extern "C" { #define STLINK_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) - // Max data transfer size. - // 6kB = max mem32_read block, 8kB sram - //#define Q_BUF_LEN 96 -#define Q_BUF_LEN (1024 * 100) +/* Max data transfer size */ +// 6kB = max mem32_read block, 8kB sram +//#define Q_BUF_LEN 96 +#define Q_BUF_LEN (1024 * 100) // STLINK_DEBUG_RESETSYS, etc: enum target_state { @@ -33,79 +34,76 @@ enum target_state { TARGET_DEBUG_RUNNING = 4, }; -#define STLINK_CORE_RUNNING 0x80 -#define STLINK_CORE_HALTED 0x81 +#define STLINK_CORE_RUNNING 0x80 +#define STLINK_CORE_HALTED 0x81 -#define STLINK_GET_VERSION 0xf1 -#define STLINK_GET_CURRENT_MODE 0xf5 -#define STLINK_GET_TARGET_VOLTAGE 0xF7 +#define STLINK_GET_VERSION 0xF1 +#define STLINK_GET_CURRENT_MODE 0xF5 +#define STLINK_GET_TARGET_VOLTAGE 0xF7 -#define STLINK_DEBUG_COMMAND 0xF2 -#define STLINK_DFU_COMMAND 0xF3 -#define STLINK_DFU_EXIT 0x07 +#define STLINK_DEBUG_COMMAND 0xF2 +#define STLINK_DFU_COMMAND 0xF3 +#define STLINK_DFU_EXIT 0x07 - // STLINK_GET_CURRENT_MODE -#define STLINK_DEV_DFU_MODE 0x00 -#define STLINK_DEV_MASS_MODE 0x01 -#define STLINK_DEV_DEBUG_MODE 0x02 -#define STLINK_DEV_UNKNOWN_MODE -1 +// STLINK_GET_CURRENT_MODE +#define STLINK_DEV_DFU_MODE 0x00 +#define STLINK_DEV_MASS_MODE 0x01 +#define STLINK_DEV_DEBUG_MODE 0x02 +#define STLINK_DEV_UNKNOWN_MODE -1 - // TODO - possible poor names... -#define STLINK_SWD_ENTER 0x30 -#define STLINK_SWD_READCOREID 0x32 // TBD -#define STLINK_JTAG_WRITEDEBUG_32BIT 0x35 -#define STLINK_JTAG_READDEBUG_32BIT 0x36 -#define STLINK_JTAG_DRIVE_NRST 0x3c +// TODO - possible poor names... +#define STLINK_SWD_ENTER 0x30 +#define STLINK_SWD_READCOREID 0x32 // TBD +#define STLINK_JTAG_WRITEDEBUG_32BIT 0x35 +#define STLINK_JTAG_READDEBUG_32BIT 0x36 +#define STLINK_JTAG_DRIVE_NRST 0x3C -#define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43 +#define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43 -#define STLINK_APIV3_SET_COM_FREQ 0x61 -#define STLINK_APIV3_GET_COM_FREQ 0x62 +#define STLINK_APIV3_SET_COM_FREQ 0x61 +#define STLINK_APIV3_GET_COM_FREQ 0x62 -#define STLINK_APIV3_GET_VERSION_EX 0xFB +#define STLINK_APIV3_GET_VERSION_EX 0xFB -// Baud rate divisors for SWDCLK -#define STLINK_SWDCLK_4MHZ_DIVISOR 0 -#define STLINK_SWDCLK_1P8MHZ_DIVISOR 1 -#define STLINK_SWDCLK_1P2MHZ_DIVISOR 2 -#define STLINK_SWDCLK_950KHZ_DIVISOR 3 -#define STLINK_SWDCLK_480KHZ_DIVISOR 7 -#define STLINK_SWDCLK_240KHZ_DIVISOR 15 -#define STLINK_SWDCLK_125KHZ_DIVISOR 31 -#define STLINK_SWDCLK_100KHZ_DIVISOR 40 -#define STLINK_SWDCLK_50KHZ_DIVISOR 79 -#define STLINK_SWDCLK_25KHZ_DIVISOR 158 -#define STLINK_SWDCLK_15KHZ_DIVISOR 265 -#define STLINK_SWDCLK_5KHZ_DIVISOR 798 +/* Baud rate divisors for SWDCLK */ +#define STLINK_SWDCLK_4MHZ_DIVISOR 0 +#define STLINK_SWDCLK_1P8MHZ_DIVISOR 1 +#define STLINK_SWDCLK_1P2MHZ_DIVISOR 2 +#define STLINK_SWDCLK_950KHZ_DIVISOR 3 +#define STLINK_SWDCLK_480KHZ_DIVISOR 7 +#define STLINK_SWDCLK_240KHZ_DIVISOR 15 +#define STLINK_SWDCLK_125KHZ_DIVISOR 31 +#define STLINK_SWDCLK_100KHZ_DIVISOR 40 +#define STLINK_SWDCLK_50KHZ_DIVISOR 79 +#define STLINK_SWDCLK_25KHZ_DIVISOR 158 +#define STLINK_SWDCLK_15KHZ_DIVISOR 265 +#define STLINK_SWDCLK_5KHZ_DIVISOR 798 -#define STLINK_SERIAL_MAX_SIZE 64 +#define STLINK_SERIAL_MAX_SIZE 64 -#define STLINK_V3_MAX_FREQ_NB 10 +#define STLINK_V3_MAX_FREQ_NB 10 /* Cortex Debug Control Block */ -#define DCB_DHCSR 0xE000EDF0 -#define DCB_DCRSR 0xE000EDF4 -#define DCB_DCRDR 0xE000EDF8 -#define DCB_DEMCR 0xE000EDFC +#define DCB_DHCSR 0xE000EDF0 +#define DCB_DCRSR 0xE000EDF4 +#define DCB_DCRDR 0xE000EDF8 +#define DCB_DEMCR 0xE000EDFC /* DCB_DHCSR bit and field definitions */ -#define DBGKEY (0xA05F << 16) -#define C_DEBUGEN (1 << 0) -#define C_HALT (1 << 1) -#define C_STEP (1 << 2) -#define C_MASKINTS (1 << 3) -#define S_REGRDY (1 << 16) -#define S_HALT (1 << 17) -#define S_SLEEP (1 << 18) -#define S_LOCKUP (1 << 19) -#define S_RETIRE_ST (1 << 24) -#define S_RESET_ST (1 << 25) - - -/* - * Map the relevant features, quirks and workaround for specific firmware - * version of stlink - */ +#define DBGKEY (0xA05F << 16) +#define C_DEBUGEN (1 << 0) +#define C_HALT (1 << 1) +#define C_STEP (1 << 2) +#define C_MASKINTS (1 << 3) +#define S_REGRDY (1 << 16) +#define S_HALT (1 << 17) +#define S_SLEEP (1 << 18) +#define S_LOCKUP (1 << 19) +#define S_RETIRE_ST (1 << 24) +#define S_RESET_ST (1 << 25) + + +/* Map the relevant features, quirks and workaround for specific firmware version of stlink */ #define STLINK_F_HAS_TRACE (1<<0) #define STLINK_F_HAS_SWD_SET_FREQ (1<<1) #define STLINK_F_HAS_JTAG_SET_FREQ (1<<2) @@ -120,181 +118,181 @@ enum target_state { #define C_BUF_LEN 32 - enum stlink_flash_type { - STLINK_FLASH_TYPE_UNKNOWN = 0, - STLINK_FLASH_TYPE_F0, /* used by f0, f1 (except f1xl),f3. */ - STLINK_FLASH_TYPE_F1_XL, /* f0 flash with dual bank, apparently */ - STLINK_FLASH_TYPE_F4, /* used by f2, f4, f7 */ - STLINK_FLASH_TYPE_L0, /* l0, l1 */ - STLINK_FLASH_TYPE_L4, /* l4, l4+ */ - STLINK_FLASH_TYPE_G0, - STLINK_FLASH_TYPE_G4, - STLINK_FLASH_TYPE_WB - }; - - struct stlink_reg { - uint32_t r[16]; - uint32_t s[32]; - uint32_t xpsr; - uint32_t main_sp; - uint32_t process_sp; - uint32_t rw; - uint32_t rw2; - uint8_t control; - uint8_t faultmask; - uint8_t basepri; - uint8_t primask; - uint32_t fpscr; - }; - - typedef uint32_t stm32_addr_t; +enum stlink_flash_type { + STLINK_FLASH_TYPE_UNKNOWN = 0, + STLINK_FLASH_TYPE_F0, // used by f0, f1 (except f1xl),f3. */ + STLINK_FLASH_TYPE_F1_XL, // f0 flash with dual bank, apparently */ + STLINK_FLASH_TYPE_F4, // used by f2, f4, f7 */ + STLINK_FLASH_TYPE_L0, // l0, l1 */ + STLINK_FLASH_TYPE_L4, // l4, l4+ */ + STLINK_FLASH_TYPE_G0, + STLINK_FLASH_TYPE_G4, + STLINK_FLASH_TYPE_WB +}; + +struct stlink_reg { + uint32_t r[16]; + uint32_t s[32]; + uint32_t xpsr; + uint32_t main_sp; + uint32_t process_sp; + uint32_t rw; + uint32_t rw2; + uint8_t control; + uint8_t faultmask; + uint8_t basepri; + uint8_t primask; + uint32_t fpscr; +}; + +typedef uint32_t stm32_addr_t; typedef struct flash_loader { - stm32_addr_t loader_addr; /* loader sram adddr */ - stm32_addr_t buf_addr; /* buffer sram address */ +stm32_addr_t loader_addr; // loader sram addr +stm32_addr_t buf_addr; // buffer sram address } flash_loader_t; - typedef struct _cortex_m3_cpuid_ { - uint16_t implementer_id; - uint16_t variant; - uint16_t part; - uint8_t revision; - } cortex_m3_cpuid_t; - - enum stlink_jtag_api_version { - STLINK_JTAG_API_V1 = 1, - STLINK_JTAG_API_V2, - STLINK_JTAG_API_V3, - }; - - typedef struct stlink_version_ { - uint32_t stlink_v; - uint32_t jtag_v; - uint32_t swim_v; - uint32_t st_vid; - uint32_t stlink_pid; - /** jtag api version supported */ - enum stlink_jtag_api_version jtag_api; - /** one bit for each feature supported. See macros STLINK_F_* */ - uint32_t flags; - } stlink_version_t; - - enum transport_type { - TRANSPORT_TYPE_ZERO = 0, - TRANSPORT_TYPE_LIBSG, - TRANSPORT_TYPE_LIBUSB, - TRANSPORT_TYPE_INVALID - }; - - typedef struct _stlink stlink_t; +typedef struct _cortex_m3_cpuid_ { + uint16_t implementer_id; + uint16_t variant; + uint16_t part; + uint8_t revision; +} cortex_m3_cpuid_t; + +enum stlink_jtag_api_version { + STLINK_JTAG_API_V1 = 1, + STLINK_JTAG_API_V2, + STLINK_JTAG_API_V3, +}; + +typedef struct stlink_version_ { + uint32_t stlink_v; + uint32_t jtag_v; + uint32_t swim_v; + uint32_t st_vid; + uint32_t stlink_pid; + // jtag api version supported + enum stlink_jtag_api_version jtag_api; + // one bit for each feature supported. See macros STLINK_F_* + uint32_t flags; +} stlink_version_t; + +enum transport_type { + TRANSPORT_TYPE_ZERO = 0, + TRANSPORT_TYPE_LIBSG, + TRANSPORT_TYPE_LIBUSB, + TRANSPORT_TYPE_INVALID +}; + +typedef struct _stlink stlink_t; #include - struct _stlink { - struct _stlink_backend *backend; - void *backend_data; - - // Room for the command header - unsigned char c_buf[C_BUF_LEN]; - // Data transferred from or to device - unsigned char q_buf[Q_BUF_LEN]; - int q_len; - - // transport layer verboseness: 0 for no debug info, 10 for lots - int verbose; - int opt; - uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID - uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram - enum target_state core_stat; // set by stlink_status() - - char serial[STLINK_SERIAL_MAX_SIZE]; - int serial_size; - - enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx - bool has_dual_bank; - - stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() - size_t flash_size; // calculated by stlink_load_device_params() - size_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() - - /* sram settings */ - stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() - size_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() - - /* option settings */ - stm32_addr_t option_base; - size_t option_size; - - // bootloader - // sys_base and sys_size are not used by the tools, but are only there to - // download the bootloader code (see tests/sg.c) - stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() - size_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() - - struct stlink_version_ version; - }; - - int stlink_enter_swd_mode(stlink_t *sl); - int stlink_enter_jtag_mode(stlink_t *sl); - int stlink_exit_debug_mode(stlink_t *sl); - int stlink_exit_dfu_mode(stlink_t *sl); - void stlink_close(stlink_t *sl); - int stlink_core_id(stlink_t *sl); - int stlink_reset(stlink_t *sl); - int stlink_jtag_reset(stlink_t *sl, int value); - int stlink_run(stlink_t *sl); - int stlink_status(stlink_t *sl); - int stlink_version(stlink_t *sl); - int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); - int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); - int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp); - int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); - int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); - int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); - int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, struct stlink_reg *regp); - int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); - int stlink_step(stlink_t *sl); - int stlink_current_mode(stlink_t *sl); - int stlink_force_debug(stlink_t *sl); - int stlink_target_voltage(stlink_t *sl); - int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); - - int stlink_erase_flash_mass(stlink_t* sl); - int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); - int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); - uint8_t stlink_get_erased_pattern(stlink_t *sl); - int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); - int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); - int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, 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); - - int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); - int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); - - int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); - uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); - uint16_t read_uint16(const unsigned char *c, const int pt); - void stlink_core_stat(stlink_t *sl); - void stlink_print_data(stlink_t *sl); - unsigned int is_bigendian(void); - uint32_t read_uint32(const unsigned char *c, const int pt); - void write_uint32(unsigned char* buf, uint32_t ui); - void write_uint16(unsigned char* buf, uint16_t ui); - bool stlink_is_core_halted(stlink_t *sl); - int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); - int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); - int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); - int stlink_load_device_params(stlink_t *sl); - - int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); - int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); - - int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); - int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); +struct _stlink { + struct _stlink_backend *backend; + void *backend_data; + + // Room for the command header + unsigned char c_buf[C_BUF_LEN]; + // Data transferred from or to device + unsigned char q_buf[Q_BUF_LEN]; + int q_len; + + // transport layer verboseness: 0 for no debug info, 10 for lots + int verbose; + int opt; + uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID + uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram + enum target_state core_stat; // set by stlink_status() + + char serial[STLINK_SERIAL_MAX_SIZE]; + int serial_size; + + enum stlink_flash_type flash_type; + // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx + bool has_dual_bank; + + stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() + size_t flash_size; // calculated by stlink_load_device_params() + size_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() + + /* sram settings */ + stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() + size_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() + + /* option settings */ + stm32_addr_t option_base; + size_t option_size; + + // bootloader + // sys_base and sys_size are not used by the tools, but are only there to download the bootloader code (see tests/sg.c) + stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() + size_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() + + struct stlink_version_ version; +}; + +int stlink_enter_swd_mode(stlink_t *sl); +int stlink_enter_jtag_mode(stlink_t *sl); +int stlink_exit_debug_mode(stlink_t *sl); +int stlink_exit_dfu_mode(stlink_t *sl); +void stlink_close(stlink_t *sl); +int stlink_core_id(stlink_t *sl); +int stlink_reset(stlink_t *sl); +int stlink_jtag_reset(stlink_t *sl, int value); +int stlink_run(stlink_t *sl); +int stlink_status(stlink_t *sl); +int stlink_version(stlink_t *sl); +int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); +int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); +int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); +int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp); +int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); +int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); +int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); +int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, struct stlink_reg *regp); +int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); +int stlink_step(stlink_t *sl); +int stlink_current_mode(stlink_t *sl); +int stlink_force_debug(stlink_t *sl); +int stlink_target_voltage(stlink_t *sl); +int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); + +int stlink_erase_flash_mass(stlink_t* sl); +int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); +int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); +uint8_t stlink_get_erased_pattern(stlink_t *sl); +int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); +int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); +int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, 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); + +int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); +int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); + +int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); +uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); +uint16_t read_uint16(const unsigned char *c, const int pt); +void stlink_core_stat(stlink_t *sl); +void stlink_print_data(stlink_t *sl); +unsigned int is_bigendian(void); +uint32_t read_uint32(const unsigned char *c, const int pt); +void write_uint32(unsigned char* buf, uint32_t ui); +void write_uint16(unsigned char* buf, uint16_t ui); +bool stlink_is_core_halted(stlink_t *sl); +int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); +int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); +int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); +int stlink_load_device_params(stlink_t *sl); + +int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); +int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); + +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); +int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); #include #include diff --git a/src/usb.c b/src/usb.c index 8db78016d..bd9f8e51e 100644 --- a/src/usb.c +++ b/src/usb.c @@ -87,11 +87,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, int res = 0; int t; - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, - txbuf, - (int) txsize, - &res, - 3000); + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, (int) txsize, &res, 3000); if (t) { printf("[!] send_recv send request failed: %s\n", libusb_error_name(t)); return -1; @@ -101,11 +97,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, } if (rxsize != 0) { - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, - rxbuf, - (int) rxsize, - &res, - 3000); + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int) rxsize, &res, 3000); if (t) { printf("[!] send_recv read reply failed: %s\n", libusb_error_name(t)); @@ -116,11 +108,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, if ((handle->protocoll == 1) && terminate) { /* Read the SG reply */ unsigned char sg_buf[13]; - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, - sg_buf, - 13, - &res, - 3000); + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, sg_buf, 13, &res, 3000); if (t) { printf("[!] send_recv read storage failed: %s\n", libusb_error_name(t)); @@ -270,7 +258,8 @@ int _stlink_usb_get_rw_status(stlink_t *sl) unsigned char* const rdata = sl->q_buf; struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; - int i, ret = 0; + int i; + int16_t ret = 0; i = fill_command(sl, SG_DXFER_FROM_DEV, 12); cmd[i++] = STLINK_DEBUG_COMMAND; @@ -456,6 +445,7 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; + // Select correct API-Version for entering SWD mode: V1 API (0x20) or V2 API (0x30) cmd[i++] = sl->version.jtag_api == STLINK_JTAG_API_V1 ? STLINK_DEBUG_APIV1_ENTER : STLINK_DEBUG_APIV2_ENTER; cmd[i++] = STLINK_DEBUG_ENTER_SWD; From 7a5b6ef2f707660e79d2ff7fde4aa84390da19be Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 9 May 2020 22:20:17 +0200 Subject: [PATCH 0922/1435] Whitespace cleanup --- include/stlink.h | 331 ++++++++++++++++++++++++----------------------- 1 file changed, 166 insertions(+), 165 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index b8080fd5e..68ca0ab39 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -1,9 +1,10 @@ /* * File: stlink.h * - * This should contain all the common top level stlink interfaces, regardless - * of how the backend does the work.... + * This should contain all the common top level stlink interfaces, + * regardless of how the backend does the work.... */ + #ifndef STLINK_H #define STLINK_H @@ -19,12 +20,12 @@ extern "C" { #define STLINK_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) - // Max data transfer size. - // 6kB = max mem32_read block, 8kB sram - //#define Q_BUF_LEN 96 +// Max data transfer size. +// 6kB = max mem32_read block, 8kB sram +//#define Q_BUF_LEN 96 #define Q_BUF_LEN (1024 * 100) - // STLINK_DEBUG_RESETSYS, etc: +// STLINK_DEBUG_RESETSYS, etc: #define STLINK_CORE_RUNNING 0x80 #define STLINK_CORE_HALTED 0x81 #define STLINK_CORE_STAT_UNKNOWN -1 @@ -37,13 +38,13 @@ extern "C" { #define STLINK_DFU_COMMAND 0xF3 #define STLINK_DFU_EXIT 0x07 - // STLINK_GET_CURRENT_MODE +// STLINK_GET_CURRENT_MODE #define STLINK_DEV_DFU_MODE 0x00 #define STLINK_DEV_MASS_MODE 0x01 #define STLINK_DEV_DEBUG_MODE 0x02 #define STLINK_DEV_UNKNOWN_MODE -1 - // TODO - possible poor names... +// TODO - possible poor names... #define STLINK_SWD_ENTER 0x30 #define STLINK_SWD_READCOREID 0x32 // TBD #define STLINK_JTAG_WRITEDEBUG_32BIT 0x35 @@ -76,176 +77,176 @@ extern "C" { #define STLINK_V3_MAX_FREQ_NB 10 - /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ +/* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ #define C_BUF_LEN 32 - enum stlink_flash_type { - STLINK_FLASH_TYPE_UNKNOWN = 0, - STLINK_FLASH_TYPE_F0, /* used by f0, f1 (except f1xl),f3. */ - STLINK_FLASH_TYPE_F1_XL, /* f0 flash with dual bank, apparently */ - STLINK_FLASH_TYPE_F4, /* used by f2, f4, f7 */ - STLINK_FLASH_TYPE_L0, /* l0, l1 */ - STLINK_FLASH_TYPE_L4, /* l4, l4+ */ - STLINK_FLASH_TYPE_G0, - STLINK_FLASH_TYPE_G4, - STLINK_FLASH_TYPE_WB - }; - - struct stlink_reg { - uint32_t r[16]; - uint32_t s[32]; - uint32_t xpsr; - uint32_t main_sp; - uint32_t process_sp; - uint32_t rw; - uint32_t rw2; - uint8_t control; - uint8_t faultmask; - uint8_t basepri; - uint8_t primask; - uint32_t fpscr; - }; - - typedef uint32_t stm32_addr_t; +enum stlink_flash_type { + STLINK_FLASH_TYPE_UNKNOWN = 0, + STLINK_FLASH_TYPE_F0, /* used by f0, f1 (except f1xl),f3. */ + STLINK_FLASH_TYPE_F1_XL, /* f0 flash with dual bank, apparently */ + STLINK_FLASH_TYPE_F4, /* used by f2, f4, f7 */ + STLINK_FLASH_TYPE_L0, /* l0, l1 */ + STLINK_FLASH_TYPE_L4, /* l4, l4+ */ + STLINK_FLASH_TYPE_G0, + STLINK_FLASH_TYPE_G4, + STLINK_FLASH_TYPE_WB +}; + +struct stlink_reg { + uint32_t r[16]; + uint32_t s[32]; + uint32_t xpsr; + uint32_t main_sp; + uint32_t process_sp; + uint32_t rw; + uint32_t rw2; + uint8_t control; + uint8_t faultmask; + uint8_t basepri; + uint8_t primask; + uint32_t fpscr; +}; + +typedef uint32_t stm32_addr_t; typedef struct flash_loader { stm32_addr_t loader_addr; /* loader sram adddr */ stm32_addr_t buf_addr; /* buffer sram address */ } flash_loader_t; - typedef struct _cortex_m3_cpuid_ { - uint16_t implementer_id; - uint16_t variant; - uint16_t part; - uint8_t revision; - } cortex_m3_cpuid_t; - - typedef struct stlink_version_ { - uint32_t stlink_v; - uint32_t jtag_v; - uint32_t swim_v; - uint32_t st_vid; - uint32_t stlink_pid; - } stlink_version_t; - - enum transport_type { - TRANSPORT_TYPE_ZERO = 0, - TRANSPORT_TYPE_LIBSG, - TRANSPORT_TYPE_LIBUSB, - TRANSPORT_TYPE_INVALID - }; +typedef struct _cortex_m3_cpuid_ { + uint16_t implementer_id; + uint16_t variant; + uint16_t part; + uint8_t revision; +} cortex_m3_cpuid_t; + +typedef struct stlink_version_ { + uint32_t stlink_v; + uint32_t jtag_v; + uint32_t swim_v; + uint32_t st_vid; + uint32_t stlink_pid; +} stlink_version_t; + +enum transport_type { + TRANSPORT_TYPE_ZERO = 0, + TRANSPORT_TYPE_LIBSG, + TRANSPORT_TYPE_LIBUSB, + TRANSPORT_TYPE_INVALID +}; typedef struct _stlink stlink_t; #include - struct _stlink { - struct _stlink_backend *backend; - void *backend_data; - - // Room for the command header - unsigned char c_buf[C_BUF_LEN]; - // Data transferred from or to device - unsigned char q_buf[Q_BUF_LEN]; - int q_len; - - // transport layer verboseness: 0 for no debug info, 10 for lots - int verbose; - int opt; // set by main() in tools/flash.c, empty tail bytes drop optimization - uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID - uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram - int core_stat; // set by stlink_status(), values STLINK_CORE_xxxxx - - char serial[STLINK_SERIAL_MAX_SIZE]; - int serial_size; - - int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR - - enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx - bool has_dual_bank; - - stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() - size_t flash_size; // calculated by stlink_load_device_params() - size_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() - - /* sram settings */ - stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() - size_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() - - /* option settings */ - stm32_addr_t option_base; - size_t option_size; - - // bootloader - // sys_base and sys_size are not used by the tools, but are only there to - // download the bootloader code (see tests/sg.c) - stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() - size_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() - - struct stlink_version_ version; - }; - - int stlink_enter_swd_mode(stlink_t *sl); - int stlink_enter_jtag_mode(stlink_t *sl); - int stlink_exit_debug_mode(stlink_t *sl); - int stlink_exit_dfu_mode(stlink_t *sl); - void stlink_close(stlink_t *sl); - int stlink_core_id(stlink_t *sl); - int stlink_reset(stlink_t *sl); - int stlink_jtag_reset(stlink_t *sl, int value); - int stlink_run(stlink_t *sl); - int stlink_status(stlink_t *sl); - int stlink_version(stlink_t *sl); - int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); - int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); - int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp); - int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); - int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); - int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); - int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, struct stlink_reg *regp); - int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); - int stlink_step(stlink_t *sl); - int stlink_current_mode(stlink_t *sl); - int stlink_force_debug(stlink_t *sl); - int stlink_target_voltage(stlink_t *sl); - int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); - - int stlink_erase_flash_mass(stlink_t* sl); - int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); - int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); - uint8_t stlink_get_erased_pattern(stlink_t *sl); - int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); - int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); - int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, 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); - - int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); - int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); - - int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); - uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); - uint16_t read_uint16(const unsigned char *c, const int pt); - void stlink_core_stat(stlink_t *sl); - void stlink_print_data(stlink_t *sl); - unsigned int is_bigendian(void); - uint32_t read_uint32(const unsigned char *c, const int pt); - void write_uint32(unsigned char* buf, uint32_t ui); - void write_uint16(unsigned char* buf, uint16_t ui); - bool stlink_is_core_halted(stlink_t *sl); - int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); - int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); - int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); - int stlink_load_device_params(stlink_t *sl); - - int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); - int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); - - int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); - int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); +struct _stlink { + struct _stlink_backend *backend; + void *backend_data; + + // Room for the command header + unsigned char c_buf[C_BUF_LEN]; + // Data transferred from or to device + unsigned char q_buf[Q_BUF_LEN]; + int q_len; + + // transport layer verboseness: 0 for no debug info, 10 for lots + int verbose; + int opt; // set by main() in tools/flash.c, empty tail bytes drop optimization + uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID + uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram + int core_stat; // set by stlink_status(), values STLINK_CORE_xxxxx + + char serial[STLINK_SERIAL_MAX_SIZE]; + int serial_size; + + int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR + + enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx + bool has_dual_bank; + + stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() + size_t flash_size; // calculated by stlink_load_device_params() + size_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() + + /* sram settings */ + stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() + size_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() + + /* option settings */ + stm32_addr_t option_base; + size_t option_size; + + // bootloader + // sys_base and sys_size are not used by the tools, but are only there to + // download the bootloader code (see tests/sg.c) + stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() + size_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() + + struct stlink_version_ version; +}; + +int stlink_enter_swd_mode(stlink_t *sl); +int stlink_enter_jtag_mode(stlink_t *sl); +int stlink_exit_debug_mode(stlink_t *sl); +int stlink_exit_dfu_mode(stlink_t *sl); +void stlink_close(stlink_t *sl); +int stlink_core_id(stlink_t *sl); +int stlink_reset(stlink_t *sl); +int stlink_jtag_reset(stlink_t *sl, int value); +int stlink_run(stlink_t *sl); +int stlink_status(stlink_t *sl); +int stlink_version(stlink_t *sl); +int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); +int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); +int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); +int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp); +int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); +int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); +int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); +int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, struct stlink_reg *regp); +int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); +int stlink_step(stlink_t *sl); +int stlink_current_mode(stlink_t *sl); +int stlink_force_debug(stlink_t *sl); +int stlink_target_voltage(stlink_t *sl); +int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); + +int stlink_erase_flash_mass(stlink_t* sl); +int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); +int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); +uint8_t stlink_get_erased_pattern(stlink_t *sl); +int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); +int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); +int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, 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); + +int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); +int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); + +int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); +uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); +uint16_t read_uint16(const unsigned char *c, const int pt); +void stlink_core_stat(stlink_t *sl); +void stlink_print_data(stlink_t *sl); +unsigned int is_bigendian(void); +uint32_t read_uint32(const unsigned char *c, const int pt); +void write_uint32(unsigned char* buf, uint32_t ui); +void write_uint16(unsigned char* buf, uint16_t ui); +bool stlink_is_core_halted(stlink_t *sl); +int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); +int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); +int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); +int stlink_load_device_params(stlink_t *sl); + +int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); +int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); + +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); +int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); #include #include From 7bb34fcfb2a19c03c7daa2986aad4515f699f24b Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 10 May 2020 00:47:37 +0200 Subject: [PATCH 0923/1435] Update for windows binary packaging - Updated steps for release preparation - Changed destination for binary archives (Closes #798) --- cmake/packaging/cpack_config.cmake | 3 +-- cmake/packaging/windows/generate_binaries.sh | 2 ++ doc/release.md | 13 +++++++------ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake index c81362896..a0fddd71c 100644 --- a/cmake/packaging/cpack_config.cmake +++ b/cmake/packaging/cpack_config.cmake @@ -25,12 +25,11 @@ elseif (WIN32 AND NOT EXISTS "/etc/debian_version") set(CPACK_INSTALL_PREFIX "") elseif (WIN32) # Windows cross-build on Debian/Ubuntu - set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_SOURCE_DIR}/build/Release/dist") set(CPACK_GENERATOR "ZIP") set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-${TOOLCHAIN_PREFIX}") set(CPACK_INSTALL_PREFIX "") -elseif (EXISTS "/etc/debian_version") # Package-build is available on Debian/Ubuntu only +elseif (EXISTS "/etc/debian_version" AND NOT EXISTS WIN32) # Package-build is available on Debian/Ubuntu only message(STATUS "Debian-based Linux OS detected") set(CPACK_GENERATOR "DEB;RPM") # RPM requires package `rpm` diff --git a/cmake/packaging/windows/generate_binaries.sh b/cmake/packaging/windows/generate_binaries.sh index ba5b965f5..d38f8d62f 100644 --- a/cmake/packaging/windows/generate_binaries.sh +++ b/cmake/packaging/windows/generate_binaries.sh @@ -12,6 +12,7 @@ cmake -DCMAKE_SYSTEM_NAME=Windows \ -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=./cmake/modules/set_toolchain.cmake .. make package +cp dist/*.zip ../build/Release/dist cd .. rm -rf build-mingw @@ -22,5 +23,6 @@ cmake -DCMAKE_SYSTEM_NAME=Windows \ -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=./cmake/modules/set_toolchain.cmake .. make package +cp dist/*.zip ../build/Release/dist cd .. rm -rf build-mingw diff --git a/doc/release.md b/doc/release.md index ae8b864ee..4b536d95a 100644 --- a/doc/release.md +++ b/doc/release.md @@ -1,10 +1,11 @@ Release ======= -This document describes the steps it takes for developers to create a release +This document describes the necessary steps for developers to create a release: -1. Update `.version` with semantic version: `x.x.x` -2. Update `README.md` with semantic version `x.x.x` in commits badge -2. Create and push git tag and commits `git tag x.x.x` -3. Create source tarball/zipfile with `make dist` -4. Create binary package with `make package` +1. Update `CHANGELOG.md` and `cmake/packaging/deb/changelog` +2. Update `.version` with semantic version: `x.x.x` +3. Update `README.md` with semantic version `x.x.x` in commits badge +4. Create and push git tag and commits `git tag x.x.x` +5. Create binary packages (.rpm / .deb / .zip) with `make package && sh ./cmake/packaging/windows/generate_binaries.sh` +6. Upload packages to the [release page](https://github.com/stlink-org/stlink/releases) of this project From d11e6f4c8affac671e42ed55d88d6b911418a215 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 10 May 2020 02:11:08 +0200 Subject: [PATCH 0924/1435] Updated tutorial - Added table for available tool options - Removed install instructions for OpenOCD - Removed outdated content - Fixed toolset description in desktop-file - Added documentation for the stlink-gui (Closes #884) --- doc/tutorial.md | 167 +++++------------------------- src/stlink-gui/stlink-gui.desktop | 2 +- 2 files changed, 25 insertions(+), 144 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index ad64a8db8..694142184 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1,35 +1,32 @@ stlink Tools Tutorial ===================== -## Useful tool options +## Available tools and options -### st-flash - -#### --flash=n[k][m] - -(since v1.4.0) - -You can specify `--flash=128k` for example, to override the STM32F103C8T6 to assume 128k of flash instead of the default of 64k. -This option accepts decimal (128k), octal 0200k, or hex 0x80k. -Obviously leaving the multiplier out is equally valid, for example: `--flash=0x20000`. -The size may be followed by an optional "k" or "m" to multiply the given value by 1k (1024) or 1M respectively. - -#### Checksum for binary files +| Option | Tool | Description | Available
    since | +| --- | --- | --- | --- | +| --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k
    for the STM32F103C8T6 to assume 128k of flash being present. This option accepts
    decimal (128k), octal 0200k, or hex 0x80k values. Leaving the multiplier out is
    equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional "k"
    or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | +| --freq=n[k][m] | st-flash,
    st-util | The frequency of the SWD/JTAG interface can be specified, to override the default
    1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
    the unit `Hz` being left out. Valid frequencies are `5K, 15K, 25K, 50K, 100K,`
    `125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | +| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at
    the end of binary file. This may cause some garbage data left after a flash operation.
    This option was enabled by default in earlier releases. | v1.6.1 | +| --version | st-info,
    st-flash,
    st-util | Print version information. | | +| --help | st-flash,
    st-util | Print list of available commands. _(To be added to this table.)_ | | +### st-flash: Checksum for binary files When flashing a file, a checksum is calculated for the binary file, both in md5 and the sum algorithm. The latter is also used by the official ST-Link utility tool from STMicroelectronics as described in the document: [`UM0892 - User manual - STM32 ST-LINK utility software description`](https://www.st.com/resource/en/user_manual/cd00262073-stm32-stlink-utility-software-description-stmicroelectronics.pdf). -#### --freq=n[k][m] - -(since v1.6.1) +### stlink-gui +The `stlink` toolset also provides a GUI which is an optional feature. It is only installed if a gtk3 toolset has been detected during package installation or compilation from source. It is not available for Windows. If you prefer to have an user interface on the latter system, please use the official `ST-LINK Utility` instead. -You can specify the frequency of SWD/JTAG interface, to override the default 1800KHz configuration. This option accpets decimal only (5K or 1.8M). `Hz` is left out in this option. Valid frequencies are `5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)` +The stlink-gui offers the following features: +* Connect/disconnect to a present STlink programmer +* Display basic device information +* Select a binary file from the local filesystem to flash it to the detected device connected to the programmer +* Export the memory of the connected chip to a file which can be saved to the local filesystem +* Display of the memory address map in the main window for each, the device memory and a loaded binary file -#### --opt +Within the GUI main window tooltips explain the available user elements. -(since v1.6.1, optional; enabled by default from v1.0.0 to v1.6.0) - -You can enable the optimization to skip flashing empty (0x00 or 0xff) bytes at the end of binary file. May cause some garbage data left after a flash. ## Solutions to common problems ### a) STLINK/v1 driver: Issue with Kernel Extension (kext) (macOS 10.11 and later only) @@ -153,22 +150,13 @@ This guide details the use of STMicroelectronics STM32 discovery kits in an open ## Installing a GNU toolchain -Any toolchain supporting the cortex m3 should do. You can find the -necessary to install such a toolchain here: - -``` -https://github.com/esden/summon-arm-toolchain -``` - -Details for the installation are provided in the topmost `README` file. -This documentation assumes the toolchains is installed in a -`$TOOLCHAIN_PATH`. +Any toolchain supporting the cortex m3 should do. ## Using the GDB server -This assumes you have got the libopencm3 project downloaded in `ocm3`. -The libopencm3 project has some good, reliable examples for each of the -Discovery boards. +This assumes you have got the [libopencm3](http://www.libopencm3.org) project downloaded in `ocm3`. +The libopencm3 project provides a firmware library, with solid examples for Cortex M3, M4 and M0 processors +from any vendor. It has some good, reliable examples for each of the Discovery boards. Even if you don’t plan on using libopencm3, the examples they provide will help you verify that: @@ -179,7 +167,7 @@ will help you verify that: - Your arm-none-eabi-gdb is functional - Your board is functional -A GDB server must be started to interact with the STM32 by running +A GDB server must be started to interact with the STM32 by running st-util tool : ``` @@ -283,7 +271,7 @@ There are a few options: Do not reset board on connection. ``` -The STLink device to use can be specified using the --serial parameter, or via +The STLink device to use can be specified using the --serial parameter, or via the environment variable STLINK_DEVICE on the format :. Then, in your project directory, someting like this... @@ -373,42 +361,6 @@ Example to read and write option bytes (currently writing only supported for STM ./st-flash --debug --reset --format binary --flash=128k write option_bytes_dump.bin 0x1FFF7800 ``` -## Installation of openOCD on Mac OS X with STlink-v2: - -`sudo port install openocd +jlink +stlink +ft2232` - -`/opt/local/bin/openocd --version` - -> Open On-Chip Debugger 0.7.0 (2014-08-11-22:12) - -`openocd -f /opt/local/share/openocd/scripts/interface/stlink-v2.cfg -f /opt/local/share/openocd/scripts/target/stm32f1x_stlink.cfg ` - -> Open On-Chip Debugger 0.8.0 (2014-08-11-15:36) -> -> Licensed under GNU GPL v2 -> -> For bug reports, read http://openocd.sourceforge.net/doc/doxygen/bugs.html -> -> Info : This adapter doesn't support configurable speed -> -> Info : STLINK v2 JTAG v21 API v2 SWIM v4 VID 0x0483 PID 0x3748 -> -> Info : using stlink api v2 -> -> Info : Target voltage: 3.244269 -> -> Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints - -and connecting to the server through telnet yields a successful installation - -`telnet localhost 4444` - -> Connected to localhost. -> -> Escape character is '^]'. -> -> Open On-Chip Debugger - FAQ === @@ -424,74 +376,3 @@ A: Sometimes when you will try to use GDB `next` command to skip a loop, it will Q: Load command does not work in GDB. A: Some people report XML/EXPAT is not enabled by default when compiling GDB. Memory map parsing thus fail. Use --enable-expat. - -Q: How can I install stlink and flash binaries on Mac OS X ? - -A: Installed on Mac OS X 10.9.4 with ports method, - however STlink v2 does not seem to work with libusb if you upgrade to the newest firmware !! - Only older firmware on STlink v2 works. - -[https://coderwall.com/p/oznj_q](https://coderwall.com/p/oznj_q) - -``` -sudo port install libusb automake autoconf pkgconfig -aclocal --force -I /opt/local/share/aclocal -git clone https://github.com/stlink-org/stlink.git stlink-utility -cd stlink-utility -./autogen.sh -./configure -make -``` - -Then trying to flash the image with STLINK v2 : - -`./st-flash write ~/Downloads/irq.bin 0x8000000` - -> libusb_handle_events() timeout -> -> [!] send_recv - -ST-Link/V2 debugger with downgraded V2.14.3 firmware: - -https://drive.google.com/folderview?id=0Bzv7UpKpOQhnbXJVVEg4VUo2M1k - -After downgrading the firmware, flashing works as described here: - -http://community.spark.io/t/how-to-flash-a-brand-new-freshly-soldered-stm32f103-chip/3906 - -`./st-flash write ~/Downloads/irq.bin 0x8000000` - -> 2014-08-11T23:14:52 INFO src/stlink-common.c: Loading device parameters.... -> -> 2014-08-11T23:14:52 INFO src/stlink-common.c: Device connected is: F1 Medium-density device, id 0x20036410 -> -> 2014-08-11T23:14:52 INFO src/stlink-common.c: SRAM size: 0x5000 bytes (20 KiB), Flash: 0x20000 bytes (128 KiB) in -> pages of 1024 bytes -> -> 2014-08-11T23:14:52 INFO src/stlink-common.c: Attempting to write 24904 (0x6148) bytes to stm32 address: 134217728 -> (0x8000000) -> -> Flash page at addr: 0x08006000 erased -> -> 2014-08-11T23:14:53 INFO src/stlink-common.c: Finished erasing 25 pages of 1024 (0x400) bytes -> -> 2014-08-11T23:14:53 INFO src/stlink-common.c: Starting Flash write for VL/F0 core id -> -> 2014-08-11T23:14:53 INFO src/stlink-common.c: Successfully loaded flash loader in sram 24/24 pages written -> -> 2014-08-11T23:14:54 INFO src/stlink-common.c: Starting verification of write complete -> -> 2014-08-11T23:14:54 INFO src/stlink-common.c: Flash written and verified! jolly good! - - -References -========== - -- - documentation related to the STM32L mcu - -- - documentation related to the STM32L discovery kit - -- - libopencm3, a project providing a firmware library, with solid examples for Cortex M3, M4 and M0 processors from any vendor. diff --git a/src/stlink-gui/stlink-gui.desktop b/src/stlink-gui/stlink-gui.desktop index 54cb40349..72bc26ac6 100644 --- a/src/stlink-gui/stlink-gui.desktop +++ b/src/stlink-gui/stlink-gui.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Name=stlink GenericName=Stlink Tools -Comment=STM32 discovery line Linux programmer +Comment=Open source STM32 MCU programming toolset Exec=stlink-gui Icon=stlink-gui Terminal=false From 06c66ed308d6e65ad70757c7177444257cb2ea1a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 10 May 2020 16:45:13 +0200 Subject: [PATCH 0925/1435] Updated documentation - Added note on windows binary installation - Contributors now listed in separate file (Closes #738) (Closes #795) --- README.md | 5 +- cmake/packaging/cpack_config.cmake | 7 +- cmake/packaging/deb/copyright | 122 +--------------------------- contributors.txt | 124 +++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+), 124 deletions(-) create mode 100644 contributors.txt diff --git a/README.md b/README.md index 4bf663e34..842284ff7 100644 --- a/README.md +++ b/README.md @@ -66,9 +66,10 @@ Our [tutorial.md](doc/tutorial.md may help you along with some advanced tasks an **Windows**: -Please compile and install from source as described in our [compiling manual](doc/compiling.md#Windows). +As of Release v1.6.1 stand-alone Windows binaries are made available (again) on the release page of the project. +Please ensure to select the correct version for your system (i686 or x86_64). The archive file can be unzipped to any desired location as it does not contain any hardcoded paths. However we suggest to move the unzipped application folder to `C:\Program Files\` on 32-bit systems and to `C:\Program Files (x86)\` on 64-bit systems (the toolset is a 32-bit). -Long awaited binaries will be available soon... +Alternatively one may compile and install from source as described in our [compiling manual](doc/compiling.md#Windows). **macOS**: diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake index a0fddd71c..da03bb596 100644 --- a/cmake/packaging/cpack_config.cmake +++ b/cmake/packaging/cpack_config.cmake @@ -19,7 +19,7 @@ if (APPLE) set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-macosx-amd64") set(CPACK_INSTALL_PREFIX "") -elseif (WIN32 AND NOT EXISTS "/etc/debian_version") # Windows +elseif (WIN32 AND (NOT EXISTS "/etc/debian_version")) # Windows set(CPACK_GENERATOR "ZIP") set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-win32") set(CPACK_INSTALL_PREFIX "") @@ -75,6 +75,8 @@ elseif (EXISTS "/etc/debian_version" AND NOT EXISTS WIN32) # Package-build is av # Slackware & Redhat (RPM) ### + set(CPACK_SET_DESTDIR "OFF") + # CPACK_RPM_PACKAGE_SUMMARY --> Default: CPACK_PACKAGE_DESCRIPTION_SUMMARY # CPACK_RPM_PACKAGE_NAME --> Default: CPACK_PACKAGE_NAME @@ -94,6 +96,9 @@ elseif (EXISTS "/etc/debian_version" AND NOT EXISTS WIN32) # Package-build is av # CPACK_RPM_PACKAGE_VENDOR --> Default: CPACK_PACKAGE_VENDOR (as it is set) # CPACK_RPM_PACKAGE_URL --> Default: CMAKE_PROJECT_HOMEPAGE_URL set(CPACK_RPM_PACKAGE_DESCRIPTION CPACK_DEBIAN_PACKAGE_DESCRIPTION) + + ## Add CHANGELOG in rpm-specific format + ### TODO else () # No package configuration on other platforms ... endif () diff --git a/cmake/packaging/deb/copyright b/cmake/packaging/deb/copyright index 4e58490f6..37a101b98 100644 --- a/cmake/packaging/deb/copyright +++ b/cmake/packaging/deb/copyright @@ -34,124 +34,4 @@ Copyright: 2011-2020 stlink-org Jerry Jacobs [xor-gate] [Nightwalker-87] . - Alexey Cherevatenko - Alexey Panarin - Anatoli Klassen [dev26th] - Andrea Mucignat - Andrew Andrianov [necromant] - Andrey Yurovsky - Andy Isaacson - Áron Radics - A. Sheaff - Björn Hauffe - Ihor Bobalo - Breton M. Saunders - Bruno Dal Bo - Burns Fisher - Cheng Guokai (Xim) [chenguokai] - Chris Dew - Chris Hiszpanski - Chris Li - Chris Samuelson - Christian Deussen [nullsub] - Christophe Levantis - Craig Lilley - Dan Dev - Dan Hepler - Daniel Campoverde [alx741] - Daniel O'Connor - Dave Flogeras - Dave Murphy [WinterMute] - Dave Vandervies [dj3vande] - Denis Fokin - Denis Osterland - Dmitry Bravikov [bravikov] - Efe Can İçöz - Ethan Zonca - Fabien Chouteau - Florian Hars - Friedrich Beckmann - Geoffrey Brown - George Talusan [gtalusan] - Georg von Zengen - Giuseppe Barba - Greg Alexander [galexander1] - Greg Meiste [meisteg] - Guillaume Revaillot [grevaillot] - Hakkavélin - Halt Hammerzeit - htk - Ian Griffiths - Jack Peel - Jakub Tyszkowski - Jan Sarenik - Jean-Luc Béchennec - Jean-Marie Lemetayer - Jeff Kent - Jeffrey Nelson - Jens Hoffmann - Jerome Lambourg - Jim Paris - Jiří Netolický - Jerry Nosky [jnosky] - Johannes Taelman - Jonas Danielsson - Jonas Norling - Josh Bialkowski - Karl Palsson [karlp] - Kevlar Harness - Kyle Manna - Lari Lehtomäki - Martin Nowak - Matteo Collina - Max Chen - Maxime Coquelin [mcoquelin-stm32] - Maxime Vincent - Michael Pratt [prattmic] - Michael Sparmann - Mike Szczys - Magnus Lundin [mlu] - mux - Ned Konz - Nic McDonald - Nicolas Schodet - Oleksiy Slyshyk [slyshykO] - Olivier Croquette - Olivier Gay - Onno Kortmann - orangeudav - Pavel Kirienko - Pekka Nikander - Pete Nelson - Peter Zotov - Petteri Aimonen - Piotr Haber - Rene Hopf [rene-dev] - Robin Kreis - Roger Wolff [rewolff] - Rob Spanton - Rytis Karpuska - Sean Simmons - Sergey Alirzaev - Simon Wright - Stany Marcel - Stefan Misik - Sven Wegener - Joel Bodenmann [Tectu] - Tuomo Kaikkonen - Theodore A. Roth - Thomas Gärtner - Tobias Badertscher - Tom de Boer - Tristan Gingold - Uli Köhler - Uwe Bonnes [UweBonnes] - Vadim Kaushan - Vasiliy Glazov [Vascom] - Vegard Storheil Eriksen - Viacheslav Dobromyslov - Victor Mayoral Vilches - William Ransohoff [WRansohoff] - Wojciech A. Koszek - Woodrow Douglass - ... and others + and many others... A list of contributors can be found in "contributors.txt". diff --git a/contributors.txt b/contributors.txt new file mode 100644 index 000000000..32c8e58e3 --- /dev/null +++ b/contributors.txt @@ -0,0 +1,124 @@ +List of contributors to the stlink project: + +Alexey Cherevatenko +Alexey Panarin +Anatoli Klassen [dev26th] +Andrea Mucignat +Andrew Andrianov [necromant] +Andrey Yurovsky +Andy Isaacson +Áron Radics +A. Sheaff +Björn Hauffe +Ihor Bobalo +Breton M. Saunders +Bruno Dal Bo +Burns Fisher +Cheng Guokai (Xim) [chenguokai] +Chris Dew +Chris Hiszpanski +Chris Li +Chris Samuelson +Christian Deussen [nullsub] +Christophe Levantis +Craig Lilley +Dan Dev +Dan Hepler +Daniel Campoverde [alx741] +Daniel O'Connor +Dave Flogeras +Dave Murphy [WinterMute] +Dave Vandervies [dj3vande] +Denis Fokin +Denis Osterland +Dmitry Bravikov [bravikov] +Efe Can İçöz +Ethan Zonca +Fabien Chouteau +Florian Hars +Friedrich Beckmann +Geoffrey Brown +George Talusan [gtalusan] +Georg von Zengen +Giuseppe Barba +Greg Alexander [galexander1] +Greg Meiste [meisteg] +Guillaume Revaillot [grevaillot] +Hakkavélin +Halt Hammerzeit +htk +Ian Griffiths +Jack Peel +Jakub Tyszkowski +Jan Sarenik +Jean-Luc Béchennec +Jean-Marie Lemetayer +Jeff Kent +Jeffrey Nelson +Jens Hoffmann +Jerome Lambourg +Jim Paris +Jiří Netolický +Jerry Nosky [jnosky] +Johannes Taelman +Jonas Danielsson +Jonas Norling +Josh Bialkowski +Karl Palsson [karlp] +Kevlar Harness +Kyle Manna +Lari Lehtomäki +Martin Nowak +Matteo Collina +Max Chen +Maxime Coquelin [mcoquelin-stm32] +Maxime Vincent +Michael Pratt [prattmic] +Michael Sparmann +Mike Szczys +Magnus Lundin [mlu] +mux +Ned Konz +Nic McDonald +Nicolas Schodet +Oleksiy Slyshyk [slyshykO] +Olivier Croquette +Olivier Gay +Onno Kortmann +orangeudav +Pavel Kirienko +Pekka Nikander +Pete Nelson +Peter Zotov +Petteri Aimonen +Piotr Haber +Rene Hopf [rene-dev] +Robin Kreis +Roger Wolff [rewolff] +Rob Spanton +Rytis Karpuska +Sean Simmons +Sergey Alirzaev +Simon Wright +Stany Marcel +Stefan Misik +Sven Wegener +Joel Bodenmann [Tectu] +Tuomo Kaikkonen +Theodore A. Roth +Thomas Gärtner +Tobias Badertscher +Tom de Boer +Tristan Gingold +Uli Köhler +Uwe Bonnes [UweBonnes] +Vadim Kaushan +Vasiliy Glazov [Vascom] +Vegard Storheil Eriksen +Viacheslav Dobromyslov +Victor Mayoral Vilches +William Ransohoff [WRansohoff] +Wojciech A. Koszek +Woodrow Douglass + +... and others From 4c1f5b9575a90178a9f8fd29b64ccbbb00953ec9 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 13 May 2020 12:38:43 +0200 Subject: [PATCH 0926/1435] Update issue templates Added reference to #906 in bug report template --- ...ort--only-valid-if-template-is-reused--.md | 38 +++++++++++++++++++ .github/ISSUE_TEMPLATE/bug-report.md | 6 +-- 2 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md diff --git a/.github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md b/.github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md new file mode 100644 index 000000000..255596955 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md @@ -0,0 +1,38 @@ +--- +name: Bug Report (only valid if template is reused!) +about: 'Please read #906 before submitting a ticket.' +title: "[STM32 device name]: [Title]" +labels: '' +assignees: '' + +--- + +Thank you for giving feedback to the stlink project. + +In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out each of the following items appropriate to your specific problem: + +- Programmer/board type: [enter here] (e.g Stlink /v1, /v2, /v2-clone, /v2-1) +- Programmer firmware version: [enter here] (e.g STSW-LINK007 2.27.15) +- Operating system and version: [enter here] (e.g Linux, Mac OS X, Windows) +- **Stlink tools version** and/or git commit hash: [enter here] (e.g v1.1.0/git-c722056) +- Stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-util`) +- Target chip (and board if applicable): [enter here] (e.g STM32F402VG) + +Futher we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: + +Commandline-Output: + +``` +OUTPUT/ERROR of the commandline tool(s) +``` + +Expected/description: + +`short description of the expected value` + + +**NOTICE: This bug report may be closed without further notice, if not enough information is provided!** + +Thank you for your support. + +The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 2d565a3f7..344a53ea6 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -1,8 +1,8 @@ --- name: Bug Report -about: Create a report to help us improve -title: "[Your device name]: [Title]" -labels: bug/needs-investigation +about: 'Please read #906 before submitting a ticket.' +title: "[STM32 device name]: [Title]" +labels: '' assignees: '' --- From def770b0c5ea841a69e7828a11baa4c306d2ce6a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 17 May 2020 12:40:45 +0200 Subject: [PATCH 0927/1435] Bugfix & cleanup - Fixed problem "libusb: warning [libusb_exit] application left some devices open" resulting from deprecated commands reintroduced in merge commit 0a91936b263f3fd09a42fb1ec32a72a06d9a39d6. - Whitespace cleanup --- src/mingw/mingw.h | 14 +- src/usb.c | 497 +++++++++++++++++++++------------------------- 2 files changed, 234 insertions(+), 277 deletions(-) diff --git a/src/mingw/mingw.h b/src/mingw/mingw.h index e3a7267a9..8f5b992fe 100644 --- a/src/mingw/mingw.h +++ b/src/mingw/mingw.h @@ -37,7 +37,7 @@ struct pollfd { short revents; /* returned events */ }; #endif -#define poll(x, y, z) win32_poll(x, y, z) +#define poll(x, y, z) win32_poll(x, y, z) /* These wrappers do nothing special except set the global errno variable if * an error occurs (winsock doesn't do this by default). They set errno @@ -45,12 +45,12 @@ struct pollfd { * outside of this file "shouldn't" have to worry about winsock specific error * handling. */ -#define socket(x, y, z) win32_socket(x, y, z) -#define connect(x, y, z) win32_connect(x, y, z) -#define accept(x, y, z) win32_accept(x, y, z) -#define shutdown(x, y) win32_shutdown(x, y) -#define read(x, y, z) win32_read_socket(x, y, z) -#define write(x, y, z) win32_write_socket(x, y, z) +#define socket(x, y, z) win32_socket(x, y, z) +#define connect(x, y, z) win32_connect(x, y, z) +#define accept(x, y, z) win32_accept(x, y, z) +#define shutdown(x, y) win32_shutdown(x, y) +#define read(x, y, z) win32_read_socket(x, y, z) +#define write(x, y, z) win32_write_socket(x, y, z) /* Winsock uses int instead of the usual socklen_t */ typedef int socklen_t; diff --git a/src/usb.c b/src/usb.c index 3445a7464..fcb2e1b30 100644 --- a/src/usb.c +++ b/src/usb.c @@ -17,13 +17,11 @@ enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80}; -static inline uint32_t le_to_h_u32(const uint8_t* buf) -{ +static inline uint32_t le_to_h_u32(const uint8_t* buf) { return (uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24); } -static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, uint32_t khz) -{ +static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, uint32_t khz) { unsigned int i; int speed_index = -1; int speed_diff = INT_MAX; @@ -31,59 +29,51 @@ static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, u bool match = true; for (i = 0; i < map_size; i++) { - if (!map[i]) - continue; - last_valid_speed = i; - if (khz == map[i]) { - speed_index = i; - break; - } else { - int current_diff = khz - map[i]; - /* get abs value for comparison */ - current_diff = (current_diff > 0) ? current_diff : -current_diff; - if ((current_diff < speed_diff) && khz >= map[i]) { - speed_diff = current_diff; - speed_index = i; - } - } + if (!map[i]) continue; + last_valid_speed = i; + if (khz == map[i]) { + speed_index = i; + break; + } else { + int current_diff = khz - map[i]; + // Get abs value for comparison + current_diff = (current_diff > 0) ? current_diff : -current_diff; + if ((current_diff < speed_diff) && khz >= map[i]) { + speed_diff = current_diff; + speed_index = i; + } + } } if (speed_index == -1) { - /* this will only be here if we cannot match the slow speed. - * use the slowest speed we support.*/ - speed_index = last_valid_speed; - match = false; - } else if (i == map_size) - match = false; - + // This will only be here if we cannot match the slow speed. Use the slowest speed we support. + speed_index = last_valid_speed; + match = false; + } else if (i == map_size) { + match = false; + } if (!match) { - ILOG("Unable to match requested speed %d kHz, using %d kHz\n", \ - khz, map[speed_index]); + ILOG("Unable to match requested speed %d kHz, using %d kHz\n", khz, map[speed_index]); } return speed_index; } void _stlink_usb_close(stlink_t* sl) { - if (!sl) - return; + if (!sl) return; struct stlink_libusb * const handle = sl->backend_data; - // maybe we couldn't even get the usb device? + // Maybe we couldn't even get the usb device? if (handle != NULL) { - if (handle->usb_handle != NULL) { - libusb_close(handle->usb_handle); - } - + if (handle->usb_handle != NULL) libusb_close(handle->usb_handle); libusb_exit(handle->libusb_ctx); free(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 */ + 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; int t; @@ -93,43 +83,39 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, return -1; } else if ((size_t)res != txsize) { printf("[!] send_recv send request wrote %u bytes (instead of %u).\n", - (unsigned int)res, (unsigned int)txsize); + (unsigned int)res, (unsigned int)txsize); } if (rxsize != 0) { t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int) rxsize, &res, 3000); if (t) { - printf("[!] send_recv read reply failed: %s\n", - libusb_error_name(t)); + printf("[!] send_recv read reply failed: %s\n", libusb_error_name(t)); return -1; } } if ((handle->protocoll == 1) && terminate) { - /* Read the SG reply */ + // Read the SG reply unsigned char sg_buf[13]; t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, sg_buf, 13, &res, 3000); if (t) { - printf("[!] send_recv read storage failed: %s\n", - libusb_error_name(t)); + printf("[!] send_recv read storage failed: %s\n", libusb_error_name(t)); return -1; } - /* The STLink doesn't seem to evaluate the sequence number */ + // The STLink doesn't seem to evaluate the sequence number. handle->sg_transfer_idx++; } return res; } -static inline int send_only -(struct stlink_libusb* handle, int terminate, - unsigned char* txbuf, size_t txsize) { +static inline int send_only(struct stlink_libusb* handle, int terminate, + unsigned char* txbuf, size_t txsize) { return (int) send_recv(handle, terminate, txbuf, txsize, NULL, 0); } -static int fill_command -(stlink_t * sl, enum SCSI_Generic_Direction dir, uint32_t len) { +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; @@ -142,9 +128,9 @@ static int fill_command 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 */ + cmd[i++] = (dir == SG_DXFER_FROM_DEV) ? 0x80 : 0; + cmd[i++] = 0; // Logical unit + cmd[i++] = 0xa; // Command length } return i; } @@ -226,6 +212,7 @@ int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { return (int) size; } *data = read_uint32(rdata, 4); + return 0; } @@ -250,10 +237,8 @@ int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { return 0; } -int _stlink_usb_get_rw_status(stlink_t *sl) -{ - if (sl->version.jtag_api == STLINK_JTAG_API_V1) - return -1; +int _stlink_usb_get_rw_status(stlink_t *sl) { + if (sl->version.jtag_api == STLINK_JTAG_API_V1) return -1; unsigned char* const rdata = sl->q_buf; struct stlink_libusb * const slu = sl->backend_data; @@ -270,8 +255,8 @@ int _stlink_usb_get_rw_status(stlink_t *sl) cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS; ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 2); } - if (ret < 0) - return -1; + if (ret < 0) return -1; + return 0; } @@ -287,11 +272,9 @@ int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); ret = send_only(slu, 0, cmd, slu->cmd_len); - if (ret == -1) - return ret; + if (ret == -1) return ret; ret = send_only(slu, 0, data, len); - if (ret == -1) - return ret; + if (ret == -1) return ret; return _stlink_usb_get_rw_status(sl); } @@ -308,12 +291,9 @@ int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); ret = send_only(slu, 0, cmd, slu->cmd_len); - if (ret == -1) - return ret; - + if (ret == -1) return ret; ret = send_only(slu, 1, data, len); - if (ret == -1) - return ret; + if (ret == -1) return ret; return 0; } @@ -333,6 +313,7 @@ int _stlink_usb_current_mode(stlink_t * sl) { printf("[!] send_recv STLINK_GET_CURRENT_MODE\n"); return -1; } + return sl->q_buf[0]; } @@ -345,21 +326,22 @@ int _stlink_usb_core_id(stlink_t * sl) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - if (sl->version.jtag_api == STLINK_JTAG_API_V1) + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { cmd[i++] = STLINK_DEBUG_READCOREID; - else + } else { cmd[i++] = STLINK_DEBUG_APIV2_READ_IDCODES; - + } size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_DEBUG_READCOREID\n"); return -1; } - if (sl->version.jtag_api == STLINK_JTAG_API_V1) + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { sl->core_id = read_uint32(data, 0); - else + } else { sl->core_id = read_uint32(data, 4); + } return 0; } int _stlink_usb_status_v2(stlink_t *sl) @@ -385,9 +367,7 @@ int _stlink_usb_status_v2(stlink_t *sl) } int _stlink_usb_status(stlink_t * sl) { - if (sl->version.jtag_api != STLINK_JTAG_API_V1) { - return _stlink_usb_status_v2(sl); - } + if (sl->version.jtag_api != STLINK_JTAG_API_V1) return _stlink_usb_status_v2(sl); struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; @@ -398,7 +378,6 @@ int _stlink_usb_status(stlink_t * sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_GETSTATUS; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_DEBUG_GETSTATUS\n"); @@ -445,7 +424,7 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - // Select correct API-Version for entering SWD mode: V1 API (0x20) or V2 API (0x30) + // Select correct API-Version for entering SWD mode: V1 API (0x20) or V2 API (0x30). cmd[i++] = sl->version.jtag_api == STLINK_JTAG_API_V1 ? STLINK_DEBUG_APIV1_ENTER : STLINK_DEBUG_APIV2_ENTER; cmd[i++] = STLINK_DEBUG_ENTER_SWD; @@ -455,8 +434,8 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); } if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_ENTER\n"); - return (int) size; + printf("[!] send_recv STLINK_DEBUG_ENTER\n"); + return (int) size; } return 0; @@ -470,7 +449,6 @@ int _stlink_usb_exit_dfu_mode(stlink_t* sl) { cmd[i++] = STLINK_DFU_COMMAND; cmd[i++] = STLINK_DFU_EXIT; - size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { printf("[!] send_recv STLINK_DFU_EXIT\n"); @@ -490,10 +468,11 @@ int _stlink_usb_reset(stlink_t * sl) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - if (sl->version.jtag_api == STLINK_JTAG_API_V1) + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { cmd[i++] = STLINK_DEBUG_APIV1_RESETSYS; - else + } else { cmd[i++] = STLINK_DEBUG_APIV2_RESETSYS; + } size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { @@ -501,12 +480,11 @@ int _stlink_usb_reset(stlink_t * sl) { return (int) size; } - // Reset through AIRCR so NRST does not need to be connected - return stlink_write_debug32(sl, STLINK_REG_AIRCR, - STLINK_REG_AIRCR_VECTKEY | STLINK_REG_AIRCR_SYSRESETREQ); + // Reset through AIRCR so that NRST does not need to be connected. + return stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | + STLINK_REG_AIRCR_SYSRESETREQ); } - int _stlink_usb_jtag_reset(stlink_t * sl, int value) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; @@ -518,7 +496,6 @@ int _stlink_usb_jtag_reset(stlink_t * sl, int value) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_JTAG_DRIVE_NRST; cmd[i++] = value; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_JTAG_DRIVE_NRST\n"); @@ -539,7 +516,6 @@ int _stlink_usb_step(stlink_t* sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_STEPCORE; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_DEBUG_STEPCORE\n"); @@ -557,6 +533,7 @@ int _stlink_usb_run(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; int res; + if (sl->version.jtag_api != STLINK_JTAG_API_V1) { res = _stlink_usb_write_debug32(sl, DCB_DHCSR, DBGKEY|C_DEBUGEN); return res; @@ -571,7 +548,6 @@ int _stlink_usb_run(stlink_t* sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_RUNCORE; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_DEBUG_RUNCORE\n"); @@ -589,6 +565,7 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { ssize_t size; int rep_len = 2; int i; + // clock speed only supported by stlink/v2 and for firmware >= 22 if (sl->version.stlink_v == 2 && sl->version.jtag_v >= 22) { i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); @@ -597,7 +574,6 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { cmd[i++] = STLINK_DEBUG_APIV2_SWD_SET_FREQ; cmd[i++] = clk_divisor & 0xFF; cmd[i++] = (clk_divisor >> 8) & 0xFF; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_DEBUG_APIV2_SWD_SET_FREQ\n"); @@ -613,7 +589,6 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_APIV3_GET_COM_FREQ; cmd[i++] = 0; // SWD mode - size = send_recv(slu, 1, cmd, slu->cmd_len, data, 52); if (size == -1) { printf("[!] send_recv STLINK_APIV3_GET_COM_FREQ\n"); @@ -622,15 +597,12 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { int speeds_size = data[8]; - if (speeds_size > STLINK_V3_MAX_FREQ_NB) - speeds_size = STLINK_V3_MAX_FREQ_NB; + if (speeds_size > STLINK_V3_MAX_FREQ_NB) speeds_size = STLINK_V3_MAX_FREQ_NB; - for (i = 0; i < speeds_size; i++) - map[i] = le_to_h_u32(&data[12 + 4 * i]); + for (i = 0; i < speeds_size; i++) map[i] = le_to_h_u32(&data[12 + 4 * i]); - /* set to zero all the next entries */ - for (i = speeds_size; i < STLINK_V3_MAX_FREQ_NB; i++) - map[i] = 0; + // Set to zero all the next entries + for (i = speeds_size; i < STLINK_V3_MAX_FREQ_NB; i++) map[i] = 0; speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), 1800); @@ -685,16 +657,16 @@ int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { cmd[i++] = STLINK_DEBUG_READMEM_32BIT; write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); - size = send_recv(slu, 1, cmd, slu->cmd_len, data, len); + if (size == -1) { printf("[!] send_recv STLINK_DEBUG_READMEM_32BIT\n"); return (int) size; } sl->q_len = (int) size; - stlink_print_data(sl); + return 0; } @@ -707,11 +679,15 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - if (sl->version.jtag_api == STLINK_JTAG_API_V1) + + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { cmd[i++] = STLINK_DEBUG_APIV1_READALLREGS; - else + } else { cmd[i++] = STLINK_DEBUG_APIV2_READALLREGS; + } + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_DEBUG_READALLREGS\n"); return (int) size; @@ -722,15 +698,15 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { int reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; sl->q_len = (int) size; stlink_print_data(sl); - for(i=reg_offset; i<16; i++) - regp->r[i]= read_uint32(sl->q_buf, i*4); + + for(i=reg_offset; i<16; i++) regp->r[i]= read_uint32(sl->q_buf, i*4); regp->xpsr = read_uint32(sl->q_buf, reg_offset + 64); regp->main_sp = read_uint32(sl->q_buf, reg_offset + 68); regp->process_sp = read_uint32(sl->q_buf, reg_offset + 72); regp->rw = read_uint32(sl->q_buf, reg_offset + 76); regp->rw2 = read_uint32(sl->q_buf, reg_offset + 80); - if (sl->verbose < 2) - return 0; + + if (sl->verbose < 2) return 0; DLOG("xpsr = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 64)); DLOG("main_sp = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 68)); @@ -752,16 +728,21 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - if (sl->version.jtag_api == STLINK_JTAG_API_V1) + + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { cmd[i++] = STLINK_DEBUG_APIV1_READREG; - else + } else { cmd[i++] = STLINK_DEBUG_APIV2_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 STLINK_DEBUG_READREG\n"); return (int) size; } + sl->q_len = (int) size; stlink_print_data(sl); r = read_uint32(sl->q_buf, reg_offset); @@ -778,10 +759,10 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_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; @@ -796,34 +777,30 @@ int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg int ret; sl->q_buf[0] = (unsigned char) r_idx; - for (int i = 1; i < 4; i++) { - sl->q_buf[i] = 0; - } + for (int i = 1; i < 4; i++) sl->q_buf[i] = 0; ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4); - if (ret == -1) - return ret; + if (ret == -1) return ret; ret = _stlink_usb_read_mem32(sl, STLINK_REG_DCRDR, 4); - if (ret == -1) - return ret; + if (ret == -1) return ret; r = read_uint32(sl->q_buf, 0); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); switch (r_idx) { - case 0x14: - regp->primask = (uint8_t) (r & 0xFF); - regp->basepri = (uint8_t) ((r>>8) & 0xFF); - regp->faultmask = (uint8_t) ((r>>16) & 0xFF); - regp->control = (uint8_t) ((r>>24) & 0xFF); - break; - case 0x21: - regp->fpscr = r; - break; - default: - regp->s[r_idx - 0x40] = r; - break; + case 0x14: + regp->primask = (uint8_t) (r & 0xFF); + regp->basepri = (uint8_t) ((r>>8) & 0xFF); + regp->faultmask = (uint8_t) ((r>>16) & 0xFF); + regp->control = (uint8_t) ((r>>24) & 0xFF); + break; + case 0x21: + regp->fpscr = r; + break; + default: + regp->s[r_idx - 0x40] = r; + break; } return 0; @@ -833,17 +810,14 @@ int _stlink_usb_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) int ret; ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); - if (ret == -1) - return ret; + if (ret == -1) return ret; ret = _stlink_usb_read_unsupported_reg(sl, 0x21, regp); - if (ret == -1) - return ret; + if (ret == -1) return ret; for (int i = 0; i < 32; i++) { ret = _stlink_usb_read_unsupported_reg(sl, 0x40+i, regp); - if (ret == -1) - return ret; + if (ret == -1) return ret; } return 0; @@ -856,24 +830,35 @@ int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, str if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ /* These are held in the same register */ ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); - if (ret == -1) - return ret; + if (ret == -1) return ret; val = (uint8_t) (val>>24); switch (r_idx) { - case 0x1C: /* control */ - val = (((uint32_t) val) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) regp->primask); - break; - case 0x1D: /* faultmask */ - val = (((uint32_t) regp->control) << 24) | (((uint32_t) val) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) regp->primask); - break; - case 0x1E: /* basepri */ - val = (((uint32_t) regp->control) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) val) << 8) | ((uint32_t) regp->primask); - break; - case 0x1F: /* primask */ - val = (((uint32_t) regp->control) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) val); - break; + case 0x1C: /* control */ + val = (((uint32_t) val) << 24) | + (((uint32_t) regp->faultmask) << 16) | + (((uint32_t) regp->basepri) << 8) | + ((uint32_t) regp->primask); + break; + case 0x1D: /* faultmask */ + val = (((uint32_t) regp->control) << 24) | + (((uint32_t) val) << 16) | + (((uint32_t) regp->basepri) << 8) | + ((uint32_t) regp->primask); + break; + case 0x1E: /* basepri */ + val = (((uint32_t) regp->control) << 24) | + (((uint32_t) regp->faultmask) << 16) | + (((uint32_t) val) << 8) | + ((uint32_t) regp->primask); + break; + case 0x1F: /* primask */ + val = (((uint32_t) regp->control) << 24) | + (((uint32_t) regp->faultmask) << 16) | + (((uint32_t) regp->basepri) << 8) | + ((uint32_t) val); + break; } r_idx = 0x14; @@ -882,8 +867,7 @@ int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, str write_uint32(sl->q_buf, val); ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRDR, 4); - if (ret == -1) - return ret; + if (ret == -1) return ret; sl->q_buf[0] = (unsigned char) r_idx; sl->q_buf[1] = 0; @@ -902,13 +886,17 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - if (sl->version.jtag_api == STLINK_JTAG_API_V1) + + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { cmd[i++] = STLINK_DEBUG_APIV1_WRITEREG; - else + } else { cmd[i++] = STLINK_DEBUG_APIV2_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 STLINK_DEBUG_WRITEREG\n"); return (int) size; @@ -949,8 +937,7 @@ static stlink_backend_t _stlink_usb_backend = { _stlink_usb_set_swdclk }; -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq) -{ +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; int ret = -1; @@ -958,10 +945,9 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST sl = calloc(1, sizeof (stlink_t)); slu = calloc(1, sizeof (struct stlink_libusb)); - if (sl == NULL) - goto on_malloc_error; - if (slu == NULL) - goto on_malloc_error; + + if (sl == NULL) goto on_malloc_error; + if (slu == NULL) goto on_malloc_error; ugly_init(verbose); sl->backend = &_stlink_usb_backend; @@ -980,81 +966,66 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST #endif libusb_device **list; - /** @todo We should use ssize_t and use it as a counter if > 0. As per libusb API: ssize_t libusb_get_device_list (libusb_context *ctx, libusb_device ***list) */ + /* @TODO: We should use ssize_t and use it as a counter if > 0. + * As per libusb API: ssize_t libusb_get_device_list (libusb_context *ctx, libusb_device ***list) + */ int cnt = (int) libusb_get_device_list(slu->libusb_ctx, &list); struct libusb_device_descriptor desc; - int devBus =0; - int devAddr=0; - - /* @TODO: Reading a environment variable in a usb open function is not very nice, this - should be refactored and moved into the CLI tools, and instead of giving USB_BUS:USB_ADDR a real stlink - serial string should be passed to this function. Probably people are using this but this is very odd because - as programmer can change to multiple busses and it is better to detect them based on serial. */ + int devBus = 0; + int devAddr = 0; + + /* @TODO: Reading a environment variable in a usb open function is not very nice, this should be refactored + * and moved into the CLI tools, and instead of giving USB_BUS:USB_ADDR a real stlink serial string should + * be passed to this function. Probably people are using this but this is very odd because as programmer + * can change to multiple busses and it is better to detect them based on serial. + */ char *device = getenv("STLINK_DEVICE"); if (device) { char *c = strchr(device,':'); - if (c==NULL) { + if (c == NULL) { WLOG("STLINK_DEVICE must be : format\n"); goto on_error; } - devBus=atoi(device); - *c++=0; - devAddr=atoi(c); + devBus = atoi(device); + *c++ = 0; + devAddr = atoi(c); ILOG("bus %03d dev %03d\n",devBus, devAddr); } while (cnt--) { - struct libusb_device_handle *handle; + struct libusb_device_handle *handle; - libusb_get_device_descriptor( list[cnt], &desc ); - if (desc.idVendor != STLINK_USB_VID_ST) - continue; + libusb_get_device_descriptor(list[cnt], &desc); + if (desc.idVendor != STLINK_USB_VID_ST) continue; if (devBus && devAddr) { - if ((libusb_get_bus_number(list[cnt]) != devBus) - || (libusb_get_device_address(list[cnt]) != devAddr)) { + if ((libusb_get_bus_number(list[cnt]) != devBus) || (libusb_get_device_address(list[cnt]) != devAddr)) { continue; } } - ret = libusb_open(list[cnt], &handle); + ret = libusb_open(list[cnt], &handle); + if (ret) continue; // could not open device - /* could not open device, continue */ - if (ret) - continue; + sl->serial_size = libusb_get_string_descriptor_ascii( + handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial)); + libusb_close(handle); - sl->serial_size = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, - (unsigned char *)sl->serial, sizeof(sl->serial)); - - if ((serial == NULL) || (*serial == 0)) - break; - - if (sl->serial_size < 0) - continue; + if (sl->serial_size < 0) continue; // could not read serial - if (memcmp(serial, &sl->serial, sl->serial_size) == 0) + // if no serial provided, or if serial match device, fixup version and protocol + if (((serial == NULL) || (*serial == 0)) || (memcmp(serial, &sl->serial, sl->serial_size) == 0)) { + if (STLINK_V1_USB_PID(desc.idProduct)) { + slu->protocoll = 1; + sl->version.stlink_v = 1; + } else if (STLINK_V2_USB_PID(desc.idProduct) || STLINK_V2_1_USB_PID(desc.idProduct)) { + sl->version.stlink_v = 2; + } else if (STLINK_V3_USB_PID(desc.idProduct)) { + sl->version.stlink_v = 3; + } break; - - libusb_close(handle); - - /* could not read serial, continue */ - if (sl->serial_size < 0) - continue; - - /* if no serial provided, or if serial match device, fixup version and protocol */ - if (((serial == NULL) || (*serial == 0)) || (memcmp(serial, &sl->serial, sl->serial_size) == 0)) { - if (STLINK_V1_USB_PID(desc.idProduct)) { - slu->protocoll = 1; - sl->version.stlink_v = 1; - } else if (STLINK_V2_USB_PID(desc.idProduct) || STLINK_V2_1_USB_PID(desc.idProduct)) { - sl->version.stlink_v = 2; - } else if (STLINK_V3_USB_PID(desc.idProduct)) { - sl->version.stlink_v = 3; - } - - break; - } + } } if (cnt < 0) { @@ -1063,8 +1034,8 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST } else { ret = libusb_open(list[cnt], &slu->usb_handle); if (ret != 0) { - WLOG("Error %d (%s) opening ST-Link v%d device %03d:%03d\n", - ret, strerror (errno), sl->version.stlink_v, libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); + WLOG("Error %d (%s) opening ST-Link v%d device %03d:%03d\n", ret, strerror (errno), + sl->version.stlink_v, libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); libusb_free_device_list(list, 1); goto on_error; } @@ -1130,10 +1101,9 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST stlink_exit_dfu_mode(sl); } - sl->freq = freq; - // set the speed before entering the mode - // as the chip discovery phase should be done at this speed too + // set the speed before entering the mode as the chip discovery phase + // should be done at this speed too // Set the stlink clock speed (default is 1800kHz) DLOG("JTAG/SWD freq set to %d\n", freq); switch (freq) { @@ -1174,38 +1144,29 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST stlink_set_swdclk(sl, STLINK_SWDCLK_4MHZ_DIVISOR); break; } - - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { - stlink_enter_swd_mode(sl); - } + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); if (reset) { - if ( sl->version.stlink_v > 1)stlink_jtag_reset(sl, 2); + if ( sl->version.stlink_v > 1) stlink_jtag_reset(sl, 2); stlink_reset(sl); usleep(10000); } stlink_load_device_params(sl); - return sl; -on_libusb_error: - stlink_close(sl); - return NULL; + on_libusb_error: + stlink_close(sl); + return NULL; + on_error: + if (slu->libusb_ctx) libusb_exit(slu->libusb_ctx); -on_error: - if (slu->libusb_ctx) - libusb_exit(slu->libusb_ctx); - -on_malloc_error: - if (sl != NULL) - free(sl); - if (slu != NULL) - free(slu); - - return NULL; + on_malloc_error: + if (sl != NULL) free(sl); + if (slu != NULL) free(slu); + return NULL; } static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { @@ -1219,18 +1180,19 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; int ret = libusb_get_device_descriptor(dev, &desc); + if (ret < 0) { WLOG("failed to get libusb device descriptor (libusb error: %d)\n", ret); break; } - if (desc.idVendor != STLINK_USB_VID_ST) - continue; + if (desc.idVendor != STLINK_USB_VID_ST) continue; + + if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { + WLOG("skipping ST device : %#04x:%#04x)\n", desc.idVendor, desc.idProduct); + continue; + } - if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { - WLOG("skipping ST device : %#04x:%#04x)\n", desc.idVendor, desc.idProduct); - continue; - } slcnt++; } @@ -1246,45 +1208,44 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; int ret = libusb_get_device_descriptor(dev, &desc); + if (ret < 0) { WLOG("failed to get libusb device descriptor (libusb error: %d)\n", ret); break; } - if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { - continue; - } + if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) continue; - struct libusb_device_handle* handle; + struct libusb_device_handle* handle; char serial[STLINK_SERIAL_MAX_SIZE] = {0,}; - ret = libusb_open(dev, &handle); - if (ret < 0) { - if (ret == LIBUSB_ERROR_ACCESS) { - ELOG("Could not open USB device %#06x:%#06x, access error.\n", desc.idVendor, desc.idProduct, ret); - } else { - ELOG("Failed to open USB device %#06x:%#06x, libusb error: %d)\n", desc.idVendor, desc.idProduct, ret); - } - break; - } - ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial)); + ret = libusb_open(dev, &handle); + + if (ret < 0) { + if (ret == LIBUSB_ERROR_ACCESS) { + ELOG("Could not open USB device %#06x:%#06x, access error.\n", desc.idVendor, desc.idProduct, ret); + } else { + ELOG("Failed to open USB device %#06x:%#06x, libusb error: %d)\n", desc.idVendor, desc.idProduct, ret); + } + break; + } + ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial)); - libusb_close(handle); + libusb_close(handle); - if (ret < 0) { - continue; - } + if (ret < 0) continue; stlink_t *sl = stlink_open_usb(0, 1, serial, 0); if (!sl) { ELOG("Failed to open USB device %#06x:%#06x\n", desc.idVendor, desc.idProduct); continue; - } + } _sldevs[slcur++] = sl; } *sldevs = _sldevs; + return slcur; } @@ -1297,12 +1258,10 @@ size_t stlink_probe_usb(stlink_t **stdevs[]) { ssize_t cnt; r = libusb_init(NULL); - if (r < 0) - return 0; + if (r < 0) return 0; cnt = libusb_get_device_list(NULL, &devs); - if (cnt < 0) - return 0; + if (cnt < 0) return 0; slcnt = stlink_probe_usb_devs(devs, &sldevs); libusb_free_device_list(devs, 1); @@ -1310,15 +1269,13 @@ size_t stlink_probe_usb(stlink_t **stdevs[]) { libusb_exit(NULL); *stdevs = sldevs; + return slcnt; } void stlink_probe_usb_free(stlink_t ***stdevs, size_t size) { - if (stdevs == NULL || *stdevs == NULL || size == 0) - return; - - for (size_t n = 0; n < size; n++) - stlink_close((*stdevs)[n]); + if (stdevs == NULL || *stdevs == NULL || size == 0) return; + for (size_t n = 0; n < size; n++) stlink_close((*stdevs)[n]); free(*stdevs); *stdevs = NULL; } From e3aa887f7ffdfcfb3a0529ee3b94a7d3fe39b5d8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 18 May 2020 00:49:08 +0200 Subject: [PATCH 0928/1435] Update for library linking - Simplified code - Added version info for static library --- CMakeLists.txt | 41 ++++++++++++++++++++++++----------------- Makefile | 3 ++- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b5301fb0a..57a9161e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,11 +19,11 @@ set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics ST-LINK T include(GNUInstallDirs) # Define GNU standard installation directories set(STLINK_UDEV_RULES_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/udev/rules.d" CACHE PATH "udev rules directory") -set(STLINK_MODPROBED_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/modprobe.d" CACHE PATH "modprobe.d directory") -set(STLINK_STATIC_LIB ON CACHE BOOL "Install static lib") - option(STLINK_INSTALL_UDEV_RULES "Install udev rules files" ON) + +set(STLINK_MODPROBED_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/modprobe.d" CACHE PATH "modprobe.d directory") option(STLINK_INSTALL_MODPROBE_CONF "Install modprobe conf files" ON) + option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) ## Determine project version @@ -186,16 +186,14 @@ set_target_properties( VERSION ${STLINK_SHARED_VERSION} ) -# Link shared library with Apple macOS libraries -if (APPLE) +# Link shared library +if (APPLE) # ... with Apple macOS libraries find_library(ObjC objc) find_library(CoreFoundation CoreFoundation) find_library(IOKit IOKit) - target_link_libraries(${STLINK_LIB_SHARED} ${CoreFoundation} ${IOKit} ${ObjC} ${SSP_LIB}) -endif () - -if (WIN32 OR MINGW OR MSYS) - target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} wsock32 ws2_32 ${SSP_LIB}) + target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB} ${ObjC} ${CoreFoundation} ${IOKit}) +elseif (WIN32) # ... with Windows libraries + target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB} wsock32 ws2_32) else () target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB}) endif () @@ -207,6 +205,9 @@ install(TARGETS ${STLINK_LIB_SHARED} DESTINATION ${STLINK_LIBRARY_PATH}) # Static library ### +# Install static library per default +set(STLINK_STATIC_LIB ON CACHE BOOL "Install static lib") + set(STLINK_LIB_STATIC ${PROJECT_NAME}-static) add_library( @@ -215,21 +216,27 @@ add_library( ${STLINK_SOURCE} ) +set(STLINK_STATIC_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) + +message(STATUS "STLINK_LIB_STATIC: ${STLINK_LIB_STATIC}") +message(STATUS "PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}") +message(STATUS "VERSION: ${STLINK_STATIC_VERSION}") + set_target_properties( ${STLINK_LIB_STATIC} PROPERTIES + SOVERSION ${PROJECT_VERSION_MAJOR} + VERSION ${STLINK_STATIC_VERSION} OUTPUT_NAME ${PROJECT_NAME} ) -# Link static library with Apple macOS libraries -if (APPLE) +# Link static library +if (APPLE) # ... with Apple macOS libraries find_library(ObjC objc) find_library(CoreFoundation CoreFoundation) find_library(IOKit IOKit) - target_link_libraries(${STLINK_LIB_STATIC} ${CoreFoundation} ${IOKit} ${ObjC} ${SSP_LIB}) -endif () - -if (WIN32 OR MINGW OR MSYS) - target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} wsock32 ws2_32 ${SSP_LIB}) + target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB} ${ObjC} ${CoreFoundation} ${IOKit}) +elseif (WIN32) # ... with Windows libraries + target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB} wsock32 ws2_32) else () target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB}) endif () diff --git a/Makefile b/Makefile index 7f373ebcd..3f46d2943 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ ## -# This Makefile is used to drive building of Debug and Release targets of CMake +# This Makefile is used to drive building of CMake build targets ## + MAKEFLAGS += -s # additional flags for cmake, e.g. install path -DCMAKE_INSTALL_PREFIX=$(HOME)/.local From d73f864a375287ed93efaedd87a106a378c91d12 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Mon, 18 May 2020 11:53:58 +0800 Subject: [PATCH 0929/1435] Fix some uninitialized variables --- src/flash_loader.c | 2 +- src/usb.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flash_loader.c b/src/flash_loader.c index 6862d493c..20a2bdc73 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -191,7 +191,7 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { - size_t size; + size_t size = 0; /* allocate the loader in sram */ if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { diff --git a/src/usb.c b/src/usb.c index fcb2e1b30..b986aed57 100644 --- a/src/usb.c +++ b/src/usb.c @@ -347,7 +347,7 @@ int _stlink_usb_core_id(stlink_t * sl) { int _stlink_usb_status_v2(stlink_t *sl) { int result; - uint32_t status; + uint32_t status = 0; result = _stlink_usb_read_debug32(sl, DCB_DHCSR, &status); DLOG("core status: %08X\n", status); From f8ef21cd130c2ad6460c375747be5987112c4703 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Mon, 18 May 2020 11:58:31 +0800 Subject: [PATCH 0930/1435] Fix issue 958, move F0 flashloader nops to assembly --- flashloaders/stm32f0.s | 14 ++++++++++++++ src/flash_loader.c | 19 ++----------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index 6c4b8588f..cbb932b49 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -3,6 +3,20 @@ .global copy copy: + /* + * These two NOPs here are a safety precaution, added by Pekka Nikander + * while debugging the STM32F05x support. They may not be needed, but + * there were strange problems with simpler programs, like a program + * that had just a breakpoint or a program that first moved zero to register r2 + * and then had a breakpoint. So, it appears safest to have these two nops. + * + * Feel free to remove them, if you dare, but then please do test the result + * rigorously. Also, if you remove these, it may be a good idea first to + * #if 0 them out, with a comment when these were taken out, and to remove + * these only a few months later... But YMMV. + */ + nop + nop ldr r7, =flash_base ldr r4, [r7] ldr r7, =flash_off_cr diff --git a/src/flash_loader.c b/src/flash_loader.c index 20a2bdc73..a2c5879ce 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -41,22 +41,7 @@ /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ static const uint8_t loader_code_stm32f0[] = { -#if 1 - /* - * These two NOPs here are a safety precaution, added by Pekka Nikander - * while debugging the STM32F05x support. They may not be needed, but - * there were strange problems with simpler programs, like a program - * that had just a breakpoint or a program that first moved zero to register r2 - * and then had a breakpoint. So, it appears safest to have these two nops. - * - * Feel free to remove them, if you dare, but then please do test the result - * rigorously. Also, if you remove these, it may be a good idea first to - * #if 0 them out, with a comment when these were taken out, and to remove - * these only a few months later... But YMMV. - */ - 0x00, 0x30, // nop /* add r0,#0 */ - 0x00, 0x30, // nop /* add r0,#0 */ -#endif + 0xc0, 0x46, 0xc0, 0x46, 0x13, 0x4f, 0x3c, 0x68, 0x13, 0x4f, 0x3e, 0x68, 0x36, 0x19, 0x13, 0x4f, @@ -77,9 +62,9 @@ 0x00, 0x20, 0x02, 0x40, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x20, 0x48, 0x00, 0x00, 0x20, 0x4c, 0x00, 0x00, 0x20, + 0x50, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 From 97d3173f480db33c770ef2c66a002d708b139fa0 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 18 May 2020 15:13:36 +0200 Subject: [PATCH 0931/1435] Updated package & install configuration - Added package changelog files for deb & rpm - Added license file for deb pkg - Added rules file for deb pkg - Changed install subdirectory --- .travis.sh | 32 ++-- CMakeLists.txt | 6 +- cmake/packaging/cpack_config.cmake | 26 ++-- cmake/packaging/deb/changelog | 237 ++++------------------------- cmake/packaging/deb/control | 9 ++ cmake/packaging/deb/copyright | 16 +- cmake/packaging/deb/rules | 2 +- cmake/packaging/rpm/changelog | 2 + mingw64-build.bat | 2 +- 9 files changed, 85 insertions(+), 247 deletions(-) create mode 100644 cmake/packaging/deb/control create mode 100644 cmake/packaging/rpm/changelog diff --git a/.travis.sh b/.travis.sh index e61098f89..3bab4c5d0 100755 --- a/.travis.sh +++ b/.travis.sh @@ -12,17 +12,17 @@ if [ "$TRAVIS_JOB_NAME" == "linux-mingw" ]; then echo "--> Building Release for Windows (x86-64) ..." mkdir -p build-mingw && cd build-mingw echo "-DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR" + -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR" cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR + -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && rm -rf build-mingw && cd - echo "--> Building Release for Windows (i686) ..." mkdir -p build-mingw && cd build-mingw echo "-DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR" + -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR" cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR + -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && rm -rf build-mingw && cd - elif [ "$TRAVIS_OS_NAME" == "linux" ]; then @@ -31,14 +31,14 @@ elif [ "$TRAVIS_OS_NAME" == "linux" ]; then echo "--> Building Debug..." mkdir -p build/Debug && cd build/Debug - echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install" - cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR + echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" + cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && make package && cd - echo "--> Building Release..." mkdir -p build/Release && cd build/Release - echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install" - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR + echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && make package && cd - elif [ "$TRAVIS_OS_NAME" == "osx" ]; then @@ -46,26 +46,26 @@ elif [ "$TRAVIS_OS_NAME" == "osx" ]; then echo "--> Building Debug..." mkdir -p build/Debug && cd build/Debug - echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install" - cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR + echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" + cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && make package && cd - echo "--> Building Release..." mkdir -p build/Release && cd build/Release - echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install" - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install $DIR + echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && make package && cd - else # local test-build echo "--> Building Debug..." mkdir -p build/Debug && cd build/Debug - echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install" - cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ + echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" + cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install ../../ make && make package && cd - echo "--> Building Release..." mkdir -p build/Release && cd build/Release - echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install" - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/_install ../../ + echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install ../../ make && make package && cd - fi diff --git a/CMakeLists.txt b/CMakeLists.txt index 57a9161e7..1526f3122 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,7 @@ find_package(libusb REQUIRED) ## Package configuration (pkg-config) on unix-based systems if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) - add_subdirectory(cmake/pkgconfig) + #add_subdirectory(cmake/pkgconfig) find_package(PkgConfig) pkg_check_modules(GTK3 gtk+-3.0) endif () @@ -187,7 +187,7 @@ set_target_properties( ) # Link shared library -if (APPLE) # ... with Apple macOS libraries +if (APPLE) # ... with Apple macOS libraries find_library(ObjC objc) find_library(CoreFoundation CoreFoundation) find_library(IOKit IOKit) @@ -230,7 +230,7 @@ set_target_properties( ) # Link static library -if (APPLE) # ... with Apple macOS libraries +if (APPLE) # ... with Apple macOS libraries find_library(ObjC objc) find_library(CoreFoundation CoreFoundation) find_library(IOKit IOKit) diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake index da03bb596..f36a50b40 100644 --- a/cmake/packaging/cpack_config.cmake +++ b/cmake/packaging/cpack_config.cmake @@ -62,20 +62,23 @@ elseif (EXISTS "/etc/debian_version" AND NOT EXISTS WIN32) # Package-build is av # CPACK_DEBIAN_PACKAGE_HOMEPAGE --> Default: CMAKE_PROJECT_HOMEPAGE_URL set(CPACK_DEBIAN_PACKAGE_SUGGESTS "libgtk-3-dev, pandoc") - ## Add CHANGELOG in Debian-specific format - ### TODO - - ## Add license file - ### TODO - - # Include a postinst-script - set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/cmake/packaging/debian/postinst") + ## Additional package files in Debian-specific format: + # * changelog (package changelog) + # * copyright (license file) + # * rules + # * postinst-script + set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA + "${CMAKE_SOURCE_DIR}/cmake/packaging/deb/changelog" + "${CMAKE_SOURCE_DIR}/cmake/packaging/deb/copyright" + "${CMAKE_SOURCE_DIR}/cmake/packaging/deb/rules" + "${CMAKE_SOURCE_DIR}/cmake/packaging/deb/postinst" + ) ### # Slackware & Redhat (RPM) ### - set(CPACK_SET_DESTDIR "OFF") + set(CPACK_SET_DESTDIR "OFF") # Required for relocatable package # CPACK_RPM_PACKAGE_SUMMARY --> Default: CPACK_PACKAGE_DESCRIPTION_SUMMARY # CPACK_RPM_PACKAGE_NAME --> Default: CPACK_PACKAGE_NAME @@ -97,8 +100,9 @@ elseif (EXISTS "/etc/debian_version" AND NOT EXISTS WIN32) # Package-build is av # CPACK_RPM_PACKAGE_URL --> Default: CMAKE_PROJECT_HOMEPAGE_URL set(CPACK_RPM_PACKAGE_DESCRIPTION CPACK_DEBIAN_PACKAGE_DESCRIPTION) - ## Add CHANGELOG in rpm-specific format - ### TODO + ## Add package changelog in rpm-specific format + set(CPACK_RPM_CHANGELOG_FILE "${CMAKE_SOURCE_DIR}/cmake/packaging/rpm/changelog") + else () # No package configuration on other platforms ... endif () diff --git a/cmake/packaging/deb/changelog b/cmake/packaging/deb/changelog index b4e942d7c..f4b644176 100644 --- a/cmake/packaging/deb/changelog +++ b/cmake/packaging/deb/changelog @@ -1,226 +1,49 @@ -stlink (1.6.0) unstable; urgency=medium - -Release date: 2020-02-20 - -Major changes and added features: - -* Initial support for STM32L41X -* Working support for CKS32F103C8T6 and related CKS devices with Core-ID 0x2ba01477 -* Added preliminary support for some STM32G0 chips -* Added support for mass erasing second bank on STM32F10x_XL -* Added call to clear PG bit after writing to flash -* Added support to write option bytes for the STM32G0 -* Added support for STM32WB55 chips -* Added STLink V3SET VID:PIDs to the udev rules -* Support for "STM32+Audio" v2-1 firmware -* Build for Windows under Debian/Ubuntu -* Allow for 64 bytes serials -* Added full support for STLINK CHIP ID L4RX -* Added support for the STLink-v2.1 when flashed with no mass storage (PID 0x3752) -* Added support for writing option bytes on STM32L0xx -* Added support to read and write option bytes for STM32F2 series -* Added support to read and write option bytes for STM32F446 - -Updates and fixes: - -* Fixed "unkown chip id", piped output and st-util -v -* Fixed an issue with versioning stuck at 1.4.0 for versions cloned with git -* Updated STM32F3xx chip ID that covers a few different devices -* Made udev rules and modprobe conf installation optional -* Fixed case when __FILE__ don't contain "/" nor "\\" -* Fixed double dash issue in doc/man -* Compiling documentation: package is called libusb-1.0-0-dev on Debian -* Only do bank calculation on STM32L4 devices with dual banked flash / Added chip-ID 0x464 for STM32L41xxx/L42xxx devices -* Added O_BINARY option to open file -* Fixed versioning when compiling from the checked out git-repo -* win32: move usleep definition to unistd.h -* Fixed relative path to the UI files needed by stlink-gui-local (GUI) -* Added howto for sending NRST signal through GDB -* Fixed package name "devscripts" in doc/compiling.md -* Fixed few potential memory/resource leaks -* Updated Linux source repositories in README.md: Debian and Ubuntu -* Do not issue JTAG reset on stlink-v1 -* Fixed flash size of STM32 Discovery vl -* Updated documentation on software structure - -General project updates: - -* Updated README.md, CHANGELOG.md and issue templates -* Fixed travis build config file -* Added CODE_OF_CONDUCT -* Archived page from github project wiki to doc/wiki_old.md - --- Luca Boccassi Tue, 25 Feb 2020 22:08:33 +0000 - - -stlink (1.5.1) unstable; urgency=medium - -Release date: 2018-09-13 - -Major changes and added features: - -* Added reset through AIRCR -* Added creation of icons for .desktop file -* Added desktop file for linux -* Added button to export STM32 flash memory to a file -* Updated libusb to 1.0.22 -* Added icons for STLink GUI -* Added support for STM32L4R9 target -* Added memory map for STM32F411RE target -* Implemented intel hex support for GTK GUI - -Updates and fixes: - -* Fixed missing flash_loader for STM32L0x -* Fix for stlink library calls exit() or _exit() -* Added semihosting parameter documentation in doc/man -* Fixed reference to non-exisiting st-term tool in doc/man -* Fixed serial number size mismatch with stlink_open_usb() -* Debian packaging, CMake and README.md fixes -* Disabled static library installation by default -* Fix for libusb deprecation -* Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX -* Regression: stlink installation under Linux (Debian 9) is broken since #695 -* Fixed flash memory map for STM32F72xxx target -* Proper flash page size calculation for STM32F412xx target -* Return correct value on EOF for Semihosting SYS_READ -* FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION - --- Luca Boccassi Fri, 28 Sep 2018 10:26:39 +0100 - - -stlink (1.5.0) unstable; urgency=medium - -Release date: 2018-02-16 - -Major changes and added features: - -* Added support of STM32L496xx/4A6xx devices -* Added unknown chip dummy to obtain the serial of the ST-link by a call to st-info --probe -* Added support for STM32F72xx (chip-ID: 0x452) devices - -Updates and fixes: - -* Fixed verification of flash error for STM32L496x device -* Updated Linux source repositories in README.md: Gentoo, Fedora and RedHat/CentOS -* Updated changelog in debian package -* Added LIB_INSTALL_DIR to correct libs install on 64-bit systems -* Fixed write for microcontroller with RAM size less or equal to 32K -* Fixed memory map for STM32L496xx boards -* Fixed __FILE__ base name extraction -* Added debian/triggers to run ldconfig -* Fixed build on Fedora with GCC 8 - --- Luca Boccassi Fri, 16 Mar 2018 16:56:17 +0000 +stlink (1.6.0+ds-1) unstable; urgency=medium + * Merge tag 'v1.6.0' into debian + * Bump Standards-Version to 4.5.0, no changes. + * Update libstlink1 symbols file for 1.6.0. -stlink (1.4.0) unstable; urgency=low + -- Luca Boccassi Tue, 25 Feb 2020 22:08:33 +0000 -Release date: 2017-07-01 +stlink (1.5.1+ds-2) unstable; urgency=medium -Major changes and added features: + * Mark library packages as Multi-Arch: same. + * Apply cross.patch to fix cross-compiling the GUI. Thanks Helmut for the patch! (Closes: #941320) + * Vcs-Git: add -b debian + * Set Rules-Requires-Root: no + * Bump Standards-Version to 4.4.0 -* Allow building of debian package with CPack -* Added support for STM32L011 target -* Added support for flashing second bank on STM32F10x_XL -* Initial support to compile with Microsoft Visual Studio 2017 -* Added support for STM32L452 target + -- Luca Boccassi Sun, 29 Sep 2019 12:50:58 +0100 -Updates and fixes: +stlink (1.5.1+ds-1) unstable; urgency=medium -* Fixed gdb-server: STM32L0xx has no FP_CTRL register for breakpoints -* Added --flash=n[k][m] command line option to override device model -* Updated libusb to 1.0.21 for Windows -* Fixed low-voltage flashing on STM32F7 devices -* Fixed building with mingw64 -* Fixed possible memory leak -* Fixed installation path for shared objects -* Fixed a few -Wformat warnings -* Removed unused defines in mimgw.h -* Skip GTK detection when cross-compiling -* Fixed compilation with GCC 7 -* Fixed flashing to 'f0 device' targets -* Fixed wrong counting when flashing + * Merge tag 'v1.5.1' into debian. See upstream changelog for info: + https://github.com/stlink-org/stlink/releases/tag/v1.5.1 + * Mark packages as linux-any, other systems not supported. --- Andrew 'Necromant' Andrianov Sat, 01 Jul 2017 00:00:00 +0000 + -- Luca Boccassi Fri, 28 Sep 2018 10:26:39 +0100 +stlink (1.5.0+ds-1) unstable; urgency=medium -stlink (1.3.1) unstable; urgency=low + * Upload to unstable. (Closes: #869421) -Release date: 2017-02-25 + -- Luca Boccassi Fri, 16 Mar 2018 16:56:17 +0000 -Major changes and added features: +stlink (1.4.0) unstable; urgency=low -* Added support for Semihosting `SYS_READC` -* Added support for STM32F413 -* Added preliminary support for STM32L011 to see it after probe (chip-ID 0x457) + -- Andrew 'Necromant' Andrianov Sat, 01 Jul 2017 00:00:00 +0000 -Updates and fixes: +stlink (1.3.1) unstable; urgency=low -* cmake/CPackConfig.cmake: Fixup OSX zip filename -* Updated source repositories in README.md: Windows, macOS, Alpine Linux -* Compilation fixes -* Stripped full paths to source files in log -* Fixed incorrect release folder name in docs -* Fixed compilation when path includes spaces + -- Andrew 'Necromant' Andrianov Sat, 25 Feb 2017 00:00:00 +0000 --- Andrew 'Necromant' Andrianov Sat, 25 Feb 2017 00:00:00 +0000 +stlink (1.3.0) unstable; urgency=low + -- Andrew 'Necromant' Andrianov Sat, 28 Jan 2017 00:00:00 +0000 -stlink (1.3.0) unstable; urgency=low +stlink (1.2.1) unstable; urgency=low + + * Initial Debian-Packaged Release. -Release date: 2017-01-28 - -Major changes and added features: - -* Deprecation of autotools (autoconf, automake) and fixed build with MinGW -* Added intel hex file reading for `st-flash` -* Added support for ARM semihosting to `st-util` -* Added manpages (generated with pandoc from Markdown) -* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature -* Support serial numbers argument for `st-util` and `st-flash` to probe and control multiple connected programmers -* Merge st-probe tool into st-info -* Added support for native debian packaging -* Rewritten commandline parsing for `st-flash` -* Added `--reset` command to `st-flash` -* st-util should detect when USB commands fail - -Chip support added for: - -* STM32F401XE: Added memory map for device -* STM32F410RBTx -* STM32F412 -* STM32F7xx -* STM32F7x7x -* STM32L0xx Cat2 devices (chip-ID: 0x425) -* STM32L0xx Cat5 devices (chip-ID: 0x447) -* STM32L4xx -* STM32L432 - -Updates and fixes: - -* Fixed "unaligned addr or size" when trying to write a program in RAM -* Fixed flashing on STM32_F3_SMALL -* Fixed STM32L-problem with flash loader -* Don't read the target voltage on startup, because it crashes STM32F100 -* Added a useful error message instead of "[!] send_recv" -* Do a JTAG reset prior to reading CPU information when processor is in deep sleep -* Fixed STM32F030 erase error -* Fixed memory map for STM32F7xx -* Redesign of `st-flash` commandline options parsing -* Set SWDCLK and fixed jtag_reset bug -* doc/compiling.md: Add note about installation and ldconfig -* Fixed Release target to generate the man-pages with pandoc -* Fixed Cygwin build -* Reset flash mass erase (MER) bit after mass erase for safety -* Wrong extract command in FindLibUSB.cmake -* Fixed compilation error on Ubuntu 16.10 - --- Andrew 'Necromant' Andrianov Sat, 28 Jan 2017 00:00:00 +0000 - - -libstlink (1.2.1) unstable; urgency=low - -* Initial Debian-packaged release. - --- Andrew 'Necromant' Andrianov Sat, 09 Jul 2016 23:16:07 +0300 + -- Andrew 'Necromant' Andrianov Sat, 09 Jul 2016 23:16:07 +0300 diff --git a/cmake/packaging/deb/control b/cmake/packaging/deb/control new file mode 100644 index 000000000..d96746e65 --- /dev/null +++ b/cmake/packaging/deb/control @@ -0,0 +1,9 @@ +Source: stlink +Maintainer: Luca Bocassi +Build-Depends: cmake, dh-cmake, debhelper (>= 9), libusb-1.0-0-dev, libgtk-3-dev +Standards-Version: 4.1.3 +Section: electronics +Priority: optional +Homepage: https://github.com/stlink-org/stlink +Vcs-Git: https://github.com/stlink-org/stlink.git +Vcs-Browser: https://github.com/stlink-org/stlink diff --git a/cmake/packaging/deb/copyright b/cmake/packaging/deb/copyright index 37a101b98..a14d4eb6e 100644 --- a/cmake/packaging/deb/copyright +++ b/cmake/packaging/deb/copyright @@ -4,6 +4,14 @@ Upstream-Contact: Luca Bocassi Source: https://github.com/stlink-org/stlink Disclaimer: Comment: +Files: * +Copyright: 2011-2020 stlink-org + Martin Capitanio [capnm] + Fabien Le Mentec [texane] + Jerry Jacobs [xor-gate] + [Nightwalker-87] + and many others... + A list of contributors can be found in "contributors.txt". License: BSD-3-clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -27,11 +35,3 @@ License: BSD-3-clause CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -Files: * -Copyright: 2011-2020 stlink-org - Martin Capitanio [capnm] - Fabien Le Mentec [texane] - Jerry Jacobs [xor-gate] - [Nightwalker-87] - . - and many others... A list of contributors can be found in "contributors.txt". diff --git a/cmake/packaging/deb/rules b/cmake/packaging/deb/rules index e183fffb7..2f80faeac 100755 --- a/cmake/packaging/deb/rules +++ b/cmake/packaging/deb/rules @@ -11,7 +11,7 @@ include /usr/share/dpkg/default.mk export DEB_BUILD_MAINT_OPTIONS = hardening=+all %: - dh $@ --buildsystem cmake + dh $@ --buildsystem cmake --with cpack override_dh_auto_configure: dh_auto_configure -- \ diff --git a/cmake/packaging/rpm/changelog b/cmake/packaging/rpm/changelog new file mode 100644 index 000000000..de2400d65 --- /dev/null +++ b/cmake/packaging/rpm/changelog @@ -0,0 +1,2 @@ +* Mon Jun 01 2020 Vasiliy Glazov - 1.6.1 +- Initial RPM-packaged release diff --git a/mingw64-build.bat b/mingw64-build.bat index 9d5cf4d06..eeaacddab 100644 --- a/mingw64-build.bat +++ b/mingw64-build.bat @@ -5,5 +5,5 @@ cd build-mingw set PATH=C:\Program Files (x86)\CMake\bin;C:\Program Files\CMake\bin;C:\Program Files\mingw-w64\x86_64-8.1.0-win32-sjlj-rt_v6-rev0\mingw64\bin;%PATH% cmake -G "MinGW Makefiles" .. mingw32-make -mingw32-make install DESTDIR=_install +mingw32-make install DESTDIR=install mingw32-make package From 1b3200d5bc1d6c5b90a54f4c92aa8fbe3f8bb660 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 18 May 2020 18:34:16 +0200 Subject: [PATCH 0932/1435] Updated build settings - Removed unneeded commands in travis.sh - Removed -Wno-dev flag in Release target - cmake: Grouped udev and modprobe.d config - rpm package now relocatable (CPackRPM) --- .travis.sh | 6 +++--- CMakeLists.txt | 36 +++++++++++++++++++++--------------- Makefile | 2 +- doc/man/CMakeLists.txt | 2 +- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/.travis.sh b/.travis.sh index 3bab4c5d0..2c98a6ef6 100755 --- a/.travis.sh +++ b/.travis.sh @@ -33,7 +33,7 @@ elif [ "$TRAVIS_OS_NAME" == "linux" ]; then mkdir -p build/Debug && cd build/Debug echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && make package && cd - + make && cd - echo "--> Building Release..." mkdir -p build/Release && cd build/Release @@ -48,7 +48,7 @@ elif [ "$TRAVIS_OS_NAME" == "osx" ]; then mkdir -p build/Debug && cd build/Debug echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && make package && cd - + make && cd - echo "--> Building Release..." mkdir -p build/Release && cd build/Release @@ -61,7 +61,7 @@ else # local test-build mkdir -p build/Debug && cd build/Debug echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install ../../ - make && make package && cd - + make && cd - echo "--> Building Release..." mkdir -p build/Release && cd build/Release diff --git a/CMakeLists.txt b/CMakeLists.txt index 1526f3122..8b3210dbf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,14 +18,6 @@ project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics ST-LINK Tools") include(GNUInstallDirs) # Define GNU standard installation directories -set(STLINK_UDEV_RULES_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/udev/rules.d" CACHE PATH "udev rules directory") -option(STLINK_INSTALL_UDEV_RULES "Install udev rules files" ON) - -set(STLINK_MODPROBED_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/modprobe.d" CACHE PATH "modprobe.d directory") -option(STLINK_INSTALL_MODPROBE_CONF "Install modprobe conf files" ON) - -option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) - ## Determine project version include(${CMAKE_MODULE_PATH}/get_version.cmake) @@ -271,20 +263,32 @@ else () target_link_libraries(st-util ${STLINK_LIB_SHARED} ${SSP_LIB}) endif () +install(TARGETS st-flash DESTINATION bin) +install(TARGETS st-info DESTINATION bin) +install(TARGETS st-util DESTINATION bin) + + +### +# udev and modprobe.d configuration +### + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + ## modprobe.d rules + set(STLINK_MODPROBED_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/modprobe.d" CACHE PATH "modprobe.d directory") + option(STLINK_INSTALL_MODPROBE_CONF "Install modprobe conf files" ON) if (STLINK_INSTALL_MODPROBE_CONF) - install(FILES etc/modprobe.d/stlink_v1.conf DESTINATION ${STLINK_MODPROBED_DIR}/) + install(FILES ${CMAKE_SOURCE_DIR}/etc/modprobe.d/stlink_v1.conf DESTINATION ${STLINK_MODPROBED_DIR}/) endif () + + ## udev rules + set(STLINK_UDEV_RULES_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/udev/rules.d" CACHE PATH "udev rules directory") + option(STLINK_INSTALL_UDEV_RULES "Install udev rules files" ON) if (STLINK_INSTALL_UDEV_RULES) - file(GLOB RULES_FILES etc/udev/rules.d/*.rules) + file(GLOB RULES_FILES ${CMAKE_SOURCE_DIR}/etc/udev/rules.d/*.rules) install(FILES ${RULES_FILES} DESTINATION ${STLINK_UDEV_RULES_DIR}/) endif () endif () -install(TARGETS st-flash DESTINATION bin) -install(TARGETS st-info DESTINATION bin) -install(TARGETS st-util DESTINATION bin) - ### # Additional build tasks @@ -297,9 +301,11 @@ add_subdirectory(include) # contains subordinate CMakeLists for version config a add_subdirectory(src/stlink-gui) # contains subordinate CMakeLists to build GUI add_subdirectory(tests) # contains subordinate CMakeLists to build test executables -add_subdirectory(doc/man) # contains subordinate CMakeLists to generate manpages add_subdirectory(cmake/packaging) # contains subordinate CMakeLists to build packages +option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) +add_subdirectory(doc/man) # contains subordinate CMakeLists to generate manpages + ### # Uninstall target diff --git a/Makefile b/Makefile index 3f46d2943..53b0ddcde 100644 --- a/Makefile +++ b/Makefile @@ -55,7 +55,7 @@ build/Debug: build/Release: @mkdir -p $@ - @cd $@ && cmake -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) -Wno-dev ../../ + @cd $@ && cmake -DCMAKE_BUILD_TYPE=Release $(CMAKEFLAGS) ../../ clean: @echo "[CLEAN]" diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 221c84d7b..3646654f4 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -30,7 +30,7 @@ foreach (manpage ${MANPAGES}) endif () if (f AND NOT WIN32) - install(FILES ${f} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1) + install(FILES ${f} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) unset(f) endif () endforeach () From 7ef06378aa16e210dc480ef5ae2bc12973becc0c Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 19 May 2020 11:28:35 +0200 Subject: [PATCH 0933/1435] Refactoring for build settings Tidy up install paths & directories: -> modprobe.d & udev rules (both are now ON per default on Linux) -> stlink-gui supplements -> man pages - Fixed paths according to GNUInstallDirs - cmake: Restructured library config - Test files & gui now use shared library --- .travis.sh | 12 +-- CMakeLists.txt | 88 +++++++------------ {etc => config}/modprobe.d/stlink_v1.conf | 0 .../udev/rules.d/49-stlinkv1.rules | 0 .../udev/rules.d/49-stlinkv2-1.rules | 0 .../udev/rules.d/49-stlinkv2.rules | 0 .../udev/rules.d/49-stlinkv3.rules | 0 doc/man/CMakeLists.txt | 2 +- src/stlink-gui/CMakeLists.txt | 29 +++--- tests/CMakeLists.txt | 6 +- 10 files changed, 56 insertions(+), 81 deletions(-) rename {etc => config}/modprobe.d/stlink_v1.conf (100%) rename {etc => config}/udev/rules.d/49-stlinkv1.rules (100%) rename {etc => config}/udev/rules.d/49-stlinkv2-1.rules (100%) rename {etc => config}/udev/rules.d/49-stlinkv2.rules (100%) rename {etc => config}/udev/rules.d/49-stlinkv3.rules (100%) diff --git a/.travis.sh b/.travis.sh index 2c98a6ef6..cc0958bf5 100755 --- a/.travis.sh +++ b/.travis.sh @@ -35,11 +35,11 @@ elif [ "$TRAVIS_OS_NAME" == "linux" ]; then cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && cd - - echo "--> Building Release..." + echo "--> Building Release with package..." mkdir -p build/Release && cd build/Release echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && make package && cd - + make package && cd - elif [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install libusb @@ -50,11 +50,11 @@ elif [ "$TRAVIS_OS_NAME" == "osx" ]; then cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && cd - - echo "--> Building Release..." + echo "--> Building Release with package..." mkdir -p build/Release && cd build/Release echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && make package && cd - + make package && cd - else # local test-build echo "--> Building Debug..." @@ -63,9 +63,9 @@ else # local test-build cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install ../../ make && cd - - echo "--> Building Release..." + echo "--> Building Release with package..." mkdir -p build/Release && cd build/Release echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install ../../ - make && make package && cd - + make package && cd - fi diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b3210dbf..dcdaf2ad4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,6 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) - ### # General project settings ### @@ -32,16 +31,7 @@ else () set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") endif () -## Set installation directories for libraries -if (IS_DIRECTORY ${LIB_INSTALL_DIR}) - set(LIB_INSTALL_DIR ${LIB_INSTALL_DIR} CACHE PATH "Main library directory") - set(STLINK_LIBRARY_PATH "${LIB_INSTALL_DIR}") -else () - set(LIB_INSTALL_DIR "lib" CACHE PATH "Main library directory") - set(STLINK_LIBRARY_PATH "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}") -endif () - -## Set installation directories for header files +## Set installation directories for header files ### TODO: Clean this up... if (IS_DIRECTORY ${INCLUDE_INSTALL_DIR}) set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_DIR} CACHE PATH "Main include directory") set(STLINK_INCLUDE_PATH "${INCLUDE_INSTALL_DIR}") @@ -95,13 +85,14 @@ endif () include_directories(${LIBUSB_INCLUDE_DIR}) # ==== -include_directories(include) ### TODO: Clean this up... +include_directories(${PROJECT_SOURCE_DIR}/include) ### TODO: Clean this up... include_directories(${PROJECT_BINARY_DIR}/include/stlink) -include_directories(include/stlink) -include_directories(include/stlink/tools) +include_directories(${PROJECT_SOURCE_DIR}/include/stlink) +include_directories(${PROJECT_SOURCE_DIR}/include/stlink/tools) # ==== include_directories(src) +include_directories(src/tools) ### TODO: Clean this up... set(STLINK_HEADERS include/stlink.h @@ -145,29 +136,30 @@ if (${CMAKE_BUILD_TYPE} MATCHES "Debug") endif () +### +# Libraries +### + +set(STLINK_LIBRARY_PATH ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Main library install directory") + +# Set the environment variable LD_LIBRARY_PATH to point to /usr/local/lib (per default). +execute_process (COMMAND bash -c "export LD_LIBRARY_PATH="${CMAKE_INSTALL_LIBDIR}"") + + ### # Shared library ### +# Set library name if (NOT WIN32) set(STLINK_LIB_SHARED ${PROJECT_NAME}) else (WIN32) set(STLINK_LIB_SHARED ${PROJECT_NAME}-shared) endif () -add_library( - ${STLINK_LIB_SHARED} SHARED - ${STLINK_HEADERS} # header files for ide projects generated by cmake - ${STLINK_SOURCE} - ) - -target_link_libraries( - ${STLINK_LIB_SHARED} - ${LIBUSB_LIBRARY} - ) +add_library(${STLINK_LIB_SHARED} SHARED ${STLINK_HEADERS} ${STLINK_SOURCE}) set(STLINK_SHARED_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) - message(STATUS "STLINK_LIB_SHARED: ${STLINK_LIB_SHARED}") message(STATUS "PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}") message(STATUS "VERSION: ${STLINK_SHARED_VERSION}") @@ -176,6 +168,7 @@ set_target_properties( ${STLINK_LIB_SHARED} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} VERSION ${STLINK_SHARED_VERSION} + OUTPUT_NAME ${PROJECT_NAME} ) # Link shared library @@ -197,19 +190,12 @@ install(TARGETS ${STLINK_LIB_SHARED} DESTINATION ${STLINK_LIBRARY_PATH}) # Static library ### -# Install static library per default -set(STLINK_STATIC_LIB ON CACHE BOOL "Install static lib") - +# Set library name set(STLINK_LIB_STATIC ${PROJECT_NAME}-static) -add_library( - ${STLINK_LIB_STATIC} STATIC - ${STLINK_HEADERS} # header files for ide projects generated by cmake - ${STLINK_SOURCE} - ) +add_library(${STLINK_LIB_STATIC} STATIC ${STLINK_HEADERS} ${STLINK_SOURCE}) set(STLINK_STATIC_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) - message(STATUS "STLINK_LIB_STATIC: ${STLINK_LIB_STATIC}") message(STATUS "PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}") message(STATUS "VERSION: ${STLINK_STATIC_VERSION}") @@ -233,9 +219,7 @@ else () target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB}) endif () -if (STLINK_STATIC_LIB) - install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH}) -endif () +install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH}) ### @@ -263,30 +247,24 @@ else () target_link_libraries(st-util ${STLINK_LIB_SHARED} ${SSP_LIB}) endif () -install(TARGETS st-flash DESTINATION bin) -install(TARGETS st-info DESTINATION bin) -install(TARGETS st-util DESTINATION bin) +install(TARGETS st-flash DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS st-info DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS st-util DESTINATION ${CMAKE_INSTALL_BINDIR}) ### -# udev and modprobe.d configuration +# Device configuration (Linux only) ### if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - ## modprobe.d rules - set(STLINK_MODPROBED_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/modprobe.d" CACHE PATH "modprobe.d directory") - option(STLINK_INSTALL_MODPROBE_CONF "Install modprobe conf files" ON) - if (STLINK_INSTALL_MODPROBE_CONF) - install(FILES ${CMAKE_SOURCE_DIR}/etc/modprobe.d/stlink_v1.conf DESTINATION ${STLINK_MODPROBED_DIR}/) - endif () - - ## udev rules - set(STLINK_UDEV_RULES_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/udev/rules.d" CACHE PATH "udev rules directory") - option(STLINK_INSTALL_UDEV_RULES "Install udev rules files" ON) - if (STLINK_INSTALL_UDEV_RULES) - file(GLOB RULES_FILES ${CMAKE_SOURCE_DIR}/etc/udev/rules.d/*.rules) - install(FILES ${RULES_FILES} DESTINATION ${STLINK_UDEV_RULES_DIR}/) - endif () + ## Install modprobe.d conf files / rules to /usr/local/etc/stlink (default) + set(STLINK_MODPROBED_DIR "${CMAKE_INSTALL_SYSCONFDIR}/${PROJECT_NAME}/modprobe.d" CACHE PATH "modprobe.d directory") + install(FILES ${CMAKE_SOURCE_DIR}/config/modprobe.d/stlink_v1.conf DESTINATION ${STLINK_MODPROBED_DIR}) + + ## Install udev rules files / rules to /usr/local/etc/stlink (default) + set(STLINK_UDEV_RULES_DIR "${CMAKE_INSTALL_SYSCONFDIR}/${PROJECT_NAME}/udev/rules.d" CACHE PATH "udev rules directory") + file(GLOB RULES_FILES ${CMAKE_SOURCE_DIR}/config/udev/rules.d/*.rules) + install(FILES ${RULES_FILES} DESTINATION ${STLINK_UDEV_RULES_DIR}) endif () diff --git a/etc/modprobe.d/stlink_v1.conf b/config/modprobe.d/stlink_v1.conf similarity index 100% rename from etc/modprobe.d/stlink_v1.conf rename to config/modprobe.d/stlink_v1.conf diff --git a/etc/udev/rules.d/49-stlinkv1.rules b/config/udev/rules.d/49-stlinkv1.rules similarity index 100% rename from etc/udev/rules.d/49-stlinkv1.rules rename to config/udev/rules.d/49-stlinkv1.rules diff --git a/etc/udev/rules.d/49-stlinkv2-1.rules b/config/udev/rules.d/49-stlinkv2-1.rules similarity index 100% rename from etc/udev/rules.d/49-stlinkv2-1.rules rename to config/udev/rules.d/49-stlinkv2-1.rules diff --git a/etc/udev/rules.d/49-stlinkv2.rules b/config/udev/rules.d/49-stlinkv2.rules similarity index 100% rename from etc/udev/rules.d/49-stlinkv2.rules rename to config/udev/rules.d/49-stlinkv2.rules diff --git a/etc/udev/rules.d/49-stlinkv3.rules b/config/udev/rules.d/49-stlinkv3.rules similarity index 100% rename from etc/udev/rules.d/49-stlinkv3.rules rename to config/udev/rules.d/49-stlinkv3.rules diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 3646654f4..23da9e150 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -30,7 +30,7 @@ foreach (manpage ${MANPAGES}) endif () if (f AND NOT WIN32) - install(FILES ${f} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + install(FILES ${f} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/man/man1) unset(f) endif () endforeach () diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index b5ef99df9..c38fdadaa 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -16,26 +16,23 @@ set(GUI_SOURCES gui.c gui.h) ## stlink-gui-local add_executable(stlink-gui-local ${GUI_SOURCES}) -set_target_properties( - stlink-gui-local PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}" - # Note: ${CMAKE_CURRENT_SOURCE_DIR} is src/stlink-gui - ) -target_link_libraries(stlink-gui-local ${STLINK_LIB_STATIC} ${GTK3_LDFLAGS} ${SSP_LIB}) +set_target_properties(stlink-gui-local PROPERTIES + # Note: ${CMAKE_CURRENT_SOURCE_DIR} is src/stlink-gui + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}") +target_link_libraries(stlink-gui-local ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) ## stlink-gui add_executable(stlink-gui ${GUI_SOURCES}) -set_target_properties( - stlink-gui PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/bin" - # Note: ${CMAKE_INSTALL_PREFIX} defaults to /usr/local - ) -target_link_libraries(stlink-gui ${STLINK_LIB_STATIC} ${GTK3_LDFLAGS} ${SSP_LIB}) +set_target_properties(stlink-gui PROPERTIES + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_BINDIR}") +target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) -install(TARGETS stlink-gui DESTINATION bin) -install(FILES stlink-gui.ui DESTINATION bin) +install(TARGETS stlink-gui DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_BINDIR}) if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - install(FILES stlink-gui.desktop DESTINATION share/applications) # Install desktop application entry - install(FILES icons/stlink-gui.svg DESTINATION share/icons/hicolor/scalable/apps) # Install icon + # Install desktop application entry + install(FILES stlink-gui.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/applications) + # Install icons + install(FILES icons/stlink-gui.svg DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/icons/hicolor/scalable/apps) endif () diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 40d2203db..6e60fdd5a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -6,11 +6,11 @@ set(TESTEXEC usb sg) foreach (test ${TESTEXEC}) add_executable(test-${test} ${test}.c) - add_dependencies(test-${test} ${STLINK_LIB_STATIC}) - target_link_libraries(test-${test} ${STLINK_LIB_STATIC} ${SSP_LIB}) + add_dependencies(test-${test} ${STLINK_LIB_SHARED}) + target_link_libraries(test-${test} ${STLINK_LIB_SHARED} ${SSP_LIB}) add_test(test-${test} ${CMAKE_BINARY_DIR}/bin/test-${test}) endforeach () add_executable(test-flash flash.c "${CMAKE_SOURCE_DIR}/src/tools/flash_opts.c") -target_link_libraries(test-flash ${STLINK_LIB_STATIC} ${SSP_LIB}) +target_link_libraries(test-flash ${STLINK_LIB_SHARED} ${SSP_LIB}) add_test(test-flash ${CMAKE_BINARY_DIR}/bin/test-flash) From 5fc02abf33722fbf27996e955b2cc3017368e45a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 19 May 2020 14:08:07 +0200 Subject: [PATCH 0934/1435] Improved cmake-config for GUI build --- src/stlink-gui/CMakeLists.txt | 57 ++++++++++++++++++----------------- src/stlink-gui/gui.c | 3 +- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index c38fdadaa..8c36e5a1f 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -2,37 +2,40 @@ # Build GUI ### -## GUI-Building requires the presence of a GTK3 toolset -if (NOT GTK3_FOUND) - message(STATUS "GTK3 not found!") - return() # no GTK3 present => no GUI build -else (GTK3_FOUND) - message(STATUS "Found GTK3: -I${GTK3_INCLUDE_DIRS}, ${GTK3_LIBRARIES}") -endif () +if (NOT WIN32) + ## GUI-Building requires the presence of a GTK3 toolset + if (NOT GTK3_FOUND) + message(STATUS "GTK3 not found!") + return() # no GTK3 present => no GUI build + else (GTK3_FOUND) + message(STATUS "Found GTK3: -I${GTK3_INCLUDE_DIRS}, ${GTK3_LIBRARIES}") + include_directories(SYSTEM ${GTK3_INCLUDE_DIRS}) + + # Install desktop application entry + install(FILES stlink-gui.desktop + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/applications) -include_directories(SYSTEM ${GTK3_INCLUDE_DIRS}) + # Install icons + install(FILES icons/stlink-gui.svg + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/icons/hicolor/scalable/apps) -set(GUI_SOURCES gui.c gui.h) + set(GUI_SOURCES gui.c gui.h) -## stlink-gui-local -add_executable(stlink-gui-local ${GUI_SOURCES}) -set_target_properties(stlink-gui-local PROPERTIES - # Note: ${CMAKE_CURRENT_SOURCE_DIR} is src/stlink-gui - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}") -target_link_libraries(stlink-gui-local ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) + ## stlink-gui-local + add_executable(stlink-gui-local ${GUI_SOURCES}) + file(COPY stlink-gui.ui DESTINATION ${CMAKE_BINARY_DIR}/bin) + set_target_properties(stlink-gui-local PROPERTIES + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_BINARY_DIR}/bin") + target_link_libraries(stlink-gui-local ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) -## stlink-gui -add_executable(stlink-gui ${GUI_SOURCES}) -set_target_properties(stlink-gui PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_BINDIR}") -target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) + ## stlink-gui + add_executable(stlink-gui ${GUI_SOURCES}) + install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_BINDIR}) + set_target_properties(stlink-gui PROPERTIES + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/bin") + target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) + install(TARGETS stlink-gui DESTINATION ${CMAKE_INSTALL_BINDIR}) -install(TARGETS stlink-gui DESTINATION ${CMAKE_INSTALL_BINDIR}) -install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_BINDIR}) -if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - # Install desktop application entry - install(FILES stlink-gui.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/applications) - # Install icons - install(FILES icons/stlink-gui.svg DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/icons/hicolor/scalable/apps) + endif () endif () diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index 5d5a422d5..0a95aee76 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -781,8 +781,7 @@ static void stlink_gui_build_ui (STlinkGUI *gui) { GtkListStore *filemem_store; gchar *ui_file = STLINK_UI_DIR "/stlink-gui.ui"; - if (!g_file_test (ui_file, G_FILE_TEST_EXISTS)) - ui_file = "stlink-gui.ui"; + if (!g_file_test (ui_file, G_FILE_TEST_EXISTS)) ui_file = "stlink-gui.ui"; builder = gtk_builder_new (); if (!gtk_builder_add_from_file (builder, ui_file, NULL)) { g_printerr ("Failed to load UI file: %s\n", ui_file); From 73dc5fed246317711f0ece4252064dbf3b63534b Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Tue, 19 May 2020 17:50:10 +0300 Subject: [PATCH 0935/1435] link libssp statically --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dcdaf2ad4..c61b9b6bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,7 @@ include(CheckLibraryExists) CHECK_LIBRARY_EXISTS(ssp __stack_chk_fail "" _stack_chk_fail_exists) if (_stack_chk_fail_exists) - set(SSP_LIB ssp) + set(SSP_LIB -static ssp) else () set(SSP_LIB "") endif () From af765a20228dd973d9933ed49228049bc121fcce Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 22 May 2020 15:11:43 +0200 Subject: [PATCH 0936/1435] Minor fixes for flashloader files --- flashloaders/stm32f0.s | 4 ++-- flashloaders/stm32f4.s | 4 ++-- flashloaders/stm32f4lv.s | 4 ++-- flashloaders/stm32f7.s | 4 ++-- flashloaders/stm32f7lv.s | 4 ++-- flashloaders/stm32l4.s | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index cbb932b49..f30e4bfc6 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -42,11 +42,11 @@ loop: adds r1, r1, r7 # wait if FLASH_SR == 1 -mywait: +wait: ldr r7, =0x1 ldr r3, [r5] tst r3, r7 - beq mywait + beq wait # exit if FLASH_SR != 4 ldr r7, =0x4 diff --git a/flashloaders/stm32f4.s b/flashloaders/stm32f4.s index b4e0f4913..a88ad9e02 100644 --- a/flashloaders/stm32f4.s +++ b/flashloaders/stm32f4.s @@ -16,10 +16,10 @@ loop: add r1, r1, #4 # wait if FLASH_SR == 1 -mywait: +wait: ldrh r3, [r10] tst r3, #0x1 - beq mywait + beq wait # loop if r2 != 0 sub r2, r2, #1 diff --git a/flashloaders/stm32f4lv.s b/flashloaders/stm32f4lv.s index f5cc29841..41467a9ef 100644 --- a/flashloaders/stm32f4lv.s +++ b/flashloaders/stm32f4lv.s @@ -22,10 +22,10 @@ loop: add r1, r1, #1 # wait if FLASH_SR == 1 -mywait: +wait: ldrh r3, [r10] tst r3, #0x1 - beq mywait + beq wait # loop if r2 != 0 sub r2, r2, #1 diff --git a/flashloaders/stm32f7.s b/flashloaders/stm32f7.s index 8694d864e..3779a5ea6 100644 --- a/flashloaders/stm32f7.s +++ b/flashloaders/stm32f7.s @@ -19,10 +19,10 @@ loop: dsb sy # wait if FLASH_SR == 1 -mywait: +wait: ldrh r3, [r10] tst r3, #0x1 - beq mywait + beq wait # loop if r2 != 0 sub r2, r2, #1 diff --git a/flashloaders/stm32f7lv.s b/flashloaders/stm32f7lv.s index b48e40f0d..e7b66cc2c 100644 --- a/flashloaders/stm32f7lv.s +++ b/flashloaders/stm32f7lv.s @@ -25,10 +25,10 @@ loop: dsb sy # wait if FLASH_SR == 1 -mywait: +wait: ldrh r3, [r10] tst r3, #0x1 - beq mywait + beq wait # loop if r2 != 0 sub r2, r2, #1 diff --git a/flashloaders/stm32l4.s b/flashloaders/stm32l4.s index c68198bfa..32c27a057 100644 --- a/flashloaders/stm32l4.s +++ b/flashloaders/stm32l4.s @@ -18,10 +18,10 @@ loop: add r1, r1, #8 # wait if FLASH_BSY[0b] == 1 -mywait: +wait: ldrh r3, [r10] tst r3, #0x1 - beq mywait + beq wait # loop if r2 != 0 sub r2, r2, #1 From 937f4d6aeaf7ddc50bc181a1448a40fc9389e8c2 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 22 May 2020 19:42:16 +0200 Subject: [PATCH 0937/1435] General Project Update - Updated CHANGELOG - Minor fixes --- CHANGELOG.md | 126 ++++++++++++++++++++++++++++--------------------- CMakeLists.txt | 6 +-- README.md | 2 +- 3 files changed, 74 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f79cd846c..b6b63e156 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,67 +10,83 @@ This release drops support for some older operating systems. Check project READM Features: -- Support for STM32L1, SM32L4 option bytes write (#596, #844, #847) -- CMake now creates an uninstall target (#619, #907) -- Added CMAKEFLAGS and install target (#804, #935) -- Support for STM32G4 (#822) -- Add aliased SRAM2 region in the L496 memory map (#824) -- Improved support for STM32G0 (#825, #850, #856, #857) -- Added postinst script with 'depmod -a' for 'make package' (#845, #931) -- Calculate checksums for flash operations (#862, #924) -- Added usb PID and udev rules for STlink v2.1 found on Nucleo-L432KC and Nucleo-L552ze boards (#900) -- STM32G0/G4 improvements (#910) +- Basic compatibility for STLink-v3 programmer ([#271](https://github.com/stlink-org/stlink/pull/271), [#863](https://github.com/stlink-org/stlink/pull/863), [#954](https://github.com/stlink-org/stlink/pull/954)) + - Added support for JTAG command API v2 & distinguish protocol versions v1 and v2 + - Compatibility with the STLink-v3 firmware which dropped support for the previous API v1 + - As of firmware version J11 the ST-LINK-V1 programmer supports API v2 commands as well +- Display programmer serial when no target is connected ([#432](https://github.com/stlink-org/stlink/pull/432), [#933](https://github.com/stlink-org/stlink/pull/933), [#943](https://github.com/stlink-org/stlink/pull/943)) +- Support for STM32L1, SM32L4 option bytes write ([#596](https://github.com/stlink-org/stlink/pull/596), [#844](https://github.com/stlink-org/stlink/pull/844), [#847](https://github.com/stlink-org/stlink/pull/847)) +- CMake now creates an uninstall target ([#619](https://github.com/stlink-org/stlink/pull/619), [#907](https://github.com/stlink-org/stlink/pull/907)) +- Added CMAKEFLAGS and install target ([#804](https://github.com/stlink-org/stlink/pull/804), [#935](https://github.com/stlink-org/stlink/pull/935)) +- Support for STM32G4 ([#822](https://github.com/stlink-org/stlink/pull/822)) +- Add aliased SRAM2 region in the L496 memory map ([#824](https://github.com/stlink-org/stlink/pull/824)) +- Improved support for STM32G0 ([#825](https://github.com/stlink-org/stlink/pull/825), [#850](https://github.com/stlink-org/stlink/pull/850), [#856](https://github.com/stlink-org/stlink/pull/856), [#857](https://github.com/stlink-org/stlink/pull/857)) +- Added postinst script with 'depmod -a' for 'make package' ([#845](https://github.com/stlink-org/stlink/pull/845), [#931](https://github.com/stlink-org/stlink/pull/931)) +- Calculate checksums for flash operations ([#862](https://github.com/stlink-org/stlink/pull/862), [#924](https://github.com/stlink-org/stlink/pull/924)) +- Adjust the JTAG/SWD frequency via cmdline option ([#893](https://github.com/stlink-org/stlink/pull/893), [#953](https://github.com/stlink-org/stlink/pull/953)) +- Added usb PID and udev rules for STlink v2.1 found on Nucleo-L432KC and Nucleo-L552ze boards ([#900](https://github.com/stlink-org/stlink/pull/900)) +- STM32G0/G4 improvements ([#910](https://github.com/stlink-org/stlink/pull/910)) - Enable mass erase with a flash programming check - Handle G4 Cat3 devices with configurable dual bank flash by using a helper -- Display programmer serial when no target is connected (#432, #933, #943) Updates & changes: -- Define libusb version compatibility for supported operating systems via LIBUSB_API_VERSION (#211, #782, #895) -- Improved argument parsing for CLI tools (#378, #922) -- [doc] Updated tutorial: macOS ST-Link-v1 detection (#574, #587) -- Enhanced output for error msg "addr not a multiple of pagesize, not supported" (#663, #945) -- [doc] Verify correct udev configuration for device access (#764) -- Added more error info to WLOGs during probe (#883) -- Added check for libssp during compilation (#885) -- Silence unnecessary messages (#886) -- Set up a libusb log level accordingly to verbosity (commit 49f887d5247fdd28f163b6317790c4f087e652cc) -- [doc] Define libusb & cmake version compatibility (#896, #897, #899, commit 27aa88821197d3ffe82baff4e971c3488ec39899) -- Update for STM32G471/473/474/483/484 devices (#901) -- [doc] st-flash --flash=n[k][m] command line option to override device model (#902) -- [doc] Update compiling instructions (#113, commit 10ae5294cd03aacfc07312010f026d3cb12ea56c) -- [doc] Defined version compatibility and installation instructions for macOS (commit 23c071edea45f6e8852fef52d884a680973d6d8f) -- Deprecated old appveyor-mingw script (commit 97484422008df0f75c978627054776f35842a075) -- Enhanced error log with file path for map_file() (#650, #879, #921) -- [refactoring] Overall option code rework (#927) -- [refactoring] Build settings / GUI-Build on UNIX-based systems if GTK3 is detected (#929) -- [refactoring] Reconfiguration of package build process (#931, #936, #940, commit 9b19f9225460472af9d98959b7217d0a840ee972) -- [refactoring] st-util: Removed now useless v1/v2 STLink version stuff (#934) -- [refactoring] Cleanup for option bytes and flash settings (#941) -- Added compilation guideline for MSVC toolchain (#942) -- st-util: Removal of useless v1/v2 stlink version stuff (#934) -- libusb package extraction no longer requires 7zip as an external unarchiver (commit 5db2dc4c0410ace65308cddcc03d1c0cfa4855cf) -- [refactoring] Cleanup of cmake build process (#944, #946, #947) +- [doc] Update compiling instructions ([#113](https://github.com/stlink-org/stlink/pull/113), commit [#10ae529](https://github.com/stlink-org/stlink/commit/10ae5294cd03aacfc07312010f026d3cb12ea56c)) +- Define libusb version compatibility for supported operating systems via LIBUSB_API_VERSION ([#211](https://github.com/stlink-org/stlink/pull/211), [#782](https://github.com/stlink-org/stlink/pull/782), [#895](https://github.com/stlink-org/stlink/pull/895)) +- Improved argument parsing for CLI tools ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) +- [doc] Updated tutorial: macOS ST-Link-v1 detection ([#574](https://github.com/stlink-org/stlink/pull/574), [#587](https://github.com/stlink-org/stlink/pull/587)) +- Enhanced error log with file path for map_file() ([#650](https://github.com/stlink-org/stlink/pull/650), [#879](https://github.com/stlink-org/stlink/pull/879), [#921](https://github.com/stlink-org/stlink/pull/921)) +- Enhanced output for error msg "addr not a multiple of pagesize, not supported" ([#663](https://github.com/stlink-org/stlink/pull/663), [#945](https://github.com/stlink-org/stlink/pull/945)) +- [refactoring] Package distribution: Provide Windows binaries via Debian-based cross-build ([#738](https://github.com/stlink-org/stlink/pull/738), [#795](https://github.com/stlink-org/stlink/pull/795), [#798](https://github.com/stlink-org/stlink/pull/798), [#955](https://github.com/stlink-org/stlink/pull/955)) + - Update, corrections & cleanup for build settings (see #955 for details) + - New cpack package-config for DEB and RPM build + - Update for travis build configuration: builds for clang -m32, clang-9, MinGW-cross on linux + - Updated steps for release preparation + - Project contributors now listed in separate file + - Test files & gui now use shared stlink-library +- [doc] Verify correct udev configuration for device access ([#764](https://github.com/stlink-org/stlink/pull/764)) +- Added more error info to WLOGs during probe ([#883](https://github.com/stlink-org/stlink/pull/883)) +- [doc] Add missing documentation for stlink-gui ([#884](https://github.com/stlink-org/stlink/pull/884)) +- Added check for libssp during compilation ([#885](https://github.com/stlink-org/stlink/pull/885)) +- Silence unnecessary messages ([#886](https://github.com/stlink-org/stlink/pull/886)) +- [doc] Define libusb & cmake version compatibility ([#896](https://github.com/stlink-org/stlink/pull/896), [#897](https://github.com/stlink-org/stlink/pull/897), [#899](https://github.com/stlink-org/stlink/pull/899), commit [#27aa888](https://github.com/stlink-org/stlink/commit/27aa88821197d3ffe82baff4e971c3488ec39899)) +- Update for STM32G471/473/474/483/484 devices ([#901](https://github.com/stlink-org/stlink/pull/901)) +- [doc] st-flash --flash=n[k][m] command line option to override device model ([#902](https://github.com/stlink-org/stlink/pull/902)) +- [refactoring] BSD-License-compliant rewrite of flashloader source files ([#915](https://github.com/stlink-org/stlink/pull/915), [#932](https://github.com/stlink-org/stlink/pull/932)) +- [refactoring] Overall option code rework ([#927](https://github.com/stlink-org/stlink/pull/927)) +- [refactoring] Build settings / GUI-Build on UNIX-based systems if GTK3 is detected ([#929](https://github.com/stlink-org/stlink/pull/929)) +- [refactoring] Reconfiguration of package build process ([#931](https://github.com/stlink-org/stlink/pull/931), [#936](https://github.com/stlink-org/stlink/pull/936), [#940](https://github.com/stlink-org/stlink/pull/940), commit [#9b19f92](https://github.com/stlink-org/stlink/commit/9b19f9225460472af9d98959b7217d0a840ee972)) +- [refactoring] st-util: Removed now useless v1/v2 STLink version stuff ([#934](https://github.com/stlink-org/stlink/pull/934)) +- [refactoring] Cleanup for option bytes and flash settings ([#941](https://github.com/stlink-org/stlink/pull/941)) +- Added compilation guideline for MSVC toolchain ([#942](https://github.com/stlink-org/stlink/pull/942)) +- [refactoring] Cleanup of cmake build process ([#944](https://github.com/stlink-org/stlink/pull/944), [#946](https://github.com/stlink-org/stlink/pull/946), [#947](https://github.com/stlink-org/stlink/pull/947)) +- Set up a libusb log level accordingly to verbosity (commit [#49f887d](https://github.com/stlink-org/stlink/commit/49f887d5247fdd28f163b6317790c4f087e652cc)) +- [doc] Defined version compatibility and installation instructions for macOS (commit [#23c071e](https://github.com/stlink-org/stlink/commit/23c071edea45f6e8852fef52d884a680973d6d8f)) +- Deprecated old appveyor-mingw script (commit [#9748442](https://github.com/stlink-org/stlink/commit/97484422008df0f75c978627054776f35842a075)) +- libusb package extraction no longer requires 7zip as an external unarchiver (commit [#5db2dc4](https://github.com/stlink-org/stlink/commit/5db2dc4c0410ace65308cddcc03d1c0cfa4855cf)) + Fixes: -- Fixed wait-loop for flash_loader_run() (#290) -- Clear the PG bit before setting the PER bit (#579, #876) -- Fixed compilation issues with int length on 32-bit platforms (#629, #908) -- Fixed st-info --probe mechanism (#679, #918) -- Fixed sign-compare (size != rep_len) in usb.c (Regression) (#772, #869, #872, #891) -- Avoid re-define of O_BINARY on Windows (#788) -- Fixed st-flash manpage read example (#858) -- Fixed stlink support with no mass storage (#861) -- Make Version.cmake more error-resistant (#872) -- Error return in failed probe (#887, #890) -- Fixed formatting for options display in st-flash & st-info (commits c783d0e777ccc83a7a8be26a4f4d3414e0478560 and 562cd2496e696dbd22950925866aac662d81ee5f) -- Fixed dead loop after an unexpected unplug (#780, #812, #913) -- Fixed broken build on 32-bit systems (#919, #920) -- st-flash: Minor usage fix and make cmdline parsing more user friendly (#925) -- Better argument parsing for CLI tools: stlink_open_usb can address v1, v2, v3 (#378, #922) -- Restored functionality of make test builds (Regression) (#926, #929) -- Fixed compilation error due to uninitialized cpuid (#937, #938) +- Fixed wait-loop for flash_loader_run() ([#290](https://github.com/stlink-org/stlink/pull/290)) +- Better argument parsing for CLI tools: stlink_open_usb can address v1, v2, v3 ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) +- Clear the PG bit before setting the PER bit ([#579](https://github.com/stlink-org/stlink/pull/579), [#876](https://github.com/stlink-org/stlink/pull/876)) +- Fixed compilation issues with int length on 32-bit platforms ([#629](https://github.com/stlink-org/stlink/pull/629), [#908](https://github.com/stlink-org/stlink/pull/908)) +- Fixed st-info --probe mechanism ([#679](https://github.com/stlink-org/stlink/pull/679), [#918](https://github.com/stlink-org/stlink/pull/918)) +- [regression] Fixed sign-compare (size != rep_len) in usb.c ([#772](https://github.com/stlink-org/stlink/pull/772), [#869](https://github.com/stlink-org/stlink/pull/869), [#872](https://github.com/stlink-org/stlink/pull/872), [#891](https://github.com/stlink-org/stlink/pull/891)) +- Fixed dead loop after an unexpected unplug ([#780](https://github.com/stlink-org/stlink/pull/780), [#812](https://github.com/stlink-org/stlink/pull/812), [#913](https://github.com/stlink-org/stlink/pull/913)) +- Avoid re-define of O_BINARY on Windows ([#788](https://github.com/stlink-org/stlink/pull/788)) +- Fixed st-flash manpage read example ([#858](https://github.com/stlink-org/stlink/pull/858)) +- Fixed stlink support with no mass storage ([#861](https://github.com/stlink-org/stlink/pull/861)) +- Make Version.cmake more error-resistant ([#872](https://github.com/stlink-org/stlink/pull/872)) +- Error return in failed probe ([#887](https://github.com/stlink-org/stlink/pull/887), [#890](https://github.com/stlink-org/stlink/pull/890)) +- Fixed broken build on 32-bit systems ([#919](https://github.com/stlink-org/stlink/pull/919), [#920](https://github.com/stlink-org/stlink/pull/920)) +- st-flash: Minor usage fix and make cmdline parsing more user friendly ([#925](https://github.com/stlink-org/stlink/pull/925)) +- [regression] Restored functionality of make test builds ([#926](https://github.com/stlink-org/stlink/pull/926), [#929](https://github.com/stlink-org/stlink/pull/929)) +- Fixed compilation error due to uninitialized cpuid ([#937](https://github.com/stlink-org/stlink/pull/937), [#938](https://github.com/stlink-org/stlink/pull/938)) +- Fixes for STM32F0 flashloader ([#958](https://github.com/stlink-org/stlink/pull/958), [#959](https://github.com/stlink-org/stlink/pull/959) +- Set static link for libssp (stack-smashing protection) ([#960](https://github.com/stlink-org/stlink/pull/960), [#961](https://github.com/stlink-org/stlink/pull/961)) +- Fixed formatting for options display in st-flash & st-info (commits [#c783d0e](https://github.com/stlink-org/stlink/commit/c783d0e777ccc83a7a8be26a4f4d3414e0478560) and [#562cd24](https://github.com/stlink-org/stlink/commit/562cd2496e696dbd22950925866aac662d81ee5f)) v1.6.0 @@ -81,7 +97,7 @@ Release date: 2020-02-20 Major changes and added features: * Initial support for STM32L41X ([#754](https://github.com/stlink-org/stlink/pull/754), [#799](https://github.com/stlink-org/stlink/pull/799)) -* Working support for CKS32F103C8T6 and related CKS devices with Core-ID 0x2ba01477 ([#756](https://github.com/stlink-org/stlink/pull/756), [#757](https://github.com/stlink-org/stlink/pull/757), [#805](https://github.com/stlink-org/stlink/pull/805), [#834](https://github.com/stlink-org/stlink/pull/834), Regression-Fixes: [#761](https://github.com/stlink-org/stlink/pull/761), [#766](https://github.com/stlink-org/stlink/pull/766)) +* Verified support for CKS32F103C8T6 and related CKS devices with Core-ID 0x2ba01477 ([#756](https://github.com/stlink-org/stlink/pull/756), [#757](https://github.com/stlink-org/stlink/pull/757), [#805](https://github.com/stlink-org/stlink/pull/805), [#834](https://github.com/stlink-org/stlink/pull/834), Regression-Fixes: [#761](https://github.com/stlink-org/stlink/pull/761), [#766](https://github.com/stlink-org/stlink/pull/766)) * Added preliminary support for some STM32G0 chips ([#759](https://github.com/stlink-org/stlink/pull/759), [#760](https://github.com/stlink-org/stlink/pull/760), [#797](https://github.com/stlink-org/stlink/pull/797)) * Added support for mass erasing second bank on STM32F10x_XL ([#767](https://github.com/stlink-org/stlink/pull/767), [#768](https://github.com/stlink-org/stlink/pull/768)) * Added call to clear PG bit after writing to flash ([#773](https://github.com/stlink-org/stlink/pull/773)) @@ -155,7 +171,7 @@ Updates and fixes: * Disabled static library installation by default ([#702](https://github.com/stlink-org/stlink/pull/702)) * Fix for libusb deprecation ([#703](https://github.com/stlink-org/stlink/pull/703), [#704](https://github.com/stlink-org/stlink/pull/704)) * Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX ([#706](https://github.com/stlink-org/stlink/pull/706)) -* Regression: stlink installation under Linux (Debian 9) is broken since #695 ([#700](https://github.com/stlink-org/stlink/pull/700), [#701](https://github.com/stlink-org/stlink/pull/701), [#707](https://github.com/stlink-org/stlink/pull/707)) +* [regression] stlink installation under Linux (Debian 9) is broken since #695 ([#700](https://github.com/stlink-org/stlink/pull/700), [#701](https://github.com/stlink-org/stlink/pull/701), [#707](https://github.com/stlink-org/stlink/pull/707)) * Fixed flash memory map for STM32F72xxx target ([#711](https://github.com/stlink-org/stlink/pull/711)) * Proper flash page size calculation for STM32F412xx target ([#721](https://github.com/stlink-org/stlink/pull/721)) * Return correct value on EOF for Semihosting SYS_READ ([#726](https://github.com/stlink-org/stlink/pull/726), [#727](https://github.com/stlink-org/stlink/pull/727), [#728](https://github.com/stlink-org/stlink/pull/728), [#729](https://github.com/stlink-org/stlink/pull/729), [#730](https://github.com/stlink-org/stlink/pull/730), [#731](https://github.com/stlink-org/stlink/pull/731), [#732](https://github.com/stlink-org/stlink/pull/732)) diff --git a/CMakeLists.txt b/CMakeLists.txt index c61b9b6bf..6b17fdc57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,8 +164,7 @@ message(STATUS "STLINK_LIB_SHARED: ${STLINK_LIB_SHARED}") message(STATUS "PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}") message(STATUS "VERSION: ${STLINK_SHARED_VERSION}") -set_target_properties( - ${STLINK_LIB_SHARED} PROPERTIES +set_target_properties(${STLINK_LIB_SHARED} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} VERSION ${STLINK_SHARED_VERSION} OUTPUT_NAME ${PROJECT_NAME} @@ -200,8 +199,7 @@ message(STATUS "STLINK_LIB_STATIC: ${STLINK_LIB_STATIC}") message(STATUS "PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}") message(STATUS "VERSION: ${STLINK_STATIC_VERSION}") -set_target_properties( - ${STLINK_LIB_STATIC} PROPERTIES +set_target_properties(${STLINK_LIB_STATIC} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} VERSION ${STLINK_STATIC_VERSION} OUTPUT_NAME ${PROJECT_NAME} diff --git a/README.md b/README.md index 42ee63aa2..b2495840d 100644 --- a/README.md +++ b/README.md @@ -125,4 +125,4 @@ Here we would appreciate any help and would love to welcome new contributors who * Writing external memory connected to an STM32 controller (e.g Quad SPI NOR flash) ([#412](https://github.com/stlink-org/stlink/issues/412)) * MCU hotplug ([#449](https://github.com/stlink-org/stlink/issues/449)) * Writing options bytes (region) ([#458](https://github.com/stlink-org/stlink/issues/458)) -* Support for STLINKv3 programmer ([#820](https://github.com/stlink-org/stlink/issues/820)) +* Enhanced support for STLINKv3 programmer ([#820](https://github.com/stlink-org/stlink/issues/820)) From ea17f9ac77064e3c47b58fd014834f06bd763724 Mon Sep 17 00:00:00 2001 From: Geoffrey Brown Date: Fri, 22 May 2020 14:40:26 -0400 Subject: [PATCH 0938/1435] added connect under reset code --- .vscode/settings.json | 3 +++ src/usb.c | 5 +++-- src/usb.h | 2 +- tests/usb.c | 23 ++++++++++++++++++++--- 4 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..cad7657df --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.configureOnOpen": false +} \ No newline at end of file diff --git a/src/usb.c b/src/usb.c index b986aed57..26243daa3 100644 --- a/src/usb.c +++ b/src/usb.c @@ -937,7 +937,7 @@ static stlink_backend_t _stlink_usb_backend = { _stlink_usb_set_swdclk }; -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq) { +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; int ret = -1; @@ -1145,9 +1145,10 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST break; } + if (reset == 2) stlink_jtag_reset(sl,0); if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); - if (reset) { + if (reset == 1) { if ( sl->version.stlink_v > 1) stlink_jtag_reset(sl, 2); stlink_reset(sl); usleep(10000); diff --git a/src/usb.h b/src/usb.h index 061042e8d..5c1f5b7ca 100644 --- a/src/usb.h +++ b/src/usb.h @@ -68,7 +68,7 @@ extern "C" { * @retval NULL Error while opening the stlink * @retval !NULL Stlink found and ready to use */ - stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq); + stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq); size_t stlink_probe_usb(stlink_t **stdevs[]); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); diff --git a/tests/usb.c b/tests/usb.c index 5165ea563..ce72e24a5 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -1,15 +1,32 @@ #include #include +#include + +static void usage(void) +{ + puts("test-usb --reset"); + puts("test-usb --no-reset"); +} int main(int ac, char** av) { - (void)ac; - (void)av; stlink_t* sl; struct stlink_reg regs; + int reset = 0; + + if (ac == 2) { + if (strcmp(av[1], "--reset") == 0) + reset = 2; + if (strcmp(av[1], "--no-reset") == 0) + reset = 1; + } + if (reset == 0) { + usage(); + return 0; + } - sl = stlink_open_usb(10, 1, NULL, 0); + sl = stlink_open_usb(10, reset, NULL, 0); if (sl != NULL) { printf("-- version\n"); stlink_version(sl); From ce0df3ba3c3ea211f343b1b83800d7a8161792e4 Mon Sep 17 00:00:00 2001 From: Geoffrey Brown Date: Fri, 22 May 2020 17:51:17 -0400 Subject: [PATCH 0939/1435] removed .vscode --- .vscode/settings.json | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index cad7657df..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "cmake.configureOnOpen": false -} \ No newline at end of file From 25d0e56161d02014f77b9efd1a3fc66ef30f27b5 Mon Sep 17 00:00:00 2001 From: Geoffrey Brown Date: Sat, 23 May 2020 16:01:12 -0400 Subject: [PATCH 0940/1435] Added --connect-under-reset to st-flash and st-info --- include/stlink/tools/flash.h | 3 ++- src/tools/flash_opts.c | 3 +++ src/tools/info.c | 39 +++++++++++++++++++++++++----------- src/usb.c | 10 ++++++++- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index a912a14aa..3a4dc3ec4 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -27,9 +27,10 @@ struct flash_opts size_t flash_size; /* --flash=n[k][m] */ int opt; /* enable empty tail data drop optimization */ int freq; /* --freq=n[k][m] frequency of JTAG/SWD */ + bool connect_under_reset; }; -#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} int flash_get_opts(struct flash_opts* o, int ac, char** av); diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index a5c9d287f..c8d7841de 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -225,6 +225,9 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { if (result != 0) return bad_arg ("--flash"); else o->flash_size = (size_t) flash_size; } + else if (strcmp(av[0],"--connect-under-reset")== 0){ + o->connect_under_reset = true; + } else { break; // non-option found } diff --git a/src/tools/info.c b/src/tools/info.c index 45d484270..8464d8632 100644 --- a/src/tools/info.c +++ b/src/tools/info.c @@ -11,11 +11,11 @@ static void usage(void) puts("st-info --probe"); puts("st-info --serial"); puts("st-info --hla-serial"); - puts("st-info --flash"); - puts("st-info --pagesize"); - puts("st-info --sram"); - puts("st-info --chipid"); - puts("st-info --descr"); + puts("st-info --flash [--connect-under-reset]"); + puts("st-info --pagesize [--connect-under-reset]"); + puts("st-info --sram [--connect-under-reset]"); + puts("st-info --chipid [--connect-under-reset]"); + puts("st-info --descr [--connect-under-reset]"); } /* Print normal or OpenOCD hla_serial with newline */ @@ -76,19 +76,25 @@ static void stlink_probe(void) stlink_probe_usb_free(&stdevs, size); } -static stlink_t *stlink_open_first(void) +static stlink_t *stlink_open_first(bool under_reset) { stlink_t* sl = NULL; sl = stlink_v1_open(0, 1); - if (sl == NULL) - sl = stlink_open_usb(0, 1, NULL, 0); - + if (sl == NULL) { + if (under_reset) { + sl = stlink_open_usb(0, 2, NULL, 0); + } else { + sl = stlink_open_usb(0, 1, NULL, 0); + } + } + return sl; } -static int print_data(char **av) +static int print_data(int ac, char **av) { stlink_t* sl = NULL; + bool under_reset = false; // Probe needs all devices unclaimed if (strcmp(av[1], "--probe") == 0) { @@ -99,7 +105,16 @@ static int print_data(char **av) return 0; } - sl = stlink_open_first(); + if (ac == 3) { + if (strcmp(av[2],"--connect-under-reset") == 0) { + under_reset = true; + } else { + usage(); + return -1; + } + } + + sl = stlink_open_first(under_reset); if (sl == NULL) { return -1; @@ -149,7 +164,7 @@ int main(int ac, char** av) return -1; } - err = print_data(av); + err = print_data(ac,av); return err; } diff --git a/src/usb.c b/src/usb.c index 26243daa3..a711749da 100644 --- a/src/usb.c +++ b/src/usb.c @@ -1145,7 +1145,15 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL break; } - if (reset == 2) stlink_jtag_reset(sl,0); + if (reset == 2) { + stlink_jtag_reset(sl,0); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); + stlink_force_debug(sl); + stlink_jtag_reset(sl,1); + usleep(10000); + } + + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); if (reset == 1) { From fd2a5c37d4e5b7886bef1157717ea64a611b7b5a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 25 May 2020 00:40:56 +0200 Subject: [PATCH 0941/1435] Minor formatting fixes & corrections --- README.md | 9 +++------ contributors.txt | 6 ++++++ doc/app-example/CMakeLists.txt | 7 ++++--- doc/app-example/README.md | 2 +- doc/app-example/main.c | 7 +++---- doc/devices_boards.md | 2 +- doc/release.md | 2 +- doc/version_support.md | 2 ++ run_clang_analyze.sh | 5 +++-- 9 files changed, 24 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index b2495840d..7dc634c9c 100644 --- a/README.md +++ b/README.md @@ -15,16 +15,13 @@ Recent new features and bugfixes can be found in the [Changelog](CHANGELOG.md) o #### License -The stlink library and tools are licensed under the **[BSD-3 License](LICENSE.md)**.
    -The source files **stm32l0x.s** and **stm32lx.s** found in the subdirectory `/flashloaders/` -are licensed under the **General Public License (GPL v2+)**. +The stlink library and tools are licensed under the **[BSD-3 License](LICENSE.md)**. ## Introduction STLink is an open source toolset to program and debug STM32 devices and boards manufactured by STMicroelectronics. -It supports several so called STLINK programmer boards (and clones thereof) which use a microcontroller chip -to translate commands from USB to JTAG/SWD. There are four generations available on the market: +It supports several so called STLINK programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG/SWD. There are four generations available on the market which are _all_ supported by this toolset: * **STLINK/v1** _(obsolete as of 21-11-2019)_ - transport layer: SCSI passthru commands over USB @@ -59,7 +56,7 @@ Supported operating systems are listed in [version_support.md](doc/version_suppo ## Tutorial & HOWTO -Our [tutorial.md](doc/tutorial.md) may help you along with some advanced tasks and additional info. +Our [tutorial](doc/tutorial.md) may help you along with some advanced tasks and additional info. ## Installation diff --git a/contributors.txt b/contributors.txt index 32c8e58e3..8811da855 100644 --- a/contributors.txt +++ b/contributors.txt @@ -37,6 +37,7 @@ Ethan Zonca Fabien Chouteau Florian Hars Friedrich Beckmann +Gabriel Górski [Glaeqen] Geoffrey Brown George Talusan [gtalusan] Georg von Zengen @@ -60,6 +61,7 @@ Jerome Lambourg Jim Paris Jiří Netolický Jerry Nosky [jnosky] +Jochen Wilhelmy [Jochen0x90h] Johannes Taelman Jonas Danielsson Jonas Norling @@ -68,6 +70,7 @@ Karl Palsson [karlp] Kevlar Harness Kyle Manna Lari Lehtomäki +Lutz Freitag [nerdmaennchen] Martin Nowak Matteo Collina Max Chen @@ -76,6 +79,7 @@ Maxime Vincent Michael Pratt [prattmic] Michael Sparmann Mike Szczys +Miklós Márton [martonmiklos] Magnus Lundin [mlu] mux Ned Konz @@ -89,6 +93,7 @@ orangeudav Pavel Kirienko Pekka Nikander Pete Nelson +Peter Torelli [petertorelli] Peter Zotov Petteri Aimonen Piotr Haber @@ -99,6 +104,7 @@ Rob Spanton Rytis Karpuska Sean Simmons Sergey Alirzaev +Simon Derr [sderr] Simon Wright Stany Marcel Stefan Misik diff --git a/doc/app-example/CMakeLists.txt b/doc/app-example/CMakeLists.txt index a7697720c..5f71a5d4f 100644 --- a/doc/app-example/CMakeLists.txt +++ b/doc/app-example/CMakeLists.txt @@ -6,17 +6,18 @@ cmake_minimum_required(VERSION 3.4.2) project(st-hello) set(PROJECT_VERSION 0.1) + set(SRCS main.c) +include_directories(${STLINK_INCLUDE_DIRS}) + find_package(PkgConfig) pkg_check_modules(STLINK REQUIRED stlink) set(CMAKE_C_FLAGS " ${STLINK_CFLAGS_OTHER} -Wall -Werror") -include_directories(${STLINK_INCLUDE_DIRS}) - add_executable(${PROJECT_NAME} ${SRCS}) target_link_libraries(${PROJECT_NAME} ${STLINK_LIBRARIES}) -install(TARGETS ${PROJECT_NAME} DESTINATION bin) +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/doc/app-example/README.md b/doc/app-example/README.md index 683056171..f3a0bf9bb 100644 --- a/doc/app-example/README.md +++ b/doc/app-example/README.md @@ -1,2 +1,2 @@ This is a simple standalone application example that uses libstlink. -You can use this as a boilerplate for your own app development +It can be used as a boilerplate for app development. diff --git a/doc/app-example/main.c b/doc/app-example/main.c index 12621434a..b8e64b259 100644 --- a/doc/app-example/main.c +++ b/doc/app-example/main.c @@ -2,8 +2,7 @@ #include #include -static stlink_t *stlink_open_first(void) -{ +static stlink_t *stlink_open_first(void) { stlink_t* sl = NULL; sl = stlink_v1_open(0, 1); if (sl == NULL) @@ -13,8 +12,7 @@ static stlink_t *stlink_open_first(void) } -int main() -{ +int main() { stlink_t* sl = NULL; sl = stlink_open_first(); @@ -25,5 +23,6 @@ int main() fprintf(stderr, "STlink device opened, that's cool!\n"); stlink_close(sl); + return 0; } diff --git a/doc/devices_boards.md b/doc/devices_boards.md index 00acdd2cf..8291f7532 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -53,7 +53,7 @@ Tested boards [incl. STLink programmers]: | 0x430 | XL-Density | xF XG | | F101 | | F103 | | Tested boards [incl. STLink programmers]: -* 32VL-Discovery (STM32F100RBT6) with STLink-v1 [v1, v2] +* STM32VL-Discovery (STM32F100RBT6) with STLink-v1 [v1, v2] * STM32F103-Bluepill: C8Tx & R8xx [v2] * Nucleo-F103RB [v2-1] * HY-STM32 (STM32F103VETx) [v1, v2] diff --git a/doc/release.md b/doc/release.md index 4b536d95a..b44183b80 100644 --- a/doc/release.md +++ b/doc/release.md @@ -3,7 +3,7 @@ Release This document describes the necessary steps for developers to create a release: -1. Update `CHANGELOG.md` and `cmake/packaging/deb/changelog` +1. Update `CHANGELOG.md` 2. Update `.version` with semantic version: `x.x.x` 3. Update `README.md` with semantic version `x.x.x` in commits badge 4. Create and push git tag and commits `git tag x.x.x` diff --git a/doc/version_support.md b/doc/version_support.md index f889fbc32..4d1f724f7 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -21,6 +21,8 @@ Thus no user interaction regarding libusb is necessary. | homebrew | 1.0.23 | 3.17.0 | 3.24.18
    gtk+3 | 10.12 (Sierra)- 10.15 (Catalina) | | MacPorts | 1.0.23 | 3.17.0 | 3.24.18
    gtk3 | 10.6 (Snow Leopard) - 10.15 (Catalina) | +NOTE: In order to use a STLINK/v1 programmer on macOS, versions 10.13, 10.14 or 10.15 are required. + ### Linux-/Unix-based: diff --git a/run_clang_analyze.sh b/run_clang_analyze.sh index 8d5c5a988..fd1b78b55 100755 --- a/run_clang_analyze.sh +++ b/run_clang_analyze.sh @@ -1,6 +1,7 @@ #!/bin/bash -# Run this hacky script in project root directory to start -# clang static analysis. Adjust ccc-analyzer path if nesesary +# Run this hacky script in project root directory to start clang static analysis. +# Adjust ccc-analyzer path if necessary + CCC_ANALYZER=/usr/share/clang/scan-build-3.5/ccc-analyzer mkdir -p build-clang-analyze/reports cd build-clang-analyze From 252ac0b3cc0690d8d2e26c117ca178f481e9fdb2 Mon Sep 17 00:00:00 2001 From: matthew sherwood Date: Mon, 25 May 2020 15:33:44 -0400 Subject: [PATCH 0942/1435] Update compiling.md neither `make release` nor `make debug` would execute properly on a fresh clone of the directory until i ran `make clean`. system is linux mint - 5.3.0-53-generic #47~18.04.1-Ubuntu SMP Thu May 7 13:10:50 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux --- doc/compiling.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/compiling.md b/doc/compiling.md index e20cbca83..2da79f071 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -110,8 +110,9 @@ or execute (Debian-based systems only): `apt-get install gcc build-essential cma ### Building 1. Change into the project source directory: `cd stlink` -2. Run `make release` to create the _Release_ target -3. Run `make debug` to create the _Debug_ target (_optional_)
    +2. Run `make clean` -- required by some linux variants. +3. Run `make release` to create the _Release_ target +4. Run `make debug` to create the _Debug_ target (_optional_)
    The debug target is only necessary in order to modify the sources and to run under a debugger. The top level Makefile is just a handy wrapper for: From 230497c1a457673be20b18e6e3453a4104075133 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 26 May 2020 13:58:56 +0200 Subject: [PATCH 0943/1435] Updated stlink-v1 driver for macOS - Updated xcode project settings v11.3.1 - Removed support for 10.6-10.12 - Compiled new kexts for macOS 10.13-10.15 - Moved instructions to separate README - Updated installation instructions --- doc/tutorial.md | 65 +- .../Makefile | 25 +- stlinkv1_macos_driver/README.md | 50 ++ stlinkv1_macos_driver/install.sh | 22 + .../Contents/Info.plist | 82 +++ .../Contents/MacOS/stlink_shield_10_13 | Bin 0 -> 33840 bytes .../stlink_shield_10_13.kext/Contents/PkgInfo | 1 + .../Contents/_CodeSignature/CodeResources | 115 ++++ .../Contents/Info.plist | 82 +++ .../Contents/MacOS/stlink_shield_10_14 | Bin 0 -> 33840 bytes .../stlink_shield_10_14.kext/Contents/PkgInfo | 1 + .../Contents/_CodeSignature/CodeResources | 115 ++++ .../Contents/Info.plist | 82 +++ .../Contents/MacOS/stlink_shield_10_15 | Bin 0 -> 33840 bytes .../stlink_shield_10_15.kext/Contents/PkgInfo | 1 + .../Contents/_CodeSignature/CodeResources | 115 ++++ .../stlink_shield_xcode/Info.plist | 60 ++ .../stlink_shield.xcodeproj/project.pbxproj | 613 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + .../UserInterfaceState.xcuserstate | Bin 0 -> 185319 bytes .../WorkspaceSettings.xcsettings | 22 + .../xcschemes/stlink_shield_10.13.xcscheme | 67 ++ .../xcschemes/stlink_shield_10.14.xcscheme | 67 ++ .../xcschemes/stlink_shield_10.15.xcscheme | 67 ++ .../xcschemes/xcschememanagement.plist | 67 ++ stlinkv1_macosx_driver/README.md | 47 -- stlinkv1_macosx_driver/osx.tar.gz | Bin 23580 -> 0 bytes 29 files changed, 1666 insertions(+), 123 deletions(-) rename {stlinkv1_macosx_driver => stlinkv1_macos_driver}/Makefile (74%) create mode 100644 stlinkv1_macos_driver/README.md create mode 100644 stlinkv1_macos_driver/install.sh create mode 100644 stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/Info.plist create mode 100644 stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/MacOS/stlink_shield_10_13 create mode 100644 stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/PkgInfo create mode 100644 stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/_CodeSignature/CodeResources create mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist create mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 create mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/PkgInfo create mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/_CodeSignature/CodeResources create mode 100644 stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/Info.plist create mode 100644 stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/MacOS/stlink_shield_10_15 create mode 100644 stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/PkgInfo create mode 100644 stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/_CodeSignature/CodeResources create mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/Info.plist create mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj create mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/WorkspaceSettings.xcsettings create mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.13.xcscheme create mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.14.xcscheme create mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.15.xcscheme create mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist delete mode 100644 stlinkv1_macosx_driver/README.md delete mode 100644 stlinkv1_macosx_driver/osx.tar.gz diff --git a/doc/tutorial.md b/doc/tutorial.md index 694142184..81315dbef 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -29,70 +29,7 @@ Within the GUI main window tooltips explain the available user elements. ## Solutions to common problems -### a) STLINK/v1 driver: Issue with Kernel Extension (kext) (macOS 10.11 and later only) -#### Problem: - -st-util fails to detect a STLINK/v1 device: - -``` -st-util -1 -st-util $VERSION-STRING$ -WARN src/sg.c: Failed to find an stlink v1 by VID:PID -ERROR src/sg.c: Could not open stlink device -``` - -#### Solution (clean setup): - -1) Configure System Integrity Protection (SIP) - -The root of this problem is a system security setting introduced by Apple with OS X El Capitan (10.11) in 2015. -The so called System Integrity Protection (SIP) is active per default -and prevents the operating system amongst other things to load unsigned Kernel Extension Modules (kext). -Thus the STLINK/v1 driver supplied with the tools, which installs as a kext, remains not functional, -while SIP is fully activated (as is per default). - -Action needs to be taken here by booting into the recovery mode where a terminal console window needs to be opened. - -For macOS 10.11 - 10.13 it is not recommended to disable SIP completely as with the command `csrutil disable`, -because this leaves the system more vulnerable to common threats. -Instead there is a more adequate and reasonable option implemented by Apple. -Running `csrutil enable --without kext`, allows to load unsigned kernel extensions -while leaving SIP active with all other security features. -Unfortunately this option has been removed in macOS 10.14, which leaves the only option to disable SIP completely. - -So who ever intends to run the STLINK/v1 programmer on macOS please take this into account. - -Further details can be found here: https://forums.developer.apple.com/thread/17452 - -2) Install the ST-Link-v1 driver from the subdirectory `/stlinkv1_macosx_driver` - by referring to the instructions in the README file available there. - -3) Move the $OS_VERSION$.kext file to `/System/Library/Extensions`. - -4) Load the Kernel Extension (kext): `$ sudo kextload -v /System/Library/Extensions/stlink_shield10_x.kext` - -``` -Requesting load of /System/Library/Extensions/stlink_shield10_x.kext. -/System/Library/Extensions/stlink_shield10_x.kext loaded successfully (or already loaded). -``` - -5) Enter the command `$ sudo touch /System/Library/Extensions` - - -7) Verify correct detection of the STLINK/v1 device with the following input: `st-util -1` - -You should then see a similar output like in this example: - -``` -INFO common.c: Loading device parameters.... -INFO common.c: Device connected is: F1 High-density device, id 0x10036414 -INFO common.c: SRAM size: 0x10000 bytes (64 KiB), Flash: 0x80000 bytes (512 KiB) in pages of 2048 bytes -INFO sg.c: Successfully opened a stlink v1 debugger -INFO gdb-server.c: Chip ID is 00000414, Core ID is 1ba01477. -INFO gdb-server.c: Listening at *:4242... -``` - -### b) Verify if udev rules are set correctly (by Dave Hylands) +### a) Verify if udev rules are set correctly (by Dave Hylands) To investigate, start by plugging your STLINK device into the usb port. Then run `lsusb`. You should see an entry something like the following: diff --git a/stlinkv1_macosx_driver/Makefile b/stlinkv1_macos_driver/Makefile similarity index 74% rename from stlinkv1_macosx_driver/Makefile rename to stlinkv1_macos_driver/Makefile index 9947ff672..e6ba6309b 100644 --- a/stlinkv1_macosx_driver/Makefile +++ b/stlinkv1_macos_driver/Makefile @@ -1,15 +1,17 @@ -# make ... for both stlink v1 and stlink v2 support -## +### +# Makefile for STlink-v1 support +### + VPATH=src -SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c uglylogging.c +SOURCES_LIB=common.c usb.c sg.c logging.c OBJS_LIB=$(SOURCES_LIB:.c=.o) -TEST_PROGRAMS=test_usb test_sg +TEST_PROGRAMS=test-flash test-sg test-usb LDFLAGS=-L. -lstlink -lusb-1.0 CFLAGS+=-g CFLAGS+=-DDEBUG=1 -CFLAGS+=-std=gnu99 +CFLAGS+=-std=gnu11 CFLAGS+=-Wall -Wextra @@ -20,8 +22,8 @@ all: $(LIBRARY) flash gdbserver $(TEST_PROGRAMS) $(LIBRARY): $(OBJS_LIB) @echo "objs are $(OBJS_LIB)" $(AR) -cr $@ $^ - @echo "done making library" - + @echo "Compilation of library completed." + test_sg: test_sg.o $(LIBRARY) @echo "building test_sg" @@ -40,18 +42,17 @@ test_usb: test_usb.o $(LIBRARY) clean: rm -rf $(OBJS_LIB) rm -rf $(LIBRARY) - rm -rf test_usb* - rm -rf test_sg* + rm -rf test-flash* test-sg* test-usb* $(MAKE) -C flash clean $(MAKE) -C gdbserver clean - + flash: $(MAKE) -C flash gdbserver: $(MAKE) -C gdbserver CONFIG_USE_LIBSG="$(CONFIG_USE_LIBSG)" -osx_stlink_shield: - ./osx/install.sh +macos_stlink_shield: + ./install.sh .PHONY: clean all flash gdbserver diff --git a/stlinkv1_macos_driver/README.md b/stlinkv1_macos_driver/README.md new file mode 100644 index 000000000..ca4a3da30 --- /dev/null +++ b/stlinkv1_macos_driver/README.md @@ -0,0 +1,50 @@ +### +# Installation instructions for STLINK/v1 driver +### + +When connecting to the STLINK/v1 on macOS via USB, the system claims the programmer as a SCSI device. Thus libusb is not able to initialise and establish a connection to it. To solve this issue Marco Cassinerio (marco.cassinerio@gmail.com) has created a so called "codeless driver" which claims the device. It is of higher priority then the default apple mass storage driver, what allows the device to be accessed through libusb. + +To make use of this alternative approach one needs to go through the following steps: + +1) Install the macOS Kernel Extension (kext): + - Open a terminal console and navigate to this subdirectory `/stlinkv1_macos_driver` + - Use the command ```sudo sh ./install.sh``` to install the appropiate kext for your system version. + +2) Install the ST-Link-v1 driver from this subdirectory `/stlinkv1_macos_driver` by executing: ```sudo make osx_stlink_shield```. This should result in the following output: + +``` +Requesting load of /System/Library/Extensions/stlink_shield.kext. +/System/Library/Extensions/stlink_shield.kext loaded successfully (or already loaded). +``` + +3) Configure System Integrity Protection (SIP) + +The above system security setting introduced by Apple with OS X El Capitan (10.11) in 2015 is active per default +and prevents the operating system amongst other things to load unsigned Kernel Extension Modules (kext). +Thus the STLINK/v1 driver supplied with the tools, which installs as a kext, remains not functional, +until SIP is fully deactivated. + +Without SIP-deactivation, st-util fails to detect a STLINK/v1 device: + +``` +st-util -1 +st-util $VERSION-STRING$ +WARN src/sg.c: Failed to find an stlink v1 by VID:PID +ERROR src/sg.c: Could not open stlink device +``` + +In order to deactivate SIP, boot into the recovery mode and run ```csrutil disable``` in a terminal console window. + +4) Reboot the system. + +5) Verify correct detection of the STLINK/v1 device with the following input: `st-util -1` +You should then see a similar output like in this example: + +``` +INFO common.c: Loading device parameters.... +INFO common.c: Device connected is: F1 High-density device, id 0x10036414 +INFO common.c: SRAM size: 0x10000 bytes (64 KiB), Flash: 0x80000 bytes (512 KiB) in pages of 2048 bytes +INFO sg.c: Successfully opened a stlink v1 debugger +INFO gdb-server.c: Chip ID is 00000414, Core ID is 1ba01477. +INFO gdb-server.c: Listening at *:4242... +``` diff --git a/stlinkv1_macos_driver/install.sh b/stlinkv1_macos_driver/install.sh new file mode 100644 index 000000000..9e5f8d813 --- /dev/null +++ b/stlinkv1_macos_driver/install.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +ISMACOS=$(sw_vers -productVersion) +case $ISMACOS in +10.13*) + KEXT="stlink_shield_10_13.kext" + ;; +10.14*) + KEXT="stlink_shield_10_14.kext" + ;; +10.15*) + KEXT="stlink_shield_10_15.kext" + ;; +*) + echo "OS X version not supported." + exit 1 + ;; +esac +chown -R root:wheel $KEXT/ +cp -R $KEXT /System/Library/Extensions/stlink_shield.kext +kextload -v /System/Library/Extensions/stlink_shield.kext +touch /System/Library/Extensions diff --git a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/Info.plist b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/Info.plist new file mode 100644 index 000000000..fc759b362 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/Info.plist @@ -0,0 +1,82 @@ + + + + + BuildMachineOSBuild + 18G4032 + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.libusb.stlink-shield + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + KEXT + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1.0.0 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 11C504 + DTPlatformVersion + GM + DTSDKBuild + 19B90 + DTSDKName + macosx10.15 + DTXcode + 1130 + DTXcodeBuild + 11C504 + IOKitPersonalities + + DeviceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBDevice + bcdDevice + 256 + idProduct + 14148 + idVendor + 1155 + + InterfaceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 14148 + idVendor + 1155 + + + LSMinimumSystemVersion + 10.13 + OSBundleLibraries + + com.apple.iokit.IOUSBFamily + 1.8 + com.apple.kpi.libkern + 11.2.0 + + + diff --git a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/MacOS/stlink_shield_10_13 b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/MacOS/stlink_shield_10_13 new file mode 100644 index 0000000000000000000000000000000000000000..161c0a829359293dc1189621a2d41dbdc31ab5ad GIT binary patch literal 33840 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 literal 0 HcmV?d00001 diff --git a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/PkgInfo b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/PkgInfo new file mode 100644 index 000000000..bdab95bcc --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/PkgInfo @@ -0,0 +1 @@ +KEXT???? \ No newline at end of file diff --git a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/_CodeSignature/CodeResources b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/_CodeSignature/CodeResources new file mode 100644 index 000000000..d5d0fd744 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/_CodeSignature/CodeResources @@ -0,0 +1,115 @@ + + + + + files + + files2 + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist new file mode 100644 index 000000000..d43deca2b --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist @@ -0,0 +1,82 @@ + + + + + BuildMachineOSBuild + 18G4032 + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.libusb.stlink-shield + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + KEXT + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1.0.0 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 11C504 + DTPlatformVersion + GM + DTSDKBuild + 19B90 + DTSDKName + macosx10.15 + DTXcode + 1130 + DTXcodeBuild + 11C504 + IOKitPersonalities + + DeviceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBDevice + bcdDevice + 256 + idProduct + 14148 + idVendor + 1155 + + InterfaceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 14148 + idVendor + 1155 + + + LSMinimumSystemVersion + 10.14 + OSBundleLibraries + + com.apple.iokit.IOUSBFamily + 1.8 + com.apple.kpi.libkern + 11.2.0 + + + diff --git a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 new file mode 100644 index 0000000000000000000000000000000000000000..a49757ef1fc67fcaeb819c141550efa3f275928a GIT binary patch literal 33840 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 + + + + files + + files2 + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/Info.plist b/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/Info.plist new file mode 100644 index 000000000..a2a5f8ac2 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/Info.plist @@ -0,0 +1,82 @@ + + + + + BuildMachineOSBuild + 18G4032 + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.libusb.stlink-shield + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + KEXT + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1.0.0 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 11C504 + DTPlatformVersion + GM + DTSDKBuild + 19B90 + DTSDKName + macosx10.15 + DTXcode + 1130 + DTXcodeBuild + 11C504 + IOKitPersonalities + + DeviceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBDevice + bcdDevice + 256 + idProduct + 14148 + idVendor + 1155 + + InterfaceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 14148 + idVendor + 1155 + + + LSMinimumSystemVersion + 10.15 + OSBundleLibraries + + com.apple.iokit.IOUSBFamily + 1.8 + com.apple.kpi.libkern + 11.2.0 + + + diff --git a/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/MacOS/stlink_shield_10_15 b/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/MacOS/stlink_shield_10_15 new file mode 100644 index 0000000000000000000000000000000000000000..4e64961ae1a6cb922efe525978510783165de57f GIT binary patch literal 33840 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 + + + + files + + files2 + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/Info.plist b/stlinkv1_macos_driver/stlink_shield_xcode/Info.plist new file mode 100644 index 000000000..b0a0228d8 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/Info.plist @@ -0,0 +1,60 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + KEXT + CFBundleSignature + ???? + CFBundleVersion + 1.0.0 + IOKitPersonalities + + DeviceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBDevice + bcdDevice + 256 + idProduct + 14148 + idVendor + 1155 + + InterfaceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 14148 + idVendor + 1155 + + + OSBundleLibraries + + com.apple.iokit.IOUSBFamily + 1.8 + com.apple.kpi.libkern + 11.2.0 + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj new file mode 100644 index 000000000..23dc192d8 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj @@ -0,0 +1,613 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 52; + objects = { + +/* Begin PBXFileReference section */ + 8CD33C31149BB80D0033D618 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8F9084F124786F0B009109AD /* stlink_shield_10_13.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = stlink_shield_10_13.kext; sourceTree = BUILT_PRODUCTS_DIR; }; + 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = stlink_shield_10_14.kext; sourceTree = BUILT_PRODUCTS_DIR; }; + 8F90850924786F39009109AD /* stlink_shield_10_15.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = stlink_shield_10_15.kext; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXGroup section */ + 089C166AFE841209C02AAC07 /* NanosMouse */ = { + isa = PBXGroup; + children = ( + 089C167CFE841241C02AAC07 /* Resources */, + 19C28FB6FE9D52B211CA2CBB /* Products */, + ); + name = NanosMouse; + sourceTree = ""; + usesTabs = 0; + }; + 089C167CFE841241C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 8CD33C31149BB80D0033D618 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 19C28FB6FE9D52B211CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8F9084F124786F0B009109AD /* stlink_shield_10_13.kext */, + 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */, + 8F90850924786F39009109AD /* stlink_shield_10_15.kext */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8F9084E924786F0B009109AD /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8F9084F524786F0F009109AD /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8F90850124786F39009109AD /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 8F9084E724786F0B009109AD /* stlink_shield_10_13 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8F9084EE24786F0B009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_13" */; + buildPhases = ( + 8F9084E824786F0B009109AD /* ShellScript */, + 8F9084E924786F0B009109AD /* Headers */, + 8F9084EA24786F0B009109AD /* Resources */, + 8F9084EC24786F0B009109AD /* Sources */, + 8F9084ED24786F0B009109AD /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = stlink_shield_10_13; + productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; + productName = NanosMouse; + productReference = 8F9084F124786F0B009109AD /* stlink_shield_10_13.kext */; + productType = "com.apple.product-type.kernel-extension.iokit"; + }; + 8F9084F324786F0F009109AD /* stlink_shield_10_14 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8F9084FA24786F0F009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_14" */; + buildPhases = ( + 8F9084F424786F0F009109AD /* ShellScript */, + 8F9084F524786F0F009109AD /* Headers */, + 8F9084F624786F0F009109AD /* Resources */, + 8F9084F824786F0F009109AD /* Sources */, + 8F9084F924786F0F009109AD /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = stlink_shield_10_14; + productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; + productName = NanosMouse; + productReference = 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */; + productType = "com.apple.product-type.kernel-extension.iokit"; + }; + 8F9084FF24786F39009109AD /* stlink_shield_10_15 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8F90850624786F39009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_15" */; + buildPhases = ( + 8F90850024786F39009109AD /* ShellScript */, + 8F90850124786F39009109AD /* Headers */, + 8F90850224786F39009109AD /* Resources */, + 8F90850424786F39009109AD /* Sources */, + 8F90850524786F39009109AD /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = stlink_shield_10_15; + productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; + productName = NanosMouse; + productReference = 8F90850924786F39009109AD /* stlink_shield_10_15.kext */; + productType = "com.apple.product-type.kernel-extension.iokit"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 089C1669FE841209C02AAC07 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1130; + ORGANIZATIONNAME = "stlink-org"; + }; + buildConfigurationList = 3EEA308708D71E4B002CBB49 /* Build configuration list for PBXProject "stlink_shield" */; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; + hasScannedForEncodings = 1; + knownRegions = ( + en, + ); + mainGroup = 089C166AFE841209C02AAC07 /* NanosMouse */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8F9084E724786F0B009109AD /* stlink_shield_10_13 */, + 8F9084F324786F0F009109AD /* stlink_shield_10_14 */, + 8F9084FF24786F39009109AD /* stlink_shield_10_15 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8F9084EA24786F0B009109AD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8F9084F624786F0F009109AD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8F90850224786F39009109AD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 8F9084E824786F0B009109AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPreprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi\n"; + }; + 8F9084ED24786F0B009109AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPostprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi\n"; + }; + 8F9084F424786F0F009109AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPreprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; + }; + 8F9084F924786F0F009109AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPostprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; + }; + 8F90850024786F39009109AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPreprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; + }; + 8F90850524786F39009109AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPostprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8F9084EC24786F0B009109AD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8F9084F824786F0F009109AD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8F90850424786F39009109AD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 3EEA308808D71E4B002CBB49 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + APPLICATION_EXTENSION_API_ONLY = YES; + APPLY_RULES_IN_COPY_FILES = YES; + APPLY_RULES_IN_COPY_HEADERS = YES; + CLANG_ADDRESS_SANITIZER_CONTAINER_OVERFLOW = YES; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; + CLANG_ANALYZER_GCD_PERFORMANCE = YES; + CLANG_ANALYZER_LOCALIZABILITY_EMPTY_CONTEXT = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES; + CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_STATIC_ANALYZER_MODE = deep; + CLANG_UNDEFINED_BEHAVIOR_SANITIZER_INTEGER = YES; + CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES; + CLANG_WARN_ASSIGN_ENUM = YES; + CLANG_WARN_ATOMIC_IMPLICIT_SEQ_CST = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_CXX0X_EXTENSIONS = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_FLOAT_CONVERSION = YES; + CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES; + CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_INTERFACE_IVARS = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES; + CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + COPY_HEADERS_RUN_UNIFDEF = YES; + CREATE_INFOPLIST_SECTION_IN_BINARY = YES; + DEAD_CODE_STRIPPING = YES; + DEFINES_MODULE = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DONT_GENERATE_INFOPLIST_FILE = NO; + DRIVERKIT_DEPLOYMENT_TARGET = 19.0; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_PREVIEWS = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_CHAR_IS_UNSIGNED_CHAR = YES; + GCC_ENABLE_FLOATING_POINT_LIBRARY_CALLS = YES; + GCC_ENABLE_KERNEL_DEVELOPMENT = YES; + GCC_ENABLE_TRIGRAPHS = YES; + GCC_FAST_MATH = YES; + GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES; + GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_SHORT_ENUMS = YES; + GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; + GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_UNROLL_LOOPS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_STRICT_SELECTOR_MATCH = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_MASTER_OBJECT_FILE = YES; + GENERATE_PKGINFO_FILE = YES; + GENERATE_PROFILING_CODE = YES; + GENERATE_TEXT_BASED_STUBS = YES; + INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; + INFOPLIST_OUTPUT_FORMAT = XML; + INFOPLIST_PREPROCESS = YES; + INLINE_PRIVATE_FRAMEWORKS = YES; + KEEP_PRIVATE_EXTERNS = YES; + LD_GENERATE_MAP_FILE = YES; + LINKER_DISPLAYS_MANGLED_NAMES = YES; + MODULE_NAME = com.libusb.stlink_shield; + MODULE_VERSION = 1.0; + PLIST_FILE_OUTPUT_FORMAT = XML; + PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.libusb.stlink-shield"; + RUN_CLANG_STATIC_ANALYZER = YES; + SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; + SEPARATE_SYMBOL_EDIT = YES; + SUPPORTS_TEXT_BASED_API = YES; + TAPI_VERIFY_MODE = Pedantic; + VALIDATE_PRODUCT = YES; + VALIDATE_WORKSPACE = YES; + VERSIONING_SYSTEM = "apple-generic"; + WRAPPER_EXTENSION = kext; + }; + name = Debug; + }; + 3EEA308908D71E4B002CBB49 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + APPLICATION_EXTENSION_API_ONLY = YES; + APPLY_RULES_IN_COPY_FILES = YES; + APPLY_RULES_IN_COPY_HEADERS = YES; + CLANG_ADDRESS_SANITIZER_CONTAINER_OVERFLOW = YES; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; + CLANG_ANALYZER_GCD_PERFORMANCE = YES; + CLANG_ANALYZER_LOCALIZABILITY_EMPTY_CONTEXT = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES; + CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_STATIC_ANALYZER_MODE = deep; + CLANG_UNDEFINED_BEHAVIOR_SANITIZER_INTEGER = YES; + CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES; + CLANG_WARN_ASSIGN_ENUM = YES; + CLANG_WARN_ATOMIC_IMPLICIT_SEQ_CST = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_CXX0X_EXTENSIONS = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_FLOAT_CONVERSION = YES; + CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES; + CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_INTERFACE_IVARS = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES; + CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + COPY_HEADERS_RUN_UNIFDEF = YES; + CREATE_INFOPLIST_SECTION_IN_BINARY = YES; + DEAD_CODE_STRIPPING = YES; + DEFINES_MODULE = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DONT_GENERATE_INFOPLIST_FILE = NO; + DRIVERKIT_DEPLOYMENT_TARGET = 19.0; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_PREVIEWS = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_CHAR_IS_UNSIGNED_CHAR = YES; + GCC_ENABLE_FLOATING_POINT_LIBRARY_CALLS = YES; + GCC_ENABLE_KERNEL_DEVELOPMENT = YES; + GCC_ENABLE_TRIGRAPHS = YES; + GCC_FAST_MATH = YES; + GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES; + GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_SHORT_ENUMS = YES; + GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; + GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_UNROLL_LOOPS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_STRICT_SELECTOR_MATCH = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_MASTER_OBJECT_FILE = YES; + GENERATE_PKGINFO_FILE = YES; + GENERATE_PROFILING_CODE = YES; + GENERATE_TEXT_BASED_STUBS = YES; + INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; + INFOPLIST_OUTPUT_FORMAT = XML; + INFOPLIST_PREPROCESS = YES; + INLINE_PRIVATE_FRAMEWORKS = YES; + KEEP_PRIVATE_EXTERNS = YES; + LD_GENERATE_MAP_FILE = YES; + LINKER_DISPLAYS_MANGLED_NAMES = YES; + MODULE_NAME = com.libusb.stlink_shield; + MODULE_VERSION = 1.0; + PLIST_FILE_OUTPUT_FORMAT = XML; + PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.libusb.stlink-shield"; + RUN_CLANG_STATIC_ANALYZER = YES; + SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; + SEPARATE_SYMBOL_EDIT = YES; + SUPPORTS_TEXT_BASED_API = YES; + TAPI_VERIFY_MODE = Pedantic; + VALIDATE_PRODUCT = YES; + VALIDATE_WORKSPACE = YES; + VERSIONING_SYSTEM = "apple-generic"; + WRAPPER_EXTENSION = kext; + }; + name = Release; + }; + 8F9084EF24786F0B009109AD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 8F9084F024786F0B009109AD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 8F9084FB24786F0F009109AD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + MACOSX_DEPLOYMENT_TARGET = 10.14; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 8F9084FC24786F0F009109AD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + MACOSX_DEPLOYMENT_TARGET = 10.14; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 8F90850724786F39009109AD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 8F90850824786F39009109AD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3EEA308708D71E4B002CBB49 /* Build configuration list for PBXProject "stlink_shield" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3EEA308808D71E4B002CBB49 /* Debug */, + 3EEA308908D71E4B002CBB49 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8F9084EE24786F0B009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_13" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8F9084EF24786F0B009109AD /* Debug */, + 8F9084F024786F0B009109AD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8F9084FA24786F0F009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_14" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8F9084FB24786F0F009109AD /* Debug */, + 8F9084FC24786F0F009109AD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8F90850624786F39009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_15" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8F90850724786F39009109AD /* Debug */, + 8F90850824786F39009109AD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 089C1669FE841209C02AAC07 /* Project object */; +} diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..f9b0d7c5e --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/UserInterfaceState.xcuserstate b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..b06818d2f7b3b1cd51b2e0589a4382c7af8c7b30 GIT binary patch literal 185319 zcmeEv2Y3@l)9~%8oKBKuHB@X#Rxu?MW78o(kZlm4&LxN�S327Hl5@)y@&Lk zP?L~^^g?>?9g>jVd+)vcvv)cbH%Rh+-}AlC^QYLdZf16NW_EUVc5ZiZS6geMySVrT z1~HhCF>*%1C<}`U$IdTY8H*=cJ3HnVb}n8XYwk`o7B#lRDo*IJQPA<6hU>U5w)V_Xa#CR?WhBF;+yd< zd>6hKKY$;`kKrfrGx&M@0^W;X#c$xZ@q73~{0aUXe}%urKj5G7Z}?9clF4PPOfAci z>18IFMP`>dWCb#>Y^ZF6Y?Q1>RwA1qn=G3qn<1MeE0a~og0f0kjVvUqlg*bclr54q z$y#JfWy@vlvMyOdwo?ql>vJ+${%TAM>Av;@kp6o)|C9+Mjt+LByJ7m|$ zu9Mv;yG6E3cBkwf+5NJIWRJ?8kUcGXPPRw(lI#`P>$10G@5(-qeJuM-_ND9_+4r)a zWWUP(kTY_bTq)<|T6wPAC?6uX$@Aqdxkp|oA1)s$A0sc8kC#u9PnA!XA0#i82jp|) zbLG|YdGd(7LB2qKsQfT_vwVrXRo*7=l*i>g^40Qn@+0I#evJHh`APCqXOtX2mwe6^g4AI~CU}Zc^N;xLt9V;$FoAiiZ`CDV|h3 zqj+BNf?}`YRmB^Mw-xUxK2&_7_+0Uo;#)yf>DUTIQVly;>< zS)lYPhbl)XM=6VxCCUlP$;xTU8OmA8GG&D_sH{}hC_~CR<$UEr{2F_E0t@M>y<|;k7lk`9;ZB6dAf3=@(krU$_td+m6t28P+qCrp}a+TtMWGGF6HgY zyOa+oA5=cBd_wuG@)hN)%GZ=1C_hwwr2Inpo$?RmpUS^jj#aZ7b_i=>t?U@Kh#kuo zvnA{}c04>1!OmvqutBzltz{!@9b3;H!XCyhVVAS(*$wOw?2#s%q&i!5f$CD#WvZ>JZK`WkH>q~1Zdcu-x>xnM z>KWA@)eEXuRj;W&P<^WUO7*qsN7YXp;*^|*({e`6#F;ra=i$7Zk1OPca-+D>+!Ssq zH;p@xo6gPPW^xB}^SC;$o@?M1a_w9P*U5EphjVdmHMfR4lH<9PxRbe4xKp{axC^+; zxUJlE-1XcI+-=-0?k?_b?m_M$?g{Qm?kVnR?ip@3_Y(Ix_XYPQ_Z9aw_YLWS*9>S^kk>Vwo}>T>lQbx>WUu2zTCVReIg zzWNaLq3R~}V)YXBQuPM)5$Yq=yqc(wQXj28Mt!XMIQ2;?PJM>@O!bB8i_{mZFHvt- zU#`AFeYg4^^}Xu*)c30&P(P@CNd2(-5%m-5=T#-@-ReE+*VM18-%!7){!smq`VaM= z>c2FM25GQHrjctD8l^_9YS9=pc1@lpU*pphYNlxp)J)gR(9F~vq?x7hYf3d`n%SCa zO}(Z;GhcI=YfsUhtvyG3we}kAPVKeY>$KNvZ_wVTy-9ns zc9-^E?S0zEw2!O4)jpx!t=*&jMEj}sGwtWvFSK83ztVoK{YLw(_DAg>If@)*4x5vk zqt6+ZGdyQR&H*_ib4KNi&KZ+alruJGe9p9-(wwrK@|?a$d^WoAYwcD>-lGyp{8I&c`{Q<$RU%ea;U#zvldz^Op|mWV#%kPM53G z>kPUfI-Aa`^XUq8Lvbf@b!>dw$zpu1SNNw-;dx$X+x)w=6-cj)fX-K)D# z_pt6U-BY@kbg$`N*S(>8Q}?0n6WtfOZ*<@4e$xG}`y-dlRpn}Pb93#vuH1s$;khGo zi*m>3PR^a4J14g?w<>pDZYZ}tw;{JVwYQs9i5e8y7#&EphB*UqOjfS%f=Nc|BTx__^u*I<5aHZjD z!?lJR3^yBYGu&ag+i;)ZLBk`4#|=*zo;B zN5e0M-wl5mu~A`E88t?o(O@(it;Rf~)95z(jKhov7)Kk&8pjzY8mAZ!G|n{ojpfGK z#)FMj##&?8SZ{1J9%76d7aL>7WyTf84&&j*ZsRKBTH^*IZ#>#~obg2CDaO-{XBy8j zo^QO!c&Tx-ahvf9<5k9;#_NqY8E-Y-ZoJEQukiun!^X#qPa2;wK5u-%xYziq@eSkK z#`laL8b2|9Zv4vlt?>ur&&J=3f0~d}!n&}MF*{1VM7n&|HZ8B{&U2fW8y2f;!=|6cEDe?gmP0Lv zS(+_NEUlI{OQ$7n>9MS~tg{?pA(mq-$6HRaoNC!dcCj~V|m~5k>yj%7nZLr-&uaN z{9^gt@|P7`6;_p1W7Sy=R7by^&IQ@ z){Cr{S~pv_S+B5OW!-7L-g=YuR_pE7yR7$GAFw`bea!l#^%?8)))%aMt*=_&u)b}5 z&-$VD6YJ;JudLr%f3W^+{muHP4cX*2)~2@Q*z`7&&0@3L9JT_R*EZBP!ZylQWGk^v zuuZm2v(2#0vX$8?Y(ZP4t;QCz)!F9T7TOlsnrtn$rMBg^c3YP%VOwciV_R=K(sq>X zSlbDY}eUtwB2IcWxLaMkL`ZjL$*h4PuQNe zJ!jivd&%~S?RDE*ws&nG*gm#>X8Y3ijqQ8ePqtref7ltj%&xR^cC9_vZnO`v+wA#v zm)&D8v=6tBw2!eD+sE4{*{9m4+Yhpr+5`4E_PO?I`#gKZ-e6x~Kh%Dhz1hCR-fC~N zciQ9j9{XzhI{OiJVn4=yy!|BmsrHTbv+U>EFR)*1zs$bHzTJMM{c8KQ_8aUs+i$bq zVZYmcpZ!7mBlgGbPuZWf@3y~af7$+;{Z0Ej_V?`{**~>^VgK6xo&87qul7IkxIA^9 zCQqA}lc&qe%`@fM^6Yted4+jH^M>UO&l{C@VBYk+8F@4F4$7OA=g$k|&B;F{|MdJb z^UujYKmVfqOY=A9Z_B?T|Em0*`Pb*)lz(gf?fG}*-<$tH{=@l?MM&{I~Pp%l|O{ll;%~zsmnM|A+ja^MA|#(}5gv2kTHfavXYx$zgHW9S%oowGHIC~XH#%-{>~h@cxW{q7 z;~~eRjwc*XJDzjwalGVs#qql1Eyuf#4;&vmK68BO_{QohutIBm{+r_1Sa7CMJJM>@wii=E@0lblnX)13!7OPvAd9OqnTwR4^`;%sm(a31PB z%-QT*;%s%cIXj(kXODBWbDi@DCvhI*Jl=Vd^Hk?X=UL8kofkMSc3$S(;@s}M(s{M> zTIUVUo1M2g?{MDjywCZd^AYFc&ZnHuI(Iu?biV9-&H1MD9q0SbkDQ-6zi@u-{LcBK z^B3pu&c9sPrEsZS8kf#xaG70JSDwr1a=U!4VXgyQqg`WN<6IM6Q(OnSX1e^Ya@TCv z!LBM-tt;%RcQv{WaYbE=T`|`(*9upM>u^`MYn5xQYlDk-9ql^Kb)xGO*Xgb^UFW#Y zcU|PV)V0~Q&2@$AD%Vce^{$&-x4Le3-Q~L1^?>VP*JG|HUC+3lcfH`+>w4AohU;zD zd#(>%pSV7EedYSr^@HnY*Ke*r3s8Z)fGtoLW$p@h z&|T@SafjS>?)mP8?nUkkKLcSzjS}&{@(qQ`&aiL9>yc{C_S7<>&f*PJwrS;Prk?H@puY7!#yKCV?4#4 z@t#SZsh;VcgFL04fM}~Nb^R{~1y&c}TH{o67UF}`(-QXqOqrAs?kN2MJJ;l4xdxrNM z@44O!y%%{md$)M6^zQIp=e^#0tM@MN-QEYik9(i+KIeVO`?~jC?|a@)ykB{L@c!mQ zKGv7xGx_Yk0^d;IC|`+hvTug3%op?>?3?Rr@-6l?`&xW4-xA+a-!fmTZ@F)Uug%x) z>+p5@x_oPW>wN2d8+^z5PWNr}o#8vvcb4yL-#Na^e4BimeOr9j_;&iP^{Be@qO<5vk(_53)O|1!rVfAp}BBKp}jD# z&{bGa=qoHN98q{c;h4I@j-Ix*Jq*XF84aUlav5Vob+~9nY)xVT{7z=j>I<9Oni7dE zOb(;tF)!P~=oteqC-`iBR8(JBGHH^3Vo62$n3AdE#*djWb<&hEQzunS95ZoTi9Y}z zrcN4H8r7SF<$;FI_=-eVQ**4mv$>}|*3m7sY++o?uqzlVV`J=09+S^F7$>jbl|0L< zc#c=|nk$$B#?5#bF8~!X9$riE8GI4JX9Cy(d=Xy~)z8dqA=0$Cth1v#-r3d`i$}|V zs|gd!#*HcQ`^(2n@Rv>*Go^U)#4(eKr%Vh~Oe&vTQBtyqqPKRmbgrt1H?_y2`eCUr zfLLi$yrC&k-Y`6e~jwg;aD5=Kh}~~fY3~^qb0VwwyAp= zRSs2#_#A{r|B!eUMe8n)EolNCYia&F(G8<36zht|67Zp^8xrD)MG|{0fBE^HGKZ%-Su?YGw^z$dBfWB?9Xio-uA^HZVspNAg4YVf^r|3<0$t z&5r;TkK{)k3gm(c)w8R>rTVjtn->hS58T!v| z<`m{s<}~K?1)?YH0RJ#w{1{6dQXMXDg(2P90S2)Jpf=904%Y~K4-$)KGUxVT@jS50 z3-~c$c4Mg*%@w36+8&jp$~Wtf`!X88jM=oPI$YJ$O&y9q9&cK+mAQ=B%xnaIE&M6+ zxRu!knn?ks8QaQirL0Bu#-zL0pD*Q^sJ?zlYg=sE*s)`&H%g3M**>NRK8yv&y#jW{#-90v| z8`0HNaM|A#3Ey?aJC}=$y~?}>W(Pw_(t)JEEzIk*Z~Z+IG2dj~5+~3st)yj@?TxlD zZ&Pw~!rd=;QHk#|Yd16R@qx6@_>lRO4#}XDjm=DE13J2zor2AGMI$ z#@yD9mbtMtS)SS?`i42+VLRh%z!x^J0AH9Zfk(y1V!Pkdc7NdK^2NKEpFvN*Fu%ea z-rN(9gEPvaL(%z4g6?>k`JMTL`IGqzQrHYa2qPJiBLz|-7Cv!E4dyPXIZFc7LdfEw zN~V!UWKCDBDA7&rEL(!WE0_g@BPo{^)#rBzQ+#qn^oBQNJ*Dkr8X90r`~+6Rq(iq} z(}RPcU3?v1&sPz2JN+Cc=(dcZkF+R<4t=EOLwvO`Qs)VxLq-^P$i&yA#vQWIamUy8 z9cKLx2GQ*IAU6oo!|X*q=0zIWE^bQ1z%doYV{PDHR>pXSkMMrM6wxp=yskP7gJ%mG zMy<@++}U2#)CE(%XzoSS-eHzbIx{p9jb)76&?qz-jX_0x13#Z{yA`xwFdjIR|bh`O(h$5ys>_9U{tETfS&L|TKuN1EbGV@dlN1Y8O!dJjpU z-XAwnvBlD!*0z>#th*a5Cn53)Cijn?iJF{FH93P{#Ls*I%>q{i4h#8FDf1#KZ%hbL z4_FL;7$4>R1l{8EKQQy+FPe6jNIX^jwn>U|ktQX9eyo(1L1fXcQ2 zkxHgyB`VY%WDpVM)Wxj5&VWkM;V6z0s2la5m1q@Ojn<&GXdPOQHlQQWk%&hG9fgiY z$Dm`;ap-t-0y+_$gic1Mpi|Ll=ybFZoq^6oXQ8vvIp|z;9y%XgfG$KAp^MQa=u&hU z+JrWvEodv+hPI>2(G}=Qv;$p*u143Oo#rY4i+w7CncaN4wD;^a6Sjy@d9n zm(eTeRrDHq9le3xL~o(D(L3l}^d5R2eSkhhAEA%YC+Ji38TuT3fxbjvp|8<5=v(w1 z`X2p&endZ^pV2SqSM(eD9sPm+M1NrhBaE>O%drA0F^g50!)mO-TAYJ*I2Y@&0UNOi zoAD5A!B%X;cASUvu>(7?3m0HF_Fyme;X*tV55vRp2z&q@iAUklcnmJWV{tJq!Q=3F zJONL{lkj9b1y9A(@PT+bo`GlLgYYcu$ECOom*W7gz_alj9K;9XxwsNn;c8riYw-g*W8~7XfoA{ggTlib~+xT7l z?ff15o%~(=-TXcLz5IRr{rm&`gZxAM!~7%sqx@t1JiT|1Zh5wcRjsKnhga4ENiy(#|7>Jl489{P_6a*;= zVhK_a#1W(>NJEg8pd5m91mzN>C&)mMksuR6W`c$gWFg2(kc}WaL3sq_6XYPsNsx=6 z0)pHGc?j|n~37SFBOo9#~Xcj>*ag-8NMo>9H0fH(BnoZCgf`SAcOwe3{ zAhLo8q?(`_f@%qxM^K0$h(#g<)e%%rPy<2p32G#00YM81I)osYxEB!=CFn4Mnh07< zP%}X-1jPtiLeNrzmJ!rS&~k!S5Y$FcJ3-*!I|=F{=x~DK1SJUSCa8y?l?1IKXf;7= z2wF?fI)c^{w1J=_2s)A=o*)8_kf5UpI)Y5N4(pp|GTaU}7tLeW$QC7XOx7 zxQEgm(uZ!SYz|NpnYf>VSbKv&d!d?|hy?Ty1#Tp{M=7+g zH*~nJwzeh|36w``EB%p*now1WhbJgPes6?&e`T;-Ae;hxngR|-{zM|yO$8JV2O`m0 zf7#q>?_ z66T&{N0QA2s{N&vfoM&2v^)Uql}AH?a7|sPERf>wC5ljzYN{VdXbf};8Vy#5BmTE@rlz6xySP_Xrr>o2T zq4H>Dur%Zk1=F(on35>!O`^0eSSbNFM!{;J)o>&fEUlv>L+bx$6xY>1ZauW(ua2aI z{3V6W?+rVdeF>>U6&0^`768mtUP8YSX?Q23F3 z;OCcB)Rq)kuel+cyGMff$BiW9|_Q5131Cz+0n9^a%tGeWc@Z4 ztln2+N{TnDcVj7YOA?6A3HZVE!_kURO%)8-U?sQ!arkDMq>Q7~`q-1dwze`@CMqs4 zKN5h%8mQ1;8-!t9DTzy_rMTmIa}qA|11OBy3~>P)V3SGKB=yL0DZaZmzTnW3Vx!(B zsT`S+LibT-3c8^tG&c-RE+yX~6n^S})Kl=$@Z4Z+Emd#%T#y#%Rd^&dYolbWs65uy z*13jm7=gclkyTq!nRZFCd|{xYcR-~2Cx_j(nBHh2cTJ% zVMv7(aKr$BwSiDoFih14Isn5>34b`n@?>Gb@GA{g2cmO=<)GTXMvXo zYAb6Rs{+-LXl0FPEE4ZyDD<#_plfTw5wJy=5yCJiB%ET3Q`ifqK2TXxD>NZZMUm8` zEE`WTvO8WLf@wB1HyDA*C&gXFADSIV+0i75m6z3yG|OaZYU;pnS$djI;avUFqgskm zLy`J;5QQ~o!IpzHrDF(LDTT0SK}g)y`Xf^CAPZ2ip;=(kuS_TPb|u0Psmz!FW^RYNHtWXl^Xt5o>cp zMy97NwthVrd0lcslt_0{K*s=pFzbd=Mj0QBB+UOQgXy7wt^r79ha|Gq6xNC=VIKsd z{`Kp{a21>soe?D-*HNIMX`u2(h_zsXu7Y6}6vKjEp^oebic-)Ar7jerKCl-PgaSJ= zfMGrs=6`V@)Mj|TV<_nGG$@1$b0G+V5DwM=5E()gJ-ZS{L{`jkJVhFvMuGq!90CGbD`zBOVqP(MV%$itH8&Vorky zOOGt>w^Im521H~Is2R*IQd3iz6;E7AAu}wvMuaTS0=k+4Wms@3-mLP6LE%wYuLNMR zMrVDg>(^404Do=`2)zd$Qp&!8!no30&J6@=A#@DZ(^!TEgQ4ma?9CK*avB!&F|V!$ z;F2Z`vq~MEy~X%172b=pw8YeHlt_j>h5{)YNQGnBwtol3@TQy1zz`QqjoI*b?;D;@ zuBmR_N8vL}7`g=xl!8RV0lJ2V)pQ2XhL68$8eUqT1jORntXDWwu%EreGPpfzD@GR&AC& zy+~n4A-a}sYh5dBm#<$>gTcz+0vb`nln)KSUTcBpJR& zk%yvM*!XN(DtLIhUTFj!L3|4l1h`p!ewbI4JW!n=xTBW0qe@FvGY5{^<{FOfm;`; ztpksknTnA8HArJw&7=cs$x+DhAdQLINUp<^`jaatLY4$X8>;eW4J^5e!ev=Sx)*7t zB&r$;JuI`&bOg|$2e3j^5RT5NfSA@FfsJM%qbb)>oZ*=`l8={S#)_Ish?fLcCm|Uq zk~b46&Ax=5p-8#8Pb2+})MSHFBUXx(HN2&zO)`+9r5BN4MKBf2$@3^mK_*`kO5f;I z?xeuB{(v*W7`dB56=p%v)s$fRQ3xpd7?RvaF|xE!TUQEclyoYluRw=UoGhOq`b;tG zk=hAVL*fY3DM{!6ik0OB8bTmgP*!h;AsGfLki&#nIin$%WJ)1bE6lX%e5-tBf0R;5y1zroPbrP=#Z$NuLba-N+9{Kx zl$R-|mL{E_H;0X>}@21SqwtHiXypD7>aI%Ihf`)qv7D} zYRK3|f|1IA5co+=)Fzqf3oVZ3R1#JmrjQ_~ejuxbfR?Tv`fa10V%qz|%*+wU8!1>` z8Vph%sVq|@;IEQcK7_(~(s0QnGo<&y|3GvDAz>t#TKCAK6dVjx;#-`k(o)HsrR0k# z@Q5@pxU2dg&C-cZo92r_n6-hjEH@XUSSA#KvN}QJG=&|7q<|D%%9l}qaTx$K$cYLG zK$r}u;2~Lc$pb3$$1Jp zbYNI9f`>(XS*67P(S6BR`9pI9G-&IUb&wxNVci3h7lRUs@`?L^4%bzr14{WRefdas zlQJTDGKuo(6xK5^A424rp1;qe;B)=7(9I3?WF1T0W8D6h7TDiSxWi3Q6%7^baY$)Z zLM9{%8@^z&;b<5(Gb6Ch2tmAG9r1&u!I~F1s(>tp#K$?5@bqlLWl&4%o*nCm#ghvb zk!;^Bt4it^BueM+Kc)FoCV^h)k`43^^Eqr{(EPhZ=^{#L>VEN*bUA_(DWiRZl)Oad zQc7mrKFH7wI~q|y9st&4{)~LPd^5$Lu^;%U(Jx2{764S)nR!(CHcINCze7s!K2nde zmTK}VD6x|LAXeT8@fw6zLI$Wz63bQl+bz*KfiHwTMk#is;ZsQ3FO~1y-)@Oo7PcwC zMa+ghB=B1`4RlvNrSL_HUg}QZi%rqYrh}p&HnZt*oi3P3hwqioCDEFA9^I zLw^F5RQo(7)qA}5Ky7-vo4$ku)!=b=MO)KSSa&2tqO3Xnh5n>5D0*#W9VEu0cm8s$O&NWYMz@CHRM%GO3U zdU9O*!&T9_fkxP4E|+lMrntQ{nT=Z(r88e0czC;YOGw zrE(wnhZJq(U}(W=VTlWYXhxP>{t3mKJQ$vkP!`hZl7kkPbs3AQ&nb~!!!NtTNnydv z1>Uqam6?@)MKOELH2q?N|Aj#ZQ&nwEkZw>5bu^7p$V{fT|K#89lNc=YU=+gufVe4{ zy)I8KpQ2&VJ~SZd;Ri}=!eD|))1c%auQZqMIGJAg;5i@zTcquI8#-&*? z>CPq29hB$*9s)Yvi}R!mlUc%4fGZIzpu{HaFNaygQoZz28dLU{hSW=cU8IJ3Qi+qH zl*+6DsfaIo!rMe+%EZYk$qVcOf}!-WjuDhvujxNy)MQZ;RV;XQfm(LjLoteyI&l9O z6G>&V1`)EUZ=#!{W6h-TbLRmv+ z0!8mN{`yBxuB-&HRE1}U1J%-;u9!@T^zuu+h|n<%9v$LSS_wsKHdB>5DdU+&$y8@c z_ivDaF$uN4VTe_P>RquSRTB6NO1nOrb{)LOx}>#(z77;y2Cw9G#`~_nq4<|F3Pei- zbNux|;5@w)hsicDJGHP^%%W{9_z$;HT~}F|UAd_!qwVxE=!T{^%}ly$JKI{D;aw$h zU{H4f(wGA^9&}Ay8BO|+l*lV6sb1DI2q~x>gu2;a%8Y{)y_XsHj~)?{b5ip(Cl?5X zGUkCwN~xFblavzR$^30??zUurn)1X#?}VinggUhm$n8a`CxLB#2xBs)%^FI3PPSeK zrcEtXpjw>9Qs($*Txas=d-U`$5%T3i~Nw{WL%VlI49O6h$2+9Nb@a zMK>cbTwYTq6d;J}NxC%6sB2Nor)2xLn!zO;sH%-LMoVkTrA=bR!oS5~N}v@`8856O z-~|COkwxSCROO9g5hdHp7wv~cAvP^fCBYO;lt}46kX|X&rO@PBGR-GBjuuL<;vdih zQbPCop}CaO{QCwuX+kto6CFPew(KMQP+k5{dro83e(1GRdS(Bh=fZNNAA((!V6V_| zVEtwoHeJ;8)l7nt`zJ1g#%@pv4++M~D0Q#>&|XPt@Au%&WVMPGlY@SQ&7r=!iB_zz86(9*1<{@}>h8D+4_J1U$ zzTe|1MO}1rp#XU0>deY9#Zi=A`QPSN+SY+$BXDYSV52`ZhaF2P&imUGMGhspu)z+s zKN&Jfkw1Zw-*0!^O8^pihNHBTSJrU91{lPJ z;$CK*v>~WCgVOpZgH>9ph{3(Y+S&g`ib7fgW(+YE1$%laDV|5k*6pwEGsdY0F?EH&5tbF1Oi7w9!LlN7akD7AkQ6v4(s0P3j4iu3diyyE_U%AT;&m5e~L;D;!+ zzwb}#ss(DGjMN^m;!#R!zbAkUO$elDQ84(s^y2u5f5jQR`Bs-)i1iWIz72Zcka{z-P4 z8b@zYV*O_h=xVgL$U?9q1cmmns|T-m_$wR3!4#!;DW!pDsos>r=~<-;iVURAeL$%U zJg&3lB!-T`YT_P%22@u>cOken_&VOEVPTP?`fTW(T4f zEw2+_yG_MKu=AWcFhKD=r8@AUW+18}i_#RC6e>hEP%aut@5w2C`e!@~)TNbU-%#Y& zf5CIcLV@zyDC}UuGAC{4fBX%eQ^Qbr%ZWz05T6K6M~LzuDovWHlA%-wUXKngXGnjB zD&Q^TD7-I|+R{XC=Q|`iK@h5E~PiHBgvwd5oQUUrZ3w@ z;mg#5Nol0i23{~_P;)nRKt*H-wpe;og|a;{$058L9G(L&$7bxBD~He~LIXye`_)9s z4?+e3iruJCq{vfg`w!5Eoe26yOgY^z00$n;*iljDQ~LYmdioU+ErfzJO0XOztTI|r z1G8#+=SS(H)Jtl@{$#xfOm^ZK9jPNS#KI8@A)XMCS-GL~Q1tPGqNfmH0-!I~(Bnx` zuQw|TDS_!>dPZ%t+uzaDwg##VX@;GCgoA9w9fURO*VDIXMa|RPH_T1K#0wROl3@;~ zlxp^aQomG$GE{nSN|LN_YD_Arr5s6#&-howB|gVcQssR~3009GgkU1kLpMxBHlVpX83CIt1j(8O%P6-gY9r}U=$ZF*o>G<_*inMA1^ z^tY+d5#X<&3Hgk8NI7)?p^3tx_9E1;LgjH^$qBBfI$TyEZ1G6!O{Wy+^<{5=C??;s zORg2^h)TV8Cy_shk`Mhy$cq~uFu&6hYl(g-rC;&S=nDdYNtaF+8FdTF0HrzgpV6FM zCZ%YVb10d>KPD4}fJ1motU7g`h;l9^S^dvQ!frw-txgu-$n6s*DXS^%gZ~+AC~cy( zqL2g^riHQ^cr8KF(7b;khN>VvuLkyhV0SZJSfY$jlKl+yl+9*LW_=uppml!)O3|eK zQe^|BS2jr3_el?&5!9cg2ri%m`|-j1&!89^O1a6*6t(hDO1vM(x&Oq4YU*?~sPZsM zan8T#e=<{%6>v6Fs)O18KBY>-3nBS0+0v4K&1ioX+DfTb4buH^3{ER(+(f@FrSn?T^rPuweS>$+(S@4*o0BP^by{DG0XGuahV{DcSk|iY(NNQ|1Ho1s5pB zqnqjhc&CAG3`x?C(^kU&u~y)4m)Zt+6*;xDtn8r;)c(gBsG3V(WRu<~Q?91e|D9Sh zg#@{dlxtr{Ne?!@_iZtmq+#JwRx54eE03VW2Xpd&k9a*yB2bnDH=8JVIEh;c$1L8I zI@wSu?9%)t;!RXC(#q62M6o_SoGx4!pc*W zr;11ALkWV=T2WS;;hwIp&Ukl`c>1x#K{iZ3$I&a#RGuZ?#Udgm&oQUxk8e?)O?jsG zwDfr+@#!$T9j}`<$VM_0_P(W^cY_jL|a9}jO69aCuNp!ZwDq7pRV{zJjshbZe zAED3>6ZH6I<)Z{WF~}7f$|vCp4dqkHrwMwJpl4DC;wzt1zR>%I3gwGTp>i)lPtki~ zp5{lTl;NAjUoYHDA#w1!^6fsz?*Q_91U*ZUpW{cR6$sc@W?_G<{4~w~X9Vr$OGKf3 z$*kR~{7U(?@*9Ho5cCp3ucR6NUiovMHh+OOe=X5%e}e?-2AZK_J)n3Ho3M z>thSqq3kerI6HzpfE~$>BIrYcejw;ig8m{{L-3&lHxnEu_!w#x#iApjqo%Vb-VFED z2sb3v1&dNr5^lnP!o9N2F5!f6(S^}#Gv>B-XMly*v@h;#1G|(?Cr?p;b1zcOWaE^A z23B-+wsv$UL}(aml9TM)f*94oOVk5U6UIA?+5sL{z~v1vFb8-FXV8k*d<;y0zUV8N z$z*m0Gi*CMg`LVyV-IAf6Z8>59~1NmL7x)z*>-j&dk{N|^|Pe}eNNC<1bs~qnC*8| z>VijI-395ZSPONuiAX#aqqj{Z?*t0L6e8a31cN(9PgIAK0$`ALhzI40cf&|xrnvC> z24JTI9>}CEUcV!H2~Z;impXAUTgezVvvUdhVl!Js(3jLQ>Af?ei}MS7Nx<{ikTm_6 z*R3la?JnLh+P!Yvy4x{c5`U71E+3%sp)821MiRb4>bpF4Wb7)00ea?S>lHG zZ2LzNE@p@&M8bI)FnzS!9|3805e6Ad9)%eMlDBbD{^|II+iT!uY1)q9HQ8gBwVU|j z{jhvVDJQU}QQJO|J&8S;J%v4$V1{5sFdWY=BUrwjJsoCC4|^ti7QqS-CtSLwBAAmb zJ9USFWZCdK3UHeq>nVwgMp;Ae#A>BiF~RU0IyhvYgHFdSeZ~qk+ROnVb>$-V5^7%; z6Rh0KUP>@Kn1yd)w+?FI645Kz9ciLh5v)!d?N0XEY@@w_y@wfg4SOSd6MHjz3wtYj z8@r3WoxOv-lf8?bN-*47mqW0Q;9P?B1RDr85^N&aOz;qbE#OnGVee({ga7XZkv{~2 zFNFIeJn;7u1X~HV3qP$?2YH|hu<@JeXLxdmFzbU{Qu?6I1WZSWk&^b5^1AT7ArqEH zBJiCRzLU(Gh8S()LKU9So96=YcxOE2S(3UDAEg@2#-exGfp>#*Tl=EX>yAVlZttS6 zn#Wp%KvKASFF`dfgh-`pC~G3O$uB}ZaFbU%d}jopRKv65ojqL%aR|K3zOsp6n-H|J zud%PgJA-ha#TNE8W}^u3rZ7gt&+o9WT*bc2zQ?}Le!zane#Cyve!_mrenxOU!NUk1 zP4GB^rw}}o;BtZwCb*X1dLS>^$CvE4a6<|E75g>&4Z#kAodmnKvfr`avp*1AK(L$O zp?pcCTkJ?n@{*?15!eftz!i*DAOU#S5oW{6*y>g|(8~?Q|LJ!P;16Ls6j}bAd2kE+ z2m2?%9)b(`nXfW?R7izYGL@Xss1(c#Dy525sZ^YbgWJ5WR;g7QX0J-4%7M8k(cKiM z=U0H>dfGdxd)gPn^@w_7tfQsRmxktLP4OnUl`bBFO7|FC0|pMTEqO6lpaX7&0u=a4 z#DxPNV<~b{E16&RCf5mpiC51N?9;n>#-M;($8KE$HcRiQqRCv4f^bH6^5U+huCB4v z-+?hD;MS^@u{L^F%Gg@C#|N(7Yfp@=qBmI0FM?Z7gfB8+;A~;(aY=De$;6^W%Zjn# zHE>5>``F6X#o*l6j1}x|6}{VVta!v`(Gq$KB>iS=@>EZHN7gdo2Xu98Y;|)?I7GZ? znP6xty~+S12=2h52Y5&eGD*u@RYsLbxKwBWfc_VQ18Y{JvSezOiW0nlkKXjvT;ACO zZgb4xJ)Ll)pu4rBxee~Mb9)8$TgOkCl*zjnp1V_BbuSYRFdglVt)}-e0ybzKNP&!+ zSHwhWAhxEKr17irRR#STzsjTX3dTR2;8DqdUNsc#Ry9loUyUGmivX9-4AsDWx zguWRRH%Ik%{1+KX_c921TcR)=x_c5u%lcO*?Qn@|T!uPnhxLVea6p1Wm+n)cz1sPg zN}a4auz#h_P=ON!j|TjeNJ{lnrIxD72!@HMcp#-#^igV%;IT=iZjb73`7cr`sFN-p z2Gl3*Yn7@xL!Y#-`U1Trsn5mx)MvVhf2qo_s-b^XHmVi~svJ-7WJ#5WQdKTeMG2lj z@T7rMxi~|WEikXNsFn~s5xS=L(h>SzRKN58zA~u?rxWskN~FECsFn*#O!ra`p_?!y z7Yv|6!M!F4|4Y?%s$c=sPh6quQLPkI2l3<#Np)+e>ei~(5j>6H=>w_mhz!+Q(rH43M&|uR58cffUsTTgF zB2QMG-oGNxP@O3#@*slCBt@P>6?v}eJc4HtTsn{Nekl(~j1TUtk zO=mJANE6*b$O1viP)uV986hzXNfU(hIb;aw*%PIZtD={4)7+(yTcj1PG}QKl@JW;qoo8dBe-=NQ_oG{CUTQt+Zit>cm=_2l%|F91(_}2TG&x8Th`eL zx3k0M7hDJ39cW6diF5|(Nt|#m@I2bQu)VNQ;Kbid(`1mt6aETA-UgEEV(v`L{+2d% zH!q{xVKgx%U`ODTk(QUZgSc6opDX3c7!6m>1(=JOz1$ow*x1z3ybLZM?pWF=kc`CQ z?Tzh}NEw_;yPyO5-6C+gKzJ;$LU0$s?JAxjxRc<+UjT}8xk|2zt7i5xm$S2g6G$o1 zqd>Zo*9D84Tk}DJ?GadrMY@4Gf;)f$`dUb+aUm|;s{tyyYdv(Y5U;#~i!mNkpgt{r3xhFi<6r{fD&t?M>(8wg&{mt@zhNK^@TEKCmEQQXnoF$4qT5d3F|`c z;xrblJC06cZQ?d(ZT@iEI9MQTV^8HS2cLE&Y@HE&tl-m*+s0i5+P;SI5PUq<_DP^^ z&@wfxiY7>T!^li@_oHXJe-dt97HdzIeWYzb;_pW8X3F191fQ^(yM^Er2NU=0+#Lh& zc!A@Sh~C59N9A!Z!KZBI?kD(E%B-gcYz1~Cmc-)mSWEJP@->0gkdUViHCQfgzHkpi z)du$n_bB%m!KV>?I>8(1cBFU(xwOk4>`2i3a%WtkQv?PKyB{O6w(I*s&Fg7xUNI-u z)&-|tr9gYvGW12uf~f3-O$&=KIZd8GH?>P96~q4al;ZIlHtgn}1<&;y_k06fd)v~~ z-Be?cpS>9TR-(JO_yvSza)ol{LGue&isw_$FYH`Q3&0YMg>-`$P5_HX3cEYIj0`$% z({=hGFdeHk+8o^wi=%MlsL^95PMSPzMqObCZ1}(!FLsxdjC0f0-IFIxbQiQ6fJxgo3xc!ydz-|DC-npt)bbXRj$e5XO^#-HKTwmA> z^GRaY&w%Y7@3q(Zf`sa%u>2{&3 zI$WDVuL}xWLa~+*HIZ0Hb8L$}e|~jX+(O*rbmbO!d{nF}Vrvo$;CE7Vo87!-vzO21 zO?!q8%N;)A0GP00zpfby7dpgRue!Qmxl{^a%zhMxqp5i2ucOApJlQuK=69rz#9j& zGtg5yI!fB#Mu zYDi!ibQ5XqrlZgR#wT(BUK9ptEDrjLG%YTTL&XY!1ryLteRa4l7%T@32NP9Lga8|X z)!~ZPc%mDSx;mlQCB6{exuEt&OIqM@imE8j1UwFRuW5@_H6>QS_LtOV%BF+mVzaa3 zT|zs+L9k_YN;=|ZBae6)uT*h7R3xyxoLB2}c?ECQGy2CE6=PuX7#}l+8OKa!YM45v zn_0)4!(7E&%{<6F!935r%6!9o$Na$j#Qce5NQbOw3OW##qq!)I7NNt?V$_0`pk=5N zorEq!o6%OZ9X*9!MsJ|c(O2k4Y{V1rBs>LA!(qGvZoEGdZnQrhZmd5KZlvFZU%?;Y zuVgZrPG*rgWy54sWdYfIS&M9~>{!`pvP)!_$u`Tj%C^b2%dU`JDZ5H`jqF<4^|Bjf zH_L7ntJE+Oe>01czmvaYy9ho@jAZt3FMt}Wdb(+)L^*h@t=t~&MP?(YhyEqG^u63W zP+rEp%)P?B%Du+D&b`6C$-TwBP4GDcpGz?08_y^B0)j6j_#%R#g5r`L5Qe|Uz0ZBX zeaL;peawBreF_B!_)@}6Cfqc_9ZVp4;o1n-LAXvjLzvSw9|;Z$VhX^eVv-cNO$@KHt7|FC zl0bjtV7a=T`-%IR`-S_J`;Fks2;M~SW`eg6ymdSG2lprUmzq%{g0~Ub4kGsw)zd`v z7M0YP)Z9f2FgxZ_~)g<```)U5E`PuW_yR!(x5!S z94l!cDKIsswlc$Zs?}(sewz1pBQs!eLMdWahK#s} zLf!)w-!u!5DC&Sh+Ll-^8bynHTH9KH(&C<_*)*bJ>5KGSXi4-jiT(h^G*feC&t`}{ zyY_!$d+9%5XF^Jg{*V%snSCi0`*M9$|7QPMlInuel}3UO9#}_X7I$^8ZC<*3^|F?w zt79vhmM>e`y>iKt_?p(kS1um=e?oz?#ZJRc#DC2ogHaRhqN%oQcTp+!1ge3K?O%NZ z4>EB8WDUIJpb0^hBsiw*(J*veF}&ijCJB;-29ID&O)i23S*B^t6M2LD^7{W(-h_^g zp`}JKx^&HCsa|Ah*Z;;2|9@)ag5u+`rI1<3*8D=TD|bKw;O|NooM!h}`lBeztsN#( zybIoI`@0kaP#o8qSXR_VSLEQHmvq+BV5}(7O|z$oOclh$R_=i}jsI>dv5o;75Z_`^ zFH^@Mx>vWVm#bH(+tlsq4t1xxOMN)O_Yn*UoCgSgkl=?1ewg4#2!52{$9AX_P&W@r zNcAf9YNj53Ll*9FD4rJzykVpBX?X7lQdQ5>cr`B_jEdo3Q9`IF7V^%Hz7HV}U)9>t z+TH|t8c)BE=`~PgoscgPie3x)g$Z`7Y)!PnvIfF;UtfskIOH*f%M08RHi9*=ksrJwx!bTa-7d z&xaQo2!_|F7E%s_blQ(47PUx~#IcU0-OCKt7bFswsy9;-m#JYr0z0yMvPje|0Zw}( zOPE)xZ={B_Lw%L{YV|eho$71V*Qu{pLmd7h!7mZKm*AHPeudyy34V>>*9m@Ohx(?Z zA>F3lrM?{u3BvR@B}00bVAy*7kXq75|KF10MTx&@Nsm%Xf=udLk|jM!E$J!s)AWCW zVg3G&_>-S$KzY7d#o5O6f_krLOrSe3ruV5OydoIW2mGks1~l?C1CmRY@Rs^r(T0FN z*wDv=VM;h3tDzEphx!xsr|QqtpR2!6f2saT{k8fVf??z1GlD-S_zQx+B={?Wza|*I z|8|G^yObOHS#U$Y5&WHGJ>Z6Z6y4A-|KE82w()3KFdmJH;O~>hqtSrzXte56=>G)& zAh@Cb$KF|oNo{@qpC#Jv&Q93fj3i@=w|HG?m)!xjtg(VswiGC(P-u}VZ8>#!_ZBMD z-QC^Y-QB&vbCO9W$t0P~E`0y^J)fr!6qa+|_vYSnHTS+kznfQ2%d5&|Env!Pw1D{y ztGzs`1-u|ReC4I3bRgOtdw0~xJ@tL zL64Q~DOQ+rKR3f?m+}P^E3?XHm(MBRwR~>*ZsqgJcQ2n0ObD1tV8Xyi!1M#A3YcnO zYJibfm+xVWOXZ8pmtd?c114g`%7?(jfl1)F#3cV0ETsnvP_P^VOwMaI0=pLc z1x$>(7VY;HW2L=}T0FiSU%}$krW{`iV!$X=^QUM5qZS6t;LD`#4ac*}&(%W)cc(FA zQhttx&&B0eQOI0UzOsB(`K9HTm0w5FdG1~Aut;OvoSE60JAADo2@SY-0WMvDgPGxmhXYt+z1rxTebpb8|quO z{a>V%9w~Ue@#6A-fY~A!DHVM%QYy;UJ&t|>v!&Lz(C^r{H07Fmg;-IpMN0)9@xy4@ z8f(5Hr1dRh3;UKq)1*xd$LflR*0)s1TFBJ-IT}8RioqB%70HTJMY17_0diXledQZbzRmI{0|(PV_o)4;UoeaqzkMNG*N zQ?VsROa->NW+P&@(WWj~%=jOctNx!caj6(z(WuADL@icYsmhUx@CYz%g|X825Tn-H zDmwH?!2`qCxwQMa89vi1W>KWfsMx+@hl(95cB<&E*tue6#V){f0@DS|6kw(TGYy#O zz{~(V`tcRoMCZZ^oakVr%<^+He9ox2h$7|8inA)tt~jUS z+=}xm&ab$j;zD5N0JAGFbAj0nn0dhL4h+tFF(&p{U2(B73{_lKaXI!WtASZ)L<$Z= zdjYeQhM{Hu>r_hbRBoYAxfPg2MyT9D!_b{L4B;%!hqT6L&NQ<3T>`)VFk{0Fktrfb2EHiu6UOM=9P+9D_*O3z2c3E zH!I$%c)Q{qVD<$DLwtW=4gh93Fb4v25HJS=vto6{duG@2vDUSG1`HShgM-kade?Hq z|Kg?ec=?Iq&7~P?;7fp*~uq9EMdMVzfv(yf9MAF3QzQGHc4n;!IP%IP=DZm^J%rU?m3k(MI@xYt_%!$C91kA~+ zLkS~NLdZ(%QyapS(kYfmIZcn0GyfMUB}YnVG)77YR~Dz{A|Pd|)mB21liffVmi$OIC-bn}M>E7AP};S!oHBOZ7mx{C|N`dZ6qWMNuiTN zr-V)g26tDk2Ig8|t_S8uU~u~c2hiJrxpQ^s^w1fhGec*E&JLXuIyZD)2m|SEV4eZy zWnexA=4W8bfE9t2fsNaaXoW7(UY#;mA*s03SEsi3^@xVSm$R0avZ2d$3*LYqN+?y(mT~O}&_=lv4I|vsx>Zl>Cj2&d zuhJSbx_i^YC%H>kzolq_7Z#27_TD|u_v@;+_23P@t$h4T<`F%WJMgp3y(*bpD*lN* zsV8<9GL(Cjm{#Q*<|;xzEf9Jp^a5U{2|XKnF7!Mw_W*M*F!!wty%>5agl+MDU>*YI zY3i=&eo8lfS_8isk!@(iFGA(M1%gEKZiF+t8Q`Zl>hMIkVUQ_Mn9|tMh#$MckA`-V zhPD+LdK0g6hTaOj4GeA&KDc5mU2bT_qp@_>cM*OE0x!PJS+WBj#hN#3P6M4>Tdezi z5c=%W(1)RqLLY}d3E_s_!@%H7`%z#X2j&T2p3<$p$kV<;Un2-O^cJQ=AYdc|hrUN3 zDklA-mh@wEQzfh&v)gs1J*i)HJ0puZ@4rayZ(yDz$9}CH~{c0Z?f6&4BihhZ{bw3l_FMCC0EH;3c%oE;yGZRU&-HC zxo%~-Hu}E+46;()YC->GOYmB7({R+J^}a$ruUZ*aR)s#hxDsExykr!4Wkf6T+_a)H zUYVpPQ7YBS1Te1v^C~c}t*lH{rYmtT{&irmLf-yAdJ;XygE8PLhg1#)<_%!p3=(iI zwYBM(F?eHxqNs8t24dx?%F&f$DmSRa-QstEc^8=Xf%yQKkIYipBp-;Cn`7iuZUM}D zUXeqxV=?F~+0=usvR?mbR?GZ{o*`S=NJ$JqE0daA*<3l9YNDmGwXzMEPk_Nj^V!PE z_R5aRPGCL<=1X9{`ai9S892qM+#Z-Os1gcWkZZATU=;h#RO~Y=cd49JIlFQWFkb`n z4KUvV^8+wHnZ>@FrP$|FnP|!73Ud(^=AM)s5}#xKY{rRn16uz57<6tk)2~Hvh(Q)aL)g?U!-0_C2?%!DlMD;ddK7y zB!=tFUvvF$<<+{Q@qD9=KI4YUTigoi*2>!|ZwIz7uq?2gQAl@D5Zw(dQ$i4#ZTErD zXO~nySosjJJh0f)>Z3;Gqn09gf^x0toB4aDk_OR&mh@ufOO-DJyAH4wz=n+cy+)Pz zdgU9yt_y5=?JszKdAh$@}tU+fvp5K46Fof6|mS3=bqp*%M*M_Pw+aXZCsH=4c3GBfv(fyD1o5 zHXUO$^6)x1x`eUZV#b4oL)wGo5(!J;8ka=EaySx>0;>S40-MOyL|7?kPA*9sp%Knt zIfrY*{lf#o1H*%WO#+(&HVteB*jh6?L-XYv9!ABgHx{k^hDSLXhW^uy$js6V!kf7_ zgYeejad@XVJhp6|@V4PPU+GvE3Y zI6N)9BNglP@Qm>G;T?coAJ}2Q4hMF`s_;(X?(ojxnZS+&b`-Fqfjg2yRKK&eAzm=2 z8^8K7SiBCs_q;{Rme_u%U3o-Aw{~B^-M(|?;<rmQL#S@K>DE)! zt{UJplVB1{^nBu7)*k(v9;~}#?;4&D?3fi}UoP9W&&vqUFApyaFADEj)&T5Az-|ca z22h5Jx-}kW1L_{!>Pg}5)!P`2eOY)vZ0zB^!~2By1$JX#Hvx9jmErxv2ZWacyBV;X z1G~kFF;jCjGR1iQ{+`co7OI^*;8$dNu^dLlayYPCnnxDGM}?8}c3Jr7@G;?I!^ee> z51#<+R={oz>{wv80d`wp>n;nQ6h0ZD&iH1sY&NjtfIFNh&iIOw{)d4!z~nRJKE#L5 zg15An?w843me;uaaU(eFM%up(^nBPHdxI#=#+CdHwRkbo(6}fztK2tCT%t->v6if% zLKl85B6@jU&}aYa`jw3fUl_h9d~x`a@XGM2@TK9)!k34y2(J!b8NMofb@-a_wc+c+ z*N1Ni-x$6rd~^7g@U7w7!ncR-2;UjLD|~nOp76cl`@;8!9|%7feklBK_>u6V;m5*{ zho1;P8Gb7KboiO@v*G8$&xc=Ib;m^XKhrbAa8U8B#b@-d`x8d)?--mw){}}!${B!u1@UP+D!oP?A z2>%)WEBtr(pYXro|L|^cnbcQeBv#@iUJ@ixT1Q$}DwisxkW?v!B}wWhRY}!SjU-DE zDT*MaxTHv`l#r4LAWTacsaEQbn5=;a<{2yvk%mg^N$X3)q~X#CX{0nt8ZC{HHjp-y zHj*}$Hjy@!Hj_4&wve`zwvx7%#!A~r+e&rPIH_K0kh0QvX@WFSYLvEWzyx+71CB! zW$6{^Rp~Y9b?FW1P3bM^ZRs89UFkjPePHW>#l9;GERLTOfSm|zBe2^6I|;#fZZNg96ojgb|+xFf!!Hc95{9Xb{4SM zxaR=7E3k8c-3{1z!0rw#cB2b`-2>Q#z%BxIPhj@~b}_I^fL#jgGGO-xb{}A|Z`%*p z{ee9ISnSsh1oj|c4+eGxumJ2Kz#a9I(d&i#^YY zz@7x`$-tfh?5V(>2JGp;o&oHcz@7!{*}$Fy?76_62kiO4UI6Tcz+MFG#lT(y>`Gu) z0edO1mjQb@uvY-P8rUm=y$aZ?fxQOUYk|EE*z1A40oWUXy$RTxfxQLTTYkeG1s8fqe$p zXMueV*yn+L0oWITeF@l?fqezoSAl&E*w=x51K2l#eGAyPfqe(qcY%Em*!O|`0N4+K z{Rr5Pf&B#7Pl5dm*w2Ce0@yEs{R-Hxf&B*9Z-M;|*zbY;0oWgb{R!Bgf&B&8UxED% z*x!Nu1K2--{R`N?f&B;Ae}VlExIVy@0oNBe1~?Wt4mch-0XPx3b%0wJxN_hsfC~Xv z30xRB3Ald1RRLEGTn%tCa1r35z{P-z1E&C|0+#?T30w-eG;kT9obmH@XDxMjfY4ctD!?F-y~!0iv*0l+N> z?m*xU0`6eoRsaXU9Rl2;z#V3O%S-y0J{*=V)4&%?adx&0X!gofntAw%98{-+{)KlEHVuCz!y#pL_z8uj^wb^r@%Qewy821< zVb{j-S=_xva6xxldv<)|G$T8IkW-0YKP&HhOW#|izjF_gOD@||hugXI-Q0#Orq_U9 z!t7}6YOl|l`TLI?#+dnYvDChF*of7HpN8wi&q;Q7)=eZ7qyAnN3t;s^mXKp?uJG) z1C`{man8m3nsQy!)Vk>%-C6u5DSlgfYUB9MZhYvLhPw8KZv2{PdtH0}yYT(`k;F)+ z#JH};Cc_xNz=-?u4Y)_&-Z-v{!rgfO8uCrK`{L)(8|zxk?-BNklCA2rolsxjJtf;t z+xdp5LWV<~hR9Ltnt-*ZeYKVHK$*gikQ-h}@*3v!%6(3{9UU98)36j;+q2zzJQ_eA_A zG}cu2`1aQ3Zi)}=0@_;}y6QV^A-Msm6~t3r8+|`r`wl&RqPsJzzrdmIV_H7c-EU*^ z-N2cXj`}+MKqt0YOL1W~FeYTQ^WrG@pX{gaVw9mzz?8s_Y|V9|a=iNXE?TUML(o9F!+ z$S7ems%ydzR=3b|OlWWIYBS^}_*rUSt2ZpSBTLmov)K|z&15*#!w|om+}zkf4HoMF z1J^A4Hu9>qd13P#*VvNnp4ixcHQm^Z-vBqwJIFj^GjGVYHMLG}#t#yA)3>gzJ{70JR7?0h+&c3acO%;xn=O90-8!nw zCyThv!pL1)U8ga5=(mu}2HDJVts5VFd}E6?&C%b~8qd8Kxs0&6m?JZeuT(_X2=Lo) zjrEx6y5`0vd>5;Y@cot+W{Mh(F*+M&`;b}EmO_1N+w|_XiFNn|cdgYJru&nry|T4` zHzYA9x#uxF4kVA5OD+1NI*wI$n% zeWX|X96?U@qHnIN#}5s8yBtj}18nJZPVr0QIC8MJpQ&{?pYiiKk$n1>-)E+x zH%5W>t`_{XapQOl4x>O%A^U+I_BmTEc+KKEojlYs{cA`W-0WGlV9xU8801~K0nv~? ziwqMUhB)fBn~m{YKS><_&3^L&GE8|$I;JESlWnvNKQ%QUcRZIbAJ^5=fH}nPQd=g2 ztH@|j-l$kEu zaVRp^5&do=&w+VQoH^zZH=FD5OZtWg8Dn*EWC;`!&p&(q^l z2s)KmrQPN}&tG~$1@-+DHmdI+e#nZoJJFJY>(hKJ8 zuhAKoFQ>_1Q{xPpQR74z6TrsO-fF9nsxopMRm@Ra40knl=Qc%hWmv_M^PsXe`~uy~ zxmpiT>y_zPM>xO583cB-IP_U(yHx_YjI_Gcw`Zw}Xo;#HXrn@=g(~{vEV!=SnEh0( zOTLQLSDRvCQu@$mWGh5=Lv41gI4+olmru&lB&#Iy%2>U!)3WtlxHQEf%UpXIX;hPS z(!&~KDZimp6(Q4MR?~b2w4+=N+OiO9DcgzNqq)CQ6(`49tE2e{ZIdRDh&2YP5(Qbx zw_5v{Sd}JITS?}#WG$2aWM`|byq(?^;-ltP5V)?iwwXKPqhW5~`H75S&gXUb6Bh^z-& zpP5Th+*XWwwQ zR^-+NiMX}YT!Ka-+me&5c^gZc+(ZtKkhXL-j&C$~_Nwa1C2h@@;Zis|tr}0pF*jq& zG^VPNtOnYwv~#cYc-=UmC=8?~^03uHTh}<;MlmPhE(O|3KDItX?=$sjkC9Hc1viec zI*k%)CofwsFtr^E7Avcu!{{Q@A!QwN2uGg5&xr3vJHq;oV{R<#!U(YqXjRk5X^_Jy z->O~4z^d)ZrN6^PuUNM+vuY=@AK~J6UsN_A+~r=X&m* zK1IAIxg{KKSlPLF#4g8(rzK?R3=%CYeB}2gr%YMLytxatF_`u?yE_^uwBU|yXJcnm zR-5=4N$i))Orf>jnmf(mb~#yMIk{N2XcJmmJ-DWEFnPw^Jgs{KRfmw7k~hOG4|A8P zGh5eeWchHitIgZxHkomIANwDi-Qbk4v(a4lR2@a;7@$VJ^?@p1Dz;JTSTY`(H^%OY z&cU~86EggZ*2{FXW$SI-+zI4WUDm0wuyJ8aTiD&WDPSz8t4=0^4J-yU$?4WM0C6y& zg2Rb9PF(6ba7l>1bMk}qdxaL;%7a&!Fe#QsH-p}Ad` zxn`(3)7`JJg_1KD4`vTyrgskc)fS|u7hNaqH`_|>d@>(eV4j;E(leRaLto>eE^<#q zlg9~4yr{g`NksF9bMxs6Uti(^O1W@%81^R z8OpblZLN1cv=>(S@%t_^pG4pIo|D1jZwu#UMr7({&&HRwOEMiZ=`%@^LQ-Z)F!I(qv}BoP~&*r0*md zvW2g#ny6zilpYAKG;Om@uwH1%hV_r*Iljc8{dYs@VN%*WP@ZyKj@F6P)3f20ydm=# z$!t(WhF;jwi~{!oa7|Wc*>A6UlKi(0;BU5mt%Ps^K$UIXN3D8>q_!zVO6z@$C$cZq zo+q&}0mK@n<9rRLSK1Cxy-_SL1$`{NbHct5-!U3uqE4s9f3JG8Bh2&DGe!7Kut|kn!B4iTMei8 z$Z2#DCrZ9OOH+j0EY$G+ki0hx;Ei>GyFAUfj2?&E0Ok>ks!vE@;{XD!Z8)Yj&d^^y z+8W^JBr&##gx*8gM2ykYx-R*Ow1yYaqS6?TTWPp|kzWCQ8}vasC*s)K&`~#@3KJhE z9|=E@M6vd-HQd||sC#t&OfsVaJVRGYdn>+b>YT%SBF)mx(~@XBh+2S z*!QZp2{0~?(S#$>GUO5C3@fRj%Io{?o67m|EkrZVz|)5R*Ve*=S{iY>xSI&sk;Mf z9}_U@Aw^;v`4voFgXC~xW#1dBt|bNEnsjv=STx~WVQPm!aCdWjSBq^zQaywe94*+j zP}}M{umBx{L-qRP?ii2k?i~~Hl@1PUUFJ)u>Jj9$gU$9$>eKhGf zI#VNYoJ7_S8)nS!>ZeWfZbciCj7Jl6kl4J* zcB5~u-kjt-nwTL+{gFisw>GjkaONkO)mxE>N1b|zwBt6g@krZ{`&7?I(%=1JkDi;6 z(~Co#hqdTC;?zy*$C$L;cyrm8+b=gCbQ~ozA!s7{P97az>d^MajZrbzof|pNlBh=y zfe-G;d9Dm|yM*Qh*ASaXVw(ibp-s$u%1NZLSx^n*DeJmATd5~Ca?(O7+j^?#-_*l< z@FVK=!77&*d)uS@f-6Iuej`#Y0hauBhGCbao_nNBeVk&#kPq zVrlM}(2;F1$Ml^^#L+J~M5qm8kB;+GItfK*HqDbeX7J1+nHGELmLP*|63_Z};9Ld! z{oMFtYVS(gQ|#JZ_$2}S6fkc5jGMFDOuWjrxN!ZArzt3-C^{}Xv2IEu<~+X?$H6u` z!Ccr^&!aSEtl>0Tx|*8oCpW7XP&$r)o;q_e?M!Cc7SUIR>HIg9ICU3T8WZu12d#;l zv>)JrViwCHl5#|kj})F9#B;NaW*9FfcSjhzyLW1vbGhz|0ubX-je9e#37|XD^FKJJ-*NeBdS#I?cvv`Ue zU(3?jYFgIVHhHTLAXUdUP5{-qariz3qn`p4B^wH7CnW6%FX3!+8y*iD*VYJssJ=jVzkqnlazdpT5?=}SmB+k-;ISK@TOD~o$p+6z7N zQbP5mB-s{J(rk^|xmoS(O1n04j>nR~X5NlhXXtRO5&u_^df@hCs_Wfcdlq};7VF8e z>Z?evq2$~euXXUS5q4@5@kPHmhFwdFlS@|Ab7<(|3wAvFV<{6;{sxi{+#Nd#z>vpz zPiHG_Ets-5lWgFA#Y46wJC$BK8Fh6VX*zZd12r(57wYdayNnlt)pwFsPa3PSRM98* zM%M1>O(|;I8aQI;TT%E<&n(6JNwzC!-CNqJc5;s@T)TlnGsgVNO@9w;_PirxXa!0B0xQr33)Y{GYcHxBgbxO;zSnw`fOIk)z7&}`ym&8KD zBbc-!Qkc$Ll+JdgJd-w;q}=NhU~LzXCLY+ZTRM#s_0{i^Zs2awQmtLIw~MC=8oKMI z;2U|z+U5h24IIU0gTN#F^nNsV6q8l~W*6}>DLOV2{0mwufUcHFEqL_>pPItNRQrt7 zdNL`(7ZX`LN3EYY&%c4M{<5dp(^k4h5Ev2s4XKshpLDfoYFHWOJK*Z?Nh{>1a9Mv?tNYL2&cmiVx2s%mjDB|8n5me_5y zo5%XA|Mt(2Q=$PEs5p_MY3P*3_RcPxhBn}`)yU9)q~_Sv^T`nIc;R%D4(GV+uh#S> zG4FuTvS!wuEl1{FZ7yFmT!4I;Qh2Qn4-T2nXT+(|j%q{_bKg0j)u^+`+VPDLU217< z!z&(jP18FXO{H>D@*bs}N*(!8r5O(y7!OxTD&FndUQYVdv9U$FkJ;TiemtHkZXK^5 z{Wb*qk)U_C%l^DpE6`7kRcU6ezFLwKtf!%*n_3;1cp|Hbd=} z6U}mQexh|c+AI%erAC;pN2=cIQU7wr?a%h{cni53@5`94bZUl^r1!w#C25pEOKTQi zytSDvb5zet)w08828FhPr%#lO=ih+Tz2_UY%$lW|n=$L0S=ehfhzKNh4F%9&-06Xw* z%Nv!N2GS4I^|%%h9fZPdl*R@euJN)&NSbD%vqr0;l9;HEN8xsa4ZK;#>Dh z+{ot?l4>ZF(oRKUAv7*ovW#As=-D)$5+_r24cb{m`h!O2Fo)6Uq&Ti*#pY~tYdfC5 z#Uv(ZU6GN)9Y}AplJzjKX#3Jo=_ZwJN>-s3P&b}7+0rvfe48+i zPABU(ato(P`;hi_J=4acO>|ZiH^H@Gp}rNbB^Wide=mxmxsiA^`0fYaZsre`)Er2X zE)Cs`S<7Hn(1B>RUe}37(Tw+{H7iK3-sjPa>S1Su=TA(*LrKu34-TF|eQs#%OIxOSR4e;TyrXi}Wmo9EB%RM;k*$C0XE{1+`%nqFv||3)mG*z1hCMd&G{ z+U)cA9dl+aTRd+mj=qk;2=D85wG*X5d$&gGU@i3XgYoGk-PkK>JgABLQ#jemUni+K zi)5$uN*2$HQ|7aD!37WF(M$C#-f5s0Lq=(zOR03Mu~ZQ5(l!;ZBAaiPYc8M!+SXVC z&6DUNn{lJ8=3-LsUA0;Z3HLh8u6-3r`?c@l5o49cg-d;#@fyG8auWCJZ+9brNWYqYm?B_a26(BqoxYi{T>_@axD?ycjiYi_Q&1M$^m!^(!2 zjVK$rV(N-%E2giQv8v|In!9T5E<+aN(ZC%8+_6x0D-nfz0e`M}5Glts4*_?a1^!&~ zXw74NUP1UXcLH$7uc$-zGlH7Op7+hnBc~f#e7fd&1T~jUENiTJZpF+Mh=e?GWz7p^ z%{4CpchU+3L!L}Iv%-Vz$Z8YV=a+rGtY4=rz5(1RCWyJ_?V67e#9X$0*$!npmhDv5 zUAFUz-B!$7vHOboD;BKS#F#r7{V3Td{gsn&3855*ZffP zW6e)BKiB+H^J~p-HNV&VQS)cbUp0T%{8RI9&3|$qxlHaWGcqf4GA|3VD6b>0E0@a^ za!9U}!?GmzldI%vxki@dh#Zw;a$HtqRZhrBIVGp%j9e@Cmj}oLgl%U8-*$ydwQ$k)o($=Ay_ z$T!M2$v4Zl$hXS3$+ydQ$al(j$#={5$oIhDC-)Mnn+xdKz%219t{+X99N?aAyN| z4shoJcOG!(19t&%7Xo(?a2Er232-ZcTLs*uz+DF1<-lD5+-l&kFS-i2tAV=)xNCvC z4!G-qy8*Zxfx8K~n}NFpxLbj{4Y=EZy92m8fx8R1yMen0xO;)S54ih*djPlxfy3V5 zVc;GC?or?#1MYF)o&fGi;GP2RY2cm#?pffT1MYd?UI6Yz;IPHN4BRWgy$alGz`YI} zHr6+RdkeU?fqMtIcY%8kxc7nk0Jsl<`v|y?f%^owPl5XkxX*$60=O@M`wFM1Gqnd`wO_gf%^xze}VfC_&&gw0pAyR z26z^D4tO4T0eBJkb%0+N_;TPYfDZv*349oM3HW}%R{>uQd=2n2@Dbpnz{h}(1FrzD z0-pdr3499pH1HYVYk}_%`~ctw0zU}&!N3mzekkzk0lz-*!+;+S{0QJj0zV4)(ZG)Z zegoh)1b!pnHwJza;5P++GvGG|ehc8Y1b!>vw+4PJ@Y?{tE%0@~j|09Q_y*v!z>f!h z0`L=oZv=ij;3om!1bj2_Ex@+|-v<0-;M;-k0KOCWF5ssCKNa|Cz)uH$2JqVhzXR|) z0>2aR-N5e*{7m3?0e%+nvw@!j{I0;y1%5Z+=K;Sv@biIR0Q?@nF9d!O@OuKk7x0UL zUjqD6;FkfvH}Lxazc29n0lz=+2LQhu_yd7I2>646UjaM-e+cl00)H6rhXa2E@J9lF z6!1p_e+=-)0)HIv#{+)?@FxO)67VMje+uxY0)HCtrvrZm@Mi*l7Vu{Se-7~H0)HOx z=L3HM@D~Dq5%3oSe+lp_fnNpurNCbX{N=!30sLy}yK(Y9Oz;))~MZmKV? zIHGNk7Qq!qw0+N@xZ;Smg;@fwIHK)I2EY|Zw9Um5am5jB&#ec_0>OAN(3N(|X;ae}60|J^J8sot z?TRaoXgdXVg01DQzILsMp!<1DVB|{LTd+TPaa?ia8uBWRD~??6ZD*^eo5(I0t~hcl z+4|v%BX^KRQCxB4ZZfkobMdV^(Y^7Vk}Iw_av!<$2v;0=urO0DxZ=noWEKcl9C@5f z?UhY0yiEc!zBSD~j}cN&kw-CHapYODvWKazoBIra4YLt>fvktvFv3M~#gUiE$zJqD zaK(|=$fX2aapX;Mu(zLLxZ=n=Djfm;t}!r5#uZ0Ll87Z9 zE%4#|eF=&%GmB%$BRH-&x>0d^>%=0uDcM^>7$3_AR~+4f%q=D6gDZ}1O}3VrHEO_m z04KUF85PA9N9!Hg^v4xP$2(N%*d-k^c7#$!@64t~jnZx)XV2tX@92 z;^<7WPI_2lEamBP(b;4=%xan^-umH+qjSlz*6L{1zYDH7x_d#E@~zf>&o#OSnc7M+ zpCt=TD!M1x*=j3qr+0<;s5n2&UGulKoh9Tuz?yrDuM1^1y0=eawq)`XYqKNT&nGdx zHta~6=yGzfm4JSQt+~$Luns0WTU6wqBA=<;+&Fp&Sr4{8b5UGz^lzJ!&19DRT+ok4h zm~S5A>%bL9pCrqk;EJQqkY`a`arAjID~>CUzC?C`amCSB$vhygIQj+|mx?QnzD-^} zxZ>!0WYBY5ar8s-FCAAL{lwj`7_K<_Ir-HV@Q3v=zLQRK*~a#-$h=fsar9gFL^OGv zpg3^F(I3dX6kKuiXYvS!D~|p~wk6?;qkk64d*O zlS!uMxZ+rh{2jM83$j7ik<8h@Npo}HieoBCIc}5sOL^mpV<{4I;G$f`3>u~lR~)Mi z`dCGA#j$}wAB(oZ+BGZ^?OMCyiep1atXL#cap&sX6IUEtpOhSU$btfL;EH1-$Z53w z!c>71CGUnSj*TX7Ck)m}{U&b@Tybne5^!9Ac1_*}#o!bqY?51P_`18{ieoJ#E3{_UEp>$!{ zbf!k)cE*Drt~drHp? z%~P-DOY(~t}K`9V^@%pBlaDP-<+!( zt~hoTxjWjQyF2aG;)xqA19n_->{=3W^h*vAs;2y2zALUcb_2;c_>(2b;C$Q@R~);U zwAU`KICdMQ;UJLp8i`zpD~{bs={N#9$F3<6R~);Cq#V)XBjvyq$L=S0M;N=i7r_E~ zq&V3=efJJ4M-B~LPh4^AKavmJ9ec>*Hj*7z9PdlAf%_E?Sv#&c&XJ~L*U-BpEKysC zD~^k#)sx0*Y~bmW``na1Uf!EhGzhQ-xZ-#v$$Hbb9MNQX;=s7#ct1*FE#ZpeH6$K* zP&T8$1y>x8l2qV^Whsi>#J(^@6;gC8<^qM26;~Wjl1kv_Y0Xz2ENRlq3g9>K49WK- z<_mGf@d2due}gNI52myniv{n(rJB#7k&OYym^b?4isS21I%^(R93M`)fxAUZwff?U zHUcdt~frHqyi5BmYUEq=EN1p>w1+lE3P=+(5oVI;ELlDNX_xK&JrI^uB;2LIKG{K zhMW@qxZ-#-sW~?Fd@|&VD~`93n0G+fF}yS}HUY{`TyeZ3K)%c{D1s}FPa!e)orBVF z#qsH+&sYU#2Yd~n6_-AL1WG3%x2k1LMPCspr7jhCvnJ88}qyl}b)NIFK1U=aeRN0^d308B#jbq;ELl1_N-Jb zJ8Wi96yl2GD@fgYzG2I(S*p1ivjG;i;fmvjlA`y5*sKwXb(5&7eaGe3s)S!lJt6uD~?}7Dr*Q=9KYV9&`eZmskq|!O{BQiaK-UkNq+6&isN^X{+h)V z$L}W1UgL`6_mPYruGOcmkb3NbD~>-%l71vhAIT!P;`k$^z2Pq95VP7?X~PxApC!FDh%1i2K!PrPaPSOzbvrT=KZ$_%9^x*U6VAp2ro(e?wex z{CD7AGa-d>?JZqN$h{o;H~z1}Ae}h=pVCJuQ~Cn`2JmkJ{}%9XuTofrQ+P!H{vF`o z1^zt{HzW@5h-tI%!2X79ix=%aXV%i}?0HKUEyj~X_(k$%OKd-^UodmY5BFI4zGTZ|ets%y!d#Y;x*y~l`U_=iyqbC%3s zx@gZ)iBiq4?turN>_n_|Hvtvoc)S5ZTSj z2xX))N*S$;Q8obn3*f&5{wv_W2L2o1zrCz%wz4r1oR!V`OhI-t@ZV_!XW)NWp#_u` zER6xQ=bXh$_iLHC$DD?FOZHqab3Z(2IR`Um#6a!?G&w{3cs$;*^Q>>1!~lz#kJF1E>bR5E>Tu0tCUNX%aqHNE0opBmC9Ah)yg%>waRtM z^~w#(jmk~R&B`sxt;%i6?aCd>oyuLx-O4@6y~=&c{mKK%gUUn7!^$Jdqsn8-&hF-o61|t+sZr2yUKgY`^pE(hssCF z$I2(lr^;u_=gJq#m&#Yl*UC4_x5{_Q_sS2-kIGNV&&n^#ugY)A@5&#_pUPj#-^xGA zzsi4VAGJ*Ft1>F9aw@M1s;I7`uB(=-6>3PWRKu#I_EW3WYPCj{)rcBZV`^MgR8>u= zNj0UW)r?xJ_E!g}1Jyz5V0DN(R9#P9Umd0nS4XHL)luqbb&R@!x}my}y0N;6x~aOE zy1BZAx~006y0to1-A3J3ty9OT^=gBfRmZCn)QM`Nx}7>nZBm=n7PVDvQzxtKYKPjX zcBxa;sp>R!x;jJMUfn_6QQb-HR(Doss=KJO)YQPS7pjZY zJ=ML`#p)7usk%(vTir+9SKUwDUp+uwt{$i!q#mrUP(eLJJybnRJzPCPJyJbNJz7Qb z?~lO$1pLpy{{sB4!2bq3jzxa}|0nQ&0slAf{{a6l@c)6(2ZS;Z`hviKz=FVmz=I%w zAcC+C2n4A0Kz~J27xdbgdrdd1z|l9)(2r22*W`b0m4WSMu9LIgfSp&0K$eKYy`r_ zAZ!A{rXXwv!sZ}s0m7CbYz4yBAdCfJ8xXbyp$>#`Ak>4<074do@gPh9VIl~PAZ!Q1 zBoLZFXa=DLgjNvRK$r|dI|v;hbb`;}R-5OxP)J_rjy*aL)xAS?o5PZ0J3VKE3xKv)XGG7$C# zVIL6o1z|rB_6Okr5SD{*AP5J6a4-lfKmZU90pU;(4g=wE5RL%hNDz(!;b;(!0pVB> zjsxL%5KaK$L=a8_;bag_0pU~-P6Od|5Y7PMOc2fj;cO7j0pVN_&I93m5H0}WLJ%$j z;bIUj0bwNwt3bFEgv&s<9E2-CSPjCJAY28))gW90!nGh=2g3Cr+yKIjAlwAP%^=(Y z!mS|O2Ey$i+yTO!AlwDQ-5}fp!o48e2g3azJOILjAUp)Z!yr5Y!lNKO2EyYYJORR! zAUp-a(;z$p!m}Ve2g36pya2+BAiM;^%OJc0!mA*>2EywgyaB?SAiM>_+aSCH!n+{6 z2g3Uxd;r3SAbbSE#~^$H!lxj72Eykcd;!9jAbbVF*C2cY!nYuN2g3It`~bp_Ap8Wv z&mjB)!ml9w2Ey+k`~kwBAp8Zw-yr-0!oMK=2Vx%(%RuZ4A_F1|A_pQ5q5z@@;yNI% z3t~Bl6(EK{tOPL(q6A_;5UW6}2C)W28N>*PQ4nJw#z9m-R6$IDm;^BeVj9E@h_xX0 z2XO$113?@F;$RSmfH)My^*~%7#9<%~2XO?5BS9Pm;%E@ZfVhD<8mTAH95o=@T0NPJ zec9IPX=GA_ZLOY3MnT!u>N#Xx0^3?WpBw_Pt<{Ujutc`Cx{{nq9KXx^-qQD0^|IW9 z1Z7*RtI1)E3B$&>#|>Hh7#jk_vO3WhKQyj?MH>IF!}B`pCKx~=^=fkO0oz)=jvQT} z)p&>00R50GsDwzc{& z8J5bnRv#m;9FploaP6S6L-Oi#A8`Z?M6 znr*FqMKVR$*6O!p}A>pOI zsSz*27<1{wj^tr^aMQz>cw2CfiJi&Vg8cQTRwrgTwEd{niCxLqhgzMOM+O!wvkSF4 zv4Ct!qgE#tk&iF6IYATAkRJEG-f2My*a9Kt`4bHtABH)at}R3fzP9l3t2>Vm3 z6Q`27rNn%w)rm96)>5-Z4Or=XiL=S5D789qo+F$7)at~A4poERW2aUpE+I3^)A&%U z6PJ>052)3NE6A~j)at}l^sI&lN}Dpp@tYIWjfvKwl% zD^9IW+(up*tCtV8I&mjiCq1lns7>y+M&cea9cDGngOB~F)rtGbvDWHn_AD;c>cm3@ zS@NP*CmtnJTS?}#WPu$go*+A0ZRPEXP^%M9lkWg)?k&D9)at}@K8Y29N+e$NNldQ| zJGDCT3OU$HK)=b@TxX+JCtfEzTU6wqBA+Rvs^22(!PaLkO07=3OFl!aKE~ZjZ)$bo z19Iwbb;@VoaJN?E#|4SFwNyK`I`J7f*_yYpXz`*}C%z!# zA32potxonOm*CXuBuDloP^*(7IRvCuC(FrrO;D?om2OJr_FDSRAs>It&9vatlJOPAX*S43Z+$>SU6ff>NuKnOtUyQmc~#$g(HY>f~VZEK03Tu199YsnyBh zWEYrPog78x0jbr=4am4uYISmB^75fpCpRO5o>QxnTath2)av9|cfVrP>SP`H1*TRf z8_2v=YISmgdm^0##V({)C$}T>QmEC*X7UI|txmR)ZAsMXWJjUA7qvP$g=~XTtCQ1< zSlg)8$sG#w;YF=Zc9U&jYISlKGItPB)&#XWIfsNDH$e-~uKE=c4Oxe;634f;H*23@ z?6yL4le-01@~2iO=aZ7-x}`^+axbCWsMX1ZB-3+hb#gEAcU;~r$Ohd?GiU!M)X(7Q z=H{Qtr6lFJRO~P1O|4GuLt+kUn5&p8wK}f~`G;J620 zkY{>&8*tjz08bf|c7((rY6qgE#` zCmCmiy2}{*UN&lV@=BM-Frb;msnyAA$h~LO>g4t0>!?Xb(w@}nKTAqoqVvUSa51}@(~j2 z4YfM?I4Stnq}!HK@~NT;=L*w{TAh5B6dWzswNPED)yWsg-7y~7-3zJJ$(PBg_tfg- zYoz1oOpU}1I1i)Erv zk75N};^app;!&p_A{J_O@>6o3YRBGL9?8Le?isZ@`2{7ihN;!buSwLShrkDSf|q^;s7;RRBV?JEy0mPD%5B3vlEC6 zHJP ziY0eP`*U}vy;^r_bxI%+N5A9{p=!$S<-1a=Q|pq914CMZj32c+6(a4mORY{xl!gOD zw-%_?scK5c5zsk=QHj**RD`4)(c>fKpjM~iQsW19CdHOGI`@C$KgS{ zN!|5zZJk~1S*<6**ZkSK4t%eW>i|+|()Q*mIkYKKHEx|hwK~z~uwGruggTB1=ys6cxO-Zx#fb^$Ur?%+nle<%^Q(KdsH^|NV$vvpmsclKnF?IB= zUrW`vQma$-B-fKJqd2uXHJ-EsH*RZI4XCI)wK~;E!rqiH??T1BT6b!7s);1MDN7DX zvo!{zR;OA?J#c$6)xD_Isdm!y#)Nt0)?k_yQma#4q&V3=efJJ4M-B~LPil2)8p#Ll zjy>dYU(QagPHj)Jf%_E?Sv$2lwG(MNb`8Bt!VL z^rTj&=8~*8gv}96mM0EOtxoMuNvtJmb!rb14?HNFQQ$(YPVGrjfg6^kC~_0~!Vq0T zijKuxpm4HMt5bWEO5o;c%~ud=b!tD7?@7!TQma$TN$dZHTAezW(sC>oybG6VzDLyR z)FG74nx|H$4kz8f-J+#heW}%{qewPz6q^mgn_8VZmJ}VE3H}AGO$Xhn)u|ImttXQr z4{CMlLjnqo-Ph6YQHX%u20Jo!_e>b5N^O7m=Fd zZJi}PoOoduYISO*e}z zQ`eE0`_4gW)aulYq~twHISb#NTAjLuRJ_}@y_^D2t5dg=pm(?9%$7g3I&~MRId<55 zV#0%3ow}D~yeFNuja5sR?MJOnJwTe?i&-yCe`iO3o>bNlwK~0yN1>U-S|4n&)=9K<)Q``$x3{(%g;qg| zYmHi+4wL-aqgJP@NPo>ztJ5-R_L^Fqj**NXwb!Sv+^N-Rl_dRuraqEIsMYBdX|H)| zb-K0}#o$h@P7fqWmxgY(0?T+AfLfg%LV9bETAf~>1YP>z;2HF$R;NdhxJ$PH#ohYn)o0-iBn?HnloE zj#62R)arDW5?EW*>hwfX?_ITeP^;6ENZPM`mj;%`g-f1Voo*pvp z(v$lPzUZPAV~ihkrl%u&I^C6?lAfBL2I9sbZUW+_Aa1rQJtMt+dWZCmAZ`xg79eg3 z;?w_sv!|3V!>18?Kbb4tHI4y3wGQD?tpY*;U)`2(<#QL=ZoK7D^kA5(S4JL3p zeMtIf1Wu<9O&^v%Jbgs^$n;SlW@RI(-%rr_*PH*km$3)7s9sKeTAwKIQ2P5il(sl)fl^ar%<<%Ji!A zrRmGkm#42tuTEc?zAAln`kM5$>Fd(hr*BB#n7%1}bNZI_t?Ap+x2Nw&-F3hVr(a0Fn0_h!a{86@ ztLfL$uczNgznOk3{dW4D^tF?6tr+-NQnEomKbNZL`uj${?zo-95|C#qK%4^NR1mR)nhxR&5Vr?$2N1Dq+6lyN5O)S~CWyO$I19wtAkG1CR}iti?grvK z5O)W0K8OoI+ylggAT9!NPZ0M4aWRNXKwJvqG7$F$aUT$|HSGuD{vaLz;&KoV1o0pc zG5A-22p}E;;-MfO2IAo$9s%N!AY$Mj4dO8%9t+}eARZ6m2_T*b;z=N$4B{yuo(ke= zAf68586chs;#nYKWSj%yxgeeg;`tz60OExpUIgOBAYKCEN)T6pcqxdNfp|HHSAe)0 z#4AC(3dE~HyavQ;LA(yc>p{E$#2Z1p2}EpKw}5ynh_``wJBW9HcqfQ=fp|BF_kegW zi1&ebKZp;2_#lW6f%q_pkAV0nh>wBzIEYVx_#}u=nZcUT=If+?MhP2XcNFvxriBUVi%k;m(gZx{@t&}2hM0S zuV8?;%w(FS1!AjZI?1#|wpwN?IrW6CmYG4GB{8`&JCciqx8%dy%Ixg0^&w4VW;twq zI8K>e^=!AzoHc*u+<6PH-$Z96$~kcZdAB|J+_+<{+{j zVzqXw0y`=v1LQQw>Vz-LG`^=7DkpOoxeTfuG3$s9wbh#VspMZe*dlX=yI(P|MdobsE0t7{Igh*waTuNMq>9XiWbVqHz?1%X zd$^-B+iZl_C1mS3y}Kp|3z7PIXlj$6gcazHH+NM&fG>)j=L1OUBPe)X^dIq?so4LQJSnzwgnTJTMH}`ZikCH-(_gynjkkeYeP?>p} z66xJ_#msZ0u?Ft*WnLs9$8jbj1n?rJ%LcT^eZI^qq~y2+)g>Nx7%)xD{7e!$lXyh?(RjdsAWDTrJme3DSkyQ^BHOP zZkH=@5+d8Lrk85q1Zj7nll$1mBs7#SNUzzVo))DUBIW%Q$ zcfK+|k%;$^8}G+-zw?#(mGr!i$$9H}-}%b?L7LvjJ7$gEp=fz_^Sq(^ov+$* z681i0=T`k1z0IJ=R6ul47I;zs5 zIH?7{YJ=2@x(WD^0i(>vl3GtjNRJCZwRJtsp4$bW+6Gc9y-~Sb0IHopQh|qVOS!pT z0IJ=tSI_CVwNu+nYK}FxB^;gCD||1>)VBE-n*H*J?Gi>k;anc68N=Dv0* z?UGFGbW-x}&YZ<%>3*79r(})T-+@%TTar`7|4vJ7H>vgdPD|}BB;!4?c3FCB_xt?s zpVZDFRqqLwm#TL3)$Flz1(3Vb(P$nZuHCI?dDhfD@1NAp??s-CS(fMhliG!(?mdh3 zFA>+9BDH(yt=f&=d-d8(n_a{B?8JtDW^`=39 z%NVr>QW9(LGDhu+HK6Zv8Kd@4(q9wT6>5(lr8RP+p!R5zT5CtyYmd{)v|}lvW@lxz z+Z6lHS&X}g=DAy+!`Jk(ys2?U-MB{VC#HAn`#3mr?95Ky;f0i1z^8Qd8}aiM~HB1AzEkl_NASV!H~ zx-Wd+Y0vvKCb_TcyY8DvBDyYdUFy2b zl@H=vG}>G;+FUW(T;-#a5*JZI;wo|_GS@ZfBApK?o#DG5|M`P|@kxWf{kY$^zv`h> zcqx6o21h0vl9Cf*BjSp0vax8BbG*R)Z#M~Nxz;TAZ&uz`wDS4?k?{Tg%_h5xHo5RW zvWb83O@vhNxjEN;uKR`OLRUWLl)KQC&pG9#E4wBcVht2Cs&z!1p`EFyNnZ!xi0d)a zv-$MX<$rwk*XNybJ!5(vjT$^u8&+FyFPJ!>iW#}x$6tpm#(i|U%S3B+7uXV zZWwKD8Ex(uZSEOu9vE#N8Eu{zZJrrzUKnj&8EtsZJEP49qs=Fy&1a)j7^P-LsfAH$ zWt7?&rM5mRP4UB9>qH;J2>o4K2Xo28qT zo3)#bo7BzLt%O@iw^D9)Zl&Gq-O9Letdmh%!6>a{lsX%wRgBVVMyZQY>SmP6j8b=_ z)WayPZj{zAN^2UWwT#l*Mrj?RRBn`d8KvGvslq5#8l^r)sjpG$XO#LIr2*fZQEugn zrsXkd2D>2y58P?0lq=nVBbKw#y?0c_Y2Sl%hhUMt=wOyRV%as{s93x z-(qKtn{&}ZH@{m*9jw%=wH&F`Y87%nAB9e?(&+u!>R(unYqG+Lq-!0^;@lgb5RZ6*^*4Lkid~|XR^_2&!0~HD_W%u>* zD;|-5(L#^ETPPq{=Nl00tC0sORV<_oq}ajQAi0JWg4GJ0CQ$uNM0JZ6divc$`T&)` zpF-~|*9NI+e-QoC1S-{Xh0@o@U*Sh|e){4OH7Z)@`F9KX1?v430loq90AIf#xnH0{ zBUkzB^m3iQzrWH?7pPLJzL_Ik(Lyi3TgW$1sR|6zY2_-tmeh0_1ta96mn+GVf+>S^ z%5N45DO%|DcMIu*1O5F}IzM@EfHIgGsRK<5DdkFKklH6u?WgqBeUn=f0c?+)=(Zlm6nBqeEj8lrN6&Uq4CoPD!(~JdKE47<-3La z0(E+gMiVU82dinnX&}`;!G3bRS`(=C4N&?8emh5f3Kx<}zFSD?991xda5LeS;Oj0SYZ=Tk(Yk7A<7`-9joKAEl38 zPmNSMnjYjsYFb~FJRpFs>HPzA3WcipLa9XyNxxf2p;jrm^eE*zp8yT1`2}#&>H_83 z0KXuAUu9r$fcBfqNP5viCB9oo8_dNvKpA8jWoi_p=3Jw`@?bwjph~L^@(tGMibpiM zXrWTyEu_~3>y?24I=LcP=fl;F$yNpUYvdZAz(7@?I#3nt|4l^Wixw*V-9ieQt@91^ zkp~3@Gui4OEyX4*MWCNX$u(E6)qHdIPbpfc%=Zf^6n^JZW(S1c=h8p-zY7=&}x%W za@h1oJ1U0#`RYp-ADPnM5SQE{KCxQ8l)C;mD`vT!G96aD zkY86k=XU;ISN!@=uG^)5_s~_h-%Sr)GfF-Gn>cQ{-T8MbK5%ugzkA3|W^a0^_*i{C%0cF2dZ>6g zzCKh*=4^WCAM%p9$lOd16>sL(qda9b{@qb^WL~C+{vlcyU_v@9Uhkeuzg;)| zj@-Xp;cfm_$*6(JQH8+Uq;6#CAS}}3g{8w*SdSlh)7L* zd_Vq7n^IZluR;%ynf?r)EK!yuOEyZI8>KCb(w2*517(9`gN@QwMrmK8w3F%Lsi1r6 z$mE!TG08*P8WQ3YleO#>YcTxO3^BOcSvZ0>FGS=^xZ?@ zG0Cxp!avq18!m<}m5q?4%Z##-vLB4nP@}ZHQQFxk?QWFzN>_ZHkukFIrqIXAew2+f zN?RMHZH&^ki)9mJ6J?W((lDbm+$e2l3f=R&&Ay4Wbz)3>B3bcQ0{`bHYWOn%VTOc= z#E9hhME*XK|NQKtJ=#aarWj<6ZA9Tek;28pOt^IWX7a!0GgCJApYoX}%P_T~gHhVC zuoawhMgO#MX{SkviH-Vt{9@Vie>#4JY^7|KQQE~Q?P`>EOIOMo+ZP?*wyw*6J_$F- zw*1qATV>m1+l|s5Mrlu@G=c>iJu6!9&+M|LXG96v9_hKzGEQTACB()gB`Xv;5;JoP zODp5Zj_v~uiAhXBNB8(%eK|prI=M%fP8RMCcTbK_C@UmmeqC?xYHd^6zEWjp&+4`P z0|Hg9K@EcSO`3*;hPCh9txsIyz@fw1xyPl%#-5kjmMB@uu460yM7Zg?(%wBXHXxncPBVfFH$~Ylq+L=(AH!b< z)7_$lO@S7>*X8R0dP9Wi`V?kJPNs56#hy~SXhlGF zHENt*CcW$;jW)epxun%*;4+mN5h9C82*05Uf5e@ zH*4OaW#^*C#ZkA8MK=wFMUCO26CcOrWl@V(RJ-VH4vuKurhBWfmMO^*T)EYWi4j8< zw{F{tMit)X@$hzq`TzM0-CxTr4sX$lhdXrSs{XHaU(~79Kitc+yLA0?5*Br7b)kEY zo)NaaBBKnw*{*}>GEehOSHt)?(}l0_7Ys{SLPVtL+RtN!f7@2!1Qp(?Q3$QVMQLxI zUOBy5PIOFP+kUZ4`iHj)3(>XX|Fl}xE&PIDFHLt&ubLfin=pX8yrLqKBSOoRi58+v zbVNcztQphQKQ1}3Nn3TNj-5KYSmz5HQC^f5UZQkFWKx3ZkI9$@Fpj{A2C?}6zqu$R zreB|zo7O7+$p6D_%P5AO=k3RksHDjLLP+WhVSO($Au(A9sXO<}1|=t$Za3w&LqC3) z0JpmeVN>$YW4T*Y`}$Lmn$SU)CJ}rgaq;o;apB99>6^-?r~J?U(?2%F6u0T0YABi1 zFRVHL^&}UQYF}|(o`L%?ws2^p}1sC0K(Ys%Kb5jg%+`lDhV3_It!kC9fYfW*o zm&L`t5zSh2n+uS|D?@A()AL!!vQk2FYtx$i+EN!6+sd?WV{XqhBo*e%uPrYoM~9nw z<|BlaTXJH!=~!a33hy1G58<|++k>MMo0{$?U#ooyv4wL+O{_j8rnEKXPL9@kLtHyk z4NY^A9+4Q_gxl20dXH!?i4X=6FM9F+ks?l97cL@6#E5}~xB7?((H|~EPzOzTRvZ#} zMv~~q{e8H7`>)4Mzcw9VIwpZf;ze(s8Ow2B?{yJT9A9*tX^nW8eq~zsUg5ftf9~hS ze%h)_MGB8ci$^>j&8?QApzxl-#Mhr+Yq>Xt$NF%)_%1%ok&kFy7;8}srpHaY-2Zcz zc#eoF+^gs~Q}8p4dDilpWsY#+ zzqc$eSl;8-70Z17z4TW+t&7crsrIJHiQ)fa$non06irrS;XS5a#PYAHFW<-cch8E} z`Ii+W=7sy3W>#IeifO|7!_-+rVPBiDe+2zVqS`6UscAOkOic0K741^&3^~ zIC1}R;j+el=dr?F3afp=Vn^5WC6A`{j+`t22=s5^ycot?~1X=iO$%g*0UZ6~pF?;3N zkD_zj6o=`2H%-{r>%!kxu}(btbrMYZMKcG9h1aZzKlA<999_Q2(sV_ODSlQ-N^xcu z?NoG4_`2uUx)x5zH)mEmc8U>$h$E4@n$Gq(t|cztJjZk;HeH37NJ*E%9{$6bU{TdV zX%WJeDO9*vs4e_08vl9QbhWC_zou(d(bZdS(TGPITIeiPrt4Vo3|PIWUZyMBKSy8u z%rIEhwW@9vY*oE*?ZWJ=bXHBR^uonTX}aIa+o~D2gG|p#<~257Z-h2JVMt<3pXg+l zqR%OW#6^15aq&?o`RZnR&18Cx5HH&lz7~==os3LL99VRph3P+*yp>y8IEadTRh9A8 zT25Ahq8?u}gLw@QD#Ar4(VaY^>0~06O%p~jMobV>#SAf5{34c!m13RPB({q^;($0J zvcy?&L0sYM$!+maJQHukM~OsYEh!}_C#fi@Ch?HemiS0il7^CCNef9^Nhe89Ngqj^ zBt?=Y`9U&4GEFj9vQV;8vQe^AazJuia!ztda$Ry?@Y&P3$k=YuvZDt3|vdk`+6_`CVdu=YvOPD*EyPC_*Rpwgr zQ1i~_z0DKNhntT#pJ~3xd>z+-qvq$$3(OyxzqhcmC}-hfA*YK?E!tT`S`4rlZZXkf zuEh$AZ5Ejp=Pj;VJhS+0S<2GcvbJSi%MiZ+S=N>qIGTS2G*h05!T7pW31;`ud)8kI@|iT z^*fsqHq~r=Z1gsrZQ^W3+RU_BWwXyF+vcv#N2$HkLt0lFDvgp3kxr2=k?xY7k=~Ym zv@K&>-L`>kxNTosqwQ?lb+(6X^KD<2C{e<#L{Nz~C1OgXmzZ5*Ly2Q0u9tXUvTVs( zCAB5HmP{!*x#aSa`%7Lb`La~0Ql6z6m+D+9xzyxRD@z?Jb*o_IvP@{1 z{$(bXSykqEnR{ie%X*d#E*n*LRN2L450$-H&b*wgoVHwKxgW|cDR;QsZ3iod>JA|e zeH|t^taUi;@XWESqn~4Y$H9*C9QQgFIGH+S7+Czt|@#@<+STZx9V=~+(x>sce^UHm8oRC zWz%H`WzXEJxwmvrb6@R#*+c4~@`(1B<#E*Gt!H)54xVE@w|m~JUZHwO^`X^QSI@6e zsz#$418OX)kyF#ErmAMYn)7R(tz}lrzgBdud9}{eHme;_JEr#h+UM$6)(NT;S7%Y3 zTzN^kT0T&|T7KQj$*YCeNU!Z)PrTi|JA41+eboE2!e0@~SGOz5vdU)4k;+}l7e2Lo zB7Nrhwk_{$u?Q`u`CS7?2pSF5rHkdtlGNjKEx# zgQ~S^qUuM2=B>7_c9?d*&Ro|- zH(qx-xNLB{;JLxq^lth-`qlbpP5hgrHre0QvT5_CKQ+w_sS*+yvNGgZv%qGmxf&4bGfjvIV(NUb5` zhTI*hAG$QvA~iDgV47>1G41*=^{|D*CBu6SKR7}*V$_J+=}ppC7;TOHjHgB_Mot^~ z>W2>5>NRQjl!qnnIgJ;rWK;+WjA^~V14qs5OgKb{`vJ8sUn&*P)UpO~PSFmuAE ziIEdeOj1soJ?YEj-jh#H37E2As@2rEsTY50^wWxIWu^_CcJt?!KX04vGJX8?S2KFd zI6l*F<}b5sXQj+4nB8Lbjydjgrq1~^H+t@cd763aGn_NVWxSmqH9vbn;|1$}sq)K& zUq1XA^K0J1CJVPM@?11?vDM;%i|;IHzvSpr)zX#ADlMC^?2qMf%L`VtU6HvmaOKKX z&a0-ZHd~#t`u>`(YtF9Kt=+LszHZ@qr}Yyyhz%(l9&GHn@#3cDn+|SPZCh0RP+iUmoJ+6D^?RDHcWuNW7QTx99HuSgG z`xEv*I?(69&4WD-UOCk9P)=r>%+rUPA3kHncww?|+z3oiknH^_?&h9!_|J=UpM%f3>>&_p^3CYR2(CWgui|sDv<#x?2 z$cxImcPaML^UDJ-f4q{;i}>+Z?XS+f=6r3@?=^p4Ul35R_qy)-$s1ueuH1~g`S4cK ztxvZ{-6?fv=G|&{SKjlvx97h8{@Djz9^8JI@bKfKF^|hU&UjMe$(E;$pPqcy@!9R? ziO;{hnE0~d%jK{9ULAbh`t`Lp{oj0iJN{k8cPrkj-XHzY;ltgJgFab*n*B%3KX!d? z{yG0k|1V$CtMIL#q~vaYeV<9kH((YgrL^LkL8hBLI%x1W-|ks7q}4aS<{7DJeCww0 zdq0a(P2YGLKBDk@LVta;Evo4ImW$H)))U_=`q%q=*q3e<*4!|}5LNh=0^cP)_rs|0 z#Q6B+bP3<>DI+TJx}@k;Nf%zVMT-Gquox}IigCOOnISTG1+t#kA6vvWu~Y08d&O_O z3OOw<@e1TVuRi{eSV^Rk61@H>EvYJzNg7Ku5}l;EBvjHy5+-TK>yIvyZjv672ws0o zlWdh7m7J8EmYkJj^SUEna!pboxhc6VxhuJEW^LwbCNuLet7YbI){xg8t;{-@bv5f} z7H>AlEX{11*-W!}X6wv0nq`_DH#=)~-t3y$9kZ9b{%|y}VD4;Q)!fD0&Ahg`!aTsd zp?PC-jk(S|#Jr8eUWeZtG99uVE;?LwxZ&{B;f2E&M+?W2j-?$P9BVq(aa22o@pZ9F z(JMAHNzs4F|C@gtyBW=X{`zh5-(8m0Zy zl||3I^Vc(re*HiU{nhlt+xQ@)?6Eks-oCU%Dtjt>#zzRRy8bSEC3`J8jc=KuP*N>~3en$}V=SKj%3xCL_7vBo?<{h_W z(>HRxdB4sO8=qiE^yb5=$-Uzf`zLwxHd<&{M=w4MTX;vY=kR9YUk@im_45uJl9X)d z@7*G%S0dlN_SPrzo$W#KiT#qin;R1246$Clzux2BzUVEHByY8MQ$s`)zw(Yx^6nLp zWbleEo`YRc4k zO(gFSa!%}Th>Bq*lf2^MW8$I=|FVWxFVovi?9nTw&$nw7y?OiBPk$U!TTRFaVyGXSP%Ox|KD_l`ARhO;mxman^L_f6<$VM`~DH8(!XE6yejEigt&j!ssX(k1uHyzC;uWJuOckkbMQU1+cq-DriYic_ ziqxkfy{gz9i5QKs7>8+CfW=r3_N}-V>|K$)D_+1oycMDn>sKPbO5|6G{3?-OB`+w@ z3;jTDl@h={l}2DZrh|4d;=BXrK|P%FK)h8P5d_w+!aP+O24bwT9ILPf>#zazwF>7(71pV;8)uOX z=B>&_ux6FZxQRQU=2aem+^U%N`iMVxPq+lAPgPgQ-~sZk>WBJhie_kmR_K6kpg&d9 zKzvoHVb$rN7gc9tF6cjRmx`*yUUemiy(+O+y~g|NrNG+Ns8O{aLI0{zmuloyZ4YmFdxF;>mulovja*#JU;!)Gz!qgt0S(Xz@feI$P+J$~$z>wu zU>@d!Ub!p;@w*Ve3-P!RkIQ!K!X7ZoE(dT3_l0n^L>;t6B4*)N-W#uhTHrBvFEC5) zKA^Vl0Z^eXsD*n&G=>Jun7ba--ksXJw*a+wZw>Zv4@Y}+L}zpbbLY<7xziW-DD*}& z`XUx_NC5G`V5HN!UtY8CMl!P7ZQ5FtxLIqTUGpfP`Zg7VuYM>VCzzYiazz+dX zp)Ts9AsRyi9rS1lt_2>gz;(tW9Grh1oxwTi(G!vAjTpp&8TUv;3I>B&_ZSW%Mqw<* zgX@yVRQ!yY;2iMC0Q2v$2+Y363UJNxSci?+0?q@EUD%8L;2iKcg5x*|&RLIaaK3uv z;R>$dI&R@E=!wT;&<~H7pcfvT#~$>-;|rfnp$DFvQ=Zh{lk1ZwwfE#)_N4Bfcx z27A_Ets04-CpD&lI@g$wqd1FfA!?FyO^&Zw5GsCf?f2L+xcC@7naXHfz*jzdFQQ#}4FMhkWahZ=D2iT%A?`XcAK@?bE#a`Kc@Z~1I2#9|Pm{2m_g**50Ei#hNr4KL7JuOM_p1R`O?cud50 z><7K_V&=Sut?XoE0NWA7g@8XK?^yOD?MxG97}K#CHm1L~z94n-?; zKqsVNIMT5K8$sO_rsE&si4aO^ttN^kfK|Ot`r!V#NWgTDE@ns#q@^FD0G-!^N7zAqIHxksqZx{A}I`~lsKkDFbkBX>_ zMqq#cW{5=!Si_$>_)`ae>fp~h{;cEAI{ut@{-!mkM}Q5=fSdwq!599ZCIQqWfSLph z0kH&(!WwJ^IR%`>C0xNLAp)7rK(0H1Y7k3c3nU>8^fhoXI6iP4&Lbb!`0Sz?ms|A%x2xPZ~*nJOFiq7L*4!uh{2$abr*s>>Yl@8kV8EIj;}`!^=iWp z0U-W*#9xp2>rDa2*PDy|IF2k3bA4j2Pt5h@;JErKv;)W0?+Nm*KM|8b-RpCF{evLx z`mga;hz8E^Ky|c1XRvnzde(qBXu$prn1Kenum`y)zzsgbN$d^Dy&<_bYyjrDA^A6? zcMa1p91E}=|i?9TTa1y8SP6)LG=J13!I9}ZvozMm2@iS(CeAVQuCSNr(q9#}MEg>|_ zyoPu+<-nY18lo}SUy}^_t)bo;*3irX`)e+MnrSUi3goP6nS<&rACXRr5>0aQK5W$Y93K!_m5}}~R z!OO4$)HwJVI7Uy6^mReJ`oS=QnbPmT0Z`*6)U-)S*nxUBp`J~sXOk%)mL_v?88>lT zh^Ez{fDZ;>DAK_GP1l3kH@$_&cq&8)vl&9pAsiDD4UP#(!WQhsZ+L>Yc+cmniMbgu zHzVd|#N3RSn-O!ft=NbCLNpg(cAHbv=FDC5rr?}yJ_f|y{3jg6S!4^*!V0BP1{$zH z3u@P51bzgw(_$Nlr3H0qK|C#prv>q}WJX&OOG{>@Wq;7;mc-R^7pPy$!+d7j8uloQ z5VS=&(lHJba1dEIB}AwMwxI5z0U(D^HHKp>I3|>JLr;SoS~EYb$+dMUv_WTd1@qGS z7c2yG+WHy_glI$k+Gr6B>d}Tiwwa53+{Rr#2kwHJsEyu;#{kfmw)CYfwP^cAh%g%v zYZx^SWACsqOv5}dcVXvn8LS=dglcd_H?VGaG&u83i51s37jwO z=~ep*sDw`Fg(xrs?U{l0`-SL0JvummJv;DN2YSfNm!7Jyi~t;7TH zyl%wQJqWDTT?gveeGcY<$Gfvmch>3A8q~2z7w}k*C0K^Xc!PIB^z=o2Gz9(a$@6*= zQ_pK)UV7daB7%4#h$n)0A~s<+_6pI<7UkfG2=qlPHe(O=2@xp)&x;iim zJ_*s=64nR-d-o2<&&a?6T*3|95~5En_`)BY=Y5Re`qSq(9K#7AqRYVkc`*k%Tl12hZutbNcd}elpa77kExTp3{%#^g94z z>333ySk{SUomke1WuMqdn1Wk)jHmo@A!ejM^VYv5$f^H$OvFKC;S_&dh~C7}!?^Mw zuQ>9GBd@qEpwDsCAl?e4Q3mbN0};po=Sw^@8h;-z@Jfh;deA|SxmXOIm+(P|0p_4L z16rX2n9%_W8rGGcphl_8Q7ZjQZHKPtj-Kd+7{nqD1CWF? zjK(y~!8}mg)L*a+E3q2uK+LJsE0ubso&|BI(zDb{$OpAbr4Ol3z^tS)->Gl$UWha+ zltO8g0lB1ALKRel8{82Ha!G56aI{B9bOy7O7KPp*m$ZHuf{~blnV5~a$iQNdL)r?E zL)u#G2X#*)?zH=O1Ztf20}|L{dv3gREW3I{;lhd;z0 zLX2SV5kaVrM$jM_P0$I{X$1R?h(=!+!JZ?i)d>1MVg{(!2x1*U&quJw2;2Ji6+UxY|EgC)p4y#%OVx-+W671S`Dnxxl6ZO9RZ z6i|t50M4C}12F{bF>*L2U?L`g8jsAtR_wrT z>;ttNnF(q+@&rzSo{r>P8cAJ8UIMc?@-^P!BR&i9gMc}x=?~VhMM;!KSx}=NYM?Q~ z5r=VDg8ld%PlOmnUq&&{qp0I3@*PFKqvY^~3TkMeLre660nz9O)*Z#QV-zzyY7nUL zs9{J4L5`Y=S(poEYSgb-j#XHT4cLV3$U-jOio#DOjwZL!HYkBo2mmpRCWg_}dNlcr zrlzAe;xLYZ8je1NGdPDFA;wI?Ot9A&_8G(dW9|wu)*j{HhzejP#}fBgo-a5T|M5G) z%uR5C9DWEyT{M6WP0$Q25sHrJhMtH7eV;HHKY{v8pr#XuW5PTkCN@Vh27%Zo68l8X zfr(de4^Qy|%<;r`_#(t4GtlEn^mvjj=*6T8sEn#0)=42~0pgj|2H`?XW*#OJ|77By z9E5skh{m8#lQ&`qc4Hq7fZ3Q#eI`?%$>+fNH8~&GK~E+#50mN1l(JwRrVz&z=3z<| zT)<}`rb=J|EA+!)(4VRFXXG>zU&YXxdBjT%hrfbNJu6#9S}nwAK9Fl{J?f%vAe_cZpN z#@^G|d)j6pevSw6{X7rz!QMYF!V)2-mjby@cZEBuqZX8)?$fFJbYhxbAHiT|rZY3s zTca&fF&swx0OoN9$IM`kW-v!Hn4=lQJEJd{`57mWi))}3GpNOkyLf`N%Ub&!+CPH)0F6V?Pdp{b$qf z+4Ot%DcliajwQ;#6XY|8T;{OXoZd(PeVsEJQ}Hu62j|Sf9Atn#&Y{P1Sa%M2&AA9> zZO#>313At4BE(z^ID?wZ4T1*rW^OdbfpzCD1+z1k9Ojb4TymI84s*$2?k*h1Nl?SN z>@}BjYA)x>+&r+~+^hH`#5@-?2eHrl2@60E<}qvYmSYvxU>~T(Jl31Xdh>FS3*w(g z-1A=HBR&g}L4PyIA)^HBPzDZgLV2)f2EED%L|rrhvynkPGlIdKX0$^`bU}CYM1N4{ zj3f-i5TxQqP?wDHn20%`zZujhgBoQ}qYP@4L2WXqO~xMlh66YRW}4GX%r6CdlmoHO zuZYT!gE;5cLwz&^@y+iA1L({Aeux9{&7TeyoKFqsQ^WbxaQ<4X2R&H8UJF=bK?ji6 z0*+tIeT&Ue5|!YJ8t_L`G)F76K{z;eac6V`Yb=fgHCa3u)MW8+7%>WCL2VXK!cwzqb3tB9eg!pMLQR)!#1>H7CA&avmpl?; zDfL_08tEYar98eg8|1%~8C-e=*Ki%weGHORV#PU+$da=9=SbKRU&VgDiC%)yxw_-Bp zfqYkR-mYMtR??@HDHsImvocMHRen%I3ubo}y;@C7s{=qBtLuU|R+G;f_FiKK3s_?c zGOz%@VzCfw-9RpDmGA}YtfeMvKj0HS3$aduMj)?s+AcVFJdtcD{vA| zgxEkWHxTcJ&Y(UUW@90ifWmKB3F6zZ8~bno)PBQJ97i^O$1U6i^RVG5Uf?y}3bD}~ zW#I^FwXr&CK@J~~(?)XINZmI!Mku->9*Ic7V5DL=j2MNn7!UfrkzQ=1-y4a0<1!HU z#x+=vjiA08sqe<~Ahu0TV9!n6kq(aAbO<-_5Y%SVbG!sS+-wOOlz<(|fF5mToz2xy z2lRil9|BPy^n0@gI)tG;=+Wlh=!ZBAz(7#@&1oRN&66+}Yq0^Fu?;)12fyJU4&xZE z;2H`*{F`rqUTmfpn;(H(Hj~R{a@k@JZxGKG>bhkf_Tst_TLs8vYYo(f7ZeBrd29_v zQ#3~_FvDA!wXMCtoNbLpe>=+oBen1c-b0_weWIaYx_ZDqc;lFL?d*-9>3 zP4SS&R`S?N9$O#d8OUMl8zHtyQ4)5r2lKVf5fxAg&LEd+; zhJzrlohNV#tiLlG*Fn#A-T{5u`3@iPS%_Wcu!0mNPzlvRF1s3_F|^QwJa&=Cu28f^ zJ1|?j$Z1!9#Dnu@S2F0!t|3UpaHNAAcI`od5WCG#1I-YJNnqY~Z^aJm#$Fu38IZ^B z9OU8>uHYUX;~B_nH+k(QuifOuHewHRw8t5)a0hwqsRM8Lzz^iMr!^wc8!?Clx$H>< zGqz_i$YT$A>|wU{(2qScF&lG1UVDDUVl2f9tin;;5n`_`*mo~A+e>Zsa@^kSVBYrr zjvKg*yC9dn@9_y=gxE)&_F2Lj^k^URx34m)g1q*5q9#~>pBEaSF*FE8I69y+dY~5! z=!1dy0pzl84l?iy7J)qWk;gt}Y#+0_ZzD26PWz4{3(VL)W^5nl&b|wvH~TIlALQ^` z1=L4(jKVT7o4?%`V!sW_zyak^5pJjrIq1=TC4Auz^4Z@6%*+0kpqBgFp(Ds`e+=l` z{vn`G`;B1F{o^nZQ$X+b)2IDwu^)$U1mv^-B+eik-nzFf#`S zAq^ui66AL9XVANYi$Sjr(yN2)d2lnfVJCKjnjg%?13U&Zc947yzQKEZ0=XPA1G9FB zz8$KJDyRnL?2tREqZaCb{v4t|hgzXOsO=&4J#+~lg~;T%O!CYmmrUxBNq;iQCo>M@ zl9`SlFb4D}b0Q{VD&}Jmn88f)%A{YJ8^HRRTagLoFf#}2m&v?k{*GI?3-Zi-1mZZ% zoE;{Y!&N~ZhsonGc^oE>!*VF#ivWb61<2`eYcOMn>CItg>@YKSxGQ=f0?gQ9;yio+ zH-$JN1+#l36y$hh66np5Imo~QEC+cU*@P{iM@M#G7s%(xNic&)n873T>&RtX1-Tu0 z0_O0@XCaQ7!wT$q)DC6f04I2WIXfDRrf3fGIobx{=m2s#N?(rlL=pyKFoq%xBfyLu z9R>Pxl>Qu@0D5thIFCLQ;#etAw`0`j*bvOdc5q%DJA@-RhI1f~WAy0QH5A|m=+!au zIrawc@kxl|5?H_*%#c0@N&ve6p&+4fHCDIn0uSIm{xrEH%g{D-7+?3EdHa zDD*}O=ug%RQ1`5PSOD_LT7uUN7X8RN4rVOt46<ufzV1Tmb| zq6OIhY&bfA{+;cIWDG$XM!<;in1rdAhGkd}>T>oF=*wAhJWD^$Qq!~4^z1u)5#pQ~ zn6Gm-utjZ<`?+|G1#6!B88a~l%{N+37_C687m4*E zv0kKq7m4#?Z$yJwFB0p;K^THDn1rby?u#?QEM6q$i;J-gE3gsUuoHVg9v9D}0Ph5U zQyNO5G|Ive6+lgMtAe@9tpR2)*B1c@LOtj}y>qE|ZVU8845)1`@#Ye5?m#euxuY-^ z)H!z|sBi9SP~Y6G*a7OC%Xyi57{|ao_pu6e|sM{V=$K|S-B-8^PD z&jrMtN6dNDH%|c{5OZE*XrV__5OW?e=MifjwapufVMxahpw4+yK%MiZVIGJ*Zy~62 z-WpKjye-%c>YPUodE}5s4tXa)z4Hh-?+UJ=0FUto@9`0zg}6jMmuyiAk{?490>Y!xg}a74DHbgoDY``h(>+y%CQ@q<~so`4JO93|D@_blk-={2@d>*RgzSkW)T6wQzwa=&K`CL2l$uFO^^Qn3M3NSDE>p;Epsdqm0&fkTjIDu0*i)`c|7nkrw zh^v*M0l8i!?yGCDO^AYqP=gv3Gy%C5P^$uJRX|Jy)T)456>vTl^Z+$0pk@WEQ$WoM z;xGWope6;(PXRd;Fh2#%PXW0UkV^r%6fj2x%uvA$%m#TCEC91qumsDo3dB~h0h?ip zaVI!;3w{H$RlsZ&977gP;~dDhfP4!s<0_c3f}6O5`(P#tp5g^w;~kj00(yL%xw}rU zu3Lj%T`vWDl!Fs0!Ws1Ix*M3q>orgtUQoghfvAfHXbdg%2tf;kqAl8?Bf6kF===33 z^g&FR%0DDVhgro7xrR54&exn<0Q@?8yAp=E4YU1xP`lTfX8@-mw1Es_=GP) z+%$tFY)}GrC<6zSMY*Xj(4h&Mp(R=)4DHbgUC{%*U_dnb zAr1qOj6oQRVMxah7=v+`h$)zc8JLZESb&9Cg5_9+wb+2o*oK|hgWqrvhj9#9IE{12 zK`t)iDhhBDcW@t%@Dwlb8t?ECpM|(3fd#Bk8r1WaFY1H(+@c1z$o*CXQZWkTb!#Oy zf!^O@-&^c=>$VWL%~2Bc<~DV{O?_``kqC~zO?_@J#u}`{4Lk&Wzf&3R@Pr1y-P3e(!;xLk$@p!@4L&e9vi{2cRBVh$KE5} zdyZg+?veMsV6etL_Pa;C_eOwx?~(64^1XK*rsJsVeQ%KG{kmW#?sLrjfmjWmd!HWO zzXbBUe@lo5Qj~=Qi17jQ^`HwhXj)p7pRvv})_KM{&wj*D_!*nA2m5dj)Zp1mA)Zr%=d~dRb$Cu4o>PbCMvTWqYykT| z-;Jxd1J-y>9bQm}7u4Ye>%3r{7p(Jw^X>&}yr3R0hF~Pf>BT%O0d;*rOTuZFq?1a$D3|oHsAaJX8aBHd_z6oki(m6xQqKjyrqtB%Yr=KYS0|y@OA(={w+DY z&A?JD2l2lp{S{U;6rW5(G+bE24ep}?jOkg1M~cWdHz8D zAL!kO$9O8l$I_^PN}zWiTOt&LkPc?(Be8#^b|2~g$2?pIwf|%Z&Vx_(;FwPx(HV2F z2upAt`Jmo^*rFU9;fDrjgcu|u8ME*!IR1|VIDwP+D8y$ASb=;$lkaEp{mhJfCfCpH zz|4Op-p`}JoP1u7jbQ)Jw?V%@Q|~XV@x=!0|3wdK_9X?wLC#;+VjFgVW500hm%BnD z_-mF#WmJJ0&Cmi#NW*aaf)!YWY+S)rd=~u3a!64J{s=^8M8beEn1Y|M75lJXNX+a| z9u?6M5#SiJMOclsxQ`cjB_!rG;R8P;V;Dx@08ZefkWfmA1+iF^Ky!qnJ!WGe7UKpU z;<1oevcIJZ+|Ul)(GxR4&Xycwc?le2c}qyFJm3WddLSBoLCjXfY(>mg#B4>(R>W-W z32!Jd07F4dtv6sNcH^y(&^F2cY3Z)Ryehwb0q;G4O2-T}Fw6|2be9edDk+V$lpr7= zDWxc(q?8QON_R*rDUAw<3KpS+^dJIK0-pPK&N;ex9{HYi<8H*O~A8Oaw1b zjTafnFh;O}?a1z#n>^s(AWWSfwWO9yYW1X6Pipm~UW8gwujLHpoLXIJ3M0QXB~FFJ?&ETkaj(PaUbubb8fmS=pmi`NvGFz@3Dt(ITD2F z?MwPhWT6HPXoURIZ)9^2`uxHS=9nQZ^=L*5rZ9^+{LCMm3&M=%lF?i;$|7TL2BX%D zGS2AkjQfHxQwq{y?=n@VF3!$0n#p|3QJkCU*C5PX2>oZa)0rnSotfO_zaY#KqR%XK z@V#U)t1M#~&o}(Yi6D%$1Ce$hvLy0|{1A6W{_o$+CQ=VkzMUxdL_N6x6K$?2J#-p|>SUN|GCymKB1!sv{sB|4hccrIE^ z(JOFP^rj%pCC6N8NQZyV<(yp3$+a6f`hBi2w|~o>mF%>o3*A`6YSso}jQPfRE=El; z4X`gUtx!*ldScY$_pZV`MJUEQe84Dv;3TJmF!ouBQk=ecE_Nt;QA_O6AdJh5p5n|S zt__`0Q=A=+v%_(AIL@BL*^_wv#lJ*7)D>^`@%Am=zQx;tcsmgPM-b-COJUrdwG0rwPm5`+Z^so=jn4#GmEsYqqarjQvH8iT$H>8p^w3O|QA z7nXtFUDB6hS$D_*BFtJuVrAS{}eC_GoRJN+@6qPsYR9WC}0 zW>U;v6!T3L>qsY@QB3W{z6!$P?ket#;_fQ0x8nAzJN_eJ(XG*%Oq`OMGtE9V1x~rtSO0MM#>`N(Ul!_!P9e9%-=)IKQOXe;N6fsYz{Sv5+M!XC)iijJ(U3Pnp}?;cgI?O@ThjW*`$; zkYm{x;z%GL1u2Ys%F4g2I?MK=FS0KCA!b{4JQJAAOw>_!HTo{Q4z-k(Pg!}Fm3P^_ z>_;!>QIk{G~rd6V^7NY=F8cW7m~S&zF*Mu z3lDgN?>;etR6Ijk(tF&bGU$|6w~iLywPMPd<(Qwnt@`aToYB34=Pmjm)5L)c!MBq*jFF6DEFUq6kD0~{ zX7efYS;SISApgYA*?>Jr{F3eXHWK$B|HMOl%Td1PI6w0nr}=~PT;vMZ`HNfp!+rkc zNf4F~Ny*csAw8LhBpW%&O)PnNjsg^>80KBR49`;@b1q+%7pXyQUZDYvG4t{*XiZx> z(1|X*Nl$vyj{ywkUEXH|A2NpVOk@g4OlKBzna4twu$)z_Wj&ktf^F<%H~ToqHyq&@ zKk^g5a*E$M$Dds08aMcxJKW5Dbfr6Q(TDyFWC%kU#z;mn zmXDak$4p}ev-yd(;%&sI0X>SNGn^{ITpZuX+a z7wy-JX?T{R*qs;a(;WNo;vj}IlKHG)6+iO_X7$ojWF#|Xs6-X)&P#phhm2oZ$YPH1 zD<`=h_}@@Q3gWQCFBj$&E(GG;(O#?!}~STkpWrPC{0PVMKZN_9HYot{ib z2DKL;gWA7wDhTVyp^hBt$e~UN5~)Bt++XKSK4Kcqs3V6ua;PJRI?k!%oI1{_>$|J# zjJoouTY!@2scs#bAlJGwsVkGZGO0Tgwbb=}*FDS$^i=mI5BN6-U&)Q#d?h~}P|GVl zn93Z?^_9JN|COWM<`GYVuwGv5MLj!O&phfirzQP(m-nz^^%i2s>V3@*97hfH)KE_i z_0>>c4fWMfUk~-$VmIpBiTbmd%YNKn|5)IEe+}l*ARTtIK`HEb19>)(X9GPnn7}8@ zK#mP|qmKrE^AJ5WjKlj4_0X^`O=*Vu8>+vd`Wvpr`wh492UoZjgpJhPNX?DZ+^8Pj zYt(|b@m`~0=)2J>)*$yr-fwg+2pg-raaOWZk(a4SABN!W#%9*o9yE4;V>{6JH%@Uc z2>m}JhD{<+dlS7k(R&m7+{8XN(SH-OYchvV*~vk^#_XCr;zs4e*esp|YR~}hH|xz{ z-eCnB*o1zY>9?7Fo7s`(dTpK(JKtQr%}ZlXnzyAr?r)xic{i7Lb7wT)g8Q5QgUnhy zOHuUPq79wtf_GbZw}p3G*pU|Ba2Wg9!rd+GXUn`4#``VpdCTUsWH{sa2(xOr8N1T* zBp0|CgstS&DhpARr7~6NL{EAl<5mYa6ojp1+&UB9X)UAHtx#|48O+B{wf=>($heJ6 z+Z3S~@@yl|Hu7w<7PYk5%EKUhEd{BlNkbYlg;~tO{jYt8?Ayw^ZF(|dH{0sDt#{gv z!8>iIa-7rr9)#^Oke!^Uxt*HZskxn++o`#on%kY=48DQ(aoFAVGHq|~+IPh_+kOe^ zZoiI8+~igecF0F@O45<;$gaa@EW_?}_zAUikV{APbW~4A^>nnO9o5p&u5_G$Id@c7 z$KQ}&$3KJc_575e6y4}cf9A2Am7L=m$wAmDoBA7-#lCdj#cu3r=O;nuuCeQrYg0m%P1x>1#{_Q zE?s2NHI@RXwX2M~y1Q#X*0T+J*Y$56;_Pnas6sV{;@oay_!a$kv(s-@q6W2C%o;vN zpKm_E_tM?0y1zhq1~Y;Wumj!gK=(g_u!lT)l);^T&nonLR$&i4^ziNYO{=iS#USjN z4`=l(iF$gfr>A=So>l1gtU|wM6~2{)T*UAOz0l`d+u6^-AncWntk{WOui?2~^60gS zO>7Cm-p`PkNX)XgeeB(XjqJdj`nao)yZX4RPe;1b6VLSVOdrqm^?u*ni5MjN>DI

    Lua8Nv+ z8&rh8sAbSlzCurf%wup`qEORdJ3QD954OXD?a5$!GFX3uZ}SLs4Ke#6_HBrL8)65B z*nuH-V959UhP(YnRQS$w4%Web2n_nPD&T z3ia{KFwYG0%&@blW!Uu~9PXUq&Kd5U;qDo}nzcbVA|>g`h#eVW-$wLAPa{^aigR2e zIS5CZ%}6sG`8@g>sjrdx8hIRZ9w~zl@==_U4B&l+vz`6e(GOFTg(zCni8t8FUOYD{ zngq;d)LRV1j*i-dnT)a*qkU7OGZTq3Myq{vFWlvKXTs6$8l$%{_IHf)#)* z_!h=&3&OE77;C4-dTy*|#(HL~XU4i~th>g#Yn;2rxoe!e#Px_whgDze(d|`H}oSs!UZTGZXXwNWLH4<$e(QeV1@TV_u~Nt$3Zz$a{kM zOfa7btI@}V4Qyr?YMG$-35W2_OgO^hAe?A+6J!~PrQLW zn^b|9XoOlOIb)LkCv`whle%L*llst)8Q9}V>X_vINk{pfACbW%eNMW`ZS*_o0rq&( ze?d4o9p*LJZcNTfcFb*ZZu0OV<}-N|t5EmkTl~wDAe<7C0_RN0fNyL{jUb$=&#C&H z>iMZB_=S_4;Vc)p#8uQcRee*{H&uO8)i+grQ`MIgK`QJ*Qd-=Rlo@-Rq}C+0CdCj( z0{JLN5sFg^^G|vKxh7Sn8uCr5Nge9ZkR~*vC2i1mQb+7SlH8Nzo+S4qxhM6<_mMP& zp$uara!MM@M@-^lreQ`&v-y->dTCH=#F%q+>wrkUBalsruu(vyiuvXK+>pB77Ao}&PT zDMm@k@I2))^J!Ii5woA>TblL?4QR}(w4gO@=|CsC@FqR!O+N-On0I-f5q!uP#xs#A zBr%;?%w--6S;BHwv6l60;tRI1lilp&Am4C=WBkZZ{K_eQ=Nx}>nQPqOZ|-o9hdd5K z|KDW7Pg3v{sYyphvXGS=qzct}nOfAPK8V zFHw^^)T1FyXhuug(2kCDrYqffi$3&cAVV0+Fh(+pv3$fNrZ5Y6PT$EvC@-yocw5_iuoNqH*b z-Pzuq?cLexojngbG+W=ZkKv5j?wh0DIcdq0hO!NMbIZp~kuPYwpD${4^jncIVSVl*T@M+LYI5$52Kwh7D}TtUf)* zHIjqyvrOb97k1~fdNe@BpS{m;R#R$furzJ~R%R21w z5_`79jF)CdElcxKo5t9$rGxSQ(hpe9dN%S4XE`5)%Tkh_j1;64WoSrCT4TSK+0A9+ zP{T4cEK|cWH7rxZGBqsM!}2JyQHw@2;T_z+d=&O_xp^$#gS}dAua?`Z74lpm&lP&` z+fLz%SE!F1R}4fSE0*#(dRXxj-d~}Il_6Regfx>uiRXOy%sw16{`zr6Rnt{4keajJU@h^{qaCLr4;O^CCw%Q)7cK>QS zuzE5dvzpC(f!bH=eYM`#*ylC&d5!+pnBAJjG^Ia7c^|X$TT`LmnhMvP;!o_*TD7m0 z-CFZsTZtOT-fu>QYkdc6-^M#@cd&~mLHPO8q~-;xA@9$7F^D0|WC4pf%Fq1Dqaa+D z3h%GWM{!Eho^EtUzw7k7PQQM?DO{)5bz8CX>(smMN)WEMC+nlghWppo!MxYYd%ZK( z_r(3{S0c0Zzi}QtZ^%L}V({(;?{4t!20OB07$dNs8{ECYes1`Mvv_}_J>Qs~j66?O zs$*6gdtg^KPGJ^vkk`gTe8V;Fa5o4yMU%jD$avGcyoZc89l$%AW#qSw!p-X4T%YFH zsm&9aj*K_Ubn`hb1mPBWZjt8}d2Z>9TDJ7&bG~F7kAv`wr+9{%G^8=^|KdYr|Anl- z*vo$G=9hZ@(mP*P#yeluW*k$Q#y*blT@Y?n^Hw!)Rr6LgZ&mYFHE$hH625`0KVf&b z%5)v;!iFG;r1NFBfIUd(iXe3{Ug+}T`t?zvt2#g)w9En z?oi7PyRzd&%z1~pc1%WoJ7#m5i(C%Eov{?45Y1>u2WBvzh5XDP$bDBj^sp;CO?eIP z>~ij|Md)Fd{n@40UFU=FtNfIp6!zt-w;6~%{c0ndgK)R}cIPA)^4M*TyL+>qZS3GK z{{`WmkczxaP0VGFx$Kd}o)erwt$Ss>*WG&y(v?2gyS+>K9B1#n&Oh7>!hNN2?!L-Q zLjU{h^uF6X;zEO)bI?5p=Wq&V9lR8ThtzXOJ%`kDXb{60$sxYy#~}PVH_xHZulw>2L)pW( z*oki<@!U7^_@*P>>B&wG@^uh?YnI>IN57pBe)}f#FKz$4twUX zXAXP+@DCgh!XwT&BJU%G>5p2Dyw6v7?ueR>X2e-Xqmkp$Ui87gA9ar3q6ojshaA5v ziGTZU2=B6&!yFC5W2wnP6y|%(bH~(lY$NvN*sdV_UOnHd$8R`<-;ZGmQ~84{TnoY< zo~J6+8Oz5c@iU(L;am{@SOB&BSegOo=|}VUaW~(frsH<_xE(%jhmYHn5K2> zcRTv~E)MZc5dM*wXmZn=!FcYEWBiKQoPCy}*wM4yF%y479G>+}`TO4R?AJkf&Kc*_ ze(pKk!Pc{_F9a~C{w!7~>;bHQB~+;zcS z7uM=n>?ab**G(C?MQ=qmi@R@kGB}eVDx=!A!c~X{kPPAOZ~S~lZ7ZsQXV^Zy9>SP%O~jn_I%`aTW+`I zcKa{x^DqeSsQ-@o@2LNd+V8aHH9kcDckI=jE!dAcdpO56l7sM{boe&@$xa1cq6YT# zAN%>wC^oPi_y6O)f9`NM2=D6oZXslUw;?TY_uY4K_ubLhySw)7?jJ#T&u-ka8~2Lh zySO)qA$-o4Y{M?zvxE2k3BvpNDM2Y@abHdM&Evk^zrPhV-B*vl6AkaH=fMk9<3-&6 zK<^Lq{y=6Aj`0JJg79G~o~8r#>tPQTvj(+1yum#l1mVBV{MVWPI`dz5|0|Dw$8Z+4 z{%a2&*_lUjf7BHJ_QF?)%I9jkAKB;PxSkw1f@{Z zleZa&KA-GIAOB?{C%Je7IsVs&&Fo@#5D`30CbH0sc64Ap+t?9AglUN)8*S-AH@35% zgF!?@Id-#?kK|~7gr-&tav3?iO-foiVODdq8<&H$aH3MoYVXsM5NJU8a<{diX7AQMP6z2 zm`0Cj^q4k=d=#J`@A4ks^Bbpvh;+~5jC93Oce?RRz+LIwmCjx1J(J!u={=KvG?V$5 zOWfpE5RsuK4Qb32W-$kMWcU-$W~_kTGS*-=i&(-9^q=uT5Rs`i&dAgh|DI_zYlDc) zA?B4iBbmrTEPBfBBlv<qHmku$+~w#?EB> zlUv+DhS_A8y%-fR&+JvGj^49>fPS-&VLWD+{Rrlj{d??Dj?`qsj^v0YhQ`P?M+aW# z4P=vJ8M4VCn;dH~+Z=x*n;f#qaX*O2S(Ng~CZ}w2R$~CN&ncUnvdKA)T^vR>Ic1ac z#~>ow?4z?Hn`qfY=cW;DkxjI0qRl#b7E6&$v}~fyDf&D&kxjI0qRlB+5fYJ2F4^QV zr(AC{0@>t}O)hiFwUcj=O)lBwGN;^66NPMY%O{FyB9T~|& z6ncw&mi!c=D8hIN=%>}K>9dw{PwjCsY{tysOqp5+3UFt6C_m{**gii@EHr71@udWh3Q zoF3xz5T}Q@y0oPOYL8QUTvxjD7JcZ?0Q3@PR&jcWGmp40k$c>qxHn#g@rAJu@s;RE zH_SYKFr)Bpy#C|$AFuy-Gmbao_=Pw#UJmgmxf?{}HJ7|ONFW~tDS~(lG#0R&Rjg$_@=MsxF7~jGBOK>+5K-Ql<(*l65Favz z@l0e2Nla%EOIg8cK4$})`2uHEh(LA~n$Zs5VujwQvw}J+jKujBoL6Bc>h<@55fz+U zLEROcRYAQKwy~4l?By`u@jX9sivQjBJC}oqim6FU1~L;xcA|+P4)gW*eG&e?FQTFv zE1GXb^Y!R literal 0 HcmV?d00001 diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/WorkspaceSettings.xcsettings b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..e097e4fe6 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,22 @@ + + + + + BuildLocationStyle + UseAppPreferences + CustomBuildIntermediatesPath + Build/Intermediates.noindex + CustomBuildLocationType + RelativeToDerivedData + CustomBuildProductsPath + Build/Products + DerivedDataLocationStyle + Default + IssueFilterStyle + ShowActiveSchemeOnly + LiveSourceIssuesEnabled + + SharedBuildFolderName + Build + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.13.xcscheme b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.13.xcscheme new file mode 100644 index 000000000..d98dd9b97 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.13.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.14.xcscheme b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.14.xcscheme new file mode 100644 index 000000000..79299d7a5 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.14.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.15.xcscheme b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.15.xcscheme new file mode 100644 index 000000000..e72a90366 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.15.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 000000000..d23112ec9 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,67 @@ + + + + + SchemeUserState + + stlink_shield 10.7.xcscheme_^#shared#^_ + + orderHint + 2 + + stlink_shield copy copy.xcscheme_^#shared#^_ + + orderHint + 3 + + stlink_shield copy.xcscheme_^#shared#^_ + + orderHint + 2 + + stlink_shield.xcscheme_^#shared#^_ + + orderHint + 1 + + stlink_shield_10.13.xcscheme_^#shared#^_ + + orderHint + 0 + + stlink_shield_10.14 copy.xcscheme_^#shared#^_ + + orderHint + 4 + + stlink_shield_10.14.xcscheme_^#shared#^_ + + orderHint + 1 + + stlink_shield_10.15.xcscheme_^#shared#^_ + + orderHint + 2 + + + SuppressBuildableAutocreation + + 8F9084E724786F0B009109AD + + primary + + + 8F9084F324786F0F009109AD + + primary + + + 8F9084FF24786F39009109AD + + primary + + + + + diff --git a/stlinkv1_macosx_driver/README.md b/stlinkv1_macosx_driver/README.md deleted file mode 100644 index b2a68442c..000000000 --- a/stlinkv1_macosx_driver/README.md +++ /dev/null @@ -1,47 +0,0 @@ -from: marco.cassinerio@gmail.com - -to: texane@gmail.com - -Hi, - -i managed to get the stlink v1 working under os x and i would like to share the solution so maybe you can add it in your package. -The problem is that os x claims the device as scsi and libusb won't be able to connect to it. -I've created what is called a codeless driver which claims the device and has a higher priority then the default apple mass storage driver, so the device can be accessed through libusb. - -I tested this codeless driver under OS X 10.6.8 and 10.7.2. -I assume it works with any 10.6.x and 10.7.x version as well. - -Attached to this mail you'll find the osx folder with the source code of the driver, both drivers (for 10.6.x and 10.7.x), an install.sh script and the modified Makefile, i only added a line at the end which invoke the `install.sh`. - -First, unpack the `osx.tar.gz` contents: -```bash -tar xzvf osx.tar.gz -``` - -Then, install the driver using: -```bash -sudo make osx_stlink_shield -``` - -no reboot required. - -P.S. If error `OS X version not supported` occurs. For the latest versions of Mac OS X you may need to change the `osx/install.sh` as follows: -```bash -< ISOSXLION=$(sw_vers -productVersion) ---- -> ISOSXLION=$(sw_vers -productVersion | sed -e 's:.[[:digit:]]*$::') -``` - -### OS X 10.10 Yosemite - -For OS X 10.10 Yosemite you must force the system to load unsigned kernelextensions - -```bash -sudo nvram boot-args="kext-dev-mode=1" -``` - -reboot the system! - -### OS X 10.11 El Capitan - -For OS X 10.11 El Capitan: the Yosemite kext seems to work (tested on 10.11.04). diff --git a/stlinkv1_macosx_driver/osx.tar.gz b/stlinkv1_macosx_driver/osx.tar.gz deleted file mode 100644 index 57bc314668c66f849b8fdcd50a5e38a430cac624..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23580 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

      j8Y(F{;Oc1p&o2`rjEgTlTet!n|}EG9(XKHIrH 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 M^A0x(5eCYC0W6&Nj{pDw From 3e49becc2f20f2b62cff266f12f4f99d6101446f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 27 May 2020 12:35:05 +0200 Subject: [PATCH 0944/1435] Corrected udev & modprobe install directories (Fixes #966) --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b17fdc57..b660e0f23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -255,12 +255,12 @@ install(TARGETS st-util DESTINATION ${CMAKE_INSTALL_BINDIR}) ### if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - ## Install modprobe.d conf files / rules to /usr/local/etc/stlink (default) - set(STLINK_MODPROBED_DIR "${CMAKE_INSTALL_SYSCONFDIR}/${PROJECT_NAME}/modprobe.d" CACHE PATH "modprobe.d directory") + ## Install modprobe.d conf files to /etc/modprobe.d/ (explicitly hardcoded) + set(STLINK_MODPROBED_DIR "/etc/modprobe.d" CACHE PATH "modprobe.d directory") install(FILES ${CMAKE_SOURCE_DIR}/config/modprobe.d/stlink_v1.conf DESTINATION ${STLINK_MODPROBED_DIR}) - ## Install udev rules files / rules to /usr/local/etc/stlink (default) - set(STLINK_UDEV_RULES_DIR "${CMAKE_INSTALL_SYSCONFDIR}/${PROJECT_NAME}/udev/rules.d" CACHE PATH "udev rules directory") + ## Install udev rules files to /etc/udev/rules.d/ (explicitly hardcoded) + set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "udev rules directory") file(GLOB RULES_FILES ${CMAKE_SOURCE_DIR}/config/udev/rules.d/*.rules) install(FILES ${RULES_FILES} DESTINATION ${STLINK_UDEV_RULES_DIR}) endif () From 4337408e0413e61b74be90fe46f9b0336acc7215 Mon Sep 17 00:00:00 2001 From: rutgerhendriks <3134550+rutgerhendriks@users.noreply.github.com> Date: Wed, 27 May 2020 15:59:44 +0200 Subject: [PATCH 0945/1435] Create ccpp.yml --- .github/workflows/ccpp.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/ccpp.yml diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml new file mode 100644 index 000000000..23aa0bfc5 --- /dev/null +++ b/.github/workflows/ccpp.yml @@ -0,0 +1,17 @@ +name: C/C++ CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: make + run: make From 71011a3e7dec751f193556881507eb213f1da6b2 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 27 May 2020 21:50:45 +0200 Subject: [PATCH 0946/1435] Updated README for STLink-v1 setup on macOS --- stlinkv1_macos_driver/README.md | 38 +++++++++++---------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/stlinkv1_macos_driver/README.md b/stlinkv1_macos_driver/README.md index ca4a3da30..7221732c0 100644 --- a/stlinkv1_macos_driver/README.md +++ b/stlinkv1_macos_driver/README.md @@ -1,43 +1,31 @@ -### # Installation instructions for STLINK/v1 driver -### When connecting to the STLINK/v1 on macOS via USB, the system claims the programmer as a SCSI device. Thus libusb is not able to initialise and establish a connection to it. To solve this issue Marco Cassinerio (marco.cassinerio@gmail.com) has created a so called "codeless driver" which claims the device. It is of higher priority then the default apple mass storage driver, what allows the device to be accessed through libusb. To make use of this alternative approach one needs to go through the following steps: -1) Install the macOS Kernel Extension (kext): - - Open a terminal console and navigate to this subdirectory `/stlinkv1_macos_driver` - - Use the command ```sudo sh ./install.sh``` to install the appropiate kext for your system version. - -2) Install the ST-Link-v1 driver from this subdirectory `/stlinkv1_macos_driver` by executing: ```sudo make osx_stlink_shield```. This should result in the following output: - -``` -Requesting load of /System/Library/Extensions/stlink_shield.kext. -/System/Library/Extensions/stlink_shield.kext loaded successfully (or already loaded). -``` - -3) Configure System Integrity Protection (SIP) +1) Configure System Integrity Protection (SIP) The above system security setting introduced by Apple with OS X El Capitan (10.11) in 2015 is active per default and prevents the operating system amongst other things to load unsigned Kernel Extension Modules (kext). Thus the STLINK/v1 driver supplied with the tools, which installs as a kext, remains not functional, -until SIP is fully deactivated. +until SIP is fully deactivated. Without SIP-deactivation, st-util would fail to detect a STLINK/v1 device later on. -Without SIP-deactivation, st-util fails to detect a STLINK/v1 device: +In order to deactivate SIP, boot into the recovery mode and run ```csrutil disable``` in a terminal console window. -``` -st-util -1 -st-util $VERSION-STRING$ -WARN src/sg.c: Failed to find an stlink v1 by VID:PID -ERROR src/sg.c: Could not open stlink device -``` +2) Reboot the system. -In order to deactivate SIP, boot into the recovery mode and run ```csrutil disable``` in a terminal console window. +3) Install the macOS Kernel Extension (kext) (ST-Link-v1 driver): + - Open a terminal console and navigate to this subdirectory `/stlinkv1_macos_driver` + - Use the command ```sudo sh ./install.sh``` to install the appropiate kext for your system version. + This should result in the following output: -4) Reboot the system. +``` +Requesting load of /System/Library/Extensions/stlink_shield.kext. +/System/Library/Extensions/stlink_shield.kext loaded successfully (or already loaded). +``` -5) Verify correct detection of the STLINK/v1 device with the following input: `st-util -1` +4) Verify correct detection of the STLINK/v1 device with the following input: `st-util -1` You should then see a similar output like in this example: ``` From 9b6cd7f99ba33fe7f783cbdc49bddafeee017ca8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 28 May 2020 11:09:32 +0200 Subject: [PATCH 0947/1435] General Project Update - Updated CHANGELOG - Corrected instructions for udev & STLink-v1 --- CHANGELOG.md | 134 +++++++++++++++++++++++++---------------------- doc/compiling.md | 22 ++++---- 2 files changed, 81 insertions(+), 75 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6b63e156..94c47e8fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,89 +4,98 @@ stlink ChangeLog v1.6.1 ====== -Release date: (TBD) +Release date: 2020-06-xx This release drops support for some older operating systems. Check project README for details. Features: -- Basic compatibility for STLink-v3 programmer ([#271](https://github.com/stlink-org/stlink/pull/271), [#863](https://github.com/stlink-org/stlink/pull/863), [#954](https://github.com/stlink-org/stlink/pull/954)) +* Basic compatibility for STLink-v3 programmer ([#271](https://github.com/stlink-org/stlink/pull/271), [#863](https://github.com/stlink-org/stlink/pull/863), [#954](https://github.com/stlink-org/stlink/pull/954)) - Added support for JTAG command API v2 & distinguish protocol versions v1 and v2 - Compatibility with the STLink-v3 firmware which dropped support for the previous API v1 - As of firmware version J11 the ST-LINK-V1 programmer supports API v2 commands as well -- Display programmer serial when no target is connected ([#432](https://github.com/stlink-org/stlink/pull/432), [#933](https://github.com/stlink-org/stlink/pull/933), [#943](https://github.com/stlink-org/stlink/pull/943)) -- Support for STM32L1, SM32L4 option bytes write ([#596](https://github.com/stlink-org/stlink/pull/596), [#844](https://github.com/stlink-org/stlink/pull/844), [#847](https://github.com/stlink-org/stlink/pull/847)) -- CMake now creates an uninstall target ([#619](https://github.com/stlink-org/stlink/pull/619), [#907](https://github.com/stlink-org/stlink/pull/907)) -- Added CMAKEFLAGS and install target ([#804](https://github.com/stlink-org/stlink/pull/804), [#935](https://github.com/stlink-org/stlink/pull/935)) -- Support for STM32G4 ([#822](https://github.com/stlink-org/stlink/pull/822)) -- Add aliased SRAM2 region in the L496 memory map ([#824](https://github.com/stlink-org/stlink/pull/824)) -- Improved support for STM32G0 ([#825](https://github.com/stlink-org/stlink/pull/825), [#850](https://github.com/stlink-org/stlink/pull/850), [#856](https://github.com/stlink-org/stlink/pull/856), [#857](https://github.com/stlink-org/stlink/pull/857)) -- Added postinst script with 'depmod -a' for 'make package' ([#845](https://github.com/stlink-org/stlink/pull/845), [#931](https://github.com/stlink-org/stlink/pull/931)) -- Calculate checksums for flash operations ([#862](https://github.com/stlink-org/stlink/pull/862), [#924](https://github.com/stlink-org/stlink/pull/924)) -- Adjust the JTAG/SWD frequency via cmdline option ([#893](https://github.com/stlink-org/stlink/pull/893), [#953](https://github.com/stlink-org/stlink/pull/953)) -- Added usb PID and udev rules for STlink v2.1 found on Nucleo-L432KC and Nucleo-L552ze boards ([#900](https://github.com/stlink-org/stlink/pull/900)) -- STM32G0/G4 improvements ([#910](https://github.com/stlink-org/stlink/pull/910)) +* Display programmer serial when no target is connected ([#432](https://github.com/stlink-org/stlink/pull/432), [#933](https://github.com/stlink-org/stlink/pull/933), [#943](https://github.com/stlink-org/stlink/pull/943)) +* Added connect under reset to stlink_open_usb( ) ([#577](https://github.com/stlink-org/stlink/pull/577), [#963](https://github.com/stlink-org/stlink/pull/963)) +* Support for STM32L1, SM32L4 option bytes write ([#596](https://github.com/stlink-org/stlink/pull/596), [#844](https://github.com/stlink-org/stlink/pull/844), [#847](https://github.com/stlink-org/stlink/pull/847)) +* Added CMAKEFLAGS and install target ([#804](https://github.com/stlink-org/stlink/pull/804), [#935](https://github.com/stlink-org/stlink/pull/935)) +* Support for STM32G4 ([#822](https://github.com/stlink-org/stlink/pull/822)) +* Add aliased SRAM2 region in the L496 memory map ([#824](https://github.com/stlink-org/stlink/pull/824)) +* Improved support for STM32G0 ([#825](https://github.com/stlink-org/stlink/pull/825), [#850](https://github.com/stlink-org/stlink/pull/850), [#856](https://github.com/stlink-org/stlink/pull/856), [#857](https://github.com/stlink-org/stlink/pull/857)) +* Added postinst script with 'depmod -a' for 'make package' ([#845](https://github.com/stlink-org/stlink/pull/845), [#931](https://github.com/stlink-org/stlink/pull/931)) +* Calculate checksums for flash operations ([#862](https://github.com/stlink-org/stlink/pull/862), [#924](https://github.com/stlink-org/stlink/pull/924)) +* Adjust the JTAG/SWD frequency via cmdline option ([#893](https://github.com/stlink-org/stlink/pull/893), [#953](https://github.com/stlink-org/stlink/pull/953)) +* Added usb PID and udev rules for STlink v2.1 found on Nucleo-L432KC and Nucleo-L552ze boards ([#900](https://github.com/stlink-org/stlink/pull/900)) +* STM32G0/G4 improvements ([#910](https://github.com/stlink-org/stlink/pull/910)) - Enable mass erase with a flash programming check - Handle G4 Cat3 devices with configurable dual bank flash by using a helper Updates & changes: -- [doc] Update compiling instructions ([#113](https://github.com/stlink-org/stlink/pull/113), commit [#10ae529](https://github.com/stlink-org/stlink/commit/10ae5294cd03aacfc07312010f026d3cb12ea56c)) -- Define libusb version compatibility for supported operating systems via LIBUSB_API_VERSION ([#211](https://github.com/stlink-org/stlink/pull/211), [#782](https://github.com/stlink-org/stlink/pull/782), [#895](https://github.com/stlink-org/stlink/pull/895)) -- Improved argument parsing for CLI tools ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) -- [doc] Updated tutorial: macOS ST-Link-v1 detection ([#574](https://github.com/stlink-org/stlink/pull/574), [#587](https://github.com/stlink-org/stlink/pull/587)) -- Enhanced error log with file path for map_file() ([#650](https://github.com/stlink-org/stlink/pull/650), [#879](https://github.com/stlink-org/stlink/pull/879), [#921](https://github.com/stlink-org/stlink/pull/921)) -- Enhanced output for error msg "addr not a multiple of pagesize, not supported" ([#663](https://github.com/stlink-org/stlink/pull/663), [#945](https://github.com/stlink-org/stlink/pull/945)) -- [refactoring] Package distribution: Provide Windows binaries via Debian-based cross-build ([#738](https://github.com/stlink-org/stlink/pull/738), [#795](https://github.com/stlink-org/stlink/pull/795), [#798](https://github.com/stlink-org/stlink/pull/798), [#955](https://github.com/stlink-org/stlink/pull/955)) - - Update, corrections & cleanup for build settings (see #955 for details) +* [doc] Updated compiling instructions ([#113](https://github.com/stlink-org/stlink/pull/113), commit [#10ae529](https://github.com/stlink-org/stlink/commit/10ae5294cd03aacfc07312010f026d3cb12ea56c)) +* Defined libusb version compatibility for supported systems via LIBUSB_API_VERSION ([#211](https://github.com/stlink-org/stlink/pull/211), [#782](https://github.com/stlink-org/stlink/pull/782), [#895](https://github.com/stlink-org/stlink/pull/895)) +* Improved argument parsing for CLI tools ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) +* [doc] Updated tutorial: macOS ST-Link-v1 detection ([#574](https://github.com/stlink-org/stlink/pull/574), [#587](https://github.com/stlink-org/stlink/pull/587)) +* Enhanced error log with file path for map_file() ([#650](https://github.com/stlink-org/stlink/pull/650), [#879](https://github.com/stlink-org/stlink/pull/879), [#921](https://github.com/stlink-org/stlink/pull/921)) +* Enhanced output for error msg "addr not a multiple of pagesize, not supported" ([#663](https://github.com/stlink-org/stlink/pull/663), [#945](https://github.com/stlink-org/stlink/pull/945)) +* Package distribution: Provide Windows binaries via Debian-based cross-build ([#738](https://github.com/stlink-org/stlink/pull/738), [#795](https://github.com/stlink-org/stlink/pull/795), [#798](https://github.com/stlink-org/stlink/pull/798), [#870](https://github.com/stlink-org/stlink/pull/870), [#955](https://github.com/stlink-org/stlink/pull/955)) + - [refactoring] Update, corrections & cleanup for build settings (see #955 for details) - New cpack package-config for DEB and RPM build - Update for travis build configuration: builds for clang -m32, clang-9, MinGW-cross on linux - Updated steps for release preparation - Project contributors now listed in separate file - Test files & gui now use shared stlink-library -- [doc] Verify correct udev configuration for device access ([#764](https://github.com/stlink-org/stlink/pull/764)) -- Added more error info to WLOGs during probe ([#883](https://github.com/stlink-org/stlink/pull/883)) -- [doc] Add missing documentation for stlink-gui ([#884](https://github.com/stlink-org/stlink/pull/884)) -- Added check for libssp during compilation ([#885](https://github.com/stlink-org/stlink/pull/885)) -- Silence unnecessary messages ([#886](https://github.com/stlink-org/stlink/pull/886)) -- [doc] Define libusb & cmake version compatibility ([#896](https://github.com/stlink-org/stlink/pull/896), [#897](https://github.com/stlink-org/stlink/pull/897), [#899](https://github.com/stlink-org/stlink/pull/899), commit [#27aa888](https://github.com/stlink-org/stlink/commit/27aa88821197d3ffe82baff4e971c3488ec39899)) -- Update for STM32G471/473/474/483/484 devices ([#901](https://github.com/stlink-org/stlink/pull/901)) -- [doc] st-flash --flash=n[k][m] command line option to override device model ([#902](https://github.com/stlink-org/stlink/pull/902)) -- [refactoring] BSD-License-compliant rewrite of flashloader source files ([#915](https://github.com/stlink-org/stlink/pull/915), [#932](https://github.com/stlink-org/stlink/pull/932)) -- [refactoring] Overall option code rework ([#927](https://github.com/stlink-org/stlink/pull/927)) -- [refactoring] Build settings / GUI-Build on UNIX-based systems if GTK3 is detected ([#929](https://github.com/stlink-org/stlink/pull/929)) -- [refactoring] Reconfiguration of package build process ([#931](https://github.com/stlink-org/stlink/pull/931), [#936](https://github.com/stlink-org/stlink/pull/936), [#940](https://github.com/stlink-org/stlink/pull/940), commit [#9b19f92](https://github.com/stlink-org/stlink/commit/9b19f9225460472af9d98959b7217d0a840ee972)) -- [refactoring] st-util: Removed now useless v1/v2 STLink version stuff ([#934](https://github.com/stlink-org/stlink/pull/934)) -- [refactoring] Cleanup for option bytes and flash settings ([#941](https://github.com/stlink-org/stlink/pull/941)) -- Added compilation guideline for MSVC toolchain ([#942](https://github.com/stlink-org/stlink/pull/942)) -- [refactoring] Cleanup of cmake build process ([#944](https://github.com/stlink-org/stlink/pull/944), [#946](https://github.com/stlink-org/stlink/pull/946), [#947](https://github.com/stlink-org/stlink/pull/947)) -- Set up a libusb log level accordingly to verbosity (commit [#49f887d](https://github.com/stlink-org/stlink/commit/49f887d5247fdd28f163b6317790c4f087e652cc)) -- [doc] Defined version compatibility and installation instructions for macOS (commit [#23c071e](https://github.com/stlink-org/stlink/commit/23c071edea45f6e8852fef52d884a680973d6d8f)) -- Deprecated old appveyor-mingw script (commit [#9748442](https://github.com/stlink-org/stlink/commit/97484422008df0f75c978627054776f35842a075)) -- libusb package extraction no longer requires 7zip as an external unarchiver (commit [#5db2dc4](https://github.com/stlink-org/stlink/commit/5db2dc4c0410ace65308cddcc03d1c0cfa4855cf)) - +* [doc] Verify correct udev configuration for device access ([#764](https://github.com/stlink-org/stlink/pull/764)) +* Added more error info to WLOGs during probe ([#883](https://github.com/stlink-org/stlink/pull/883)) +* [doc] Added missing documentation for stlink-gui ([#884](https://github.com/stlink-org/stlink/pull/884)) +* Added check for libssp during compilation ([#885](https://github.com/stlink-org/stlink/pull/885)) +* Silenced unnecessary messages ([#886](https://github.com/stlink-org/stlink/pull/886)) +* [doc] Defined libusb & cmake version compatibility ([#896](https://github.com/stlink-org/stlink/pull/896), [#897](https://github.com/stlink-org/stlink/pull/897), [#899](https://github.com/stlink-org/stlink/pull/899), commit [#27aa888](https://github.com/stlink-org/stlink/commit/27aa88821197d3ffe82baff4e971c3488ec39899)) +* Update for STM32G471/473/474/483/484 devices ([#901](https://github.com/stlink-org/stlink/pull/901)) +* [doc] st-flash --flash=n[k][m] command line option to override device model ([#902](https://github.com/stlink-org/stlink/pull/902)) +* [refactoring] Improved cmake build process ([#912](https://github.com/stlink-org/stlink/pull/912)) + - Set up a libusb log level accordingly to verbosity ([#894](https://github.com/stlink-org/stlink/pull/894) + - [compatibility] Updated libusb to v1.0.23 ([#895](https://github.com/stlink-org/stlink/pull/895) + - Updated compiling doc & version support ([#896](https://github.com/stlink-org/stlink/pull/896), [#897](https://github.com/stlink-org/stlink/pull/897), [#899](https://github.com/stlink-org/stlink/pull/899)) + - Version requirements & pkg-maintainer + - Fixed install paths in build script + - Updated C-flag -std=gnu99 to gnu11) + - Added cmake uninstall target ([#619](https://github.com/stlink-org/stlink/pull/619), [#907](https://github.com/stlink-org/stlink/pull/907)) + - Integrated module GNUInstallDirs.cmake ([#557](https://github.com/stlink-org/stlink/pull/557)) + - [doc] Defined version compatibility and installation instructions for macOS + - [refactoring] libusb detection + - Deprecated old appveyor-mingw script +* [refactoring] BSD-License-compliant rewrite of flashloader source files ([#915](https://github.com/stlink-org/stlink/pull/915), [#932](https://github.com/stlink-org/stlink/pull/932)) +* [refactoring] Overall option code rework ([#927](https://github.com/stlink-org/stlink/pull/927)) +* [refactoring] Build settings / GUI-Build on UNIX-based systems if GTK3 is detected ([#929](https://github.com/stlink-org/stlink/pull/929)) +* [refactoring] Reconfiguration of package build process ([#931](https://github.com/stlink-org/stlink/pull/931), [#936](https://github.com/stlink-org/stlink/pull/936), [#940](https://github.com/stlink-org/stlink/pull/940), commit [#9b19f92](https://github.com/stlink-org/stlink/commit/9b19f9225460472af9d98959b7217d0a840ee972)) +* [refactoring] st-util: Removed now useless v1/v2 STLink version stuff ([#934](https://github.com/stlink-org/stlink/pull/934)) +* [refactoring] Cleanup for option bytes and flash settings ([#941](https://github.com/stlink-org/stlink/pull/941)) +* Added compilation guideline for MSVC toolchain ([#942](https://github.com/stlink-org/stlink/pull/942)) +* [refactoring] Cleanup of cmake build process ([#944](https://github.com/stlink-org/stlink/pull/944), [#946](https://github.com/stlink-org/stlink/pull/946), [#947](https://github.com/stlink-org/stlink/pull/947)) + - libusb package extraction no longer requires 7zip as an external unarchiver Fixes: -- Fixed wait-loop for flash_loader_run() ([#290](https://github.com/stlink-org/stlink/pull/290)) -- Better argument parsing for CLI tools: stlink_open_usb can address v1, v2, v3 ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) -- Clear the PG bit before setting the PER bit ([#579](https://github.com/stlink-org/stlink/pull/579), [#876](https://github.com/stlink-org/stlink/pull/876)) -- Fixed compilation issues with int length on 32-bit platforms ([#629](https://github.com/stlink-org/stlink/pull/629), [#908](https://github.com/stlink-org/stlink/pull/908)) -- Fixed st-info --probe mechanism ([#679](https://github.com/stlink-org/stlink/pull/679), [#918](https://github.com/stlink-org/stlink/pull/918)) -- [regression] Fixed sign-compare (size != rep_len) in usb.c ([#772](https://github.com/stlink-org/stlink/pull/772), [#869](https://github.com/stlink-org/stlink/pull/869), [#872](https://github.com/stlink-org/stlink/pull/872), [#891](https://github.com/stlink-org/stlink/pull/891)) -- Fixed dead loop after an unexpected unplug ([#780](https://github.com/stlink-org/stlink/pull/780), [#812](https://github.com/stlink-org/stlink/pull/812), [#913](https://github.com/stlink-org/stlink/pull/913)) -- Avoid re-define of O_BINARY on Windows ([#788](https://github.com/stlink-org/stlink/pull/788)) -- Fixed st-flash manpage read example ([#858](https://github.com/stlink-org/stlink/pull/858)) -- Fixed stlink support with no mass storage ([#861](https://github.com/stlink-org/stlink/pull/861)) -- Make Version.cmake more error-resistant ([#872](https://github.com/stlink-org/stlink/pull/872)) -- Error return in failed probe ([#887](https://github.com/stlink-org/stlink/pull/887), [#890](https://github.com/stlink-org/stlink/pull/890)) -- Fixed broken build on 32-bit systems ([#919](https://github.com/stlink-org/stlink/pull/919), [#920](https://github.com/stlink-org/stlink/pull/920)) -- st-flash: Minor usage fix and make cmdline parsing more user friendly ([#925](https://github.com/stlink-org/stlink/pull/925)) -- [regression] Restored functionality of make test builds ([#926](https://github.com/stlink-org/stlink/pull/926), [#929](https://github.com/stlink-org/stlink/pull/929)) -- Fixed compilation error due to uninitialized cpuid ([#937](https://github.com/stlink-org/stlink/pull/937), [#938](https://github.com/stlink-org/stlink/pull/938)) -- Fixes for STM32F0 flashloader ([#958](https://github.com/stlink-org/stlink/pull/958), [#959](https://github.com/stlink-org/stlink/pull/959) -- Set static link for libssp (stack-smashing protection) ([#960](https://github.com/stlink-org/stlink/pull/960), [#961](https://github.com/stlink-org/stlink/pull/961)) -- Fixed formatting for options display in st-flash & st-info (commits [#c783d0e](https://github.com/stlink-org/stlink/commit/c783d0e777ccc83a7a8be26a4f4d3414e0478560) and [#562cd24](https://github.com/stlink-org/stlink/commit/562cd2496e696dbd22950925866aac662d81ee5f)) +* Fixed wait-loop for flash_loader_run() ([#290](https://github.com/stlink-org/stlink/pull/290)) +* Better argument parsing for CLI tools: stlink_open_usb can address v1, v2, v3 ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) +* Clear the PG bit before setting the PER bit ([#579](https://github.com/stlink-org/stlink/pull/579), [#876](https://github.com/stlink-org/stlink/pull/876)) +* Fixed compilation issues with int length on 32-bit platforms ([#629](https://github.com/stlink-org/stlink/pull/629), [#908](https://github.com/stlink-org/stlink/pull/908)) +* Fixed st-info --probe mechanism ([#679](https://github.com/stlink-org/stlink/pull/679), [#918](https://github.com/stlink-org/stlink/pull/918)) +* [regression] Fixed sign-compare (size != rep_len) in usb.c ([#772](https://github.com/stlink-org/stlink/pull/772), [#869](https://github.com/stlink-org/stlink/pull/869), [#872](https://github.com/stlink-org/stlink/pull/872), [#891](https://github.com/stlink-org/stlink/pull/891)) +* Fixed dead loop after an unexpected unplug ([#780](https://github.com/stlink-org/stlink/pull/780), [#812](https://github.com/stlink-org/stlink/pull/812), [#913](https://github.com/stlink-org/stlink/pull/913)) +* Avoid re-define of O_BINARY on Windows ([#788](https://github.com/stlink-org/stlink/pull/788)) +* Fixed st-flash manpage read example ([#858](https://github.com/stlink-org/stlink/pull/858)) +* Fixed stlink support with no mass storage ([#861](https://github.com/stlink-org/stlink/pull/861)) +* Make Version.cmake more error-resistant ([#872](https://github.com/stlink-org/stlink/pull/872)) +* Error return in failed probe ([#887](https://github.com/stlink-org/stlink/pull/887), [#890](https://github.com/stlink-org/stlink/pull/890)) +* Fixed broken build on 32-bit systems ([#919](https://github.com/stlink-org/stlink/pull/919), [#920](https://github.com/stlink-org/stlink/pull/920)) +* st-flash: Minor usage fix and make cmdline parsing more user friendly ([#925](https://github.com/stlink-org/stlink/pull/925)) +* [regression] Restored functionality of make test builds ([#926](https://github.com/stlink-org/stlink/pull/926), [#929](https://github.com/stlink-org/stlink/pull/929)) +* Fixed compilation error due to uninitialized cpuid ([#937](https://github.com/stlink-org/stlink/pull/937), [#938](https://github.com/stlink-org/stlink/pull/938)) +* Fixes for STM32F0 flashloader ([#958](https://github.com/stlink-org/stlink/pull/958), [#959](https://github.com/stlink-org/stlink/pull/959)) +* Set static link for libssp (stack-smashing protection) ([#960](https://github.com/stlink-org/stlink/pull/960), [#961](https://github.com/stlink-org/stlink/pull/961)) +* Fixed udev rules installing to wrong directory ([#966](https://github.com/stlink-org/stlink/pull/966)) +* Fixed formatting for options display in st-flash & st-info (commits [#c783d0e](https://github.com/stlink-org/stlink/commit/c783d0e777ccc83a7a8be26a4f4d3414e0478560) and [#562cd24](https://github.com/stlink-org/stlink/commit/562cd2496e696dbd22950925866aac662d81ee5f)) v1.6.0 @@ -333,6 +342,7 @@ Updates and fixes: * Fixed STM32F2xx memory map (Nicolas Schodet) * Memory map for STM32F42xxx and STM32F43xxx devices (Craig Lilley) * Stm32l0x flash loader (Robin Kreis) +* Fixed segfault when programmer is already busy and NULL pointers are in the list ([#256](https://github.com/stlink-org/stlink/pull/256), [#394](https://github.com/stlink-org/stlink/pull/394)) * Send F4 memory-map and features for STM32F429 ([#188](https://github.com/stlink-org/stlink/pull/188), [#196](https://github.com/stlink-org/stlink/pull/196), [#250](https://github.com/stlink-org/stlink/pull/250), [#251](https://github.com/stlink-org/stlink/pull/251)) (Release v1.1.0) * Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/stlink-org/stlink/pull/218), [#288](https://github.com/stlink-org/stlink/pull/288)) (Release v1.1.0) * Corrected flash size register address for STM32F2 devices ([#278](https://github.com/stlink-org/stlink/pull/278)) (Release v1.0.0) diff --git a/doc/compiling.md b/doc/compiling.md index 2da79f071..428d9cc3c 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -153,11 +153,11 @@ $ debuild -uc -us ### Set permissions with udev By default most distributions don't allow access to USB devices. -Therefore make sure you install udev files which are necessary to run the tools without root permissions. +Therefore make sure you install udev files which are necessary to run the tools without root permissions.
      udev rules create devices nodes and set the group of these to `stlink`. -The rules are located in the subdirectory `etc/udev/rules.d` within the sourcefolder. -Copy them to the directory path `/etc/udev/rules.d` and subsequently reload the udev rules: +The rules are located in the subdirectory `config/udev/rules.d` within the sourcefolder and are automatically installed along with `sudo make install` on linux. +Afterwards it may be necessary to reload the udev rules: ```sh $ cp etc/udev/rules.d /etc/udev/rules.d @@ -165,18 +165,14 @@ $ udevadm control --reload-rules $ udevadm trigger ``` -Udev will now create device node files `/dev/stlinkv2_XX`, `/dev/stlinkv1_XX`. +Udev will now create device node files `/dev/stlinkv2_XX`, `/dev/stlinkv1_XX`.
      You need to ensure that the group `stlink` exists and the user who is trying to access these devices is a member of this group. -### Note on the use of STLink-v1 programmers: +### Note on the use of STLink-v1 programmers (legacy): -At the time of writing the STLink-v1 has mostly been replaced with the newer generation STLink-v2 programmers and thus is only rarely used. -As there are some caveats as well, we recommend to use the STLink-v2 programmers if possible. - -To be more precise, the STLINKv1's SCSI emulation is somehow broken, so the best advice possibly is to tell your operating system to completely ignore it. - -Choose on of the following options _before_ connecting the device to your computer: +As the STLINKv1's SCSI emulation is somehow broken, the best advice possibly is to tell your operating system to completely ignore it.
      +Choose one of the following options _before_ connecting the device to your computer: * `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` * _OR_ @@ -208,8 +204,8 @@ To do this with only one simple command, type: - with gcc: `sudo brew install git gcc cmake libusb gtk+3` or - with clang: `sudo brew install git llvm cmake libusb gtk+3` or * for MacPorts: - - with gcc: `sudo port install git llvm-9.0 cmake libusb gtk3` or - - with clang: `sudo port install git gcc9 cmake libusb gtk3` + - with gcc: `sudo port install git gcc10 cmake libusb gtk3` or + - with clang: `sudo port install git llvm-10 cmake libusb gtk3` ### Installation From a5dc016b42ab1faf872c8fce49521f1bacf28256 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 28 May 2020 11:42:26 +0200 Subject: [PATCH 0948/1435] Changed kext-path to /Library/Extensions --- CMakeLists.txt | 2 +- stlinkv1_macos_driver/README.md | 7 ++++--- stlinkv1_macos_driver/install.sh | 8 ++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b17fdc57..7e54b3fa2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,7 +143,7 @@ endif () set(STLINK_LIBRARY_PATH ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Main library install directory") # Set the environment variable LD_LIBRARY_PATH to point to /usr/local/lib (per default). -execute_process (COMMAND bash -c "export LD_LIBRARY_PATH="${CMAKE_INSTALL_LIBDIR}"") +execute_process (COMMAND bash -c "export LD_LIBRARY_PATH="${CMAKE_INSTALL_LIBDIR}" ") ### diff --git a/stlinkv1_macos_driver/README.md b/stlinkv1_macos_driver/README.md index 7221732c0..e0f9256e8 100644 --- a/stlinkv1_macos_driver/README.md +++ b/stlinkv1_macos_driver/README.md @@ -21,11 +21,12 @@ In order to deactivate SIP, boot into the recovery mode and run ```csrutil disab This should result in the following output: ``` -Requesting load of /System/Library/Extensions/stlink_shield.kext. -/System/Library/Extensions/stlink_shield.kext loaded successfully (or already loaded). +Requesting load of /Library/Extensions/stlink_shield.kext. +/Library/Extensions/stlink_shield.kext loaded successfully (or already loaded). ``` +4) Reboot the system. -4) Verify correct detection of the STLINK/v1 device with the following input: `st-util -1` +5) Verify correct detection of the STLINK/v1 device with the following input: `st-util -1` You should then see a similar output like in this example: ``` diff --git a/stlinkv1_macos_driver/install.sh b/stlinkv1_macos_driver/install.sh index 9e5f8d813..19e9f141d 100644 --- a/stlinkv1_macos_driver/install.sh +++ b/stlinkv1_macos_driver/install.sh @@ -10,13 +10,13 @@ case $ISMACOS in ;; 10.15*) KEXT="stlink_shield_10_15.kext" - ;; + ;; *) echo "OS X version not supported." exit 1 ;; esac chown -R root:wheel $KEXT/ -cp -R $KEXT /System/Library/Extensions/stlink_shield.kext -kextload -v /System/Library/Extensions/stlink_shield.kext -touch /System/Library/Extensions +cp -R $KEXT /Library/Extensions/stlink_shield.kext +kextload -v /Library/Extensions/stlink_shield.kext +touch /Library/Extensions From 7829600c9af2cd354f61fc9ed2165b58733d54de Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 28 May 2020 21:57:56 +0200 Subject: [PATCH 0949/1435] Preparation for Release v1.6.1 --- .version | 2 +- CHANGELOG.md | 3 ++- README.md | 4 +++- contributors.txt | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.version b/.version index ce6a70b9d..9c6d6293b 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.6.0 \ No newline at end of file +1.6.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 94c47e8fb..3195bae3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ stlink ChangeLog v1.6.1 ====== -Release date: 2020-06-xx +Release date: 2020-06-01 This release drops support for some older operating systems. Check project README for details. @@ -37,6 +37,7 @@ Updates & changes: * [doc] Updated tutorial: macOS ST-Link-v1 detection ([#574](https://github.com/stlink-org/stlink/pull/574), [#587](https://github.com/stlink-org/stlink/pull/587)) * Enhanced error log with file path for map_file() ([#650](https://github.com/stlink-org/stlink/pull/650), [#879](https://github.com/stlink-org/stlink/pull/879), [#921](https://github.com/stlink-org/stlink/pull/921)) * Enhanced output for error msg "addr not a multiple of pagesize, not supported" ([#663](https://github.com/stlink-org/stlink/pull/663), [#945](https://github.com/stlink-org/stlink/pull/945)) +* Updated STLink-v1 driver for macOS ([#735](https://github.com/stlink-org/stlink/pull/735), [#964](https://github.com/stlink-org/stlink/pull/964)) * Package distribution: Provide Windows binaries via Debian-based cross-build ([#738](https://github.com/stlink-org/stlink/pull/738), [#795](https://github.com/stlink-org/stlink/pull/795), [#798](https://github.com/stlink-org/stlink/pull/798), [#870](https://github.com/stlink-org/stlink/pull/870), [#955](https://github.com/stlink-org/stlink/pull/955)) - [refactoring] Update, corrections & cleanup for build settings (see #955 for details) - New cpack package-config for DEB and RPM build diff --git a/README.md b/README.md index 7dc634c9c..21ab9f48b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Open source version of the STMicroelectronics STlink Tools [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/stlink-org/stlink.svg)](https://github.com/stlink-org/stlink/releases/latest) [![Downloads](https://img.shields.io/github/downloads/stlink-org/stlink/total)](https://github.com/stlink-org/stlink/releases/latest) -![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.0/develop) +![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.1/develop) ![GitHub activity](https://img.shields.io/github/commit-activity/m/stlink-org/stlink) ![GitHub contributors](https://img.shields.io/github/contributors/stlink-org/stlink) [![Linux Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=linux&label=linux)](https://travis-ci.org/stlink-org/stlink) @@ -53,6 +53,8 @@ Currently known working combinations of programmers and targets are listed in [d Supported operating systems are listed in [version_support.md](doc/version_support.md). +The `stlink` toolset continues to maintain backwards compatibility with the **STLINK/v1** programmer.
      +Please note that on macOS this support is limited to versions 10.13 - 10.15. ## Tutorial & HOWTO diff --git a/contributors.txt b/contributors.txt index 8811da855..fec7510c3 100644 --- a/contributors.txt +++ b/contributors.txt @@ -13,6 +13,7 @@ Björn Hauffe Ihor Bobalo Breton M. Saunders Bruno Dal Bo +Brian Team [dot4qu] Burns Fisher Cheng Guokai (Xim) [chenguokai] Chris Dew From 2016590502558caa98c21abad2ce83c5f4804a98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Tempel?= Date: Mon, 1 Jun 2020 00:20:26 +0200 Subject: [PATCH 0950/1435] doc/man: Fix installation directory On Unix-like operating systems man pages are commonly installed to `/usr/share/man` not `/usr/share/stlink/man`. --- doc/man/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 23da9e150..9b3c50764 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -30,7 +30,7 @@ foreach (manpage ${MANPAGES}) endif () if (f AND NOT WIN32) - install(FILES ${f} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/man/man1) + install(FILES ${f} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/man/man1) unset(f) endif () endforeach () From e95b5ffcfe38c917a1f421c2257e58a3d9b2e8cc Mon Sep 17 00:00:00 2001 From: Vasiliy Glazov Date: Mon, 1 Jun 2020 08:44:11 +0300 Subject: [PATCH 0951/1435] Fix installation path for desktop-file and icons. This change fixes installation path for desktop-file and icons. They should be installed directly to ``` /usr/share/applications/ /usr/share/icons/hicolor/scalable/apps/ ``` --- src/stlink-gui/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index 8c36e5a1f..cc68509fe 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -13,11 +13,11 @@ if (NOT WIN32) # Install desktop application entry install(FILES stlink-gui.desktop - DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/applications) + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications) # Install icons install(FILES icons/stlink-gui.svg - DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/icons/hicolor/scalable/apps) + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps) set(GUI_SOURCES gui.c gui.h) From c774dca67676dbf06784ca088a6ff369ef4fe9ce Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Tue, 2 Jun 2020 17:46:05 +0300 Subject: [PATCH 0952/1435] link ssp as static only for WIN32 --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86282775e..ae7ddf971 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,11 @@ include(CheckLibraryExists) CHECK_LIBRARY_EXISTS(ssp __stack_chk_fail "" _stack_chk_fail_exists) if (_stack_chk_fail_exists) - set(SSP_LIB -static ssp) + if(WIN32) + set(SSP_LIB -static ssp) + else() + set(SSP_LIB -static ssp) + endif() else () set(SSP_LIB "") endif () From b1af21d396e5888a4df802d9364f172cd9260846 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Tue, 2 Jun 2020 17:55:34 +0300 Subject: [PATCH 0953/1435] link ssp as static only for WIN32 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae7ddf971..51d09412d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,7 @@ if (_stack_chk_fail_exists) if(WIN32) set(SSP_LIB -static ssp) else() - set(SSP_LIB -static ssp) + set(SSP_LIB ssp) endif() else () set(SSP_LIB "") From ade735dd671ea30ebbef36aaa17b51c6294425cf Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 3 Jun 2020 20:02:09 +0200 Subject: [PATCH 0954/1435] Moved unused pkg-config settings to /doc/dev (Closes #971) --- .gitignore | 2 +- CMakeLists.txt | 7 -- doc/compiling.md | 2 - doc/{ => dev}/app-example/CMakeLists.txt | 0 doc/{ => dev}/app-example/README.md | 0 doc/{ => dev}/app-example/main.c | 0 doc/{ => dev}/developer.txt | 115 ++++++++++-------- .../dev/pkg-config}/CMakeLists.txt | 0 .../dev/pkg-config}/pkgconfig.pc.cmake | 0 9 files changed, 67 insertions(+), 59 deletions(-) rename doc/{ => dev}/app-example/CMakeLists.txt (100%) rename doc/{ => dev}/app-example/README.md (100%) rename doc/{ => dev}/app-example/main.c (100%) rename doc/{ => dev}/developer.txt (93%) rename {cmake/pkgconfig => doc/dev/pkg-config}/CMakeLists.txt (100%) rename {cmake/pkgconfig => doc/dev/pkg-config}/pkgconfig.pc.cmake (100%) diff --git a/.gitignore b/.gitignore index 09b9b33de..229242a53 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ build build-mingw +.project obj-* *.user* -.project diff --git a/CMakeLists.txt b/CMakeLists.txt index 51d09412d..0538f3b14 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,13 +47,6 @@ endif () find_package(libusb REQUIRED) -## Package configuration (pkg-config) on unix-based systems -if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) - #add_subdirectory(cmake/pkgconfig) - find_package(PkgConfig) - pkg_check_modules(GTK3 gtk+-3.0) -endif () - ## Check for system-specific additional header files and libraries include(CheckIncludeFile) diff --git a/doc/compiling.md b/doc/compiling.md index 428d9cc3c..c278c9ca8 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -88,7 +88,6 @@ Install the following packages from your package repository: * `build-essential` (on Debian based distros (Debian, Ubuntu)) * `cmake` (3.4.2 or later, use the latest version available from the repository) * `rpm` (on Debian based distros (Debian, Ubuntu), needed for package build with `make package`) -* `pkg-config` * `libusb-1.0` * `libusb-1.0-0-dev` (development headers for building) * `libgtk-3-dev` (_optional_, needed for `stlink-gui`) @@ -194,7 +193,6 @@ Then install the following dependencies from the package repository: * `git` * `gcc` or `llvm` (for clang) (C-compiler) * `cmake` -* `pkg-config` * `libusb` * `gtk+3` or `gtk3` (_optional_, needed for `stlink-gui`) diff --git a/doc/app-example/CMakeLists.txt b/doc/dev/app-example/CMakeLists.txt similarity index 100% rename from doc/app-example/CMakeLists.txt rename to doc/dev/app-example/CMakeLists.txt diff --git a/doc/app-example/README.md b/doc/dev/app-example/README.md similarity index 100% rename from doc/app-example/README.md rename to doc/dev/app-example/README.md diff --git a/doc/app-example/main.c b/doc/dev/app-example/main.c similarity index 100% rename from doc/app-example/main.c rename to doc/dev/app-example/main.c diff --git a/doc/developer.txt b/doc/dev/developer.txt similarity index 93% rename from doc/developer.txt rename to doc/dev/developer.txt index 2d05b9312..4032eca3e 100644 --- a/doc/developer.txt +++ b/doc/dev/developer.txt @@ -1,4 +1,21 @@ - +=== Compilation with pkg-config === + +In order to use pkg-config for development purposes, add the following lines to the toplevel CMakeLists.txt file: + +### +# Additional build tasks +### + +## Package configuration (pkg-config) on unix-based systems +if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) + add_subdirectory(doc/dev/pkg-config) # Option A: external tool pkg-config + find_package(PkgConfig) # Option B: internal cmake module for pkg-config integration + pkg_check_modules(GTK3 gtk+-3.0) +endif () + +ToDo: Check for compatibility issues between options A and B. + + === Target Identification === The following information is available about the target: @@ -42,7 +59,7 @@ Include stlink/backend.h int (*current_mode) (stlink_t * stl); int (*force_debug) (stlink_t *sl); int32_t (*target_voltage) (stlink_t *sl); - int (*set_swdclk) (stlink_t * stl, uint16_t divisor); + int (*set_swdclk) (stlink_t * stl, uint16_t divisor); } stlink_backend_t; Descriptions below describe the actions of the usb.h backend: @@ -55,7 +72,7 @@ int (*exit_debug_mode) (stlink_t * sl); int (*enter_swd_mode) (stlink_t * sl); _stlink_usb_enter_swd_mode: Send STLINK_DEBUG_ENTER+STLINK_DEBUG_ENTER_SWD returns -1 or 0 - + int (*enter_jtag_mode) (stlink_t * stl); int (*exit_dfu_mode) (stlink_t * stl); @@ -65,19 +82,19 @@ int (*exit_dfu_mode) (stlink_t * stl); int (*core_id) (stlink_t * stl); _stlink_usb_core_id: Assign the result from STLINK_DEBUG_READCOREID to stl->core_id returns -1 or 0 - + int (*reset) (stlink_t * stl); _stlink_usb_reset: Send STLINK_DEBUG_RESETSYS and reset via AIRCR - AIRCR is part of the CMSIS System Control Block (SCB), which is located in + AIRCR is part of the CMSIS System Control Block (SCB), which is located in the System Control Space at 0xE000ED0C returns -1 or 0 ? - + int (*jtag_reset) (stlink_t * stl, int value); _stlink_usb_jtag_reset: Send STLINK_JTAG_DRIVE_NRST. "value" is sent as argument for STLINK_JTAG_DRIVE_NRST and probably contains the status of the NRST line (0: low, 1: high). Also the value 2 is used in the software. returns -1 or 0 - + int (*run) (stlink_t * stl); _stlink_usb_run: Send STLINK_DEBUG_RUNCORE returns -1 or 0 @@ -85,12 +102,12 @@ int (*run) (stlink_t * stl); int (*status) (stlink_t * stl); _stlink_usb_status: Assign the result from STLINK_DEBUG_GETSTATUS to stl->q_len returns -1 or 0 - + int (*version) (stlink_t *sl); _stlink_usb_version: Read version with STLINK_GET_VERSION. Result is stored in sl->q_buf (6 bytes????) returns -1 or 0 - + int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); _stlink_usb_read_debug32: Send STLINK_JTAG_READDEBUG_32BIT to read 32 bits from "addr". The result data is stored at "*data". @@ -99,10 +116,10 @@ int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); int (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); _stlink_usb_read_mem32: Use STLINK_DEBUG_READMEM_32BIT to read "len" bytes from "addr" - Result is returned in sl->q_buf, sl->q_len returns the size of the data (should be + Result is returned in sl->q_buf, sl->q_len returns the size of the data (should be equal to "len"???). returns -1 or 0 - + int (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); _stlink_usb_write_debug32: Use STLINK_JTAG_WRITEDEBUG_32BIT to store "data" at "addr" @@ -124,13 +141,13 @@ int (*read_all_regs) (stlink_t *sl, struct stlink_reg * regp); _stlink_usb_read_all_regs: Send STLINK_DEBUG_READALLREGS to read all register values and store them into *regp; returns -1 or 0 - + int (*read_reg) (stlink_t *sl, int r_idx, struct stlink_reg * regp); _stlink_usb_read_reg: Send STLINK_DEBUG_READREG to read specific register "r_idx". - The result is then stored in *regp in the correct register. + The result is then stored in *regp in the correct register. Example if "r_idx" is 18, then the result is stored in regp->process_sp returns -1 or 0 - + int (*read_all_unsupported_regs) (stlink_t *sl, struct stlink_reg *regp); _stlink_usb_read_all_unsupported_regs: Calls "_stlink_usb_read_unsupported_reg" (see below) to read all registers. @@ -142,7 +159,7 @@ int (*read_unsupported_reg) (stlink_t *sl, int r_idx, struct stlink_reg *regp); Also will fill regp->s (???) for some specific "r_idx" values. WARNING: Some r_idx values may lead to a out of array bound problem in C. returns -1 or 0 - + int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, struct stlink_reg *regp); _stlink_usb_write_unsupported_reg: Updates one of the following registers: @@ -154,14 +171,14 @@ int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, struct stli returns -1 or 0 int (*write_reg) (stlink_t *sl, uint32_t reg, int idx); - _stlink_usb_write_reg: Use STLINK_DEBUG_WRITEREG to update register "idx" + _stlink_usb_write_reg: Use STLINK_DEBUG_WRITEREG to update register "idx" with value "reg". returns -1 or 0 - + int (*step) (stlink_t * stl); _stlink_usb_step: Send STLINK_DEBUG_STEPCORE returns -1 or 0 - + int (*current_mode) (stlink_t * stl); _stlink_usb_current_mode: Send STLINK_GET_CURRENT_MODE and return the current mode. @@ -174,15 +191,15 @@ int (*current_mode) (stlink_t * stl); int (*force_debug) (stlink_t *sl); _stlink_usb_force_debug: Sends STLINK_DEBUG_FORCEDEBUG. No other side effects returns -1 or 0 - + int32_t (*target_voltage) (stlink_t *sl); _stlink_usb_target_voltage: Send STLINK_GET_TARGET_VOLTAGE returns -1 or the target voltage. (??? dimension is not clear...) -int (*set_swdclk) (stlink_t * stl, uint16_t divisor); +int (*set_swdclk) (stlink_t * stl, uint16_t divisor); _stlink_usb_set_swdclk: Send STLINK_DEBUG_APIV2_SWD_SET_FREQ and "divisor" value returns -1 or 0 - + === Other Functions === @@ -193,17 +210,17 @@ Include: stlink.h Prototype: void stlink_close(stlink_t *sl); Include: inc/stlink.h Definition: src/common.c -Description: +Description: Calls the backend "close" procedure and frees 'sl' Backend: "close" Arguments: sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() Return: - - + Include: inc/stlink.h Prototype: int stlink_core_id(stlink_t *sl); Definition: src/common.c -Description: +Description: Calls the backend "core_id", calls stlink_print_data() on higher verbose levels. Assigns the core id returned by STLINK_DEBUGREADCOREID to sl->core_id Only some specific core ids are used: See include/stm32.h @@ -216,8 +233,8 @@ Return: -1 for error. 0 for success. Include: inc/stlink.h Prototype: int stlink_reset(stlink_t *sl); Definition: src/common.c -Description: - Just calls the backend "reset" procedure (reset via STLINK_DEBUG_RESETSYS +Description: + Just calls the backend "reset" procedure (reset via STLINK_DEBUG_RESETSYS and reset via AIRCR register at 0xE000ED0C) Backend: "reset" Arguments: @@ -227,29 +244,29 @@ Return: -1 for error. 0 for success. Include: inc/stlink.h Prototype: int stlink_jtag_reset(stlink_t *sl, int value); Definition: src/common.c -Description: - Just calls the backend "jtag_reset" procedure +Description: + Just calls the backend "jtag_reset" procedure Backend: "jtag_reset" Arguments: sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() value: 0: drive low, 1: drive high, 2: ???? Return: -1 for error. 0 for success. - - + + Include: inc/stlink.h Prototype: int stlink_run(stlink_t *sl); Definition: src/common.c -Description: +Description: Just calls the backend "run" procedure. Backend: "run" Arguments: sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() Return: -1 for error. 0 for success. - + Include: inc/stlink.h Prototype: int stlink_status(stlink_t *sl); Definition: src/common.c -Description: +Description: Calls the backend "status" procedure and the procedure "stlink_core_stat()" to store the status in "sl->core_stat". Possible value for "sl->core_stat" are: STLINK_CORE_RUNNING @@ -259,12 +276,12 @@ Backend: "status" Arguments: sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() Return: -1 for error. 0 for success. - + Include: inc/stlink.h Prototype: int stlink_version(stlink_t *sl); Definition: src/common.c -Description: +Description: Calls the backend "version" procedure, parses the result and puts the result into sl->version This version probably refers to the version of the adapter. Backend: "version" @@ -272,9 +289,9 @@ Arguments: sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() Return: -1 for error. 0 for success. - + int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); - int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); + int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); @@ -305,9 +322,9 @@ Return: -1 for error. 0 for success. Include: inc/stlink.h Prototype: int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); Definition: src/common.c -Description: +Description: Tries to read out the chip id via memory read from the device. - Note: sl->chip_id is NOT updated by this procedure. Instead this happens in stlink_load_device_params(): + Note: sl->chip_id is NOT updated by this procedure. Instead this happens in stlink_load_device_params(): Do not call this function, but instead call stlink_load_device_params() Backend: - Arguments: @@ -319,7 +336,7 @@ Return: -1 for error. 0 for success. Include: inc/stlink.h Prototype: int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); Definition: src/common.c -Description: +Description: Reads the CPU id from STLINK_REG_CM3_CPUID (0xE000ED00, first value of the SCB, system control block) and splits this into cpuid->implementer_id @@ -333,19 +350,19 @@ Arguments: cpuid: Pointer. Result is stored via this pointer. Return: -1 for error. 0 for success. - - + + int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); uint16_t read_uint16(const unsigned char *c, const int pt); void stlink_core_stat(stlink_t *sl); - + Include: inc/stlink.h Prototype: void stlink_print_data(stlink_t *sl); Definition: src/common.c -Description: +Description: If debug logging is enabled: Print the HEX content of the q_buf array. q_buf will contain the result of the last "backend" command. Backend: - @@ -362,21 +379,21 @@ Return: - int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); - - + + Include: inc/stlink.h Prototype: int stlink_load_device_params(stlink_t *sl); Definition: src/common.c -Description: +Description: This is one of the most important procedures. It will get all the device info and store the results in the "sl" structure. Many other procedures will depend on this information. - The identification is based on the stlink_chip_id() result and the flash_size register value + The identification is based on the stlink_chip_id() result and the flash_size register value Backend: - Arguments: sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() Return: -1 for error. 0 for success. - + int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte); int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte); diff --git a/cmake/pkgconfig/CMakeLists.txt b/doc/dev/pkg-config/CMakeLists.txt similarity index 100% rename from cmake/pkgconfig/CMakeLists.txt rename to doc/dev/pkg-config/CMakeLists.txt diff --git a/cmake/pkgconfig/pkgconfig.pc.cmake b/doc/dev/pkg-config/pkgconfig.pc.cmake similarity index 100% rename from cmake/pkgconfig/pkgconfig.pc.cmake rename to doc/dev/pkg-config/pkgconfig.pc.cmake From 8f42f5443852bfb062fdb858a157d88a800470a9 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 4 Jun 2020 12:50:02 +0200 Subject: [PATCH 0955/1435] Deleted duplicated issue template --- ...ort--only-valid-if-template-is-reused--.md | 38 ------------------- 1 file changed, 38 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md diff --git a/.github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md b/.github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md deleted file mode 100644 index 255596955..000000000 --- a/.github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: Bug Report (only valid if template is reused!) -about: 'Please read #906 before submitting a ticket.' -title: "[STM32 device name]: [Title]" -labels: '' -assignees: '' - ---- - -Thank you for giving feedback to the stlink project. - -In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out each of the following items appropriate to your specific problem: - -- Programmer/board type: [enter here] (e.g Stlink /v1, /v2, /v2-clone, /v2-1) -- Programmer firmware version: [enter here] (e.g STSW-LINK007 2.27.15) -- Operating system and version: [enter here] (e.g Linux, Mac OS X, Windows) -- **Stlink tools version** and/or git commit hash: [enter here] (e.g v1.1.0/git-c722056) -- Stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-util`) -- Target chip (and board if applicable): [enter here] (e.g STM32F402VG) - -Futher we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: - -Commandline-Output: - -``` -OUTPUT/ERROR of the commandline tool(s) -``` - -Expected/description: - -`short description of the expected value` - - -**NOTICE: This bug report may be closed without further notice, if not enough information is provided!** - -Thank you for your support. - -The stlink project maintainers From 05f79e1cdf72a3a6ebdeac229842e39577e6700b Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 4 Jun 2020 21:33:34 +0200 Subject: [PATCH 0956/1435] [regression] Fixed GTK3 detection --- CMakeLists.txt | 2 +- doc/dev/developer.txt | 7 +------ src/stlink-gui/CMakeLists.txt | 7 ++++--- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0538f3b14..4055110ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,7 +140,7 @@ endif () set(STLINK_LIBRARY_PATH ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Main library install directory") # Set the environment variable LD_LIBRARY_PATH to point to /usr/local/lib (per default). -execute_process (COMMAND bash -c "export LD_LIBRARY_PATH="${CMAKE_INSTALL_LIBDIR}" ") +execute_process (COMMAND bash -c "export LD_LIBRARY_PATH=${CMAKE_INSTALL_LIBDIR}") ### diff --git a/doc/dev/developer.txt b/doc/dev/developer.txt index 4032eca3e..32afd4352 100644 --- a/doc/dev/developer.txt +++ b/doc/dev/developer.txt @@ -8,14 +8,9 @@ In order to use pkg-config for development purposes, add the following lines to ## Package configuration (pkg-config) on unix-based systems if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) - add_subdirectory(doc/dev/pkg-config) # Option A: external tool pkg-config - find_package(PkgConfig) # Option B: internal cmake module for pkg-config integration - pkg_check_modules(GTK3 gtk+-3.0) + add_subdirectory(doc/dev/pkg-config) # external tool pkg-config endif () -ToDo: Check for compatibility issues between options A and B. - - === Target Identification === The following information is available about the target: diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index cc68509fe..89e5403d8 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -2,7 +2,10 @@ # Build GUI ### -if (NOT WIN32) +if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) + find_package(PkgConfig) + pkg_check_modules(GTK3 gtk+-3.0) + ## GUI-Building requires the presence of a GTK3 toolset if (NOT GTK3_FOUND) message(STATUS "GTK3 not found!") @@ -35,7 +38,5 @@ if (NOT WIN32) COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/bin") target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) install(TARGETS stlink-gui DESTINATION ${CMAKE_INSTALL_BINDIR}) - - endif () endif () From c7041cc2be2582caca522c18babeb40aadcc246f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 4 Jun 2020 21:53:17 +0200 Subject: [PATCH 0957/1435] Reorganised project source directories (Closes #976) --- CMakeLists.txt | 62 +++-- doc/dev/developer.txt | 4 +- inc/CMakeLists.txt | 9 + {include => inc}/stlink.h | 0 {include => inc}/stm32.h | 0 {include/stlink => inc}/version.h.in | 0 include/CMakeLists.txt | 9 - {include/stlink => src}/backend.h | 0 {include/stlink => src}/commands.h | 0 src/common.c | 6 +- src/{ => mmap}/mmap.c | 0 src/{ => mmap}/mmap.h | 0 {include/stlink => src}/reg.h | 0 src/{tools => st-flash}/flash.c | 2 +- .../stlink/tools => src/st-flash}/flash.h | 0 src/{tools => st-flash}/flash_opts.c | 2 +- src/{tools => st-info}/info.c | 0 src/st-util/semihosting.c | 59 ++--- src/stlink-gui/CMakeLists.txt | 7 +- src/{ => stlink-lib}/chipid.c | 2 +- {include/stlink => src/stlink-lib}/chipid.h | 0 src/{ => stlink-lib}/flash_loader.c | 243 +++++++++--------- .../stlink => src/stlink-lib}/flash_loader.h | 0 src/{ => stlink-lib}/logging.c | 0 src/{ => stlink-lib}/logging.h | 0 src/{ => stlink-lib}/md5.c | 0 src/{ => stlink-lib}/md5.h | 0 src/{ => stlink-lib}/sg.c | 1 + src/{ => stlink-lib}/sg.h | 2 +- src/{ => stlink-lib}/usb.c | 3 +- src/{ => stlink-lib}/usb.h | 2 +- tests/CMakeLists.txt | 2 +- 32 files changed, 193 insertions(+), 222 deletions(-) create mode 100644 inc/CMakeLists.txt rename {include => inc}/stlink.h (100%) rename {include => inc}/stm32.h (100%) rename {include/stlink => inc}/version.h.in (100%) delete mode 100644 include/CMakeLists.txt rename {include/stlink => src}/backend.h (100%) rename {include/stlink => src}/commands.h (100%) rename src/{ => mmap}/mmap.c (100%) rename src/{ => mmap}/mmap.h (100%) rename {include/stlink => src}/reg.h (100%) rename src/{tools => st-flash}/flash.c (99%) rename {include/stlink/tools => src/st-flash}/flash.h (100%) rename src/{tools => st-flash}/flash_opts.c (99%) rename src/{tools => st-info}/info.c (100%) rename src/{ => stlink-lib}/chipid.c (99%) rename {include/stlink => src/stlink-lib}/chipid.h (100%) rename src/{ => stlink-lib}/flash_loader.c (71%) rename {include/stlink => src/stlink-lib}/flash_loader.h (100%) rename src/{ => stlink-lib}/logging.c (100%) rename src/{ => stlink-lib}/logging.h (100%) rename src/{ => stlink-lib}/md5.c (100%) rename src/{ => stlink-lib}/md5.h (100%) rename src/{ => stlink-lib}/sg.c (99%) rename src/{ => stlink-lib}/sg.h (98%) rename src/{ => stlink-lib}/usb.c (99%) rename src/{ => stlink-lib}/usb.h (98%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0538f3b14..854ce9ed5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,43 +81,41 @@ endif () ## Define include directories to avoid absolute paths for header defines include_directories(${LIBUSB_INCLUDE_DIR}) -# ==== -include_directories(${PROJECT_SOURCE_DIR}/include) ### TODO: Clean this up... -include_directories(${PROJECT_BINARY_DIR}/include/stlink) -include_directories(${PROJECT_SOURCE_DIR}/include/stlink) -include_directories(${PROJECT_SOURCE_DIR}/include/stlink/tools) -# ==== +include_directories(${PROJECT_SOURCE_DIR}/inc) # contains top-level header files +include_directories(${PROJECT_BINARY_DIR}/inc) # contains version.h include_directories(src) -include_directories(src/tools) ### TODO: Clean this up... +include_directories(src/mmap) +include_directories(src/st-flash) +include_directories(src/stlink-lib) set(STLINK_HEADERS - include/stlink.h - include/stlink/backend.h - include/stlink/chipid.h - include/stlink/commands.h - include/stlink/flash_loader.h - include/stlink/reg.h - src/logging.h - src/md5.h - src/sg.h - src/usb.h + inc/stlink.h + src/backend.h + src/commands.h + src/reg.h + src/stlink-lib/chipid.h + src/stlink-lib/flash_loader.h + src/stlink-lib/logging.h + src/stlink-lib/md5.h + src/stlink-lib/sg.h + src/stlink-lib/usb.h ) set(STLINK_SOURCE src/common.c - src/chipid.c - src/flash_loader.c - src/logging.c - src/md5.c - src/sg.c - src/usb.c + src/stlink-lib/chipid.c + src/stlink-lib/flash_loader.c + src/stlink-lib/logging.c + src/stlink-lib/md5.c + src/stlink-lib/sg.c + src/stlink-lib/usb.c ) if (WIN32 OR MINGW OR MSYS) include_directories(src/mingw) - set(STLINK_SOURCE "${STLINK_SOURCE};src/mmap.c;src/mingw/mingw.c") - set(STLINK_HEADERS "${STLINK_HEADERS};src/mmap.h;src/mingw/mingw.h") + set(STLINK_SOURCE "${STLINK_SOURCE};src/mmap/mmap.c;src/mingw/mingw.c") + set(STLINK_HEADERS "${STLINK_HEADERS};src/mmap/mmap.h;src/mingw/mingw.h") endif () if (MSVC) @@ -140,7 +138,7 @@ endif () set(STLINK_LIBRARY_PATH ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Main library install directory") # Set the environment variable LD_LIBRARY_PATH to point to /usr/local/lib (per default). -execute_process (COMMAND bash -c "export LD_LIBRARY_PATH="${CMAKE_INSTALL_LIBDIR}" ") +execute_process (COMMAND bash -c "export LD_LIBRARY_PATH=${CMAKE_INSTALL_LIBDIR}") ### @@ -221,6 +219,8 @@ install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH}) # Build toolset executables ### +set(ST-FLASH_SOURCES src/st-flash/flash.c src/st-flash/flash_opts.c) +set(ST-INFO_SOURCES src/st-info/info.c) set(ST-UTIL_SOURCES src/st-util/gdb-remote.c src/st-util/gdb-server.c src/st-util/semihosting.c) if (MSVC) @@ -228,8 +228,8 @@ if (MSVC) set(ST-UTIL_SOURCES "${ST-UTIL_SOURCES};src/getopt/getopt.c") endif () -add_executable(st-flash src/tools/flash.c src/tools/flash_opts.c) -add_executable(st-info src/tools/info.c) +add_executable(st-flash ${ST-FLASH_SOURCES}) +add_executable(st-info ${ST-INFO_SOURCES}) add_executable(st-util ${ST-UTIL_SOURCES}) if (WIN32 OR APPLE) @@ -267,11 +267,7 @@ endif () # Additional build tasks ### -# ==== -add_subdirectory(include) # contains subordinate CMakeLists for version config and old header includes - ### TODO: Clean this up ... -# ==== - +add_subdirectory(inc) # contains subordinate CMakeLists for version config add_subdirectory(src/stlink-gui) # contains subordinate CMakeLists to build GUI add_subdirectory(tests) # contains subordinate CMakeLists to build test executables add_subdirectory(cmake/packaging) # contains subordinate CMakeLists to build packages diff --git a/doc/dev/developer.txt b/doc/dev/developer.txt index 4032eca3e..077234e54 100644 --- a/doc/dev/developer.txt +++ b/doc/dev/developer.txt @@ -8,9 +8,7 @@ In order to use pkg-config for development purposes, add the following lines to ## Package configuration (pkg-config) on unix-based systems if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) - add_subdirectory(doc/dev/pkg-config) # Option A: external tool pkg-config - find_package(PkgConfig) # Option B: internal cmake module for pkg-config integration - pkg_check_modules(GTK3 gtk+-3.0) + add_subdirectory(doc/dev/pkg-config) # external tool pkg-config endif () ToDo: Check for compatibility issues between options A and B. diff --git a/inc/CMakeLists.txt b/inc/CMakeLists.txt new file mode 100644 index 000000000..66af7e33f --- /dev/null +++ b/inc/CMakeLists.txt @@ -0,0 +1,9 @@ +configure_file( + "${PROJECT_SOURCE_DIR}/inc/version.h.in" + "${CMAKE_BINARY_DIR}/inc/version.h" + ) + +file(GLOB STLINK_HEADERS "src/st-link-lib/*.h" "${CMAKE_BINARY_DIR}/inc/version.h") +install(FILES ${STLINK_HEADERS} DESTINATION ${STLINK_INCLUDE_PATH}) +install(FILES ${CMAKE_SOURCE_DIR}/inc/stlink.h DESTINATION ${STLINK_INCLUDE_PATH}) +install(FILES ${CMAKE_SOURCE_DIR}/inc/stm32.h DESTINATION ${STLINK_INCLUDE_PATH}) diff --git a/include/stlink.h b/inc/stlink.h similarity index 100% rename from include/stlink.h rename to inc/stlink.h diff --git a/include/stm32.h b/inc/stm32.h similarity index 100% rename from include/stm32.h rename to inc/stm32.h diff --git a/include/stlink/version.h.in b/inc/version.h.in similarity index 100% rename from include/stlink/version.h.in rename to inc/version.h.in diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt deleted file mode 100644 index 6cf397659..000000000 --- a/include/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -configure_file( - "${PROJECT_SOURCE_DIR}/include/stlink/version.h.in" - "${CMAKE_BINARY_DIR}/include/stlink/version.h" - ) - -file(GLOB STLINK_HEADERS "stlink/*.h" "${CMAKE_BINARY_DIR}/include/stlink/*.h") -install(FILES ${CMAKE_SOURCE_DIR}/include/stlink.h DESTINATION ${STLINK_INCLUDE_PATH}) -install(FILES ${CMAKE_SOURCE_DIR}/include/stm32.h DESTINATION ${STLINK_INCLUDE_PATH}) -install(FILES ${STLINK_HEADERS} DESTINATION ${STLINK_INCLUDE_PATH}/stlink) diff --git a/include/stlink/backend.h b/src/backend.h similarity index 100% rename from include/stlink/backend.h rename to src/backend.h diff --git a/include/stlink/commands.h b/src/commands.h similarity index 100% rename from include/stlink/commands.h rename to src/commands.h diff --git a/src/common.c b/src/common.c index e8f7cebc6..fb669e255 100644 --- a/src/common.c +++ b/src/common.c @@ -12,9 +12,9 @@ #include #include -#include "mmap.h" -#include "logging.h" -#include "md5.h" +#include +#include +#include #ifndef O_BINARY #define O_BINARY 0 diff --git a/src/mmap.c b/src/mmap/mmap.c similarity index 100% rename from src/mmap.c rename to src/mmap/mmap.c diff --git a/src/mmap.h b/src/mmap/mmap.h similarity index 100% rename from src/mmap.h rename to src/mmap/mmap.h diff --git a/include/stlink/reg.h b/src/reg.h similarity index 100% rename from include/stlink/reg.h rename to src/reg.h diff --git a/src/tools/flash.c b/src/st-flash/flash.c similarity index 99% rename from src/tools/flash.c rename to src/st-flash/flash.c index 3a83daf8a..fc62bcf15 100644 --- a/src/tools/flash.c +++ b/src/st-flash/flash.c @@ -9,7 +9,7 @@ #include #include -#include +#include "flash.h" static stlink_t *connected_stlink = NULL; diff --git a/include/stlink/tools/flash.h b/src/st-flash/flash.h similarity index 100% rename from include/stlink/tools/flash.h rename to src/st-flash/flash.h diff --git a/src/tools/flash_opts.c b/src/st-flash/flash_opts.c similarity index 99% rename from src/tools/flash_opts.c rename to src/st-flash/flash_opts.c index c8d7841de..9d8d3225b 100644 --- a/src/tools/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -2,7 +2,7 @@ #include #include -#include +#include "flash.h" static bool starts_with(const char * str, const char * prefix) { size_t n = strlen(prefix); diff --git a/src/tools/info.c b/src/st-info/info.c similarity index 100% rename from src/tools/info.c rename to src/st-info/info.c diff --git a/src/st-util/semihosting.c b/src/st-util/semihosting.c index fed66ab60..cb03868cd 100644 --- a/src/st-util/semihosting.c +++ b/src/st-util/semihosting.c @@ -9,70 +9,52 @@ #include #include "semihosting.h" -static int mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) -{ +static int mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) { int offset = addr % 4; int len = 4; - if (sl == NULL || data == NULL) { - return -1; - } + if (sl == NULL || data == NULL) return -1; /* Read address and length must be aligned */ - if (stlink_read_mem32(sl, addr - offset, len) != 0) { - return -1; - } + if (stlink_read_mem32(sl, addr - offset, len) != 0) return -1; *data = sl->q_buf[offset]; return 0; } #ifdef UNUSED -static int mem_read_u16(stlink_t *sl, uint32_t addr, uint16_t *data) -{ +static int mem_read_u16(stlink_t *sl, uint32_t addr, uint16_t *data) { int offset = addr % 4; int len = (offset > 2 ? 8 : 4); - if (sl == NULL || data == NULL) { - return -1; - } + if (sl == NULL || data == NULL) return -1; /* Read address and length must be aligned */ - if (stlink_read_mem32(sl, addr - offset, len) != 0) { - return -1; - } + if (stlink_read_mem32(sl, addr - offset, len) != 0) return -1; memcpy(data, &sl->q_buf[offset], sizeof(*data)); return 0; } -static int mem_read_u32(stlink_t *sl, uint32_t addr, uint32_t *data) -{ +static int mem_read_u32(stlink_t *sl, uint32_t addr, uint32_t *data) { int offset = addr % 4; int len = (offset > 0 ? 8 : 4); - if (sl == NULL || data == NULL) { - return -1; - } + if (sl == NULL || data == NULL) return -1; /* Read address and length must be aligned */ - if (stlink_read_mem32(sl, addr - offset, len) != 0) { - return -1; - } + if (stlink_read_mem32(sl, addr - offset, len) != 0) return -1; memcpy(data, &sl->q_buf[offset], sizeof(*data)); return 0; } #endif -static int mem_read(stlink_t *sl, uint32_t addr, void *data, uint16_t len) -{ +static int mem_read(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { int offset = addr % 4; int read_len = len + offset; - if (sl == NULL || data == NULL) { - return -1; - } + if (sl == NULL || data == NULL) return -1; /* Align read size */ if ((read_len % 4) != 0) { @@ -80,16 +62,13 @@ static int mem_read(stlink_t *sl, uint32_t addr, void *data, uint16_t len) } /* Address and length must be aligned */ - if (stlink_read_mem32(sl, addr - offset, read_len) != 0) { - return -1; - } + if (stlink_read_mem32(sl, addr - offset, read_len) != 0) return -1; memcpy(data, &sl->q_buf[offset], len); return 0; } -static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) -{ +static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { // Note: this function can write more than it is asked to! // If addr is not an even 32 bit boundary, or len is not a multiple of 4. // @@ -106,9 +85,7 @@ static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) int offset = addr % 4; int write_len = len + offset; - if (sl == NULL || data == NULL) { - return -1; - } + if (sl == NULL || data == NULL) return -1; /* Align read size */ if ((write_len % 4) != 0) { @@ -118,9 +95,7 @@ static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) memcpy(&sl->q_buf[offset], data, len); /* Address and length must be aligned */ - if (stlink_write_mem32(sl, addr - offset, write_len) != 0) { - return -1; - } + if (stlink_write_mem32(sl, addr - offset, write_len) != 0) return -1; return 0; } @@ -162,9 +137,7 @@ static int saved_errno = 0; int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { - if (sl == NULL || ret == NULL) { - return -1; - } + if (sl == NULL || ret == NULL) return -1; DLOG("Do semihosting R0=0x%08x R1=0x%08x\n", r0, r1); diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index cc68509fe..89e5403d8 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -2,7 +2,10 @@ # Build GUI ### -if (NOT WIN32) +if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) + find_package(PkgConfig) + pkg_check_modules(GTK3 gtk+-3.0) + ## GUI-Building requires the presence of a GTK3 toolset if (NOT GTK3_FOUND) message(STATUS "GTK3 not found!") @@ -35,7 +38,5 @@ if (NOT WIN32) COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/bin") target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) install(TARGETS stlink-gui DESTINATION ${CMAKE_INSTALL_BINDIR}) - - endif () endif () diff --git a/src/chipid.c b/src/stlink-lib/chipid.c similarity index 99% rename from src/chipid.c rename to src/stlink-lib/chipid.c index fcc1c55eb..e6a82a2a9 100644 --- a/src/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1,5 +1,5 @@ #include -#include +#include "chipid.h" static const struct stlink_chipid_params devices[] = { { diff --git a/include/stlink/chipid.h b/src/stlink-lib/chipid.h similarity index 100% rename from include/stlink/chipid.h rename to src/stlink-lib/chipid.h diff --git a/src/flash_loader.c b/src/stlink-lib/flash_loader.c similarity index 71% rename from src/flash_loader.c rename to src/stlink-lib/flash_loader.c index a2c5879ce..b97a6edaa 100644 --- a/src/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -3,6 +3,7 @@ #include #include +#include "flash_loader.h" #define FLASH_REGS_BANK2_OFS 0x40 #define FLASH_BANK2_START_ADDR 0x08080000 @@ -11,164 +12,164 @@ /* flashloaders/stm32f0.s -- compiled with thumb2 */ static const uint8_t loader_code_stm32vl[] = { - 0x16, 0x4f, 0x3c, 0x68, - 0x16, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x16, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, - 0x4f, 0xf0, 0x01, 0x07, - 0x33, 0x68, 0x3b, 0x43, - 0x33, 0x60, 0x03, 0x88, - 0x0b, 0x80, 0x4f, 0xf0, - 0x02, 0x07, 0xc0, 0x19, - 0xc9, 0x19, 0x4f, 0xf0, - 0x01, 0x07, 0x2b, 0x68, - 0x3b, 0x42, 0xfa, 0xd0, - 0x4f, 0xf0, 0x04, 0x07, - 0x3b, 0x42, 0x04, 0xd1, - 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xe6, 0xd1, 0x4f, 0xf0, - 0x01, 0x07, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x20, 0x02, 0x40, - 0x10, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x20, - 0x54, 0x00, 0x00, 0x20, + 0x16, 0x4f, 0x3c, 0x68, + 0x16, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x16, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x4f, 0xf0, 0x01, 0x07, + 0x33, 0x68, 0x3b, 0x43, + 0x33, 0x60, 0x03, 0x88, + 0x0b, 0x80, 0x4f, 0xf0, + 0x02, 0x07, 0xc0, 0x19, + 0xc9, 0x19, 0x4f, 0xf0, + 0x01, 0x07, 0x2b, 0x68, + 0x3b, 0x42, 0xfa, 0xd0, + 0x4f, 0xf0, 0x04, 0x07, + 0x3b, 0x42, 0x04, 0xd1, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xe6, 0xd1, 0x4f, 0xf0, + 0x01, 0x07, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x20, + 0x54, 0x00, 0x00, 0x20, 0x58, 0x00, 0x00, 0x20 }; /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ static const uint8_t loader_code_stm32f0[] = { - 0xc0, 0x46, 0xc0, 0x46, - 0x13, 0x4f, 0x3c, 0x68, - 0x13, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x13, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, - 0x12, 0x4f, 0x33, 0x68, - 0x3b, 0x43, 0x33, 0x60, - 0x03, 0x88, 0x0b, 0x80, - 0x10, 0x4f, 0xc0, 0x19, - 0xc9, 0x19, 0x0e, 0x4f, - 0x2b, 0x68, 0x3b, 0x42, - 0xfb, 0xd0, 0x0e, 0x4f, - 0x3b, 0x42, 0x03, 0xd1, - 0x0a, 0x4f, 0xd2, 0x1b, - 0x00, 0x2a, 0xeb, 0xd1, - 0x08, 0x4f, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0xc0, 0x46, - 0x00, 0x20, 0x02, 0x40, - 0x10, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x20, - 0x4c, 0x00, 0x00, 0x20, - 0x50, 0x00, 0x00, 0x20, - 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, + 0xc0, 0x46, 0xc0, 0x46, + 0x13, 0x4f, 0x3c, 0x68, + 0x13, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x13, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x12, 0x4f, 0x33, 0x68, + 0x3b, 0x43, 0x33, 0x60, + 0x03, 0x88, 0x0b, 0x80, + 0x10, 0x4f, 0xc0, 0x19, + 0xc9, 0x19, 0x0e, 0x4f, + 0x2b, 0x68, 0x3b, 0x42, + 0xfb, 0xd0, 0x0e, 0x4f, + 0x3b, 0x42, 0x03, 0xd1, + 0x0a, 0x4f, 0xd2, 0x1b, + 0x00, 0x2a, 0xeb, 0xd1, + 0x08, 0x4f, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0xc0, 0x46, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x20, + 0x4c, 0x00, 0x00, 0x20, + 0x50, 0x00, 0x00, 0x20, + 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32l[] = { // flashloaders/stm32lx.s - 0x03, 0x68, 0x0b, 0x60, - 0x4f, 0xf0, 0x04, 0x07, - 0x38, 0x44, 0x39, 0x44, - 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, + 0x03, 0x68, 0x0b, 0x60, + 0x4f, 0xf0, 0x04, 0x07, + 0x38, 0x44, 0x39, 0x44, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, 0xf4, 0xd1, 0x00, 0xbe, }; static const uint8_t loader_code_stm32f4[] = { // flashloaders/stm32f4.s - 0xdf, 0xf8, 0x28, 0xc0, - 0xdf, 0xf8, 0x28, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, - 0x04, 0x00, 0x01, 0xf1, - 0x04, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, 0x0e, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32f4_lv[] = { // flashloaders/stm32f4lv.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, - 0x01, 0x00, 0x01, 0xf1, - 0x01, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, 0x0e, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32l4[] = { // flashloaders/stm32l4.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x44, 0x68, 0x0b, 0x60, - 0x4c, 0x60, 0x00, 0xf1, - 0x08, 0x00, 0x01, 0xf1, - 0x08, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x20, 0x02, 0x40, + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x44, 0x68, 0x0b, 0x60, + 0x4c, 0x60, 0x00, 0xf1, + 0x08, 0x00, 0x01, 0xf1, + 0x08, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, 0x12, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32f7[] = { // flashloaders/stm32f7.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, - 0x04, 0x00, 0x01, 0xf1, - 0x04, 0x01, 0xbf, 0xf3, - 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, 0x0e, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32f7_lv[] = { // flashloaders/stm32f7lv.s - 0xdf, 0xf8, 0x30, 0xc0, - 0xdf, 0xf8, 0x30, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, - 0x01, 0x00, 0x01, 0xf1, - 0x01, 0x01, 0xbf, 0xf3, - 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, + 0xdf, 0xf8, 0x30, 0xc0, + 0xdf, 0xf8, 0x30, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, 0x0e, 0x00, 0x00, 0x00 }; diff --git a/include/stlink/flash_loader.h b/src/stlink-lib/flash_loader.h similarity index 100% rename from include/stlink/flash_loader.h rename to src/stlink-lib/flash_loader.h diff --git a/src/logging.c b/src/stlink-lib/logging.c similarity index 100% rename from src/logging.c rename to src/stlink-lib/logging.c diff --git a/src/logging.h b/src/stlink-lib/logging.h similarity index 100% rename from src/logging.h rename to src/stlink-lib/logging.h diff --git a/src/md5.c b/src/stlink-lib/md5.c similarity index 100% rename from src/md5.c rename to src/stlink-lib/md5.c diff --git a/src/md5.h b/src/stlink-lib/md5.h similarity index 100% rename from src/md5.h rename to src/stlink-lib/md5.h diff --git a/src/sg.c b/src/stlink-lib/sg.c similarity index 99% rename from src/sg.c rename to src/stlink-lib/sg.c index 798cda9ab..7fae19976 100644 --- a/src/sg.c +++ b/src/stlink-lib/sg.c @@ -84,6 +84,7 @@ #include #include "logging.h" +#include "sg.h" #define STLINK_OK 0x80 #define STLINK_FALSE 0x81 diff --git a/src/sg.h b/src/stlink-lib/sg.h similarity index 98% rename from src/sg.h rename to src/stlink-lib/sg.h index 3a8a7a239..811b339c7 100644 --- a/src/sg.h +++ b/src/stlink-lib/sg.h @@ -8,8 +8,8 @@ #ifndef STLINK_SG_H #define STLINK_SG_H -#include "libusb_settings.h" #include +#include #ifdef __cplusplus extern "C" { diff --git a/src/usb.c b/src/stlink-lib/usb.c similarity index 99% rename from src/usb.c rename to src/stlink-lib/usb.c index a711749da..b76639731 100644 --- a/src/usb.c +++ b/src/stlink-lib/usb.c @@ -14,6 +14,7 @@ #include #endif #include +#include "usb.h" enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80}; @@ -1147,7 +1148,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL if (reset == 2) { stlink_jtag_reset(sl,0); - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); stlink_force_debug(sl); stlink_jtag_reset(sl,1); usleep(10000); diff --git a/src/usb.h b/src/stlink-lib/usb.h similarity index 98% rename from src/usb.h rename to src/stlink-lib/usb.h index 5c1f5b7ca..3581eabf1 100644 --- a/src/usb.h +++ b/src/stlink-lib/usb.h @@ -11,7 +11,7 @@ #include #include -#include "libusb_settings.h" +#include #include "logging.h" #ifdef __cplusplus diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6e60fdd5a..a3011fc7e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -11,6 +11,6 @@ foreach (test ${TESTEXEC}) add_test(test-${test} ${CMAKE_BINARY_DIR}/bin/test-${test}) endforeach () -add_executable(test-flash flash.c "${CMAKE_SOURCE_DIR}/src/tools/flash_opts.c") +add_executable(test-flash flash.c "${CMAKE_SOURCE_DIR}/src/st-flash/flash_opts.c") target_link_libraries(test-flash ${STLINK_LIB_SHARED} ${SSP_LIB}) add_test(test-flash ${CMAKE_BINARY_DIR}/bin/test-flash) From e895a7c85e8150bf6874f7831d3bee247418091b Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 5 Jun 2020 16:41:47 +0200 Subject: [PATCH 0958/1435] [refactoring] Build settings for win32 - Grouped source files for win32 - Whitespace & code style cleanup --- CMakeLists.txt | 62 ++++--- src/common.c | 100 ++++++------ src/mmap/mmap.h | 31 ---- src/st-util/gdb-remote.c | 4 +- src/st-util/gdb-server.c | 2 +- src/stlink-lib/usb.c | 5 +- src/{ => win32}/getopt/LICENSE.txt | 0 src/{ => win32}/getopt/README.md | 0 src/{ => win32}/getopt/getopt.c | 0 src/{ => win32}/getopt/getopt.h | 0 src/{mmap => win32}/mmap.c | 1 - src/win32/mmap.h | 29 ++++ src/win32/{ => unistd}/unistd.h | 0 src/{mingw/mingw.c => win32/win32_socket.c} | 171 +++++++++----------- src/{mingw/mingw.h => win32/win32_socket.h} | 20 +-- 15 files changed, 206 insertions(+), 219 deletions(-) delete mode 100644 src/mmap/mmap.h rename src/{ => win32}/getopt/LICENSE.txt (100%) rename src/{ => win32}/getopt/README.md (100%) rename src/{ => win32}/getopt/getopt.c (100%) rename src/{ => win32}/getopt/getopt.h (100%) rename src/{mmap => win32}/mmap.c (99%) create mode 100644 src/win32/mmap.h rename src/win32/{ => unistd}/unistd.h (100%) rename src/{mingw/mingw.c => win32/win32_socket.c} (59%) rename src/{mingw/mingw.h => win32/win32_socket.h} (81%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 854ce9ed5..c1ced137d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,29 +48,34 @@ endif () find_package(libusb REQUIRED) ## Check for system-specific additional header files and libraries + include(CheckIncludeFile) +include(CheckLibraryExists) + +CHECK_LIBRARY_EXISTS(ssp __stack_chk_fail "" _stack_chk_fail_exists) +if (_stack_chk_fail_exists) + if (WIN32) + set(SSP_LIB -static ssp) + else () + set(SSP_LIB ssp) + endif () +else () + set(SSP_LIB "") +endif () CHECK_INCLUDE_FILE(sys/mman.h STLINK_HAVE_SYS_MMAN_H) if (STLINK_HAVE_SYS_MMAN_H) add_definitions(-DSTLINK_HAVE_SYS_MMAN_H) -endif () +endif() CHECK_INCLUDE_FILE(unistd.h STLINK_HAVE_UNISTD_H) if (STLINK_HAVE_UNISTD_H) add_definitions(-DSTLINK_HAVE_UNISTD_H) endif () -include(CheckLibraryExists) - -CHECK_LIBRARY_EXISTS(ssp __stack_chk_fail "" _stack_chk_fail_exists) -if (_stack_chk_fail_exists) - if(WIN32) - set(SSP_LIB -static ssp) - else() - set(SSP_LIB ssp) - endif() -else () - set(SSP_LIB "") +if (MSVC) + # Use string.h rather than strings.h and disable annoying warnings + add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) endif () @@ -85,10 +90,14 @@ include_directories(${PROJECT_SOURCE_DIR}/inc) # contains top-level header files include_directories(${PROJECT_BINARY_DIR}/inc) # contains version.h include_directories(src) -include_directories(src/mmap) include_directories(src/st-flash) include_directories(src/stlink-lib) +if (MSVC) + include_directories(src/win32) + include_directories(src/win32/unistd) +endif () + set(STLINK_HEADERS inc/stlink.h src/backend.h @@ -112,17 +121,21 @@ set(STLINK_SOURCE src/stlink-lib/usb.c ) -if (WIN32 OR MINGW OR MSYS) - include_directories(src/mingw) - set(STLINK_SOURCE "${STLINK_SOURCE};src/mmap/mmap.c;src/mingw/mingw.c") - set(STLINK_HEADERS "${STLINK_HEADERS};src/mmap/mmap.h;src/mingw/mingw.h") -endif () - -if (MSVC) +if (WIN32) include_directories(src/win32) - include_directories(src/getopt) - # Use string.h rather than strings.h and disable annoying warnings - add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) + set(STLINK_SOURCE "${STLINK_SOURCE};src/win32/win32_socket.c") + set(STLINK_HEADERS "${STLINK_HEADERS};src/win32/win32_socket.h") + + if (MSVC) + include_directories(src/win32/unistd) + set(STLINK_HEADERS "${STLINK_HEADERS};src/win32/unistd/unistd.h") + endif () + + if (NOT STLINK_HAVE_SYS_MMAN_H) + include_directories(src/win32/mmap) + set(STLINK_SOURCE "${STLINK_SOURCE};src/win32/mmap.c") + set(STLINK_HEADERS "${STLINK_HEADERS};src/win32/mmap.h") + endif() endif () ## Include test execution for test-targets for target Debug @@ -225,7 +238,8 @@ set(ST-UTIL_SOURCES src/st-util/gdb-remote.c src/st-util/gdb-server.c src/st-uti if (MSVC) # Add getopt to sources - set(ST-UTIL_SOURCES "${ST-UTIL_SOURCES};src/getopt/getopt.c") + include_directories(src/win32/getopt) + set(ST-UTIL_SOURCES "${ST-UTIL_SOURCES};src/win32/getopt/getopt.c") endif () add_executable(st-flash ${ST-FLASH_SOURCES}) diff --git a/src/common.c b/src/common.c index fb669e255..c9a54cf9f 100644 --- a/src/common.c +++ b/src/common.c @@ -12,10 +12,15 @@ #include #include -#include #include #include +#ifdef STLINK_HAVE_SYS_MMAN_H +#include +#else +#include +#endif + #ifndef O_BINARY #define O_BINARY 0 #endif @@ -193,24 +198,26 @@ #define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) #define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) -#define STM32L4_FLASH_SR_BSY 16 -#define STM32L4_FLASH_SR_ERRMASK 0x3f8 /* SR [9:3] */ - -#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ -#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ -#define STM32L4_FLASH_CR_PG 0 /* Program */ -#define STM32L4_FLASH_CR_PER 1 /* Page erase */ -#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ -#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ -#define STM32L4_FLASH_CR_STRT 16 /* Start command */ -#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ -#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ -#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ -#define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ +#define STM32L4_FLASH_SR_BSY 16 +#define STM32L4_FLASH_SR_ERRMASK 0x3f8 /* SR [9:3] */ + +#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ +#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ +#define STM32L4_FLASH_CR_PG 0 /* Program */ +#define STM32L4_FLASH_CR_PER 1 /* Page erase */ +#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ +#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ +#define STM32L4_FLASH_CR_STRT 16 /* Start command */ +#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ +#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ +#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ +#define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ // Bits requesting flash operations (useful when we want to clear them) -#define STM32L4_FLASH_CR_OPBITS \ - (uint32_t)((1lu<flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; - x |= 1 << FLASH_CR_PG; + x |= (1 << FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; x &= ~STM32L4_FLASH_CR_OPBITS; - x |= 1 << STM32L4_FLASH_CR_PG; + x |= (1 << STM32L4_FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; @@ -662,7 +668,7 @@ static void set_flash_cr_pg(stlink_t *sl) { x |= (1 << FLASH_CR_PG); } else { cr_reg = FLASH_CR; - x = 1 << FLASH_CR_PG; + x = (1 << FLASH_CR_PG); } stlink_write_debug32(sl, cr_reg, x); @@ -704,7 +710,7 @@ static void set_flash_cr_per(stlink_t *sl) { } static void set_flash_cr2_per(stlink_t *sl) { - const uint32_t n = 1 << FLASH_CR_PER; + const uint32_t n = (1 << FLASH_CR_PER); stlink_write_debug32(sl, FLASH_CR2, n); } @@ -728,12 +734,12 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; - cr_mer = 1 << FLASH_CR_MER; - cr_pg = 1 << FLASH_CR_PG; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); - cr_pg = 1 << STM32L4_FLASH_CR_PG; + cr_pg = (1 << STM32L4_FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; @@ -748,8 +754,8 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { cr_pg = (1 << FLASH_CR_PG); } else { cr_reg = FLASH_CR; - cr_mer = 1 << FLASH_CR_MER; - cr_pg = 1 << FLASH_CR_PG; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); } stlink_read_debug32(sl, cr_reg, &val); @@ -767,8 +773,8 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { } static void set_flash_cr2_mer(stlink_t *sl, bool v) { - const uint32_t cr_pg = 1 << FLASH_CR_PER; - const uint32_t cr_mer = 1 << FLASH_CR_MER; + const uint32_t cr_pg = (1 << FLASH_CR_PER); + const uint32_t cr_mer = (1 << FLASH_CR_MER); uint32_t val; stlink_read_debug32(sl, FLASH_CR2, &val); @@ -785,13 +791,13 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; - cr_mer = 1 << FLASH_CR_MER; + cr_mer = (1 << FLASH_CR_MER); } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); } else { cr_reg = FLASH_CR; - cr_mer = 1 << FLASH_CR_MER; + cr_mer = (1 << FLASH_CR_MER); } stlink_read_debug32(sl, cr_reg, &val); @@ -804,20 +810,20 @@ static void set_flash_cr_strt(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; - cr_strt = 1 << FLASH_F4_CR_STRT; + cr_strt = (1 << FLASH_F4_CR_STRT); } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; - cr_strt = 1 << STM32L4_FLASH_CR_STRT; + cr_strt = (1 << STM32L4_FLASH_CR_STRT); } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; - cr_strt = 1 << STM32Gx_FLASH_CR_STRT; + cr_strt = (1 << STM32Gx_FLASH_CR_STRT); } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; - cr_strt = 1 << STM32WB_FLASH_CR_STRT; + cr_strt = (1 << STM32WB_FLASH_CR_STRT); } else { cr_reg = FLASH_CR; - cr_strt = 1 << FLASH_CR_STRT; + cr_strt = (1 << FLASH_CR_STRT); } stlink_read_debug32(sl, cr_reg, &val); @@ -2377,8 +2383,7 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, } -int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len, uint32_t pagesize) -{ +int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len, uint32_t pagesize) { unsigned int count; unsigned int num_half_pages = len / pagesize; uint32_t val; @@ -2742,7 +2747,8 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, uint32_t end = 0; bool eof_found = false; - for (int scan = 0; (res == 0) && (scan < 2); ++scan) { // parse file two times - first to find memory range, second - to fill it + for (int scan = 0; (res == 0) && (scan < 2); ++scan) { + // parse file two times - first to find memory range, second - to fill it if (scan == 1) { if (!eof_found) { ELOG("No EoF recond\n"); @@ -3015,8 +3021,7 @@ static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, stm32_addr_ * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) -{ +static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { uint32_t flash_base = get_stm32l0_flash_base(sl); uint32_t val; uint32_t data; @@ -3162,8 +3167,7 @@ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { * @param option_byte option value * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) -{ +int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) { if (sl->option_base == 0) { ELOG("Option bytes read is currently not supported for connected chip\n"); return -1; @@ -3190,8 +3194,7 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) -{ +int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { WLOG("About to write option byte %#10x to target.\n", option_byte); return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *) &option_byte, 4); } @@ -3203,8 +3206,7 @@ int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) * @param base option bytes to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) -{ +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { int ret = -1; if (sl->option_base == 0) { diff --git a/src/mmap/mmap.h b/src/mmap/mmap.h deleted file mode 100644 index ab94fb7d4..000000000 --- a/src/mmap/mmap.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef STLINK_MMAP_H -#define STLINK_MMAP_H - -#ifdef STLINK_HAVE_SYS_MMAN_H -#include -#else - -#define PROT_READ (1<<0) -#define PROT_WRITE (1<<1) - -#define MAP_SHARED (1<<0) -#define MAP_PRIVATE (1<<1) - -#define MAP_ANONYMOUS (1<<5) - -#define MAP_FAILED ((void *)-1) - -#ifdef __cplusplus -extern "C" { -#endif - - void *mmap(void *addr, size_t len, int prot, int flags, int fd, long long offset); - int munmap(void *addr, size_t len); - -#ifdef __cplusplus -} -#endif - -#endif /* HAVE_SYS_MMAN_H */ - -#endif /* STLINK_MMAP_H */ diff --git a/src/st-util/gdb-remote.c b/src/st-util/gdb-remote.c index 24636e8c9..d5ea0b1c6 100644 --- a/src/st-util/gdb-remote.c +++ b/src/st-util/gdb-remote.c @@ -9,8 +9,8 @@ #include #include -#if defined(__MINGW32__) || defined(_MSC_VER) -#include +#if defined(_WIN32) +#include #else #include #include diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index a7107ff88..b851409e0 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -16,7 +16,7 @@ #endif #if defined(_WIN32) -#include +#include #else #include #include diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index b76639731..ec126cc7e 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -10,9 +10,10 @@ #include #include -#if defined(__MINGW32__) || defined(_MSC_VER) -#include +#if defined(_WIN32) +#include #endif + #include #include "usb.h" diff --git a/src/getopt/LICENSE.txt b/src/win32/getopt/LICENSE.txt similarity index 100% rename from src/getopt/LICENSE.txt rename to src/win32/getopt/LICENSE.txt diff --git a/src/getopt/README.md b/src/win32/getopt/README.md similarity index 100% rename from src/getopt/README.md rename to src/win32/getopt/README.md diff --git a/src/getopt/getopt.c b/src/win32/getopt/getopt.c similarity index 100% rename from src/getopt/getopt.c rename to src/win32/getopt/getopt.c diff --git a/src/getopt/getopt.h b/src/win32/getopt/getopt.h similarity index 100% rename from src/getopt/getopt.h rename to src/win32/getopt/getopt.h diff --git a/src/mmap/mmap.c b/src/win32/mmap.c similarity index 99% rename from src/mmap/mmap.c rename to src/win32/mmap.c index b76e4ad64..60bb440e9 100644 --- a/src/mmap/mmap.c +++ b/src/win32/mmap.c @@ -20,7 +20,6 @@ void *mmap (void *addr, size_t len, int prot, int flags, int fd, long long offs return MAP_FAILED; } - count = read(fd, buf, len); if (count != (ssize_t)len) { diff --git a/src/win32/mmap.h b/src/win32/mmap.h new file mode 100644 index 000000000..1f2e756cb --- /dev/null +++ b/src/win32/mmap.h @@ -0,0 +1,29 @@ +#ifndef STLINK_MMAP_H +#define STLINK_MMAP_H + +#ifdef STLINK_HAVE_SYS_MMAN_H +#include +#else + +#define PROT_READ (1 << 0) +#define PROT_WRITE (1 << 1) + +#define MAP_SHARED (1 << 0) +#define MAP_PRIVATE (1 << 1) +#define MAP_ANONYMOUS (1 << 5) +#define MAP_FAILED ((void *)-1) + +#ifdef __cplusplus +extern "C" { +#endif + +void *mmap(void *addr, size_t len, int prot, int flags, int fd, long long offset); +int munmap(void *addr, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* HAVE_SYS_MMAN_H */ + +#endif /* STLINK_MMAP_H */ diff --git a/src/win32/unistd.h b/src/win32/unistd/unistd.h similarity index 100% rename from src/win32/unistd.h rename to src/win32/unistd/unistd.h diff --git a/src/mingw/mingw.c b/src/win32/win32_socket.c similarity index 59% rename from src/mingw/mingw.c rename to src/win32/win32_socket.c index 646fca238..3a3abae16 100644 --- a/src/mingw/mingw.c +++ b/src/win32/win32_socket.c @@ -1,6 +1,6 @@ -#if defined(__MINGW32__) || defined(_MSC_VER) +#if defined(_WIN32) -#include "mingw.h" +#include "win32_socket.h" #undef socket #undef connect @@ -11,23 +11,23 @@ #include #include -int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) -{ +int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) { struct timeval timeout, *toptr; fd_set ifds, ofds, efds, *ip, *op; unsigned int i; int rc; - /* Set up the file-descriptor sets in ifds, ofds and efds. */ #ifdef _MSC_VER #pragma warning(disable: 4548) #endif + + /* Set up the file-descriptor sets in ifds, ofds and efds. */ FD_ZERO(&ifds); FD_ZERO(&ofds); FD_ZERO(&efds); for (i = 0, op = ip = 0; i < nfds; ++i) { fds[i].revents = 0; - if (fds[i].events & (POLLIN|POLLPRI)) { + if (fds[i].events & (POLLIN | POLLPRI)) { ip = &ifds; FD_SET(fds[i].fd, ip); } @@ -36,7 +36,8 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) FD_SET(fds[i].fd, op); } FD_SET(fds[i].fd, &efds); - } + } + #ifdef _MSC_VER #pragma warning(default: 4548) #endif @@ -54,13 +55,14 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n", (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op); #endif + rc = select(0, ip, op, &efds, toptr); + #ifdef DEBUG_POLL printf("Exiting select rc=%d\n", rc); #endif - if (rc <= 0) - return rc; + if (rc <= 0) return rc; if (rc > 0) { for ( i = 0; i < nfds; ++i) { @@ -72,19 +74,20 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) if (FD_ISSET(fd, &efds)) /* Some error was detected ... should be some way to know. */ fds[i].revents |= POLLHUP; + #ifdef DEBUG_POLL - printf("%d %d %d revent = %x\n", - FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds), - fds[i].revents - ); + printf("%d %d %d revent = %x\n", + FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds), + fds[i].revents + ); #endif + } } return rc; } -static void -set_connect_errno(int winsock_err) -{ + +static void set_connect_errno(int winsock_err) { switch(winsock_err) { case WSAEINVAL: case WSAEALREADY: @@ -97,9 +100,7 @@ set_connect_errno(int winsock_err) } } -static void -set_socket_errno(int winsock_err) -{ +static void set_socket_errno(int winsock_err) { switch(winsock_err) { case WSAEWOULDBLOCK: errno = EAGAIN; @@ -109,44 +110,36 @@ set_socket_errno(int winsock_err) break; } } + /* - * A wrapper around the socket() function. The purpose of this wrapper - * is to ensure that the global errno symbol is set if an error occurs, + * A wrapper around the socket() function. + * The purpose of this wrapper is to ensure that the global errno symbol is set if an error occurs, * even if we are using winsock. */ -SOCKET -win32_socket(int domain, int type, int protocol) -{ +SOCKET win32_socket(int domain, int type, int protocol) { SOCKET fd = socket(domain, type, protocol); - if (fd == INVALID_SOCKET) { - set_socket_errno(WSAGetLastError()); - } + if (fd == INVALID_SOCKET) set_socket_errno(WSAGetLastError()); return fd; } + /* - * A wrapper around the connect() function. The purpose of this wrapper - * is to ensure that the global errno symbol is set if an error occurs, + * A wrapper around the connect() function. + * The purpose of this wrapper is to ensure that the global errno symbol is set if an error occurs, * even if we are using winsock. */ -int -win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len) -{ +int win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len) { int rc = connect(fd, addr, addr_len); assert(rc == 0 || rc == SOCKET_ERROR); - if (rc == SOCKET_ERROR) { - set_connect_errno(WSAGetLastError()); - } + if (rc == SOCKET_ERROR) set_connect_errno(WSAGetLastError()); return rc; } /* - * A wrapper around the accept() function. The purpose of this wrapper - * is to ensure that the global errno symbol is set if an error occurs, + * A wrapper around the accept() function. + * The purpose of this wrapper is to ensure that the global errno symbol is set if an error occurs, * even if we are using winsock. */ -SOCKET -win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len) -{ +SOCKET win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len) { SOCKET newfd = accept(fd, addr, addr_len); if (newfd == INVALID_SOCKET) { set_socket_errno(WSAGetLastError()); @@ -156,62 +149,45 @@ win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len) } /* - * A wrapper around the shutdown() function. The purpose of this wrapper - * is to ensure that the global errno symbol is set if an error occurs, + * A wrapper around the shutdown() function. + * The purpose of this wrapper is to ensure that the global errno symbol is set if an error occurs, * even if we are using winsock. */ -int -win32_shutdown(SOCKET fd, int mode) -{ +int win32_shutdown(SOCKET fd, int mode) { int rc = shutdown(fd, mode); assert(rc == 0 || rc == SOCKET_ERROR); - if (rc == SOCKET_ERROR) { - set_socket_errno(WSAGetLastError()); - } + if (rc == SOCKET_ERROR) set_socket_errno(WSAGetLastError()); return rc; } -int win32_close_socket(SOCKET fd) -{ +int win32_close_socket(SOCKET fd) { int rc = closesocket(fd); - if (rc == SOCKET_ERROR) { - set_socket_errno(WSAGetLastError()); - } + if (rc == SOCKET_ERROR) set_socket_errno(WSAGetLastError()); return rc; } -ssize_t win32_write_socket(SOCKET fd, void *buf, int n) -{ +ssize_t win32_write_socket(SOCKET fd, void *buf, int n) { int rc = send(fd, buf, n, 0); - if (rc == SOCKET_ERROR) { - set_socket_errno(WSAGetLastError()); - } + if (rc == SOCKET_ERROR) set_socket_errno(WSAGetLastError()); return rc; } -ssize_t win32_read_socket(SOCKET fd, void *buf, int n) -{ +ssize_t win32_read_socket(SOCKET fd, void *buf, int n) { int rc = recv(fd, buf, n, 0); - if (rc == SOCKET_ERROR) { - set_socket_errno(WSAGetLastError()); - } + if (rc == SOCKET_ERROR) set_socket_errno(WSAGetLastError()); return rc; } -char * win32_strtok_r(char *s, const char *delim, char **lasts) -{ +char * win32_strtok_r(char *s, const char *delim, char **lasts) { register char *spanp; register int c, sc; char *tok; - if (s == NULL && (s = *lasts) == NULL) - return (NULL); + if (s == NULL && (s = *lasts) == NULL) return (NULL); - /* - * Skip (span) leading delimiters (s += strspn(s, delim), sort of). - */ + // Skip (span) leading delimiters (s += strspn(s, delim), sort of). cont: c = *s++; for (spanp = (char *)delim; (sc = *spanp++) != 0;) { @@ -219,7 +195,7 @@ char * win32_strtok_r(char *s, const char *delim, char **lasts) goto cont; } - if (c == 0) { /* no non-delimiter characters */ + if (c == 0) { // no non-delimiter characters *lasts = NULL; return (NULL); } @@ -234,10 +210,11 @@ char * win32_strtok_r(char *s, const char *delim, char **lasts) spanp = (char *)delim; do { if ((sc = *spanp++) == c) { - if (c == 0) + if (c == 0) { s = NULL; - else + } else { s[-1] = 0; + } *lasts = s; return (tok); } @@ -246,24 +223,23 @@ char * win32_strtok_r(char *s, const char *delim, char **lasts) /* NOTREACHED */ } -char *win32_strsep (char **stringp, const char *delim) -{ +char *win32_strsep (char **stringp, const char *delim) { register char *s; register const char *spanp; register int c, sc; char *tok; - if ((s = *stringp) == NULL) - return (NULL); + if ((s = *stringp) == NULL) return (NULL); for (tok = s;;) { c = *s++; spanp = delim; do { if ((sc = *spanp++) == c) { - if (c == 0) + if (c == 0) { s = NULL; - else + } else { s[-1] = 0; + } *stringp = s; return (tok); } @@ -273,24 +249,23 @@ char *win32_strsep (char **stringp, const char *delim) } #ifndef STLINK_HAVE_UNISTD_H -int usleep(unsigned int waitTime) -{ - if (waitTime >= 1000) - { - // Don't do long busy-waits. - // However much it seems like the QPC code would be more accurate, - // you can and probably will lose your time slice at any point during the wait, - // so we might as well voluntarily give up the CPU with a WaitForSingleObject. - HANDLE timer; - LARGE_INTEGER dueTime; - dueTime.QuadPart = -10 * (LONGLONG)waitTime; - - timer = CreateWaitableTimer(NULL, TRUE, NULL); - SetWaitableTimer(timer, &dueTime, 0, NULL, NULL, 0); - WaitForSingleObject(timer, INFINITE); - CloseHandle(timer); +int usleep(unsigned int waitTime) { + if (waitTime >= 1000) { + /* Don't do long busy-waits. + * However much it seems like the QPC code would be more accurate, + * you can and probably will lose your time slice at any point during the wait, + * so we might as well voluntarily give up the CPU with a WaitForSingleObject. + */ + HANDLE timer; + LARGE_INTEGER dueTime; + dueTime.QuadPart = -10 * (LONGLONG)waitTime; + timer = CreateWaitableTimer(NULL, TRUE, NULL); + SetWaitableTimer(timer, &dueTime, 0, NULL, NULL, 0); + WaitForSingleObject(timer, INFINITE); + CloseHandle(timer); + return 0; - } + } LARGE_INTEGER perf_cnt, start, now; QueryPerformanceFrequency(&perf_cnt); @@ -304,6 +279,4 @@ int usleep(unsigned int waitTime) } #endif -#endif - - +#endif // defined(_WIN32) diff --git a/src/mingw/mingw.h b/src/win32/win32_socket.h similarity index 81% rename from src/mingw/mingw.h rename to src/win32/win32_socket.h index 8f5b992fe..0d26a80e3 100644 --- a/src/mingw/mingw.h +++ b/src/win32/win32_socket.h @@ -9,19 +9,20 @@ #include #include + #if defined(_MSC_VER) #pragma comment(lib, "ws2_32.lib") #endif + #include #if defined(_MSC_VER) #pragma warning(pop) #endif -/* winsock doesn't feature poll(), so there is a version implemented - * in terms of select() in mingw.c. The following definitions - * are copied from linux man pages. A poll() macro is defined to - * call the version in mingw.c. +/* winsock doesn't feature poll(), so there is a version implemented in terms of select() in mingw.c. + * The following definitions are copied from linux man pages. + * A poll() macro is defined to call the version in mingw.c. */ #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0600) @@ -39,11 +40,10 @@ struct pollfd { #endif #define poll(x, y, z) win32_poll(x, y, z) -/* These wrappers do nothing special except set the global errno variable if - * an error occurs (winsock doesn't do this by default). They set errno - * to unix-like values (i.e. WSAEWOULDBLOCK is mapped to EAGAIN), so code - * outside of this file "shouldn't" have to worry about winsock specific error - * handling. +/* These wrappers do nothing special except set the global errno variable if an error occurs + * (winsock doesn't do this by default). + * They set errno to unix-like values (i.e. WSAEWOULDBLOCK is mapped to EAGAIN), + * so code outside of this file "shouldn't" have to worry about winsock specific error handling. */ #define socket(x, y, z) win32_socket(x, y, z) #define connect(x, y, z) win32_connect(x, y, z) @@ -71,4 +71,4 @@ char *win32_strsep(char **stringp, const char *delim); ssize_t win32_read_socket(SOCKET fd, void *buf, int n); ssize_t win32_write_socket(SOCKET fd, void *buf, int n); -#endif //defined(__MINGW32__) || defined(_MSC_VER) +#endif // defined(__MINGW32__) || defined(_MSC_VER) From 97974649c38533a2a7a2e72bb356fe20e8b232ce Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 6 Jun 2020 00:13:15 +0200 Subject: [PATCH 0959/1435] Whitespace & code style cleanup --- CMakeLists.txt | 7 +- src/st-util/gdb-remote.c | 35 +-- src/st-util/gdb-server.c | 518 +++++++++++++++----------------------- src/stlink-lib/usb.c | 2 + src/win32/unistd/unistd.h | 12 +- src/win32/win32_socket.c | 4 +- src/win32/win32_socket.h | 4 +- 7 files changed, 227 insertions(+), 355 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c1ced137d..8428e7565 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + ### # General project settings ### @@ -93,11 +94,6 @@ include_directories(src) include_directories(src/st-flash) include_directories(src/stlink-lib) -if (MSVC) - include_directories(src/win32) - include_directories(src/win32/unistd) -endif () - set(STLINK_HEADERS inc/stlink.h src/backend.h @@ -127,6 +123,7 @@ if (WIN32) set(STLINK_HEADERS "${STLINK_HEADERS};src/win32/win32_socket.h") if (MSVC) + # Add drop-in replacement for unistd.h to sources include_directories(src/win32/unistd) set(STLINK_HEADERS "${STLINK_HEADERS};src/win32/unistd/unistd.h") endif () diff --git a/src/st-util/gdb-remote.c b/src/st-util/gdb-remote.c index d5ea0b1c6..04729cc75 100644 --- a/src/st-util/gdb-remote.c +++ b/src/st-util/gdb-remote.c @@ -1,7 +1,6 @@ /* * Copyright (C) 2011 Peter Zotov - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. + * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ #include @@ -23,7 +22,7 @@ static const char hex[] = "0123456789abcdef"; int gdb_send_packet(int fd, char* data) { unsigned int data_length = (unsigned int) strlen(data); int length = data_length + 4; - char* packet = malloc(length); /* '$' data (hex) '#' cksum (hex) */ + char* packet = malloc(length); // '$' data (hex) '#' cksum (hex) memset(packet, 0, length); @@ -67,8 +66,7 @@ int gdb_recv_packet(int fd, char** buffer) { char* packet_buffer = malloc(packet_size); unsigned state; - if (packet_buffer == NULL) - return -2; + if (packet_buffer == NULL) return -2; start: state = 0; @@ -90,11 +88,7 @@ int gdb_recv_packet(int fd, char** buffer) { switch(state) { case 0: - if (c != '$') { - // ignore - } else { - state = 1; - } + if (c != '$') { /* ignore */ } else { state = 1; } break; case 1: @@ -107,9 +101,9 @@ int gdb_recv_packet(int fd, char** buffer) { if (packet_idx == packet_size) { packet_size += ALLOC_STEP; void* p = realloc(packet_buffer, packet_size); - if (p != NULL) + if (p != NULL) { packet_buffer = p; - else { + } else { free(packet_buffer); return -2; } @@ -136,7 +130,6 @@ int gdb_recv_packet(int fd, char** buffer) { free(packet_buffer); return -2; } - goto start; } else { char ack = '+'; @@ -152,9 +145,11 @@ int gdb_recv_packet(int fd, char** buffer) { return packet_idx; } -// Here we skip any characters which are not \x03, GDB interrupt. -// As we use the mode with ACK, in a (very unlikely) situation of a packet -// lost because of this skipping, it will be resent anyway. +/* + * Here we skip any characters which are not \x03, GDB interrupt. + * As we use the mode with ACK, in a (very unlikely) situation of a packet lost + * because of this skipping, it will be resent anyway. + */ int gdb_check_for_interrupt(int fd) { struct pollfd pfd; pfd.fd = fd; @@ -162,12 +157,8 @@ int gdb_check_for_interrupt(int fd) { if (poll(&pfd, 1, 0) != 0) { char c; - - if (read(fd, &c, 1) != 1) - return -2; - - if (c == '\x03') // ^C - return 1; + if (read(fd, &c, 1) != 1) return -2; + if (c == '\x03') return 1; // ^C } return 0; diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index b851409e0..119d0ff9a 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -1,8 +1,8 @@ /* * Copyright (C) 2011 Peter Zotov - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. + * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ + #include #include #include @@ -10,6 +10,7 @@ #include #include #include + #if defined(_MSC_VER) #include #define __attribute__(x) @@ -32,11 +33,11 @@ #define FLASH_BASE 0x08000000 -/* Semihosting doesn't have a short option, we define a value to identify it */ +// Semihosting doesn't have a short option, we define a value to identify it #define SEMIHOSTING_OPTION 128 #define SERIAL_OPTION 127 -//Allways update the FLASH_PAGE before each use, by calling stlink_calculate_pagesize +// always update the FLASH_PAGE before each use, by calling stlink_calculate_pagesize #define FLASH_PAGE (sl->flash_pgsz) static stlink_t *connected_stlink = NULL; @@ -71,7 +72,7 @@ char* make_memory_map(stlink_t *sl); static void init_cache (stlink_t *sl); static void cleanup(int signum) { - (void)signum; + (void)signum; if (connected_stlink) { /* Switch back to mass storage mode before closing. */ @@ -86,10 +87,10 @@ static void cleanup(int signum) { static stlink_t* do_connect(st_state_t *st) { stlink_t *sl = NULL; - if (serial_specified) { - sl = stlink_open_usb(st->logging_level, st->reset, serialnumber, 0); - } else { - sl = stlink_open_usb(st->logging_level, st->reset, NULL, 0); + if (serial_specified) { + sl = stlink_open_usb(st->logging_level, st->reset, serialnumber, 0); + } else { + sl = stlink_open_usb(st->logging_level, st->reset, NULL, 0); } return sl; } @@ -201,18 +202,16 @@ int main(int argc, char** argv) { st_state_t state; memset(&state, 0, sizeof(state)); - // set defaults... + // set defaults ... state.logging_level = DEFAULT_LOGGING_LEVEL; state.listen_port = DEFAULT_GDB_LISTEN_PORT; - state.reset = 1; /* By default, reset board */ + state.reset = 1; // by default, reset board parse_options(argc, argv, &state); printf("st-util\n"); sl = do_connect(&state); - if (sl == NULL) { - return 1; - } + if (sl == NULL) return 1; if (sl->chip_id == STLINK_CHIPID_UNKNOWN) { ELOG("Unsupported Target (Chip ID is %#010x, Core ID is %#010x).\n", sl->chip_id, sl->core_id); @@ -224,42 +223,32 @@ int main(int argc, char** argv) { signal(SIGTERM, &cleanup); signal(SIGSEGV, &cleanup); - if (state.reset) { - stlink_reset(sl); - } + if (state.reset) stlink_reset(sl); DLOG("Chip ID is %#010x, Core ID is %#08x.\n", sl->chip_id, sl->core_id); sl->verbose=0; current_memory_map = make_memory_map(sl); -#if defined(__MINGW32__) || defined(_MSC_VER) - WSADATA wsadata; - if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0){ - goto winsock_error; - } +#if defined(_WIN32) + WSADATA wsadata; + if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0) goto winsock_error; #endif init_cache(sl); do { - if (serve(sl, &state)) { - usleep (1 * 1000); // don't go bezurk if serve returns with error - } - - /* in case serve() changed the connection */ - sl = connected_stlink; - - /* Continue */ - stlink_run(sl); + if (serve(sl, &state)) { usleep (1 * 1000); } // don't go beserk if serve returns with error + sl = connected_stlink; // in case serve() changed the connection + stlink_run(sl); // continue } while (state.persistent); -#if defined(__MINGW32__) || defined(_MSC_VER) +#if defined(_WIN32) winsock_error: WSACleanup(); #endif - /* Switch back to mass storage mode before closing. */ + // switch back to mass storage mode before closing stlink_exit_debug_mode(sl); stlink_close(sl); @@ -507,7 +496,7 @@ static const char* const memory_map_template_F4_DE = ""; char* make_memory_map(stlink_t *sl) { - /* This will be freed in serve() */ + // this will be freed in serve() const size_t sz = 4096; char* map = malloc(sz); map[0] = '\0'; @@ -545,7 +534,6 @@ char* make_memory_map(stlink_t *sl) { return map; } - /* * DWT_COMP0 0xE0001020 * DWT_MASK0 0xE0001024 @@ -589,8 +577,8 @@ static void init_data_watchpoints(stlink_t *sl) { } } -static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, - stm32_addr_t addr, unsigned int len) { +static int add_data_watchpoint( + stlink_t *sl, enum watchfun wf, stm32_addr_t addr, unsigned int len) { int i = 0; uint32_t mask, dummy; @@ -635,8 +623,7 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, return -1; } -static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) -{ +static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { int i; for (i = 0 ; i < DATA_WATCH_NUM; i++) { @@ -657,9 +644,9 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) static int code_break_num; static int code_lit_num; -#define CODE_BREAK_NUM_MAX 15 -#define CODE_BREAK_LOW 0x01 -#define CODE_BREAK_HIGH 0x02 +#define CODE_BREAK_NUM_MAX 15 +#define CODE_BREAK_LOW 0x01 +#define CODE_BREAK_HIGH 0x02 struct code_hw_breakpoint { stm32_addr_t addr; @@ -687,9 +674,7 @@ static void init_code_breakpoints(stlink_t *sl) { static int has_breakpoint(stm32_addr_t addr) { for (int i = 0; i < code_break_num; i++) { - if (code_breaks[i].addr == addr) { - return 1; - } + if (code_breaks[i].addr == addr) return 1; } return 0; } @@ -704,52 +689,43 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { return -1; } - if (sl->core_id==STM32F7_CORE_ID) { - fpb_addr = addr; - } else { - fpb_addr = addr & ~0x3; - } + if (sl->core_id==STM32F7_CORE_ID) { + fpb_addr = addr; + } else { + fpb_addr = addr & ~0x3; + } int id = -1; for (int i = 0; i < code_break_num; i++) { - if (fpb_addr == code_breaks[i].addr || - (set && code_breaks[i].type == 0)) { + if (fpb_addr == code_breaks[i].addr || (set && code_breaks[i].type == 0)) { id = i; break; } } if (id == -1) { - if (set) return -1; // Free slot not found - else return 0; // Breakpoint is already removed + if (set) { return -1; } // free slot not found + else { return 0; } // breakpoint is already removed } struct code_hw_breakpoint* bp = &code_breaks[id]; bp->addr = fpb_addr; - if (sl->core_id==STM32F7_CORE_ID) { - if (set) bp->type = type; - else bp->type = 0; - - mask = (bp->addr) | 1; - } else { - if (set) bp->type |= type; - else bp->type &= ~type; - - mask = (bp->addr) | 1 | (bp->type << 30); - } + if (sl->core_id==STM32F7_CORE_ID) { + if (set) { bp->type = type; } else { bp->type = 0; } + mask = (bp->addr) | 1; + } else { + if (set) { bp->type |= type; } else { bp->type &= ~type; } + mask = (bp->addr) | 1 | (bp->type << 30); + } if (bp->type == 0) { DLOG("clearing hw break %d\n", id); - stlink_write_debug32(sl, 0xe0002008 + id * 4, 0); } else { - DLOG("setting hw break %d at %08x (%d)\n", - id, bp->addr, bp->type); - DLOG("reg %08x \n", - mask); - + DLOG("setting hw break %d at %08x (%d)\n", id, bp->addr, bp->type); + DLOG("reg %08x \n", mask); stlink_write_debug32(sl, 0xe0002008 + id * 4, mask); } @@ -782,7 +758,6 @@ static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { struct flash_block* new = malloc(sizeof(struct flash_block)); new->next = flash_root; - new->addr = addr; new->length = length; new->data = calloc(length, 1); @@ -824,8 +799,7 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { } if (fit_length != length) { - WLOG("data block %08x -> %04x truncated to %04x\n", - addr, length, fit_length); + WLOG("data block %08x -> %04x truncated to %04x\n", addr, length, fit_length); WLOG("(this is not an error, just a GDB glitch)\n"); } @@ -835,7 +809,7 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { static int flash_go(stlink_t *sl) { int error = -1; - // Some kinds of clock settings do not allow writing to flash. + // some kinds of clock settings do not allow writing to flash. stlink_reset(sl); stlink_force_debug(sl); @@ -845,14 +819,13 @@ static int flash_go(stlink_t *sl) { for (stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += (uint32_t)FLASH_PAGE) { unsigned length = fb->length - (page - fb->addr); - //Update FLASH_PAGE + // update FLASH_PAGE stlink_calculate_pagesize(sl, page); DLOG("flash_do: page %08x\n", page); unsigned len = (length > FLASH_PAGE) ? (unsigned int) FLASH_PAGE : length; int ret = stlink_write_flash(sl, page, fb->data + (page - fb->addr), len, 0); - if (ret < 0) - goto error; + if (ret < 0) goto error; } } @@ -882,98 +855,86 @@ static int flash_go(stlink_t *sl) { #define DCCSW 0xE000EF6C #define ICIALLU 0xE000EF50 -struct cache_level_desc -{ - unsigned int nsets; - unsigned int nways; - unsigned int log2_nways; - unsigned int width; +struct cache_level_desc { + unsigned int nsets; + unsigned int nways; + unsigned int log2_nways; + unsigned int width; }; -struct cache_desc_t -{ - /* Minimal line size in bytes. */ - unsigned int dminline; - unsigned int iminline; +struct cache_desc_t { + // Minimal line size in bytes + unsigned int dminline; + unsigned int iminline; - /* Last level of unification (uniprocessor). */ - unsigned int louu; + // Last level of unification (uniprocessor) + unsigned int louu; - struct cache_level_desc icache[7]; - struct cache_level_desc dcache[7]; + struct cache_level_desc icache[7]; + struct cache_level_desc dcache[7]; }; static struct cache_desc_t cache_desc; -/* Return the smallest R so that V <= (1 << R). Not performance critical. */ -static unsigned ceil_log2(unsigned v) -{ - unsigned res; - for (res = 0; (1U << res) < v; res++) - ; - return res; +// return the smallest R so that V <= (1 << R); not performance critical +static unsigned ceil_log2(unsigned v) { + unsigned res; + for (res = 0; (1U << res) < v; res++) ; + return res; } -static void read_cache_level_desc(stlink_t *sl, struct cache_level_desc *desc) -{ - unsigned int ccsidr; - unsigned int log2_nsets; - - stlink_read_debug32(sl, CCSIDR, &ccsidr); - desc->nsets = ((ccsidr >> 13) & 0x3fff) + 1; - desc->nways = ((ccsidr >> 3) & 0x1ff) + 1; - desc->log2_nways = ceil_log2 (desc->nways); - log2_nsets = ceil_log2 (desc->nsets); - desc->width = 4 + (ccsidr & 7) + log2_nsets; - ILOG("%08x LineSize: %u, ways: %u, sets: %u (width: %u)\n", - ccsidr, 4 << (ccsidr & 7), desc->nways, desc->nsets, desc->width); +static void read_cache_level_desc(stlink_t *sl, struct cache_level_desc *desc) { + unsigned int ccsidr; + unsigned int log2_nsets; + + stlink_read_debug32(sl, CCSIDR, &ccsidr); + desc->nsets = ((ccsidr >> 13) & 0x3fff) + 1; + desc->nways = ((ccsidr >> 3) & 0x1ff) + 1; + desc->log2_nways = ceil_log2 (desc->nways); + log2_nsets = ceil_log2 (desc->nsets); + desc->width = 4 + (ccsidr & 7) + log2_nsets; + ILOG("%08x LineSize: %u, ways: %u, sets: %u (width: %u)\n", + ccsidr, 4 << (ccsidr & 7), desc->nways, desc->nsets, desc->width); } static void init_cache (stlink_t *sl) { - unsigned int clidr; - unsigned int ccr; - unsigned int ctr; - int i; - - /* Assume only F7 has a cache. */ - if (sl->core_id!=STM32F7_CORE_ID) - return; - - stlink_read_debug32(sl, CLIDR, &clidr); - stlink_read_debug32(sl, CCR, &ccr); - stlink_read_debug32(sl, CTR, &ctr); - cache_desc.dminline = 4 << ((ctr >> 16) & 0x0f); - cache_desc.iminline = 4 << (ctr & 0x0f); - cache_desc.louu = (clidr >> 27) & 7; - - ILOG("Chip clidr: %08x, I-Cache: %s, D-Cache: %s\n", - clidr, ccr & CCR_IC ? "on" : "off", ccr & CCR_DC ? "on" : "off"); - ILOG(" cache: LoUU: %u, LoC: %u, LoUIS: %u\n", - (clidr >> 27) & 7, (clidr >> 24) & 7, (clidr >> 21) & 7); - ILOG(" cache: ctr: %08x, DminLine: %u bytes, IminLine: %u bytes\n", ctr, - cache_desc.dminline, cache_desc.iminline); - for (i = 0; i < 7; i++) - { - unsigned int ct = (clidr >> (3 * i)) & 0x07; - - cache_desc.dcache[i].width = 0; - cache_desc.icache[i].width = 0; - - if (ct == 2 || ct == 3 || ct == 4) - { - /* Data. */ - stlink_write_debug32(sl, CSSELR, i << 1); - ILOG("D-Cache L%d: ", i); - read_cache_level_desc(sl, &cache_desc.dcache[i]); - } - - if (ct == 1 || ct == 3) - { - /* Instruction. */ - stlink_write_debug32(sl, CSSELR, (i << 1) | 1); - ILOG("I-Cache L%d: ", i); - read_cache_level_desc(sl, &cache_desc.icache[i]); - } + unsigned int clidr; + unsigned int ccr; + unsigned int ctr; + int i; + + // Assume only F7 has a cache + if (sl->core_id!=STM32F7_CORE_ID) return; + + stlink_read_debug32(sl, CLIDR, &clidr); + stlink_read_debug32(sl, CCR, &ccr); + stlink_read_debug32(sl, CTR, &ctr); + cache_desc.dminline = 4 << ((ctr >> 16) & 0x0f); + cache_desc.iminline = 4 << (ctr & 0x0f); + cache_desc.louu = (clidr >> 27) & 7; + + ILOG("Chip clidr: %08x, I-Cache: %s, D-Cache: %s\n", + clidr, ccr & CCR_IC ? "on" : "off", ccr & CCR_DC ? "on" : "off"); + ILOG(" cache: LoUU: %u, LoC: %u, LoUIS: %u\n", + (clidr >> 27) & 7, (clidr >> 24) & 7, (clidr >> 21) & 7); + ILOG(" cache: ctr: %08x, DminLine: %u bytes, IminLine: %u bytes\n", ctr, + cache_desc.dminline, cache_desc.iminline); + for (i = 0; i < 7; i++) { + unsigned int ct = (clidr >> (3 * i)) & 0x07; + cache_desc.dcache[i].width = 0; + cache_desc.icache[i].width = 0; + + if (ct == 2 || ct == 3 || ct == 4) { // Data + stlink_write_debug32(sl, CSSELR, i << 1); + ILOG("D-Cache L%d: ", i); + read_cache_level_desc(sl, &cache_desc.dcache[i]); + } + + if (ct == 1 || ct == 3) { // Instruction + stlink_write_debug32(sl, CSSELR, (i << 1) | 1); + ILOG("I-Cache L%d: ", i); + read_cache_level_desc(sl, &cache_desc.icache[i]); + } } } @@ -987,54 +948,43 @@ static void cache_flush(stlink_t *sl, unsigned ccr) { unsigned max_addr = 1 << desc->width; unsigned way_sh = 32 - desc->log2_nways; - /* D-cache clean by set-ways. */ + // D-cache clean by set-ways. for (addr = (level << 1); addr < max_addr; addr += cache_desc.dminline) { unsigned int way; - for (way = 0; way < desc->nways; way++) - stlink_write_debug32(sl, DCCSW, addr | (way << way_sh)); - } + stlink_write_debug32(sl, DCCSW, addr | (way << way_sh)); + } } - /* Invalidate all I-cache to oPU. */ - if (ccr & CCR_IC) - stlink_write_debug32(sl, ICIALLU, 0); + // invalidate all I-cache to oPU + if (ccr & CCR_IC) stlink_write_debug32(sl, ICIALLU, 0); } static int cache_modified; -static void cache_change(stm32_addr_t start, unsigned count) -{ - if (count == 0) - return; - (void)start; - cache_modified = 1; +static void cache_change(stm32_addr_t start, unsigned count) { + if (count == 0) return; + (void)start; + cache_modified = 1; } -static void cache_sync(stlink_t *sl) -{ - unsigned ccr; +static void cache_sync(stlink_t *sl) { + unsigned ccr; - if (sl->core_id!=STM32F7_CORE_ID) - return; - if (!cache_modified) - return; - cache_modified = 0; + if (sl->core_id!=STM32F7_CORE_ID) return; + if (!cache_modified) return; + cache_modified = 0; - stlink_read_debug32(sl, CCR, &ccr); - if (ccr & (CCR_IC | CCR_DC)) - cache_flush(sl, ccr); + stlink_read_debug32(sl, CCR, &ccr); + if (ccr & (CCR_IC | CCR_DC)) cache_flush(sl, ccr); } -static size_t unhexify(const char *in, char *out, size_t out_count) -{ +static size_t unhexify(const char *in, char *out, size_t out_count) { size_t i; unsigned int c; for (i = 0; i < out_count; i++) { - if (sscanf(in + (2 * i), "%02x", &c) != 1) { - return i; - } + if (sscanf(in + (2 * i), "%02x", &c) != 1) return i; out[i] = (char)c; } @@ -1082,24 +1032,21 @@ int serve(stlink_t *sl, st_state_t *st) { close_socket(sock); stlink_force_debug(sl); - if (st->reset) { - stlink_reset(sl); - } + if (st->reset) stlink_reset(sl); init_code_breakpoints(sl); init_data_watchpoints(sl); ILOG("GDB connected.\n"); /* - * To allow resetting the chip from GDB it is required to - * emulate attaching and detaching to target. + * To allow resetting the chip from GDB it is required to emulate attaching + * and detaching to target. */ unsigned int attached = 1; - /* - * If a critical error is detected, break from the loop - */ + // if a critical error is detected, break from the loop int critical_error = 0; int ret; + while (1) { ret = 0; char* packet; @@ -1137,12 +1084,11 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("query: %s;%s\n", queryName, params); if (!strcmp(queryName, "Supported")) { - if (sl->chip_id==STLINK_CHIPID_STM32_F4 - || sl->chip_id==STLINK_CHIPID_STM32_F4_HD - || sl->core_id==STM32F7_CORE_ID) { - reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); - } - else { + if (sl->chip_id==STLINK_CHIPID_STM32_F4 || + sl->chip_id==STLINK_CHIPID_STM32_F4_HD || + sl->core_id==STM32F7_CORE_ID) { + reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); + } else { reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); } } else if (!strcmp(queryName, "Xfer")) { @@ -1174,7 +1120,6 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned data_length = (unsigned int) strlen(data); if (addr + length > data_length) length = data_length - addr; - if (length == 0) { reply = strdup("l"); } else { @@ -1208,52 +1153,48 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("unhexified Rcmd: '%s'\n", cmd); - if (!strncmp(cmd, "resume", 6)) {// resume + if (!strncmp(cmd, "resume", 6)) { // resume DLOG("Rcmd: resume\n"); cache_sync(sl); ret = stlink_run(sl); if (ret) { DLOG("Rcmd: resume failed\n"); reply = strdup("E00"); - } else { reply = strdup("OK"); } - } else if (!strncmp(cmd, "halt", 4)) { //halt + } else if (!strncmp(cmd, "halt", 4)) { // halt ret = stlink_force_debug(sl); if (ret) { DLOG("Rcmd: halt failed\n"); reply = strdup("E00"); - } else { reply = strdup("OK"); DLOG("Rcmd: halt\n"); } - } else if (!strncmp(cmd, "jtag_reset", 10)) { //jtag_reset + } else if (!strncmp(cmd, "jtag_reset", 10)) { // jtag_reset reply = strdup("OK"); ret = stlink_jtag_reset(sl, 0); if (ret) { DLOG("Rcmd: jtag_reset failed with jtag_reset\n"); reply = strdup("E00"); - } ret = stlink_jtag_reset(sl, 1); if (ret) { DLOG("Rcmd: jtag_reset failed with jtag_reset\n"); reply = strdup("E00"); - } ret = stlink_force_debug(sl); if (ret) { DLOG("Rcmd: jtag_reset failed with force_debug\n"); reply = strdup("E00"); - } + if (strcmp(reply, "E00")) { // no errors have been found DLOG("Rcmd: jtag_reset\n"); @@ -1284,19 +1225,13 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("Rcmd: got semihosting cmd '%s'", cmd); char *arg = cmd + 12; - /* Skip whitespaces */ - while (isspace(*arg)) { - arg++; - } + // Skip whitespaces + while (isspace(*arg)) { arg++; } - if (!strncmp(arg, "enable", 6) - || !strncmp(arg, "1", 1)) - { + if (!strncmp(arg, "enable", 6) || !strncmp(arg, "1", 1)) { semihosting = true; reply = strdup("OK"); - } else if (!strncmp(arg, "disable", 7) - || !strncmp(arg, "0", 1)) - { + } else if (!strncmp(arg, "disable", 7) || !strncmp(arg, "0", 1)) { semihosting = false; reply = strdup("OK"); } else { @@ -1350,8 +1285,7 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned addr = (unsigned int) strtoul(__s_addr, NULL, 16); unsigned data_length = status - (unsigned int) (data - packet); - // Length of decoded data cannot be more than - // encoded, as escapes are removed. + // Length of decoded data cannot be more than encoded, as escapes are removed. // Additional byte is reserved for alignment fix. uint8_t *decoded = calloc(data_length + 1, 1); unsigned dec_index = 0; @@ -1364,9 +1298,8 @@ int serve(stlink_t *sl, st_state_t *st) { } } - // Fix alignment - if (dec_index % 2 != 0) - dec_index++; + // fix alignment + if (dec_index % 2 != 0) dec_index++; DLOG("binary packet %d -> %d\n", data_length, dec_index); @@ -1385,7 +1318,6 @@ int serve(stlink_t *sl, st_state_t *st) { } } else if (!strcmp(cmdName, "Kill")) { attached = 0; - reply = strdup("OK"); } @@ -1398,9 +1330,7 @@ int serve(stlink_t *sl, st_state_t *st) { case 'c': cache_sync(sl); ret = stlink_run(sl); - if (ret) { - DLOG("Semihost: run failed\n"); - } + if (ret) DLOG("Semihost: run failed\n"); while (1) { status = gdb_check_for_interrupt(client); @@ -1416,9 +1346,7 @@ int serve(stlink_t *sl, st_state_t *st) { } ret = stlink_status(sl); - if (ret) { - DLOG("Semihost: status failed\n"); - } + if (ret) DLOG("Semihost: status failed\n"); if(sl->core_stat == TARGET_HALTED) { struct stlink_reg reg; stm32_addr_t pc; @@ -1426,30 +1354,23 @@ int serve(stlink_t *sl, st_state_t *st) { int offset = 0; uint16_t insn; - if (!semihosting) { - break; - } + if (!semihosting) break; ret = stlink_read_all_regs (sl, ®); - if (ret) { - DLOG("Semihost: read_all_regs failed\n"); - } + if (ret) DLOG("Semihost: read_all_regs failed\n"); - /* Read PC */ + // Read PC pc = reg.r[15]; - /* Compute aligned value */ + // Compute aligned value offset = pc % 4; addr = pc - offset; - /* Read instructions (address and length must be - * aligned). - */ + // Read instructions (address and length must be aligned). ret = stlink_read_mem32(sl, addr, (offset > 2 ? 8 : 4)); if (ret != 0) { - DLOG("Semihost: cannot read instructions at: " - "0x%08x\n", addr); + DLOG("Semihost: cannot read instructions at: 0x%08x\n", addr); break; } @@ -1458,28 +1379,20 @@ int serve(stlink_t *sl, st_state_t *st) { if (insn == 0xBEAB && !has_breakpoint(addr)) { ret = do_semihosting (sl, reg.r[0], reg.r[1], ®.r[0]); - if (ret) { - DLOG("Semihost: do_semihosting failed\n"); - } + if (ret) DLOG("Semihost: do_semihosting failed\n"); - /* Write return value */ + // Write return value ret = stlink_write_reg(sl, reg.r[0], 0); - if (ret) { - DLOG("Semihost: write_reg failed for return value\n"); - } + if (ret) DLOG("Semihost: write_reg failed for return value\n"); - /* Jump over the break instruction */ + // Jump over the break instruction ret = stlink_write_reg(sl, reg.r[15] + 2, 15); - if (ret) { - DLOG("Semihost: write_reg failed for jumping over break\n"); - } + if (ret) DLOG("Semihost: write_reg failed for jumping over break\n"); - /* continue execution */ + // Continue execution cache_sync(sl); ret = stlink_run(sl); - if (ret) { - DLOG("Semihost: continue execution failed with stlink_run\n"); - } + if (ret) DLOG("Semihost: continue execution failed with stlink_run\n"); } else { break; } @@ -1492,10 +1405,10 @@ int serve(stlink_t *sl, st_state_t *st) { break; case 's': - cache_sync(sl); + cache_sync(sl); ret = stlink_step(sl); if (ret) { - // have problem sending step packet + // ... having a problem sending step packet ELOG("Step: cannot send step request\n"); reply = strdup("E00"); critical_error = 1; // absolutely critical @@ -1509,21 +1422,18 @@ int serve(stlink_t *sl, st_state_t *st) { if (attached) { reply = strdup("S05"); // TRAP } else { - /* Stub shall reply OK if not attached. */ + // Stub shall reply OK if not attached. reply = strdup("OK"); } break; case 'g': ret = stlink_read_all_regs(sl, ®p); - if (ret) { - DLOG("g packet: read_all_regs failed\n"); - } + if (ret) DLOG("g packet: read_all_regs failed\n"); reply = calloc(8 * 16 + 1, 1); for (int i = 0; i < 16; i++) sprintf(&reply[i * 8], "%08x", (uint32_t)htonl(regp.r[i])); - break; case 'p': { @@ -1564,12 +1474,10 @@ int serve(stlink_t *sl, st_state_t *st) { ret = 1; reply = strdup("E00"); } - if (ret) { - DLOG("p packet: stlink_read_unsupported_reg failed with id %u\n", id); - } + if (ret) DLOG("p packet: stlink_read_unsupported_reg failed with id %u\n", id); if (reply == NULL) { - // if reply is set to "E00", skip + // If reply is set to "E00", skip reply = calloc(8 + 1, 1); sprintf(reply, "%08x", myreg); } @@ -1609,13 +1517,8 @@ int serve(stlink_t *sl, st_state_t *st) { ret = 1; reply = strdup("E00"); } - if (ret) { - DLOG("P packet: stlink_write_unsupported_reg failed with reg %u\n", reg); - } - if (reply == NULL) { - // note that NULL may not be zero - reply = strdup("OK"); - } + if (ret) DLOG("P packet: stlink_write_unsupported_reg failed with reg %u\n", reg); + if (reply == NULL) reply = strdup("OK"); // note that NULL may not be zero break; } @@ -1626,9 +1529,7 @@ int serve(stlink_t *sl, st_state_t *st) { strncpy(str, &packet[1 + i * 8], 8); uint32_t reg = (uint32_t) strtoul(str, NULL, 16); ret = stlink_write_reg(sl, ntohl(reg), i); - if (ret) { - DLOG("G packet: stlink_write_reg failed"); - } + if (ret) DLOG("G packet: stlink_write_reg failed"); } reply = strdup("OK"); @@ -1643,17 +1544,12 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned adj_start = start % 4; unsigned count_rnd = (count + adj_start + 4 - 1) / 4 * 4; - if (count_rnd > sl->flash_pgsz) - count_rnd = (unsigned int) sl->flash_pgsz; - if (count_rnd > 0x1800) - count_rnd = 0x1800; - if (count_rnd < count) - count = count_rnd; - - if (stlink_read_mem32(sl, start - adj_start, count_rnd) != 0) { - /* read failed somehow, don't return stale buffer */ - count = 0; - } + if (count_rnd > sl->flash_pgsz) count_rnd = (unsigned int) sl->flash_pgsz; + if (count_rnd > 0x1800) count_rnd = 0x1800; + if (count_rnd < count) count = count_rnd; + + if (stlink_read_mem32(sl, start - adj_start, count_rnd) != 0) count = 0; + // read failed somehow, don't return stale buffer reply = calloc(count * 2 + 1, 1); for (unsigned int i = 0; i < count; i++) { @@ -1785,15 +1681,9 @@ int serve(stlink_t *sl, st_state_t *st) { } case '!': { - /* - * Enter extended mode which allows restarting. - * We do support that always. - */ - - /* - * Also, set to persistent mode - * to allow GDB disconnect. - */ + // Enter extended mode which allows restarting. We do support that always. + + // Also, set to persistent mode to allow GDB disconnect. st->persistent = 1; reply = strdup("OK"); @@ -1802,9 +1692,7 @@ int serve(stlink_t *sl, st_state_t *st) { } case 'R': { - - /* Reset the core. */ - + // Reset the core. ret = stlink_reset(sl); if (ret) { DLOG("R packet : stlink_reset failed\n"); @@ -1819,35 +1707,25 @@ int serve(stlink_t *sl, st_state_t *st) { break; } case 'k': - /* Kill request - reset the connection itself */ + // Kill request - reset the connection itself ret = stlink_run(sl); - if (ret) { - DLOG("Kill: stlink_run failed\n"); - } - + if (ret) DLOG("Kill: stlink_run failed\n"); ret = stlink_exit_debug_mode(sl); - if (ret) { - DLOG("Kill: stlink_exit_debug_mode failed\n"); - } + if (ret) DLOG("Kill: stlink_exit_debug_mode failed\n"); stlink_close(sl); sl = do_connect(st); - if (sl == NULL || sl->chip_id == STLINK_CHIPID_UNKNOWN) - cleanup(0); + if (sl == NULL || sl->chip_id == STLINK_CHIPID_UNKNOWN) cleanup(0); connected_stlink = sl; - if (st->reset) { - stlink_reset(sl); - } + if (st->reset) stlink_reset(sl); ret = stlink_force_debug(sl); - if (ret) { - DLOG("Kill: stlink_force_debug failed\n"); - } + if (ret) DLOG("Kill: stlink_force_debug failed\n"); init_cache(sl); init_code_breakpoints(sl); init_data_watchpoints(sl); - reply = NULL; /* no response */ + reply = NULL; // no response break; diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index ec126cc7e..c22f2fe5e 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -3,9 +3,11 @@ #include #include #include + #if !defined(_MSC_VER) #include #endif + #include #include #include diff --git a/src/win32/unistd/unistd.h b/src/win32/unistd/unistd.h index 5b2798b41..0cdb9af7b 100644 --- a/src/win32/unistd/unistd.h +++ b/src/win32/unistd/unistd.h @@ -3,19 +3,23 @@ /* * This file intended to serve as a drop-in replacement for unistd.h on Windows - * Please add functionality as neeeded. + * Please add functionality as needed. */ #include #include + #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable: 4820) #endif + #include + #if defined(_MSC_VER) #pragma warning(pop) #endif + #include // getopt at: https://gist.github.com/ashelly/7776712 #include // for getpid() and the exec..() family #include // for _getcwd() and _chdir() @@ -23,7 +27,7 @@ #define srandom srand #define random rand -/* Values for the second argument to access. These may be OR'd together. */ +/* values for the second argument to access. These may be OR'd together. */ #define R_OK 4 // Test for read permission #define W_OK 2 // Test for write permission // #define X_OK 1 // execute permission - unsupported in windows @@ -48,7 +52,7 @@ #define STDIN_FILENO 0 #define STDOUT_FILENO 1 #define STDERR_FILENO 2 -/* should be in some equivalent to */ +// should be in some equivalent to typedef __int8 int8_t; typedef __int16 int16_t; typedef __int32 int32_t; @@ -62,4 +66,4 @@ typedef unsigned __int64 uint64_t; int usleep(unsigned int waitTime); #endif -#endif /* unistd.h */ +#endif // _UNISTD_H diff --git a/src/win32/win32_socket.c b/src/win32/win32_socket.c index 3a3abae16..18f2351f8 100644 --- a/src/win32/win32_socket.c +++ b/src/win32/win32_socket.c @@ -220,7 +220,7 @@ char * win32_strtok_r(char *s, const char *delim, char **lasts) { } } while (sc != 0); } - /* NOTREACHED */ + // NOT REACHED } char *win32_strsep (char **stringp, const char *delim) { @@ -245,7 +245,7 @@ char *win32_strsep (char **stringp, const char *delim) { } } while (sc != 0); } - /* NOTREACHED */ + // NOT REACHED } #ifndef STLINK_HAVE_UNISTD_H diff --git a/src/win32/win32_socket.h b/src/win32/win32_socket.h index 0d26a80e3..d2a3ac38c 100644 --- a/src/win32/win32_socket.h +++ b/src/win32/win32_socket.h @@ -1,4 +1,4 @@ -#if defined(__MINGW32__) || defined(_MSC_VER) +#if defined(_WIN32) #define _USE_W32_SOCKETS 1 @@ -71,4 +71,4 @@ char *win32_strsep(char **stringp, const char *delim); ssize_t win32_read_socket(SOCKET fd, void *buf, int n); ssize_t win32_write_socket(SOCKET fd, void *buf, int n); -#endif // defined(__MINGW32__) || defined(_MSC_VER) +#endif // defined(_WIN32) From 03a358bd078f8d0c965b26ba2ae3098894a2179a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 6 Jun 2020 01:00:17 +0200 Subject: [PATCH 0960/1435] Added check for cflag -std=gnu18 --- cmake/modules/c_flags.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/modules/c_flags.cmake b/cmake/modules/c_flags.cmake index 520182e37..8291ea0ee 100644 --- a/cmake/modules/c_flags.cmake +++ b/cmake/modules/c_flags.cmake @@ -18,6 +18,7 @@ function(add_cflag_if_supported flag) endfunction() add_cflag_if_supported("-std=gnu11") +add_cflag_if_supported("-std=gnu18") add_cflag_if_supported("-Wall") add_cflag_if_supported("-Wextra") add_cflag_if_supported("-Wshadow") From 77df52ff61fdfe2c8675b504e523535bf972da61 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 6 Jun 2020 12:34:32 +0100 Subject: [PATCH 0961/1435] Update Files-Excluded in d/copyright for new layout --- debian/copyright | 4 +--- debian/source/options | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/debian/copyright b/debian/copyright index d56807ca5..cf13a5b4f 100644 --- a/debian/copyright +++ b/debian/copyright @@ -4,9 +4,7 @@ Upstream-Contact: Andrew 'Necromant' Andrianov Source: https://github.com/texane/stlink Comment: Upstream tarball has been repackaged to remove binary OSX kernel drivers that are of unknown license and of no use to Debian. - Upstream's debian directory is also removed. -Files-Excluded: stlinkv1_macosx_driver - debian +Files-Excluded: stlinkv1_macos_driver Files: * Copyright: 2011-2018 agpanarin diff --git a/debian/source/options b/debian/source/options index 7022977a9..506210d2c 100644 --- a/debian/source/options +++ b/debian/source/options @@ -1 +1 @@ -extend-diff-ignore=stlinkv1_macosx_driver +extend-diff-ignore=stlinkv1_macos_driver From 3775e7504eeecbae40813993dc181ae1605a5235 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 6 Jun 2020 12:36:32 +0100 Subject: [PATCH 0962/1435] Fix d/watch intermediary file name --- debian/watch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/watch b/debian/watch index 921dc8f0d..45fece19b 100644 --- a/debian/watch +++ b/debian/watch @@ -1,3 +1,3 @@ version=3 -opts=dversionmangle=s/\+ds$//,repacksuffix=+ds,filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/-$1\.tar\.gz/ \ +opts=dversionmangle=s/\+ds$//,repacksuffix=+ds,filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/stlink-$1\.tar\.gz/ \ https://github.com/texane/stlink/tags .*/v?(\d\S+)\.tar\.gz From b4ddd0d38dfabb88298179fcaf6f5fefa274e35d Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 6 Jun 2020 12:44:55 +0100 Subject: [PATCH 0963/1435] Drop cross.patch, merged upstream in v1.6.1 --- debian/patches/cross.patch | 15 --------------- debian/patches/series | 1 - 2 files changed, 16 deletions(-) delete mode 100644 debian/patches/cross.patch delete mode 100644 debian/patches/series diff --git a/debian/patches/cross.patch b/debian/patches/cross.patch deleted file mode 100644 index 92084238b..000000000 --- a/debian/patches/cross.patch +++ /dev/null @@ -1,15 +0,0 @@ -Author: Helmut Grohne -Description: do not stop the GUI from being cross-compiled -Bug-Debian: 941320 -Forwarded: yes ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -39,7 +39,7 @@ - # Dependencies - ### - find_package(LibUSB REQUIRED) --if (NOT APPLE AND NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) -+if (NOT APPLE AND NOT WIN32) - find_package(PkgConfig) - pkg_check_modules(gtk gtk+-3.0) - endif () diff --git a/debian/patches/series b/debian/patches/series deleted file mode 100644 index def274a02..000000000 --- a/debian/patches/series +++ /dev/null @@ -1 +0,0 @@ -cross.patch From fbaf536f940a5f93debc72ba69429dae4bba9252 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 6 Jun 2020 14:30:41 +0100 Subject: [PATCH 0964/1435] Bump Build-Depends to cmake >= 3.4.2 --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 4382cdcd5..0e81de671 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,7 @@ Source: stlink Priority: optional Maintainer: Luca Boccassi -Build-Depends: debhelper (>= 9), cmake, libusb-1.0-0-dev, libgtk-3-dev +Build-Depends: debhelper (>= 9), cmake (>= 3.4.2), libusb-1.0-0-dev, libgtk-3-dev Standards-Version: 4.5.0 Rules-Requires-Root: no Section: electronics From 1ea5b4d8ff9bae9fc4d921563f800129e66ae164 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 6 Jun 2020 14:30:56 +0100 Subject: [PATCH 0965/1435] Add new symbols from upstream version 1.6.1 --- debian/libstlink1.symbols | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/debian/libstlink1.symbols b/debian/libstlink1.symbols index 4518989a1..159f27d0f 100644 --- a/debian/libstlink1.symbols +++ b/debian/libstlink1.symbols @@ -1,4 +1,8 @@ libstlink.so.1 libstlink1 #MINVER# + Md5Calculate@Base 1.6.1 + Md5Finalise@Base 1.6.1 + Md5Initialise@Base 1.6.1 + Md5Update@Base 1.6.1 _parse_version@Base 1.5.0 _stlink_sg_close@Base 1.5.0 _stlink_sg_core_id@Base 1.5.0 @@ -29,6 +33,7 @@ libstlink.so.1 libstlink1 #MINVER# _stlink_usb_exit_debug_mode@Base 1.5.0 _stlink_usb_exit_dfu_mode@Base 1.5.0 _stlink_usb_force_debug@Base 1.5.0 + _stlink_usb_get_rw_status@Base 1.6.1 _stlink_usb_jtag_reset@Base 1.5.0 _stlink_usb_read_all_regs@Base 1.5.0 _stlink_usb_read_all_unsupported_regs@Base 1.5.0 @@ -40,6 +45,7 @@ libstlink.so.1 libstlink1 #MINVER# _stlink_usb_run@Base 1.5.0 _stlink_usb_set_swdclk@Base 1.5.0 _stlink_usb_status@Base 1.5.0 + _stlink_usb_status_v2@Base 1.6.1 _stlink_usb_step@Base 1.5.0 _stlink_usb_target_voltage@Base 1.5.0 _stlink_usb_version@Base 1.5.0 @@ -79,7 +85,7 @@ libstlink.so.1 libstlink1 #MINVER# stlink_fread@Base 1.5.0 stlink_fwrite_flash@Base 1.5.0 stlink_fwrite_option_bytes@Base 1.6.0 - stlink_fwrite_option_bytes_32bit@Base 1.6.0 +#MISSING: 1.6.1# stlink_fwrite_option_bytes_32bit@Base 1.6.0 stlink_fwrite_sram@Base 1.5.0 stlink_get_erased_pattern@Base 1.5.0 stlink_is_core_halted@Base 1.5.0 @@ -97,8 +103,11 @@ libstlink.so.1 libstlink1 #MINVER# stlink_read_all_unsupported_regs@Base 1.5.0 stlink_read_debug32@Base 1.5.0 stlink_read_mem32@Base 1.5.0 + stlink_read_option_bytes32@Base 1.6.1 + stlink_read_option_bytes_Gx@Base 1.6.1 stlink_read_option_bytes_f2@Base 1.6.0 stlink_read_option_bytes_f4@Base 1.6.0 + stlink_read_option_bytes_generic@Base 1.6.1 stlink_read_reg@Base 1.5.0 stlink_read_unsupported_reg@Base 1.5.0 stlink_reset@Base 1.5.0 @@ -119,11 +128,13 @@ libstlink.so.1 libstlink1 #MINVER# stlink_write_flash@Base 1.5.0 stlink_write_mem32@Base 1.5.0 stlink_write_mem8@Base 1.5.0 + stlink_write_option_bytes32@Base 1.6.1 stlink_write_option_bytes@Base 1.6.0 stlink_write_reg@Base 1.5.0 stlink_write_unsupported_reg@Base 1.5.0 stm32l1_write_half_pages@Base 1.5.0 ugly_init@Base 1.5.0 + ugly_libusb_log_level@Base 1.6.1 ugly_log@Base 1.5.0 write_buffer_to_sram@Base 1.5.0 write_uint16@Base 1.5.0 From c74c942a37913f70fa96a3e10dc6527b026c8fe7 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 6 Jun 2020 14:31:24 +0100 Subject: [PATCH 0966/1435] Adjust install files, some files moved --- debian/stlink-gui.install | 8 ++++---- debian/stlink-tools.manpages | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/debian/stlink-gui.install b/debian/stlink-gui.install index b419ac054..5620a25e5 100644 --- a/debian/stlink-gui.install +++ b/debian/stlink-gui.install @@ -1,4 +1,4 @@ -/usr/bin/stlink-gui* -/usr/share/stlink/stlink-gui.ui -/usr/share/applications/stlink-gui.desktop -/usr/share/icons/hicolor/scalable/apps/stlink-gui.svg +/usr/bin/stlink-gui +/usr/bin/stlink-gui.ui /usr/share/stlink/ +/usr/share/stlink/applications/stlink-gui.desktop /usr/share/applications/ +/usr/share/stlink/icons/hicolor/scalable/apps/stlink-gui.svg /usr/share/icons/hicolor/scalable/apps/stlink-gui.svg diff --git a/debian/stlink-tools.manpages b/debian/stlink-tools.manpages index 6a461c09e..049509abe 100644 --- a/debian/stlink-tools.manpages +++ b/debian/stlink-tools.manpages @@ -1 +1,3 @@ -doc/man/st-*.1 +usr/share/stlink/man/man1/st-flash.1 +usr/share/stlink/man/man1/st-info.1 +usr/share/stlink/man/man1/st-util.1 From f5095079717ebe4168ac26ea0b4a65c0b1f4ec1f Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 6 Jun 2020 14:31:41 +0100 Subject: [PATCH 0967/1435] Remove unused variable from d/rules --- debian/rules | 1 - 1 file changed, 1 deletion(-) diff --git a/debian/rules b/debian/rules index e228a7087..99ee08aa7 100755 --- a/debian/rules +++ b/debian/rules @@ -15,5 +15,4 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all override_dh_auto_configure: dh_auto_configure -- \ - -DLIB_INSTALL_DIR=/usr/lib/$(DEB_HOST_MULTIARCH) \ -DSTLINK_UDEV_RULES_DIR='/lib/udev/rules.d' From 0052b907a9c216b816c79abc33b8ffb8fd29ec4f Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 6 Jun 2020 14:32:03 +0100 Subject: [PATCH 0968/1435] Generate pkgconfig file from d/rules, upstream doesn't do it --- debian/rules | 5 +++++ debian/stlink.pc.in | 10 ++++++++++ 2 files changed, 15 insertions(+) create mode 100644 debian/stlink.pc.in diff --git a/debian/rules b/debian/rules index 99ee08aa7..512bd533f 100755 --- a/debian/rules +++ b/debian/rules @@ -16,3 +16,8 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all override_dh_auto_configure: dh_auto_configure -- \ -DSTLINK_UDEV_RULES_DIR='/lib/udev/rules.d' + +override_dh_auto_install: + dh_auto_install + mkdir -p $(CURDIR)/debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig + sed -e "s/@VERSION@/$(DEB_VERSION_UPSTREAM)/" -e "s/@DEB_HOST_MULTIARCH@/$(DEB_HOST_MULTIARCH)/" $(CURDIR)/debian/stlink.pc.in > $(CURDIR)/debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig/stlink.pc diff --git a/debian/stlink.pc.in b/debian/stlink.pc.in new file mode 100644 index 000000000..7fde2d968 --- /dev/null +++ b/debian/stlink.pc.in @@ -0,0 +1,10 @@ +prefix=/usr +includedir=${prefix}/include/stlink +libdir=${prefix}/lib/@DEB_HOST_MULTIARCH@ + +Name: stlink +Description: Open source version of the STMicroelectronics Stlink Tools +Version: @VERSION@ +Requires: libusb-1.0 +Libs: -L${libdir} -lstlink +Cflags: -I${includedir} From b85c7fb41e9b5a8c5dcde7f6f241d101537e161f Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 6 Jun 2020 14:33:19 +0100 Subject: [PATCH 0969/1435] Switch to debhelper-compat 12 --- debian/compat | 1 - debian/control | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 debian/compat diff --git a/debian/compat b/debian/compat deleted file mode 100644 index ec635144f..000000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/debian/control b/debian/control index 0e81de671..7172583e9 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,7 @@ Source: stlink Priority: optional Maintainer: Luca Boccassi -Build-Depends: debhelper (>= 9), cmake (>= 3.4.2), libusb-1.0-0-dev, libgtk-3-dev +Build-Depends: debhelper-compat (= 12), cmake (>= 3.4.2), libusb-1.0-0-dev, libgtk-3-dev Standards-Version: 4.5.0 Rules-Requires-Root: no Section: electronics From 7056afe415028d6786075d12325e3b835e5d0f02 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 6 Jun 2020 14:45:15 +0100 Subject: [PATCH 0970/1435] Update changelog for 1.6.1+ds-1 release --- debian/changelog | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/debian/changelog b/debian/changelog index 0ad68fed3..26f17b1fb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,18 @@ +stlink (1.6.1+ds-1) unstable; urgency=medium + + * Merge tag 'v1.6.1' into debian + * Update Files-Excluded in d/copyright for new layout + * Fix d/watch intermediary file name + * Drop cross.patch, merged upstream in v1.6.1 + * Bump Build-Depends to cmake >= 3.4.2 + * Add new symbols from upstream version 1.6.1 + * Adjust install files, some files moved + * Remove unused variable from d/rules + * Generate pkgconfig file from d/rules, upstream doesn't do it + * Switch to debhelper-compat 12 + + -- Luca Boccassi Sat, 06 Jun 2020 14:44:54 +0100 + stlink (1.6.0+ds-1) unstable; urgency=medium * Merge tag 'v1.6.0' into debian From c1918c0ff636494546bddbc5cc3793fc287c6594 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 12 Jun 2020 22:28:16 +0200 Subject: [PATCH 0971/1435] Aligned coding style - Added config for uncrustify style settings - Applied changes to source files - Moved some header files --- CMakeLists.txt | 7 +- config/code_style.cfg | 3090 ++++++++++++++++++++++++ flashloaders/linker.ld | 6 +- {src => inc}/backend.h | 4 +- inc/stlink.h | 57 +- inc/stm32.h | 10 +- inc/version.h.in | 2 +- src/common.c | 1970 +++++++-------- src/reg.h | 20 - src/st-flash/flash.c | 153 +- src/st-flash/flash.h | 11 +- src/st-flash/flash_opts.c | 342 +-- src/st-info/info.c | 103 +- src/st-util/gdb-remote.c | 55 +- src/st-util/gdb-remote.h | 2 +- src/st-util/gdb-server.c | 1664 +++++++------ src/st-util/gdb-server.h | 2 +- src/st-util/semihosting.c | 230 +- src/st-util/semihosting.h | 4 +- src/stlink-gui/gui.c | 1089 +++++---- src/stlink-gui/gui.h | 39 +- src/stlink-lib/chipid.c | 1259 +++++----- src/stlink-lib/chipid.h | 134 +- src/{ => stlink-lib}/commands.h | 2 +- src/stlink-lib/flash_loader.c | 497 ++-- src/stlink-lib/flash_loader.h | 8 +- src/{ => stlink-lib}/libusb_settings.h | 36 +- src/stlink-lib/logging.c | 36 +- src/stlink-lib/logging.h | 17 +- src/stlink-lib/md5.c | 259 +- src/stlink-lib/md5.h | 127 +- src/stlink-lib/reg.h | 20 + src/stlink-lib/sg.c | 401 +-- src/stlink-lib/sg.h | 45 +- src/stlink-lib/usb.c | 603 +++-- src/stlink-lib/usb.h | 66 +- src/win32/getopt/README.md | 7 +- src/win32/getopt/getopt.c | 341 ++- src/win32/getopt/getopt.h | 15 +- src/win32/mmap.c | 18 +- src/win32/unistd/unistd.h | 27 +- src/win32/win32_socket.c | 144 +- src/win32/win32_socket.h | 4 +- tests/flash.c | 237 +- tests/sg.c | 58 +- tests/usb.c | 42 +- 46 files changed, 8306 insertions(+), 4957 deletions(-) create mode 100644 config/code_style.cfg rename {src => inc}/backend.h (94%) delete mode 100644 src/reg.h rename src/{ => stlink-lib}/commands.h (97%) rename src/{ => stlink-lib}/libusb_settings.h (53%) create mode 100644 src/stlink-lib/reg.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8428e7565..52f6867f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,10 +95,11 @@ include_directories(src/st-flash) include_directories(src/stlink-lib) set(STLINK_HEADERS + inc/backend.h + src/stlink-lib/commands.h + src/stlink-lib/libusb_settings.h + src/stlink-lib/reg.h inc/stlink.h - src/backend.h - src/commands.h - src/reg.h src/stlink-lib/chipid.h src/stlink-lib/flash_loader.h src/stlink-lib/logging.h diff --git a/config/code_style.cfg b/config/code_style.cfg new file mode 100644 index 000000000..c6ced268c --- /dev/null +++ b/config/code_style.cfg @@ -0,0 +1,3090 @@ +# Uncrustify-0.71.0 + +# +# General options +# + +# The type of line endings. +# +# Default: auto +newlines = auto # lf/crlf/cr/auto + +# The original size of tabs in the input. +# +# Default: 8 +input_tab_size = 4 # unsigned number + +# The size of tabs in the output (only used if align_with_tabs=true). +# +# Default: 8 +output_tab_size = 4 # unsigned number + +# The ASCII value of the string escape char, usually 92 (\) or (Pawn) 94 (^). +# +# Default: 92 +string_escape_char = 92 # unsigned number + +# Alternate string escape char (usually only used for Pawn). +# Only works right before the quote char. +string_escape_char2 = 0 # unsigned number + +# Replace tab characters found in string literals with the escape sequence \t +# instead. +string_replace_tab_chars = false # true/false + +# Allow interpreting '>=' and '>>=' as part of a template in code like +# 'void f(list>=val);'. If true, 'assert(x<0 && y>=3)' will be broken. +# Improvements to template detection may make this option obsolete. +tok_split_gte = false # true/false + +# Disable formatting of NL_CONT ('\\n') ended lines (e.g. multiline macros) +#disable_processing_nl_cont = false # true/false ### not 0.69 + +# Specify the marker used in comments to disable processing of part of the +# file. +# The comment should be used alone in one line. +# +# Default: *INDENT-OFF* +disable_processing_cmt = " *INDENT-OFF*" # string + +# Specify the marker used in comments to (re)enable processing in a file. +# The comment should be used alone in one line. +# +# Default: *INDENT-ON* +enable_processing_cmt = " *INDENT-ON*" # string + +# Enable parsing of digraphs. +enable_digraphs = false # true/false + +# Add or remove the UTF-8 BOM (recommend 'remove'). +utf8_bom = ignore # ignore/add/remove/force + +# If the file contains bytes with values between 128 and 255, but is not +# UTF-8, then output as UTF-8. +utf8_byte = false # true/false + +# Force the output encoding to UTF-8. +utf8_force = true # true/false + +# Add or remove space between 'do' and '{'. +#sp_do_brace_open = add # ignore/add/remove/force ### not 0.69 + +# Add or remove space between '}' and 'while'. +#sp_brace_close_while = add # ignore/add/remove/force ### not 0.69 + +# Add or remove space between 'while' and '('. +#sp_while_paren_open = add # ignore/add/remove/force ### not 0.69 + +# +# Spacing options +# + +# Add or remove space around non-assignment symbolic operators ('+', '/', '%', +# '<<', and so forth). +sp_arith = add # ignore/add/remove/force + +# Add or remove space around arithmetic operators '+' and '-'. +# +# Overrides sp_arith. +sp_arith_additive = add # ignore/add/remove/force + +# Add or remove space around assignment operator '=', '+=', etc. +sp_assign = add # ignore/add/remove/force + +# Add or remove space around '=' in C++11 lambda capture specifications. +# +# Overrides sp_assign. +sp_cpp_lambda_assign = add # ignore/add/remove/force + +# Add or remove space after the capture specification of a C++11 lambda when +# an argument list is present, as in '[] (int x){ ... }'. +#sp_cpp_lambda_square_paren = add # ignore/add/remove/force ### not 0.69 + +# Add or remove space after the capture specification of a C++11 lambda with +# no argument list is present, as in '[] { ... }'. +#sp_cpp_lambda_square_brace = add # ignore/add/remove/force ### not 0.69 + +# Add or remove space after the argument list of a C++11 lambda, as in +# '[](int x) { ... }'. +#sp_cpp_lambda_paren_brace = add # ignore/add/remove/force ### not 0.69 + +# Add or remove space between a lambda body and its call operator of an +# immediately invoked lambda, as in '[]( ... ){ ... } ( ... )'. +#sp_cpp_lambda_fparen = add # ignore/add/remove/force ### not 0.69 + +# Add or remove space around assignment operator '=' in a prototype. +# +# If set to ignore, use sp_assign. +sp_assign_default = add # ignore/add/remove/force + +# Add or remove space before assignment operator '=', '+=', etc. +# +# Overrides sp_assign. +sp_before_assign = add # ignore/add/remove/force + +# Add or remove space after assignment operator '=', '+=', etc. +# +# Overrides sp_assign. +sp_after_assign = add # ignore/add/remove/force + +# Add or remove space in 'NS_ENUM ('. +sp_enum_paren = add # ignore/add/remove/force + +# Add or remove space around assignment '=' in enum. +sp_enum_assign = add # ignore/add/remove/force + +# Add or remove space before assignment '=' in enum. +# +# Overrides sp_enum_assign. +sp_enum_before_assign = add # ignore/add/remove/force + +# Add or remove space after assignment '=' in enum. +# +# Overrides sp_enum_assign. +sp_enum_after_assign = add # ignore/add/remove/force + +# Add or remove space around assignment ':' in enum. +sp_enum_colon = add # ignore/add/remove/force + +# Add or remove space around preprocessor '##' concatenation operator. +# +# Default: add +sp_pp_concat = add # ignore/add/remove/force + +# Add or remove space after preprocessor '#' stringify operator. +# Also affects the '#@' charizing operator. +sp_pp_stringify = ignore # ignore/add/remove/force + +# Add or remove space before preprocessor '#' stringify operator +# as in '#define x(y) L#y'. +sp_before_pp_stringify = ignore # ignore/add/remove/force + +# Add or remove space around boolean operators '&&' and '||'. +sp_bool = add # ignore/add/remove/force + +# Add or remove space around compare operator '<', '>', '==', etc. +sp_compare = add # ignore/add/remove/force + +# Add or remove space inside '(' and ')'. +sp_inside_paren = remove # ignore/add/remove/force + +# Add or remove space between nested parentheses, i.e. '((' vs. ') )'. +sp_paren_paren = remove # ignore/add/remove/force + +# Add or remove space between back-to-back parentheses, i.e. ')(' vs. ') ('. +sp_cparen_oparen = add # ignore/add/remove/force + +# Whether to balance spaces inside nested parentheses. +sp_balance_nested_parens = false # true/false + +# Add or remove space between ')' and '{'. +sp_paren_brace = add # ignore/add/remove/force + +# Add or remove space between nested braces, i.e. '{{' vs '{ {'. +sp_brace_brace = remove # ignore/add/remove/force + +# Add or remove space before pointer star '*'. +sp_before_ptr_star = ignore # ignore/add/remove/force + +# Add or remove space before pointer star '*' that isn't followed by a +# variable name. If set to ignore, sp_before_ptr_star is used instead. +sp_before_unnamed_ptr_star = ignore # ignore/add/remove/force + +# Add or remove space between pointer stars '*'. +sp_between_ptr_star = ignore # ignore/add/remove/force + +# Add or remove space after pointer star '*', if followed by a word. +# +# Overrides sp_type_func. +sp_after_ptr_star = ignore # ignore/add/remove/force + +# Add or remove space after pointer caret '^', if followed by a word. +sp_after_ptr_block_caret = ignore # ignore/add/remove/force + +# Add or remove space after pointer star '*', if followed by a qualifier. +sp_after_ptr_star_qualifier = ignore # ignore/add/remove/force + +# Add or remove space after a pointer star '*', if followed by a function +# prototype or function definition. +# +# Overrides sp_after_ptr_star and sp_type_func. +sp_after_ptr_star_func = ignore # ignore/add/remove/force + +# Add or remove space after a pointer star '*', if followed by an open +# parenthesis, as in 'void* (*)(). +sp_ptr_star_paren = ignore # ignore/add/remove/force + +# Add or remove space before a pointer star '*', if followed by a function +# prototype or function definition. +sp_before_ptr_star_func = ignore # ignore/add/remove/force + +# Add or remove space before a reference sign '&'. +sp_before_byref = ignore # ignore/add/remove/force + +# Add or remove space before a reference sign '&' that isn't followed by a +# variable name. If set to ignore, sp_before_byref is used instead. +sp_before_unnamed_byref = ignore # ignore/add/remove/force + +# Add or remove space after reference sign '&', if followed by a word. +# +# Overrides sp_type_func. +sp_after_byref = ignore # ignore/add/remove/force + +# Add or remove space after a reference sign '&', if followed by a function +# prototype or function definition. +# +# Overrides sp_after_byref and sp_type_func. +sp_after_byref_func = ignore # ignore/add/remove/force + +# Add or remove space before a reference sign '&', if followed by a function +# prototype or function definition. +sp_before_byref_func = ignore # ignore/add/remove/force + +# Add or remove space between type and word. +# +# Default: force +sp_after_type = force # ignore/add/remove/force + +# Add or remove space between 'decltype(...)' and word. +sp_after_decltype = ignore # ignore/add/remove/force + +# (D) Add or remove space before the parenthesis in the D constructs +# 'template Foo(' and 'class Foo('. +sp_before_template_paren = ignore # ignore/add/remove/force + +# Add or remove space between 'template' and '<'. +# If set to ignore, sp_before_angle is used. +sp_template_angle = ignore # ignore/add/remove/force + +# Add or remove space before '<'. +sp_before_angle = ignore # ignore/add/remove/force + +# Add or remove space inside '<' and '>'. +sp_inside_angle = ignore # ignore/add/remove/force + +# Add or remove space inside '<>'. +sp_inside_angle_empty = add # ignore/add/remove/force + +# Add or remove space between '>' and ':'. +sp_angle_colon = ignore # ignore/add/remove/force + +# Add or remove space after '>'. +sp_after_angle = ignore # ignore/add/remove/force + +# Add or remove space between '>' and '(' as found in 'new List(foo);'. +sp_angle_paren = remove # ignore/add/remove/force + +# Add or remove space between '>' and '()' as found in 'new List();'. +sp_angle_paren_empty = remove # ignore/add/remove/force + +# Add or remove space between '>' and a word as in 'List m;' or +# 'template static ...'. +sp_angle_word = add # ignore/add/remove/force + +# Add or remove space between '>' and '>' in '>>' (template stuff). +# +# Default: add +sp_angle_shift = add # ignore/add/remove/force + +# (C++11) Permit removal of the space between '>>' in 'foo >'. Note +# that sp_angle_shift cannot remove the space without this option. +sp_permit_cpp11_shift = false # true/false + +# Add or remove space before '(' of control statements ('if', 'for', 'switch', +# 'while', etc.). +sp_before_sparen = add # ignore/add/remove/force + +# Add or remove space inside '(' and ')' of control statements. +sp_inside_sparen = ignore # ignore/add/remove/force + +# Add or remove space after '(' of control statements. +# +# Overrides sp_inside_sparen. +sp_inside_sparen_open = ignore # ignore/add/remove/force + +# Add or remove space before ')' of control statements. +# +# Overrides sp_inside_sparen. +sp_inside_sparen_close = ignore # ignore/add/remove/force + +# Add or remove space after ')' of control statements. +sp_after_sparen = ignore # ignore/add/remove/force + +# Add or remove space between ')' and '{' of of control statements. +sp_sparen_brace = add # ignore/add/remove/force + +# (D) Add or remove space between 'invariant' and '('. +sp_invariant_paren = ignore # ignore/add/remove/force + +# (D) Add or remove space after the ')' in 'invariant (C) c'. +sp_after_invariant_paren = ignore # ignore/add/remove/force + +# Add or remove space before empty statement ';' on 'if', 'for' and 'while'. +sp_special_semi = add # ignore/add/remove/force + +# Add or remove space before ';'. +# +# Default: remove +sp_before_semi = remove # ignore/add/remove/force + +# Add or remove space before ';' in non-empty 'for' statements. +sp_before_semi_for = remove # ignore/add/remove/force + +# Add or remove space before a semicolon of an empty part of a for statement. +sp_before_semi_for_empty = add # ignore/add/remove/force + +# Add or remove space after ';', except when followed by a comment. +# +# Default: add +sp_after_semi = add # ignore/add/remove/force + +# Add or remove space after ';' in non-empty 'for' statements. +# +# Default: force +sp_after_semi_for = force # ignore/add/remove/force + +# Add or remove space after the final semicolon of an empty part of a for +# statement, as in 'for ( ; ; )'. +sp_after_semi_for_empty = ignore # ignore/add/remove/force + +# Add or remove space before '[' (except '[]'). +sp_before_square = ignore # ignore/add/remove/force + +# Add or remove space before '[' for a variable definition. +# +# Default: remove +#sp_before_vardef_square = remove # ignore/add/remove/force ### not 0.69 + +# Add or remove space before '[' for asm block. +#sp_before_square_asm_block = ignore # ignore/add/remove/force ### not 0.69 + +# Add or remove space before '[]'. +sp_before_squares = ignore # ignore/add/remove/force + +# Add or remove space before C++17 structured bindings. +sp_cpp_before_struct_binding = ignore # ignore/add/remove/force + +# Add or remove space inside a non-empty '[' and ']'. +sp_inside_square = ignore # ignore/add/remove/force + +# (OC) Add or remove space inside a non-empty Objective-C boxed array '@[' and +# ']'. If set to ignore, sp_inside_square is used. +sp_inside_square_oc_array = ignore # ignore/add/remove/force + +# Add or remove space after ',', i.e. 'a,b' vs. 'a, b'. +sp_after_comma = add # ignore/add/remove/force + +# Add or remove space before ','. +# +# Default: remove +sp_before_comma = remove # ignore/add/remove/force + +# (C#) Add or remove space between ',' and ']' in multidimensional array type +# like 'int[,,]'. +sp_after_mdatype_commas = ignore # ignore/add/remove/force + +# (C#) Add or remove space between '[' and ',' in multidimensional array type +# like 'int[,,]'. +sp_before_mdatype_commas = ignore # ignore/add/remove/force + +# (C#) Add or remove space between ',' in multidimensional array type +# like 'int[,,]'. +sp_between_mdatype_commas = ignore # ignore/add/remove/force + +# Add or remove space between an open parenthesis and comma, +# i.e. '(,' vs. '( ,'. +# +# Default: force +sp_paren_comma = force # ignore/add/remove/force + +# Add or remove space before the variadic '...' when preceded by a +# non-punctuator. +sp_before_ellipsis = ignore # ignore/add/remove/force + +# Add or remove space between a type and '...'. +sp_type_ellipsis = ignore # ignore/add/remove/force + +# (D) Add or remove space between a type and '?'. +sp_type_question = ignore # ignore/add/remove/force + +# Add or remove space between ')' and '...'. +sp_paren_ellipsis = ignore # ignore/add/remove/force + +# Add or remove space between ')' and a qualifier such as 'const'. +sp_paren_qualifier = ignore # ignore/add/remove/force + +# Add or remove space between ')' and 'noexcept'. +sp_paren_noexcept = ignore # ignore/add/remove/force + +# Add or remove space after class ':'. +sp_after_class_colon = ignore # ignore/add/remove/force + +# Add or remove space before class ':'. +sp_before_class_colon = ignore # ignore/add/remove/force + +# Add or remove space after class constructor ':'. +sp_after_constr_colon = ignore # ignore/add/remove/force + +# Add or remove space before class constructor ':'. +sp_before_constr_colon = ignore # ignore/add/remove/force + +# Add or remove space before case ':'. +# +# Default: remove +sp_before_case_colon = remove # ignore/add/remove/force + +# Add or remove space between 'operator' and operator sign. +sp_after_operator = ignore # ignore/add/remove/force + +# Add or remove space between the operator symbol and the open parenthesis, as +# in 'operator ++('. +sp_after_operator_sym = ignore # ignore/add/remove/force + +# Overrides sp_after_operator_sym when the operator has no arguments, as in +# 'operator *()'. +sp_after_operator_sym_empty = ignore # ignore/add/remove/force + +# Add or remove space after C/D cast, i.e. 'cast(int)a' vs. 'cast(int) a' or +# '(int)a' vs. '(int) a'. +sp_after_cast = remove # ignore/add/remove/force + +# Add or remove spaces inside cast parentheses. +sp_inside_paren_cast = ignore # ignore/add/remove/force + +# Add or remove space between the type and open parenthesis in a C++ cast, +# i.e. 'int(exp)' vs. 'int (exp)'. +sp_cpp_cast_paren = remove # ignore/add/remove/force + +# Add or remove space between 'sizeof' and '('. +sp_sizeof_paren = remove # ignore/add/remove/force + +# Add or remove space between 'sizeof' and '...'. +sp_sizeof_ellipsis = add # ignore/add/remove/force + +# Add or remove space between 'sizeof...' and '('. +sp_sizeof_ellipsis_paren = add # ignore/add/remove/force + +# Add or remove space between 'decltype' and '('. +sp_decltype_paren = ignore # ignore/add/remove/force + +# (Pawn) Add or remove space after the tag keyword. +sp_after_tag = ignore # ignore/add/remove/force + +# Add or remove space inside enum '{' and '}'. +sp_inside_braces_enum = ignore # ignore/add/remove/force + +# Add or remove space inside struct/union '{' and '}'. +sp_inside_braces_struct = ignore # ignore/add/remove/force + +# (OC) Add or remove space inside Objective-C boxed dictionary '{' and '}' +sp_inside_braces_oc_dict = ignore # ignore/add/remove/force + +# Add or remove space after open brace in an unnamed temporary +# direct-list-initialization. +sp_after_type_brace_init_lst_open = ignore # ignore/add/remove/force + +# Add or remove space before close brace in an unnamed temporary +# direct-list-initialization. +sp_before_type_brace_init_lst_close = ignore # ignore/add/remove/force + +# Add or remove space inside an unnamed temporary direct-list-initialization. +sp_inside_type_brace_init_lst = ignore # ignore/add/remove/force + +# Add or remove space inside '{' and '}'. +sp_inside_braces = ignore # ignore/add/remove/force + +# Add or remove space inside '{}'. +sp_inside_braces_empty = ignore # ignore/add/remove/force + +# Add or remove space around trailing return operator '->'. +#sp_trailing_return = ignore # ignore/add/remove/force ### not 0.69 + +# Add or remove space between return type and function name. A minimum of 1 +# is forced except for pointer return types. +sp_type_func = ignore # ignore/add/remove/force + +# Add or remove space between type and open brace of an unnamed temporary +# direct-list-initialization. +sp_type_brace_init_lst = ignore # ignore/add/remove/force + +# Add or remove space between function name and '(' on function declaration. +sp_func_proto_paren = remove # ignore/add/remove/force + +# Add or remove space between function name and '()' on function declaration +# without parameters. +sp_func_proto_paren_empty = remove # ignore/add/remove/force + +# Add or remove space between function name and '(' with a typedef specifier. +#sp_func_type_paren = ignore # ignore/add/remove/force ### not 0.69 + +# Add or remove space between alias name and '(' of a non-pointer function type typedef. +sp_func_def_paren = ignore # ignore/add/remove/force + +# Add or remove space between function name and '()' on function definition +# without parameters. +sp_func_def_paren_empty = remove # ignore/add/remove/force + +# Add or remove space inside empty function '()'. +# Overrides sp_after_angle unless use_sp_after_angle_always is set to true. +sp_inside_fparens = ignore # ignore/add/remove/force + +# Add or remove space inside function '(' and ')'. +sp_inside_fparen = ignore # ignore/add/remove/force + +# Add or remove space inside the first parentheses in a function type, as in +# 'void (*x)(...)'. +sp_inside_tparen = ignore # ignore/add/remove/force + +# Add or remove space between the ')' and '(' in a function type, as in +# 'void (*x)(...)'. +sp_after_tparen_close = ignore # ignore/add/remove/force + +# Add or remove space between ']' and '(' when part of a function call. +sp_square_fparen = add # ignore/add/remove/force + +# Add or remove space between ')' and '{' of function. +sp_fparen_brace = add # ignore/add/remove/force + +# Add or remove space between ')' and '{' of s function call in object +# initialization. +# +# Overrides sp_fparen_brace. +sp_fparen_brace_initializer = ignore # ignore/add/remove/force + +# (Java) Add or remove space between ')' and '{{' of double brace initializer. +sp_fparen_dbrace = ignore # ignore/add/remove/force + +# Add or remove space between function name and '(' on function calls. +sp_func_call_paren = ignore # ignore/add/remove/force + +# Add or remove space between function name and '()' on function calls without +# parameters. If set to ignore (the default), sp_func_call_paren is used. +sp_func_call_paren_empty = ignore # ignore/add/remove/force + +# Add or remove space between the user function name and '(' on function +# calls. You need to set a keyword to be a user function in the config file, +# like: +# set func_call_user tr _ i18n +sp_func_call_user_paren = ignore # ignore/add/remove/force + +# Add or remove space inside user function '(' and ')'. +sp_func_call_user_inside_fparen = ignore # ignore/add/remove/force + +# Add or remove space between nested parentheses with user functions, +# i.e. '((' vs. '( ('. +sp_func_call_user_paren_paren = ignore # ignore/add/remove/force + +# Add or remove space between a constructor/destructor and the open +# parenthesis. +sp_func_class_paren = ignore # ignore/add/remove/force + +# Add or remove space between a constructor without parameters or destructor +# and '()'. +sp_func_class_paren_empty = ignore # ignore/add/remove/force + +# Add or remove space between 'return' and '('. +sp_return_paren = ignore # ignore/add/remove/force + +# Add or remove space between 'return' and '{'. +sp_return_brace = ignore # ignore/add/remove/force + +# Add or remove space between '__attribute__' and '('. +sp_attribute_paren = ignore # ignore/add/remove/force + +# Add or remove space between 'defined' and '(' in '#if defined (FOO)'. +sp_defined_paren = ignore # ignore/add/remove/force + +# Add or remove space between 'throw' and '(' in 'throw (something)'. +sp_throw_paren = ignore # ignore/add/remove/force + +# Add or remove space between 'throw' and anything other than '(' as in +# '@throw [...];'. +sp_after_throw = ignore # ignore/add/remove/force + +# Add or remove space between 'catch' and '(' in 'catch (something) { }'. +# If set to ignore, sp_before_sparen is used. +sp_catch_paren = ignore # ignore/add/remove/force + +# (OC) Add or remove space between '@catch' and '(' +# in '@catch (something) { }'. If set to ignore, sp_catch_paren is used. +sp_oc_catch_paren = ignore # ignore/add/remove/force + +# (OC) Add or remove space before Objective-C protocol list +# as in '@protocol Protocol' or '@interface MyClass : NSObject'. +#sp_before_oc_proto_list = ignore # ignore/add/remove/force ### not 0.69 + +# (OC) Add or remove space between class name and '(' +# in '@interface className(categoryName):BaseClass' +sp_oc_classname_paren = ignore # ignore/add/remove/force + +# (D) Add or remove space between 'version' and '(' +# in 'version (something) { }'. If set to ignore, sp_before_sparen is used. +sp_version_paren = ignore # ignore/add/remove/force + +# (D) Add or remove space between 'scope' and '(' +# in 'scope (something) { }'. If set to ignore, sp_before_sparen is used. +sp_scope_paren = ignore # ignore/add/remove/force + +# Add or remove space between 'super' and '(' in 'super (something)'. +# +# Default: remove +sp_super_paren = remove # ignore/add/remove/force + +# Add or remove space between 'this' and '(' in 'this (something)'. +# +# Default: remove +sp_this_paren = remove # ignore/add/remove/force + +# Add or remove space between a macro name and its definition. +sp_macro = ignore # ignore/add/remove/force + +# Add or remove space between a macro function ')' and its definition. +sp_macro_func = ignore # ignore/add/remove/force + +# Add or remove space between 'else' and '{' if on the same line. +sp_else_brace = add # ignore/add/remove/force + +# Add or remove space between '}' and 'else' if on the same line. +sp_brace_else = add # ignore/add/remove/force + +# Add or remove space between '}' and the name of a typedef on the same line. +sp_brace_typedef = add # ignore/add/remove/force + +# Add or remove space before the '{' of a 'catch' statement, if the '{' and +# 'catch' are on the same line, as in 'catch (decl) {'. +sp_catch_brace = add # ignore/add/remove/force + +# (OC) Add or remove space before the '{' of a '@catch' statement, if the '{' +# and '@catch' are on the same line, as in '@catch (decl) {'. +# If set to ignore, sp_catch_brace is used. +sp_oc_catch_brace = ignore # ignore/add/remove/force + +# Add or remove space between '}' and 'catch' if on the same line. +sp_brace_catch = add # ignore/add/remove/force + +# (OC) Add or remove space between '}' and '@catch' if on the same line. +# If set to ignore, sp_brace_catch is used. +sp_oc_brace_catch = ignore # ignore/add/remove/force + +# Add or remove space between 'finally' and '{' if on the same line. +sp_finally_brace = add # ignore/add/remove/force + +# Add or remove space between '}' and 'finally' if on the same line. +sp_brace_finally = add # ignore/add/remove/force + +# Add or remove space between 'try' and '{' if on the same line. +sp_try_brace = add # ignore/add/remove/force + +# Add or remove space between get/set and '{' if on the same line. +sp_getset_brace = add # ignore/add/remove/force + +# Add or remove space between a variable and '{' for C++ uniform +# initialization. +#sp_word_brace_init_lst = add # ignore/add/remove/force ### not 0.69 + +# Add or remove space between a variable and '{' for a namespace. +# +# Default: add +sp_word_brace_ns = add # ignore/add/remove/force + +# Add or remove space before the '::' operator. +sp_before_dc = ignore # ignore/add/remove/force + +# Add or remove space after the '::' operator. +sp_after_dc = ignore # ignore/add/remove/force + +# (D) Add or remove around the D named array initializer ':' operator. +sp_d_array_colon = ignore # ignore/add/remove/force + +# Add or remove space after the '!' (not) unary operator. +# +# Default: remove +sp_not = remove # ignore/add/remove/force + +# Add or remove space after the '~' (invert) unary operator. +# +# Default: remove +sp_inv = remove # ignore/add/remove/force + +# Add or remove space after the '&' (address-of) unary operator. This does not +# affect the spacing after a '&' that is part of a type. +# +# Default: remove +sp_addr = remove # ignore/add/remove/force + +# Add or remove space around the '.' or '->' operators. +# +# Default: remove +sp_member = remove # ignore/add/remove/force + +# Add or remove space after the '*' (dereference) unary operator. This does +# not affect the spacing after a '*' that is part of a type. +# +# Default: remove +sp_deref = remove # ignore/add/remove/force + +# Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. +# +# Default: remove +sp_sign = remove # ignore/add/remove/force + +# Add or remove space between '++' and '--' the word to which it is being +# applied, as in '(--x)' or 'y++;'. +# +# Default: remove +sp_incdec = remove # ignore/add/remove/force + +# Add or remove space before a backslash-newline at the end of a line. +# +# Default: add +sp_before_nl_cont = add # ignore/add/remove/force + +# (OC) Add or remove space after the scope '+' or '-', as in '-(void) foo;' +# or '+(int) bar;'. +sp_after_oc_scope = ignore # ignore/add/remove/force + +# (OC) Add or remove space after the colon in message specs, +# i.e. '-(int) f:(int) x;' vs. '-(int) f: (int) x;'. +sp_after_oc_colon = ignore # ignore/add/remove/force + +# (OC) Add or remove space before the colon in message specs, +# i.e. '-(int) f: (int) x;' vs. '-(int) f : (int) x;'. +sp_before_oc_colon = ignore # ignore/add/remove/force + +# (OC) Add or remove space after the colon in immutable dictionary expression +# 'NSDictionary *test = @{@"foo" :@"bar"};'. +sp_after_oc_dict_colon = ignore # ignore/add/remove/force + +# (OC) Add or remove space before the colon in immutable dictionary expression +# 'NSDictionary *test = @{@"foo" :@"bar"};'. +sp_before_oc_dict_colon = ignore # ignore/add/remove/force + +# (OC) Add or remove space after the colon in message specs, +# i.e. '[object setValue:1];' vs. '[object setValue: 1];'. +sp_after_send_oc_colon = ignore # ignore/add/remove/force + +# (OC) Add or remove space before the colon in message specs, +# i.e. '[object setValue:1];' vs. '[object setValue :1];'. +sp_before_send_oc_colon = ignore # ignore/add/remove/force + +# (OC) Add or remove space after the (type) in message specs, +# i.e. '-(int)f: (int) x;' vs. '-(int)f: (int)x;'. +sp_after_oc_type = ignore # ignore/add/remove/force + +# (OC) Add or remove space after the first (type) in message specs, +# i.e. '-(int) f:(int)x;' vs. '-(int)f:(int)x;'. +sp_after_oc_return_type = ignore # ignore/add/remove/force + +# (OC) Add or remove space between '@selector' and '(', +# i.e. '@selector(msgName)' vs. '@selector (msgName)'. +# Also applies to '@protocol()' constructs. +sp_after_oc_at_sel = ignore # ignore/add/remove/force + +# (OC) Add or remove space between '@selector(x)' and the following word, +# i.e. '@selector(foo) a:' vs. '@selector(foo)a:'. +sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force + +# (OC) Add or remove space inside '@selector' parentheses, +# i.e. '@selector(foo)' vs. '@selector( foo )'. +# Also applies to '@protocol()' constructs. +sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force + +# (OC) Add or remove space before a block pointer caret, +# i.e. '^int (int arg){...}' vs. ' ^int (int arg){...}'. +sp_before_oc_block_caret = ignore # ignore/add/remove/force + +# (OC) Add or remove space after a block pointer caret, +# i.e. '^int (int arg){...}' vs. '^ int (int arg){...}'. +sp_after_oc_block_caret = ignore # ignore/add/remove/force + +# (OC) Add or remove space between the receiver and selector in a message, +# as in '[receiver selector ...]'. +sp_after_oc_msg_receiver = ignore # ignore/add/remove/force + +# (OC) Add or remove space after '@property'. +sp_after_oc_property = ignore # ignore/add/remove/force + +# (OC) Add or remove space between '@synchronized' and the open parenthesis, +# i.e. '@synchronized(foo)' vs. '@synchronized (foo)'. +sp_after_oc_synchronized = ignore # ignore/add/remove/force + +# Add or remove space around the ':' in 'b ? t : f'. +sp_cond_colon = add # ignore/add/remove/force + +# Add or remove space before the ':' in 'b ? t : f'. +# +# Overrides sp_cond_colon. +sp_cond_colon_before = ignore # ignore/add/remove/force + +# Add or remove space after the ':' in 'b ? t : f'. +# +# Overrides sp_cond_colon. +sp_cond_colon_after = ignore # ignore/add/remove/force + +# Add or remove space around the '?' in 'b ? t : f'. +sp_cond_question = add # ignore/add/remove/force + +# Add or remove space before the '?' in 'b ? t : f'. +# +# Overrides sp_cond_question. +sp_cond_question_before = ignore # ignore/add/remove/force + +# Add or remove space after the '?' in 'b ? t : f'. +# +# Overrides sp_cond_question. +sp_cond_question_after = ignore # ignore/add/remove/force + +# In the abbreviated ternary form '(a ?: b)', add or remove space between '?' +# and ':'. +# +# Overrides all other sp_cond_* options. +sp_cond_ternary_short = ignore # ignore/add/remove/force + +# Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make +# sense here. +sp_case_label = ignore # ignore/add/remove/force + +# (D) Add or remove space around the D '..' operator. +sp_range = ignore # ignore/add/remove/force + +# Add or remove space after ':' in a Java/C++11 range-based 'for', +# as in 'for (Type var : expr)'. +sp_after_for_colon = ignore # ignore/add/remove/force + +# Add or remove space before ':' in a Java/C++11 range-based 'for', +# as in 'for (Type var : expr)'. +sp_before_for_colon = ignore # ignore/add/remove/force + +# (D) Add or remove space between 'extern' and '(' as in 'extern (C)'. +sp_extern_paren = ignore # ignore/add/remove/force + +# Add or remove space after the opening of a C++ comment, +# i.e. '// A' vs. '//A'. +sp_cmt_cpp_start = add # ignore/add/remove/force + +# If true, space is added with sp_cmt_cpp_start will be added after doxygen +# sequences like '///', '///<', '//!' and '//!<'. +sp_cmt_cpp_doxygen = false # true/false + +# If true, space is added with sp_cmt_cpp_start will be added after Qt +# translator or meta-data comments like '//:', '//=', and '//~'. +sp_cmt_cpp_qttr = false # true/false + +# Add or remove space between #else or #endif and a trailing comment. +sp_endif_cmt = add # ignore/add/remove/force + +# Add or remove space after 'new', 'delete' and 'delete[]'. +sp_after_new = ignore # ignore/add/remove/force + +# Add or remove space between 'new' and '(' in 'new()'. +sp_between_new_paren = ignore # ignore/add/remove/force + +# Add or remove space between ')' and type in 'new(foo) BAR'. +sp_after_newop_paren = ignore # ignore/add/remove/force + +# Add or remove space inside parenthesis of the new operator +# as in 'new(foo) BAR'. +sp_inside_newop_paren = ignore # ignore/add/remove/force + +# Add or remove space after the open parenthesis of the new operator, +# as in 'new(foo) BAR'. +# +# Overrides sp_inside_newop_paren. +sp_inside_newop_paren_open = ignore # ignore/add/remove/force + +# Add or remove space before the close parenthesis of the new operator, +# as in 'new(foo) BAR'. +# +# Overrides sp_inside_newop_paren. +sp_inside_newop_paren_close = ignore # ignore/add/remove/force + +# Add or remove space before a trailing or embedded comment. +sp_before_tr_emb_cmt = ignore # ignore/add/remove/force + +# Number of spaces before a trailing or embedded comment. +sp_num_before_tr_emb_cmt = 0 # unsigned number + +# (Java) Add or remove space between an annotation and the open parenthesis. +sp_annotation_paren = ignore # ignore/add/remove/force + +# If true, vbrace tokens are dropped to the previous token and skipped. +sp_skip_vbrace_tokens = false # true/false + +# Add or remove space after 'noexcept'. +sp_after_noexcept = ignore # ignore/add/remove/force + +# Add or remove space after '_'. +sp_vala_after_translation = ignore # ignore/add/remove/force + +# If true, a is inserted after #define. +force_tab_after_define = false # true/false + +# +# Indenting options +# + +# The number of columns to indent per level. Usually 2, 3, 4, or 8. +# +# Default: 8 +indent_columns = 4 # unsigned number + +# The continuation indent. If non-zero, this overrides the indent of '(', '[' +# and '=' continuation indents. Negative values are OK; negative value is +# absolute and not increased for each '(' or '[' level. +# +# For FreeBSD, this is set to 4. +indent_continue = 0 # number + +# The continuation indent, only for class header line(s). If non-zero, this +# overrides the indent of 'class' continuation indents. +indent_continue_class_head = 0 # unsigned number + +# Whether to indent empty lines (i.e. lines which contain only spaces before +# the newline character). +indent_single_newlines = false # true/false + +# The continuation indent for func_*_param if they are true. If non-zero, this +# overrides the indent. +indent_param = 0 # unsigned number + +# How to use tabs when indenting code. +# +# 0: Spaces only +# 1: Indent with tabs to brace level, align with spaces (default) +# 2: Indent and align with tabs, using spaces when not on a tabstop +# +# Default: 1 +indent_with_tabs = 0 # unsigned number + +# Whether to indent comments that are not at a brace level with tabs on a +# tabstop. Requires indent_with_tabs=2. If false, will use spaces. +indent_cmt_with_tabs = false # true/false + +# Whether to indent strings broken by '\' so that they line up. +indent_align_string = false # true/false + +# The number of spaces to indent multi-line XML strings. +# Requires indent_align_string=true. +indent_xml_string = 0 # unsigned number + +# Spaces to indent '{' from level. +indent_brace = 0 # unsigned number + +# Whether braces are indented to the body level. +indent_braces = false # true/false + +# Whether to disable indenting function braces if indent_braces=true. +indent_braces_no_func = false # true/false + +# Whether to disable indenting class braces if indent_braces=true. +indent_braces_no_class = false # true/false + +# Whether to disable indenting struct braces if indent_braces=true. +indent_braces_no_struct = false # true/false + +# Whether to indent based on the size of the brace parent, +# i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc. +indent_brace_parent = false # true/false + +# Whether to indent based on the open parenthesis instead of the open brace +# in '({\n'. +indent_paren_open_brace = false # true/false + +# (C#) Whether to indent the brace of a C# delegate by another level. +indent_cs_delegate_brace = false # true/false + +# (C#) Whether to indent a C# delegate (to handle delegates with no brace) by +# another level. +indent_cs_delegate_body = false # true/false + +# Whether to indent the body of a 'namespace'. +indent_namespace = false # true/false + +# Whether to indent only the first namespace, and not any nested namespaces. +# Requires indent_namespace=true. +indent_namespace_single_indent = false # true/false + +# The number of spaces to indent a namespace block. +# If set to zero, use the value indent_columns +indent_namespace_level = 0 # unsigned number + +# If the body of the namespace is longer than this number, it won't be +# indented. Requires indent_namespace=true. 0 means no limit. +indent_namespace_limit = 0 # unsigned number + +# Whether the 'extern "C"' body is indented. +indent_extern = false # true/false + +# Whether the 'class' body is indented. +indent_class = false # true/false + +# Whether to indent the stuff after a leading base class colon. +indent_class_colon = false # true/false + +# Whether to indent based on a class colon instead of the stuff after the +# colon. Requires indent_class_colon=true. +indent_class_on_colon = false # true/false + +# Whether to indent the stuff after a leading class initializer colon. +indent_constr_colon = false # true/false + +# Virtual indent from the ':' for member initializers. +# +# Default: 2 +indent_ctor_init_leading = 2 # unsigned number + +# Additional indent for constructor initializer list. +# Negative values decrease indent down to the first column. +indent_ctor_init = 0 # number + +# Whether to indent 'if' following 'else' as a new block under the 'else'. +# If false, 'else\nif' is treated as 'else if' for indenting purposes. +indent_else_if = false # true/false + +# Amount to indent variable declarations after a open brace. +# +# <0: Relative +# >=0: Absolute +indent_var_def_blk = 0 # number + +# Whether to indent continued variable declarations instead of aligning. +indent_var_def_cont = false # true/false + +# Whether to indent continued shift expressions ('<<' and '>>') instead of +# aligning. Set align_left_shift=false when enabling this. +indent_shift = false # true/false + +# Whether to force indentation of function definitions to start in column 1. +indent_func_def_force_col1 = false # true/false + +# Whether to indent continued function call parameters one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_call_param = false # true/false + +# Whether to indent continued function definition parameters one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_def_param = false # true/false + +# for function definitions, only if indent_func_def_param is false +# Allows to align params when appropriate and indent them when not +# behave as if it was true if paren position is more than this value +# if paren position is more than the option value +#indent_func_def_param_paren_pos_threshold = 0 # unsigned number ### not 0.69 + +# Whether to indent continued function call prototype one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_proto_param = false # true/false + +# Whether to indent continued function call declaration one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_class_param = false # true/false + +# Whether to indent continued class variable constructors one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_ctor_var_param = false # true/false + +# Whether to indent continued template parameter list one indent level, +# rather than aligning parameters under the open parenthesis. +indent_template_param = false # true/false + +# Double the indent for indent_func_xxx_param options. +# Use both values of the options indent_columns and indent_param. +indent_func_param_double = false # true/false + +# Indentation column for standalone 'const' qualifier on a function +# prototype. +indent_func_const = 0 # unsigned number + +# Indentation column for standalone 'throw' qualifier on a function +# prototype. +indent_func_throw = 0 # unsigned number + +# How to indent within a macro followed by a brace on the same line +# This allows reducing the indent in macros that have (for example) +# `do { ... } while (0)` blocks bracketing them. +# +# true: add an indent for the brace on the same line as the macro +# false: do not add an indent for the brace on the same line as the macro +# +# Default: true +#indent_macro_brace = true # true/false ### not 0.69 + +# The number of spaces to indent a continued '->' or '.'. +# Usually set to 0, 1, or indent_columns. +indent_member = 0 # unsigned number + +# Whether lines broken at '.' or '->' should be indented by a single indent. +# The indent_member option will not be effective if this is set to true. +indent_member_single = false # true/false + +# Spaces to indent single line ('//') comments on lines before code. +indent_sing_line_comments = 0 # unsigned number + +# When opening a paren for a control statement (if, for, while, etc), increase +# the indent level by this value. Negative values decrease the indent level. +#indent_sparen_extra = 0 # number ### not 0.69 + +# Whether to indent trailing single line ('//') comments relative to the code +# instead of trying to keep the same absolute column. +indent_relative_single_line_comments = false # true/false + +# Spaces to indent 'case' from 'switch'. Usually 0 or indent_columns. +indent_switch_case = 0 # unsigned number + +# indent 'break' with 'case' from 'switch'. +#indent_switch_break_with_case = false # true/false ### not 0.69 + +# Whether to indent preprocessor statements inside of switch statements. +# +# Default: true +indent_switch_pp = true # true/false + +# Spaces to shift the 'case' line, without affecting any other lines. +# Usually 0. +indent_case_shift = 0 # unsigned number + +# Spaces to indent '{' from 'case'. By default, the brace will appear under +# the 'c' in case. Usually set to 0 or indent_columns. Negative values are OK. +indent_case_brace = 0 # number + +# Whether to indent comments found in first column. +indent_col1_comment = false # true/false + +# Whether to indent multi string literal in first column. +indent_col1_multi_string_literal = false # true/false + +# How to indent goto labels. +# +# >0: Absolute column where 1 is the leftmost column +# <=0: Subtract from brace indent +# +# Default: 1 +indent_label = 1 # number + +# How to indent access specifiers that are followed by a +# colon. +# +# >0: Absolute column where 1 is the leftmost column +# <=0: Subtract from brace indent +# +# Default: 1 +indent_access_spec = 1 # number + +# Whether to indent the code after an access specifier by one level. +# If true, this option forces 'indent_access_spec=0'. +indent_access_spec_body = false # true/false + +# If an open parenthesis is followed by a newline, whether to indent the next +# line so that it lines up after the open parenthesis (not recommended). +indent_paren_nl = false # true/false + +# How to indent a close parenthesis after a newline. +# +# 0: Indent to body level (default) +# 1: Align under the open parenthesis +# 2: Indent to the brace level +indent_paren_close = 0 # unsigned number + +# Whether to indent the open parenthesis of a function definition, +# if the parenthesis is on its own line. +indent_paren_after_func_def = false # true/false + +# Whether to indent the open parenthesis of a function declaration, +# if the parenthesis is on its own line. +indent_paren_after_func_decl = false # true/false + +# Whether to indent the open parenthesis of a function call, +# if the parenthesis is on its own line. +indent_paren_after_func_call = false # true/false + +# Whether to indent a comma when inside a parenthesis. +# If true, aligns under the open parenthesis. +indent_comma_paren = false # true/false + +# Whether to indent a Boolean operator when inside a parenthesis. +# If true, aligns under the open parenthesis. +indent_bool_paren = false # true/false + +# Whether to indent a semicolon when inside a for parenthesis. +# If true, aligns under the open for parenthesis. +indent_semicolon_for_paren = false # true/false + +# Whether to align the first expression to following ones +# if indent_bool_paren=true. +indent_first_bool_expr = false # true/false + +# Whether to align the first expression to following ones +# if indent_semicolon_for_paren=true. +indent_first_for_expr = false # true/false + +# If an open square is followed by a newline, whether to indent the next line +# so that it lines up after the open square (not recommended). +indent_square_nl = false # true/false + +# (ESQL/C) Whether to preserve the relative indent of 'EXEC SQL' bodies. +indent_preserve_sql = false # true/false + +# Whether to align continued statements at the '='. If false or if the '=' is +# followed by a newline, the next line is indent one tab. +# +# Default: true +indent_align_assign = true # true/false + +# If true, the indentation of the chunks after a '=' sequence will be set at +# LHS token indentation column before '='. +#indent_off_after_assign = false # true/false ### not 0.69 + +# Whether to align continued statements at the '('. If false or the '(' is +# followed by a newline, the next line indent is one tab. +# +# Default: true +indent_align_paren = true # true/false + +# (OC) Whether to indent Objective-C code inside message selectors. +#indent_oc_inside_msg_sel = false # true/false ### not 0.69 + +# (OC) Whether to indent Objective-C blocks at brace level instead of usual +# rules. +indent_oc_block = false # true/false + +# (OC) Indent for Objective-C blocks in a message relative to the parameter +# name. +# +# =0: Use indent_oc_block rules +# >0: Use specified number of spaces to indent +indent_oc_block_msg = 0 # unsigned number + +# (OC) Minimum indent for subsequent parameters +indent_oc_msg_colon = 0 # unsigned number + +# (OC) Whether to prioritize aligning with initial colon (and stripping spaces +# from lines, if necessary). +# +# Default: true +indent_oc_msg_prioritize_first_colon = true # true/false + +# (OC) Whether to indent blocks the way that Xcode does by default +# (from the keyword if the parameter is on its own line; otherwise, from the +# previous indentation level). Requires indent_oc_block_msg=true. +indent_oc_block_msg_xcode_style = false # true/false + +# (OC) Whether to indent blocks from where the brace is, relative to a +# message keyword. Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_keyword = false # true/false + +# (OC) Whether to indent blocks from where the brace is, relative to a message +# colon. Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_colon = false # true/false + +# (OC) Whether to indent blocks from where the block caret is. +# Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_caret = false # true/false + +# (OC) Whether to indent blocks from where the brace caret is. +# Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_brace = false # true/false + +# When indenting after virtual brace open and newline add further spaces to +# reach this minimum indent. +indent_min_vbrace_open = 0 # unsigned number + +# Whether to add further spaces after regular indent to reach next tabstop +# when identing after virtual brace open and newline. +indent_vbrace_open_on_tabstop = false # true/false + +# How to indent after a brace followed by another token (not a newline). +# true: indent all contained lines to match the token +# false: indent all contained lines to match the brace +# +# Default: true +indent_token_after_brace = true # true/false + +# Whether to indent the body of a C++11 lambda. +indent_cpp_lambda_body = false # true/false + +# How to indent compound literals that are being returned. +# true: add both the indent from return & the compound literal open brace (ie: +# 2 indent levels) +# false: only indent 1 level, don't add the indent for the open brace, only add +# the indent for the return. +# +# Default: true +#indent_compound_literal_return = true # true/false ### not 0.69 + +# (C#) Whether to indent a 'using' block if no braces are used. +# +# Default: true +indent_using_block = true # true/false + +# How to indent the continuation of ternary operator. +# +# 0: Off (default) +# 1: When the `if_false` is a continuation, indent it under `if_false` +# 2: When the `:` is a continuation, indent it under `?` +indent_ternary_operator = 0 # unsigned number + +# Whether to indent the statments inside ternary operator. +#indent_inside_ternary_operator = false # true/false ### not 0.69 + +# If true, the indentation of the chunks after a `return` sequence will be set at return indentation column. +#indent_off_after_return = false # true/false ### not 0.69 + +# If true, the indentation of the chunks after a `return new` sequence will be set at return indentation column. +indent_off_after_return_new = false # true/false + +# If true, the tokens after return are indented with regular single indentation. By default (false) the indentation is after the return token. +indent_single_after_return = false # true/false + +# Whether to ignore indent and alignment for 'asm' blocks (i.e. assume they +# have their own indentation). +indent_ignore_asm_block = false # true/false + +# +# Newline adding and removing options +# + +# Whether to collapse empty blocks between '{' and '}'. +nl_collapse_empty_body = false # true/false + +# Don't split one-line braced assignments, as in 'foo_t f = { 1, 2 };'. +nl_assign_leave_one_liners = false # true/false + +# Don't split one-line braced statements inside a 'class xx { }' body. +nl_class_leave_one_liners = false # true/false + +# Don't split one-line enums, as in 'enum foo { BAR = 15 };' +nl_enum_leave_one_liners = false # true/false + +# Don't split one-line get or set functions. +nl_getset_leave_one_liners = false # true/false + +# (C#) Don't split one-line property get or set functions. +nl_cs_property_leave_one_liners = false # true/false + +# Don't split one-line function definitions, as in 'int foo() { return 0; }'. +# might modify nl_func_type_name +nl_func_leave_one_liners = false # true/false + +# Don't split one-line C++11 lambdas, as in '[]() { return 0; }'. +nl_cpp_lambda_leave_one_liners = false # true/false + +# Don't split one-line if/else statements, as in 'if(...) b++;'. +nl_if_leave_one_liners = false # true/false + +# Don't split one-line while statements, as in 'while(...) b++;'. +nl_while_leave_one_liners = false # true/false + +# Don't split one-line for statements, as in 'for(...) b++;'. +nl_for_leave_one_liners = false # true/false + +# (OC) Don't split one-line Objective-C messages. +nl_oc_msg_leave_one_liner = false # true/false + +# (OC) Add or remove newline between method declaration and '{'. +nl_oc_mdef_brace = ignore # ignore/add/remove/force + +# (OC) Add or remove newline between Objective-C block signature and '{'. +nl_oc_block_brace = ignore # ignore/add/remove/force + +# (OC) Add or remove blank line before '@interface' statement. +#nl_oc_before_interface = ignore # ignore/add/remove/force ### not 0.69 + +# (OC) Add or remove blank line before '@implementation' statement. +#nl_oc_before_implementation = ignore # ignore/add/remove/force ### not 0.69 + +# (OC) Add or remove blank line before '@end' statement. +#nl_oc_before_end = ignore # ignore/add/remove/force ### not 0.69 + +# (OC) Add or remove newline between '@interface' and '{'. +nl_oc_interface_brace = ignore # ignore/add/remove/force + +# (OC) Add or remove newline between '@implementation' and '{'. +nl_oc_implementation_brace = ignore # ignore/add/remove/force + +# Add or remove newlines at the start of the file. +nl_start_of_file = remove # ignore/add/remove/force + +# The minimum number of newlines at the start of the file (only used if +# nl_start_of_file is 'add' or 'force'). +nl_start_of_file_min = 0 # unsigned number + +# Add or remove newline at the end of the file. +nl_end_of_file = ignore # ignore/add/remove/force + +# The minimum number of newlines at the end of the file (only used if +# nl_end_of_file is 'add' or 'force'). +nl_end_of_file_min = 0 # unsigned number + +# Add or remove newline between '=' and '{'. +nl_assign_brace = ignore # ignore/add/remove/force + +# (D) Add or remove newline between '=' and '['. +nl_assign_square = ignore # ignore/add/remove/force + +# Add or remove newline between '[]' and '{'. +nl_tsquare_brace = ignore # ignore/add/remove/force + +# (D) Add or remove newline after '= ['. Will also affect the newline before +# the ']'. +nl_after_square_assign = ignore # ignore/add/remove/force + +# Add or remove newline between a function call's ')' and '{', as in +# 'list_for_each(item, &list) { }'. +nl_fcall_brace = ignore # ignore/add/remove/force + +# Add or remove newline between 'enum' and '{'. +nl_enum_brace = remove # ignore/add/remove/force + +# Add or remove newline between 'enum' and 'class'. +nl_enum_class = ignore # ignore/add/remove/force + +# Add or remove newline between 'enum class' and the identifier. +nl_enum_class_identifier = ignore # ignore/add/remove/force + +# Add or remove newline between 'enum class' type and ':'. +nl_enum_identifier_colon = ignore # ignore/add/remove/force + +# Add or remove newline between 'enum class identifier :' and type. +nl_enum_colon_type = ignore # ignore/add/remove/force + +# Add or remove newline between 'struct and '{'. +nl_struct_brace = remove # ignore/add/remove/force + +# Add or remove newline between 'union' and '{'. +nl_union_brace = remove # ignore/add/remove/force + +# Add or remove newline between 'if' and '{'. +nl_if_brace = remove # ignore/add/remove/force + +# Add or remove newline between '}' and 'else'. +nl_brace_else = remove # ignore/add/remove/force + +# Add or remove newline between 'else if' and '{'. If set to ignore, +# nl_if_brace is used instead. +nl_elseif_brace = remove # ignore/add/remove/force + +# Add or remove newline between 'else' and '{'. +nl_else_brace = remove # ignore/add/remove/force + +# Add or remove newline between 'else' and 'if'. +nl_else_if = remove # ignore/add/remove/force + +# Add or remove newline before '{' opening brace +#nl_before_opening_brace_func_class_def = remove # ignore/add/remove/force ### not 0.69 + +# Add or remove newline before 'if'/'else if' closing parenthesis. +nl_before_if_closing_paren = remove # ignore/add/remove/force + +# Add or remove newline between '}' and 'finally'. +nl_brace_finally = remove # ignore/add/remove/force + +# Add or remove newline between 'finally' and '{'. +nl_finally_brace = remove # ignore/add/remove/force + +# Add or remove newline between 'try' and '{'. +nl_try_brace = remove # ignore/add/remove/force + +# Add or remove newline between get/set and '{'. +nl_getset_brace = remove # ignore/add/remove/force + +# Add or remove newline between 'for' and '{'. +nl_for_brace = remove # ignore/add/remove/force + +# Add or remove newline before the '{' of a 'catch' statement, as in +# 'catch (decl) {'. +nl_catch_brace = remove # ignore/add/remove/force + +# (OC) Add or remove newline before the '{' of a '@catch' statement, as in +# '@catch (decl) {'. If set to ignore, nl_catch_brace is used. +nl_oc_catch_brace = ignore # ignore/add/remove/force + +# Add or remove newline between '}' and 'catch'. +nl_brace_catch = remove # ignore/add/remove/force + +# (OC) Add or remove newline between '}' and '@catch'. If set to ignore, +# nl_brace_catch is used. +nl_oc_brace_catch = ignore # ignore/add/remove/force + +# Add or remove newline between '}' and ']'. +nl_brace_square = ignore # ignore/add/remove/force + +# Add or remove newline between '}' and ')' in a function invocation. +nl_brace_fparen = ignore # ignore/add/remove/force + +# Add or remove newline between 'while' and '{'. +nl_while_brace = remove # ignore/add/remove/force + +# (D) Add or remove newline between 'scope (x)' and '{'. +nl_scope_brace = ignore # ignore/add/remove/force + +# (D) Add or remove newline between 'unittest' and '{'. +nl_unittest_brace = ignore # ignore/add/remove/force + +# (D) Add or remove newline between 'version (x)' and '{'. +nl_version_brace = ignore # ignore/add/remove/force + +# (C#) Add or remove newline between 'using' and '{'. +nl_using_brace = ignore # ignore/add/remove/force + +# Add or remove newline between two open or close braces. Due to general +# newline/brace handling, REMOVE may not work. +nl_brace_brace = add # ignore/add/remove/force + +# Add or remove newline between 'do' and '{'. +nl_do_brace = remove # ignore/add/remove/force + +# Add or remove newline between '}' and 'while' of 'do' statement. +nl_brace_while = remove # ignore/add/remove/force + +# Add or remove newline between 'switch' and '{'. +nl_switch_brace = remove # ignore/add/remove/force + +# Add or remove newline between 'synchronized' and '{'. +nl_synchronized_brace = remove # ignore/add/remove/force + +# Add a newline between ')' and '{' if the ')' is on a different line than the +# if/for/etc. +# +# Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch and +# nl_catch_brace. +nl_multi_line_cond = false # true/false + +# Add a newline after '(' if an if/for/while/switch condition spans multiple +# lines +#nl_multi_line_sparen_open = ignore # ignore/add/remove/force ### not 0.69 + +# Add a newline before ')' if an if/for/while/switch condition spans multiple +# lines. Overrides nl_before_if_closing_paren if both are specified. +#nl_multi_line_sparen_close = ignore # ignore/add/remove/force ### not 0.69 + +# Force a newline in a define after the macro name for multi-line defines. +nl_multi_line_define = false # true/false + +# Whether to add a newline before 'case', and a blank line before a 'case' +# statement that follows a ';' or '}'. +nl_before_case = false # true/false + +# Whether to add a newline after a 'case' statement. +nl_after_case = false # true/false + +# Add or remove newline between a case ':' and '{'. +# +# Overrides nl_after_case. +nl_case_colon_brace = ignore # ignore/add/remove/force + +# Add or remove newline between ')' and 'throw'. +nl_before_throw = ignore # ignore/add/remove/force + +# Add or remove newline between 'namespace' and '{'. +nl_namespace_brace = ignore # ignore/add/remove/force + +# Add or remove newline after 'template<...>' of a template class. +nl_template_class = ignore # ignore/add/remove/force + +# Add or remove newline after 'template<...>' of a template class declaration. +# +# Overrides nl_template_class. +#nl_template_class_decl = ignore # ignore/add/remove/force ### not 0.69 + +# Add or remove newline after 'template<>' of a specialized class declaration. +# +# Overrides nl_template_class_decl. +#nl_template_class_decl_special = ignore # ignore/add/remove/force ### not 0.69 + +# Add or remove newline after 'template<...>' of a template class definition. +# +# Overrides nl_template_class. +#nl_template_class_def = ignore # ignore/add/remove/force ### not 0.69 + +# Add or remove newline after 'template<>' of a specialized class definition. +# +# Overrides nl_template_class_def. +#nl_template_class_def_special = ignore # ignore/add/remove/force ### not 0.69 + +# Add or remove newline after 'template<...>' of a template function. +#nl_template_func = ignore # ignore/add/remove/force ### not 0.69 + +# Add or remove newline after 'template<...>' of a template function +# declaration. +# +# Overrides nl_template_func. +#nl_template_func_decl = ignore # ignore/add/remove/force ### not 0.69 + +# Add or remove newline after 'template<>' of a specialized function +# declaration. +# +# Overrides nl_template_func_decl. +#nl_template_func_decl_special = ignore # ignore/add/remove/force ### not 0.69 + +# Add or remove newline after 'template<...>' of a template function +# definition. +# +# Overrides nl_template_func. +#nl_template_func_def = ignore # ignore/add/remove/force ### not 0.69 + +# Add or remove newline after 'template<>' of a specialized function +# definition. +# +# Overrides nl_template_func_def. +#nl_template_func_def_special = ignore # ignore/add/remove/force ### not 0.69 + +# Add or remove newline after 'template<...>' of a template variable. +#nl_template_var = ignore # ignore/add/remove/force ### not 0.69 + +# Add or remove newline between 'template<...>' and 'using' of a templated +# type alias. +#nl_template_using = ignore # ignore/add/remove/force ### not 0.69 + +# Add or remove newline between 'class' and '{'. +nl_class_brace = ignore # ignore/add/remove/force + +# Add or remove newline before or after (depending on pos_class_comma, +# may not be IGNORE) each',' in the base class list. +nl_class_init_args = ignore # ignore/add/remove/force + +# Add or remove newline after each ',' in the constructor member +# initialization. Related to nl_constr_colon, pos_constr_colon and +# pos_constr_comma. +nl_constr_init_args = ignore # ignore/add/remove/force + +# Add or remove newline before first element, after comma, and after last +# element, in 'enum'. +nl_enum_own_lines = ignore # ignore/add/remove/force + +# Add or remove newline between return type and function name in a function +# definition. +# might be modified by nl_func_leave_one_liners +nl_func_type_name = ignore # ignore/add/remove/force + +# Add or remove newline between return type and function name inside a class +# definition. If set to ignore, nl_func_type_name or nl_func_proto_type_name +# is used instead. +nl_func_type_name_class = ignore # ignore/add/remove/force + +# Add or remove newline between class specification and '::' +# in 'void A::f() { }'. Only appears in separate member implementation (does +# not appear with in-line implementation). +nl_func_class_scope = ignore # ignore/add/remove/force + +# Add or remove newline between function scope and name, as in +# 'void A :: f() { }'. +nl_func_scope_name = ignore # ignore/add/remove/force + +# Add or remove newline between return type and function name in a prototype. +nl_func_proto_type_name = ignore # ignore/add/remove/force + +# Add or remove newline between a function name and the opening '(' in the +# declaration. +nl_func_paren = remove # ignore/add/remove/force + +# Overrides nl_func_paren for functions with no parameters. +nl_func_paren_empty = ignore # ignore/add/remove/force + +# Add or remove newline between a function name and the opening '(' in the +# definition. +nl_func_def_paren = remove # ignore/add/remove/force + +# Overrides nl_func_def_paren for functions with no parameters. +nl_func_def_paren_empty = ignore # ignore/add/remove/force + +# Add or remove newline between a function name and the opening '(' in the +# call. +nl_func_call_paren = ignore # ignore/add/remove/force + +# Overrides nl_func_call_paren for functions with no parameters. +nl_func_call_paren_empty = ignore # ignore/add/remove/force + +# Add or remove newline after '(' in a function declaration. +nl_func_decl_start = remove # ignore/add/remove/force + +# Add or remove newline after '(' in a function definition. +nl_func_def_start = remove # ignore/add/remove/force + +# Overrides nl_func_decl_start when there is only one parameter. +nl_func_decl_start_single = ignore # ignore/add/remove/force + +# Overrides nl_func_def_start when there is only one parameter. +nl_func_def_start_single = ignore # ignore/add/remove/force + +# Whether to add a newline after '(' in a function declaration if '(' and ')' +# are in different lines. If false, nl_func_decl_start is used instead. +nl_func_decl_start_multi_line = false # true/false + +# Whether to add a newline after '(' in a function definition if '(' and ')' +# are in different lines. If false, nl_func_def_start is used instead. +nl_func_def_start_multi_line = false # true/false + +# Add or remove newline after each ',' in a function declaration. +nl_func_decl_args = ignore # ignore/add/remove/force + +# Add or remove newline after each ',' in a function definition. +nl_func_def_args = ignore # ignore/add/remove/force + +# Add or remove newline after each ',' in a function call. +#nl_func_call_args = ignore # ignore/add/remove/force ### not 0.69 + +# Whether to add a newline after each ',' in a function declaration if '(' +# and ')' are in different lines. If false, nl_func_decl_args is used instead. +nl_func_decl_args_multi_line = false # true/false + +# Whether to add a newline after each ',' in a function definition if '(' +# and ')' are in different lines. If false, nl_func_def_args is used instead. +nl_func_def_args_multi_line = false # true/false + +# Add or remove newline before the ')' in a function declaration. +nl_func_decl_end = remove # ignore/add/remove/force + +# Add or remove newline before the ')' in a function definition. +nl_func_def_end = remove # ignore/add/remove/force + +# Overrides nl_func_decl_end when there is only one parameter. +nl_func_decl_end_single = ignore # ignore/add/remove/force + +# Overrides nl_func_def_end when there is only one parameter. +nl_func_def_end_single = ignore # ignore/add/remove/force + +# Whether to add a newline before ')' in a function declaration if '(' and ')' +# are in different lines. If false, nl_func_decl_end is used instead. +nl_func_decl_end_multi_line = false # true/false + +# Whether to add a newline before ')' in a function definition if '(' and ')' +# are in different lines. If false, nl_func_def_end is used instead. +nl_func_def_end_multi_line = false # true/false + +# Add or remove newline between '()' in a function declaration. +nl_func_decl_empty = remove # ignore/add/remove/force + +# Add or remove newline between '()' in a function definition. +nl_func_def_empty = remove # ignore/add/remove/force + +# Add or remove newline between '()' in a function call. +nl_func_call_empty = remove # ignore/add/remove/force + +# Whether to add a newline after '(' in a function call, +# has preference over nl_func_call_start_multi_line. +nl_func_call_start = ignore # ignore/add/remove/force + +# Whether to add a newline before ')' in a function call. +#nl_func_call_end = ignore # ignore/add/remove/force ### not 0.69 + +# Whether to add a newline after '(' in a function call if '(' and ')' are in +# different lines. +nl_func_call_start_multi_line = false # true/false + +# Whether to add a newline after each ',' in a function call if '(' and ')' +# are in different lines. +nl_func_call_args_multi_line = false # true/false + +# Whether to add a newline before ')' in a function call if '(' and ')' are in +# different lines. +nl_func_call_end_multi_line = false # true/false + +# Whether to respect nl_func_call_XXX option incase of closure args. +#nl_func_call_args_multi_line_ignore_closures = false # true/false ### not 0.69 + +# Whether to add a newline after '<' of a template parameter list. +#nl_template_start = false # true/false ### not 0.69 + +# Whether to add a newline after each ',' in a template parameter list. +#nl_template_args = false # true/false ### not 0.69 + +# Whether to add a newline before '>' of a template parameter list. +#nl_template_end = false # true/false ### not 0.69 + +# (OC) Whether to put each Objective-C message parameter on a separate line. +# See nl_oc_msg_leave_one_liner. +nl_oc_msg_args = false # true/false + +# Add or remove newline between function signature and '{'. +nl_fdef_brace = ignore # ignore/add/remove/force + +# Add or remove newline between function signature and '{', +# if signature ends with ')'. Overrides nl_fdef_brace. +nl_fdef_brace_cond = ignore # ignore/add/remove/force + +# Add or remove newline between C++11 lambda signature and '{'. +nl_cpp_ldef_brace = ignore # ignore/add/remove/force + +# Add or remove newline between 'return' and the return expression. +nl_return_expr = ignore # ignore/add/remove/force + +# Whether to add a newline after semicolons, except in 'for' statements. +nl_after_semicolon = false # true/false + +# (Java) Add or remove newline between the ')' and '{{' of the double brace +# initializer. +nl_paren_dbrace_open = ignore # ignore/add/remove/force + +# Whether to add a newline after the type in an unnamed temporary +# direct-list-initialization. +nl_type_brace_init_lst = ignore # ignore/add/remove/force + +# Whether to add a newline after the open brace in an unnamed temporary +# direct-list-initialization. +nl_type_brace_init_lst_open = ignore # ignore/add/remove/force + +# Whether to add a newline before the close brace in an unnamed temporary +# direct-list-initialization. +nl_type_brace_init_lst_close = ignore # ignore/add/remove/force + +# Whether to add a newline after '{'. This also adds a newline before the +# matching '}'. +nl_after_brace_open = false # true/false + +# Whether to add a newline between the open brace and a trailing single-line +# comment. Requires nl_after_brace_open=true. +nl_after_brace_open_cmt = false # true/false + +# Whether to add a newline after a virtual brace open with a non-empty body. +# These occur in un-braced if/while/do/for statement bodies. +nl_after_vbrace_open = false # true/false + +# Whether to add a newline after a virtual brace open with an empty body. +# These occur in un-braced if/while/do/for statement bodies. +nl_after_vbrace_open_empty = false # true/false + +# Whether to add a newline after '}'. Does not apply if followed by a +# necessary ';'. +nl_after_brace_close = false # true/false + +# Whether to add a newline after a virtual brace close, +# as in 'if (foo) a++; return;'. +nl_after_vbrace_close = false # true/false + +# Add or remove newline between the close brace and identifier, +# as in 'struct { int a; } b;'. Affects enumerations, unions and +# structures. If set to ignore, uses nl_after_brace_close. +nl_brace_struct_var = ignore # ignore/add/remove/force + +# Whether to alter newlines in '#define' macros. +nl_define_macro = false # true/false + +# Whether to alter newlines between consecutive parenthesis closes. The number +# of closing parentheses in a line will depend on respective open parenthesis +# lines. +nl_squeeze_paren_close = false # true/false + +# Whether to remove blanks after '#ifxx' and '#elxx', or before '#elxx' and +# '#endif'. Does not affect top-level #ifdefs. +nl_squeeze_ifdef = false # true/false + +# Makes the nl_squeeze_ifdef option affect the top-level #ifdefs as well. +nl_squeeze_ifdef_top_level = false # true/false + +# Add or remove blank line before 'if'. +nl_before_if = add # ignore/add/remove/force + +# Add or remove blank line after 'if' statement. Add/Force work only if the +# next token is not a closing brace. +nl_after_if = add # ignore/add/remove/force + +# Add or remove blank line before 'for'. +nl_before_for = add # ignore/add/remove/force + +# Add or remove blank line after 'for' statement. +nl_after_for = add # ignore/add/remove/force + +# Add or remove blank line before 'while'. +nl_before_while = add # ignore/add/remove/force + +# Add or remove blank line after 'while' statement. +nl_after_while = add # ignore/add/remove/force + +# Add or remove blank line before 'switch'. +nl_before_switch = add # ignore/add/remove/force + +# Add or remove blank line after 'switch' statement. +nl_after_switch = add # ignore/add/remove/force + +# Add or remove blank line before 'synchronized'. +nl_before_synchronized = add # ignore/add/remove/force + +# Add or remove blank line after 'synchronized' statement. +nl_after_synchronized = add # ignore/add/remove/force + +# Add or remove blank line before 'do'. +nl_before_do = add # ignore/add/remove/force + +# Add or remove blank line after 'do/while' statement. +nl_after_do = add # ignore/add/remove/force + +# Whether to put a blank line before 'return' statements, unless after an open +# brace. +nl_before_return = false # true/false + +# Whether to put a blank line after 'return' statements, unless followed by a +# close brace. +nl_after_return = false # true/false + +# Whether to put a blank line before a member '.' or '->' operators. +#nl_before_member = ignore # ignore/add/remove/force ### not 0.69 + +# (Java) Whether to put a blank line after a member '.' or '->' operators. +#nl_after_member = ignore # ignore/add/remove/force ### not 0.69 + +# Whether to double-space commented-entries in 'struct'/'union'/'enum'. +nl_ds_struct_enum_cmt = false # true/false + +# Whether to force a newline before '}' of a 'struct'/'union'/'enum'. +# (Lower priority than eat_blanks_before_close_brace.) +nl_ds_struct_enum_close_brace = false # true/false + +# Add or remove newline before or after (depending on pos_class_colon) a class +# colon, as in 'class Foo : public Bar'. +nl_class_colon = ignore # ignore/add/remove/force + +# Add or remove newline around a class constructor colon. The exact position +# depends on nl_constr_init_args, pos_constr_colon and pos_constr_comma. +nl_constr_colon = ignore # ignore/add/remove/force + +# Whether to collapse a two-line namespace, like 'namespace foo\n{ decl; }' +# into a single line. If true, prevents other brace newline rules from turning +# such code into four lines. +nl_namespace_two_to_one_liner = false # true/false + +# Whether to remove a newline in simple unbraced if statements, turning them +# into one-liners, as in 'if(b)\n i++;' => 'if(b) i++;'. +nl_create_if_one_liner = false # true/false + +# Whether to remove a newline in simple unbraced for statements, turning them +# into one-liners, as in 'for (...)\n stmt;' => 'for (...) stmt;'. +nl_create_for_one_liner = false # true/false + +# Whether to remove a newline in simple unbraced while statements, turning +# them into one-liners, as in 'while (expr)\n stmt;' => 'while (expr) stmt;'. +nl_create_while_one_liner = false # true/false + +# Whether to collapse a function definition whose body (not counting braces) +# is only one line so that the entire definition (prototype, braces, body) is +# a single line. +nl_create_func_def_one_liner = false # true/false + +# Whether to collapse a function definition whose body (not counting braces) +# is only one line so that the entire definition (prototype, braces, body) is +# a single line. +#nl_create_list_one_liner = false # true/false ### not 0.69 + +# Whether to split one-line simple unbraced if statements into two lines by +# adding a newline, as in 'if(b) i++;'. +nl_split_if_one_liner = false # true/false + +# Whether to split one-line simple unbraced for statements into two lines by +# adding a newline, as in 'for (...) stmt;'. +nl_split_for_one_liner = false # true/false + +# Whether to split one-line simple unbraced while statements into two lines by +# adding a newline, as in 'while (expr) stmt;'. +nl_split_while_one_liner = false # true/false + +# +# Blank line options +# + +# The maximum number of consecutive newlines (3 = 2 blank lines). +nl_max = 0 # unsigned number + +# The maximum number of consecutive newlines in a function. +nl_max_blank_in_func = 0 # unsigned number + +# The number of newlines before a function prototype. +nl_before_func_body_proto = 0 # unsigned number + +# The number of newlines before a multi-line function definition. +nl_before_func_body_def = 0 # unsigned number + +# The number of newlines before a class constructor/destructor prototype. +nl_before_func_class_proto = 0 # unsigned number + +# The number of newlines before a class constructor/destructor definition. +nl_before_func_class_def = 0 # unsigned number + +# The number of newlines after a function prototype. +nl_after_func_proto = 0 # unsigned number + +# The number of newlines after a function prototype, if not followed by +# another function prototype. +nl_after_func_proto_group = 0 # unsigned number + +# The number of newlines after a class constructor/destructor prototype. +nl_after_func_class_proto = 0 # unsigned number + +# The number of newlines after a class constructor/destructor prototype, +# if not followed by another constructor/destructor prototype. +nl_after_func_class_proto_group = 0 # unsigned number + +# Whether one-line method definitions inside a class body should be treated +# as if they were prototypes for the purposes of adding newlines. +# +# Requires nl_class_leave_one_liners=true. Overrides nl_before_func_body_def +# and nl_before_func_class_def for one-liners. +nl_class_leave_one_liner_groups = false # true/false + +# The number of newlines after '}' of a multi-line function body. +nl_after_func_body = 0 # unsigned number + +# The number of newlines after '}' of a multi-line function body in a class +# declaration. Also affects class constructors/destructors. +# +# Overrides nl_after_func_body. +nl_after_func_body_class = 0 # unsigned number + +# The number of newlines after '}' of a single line function body. Also +# affects class constructors/destructors. +# +# Overrides nl_after_func_body and nl_after_func_body_class. +nl_after_func_body_one_liner = 0 # unsigned number + +# The number of blank lines after a block of variable definitions at the top +# of a function body. +# +# 0: No change (default). +nl_func_var_def_blk = 0 # unsigned number + +# The number of newlines before a block of typedefs. If nl_after_access_spec +# is non-zero, that option takes precedence. +# +# 0: No change (default). +nl_typedef_blk_start = 0 # unsigned number + +# The number of newlines after a block of typedefs. +# +# 0: No change (default). +nl_typedef_blk_end = 0 # unsigned number + +# The maximum number of consecutive newlines within a block of typedefs. +# +# 0: No change (default). +nl_typedef_blk_in = 0 # unsigned number + +# The number of newlines before a block of variable definitions not at the top +# of a function body. If nl_after_access_spec is non-zero, that option takes +# precedence. +# +# 0: No change (default). +nl_var_def_blk_start = 0 # unsigned number + +# The number of newlines after a block of variable definitions not at the top +# of a function body. +# +# 0: No change (default). +nl_var_def_blk_end = 0 # unsigned number + +# The maximum number of consecutive newlines within a block of variable +# definitions. +# +# 0: No change (default). +nl_var_def_blk_in = 0 # unsigned number + +# The minimum number of newlines before a multi-line comment. +# Doesn't apply if after a brace open or another multi-line comment. +nl_before_block_comment = 0 # unsigned number + +# The minimum number of newlines before a single-line C comment. +# Doesn't apply if after a brace open or other single-line C comments. +nl_before_c_comment = 0 # unsigned number + +# The minimum number of newlines before a CPP comment. +# Doesn't apply if after a brace open or other CPP comments. +nl_before_cpp_comment = 0 # unsigned number + +# Whether to force a newline after a multi-line comment. +nl_after_multiline_comment = false # true/false + +# Whether to force a newline after a label's colon. +nl_after_label_colon = false # true/false + +# The number of newlines after '}' or ';' of a struct/enum/union definition. +nl_after_struct = 0 # unsigned number + +# The number of newlines before a class definition. +nl_before_class = 0 # unsigned number + +# The number of newlines after '}' or ';' of a class definition. +nl_after_class = 0 # unsigned number + +# The number of newlines before a namespace. +#nl_before_namespace = 0 # unsigned number ### not 0.69 + +# The number of newlines after '{' of a namespace. This also adds newlines +# before the matching '}'. +# +# 0: Apply eat_blanks_after_open_brace or eat_blanks_before_close_brace if +# applicable, otherwise no change. +# +# Overrides eat_blanks_after_open_brace and eat_blanks_before_close_brace. +nl_inside_namespace = 0 # unsigned number + +# The number of newlines after '}' of a namespace. +#nl_after_namespace = 0 # unsigned number ### not 0.69 + +# The number of newlines before an access specifier label. This also includes +# the Qt-specific 'signals:' and 'slots:'. Will not change the newline count +# if after a brace open. +# +# 0: No change (default). +nl_before_access_spec = 0 # unsigned number + +# The number of newlines after an access specifier label. This also includes +# the Qt-specific 'signals:' and 'slots:'. Will not change the newline count +# if after a brace open. +# +# 0: No change (default). +# +# Overrides nl_typedef_blk_start and nl_var_def_blk_start. +nl_after_access_spec = 0 # unsigned number + +# The number of newlines between a function definition and the function +# comment, as in '// comment\n void foo() {...}'. +# +# 0: No change (default). +nl_comment_func_def = 0 # unsigned number + +# The number of newlines after a try-catch-finally block that isn't followed +# by a brace close. +# +# 0: No change (default). +nl_after_try_catch_finally = 0 # unsigned number + +# (C#) The number of newlines before and after a property, indexer or event +# declaration. +# +# 0: No change (default). +nl_around_cs_property = 0 # unsigned number + +# (C#) The number of newlines between the get/set/add/remove handlers. +# +# 0: No change (default). +nl_between_get_set = 0 # unsigned number + +# (C#) Add or remove newline between property and the '{'. +nl_property_brace = ignore # ignore/add/remove/force + +# Whether to remove blank lines after '{'. +eat_blanks_after_open_brace = false # true/false + +# Whether to remove blank lines before '}'. +eat_blanks_before_close_brace = false # true/false + +# How aggressively to remove extra newlines not in preprocessor. +# +# 0: No change (default) +# 1: Remove most newlines not handled by other config +# 2: Remove all newlines and reformat completely by config +nl_remove_extra_newlines = 0 # unsigned number + +# (Java) Add or remove newline after an annotation statement. Only affects +# annotations that are after a newline. +nl_after_annotation = ignore # ignore/add/remove/force + +# (Java) Add or remove newline between two annotations. +nl_between_annotation = ignore # ignore/add/remove/force + +# The number of newlines before a whole-file #ifdef. +# +# 0: No change (default). +#nl_before_whole_file_ifdef = 0 # unsigned number ### not 0.69 + +# The number of newlines after a whole-file #ifdef. +# +# 0: No change (default). +#nl_after_whole_file_ifdef = 0 # unsigned number ### not 0.69 + +# The number of newlines before a whole-file #endif. +# +# 0: No change (default). +#nl_before_whole_file_endif = 0 # unsigned number ### not 0.69 + +# The number of newlines after a whole-file #endif. +# +# 0: No change (default). +#nl_after_whole_file_endif = 0 # unsigned number ### not 0.69 + +# +# Positioning options +# + +# The position of arithmetic operators in wrapped expressions. +pos_arith = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of assignment in wrapped expressions. Do not affect '=' +# followed by '{'. +pos_assign = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of Boolean operators in wrapped expressions. +pos_bool = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of comparison operators in wrapped expressions. +pos_compare = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of conditional operators, as in the '?' and ':' of +# 'expr ? stmt : stmt', in wrapped expressions. +pos_conditional = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in wrapped expressions. +pos_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in enum entries. +pos_enum_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in the base class list if there is more than one +# line. Affects nl_class_init_args. +pos_class_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in the constructor initialization list. +# Related to nl_constr_colon, nl_constr_init_args and pos_constr_colon. +pos_constr_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of trailing/leading class colon, between class and base class +# list. Affects nl_class_colon. +pos_class_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of colons between constructor and member initialization. +# Related to nl_constr_colon, nl_constr_init_args and pos_constr_comma. +pos_constr_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# +# Line splitting options +# + +# Try to limit code width to N columns. +code_width = 0 # unsigned number + +# Whether to fully split long 'for' statements at semi-colons. +ls_for_split_full = false # true/false + +# Whether to fully split long function prototypes/calls at commas. +# The option ls_code_width has priority over the option ls_func_split_full. +ls_func_split_full = false # true/false + +# Whether to split lines as close to code_width as possible and ignore some +# groupings. +# The option ls_code_width has priority over the option ls_func_split_full. +ls_code_width = false # true/false + +# +# Code alignment options (not left column spaces/tabs) +# + +# Whether to keep non-indenting tabs. +align_keep_tabs = false # true/false + +# Whether to use tabs for aligning. +align_with_tabs = false # true/false + +# Whether to bump out to the next tab when aligning. +align_on_tabstop = false # true/false + +# Whether to right-align numbers. +align_number_right = false # true/false + +# Whether to keep whitespace not required for alignment. +align_keep_extra_space = false # true/false + +# Whether to align variable definitions in prototypes and functions. +align_func_params = false # true/false + +# The span for aligning parameter definitions in function on parameter name. +# +# 0: Don't align (default). +align_func_params_span = 0 # unsigned number + +# The threshold for aligning function parameter definitions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_func_params_thresh = 0 # number + +# The gap for aligning function parameter definitions. +align_func_params_gap = 0 # unsigned number + +# The span for aligning constructor value. +# +# 0: Don't align (default). +align_constr_value_span = 0 # unsigned number + +# The threshold for aligning constructor value. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_constr_value_thresh = 0 # number + +# The gap for aligning constructor value. +align_constr_value_gap = 0 # unsigned number + +# Whether to align parameters in single-line functions that have the same +# name. The function names must already be aligned with each other. +align_same_func_call_params = false # true/false + +# The span for aligning function-call parameters for single line functions. +# +# 0: Don't align (default). +align_same_func_call_params_span = 0 # unsigned number + +# The threshold for aligning function-call parameters for single line +# functions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_same_func_call_params_thresh = 0 # number + +# The span for aligning variable definitions. +# +# 0: Don't align (default). +align_var_def_span = 0 # unsigned number + +# How to consider (or treat) the '*' in the alignment of variable definitions. +# +# 0: Part of the type 'void * foo;' (default) +# 1: Part of the variable 'void *foo;' +# 2: Dangling 'void *foo;' +# Dangling: the '*' will not be taken into account when aligning. +align_var_def_star_style = 0 # unsigned number + +# How to consider (or treat) the '&' in the alignment of variable definitions. +# +# 0: Part of the type 'long & foo;' (default) +# 1: Part of the variable 'long &foo;' +# 2: Dangling 'long &foo;' +# Dangling: the '&' will not be taken into account when aligning. +align_var_def_amp_style = 0 # unsigned number + +# The threshold for aligning variable definitions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_var_def_thresh = 0 # number + +# The gap for aligning variable definitions. +align_var_def_gap = 0 # unsigned number + +# Whether to align the colon in struct bit fields. +align_var_def_colon = false # true/false + +# The gap for aligning the colon in struct bit fields. +align_var_def_colon_gap = 0 # unsigned number + +# Whether to align any attribute after the variable name. +align_var_def_attribute = false # true/false + +# Whether to align inline struct/enum/union variable definitions. +align_var_def_inline = false # true/false + +# The span for aligning on '=' in assignments. +# +# 0: Don't align (default). +align_assign_span = 0 # unsigned number + +# The span for aligning on '=' in function prototype modifier. +# +# 0: Don't align (default). +align_assign_func_proto_span = 0 # unsigned number + +# The threshold for aligning on '=' in assignments. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_assign_thresh = 0 # number + +# How to apply align_assign_span to function declaration "assignments", i.e. +# 'virtual void foo() = 0' or '~foo() = {default|delete}'. +# +# 0: Align with other assignments (default) +# 1: Align with each other, ignoring regular assignments +# 2: Don't align +align_assign_decl_func = 0 # unsigned number + +# The span for aligning on '=' in enums. +# +# 0: Don't align (default). +align_enum_equ_span = 0 # unsigned number + +# The threshold for aligning on '=' in enums. +# Use a negative number for absolute thresholds. +# +# 0: no limit (default). +align_enum_equ_thresh = 0 # number + +# The span for aligning class member definitions. +# +# 0: Don't align (default). +align_var_class_span = 0 # unsigned number + +# The threshold for aligning class member definitions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_var_class_thresh = 0 # number + +# The gap for aligning class member definitions. +align_var_class_gap = 0 # unsigned number + +# The span for aligning struct/union member definitions. +# +# 0: Don't align (default). +align_var_struct_span = 0 # unsigned number + +# The threshold for aligning struct/union member definitions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_var_struct_thresh = 0 # number + +# The gap for aligning struct/union member definitions. +align_var_struct_gap = 0 # unsigned number + +# The span for aligning struct initializer values. +# +# 0: Don't align (default). +align_struct_init_span = 0 # unsigned number + +# The span for aligning single-line typedefs. +# +# 0: Don't align (default). +align_typedef_span = 0 # unsigned number + +# The minimum space between the type and the synonym of a typedef. +align_typedef_gap = 0 # unsigned number + +# How to align typedef'd functions with other typedefs. +# +# 0: Don't mix them at all (default) +# 1: Align the open parenthesis with the types +# 2: Align the function type name with the other type names +align_typedef_func = 0 # unsigned number + +# How to consider (or treat) the '*' in the alignment of typedefs. +# +# 0: Part of the typedef type, 'typedef int * pint;' (default) +# 1: Part of type name: 'typedef int *pint;' +# 2: Dangling: 'typedef int *pint;' +# Dangling: the '*' will not be taken into account when aligning. +align_typedef_star_style = 0 # unsigned number + +# How to consider (or treat) the '&' in the alignment of typedefs. +# +# 0: Part of the typedef type, 'typedef int & intref;' (default) +# 1: Part of type name: 'typedef int &intref;' +# 2: Dangling: 'typedef int &intref;' +# Dangling: the '&' will not be taken into account when aligning. +align_typedef_amp_style = 0 # unsigned number + +# The span for aligning comments that end lines. +# +# 0: Don't align (default). +align_right_cmt_span = 0 # unsigned number + +# Minimum number of columns between preceding text and a trailing comment in +# order for the comment to qualify for being aligned. Must be non-zero to have +# an effect. +align_right_cmt_gap = 0 # unsigned number + +# If aligning comments, whether to mix with comments after '}' and #endif with +# less than three spaces before the comment. +align_right_cmt_mix = false # true/false + +# Whether to only align trailing comments that are at the same brace level. +align_right_cmt_same_level = false # true/false + +# Minimum column at which to align trailing comments. Comments which are +# aligned beyond this column, but which can be aligned in a lesser column, +# may be "pulled in". +# +# 0: Ignore (default). +align_right_cmt_at_col = 0 # unsigned number + +# The span for aligning function prototypes. +# +# 0: Don't align (default). +align_func_proto_span = 0 # unsigned number + +# The threshold for aligning function prototypes. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_func_proto_thresh = 0 # number + +# Minimum gap between the return type and the function name. +align_func_proto_gap = 0 # unsigned number + +# Whether to align function prototypes on the 'operator' keyword instead of +# what follows. +align_on_operator = false # true/false + +# Whether to mix aligning prototype and variable declarations. If true, +# align_var_def_XXX options are used instead of align_func_proto_XXX options. +align_mix_var_proto = false # true/false + +# Whether to align single-line functions with function prototypes. +# Uses align_func_proto_span. +align_single_line_func = false # true/false + +# Whether to align the open brace of single-line functions. +# Requires align_single_line_func=true. Uses align_func_proto_span. +align_single_line_brace = false # true/false + +# Gap for align_single_line_brace. +align_single_line_brace_gap = 0 # unsigned number + +# (OC) The span for aligning Objective-C message specifications. +# +# 0: Don't align (default). +align_oc_msg_spec_span = 0 # unsigned number + +# Whether to align macros wrapped with a backslash and a newline. This will +# not work right if the macro contains a multi-line comment. +align_nl_cont = false # true/false + +# Whether to align macro functions and variables together. +align_pp_define_together = false # true/false + +# The span for aligning on '#define' bodies. +# +# =0: Don't align (default) +# >0: Number of lines (including comments) between blocks +align_pp_define_span = 0 # unsigned number + +# The minimum space between label and value of a preprocessor define. +align_pp_define_gap = 0 # unsigned number + +# Whether to align lines that start with '<<' with previous '<<'. +# +# Default: true +align_left_shift = true # true/false + +# Whether to align text after 'asm volatile ()' colons. +align_asm_colon = false # true/false + +# (OC) Span for aligning parameters in an Objective-C message call +# on the ':'. +# +# 0: Don't align. +align_oc_msg_colon_span = 0 # unsigned number + +# (OC) Whether to always align with the first parameter, even if it is too +# short. +align_oc_msg_colon_first = false # true/false + +# (OC) Whether to align parameters in an Objective-C '+' or '-' declaration +# on the ':'. +align_oc_decl_colon = false # true/false + +# (OC) Whether to not align parameters in an Objectve-C message call if first +# colon is not on next line of the message call (the same way Xcode does +# aligment) +#align_oc_msg_colon_xcode_like = false # true/false ### not 0.69 + +# +# Comment modification options +# + +# Try to wrap comments at N columns. +cmt_width = 0 # unsigned number + +# How to reflow comments. +# +# 0: No reflowing (apart from the line wrapping due to cmt_width) (default) +# 1: No touching at all +# 2: Full reflow +cmt_reflow_mode = 0 # unsigned number + +# Whether to convert all tabs to spaces in comments. If false, tabs in +# comments are left alone, unless used for indenting. +cmt_convert_tab_to_spaces = false # true/false + +# Whether to apply changes to multi-line comments, including cmt_width, +# keyword substitution and leading chars. +# +# Default: true +cmt_indent_multi = true # true/false + +# Whether to group c-comments that look like they are in a block. +cmt_c_group = false # true/false + +# Whether to put an empty '/*' on the first line of the combined c-comment. +cmt_c_nl_start = false # true/false + +# Whether to add a newline before the closing '*/' of the combined c-comment. +cmt_c_nl_end = false # true/false + +# Whether to change cpp-comments into c-comments. +cmt_cpp_to_c = false # true/false + +# Whether to group cpp-comments that look like they are in a block. Only +# meaningful if cmt_cpp_to_c=true. +cmt_cpp_group = false # true/false + +# Whether to put an empty '/*' on the first line of the combined cpp-comment +# when converting to a c-comment. +# +# Requires cmt_cpp_to_c=true and cmt_cpp_group=true. +cmt_cpp_nl_start = false # true/false + +# Whether to add a newline before the closing '*/' of the combined cpp-comment +# when converting to a c-comment. +# +# Requires cmt_cpp_to_c=true and cmt_cpp_group=true. +cmt_cpp_nl_end = false # true/false + +# Whether to put a star on subsequent comment lines. +cmt_star_cont = false # true/false + +# The number of spaces to insert at the start of subsequent comment lines. +cmt_sp_before_star_cont = 0 # unsigned number + +# The number of spaces to insert after the star on subsequent comment lines. +cmt_sp_after_star_cont = 0 # unsigned number + +# For multi-line comments with a '*' lead, remove leading spaces if the first +# and last lines of the comment are the same length. +# +# Default: true +cmt_multi_check_last = true # true/false + +# For multi-line comments with a '*' lead, remove leading spaces if the first +# and last lines of the comment are the same length AND if the length is +# bigger as the first_len minimum. +# +# Default: 4 +cmt_multi_first_len_minimum = 4 # unsigned number + +# Path to a file that contains text to insert at the beginning of a file if +# the file doesn't start with a C/C++ comment. If the inserted text contains +# '$(filename)', that will be replaced with the current file's name. +cmt_insert_file_header = "" # string + +# Path to a file that contains text to insert at the end of a file if the +# file doesn't end with a C/C++ comment. If the inserted text contains +# '$(filename)', that will be replaced with the current file's name. +cmt_insert_file_footer = "" # string + +# Path to a file that contains text to insert before a function definition if +# the function isn't preceded by a C/C++ comment. If the inserted text +# contains '$(function)', '$(javaparam)' or '$(fclass)', these will be +# replaced with, respectively, the name of the function, the javadoc '@param' +# and '@return' stuff, or the name of the class to which the member function +# belongs. +cmt_insert_func_header = "" # string + +# Path to a file that contains text to insert before a class if the class +# isn't preceded by a C/C++ comment. If the inserted text contains '$(class)', +# that will be replaced with the class name. +cmt_insert_class_header = "" # string + +# Path to a file that contains text to insert before an Objective-C message +# specification, if the method isn't preceded by a C/C++ comment. If the +# inserted text contains '$(message)' or '$(javaparam)', these will be +# replaced with, respectively, the name of the function, or the javadoc +# '@param' and '@return' stuff. +cmt_insert_oc_msg_header = "" # string + +# Whether a comment should be inserted if a preprocessor is encountered when +# stepping backwards from a function name. +# +# Applies to cmt_insert_oc_msg_header, cmt_insert_func_header and +# cmt_insert_class_header. +cmt_insert_before_preproc = false # true/false + +# Whether a comment should be inserted if a function is declared inline to a +# class definition. +# +# Applies to cmt_insert_func_header. +# +# Default: true +cmt_insert_before_inlines = true # true/false + +# Whether a comment should be inserted if the function is a class constructor +# or destructor. +# +# Applies to cmt_insert_func_header. +cmt_insert_before_ctor_dtor = false # true/false + +# +# Code modifying options (non-whitespace) +# + +# Add or remove braces on a single-line 'do' statement. +mod_full_brace_do = remove # ignore/add/remove/force + +# Add or remove braces on a single-line 'for' statement. +mod_full_brace_for = remove # ignore/add/remove/force + +# (Pawn) Add or remove braces on a single-line function definition. +mod_full_brace_function = ignore # ignore/add/remove/force + +# Add or remove braces on a single-line 'if' statement. Braces will not be +# removed if the braced statement contains an 'else'. +mod_full_brace_if = add # ignore/add/remove/force + +# Whether to enforce that all blocks of an 'if'/'else if'/'else' chain either +# have, or do not have, braces. If true, braces will be added if any block +# needs braces, and will only be removed if they can be removed from all +# blocks. +# +# Overrides mod_full_brace_if. +mod_full_brace_if_chain = false # true/false + +# Whether to add braces to all blocks of an 'if'/'else if'/'else' chain. +# If true, mod_full_brace_if_chain will only remove braces from an 'if' that +# does not have an 'else if' or 'else'. +mod_full_brace_if_chain_only = true # true/false + +# Add or remove braces on single-line 'while' statement. +mod_full_brace_while = remove # ignore/add/remove/force + +# Add or remove braces on single-line 'using ()' statement. +mod_full_brace_using = remove # ignore/add/remove/force + +# Don't remove braces around statements that span N newlines +mod_full_brace_nl = 0 # unsigned number + +# Whether to prevent removal of braces from 'if'/'for'/'while'/etc. blocks +# which span multiple lines. +# +# Affects: +# mod_full_brace_for +# mod_full_brace_if +# mod_full_brace_if_chain +# mod_full_brace_if_chain_only +# mod_full_brace_while +# mod_full_brace_using +# +# Does not affect: +# mod_full_brace_do +# mod_full_brace_function +mod_full_brace_nl_block_rem_mlcond = false # true/false + +# Add or remove unnecessary parenthesis on 'return' statement. +mod_paren_on_return = add # ignore/add/remove/force + +# (Pawn) Whether to change optional semicolons to real semicolons. +mod_pawn_semicolon = false # true/false + +# Whether to fully parenthesize Boolean expressions in 'while' and 'if' +# statement, as in 'if (a && b > c)' => 'if (a && (b > c))'. +mod_full_paren_if_bool = false # true/false + +# Whether to remove superfluous semicolons. +mod_remove_extra_semicolon = false # true/false + +# If a function body exceeds the specified number of newlines and doesn't have +# a comment after the close brace, a comment will be added. +mod_add_long_function_closebrace_comment = 0 # unsigned number + +# If a namespace body exceeds the specified number of newlines and doesn't +# have a comment after the close brace, a comment will be added. +mod_add_long_namespace_closebrace_comment = 0 # unsigned number + +# If a class body exceeds the specified number of newlines and doesn't have a +# comment after the close brace, a comment will be added. +mod_add_long_class_closebrace_comment = 0 # unsigned number + +# If a switch body exceeds the specified number of newlines and doesn't have a +# comment after the close brace, a comment will be added. +mod_add_long_switch_closebrace_comment = 0 # unsigned number + +# If an #ifdef body exceeds the specified number of newlines and doesn't have +# a comment after the #endif, a comment will be added. +mod_add_long_ifdef_endif_comment = 0 # unsigned number + +# If an #ifdef or #else body exceeds the specified number of newlines and +# doesn't have a comment after the #else, a comment will be added. +mod_add_long_ifdef_else_comment = 0 # unsigned number + +# Whether to take care of the case by the mod_sort_xx options. +#mod_sort_case_sensitive = false # true/false ### not 0.69 + +# Whether to sort consecutive single-line 'import' statements. +mod_sort_import = false # true/false + +# (C#) Whether to sort consecutive single-line 'using' statements. +mod_sort_using = false # true/false + +# Whether to sort consecutive single-line '#include' statements (C/C++) and +# '#import' statements (Objective-C). Be aware that this has the potential to +# break your code if your includes/imports have ordering dependencies. +mod_sort_include = false # true/false + +# Whether to prioritize '#include' and '#import' statements that contain +# filename without extension when sorting is enabled. +#mod_sort_incl_import_prioritize_filename = false # true/false ### not 0.69 + +# Whether to prioritize '#include' and '#import' statements that does not +# contain extensions when sorting is enabled. +#mod_sort_incl_import_prioritize_extensionless = false # true/false ### not 0.69 + +# Whether to prioritize '#include' and '#import' statements that contain +# angle over quotes when sorting is enabled. +#mod_sort_incl_import_prioritize_angle_over_quotes = false # true/false ### not 0.69 + +# Whether to ignore file extension in '#include' and '#import' statements +# for sorting comparison. +#mod_sort_incl_import_ignore_extension = false # true/false ### not 0.69 + +# Whether to group '#include' and '#import' statements when sorting is enabled. +#mod_sort_incl_import_grouping_enabled = false # true/false ### not 0.69 + +# Whether to move a 'break' that appears after a fully braced 'case' before +# the close brace, as in 'case X: { ... } break;' => 'case X: { ... break; }'. +mod_move_case_break = false # true/false + +# Add or remove braces around a fully braced case statement. Will only remove +# braces if there are no variable declarations in the block. +mod_case_brace = ignore # ignore/add/remove/force + +# Whether to remove a void 'return;' that appears as the last statement in a +# function. +mod_remove_empty_return = false # true/false + +# Add or remove the comma after the last value of an enumeration. +mod_enum_last_comma = ignore # ignore/add/remove/force + +# (OC) Whether to organize the properties. If true, properties will be +# rearranged according to the mod_sort_oc_property_*_weight factors. +mod_sort_oc_properties = false # true/false + +# (OC) Weight of a class property modifier. +mod_sort_oc_property_class_weight = 0 # number + +# (OC) Weight of 'atomic' and 'nonatomic'. +mod_sort_oc_property_thread_safe_weight = 0 # number + +# (OC) Weight of 'readwrite' when organizing properties. +mod_sort_oc_property_readwrite_weight = 0 # number + +# (OC) Weight of a reference type specifier ('retain', 'copy', 'assign', +# 'weak', 'strong') when organizing properties. +mod_sort_oc_property_reference_weight = 0 # number + +# (OC) Weight of getter type ('getter=') when organizing properties. +mod_sort_oc_property_getter_weight = 0 # number + +# (OC) Weight of setter type ('setter=') when organizing properties. +mod_sort_oc_property_setter_weight = 0 # number + +# (OC) Weight of nullability type ('nullable', 'nonnull', 'null_unspecified', +# 'null_resettable') when organizing properties. +mod_sort_oc_property_nullability_weight = 0 # number + +# +# Preprocessor options +# + +# Add or remove indentation of preprocessor directives inside #if blocks +# at brace level 0 (file-level). +pp_indent = ignore # ignore/add/remove/force + +# Whether to indent #if/#else/#endif at the brace level. If false, these are +# indented from column 1. +pp_indent_at_level = false # true/false + +# Specifies the number of columns to indent preprocessors per level +# at brace level 0 (file-level). If pp_indent_at_level=false, also specifies +# the number of columns to indent preprocessors per level +# at brace level > 0 (function-level). +# +# Default: 1 +pp_indent_count = 1 # unsigned number + +# Add or remove space after # based on pp_level of #if blocks. +pp_space = ignore # ignore/add/remove/force + +# Sets the number of spaces per level added with pp_space. +pp_space_count = 0 # unsigned number + +# The indent for '#region' and '#endregion' in C# and '#pragma region' in +# C/C++. Negative values decrease indent down to the first column. +pp_indent_region = 0 # number + +# Whether to indent the code between #region and #endregion. +pp_region_indent_code = false # true/false + +# If pp_indent_at_level=true, sets the indent for #if, #else and #endif when +# not at file-level. Negative values decrease indent down to the first column. +# +# =0: Indent preprocessors using output_tab_size +# >0: Column at which all preprocessors will be indented +pp_indent_if = 0 # number + +# Whether to indent the code between #if, #else and #endif. +pp_if_indent_code = false # true/false + +# Whether to indent '#define' at the brace level. If false, these are +# indented from column 1. +pp_define_at_level = false # true/false + +# Whether to ignore the '#define' body while formatting. +pp_ignore_define_body = false # true/false + +# Whether to indent case statements between #if, #else, and #endif. +# Only applies to the indent of the preprocesser that the case statements +# directly inside of. +# +# Default: true +pp_indent_case = true # true/false + +# Whether to indent whole function definitions between #if, #else, and #endif. +# Only applies to the indent of the preprocesser that the function definition +# is directly inside of. +# +# Default: true +pp_indent_func_def = true # true/false + +# Whether to indent extern C blocks between #if, #else, and #endif. +# Only applies to the indent of the preprocesser that the extern block is +# directly inside of. +# +# Default: true +pp_indent_extern = true # true/false + +# Whether to indent braces directly inside #if, #else, and #endif. +# Only applies to the indent of the preprocesser that the braces are directly +# inside of. +# +# Default: true +pp_indent_brace = true # true/false + +# +# Sort includes options +# + +# The regex for include category with priority 0. +include_category_0 = "" # string + +# The regex for include category with priority 1. +include_category_1 = "" # string + +# The regex for include category with priority 2. +include_category_2 = "" # string + +# +# Use or Do not Use options +# + +# true: indent_func_call_param will be used (default) +# false: indent_func_call_param will NOT be used +# +# Default: true +use_indent_func_call_param = true # true/false + +# The value of the indentation for a continuation line is calculated +# differently if the statement is: +# - a declaration: your case with QString fileName ... +# - an assignment: your case with pSettings = new QSettings( ... +# +# At the second case the indentation value might be used twice: +# - at the assignment +# - at the function call (if present) +# +# To prevent the double use of the indentation value, use this option with the +# value 'true'. +# +# true: indent_continue will be used only once +# false: indent_continue will be used every time (default) +use_indent_continue_only_once = false # true/false + +# The value might be used twice: +# - at the assignment +# - at the opening brace +# +# To prevent the double use of the indentation value, use this option with the +# value 'true'. +# +# true: indentation will be used only once +# false: indentation will be used every time (default) +indent_cpp_lambda_only_once = false # true/false + +# Whether sp_after_angle takes precedence over sp_inside_fparen. This was the +# historic behavior, but is probably not the desired behavior, so this is off +# by default. +#use_sp_after_angle_always = false # true/false ### not 0.69 + +# Whether to apply special formatting for Qt SIGNAL/SLOT macros. Essentially, +# this tries to format these so that they match Qt's normalized form (i.e. the +# result of QMetaObject::normalizedSignature), which can slightly improve the +# performance of the QObject::connect call, rather than how they would +# otherwise be formatted. +# +# See options_for_QT.cpp for details. +# +# Default: true +use_options_overriding_for_qt_macros = true # true/false + +# If true: the form feed character is removed from the list +# of whitespace characters. +# See https://en.cppreference.com/w/cpp/string/byte/isspace +#use_form_feed_no_more_as_whitespace_character = false # true/false ### not 0.69 + +# +# Warn levels - 1: error, 2: warning (default), 3: note +# + +# (C#) Warning is given if doing tab-to-\t replacement and we have found one +# in a C# verbatim string literal. +# +# Default: 2 +warn_level_tabs_found_in_verbatim_string_literals = 2 # unsigned number + +# Limit the number of loops. +# Used by uncrustify.cpp to exit from infinite loop. +# 0: no limit. +#debug_max_number_of_loops = 0 # number ### not 0.69 + +# Set the number of the line to protocol; +# Used in the function prot_the_line if the 2. parameter is zero. +# 0: nothing protocol. +#debug_line_number_to_protocol = 0 # number ### not 0.69 + +# Meaning of the settings: +# Ignore - do not do any changes +# Add - makes sure there is 1 or more space/brace/newline/etc +# Force - makes sure there is exactly 1 space/brace/newline/etc, +# behaves like Add in some contexts +# Remove - removes space/brace/newline/etc +# +# +# - Token(s) can be treated as specific type(s) with the 'set' option: +# `set tokenType tokenString [tokenString...]` +# +# Example: +# `set BOOL __AND__ __OR__` +# +# tokenTypes are defined in src/token_enum.h, use them without the +# 'CT_' prefix: 'CT_BOOL' => 'BOOL' +# +# +# - Token(s) can be treated as type(s) with the 'type' option. +# `type tokenString [tokenString...]` +# +# Example: +# `type int c_uint_8 Rectangle` +# +# This can also be achieved with `set TYPE int c_uint_8 Rectangle` +# +# +# To embed whitespace in tokenStrings use the '\' escape character, or quote +# the tokenStrings. These quotes are supported: "'` +# +# +# - Support for the auto detection of languages through the file ending can be +# added using the 'file_ext' command. +# `file_ext langType langString [langString..]` +# +# Example: +# `file_ext CPP .ch .cxx .cpp.in` +# +# langTypes are defined in uncrusify_types.h in the lang_flag_e enum, use +# them without the 'LANG_' prefix: 'LANG_CPP' => 'CPP' +# +# +# - Custom macro-based indentation can be set up using 'macro-open', +# 'macro-else' and 'macro-close'. +# `(macro-open | macro-else | macro-close) tokenString` +# +# Example: +# `macro-open BEGIN_TEMPLATE_MESSAGE_MAP` +# `macro-open BEGIN_MESSAGE_MAP` +# `macro-close END_MESSAGE_MAP` +# +# +# option(s) with 'not default' value: 0 +# diff --git a/flashloaders/linker.ld b/flashloaders/linker.ld index 4d06433ea..7267fe10f 100644 --- a/flashloaders/linker.ld +++ b/flashloaders/linker.ld @@ -1,9 +1,9 @@ -/*. Entry Point *./ +/* Entry Point */ ENTRY( copy ) -/*. Specify the memory areas .*/ +/* Specify the memory areas */ MEMORY { RAM ( xrw) : ORIGIN = 0x20000000 , LENGTH = 64K -} \ No newline at end of file +} diff --git a/src/backend.h b/inc/backend.h similarity index 94% rename from src/backend.h rename to inc/backend.h index 42d12d4ac..f852da05d 100644 --- a/src/backend.h +++ b/inc/backend.h @@ -28,7 +28,7 @@ int (*current_mode) (stlink_t * stl); int (*force_debug) (stlink_t *sl); int32_t (*target_voltage) (stlink_t *sl); - int (*set_swdclk) (stlink_t * stl, uint16_t divisor); + int (*set_swdclk) (stlink_t * stl, uint16_t divisor); } stlink_backend_t; -#endif /* STLINK_BACKEND_H_ */ +#endif // STLINK_BACKEND_H_ diff --git a/inc/stlink.h b/inc/stlink.h index c87c6b173..140d68866 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -18,11 +18,11 @@ extern "C" { #endif -#define STLINK_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#define STLINK_ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) /* Max data transfer size */ // 6kB = max mem32_read block, 8kB sram -//#define Q_BUF_LEN 96 +// #define Q_BUF_LEN 96 #define Q_BUF_LEN (1024 * 100) // STLINK_DEBUG_RESETSYS, etc: @@ -103,16 +103,16 @@ enum target_state { #define S_RESET_ST (1 << 25) /* Map the relevant features, quirks and workaround for specific firmware version of stlink */ -#define STLINK_F_HAS_TRACE (1<<0) -#define STLINK_F_HAS_SWD_SET_FREQ (1<<1) -#define STLINK_F_HAS_JTAG_SET_FREQ (1<<2) -#define STLINK_F_HAS_MEM_16BIT (1<<3) -#define STLINK_F_HAS_GETLASTRWSTATUS2 (1<<4) -#define STLINK_F_HAS_DAP_REG (1<<5) -#define STLINK_F_QUIRK_JTAG_DP_READ (1<<6) -#define STLINK_F_HAS_AP_INIT (1<<7) -#define STLINK_F_HAS_DPBANKSEL (1<<8) -#define STLINK_F_HAS_RW8_512BYTES (1<<9) +#define STLINK_F_HAS_TRACE (1 << 0) +#define STLINK_F_HAS_SWD_SET_FREQ (1 << 1) +#define STLINK_F_HAS_JTAG_SET_FREQ (1 << 2) +#define STLINK_F_HAS_MEM_16BIT (1 << 3) +#define STLINK_F_HAS_GETLASTRWSTATUS2 (1 << 4) +#define STLINK_F_HAS_DAP_REG (1 << 5) +#define STLINK_F_QUIRK_JTAG_DP_READ (1 << 6) +#define STLINK_F_HAS_AP_INIT (1 << 7) +#define STLINK_F_HAS_DPBANKSEL (1 << 8) +#define STLINK_F_HAS_RW8_512BYTES (1 << 9) #define C_BUF_LEN 32 @@ -146,8 +146,8 @@ struct stlink_reg { typedef uint32_t stm32_addr_t; typedef struct flash_loader { -stm32_addr_t loader_addr; // loader sram addr -stm32_addr_t buf_addr; // buffer sram address + stm32_addr_t loader_addr; // loader sram addr + stm32_addr_t buf_addr; // buffer sram address } flash_loader_t; typedef struct _cortex_m3_cpuid_ { @@ -183,16 +183,16 @@ enum transport_type { }; typedef struct _stlink stlink_t; - + #include struct _stlink { struct _stlink_backend *backend; void *backend_data; - // Room for the command header + // room for the command header unsigned char c_buf[C_BUF_LEN]; - // Data transferred from or to device + // data transferred from or to device unsigned char q_buf[Q_BUF_LEN]; int q_len; @@ -205,28 +205,29 @@ struct _stlink { char serial[STLINK_SERIAL_MAX_SIZE]; int serial_size; - int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR + int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx bool has_dual_bank; - stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() - size_t flash_size; // calculated by stlink_load_device_params() - size_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() + stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() + size_t flash_size; // calculated by stlink_load_device_params() + size_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() /* sram settings */ - stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() - size_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() + stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() + size_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() - /* option settings */ + /* option settings */ stm32_addr_t option_base; size_t option_size; // bootloader - // sys_base and sys_size are not used by the tools, but are only there to download the bootloader code (see tests/sg.c) - stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() - size_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() + // sys_base and sys_size are not used by the tools, but are only there to download the bootloader code + // (see tests/sg.c) + stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() + size_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() struct stlink_version_ version; }; @@ -306,4 +307,4 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr } #endif -#endif /* STLINK_H */ +#endif // STLINK_H diff --git a/inc/stm32.h b/inc/stm32.h index c71718653..36c14ee23 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -1,17 +1,17 @@ /* - * File: stm32.h + * File: stm32.h * - * STM32 specific defines + * STM32-specific defines */ #ifndef STM32_H #define STM32_H -// cortex core ids +/* Cortex core ids */ #define STM32VL_CORE_ID 0x1ba01477 #define STM32F7_CORE_ID 0x5ba02477 -// Constant STM32 memory map figures +/* Constant STM32 memory map figures */ #define STM32_FLASH_BASE ((uint32_t)0x08000000) #define STM32_SRAM_BASE ((uint32_t)0x20000000) #define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) @@ -21,4 +21,4 @@ #define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) -#endif /* STM32_H */ +#endif // STM32_H diff --git a/inc/version.h.in b/inc/version.h.in index 4ce2a5cac..66159e0e5 100644 --- a/inc/version.h.in +++ b/inc/version.h.in @@ -6,4 +6,4 @@ #define STLINK_VERSION_MINOR @PROJECT_VERSION_MINOR@ #define STLINK_VERSION_PATCH @PROJECT_VERSION_PATCH@ -#endif /* STLINK_VERSION_ */ +#endif // STLINK_VERSION_H_ diff --git a/src/common.c b/src/common.c index c9a54cf9f..361a24dbf 100644 --- a/src/common.c +++ b/src/common.c @@ -191,7 +191,7 @@ // WB Flash status register. #define STM32WB_FLASH_SR_BSY (16) /* FLASH_SR Busy */ -//32L4 register base is at FLASH_REGS_ADDR (0x40022000) +// 32L4 register base is at FLASH_REGS_ADDR (0x40022000) #define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) #define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) #define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) @@ -214,16 +214,16 @@ #define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ // Bits requesting flash operations (useful when we want to clear them) #define STM32L4_FLASH_CR_OPBITS \ - (uint32_t)((1lu< le (don't swap) - buf[0] = ((unsigned char*) &ui)[0]; - buf[1] = ((unsigned char*) &ui)[1]; - buf[2] = ((unsigned char*) &ui)[2]; - buf[3] = ((unsigned char*) &ui)[3]; + buf[0] = ((unsigned char*)&ui)[0]; + buf[1] = ((unsigned char*)&ui)[1]; + buf[2] = ((unsigned char*)&ui)[2]; + buf[3] = ((unsigned char*)&ui)[3]; } else { - buf[0] = ((unsigned char*) &ui)[3]; - buf[1] = ((unsigned char*) &ui)[2]; - buf[2] = ((unsigned char*) &ui)[1]; - buf[3] = ((unsigned char*) &ui)[0]; + buf[0] = ((unsigned char*)&ui)[3]; + buf[1] = ((unsigned char*)&ui)[2]; + buf[2] = ((unsigned char*)&ui)[1]; + buf[3] = ((unsigned char*)&ui)[0]; } } void write_uint16(unsigned char* buf, uint16_t ui) { if (!is_bigendian()) { // le -> le (don't swap) - buf[0] = ((unsigned char*) &ui)[0]; - buf[1] = ((unsigned char*) &ui)[1]; + buf[0] = ((unsigned char*)&ui)[0]; + buf[1] = ((unsigned char*)&ui)[1]; } else { - buf[0] = ((unsigned char*) &ui)[1]; - buf[1] = ((unsigned char*) &ui)[0]; + buf[0] = ((unsigned char*)&ui)[1]; + buf[1] = ((unsigned char*)&ui)[0]; } } uint32_t read_uint32(const unsigned char *c, const int pt) { uint32_t ui; - char *p = (char *) &ui; + char *p = (char *)&ui; if (!is_bigendian()) { // le -> le (don't swap) p[0] = c[pt + 0]; @@ -317,49 +317,51 @@ uint32_t read_uint32(const unsigned char *c, const int pt) { p[2] = c[pt + 1]; p[3] = c[pt + 0]; } - return ui; + + return(ui); } static uint32_t get_stm32l0_flash_base(stlink_t *sl) { switch (sl->chip_id) { - case STLINK_CHIPID_STM32_L1_CAT2: - case STLINK_CHIPID_STM32_L1_MEDIUM: - case STLINK_CHIPID_STM32_L1_MEDIUM_PLUS: - case STLINK_CHIPID_STM32_L1_HIGH: - return STM32L1_FLASH_REGS_ADDR; - default: - return STM32L0_FLASH_REGS_ADDR; + case STLINK_CHIPID_STM32_L1_CAT2: + case STLINK_CHIPID_STM32_L1_MEDIUM: + case STLINK_CHIPID_STM32_L1_MEDIUM_PLUS: + case STLINK_CHIPID_STM32_L1_HIGH: + return(STM32L1_FLASH_REGS_ADDR); + default: + return(STM32L0_FLASH_REGS_ADDR); } } static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { uint32_t rdp; stlink_read_debug32(sl, FLASH_WRPR, &rdp); - return rdp & 0xff; + return(rdp & 0xff); } static inline uint32_t read_flash_cr(stlink_t *sl) { uint32_t reg, res; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { reg = FLASH_F4_CR; - else if (sl->flash_type == STLINK_FLASH_TYPE_L4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { reg = STM32L4_FLASH_CR; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { reg = STM32Gx_FLASH_CR; - else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { reg = STM32WB_FLASH_CR; - else + } else { reg = FLASH_CR; + } stlink_read_debug32(sl, reg, &res); #if DEBUG_FLASH fprintf(stdout, "CR:0x%x\n", res); #endif - return res; + return(res); } static inline uint32_t read_flash_cr2(stlink_t *sl) { @@ -368,7 +370,7 @@ static inline uint32_t read_flash_cr2(stlink_t *sl) { #if DEBUG_FLASH fprintf(stdout, "CR2:0x%x\n", res); #endif - return res; + return(res); } static inline unsigned int is_flash_locked(stlink_t *sl) { @@ -378,7 +380,7 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { uint32_t n; if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { cr_reg = FLASH_CR; cr_lock_shift = FLASH_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { @@ -399,25 +401,24 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { cr_lock_shift = STM32WB_FLASH_CR_LOCK; } else { ELOG("unsupported flash method, abort\n"); - return -1; + return(-1); } stlink_read_debug32(sl, cr_reg, &n); - return n & (1u << cr_lock_shift); + return(n & (1u << cr_lock_shift)); } static void unlock_flash(stlink_t *sl) { uint32_t key_reg; uint32_t flash_key1 = FLASH_KEY1; uint32_t flash_key2 = FLASH_KEY2; - /* the unlock sequence consists of 2 write cycles where - 2 key values are written to the FLASH_KEYR register. - an invalid sequence results in a definitive lock of - the FPEC block until next reset. - */ + /* The unlock sequence consists of 2 write cycles where 2 key values are written + * to the FLASH_KEYR register. + * An invalid sequence results in a definitive lock of the FPEC block until next reset. + */ if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { key_reg = FLASH_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { key_reg = FLASH_F4_KEYR; @@ -428,7 +429,7 @@ static void unlock_flash(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { key_reg = STM32L4_FLASH_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + sl->flash_type == STLINK_FLASH_TYPE_G4) { key_reg = STM32Gx_FLASH_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { key_reg = STM32WB_FLASH_KEYR; @@ -450,20 +451,22 @@ static void unlock_flash(stlink_t *sl) { static int unlock_flash_if(stlink_t *sl) { if (is_flash_locked(sl)) { unlock_flash(sl); + if (is_flash_locked(sl)) { WLOG("Failed to unlock flash!\n"); - return -1; + return(-1); } } + DLOG("Successfully unlocked flash\n"); - return 0; + return(0); } static void lock_flash(stlink_t *sl) { uint32_t cr_lock_shift, cr_reg, n; if (sl->flash_type == STLINK_FLASH_TYPE_F0 || - sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { cr_reg = FLASH_CR; cr_lock_shift = FLASH_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { @@ -503,43 +506,45 @@ static bool is_flash_option_locked(stlink_t *sl) { uint32_t n; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - optcr_reg = FLASH_CR; - optlock_shift = FLASH_CR_OPTWRE; - active_bit_level = 0; /* bit is "option write enable", not lock */ - break; - case STLINK_FLASH_TYPE_F4: - optcr_reg = FLASH_F4_OPTCR; - optlock_shift = FLASH_F4_OPTCR_LOCK; - break; - case STLINK_FLASH_TYPE_L0: - optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - optlock_shift = STM32L0_FLASH_OPTLOCK; - break; - case STLINK_FLASH_TYPE_L4: - optcr_reg = STM32L4_FLASH_CR; - optlock_shift = STM32L4_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_WB: - optcr_reg = STM32WB_FLASH_CR; - optlock_shift = STM32WB_FLASH_CR_OPTLOCK; - break; - default: - ELOG("unsupported flash method, abort\n"); - return -1; + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; + optlock_shift = FLASH_CR_OPTWRE; + active_bit_level = 0; // bit is "option write enable", not lock + break; + case STLINK_FLASH_TYPE_F4: + optcr_reg = FLASH_F4_OPTCR; + optlock_shift = FLASH_F4_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_L0: + optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + optlock_shift = STM32L0_FLASH_OPTLOCK; + break; + case STLINK_FLASH_TYPE_L4: + optcr_reg = STM32L4_FLASH_CR; + optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_WB: + optcr_reg = STM32WB_FLASH_CR; + optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + break; + default: + ELOG("unsupported flash method, abort\n"); + return(-1); } stlink_read_debug32(sl, optcr_reg, &n); - if (active_bit_level == 0) - return !(n & (1u << optlock_shift)); - return n & (1u << optlock_shift); + if (active_bit_level == 0) { + return(!(n & (1u << optlock_shift))); + } + + return(n & (1u << optlock_shift)); } @@ -548,46 +553,48 @@ static int lock_flash_option(stlink_t *sl) { int active_bit_level = 1; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - optcr_reg = FLASH_CR; - optlock_shift = FLASH_CR_OPTWRE; - active_bit_level = 0; - break; - case STLINK_FLASH_TYPE_F4: - optcr_reg = FLASH_F4_OPTCR; - optlock_shift = FLASH_F4_OPTCR_LOCK; - break; - case STLINK_FLASH_TYPE_L0: - optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - optlock_shift = STM32L0_FLASH_OPTLOCK; - break; - case STLINK_FLASH_TYPE_L4: - optcr_reg = STM32L4_FLASH_CR; - optlock_shift = STM32L4_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_WB: - optcr_reg = STM32WB_FLASH_CR; - optlock_shift = STM32WB_FLASH_CR_OPTLOCK; - break; - default: - ELOG("unsupported flash method, abort\n"); - return -1; + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; + optlock_shift = FLASH_CR_OPTWRE; + active_bit_level = 0; + break; + case STLINK_FLASH_TYPE_F4: + optcr_reg = FLASH_F4_OPTCR; + optlock_shift = FLASH_F4_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_L0: + optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + optlock_shift = STM32L0_FLASH_OPTLOCK; + break; + case STLINK_FLASH_TYPE_L4: + optcr_reg = STM32L4_FLASH_CR; + optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_WB: + optcr_reg = STM32WB_FLASH_CR; + optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + break; + default: + ELOG("unsupported flash method, abort\n"); + return(-1); } stlink_read_debug32(sl, optcr_reg, &n); - if (active_bit_level == 0) + + if (active_bit_level == 0) { n &= ~(1u << optlock_shift); - else + } else { n |= (1u << optlock_shift); - stlink_write_debug32(sl, optcr_reg, n); + } - return 0; + stlink_write_debug32(sl, optcr_reg, n); + return(0); } static int unlock_flash_option(stlink_t *sl) { @@ -596,55 +603,56 @@ static int unlock_flash_option(stlink_t *sl) { uint32_t optkey2 = FLASH_OPTKEY2; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - optkey_reg = FLASH_OPTKEYR; - optkey1 = FLASH_F0_OPTKEY1; - optkey2 = FLASH_F0_OPTKEY2; - break; - case STLINK_FLASH_TYPE_F4: - optkey_reg = FLASH_F4_OPT_KEYR; - break; - case STLINK_FLASH_TYPE_L0: - optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; - optkey1 = FLASH_L0_OPTKEY1; - optkey2 = FLASH_L0_OPTKEY2; - break; - case STLINK_FLASH_TYPE_L4: - optkey_reg = STM32L4_FLASH_OPTKEYR; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optkey_reg = STM32Gx_FLASH_OPTKEYR; - break; - case STLINK_FLASH_TYPE_WB: - optkey_reg = STM32WB_FLASH_OPT_KEYR; - break; + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optkey_reg = FLASH_OPTKEYR; + optkey1 = FLASH_F0_OPTKEY1; + optkey2 = FLASH_F0_OPTKEY2; + break; + case STLINK_FLASH_TYPE_F4: + optkey_reg = FLASH_F4_OPT_KEYR; + break; + case STLINK_FLASH_TYPE_L0: + optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; + optkey1 = FLASH_L0_OPTKEY1; + optkey2 = FLASH_L0_OPTKEY2; + break; + case STLINK_FLASH_TYPE_L4: + optkey_reg = STM32L4_FLASH_OPTKEYR; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optkey_reg = STM32Gx_FLASH_OPTKEYR; + break; + case STLINK_FLASH_TYPE_WB: + optkey_reg = STM32WB_FLASH_OPT_KEYR; + break; - default: - ELOG("unsupported flash method, abort\n"); - return -1; + default: + ELOG("unsupported flash method, abort\n"); + return(-1); } stlink_write_debug32(sl, optkey_reg, optkey1); stlink_write_debug32(sl, optkey_reg, optkey2); - - return 0; + return(0); } static int unlock_flash_option_if(stlink_t *sl) { if (is_flash_option_locked(sl)) { if (unlock_flash_option(sl)) { ELOG("Could not unlock flash option!\n"); - return -1; + return(-1); } + if (is_flash_option_locked(sl)) { ELOG("Failed to unlock flash option!\n"); - return -1; + return(-1); } } + DLOG("Successfully unlocked flash option\n"); - return 0; + return(0); } static void set_flash_cr_pg(stlink_t *sl) { @@ -677,17 +685,18 @@ static void set_flash_cr_pg(stlink_t *sl) { static void clear_flash_cr_pg(stlink_t *sl) { uint32_t cr_reg, n; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; - else if (sl->flash_type == STLINK_FLASH_TYPE_L4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; - else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; - else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; - else + } else { cr_reg = FLASH_CR; + } n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); stlink_write_debug32(sl, cr_reg, n); @@ -697,12 +706,13 @@ static void set_flash_cr_per(stlink_t *sl) { uint32_t cr_reg, val; if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) + sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; - else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; - else + } else { cr_reg = FLASH_CR; + } stlink_read_debug32(sl, cr_reg, &val); val |= (1 << FLASH_CR_PER); @@ -718,12 +728,13 @@ static void clear_flash_cr_per(stlink_t *sl) { uint32_t cr_reg; if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) + sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; - else if (sl->flash_type == STLINK_FLASH_TYPE_WB) + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; - else + } else { cr_reg = FLASH_CR; + } const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PER); stlink_write_debug32(sl, cr_reg, n); @@ -744,9 +755,11 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_mer = (1 << STM32Gx_FLASH_CR_MER1); + if (sl->has_dual_bank) { cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); } + cr_pg = (1 << FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; @@ -759,16 +772,19 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { } stlink_read_debug32(sl, cr_reg, &val); + if (val & cr_pg) { - /* STM32F030 will drop MER bit if PG was set */ + // STM32F030 will drop MER bit if PG was set val &= ~cr_pg; stlink_write_debug32(sl, cr_reg, val); } - if (v) + if (v) { val |= cr_mer; - else + } else { val &= ~cr_mer; + } + stlink_write_debug32(sl, cr_reg, val); } @@ -779,10 +795,13 @@ static void set_flash_cr2_mer(stlink_t *sl, bool v) { stlink_read_debug32(sl, FLASH_CR2, &val); val &= ~cr_pg; - if (v) + + if (v) { val |= cr_mer; - else + } else { val &= ~cr_mer; + } + stlink_write_debug32(sl, FLASH_CR2, val); } @@ -842,7 +861,8 @@ static void set_flash_cr2_strt(stlink_t *sl) { static inline uint32_t read_flash_sr(stlink_t *sl) { uint32_t res, sr_reg; - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { sr_reg = FLASH_SR; } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; @@ -851,44 +871,45 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { sr_reg = STM32L4_FLASH_SR; } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + sl->flash_type == STLINK_FLASH_TYPE_G4) { sr_reg = STM32Gx_FLASH_SR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_reg = STM32WB_FLASH_SR; } else { ELOG("unsupported flash method, abort"); - return -1; + return(-1); } stlink_read_debug32(sl, sr_reg, &res); - - return res; + return(res); } static inline uint32_t read_flash_sr2(stlink_t *sl) { uint32_t res; stlink_read_debug32(sl, FLASH_SR2, &res); - return res; + return(res); } static inline unsigned int is_flash_busy(stlink_t *sl) { uint32_t sr_busy_shift; unsigned int res; - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_L0)) { + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_L0)) { sr_busy_shift = FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { sr_busy_shift = FLASH_F4_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { sr_busy_shift = STM32L4_FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + sl->flash_type == STLINK_FLASH_TYPE_G4) { sr_busy_shift = STM32Gx_FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_busy_shift = STM32WB_FLASH_SR_BSY; } else { ELOG("unsupported flash method, abort"); - return -1; + return(-1); } res = read_flash_sr(sl) & (1 << sr_busy_shift); @@ -897,11 +918,11 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { res |= read_flash_sr2(sl) & (1 << sr_busy_shift); } - return res; + return(res); } static void wait_flash_busy(stlink_t *sl) { - /* todo: add some delays here */ + // TODO: add some delays here while (is_flash_busy(sl)) ; } @@ -910,44 +931,48 @@ static void wait_flash_busy_progress(stlink_t *sl) { int i = 0; fprintf(stdout, "Mass erasing"); fflush(stdout); + while (is_flash_busy(sl)) { usleep(10000); i++; + if (i % 100 == 0) { fprintf(stdout, "."); fflush(stdout); } } + fprintf(stdout, "\n"); } static int check_flash_error(stlink_t *sl) { uint32_t res = 0; + switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - res = read_flash_sr(sl) & FLASH_SR_ERROR_MASK; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK; - break; - case STLINK_FLASH_TYPE_L0: - res = read_flash_sr(sl) & STM32L0_FLASH_SR_ERROR_MASK; - default: - break; + case STLINK_FLASH_TYPE_F0: + res = read_flash_sr(sl) & FLASH_SR_ERROR_MASK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK; + break; + case STLINK_FLASH_TYPE_L0: + res = read_flash_sr(sl) & STM32L0_FLASH_SR_ERROR_MASK; + default: + break; } if (res) { ELOG("Flash programming error : %#010x\n", res); - return -1; + return(-1); } - return 0; + return(0); } static inline unsigned int is_flash_eop(stlink_t *sl) { - return read_flash_sr(sl) & (1 << FLASH_SR_EOP); + return(read_flash_sr(sl) & (1 << FLASH_SR_EOP)); } static void __attribute__((unused)) clear_flash_sr_eop(stlink_t *sl) { @@ -956,7 +981,7 @@ static void __attribute__((unused)) clear_flash_sr_eop(stlink_t *sl) { } static void __attribute__((unused)) wait_flash_eop(stlink_t *sl) { - /* todo: add some delays here */ + // TODO: add some delays here while (is_flash_eop(sl) == 0) ; } @@ -992,12 +1017,12 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { } static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { - stlink_write_debug32(sl, STM32L4_FLASH_SR, 0xFFFFFFFF & ~(1<backend->close(sl); free(sl); } @@ -1021,26 +1049,28 @@ int stlink_exit_debug_mode(stlink_t *sl) { DLOG("*** stlink_exit_debug_mode ***\n"); ret = stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); - if (ret == -1) - return ret; - return sl->backend->exit_debug_mode(sl); + if (ret == -1) { + return(ret); + } + + return(sl->backend->exit_debug_mode(sl)); } int stlink_enter_swd_mode(stlink_t *sl) { DLOG("*** stlink_enter_swd_mode ***\n"); - return sl->backend->enter_swd_mode(sl); + return(sl->backend->enter_swd_mode(sl)); } // Force the core into the debug mode -> halted state. int stlink_force_debug(stlink_t *sl) { DLOG("*** stlink_force_debug_mode ***\n"); - return sl->backend->force_debug(sl); + return(sl->backend->force_debug(sl)); } int stlink_exit_dfu_mode(stlink_t *sl) { DLOG("*** stlink_exit_dfu_mode ***\n"); - return sl->backend->exit_dfu_mode(sl); + return(sl->backend->exit_dfu_mode(sl)); } int stlink_core_id(stlink_t *sl) { @@ -1048,14 +1078,18 @@ int stlink_core_id(stlink_t *sl) { DLOG("*** stlink_core_id ***\n"); ret = sl->backend->core_id(sl); + if (ret == -1) { ELOG("Failed to read core_id\n"); - return ret; + return(ret); } - if (sl->verbose > 2) + + if (sl->verbose > 2) { stlink_print_data(sl); + } + DLOG("core_id = 0x%08x\n", sl->core_id); - return ret; + return(ret); } // stlink_chip_id() is called by stlink_load_device_params() @@ -1064,13 +1098,17 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { int ret; ret = stlink_read_debug32(sl, 0xE0042000, chip_id); - if (ret == -1) - return ret; - if (*chip_id == 0) - ret = stlink_read_debug32(sl, 0x40015800, chip_id); //Try Corex M0 DBGMCU_IDCODE register address + if (ret == -1) { + return(ret); + } + + if (*chip_id == 0) { + // Try Corex M0 DBGMCU_IDCODE register address + ret = stlink_read_debug32(sl, 0x40015800, chip_id); + } - return ret; + return(ret); } /** @@ -1086,23 +1124,24 @@ int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { cpuid->variant = 0; cpuid->part = 0; cpuid->revision = 0; - return -1; + return(-1); } + cpuid->implementer_id = (raw >> 24) & 0x7f; cpuid->variant = (raw >> 20) & 0xf; cpuid->part = (raw >> 4) & 0xfff; cpuid->revision = raw & 0xf; - return 0; + return(0); } /** - * reads and decodes the flash parameters, as dynamically as possible + * Reads and decodes the flash parameters, as dynamically as possible * @param sl * @return 0 for success, or -1 for unsupported core type. */ int stlink_load_device_params(stlink_t *sl) { - // This seems to normally work so is unnecessary info for a normal - // user. Demoted to debug. -- REW + // This seems to normally work so is unnecessary info for a normal user. + // Demoted to debug. -- REW DLOG("Loading device parameters....\n"); const struct stlink_chipid_params *params = NULL; stlink_core_id(sl); @@ -1111,43 +1150,50 @@ int stlink_load_device_params(stlink_t *sl) { stlink_chip_id(sl, &chip_id); sl->chip_id = chip_id & 0xfff; - /* Fix chip_id for F4 rev A errata , Read CPU ID, as CoreID is the same for F2/F4*/ + + // Fix chip_id for F4 rev A errata , Read CPU ID, as CoreID is the same for F2/F4 if (sl->chip_id == 0x411) { uint32_t cpuid; stlink_read_debug32(sl, 0xE000ED00, &cpuid); - if ((cpuid & 0xfff0) == 0xc240) + + if ((cpuid & 0xfff0) == 0xc240) { sl->chip_id = 0x413; + } } params = stlink_chipid_get_params(sl->chip_id); + if (params == NULL) { WLOG("unknown chip id! %#x\n", chip_id); - return -1; + return(-1); } if (params->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { WLOG("Invalid flash type, please check device declaration\n"); sl->flash_size = 0; - return 0; + return(0); } // These are fixed... sl->flash_base = STM32_FLASH_BASE; sl->sram_base = STM32_SRAM_BASE; - stlink_read_debug32(sl,(params->flash_size_reg) & ~3, &flash_size); - if (params->flash_size_reg & 2) - flash_size = flash_size >>16; + stlink_read_debug32(sl, (params->flash_size_reg) & ~3, &flash_size); + + if (params->flash_size_reg & 2) { + flash_size = flash_size >> 16; + } + flash_size = flash_size & 0xffff; if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW || - sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS) && ( flash_size == 0 )) { - sl->flash_size = 128 * 1024; + sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS) && (flash_size == 0)) { + sl->flash_size = 128 * 1024; } else if (sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2) { sl->flash_size = (flash_size & 0xff) * 1024; } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_HIGH) { // 0 is 384k and 1 is 256k - if ( flash_size == 0){ + if (flash_size == 0) { sl->flash_size = 384 * 1024; } else { sl->flash_size = 256 * 1024; @@ -1165,54 +1211,53 @@ int stlink_load_device_params(stlink_t *sl) { sl->option_base = params->option_base; sl->option_size = params->option_size; - //medium and low devices have the same chipid. ram size depends on flash size. - //STM32F100xx datasheet Doc ID 16455 Table 2 - if (sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW && sl->flash_size < 64 * 1024){ + // medium and low devices have the same chipid. ram size depends on flash size. + // STM32F100xx datasheet Doc ID 16455 Table 2 + if (sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW && sl->flash_size < 64 * 1024) { sl->sram_size = 0x1000; } if (sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3) { uint32_t flash_optr; stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); - if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { - sl->flash_pgsz <<= 1; - } + + if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { sl->flash_pgsz <<= 1; } } #if 0 // Old code -- REW ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); - // TODO make note of variable page size here..... + // TODO: make note of variable page size here..... ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %u bytes\n", - sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, - (unsigned int)sl->flash_pgsz); + sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, + (unsigned int)sl->flash_pgsz); #else ILOG("%s: %zd KiB SRAM, %zd KiB flash in at least %zd %s pages.\n", - params->description, sl->sram_size / 1024, sl->flash_size / 1024, - (sl->flash_pgsz < 1024)? sl->flash_pgsz : sl->flash_pgsz/1024, - (sl->flash_pgsz < 1024)? "byte" : "KiB"); + params->description, sl->sram_size / 1024, sl->flash_size / 1024, + (sl->flash_pgsz < 1024) ? sl->flash_pgsz : sl->flash_pgsz / 1024, + (sl->flash_pgsz < 1024) ? "byte" : "KiB"); #endif - return 0; + return(0); } int stlink_reset(stlink_t *sl) { DLOG("*** stlink_reset ***\n"); - return sl->backend->reset(sl); + return(sl->backend->reset(sl)); } int stlink_jtag_reset(stlink_t *sl, int value) { DLOG("*** stlink_jtag_reset ***\n"); - return sl->backend->jtag_reset(sl, value); + return(sl->backend->jtag_reset(sl, value)); } int stlink_run(stlink_t *sl) { DLOG("*** stlink_run ***\n"); - return sl->backend->run(sl); + return(sl->backend->run(sl)); } int stlink_set_swdclk(stlink_t *sl, uint16_t divisor) { DLOG("*** set_swdclk ***\n"); - return sl->backend->set_swdclk(sl, divisor); + return(sl->backend->set_swdclk(sl, divisor)); } int stlink_status(stlink_t *sl) { @@ -1221,8 +1266,7 @@ int stlink_status(stlink_t *sl) { DLOG("*** stlink_status ***\n"); ret = sl->backend->status(sl); stlink_core_stat(sl); - - return ret; + return(ret); } /** @@ -1232,13 +1276,14 @@ int stlink_status(stlink_t *sl) { */ void _parse_version(stlink_t *sl, stlink_version_t *slv) { sl->version.flags = 0; + if (sl->version.stlink_v < 3) { - uint32_t b0 = sl->q_buf[0]; //lsb + uint32_t b0 = sl->q_buf[0]; // lsb uint32_t b1 = sl->q_buf[1]; uint32_t b2 = sl->q_buf[2]; uint32_t b3 = sl->q_buf[3]; uint32_t b4 = sl->q_buf[4]; - uint32_t b5 = sl->q_buf[5]; //msb + uint32_t b5 = sl->q_buf[5]; // msb // b0 b1 || b2 b3 | b4 b5 // 4b | 6b | 6b || 2B | 2B @@ -1249,14 +1294,17 @@ void _parse_version(stlink_t *sl, stlink_version_t *slv) { slv->swim_v = b1 & 0x3f; slv->st_vid = (b3 << 8) | b2; slv->stlink_pid = (b5 << 8) | b4; - /* ST-LINK/V1 from J11 switch to api-v2 (and support SWD) */ - if (slv->stlink_v == 1) - slv->jtag_api = slv->jtag_v > 11? STLINK_JTAG_API_V2 : STLINK_JTAG_API_V1; - else { + + // ST-LINK/V1 from J11 switch to api-v2 (and support SWD) + if (slv->stlink_v == 1) { + slv->jtag_api = slv->jtag_v > 11 ? STLINK_JTAG_API_V2 : STLINK_JTAG_API_V1; + } else { slv->jtag_api = STLINK_JTAG_API_V2; - /* preferred API to get last R/W status from J15 */ - if (sl->version.jtag_v >= 15) + + // preferred API to get last R/W status from J15 + if (sl->version.jtag_v >= 15) { sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; + } } } else { // V3 uses different version format, for reference see OpenOCD source @@ -1271,13 +1319,16 @@ void _parse_version(stlink_t *sl, stlink_version_t *slv) { /* preferred API to get last R/W status */ sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; } + return; } int stlink_version(stlink_t *sl) { DLOG("*** looking up stlink version\n"); - if (sl->backend->version(sl)) - return -1; + + if (sl->backend->version(sl)) { + return(-1); + } _parse_version(sl, &sl->version); @@ -1286,21 +1337,25 @@ int stlink_version(stlink_t *sl) { DLOG("stlink version = 0x%x\n", sl->version.stlink_v); DLOG("jtag version = 0x%x\n", sl->version.jtag_v); DLOG("swim version = 0x%x\n", sl->version.swim_v); + if (sl->version.jtag_v == 0) { DLOG(" notice: the firmware doesn't support a jtag/swd interface\n"); } + if (sl->version.swim_v == 0) { DLOG(" notice: the firmware doesn't support a swim interface\n"); } - return 0; + return(0); } int stlink_target_voltage(stlink_t *sl) { int voltage = -1; DLOG("*** reading target voltage\n"); + if (sl->backend->target_voltage != NULL) { voltage = sl->backend->target_voltage(sl); + if (voltage != -1) { DLOG("target voltage = %ldmV\n", voltage); } else { @@ -1309,66 +1364,76 @@ int stlink_target_voltage(stlink_t *sl) { } else { DLOG("reading voltage not supported by backend\n"); } - return voltage; + + return(voltage); } int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { int ret; ret = sl->backend->read_debug32(sl, addr, data); - if (!ret) + + if (!ret) { DLOG("*** stlink_read_debug32 %x is %#x\n", *data, addr); + } - return ret; + return(ret); } int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { DLOG("*** stlink_write_debug32 %x to %#x\n", data, addr); - return sl->backend->write_debug32(sl, addr, data); + return(sl->backend->write_debug32(sl, addr, data)); } int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); + if (len % 4 != 0) { - fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); + fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", + len % 4); abort(); } - return sl->backend->write_mem32(sl, addr, len); + + return(sl->backend->write_mem32(sl, addr, len)); } int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_read_mem32 ***\n"); + if (len % 4 != 0) { // !!! never ever: fw gives just wrong values fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); abort(); } - return sl->backend->read_mem32(sl, addr, len); + + return(sl->backend->read_mem32(sl, addr, len)); } int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem8 ***\n"); - if (len > 0x40){ // !!! never ever: Writing more then 0x40 bytes gives unexpected behaviour + + if (len > 0x40) { // !!! never ever: Writing more then 0x40 bytes gives unexpected behaviour fprintf(stderr, "Error: Data length > 64: +%d byte.\n", len); abort(); } - return sl->backend->write_mem8(sl, addr, len); + + return(sl->backend->write_mem8(sl, addr, len)); } int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { DLOG("*** stlink_read_all_regs ***\n"); - return sl->backend->read_all_regs(sl, regp); + return(sl->backend->read_all_regs(sl, regp)); } int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { DLOG("*** stlink_read_all_unsupported_regs ***\n"); - return sl->backend->read_all_unsupported_regs(sl, regp); + return(sl->backend->read_all_unsupported_regs(sl, regp)); } int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) { DLOG("*** stlink_write_reg\n"); - return sl->backend->write_reg(sl, reg, idx); + return(sl->backend->write_reg(sl, reg, idx)); } int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { @@ -1377,10 +1442,10 @@ int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { if (r_idx > 20 || r_idx < 0) { fprintf(stderr, "Error: register index must be in [0..20]\n"); - return -1; + return(-1); } - return sl->backend->read_reg(sl, r_idx, regp); + return(sl->backend->read_reg(sl, r_idx, regp)); } int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { @@ -1390,18 +1455,18 @@ int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp DLOG(" (%d) ***\n", r_idx); /* Convert to values used by STLINK_REG_DCRSR */ - if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ + if (r_idx >= 0x1C && r_idx <= 0x1F) { // primask, basepri, faultmask, or control r_convert = 0x14; - } else if (r_idx == 0x40) { /* FPSCR */ + } else if (r_idx == 0x40) { // FPSCR r_convert = 0x21; } else if (r_idx >= 0x20 && r_idx < 0x40) { r_convert = 0x40 + (r_idx - 0x20); } else { fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); - return -1; + return(-1); } - return sl->backend->read_unsupported_reg(sl, r_convert, regp); + return(sl->backend->read_unsupported_reg(sl, r_convert, regp)); } int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, struct stlink_reg *regp) { @@ -1412,45 +1477,46 @@ int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, struct s /* Convert to values used by STLINK_REG_DCRSR */ if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ - r_convert = r_idx; /* The backend function handles this */ - } else if (r_idx == 0x40) { /* FPSCR */ + r_convert = r_idx; // the backend function handles this + } else if (r_idx == 0x40) { // FPSCR r_convert = 0x21; } else if (r_idx >= 0x20 && r_idx < 0x40) { r_convert = 0x40 + (r_idx - 0x20); } else { fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); - return -1; + return(-1); } - return sl->backend->write_unsupported_reg(sl, val, r_convert, regp); + return(sl->backend->write_unsupported_reg(sl, val, r_convert, regp)); } -bool stlink_is_core_halted(stlink_t *sl) -{ +bool stlink_is_core_halted(stlink_t *sl) { stlink_status(sl); - return sl->core_stat == TARGET_HALTED; + return(sl->core_stat == TARGET_HALTED); } int stlink_step(stlink_t *sl) { DLOG("*** stlink_step ***\n"); - return sl->backend->step(sl); + return(sl->backend->step(sl)); } int stlink_current_mode(stlink_t *sl) { int mode = sl->backend->current_mode(sl); + switch (mode) { case STLINK_DEV_DFU_MODE: DLOG("stlink current mode: dfu\n"); - return mode; + return(mode); case STLINK_DEV_DEBUG_MODE: DLOG("stlink current mode: debug (jtag or swd)\n"); - return mode; + return(mode); case STLINK_DEV_MASS_MODE: DLOG("stlink current mode: mass\n"); - return mode; + return(mode); } + DLOG("stlink mode: unknown!\n"); - return STLINK_DEV_UNKNOWN_MODE; + return(STLINK_DEV_UNKNOWN_MODE); } @@ -1463,12 +1529,12 @@ int stlink_current_mode(stlink_t *sl) { unsigned int is_bigendian(void) { static volatile const unsigned int i = 1; - return *(volatile const char*) &i == 0; + return(*(volatile const char*)&i == 0); } uint16_t read_uint16(const unsigned char *c, const int pt) { uint32_t ui; - char *p = (char *) &ui; + char *p = (char *)&ui; if (!is_bigendian()) { // le -> le (don't swap) p[0] = c[pt + 0]; @@ -1477,18 +1543,17 @@ uint16_t read_uint16(const unsigned char *c, const int pt) { p[0] = c[pt + 1]; p[1] = c[pt + 0]; } - return ui; + + return(ui); } // same as above with entrypoint. void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { stlink_write_reg(sl, addr, 15); /* pc register */ - stlink_run(sl); - while (stlink_is_core_halted(sl)) - usleep(3000000); + while (stlink_is_core_halted(sl)) { usleep(3000000); } } @@ -1514,27 +1579,26 @@ void stlink_core_stat(stlink_t *sl) { } void stlink_print_data(stlink_t * sl) { - if (sl->q_len <= 0 || sl->verbose < UDEBUG) - return; - if (sl->verbose > 2) - DLOG("data_len = %d 0x%x\n", sl->q_len, sl->q_len); + if (sl->q_len <= 0 || sl->verbose < UDEBUG) { return; } + + if (sl->verbose > 2) { DLOG("data_len = %d 0x%x\n", sl->q_len, sl->q_len); } for (int i = 0; i < sl->q_len; i++) { if (i % 16 == 0) { - /* - if (sl->q_data_dir == Q_DATA_OUT) - fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i); - else - fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); - */ + // if (sl->q_data_dir == Q_DATA_OUT) { + // fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i); + // } else { + // fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); + // } } - DLOG(" %02x", (unsigned int) sl->q_buf[i]); + + DLOG(" %02x", (unsigned int)sl->q_buf[i]); } + DLOG("\n\n"); } -/* memory mapped file */ - +/* Memory mapped file */ typedef struct mapped_file { uint8_t* base; size_t len; @@ -1547,86 +1611,85 @@ static int map_file(mapped_file_t* mf, const char* path) { struct stat st; const int fd = open(path, O_RDONLY | O_BINARY); + if (fd == -1) { fprintf(stderr, "open(%s) == -1\n", path); - return -1; + return(-1); } if (fstat(fd, &st) == -1) { fprintf(stderr, "fstat(%s) == -1\n", path); goto on_error; } + if (sizeof(st.st_size) != sizeof(size_t)) { - /* On 32 bit systems, check if there is an overflow */ + // on 32 bit systems, check if there is an overflow if (st.st_size > (off_t)UINT32_MAX) { fprintf(stderr, "mmap() size_t overflow for file %s\n", path); goto on_error; } } - mf->base = (uint8_t*) mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); + + mf->base = (uint8_t*)mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); + if (mf->base == MAP_FAILED) { fprintf(stderr, "mmap() == MAP_FAILED for file %s\n", path); goto on_error; } mf->len = st.st_size; - - /* success */ - error = 0; + error = 0; // success on_error: close(fd); - - return error; + return(error); } static void unmap_file(mapped_file_t * mf) { - munmap((void*) mf->base, mf->len); - mf->base = (unsigned char*) MAP_FAILED; + munmap((void*)mf->base, mf->len); + mf->base = (unsigned char*)MAP_FAILED; mf->len = 0; } -/* Limit the block size to compare to 0x1800 - Anything larger will stall the STLINK2 - Maybe STLINK V1 needs smaller value!*/ +/* Limit the block size to compare to 0x1800 as anything larger will stall the STLINK2 + * Maybe STLINK V1 needs smaller value! + */ static int check_file(stlink_t* sl, mapped_file_t* mf, stm32_addr_t addr) { size_t off; size_t n_cmp = sl->flash_pgsz; - if ( n_cmp > 0x1800) - n_cmp = 0x1800; + + if ( n_cmp > 0x1800) { n_cmp = 0x1800; } for (off = 0; off < mf->len; off += n_cmp) { size_t aligned_size; - /* adjust last page size */ - size_t cmp_size = n_cmp; - if ((off + n_cmp) > mf->len) - cmp_size = mf->len - off; + size_t cmp_size = n_cmp; // adjust last page size + + if ((off + n_cmp) > mf->len) { cmp_size = mf->len - off; } aligned_size = cmp_size; - if (aligned_size & (4 - 1)) - aligned_size = (cmp_size + 4) & ~(4 - 1); - stlink_read_mem32(sl, addr + (uint32_t) off, aligned_size); + if (aligned_size & (4 - 1)) { aligned_size = (cmp_size + 4) & ~(4 - 1); } + + stlink_read_mem32(sl, addr + (uint32_t)off, aligned_size); - if (memcmp(sl->q_buf, mf->base + off, cmp_size)) - return -1; + if (memcmp(sl->q_buf, mf->base + off, cmp_size)) { return(-1); } } - return 0; + return(0); } static void md5_calculate(mapped_file_t *mf) { - /* calculate md5 checksum of given binary file */ - Md5Context md5Context; - MD5_HASH md5Hash; + // calculate md5 checksum of given binary file + Md5Context md5Context; + MD5_HASH md5Hash; Md5Initialise(&md5Context); Md5Update(&md5Context, mf->base, (uint32_t)mf->len); Md5Finalise(&md5Context, &md5Hash); printf("md5 checksum: "); - for (int i = 0; i < (int) sizeof(md5Hash); i++) { - printf("%x", md5Hash.bytes[i]); - } + + for (int i = 0; i < (int)sizeof(md5Hash); i++) { printf("%x", md5Hash.bytes[i]); } + printf(", "); } @@ -1634,31 +1697,31 @@ static void stlink_checksum(mapped_file_t *mp) { /* checksum that backward compatible with official ST tools */ uint32_t sum = 0; uint8_t *mp_byte = (uint8_t *)mp->base; - for (size_t i = 0; i < mp->len; ++i) { - sum += mp_byte[i]; - } + + for (size_t i = 0; i < mp->len; ++i) { sum += mp_byte[i]; } + printf("stlink checksum: 0x%08x\n", sum); } static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { unsigned int val; - /* set stack*/ + // set stack stlink_read_debug32(sl, addr, &val); stlink_write_reg(sl, val, 13); - /* Set PC to the reset routine*/ + // set PC to the reset routine stlink_read_debug32(sl, addr + 4, &val); stlink_write_reg(sl, val, 15); stlink_run(sl); } int stlink_mwrite_sram(stlink_t * sl, uint8_t* data, uint32_t length, stm32_addr_t addr) { - /* write the file in sram at addr */ + // write the file in sram at addr int error = -1; size_t off; size_t len; - /* check addr range is inside the sram */ + // check addr range is inside the sram if (addr < sl->sram_base) { fprintf(stderr, "addr too low\n"); goto on_error; @@ -1669,47 +1732,42 @@ int stlink_mwrite_sram(stlink_t * sl, uint8_t* data, uint32_t length, stm32_addr fprintf(stderr, "addr too high\n"); goto on_error; } else if (addr & 3) { - /* todo */ fprintf(stderr, "unaligned addr\n"); goto on_error; } len = length; - if (len & 3) { - len -= len & 3; - } + if (len & 3) { len -= len & 3; } - /* do the copy by 1k blocks */ + // do the copy by 1kB blocks for (off = 0; off < len; off += 1024) { size_t size = 1024; - if ((off + size) > len) - size = len - off; + + if ((off + size) > len) { size = len - off; } memcpy(sl->q_buf, data + off, size); - /* round size if needed */ - if (size & 3) - size += 2; + if (size & 3) { size += 2; } // round size if needed - stlink_write_mem32(sl, addr + (uint32_t) off, size); + stlink_write_mem32(sl, addr + (uint32_t)off, size); } if (length > len) { memcpy(sl->q_buf, data + len, length - len); - stlink_write_mem8(sl, addr + (uint32_t) len, length - len); + stlink_write_mem8(sl, addr + (uint32_t)len, length - len); } - /* success */ - error = 0; + + error = 0; // success stlink_fwrite_finalize(sl, addr); on_error: - return error; + return(error); } int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { - /* write the file in sram at addr */ + // write the file in sram at addr int error = -1; size_t off; @@ -1718,13 +1776,14 @@ int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { if (map_file(&mf, path) == -1) { fprintf(stderr, "map_file() == -1\n"); - return -1; + return(-1); } + printf("file %s ", path); md5_calculate(&mf); stlink_checksum(&mf); - /* check addr range is inside the sram */ + // check if addr range is inside the SRAM if (addr < sl->sram_base) { fprintf(stderr, "addr too low\n"); goto on_error; @@ -1735,88 +1794,80 @@ int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { fprintf(stderr, "addr too high\n"); goto on_error; } else if (addr & 3) { - /* todo */ fprintf(stderr, "unaligned addr\n"); goto on_error; } len = mf.len; - if (len & 3) { - len -= len & 3; - } + if (len & 3) { len -= len & 3; } - /* do the copy by 1k blocks */ + // do the copy by 1kB blocks for (off = 0; off < len; off += 1024) { size_t size = 1024; - if ((off + size) > len) - size = len - off; + + if ((off + size) > len) { size = len - off; } memcpy(sl->q_buf, mf.base + off, size); - /* round size if needed */ - if (size & 3) - size += 2; + if (size & 3) { size += 2; } // round size if needed - stlink_write_mem32(sl, addr + (uint32_t) off, size); + stlink_write_mem32(sl, addr + (uint32_t)off, size); } if (mf.len > len) { memcpy(sl->q_buf, mf.base + len, mf.len - len); - stlink_write_mem8(sl, addr + (uint32_t) len, mf.len - len); + stlink_write_mem8(sl, addr + (uint32_t)len, mf.len - len); } - /* check the file ha been written */ + // check the file has been written if (check_file(sl, &mf, addr) == -1) { fprintf(stderr, "check_file() == -1\n"); goto on_error; } - /* success */ - error = 0; + error = 0; // success stlink_fwrite_finalize(sl, addr); on_error: unmap_file(&mf); - return error; + return(error); } typedef bool (*save_block_fn)(void* arg, uint8_t* block, ssize_t len); -static int stlink_read(stlink_t* sl, stm32_addr_t addr, size_t size, save_block_fn fn, void* fn_arg) { +static int stlink_read( + stlink_t* sl, stm32_addr_t addr, size_t size, save_block_fn fn, void* fn_arg) { int error = -1; - if (size <1) - size = sl->flash_size; + if (size < 1) { size = sl->flash_size; } - if (size > sl->flash_size) + if (size > sl->flash_size) { size = sl->flash_size; + } + + size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; - size_t cmp_size = (sl->flash_pgsz > 0x1800)? 0x1800:sl->flash_pgsz; for (size_t off = 0; off < size; off += cmp_size) { size_t aligned_size; - /* adjust last page size */ - if ((off + cmp_size) > size) - cmp_size = size - off; + // adjust last page size + if ((off + cmp_size) > size) { cmp_size = size - off; } aligned_size = cmp_size; - if (aligned_size & (4 - 1)) - aligned_size = (cmp_size + 4) & ~(4 - 1); - stlink_read_mem32(sl, addr + (uint32_t) off, aligned_size); + if (aligned_size & (4 - 1)) { aligned_size = (cmp_size + 4) & ~(4 - 1); } - if (!fn(fn_arg, sl->q_buf, aligned_size)) { - goto on_error; - } + stlink_read_mem32(sl, addr + (uint32_t)off, aligned_size); + + if (!fn(fn_arg, sl->q_buf, aligned_size)) { goto on_error; } } - /* success */ - error = 0; + error = 0; // success on_error: - return error; + return(error); } struct stlink_fread_worker_arg { @@ -1825,12 +1876,12 @@ struct stlink_fread_worker_arg { static bool stlink_fread_worker(void* arg, uint8_t* block, ssize_t len) { struct stlink_fread_worker_arg* the_arg = (struct stlink_fread_worker_arg*)arg; + if (write(the_arg->fd, block, len) != len) { fprintf(stderr, "write() != aligned_size\n"); - return false; - } - else { - return true; + return(false); + } else { + return(true); } } @@ -1845,45 +1896,56 @@ struct stlink_fread_ihex_worker_arg { static bool stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg* the_arg) { uint32_t addr = the_arg->addr; uint8_t sum = 2 + 4 + (uint8_t)((addr & 0xFF000000) >> 24) + (uint8_t)((addr & 0x00FF0000) >> 16); - if (17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", (addr & 0xFFFF0000) >> 16, (uint8_t)(0x100 - sum))) - return false; - the_arg->lba = (addr & 0xFFFF0000); + if (17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", (addr & 0xFFFF0000) >> 16, + (uint8_t)(0x100 - sum))) { + return(false); + } - return true; + the_arg->lba = (addr & 0xFFFF0000); + return(true); } static bool stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg* the_arg) { uint8_t count = the_arg->buf_pos; - if (count == 0) return true; + + if (count == 0) { return(true); } uint32_t addr = the_arg->addr; if (the_arg->lba != (addr & 0xFFFF0000)) { // segment changed - if (!stlink_fread_ihex_newsegment(the_arg)) return false; + if (!stlink_fread_ihex_newsegment(the_arg)) { + return(false); + } } uint8_t sum = count + (uint8_t)((addr & 0x0000FF00) >> 8) + (uint8_t)(addr & 0x000000FF); - if (9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) - return false; + + if (9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) { + return(false); + } for (uint8_t i = 0; i < count; ++i) { uint8_t b = the_arg->buf[i]; sum += b; - if (2 != fprintf(the_arg->file, "%02X", b)) - return false; + + if (2 != fprintf(the_arg->file, "%02X", b)) { + return(false); + } } - if (4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) - return false; + if (4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) { + return(false); + } the_arg->addr += count; the_arg->buf_pos = 0; - return true; + return(true); } -static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg* the_arg, int fd, stm32_addr_t addr) { +static bool stlink_fread_ihex_init( + struct stlink_fread_ihex_worker_arg* the_arg, int fd, stm32_addr_t addr) { the_arg->file = fdopen(fd, "w"); the_arg->addr = addr; the_arg->lba = 0; @@ -1897,109 +1959,127 @@ static bool stlink_fread_ihex_worker(void* arg, uint8_t* block, ssize_t len) { for (ssize_t i = 0; i < len; ++i) { if (the_arg->buf_pos == sizeof(the_arg->buf)) { // line is full - if (!stlink_fread_ihex_writeline(the_arg)) return false; + if (!stlink_fread_ihex_writeline(the_arg)) { return(false); } } the_arg->buf[the_arg->buf_pos++] = block[i]; } - return true; + return(true); } static bool stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg* the_arg) { - if (!stlink_fread_ihex_writeline(the_arg)) return false; + if (!stlink_fread_ihex_writeline(the_arg)) { return(false); } - // FIXME do we need the Start Linear Address? + // FIXME: do we need the Start Linear Address? - if (13 != fprintf(the_arg->file, ":00000001FF\r\n")) // EoF - return false; + if (13 != fprintf(the_arg->file, ":00000001FF\r\n")) { // EoF + return(false); + } return (0 == fclose(the_arg->file)); } int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size) { - /* read size bytes from addr to file */ + // read size bytes from addr to file int error; - int fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); + if (fd == -1) { fprintf(stderr, "open(%s) == -1\n", path); - return -1; + return(-1); } if (is_ihex) { struct stlink_fread_ihex_worker_arg arg; + if (stlink_fread_ihex_init(&arg, fd, addr)) { error = stlink_read(sl, addr, size, &stlink_fread_ihex_worker, &arg); - if (!stlink_fread_ihex_finalize(&arg)) - error = -1; - } - else { + + if (!stlink_fread_ihex_finalize(&arg)) { error = -1; } + } else { error = -1; } - } - else { + } else { struct stlink_fread_worker_arg arg = { fd }; error = stlink_read(sl, addr, size, &stlink_fread_worker, &arg); } close(fd); - - return error; + return(error); } int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size) { - /* write the buffer right after the loader */ + // write the buffer right after the loader size_t chunk = size & ~0x3; size_t rem = size & 0x3; + if (chunk) { memcpy(sl->q_buf, buf, chunk); stlink_write_mem32(sl, fl->buf_addr, chunk); } + if (rem) { - memcpy(sl->q_buf, buf+chunk, rem); - stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t) chunk, rem); + memcpy(sl->q_buf, buf + chunk, rem); + stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, rem); } - return 0; + + return(0); } -uint32_t calculate_F4_sectornum(uint32_t flashaddr){ +uint32_t calculate_F4_sectornum(uint32_t flashaddr) { uint32_t offset = 0; - flashaddr &= ~STM32_FLASH_BASE; //Page now holding the actual flash address + flashaddr &= ~STM32_FLASH_BASE; // page now holding the actual flash address + if (flashaddr >= 0x100000) { offset = 12; flashaddr -= 0x100000; } - if (flashaddr<0x4000) return (offset + 0); - else if (flashaddr<0x8000) return(offset + 1); - else if (flashaddr<0xc000) return(offset + 2); - else if (flashaddr<0x10000) return(offset + 3); - else if (flashaddr<0x20000) return(offset + 4); - else return offset + (flashaddr/0x20000) +4; + + if (flashaddr < 0x4000) { + return (offset + 0); + } else if (flashaddr < 0x8000) { + return(offset + 1); + } else if (flashaddr < 0xc000) { + return(offset + 2); + } else if (flashaddr < 0x10000) { + return(offset + 3); + } else if (flashaddr < 0x20000) { + return(offset + 4); + } else { + return(offset + (flashaddr / 0x20000) + 4); + } } -uint32_t calculate_F7_sectornum(uint32_t flashaddr){ - flashaddr &= ~STM32_FLASH_BASE; //Page now holding the actual flash address - if (flashaddr<0x20000) return(flashaddr/0x8000); - else if (flashaddr<0x40000) return(4); - else return(flashaddr/0x40000) +4; +uint32_t calculate_F7_sectornum(uint32_t flashaddr) { + flashaddr &= ~STM32_FLASH_BASE; // Page now holding the actual flash address + + if (flashaddr < 0x20000) { + return(flashaddr / 0x8000); + } else if (flashaddr < 0x40000) { + return(4); + } else { + return((flashaddr / 0x40000) + 4); + } } -// Returns BKER:PNB for the given page address +// returns BKER:PNB for the given page address uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { uint32_t bker = 0; uint32_t flashopt; stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); flashaddr -= STM32_FLASH_BASE; + if (sl->chip_id == STLINK_CHIPID_STM32_L4 || sl->chip_id == STLINK_CHIPID_STM32_L496X || sl->chip_id == STLINK_CHIPID_STM32_L4RX) { - // This chip use dual banked flash + // this chip use dual banked flash if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { - uint32_t banksize = (uint32_t) sl->flash_size / 2; + uint32_t banksize = (uint32_t)sl->flash_size / 2; + if (flashaddr >= banksize) { flashaddr -= banksize; bker = 0x100; @@ -2007,38 +2087,47 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { } } - // For 1MB chips without the dual-bank option set, the page address will - // overflow into the BKER bit, which gives us the correct bank:page value. - return bker | flashaddr/(uint32_t)sl->flash_pgsz; + // For 1MB chips without the dual-bank option set, the page address will overflow + // into the BKER bit, which gives us the correct bank:page value. + return(bker | flashaddr / (uint32_t)sl->flash_pgsz); } -uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ +uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || (sl->chip_id == STLINK_CHIPID_STM32_F4) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || - (sl->chip_id == STLINK_CHIPID_STM32_F411RE) || - (sl->chip_id == STLINK_CHIPID_STM32_F446) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || - (sl->chip_id == STLINK_CHIPID_STM32_F72XXX) || - (sl->chip_id == STLINK_CHIPID_STM32_F412)) { - uint32_t sector=calculate_F4_sectornum(flashaddr); - if (sector>= 12) { - sector -= 12; + (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || + (sl->chip_id == STLINK_CHIPID_STM32_F411RE) || + (sl->chip_id == STLINK_CHIPID_STM32_F446) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || + (sl->chip_id == STLINK_CHIPID_STM32_F72XXX) || + (sl->chip_id == STLINK_CHIPID_STM32_F412)) { + uint32_t sector = calculate_F4_sectornum(flashaddr); + + if (sector >= 12) { sector -= 12; } + + if (sector < 4) { + sl->flash_pgsz = 0x4000; + } else if (sector < 5) { + sl->flash_pgsz = 0x10000; + } else { + sl->flash_pgsz = 0x20000; + } + } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || + sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { + uint32_t sector = calculate_F7_sectornum(flashaddr); + + if (sector < 4) { + sl->flash_pgsz = 0x8000; + } else if (sector < 5) { + sl->flash_pgsz = 0x20000; + } else { + sl->flash_pgsz = 0x40000; } - if (sector<4) sl->flash_pgsz=0x4000; - else if (sector<5) sl->flash_pgsz=0x10000; - else sl->flash_pgsz=0x20000; - } - else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { - uint32_t sector=calculate_F7_sectornum(flashaddr); - if (sector<4) sl->flash_pgsz=0x8000; - else if (sector<5) sl->flash_pgsz=0x20000; - else sl->flash_pgsz=0x40000; } - return (uint32_t) sl->flash_pgsz; + + return((uint32_t)sl->flash_pgsz); } /** @@ -2047,17 +2136,16 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ * @param flashaddr an address in the flash page to erase * @return 0 on success -ve on failure */ -int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) -{ +int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_L4) { - /* wait for ongoing op to finish */ + // wait for ongoing op to finish wait_flash_busy(sl); - /* unlock if locked */ + // unlock if locked unlock_flash_if(sl); - /* select the page to erase */ + // select the page to erase if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || (sl->chip_id == STLINK_CHIPID_STM32_L43X) || (sl->chip_id == STLINK_CHIPID_STM32_L46X) || @@ -2066,38 +2154,35 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) // calculate the actual bank+page from the address uint32_t page = calculate_L4_page(sl, flashaddr); - fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", page, stlink_calculate_pagesize(sl, flashaddr)); + fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", + page, stlink_calculate_pagesize(sl, flashaddr)); write_flash_cr_bker_pnb(sl, page); } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { // calculate the actual page from the address - uint32_t sector=calculate_F7_sectornum(flashaddr); - - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, stlink_calculate_pagesize(sl, flashaddr)); + uint32_t sector = calculate_F7_sectornum(flashaddr); + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", + sector, stlink_calculate_pagesize(sl, flashaddr)); write_flash_cr_snb(sl, sector); } else { // calculate the actual page from the address - uint32_t sector=calculate_F4_sectornum(flashaddr); + uint32_t sector = calculate_F4_sectornum(flashaddr); - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, stlink_calculate_pagesize(sl, flashaddr)); + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", + sector, stlink_calculate_pagesize(sl, flashaddr)); - //the SNB values for flash sectors in the second bank do not directly follow the values for the first bank on 2mb devices... - if (sector >= 12) sector += 4; + // the SNB values for flash sectors in the second bank do not directly + // follow the values for the first bank on 2mb devices... + if (sector >= 12) { sector += 4; } write_flash_cr_snb(sl, sector); } - /* start erase operation */ - set_flash_cr_strt(sl); - - /* wait for completion */ - wait_flash_busy(sl); - - /* relock the flash */ - //todo: fails to program if this is in - lock_flash(sl); + set_flash_cr_strt(sl); // start erase operation + wait_flash_busy(sl); // wait for completion + lock_flash(sl); // TODO: fails to program if this is in #if DEBUG_FLASH fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); #endif @@ -2105,6 +2190,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) uint32_t val; uint32_t flash_regs_base; + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || @@ -2114,61 +2200,61 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) flash_regs_base = STM32L_FLASH_REGS_ADDR; } - /* check if the locks are set */ + // check if the locks are set stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if ((val & (1<<0))||(val & (1<<1))) { - /* disable pecr protection */ + + if ((val & (1 << 0)) || (val & (1 << 1))) { + // disable pecr protection stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY1); stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY2); - /* check pecr.pelock is cleared */ + // check pecr.pelock is cleared stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 0)) { WLOG("pecr.pelock not clear (%#x)\n", val); - return -1; + return(-1); } - /* unlock program memory */ + // unlock program memory stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY1); stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY2); - /* check pecr.prglock is cleared */ + // check pecr.prglock is cleared stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 1)) { WLOG("pecr.prglock not clear (%#x)\n", val); - return -1; + return(-1); } } - /* set pecr.{erase,prog} */ + // set pecr.{erase,prog} val |= (1 << 9) | (1 << 3); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); -#if 0 /* fix_to_be_confirmed */ - - /* wait for sr.busy to be cleared - * MP: Test shows that busy bit is not set here. Perhaps, PM0062 is - * wrong and we do not need to wait here for clearing the busy bit. - * TEXANE: ok, if experience says so and it works for you, we comment - * it. If someone has a problem, please drop an email. +#if 0 + /* Wait for sr.busy to be cleared + * MP: Test shows that busy bit is not set here. Perhaps, PM0062 is wrong + * and we do not need to wait here for clearing the busy bit. */ do { stlink_read_debug32(sl, STM32L_FLASH_SR, &val) } while ((val & (1 << 0)) != 0); +#endif -#endif /* fix_to_be_confirmed */ - - /* write 0 to the first word of the page to be erased */ + // write 0 to the first word of the page to be erased stlink_write_debug32(sl, flashaddr, 0); - /* MP: It is better to wait for clearing the busy bit after issuing - page erase command, even though PM0062 recommends to wait before it. - Test shows that a few iterations is performed in the following loop - before busy bit is cleared.*/ - do { + /* MP: It is better to wait for clearing the busy bit after issuing page + * erase command, even though PM0062 recommends to wait before it. + * Test shows that a few iterations is performed in the following loop + * before busy bit is cleared. + */ + do stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); - } while ((val & (1 << 0)) != 0); + while ((val & (1 << 0)) != 0); - /* reset lock bits */ + // reset lock bits stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); @@ -2176,14 +2262,11 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { uint32_t val; - // Wait for any ongoing Flash operation to finish. - wait_flash_busy(sl); - // Unlock Flash if necessary. + wait_flash_busy(sl); // wait for any ongoing Flash operation to finish unlock_flash_if(sl); - // Set the 'enable Flash erase' bit. - set_flash_cr_per(sl); + set_flash_cr_per(sl); // set the 'enable Flash erase' bit - // Set the page to erase. + // set the page to erase if (sl->flash_type == STLINK_FLASH_TYPE_WB) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); @@ -2198,154 +2281,107 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. val &= ~(0x3F << 3); - val |= ((flash_page & 0x3F) << 3) | ( 1 << FLASH_CR_PER ); + val |= ((flash_page & 0x3F) << 3) | (1 << FLASH_CR_PER); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); } else if (sl->flash_type == STLINK_FLASH_TYPE_G4) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. val &= ~(0x7F << 3); - val |= ((flash_page & 0x7F) << 3) | ( 1 << FLASH_CR_PER ); + val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); } - // Set the 'start operation' bit. - set_flash_cr_strt(sl); - // Wait for the 'busy' bit to clear. - wait_flash_busy(sl); - // Clear the 'enable page erase' bit. - clear_flash_cr_per(sl); - // Re-lock the flash. + set_flash_cr_strt(sl); // set the 'start operation' bit + wait_flash_busy(sl); // wait for the 'busy' bit to clear + clear_flash_cr_per(sl); // clear the 'enable page erase' bit lock_flash(sl); } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr < FLASH_BANK2_START_ADDR))) { - /* wait for ongoing op to finish */ + ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr < FLASH_BANK2_START_ADDR))) { wait_flash_busy(sl); - - /* unlock if locked */ unlock_flash_if(sl); - - /* clear the pg bit */ - clear_flash_cr_pg(sl); - - /* set the page erase bit */ - set_flash_cr_per(sl); - - /* select the page to erase */ - write_flash_ar(sl, flashaddr); - - /* start erase operation, reset by hw with bsy bit */ - set_flash_cr_strt(sl); - - /* wait for completion */ + clear_flash_cr_pg(sl); // clear the pg bit + set_flash_cr_per(sl); // set the page erase bit + write_flash_ar(sl, flashaddr); // select the page to erase + set_flash_cr_strt(sl); // start erase operation, reset by hw with busy bit wait_flash_busy(sl); - - /* relock the flash */ lock_flash(sl); } else if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr >= FLASH_BANK2_START_ADDR)) { - /* wait for ongoing op to finish */ wait_flash_busy(sl); - - /* unlock if locked */ unlock_flash_if(sl); - - /* set the page erase bit */ - set_flash_cr2_per(sl); - - /* select the page to erase */ - write_flash_ar2(sl, flashaddr); - - /* start erase operation, reset by hw with bsy bit */ - set_flash_cr2_strt(sl); - - /* wait for completion */ + set_flash_cr2_per(sl); // set the page erase bit + write_flash_ar2(sl, flashaddr); // select the page to erase + set_flash_cr2_strt(sl); // start erase operation, reset by hw with busy bit wait_flash_busy(sl); - - /* relock the flash */ lock_flash(sl); } else { WLOG("unknown coreid %x, page erase failed\n", sl->core_id); - return -1; + return(-1); } - /* todo: verify the erased page */ - - return 0; + // TODO: verify the erased page + return(0); } int stlink_erase_flash_mass(stlink_t *sl) { - /* TODO: User MER bit to mass-erase G0, G4, WB series. */ + // TODO: User MER bit to mass-erase G0, G4, WB series. if (sl->flash_type == STLINK_FLASH_TYPE_L0 || sl->flash_type == STLINK_FLASH_TYPE_WB) { - /* erase each page */ - int i = 0, num_pages = (int)(sl->flash_size/sl->flash_pgsz); + // erase each page + int i = 0, num_pages = (int)(sl->flash_size / sl->flash_pgsz); + for (i = 0; i < num_pages; i++) { - /* addr must be an addr inside the page */ - stm32_addr_t addr = (stm32_addr_t) sl->flash_base + i * (stm32_addr_t) sl->flash_pgsz; + // addr must be an addr inside the page + stm32_addr_t addr = (stm32_addr_t)sl->flash_base + i * (stm32_addr_t)sl->flash_pgsz; + if (stlink_erase_flash_page(sl, addr) == -1) { WLOG("Failed to erase_flash_page(%#zx) == -1\n", addr); - return -1; + return(-1); } - fprintf(stdout,"-> Flash page at %5d/%5d erased\n", i, num_pages); + + fprintf(stdout, "-> Flash page at %5d/%5d erased\n", i, num_pages); fflush(stdout); } + fprintf(stdout, "\n"); } else { - /* wait for ongoing op to finish */ wait_flash_busy(sl); - - /* unlock if locked */ unlock_flash_if(sl); - - /* set the mass erase bit */ - set_flash_cr_mer(sl,1); - - /* start erase operation, reset by hw with bsy bit */ - set_flash_cr_strt(sl); + set_flash_cr_mer(sl, 1); // set the mass erase bit + set_flash_cr_strt(sl); // start erase operation, reset by hw with busy bit if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - /* set the mass erase bit in bank 2 */ - set_flash_cr2_mer(sl,1); - - /* start erase operation in bank 2 */ - set_flash_cr2_strt(sl); + set_flash_cr2_mer(sl, 1); // set the mass erase bit in bank 2 + set_flash_cr2_strt(sl); // start erase operation in bank 2 } - /* wait for completion */ wait_flash_busy_progress(sl); - check_flash_error(sl); - - /* relock the flash */ lock_flash(sl); - /* reset the mass erase bit */ - set_flash_cr_mer(sl,0); + set_flash_cr_mer(sl, 0); // reset the mass erase bit if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - /* reset the mass erase bit in bank 2 */ - set_flash_cr2_mer(sl,0); + set_flash_cr2_mer(sl, 0); // reset the mass erase bit in bank 2 } - /* todo: verify the erased memory */ + // TODO: verify the erased memory } - return 0; + + return(0); } int stlink_fcheck_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { - /* check the contents of path are at addr */ + // check the contents of path are at addr int res; mapped_file_t mf = MAPPED_FILE_INITIALIZER; - if (map_file(&mf, path) == -1) - return -1; + if (map_file(&mf, path) == -1) { return(-1); } res = check_file(sl, &mf, addr); - unmap_file(&mf); - - return res; + return(res); } /** @@ -2358,32 +2394,34 @@ int stlink_fcheck_flash(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, unsigned length) { size_t off; - size_t cmp_size = (sl->flash_pgsz > 0x1800)? 0x1800:sl->flash_pgsz; + size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; ILOG("Starting verification of write complete\n"); + for (off = 0; off < length; off += cmp_size) { size_t aligned_size; - /* adjust last page size */ - if ((off + cmp_size) > length) - cmp_size = length - off; + // adjust last page size + if ((off + cmp_size) > length) { cmp_size = length - off; } aligned_size = cmp_size; - if (aligned_size & (4 - 1)) - aligned_size = (cmp_size + 4) & ~(4 - 1); - stlink_read_mem32(sl, address + (uint32_t) off, aligned_size); + if (aligned_size & (4 - 1)) { aligned_size = (cmp_size + 4) & ~(4 - 1); } + + stlink_read_mem32(sl, address + (uint32_t)off, aligned_size); if (memcmp(sl->q_buf, data + off, cmp_size)) { ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); - return -1; + return(-1); } } + ILOG("Flash written and verified! jolly good!\n"); - return 0; + return(0); } -int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len, uint32_t pagesize) { +int stm32l1_write_half_pages( + stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len, uint32_t pagesize) { unsigned int count; unsigned int num_half_pages = len / pagesize; uint32_t val; @@ -2400,215 +2438,223 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uin } ILOG("Starting Half page flash write for STM32L core id\n"); - /* flash loader initialization */ + + /* Flash loader initialisation */ if (stlink_flash_loader_init(sl, &fl) == -1) { WLOG("stlink_flash_loader_init() == -1\n"); - return -1; + return(-1); } - /* Unlock already done */ + + // unlock already done stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << FLASH_L1_FPRG); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); val |= (1 << FLASH_L1_PROG); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + do { stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); } while ((val & (1 << 0)) != 0); - for (count = 0; count < num_half_pages; count ++) { - if (stlink_flash_loader_run(sl, &fl, addr + count * pagesize, base + count * pagesize, pagesize) == -1) { + for (count = 0; count < num_half_pages; count++) { + if (stlink_flash_loader_run( + sl, &fl, addr + count * pagesize, base + count * pagesize, pagesize) == -1) { WLOG("l1_stlink_flash_loader_run(%#zx) failed! == -1\n", addr + count * pagesize); stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val &= ~((1 << FLASH_L1_FPRG) |(1 << FLASH_L1_PROG)); + val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - return -1; + return(-1); } - /* wait for sr.busy to be cleared */ + + // wait for sr.busy to be cleared if (sl->verbose >= 1) { - /* show progress. writing procedure is slow - and previous errors are misleading */ + // show progress; writing procedure is slow and previous errors are misleading fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); fflush(stdout); } + do { stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); } while ((val & (1 << 0)) != 0); } + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val &= ~(1 << FLASH_L1_PROG); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val &= ~(1 << FLASH_L1_FPRG); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - - return 0; + return(0); } -int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len, uint8_t eraseonly) { +int stlink_write_flash( + stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len, uint8_t eraseonly) { size_t off; flash_loader_t fl; - ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", - len, len, addr, addr); - /* check addr range is inside the flash */ + ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr); + // check addr range is inside the flash stlink_calculate_pagesize(sl, addr); + if (addr < sl->flash_base) { ELOG("addr too low %#x < %#x\n", addr, sl->flash_base); - return -1; + return(-1); } else if ((addr + len) < addr) { ELOG("addr overruns\n"); - return -1; + return(-1); } else if ((addr + len) > (sl->flash_base + sl->flash_size)) { ELOG("addr too high\n"); - return -1; + return(-1); } else if (addr & 1) { ELOG("unaligned addr 0x%x\n", addr); - return -1; + return(-1); } else if (len & 1) { WLOG("unaligned len 0x%x -- padding with zero\n", len); len += 1; } else if (addr & (sl->flash_pgsz - 1)) { - ELOG("addr not a multiple of current pagesize (%zd bytes), not supported, check page start address and compare with flash module organisation in related ST reference manual of your device.\n", sl->flash_pgsz); - return -1; + ELOG("addr not a multiple of current pagesize (%zd bytes), not supported, " + "check page start address and compare with flash module organisation " + "in related ST reference manual of your device.\n", sl->flash_pgsz); + return(-1); } - // Make sure we've loaded the context with the chip details + // make sure we've loaded the context with the chip details stlink_core_id(sl); - /* erase each page */ + + // Erase each page int page_count = 0; - for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + (uint32_t) off)) { + + for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + (uint32_t)off)) { // addr must be an addr inside the page - if (stlink_erase_flash_page(sl, addr + (uint32_t) off) == -1) { + if (stlink_erase_flash_page(sl, addr + (uint32_t)off) == -1) { ELOG("Failed to erase_flash_page(%#zx) == -1\n", addr + off); - return -1; + return(-1); } - ILOG("Flash page at addr: 0x%08lx erased\n", - (unsigned long)(addr + off)); + + ILOG("Flash page at addr: 0x%08lx erased\n", (unsigned long)(addr + off)); page_count++; } + ILOG("Finished erasing %d pages of %d (%#x) bytes\n", - page_count, sl->flash_pgsz, sl->flash_pgsz); + page_count, sl->flash_pgsz, sl->flash_pgsz); - if (eraseonly) - return 0; + if (eraseonly) { return(0); } if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_L4)) { - /* todo: check write operation */ + // TODO: check write operation ILOG("Starting Flash write for F2/F4/L4\n"); - /* flash loader initialization */ + + // Flash loader initialisation if (stlink_flash_loader_init(sl, &fl) == -1) { ELOG("stlink_flash_loader_init() == -1\n"); - return -1; + return(-1); } - /* First unlock the cr */ - unlock_flash_if(sl); + unlock_flash_if(sl); // first unlock the cr - /* TODO: Check that Voltage range is 2.7 - 3.6 V */ + // TODO: Check that Voltage range is 2.7 - 3.6 V if ((sl->chip_id != STLINK_CHIPID_STM32_L4) && (sl->chip_id != STLINK_CHIPID_STM32_L43X) && (sl->chip_id != STLINK_CHIPID_STM32_L46X) && (sl->chip_id != STLINK_CHIPID_STM32_L496X) && (sl->chip_id != STLINK_CHIPID_STM32_L4RX)) { - if ( sl->version.stlink_v == 1){ - printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes on F4 devices\n"); + if ( sl->version.stlink_v == 1) { + printf("STLINK V1 cannot read voltage, defaulting to 32-bit " + "writes on F4 devices\n"); write_flash_cr_psiz(sl, 2); - } - else { - /* set parallelisim to 32 bit*/ + } else { + // set parallelism to 32 bit int voltage = stlink_target_voltage(sl); + if (voltage == -1) { printf("Failed to read Target voltage\n"); - return voltage; + return(voltage); } else if (voltage > 2700) { printf("enabling 32-bit flash writes\n"); write_flash_cr_psiz(sl, 2); } else { - printf("Target voltage (%d mV) too low for 32-bit flash, using 8-bit flash writes\n", voltage); + printf("Target voltage (%d mV) too low for 32-bit flash, " + "using 8-bit flash writes\n", voltage); write_flash_cr_psiz(sl, 0); } } } else { - /* L4 does not have a byte-write mode */ + // L4 does not have a byte-write mode int voltage = stlink_target_voltage(sl); + if (voltage == -1) { printf("Failed to read Target voltage\n"); - return voltage; + return(voltage); } else if (voltage < 1710) { printf("Target voltage (%d mV) too low for flash writes!\n", voltage); - return -1; + return(-1); } } - /* set programming mode */ + // set programming mode set_flash_cr_pg(sl); size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; + for (off = 0; off < len;) { size_t size = len - off > buf_size ? buf_size : len - off; - printf("size: %u\n", (unsigned int)size); - if (stlink_flash_loader_run(sl, &fl, addr + (uint32_t) off, base + off, size) == -1) { + if (stlink_flash_loader_run(sl, &fl, addr + (uint32_t)off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); - return -1; + return(-1); } off += size; } - /* Relock flash */ clear_flash_cr_pg(sl); lock_flash(sl); - } //STM32F4END - else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + // STM32F4END + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { fprintf(stdout, "Writing\r\n"); fflush(stdout); - // Wait for any ongoing operations to finish. wait_flash_busy(sl); - // Unlock flash if necessary. - unlock_flash_if(sl); - // Set PG 'allow programming' bit. - set_flash_cr_pg(sl); - // Write all words. + unlock_flash_if(sl); // unlock flash if necessary + set_flash_cr_pg(sl); // set PG 'allow programming' bit + // write all words. off = 0; - fprintf(stdout, "Starting %3u page write\r\n", (unsigned int)(len/sl->flash_pgsz)); + fprintf(stdout, "Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); fflush(stdout); + for ( ; off < len; off += sizeof(uint32_t)) { uint32_t data; - if (off > 254) - fprintf(stdout, "\r"); - if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) { + if (off > 254) { fprintf(stdout, "\r"); } + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off/sl->flash_pgsz), - (unsigned int)(len/sl->flash_pgsz)); + (unsigned int)(off / sl->flash_pgsz), + (unsigned int)(len / sl->flash_pgsz)); fflush(stdout); } - write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); - stlink_write_debug32(sl, addr + (uint32_t) off, data); - // Wait for 'busy' bit in FLASH_SR to clear. - wait_flash_busy(sl); + + write_uint32((unsigned char*)&data, *(uint32_t*)(base + off)); + stlink_write_debug32(sl, addr + (uint32_t)off, data); + wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear } - // (Flash writes happen 2 words at a time.) + + // flash writes happen as 2 words at a time if ((off / sizeof(uint32_t)) % 2 != 0) { - // Write a single word of zeros. - stlink_write_debug32(sl, addr + (uint32_t) off, 0); - // Wait for 'busy' bit in FLASH_SR to clear. - wait_flash_busy(sl); + stlink_write_debug32(sl, addr + (uint32_t)off, 0); // write a single word of zeros + wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear } - // Reset PG bit. - clear_flash_cr_pg(sl); - // Re-lock flash. + + clear_flash_cr_pg(sl); // reset PG bit. lock_flash(sl); - } - else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - /* use fast word write. todo: half page. */ + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + // use fast word write + // TODO: half page uint32_t val; uint32_t flash_regs_base; uint32_t pagesize; @@ -2624,123 +2670,144 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t pagesize = L1_WRITE_BLOCK_SIZE; } - /* todo: check write operation */ + // TODO: check write operation - /* disable pecr protection */ + // disable pecr protection stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY1); stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY2); - /* check pecr.pelock is cleared */ + // check pecr.pelock is cleared stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 0)) { fprintf(stderr, "pecr.pelock not clear\n"); - return -1; + return(-1); } - /* unlock program memory */ + // unlock program memory stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY1); stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY2); - /* check pecr.prglock is cleared */ + // check pecr.prglock is cleared stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 1)) { fprintf(stderr, "pecr.prglock not clear\n"); - return -1; + return(-1); } + off = 0; + if (len > pagesize) { if (stm32l1_write_half_pages(sl, addr, base, len, pagesize) == -1) { - /* This may happen on a blank device! */ + // this may happen on a blank device! WLOG("\nwrite_half_pages failed == -1\n"); } else { - off = (len / pagesize)*pagesize; + off = (len / pagesize) * pagesize; } } - /* write remainingword in program memory */ + // write remaining word in program memory for ( ; off < len; off += sizeof(uint32_t)) { uint32_t data; - if (off > 254) - fprintf(stdout, "\r"); - if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) { + if (off > 254) { fprintf(stdout, "\r"); } + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off/sl->flash_pgsz), - (unsigned int)(len/sl->flash_pgsz)); + (unsigned int)(off / sl->flash_pgsz), + (unsigned int)(len / sl->flash_pgsz)); fflush(stdout); } - write_uint32((unsigned char*) &data, *(uint32_t*) (base + off)); - stlink_write_debug32(sl, addr + (uint32_t) off, data); + write_uint32((unsigned char*)&data, *(uint32_t*)(base + off)); + stlink_write_debug32(sl, addr + (uint32_t)off, data); - /* wait for sr.busy to be cleared */ + // wait for sr.busy to be cleared do { stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); } while ((val & (1 << 0)) != 0); - /* todo: check redo write operation */ - + // TODO: check redo write operation } + fprintf(stdout, "\n"); - /* reset lock bits */ + // reset lock bits stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { ILOG("Starting Flash write for VL/F0/F3/F1_XL core id\n"); - /* flash loader initialization */ + + // flash loader initialisation if (stlink_flash_loader_init(sl, &fl) == -1) { ELOG("stlink_flash_loader_init() == -1\n"); - return -1; + return(-1); } int write_block_count = 0; + for (off = 0; off < len; off += sl->flash_pgsz) { - /* adjust last write size */ + // adjust last write size size_t size = sl->flash_pgsz; - if ((off + sl->flash_pgsz) > len) size = len - off; - /* unlock and set programming mode */ + if ((off + sl->flash_pgsz) > len) { size = len - off; } + + // unlock and set programming mode unlock_flash_if(sl); - if (sl->flash_type != STLINK_FLASH_TYPE_F1_XL) { - set_flash_cr_pg(sl); - } + + if (sl->flash_type != STLINK_FLASH_TYPE_F1_XL) { set_flash_cr_pg(sl); } + DLOG("Finished unlocking flash, running loader!\n"); - if (stlink_flash_loader_run(sl, &fl, addr + (uint32_t) off, base + off, size) == -1) { + + if (stlink_flash_loader_run(sl, &fl, addr + (uint32_t)off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); - return -1; + return(-1); } + lock_flash(sl); + if (sl->verbose >= 1) { - /* show progress. writing procedure is slow - and previous errors are misleading */ - fprintf(stdout, "\r%3u/%lu pages written", ++write_block_count, (unsigned long)((len+sl->flash_pgsz-1)/sl->flash_pgsz)); + // show progress; writing procedure is slow and previous errors are misleading + fprintf(stdout, "\r%3u/%lu pages written", ++write_block_count, + (unsigned long)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); fflush(stdout); } } + fprintf(stdout, "\n"); } else { ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); - return -1; + return(-1); } - return stlink_verify_write_flash(sl, addr, base, len); + return(stlink_verify_write_flash(sl, addr, base, len)); } -// note: length not checked +// TODO: length not checked static uint8_t stlink_parse_hex(const char* hex) { uint8_t d[2]; + for (int i = 0; i < 2; ++i) { char c = *(hex + i); - if (c >= '0' && c <= '9') d[i] = c - '0'; - else if (c >= 'A' && c <= 'F') d[i] = c - 'A' + 10; - else if (c >= 'a' && c <= 'f') d[i] = c - 'a' + 10; - else return 0; // error + + if (c >= '0' && c <= '9') { + d[i] = c - '0'; + } else if (c >= 'A' && c <= 'F') { + d[i] = c - 'A' + 10; + } else if (c >= 'a' && c <= 'f') { + d[i] = c - 'a' + 10; + } else { + return(0); // error + } } - return (d[0] << 4) | (d[1]); + + return((d[0] << 4) | (d[1])); } -int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin) { +int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, + uint32_t * begin) { int res = 0; *begin = UINT32_MAX; uint8_t* data = NULL; @@ -2764,6 +2831,7 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, *size = (end - *begin) + 1; data = calloc(*size, 1); // use calloc to get NULL if out of memory + if (!data) { ELOG("Cannot allocate %d bytes\n", *size); res = -1; @@ -2774,6 +2842,7 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, } FILE* file = fopen(path, "r"); + if (!file) { ELOG("Cannot open file\n"); res = -1; @@ -2781,10 +2850,11 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, } uint32_t lba = 0; + char line[1 + 5 * 2 + 255 * 2 + 2]; - char line[1 + 5*2 + 255*2 + 2]; while (fgets(line, sizeof(line), file)) { - if (line[0] == '\n' || line[0] == '\r') continue; // skip empty lines + if (line[0] == '\n' || line[0] == '\r') { continue; } // skip empty lines + if (line[0] != ':') { // no marker - wrong file format ELOG("Wrong file format - no marker\n"); res = -1; @@ -2792,18 +2862,19 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, } size_t l = strlen(line); - while (l > 0 && (line[l-1] == '\n' || line[l-1] == '\r')) --l; // trim EoL - if ((l < 11) || (l == (sizeof(line)-1))) { // line too short or long - wrong file format + + while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r')) { --l; } // trim EoL + + if ((l < 11) || (l == (sizeof(line) - 1))) { // line too short or long - wrong file format ELOG("Wrong file format - wrong line length\n"); res = -1; break; } - // check sum - uint8_t chksum = 0; - for (size_t i = 1; i < l; i += 2) { - chksum += stlink_parse_hex(line + i); - } + uint8_t chksum = 0; // check sum + + for (size_t i = 1; i < l; i += 2) { chksum += stlink_parse_hex(line + i); } + if (chksum != 0) { ELOG("Wrong file format - checksum mismatch\n"); res = -1; @@ -2811,64 +2882,61 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, } uint8_t reclen = stlink_parse_hex(line + 1); - if (((uint32_t)reclen + 5)*2 + 1 != l) { + + if (((uint32_t)reclen + 5) * 2 + 1 != l) { ELOG("Wrong file format - record length mismatch\n"); res = -1; break; } - uint16_t offset = ((uint16_t)stlink_parse_hex(line + 3) << 8) | ((uint16_t)stlink_parse_hex(line + 5)); - uint8_t rectype = stlink_parse_hex(line + 7); - - switch(rectype) { - case 0: // data - if (scan == 0) { - uint32_t b = lba + offset; - uint32_t e = b + reclen - 1; - if (b < *begin) *begin = b; - if (e > end) end = e; - } - else { - for (uint8_t i = 0; i < reclen; ++i) { - uint8_t b = stlink_parse_hex(line + 9 + i*2); - uint32_t addr = lba + offset + i; - if (addr >= *begin && addr <= end) { - data[addr - *begin] = b; - } - } - } - break; + uint16_t offset = ((uint16_t)stlink_parse_hex(line + 3) << 8) | + ((uint16_t)stlink_parse_hex(line + 5)); + uint8_t rectype = stlink_parse_hex(line + 7); - case 1: // EoF - eof_found = true; - break; + switch (rectype) { + case 0: /* Data */ + if (scan == 0) { + uint32_t b = lba + offset; + uint32_t e = b + reclen - 1; - case 2: // Extended Segment Address, unexpected - res = -1; - break; + if (b < *begin) { *begin = b; } - case 3: // Start Segment Address, unexpected - res = -1; - break; + if (e > end) { end = e; } + } else { + for (uint8_t i = 0; i < reclen; ++i) { + uint8_t b = stlink_parse_hex(line + 9 + i * 2); + uint32_t addr = lba + offset + i; - case 4: // Extended Linear Address - if (reclen == 2) { - lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | ((uint32_t)stlink_parse_hex(line + 11) << 16); - } - else { - ELOG("Wrong file format - wrong LBA length\n"); - res = -1; + if (addr >= *begin && addr <= end) { data[addr - *begin] = b; } } - break; - - case 5: // Start Linear Address - expected, but ignore - break; - - default: - ELOG("Wrong file format - unexpected record type %d\n", rectype); + } + break; + case 1: /* EoF */ + eof_found = true; + break; + case 2: /* Extended Segment Address, unexpected */ + res = -1; + break; + case 3: /* Start Segment Address, unexpected */ + res = -1; + break; + case 4: /* Extended Linear Address */ + if (reclen == 2) { + lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | + ((uint32_t)stlink_parse_hex(line + 11) << 16); + } else { + ELOG("Wrong file format - wrong LBA length\n"); res = -1; + } + break; + case 5: /* Start Linear Address - expected, but ignore */ + break; + default: + ELOG("Wrong file format - unexpected record type %d\n", rectype); + res = -1; } - if (res != 0) break; + + if (res != 0) { break; } } fclose(file); @@ -2876,55 +2944,56 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, if (res == 0) { *mem = data; - } - else { + } else { free(data); } - return res; + return(res); } uint8_t stlink_get_erased_pattern(stlink_t *sl) { - if (sl->flash_type == STLINK_FLASH_TYPE_L0) - return 0x00; - else - return 0xff; + if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + return(0x00); + } else { + return(0xff); + } } int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr) { - /* write the block in flash at addr */ + /* Write the block in flash at addr */ int err; unsigned int num_empty, idx; uint8_t erased_pattern = stlink_get_erased_pattern(sl); /* - * This optimization may cause unexpected garbage data remaining - * Turned off by default + * This optimisation may cause unexpected garbage data remaining. + * Therfore it is turned off by default. */ if (sl->opt) { idx = (unsigned int)length; - for (num_empty = 0; num_empty != length; ++num_empty) { - if (data[--idx] != erased_pattern) { - break; - } - } - /* Round down to words */ - num_empty -= (num_empty & 3); + + for (num_empty = 0; num_empty != length; ++num_empty) + if (data[--idx] != erased_pattern) { break; } + + num_empty -= (num_empty & 3); // Round down to words + if (num_empty != 0) { ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); } } else { num_empty = 0; } + /* - * TODO: investigate: - * a kind of weird behaviour here: - * if the file is identified to be all-empty and four-bytes aligned, - * still flash the whole file even if ignoring message is printed + * TODO: investigate a kind of weird behaviour here: + * If the file is identified to be all-empty and four-bytes aligned, + * still flash the whole file even if ignoring message is printed. */ - err = stlink_write_flash(sl, addr, data, (num_empty == length) ? (uint32_t) length : (uint32_t) length - num_empty, num_empty == length); + err = stlink_write_flash(sl, addr, data, + (num_empty == length) ? (uint32_t)length : (uint32_t)length - num_empty, + num_empty == length); stlink_fwrite_finalize(sl, addr); - return err; + return(err); } /** @@ -2935,7 +3004,7 @@ int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr * @return 0 on success, -ve on failure. */ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { - /* write the file in flash at addr */ + /* Write the file in flash at addr */ int err; unsigned int num_empty, idx; uint8_t erased_pattern = stlink_get_erased_pattern(sl); @@ -2943,7 +3012,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { if (map_file(&mf, path) == -1) { ELOG("map_file() == -1\n"); - return -1; + return(-1); } printf("file %s ", path); @@ -2951,30 +3020,32 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { stlink_checksum(&mf); if (sl->opt) { - idx = (unsigned int) mf.len; + idx = (unsigned int)mf.len; + for (num_empty = 0; num_empty != mf.len; ++num_empty) { - if (mf.base[--idx] != erased_pattern) { - break; - } + if (mf.base[--idx] != erased_pattern) { break; } } - /* Round down to words */ - num_empty -= (num_empty & 3); + + num_empty -= (num_empty & 3); // round down to words + if (num_empty != 0) { ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); } } else { num_empty = 0; } + /* - * TODO: investigate: - * a kind of weird behaviour here: - * if the file is identified to be all-empty and four-bytes aligned, - * still flash the whole file even if ignoring message is printed + * TODO: investigate a kind of weird behaviour here: + * If the file is identified to be all-empty and four-bytes aligned, + * still flash the whole file even if ignoring message is printed. */ - err = stlink_write_flash(sl, addr, mf.base, (num_empty == mf.len) ? (uint32_t) mf.len : (uint32_t) mf.len - num_empty, num_empty == mf.len); + err = stlink_write_flash(sl, addr, mf.base, + (num_empty == mf.len) ? (uint32_t)mf.len : (uint32_t)mf.len - num_empty, + num_empty == mf.len); stlink_fwrite_finalize(sl, addr); unmap_file(&mf); - return err; + return(err); } /** @@ -2984,20 +3055,19 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - +static int stlink_write_option_bytes_gx( + stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { + /* Write options bytes */ uint32_t val; int ret = 0; - (void) len; - - /* Write options bytes */ + (void)len; uint32_t data; - write_uint32((unsigned char*) &data, *(uint32_t*) (base)); - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + write_uint32((unsigned char*)&data, *(uint32_t*)(base)); + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); - /* Set Options Start bit */ + // Set Options Start bit stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); @@ -3006,12 +3076,12 @@ static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, stm32_addr_ ret = check_flash_error(sl); - /* Reload options */ + // Reload options stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - return ret; + return(ret); } /** @@ -3021,38 +3091,36 @@ static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t* base, stm32_addr_ * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { +static int stlink_write_option_bytes_l0( + stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { uint32_t flash_base = get_stm32l0_flash_base(sl); uint32_t val; uint32_t data; int ret = 0; - /* Clear errors */ + // Clear errors stlink_write_debug32(sl, flash_base + FLASH_SR_OFF, STM32L0_FLASH_REGS_ADDR); while (len != 0) { - /* Write options bytes */ - write_uint32((unsigned char*) &data, *(uint32_t*) (base)); + write_uint32((unsigned char*)&data, *(uint32_t*)(base)); // write options bytes WLOG("Writing option bytes %#10x to %#10x\n", data, addr); stlink_write_debug32(sl, addr, data); - wait_flash_busy(sl); - if ((ret = check_flash_error(sl))) - break; + if ((ret = check_flash_error(sl))) { break; } - len-=4; - addr+=4; - base+=4; + len -= 4; + addr += 4; + base += 4; } - /* Reload options */ + // Reload options stlink_read_debug32(sl, flash_base + FLASH_PECR_OFF, &val); val |= (1 << STM32L0_FLASH_OBL_LAUNCH); stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); - return ret; + return(ret); } /** @@ -3062,36 +3130,34 @@ static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t* base, stm32_addr_ * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l4(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { +static int stlink_write_option_bytes_l4( + stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { uint32_t val; int ret = 0; + (void)addr; + (void)len; - (void) addr; - (void) len; - - /* Write options bytes */ + // write options bytes uint32_t data; - write_uint32((unsigned char*) &data, *(uint32_t*) (base)); + write_uint32((unsigned char*)&data, *(uint32_t*)(base)); WLOG("Writing option bytes 0x%04x\n", data); stlink_write_debug32(sl, STM32L4_FLASH_OPTR, data); - /* Set Options Start bit */ + // set options start bit stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); val |= (1 << STM32L4_FLASH_CR_OPTSTRT); stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - /* Wait for 'busy' bit in FLASH_SR to clear. */ wait_flash_busy(sl); - ret = check_flash_error(sl); - /* apply options bytes immediate */ + // apply options bytes immediate stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - return ret; + return(ret); } @@ -3101,25 +3167,24 @@ static int stlink_write_option_bytes_l4(stlink_t *sl, uint8_t* base, stm32_addr_ * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { +static int stlink_write_option_bytes_f4( + stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { uint32_t option_byte; int ret = 0; + (void)addr; + (void)len; - (void) addr; - (void) len; - - write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); + write_uint32((unsigned char*)&option_byte, *(uint32_t*)(base)); - /* write option byte, ensuring we dont lock opt, and set strt bit */ - stlink_write_debug32(sl, FLASH_F4_OPTCR, (option_byte & ~(1 << FLASH_F4_OPTCR_LOCK)) | (1 << FLASH_F4_OPTCR_START)); + // write option byte, ensuring we dont lock opt, and set strt bit + stlink_write_debug32(sl, FLASH_F4_OPTCR, + (option_byte & ~(1 << FLASH_F4_OPTCR_LOCK)) | (1 << FLASH_F4_OPTCR_START)); wait_flash_busy(sl); - ret = check_flash_error(sl); - /* option bytes are reloaded at reset only, no obl. */ - - return ret; + // option bytes are reloaded at reset only, no obl. */ + return(ret); } /** @@ -3129,7 +3194,7 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_ * @return 0 on success, -ve on failure. */ int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); + return(stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte)); } /** @@ -3139,7 +3204,7 @@ int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) { * @return 0 on success, -ve on failure. */ int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); + return(stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte)); } /** @@ -3149,16 +3214,16 @@ int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { * @return 0 on success, -ve on failure. */ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); + return(stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte)); } /** * Read first option bytes -* @param sl -* @param option_byte option value -* @return 0 on success, -ve on failure. -*/ + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_debug32(sl, sl->option_base, option_byte); + return(stlink_read_debug32(sl, sl->option_base, option_byte)); } /** @@ -3170,21 +3235,21 @@ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) { if (sl->option_base == 0) { ELOG("Option bytes read is currently not supported for connected chip\n"); - return -1; + return(-1); } switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F2: - return stlink_read_option_bytes_f2(sl, option_byte); - case STLINK_CHIPID_STM32_F446: - return stlink_read_option_bytes_f4(sl, option_byte); - case STLINK_CHIPID_STM32_G0_CAT1: - case STLINK_CHIPID_STM32_G0_CAT2: - case STLINK_CHIPID_STM32_G4_CAT2: - case STLINK_CHIPID_STM32_G4_CAT3: - return stlink_read_option_bytes_Gx(sl, option_byte); - default: - return stlink_read_option_bytes_generic(sl, option_byte); + case STLINK_CHIPID_STM32_F2: + return(stlink_read_option_bytes_f2(sl, option_byte)); + case STLINK_CHIPID_STM32_F446: + return(stlink_read_option_bytes_f4(sl, option_byte)); + case STLINK_CHIPID_STM32_G0_CAT1: + case STLINK_CHIPID_STM32_G0_CAT2: + case STLINK_CHIPID_STM32_G4_CAT2: + case STLINK_CHIPID_STM32_G4_CAT3: + return(stlink_read_option_bytes_Gx(sl, option_byte)); + default: + return(stlink_read_option_bytes_generic(sl, option_byte)); } } @@ -3196,7 +3261,7 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) { */ int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { WLOG("About to write option byte %#10x to target.\n", option_byte); - return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *) &option_byte, 4); + return(stlink_write_option_bytes(sl, sl->option_base, (uint8_t *)&option_byte, 4)); } /** @@ -3211,60 +3276,60 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui if (sl->option_base == 0) { ELOG("Option bytes writing is currently not supported for connected chip\n"); - return -1; + return(-1); } if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { ELOG("Option bytes start address out of Option bytes range\n"); - return -1; + return(-1); } if (addr + len > sl->option_base + sl->option_size) { ELOG("Option bytes data too long\n"); - return -1; + return(-1); } wait_flash_busy(sl); if (unlock_flash_if(sl)) { ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; + return(-1); } if (unlock_flash_option_if(sl)) { ELOG("Flash option unlock failed!\n"); - return -1; + return(-1); } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F4: - ret = stlink_write_option_bytes_f4(sl, base, addr, len); - break; - case STLINK_FLASH_TYPE_L0: - ret = stlink_write_option_bytes_l0(sl, base, addr, len); - break; - case STLINK_FLASH_TYPE_L4: - ret = stlink_write_option_bytes_l4(sl, base, addr, len); - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - ret = stlink_write_option_bytes_gx(sl, base, addr, len); - break; - default: - ELOG("Option bytes writing is currently not implemented for connected chip\n"); - break; + case STLINK_FLASH_TYPE_F4: + ret = stlink_write_option_bytes_f4(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_L0: + ret = stlink_write_option_bytes_l0(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_L4: + ret = stlink_write_option_bytes_l4(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + ret = stlink_write_option_bytes_gx(sl, base, addr, len); + break; + default: + ELOG("Option bytes writing is currently not implemented for connected chip\n"); + break; } - if (ret) + if (ret) { ELOG("Flash option write failed!\n"); - else - ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + } else { + ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + } - /* Re-lock flash. */ lock_flash_option(sl); lock_flash(sl); - return ret; + return(ret); } /** @@ -3275,21 +3340,22 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui * @return 0 on success, -ve on failure. */ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr) { - /* write the file in flash at addr */ + /* Write the file in flash at addr */ int err; mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { ELOG("map_file() == -1\n"); - return -1; + return(-1); } printf("file %s ", path); md5_calculate(&mf); stlink_checksum(&mf); - err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t) mf.len); + err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t)mf.len); stlink_fwrite_finalize(sl, addr); unmap_file(&mf); - return err; + + return(err); } diff --git a/src/reg.h b/src/reg.h deleted file mode 100644 index 765ac9525..000000000 --- a/src/reg.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef STLINK_REG_H_ -#define STLINK_REG_H_ - -#define STLINK_REG_CM3_CPUID 0xE000ED00 -#define STLINK_REG_CM3_FP_CTRL 0xE0002000 -#define STLINK_REG_CM3_FP_COMP0 0xE0002008 - -/* Cortex™-M3 Technical Reference Manual */ -/* Debug Halting Control and Status Register */ -#define STLINK_REG_DHCSR 0xe000edf0 -#define STLINK_REG_DHCSR_DBGKEY 0xa05f0000 -#define STLINK_REG_DCRSR 0xe000edf4 -#define STLINK_REG_DCRDR 0xe000edf8 - -/* Application Interrupt and Reset Control Register */ -#define STLINK_REG_AIRCR 0xe000ed0c -#define STLINK_REG_AIRCR_VECTKEY 0x05fa0000 -#define STLINK_REG_AIRCR_SYSRESETREQ 0x00000004 - -#endif /* STLINK_REG_H_ */ diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index fc62bcf15..43378965c 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -1,4 +1,4 @@ -/* simple wrapper around the stlink_flash_write function */ +/* Simple wrapper around the stlink_flash_write function */ // TODO - this should be done as just a simple flag to the st-util command line... @@ -16,8 +16,7 @@ static stlink_t *connected_stlink = NULL; static void cleanup(int signum) { (void)signum; - if (connected_stlink) { - /* Switch back to mass storage mode before closing. */ + if (connected_stlink) { // switch back to mass storage mode before closing stlink_run(connected_stlink); stlink_exit_debug_mode(connected_stlink); stlink_close(connected_stlink); @@ -26,8 +25,7 @@ static void cleanup(int signum) { exit(1); } -static void usage(void) -{ +static void usage(void) { puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] {read|write} [addr] [size]"); puts("command line: ./st-flash [--debug] [--freq=] [--serial ] erase"); puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); @@ -39,37 +37,34 @@ static void usage(void) puts("example read option byte: ./st-flash --debug --reset --area=option read > option_byte"); } -int main(int ac, char** av) -{ +int main(int ac, char** av) { stlink_t* sl = NULL; struct flash_opts o; int err = -1; uint8_t * mem = NULL; o.size = 0; - if (flash_get_opts(&o, ac - 1, av + 1) == -1) - { + + if (flash_get_opts(&o, ac - 1, av + 1) == -1) { printf("invalid command line\n"); usage(); - return -1; + return(-1); } printf("st-flash %s\n", STLINK_VERSION); sl = stlink_open_usb(o.log_level, 1, (char *)o.serial, o.freq); - if (sl == NULL) { - return -1; - } + if (sl == NULL) { return(-1); } if (sl->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { printf("Failed to connect to target\n"); - return -1; + return(-1); } if ( o.flash_size != 0u && o.flash_size != sl->flash_size ) { sl->flash_size = o.flash_size; - printf("Forcing flash size: --flash=0x%08X\n",(unsigned int)sl->flash_size); + printf("Forcing flash size: --flash=0x%08X\n", (unsigned int)sl->flash_size); } sl->verbose = o.log_level; @@ -94,7 +89,7 @@ int main(int ac, char** av) } } - if (o.reset){ + if (o.reset) { if (sl->version.stlink_v > 1) { if (stlink_jtag_reset(sl, 2)) { printf("Failed to reset JTAG\n"); @@ -108,19 +103,19 @@ int main(int ac, char** av) } } - // Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 - if (sl->chip_id == STLINK_CHIPID_STM32_F4) - { - memset(sl->q_buf,0,4); - for (int i=0;i<8;i++) { - stlink_write_mem32(sl,0x40026000+0x10+0x18*i,4); - stlink_write_mem32(sl,0x40026400+0x10+0x18*i,4); - stlink_write_mem32(sl,0x40026000+0x24+0x18*i,4); - stlink_write_mem32(sl,0x40026400+0x24+0x18*i,4); + // disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 + if (sl->chip_id == STLINK_CHIPID_STM32_F4) { + memset(sl->q_buf, 0, 4); + + for (int i = 0; i < 8; i++) { + stlink_write_mem32(sl, 0x40026000 + 0x10 + 0x18 * i, 4); + stlink_write_mem32(sl, 0x40026400 + 0x10 + 0x18 * i, 4); + stlink_write_mem32(sl, 0x40026000 + 0x24 + 0x18 * i, 4); + stlink_write_mem32(sl, 0x40026400 + 0x24 + 0x18 * i, 4); } } - // Core must be halted to use RAM based flashloaders + // core must be halted to use RAM based flashloaders if (stlink_force_debug(sl)) { printf("Failed to halt the core\n"); goto on_error; @@ -131,77 +126,75 @@ int main(int ac, char** av) goto on_error; } - if (o.cmd == FLASH_CMD_WRITE) /* write */ - { + if (o.cmd == FLASH_CMD_WRITE) { // write size_t size = 0; + if (o.format == FLASH_FORMAT_IHEX) { err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr); + if (err == -1) { printf("Cannot parse %s as Intel-HEX file\n", o.filename); goto on_error; } } + if ((o.addr >= sl->flash_base) && - (o.addr < sl->flash_base + sl->flash_size)) { - if (o.format == FLASH_FORMAT_IHEX) + (o.addr < sl->flash_base + sl->flash_size)) { + if (o.format == FLASH_FORMAT_IHEX) { err = stlink_mwrite_flash(sl, mem, (uint32_t)size, o.addr); - else + } else { err = stlink_fwrite_flash(sl, o.filename, o.addr); - if (err == -1) - { + } + + if (err == -1) { printf("stlink_fwrite_flash() == -1\n"); goto on_error; } - } - else if ((o.addr >= sl->sram_base) && - (o.addr < sl->sram_base + sl->sram_size)) { - if (o.format == FLASH_FORMAT_IHEX) + } else if ((o.addr >= sl->sram_base) && + (o.addr < sl->sram_base + sl->sram_size)) { + if (o.format == FLASH_FORMAT_IHEX) { err = stlink_mwrite_sram(sl, mem, (uint32_t)size, o.addr); - else + } else { err = stlink_fwrite_sram(sl, o.filename, o.addr); - if (err == -1) - { + } + + if (err == -1) { printf("stlink_fwrite_sram() == -1\n"); goto on_error; } - } - else if ((o.addr >= sl->option_base) && - (o.addr < sl->option_base + sl->option_size)) { + } else if ((o.addr >= sl->option_base) && + (o.addr < sl->option_base + sl->option_size)) { err = stlink_fwrite_option_bytes(sl, o.filename, o.addr); - if (err == -1) - { + + if (err == -1) { printf("stlink_fwrite_option_bytes() == -1\n"); goto on_error; } - } - else if (o.area == FLASH_OPTION_BYTES){ + } else if (o.area == FLASH_OPTION_BYTES) { if (o.val == 0) { printf("attempting to set option byte to 0, abort.\n"); goto on_error; - } + } err = stlink_write_option_bytes32(sl, o.val); - if (err == -1) - { + + if (err == -1) { printf("stlink_write_option_bytes32() == -1\n"); goto on_error; } - } - else { + } else { err = -1; printf("Unknown memory region\n"); goto on_error; } - } else if (o.cmd == FLASH_CMD_ERASE) - { + } else if (o.cmd == FLASH_CMD_ERASE) { err = stlink_erase_flash_mass(sl); - if (err == -1) - { + + if (err == -1) { printf("stlink_erase_flash_mass() == -1\n"); goto on_error; } - } else if (o.cmd == CMD_RESET) - { + } else if (o.cmd == CMD_RESET) { if (sl->version.stlink_v > 1) { if (stlink_jtag_reset(sl, 2)) { printf("Failed to reset JTAG\n"); @@ -213,49 +206,47 @@ int main(int ac, char** av) printf("Failed to reset device\n"); goto on_error; } - } - else /* read */ - { - if(o.area == FLASH_OPTION_BYTES){ - uint32_t option_byte; - err = stlink_read_option_bytes32(sl, &option_byte); - if (err == -1) { - printf("could not read option bytes (%d)\n", err); - goto on_error; - } else { - printf("%x\n",option_byte); + } else { // read + if (o.area == FLASH_OPTION_BYTES) { + uint32_t option_byte; + err = stlink_read_option_bytes32(sl, &option_byte); + + if (err == -1) { + printf("could not read option bytes (%d)\n", err); + goto on_error; + } else { + printf("%x\n", option_byte); } - }else{ + } else { if ((o.addr >= sl->flash_base) && (o.size == 0) && - (o.addr < sl->flash_base + sl->flash_size)){ + (o.addr < sl->flash_base + sl->flash_size)) { o.size = sl->flash_size; - } - else if ((o.addr >= sl->sram_base) && (o.size == 0) && - (o.addr < sl->sram_base + sl->sram_size)){ + } else if ((o.addr >= sl->sram_base) && (o.size == 0) && + (o.addr < sl->sram_base + sl->sram_size)) { o.size = sl->sram_size; } + err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); - if (err == -1) - { + if (err == -1) { printf("stlink_fread() == -1\n"); goto on_error; } } } - if (o.reset){ - if (sl->version.stlink_v > 1) stlink_jtag_reset(sl, 2); + if (o.reset) { + if (sl->version.stlink_v > 1) { stlink_jtag_reset(sl, 2); } + stlink_reset(sl); } - /* success */ - err = 0; + err = 0; // success on_error: stlink_exit_debug_mode(sl); stlink_close(sl); free(mem); - return err; + return(err); } diff --git a/src/st-flash/flash.h b/src/st-flash/flash.h index 3a4dc3ec4..0b7555188 100644 --- a/src/st-flash/flash.h +++ b/src/st-flash/flash.h @@ -11,9 +11,8 @@ enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3, CMD_RESET = 4}; enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1}; -enum flash_area {FLASH_MAIN_MEMORY = 0, FLASH_SYSTEM_MEMORY = 1,FLASH_OTP = 2, FLASH_OPTION_BYTES = 3}; -struct flash_opts -{ +enum flash_area {FLASH_MAIN_MEMORY = 0, FLASH_SYSTEM_MEMORY = 1, FLASH_OTP = 2, FLASH_OPTION_BYTES = 3}; +struct flash_opts { enum flash_cmd cmd; uint8_t serial[STLINK_SERIAL_MAX_SIZE]; const char* filename; @@ -24,9 +23,9 @@ struct flash_opts enum flash_format format; enum flash_area area; uint32_t val; - size_t flash_size; /* --flash=n[k][m] */ - int opt; /* enable empty tail data drop optimization */ - int freq; /* --freq=n[k][m] frequency of JTAG/SWD */ + size_t flash_size; // --flash=n[k][m] + int opt; // enable empty tail data drop optimization + int freq; // --freq=n[k][m] frequency of JTAG/SWD bool connect_under_reset; }; diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 9d8d3225b..6d1940675 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -6,7 +6,8 @@ static bool starts_with(const char * str, const char * prefix) { size_t n = strlen(prefix); - if (strlen(str) < n) return false; + + if (strlen(str) < n) { return(false); } return (0 == strncmp(str, prefix, n)); } @@ -19,37 +20,28 @@ static int get_long_integer_from_char_array (const char *const str, uint64_t *re uint64_t value; char *tail; - // hexadecimal - if (starts_with (str, "0x") || starts_with (str, "0X")) { + if (starts_with (str, "0x") || starts_with (str, "0X")) { // hexadecimal value = strtoul (str + 2, &tail, 16); - } - // binary - else if (starts_with (str, "0b") || starts_with (str, "0B")) { + } else if (starts_with (str, "0b") || starts_with (str, "0B")) { // binary value = strtoul (str + 2, &tail, 2); - } - // octal - else if (starts_with (str, "0")) { + } else if (starts_with (str, "0")) { // octal value = strtoul (str + 1, &tail, 8); - } - // decimal - else { + } else { // decimal value = strtoul (str, &tail, 10); } if (((tail[0] == 'k') || (tail[0] == 'K')) && (tail[1] == '\0')) { value = value * 1024; - } - else if (((tail[0] == 'm') || (tail[0] == 'M')) && (tail[1] == '\0')) { + } else if (((tail[0] == 'm') || (tail[0] == 'M')) && (tail[1] == '\0')) { value = value * 1024 * 1024; + } else if (tail[0] == '\0') { + /* value not changed */ + } else { + return(-1); } - else if (tail[0] == '\0') { - // value not change - } - else { - return -1; - } + *read_value = value; - return 0; + return(0); } // support positive integer from 0 to UINT32_MAX @@ -59,28 +51,26 @@ static int get_long_integer_from_char_array (const char *const str, uint64_t *re static int get_integer_from_char_array (const char *const str, uint32_t *read_value) { uint64_t value; int result = get_long_integer_from_char_array (str, &value); + if (result != 0) { - return result; - } - else if (value > UINT32_MAX) { - fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, \ -cannot convert to int32_t\n"); - return -1; - } - else { + return(result); + } else if (value > UINT32_MAX) { + fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, cannot convert to int32_t\n"); + return(-1); + } else { *read_value = (uint32_t)value; - return 0; + return(0); } } static int invalid_args(const char *expected) { fprintf(stderr, "*** Error: Expected args for this command: %s\n", expected); - return -1; + return(-1); } static int bad_arg(const char *arg) { fprintf(stderr, "*** Error: Invalid value for %s\n", arg); - return -1; + return(-1); } int flash_get_opts(struct flash_opts* o, int ac, char** av) { @@ -91,170 +81,177 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { // options int result; + while (ac >= 1) { if (strcmp(av[0], "--version") == 0) { printf("v%s\n", STLINK_VERSION); exit(EXIT_SUCCESS); - } - else if (strcmp(av[0], "--debug") == 0) { + } else if (strcmp(av[0], "--debug") == 0) { o->log_level = DEBUG_LOG_LEVEL; - } - else if (strcmp(av[0], "--opt") == 0) { + } else if (strcmp(av[0], "--opt") == 0) { o->opt = ENABLE_OPT; - } - else if (strcmp(av[0], "--reset") == 0) { + } else if (strcmp(av[0], "--reset") == 0) { o->reset = 1; - } - else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) { + } else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) { const char * serial; + if (strcmp(av[0], "--serial") == 0) { ac--; av++; - if (ac < 1) return -1; + + if (ac < 1) { return(-1); } + serial = av[0]; - } - else { + } else { serial = av[0] + strlen("--serial="); } - /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ + + /** @todo This is not really portable, as strlen really returns size_t we need to obey + and not cast it to a signed type. */ int j = (int)strlen(serial); - int length = j / 2; // the length of the destination-array - if (j % 2 != 0) return -1; + int length = j / 2; // the length of the destination-array + + if (j % 2 != 0) { return(-1); } + for (size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { char buffer[3] = {0}; memcpy(buffer, serial + j, 2); o->serial[length - k] = (uint8_t)strtol(buffer, NULL, 16); } - } - else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { + } else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { const char * area; + if (strcmp(av[0], "--area") == 0) { ac--; av++; - if (ac < 1) return -1; + + if (ac < 1) { return(-1); } + area = av[0]; - } - else { + } else { area = av[0] + strlen("--area="); } - if (strcmp(area, "main") == 0) + + if (strcmp(area, "main") == 0) { o->area = FLASH_MAIN_MEMORY; - else if (strcmp(area, "system") == 0) + } else if (strcmp(area, "system") == 0) { o->area = FLASH_SYSTEM_MEMORY; - else if (strcmp(area, "otp") == 0) + } else if (strcmp(area, "otp") == 0) { o->area = FLASH_OTP; - else if (strcmp(area, "option") == 0) + } else if (strcmp(area, "option") == 0) { o->area = FLASH_OPTION_BYTES; - else - return -1; + } else { + return(-1); + } - } - else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) { + } else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) { const char* freq; + if (strcmp(av[0], "--freq") == 0) { ac--; av++; - if (ac < 1) return -1; + + if (ac < 1) { + return(-1); + } + freq = av[0]; - } - else { + } else { freq = av[0] + strlen("--freq="); } + if (strcmp(freq, "5K") == 0 || strcmp(freq, "5k") == 0) { o->freq = 5; - } - else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) { + } else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) { o->freq = 15; - } - else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) { + } else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) { o->freq = 25; - } - else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) { + } else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) { o->freq = 50; - } - else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) { + } else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) { o->freq = 100; - } - else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) { + } else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) { o->freq = 125; - } - else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) { + } else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) { o->freq = 240; - } - else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) { + } else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) { o->freq = 480; - } - else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) { + } else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) { o->freq = 950; - } - else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) { + } else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || + strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) { o->freq = 1200; - } - else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) { + } else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || + strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) { o->freq = 1800; - } - else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) { + } else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || + strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) { o->freq = 4000; + } else { + return(-1); } - else - return -1; - } - else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { + } else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { const char * format; + if (strcmp(av[0], "--format") == 0) { ac--; av++; - if (ac < 1) return -1; + + if (ac < 1) { return(-1); } + format = av[0]; - } - else { + } else { format = av[0] + strlen("--format="); } - if (strcmp(format, "binary") == 0) + + if (strcmp(format, "binary") == 0) { o->format = FLASH_FORMAT_BINARY; - else if (strcmp(format, "ihex") == 0) + } else if (strcmp(format, "ihex") == 0) { o->format = FLASH_FORMAT_IHEX; - else - return bad_arg("format"); - } - else if ( starts_with(av[0], "--flash=") ) { + } else { + return(bad_arg("format")); + } + } else if ( starts_with(av[0], "--flash=")) { const char *arg = av[0] + strlen("--flash="); uint32_t flash_size; result = get_integer_from_char_array(arg, &flash_size); - if (result != 0) return bad_arg ("--flash"); - else o->flash_size = (size_t) flash_size; - } - else if (strcmp(av[0],"--connect-under-reset")== 0){ + + if (result != 0) { + return(bad_arg ("--flash")); + } else { + o->flash_size = (size_t)flash_size; + } + } else if (strcmp(av[0], "--connect-under-reset") == 0) { o->connect_under_reset = true; - } - else { - break; // non-option found + } else { + break; // non-option found + } ac--; av++; } - // command and (optional) device name + /* command and (optional) device name */ while (ac >= 1) { if (strcmp(av[0], "erase") == 0) { - if (o->cmd != FLASH_CMD_NONE) return -1; + if (o->cmd != FLASH_CMD_NONE) { return(-1); } + o->cmd = FLASH_CMD_ERASE; - } - else if (strcmp(av[0], "read") == 0) { - if (o->cmd != FLASH_CMD_NONE) return -1; + } else if (strcmp(av[0], "read") == 0) { + if (o->cmd != FLASH_CMD_NONE) { return(-1); } + o->cmd = FLASH_CMD_READ; - } - else if (strcmp(av[0], "write") == 0) { - if (o->cmd != FLASH_CMD_NONE) return -1; + } else if (strcmp(av[0], "write") == 0) { + if (o->cmd != FLASH_CMD_NONE) { return(-1); } + o->cmd = FLASH_CMD_WRITE; - } - else if (strcmp(av[0], "reset") == 0) { - if (o->cmd != FLASH_CMD_NONE) return -1; + } else if (strcmp(av[0], "reset") == 0) { + if (o->cmd != FLASH_CMD_NONE) { return(-1); } + o->cmd = CMD_RESET; - } - else { + } else { break; } @@ -262,60 +259,83 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { av++; } - switch(o->cmd) { - case FLASH_CMD_NONE: // no command found - return -1; + switch (o->cmd) { + case FLASH_CMD_NONE: // no command found + return(-1); - case FLASH_CMD_ERASE: // no more arguments expected - if (ac != 0) return -1; - break; + case FLASH_CMD_ERASE: // no more arguments expected - case FLASH_CMD_READ: // expect filename, addr and size - if ((o->area == FLASH_OPTION_BYTES) &&(ac == 0)) break; - if (ac != 3) return invalid_args("read "); - if (ac != 3) return -1; - o->filename = av[0]; - uint32_t address; - result = get_integer_from_char_array(av[1], &address); - if (result != 0) return bad_arg ("addr"); - else o->addr = (stm32_addr_t) address; + if (ac != 0) { return(-1); } - uint32_t size; - result = get_integer_from_char_array(av[2], &size); - if (result != 0) return bad_arg ("size"); - else o->size = (size_t) size; + break; - break; + case FLASH_CMD_READ: // expect filename, addr and size - case FLASH_CMD_WRITE: - if (o->area == FLASH_OPTION_BYTES){ - if (ac != 1) return -1; + if ((o->area == FLASH_OPTION_BYTES) && (ac == 0)) { break; } - uint32_t val; - result = get_integer_from_char_array(av[0], &val); - if (result != 0) return bad_arg ("val"); - else o->val = (uint32_t) val; + if (ac != 3) { return(invalid_args("read ")); } + if (ac != 3) { return(-1); } + + o->filename = av[0]; + uint32_t address; + result = get_integer_from_char_array(av[1], &address); + + if (result != 0) { + return(bad_arg ("addr")); + } else { + o->addr = (stm32_addr_t)address; + } + + uint32_t size; + result = get_integer_from_char_array(av[2], &size); + + if (result != 0) { + return(bad_arg ("size")); + } else { + o->size = (size_t)size; + } + + break; + + case FLASH_CMD_WRITE: + + if (o->area == FLASH_OPTION_BYTES) { + if (ac != 1) { return(-1); } + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + + if (result != 0) { + return(bad_arg ("val")); + } else { + o->val = (uint32_t)val; } - else if (o->format == FLASH_FORMAT_BINARY) { // expect filename and addr - if (ac != 2) return invalid_args("write "); - o->filename = av[0]; - uint32_t addr; - result = get_integer_from_char_array(av[1], &addr); - if (result != 0) return bad_arg ("addr"); - else o->addr = (stm32_addr_t) addr; - } - else if (o->format == FLASH_FORMAT_IHEX) { // expect filename - if (ac != 1) return invalid_args("write "); - o->filename = av[0]; - } - else { - return -1; // should have been caught during format parsing + + } else if (o->format == FLASH_FORMAT_BINARY) { // expect filename and addr + if (ac != 2) { return(invalid_args("write ")); } + + o->filename = av[0]; + uint32_t addr; + result = get_integer_from_char_array(av[1], &addr); + + if (result != 0) { + return(bad_arg ("addr")); + } else { + o->addr = (stm32_addr_t)addr; } - break; + } else if (o->format == FLASH_FORMAT_IHEX) { // expect filename + if (ac != 1) { return(invalid_args("write ")); } + + o->filename = av[0]; + } else { + return(-1); // should have been caught during format parsing + } + + break; - default: break ; + default: break; } - return 0; + return(0); } diff --git a/src/st-info/info.c b/src/st-info/info.c index 8464d8632..1bc48a05e 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -5,8 +5,7 @@ #include -static void usage(void) -{ +static void usage(void) { puts("st-info --version"); puts("st-info --probe"); puts("st-info --serial"); @@ -19,31 +18,32 @@ static void usage(void) } /* Print normal or OpenOCD hla_serial with newline */ -static void stlink_print_serial(stlink_t *sl, bool openocd) -{ +static void stlink_print_serial(stlink_t *sl, bool openocd) { const char *fmt; if (openocd) { - printf("\""); - fmt = "\\x%02x"; + printf("\""); + fmt = "\\x%02x"; } else { - fmt = "%02x"; + fmt = "%02x"; } for (int n = 0; n < sl->serial_size; n++) printf(fmt, sl->serial[n]); - if (openocd) - printf("\""); + if (openocd) { + printf("\""); + } + printf("\n"); } -static void stlink_print_info(stlink_t *sl) -{ +static void stlink_print_info(stlink_t *sl) { const struct stlink_chipid_params *params = NULL; - if (!sl) + if (!sl) { return; + } printf(" serial: "); stlink_print_serial(sl, false); @@ -51,18 +51,17 @@ static void stlink_print_info(stlink_t *sl) stlink_print_serial(sl, true); printf(" flash: %u (pagesize: %u)\n", - (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz); + (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz); printf(" sram: %u\n", (unsigned int)sl->sram_size); printf(" chipid: 0x%.4x\n", sl->chip_id); - params = stlink_chipid_get_params(sl->chip_id); - if (params) - printf(" descr: %s\n", params->description); + params = stlink_chipid_get_params(sl->chip_id); + + if (params) { printf(" descr: %s\n", params->description); } } -static void stlink_probe(void) -{ +static void stlink_probe(void) { stlink_t **stdevs; size_t size; @@ -70,16 +69,15 @@ static void stlink_probe(void) printf("Found %u stlink programmers\n", (unsigned int)size); - for (size_t n = 0; n < size; n++) - stlink_print_info(stdevs[n]); + for (size_t n = 0; n < size; n++) stlink_print_info(stdevs[n]); stlink_probe_usb_free(&stdevs, size); } -static stlink_t *stlink_open_first(bool under_reset) -{ +static stlink_t *stlink_open_first(bool under_reset) { stlink_t* sl = NULL; sl = stlink_v1_open(0, 1); + if (sl == NULL) { if (under_reset) { sl = stlink_open_usb(0, 2, NULL, 0); @@ -87,84 +85,79 @@ static stlink_t *stlink_open_first(bool under_reset) sl = stlink_open_usb(0, 1, NULL, 0); } } - - return sl; + + return(sl); } -static int print_data(int ac, char **av) -{ +static int print_data(int ac, char **av) { stlink_t* sl = NULL; bool under_reset = false; - // Probe needs all devices unclaimed + // probe needs all devices unclaimed if (strcmp(av[1], "--probe") == 0) { stlink_probe(); - return 0; + return(0); } else if (strcmp(av[1], "--version") == 0) { printf("v%s\n", STLINK_VERSION); - return 0; + return(0); } if (ac == 3) { - if (strcmp(av[2],"--connect-under-reset") == 0) { + if (strcmp(av[2], "--connect-under-reset") == 0) { under_reset = true; } else { usage(); - return -1; + return(-1); } } sl = stlink_open_first(under_reset); - if (sl == NULL) { - return -1; - } + if (sl == NULL) { return(-1); } sl->verbose = 0; - 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); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } - if (strcmp(av[1], "--serial") == 0) + if (strcmp(av[1], "--serial") == 0) { stlink_print_serial(sl, false); - else if (strcmp(av[1], "--hla-serial") == 0) + } else if (strcmp(av[1], "--hla-serial") == 0) { stlink_print_serial(sl, true); - else if (strcmp(av[1], "--flash") == 0) + } else if (strcmp(av[1], "--flash") == 0) { printf("0x%x\n", (unsigned int)sl->flash_size); - else if (strcmp(av[1], "--pagesize") == 0) + } else if (strcmp(av[1], "--pagesize") == 0) { printf("0x%x\n", (unsigned int)sl->flash_pgsz); - else if (strcmp(av[1], "--sram") == 0) + } else if (strcmp(av[1], "--sram") == 0) { printf("0x%x\n", (unsigned int)sl->sram_size); - else if (strcmp(av[1], "--chipid") == 0) + } else if (strcmp(av[1], "--chipid") == 0) { printf("0x%.4x\n", sl->chip_id); - else if (strcmp(av[1], "--descr") == 0) { + } else if (strcmp(av[1], "--descr") == 0) { const struct stlink_chipid_params *params = stlink_chipid_get_params(sl->chip_id); - if (params == NULL) - return -1; + + if (params == NULL) { return(-1); } + printf("%s\n", params->description); } - if (sl) - { + if (sl) { stlink_exit_debug_mode(sl); stlink_close(sl); } - return 0; + return(0); } -int main(int ac, char** av) -{ +int main(int ac, char** av) { int err = -1; + if (ac < 2) { usage(); - return -1; + return(-1); } - err = print_data(ac,av); + err = print_data(ac, av); - return err; + return(err); } diff --git a/src/st-util/gdb-remote.c b/src/st-util/gdb-remote.c index 04729cc75..bdf8afd24 100644 --- a/src/st-util/gdb-remote.c +++ b/src/st-util/gdb-remote.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Peter Zotov + * Copyright (c) 2011 Peter Zotov * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ @@ -20,7 +20,7 @@ static const char hex[] = "0123456789abcdef"; int gdb_send_packet(int fd, char* data) { - unsigned int data_length = (unsigned int) strlen(data); + unsigned int data_length = (unsigned int)strlen(data); int length = data_length + 4; char* packet = malloc(length); // '$' data (hex) '#' cksum (hex) @@ -29,6 +29,7 @@ int gdb_send_packet(int fd, char* data) { packet[0] = '$'; uint8_t cksum = 0; + for (unsigned int i = 0; i < data_length; i++) { packet[i + 1] = data[i]; cksum += data[i]; @@ -41,18 +42,19 @@ int gdb_send_packet(int fd, char* data) { while (1) { if (write(fd, packet, length) != length) { free(packet); - return -2; + return(-2); } char ack; + if (read(fd, &ack, 1) != 1) { free(packet); - return -2; + return(-2); } if (ack == '+') { free(packet); - return 0; + return(0); } } } @@ -66,7 +68,9 @@ int gdb_recv_packet(int fd, char** buffer) { char* packet_buffer = malloc(packet_size); unsigned state; - if (packet_buffer == NULL) return -2; + if (packet_buffer == NULL) { + return(-2); + } start: state = 0; @@ -80,18 +84,25 @@ int gdb_recv_packet(int fd, char** buffer) { */ char c; + while (state != 4) { if (read(fd, &c, 1) != 1) { free(packet_buffer); - return -2; + return(-2); } - switch(state) { + switch (state) { case 0: - if (c != '$') { /* ignore */ } else { state = 1; } + + if (c != '$') { /* ignore */ + } else { + state = 1; + } + break; case 1: + if (c == '#') { state = 2; } else { @@ -101,14 +112,16 @@ int gdb_recv_packet(int fd, char** buffer) { if (packet_idx == packet_size) { packet_size += ALLOC_STEP; void* p = realloc(packet_buffer, packet_size); + if (p != NULL) { packet_buffer = p; } else { free(packet_buffer); - return -2; + return(-2); } } } + break; case 2: @@ -124,25 +137,29 @@ int gdb_recv_packet(int fd, char** buffer) { } uint8_t recv_cksum_int = strtoul(recv_cksum, NULL, 16); + if (recv_cksum_int != cksum) { char nack = '-'; + if (write(fd, &nack, 1) != 1) { free(packet_buffer); - return -2; + return(-2); } + goto start; } else { char ack = '+'; + if (write(fd, &ack, 1) != 1) { free(packet_buffer); - return -2; + return(-2); } } packet_buffer[packet_idx] = 0; *buffer = packet_buffer; - return packet_idx; + return(packet_idx); } /* @@ -157,9 +174,15 @@ int gdb_check_for_interrupt(int fd) { if (poll(&pfd, 1, 0) != 0) { char c; - if (read(fd, &c, 1) != 1) return -2; - if (c == '\x03') return 1; // ^C + + if (read(fd, &c, 1) != 1) { + return(-2); + } + + if (c == '\x03') { + return(1); // ^C + } } - return 0; + return(0); } diff --git a/src/st-util/gdb-remote.h b/src/st-util/gdb-remote.h index bfa01046c..6e76746b7 100644 --- a/src/st-util/gdb-remote.h +++ b/src/st-util/gdb-remote.h @@ -5,4 +5,4 @@ int gdb_send_packet(int fd, char* data); int gdb_recv_packet(int fd, char** buffer); int gdb_check_for_interrupt(int fd); -#endif +#endif // _GDB_REMOTE_H_ diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 119d0ff9a..94cd6fda7 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Peter Zotov + * Copyright (c) 2011 Peter Zotov * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ @@ -69,13 +69,13 @@ typedef struct _st_state_t { int serve(stlink_t *sl, st_state_t *st); char* make_memory_map(stlink_t *sl); -static void init_cache (stlink_t *sl); +static void init_cache(stlink_t *sl); static void cleanup(int signum) { (void)signum; if (connected_stlink) { - /* Switch back to mass storage mode before closing. */ + // Switch back to mass storage mode before closing stlink_run(connected_stlink); stlink_exit_debug_mode(connected_stlink); stlink_close(connected_stlink); @@ -87,12 +87,14 @@ static void cleanup(int signum) { static stlink_t* do_connect(st_state_t *st) { stlink_t *sl = NULL; + if (serial_specified) { sl = stlink_open_usb(st->logging_level, st->reset, serialnumber, 0); } else { sl = stlink_open_usb(st->logging_level, st->reset, NULL, 0); } - return sl; + + return(sl); } @@ -109,92 +111,104 @@ int parse_options(int argc, char** argv, st_state_t *st) { {0, 0, 0, 0}, }; const char * help_str = "%s - usage:\n\n" - " -h, --help\t\tPrint this help\n" - " -V, --version\t\tPrint the version\n" - " -vXX, --verbose=XX\tSpecify a specific verbosity level (0..99)\n" - " -v, --verbose\t\tSpecify generally verbose logging\n" - "\t\t\tChoose what version of stlink to use, (defaults to 2)\n" - " -1, --stlinkv1\tForce stlink version 1\n" - " -p 4242, --listen_port=1234\n" - "\t\t\tSet the gdb server listen port. " - "(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n" - " -m, --multi\n" - "\t\t\tSet gdb server to extended mode.\n" - "\t\t\tst-util will continue listening for connections after disconnect.\n" - " -n, --no-reset\n" - "\t\t\tDo not reset board on connection.\n" - " --semihosting\n" - "\t\t\tEnable semihosting support.\n" - " --serial \n" - "\t\t\tUse a specific serial number.\n" - "\n" - "The STLINK device to use can be specified in the environment\n" - "variable STLINK_DEVICE on the format :.\n" - "\n" - ; + " -h, --help\t\tPrint this help\n" + " -V, --version\t\tPrint the version\n" + " -vXX, --verbose=XX\tSpecify a specific verbosity level (0..99)\n" + " -v, --verbose\t\tSpecify generally verbose logging\n" + "\t\t\tChoose what version of stlink to use, (defaults to 2)\n" + " -1, --stlinkv1\tForce stlink version 1\n" + " -p 4242, --listen_port=1234\n" + "\t\t\tSet the gdb server listen port. " + "(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n" + " -m, --multi\n" + "\t\t\tSet gdb server to extended mode.\n" + "\t\t\tst-util will continue listening for connections after disconnect.\n" + " -n, --no-reset\n" + "\t\t\tDo not reset board on connection.\n" + " --semihosting\n" + "\t\t\tEnable semihosting support.\n" + " --serial \n" + "\t\t\tUse a specific serial number.\n" + "\n" + "The STLINK device to use can be specified in the environment\n" + "variable STLINK_DEVICE on the format :.\n" + "\n" + ; int option_index = 0; int c; int q; - while ((c = getopt_long(argc, argv, "hv::p:mn", long_options, &option_index)) != -1) { + + while ((c = getopt_long(argc, argv, "hv::p:mn", long_options, &option_index)) != -1) switch (c) { - case 0: - break; - case 'h': - printf(help_str, argv[0]); - exit(EXIT_SUCCESS); - break; - case 'v': - if (optarg) { - st->logging_level = atoi(optarg); - } else { - st->logging_level = DEBUG_LOGGING_LEVEL; - } - break; - case 'p': - sscanf(optarg, "%i", &q); - if (q < 0) { - fprintf(stderr, "Can't use a negative port to listen on: %d\n", q); - exit(EXIT_FAILURE); - } - st->listen_port = q; - break; - case 'm': - st->persistent = 1; - break; - case 'n': - st->reset = 0; - break; - case 'V': - printf("v%s\n", STLINK_VERSION); - exit(EXIT_SUCCESS); - case SEMIHOSTING_OPTION: - semihosting = true; - break; - case SERIAL_OPTION: - printf("use serial %s\n",optarg); - /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ - int j = (int)strlen(optarg); - int length = j / 2; //the length of the destination-array - if (j % 2 != 0) return -1; - for (size_t k = 0; j >= 0 && k < sizeof(serialnumber); ++k, j -= 2) { - char buffer[3] = {0}; - memcpy(buffer, optarg + j, 2); - serialnumber[length - k] = (uint8_t)strtol(buffer, NULL, 16); - } - serial_specified = true; - break; + case 0: + break; + case 'h': + printf(help_str, argv[0]); + exit(EXIT_SUCCESS); + break; + case 'v': + + if (optarg) { + st->logging_level = atoi(optarg); + } else { + st->logging_level = DEBUG_LOGGING_LEVEL; + } + + break; + case 'p': + sscanf(optarg, "%i", &q); + + if (q < 0) { + fprintf(stderr, "Can't use a negative port to listen on: %d\n", q); + exit(EXIT_FAILURE); + } + + st->listen_port = q; + break; + case 'm': + st->persistent = 1; + break; + case 'n': + st->reset = 0; + break; + case 'V': + printf("v%s\n", STLINK_VERSION); + exit(EXIT_SUCCESS); + case SEMIHOSTING_OPTION: + semihosting = true; + break; + case SERIAL_OPTION: + printf("use serial %s\n", optarg); + /* TODO: This is not really portable, as strlen really returns size_t, + * we need to obey and not cast it to a signed type. + */ + int j = (int)strlen(optarg); + int length = j / 2; // the length of the destination-array + + if (j % 2 != 0) { return(-1); } + + for (size_t k = 0; j >= 0 && k < sizeof(serialnumber); ++k, j -= 2) { + char buffer[3] = {0}; + memcpy(buffer, optarg + j, 2); + serialnumber[length - k] = (uint8_t)strtol(buffer, NULL, 16); + } + + serial_specified = true; + break; } - } + if (optind < argc) { printf("non-option ARGV-elements: "); - while (optind < argc) - printf("%s ", argv[optind++]); + + while (optind < argc) { printf("%s ", argv[optind++]); } + printf("\n"); } - return 0; + + return(0); } int main(int argc, char** argv) { @@ -211,11 +225,12 @@ int main(int argc, char** argv) { printf("st-util\n"); sl = do_connect(&state); - if (sl == NULL) return 1; - if (sl->chip_id == STLINK_CHIPID_UNKNOWN) { + if (sl == NULL) { return(1); } + + if (sl->chip_id == STLINK_CHIPID_UNKNOWN) { ELOG("Unsupported Target (Chip ID is %#010x, Core ID is %#010x).\n", sl->chip_id, sl->core_id); - return 1; + return(1); } connected_stlink = sl; @@ -223,22 +238,25 @@ int main(int argc, char** argv) { signal(SIGTERM, &cleanup); signal(SIGSEGV, &cleanup); - if (state.reset) stlink_reset(sl); + if (state.reset) { stlink_reset(sl); } DLOG("Chip ID is %#010x, Core ID is %#08x.\n", sl->chip_id, sl->core_id); - sl->verbose=0; + sl->verbose = 0; current_memory_map = make_memory_map(sl); #if defined(_WIN32) - WSADATA wsadata; - if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0) goto winsock_error; + WSADATA wsadata; + + if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) { goto winsock_error; } + #endif init_cache(sl); - do { - if (serve(sl, &state)) { usleep (1 * 1000); } // don't go beserk if serve returns with error + do { // don't go beserk if serve() returns with error + if (serve(sl, &state)) { usleep (1 * 1000); } + sl = connected_stlink; // in case serve() changed the connection stlink_run(sl); // continue } while (state.persistent); @@ -252,7 +270,7 @@ int main(int argc, char** argv) { stlink_exit_debug_mode(sl); stlink_close(sl); - return 0; + return(0); } static const char* const target_description_F4 = @@ -328,14 +346,14 @@ static const char* const memory_map_template_F4 = " " // code = sram, bootrom or flash; flash is bigger " " // ccm ram " " // sram - " " //Sectors 0..3 - " 0x4000" //16kB + " " // Sectors 0..3 + " 0x4000" // 16kB " " - " " //Sector 4 - " 0x10000" //64kB + " " // Sector 4 + " 0x10000" // 64kB " " - " " //Sectors 5..11 - " 0x20000" //128kB + " " // Sectors 5..11 + " 0x20000" // 128kB " " " " // peripheral regs " " // AHB3 Peripherals @@ -356,14 +374,14 @@ static const char* const memory_map_template_F4_HD = " " // fmc bank 2 & 3 (nand flash) " " // fmc bank 4 (pc card) " " // fmc sdram bank 1 & 2 - " " //Sectors 0..3 - " 0x4000" //16kB + " " // Sectors 0..3 + " 0x4000" // 16kB " " - " " //Sector 4 - " 0x10000" //64kB + " " // Sector 4 + " 0x10000" // 64kB " " - " " //Sectors 5..11 - " 0x20000" //128kB + " " // Sectors 5..11 + " 0x20000" // 128kB " " " " // peripheral regs " " // cortex regs @@ -376,20 +394,20 @@ static const char* const memory_map_template_F2 = "" "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram - " " //Sectors 0..3 - " 0x4000" //16kB + " " // code = sram, bootrom or flash; flash is bigger + " " // sram + " " // Sectors 0..3 + " 0x4000" // 16kB " " - " " //Sector 4 - " 0x10000" //64kB + " " // Sector 4 + " 0x10000" // 64kB " " - " " //Sectors 5.. - " 0x20000" //128kB + " " // Sectors 5.. + " 0x20000" // 128kB " " " " // peripheral regs " " // cortex regs - " " // bootrom + " " // bootrom " " // option byte area ""; @@ -398,9 +416,9 @@ static const char* const memory_map_template_L4 = "" "" - " " // code = sram, bootrom or flash; flash is bigger - " " // SRAM2 (32 KB) - " " // SRAM1 (96 KB) + " " // code = sram, bootrom or flash; flash is bigger + " " // SRAM2 (32kB) + " " // SRAM1 (96kB) " " " 0x800" " " @@ -417,9 +435,9 @@ static const char* const memory_map_template_L496 = "" "" - " " // code = sram, bootrom or flash; flash is bigger - " " // SRAM2 (64 KB) - " " // SRAM1 + aliased SRAM2 (256+64=320 KB) + " " // code = sram, bootrom or flash; flash is bigger + " " // SRAM2 (64kB) + " " // SRAM1 + aliased SRAM2 (256 + 64 = 320kB) " " " 0x800" " " @@ -436,14 +454,14 @@ static const char* const memory_map_template = "" "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram 8k + " " // code = sram, bootrom or flash; flash is bigger + " " // sram 8kB " " " 0x%x" " " " " // peripheral regs " " // cortex regs - " " // bootrom + " " // bootrom " " // option byte area ""; @@ -454,7 +472,7 @@ static const char* const memory_map_template_F7 = "" " " // ITCM ram 16kB " " // ITCM flash - " " // sram + " " // sram " " // Sectors 0..3 " 0x8000" // 32kB " " @@ -479,14 +497,14 @@ static const char* const memory_map_template_F4_DE = "" " " // code = sram, bootrom or flash; flash is bigger " " // sram - " " //Sectors 0..3 - " 0x4000" //16kB + " " // Sectors 0..3 + " 0x4000" // 16kB " " - " " //Sector 4 - " 0x10000" //64kB + " " // Sector 4 + " 0x10000" // 64kB " " - " " //Sectors 5..7 - " 0x20000" //128kB + " " // Sectors 5..7 + " 0x20000" // 128kB " " " " // peripheral regs " " // cortex regs @@ -501,37 +519,45 @@ char* make_memory_map(stlink_t *sl) { char* map = malloc(sz); map[0] = '\0'; - if (sl->chip_id==STLINK_CHIPID_STM32_F4 || sl->chip_id==STLINK_CHIPID_STM32_F446 || sl->chip_id==STLINK_CHIPID_STM32_F411RE) { - strcpy(map, memory_map_template_F4); - } else if (sl->chip_id==STLINK_CHIPID_STM32_F4_DE) { + if (sl->chip_id == STLINK_CHIPID_STM32_F4 || + sl->chip_id == STLINK_CHIPID_STM32_F446 || + sl->chip_id == STLINK_CHIPID_STM32_F411RE) { + strcpy(map, memory_map_template_F4); + } else if (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) { strcpy(map, memory_map_template_F4_DE); - } else if (sl->core_id==STM32F7_CORE_ID) { + } else if (sl->core_id == STM32F7_CORE_ID) { snprintf(map, sz, memory_map_template_F7, - (unsigned int)sl->sram_size); - } else if (sl->chip_id==STLINK_CHIPID_STM32_F4_HD) { + (unsigned int)sl->sram_size); + } else if (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) { strcpy(map, memory_map_template_F4_HD); - } else if (sl->chip_id==STLINK_CHIPID_STM32_F2) { + } else if (sl->chip_id == STLINK_CHIPID_STM32_F2) { snprintf(map, sz, memory_map_template_F2, - (unsigned int)sl->flash_size, - (unsigned int)sl->sram_size, - (unsigned int)sl->flash_size - 0x20000, - (unsigned int)sl->sys_base, (unsigned int)sl->sys_size); - } else if ((sl->chip_id==STLINK_CHIPID_STM32_L4) || - (sl->chip_id==STLINK_CHIPID_STM32_L43X) || - (sl->chip_id==STLINK_CHIPID_STM32_L46X)) { + (unsigned int)sl->flash_size, + (unsigned int)sl->sram_size, + (unsigned int)sl->flash_size - 0x20000, + (unsigned int)sl->sys_base, + (unsigned int)sl->sys_size); + } else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || + (sl->chip_id == STLINK_CHIPID_STM32_L43X) || + (sl->chip_id == STLINK_CHIPID_STM32_L46X)) { snprintf(map, sz, memory_map_template_L4, - (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); - } else if (sl->chip_id==STLINK_CHIPID_STM32_L496X) { + (unsigned int)sl->flash_size, + (unsigned int)sl->flash_size); + } else if (sl->chip_id == STLINK_CHIPID_STM32_L496X) { snprintf(map, sz, memory_map_template_L496, - (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); + (unsigned int)sl->flash_size, + (unsigned int)sl->flash_size); } else { snprintf(map, sz, memory_map_template, - (unsigned int)sl->flash_size, - (unsigned int)sl->sram_size, - (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz, - (unsigned int)sl->sys_base, (unsigned int)sl->sys_size); + (unsigned int)sl->flash_size, + (unsigned int)sl->sram_size, + (unsigned int)sl->flash_size, + (unsigned int)sl->flash_pgsz, + (unsigned int)sl->sys_base, + (unsigned int)sl->sys_size); } - return map; + + return(map); } /* @@ -566,7 +592,7 @@ static void init_data_watchpoints(stlink_t *sl) { DLOG("init watchpoints\n"); stlink_read_debug32(sl, 0xE000EDFC, &data); - data |= 1<<24; + data |= 1 << 24; // set trcena in debug command to turn on dwt unit stlink_write_debug32(sl, 0xE000EDFC, data); @@ -577,8 +603,7 @@ static void init_data_watchpoints(stlink_t *sl) { } } -static int add_data_watchpoint( - stlink_t *sl, enum watchfun wf, stm32_addr_t addr, unsigned int len) { +static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr, unsigned int len) { int i = 0; uint32_t mask, dummy; @@ -588,13 +613,14 @@ static int add_data_watchpoint( mask = -1; i = len; + while (i) { i >>= 1; mask++; } if ((mask != (uint32_t)-1) && (mask < 16)) { - for (i = 0; i < DATA_WATCH_NUM; i++) { + for (i = 0; i < DATA_WATCH_NUM; i++) // is this an empty slot ? if (data_watches[i].fun == WATCHDISABLED) { DLOG("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len); @@ -614,43 +640,42 @@ static int add_data_watchpoint( // just to make sure the matched bit is clear ! stlink_read_debug32(sl, 0xE0001028 + i * 16, &dummy); - return 0; + return(0); } - } } DLOG("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len); - return -1; + return(-1); } static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { int i; - for (i = 0 ; i < DATA_WATCH_NUM; i++) { + for (i = 0; i < DATA_WATCH_NUM; i++) { if ((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) { DLOG("delete watchpoint %d addr %x\n", i, addr); data_watches[i].fun = WATCHDISABLED; stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); - return 0; + return(0); } } DLOG("failure: delete watchpoint addr %x\n", addr); - return -1; + return(-1); } static int code_break_num; static int code_lit_num; -#define CODE_BREAK_NUM_MAX 15 -#define CODE_BREAK_LOW 0x01 +#define CODE_BREAK_NUM_MAX 15 +#define CODE_BREAK_LOW 0x01 #define CODE_BREAK_HIGH 0x02 struct code_hw_breakpoint { stm32_addr_t addr; - int type; + int type; }; static struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM_MAX]; @@ -658,7 +683,7 @@ static struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM_MAX]; static void init_code_breakpoints(stlink_t *sl) { unsigned int val; memset(sl->q_buf, 0, 4); - stlink_write_debug32(sl, STLINK_REG_CM3_FP_CTRL, 0x03 /*KEY | ENABLE4*/); + stlink_write_debug32(sl, STLINK_REG_CM3_FP_CTRL, 0x03 /* KEY | ENABLE4 */); stlink_read_debug32(sl, STLINK_REG_CM3_FP_CTRL, &val); code_break_num = ((val >> 4) & 0xf); code_lit_num = ((val >> 8) & 0xf); @@ -671,12 +696,11 @@ static void init_code_breakpoints(stlink_t *sl) { } } -static int has_breakpoint(stm32_addr_t addr) -{ - for (int i = 0; i < code_break_num; i++) { - if (code_breaks[i].addr == addr) return 1; - } - return 0; +static int has_breakpoint(stm32_addr_t addr) { + for (int i = 0; i < code_break_num; i++) + if (code_breaks[i].addr == addr) { return(1); } + + return(0); } static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { @@ -686,37 +710,53 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { if (addr & 1) { ELOG("update_code_breakpoint: unaligned address %08x\n", addr); - return -1; + return(-1); } - if (sl->core_id==STM32F7_CORE_ID) { + if (sl->core_id == STM32F7_CORE_ID) { fpb_addr = addr; } else { fpb_addr = addr & ~0x3; } int id = -1; - for (int i = 0; i < code_break_num; i++) { + + for (int i = 0; i < code_break_num; i++) if (fpb_addr == code_breaks[i].addr || (set && code_breaks[i].type == 0)) { id = i; break; } - } + if (id == -1) { - if (set) { return -1; } // free slot not found - else { return 0; } // breakpoint is already removed + if (set) { + return(-1); + } // free slot not found + else { + return(0); + } // breakpoint is already removed + } struct code_hw_breakpoint* bp = &code_breaks[id]; bp->addr = fpb_addr; - if (sl->core_id==STM32F7_CORE_ID) { - if (set) { bp->type = type; } else { bp->type = 0; } + if (sl->core_id == STM32F7_CORE_ID) { + if (set) { + bp->type = type; + } else { + bp->type = 0; + } + mask = (bp->addr) | 1; } else { - if (set) { bp->type |= type; } else { bp->type &= ~type; } + if (set) { + bp->type |= type; + } else { + bp->type &= ~type; + } + mask = (bp->addr) | 1 | (bp->type << 30); } @@ -729,13 +769,13 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { stlink_write_debug32(sl, 0xe0002008 + id * 4, mask); } - return 0; + return(0); } struct flash_block { stm32_addr_t addr; - unsigned length; + unsigned length; uint8_t* data; struct flash_block* next; @@ -747,13 +787,14 @@ static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { if (addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) { ELOG("flash_add_block: incorrect bounds\n"); - return -1; + return(-1); } stlink_calculate_pagesize(sl, addr); + if (addr % FLASH_PAGE != 0 || length % FLASH_PAGE != 0) { ELOG("flash_add_block: unaligned block\n"); - return -1; + return(-1); } struct flash_block* new = malloc(sizeof(struct flash_block)); @@ -763,15 +804,15 @@ static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { new->data = calloc(length, 1); flash_root = new; - - return 0; + return(0); } static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { unsigned int fit_blocks = 0, fit_length = 0; for (struct flash_block* fb = flash_root; fb; fb = fb->next) { - /* Block: ------X------Y-------- + /* + * Block: ------X------Y-------- * Data: a-----b * a--b * a-----------b @@ -781,6 +822,7 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { unsigned X = fb->addr, Y = fb->addr + fb->length; unsigned a = addr, b = addr + length; + if (a < Y && b > X) { // from start of the block unsigned start = (a > X ? a : X) - X; @@ -795,7 +837,7 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { if (fit_blocks == 0) { ELOG("Unfit data block %08x -> %04x\n", addr, length); - return -1; + return(-1); } if (fit_length != length) { @@ -803,7 +845,7 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { WLOG("(this is not an error, just a GDB glitch)\n"); } - return 0; + return(0); } static int flash_go(stlink_t *sl) { @@ -823,17 +865,18 @@ static int flash_go(stlink_t *sl) { stlink_calculate_pagesize(sl, page); DLOG("flash_do: page %08x\n", page); - unsigned len = (length > FLASH_PAGE) ? (unsigned int) FLASH_PAGE : length; + unsigned len = (length > FLASH_PAGE) ? (unsigned int)FLASH_PAGE : length; int ret = stlink_write_flash(sl, page, fb->data + (page - fb->addr), len, 0); - if (ret < 0) goto error; + + if (ret < 0) { goto error; } } } stlink_reset(sl); - error = 0; error: + for (struct flash_block* fb = flash_root, *next; fb; fb = next) { next = fb->next; free(fb->data); @@ -841,8 +884,7 @@ static int flash_go(stlink_t *sl) { } flash_root = NULL; - - return error; + return(error); } #define CLIDR 0xE000ED78 @@ -863,11 +905,11 @@ struct cache_level_desc { }; struct cache_desc_t { - // Minimal line size in bytes + // minimal line size in bytes unsigned int dminline; unsigned int iminline; - // Last level of unification (uniprocessor) + // last level of unification (uniprocessor) unsigned int louu; struct cache_level_desc icache[7]; @@ -879,8 +921,10 @@ static struct cache_desc_t cache_desc; // return the smallest R so that V <= (1 << R); not performance critical static unsigned ceil_log2(unsigned v) { unsigned res; - for (res = 0; (1U << res) < v; res++) ; - return res; + + for (res = 0; (1U << res) < v; res++); + + return(res); } static void read_cache_level_desc(stlink_t *sl, struct cache_level_desc *desc) { @@ -894,7 +938,7 @@ static void read_cache_level_desc(stlink_t *sl, struct cache_level_desc *desc) { log2_nsets = ceil_log2 (desc->nsets); desc->width = 4 + (ccsidr & 7) + log2_nsets; ILOG("%08x LineSize: %u, ways: %u, sets: %u (width: %u)\n", - ccsidr, 4 << (ccsidr & 7), desc->nways, desc->nsets, desc->width); + ccsidr, 4 << (ccsidr & 7), desc->nways, desc->nsets, desc->width); } static void init_cache (stlink_t *sl) { @@ -903,8 +947,8 @@ static void init_cache (stlink_t *sl) { unsigned int ctr; int i; - // Assume only F7 has a cache - if (sl->core_id!=STM32F7_CORE_ID) return; + // assume only F7 has a cache + if (sl->core_id != STM32F7_CORE_ID) { return; } stlink_read_debug32(sl, CLIDR, &clidr); stlink_read_debug32(sl, CCR, &ccr); @@ -914,23 +958,24 @@ static void init_cache (stlink_t *sl) { cache_desc.louu = (clidr >> 27) & 7; ILOG("Chip clidr: %08x, I-Cache: %s, D-Cache: %s\n", - clidr, ccr & CCR_IC ? "on" : "off", ccr & CCR_DC ? "on" : "off"); + clidr, ccr & CCR_IC ? "on" : "off", ccr & CCR_DC ? "on" : "off"); ILOG(" cache: LoUU: %u, LoC: %u, LoUIS: %u\n", - (clidr >> 27) & 7, (clidr >> 24) & 7, (clidr >> 21) & 7); + (clidr >> 27) & 7, (clidr >> 24) & 7, (clidr >> 21) & 7); ILOG(" cache: ctr: %08x, DminLine: %u bytes, IminLine: %u bytes\n", ctr, - cache_desc.dminline, cache_desc.iminline); + cache_desc.dminline, cache_desc.iminline); + for (i = 0; i < 7; i++) { unsigned int ct = (clidr >> (3 * i)) & 0x07; cache_desc.dcache[i].width = 0; cache_desc.icache[i].width = 0; - if (ct == 2 || ct == 3 || ct == 4) { // Data + if (ct == 2 || ct == 3 || ct == 4) { // data stlink_write_debug32(sl, CSSELR, i << 1); ILOG("D-Cache L%d: ", i); read_cache_level_desc(sl, &cache_desc.dcache[i]); } - if (ct == 1 || ct == 3) { // Instruction + if (ct == 1 || ct == 3) { // instruction stlink_write_debug32(sl, CSSELR, (i << 1) | 1); ILOG("I-Cache L%d: ", i); read_cache_level_desc(sl, &cache_desc.icache[i]); @@ -941,7 +986,7 @@ static void init_cache (stlink_t *sl) { static void cache_flush(stlink_t *sl, unsigned ccr) { int level; - if (ccr & CCR_DC) + if (ccr & CCR_DC) { for (level = cache_desc.louu - 1; level >= 0; level--) { struct cache_level_desc *desc = &cache_desc.dcache[level]; unsigned addr; @@ -951,19 +996,25 @@ static void cache_flush(stlink_t *sl, unsigned ccr) { // D-cache clean by set-ways. for (addr = (level << 1); addr < max_addr; addr += cache_desc.dminline) { unsigned int way; - for (way = 0; way < desc->nways; way++) + + for (way = 0; way < desc->nways; way++) { stlink_write_debug32(sl, DCCSW, addr | (way << way_sh)); + } } } + } // invalidate all I-cache to oPU - if (ccr & CCR_IC) stlink_write_debug32(sl, ICIALLU, 0); + if (ccr & CCR_IC) { + stlink_write_debug32(sl, ICIALLU, 0); + } } static int cache_modified; static void cache_change(stm32_addr_t start, unsigned count) { - if (count == 0) return; + if (count == 0) { return; } + (void)start; cache_modified = 1; } @@ -971,12 +1022,14 @@ static void cache_change(stm32_addr_t start, unsigned count) { static void cache_sync(stlink_t *sl) { unsigned ccr; - if (sl->core_id!=STM32F7_CORE_ID) return; - if (!cache_modified) return; - cache_modified = 0; + if (sl->core_id != STM32F7_CORE_ID) { return; } + if (!cache_modified) { return; } + + cache_modified = 0; stlink_read_debug32(sl, CCR, &ccr); - if (ccr & (CCR_IC | CCR_DC)) cache_flush(sl, ccr); + + if (ccr & (CCR_IC | CCR_DC)) { cache_flush(sl, ccr); } } static size_t unhexify(const char *in, char *out, size_t out_count) { @@ -984,55 +1037,60 @@ static size_t unhexify(const char *in, char *out, size_t out_count) { unsigned int c; for (i = 0; i < out_count; i++) { - if (sscanf(in + (2 * i), "%02x", &c) != 1) return i; + if (sscanf(in + (2 * i), "%02x", &c) != 1) { return(i); } + out[i] = (char)c; } - return i; + return(i); } int serve(stlink_t *sl, st_state_t *st) { SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); + if (!IS_SOCK_VALID(sock)) { perror("socket"); - return 1; + return(1); } unsigned int val = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); struct sockaddr_in serv_addr; - memset(&serv_addr,0,sizeof(struct sockaddr_in)); + memset(&serv_addr, 0, sizeof(struct sockaddr_in)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(st->listen_port); - if (bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { + if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("bind"); close_socket(sock); - return 1; + return(1); } if (listen(sock, 5) < 0) { perror("listen"); close_socket(sock); - return 1; + return(1); } ILOG("Listening at *:%d...\n", st->listen_port); SOCKET client = accept(sock, NULL, NULL); - //signal (SIGINT, SIG_DFL); + + // signal (SIGINT, SIG_DFL); if (!IS_SOCK_VALID(client)) { perror("accept"); close_socket(sock); - return 1; + return(1); } close_socket(sock); stlink_force_debug(sl); - if (st->reset) stlink_reset(sl); + + if (st->reset) { stlink_reset(sl); } + init_code_breakpoints(sl); init_data_watchpoints(sl); @@ -1052,10 +1110,11 @@ int serve(stlink_t *sl, st_state_t *st) { char* packet; int status = gdb_recv_packet(client, &packet); + if (status < 0) { ELOG("cannot recv: %d\n", status); close_socket(client); - return 1; + return(1); } DLOG("recv: %s\n", packet); @@ -1063,686 +1122,736 @@ int serve(stlink_t *sl, st_state_t *st) { char* reply = NULL; struct stlink_reg regp; - switch(packet[0]) { - case 'q': { - if (packet[1] == 'P' || packet[1] == 'C' || packet[1] == 'L') { - reply = strdup(""); - break; - } + switch (packet[0]) { + case 'q': { + if (packet[1] == 'P' || packet[1] == 'C' || packet[1] == 'L') { + reply = strdup(""); + break; + } - char *separator = strstr(packet, ":"), *params = ""; - if (separator == NULL) { - separator = packet + strlen(packet); + char *separator = strstr(packet, ":"), *params = ""; + + if (separator == NULL) { + separator = packet + strlen(packet); + } else { + params = separator + 1; + } + + unsigned queryNameLength = (unsigned int)(separator - &packet[1]); + char* queryName = calloc(queryNameLength + 1, 1); + strncpy(queryName, &packet[1], queryNameLength); + + DLOG("query: %s;%s\n", queryName, params); + + if (!strcmp(queryName, "Supported")) { + if (sl->chip_id == STLINK_CHIPID_STM32_F4 || + sl->chip_id == STLINK_CHIPID_STM32_F4_HD || + sl->core_id == STM32F7_CORE_ID) { + reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); } else { - params = separator + 1; + reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); } + } else if (!strcmp(queryName, "Xfer")) { + char *type, *op, *__s_addr, *s_length; + char *tok = params; + char *annex __attribute__((unused)); - unsigned queryNameLength = (unsigned int) (separator - &packet[1]); - char* queryName = calloc(queryNameLength + 1, 1); - strncpy(queryName, &packet[1], queryNameLength); + type = strsep(&tok, ":"); + op = strsep(&tok, ":"); + annex = strsep(&tok, ":"); + __s_addr = strsep(&tok, ","); + s_length = tok; - DLOG("query: %s;%s\n", queryName, params); + unsigned addr = (unsigned int)strtoul(__s_addr, NULL, 16), + length = (unsigned int)strtoul(s_length, NULL, 16); - if (!strcmp(queryName, "Supported")) { - if (sl->chip_id==STLINK_CHIPID_STM32_F4 || - sl->chip_id==STLINK_CHIPID_STM32_F4_HD || - sl->core_id==STM32F7_CORE_ID) { - reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); - } else { - reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); - } - } else if (!strcmp(queryName, "Xfer")) { - char *type, *op, *__s_addr, *s_length; - char *tok = params; - char *annex __attribute__((unused)); - - type = strsep(&tok, ":"); - op = strsep(&tok, ":"); - annex = strsep(&tok, ":"); - __s_addr = strsep(&tok, ","); - s_length = tok; - - unsigned addr = (unsigned int) strtoul(__s_addr, NULL, 16), - length = (unsigned int) strtoul(s_length, NULL, 16); - - DLOG("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", - type, op, annex, addr, length); - - const char* data = NULL; - - if (!strcmp(type, "memory-map") && !strcmp(op, "read")) - data = current_memory_map; - - if (!strcmp(type, "features") && !strcmp(op, "read")) - data = target_description_F4; - - if (data) { - unsigned data_length = (unsigned int) strlen(data); - if (addr + length > data_length) - length = data_length - addr; - if (length == 0) { - reply = strdup("l"); - } else { - reply = calloc(length + 2, 1); - reply[0] = 'm'; - strncpy(&reply[1], data, length); - } - } - } else if (!strncmp(queryName, "Rcmd,",4)) { - // Rcmd uses the wrong separator - separator = strstr(packet, ","); - params = ""; - if (separator == NULL) { - separator = packet + strlen(packet); - } else { - params = separator + 1; - } + DLOG("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", + type, op, annex, addr, length); - size_t hex_len = strlen(params); - size_t alloc_size = (hex_len / 2) + 1; - size_t cmd_len; - char *cmd = malloc(alloc_size); + const char* data = NULL; - if (cmd == NULL) { - DLOG("Rcmd unhexify allocation error\n"); - break; - } + if (!strcmp(type, "memory-map") && !strcmp(op, "read")) { + data = current_memory_map; + } - cmd_len = unhexify(params, cmd, alloc_size - 1); - cmd[cmd_len] = 0; + if (!strcmp(type, "features") && !strcmp(op, "read")) { + data = target_description_F4; + } - DLOG("unhexified Rcmd: '%s'\n", cmd); + if (data) { + unsigned data_length = (unsigned int)strlen(data); - if (!strncmp(cmd, "resume", 6)) { // resume - DLOG("Rcmd: resume\n"); - cache_sync(sl); - ret = stlink_run(sl); - if (ret) { - DLOG("Rcmd: resume failed\n"); - reply = strdup("E00"); - } else { - reply = strdup("OK"); - } - - } else if (!strncmp(cmd, "halt", 4)) { // halt - ret = stlink_force_debug(sl); - if (ret) { - DLOG("Rcmd: halt failed\n"); - reply = strdup("E00"); - } else { - reply = strdup("OK"); - DLOG("Rcmd: halt\n"); - } - - } else if (!strncmp(cmd, "jtag_reset", 10)) { // jtag_reset - reply = strdup("OK"); + if (addr + length > data_length) { length = data_length - addr; } - ret = stlink_jtag_reset(sl, 0); - if (ret) { - DLOG("Rcmd: jtag_reset failed with jtag_reset\n"); - reply = strdup("E00"); - } - - ret = stlink_jtag_reset(sl, 1); - if (ret) { - DLOG("Rcmd: jtag_reset failed with jtag_reset\n"); - reply = strdup("E00"); - } - - ret = stlink_force_debug(sl); - if (ret) { - DLOG("Rcmd: jtag_reset failed with force_debug\n"); - reply = strdup("E00"); - } - - if (strcmp(reply, "E00")) { - // no errors have been found - DLOG("Rcmd: jtag_reset\n"); - } - } else if (!strncmp(cmd, "reset", 5)) { //reset - - ret = stlink_force_debug(sl); - if (ret) { - DLOG("Rcmd: reset failed with force_debug\n"); - reply = strdup("E00"); - } - - ret = stlink_reset(sl); - if (ret) { - DLOG("Rcmd: reset failed with reset\n"); - reply = strdup("E00"); - } - - init_code_breakpoints(sl); - init_data_watchpoints(sl); - - if (reply == NULL) { - reply = strdup("OK"); - DLOG("Rcmd: reset\n"); - } - - } else if (!strncmp(cmd, "semihosting ", 12)) { - DLOG("Rcmd: got semihosting cmd '%s'", cmd); - char *arg = cmd + 12; - - // Skip whitespaces - while (isspace(*arg)) { arg++; } - - if (!strncmp(arg, "enable", 6) || !strncmp(arg, "1", 1)) { - semihosting = true; - reply = strdup("OK"); - } else if (!strncmp(arg, "disable", 7) || !strncmp(arg, "0", 1)) { - semihosting = false; - reply = strdup("OK"); - } else { - DLOG("Rcmd: unknown semihosting arg: '%s'\n", arg); - } + if (length == 0) { + reply = strdup("l"); } else { - DLOG("Rcmd: %s\n", cmd); + reply = calloc(length + 2, 1); + reply[0] = 'm'; + strncpy(&reply[1], data, length); } - free(cmd); } + } else if (!strncmp(queryName, "Rcmd,", 4)) { + // Rcmd uses the wrong separator + separator = strstr(packet, ","); + params = ""; - if (reply == NULL) - reply = strdup(""); + if (separator == NULL) { + separator = packet + strlen(packet); + } else { + params = separator + 1; + } - free(queryName); + size_t hex_len = strlen(params); + size_t alloc_size = (hex_len / 2) + 1; + size_t cmd_len; + char *cmd = malloc(alloc_size); - break; - } - - case 'v': { - char *params = NULL; - char *cmdName = strtok_r(packet, ":;", ¶ms); + if (cmd == NULL) { + DLOG("Rcmd unhexify allocation error\n"); + break; + } - cmdName++; // vCommand -> Command + cmd_len = unhexify(params, cmd, alloc_size - 1); + cmd[cmd_len] = 0; - if (!strcmp(cmdName, "FlashErase")) { - char *__s_addr, *s_length; - char *tok = params; + DLOG("unhexified Rcmd: '%s'\n", cmd); - __s_addr = strsep(&tok, ","); - s_length = tok; + if (!strncmp(cmd, "resume", 6)) { // resume + DLOG("Rcmd: resume\n"); + cache_sync(sl); + ret = stlink_run(sl); - unsigned addr = (unsigned int) strtoul(__s_addr, NULL, 16), - length = (unsigned int) strtoul(s_length, NULL, 16); + if (ret) { + DLOG("Rcmd: resume failed\n"); + reply = strdup("E00"); + } else { + reply = strdup("OK"); + } - DLOG("FlashErase: addr:%08x,len:%04x\n", - addr, length); + } else if (!strncmp(cmd, "halt", 4)) { // halt + ret = stlink_force_debug(sl); - if (flash_add_block(addr, length, sl) < 0) { + if (ret) { + DLOG("Rcmd: halt failed\n"); reply = strdup("E00"); } else { reply = strdup("OK"); + DLOG("Rcmd: halt\n"); } - } else if (!strcmp(cmdName, "FlashWrite")) { - char *__s_addr, *data; - char *tok = params; - - __s_addr = strsep(&tok, ":"); - data = tok; - - unsigned addr = (unsigned int) strtoul(__s_addr, NULL, 16); - unsigned data_length = status - (unsigned int) (data - packet); - - // Length of decoded data cannot be more than encoded, as escapes are removed. - // Additional byte is reserved for alignment fix. - uint8_t *decoded = calloc(data_length + 1, 1); - unsigned dec_index = 0; - for (unsigned int i = 0; i < data_length; i++) { - if (data[i] == 0x7d) { - i++; - decoded[dec_index++] = data[i] ^ 0x20; - } else { - decoded[dec_index++] = data[i]; - } + + } else if (!strncmp(cmd, "jtag_reset", 10)) { // jtag_reset + reply = strdup("OK"); + ret = stlink_jtag_reset(sl, 0); + + if (ret) { + DLOG("Rcmd: jtag_reset failed with jtag_reset\n"); + reply = strdup("E00"); } - // fix alignment - if (dec_index % 2 != 0) dec_index++; + ret = stlink_jtag_reset(sl, 1); - DLOG("binary packet %d -> %d\n", data_length, dec_index); + if (ret) { + DLOG("Rcmd: jtag_reset failed with jtag_reset\n"); + reply = strdup("E00"); + } - if (flash_populate(addr, decoded, dec_index) < 0) { + ret = stlink_force_debug(sl); + + if (ret) { + DLOG("Rcmd: jtag_reset failed with force_debug\n"); reply = strdup("E00"); - } else { - reply = strdup("OK"); } - free(decoded); - } else if (!strcmp(cmdName, "FlashDone")) { - if (flash_go(sl) < 0) { + if (strcmp(reply, "E00")) { + // no errors have been found + DLOG("Rcmd: jtag_reset\n"); + } + } else if (!strncmp(cmd, "reset", 5)) { // reset + + ret = stlink_force_debug(sl); + + if (ret) { + DLOG("Rcmd: reset failed with force_debug\n"); reply = strdup("E00"); - } else { - reply = strdup("OK"); } - } else if (!strcmp(cmdName, "Kill")) { - attached = 0; - reply = strdup("OK"); - } - if (reply == NULL) - reply = strdup(""); + ret = stlink_reset(sl); - break; - } + if (ret) { + DLOG("Rcmd: reset failed with reset\n"); + reply = strdup("E00"); + } + + init_code_breakpoints(sl); + init_data_watchpoints(sl); - case 'c': - cache_sync(sl); - ret = stlink_run(sl); - if (ret) DLOG("Semihost: run failed\n"); - - while (1) { - status = gdb_check_for_interrupt(client); - if (status < 0) { - ELOG("cannot check for int: %d\n", status); - close_socket(client); - return 1; + if (reply == NULL) { + reply = strdup("OK"); + DLOG("Rcmd: reset\n"); } - if (status == 1) { - stlink_force_debug(sl); - break; + } else if (!strncmp(cmd, "semihosting ", 12)) { + DLOG("Rcmd: got semihosting cmd '%s'", cmd); + char *arg = cmd + 12; + + while (isspace(*arg)) { arg++; } // skip whitespaces + + if (!strncmp(arg, "enable", 6) || !strncmp(arg, "1", 1)) { + semihosting = true; + reply = strdup("OK"); + } else if (!strncmp(arg, "disable", 7) || !strncmp(arg, "0", 1)) { + semihosting = false; + reply = strdup("OK"); + } else { + DLOG("Rcmd: unknown semihosting arg: '%s'\n", arg); } + } else { + DLOG("Rcmd: %s\n", cmd); + } - ret = stlink_status(sl); - if (ret) DLOG("Semihost: status failed\n"); - if(sl->core_stat == TARGET_HALTED) { - struct stlink_reg reg; - stm32_addr_t pc; - stm32_addr_t addr; - int offset = 0; - uint16_t insn; + free(cmd); + } - if (!semihosting) break; + if (reply == NULL) { reply = strdup(""); } - ret = stlink_read_all_regs (sl, ®); - if (ret) DLOG("Semihost: read_all_regs failed\n"); + free(queryName); + break; + } - // Read PC - pc = reg.r[15]; + case 'v': { + char *params = NULL; + char *cmdName = strtok_r(packet, ":;", ¶ms); - // Compute aligned value - offset = pc % 4; - addr = pc - offset; + cmdName++; // vCommand -> Command - // Read instructions (address and length must be aligned). - ret = stlink_read_mem32(sl, addr, (offset > 2 ? 8 : 4)); + if (!strcmp(cmdName, "FlashErase")) { + char *__s_addr, *s_length; + char *tok = params; - if (ret != 0) { - DLOG("Semihost: cannot read instructions at: 0x%08x\n", addr); - break; - } + __s_addr = strsep(&tok, ","); + s_length = tok; - memcpy(&insn, &sl->q_buf[offset], sizeof(insn)); + unsigned addr = (unsigned int)strtoul(__s_addr, NULL, 16), + length = (unsigned int)strtoul(s_length, NULL, 16); - if (insn == 0xBEAB && !has_breakpoint(addr)) { + DLOG("FlashErase: addr:%08x,len:%04x\n", + addr, length); - ret = do_semihosting (sl, reg.r[0], reg.r[1], ®.r[0]); - if (ret) DLOG("Semihost: do_semihosting failed\n"); + if (flash_add_block(addr, length, sl) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + } + } else if (!strcmp(cmdName, "FlashWrite")) { + char *__s_addr, *data; + char *tok = params; - // Write return value - ret = stlink_write_reg(sl, reg.r[0], 0); - if (ret) DLOG("Semihost: write_reg failed for return value\n"); + __s_addr = strsep(&tok, ":"); + data = tok; - // Jump over the break instruction - ret = stlink_write_reg(sl, reg.r[15] + 2, 15); - if (ret) DLOG("Semihost: write_reg failed for jumping over break\n"); + unsigned addr = (unsigned int)strtoul(__s_addr, NULL, 16); + unsigned data_length = status - (unsigned int)(data - packet); - // Continue execution - cache_sync(sl); - ret = stlink_run(sl); - if (ret) DLOG("Semihost: continue execution failed with stlink_run\n"); - } else { - break; - } - } + // Length of decoded data cannot be more than encoded, as escapes are removed. + // Additional byte is reserved for alignment fix. + uint8_t *decoded = calloc(data_length + 1, 1); + unsigned dec_index = 0; - usleep(100000); + for (unsigned int i = 0; i < data_length; i++) { + if (data[i] == 0x7d) { + i++; + decoded[dec_index++] = data[i] ^ 0x20; + } else { + decoded[dec_index++] = data[i]; + } } - reply = strdup("S05"); // TRAP - break; + // fix alignment + if (dec_index % 2 != 0) { dec_index++; } + + DLOG("binary packet %d -> %d\n", data_length, dec_index); - case 's': - cache_sync(sl); - ret = stlink_step(sl); - if (ret) { - // ... having a problem sending step packet - ELOG("Step: cannot send step request\n"); + if (flash_populate(addr, decoded, dec_index) < 0) { reply = strdup("E00"); - critical_error = 1; // absolutely critical } else { - reply = strdup("S05"); // TRAP + reply = strdup("OK"); } - break; - - case '?': - if (attached) { - reply = strdup("S05"); // TRAP + free(decoded); + } else if (!strcmp(cmdName, "FlashDone")) { + if (flash_go(sl) < 0) { + reply = strdup("E00"); } else { - // Stub shall reply OK if not attached. reply = strdup("OK"); } - break; + } else if (!strcmp(cmdName, "Kill")) { + attached = 0; + reply = strdup("OK"); + } - case 'g': - ret = stlink_read_all_regs(sl, ®p); - if (ret) DLOG("g packet: read_all_regs failed\n"); + if (reply == NULL) { reply = strdup(""); } - reply = calloc(8 * 16 + 1, 1); - for (int i = 0; i < 16; i++) - sprintf(&reply[i * 8], "%08x", (uint32_t)htonl(regp.r[i])); - break; + break; + } - case 'p': { - unsigned id = (unsigned int) strtoul(&packet[1], NULL, 16); - unsigned myreg = 0xDEADDEAD; - - if (id < 16) { - ret = stlink_read_reg(sl, id, ®p); - myreg = htonl(regp.r[id]); - } else if (id == 0x19) { - ret = stlink_read_reg(sl, 16, ®p); - myreg = htonl(regp.xpsr); - } else if (id == 0x1A) { - ret = stlink_read_reg(sl, 17, ®p); - myreg = htonl(regp.main_sp); - } else if (id == 0x1B) { - ret = stlink_read_reg(sl, 18, ®p); - myreg = htonl(regp.process_sp); - } else if (id == 0x1C) { - ret = stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.control); - } else if (id == 0x1D) { - ret = stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.faultmask); - } else if (id == 0x1E) { - ret = stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.basepri); - } else if (id == 0x1F) { - ret = stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.primask); - } else if (id >= 0x20 && id < 0x40) { - ret = stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.s[id-0x20]); - } else if (id == 0x40) { - ret = stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.fpscr); - } else { - ret = 1; - reply = strdup("E00"); + case 'c': + cache_sync(sl); + ret = stlink_run(sl); + + if (ret) { DLOG("Semihost: run failed\n"); } + + while (1) { + status = gdb_check_for_interrupt(client); + + if (status < 0) { + ELOG("cannot check for int: %d\n", status); + close_socket(client); + return(1); } - if (ret) DLOG("p packet: stlink_read_unsupported_reg failed with id %u\n", id); - if (reply == NULL) { - // If reply is set to "E00", skip - reply = calloc(8 + 1, 1); - sprintf(reply, "%08x", myreg); + if (status == 1) { + stlink_force_debug(sl); + break; } - break; - } + ret = stlink_status(sl); - case 'P': { - char* s_reg = &packet[1]; - char* s_value = strstr(&packet[1], "=") + 1; - - unsigned reg = (unsigned int) strtoul(s_reg, NULL, 16); - unsigned value = (unsigned int) strtoul(s_value, NULL, 16); - - - if (reg < 16) { - ret = stlink_write_reg(sl, ntohl(value), reg); - } else if (reg == 0x19) { - ret = stlink_write_reg(sl, ntohl(value), 16); - } else if (reg == 0x1A) { - ret = stlink_write_reg(sl, ntohl(value), 17); - } else if (reg == 0x1B) { - ret = stlink_write_reg(sl, ntohl(value), 18); - } else if (reg == 0x1C) { - ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if (reg == 0x1D) { - ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if (reg == 0x1E) { - ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if (reg == 0x1F) { - ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if (reg >= 0x20 && reg < 0x40) { - ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if (reg == 0x40) { - ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else { - ret = 1; - reply = strdup("E00"); + if (ret) { DLOG("Semihost: status failed\n"); } + + if (sl->core_stat == TARGET_HALTED) { + struct stlink_reg reg; + stm32_addr_t pc; + stm32_addr_t addr; + int offset = 0; + uint16_t insn; + + if (!semihosting) { break; } + + ret = stlink_read_all_regs (sl, ®); + + if (ret) { DLOG("Semihost: read_all_regs failed\n"); } + + // read PC + pc = reg.r[15]; + + // compute aligned value + offset = pc % 4; + addr = pc - offset; + + // read instructions (address and length must be aligned). + ret = stlink_read_mem32(sl, addr, (offset > 2 ? 8 : 4)); + + if (ret != 0) { + DLOG("Semihost: cannot read instructions at: 0x%08x\n", addr); + break; + } + + memcpy(&insn, &sl->q_buf[offset], sizeof(insn)); + + if (insn == 0xBEAB && !has_breakpoint(addr)) { + + ret = do_semihosting (sl, reg.r[0], reg.r[1], ®.r[0]); + + if (ret) { DLOG("Semihost: do_semihosting failed\n"); } + + // write return value + ret = stlink_write_reg(sl, reg.r[0], 0); + + if (ret) { DLOG("Semihost: write_reg failed for return value\n"); } + + // jump over the break instruction + ret = stlink_write_reg(sl, reg.r[15] + 2, 15); + + if (ret) { DLOG("Semihost: write_reg failed for jumping over break\n"); } + + // continue execution + cache_sync(sl); + ret = stlink_run(sl); + + if (ret) { DLOG("Semihost: continue execution failed with stlink_run\n"); } + } else { + break; + } } - if (ret) DLOG("P packet: stlink_write_unsupported_reg failed with reg %u\n", reg); - if (reply == NULL) reply = strdup("OK"); // note that NULL may not be zero - break; + usleep(100000); } - case 'G': - for (int i = 0; i < 16; i++) { - char str[9] = {0}; - strncpy(str, &packet[1 + i * 8], 8); - uint32_t reg = (uint32_t) strtoul(str, NULL, 16); - ret = stlink_write_reg(sl, ntohl(reg), i); - if (ret) DLOG("G packet: stlink_write_reg failed"); - } + reply = strdup("S05"); // TRAP + break; - reply = strdup("OK"); - break; + case 's': + cache_sync(sl); + ret = stlink_step(sl); - case 'm': { - char* s_start = &packet[1]; - char* s_count = strstr(&packet[1], ",") + 1; + if (ret) { + // ... having a problem sending step packet + ELOG("Step: cannot send step request\n"); + reply = strdup("E00"); + critical_error = 1; // absolutely critical + } else { + reply = strdup("S05"); // TRAP + } - stm32_addr_t start = (stm32_addr_t) strtoul(s_start, NULL, 16); - unsigned count = (unsigned int) strtoul(s_count, NULL, 16); + break; - unsigned adj_start = start % 4; - unsigned count_rnd = (count + adj_start + 4 - 1) / 4 * 4; - if (count_rnd > sl->flash_pgsz) count_rnd = (unsigned int) sl->flash_pgsz; - if (count_rnd > 0x1800) count_rnd = 0x1800; - if (count_rnd < count) count = count_rnd; + case '?': - if (stlink_read_mem32(sl, start - adj_start, count_rnd) != 0) count = 0; - // read failed somehow, don't return stale buffer + if (attached) { + reply = strdup("S05"); // TRAP + } else { + reply = strdup("OK"); // stub shall reply OK if not attached + } - reply = calloc(count * 2 + 1, 1); - for (unsigned int i = 0; i < count; i++) { - reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4]; - reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf]; - } + break; - break; + case 'g': + ret = stlink_read_all_regs(sl, ®p); + + if (ret) { DLOG("g packet: read_all_regs failed\n"); } + + reply = calloc(8 * 16 + 1, 1); + + for (int i = 0; i < 16; i++) { + sprintf(&reply[i * 8], "%08x", (uint32_t)htonl(regp.r[i])); } - case 'M': { - char* s_start = &packet[1]; - char* s_count = strstr(&packet[1], ",") + 1; - char* hexdata = strstr(packet, ":") + 1; - - stm32_addr_t start = (stm32_addr_t) strtoul(s_start, NULL, 16); - unsigned count = (unsigned int) strtoul(s_count, NULL, 16); - int err = 0; - - if (start % 4) { - unsigned align_count = 4 - start % 4; - if (align_count > count) align_count = count; - for (unsigned int i = 0; i < align_count; i ++) { - char hextmp[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; - uint8_t byte = strtoul(hextmp, NULL, 16); - sl->q_buf[i] = byte; - } - err |= stlink_write_mem8(sl, start, align_count); - cache_change(start, align_count); - start += align_count; - count -= align_count; - hexdata += 2*align_count; - } + break; - if (count - count % 4) { - unsigned aligned_count = count - count % 4; + case 'p': { + unsigned id = (unsigned int)strtoul(&packet[1], NULL, 16); + unsigned myreg = 0xDEADDEAD; + + if (id < 16) { + ret = stlink_read_reg(sl, id, ®p); + myreg = htonl(regp.r[id]); + } else if (id == 0x19) { + ret = stlink_read_reg(sl, 16, ®p); + myreg = htonl(regp.xpsr); + } else if (id == 0x1A) { + ret = stlink_read_reg(sl, 17, ®p); + myreg = htonl(regp.main_sp); + } else if (id == 0x1B) { + ret = stlink_read_reg(sl, 18, ®p); + myreg = htonl(regp.process_sp); + } else if (id == 0x1C) { + ret = stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.control); + } else if (id == 0x1D) { + ret = stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.faultmask); + } else if (id == 0x1E) { + ret = stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.basepri); + } else if (id == 0x1F) { + ret = stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.primask); + } else if (id >= 0x20 && id < 0x40) { + ret = stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.s[id - 0x20]); + } else if (id == 0x40) { + ret = stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.fpscr); + } else { + ret = 1; + reply = strdup("E00"); + } - for (unsigned int i = 0; i < aligned_count; i ++) { - char hextmp[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; - uint8_t byte = strtoul(hextmp, NULL, 16); - sl->q_buf[i] = byte; - } - err |= stlink_write_mem32(sl, start, aligned_count); - cache_change(start, aligned_count); - count -= aligned_count; - start += aligned_count; - hexdata += 2*aligned_count; - } + if (ret) { DLOG("p packet: stlink_read_unsupported_reg failed with id %u\n", id); } - if (count) { - for (unsigned int i = 0; i < count; i ++) { - char hextmp[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; - uint8_t byte = strtoul(hextmp, NULL, 16); - sl->q_buf[i] = byte; - } - err |= stlink_write_mem8(sl, start, count); - cache_change(start, count); - } - reply = strdup(err ? "E00" : "OK"); - break; + if (reply == NULL) { + // if reply is set to "E00", skip + reply = calloc(8 + 1, 1); + sprintf(reply, "%08x", myreg); } - case 'Z': { - char *endptr; - stm32_addr_t addr = (stm32_addr_t) strtoul(&packet[3], &endptr, 16); - stm32_addr_t len = (stm32_addr_t) strtoul(&endptr[1], NULL, 16); - - switch (packet[1]) { - case '1': - if (update_code_breakpoint(sl, addr, 1) < 0) { - reply = strdup("E00"); - } else { - reply = strdup("OK"); - } - break; + break; + } - case '2': // insert write watchpoint - case '3': // insert read watchpoint - case '4': { // insert access watchpoint - enum watchfun wf; - if (packet[1] == '2') { - wf = WATCHWRITE; - } else if (packet[1] == '3') { - wf = WATCHREAD; - } else { - wf = WATCHACCESS; - } - - if (add_data_watchpoint(sl, wf, addr, len) < 0) { - reply = strdup("E00"); - } else { - reply = strdup("OK"); - break; - } - } - break; + case 'P': { + char* s_reg = &packet[1]; + char* s_value = strstr(&packet[1], "=") + 1; + + unsigned reg = (unsigned int)strtoul(s_reg, NULL, 16); + unsigned value = (unsigned int)strtoul(s_value, NULL, 16); + + + if (reg < 16) { + ret = stlink_write_reg(sl, ntohl(value), reg); + } else if (reg == 0x19) { + ret = stlink_write_reg(sl, ntohl(value), 16); + } else if (reg == 0x1A) { + ret = stlink_write_reg(sl, ntohl(value), 17); + } else if (reg == 0x1B) { + ret = stlink_write_reg(sl, ntohl(value), 18); + } else if (reg == 0x1C) { + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if (reg == 0x1D) { + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if (reg == 0x1E) { + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if (reg == 0x1F) { + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if (reg >= 0x20 && reg < 0x40) { + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if (reg == 0x40) { + ret = stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else { + ret = 1; + reply = strdup("E00"); + } - default: - reply = strdup(""); - } - break; + if (ret) { DLOG("P packet: stlink_write_unsupported_reg failed with reg %u\n", reg); } + + if (reply == NULL) { reply = strdup("OK"); /* Note: NULL may not be zero */ } + + break; + } + + case 'G': + + for (int i = 0; i < 16; i++) { + char str[9] = {0}; + strncpy(str, &packet[1 + i * 8], 8); + uint32_t reg = (uint32_t)strtoul(str, NULL, 16); + ret = stlink_write_reg(sl, ntohl(reg), i); + + if (ret) { DLOG("G packet: stlink_write_reg failed"); } } - case 'z': { - char *endptr; - stm32_addr_t addr = (stm32_addr_t) strtoul(&packet[3], &endptr, 16); - //stm32_addr_t len = strtoul(&endptr[1], NULL, 16); - - switch (packet[1]) { - case '1': // remove breakpoint - update_code_breakpoint(sl, addr, 0); - reply = strdup("OK"); - break; - case '2' : // remove write watchpoint - case '3' : // remove read watchpoint - case '4' : // remove access watchpoint - if (delete_data_watchpoint(sl, addr) < 0) { - reply = strdup("E00"); - break; - } else { - reply = strdup("OK"); - break; - } - - default: - reply = strdup(""); - } - break; + reply = strdup("OK"); + break; + + case 'm': { + char* s_start = &packet[1]; + char* s_count = strstr(&packet[1], ",") + 1; + + stm32_addr_t start = (stm32_addr_t)strtoul(s_start, NULL, 16); + unsigned count = (unsigned int)strtoul(s_count, NULL, 16); + + unsigned adj_start = start % 4; + unsigned count_rnd = (count + adj_start + 4 - 1) / 4 * 4; + + if (count_rnd > sl->flash_pgsz) { count_rnd = (unsigned int)sl->flash_pgsz; } + + if (count_rnd > 0x1800) { count_rnd = 0x1800; } + + if (count_rnd < count) { count = count_rnd; } + + if (stlink_read_mem32(sl, start - adj_start, count_rnd) != 0) { count = 0; } + + // read failed somehow, don't return stale buffer + + reply = calloc(count * 2 + 1, 1); + + for (unsigned int i = 0; i < count; i++) { + reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4]; + reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf]; } - case '!': { - // Enter extended mode which allows restarting. We do support that always. + break; + } - // Also, set to persistent mode to allow GDB disconnect. - st->persistent = 1; + case 'M': { + char* s_start = &packet[1]; + char* s_count = strstr(&packet[1], ",") + 1; + char* hexdata = strstr(packet, ":") + 1; - reply = strdup("OK"); + stm32_addr_t start = (stm32_addr_t)strtoul(s_start, NULL, 16); + unsigned count = (unsigned int)strtoul(s_count, NULL, 16); + int err = 0; - break; + if (start % 4) { + unsigned align_count = 4 - start % 4; + + if (align_count > count) { align_count = count; } + + for (unsigned int i = 0; i < align_count; i++) { + char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 }; + uint8_t byte = strtoul(hextmp, NULL, 16); + sl->q_buf[i] = byte; + } + + err |= stlink_write_mem8(sl, start, align_count); + cache_change(start, align_count); + start += align_count; + count -= align_count; + hexdata += 2 * align_count; } - case 'R': { - // Reset the core. - ret = stlink_reset(sl); - if (ret) { - DLOG("R packet : stlink_reset failed\n"); + if (count - count % 4) { + unsigned aligned_count = count - count % 4; + + for (unsigned int i = 0; i < aligned_count; i++) { + char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 }; + uint8_t byte = strtoul(hextmp, NULL, 16); + sl->q_buf[i] = byte; } - init_code_breakpoints(sl); - init_data_watchpoints(sl); - attached = 1; + err |= stlink_write_mem32(sl, start, aligned_count); + cache_change(start, aligned_count); + count -= aligned_count; + start += aligned_count; + hexdata += 2 * aligned_count; + } - reply = strdup("OK"); + if (count) { + for (unsigned int i = 0; i < count; i++) { + char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 }; + uint8_t byte = strtoul(hextmp, NULL, 16); + sl->q_buf[i] = byte; + } + + err |= stlink_write_mem8(sl, start, count); + cache_change(start, count); + } + + reply = strdup(err ? "E00" : "OK"); + break; + } + + case 'Z': { + char *endptr; + stm32_addr_t addr = (stm32_addr_t)strtoul(&packet[3], &endptr, 16); + stm32_addr_t len = (stm32_addr_t)strtoul(&endptr[1], NULL, 16); + + switch (packet[1]) { + case '1': + + if (update_code_breakpoint(sl, addr, 1) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + } break; + + case '2': // insert write watchpoint + case '3': // insert read watchpoint + case '4': { // insert access watchpoint + enum watchfun wf; + + if (packet[1] == '2') { + wf = WATCHWRITE; + } else if (packet[1] == '3') { + wf = WATCHREAD; + } else { + wf = WATCHACCESS; + } + + if (add_data_watchpoint(sl, wf, addr, len) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + break; + } } - case 'k': - // Kill request - reset the connection itself - ret = stlink_run(sl); - if (ret) DLOG("Kill: stlink_run failed\n"); - ret = stlink_exit_debug_mode(sl); - if (ret) DLOG("Kill: stlink_exit_debug_mode failed\n"); - stlink_close(sl); - - sl = do_connect(st); - if (sl == NULL || sl->chip_id == STLINK_CHIPID_UNKNOWN) cleanup(0); - connected_stlink = sl; - - if (st->reset) stlink_reset(sl); - ret = stlink_force_debug(sl); - if (ret) DLOG("Kill: stlink_force_debug failed\n"); - init_cache(sl); - init_code_breakpoints(sl); - init_data_watchpoints(sl); - - reply = NULL; // no response + break; + default: + reply = strdup(""); + } + break; + } + case 'z': { + char *endptr; + stm32_addr_t addr = (stm32_addr_t)strtoul(&packet[3], &endptr, 16); + // stm32_addr_t len = strtoul(&endptr[1], NULL, 16); + + switch (packet[1]) { + case '1': // remove breakpoint + update_code_breakpoint(sl, addr, 0); + reply = strdup("OK"); break; + case '2': // remove write watchpoint + case '3': // remove read watchpoint + case '4': // remove access watchpoint + + if (delete_data_watchpoint(sl, addr) < 0) { + reply = strdup("E00"); + break; + } else { + reply = strdup("OK"); + break; + } + default: reply = strdup(""); + } + break; + } + + case '!': { + // enter extended mode which allows restarting. We do support that always. + // also, set to persistent mode to allow GDB disconnect. + st->persistent = 1; + + reply = strdup("OK"); + break; + } + + case 'R': { + // reset the core. + ret = stlink_reset(sl); + + if (ret) { DLOG("R packet : stlink_reset failed\n"); } + + init_code_breakpoints(sl); + init_data_watchpoints(sl); + + attached = 1; + + reply = strdup("OK"); + break; + } + case 'k': + // kill request - reset the connection itself + ret = stlink_run(sl); + + if (ret) { DLOG("Kill: stlink_run failed\n"); } + + ret = stlink_exit_debug_mode(sl); + + if (ret) { DLOG("Kill: stlink_exit_debug_mode failed\n"); } + + stlink_close(sl); + + sl = do_connect(st); + + if (sl == NULL || sl->chip_id == STLINK_CHIPID_UNKNOWN) { cleanup(0); } + + connected_stlink = sl; + + if (st->reset) { stlink_reset(sl); } + + ret = stlink_force_debug(sl); + + if (ret) { DLOG("Kill: stlink_force_debug failed\n"); } + + init_cache(sl); + init_code_breakpoints(sl); + init_data_watchpoints(sl); + + reply = NULL; // no response + break; + + default: + reply = strdup(""); } if (reply) { DLOG("send: %s\n", reply); int result = gdb_send_packet(client, reply); + if (result != 0) { ELOG("cannot send: %d\n", result); free(reply); free(packet); close_socket(client); - return 1; + return(1); } free(reply); @@ -1750,13 +1859,12 @@ int serve(stlink_t *sl, st_state_t *st) { if (critical_error) { close_socket(client); - return 1; + return(1); } free(packet); } close_socket(client); - - return 0; + return(0); } diff --git a/src/st-util/gdb-server.h b/src/st-util/gdb-server.h index 8c8d47114..b50a7941d 100644 --- a/src/st-util/gdb-server.h +++ b/src/st-util/gdb-server.h @@ -8,4 +8,4 @@ #define DEBUG_LOGGING_LEVEL 100 #define DEFAULT_GDB_LISTEN_PORT 4242 -#endif +#endif // _GDB_SERVER_H diff --git a/src/st-util/semihosting.c b/src/st-util/semihosting.c index cb03868cd..821dcdbbb 100644 --- a/src/st-util/semihosting.c +++ b/src/st-util/semihosting.c @@ -13,13 +13,13 @@ static int mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) { int offset = addr % 4; int len = 4; - if (sl == NULL || data == NULL) return -1; + if (sl == NULL || data == NULL) { return(-1); } - /* Read address and length must be aligned */ - if (stlink_read_mem32(sl, addr - offset, len) != 0) return -1; + // read address and length must be aligned + if (stlink_read_mem32(sl, addr - offset, len) != 0) { return(-1); } *data = sl->q_buf[offset]; - return 0; + return(0); } #ifdef UNUSED @@ -27,26 +27,26 @@ static int mem_read_u16(stlink_t *sl, uint32_t addr, uint16_t *data) { int offset = addr % 4; int len = (offset > 2 ? 8 : 4); - if (sl == NULL || data == NULL) return -1; + if (sl == NULL || data == NULL) { return(-1); } - /* Read address and length must be aligned */ - if (stlink_read_mem32(sl, addr - offset, len) != 0) return -1; + // read address and length must be aligned + if (stlink_read_mem32(sl, addr - offset, len) != 0) { return(-1); } memcpy(data, &sl->q_buf[offset], sizeof(*data)); - return 0; + return(0); } static int mem_read_u32(stlink_t *sl, uint32_t addr, uint32_t *data) { int offset = addr % 4; int len = (offset > 0 ? 8 : 4); - if (sl == NULL || data == NULL) return -1; + if (sl == NULL || data == NULL) { return(-1); } - /* Read address and length must be aligned */ - if (stlink_read_mem32(sl, addr - offset, len) != 0) return -1; + // read address and length must be aligned + if (stlink_read_mem32(sl, addr - offset, len) != 0) { return(-1); } memcpy(data, &sl->q_buf[offset], sizeof(*data)); - return 0; + return(0); } #endif @@ -54,50 +54,42 @@ static int mem_read(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { int offset = addr % 4; int read_len = len + offset; - if (sl == NULL || data == NULL) return -1; + if (sl == NULL || data == NULL) { return(-1); } - /* Align read size */ - if ((read_len % 4) != 0) { - read_len += 4 - (read_len % 4); - } + // align read size + if ((read_len % 4) != 0) { read_len += 4 - (read_len % 4); } - /* Address and length must be aligned */ - if (stlink_read_mem32(sl, addr - offset, read_len) != 0) return -1; + // address and length must be aligned + if (stlink_read_mem32(sl, addr - offset, read_len) != 0) { return(-1); } memcpy(data, &sl->q_buf[offset], len); - return 0; + return(0); } static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { - // Note: this function can write more than it is asked to! - // If addr is not an even 32 bit boundary, or len is not a multiple of 4. - // - // If only 32 bit values can be written to the target, - // then this function should read the target memory at the - // start and end of the buffer where it will write more that - // the requested bytes. (perhaps reading the whole area is faster??). - // - // If 16 and 8 bit writes are available, then they could be used instead. - - // Just return when the length is zero avoiding unneeded work. - if (len == 0) return 0; + /* Note: this function can write more than it is asked to! + * If addr is not an even 32 bit boundary, or len is not a multiple of 4. + * If only 32 bit values can be written to the target, then this function should read + * the target memory at the start and end of the buffer where it will write more that + * the requested bytes. (perhaps reading the whole area is faster??). + * If 16 and 8 bit writes are available, then they could be used instead. + * Just return when the length is zero avoiding unneeded work. */ + if (len == 0) { return(0); } int offset = addr % 4; int write_len = len + offset; - if (sl == NULL || data == NULL) return -1; + if (sl == NULL || data == NULL) { return(-1); } - /* Align read size */ - if ((write_len % 4) != 0) { - write_len += 4 - (write_len % 4); - } + // align read size + if ((write_len % 4) != 0) { write_len += 4 - (write_len % 4); } memcpy(&sl->q_buf[offset], data, len); - /* Address and length must be aligned */ - if (stlink_write_mem32(sl, addr - offset, write_len) != 0) return -1; + // address and length must be aligned + if (stlink_write_mem32(sl, addr - offset, write_len) != 0) { return(-1); } - return 0; + return(0); } /* For the SYS_WRITE0 call, we don't know the size of the null-terminated buffer @@ -137,7 +129,7 @@ static int saved_errno = 0; int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { - if (sl == NULL || ret == NULL) return -1; + if (sl == NULL || ret == NULL) { return(-1); } DLOG("Do semihosting R0=0x%08x R1=0x%08x\n", r0, r1); @@ -150,11 +142,10 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint32_t name_len; char *name; - if (mem_read(sl, r1, args, sizeof (args)) != 0){ - DLOG("Semihosting SYS_OPEN error: " - "cannot read args from target memory\n"); + if (mem_read(sl, r1, args, sizeof(args)) != 0) { + DLOG("Semihosting SYS_OPEN error: cannot read args from target memory\n"); *ret = -1; - return -1; + return(-1); } name_address = args[0]; @@ -165,7 +156,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { /* Invalid mode */ DLOG("Semihosting SYS_OPEN error: invalid mode %d\n", mode); *ret = -1; - return -1; + return(-1); } /* Add the trailing zero that is not counted in the length argument (see @@ -174,25 +165,24 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { name_len += 1; if (name_len > MAX_BUFFER_SIZE) { - DLOG("Semihosting SYS_OPEN error: name buffer size is too big %d\n", - name_len); + DLOG("Semihosting SYS_OPEN error: name buffer size is too big %d\n", name_len); *ret = -1; - return -1; + return(-1); } + name = malloc(name_len); if (name == NULL) { DLOG("Semihosting SYS_OPEN error: cannot allocate name buffer\n"); *ret = -1; - return -1; + return(-1); } - if (mem_read(sl, name_address, name, name_len) != 0){ + if (mem_read(sl, name_address, name, name_len) != 0) { free(name); *ret = -1; - DLOG("Semihosting SYS_OPEN error: " - "cannot read name from target memory\n"); - return -1; + DLOG("Semihosting SYS_OPEN error: cannot read name from target memory\n"); + return(-1); } DLOG("Semihosting: open('%s', (SH open mode)%d, 0644)\n", name, mode); @@ -208,13 +198,12 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { case SEMIHOST_SYS_CLOSE: { uint32_t args[1]; - int fd; + int fd; - if (mem_read(sl, r1, args, sizeof (args)) != 0){ - DLOG("Semihosting SYS_CLOSE error: " - "cannot read args from target memory\n"); + if (mem_read(sl, r1, args, sizeof(args)) != 0) { + DLOG("Semihosting SYS_CLOSE error: cannot read args from target memory\n"); *ret = -1; - return -1; + return(-1); } fd = (int)args[0]; @@ -231,15 +220,14 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { { uint32_t args[3]; uint32_t buffer_address; - int fd; + int fd; uint32_t buffer_len; void *buffer; - if (mem_read(sl, r1, args, sizeof (args)) != 0){ - DLOG("Semihosting SYS_WRITE error: " - "cannot read args from target memory\n"); + if (mem_read(sl, r1, args, sizeof(args)) != 0) { + DLOG("Semihosting SYS_WRITE error: cannot read args from target memory\n"); *ret = -1; - return -1; + return(-1); } fd = (int)args[0]; @@ -248,9 +236,9 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (buffer_len > MAX_BUFFER_SIZE) { DLOG("Semihosting SYS_WRITE error: buffer size is too big %d\n", - buffer_len); + buffer_len); *ret = buffer_len; - return -1; + return(-1); } buffer = malloc(buffer_len); @@ -258,19 +246,18 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (buffer == NULL) { DLOG("Semihosting SYS_WRITE error: cannot allocate buffer\n"); *ret = buffer_len; - return -1; + return(-1); } - if (mem_read(sl, buffer_address, buffer, buffer_len) != 0){ - DLOG("Semihosting SYS_WRITE error: " - "cannot read buffer from target memory\n"); + if (mem_read(sl, buffer_address, buffer, buffer_len) != 0) { + DLOG("Semihosting SYS_WRITE error: cannot read buffer from target memory\n"); free(buffer); *ret = buffer_len; - return -1; + return(-1); } - DLOG("Semihosting: write(%d, target_addr:0x%08x, %zu)\n", fd, - buffer_address, buffer_len); + DLOG("Semihosting: write(%d, target_addr:0x%08x, %zu)\n", fd, buffer_address, + buffer_len); *ret = (uint32_t)write(fd, buffer, buffer_len); saved_errno = errno; @@ -289,16 +276,15 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { { uint32_t args[3]; uint32_t buffer_address; - int fd; + int fd; uint32_t buffer_len; void *buffer; - ssize_t read_result; + ssize_t read_result; - if (mem_read(sl, r1, args, sizeof (args)) != 0){ - DLOG("Semihosting SYS_READ error: " - "cannot read args from target memory\n"); + if (mem_read(sl, r1, args, sizeof(args)) != 0) { + DLOG("Semihosting SYS_READ error: cannot read args from target memory\n"); *ret = -1; - return -1; + return(-1); } fd = (int)args[0]; @@ -306,10 +292,9 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { buffer_len = args[2]; if (buffer_len > MAX_BUFFER_SIZE) { - DLOG("Semihosting SYS_READ error: buffer size is too big %d\n", - buffer_len); + DLOG("Semihosting SYS_READ error: buffer size is too big %d\n", buffer_len); *ret = buffer_len; - return -1; + return(-1); } buffer = malloc(buffer_len); @@ -317,11 +302,11 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (buffer == NULL) { DLOG("Semihosting SYS_READ error: cannot allocatebuffer\n"); *ret = buffer_len; - return -1; + return(-1); } - DLOG("Semihosting: read(%d, target_addr:0x%08x, %zu)\n", fd, - buffer_address, buffer_len); + DLOG("Semihosting: read(%d, target_addr:0x%08x, %zu)\n", fd, buffer_address, + buffer_len); read_result = read(fd, buffer, buffer_len); saved_errno = errno; @@ -329,12 +314,11 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (read_result == -1) { *ret = buffer_len; } else { - if (mem_write(sl, buffer_address, buffer, read_result) != 0){ - DLOG("Semihosting SYS_READ error: " - "cannot write buffer to target memory\n"); + if (mem_write(sl, buffer_address, buffer, read_result) != 0) { + DLOG("Semihosting SYS_READ error: cannot write buffer to target memory\n"); free(buffer); *ret = buffer_len; - return -1; + return(-1); } else { *ret = buffer_len - (uint32_t)read_result; } @@ -357,11 +341,10 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint32_t name_len; char *name; - if (mem_read(sl, r1, args, sizeof (args)) != 0){ - DLOG("Semihosting SYS_REMOVE error: " - "cannot read args from target memory\n"); + if (mem_read(sl, r1, args, sizeof(args)) != 0) { + DLOG("Semihosting SYS_REMOVE error: cannot read args from target memory\n"); *ret = -1; - return -1; + return(-1); } name_address = args[0]; @@ -373,74 +356,68 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { name_len += 1; if (name_len > MAX_BUFFER_SIZE) { - DLOG("Semihosting SYS_REMOVE error: " - "name buffer size is too big %d\n", name_len); + DLOG("Semihosting SYS_REMOVE error: name buffer size is too big %d\n", + name_len); *ret = -1; - return -1; + return(-1); } + name = malloc(name_len); if (name == NULL) { DLOG("Semihosting SYS_REMOVE error: cannot allocate name buffer\n"); *ret = -1; - return -1; + return(-1); } - if (mem_read(sl, name_address, name, name_len) != 0){ + if (mem_read(sl, name_address, name, name_len) != 0) { free(name); *ret = -1; - DLOG("Semihosting SYS_REMOVE error: " - "cannot read name from target memory\n"); - return -1; + DLOG("Semihosting SYS_REMOVE error: cannot read name from target memory\n"); + return(-1); } DLOG("Semihosting: unlink('%s')\n", name); - *ret = (uint32_t)unlink(name); saved_errno = errno; - DLOG("Semihosting: return %d\n", *ret); - free(name); break; } case SEMIHOST_SYS_SEEK: { uint32_t args[2]; - int fd; - off_t offset; + int fd; + off_t offset; - if (mem_read(sl, r1, args, sizeof (args)) != 0){ - DLOG("Semihosting SYS_SEEK error: " - "cannot read args from target memory\n"); + if (mem_read(sl, r1, args, sizeof(args)) != 0) { + DLOG("Semihosting SYS_SEEK error: cannot read args from target memory\n"); *ret = -1; - return -1; + return(-1); } fd = (int)args[0]; offset = (off_t)args[1]; DLOG("Semihosting: lseek(%d, %d, SEEK_SET)\n", fd, offset); - *ret = (uint32_t)lseek(fd, offset, SEEK_SET); saved_errno = errno; - if (*ret != (uint32_t)-1) { - /* Success */ - *ret = 0; - } + if (*ret != (uint32_t)-1) { *ret = 0; /* Success */ } + DLOG("Semihosting: return %d\n", *ret); break; } case SEMIHOST_SYS_WRITEC: { uint8_t c; + if (mem_read_u8(sl, r1, &c) == 0) { fprintf(stderr, "%c", c); } else { - DLOG("Semihosting WRITEC: " - "cannot read target memory at 0x%08x\n", r1); + DLOG("Semihosting WRITEC: cannot read target memory at 0x%08x\n", r1); } + break; } case SEMIHOST_SYS_READC: @@ -454,24 +431,25 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { uint8_t buf[WRITE0_BUFFER_SIZE]; while (true) { - if (mem_read(sl, r1, buf, WRITE0_BUFFER_SIZE) != 0){ - DLOG("Semihosting WRITE0: " - "cannot read target memory at 0x%08x\n", r1); - return -1; + if (mem_read(sl, r1, buf, WRITE0_BUFFER_SIZE) != 0) { + DLOG("Semihosting WRITE0: cannot read target memory at 0x%08x\n", r1); + return(-1); } + for (int i = 0; i < WRITE0_BUFFER_SIZE; i++) { - if (buf[i] == 0) { - return 0; - } + if (buf[i] == 0) { return(0); } + fprintf(stderr, "%c", buf[i]); } + r1 += WRITE0_BUFFER_SIZE; } + break; } default: fprintf(stderr, "semihosting: unsupported call %#x\n", r0); - return -1; + return(-1); } - return 0; + return(0); } diff --git a/src/st-util/semihosting.h b/src/st-util/semihosting.h index 8157df9df..8c1ac15f0 100644 --- a/src/st-util/semihosting.h +++ b/src/st-util/semihosting.h @@ -29,6 +29,6 @@ #define SEMIHOST_SYS_ELAPSED 0x30 #define SEMIHOST_SYS_TICKFREQ 0x31 -int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret); +int do_semihosting(stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret); -#endif /* ! _SEMIHOSTING_H_ */ +#endif // _SEMIHOSTING_H_ diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index 7ae591f2d..ed38fcc7c 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -13,23 +13,23 @@ #define G_VALUE_INIT {0, {{0}}} #endif -G_DEFINE_TYPE (STlinkGUI, stlink_gui, G_TYPE_OBJECT); +G_DEFINE_TYPE(STlinkGUI, stlink_gui, G_TYPE_OBJECT); -static void stlink_gui_dispose (GObject *gobject) { - G_OBJECT_CLASS (stlink_gui_parent_class)->dispose (gobject); +static void stlink_gui_dispose(GObject *gobject) { + G_OBJECT_CLASS(stlink_gui_parent_class)->dispose(gobject); } -static void stlink_gui_finalize (GObject *gobject) { - G_OBJECT_CLASS (stlink_gui_parent_class)->finalize (gobject); +static void stlink_gui_finalize(GObject *gobject) { + G_OBJECT_CLASS(stlink_gui_parent_class)->finalize(gobject); } -static void stlink_gui_class_init (STlinkGUIClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); +static void stlink_gui_class_init(STlinkGUIClass *klass) { + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); gobject_class->dispose = stlink_gui_dispose; gobject_class->finalize = stlink_gui_finalize; } -static void stlink_gui_init (STlinkGUI *self) { +static void stlink_gui_init(STlinkGUI *self) { self->sl = NULL; self->filename = NULL; @@ -45,162 +45,159 @@ static void stlink_gui_init (STlinkGUI *self) { self->file_mem.base = 0; } -static gboolean set_info_error_message_idle (STlinkGUI *gui) { +static gboolean set_info_error_message_idle(STlinkGUI *gui) { if (gui->error_message != NULL) { gchar *markup; - markup = g_markup_printf_escaped ("%s", gui->error_message); - gtk_label_set_markup (gui->infolabel, markup); - gtk_info_bar_set_message_type (gui->infobar, GTK_MESSAGE_ERROR); - gtk_widget_show (GTK_WIDGET (gui->infobar)); + markup = g_markup_printf_escaped("%s", gui->error_message); + gtk_label_set_markup(gui->infolabel, markup); + gtk_info_bar_set_message_type(gui->infobar, GTK_MESSAGE_ERROR); + gtk_widget_show(GTK_WIDGET(gui->infobar)); - g_free (markup); - g_free (gui->error_message); + g_free(markup); + g_free(gui->error_message); gui->error_message = NULL; } - return FALSE; + + return(FALSE); } -static void stlink_gui_set_info_error_message (STlinkGUI *gui, const gchar *message) { - gui->error_message = g_strdup (message); - g_idle_add ((GSourceFunc) set_info_error_message_idle, gui); +static void stlink_gui_set_info_error_message(STlinkGUI *gui, const gchar *message) { + gui->error_message = g_strdup(message); + g_idle_add((GSourceFunc)set_info_error_message_idle, gui); } -static void stlink_gui_set_sensitivity (STlinkGUI *gui, gboolean sensitivity) { - gtk_widget_set_sensitive (GTK_WIDGET (gui->open_button), sensitivity); - if (sensitivity && gui->sl) - gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), sensitivity); - if (sensitivity && !gui->sl) - gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), sensitivity); - if (sensitivity && gui->sl && gui->filename) - gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), sensitivity); - gtk_widget_set_sensitive (GTK_WIDGET (gui->export_button), sensitivity && (gui->sl != NULL)); +static void stlink_gui_set_sensitivity(STlinkGUI *gui, gboolean sensitivity) { + gtk_widget_set_sensitive(GTK_WIDGET(gui->open_button), sensitivity); + + if (sensitivity && gui->sl) { + gtk_widget_set_sensitive(GTK_WIDGET(gui->disconnect_button), sensitivity); + } + + if (sensitivity && !gui->sl) { + gtk_widget_set_sensitive(GTK_WIDGET(gui->connect_button), sensitivity); + } + + if (sensitivity && gui->sl && gui->filename) { + gtk_widget_set_sensitive(GTK_WIDGET(gui->flash_button), sensitivity); + } + + gtk_widget_set_sensitive(GTK_WIDGET(gui->export_button), sensitivity && (gui->sl != NULL)); } -static void mem_view_init_headers (GtkTreeView *view) { +static void mem_view_init_headers(GtkTreeView *view) { GtkCellRenderer *renderer; - gint i; - - g_return_if_fail (view != NULL); - - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_insert_column_with_attributes ( - view, - -1, - "Address", - renderer, - "text", - 0, /* column */ - NULL); + gint i; + + g_return_if_fail(view != NULL); + + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, "Address", renderer, "text", 0, /* column */ NULL); + for (i = 0; i < 4; i++) { gchar *label; - label = g_strdup_printf ("%X", i * 4); - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_insert_column_with_attributes (view, - -1, - label, - renderer, - "text", - (i + 1), /* column */ - NULL); - g_free (label); + label = g_strdup_printf("%X", i * 4); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, label, renderer, "text", (i + 1), /* column */ NULL); + g_free(label); } for (i = 0; i < 5; i++) { - GtkTreeViewColumn *column = gtk_tree_view_get_column (view, i); - gtk_tree_view_column_set_expand (column, TRUE); + GtkTreeViewColumn *column = gtk_tree_view_get_column(view, i); + gtk_tree_view_column_set_expand(column, TRUE); } } -static void mem_view_add_as_hex ( - GtkListStore *store, - GtkTreeIter *iter, - gint column, - guint32 value) { +static void mem_view_add_as_hex(GtkListStore *store, + GtkTreeIter *iter, + gint column, + guint32 value) { gchar *hex_str; - hex_str = g_strdup_printf ("0x%08X", value); + hex_str = g_strdup_printf("0x%08X", value); gtk_list_store_set(store, iter, column, hex_str, -1); - g_free (hex_str); + g_free(hex_str); } -static void mem_view_add_buffer ( - GtkListStore *store, - GtkTreeIter *iter, - guint32 address, - guchar *buffer, - gint len) { +static void mem_view_add_buffer(GtkListStore *store, + GtkTreeIter *iter, + guint32 address, + guchar *buffer, + gint len) { guint32 *word; - gint i, step; - gint column = 0; + gint i, step; + gint column = 0; - step = sizeof (*word); + step = sizeof(*word); for (i = 0; i < len; i += step) { - word = (guint *) &buffer[i]; + word = (guint *)&buffer[i]; if (column == 0) { - /* new row */ - gtk_list_store_append (store, iter); - - /* add address */ - mem_view_add_as_hex (store, iter, column, (address + i)); + gtk_list_store_append(store, iter); // new row + mem_view_add_as_hex(store, iter, column, (address + i)); // add address } - mem_view_add_as_hex (store, iter, (column + 1), *word); + + mem_view_add_as_hex(store, iter, (column + 1), *word); column = (column + 1) % step; } } -static guint32 hexstr_to_guint32 (const gchar *str, GError **err) { - guint32 val; - gchar *end_ptr; +static guint32 hexstr_to_guint32(const gchar *str, GError **err) { + guint32 val; + gchar *end_ptr; + + val = (guint32)strtoul(str, &end_ptr, 16); - val = (guint32) strtoul (str, &end_ptr, 16); if ((errno == ERANGE && val == UINT_MAX) || (errno != 0 && val == 0)) { - g_set_error (err, g_quark_from_string ("hextou32"), 1, "Invalid hexstring"); - return UINT32_MAX; + g_set_error(err, g_quark_from_string("hextou32"), 1, "Invalid hexstring"); + return(UINT32_MAX); } + if (end_ptr == str) { - g_set_error (err, g_quark_from_string ("hextou32"), 2, "Invalid hexstring"); - return UINT32_MAX; + g_set_error(err, g_quark_from_string("hextou32"), 2, "Invalid hexstring"); + return(UINT32_MAX); } - return val; + + return(val); } -static void stlink_gui_update_mem_view (STlinkGUI *gui, struct mem_t *mem, GtkTreeView *view) { +static void stlink_gui_update_mem_view(STlinkGUI *gui, struct mem_t *mem, GtkTreeView *view) { GtkListStore *store; - GtkTreeIter iter; + GtkTreeIter iter; - store = GTK_LIST_STORE (gtk_tree_view_get_model (view)); + store = GTK_LIST_STORE(gtk_tree_view_get_model(view)); - mem_view_add_buffer (store, &iter, mem->base, mem->memory, (gint) mem->size); + mem_view_add_buffer(store, &iter, mem->base, mem->memory, (gint)mem->size); - gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); - gtk_progress_bar_set_fraction (gui->progress.bar, 0); - stlink_gui_set_sensitivity (gui, TRUE); + gtk_widget_hide(GTK_WIDGET(gui->progress.bar)); + gtk_progress_bar_set_fraction(gui->progress.bar, 0); + stlink_gui_set_sensitivity(gui, TRUE); } -static gboolean stlink_gui_update_devmem_view (STlinkGUI *gui) { - stlink_gui_update_mem_view (gui, &gui->flash_mem, gui->devmem_treeview); - return FALSE; +static gboolean stlink_gui_update_devmem_view(STlinkGUI *gui) { + stlink_gui_update_mem_view(gui, &gui->flash_mem, gui->devmem_treeview); + return(FALSE); } -static gpointer stlink_gui_populate_devmem_view (gpointer data) { - guint off; - stm32_addr_t addr; +static gpointer stlink_gui_populate_devmem_view(gpointer data) { + guint off; + stm32_addr_t addr; - g_return_val_if_fail (STLINK_IS_GUI (data), NULL); + g_return_val_if_fail(STLINK_IS_GUI(data), NULL); STlinkGUI *gui = (STlinkGUI *)data; - g_return_val_if_fail ((gui != NULL), NULL); - g_return_val_if_fail ((gui->sl != NULL), NULL); + g_return_val_if_fail((gui != NULL), NULL); + g_return_val_if_fail((gui->sl != NULL), NULL); addr = gui->sl->flash_base; - if (gui->flash_mem.memory) - g_free (gui->flash_mem.memory); - gui->flash_mem.memory = g_malloc (gui->sl->flash_size); + if (gui->flash_mem.memory) { + g_free(gui->flash_mem.memory); + } + + gui->flash_mem.memory = g_malloc(gui->sl->flash_size); gui->flash_mem.size = gui->sl->flash_size; gui->flash_mem.base = gui->sl->flash_base; @@ -208,304 +205,319 @@ static gpointer stlink_gui_populate_devmem_view (gpointer data) { guint n_read = MEM_READ_SIZE; if (off + MEM_READ_SIZE > gui->sl->flash_size) { - n_read = (guint) gui->sl->flash_size - off; + n_read = (guint)gui->sl->flash_size - off; - /* align if needed */ - if (n_read & 3) - n_read = (n_read + 4) & ~(3); + if (n_read & 3) { n_read = (n_read + 4) & ~(3); } // align if needed } - /* reads to sl->q_buf */ - stlink_read_mem32(gui->sl, addr + off, n_read); + + stlink_read_mem32(gui->sl, addr + off, n_read); // reads to sl->q_buf + if (gui->sl->q_len < 0) { - stlink_gui_set_info_error_message (gui, "Failed to read memory"); - g_free (gui->flash_mem.memory); + stlink_gui_set_info_error_message(gui, "Failed to read memory"); + g_free(gui->flash_mem.memory); gui->flash_mem.memory = NULL; - return NULL; + return(NULL); } - memcpy (gui->flash_mem.memory + off, gui->sl->q_buf, n_read); - gui->progress.fraction = (gdouble) (off + n_read) / gui->sl->flash_size; + + memcpy(gui->flash_mem.memory + off, gui->sl->q_buf, n_read); + gui->progress.fraction = (gdouble)(off + n_read) / gui->sl->flash_size; } - g_idle_add ((GSourceFunc) stlink_gui_update_devmem_view, gui); - return NULL; + + g_idle_add((GSourceFunc)stlink_gui_update_devmem_view, gui); + return(NULL); } -static gboolean stlink_gui_update_filemem_view (STlinkGUI *gui) { +static gboolean stlink_gui_update_filemem_view(STlinkGUI *gui) { gchar *basename; - basename = g_path_get_basename (gui->filename); - gtk_notebook_set_tab_label_text (gui->notebook, - GTK_WIDGET (gtk_notebook_get_nth_page (gui->notebook, 1)), basename); - g_free (basename); + basename = g_path_get_basename(gui->filename); + gtk_notebook_set_tab_label_text( + gui->notebook, GTK_WIDGET(gtk_notebook_get_nth_page(gui->notebook, 1)), basename); + g_free(basename); - stlink_gui_update_mem_view (gui, &gui->file_mem, gui->filemem_treeview); - return FALSE; + stlink_gui_update_mem_view(gui, &gui->file_mem, gui->filemem_treeview); + return(FALSE); } -static gpointer stlink_gui_populate_filemem_view (gpointer data) { - guchar buffer[MEM_READ_SIZE]; - GFile *file; - GFileInfo *file_info; +static gpointer stlink_gui_populate_filemem_view(gpointer data) { + guchar buffer[MEM_READ_SIZE]; + GFile *file; + GFileInfo *file_info; GInputStream *input_stream; - gint off; - GError *err = NULL; + gint off; + GError *err = NULL; - g_return_val_if_fail (STLINK_IS_GUI (data), NULL); + g_return_val_if_fail(STLINK_IS_GUI(data), NULL); STlinkGUI *gui = (STlinkGUI *)data; - g_return_val_if_fail (gui != NULL, NULL); - g_return_val_if_fail (gui->filename != NULL, NULL); + g_return_val_if_fail(gui != NULL, NULL); + g_return_val_if_fail(gui->filename != NULL, NULL); - if (g_str_has_suffix (gui->filename, ".hex")) { - // If the file has prefix .hex - try to interpret it as Intel-HEX. - // It's difficult to merge the world of standard functions and GLib, - // so do it simple - load whole file into buffer and copy the data to the - // destination afterwards. - // We loose meanwhile the displaying of the progress and need double memory. + if (g_str_has_suffix(gui->filename, ".hex")) { + /* If the file has prefix .hex - try to interpret it as Intel-HEX. + * It's difficult to merge the world of standard functions and GLib, so do it simple: + * Load whole file into buffer and copy the data to the destination afterwards. + * In the meanwhile we loose the displaying of the progress and need double memory. + */ uint8_t* mem = NULL; - size_t size = 0; + size_t size = 0; uint32_t begin = 0; - int res = stlink_parse_ihex (gui->filename, 0, &mem, &size, &begin); + int res = stlink_parse_ihex(gui->filename, 0, &mem, &size, &begin); if (res == 0) { - if (gui->file_mem.memory) - g_free (gui->file_mem.memory); + if (gui->file_mem.memory) { + g_free(gui->file_mem.memory); + } + gui->file_mem.size = size; - gui->file_mem.memory = g_malloc (size); + gui->file_mem.memory = g_malloc(size); gui->file_mem.base = begin; - memcpy (gui->file_mem.memory, mem, size); + memcpy(gui->file_mem.memory, mem, size); } else { - stlink_gui_set_info_error_message (gui, "Cannot interpret the file as Intel-HEX"); + stlink_gui_set_info_error_message(gui, "Cannot interpret the file as Intel-HEX"); } free(mem); } else { - file = g_file_new_for_path (gui->filename); - input_stream = G_INPUT_STREAM (g_file_read (file, NULL, &err)); + file = g_file_new_for_path(gui->filename); + input_stream = G_INPUT_STREAM(g_file_read(file, NULL, &err)); + if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); + stlink_gui_set_info_error_message(gui, err->message); + g_error_free(err); goto out; } - file_info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (input_stream), - G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, &err); + file_info = g_file_input_stream_query_info( + G_FILE_INPUT_STREAM(input_stream), G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, &err); + if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); + stlink_gui_set_info_error_message(gui, err->message); + g_error_free(err); goto out_input; } - if (gui->file_mem.memory) - g_free (gui->file_mem.memory); - gui->file_mem.size = g_file_info_get_size (file_info); - gui->file_mem.memory = g_malloc (gui->file_mem.size); - for (off = 0; off < (gint) gui->file_mem.size; off += MEM_READ_SIZE) { + if (gui->file_mem.memory) { g_free(gui->file_mem.memory); } + + gui->file_mem.size = g_file_info_get_size(file_info); + gui->file_mem.memory = g_malloc(gui->file_mem.size); + + for (off = 0; off < (gint)gui->file_mem.size; off += MEM_READ_SIZE) { guint n_read = MEM_READ_SIZE; - if (off + MEM_READ_SIZE > (gint) gui->file_mem.size) - n_read = (guint) gui->file_mem.size - off; + if (off + MEM_READ_SIZE > (gint)gui->file_mem.size) { + n_read = (guint)gui->file_mem.size - off; + } - if (g_input_stream_read (G_INPUT_STREAM (input_stream), - &buffer, n_read, NULL, &err) == -1) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); + if (g_input_stream_read( + G_INPUT_STREAM(input_stream), &buffer, n_read, NULL, &err) == -1) { + stlink_gui_set_info_error_message(gui, err->message); + g_error_free(err); goto out_input; } - memcpy (gui->file_mem.memory + off, buffer, n_read); - gui->progress.fraction = (gdouble) (off + n_read) / gui->file_mem.size; + + memcpy(gui->file_mem.memory + off, buffer, n_read); + gui->progress.fraction = (gdouble)(off + n_read) / gui->file_mem.size; } - out_input: g_object_unref (input_stream); - out: g_object_unref (file); +out_input: g_object_unref(input_stream); +out: g_object_unref(file); } - g_idle_add ((GSourceFunc) stlink_gui_update_filemem_view, gui); - return NULL; + g_idle_add((GSourceFunc)stlink_gui_update_filemem_view, gui); + return(NULL); } -static void mem_jmp (GtkTreeView *view, - GtkEntry *entry, - guint32 base_addr, - gsize size, - GError **err) { +static void mem_jmp(GtkTreeView *view, + GtkEntry *entry, + guint32 base_addr, + gsize size, + GError **err) { GtkTreeModel *model; - guint32 jmp_addr; - GtkTreeIter iter; + guint32 jmp_addr; + GtkTreeIter iter; - jmp_addr = hexstr_to_guint32 (gtk_entry_get_text (entry), err); - if (err && *err) - return; + jmp_addr = hexstr_to_guint32(gtk_entry_get_text(entry), err); + + if (err && *err) { return; } if (jmp_addr < base_addr || jmp_addr > base_addr + size) { - g_set_error (err, g_quark_from_string ("mem_jmp"), 1, "Invalid address"); + g_set_error(err, g_quark_from_string("mem_jmp"), 1, "Invalid address"); return; } - model = gtk_tree_view_get_model (view); - if (!model) - return; + model = gtk_tree_view_get_model(view); + + if (!model) { return; } - if (gtk_tree_model_get_iter_first (model, &iter)) { + if (gtk_tree_model_get_iter_first(model, &iter)) { do { guint32 addr; - GValue value = G_VALUE_INIT; + GValue value = G_VALUE_INIT; + + gtk_tree_model_get_value(model, &iter, 0, &value); + + if (G_VALUE_HOLDS_STRING(&value)) { + addr = hexstr_to_guint32(g_value_get_string(&value), err); - gtk_tree_model_get_value (model, &iter, 0, &value); - if (G_VALUE_HOLDS_STRING (&value)) { - addr = hexstr_to_guint32 (g_value_get_string (&value), err); if (!*err) { if (addr == (jmp_addr & 0xFFFFFFF0)) { GtkTreeSelection *selection; - GtkTreePath *path; + GtkTreePath *path; - selection = gtk_tree_view_get_selection (view); - path = gtk_tree_model_get_path (model, &iter); + selection = gtk_tree_view_get_selection(view); + path = gtk_tree_model_get_path(model, &iter); - gtk_tree_selection_select_iter (selection, &iter); - gtk_tree_view_scroll_to_cell (view, path, NULL, TRUE, 0.0, 0.0); - gtk_tree_path_free (path); + gtk_tree_selection_select_iter(selection, &iter); + gtk_tree_view_scroll_to_cell(view, path, NULL, TRUE, 0.0, 0.0); + gtk_tree_path_free(path); } } } + g_value_unset(&value); - } while (gtk_tree_model_iter_next (model, &iter)); + } while (gtk_tree_model_iter_next(model, &iter)); } } -static void devmem_jmp_cb (GtkWidget *widget, gpointer data) { +static void devmem_jmp_cb(GtkWidget *widget, gpointer data) { STlinkGUI *gui; - GError *err = NULL; - (void) widget; + GError *err = NULL; + (void)widget; - gui = STLINK_GUI (data); + gui = STLINK_GUI(data); - mem_jmp (gui->devmem_treeview, + mem_jmp(gui->devmem_treeview, gui->devmem_jmp_entry, gui->sl->flash_base, gui->sl->flash_size, &err); if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); + stlink_gui_set_info_error_message(gui, err->message); + g_error_free(err); } } -static void filemem_jmp_cb (GtkWidget *widget, gpointer data) { +static void filemem_jmp_cb(GtkWidget *widget, gpointer data) { STlinkGUI *gui; - GError *err = NULL; - (void) widget; + GError *err = NULL; + (void)widget; - gui = STLINK_GUI (data); + gui = STLINK_GUI(data); - g_return_if_fail (gui->filename != NULL); + g_return_if_fail(gui->filename != NULL); - mem_jmp (gui->filemem_treeview, + mem_jmp(gui->filemem_treeview, gui->filemem_jmp_entry, 0, gui->file_mem.size, &err); if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); + stlink_gui_set_info_error_message(gui, err->message); + g_error_free(err); } } -static gchar *dev_format_chip_id (guint32 chip_id) { +static gchar *dev_format_chip_id(guint32 chip_id) { const struct stlink_chipid_params *params; params = stlink_chipid_get_params(chip_id); - if (!params) - return g_strdup_printf ("0x%x", chip_id); - return g_strdup (params->description); + if (!params) { return(g_strdup_printf("0x%x", chip_id)); } + + return(g_strdup(params->description)); } -static gchar *dev_format_mem_size (gsize flash_size) { - return g_strdup_printf ("%u kB", (unsigned int)(flash_size / 1024)); +static gchar *dev_format_mem_size(gsize flash_size) { + return(g_strdup_printf("%u kB", (unsigned int)(flash_size / 1024))); } -static void stlink_gui_set_connected (STlinkGUI *gui) { - gchar *tmp_str; +static void stlink_gui_set_connected(STlinkGUI *gui) { + gchar *tmp_str; GtkListStore *store; - GtkTreeIter iter; + GtkTreeIter iter; + + gtk_statusbar_push(gui->statusbar, gtk_statusbar_get_context_id(gui->statusbar, "conn"), "Connected"); - gtk_statusbar_push (gui->statusbar, - gtk_statusbar_get_context_id (gui->statusbar, "conn"), "Connected"); + gtk_widget_set_sensitive(GTK_WIDGET(gui->device_frame), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gui->devmem_box), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gui->connect_button), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), TRUE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->devmem_box), TRUE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), FALSE); + if (gui->filename) { + gtk_widget_set_sensitive(GTK_WIDGET(gui->flash_button), TRUE); + } - if (gui->filename) - gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), TRUE); + tmp_str = dev_format_chip_id(gui->sl->chip_id); + gtk_label_set_text(gui->chip_id_label, tmp_str); + g_free(tmp_str); - tmp_str = dev_format_chip_id (gui->sl->chip_id); - gtk_label_set_text (gui->chip_id_label, tmp_str); - g_free (tmp_str); + tmp_str = g_strdup_printf("0x%x", gui->sl->core_id); + gtk_label_set_text(gui->core_id_label, tmp_str); + g_free(tmp_str); - tmp_str = g_strdup_printf ("0x%x", gui->sl->core_id); - gtk_label_set_text (gui->core_id_label, tmp_str); - g_free (tmp_str); + tmp_str = dev_format_mem_size(gui->sl->flash_size); + gtk_label_set_text(gui->flash_size_label, tmp_str); + g_free(tmp_str); - tmp_str = dev_format_mem_size (gui->sl->flash_size); - gtk_label_set_text (gui->flash_size_label, tmp_str); - g_free (tmp_str); + tmp_str = dev_format_mem_size(gui->sl->sram_size); + gtk_label_set_text(gui->ram_size_label, tmp_str); + g_free(tmp_str); - tmp_str = dev_format_mem_size (gui->sl->sram_size); - gtk_label_set_text (gui->ram_size_label, tmp_str); - g_free (tmp_str); + tmp_str = g_strdup_printf("0x%08X", gui->sl->flash_base); + gtk_entry_set_text(gui->devmem_jmp_entry, tmp_str); + gtk_editable_set_editable(GTK_EDITABLE(gui->devmem_jmp_entry), TRUE); + g_free(tmp_str); - tmp_str = g_strdup_printf ("0x%08X", gui->sl->flash_base); - gtk_entry_set_text (gui->devmem_jmp_entry, tmp_str); - gtk_editable_set_editable (GTK_EDITABLE (gui->devmem_jmp_entry), TRUE); - g_free (tmp_str); + store = GTK_LIST_STORE(gtk_tree_view_get_model(gui->devmem_treeview)); - store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) - gtk_list_store_clear (store); + if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) { + gtk_list_store_clear(store); + } - stlink_gui_set_sensitivity (gui, FALSE); - gtk_notebook_set_current_page (gui->notebook, PAGE_DEVMEM); - gtk_widget_show (GTK_WIDGET (gui->progress.bar)); - gtk_progress_bar_set_text (gui->progress.bar, "Reading memory"); + stlink_gui_set_sensitivity(gui, FALSE); + gtk_notebook_set_current_page(gui->notebook, PAGE_DEVMEM); + gtk_widget_show(GTK_WIDGET(gui->progress.bar)); + gtk_progress_bar_set_text(gui->progress.bar, "Reading memory"); - g_thread_new ("devmem", (GThreadFunc) stlink_gui_populate_devmem_view, gui); + g_thread_new("devmem", (GThreadFunc)stlink_gui_populate_devmem_view, gui); } -static void connect_button_cb (GtkWidget *widget, gpointer data) { +static void connect_button_cb(GtkWidget *widget, gpointer data) { STlinkGUI *gui; - gint i; - (void) widget; + gint i; + (void)widget; - gui = STLINK_GUI (data); + gui = STLINK_GUI(data); - if (gui->sl != NULL) - return; + if (gui->sl != NULL) { return; } + + gui->sl = stlink_v1_open(0, 1); // try version 1 then version 2 + + if (gui->sl == NULL) { gui->sl = stlink_open_usb(0, 1, NULL, 0); } - /* try version 1 then version 2 */ - gui->sl = stlink_v1_open(0, 1); - if (gui->sl == NULL) - gui->sl = stlink_open_usb(0, 1, NULL, 0); if (gui->sl == NULL) { - stlink_gui_set_info_error_message (gui, "Failed to connect to STLink."); + stlink_gui_set_info_error_message(gui, "Failed to connect to STLink."); return; } - /* code below taken from flash/main.c, refactoring might be in order */ - if (stlink_current_mode(gui->sl) == STLINK_DEV_DFU_MODE) + // code below taken from flash/main.c, refactoring might be in order + if (stlink_current_mode(gui->sl) == STLINK_DEV_DFU_MODE) { stlink_exit_dfu_mode(gui->sl); + } - if (stlink_current_mode(gui->sl) != STLINK_DEV_DEBUG_MODE) + if (stlink_current_mode(gui->sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(gui->sl); + } - /* Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 */ + // disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 if (gui->sl->chip_id == STLINK_CHIPID_STM32_F4) { memset(gui->sl->q_buf, 0, 4); + for (i = 0; i < 8; i++) { stlink_write_mem32(gui->sl, 0x40026000 + 0x10 + 0x18 * i, 4); stlink_write_mem32(gui->sl, 0x40026400 + 0x10 + 0x18 * i, 4); @@ -513,128 +525,133 @@ static void connect_button_cb (GtkWidget *widget, gpointer data) { stlink_write_mem32(gui->sl, 0x40026400 + 0x24 + 0x18 * i, 4); } } - stlink_gui_set_connected (gui); + + stlink_gui_set_connected(gui); } -static void stlink_gui_set_disconnected (STlinkGUI *gui) { - gtk_statusbar_push (gui->statusbar, - gtk_statusbar_get_context_id (gui->statusbar, "conn"), - "Disconnected"); +static void stlink_gui_set_disconnected(STlinkGUI *gui) { + gtk_statusbar_push(gui->statusbar, gtk_statusbar_get_context_id(gui->statusbar, "conn"), "Disconnected"); - gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->export_button), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gui->device_frame), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(gui->flash_button), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(gui->export_button), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(gui->disconnect_button), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(gui->connect_button), TRUE); } -static void disconnect_button_cb (GtkWidget *widget, gpointer data) { +static void disconnect_button_cb(GtkWidget *widget, gpointer data) { STlinkGUI *gui; - (void) widget; + (void)widget; - gui = STLINK_GUI (data); + gui = STLINK_GUI(data); if (gui->sl != NULL) { stlink_exit_debug_mode(gui->sl); stlink_close(gui->sl); gui->sl = NULL; } - stlink_gui_set_disconnected (gui); + + stlink_gui_set_disconnected(gui); } -static void stlink_gui_open_file (STlinkGUI *gui) { - GtkWidget *dialog; +static void stlink_gui_open_file(STlinkGUI *gui) { + GtkWidget *dialog; GtkListStore *store; - GtkTreeIter iter; + GtkTreeIter iter; - dialog = gtk_file_chooser_dialog_new ("Open file", - gui->window, - GTK_FILE_CHOOSER_ACTION_OPEN, - "_Cancel", GTK_RESPONSE_CANCEL, - "_Open", GTK_RESPONSE_ACCEPT, - NULL); + dialog = gtk_file_chooser_dialog_new("Open file", + gui->window, + GTK_FILE_CHOOSER_ACTION_OPEN, + "_Cancel", GTK_RESPONSE_CANCEL, + "_Open", GTK_RESPONSE_ACCEPT, + NULL); - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { - gui->filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { + gui->filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->filemem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) - gtk_list_store_clear (store); + store = GTK_LIST_STORE(gtk_tree_view_get_model(gui->filemem_treeview)); - stlink_gui_set_sensitivity (gui, FALSE); - gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); - gtk_widget_show (GTK_WIDGET (gui->progress.bar)); - gtk_progress_bar_set_text (gui->progress.bar, "Reading file"); - g_thread_new ("file", (GThreadFunc) stlink_gui_populate_filemem_view, gui); + if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) { + gtk_list_store_clear(store); + } + + stlink_gui_set_sensitivity(gui, FALSE); + gtk_notebook_set_current_page(gui->notebook, PAGE_FILEMEM); + gtk_widget_show(GTK_WIDGET(gui->progress.bar)); + gtk_progress_bar_set_text(gui->progress.bar, "Reading file"); + g_thread_new("file", (GThreadFunc)stlink_gui_populate_filemem_view, gui); } - gtk_widget_destroy (dialog); + + gtk_widget_destroy(dialog); } -static void open_button_cb (GtkWidget *widget, gpointer data) { - STlinkGUI *gui; - (void) widget; +static void open_button_cb(GtkWidget *widget, gpointer data) { + STlinkGUI *gui; + (void)widget; - gui = STLINK_GUI (data); - stlink_gui_open_file (gui); + gui = STLINK_GUI(data); + stlink_gui_open_file(gui); } -static gboolean stlink_gui_write_flash_update (STlinkGUI *gui) { - stlink_gui_set_sensitivity (gui, TRUE); +static gboolean stlink_gui_write_flash_update(STlinkGUI *gui) { + stlink_gui_set_sensitivity(gui, TRUE); gui->progress.activity_mode = FALSE; - gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); - return FALSE; + gtk_widget_hide(GTK_WIDGET(gui->progress.bar)); + return(FALSE); } -static gpointer stlink_gui_write_flash (gpointer data) { - g_return_val_if_fail (STLINK_IS_GUI (data), NULL); +static gpointer stlink_gui_write_flash(gpointer data) { + g_return_val_if_fail(STLINK_IS_GUI(data), NULL); STlinkGUI *gui = (STlinkGUI *)data; - g_return_val_if_fail ((gui->sl != NULL), NULL); - g_return_val_if_fail ((gui->filename != NULL), NULL); + g_return_val_if_fail((gui->sl != NULL), NULL); + g_return_val_if_fail((gui->filename != NULL), NULL); - if (stlink_mwrite_flash(gui->sl, gui->file_mem.memory, - (uint32_t)gui->file_mem.size, gui->sl->flash_base) < 0) { - stlink_gui_set_info_error_message (gui, "Failed to write to flash"); + if (stlink_mwrite_flash( + gui->sl, gui->file_mem.memory, (uint32_t)gui->file_mem.size, gui->sl->flash_base) < 0) { + stlink_gui_set_info_error_message(gui, "Failed to write to flash"); } - g_idle_add ((GSourceFunc) stlink_gui_write_flash_update, gui); - return NULL; + g_idle_add((GSourceFunc)stlink_gui_write_flash_update, gui); + return(NULL); } -static void flash_button_cb (GtkWidget *widget, gpointer data) { +static void flash_button_cb(GtkWidget *widget, gpointer data) { STlinkGUI *gui; - gchar *tmp_str; - guint32 address; - gint result; - GError *err = NULL; - (void) widget; + gchar *tmp_str; + guint32 address; + gint result; + GError *err = NULL; + (void)widget; - gui = STLINK_GUI (data); - g_return_if_fail (gui->sl != NULL); + gui = STLINK_GUI(data); + g_return_if_fail(gui->sl != NULL); - if (!g_strcmp0 (gtk_entry_get_text (gui->flash_dialog_entry), "")) { - tmp_str = g_strdup_printf ("0x%08X", gui->sl->flash_base); - gtk_entry_set_text (gui->flash_dialog_entry, tmp_str); - g_free (tmp_str); + if (!g_strcmp0(gtk_entry_get_text(gui->flash_dialog_entry), "")) { + tmp_str = g_strdup_printf("0x%08X", gui->sl->flash_base); + gtk_entry_set_text(gui->flash_dialog_entry, tmp_str); + g_free(tmp_str); } - result = gtk_dialog_run (gui->flash_dialog); + result = gtk_dialog_run(gui->flash_dialog); + if (result == GTK_RESPONSE_OK) { - address = hexstr_to_guint32 (gtk_entry_get_text (gui->flash_dialog_entry), &err); + address = hexstr_to_guint32(gtk_entry_get_text(gui->flash_dialog_entry), &err); + if (err) { - stlink_gui_set_info_error_message (gui, err->message); + stlink_gui_set_info_error_message(gui, err->message); } else { if (address > gui->sl->flash_base + gui->sl->flash_size || address < gui->sl->flash_base) { - stlink_gui_set_info_error_message (gui, "Invalid address"); + stlink_gui_set_info_error_message(gui, "Invalid address"); } else if (address + gui->file_mem.size > gui->sl->flash_base + gui->sl->flash_size) { - stlink_gui_set_info_error_message (gui, "Binary overwrites flash"); + stlink_gui_set_info_error_message(gui, "Binary overwrites flash"); } else { - stlink_gui_set_sensitivity (gui, FALSE); - gtk_progress_bar_set_text (gui->progress.bar, "Writing to flash"); + stlink_gui_set_sensitivity(gui, FALSE); + gtk_progress_bar_set_text(gui->progress.bar, "Writing to flash"); gui->progress.activity_mode = TRUE; - gtk_widget_show (GTK_WIDGET (gui->progress.bar)); - g_thread_new ("flash", (GThreadFunc) stlink_gui_write_flash, gui); + gtk_widget_show(GTK_WIDGET(gui->progress.bar)); + g_thread_new("flash", (GThreadFunc)stlink_gui_write_flash, gui); } } } @@ -642,248 +659,258 @@ static void flash_button_cb (GtkWidget *widget, gpointer data) { int export_to_file(const char*filename, const struct mem_t flash_mem) { printf("%s\n", filename); - FILE * f=fopen(filename, "w"); - if (f == NULL) - return -1; - for (gsize i=0;iwindow, - GTK_FILE_CHOOSER_ACTION_SAVE, - "_Cancel", - GTK_RESPONSE_CANCEL, - "_Open", - GTK_RESPONSE_ACCEPT, - NULL); - GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog); - gtk_file_chooser_set_do_overwrite_confirmation (chooser, TRUE); - gint res = gtk_dialog_run (GTK_DIALOG (dialog)); + dialog = gtk_file_chooser_dialog_new("Save as", + gui->window, + GTK_FILE_CHOOSER_ACTION_SAVE, + "_Cancel", + GTK_RESPONSE_CANCEL, + "_Open", + GTK_RESPONSE_ACCEPT, + NULL); + GtkFileChooser *chooser = GTK_FILE_CHOOSER(dialog); + gtk_file_chooser_set_do_overwrite_confirmation(chooser, TRUE); + gint res = gtk_dialog_run(GTK_DIALOG(dialog)); + if (res == GTK_RESPONSE_ACCEPT) { char *filename; - filename = gtk_file_chooser_get_filename (chooser); - if (export_to_file (filename, gui->flash_mem) != 0) { + filename = gtk_file_chooser_get_filename(chooser); + + if (export_to_file(filename, gui->flash_mem) != 0) { stlink_gui_set_info_error_message(gui, "Failed to export flash"); } else { stlink_gui_set_info_error_message(gui, "Export successful"); } - g_free (filename); + + g_free(filename); } - gtk_widget_destroy (dialog); + gtk_widget_destroy(dialog); } -static gboolean progress_pulse_timeout (STlinkGUI *gui) { +static gboolean progress_pulse_timeout(STlinkGUI *gui) { if (gui->progress.activity_mode) { - gtk_progress_bar_pulse (gui->progress.bar); + gtk_progress_bar_pulse(gui->progress.bar); } else { - gtk_progress_bar_set_fraction (gui->progress.bar, gui->progress.fraction); + gtk_progress_bar_set_fraction(gui->progress.bar, gui->progress.fraction); } - return TRUE; + + return(TRUE); } -static void notebook_switch_page_cb ( - GtkNotebook *notebook, - GtkWidget *widget, - guint page_num, - gpointer data) { +static void notebook_switch_page_cb(GtkNotebook *notebook, + GtkWidget *widget, + guint page_num, + gpointer data) { STlinkGUI *gui; - (void) notebook; - (void) widget; + (void)notebook; + (void)widget; - gui = STLINK_GUI (data); + gui = STLINK_GUI(data); if (page_num == 1) { - if (gui->filename == NULL) - stlink_gui_open_file (gui); - } -} - -static void dnd_received_cb ( - GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint target_type, - guint timestamp, - gpointer data) { - GFile *file_uri; - gchar **file_list; + if (gui->filename == NULL) { stlink_gui_open_file(gui); } + } +} + +static void dnd_received_cb(GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint target_type, + guint timestamp, + gpointer data) { + GFile *file_uri; + gchar **file_list; const guchar *file_data; - STlinkGUI *gui = STLINK_GUI (data); + STlinkGUI *gui = STLINK_GUI(data); GtkListStore *store; - GtkTreeIter iter; - (void) widget; - (void) x; - (void) y; + GtkTreeIter iter; + (void)widget; + (void)x; + (void)y; - if (selection_data != NULL && gtk_selection_data_get_length (selection_data) > 0) { + if (selection_data != NULL && gtk_selection_data_get_length(selection_data) > 0) { switch (target_type) { case TARGET_FILENAME: - if (gui->filename) - g_free (gui->filename); + if (gui->filename) { + g_free(gui->filename); + } - file_data = gtk_selection_data_get_data (selection_data); - file_list = g_strsplit ((gchar *)file_data, "\r\n", 0); + file_data = gtk_selection_data_get_data(selection_data); + file_list = g_strsplit((gchar *)file_data, "\r\n", 0); - file_uri = g_file_new_for_uri (file_list[0]); - gui->filename = g_file_get_path (file_uri); + file_uri = g_file_new_for_uri(file_list[0]); + gui->filename = g_file_get_path(file_uri); - g_strfreev (file_list); - g_object_unref (file_uri); + g_strfreev(file_list); + g_object_unref(file_uri); - store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) - gtk_list_store_clear (store); + store = GTK_LIST_STORE(gtk_tree_view_get_model(gui->devmem_treeview)); + + if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) { + gtk_list_store_clear(store); + } - stlink_gui_set_sensitivity (gui, FALSE); - gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); - gtk_widget_show (GTK_WIDGET (gui->progress.bar)); - gtk_progress_bar_set_text (gui->progress.bar, "Reading file"); - g_thread_new ("file", (GThreadFunc) stlink_gui_populate_filemem_view, gui); + stlink_gui_set_sensitivity(gui, FALSE); + gtk_notebook_set_current_page(gui->notebook, PAGE_FILEMEM); + gtk_widget_show(GTK_WIDGET(gui->progress.bar)); + gtk_progress_bar_set_text(gui->progress.bar, "Reading file"); + g_thread_new("file", (GThreadFunc)stlink_gui_populate_filemem_view, gui); break; } } - gtk_drag_finish ( - context, - TRUE, - gdk_drag_context_get_suggested_action (context) == GDK_ACTION_MOVE, - timestamp); + + gtk_drag_finish( + context, + TRUE, + gdk_drag_context_get_suggested_action(context) == GDK_ACTION_MOVE, + timestamp); } -void stlink_gui_init_dnd (STlinkGUI *gui) { - GtkTargetEntry target_list[] = { { "text/uri-list", 0, TARGET_FILENAME }, }; +void stlink_gui_init_dnd(STlinkGUI *gui) { + GtkTargetEntry target_list[] = { + { "text/uri-list", 0, TARGET_FILENAME }, + }; gtk_drag_dest_set( - GTK_WIDGET (gui->window), - GTK_DEST_DEFAULT_ALL, - target_list, - G_N_ELEMENTS (target_list), - GDK_ACTION_COPY); + GTK_WIDGET(gui->window), + GTK_DEST_DEFAULT_ALL, + target_list, + G_N_ELEMENTS(target_list), + GDK_ACTION_COPY); - g_signal_connect (gui->window, "drag-data-received", G_CALLBACK (dnd_received_cb), gui); + g_signal_connect(gui->window, "drag-data-received", G_CALLBACK(dnd_received_cb), gui); } -static void stlink_gui_build_ui (STlinkGUI *gui) { - GtkBuilder *builder; +static void stlink_gui_build_ui(STlinkGUI *gui) { + GtkBuilder *builder; GtkListStore *devmem_store; GtkListStore *filemem_store; gchar *ui_file = STLINK_UI_DIR "/stlink-gui.ui"; - if (!g_file_test (ui_file, G_FILE_TEST_EXISTS)) ui_file = "stlink-gui.ui"; - builder = gtk_builder_new (); - if (!gtk_builder_add_from_file (builder, ui_file, NULL)) { - g_printerr ("Failed to load UI file: %s\n", ui_file); - exit (1); - } - - gui->window = GTK_WINDOW (gtk_builder_get_object (builder, "window")); - g_signal_connect (G_OBJECT (gui->window), "destroy", G_CALLBACK (gtk_main_quit), NULL); - - /* set up toolutton clicked callbacks */ - gui->open_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "open_button")); - g_signal_connect (G_OBJECT (gui->open_button), "clicked", G_CALLBACK (open_button_cb), gui); - - gui->connect_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "connect_button")); - g_signal_connect (G_OBJECT (gui->connect_button), "clicked", G_CALLBACK (connect_button_cb), gui); - - gui->disconnect_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "disconnect_button")); - g_signal_connect (G_OBJECT (gui->disconnect_button), "clicked", G_CALLBACK (disconnect_button_cb), gui); - - gui->flash_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "flash_button")); - g_signal_connect (G_OBJECT (gui->flash_button), "clicked", G_CALLBACK (flash_button_cb), gui); - - gui->export_button = GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "export_button")); - g_signal_connect (G_OBJECT (gui->export_button), "clicked", G_CALLBACK (export_button_cb), gui); - - gui->devmem_treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "devmem_treeview")); - mem_view_init_headers (gui->devmem_treeview); - devmem_store = gtk_list_store_new (5, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING); - gtk_tree_view_set_model (gui->devmem_treeview, GTK_TREE_MODEL (devmem_store)); - g_object_unref (devmem_store); - - gui->filemem_treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "filemem_treeview")); - mem_view_init_headers (gui->filemem_treeview); - filemem_store = gtk_list_store_new (5, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING); - gtk_tree_view_set_model (gui->filemem_treeview, GTK_TREE_MODEL (filemem_store)); - g_object_unref (filemem_store); - - gui->core_id_label = GTK_LABEL (gtk_builder_get_object (builder, "core_id_value")); - gui->chip_id_label = GTK_LABEL (gtk_builder_get_object (builder, "chip_id_value")); - gui->flash_size_label = GTK_LABEL (gtk_builder_get_object (builder, "flash_size_value")); - gui->ram_size_label = GTK_LABEL (gtk_builder_get_object (builder, "ram_size_value")); - gui->device_frame = GTK_FRAME (gtk_builder_get_object (builder, "device_frame")); - - gui->notebook = GTK_NOTEBOOK (gtk_builder_get_object (builder, "mem_notebook")); - g_signal_connect (gui->notebook, "switch-page", G_CALLBACK (notebook_switch_page_cb), gui); - - gui->devmem_box = GTK_BOX (gtk_builder_get_object (builder, "devmem_box")); - gui->filemem_box = GTK_BOX (gtk_builder_get_object (builder, "filemem_box")); - - gui->devmem_jmp_entry = GTK_ENTRY (gtk_builder_get_object (builder, "devmem_jmp_entry")); - g_signal_connect (gui->devmem_jmp_entry, "activate", G_CALLBACK (devmem_jmp_cb), gui); - - gui->filemem_jmp_entry = GTK_ENTRY (gtk_builder_get_object (builder, "filemem_jmp_entry")); - g_signal_connect (gui->filemem_jmp_entry, "activate", G_CALLBACK (filemem_jmp_cb), gui); - gtk_editable_set_editable (GTK_EDITABLE (gui->filemem_jmp_entry), TRUE); - - gui->progress.bar = GTK_PROGRESS_BAR (gtk_builder_get_object (builder, "progressbar")); - gtk_progress_bar_set_show_text (gui->progress.bar, TRUE); - gui->progress.timer = g_timeout_add (100, (GSourceFunc) progress_pulse_timeout, gui); - - gui->statusbar = GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")); - - gui->infobar = GTK_INFO_BAR (gtk_builder_get_object (builder, "infobar")); - gtk_info_bar_add_button (gui->infobar, "_OK", GTK_RESPONSE_OK); - gui->infolabel = GTK_LABEL (gtk_label_new ("")); - gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (gui->infobar)), GTK_WIDGET (gui->infolabel)); - g_signal_connect (gui->infobar, "response", G_CALLBACK (gtk_widget_hide), NULL); - - /* flash dialog */ - gui->flash_dialog = GTK_DIALOG (gtk_builder_get_object (builder, "flash_dialog")); - g_signal_connect_swapped (gui->flash_dialog, "response", G_CALLBACK (gtk_widget_hide), gui->flash_dialog); - gui->flash_dialog_ok = GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_ok_button")); - gui->flash_dialog_cancel = GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_cancel_button")); - gui->flash_dialog_entry = GTK_ENTRY (gtk_builder_get_object (builder, "flash_dialog_entry")); - - /* make it so */ - gtk_widget_show_all (GTK_WIDGET (gui->window)); - gtk_widget_hide (GTK_WIDGET (gui->infobar)); - gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); - - stlink_gui_set_disconnected (gui); -} - -int main (int argc, char **argv) { + if (!g_file_test(ui_file, G_FILE_TEST_EXISTS)) { ui_file = "stlink-gui.ui"; } + + builder = gtk_builder_new(); + + if (!gtk_builder_add_from_file(builder, ui_file, NULL)) { + g_printerr("Failed to load UI file: %s\n", ui_file); + exit(1); + } + + gui->window = GTK_WINDOW(gtk_builder_get_object(builder, "window")); + g_signal_connect(G_OBJECT(gui->window), "destroy", G_CALLBACK(gtk_main_quit), NULL); + + /* Setup for toolbutton clicked callbacks */ + gui->open_button = GTK_TOOL_BUTTON(gtk_builder_get_object(builder, "open_button")); + g_signal_connect(G_OBJECT(gui->open_button), "clicked", G_CALLBACK(open_button_cb), gui); + + gui->connect_button = GTK_TOOL_BUTTON(gtk_builder_get_object(builder, "connect_button")); + g_signal_connect(G_OBJECT(gui->connect_button), "clicked", G_CALLBACK(connect_button_cb), gui); + + gui->disconnect_button = GTK_TOOL_BUTTON(gtk_builder_get_object(builder, "disconnect_button")); + g_signal_connect(G_OBJECT(gui->disconnect_button), "clicked", G_CALLBACK(disconnect_button_cb), gui); + + gui->flash_button = GTK_TOOL_BUTTON(gtk_builder_get_object(builder, "flash_button")); + g_signal_connect(G_OBJECT(gui->flash_button), "clicked", G_CALLBACK(flash_button_cb), gui); + + gui->export_button = GTK_TOOL_BUTTON(gtk_builder_get_object(builder, "export_button")); + g_signal_connect(G_OBJECT(gui->export_button), "clicked", G_CALLBACK(export_button_cb), gui); + + gui->devmem_treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "devmem_treeview")); + mem_view_init_headers(gui->devmem_treeview); + devmem_store = gtk_list_store_new(5, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); + gtk_tree_view_set_model(gui->devmem_treeview, GTK_TREE_MODEL(devmem_store)); + g_object_unref(devmem_store); + + gui->filemem_treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "filemem_treeview")); + mem_view_init_headers(gui->filemem_treeview); + filemem_store = gtk_list_store_new(5, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); + gtk_tree_view_set_model(gui->filemem_treeview, GTK_TREE_MODEL(filemem_store)); + g_object_unref(filemem_store); + + gui->core_id_label = GTK_LABEL(gtk_builder_get_object(builder, "core_id_value")); + gui->chip_id_label = GTK_LABEL(gtk_builder_get_object(builder, "chip_id_value")); + gui->flash_size_label = GTK_LABEL(gtk_builder_get_object(builder, "flash_size_value")); + gui->ram_size_label = GTK_LABEL(gtk_builder_get_object(builder, "ram_size_value")); + gui->device_frame = GTK_FRAME(gtk_builder_get_object(builder, "device_frame")); + + gui->notebook = GTK_NOTEBOOK(gtk_builder_get_object(builder, "mem_notebook")); + g_signal_connect(gui->notebook, "switch-page", G_CALLBACK(notebook_switch_page_cb), gui); + + gui->devmem_box = GTK_BOX(gtk_builder_get_object(builder, "devmem_box")); + gui->filemem_box = GTK_BOX(gtk_builder_get_object(builder, "filemem_box")); + + gui->devmem_jmp_entry = GTK_ENTRY(gtk_builder_get_object(builder, "devmem_jmp_entry")); + g_signal_connect(gui->devmem_jmp_entry, "activate", G_CALLBACK(devmem_jmp_cb), gui); + + gui->filemem_jmp_entry = GTK_ENTRY(gtk_builder_get_object(builder, "filemem_jmp_entry")); + g_signal_connect(gui->filemem_jmp_entry, "activate", G_CALLBACK(filemem_jmp_cb), gui); + gtk_editable_set_editable(GTK_EDITABLE(gui->filemem_jmp_entry), TRUE); + + gui->progress.bar = GTK_PROGRESS_BAR(gtk_builder_get_object(builder, "progressbar")); + gtk_progress_bar_set_show_text(gui->progress.bar, TRUE); + gui->progress.timer = g_timeout_add(100, (GSourceFunc)progress_pulse_timeout, gui); + + gui->statusbar = GTK_STATUSBAR(gtk_builder_get_object(builder, "statusbar")); + + gui->infobar = GTK_INFO_BAR(gtk_builder_get_object(builder, "infobar")); + gtk_info_bar_add_button(gui->infobar, "_OK", GTK_RESPONSE_OK); + gui->infolabel = GTK_LABEL(gtk_label_new("")); + gtk_container_add(GTK_CONTAINER(gtk_info_bar_get_content_area(gui->infobar)), GTK_WIDGET(gui->infolabel)); + g_signal_connect(gui->infobar, "response", G_CALLBACK(gtk_widget_hide), NULL); + + /* Flash dialog */ + gui->flash_dialog = GTK_DIALOG(gtk_builder_get_object(builder, "flash_dialog")); + g_signal_connect_swapped(gui->flash_dialog, "response", G_CALLBACK(gtk_widget_hide), gui->flash_dialog); + gui->flash_dialog_ok = GTK_BUTTON(gtk_builder_get_object(builder, "flash_dialog_ok_button")); + gui->flash_dialog_cancel = GTK_BUTTON(gtk_builder_get_object(builder, "flash_dialog_cancel_button")); + gui->flash_dialog_entry = GTK_ENTRY(gtk_builder_get_object(builder, "flash_dialog_entry")); + + // make it so + gtk_widget_show_all(GTK_WIDGET(gui->window)); + gtk_widget_hide(GTK_WIDGET(gui->infobar)); + gtk_widget_hide(GTK_WIDGET(gui->progress.bar)); + + stlink_gui_set_disconnected(gui); +} + +int main(int argc, char **argv) { STlinkGUI *gui; - gtk_init (&argc, &argv); + gtk_init(&argc, &argv); - gui = g_object_new (STLINK_TYPE_GUI, NULL); - stlink_gui_build_ui (gui); - stlink_gui_init_dnd (gui); + gui = g_object_new(STLINK_TYPE_GUI, NULL); + stlink_gui_build_ui(gui); + stlink_gui_init_dnd(gui); - gtk_main (); - return 0; + gtk_main(); + return(0); } diff --git a/src/stlink-gui/gui.h b/src/stlink-gui/gui.h index c83e638f6..b3d5dfff8 100644 --- a/src/stlink-gui/gui.h +++ b/src/stlink-gui/gui.h @@ -1,19 +1,18 @@ - #ifndef __STLINK_GUI_H__ #define __STLINK_GUI_H__ #include -#define STLINK_TYPE_GUI (stlink_gui_get_type ()) -#define STLINK_GUI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STLINK_TYPE_GUI, STlinkGUI)) -#define STLINK_IS_GUI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STLINK_TYPE_GUI)) -#define STLINK_GUI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STLINK_TYPE_GUI, STlinkGUIClass)) -#define STLINK_IS_GUI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STLINK_TYPE_GUI)) -#define STLINK_GUI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STLINK_TYPE_GUI, STlinkGUIlass)) -#define STLINK_GUI_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), STLINK_TYPE_GUI, STlinkGUIPrivate)) +#define STLINK_TYPE_GUI (stlink_gui_get_type()) +#define STLINK_GUI(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), STLINK_TYPE_GUI, STlinkGUI)) +#define STLINK_IS_GUI(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), STLINK_TYPE_GUI)) +#define STLINK_GUI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), STLINK_TYPE_GUI, STlinkGUIClass)) +#define STLINK_IS_GUI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), STLINK_TYPE_GUI)) +#define STLINK_GUI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), STLINK_TYPE_GUI, STlinkGUIlass)) +#define STLINK_GUI_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), STLINK_TYPE_GUI, STlinkGUIPrivate)) -typedef struct _STlinkGUI STlinkGUI; -typedef struct _STlinkGUIClass STlinkGUIClass; +typedef struct _STlinkGUI STlinkGUI; +typedef struct _STlinkGUIClass STlinkGUIClass; typedef struct _STlinkGUIPrivate STlinkGUIPrivate; enum stlink_gui_pages_t { @@ -28,21 +27,21 @@ enum stlink_gui_dnd_targets_t { struct progress_t { GtkProgressBar *bar; - guint timer; - gboolean activity_mode; - gdouble fraction; + guint timer; + gboolean activity_mode; + gdouble fraction; }; struct mem_t { guchar *memory; - gsize size; + gsize size; guint32 base; }; struct _STlinkGUI { GObject parent_instance; - /*< private >*/ + /* < private > */ GtkWindow *window; GtkTreeView *devmem_treeview; GtkTreeView *filemem_treeview; @@ -72,9 +71,9 @@ struct _STlinkGUI { GtkButton *flash_dialog_cancel; GtkEntry *flash_dialog_entry; - struct progress_t progress; - struct mem_t flash_mem; - struct mem_t file_mem; + struct progress_t progress; + struct mem_t flash_mem; + struct mem_t file_mem; gchar *error_message; gchar *filename; @@ -87,7 +86,7 @@ struct _STlinkGUIClass { /* class members */ }; -GType stlink_gui_get_type (void); +GType stlink_gui_get_type(void); int export_to_file(const char*filename, const struct mem_t flash_mem); -#endif +#endif // __STLINK_GUI_H__ diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index e6a82a2a9..bf0a56c96 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -2,636 +2,637 @@ #include "chipid.h" static const struct stlink_chipid_params devices[] = { - { - //RM0410 document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F7XXXX, - .description = "F76xxx", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff0f442, // section 45.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x80000, // "SRAM" byte size in hex from - .bootrom_base = 0x00200000, //! "System memory" starting address from - .bootrom_size = 0xEDC0 //! @todo "System memory" byte size in hex from - }, - { - //RM0385 and DS10916 document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F7, - .description = "F7xx", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff0f442, // section 41.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 - .bootrom_size = 0xEDC0 // "System memory" byte size in hex from DS Fig 18 - }, - { - //RM0431 and DS document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F72XXX, - .description = "F72x/F73x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff07a22, // section 35.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 - .bootrom_size = 0xEDC0 // "System memory" byte size in hex from DS Fig 24 - }, - { // table 2, PM0063 - .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, - .description = "F1xx Medium-density", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x5000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { // table 1, PM0059 - .chip_id = STLINK_CHIPID_STM32_F2, - .description = "F2xx", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, /* As in RM0033 Rev 5*/ - .flash_pagesize = 0x20000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .option_base = 0x1FFFC000, - .option_size = 4, - }, - { // PM0063 - .chip_id = STLINK_CHIPID_STM32_F1_LOW, - .description = "F1 Low-density device", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2800, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - .chip_id = STLINK_CHIPID_STM32_F4, - .description = "F4xx", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ - .flash_pagesize = 0x4000, - .sram_size = 0x30000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - .chip_id = STLINK_CHIPID_STM32_F4_DSI, - .description = "F46x/F47x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ - .flash_pagesize = 0x4000, - .sram_size = 0x40000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - .chip_id = STLINK_CHIPID_STM32_F4_HD, - .description = "F42x/F43x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ - .flash_pagesize = 0x4000, - .sram_size = 0x40000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - .chip_id = STLINK_CHIPID_STM32_F4_LP, - .description = "F4xx (low power)", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x10000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - .chip_id = STLINK_CHIPID_STM32_F411RE, - .description = "stm32f411re", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - .chip_id = STLINK_CHIPID_STM32_F4_DE, - .description = "F4xx (Dynamic Efficency)", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - .chip_id = STLINK_CHIPID_STM32_F1_HIGH, - .description = "F1xx High-density", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - // This ignores the EEPROM! (and uses the page erase size, - // not the sector write protection...) - .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM, - .description = "L1xx Medium-density", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8004c, - .flash_pagesize = 0x100, - .sram_size = 0x4000, - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 - }, - { - .chip_id = STLINK_CHIPID_STM32_L1_CAT2, - .description = "L1xx Cat.2", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8004c, - .flash_pagesize = 0x100, - .sram_size = 0x8000, - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 - }, - { - .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM_PLUS, - .description = "L1xx Medium-Plus-density", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x8000,/*Not completely clear if there are some with 48K*/ - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 - }, - { - .chip_id = STLINK_CHIPID_STM32_L1_HIGH, - .description = "L1xx High-density", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0xC000, /*Not completely clear if there are some with 32K*/ - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .option_base = STM32_L1_OPTION_BYTES_BASE, - .option_size = 8, - }, - { - .chip_id = STLINK_CHIPID_STM32_L152_RE, - .description = "L152RE", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x14000, /*Not completely clear if there are some with 32K*/ - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 - }, - { - .chip_id = STLINK_CHIPID_STM32_F1_CONN, - .description = "F1 Connectivity line", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1fffb000, - .bootrom_size = 0x4800 - }, - {//Low and Medium density VL have same chipid. RM0041 25.6.1 - .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, - .description = "F1xx Value Line", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2000,//0x1000 for low density devices - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - // STM32F446x family. Support based on DM00135183.pdf (RM0390) document. - .chip_id = STLINK_CHIPID_STM32_F446, - .description = "F446", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, - .flash_pagesize = 0x20000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .option_base = 0x1FFFC000, - .option_size = 4, - }, - { - // STM32F410 MCUs. Support based on DM00180366.pdf (RM0401) document. - .chip_id = STLINK_CHIPID_STM32_F410, - .description = "F410", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, - .flash_pagesize = 0x4000, - .sram_size = 0x8000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - // This is STK32F303VCT6 device from STM32 F3 Discovery board. - // Support based on DM00043574.pdf (RM0316) document. - .chip_id = STLINK_CHIPID_STM32_F3, - .description = "F3xx", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - // This is STK32F373VCT6 device from STM32 F373 eval board - // Support based on 303 above (37x and 30x have same memory map) - .chip_id = STLINK_CHIPID_STM32_F37x, - .description = "F3xx", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - .chip_id = STLINK_CHIPID_STM32_F1_VL_HIGH, - .description = "F1xx High-density value line", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x8000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - .chip_id = STLINK_CHIPID_STM32_F1_XL, - .description = "F1xx XL-density", - .flash_type = STLINK_FLASH_TYPE_F1_XL, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x18000, - .bootrom_base = 0x1fffe000, - .bootrom_size = 0x1800 - }, - { - //Use this as an example for mapping future chips: - //RM0091 document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F0_CAN, - .description = "F07x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 - .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 - .bootrom_size = 0x3000 // "System memory" byte size in hex from Table 2 - }, - { - //Use this as an example for mapping future chips: - //RM0091 document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F0, - .description = "F0xx", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 - }, - { - // RM0402 document was used to find these parameters - // Table 4. - .chip_id = STLINK_CHIPID_STM32_F412, - .description = "F412", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) - .flash_pagesize = 0x4000, // Table 5. Flash module organization ? - .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 - .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800 // "System memory" byte size in hex from Table 4 - }, - { - // RM0430 DocID029473 Rev 2 document was used to find these parameters - // Figure 2, Table 4, Table 5, Section 35.2 - .chip_id = STLINK_CHIPID_STM32_F413, - .description = "F413", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 - .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector sizes, but 0x4000 is smallest) - .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 only says 0x40000) - .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800 // "System memory" byte size in hex from Table 4 - }, - { - .chip_id = STLINK_CHIPID_STM32_F09X, - .description = "F09X", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) - .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) - .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 - .bootrom_size = 0x2000 // "System memory" byte size in hex from Table 2 - }, - { - //Use this as an example for mapping future chips: - //RM0091 document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F04, - .description = "F04x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 - }, - { - //Use this as an example for mapping future chips: - //RM0091 document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F0_SMALL, - .description = "F0xx small", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 - }, - { - // STM32F30x - .chip_id = STLINK_CHIPID_STM32_F3_SMALL, - .description = "F3xx small", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1fffd800, - .bootrom_size = 0x2000 - }, - { - // STM32L0x - // RM0367,RM0377 documents was used to find these parameters - .chip_id = STLINK_CHIPID_STM32_L0, - .description = "L0x3", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000, - .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32L0x Category 5 - // RM0367,RM0377 documents was used to find these parameters - .chip_id = STLINK_CHIPID_STM32_L0_CAT5, - .description = "L0xx Category 5", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x5000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x2000, - .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32L0x Category 2 - // RM0367,RM0377 documents was used to find these parameters - .chip_id = STLINK_CHIPID_STM32_L0_CAT2, - .description = "L0xx Category 2", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000, - .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32F334, STM32F303x6/8, and STM32F328 - // From RM0364 and RM0316 - .chip_id = STLINK_CHIPID_STM32_F334, - .description = "F334 medium density", // (RM0316 sec 33.6.1) - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0x3000, - .bootrom_base = 0x1fffd800, - .bootrom_size = 0x2000 - }, - { - // This is STK32F303RET6 device from STM32 F3 Nucelo board. - // Support based on DM00043574.pdf (RM0316) document rev 5. - .chip_id = STLINK_CHIPID_STM32_F303_HIGH, - .description = "F303 high density", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register - .flash_pagesize = 0x800, // 4.2.1 Flash memory organization - .sram_size = 0x10000, // 3.3 Embedded SRAM - .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory - .bootrom_size = 0x2000 - }, - { - // STM32L4x6 - // From RM0351. - .chip_id = STLINK_CHIPID_STM32_L4, - .description = "L4xx", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) - .flash_pagesize = 0x800, // 2K (sec 3.2, page 78; also appears in sec 3.3.1 and tables 4-6 on pages 79-81) - // SRAM1 is "up to" 96k in the standard Cortex-M memory map; - // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) - .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32L4RX - // From DM00310109.pdf - .chip_id = STLINK_CHIPID_STM32_L4RX, - .description = "L4Rx", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 52.2, page 2049) - .flash_pagesize = 0x1000, // 4k, section 3.3, pg 97 - .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 - .bootrom_base = 0x1fff0000, // 3.3.1, pg 99 - .bootrom_size = 0x7000 // 28k (per bank), same source as base (pg 99) - }, - { - // STLINK_CHIPID_STM32_L41X - // From RM0394 Rev 4 and DS12469 Rev 5 - .chip_id = STLINK_CHIPID_STM32_L41X, - .description = "L41x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, sec 47.2, page 1586) - .flash_pagesize = 0x800, // 2K (DS12469, sec 3.4, page 17) - // SRAM1 is 32k at 0x20000000 - // SRAM2 is 8k at 0x10000000 and 0x20008000 (DS12469, sec 3.5, page 18) - .sram_size = 0xa000, // 40K (DS12469, sec 3.5, page 18) - .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) - .bootrom_size = 0x7000 // 28k, same source as base - }, - { - // STLINK_CHIPID_STM32_L43X - // From RM0392. - .chip_id = STLINK_CHIPID_STM32_L43X, - .description = "L43x/L44x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) - .flash_pagesize = 0x800, // 2K (sec 3.2, page 74; also appears in sec 3.3.1 and tables 7-8 on pages 75-76) - // SRAM1 is "up to" 64k in the standard Cortex-M memory map; - // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) - .sram_size = 0xc000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STLINK_CHIPID_STM32_L496X - // Support based on en.DM00083560.pdf (RM0351) document rev 5. - .chip_id = STLINK_CHIPID_STM32_L496X, - .description = "L496x/L4A6x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) - .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) - // SRAM1 is 256k at 0x20000000 - // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) - .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) - .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STLINK_CHIPID_STM32_L46X - // From RM0394 (updated version of RM0392?). - .chip_id = STLINK_CHIPID_STM32_L46X, - .description = "L45x/46x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) - .flash_pagesize = 0x800, // 2K (sec 3.2, page 73; also appears in sec 3.3.1 and tables 7 on pages 73-74) - // SRAM1 is 128k at 0x20000000; - // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, page 68, also fig 2 on page 63) - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system memory, also fig 2 on page 63) - .bootrom_size = 0x7000 // 28k (per bank), same source as base - }, - { - // STM32L011 - .chip_id = STLINK_CHIPID_STM32_L011, - .description = "L011", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x2000 - }, - { - // STM32G030/031/041 (from RM0454 & RM0444) - .chip_id = STLINK_CHIPID_STM32_G0_CAT1, - .description = "G030/G031/G041", - .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2K (sec 3.2) - .sram_size = 0x2000, // 8K (sec 2.3) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x2000, // 8K (sec 2.2.2 table 3) - .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32G071/081 (from RM0444) - .chip_id = STLINK_CHIPID_STM32_G0_CAT2, - .description = "G070/G071/G081", - .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2K (sec 3.2) - .sram_size = 0x9000, // 36K (sec 2.3) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28K (sec 2.2.2 table 2) - .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32G431/441 (from RM0440) - .chip_id = STLINK_CHIPID_STM32_G4_CAT2, - .description = "G4 Category-2", - .flash_type = STLINK_FLASH_TYPE_G4, - .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = 0x800, // 2K (sec 3.3.1) - // SRAM1 is 16k at 0x20000000 - // SRAM2 is 6k at 0x20014000 - // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x8000, // 32K (sec 2.4) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28K (table 2) - .option_base = STM32_G4_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32G471/473/474/483/484 (from RM0440) - .chip_id = STLINK_CHIPID_STM32_G4_CAT3, - .description = "G4 Category-3", - .flash_type = STLINK_FLASH_TYPE_G4, - .has_dual_bank = true, - .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = 0x800, // 2K (sec 3.3.1) - // SRAM1 is 80k at 0x20000000 - // SRAM2 is 16k at 0x20014000 - // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x18000, // 128K (sec 2.4) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28K (table 2) - .option_base = STM32_G4_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32WB55 (from RM0434) - .chip_id = STLINK_CHIPID_STM32_WB55, - .description = "WB55", - .flash_type = STLINK_FLASH_TYPE_WB, - .flash_size_reg = 0x1FFF75E0, - .flash_pagesize = 0x1000, // 4K - .sram_size = 0x40000, - .bootrom_base = 0x1fff0000, // See the memory map - .bootrom_size = 0x7000 - }, - { - // unknown - .chip_id = STLINK_CHIPID_UNKNOWN, - .description = "unknown device", - .flash_type = STLINK_FLASH_TYPE_UNKNOWN, - .flash_size_reg = 0x0, - .flash_pagesize = 0x0, - .sram_size = 0x0, - .bootrom_base = 0x0, - .bootrom_size = 0x0 - }, - }; + { + // RM0410 document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_F7XXXX, + .description = "F76xxx", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1ff0f442, // section 45.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x80000, // "SRAM" byte size in hex from + .bootrom_base = 0x00200000, // ! "System memory" starting address from + .bootrom_size = 0xEDC0 // ! @todo "System memory" byte size in hex from + }, + { + // RM0385 and DS10916 document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_F7, + .description = "F7xx", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1ff0f442, // section 41.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 + .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 + .bootrom_size = 0xEDC0 // "System memory" byte size in hex from DS Fig 18 + }, + { + // RM0431 and DS document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_F72XXX, + .description = "F72x/F73x", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1ff07a22, // section 35.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 + .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 + .bootrom_size = 0xEDC0 // "System memory" byte size in hex from DS Fig 24 + }, + { // table 2, PM0063 + .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, + .description = "F1xx Medium-density", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x5000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { // table 1, PM0059 + .chip_id = STLINK_CHIPID_STM32_F2, + .description = "F2xx", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1fff7a22, // as in RM0033 Rev 5 + .flash_pagesize = 0x20000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .option_base = 0x1FFFC000, + .option_size = 4, + }, + { // PM0063 + .chip_id = STLINK_CHIPID_STM32_F1_LOW, + .description = "F1 Low-density device", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2800, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F4, + .description = "F4xx", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_pagesize = 0x4000, + .sram_size = 0x30000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F4_DSI, + .description = "F46x/F47x", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_pagesize = 0x4000, + .sram_size = 0x40000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F4_HD, + .description = "F42x/F43x", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_pagesize = 0x4000, + .sram_size = 0x40000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F4_LP, + .description = "F4xx (low power)", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x10000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F411RE, + .description = "stm32f411re", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F4_DE, + .description = "F4xx (Dynamic Efficency)", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x18000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F1_HIGH, + .description = "F1xx High-density", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + // This ignores the EEPROM! (and uses the page erase size, + // not the sector write protection...) + .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM, + .description = "L1xx Medium-density", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8004c, + .flash_pagesize = 0x100, + .sram_size = 0x4000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, + { + .chip_id = STLINK_CHIPID_STM32_L1_CAT2, + .description = "L1xx Cat.2", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8004c, + .flash_pagesize = 0x100, + .sram_size = 0x8000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, + { + .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM_PLUS, + .description = "L1xx Medium-Plus-density", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0x8000, // not completely clear if there are some with 48k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, + { + .chip_id = STLINK_CHIPID_STM32_L1_HIGH, + .description = "L1xx High-density", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0xC000, // not completely clear if there are some with 32k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000, + .option_base = STM32_L1_OPTION_BYTES_BASE, + .option_size = 8, + }, + { + .chip_id = STLINK_CHIPID_STM32_L152_RE, + .description = "L152RE", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0x14000, // not completely clear if there are some with 32k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, + { + .chip_id = STLINK_CHIPID_STM32_F1_CONN, + .description = "F1 Connectivity line", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1fffb000, + .bootrom_size = 0x4800 + }, + { // Low and Medium density VL have same chipid. RM0041 25.6.1 + .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, + .description = "F1xx Value Line", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2000, // 0x1000 for low density devices + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + // STM32F446x family. Support based on DM00135183.pdf (RM0390) document. + .chip_id = STLINK_CHIPID_STM32_F446, + .description = "F446", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1fff7a22, + .flash_pagesize = 0x20000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .option_base = 0x1FFFC000, + .option_size = 4, + }, + { + // STM32F410 MCUs. Support based on DM00180366.pdf (RM0401) document. + .chip_id = STLINK_CHIPID_STM32_F410, + .description = "F410", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1fff7a22, + .flash_pagesize = 0x4000, + .sram_size = 0x8000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + // This is STK32F303VCT6 device from STM32 F3 Discovery board. + // Support based on DM00043574.pdf (RM0316) document. + .chip_id = STLINK_CHIPID_STM32_F3, + .description = "F3xx", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + // This is STK32F373VCT6 device from STM32 F373 eval board + // Support based on 303 above (37x and 30x have same memory map) + .chip_id = STLINK_CHIPID_STM32_F37x, + .description = "F3xx", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F1_VL_HIGH, + .description = "F1xx High-density value line", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x8000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + .chip_id = STLINK_CHIPID_STM32_F1_XL, + .description = "F1xx XL-density", + .flash_type = STLINK_FLASH_TYPE_F1_XL, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x18000, + .bootrom_base = 0x1fffe000, + .bootrom_size = 0x1800 + }, + { + // Use this as an example for mapping future chips: + // RM0091 document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_F0_CAN, + .description = "F07x", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 + .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 + .bootrom_size = 0x3000 // "System memory" byte size in hex from Table 2 + }, + { + // Use this as an example for mapping future chips: + // RM0091 document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_F0, + .description = "F0xx", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + }, + { + // RM0402 document was used to find these parameters + // Table 4. + .chip_id = STLINK_CHIPID_STM32_F412, + .description = "F412", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) + .flash_pagesize = 0x4000, // Table 5. Flash module organization ? + .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 + .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 + .bootrom_size = 0x7800 // "System memory" byte size in hex from Table 4 + }, + { + // RM0430 DocID029473 Rev 2 document was used to find these parameters + // Figure 2, Table 4, Table 5, Section 35.2 + .chip_id = STLINK_CHIPID_STM32_F413, + .description = "F413", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 + .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector sizes, but 0x4000 is smallest) + .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 only says 0x40000) + .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 + .bootrom_size = 0x7800 // "System memory" byte size in hex from Table 4 + }, + { + .chip_id = STLINK_CHIPID_STM32_F09X, + .description = "F09X", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) + .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) + .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 + .bootrom_size = 0x2000 // "System memory" byte size in hex from Table 2 + }, + { + // Use this as an example for mapping future chips: + // RM0091 document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_F04, + .description = "F04x", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + }, + { + // Use this as an example for mapping future chips: + // RM0091 document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_F0_SMALL, + .description = "F0xx small", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + }, + { + // STM32F30x + .chip_id = STLINK_CHIPID_STM32_F3_SMALL, + .description = "F3xx small", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1fffd800, + .bootrom_size = 0x2000 + }, + { + // STM32L0x + // RM0367,RM0377 documents was used to find these parameters + .chip_id = STLINK_CHIPID_STM32_L0, + .description = "L0x3", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x2000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x1000, + .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STM32L0x Category 5 + // RM0367,RM0377 documents was used to find these parameters + .chip_id = STLINK_CHIPID_STM32_L0_CAT5, + .description = "L0xx Category 5", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x5000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x2000, + .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STM32L0x Category 2 + // RM0367,RM0377 documents was used to find these parameters + .chip_id = STLINK_CHIPID_STM32_L0_CAT2, + .description = "L0xx Category 2", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x2000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x1000, + .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STM32F334, STM32F303x6/8, and STM32F328 + // From RM0364 and RM0316 + .chip_id = STLINK_CHIPID_STM32_F334, + .description = "F334 medium density", // (RM0316 sec 33.6.1) + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0x3000, + .bootrom_base = 0x1fffd800, + .bootrom_size = 0x2000 + }, + { + // This is STK32F303RET6 device from STM32 F3 Nucelo board. + // Support based on DM00043574.pdf (RM0316) document rev 5. + .chip_id = STLINK_CHIPID_STM32_F303_HIGH, + .description = "F303 high density", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register + .flash_pagesize = 0x800, // 4.2.1 Flash memory organization + .sram_size = 0x10000, // 3.3 Embedded SRAM + .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory + .bootrom_size = 0x2000 + }, + { + // STM32L4x6 + // From RM0351. + .chip_id = STLINK_CHIPID_STM32_L4, + .description = "L4xx", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 + // and tables 4-6 on pages 79-81) + // SRAM1 is "up to" 96k in the standard Cortex-M memory map; + // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) + .sram_size = 0x18000, + .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STM32L4RX + // From DM00310109.pdf + .chip_id = STLINK_CHIPID_STM32_L4RX, + .description = "L4Rx", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 52.2, page 2049) + .flash_pagesize = 0x1000, // 4k, section 3.3, pg 97 + .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 + .bootrom_base = 0x1fff0000, // 3.3.1, pg 99 + .bootrom_size = 0x7000 // 28k (per bank), same source as base (pg 99) + }, + { + // STLINK_CHIPID_STM32_L41X + // From RM0394 Rev 4 and DS12469 Rev 5 + .chip_id = STLINK_CHIPID_STM32_L41X, + .description = "L41x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, sec 47.2, page 1586) + .flash_pagesize = 0x800, // 2k (DS12469, sec 3.4, page 17) + // SRAM1 is 32k at 0x20000000 + // SRAM2 is 8k at 0x10000000 and 0x20008000 (DS12469, sec 3.5, page 18) + .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) + .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) + .bootrom_size = 0x7000 // 28k, same source as base + }, + { + // STLINK_CHIPID_STM32_L43X + // From RM0392. + .chip_id = STLINK_CHIPID_STM32_L43X, + .description = "L43x/L44x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 + // and tables 7-8 on pages 75-76) + // SRAM1 is "up to" 64k in the standard Cortex-M memory map; + // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) + .sram_size = 0xc000, + .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STLINK_CHIPID_STM32_L496X + // Support based on en.DM00083560.pdf (RM0351) document rev 5. + .chip_id = STLINK_CHIPID_STM32_L496X, + .description = "L496x/L4A6x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) + .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) + // SRAM1 is 256k at 0x20000000 + // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) + .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) + .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STLINK_CHIPID_STM32_L46X + // From RM0394 (updated version of RM0392?). + .chip_id = STLINK_CHIPID_STM32_L46X, + .description = "L45x/46x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 + // and tables 7 on pages 73-74) + // SRAM1 is 128k at 0x20000000; + // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, page 68, also fig 2 on page 63) + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system memory, also fig 2 on page 63) + .bootrom_size = 0x7000 // 28k (per bank), same source as base + }, + { + // STM32L011 + .chip_id = STLINK_CHIPID_STM32_L011, + .description = "L011", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x2000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x2000 + }, + { + // STM32G030/031/041 (from RM0454 & RM0444) + .chip_id = STLINK_CHIPID_STM32_G0_CAT1, + .description = "G030/G031/G041", + .flash_type = STLINK_FLASH_TYPE_G0, + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (sec 3.2) + .sram_size = 0x2000, // 8k (sec 2.3) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 3) + .option_base = STM32_G0_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STM32G071/081 (from RM0444) + .chip_id = STLINK_CHIPID_STM32_G0_CAT2, + .description = "G070/G071/G081", + .flash_type = STLINK_FLASH_TYPE_G0, + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (sec 3.2) + .sram_size = 0x9000, // 36k (sec 2.3) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) + .option_base = STM32_G0_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STM32G431/441 (from RM0440) + .chip_id = STLINK_CHIPID_STM32_G4_CAT2, + .description = "G4 Category-2", + .flash_type = STLINK_FLASH_TYPE_G4, + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = 0x800, // 2k (sec 3.3.1) + // SRAM1 is 16k at 0x20000000 + // SRAM2 is 6k at 0x20014000 + // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 + .sram_size = 0x8000, // 32k (sec 2.4) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28k (table 2) + .option_base = STM32_G4_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STM32G471/473/474/483/484 (from RM0440) + .chip_id = STLINK_CHIPID_STM32_G4_CAT3, + .description = "G4 Category-3", + .flash_type = STLINK_FLASH_TYPE_G4, + .has_dual_bank = true, + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = 0x800, // 2k (sec 3.3.1) + // SRAM1 is 80k at 0x20000000 + // SRAM2 is 16k at 0x20014000 + // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 + .sram_size = 0x18000, // 128k (sec 2.4) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28k (table 2) + .option_base = STM32_G4_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STM32WB55 (from RM0434) + .chip_id = STLINK_CHIPID_STM32_WB55, + .description = "WB55", + .flash_type = STLINK_FLASH_TYPE_WB, + .flash_size_reg = 0x1FFF75E0, + .flash_pagesize = 0x1000, // 4k + .sram_size = 0x40000, + .bootrom_base = 0x1fff0000, // see the memory map + .bootrom_size = 0x7000 + }, + { + // unknown + .chip_id = STLINK_CHIPID_UNKNOWN, + .description = "unknown device", + .flash_type = STLINK_FLASH_TYPE_UNKNOWN, + .flash_size_reg = 0x0, + .flash_pagesize = 0x0, + .sram_size = 0x0, + .bootrom_base = 0x0, + .bootrom_size = 0x0 + }, +}; -const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) -{ - const struct stlink_chipid_params *params = NULL; +const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { + const struct stlink_chipid_params *params = NULL; - for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) { - if (devices[n].chip_id == chipid) { - params = &devices[n]; - break; - } - } + for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) + if (devices[n].chip_id == chipid) { + params = &devices[n]; + break; + } - return params; + return(params); } diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index 98164a8fc..b591f0012 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -8,79 +8,77 @@ extern "C" { /** * Chip IDs are explained in the appropriate programming manual for the * DBGMCU_IDCODE register (0xE0042000) - * stm32 chipids, only lower 12 bits.. + * stm32 chipids, only lower 12 bits... */ enum stlink_stm32_chipids { - STLINK_CHIPID_UNKNOWN = 0x000, + STLINK_CHIPID_UNKNOWN = 0x000, - STLINK_CHIPID_STM32_F1_MEDIUM = 0x410, - STLINK_CHIPID_STM32_F2 = 0x411, - STLINK_CHIPID_STM32_F1_LOW = 0x412, - STLINK_CHIPID_STM32_F4 = 0x413, - STLINK_CHIPID_STM32_F1_HIGH = 0x414, - STLINK_CHIPID_STM32_L4 = 0x415, - STLINK_CHIPID_STM32_L1_MEDIUM = 0x416, - STLINK_CHIPID_STM32_L0 = 0x417, - STLINK_CHIPID_STM32_F1_CONN = 0x418, - STLINK_CHIPID_STM32_F4_HD = 0x419, - STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW = 0x420, - STLINK_CHIPID_STM32_F446 = 0x421, - STLINK_CHIPID_STM32_F3 = 0x422, - STLINK_CHIPID_STM32_F4_LP = 0x423, - STLINK_CHIPID_STM32_L0_CAT2 = 0x425, - STLINK_CHIPID_STM32_L1_MEDIUM_PLUS = 0x427, /* assigned to some L1 "Medium-plus" chips */ - STLINK_CHIPID_STM32_F1_VL_HIGH = 0x428, - STLINK_CHIPID_STM32_L1_CAT2 = 0x429, - STLINK_CHIPID_STM32_F1_XL = 0x430, - STLINK_CHIPID_STM32_F411RE = 0x431, - STLINK_CHIPID_STM32_F37x = 0x432, - STLINK_CHIPID_STM32_F4_DE = 0x433, - STLINK_CHIPID_STM32_F4_DSI = 0x434, - STLINK_CHIPID_STM32_L43X = 0x435, /* covers STM32L43xxx and STM32L44xxx devices */ - STLINK_CHIPID_STM32_L496X = 0x461, /* covers STM32L496xx and STM32L4A6xx devices */ - STLINK_CHIPID_STM32_L46X = 0x462, /* covers STM32L45xxx and STM32L46xxx devices */ - STLINK_CHIPID_STM32_L41X = 0x464, /* covers STM32L41xxx and STM32L42xxx devices */ - STLINK_CHIPID_STM32_L1_HIGH = 0x436, /* assigned to some L1 chips called "Medium-Plus" and to some called "High" */ - STLINK_CHIPID_STM32_L152_RE = 0x437, - STLINK_CHIPID_STM32_F334 = 0x438, - STLINK_CHIPID_STM32_F3_SMALL = 0x439, - STLINK_CHIPID_STM32_F0 = 0x440, - STLINK_CHIPID_STM32_F412 = 0x441, - STLINK_CHIPID_STM32_F09X = 0x442, - STLINK_CHIPID_STM32_F0_SMALL = 0x444, - STLINK_CHIPID_STM32_F04 = 0x445, - STLINK_CHIPID_STM32_F303_HIGH = 0x446, - STLINK_CHIPID_STM32_L0_CAT5 = 0x447, - STLINK_CHIPID_STM32_F0_CAN = 0x448, - STLINK_CHIPID_STM32_F7 = 0x449, /* This ID is found on the NucleoF746ZG board */ - STLINK_CHIPID_STM32_F7XXXX = 0x451, - STLINK_CHIPID_STM32_F72XXX = 0x452, /* This ID is found on the NucleoF722ZE board */ - STLINK_CHIPID_STM32_L011 = 0x457, - STLINK_CHIPID_STM32_F410 = 0x458, - STLINK_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/081 */ - STLINK_CHIPID_STM32_F413 = 0x463, - STLINK_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/041 */ - STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* See: RM 0440 s46.6.1 "MCU device ID code" */ - STLINK_CHIPID_STM32_G4_CAT3 = 0x469, - STLINK_CHIPID_STM32_L4RX = 0x470, /* taken from the STM32L4R9I-DISCO board */ - STLINK_CHIPID_STM32_WB55 = 0x495 + STLINK_CHIPID_STM32_F1_MEDIUM = 0x410, + STLINK_CHIPID_STM32_F2 = 0x411, + STLINK_CHIPID_STM32_F1_LOW = 0x412, + STLINK_CHIPID_STM32_F4 = 0x413, + STLINK_CHIPID_STM32_F1_HIGH = 0x414, + STLINK_CHIPID_STM32_L4 = 0x415, + STLINK_CHIPID_STM32_L1_MEDIUM = 0x416, + STLINK_CHIPID_STM32_L0 = 0x417, + STLINK_CHIPID_STM32_F1_CONN = 0x418, + STLINK_CHIPID_STM32_F4_HD = 0x419, + STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW = 0x420, + STLINK_CHIPID_STM32_F446 = 0x421, + STLINK_CHIPID_STM32_F3 = 0x422, + STLINK_CHIPID_STM32_F4_LP = 0x423, + STLINK_CHIPID_STM32_L0_CAT2 = 0x425, + STLINK_CHIPID_STM32_L1_MEDIUM_PLUS = 0x427, /* assigned to some L1 "Medium-plus" chips */ + STLINK_CHIPID_STM32_F1_VL_HIGH = 0x428, + STLINK_CHIPID_STM32_L1_CAT2 = 0x429, + STLINK_CHIPID_STM32_F1_XL = 0x430, + STLINK_CHIPID_STM32_F411RE = 0x431, + STLINK_CHIPID_STM32_F37x = 0x432, + STLINK_CHIPID_STM32_F4_DE = 0x433, + STLINK_CHIPID_STM32_F4_DSI = 0x434, + STLINK_CHIPID_STM32_L43X = 0x435, /* covers STM32L43xxx and STM32L44xxx devices */ + STLINK_CHIPID_STM32_L496X = 0x461, /* covers STM32L496xx and STM32L4A6xx devices */ + STLINK_CHIPID_STM32_L46X = 0x462, /* covers STM32L45xxx and STM32L46xxx devices */ + STLINK_CHIPID_STM32_L41X = 0x464, /* covers STM32L41xxx and STM32L42xxx devices */ + STLINK_CHIPID_STM32_L1_HIGH = 0x436, /* assigned to some L1 "Medium-Plus" and "High" chips */ + STLINK_CHIPID_STM32_L152_RE = 0x437, + STLINK_CHIPID_STM32_F334 = 0x438, + STLINK_CHIPID_STM32_F3_SMALL = 0x439, + STLINK_CHIPID_STM32_F0 = 0x440, + STLINK_CHIPID_STM32_F412 = 0x441, + STLINK_CHIPID_STM32_F09X = 0x442, + STLINK_CHIPID_STM32_F0_SMALL = 0x444, + STLINK_CHIPID_STM32_F04 = 0x445, + STLINK_CHIPID_STM32_F303_HIGH = 0x446, + STLINK_CHIPID_STM32_L0_CAT5 = 0x447, + STLINK_CHIPID_STM32_F0_CAN = 0x448, + STLINK_CHIPID_STM32_F7 = 0x449, /* ID found on the NucleoF746ZG board */ + STLINK_CHIPID_STM32_F7XXXX = 0x451, + STLINK_CHIPID_STM32_F72XXX = 0x452, /* ID found on the NucleoF722ZE board */ + STLINK_CHIPID_STM32_L011 = 0x457, + STLINK_CHIPID_STM32_F410 = 0x458, + STLINK_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/081 */ + STLINK_CHIPID_STM32_F413 = 0x463, + STLINK_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/041 */ + STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* See: RM 0440 s46.6.1 "MCU device ID code" */ + STLINK_CHIPID_STM32_G4_CAT3 = 0x469, + STLINK_CHIPID_STM32_L4RX = 0x470, /* ID found on the STM32L4R9I-DISCO board */ + STLINK_CHIPID_STM32_WB55 = 0x495 }; -/** - * Chipid parameters - */ +/** Chipid parameters */ struct stlink_chipid_params { - uint32_t chip_id; - char *description; - enum stlink_flash_type flash_type; - bool has_dual_bank; - uint32_t flash_size_reg; - uint32_t flash_pagesize; - uint32_t sram_size; - uint32_t bootrom_base; - uint32_t bootrom_size; - uint32_t option_base; - uint32_t option_size; + uint32_t chip_id; + char *description; + enum stlink_flash_type flash_type; + bool has_dual_bank; + uint32_t flash_size_reg; + uint32_t flash_pagesize; + uint32_t sram_size; + uint32_t bootrom_base; + uint32_t bootrom_size; + uint32_t option_base; + uint32_t option_size; }; const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); @@ -89,4 +87,4 @@ const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); } #endif -#endif /* STLINK_CHIPID_H_ */ +#endif // STLINK_CHIPID_H_ diff --git a/src/commands.h b/src/stlink-lib/commands.h similarity index 97% rename from src/commands.h rename to src/stlink-lib/commands.h index a6830ff26..0925e8e67 100644 --- a/src/commands.h +++ b/src/stlink-lib/commands.h @@ -33,4 +33,4 @@ enum stlink_debug_commands { STLINK_DEBUG_ENTER_SWD = 0xa3 }; -#endif /* STLINK_COMMANDS_H_ */ +#endif // STLINK_COMMANDS_H_ diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index b97a6edaa..71601e3da 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -10,207 +10,203 @@ /* DO NOT MODIFY SOURCECODE DIRECTLY, EDIT ASSEMBLY FILES INSTEAD */ - /* flashloaders/stm32f0.s -- compiled with thumb2 */ - static const uint8_t loader_code_stm32vl[] = { - 0x16, 0x4f, 0x3c, 0x68, - 0x16, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x16, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, - 0x4f, 0xf0, 0x01, 0x07, - 0x33, 0x68, 0x3b, 0x43, - 0x33, 0x60, 0x03, 0x88, - 0x0b, 0x80, 0x4f, 0xf0, - 0x02, 0x07, 0xc0, 0x19, - 0xc9, 0x19, 0x4f, 0xf0, - 0x01, 0x07, 0x2b, 0x68, - 0x3b, 0x42, 0xfa, 0xd0, - 0x4f, 0xf0, 0x04, 0x07, - 0x3b, 0x42, 0x04, 0xd1, - 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xe6, 0xd1, 0x4f, 0xf0, - 0x01, 0x07, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x20, 0x02, 0x40, - 0x10, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x20, - 0x54, 0x00, 0x00, 0x20, - 0x58, 0x00, 0x00, 0x20 - }; - - /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ - static const uint8_t loader_code_stm32f0[] = { - 0xc0, 0x46, 0xc0, 0x46, - 0x13, 0x4f, 0x3c, 0x68, - 0x13, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x13, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, - 0x12, 0x4f, 0x33, 0x68, - 0x3b, 0x43, 0x33, 0x60, - 0x03, 0x88, 0x0b, 0x80, - 0x10, 0x4f, 0xc0, 0x19, - 0xc9, 0x19, 0x0e, 0x4f, - 0x2b, 0x68, 0x3b, 0x42, - 0xfb, 0xd0, 0x0e, 0x4f, - 0x3b, 0x42, 0x03, 0xd1, - 0x0a, 0x4f, 0xd2, 0x1b, - 0x00, 0x2a, 0xeb, 0xd1, - 0x08, 0x4f, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0xc0, 0x46, - 0x00, 0x20, 0x02, 0x40, - 0x10, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x20, - 0x4c, 0x00, 0x00, 0x20, - 0x50, 0x00, 0x00, 0x20, - 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32l[] = { - // flashloaders/stm32lx.s - - 0x03, 0x68, 0x0b, 0x60, - 0x4f, 0xf0, 0x04, 0x07, - 0x38, 0x44, 0x39, 0x44, - 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xf4, 0xd1, 0x00, 0xbe, - }; - - static const uint8_t loader_code_stm32f4[] = { - // flashloaders/stm32f4.s - - 0xdf, 0xf8, 0x28, 0xc0, - 0xdf, 0xf8, 0x28, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, - 0x04, 0x00, 0x01, 0xf1, - 0x04, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32f4_lv[] = { - // flashloaders/stm32f4lv.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, - 0x01, 0x00, 0x01, 0xf1, - 0x01, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32l4[] = { - // flashloaders/stm32l4.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x44, 0x68, 0x0b, 0x60, - 0x4c, 0x60, 0x00, 0xf1, - 0x08, 0x00, 0x01, 0xf1, - 0x08, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x20, 0x02, 0x40, - 0x12, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32f7[] = { - // flashloaders/stm32f7.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, - 0x04, 0x00, 0x01, 0xf1, - 0x04, 0x01, 0xbf, 0xf3, - 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32f7_lv[] = { - // flashloaders/stm32f7lv.s - 0xdf, 0xf8, 0x30, 0xc0, - 0xdf, 0xf8, 0x30, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, - 0x01, 0x00, 0x01, 0xf1, - 0x01, 0x01, 0xbf, 0xf3, - 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 - }; - - - -int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) -{ - size_t size = 0; - - /* allocate the loader in sram */ - if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { - WLOG("Failed to write flash loader to sram!\n"); - return -1; - } - - /* allocate a one page buffer in sram right after loader */ - fl->buf_addr = fl->loader_addr + (uint32_t) size; - ILOG("Successfully loaded flash loader in sram\n"); - - return 0; +/* flashloaders/stm32f0.s -- compiled with thumb2 */ +static const uint8_t loader_code_stm32vl[] = { + 0x16, 0x4f, 0x3c, 0x68, + 0x16, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x16, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x4f, 0xf0, 0x01, 0x07, + 0x33, 0x68, 0x3b, 0x43, + 0x33, 0x60, 0x03, 0x88, + 0x0b, 0x80, 0x4f, 0xf0, + 0x02, 0x07, 0xc0, 0x19, + 0xc9, 0x19, 0x4f, 0xf0, + 0x01, 0x07, 0x2b, 0x68, + 0x3b, 0x42, 0xfa, 0xd0, + 0x4f, 0xf0, 0x04, 0x07, + 0x3b, 0x42, 0x04, 0xd1, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xe6, 0xd1, 0x4f, 0xf0, + 0x01, 0x07, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x20, + 0x54, 0x00, 0x00, 0x20, + 0x58, 0x00, 0x00, 0x20 +}; + +/* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ +static const uint8_t loader_code_stm32f0[] = { + 0xc0, 0x46, 0xc0, 0x46, + 0x13, 0x4f, 0x3c, 0x68, + 0x13, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x13, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x12, 0x4f, 0x33, 0x68, + 0x3b, 0x43, 0x33, 0x60, + 0x03, 0x88, 0x0b, 0x80, + 0x10, 0x4f, 0xc0, 0x19, + 0xc9, 0x19, 0x0e, 0x4f, + 0x2b, 0x68, 0x3b, 0x42, + 0xfb, 0xd0, 0x0e, 0x4f, + 0x3b, 0x42, 0x03, 0xd1, + 0x0a, 0x4f, 0xd2, 0x1b, + 0x00, 0x2a, 0xeb, 0xd1, + 0x08, 0x4f, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0xc0, 0x46, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x20, + 0x4c, 0x00, 0x00, 0x20, + 0x50, 0x00, 0x00, 0x20, + 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32l[] = { + // flashloaders/stm32lx.s + + 0x03, 0x68, 0x0b, 0x60, + 0x4f, 0xf0, 0x04, 0x07, + 0x38, 0x44, 0x39, 0x44, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xf4, 0xd1, 0x00, 0xbe, +}; + +static const uint8_t loader_code_stm32f4[] = { + // flashloaders/stm32f4.s + + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32f4_lv[] = { + // flashloaders/stm32f4lv.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32l4[] = { + // flashloaders/stm32l4.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x44, 0x68, 0x0b, 0x60, + 0x4c, 0x60, 0x00, 0xf1, + 0x08, 0x00, 0x01, 0xf1, + 0x08, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x12, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32f7[] = { + // flashloaders/stm32f7.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32f7_lv[] = { + // flashloaders/stm32f7lv.s + 0xdf, 0xf8, 0x30, 0xc0, + 0xdf, 0xf8, 0x30, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 +}; + + +int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { + size_t size = 0; + + // allocate the loader in SRAM + if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { + WLOG("Failed to write flash loader to sram!\n"); + return(-1); + } + + // allocate a one page buffer in SRAM right after loader + fl->buf_addr = fl->loader_addr + (uint32_t)size; + ILOG("Successfully loaded flash loader in sram\n"); + + return(0); } static int loader_v_dependent_assignment(stlink_t *sl, const uint8_t **loader_code, size_t *loader_size, const uint8_t *high_v_loader, size_t high_v_loader_size, - const uint8_t *low_v_loader, size_t low_v_loader_size) -{ + const uint8_t *low_v_loader, size_t low_v_loader_size) { int retval = 0; - if ( sl->version.stlink_v == 1){ + if ( sl->version.stlink_v == 1) { printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes\n"); *loader_code = high_v_loader; *loader_size = high_v_loader_size; - } - else { + } else { int voltage = stlink_target_voltage(sl); + if (voltage == -1) { retval = -1; printf("Failed to read Target voltage\n"); - } - else { + } else { if (voltage > 2700) { *loader_code = high_v_loader; *loader_size = high_v_loader_size; @@ -220,11 +216,11 @@ static int loader_v_dependent_assignment(stlink_t *sl, } } } - return retval; + + return(retval); } -int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) -{ +int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { const uint8_t* loader_code; size_t loader_size; @@ -236,7 +232,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_L011 || sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { /* stm32l */ + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { // STM32l loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || @@ -249,38 +245,34 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 || - sl->chip_id == STLINK_CHIPID_STM32_F4 || - sl->chip_id == STLINK_CHIPID_STM32_F4_DE || - sl->chip_id == STLINK_CHIPID_STM32_F4_LP || - sl->chip_id == STLINK_CHIPID_STM32_F4_HD || - sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || - sl->chip_id == STLINK_CHIPID_STM32_F410 || - sl->chip_id == STLINK_CHIPID_STM32_F411RE || - sl->chip_id == STLINK_CHIPID_STM32_F412 || - sl->chip_id == STLINK_CHIPID_STM32_F413 || - sl->chip_id == STLINK_CHIPID_STM32_F446 - ) { + sl->chip_id == STLINK_CHIPID_STM32_F4 || + sl->chip_id == STLINK_CHIPID_STM32_F4_DE || + sl->chip_id == STLINK_CHIPID_STM32_F4_LP || + sl->chip_id == STLINK_CHIPID_STM32_F4_HD || + sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || + sl->chip_id == STLINK_CHIPID_STM32_F410 || + sl->chip_id == STLINK_CHIPID_STM32_F411RE || + sl->chip_id == STLINK_CHIPID_STM32_F412 || + sl->chip_id == STLINK_CHIPID_STM32_F413 || + sl->chip_id == STLINK_CHIPID_STM32_F446) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, loader_code_stm32f4, sizeof(loader_code_stm32f4), loader_code_stm32f4_lv, sizeof(loader_code_stm32f4_lv)); - if (retval == -1) { - return retval; - } + + if (retval == -1) { return(retval); } } else if (sl->core_id == STM32F7_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX || - sl->chip_id == STLINK_CHIPID_STM32_F72XXX - ) { + sl->chip_id == STLINK_CHIPID_STM32_F72XXX) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, loader_code_stm32f7, sizeof(loader_code_stm32f7), loader_code_stm32f7_lv, sizeof(loader_code_stm32f7_lv)); - if (retval == -1) { - return retval; - } + + if (retval == -1) { return(retval); } } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || sl->chip_id == STLINK_CHIPID_STM32_F04 || sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || @@ -293,101 +285,102 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* (sl->chip_id == STLINK_CHIPID_STM32_L43X) || (sl->chip_id == STLINK_CHIPID_STM32_L46X) || (sl->chip_id == STLINK_CHIPID_STM32_L4RX) || - (sl->chip_id == STLINK_CHIPID_STM32_L496X)) - { + (sl->chip_id == STLINK_CHIPID_STM32_L496X)) { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); } else { - ELOG("unknown coreid, not sure what flash loader to use, aborting! coreid: %x, chipid: %x\n", sl->core_id, sl->chip_id); - return -1; + ELOG("unknown coreid, not sure what flash loader to use, aborting! coreid: %x, chipid: %x\n", + sl->core_id, sl->chip_id); + return(-1); } memcpy(sl->q_buf, loader_code, loader_size); int ret = stlink_write_mem32(sl, sl->sram_base, loader_size); - if (ret) - return ret; + + if (ret) { return(ret); } *addr = sl->sram_base; *size = loader_size; - /* success */ - return 0; + return(0); // success } -int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) -{ +int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { struct stlink_reg rr; int i = 0; size_t count = 0; uint32_t flash_base = 0; DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); - // FIXME This can never return -1 + + // TODO: This can never return -1 if (write_buffer_to_sram(sl, fl, buf, size) == -1) { // IMPOSSIBLE! ELOG("write_buffer_to_sram() == -1\n"); - return -1; + return(-1); } if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { count = size / sizeof(uint16_t); - if (size % sizeof(uint16_t)) - ++count; + + if (size % sizeof(uint16_t)) { ++count; } } else if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_L0) { count = size / sizeof(uint32_t); - if (size % sizeof(uint32_t)) - ++count; + + if (size % sizeof(uint32_t)) { ++count; } } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { count = size / sizeof(uint64_t); - if (size % sizeof(uint64_t)) - ++count; + + if (size % sizeof(uint64_t)) { ++count; } } if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (target >= FLASH_BANK2_START_ADDR)) { flash_base = FLASH_REGS_BANK2_OFS; } - /* setup core */ - stlink_write_reg(sl, fl->buf_addr, 0); /* source */ - stlink_write_reg(sl, target, 1); /* target */ - stlink_write_reg(sl, (uint32_t) count, 2); /* count */ - stlink_write_reg(sl, flash_base, 3); /* flash register base, only used on VL/F1_XL, but harmless for others */ - stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ + /* Setup core */ + stlink_write_reg(sl, fl->buf_addr, 0); // source + stlink_write_reg(sl, target, 1); // target + stlink_write_reg(sl, (uint32_t)count, 2); // count + stlink_write_reg(sl, flash_base, 3); // flash register base + // only used on VL/F1_XL, but harmless for others + stlink_write_reg(sl, fl->loader_addr, 15); // pc register - /* run loader */ + /* Run loader */ stlink_run(sl); -// This piece of code used to try to spin for .1 second by waiting -// doing 10000 rounds of 10 microseconds. But because this usually runs -// on Unix-like OSes, the 10 microseconds get rounded up to the "tick" -// (actually almost two ticks) of the system. 1 milisecond. Thus, the -// ten thousand attempts, when "something goes wrong" that requires -// the error message "flash loader run error" would wait for something -// like 20 seconds before coming up with the error. -// by increasing the sleep-per-round to the same order-of-magnitude as -// the tick-rounding that the OS uses, the wait until the error message is -// reduced to the same order of magnitude as what was intended. -- REW. +/* This piece of code used to try to spin for .1 second by waiting doing 10000 rounds of 10 µs. + * But because this usually runs on Unix-like OSes, the 10 µs get rounded up to the "tick" + * (actually almost two ticks) of the system. 1 ms. Thus, the ten thousand attempts, when + * "something goes wrong" that requires the error message "flash loader run error" would wait + * for something like 20 seconds before coming up with the error. + * By increasing the sleep-per-round to the same order-of-magnitude as the tick-rounding that + * the OS uses, the wait until the error message is reduced to the same order of magnitude + * as what was intended. -- REW. + */ #define WAIT_ROUNDS 100 - /* wait until done (reaches breakpoint) */ + + // wait until done (reaches breakpoint) for (i = 0; i < WAIT_ROUNDS; i++) { usleep(1000); - if (stlink_is_core_halted(sl)) - break; + + if (stlink_is_core_halted(sl)) { break; } } if (i >= WAIT_ROUNDS) { ELOG("flash loader run error\n"); - return -1; + return(-1); } - /* check written byte count */ + // check written byte count stlink_read_reg(sl, 2, &rr); + if (rr.r[2] != 0) { ELOG("write error, count == %u\n", rr.r[2]); - return -1; + return(-1); } - return 0; + return(0); } diff --git a/src/stlink-lib/flash_loader.h b/src/stlink-lib/flash_loader.h index 5f4526114..29fd5b068 100644 --- a/src/stlink-lib/flash_loader.h +++ b/src/stlink-lib/flash_loader.h @@ -1,8 +1,8 @@ /* - * File: stlink.h + * File: stlink.h * - * This should contain all the common top level stlink interfaces, regardless - * of how the backend does the work.... + * This should contain all the common top level stlink interfaces, + * regardless of how the backend does the work.... */ #ifndef STLINK_FLASH_LOADER_H_ #define STLINK_FLASH_LOADER_H_ @@ -24,4 +24,4 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe } #endif -#endif /* STLINK_FLASH_LOADER_H_ */ +#endif // STLINK_FLASH_LOADER_H_ diff --git a/src/libusb_settings.h b/src/stlink-lib/libusb_settings.h similarity index 53% rename from src/libusb_settings.h rename to src/stlink-lib/libusb_settings.h index c2e2df923..046c0b33d 100644 --- a/src/libusb_settings.h +++ b/src/stlink-lib/libusb_settings.h @@ -5,24 +5,24 @@ /* - libusb ver | LIBUSB_API_VERSION --------------+-------------------- - v1.0.13 | 0x01000100 - v1.0.14 | 0x010000FF - v1.0.15 | 0x01000101 - v1.0.16 | 0x01000102 - v1.0.17 | 0x01000102 - v1.0.18 | 0x01000102 - v1.0.19 | 0x01000103 - v1.0.20 | 0x01000104 - v1.0.21 | 0x01000105 - v1.0.22 | 0x01000106 - v1.0.23 | 0x01000107 - -*/ + libusb ver | LIBUSB_API_VERSION + -----------+-------------------- + v1.0.13 | 0x01000100 + v1.0.14 | 0x010000FF + v1.0.15 | 0x01000101 + v1.0.16 | 0x01000102 + v1.0.17 | 0x01000102 + v1.0.18 | 0x01000102 + v1.0.19 | 0x01000103 + v1.0.20 | 0x01000104 + v1.0.21 | 0x01000105 + v1.0.22 | 0x01000106 + v1.0.23 | 0x01000107 + + */ #if defined (__FreeBSD__) - #if !defined ( LIBUSBX_API_VERSION ) + #if !defined (LIBUSBX_API_VERSION) #define LIBUSBX_API_VERSION LIBUSB_API_VERSION #elif !defined (LIBUSB_API_VERSION) #error unsupported libusb version @@ -39,8 +39,8 @@ #define MINIMAL_API_VERSION 0x01000104 // v1.0.20 #endif -#if ( LIBUSB_API_VERSION < MINIMAL_API_VERSION ) +#if (LIBUSB_API_VERSION < MINIMAL_API_VERSION) #error unsupported libusb version #endif -#endif // STLINKUSB_H +#endif // LIBUSB_SETTINGS_H diff --git a/src/stlink-lib/logging.c b/src/stlink-lib/logging.c index ad144f6a4..a5eef9e17 100644 --- a/src/stlink-lib/logging.c +++ b/src/stlink-lib/logging.c @@ -1,7 +1,7 @@ /* - * UglyLogging. Slow, yet another wheel reinvented, but enough to make the - * rest of our code pretty enough. + * UglyLogging * + * Slow, yet another wheel reinvented, but enough to make the rest of our code pretty enough. */ #include #include @@ -15,23 +15,24 @@ static int max_level = UDEBUG; int ugly_init(int maximum_threshold) { max_level = maximum_threshold; - return 0; + return(0); } int ugly_log(int level, const char *tag, const char *format, ...) { if (level > max_level) { - return 0; + return(0); } - // Flush to maintain order of streams - fflush(stdout); + fflush(stdout); // flush to maintain order of streams va_list args; va_start(args, format); time_t mytt = time(NULL); struct tm *tt; tt = localtime(&mytt); - fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", tt->tm_year + 1900, tt->tm_mon + 1, tt->tm_mday, tt->tm_hour, tt->tm_min, tt->tm_sec); + fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", tt->tm_year + 1900, tt->tm_mon + 1, + tt->tm_mday, tt->tm_hour, tt->tm_min, tt->tm_sec); + switch (level) { case UDEBUG: fprintf(stderr, "DEBUG %s: ", tag); @@ -49,13 +50,13 @@ int ugly_log(int level, const char *tag, const char *format, ...) { fprintf(stderr, "%d %s: ", level, tag); break; } + vfprintf(stderr, format, args); fflush(stderr); va_end(args); - return 1; + return(1); } - /* * Log message levels. * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default) @@ -63,15 +64,14 @@ int ugly_log(int level, const char *tag, const char *format, ...) { * - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to stderr * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to stderr * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stderr -*/ -int ugly_libusb_log_level(enum ugly_loglevel v) -{ + */ +int ugly_libusb_log_level(enum ugly_loglevel v) { switch (v) { - case UDEBUG: return 4; - case UINFO: return 3; - case UWARN: return 2; - case UERROR: return 1; - }; + case UDEBUG: return(4); + case UINFO: return(3); + case UWARN: return(2); + case UERROR: return(1); + } - return 2; + return(2); } diff --git a/src/stlink-lib/logging.h b/src/stlink-lib/logging.h index 1083b2c55..78562b0d9 100644 --- a/src/stlink-lib/logging.h +++ b/src/stlink-lib/logging.h @@ -3,9 +3,9 @@ */ #ifndef UGLYLOGGING_H -#define UGLYLOGGING_H +#define UGLYLOGGING_H -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -21,11 +21,11 @@ int ugly_log(int level, const char *tag, const char *format, ...); int ugly_libusb_log_level(enum ugly_loglevel v); #define UGLY_LOG_FILE (strstr(__FILE__, "/") != NULL ? \ - strrchr(__FILE__, '/') + 1 : strstr(__FILE__, "\\") != NULL ? \ - strrchr(__FILE__, '\\') + 1 : __FILE__) + strrchr(__FILE__, '/') + 1 : strstr(__FILE__, "\\") != NULL ? \ + strrchr(__FILE__, '\\') + 1 : __FILE__) -/** @todo we need to write this in a more generic way, for now this should compile - on visual studio (See http://stackoverflow.com/a/8673872/1836746) */ +// TODO: we need to write this in a more generic way, for now this should compile +// on visual studio (See http://stackoverflow.com/a/8673872/1836746) #define DLOG_HELPER(format, ...) ugly_log(UDEBUG, UGLY_LOG_FILE, format, __VA_ARGS__) #define DLOG(...) DLOG_HELPER(__VA_ARGS__, "") #define ILOG_HELPER(format, ...) ugly_log(UINFO, UGLY_LOG_FILE, format, __VA_ARGS__) @@ -35,9 +35,8 @@ int ugly_libusb_log_level(enum ugly_loglevel v); #define ELOG_HELPER(format, ...) ugly_log(UERROR, UGLY_LOG_FILE, format, __VA_ARGS__) #define ELOG(...) ELOG_HELPER(__VA_ARGS__, "") -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* UGLYLOGGING_H */ - +#endif // UGLYLOGGING_H diff --git a/src/stlink-lib/md5.c b/src/stlink-lib/md5.c index 521c52969..4c353bfd6 100755 --- a/src/stlink-lib/md5.c +++ b/src/stlink-lib/md5.c @@ -1,80 +1,53 @@ /* - * Retrieved from https://github.com/WaterJuice/WjCryptLib + * WjCryptLib_Md5 (https://github.com/WaterJuice/WjCryptLib) + * Implementation of MD5 hash function. Originally written by Alexander Peslyak. + * Modified by WaterJuice retaining Public Domain license. + * This is free and unencumbered software released into the public domain - June 2013 - waterjuice.org */ -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// WjCryptLib_Md5 -// -// Implementation of MD5 hash function. Originally written by Alexander Peslyak. Modified by WaterJuice retaining -// Public Domain license. -// -// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// IMPORTS -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #include #include "md5.h" -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// INTERNAL FUNCTIONS -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// F, G, H, I -// -// The basic MD5 functions. F and G are optimised compared to their RFC 1321 definitions for architectures that lack -// an AND-NOT instruction, just like in Colin Plumb's implementation. -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#define F( x, y, z ) ( (z) ^ ((x) & ((y) ^ (z))) ) -#define G( x, y, z ) ( (y) ^ ((z) & ((x) ^ (y))) ) -#define H( x, y, z ) ( (x) ^ (y) ^ (z) ) -#define I( x, y, z ) ( (y) ^ ((x) | ~(z)) ) - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// STEP -// -// The MD5 transformation for all four rounds. -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* INTERNAL FUNCTIONS */ + +/* F, G, H, I + * + * The basic MD5 functions. + * F and G are optimised compared to their RFC 1321 definitions for architectures + * that lack an AND-NOT instruction, just like in Colin Plumb's implementation. + */ +#define F( x, y, z ) ((z) ^ ((x) & ((y) ^ (z)))) +#define G( x, y, z ) ((y) ^ ((z) & ((x) ^ (y)))) +#define H( x, y, z ) ((x) ^ (y) ^ (z)) +#define I( x, y, z ) ((y) ^ ((x) | ~(z))) + +/* STEP: The MD5 transformation for all four rounds. */ #define STEP( f, a, b, c, d, x, t, s ) \ (a) += f((b), (c), (d)) + (x) + (t); \ (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ (a) += (b); -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// TransformFunction -// -// This processes one or more 64-byte data blocks, but does NOT update the bit counters. There are no alignment -// requirements. -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static -void* - TransformFunction - ( - Md5Context* ctx, - void const* data, - uintmax_t size - ) -{ +/* TransformFunction + * This processes one or more 64-byte data blocks, but does NOT update the bit counters. + * There are no alignment requirements. + */ +static void* TransformFunction(Md5Context* ctx, void const* data, uintmax_t size) { uint8_t* ptr; - uint32_t a; - uint32_t b; - uint32_t c; - uint32_t d; - uint32_t saved_a; - uint32_t saved_b; - uint32_t saved_c; - uint32_t saved_d; + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; + uint32_t saved_a; + uint32_t saved_b; + uint32_t saved_c; + uint32_t saved_d; #define GET(n) (ctx->block[(n)]) - #define SET(n) (ctx->block[(n)] = \ - ((uint32_t)ptr[(n)*4 + 0] << 0) \ - | ((uint32_t)ptr[(n)*4 + 1] << 8 ) \ - | ((uint32_t)ptr[(n)*4 + 2] << 16) \ - | ((uint32_t)ptr[(n)*4 + 3] << 24) ) + #define SET(n) (ctx->block[(n)] = ((uint32_t)ptr[(n) * 4 + 0] << 0) | \ + ((uint32_t)ptr[(n) * 4 + 1] << 8) | \ + ((uint32_t)ptr[(n) * 4 + 2] << 16) | \ + ((uint32_t)ptr[(n) * 4 + 3] << 24)) ptr = (uint8_t*)data; @@ -83,8 +56,7 @@ void* c = ctx->c; d = ctx->d; - do - { + do { saved_a = a; saved_b = b; saved_c = c; @@ -178,24 +150,16 @@ void* #undef GET #undef SET - return ptr; + return(ptr); } -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// EXPORTED FUNCTIONS -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Md5Initialise -// -// Initialises an MD5 Context. Use this to initialise/reset a context. -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void - Md5Initialise - ( - Md5Context* Context // [out] - ) -{ +/* EXPORTED FUNCTIONS */ + +/* Md5Initialise + * Initialises an MD5 Context. + * Use this to initialise/reset a context. + */ +void Md5Initialise(Md5Context* Context /* [out] */) { Context->a = 0x67452301; Context->b = 0xefcdab89; Context->c = 0x98badcfe; @@ -205,39 +169,31 @@ void Context->hi = 0; } -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Md5Update -// -// Adds data to the MD5 context. This will process the data and update the internal state of the context. Keep on -// calling this function until all the data has been added. Then call Md5Finalise to calculate the hash. -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void - Md5Update - ( - Md5Context* Context, // [in out] - void const* Buffer, // [in] - uint32_t BufferSize // [in] - ) -{ - uint32_t saved_lo; - uint32_t used; - uint32_t free; +/* Md5Update + * Adds data to the MD5 context. + * This will process the data and update the internal state of the context. + * Keep on calling this function until all the data has been added. + * Then call Md5Finalise to calculate the hash. + */ +void Md5Update(Md5Context* Context /* [in out] */, void const* Buffer /* [in] */, uint32_t BufferSize /* [in] */) { + uint32_t saved_lo; + uint32_t used; + uint32_t free; saved_lo = Context->lo; - if ( (Context->lo = (saved_lo + BufferSize) & 0x1fffffff) < saved_lo ) - { + + if ((Context->lo = (saved_lo + BufferSize) & 0x1fffffff) < saved_lo) { Context->hi++; } - Context->hi += (uint32_t)( BufferSize >> 29 ); + + Context->hi += (uint32_t)(BufferSize >> 29); used = saved_lo & 0x3f; - if ( used ) - { + if ( used ) { free = 64 - used; - if ( BufferSize < free ) - { + if ( BufferSize < free ) { memcpy( &Context->buffer[used], Buffer, BufferSize ); return; } @@ -248,8 +204,7 @@ void TransformFunction(Context, Context->buffer, 64); } - if ( BufferSize >= 64 ) - { + if ( BufferSize >= 64 ) { Buffer = TransformFunction( Context, Buffer, BufferSize & ~(unsigned long)0x3f ); BufferSize &= 0x3f; } @@ -257,21 +212,14 @@ void memcpy( Context->buffer, Buffer, BufferSize ); } -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Md5Finalise -// -// Performs the final calculation of the hash and returns the digest (16 byte buffer containing 128bit hash). After -// calling this, Md5Initialised must be used to reuse the context. -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void - Md5Finalise - ( - Md5Context* Context, // [in out] - MD5_HASH* Digest // [in] - ) -{ - uint32_t used; - uint32_t free; +/* Md5Finalise + * Performs the final calculation of the hash and returns the digest + * (16 byte buffer containing 128bit hash). + * After calling this, Md5Initialised must be used to reuse the context. + */ +void Md5Finalise(Md5Context* Context /* [in out] */, MD5_HASH* Digest /* [in] */) { + uint32_t used; + uint32_t free; used = Context->lo & 0x3f; @@ -279,8 +227,7 @@ void free = 64 - used; - if (free < 8) - { + if (free < 8) { memset( &Context->buffer[used], 0, free ); TransformFunction( Context, Context->buffer, 64 ); used = 0; @@ -290,48 +237,40 @@ void memset( &Context->buffer[used], 0, free - 8 ); Context->lo <<= 3; - Context->buffer[56] = (uint8_t)( Context->lo ); - Context->buffer[57] = (uint8_t)( Context->lo >> 8 ); - Context->buffer[58] = (uint8_t)( Context->lo >> 16 ); - Context->buffer[59] = (uint8_t)( Context->lo >> 24 ); - Context->buffer[60] = (uint8_t)( Context->hi ); - Context->buffer[61] = (uint8_t)( Context->hi >> 8 ); - Context->buffer[62] = (uint8_t)( Context->hi >> 16 ); - Context->buffer[63] = (uint8_t)( Context->hi >> 24 ); + Context->buffer[56] = (uint8_t)(Context->lo); + Context->buffer[57] = (uint8_t)(Context->lo >> 8); + Context->buffer[58] = (uint8_t)(Context->lo >> 16); + Context->buffer[59] = (uint8_t)(Context->lo >> 24); + Context->buffer[60] = (uint8_t)(Context->hi); + Context->buffer[61] = (uint8_t)(Context->hi >> 8); + Context->buffer[62] = (uint8_t)(Context->hi >> 16); + Context->buffer[63] = (uint8_t)(Context->hi >> 24); TransformFunction( Context, Context->buffer, 64 ); - Digest->bytes[0] = (uint8_t)( Context->a ); - Digest->bytes[1] = (uint8_t)( Context->a >> 8 ); - Digest->bytes[2] = (uint8_t)( Context->a >> 16 ); - Digest->bytes[3] = (uint8_t)( Context->a >> 24 ); - Digest->bytes[4] = (uint8_t)( Context->b ); - Digest->bytes[5] = (uint8_t)( Context->b >> 8 ); - Digest->bytes[6] = (uint8_t)( Context->b >> 16 ); - Digest->bytes[7] = (uint8_t)( Context->b >> 24 ); - Digest->bytes[8] = (uint8_t)( Context->c ); - Digest->bytes[9] = (uint8_t)( Context->c >> 8 ); - Digest->bytes[10] = (uint8_t)( Context->c >> 16 ); - Digest->bytes[11] = (uint8_t)( Context->c >> 24 ); - Digest->bytes[12] = (uint8_t)( Context->d ); - Digest->bytes[13] = (uint8_t)( Context->d >> 8 ); - Digest->bytes[14] = (uint8_t)( Context->d >> 16 ); - Digest->bytes[15] = (uint8_t)( Context->d >> 24 ); + Digest->bytes[0] = (uint8_t)(Context->a); + Digest->bytes[1] = (uint8_t)(Context->a >> 8); + Digest->bytes[2] = (uint8_t)(Context->a >> 16); + Digest->bytes[3] = (uint8_t)(Context->a >> 24); + Digest->bytes[4] = (uint8_t)(Context->b); + Digest->bytes[5] = (uint8_t)(Context->b >> 8); + Digest->bytes[6] = (uint8_t)(Context->b >> 16); + Digest->bytes[7] = (uint8_t)(Context->b >> 24); + Digest->bytes[8] = (uint8_t)(Context->c); + Digest->bytes[9] = (uint8_t)(Context->c >> 8); + Digest->bytes[10] = (uint8_t)(Context->c >> 16); + Digest->bytes[11] = (uint8_t)(Context->c >> 24); + Digest->bytes[12] = (uint8_t)(Context->d); + Digest->bytes[13] = (uint8_t)(Context->d >> 8); + Digest->bytes[14] = (uint8_t)(Context->d >> 16); + Digest->bytes[15] = (uint8_t)(Context->d >> 24); } -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Md5Calculate -// -// Combines Md5Initialise, Md5Update, and Md5Finalise into one function. Calculates the MD5 hash of the buffer. -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void - Md5Calculate - ( - void const* Buffer, // [in] - uint32_t BufferSize, // [in] - MD5_HASH* Digest // [in] - ) -{ +/* Md5Calculate + * Combines Md5Initialise, Md5Update, and Md5Finalise into one function. + * Calculates the MD5 hash of the buffer. + */ +void Md5Calculate(void const* Buffer /* [in] */, uint32_t BufferSize /* [in] */, MD5_HASH* Digest /* [in] */) { Md5Context context; Md5Initialise( &context ); diff --git a/src/stlink-lib/md5.h b/src/stlink-lib/md5.h index 5ef252221..a69d7fc6b 100755 --- a/src/stlink-lib/md5.h +++ b/src/stlink-lib/md5.h @@ -1,100 +1,63 @@ /* - * Retrieved from https://github.com/WaterJuice/WjCryptLib + * WjCryptLib_Md5 (https://github.com/WaterJuice/WjCryptLib) + * Implementation of MD5 hash function. Originally written by Alexander Peslyak. + * Modified by WaterJuice retaining Public Domain license. + * This is free and unencumbered software released into the public domain - June 2013 - waterjuice.org */ -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// WjCryptLib_Md5 -// -// Implementation of MD5 hash function. Originally written by Alexander Peslyak. Modified by WaterJuice retaining -// Public Domain license. -// -// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #pragma once -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// IMPORTS -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #include #include -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// TYPES -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* TYPES */ -// Md5Context - This must be initialised using Md5Initialised. Do not modify the contents of this structure directly. -typedef struct -{ - uint32_t lo; - uint32_t hi; - uint32_t a; - uint32_t b; - uint32_t c; - uint32_t d; - uint8_t buffer[64]; - uint32_t block[16]; +/* Md5Context + * This must be initialised using Md5Initialised. + * Do not modify the contents of this structure directly. + */ +typedef struct { + uint32_t lo; + uint32_t hi; + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; + uint8_t buffer[64]; + uint32_t block[16]; } Md5Context; -#define MD5_HASH_SIZE ( 128 / 8 ) +#define MD5_HASH_SIZE (128 / 8) -typedef struct -{ - uint8_t bytes [MD5_HASH_SIZE]; +typedef struct { + uint8_t bytes [MD5_HASH_SIZE]; } MD5_HASH; -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// PUBLIC FUNCTIONS -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* PUBLIC FUNCTIONS */ -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Md5Initialise -// -// Initialises an MD5 Context. Use this to initialise/reset a context. -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void - Md5Initialise - ( - Md5Context* Context // [out] - ); +/* Md5Initialise + * Initialises an MD5 Context. + * Use this to initialise/reset a context. + */ +void Md5Initialise(Md5Context* Context /* [out] */); -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Md5Update -// -// Adds data to the MD5 context. This will process the data and update the internal state of the context. Keep on -// calling this function until all the data has been added. Then call Md5Finalise to calculate the hash. -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void - Md5Update - ( - Md5Context* Context, // [in out] - void const* Buffer, // [in] - uint32_t BufferSize // [in] - ); +/* Md5Update + * Adds data to the MD5 context. + * This will process the data and update the internal state of the context. + * Keep on calling this function until all the data has been added. + * Then call Md5Finalise to calculate the hash. + */ +void Md5Update(Md5Context* Context /* [in out] */, void const* Buffer /* [in] */, uint32_t BufferSize /* [in] */); -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Md5Finalise -// -// Performs the final calculation of the hash and returns the digest (16 byte buffer containing 128bit hash). After -// calling this, Md5Initialised must be used to reuse the context. -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void - Md5Finalise - ( - Md5Context* Context, // [in out] - MD5_HASH* Digest // [in] - ); +/* Md5Finalise + * Performs the final calculation of the hash and returns the digest + * (16 byte buffer containing 128bit hash). + * After calling this, Md5Initialised must be used to reuse the context. + */ +void Md5Finalise(Md5Context* Context /* [in out] */, MD5_HASH* Digest /* [in] */); -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Md5Calculate -// -// Combines Md5Initialise, Md5Update, and Md5Finalise into one function. Calculates the MD5 hash of the buffer. -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void - Md5Calculate - ( - void const* Buffer, // [in] - uint32_t BufferSize, // [in] - MD5_HASH* Digest // [in] - ); +/* Md5Calculate + * Combines Md5Initialise, Md5Update, and Md5Finalise into one function. + * Calculates the MD5 hash of the buffer. + */ +void Md5Calculate(void const* Buffer /* [in] */, uint32_t BufferSize /* [in] */, MD5_HASH* Digest /* [in] */); diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h new file mode 100644 index 000000000..dde77ef50 --- /dev/null +++ b/src/stlink-lib/reg.h @@ -0,0 +1,20 @@ +#ifndef STLINK_REG_H_ +#define STLINK_REG_H_ + +#define STLINK_REG_CM3_CPUID 0xE000ED00 +#define STLINK_REG_CM3_FP_CTRL 0xE0002000 +#define STLINK_REG_CM3_FP_COMP0 0xE0002008 + +/* Cortex™-M3 Technical Reference Manual */ +/* Debug Halting Control and Status Register */ +#define STLINK_REG_DHCSR 0xe000edf0 +#define STLINK_REG_DHCSR_DBGKEY 0xa05f0000 +#define STLINK_REG_DCRSR 0xe000edf4 +#define STLINK_REG_DCRDR 0xe000edf8 + +/* Application Interrupt and Reset Control Register */ +#define STLINK_REG_AIRCR 0xe000ed0c +#define STLINK_REG_AIRCR_VECTKEY 0x05fa0000 +#define STLINK_REG_AIRCR_SYSRESETREQ 0x00000004 + +#endif // STLINK_REG_H_ diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index 7fae19976..5cc27b1fe 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -27,7 +27,7 @@ * www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf * * dt - Data Transfer (IN/OUT) - * CBW - Command Block Wrapper + * CBW - Command Block Wrapper * CSW - Command Status Wrapper * RFU - Reserved for Future Use * @@ -90,8 +90,8 @@ #define STLINK_FALSE 0x81 static void clear_cdb(struct stlink_libsg *sl) { - for (size_t i = 0; i < sizeof (sl->cdb_cmd_blk); i++) - sl->cdb_cmd_blk[i] = 0; + for (size_t i = 0; i < sizeof(sl->cdb_cmd_blk); i++) { sl->cdb_cmd_blk[i] = 0; } + // set default sl->cdb_cmd_blk[0] = STLINK_DEBUG_COMMAND; sl->q_data_dir = Q_DATA_IN; @@ -116,46 +116,53 @@ static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t end int transferred; int ret; int try = 0; + do { ret = libusb_bulk_transfer(handle, endpoint, (unsigned char *)&csw, sizeof(csw), - &transferred, SG_TIMEOUT_MSEC); - if (ret == LIBUSB_ERROR_PIPE) { - libusb_clear_halt(handle, endpoint); - } + &transferred, SG_TIMEOUT_MSEC); + + if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint); } + try++; } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); + if (ret != LIBUSB_SUCCESS) { WLOG("%s: receiving failed: %d\n", __func__, ret); - return -1; + return(-1); } + if (transferred != sizeof(csw)) { WLOG("%s: received unexpected amount: %d\n", __func__, transferred); - return -1; + return(-1); } uint32_t rsig = read_uint32(csw, 0); uint32_t rtag = read_uint32(csw, 4); /* uint32_t residue = read_uint32(csw, 8); */ #define USB_CSW_SIGNATURE 0x53425355 // 'U' 'S' 'B' 'S' (reversed) + if (rsig != USB_CSW_SIGNATURE) { WLOG("status signature was invalid: %#x\n", rsig); - return -1; + return(-1); } + *tag = rtag; uint8_t rstatus = csw[12]; - return rstatus; + return(rstatus); } static int dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) { char dbugblah[100]; char *dbugp = dbugblah; dbugp += sprintf(dbugp, "Sending CDB ["); + for (uint8_t i = 0; i < cdb_len; i++) { - dbugp += sprintf(dbugp, " %#02x", (unsigned int) cdb[i]); + dbugp += sprintf(dbugp, " %#02x", (unsigned int)cdb[i]); } + sprintf(dbugp, "]\n"); DLOG(dbugblah); - return 0; + return(0); } /** @@ -170,15 +177,14 @@ static int dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) { * @return */ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint_out, - uint8_t *cdb, uint8_t cdb_length, - uint8_t lun, uint8_t flags, uint32_t expected_rx_size) { + uint8_t *cdb, uint8_t cdb_length, + uint8_t lun, uint8_t flags, uint32_t expected_rx_size) { DLOG("Sending usb m-s cmd: cdblen:%d, rxsize=%d\n", cdb_length, expected_rx_size); dump_CDB_command(cdb, cdb_length); static uint32_t tag; - if (tag == 0) { - tag = 1; - } + + if (tag == 0) { tag = 1; } int try = 0; int ret = 0; @@ -193,14 +199,14 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint c_buf[i++] = 'C'; write_uint32(&c_buf[i], tag); uint32_t this_tag = tag++; - write_uint32(&c_buf[i+4], expected_rx_size); - i+= 8; + write_uint32(&c_buf[i + 4], expected_rx_size); + i += 8; c_buf[i++] = flags; c_buf[i++] = lun; c_buf[i++] = cdb_length; - // Now the actual CDB request + // now the actual CDB request assert(cdb_length <= CDB_SL); memcpy(&(c_buf[i]), cdb, cdb_length); @@ -209,19 +215,22 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint // send.... do { ret = libusb_bulk_transfer(handle, endpoint_out, c_buf, sending_length, - &real_transferred, SG_TIMEOUT_MSEC); + &real_transferred, SG_TIMEOUT_MSEC); + if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint_out); } + try++; } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); + if (ret != LIBUSB_SUCCESS) { WLOG("sending failed: %d\n", ret); - return -1; + return(-1); } - return this_tag; -} + return(this_tag); +} /** * Straight from stm8 stlink code... @@ -238,36 +247,44 @@ static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t cdb[0] = REQUEST_SENSE; cdb[4] = REQUEST_SENSE_LENGTH; uint32_t tag = send_usb_mass_storage_command(handle, endpoint_out, cdb, sizeof(cdb), 0, - LIBUSB_ENDPOINT_IN, REQUEST_SENSE_LENGTH); + LIBUSB_ENDPOINT_IN, REQUEST_SENSE_LENGTH); + if (tag == 0) { WLOG("refusing to send request sense with tag 0\n"); return; } + unsigned char sense[REQUEST_SENSE_LENGTH]; int transferred; int ret; int try = 0; + do { ret = libusb_bulk_transfer(handle, endpoint_in, sense, sizeof(sense), - &transferred, SG_TIMEOUT_MSEC); - if (ret == LIBUSB_ERROR_PIPE) { - libusb_clear_halt(handle, endpoint_in); - } + &transferred, SG_TIMEOUT_MSEC); + + if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint_in); } + try++; } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); + if (ret != LIBUSB_SUCCESS) { WLOG("receiving sense failed: %d\n", ret); return; } + if (transferred != sizeof(sense)) { WLOG("received unexpected amount of sense: %d != %d\n", transferred, sizeof(sense)); } + uint32_t received_tag; int status = get_usb_mass_storage_status(handle, endpoint_in, &received_tag); + if (status != 0) { WLOG("receiving sense failed with status: %02x\n", status); return; } + if (sense[0] != 0x70 && sense[0] != 0x71) { WLOG("No sense data\n"); } else { @@ -286,49 +303,55 @@ static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t * @return number of bytes actually sent, or -1 for failures. */ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, - unsigned char endpoint_in, unsigned char *cbuf, unsigned int length) { + unsigned char endpoint_in, unsigned char *cbuf, unsigned int length) { int ret; int real_transferred; int try = 0; + do { ret = libusb_bulk_transfer(handle, endpoint_out, cbuf, length, - &real_transferred, SG_TIMEOUT_MSEC); - if (ret == LIBUSB_ERROR_PIPE) { - libusb_clear_halt(handle, endpoint_out); - } + &real_transferred, SG_TIMEOUT_MSEC); + + if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint_out); } + try++; } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); + if (ret != LIBUSB_SUCCESS) { WLOG("sending failed: %d\n", ret); - return -1; + return(-1); } // now, swallow up the status, so that things behave nicely... uint32_t received_tag; // -ve is for my errors, 0 is good, +ve is libusb sense status bytes int status = get_usb_mass_storage_status(handle, endpoint_in, &received_tag); + if (status < 0) { WLOG("receiving status failed: %d\n", status); - return -1; + return(-1); } + if (status != 0) { WLOG("receiving status not passed :(: %02x\n", status); } + if (status == 1) { get_sense(handle, endpoint_in, endpoint_out); - return -1; + return(-1); } - return real_transferred; + return(real_transferred); } int stlink_q(stlink_t *sl) { struct stlink_libsg* sg = sl->backend_data; - //uint8_t cdb_len = 6; // FIXME varies!!! + // uint8_t cdb_len = 6; // FIXME varies!!! uint8_t cdb_len = 10; // FIXME varies!!! uint8_t lun = 0; // always zero... uint32_t tag = send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, - sg->cdb_cmd_blk, cdb_len, lun, LIBUSB_ENDPOINT_IN, sl->q_len); + sg->cdb_cmd_blk, cdb_len, lun, + LIBUSB_ENDPOINT_IN, sl->q_len); // now wait for our response... @@ -337,19 +360,20 @@ int stlink_q(stlink_t *sl) { int try = 0; int real_transferred; int ret; + if (rx_length > 0) { do { ret = libusb_bulk_transfer(sg->usb_handle, sg->ep_rep, sl->q_buf, rx_length, - &real_transferred, SG_TIMEOUT_MSEC); - if (ret == LIBUSB_ERROR_PIPE) { - libusb_clear_halt(sg->usb_handle, sg->ep_req); - } + &real_transferred, SG_TIMEOUT_MSEC); + + if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(sg->usb_handle, sg->ep_req); } + try++; } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); if (ret != LIBUSB_SUCCESS) { WLOG("Receiving failed: %d\n", ret); - return -1; + return(-1); } if (real_transferred != rx_length) { @@ -360,31 +384,36 @@ int stlink_q(stlink_t *sl) { uint32_t received_tag; // -ve is for my errors, 0 is good, +ve is libusb sense status bytes int status = get_usb_mass_storage_status(sg->usb_handle, sg->ep_rep, &received_tag); + if (status < 0) { WLOG("receiving status failed: %d\n", status); - return -1; + return(-1); } + if (status != 0) { WLOG("receiving status not passed :(: %02x\n", status); } + if (status == 1) { get_sense(sg->usb_handle, sg->ep_rep, sg->ep_req); - return -1; + return(-1); } + if (received_tag != tag) { WLOG("received tag %d but expected %d\n", received_tag, tag); - //return -1; + // return -1; } + if (rx_length > 0 && real_transferred != rx_length) { - return -1; + return(-1); } - return 0; + + return(0); } -// TODO thinking, cleanup +// TODO: thinking, cleanup void stlink_stat(stlink_t *stl, char *txt) { - if (stl->q_len <= 0) - return; + if (stl->q_len <= 0) { return; } stlink_print_data(stl); @@ -406,7 +435,7 @@ int _stlink_sg_version(stlink_t *stl) { sl->cdb_cmd_blk[0] = STLINK_GET_VERSION; stl->q_len = 6; sl->q_addr = 0; - return stlink_q(stl); + return(stlink_q(stl)); } // Get stlink mode: @@ -418,23 +447,23 @@ int _stlink_sg_current_mode(stlink_t *stl) { sl->cdb_cmd_blk[0] = STLINK_GET_CURRENT_MODE; stl->q_len = 2; sl->q_addr = 0; - if (stlink_q(stl)) - return -1; - return stl->q_buf[0]; + if (stlink_q(stl)) { return(-1); } + + return(stl->q_buf[0]); } -// Exit the mass mode and enter the swd debug mode. +// exit the mass mode and enter the swd debug mode. int _stlink_sg_enter_swd_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_SWD; sl->q_len = 0; // >0 -> aboard - return stlink_q(sl); + return(stlink_q(sl)); } -// Exit the mass mode and enter the jtag debug mode. +// exit the mass mode and enter the jtag debug mode. // (jtag is disabled in the discovery's stlink firmware) int _stlink_sg_enter_jtag_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; @@ -443,7 +472,7 @@ int _stlink_sg_enter_jtag_mode(stlink_t *sl) { sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_JTAG; sl->q_len = 0; - return stlink_q(sl); + return(stlink_q(sl)); } // XXX kernel driver performs reset, the device temporally disappears @@ -455,7 +484,7 @@ int _stlink_sg_exit_dfu_mode(stlink_t *sl) { sg->cdb_cmd_blk[0] = STLINK_DFU_COMMAND; sg->cdb_cmd_blk[1] = STLINK_DFU_EXIT; sl->q_len = 0; // ?? - return stlink_q(sl); + return(stlink_q(sl)); /* [135121.844564] sd 19:0:0:0: [sdb] Unhandled error code [135121.844569] sd 19:0:0:0: [sdb] Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK @@ -498,7 +527,7 @@ int _stlink_sg_exit_dfu_mode(stlink_t *sl) { [135131.678551] end_request: I/O error, dev sdb, sector 63872 ... [135131.853565] end_request: I/O error, dev sdb, sector 4096 - */ + */ } int _stlink_sg_core_id(stlink_t *sl) { @@ -509,73 +538,75 @@ int _stlink_sg_core_id(stlink_t *sl) { sl->q_len = 4; sg->q_addr = 0; ret = stlink_q(sl); - if (ret) - return ret; + + if (ret) { return(ret); } sl->core_id = read_uint32(sl->q_buf, 0); - return 0; + return(0); } -// Arm-core reset -> halted state. +// arm-core reset -> halted state. int _stlink_sg_reset(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_RESETSYS; sl->q_len = 2; sg->q_addr = 0; - if (stlink_q(sl)) - return -1; + + if (stlink_q(sl)) { return(-1); } // Reset through AIRCR so NRST does not need to be connected if (stlink_write_debug32(sl, STLINK_REG_AIRCR, - STLINK_REG_AIRCR_VECTKEY | STLINK_REG_AIRCR_SYSRESETREQ)) - return -1; + STLINK_REG_AIRCR_VECTKEY | \ + STLINK_REG_AIRCR_SYSRESETREQ)) { + return(-1); + } stlink_stat(sl, "core reset"); - return 0; + return(0); } -// Arm-core reset -> halted state. +// arm-core reset -> halted state. int _stlink_sg_jtag_reset(stlink_t *sl, int value) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_JTAG_DRIVE_NRST; - sg->cdb_cmd_blk[2] = (value)?0:1; + sg->cdb_cmd_blk[2] = (value) ? 0 : 1; sl->q_len = 3; sg->q_addr = 2; - if (stlink_q(sl)) - return -1; + + if (stlink_q(sl)) { return(-1); } stlink_stat(sl, "core reset"); - return 0; + return(0); } -// Arm-core status: halted or running. +// arm-core status: halted or running. int _stlink_sg_status(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_GETSTATUS; sl->q_len = 2; sg->q_addr = 0; - return stlink_q(sl); + return(stlink_q(sl)); } -// Force the core into the debug mode -> halted state. +// force the core into the debug mode -> halted state. int _stlink_sg_force_debug(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_FORCEDEBUG; sl->q_len = 2; sg->q_addr = 0; - if (stlink_q(sl)) - return -1; + + if (stlink_q(sl)) { return(-1); } stlink_stat(sl, "force debug"); - return 0; + return(0); } -// Read all arm-core registers. +// read all arm-core registers. int _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { struct stlink_libsg *sg = sl->backend_data; @@ -583,27 +614,28 @@ int _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_READALLREGS; sl->q_len = 84; sg->q_addr = 0; - if (stlink_q(sl)) - return -1; + + if (stlink_q(sl)) { return(-1); } stlink_print_data(sl); - // TODO - most of this should be re-extracted up.... + // TODO: most of this should be re-extracted up.... // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71 | 72-75 | 76-79 | 80-83 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 for (int i = 0; i < 16; i++) { regp->r[i] = read_uint32(sl->q_buf, 4 * i); - if (sl->verbose > 1) - DLOG("r%2d = 0x%08x\n", i, regp->r[i]); + + if (sl->verbose > 1) { DLOG("r%2d = 0x%08x\n", i, regp->r[i]); } } + 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); - if (sl->verbose < 2) - return 0; + + if (sl->verbose < 2) { return(0); } DLOG("xpsr = 0x%08x\n", regp->xpsr); DLOG("main_sp = 0x%08x\n", regp->main_sp); @@ -611,10 +643,10 @@ int _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { DLOG("rw = 0x%08x\n", regp->rw); DLOG("rw2 = 0x%08x\n", regp->rw2); - return 0; + return(0); } -// Read an arm-core register, the index must be in the range 0..20. +// read an arm-core register, the index must be in the range 0..20. // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 @@ -625,8 +657,8 @@ int _stlink_sg_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { sg->cdb_cmd_blk[2] = r_idx; sl->q_len = 4; sg->q_addr = 0; - if (stlink_q(sl)) - return -1; + + if (stlink_q(sl)) { return(-1); } // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71 | 72-75 | 76-79 | 80-83 @@ -647,19 +679,19 @@ int _stlink_sg_read_reg(stlink_t *sl, int r_idx, struct stlink_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; } - return 0; + return(0); } -// Write an arm-core register. Index: +// write an arm-core register. Index: // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 @@ -673,16 +705,16 @@ int _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) { write_uint32(sg->cdb_cmd_blk + 3, reg); sl->q_len = 2; sg->q_addr = 0; - if (stlink_q(sl)) - return -1; + + if (stlink_q(sl)) { return(-1); } stlink_stat(sl, "write reg"); - return 0; + return(0); } -// Write a register of the debug module of the core. +// write a register of the debug module of the core. // XXX ?(atomic writes) -// TODO test +// TODO: test void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_write_dreg ***\n"); @@ -698,38 +730,37 @@ void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { stlink_stat(sl, "write debug reg"); } -// Force the core exit the debug mode. +// force the core exit the debug mode. int _stlink_sg_run(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_RUNCORE; sl->q_len = 2; sg->q_addr = 0; - if (stlink_q(sl)) - return -1; + + if (stlink_q(sl)) { return(-1); } stlink_stat(sl, "run core"); - return 0; + return(0); } -// Step the arm-core. +// step the arm-core. int _stlink_sg_step(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_STEPCORE; sl->q_len = 2; sg->q_addr = 0; - if (stlink_q(sl)) - return -1; + + if (stlink_q(sl)) { return(-1); } stlink_stat(sl, "step core"); - return 0; + return(0); } -// TODO test +// TODO: test and make delegate! // see Cortex-M3 Technical Reference Manual -// TODO make delegate! void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) { DLOG("\n*** stlink_set_hw_bp ***\n"); struct stlink_libsg *sg = sl->backend_data; @@ -747,8 +778,7 @@ void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) { stlink_stat(sl, "set flash breakpoint"); } -// TODO test -// TODO make delegate! +// TODO: test and make delegate! void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_clr_hw_bp ***\n"); @@ -761,7 +791,7 @@ void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) { stlink_stat(sl, "clear flash breakpoint"); } -// Read a "len" bytes to the sl->q_buf from the memory, max 6kB (6144 bytes) +// read a "len" bytes to the sl->q_buf from the memory, max 6kB (6144 bytes) int _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -778,14 +808,14 @@ int _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { // (broken residue issue) sl->q_len = len; sg->q_addr = addr; - if (stlink_q(sl)) - return -1; + + if (stlink_q(sl)) { return(-1); } stlink_print_data(sl); - return 0; + return(0); } -// Write a "len" bytes from the sl->q_buf to the memory, max 64 Bytes. +// write a "len" bytes from the sl->q_buf to the memory, max 64 Bytes. int _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; int ret; @@ -799,21 +829,21 @@ int _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { // this sends the command... ret = send_usb_mass_storage_command(sg->usb_handle, - sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); - if (ret == -1) - return ret; + sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); + + if (ret == -1) { return(ret); } // This sends the data... ret = send_usb_data_only(sg->usb_handle, - sg->ep_req, sg->ep_rep, sl->q_buf, len); - if (ret == -1) - return ret; + sg->ep_req, sg->ep_rep, sl->q_buf, len); + + if (ret == -1) { return(ret); } stlink_print_data(sl); - return 0; + return(0); } -// Write a "len" bytes from the sl->q_buf to the memory, max Q_BUF_LEN bytes. +// write a "len" bytes from the sl->q_buf to the memory, max Q_BUF_LEN bytes. int _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; int ret; @@ -827,21 +857,21 @@ int _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { // this sends the command... ret = send_usb_mass_storage_command(sg->usb_handle, - sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); - if (ret == -1) - return ret; + sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); + + if (ret == -1) { return(ret); } // This sends the data... ret = send_usb_data_only(sg->usb_handle, - sg->ep_req, sg->ep_rep, sl->q_buf, len); - if (ret == -1) - return ret; + sg->ep_req, sg->ep_rep, sl->q_buf, len); + + if (ret == -1) { return(ret); } stlink_print_data(sl); - return 0; + return(0); } -// Write one DWORD data to memory +// write one DWORD data to memory int _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -850,10 +880,10 @@ int _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { write_uint32(sg->cdb_cmd_blk + 2, addr); write_uint32(sg->cdb_cmd_blk + 6, data); sl->q_len = 2; - return stlink_q(sl); + return(stlink_q(sl)); } -// Read one DWORD data from memory +// read one DWORD data from memory int _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -861,24 +891,24 @@ int _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { // 2-5: addr write_uint32(sg->cdb_cmd_blk + 2, addr); sl->q_len = 8; - if (stlink_q(sl)) - return -1; + + if (stlink_q(sl)) { return(-1); } *data = read_uint32(sl->q_buf, 4); - return 0; + return(0); } -// Exit the jtag or swd mode and enter the mass mode. +// exit the jtag or swd mode and enter the mass mode. int _stlink_sg_exit_debug_mode(stlink_t *stl) { if (stl) { struct stlink_libsg* sl = stl->backend_data; clear_cdb(sl); sl->cdb_cmd_blk[1] = STLINK_DEBUG_EXIT; stl->q_len = 0; // >0 -> aboard - return stlink_q(stl); + return(stlink_q(stl)); } - return 0; + return(0); } // 1) open a sg device, switch the stlink from dfu to mass mode @@ -906,35 +936,38 @@ static stlink_backend_t _stlink_sg_backend = { _stlink_sg_write_mem8, _stlink_sg_read_all_regs, _stlink_sg_read_reg, - NULL, /* read_all_unsupported_regs */ - NULL, /* read_unsupported_regs */ - NULL, /* write_unsupported_regs */ + NULL, // read_all_unsupported_regs + NULL, // read_unsupported_regs + NULL, // write_unsupported_regs _stlink_sg_write_reg, _stlink_sg_step, _stlink_sg_current_mode, _stlink_sg_force_debug, - NULL, /* target_voltage */ - NULL /* set_swdclk */ + NULL, // target_voltage + NULL // set_swdclk }; static stlink_t* stlink_open(const int verbose) { - stlink_t *sl = malloc(sizeof (stlink_t)); - struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg)); + stlink_t *sl = malloc(sizeof(stlink_t)); + struct stlink_libsg *slsg = malloc(sizeof(struct stlink_libsg)); + if (sl == NULL || slsg == NULL) { WLOG("Couldn't malloc stlink and stlink_sg structures out of memory!\n"); - if (sl != NULL) - free(sl); - if (slsg != NULL) - free(slsg); - return NULL; + + if (sl != NULL) { free(sl); } + + if (slsg != NULL) { free(slsg); } + + return(NULL); } + memset(sl, 0, sizeof(stlink_t)); if (libusb_init(&(slsg->libusb_ctx))) { WLOG("failed to init libusb context, wrong version of libraries?\n"); free(sl); free(slsg); - return NULL; + return(NULL); } #if LIBUSB_API_VERSION < 0x01000106 @@ -944,32 +977,35 @@ static stlink_t* stlink_open(const int verbose) { #endif slsg->usb_handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, STLINK_USB_VID_ST, STLINK_USB_PID_STLINK); + if (slsg->usb_handle == NULL) { WLOG("Failed to find an stlink v1 by VID:PID\n"); libusb_close(slsg->usb_handle); libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); - return NULL; + return(NULL); } - // TODO - // Could read the interface config descriptor, and assert lots of the assumptions + // TODO: Could read the interface config descriptor, and assert lots of the assumptions // assumption: numInterfaces is always 1... if (libusb_kernel_driver_active(slsg->usb_handle, 0) == 1) { int r = libusb_detach_kernel_driver(slsg->usb_handle, 0); + if (r < 0) { WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-r)); libusb_close(slsg->usb_handle); libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); - return NULL; + return(NULL); } + DLOG("Kernel driver was successfully detached\n"); } int config; + if (libusb_get_configuration(slsg->usb_handle, &config)) { /* this may fail for a previous configured device */ WLOG("libusb_get_configuration()\n"); @@ -977,7 +1013,7 @@ static stlink_t* stlink_open(const int verbose) { libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); - return NULL; + return(NULL); } @@ -985,6 +1021,7 @@ static stlink_t* stlink_open(const int verbose) { if (config != 1) { WLOG("Your stlink got into a real weird configuration, trying to fix it!\n"); DLOG("setting new configuration (%d -> 1)\n", config); + if (libusb_set_configuration(slsg->usb_handle, 1)) { /* this may fail for a previous configured device */ WLOG("libusb_set_configuration() failed\n"); @@ -992,7 +1029,7 @@ static stlink_t* stlink_open(const int verbose) { libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); - return NULL; + return(NULL); } } @@ -1002,7 +1039,7 @@ static stlink_t* stlink_open(const int verbose) { libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); - return NULL; + return(NULL); } // assumption: endpoint config is fixed mang. really. @@ -1018,31 +1055,34 @@ static stlink_t* stlink_open(const int verbose) { sl->core_stat = TARGET_UNKNOWN; slsg->q_addr = 0; - return sl; + return(sl); } stlink_t* stlink_v1_open_inner(const int verbose) { ugly_init(verbose); stlink_t *sl = stlink_open(verbose); + if (sl == NULL) { ELOG("Could not open stlink device\n"); - return NULL; + return(NULL); } stlink_version(sl); + if ((sl->version.st_vid != STLINK_USB_VID_ST) || (sl->version.stlink_pid != STLINK_USB_PID_STLINK)) { ELOG("WTF? successfully opened, but unable to read version details. BROKEN!\n"); - return NULL; + return(NULL); } DLOG("Reading current mode...\n"); + switch (stlink_current_mode(sl)) { case STLINK_DEV_MASS_MODE: - return sl; + return(sl); case STLINK_DEV_DEBUG_MODE: // TODO go to mass? - return sl; + return(sl); default: ILOG("Current mode unusable, trying to get back to a useful state...\n"); break; @@ -1053,26 +1093,27 @@ stlink_t* stlink_v1_open_inner(const int verbose) { // re-query device info (and retest) stlink_version(sl); + if ((sl->version.st_vid != STLINK_USB_VID_ST) || (sl->version.stlink_pid != STLINK_USB_PID_STLINK)) { ELOG("WTF? successfully opened, but unable to read version details. BROKEN!\n"); - return NULL; + return(NULL); } - return sl; + return(sl); } stlink_t* stlink_v1_open(const int verbose, int reset) { stlink_t *sl = stlink_v1_open_inner(verbose); - if (sl == NULL) - return NULL; + + if (sl == NULL) { return(NULL); } // by now, it _must_ be fully open and in a useful mode.... stlink_enter_swd_mode(sl); - /* Now we are ready to read the parameters */ - if (reset) { - stlink_reset(sl); - } + + // now we are ready to read the parameters + if (reset) { stlink_reset(sl); } + stlink_load_device_params(sl); ILOG("Successfully opened a stlink v1 debugger\n"); - return sl; + return(sl); } diff --git a/src/stlink-lib/sg.h b/src/stlink-lib/sg.h index 811b339c7..f34b2e122 100644 --- a/src/stlink-lib/sg.h +++ b/src/stlink-lib/sg.h @@ -1,8 +1,6 @@ /* * File: sg.h * Author: karl - * - * Created on October 1, 2011, 11:29 PM */ #ifndef STLINK_SG_H @@ -15,31 +13,28 @@ extern "C" { #endif - // device access -#define RDWR 0 -#define RO 1 -#define SG_TIMEOUT_SEC 1 // actually 1 is about 2 sec -#define SG_TIMEOUT_MSEC 3 * 1000 - // Each CDB can be a total of 6, 10, 12, or 16 bytes, later version - // of the SCSI standard also allow for variable-length CDBs (min. CDB is 6). - // the stlink needs max. 10 bytes. -#define CDB_6 6 -#define CDB_10 10 -#define CDB_12 12 -#define CDB_16 16 +/* Device access */ +#define RDWR 0 +#define RO 1 +#define SG_TIMEOUT_SEC 1 // actually 1 is about 2 sec +#define SG_TIMEOUT_MSEC 3 * 1000 -#define CDB_SL 10 +// Each CDB can be a total of 6, 10, 12, or 16 bytes, later version of the SCSI standard +// also allow for variable-length CDBs (min. CDB is 6). The stlink needs max. 10 bytes. +#define CDB_6 6 +#define CDB_10 10 +#define CDB_12 12 +#define CDB_16 16 - // Query data flow direction. -#define Q_DATA_OUT 0 -#define Q_DATA_IN 1 - - // The SCSI Request Sense command is used to obtain sense data - // (error information) from a target device. - // http://en.wikipedia.org/wiki/SCSI_Request_Sense_Command -#define SENSE_BUF_LEN 32 +#define CDB_SL 10 +/* Query data flow direction */ +#define Q_DATA_OUT 0 +#define Q_DATA_IN 1 +// The SCSI Request Sense command is used to obtain sense data (error information) from +// a target device. (http://en.wikipedia.org/wiki/SCSI_Request_Sense_Command) +#define SENSE_BUF_LEN 32 struct stlink_libsg { libusb_context* libusb_ctx; @@ -65,8 +60,8 @@ struct stlink_libsg { stlink_t* stlink_v1_open(const int verbose, int reset); -#ifdef __cplusplus +#ifdef __cplusplus } #endif -#endif /* STLINK_SG_H */ +#endif // STLINK_SG_H diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index c22f2fe5e..f9b4775f3 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -19,10 +19,10 @@ #include #include "usb.h" -enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80}; +enum SCSI_Generic_Direction {SG_DXFER_TO_DEV = 0, SG_DXFER_FROM_DEV = 0x80}; static inline uint32_t le_to_h_u32(const uint8_t* buf) { - return (uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24); + return((uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24)); } static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, uint32_t khz) { @@ -33,15 +33,18 @@ static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, u bool match = true; for (i = 0; i < map_size; i++) { - if (!map[i]) continue; + if (!map[i]) { continue; } + last_valid_speed = i; + if (khz == map[i]) { speed_index = i; break; } else { int current_diff = khz - map[i]; - // Get abs value for comparison + // get abs value for comparison current_diff = (current_diff > 0) ? current_diff : -current_diff; + if ((current_diff < speed_diff) && khz >= map[i]) { speed_diff = current_diff; speed_index = i; @@ -50,72 +53,80 @@ static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, u } if (speed_index == -1) { - // This will only be here if we cannot match the slow speed. Use the slowest speed we support. + // This will only be here if we cannot match the slow speed. + // Use the slowest speed we support. speed_index = last_valid_speed; match = false; } else if (i == map_size) { match = false; } + if (!match) { ILOG("Unable to match requested speed %d kHz, using %d kHz\n", khz, map[speed_index]); } - return speed_index; + return(speed_index); } void _stlink_usb_close(stlink_t* sl) { - if (!sl) return; + if (!sl) { return; } struct stlink_libusb * const handle = sl->backend_data; - // Maybe we couldn't even get the usb device? + + // maybe we couldn't even get the usb device? if (handle != NULL) { - if (handle->usb_handle != NULL) libusb_close(handle->usb_handle); + if (handle->usb_handle != NULL) { libusb_close(handle->usb_handle); } + libusb_exit(handle->libusb_ctx); free(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 */ + 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; int t; - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, (int) txsize, &res, 3000); + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, (int)txsize, &res, 3000); + if (t) { printf("[!] send_recv send request failed: %s\n", libusb_error_name(t)); - return -1; + return(-1); } else if ((size_t)res != txsize) { printf("[!] send_recv send request wrote %u bytes (instead of %u).\n", - (unsigned int)res, (unsigned int)txsize); + (unsigned int)res, (unsigned int)txsize); } if (rxsize != 0) { - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int) rxsize, &res, 3000); + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int)rxsize, &res, 3000); + if (t) { printf("[!] send_recv read reply failed: %s\n", libusb_error_name(t)); - return -1; + return(-1); } } if ((handle->protocoll == 1) && terminate) { - // Read the SG reply + // read the SG reply unsigned char sg_buf[13]; t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, sg_buf, 13, &res, 3000); + if (t) { printf("[!] send_recv read storage failed: %s\n", libusb_error_name(t)); - return -1; + return(-1); } + // The STLink doesn't seem to evaluate the sequence number. handle->sg_transfer_idx++; } - return res; + return(res); } static inline int send_only(struct stlink_libusb* handle, int terminate, - unsigned char* txbuf, size_t txsize) { - return (int) send_recv(handle, terminate, txbuf, txsize, NULL, 0); + unsigned char* txbuf, size_t txsize) { + return((int)send_recv(handle, terminate, txbuf, txsize, NULL, 0)); } @@ -123,7 +134,8 @@ static int fill_command(stlink_t * sl, enum SCSI_Generic_Direction dir, uint32_t 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)); + memset(cmd, 0, sizeof(sl->c_buf)); + if (slu->protocoll == 1) { cmd[i++] = 'U'; cmd[i++] = 'S'; @@ -133,10 +145,11 @@ static int fill_command(stlink_t * sl, enum SCSI_Generic_Direction dir, uint32_t 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 + cmd[i++] = 0; // logical unit + cmd[i++] = 0xa; // command length } - return i; + + return(i); } int _stlink_usb_version(stlink_t *sl) { @@ -150,9 +163,10 @@ int _stlink_usb_version(stlink_t *sl) { cmd[i++] = STLINK_GET_VERSION; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_GET_VERSION\n"); - return (int) size; + return((int)size); } /* STLINK-V3 requires a specific command */ @@ -162,13 +176,14 @@ int _stlink_usb_version(stlink_t *sl) { cmd[i++] = STLINK_APIV3_GET_VERSION_EX; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size != (ssize_t)rep_len) { printf("[!] send_recv STLINK_APIV3_GET_VERSION_EX\n"); - return (int) size; + return((int)size); } } - return 0; + return(0); } int32_t _stlink_usb_target_voltage(stlink_t *sl) { @@ -184,19 +199,20 @@ int32_t _stlink_usb_target_voltage(stlink_t *sl) { cmd[i++] = STLINK_GET_TARGET_VOLTAGE; size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_GET_TARGET_VOLTAGE\n"); - return -1; + return(-1); } else if (size != 8) { printf("[!] wrong length STLINK_GET_TARGET_VOLTAGE\n"); - return -1; + return(-1); } factor = (rdata[3] << 24) | (rdata[2] << 16) | (rdata[1] << 8) | (rdata[0] << 0); reading = (rdata[7] << 24) | (rdata[6] << 16) | (rdata[5] << 8) | (rdata[4] << 0); voltage = 2400 * reading / factor; - return voltage; + return(voltage); } int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { @@ -211,13 +227,15 @@ int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { cmd[i++] = STLINK_JTAG_READDEBUG_32BIT; write_uint32(&cmd[i], addr); size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_JTAG_READDEBUG_32BIT\n"); - return (int) size; + return((int)size); } + *data = read_uint32(rdata, 4); - return 0; + return(0); } int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { @@ -233,16 +251,17 @@ int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { write_uint32(&cmd[i], addr); write_uint32(&cmd[i + 4], data); size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_JTAG_WRITEDEBUG_32BIT\n"); - return (int) size; + return((int)size); } - return 0; + return(0); } int _stlink_usb_get_rw_status(stlink_t *sl) { - if (sl->version.jtag_api == STLINK_JTAG_API_V1) return -1; + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { return(-1); } unsigned char* const rdata = sl->q_buf; struct stlink_libusb * const slu = sl->backend_data; @@ -252,6 +271,7 @@ int _stlink_usb_get_rw_status(stlink_t *sl) { i = fill_command(sl, SG_DXFER_FROM_DEV, 12); cmd[i++] = STLINK_DEBUG_COMMAND; + if (sl->version.flags & STLINK_F_HAS_GETLASTRWSTATUS2) { cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS2; ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 12); @@ -259,9 +279,10 @@ int _stlink_usb_get_rw_status(stlink_t *sl) { cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS; ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 2); } - if (ret < 0) return -1; - return 0; + if (ret < 0) { return(-1); } + + return(0); } int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { @@ -276,11 +297,14 @@ int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); ret = send_only(slu, 0, cmd, slu->cmd_len); - if (ret == -1) return ret; + + if (ret == -1) { return(ret); } + ret = send_only(slu, 0, data, len); - if (ret == -1) return ret; - return _stlink_usb_get_rw_status(sl); + if (ret == -1) { return(ret); } + + return(_stlink_usb_get_rw_status(sl)); } int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { @@ -295,11 +319,14 @@ int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); ret = send_only(slu, 0, cmd, slu->cmd_len); - if (ret == -1) return ret; + + if (ret == -1) { return(ret); } + ret = send_only(slu, 1, data, len); - if (ret == -1) return ret; - return 0; + if (ret == -1) { return(ret); } + + return(0); } @@ -313,12 +340,13 @@ int _stlink_usb_current_mode(stlink_t * sl) { cmd[i++] = STLINK_GET_CURRENT_MODE; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_GET_CURRENT_MODE\n"); - return -1; + return(-1); } - return sl->q_buf[0]; + return(sl->q_buf[0]); } int _stlink_usb_core_id(stlink_t * sl) { @@ -330,15 +358,18 @@ int _stlink_usb_core_id(stlink_t * sl) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { cmd[i++] = STLINK_DEBUG_READCOREID; } else { cmd[i++] = STLINK_DEBUG_APIV2_READ_IDCODES; } + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_DEBUG_READCOREID\n"); - return -1; + return(-1); } if (sl->version.jtag_api == STLINK_JTAG_API_V1) { @@ -346,16 +377,18 @@ int _stlink_usb_core_id(stlink_t * sl) { } else { sl->core_id = read_uint32(data, 4); } - return 0; + + return(0); } -int _stlink_usb_status_v2(stlink_t *sl) -{ + +int _stlink_usb_status_v2(stlink_t *sl) { int result; uint32_t status = 0; result = _stlink_usb_read_debug32(sl, DCB_DHCSR, &status); DLOG("core status: %08X\n", status); - if (result != 0) { + + if (result != 0) { sl->core_stat = TARGET_UNKNOWN; } else { if (status & S_HALT) { @@ -367,11 +400,11 @@ int _stlink_usb_status_v2(stlink_t *sl) } } - return result; + return(result); } int _stlink_usb_status(stlink_t * sl) { - if (sl->version.jtag_api != STLINK_JTAG_API_V1) return _stlink_usb_status_v2(sl); + if (sl->version.jtag_api != STLINK_JTAG_API_V1) { return(_stlink_usb_status_v2(sl)); } struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; @@ -383,21 +416,25 @@ int _stlink_usb_status(stlink_t * sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_GETSTATUS; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_DEBUG_GETSTATUS\n"); - return (int) size; + return((int)size); } - sl->q_len = (int) size; + + sl->q_len = (int)size; + if (sl->q_len > 1) { - if (sl->q_buf[0] == STLINK_CORE_RUNNING) + if (sl->q_buf[0] == STLINK_CORE_RUNNING) { sl->core_stat = TARGET_RUNNING; - else if (sl->q_buf[0] == STLINK_CORE_HALTED) + } else if (sl->q_buf[0] == STLINK_CORE_HALTED) { sl->core_stat = TARGET_HALTED; - else + } else { sl->core_stat = TARGET_UNKNOWN; + } } - return 0; + return(0); } int _stlink_usb_force_debug(stlink_t *sl) { @@ -411,12 +448,13 @@ int _stlink_usb_force_debug(stlink_t *sl) { 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 STLINK_DEBUG_FORCEDEBUG\n"); - return (int) size; + return((int)size); } - return 0; + return(0); } int _stlink_usb_enter_swd_mode(stlink_t * sl) { @@ -428,7 +466,7 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - // Select correct API-Version for entering SWD mode: V1 API (0x20) or V2 API (0x30). + // select correct API-Version for entering SWD mode: V1 API (0x20) or V2 API (0x30). cmd[i++] = sl->version.jtag_api == STLINK_JTAG_API_V1 ? STLINK_DEBUG_APIV1_ENTER : STLINK_DEBUG_APIV2_ENTER; cmd[i++] = STLINK_DEBUG_ENTER_SWD; @@ -437,12 +475,13 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { } else { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); } + if (size == -1) { printf("[!] send_recv STLINK_DEBUG_ENTER\n"); - return (int) size; + return((int)size); } - return 0; + return(0); } int _stlink_usb_exit_dfu_mode(stlink_t* sl) { @@ -454,12 +493,13 @@ int _stlink_usb_exit_dfu_mode(stlink_t* sl) { cmd[i++] = STLINK_DFU_COMMAND; cmd[i++] = STLINK_DFU_EXIT; size = send_only(slu, 1, cmd, slu->cmd_len); + if (size == -1) { printf("[!] send_recv STLINK_DFU_EXIT\n"); - return (int) size; + return((int)size); } - return 0; + return(0); } @@ -472,6 +512,7 @@ int _stlink_usb_reset(stlink_t * sl) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { cmd[i++] = STLINK_DEBUG_APIV1_RESETSYS; } else { @@ -479,14 +520,15 @@ int _stlink_usb_reset(stlink_t * sl) { } size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_DEBUG_RESETSYS\n"); - return (int) size; + return((int)size); } - // Reset through AIRCR so that NRST does not need to be connected. - return stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | - STLINK_REG_AIRCR_SYSRESETREQ); + // reset through AIRCR so that NRST does not need to be connected + return(stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | + STLINK_REG_AIRCR_SYSRESETREQ)); } int _stlink_usb_jtag_reset(stlink_t * sl, int value) { @@ -501,12 +543,13 @@ int _stlink_usb_jtag_reset(stlink_t * sl, int value) { cmd[i++] = STLINK_JTAG_DRIVE_NRST; cmd[i++] = value; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_JTAG_DRIVE_NRST\n"); - return (int) size; + return((int)size); } - return 0; + return(0); } @@ -521,12 +564,13 @@ int _stlink_usb_step(stlink_t* sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_STEPCORE; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_DEBUG_STEPCORE\n"); - return (int) size; + return((int)size); } - return 0; + return(0); } /** @@ -539,8 +583,8 @@ int _stlink_usb_run(stlink_t* sl) { int res; if (sl->version.jtag_api != STLINK_JTAG_API_V1) { - res = _stlink_usb_write_debug32(sl, DCB_DHCSR, DBGKEY|C_DEBUGEN); - return res; + res = _stlink_usb_write_debug32(sl, DCB_DHCSR, DBGKEY | C_DEBUGEN); + return(res); } @@ -553,15 +597,15 @@ int _stlink_usb_run(stlink_t* sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_RUNCORE; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_DEBUG_RUNCORE\n"); - return (int) size; + return((int)size); } - return 0; + return(0); } - int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; @@ -579,12 +623,13 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { cmd[i++] = clk_divisor & 0xFF; cmd[i++] = (clk_divisor >> 8) & 0xFF; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size == -1) { printf("[!] send_recv STLINK_DEBUG_APIV2_SWD_SET_FREQ\n"); - return (int) size; + return((int)size); } - return 0; + return(0); } else if (sl->version.stlink_v == 3) { int speed_index; uint32_t map[STLINK_V3_MAX_FREQ_NB]; @@ -594,14 +639,17 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { cmd[i++] = STLINK_APIV3_GET_COM_FREQ; cmd[i++] = 0; // SWD mode size = send_recv(slu, 1, cmd, slu->cmd_len, data, 52); + if (size == -1) { printf("[!] send_recv STLINK_APIV3_GET_COM_FREQ\n"); - return (int) size; + return((int)size); } int speeds_size = data[8]; - if (speeds_size > STLINK_V3_MAX_FREQ_NB) speeds_size = STLINK_V3_MAX_FREQ_NB; + if (speeds_size > STLINK_V3_MAX_FREQ_NB) { + speeds_size = STLINK_V3_MAX_FREQ_NB; + } for (i = 0; i < speeds_size; i++) map[i] = le_to_h_u32(&data[12 + 4 * i]); @@ -622,14 +670,16 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { cmd[i++] = (uint8_t)((map[speed_index] >> 24) & 0xFF); size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8); + if (size == -1) { printf("[!] send_recv STLINK_APIV3_SET_COM_FREQ\n"); - return (int) size; + return((int)size); } - return 0; + return(0); } - return -1; + + return(-1); } int _stlink_usb_exit_debug_mode(stlink_t *sl) { @@ -642,12 +692,13 @@ int _stlink_usb_exit_debug_mode(stlink_t *sl) { cmd[i++] = STLINK_DEBUG_EXIT; size = send_only(slu, 1, cmd, slu->cmd_len); + if (size == -1) { printf("[!] send_only STLINK_DEBUG_EXIT\n"); - return (int) size; + return((int)size); } - return 0; + return(0); } int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { @@ -665,13 +716,13 @@ int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { if (size == -1) { printf("[!] send_recv STLINK_DEBUG_READMEM_32BIT\n"); - return (int) size; + return((int)size); } - sl->q_len = (int) size; + sl->q_len = (int)size; stlink_print_data(sl); - return 0; + return(0); } int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { @@ -694,23 +745,24 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { if (size == -1) { printf("[!] send_recv STLINK_DEBUG_READALLREGS\n"); - return (int) size; + return((int)size); } /* V1: regs data from offset 0 */ /* V2: status at offset 0, regs data from offset 4 */ int reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; - sl->q_len = (int) size; + sl->q_len = (int)size; stlink_print_data(sl); - for(i=reg_offset; i<16; i++) regp->r[i]= read_uint32(sl->q_buf, i*4); + for (i = reg_offset; i < 16; i++) regp->r[i] = read_uint32(sl->q_buf, i * 4); + regp->xpsr = read_uint32(sl->q_buf, reg_offset + 64); regp->main_sp = read_uint32(sl->q_buf, reg_offset + 68); regp->process_sp = read_uint32(sl->q_buf, reg_offset + 72); regp->rw = read_uint32(sl->q_buf, reg_offset + 76); regp->rw2 = read_uint32(sl->q_buf, reg_offset + 80); - if (sl->verbose < 2) return 0; + if (sl->verbose < 2) { return(0); } DLOG("xpsr = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 64)); DLOG("main_sp = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 68)); @@ -718,7 +770,7 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { DLOG("rw = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 76)); DLOG("rw2 = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 80)); - return 0; + return(0); } int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { @@ -739,15 +791,15 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { cmd[i++] = STLINK_DEBUG_APIV2_READREG; } - cmd[i++] = (uint8_t) r_idx; + cmd[i++] = (uint8_t)r_idx; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_DEBUG_READREG\n"); - return (int) size; + return((int)size); } - sl->q_len = (int) size; + sl->q_len = (int)size; stlink_print_data(sl); r = read_uint32(sl->q_buf, reg_offset); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); @@ -772,7 +824,7 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { regp->r[r_idx] = r; } - return 0; + return(0); } /* See section C1.6 of the ARMv7-M Architecture Reference Manual */ @@ -780,89 +832,96 @@ int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg uint32_t r; int ret; - sl->q_buf[0] = (unsigned char) r_idx; + sl->q_buf[0] = (unsigned char)r_idx; + for (int i = 1; i < 4; i++) sl->q_buf[i] = 0; ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4); - if (ret == -1) return ret; + + if (ret == -1) { return(ret); } ret = _stlink_usb_read_mem32(sl, STLINK_REG_DCRDR, 4); - if (ret == -1) return ret; + + if (ret == -1) { return(ret); } r = read_uint32(sl->q_buf, 0); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); switch (r_idx) { - case 0x14: - regp->primask = (uint8_t) (r & 0xFF); - regp->basepri = (uint8_t) ((r>>8) & 0xFF); - regp->faultmask = (uint8_t) ((r>>16) & 0xFF); - regp->control = (uint8_t) ((r>>24) & 0xFF); - break; - case 0x21: - regp->fpscr = r; - break; - default: - regp->s[r_idx - 0x40] = r; - break; + case 0x14: + regp->primask = (uint8_t)(r & 0xFF); + regp->basepri = (uint8_t)((r >> 8) & 0xFF); + regp->faultmask = (uint8_t)((r >> 16) & 0xFF); + regp->control = (uint8_t)((r >> 24) & 0xFF); + break; + case 0x21: + regp->fpscr = r; + break; + default: + regp->s[r_idx - 0x40] = r; + break; } - return 0; + return(0); } int _stlink_usb_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { int ret; ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); - if (ret == -1) return ret; + + if (ret == -1) { return(ret); } ret = _stlink_usb_read_unsupported_reg(sl, 0x21, regp); - if (ret == -1) return ret; + + if (ret == -1) { return(ret); } for (int i = 0; i < 32; i++) { - ret = _stlink_usb_read_unsupported_reg(sl, 0x40+i, regp); - if (ret == -1) return ret; + ret = _stlink_usb_read_unsupported_reg(sl, 0x40 + i, regp); + + if (ret == -1) { return(ret); } } - return 0; + return(0); } /* See section C1.6 of the ARMv7-M Architecture Reference Manual */ int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, struct stlink_reg *regp) { int ret; - if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ + if (r_idx >= 0x1C && r_idx <= 0x1F) { // primask, basepri, faultmask, or control /* These are held in the same register */ ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); - if (ret == -1) return ret; - val = (uint8_t) (val>>24); + if (ret == -1) { return(ret); } + + val = (uint8_t)(val >> 24); switch (r_idx) { - case 0x1C: /* control */ - val = (((uint32_t) val) << 24) | - (((uint32_t) regp->faultmask) << 16) | - (((uint32_t) regp->basepri) << 8) | - ((uint32_t) regp->primask); - break; - case 0x1D: /* faultmask */ - val = (((uint32_t) regp->control) << 24) | - (((uint32_t) val) << 16) | - (((uint32_t) regp->basepri) << 8) | - ((uint32_t) regp->primask); - break; - case 0x1E: /* basepri */ - val = (((uint32_t) regp->control) << 24) | - (((uint32_t) regp->faultmask) << 16) | - (((uint32_t) val) << 8) | - ((uint32_t) regp->primask); - break; - case 0x1F: /* primask */ - val = (((uint32_t) regp->control) << 24) | - (((uint32_t) regp->faultmask) << 16) | - (((uint32_t) regp->basepri) << 8) | - ((uint32_t) val); - break; + case 0x1C: /* control */ + val = (((uint32_t)val) << 24) | + (((uint32_t)regp->faultmask) << 16) | + (((uint32_t)regp->basepri) << 8) | + ((uint32_t)regp->primask); + break; + case 0x1D: /* faultmask */ + val = (((uint32_t)regp->control) << 24) | + (((uint32_t)val) << 16) | + (((uint32_t)regp->basepri) << 8) | + ((uint32_t)regp->primask); + break; + case 0x1E: /* basepri */ + val = (((uint32_t)regp->control) << 24) | + (((uint32_t)regp->faultmask) << 16) | + (((uint32_t)val) << 8) | + ((uint32_t)regp->primask); + break; + case 0x1F: /* primask */ + val = (((uint32_t)regp->control) << 24) | + (((uint32_t)regp->faultmask) << 16) | + (((uint32_t)regp->basepri) << 8) | + ((uint32_t)val); + break; } r_idx = 0x14; @@ -871,14 +930,15 @@ int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, str write_uint32(sl->q_buf, val); ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRDR, 4); - if (ret == -1) return ret; - sl->q_buf[0] = (unsigned char) r_idx; + if (ret == -1) { return(ret); } + + sl->q_buf[0] = (unsigned char)r_idx; sl->q_buf[1] = 0; sl->q_buf[2] = 0x01; sl->q_buf[3] = 0; - return _stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4); + return(_stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4)); } int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { @@ -903,19 +963,20 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { if (size == -1) { printf("[!] send_recv STLINK_DEBUG_WRITEREG\n"); - return (int) size; + return((int)size); } - sl->q_len = (int) size; + + sl->q_len = (int)size; stlink_print_data(sl); - return 0; + return(0); } static stlink_backend_t _stlink_usb_backend = { _stlink_usb_close, _stlink_usb_exit_debug_mode, _stlink_usb_enter_swd_mode, - NULL, // no enter_jtag_mode here... + NULL, // don't enter_jtag_mode here... _stlink_usb_exit_dfu_mode, _stlink_usb_core_id, _stlink_usb_reset, @@ -947,17 +1008,19 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL int ret = -1; int config; - sl = calloc(1, sizeof (stlink_t)); - slu = calloc(1, sizeof (struct stlink_libusb)); + sl = calloc(1, sizeof(stlink_t)); + slu = calloc(1, sizeof(struct stlink_libusb)); - if (sl == NULL) goto on_malloc_error; - if (slu == NULL) goto on_malloc_error; + if (sl == NULL) { goto on_malloc_error; } + + if (slu == NULL) { goto on_malloc_error; } ugly_init(verbose); sl->backend = &_stlink_usb_backend; sl->backend_data = slu; sl->core_stat = TARGET_UNKNOWN; + if (libusb_init(&(slu->libusb_ctx))) { WLOG("failed to init libusb context, wrong version of libraries?\n"); goto on_error; @@ -970,53 +1033,58 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL #endif libusb_device **list; - /* @TODO: We should use ssize_t and use it as a counter if > 0. - * As per libusb API: ssize_t libusb_get_device_list (libusb_context *ctx, libusb_device ***list) - */ - int cnt = (int) libusb_get_device_list(slu->libusb_ctx, &list); + // TODO: We should use ssize_t and use it as a counter if > 0. + // As per libusb API: ssize_t libusb_get_device_list (libusb_context *ctx, libusb_device ***list) + int cnt = (int)libusb_get_device_list(slu->libusb_ctx, &list); struct libusb_device_descriptor desc; int devBus = 0; int devAddr = 0; - /* @TODO: Reading a environment variable in a usb open function is not very nice, this should be refactored - * and moved into the CLI tools, and instead of giving USB_BUS:USB_ADDR a real stlink serial string should - * be passed to this function. Probably people are using this but this is very odd because as programmer - * can change to multiple busses and it is better to detect them based on serial. - */ + // TODO: Reading a environment variable in a usb open function is not very nice, this should + // be refactored and moved into the CLI tools, and instead of giving USB_BUS:USB_ADDR a real + // stlink serial string should be passed to this function. Probably people are using this + // but this is very odd because as programmer can change to multiple busses and it is better + // to detect them based on serial. char *device = getenv("STLINK_DEVICE"); + if (device) { - char *c = strchr(device,':'); + char *c = strchr(device, ':'); + if (c == NULL) { WLOG("STLINK_DEVICE must be : format\n"); goto on_error; } + devBus = atoi(device); *c++ = 0; devAddr = atoi(c); - ILOG("bus %03d dev %03d\n",devBus, devAddr); + ILOG("bus %03d dev %03d\n", devBus, devAddr); } while (cnt--) { struct libusb_device_handle *handle; libusb_get_device_descriptor(list[cnt], &desc); - if (desc.idVendor != STLINK_USB_VID_ST) continue; + + if (desc.idVendor != STLINK_USB_VID_ST) { continue; } if (devBus && devAddr) { - if ((libusb_get_bus_number(list[cnt]) != devBus) || (libusb_get_device_address(list[cnt]) != devAddr)) { + if ((libusb_get_bus_number(list[cnt]) != devBus) || + (libusb_get_device_address(list[cnt]) != devAddr)) { continue; } } ret = libusb_open(list[cnt], &handle); - if (ret) continue; // could not open device + + if (ret) { continue; } // could not open device sl->serial_size = libusb_get_string_descriptor_ascii( - handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial)); + handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial)); libusb_close(handle); - if (sl->serial_size < 0) continue; // could not read serial + if (sl->serial_size < 0) { continue; } // could not read serial // if no serial provided, or if serial match device, fixup version and protocol if (((serial == NULL) || (*serial == 0)) || (memcmp(serial, &sl->serial, sl->serial_size) == 0)) { @@ -1028,18 +1096,23 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL } else if (STLINK_V3_USB_PID(desc.idProduct)) { sl->version.stlink_v = 3; } + break; } } if (cnt < 0) { - WLOG ("Couldn't find %s ST-Link devices\n", (devBus && devAddr) ? "matched":"any"); + WLOG ("Couldn't find %s ST-Link devices\n", (devBus && devAddr) ? "matched" : "any"); goto on_error; } else { ret = libusb_open(list[cnt], &slu->usb_handle); + if (ret != 0) { - WLOG("Error %d (%s) opening ST-Link v%d device %03d:%03d\n", ret, strerror (errno), - sl->version.stlink_v, libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt])); + WLOG("Error %d (%s) opening ST-Link v%d device %03d:%03d\n", ret, + strerror(errno), + sl->version.stlink_v, + libusb_get_bus_number(list[cnt]), + libusb_get_device_address(list[cnt])); libusb_free_device_list(list, 1); goto on_error; } @@ -1049,6 +1122,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL if (libusb_kernel_driver_active(slu->usb_handle, 0) == 1) { ret = libusb_detach_kernel_driver(slu->usb_handle, 0); + if (ret < 0) { WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-ret)); goto on_libusb_error; @@ -1056,15 +1130,16 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL } if (libusb_get_configuration(slu->usb_handle, &config)) { - /* this may fail for a previous configured device */ + // this may fail for a previous configured device WLOG("libusb_get_configuration()\n"); goto on_libusb_error; } if (config != 1) { printf("setting new configuration (%d -> 1)\n", config); + if (libusb_set_configuration(slu->usb_handle, 1)) { - /* this may fail for a previous configured device */ + // this may fail for a previous configured device WLOG("libusb_set_configuration() failed\n"); goto on_libusb_error; } @@ -1075,8 +1150,9 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL goto on_libusb_error; } - // TODO - could use the scanning techniq from stm8 code here... + // TODO: Could use the scanning technique from STM8 code here... slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; + if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO || desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO || desc.idProduct == STLINK_USB_PID_STLINK_V2_1 || @@ -1090,17 +1166,14 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL } slu->sg_transfer_idx = 0; - slu->cmd_len = (slu->protocoll == 1) ? STLINK_SG_SIZE: STLINK_CMD_SIZE; + slu->cmd_len = (slu->protocoll == 1) ? STLINK_SG_SIZE : STLINK_CMD_SIZE; - // Initialize stlink version (sl->version) - stlink_version(sl); - - // Initialize stlink version (sl->version) + // initialize stlink version (sl->version) stlink_version(sl); if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { - // This seems to work, and is unnecessary information for the user. - // Demoted to debug -- REW + // this seems to work, and is unnecessary information for the user. + // demoted to debug -- REW DLOG("-- exit_dfu_mode\n"); stlink_exit_dfu_mode(sl); } @@ -1108,78 +1181,86 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL sl->freq = freq; // set the speed before entering the mode as the chip discovery phase // should be done at this speed too - // Set the stlink clock speed (default is 1800kHz) + // set the stlink clock speed (default is 1800kHz) DLOG("JTAG/SWD freq set to %d\n", freq); + switch (freq) { - case 5: - stlink_set_swdclk(sl, STLINK_SWDCLK_5KHZ_DIVISOR); - break; - case 15: - stlink_set_swdclk(sl, STLINK_SWDCLK_15KHZ_DIVISOR); - break; - case 25: - stlink_set_swdclk(sl, STLINK_SWDCLK_25KHZ_DIVISOR); - break; - case 50: - stlink_set_swdclk(sl, STLINK_SWDCLK_50KHZ_DIVISOR); - break; - case 100: - stlink_set_swdclk(sl, STLINK_SWDCLK_100KHZ_DIVISOR); - break; - case 125: - stlink_set_swdclk(sl, STLINK_SWDCLK_125KHZ_DIVISOR); - break; - case 240: - stlink_set_swdclk(sl, STLINK_SWDCLK_240KHZ_DIVISOR); - break; - case 480: - stlink_set_swdclk(sl, STLINK_SWDCLK_480KHZ_DIVISOR); - break; - case 950: - stlink_set_swdclk(sl, STLINK_SWDCLK_950KHZ_DIVISOR); - break; - case 1200: - stlink_set_swdclk(sl, STLINK_SWDCLK_1P2MHZ_DIVISOR); - break; - case 0: case 1800: - stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); - break; - case 4000: - stlink_set_swdclk(sl, STLINK_SWDCLK_4MHZ_DIVISOR); - break; + case 5: + stlink_set_swdclk(sl, STLINK_SWDCLK_5KHZ_DIVISOR); + break; + case 15: + stlink_set_swdclk(sl, STLINK_SWDCLK_15KHZ_DIVISOR); + break; + case 25: + stlink_set_swdclk(sl, STLINK_SWDCLK_25KHZ_DIVISOR); + break; + case 50: + stlink_set_swdclk(sl, STLINK_SWDCLK_50KHZ_DIVISOR); + break; + case 100: + stlink_set_swdclk(sl, STLINK_SWDCLK_100KHZ_DIVISOR); + break; + case 125: + stlink_set_swdclk(sl, STLINK_SWDCLK_125KHZ_DIVISOR); + break; + case 240: + stlink_set_swdclk(sl, STLINK_SWDCLK_240KHZ_DIVISOR); + break; + case 480: + stlink_set_swdclk(sl, STLINK_SWDCLK_480KHZ_DIVISOR); + break; + case 950: + stlink_set_swdclk(sl, STLINK_SWDCLK_950KHZ_DIVISOR); + break; + case 1200: + stlink_set_swdclk(sl, STLINK_SWDCLK_1P2MHZ_DIVISOR); + break; + case 0: case 1800: + stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); + break; + case 4000: + stlink_set_swdclk(sl, STLINK_SWDCLK_4MHZ_DIVISOR); + break; } if (reset == 2) { - stlink_jtag_reset(sl,0); - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); - stlink_force_debug(sl); - stlink_jtag_reset(sl,1); - usleep(10000); + stlink_jtag_reset(sl, 0); + + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } + + stlink_force_debug(sl); + stlink_jtag_reset(sl, 1); + usleep(10000); } - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } if (reset == 1) { - if ( sl->version.stlink_v > 1) stlink_jtag_reset(sl, 2); + if ( sl->version.stlink_v > 1) { stlink_jtag_reset(sl, 2); } + stlink_reset(sl); usleep(10000); } stlink_load_device_params(sl); - return sl; + return(sl); + +on_libusb_error: + stlink_close(sl); + return(NULL); - on_libusb_error: - stlink_close(sl); - return NULL; +on_error: - on_error: - if (slu->libusb_ctx) libusb_exit(slu->libusb_ctx); + if (slu->libusb_ctx) { libusb_exit(slu->libusb_ctx); } - on_malloc_error: - if (sl != NULL) free(sl); - if (slu != NULL) free(slu); - return NULL; +on_malloc_error: + + if (sl != NULL) { free(sl); } + + if (slu != NULL) { free(slu); } + + return(NULL); } static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { @@ -1189,7 +1270,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { size_t slcnt = 0; size_t slcur = 0; - /* Count stlink */ + /* Count STLINKs */ while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; int ret = libusb_get_device_descriptor(dev, &desc); @@ -1199,7 +1280,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { break; } - if (desc.idVendor != STLINK_USB_VID_ST) continue; + if (desc.idVendor != STLINK_USB_VID_ST) { continue; } if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { WLOG("skipping ST device : %#04x:%#04x)\n", desc.idVendor, desc.idProduct); @@ -1209,15 +1290,16 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { slcnt++; } - /* Allocate list of pointers */ - _sldevs = calloc(slcnt, sizeof(stlink_t *)); + _sldevs = calloc(slcnt, sizeof(stlink_t *)); // allocate list of pointers + if (!_sldevs) { *sldevs = NULL; - return 0; + return(0); } - /* Open stlinks and attach to list */ + /* Open STLINKS and attach them to list */ i = 0; + while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; int ret = libusb_get_device_descriptor(dev, &desc); @@ -1227,10 +1309,10 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { break; } - if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) continue; + if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { continue; } struct libusb_device_handle* handle; - char serial[STLINK_SERIAL_MAX_SIZE] = {0,}; + char serial[STLINK_SERIAL_MAX_SIZE] = {0, }; ret = libusb_open(dev, &handle); @@ -1240,15 +1322,18 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { } else { ELOG("Failed to open USB device %#06x:%#06x, libusb error: %d)\n", desc.idVendor, desc.idProduct, ret); } + break; } + ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial)); libusb_close(handle); - if (ret < 0) continue; + if (ret < 0) { continue; } stlink_t *sl = stlink_open_usb(0, 1, serial, 0); + if (!sl) { ELOG("Failed to open USB device %#06x:%#06x\n", desc.idVendor, desc.idProduct); continue; @@ -1259,7 +1344,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { *sldevs = _sldevs; - return slcur; + return(slcur); } size_t stlink_probe_usb(stlink_t **stdevs[]) { @@ -1271,10 +1356,12 @@ size_t stlink_probe_usb(stlink_t **stdevs[]) { ssize_t cnt; r = libusb_init(NULL); - if (r < 0) return 0; + + if (r < 0) { return(0); } cnt = libusb_get_device_list(NULL, &devs); - if (cnt < 0) return 0; + + if (cnt < 0) { return(0); } slcnt = stlink_probe_usb_devs(devs, &sldevs); libusb_free_device_list(devs, 1); @@ -1283,12 +1370,14 @@ size_t stlink_probe_usb(stlink_t **stdevs[]) { *stdevs = sldevs; - return slcnt; + return(slcnt); } void stlink_probe_usb_free(stlink_t ***stdevs, size_t size) { - if (stdevs == NULL || *stdevs == NULL || size == 0) return; - for (size_t n = 0; n < size; n++) stlink_close((*stdevs)[n]); + if (stdevs == NULL || *stdevs == NULL || size == 0) { return; } + + for (size_t n = 0; n < size; n++) { stlink_close((*stdevs)[n]); } + free(*stdevs); *stdevs = NULL; } diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index 3581eabf1..d11f17381 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -1,8 +1,6 @@ /* * File: usb.h * Author: karl - * - * Created on October 1, 2011, 11:29 PM */ #ifndef STLINK_USB_H @@ -29,51 +27,51 @@ extern "C" { #define STLINK_USB_PID_STLINK_V3S_PID 0x374f #define STLINK_USB_PID_STLINK_V3_2VCP_PID 0x3753 -#define STLINK_V1_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK ) +#define STLINK_V1_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK) #define STLINK_V2_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK_32L || \ - (pid) == STLINK_USB_PID_STLINK_32L_AUDIO || \ - (pid) == STLINK_USB_PID_STLINK_NUCLEO) + (pid) == STLINK_USB_PID_STLINK_32L_AUDIO || \ + (pid) == STLINK_USB_PID_STLINK_NUCLEO) -#define STLINK_V2_1_USB_PID(pid) ( (pid) == STLINK_USB_PID_STLINK_V2_1 ) +#define STLINK_V2_1_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK_V2_1) #define STLINK_V3_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK_V3_USBLOADER || \ - (pid) == STLINK_USB_PID_STLINK_V3E_PID || \ - (pid) == STLINK_USB_PID_STLINK_V3S_PID || \ - (pid) == STLINK_USB_PID_STLINK_V3_2VCP_PID ) + (pid) == STLINK_USB_PID_STLINK_V3E_PID || \ + (pid) == STLINK_USB_PID_STLINK_V3S_PID || \ + (pid) == STLINK_USB_PID_STLINK_V3_2VCP_PID) -#define STLINK_SUPPORTED_USB_PID(pid) ( STLINK_V1_USB_PID(pid) || \ - STLINK_V2_USB_PID(pid) || \ - STLINK_V2_1_USB_PID(pid) || \ - STLINK_V3_USB_PID(pid)) +#define STLINK_SUPPORTED_USB_PID(pid) (STLINK_V1_USB_PID(pid) || \ + STLINK_V2_USB_PID(pid) || \ + STLINK_V2_1_USB_PID(pid) || \ + STLINK_V3_USB_PID(pid)) #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 - struct stlink_libusb { - libusb_context* libusb_ctx; - libusb_device_handle* usb_handle; - unsigned int ep_req; - unsigned int ep_rep; - int protocoll; - unsigned int sg_transfer_idx; - unsigned int cmd_len; - }; +struct stlink_libusb { + libusb_context* libusb_ctx; + libusb_device_handle* usb_handle; + unsigned int ep_req; + unsigned int ep_rep; + int protocoll; + unsigned int sg_transfer_idx; + unsigned int cmd_len; +}; - /** - * Open a stlink - * @param verbose Verbosity loglevel - * @param reset Reset stlink programmer - * @param serial Serial number to search for, when NULL the first stlink found is opened (binary format) - * @retval NULL Error while opening the stlink - * @retval !NULL Stlink found and ready to use - */ - stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq); - size_t stlink_probe_usb(stlink_t **stdevs[]); - void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); +/** + * Open a stlink + * @param verbose Verbosity loglevel + * @param reset Reset stlink programmer + * @param serial Serial number to search for, when NULL the first stlink found is opened (binary format) + * @retval NULL Error while opening the stlink + * @retval !NULL Stlink found and ready to use + */ +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq); +size_t stlink_probe_usb(stlink_t **stdevs[]); +void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); #ifdef __cplusplus } #endif -#endif /* STLINK_USB_H */ +#endif // STLINK_USB_H diff --git a/src/win32/getopt/README.md b/src/win32/getopt/README.md index 9bf81fa73..2ec27c2d5 100644 --- a/src/win32/getopt/README.md +++ b/src/win32/getopt/README.md @@ -1,10 +1,11 @@ getopt_port =========== -[Kim Gräsman](http://grundlig.wordpress.com) +[Kim Gräsman](http://grundlig.wordpress.com) [@kimgr](http://twitter.com/kimgr) -An original implementation of `getopt` and `getopt_long` with limited GNU extensions. Provided under the BSD license, to allow non-GPL projects to use `getopt`-style command-line parsing. +An original implementation of `getopt` and `getopt_long` with limited GNU extensions. +Provided under the BSD license, to allow non-GPL projects to use `getopt`-style command-line parsing. So far only built with Visual C++, but has no inherently non-portable constructs. @@ -18,4 +19,4 @@ See also: * [XGetOpt](http://www.codeproject.com/Articles/1940/XGetopt-A-Unix-compatible-getopt-for-MFC-and-Win32) -- No `getopt_long` support. * [Free Getopt](https://sourceforge.net/projects/freegetopt/) -- No `getopt_long` support. -For license terms, see LICENSE.txt. \ No newline at end of file +For license terms, see LICENSE.txt. diff --git a/src/win32/getopt/getopt.c b/src/win32/getopt/getopt.c index 5dd45bff7..85e8804d8 100644 --- a/src/win32/getopt/getopt.c +++ b/src/win32/getopt/getopt.c @@ -11,196 +11,191 @@ const int optional_argument = 2; char* optarg; int optopt; -/* The variable optind [...] shall be initialized to 1 by the system. */ -int optind = 1; +int optind = 1; // The variable optind [...] shall be initialized to 1 by the system int opterr; static char* optcursor = NULL; /* Implemented based on [1] and [2] for optional arguments. - optopt is handled FreeBSD-style, per [3]. - Other GNU and FreeBSD extensions are purely accidental. - -[1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html -[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html -[3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE -*/ + * optopt is handled FreeBSD-style, per [3]. + * Other GNU and FreeBSD extensions are purely accidental. + * + * [1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html + * [2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html + * [3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE + */ int getopt(int argc, char* const argv[], const char* optstring) { - int optchar = -1; - const char* optdecl = NULL; - - optarg = NULL; - opterr = 0; - optopt = 0; - - /* Unspecified, but we need it to avoid overrunning the argv bounds. */ - if (optind >= argc) - goto no_more_optchars; - - /* If, when getopt() is called argv[optind] is a null pointer, getopt() - shall return -1 without changing optind. */ - if (argv[optind] == NULL) - goto no_more_optchars; - - /* If, when getopt() is called *argv[optind] is not the character '-', - getopt() shall return -1 without changing optind. */ - if (*argv[optind] != '-') - goto no_more_optchars; - - /* If, when getopt() is called argv[optind] points to the string "-", - getopt() shall return -1 without changing optind. */ - if (strcmp(argv[optind], "-") == 0) - goto no_more_optchars; - - /* If, when getopt() is called argv[optind] points to the string "--", - getopt() shall return -1 after incrementing optind. */ - if (strcmp(argv[optind], "--") == 0) { - ++optind; - goto no_more_optchars; - } - - if (optcursor == NULL || *optcursor == '\0') - optcursor = argv[optind] + 1; - - optchar = *optcursor; - - /* FreeBSD: The variable optopt saves the last known option character - returned by getopt(). */ - optopt = optchar; - - /* The getopt() function shall return the next option character (if one is - found) from argv that matches a character in optstring, if there is - one that matches. */ - optdecl = strchr(optstring, optchar); - if (optdecl) { - /* [I]f a character is followed by a colon, the option takes an - argument. */ - if (optdecl[1] == ':') { - optarg = ++optcursor; - if (*optarg == '\0') { - /* GNU extension: Two colons mean an option takes an - optional arg; if there is text in the current argv-element - (i.e., in the same word as the option name itself, for example, - "-oarg"), then it is returned in optarg, otherwise optarg is set - to zero. */ - if (optdecl[2] != ':') { - /* If the option was the last character in the string pointed to by - an element of argv, then optarg shall contain the next element - of argv, and optind shall be incremented by 2. If the resulting - value of optind is greater than argc, this indicates a missing - option-argument, and getopt() shall return an error indication. - - Otherwise, optarg shall point to the string following the - option character in that element of argv, and optind shall be - incremented by 1. - */ - if (++optind < argc) { - optarg = argv[optind]; - } else { - /* If it detects a missing option-argument, it shall return the - colon character ( ':' ) if the first character of optstring - was a colon, or a question-mark character ( '?' ) otherwise. - */ - optarg = NULL; - optchar = (optstring[0] == ':') ? ':' : '?'; - } - } else { - optarg = NULL; - } - } + int optchar = -1; + const char* optdecl = NULL; + + optarg = NULL; + opterr = 0; + optopt = 0; + + /* Unspecified, but we need it to avoid overrunning the argv bounds. */ + if (optind >= argc) { goto no_more_optchars; } + + /* If, when getopt() is called argv[optind] is a null pointer, + * getopt() shall return -1 without changing optind. + */ + if (argv[optind] == NULL) { goto no_more_optchars; } + + /* If, when getopt() is called *argv[optind] is not the character '-', + * getopt() shall return -1 without changing optind. + */ + if (*argv[optind] != '-') { goto no_more_optchars; } + + /* If, when getopt() is called argv[optind] points to the string "-", + * getopt() shall return -1 without changing optind. + */ + if (strcmp(argv[optind], "-") == 0) { goto no_more_optchars; } + + /* If, when getopt() is called argv[optind] points to the string "--", + * getopt() shall return -1 after incrementing optind. + */ + if (strcmp(argv[optind], "--") == 0) { + ++optind; + goto no_more_optchars; + } - optcursor = NULL; + if (optcursor == NULL || *optcursor == '\0') { optcursor = argv[optind] + 1; } + + optchar = *optcursor; + + /* FreeBSD: The variable optopt saves the last known option character returned by getopt(). */ + optopt = optchar; + + /* The getopt() function shall return the next option character (if one is found) + * from argv that matches a character in optstring, if there is one that matches. + */ + optdecl = strchr(optstring, optchar); + + if (optdecl) { + /* [I]f a character is followed by a colon, the option takes an argument. */ + if (optdecl[1] == ':') { + optarg = ++optcursor; + + if (*optarg == '\0') { + /* GNU extension: Two colons mean an option takes an optional arg; + * if there is text in the current argv-element (i.e., in the same word + * as the option name itself, for example, "-oarg"), then it is returned + * in optarg, otherwise optarg is set to zero. + */ + if (optdecl[2] != ':') { + /* If the option was the last character in the string pointed to by + * an element of argv, then optarg shall contain the next element + * of argv, and optind shall be incremented by 2. If the resulting + * value of optind is greater than argc, this indicates a missing + * option-argument, and getopt() shall return an error indication. + * Otherwise, optarg shall point to the string following the + * option character in that element of argv, and optind shall be + * incremented by 1. + */ + if (++optind < argc) { + optarg = argv[optind]; + } else { + /* If it detects a missing option-argument, it shall return the + * colon character ( ':' ) if the first character of optstring + * was a colon, or a question-mark character ( '?' ) otherwise. + */ + optarg = NULL; + optchar = (optstring[0] == ':') ? ':' : '?'; + } + } else { + optarg = NULL; + } + } + + optcursor = NULL; + } + } else { + /* If getopt() encounters an option character that is not contained in + * optstring, it shall return the question-mark ( '?' ) character. + */ + optchar = '?'; } - } else { - /* If getopt() encounters an option character that is not contained in - optstring, it shall return the question-mark ( '?' ) character. */ - optchar = '?'; - } - if (optcursor == NULL || *++optcursor == '\0') - ++optind; + if (optcursor == NULL || *++optcursor == '\0') { ++optind; } - return optchar; + return(optchar); no_more_optchars: - optcursor = NULL; - return -1; + optcursor = NULL; + return(-1); } -/* Implementation based on [1]. - -[1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html -*/ -int getopt_long(int argc, char* const argv[], const char* optstring, - const struct option* longopts, int* longindex) { - const struct option* o = longopts; - const struct option* match = NULL; - int num_matches = 0; - size_t argument_name_length = 0; - const char* current_argument = NULL; - int retval = -1; - - optarg = NULL; - optopt = 0; - - if (optind >= argc) - return -1; - - if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0) - return getopt(argc, argv, optstring); - - /* It's an option; starts with -- and is longer than two chars. */ - current_argument = argv[optind] + 2; - argument_name_length = strcspn(current_argument, "="); - for (; o->name; ++o) { - if (strncmp(o->name, current_argument, argument_name_length) == 0) { - match = o; - ++num_matches; +/* Implementation based on http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html */ +int getopt_long(int argc, + char* const argv[], + const char* optstring, + const struct option* longopts, + int* longindex) { + const struct option* o = longopts; + const struct option* match = NULL; + int num_matches = 0; + size_t argument_name_length = 0; + const char* current_argument = NULL; + int retval = -1; + + optarg = NULL; + optopt = 0; + + if (optind >= argc) { return(-1); } + + if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0) { + return(getopt(argc, argv, optstring)); } - } - - if (num_matches == 1) { - /* If longindex is not NULL, it points to a variable which is set to the - index of the long option relative to longopts. */ - if (longindex) - *longindex = (match - longopts); - - /* If flag is NULL, then getopt_long() shall return val. - Otherwise, getopt_long() returns 0, and flag shall point to a variable - which shall be set to val if the option is found, but left unchanged if - the option is not found. */ - if (match->flag) - *(match->flag) = match->val; - - retval = match->flag ? 0 : match->val; - - if (match->has_arg != no_argument) { - optarg = strchr(argv[optind], '='); - if (optarg != NULL) - ++optarg; - - if (match->has_arg == required_argument) { - /* Only scan the next argv for required arguments. Behavior is not - specified, but has been observed with Ubuntu and Mac OSX. */ - if (optarg == NULL && ++optind < argc) { - optarg = argv[optind]; + + // it's an option; starts with -- and is longer than two chars + current_argument = argv[optind] + 2; + argument_name_length = strcspn(current_argument, "="); + + for ( ; o->name; ++o) + if (strncmp(o->name, current_argument, argument_name_length) == 0) { + match = o; + ++num_matches; } - if (optarg == NULL) - retval = ':'; - } - } else if (strchr(argv[optind], '=')) { - /* An argument was provided to a non-argument option. - I haven't seen this specified explicitly, but both GNU and BSD-based - implementations show this behavior. - */ - retval = '?'; + + if (num_matches == 1) { + /* If longindex is not NULL, it points to a variable which is set to the + * index of the long option relative to longopts. + */ + if (longindex) { *longindex = (match - longopts); } + + /* If flag is NULL, then getopt_long() shall return val. + * Otherwise, getopt_long() returns 0, and flag shall point to a variable + * which shall be set to val if the option is found, but left unchanged if + * the option is not found. + */ + if (match->flag) { *(match->flag) = match->val; } + + retval = match->flag ? 0 : match->val; + + if (match->has_arg != no_argument) { + optarg = strchr(argv[optind], '='); + + if (optarg != NULL) { ++optarg; } + + if (match->has_arg == required_argument) { + /* Only scan the next argv for required arguments. Behavior is not + specified, but has been observed with Ubuntu and macOS. */ + if (optarg == NULL && ++optind < argc) { optarg = argv[optind]; } + + if (optarg == NULL) { retval = ':'; } + } + } else if (strchr(argv[optind], '=')) { + /* An argument was provided to a non-argument option. + * I haven't seen this specified explicitly, but both GNU and BSD-based + * implementations show this behavior. + */ + retval = '?'; + } + } else { + // unknown option or ambiguous match + retval = '?'; } - } else { - /* Unknown option or ambiguous match. */ - retval = '?'; - } - ++optind; - return retval; + ++optind; + return(retval); } diff --git a/src/win32/getopt/getopt.h b/src/win32/getopt/getopt.h index bc189b9d4..3aaf73bed 100644 --- a/src/win32/getopt/getopt.h +++ b/src/win32/getopt/getopt.h @@ -20,16 +20,19 @@ extern char* optarg; extern int optind, opterr, optopt; struct option { - const char* name; - int has_arg; - int* flag; - int val; + const char* name; + int has_arg; + int* flag; + int val; }; int getopt(int argc, char* const argv[], const char* optstring); -int getopt_long(int argc, char* const argv[], - const char* optstring, const struct option* longopts, int* longindex); +int getopt_long(int argc, + char* const argv[], + const char* optstring, + const struct option* longopts, + int* longindex); #if defined(__cplusplus) } diff --git a/src/win32/mmap.c b/src/win32/mmap.c index 60bb440e9..d702a78f6 100644 --- a/src/win32/mmap.c +++ b/src/win32/mmap.c @@ -5,34 +5,34 @@ #include "mmap.h" -void *mmap (void *addr, size_t len, int prot, int flags, int fd, long long offset) { - +void *mmap (void *addr, size_t len, int prot, int flags, int fd, long long offset) { void *buf; ssize_t count; - if ( addr || fd == -1 || (prot & PROT_WRITE)) return MAP_FAILED; + if ( addr || fd == -1 || (prot & PROT_WRITE)) { return(MAP_FAILED); } buf = malloc(len); - if ( NULL == buf ) return MAP_FAILED; - if (lseek(fd,offset,SEEK_SET) != offset) { + if ( NULL == buf ) { return(MAP_FAILED); } + + if (lseek(fd, offset, SEEK_SET) != offset) { free(buf); - return MAP_FAILED; + return(MAP_FAILED); } count = read(fd, buf, len); if (count != (ssize_t)len) { free (buf); - return MAP_FAILED; + return(MAP_FAILED); } - return buf; + return(buf); (void)flags; } int munmap (void *addr, size_t len) { free (addr); - return 0; + return(0); (void)len; } diff --git a/src/win32/unistd/unistd.h b/src/win32/unistd/unistd.h index 0cdb9af7b..ac9d0add3 100644 --- a/src/win32/unistd/unistd.h +++ b/src/win32/unistd/unistd.h @@ -27,7 +27,7 @@ #define srandom srand #define random rand -/* values for the second argument to access. These may be OR'd together. */ +/* Values for the second argument to access. These may be OR'd together. */ #define R_OK 4 // Test for read permission #define W_OK 2 // Test for write permission // #define X_OK 1 // execute permission - unsupported in windows @@ -43,24 +43,27 @@ #define chdir _chdir #define isatty _isatty #define lseek _lseek -/* read, write, and close are NOT being defined here, + +/* + * Read, write, and close are NOT being defined here, * because while there are file handle specific versions for Windows, they probably don't work for sockets. - * You need to look at your app and consider whether to call e.g. closesocket(). */ + * You need to look at your app and consider whether to call e.g. closesocket(). + */ #define ssize_t int -#define STDIN_FILENO 0 +#define STDIN_FILENO 0 #define STDOUT_FILENO 1 #define STDERR_FILENO 2 // should be in some equivalent to -typedef __int8 int8_t; -typedef __int16 int16_t; -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int8 uint8_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int64 uint64_t; +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; #ifndef STLINK_HAVE_UNISTD_H int usleep(unsigned int waitTime); diff --git a/src/win32/win32_socket.c b/src/win32/win32_socket.c index 18f2351f8..de1c7e112 100644 --- a/src/win32/win32_socket.c +++ b/src/win32/win32_socket.c @@ -25,16 +25,20 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) { FD_ZERO(&ifds); FD_ZERO(&ofds); FD_ZERO(&efds); + for (i = 0, op = ip = 0; i < nfds; ++i) { fds[i].revents = 0; + if (fds[i].events & (POLLIN | POLLPRI)) { ip = &ifds; FD_SET(fds[i].fd, ip); } + if (fds[i].events & POLLOUT) { op = &ofds; FD_SET(fds[i].fd, op); } + FD_SET(fds[i].fd, &efds); } @@ -53,7 +57,7 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) { #ifdef DEBUG_POLL printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n", - (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op); + (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op); #endif rc = select(0, ip, op, &efds, toptr); @@ -62,33 +66,41 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) { printf("Exiting select rc=%d\n", rc); #endif - if (rc <= 0) return rc; + if (rc <= 0) { return(rc); } if (rc > 0) { for ( i = 0; i < nfds; ++i) { int fd = fds[i].fd; - if (fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) + + if (fds[i].events & (POLLIN | POLLPRI) && FD_ISSET(fd, &ifds)) { fds[i].revents |= POLLIN; - if (fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) + } + + if (fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) { fds[i].revents |= POLLOUT; - if (FD_ISSET(fd, &efds)) - /* Some error was detected ... should be some way to know. */ + } + + if (FD_ISSET(fd, &efds)) { + // Some error was detected ... should be some way to know fds[i].revents |= POLLHUP; + } #ifdef DEBUG_POLL printf("%d %d %d revent = %x\n", - FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds), - fds[i].revents - ); + FD_ISSET(fd, &ifds), + FD_ISSET(fd, &ofds), + FD_ISSET(fd, &efds), + fds[i].revents); #endif } } - return rc; + + return(rc); } static void set_connect_errno(int winsock_err) { - switch(winsock_err) { + switch (winsock_err) { case WSAEINVAL: case WSAEALREADY: case WSAEWOULDBLOCK: @@ -101,7 +113,7 @@ static void set_connect_errno(int winsock_err) { } static void set_socket_errno(int winsock_err) { - switch(winsock_err) { + switch (winsock_err) { case WSAEWOULDBLOCK: errno = EAGAIN; break; @@ -111,71 +123,81 @@ static void set_socket_errno(int winsock_err) { } } -/* - * A wrapper around the socket() function. +/* A wrapper around the socket() function. * The purpose of this wrapper is to ensure that the global errno symbol is set if an error occurs, * even if we are using winsock. */ SOCKET win32_socket(int domain, int type, int protocol) { SOCKET fd = socket(domain, type, protocol); - if (fd == INVALID_SOCKET) set_socket_errno(WSAGetLastError()); - return fd; + + if (fd == INVALID_SOCKET) { set_socket_errno(WSAGetLastError()); } + + return(fd); } -/* - * A wrapper around the connect() function. +/* A wrapper around the connect() function. * The purpose of this wrapper is to ensure that the global errno symbol is set if an error occurs, * even if we are using winsock. */ int win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len) { int rc = connect(fd, addr, addr_len); assert(rc == 0 || rc == SOCKET_ERROR); - if (rc == SOCKET_ERROR) set_connect_errno(WSAGetLastError()); - return rc; + + if (rc == SOCKET_ERROR) { set_connect_errno(WSAGetLastError()); } + + return(rc); } -/* - * A wrapper around the accept() function. +/* A wrapper around the accept() function. * The purpose of this wrapper is to ensure that the global errno symbol is set if an error occurs, * even if we are using winsock. */ SOCKET win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len) { SOCKET newfd = accept(fd, addr, addr_len); + if (newfd == INVALID_SOCKET) { set_socket_errno(WSAGetLastError()); newfd = (SOCKET)-1; } - return newfd; + + return(newfd); } -/* - * A wrapper around the shutdown() function. +/* A wrapper around the shutdown() function. * The purpose of this wrapper is to ensure that the global errno symbol is set if an error occurs, * even if we are using winsock. */ int win32_shutdown(SOCKET fd, int mode) { int rc = shutdown(fd, mode); assert(rc == 0 || rc == SOCKET_ERROR); - if (rc == SOCKET_ERROR) set_socket_errno(WSAGetLastError()); - return rc; + + if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } + + return(rc); } int win32_close_socket(SOCKET fd) { int rc = closesocket(fd); - if (rc == SOCKET_ERROR) set_socket_errno(WSAGetLastError()); - return rc; + + if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } + + return(rc); } ssize_t win32_write_socket(SOCKET fd, void *buf, int n) { int rc = send(fd, buf, n, 0); - if (rc == SOCKET_ERROR) set_socket_errno(WSAGetLastError()); - return rc; + + if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } + + return(rc); } ssize_t win32_read_socket(SOCKET fd, void *buf, int n) { int rc = recv(fd, buf, n, 0); - if (rc == SOCKET_ERROR) set_socket_errno(WSAGetLastError()); - return rc; + + if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } + + return(rc); } @@ -185,41 +207,45 @@ char * win32_strtok_r(char *s, const char *delim, char **lasts) { char *tok; - if (s == NULL && (s = *lasts) == NULL) return (NULL); + if (s == NULL && (s = *lasts) == NULL) { return (NULL); } - // Skip (span) leading delimiters (s += strspn(s, delim), sort of). + // skip (span) leading delimiters (s += strspn(s, delim), sort of). cont: c = *s++; - for (spanp = (char *)delim; (sc = *spanp++) != 0;) { - if (c == sc) - goto cont; - } + + for (spanp = (char *)delim; (sc = *spanp++) != 0;) + if (c == sc) { goto cont; } + if (c == 0) { // no non-delimiter characters *lasts = NULL; return (NULL); } + tok = s - 1; - /* - * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + /* Scan token (scan for delimiters: s += strcspn(s, delim), sort of). * Note that delim must have one NUL; we stop if we see that, too. */ - for (;;) { + for ( ; ;) { c = *s++; spanp = (char *)delim; - do { + + do if ((sc = *spanp++) == c) { if (c == 0) { s = NULL; } else { s[-1] = 0; } + *lasts = s; - return (tok); + return(tok); } - } while (sc != 0); + + while (sc != 0); } + // NOT REACHED } @@ -229,22 +255,29 @@ char *win32_strsep (char **stringp, const char *delim) { register int c, sc; char *tok; - if ((s = *stringp) == NULL) return (NULL); - for (tok = s;;) { + if ((s = *stringp) == NULL) { + return(NULL); + } + + for (tok = s; ;) { c = *s++; spanp = delim; - do { + + do if ((sc = *spanp++) == c) { if (c == 0) { s = NULL; } else { s[-1] = 0; } + *stringp = s; - return (tok); + return(tok); } - } while (sc != 0); + + while (sc != 0); } + // NOT REACHED } @@ -264,18 +297,19 @@ int usleep(unsigned int waitTime) { WaitForSingleObject(timer, INFINITE); CloseHandle(timer); - return 0; + return(0); } + LARGE_INTEGER perf_cnt, start, now; QueryPerformanceFrequency(&perf_cnt); QueryPerformanceCounter(&start); - do { - QueryPerformanceCounter((LARGE_INTEGER*) &now); - } while ((now.QuadPart - start.QuadPart) / (float)perf_cnt.QuadPart * 1000 * 1000 < waitTime); + do + QueryPerformanceCounter((LARGE_INTEGER*)&now); + while ((now.QuadPart - start.QuadPart) / (float)perf_cnt.QuadPart * 1000 * 1000 < waitTime); - return 0; + return(0); } #endif diff --git a/src/win32/win32_socket.h b/src/win32/win32_socket.h index d2a3ac38c..ea1a39c93 100644 --- a/src/win32/win32_socket.h +++ b/src/win32/win32_socket.h @@ -62,8 +62,8 @@ SOCKET win32_accept(SOCKET, struct sockaddr*, socklen_t *); int win32_shutdown(SOCKET, int); int win32_close_socket(SOCKET fd); -#define strtok_r(x, y, z) win32_strtok_r(x, y, z) -#define strsep(x,y) win32_strsep(x,y) +#define strtok_r(x, y, z) win32_strtok_r(x, y, z) +#define strsep(x,y) win32_strsep(x,y) char *win32_strtok_r(char *s, const char *delim, char **lasts); char *win32_strsep(char **stringp, const char *delim); diff --git a/tests/flash.c b/tests/flash.c index d47b3564d..a8d479b2d 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -6,7 +6,7 @@ #include #if defined(_MSC_VER) - #include +#include #endif struct Test { @@ -37,25 +37,25 @@ static bool execute_test(const struct Test * test) { /* parse (tokenize) the test command line */ #if defined(_MSC_VER) - char *cmd_line = alloca(strlen(test->cmd_line) + 1); + char *cmd_line = alloca(strlen(test->cmd_line) + 1); #else - char cmd_line[strlen(test->cmd_line) + 1]; + char cmd_line[strlen(test->cmd_line) + 1]; #endif strcpy(cmd_line, test->cmd_line); for (char * tok = strtok(cmd_line, " "); tok; tok = strtok(NULL, " ")) { - if ((size_t)ac >= sizeof(av)/sizeof(av[0])) - return false; + if ((size_t)ac >= sizeof(av) / sizeof(av[0])) return(false); + av[ac] = tok; ++ac; } - /* call */ + /* Call */ struct flash_opts opts; int res = flash_get_opts(&opts, ac, av); - /* compare results */ + /* Compare results */ bool ret = (res == test->res); if (ret && (res == 0)) { @@ -71,87 +71,87 @@ static bool execute_test(const struct Test * test) { } printf("[%s] (%d) %s\n", ret ? "OK" : "ERROR", res, test->cmd_line); - return ret; + return(ret); } static struct Test tests[] = { { "", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset read test.bin 0x80000000 0x1000", 0, - { .cmd = FLASH_CMD_READ, - .serial = { 0 }, - .filename = "test.bin", - .addr = 0x80000000, - .size = 0x1000, - .reset = 1, - .log_level = DEBUG_LOG_LEVEL, - .freq = 0, - .format = FLASH_FORMAT_BINARY } + { .cmd = FLASH_CMD_READ, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0x1000, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } }, { "--debug --reset write test.bin 0x80000000", 0, - { .cmd = FLASH_CMD_WRITE, - .serial = { 0 }, - .filename = "test.bin", - .addr = 0x80000000, - .size = 0, - .reset = 1, - .log_level = DEBUG_LOG_LEVEL, - .freq = 0, - .format = FLASH_FORMAT_BINARY } + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } }, { "--debug --freq 5k --reset write test.bin 0x80000000", 0, - { .cmd = FLASH_CMD_WRITE, - .serial = { 0 }, - .filename = "test.bin", - .addr = 0x80000000, - .size = 0, - .reset = 1, - .log_level = DEBUG_LOG_LEVEL, - .freq = 5, - .format = FLASH_FORMAT_BINARY } + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 5, + .format = FLASH_FORMAT_BINARY } }, { "--debug --freq 15K --reset write test.bin 0x80000000", 0, - { .cmd = FLASH_CMD_WRITE, - .serial = { 0 }, - .filename = "test.bin", - .addr = 0x80000000, - .size = 0, - .reset = 1, - .log_level = DEBUG_LOG_LEVEL, - .freq = 15, - .format = FLASH_FORMAT_BINARY } + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 15, + .format = FLASH_FORMAT_BINARY } }, { "--debug --freq=5k --reset write test.bin 0x80000000", 0, - { .cmd = FLASH_CMD_WRITE, - .serial = { 0 }, - .filename = "test.bin", - .addr = 0x80000000, - .size = 0, - .reset = 1, - .log_level = DEBUG_LOG_LEVEL, - .freq = 5, - .format = FLASH_FORMAT_BINARY } + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 5, + .format = FLASH_FORMAT_BINARY } }, { "--debug --freq=6k --reset write test.bin 0x80000000", -1, - { .cmd = FLASH_CMD_WRITE, - .serial = { 0 }, - .filename = "test.bin", - .addr = 0x80000000, - .size = 0, - .reset = 1, - .log_level = DEBUG_LOG_LEVEL, - .freq = 6, - .format = FLASH_FORMAT_BINARY } + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 6, + .format = FLASH_FORMAT_BINARY } }, { "--debug --reset read test.bin 0x80000000 1000", 0, - { .cmd = FLASH_CMD_READ, - .serial = { 0 }, - .filename = "test.bin", - .addr = 0x80000000, - .size = 1000, - .reset = 1, - .log_level = DEBUG_LOG_LEVEL, - .freq = 0, - .format = FLASH_FORMAT_BINARY } + { .cmd = FLASH_CMD_READ, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 1000, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } }, { "--debug --reset read test.bin 0x80000000 1k", 0, { .cmd = FLASH_CMD_READ, @@ -176,71 +176,72 @@ static struct Test tests[] = { .format = FLASH_FORMAT_BINARY } }, { "--debug --reset write test.bin 0x80000000", 0, - { .cmd = FLASH_CMD_WRITE, - .serial = { 0 }, - .filename = "test.bin", - .addr = 0x80000000, - .size = 0, - .reset = 1, - .log_level = DEBUG_LOG_LEVEL, - .freq = 0, - .format = FLASH_FORMAT_BINARY } + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } }, { "erase", 0, - { .cmd = FLASH_CMD_ERASE, - .serial = { 0 }, - .filename = NULL, - .addr = 0, - .size = 0, - .reset = 0, - .log_level = STND_LOG_LEVEL, - .freq = 0, - .format = FLASH_FORMAT_BINARY } + { .cmd = FLASH_CMD_ERASE, + .serial = { 0 }, + .filename = NULL, + .addr = 0, + .size = 0, + .reset = 0, + .log_level = STND_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } }, { "--debug --reset --format=ihex write test.hex", 0, - { .cmd = FLASH_CMD_WRITE, - .serial = { 0 }, - .filename = "test.hex", - .addr = 0, - .size = 0, - .reset = 1, - .log_level = DEBUG_LOG_LEVEL, - .freq = 0, - .format = FLASH_FORMAT_IHEX } + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.hex", + .addr = 0, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_IHEX } }, { "--debug --reset --format=binary write test.hex", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset --format=ihex write test.hex 0x80000000", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset write test.hex sometext", -1, FLASH_OPTS_INITIALIZER }, { "--serial A1020304 erase sometext", -1, FLASH_OPTS_INITIALIZER }, { "--serial A1020304 erase", 0, - { .cmd = FLASH_CMD_ERASE, - .serial = "\xA1\x02\x03\x04", - .filename = NULL, - .addr = 0, - .size = 0, - .reset = 0, - .log_level = STND_LOG_LEVEL, - .freq = 0, - .format = FLASH_FORMAT_BINARY } + { .cmd = FLASH_CMD_ERASE, + .serial = "\xA1\x02\x03\x04", + .filename = NULL, + .addr = 0, + .size = 0, + .reset = 0, + .log_level = STND_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } }, { "--serial=A1020304 erase", 0, - { .cmd = FLASH_CMD_ERASE, - .serial = "\xA1\x02\x03\x04", - .filename = NULL, - .addr = 0, - .size = 0, - .reset = 0, - .log_level = STND_LOG_LEVEL, - .freq = 0, - .format = FLASH_FORMAT_BINARY } + { .cmd = FLASH_CMD_ERASE, + .serial = "\xA1\x02\x03\x04", + .filename = NULL, + .addr = 0, + .size = 0, + .reset = 0, + .log_level = STND_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } }, }; int main() { bool allOk = true; - for (size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) { + + for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) if (!execute_test(&tests[i])) allOk = false; - } + return (allOk ? 0 : 1); } diff --git a/tests/sg.c b/tests/sg.c index 1af177174..745df845f 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -1,9 +1,3 @@ -/* - * File: test_main.c - * - * main() ripped out of old stlink-hw.c - */ - #include #include #include @@ -11,7 +5,7 @@ #include #if defined(_MSC_VER) - #define __attribute__(x) +#define __attribute__(x) #endif static void __attribute__((unused)) mark_buf(stlink_t *sl) { @@ -30,28 +24,28 @@ static void __attribute__((unused)) mark_buf(stlink_t *sl) { } -int main(void) { +int main(void) { // main() ripped out of old stlink-hw.c /* Avoid unused parameter warning */ // set scpi lib debug level: 0 for no debug info, 10 for lots fputs( - "\nUsage: stlink-access-test [anything at all] ...\n" - "\n*** Notice: The stlink firmware violates the USB standard.\n" - "*** Because we just use libusb, we can just tell the kernel's\n" - "*** driver to simply ignore the device...\n" - "*** Unplug the stlink and execute once as root:\n" - "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n\n", - stderr); + "\nUsage: stlink-access-test [anything at all] ...\n" + "\n*** Notice: The stlink firmware violates the USB standard.\n" + "*** Because we just use libusb, we can just tell the kernel's\n" + "*** driver to simply ignore the device...\n" + "*** Unplug the stlink and execute once as root:\n" + "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n\n", + stderr); stlink_t *sl = stlink_v1_open(99, 1); - if (sl == NULL) - return 0; + + if (sl == NULL) return(0); // we are in mass mode, go to swd stlink_enter_swd_mode(sl); stlink_current_mode(sl); stlink_core_id(sl); stlink_status(sl); - //stlink_force_debug(sl); + // stlink_force_debug(sl); stlink_reset(sl); stlink_status(sl); // core system control block @@ -75,8 +69,8 @@ int main(void) { #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) // pin 8 - #define LED_GREEN (1<<9) // pin 9 + #define LED_BLUE (1 << 8) // pin 8 + #define LED_GREEN (1 << 9) // pin 9 stlink_read_mem32(sl, GPIOC_CRH, 4); uint32_t io_conf = read_uint32(sl->q_buf, 0); DLOG("GPIOC_CRH = 0x%08x\n", io_conf); @@ -86,17 +80,19 @@ int main(void) { stlink_write_mem32(sl, GPIOC_CRH, 4); memset(sl->q_buf, 0, sizeof(sl->q_buf)); + for (int i = 0; i < 100; i++) { write_uint32(sl->q_buf, LED_BLUE | LED_GREEN); stlink_write_mem32(sl, GPIOC_ODR, 4); - //stlink_read_mem32(sl, 0x4001100c, 4); - //DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); + // stlink_read_mem32(sl, 0x4001100c, 4); + // DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); usleep(100 * 1000); memset(sl->q_buf, 0, sizeof(sl->q_buf)); stlink_write_mem32(sl, GPIOC_ODR, 4); // PC lo usleep(100 * 1000); } + write_uint32(sl->q_buf, io_conf); // set old state #endif @@ -104,10 +100,10 @@ int main(void) { // TODO rtfm: stlink doesn't have flash write routines // writing to the flash area confuses the fw for the next read access - //stlink_read_mem32(sl, 0, 1024*6); + // stlink_read_mem32(sl, 0, 1024*6); // flash 0x08000000 128kB fputs("++++++++++ read a flash at 0x0800 0000\n", stderr); - stlink_read_mem32(sl, 0x08000000, 1024 * 6); //max 6kB + stlink_read_mem32(sl, 0x08000000, 1024 * 6); // max 6kB clear_buf(sl); stlink_read_mem32(sl, 0x08000c00, 5); stlink_read_mem32(sl, 0x08000c00, 4); @@ -122,9 +118,9 @@ int main(void) { fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); mark_buf(sl); - //stlink_write_mem8(sl, 0x20000000, 16); - //stlink_write_mem8(sl, 0x20000000, 1); - //stlink_write_mem8(sl, 0x20000001, 1); + // stlink_write_mem8(sl, 0x20000000, 16); + // stlink_write_mem8(sl, 0x20000000, 1); + // stlink_write_mem8(sl, 0x20000001, 1); stlink_write_mem8(sl, 0x2000000b, 3); stlink_read_mem32(sl, 0x20000000, 16); #endif @@ -157,7 +153,7 @@ int main(void) { stlink_read_mem32(sl, 0x20000000, 64); mark_buf(sl); - stlink_write_mem32(sl, 0x20000000, 1024 * 8); //8kB + stlink_write_mem32(sl, 0x20000000, 1024 * 8); // 8kB stlink_read_mem32(sl, 0x20000000, 1024 * 6); stlink_read_mem32(sl, 0x20000000 + 1024 * 6, 1024 * 2); #endif @@ -208,7 +204,7 @@ int main(void) { stlink_close(sl); #endif - //fflush(stderr); - //fflush(stdout); - return EXIT_SUCCESS; + // fflush(stderr); + // fflush(stdout); + return(EXIT_SUCCESS); } diff --git a/tests/usb.c b/tests/usb.c index ce72e24a5..03c135f00 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -3,14 +3,12 @@ #include #include -static void usage(void) -{ +static void usage(void) { puts("test-usb --reset"); puts("test-usb --no-reset"); } int main(int ac, char** av) { - stlink_t* sl; struct stlink_reg regs; int reset = 0; @@ -18,15 +16,18 @@ int main(int ac, char** av) { if (ac == 2) { if (strcmp(av[1], "--reset") == 0) reset = 2; - if (strcmp(av[1], "--no-reset") == 0) + + if (strcmp(av[1], "--no-reset") == 0) reset = 1; } + if (reset == 0) { usage(); - return 0; + return(0); } sl = stlink_open_usb(10, reset, NULL, 0); + if (sl != NULL) { printf("-- version\n"); stlink_version(sl); @@ -47,6 +48,7 @@ int main(int ac, char** av) { printf("-- core_id: %#x\n", sl->core_id); cortex_m3_cpuid_t cpuid; + if (stlink_cpu_id(sl, &cpuid)) { printf("Failed reading stlink_cpu_id\n"); } else { @@ -57,6 +59,7 @@ int main(int ac, char** av) { printf("-- read_sram\n"); static const uint32_t sram_base = STM32_SRAM_BASE; uint32_t off; + for (off = 0; off < 16; off += 4) stlink_read_mem32(sl, sram_base + off, 4); @@ -64,24 +67,24 @@ int main(int ac, char** av) { stlink_read_mem32(sl, STLINK_REG_CM3_FP_CTRL, 4); // no idea what reg this is... - //stlink_read_mem32(sl, 0xe000ed90, 4); + // stlink_read_mem32(sl, 0xe000ed90, 4); // no idea what register this is... - //stlink_read_mem32(sl, 0xe000edf0, 4); + // stlink_read_mem32(sl, 0xe000edf0, 4); // offset 0xC into TIM11 register? TIMx_DIER? - //stlink_read_mem32(sl, 0x4001100c, 4); + // stlink_read_mem32(sl, 0x4001100c, 4); - /* Test 32 bit Write */ - write_uint32(sl->q_buf,0x01234567); - stlink_write_mem32(sl,0x200000a8,4); - write_uint32(sl->q_buf,0x89abcdef); - stlink_write_mem32(sl,0x200000ac, 4); + /* Test 32 bit write */ + write_uint32(sl->q_buf, 0x01234567); + stlink_write_mem32(sl, 0x200000a8, 4); + write_uint32(sl->q_buf, 0x89abcdef); + stlink_write_mem32(sl, 0x200000ac, 4); stlink_read_mem32(sl, 0x200000a8, 4); stlink_read_mem32(sl, 0x200000ac, 4); /* Test 8 bit write */ - write_uint32(sl->q_buf,0x01234567); - stlink_write_mem8(sl,0x200001a8,3); - write_uint32(sl->q_buf,0x89abcdef); + write_uint32(sl->q_buf, 0x01234567); + stlink_write_mem8(sl, 0x200001a8, 3); + write_uint32(sl->q_buf, 0x89abcdef); stlink_write_mem8(sl, 0x200001ac, 3); stlink_read_mem32(sl, 0x200001a8, 4); stlink_read_mem32(sl, 0x200001ac, 4); @@ -96,8 +99,8 @@ int main(int ac, char** av) { stlink_write_reg(sl, 0x01234567, 3); stlink_write_reg(sl, 0x89abcdef, 4); stlink_write_reg(sl, 0x12345678, 15); - for (off = 0; off < 21; off += 1) - stlink_read_reg(sl, off, ®s); + + for (off = 0; off < 21; off += 1) stlink_read_reg(sl, off, ®s); stlink_read_all_regs(sl, ®s); @@ -115,5 +118,6 @@ int main(int ac, char** av) { stlink_close(sl); } - return 0; + + return(0); } From 06aec5b541ac0e97125dad5e14ce0f8e72e5e6c4 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 13 Jun 2020 21:45:05 +0200 Subject: [PATCH 0972/1435] Code style fixes for win32_socket. --- src/win32/win32_socket.c | 12 ++++++------ src/win32/win32_socket.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/win32/win32_socket.c b/src/win32/win32_socket.c index de1c7e112..9138a7679 100644 --- a/src/win32/win32_socket.c +++ b/src/win32/win32_socket.c @@ -231,7 +231,7 @@ char * win32_strtok_r(char *s, const char *delim, char **lasts) { c = *s++; spanp = (char *)delim; - do + do { if ((sc = *spanp++) == c) { if (c == 0) { s = NULL; @@ -243,7 +243,7 @@ char * win32_strtok_r(char *s, const char *delim, char **lasts) { return(tok); } - while (sc != 0); + } while (sc != 0); } // NOT REACHED @@ -263,7 +263,7 @@ char *win32_strsep (char **stringp, const char *delim) { c = *s++; spanp = delim; - do + do { if ((sc = *spanp++) == c) { if (c == 0) { s = NULL; @@ -275,7 +275,7 @@ char *win32_strsep (char **stringp, const char *delim) { return(tok); } - while (sc != 0); + } while (sc != 0); } // NOT REACHED @@ -305,9 +305,9 @@ int usleep(unsigned int waitTime) { QueryPerformanceFrequency(&perf_cnt); QueryPerformanceCounter(&start); - do + do { QueryPerformanceCounter((LARGE_INTEGER*)&now); - while ((now.QuadPart - start.QuadPart) / (float)perf_cnt.QuadPart * 1000 * 1000 < waitTime); + } while ((now.QuadPart - start.QuadPart) / (float)perf_cnt.QuadPart * 1000 * 1000 < waitTime); return(0); } diff --git a/src/win32/win32_socket.h b/src/win32/win32_socket.h index ea1a39c93..5f8f09589 100644 --- a/src/win32/win32_socket.h +++ b/src/win32/win32_socket.h @@ -20,9 +20,9 @@ #pragma warning(pop) #endif -/* winsock doesn't feature poll(), so there is a version implemented in terms of select() in mingw.c. +/* winsock doesn't feature poll(), so there is a version implemented in terms of select() in win32_socket.c. * The following definitions are copied from linux man pages. - * A poll() macro is defined to call the version in mingw.c. + * A poll() macro is defined to call the version in win32_socket.c. */ #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0600) From d473c99f10ec10ca525c9cbe9b0e3d3c36bf5af7 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 14 Jun 2020 17:20:49 +0200 Subject: [PATCH 0973/1435] Fix for external CMAKE_MODULE_PATH (Closes #962) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 52f6867f4..59b9d963c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.4.2) cmake_policy(SET CMP0042 NEW) -set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) From ffe6240012d7cb83749bf00baf0e300cf7cab2ea Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 15 Jun 2020 10:46:09 +0200 Subject: [PATCH 0974/1435] Minor whitespace and code style fix --- cmake/modules/get_version.cmake | 2 +- src/stlink-lib/libusb_settings.h | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cmake/modules/get_version.cmake b/cmake/modules/get_version.cmake index b80f0c9db..dddb35549 100644 --- a/cmake/modules/get_version.cmake +++ b/cmake/modules/get_version.cmake @@ -55,7 +55,7 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") message(STATUS "Rewrite ${PROJECT_SOURCE_DIR}/.version with ${__version_str}.") endif () - else (EXISTS "${PROJECT_SOURCE_DIR}/.version") + else (NOT EXISTS "${PROJECT_SOURCE_DIR}/.version") # No local .version file found: Create a new one... file(WRITE "${PROJECT_SOURCE_DIR}/.version" ${__version_str}) diff --git a/src/stlink-lib/libusb_settings.h b/src/stlink-lib/libusb_settings.h index 046c0b33d..fea28237b 100644 --- a/src/stlink-lib/libusb_settings.h +++ b/src/stlink-lib/libusb_settings.h @@ -5,19 +5,19 @@ /* - libusb ver | LIBUSB_API_VERSION - -----------+-------------------- - v1.0.13 | 0x01000100 - v1.0.14 | 0x010000FF - v1.0.15 | 0x01000101 - v1.0.16 | 0x01000102 - v1.0.17 | 0x01000102 - v1.0.18 | 0x01000102 - v1.0.19 | 0x01000103 - v1.0.20 | 0x01000104 - v1.0.21 | 0x01000105 - v1.0.22 | 0x01000106 - v1.0.23 | 0x01000107 + libusb ver | LIBUSB_API_VERSION + -----------+-------------------- + v1.0.13 | 0x01000100 + v1.0.14 | 0x010000FF + v1.0.15 | 0x01000101 + v1.0.16 | 0x01000102 + v1.0.17 | 0x01000102 + v1.0.18 | 0x01000102 + v1.0.19 | 0x01000103 + v1.0.20 | 0x01000104 + v1.0.21 | 0x01000105 + v1.0.22 | 0x01000106 + v1.0.23 | 0x01000107 */ From 15bdf0a4f0c29c14e81974d322bcf31ee5338de8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 16 Jun 2020 16:54:46 +0200 Subject: [PATCH 0975/1435] Changed path for udev rules to default /etc/udev/rules.d/ -> /lib/udev/rules.d/ --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 59b9d963c..82e5bf769 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -268,8 +268,8 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux") set(STLINK_MODPROBED_DIR "/etc/modprobe.d" CACHE PATH "modprobe.d directory") install(FILES ${CMAKE_SOURCE_DIR}/config/modprobe.d/stlink_v1.conf DESTINATION ${STLINK_MODPROBED_DIR}) - ## Install udev rules files to /etc/udev/rules.d/ (explicitly hardcoded) - set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "udev rules directory") + ## Install udev rules files to /lib/udev/rules.d/ (explicitly hardcoded) + set(STLINK_UDEV_RULES_DIR "/lib/udev/rules.d" CACHE PATH "udev rules directory") file(GLOB RULES_FILES ${CMAKE_SOURCE_DIR}/config/udev/rules.d/*.rules) install(FILES ${RULES_FILES} DESTINATION ${STLINK_UDEV_RULES_DIR}) endif () From e250773b88c915a9726a9eae112262fb74dcd193 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 17 Jun 2020 11:32:41 +0200 Subject: [PATCH 0976/1435] [doc] Added --reset option for st-flash (Closes #642) --- doc/tutorial.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/tutorial.md b/doc/tutorial.md index 81315dbef..7b8b1d461 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -8,6 +8,7 @@ stlink Tools Tutorial | --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k
      for the STM32F103C8T6 to assume 128k of flash being present. This option accepts
      decimal (128k), octal 0200k, or hex 0x80k values. Leaving the multiplier out is
      equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional "k"
      or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | | --freq=n[k][m] | st-flash,
      st-util | The frequency of the SWD/JTAG interface can be specified, to override the default
      1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
      the unit `Hz` being left out. Valid frequencies are `5K, 15K, 25K, 50K, 100K,`
      `125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | | --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at
      the end of binary file. This may cause some garbage data left after a flash operation.
      This option was enabled by default in earlier releases. | v1.6.1 | +| --reset | st-flash | Trigger a reset both before and after flashing. | v1.0.0 | | --version | st-info,
      st-flash,
      st-util | Print version information. | | | --help | st-flash,
      st-util | Print list of available commands. _(To be added to this table.)_ | | From 3f20a25cc0330b3a3e8093a93bba99d91227bbed Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 17 Jun 2020 15:15:33 +0200 Subject: [PATCH 0977/1435] Updated cmake-settings - Changed header installation path - Fix for cpack output directory --- CMakeLists.txt | 19 ++++++++----------- cmake/modules/get_version.cmake | 2 +- cmake/packaging/cpack_config.cmake | 1 + inc/CMakeLists.txt | 7 ++++--- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 82e5bf769..5171628ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,15 +32,6 @@ else () set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") endif () -## Set installation directories for header files ### TODO: Clean this up... -if (IS_DIRECTORY ${INCLUDE_INSTALL_DIR}) - set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_DIR} CACHE PATH "Main include directory") - set(STLINK_INCLUDE_PATH "${INCLUDE_INSTALL_DIR}") -else () - set(INCLUDE_INSTALL_DIR "include" CACHE PATH "Main include directory") - set(STLINK_INCLUDE_PATH "${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_DIR}") -endif () - ### # Dependencies @@ -94,12 +85,19 @@ include_directories(src) include_directories(src/st-flash) include_directories(src/stlink-lib) +## Set installation directory for header files +set(STLINK_INCLUDE_PATH ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Main include install directory") + +## Subordinate CMakeLists for version config & header installation +add_subdirectory(inc) + +## Define source- and headerfiles for stlink library set(STLINK_HEADERS inc/backend.h + inc/stlink.h src/stlink-lib/commands.h src/stlink-lib/libusb_settings.h src/stlink-lib/reg.h - inc/stlink.h src/stlink-lib/chipid.h src/stlink-lib/flash_loader.h src/stlink-lib/logging.h @@ -279,7 +277,6 @@ endif () # Additional build tasks ### -add_subdirectory(inc) # contains subordinate CMakeLists for version config add_subdirectory(src/stlink-gui) # contains subordinate CMakeLists to build GUI add_subdirectory(tests) # contains subordinate CMakeLists to build test executables add_subdirectory(cmake/packaging) # contains subordinate CMakeLists to build packages diff --git a/cmake/modules/get_version.cmake b/cmake/modules/get_version.cmake index dddb35549..70fbde816 100644 --- a/cmake/modules/get_version.cmake +++ b/cmake/modules/get_version.cmake @@ -52,7 +52,7 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") # ...the version does not match with git-version string if (NOT __version_str STREQUAL __version_file) - message(STATUS "Rewrite ${PROJECT_SOURCE_DIR}/.version with ${__version_str}.") + message(STATUS "Rewrite ${PROJECT_SOURCE_DIR}/.version with ${__version_str}!") endif () else (NOT EXISTS "${PROJECT_SOURCE_DIR}/.version") diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake index f36a50b40..469e743ca 100644 --- a/cmake/packaging/cpack_config.cmake +++ b/cmake/packaging/cpack_config.cmake @@ -12,6 +12,7 @@ set(CPACK_PACKAGE_VENDOR "stlink-org") set(CMAKE_PROJECT_HOMEPAGE_URL "https://github.com/stlink-org/stlink") set(CPACK_SET_DESTDIR "ON") +file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/dist) set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist") if (APPLE) # macOS diff --git a/inc/CMakeLists.txt b/inc/CMakeLists.txt index 66af7e33f..c816c7044 100644 --- a/inc/CMakeLists.txt +++ b/inc/CMakeLists.txt @@ -3,7 +3,8 @@ configure_file( "${CMAKE_BINARY_DIR}/inc/version.h" ) -file(GLOB STLINK_HEADERS "src/st-link-lib/*.h" "${CMAKE_BINARY_DIR}/inc/version.h") +file(GLOB STLINK_HEADERS + "${CMAKE_SOURCE_DIR}/inc/*.h" + "${CMAKE_SOURCE_DIR}/src/stlink-lib/*.h" + "${CMAKE_BINARY_DIR}/inc/version.h") install(FILES ${STLINK_HEADERS} DESTINATION ${STLINK_INCLUDE_PATH}) -install(FILES ${CMAKE_SOURCE_DIR}/inc/stlink.h DESTINATION ${STLINK_INCLUDE_PATH}) -install(FILES ${CMAKE_SOURCE_DIR}/inc/stm32.h DESTINATION ${STLINK_INCLUDE_PATH}) From ae0db2da1517ba0fc6273d8bb4b04a076e971cba Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 17 Jun 2020 17:19:58 +0200 Subject: [PATCH 0978/1435] st-info: Fixed width int sizes for casting --- src/st-info/info.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/st-info/info.c b/src/st-info/info.c index 1bc48a05e..2343140de 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -28,12 +28,9 @@ static void stlink_print_serial(stlink_t *sl, bool openocd) { fmt = "%02x"; } - for (int n = 0; n < sl->serial_size; n++) - printf(fmt, sl->serial[n]); + for (int n = 0; n < sl->serial_size; n++) { printf(fmt, sl->serial[n]); } - if (openocd) { - printf("\""); - } + if (openocd) { printf("\""); } printf("\n"); } @@ -41,19 +38,15 @@ static void stlink_print_serial(stlink_t *sl, bool openocd) { static void stlink_print_info(stlink_t *sl) { const struct stlink_chipid_params *params = NULL; - if (!sl) { - return; - } + if (!sl) { return; } printf(" serial: "); stlink_print_serial(sl, false); printf(" hla-serial: "); stlink_print_serial(sl, true); - printf(" flash: %u (pagesize: %u)\n", - (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz); - - printf(" sram: %u\n", (unsigned int)sl->sram_size); + (uint32_t)sl->flash_size, (uint32_t)sl->flash_pgsz); + printf(" sram: %u\n", (uint32_t)sl->sram_size); printf(" chipid: 0x%.4x\n", sl->chip_id); params = stlink_chipid_get_params(sl->chip_id); @@ -69,7 +62,7 @@ static void stlink_probe(void) { printf("Found %u stlink programmers\n", (unsigned int)size); - for (size_t n = 0; n < size; n++) stlink_print_info(stdevs[n]); + for (size_t n = 0; n < size; n++) { stlink_print_info(stdevs[n]); } stlink_probe_usb_free(&stdevs, size); } @@ -126,11 +119,11 @@ static int print_data(int ac, char **av) { } else if (strcmp(av[1], "--hla-serial") == 0) { stlink_print_serial(sl, true); } else if (strcmp(av[1], "--flash") == 0) { - printf("0x%x\n", (unsigned int)sl->flash_size); + printf("0x%x\n", (uint32_t)sl->flash_size); } else if (strcmp(av[1], "--pagesize") == 0) { - printf("0x%x\n", (unsigned int)sl->flash_pgsz); + printf("0x%x\n", (uint32_t)sl->flash_pgsz); } else if (strcmp(av[1], "--sram") == 0) { - printf("0x%x\n", (unsigned int)sl->sram_size); + printf("0x%x\n", (uint32_t)sl->sram_size); } else if (strcmp(av[1], "--chipid") == 0) { printf("0x%.4x\n", sl->chip_id); } else if (strcmp(av[1], "--descr") == 0) { From 2952859d61903f99555a7736e60b3237fbe0132a Mon Sep 17 00:00:00 2001 From: Geoffrey Brown Date: Wed, 17 Jun 2020 17:16:58 -0400 Subject: [PATCH 0979/1435] change timeout on flash write --- src/stlink-lib/flash_loader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 71601e3da..0e79c3c0a 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -360,11 +360,11 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe * the OS uses, the wait until the error message is reduced to the same order of magnitude * as what was intended. -- REW. */ -#define WAIT_ROUNDS 100 +#define WAIT_ROUNDS 30 // wait until done (reaches breakpoint) for (i = 0; i < WAIT_ROUNDS; i++) { - usleep(1000); + usleep(10000); if (stlink_is_core_halted(sl)) { break; } } From 1541dfcb0bfa3984e54b599d6b7d13c3f26c65d7 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Thu, 18 Jun 2020 17:17:51 +0300 Subject: [PATCH 0980/1435] fix #988 --- src/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 361a24dbf..3459a53a0 100644 --- a/src/common.c +++ b/src/common.c @@ -1624,7 +1624,7 @@ static int map_file(mapped_file_t* mf, const char* path) { if (sizeof(st.st_size) != sizeof(size_t)) { // on 32 bit systems, check if there is an overflow - if (st.st_size > (off_t)UINT32_MAX) { + if (st.st_size > (off_t)INT32_MAX) { fprintf(stderr, "mmap() size_t overflow for file %s\n", path); goto on_error; } From 54e5627a269dddcd00fd1476f7dee62c5b207a52 Mon Sep 17 00:00:00 2001 From: Jan Bramkamp Date: Sat, 20 Jun 2020 01:44:25 +0200 Subject: [PATCH 0981/1435] Add support for FreeBSD's libusb reimplementation FreeBSD reimplemented the libusb API, but their implementation of libusb_set_debug() expects an enum libusb_debug_level instead of an enum libusb_log_level. This causes excessive logging on FreeBSD drowning out all expected output. To keep the changes to other platforms minimal the FreeBSD specific code is kept inside an ifdef block and the enum values are recreated as magic numbers just like the log levels for other platforms. --- src/stlink-lib/logging.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/stlink-lib/logging.c b/src/stlink-lib/logging.c index a5eef9e17..744f1759d 100644 --- a/src/stlink-lib/logging.c +++ b/src/stlink-lib/logging.c @@ -66,12 +66,25 @@ int ugly_log(int level, const char *tag, const char *format, ...) { * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stderr */ int ugly_libusb_log_level(enum ugly_loglevel v) { +#if __FreeBSD__ + // FreeBSD includes its own reimplementation of libusb. + // Its libusb_set_debug() function expects a lib_debug_level + // instead of a lib_log_level and is verbose enough to drown out + // all other output. switch (v) { - case UDEBUG: return(4); - case UINFO: return(3); - case UWARN: return(2); - case UERROR: return(1); + case UDEBUG: return (3); // LIBUSB_DEBUG_FUNCTION + LIBUSB_DEBUG_TRANSFER + case UINFO: return (1); // LIBUSB_DEBUG_FUNCTION only + case UWARN: return (0); // LIBUSB_DEBUG_NO + case UERROR: return (0); // LIBUSB_DEBUG_NO } - - return(2); + return (0); +#else + switch (v) { + case UDEBUG: return (4); + case UINFO: return (3); + case UWARN: return (2); + case UERROR: return (1); + } + return (2); +#endif } From 44c7de765fdae723c5e3fda1268f5df5f4587b7b Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 21 Jun 2020 13:23:44 +0100 Subject: [PATCH 0982/1435] Update d/copyright to remove GPL-2+ stanza about flashloaders The 2 loaders were rewritten from scratch --- debian/copyright | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/debian/copyright b/debian/copyright index cf13a5b4f..98af5a9d0 100644 --- a/debian/copyright +++ b/debian/copyright @@ -153,25 +153,3 @@ License: BSD-3-clause THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Files: flashloaders/stm32l0x.s - flashloaders/stm32lx.s -Copyright: 2010 Spencer Oliver - 2011 Øyvind Harboe - 2011 Clement Burin des Roziers -License: GPL-2+ - This package is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see - . - On Debian systems, the complete text of the GNU General - Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". From 1195dae9e549fe0b474fe11a2b58bfcb2a31dab5 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 21 Jun 2020 13:24:37 +0100 Subject: [PATCH 0983/1435] Update upstream URLs for new Github org --- debian/control | 2 +- debian/copyright | 2 +- debian/watch | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/debian/control b/debian/control index 7172583e9..3ac6af91f 100644 --- a/debian/control +++ b/debian/control @@ -5,7 +5,7 @@ Build-Depends: debhelper-compat (= 12), cmake (>= 3.4.2), libusb-1.0-0-dev, libg Standards-Version: 4.5.0 Rules-Requires-Root: no Section: electronics -Homepage: https://github.com/texane/stlink +Homepage: https://github.com/stlink-org/stlink Vcs-Git: https://github.com/bluca/stlink.git -b debian Vcs-Browser: https://github.com/bluca/stlink diff --git a/debian/copyright b/debian/copyright index 98af5a9d0..1a0febd9c 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,7 +1,7 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: stlink Upstream-Contact: Andrew 'Necromant' Andrianov -Source: https://github.com/texane/stlink +Source: https://github.com/stlink-org/stlink Comment: Upstream tarball has been repackaged to remove binary OSX kernel drivers that are of unknown license and of no use to Debian. Files-Excluded: stlinkv1_macos_driver diff --git a/debian/watch b/debian/watch index 45fece19b..6eb6b78d6 100644 --- a/debian/watch +++ b/debian/watch @@ -1,3 +1,3 @@ version=3 opts=dversionmangle=s/\+ds$//,repacksuffix=+ds,filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/stlink-$1\.tar\.gz/ \ - https://github.com/texane/stlink/tags .*/v?(\d\S+)\.tar\.gz + https://github.com/stlink-org/stlink/tags .*/v?(\d\S+)\.tar\.gz From 9fd796c0ffebe746b4383382161ee946c49889e6 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 21 Jun 2020 13:32:09 +0100 Subject: [PATCH 0984/1435] Patch CMake's hard-coded define of XML gui file location Closes: #963219 --- debian/patches/guipath.patch | 11 +++++++++++ debian/patches/series | 1 + 2 files changed, 12 insertions(+) create mode 100644 debian/patches/guipath.patch create mode 100644 debian/patches/series diff --git a/debian/patches/guipath.patch b/debian/patches/guipath.patch new file mode 100644 index 000000000..d3effc92b --- /dev/null +++ b/debian/patches/guipath.patch @@ -0,0 +1,11 @@ +--- a/src/stlink-gui/CMakeLists.txt ++++ b/src/stlink-gui/CMakeLists.txt +@@ -32,7 +32,7 @@ + add_executable(stlink-gui ${GUI_SOURCES}) + install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_BINDIR}) + set_target_properties(stlink-gui PROPERTIES +- COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/bin") ++ COMPILE_DEFINITIONS STLINK_UI_DIR="/usr/share/stlink") + target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) + install(TARGETS stlink-gui DESTINATION ${CMAKE_INSTALL_BINDIR}) + diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 000000000..1fdcf9977 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1 @@ +guipath.patch From a741f41552927bae5580c06ae63dfe674765a5a6 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 21 Jun 2020 13:41:52 +0100 Subject: [PATCH 0985/1435] Update changelog for 1.6.1+ds-2 release --- debian/changelog | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/debian/changelog b/debian/changelog index 26f17b1fb..f1265ee32 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +stlink (1.6.1+ds-2) unstable; urgency=medium + + * Update d/copyright to remove GPL-2+ stanza about flashloaders + * Update upstream URLs for new Github org + * Patch CMake's hard-coded define of XML gui file location (Closes: + #963219) + + -- Luca Boccassi Sun, 21 Jun 2020 13:41:37 +0100 + stlink (1.6.1+ds-1) unstable; urgency=medium * Merge tag 'v1.6.1' into debian From ff263131cf0d00657c308402762cdd591d313d5e Mon Sep 17 00:00:00 2001 From: Jan Bramkamp Date: Sun, 21 Jun 2020 16:40:51 +0200 Subject: [PATCH 0986/1435] Use #ifdef instead of #if --- src/stlink-lib/logging.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/logging.c b/src/stlink-lib/logging.c index 744f1759d..ce0a2baab 100644 --- a/src/stlink-lib/logging.c +++ b/src/stlink-lib/logging.c @@ -66,7 +66,7 @@ int ugly_log(int level, const char *tag, const char *format, ...) { * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stderr */ int ugly_libusb_log_level(enum ugly_loglevel v) { -#if __FreeBSD__ +#ifdef __FreeBSD__ // FreeBSD includes its own reimplementation of libusb. // Its libusb_set_debug() function expects a lib_debug_level // instead of a lib_log_level and is verbose enough to drown out From c1ea72d842702160173504f4e5869b55b8e986d7 Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Thu, 25 Jun 2020 10:48:51 +0200 Subject: [PATCH 0987/1435] Add support for writing option bytes to the Nucleo 144 STM32F767ZI. This adds --area=option_boot_add, --area=optcr and --area=optcr1 --- include/stlink.h | 14 +- include/stlink/tools/flash.h | 2 +- include/stm32.h | 1 + src/chipid.c | 14 +- src/common.c | 560 +++++++++++++++++++++++++++++++++-- src/flash_loader.c | 20 +- src/tools/flash.c | 131 +++++--- src/tools/flash_opts.c | 110 +++++-- src/usb.c | 1 + 9 files changed, 750 insertions(+), 103 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index c87c6b173..c96cf2ef9 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -120,7 +120,8 @@ enum stlink_flash_type { STLINK_FLASH_TYPE_UNKNOWN = 0, STLINK_FLASH_TYPE_F0, // used by f0, f1 (except f1xl),f3. */ STLINK_FLASH_TYPE_F1_XL, // f0 flash with dual bank, apparently */ - STLINK_FLASH_TYPE_F4, // used by f2, f4, f7 */ + STLINK_FLASH_TYPE_F4, // used by f2, f4 */ + STLINK_FLASH_TYPE_F7, STLINK_FLASH_TYPE_L0, // l0, l1 */ STLINK_FLASH_TYPE_L4, // l4, l4+ */ STLINK_FLASH_TYPE_G0, @@ -146,8 +147,8 @@ struct stlink_reg { typedef uint32_t stm32_addr_t; typedef struct flash_loader { -stm32_addr_t loader_addr; // loader sram addr -stm32_addr_t buf_addr; // buffer sram address + stm32_addr_t loader_addr; // loader sram addr + stm32_addr_t buf_addr; // buffer sram address } flash_loader_t; typedef struct _cortex_m3_cpuid_ { @@ -288,7 +289,14 @@ int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr int stlink_load_device_params(stlink_t *sl); int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); +int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte); +int stlink_read_option_control_register32(stlink_t *sl, uint32_t* option_byte); +int stlink_read_option_control_register1_32(stlink_t *sl, uint32_t* option_byte); + int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); +int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add); +int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_control_register); +int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_control_register1); int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index a912a14aa..e5b4d2572 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -11,7 +11,7 @@ enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3, CMD_RESET = 4}; enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1}; -enum flash_area {FLASH_MAIN_MEMORY = 0, FLASH_SYSTEM_MEMORY = 1,FLASH_OTP = 2, FLASH_OPTION_BYTES = 3}; +enum flash_area {FLASH_MAIN_MEMORY = 0, FLASH_SYSTEM_MEMORY = 1, FLASH_OTP = 2, FLASH_OPTION_BYTES = 3, FLASH_OPTION_BYTES_BOOT_ADD = 4, FLASH_OPTCR = 5, FLASH_OPTCR1 = 6}; struct flash_opts { enum flash_cmd cmd; diff --git a/include/stm32.h b/include/stm32.h index c71718653..be5bb5bc7 100644 --- a/include/stm32.h +++ b/include/stm32.h @@ -20,5 +20,6 @@ #define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) #define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) +#define STM32_F7_OPTION_BYTES_BASE ((uint32_t)0x1FFF0000) #endif /* STM32_H */ diff --git a/src/chipid.c b/src/chipid.c index fcc1c55eb..abddb7dc5 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -6,12 +6,14 @@ static const struct stlink_chipid_params devices[] = { //RM0410 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F7XXXX, .description = "F76xxx", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff0f442, // section 45.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x80000, // "SRAM" byte size in hex from - .bootrom_base = 0x00200000, //! "System memory" starting address from - .bootrom_size = 0xEDC0 //! @todo "System memory" byte size in hex from + .flash_type = STLINK_FLASH_TYPE_F7, + .flash_size_reg = 0x1ff0f442, // section 45.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x80000, // "SRAM" byte size in hex from + .bootrom_base = 0x00200000, //! "System memory" starting address from + .bootrom_size = 0xEDC0, //! @todo "System memory" byte size in hex from + .option_base = STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option bytes, writing uses FLASH_F7_OPTCR and FLASH_F7_OPTCR1 + .option_size = 0x20 }, { //RM0385 and DS10916 document was used to find these paramaters diff --git a/src/common.c b/src/common.c index e8f7cebc6..0c3b0fe69 100644 --- a/src/common.c +++ b/src/common.c @@ -236,6 +236,33 @@ #define FLASH_OBR_OFF ((uint32_t) 0x1c) #define FLASH_WRPR_OFF ((uint32_t) 0x20) +//STM32F7 +#define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) +#define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) +#define FLASH_F7_SR (FLASH_F7_REGS_ADDR + 0x0c) +#define FLASH_F7_CR (FLASH_F7_REGS_ADDR + 0x10) +#define FLASH_F7_OPTCR (FLASH_F7_REGS_ADDR + 0x14) +#define FLASH_F7_OPTCR1 (FLASH_F7_REGS_ADDR + 0x18) +#define FLASH_F7_OPTCR_LOCK 0 +#define FLASH_F7_OPTCR_START 1 +#define FLASH_F7_CR_STRT 16 +#define FLASH_F7_CR_LOCK 31 +#define FLASH_F7_CR_SER 1 +#define FLASH_F7_CR_SNB 3 +#define FLASH_F7_CR_SNB_MASK 0xf8 +#define FLASH_F7_SR_BSY 16 +#define FLASH_F7_SR_ERS_ERR 7 /* Erase Sequence Error */ +#define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ +#define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ +#define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ +#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ +#define FLASH_F7_SR_EOP 0 /* End of operation */ +#define FLASH_F7_OPTCR1_BOOT_ADD0 0 +#define FLASH_F7_OPTCR1_BOOT_ADD1 16 + +#define FLASH_F7_SR_ERROR_MASK ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | (1 << FLASH_F7_SR_OP_ERR)) + //STM32F4 #define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) @@ -337,6 +364,8 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) reg = FLASH_F4_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_F7) + reg = FLASH_F7_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) reg = STM32L4_FLASH_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || @@ -377,6 +406,9 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_lock_shift = FLASH_F4_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_lock_shift = FLASH_F7_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = STM32L0_FLASH_PELOCK; @@ -414,6 +446,8 @@ static void unlock_flash(stlink_t *sl) { key_reg = FLASH_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { key_reg = FLASH_F4_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + key_reg = FLASH_F7_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; flash_key1 = FLASH_L0_PEKEY1; @@ -462,6 +496,9 @@ static void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_lock_shift = FLASH_F4_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_lock_shift = FLASH_F7_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = STM32L0_FLASH_PELOCK; @@ -506,6 +543,10 @@ static bool is_flash_option_locked(stlink_t *sl) { optcr_reg = FLASH_F4_OPTCR; optlock_shift = FLASH_F4_OPTCR_LOCK; break; + case STLINK_FLASH_TYPE_F7: + optcr_reg = FLASH_F7_OPTCR; + optlock_shift = FLASH_F7_OPTCR_LOCK; + break; case STLINK_FLASH_TYPE_L0: optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; optlock_shift = STM32L0_FLASH_OPTLOCK; @@ -551,6 +592,10 @@ static int lock_flash_option(stlink_t *sl) { optcr_reg = FLASH_F4_OPTCR; optlock_shift = FLASH_F4_OPTCR_LOCK; break; + case STLINK_FLASH_TYPE_F7: + optcr_reg = FLASH_F7_OPTCR; + optlock_shift = FLASH_F7_OPTCR_LOCK; + break; case STLINK_FLASH_TYPE_L0: optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; optlock_shift = STM32L0_FLASH_OPTLOCK; @@ -599,6 +644,9 @@ static int unlock_flash_option(stlink_t *sl) case STLINK_FLASH_TYPE_F4: optkey_reg = FLASH_F4_OPT_KEYR; break; + case STLINK_FLASH_TYPE_F7: + optkey_reg = FLASH_F7_OPT_KEYR; + break; case STLINK_FLASH_TYPE_L0: optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; optkey1 = FLASH_L0_OPTKEY1; @@ -649,6 +697,9 @@ static void set_flash_cr_pg(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; x |= 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + x |= 1 << FLASH_CR_PG; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; x &= ~STM32L4_FLASH_CR_OPBITS; @@ -673,6 +724,8 @@ static void clear_flash_cr_pg(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) cr_reg = FLASH_F4_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_F7) + cr_reg = FLASH_F7_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) cr_reg = STM32L4_FLASH_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || @@ -730,6 +783,10 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { cr_reg = FLASH_F4_CR; cr_mer = 1 << FLASH_CR_MER; cr_pg = 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_mer = 1 << FLASH_CR_MER; + cr_pg = 1 << FLASH_CR_PG; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); @@ -786,6 +843,9 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_mer = 1 << FLASH_CR_MER; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_mer = 1 << FLASH_CR_MER; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); @@ -805,6 +865,9 @@ static void set_flash_cr_strt(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_strt = 1 << FLASH_F4_CR_STRT; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_strt = 1 << FLASH_F7_CR_STRT; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_strt = 1 << STM32L4_FLASH_CR_STRT; @@ -842,6 +905,8 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { sr_reg = FLASH_F4_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_reg = FLASH_F7_SR; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { sr_reg = STM32L4_FLASH_SR; } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || @@ -873,6 +938,8 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { sr_busy_shift = FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { sr_busy_shift = FLASH_F4_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_busy_shift = FLASH_F7_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { sr_busy_shift = STM32L4_FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || @@ -919,17 +986,20 @@ static int check_flash_error(stlink_t *sl) { uint32_t res = 0; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - res = read_flash_sr(sl) & FLASH_SR_ERROR_MASK; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK; - break; - case STLINK_FLASH_TYPE_L0: - res = read_flash_sr(sl) & STM32L0_FLASH_SR_ERROR_MASK; - default: - break; + case STLINK_FLASH_TYPE_F0: + res = read_flash_sr(sl) & FLASH_SR_ERROR_MASK; + break; + case STLINK_FLASH_TYPE_F7: + res = read_flash_sr(sl) & FLASH_F7_SR_ERROR_MASK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK; + break; + case STLINK_FLASH_TYPE_L0: + res = read_flash_sr(sl) & STM32L0_FLASH_SR_ERROR_MASK; + default: + break; } if (res) { @@ -1311,13 +1381,13 @@ int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { ret = sl->backend->read_debug32(sl, addr, data); if (!ret) - DLOG("*** stlink_read_debug32 %x is %#x\n", *data, addr); + DLOG("*** stlink_read_debug32 %#010x at %#010x\n", *data, addr); return ret; } int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { - DLOG("*** stlink_write_debug32 %x to %#x\n", data, addr); + DLOG("*** stlink_write_debug32 %#010x to %#010x\n", data, addr); return sl->backend->write_debug32(sl, addr, data); } @@ -1522,9 +1592,11 @@ void stlink_print_data(stlink_t * sl) { fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); */ } - DLOG(" %02x", (unsigned int) sl->q_buf[i]); + //DLOG(" %02x", (unsigned int) sl->q_buf[i]); + fprintf(stderr, " %02x", (unsigned int) sl->q_buf[i]); } - DLOG("\n\n"); + //DLOG("\n\n"); + fprintf(stderr, "\n"); } /* memory mapped file */ @@ -1913,7 +1985,7 @@ static bool stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg* the_ int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size) { /* read size bytes from addr to file */ - + ILOG("read from address %#010x size %d\n", addr, size); int error; int fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); @@ -2044,6 +2116,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if (sl->flash_type == STLINK_FLASH_TYPE_F4 || + sl->flash_type == STLINK_FLASH_TYPE_F7 || sl->flash_type == STLINK_FLASH_TYPE_L4) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -2487,10 +2560,12 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t if (eraseonly) return 0; - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_L4)) { + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + (sl->flash_type == STLINK_FLASH_TYPE_F7) || + (sl->flash_type == STLINK_FLASH_TYPE_L4)) { /* todo: check write operation */ - ILOG("Starting Flash write for F2/F4/L4\n"); + ILOG("Starting Flash write for F2/F4/F7/L4\n"); /* flash loader initialization */ if (stlink_flash_loader_init(sl, &fl) == -1) { ELOG("stlink_flash_loader_init() == -1\n"); @@ -3117,13 +3192,62 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t* base, stm32_addr_ return ret; } +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { + uint32_t option_byte; + int ret = 0; + + //(void) addr; + //(void) len; + + ILOG("Asked to write option byte %#10x to %#010x.\n", *(uint32_t*) (base), addr); + write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); + ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); + + if ( addr == 0 ) { + addr = FLASH_F7_OPTCR; + ILOG("No address provided, using %#10x\n", addr); + } + + if ( addr == FLASH_F7_OPTCR ) { + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F7_OPTCR, (option_byte & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); + } else if ( addr == FLASH_F7_OPTCR1 ) { + // Read FLASH_F7_OPTCR + uint32_t oldvalue; + stlink_read_debug32(sl, FLASH_F7_OPTCR, &oldvalue); + /* write option byte */ + stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_byte); + // Write FLASH_F7_OPTCR lock and start address + stlink_write_debug32(sl, FLASH_F7_OPTCR, (oldvalue & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); + } else { + WLOG("WIP: write %#010x to address %#010x\n", option_byte, addr); + stlink_write_debug32(sl, addr, option_byte); + } + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t*) base, addr); + + /* option bytes are reloaded at reset only, no obl. */ + + return ret; +} + /** * Read option bytes * @param sl * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) { +int stlink_read_option_control_register_Gx(stlink_t *sl, uint32_t* option_byte) { return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); } @@ -3133,19 +3257,106 @@ int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) { * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { +int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) { + return stlink_read_option_control_register_Gx(sl, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f2(stlink_t *sl, uint32_t* option_byte) { return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); } +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { + return stlink_read_option_control_register_f2(sl, option_byte); +} + /** * Read option bytes * @param sl * @param option_byte value to read * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { +int stlink_read_option_control_register_f4(stlink_t *sl, uint32_t* option_byte) { return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); } + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { + return stlink_read_option_control_register_f4(sl, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f7(stlink_t *sl, uint32_t* option_byte) { + DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_F7_OPTCR); + return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register1_f7(stlink_t *sl, uint32_t* option_byte) { + DLOG("@@@@ Read option control register 1 byte from %#10x\n", FLASH_F7_OPTCR1); + return stlink_read_debug32(sl, FLASH_F7_OPTCR1, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t* option_byte) { + DLOG("@@@@ Read option byte boot address\n"); + return stlink_read_option_control_register1_f7(sl, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + * + * Since multiple bytes can be read, we read and print all but one here + * and then return the last one just like other devices + */ +int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t* option_byte) { + int err = -1; + for (uint8_t counter = 0; counter < (sl->option_size / 4 - 1); counter++) { + err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), option_byte); + if (err == -1) { + return err; + } else { + printf("%08x\n", *option_byte); + } + } + + return stlink_read_debug32(sl, sl->option_base + (sl->option_size / 4 - 1) * sizeof(uint32_t), option_byte); +} + /** * Read first option bytes * @param sl @@ -3153,9 +3364,43 @@ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { * @return 0 on success, -ve on failure. */ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { + DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); return stlink_read_debug32(sl, sl->option_base, option_byte); } +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +//int stlink_read_option_bytes_boot_add_generic(stlink_t *sl, uint32_t* option_byte) { +// DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); +// return stlink_read_debug32(sl, sl->option_base, option_byte); +//} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +//int stlink_read_option_control_register_generic(stlink_t *sl, uint32_t* option_byte) { +// DLOG("@@@@ Read option control register byte from %#10x\n", sl->option_base); +// return stlink_read_debug32(sl, sl->option_base, option_byte); +//} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +//int stlink_read_option_control_register1_generic(stlink_t *sl, uint32_t* option_byte) { +// DLOG("@@@@ Read option control register 1 byte from %#10x\n", sl->option_base); +// return stlink_read_debug32(sl, sl->option_base, option_byte); +//} + /** * Read option bytes * @param sl @@ -3174,6 +3419,8 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) return stlink_read_option_bytes_f2(sl, option_byte); case STLINK_CHIPID_STM32_F446: return stlink_read_option_bytes_f4(sl, option_byte); + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_bytes_f7(sl, option_byte); case STLINK_CHIPID_STM32_G0_CAT1: case STLINK_CHIPID_STM32_G0_CAT2: case STLINK_CHIPID_STM32_G4_CAT2: @@ -3184,6 +3431,72 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) } } +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte) +{ + if (sl->option_base == 0) { + ELOG("Option bytes boot address read is currently not supported for connected chip\n"); + return -1; + } + + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_bytes_boot_add_f7(sl, option_byte); + default: + return -1; + //return stlink_read_option_bytes_boot_add_generic(sl, option_byte); + } +} + +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register32(stlink_t *sl, uint32_t* option_byte) +{ + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } + + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_control_register_f7(sl, option_byte); + default: + return -1; + //return stlink_read_option_control_register_generic(sl, option_byte); + } +} + +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register1_32(stlink_t *sl, uint32_t* option_byte) +{ + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } + + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_control_register1_f7(sl, option_byte); + default: + return -1; + //return stlink_read_option_control_register1_generic(sl, option_byte); + } +} + /** * Write option bytes * @param sl @@ -3192,7 +3505,7 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) */ int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { - WLOG("About to write option byte %#10x to target.\n", option_byte); + WLOG("About to write option byte %#10x to %#10x.\n", option_byte, sl->option_base); return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *) &option_byte, 4); } @@ -3212,6 +3525,7 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui return -1; } + if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { ELOG("Option bytes start address out of Option bytes range\n"); return -1; @@ -3238,6 +3552,9 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui case STLINK_FLASH_TYPE_F4: ret = stlink_write_option_bytes_f4(sl, base, addr, len); break; + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_bytes_f7(sl, base, addr, len); + break; case STLINK_FLASH_TYPE_L0: ret = stlink_write_option_bytes_l0(sl, base, addr, len); break; @@ -3255,8 +3572,203 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui if (ret) ELOG("Flash option write failed!\n"); - else - ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + else + ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option_control_register) { + int ret = 0; + + ILOG("Asked to write option control register 1 %#10x to %#010x.\n", option_control_register, FLASH_F7_OPTCR); + //write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); + //ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); + + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F7_OPTCR, (option_control_register & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, FLASH_F7_OPTCR1); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t option_control_register1) { + int ret = 0; + + ILOG("Asked to write option control register 1 %#010x to %#010x.\n", option_control_register1, FLASH_F7_OPTCR1); + //write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); + //ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); + + /* write option byte, ensuring we dont lock opt, and set strt bit */ + uint32_t current_control_register_value; + stlink_read_debug32(sl, FLASH_F7_OPTCR, ¤t_control_register_value); + + /* write option byte */ + stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_control_register1); + stlink_write_debug32(sl, FLASH_F7_OPTCR, (current_control_register_value & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register1, FLASH_F7_OPTCR1); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_boot_add_f7(stlink_t *sl, uint32_t option_byte_boot_add) { + ILOG("Asked to write option byte boot add %#010x.\n", option_byte_boot_add); + return stlink_write_option_control_register1_f7(sl, option_byte_boot_add); +} + +/** + * Write option bytes + * @param sl + * @param option bytes boot address to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add) +{ + int ret = -1; + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); + break; + default: + ELOG("Option bytes boot address writing is currently not implemented for connected chip\n"); + break; + } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option bytes boot address %#010x!\n", option_bytes_boot_add); + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option bytes boot address to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_control_register) +{ + int ret = -1; + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_control_register_f7(sl, option_control_register); + break; + default: + ELOG("Option control register writing is currently not implemented for connected chip\n"); + break; + } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option control register %#010x!\n", option_control_register); + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option bytes boot address to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_control_register1) +{ + int ret = -1; + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_control_register1_f7(sl, option_control_register1); + break; + default: + ELOG("Option control register 1 writing is currently not implemented for connected chip\n"); + break; + } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option control register 1 %#010x!\n", option_control_register1); /* Re-lock flash. */ lock_flash_option(sl); diff --git a/src/flash_loader.c b/src/flash_loader.c index a2c5879ce..b6058cd0e 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -176,19 +176,19 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { - size_t size = 0; + size_t size = 0; - /* allocate the loader in sram */ - if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { - WLOG("Failed to write flash loader to sram!\n"); - return -1; - } + /* allocate the loader in sram */ + if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { + WLOG("Failed to write flash loader to sram!\n"); + return -1; + } - /* allocate a one page buffer in sram right after loader */ - fl->buf_addr = fl->loader_addr + (uint32_t) size; - ILOG("Successfully loaded flash loader in sram\n"); + /* allocate a one page buffer in sram right after loader */ + fl->buf_addr = fl->loader_addr + (uint32_t) size; + ILOG("Successfully loaded flash loader in sram\n"); - return 0; + return 0; } static int loader_v_dependent_assignment(stlink_t *sl, diff --git a/src/tools/flash.c b/src/tools/flash.c index 3a83daf8a..9c4e20dff 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -28,15 +28,23 @@ static void cleanup(int signum) { static void usage(void) { - puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] {read|write} [addr] [size]"); + puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); puts("command line: ./st-flash [--debug] [--freq=] [--serial ] erase"); puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); puts(" , and : Use hex format."); puts(" : Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); puts(" : Can be 'binary' (default) or 'ihex', although must be specified for binary format only."); + puts(" : Can be 'main' (default), 'system', 'otp', 'optcr', 'optcr1', 'option' or 'option_boot_add'"); puts("print tool version info: ./st-flash [--version]"); - puts("example write option byte: ./st-flash --debug --reset --area=option write 0xXXXXXXXX"); - puts("example read option byte: ./st-flash --debug --reset --area=option read > option_byte"); + puts("example read option byte: ./st-flash --area=option read [path] [size]"); + puts("example write option byte: ./st-flash --area=option write 0xXXXXXXXX"); + puts("On selected targets:"); + puts("example read boot_add option byte: ./st-flash --area=option_boot_add read"); + puts("example write boot_add option byte: ./st-flash --area=option_boot_add write 0xXXXXXXXX"); + puts("example read option control register byte: ./st-flash --area=optcr read"); + puts("example write option control register1 byte: ./st-flash --area=optcr write 0xXXXXXXXX"); + puts("example read option control register1 byte: ./st-flash --area=optcr1 read"); + puts("example write option control register1 byte: ./st-flash --area=optcr1 write 0xXXXXXXXX"); } int main(int ac, char** av) @@ -54,7 +62,7 @@ int main(int ac, char** av) return -1; } - printf("st-flash %s\n", STLINK_VERSION); + ILOG("st-flash %s\n", STLINK_VERSION); sl = stlink_open_usb(o.log_level, 1, (char *)o.serial, o.freq); @@ -62,7 +70,7 @@ int main(int ac, char** av) return -1; } - if (sl->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { + if (STLINK_FLASH_TYPE_UNKNOWN == sl->flash_type) { printf("Failed to connect to target\n"); return -1; } @@ -80,14 +88,14 @@ int main(int ac, char** av) signal(SIGTERM, &cleanup); signal(SIGSEGV, &cleanup); - if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { + if (STLINK_DEV_DFU_MODE == stlink_current_mode(sl)) { if (stlink_exit_dfu_mode(sl)) { printf("Failed to exit DFU mode\n"); goto on_error; } } - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { + if (STLINK_DEV_DEBUG_MODE != stlink_current_mode(sl)) { if (stlink_enter_swd_mode(sl)) { printf("Failed to enter SWD mode\n"); goto on_error; @@ -109,7 +117,7 @@ int main(int ac, char** av) } // Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 - if (sl->chip_id == STLINK_CHIPID_STM32_F4) + if (STLINK_CHIPID_STM32_F4 == sl->chip_id) { memset(sl->q_buf,0,4); for (int i=0;i<8;i++) { @@ -131,19 +139,20 @@ int main(int ac, char** av) goto on_error; } - if (o.cmd == FLASH_CMD_WRITE) /* write */ + if (FLASH_CMD_WRITE == o.cmd) // write { size_t size = 0; - if (o.format == FLASH_FORMAT_IHEX) { + if (FLASH_FORMAT_IHEX == o.format) { err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr); if (err == -1) { printf("Cannot parse %s as Intel-HEX file\n", o.filename); goto on_error; } } + if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { - if (o.format == FLASH_FORMAT_IHEX) + if (FLASH_FORMAT_IHEX == o.format) err = stlink_mwrite_flash(sl, mem, (uint32_t)size, o.addr); else err = stlink_fwrite_flash(sl, o.filename, o.addr); @@ -155,7 +164,7 @@ int main(int ac, char** av) } else if ((o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { - if (o.format == FLASH_FORMAT_IHEX) + if (FLASH_FORMAT_IHEX == o.format) err = stlink_mwrite_sram(sl, mem, (uint32_t)size, o.addr); else err = stlink_fwrite_sram(sl, o.filename, o.addr); @@ -174,25 +183,39 @@ int main(int ac, char** av) goto on_error; } } - else if (o.area == FLASH_OPTION_BYTES){ + else if (FLASH_OPTION_BYTES == o.area) { if (o.val == 0) { printf("attempting to set option byte to 0, abort.\n"); goto on_error; - } + } err = stlink_write_option_bytes32(sl, o.val); - if (err == -1) - { + if (err == -1) { printf("stlink_write_option_bytes32() == -1\n"); goto on_error; } } - else { + else if (FLASH_OPTCR == o.area) { + DLOG("@@@@ Write %d (%0#10x) to option control register\n", o.val, o.val); + + err = stlink_write_option_control_register32(sl, o.val); + } + else if (FLASH_OPTCR1 == o.area) { + DLOG("@@@@ Write %d (%0#10x) to option control register 1\n", o.val, o.val); + + err = stlink_write_option_control_register1_32(sl, o.val); + } + else if (FLASH_OPTION_BYTES_BOOT_ADD == o.area) { + DLOG("@@@@ Write %d (%0#10x) to option bytes boot address\n", o.val, o.val); + + err = stlink_write_option_bytes_boot_add32(sl, o.val); + } + else { err = -1; printf("Unknown memory region\n"); goto on_error; } - } else if (o.cmd == FLASH_CMD_ERASE) + } else if (FLASH_CMD_ERASE == o.cmd) { err = stlink_erase_flash_mass(sl); if (err == -1) @@ -200,7 +223,7 @@ int main(int ac, char** av) printf("stlink_erase_flash_mass() == -1\n"); goto on_error; } - } else if (o.cmd == CMD_RESET) + } else if (CMD_RESET == o.cmd) { if (sl->version.stlink_v > 1) { if (stlink_jtag_reset(sl, 2)) { @@ -216,35 +239,69 @@ int main(int ac, char** av) } else /* read */ { - if(o.area == FLASH_OPTION_BYTES){ - uint32_t option_byte; - err = stlink_read_option_bytes32(sl, &option_byte); - if (err == -1) { - printf("could not read option bytes (%d)\n", err); - goto on_error; - } else { - printf("%x\n",option_byte); - } - }else{ - if ((o.addr >= sl->flash_base) && (o.size == 0) && - (o.addr < sl->flash_base + sl->flash_size)){ + if ((FLASH_MAIN_MEMORY == o.area) || (FLASH_SYSTEM_MEMORY == o.area)) { + if ((o.size == 0) && (o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { o.size = sl->flash_size; } - else if ((o.addr >= sl->sram_base) && (o.size == 0) && - (o.addr < sl->sram_base + sl->sram_size)){ + else if ((o.size == 0) && (o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { o.size = sl->sram_size; } - err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); + err = stlink_fread(sl, o.filename, FLASH_FORMAT_IHEX == o.format, o.addr, o.size); - if (err == -1) - { + if (err == -1) { printf("stlink_fread() == -1\n"); goto on_error; } + } else if (FLASH_OPTION_BYTES == o.area) { + uint8_t remaining_option_length = sl->option_size / 4; + DLOG("@@@@ Read %d (%#x) option bytes from %#10x\n", remaining_option_length, remaining_option_length, sl->option_base); + + if (NULL != o.filename) { + if (0 == o.size) { + o.size = sl->option_size; + } + err = stlink_fread(sl, o.filename, FLASH_FORMAT_IHEX == o.format, sl->option_base, o.size); + } else { + uint32_t option_byte = 0; + err = stlink_read_option_bytes32(sl, &option_byte); + if (err == -1) { + printf("could not read option bytes (%d)\n", err); + goto on_error; + } else { + printf("%08x\n", option_byte); + } + } + } else if (FLASH_OPTION_BYTES_BOOT_ADD == o.area) { + uint32_t option_byte = 0; + err = stlink_read_option_bytes_boot_add32(sl, &option_byte); + if (err == -1) { + printf("could not read option bytes boot address (%d)\n", err); + goto on_error; + } else { + printf("%08x\n",option_byte); + } + } else if (FLASH_OPTCR == o.area) { + uint32_t option_byte = 0; + err = stlink_read_option_control_register32(sl, &option_byte); + if (err == -1) { + printf("could not read option control register (%d)\n", err); + goto on_error; + } else { + printf("%08x\n",option_byte); + } + } else if (FLASH_OPTCR1 == o.area) { + uint32_t option_byte = 0; + err = stlink_read_option_control_register1_32(sl, &option_byte); + if (err == -1) { + printf("could not read option control register (%d)\n", err); + goto on_error; + } else { + printf("%08x\n",option_byte); + } } } - if (o.reset){ + if (o.reset) { if (sl->version.stlink_v > 1) stlink_jtag_reset(sl, 2); stlink_reset(sl); } diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index a5c9d287f..8557445e0 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -145,6 +145,12 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { o->area = FLASH_OTP; else if (strcmp(area, "option") == 0) o->area = FLASH_OPTION_BYTES; + else if (strcmp(area, "option_boot_add") == 0) + o->area = FLASH_OPTION_BYTES_BOOT_ADD; + else if (strcmp(area, "optcr") == 0) + o->area = FLASH_OPTCR; + else if (strcmp(area, "optcr1") == 0) + o->area = FLASH_OPTCR1; else return -1; @@ -236,19 +242,19 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { // command and (optional) device name while (ac >= 1) { if (strcmp(av[0], "erase") == 0) { - if (o->cmd != FLASH_CMD_NONE) return -1; + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = FLASH_CMD_ERASE; } else if (strcmp(av[0], "read") == 0) { - if (o->cmd != FLASH_CMD_NONE) return -1; + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = FLASH_CMD_READ; } else if (strcmp(av[0], "write") == 0) { - if (o->cmd != FLASH_CMD_NONE) return -1; + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = FLASH_CMD_WRITE; } else if (strcmp(av[0], "reset") == 0) { - if (o->cmd != FLASH_CMD_NONE) return -1; + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = CMD_RESET; } else { @@ -268,33 +274,93 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { break; case FLASH_CMD_READ: // expect filename, addr and size - if ((o->area == FLASH_OPTION_BYTES) &&(ac == 0)) break; - if (ac != 3) return invalid_args("read "); - if (ac != 3) return -1; - o->filename = av[0]; - uint32_t address; - result = get_integer_from_char_array(av[1], &address); - if (result != 0) return bad_arg ("addr"); - else o->addr = (stm32_addr_t) address; + if ((FLASH_MAIN_MEMORY == o->area) || (FLASH_SYSTEM_MEMORY == o->area)) { + if (ac != 3) return invalid_args("read "); + o->filename = av[0]; + uint32_t address; + result = get_integer_from_char_array(av[1], &address); + if (result != 0) return bad_arg ("addr"); + else o->addr = (stm32_addr_t) address; - uint32_t size; - result = get_integer_from_char_array(av[2], &size); - if (result != 0) return bad_arg ("size"); - else o->size = (size_t) size; + uint32_t size; + result = get_integer_from_char_array(av[2], &size); + if (result != 0) return bad_arg ("size"); + else o->size = (size_t) size; + break; + } + else if ((FLASH_OTP == o->area)) { + return bad_arg("TODO: otp not implemented yet"); + if (ac > 1) return invalid_args("otp read: [path]"); + if (ac > 0) o->filename = av[0]; + break; + } + else if ((FLASH_OPTION_BYTES == o->area)) { + if (ac > 2) return invalid_args("option bytes read: [path] [size]"); + if (ac > 0) o->filename = av[0]; + if (ac > 1) { + uint32_t size; + result = get_integer_from_char_array(av[1], &size); + if (result != 0) return bad_arg("option bytes read: invalid size"); + else o->size = (size_t) size; + } + break; + } + else if ((FLASH_OPTION_BYTES_BOOT_ADD == o->area)) { + if (ac > 0) return invalid_args("option bytes boot_add read"); + break; + } + else if ((FLASH_OPTCR == o->area)) { + if (ac > 0) return invalid_args("option control register read"); + break; + } + else if ((FLASH_OPTCR1 == o->area)) { + if (ac > 0) return invalid_args("option control register 1 read"); + break; + } break; case FLASH_CMD_WRITE: - if (o->area == FLASH_OPTION_BYTES){ - if (ac != 1) return -1; - + // TODO: should be boot add 0 and boot add 1 uint32 + if (FLASH_OPTION_BYTES == o->area) { // expect filename and optional address + if (ac >=1 && ac <= 2) { + o->filename = av[0]; + } + else + return invalid_args("write [addr]"); + + if (ac == 2) { + uint32_t addr; + result = get_integer_from_char_array(av[1], &addr); + if (result != 0) return bad_arg ("addr"); + else o->addr = (stm32_addr_t) addr; + } + } + else if (FLASH_OPTION_BYTES_BOOT_ADD == o->area) { // expect option bytes boot address + if (ac != 1) return invalid_args("option bytes boot_add write "); + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) return bad_arg ("val"); + else o->val = (uint32_t) val; + } + else if (FLASH_OPTCR == o->area) { // expect option control register value + if (ac != 1) return invalid_args("option control register write "); + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) return bad_arg ("val"); + else o->val = (uint32_t) val; + } + else if (FLASH_OPTCR1 == o->area) { // expect option control register 1 value + if (ac != 1) return invalid_args("option control register 1 write "); + uint32_t val; result = get_integer_from_char_array(av[0], &val); if (result != 0) return bad_arg ("val"); else o->val = (uint32_t) val; - } - else if (o->format == FLASH_FORMAT_BINARY) { // expect filename and addr + else if (FLASH_FORMAT_BINARY == o->format) { // expect filename and addr if (ac != 2) return invalid_args("write "); o->filename = av[0]; uint32_t addr; @@ -302,7 +368,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { if (result != 0) return bad_arg ("addr"); else o->addr = (stm32_addr_t) addr; } - else if (o->format == FLASH_FORMAT_IHEX) { // expect filename + else if (FLASH_FORMAT_IHEX == o->format) { // expect filename if (ac != 1) return invalid_args("write "); o->filename = av[0]; } diff --git a/src/usb.c b/src/usb.c index b986aed57..b492afed7 100644 --- a/src/usb.c +++ b/src/usb.c @@ -655,6 +655,7 @@ int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_READMEM_32BIT; + DLOG("using address %#010x\n", addr); write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); size = send_recv(slu, 1, cmd, slu->cmd_len, data, len); From 972ecf8d960919d0c9433c73b809ddcc701f847b Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Thu, 25 Jun 2020 12:40:15 +0200 Subject: [PATCH 0988/1435] Continue merging upstream --- src/common.c | 3 +- src/st-flash/flash.c | 5 +- src/st-flash/flash_opts.c | 417 ++++++++++++++++------------- src/stlink-lib/chipid.c | 2 +- src/stlink-lib/flash_loader.c | 486 +++++++++++++++++----------------- 5 files changed, 481 insertions(+), 432 deletions(-) diff --git a/src/common.c b/src/common.c index 1703dee76..58e67d447 100644 --- a/src/common.c +++ b/src/common.c @@ -3637,8 +3637,9 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui if (ret) { ELOG("Flash option write failed!\n"); - else + } else { ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + } /* Re-lock flash. */ lock_flash_option(sl); diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 6d70fc5e6..128b8acc0 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -140,7 +140,6 @@ int main(int ac, char** av) { { size_t size = 0; if (FLASH_FORMAT_IHEX == o.format) { - if (o.format == FLASH_FORMAT_IHEX) { err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr); if (err == -1) { @@ -150,7 +149,7 @@ int main(int ac, char** av) { } if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { - if (FLASH_FORMAT_IHEX == o.format) + if (FLASH_FORMAT_IHEX == o.format) { err = stlink_mwrite_flash(sl, mem, (uint32_t)size, o.addr); } else { err = stlink_fwrite_flash(sl, o.filename, o.addr); @@ -162,7 +161,7 @@ int main(int ac, char** av) { } } else if ((o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { - if (FLASH_FORMAT_IHEX == o.format) + if (FLASH_FORMAT_IHEX == o.format) { err = stlink_mwrite_sram(sl, mem, (uint32_t)size, o.addr); } else { err = stlink_fwrite_sram(sl, o.filename, o.addr); diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 6d1940675..8557445e0 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -2,12 +2,11 @@ #include #include -#include "flash.h" +#include static bool starts_with(const char * str, const char * prefix) { size_t n = strlen(prefix); - - if (strlen(str) < n) { return(false); } + if (strlen(str) < n) return false; return (0 == strncmp(str, prefix, n)); } @@ -20,28 +19,37 @@ static int get_long_integer_from_char_array (const char *const str, uint64_t *re uint64_t value; char *tail; - if (starts_with (str, "0x") || starts_with (str, "0X")) { // hexadecimal + // hexadecimal + if (starts_with (str, "0x") || starts_with (str, "0X")) { value = strtoul (str + 2, &tail, 16); - } else if (starts_with (str, "0b") || starts_with (str, "0B")) { // binary + } + // binary + else if (starts_with (str, "0b") || starts_with (str, "0B")) { value = strtoul (str + 2, &tail, 2); - } else if (starts_with (str, "0")) { // octal + } + // octal + else if (starts_with (str, "0")) { value = strtoul (str + 1, &tail, 8); - } else { // decimal + } + // decimal + else { value = strtoul (str, &tail, 10); } if (((tail[0] == 'k') || (tail[0] == 'K')) && (tail[1] == '\0')) { value = value * 1024; - } else if (((tail[0] == 'm') || (tail[0] == 'M')) && (tail[1] == '\0')) { + } + else if (((tail[0] == 'm') || (tail[0] == 'M')) && (tail[1] == '\0')) { value = value * 1024 * 1024; - } else if (tail[0] == '\0') { - /* value not changed */ - } else { - return(-1); } - + else if (tail[0] == '\0') { + // value not change + } + else { + return -1; + } *read_value = value; - return(0); + return 0; } // support positive integer from 0 to UINT32_MAX @@ -51,26 +59,28 @@ static int get_long_integer_from_char_array (const char *const str, uint64_t *re static int get_integer_from_char_array (const char *const str, uint32_t *read_value) { uint64_t value; int result = get_long_integer_from_char_array (str, &value); - if (result != 0) { - return(result); - } else if (value > UINT32_MAX) { - fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, cannot convert to int32_t\n"); - return(-1); - } else { + return result; + } + else if (value > UINT32_MAX) { + fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, \ +cannot convert to int32_t\n"); + return -1; + } + else { *read_value = (uint32_t)value; - return(0); + return 0; } } static int invalid_args(const char *expected) { fprintf(stderr, "*** Error: Expected args for this command: %s\n", expected); - return(-1); + return -1; } static int bad_arg(const char *arg) { fprintf(stderr, "*** Error: Invalid value for %s\n", arg); - return(-1); + return -1; } int flash_get_opts(struct flash_opts* o, int ac, char** av) { @@ -81,177 +91,173 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { // options int result; - while (ac >= 1) { if (strcmp(av[0], "--version") == 0) { printf("v%s\n", STLINK_VERSION); exit(EXIT_SUCCESS); - } else if (strcmp(av[0], "--debug") == 0) { + } + else if (strcmp(av[0], "--debug") == 0) { o->log_level = DEBUG_LOG_LEVEL; - } else if (strcmp(av[0], "--opt") == 0) { + } + else if (strcmp(av[0], "--opt") == 0) { o->opt = ENABLE_OPT; - } else if (strcmp(av[0], "--reset") == 0) { + } + else if (strcmp(av[0], "--reset") == 0) { o->reset = 1; - } else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) { + } + else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) { const char * serial; - if (strcmp(av[0], "--serial") == 0) { ac--; av++; - - if (ac < 1) { return(-1); } - + if (ac < 1) return -1; serial = av[0]; - } else { + } + else { serial = av[0] + strlen("--serial="); } - - /** @todo This is not really portable, as strlen really returns size_t we need to obey - and not cast it to a signed type. */ + /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ int j = (int)strlen(serial); - int length = j / 2; // the length of the destination-array - - if (j % 2 != 0) { return(-1); } - + int length = j / 2; // the length of the destination-array + if (j % 2 != 0) return -1; for (size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { char buffer[3] = {0}; memcpy(buffer, serial + j, 2); o->serial[length - k] = (uint8_t)strtol(buffer, NULL, 16); } - } else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { + } + else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { const char * area; - if (strcmp(av[0], "--area") == 0) { ac--; av++; - - if (ac < 1) { return(-1); } - + if (ac < 1) return -1; area = av[0]; - } else { + } + else { area = av[0] + strlen("--area="); } - - if (strcmp(area, "main") == 0) { + if (strcmp(area, "main") == 0) o->area = FLASH_MAIN_MEMORY; - } else if (strcmp(area, "system") == 0) { + else if (strcmp(area, "system") == 0) o->area = FLASH_SYSTEM_MEMORY; - } else if (strcmp(area, "otp") == 0) { + else if (strcmp(area, "otp") == 0) o->area = FLASH_OTP; - } else if (strcmp(area, "option") == 0) { + else if (strcmp(area, "option") == 0) o->area = FLASH_OPTION_BYTES; - } else { - return(-1); - } + else if (strcmp(area, "option_boot_add") == 0) + o->area = FLASH_OPTION_BYTES_BOOT_ADD; + else if (strcmp(area, "optcr") == 0) + o->area = FLASH_OPTCR; + else if (strcmp(area, "optcr1") == 0) + o->area = FLASH_OPTCR1; + else + return -1; - } else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) { + } + else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) { const char* freq; - if (strcmp(av[0], "--freq") == 0) { ac--; av++; - - if (ac < 1) { - return(-1); - } - + if (ac < 1) return -1; freq = av[0]; - } else { + } + else { freq = av[0] + strlen("--freq="); } - if (strcmp(freq, "5K") == 0 || strcmp(freq, "5k") == 0) { o->freq = 5; - } else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) { + } + else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) { o->freq = 15; - } else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) { + } + else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) { o->freq = 25; - } else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) { + } + else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) { o->freq = 50; - } else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) { + } + else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) { o->freq = 100; - } else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) { + } + else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) { o->freq = 125; - } else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) { + } + else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) { o->freq = 240; - } else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) { + } + else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) { o->freq = 480; - } else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) { + } + else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) { o->freq = 950; - } else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || - strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) { + } + else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) { o->freq = 1200; - } else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || - strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) { + } + else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) { o->freq = 1800; - } else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || - strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) { + } + else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) { o->freq = 4000; - } else { - return(-1); } - } else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { + else + return -1; + } + else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { const char * format; - if (strcmp(av[0], "--format") == 0) { ac--; av++; - - if (ac < 1) { return(-1); } - + if (ac < 1) return -1; format = av[0]; - } else { + } + else { format = av[0] + strlen("--format="); } - - if (strcmp(format, "binary") == 0) { + if (strcmp(format, "binary") == 0) o->format = FLASH_FORMAT_BINARY; - } else if (strcmp(format, "ihex") == 0) { + else if (strcmp(format, "ihex") == 0) o->format = FLASH_FORMAT_IHEX; - } else { - return(bad_arg("format")); - } - } else if ( starts_with(av[0], "--flash=")) { + else + return bad_arg("format"); + } + else if ( starts_with(av[0], "--flash=") ) { const char *arg = av[0] + strlen("--flash="); uint32_t flash_size; result = get_integer_from_char_array(arg, &flash_size); - - if (result != 0) { - return(bad_arg ("--flash")); - } else { - o->flash_size = (size_t)flash_size; - } - } else if (strcmp(av[0], "--connect-under-reset") == 0) { - o->connect_under_reset = true; - } else { - break; // non-option found - + if (result != 0) return bad_arg ("--flash"); + else o->flash_size = (size_t) flash_size; + } + else { + break; // non-option found } ac--; av++; } - /* command and (optional) device name */ + // command and (optional) device name while (ac >= 1) { if (strcmp(av[0], "erase") == 0) { - if (o->cmd != FLASH_CMD_NONE) { return(-1); } - + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = FLASH_CMD_ERASE; - } else if (strcmp(av[0], "read") == 0) { - if (o->cmd != FLASH_CMD_NONE) { return(-1); } - + } + else if (strcmp(av[0], "read") == 0) { + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = FLASH_CMD_READ; - } else if (strcmp(av[0], "write") == 0) { - if (o->cmd != FLASH_CMD_NONE) { return(-1); } - + } + else if (strcmp(av[0], "write") == 0) { + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = FLASH_CMD_WRITE; - } else if (strcmp(av[0], "reset") == 0) { - if (o->cmd != FLASH_CMD_NONE) { return(-1); } - + } + else if (strcmp(av[0], "reset") == 0) { + if (FLASH_CMD_NONE != o->cmd) return -1; o->cmd = CMD_RESET; - } else { + } + else { break; } @@ -259,83 +265,120 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { av++; } - switch (o->cmd) { - case FLASH_CMD_NONE: // no command found - return(-1); - - case FLASH_CMD_ERASE: // no more arguments expected - - if (ac != 0) { return(-1); } - - break; - - case FLASH_CMD_READ: // expect filename, addr and size - - if ((o->area == FLASH_OPTION_BYTES) && (ac == 0)) { break; } - - if (ac != 3) { return(invalid_args("read ")); } - - if (ac != 3) { return(-1); } - - o->filename = av[0]; - uint32_t address; - result = get_integer_from_char_array(av[1], &address); - - if (result != 0) { - return(bad_arg ("addr")); - } else { - o->addr = (stm32_addr_t)address; - } - - uint32_t size; - result = get_integer_from_char_array(av[2], &size); - - if (result != 0) { - return(bad_arg ("size")); - } else { - o->size = (size_t)size; - } - - break; - - case FLASH_CMD_WRITE: - - if (o->area == FLASH_OPTION_BYTES) { - if (ac != 1) { return(-1); } + switch(o->cmd) { + case FLASH_CMD_NONE: // no command found + return -1; - uint32_t val; - result = get_integer_from_char_array(av[0], &val); + case FLASH_CMD_ERASE: // no more arguments expected + if (ac != 0) return -1; + break; - if (result != 0) { - return(bad_arg ("val")); - } else { - o->val = (uint32_t)val; + case FLASH_CMD_READ: // expect filename, addr and size + if ((FLASH_MAIN_MEMORY == o->area) || (FLASH_SYSTEM_MEMORY == o->area)) { + if (ac != 3) return invalid_args("read "); + o->filename = av[0]; + uint32_t address; + result = get_integer_from_char_array(av[1], &address); + if (result != 0) return bad_arg ("addr"); + else o->addr = (stm32_addr_t) address; + + uint32_t size; + result = get_integer_from_char_array(av[2], &size); + if (result != 0) return bad_arg ("size"); + else o->size = (size_t) size; + + break; } - - } else if (o->format == FLASH_FORMAT_BINARY) { // expect filename and addr - if (ac != 2) { return(invalid_args("write ")); } - - o->filename = av[0]; - uint32_t addr; - result = get_integer_from_char_array(av[1], &addr); - - if (result != 0) { - return(bad_arg ("addr")); - } else { - o->addr = (stm32_addr_t)addr; + else if ((FLASH_OTP == o->area)) { + return bad_arg("TODO: otp not implemented yet"); + if (ac > 1) return invalid_args("otp read: [path]"); + if (ac > 0) o->filename = av[0]; + break; } - } else if (o->format == FLASH_FORMAT_IHEX) { // expect filename - if (ac != 1) { return(invalid_args("write ")); } - - o->filename = av[0]; - } else { - return(-1); // should have been caught during format parsing - } + else if ((FLASH_OPTION_BYTES == o->area)) { + if (ac > 2) return invalid_args("option bytes read: [path] [size]"); + if (ac > 0) o->filename = av[0]; + if (ac > 1) { + uint32_t size; + result = get_integer_from_char_array(av[1], &size); + if (result != 0) return bad_arg("option bytes read: invalid size"); + else o->size = (size_t) size; + } + break; + } + else if ((FLASH_OPTION_BYTES_BOOT_ADD == o->area)) { + if (ac > 0) return invalid_args("option bytes boot_add read"); + break; + } + else if ((FLASH_OPTCR == o->area)) { + if (ac > 0) return invalid_args("option control register read"); + break; + } + else if ((FLASH_OPTCR1 == o->area)) { + if (ac > 0) return invalid_args("option control register 1 read"); + break; + } + break; - break; + case FLASH_CMD_WRITE: + // TODO: should be boot add 0 and boot add 1 uint32 + if (FLASH_OPTION_BYTES == o->area) { // expect filename and optional address + if (ac >=1 && ac <= 2) { + o->filename = av[0]; + } + else + return invalid_args("write [addr]"); + + if (ac == 2) { + uint32_t addr; + result = get_integer_from_char_array(av[1], &addr); + if (result != 0) return bad_arg ("addr"); + else o->addr = (stm32_addr_t) addr; + } + } + else if (FLASH_OPTION_BYTES_BOOT_ADD == o->area) { // expect option bytes boot address + if (ac != 1) return invalid_args("option bytes boot_add write "); + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) return bad_arg ("val"); + else o->val = (uint32_t) val; + } + else if (FLASH_OPTCR == o->area) { // expect option control register value + if (ac != 1) return invalid_args("option control register write "); + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) return bad_arg ("val"); + else o->val = (uint32_t) val; + } + else if (FLASH_OPTCR1 == o->area) { // expect option control register 1 value + if (ac != 1) return invalid_args("option control register 1 write "); + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) return bad_arg ("val"); + else o->val = (uint32_t) val; + } + else if (FLASH_FORMAT_BINARY == o->format) { // expect filename and addr + if (ac != 2) return invalid_args("write "); + o->filename = av[0]; + uint32_t addr; + result = get_integer_from_char_array(av[1], &addr); + if (result != 0) return bad_arg ("addr"); + else o->addr = (stm32_addr_t) addr; + } + else if (FLASH_FORMAT_IHEX == o->format) { // expect filename + if (ac != 1) return invalid_args("write "); + o->filename = av[0]; + } + else { + return -1; // should have been caught during format parsing + } + break; - default: break; + default: break ; } - return(0); + return 0; } diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 147b0e74e..3763587e1 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -11,7 +11,7 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, // No flash pages .sram_size = 0x80000, // "SRAM" byte size in hex from .bootrom_base = 0x00200000, // ! "System memory" starting address from - .bootrom_size = 0xEDC0 // ! @todo "System memory" byte size in hex from + .bootrom_size = 0xEDC0, // ! @todo "System memory" byte size in hex from .option_base = STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option bytes, writing uses FLASH_F7_OPTCR and FLASH_F7_OPTCR1 .option_size = 0x20 }, diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 0e79c3c0a..b6058cd0e 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -3,210 +3,213 @@ #include #include -#include "flash_loader.h" #define FLASH_REGS_BANK2_OFS 0x40 #define FLASH_BANK2_START_ADDR 0x08080000 /* DO NOT MODIFY SOURCECODE DIRECTLY, EDIT ASSEMBLY FILES INSTEAD */ -/* flashloaders/stm32f0.s -- compiled with thumb2 */ -static const uint8_t loader_code_stm32vl[] = { - 0x16, 0x4f, 0x3c, 0x68, - 0x16, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x16, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, - 0x4f, 0xf0, 0x01, 0x07, - 0x33, 0x68, 0x3b, 0x43, - 0x33, 0x60, 0x03, 0x88, - 0x0b, 0x80, 0x4f, 0xf0, - 0x02, 0x07, 0xc0, 0x19, - 0xc9, 0x19, 0x4f, 0xf0, - 0x01, 0x07, 0x2b, 0x68, - 0x3b, 0x42, 0xfa, 0xd0, - 0x4f, 0xf0, 0x04, 0x07, - 0x3b, 0x42, 0x04, 0xd1, - 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xe6, 0xd1, 0x4f, 0xf0, - 0x01, 0x07, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x20, 0x02, 0x40, - 0x10, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x20, - 0x54, 0x00, 0x00, 0x20, - 0x58, 0x00, 0x00, 0x20 -}; - -/* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ -static const uint8_t loader_code_stm32f0[] = { - 0xc0, 0x46, 0xc0, 0x46, - 0x13, 0x4f, 0x3c, 0x68, - 0x13, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x13, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, - 0x12, 0x4f, 0x33, 0x68, - 0x3b, 0x43, 0x33, 0x60, - 0x03, 0x88, 0x0b, 0x80, - 0x10, 0x4f, 0xc0, 0x19, - 0xc9, 0x19, 0x0e, 0x4f, - 0x2b, 0x68, 0x3b, 0x42, - 0xfb, 0xd0, 0x0e, 0x4f, - 0x3b, 0x42, 0x03, 0xd1, - 0x0a, 0x4f, 0xd2, 0x1b, - 0x00, 0x2a, 0xeb, 0xd1, - 0x08, 0x4f, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0xc0, 0x46, - 0x00, 0x20, 0x02, 0x40, - 0x10, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x20, - 0x4c, 0x00, 0x00, 0x20, - 0x50, 0x00, 0x00, 0x20, - 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00 -}; - -static const uint8_t loader_code_stm32l[] = { - // flashloaders/stm32lx.s - - 0x03, 0x68, 0x0b, 0x60, - 0x4f, 0xf0, 0x04, 0x07, - 0x38, 0x44, 0x39, 0x44, - 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xf4, 0xd1, 0x00, 0xbe, -}; - -static const uint8_t loader_code_stm32f4[] = { - // flashloaders/stm32f4.s - - 0xdf, 0xf8, 0x28, 0xc0, - 0xdf, 0xf8, 0x28, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, - 0x04, 0x00, 0x01, 0xf1, - 0x04, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 -}; - -static const uint8_t loader_code_stm32f4_lv[] = { - // flashloaders/stm32f4lv.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, - 0x01, 0x00, 0x01, 0xf1, - 0x01, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 -}; - -static const uint8_t loader_code_stm32l4[] = { - // flashloaders/stm32l4.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x44, 0x68, 0x0b, 0x60, - 0x4c, 0x60, 0x00, 0xf1, - 0x08, 0x00, 0x01, 0xf1, - 0x08, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x20, 0x02, 0x40, - 0x12, 0x00, 0x00, 0x00 -}; - -static const uint8_t loader_code_stm32f7[] = { - // flashloaders/stm32f7.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, - 0x04, 0x00, 0x01, 0xf1, - 0x04, 0x01, 0xbf, 0xf3, - 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 -}; - -static const uint8_t loader_code_stm32f7_lv[] = { - // flashloaders/stm32f7lv.s - 0xdf, 0xf8, 0x30, 0xc0, - 0xdf, 0xf8, 0x30, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, - 0x01, 0x00, 0x01, 0xf1, - 0x01, 0x01, 0xbf, 0xf3, - 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 -}; - - -int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { + /* flashloaders/stm32f0.s -- compiled with thumb2 */ + static const uint8_t loader_code_stm32vl[] = { + 0x16, 0x4f, 0x3c, 0x68, + 0x16, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x16, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x4f, 0xf0, 0x01, 0x07, + 0x33, 0x68, 0x3b, 0x43, + 0x33, 0x60, 0x03, 0x88, + 0x0b, 0x80, 0x4f, 0xf0, + 0x02, 0x07, 0xc0, 0x19, + 0xc9, 0x19, 0x4f, 0xf0, + 0x01, 0x07, 0x2b, 0x68, + 0x3b, 0x42, 0xfa, 0xd0, + 0x4f, 0xf0, 0x04, 0x07, + 0x3b, 0x42, 0x04, 0xd1, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xe6, 0xd1, 0x4f, 0xf0, + 0x01, 0x07, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x20, + 0x54, 0x00, 0x00, 0x20, + 0x58, 0x00, 0x00, 0x20 + }; + + /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ + static const uint8_t loader_code_stm32f0[] = { + 0xc0, 0x46, 0xc0, 0x46, + 0x13, 0x4f, 0x3c, 0x68, + 0x13, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x13, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x12, 0x4f, 0x33, 0x68, + 0x3b, 0x43, 0x33, 0x60, + 0x03, 0x88, 0x0b, 0x80, + 0x10, 0x4f, 0xc0, 0x19, + 0xc9, 0x19, 0x0e, 0x4f, + 0x2b, 0x68, 0x3b, 0x42, + 0xfb, 0xd0, 0x0e, 0x4f, + 0x3b, 0x42, 0x03, 0xd1, + 0x0a, 0x4f, 0xd2, 0x1b, + 0x00, 0x2a, 0xeb, 0xd1, + 0x08, 0x4f, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0xc0, 0x46, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x20, + 0x4c, 0x00, 0x00, 0x20, + 0x50, 0x00, 0x00, 0x20, + 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00 + }; + + static const uint8_t loader_code_stm32l[] = { + // flashloaders/stm32lx.s + + 0x03, 0x68, 0x0b, 0x60, + 0x4f, 0xf0, 0x04, 0x07, + 0x38, 0x44, 0x39, 0x44, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xf4, 0xd1, 0x00, 0xbe, + }; + + static const uint8_t loader_code_stm32f4[] = { + // flashloaders/stm32f4.s + + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 + }; + + static const uint8_t loader_code_stm32f4_lv[] = { + // flashloaders/stm32f4lv.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 + }; + + static const uint8_t loader_code_stm32l4[] = { + // flashloaders/stm32l4.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x44, 0x68, 0x0b, 0x60, + 0x4c, 0x60, 0x00, 0xf1, + 0x08, 0x00, 0x01, 0xf1, + 0x08, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x12, 0x00, 0x00, 0x00 + }; + + static const uint8_t loader_code_stm32f7[] = { + // flashloaders/stm32f7.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 + }; + + static const uint8_t loader_code_stm32f7_lv[] = { + // flashloaders/stm32f7lv.s + 0xdf, 0xf8, 0x30, 0xc0, + 0xdf, 0xf8, 0x30, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 + }; + + + +int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) +{ size_t size = 0; - // allocate the loader in SRAM + /* allocate the loader in sram */ if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { WLOG("Failed to write flash loader to sram!\n"); - return(-1); + return -1; } - // allocate a one page buffer in SRAM right after loader - fl->buf_addr = fl->loader_addr + (uint32_t)size; + /* allocate a one page buffer in sram right after loader */ + fl->buf_addr = fl->loader_addr + (uint32_t) size; ILOG("Successfully loaded flash loader in sram\n"); - return(0); + return 0; } static int loader_v_dependent_assignment(stlink_t *sl, const uint8_t **loader_code, size_t *loader_size, const uint8_t *high_v_loader, size_t high_v_loader_size, - const uint8_t *low_v_loader, size_t low_v_loader_size) { + const uint8_t *low_v_loader, size_t low_v_loader_size) +{ int retval = 0; - if ( sl->version.stlink_v == 1) { + if ( sl->version.stlink_v == 1){ printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes\n"); *loader_code = high_v_loader; *loader_size = high_v_loader_size; - } else { + } + else { int voltage = stlink_target_voltage(sl); - if (voltage == -1) { retval = -1; printf("Failed to read Target voltage\n"); - } else { + } + else { if (voltage > 2700) { *loader_code = high_v_loader; *loader_size = high_v_loader_size; @@ -216,11 +219,11 @@ static int loader_v_dependent_assignment(stlink_t *sl, } } } - - return(retval); + return retval; } -int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { +int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) +{ const uint8_t* loader_code; size_t loader_size; @@ -232,7 +235,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_L011 || sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { // STM32l + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { /* stm32l */ loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || @@ -245,34 +248,38 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 || - sl->chip_id == STLINK_CHIPID_STM32_F4 || - sl->chip_id == STLINK_CHIPID_STM32_F4_DE || - sl->chip_id == STLINK_CHIPID_STM32_F4_LP || - sl->chip_id == STLINK_CHIPID_STM32_F4_HD || - sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || - sl->chip_id == STLINK_CHIPID_STM32_F410 || - sl->chip_id == STLINK_CHIPID_STM32_F411RE || - sl->chip_id == STLINK_CHIPID_STM32_F412 || - sl->chip_id == STLINK_CHIPID_STM32_F413 || - sl->chip_id == STLINK_CHIPID_STM32_F446) { + sl->chip_id == STLINK_CHIPID_STM32_F4 || + sl->chip_id == STLINK_CHIPID_STM32_F4_DE || + sl->chip_id == STLINK_CHIPID_STM32_F4_LP || + sl->chip_id == STLINK_CHIPID_STM32_F4_HD || + sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || + sl->chip_id == STLINK_CHIPID_STM32_F410 || + sl->chip_id == STLINK_CHIPID_STM32_F411RE || + sl->chip_id == STLINK_CHIPID_STM32_F412 || + sl->chip_id == STLINK_CHIPID_STM32_F413 || + sl->chip_id == STLINK_CHIPID_STM32_F446 + ) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, loader_code_stm32f4, sizeof(loader_code_stm32f4), loader_code_stm32f4_lv, sizeof(loader_code_stm32f4_lv)); - - if (retval == -1) { return(retval); } + if (retval == -1) { + return retval; + } } else if (sl->core_id == STM32F7_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX || - sl->chip_id == STLINK_CHIPID_STM32_F72XXX) { + sl->chip_id == STLINK_CHIPID_STM32_F72XXX + ) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, loader_code_stm32f7, sizeof(loader_code_stm32f7), loader_code_stm32f7_lv, sizeof(loader_code_stm32f7_lv)); - - if (retval == -1) { return(retval); } + if (retval == -1) { + return retval; + } } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || sl->chip_id == STLINK_CHIPID_STM32_F04 || sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || @@ -285,102 +292,101 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* (sl->chip_id == STLINK_CHIPID_STM32_L43X) || (sl->chip_id == STLINK_CHIPID_STM32_L46X) || (sl->chip_id == STLINK_CHIPID_STM32_L4RX) || - (sl->chip_id == STLINK_CHIPID_STM32_L496X)) { + (sl->chip_id == STLINK_CHIPID_STM32_L496X)) + { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); } else { - ELOG("unknown coreid, not sure what flash loader to use, aborting! coreid: %x, chipid: %x\n", - sl->core_id, sl->chip_id); - return(-1); + ELOG("unknown coreid, not sure what flash loader to use, aborting! coreid: %x, chipid: %x\n", sl->core_id, sl->chip_id); + return -1; } memcpy(sl->q_buf, loader_code, loader_size); int ret = stlink_write_mem32(sl, sl->sram_base, loader_size); - - if (ret) { return(ret); } + if (ret) + return ret; *addr = sl->sram_base; *size = loader_size; - return(0); // success + /* success */ + return 0; } -int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { +int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) +{ struct stlink_reg rr; int i = 0; size_t count = 0; uint32_t flash_base = 0; DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); - - // TODO: This can never return -1 + // FIXME This can never return -1 if (write_buffer_to_sram(sl, fl, buf, size) == -1) { // IMPOSSIBLE! ELOG("write_buffer_to_sram() == -1\n"); - return(-1); + return -1; } if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { count = size / sizeof(uint16_t); - - if (size % sizeof(uint16_t)) { ++count; } + if (size % sizeof(uint16_t)) + ++count; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_L0) { count = size / sizeof(uint32_t); - - if (size % sizeof(uint32_t)) { ++count; } + if (size % sizeof(uint32_t)) + ++count; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { count = size / sizeof(uint64_t); - - if (size % sizeof(uint64_t)) { ++count; } + if (size % sizeof(uint64_t)) + ++count; } if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (target >= FLASH_BANK2_START_ADDR)) { flash_base = FLASH_REGS_BANK2_OFS; } - /* Setup core */ - stlink_write_reg(sl, fl->buf_addr, 0); // source - stlink_write_reg(sl, target, 1); // target - stlink_write_reg(sl, (uint32_t)count, 2); // count - stlink_write_reg(sl, flash_base, 3); // flash register base - // only used on VL/F1_XL, but harmless for others - stlink_write_reg(sl, fl->loader_addr, 15); // pc register + /* setup core */ + stlink_write_reg(sl, fl->buf_addr, 0); /* source */ + stlink_write_reg(sl, target, 1); /* target */ + stlink_write_reg(sl, (uint32_t) count, 2); /* count */ + stlink_write_reg(sl, flash_base, 3); /* flash register base, only used on VL/F1_XL, but harmless for others */ + stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ - /* Run loader */ + /* run loader */ stlink_run(sl); -/* This piece of code used to try to spin for .1 second by waiting doing 10000 rounds of 10 µs. - * But because this usually runs on Unix-like OSes, the 10 µs get rounded up to the "tick" - * (actually almost two ticks) of the system. 1 ms. Thus, the ten thousand attempts, when - * "something goes wrong" that requires the error message "flash loader run error" would wait - * for something like 20 seconds before coming up with the error. - * By increasing the sleep-per-round to the same order-of-magnitude as the tick-rounding that - * the OS uses, the wait until the error message is reduced to the same order of magnitude - * as what was intended. -- REW. - */ -#define WAIT_ROUNDS 30 - - // wait until done (reaches breakpoint) +// This piece of code used to try to spin for .1 second by waiting +// doing 10000 rounds of 10 microseconds. But because this usually runs +// on Unix-like OSes, the 10 microseconds get rounded up to the "tick" +// (actually almost two ticks) of the system. 1 milisecond. Thus, the +// ten thousand attempts, when "something goes wrong" that requires +// the error message "flash loader run error" would wait for something +// like 20 seconds before coming up with the error. +// by increasing the sleep-per-round to the same order-of-magnitude as +// the tick-rounding that the OS uses, the wait until the error message is +// reduced to the same order of magnitude as what was intended. -- REW. +#define WAIT_ROUNDS 100 + /* wait until done (reaches breakpoint) */ for (i = 0; i < WAIT_ROUNDS; i++) { - usleep(10000); - - if (stlink_is_core_halted(sl)) { break; } + usleep(1000); + if (stlink_is_core_halted(sl)) + break; } if (i >= WAIT_ROUNDS) { ELOG("flash loader run error\n"); - return(-1); + return -1; } - // check written byte count + /* check written byte count */ stlink_read_reg(sl, 2, &rr); - if (rr.r[2] != 0) { ELOG("write error, count == %u\n", rr.r[2]); - return(-1); + return -1; } - return(0); + return 0; } From 77c58f054e091f9c2c4c2db7cdb44e242901b24b Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Thu, 25 Jun 2020 14:55:34 +0200 Subject: [PATCH 0989/1435] re-applied the changes to the original files --- src/st-flash/flash_opts.c | 455 ++++++++++++++++--------------- src/stlink-lib/flash_loader.c | 486 +++++++++++++++++----------------- 2 files changed, 478 insertions(+), 463 deletions(-) diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 8557445e0..6653c6e62 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -2,11 +2,12 @@ #include #include -#include +#include "flash.h" static bool starts_with(const char * str, const char * prefix) { size_t n = strlen(prefix); - if (strlen(str) < n) return false; + + if (strlen(str) < n) { return(false); } return (0 == strncmp(str, prefix, n)); } @@ -19,37 +20,28 @@ static int get_long_integer_from_char_array (const char *const str, uint64_t *re uint64_t value; char *tail; - // hexadecimal - if (starts_with (str, "0x") || starts_with (str, "0X")) { + if (starts_with (str, "0x") || starts_with (str, "0X")) { // hexadecimal value = strtoul (str + 2, &tail, 16); - } - // binary - else if (starts_with (str, "0b") || starts_with (str, "0B")) { + } else if (starts_with (str, "0b") || starts_with (str, "0B")) { // binary value = strtoul (str + 2, &tail, 2); - } - // octal - else if (starts_with (str, "0")) { + } else if (starts_with (str, "0")) { // octal value = strtoul (str + 1, &tail, 8); - } - // decimal - else { + } else { // decimal value = strtoul (str, &tail, 10); } if (((tail[0] == 'k') || (tail[0] == 'K')) && (tail[1] == '\0')) { value = value * 1024; - } - else if (((tail[0] == 'm') || (tail[0] == 'M')) && (tail[1] == '\0')) { + } else if (((tail[0] == 'm') || (tail[0] == 'M')) && (tail[1] == '\0')) { value = value * 1024 * 1024; + } else if (tail[0] == '\0') { + /* value not changed */ + } else { + return(-1); } - else if (tail[0] == '\0') { - // value not change - } - else { - return -1; - } + *read_value = value; - return 0; + return(0); } // support positive integer from 0 to UINT32_MAX @@ -59,28 +51,26 @@ static int get_long_integer_from_char_array (const char *const str, uint64_t *re static int get_integer_from_char_array (const char *const str, uint32_t *read_value) { uint64_t value; int result = get_long_integer_from_char_array (str, &value); + if (result != 0) { - return result; - } - else if (value > UINT32_MAX) { - fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, \ -cannot convert to int32_t\n"); - return -1; - } - else { + return(result); + } else if (value > UINT32_MAX) { + fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, cannot convert to int32_t\n"); + return(-1); + } else { *read_value = (uint32_t)value; - return 0; + return(0); } } static int invalid_args(const char *expected) { fprintf(stderr, "*** Error: Expected args for this command: %s\n", expected); - return -1; + return(-1); } static int bad_arg(const char *arg) { fprintf(stderr, "*** Error: Invalid value for %s\n", arg); - return -1; + return(-1); } int flash_get_opts(struct flash_opts* o, int ac, char** av) { @@ -91,148 +81,158 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { // options int result; + while (ac >= 1) { if (strcmp(av[0], "--version") == 0) { printf("v%s\n", STLINK_VERSION); exit(EXIT_SUCCESS); - } - else if (strcmp(av[0], "--debug") == 0) { + } else if (strcmp(av[0], "--debug") == 0) { o->log_level = DEBUG_LOG_LEVEL; - } - else if (strcmp(av[0], "--opt") == 0) { + } else if (strcmp(av[0], "--opt") == 0) { o->opt = ENABLE_OPT; - } - else if (strcmp(av[0], "--reset") == 0) { + } else if (strcmp(av[0], "--reset") == 0) { o->reset = 1; - } - else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) { + } else if (strcmp(av[0], "--serial") == 0 || starts_with(av[0], "--serial=")) { const char * serial; + if (strcmp(av[0], "--serial") == 0) { ac--; av++; - if (ac < 1) return -1; + + if (ac < 1) { return(-1); } + serial = av[0]; - } - else { + } else { serial = av[0] + strlen("--serial="); } - /** @todo This is not really portable, as strlen really returns size_t we need to obey and not cast it to a signed type. */ + + /** @todo This is not really portable, as strlen really returns size_t we need to obey + and not cast it to a signed type. */ int j = (int)strlen(serial); - int length = j / 2; // the length of the destination-array - if (j % 2 != 0) return -1; + int length = j / 2; // the length of the destination-array + + if (j % 2 != 0) { return(-1); } + for (size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { char buffer[3] = {0}; memcpy(buffer, serial + j, 2); o->serial[length - k] = (uint8_t)strtol(buffer, NULL, 16); } - } - else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { + } else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { const char * area; + if (strcmp(av[0], "--area") == 0) { ac--; av++; - if (ac < 1) return -1; + + if (ac < 1) { return(-1); } + area = av[0]; - } - else { + } else { area = av[0] + strlen("--area="); } - if (strcmp(area, "main") == 0) + + if (strcmp(area, "main") == 0) { o->area = FLASH_MAIN_MEMORY; - else if (strcmp(area, "system") == 0) + } else if (strcmp(area, "system") == 0) { o->area = FLASH_SYSTEM_MEMORY; - else if (strcmp(area, "otp") == 0) + } else if (strcmp(area, "otp") == 0) { o->area = FLASH_OTP; - else if (strcmp(area, "option") == 0) + } else if (strcmp(area, "option") == 0) { o->area = FLASH_OPTION_BYTES; - else if (strcmp(area, "option_boot_add") == 0) + } else if (strcmp(area, "option_boot_add") == 0) { o->area = FLASH_OPTION_BYTES_BOOT_ADD; - else if (strcmp(area, "optcr") == 0) + } else if (strcmp(area, "optcr") == 0) { o->area = FLASH_OPTCR; - else if (strcmp(area, "optcr1") == 0) + } else if (strcmp(area, "optcr1") == 0) { o->area = FLASH_OPTCR1; - else - return -1; + } else { + return(-1); + } - } - else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) { + } else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) { const char* freq; + if (strcmp(av[0], "--freq") == 0) { ac--; av++; - if (ac < 1) return -1; + + if (ac < 1) { + return(-1); + } + freq = av[0]; - } - else { + } else { freq = av[0] + strlen("--freq="); } + if (strcmp(freq, "5K") == 0 || strcmp(freq, "5k") == 0) { o->freq = 5; - } - else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) { + } else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) { o->freq = 15; - } - else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) { + } else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) { o->freq = 25; - } - else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) { + } else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) { o->freq = 50; - } - else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) { + } else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) { o->freq = 100; - } - else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) { + } else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) { o->freq = 125; - } - else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) { + } else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) { o->freq = 240; - } - else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) { + } else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) { o->freq = 480; - } - else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) { + } else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) { o->freq = 950; - } - else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) { + } else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || + strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) { o->freq = 1200; - } - else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) { + } else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || + strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) { o->freq = 1800; - } - else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) { + } else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || + strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) { o->freq = 4000; + } else { + return(-1); } - else - return -1; - } - else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { + } else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { const char * format; + if (strcmp(av[0], "--format") == 0) { ac--; av++; - if (ac < 1) return -1; + + if (ac < 1) { return(-1); } + format = av[0]; - } - else { + } else { format = av[0] + strlen("--format="); } - if (strcmp(format, "binary") == 0) + + if (strcmp(format, "binary") == 0) { o->format = FLASH_FORMAT_BINARY; - else if (strcmp(format, "ihex") == 0) + } else if (strcmp(format, "ihex") == 0) { o->format = FLASH_FORMAT_IHEX; - else - return bad_arg("format"); - } - else if ( starts_with(av[0], "--flash=") ) { + } else { + return(bad_arg("format")); + } + } else if ( starts_with(av[0], "--flash=")) { const char *arg = av[0] + strlen("--flash="); uint32_t flash_size; result = get_integer_from_char_array(arg, &flash_size); - if (result != 0) return bad_arg ("--flash"); - else o->flash_size = (size_t) flash_size; - } - else { - break; // non-option found + + if (result != 0) { + return(bad_arg ("--flash")); + } else { + o->flash_size = (size_t)flash_size; + } + } else if (strcmp(av[0], "--connect-under-reset") == 0) { + o->connect_under_reset = true; + } else { + break; // non-option found + } ac--; @@ -242,22 +242,21 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { // command and (optional) device name while (ac >= 1) { if (strcmp(av[0], "erase") == 0) { - if (FLASH_CMD_NONE != o->cmd) return -1; + if (FLASH_CMD_NONE != o->cmd) { return(-1); } o->cmd = FLASH_CMD_ERASE; - } - else if (strcmp(av[0], "read") == 0) { - if (FLASH_CMD_NONE != o->cmd) return -1; + } else if (strcmp(av[0], "read") == 0) { + if (FLASH_CMD_NONE != o->cmd) { return(-1); } + o->cmd = FLASH_CMD_READ; - } - else if (strcmp(av[0], "write") == 0) { - if (FLASH_CMD_NONE != o->cmd) return -1; + } else if (strcmp(av[0], "write") == 0) { + if (FLASH_CMD_NONE != o->cmd) { return(-1); } + o->cmd = FLASH_CMD_WRITE; - } - else if (strcmp(av[0], "reset") == 0) { - if (FLASH_CMD_NONE != o->cmd) return -1; + } else if (strcmp(av[0], "reset") == 0) { + if (FLASH_CMD_NONE != o->cmd) { return(-1); } + o->cmd = CMD_RESET; - } - else { + } else { break; } @@ -265,120 +264,142 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { av++; } - switch(o->cmd) { - case FLASH_CMD_NONE: // no command found - return -1; - - case FLASH_CMD_ERASE: // no more arguments expected - if (ac != 0) return -1; - break; + switch (o->cmd) { + case FLASH_CMD_NONE: // no command found + return(-1); - case FLASH_CMD_READ: // expect filename, addr and size - if ((FLASH_MAIN_MEMORY == o->area) || (FLASH_SYSTEM_MEMORY == o->area)) { - if (ac != 3) return invalid_args("read "); - o->filename = av[0]; - uint32_t address; - result = get_integer_from_char_array(av[1], &address); - if (result != 0) return bad_arg ("addr"); - else o->addr = (stm32_addr_t) address; + case FLASH_CMD_ERASE: // no more arguments expected + if (ac != 0) { return(-1); } - uint32_t size; - result = get_integer_from_char_array(av[2], &size); - if (result != 0) return bad_arg ("size"); - else o->size = (size_t) size; + break; - break; + case FLASH_CMD_READ: // expect filename, addr and size + if ((FLASH_MAIN_MEMORY == o->area) || (FLASH_SYSTEM_MEMORY == o->area)) { + if (ac != 3) { return invalid_args("read "); } + + o->filename = av[0]; + uint32_t address; + result = get_integer_from_char_array(av[1], &address); + if (result != 0) { + return bad_arg ("addr"); + } else { + o->addr = (stm32_addr_t) address; } - else if ((FLASH_OTP == o->area)) { - return bad_arg("TODO: otp not implemented yet"); - if (ac > 1) return invalid_args("otp read: [path]"); - if (ac > 0) o->filename = av[0]; - break; + + uint32_t size; + result = get_integer_from_char_array(av[2], &size); + if (result != 0) { + return bad_arg ("size"); + } else { + o->size = (size_t) size; } - else if ((FLASH_OPTION_BYTES == o->area)) { - if (ac > 2) return invalid_args("option bytes read: [path] [size]"); - if (ac > 0) o->filename = av[0]; - if (ac > 1) { - uint32_t size; - result = get_integer_from_char_array(av[1], &size); - if (result != 0) return bad_arg("option bytes read: invalid size"); - else o->size = (size_t) size; + + break; + } else if ((FLASH_OTP == o->area)) { + return bad_arg("TODO: otp not implemented yet"); + if (ac > 1) { return invalid_args("otp read: [path]"); } + if (ac > 0) { o->filename = av[0]; } + break; + } else if ((FLASH_OPTION_BYTES == o->area)) { + if (ac > 2) { return invalid_args("option bytes read: [path] [size]"); } + if (ac > 0) { o->filename = av[0]; } + if (ac > 1) { + uint32_t size; + result = get_integer_from_char_array(av[1], &size); + if (result != 0) { + return bad_arg("option bytes read: invalid size"); + } else { + o->size = (size_t) size; } - break; - } - else if ((FLASH_OPTION_BYTES_BOOT_ADD == o->area)) { - if (ac > 0) return invalid_args("option bytes boot_add read"); - break; - } - else if ((FLASH_OPTCR == o->area)) { - if (ac > 0) return invalid_args("option control register read"); - break; - } - else if ((FLASH_OPTCR1 == o->area)) { - if (ac > 0) return invalid_args("option control register 1 read"); - break; } break; + } else if ((FLASH_OPTION_BYTES_BOOT_ADD == o->area)) { + if (ac > 0) { return invalid_args("option bytes boot_add read"); } + break; + } else if ((FLASH_OPTCR == o->area)) { + if (ac > 0) { return invalid_args("option control register read"); } + break; + } else if ((FLASH_OPTCR1 == o->area)) { + if (ac > 0) { return invalid_args("option control register 1 read"); } + break; + } - case FLASH_CMD_WRITE: - // TODO: should be boot add 0 and boot add 1 uint32 - if (FLASH_OPTION_BYTES == o->area) { // expect filename and optional address - if (ac >=1 && ac <= 2) { - o->filename = av[0]; - } - else - return invalid_args("write [addr]"); - - if (ac == 2) { - uint32_t addr; - result = get_integer_from_char_array(av[1], &addr); - if (result != 0) return bad_arg ("addr"); - else o->addr = (stm32_addr_t) addr; - } - } - else if (FLASH_OPTION_BYTES_BOOT_ADD == o->area) { // expect option bytes boot address - if (ac != 1) return invalid_args("option bytes boot_add write "); - - uint32_t val; - result = get_integer_from_char_array(av[0], &val); - if (result != 0) return bad_arg ("val"); - else o->val = (uint32_t) val; - } - else if (FLASH_OPTCR == o->area) { // expect option control register value - if (ac != 1) return invalid_args("option control register write "); - - uint32_t val; - result = get_integer_from_char_array(av[0], &val); - if (result != 0) return bad_arg ("val"); - else o->val = (uint32_t) val; - } - else if (FLASH_OPTCR1 == o->area) { // expect option control register 1 value - if (ac != 1) return invalid_args("option control register 1 write "); - - uint32_t val; - result = get_integer_from_char_array(av[0], &val); - if (result != 0) return bad_arg ("val"); - else o->val = (uint32_t) val; - } - else if (FLASH_FORMAT_BINARY == o->format) { // expect filename and addr - if (ac != 2) return invalid_args("write "); + break; + + case FLASH_CMD_WRITE: + // TODO: should be boot add 0 and boot add 1 uint32 + if (FLASH_OPTION_BYTES == o->area) { // expect filename and optional address + if (ac >=1 && ac <= 2) { o->filename = av[0]; + } else { + return invalid_args("write [addr]"); + } + + if (ac == 2) { uint32_t addr; result = get_integer_from_char_array(av[1], &addr); - if (result != 0) return bad_arg ("addr"); - else o->addr = (stm32_addr_t) addr; - } - else if (FLASH_FORMAT_IHEX == o->format) { // expect filename - if (ac != 1) return invalid_args("write "); - o->filename = av[0]; + if (result != 0) { + return bad_arg ("addr"); + } else { + o->addr = (stm32_addr_t) addr; + } } - else { - return -1; // should have been caught during format parsing + } else if (FLASH_OPTION_BYTES_BOOT_ADD == o->area) { // expect option bytes boot address + if (ac != 1) { return invalid_args("option bytes boot_add write "); } + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + + if (result != 0) { + return(bad_arg ("val")); + } else { + o->val = (uint32_t)val; + } + } else if (FLASH_OPTCR == o->area) { // expect option control register value + if (ac != 1) { return invalid_args("option control register write "); } + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + + if (result != 0) { + return bad_arg ("val"); + } else { + o->val = (uint32_t) val; + } + } else if (FLASH_OPTCR1 == o->area) { // expect option control register 1 value + if (ac != 1) { return invalid_args("option control register 1 write "); } + + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) { + return bad_arg ("val"); + } else { + o->val = (uint32_t) val; + } + } else if (FLASH_FORMAT_BINARY == o->format) { // expect filename and addr + if (ac != 2) { return invalid_args("write "); } + + o->filename = av[0]; + uint32_t addr; + result = get_integer_from_char_array(av[1], &addr); + + if (result != 0) { + return(bad_arg ("addr")); + } else { + o->addr = (stm32_addr_t)addr; } - break; + } else if (o->format == FLASH_FORMAT_IHEX) { // expect filename + if (ac != 1) { return(invalid_args("write ")); } + + o->filename = av[0]; + } else { + return(-1); // should have been caught during format parsing + } + + break; - default: break ; + default: break; } - return 0; + return(0); } diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index b6058cd0e..0e79c3c0a 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -3,213 +3,210 @@ #include #include +#include "flash_loader.h" #define FLASH_REGS_BANK2_OFS 0x40 #define FLASH_BANK2_START_ADDR 0x08080000 /* DO NOT MODIFY SOURCECODE DIRECTLY, EDIT ASSEMBLY FILES INSTEAD */ - /* flashloaders/stm32f0.s -- compiled with thumb2 */ - static const uint8_t loader_code_stm32vl[] = { - 0x16, 0x4f, 0x3c, 0x68, - 0x16, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x16, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, - 0x4f, 0xf0, 0x01, 0x07, - 0x33, 0x68, 0x3b, 0x43, - 0x33, 0x60, 0x03, 0x88, - 0x0b, 0x80, 0x4f, 0xf0, - 0x02, 0x07, 0xc0, 0x19, - 0xc9, 0x19, 0x4f, 0xf0, - 0x01, 0x07, 0x2b, 0x68, - 0x3b, 0x42, 0xfa, 0xd0, - 0x4f, 0xf0, 0x04, 0x07, - 0x3b, 0x42, 0x04, 0xd1, - 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xe6, 0xd1, 0x4f, 0xf0, - 0x01, 0x07, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x20, 0x02, 0x40, - 0x10, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x20, - 0x54, 0x00, 0x00, 0x20, - 0x58, 0x00, 0x00, 0x20 - }; - - /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ - static const uint8_t loader_code_stm32f0[] = { - 0xc0, 0x46, 0xc0, 0x46, - 0x13, 0x4f, 0x3c, 0x68, - 0x13, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x13, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, - 0x12, 0x4f, 0x33, 0x68, - 0x3b, 0x43, 0x33, 0x60, - 0x03, 0x88, 0x0b, 0x80, - 0x10, 0x4f, 0xc0, 0x19, - 0xc9, 0x19, 0x0e, 0x4f, - 0x2b, 0x68, 0x3b, 0x42, - 0xfb, 0xd0, 0x0e, 0x4f, - 0x3b, 0x42, 0x03, 0xd1, - 0x0a, 0x4f, 0xd2, 0x1b, - 0x00, 0x2a, 0xeb, 0xd1, - 0x08, 0x4f, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0xc0, 0x46, - 0x00, 0x20, 0x02, 0x40, - 0x10, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x20, - 0x4c, 0x00, 0x00, 0x20, - 0x50, 0x00, 0x00, 0x20, - 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32l[] = { - // flashloaders/stm32lx.s - - 0x03, 0x68, 0x0b, 0x60, - 0x4f, 0xf0, 0x04, 0x07, - 0x38, 0x44, 0x39, 0x44, - 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xf4, 0xd1, 0x00, 0xbe, - }; - - static const uint8_t loader_code_stm32f4[] = { - // flashloaders/stm32f4.s - - 0xdf, 0xf8, 0x28, 0xc0, - 0xdf, 0xf8, 0x28, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, - 0x04, 0x00, 0x01, 0xf1, - 0x04, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32f4_lv[] = { - // flashloaders/stm32f4lv.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, - 0x01, 0x00, 0x01, 0xf1, - 0x01, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32l4[] = { - // flashloaders/stm32l4.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x44, 0x68, 0x0b, 0x60, - 0x4c, 0x60, 0x00, 0xf1, - 0x08, 0x00, 0x01, 0xf1, - 0x08, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x20, 0x02, 0x40, - 0x12, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32f7[] = { - // flashloaders/stm32f7.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, - 0x04, 0x00, 0x01, 0xf1, - 0x04, 0x01, 0xbf, 0xf3, - 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 - }; - - static const uint8_t loader_code_stm32f7_lv[] = { - // flashloaders/stm32f7lv.s - 0xdf, 0xf8, 0x30, 0xc0, - 0xdf, 0xf8, 0x30, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, - 0x01, 0x00, 0x01, 0xf1, - 0x01, 0x01, 0xbf, 0xf3, - 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, - 0x00, 0xbe, 0x00, 0xbf, - 0x00, 0x3c, 0x02, 0x40, - 0x0e, 0x00, 0x00, 0x00 - }; - - - -int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) -{ +/* flashloaders/stm32f0.s -- compiled with thumb2 */ +static const uint8_t loader_code_stm32vl[] = { + 0x16, 0x4f, 0x3c, 0x68, + 0x16, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x16, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x4f, 0xf0, 0x01, 0x07, + 0x33, 0x68, 0x3b, 0x43, + 0x33, 0x60, 0x03, 0x88, + 0x0b, 0x80, 0x4f, 0xf0, + 0x02, 0x07, 0xc0, 0x19, + 0xc9, 0x19, 0x4f, 0xf0, + 0x01, 0x07, 0x2b, 0x68, + 0x3b, 0x42, 0xfa, 0xd0, + 0x4f, 0xf0, 0x04, 0x07, + 0x3b, 0x42, 0x04, 0xd1, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xe6, 0xd1, 0x4f, 0xf0, + 0x01, 0x07, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x20, + 0x54, 0x00, 0x00, 0x20, + 0x58, 0x00, 0x00, 0x20 +}; + +/* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ +static const uint8_t loader_code_stm32f0[] = { + 0xc0, 0x46, 0xc0, 0x46, + 0x13, 0x4f, 0x3c, 0x68, + 0x13, 0x4f, 0x3e, 0x68, + 0x36, 0x19, 0x13, 0x4f, + 0x3d, 0x68, 0x2d, 0x19, + 0x12, 0x4f, 0x33, 0x68, + 0x3b, 0x43, 0x33, 0x60, + 0x03, 0x88, 0x0b, 0x80, + 0x10, 0x4f, 0xc0, 0x19, + 0xc9, 0x19, 0x0e, 0x4f, + 0x2b, 0x68, 0x3b, 0x42, + 0xfb, 0xd0, 0x0e, 0x4f, + 0x3b, 0x42, 0x03, 0xd1, + 0x0a, 0x4f, 0xd2, 0x1b, + 0x00, 0x2a, 0xeb, 0xd1, + 0x08, 0x4f, 0x33, 0x68, + 0xbb, 0x43, 0x33, 0x60, + 0x00, 0xbe, 0xc0, 0x46, + 0x00, 0x20, 0x02, 0x40, + 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x20, + 0x4c, 0x00, 0x00, 0x20, + 0x50, 0x00, 0x00, 0x20, + 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32l[] = { + // flashloaders/stm32lx.s + + 0x03, 0x68, 0x0b, 0x60, + 0x4f, 0xf0, 0x04, 0x07, + 0x38, 0x44, 0x39, 0x44, + 0x4f, 0xf0, 0x01, 0x07, + 0xd2, 0x1b, 0x00, 0x2a, + 0xf4, 0xd1, 0x00, 0xbe, +}; + +static const uint8_t loader_code_stm32f4[] = { + // flashloaders/stm32f4.s + + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32f4_lv[] = { + // flashloaders/stm32f4lv.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32l4[] = { + // flashloaders/stm32l4.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x44, 0x68, 0x0b, 0x60, + 0x4c, 0x60, 0x00, 0xf1, + 0x08, 0x00, 0x01, 0xf1, + 0x08, 0x01, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x20, 0x02, 0x40, + 0x12, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32f7[] = { + // flashloaders/stm32f7.s + 0xdf, 0xf8, 0x2c, 0xc0, + 0xdf, 0xf8, 0x2c, 0xa0, + 0xe2, 0x44, 0x03, 0x68, + 0x0b, 0x60, 0x00, 0xf1, + 0x04, 0x00, 0x01, 0xf1, + 0x04, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 +}; + +static const uint8_t loader_code_stm32f7_lv[] = { + // flashloaders/stm32f7lv.s + 0xdf, 0xf8, 0x30, 0xc0, + 0xdf, 0xf8, 0x30, 0xa0, + 0xe2, 0x44, 0x4f, 0xea, + 0x82, 0x02, 0x03, 0x78, + 0x0b, 0x70, 0x00, 0xf1, + 0x01, 0x00, 0x01, 0xf1, + 0x01, 0x01, 0xbf, 0xf3, + 0x4f, 0x8f, 0xba, 0xf8, + 0x00, 0x30, 0x13, 0xf0, + 0x01, 0x0f, 0xfa, 0xd0, + 0xa2, 0xf1, 0x01, 0x02, + 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0xbe, 0x00, 0xbf, + 0x00, 0x3c, 0x02, 0x40, + 0x0e, 0x00, 0x00, 0x00 +}; + + +int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { size_t size = 0; - /* allocate the loader in sram */ + // allocate the loader in SRAM if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { WLOG("Failed to write flash loader to sram!\n"); - return -1; + return(-1); } - /* allocate a one page buffer in sram right after loader */ - fl->buf_addr = fl->loader_addr + (uint32_t) size; + // allocate a one page buffer in SRAM right after loader + fl->buf_addr = fl->loader_addr + (uint32_t)size; ILOG("Successfully loaded flash loader in sram\n"); - return 0; + return(0); } static int loader_v_dependent_assignment(stlink_t *sl, const uint8_t **loader_code, size_t *loader_size, const uint8_t *high_v_loader, size_t high_v_loader_size, - const uint8_t *low_v_loader, size_t low_v_loader_size) -{ + const uint8_t *low_v_loader, size_t low_v_loader_size) { int retval = 0; - if ( sl->version.stlink_v == 1){ + if ( sl->version.stlink_v == 1) { printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes\n"); *loader_code = high_v_loader; *loader_size = high_v_loader_size; - } - else { + } else { int voltage = stlink_target_voltage(sl); + if (voltage == -1) { retval = -1; printf("Failed to read Target voltage\n"); - } - else { + } else { if (voltage > 2700) { *loader_code = high_v_loader; *loader_size = high_v_loader_size; @@ -219,11 +216,11 @@ static int loader_v_dependent_assignment(stlink_t *sl, } } } - return retval; + + return(retval); } -int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) -{ +int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { const uint8_t* loader_code; size_t loader_size; @@ -235,7 +232,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_L011 || sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { /* stm32l */ + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { // STM32l loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || @@ -248,38 +245,34 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 || - sl->chip_id == STLINK_CHIPID_STM32_F4 || - sl->chip_id == STLINK_CHIPID_STM32_F4_DE || - sl->chip_id == STLINK_CHIPID_STM32_F4_LP || - sl->chip_id == STLINK_CHIPID_STM32_F4_HD || - sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || - sl->chip_id == STLINK_CHIPID_STM32_F410 || - sl->chip_id == STLINK_CHIPID_STM32_F411RE || - sl->chip_id == STLINK_CHIPID_STM32_F412 || - sl->chip_id == STLINK_CHIPID_STM32_F413 || - sl->chip_id == STLINK_CHIPID_STM32_F446 - ) { + sl->chip_id == STLINK_CHIPID_STM32_F4 || + sl->chip_id == STLINK_CHIPID_STM32_F4_DE || + sl->chip_id == STLINK_CHIPID_STM32_F4_LP || + sl->chip_id == STLINK_CHIPID_STM32_F4_HD || + sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || + sl->chip_id == STLINK_CHIPID_STM32_F410 || + sl->chip_id == STLINK_CHIPID_STM32_F411RE || + sl->chip_id == STLINK_CHIPID_STM32_F412 || + sl->chip_id == STLINK_CHIPID_STM32_F413 || + sl->chip_id == STLINK_CHIPID_STM32_F446) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, loader_code_stm32f4, sizeof(loader_code_stm32f4), loader_code_stm32f4_lv, sizeof(loader_code_stm32f4_lv)); - if (retval == -1) { - return retval; - } + + if (retval == -1) { return(retval); } } else if (sl->core_id == STM32F7_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX || - sl->chip_id == STLINK_CHIPID_STM32_F72XXX - ) { + sl->chip_id == STLINK_CHIPID_STM32_F72XXX) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, loader_code_stm32f7, sizeof(loader_code_stm32f7), loader_code_stm32f7_lv, sizeof(loader_code_stm32f7_lv)); - if (retval == -1) { - return retval; - } + + if (retval == -1) { return(retval); } } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || sl->chip_id == STLINK_CHIPID_STM32_F04 || sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || @@ -292,101 +285,102 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* (sl->chip_id == STLINK_CHIPID_STM32_L43X) || (sl->chip_id == STLINK_CHIPID_STM32_L46X) || (sl->chip_id == STLINK_CHIPID_STM32_L4RX) || - (sl->chip_id == STLINK_CHIPID_STM32_L496X)) - { + (sl->chip_id == STLINK_CHIPID_STM32_L496X)) { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); } else { - ELOG("unknown coreid, not sure what flash loader to use, aborting! coreid: %x, chipid: %x\n", sl->core_id, sl->chip_id); - return -1; + ELOG("unknown coreid, not sure what flash loader to use, aborting! coreid: %x, chipid: %x\n", + sl->core_id, sl->chip_id); + return(-1); } memcpy(sl->q_buf, loader_code, loader_size); int ret = stlink_write_mem32(sl, sl->sram_base, loader_size); - if (ret) - return ret; + + if (ret) { return(ret); } *addr = sl->sram_base; *size = loader_size; - /* success */ - return 0; + return(0); // success } -int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) -{ +int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { struct stlink_reg rr; int i = 0; size_t count = 0; uint32_t flash_base = 0; DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); - // FIXME This can never return -1 + + // TODO: This can never return -1 if (write_buffer_to_sram(sl, fl, buf, size) == -1) { // IMPOSSIBLE! ELOG("write_buffer_to_sram() == -1\n"); - return -1; + return(-1); } if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { count = size / sizeof(uint16_t); - if (size % sizeof(uint16_t)) - ++count; + + if (size % sizeof(uint16_t)) { ++count; } } else if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_L0) { count = size / sizeof(uint32_t); - if (size % sizeof(uint32_t)) - ++count; + + if (size % sizeof(uint32_t)) { ++count; } } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { count = size / sizeof(uint64_t); - if (size % sizeof(uint64_t)) - ++count; + + if (size % sizeof(uint64_t)) { ++count; } } if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (target >= FLASH_BANK2_START_ADDR)) { flash_base = FLASH_REGS_BANK2_OFS; } - /* setup core */ - stlink_write_reg(sl, fl->buf_addr, 0); /* source */ - stlink_write_reg(sl, target, 1); /* target */ - stlink_write_reg(sl, (uint32_t) count, 2); /* count */ - stlink_write_reg(sl, flash_base, 3); /* flash register base, only used on VL/F1_XL, but harmless for others */ - stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ + /* Setup core */ + stlink_write_reg(sl, fl->buf_addr, 0); // source + stlink_write_reg(sl, target, 1); // target + stlink_write_reg(sl, (uint32_t)count, 2); // count + stlink_write_reg(sl, flash_base, 3); // flash register base + // only used on VL/F1_XL, but harmless for others + stlink_write_reg(sl, fl->loader_addr, 15); // pc register - /* run loader */ + /* Run loader */ stlink_run(sl); -// This piece of code used to try to spin for .1 second by waiting -// doing 10000 rounds of 10 microseconds. But because this usually runs -// on Unix-like OSes, the 10 microseconds get rounded up to the "tick" -// (actually almost two ticks) of the system. 1 milisecond. Thus, the -// ten thousand attempts, when "something goes wrong" that requires -// the error message "flash loader run error" would wait for something -// like 20 seconds before coming up with the error. -// by increasing the sleep-per-round to the same order-of-magnitude as -// the tick-rounding that the OS uses, the wait until the error message is -// reduced to the same order of magnitude as what was intended. -- REW. -#define WAIT_ROUNDS 100 - /* wait until done (reaches breakpoint) */ +/* This piece of code used to try to spin for .1 second by waiting doing 10000 rounds of 10 µs. + * But because this usually runs on Unix-like OSes, the 10 µs get rounded up to the "tick" + * (actually almost two ticks) of the system. 1 ms. Thus, the ten thousand attempts, when + * "something goes wrong" that requires the error message "flash loader run error" would wait + * for something like 20 seconds before coming up with the error. + * By increasing the sleep-per-round to the same order-of-magnitude as the tick-rounding that + * the OS uses, the wait until the error message is reduced to the same order of magnitude + * as what was intended. -- REW. + */ +#define WAIT_ROUNDS 30 + + // wait until done (reaches breakpoint) for (i = 0; i < WAIT_ROUNDS; i++) { - usleep(1000); - if (stlink_is_core_halted(sl)) - break; + usleep(10000); + + if (stlink_is_core_halted(sl)) { break; } } if (i >= WAIT_ROUNDS) { ELOG("flash loader run error\n"); - return -1; + return(-1); } - /* check written byte count */ + // check written byte count stlink_read_reg(sl, 2, &rr); + if (rr.r[2] != 0) { ELOG("write error, count == %u\n", rr.r[2]); - return -1; + return(-1); } - return 0; + return(0); } From a5b98f58756b6a1414ca8175c578e07998a59061 Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Thu, 25 Jun 2020 15:00:53 +0200 Subject: [PATCH 0990/1435] Fix compiler warning implicit cast --- src/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 58e67d447..86d2ca8ea 100644 --- a/src/common.c +++ b/src/common.c @@ -3421,7 +3421,7 @@ int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t* option_byte) { } } - return stlink_read_debug32(sl, sl->option_base + (sl->option_size / 4 - 1) * sizeof(uint32_t), option_byte); + return stlink_read_debug32(sl, sl->option_base + (uint32_t) (sl->option_size / 4 - 1) * sizeof(uint32_t), option_byte); } /** From fc56f2412d80f09843b8f37a670ffc516640faaa Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 27 Jun 2020 02:28:00 +0200 Subject: [PATCH 0991/1435] General Project Update - Updated CHANGELOG.md - cpack: corrections for pkg config --- CHANGELOG.md | 3 ++- cmake/packaging/deb/changelog | 50 +++-------------------------------- cmake/packaging/deb/control | 4 +-- cmake/packaging/deb/copyright | 5 ++-- cmake/packaging/deb/rules | 3 +-- cmake/packaging/rpm/changelog | 4 +-- doc/version_support.md | 2 +- 7 files changed, 13 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3195bae3c..7717ca6f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ Features: * Support for STM32L1, SM32L4 option bytes write ([#596](https://github.com/stlink-org/stlink/pull/596), [#844](https://github.com/stlink-org/stlink/pull/844), [#847](https://github.com/stlink-org/stlink/pull/847)) * Added CMAKEFLAGS and install target ([#804](https://github.com/stlink-org/stlink/pull/804), [#935](https://github.com/stlink-org/stlink/pull/935)) * Support for STM32G4 ([#822](https://github.com/stlink-org/stlink/pull/822)) -* Add aliased SRAM2 region in the L496 memory map ([#824](https://github.com/stlink-org/stlink/pull/824)) +* Added aliased SRAM2 region in the L496 memory map ([#824](https://github.com/stlink-org/stlink/pull/824)) * Improved support for STM32G0 ([#825](https://github.com/stlink-org/stlink/pull/825), [#850](https://github.com/stlink-org/stlink/pull/850), [#856](https://github.com/stlink-org/stlink/pull/856), [#857](https://github.com/stlink-org/stlink/pull/857)) * Added postinst script with 'depmod -a' for 'make package' ([#845](https://github.com/stlink-org/stlink/pull/845), [#931](https://github.com/stlink-org/stlink/pull/931)) * Calculate checksums for flash operations ([#862](https://github.com/stlink-org/stlink/pull/862), [#924](https://github.com/stlink-org/stlink/pull/924)) @@ -358,6 +358,7 @@ Chip support added for: * STM32F469/STM32F479 ([#345](https://github.com/stlink-org/stlink/pull/345), [#555](https://github.com/stlink-org/stlink/pull/555)) (Release v1.2.0) * STM32L1xx Cat.2 devices (Nicolas Schodet) * STM32L1xx (chip-ID 0x427) ([#152](https://github.com/stlink-org/stlink/pull/152), [#163](https://github.com/stlink-org/stlink/pull/163), [#165](https://github.com/stlink-org/stlink/pull/165)) (Release v1.0.0) +* Added SIGINT handler for stlink cleanup ([#31](https://github.com/stlink-org/stlink/pull/31), [#135](https://github.com/stlink-org/stlink/pull/135)) (Release v1.0.0) Board support added for: diff --git a/cmake/packaging/deb/changelog b/cmake/packaging/deb/changelog index f4b644176..ec65e6744 100644 --- a/cmake/packaging/deb/changelog +++ b/cmake/packaging/deb/changelog @@ -1,49 +1,5 @@ -stlink (1.6.0+ds-1) unstable; urgency=medium +stlink (1.6.1+ds-1) unstable; urgency=medium - * Merge tag 'v1.6.0' into debian - * Bump Standards-Version to 4.5.0, no changes. - * Update libstlink1 symbols file for 1.6.0. + * Initial cpack-based package release for Debian/Ubuntu - -- Luca Boccassi Tue, 25 Feb 2020 22:08:33 +0000 - -stlink (1.5.1+ds-2) unstable; urgency=medium - - * Mark library packages as Multi-Arch: same. - * Apply cross.patch to fix cross-compiling the GUI. Thanks Helmut for the patch! (Closes: #941320) - * Vcs-Git: add -b debian - * Set Rules-Requires-Root: no - * Bump Standards-Version to 4.4.0 - - -- Luca Boccassi Sun, 29 Sep 2019 12:50:58 +0100 - -stlink (1.5.1+ds-1) unstable; urgency=medium - - * Merge tag 'v1.5.1' into debian. See upstream changelog for info: - https://github.com/stlink-org/stlink/releases/tag/v1.5.1 - * Mark packages as linux-any, other systems not supported. - - -- Luca Boccassi Fri, 28 Sep 2018 10:26:39 +0100 - -stlink (1.5.0+ds-1) unstable; urgency=medium - - * Upload to unstable. (Closes: #869421) - - -- Luca Boccassi Fri, 16 Mar 2018 16:56:17 +0000 - -stlink (1.4.0) unstable; urgency=low - - -- Andrew 'Necromant' Andrianov Sat, 01 Jul 2017 00:00:00 +0000 - -stlink (1.3.1) unstable; urgency=low - - -- Andrew 'Necromant' Andrianov Sat, 25 Feb 2017 00:00:00 +0000 - -stlink (1.3.0) unstable; urgency=low - - -- Andrew 'Necromant' Andrianov Sat, 28 Jan 2017 00:00:00 +0000 - -stlink (1.2.1) unstable; urgency=low - - * Initial Debian-Packaged Release. - - -- Andrew 'Necromant' Andrianov Sat, 09 Jul 2016 23:16:07 +0300 + -- Nightwalker-87 Sat, 06 Jun 2020 00:00:00 +0100 diff --git a/cmake/packaging/deb/control b/cmake/packaging/deb/control index d96746e65..9f17b0042 100644 --- a/cmake/packaging/deb/control +++ b/cmake/packaging/deb/control @@ -1,7 +1,7 @@ Source: stlink -Maintainer: Luca Bocassi +Maintainer: stlink-org Build-Depends: cmake, dh-cmake, debhelper (>= 9), libusb-1.0-0-dev, libgtk-3-dev -Standards-Version: 4.1.3 +Standards-Version: 4.5.0 Section: electronics Priority: optional Homepage: https://github.com/stlink-org/stlink diff --git a/cmake/packaging/deb/copyright b/cmake/packaging/deb/copyright index a14d4eb6e..fb1c49d74 100644 --- a/cmake/packaging/deb/copyright +++ b/cmake/packaging/deb/copyright @@ -1,9 +1,8 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: stlink -Upstream-Contact: Luca Bocassi +Upstream-Contact: stlink-org Source: https://github.com/stlink-org/stlink -Disclaimer: -Comment: + Files: * Copyright: 2011-2020 stlink-org Martin Capitanio [capnm] diff --git a/cmake/packaging/deb/rules b/cmake/packaging/deb/rules index 2f80faeac..ae3abcabe 100755 --- a/cmake/packaging/deb/rules +++ b/cmake/packaging/deb/rules @@ -1,7 +1,7 @@ #!/usr/bin/make -f # See debhelper(7) (uncomment to enable) # output every command that modifies files on the build system. -DH_VERBOSE = 1 +#DH_VERBOSE = 1 # see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* DPKG_EXPORT_BUILDFLAGS = 1 @@ -15,5 +15,4 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all override_dh_auto_configure: dh_auto_configure -- \ - -DLIB_INSTALL_DIR=/usr/lib/$(DEB_HOST_MULTIARCH) \ -DSTLINK_UDEV_RULES_DIR='/lib/udev/rules.d' diff --git a/cmake/packaging/rpm/changelog b/cmake/packaging/rpm/changelog index de2400d65..564bd95ae 100644 --- a/cmake/packaging/rpm/changelog +++ b/cmake/packaging/rpm/changelog @@ -1,2 +1,2 @@ -* Mon Jun 01 2020 Vasiliy Glazov - 1.6.1 -- Initial RPM-packaged release +* Mon Jun 01 2020 Nightwalker-87 - 1.6.1 +- Initial cpack-based RPM package release diff --git a/doc/version_support.md b/doc/version_support.md index 4d1f724f7..4076fb422 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -68,7 +68,7 @@ NOTE: In order to use a STLINK/v1 programmer on macOS, versions 10.13, 10.14 or ## Unsupported Operating Systems (as of Release v1.6.1) -| Operating System | libusb
      version | cmake
      version | End of OS-Support | Notes | +| Operating System | libusb
      version | cmake
      version | End of
      OS-Support | Notes | | --- | --- | --- | --- | --- | | CentOS 7 | 1.0.21 | **2.8.12.2** | | named `libusbx`, but
      `libusb`-codebase is used | | Debian 8 (Jessie) | 1.0.**19** | 3.**0.2** | Jun 2020 | From 31b1fa16201521e2aaf464576f2f169981abede0 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 28 Jun 2020 21:01:59 +0200 Subject: [PATCH 0992/1435] Fixed install paths (headers & stlink-gui.ui) --- CMakeLists.txt | 4 ++-- src/stlink-gui/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5171628ad..fae458dd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,7 +86,7 @@ include_directories(src/st-flash) include_directories(src/stlink-lib) ## Set installation directory for header files -set(STLINK_INCLUDE_PATH ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Main include install directory") +set(STLINK_INCLUDE_PATH ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} CACHE PATH "Main include install directory") ## Subordinate CMakeLists for version config & header installation add_subdirectory(inc) @@ -147,7 +147,7 @@ endif () set(STLINK_LIBRARY_PATH ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Main library install directory") # Set the environment variable LD_LIBRARY_PATH to point to /usr/local/lib (per default). -execute_process (COMMAND bash -c "export LD_LIBRARY_PATH=${CMAKE_INSTALL_LIBDIR}") +execute_process(COMMAND bash -c "export LD_LIBRARY_PATH=${CMAKE_INSTALL_LIBDIR}") ### diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index 89e5403d8..258f83cc1 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -33,9 +33,9 @@ if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) ## stlink-gui add_executable(stlink-gui ${GUI_SOURCES}) - install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}) set_target_properties(stlink-gui PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/bin") + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}") target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) install(TARGETS stlink-gui DESTINATION ${CMAKE_INSTALL_BINDIR}) endif () From 66c6696337c2e6e3db5036422e0cd10726b428ab Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 28 Jun 2020 22:48:30 +0200 Subject: [PATCH 0993/1435] Corrected settings for deb pkg distribution --- cmake/packaging/deb/changelog | 50 +--------- cmake/packaging/deb/control | 7 +- cmake/packaging/deb/copyright | 8 +- cmake/packaging/deb/rules | 3 +- debian/changelog | 122 +---------------------- debian/control | 22 ++--- debian/copyright | 178 ++++++---------------------------- debian/libstlink-dev.install | 1 - debian/stlink-gui.install | 6 +- debian/stlink.pc.in | 2 +- 10 files changed, 58 insertions(+), 341 deletions(-) diff --git a/cmake/packaging/deb/changelog b/cmake/packaging/deb/changelog index f4b644176..196da940e 100644 --- a/cmake/packaging/deb/changelog +++ b/cmake/packaging/deb/changelog @@ -1,49 +1,5 @@ -stlink (1.6.0+ds-1) unstable; urgency=medium +stlink (1.6.1) unstable; urgency=medium - * Merge tag 'v1.6.0' into debian - * Bump Standards-Version to 4.5.0, no changes. - * Update libstlink1 symbols file for 1.6.0. + * Initial Debian-packaged Release. - -- Luca Boccassi Tue, 25 Feb 2020 22:08:33 +0000 - -stlink (1.5.1+ds-2) unstable; urgency=medium - - * Mark library packages as Multi-Arch: same. - * Apply cross.patch to fix cross-compiling the GUI. Thanks Helmut for the patch! (Closes: #941320) - * Vcs-Git: add -b debian - * Set Rules-Requires-Root: no - * Bump Standards-Version to 4.4.0 - - -- Luca Boccassi Sun, 29 Sep 2019 12:50:58 +0100 - -stlink (1.5.1+ds-1) unstable; urgency=medium - - * Merge tag 'v1.5.1' into debian. See upstream changelog for info: - https://github.com/stlink-org/stlink/releases/tag/v1.5.1 - * Mark packages as linux-any, other systems not supported. - - -- Luca Boccassi Fri, 28 Sep 2018 10:26:39 +0100 - -stlink (1.5.0+ds-1) unstable; urgency=medium - - * Upload to unstable. (Closes: #869421) - - -- Luca Boccassi Fri, 16 Mar 2018 16:56:17 +0000 - -stlink (1.4.0) unstable; urgency=low - - -- Andrew 'Necromant' Andrianov Sat, 01 Jul 2017 00:00:00 +0000 - -stlink (1.3.1) unstable; urgency=low - - -- Andrew 'Necromant' Andrianov Sat, 25 Feb 2017 00:00:00 +0000 - -stlink (1.3.0) unstable; urgency=low - - -- Andrew 'Necromant' Andrianov Sat, 28 Jan 2017 00:00:00 +0000 - -stlink (1.2.1) unstable; urgency=low - - * Initial Debian-Packaged Release. - - -- Andrew 'Necromant' Andrianov Sat, 09 Jul 2016 23:16:07 +0300 + -- Nightwalker-87 Mon, 01 Jun 2020 00:00:00 +0100 diff --git a/cmake/packaging/deb/control b/cmake/packaging/deb/control index d96746e65..759668ba6 100644 --- a/cmake/packaging/deb/control +++ b/cmake/packaging/deb/control @@ -1,9 +1,10 @@ Source: stlink -Maintainer: Luca Bocassi +Priority: optional +Maintainer: stlink-org Build-Depends: cmake, dh-cmake, debhelper (>= 9), libusb-1.0-0-dev, libgtk-3-dev -Standards-Version: 4.1.3 +Standards-Version: 4.5.0 +Rules-Requires-Root: no Section: electronics -Priority: optional Homepage: https://github.com/stlink-org/stlink Vcs-Git: https://github.com/stlink-org/stlink.git Vcs-Browser: https://github.com/stlink-org/stlink diff --git a/cmake/packaging/deb/copyright b/cmake/packaging/deb/copyright index a14d4eb6e..f5dfdc51b 100644 --- a/cmake/packaging/deb/copyright +++ b/cmake/packaging/deb/copyright @@ -1,9 +1,9 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: stlink -Upstream-Contact: Luca Bocassi +Upstream-Contact: Nightwalker-87 Source: https://github.com/stlink-org/stlink -Disclaimer: -Comment: +Files-Excluded: stlinkv1_macos_driver + Files: * Copyright: 2011-2020 stlink-org Martin Capitanio [capnm] @@ -11,7 +11,7 @@ Copyright: 2011-2020 stlink-org Jerry Jacobs [xor-gate] [Nightwalker-87] and many others... - A list of contributors can be found in "contributors.txt". + An extended list of contributors can be found in "contributors.txt". License: BSD-3-clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/cmake/packaging/deb/rules b/cmake/packaging/deb/rules index 2f80faeac..ae3abcabe 100755 --- a/cmake/packaging/deb/rules +++ b/cmake/packaging/deb/rules @@ -1,7 +1,7 @@ #!/usr/bin/make -f # See debhelper(7) (uncomment to enable) # output every command that modifies files on the build system. -DH_VERBOSE = 1 +#DH_VERBOSE = 1 # see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* DPKG_EXPORT_BUILDFLAGS = 1 @@ -15,5 +15,4 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all override_dh_auto_configure: dh_auto_configure -- \ - -DLIB_INSTALL_DIR=/usr/lib/$(DEB_HOST_MULTIARCH) \ -DSTLINK_UDEV_RULES_DIR='/lib/udev/rules.d' diff --git a/debian/changelog b/debian/changelog index f1265ee32..c54850340 100644 --- a/debian/changelog +++ b/debian/changelog @@ -44,7 +44,7 @@ stlink (1.5.1+ds-2) unstable; urgency=medium stlink (1.5.1+ds-1) unstable; urgency=medium * Merge tag 'v1.5.1' into debian. See upstream changelog for info: - https://github.com/texane/stlink/releases/tag/v1.5.1 + https://github.com/stlink-org/stlink/releases/tag/v1.5.1 * Mark packages as linux-any, other systems not supported. -- Luca Boccassi Fri, 28 Sep 2018 10:26:39 +0100 @@ -55,131 +55,19 @@ stlink (1.5.0+ds-1) unstable; urgency=medium -- Luca Boccassi Fri, 16 Mar 2018 16:56:17 +0000 -stlink (1.5.0) unstable; urgency=medium - - [ Jerry Jacobs ] - * README.md: Update version badge to v1.4.0 - - [ Viallard Anthony ] - * Add support of STM32L496xx/4A6xx devices (#615) - - [ rdlim ] - * Fix verification of flash error for STM32L496x device (#617) (#618) - - [ dflogeras ] - * Add note about availability in Gentoo package manager (#622) - - [ yaofei zheng ] - * update debian package version (#630) - - [ Lyle Cheatham ] - * Minor formatting fix in FAQ section of README.md (#631) - - [ Vasiliy Glazov ] - * README.md: Added information about Fedora and RedHat/CentOS packages. - (#635) - * Added LIB_INSTALL_DIR to correct libs install on 64-bit systems (#636) - - [ Gwenhael Goavec-Merou ] - * fix write for microcontroler with RAM size less or equal to 32K (#637) - - [ Mateusz Krawiec ] - * Fix memory map for stm32l496xx boards. (#639) - - [ Rüdiger Fortanier ] - * Add unknown chip output (#641) - - [ Slyshyk Oleksiy ] - * fix __FILE__ base name extraction, #628 (#648) - - [ texane ] - * STM32F72xx73xx support, from bob.feretich@rafresearch.com - - [ Kirill Kolyshkin ] - * debian/triggers: add (to run ldconfig) (#664) - - [ Slyshyk Oleksiy ] - * Try to fix #666 issue (#667) - * Try to fix 666 issue (#668) - - [ Jerry Jacobs ] - * Update ChangeLog.md - * Update README.md - - [ texane ] - * STM32F042K6 Nucleo-32 Board reported to work, by frank@bauernoeppel.de - - [ Anatol Pomozov ] - * Update .version file to match release number (#670) - - -- Anatol Pomozov Mon, 19 Feb 2018 11:00:29 -0800 - -libstlink (1.4.0) unstable; urgency=low - - * Major changes and added features - - Add support for STM32L452 target (#608) - - Initial support to compile with Microsoft Visual Studio 2017 (#602) - - Added support for flashing second bank on STM32F10x_XL (#592) - - Add support for STM32L011 target (#572) - - Allow building of debian package with CPack (@xor-gate) - * Updates and fixes - - Fix compilation with GCC 7 (#590) - - Skip GTK detection if we're cross-compiling (#588) - - Fix possible memory leak (#570) - - Fix building with mingw64 (#569, #610) - - Update libusb to 1.0.21 for Windows (#562) - - Fixing low-voltage flashing on STM32F7 parts. (#567) - - Update libusb to 1.0.21 for Windows (#562) +stlink (1.4.0) unstable; urgency=low -- Andrew 'Necromant' Andrianov Sat, 01 Jul 2017 00:00:00 +0000 -libstlink (1.3.1) unstable; urgency=low - - * Major changes and added features: - - Add preliminary support for STM32L011 to see it after probe (chipid 0x457) (@xor-gate) - - Strip full paths to source files in log (commit #2c0ab7f) - - Add support for STM32F413 target (#549) - - Add support for Semihosting SYS_READC (#546) - * Updates and fixes: - - Update documentation markdown files - - Compilation fixes (#552) - - Fix compilation when path includes spaces (#561) +stlink (1.3.1) unstable; urgency=low -- Andrew 'Necromant' Andrianov Sat, 25 Feb 2017 00:00:00 +0000 -libstlink (1.3.0) unstable; urgency=low - - * Major changes and added features: - - Deprecation of autotools (autoconf, automake) (@xor-gate) - - Removal of undocumented st-term utility, which is now replaced by st-util ARM semihosting feature (#3fd0f09) - - Add support for native debian packaging (#444, #485) - - Add intel hex file reading for st-flash (#459) - - Add --reset command to st-flash (#505) - - Support serial numbers argument for st-util and st-flash for multi-programmer setups (#541) - - Add kill ('k') command to gdb-server for st-util (#9804416) - - Add manpages (generated with pandoc from Markdown) (#464) - - Rewrite commandline parsing for st-flash (#459) - - Add support for ARM semihosting to st-util (#454, #455) - * Chip support added for: - - STM32L432 (#501) - - STM32F412 (#538) - - STM32F410 (#9c635e4) - - Add memory map for STM32F401XE (#460) - - L0x Category 5 devices (#406) - - Add L0 Category 2 device (chip id: 0x425) (#72b8e5e) - * Updates and fixes: - - Fixed STM32F030 erase error (#442) - - Fixed Cygwin build (#68b0f3b) - - Reset flash mass erase (MER) bit after mass erase for safety (#489) - - Fix memory map for STM32F4 (@zulusw) - - Fix STM32L-problem with flash loader (issue #390) (Tom de Boer) - - st-util don't read target voltage on startup as it crashes STM32F100 (probably stlink/v1) (Greg Alexander) - - Do a JTAG reset prior to reading CPU information when processor is in deep sleep (@andyg24) - - Redesign of st-flash commandline options parsing (pull-request #459) (@dev26th) +stlink (1.3.0) unstable; urgency=low -- Andrew 'Necromant' Andrianov Sat, 28 Jan 2017 00:00:00 +0000 -libstlink (1.2.1) unstable; urgency=low +stlink (1.2.1) unstable; urgency=low * Initial Debian-Packaged Release. diff --git a/debian/control b/debian/control index 3ac6af91f..598e0e89f 100644 --- a/debian/control +++ b/debian/control @@ -14,9 +14,7 @@ Section: libdevel Architecture: linux-any Multi-Arch: same Depends: libstlink1 (= ${binary:Version}), ${misc:Depends} -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. +Description: Open source STM32 MCU programming toolset. . This package contains the development files for stlink. @@ -25,28 +23,22 @@ Section: libs Architecture: linux-any Multi-Arch: same Depends: ${shlibs:Depends}, ${misc:Depends} -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. +Description: Open source STM32 MCU programming toolset. . This package contains the shared library for stlink. Package: stlink-tools Architecture: linux-any Depends: libstlink1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. +Description: Open source STM32 MCU programming toolset. . - This package contains commandline utilities for stlink, and modprobe and - udev rules. + This package contains commandline utilities for stlink, modprobe- and + udev-rules. Package: stlink-gui Architecture: linux-any Depends: libstlink1 (= ${binary:Version}), stlink-tools (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. +Description: Open source STM32 MCU programming toolset. . - This package contains a GUI tool for stlink. + This package contains a GUI for stlink. diff --git a/debian/copyright b/debian/copyright index 1a0febd9c..8329cc250 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,155 +1,37 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: stlink -Upstream-Contact: Andrew 'Necromant' Andrianov +Upstream-Contact: Luca Boccassi Source: https://github.com/stlink-org/stlink -Comment: Upstream tarball has been repackaged to remove binary OSX kernel - drivers that are of unknown license and of no use to Debian. Files-Excluded: stlinkv1_macos_driver Files: * -Copyright: 2011-2018 agpanarin - 2011-2018 Alexey Cherevatenko - 2011-2018 Anatoli - 2011-2018 Andrea Mucignat - 2011-2018 Andrew 'Necromant' Andrianov - 2011-2018 Andrey Yurovsky - 2011-2018 Andy Isaacson - 2011-2018 Áron RADICS - 2011-2018 A Sheaff - 2011-2018 Björn Hauffe - 2011-2018 bob - 2011-2018 Breton M. Saunders - 2011-2018 Bruno Dal Bo - 2011-2018 Burns - 2011-2018 Chris Dew - 2011-2018 Chris Hiszpanski - 2011-2018 Chris Li - 2011-2018 Chris Samuelson - 2011-2018 Christophe Levantis - 2011-2018 Craig Lilley - 2011-2018 dandev37 - 2011-2018 Dan Hepler - 2011-2018 Daniel Campoverde [alx741] - 2011-2018 Daniel O'Connor - 2011-2018 Dave Flogeras - 2011-2018 Dave Murphy - 2011-2018 Dave Vandervies - 2011-2018 Denis Fokin - 2011-2018 Denis Osterland - 2011-2018 Dmitry Bravikov - 2011-2018 Efe Can İçöz - 2011-2018 Ethan Zonca - 2011-2018 Fabien Chouteau - 2011-2018 Fabien Le Mentec - 2011-2018 fhars - 2011-2018 Friedrich Beckmann - 2011-2018 Geoffrey Brown - 2011-2018 George Talusan - 2011-2018 Georg von Zengen - 2011-2018 giuseppe barba - 2011-2018 Greg Alexander - 2011-2018 Greg Meiste - 2011-2018 Hakkavélin - 2011-2018 htk - 2011-2018 Ian Griffiths <6thimage@gmail.com> - 2011-2018 Jack Peel - 2011-2018 Jakub Tyszkowski - 2011-2018 Jan Sarenik - 2011-2018 Jean-Luc Béchennec - 2011-2018 Jean-Marie Lemetayer - 2011-2018 Jeff Kent - 2011-2018 Jeffrey Nelson - 2011-2018 Jens Hoffmann - 2011-2018 Jerome Lambourg - 2011-2018 Jerry Jacobs - 2011-2018 Jim Paris - 2011-2018 Jiří Netolický - 2011-2018 jnosky - 2011-2018 jnosky - 2011-2018 JohannesTaelman - 2011-2018 Jonas Danielsson - 2011-2018 Jonas Norling - 2011-2018 Josh Bialkowski - 2011-2018 Karl Palsson - 2011-2018 kevin - 2011-2018 Kyle Manna - 2011-2018 Lari Lehtomäki - 2011-2018 le mentec fabien - 2011-2018 Martin Nowak - 2011-2018 Matteo Collina - 2011-2018 Max Chen - 2011-2018 Maxime Coquelin - 2011-2018 Maxime Vincent - 2011-2018 Michael Pratt - 2011-2018 Michael Sparmann - 2011-2018 Mike Szczys - 2011-2018 mlundinse - 2011-2018 mux - 2011-2018 Ned Konz - 2011-2018 Nic McDonald - 2011-2018 Nicolas Schodet - 2011-2018 Nikolay - 2011-2018 nullsub - 2011-2018 Olivier Croquette - 2011-2018 Olivier Gay - 2011-2018 Onno Kortmann - 2011-2018 orangeudav - 2011-2018 Pavel Kirienko - 2011-2018 Pekka Nikander - 2011-2018 Pete - 2011-2018 Peter Zotov - 2011-2018 Petteri Aimonen - 2011-2018 Piotr Haber - 2011-2018 Rene Hopf - 2011-2018 Robin Kreis - 2011-2018 Rob Spanton - 2011-2018 Rytis Karpuska - 2011-2018 Sean Simmons - 2011-2018 Sergey Alirzaev - 2011-2018 Simon Wright - 2011-2018 Stany MARCEL - 2011-2018 Stefan Misik - 2011-2018 Sven Wegener - 2011-2018 Tectu - 2011-2018 tekaikko - 2011-2018 texane - 2011-2018 Theodore A. Roth - 2011-2018 Thomas Gärtner - 2011-2018 Tobias Badertscher - 2011-2018 Tom de Boer - 2011-2018 Tristan Gingold - 2011-2018 Uli Köhler - 2011-2018 Uwe Bonnes - 2011-2018 Vadim Kaushan - 2011-2018 Vegard Storheil Eriksen - 2011-2018 Viacheslav Dobromyslov - 2011-2018 Victor Mayoral Vilches - 2011-2018 Wojciech A. Koszek - 2011-2018 Woodrow Douglass - 2011-2018 The "Capt'ns Missing Link" Authors. +Copyright: 2011-2020 stlink-org + Martin Capitanio [capnm] + Fabien Le Mentec [texane] + Jerry Jacobs [xor-gate] + [Nightwalker-87] + and many others... + An extended list of contributors can be found in "contributors.txt". License: BSD-3-clause - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - . - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - . - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/debian/libstlink-dev.install b/debian/libstlink-dev.install index 0c3543cd9..4e0e0d184 100644 --- a/debian/libstlink-dev.install +++ b/debian/libstlink-dev.install @@ -2,4 +2,3 @@ usr/include/* usr/lib/*/lib*.a usr/lib/*/pkgconfig/* usr/lib/*/lib*.so - diff --git a/debian/stlink-gui.install b/debian/stlink-gui.install index 5620a25e5..96c55213f 100644 --- a/debian/stlink-gui.install +++ b/debian/stlink-gui.install @@ -1,4 +1,4 @@ /usr/bin/stlink-gui -/usr/bin/stlink-gui.ui /usr/share/stlink/ -/usr/share/stlink/applications/stlink-gui.desktop /usr/share/applications/ -/usr/share/stlink/icons/hicolor/scalable/apps/stlink-gui.svg /usr/share/icons/hicolor/scalable/apps/stlink-gui.svg +/usr/share/stlink/stlink-gui.ui +/usr/share/applications/stlink-gui.desktop +/usr/share/icons/hicolor/scalable/apps/stlink-gui.svg diff --git a/debian/stlink.pc.in b/debian/stlink.pc.in index 7fde2d968..9f740ba09 100644 --- a/debian/stlink.pc.in +++ b/debian/stlink.pc.in @@ -3,7 +3,7 @@ includedir=${prefix}/include/stlink libdir=${prefix}/lib/@DEB_HOST_MULTIARCH@ Name: stlink -Description: Open source version of the STMicroelectronics Stlink Tools +Description: Open source STM32 MCU programming toolset Version: @VERSION@ Requires: libusb-1.0 Libs: -L${libdir} -lstlink From 2694214df73557ef30ed234845a0d0f4de9df56b Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 29 Jun 2020 08:48:43 +0200 Subject: [PATCH 0994/1435] Corrected install paths & changelog files - man-pages - desktop-file and icons - Fix for external CMAKE_MODULE_PATH - udev-rules - headers & stlink-gui.ui --- CHANGELOG.md | 3 ++- CMakeLists.txt | 15 +++++++++++---- cmake/packaging/deb/changelog | 4 ++-- cmake/packaging/rpm/changelog | 4 ++-- doc/man/CMakeLists.txt | 2 +- doc/version_support.md | 2 +- src/stlink-gui/CMakeLists.txt | 8 ++++---- 7 files changed, 23 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3195bae3c..7717ca6f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ Features: * Support for STM32L1, SM32L4 option bytes write ([#596](https://github.com/stlink-org/stlink/pull/596), [#844](https://github.com/stlink-org/stlink/pull/844), [#847](https://github.com/stlink-org/stlink/pull/847)) * Added CMAKEFLAGS and install target ([#804](https://github.com/stlink-org/stlink/pull/804), [#935](https://github.com/stlink-org/stlink/pull/935)) * Support for STM32G4 ([#822](https://github.com/stlink-org/stlink/pull/822)) -* Add aliased SRAM2 region in the L496 memory map ([#824](https://github.com/stlink-org/stlink/pull/824)) +* Added aliased SRAM2 region in the L496 memory map ([#824](https://github.com/stlink-org/stlink/pull/824)) * Improved support for STM32G0 ([#825](https://github.com/stlink-org/stlink/pull/825), [#850](https://github.com/stlink-org/stlink/pull/850), [#856](https://github.com/stlink-org/stlink/pull/856), [#857](https://github.com/stlink-org/stlink/pull/857)) * Added postinst script with 'depmod -a' for 'make package' ([#845](https://github.com/stlink-org/stlink/pull/845), [#931](https://github.com/stlink-org/stlink/pull/931)) * Calculate checksums for flash operations ([#862](https://github.com/stlink-org/stlink/pull/862), [#924](https://github.com/stlink-org/stlink/pull/924)) @@ -358,6 +358,7 @@ Chip support added for: * STM32F469/STM32F479 ([#345](https://github.com/stlink-org/stlink/pull/345), [#555](https://github.com/stlink-org/stlink/pull/555)) (Release v1.2.0) * STM32L1xx Cat.2 devices (Nicolas Schodet) * STM32L1xx (chip-ID 0x427) ([#152](https://github.com/stlink-org/stlink/pull/152), [#163](https://github.com/stlink-org/stlink/pull/163), [#165](https://github.com/stlink-org/stlink/pull/165)) (Release v1.0.0) +* Added SIGINT handler for stlink cleanup ([#31](https://github.com/stlink-org/stlink/pull/31), [#135](https://github.com/stlink-org/stlink/pull/135)) (Release v1.0.0) Board support added for: diff --git a/CMakeLists.txt b/CMakeLists.txt index 86282775e..096291b88 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.4.2) cmake_policy(SET CMP0042 NEW) -set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_SOURCE_DIR}/cmake/modules") +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) @@ -94,6 +94,13 @@ include_directories(${PROJECT_SOURCE_DIR}/include/stlink/tools) include_directories(src) include_directories(src/tools) ### TODO: Clean this up... +## Set installation directory for header files +set(STLINK_INCLUDE_PATH ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} CACHE PATH "Main include install directory") + +## Subordinate CMakeLists for version config & header installation +#add_subdirectory(inc) + +## Define source- and headerfiles for stlink library set(STLINK_HEADERS include/stlink.h include/stlink/backend.h @@ -143,7 +150,7 @@ endif () set(STLINK_LIBRARY_PATH ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Main library install directory") # Set the environment variable LD_LIBRARY_PATH to point to /usr/local/lib (per default). -execute_process (COMMAND bash -c "export LD_LIBRARY_PATH="${CMAKE_INSTALL_LIBDIR}" ") +execute_process(COMMAND bash -c "export LD_LIBRARY_PATH=${CMAKE_INSTALL_LIBDIR}") ### @@ -259,8 +266,8 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux") set(STLINK_MODPROBED_DIR "/etc/modprobe.d" CACHE PATH "modprobe.d directory") install(FILES ${CMAKE_SOURCE_DIR}/config/modprobe.d/stlink_v1.conf DESTINATION ${STLINK_MODPROBED_DIR}) - ## Install udev rules files to /etc/udev/rules.d/ (explicitly hardcoded) - set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "udev rules directory") + ## Install udev rules files to /lib/udev/rules.d/ (explicitly hardcoded) + set(STLINK_UDEV_RULES_DIR "/lib/udev/rules.d" CACHE PATH "udev rules directory") file(GLOB RULES_FILES ${CMAKE_SOURCE_DIR}/config/udev/rules.d/*.rules) install(FILES ${RULES_FILES} DESTINATION ${STLINK_UDEV_RULES_DIR}) endif () diff --git a/cmake/packaging/deb/changelog b/cmake/packaging/deb/changelog index 196da940e..997ed4056 100644 --- a/cmake/packaging/deb/changelog +++ b/cmake/packaging/deb/changelog @@ -1,5 +1,5 @@ -stlink (1.6.1) unstable; urgency=medium +stlink (1.6.1+ds-1) unstable; urgency=medium - * Initial Debian-packaged Release. + * Initial cpack-based package release for Debian/Ubuntu -- Nightwalker-87 Mon, 01 Jun 2020 00:00:00 +0100 diff --git a/cmake/packaging/rpm/changelog b/cmake/packaging/rpm/changelog index de2400d65..564bd95ae 100644 --- a/cmake/packaging/rpm/changelog +++ b/cmake/packaging/rpm/changelog @@ -1,2 +1,2 @@ -* Mon Jun 01 2020 Vasiliy Glazov - 1.6.1 -- Initial RPM-packaged release +* Mon Jun 01 2020 Nightwalker-87 - 1.6.1 +- Initial cpack-based RPM package release diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 23da9e150..9b3c50764 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -30,7 +30,7 @@ foreach (manpage ${MANPAGES}) endif () if (f AND NOT WIN32) - install(FILES ${f} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/man/man1) + install(FILES ${f} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/man/man1) unset(f) endif () endforeach () diff --git a/doc/version_support.md b/doc/version_support.md index 4d1f724f7..4076fb422 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -68,7 +68,7 @@ NOTE: In order to use a STLINK/v1 programmer on macOS, versions 10.13, 10.14 or ## Unsupported Operating Systems (as of Release v1.6.1) -| Operating System | libusb
      version | cmake
      version | End of OS-Support | Notes | +| Operating System | libusb
      version | cmake
      version | End of
      OS-Support | Notes | | --- | --- | --- | --- | --- | | CentOS 7 | 1.0.21 | **2.8.12.2** | | named `libusbx`, but
      `libusb`-codebase is used | | Debian 8 (Jessie) | 1.0.**19** | 3.**0.2** | Jun 2020 | diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index 8c36e5a1f..db29a72dd 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -13,11 +13,11 @@ if (NOT WIN32) # Install desktop application entry install(FILES stlink-gui.desktop - DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/applications) + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications) # Install icons install(FILES icons/stlink-gui.svg - DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/icons/hicolor/scalable/apps) + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps) set(GUI_SOURCES gui.c gui.h) @@ -30,9 +30,9 @@ if (NOT WIN32) ## stlink-gui add_executable(stlink-gui ${GUI_SOURCES}) - install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}) set_target_properties(stlink-gui PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/bin") + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}") target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) install(TARGETS stlink-gui DESTINATION ${CMAKE_INSTALL_BINDIR}) From 77652688f21253f94e23a7d1c02d5a5bf0008295 Mon Sep 17 00:00:00 2001 From: rutgerhendriks <3134550+rutgerhendriks@users.noreply.github.com> Date: Mon, 6 Jul 2020 09:37:32 +0200 Subject: [PATCH 0995/1435] Delete ccpp.yml Remove ccpp.yml from workflows --- .github/workflows/ccpp.yml | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 .github/workflows/ccpp.yml diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml deleted file mode 100644 index 23aa0bfc5..000000000 --- a/.github/workflows/ccpp.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: C/C++ CI - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: make - run: make From e273ec53e8cf2d3df68ada1095f39232f3d7b14f Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Mon, 6 Jul 2020 09:55:19 +0200 Subject: [PATCH 0996/1435] Revert changing all compiler warning preventions --- src/st-flash/flash.c | 48 +++++++++++++++++++-------------------- src/st-flash/flash_opts.c | 22 +++++++++--------- src/stlink-lib/usb.c | 1 - 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 128b8acc0..4bdc20a16 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -25,8 +25,7 @@ static void cleanup(int signum) { exit(1); } -static void usage(void) -{ +static void usage(void) { puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); puts("command line: ./st-flash [--debug] [--freq=] [--serial ] erase"); puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); @@ -60,13 +59,13 @@ int main(int ac, char** av) { return(-1); } - ILOG("st-flash %s\n", STLINK_VERSION); + printf("st-flash %s\n", STLINK_VERSION); sl = stlink_open_usb(o.log_level, 1, (char *)o.serial, o.freq); if (sl == NULL) { return(-1); } - if (STLINK_FLASH_TYPE_UNKNOWN == sl->flash_type) { + if (sl->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { printf("Failed to connect to target\n"); return(-1); } @@ -84,14 +83,14 @@ int main(int ac, char** av) { signal(SIGTERM, &cleanup); signal(SIGSEGV, &cleanup); - if (STLINK_DEV_DFU_MODE == stlink_current_mode(sl)) { + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { if (stlink_exit_dfu_mode(sl)) { printf("Failed to exit DFU mode\n"); goto on_error; } } - if (STLINK_DEV_DEBUG_MODE != stlink_current_mode(sl)) { + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { if (stlink_enter_swd_mode(sl)) { printf("Failed to enter SWD mode\n"); goto on_error; @@ -113,7 +112,7 @@ int main(int ac, char** av) { } // disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 - if (STLINK_CHIPID_STM32_F4 == sl->chip_id) { + if (sl->chip_id == STLINK_CHIPID_STM32_F4) { memset(sl->q_buf, 0, 4); for (int i = 0; i < 8; i++) { @@ -136,10 +135,9 @@ int main(int ac, char** av) { goto on_error; } - if (FLASH_CMD_WRITE == o.cmd) // write - { + if (o.cmd == FLASH_CMD_WRITE) { // write size_t size = 0; - if (FLASH_FORMAT_IHEX == o.format) { + if (o.format == FLASH_FORMAT_IHEX) { err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr); if (err == -1) { @@ -149,7 +147,7 @@ int main(int ac, char** av) { } if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { - if (FLASH_FORMAT_IHEX == o.format) { + if (o.format == FLASH_FORMAT_IHEX) { err = stlink_mwrite_flash(sl, mem, (uint32_t)size, o.addr); } else { err = stlink_fwrite_flash(sl, o.filename, o.addr); @@ -161,7 +159,7 @@ int main(int ac, char** av) { } } else if ((o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { - if (FLASH_FORMAT_IHEX == o.format) { + if (o.format == FLASH_FORMAT_IHEX) { err = stlink_mwrite_sram(sl, mem, (uint32_t)size, o.addr); } else { err = stlink_fwrite_sram(sl, o.filename, o.addr); @@ -179,7 +177,7 @@ int main(int ac, char** av) { printf("stlink_fwrite_option_bytes() == -1\n"); goto on_error; } - } else if (FLASH_OPTION_BYTES == o.area) { + } else if (o.area == FLASH_OPTION_BYTES) { if (o.val == 0) { printf("attempting to set option byte to 0, abort.\n"); goto on_error; @@ -191,15 +189,15 @@ int main(int ac, char** av) { printf("stlink_write_option_bytes32() == -1\n"); goto on_error; } - } else if (FLASH_OPTCR == o.area) { + } else if (o.area == FLASH_OPTCR) { DLOG("@@@@ Write %d (%0#10x) to option control register\n", o.val, o.val); err = stlink_write_option_control_register32(sl, o.val); - } else if (FLASH_OPTCR1 == o.area) { + } else if (o.area == FLASH_OPTCR1) { DLOG("@@@@ Write %d (%0#10x) to option control register 1\n", o.val, o.val); err = stlink_write_option_control_register1_32(sl, o.val); - } else if (FLASH_OPTION_BYTES_BOOT_ADD == o.area) { + } else if (o.area == FLASH_OPTION_BYTES_BOOT_ADD) { DLOG("@@@@ Write %d (%0#10x) to option bytes boot address\n", o.val, o.val); err = stlink_write_option_bytes_boot_add32(sl, o.val); @@ -208,14 +206,14 @@ int main(int ac, char** av) { printf("Unknown memory region\n"); goto on_error; } - } else if (FLASH_CMD_ERASE == o.cmd) { + } else if (o.cmd == FLASH_CMD_ERASE) { err = stlink_erase_flash_mass(sl); if (err == -1) { printf("stlink_erase_flash_mass() == -1\n"); goto on_error; } - } else if (CMD_RESET == o.cmd) { + } else if (o.cmd == CMD_RESET) { if (sl->version.stlink_v > 1) { if (stlink_jtag_reset(sl, 2)) { printf("Failed to reset JTAG\n"); @@ -228,20 +226,20 @@ int main(int ac, char** av) { goto on_error; } } else { // read - if ((FLASH_MAIN_MEMORY == o.area) || (FLASH_SYSTEM_MEMORY == o.area)) { + if ((o.area == FLASH_MAIN_MEMORY) || (o.area == FLASH_SYSTEM_MEMORY)) { if ((o.size == 0) && (o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { o.size = sl->flash_size; } else if ((o.size == 0) && (o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { o.size = sl->sram_size; } - err = stlink_fread(sl, o.filename, FLASH_FORMAT_IHEX == o.format, o.addr, o.size); + err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); if (err == -1) { printf("stlink_fread() == -1\n"); goto on_error; } - } else if (FLASH_OPTION_BYTES == o.area) { + } else if (o.area == FLASH_OPTION_BYTES) { uint8_t remaining_option_length = sl->option_size / 4; DLOG("@@@@ Read %d (%#x) option bytes from %#10x\n", remaining_option_length, remaining_option_length, sl->option_base); @@ -249,7 +247,7 @@ int main(int ac, char** av) { if (0 == o.size) { o.size = sl->option_size; } - err = stlink_fread(sl, o.filename, FLASH_FORMAT_IHEX == o.format, sl->option_base, o.size); + err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, sl->option_base, o.size); } else { uint32_t option_byte = 0; err = stlink_read_option_bytes32(sl, &option_byte); @@ -260,7 +258,7 @@ int main(int ac, char** av) { printf("%08x\n", option_byte); } } - } else if (FLASH_OPTION_BYTES_BOOT_ADD == o.area) { + } else if (o.area == FLASH_OPTION_BYTES_BOOT_ADD) { uint32_t option_byte = 0; err = stlink_read_option_bytes_boot_add32(sl, &option_byte); if (err == -1) { @@ -269,7 +267,7 @@ int main(int ac, char** av) { } else { printf("%08x\n",option_byte); } - } else if (FLASH_OPTCR == o.area) { + } else if (o.area == FLASH_OPTCR) { uint32_t option_byte = 0; err = stlink_read_option_control_register32(sl, &option_byte); if (err == -1) { @@ -278,7 +276,7 @@ int main(int ac, char** av) { } else { printf("%08x\n",option_byte); } - } else if (FLASH_OPTCR1 == o.area) { + } else if (o.area == FLASH_OPTCR1) { uint32_t option_byte = 0; err = stlink_read_option_control_register1_32(sl, &option_byte); if (err == -1) { diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 6653c6e62..1cfd6fe89 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -274,7 +274,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { break; case FLASH_CMD_READ: // expect filename, addr and size - if ((FLASH_MAIN_MEMORY == o->area) || (FLASH_SYSTEM_MEMORY == o->area)) { + if ((o->area == FLASH_MAIN_MEMORY) || (o->area == FLASH_SYSTEM_MEMORY)) { if (ac != 3) { return invalid_args("read "); } o->filename = av[0]; @@ -295,12 +295,12 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } break; - } else if ((FLASH_OTP == o->area)) { + } else if ((o->area == FLASH_OTP)) { return bad_arg("TODO: otp not implemented yet"); if (ac > 1) { return invalid_args("otp read: [path]"); } if (ac > 0) { o->filename = av[0]; } break; - } else if ((FLASH_OPTION_BYTES == o->area)) { + } else if ((o->area == FLASH_OPTION_BYTES)) { if (ac > 2) { return invalid_args("option bytes read: [path] [size]"); } if (ac > 0) { o->filename = av[0]; } if (ac > 1) { @@ -313,13 +313,13 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } } break; - } else if ((FLASH_OPTION_BYTES_BOOT_ADD == o->area)) { + } else if ((o->area == FLASH_OPTION_BYTES_BOOT_ADD)) { if (ac > 0) { return invalid_args("option bytes boot_add read"); } break; - } else if ((FLASH_OPTCR == o->area)) { + } else if ((o->area == FLASH_OPTCR)) { if (ac > 0) { return invalid_args("option control register read"); } break; - } else if ((FLASH_OPTCR1 == o->area)) { + } else if ((o->area == FLASH_OPTCR1)) { if (ac > 0) { return invalid_args("option control register 1 read"); } break; } @@ -328,7 +328,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { case FLASH_CMD_WRITE: // TODO: should be boot add 0 and boot add 1 uint32 - if (FLASH_OPTION_BYTES == o->area) { // expect filename and optional address + if (o->area == FLASH_OPTION_BYTES) { // expect filename and optional address if (ac >=1 && ac <= 2) { o->filename = av[0]; } else { @@ -344,7 +344,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { o->addr = (stm32_addr_t) addr; } } - } else if (FLASH_OPTION_BYTES_BOOT_ADD == o->area) { // expect option bytes boot address + } else if (o->area == FLASH_OPTION_BYTES_BOOT_ADD) { // expect option bytes boot address if (ac != 1) { return invalid_args("option bytes boot_add write "); } uint32_t val; @@ -355,7 +355,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } else { o->val = (uint32_t)val; } - } else if (FLASH_OPTCR == o->area) { // expect option control register value + } else if (o->area == FLASH_OPTCR) { // expect option control register value if (ac != 1) { return invalid_args("option control register write "); } uint32_t val; @@ -366,7 +366,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } else { o->val = (uint32_t) val; } - } else if (FLASH_OPTCR1 == o->area) { // expect option control register 1 value + } else if (o->area == FLASH_OPTCR1) { // expect option control register 1 value if (ac != 1) { return invalid_args("option control register 1 write "); } uint32_t val; @@ -376,7 +376,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } else { o->val = (uint32_t) val; } - } else if (FLASH_FORMAT_BINARY == o->format) { // expect filename and addr + } else if (o->format == FLASH_FORMAT_BINARY) { // expect filename and addr if (ac != 2) { return invalid_args("write "); } o->filename = av[0]; diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index a7875eb57..f9b4775f3 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -710,7 +710,6 @@ int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_READMEM_32BIT; - DLOG("using address %#010x\n", addr); write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); size = send_recv(slu, 1, cmd, slu->cmd_len, data, len); From ca02a8d507430e2a45e5c6fa9b019ab042c91770 Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Mon, 6 Jul 2020 10:07:26 +0200 Subject: [PATCH 0997/1435] src/st-flash/flash.c: improved error message --- src/st-flash/flash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 4bdc20a16..9116f9c80 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -236,7 +236,7 @@ int main(int ac, char** av) { err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); if (err == -1) { - printf("stlink_fread() == -1\n"); + printf("could not read main memory (%d)\n", err); goto on_error; } } else if (o.area == FLASH_OPTION_BYTES) { From ebb3164d903f9780beaf6d5f7c95b27f2b64ddc1 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 18 Jul 2020 00:46:26 +0200 Subject: [PATCH 0998/1435] Updated CHANGELOG & README --- CHANGELOG.md | 27 ++++++++++++++++++++++++++- README.md | 8 +++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7717ca6f4..5ad1ec2d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,31 @@ stlink ChangeLog ================ +v1.6.2 +====== + +Release date: (TBD) + +Features: + +Updates & changes: + +* [doc] st-flash --reset parameter (one solution for #356) ([#642](https://github.com/stlink-org/stlink/pull/642)) +* [refactoring] General maintenance ([#864](https://github.com/stlink-org/stlink/pull/864), [#976](https://github.com/stlink-org/stlink/pull/976), [#978](https://github.com/stlink-org/stlink/pull/978)) +* Imported debian pkg-settings ([#986](https://github.com/stlink-org/stlink/pull/986)) +* Add support for FreeBSD's libusb reimplementation ([#992](https://github.com/stlink-org/stlink/pull/992), [#993](https://github.com/stlink-org/stlink/pull/993)) + +Fixes: + +* [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) +* cmake compile failure with external CMAKE_MODULE_PATH set ([#962](https://github.com/stlink-org/stlink/pull/962)) +* doc/man: Fixed installation directory ([#970](https://github.com/stlink-org/stlink/pull/970)) +* Fixed installation path for desktop-file and icons ([#972](https://github.com/stlink-org/stlink/pull/972)) +* Fix for static linking of libssp ([#973](https://github.com/stlink-org/stlink/pull/973), [#974](https://github.com/stlink-org/stlink/pull/974)) +* Fixed connect under reset for st-flash and st-util ([#983](https://github.com/stlink-org/stlink/pull/983)) +* Fix for mmap() size_t overflow in st-flash ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) + + v1.6.1 ====== @@ -139,7 +164,7 @@ Updates and fixes: * Fixed relative path to the UI files needed by stlink-gui-local (GUI) ([#770](https://github.com/stlink-org/stlink/pull/770), [#771](https://github.com/stlink-org/stlink/pull/771)) * Added howto for sending NRST signal through GDB ([#774](https://github.com/stlink-org/stlink/pull/774), [#776](https://github.com/stlink-org/stlink/pull/776), [#779](https://github.com/stlink-org/stlink/pull/779)) * Fixed package name "devscripts" in doc/compiling.md ([#775](https://github.com/stlink-org/stlink/pull/775)) -* Fixed few potential memory/resource leaks ([#803](https://github.com/stlink-org/stlink/pull/803)) +* Fixed few potential memory/resource leaks ([#803](https://github.com/stlink-org/stlink/pull/803), [#831](https://github.com/stlink-org/stlink/pull/831)) * Updated Linux source repositories in README.md: Debian and Ubuntu ([#821](https://github.com/stlink-org/stlink/pull/821), [#835](https://github.com/stlink-org/stlink/pull/835), [#859](https://github.com/stlink-org/stlink/pull/859)) * Do not issue JTAG reset on stlink-v1 ([#828](https://github.com/stlink-org/stlink/pull/828)) * Fixed flash size of STM32 Discovery vl ([#829](https://github.com/stlink-org/stlink/pull/829)) diff --git a/README.md b/README.md index 21ab9f48b..5be842156 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ The stlink library and tools are licensed under the **[BSD-3 License](LICENSE.md STLink is an open source toolset to program and debug STM32 devices and boards manufactured by STMicroelectronics. It supports several so called STLINK programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG/SWD. There are four generations available on the market which are _all_ supported by this toolset: -* **STLINK/v1** _(obsolete as of 21-11-2019)_ +* **STLINK/v1** _(obsolete as of 21-11-2019, continued support by this toolset)_ - transport layer: SCSI passthru commands over USB - stand-alone programmer and present on STM32VL Discovery boards * **STLINK/v2** @@ -83,8 +83,10 @@ Alternatively one can compile and install from source as described in our [compi We recommend to install `stlink-tools` from the package repository of the used distribution: -* Debian Linux: [(Link)](https://packages.debian.org/buster/stlink-tools) -* Ubuntu Linux: [(Link)](https://packages.ubuntu.com/stlink-tools) +**Note:** As packages distributed via the [Debian](https://packages.debian.org/buster/stlink-tools) and [Ubuntu](https://packages.ubuntu.com/stlink-tools) repositories differ from our self-maintained deb-package, we recommend to use the latter instead (see link below). It provides the opportunity to handle and fix user-reported package issues directly within the project and is not redundant to any limitations deriving from external maintenance guidelines. + +* Debian Linux: [(Link)](https://github.com/stlink-org/stlink/releases) +* Ubuntu Linux: [(Link)](https://github.com/stlink-org/stlink/releases) * Arch Linux: [(Link)](https://www.archlinux.org/packages/community/x86_64/stlink) * Alpine Linux: [(Link)](https://pkgs.alpinelinux.org/packages?name=stlink) * Fedora: [(Link)](https://src.fedoraproject.org/rpms/stlink) From 56a699d37569caf591497427d42b5ad466c7a480 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 18 Jul 2020 00:56:49 +0200 Subject: [PATCH 0999/1435] Added missing cmake install prefix (Closes #1006) --- src/stlink-gui/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index 258f83cc1..46224dddb 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -35,7 +35,7 @@ if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) add_executable(stlink-gui ${GUI_SOURCES}) install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}) set_target_properties(stlink-gui PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}") + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}") target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) install(TARGETS stlink-gui DESTINATION ${CMAKE_INSTALL_BINDIR}) endif () From f57ae0c7142dd86b2dd5b0c298f7105ab65d574e Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Sun, 19 Jul 2020 16:55:02 +0200 Subject: [PATCH 1000/1435] Remove double parantheses --- src/st-flash/flash_opts.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 1cfd6fe89..ab716bb31 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -295,12 +295,12 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } break; - } else if ((o->area == FLASH_OTP)) { + } else if (o->area == FLASH_OTP) { return bad_arg("TODO: otp not implemented yet"); if (ac > 1) { return invalid_args("otp read: [path]"); } if (ac > 0) { o->filename = av[0]; } break; - } else if ((o->area == FLASH_OPTION_BYTES)) { + } else if (o->area == FLASH_OPTION_BYTES) { if (ac > 2) { return invalid_args("option bytes read: [path] [size]"); } if (ac > 0) { o->filename = av[0]; } if (ac > 1) { @@ -313,13 +313,13 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } } break; - } else if ((o->area == FLASH_OPTION_BYTES_BOOT_ADD)) { + } else if (o->area == FLASH_OPTION_BYTES_BOOT_ADD) { if (ac > 0) { return invalid_args("option bytes boot_add read"); } break; - } else if ((o->area == FLASH_OPTCR)) { + } else if (o->area == FLASH_OPTCR) { if (ac > 0) { return invalid_args("option control register read"); } break; - } else if ((o->area == FLASH_OPTCR1)) { + } else if (o->area == FLASH_OPTCR1) { if (ac > 0) { return invalid_args("option control register 1 read"); } break; } From 2dd47a432710c77f9dfd9a661212643a9667361f Mon Sep 17 00:00:00 2001 From: Rutger Hendriks Date: Sun, 19 Jul 2020 17:35:38 +0200 Subject: [PATCH 1001/1435] Reverted the last comparison changes --- src/st-flash/flash_opts.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index ab716bb31..e74ecc1ce 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -242,18 +242,18 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { // command and (optional) device name while (ac >= 1) { if (strcmp(av[0], "erase") == 0) { - if (FLASH_CMD_NONE != o->cmd) { return(-1); } + if (o->cmd != FLASH_CMD_NONE) { return(-1); } o->cmd = FLASH_CMD_ERASE; } else if (strcmp(av[0], "read") == 0) { - if (FLASH_CMD_NONE != o->cmd) { return(-1); } + if (o->cmd != FLASH_CMD_NONE) { return(-1); } o->cmd = FLASH_CMD_READ; } else if (strcmp(av[0], "write") == 0) { - if (FLASH_CMD_NONE != o->cmd) { return(-1); } + if (o->cmd != FLASH_CMD_NONE) { return(-1); } o->cmd = FLASH_CMD_WRITE; } else if (strcmp(av[0], "reset") == 0) { - if (FLASH_CMD_NONE != o->cmd) { return(-1); } + if (o->cmd != FLASH_CMD_NONE) { return(-1); } o->cmd = CMD_RESET; } else { From 1bcfdf5d42a29dedb44821ce30bbe6b915ebbb9a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 8 Aug 2020 13:22:56 +0200 Subject: [PATCH 1002/1435] Updated CHANGELOG.md & contributors.txt --- CHANGELOG.md | 2 ++ cmake/packaging/deb/control | 2 +- contributors.txt | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ad1ec2d4..01e679b3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ Release date: (TBD) Features: +* Option bytes on the STM32F767 ZIT6 Nucleo-144 ([#968](https://github.com/stlink-org/stlink/pull/968), [#997](https://github.com/stlink-org/stlink/pull/997)) + Updates & changes: * [doc] st-flash --reset parameter (one solution for #356) ([#642](https://github.com/stlink-org/stlink/pull/642)) diff --git a/cmake/packaging/deb/control b/cmake/packaging/deb/control index 759668ba6..ef51a6cea 100644 --- a/cmake/packaging/deb/control +++ b/cmake/packaging/deb/control @@ -1,6 +1,6 @@ Source: stlink Priority: optional -Maintainer: stlink-org +Maintainer: Nightwalker-87 Build-Depends: cmake, dh-cmake, debhelper (>= 9), libusb-1.0-0-dev, libgtk-3-dev Standards-Version: 4.5.0 Rules-Requires-Root: no diff --git a/contributors.txt b/contributors.txt index fec7510c3..cc9403456 100644 --- a/contributors.txt +++ b/contributors.txt @@ -103,6 +103,7 @@ Robin Kreis Roger Wolff [rewolff] Rob Spanton Rytis Karpuska +Rutger Hendriks [rutgerhendriks] Sean Simmons Sergey Alirzaev Simon Derr [sderr] From baab8ca2f9f7b5fcfd9a15c0bc61069a846e1f4f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 15 Aug 2020 21:31:52 +0200 Subject: [PATCH 1003/1435] Updated ISSUE_TEMPLATES (Closes #1014) --- ...ort--only-valid-if-template-is-reused--.md | 38 ------------------- .github/ISSUE_TEMPLATE/bug-report.md | 15 ++++---- .github/ISSUE_TEMPLATE/feature-request.md | 16 ++++---- 3 files changed, 14 insertions(+), 55 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md diff --git a/.github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md b/.github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md deleted file mode 100644 index 255596955..000000000 --- a/.github/ISSUE_TEMPLATE/bug-report--only-valid-if-template-is-reused--.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: Bug Report (only valid if template is reused!) -about: 'Please read #906 before submitting a ticket.' -title: "[STM32 device name]: [Title]" -labels: '' -assignees: '' - ---- - -Thank you for giving feedback to the stlink project. - -In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out each of the following items appropriate to your specific problem: - -- Programmer/board type: [enter here] (e.g Stlink /v1, /v2, /v2-clone, /v2-1) -- Programmer firmware version: [enter here] (e.g STSW-LINK007 2.27.15) -- Operating system and version: [enter here] (e.g Linux, Mac OS X, Windows) -- **Stlink tools version** and/or git commit hash: [enter here] (e.g v1.1.0/git-c722056) -- Stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-util`) -- Target chip (and board if applicable): [enter here] (e.g STM32F402VG) - -Futher we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: - -Commandline-Output: - -``` -OUTPUT/ERROR of the commandline tool(s) -``` - -Expected/description: - -`short description of the expected value` - - -**NOTICE: This bug report may be closed without further notice, if not enough information is provided!** - -Thank you for your support. - -The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 344a53ea6..fc30f3993 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -1,18 +1,19 @@ --- -name: Bug Report -about: 'Please read #906 before submitting a ticket.' -title: "[STM32 device name]: [Title]" +name: "Bug Report" +about: "Report a bug" +title: "[STM32 device name]: [_$YourTitle_]" labels: '' -assignees: '' - --- Thank you for giving feedback to the stlink project. +**NOTICE: Please read and follow instructions in #906 before submitting a ticket. This feature request will be deleted without notice when not enough information is provided! So please ensure that all fields are filled out.** + +- [ ] I made serious effort to avoid creating duplicate or nearly similar issue + In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out each of the following items appropriate to your specific problem: - Programmer/board type: [enter here] (e.g Stlink /v1, /v2, /v2-clone, /v2-1) -- Programmer firmware version: [enter here] (e.g STSW-LINK007 2.27.15) - Operating system and version: [enter here] (e.g Linux, Mac OS X, Windows) - **Stlink tools version** and/or git commit hash: [enter here] (e.g v1.1.0/git-c722056) - Stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-util`) @@ -31,8 +32,6 @@ Expected/description: `short description of the expected value` -**NOTICE: This bug report may be closed without further notice, if not enough information is provided!** - Thank you for your support. The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index 2aa7a5c7f..133b895b2 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -1,18 +1,19 @@ --- -name: Feature Request -about: Suggest an idea for this project -title: "[feature] " +name: "Feature Request" +about: "Suggest an idea for this project" +title: "[feature] [_$YourTitle_]" labels: code/feature-request -assignees: '' - --- Thank you for giving feedback to the stlink project. +**NOTICE: Please read and follow instructions in #906 before submitting a ticket. This feature request will be deleted without notice when not enough information is provided! So please ensure that all fields are filled out.** + +- [ ] I made serious effort to avoid creating duplicate or nearly similar issue + In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out the check boxes below by setting a 'x' into the checkboxes ( [x] ) and edit each item appropriate to your specific problem. - [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard -- [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 - [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) - [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 - [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` @@ -31,9 +32,6 @@ Expected/description: `short description of the expected value` -**NOTICE: This feature request may be closed without notice when not enough information is provided!** - - Thank you for your support. The stlink project maintainers From 6f3657477739582a437693797136267c45009415 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 15 Aug 2020 21:38:36 +0200 Subject: [PATCH 1004/1435] Updated ISSUE_TEMPLATES (Closes #1014) --- .github/ISSUE_TEMPLATE/bug-report.md | 15 +++++++-------- .github/ISSUE_TEMPLATE/feature-request.md | 16 +++++++--------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 344a53ea6..fc30f3993 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -1,18 +1,19 @@ --- -name: Bug Report -about: 'Please read #906 before submitting a ticket.' -title: "[STM32 device name]: [Title]" +name: "Bug Report" +about: "Report a bug" +title: "[STM32 device name]: [_$YourTitle_]" labels: '' -assignees: '' - --- Thank you for giving feedback to the stlink project. +**NOTICE: Please read and follow instructions in #906 before submitting a ticket. This feature request will be deleted without notice when not enough information is provided! So please ensure that all fields are filled out.** + +- [ ] I made serious effort to avoid creating duplicate or nearly similar issue + In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out each of the following items appropriate to your specific problem: - Programmer/board type: [enter here] (e.g Stlink /v1, /v2, /v2-clone, /v2-1) -- Programmer firmware version: [enter here] (e.g STSW-LINK007 2.27.15) - Operating system and version: [enter here] (e.g Linux, Mac OS X, Windows) - **Stlink tools version** and/or git commit hash: [enter here] (e.g v1.1.0/git-c722056) - Stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-util`) @@ -31,8 +32,6 @@ Expected/description: `short description of the expected value` -**NOTICE: This bug report may be closed without further notice, if not enough information is provided!** - Thank you for your support. The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index 2aa7a5c7f..133b895b2 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -1,18 +1,19 @@ --- -name: Feature Request -about: Suggest an idea for this project -title: "[feature] " +name: "Feature Request" +about: "Suggest an idea for this project" +title: "[feature] [_$YourTitle_]" labels: code/feature-request -assignees: '' - --- Thank you for giving feedback to the stlink project. +**NOTICE: Please read and follow instructions in #906 before submitting a ticket. This feature request will be deleted without notice when not enough information is provided! So please ensure that all fields are filled out.** + +- [ ] I made serious effort to avoid creating duplicate or nearly similar issue + In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out the check boxes below by setting a 'x' into the checkboxes ( [x] ) and edit each item appropriate to your specific problem. - [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard -- [ ] Programmer firmware version: e.g STSW-LINK007 2.27.15 - [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) - [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 - [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` @@ -31,9 +32,6 @@ Expected/description: `short description of the expected value` -**NOTICE: This feature request may be closed without notice when not enough information is provided!** - - Thank you for your support. The stlink project maintainers From 61c5e395e2a850c0bc593d086d858091939ce238 Mon Sep 17 00:00:00 2001 From: Hassan DRAGA <61518789+dragahassan@users.noreply.github.com> Date: Fri, 28 Aug 2020 10:35:16 -0300 Subject: [PATCH 1005/1435] Fixing wrong path It's seem etc folder no longer exist, now it's on "stlink/config/udev/rules.d" instead of "stlink/etc/udev/rules.d". --- doc/compiling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/compiling.md b/doc/compiling.md index c278c9ca8..48a429774 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -159,7 +159,7 @@ The rules are located in the subdirectory `config/udev/rules.d` within the sourc Afterwards it may be necessary to reload the udev rules: ```sh -$ cp etc/udev/rules.d /etc/udev/rules.d +$ cp config/udev/rules.d /etc/udev/rules.d $ udevadm control --reload-rules $ udevadm trigger ``` From 00a6ae027725e9850da5f550e193fa3dc7297eb5 Mon Sep 17 00:00:00 2001 From: Hassan DRAGA <61518789+dragahassan@users.noreply.github.com> Date: Fri, 28 Aug 2020 10:43:06 -0300 Subject: [PATCH 1006/1435] Updating commands Updating commands for "rules.d" --- doc/compiling.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/compiling.md b/doc/compiling.md index 48a429774..7f2ba698e 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -159,9 +159,9 @@ The rules are located in the subdirectory `config/udev/rules.d` within the sourc Afterwards it may be necessary to reload the udev rules: ```sh -$ cp config/udev/rules.d /etc/udev/rules.d -$ udevadm control --reload-rules -$ udevadm trigger +$ sudo cp -a config/udev/rules.d/. /etc/udev/rules.d +$ sudo udevadm control --reload-rules +$ sudo udevadm trigger ``` Udev will now create device node files `/dev/stlinkv2_XX`, `/dev/stlinkv1_XX`.
      From 5ea485de396ce004604a0adc4bf1278c6a3a845f Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Fri, 28 Aug 2020 23:35:45 +0300 Subject: [PATCH 1007/1435] use SetConsoleCtrlHandler for windows --- .gitignore | 1 + src/st-util/gdb-server.c | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 229242a53..9fbe0139c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ build-mingw .project obj-* *.user* +.cmake/ diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 94cd6fda7..60c9c16d3 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -71,19 +71,30 @@ int serve(stlink_t *sl, st_state_t *st); char* make_memory_map(stlink_t *sl); static void init_cache(stlink_t *sl); -static void cleanup(int signum) { - (void)signum; - +static void _cleanup() { if (connected_stlink) { // Switch back to mass storage mode before closing stlink_run(connected_stlink); stlink_exit_debug_mode(connected_stlink); stlink_close(connected_stlink); } +} +static void cleanup(int signum) { + printf("Receive signal %i. Exiting...\n", signum); + _cleanup(); exit(1); + (void)signum; } +#if defined(_WIN32) +BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { + printf("Receive signal %i. Exiting...\r\n", (int)fdwCtrlType); + _cleanup(); + return FALSE; +} +#endif + static stlink_t* do_connect(st_state_t *st) { stlink_t *sl = NULL; @@ -234,9 +245,13 @@ int main(int argc, char** argv) { } connected_stlink = sl; +#if defined(_WIN32) + SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE); +#else signal(SIGINT, &cleanup); signal(SIGTERM, &cleanup); signal(SIGSEGV, &cleanup); +#endif if (state.reset) { stlink_reset(sl); } From 203d68544b5fe4858854c06df66e1142d12b27bd Mon Sep 17 00:00:00 2001 From: Alex Suykov Date: Wed, 9 Sep 2020 23:47:58 +0300 Subject: [PATCH 1008/1435] Fix reg_offset handling in stlink_usb_read_all_regs --- src/stlink-lib/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index f9b4775f3..9726ddc4a 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -754,7 +754,7 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { sl->q_len = (int)size; stlink_print_data(sl); - for (i = reg_offset; i < 16; i++) regp->r[i] = read_uint32(sl->q_buf, i * 4); + for (i = 0; i < 16; i++) regp->r[i] = read_uint32(sl->q_buf, reg_offset + i * 4); regp->xpsr = read_uint32(sl->q_buf, reg_offset + 64); regp->main_sp = read_uint32(sl->q_buf, reg_offset + 68); From bf41f1404562ac5b632edd31bc4ba9afcf2f33d8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 20 Sep 2020 14:26:26 +0200 Subject: [PATCH 1009/1435] General Project Update - Updated list of required packages - Fixed install path of stlink-gui.ui file - Minor fixes in compiling.md - Updated CHANGELOG.md --- CHANGELOG.md | 2 ++ doc/compiling.md | 7 +++-- doc/version_support.md | 52 +++++++++++++++++------------------ src/stlink-gui/CMakeLists.txt | 2 +- 4 files changed, 33 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01e679b3c..d9dc64a11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ Fixes: * Fix for static linking of libssp ([#973](https://github.com/stlink-org/stlink/pull/973), [#974](https://github.com/stlink-org/stlink/pull/974)) * Fixed connect under reset for st-flash and st-util ([#983](https://github.com/stlink-org/stlink/pull/983)) * Fix for mmap() size_t overflow in st-flash ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) +* [regression] stlink-gui installation issue on Ubuntu-18.04 ([#1006](https://github.com/stlink-org/stlink/pull/1006)) +* st-util: wrong register values passed to gdb (st-link v2) ([#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027)) v1.6.1 diff --git a/doc/compiling.md b/doc/compiling.md index 7f2ba698e..d8cb62ebb 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -159,7 +159,7 @@ The rules are located in the subdirectory `config/udev/rules.d` within the sourc Afterwards it may be necessary to reload the udev rules: ```sh -$ sudo cp -a config/udev/rules.d/. /etc/udev/rules.d +$ sudo cp -a config/udev/rules.d/* /etc/udev/rules.d/ $ sudo udevadm control --reload-rules $ sudo udevadm trigger ``` @@ -217,8 +217,9 @@ To do this with only one simple command, type: ### Building 1. Change into the project source directory: `cd stlink` -2. Run `make release` to create the _Release_ target -3. Run `make debug` to create the _Debug_ target (_optional_)
      +2. Run `make clean` to clean remnants of any previous builds. +3. Run `make release` to create the _Release_ target +4. Run `make debug` to create the _Debug_ target (_optional_)
      The debug target is only necessary in order to modify the sources and to run under a debugger. diff --git a/doc/version_support.md b/doc/version_support.md index 4076fb422..43c201101 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -28,39 +28,39 @@ NOTE: In order to use a STLINK/v1 programmer on macOS, versions 10.13, 10.14 or | Operating System | libusb
      version | cmake
      version | gtk-3
      version | Notes | | --- | --- | --- | --- | --- | -| Alpine Edge | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3.0-dev | | -| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | 3.24.18
      libgtk+3-devel | | +| Alpine Edge | 1.0.23 | 3.17.0 | 3.99.0
      gtk+3.0 | | +| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | 3.24.18
      libgtk+3 | | | Arch Linux | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | -| Fedora Rawhide | 1.0.23 | 3.17.0 | 3.24.18
      gtk3-devel | | named `libusbx`, but
      `libusb`-codebase is used | +| Fedora Rawhide | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | named `libusbx`, but
      `libusb`-codebase is used | | KaOS | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | -| OpenMandriva Cooker | 1.0.23 | 3.17.0 | 3.24.18
      libgtk+3.0-devel
      lib64gtk+3.0-devel | | -| PCLinuxOS | 1.0.23
      lib64usb1.0 | 3.17.0 | 3.24.18
      lib64gtk+3.0-devel | | +| OpenMandriva Cooker | 1.0.23 | 3.17.0 | 3.24.18
      libgtk+3.0
      lib64gtk+3.0 | | +| PCLinuxOS | 1.0.23
      lib64usb1.0 | 3.17.0 | 3.24.18
      lib64gtk+3.0 | | | Slackware Current | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3 | | -| Solus | 1.0.23 | 3.16.5 | 3.24.16
      libgtk-3-devel | | -| Debian Sid | 1.0.23 | 3.16.3 | 3.24.18
      libgtk-3-dev | | -| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | 3.24.13
      libgtk+3.0-devel
      lib64gtk+3.0-devel | | -| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | 3.24.17
      libgtk-3-dev | | -| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | 3.24.16
      gtk3-devel | | -| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.13
      gtk+3.0-dev | | -| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | 3.24.12
      libgtk-3-dev | | -| Mageia Cauldron | 1.0.22 | 3.17.0 | 3.24.18
      libgtk+3.0-devel
      lib64gtk+3.0-devel | | +| Solus | 1.0.23 | 3.16.5 | 3.24.16
      libgtk-3 | | +| Debian Sid | 1.0.23 | 3.16.3 | 3.24.18
      libgtk-3 | | +| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | 3.24.13
      libgtk+3.0
      lib64gtk+3.0 | | +| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | 3.24.17
      libgtk-3 | | +| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | 3.24.16
      gtk3 | | +| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.13
      gtk+3.0 | | +| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | 3.24.12
      libgtk-3 | | +| Mageia Cauldron | 1.0.22 | 3.17.0 | 3.24.18
      libgtk+3.0
      lib64gtk+3.0 | | | NetBSD 9.0 | 1.0.22 | 3.16.1 | 3.24.12
      gtk+3 | | | NetBSD 8.1 | 1.0.22 | 3.16.1 | 3.24.12
      gtk+3 | | | NetBSD 7.2 | 1.0.22 | 3.16.1 | _N/A_ | | -| Alpine 3.10 | 1.0.22 | 3.14.5 | 3.24.8
      gtk+3.0-dev | | -| Fedora 31 | 1.0.22 | 3.14.5 | 3.24.12
      gtk3-devel | named `libusbx`, but
      `libusb`-codebase is used | -| Mageia 7.1 | 1.0.22 | 3.14.3 | 3.24.8
      libgtk+3.0-devel
      lib64gtk+3.0-devel | | -| Fedora 30 | 1.0.22 | 3.14.2 | 3.24.8
      gtk3-devel | named `libusbx`, but
      `libusb`-codebase is used | -| Debian 10 (Buster) | 1.0.22 | 3.13.4 | 3.24.5
      libgtk-3-dev | | -| Alpine 3.9 | 1.0.22 | 3.13.0 | 3.24.1
      gtk+3.0-dev | | -| CentOS 8 | 1.0.22 | 3.11.4 | 3.22.30
      gtk3-devel | named `libusbx`, but
      `libusb`-codebase is used | -| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | 3.24.14
      gtk3-devel | | -| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | 3.22.30
      gtk3-devel | | -| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | 3.22.30
      libgtk-3-dev | | -| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | 3.22.11
      libgtk-3-dev | | +| Alpine 3.10 | 1.0.22 | 3.14.5 | 3.24.8
      gtk+3.0 | | +| Fedora 31 | 1.0.22 | 3.14.5 | 3.24.12
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | +| Mageia 7.1 | 1.0.22 | 3.14.3 | 3.24.8
      libgtk+3.0
      lib64gtk+3.0 | | +| Fedora 30 | 1.0.22 | 3.14.2 | 3.24.8
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | +| Debian 10 (Buster) | 1.0.22 | 3.13.4 | 3.24.5
      libgtk-3 | | +| Alpine 3.9 | 1.0.22 | 3.13.0 | 3.24.1
      gtk+3.0 | | +| CentOS 8 | 1.0.22 | 3.11.4 | 3.22.30
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | +| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | 3.24.14
      gtk3 | | +| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | 3.22.30
      gtk3 | | +| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | 3.22.30
      libgtk-3 | | +| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | 3.22.11
      libgtk-3 | | | Slackware 14.2 | **1.0.20** | 3.5.2 | 3.18.9
      gtk+3 | | -| Ubuntu 16.04 LTS (Xenial Xerus) | **1.0.20** | 3.5.1 | 3.18.9
      libgtk-3-dev | | -| OpenMandriva Lx 3.0 | **1.0.20** | **3.4.2** | 3.18.9
      libgtk+3.0-devel
      lib64gtk+3.0-devel | | +| Ubuntu 16.04 LTS (Xenial Xerus) | **1.0.20** | 3.5.1 | 3.18.9
      libgtk-3 | | +| OpenMandriva Lx 3.0 | **1.0.20** | **3.4.2** | 3.18.9
      libgtk+3.0
      lib64gtk+3.0 | | | FreeBSD 13 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-13.0r358841
      (integrated) | | FreeBSD 12 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-11.0r261448_4
      (integrated) | | FreeBSD 11 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-11.0r261448_4
      (integrated) | diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index 46224dddb..22a22f59d 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -35,7 +35,7 @@ if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) add_executable(stlink-gui ${GUI_SOURCES}) install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}) set_target_properties(stlink-gui PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}") + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_FULL_DATAROOTDIR}/${PROJECT_NAME}") target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) install(TARGETS stlink-gui DESTINATION ${CMAKE_INSTALL_BINDIR}) endif () From 304635af647843eed06b16c3cc5806d23cd4c2d0 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Sat, 26 Sep 2020 17:27:00 +0500 Subject: [PATCH 1010/1435] Using vl flashoader with all F1 series --- src/stlink-lib/flash_loader.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 0e79c3c0a..7de485ca3 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -237,6 +237,12 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F1_MEDIUM || + sl->chip_id == STLINK_CHIPID_STM32_F1_HIGH || + sl->chip_id == STLINK_CHIPID_STM32_F1_LOW || + sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW || + sl->chip_id == STLINK_CHIPID_STM32_F1_VL_HIGH || + sl->chip_id == STLINK_CHIPID_STM32_F1_XL || + sl->chip_id == STLINK_CHIPID_STM32_F1_CONN || sl->chip_id == STLINK_CHIPID_STM32_F3 || sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL || sl->chip_id == STLINK_CHIPID_STM32_F303_HIGH || From 2a746afa8ba27d8ebf5d4d5b833aba5cc0641312 Mon Sep 17 00:00:00 2001 From: Timothy Lee Date: Thu, 8 Oct 2020 20:42:09 +1100 Subject: [PATCH 1011/1435] Increase STM32L0 option_size to 20 The FLASH_OPTR, FLASH_WRPROT1 and FLASH_WRPROT2 registers are spread across 20 option bytes. With the original option_size of 4, only the lower 16 bits of FLASH_OPTR could be modified. --- src/stlink-lib/chipid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 3763587e1..dc9f31e44 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -386,7 +386,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1ff0000, .bootrom_size = 0x1000, .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, - .option_size = 4, + .option_size = 20, }, { // STM32L0x Category 5 @@ -400,7 +400,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1ff0000, .bootrom_size = 0x2000, .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, - .option_size = 4, + .option_size = 20, }, { // STM32L0x Category 2 @@ -414,7 +414,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1ff0000, .bootrom_size = 0x1000, .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, - .option_size = 4, + .option_size = 20, }, { // STM32F334, STM32F303x6/8, and STM32F328 From cdac31075590578ff67bbfd4221ab892d50fab42 Mon Sep 17 00:00:00 2001 From: Geert Stappers Date: Sat, 10 Oct 2020 22:10:42 +0200 Subject: [PATCH 1012/1435] [manual] Added st-info --probe example output To show what to expect: information about the ST-link and the target. Bumped date to this month and removed a trailing space. Modified: doc/man/st-info.md --- doc/man/st-info.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/man/st-info.md b/doc/man/st-info.md index 94a430000..9164642f2 100644 --- a/doc/man/st-info.md +++ b/doc/man/st-info.md @@ -1,6 +1,6 @@ % st-flash(1) Open Source STMicroelectronics Stlink Tools | stlink % -% Feb 2018 +% Oct 2020 # NAME st-info - Provides information about connected STLink and STM32 devices @@ -15,7 +15,7 @@ st-info - Provides information about connected STLink and STM32 devices Provides information about connected STLink programmers and STM32 devices: Serial code, OpenOCD hla-serial, flash, page size, sram, chipid, description. -The STLink device to probe can be specified via the environment variable +The STLink device to probe can be specified via the environment variable STLINK_DEVICE on the format :. # OPTIONS @@ -52,6 +52,13 @@ STLINK_DEVICE on the format :. Display information about connected programmers and devices $ st-info --probe + Found 1 stlink programmers + serial: 303033413030323233343338353130323334333133393339 + hla-serial: "\x30\x30\x33\x41\x30\x30\x32\x32\x33\x34\x33\x38\x35\x31\x30\x32\x33\x34\x33\x31\x33\x39\x33\x39" + flash: 131072 (pagesize: 128) + sram: 20480 + chipid: 0x0447 + descr: L0xx Category 5 # SEE ALSO From 1c137bf07fb0e4e17acf73bb0229979971af7389 Mon Sep 17 00:00:00 2001 From: Timothy Lee Date: Wed, 14 Oct 2020 15:28:22 +1100 Subject: [PATCH 1013/1435] st-flash: respect --connect-under-reset option when opening USB connection --- src/st-flash/flash.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 9116f9c80..d8bd8772c 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -61,7 +61,9 @@ int main(int ac, char** av) { printf("st-flash %s\n", STLINK_VERSION); - sl = stlink_open_usb(o.log_level, 1, (char *)o.serial, o.freq); + sl = stlink_open_usb(o.log_level, + o.connect_under_reset ? 2 : 1, + (char *)o.serial, o.freq); if (sl == NULL) { return(-1); } From e8254501a1ce4832c3df9511180ffd6860446353 Mon Sep 17 00:00:00 2001 From: Timothy Lee Date: Sun, 18 Oct 2020 22:33:57 +1100 Subject: [PATCH 1014/1435] Add ability to identify STM32H742/743/753 --- inc/stlink.h | 3 ++- src/common.c | 5 +++++ src/stlink-lib/chipid.c | 11 +++++++++++ src/stlink-lib/chipid.h | 1 + 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/inc/stlink.h b/inc/stlink.h index 1566a0bd6..39f5f283c 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -126,7 +126,8 @@ enum stlink_flash_type { STLINK_FLASH_TYPE_L4, // l4, l4+ */ STLINK_FLASH_TYPE_G0, STLINK_FLASH_TYPE_G4, - STLINK_FLASH_TYPE_WB + STLINK_FLASH_TYPE_WB, + STLINK_FLASH_TYPE_H7, }; struct stlink_reg { diff --git a/src/common.c b/src/common.c index 86d2ca8ea..9aaae9073 100644 --- a/src/common.c +++ b/src/common.c @@ -1172,6 +1172,11 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { return(ret); } + if (*chip_id == 0) { + // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) + ret = stlink_read_debug32(sl, 0x5c001000, chip_id); + } + if (*chip_id == 0) { // Try Corex M0 DBGMCU_IDCODE register address ret = stlink_read_debug32(sl, 0x40015800, chip_id); diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index dc9f31e44..a9fb5af9d 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -614,6 +614,17 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, // see the memory map .bootrom_size = 0x7000 }, + { + // STM32H742/743/753 (from RM0433) + .chip_id = STLINK_CHIPID_STM32_H74XXX, + .description = "H742/743/753", + .flash_type = STLINK_FLASH_TYPE_H7, + .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) + .flash_pagesize = 0x20000, // 128k sector (pg147) + .sram_size = 0x20000, // 128k "DTCM" from Table 7 + .bootrom_base = 0x1ff00000, // "System memory" starting address from Table 7 + .bootrom_size = 0x20000 // "System memory" byte size in hex from Table 7 + }, { // unknown .chip_id = STLINK_CHIPID_UNKNOWN, diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index b591f0012..f717022ca 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -53,6 +53,7 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_L0_CAT5 = 0x447, STLINK_CHIPID_STM32_F0_CAN = 0x448, STLINK_CHIPID_STM32_F7 = 0x449, /* ID found on the NucleoF746ZG board */ + STLINK_CHIPID_STM32_H74XXX = 0x450, /* Found on page 3189 in the RM0433*/ STLINK_CHIPID_STM32_F7XXXX = 0x451, STLINK_CHIPID_STM32_F72XXX = 0x452, /* ID found on the NucleoF722ZE board */ STLINK_CHIPID_STM32_L011 = 0x457, From aada8fc2ddb56debe5900d4affd63e6fb352dc67 Mon Sep 17 00:00:00 2001 From: Timothy Lee Date: Sun, 18 Oct 2020 23:32:06 +1100 Subject: [PATCH 1015/1435] Support flashing of STM32H7xx --- src/common.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 109 insertions(+), 9 deletions(-) diff --git a/src/common.c b/src/common.c index 9aaae9073..26275c175 100644 --- a/src/common.c +++ b/src/common.c @@ -302,6 +302,22 @@ #define FLASH_F2_CR_SNB_MASK 0x78 #define FLASH_F2_SR_BSY 16 +// STM32H7xx +#define FLASH_H7_CR_LOCK 0 +#define FLASH_H7_CR_PG 1 +#define FLASH_H7_CR_SER 2 +#define FLASH_H7_CR_PSIZE 4 +#define FLASH_H7_CR_START 7 +#define FLASH_H7_CR_SNB 8 +#define FLASH_H7_CR_SNB_MASK 0x700 + +#define FLASH_H7_SR_QW 2 + +#define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) +#define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) +#define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c) +#define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) + #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 @@ -381,6 +397,8 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { reg = STM32Gx_FLASH_CR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { reg = STM32WB_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + reg = FLASH_H7_CR1; } else { reg = FLASH_CR; } @@ -431,6 +449,9 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + cr_lock_shift = FLASH_H7_CR_LOCK; } else { ELOG("unsupported flash method, abort\n"); return(-1); @@ -467,6 +488,8 @@ static void unlock_flash(stlink_t *sl) { key_reg = STM32Gx_FLASH_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { key_reg = STM32WB_FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + key_reg = FLASH_H7_KEYR1; } else { ELOG("unsupported flash method, abort\n"); return; @@ -498,6 +521,7 @@ static int unlock_flash_if(stlink_t *sl) { static void lock_flash(stlink_t *sl) { uint32_t cr_lock_shift, cr_reg, n; + uint32_t cr_mask = 0xffffffffu; if (sl->flash_type == STLINK_FLASH_TYPE_F0 || sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { @@ -522,12 +546,17 @@ static void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + cr_lock_shift = FLASH_H7_CR_LOCK; + cr_mask = ~(1u << FLASH_H7_CR_SER); } else { ELOG("unsupported flash method, abort\n"); return; } stlink_read_debug32(sl, cr_reg, &n); + n &= cr_mask; n |= (1u << cr_lock_shift); stlink_write_debug32(sl, cr_reg, n); @@ -724,6 +753,9 @@ static void set_flash_cr_pg(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + x |= (1 << FLASH_H7_CR_PG); } else { cr_reg = FLASH_CR; x = (1 << FLASH_CR_PG); @@ -902,6 +934,9 @@ static void set_flash_cr_strt(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_strt = (1 << STM32WB_FLASH_CR_STRT); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + cr_strt = 1 << FLASH_H7_CR_START; } else { cr_reg = FLASH_CR; cr_strt = (1 << FLASH_CR_STRT); @@ -939,6 +974,8 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { sr_reg = STM32Gx_FLASH_SR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_reg = STM32WB_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_reg = FLASH_H7_SR1; } else { ELOG("unsupported flash method, abort"); return(-1); @@ -973,6 +1010,8 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { sr_busy_shift = STM32Gx_FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_busy_shift = STM32WB_FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_busy_shift = FLASH_H7_SR_QW; } else { ELOG("unsupported flash method, abort"); return(-1); @@ -1064,25 +1103,48 @@ static inline void write_flash_ar2(stlink_t *sl, uint32_t n) { } static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n) { + uint32_t cr_reg, psize_shift; uint32_t x = read_flash_cr(sl); - x &= ~(0x03 << 8); - x |= (n << 8); + + if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + psize_shift = FLASH_H7_CR_PSIZE; + } else { + cr_reg = FLASH_F4_CR; + psize_shift = 8; + } + + x &= ~(0x03 << psize_shift); + x |= (n << psize_shift); #if DEBUG_FLASH fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n); #endif - stlink_write_debug32(sl, FLASH_F4_CR, x); + stlink_write_debug32(sl, cr_reg, x); } - static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { + uint32_t cr_reg, snb_mask, snb_shift, ser_shift; uint32_t x = read_flash_cr(sl); - x &= ~FLASH_F4_CR_SNB_MASK; - x |= (n << FLASH_F4_CR_SNB); - x |= (1 << FLASH_F4_CR_SER); + + if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + snb_mask = FLASH_H7_CR_SNB_MASK; + snb_shift = FLASH_H7_CR_SNB; + ser_shift = FLASH_H7_CR_SER; + } else { + cr_reg = FLASH_F4_CR; + snb_mask = FLASH_F4_CR_SNB_MASK; + snb_shift = FLASH_F4_CR_SNB; + ser_shift = FLASH_F4_CR_SER; + } + + x &= ~snb_mask; + x |= (n << snb_shift); + x |= (1 << ser_shift); #if DEBUG_FLASH fprintf(stdout, "SNB:0x%x 0x%x\n", x, n); #endif - stlink_write_debug32(sl, FLASH_F4_CR, x); + stlink_write_debug32(sl, cr_reg, x); } static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { @@ -2141,6 +2203,11 @@ uint32_t calculate_F7_sectornum(uint32_t flashaddr) { } +uint32_t calculate_H7_sectornum(uint32_t flashaddr) { + flashaddr &= ~STM32_FLASH_BASE; // sector holding the flash address + return(flashaddr / 0x20000); +} + // returns BKER:PNB for the given page address uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { uint32_t bker = 0; @@ -2214,7 +2281,8 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_F7 || - sl->flash_type == STLINK_FLASH_TYPE_L4) { + sl->flash_type == STLINK_FLASH_TYPE_L4 || + sl->flash_type == STLINK_FLASH_TYPE_H7) { // wait for ongoing op to finish wait_flash_busy(sl); @@ -2239,6 +2307,13 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { // calculate the actual page from the address uint32_t sector = calculate_F7_sectornum(flashaddr); + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", + sector, stlink_calculate_pagesize(sl, flashaddr)); + write_flash_cr_snb(sl, sector); + } else if (sl->chip_id == STLINK_CHIPID_STM32_H74XXX) { + // calculate the actual page from the address + uint32_t sector = calculate_H7_sectornum(flashaddr); + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, stlink_calculate_pagesize(sl, flashaddr)); write_flash_cr_snb(sl, sector); @@ -2854,6 +2929,31 @@ int stlink_write_flash( } fprintf(stdout, "\n"); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + ILOG("Starting Flash write for H7 core id\n"); + + unlock_flash_if(sl); // unlock the cr + set_flash_cr_pg(sl); // set programming mode + + for (off = 0; off < len;) { + // Program STM32H7x with 32-byte Flash words + size_t chunk = (len - off > 32) ? 32 : len - off; + memcpy(sl->q_buf, base + off, chunk); + stlink_write_mem32(sl, addr + (uint32_t)off, 32); + wait_flash_busy(sl); + + off += chunk; + + if (sl->verbose >= 1) { + // show progress + fprintf(stdout, "\r%u/%u bytes written", (unsigned int)off, (unsigned int)len); + fflush(stdout); + } + } + fprintf(stdout, "\n"); + + clear_flash_cr_pg(sl); + lock_flash(sl); } else { ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); return(-1); From bbc2b5417174418c597abc75755b12c11aee8f9a Mon Sep 17 00:00:00 2001 From: Timothy Lee Date: Mon, 19 Oct 2020 23:29:54 +1100 Subject: [PATCH 1016/1435] [feature] support STM32H7 option bytes --- inc/stm32.h | 1 + src/common.c | 95 +++++++++++++++++++++++++++++++++++++++++ src/stlink-lib/chipid.c | 4 +- 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/inc/stm32.h b/inc/stm32.h index 96836c9b7..1773e703b 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -21,5 +21,6 @@ #define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) #define STM32_F7_OPTION_BYTES_BASE ((uint32_t)0x1FFF0000) +#define STM32_H7_OPTION_BYTES_BASE ((uint32_t)0x5200201C) #endif // STM32_H diff --git a/src/common.c b/src/common.c index 26275c175..a08db2733 100644 --- a/src/common.c +++ b/src/common.c @@ -313,10 +313,23 @@ #define FLASH_H7_SR_QW 2 +#define FLASH_H7_OPTCR_OPTLOCK 0 +#define FLASH_H7_OPTCR_OPTSTART 1 +#define FLASH_H7_OPTCR_MER 4 + +#define FLASH_H7_OPTSR_OPT_BUSY 0 +#define FLASH_H7_OPTSR_OPTCHANGEERR 30 + +#define FLASH_H7_OPTCCR_CLR_OPTCHANGEERR 30 + #define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) #define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) +#define FLASH_H7_OPT_KEYR (FLASH_H7_REGS_ADDR + 0x08) #define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c) #define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) +#define FLASH_H7_OPTCR (FLASH_H7_REGS_ADDR + 0x18) +#define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) +#define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 @@ -603,6 +616,10 @@ static bool is_flash_option_locked(stlink_t *sl) { optcr_reg = STM32WB_FLASH_CR; optlock_shift = STM32WB_FLASH_CR_OPTLOCK; break; + case STLINK_FLASH_TYPE_H7: + optcr_reg = FLASH_H7_OPTCR; + optlock_shift = FLASH_H7_OPTCR_OPTLOCK; + break; default: ELOG("unsupported flash method, abort\n"); return -1; @@ -654,6 +671,10 @@ static int lock_flash_option(stlink_t *sl) { optcr_reg = STM32WB_FLASH_CR; optlock_shift = STM32WB_FLASH_CR_OPTLOCK; break; + case STLINK_FLASH_TYPE_H7: + optcr_reg = FLASH_H7_OPTCR; + optlock_shift = FLASH_H7_OPTCR_OPTLOCK; + break; default: ELOG("unsupported flash method, abort\n"); return -1; @@ -704,6 +725,9 @@ static int unlock_flash_option(stlink_t *sl) { case STLINK_FLASH_TYPE_WB: optkey_reg = STM32WB_FLASH_OPT_KEYR; break; + case STLINK_FLASH_TYPE_H7: + optkey_reg = FLASH_H7_OPT_KEYR; + break; default: ELOG("unsupported flash method, abort\n"); return(-1); @@ -3413,6 +3437,74 @@ static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t* base, stm32_addr_ return ret; } +/** + * Write STM32H7xx option bytes + * @param sl + * @param base option bytes to write + * @param addr of the memory mapped option bytes + * @param len number of bytes to write (must be multiple of 4) + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_h7( + stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { + uint32_t val; + uint32_t data; + + // Wait until previous flash option has completed + wait_flash_busy(sl); + + // Clear previous error + stlink_write_debug32(sl, FLASH_H7_OPTCCR, 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); + + while (len != 0) { + switch (addr) { + case FLASH_H7_REGS_ADDR + 0x20: // FLASH_OPTSR_PRG + case FLASH_H7_REGS_ADDR + 0x2c: // FLASH_PRAR_PRG1 + case FLASH_H7_REGS_ADDR + 0x34: // FLASH_SCAR_PRG1 + case FLASH_H7_REGS_ADDR + 0x3c: // FLASH_WPSN_PRG1 + case FLASH_H7_REGS_ADDR + 0x44: // FLASH_BOOT_PRG + /* Write to FLASH_xxx_PRG registers */ + write_uint32((unsigned char*)&data, *(uint32_t*)(base)); // write options bytes + + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + + /* Skip if the value in the CUR register is identical */ + stlink_read_debug32(sl, addr - 4, &val); + if (val == data) { + break; + } + + /* Write new option byte values and start modification */ + stlink_write_debug32(sl, addr, data); + stlink_read_debug32(sl, FLASH_H7_OPTCR, &val); + val |= (1 << FLASH_H7_OPTCR_OPTSTART); + stlink_write_debug32(sl, FLASH_H7_OPTCR, val); + + /* Wait for the option bytes modification to complete */ + do { + stlink_read_debug32(sl, FLASH_H7_OPTSR_CUR, &val); + } while ((val & (1 << FLASH_H7_OPTSR_OPT_BUSY)) != 0); + + /* Check for errors */ + if ((val & (1 << FLASH_H7_OPTSR_OPTCHANGEERR)) != 0) { + stlink_write_debug32(sl, FLASH_H7_OPTCCR, 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); + return -1; + } + break; + + default: + /* Skip non-programmable registers */ + break; + } + + len -= 4; + addr += 4; + base += 4; + } + + return 0; +} + /** * Read option bytes * @param sl @@ -3735,6 +3827,9 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui case STLINK_FLASH_TYPE_G4: ret = stlink_write_option_bytes_gx(sl, base, addr, len); break; + case STLINK_FLASH_TYPE_H7: + ret = stlink_write_option_bytes_h7(sl, base, addr, len); + break; default: ELOG("Option bytes writing is currently not implemented for connected chip\n"); break; diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index a9fb5af9d..c191fa919 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -623,7 +623,9 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x20000, // 128k sector (pg147) .sram_size = 0x20000, // 128k "DTCM" from Table 7 .bootrom_base = 0x1ff00000, // "System memory" starting address from Table 7 - .bootrom_size = 0x20000 // "System memory" byte size in hex from Table 7 + .bootrom_size = 0x20000, // "System memory" byte size in hex from Table 7 + .option_base = STM32_H7_OPTION_BYTES_BASE, + .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 }, { // unknown From 781557dfba15d6539ccf85e2a385e4004af875a8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 24 Oct 2020 18:06:56 +0200 Subject: [PATCH 1017/1435] Removed outdated debian configuration Debian package build uses cmake environment. --- cmake/packaging/cpack_config.cmake | 2 +- debian/.gitignore | 10 -- debian/changelog | 74 --------------- debian/control | 44 --------- debian/copyright | 37 -------- debian/gbp.conf | 7 -- debian/libstlink-dev.install | 4 - debian/libstlink1.install | 1 - debian/libstlink1.symbols | 141 ----------------------------- debian/patches/guipath.patch | 11 --- debian/patches/series | 1 - debian/rules | 23 ----- debian/source/format | 1 - debian/source/options | 1 - debian/stlink-gui.install | 4 - debian/stlink-tools.install | 3 - debian/stlink-tools.manpages | 3 - debian/stlink.pc.in | 10 -- debian/watch | 3 - 19 files changed, 1 insertion(+), 379 deletions(-) delete mode 100644 debian/.gitignore delete mode 100644 debian/changelog delete mode 100644 debian/control delete mode 100644 debian/copyright delete mode 100644 debian/gbp.conf delete mode 100644 debian/libstlink-dev.install delete mode 100644 debian/libstlink1.install delete mode 100644 debian/libstlink1.symbols delete mode 100644 debian/patches/guipath.patch delete mode 100644 debian/patches/series delete mode 100755 debian/rules delete mode 100644 debian/source/format delete mode 100644 debian/source/options delete mode 100644 debian/stlink-gui.install delete mode 100644 debian/stlink-tools.install delete mode 100644 debian/stlink-tools.manpages delete mode 100644 debian/stlink.pc.in delete mode 100644 debian/watch diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake index 469e743ca..acd5630fa 100644 --- a/cmake/packaging/cpack_config.cmake +++ b/cmake/packaging/cpack_config.cmake @@ -54,7 +54,7 @@ elseif (EXISTS "/etc/debian_version" AND NOT EXISTS WIN32) # Package-build is av # CPACK_DEBIAN_PACKAGE_ARCHITECTURE --> Default: Output of dpkg --print-architecture set(CPACK_DEBIAN_PACKAGE_DEPENDS "pkg-config, build-essential, debhelper (>=9), cmake (>= 3.4.2), libusb-1.0-0-dev (>= 1.0.20)") - set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Luca Boccassi ") + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Nightwalker-87 ") # CPACK_DEBIAN_PACKAGE_DESCRIPTION --> Default: CPACK_DEBIAN_PACKAGE_DESCRIPTION (as it is set) # CPACK_DEBIAN_PACKAGE_SECTION --> Default: “devel” # CPACK_DEBIAN_ARCHIVE_TYPE --> Default: “gnutar” diff --git a/debian/.gitignore b/debian/.gitignore deleted file mode 100644 index 7624d1c9b..000000000 --- a/debian/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.debhelper -files -debhelper-build-stamp -*.log -*.substvars -libstlink-dev -libstlink -stlink-gui -stlink-tools -tmp diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index c54850340..000000000 --- a/debian/changelog +++ /dev/null @@ -1,74 +0,0 @@ -stlink (1.6.1+ds-2) unstable; urgency=medium - - * Update d/copyright to remove GPL-2+ stanza about flashloaders - * Update upstream URLs for new Github org - * Patch CMake's hard-coded define of XML gui file location (Closes: - #963219) - - -- Luca Boccassi Sun, 21 Jun 2020 13:41:37 +0100 - -stlink (1.6.1+ds-1) unstable; urgency=medium - - * Merge tag 'v1.6.1' into debian - * Update Files-Excluded in d/copyright for new layout - * Fix d/watch intermediary file name - * Drop cross.patch, merged upstream in v1.6.1 - * Bump Build-Depends to cmake >= 3.4.2 - * Add new symbols from upstream version 1.6.1 - * Adjust install files, some files moved - * Remove unused variable from d/rules - * Generate pkgconfig file from d/rules, upstream doesn't do it - * Switch to debhelper-compat 12 - - -- Luca Boccassi Sat, 06 Jun 2020 14:44:54 +0100 - -stlink (1.6.0+ds-1) unstable; urgency=medium - - * Merge tag 'v1.6.0' into debian - * Bump Standards-Version to 4.5.0, no changes. - * Update libstlink1 symbols file for 1.6.0. - - -- Luca Boccassi Tue, 25 Feb 2020 22:08:33 +0000 - -stlink (1.5.1+ds-2) unstable; urgency=medium - - * Mark library packages as Multi-Arch: same. - * Apply cross.patch to fix cross-compiling the GUI. Thanks Helmut for - the patch! (Closes: #941320) - * Vcs-Git: add -b debian - * Set Rules-Requires-Root: no - * Bump Standards-Version to 4.4.0 - - -- Luca Boccassi Sun, 29 Sep 2019 12:50:58 +0100 - -stlink (1.5.1+ds-1) unstable; urgency=medium - - * Merge tag 'v1.5.1' into debian. See upstream changelog for info: - https://github.com/stlink-org/stlink/releases/tag/v1.5.1 - * Mark packages as linux-any, other systems not supported. - - -- Luca Boccassi Fri, 28 Sep 2018 10:26:39 +0100 - -stlink (1.5.0+ds-1) unstable; urgency=medium - - * Upload to unstable. (Closes: #869421) - - -- Luca Boccassi Fri, 16 Mar 2018 16:56:17 +0000 - -stlink (1.4.0) unstable; urgency=low - - -- Andrew 'Necromant' Andrianov Sat, 01 Jul 2017 00:00:00 +0000 - -stlink (1.3.1) unstable; urgency=low - - -- Andrew 'Necromant' Andrianov Sat, 25 Feb 2017 00:00:00 +0000 - -stlink (1.3.0) unstable; urgency=low - - -- Andrew 'Necromant' Andrianov Sat, 28 Jan 2017 00:00:00 +0000 - -stlink (1.2.1) unstable; urgency=low - - * Initial Debian-Packaged Release. - - -- Andrew 'Necromant' Andrianov Sat, 09 Jul 2016 23:16:07 +0300 diff --git a/debian/control b/debian/control deleted file mode 100644 index 598e0e89f..000000000 --- a/debian/control +++ /dev/null @@ -1,44 +0,0 @@ -Source: stlink -Priority: optional -Maintainer: Luca Boccassi -Build-Depends: debhelper-compat (= 12), cmake (>= 3.4.2), libusb-1.0-0-dev, libgtk-3-dev -Standards-Version: 4.5.0 -Rules-Requires-Root: no -Section: electronics -Homepage: https://github.com/stlink-org/stlink -Vcs-Git: https://github.com/bluca/stlink.git -b debian -Vcs-Browser: https://github.com/bluca/stlink - -Package: libstlink-dev -Section: libdevel -Architecture: linux-any -Multi-Arch: same -Depends: libstlink1 (= ${binary:Version}), ${misc:Depends} -Description: Open source STM32 MCU programming toolset. - . - This package contains the development files for stlink. - -Package: libstlink1 -Section: libs -Architecture: linux-any -Multi-Arch: same -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: Open source STM32 MCU programming toolset. - . - This package contains the shared library for stlink. - -Package: stlink-tools -Architecture: linux-any -Depends: libstlink1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} -Description: Open source STM32 MCU programming toolset. - . - This package contains commandline utilities for stlink, modprobe- and - udev-rules. - -Package: stlink-gui -Architecture: linux-any -Depends: libstlink1 (= ${binary:Version}), stlink-tools (= ${binary:Version}), - ${shlibs:Depends}, ${misc:Depends} -Description: Open source STM32 MCU programming toolset. - . - This package contains a GUI for stlink. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index 8329cc250..000000000 --- a/debian/copyright +++ /dev/null @@ -1,37 +0,0 @@ -Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: stlink -Upstream-Contact: Luca Boccassi -Source: https://github.com/stlink-org/stlink -Files-Excluded: stlinkv1_macos_driver - -Files: * -Copyright: 2011-2020 stlink-org - Martin Capitanio [capnm] - Fabien Le Mentec [texane] - Jerry Jacobs [xor-gate] - [Nightwalker-87] - and many others... - An extended list of contributors can be found in "contributors.txt". -License: BSD-3-clause - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - . - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - . - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/debian/gbp.conf b/debian/gbp.conf deleted file mode 100644 index 418e536e9..000000000 --- a/debian/gbp.conf +++ /dev/null @@ -1,7 +0,0 @@ -[buildpackage] -upstream-tag = %(version)s -debian-branch = debian - -[dch] -git-log = --first-parent -customizations = /usr/share/doc/git-buildpackage/examples/wrap_cl.py diff --git a/debian/libstlink-dev.install b/debian/libstlink-dev.install deleted file mode 100644 index 4e0e0d184..000000000 --- a/debian/libstlink-dev.install +++ /dev/null @@ -1,4 +0,0 @@ -usr/include/* -usr/lib/*/lib*.a -usr/lib/*/pkgconfig/* -usr/lib/*/lib*.so diff --git a/debian/libstlink1.install b/debian/libstlink1.install deleted file mode 100644 index 3ddde5841..000000000 --- a/debian/libstlink1.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/*/lib*.so.* diff --git a/debian/libstlink1.symbols b/debian/libstlink1.symbols deleted file mode 100644 index 159f27d0f..000000000 --- a/debian/libstlink1.symbols +++ /dev/null @@ -1,141 +0,0 @@ -libstlink.so.1 libstlink1 #MINVER# - Md5Calculate@Base 1.6.1 - Md5Finalise@Base 1.6.1 - Md5Initialise@Base 1.6.1 - Md5Update@Base 1.6.1 - _parse_version@Base 1.5.0 - _stlink_sg_close@Base 1.5.0 - _stlink_sg_core_id@Base 1.5.0 - _stlink_sg_current_mode@Base 1.5.0 - _stlink_sg_enter_jtag_mode@Base 1.5.0 - _stlink_sg_enter_swd_mode@Base 1.5.0 - _stlink_sg_exit_debug_mode@Base 1.5.0 - _stlink_sg_exit_dfu_mode@Base 1.5.0 - _stlink_sg_force_debug@Base 1.5.0 - _stlink_sg_jtag_reset@Base 1.5.0 - _stlink_sg_read_all_regs@Base 1.5.0 - _stlink_sg_read_debug32@Base 1.5.0 - _stlink_sg_read_mem32@Base 1.5.0 - _stlink_sg_read_reg@Base 1.5.0 - _stlink_sg_reset@Base 1.5.0 - _stlink_sg_run@Base 1.5.0 - _stlink_sg_status@Base 1.5.0 - _stlink_sg_step@Base 1.5.0 - _stlink_sg_version@Base 1.5.0 - _stlink_sg_write_debug32@Base 1.5.0 - _stlink_sg_write_mem32@Base 1.5.0 - _stlink_sg_write_mem8@Base 1.5.0 - _stlink_sg_write_reg@Base 1.5.0 - _stlink_usb_close@Base 1.5.0 - _stlink_usb_core_id@Base 1.5.0 - _stlink_usb_current_mode@Base 1.5.0 - _stlink_usb_enter_swd_mode@Base 1.5.0 - _stlink_usb_exit_debug_mode@Base 1.5.0 - _stlink_usb_exit_dfu_mode@Base 1.5.0 - _stlink_usb_force_debug@Base 1.5.0 - _stlink_usb_get_rw_status@Base 1.6.1 - _stlink_usb_jtag_reset@Base 1.5.0 - _stlink_usb_read_all_regs@Base 1.5.0 - _stlink_usb_read_all_unsupported_regs@Base 1.5.0 - _stlink_usb_read_debug32@Base 1.5.0 - _stlink_usb_read_mem32@Base 1.5.0 - _stlink_usb_read_reg@Base 1.5.0 - _stlink_usb_read_unsupported_reg@Base 1.5.0 - _stlink_usb_reset@Base 1.5.0 - _stlink_usb_run@Base 1.5.0 - _stlink_usb_set_swdclk@Base 1.5.0 - _stlink_usb_status@Base 1.5.0 - _stlink_usb_status_v2@Base 1.6.1 - _stlink_usb_step@Base 1.5.0 - _stlink_usb_target_voltage@Base 1.5.0 - _stlink_usb_version@Base 1.5.0 - _stlink_usb_write_debug32@Base 1.5.0 - _stlink_usb_write_mem32@Base 1.5.0 - _stlink_usb_write_mem8@Base 1.5.0 - _stlink_usb_write_reg@Base 1.5.0 - _stlink_usb_write_unsupported_reg@Base 1.5.0 - calculate_F4_sectornum@Base 1.5.0 - calculate_F7_sectornum@Base 1.5.0 - calculate_L4_page@Base 1.5.0 - is_bigendian@Base 1.5.0 - read_uint16@Base 1.5.0 - read_uint32@Base 1.5.0 - send_recv@Base 1.5.0 - send_usb_data_only@Base 1.5.0 - send_usb_mass_storage_command@Base 1.5.0 - stlink_calculate_pagesize@Base 1.5.0 - stlink_chip_id@Base 1.5.0 - stlink_chipid_get_params@Base 1.5.0 - stlink_close@Base 1.5.0 - stlink_clr_hw_bp@Base 1.5.0 - stlink_core_id@Base 1.5.0 - stlink_core_stat@Base 1.5.0 - stlink_cpu_id@Base 1.5.0 - stlink_current_mode@Base 1.5.0 - stlink_enter_swd_mode@Base 1.5.0 - stlink_erase_flash_mass@Base 1.5.0 - stlink_erase_flash_page@Base 1.5.0 - stlink_exit_debug_mode@Base 1.5.0 - stlink_exit_dfu_mode@Base 1.5.0 - stlink_fcheck_flash@Base 1.5.0 - stlink_flash_loader_init@Base 1.5.0 - stlink_flash_loader_run@Base 1.5.0 - stlink_flash_loader_write_to_sram@Base 1.5.0 - stlink_force_debug@Base 1.5.0 - stlink_fread@Base 1.5.0 - stlink_fwrite_flash@Base 1.5.0 - stlink_fwrite_option_bytes@Base 1.6.0 -#MISSING: 1.6.1# stlink_fwrite_option_bytes_32bit@Base 1.6.0 - stlink_fwrite_sram@Base 1.5.0 - stlink_get_erased_pattern@Base 1.5.0 - stlink_is_core_halted@Base 1.5.0 - stlink_jtag_reset@Base 1.5.0 - stlink_load_device_params@Base 1.5.0 - stlink_mwrite_flash@Base 1.5.0 - stlink_mwrite_sram@Base 1.5.0 - stlink_open_usb@Base 1.5.0 - stlink_parse_ihex@Base 1.5.0 - stlink_print_data@Base 1.5.0 - stlink_probe_usb@Base 1.5.0 - stlink_probe_usb_free@Base 1.5.0 - stlink_q@Base 1.5.0 - stlink_read_all_regs@Base 1.5.0 - stlink_read_all_unsupported_regs@Base 1.5.0 - stlink_read_debug32@Base 1.5.0 - stlink_read_mem32@Base 1.5.0 - stlink_read_option_bytes32@Base 1.6.1 - stlink_read_option_bytes_Gx@Base 1.6.1 - stlink_read_option_bytes_f2@Base 1.6.0 - stlink_read_option_bytes_f4@Base 1.6.0 - stlink_read_option_bytes_generic@Base 1.6.1 - stlink_read_reg@Base 1.5.0 - stlink_read_unsupported_reg@Base 1.5.0 - stlink_reset@Base 1.5.0 - stlink_run@Base 1.5.0 - stlink_run_at@Base 1.5.0 - stlink_set_hw_bp@Base 1.5.0 - stlink_set_swdclk@Base 1.5.0 - stlink_stat@Base 1.5.0 - stlink_status@Base 1.5.0 - stlink_step@Base 1.5.0 - stlink_target_voltage@Base 1.5.0 - stlink_v1_open@Base 1.5.0 - stlink_v1_open_inner@Base 1.5.0 - stlink_verify_write_flash@Base 1.5.0 - stlink_version@Base 1.5.0 - stlink_write_debug32@Base 1.5.0 - stlink_write_dreg@Base 1.5.0 - stlink_write_flash@Base 1.5.0 - stlink_write_mem32@Base 1.5.0 - stlink_write_mem8@Base 1.5.0 - stlink_write_option_bytes32@Base 1.6.1 - stlink_write_option_bytes@Base 1.6.0 - stlink_write_reg@Base 1.5.0 - stlink_write_unsupported_reg@Base 1.5.0 - stm32l1_write_half_pages@Base 1.5.0 - ugly_init@Base 1.5.0 - ugly_libusb_log_level@Base 1.6.1 - ugly_log@Base 1.5.0 - write_buffer_to_sram@Base 1.5.0 - write_uint16@Base 1.5.0 - write_uint32@Base 1.5.0 diff --git a/debian/patches/guipath.patch b/debian/patches/guipath.patch deleted file mode 100644 index d3effc92b..000000000 --- a/debian/patches/guipath.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/src/stlink-gui/CMakeLists.txt -+++ b/src/stlink-gui/CMakeLists.txt -@@ -32,7 +32,7 @@ - add_executable(stlink-gui ${GUI_SOURCES}) - install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_BINDIR}) - set_target_properties(stlink-gui PROPERTIES -- COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/bin") -+ COMPILE_DEFINITIONS STLINK_UI_DIR="/usr/share/stlink") - target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) - install(TARGETS stlink-gui DESTINATION ${CMAKE_INSTALL_BINDIR}) - diff --git a/debian/patches/series b/debian/patches/series deleted file mode 100644 index 1fdcf9977..000000000 --- a/debian/patches/series +++ /dev/null @@ -1 +0,0 @@ -guipath.patch diff --git a/debian/rules b/debian/rules deleted file mode 100755 index 512bd533f..000000000 --- a/debian/rules +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/make -f -# See debhelper(7) (uncomment to enable) -# output every command that modifies files on the build system. -#DH_VERBOSE = 1 - -# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* -DPKG_EXPORT_BUILDFLAGS = 1 -include /usr/share/dpkg/default.mk - -# see FEATURE AREAS in dpkg-buildflags(1) -export DEB_BUILD_MAINT_OPTIONS = hardening=+all - -%: - dh $@ --buildsystem cmake - -override_dh_auto_configure: - dh_auto_configure -- \ - -DSTLINK_UDEV_RULES_DIR='/lib/udev/rules.d' - -override_dh_auto_install: - dh_auto_install - mkdir -p $(CURDIR)/debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig - sed -e "s/@VERSION@/$(DEB_VERSION_UPSTREAM)/" -e "s/@DEB_HOST_MULTIARCH@/$(DEB_HOST_MULTIARCH)/" $(CURDIR)/debian/stlink.pc.in > $(CURDIR)/debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig/stlink.pc diff --git a/debian/source/format b/debian/source/format deleted file mode 100644 index 163aaf8d8..000000000 --- a/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/debian/source/options b/debian/source/options deleted file mode 100644 index 506210d2c..000000000 --- a/debian/source/options +++ /dev/null @@ -1 +0,0 @@ -extend-diff-ignore=stlinkv1_macos_driver diff --git a/debian/stlink-gui.install b/debian/stlink-gui.install deleted file mode 100644 index 96c55213f..000000000 --- a/debian/stlink-gui.install +++ /dev/null @@ -1,4 +0,0 @@ -/usr/bin/stlink-gui -/usr/share/stlink/stlink-gui.ui -/usr/share/applications/stlink-gui.desktop -/usr/share/icons/hicolor/scalable/apps/stlink-gui.svg diff --git a/debian/stlink-tools.install b/debian/stlink-tools.install deleted file mode 100644 index ca875a0e6..000000000 --- a/debian/stlink-tools.install +++ /dev/null @@ -1,3 +0,0 @@ -/usr/bin/st-* -lib/udev/rules.d/*.rules -etc/modprobe.d/*.conf diff --git a/debian/stlink-tools.manpages b/debian/stlink-tools.manpages deleted file mode 100644 index 049509abe..000000000 --- a/debian/stlink-tools.manpages +++ /dev/null @@ -1,3 +0,0 @@ -usr/share/stlink/man/man1/st-flash.1 -usr/share/stlink/man/man1/st-info.1 -usr/share/stlink/man/man1/st-util.1 diff --git a/debian/stlink.pc.in b/debian/stlink.pc.in deleted file mode 100644 index 9f740ba09..000000000 --- a/debian/stlink.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix=/usr -includedir=${prefix}/include/stlink -libdir=${prefix}/lib/@DEB_HOST_MULTIARCH@ - -Name: stlink -Description: Open source STM32 MCU programming toolset -Version: @VERSION@ -Requires: libusb-1.0 -Libs: -L${libdir} -lstlink -Cflags: -I${includedir} diff --git a/debian/watch b/debian/watch deleted file mode 100644 index 6eb6b78d6..000000000 --- a/debian/watch +++ /dev/null @@ -1,3 +0,0 @@ -version=3 -opts=dversionmangle=s/\+ds$//,repacksuffix=+ds,filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/stlink-$1\.tar\.gz/ \ - https://github.com/stlink-org/stlink/tags .*/v?(\d\S+)\.tar\.gz From e43b434c8ac59885710cb4b2b05fb49d7c023ad4 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Tue, 27 Oct 2020 11:41:39 +0500 Subject: [PATCH 1018/1435] Small rewrote setting breakpoints in gdb-server for Cortex-M7 --- inc/stm32.h | 1 + src/common.c | 8 +++- src/st-util/gdb-server.c | 92 +++++++++++++--------------------------- src/stlink-lib/reg.h | 10 ++++- 4 files changed, 47 insertions(+), 64 deletions(-) diff --git a/inc/stm32.h b/inc/stm32.h index 1773e703b..768fabb87 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -10,6 +10,7 @@ /* Cortex core ids */ #define STM32VL_CORE_ID 0x1ba01477 #define STM32F7_CORE_ID 0x5ba02477 +#define STM32H7_CORE_ID 0x6ba02477 // STM32H7 JTAG ID Code (RM0433 pg3065) /* Constant STM32 memory map figures */ #define STM32_FLASH_BASE ((uint32_t)0x08000000) diff --git a/src/common.c b/src/common.c index a08db2733..c7f2883db 100644 --- a/src/common.c +++ b/src/common.c @@ -1252,7 +1252,13 @@ int stlink_core_id(stlink_t *sl) { int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { int ret; - ret = stlink_read_debug32(sl, 0xE0042000, chip_id); + if (sl->core_id == STM32H7_CORE_ID) { + // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) + ret = stlink_read_debug32(sl, 0x5c001000, chip_id); + } else { + // default chipid address + ret = stlink_read_debug32(sl, 0xE0042000, chip_id); + } if (ret == -1) { return(ret); diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 60c9c16d3..d2685cef6 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -575,21 +575,6 @@ char* make_memory_map(stlink_t *sl) { return(map); } -/* - * DWT_COMP0 0xE0001020 - * DWT_MASK0 0xE0001024 - * DWT_FUNCTION0 0xE0001028 - * DWT_COMP1 0xE0001030 - * DWT_MASK1 0xE0001034 - * DWT_FUNCTION1 0xE0001038 - * DWT_COMP2 0xE0001040 - * DWT_MASK2 0xE0001044 - * DWT_FUNCTION2 0xE0001048 - * DWT_COMP3 0xE0001050 - * DWT_MASK3 0xE0001054 - * DWT_FUNCTION3 0xE0001058 - */ - #define DATA_WATCH_NUM 4 enum watchfun { WATCHDISABLED = 0, WATCHREAD = 5, WATCHWRITE = 6, WATCHACCESS = 7 }; @@ -606,15 +591,15 @@ static void init_data_watchpoints(stlink_t *sl) { uint32_t data; DLOG("init watchpoints\n"); - stlink_read_debug32(sl, 0xE000EDFC, &data); + stlink_read_debug32(sl, STLINK_REG_CM3_DEMCR, &data); data |= 1 << 24; - // set trcena in debug command to turn on dwt unit - stlink_write_debug32(sl, 0xE000EDFC, data); + // set TRCENA in debug command to turn on DWT unit + stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, data); // make sure all watchpoints are cleared for (int i = 0; i < DATA_WATCH_NUM; i++) { data_watches[i].fun = WATCHDISABLED; - stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); + stlink_write_debug32(sl, STLINK_REG_CM3_DWT_FUNn(i), 0); } } @@ -645,16 +630,16 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr data_watches[i].mask = mask; // insert comparator address - stlink_write_debug32(sl, 0xE0001020 + i * 16, addr); + stlink_write_debug32(sl, STLINK_REG_CM3_DWT_COMPn(i), addr); // insert mask - stlink_write_debug32(sl, 0xE0001024 + i * 16, mask); + stlink_write_debug32(sl, STLINK_REG_CM3_DWT_MASKn(i), mask); // insert function - stlink_write_debug32(sl, 0xE0001028 + i * 16, wf); + stlink_write_debug32(sl, STLINK_REG_CM3_DWT_FUNn(i), wf); // just to make sure the matched bit is clear ! - stlink_read_debug32(sl, 0xE0001028 + i * 16, &dummy); + stlink_read_debug32(sl, STLINK_REG_CM3_DWT_FUNn(i), &dummy); return(0); } } @@ -671,7 +656,7 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { DLOG("delete watchpoint %d addr %x\n", i, addr); data_watches[i].fun = WATCHDISABLED; - stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); + stlink_write_debug32(sl, STLINK_REG_CM3_DWT_FUNn(i), 0); return(0); } @@ -705,9 +690,15 @@ static void init_code_breakpoints(stlink_t *sl) { ILOG("Found %i hw breakpoint registers\n", code_break_num); + if (sl->core_id == STM32F7_CORE_ID || sl->core_id == STM32H7_CORE_ID) { + // Cortex-M7 can have locked to write FP_* registers + // IHI0029D, p. 48, Lock Access Register + stlink_write_debug32(sl, STLINK_REG_CM7_FP_LAR, STLINK_REG_CM7_FP_LAR_KEY); + } + for (int i = 0; i < code_break_num; i++) { code_breaks[i].type = 0; - stlink_write_debug32(sl, STLINK_REG_CM3_FP_COMP0 + i * 4, 0); + stlink_write_debug32(sl, STLINK_REG_CM3_FP_COMPn(i), 0); } } @@ -719,69 +710,46 @@ static int has_breakpoint(stm32_addr_t addr) { } static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { - stm32_addr_t fpb_addr; uint32_t mask; int type = (addr & 0x2) ? CODE_BREAK_HIGH : CODE_BREAK_LOW; + stm32_addr_t fpb_addr = addr & 0x1FFFFFFC; if (addr & 1) { ELOG("update_code_breakpoint: unaligned address %08x\n", addr); return(-1); } - if (sl->core_id == STM32F7_CORE_ID) { - fpb_addr = addr; - } else { - fpb_addr = addr & ~0x3; - } - int id = -1; - for (int i = 0; i < code_break_num; i++) if (fpb_addr == code_breaks[i].addr || (set && code_breaks[i].type == 0)) { id = i; break; } - if (id == -1) { - if (set) { - return(-1); - } // free slot not found - else { - return(0); - } // breakpoint is already removed - + if (set) + return(-1); // free slot not found + else + return(0); // breakpoint is already removed } struct code_hw_breakpoint* bp = &code_breaks[id]; - bp->addr = fpb_addr; - - if (sl->core_id == STM32F7_CORE_ID) { - if (set) { - bp->type = type; - } else { - bp->type = 0; - } - - mask = (bp->addr) | 1; - } else { - if (set) { - bp->type |= type; - } else { - bp->type &= ~type; - } - - mask = (bp->addr) | 1 | (bp->type << 30); - } + if (set) + bp->type |= type; + else + bp->type &= ~type; + + // DDI0403E, p. 759, FP_COMPn register description + mask = (bp->type << 30) | (bp->addr) | 1; if (bp->type == 0) { DLOG("clearing hw break %d\n", id); - stlink_write_debug32(sl, 0xe0002008 + id * 4, 0); + stlink_write_debug32(sl, STLINK_REG_CM3_FP_COMPn(id), 0); } else { DLOG("setting hw break %d at %08x (%d)\n", id, bp->addr, bp->type); DLOG("reg %08x \n", mask); - stlink_write_debug32(sl, 0xe0002008 + id * 4, mask); + stlink_write_debug32(sl, STLINK_REG_CM3_FP_COMPn(id), mask); } return(0); diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index dde77ef50..3a3682140 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -2,8 +2,16 @@ #define STLINK_REG_H_ #define STLINK_REG_CM3_CPUID 0xE000ED00 + #define STLINK_REG_CM3_FP_CTRL 0xE0002000 -#define STLINK_REG_CM3_FP_COMP0 0xE0002008 +#define STLINK_REG_CM3_FP_COMPn(n) (0xE0002008 + n*4) +#define STLINK_REG_CM7_FP_LAR 0xE0000FB0 +#define STLINK_REG_CM7_FP_LAR_KEY 0xC5ACCE55 + +#define STLINK_REG_CM3_DEMCR 0xE000EDFC +#define STLINK_REG_CM3_DWT_COMPn(n) (0xE0001020 + n*16) +#define STLINK_REG_CM3_DWT_MASKn(n) (0xE0001024 + n*16) +#define STLINK_REG_CM3_DWT_FUNn(n) (0xE0001028 + n*16) /* Cortex™-M3 Technical Reference Manual */ /* Debug Halting Control and Status Register */ From e5dcb5048c58bcbb95fee79e4775b7b447a5fc4f Mon Sep 17 00:00:00 2001 From: Timothy Lee Date: Tue, 27 Oct 2020 20:28:48 +1100 Subject: [PATCH 1019/1435] [feature] support STM32F4 option bytes --- inc/stm32.h | 1 + src/common.c | 1 + src/stlink-lib/chipid.c | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/inc/stm32.h b/inc/stm32.h index 1773e703b..b81d3149d 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -20,6 +20,7 @@ #define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) #define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) +#define STM32_F4_OPTION_BYTES_BASE ((uint32_t)0x40023C14) #define STM32_F7_OPTION_BYTES_BASE ((uint32_t)0x1FFF0000) #define STM32_H7_OPTION_BYTES_BASE ((uint32_t)0x5200201C) diff --git a/src/common.c b/src/common.c index a08db2733..32c00ad3b 100644 --- a/src/common.c +++ b/src/common.c @@ -3680,6 +3680,7 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) { switch (sl->chip_id) { case STLINK_CHIPID_STM32_F2: return stlink_read_option_bytes_f2(sl, option_byte); + case STLINK_CHIPID_STM32_F4: case STLINK_CHIPID_STM32_F446: return stlink_read_option_bytes_f4(sl, option_byte); case STLINK_CHIPID_STM32_F7XXXX: diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index c191fa919..a8d160445 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -77,7 +77,9 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x4000, .sram_size = 0x30000, .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .bootrom_size = 0x7800, + .option_base = STM32_F4_OPTION_BYTES_BASE, + .option_size = 4, }, { .chip_id = STLINK_CHIPID_STM32_F4_DSI, From 59f8b479f6e87181b4d3430ff5a57ce08f820291 Mon Sep 17 00:00:00 2001 From: Fabian Herb Date: Mon, 26 Oct 2020 16:11:49 +0000 Subject: [PATCH 1020/1435] st-util: Add specialized memory map for STM32H7 devices --- src/st-util/gdb-server.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 60c9c16d3..2e936a5de 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -504,6 +504,24 @@ static const char* const memory_map_template_F7 = " " // option byte area "
      "; +static const char* const memory_map_template_H7 = + "" + "" + "" + " " // ITCMRAM 64kB + " " // DTCMRAM 128kB + " " // RAM D1 512kB + " " // RAM D2 288kB + " " // RAM D3 64kB + " " + " 0x%x" + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + ""; + static const char* const memory_map_template_F4_DE = "" @@ -543,6 +561,10 @@ char* make_memory_map(stlink_t *sl) { } else if (sl->core_id == STM32F7_CORE_ID) { snprintf(map, sz, memory_map_template_F7, (unsigned int)sl->sram_size); + } else if (sl->chip_id == STLINK_CHIPID_STM32_H74XXX) { + snprintf(map, sz, memory_map_template_H7, + (unsigned int)sl->flash_size, + (unsigned int)sl->flash_pgsz); } else if (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) { strcpy(map, memory_map_template_F4_HD); } else if (sl->chip_id == STLINK_CHIPID_STM32_F2) { From 31bea45e32d843b5b2d5bb2ea3bba3dbec73ac1b Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Thu, 29 Oct 2020 13:30:16 +0500 Subject: [PATCH 1021/1435] Autodetect breakpoint style and cache support --- src/st-util/gdb-server.c | 75 ++++++++++++++++++++++------------------ src/stlink-lib/reg.h | 14 +++++++- 2 files changed, 55 insertions(+), 34 deletions(-) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index d2685cef6..c832098f1 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -669,9 +669,13 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { static int code_break_num; static int code_lit_num; +static int code_break_rev; #define CODE_BREAK_NUM_MAX 15 #define CODE_BREAK_LOW 0x01 #define CODE_BREAK_HIGH 0x02 +#define CODE_BREAK_REMAP 0x04 +#define CODE_BREAK_REV_V1 0x00 +#define CODE_BREAK_REV_V2 0x01 struct code_hw_breakpoint { stm32_addr_t addr; @@ -683,14 +687,16 @@ static struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM_MAX]; static void init_code_breakpoints(stlink_t *sl) { unsigned int val; memset(sl->q_buf, 0, 4); - stlink_write_debug32(sl, STLINK_REG_CM3_FP_CTRL, 0x03 /* KEY | ENABLE4 */); + stlink_write_debug32(sl, STLINK_REG_CM3_FP_CTRL, 0x03 /* KEY | ENABLE */); stlink_read_debug32(sl, STLINK_REG_CM3_FP_CTRL, &val); code_break_num = ((val >> 4) & 0xf); code_lit_num = ((val >> 8) & 0xf); + code_break_rev = ((val >> 28) & 0xf); ILOG("Found %i hw breakpoint registers\n", code_break_num); - if (sl->core_id == STM32F7_CORE_ID || sl->core_id == STM32H7_CORE_ID) { + stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &val); + if (((val>>4) & 0xFFF) == 0xC27) { // Cortex-M7 can have locked to write FP_* registers // IHI0029D, p. 48, Lock Access Register stlink_write_debug32(sl, STLINK_REG_CM7_FP_LAR, STLINK_REG_CM7_FP_LAR_KEY); @@ -711,14 +717,22 @@ static int has_breakpoint(stm32_addr_t addr) { static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { uint32_t mask; - int type = (addr & 0x2) ? CODE_BREAK_HIGH : CODE_BREAK_LOW; - stm32_addr_t fpb_addr = addr & 0x1FFFFFFC; + int type; + stm32_addr_t fpb_addr; if (addr & 1) { ELOG("update_code_breakpoint: unaligned address %08x\n", addr); return(-1); } + if (code_break_rev == CODE_BREAK_REV_V1) { + type = (addr & 0x2) ? CODE_BREAK_HIGH : CODE_BREAK_LOW; + fpb_addr = addr & 0x1FFFFFFC; + } else { + type = CODE_BREAK_REMAP; + fpb_addr = addr; + } + int id = -1; for (int i = 0; i < code_break_num; i++) if (fpb_addr == code_breaks[i].addr || (set && code_breaks[i].type == 0)) { @@ -741,7 +755,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { bp->type &= ~type; // DDI0403E, p. 759, FP_COMPn register description - mask = (bp->type << 30) | (bp->addr) | 1; + mask = ((bp->type&0x03) << 30) | bp->addr | 1; if (bp->type == 0) { DLOG("clearing hw break %d\n", id); @@ -870,16 +884,6 @@ static int flash_go(stlink_t *sl) { return(error); } -#define CLIDR 0xE000ED78 -#define CTR 0xE000ED7C -#define CCSIDR 0xE000ED80 -#define CSSELR 0xE000ED84 -#define CCR 0xE000ED14 -#define CCR_DC (1 << 16) -#define CCR_IC (1 << 17) -#define DCCSW 0xE000EF6C -#define ICIALLU 0xE000EF50 - struct cache_level_desc { unsigned int nsets; unsigned int nways; @@ -888,6 +892,8 @@ struct cache_level_desc { }; struct cache_desc_t { + unsigned used; + // minimal line size in bytes unsigned int dminline; unsigned int iminline; @@ -914,7 +920,7 @@ static void read_cache_level_desc(stlink_t *sl, struct cache_level_desc *desc) { unsigned int ccsidr; unsigned int log2_nsets; - stlink_read_debug32(sl, CCSIDR, &ccsidr); + stlink_read_debug32(sl, STLINK_REG_CM7_CCSIDR, &ccsidr); desc->nsets = ((ccsidr >> 13) & 0x3fff) + 1; desc->nways = ((ccsidr >> 3) & 0x1ff) + 1; desc->log2_nways = ceil_log2 (desc->nways); @@ -930,18 +936,22 @@ static void init_cache (stlink_t *sl) { unsigned int ctr; int i; - // assume only F7 has a cache - if (sl->core_id != STM32F7_CORE_ID) { return; } - - stlink_read_debug32(sl, CLIDR, &clidr); - stlink_read_debug32(sl, CCR, &ccr); - stlink_read_debug32(sl, CTR, &ctr); + // Check have cache + stlink_read_debug32(sl, STLINK_REG_CM7_CTR, &ctr); + if ((ctr >> 29) != 0x04) { + cache_desc.used = 0; + return; + } else + cache_desc.used = 1; cache_desc.dminline = 4 << ((ctr >> 16) & 0x0f); cache_desc.iminline = 4 << (ctr & 0x0f); + + stlink_read_debug32(sl, STLINK_REG_CM7_CLIDR, &clidr); cache_desc.louu = (clidr >> 27) & 7; + stlink_read_debug32(sl, STLINK_REG_CM7_CCR, &ccr); ILOG("Chip clidr: %08x, I-Cache: %s, D-Cache: %s\n", - clidr, ccr & CCR_IC ? "on" : "off", ccr & CCR_DC ? "on" : "off"); + clidr, ccr & STLINK_REG_CM7_CCR_IC ? "on" : "off", ccr & STLINK_REG_CM7_CCR_DC ? "on" : "off"); ILOG(" cache: LoUU: %u, LoC: %u, LoUIS: %u\n", (clidr >> 27) & 7, (clidr >> 24) & 7, (clidr >> 21) & 7); ILOG(" cache: ctr: %08x, DminLine: %u bytes, IminLine: %u bytes\n", ctr, @@ -953,13 +963,13 @@ static void init_cache (stlink_t *sl) { cache_desc.icache[i].width = 0; if (ct == 2 || ct == 3 || ct == 4) { // data - stlink_write_debug32(sl, CSSELR, i << 1); + stlink_write_debug32(sl, STLINK_REG_CM7_CSSELR, i << 1); ILOG("D-Cache L%d: ", i); read_cache_level_desc(sl, &cache_desc.dcache[i]); } if (ct == 1 || ct == 3) { // instruction - stlink_write_debug32(sl, CSSELR, (i << 1) | 1); + stlink_write_debug32(sl, STLINK_REG_CM7_CSSELR, (i << 1) | 1); ILOG("I-Cache L%d: ", i); read_cache_level_desc(sl, &cache_desc.icache[i]); } @@ -969,7 +979,7 @@ static void init_cache (stlink_t *sl) { static void cache_flush(stlink_t *sl, unsigned ccr) { int level; - if (ccr & CCR_DC) { + if (ccr & STLINK_REG_CM7_CCR_DC) { for (level = cache_desc.louu - 1; level >= 0; level--) { struct cache_level_desc *desc = &cache_desc.dcache[level]; unsigned addr; @@ -981,15 +991,15 @@ static void cache_flush(stlink_t *sl, unsigned ccr) { unsigned int way; for (way = 0; way < desc->nways; way++) { - stlink_write_debug32(sl, DCCSW, addr | (way << way_sh)); + stlink_write_debug32(sl, STLINK_REG_CM7_DCCSW, addr | (way << way_sh)); } } } } // invalidate all I-cache to oPU - if (ccr & CCR_IC) { - stlink_write_debug32(sl, ICIALLU, 0); + if (ccr & STLINK_REG_CM7_CCR_IC) { + stlink_write_debug32(sl, STLINK_REG_CM7_ICIALLU, 0); } } @@ -1005,14 +1015,13 @@ static void cache_change(stm32_addr_t start, unsigned count) { static void cache_sync(stlink_t *sl) { unsigned ccr; - if (sl->core_id != STM32F7_CORE_ID) { return; } + if (!cache_desc.used) { return; } if (!cache_modified) { return; } cache_modified = 0; - stlink_read_debug32(sl, CCR, &ccr); - - if (ccr & (CCR_IC | CCR_DC)) { cache_flush(sl, ccr); } + stlink_read_debug32(sl, STLINK_REG_CM7_CCR, &ccr); + if (ccr & (STLINK_REG_CM7_CCR_IC | STLINK_REG_CM7_CCR_DC)) { cache_flush(sl, ccr); } } static size_t unhexify(const char *in, char *out, size_t out_count) { diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 3a3682140..734107d6a 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -6,7 +6,7 @@ #define STLINK_REG_CM3_FP_CTRL 0xE0002000 #define STLINK_REG_CM3_FP_COMPn(n) (0xE0002008 + n*4) #define STLINK_REG_CM7_FP_LAR 0xE0000FB0 -#define STLINK_REG_CM7_FP_LAR_KEY 0xC5ACCE55 +#define STLINK_REG_CM7_FP_LAR_KEY 0xC5ACCE55 #define STLINK_REG_CM3_DEMCR 0xE000EDFC #define STLINK_REG_CM3_DWT_COMPn(n) (0xE0001020 + n*16) @@ -25,4 +25,16 @@ #define STLINK_REG_AIRCR_VECTKEY 0x05fa0000 #define STLINK_REG_AIRCR_SYSRESETREQ 0x00000004 +/* ARM Cortex-M7 Processor Technical Reference Manual */ +/* Cache Control and Status Register */ +#define STLINK_REG_CM7_CTR 0xE000ED7C +#define STLINK_REG_CM7_CLIDR 0xE000ED78 +#define STLINK_REG_CM7_CCR 0xE000ED14 +#define STLINK_REG_CM7_CCR_DC (1 << 16) +#define STLINK_REG_CM7_CCR_IC (1 << 17) +#define STLINK_REG_CM7_CSSELR 0xE000ED84 +#define STLINK_REG_CM7_DCCSW 0xE000EF6C +#define STLINK_REG_CM7_ICIALLU 0xE000EF50 +#define STLINK_REG_CM7_CCSIDR 0xE000ED80 + #endif // STLINK_REG_H_ From f503de605561a71bd4dafca59826d7847604ccd3 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Thu, 29 Oct 2020 18:06:33 +0000 Subject: [PATCH 1022/1435] Add cross.patch to fix cross-compilation. Thanks Helmut! Closes: #973339 --- debian/patches/cross.patch | 11 +++++++++++ debian/patches/series | 1 + 2 files changed, 12 insertions(+) create mode 100644 debian/patches/cross.patch diff --git a/debian/patches/cross.patch b/debian/patches/cross.patch new file mode 100644 index 000000000..8d927ba4b --- /dev/null +++ b/debian/patches/cross.patch @@ -0,0 +1,11 @@ +--- stlink-1.6.1+ds.orig/CMakeLists.txt ++++ stlink-1.6.1+ds/CMakeLists.txt +@@ -48,7 +48,7 @@ + find_package(libusb REQUIRED) + + ## Package configuration (pkg-config) on unix-based systems +-if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) ++if (NOT WIN32) + #add_subdirectory(cmake/pkgconfig) + find_package(PkgConfig) + pkg_check_modules(GTK3 gtk+-3.0) diff --git a/debian/patches/series b/debian/patches/series index 1fdcf9977..b3c28e7e1 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1 +1,2 @@ guipath.patch +cross.patch From a952c950a62038b231a8e303c03d1c34b0e13bcd Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Thu, 29 Oct 2020 18:06:53 +0000 Subject: [PATCH 1023/1435] Update changelog for 1.6.1+ds-3 release --- debian/changelog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/debian/changelog b/debian/changelog index f1265ee32..ac046a5f4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +stlink (1.6.1+ds-3) unstable; urgency=medium + + * Add cross.patch to fix cross-compilation. Thanks Helmut! (Closes: + #973339) + + -- Luca Boccassi Thu, 29 Oct 2020 18:06:39 +0000 + stlink (1.6.1+ds-2) unstable; urgency=medium * Update d/copyright to remove GPL-2+ stanza about flashloaders From 504858566be82af996566795c41684b701b52ce1 Mon Sep 17 00:00:00 2001 From: anton Date: Sun, 1 Nov 2020 20:42:21 +0500 Subject: [PATCH 1024/1435] Improv MCU reseting --- src/stlink-lib/reg.h | 1 + src/stlink-lib/usb.c | 43 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 734107d6a..653852440 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -17,6 +17,7 @@ /* Debug Halting Control and Status Register */ #define STLINK_REG_DHCSR 0xe000edf0 #define STLINK_REG_DHCSR_DBGKEY 0xa05f0000 +#define STLINK_REG_DHCSR_S_RESET_ST 0x02000000 #define STLINK_REG_DCRSR 0xe000edf4 #define STLINK_REG_DCRDR 0xe000edf8 diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 9726ddc4a..6b914d805 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -508,9 +508,14 @@ int _stlink_usb_reset(stlink_t * sl) { 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); + uint32_t dhcsr; + int ret, i, rep_len = 2; + // clear S_RESET_ST in DHCSR registr + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + + // send reset command + i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; if (sl->version.jtag_api == STLINK_JTAG_API_V1) { @@ -526,9 +531,37 @@ int _stlink_usb_reset(stlink_t * sl) { return((int)size); } - // reset through AIRCR so that NRST does not need to be connected - return(stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | - STLINK_REG_AIRCR_SYSRESETREQ)); + usleep(10000); + + dhcsr = 0; + ret = stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + // reset not done yet + // try reset through AIRCR so that NRST does not need to be connected + + WLOG("NRST is not connected\n"); + DLOG("Using reset through SYSRESETREQ\n"); + ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | + STLINK_REG_AIRCR_SYSRESETREQ); + if (ret) + return(ret); + + usleep(10000); + } + + // waiting for a reset within 500ms + for (i=0; i<50; i++) { + // DDI0337E, p. 10-4, Debug Halting Control and Status Register + dhcsr = STLINK_REG_DHCSR_S_RESET_ST; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) + break; + usleep(10000); + } + + if (i >= 50) + return(-1); + return(0); } int _stlink_usb_jtag_reset(stlink_t * sl, int value) { From 4d07eb363dc9ca68936fd828d62340d8a9b558e3 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Mon, 2 Nov 2020 21:52:13 +0500 Subject: [PATCH 1025/1435] Split flash write function to optimize gdb flash loading --- inc/stlink.h | 4 + src/common.c | 382 +++++++++++++++++++++------------------ src/st-util/gdb-server.c | 28 ++- 3 files changed, 234 insertions(+), 180 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 39f5f283c..e78b9569f 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -303,6 +303,10 @@ int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_contr int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); +int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); +int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len); +int stlink_flashloader_stop(stlink_t *sl); + #include #include #include diff --git a/src/common.c b/src/common.c index c7f2883db..71caeeaa8 100644 --- a/src/common.c +++ b/src/common.c @@ -2669,151 +2669,140 @@ int stm32l1_write_half_pages( return(0); } -int stlink_write_flash( - stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len, uint8_t eraseonly) { - size_t off; - flash_loader_t fl; - ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr); - // check addr range is inside the flash - stlink_calculate_pagesize(sl, addr); - - if (addr < sl->flash_base) { - ELOG("addr too low %#x < %#x\n", addr, sl->flash_base); - return(-1); - } else if ((addr + len) < addr) { - ELOG("addr overruns\n"); - return(-1); - } else if ((addr + len) > (sl->flash_base + sl->flash_size)) { - ELOG("addr too high\n"); - return(-1); - } else if (addr & 1) { - ELOG("unaligned addr 0x%x\n", addr); - return(-1); - } else if (len & 1) { - WLOG("unaligned len 0x%x -- padding with zero\n", len); - len += 1; - } else if (addr & (sl->flash_pgsz - 1)) { - ELOG("addr not a multiple of current pagesize (%zd bytes), not supported, " - "check page start address and compare with flash module organisation " - "in related ST reference manual of your device.\n", sl->flash_pgsz); - return(-1); - } - - // make sure we've loaded the context with the chip details - stlink_core_id(sl); - - // Erase each page - int page_count = 0; - - for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + (uint32_t)off)) { - // addr must be an addr inside the page - if (stlink_erase_flash_page(sl, addr + (uint32_t)off) == -1) { - ELOG("Failed to erase_flash_page(%#zx) == -1\n", addr + off); - return(-1); - } - - ILOG("Flash page at addr: 0x%08lx erased\n", (unsigned long)(addr + off)); - page_count++; - } - - ILOG("Finished erasing %d pages of %d (%#x) bytes\n", - page_count, sl->flash_pgsz, sl->flash_pgsz); - - if (eraseonly) { return(0); } - +int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_F7) || (sl->flash_type == STLINK_FLASH_TYPE_L4)) { - // TODO: check write operation - ILOG("Starting Flash write for F2/F4/F7/L4\n"); + // Flash loader initialisation - if (stlink_flash_loader_init(sl, &fl) == -1) { + if (stlink_flash_loader_init(sl, fl) == -1) { ELOG("stlink_flash_loader_init() == -1\n"); return(-1); } unlock_flash_if(sl); // first unlock the cr - // TODO: Check that Voltage range is 2.7 - 3.6 V - if ((sl->chip_id != STLINK_CHIPID_STM32_L4) && - (sl->chip_id != STLINK_CHIPID_STM32_L43X) && - (sl->chip_id != STLINK_CHIPID_STM32_L46X) && - (sl->chip_id != STLINK_CHIPID_STM32_L496X) && - (sl->chip_id != STLINK_CHIPID_STM32_L4RX)) { + int voltage; + if (sl->version.stlink_v == 1) { + WLOG("STLINK V1 cannot read voltage, use default voltage 3.2V\n"); + voltage = 3200; + } else { + voltage = stlink_target_voltage(sl); + } + + if (voltage == -1) { + ELOG("Failed to read Target voltage\n"); + return(voltage); + } - if ( sl->version.stlink_v == 1) { - printf("STLINK V1 cannot read voltage, defaulting to 32-bit " - "writes on F4 devices\n"); + if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + // L4 does not have a byte-write mode + if (voltage < 1710) { + ELOG("Target voltage (%d mV) too low for flash writes!\n", voltage); + return(-1); + } + } else { + if (voltage > 2700) { + ILOG("enabling 32-bit flash writes\n"); write_flash_cr_psiz(sl, 2); } else { - // set parallelism to 32 bit - int voltage = stlink_target_voltage(sl); - - if (voltage == -1) { - printf("Failed to read Target voltage\n"); - return(voltage); - } else if (voltage > 2700) { - printf("enabling 32-bit flash writes\n"); - write_flash_cr_psiz(sl, 2); - } else { - printf("Target voltage (%d mV) too low for 32-bit flash, " - "using 8-bit flash writes\n", voltage); - write_flash_cr_psiz(sl, 0); - } + ILOG("Target voltage (%d mV) too low for 32-bit flash, " + "using 8-bit flash writes\n", voltage); + write_flash_cr_psiz(sl, 0); } + } + + // set programming mode + set_flash_cr_pg(sl); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + ILOG("Starting Flash write for WB/G0/G4\n"); + + wait_flash_busy(sl); + unlock_flash_if(sl); // unlock flash if necessary + set_flash_cr_pg(sl); // set PG 'allow programming' bit + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + ILOG("Starting Flash write for L0\n"); + + uint32_t val; + uint32_t flash_regs_base; + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || + sl->chip_id == STLINK_CHIPID_STM32_L011) { + flash_regs_base = STM32L0_FLASH_REGS_ADDR; } else { - // L4 does not have a byte-write mode - int voltage = stlink_target_voltage(sl); + flash_regs_base = STM32L_FLASH_REGS_ADDR; + } - if (voltage == -1) { - printf("Failed to read Target voltage\n"); - return(voltage); - } else if (voltage < 1710) { - printf("Target voltage (%d mV) too low for flash writes!\n", voltage); - return(-1); - } + // disable pecr protection + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY2); + + // check pecr.pelock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 0)) { + ELOG("pecr.pelock not clear\n"); + return(-1); } - // set programming mode - set_flash_cr_pg(sl); + // unlock program memory + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY2); - size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; + // check pecr.prglock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 1)) { + ELOG("pecr.prglock not clear\n"); + return(-1); + } + } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + ILOG("Starting Flash write for VL/F0/F3/F1_XL\n"); + + // flash loader initialisation + if (stlink_flash_loader_init(sl, fl) == -1) { + ELOG("stlink_flash_loader_init() == -1\n"); + return(-1); + } + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + ILOG("Starting Flash write for H7\n"); + + unlock_flash_if(sl); // unlock the cr + set_flash_cr_pg(sl); // set programming mode + } else { + ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); + return(-1); + } + return(0); +} + +int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, + uint8_t* base, uint32_t len) { + size_t off; + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + (sl->flash_type == STLINK_FLASH_TYPE_F7) || + (sl->flash_type == STLINK_FLASH_TYPE_L4)) { + size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; for (off = 0; off < len;) { size_t size = len - off > buf_size ? buf_size : len - off; - printf("size: %u\n", (unsigned int)size); - - if (stlink_flash_loader_run(sl, &fl, addr + (uint32_t)off, base + off, size) == -1) { + if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); return(-1); } off += size; } - - clear_flash_cr_pg(sl); - lock_flash(sl); - - // STM32F4END } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { - fprintf(stdout, "Writing\r\n"); - fflush(stdout); - wait_flash_busy(sl); - unlock_flash_if(sl); // unlock flash if necessary - set_flash_cr_pg(sl); // set PG 'allow programming' bit - // write all words. - off = 0; - fprintf(stdout, "Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); - fflush(stdout); - - for ( ; off < len; off += sizeof(uint32_t)) { + DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); + for (off = 0; off < len; off += sizeof(uint32_t)) { uint32_t data; - if (off > 254) { fprintf(stdout, "\r"); } - if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { fprintf(stdout, "\r%3u/%3u pages written", (unsigned int)(off / sl->flash_pgsz), @@ -2825,18 +2814,14 @@ int stlink_write_flash( stlink_write_debug32(sl, addr + (uint32_t)off, data); wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear } + fprintf(stdout, "\n"); // flash writes happen as 2 words at a time if ((off / sizeof(uint32_t)) % 2 != 0) { stlink_write_debug32(sl, addr + (uint32_t)off, 0); // write a single word of zeros wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear } - - clear_flash_cr_pg(sl); // reset PG bit. - lock_flash(sl); } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - // use fast word write - // TODO: half page uint32_t val; uint32_t flash_regs_base; uint32_t pagesize; @@ -2852,32 +2837,6 @@ int stlink_write_flash( pagesize = L1_WRITE_BLOCK_SIZE; } - // TODO: check write operation - - // disable pecr protection - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY2); - - // check pecr.pelock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - - if (val & (1 << 0)) { - fprintf(stderr, "pecr.pelock not clear\n"); - return(-1); - } - - // unlock program memory - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY2); - - // check pecr.prglock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - - if (val & (1 << 1)) { - fprintf(stderr, "pecr.prglock not clear\n"); - return(-1); - } - off = 0; if (len > pagesize) { @@ -2892,9 +2851,7 @@ int stlink_write_flash( // write remaining word in program memory for ( ; off < len; off += sizeof(uint32_t)) { uint32_t data; - - if (off > 254) { fprintf(stdout, "\r"); } - + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { fprintf(stdout, "\r%3u/%3u pages written", (unsigned int)(off / sl->flash_pgsz), @@ -2912,29 +2869,13 @@ int stlink_write_flash( // TODO: check redo write operation } - fprintf(stdout, "\n"); - // reset lock bits - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - ILOG("Starting Flash write for VL/F0/F3/F1_XL core id\n"); - - // flash loader initialisation - if (stlink_flash_loader_init(sl, &fl) == -1) { - ELOG("stlink_flash_loader_init() == -1\n"); - return(-1); - } - int write_block_count = 0; - for (off = 0; off < len; off += sl->flash_pgsz) { // adjust last write size - size_t size = sl->flash_pgsz; - - if ((off + sl->flash_pgsz) > len) { size = len - off; } + size_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; // unlock and set programming mode unlock_flash_if(sl); @@ -2943,7 +2884,7 @@ int stlink_write_flash( DLOG("Finished unlocking flash, running loader!\n"); - if (stlink_flash_loader_run(sl, &fl, addr + (uint32_t)off, base + off, size) == -1) { + if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); return(-1); } @@ -2952,19 +2893,15 @@ int stlink_write_flash( if (sl->verbose >= 1) { // show progress; writing procedure is slow and previous errors are misleading - fprintf(stdout, "\r%3u/%lu pages written", ++write_block_count, - (unsigned long)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); + fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, + (unsigned int)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); fflush(stdout); } } - - fprintf(stdout, "\n"); + if (sl->verbose >= 1) { + fprintf(stdout, "\n"); + } } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - ILOG("Starting Flash write for H7 core id\n"); - - unlock_flash_if(sl); // unlock the cr - set_flash_cr_pg(sl); // set programming mode - for (off = 0; off < len;) { // Program STM32H7x with 32-byte Flash words size_t chunk = (len - off > 32) ? 32 : len - off; @@ -2980,15 +2917,110 @@ int stlink_write_flash( fflush(stdout); } } - fprintf(stdout, "\n"); + if (sl->verbose >= 1) { + fprintf(stdout, "\n"); + } + } else { + return(-1); + } + + return(0); +} + +int stlink_flashloader_stop(stlink_t *sl) { + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + (sl->flash_type == STLINK_FLASH_TYPE_F7) || + (sl->flash_type == STLINK_FLASH_TYPE_L4) || + (sl->flash_type == STLINK_FLASH_TYPE_WB) || + (sl->flash_type == STLINK_FLASH_TYPE_G0) || + (sl->flash_type == STLINK_FLASH_TYPE_G4) || + (sl->flash_type == STLINK_FLASH_TYPE_H7)) { clear_flash_cr_pg(sl); lock_flash(sl); - } else { - ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + uint32_t val; + uint32_t flash_regs_base; + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || + sl->chip_id == STLINK_CHIPID_STM32_L011) { + flash_regs_base = STM32L0_FLASH_REGS_ADDR; + } else { + flash_regs_base = STM32L_FLASH_REGS_ADDR; + } + // reset lock bits + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + } + + return(0); +} + +int stlink_write_flash( + stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len, uint8_t eraseonly) { + size_t off; + int ret; + flash_loader_t fl; + ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr); + // check addr range is inside the flash + stlink_calculate_pagesize(sl, addr); + + if (addr < sl->flash_base) { + ELOG("addr too low %#x < %#x\n", addr, sl->flash_base); + return(-1); + } else if ((addr + len) < addr) { + ELOG("addr overruns\n"); + return(-1); + } else if ((addr + len) > (sl->flash_base + sl->flash_size)) { + ELOG("addr too high\n"); + return(-1); + } else if (addr & 1) { + ELOG("unaligned addr 0x%x\n", addr); return(-1); + } else if (len & 1) { + WLOG("unaligned len 0x%x -- padding with zero\n", len); + len += 1; + } else if (addr & (sl->flash_pgsz - 1)) { + ELOG("addr not a multiple of current pagesize (%zd bytes), not supported, " + "check page start address and compare with flash module organisation " + "in related ST reference manual of your device.\n", sl->flash_pgsz); + return(-1); + } + + // make sure we've loaded the context with the chip details + stlink_core_id(sl); + + // Erase each page + int page_count = 0; + + for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + (uint32_t)off)) { + // addr must be an addr inside the page + if (stlink_erase_flash_page(sl, addr + (uint32_t)off) == -1) { + ELOG("Failed to erase_flash_page(%#zx) == -1\n", addr + off); + return(-1); + } + + ILOG("Flash page at addr: 0x%08lx erased\n", (unsigned long)(addr + off)); + page_count++; } + ILOG("Finished erasing %d pages of %d (%#x) bytes\n", + page_count, sl->flash_pgsz, sl->flash_pgsz); + + if (eraseonly) { return(0); } + + ret = stlink_flashloader_start(sl, &fl); + if (ret) + return ret; + ret = stlink_flashloader_write(sl, &fl, addr, base, len); + if (ret) + return ret; + ret = stlink_flashloader_stop(sl); + if (ret) + return ret; + return(stlink_verify_write_flash(sl, addr, base, len)); } diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index c832098f1..5e8a2549e 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -847,13 +847,31 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { static int flash_go(stlink_t *sl) { int error = -1; - + int ret; + flash_loader_t fl; + // some kinds of clock settings do not allow writing to flash. stlink_reset(sl); stlink_force_debug(sl); for (struct flash_block* fb = flash_root; fb; fb = fb->next) { - DLOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length); + ILOG("flash_erase: block %08x -> %04x\n", fb->addr, fb->length); + + for (stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += (uint32_t)FLASH_PAGE) { + // update FLASH_PAGE + stlink_calculate_pagesize(sl, page); + + ILOG("flash_erase: page %08x\n", page); + ret = stlink_erase_flash_page(sl, page); + if (ret < 0) { goto error; } + } + } + + ret = stlink_flashloader_start(sl, &fl); + if (ret < 0) { goto error; } + + for (struct flash_block* fb = flash_root; fb; fb = fb->next) { + ILOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length); for (stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += (uint32_t)FLASH_PAGE) { unsigned length = fb->length - (page - fb->addr); @@ -861,14 +879,14 @@ static int flash_go(stlink_t *sl) { // update FLASH_PAGE stlink_calculate_pagesize(sl, page); - DLOG("flash_do: page %08x\n", page); + ILOG("flash_do: page %08x\n", page); unsigned len = (length > FLASH_PAGE) ? (unsigned int)FLASH_PAGE : length; - int ret = stlink_write_flash(sl, page, fb->data + (page - fb->addr), len, 0); - + ret = stlink_flashloader_write(sl, &fl, page, fb->data + (page - fb->addr), len); if (ret < 0) { goto error; } } } + stlink_flashloader_stop(sl); stlink_reset(sl); error = 0; From a7ea06d7d9b44e9033de68980b4ae2816b13a435 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Tue, 3 Nov 2020 10:23:07 +0500 Subject: [PATCH 1026/1435] Remove duplicate register definitions --- inc/stlink.h | 19 ------------------- src/stlink-lib/reg.h | 13 +++++++++++-- src/stlink-lib/usb.c | 8 ++++---- 3 files changed, 15 insertions(+), 25 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index e78b9569f..c4466b10b 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -83,25 +83,6 @@ enum target_state { #define STLINK_V3_MAX_FREQ_NB 10 -/* Cortex Debug Control Block */ -#define DCB_DHCSR 0xE000EDF0 -#define DCB_DCRSR 0xE000EDF4 -#define DCB_DCRDR 0xE000EDF8 -#define DCB_DEMCR 0xE000EDFC - -/* DCB_DHCSR bit and field definitions */ -#define DBGKEY (0xA05F << 16) -#define C_DEBUGEN (1 << 0) -#define C_HALT (1 << 1) -#define C_STEP (1 << 2) -#define C_MASKINTS (1 << 3) -#define S_REGRDY (1 << 16) -#define S_HALT (1 << 17) -#define S_SLEEP (1 << 18) -#define S_LOCKUP (1 << 19) -#define S_RETIRE_ST (1 << 24) -#define S_RESET_ST (1 << 25) - /* Map the relevant features, quirks and workaround for specific firmware version of stlink */ #define STLINK_F_HAS_TRACE (1 << 0) #define STLINK_F_HAS_SWD_SET_FREQ (1 << 1) diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 653852440..926480648 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -16,8 +16,17 @@ /* Cortex™-M3 Technical Reference Manual */ /* Debug Halting Control and Status Register */ #define STLINK_REG_DHCSR 0xe000edf0 -#define STLINK_REG_DHCSR_DBGKEY 0xa05f0000 -#define STLINK_REG_DHCSR_S_RESET_ST 0x02000000 +#define STLINK_REG_DHCSR_DBGKEY (0xA05F << 16) +#define STLINK_REG_DHCSR_C_DEBUGEN (1 << 0) +#define STLINK_REG_DHCSR_C_HALT (1 << 1) +#define STLINK_REG_DHCSR_C_STEP (1 << 2) +#define STLINK_REG_DHCSR_C_MASKINTS (1 << 3) +#define STLINK_REG_DHCSR_S_REGRDY (1 << 16) +#define STLINK_REG_DHCSR_S_HALT (1 << 17) +#define STLINK_REG_DHCSR_S_SLEEP (1 << 18) +#define STLINK_REG_DHCSR_S_LOCKUP (1 << 19) +#define STLINK_REG_DHCSR_S_RETIRE_ST (1 << 24) +#define STLINK_REG_DHCSR_S_RESET_ST (1 << 25) #define STLINK_REG_DCRSR 0xe000edf4 #define STLINK_REG_DCRDR 0xe000edf8 diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 6b914d805..4e805a709 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -385,15 +385,15 @@ int _stlink_usb_status_v2(stlink_t *sl) { int result; uint32_t status = 0; - result = _stlink_usb_read_debug32(sl, DCB_DHCSR, &status); + result = _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &status); DLOG("core status: %08X\n", status); if (result != 0) { sl->core_stat = TARGET_UNKNOWN; } else { - if (status & S_HALT) { + if (status & STLINK_REG_DHCSR_C_HALT) { sl->core_stat = TARGET_HALTED; - } else if (status & S_RESET_ST) { + } else if (status & STLINK_REG_DHCSR_S_RESET_ST) { sl->core_stat = TARGET_RESET; } else { sl->core_stat = TARGET_RUNNING; @@ -616,7 +616,7 @@ int _stlink_usb_run(stlink_t* sl) { int res; if (sl->version.jtag_api != STLINK_JTAG_API_V1) { - res = _stlink_usb_write_debug32(sl, DCB_DHCSR, DBGKEY | C_DEBUGEN); + res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN); return(res); } From 922eba585b47d7ce5814a83fd96409c98acd9e6b Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Tue, 3 Nov 2020 12:19:47 +0500 Subject: [PATCH 1027/1435] Optimized timeout of the chip reset function --- CMakeLists.txt | 12 ++++++++++++ src/stlink-lib/helper.c | 13 +++++++++++++ src/stlink-lib/helper.h | 6 ++++++ src/stlink-lib/usb.c | 21 ++++++++++----------- src/win32/sys_time.c | 20 ++++++++++++++++++++ src/win32/sys_time.h | 30 ++++++++++++++++++++++++++++++ 6 files changed, 91 insertions(+), 11 deletions(-) create mode 100644 src/stlink-lib/helper.c create mode 100644 src/stlink-lib/helper.h create mode 100644 src/win32/sys_time.c create mode 100644 src/win32/sys_time.h diff --git a/CMakeLists.txt b/CMakeLists.txt index fae458dd7..4ab43271e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,6 +60,11 @@ if (STLINK_HAVE_SYS_MMAN_H) add_definitions(-DSTLINK_HAVE_SYS_MMAN_H) endif() +CHECK_INCLUDE_FILE(sys/time.h STLINK_HAVE_SYS_TIME_H) +if (STLINK_HAVE_SYS_TIME_H) + add_definitions(-DSTLINK_HAVE_SYS_TIME_H) +endif() + CHECK_INCLUDE_FILE(unistd.h STLINK_HAVE_UNISTD_H) if (STLINK_HAVE_UNISTD_H) add_definitions(-DSTLINK_HAVE_UNISTD_H) @@ -104,6 +109,7 @@ set(STLINK_HEADERS src/stlink-lib/md5.h src/stlink-lib/sg.h src/stlink-lib/usb.h + src/stlink-lib/helper.h ) set(STLINK_SOURCE @@ -114,6 +120,7 @@ set(STLINK_SOURCE src/stlink-lib/md5.c src/stlink-lib/sg.c src/stlink-lib/usb.c + src/stlink-lib/helper.c ) if (WIN32) @@ -132,6 +139,11 @@ if (WIN32) set(STLINK_SOURCE "${STLINK_SOURCE};src/win32/mmap.c") set(STLINK_HEADERS "${STLINK_HEADERS};src/win32/mmap.h") endif() + + if (NOT STLINK_HAVE_SYS_TIME_H) + set(STLINK_SOURCE "${STLINK_SOURCE};src/win32/sys_time.c") + set(STLINK_HEADERS "${STLINK_HEADERS};src/win32/sys_time.h") + endif() endif () ## Include test execution for test-targets for target Debug diff --git a/src/stlink-lib/helper.c b/src/stlink-lib/helper.c new file mode 100644 index 000000000..50c55230b --- /dev/null +++ b/src/stlink-lib/helper.c @@ -0,0 +1,13 @@ +#include + +#ifdef STLINK_HAVE_SYS_TIME_H +#include +#else +#include +#endif + +unsigned time_ms() { + struct timeval tv; + gettimeofday(&tv, NULL); + return (unsigned)tv.tv_sec * 1000 + tv.tv_usec / 1000; +} diff --git a/src/stlink-lib/helper.h b/src/stlink-lib/helper.h new file mode 100644 index 000000000..defd0504b --- /dev/null +++ b/src/stlink-lib/helper.h @@ -0,0 +1,6 @@ +#ifndef SYS_HELPER_H +#define SYS_HELPER_H + +unsigned time_ms(); + +#endif SYS_HELPER_H diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 4e805a709..b502ca2a6 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -17,6 +17,7 @@ #endif #include +#include #include "usb.h" enum SCSI_Generic_Direction {SG_DXFER_TO_DEV = 0, SG_DXFER_FROM_DEV = 0x80}; @@ -509,10 +510,10 @@ int _stlink_usb_reset(stlink_t * sl) { unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t dhcsr; - int ret, i, rep_len = 2; + int ret, timeout, i, rep_len = 2; // clear S_RESET_ST in DHCSR registr - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); // send reset command i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); @@ -534,14 +535,14 @@ int _stlink_usb_reset(stlink_t * sl) { usleep(10000); dhcsr = 0; - ret = stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + ret = _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { // reset not done yet // try reset through AIRCR so that NRST does not need to be connected WLOG("NRST is not connected\n"); DLOG("Using reset through SYSRESETREQ\n"); - ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | + ret = _stlink_usb_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | STLINK_REG_AIRCR_SYSRESETREQ); if (ret) return(ret); @@ -550,18 +551,16 @@ int _stlink_usb_reset(stlink_t * sl) { } // waiting for a reset within 500ms - for (i=0; i<50; i++) { + timeout = time_ms() + 500; + while (time_ms() < timeout) { // DDI0337E, p. 10-4, Debug Halting Control and Status Register dhcsr = STLINK_REG_DHCSR_S_RESET_ST; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) - break; - usleep(10000); + return(0); } - if (i >= 50) - return(-1); - return(0); + return(-1); } int _stlink_usb_jtag_reset(stlink_t * sl, int value) { diff --git a/src/win32/sys_time.c b/src/win32/sys_time.c new file mode 100644 index 000000000..ea7c25dda --- /dev/null +++ b/src/win32/sys_time.c @@ -0,0 +1,20 @@ +#include +#include + +#include "sys_time.h" + +/* Simple gettimeofday implementation without converting Windows time to Linux time */ +int gettimeofday(struct timeval *tv, struct timezone *tz) { + FILETIME ftime; + ULARGE_INTEGER ulint; + + GetSystemTimeAsFileTime(&ftime); + ulint.LowPart = ftime.dwLowDateTime; + ulint.HighPart = ftime.dwHighDateTime; + + tv->tv_sec = (long)(ulint.QuadPart / 10000000L); + tv->tv_usec = (long)(ulint.QuadPart % 10000000L); + + return 0; + (void)tz; +} diff --git a/src/win32/sys_time.h b/src/win32/sys_time.h new file mode 100644 index 000000000..87c3a42fd --- /dev/null +++ b/src/win32/sys_time.h @@ -0,0 +1,30 @@ +#ifndef STLINK_TIME_H +#define STLINK_TIME_H + +#ifdef STLINK_HAVE_SYS_TIME_H +#include +#else + +struct timeval { + long tv_sec; + long tv_usec; +}; + +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int gettimeofday(struct timeval *tv, struct timezone *tz); + +#ifdef __cplusplus +} +#endif + +#endif /* STLINK_HAVE_SYS_TIME_H */ + +#endif /* STLINK_TIME_H */ From ddd39354b545f6176345cce8f2d520bd109dcbe7 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Tue, 3 Nov 2020 14:49:19 +0500 Subject: [PATCH 1028/1435] Trying to use a soft reset before starting debugging --- inc/stlink.h | 1 + src/common.c | 50 ++++++++++++++++++++++++++++++++++++---- src/st-util/gdb-server.c | 13 +++++++---- src/stlink-lib/reg.h | 2 ++ 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index c4466b10b..2ec2db367 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -223,6 +223,7 @@ void stlink_close(stlink_t *sl); int stlink_core_id(stlink_t *sl); int stlink_reset(stlink_t *sl); int stlink_jtag_reset(stlink_t *sl, int value); +int stlink_soft_reset(stlink_t *sl, int halt_on_reset); int stlink_run(stlink_t *sl); int stlink_status(stlink_t *sl); int stlink_version(stlink_t *sl); diff --git a/src/common.c b/src/common.c index 71caeeaa8..ed3f7b222 100644 --- a/src/common.c +++ b/src/common.c @@ -1416,6 +1416,48 @@ int stlink_jtag_reset(stlink_t *sl, int value) { return(sl->backend->jtag_reset(sl, value)); } +int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { + int ret; + uint32_t dhcsr, demcr; + + DLOG("*** stlink_soft_reset ***\n"); + + // halt core and enable debugging (if not already done) + // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) + _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | + STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_DEBUGEN); + + // enable Halt on reset by set VC_CORERESET and TRCENA (DDI0337E, p. 10-10) + stlink_read_debug32(sl, STLINK_REG_CM3_DEMCR, &demcr); + if (halt_on_reset) { + demcr |= STLINK_REG_CM3_DEMCR_TRCENA | STLINK_REG_CM3_DEMCR_VC_CORERESET; + } else { + demcr &= ~STLINK_REG_CM3_DEMCR_VC_CORERESET; + } + stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, demcr); + + // clear S_RESET_ST in DHCSR register + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + + // soft reset (core reset) by SYSRESETREQ (DDI0337E, p. 8-23) + ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | + STLINK_REG_AIRCR_SYSRESETREQ); + if (ret) + return(ret); + + // waiting for a reset within 500ms + timeout = time_ms() + 500; + while (time_ms() < timeout) { + // DDI0337E, p. 10-4, Debug Halting Control and Status Register + dhcsr = STLINK_REG_DHCSR_S_RESET_ST; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) + return(0); + } + + return(-1); +} + int stlink_run(stlink_t *sl) { DLOG("*** stlink_run ***\n"); return(sl->backend->run(sl)); @@ -2899,8 +2941,8 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr } } if (sl->verbose >= 1) { - fprintf(stdout, "\n"); - } + fprintf(stdout, "\n"); + } } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { for (off = 0; off < len;) { // Program STM32H7x with 32-byte Flash words @@ -2918,8 +2960,8 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr } } if (sl->verbose >= 1) { - fprintf(stdout, "\n"); - } + fprintf(stdout, "\n"); + } } else { return(-1); } diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 5e8a2549e..4eca5819e 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -591,9 +591,9 @@ static void init_data_watchpoints(stlink_t *sl) { uint32_t data; DLOG("init watchpoints\n"); + // set TRCENA in debug command to turn on DWT unit stlink_read_debug32(sl, STLINK_REG_CM3_DEMCR, &data); - data |= 1 << 24; - // set TRCENA in debug command to turn on DWT unit + data |= STLINK_REG_CM3_DEMCR_TRCENA; stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, data); // make sure all watchpoints are cleared @@ -887,7 +887,7 @@ static int flash_go(stlink_t *sl) { } stlink_flashloader_stop(sl); - stlink_reset(sl); + //stlink_reset(sl); error = 0; error: @@ -1804,13 +1804,16 @@ int serve(stlink_t *sl, st_state_t *st) { case 'R': { // reset the core. - ret = stlink_reset(sl); - + ret = stlink_soft_reset(sl, 1 /* halt on reset */); if (ret) { DLOG("R packet : stlink_reset failed\n"); } init_code_breakpoints(sl); init_data_watchpoints(sl); + if (stlink_status(sl) == TARGET_HALTED) { + stlink_run(sl); + } + attached = 1; reply = strdup("OK"); diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 926480648..d9323a042 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -9,6 +9,8 @@ #define STLINK_REG_CM7_FP_LAR_KEY 0xC5ACCE55 #define STLINK_REG_CM3_DEMCR 0xE000EDFC +#define STLINK_REG_CM3_DEMCR_TRCENA (1 << 24) +#define STLINK_REG_CM3_DEMCR_VC_CORERESET (1 << 0) #define STLINK_REG_CM3_DWT_COMPn(n) (0xE0001020 + n*16) #define STLINK_REG_CM3_DWT_MASKn(n) (0xE0001024 + n*16) #define STLINK_REG_CM3_DWT_FUNn(n) (0xE0001028 + n*16) From b401eaff9a144f973f44f5914a70fc82da36d39f Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Thu, 5 Nov 2020 16:57:30 +0500 Subject: [PATCH 1029/1435] Improve soft reset with core halt --- src/common.c | 58 +++++++++++++++++++++++++++++----------- src/st-util/gdb-server.c | 22 +++++++-------- src/stlink-lib/helper.c | 2 ++ src/stlink-lib/helper.h | 2 +- src/stlink-lib/reg.h | 13 +++++++-- src/stlink-lib/usb.c | 14 ++++------ 6 files changed, 71 insertions(+), 40 deletions(-) diff --git a/src/common.c b/src/common.c index ed3f7b222..cdf0fa497 100644 --- a/src/common.c +++ b/src/common.c @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef STLINK_HAVE_SYS_MMAN_H #include @@ -1418,44 +1419,71 @@ int stlink_jtag_reset(stlink_t *sl, int value) { int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { int ret; - uint32_t dhcsr, demcr; + unsigned timeout; + uint32_t dhcsr, dfsr; - DLOG("*** stlink_soft_reset ***\n"); + ELOG("*** stlink_soft_reset %s***\n", halt_on_reset?"(halt) ":""); // halt core and enable debugging (if not already done) // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) - _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | + stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_DEBUGEN); - + // enable Halt on reset by set VC_CORERESET and TRCENA (DDI0337E, p. 10-10) - stlink_read_debug32(sl, STLINK_REG_CM3_DEMCR, &demcr); if (halt_on_reset) { - demcr |= STLINK_REG_CM3_DEMCR_TRCENA | STLINK_REG_CM3_DEMCR_VC_CORERESET; + stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, STLINK_REG_CM3_DEMCR_TRCENA | + STLINK_REG_CM3_DEMCR_VC_HARDERR | STLINK_REG_CM3_DEMCR_VC_BUSERR | + STLINK_REG_CM3_DEMCR_VC_CORERESET); + + // clear VCATCH in the DFSR register + stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_VCATCH); } else { - demcr &= ~STLINK_REG_CM3_DEMCR_VC_CORERESET; + stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, STLINK_REG_CM3_DEMCR_TRCENA | + STLINK_REG_CM3_DEMCR_VC_HARDERR | STLINK_REG_CM3_DEMCR_VC_BUSERR); } - stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, demcr); - // clear S_RESET_ST in DHCSR register + // clear S_RESET_ST in the DHCSR register stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - + // soft reset (core reset) by SYSRESETREQ (DDI0337E, p. 8-23) ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | STLINK_REG_AIRCR_SYSRESETREQ); - if (ret) + if (ret) { + ELOG("Soft reset failed: error write to AIRCR\n"); return(ret); + } // waiting for a reset within 500ms + // DDI0337E, p. 10-4, Debug Halting Control and Status Register timeout = time_ms() + 500; while (time_ms() < timeout) { // DDI0337E, p. 10-4, Debug Halting Control and Status Register dhcsr = STLINK_REG_DHCSR_S_RESET_ST; stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) - return(0); + if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) { + if (halt_on_reset) { + // waiting halt by the SYSRESETREQ exception + // DDI0403E, p. C1-699, Debug Fault Status Register + dfsr = 0; + stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); + if ((dfsr&STLINK_REG_DFSR_VCATCH) == 0) { + continue; + } + } + timeout = 0; + break; + } } - return(-1); + // reset DFSR register. DFSR is power-on reset only (DDI0337H, p. 7-5) + stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_CLEAR); + + if (timeout) { + ELOG("Soft reset failed: timeout\n"); + return(-1); + } + + return(0); } int stlink_run(stlink_t *sl) { @@ -2735,7 +2763,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { if (voltage == -1) { ELOG("Failed to read Target voltage\n"); - return(voltage); + return(-1); } if (sl->flash_type == STLINK_FLASH_TYPE_L4) { diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 4eca5819e..d69ac0626 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -591,7 +591,7 @@ static void init_data_watchpoints(stlink_t *sl) { uint32_t data; DLOG("init watchpoints\n"); - // set TRCENA in debug command to turn on DWT unit + // set TRCENA in debug command to turn on DWT unit stlink_read_debug32(sl, STLINK_REG_CM3_DEMCR, &data); data |= STLINK_REG_CM3_DEMCR_TRCENA; stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, data); @@ -849,7 +849,7 @@ static int flash_go(stlink_t *sl) { int error = -1; int ret; flash_loader_t fl; - + // some kinds of clock settings do not allow writing to flash. stlink_reset(sl); stlink_force_debug(sl); @@ -863,12 +863,12 @@ static int flash_go(stlink_t *sl) { ILOG("flash_erase: page %08x\n", page); ret = stlink_erase_flash_page(sl, page); - if (ret < 0) { goto error; } + if (ret) { goto error; } } } ret = stlink_flashloader_start(sl, &fl); - if (ret < 0) { goto error; } + if (ret) { goto error; } for (struct flash_block* fb = flash_root; fb; fb = fb->next) { ILOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length); @@ -882,12 +882,12 @@ static int flash_go(stlink_t *sl) { ILOG("flash_do: page %08x\n", page); unsigned len = (length > FLASH_PAGE) ? (unsigned int)FLASH_PAGE : length; ret = stlink_flashloader_write(sl, &fl, page, fb->data + (page - fb->addr), len); - if (ret < 0) { goto error; } + if (ret) { goto error; } } } stlink_flashloader_stop(sl); - //stlink_reset(sl); + stlink_soft_reset(sl, 1 /* halt on reset */); error = 0; error: @@ -1390,8 +1390,8 @@ int serve(stlink_t *sl, st_state_t *st) { free(decoded); } else if (!strcmp(cmdName, "FlashDone")) { - if (flash_go(sl) < 0) { - reply = strdup("E00"); + if (flash_go(sl)) { + reply = strdup("E08"); } else { reply = strdup("OK"); } @@ -1804,16 +1804,12 @@ int serve(stlink_t *sl, st_state_t *st) { case 'R': { // reset the core. - ret = stlink_soft_reset(sl, 1 /* halt on reset */); + ret = stlink_reset(sl); if (ret) { DLOG("R packet : stlink_reset failed\n"); } init_code_breakpoints(sl); init_data_watchpoints(sl); - if (stlink_status(sl) == TARGET_HALTED) { - stlink_run(sl); - } - attached = 1; reply = strdup("OK"); diff --git a/src/stlink-lib/helper.c b/src/stlink-lib/helper.c index 50c55230b..8b2c8e8f7 100644 --- a/src/stlink-lib/helper.c +++ b/src/stlink-lib/helper.c @@ -1,5 +1,7 @@ #include +#include + #ifdef STLINK_HAVE_SYS_TIME_H #include #else diff --git a/src/stlink-lib/helper.h b/src/stlink-lib/helper.h index defd0504b..12c2ea2a7 100644 --- a/src/stlink-lib/helper.h +++ b/src/stlink-lib/helper.h @@ -3,4 +3,4 @@ unsigned time_ms(); -#endif SYS_HELPER_H +#endif /* SYS_HELPER_H */ diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index d9323a042..2e93dc5b1 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -10,6 +10,8 @@ #define STLINK_REG_CM3_DEMCR 0xE000EDFC #define STLINK_REG_CM3_DEMCR_TRCENA (1 << 24) +#define STLINK_REG_CM3_DEMCR_VC_HARDERR (1 << 10) +#define STLINK_REG_CM3_DEMCR_VC_BUSERR (1 << 8) #define STLINK_REG_CM3_DEMCR_VC_CORERESET (1 << 0) #define STLINK_REG_CM3_DWT_COMPn(n) (0xE0001020 + n*16) #define STLINK_REG_CM3_DWT_MASKn(n) (0xE0001024 + n*16) @@ -17,6 +19,12 @@ /* Cortex™-M3 Technical Reference Manual */ /* Debug Halting Control and Status Register */ +#define STLINK_REG_DFSR 0xE000ED30 +#define STLINK_REG_DFSR_HALT (1 << 0) +#define STLINK_REG_DFSR_BKPT (1 << 1) +#define STLINK_REG_DFSR_VCATCH (1 << 3) +#define STLINK_REG_DFSR_EXTERNAL (1 << 4) +#define STLINK_REG_DFSR_CLEAR 0x0000001F #define STLINK_REG_DHCSR 0xe000edf0 #define STLINK_REG_DHCSR_DBGKEY (0xA05F << 16) #define STLINK_REG_DHCSR_C_DEBUGEN (1 << 0) @@ -34,8 +42,9 @@ /* Application Interrupt and Reset Control Register */ #define STLINK_REG_AIRCR 0xe000ed0c -#define STLINK_REG_AIRCR_VECTKEY 0x05fa0000 -#define STLINK_REG_AIRCR_SYSRESETREQ 0x00000004 +#define STLINK_REG_AIRCR_VECTKEY 0x05fa0000 +#define STLINK_REG_AIRCR_SYSRESETREQ 0x00000004 +#define STLINK_REG_AIRCR_VECTRESET 0x00000001 /* ARM Cortex-M7 Processor Technical Reference Manual */ /* Cache Control and Status Register */ diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index b502ca2a6..7909a4e69 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -510,7 +510,8 @@ int _stlink_usb_reset(stlink_t * sl) { unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t dhcsr; - int ret, timeout, i, rep_len = 2; + unsigned timeout; + int i, rep_len = 2; // clear S_RESET_ST in DHCSR registr _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); @@ -535,19 +536,14 @@ int _stlink_usb_reset(stlink_t * sl) { usleep(10000); dhcsr = 0; - ret = _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { // reset not done yet // try reset through AIRCR so that NRST does not need to be connected - + WLOG("NRST is not connected\n"); DLOG("Using reset through SYSRESETREQ\n"); - ret = _stlink_usb_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | - STLINK_REG_AIRCR_SYSRESETREQ); - if (ret) - return(ret); - - usleep(10000); + return stlink_soft_reset(sl, 0); } // waiting for a reset within 500ms From 85f0e939111d7350bdd40746161da7ef656d5151 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Thu, 5 Nov 2020 17:00:48 +0500 Subject: [PATCH 1030/1435] Add switch to Thumb mode before starting flash loader --- src/stlink-lib/flash_loader.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 7de485ca3..c86aefbf7 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -316,6 +316,8 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe int i = 0; size_t count = 0; uint32_t flash_base = 0; + const char *error = NULL; + uint32_t dhcsr, dfsr; DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); @@ -354,6 +356,13 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe // only used on VL/F1_XL, but harmless for others stlink_write_reg(sl, fl->loader_addr, 15); // pc register + /* Make sure we are in Thumb mode */ + stlink_read_reg(sl, 16, &rr); + if ((rr.xpsr & (1 << 24)) == 0) { + ILOG("Go to Thumb mode\n"); + stlink_write_reg(sl, rr.xpsr | (1 << 24), 16); + } + /* Run loader */ stlink_run(sl); @@ -376,17 +385,26 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe } if (i >= WAIT_ROUNDS) { - ELOG("flash loader run error\n"); - return(-1); + error = "Flash loader run error"; + goto error; } // check written byte count stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { - ELOG("write error, count == %u\n", rr.r[2]); - return(-1); + error = "Write error"; + goto error; } return(0); + +error: + dhcsr = dfsr = 0; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); + stlink_read_all_regs(sl, &rr); + ELOG("%s (R2 0x%08X R15 0x%08X DHCSR 0x%08X DFSR 0x%08X)\n", error, rr.r[2], rr.r[15], dhcsr, dfsr); + + return(-1); } From 0135a0ea162e72a6d15de768140522078bb6bf81 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Thu, 5 Nov 2020 18:50:10 +0500 Subject: [PATCH 1031/1435] Expand and simplify stlink V2 + support --- src/stlink-lib/usb.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 7909a4e69..92ad4cbc5 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -262,7 +262,7 @@ int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { } int _stlink_usb_get_rw_status(stlink_t *sl) { - if (sl->version.jtag_api == STLINK_JTAG_API_V1) { return(-1); } + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { return(0); } unsigned char* const rdata = sl->q_buf; struct stlink_libusb * const slu = sl->backend_data; @@ -355,15 +355,17 @@ int _stlink_usb_core_id(stlink_t * sl) { unsigned char* const cmd = sl->c_buf; unsigned char* const data = sl->q_buf; ssize_t size; - int rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 12; + int offset, rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 12; int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; if (sl->version.jtag_api == STLINK_JTAG_API_V1) { cmd[i++] = STLINK_DEBUG_READCOREID; + offset = 0; } else { cmd[i++] = STLINK_DEBUG_APIV2_READ_IDCODES; + offset = 4; } size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); @@ -373,11 +375,7 @@ int _stlink_usb_core_id(stlink_t * sl) { return(-1); } - if (sl->version.jtag_api == STLINK_JTAG_API_V1) { - sl->core_id = read_uint32(data, 0); - } else { - sl->core_id = read_uint32(data, 4); - } + sl->core_id = read_uint32(data, offset); return(0); } @@ -440,6 +438,14 @@ int _stlink_usb_status(stlink_t * sl) { int _stlink_usb_force_debug(stlink_t *sl) { struct stlink_libusb *slu = sl->backend_data; + + int res; + + if (sl->version.jtag_api != STLINK_JTAG_API_V1) { + res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_DEBUGEN); + return(res); + } + unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; @@ -583,6 +589,17 @@ int _stlink_usb_jtag_reset(stlink_t * sl, int value) { int _stlink_usb_step(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; + + if (sl->version.jtag_api != STLINK_JTAG_API_V1) { + // emulates the JTAG v1 API by using DHCSR + _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_MASKINTS | STLINK_REG_DHCSR_C_DEBUGEN); + _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_STEP | + STLINK_REG_DHCSR_C_MASKINTS | STLINK_REG_DHCSR_C_DEBUGEN); + return _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_DEBUGEN); + } + unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; @@ -792,11 +809,11 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { if (sl->verbose < 2) { return(0); } - DLOG("xpsr = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 64)); - DLOG("main_sp = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 68)); - DLOG("process_sp = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 72)); - DLOG("rw = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 76)); - DLOG("rw2 = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 80)); + DLOG("xpsr = 0x%08x\n", regp->xpsr); + DLOG("main_sp = 0x%08x\n", regp->main_sp); + DLOG("process_sp = 0x%08x\n", regp->process_sp); + DLOG("rw = 0x%08x\n", regp->rw); + DLOG("rw2 = 0x%08x\n", regp->rw2); return(0); } From f3c824c83e10548b89513b12f55f113452259a97 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Thu, 5 Nov 2020 18:54:03 +0500 Subject: [PATCH 1032/1435] More robust fw flash by gdb --- src/common.c | 2 +- src/st-util/gdb-server.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index cdf0fa497..89f27aa66 100644 --- a/src/common.c +++ b/src/common.c @@ -1422,7 +1422,7 @@ int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { unsigned timeout; uint32_t dhcsr, dfsr; - ELOG("*** stlink_soft_reset %s***\n", halt_on_reset?"(halt) ":""); + DLOG("*** stlink_soft_reset %s***\n", halt_on_reset?"(halt) ":""); // halt core and enable debugging (if not already done) // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index d69ac0626..63ba68fcf 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -853,6 +853,8 @@ static int flash_go(stlink_t *sl) { // some kinds of clock settings do not allow writing to flash. stlink_reset(sl); stlink_force_debug(sl); + // delay to ensure that STM32 HSI clock and others have started up fully + usleep(10000); for (struct flash_block* fb = flash_root; fb; fb = fb->next) { ILOG("flash_erase: block %08x -> %04x\n", fb->addr, fb->length); From 43019fcde99b8e745a767b8e2c307d5868c09878 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Thu, 5 Nov 2020 19:34:22 +0500 Subject: [PATCH 1033/1435] Fix change SWD frequency of stlink v3 --- doc/dev/developer.txt | 2 +- inc/backend.h | 2 +- inc/stlink.h | 2 +- src/common.c | 4 +-- src/stlink-lib/usb.c | 68 +++++++++++++++++-------------------------- 5 files changed, 31 insertions(+), 47 deletions(-) diff --git a/doc/dev/developer.txt b/doc/dev/developer.txt index 32afd4352..9c4da22f7 100644 --- a/doc/dev/developer.txt +++ b/doc/dev/developer.txt @@ -300,7 +300,7 @@ Return: -1 for error. 0 for success. int stlink_current_mode(stlink_t *sl); int stlink_force_debug(stlink_t *sl); int stlink_target_voltage(stlink_t *sl); - int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); + int stlink_set_swdclk(stlink_t *sl, int freq_khz); int stlink_erase_flash_mass(stlink_t* sl); int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); diff --git a/inc/backend.h b/inc/backend.h index f852da05d..d60708031 100644 --- a/inc/backend.h +++ b/inc/backend.h @@ -28,7 +28,7 @@ int (*current_mode) (stlink_t * stl); int (*force_debug) (stlink_t *sl); int32_t (*target_voltage) (stlink_t *sl); - int (*set_swdclk) (stlink_t * stl, uint16_t divisor); + int (*set_swdclk) (stlink_t * stl, int freq_khz); } stlink_backend_t; #endif // STLINK_BACKEND_H_ diff --git a/inc/stlink.h b/inc/stlink.h index 2ec2db367..7fce9d3dc 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -242,7 +242,7 @@ int stlink_step(stlink_t *sl); int stlink_current_mode(stlink_t *sl); int stlink_force_debug(stlink_t *sl); int stlink_target_voltage(stlink_t *sl); -int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); +int stlink_set_swdclk(stlink_t *sl, int freq_khz); int stlink_erase_flash_mass(stlink_t* sl); int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); diff --git a/src/common.c b/src/common.c index 89f27aa66..7321b39a4 100644 --- a/src/common.c +++ b/src/common.c @@ -1491,9 +1491,9 @@ int stlink_run(stlink_t *sl) { return(sl->backend->run(sl)); } -int stlink_set_swdclk(stlink_t *sl, uint16_t divisor) { +int stlink_set_swdclk(stlink_t *sl, int freq_khz) { DLOG("*** set_swdclk ***\n"); - return(sl->backend->set_swdclk(sl, divisor)); + return(sl->backend->set_swdclk(sl, freq_khz)); } int stlink_status(stlink_t *sl) { diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 92ad4cbc5..f5a91abf4 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -651,7 +651,7 @@ int _stlink_usb_run(stlink_t* sl) { return(0); } -int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { +int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -661,6 +661,28 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { // clock speed only supported by stlink/v2 and for firmware >= 22 if (sl->version.stlink_v == 2 && sl->version.jtag_v >= 22) { + uint16_t clk_divisor; + if (clk_freq) { + const uint32_t map[] = {5, 15, 25, 50, 100, 125, 240, 480, 950, 1200, 1800, 4000}; + int speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), clk_freq); + switch (map[speed_index]) { + case 5: clk_divisor = STLINK_SWDCLK_5KHZ_DIVISOR; break; + case 15: clk_divisor = STLINK_SWDCLK_15KHZ_DIVISOR; break; + case 25: clk_divisor = STLINK_SWDCLK_25KHZ_DIVISOR; break; + case 50: clk_divisor = STLINK_SWDCLK_50KHZ_DIVISOR; break; + case 100: clk_divisor = STLINK_SWDCLK_100KHZ_DIVISOR; break; + case 125: clk_divisor = STLINK_SWDCLK_125KHZ_DIVISOR; break; + case 240: clk_divisor = STLINK_SWDCLK_240KHZ_DIVISOR; break; + case 480: clk_divisor = STLINK_SWDCLK_480KHZ_DIVISOR; break; + case 950: clk_divisor = STLINK_SWDCLK_950KHZ_DIVISOR; break; + case 1200: clk_divisor = STLINK_SWDCLK_1P2MHZ_DIVISOR; break; + default: + case 1800: clk_divisor = STLINK_SWDCLK_1P8MHZ_DIVISOR; break; + case 4000: clk_divisor = STLINK_SWDCLK_4MHZ_DIVISOR; break; + } + } else + clk_divisor = STLINK_SWDCLK_1P8MHZ_DIVISOR; + i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; @@ -691,7 +713,6 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { } int speeds_size = data[8]; - if (speeds_size > STLINK_V3_MAX_FREQ_NB) { speeds_size = STLINK_V3_MAX_FREQ_NB; } @@ -701,7 +722,8 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { // Set to zero all the next entries for (i = speeds_size; i < STLINK_V3_MAX_FREQ_NB; i++) map[i] = 0; - speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), 1800); + if (!clk_freq) clk_freq = 1800; // set default frequency + speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), clk_freq); i = fill_command(sl, SG_DXFER_FROM_DEV, 16); @@ -1228,45 +1250,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL // should be done at this speed too // set the stlink clock speed (default is 1800kHz) DLOG("JTAG/SWD freq set to %d\n", freq); - - switch (freq) { - case 5: - stlink_set_swdclk(sl, STLINK_SWDCLK_5KHZ_DIVISOR); - break; - case 15: - stlink_set_swdclk(sl, STLINK_SWDCLK_15KHZ_DIVISOR); - break; - case 25: - stlink_set_swdclk(sl, STLINK_SWDCLK_25KHZ_DIVISOR); - break; - case 50: - stlink_set_swdclk(sl, STLINK_SWDCLK_50KHZ_DIVISOR); - break; - case 100: - stlink_set_swdclk(sl, STLINK_SWDCLK_100KHZ_DIVISOR); - break; - case 125: - stlink_set_swdclk(sl, STLINK_SWDCLK_125KHZ_DIVISOR); - break; - case 240: - stlink_set_swdclk(sl, STLINK_SWDCLK_240KHZ_DIVISOR); - break; - case 480: - stlink_set_swdclk(sl, STLINK_SWDCLK_480KHZ_DIVISOR); - break; - case 950: - stlink_set_swdclk(sl, STLINK_SWDCLK_950KHZ_DIVISOR); - break; - case 1200: - stlink_set_swdclk(sl, STLINK_SWDCLK_1P2MHZ_DIVISOR); - break; - case 0: case 1800: - stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); - break; - case 4000: - stlink_set_swdclk(sl, STLINK_SWDCLK_4MHZ_DIVISOR); - break; - } + stlink_set_swdclk(sl, freq); if (reset == 2) { stlink_jtag_reset(sl, 0); From 2acfa8b8f2211d5d53e3e39fa79c90c56dd54409 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Thu, 5 Nov 2020 20:42:32 +0500 Subject: [PATCH 1034/1435] Add debug message of current CPU mode --- src/common.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/common.c b/src/common.c index 7321b39a4..8eb3370ef 100644 --- a/src/common.c +++ b/src/common.c @@ -1487,7 +1487,12 @@ int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { } int stlink_run(stlink_t *sl) { + struct stlink_reg rr; DLOG("*** stlink_run ***\n"); + + stlink_read_reg(sl, 16, &rr); + DLOG("Run in %s mode\n", (rr.xpsr & (1 << 24))?"ARM":"THUMB"); + return(sl->backend->run(sl)); } From 4e58872913acd4bcbef5ac9b63514cb04bba4727 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Fri, 6 Nov 2020 16:17:54 +0500 Subject: [PATCH 1035/1435] Add printing st-link version to st-info --- src/common.c | 2 +- src/st-info/info.c | 30 +++++++++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/common.c b/src/common.c index 8eb3370ef..d04d10049 100644 --- a/src/common.c +++ b/src/common.c @@ -1487,7 +1487,7 @@ int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { } int stlink_run(stlink_t *sl) { - struct stlink_reg rr; + struct stlink_reg rr; DLOG("*** stlink_run ***\n"); stlink_read_reg(sl, 16, &rr); diff --git a/src/st-info/info.c b/src/st-info/info.c index 2343140de..4f2fae1eb 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -35,23 +35,36 @@ static void stlink_print_serial(stlink_t *sl, bool openocd) { printf("\n"); } +static void stlink_print_version(stlink_t *sl) { + // Implementation of version printing is minimalistic + // but contains all available information from sl->version + printf("V%d", sl->version.stlink_v); + if (sl->version.jtag_v > 0) + printf("J%d", sl->version.jtag_v); + if (sl->version.swim_v > 0) + printf("S%d", sl->version.swim_v); + printf("\n"); +} + static void stlink_print_info(stlink_t *sl) { const struct stlink_chipid_params *params = NULL; if (!sl) { return; } - printf(" serial: "); + printf(" version: "); + stlink_print_version(sl); + printf(" serial: "); stlink_print_serial(sl, false); - printf(" hla-serial: "); + printf(" hla-serial: "); stlink_print_serial(sl, true); - printf(" flash: %u (pagesize: %u)\n", + printf(" flash: %u (pagesize: %u)\n", (uint32_t)sl->flash_size, (uint32_t)sl->flash_pgsz); - printf(" sram: %u\n", (uint32_t)sl->sram_size); - printf(" chipid: 0x%.4x\n", sl->chip_id); + printf(" sram: %u\n", (uint32_t)sl->sram_size); + printf(" chipid: 0x%.4x\n", sl->chip_id); params = stlink_chipid_get_params(sl->chip_id); - if (params) { printf(" descr: %s\n", params->description); } + if (params) { printf(" descr: %s\n", params->description); } } static void stlink_probe(void) { @@ -62,7 +75,10 @@ static void stlink_probe(void) { printf("Found %u stlink programmers\n", (unsigned int)size); - for (size_t n = 0; n < size; n++) { stlink_print_info(stdevs[n]); } + for (size_t n = 0; n < size; n++) { + if (size>1) printf("%lu.\n", n+1); + stlink_print_info(stdevs[n]); + } stlink_probe_usb_free(&stdevs, size); } From 277eee7aec00493151d940a12d697651e8977d66 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Sat, 7 Nov 2020 13:50:14 +0500 Subject: [PATCH 1036/1435] Move check of current instruction mode to stlink_run --- src/common.c | 8 +++++++- src/stlink-lib/flash_loader.c | 7 ------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/common.c b/src/common.c index d04d10049..e3c4fdd2e 100644 --- a/src/common.c +++ b/src/common.c @@ -1490,8 +1490,14 @@ int stlink_run(stlink_t *sl) { struct stlink_reg rr; DLOG("*** stlink_run ***\n"); + /* Make sure we are in Thumb mode + * Cortex-M chips don't support ARM mode instructions + * xPSR may be incorrect if the vector table has invalid data */ stlink_read_reg(sl, 16, &rr); - DLOG("Run in %s mode\n", (rr.xpsr & (1 << 24))?"ARM":"THUMB"); + if ((rr.xpsr & (1 << 24)) == 0) { + ILOG("Go to Thumb mode\n"); + stlink_write_reg(sl, rr.xpsr | (1 << 24), 16); + } return(sl->backend->run(sl)); } diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index c86aefbf7..b7726e875 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -356,13 +356,6 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe // only used on VL/F1_XL, but harmless for others stlink_write_reg(sl, fl->loader_addr, 15); // pc register - /* Make sure we are in Thumb mode */ - stlink_read_reg(sl, 16, &rr); - if ((rr.xpsr & (1 << 24)) == 0) { - ILOG("Go to Thumb mode\n"); - stlink_write_reg(sl, rr.xpsr | (1 << 24), 16); - } - /* Run loader */ stlink_run(sl); From 54000d67acefd86df4bdb0594dee940dd04763fa Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Mon, 9 Nov 2020 13:41:51 +0500 Subject: [PATCH 1037/1435] H7 add support dual bank, mass erase and new chips --- inc/stm32.h | 2 + src/common.c | 400 ++++++++++++++++++++-------------------- src/stlink-lib/chipid.c | 31 +++- src/stlink-lib/chipid.h | 2 + 4 files changed, 239 insertions(+), 196 deletions(-) diff --git a/inc/stm32.h b/inc/stm32.h index 768fabb87..1ea0d1f04 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -14,6 +14,8 @@ /* Constant STM32 memory map figures */ #define STM32_FLASH_BASE ((uint32_t)0x08000000) +#define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) +#define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) #define STM32_SRAM_BASE ((uint32_t)0x20000000) #define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) diff --git a/src/common.c b/src/common.c index e3c4fdd2e..0ac2d1153 100644 --- a/src/common.c +++ b/src/common.c @@ -30,6 +30,9 @@ #define __attribute__(x) #endif +#define BANK_1 0 +#define BANK_2 1 + /* stm32f FPEC flash controller interface, pm0063 manual */ // TODO - all of this needs to be abstracted out.... // STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, August 2012) @@ -50,7 +53,6 @@ #define FLASH_SR2 (FLASH_REGS_ADDR + 0x4c) #define FLASH_CR2 (FLASH_REGS_ADDR + 0x50) #define FLASH_AR2 (FLASH_REGS_ADDR + 0x54) -#define FLASH_BANK2_START_ADDR 0x08080000 // For STM32F05x, the RDPTR_KEY may be wrong, but as it is not used anywhere... #define FLASH_RDPTR_KEY 0x00a5 @@ -307,12 +309,17 @@ #define FLASH_H7_CR_LOCK 0 #define FLASH_H7_CR_PG 1 #define FLASH_H7_CR_SER 2 +#define FLASH_H7_CR_BER 3 #define FLASH_H7_CR_PSIZE 4 -#define FLASH_H7_CR_START 7 +#define FLASH_H7_CR_START(chipid) (chipid==STLINK_CHIPID_STM32_H7AX?5:7) #define FLASH_H7_CR_SNB 8 #define FLASH_H7_CR_SNB_MASK 0x700 #define FLASH_H7_SR_QW 2 +#define FLASH_H7_SR_WRPERR 17 +#define FLASH_H7_SR_PGSERR 18 +#define FLASH_H7_SR_STRBERR 19 +#define FLASH_H7_SR_ERROR_MASK ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | (1 << FLASH_H7_SR_WRPERR)) #define FLASH_H7_OPTCR_OPTLOCK 0 #define FLASH_H7_OPTCR_OPTSTART 1 @@ -325,10 +332,17 @@ #define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) #define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) +#define FLASH_H7_KEYR2 (FLASH_H7_REGS_ADDR + 0x104) #define FLASH_H7_OPT_KEYR (FLASH_H7_REGS_ADDR + 0x08) +#define FLASH_H7_OPT_KEYR2 (FLASH_H7_REGS_ADDR + 0x108) #define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c) +#define FLASH_H7_CR2 (FLASH_H7_REGS_ADDR + 0x10c) #define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) +#define FLASH_H7_SR2 (FLASH_H7_REGS_ADDR + 0x110) +#define FLASH_H7_CCR1 (FLASH_H7_REGS_ADDR + 0x14) +#define FLASH_H7_CCR2 (FLASH_H7_REGS_ADDR + 0x114) #define FLASH_H7_OPTCR (FLASH_H7_REGS_ADDR + 0x18) +#define FLASH_H7_OPTCR2 (FLASH_H7_REGS_ADDR + 0x118) #define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) #define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) @@ -397,7 +411,7 @@ static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { return(rdp & 0xff); } -static inline uint32_t read_flash_cr(stlink_t *sl) { +static inline uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { uint32_t reg, res; if (sl->flash_type == STLINK_FLASH_TYPE_F4) { @@ -412,9 +426,9 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { reg = STM32WB_FLASH_CR; } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - reg = FLASH_H7_CR1; + reg = (bank == BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; } else { - reg = FLASH_CR; + reg = (bank == BANK_1)?FLASH_CR:FLASH_CR2; } stlink_read_debug32(sl, reg, &res); @@ -425,15 +439,6 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { return(res); } -static inline uint32_t read_flash_cr2(stlink_t *sl) { - uint32_t res; - stlink_read_debug32(sl, FLASH_CR2, &res); -#if DEBUG_FLASH - fprintf(stdout, "CR2:0x%x\n", res); -#endif - return(res); -} - static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ uint32_t cr_lock_shift; @@ -476,7 +481,7 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { } static void unlock_flash(stlink_t *sl) { - uint32_t key_reg; + uint32_t key_reg, key2_reg = 0; uint32_t flash_key1 = FLASH_KEY1; uint32_t flash_key2 = FLASH_KEY2; /* The unlock sequence consists of 2 write cycles where 2 key values are written @@ -484,9 +489,11 @@ static void unlock_flash(stlink_t *sl) { * An invalid sequence results in a definitive lock of the FPEC block until next reset. */ - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + if (sl->flash_type == STLINK_FLASH_TYPE_F0) { key_reg = FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + key_reg = FLASH_KEYR; + key2_reg = FLASH_KEYR2; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { key_reg = FLASH_F4_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { @@ -504,6 +511,9 @@ static void unlock_flash(stlink_t *sl) { key_reg = STM32WB_FLASH_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { key_reg = FLASH_H7_KEYR1; + if (sl->has_dual_bank) { + key2_reg = FLASH_H7_KEYR2; + } } else { ELOG("unsupported flash method, abort\n"); return; @@ -512,9 +522,9 @@ static void unlock_flash(stlink_t *sl) { stlink_write_debug32(sl, key_reg, flash_key1); stlink_write_debug32(sl, key_reg, flash_key2); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - stlink_write_debug32(sl, FLASH_KEYR2, flash_key1); - stlink_write_debug32(sl, FLASH_KEYR2, flash_key2); + if (key2_reg) { + stlink_write_debug32(sl, key2_reg, flash_key1); + stlink_write_debug32(sl, key2_reg, flash_key2); } } @@ -534,13 +544,16 @@ static int unlock_flash_if(stlink_t *sl) { } static void lock_flash(stlink_t *sl) { - uint32_t cr_lock_shift, cr_reg, n; + uint32_t cr_lock_shift, cr_reg, n, cr2_reg = 0; uint32_t cr_mask = 0xffffffffu; - if (sl->flash_type == STLINK_FLASH_TYPE_F0 || - sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + if (sl->flash_type == STLINK_FLASH_TYPE_F0) { cr_reg = FLASH_CR; cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + cr_reg = FLASH_CR; + cr2_reg = FLASH_CR2; + cr_lock_shift = FLASH_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; cr_lock_shift = FLASH_F4_CR_LOCK; @@ -562,6 +575,9 @@ static void lock_flash(stlink_t *sl) { cr_lock_shift = STM32WB_FLASH_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { cr_reg = FLASH_H7_CR1; + if (sl->has_dual_bank) { + cr2_reg = FLASH_H7_CR2; + } cr_lock_shift = FLASH_H7_CR_LOCK; cr_mask = ~(1u << FLASH_H7_CR_SER); } else { @@ -574,9 +590,9 @@ static void lock_flash(stlink_t *sl) { n |= (1u << cr_lock_shift); stlink_write_debug32(sl, cr_reg, n); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - n = read_flash_cr2(sl) | (1u << cr_lock_shift); - stlink_write_debug32(sl, FLASH_CR2, n); + if (cr2_reg) { + n = read_flash_cr(sl, BANK_2) | (1u << cr_lock_shift); + stlink_write_debug32(sl, cr2_reg, n); } } @@ -637,7 +653,7 @@ static bool is_flash_option_locked(stlink_t *sl) { } static int lock_flash_option(stlink_t *sl) { - uint32_t optlock_shift, optcr_reg, n; + uint32_t optlock_shift, optcr_reg, n, optcr2_reg = 0; int active_bit_level = 1; switch (sl->flash_type) { @@ -675,6 +691,8 @@ static int lock_flash_option(stlink_t *sl) { case STLINK_FLASH_TYPE_H7: optcr_reg = FLASH_H7_OPTCR; optlock_shift = FLASH_H7_OPTCR_OPTLOCK; + if (sl->has_dual_bank) + optcr2_reg = FLASH_H7_OPTCR2; break; default: ELOG("unsupported flash method, abort\n"); @@ -690,11 +708,24 @@ static int lock_flash_option(stlink_t *sl) { } stlink_write_debug32(sl, optcr_reg, n); + + if (optcr2_reg) { + stlink_read_debug32(sl, optcr2_reg, &n); + + if (active_bit_level == 0) { + n &= ~(1u << optlock_shift); + } else { + n |= (1u << optlock_shift); + } + + stlink_write_debug32(sl, optcr2_reg, n); + } + return(0); } static int unlock_flash_option(stlink_t *sl) { - uint32_t optkey_reg; + uint32_t optkey_reg, optkey2_reg = 0; uint32_t optkey1 = FLASH_OPTKEY1; uint32_t optkey2 = FLASH_OPTKEY2; @@ -728,6 +759,8 @@ static int unlock_flash_option(stlink_t *sl) { break; case STLINK_FLASH_TYPE_H7: optkey_reg = FLASH_H7_OPT_KEYR; + if (sl->has_dual_bank) + optkey2_reg = FLASH_H7_OPT_KEYR2; break; default: ELOG("unsupported flash method, abort\n"); @@ -736,6 +769,12 @@ static int unlock_flash_option(stlink_t *sl) { stlink_write_debug32(sl, optkey_reg, optkey1); stlink_write_debug32(sl, optkey_reg, optkey2); + + if (optkey2_reg) { + stlink_write_debug32(sl, optkey2_reg, optkey1); + stlink_write_debug32(sl, optkey2_reg, optkey2); + } + return(0); } @@ -756,10 +795,10 @@ static int unlock_flash_option_if(stlink_t *sl) { return(0); } -static void set_flash_cr_pg(stlink_t *sl) { +static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { uint32_t cr_reg, x; - x = read_flash_cr(sl); + x = read_flash_cr(sl, bank); if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; @@ -779,7 +818,7 @@ static void set_flash_cr_pg(stlink_t *sl) { cr_reg = STM32WB_FLASH_CR; x |= (1 << FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; + cr_reg = (bank == BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; x |= (1 << FLASH_H7_CR_PG); } else { cr_reg = FLASH_CR; @@ -789,8 +828,9 @@ static void set_flash_cr_pg(stlink_t *sl) { stlink_write_debug32(sl, cr_reg, x); } -static void clear_flash_cr_pg(stlink_t *sl) { +static void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { uint32_t cr_reg, n; + uint32_t bit = FLASH_CR_PG; if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; @@ -803,15 +843,18 @@ static void clear_flash_cr_pg(stlink_t *sl) { cr_reg = STM32Gx_FLASH_CR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; + bit = FLASH_H7_CR_PG; } else { cr_reg = FLASH_CR; } - n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG); + n = read_flash_cr(sl, bank) & ~(1 << bit); stlink_write_debug32(sl, cr_reg, n); } -static void set_flash_cr_per(stlink_t *sl) { +static void set_flash_cr_per(stlink_t *sl, unsigned bank) { uint32_t cr_reg, val; if (sl->flash_type == STLINK_FLASH_TYPE_G0 || @@ -820,7 +863,7 @@ static void set_flash_cr_per(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; } else { - cr_reg = FLASH_CR; + cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; } stlink_read_debug32(sl, cr_reg, &val); @@ -828,12 +871,7 @@ static void set_flash_cr_per(stlink_t *sl) { stlink_write_debug32(sl, cr_reg, val); } -static void set_flash_cr2_per(stlink_t *sl) { - const uint32_t n = (1 << FLASH_CR_PER); - stlink_write_debug32(sl, FLASH_CR2, n); -} - -static void clear_flash_cr_per(stlink_t *sl) { +static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { uint32_t cr_reg; if (sl->flash_type == STLINK_FLASH_TYPE_G0 || @@ -842,14 +880,14 @@ static void clear_flash_cr_per(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; } else { - cr_reg = FLASH_CR; + cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; } - const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PER); + const uint32_t n = read_flash_cr(sl, bank) & ~(1 << FLASH_CR_PER); stlink_write_debug32(sl, cr_reg, n); } -static void set_flash_cr_mer(stlink_t *sl, bool v) { +static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { uint32_t val, cr_reg, cr_mer, cr_pg; if (sl->flash_type == STLINK_FLASH_TYPE_F4) { @@ -878,8 +916,12 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { cr_reg = STM32WB_FLASH_CR; cr_mer = (1 << FLASH_CR_MER); cr_pg = (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank==BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; + cr_mer = (1 << FLASH_H7_CR_BER); + cr_pg = (1 << FLASH_H7_CR_PG); } else { - cr_reg = FLASH_CR; + cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; cr_mer = (1 << FLASH_CR_MER); cr_pg = (1 << FLASH_CR_PG); } @@ -901,46 +943,7 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { stlink_write_debug32(sl, cr_reg, val); } -static void set_flash_cr2_mer(stlink_t *sl, bool v) { - const uint32_t cr_pg = (1 << FLASH_CR_PER); - const uint32_t cr_mer = (1 << FLASH_CR_MER); - uint32_t val; - - stlink_read_debug32(sl, FLASH_CR2, &val); - val &= ~cr_pg; - - if (v) { - val |= cr_mer; - } else { - val &= ~cr_mer; - } - - stlink_write_debug32(sl, FLASH_CR2, val); -} - -static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { - uint32_t val, cr_reg, cr_mer; - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - cr_mer = 1 << FLASH_CR_MER; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_mer = 1 << FLASH_CR_MER; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); - } else { - cr_reg = FLASH_CR; - cr_mer = (1 << FLASH_CR_MER); - } - - stlink_read_debug32(sl, cr_reg, &val); - val &= ~cr_mer; - stlink_write_debug32(sl, cr_reg, val); -} - -static void set_flash_cr_strt(stlink_t *sl) { +static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { uint32_t val, cr_reg, cr_strt; if (sl->flash_type == STLINK_FLASH_TYPE_F4) { @@ -960,10 +963,10 @@ static void set_flash_cr_strt(stlink_t *sl) { cr_reg = STM32WB_FLASH_CR; cr_strt = (1 << STM32WB_FLASH_CR_STRT); } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; - cr_strt = 1 << FLASH_H7_CR_START; + cr_reg = (bank==BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; + cr_strt = 1 << FLASH_H7_CR_START(sl->chip_id); } else { - cr_reg = FLASH_CR; + cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; cr_strt = (1 << FLASH_CR_STRT); } @@ -972,20 +975,12 @@ static void set_flash_cr_strt(stlink_t *sl) { stlink_write_debug32(sl, cr_reg, val); } -static void set_flash_cr2_strt(stlink_t *sl) { - uint32_t val; - - stlink_read_debug32(sl, FLASH_CR2, &val); - val |= 1 << FLASH_CR_STRT; - stlink_write_debug32(sl, FLASH_CR2, val); -} - -static inline uint32_t read_flash_sr(stlink_t *sl) { +static inline uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { uint32_t res, sr_reg; if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - sr_reg = FLASH_SR; + sr_reg = (bank==BANK_1)?FLASH_SR:FLASH_SR2; } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { @@ -1000,7 +995,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_reg = STM32WB_FLASH_SR; } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - sr_reg = FLASH_H7_SR1; + sr_reg = (bank==BANK_1)?FLASH_H7_SR1:FLASH_H7_SR2; } else { ELOG("unsupported flash method, abort"); return(-1); @@ -1010,12 +1005,6 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { return(res); } -static inline uint32_t read_flash_sr2(stlink_t *sl) { - uint32_t res; - stlink_read_debug32(sl, FLASH_SR2, &res); - return(res); -} - static inline unsigned int is_flash_busy(stlink_t *sl) { uint32_t sr_busy_shift; unsigned int res; @@ -1042,10 +1031,11 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { return(-1); } - res = read_flash_sr(sl) & (1 << sr_busy_shift); + res = read_flash_sr(sl, BANK_1) & (1 << sr_busy_shift); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - res |= read_flash_sr2(sl) & (1 << sr_busy_shift); + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || + (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->has_dual_bank)) { + res |= read_flash_sr(sl, BANK_2) & (1 << sr_busy_shift); } return(res); @@ -1081,17 +1071,31 @@ static int check_flash_error(stlink_t *sl) switch (sl->flash_type) { case STLINK_FLASH_TYPE_F0: - res = read_flash_sr(sl) & FLASH_SR_ERROR_MASK; + res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; break; case STLINK_FLASH_TYPE_F7: - res = read_flash_sr(sl) & FLASH_F7_SR_ERROR_MASK; + res = read_flash_sr(sl, BANK_1) & FLASH_F7_SR_ERROR_MASK; break; case STLINK_FLASH_TYPE_G0: case STLINK_FLASH_TYPE_G4: - res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK; + res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; break; case STLINK_FLASH_TYPE_L0: - res = read_flash_sr(sl) & STM32L0_FLASH_SR_ERROR_MASK; + res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; + break; + case STLINK_FLASH_TYPE_H7: + res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; + if (sl->has_dual_bank) { + res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; + } + if (res) { + // Clear errors + stlink_write_debug32(sl, FLASH_H7_CCR1, res); + if (sl->has_dual_bank) { + stlink_write_debug32(sl, FLASH_H7_CCR2, res); + } + } + break; default: break; } @@ -1104,35 +1108,16 @@ static int check_flash_error(stlink_t *sl) return(0); } -static inline unsigned int is_flash_eop(stlink_t *sl) { - return(read_flash_sr(sl) & (1 << FLASH_SR_EOP)); -} - -static void __attribute__((unused)) clear_flash_sr_eop(stlink_t *sl) { - const uint32_t n = read_flash_sr(sl) & ~(1 << FLASH_SR_EOP); - stlink_write_debug32(sl, FLASH_SR, n); -} - -static void __attribute__((unused)) wait_flash_eop(stlink_t *sl) { - // TODO: add some delays here - while (is_flash_eop(sl) == 0) - ; -} - -static inline void write_flash_ar(stlink_t *sl, uint32_t n) { - stlink_write_debug32(sl, FLASH_AR, n); -} - -static inline void write_flash_ar2(stlink_t *sl, uint32_t n) { - stlink_write_debug32(sl, FLASH_AR2, n); +static inline void write_flash_ar(stlink_t *sl, uint32_t n, unsigned bank) { + stlink_write_debug32(sl, (bank==BANK_1)?FLASH_AR:FLASH_AR2, n); } -static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n) { +static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n, unsigned bank) { uint32_t cr_reg, psize_shift; - uint32_t x = read_flash_cr(sl); + uint32_t x = read_flash_cr(sl, bank); if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; + cr_reg = (bank==BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; psize_shift = FLASH_H7_CR_PSIZE; } else { cr_reg = FLASH_F4_CR; @@ -1147,12 +1132,12 @@ static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n) { stlink_write_debug32(sl, cr_reg, x); } -static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { +static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, unsigned bank) { uint32_t cr_reg, snb_mask, snb_shift, ser_shift; - uint32_t x = read_flash_cr(sl); + uint32_t x = read_flash_cr(sl, bank); if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; + cr_reg = (bank==BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; snb_mask = FLASH_H7_CR_SNB_MASK; snb_shift = FLASH_H7_CR_SNB; ser_shift = FLASH_H7_CR_SER; @@ -1174,7 +1159,7 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { stlink_write_debug32(sl, STM32L4_FLASH_SR, 0xFFFFFFFF & ~(1 << STM32L4_FLASH_SR_BSY)); - uint32_t x = read_flash_cr(sl); + uint32_t x = read_flash_cr(sl, BANK_1); x &= ~STM32L4_FLASH_CR_OPBITS; x &= ~STM32L4_FLASH_CR_PAGEMASK; x &= ~(1 << STM32L4_FLASH_CR_MER1); @@ -1391,6 +1376,11 @@ int stlink_load_device_params(stlink_t *sl) { if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { sl->flash_pgsz <<= 1; } } + // H7 devices with small flash has one bank + if (sl->has_dual_bank && sl->flash_type == STLINK_FLASH_TYPE_H7) { + sl->has_dual_bank = (flash_size/sl->flash_pgsz) > 1; + } + #if 0 // Old code -- REW ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); @@ -2314,9 +2304,9 @@ uint32_t calculate_F7_sectornum(uint32_t flashaddr) { } -uint32_t calculate_H7_sectornum(uint32_t flashaddr) { - flashaddr &= ~STM32_FLASH_BASE; // sector holding the flash address - return(flashaddr / 0x20000); +uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, unsigned bank) { + flashaddr &= ~((bank==BANK_1)?STM32_FLASH_BASE:STM32_H7_FLASH_BANK2_BASE); // sector holding the flash address + return(flashaddr / sl->flash_pgsz); } // returns BKER:PNB for the given page address @@ -2392,8 +2382,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_F7 || - sl->flash_type == STLINK_FLASH_TYPE_L4 || - sl->flash_type == STLINK_FLASH_TYPE_H7) { + sl->flash_type == STLINK_FLASH_TYPE_L4) { // wait for ongoing op to finish wait_flash_busy(sl); @@ -2420,14 +2409,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, stlink_calculate_pagesize(sl, flashaddr)); - write_flash_cr_snb(sl, sector); - } else if (sl->chip_id == STLINK_CHIPID_STM32_H74XXX) { - // calculate the actual page from the address - uint32_t sector = calculate_H7_sectornum(flashaddr); - - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", - sector, stlink_calculate_pagesize(sl, flashaddr)); - write_flash_cr_snb(sl, sector); + write_flash_cr_snb(sl, sector, BANK_1); } else { // calculate the actual page from the address uint32_t sector = calculate_F4_sectornum(flashaddr); @@ -2439,14 +2421,14 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { // follow the values for the first bank on 2mb devices... if (sector >= 12) { sector += 4; } - write_flash_cr_snb(sl, sector); + write_flash_cr_snb(sl, sector, BANK_1); } - set_flash_cr_strt(sl); // start erase operation + set_flash_cr_strt(sl, BANK_1); // start erase operation wait_flash_busy(sl); // wait for completion lock_flash(sl); // TODO: fails to program if this is in #if DEBUG_FLASH - fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); + fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl, BANK_1)); #endif } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { @@ -2526,7 +2508,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { uint32_t val; wait_flash_busy(sl); // wait for any ongoing Flash operation to finish unlock_flash_if(sl); - set_flash_cr_per(sl); // set the 'enable Flash erase' bit + set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit // set the page to erase if (sl->flash_type == STLINK_FLASH_TYPE_WB) { @@ -2554,27 +2536,29 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); } - set_flash_cr_strt(sl); // set the 'start operation' bit + set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit wait_flash_busy(sl); // wait for the 'busy' bit to clear - clear_flash_cr_per(sl); // clear the 'enable page erase' bit + clear_flash_cr_per(sl, BANK_1); // clear the 'enable page erase' bit lock_flash(sl); - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr < FLASH_BANK2_START_ADDR))) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_F0 || + sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + unsigned bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE)?BANK_1:BANK_2; wait_flash_busy(sl); unlock_flash_if(sl); - clear_flash_cr_pg(sl); // clear the pg bit - set_flash_cr_per(sl); // set the page erase bit - write_flash_ar(sl, flashaddr); // select the page to erase - set_flash_cr_strt(sl); // start erase operation, reset by hw with busy bit + clear_flash_cr_pg(sl, bank); // clear the pg bit + set_flash_cr_per(sl, bank); // set the page erase bit + write_flash_ar(sl, flashaddr, bank); // select the page to erase + set_flash_cr_strt(sl, bank); // start erase operation, reset by hw with busy bit wait_flash_busy(sl); lock_flash(sl); - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr >= FLASH_BANK2_START_ADDR)) { - wait_flash_busy(sl); - unlock_flash_if(sl); - set_flash_cr2_per(sl); // set the page erase bit - write_flash_ar2(sl, flashaddr); // select the page to erase - set_flash_cr2_strt(sl); // start erase operation, reset by hw with busy bit - wait_flash_busy(sl); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE)?BANK_1:BANK_2; + wait_flash_busy(sl); // wait for ongoing op to finish + unlock_flash_if(sl); // unlock if locked + uint32_t sector = calculate_H7_sectornum(sl, flashaddr, bank);// calculate the actual page from the address + write_flash_cr_snb(sl, sector, bank); // select the page to erase + set_flash_cr_strt(sl, bank); // start erase operation + wait_flash_busy(sl); // wait for completion lock_flash(sl); } else { WLOG("unknown coreid %x, page erase failed\n", sl->core_id); @@ -2586,7 +2570,9 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } int stlink_erase_flash_mass(stlink_t *sl) { - // TODO: User MER bit to mass-erase G0, G4, WB series. + int err = 0; + + // TODO: User MER bit to mass-erase WB series. if (sl->flash_type == STLINK_FLASH_TYPE_L0 || sl->flash_type == STLINK_FLASH_TYPE_WB) { // erase each page @@ -2609,28 +2595,39 @@ int stlink_erase_flash_mass(stlink_t *sl) { } else { wait_flash_busy(sl); unlock_flash_if(sl); - set_flash_cr_mer(sl, 1); // set the mass erase bit - set_flash_cr_strt(sl); // start erase operation, reset by hw with busy bit - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - set_flash_cr2_mer(sl, 1); // set the mass erase bit in bank 2 - set_flash_cr2_strt(sl); // start erase operation in bank 2 + if (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_id != STLINK_CHIPID_STM32_H7AX) { + // set parallelism + write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); + if (sl->has_dual_bank) { + write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); + } + } + + set_flash_cr_mer(sl, 1, BANK_1); // set the mass erase bit + set_flash_cr_strt(sl, BANK_1); // start erase operation, reset by hw with busy bit + + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || + (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->has_dual_bank)) { + set_flash_cr_mer(sl, 1, BANK_2); // set the mass erase bit in bank 2 + set_flash_cr_strt(sl, BANK_2); // start erase operation in bank 2 } wait_flash_busy_progress(sl); - check_flash_error(sl); + err = check_flash_error(sl); lock_flash(sl); - set_flash_cr_mer(sl, 0); // reset the mass erase bit - - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - set_flash_cr2_mer(sl, 0); // reset the mass erase bit in bank 2 + // reset the mass erase bit + set_flash_cr_mer(sl, 0, BANK_1); + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || + (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->has_dual_bank)) { + set_flash_cr_mer(sl, 0, BANK_2); } // TODO: verify the erased memory } - return(0); + return(err); } int stlink_fcheck_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { @@ -2786,16 +2783,16 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { } else { if (voltage > 2700) { ILOG("enabling 32-bit flash writes\n"); - write_flash_cr_psiz(sl, 2); + write_flash_cr_psiz(sl, 2, BANK_1); } else { ILOG("Target voltage (%d mV) too low for 32-bit flash, " "using 8-bit flash writes\n", voltage); - write_flash_cr_psiz(sl, 0); + write_flash_cr_psiz(sl, 0, BANK_1); } } // set programming mode - set_flash_cr_pg(sl); + set_flash_cr_pg(sl, BANK_1); } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { @@ -2803,7 +2800,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { wait_flash_busy(sl); unlock_flash_if(sl); // unlock flash if necessary - set_flash_cr_pg(sl); // set PG 'allow programming' bit + set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { ILOG("Starting Flash write for L0\n"); @@ -2852,7 +2849,17 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { ILOG("Starting Flash write for H7\n"); unlock_flash_if(sl); // unlock the cr - set_flash_cr_pg(sl); // set programming mode + set_flash_cr_pg(sl, BANK_1); // set programming mode + if (sl->has_dual_bank) { + set_flash_cr_pg(sl, BANK_2); + } + if (sl->chip_id != STLINK_CHIPID_STM32_H7AX) { + // set parallelism + write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); + if (sl->has_dual_bank) { + write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); + } + } } else { ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); return(-1); @@ -2961,7 +2968,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr // unlock and set programming mode unlock_flash_if(sl); - if (sl->flash_type != STLINK_FLASH_TYPE_F1_XL) { set_flash_cr_pg(sl); } + if (sl->flash_type != STLINK_FLASH_TYPE_F1_XL) { set_flash_cr_pg(sl, BANK_1); } DLOG("Finished unlocking flash, running loader!\n"); @@ -2984,10 +2991,10 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr } } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { for (off = 0; off < len;) { - // Program STM32H7x with 32-byte Flash words - size_t chunk = (len - off > 32) ? 32 : len - off; + // Program STM32H7x with 64-byte Flash words + size_t chunk = (len - off > 64) ? 64 : len - off; memcpy(sl->q_buf, base + off, chunk); - stlink_write_mem32(sl, addr + (uint32_t)off, 32); + stlink_write_mem32(sl, addr + (uint32_t)off, 64); wait_flash_busy(sl); off += chunk; @@ -3009,7 +3016,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr } int stlink_flashloader_stop(stlink_t *sl) { - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_F7) || (sl->flash_type == STLINK_FLASH_TYPE_L4) || (sl->flash_type == STLINK_FLASH_TYPE_WB) || @@ -3017,7 +3024,10 @@ int stlink_flashloader_stop(stlink_t *sl) { (sl->flash_type == STLINK_FLASH_TYPE_G4) || (sl->flash_type == STLINK_FLASH_TYPE_H7)) { - clear_flash_cr_pg(sl); + clear_flash_cr_pg(sl, BANK_1); + if (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->has_dual_bank) { + clear_flash_cr_pg(sl, BANK_2); + } lock_flash(sl); } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { uint32_t val; diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index c191fa919..5cf2ddd1c 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -617,8 +617,9 @@ static const struct stlink_chipid_params devices[] = { { // STM32H742/743/753 (from RM0433) .chip_id = STLINK_CHIPID_STM32_H74XXX, - .description = "H742/743/753", + .description = "H74x/H75x", .flash_type = STLINK_FLASH_TYPE_H7, + .has_dual_bank = true, .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) .flash_pagesize = 0x20000, // 128k sector (pg147) .sram_size = 0x20000, // 128k "DTCM" from Table 7 @@ -627,6 +628,34 @@ static const struct stlink_chipid_params devices[] = { .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 }, + { + // STM32H7A3/7B3 (from RM0455) + .chip_id = STLINK_CHIPID_STM32_H7AX, + .description = "H7Ax/H7Bx", + .flash_type = STLINK_FLASH_TYPE_H7, + .has_dual_bank = true, + .flash_size_reg = 0x08FFF80C, // "Flash size register" (p.2949) + .flash_pagesize = 0x2000, // 8k sector (p.146) + .sram_size = 0x20000, // 128k "DTCM" (Figure 1) + .bootrom_base = 0x1FF00000, // "System memory" starting address (Table 12-14) + .bootrom_size = 0x20000, // "System memory" byte size in hex splitted to two banks (Table 12-14) + .option_base = STM32_H7_OPTION_BYTES_BASE, + .option_size = 44, + }, + { + // STM32H72x/H73x (from RM0468) + .chip_id = STLINK_CHIPID_STM32_H72X, + .description = "H72x/H73x", + .flash_type = STLINK_FLASH_TYPE_H7, + .flash_size_reg = 0x1FF1E880, // "Flash size register" (p.3286) + .flash_pagesize = 0x20000, // 128k sector (p.152) + .sram_size = 0x20000, // 128k "DTCM" (Figure 1) + .bootrom_base = 0x1FF00000, // "System memory" starting address (Table 6) + .bootrom_size = 0x20000, // "System memory" byte size in hex (Table 6) + .option_base = STM32_H7_OPTION_BYTES_BASE, + .option_size = 44, + }, + { // unknown .chip_id = STLINK_CHIPID_UNKNOWN, diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index f717022ca..a342df2dc 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -64,6 +64,8 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* See: RM 0440 s46.6.1 "MCU device ID code" */ STLINK_CHIPID_STM32_G4_CAT3 = 0x469, STLINK_CHIPID_STM32_L4RX = 0x470, /* ID found on the STM32L4R9I-DISCO board */ + STLINK_CHIPID_STM32_H7AX = 0x480, /* RM0455, p. 2863 */ + STLINK_CHIPID_STM32_H72X = 0x483, /* RM0468, p. 3199 */ STLINK_CHIPID_STM32_WB55 = 0x495 }; From d902fba40aa3db82c4b144849a5ea427492cb06e Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Wed, 11 Nov 2020 19:57:57 +0500 Subject: [PATCH 1038/1435] Fix printf format --- src/st-info/info.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/st-info/info.c b/src/st-info/info.c index 4f2fae1eb..2e1ce0e96 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -38,11 +38,11 @@ static void stlink_print_serial(stlink_t *sl, bool openocd) { static void stlink_print_version(stlink_t *sl) { // Implementation of version printing is minimalistic // but contains all available information from sl->version - printf("V%d", sl->version.stlink_v); + printf("V%u", sl->version.stlink_v); if (sl->version.jtag_v > 0) - printf("J%d", sl->version.jtag_v); + printf("J%u", sl->version.jtag_v); if (sl->version.swim_v > 0) - printf("S%d", sl->version.swim_v); + printf("S%u", sl->version.swim_v); printf("\n"); } From 79b225945b93a6306f374eb9438d78136d3fea8f Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Thu, 12 Nov 2020 22:39:49 +0200 Subject: [PATCH 1039/1435] link for WIN32 & APPLE with stlink-static --- CMakeLists.txt | 12 ++++++------ tests/CMakeLists.txt | 12 +++++++++--- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fae458dd7..824c3671e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,11 +155,7 @@ execute_process(COMMAND bash -c "export LD_LIBRARY_PATH=${CMAKE_INSTALL_LIBDIR}" ### # Set library name -if (NOT WIN32) - set(STLINK_LIB_SHARED ${PROJECT_NAME}) -else (WIN32) - set(STLINK_LIB_SHARED ${PROJECT_NAME}-shared) -endif () +set(STLINK_LIB_SHARED ${PROJECT_NAME}-shared) add_library(${STLINK_LIB_SHARED} SHARED ${STLINK_HEADERS} ${STLINK_SOURCE}) @@ -195,6 +191,10 @@ install(TARGETS ${STLINK_LIB_SHARED} DESTINATION ${STLINK_LIBRARY_PATH}) # Set library name set(STLINK_LIB_STATIC ${PROJECT_NAME}-static) +set(STLINK_LIB_STATIC_OUTPUT_NAME ${PROJECT_NAME}) +if (MSVC) + set(STLINK_LIB_STATIC_OUTPUT_NAME ${PROJECT_NAME}-static) +endif() add_library(${STLINK_LIB_STATIC} STATIC ${STLINK_HEADERS} ${STLINK_SOURCE}) @@ -206,7 +206,7 @@ message(STATUS "VERSION: ${STLINK_STATIC_VERSION}") set_target_properties(${STLINK_LIB_STATIC} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} VERSION ${STLINK_STATIC_VERSION} - OUTPUT_NAME ${PROJECT_NAME} + OUTPUT_NAME ${STLINK_LIB_STATIC_OUTPUT_NAME} ) # Link static library diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a3011fc7e..0f23214d6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -4,13 +4,19 @@ set(TESTEXEC usb sg) +set(TEST_DEPENDENCY ${STLINK_LIB_SHARED}) +if (WIN32 OR APPLE) + set(TEST_DEPENDENCY ${STLINK_LIB_STATIC}) +endif() + foreach (test ${TESTEXEC}) add_executable(test-${test} ${test}.c) - add_dependencies(test-${test} ${STLINK_LIB_SHARED}) - target_link_libraries(test-${test} ${STLINK_LIB_SHARED} ${SSP_LIB}) + add_dependencies(test-${test} ${TEST_DEPENDENCY}) + target_link_libraries(test-${test} ${TEST_DEPENDENCY} ${SSP_LIB}) add_test(test-${test} ${CMAKE_BINARY_DIR}/bin/test-${test}) endforeach () add_executable(test-flash flash.c "${CMAKE_SOURCE_DIR}/src/st-flash/flash_opts.c") -target_link_libraries(test-flash ${STLINK_LIB_SHARED} ${SSP_LIB}) +add_dependencies(test-flash ${TEST_DEPENDENCY}) +target_link_libraries(test-flash ${TEST_DEPENDENCY} ${SSP_LIB}) add_test(test-flash ${CMAKE_BINARY_DIR}/bin/test-flash) From 27d3144fce97ecf8ece522b96ad5c60eb8dc446d Mon Sep 17 00:00:00 2001 From: John Hall Date: Wed, 25 Nov 2020 10:51:20 -0800 Subject: [PATCH 1040/1435] Adding framework for st-trace. --- .gitignore | 1 + CMakeLists.txt | 5 ++ src/st-trace/trace.c | 143 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 src/st-trace/trace.c diff --git a/.gitignore b/.gitignore index 9fbe0139c..8b1dc465d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ build-mingw obj-* *.user* .cmake/ +*.swp diff --git a/CMakeLists.txt b/CMakeLists.txt index 824c3671e..08a889660 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -231,6 +231,7 @@ install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH}) set(ST-FLASH_SOURCES src/st-flash/flash.c src/st-flash/flash_opts.c) set(ST-INFO_SOURCES src/st-info/info.c) set(ST-UTIL_SOURCES src/st-util/gdb-remote.c src/st-util/gdb-server.c src/st-util/semihosting.c) +set(ST-TRACE_SOURCES src/st-trace/trace.c) if (MSVC) # Add getopt to sources @@ -241,20 +242,24 @@ endif () add_executable(st-flash ${ST-FLASH_SOURCES}) add_executable(st-info ${ST-INFO_SOURCES}) add_executable(st-util ${ST-UTIL_SOURCES}) +add_executable(st-trace ${ST-TRACE_SOURCES}) if (WIN32 OR APPLE) target_link_libraries(st-flash ${STLINK_LIB_STATIC} ${SSP_LIB}) target_link_libraries(st-info ${STLINK_LIB_STATIC} ${SSP_LIB}) target_link_libraries(st-util ${STLINK_LIB_STATIC} ${SSP_LIB}) + target_link_libraries(st-trace ${STLINK_LIB_STATIC} ${SSP_LIB}) else () target_link_libraries(st-flash ${STLINK_LIB_SHARED} ${SSP_LIB}) target_link_libraries(st-info ${STLINK_LIB_SHARED} ${SSP_LIB}) target_link_libraries(st-util ${STLINK_LIB_SHARED} ${SSP_LIB}) + target_link_libraries(st-trace ${STLINK_LIB_SHARED} ${SSP_LIB}) endif () install(TARGETS st-flash DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS st-info DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS st-util DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS st-trace DESTINATION ${CMAKE_INSTALL_BINDIR}) ### diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c new file mode 100644 index 000000000..d7ece29d4 --- /dev/null +++ b/src/st-trace/trace.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + + +#define DEFAULT_LOGGING_LEVEL 50 +#define DEBUG_LOGGING_LEVEL 100 + +#define APP_RESULT_SUCCESS 0 +#define APP_RESULT_INVALID_PARAMS 1 + + +struct _st_settings_t +{ + bool show_help; + bool show_version; + int logging_level; + int core_frequency_mhz; + bool reset_board; + char* serial_number; + bool wait_sync; +}; +typedef struct _st_settings_t st_settings_t; + + +static void usage(void) { + puts("st-trace - usage:"); + puts(" -h, --help Print this help"); + puts(" -V, --version Print this version"); + puts(" -vXX, --verbose=XX Specify a specific verbosity level (0..99)"); + puts(" -v, --verbose Specify a generally verbose logging"); + puts(" -cXX, --clock=XX Specify the core frequency in MHz"); + puts(" -n, --no-reset Do not reset board on connection"); + puts(" -sXX, --serial=XX Use a specific serial number"); + puts(" -a, --no-sync Do not wait for a sync packet"); +} + +bool parse_options(int argc, char** argv, st_settings_t *settings) { + + static struct option long_options[] = { + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'V'}, + {"verbose", optional_argument, NULL, 'v'}, + {"clock", required_argument, NULL, 'c'}, + {"no-reset", no_argument, NULL, 'n'}, + {"serial", required_argument, NULL, 's'}, + {"no-sync", no_argument, NULL, 'a'}, + {0, 0, 0, 0}, + }; + int option_index = 0; + int c; + + settings->show_help = false; + settings->show_version = false; + settings->logging_level = DEFAULT_LOGGING_LEVEL; + settings->core_frequency_mhz = 0; + settings->reset_board = true; + settings->serial_number = NULL; + settings->wait_sync = true; + + while ((c = getopt_long(argc, argv, "hVv::c:ns:a", long_options, &option_index)) != -1) { + switch (c) { + case 'h': + settings->show_help = true; + break; + case 'V': + settings->show_version = true; + break; + case 'v': + if (optarg) { + settings->logging_level = atoi(optarg); + } else { + settings->logging_level = DEBUG_LOGGING_LEVEL; + } + break; + case 'c': + settings->core_frequency_mhz = atoi(optarg); + break; + case 'n': + settings->reset_board = false; + break; + case 's': + settings->serial_number = optarg; + break; + case 'a': + settings->wait_sync = false; + break; + case '?': + return false; + break; + default: + printf("ERROR: Unknown command line option: '%c' (0x%02x)\n", c, c); + return false; + } + } + + if (optind < argc) { + while (optind < argc) { + printf("ERROR: Unknown command line argument: '%s'\n", argv[optind++]); + } + return false; + } + + return true; +} + +int main(int argc, char** argv) +{ + st_settings_t settings; + + if (!parse_options(argc, argv, &settings)) { + usage(); + return APP_RESULT_INVALID_PARAMS; + } + + /* if (settings.logging_level >= UDEBUG) */ + printf("show_help = %s\n", settings.show_help ? "true" : "false"); + printf("show_version = %s\n", settings.show_version ? "true" : "false"); + printf("logging_level = %d\n", settings.logging_level); + printf("core_frequency = %d MHz\n", settings.core_frequency_mhz); + printf("reset_board = %s\n", settings.reset_board ? "true" : "false"); + printf("serial_number = %s\n", settings.serial_number ? settings.serial_number : "any"); + printf("wait_sync = %s\n", settings.wait_sync ? "true" : "false"); + + if (settings.show_help) { + usage(); + return APP_RESULT_SUCCESS; + } + + if (settings.show_version) { + printf("v%s\n", STLINK_VERSION); + return APP_RESULT_SUCCESS; + } + + return APP_RESULT_SUCCESS; +} + From 0f411da1d75620e5b005643afaf7110cf25b2d70 Mon Sep 17 00:00:00 2001 From: John Hall Date: Wed, 25 Nov 2020 23:49:42 +0000 Subject: [PATCH 1041/1435] Getting to build on raspberry pi. Adding calls to identify st-links. --- raspberrypi-build.sh | 20 +++++++++++ src/st-trace/trace.c | 80 +++++++++++++++++++++++++++++++++----------- 2 files changed, 81 insertions(+), 19 deletions(-) create mode 100755 raspberrypi-build.sh diff --git a/raspberrypi-build.sh b/raspberrypi-build.sh new file mode 100755 index 000000000..7f77dab45 --- /dev/null +++ b/raspberrypi-build.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +mkdir -p build/raspberry +mkdir -p build/raspberry/inc +mkdir -p build/raspberry/bin + +cat << EOF > build/raspberry/inc/version.h +#ifndef STLINK_VERSION_H_ +#define STLINK_VERSION_H_ + +#define STLINK_VERSION "1.6.1-116-g27d3-pi-dirty" +#define STLINK_VERSION_MAJOR 1 +#define STLINK_VERSION_MINOR 6 +#define STLINK_VERSION_PATCH 1 + +#endif // STLINK_VERSION_H_ +EOF + +gcc -std=gnu99 -Iinc -Isrc/stlink-lib/ -I/usr/include/libusb-1.0/ -Ibuild/raspberry/inc -DLIBUSB_API_VERSION=MINIMAL_API_VERSION -DSTLINK_HAVE_SYS_MMAN_H src/*.c src/stlink-lib/*.c src/st-trace/*.c -lusb-1.0 -o build/raspberry/bin/st-trace + diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index d7ece29d4..03f1ac43d 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -12,8 +12,9 @@ #define DEFAULT_LOGGING_LEVEL 50 #define DEBUG_LOGGING_LEVEL 100 -#define APP_RESULT_SUCCESS 0 -#define APP_RESULT_INVALID_PARAMS 1 +#define APP_RESULT_SUCCESS 0 +#define APP_RESULT_INVALID_PARAMS 1 +#define APP_RESULT_STLINK_NOT_FOUND 2 struct _st_settings_t @@ -30,15 +31,15 @@ typedef struct _st_settings_t st_settings_t; static void usage(void) { - puts("st-trace - usage:"); - puts(" -h, --help Print this help"); - puts(" -V, --version Print this version"); - puts(" -vXX, --verbose=XX Specify a specific verbosity level (0..99)"); - puts(" -v, --verbose Specify a generally verbose logging"); - puts(" -cXX, --clock=XX Specify the core frequency in MHz"); - puts(" -n, --no-reset Do not reset board on connection"); - puts(" -sXX, --serial=XX Use a specific serial number"); - puts(" -a, --no-sync Do not wait for a sync packet"); + puts("st-trace - usage:"); + puts(" -h, --help Print this help"); + puts(" -V, --version Print this version"); + puts(" -vXX, --verbose=XX Specify a specific verbosity level (0..99)"); + puts(" -v, --verbose Specify a generally verbose logging"); + puts(" -cXX, --clock=XX Specify the core frequency in MHz"); + puts(" -n, --no-reset Do not reset board on connection"); + puts(" -sXX, --serial=XX Use a specific serial number"); + puts(" -a, --no-sync Do not wait for a sync packet"); } bool parse_options(int argc, char** argv, st_settings_t *settings) { @@ -110,6 +111,33 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { return true; } +static bool FindStLink(const st_settings_t* settings, stlink_t* link) { + stlink_t **stdevs; + size_t size; + bool result = false; + + size = stlink_probe_usb(&stdevs); + if (settings->logging_level >= UDEBUG) { + printf("Found %u stlink programmers\n", (unsigned int)size); + } + + if (!settings->serial_number && size > 0) { + *link = *stdevs[0]; + result = true; + } else { + for (size_t n = 0; n < size; n++) { + if (strncmp(stdevs[n]->serial, settings->serial_number, stdevs[n]->serial_size) == 0) { + *link = *stdevs[n]; + result = true; + } + } + } + + stlink_probe_usb_free(&stdevs, size); + + return result; +} + int main(int argc, char** argv) { st_settings_t settings; @@ -119,14 +147,15 @@ int main(int argc, char** argv) return APP_RESULT_INVALID_PARAMS; } - /* if (settings.logging_level >= UDEBUG) */ - printf("show_help = %s\n", settings.show_help ? "true" : "false"); - printf("show_version = %s\n", settings.show_version ? "true" : "false"); - printf("logging_level = %d\n", settings.logging_level); - printf("core_frequency = %d MHz\n", settings.core_frequency_mhz); - printf("reset_board = %s\n", settings.reset_board ? "true" : "false"); - printf("serial_number = %s\n", settings.serial_number ? settings.serial_number : "any"); - printf("wait_sync = %s\n", settings.wait_sync ? "true" : "false"); + if (settings.logging_level >= UDEBUG) { + printf("show_help = %s\n", settings.show_help ? "true" : "false"); + printf("show_version = %s\n", settings.show_version ? "true" : "false"); + printf("logging_level = %d\n", settings.logging_level); + printf("core_frequency = %d MHz\n", settings.core_frequency_mhz); + printf("reset_board = %s\n", settings.reset_board ? "true" : "false"); + printf("serial_number = %s\n", settings.serial_number ? settings.serial_number : "any"); + printf("wait_sync = %s\n", settings.wait_sync ? "true" : "false"); + } if (settings.show_help) { usage(); @@ -137,6 +166,19 @@ int main(int argc, char** argv) printf("v%s\n", STLINK_VERSION); return APP_RESULT_SUCCESS; } + + stlink_t link; + if (!FindStLink(&settings, &link)) { + if (settings.serial_number) { + printf("ERROR: Unable to locate st-link '%s'\n", settings.serial_number); + } else { + printf("ERROR: Unable to locate st-link\n"); + } + return APP_RESULT_STLINK_NOT_FOUND; + } + + + return APP_RESULT_SUCCESS; } From 5ad3bb9846c58086c9758aa5e1816b551473c422 Mon Sep 17 00:00:00 2001 From: John Hall Date: Wed, 25 Nov 2020 16:15:51 -0800 Subject: [PATCH 1042/1435] Separating out method to check if stlink is usable. Adding a log macro. Adding logs with stlink list. --- src/st-trace/trace.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 03f1ac43d..2fec00c8d 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -16,6 +16,8 @@ #define APP_RESULT_INVALID_PARAMS 1 #define APP_RESULT_STLINK_NOT_FOUND 2 +#define LOG(SETTINGS, LEVEL, ARGS...) if (settings->logging_level >= LEVEL) printf(ARGS) + struct _st_settings_t { @@ -111,25 +113,34 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { return true; } +static bool CompareStlink(const st_settings_t* settings, const stlink_t* link) { + if (!settings->serial_number) { + return true; + } + + if (strncmp(link->serial, settings->serial_number, link->serial_size) == 0) { + return true; + } + + return false; +} + static bool FindStLink(const st_settings_t* settings, stlink_t* link) { stlink_t **stdevs; size_t size; bool result = false; size = stlink_probe_usb(&stdevs); - if (settings->logging_level >= UDEBUG) { - printf("Found %u stlink programmers\n", (unsigned int)size); - } + LOG(settings, UDEBUG, "Found %u stlink programmers\n", (unsigned int)size); - if (!settings->serial_number && size > 0) { - *link = *stdevs[0]; - result = true; - } else { - for (size_t n = 0; n < size; n++) { - if (strncmp(stdevs[n]->serial, settings->serial_number, stdevs[n]->serial_size) == 0) { - *link = *stdevs[n]; - result = true; + for (size_t n = 0; n < size; n++) { + if (CompareStlink(settings, stdevs[n])) { + LOG(settings, UDEBUG, "Matching stlink '%*s'\n", stdevs[n]->serial_size, stdevs[n]->serial); + if (result) { + LOG(settings, UWARN, "WARNING: Multiple matching stlinks\n"); } + *link = *stdevs[n]; + result = true; } } From 4aed3205a8d014091662925329dcd4b46db0be6d Mon Sep 17 00:00:00 2001 From: John Hall Date: Thu, 26 Nov 2020 05:52:37 +0000 Subject: [PATCH 1043/1435] Fixed that serial numbers are stored as binary values. --- src/st-trace/trace.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 2fec00c8d..19ea1def2 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -113,12 +113,26 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { return true; } +static const char* GetSerialString(const stlink_t* link) { + const char kHexChars[16] = "0123456789abcdef"; + static char serial[2 * sizeof(link->serial) + 1]; + + size_t cursor = 0; + for (size_t n = 0; n < link->serial_size; n++) { + serial[cursor++] = kHexChars[(link->serial[n] >> 4) & 0x0f]; + serial[cursor++] = kHexChars[(link->serial[n] >> 0) & 0x0f]; + } + serial[cursor++] = 0; + + return serial; +} + static bool CompareStlink(const st_settings_t* settings, const stlink_t* link) { if (!settings->serial_number) { return true; } - if (strncmp(link->serial, settings->serial_number, link->serial_size) == 0) { + if (strncmp(GetSerialString(link), settings->serial_number, strlen(settings->serial_number)) == 0) { return true; } @@ -131,16 +145,17 @@ static bool FindStLink(const st_settings_t* settings, stlink_t* link) { bool result = false; size = stlink_probe_usb(&stdevs); - LOG(settings, UDEBUG, "Found %u stlink programmers\n", (unsigned int)size); + LOG(settings, UDEBUG, "Found %u stlink programmer(s)\n", (unsigned int)size); for (size_t n = 0; n < size; n++) { if (CompareStlink(settings, stdevs[n])) { - LOG(settings, UDEBUG, "Matching stlink '%*s'\n", stdevs[n]->serial_size, stdevs[n]->serial); + LOG(settings, UDEBUG, "Matching stlink '%s'\n", GetSerialString(stdevs[n])); if (result) { - LOG(settings, UWARN, "WARNING: Multiple matching stlinks\n"); + LOG(settings, UWARN, "WARNING: Multiple matching stlink programmers. Using '%s'\n", GetSerialString(link)); + } else { + *link = *stdevs[n]; + result = true; } - *link = *stdevs[n]; - result = true; } } From f5cc12ce331ec2ecd41b8838f279332bf1ebcc96 Mon Sep 17 00:00:00 2001 From: John Hall Date: Thu, 26 Nov 2020 05:59:27 +0000 Subject: [PATCH 1044/1435] Cleaning up logging a bit. --- src/st-trace/trace.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 19ea1def2..8f02a06f1 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -16,7 +16,7 @@ #define APP_RESULT_INVALID_PARAMS 1 #define APP_RESULT_STLINK_NOT_FOUND 2 -#define LOG(SETTINGS, LEVEL, ARGS...) if (settings->logging_level >= LEVEL) printf(ARGS) +#define LOG(SETTINGS, LEVEL, ARGS...) if ((SETTINGS)->logging_level >= (LEVEL)) printf(ARGS) struct _st_settings_t @@ -98,14 +98,14 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { return false; break; default: - printf("ERROR: Unknown command line option: '%c' (0x%02x)\n", c, c); + LOG(settings, UERROR, "ERROR: Unknown command line option: '%c' (0x%02x)\n", c, c); return false; } } if (optind < argc) { while (optind < argc) { - printf("ERROR: Unknown command line argument: '%s'\n", argv[optind++]); + LOG(settings, UERROR, "ERROR: Unknown command line argument: '%s'\n", argv[optind++]); } return false; } @@ -173,15 +173,13 @@ int main(int argc, char** argv) return APP_RESULT_INVALID_PARAMS; } - if (settings.logging_level >= UDEBUG) { - printf("show_help = %s\n", settings.show_help ? "true" : "false"); - printf("show_version = %s\n", settings.show_version ? "true" : "false"); - printf("logging_level = %d\n", settings.logging_level); - printf("core_frequency = %d MHz\n", settings.core_frequency_mhz); - printf("reset_board = %s\n", settings.reset_board ? "true" : "false"); - printf("serial_number = %s\n", settings.serial_number ? settings.serial_number : "any"); - printf("wait_sync = %s\n", settings.wait_sync ? "true" : "false"); - } + LOG(&settings, UDEBUG, "show_help = %s\n", settings.show_help ? "true" : "false"); + LOG(&settings, UDEBUG, "show_version = %s\n", settings.show_version ? "true" : "false"); + LOG(&settings, UDEBUG, "logging_level = %d\n", settings.logging_level); + LOG(&settings, UDEBUG, "core_frequency = %d MHz\n", settings.core_frequency_mhz); + LOG(&settings, UDEBUG, "reset_board = %s\n", settings.reset_board ? "true" : "false"); + LOG(&settings, UDEBUG, "serial_number = %s\n", settings.serial_number ? settings.serial_number : "any"); + LOG(&settings, UDEBUG, "wait_sync = %s\n", settings.wait_sync ? "true" : "false"); if (settings.show_help) { usage(); @@ -195,11 +193,7 @@ int main(int argc, char** argv) stlink_t link; if (!FindStLink(&settings, &link)) { - if (settings.serial_number) { - printf("ERROR: Unable to locate st-link '%s'\n", settings.serial_number); - } else { - printf("ERROR: Unable to locate st-link\n"); - } + LOG(&settings, UERROR, "ERROR: Unable to locate st-link\n"); return APP_RESULT_STLINK_NOT_FOUND; } From be8d86f6333da1dba6b94e2f22bc9788965177de Mon Sep 17 00:00:00 2001 From: John Hall Date: Thu, 26 Nov 2020 06:46:42 +0000 Subject: [PATCH 1045/1435] Fixing to use built in logging. --- src/st-trace/trace.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 8f02a06f1..0f651b0d8 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -16,8 +16,6 @@ #define APP_RESULT_INVALID_PARAMS 1 #define APP_RESULT_STLINK_NOT_FOUND 2 -#define LOG(SETTINGS, LEVEL, ARGS...) if ((SETTINGS)->logging_level >= (LEVEL)) printf(ARGS) - struct _st_settings_t { @@ -66,6 +64,7 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { settings->reset_board = true; settings->serial_number = NULL; settings->wait_sync = true; + ugly_init(settings->logging_level); while ((c = getopt_long(argc, argv, "hVv::c:ns:a", long_options, &option_index)) != -1) { switch (c) { @@ -81,6 +80,7 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { } else { settings->logging_level = DEBUG_LOGGING_LEVEL; } + ugly_init(settings->logging_level); break; case 'c': settings->core_frequency_mhz = atoi(optarg); @@ -98,14 +98,14 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { return false; break; default: - LOG(settings, UERROR, "ERROR: Unknown command line option: '%c' (0x%02x)\n", c, c); + ELOG("Unknown command line option: '%c' (0x%02x)\n", c, c); return false; } } if (optind < argc) { while (optind < argc) { - LOG(settings, UERROR, "ERROR: Unknown command line argument: '%s'\n", argv[optind++]); + ELOG("Unknown command line argument: '%s'\n", argv[optind++]); } return false; } @@ -145,13 +145,13 @@ static bool FindStLink(const st_settings_t* settings, stlink_t* link) { bool result = false; size = stlink_probe_usb(&stdevs); - LOG(settings, UDEBUG, "Found %u stlink programmer(s)\n", (unsigned int)size); + DLOG("Found %u stlink programmer(s)\n", (unsigned int)size); for (size_t n = 0; n < size; n++) { if (CompareStlink(settings, stdevs[n])) { - LOG(settings, UDEBUG, "Matching stlink '%s'\n", GetSerialString(stdevs[n])); + DLOG("Matching stlink '%s'\n", GetSerialString(stdevs[n])); if (result) { - LOG(settings, UWARN, "WARNING: Multiple matching stlink programmers. Using '%s'\n", GetSerialString(link)); + WLOG("Multiple matching stlink programmers. Using '%s'\n", GetSerialString(link)); } else { *link = *stdevs[n]; result = true; @@ -173,13 +173,13 @@ int main(int argc, char** argv) return APP_RESULT_INVALID_PARAMS; } - LOG(&settings, UDEBUG, "show_help = %s\n", settings.show_help ? "true" : "false"); - LOG(&settings, UDEBUG, "show_version = %s\n", settings.show_version ? "true" : "false"); - LOG(&settings, UDEBUG, "logging_level = %d\n", settings.logging_level); - LOG(&settings, UDEBUG, "core_frequency = %d MHz\n", settings.core_frequency_mhz); - LOG(&settings, UDEBUG, "reset_board = %s\n", settings.reset_board ? "true" : "false"); - LOG(&settings, UDEBUG, "serial_number = %s\n", settings.serial_number ? settings.serial_number : "any"); - LOG(&settings, UDEBUG, "wait_sync = %s\n", settings.wait_sync ? "true" : "false"); + DLOG("show_help = %s\n", settings.show_help ? "true" : "false"); + DLOG("show_version = %s\n", settings.show_version ? "true" : "false"); + DLOG("logging_level = %d\n", settings.logging_level); + DLOG("core_frequency = %d MHz\n", settings.core_frequency_mhz); + DLOG("reset_board = %s\n", settings.reset_board ? "true" : "false"); + DLOG("serial_number = %s\n", settings.serial_number ? settings.serial_number : "any"); + DLOG("wait_sync = %s\n", settings.wait_sync ? "true" : "false"); if (settings.show_help) { usage(); @@ -193,7 +193,7 @@ int main(int argc, char** argv) stlink_t link; if (!FindStLink(&settings, &link)) { - LOG(&settings, UERROR, "ERROR: Unable to locate st-link\n"); + ELOG("Unable to locate st-link\n"); return APP_RESULT_STLINK_NOT_FOUND; } From 2fd0ab86144c894979fd3271f898902696fd80e4 Mon Sep 17 00:00:00 2001 From: John Hall Date: Thu, 26 Nov 2020 16:28:43 +0000 Subject: [PATCH 1046/1435] Library already supported specifying which stlink to use. --- src/st-trace/trace.c | 68 ++++++++++---------------------------------- 1 file changed, 15 insertions(+), 53 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 0f651b0d8..0427d5760 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -113,60 +113,25 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { return true; } -static const char* GetSerialString(const stlink_t* link) { - const char kHexChars[16] = "0123456789abcdef"; - static char serial[2 * sizeof(link->serial) + 1]; - - size_t cursor = 0; - for (size_t n = 0; n < link->serial_size; n++) { - serial[cursor++] = kHexChars[(link->serial[n] >> 4) & 0x0f]; - serial[cursor++] = kHexChars[(link->serial[n] >> 0) & 0x0f]; - } - serial[cursor++] = 0; - - return serial; -} - -static bool CompareStlink(const st_settings_t* settings, const stlink_t* link) { - if (!settings->serial_number) { - return true; - } - - if (strncmp(GetSerialString(link), settings->serial_number, strlen(settings->serial_number)) == 0) { - return true; - } - - return false; -} - -static bool FindStLink(const st_settings_t* settings, stlink_t* link) { - stlink_t **stdevs; - size_t size; - bool result = false; - - size = stlink_probe_usb(&stdevs); - DLOG("Found %u stlink programmer(s)\n", (unsigned int)size); - - for (size_t n = 0; n < size; n++) { - if (CompareStlink(settings, stdevs[n])) { - DLOG("Matching stlink '%s'\n", GetSerialString(stdevs[n])); - if (result) { - WLOG("Multiple matching stlink programmers. Using '%s'\n", GetSerialString(link)); - } else { - *link = *stdevs[n]; - result = true; - } +static stlink_t* StLinkConnect(const st_settings_t* settings) { + if (settings->serial_number) { + char serial_number[STLINK_SERIAL_MAX_SIZE] = { 0 }; + size_t length = 0; + for (uint32_t n = 0; n < strlen(settings->serial_number) && length < STLINK_SERIAL_MAX_SIZE; n += 2) { + char buffer[3] = { 0 }; + memcpy(buffer, settings->serial_number + n, 2); + serial_number[length++] = (uint8_t)strtol(buffer, NULL, 16); } + return stlink_open_usb(settings->logging_level, false, serial_number, 0); + } else { + return stlink_open_usb(settings->logging_level, false, NULL, 0); } - - stlink_probe_usb_free(&stdevs, size); - - return result; } int main(int argc, char** argv) { st_settings_t settings; + stlink_t* link = NULL; if (!parse_options(argc, argv, &settings)) { usage(); @@ -191,15 +156,12 @@ int main(int argc, char** argv) return APP_RESULT_SUCCESS; } - stlink_t link; - if (!FindStLink(&settings, &link)) { + link = StLinkConnect(&settings); + if (!link) { ELOG("Unable to locate st-link\n"); return APP_RESULT_STLINK_NOT_FOUND; } - - - - + return APP_RESULT_SUCCESS; } From 380444a6fd8f4394374cb433f0e1b21f9807bebd Mon Sep 17 00:00:00 2001 From: John Hall Date: Fri, 27 Nov 2020 16:16:16 +0000 Subject: [PATCH 1047/1435] In progress. Added defines for trace debug commands. Added initial start trace method. --- src/st-trace/trace.c | 158 ++++++++++++++++++++++++++++++++++++-- src/stlink-lib/commands.h | 3 + 2 files changed, 154 insertions(+), 7 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 0427d5760..2f9bcc2ff 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -12,9 +12,12 @@ #define DEFAULT_LOGGING_LEVEL 50 #define DEBUG_LOGGING_LEVEL 100 -#define APP_RESULT_SUCCESS 0 -#define APP_RESULT_INVALID_PARAMS 1 -#define APP_RESULT_STLINK_NOT_FOUND 2 +#define APP_RESULT_SUCCESS 0 +#define APP_RESULT_INVALID_PARAMS 1 +#define APP_RESULT_STLINK_NOT_FOUND 2 +#define APP_RESULT_STLINK_MISSING_DEVICE 3 +#define APP_RESULT_STLINK_UNSUPPORTED_DEVICE 4 +#define APP_RESULT_STLINK_STATE_ERROR 5 struct _st_settings_t @@ -128,10 +131,122 @@ static stlink_t* StLinkConnect(const st_settings_t* settings) { } } +// TODO: Move this to device table. +static bool IsDeviceTraceSupported(int chip_id) { + switch (chip_id) { + case STLINK_CHIPID_STM32_F4: + case STLINK_CHIPID_STM32_F4_DSI: + case STLINK_CHIPID_STM32_F4_HD: + case STLINK_CHIPID_STM32_F4_LP: + case STLINK_CHIPID_STM32_F411RE: + case STLINK_CHIPID_STM32_F4_DE: + case STLINK_CHIPID_STM32_F446: + case STLINK_CHIPID_STM32_F410: + case STLINK_CHIPID_STM32_F3: + case STLINK_CHIPID_STM32_F37x: + case STLINK_CHIPID_STM32_F412: + case STLINK_CHIPID_STM32_F413: + case STLINK_CHIPID_STM32_F3_SMALL: + case STLINK_CHIPID_STM32_F334: + case STLINK_CHIPID_STM32_F303_HIGH: + return true; + default: + return false; + } +} + +static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_board) { + struct stlink_read_reg regp = {}; + + if (stlink_force_debug(stlink)) { + return false; + } + + if (reset_board && stlink_reset(stlink)) { + return false; + } + + // The remainder of the items in this function were taken directly from https://github.com/avrhack/stlink-trace/blob/master/stlink-trace.c#L386 + + // Set DHCSR to C_HALT and C_DEBUGEN + stlink_write_debug32(stlink, 0xE000EDF0, 0xA05F0003); + + // Set TRCENA flag to enable global DWT and ITM + stlink_write_debug32(stlink, 0xE000EDFC, 0x01000000); + + // Set FP_CTRL to enable write + stlink_write_debug32(stlink, 0xE0002000, 0x00000002); + + // Set DWT_FUNCTION0 to DWT_FUNCTION3 to disable sampling + stlink_write_debug32(stlink, 0xE0001028, 0x00000000); + stlink_write_debug32(stlink, 0xE0001038, 0x00000000); + stlink_write_debug32(stlink, 0xE0001048, 0x00000000); + stlink_write_debug32(stlink, 0xE0001058, 0x00000000); + + // Clear DWT_CTRL and other registers + stlink_write_debug32(stlink, 0xE0001000, 0x00000000); + stlink_write_debug32(stlink, 0xE0001004, 0x00000000); + stlink_write_debug32(stlink, 0xE0001008, 0x00000000); + stlink_write_debug32(stlink, 0xE000100C, 0x00000000); + stlink_write_debug32(stlink, 0xE0001010, 0x00000000); + stlink_write_debug32(stlink, 0xE0001014, 0x00000000); + stlink_write_debug32(stlink, 0xE0001018, 0x00000000); + + // We should be checking these regisers. + stlink_read_reg(stlink, 15, ®p); // Read program counter + stlink_read_reg(stlink, 16, ®p); // Read xpsr register + + // Set DBGMCU_CR to enable asynchronous transmission + stlink_write_debug32(stlink, 0xE0042004, 0x00000027); + + + // STLINK_DEBUG_APIV2_START_TRACE_RX + // ???? + unsigned char txBuffer3[] = {STLINK_DEBUG_COMMAND, 0x40, 0x00, 0x10, 0x80, 0x84, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + unsigned char rxBuffer3[100]; + SendAndReceive(&txBuffer3[0], 16, &rxBuffer3[0], 64); + + + + // Set TPIU_CSPSR to enable trace port width of 2 + stlink_write_debug32(stlink, 0xE0040004, 0x00000001); + + if (core_frequency_mhz) + // Set TPIU_ACPR clock divisor + stlink_write_debug32(stlink, 0xE0040010, core_frequency_mhz / 2 - 1); + + // Set TPIU_SPPR to Asynchronous SWO (NRZ) + stlink_write_debug32(stlink, 0xE00400F0, 0x00000002); + + // Set TPIU_FFCR continuous formatting) + stlink_write_debug32(stlink, 0xE0040304, 0x00000100); + + // Unlock the ITM registers for write + stlink_write_debug32(stlink, 0xE0000FB0, 0xC5ACCE55); + + // Set sync counter + stlink_write_debug32(stlink, 0xE0000E90, 0x00000400); + + // Set ITM_TCR flags : ITMENA,TSENA ATB=0 + stlink_write_debug32(stlink, 0xE0000E80, 0x00010003); + + // Enable all trace ports in ITM_TER + stlink_write_debug32(stlink, 0xE0000E00, 0xFFFFFFFF); + + // Enable unprivileged access to trace ports 31:0 in ITM_TPR + stlink_write_debug32(stlink, 0xE0000E40, 0x0000000F); + + // Set DWT_CTRL flags) + stlink_write_debug32(stlink, 0xE0000E40, 0x400003FE); // Keil one + + // Enable tracing (DEMCR - TRCENA bit) + stlink_write_debug32(stlink, 0xE000EDFC, 0x01000000); +} + int main(int argc, char** argv) { st_settings_t settings; - stlink_t* link = NULL; + stlink_t* stlink = NULL; if (!parse_options(argc, argv, &settings)) { usage(); @@ -156,12 +271,41 @@ int main(int argc, char** argv) return APP_RESULT_SUCCESS; } - link = StLinkConnect(&settings); - if (!link) { + stlink = StLinkConnect(&settings); + if (!stlink) { ELOG("Unable to locate st-link\n"); return APP_RESULT_STLINK_NOT_FOUND; } - + + if (stlink->chip_id == STLINK_CHIPID_UNKNOWN) { + ELOG("st-link not connected\n"); + return APP_RESULT_STLINK_MISSING_DEVICE; + } + + // TODO: Check if trace is supported by stlink. + + if (!IsDeviceTraceSupported(stlink->chip_id)) { + const struct stlink_chipid_params *params = stlink_chipid_get_params(stlink->chip_id); + ELOG("We do not support SWO output for device '%s'", params->description); + return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; + } + + if (!EnableTrace(stlink, settings.core_frequency_mhz, settings.reset_board)) { + ELOG("Unable to enable trace mode\n"); + return APP_RESULT_STLINK_STATE_ERROR; + } + + if (stlink_run(stlink)) { + ELOG("Unable to run device\n"); + return APP_RESULT_STLINK_STATE_ERROR; + } + + + // Read SWO output + + + stlink_close(stlink); + return APP_RESULT_SUCCESS; } diff --git a/src/stlink-lib/commands.h b/src/stlink-lib/commands.h index 0925e8e67..dac82b8e6 100644 --- a/src/stlink-lib/commands.h +++ b/src/stlink-lib/commands.h @@ -30,6 +30,9 @@ enum stlink_debug_commands { STLINK_DEBUG_APIV2_READALLREGS = 0x3A, STLINK_DEBUG_APIV2_GETLASTRWSTATUS = 0x3B, STLINK_DEBUG_APIV2_GETLASTRWSTATUS2 = 0x3E, + STLINK_DEBUG_APIV2_START_TRACE_RX = 0x40, + STLINK_DEBUG_APIV2_STOP_TRACE_RX = 0x41, + STLINK_DEBUG_APIV2_GET_TRACE_NB = 0x42, STLINK_DEBUG_ENTER_SWD = 0xa3 }; From 568b0d130a5f61e511b1063bcea68f2e0ad18c1c Mon Sep 17 00:00:00 2001 From: John Hall Date: Fri, 27 Nov 2020 09:37:50 -0800 Subject: [PATCH 1048/1435] Adding backend code to start/stop tracing and to read the incoming data. --- inc/backend.h | 4 +++ inc/stlink.h | 7 ++++ src/common.c | 16 +++++++++ src/st-trace/trace.c | 14 +++----- src/stlink-lib/sg.c | 5 ++- src/stlink-lib/usb.c | 83 +++++++++++++++++++++++++++++++++++++++++++- src/stlink-lib/usb.h | 1 + 7 files changed, 119 insertions(+), 11 deletions(-) diff --git a/inc/backend.h b/inc/backend.h index f852da05d..470702fde 100644 --- a/inc/backend.h +++ b/inc/backend.h @@ -29,6 +29,10 @@ int (*force_debug) (stlink_t *sl); int32_t (*target_voltage) (stlink_t *sl); int (*set_swdclk) (stlink_t * stl, uint16_t divisor); + int (*trace_enable) (stlink_t * sl); + int (*trace_disable) (stlink_t * sl); + int (*trace_read) (stlink_t * sl, uint8_t* buf, size_t size); + } stlink_backend_t; #endif // STLINK_BACKEND_H_ diff --git a/inc/stlink.h b/inc/stlink.h index 39f5f283c..e7aefbded 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -83,6 +83,9 @@ enum target_state { #define STLINK_V3_MAX_FREQ_NB 10 +#define STLINK_TRACE_BUF_LEN 4096 +#define STLINK_TRACE_FREQUENCY 2000000 + /* Cortex Debug Control Block */ #define DCB_DHCSR 0xE000EDF0 #define DCB_DCRSR 0xE000EDF4 @@ -261,6 +264,9 @@ int stlink_current_mode(stlink_t *sl); int stlink_force_debug(stlink_t *sl); int stlink_target_voltage(stlink_t *sl); int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); +int stlink_trace_enable(stlink_t* sl); +int stlink_trace_disable(stlink_t* sl); +int stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size); int stlink_erase_flash_mass(stlink_t* sl); int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); @@ -303,6 +309,7 @@ int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_contr int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); + #include #include #include diff --git a/src/common.c b/src/common.c index 32c00ad3b..e340ecc71 100644 --- a/src/common.c +++ b/src/common.c @@ -1677,6 +1677,21 @@ int stlink_current_mode(stlink_t *sl) { return(STLINK_DEV_UNKNOWN_MODE); } +int stlink_trace_enable(stlink_t* sl) { + DLOG("*** stlink_trace_enable ***\n"); + return(sl->backend->trace_enable(sl)); +} + +int stlink_trace_disable(stlink_t* sl) { + DLOG("*** stlink_trace_disable ***\n"); + return(sl->backend->trace_disable(sl)); +} + +int stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size) { + DLOG("*** stlink_trace_read ***\n"); + return(sl->backend->trace_read(sl, buf, size)); +} + // End of delegates.... Common code below here... @@ -4070,3 +4085,4 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr return(err); } + diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 2f9bcc2ff..0bbec903e 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -156,7 +156,6 @@ static bool IsDeviceTraceSupported(int chip_id) { } static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_board) { - struct stlink_read_reg regp = {}; if (stlink_force_debug(stlink)) { return false; @@ -193,20 +192,15 @@ static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_boa stlink_write_debug32(stlink, 0xE0001018, 0x00000000); // We should be checking these regisers. + struct stlink_reg regp = {}; stlink_read_reg(stlink, 15, ®p); // Read program counter stlink_read_reg(stlink, 16, ®p); // Read xpsr register // Set DBGMCU_CR to enable asynchronous transmission stlink_write_debug32(stlink, 0xE0042004, 0x00000027); - - // STLINK_DEBUG_APIV2_START_TRACE_RX - // ???? - unsigned char txBuffer3[] = {STLINK_DEBUG_COMMAND, 0x40, 0x00, 0x10, 0x80, 0x84, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - unsigned char rxBuffer3[100]; - SendAndReceive(&txBuffer3[0], 16, &rxBuffer3[0], 64); - - + // Actually start tracing. + stlink_trace_enable(stlink); // Set TPIU_CSPSR to enable trace port width of 2 stlink_write_debug32(stlink, 0xE0040004, 0x00000001); @@ -241,6 +235,8 @@ static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_boa // Enable tracing (DEMCR - TRCENA bit) stlink_write_debug32(stlink, 0xE000EDFC, 0x01000000); + + return true; } int main(int argc, char** argv) diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index 5cc27b1fe..f66864c44 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -944,7 +944,10 @@ static stlink_backend_t _stlink_sg_backend = { _stlink_sg_current_mode, _stlink_sg_force_debug, NULL, // target_voltage - NULL // set_swdclk + NULL, // set_swdclk + NULL, // trace_enable + NULL, // trace_disable + NULL, // trace_read }; static stlink_t* stlink_open(const int verbose) { diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 9726ddc4a..a7ebab0f3 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -972,6 +972,82 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { return(0); } +int _stlink_usb_enable_trace(stlink_t* sl) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + + int i = fill_command(sl, SG_DXFER_FROM_DEV, 0); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_APIV2_START_TRACE_RX; + write_uint16(&cmd[i + 0], STLINK_TRACE_BUF_LEN); + write_uint32(&cmd[i + 2], STLINK_TRACE_FREQUENCY); + + size = send_only(slu, 1, cmd, slu->cmd_len); + + if (size == -1) { + printf("[!] send_only STLINK_DEBUG_APIV2_START_TRACE_RX\n"); + return((int)size); + } + + return(0); +} + +int _stlink_usb_disable_trace(stlink_t* sl) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + + int i = fill_command(sl, SG_DXFER_FROM_DEV, 0); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_APIV2_STOP_TRACE_RX; + + size = send_only(slu, 1, cmd, slu->cmd_len); + + if (size == -1) { + printf("[!] send_only STLINK_DEBUG_APIV2_STOP_TRACE_RX\n"); + return((int)size); + } + + return(0); +} + +int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + 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_APIV2_GET_TRACE_NB; + ssize_t send_size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + + if (send_size == -1) { + printf("[!] send_recv STLINK_DEBUG_APIV2_GET_TRACE_NB\n"); + return((int)send_size); + } + + stlink_print_data(sl); + size_t trace_count = read_uint16(sl->q_buf, 0); + DLOG("trace_count = 0x%08x\n", trace_count); + + if (trace_count > size) { + ELOG("read_trace insufficient buffer length\n"); + return -1; + } + + int res = 0; + int t = libusb_bulk_transfer(slu->usb_handle, slu->ep_trace, buf, trace_count, &res, 3000); + + if (t) { + ELOG("read_trace read error\n"); + return(-1); + } + + return trace_count; +} + static stlink_backend_t _stlink_usb_backend = { _stlink_usb_close, _stlink_usb_exit_debug_mode, @@ -999,7 +1075,10 @@ static stlink_backend_t _stlink_usb_backend = { _stlink_usb_current_mode, _stlink_usb_force_debug, _stlink_usb_target_voltage, - _stlink_usb_set_swdclk + _stlink_usb_set_swdclk, + _stlink_usb_enable_trace, + _stlink_usb_disable_trace, + _stlink_usb_read_trace }; stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq) { @@ -1161,8 +1240,10 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID || desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID) { slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; + slu->ep_trace = 2 | LIBUSB_ENDPOINT_IN; } else { slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; + slu->ep_trace = 3 | LIBUSB_ENDPOINT_IN; } slu->sg_transfer_idx = 0; diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index d11f17381..717a82f6d 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -53,6 +53,7 @@ struct stlink_libusb { libusb_device_handle* usb_handle; unsigned int ep_req; unsigned int ep_rep; + unsigned int ep_trace; int protocoll; unsigned int sg_transfer_idx; unsigned int cmd_len; From 2900571f95cfaf7880b9bba0008e56fb07bea09a Mon Sep 17 00:00:00 2001 From: John Hall Date: Sat, 28 Nov 2020 17:02:49 +0000 Subject: [PATCH 1049/1435] In progress. --- src/st-trace/trace.c | 57 ++++++++++++++++++++++++-------------------- src/stlink-lib/usb.c | 4 ++-- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 0bbec903e..2918fd61e 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -155,6 +155,11 @@ static bool IsDeviceTraceSupported(int chip_id) { } } +static void Write32(stlink_t* stlink, uint32_t address, uint32_t data) { + write_uint32(stlink->q_buf, data); + stlink_write_mem32(stlink, address, 4); +} + static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_board) { if (stlink_force_debug(stlink)) { @@ -168,28 +173,28 @@ static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_boa // The remainder of the items in this function were taken directly from https://github.com/avrhack/stlink-trace/blob/master/stlink-trace.c#L386 // Set DHCSR to C_HALT and C_DEBUGEN - stlink_write_debug32(stlink, 0xE000EDF0, 0xA05F0003); + Write32(stlink, 0xE000EDF0, 0xA05F0003); // Set TRCENA flag to enable global DWT and ITM - stlink_write_debug32(stlink, 0xE000EDFC, 0x01000000); + Write32(stlink, 0xE000EDFC, 0x01000000); // Set FP_CTRL to enable write - stlink_write_debug32(stlink, 0xE0002000, 0x00000002); + Write32(stlink, 0xE0002000, 0x00000002); // Set DWT_FUNCTION0 to DWT_FUNCTION3 to disable sampling - stlink_write_debug32(stlink, 0xE0001028, 0x00000000); - stlink_write_debug32(stlink, 0xE0001038, 0x00000000); - stlink_write_debug32(stlink, 0xE0001048, 0x00000000); - stlink_write_debug32(stlink, 0xE0001058, 0x00000000); + Write32(stlink, 0xE0001028, 0x00000000); + Write32(stlink, 0xE0001038, 0x00000000); + Write32(stlink, 0xE0001048, 0x00000000); + Write32(stlink, 0xE0001058, 0x00000000); // Clear DWT_CTRL and other registers - stlink_write_debug32(stlink, 0xE0001000, 0x00000000); - stlink_write_debug32(stlink, 0xE0001004, 0x00000000); - stlink_write_debug32(stlink, 0xE0001008, 0x00000000); - stlink_write_debug32(stlink, 0xE000100C, 0x00000000); - stlink_write_debug32(stlink, 0xE0001010, 0x00000000); - stlink_write_debug32(stlink, 0xE0001014, 0x00000000); - stlink_write_debug32(stlink, 0xE0001018, 0x00000000); + Write32(stlink, 0xE0001000, 0x00000000); + Write32(stlink, 0xE0001004, 0x00000000); + Write32(stlink, 0xE0001008, 0x00000000); + Write32(stlink, 0xE000100C, 0x00000000); + Write32(stlink, 0xE0001010, 0x00000000); + Write32(stlink, 0xE0001014, 0x00000000); + Write32(stlink, 0xE0001018, 0x00000000); // We should be checking these regisers. struct stlink_reg regp = {}; @@ -197,44 +202,44 @@ static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_boa stlink_read_reg(stlink, 16, ®p); // Read xpsr register // Set DBGMCU_CR to enable asynchronous transmission - stlink_write_debug32(stlink, 0xE0042004, 0x00000027); + Write32(stlink, 0xE0042004, 0x00000027); // Actually start tracing. stlink_trace_enable(stlink); // Set TPIU_CSPSR to enable trace port width of 2 - stlink_write_debug32(stlink, 0xE0040004, 0x00000001); + Write32(stlink, 0xE0040004, 0x00000001); if (core_frequency_mhz) // Set TPIU_ACPR clock divisor - stlink_write_debug32(stlink, 0xE0040010, core_frequency_mhz / 2 - 1); + Write32(stlink, 0xE0040010, core_frequency_mhz / 2 - 1); // Set TPIU_SPPR to Asynchronous SWO (NRZ) - stlink_write_debug32(stlink, 0xE00400F0, 0x00000002); + Write32(stlink, 0xE00400F0, 0x00000002); // Set TPIU_FFCR continuous formatting) - stlink_write_debug32(stlink, 0xE0040304, 0x00000100); + Write32(stlink, 0xE0040304, 0x00000100); // Unlock the ITM registers for write - stlink_write_debug32(stlink, 0xE0000FB0, 0xC5ACCE55); + Write32(stlink, 0xE0000FB0, 0xC5ACCE55); // Set sync counter - stlink_write_debug32(stlink, 0xE0000E90, 0x00000400); + Write32(stlink, 0xE0000E90, 0x00000400); // Set ITM_TCR flags : ITMENA,TSENA ATB=0 - stlink_write_debug32(stlink, 0xE0000E80, 0x00010003); + Write32(stlink, 0xE0000E80, 0x00010003); // Enable all trace ports in ITM_TER - stlink_write_debug32(stlink, 0xE0000E00, 0xFFFFFFFF); + Write32(stlink, 0xE0000E00, 0xFFFFFFFF); // Enable unprivileged access to trace ports 31:0 in ITM_TPR - stlink_write_debug32(stlink, 0xE0000E40, 0x0000000F); + Write32(stlink, 0xE0000E40, 0x0000000F); // Set DWT_CTRL flags) - stlink_write_debug32(stlink, 0xE0000E40, 0x400003FE); // Keil one + Write32(stlink, 0xE0000E40, 0x400003FE); // Keil one // Enable tracing (DEMCR - TRCENA bit) - stlink_write_debug32(stlink, 0xE000EDFC, 0x01000000); + Write32(stlink, 0xE000EDFC, 0x01000000); return true; } diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index a7ebab0f3..a5d2c3678 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -977,7 +977,7 @@ int _stlink_usb_enable_trace(stlink_t* sl) { unsigned char* const cmd = sl->c_buf; ssize_t size; - int i = fill_command(sl, SG_DXFER_FROM_DEV, 0); + int i = fill_command(sl, SG_DXFER_TO_DEV, 0); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_START_TRACE_RX; write_uint16(&cmd[i + 0], STLINK_TRACE_BUF_LEN); @@ -998,7 +998,7 @@ int _stlink_usb_disable_trace(stlink_t* sl) { unsigned char* const cmd = sl->c_buf; ssize_t size; - int i = fill_command(sl, SG_DXFER_FROM_DEV, 0); + int i = fill_command(sl, SG_DXFER_TO_DEV, 0); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_STOP_TRACE_RX; From 737894cbe080da25c20b451298cfaadf8b0fc0fa Mon Sep 17 00:00:00 2001 From: John Hall Date: Sat, 28 Nov 2020 20:58:54 -0800 Subject: [PATCH 1050/1435] Got basic trace data transfer working. Still needs to decode the data stream. --- raspberrypi-build.sh | 20 -------- src/st-trace/trace.c | 114 ++++++++++++++++++++++++++----------------- src/stlink-lib/usb.c | 35 +++++++++---- 3 files changed, 93 insertions(+), 76 deletions(-) delete mode 100755 raspberrypi-build.sh diff --git a/raspberrypi-build.sh b/raspberrypi-build.sh deleted file mode 100755 index 7f77dab45..000000000 --- a/raspberrypi-build.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -mkdir -p build/raspberry -mkdir -p build/raspberry/inc -mkdir -p build/raspberry/bin - -cat << EOF > build/raspberry/inc/version.h -#ifndef STLINK_VERSION_H_ -#define STLINK_VERSION_H_ - -#define STLINK_VERSION "1.6.1-116-g27d3-pi-dirty" -#define STLINK_VERSION_MAJOR 1 -#define STLINK_VERSION_MINOR 6 -#define STLINK_VERSION_PATCH 1 - -#endif // STLINK_VERSION_H_ -EOF - -gcc -std=gnu99 -Iinc -Isrc/stlink-lib/ -I/usr/include/libusb-1.0/ -Ibuild/raspberry/inc -DLIBUSB_API_VERSION=MINIMAL_API_VERSION -DSTLINK_HAVE_SYS_MMAN_H src/*.c src/stlink-lib/*.c src/st-trace/*.c -lusb-1.0 -o build/raspberry/bin/st-trace - diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 2918fd61e..9146dd2bc 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include #include #include @@ -20,6 +23,9 @@ #define APP_RESULT_STLINK_STATE_ERROR 5 +static bool g_done = false; + + struct _st_settings_t { bool show_help; @@ -45,6 +51,10 @@ static void usage(void) { puts(" -a, --no-sync Do not wait for a sync packet"); } +static void cleanup() { + g_done = true; +} + bool parse_options(int argc, char** argv, st_settings_t *settings) { static struct option long_options[] = { @@ -161,6 +171,7 @@ static void Write32(stlink_t* stlink, uint32_t address, uint32_t data) { } static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_board) { + struct stlink_reg regp = {}; if (stlink_force_debug(stlink)) { return false; @@ -172,23 +183,14 @@ static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_boa // The remainder of the items in this function were taken directly from https://github.com/avrhack/stlink-trace/blob/master/stlink-trace.c#L386 - // Set DHCSR to C_HALT and C_DEBUGEN - Write32(stlink, 0xE000EDF0, 0xA05F0003); - - // Set TRCENA flag to enable global DWT and ITM - Write32(stlink, 0xE000EDFC, 0x01000000); - - // Set FP_CTRL to enable write - Write32(stlink, 0xE0002000, 0x00000002); - - // Set DWT_FUNCTION0 to DWT_FUNCTION3 to disable sampling - Write32(stlink, 0xE0001028, 0x00000000); + Write32(stlink, 0xE000EDF0, 0xA05F0003); // Set DHCSR to C_HALT and C_DEBUGEN + Write32(stlink, 0xE000EDFC, 0x01000000); // Set TRCENA flag to enable global DWT and ITM + Write32(stlink, 0xE0002000, 0x00000002); // Set FP_CTRL to enable write + Write32(stlink, 0xE0001028, 0x00000000); // Set DWT_FUNCTION0 to DWT_FUNCTION3 to disable sampling Write32(stlink, 0xE0001038, 0x00000000); Write32(stlink, 0xE0001048, 0x00000000); Write32(stlink, 0xE0001058, 0x00000000); - - // Clear DWT_CTRL and other registers - Write32(stlink, 0xE0001000, 0x00000000); + Write32(stlink, 0xE0001000, 0x00000000); // Clear DWT_CTRL and other registers Write32(stlink, 0xE0001004, 0x00000000); Write32(stlink, 0xE0001008, 0x00000000); Write32(stlink, 0xE000100C, 0x00000000); @@ -196,50 +198,60 @@ static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_boa Write32(stlink, 0xE0001014, 0x00000000); Write32(stlink, 0xE0001018, 0x00000000); - // We should be checking these regisers. - struct stlink_reg regp = {}; stlink_read_reg(stlink, 15, ®p); // Read program counter stlink_read_reg(stlink, 16, ®p); // Read xpsr register - // Set DBGMCU_CR to enable asynchronous transmission - Write32(stlink, 0xE0042004, 0x00000027); + Write32(stlink, 0xE0042004, 0x00000027); // Set DBGMCU_CR to enable asynchronous transmission // Actually start tracing. - stlink_trace_enable(stlink); - - // Set TPIU_CSPSR to enable trace port width of 2 - Write32(stlink, 0xE0040004, 0x00000001); + if (stlink_trace_enable(stlink)) { + return false; + } - if (core_frequency_mhz) - // Set TPIU_ACPR clock divisor - Write32(stlink, 0xE0040010, core_frequency_mhz / 2 - 1); + Write32(stlink, 0xE0040004, 0x00000001); // Set TPIU_CSPSR to enable trace port width of 2 - // Set TPIU_SPPR to Asynchronous SWO (NRZ) - Write32(stlink, 0xE00400F0, 0x00000002); + if (core_frequency_mhz) { + uint32_t clock_divisor = core_frequency_mhz / 2 - 1; + Write32(stlink, 0xE0040010, clock_divisor); // Set TPIU_ACPR clock divisor + } - // Set TPIU_FFCR continuous formatting) - Write32(stlink, 0xE0040304, 0x00000100); + Write32(stlink, 0xE00400F0, 0x00000002); // Set TPIU_SPPR to Asynchronous SWO (NRZ) + Write32(stlink, 0xE0040304, 0x00000100); // Set TPIU_FFCR continuous formatting) + Write32(stlink, 0xE0000FB0, 0xC5ACCE55); // Unlock the ITM registers for write + Write32(stlink, 0xE0000E90, 0x00000400); // Set sync counter + Write32(stlink, 0xE0000E80, 0x00010003); // Set ITM_TCR flags : ITMENA,TSENA ATB=0 + Write32(stlink, 0xE0000E00, 0xFFFFFFFF); // Enable all trace ports in ITM_TER + Write32(stlink, 0xE0000E40, 0x0000000F); // Enable unprivileged access to trace ports 31:0 in ITM_TPR + Write32(stlink, 0xE0000E40, 0x400003FE); // Set DWT_CTRL flags) + Write32(stlink, 0xE000EDFC, 0x01000000); // Enable tracing (DEMCR - TRCENA bit) - // Unlock the ITM registers for write - Write32(stlink, 0xE0000FB0, 0xC5ACCE55); + return true; +} - // Set sync counter - Write32(stlink, 0xE0000E90, 0x00000400); +static bool ReadTrace(stlink_t* stlink) { + uint8_t buffer[STLINK_TRACE_BUF_LEN]; + int length = stlink_trace_read(stlink, buffer, sizeof(buffer)); - // Set ITM_TCR flags : ITMENA,TSENA ATB=0 - Write32(stlink, 0xE0000E80, 0x00010003); + if (length < 0) { + ELOG("Error reading trace (%d)\n", length); + return false; + } - // Enable all trace ports in ITM_TER - Write32(stlink, 0xE0000E00, 0xFFFFFFFF); + if (length == 0) { + usleep(1000); + return true; + } - // Enable unprivileged access to trace ports 31:0 in ITM_TPR - Write32(stlink, 0xE0000E40, 0x0000000F); + DLOG("Trace Length: %d\n", length); - // Set DWT_CTRL flags) - Write32(stlink, 0xE0000E40, 0x400003FE); // Keil one + printf("Data: "); + for (int i = 0; i < length; i++) + printf("%02x ", buffer[i]); + printf(" '"); + for (int i = 0; i < length; i++) + printf("%c", isprint(buffer[i]) ? buffer[i] : '?'); + printf("'\n"); - // Enable tracing (DEMCR - TRCENA bit) - Write32(stlink, 0xE000EDFC, 0x01000000); return true; } @@ -249,6 +261,10 @@ int main(int argc, char** argv) st_settings_t settings; stlink_t* stlink = NULL; + signal(SIGINT, &cleanup); + signal(SIGTERM, &cleanup); + signal(SIGSEGV, &cleanup); + if (!parse_options(argc, argv, &settings)) { usage(); return APP_RESULT_INVALID_PARAMS; @@ -278,6 +294,8 @@ int main(int argc, char** argv) return APP_RESULT_STLINK_NOT_FOUND; } + stlink->verbose = settings.logging_level; + if (stlink->chip_id == STLINK_CHIPID_UNKNOWN) { ELOG("st-link not connected\n"); return APP_RESULT_STLINK_MISSING_DEVICE; @@ -295,16 +313,20 @@ int main(int argc, char** argv) ELOG("Unable to enable trace mode\n"); return APP_RESULT_STLINK_STATE_ERROR; } - + if (stlink_run(stlink)) { ELOG("Unable to run device\n"); return APP_RESULT_STLINK_STATE_ERROR; } + ILOG("Reading SWO Data\n"); - // Read SWO output - + while (!g_done) { + if (!ReadTrace(stlink)) + g_done = true; + } + stlink_trace_disable(stlink); stlink_close(stlink); return APP_RESULT_SUCCESS; diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index a5d2c3678..4d8d78a65 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -974,41 +974,51 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { int _stlink_usb_enable_trace(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; + uint32_t rep_len = 2; - int i = fill_command(sl, SG_DXFER_TO_DEV, 0); + int i = fill_command(sl, SG_DXFER_TO_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_START_TRACE_RX; write_uint16(&cmd[i + 0], STLINK_TRACE_BUF_LEN); write_uint32(&cmd[i + 2], STLINK_TRACE_FREQUENCY); - size = send_only(slu, 1, cmd, slu->cmd_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_only STLINK_DEBUG_APIV2_START_TRACE_RX\n"); return((int)size); } + sl->q_len = (int)size; + stlink_print_data(sl); + return(0); } int _stlink_usb_disable_trace(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; + uint32_t rep_len = 2; - int i = fill_command(sl, SG_DXFER_TO_DEV, 0); + int i = fill_command(sl, SG_DXFER_TO_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_STOP_TRACE_RX; - size = send_only(slu, 1, cmd, slu->cmd_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_only STLINK_DEBUG_APIV2_STOP_TRACE_RX\n"); return((int)size); } + sl->q_len = (int)size; + stlink_print_data(sl); + return(0); } @@ -1027,8 +1037,11 @@ int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { printf("[!] send_recv STLINK_DEBUG_APIV2_GET_TRACE_NB\n"); return((int)send_size); } + if (send_size != 2) { + printf("[!] send_recv STLINK_DEBUG_APIV2_GET_TRACE_NB %d\n", (int)send_size); + return -1; + } - stlink_print_data(sl); size_t trace_count = read_uint16(sl->q_buf, 0); DLOG("trace_count = 0x%08x\n", trace_count); @@ -1037,12 +1050,14 @@ int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { return -1; } - int res = 0; - int t = libusb_bulk_transfer(slu->usb_handle, slu->ep_trace, buf, trace_count, &res, 3000); + if (trace_count != 0) { + int res = 0; + int t = libusb_bulk_transfer(slu->usb_handle, slu->ep_trace, buf, trace_count, &res, 3000); - if (t) { - ELOG("read_trace read error\n"); - return(-1); + if (t) { + ELOG("read_trace read error\n"); + return(-1); + } } return trace_count; From 9c86d53341e2dd1a8b168d79bc53ccf45008638a Mon Sep 17 00:00:00 2001 From: John Hall Date: Sat, 28 Nov 2020 23:47:29 -0800 Subject: [PATCH 1051/1435] Added a state machine to parse trace output. Improved comments. --- src/st-trace/trace.c | 134 +++++++++++++++++++++++++++++++++---------- 1 file changed, 103 insertions(+), 31 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 9146dd2bc..ccb1a4828 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -15,30 +15,63 @@ #define DEFAULT_LOGGING_LEVEL 50 #define DEBUG_LOGGING_LEVEL 100 -#define APP_RESULT_SUCCESS 0 -#define APP_RESULT_INVALID_PARAMS 1 -#define APP_RESULT_STLINK_NOT_FOUND 2 -#define APP_RESULT_STLINK_MISSING_DEVICE 3 -#define APP_RESULT_STLINK_UNSUPPORTED_DEVICE 4 -#define APP_RESULT_STLINK_STATE_ERROR 5 - - +#define APP_RESULT_SUCCESS 0 +#define APP_RESULT_INVALID_PARAMS 1 +#define APP_RESULT_STLINK_NOT_FOUND 2 +#define APP_RESULT_STLINK_MISSING_DEVICE 3 +#define APP_RESULT_STLINK_UNSUPPORTED_DEVICE 4 +#define APP_RESULT_STLINK_STATE_ERROR 5 + +// See https://developer.arm.com/documentation/ddi0403/ed/ +#define TRACE_OP_IS_OVERFLOW(c) ((c) == 0x70) +#define TRACE_OP_IS_LOCAL_TIME(c) (((c) & 0x0f) == 0x00 && ((c) & 0x70) != 0x00) +#define TRACE_OP_IS_EXTENSION(c) (((c) & 0x0b) == 0x08) +#define TRACE_OP_IS_GLOBAL_TIME(c) (((c) & 0xdf) == 0x94) +#define TRACE_OP_IS_SOURCE(c) (((c) & 0x03) != 0x00) +#define TRACE_OP_IS_SW_SOURCE(c) (((c) & 0x03) != 0x00 && ((c) & 0x04) == 0x00) +#define TRACE_OP_IS_HW_SOURCE(c) (((c) & 0x03) != 0x00 && ((c) & 0x04) == 0x04) +#define TRACE_OP_IS_TARGET_SOURCE(c) ((c) == 0x01) + +#define TRACE_OP_GET_CONTINUATION(c) ((c) & 0x80) +#define TRACE_OP_GET_SOURCE_SIZE(c) ((c) & 0x03) +#define TRACE_OP_GET_SW_SOURCE_ADDR(c) ((c) >> 3) + + +// We use a global flag to allow communicating to the main thread from the signal handler. static bool g_done = false; -struct _st_settings_t -{ +struct _st_settings_t { bool show_help; bool show_version; int logging_level; int core_frequency_mhz; bool reset_board; char* serial_number; - bool wait_sync; }; typedef struct _st_settings_t st_settings_t; +// We use a simple state machine to parse the trace data. +enum _trace_step { + TRACE_STEP_IDLE, + TRACE_STEP_TARGET_SOURCE, + TRACE_STEP_SKIP_FRAME, + TRACE_STEP_SKIP_4, + TRACE_STEP_SKIP_3, + TRACE_STEP_SKIP_2, + TRACE_STEP_SKIP_1, +}; +typedef enum _trace_step trace_step; + +struct _st_trace_state_t { + trace_step step; + bool overflow; + bool error; +}; +typedef struct _st_trace_state_t st_trace_state_t; + + static void usage(void) { puts("st-trace - usage:"); puts(" -h, --help Print this help"); @@ -48,7 +81,6 @@ static void usage(void) { puts(" -cXX, --clock=XX Specify the core frequency in MHz"); puts(" -n, --no-reset Do not reset board on connection"); puts(" -sXX, --serial=XX Use a specific serial number"); - puts(" -a, --no-sync Do not wait for a sync packet"); } static void cleanup() { @@ -64,7 +96,6 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { {"clock", required_argument, NULL, 'c'}, {"no-reset", no_argument, NULL, 'n'}, {"serial", required_argument, NULL, 's'}, - {"no-sync", no_argument, NULL, 'a'}, {0, 0, 0, 0}, }; int option_index = 0; @@ -76,10 +107,9 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { settings->core_frequency_mhz = 0; settings->reset_board = true; settings->serial_number = NULL; - settings->wait_sync = true; ugly_init(settings->logging_level); - while ((c = getopt_long(argc, argv, "hVv::c:ns:a", long_options, &option_index)) != -1) { + while ((c = getopt_long(argc, argv, "hVv::c:ns:", long_options, &option_index)) != -1) { switch (c) { case 'h': settings->show_help = true; @@ -104,9 +134,6 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { case 's': settings->serial_number = optarg; break; - case 'a': - settings->wait_sync = false; - break; case '?': return false; break; @@ -128,6 +155,7 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { static stlink_t* StLinkConnect(const st_settings_t* settings) { if (settings->serial_number) { + // Convert our serial number string to a binary value. char serial_number[STLINK_SERIAL_MAX_SIZE] = { 0 }; size_t length = 0; for (uint32_t n = 0; n < strlen(settings->serial_number) && length < STLINK_SERIAL_MAX_SIZE; n += 2) { @@ -135,13 +163,16 @@ static stlink_t* StLinkConnect(const st_settings_t* settings) { memcpy(buffer, settings->serial_number + n, 2); serial_number[length++] = (uint8_t)strtol(buffer, NULL, 16); } + + // Open this specific stlink. return stlink_open_usb(settings->logging_level, false, serial_number, 0); } else { + // Otherwise, open any stlink. return stlink_open_usb(settings->logging_level, false, NULL, 0); } } -// TODO: Move this to device table. +// TODO: Consider moving this to the device table. static bool IsDeviceTraceSupported(int chip_id) { switch (chip_id) { case STLINK_CHIPID_STM32_F4: @@ -228,7 +259,7 @@ static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_boa return true; } -static bool ReadTrace(stlink_t* stlink) { +static bool ReadTrace(stlink_t* stlink, st_trace_state_t* state) { uint8_t buffer[STLINK_TRACE_BUF_LEN]; int length = stlink_trace_read(stlink, buffer, sizeof(buffer)); @@ -244,14 +275,55 @@ static bool ReadTrace(stlink_t* stlink) { DLOG("Trace Length: %d\n", length); - printf("Data: "); - for (int i = 0; i < length; i++) - printf("%02x ", buffer[i]); - printf(" '"); - for (int i = 0; i < length; i++) - printf("%c", isprint(buffer[i]) ? buffer[i] : '?'); - printf("'\n"); - + for (int i = 0; i < length; i++) { + uint8_t c = buffer[i]; + + // Parse the input using a state machine. + switch (state->step) + { + case TRACE_STEP_IDLE: + if (TRACE_OP_IS_TARGET_SOURCE(c)) { + state->step = TRACE_STEP_TARGET_SOURCE; + } else if (TRACE_OP_IS_SOURCE(c)) { + const trace_step kSourceSkip[] = { TRACE_STEP_IDLE, TRACE_STEP_SKIP_1, TRACE_STEP_SKIP_2, TRACE_STEP_SKIP_4 }; + const char* type = TRACE_OP_IS_SW_SOURCE(c) ? "sw" : "hw"; + uint8_t addr = TRACE_OP_GET_SW_SOURCE_ADDR(c); + uint8_t size = TRACE_OP_GET_SOURCE_SIZE(c); + WLOG("Unsupported %s source 0x%x size %d", type, addr, size); + state->step = kSourceSkip[size]; + } else if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_EXTENSION(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { + if (TRACE_OP_GET_CONTINUATION(c)) + state->step = TRACE_STEP_SKIP_FRAME; + } else if (TRACE_OP_IS_OVERFLOW(c)) { + state->overflow = true; + } else { + WLOG("Unknown opcode 0x%02x\n", c); + if (TRACE_OP_GET_CONTINUATION(c)) + state->step = TRACE_STEP_SKIP_FRAME; + } + break; + case TRACE_STEP_TARGET_SOURCE: + putchar(c); + state->step = TRACE_STEP_IDLE; + break; + case TRACE_STEP_SKIP_FRAME: + if (TRACE_OP_GET_CONTINUATION(c) == 0) + state->step = TRACE_STEP_IDLE; + break; + case TRACE_STEP_SKIP_4: + state->step = TRACE_STEP_SKIP_3; + break; + case TRACE_STEP_SKIP_3: + state->step = TRACE_STEP_SKIP_2; + break; + case TRACE_STEP_SKIP_2: + state->step = TRACE_STEP_SKIP_1; + break; + case TRACE_STEP_SKIP_1: + state->step = TRACE_STEP_IDLE; + break; + } + } return true; } @@ -276,7 +348,6 @@ int main(int argc, char** argv) DLOG("core_frequency = %d MHz\n", settings.core_frequency_mhz); DLOG("reset_board = %s\n", settings.reset_board ? "true" : "false"); DLOG("serial_number = %s\n", settings.serial_number ? settings.serial_number : "any"); - DLOG("wait_sync = %s\n", settings.wait_sync ? "true" : "false"); if (settings.show_help) { usage(); @@ -319,10 +390,11 @@ int main(int argc, char** argv) return APP_RESULT_STLINK_STATE_ERROR; } - ILOG("Reading SWO Data\n"); + ILOG("Reading.\n"); + st_trace_state_t state = {}; while (!g_done) { - if (!ReadTrace(stlink)) + if (!ReadTrace(stlink, &state)) g_done = true; } From 8793f3ceef06a394c6ea8120dbe58ddd28b42ba4 Mon Sep 17 00:00:00 2001 From: John Hall Date: Sun, 29 Nov 2020 00:25:00 -0800 Subject: [PATCH 1052/1435] Tabs to spaces --- src/st-trace/trace.c | 670 +++++++++++++++++++++---------------------- 1 file changed, 335 insertions(+), 335 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index ccb1a4828..bb516ebf0 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -15,26 +15,26 @@ #define DEFAULT_LOGGING_LEVEL 50 #define DEBUG_LOGGING_LEVEL 100 -#define APP_RESULT_SUCCESS 0 -#define APP_RESULT_INVALID_PARAMS 1 -#define APP_RESULT_STLINK_NOT_FOUND 2 -#define APP_RESULT_STLINK_MISSING_DEVICE 3 -#define APP_RESULT_STLINK_UNSUPPORTED_DEVICE 4 -#define APP_RESULT_STLINK_STATE_ERROR 5 +#define APP_RESULT_SUCCESS 0 +#define APP_RESULT_INVALID_PARAMS 1 +#define APP_RESULT_STLINK_NOT_FOUND 2 +#define APP_RESULT_STLINK_MISSING_DEVICE 3 +#define APP_RESULT_STLINK_UNSUPPORTED_DEVICE 4 +#define APP_RESULT_STLINK_STATE_ERROR 5 // See https://developer.arm.com/documentation/ddi0403/ed/ -#define TRACE_OP_IS_OVERFLOW(c) ((c) == 0x70) -#define TRACE_OP_IS_LOCAL_TIME(c) (((c) & 0x0f) == 0x00 && ((c) & 0x70) != 0x00) -#define TRACE_OP_IS_EXTENSION(c) (((c) & 0x0b) == 0x08) -#define TRACE_OP_IS_GLOBAL_TIME(c) (((c) & 0xdf) == 0x94) -#define TRACE_OP_IS_SOURCE(c) (((c) & 0x03) != 0x00) -#define TRACE_OP_IS_SW_SOURCE(c) (((c) & 0x03) != 0x00 && ((c) & 0x04) == 0x00) -#define TRACE_OP_IS_HW_SOURCE(c) (((c) & 0x03) != 0x00 && ((c) & 0x04) == 0x04) -#define TRACE_OP_IS_TARGET_SOURCE(c) ((c) == 0x01) +#define TRACE_OP_IS_OVERFLOW(c) ((c) == 0x70) +#define TRACE_OP_IS_LOCAL_TIME(c) (((c) & 0x0f) == 0x00 && ((c) & 0x70) != 0x00) +#define TRACE_OP_IS_EXTENSION(c) (((c) & 0x0b) == 0x08) +#define TRACE_OP_IS_GLOBAL_TIME(c) (((c) & 0xdf) == 0x94) +#define TRACE_OP_IS_SOURCE(c) (((c) & 0x03) != 0x00) +#define TRACE_OP_IS_SW_SOURCE(c) (((c) & 0x03) != 0x00 && ((c) & 0x04) == 0x00) +#define TRACE_OP_IS_HW_SOURCE(c) (((c) & 0x03) != 0x00 && ((c) & 0x04) == 0x04) +#define TRACE_OP_IS_TARGET_SOURCE(c) ((c) == 0x01) -#define TRACE_OP_GET_CONTINUATION(c) ((c) & 0x80) -#define TRACE_OP_GET_SOURCE_SIZE(c) ((c) & 0x03) -#define TRACE_OP_GET_SW_SOURCE_ADDR(c) ((c) >> 3) +#define TRACE_OP_GET_CONTINUATION(c) ((c) & 0x80) +#define TRACE_OP_GET_SOURCE_SIZE(c) ((c) & 0x03) +#define TRACE_OP_GET_SW_SOURCE_ADDR(c) ((c) >> 3) // We use a global flag to allow communicating to the main thread from the signal handler. @@ -42,365 +42,365 @@ static bool g_done = false; struct _st_settings_t { - bool show_help; - bool show_version; - int logging_level; - int core_frequency_mhz; - bool reset_board; - char* serial_number; + bool show_help; + bool show_version; + int logging_level; + int core_frequency_mhz; + bool reset_board; + char* serial_number; }; typedef struct _st_settings_t st_settings_t; // We use a simple state machine to parse the trace data. enum _trace_step { - TRACE_STEP_IDLE, - TRACE_STEP_TARGET_SOURCE, - TRACE_STEP_SKIP_FRAME, - TRACE_STEP_SKIP_4, - TRACE_STEP_SKIP_3, - TRACE_STEP_SKIP_2, - TRACE_STEP_SKIP_1, + TRACE_STEP_IDLE, + TRACE_STEP_TARGET_SOURCE, + TRACE_STEP_SKIP_FRAME, + TRACE_STEP_SKIP_4, + TRACE_STEP_SKIP_3, + TRACE_STEP_SKIP_2, + TRACE_STEP_SKIP_1, }; typedef enum _trace_step trace_step; struct _st_trace_state_t { - trace_step step; - bool overflow; - bool error; + trace_step step; + bool overflow; + bool error; }; typedef struct _st_trace_state_t st_trace_state_t; static void usage(void) { - puts("st-trace - usage:"); - puts(" -h, --help Print this help"); - puts(" -V, --version Print this version"); - puts(" -vXX, --verbose=XX Specify a specific verbosity level (0..99)"); - puts(" -v, --verbose Specify a generally verbose logging"); - puts(" -cXX, --clock=XX Specify the core frequency in MHz"); - puts(" -n, --no-reset Do not reset board on connection"); - puts(" -sXX, --serial=XX Use a specific serial number"); + puts("st-trace - usage:"); + puts(" -h, --help Print this help"); + puts(" -V, --version Print this version"); + puts(" -vXX, --verbose=XX Specify a specific verbosity level (0..99)"); + puts(" -v, --verbose Specify a generally verbose logging"); + puts(" -cXX, --clock=XX Specify the core frequency in MHz"); + puts(" -n, --no-reset Do not reset board on connection"); + puts(" -sXX, --serial=XX Use a specific serial number"); } static void cleanup() { - g_done = true; + g_done = true; } bool parse_options(int argc, char** argv, st_settings_t *settings) { - static struct option long_options[] = { - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'V'}, - {"verbose", optional_argument, NULL, 'v'}, - {"clock", required_argument, NULL, 'c'}, - {"no-reset", no_argument, NULL, 'n'}, - {"serial", required_argument, NULL, 's'}, - {0, 0, 0, 0}, - }; - int option_index = 0; - int c; - - settings->show_help = false; - settings->show_version = false; - settings->logging_level = DEFAULT_LOGGING_LEVEL; - settings->core_frequency_mhz = 0; - settings->reset_board = true; - settings->serial_number = NULL; - ugly_init(settings->logging_level); - - while ((c = getopt_long(argc, argv, "hVv::c:ns:", long_options, &option_index)) != -1) { - switch (c) { - case 'h': - settings->show_help = true; - break; - case 'V': - settings->show_version = true; - break; - case 'v': - if (optarg) { - settings->logging_level = atoi(optarg); - } else { - settings->logging_level = DEBUG_LOGGING_LEVEL; - } - ugly_init(settings->logging_level); - break; - case 'c': - settings->core_frequency_mhz = atoi(optarg); - break; - case 'n': - settings->reset_board = false; - break; - case 's': - settings->serial_number = optarg; - break; - case '?': - return false; - break; - default: - ELOG("Unknown command line option: '%c' (0x%02x)\n", c, c); - return false; - } - } - - if (optind < argc) { - while (optind < argc) { - ELOG("Unknown command line argument: '%s'\n", argv[optind++]); - } - return false; - } - - return true; + static struct option long_options[] = { + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'V'}, + {"verbose", optional_argument, NULL, 'v'}, + {"clock", required_argument, NULL, 'c'}, + {"no-reset", no_argument, NULL, 'n'}, + {"serial", required_argument, NULL, 's'}, + {0, 0, 0, 0}, + }; + int option_index = 0; + int c; + + settings->show_help = false; + settings->show_version = false; + settings->logging_level = DEFAULT_LOGGING_LEVEL; + settings->core_frequency_mhz = 0; + settings->reset_board = true; + settings->serial_number = NULL; + ugly_init(settings->logging_level); + + while ((c = getopt_long(argc, argv, "hVv::c:ns:", long_options, &option_index)) != -1) { + switch (c) { + case 'h': + settings->show_help = true; + break; + case 'V': + settings->show_version = true; + break; + case 'v': + if (optarg) { + settings->logging_level = atoi(optarg); + } else { + settings->logging_level = DEBUG_LOGGING_LEVEL; + } + ugly_init(settings->logging_level); + break; + case 'c': + settings->core_frequency_mhz = atoi(optarg); + break; + case 'n': + settings->reset_board = false; + break; + case 's': + settings->serial_number = optarg; + break; + case '?': + return false; + break; + default: + ELOG("Unknown command line option: '%c' (0x%02x)\n", c, c); + return false; + } + } + + if (optind < argc) { + while (optind < argc) { + ELOG("Unknown command line argument: '%s'\n", argv[optind++]); + } + return false; + } + + return true; } static stlink_t* StLinkConnect(const st_settings_t* settings) { - if (settings->serial_number) { - // Convert our serial number string to a binary value. - char serial_number[STLINK_SERIAL_MAX_SIZE] = { 0 }; - size_t length = 0; - for (uint32_t n = 0; n < strlen(settings->serial_number) && length < STLINK_SERIAL_MAX_SIZE; n += 2) { - char buffer[3] = { 0 }; - memcpy(buffer, settings->serial_number + n, 2); - serial_number[length++] = (uint8_t)strtol(buffer, NULL, 16); - } - - // Open this specific stlink. - return stlink_open_usb(settings->logging_level, false, serial_number, 0); - } else { - // Otherwise, open any stlink. - return stlink_open_usb(settings->logging_level, false, NULL, 0); - } + if (settings->serial_number) { + // Convert our serial number string to a binary value. + char serial_number[STLINK_SERIAL_MAX_SIZE] = { 0 }; + size_t length = 0; + for (uint32_t n = 0; n < strlen(settings->serial_number) && length < STLINK_SERIAL_MAX_SIZE; n += 2) { + char buffer[3] = { 0 }; + memcpy(buffer, settings->serial_number + n, 2); + serial_number[length++] = (uint8_t)strtol(buffer, NULL, 16); + } + + // Open this specific stlink. + return stlink_open_usb(settings->logging_level, false, serial_number, 0); + } else { + // Otherwise, open any stlink. + return stlink_open_usb(settings->logging_level, false, NULL, 0); + } } // TODO: Consider moving this to the device table. static bool IsDeviceTraceSupported(int chip_id) { - switch (chip_id) { - case STLINK_CHIPID_STM32_F4: - case STLINK_CHIPID_STM32_F4_DSI: - case STLINK_CHIPID_STM32_F4_HD: - case STLINK_CHIPID_STM32_F4_LP: - case STLINK_CHIPID_STM32_F411RE: - case STLINK_CHIPID_STM32_F4_DE: - case STLINK_CHIPID_STM32_F446: - case STLINK_CHIPID_STM32_F410: - case STLINK_CHIPID_STM32_F3: - case STLINK_CHIPID_STM32_F37x: - case STLINK_CHIPID_STM32_F412: - case STLINK_CHIPID_STM32_F413: - case STLINK_CHIPID_STM32_F3_SMALL: - case STLINK_CHIPID_STM32_F334: - case STLINK_CHIPID_STM32_F303_HIGH: - return true; - default: - return false; - } + switch (chip_id) { + case STLINK_CHIPID_STM32_F4: + case STLINK_CHIPID_STM32_F4_DSI: + case STLINK_CHIPID_STM32_F4_HD: + case STLINK_CHIPID_STM32_F4_LP: + case STLINK_CHIPID_STM32_F411RE: + case STLINK_CHIPID_STM32_F4_DE: + case STLINK_CHIPID_STM32_F446: + case STLINK_CHIPID_STM32_F410: + case STLINK_CHIPID_STM32_F3: + case STLINK_CHIPID_STM32_F37x: + case STLINK_CHIPID_STM32_F412: + case STLINK_CHIPID_STM32_F413: + case STLINK_CHIPID_STM32_F3_SMALL: + case STLINK_CHIPID_STM32_F334: + case STLINK_CHIPID_STM32_F303_HIGH: + return true; + default: + return false; + } } static void Write32(stlink_t* stlink, uint32_t address, uint32_t data) { - write_uint32(stlink->q_buf, data); - stlink_write_mem32(stlink, address, 4); + write_uint32(stlink->q_buf, data); + stlink_write_mem32(stlink, address, 4); } static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_board) { - struct stlink_reg regp = {}; - - if (stlink_force_debug(stlink)) { - return false; - } - - if (reset_board && stlink_reset(stlink)) { - return false; - } - - // The remainder of the items in this function were taken directly from https://github.com/avrhack/stlink-trace/blob/master/stlink-trace.c#L386 - - Write32(stlink, 0xE000EDF0, 0xA05F0003); // Set DHCSR to C_HALT and C_DEBUGEN - Write32(stlink, 0xE000EDFC, 0x01000000); // Set TRCENA flag to enable global DWT and ITM - Write32(stlink, 0xE0002000, 0x00000002); // Set FP_CTRL to enable write - Write32(stlink, 0xE0001028, 0x00000000); // Set DWT_FUNCTION0 to DWT_FUNCTION3 to disable sampling - Write32(stlink, 0xE0001038, 0x00000000); - Write32(stlink, 0xE0001048, 0x00000000); - Write32(stlink, 0xE0001058, 0x00000000); - Write32(stlink, 0xE0001000, 0x00000000); // Clear DWT_CTRL and other registers - Write32(stlink, 0xE0001004, 0x00000000); - Write32(stlink, 0xE0001008, 0x00000000); - Write32(stlink, 0xE000100C, 0x00000000); - Write32(stlink, 0xE0001010, 0x00000000); - Write32(stlink, 0xE0001014, 0x00000000); - Write32(stlink, 0xE0001018, 0x00000000); - - stlink_read_reg(stlink, 15, ®p); // Read program counter - stlink_read_reg(stlink, 16, ®p); // Read xpsr register - - Write32(stlink, 0xE0042004, 0x00000027); // Set DBGMCU_CR to enable asynchronous transmission - - // Actually start tracing. - if (stlink_trace_enable(stlink)) { - return false; - } - - Write32(stlink, 0xE0040004, 0x00000001); // Set TPIU_CSPSR to enable trace port width of 2 - - if (core_frequency_mhz) { - uint32_t clock_divisor = core_frequency_mhz / 2 - 1; - Write32(stlink, 0xE0040010, clock_divisor); // Set TPIU_ACPR clock divisor - } - - Write32(stlink, 0xE00400F0, 0x00000002); // Set TPIU_SPPR to Asynchronous SWO (NRZ) - Write32(stlink, 0xE0040304, 0x00000100); // Set TPIU_FFCR continuous formatting) - Write32(stlink, 0xE0000FB0, 0xC5ACCE55); // Unlock the ITM registers for write - Write32(stlink, 0xE0000E90, 0x00000400); // Set sync counter - Write32(stlink, 0xE0000E80, 0x00010003); // Set ITM_TCR flags : ITMENA,TSENA ATB=0 - Write32(stlink, 0xE0000E00, 0xFFFFFFFF); // Enable all trace ports in ITM_TER - Write32(stlink, 0xE0000E40, 0x0000000F); // Enable unprivileged access to trace ports 31:0 in ITM_TPR - Write32(stlink, 0xE0000E40, 0x400003FE); // Set DWT_CTRL flags) - Write32(stlink, 0xE000EDFC, 0x01000000); // Enable tracing (DEMCR - TRCENA bit) - - return true; + struct stlink_reg regp = {}; + + if (stlink_force_debug(stlink)) { + return false; + } + + if (reset_board && stlink_reset(stlink)) { + return false; + } + + // The order and values to set were taken from https://github.com/avrhack/stlink-trace/blob/master/stlink-trace.c#L386 + + Write32(stlink, 0xE000EDF0, 0xA05F0003); // Set DHCSR to C_HALT and C_DEBUGEN + Write32(stlink, 0xE000EDFC, 0x01000000); // Set TRCENA flag to enable global DWT and ITM + Write32(stlink, 0xE0002000, 0x00000002); // Set FP_CTRL to enable write + Write32(stlink, 0xE0001028, 0x00000000); // Set DWT_FUNCTION0 to DWT_FUNCTION3 to disable sampling + Write32(stlink, 0xE0001038, 0x00000000); + Write32(stlink, 0xE0001048, 0x00000000); + Write32(stlink, 0xE0001058, 0x00000000); + Write32(stlink, 0xE0001000, 0x00000000); // Clear DWT_CTRL and other registers + Write32(stlink, 0xE0001004, 0x00000000); + Write32(stlink, 0xE0001008, 0x00000000); + Write32(stlink, 0xE000100C, 0x00000000); + Write32(stlink, 0xE0001010, 0x00000000); + Write32(stlink, 0xE0001014, 0x00000000); + Write32(stlink, 0xE0001018, 0x00000000); + + stlink_read_reg(stlink, 15, ®p); // Read program counter + stlink_read_reg(stlink, 16, ®p); // Read xpsr register + + Write32(stlink, 0xE0042004, 0x00000027); // Set DBGMCU_CR to enable asynchronous transmission + + // Actually start tracing. + if (stlink_trace_enable(stlink)) { + return false; + } + + Write32(stlink, 0xE0040004, 0x00000001); // Set TPIU_CSPSR to enable trace port width of 2 + + if (core_frequency_mhz) { + uint32_t clock_divisor = core_frequency_mhz / 2 - 1; + Write32(stlink, 0xE0040010, clock_divisor); // Set TPIU_ACPR clock divisor + } + + Write32(stlink, 0xE00400F0, 0x00000002); // Set TPIU_SPPR to Asynchronous SWO (NRZ) + Write32(stlink, 0xE0040304, 0x00000100); // Set TPIU_FFCR continuous formatting) + Write32(stlink, 0xE0000FB0, 0xC5ACCE55); // Unlock the ITM registers for write + Write32(stlink, 0xE0000E90, 0x00000400); // Set sync counter + Write32(stlink, 0xE0000E80, 0x00010003); // Set ITM_TCR flags : ITMENA,TSENA ATB=0 + Write32(stlink, 0xE0000E00, 0xFFFFFFFF); // Enable all trace ports in ITM_TER + Write32(stlink, 0xE0000E40, 0x0000000F); // Enable unprivileged access to trace ports 31:0 in ITM_TPR + Write32(stlink, 0xE0000E40, 0x400003FE); // Set DWT_CTRL flags) + Write32(stlink, 0xE000EDFC, 0x01000000); // Enable tracing (DEMCR - TRCENA bit) + + return true; } static bool ReadTrace(stlink_t* stlink, st_trace_state_t* state) { - uint8_t buffer[STLINK_TRACE_BUF_LEN]; - int length = stlink_trace_read(stlink, buffer, sizeof(buffer)); - - if (length < 0) { - ELOG("Error reading trace (%d)\n", length); - return false; - } - - if (length == 0) { - usleep(1000); - return true; - } - - DLOG("Trace Length: %d\n", length); - - for (int i = 0; i < length; i++) { - uint8_t c = buffer[i]; - - // Parse the input using a state machine. - switch (state->step) - { - case TRACE_STEP_IDLE: - if (TRACE_OP_IS_TARGET_SOURCE(c)) { - state->step = TRACE_STEP_TARGET_SOURCE; - } else if (TRACE_OP_IS_SOURCE(c)) { - const trace_step kSourceSkip[] = { TRACE_STEP_IDLE, TRACE_STEP_SKIP_1, TRACE_STEP_SKIP_2, TRACE_STEP_SKIP_4 }; - const char* type = TRACE_OP_IS_SW_SOURCE(c) ? "sw" : "hw"; - uint8_t addr = TRACE_OP_GET_SW_SOURCE_ADDR(c); - uint8_t size = TRACE_OP_GET_SOURCE_SIZE(c); - WLOG("Unsupported %s source 0x%x size %d", type, addr, size); - state->step = kSourceSkip[size]; - } else if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_EXTENSION(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { - if (TRACE_OP_GET_CONTINUATION(c)) - state->step = TRACE_STEP_SKIP_FRAME; - } else if (TRACE_OP_IS_OVERFLOW(c)) { - state->overflow = true; - } else { - WLOG("Unknown opcode 0x%02x\n", c); - if (TRACE_OP_GET_CONTINUATION(c)) - state->step = TRACE_STEP_SKIP_FRAME; - } - break; - case TRACE_STEP_TARGET_SOURCE: - putchar(c); - state->step = TRACE_STEP_IDLE; - break; - case TRACE_STEP_SKIP_FRAME: - if (TRACE_OP_GET_CONTINUATION(c) == 0) - state->step = TRACE_STEP_IDLE; - break; - case TRACE_STEP_SKIP_4: - state->step = TRACE_STEP_SKIP_3; - break; - case TRACE_STEP_SKIP_3: - state->step = TRACE_STEP_SKIP_2; - break; - case TRACE_STEP_SKIP_2: - state->step = TRACE_STEP_SKIP_1; - break; - case TRACE_STEP_SKIP_1: - state->step = TRACE_STEP_IDLE; - break; - } - } - - return true; + uint8_t buffer[STLINK_TRACE_BUF_LEN]; + int length = stlink_trace_read(stlink, buffer, sizeof(buffer)); + + if (length < 0) { + ELOG("Error reading trace (%d)\n", length); + return false; + } + + if (length == 0) { + usleep(1000); + return true; + } + + DLOG("Trace Length: %d\n", length); + + for (int i = 0; i < length; i++) { + uint8_t c = buffer[i]; + + // Parse the input using a state machine. + switch (state->step) + { + case TRACE_STEP_IDLE: + if (TRACE_OP_IS_TARGET_SOURCE(c)) { + state->step = TRACE_STEP_TARGET_SOURCE; + } else if (TRACE_OP_IS_SOURCE(c)) { + const trace_step kSourceSkip[] = { TRACE_STEP_IDLE, TRACE_STEP_SKIP_1, TRACE_STEP_SKIP_2, TRACE_STEP_SKIP_4 }; + const char* type = TRACE_OP_IS_SW_SOURCE(c) ? "sw" : "hw"; + uint8_t addr = TRACE_OP_GET_SW_SOURCE_ADDR(c); + uint8_t size = TRACE_OP_GET_SOURCE_SIZE(c); + WLOG("Unsupported %s source 0x%x size %d", type, addr, size); + state->step = kSourceSkip[size]; + } else if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_EXTENSION(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { + if (TRACE_OP_GET_CONTINUATION(c)) + state->step = TRACE_STEP_SKIP_FRAME; + } else if (TRACE_OP_IS_OVERFLOW(c)) { + state->overflow = true; + } else { + WLOG("Unknown opcode 0x%02x\n", c); + if (TRACE_OP_GET_CONTINUATION(c)) + state->step = TRACE_STEP_SKIP_FRAME; + } + break; + case TRACE_STEP_TARGET_SOURCE: + putchar(c); + state->step = TRACE_STEP_IDLE; + break; + case TRACE_STEP_SKIP_FRAME: + if (TRACE_OP_GET_CONTINUATION(c) == 0) + state->step = TRACE_STEP_IDLE; + break; + case TRACE_STEP_SKIP_4: + state->step = TRACE_STEP_SKIP_3; + break; + case TRACE_STEP_SKIP_3: + state->step = TRACE_STEP_SKIP_2; + break; + case TRACE_STEP_SKIP_2: + state->step = TRACE_STEP_SKIP_1; + break; + case TRACE_STEP_SKIP_1: + state->step = TRACE_STEP_IDLE; + break; + } + } + + return true; } int main(int argc, char** argv) { - st_settings_t settings; - stlink_t* stlink = NULL; - - signal(SIGINT, &cleanup); - signal(SIGTERM, &cleanup); - signal(SIGSEGV, &cleanup); - - if (!parse_options(argc, argv, &settings)) { - usage(); - return APP_RESULT_INVALID_PARAMS; - } - - DLOG("show_help = %s\n", settings.show_help ? "true" : "false"); - DLOG("show_version = %s\n", settings.show_version ? "true" : "false"); - DLOG("logging_level = %d\n", settings.logging_level); - DLOG("core_frequency = %d MHz\n", settings.core_frequency_mhz); - DLOG("reset_board = %s\n", settings.reset_board ? "true" : "false"); - DLOG("serial_number = %s\n", settings.serial_number ? settings.serial_number : "any"); - - if (settings.show_help) { - usage(); - return APP_RESULT_SUCCESS; - } - - if (settings.show_version) { - printf("v%s\n", STLINK_VERSION); - return APP_RESULT_SUCCESS; - } - - stlink = StLinkConnect(&settings); - if (!stlink) { - ELOG("Unable to locate st-link\n"); - return APP_RESULT_STLINK_NOT_FOUND; - } - - stlink->verbose = settings.logging_level; - - if (stlink->chip_id == STLINK_CHIPID_UNKNOWN) { - ELOG("st-link not connected\n"); - return APP_RESULT_STLINK_MISSING_DEVICE; - } - - // TODO: Check if trace is supported by stlink. - - if (!IsDeviceTraceSupported(stlink->chip_id)) { - const struct stlink_chipid_params *params = stlink_chipid_get_params(stlink->chip_id); - ELOG("We do not support SWO output for device '%s'", params->description); - return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; - } - - if (!EnableTrace(stlink, settings.core_frequency_mhz, settings.reset_board)) { - ELOG("Unable to enable trace mode\n"); - return APP_RESULT_STLINK_STATE_ERROR; - } - - if (stlink_run(stlink)) { - ELOG("Unable to run device\n"); - return APP_RESULT_STLINK_STATE_ERROR; - } - - ILOG("Reading.\n"); - - st_trace_state_t state = {}; - while (!g_done) { - if (!ReadTrace(stlink, &state)) - g_done = true; - } - - stlink_trace_disable(stlink); - stlink_close(stlink); - - return APP_RESULT_SUCCESS; + st_settings_t settings; + stlink_t* stlink = NULL; + + signal(SIGINT, &cleanup); + signal(SIGTERM, &cleanup); + signal(SIGSEGV, &cleanup); + + if (!parse_options(argc, argv, &settings)) { + usage(); + return APP_RESULT_INVALID_PARAMS; + } + + DLOG("show_help = %s\n", settings.show_help ? "true" : "false"); + DLOG("show_version = %s\n", settings.show_version ? "true" : "false"); + DLOG("logging_level = %d\n", settings.logging_level); + DLOG("core_frequency = %d MHz\n", settings.core_frequency_mhz); + DLOG("reset_board = %s\n", settings.reset_board ? "true" : "false"); + DLOG("serial_number = %s\n", settings.serial_number ? settings.serial_number : "any"); + + if (settings.show_help) { + usage(); + return APP_RESULT_SUCCESS; + } + + if (settings.show_version) { + printf("v%s\n", STLINK_VERSION); + return APP_RESULT_SUCCESS; + } + + stlink = StLinkConnect(&settings); + if (!stlink) { + ELOG("Unable to locate st-link\n"); + return APP_RESULT_STLINK_NOT_FOUND; + } + + stlink->verbose = settings.logging_level; + + if (stlink->chip_id == STLINK_CHIPID_UNKNOWN) { + ELOG("st-link not connected\n"); + return APP_RESULT_STLINK_MISSING_DEVICE; + } + + // TODO: Check if trace is supported by stlink. + + if (!IsDeviceTraceSupported(stlink->chip_id)) { + const struct stlink_chipid_params *params = stlink_chipid_get_params(stlink->chip_id); + ELOG("We do not support SWO output for device '%s'", params->description); + return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; + } + + if (!EnableTrace(stlink, settings.core_frequency_mhz, settings.reset_board)) { + ELOG("Unable to enable trace mode\n"); + return APP_RESULT_STLINK_STATE_ERROR; + } + + if (stlink_run(stlink)) { + ELOG("Unable to run device\n"); + return APP_RESULT_STLINK_STATE_ERROR; + } + + ILOG("Reading.\n"); + + st_trace_state_t state = {}; + while (!g_done) { + if (!ReadTrace(stlink, &state)) + g_done = true; + } + + stlink_trace_disable(stlink); + stlink_close(stlink); + + return APP_RESULT_SUCCESS; } From 3531e34636f75cc094c995416c2a5b09daf67763 Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 30 Nov 2020 09:08:59 -0800 Subject: [PATCH 1053/1435] Code cleanup. --- src/common.c | 1 - src/st-trace/trace.c | 145 ++++++++++++++++++++++++------------------- src/stlink-lib/usb.c | 1 - 3 files changed, 80 insertions(+), 67 deletions(-) diff --git a/src/common.c b/src/common.c index e340ecc71..78cda9318 100644 --- a/src/common.c +++ b/src/common.c @@ -1688,7 +1688,6 @@ int stlink_trace_disable(stlink_t* sl) { } int stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size) { - DLOG("*** stlink_trace_read ***\n"); return(sl->backend->trace_read(sl, buf, size)); } diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index bb516ebf0..148876c7a 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -24,6 +24,7 @@ // See https://developer.arm.com/documentation/ddi0403/ed/ #define TRACE_OP_IS_OVERFLOW(c) ((c) == 0x70) +#define TRACE_OP_IS_SYNC(c) ((c) == 0x00) #define TRACE_OP_IS_LOCAL_TIME(c) (((c) & 0x0f) == 0x00 && ((c) & 0x70) != 0x00) #define TRACE_OP_IS_EXTENSION(c) (((c) & 0x0b) == 0x08) #define TRACE_OP_IS_GLOBAL_TIME(c) (((c) & 0xdf) == 0x94) @@ -53,23 +54,23 @@ typedef struct _st_settings_t st_settings_t; // We use a simple state machine to parse the trace data. -enum _trace_step { - TRACE_STEP_IDLE, - TRACE_STEP_TARGET_SOURCE, - TRACE_STEP_SKIP_FRAME, - TRACE_STEP_SKIP_4, - TRACE_STEP_SKIP_3, - TRACE_STEP_SKIP_2, - TRACE_STEP_SKIP_1, +enum _trace_state { + TRACE_STATE_IDLE, + TRACE_STATE_TARGET_SOURCE, + TRACE_STATE_SKIP_FRAME, + TRACE_STATE_SKIP_4, + TRACE_STATE_SKIP_3, + TRACE_STATE_SKIP_2, + TRACE_STATE_SKIP_1, }; -typedef enum _trace_step trace_step; +typedef enum _trace_state trace_state; -struct _st_trace_state_t { - trace_step step; +struct _st_trace_t { + trace_state state; bool overflow; bool error; }; -typedef struct _st_trace_state_t st_trace_state_t; +typedef struct _st_trace_t st_trace_t; static void usage(void) { @@ -242,8 +243,9 @@ static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_boa Write32(stlink, 0xE0040004, 0x00000001); // Set TPIU_CSPSR to enable trace port width of 2 if (core_frequency_mhz) { - uint32_t clock_divisor = core_frequency_mhz / 2 - 1; + uint32_t clock_divisor = core_frequency_mhz * 1000000 / STLINK_TRACE_FREQUENCY - 1; Write32(stlink, 0xE0040010, clock_divisor); // Set TPIU_ACPR clock divisor + } else { } Write32(stlink, 0xE00400F0, 0x00000002); // Set TPIU_SPPR to Asynchronous SWO (NRZ) @@ -259,7 +261,67 @@ static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_boa return true; } -static bool ReadTrace(stlink_t* stlink, st_trace_state_t* state) { +static void UpdateTrace(st_trace_t* trace, uint8_t c) { + // Parse the input using a state machine. + switch (trace->state) + { + case TRACE_STATE_IDLE: + if (TRACE_OP_IS_TARGET_SOURCE(c)) { + trace->state = TRACE_STATE_TARGET_SOURCE; + } else if (TRACE_OP_IS_SOURCE(c)) { + const trace_state kSourceSkip[] = { TRACE_STATE_IDLE, TRACE_STATE_SKIP_1, TRACE_STATE_SKIP_2, TRACE_STATE_SKIP_4 }; + const char* type = TRACE_OP_IS_SW_SOURCE(c) ? "sw" : "hw"; + uint8_t addr = TRACE_OP_GET_SW_SOURCE_ADDR(c); + uint8_t size = TRACE_OP_GET_SOURCE_SIZE(c); + if (TRACE_OP_IS_SW_SOURCE(c)) + WLOG("Unsupported %s source 0x%x size %d\n", type, addr, size); + trace->state = kSourceSkip[size]; + } else if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_EXTENSION(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { + if (TRACE_OP_GET_CONTINUATION(c)) + trace->state = TRACE_STATE_SKIP_FRAME; + } else if (TRACE_OP_IS_SYNC(c)) { + } else if (TRACE_OP_IS_OVERFLOW(c)) { + trace->overflow = true; + } else { + WLOG("Unknown opcode 0x%02x\n", c); + if (TRACE_OP_GET_CONTINUATION(c)) + trace->state = TRACE_STATE_SKIP_FRAME; + } + break; + + case TRACE_STATE_TARGET_SOURCE: + putchar(c); + trace->state = TRACE_STATE_IDLE; + break; + + case TRACE_STATE_SKIP_FRAME: + if (TRACE_OP_GET_CONTINUATION(c) == 0) + trace->state = TRACE_STATE_IDLE; + break; + + case TRACE_STATE_SKIP_4: + trace->state = TRACE_STATE_SKIP_3; + break; + + case TRACE_STATE_SKIP_3: + trace->state = TRACE_STATE_SKIP_2; + break; + + case TRACE_STATE_SKIP_2: + trace->state = TRACE_STATE_SKIP_1; + break; + + case TRACE_STATE_SKIP_1: + trace->state = TRACE_STATE_IDLE; + break; + + default: + ELOG("Invalid state %d", trace->state); + trace->state = TRACE_STATE_IDLE; + } +} + +static bool ReadTrace(stlink_t* stlink, st_trace_t* trace) { uint8_t buffer[STLINK_TRACE_BUF_LEN]; int length = stlink_trace_read(stlink, buffer, sizeof(buffer)); @@ -274,55 +336,8 @@ static bool ReadTrace(stlink_t* stlink, st_trace_state_t* state) { } DLOG("Trace Length: %d\n", length); - for (int i = 0; i < length; i++) { - uint8_t c = buffer[i]; - - // Parse the input using a state machine. - switch (state->step) - { - case TRACE_STEP_IDLE: - if (TRACE_OP_IS_TARGET_SOURCE(c)) { - state->step = TRACE_STEP_TARGET_SOURCE; - } else if (TRACE_OP_IS_SOURCE(c)) { - const trace_step kSourceSkip[] = { TRACE_STEP_IDLE, TRACE_STEP_SKIP_1, TRACE_STEP_SKIP_2, TRACE_STEP_SKIP_4 }; - const char* type = TRACE_OP_IS_SW_SOURCE(c) ? "sw" : "hw"; - uint8_t addr = TRACE_OP_GET_SW_SOURCE_ADDR(c); - uint8_t size = TRACE_OP_GET_SOURCE_SIZE(c); - WLOG("Unsupported %s source 0x%x size %d", type, addr, size); - state->step = kSourceSkip[size]; - } else if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_EXTENSION(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { - if (TRACE_OP_GET_CONTINUATION(c)) - state->step = TRACE_STEP_SKIP_FRAME; - } else if (TRACE_OP_IS_OVERFLOW(c)) { - state->overflow = true; - } else { - WLOG("Unknown opcode 0x%02x\n", c); - if (TRACE_OP_GET_CONTINUATION(c)) - state->step = TRACE_STEP_SKIP_FRAME; - } - break; - case TRACE_STEP_TARGET_SOURCE: - putchar(c); - state->step = TRACE_STEP_IDLE; - break; - case TRACE_STEP_SKIP_FRAME: - if (TRACE_OP_GET_CONTINUATION(c) == 0) - state->step = TRACE_STEP_IDLE; - break; - case TRACE_STEP_SKIP_4: - state->step = TRACE_STEP_SKIP_3; - break; - case TRACE_STEP_SKIP_3: - state->step = TRACE_STEP_SKIP_2; - break; - case TRACE_STEP_SKIP_2: - state->step = TRACE_STEP_SKIP_1; - break; - case TRACE_STEP_SKIP_1: - state->step = TRACE_STEP_IDLE; - break; - } + UpdateTrace(trace, buffer[i]); } return true; @@ -376,7 +391,7 @@ int main(int argc, char** argv) if (!IsDeviceTraceSupported(stlink->chip_id)) { const struct stlink_chipid_params *params = stlink_chipid_get_params(stlink->chip_id); - ELOG("We do not support SWO output for device '%s'", params->description); + ELOG("We do not support SWO output for device '%s'\n", params->description); return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; } @@ -392,9 +407,9 @@ int main(int argc, char** argv) ILOG("Reading.\n"); - st_trace_state_t state = {}; + st_trace_t trace = {}; while (!g_done) { - if (!ReadTrace(stlink, &state)) + if (!ReadTrace(stlink, &trace)) g_done = true; } diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 4d8d78a65..db187acc5 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1043,7 +1043,6 @@ int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { } size_t trace_count = read_uint16(sl->q_buf, 0); - DLOG("trace_count = 0x%08x\n", trace_count); if (trace_count > size) { ELOG("read_trace insufficient buffer length\n"); From 0b3f39fb13ea386105a9a8bb94256fef173073f6 Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 30 Nov 2020 10:21:19 -0800 Subject: [PATCH 1054/1435] Checked that the trace port is configured. Added log messages to share the configuration and to tell the user what to do if it is not configured. --- src/st-trace/trace.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 148876c7a..aa8fb50c4 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -199,7 +199,16 @@ static bool IsDeviceTraceSupported(int chip_id) { static void Write32(stlink_t* stlink, uint32_t address, uint32_t data) { write_uint32(stlink->q_buf, data); - stlink_write_mem32(stlink, address, 4); + if (stlink_write_mem32(stlink, address, 4)) { + ELOG("Unable to set address 0x%08x to 0x%08x\n", address, data); + } +} + +static uint32_t Read32(stlink_t* stlink, uint32_t address) { + if (stlink_read_mem32(stlink, address, 4)) { + ELOG("Unable to read from address 0x%08x\n", address); + } + return read_uint32(stlink->q_buf, 0); } static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_board) { @@ -243,9 +252,17 @@ static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_boa Write32(stlink, 0xE0040004, 0x00000001); // Set TPIU_CSPSR to enable trace port width of 2 if (core_frequency_mhz) { - uint32_t clock_divisor = core_frequency_mhz * 1000000 / STLINK_TRACE_FREQUENCY - 1; - Write32(stlink, 0xE0040010, clock_divisor); // Set TPIU_ACPR clock divisor + uint32_t prescaler = core_frequency_mhz * 1000000 / STLINK_TRACE_FREQUENCY - 1; + Write32(stlink, 0xE0040010, prescaler); // Set TPIU_ACPR clock divisor + } + uint32_t prescaler = Read32(stlink, 0xE0040010); + if (prescaler) { + uint32_t system_clock_speed = (prescaler + 1) * STLINK_TRACE_FREQUENCY; + ILOG("Trace Port Interface configured to expect a %d MHz system clock.\n", (system_clock_speed + 500000) / 1000000); } else { + WLOG("Trace Port Interface not configured. Specify the system clock with a --clock=XX command\n"); + WLOG("line option or set it in your device's clock initialization routine, such as with:\n"); + WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / 2000000 - 1;\n"); } Write32(stlink, 0xE00400F0, 0x00000002); // Set TPIU_SPPR to Asynchronous SWO (NRZ) From acbb78d1f4674b5dfd2464c1ed2e5322a27d5370 Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 30 Nov 2020 10:51:28 -0800 Subject: [PATCH 1055/1435] Checking that stlink supports tracing. --- src/common.c | 5 +++++ src/st-trace/trace.c | 28 ++++++++++++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/common.c b/src/common.c index 78cda9318..bda2ccf87 100644 --- a/src/common.c +++ b/src/common.c @@ -1465,6 +1465,10 @@ void _parse_version(stlink_t *sl, stlink_version_t *slv) { if (sl->version.jtag_v >= 15) { sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; } + + if (sl->version.jtag_v >= 13) { + sl->version.flags |= STLINK_F_HAS_TRACE; + } } } else { // V3 uses different version format, for reference see OpenOCD source @@ -1478,6 +1482,7 @@ void _parse_version(stlink_t *sl, stlink_version_t *slv) { slv->jtag_api = STLINK_JTAG_API_V3; /* preferred API to get last R/W status */ sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; + sl->version.flags |= STLINK_F_HAS_TRACE; } return; diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index aa8fb50c4..2646dead5 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -20,9 +20,10 @@ #define APP_RESULT_STLINK_NOT_FOUND 2 #define APP_RESULT_STLINK_MISSING_DEVICE 3 #define APP_RESULT_STLINK_UNSUPPORTED_DEVICE 4 -#define APP_RESULT_STLINK_STATE_ERROR 5 +#define APP_RESULT_STLINK_UNSUPPORTED_LINK 5 +#define APP_RESULT_STLINK_STATE_ERROR 6 -// See https://developer.arm.com/documentation/ddi0403/ed/ +// See D4.2 of https://developer.arm.com/documentation/ddi0403/ed/ #define TRACE_OP_IS_OVERFLOW(c) ((c) == 0x70) #define TRACE_OP_IS_SYNC(c) ((c) == 0x00) #define TRACE_OP_IS_LOCAL_TIME(c) (((c) & 0x0f) == 0x00 && ((c) & 0x70) != 0x00) @@ -32,7 +33,6 @@ #define TRACE_OP_IS_SW_SOURCE(c) (((c) & 0x03) != 0x00 && ((c) & 0x04) == 0x00) #define TRACE_OP_IS_HW_SOURCE(c) (((c) & 0x03) != 0x00 && ((c) & 0x04) == 0x04) #define TRACE_OP_IS_TARGET_SOURCE(c) ((c) == 0x01) - #define TRACE_OP_GET_CONTINUATION(c) ((c) & 0x80) #define TRACE_OP_GET_SOURCE_SIZE(c) ((c) & 0x03) #define TRACE_OP_GET_SW_SOURCE_ADDR(c) ((c) >> 3) @@ -293,7 +293,10 @@ static void UpdateTrace(st_trace_t* trace, uint8_t c) { if (TRACE_OP_IS_SW_SOURCE(c)) WLOG("Unsupported %s source 0x%x size %d\n", type, addr, size); trace->state = kSourceSkip[size]; - } else if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_EXTENSION(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { + } else if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { + if (TRACE_OP_GET_CONTINUATION(c)) + trace->state = TRACE_STATE_SKIP_FRAME; + } else if (TRACE_OP_IS_EXTENSION(c)) { if (TRACE_OP_GET_CONTINUATION(c)) trace->state = TRACE_STATE_SKIP_FRAME; } else if (TRACE_OP_IS_SYNC(c)) { @@ -393,18 +396,21 @@ int main(int argc, char** argv) stlink = StLinkConnect(&settings); if (!stlink) { - ELOG("Unable to locate st-link\n"); + ELOG("Unable to locate an stlink\n"); return APP_RESULT_STLINK_NOT_FOUND; } stlink->verbose = settings.logging_level; if (stlink->chip_id == STLINK_CHIPID_UNKNOWN) { - ELOG("st-link not connected\n"); + ELOG("Your stlink is not connected to a device\n"); return APP_RESULT_STLINK_MISSING_DEVICE; } - // TODO: Check if trace is supported by stlink. + if (!(stlink->version.flags & STLINK_F_HAS_TRACE)) { + ELOG("Your stlink does not support tracing\n"); + return APP_RESULT_STLINK_UNSUPPORTED_LINK; + } if (!IsDeviceTraceSupported(stlink->chip_id)) { const struct stlink_chipid_params *params = stlink_chipid_get_params(stlink->chip_id); @@ -422,12 +428,10 @@ int main(int argc, char** argv) return APP_RESULT_STLINK_STATE_ERROR; } - ILOG("Reading.\n"); - + ILOG("Reading Trace\n"); st_trace_t trace = {}; - while (!g_done) { - if (!ReadTrace(stlink, &trace)) - g_done = true; + while (!g_done && ReadTrace(stlink, &trace)) { + // TODO: Check that things are roughly working. } stlink_trace_disable(stlink); From 722224e5f282dd0ee727fbf7787d7ccd745f3a01 Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 30 Nov 2020 11:10:59 -0800 Subject: [PATCH 1056/1435] Adding a force flag to ignore errors. --- src/st-trace/trace.c | 61 +++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 2646dead5..ef34d62e0 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -48,6 +48,7 @@ struct _st_settings_t { int logging_level; int core_frequency_mhz; bool reset_board; + bool force; char* serial_number; }; typedef struct _st_settings_t st_settings_t; @@ -82,6 +83,7 @@ static void usage(void) { puts(" -cXX, --clock=XX Specify the core frequency in MHz"); puts(" -n, --no-reset Do not reset board on connection"); puts(" -sXX, --serial=XX Use a specific serial number"); + puts(" -f, --force Ignore some errors"); } static void cleanup() { @@ -97,20 +99,23 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { {"clock", required_argument, NULL, 'c'}, {"no-reset", no_argument, NULL, 'n'}, {"serial", required_argument, NULL, 's'}, + {"force", no_argument, NULL, 'f'}, {0, 0, 0, 0}, }; int option_index = 0; int c; + bool error = false; settings->show_help = false; settings->show_version = false; settings->logging_level = DEFAULT_LOGGING_LEVEL; settings->core_frequency_mhz = 0; settings->reset_board = true; + settings->force = false; settings->serial_number = NULL; ugly_init(settings->logging_level); - while ((c = getopt_long(argc, argv, "hVv::c:ns:", long_options, &option_index)) != -1) { + while ((c = getopt_long(argc, argv, "hVv::c:ns:f", long_options, &option_index)) != -1) { switch (c) { case 'h': settings->show_help = true; @@ -132,15 +137,19 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { case 'n': settings->reset_board = false; break; + case 'f': + settings->force = true; + break; case 's': settings->serial_number = optarg; break; case '?': - return false; + error = true; break; default: ELOG("Unknown command line option: '%c' (0x%02x)\n", c, c); - return false; + error = true; + break; } } @@ -148,9 +157,12 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { while (optind < argc) { ELOG("Unknown command line argument: '%s'\n", argv[optind++]); } - return false; + error = true; } + if (error && !settings->force) + return false; + return true; } @@ -211,15 +223,19 @@ static uint32_t Read32(stlink_t* stlink, uint32_t address) { return read_uint32(stlink->q_buf, 0); } -static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_board) { +static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { struct stlink_reg regp = {}; if (stlink_force_debug(stlink)) { - return false; + ELOG("Unable to debug device\n"); + if (!settings->force) + return false; } - if (reset_board && stlink_reset(stlink)) { - return false; + if (settings->reset_board && stlink_reset(stlink)) { + ELOG("Unable to reset device\n"); + if (!settings->force) + return false; } // The order and values to set were taken from https://github.com/avrhack/stlink-trace/blob/master/stlink-trace.c#L386 @@ -246,13 +262,15 @@ static bool EnableTrace(stlink_t* stlink, int core_frequency_mhz, bool reset_boa // Actually start tracing. if (stlink_trace_enable(stlink)) { - return false; + ELOG("Unable to trace device\n"); + if (!settings->force) + return false; } Write32(stlink, 0xE0040004, 0x00000001); // Set TPIU_CSPSR to enable trace port width of 2 - if (core_frequency_mhz) { - uint32_t prescaler = core_frequency_mhz * 1000000 / STLINK_TRACE_FREQUENCY - 1; + if (settings->core_frequency_mhz) { + uint32_t prescaler = settings->core_frequency_mhz * 1000000 / STLINK_TRACE_FREQUENCY - 1; Write32(stlink, 0xE0040010, prescaler); // Set TPIU_ACPR clock divisor } uint32_t prescaler = Read32(stlink, 0xE0040010); @@ -304,6 +322,7 @@ static void UpdateTrace(st_trace_t* trace, uint8_t c) { trace->overflow = true; } else { WLOG("Unknown opcode 0x%02x\n", c); + trace->error = true; if (TRACE_OP_GET_CONTINUATION(c)) trace->state = TRACE_STATE_SKIP_FRAME; } @@ -336,7 +355,7 @@ static void UpdateTrace(st_trace_t* trace, uint8_t c) { break; default: - ELOG("Invalid state %d", trace->state); + ELOG("Invalid state %d. This should never happen\n", trace->state); trace->state = TRACE_STATE_IDLE; } } @@ -382,6 +401,7 @@ int main(int argc, char** argv) DLOG("logging_level = %d\n", settings.logging_level); DLOG("core_frequency = %d MHz\n", settings.core_frequency_mhz); DLOG("reset_board = %s\n", settings.reset_board ? "true" : "false"); + DLOG("force = %s\n", settings.force ? "true" : "false"); DLOG("serial_number = %s\n", settings.serial_number ? settings.serial_number : "any"); if (settings.show_help) { @@ -404,28 +424,33 @@ int main(int argc, char** argv) if (stlink->chip_id == STLINK_CHIPID_UNKNOWN) { ELOG("Your stlink is not connected to a device\n"); - return APP_RESULT_STLINK_MISSING_DEVICE; + if (!settings.force) + return APP_RESULT_STLINK_MISSING_DEVICE; } if (!(stlink->version.flags & STLINK_F_HAS_TRACE)) { ELOG("Your stlink does not support tracing\n"); - return APP_RESULT_STLINK_UNSUPPORTED_LINK; + if (!settings.force) + return APP_RESULT_STLINK_UNSUPPORTED_LINK; } if (!IsDeviceTraceSupported(stlink->chip_id)) { const struct stlink_chipid_params *params = stlink_chipid_get_params(stlink->chip_id); ELOG("We do not support SWO output for device '%s'\n", params->description); - return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; + if (!settings.force) + return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; } - if (!EnableTrace(stlink, settings.core_frequency_mhz, settings.reset_board)) { + if (!EnableTrace(stlink, &settings)) { ELOG("Unable to enable trace mode\n"); - return APP_RESULT_STLINK_STATE_ERROR; + if (!settings.force) + return APP_RESULT_STLINK_STATE_ERROR; } if (stlink_run(stlink)) { ELOG("Unable to run device\n"); - return APP_RESULT_STLINK_STATE_ERROR; + if (!settings.force) + return APP_RESULT_STLINK_STATE_ERROR; } ILOG("Reading Trace\n"); From 3188fb48d1cbd745f437c3bd55af3a8599c0484f Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 30 Nov 2020 19:39:43 -0800 Subject: [PATCH 1057/1435] Updating to use register names to make code more readable. --- inc/stlink.h | 3 ++ src/st-trace/trace.c | 124 ++++++++++++++++++++++++++++++------------- 2 files changed, 89 insertions(+), 38 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index e7aefbded..1c9f6b09a 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -105,6 +105,9 @@ enum target_state { #define S_RETIRE_ST (1 << 24) #define S_RESET_ST (1 << 25) +/* DCB_DEMCR field definitions */ +#define DEMCR_TRCENA (1 << 24) + /* Map the relevant features, quirks and workaround for specific firmware version of stlink */ #define STLINK_F_HAS_TRACE (1 << 0) #define STLINK_F_HAS_SWD_SET_FREQ (1 << 1) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index ef34d62e0..877bd4e35 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -38,6 +38,64 @@ #define TRACE_OP_GET_SW_SOURCE_ADDR(c) ((c) >> 3) +// Instrumentation Trace Macrocell (ITM) Registers +#define ITM_TER 0xE0000E00 // ITM Trace Enable Register +#define ITM_TPR 0xE0000E40 // ITM Trace Privilege Register +#define ITM_TCR 0xE0000E80 // ITM Trace Control Register +#define ITM_TCC 0xE0000E90 // ITM Trace Cycle Count +#define ITM_LAR 0xE0000FB0 // ITM Lock Access Register + +// ITM field definitions +#define ITM_TER_PORTS_ALL (0xFFFFFFFF) +#define ITM_TPR_PORTS_ALL (0x0F) +#define ITM_TCR_TRACE_BUS_ID_1 (0x01 << 16) +#define ITM_TCR_SWO_ENA (1 << 4) +#define ITM_TCR_DWT_ENA (1 << 3) +#define ITM_TCR_SYNC_ENA (1 << 2) +#define ITM_TCR_TS_ENA (1 << 1) +#define ITM_TCR_ITM_ENA (1 << 0) +#define ITM_LAR_KEY 0xC5ACCE55 + +// Data Watchpoint and Trace (DWT) Registers +#define DWT_CTRL 0xE0001000 // DWT Control Register +#define DWT_FUNCTION0 0xE0001028 // DWT Function Register 0 +#define DWT_FUNCTION1 0xE0001038 // DWT Function Register 1 +#define DWT_FUNCTION2 0xE0001048 // DWT Function Register 2 +#define DWT_FUNCTION3 0xE0001058 // DWT Function Register 3 + +// DWT field definitions +#define DWT_CTRL_NUM_COMP (1 << 28) +#define DWT_CTRL_CYC_TAP (1 << 9) +#define DWT_CTRL_POST_INIT (1 << 5) +#define DWT_CTRL_POST_PRESET (1 << 1) +#define DWT_CTRL_CYCCNT_ENA (1 << 0) + +// Trace Port Interface (TPI) Registers +#define TPI_CSPSR 0xE0040004 // TPI Current Parallel Port Size Register +#define TPI_ACPR 0xE0040010 // TPI Asynchronous Clock Prescaler Register +#define TPI_SPPR 0xE00400F0 // TPI Selected Pin Protocol Register +#define TPI_FFCR 0xE0040304 // TPI Formatter and Flush Control Register + +// TPI field definitions +#define TPI_TPI_CSPSR_PORT_SIZE_1 (0x01 << 0) +#define TPI_SPPR_SWO_MANCHESTER (0x01 << 0) +#define TPI_SPPR_SWO_NRZ (0x02 << 0) +#define TPI_FFCR_EN_F_CONT (0x01 << 1) +#define TPI_FFCR_F_ON_MAN (0x01 << 6) +#define TPI_FFCR_TRIG_IN (0x01 << 8) + +// Other Registers +#define FP_CTRL 0xE0002000 // Flash Patch Control Register [WHY DO WE NEED THIS?] +#define DBGMCU_CR 0xE0042004 // Debug MCU Configuration Register + +// Other register field definitions +#define FP_CTRL_KEY (1 << 1) +#define DBGMCU_CR_DBG_SLEEP (1 << 0) +#define DBGMCU_CR_DBG_STOP (1 << 1) +#define DBGMCU_CR_DBG_STANDBY (1 << 2) +#define DBGMCU_CR_TRACE_IOEN (1 << 5) +#define DBGMCU_CR_TRACE_MODE_ASYNC (0x00 << 6) + // We use a global flag to allow communicating to the main thread from the signal handler. static bool g_done = false; @@ -185,8 +243,8 @@ static stlink_t* StLinkConnect(const st_settings_t* settings) { } } -// TODO: Consider moving this to the device table. static bool IsDeviceTraceSupported(int chip_id) { + // TODO: Consider moving this to a flag in the device table. switch (chip_id) { case STLINK_CHIPID_STM32_F4: case STLINK_CHIPID_STM32_F4_DSI: @@ -224,7 +282,6 @@ static uint32_t Read32(stlink_t* stlink, uint32_t address) { } static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { - struct stlink_reg regp = {}; if (stlink_force_debug(stlink)) { ELOG("Unable to debug device\n"); @@ -238,42 +295,31 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { return false; } - // The order and values to set were taken from https://github.com/avrhack/stlink-trace/blob/master/stlink-trace.c#L386 - - Write32(stlink, 0xE000EDF0, 0xA05F0003); // Set DHCSR to C_HALT and C_DEBUGEN - Write32(stlink, 0xE000EDFC, 0x01000000); // Set TRCENA flag to enable global DWT and ITM - Write32(stlink, 0xE0002000, 0x00000002); // Set FP_CTRL to enable write - Write32(stlink, 0xE0001028, 0x00000000); // Set DWT_FUNCTION0 to DWT_FUNCTION3 to disable sampling - Write32(stlink, 0xE0001038, 0x00000000); - Write32(stlink, 0xE0001048, 0x00000000); - Write32(stlink, 0xE0001058, 0x00000000); - Write32(stlink, 0xE0001000, 0x00000000); // Clear DWT_CTRL and other registers - Write32(stlink, 0xE0001004, 0x00000000); - Write32(stlink, 0xE0001008, 0x00000000); - Write32(stlink, 0xE000100C, 0x00000000); - Write32(stlink, 0xE0001010, 0x00000000); - Write32(stlink, 0xE0001014, 0x00000000); - Write32(stlink, 0xE0001018, 0x00000000); - - stlink_read_reg(stlink, 15, ®p); // Read program counter - stlink_read_reg(stlink, 16, ®p); // Read xpsr register - - Write32(stlink, 0xE0042004, 0x00000027); // Set DBGMCU_CR to enable asynchronous transmission - - // Actually start tracing. + Write32(stlink, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT); // Debug and halt the CPU + Write32(stlink, DCB_DEMCR, DEMCR_TRCENA); // Enable tracing + Write32(stlink, FP_CTRL, FP_CTRL_KEY); // Disable flash patch unit. + Write32(stlink, DWT_FUNCTION0, 0); // Disable sampling units + Write32(stlink, DWT_FUNCTION1, 0); + Write32(stlink, DWT_FUNCTION2, 0); + Write32(stlink, DWT_FUNCTION3, 0); + Write32(stlink, DWT_CTRL, 0); // Disable other watchpoint and trace features + Write32(stlink, DBGMCU_CR, DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP | + DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_TRACE_IOEN | + DBGMCU_CR_TRACE_MODE_ASYNC); // Enable async tracing + if (stlink_trace_enable(stlink)) { - ELOG("Unable to trace device\n"); + ELOG("Unable to turn on tracing in stlink\n"); if (!settings->force) return false; } - Write32(stlink, 0xE0040004, 0x00000001); // Set TPIU_CSPSR to enable trace port width of 2 + Write32(stlink, TPI_CSPSR, TPI_TPI_CSPSR_PORT_SIZE_1); if (settings->core_frequency_mhz) { uint32_t prescaler = settings->core_frequency_mhz * 1000000 / STLINK_TRACE_FREQUENCY - 1; - Write32(stlink, 0xE0040010, prescaler); // Set TPIU_ACPR clock divisor + Write32(stlink, TPI_ACPR, prescaler); // Set TPIU_ACPR clock divisor } - uint32_t prescaler = Read32(stlink, 0xE0040010); + uint32_t prescaler = Read32(stlink, TPI_ACPR); if (prescaler) { uint32_t system_clock_speed = (prescaler + 1) * STLINK_TRACE_FREQUENCY; ILOG("Trace Port Interface configured to expect a %d MHz system clock.\n", (system_clock_speed + 500000) / 1000000); @@ -283,15 +329,17 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / 2000000 - 1;\n"); } - Write32(stlink, 0xE00400F0, 0x00000002); // Set TPIU_SPPR to Asynchronous SWO (NRZ) - Write32(stlink, 0xE0040304, 0x00000100); // Set TPIU_FFCR continuous formatting) - Write32(stlink, 0xE0000FB0, 0xC5ACCE55); // Unlock the ITM registers for write - Write32(stlink, 0xE0000E90, 0x00000400); // Set sync counter - Write32(stlink, 0xE0000E80, 0x00010003); // Set ITM_TCR flags : ITMENA,TSENA ATB=0 - Write32(stlink, 0xE0000E00, 0xFFFFFFFF); // Enable all trace ports in ITM_TER - Write32(stlink, 0xE0000E40, 0x0000000F); // Enable unprivileged access to trace ports 31:0 in ITM_TPR - Write32(stlink, 0xE0000E40, 0x400003FE); // Set DWT_CTRL flags) - Write32(stlink, 0xE000EDFC, 0x01000000); // Enable tracing (DEMCR - TRCENA bit) + Write32(stlink, TPI_FFCR, TPI_FFCR_TRIG_IN | TPI_FFCR_EN_F_CONT); + Write32(stlink, TPI_SPPR, TPI_SPPR_SWO_NRZ); + Write32(stlink, ITM_LAR, ITM_LAR_KEY); // Unlocks the following registers. + Write32(stlink, ITM_TCC, 0x00000400); // Set sync counter + Write32(stlink, ITM_TCR, ITM_TCR_TRACE_BUS_ID_1 | ITM_TCR_TS_ENA | ITM_TCR_ITM_ENA); + Write32(stlink, ITM_TER, ITM_TER_PORTS_ALL); + Write32(stlink, ITM_TPR, ITM_TPR_PORTS_ALL); + Write32(stlink, DWT_CTRL, 4 * DWT_CTRL_NUM_COMP | DWT_CTRL_CYC_TAP | + 0xF * DWT_CTRL_POST_INIT | 0xF * DWT_CTRL_POST_PRESET | + DWT_CTRL_CYCCNT_ENA); + Write32(stlink, DCB_DEMCR, DEMCR_TRCENA); // Enable tracing (again...?) return true; } From 074f061b667a2bdae8eeb26d786f88ac2920fb94 Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 30 Nov 2020 19:43:36 -0800 Subject: [PATCH 1058/1435] Verified sleep timer is about right. --- src/st-trace/trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 877bd4e35..5cafc85ec 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -141,7 +141,7 @@ static void usage(void) { puts(" -cXX, --clock=XX Specify the core frequency in MHz"); puts(" -n, --no-reset Do not reset board on connection"); puts(" -sXX, --serial=XX Use a specific serial number"); - puts(" -f, --force Ignore some errors"); + puts(" -f, --force Ignore most initialization errors"); } static void cleanup() { @@ -418,7 +418,7 @@ static bool ReadTrace(stlink_t* stlink, st_trace_t* trace) { } if (length == 0) { - usleep(1000); + usleep(1000); // Our buffer could fill in around 2ms, so sleep half that. return true; } From f51f06535eb9979456eb553a1c7724f96116e7ba Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 30 Nov 2020 21:00:29 -0800 Subject: [PATCH 1059/1435] Added a check that looks at connection results after 10 seconds and displays a diagnositic message if it looks like we are not configured correctly. --- src/st-trace/trace.c | 99 ++++++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 26 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 5cafc85ec..b2837dbbe 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -25,7 +26,6 @@ // See D4.2 of https://developer.arm.com/documentation/ddi0403/ed/ #define TRACE_OP_IS_OVERFLOW(c) ((c) == 0x70) -#define TRACE_OP_IS_SYNC(c) ((c) == 0x00) #define TRACE_OP_IS_LOCAL_TIME(c) (((c) & 0x0f) == 0x00 && ((c) & 0x70) != 0x00) #define TRACE_OP_IS_EXTENSION(c) (((c) & 0x0b) == 0x08) #define TRACE_OP_IS_GLOBAL_TIME(c) (((c) & 0xdf) == 0x94) @@ -100,7 +100,7 @@ static bool g_done = false; -struct _st_settings_t { +typedef struct { bool show_help; bool show_version; int logging_level; @@ -108,12 +108,11 @@ struct _st_settings_t { bool reset_board; bool force; char* serial_number; -}; -typedef struct _st_settings_t st_settings_t; +} st_settings_t; // We use a simple state machine to parse the trace data. -enum _trace_state { +typedef enum { TRACE_STATE_IDLE, TRACE_STATE_TARGET_SOURCE, TRACE_STATE_SKIP_FRAME, @@ -121,15 +120,22 @@ enum _trace_state { TRACE_STATE_SKIP_3, TRACE_STATE_SKIP_2, TRACE_STATE_SKIP_1, -}; -typedef enum _trace_state trace_state; +} trace_state; + +typedef struct { + time_t start_time; + bool configuration_checked; -struct _st_trace_t { trace_state state; - bool overflow; - bool error; -}; -typedef struct _st_trace_t st_trace_t; + + uint32_t count_raw_bytes; + uint32_t count_target_data; + uint32_t count_time_packets; + uint32_t count_overflow; + uint32_t count_error; + + uint8_t unknown_opcodes[256 / 8]; +} st_trace_t; static void usage(void) { @@ -295,14 +301,14 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { return false; } - Write32(stlink, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT); // Debug and halt the CPU - Write32(stlink, DCB_DEMCR, DEMCR_TRCENA); // Enable tracing - Write32(stlink, FP_CTRL, FP_CTRL_KEY); // Disable flash patch unit. - Write32(stlink, DWT_FUNCTION0, 0); // Disable sampling units + Write32(stlink, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT); + Write32(stlink, DCB_DEMCR, DEMCR_TRCENA); + Write32(stlink, FP_CTRL, FP_CTRL_KEY); + Write32(stlink, DWT_FUNCTION0, 0); Write32(stlink, DWT_FUNCTION1, 0); Write32(stlink, DWT_FUNCTION2, 0); Write32(stlink, DWT_FUNCTION3, 0); - Write32(stlink, DWT_CTRL, 0); // Disable other watchpoint and trace features + Write32(stlink, DWT_CTRL, 0); Write32(stlink, DBGMCU_CR, DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP | DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE_ASYNC); // Enable async tracing @@ -322,7 +328,8 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { uint32_t prescaler = Read32(stlink, TPI_ACPR); if (prescaler) { uint32_t system_clock_speed = (prescaler + 1) * STLINK_TRACE_FREQUENCY; - ILOG("Trace Port Interface configured to expect a %d MHz system clock.\n", (system_clock_speed + 500000) / 1000000); + uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; + ILOG("Trace Port Interface configured to expect a %d MHz system clock.\n", system_clock_speed_mhz); } else { WLOG("Trace Port Interface not configured. Specify the system clock with a --clock=XX command\n"); WLOG("line option or set it in your device's clock initialization routine, such as with:\n"); @@ -331,7 +338,7 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { Write32(stlink, TPI_FFCR, TPI_FFCR_TRIG_IN | TPI_FFCR_EN_F_CONT); Write32(stlink, TPI_SPPR, TPI_SPPR_SWO_NRZ); - Write32(stlink, ITM_LAR, ITM_LAR_KEY); // Unlocks the following registers. + Write32(stlink, ITM_LAR, ITM_LAR_KEY); Write32(stlink, ITM_TCC, 0x00000400); // Set sync counter Write32(stlink, ITM_TCR, ITM_TCR_TRACE_BUS_ID_1 | ITM_TCR_TS_ENA | ITM_TCR_ITM_ENA); Write32(stlink, ITM_TER, ITM_TER_PORTS_ALL); @@ -339,13 +346,14 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { Write32(stlink, DWT_CTRL, 4 * DWT_CTRL_NUM_COMP | DWT_CTRL_CYC_TAP | 0xF * DWT_CTRL_POST_INIT | 0xF * DWT_CTRL_POST_PRESET | DWT_CTRL_CYCCNT_ENA); - Write32(stlink, DCB_DEMCR, DEMCR_TRCENA); // Enable tracing (again...?) + Write32(stlink, DCB_DEMCR, DEMCR_TRCENA); return true; } static void UpdateTrace(st_trace_t* trace, uint8_t c) { // Parse the input using a state machine. + trace->count_raw_bytes++; switch (trace->state) { case TRACE_STATE_IDLE: @@ -360,17 +368,19 @@ static void UpdateTrace(st_trace_t* trace, uint8_t c) { WLOG("Unsupported %s source 0x%x size %d\n", type, addr, size); trace->state = kSourceSkip[size]; } else if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { + trace->count_time_packets++; if (TRACE_OP_GET_CONTINUATION(c)) trace->state = TRACE_STATE_SKIP_FRAME; } else if (TRACE_OP_IS_EXTENSION(c)) { if (TRACE_OP_GET_CONTINUATION(c)) trace->state = TRACE_STATE_SKIP_FRAME; - } else if (TRACE_OP_IS_SYNC(c)) { } else if (TRACE_OP_IS_OVERFLOW(c)) { - trace->overflow = true; + trace->count_overflow++; } else { - WLOG("Unknown opcode 0x%02x\n", c); - trace->error = true; + if (!(trace->unknown_opcodes[c / 8] & (1 << c % 8))) + WLOG("Unknown opcode 0x%02x\n", c); + trace->unknown_opcodes[c / 8] |= (1 << c % 8); + trace->count_error++; if (TRACE_OP_GET_CONTINUATION(c)) trace->state = TRACE_STATE_SKIP_FRAME; } @@ -378,6 +388,7 @@ static void UpdateTrace(st_trace_t* trace, uint8_t c) { case TRACE_STATE_TARGET_SOURCE: putchar(c); + trace->count_target_data++; trace->state = TRACE_STATE_IDLE; break; @@ -422,7 +433,6 @@ static bool ReadTrace(stlink_t* stlink, st_trace_t* trace) { return true; } - DLOG("Trace Length: %d\n", length); for (int i = 0; i < length; i++) { UpdateTrace(trace, buffer[i]); } @@ -430,6 +440,42 @@ static bool ReadTrace(stlink_t* stlink, st_trace_t* trace) { return true; } +static void CheckForConfigurationError(stlink_t* stlink, st_trace_t* trace) { + uint32_t elapsed_time_s = time(NULL) - trace->start_time; + if (trace->configuration_checked || elapsed_time_s < 10) { + return; + } + trace->configuration_checked = true; + + // Simple huristic to determine if we are configured poorly. + if (trace->count_raw_bytes < 100 || trace->count_error > 1 || trace->count_time_packets < 10) { + // Output Diagnostic Information + WLOG("****\n"); + WLOG("We do not appear to be retrieving data from the stlink correctly.\n"); + WLOG("Raw Bytes: %d\n", trace->count_raw_bytes); + WLOG("Target Data: %d\n", trace->count_target_data); + WLOG("Time Packets: %d\n", trace->count_time_packets); + WLOG("Overlow Count: %d\n", trace->count_overflow); + WLOG("Errors: %d\n", trace->count_error); + for (uint32_t i = 0; i <= 0xFF; i++) + if (trace->unknown_opcodes[i / 8] & (1 << i % 8)) + WLOG("Unknown Opcode 0x%02x\n", i); + uint32_t prescaler = Read32(stlink, TPI_ACPR); + if (prescaler) { + uint32_t system_clock_speed = (prescaler + 1) * STLINK_TRACE_FREQUENCY; + uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; + WLOG("Trace Port Interface configured to expect a %d MHz system clock.\n", system_clock_speed_mhz); + } else { + WLOG("Trace Port Interface not configured. Specify the system clock with a --clock=XX command\n"); + WLOG("line option or set it in your device's clock initialization routine, such as with:\n"); + WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / 2000000 - 1;\n"); + } + // TODO: Include clock configuration information here. + // TODO: Include TRACE/DEBUG register values here. + WLOG("****\n"); + } +} + int main(int argc, char** argv) { st_settings_t settings; @@ -503,8 +549,9 @@ int main(int argc, char** argv) ILOG("Reading Trace\n"); st_trace_t trace = {}; + trace.start_time = time(NULL); while (!g_done && ReadTrace(stlink, &trace)) { - // TODO: Check that things are roughly working. + CheckForConfigurationError(stlink, &trace); } stlink_trace_disable(stlink); From b8c459fd4bff00ef8bc7718d7b80cb3d706f15ba Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 30 Nov 2020 21:27:29 -0800 Subject: [PATCH 1060/1435] Avoiding duplicating logs for unknown sources. --- src/st-trace/trace.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index b2837dbbe..70e80b49b 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -135,6 +135,7 @@ typedef struct { uint32_t count_error; uint8_t unknown_opcodes[256 / 8]; + uint32_t unknown_sources; } st_trace_t; @@ -364,8 +365,11 @@ static void UpdateTrace(st_trace_t* trace, uint8_t c) { const char* type = TRACE_OP_IS_SW_SOURCE(c) ? "sw" : "hw"; uint8_t addr = TRACE_OP_GET_SW_SOURCE_ADDR(c); uint8_t size = TRACE_OP_GET_SOURCE_SIZE(c); - if (TRACE_OP_IS_SW_SOURCE(c)) - WLOG("Unsupported %s source 0x%x size %d\n", type, addr, size); + if (TRACE_OP_IS_SW_SOURCE(c)) { + if (!(trace->unknown_sources & (1 << addr))) + WLOG("Unsupported %s source 0x%x size %d\n", type, addr, size); + trace->unknown_sources |= (1 << addr); + } trace->state = kSourceSkip[size]; } else if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { trace->count_time_packets++; @@ -460,6 +464,9 @@ static void CheckForConfigurationError(stlink_t* stlink, st_trace_t* trace) { for (uint32_t i = 0; i <= 0xFF; i++) if (trace->unknown_opcodes[i / 8] & (1 << i % 8)) WLOG("Unknown Opcode 0x%02x\n", i); + for (uint32_t i = 0; i < 32; i++) + if (trace->unknown_sources & (1 << i)) + WLOG("Unknown Source %d\n", i); uint32_t prescaler = Read32(stlink, TPI_ACPR); if (prescaler) { uint32_t system_clock_speed = (prescaler + 1) * STLINK_TRACE_FREQUENCY; From 7ceb09dc65a3aee96d84287fc7d4a8fa35a02fe4 Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 30 Nov 2020 21:44:26 -0800 Subject: [PATCH 1061/1435] Avoiding reading register from check method as this seems to halt the process. --- src/st-trace/trace.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 70e80b49b..2ff90c8d9 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -444,7 +444,7 @@ static bool ReadTrace(stlink_t* stlink, st_trace_t* trace) { return true; } -static void CheckForConfigurationError(stlink_t* stlink, st_trace_t* trace) { +static void CheckForConfigurationError(st_trace_t* trace) { uint32_t elapsed_time_s = time(NULL) - trace->start_time; if (trace->configuration_checked || elapsed_time_s < 10) { return; @@ -467,18 +467,9 @@ static void CheckForConfigurationError(stlink_t* stlink, st_trace_t* trace) { for (uint32_t i = 0; i < 32; i++) if (trace->unknown_sources & (1 << i)) WLOG("Unknown Source %d\n", i); - uint32_t prescaler = Read32(stlink, TPI_ACPR); - if (prescaler) { - uint32_t system_clock_speed = (prescaler + 1) * STLINK_TRACE_FREQUENCY; - uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; - WLOG("Trace Port Interface configured to expect a %d MHz system clock.\n", system_clock_speed_mhz); - } else { - WLOG("Trace Port Interface not configured. Specify the system clock with a --clock=XX command\n"); - WLOG("line option or set it in your device's clock initialization routine, such as with:\n"); - WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / 2000000 - 1;\n"); - } - // TODO: Include clock configuration information here. - // TODO: Include TRACE/DEBUG register values here. + WLOG("Check that the clock frequency is set correctly. Either with the --clock=XX\n"); + WLOG("command line option, or by adding the following to your device's clock initialization:\n"); + WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / 2000000 - 1;\n"); WLOG("****\n"); } } @@ -491,6 +482,7 @@ int main(int argc, char** argv) signal(SIGINT, &cleanup); signal(SIGTERM, &cleanup); signal(SIGSEGV, &cleanup); + signal(SIGPIPE, &cleanup); if (!parse_options(argc, argv, &settings)) { usage(); @@ -558,7 +550,7 @@ int main(int argc, char** argv) st_trace_t trace = {}; trace.start_time = time(NULL); while (!g_done && ReadTrace(stlink, &trace)) { - CheckForConfigurationError(stlink, &trace); + CheckForConfigurationError(&trace); } stlink_trace_disable(stlink); From 2e4c81e2a3552cc7a5db1657b5794507d4b68403 Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 30 Nov 2020 22:30:54 -0800 Subject: [PATCH 1062/1435] Was using continouous triggering wrong. --- src/st-trace/trace.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 2ff90c8d9..b4c509063 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -80,8 +80,6 @@ #define TPI_TPI_CSPSR_PORT_SIZE_1 (0x01 << 0) #define TPI_SPPR_SWO_MANCHESTER (0x01 << 0) #define TPI_SPPR_SWO_NRZ (0x02 << 0) -#define TPI_FFCR_EN_F_CONT (0x01 << 1) -#define TPI_FFCR_F_ON_MAN (0x01 << 6) #define TPI_FFCR_TRIG_IN (0x01 << 8) // Other Registers @@ -337,7 +335,7 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / 2000000 - 1;\n"); } - Write32(stlink, TPI_FFCR, TPI_FFCR_TRIG_IN | TPI_FFCR_EN_F_CONT); + Write32(stlink, TPI_FFCR, TPI_FFCR_TRIG_IN); Write32(stlink, TPI_SPPR, TPI_SPPR_SWO_NRZ); Write32(stlink, ITM_LAR, ITM_LAR_KEY); Write32(stlink, ITM_TCC, 0x00000400); // Set sync counter From b88b19287b41e98ece35072ffa94e45a47b13fec Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 30 Nov 2020 22:41:47 -0800 Subject: [PATCH 1063/1435] Flushing stdout after every newline. This is needed for things to run correctly in some scripts. --- src/st-trace/trace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index b4c509063..a50bef4ef 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -390,6 +390,8 @@ static void UpdateTrace(st_trace_t* trace, uint8_t c) { case TRACE_STATE_TARGET_SOURCE: putchar(c); + if (c == '\n') + fflush(stdout); trace->count_target_data++; trace->state = TRACE_STATE_IDLE; break; From c2356fabac30a0daac176dd0f472d48e7a74ac77 Mon Sep 17 00:00:00 2001 From: John Hall Date: Tue, 1 Dec 2020 09:22:07 -0800 Subject: [PATCH 1064/1435] Cleaning up code before code review. --- src/st-trace/trace.c | 138 ++++++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 67 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index a50bef4ef..08775c226 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -38,6 +38,8 @@ #define TRACE_OP_GET_SW_SOURCE_ADDR(c) ((c) >> 3) +// TODO: Ideally all register and field definitions would be in a common header file. + // Instrumentation Trace Macrocell (ITM) Registers #define ITM_TER 0xE0000E00 // ITM Trace Enable Register #define ITM_TPR 0xE0000E40 // ITM Trace Privilege Register @@ -83,7 +85,7 @@ #define TPI_FFCR_TRIG_IN (0x01 << 8) // Other Registers -#define FP_CTRL 0xE0002000 // Flash Patch Control Register [WHY DO WE NEED THIS?] +#define FP_CTRL 0xE0002000 // Flash Patch Control Register #define DBGMCU_CR 0xE0042004 // Debug MCU Configuration Register // Other register field definitions @@ -94,8 +96,9 @@ #define DBGMCU_CR_TRACE_IOEN (1 << 5) #define DBGMCU_CR_TRACE_MODE_ASYNC (0x00 << 6) + // We use a global flag to allow communicating to the main thread from the signal handler. -static bool g_done = false; +static bool g_abort_trace = false; typedef struct { @@ -149,8 +152,8 @@ static void usage(void) { puts(" -f, --force Ignore most initialization errors"); } -static void cleanup() { - g_done = true; +static void abort_trace() { + g_abort_trace = true; } bool parse_options(int argc, char** argv, st_settings_t *settings) { @@ -229,19 +232,21 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { return true; } +static void ConvertSerialNumberTextToBinary(const char* text, char binary_out[STLINK_SERIAL_MAX_SIZE]) { + size_t length = 0; + for (uint32_t n = 0; n < strlen(text) && length < STLINK_SERIAL_MAX_SIZE; n += 2) { + char buffer[3] = { 0 }; + memcpy(buffer, text + n, 2); + binary_out[length++] = (uint8_t)strtol(buffer, NULL, 16); + } +} + static stlink_t* StLinkConnect(const st_settings_t* settings) { if (settings->serial_number) { - // Convert our serial number string to a binary value. - char serial_number[STLINK_SERIAL_MAX_SIZE] = { 0 }; - size_t length = 0; - for (uint32_t n = 0; n < strlen(settings->serial_number) && length < STLINK_SERIAL_MAX_SIZE; n += 2) { - char buffer[3] = { 0 }; - memcpy(buffer, settings->serial_number + n, 2); - serial_number[length++] = (uint8_t)strtol(buffer, NULL, 16); - } - // Open this specific stlink. - return stlink_open_usb(settings->logging_level, false, serial_number, 0); + char binary_serial_number[STLINK_SERIAL_MAX_SIZE] = { 0 }; + ConvertSerialNumberTextToBinary(settings->serial_number, binary_serial_number); + return stlink_open_usb(settings->logging_level, false, binary_serial_number, 0); } else { // Otherwise, open any stlink. return stlink_open_usb(settings->logging_level, false, NULL, 0); @@ -350,76 +355,75 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { return true; } -static void UpdateTrace(st_trace_t* trace, uint8_t c) { - // Parse the input using a state machine. +static trace_state UpdateTraceIdle(st_trace_t* trace, uint8_t c) { + if (TRACE_OP_IS_TARGET_SOURCE(c)) { + return TRACE_STATE_TARGET_SOURCE; + } + if (TRACE_OP_IS_SOURCE(c)) { + uint8_t size = TRACE_OP_GET_SOURCE_SIZE(c); + if (TRACE_OP_IS_SW_SOURCE(c)) { + uint8_t addr = TRACE_OP_GET_SW_SOURCE_ADDR(c); + if (!(trace->unknown_sources & (1 << addr))) + WLOG("Unsupported source 0x%x size %d\n", addr, size); + trace->unknown_sources |= (1 << addr); + } + if (size == 1) return TRACE_STATE_SKIP_1; + if (size == 2) return TRACE_STATE_SKIP_2; + if (size == 3) return TRACE_STATE_SKIP_4; + } + if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { + trace->count_time_packets++; + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; + } + if (TRACE_OP_IS_EXTENSION(c)) { + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; + } + if (TRACE_OP_IS_OVERFLOW(c)) { + trace->count_overflow++; + } + + if (!(trace->unknown_opcodes[c / 8] & (1 << c % 8))) + WLOG("Unknown opcode 0x%02x\n", c); + trace->unknown_opcodes[c / 8] |= (1 << c % 8); + + trace->count_error++; + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; +} + +static trace_state UpdateTrace(st_trace_t* trace, uint8_t c) { trace->count_raw_bytes++; + + // Parse the input using a state machine. switch (trace->state) { case TRACE_STATE_IDLE: - if (TRACE_OP_IS_TARGET_SOURCE(c)) { - trace->state = TRACE_STATE_TARGET_SOURCE; - } else if (TRACE_OP_IS_SOURCE(c)) { - const trace_state kSourceSkip[] = { TRACE_STATE_IDLE, TRACE_STATE_SKIP_1, TRACE_STATE_SKIP_2, TRACE_STATE_SKIP_4 }; - const char* type = TRACE_OP_IS_SW_SOURCE(c) ? "sw" : "hw"; - uint8_t addr = TRACE_OP_GET_SW_SOURCE_ADDR(c); - uint8_t size = TRACE_OP_GET_SOURCE_SIZE(c); - if (TRACE_OP_IS_SW_SOURCE(c)) { - if (!(trace->unknown_sources & (1 << addr))) - WLOG("Unsupported %s source 0x%x size %d\n", type, addr, size); - trace->unknown_sources |= (1 << addr); - } - trace->state = kSourceSkip[size]; - } else if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { - trace->count_time_packets++; - if (TRACE_OP_GET_CONTINUATION(c)) - trace->state = TRACE_STATE_SKIP_FRAME; - } else if (TRACE_OP_IS_EXTENSION(c)) { - if (TRACE_OP_GET_CONTINUATION(c)) - trace->state = TRACE_STATE_SKIP_FRAME; - } else if (TRACE_OP_IS_OVERFLOW(c)) { - trace->count_overflow++; - } else { - if (!(trace->unknown_opcodes[c / 8] & (1 << c % 8))) - WLOG("Unknown opcode 0x%02x\n", c); - trace->unknown_opcodes[c / 8] |= (1 << c % 8); - trace->count_error++; - if (TRACE_OP_GET_CONTINUATION(c)) - trace->state = TRACE_STATE_SKIP_FRAME; - } - break; + return UpdateTraceIdle(trace, c); case TRACE_STATE_TARGET_SOURCE: putchar(c); if (c == '\n') fflush(stdout); trace->count_target_data++; - trace->state = TRACE_STATE_IDLE; - break; + return TRACE_STATE_IDLE; case TRACE_STATE_SKIP_FRAME: - if (TRACE_OP_GET_CONTINUATION(c) == 0) - trace->state = TRACE_STATE_IDLE; - break; + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; case TRACE_STATE_SKIP_4: - trace->state = TRACE_STATE_SKIP_3; - break; + return TRACE_STATE_SKIP_3; case TRACE_STATE_SKIP_3: - trace->state = TRACE_STATE_SKIP_2; - break; + return TRACE_STATE_SKIP_2; case TRACE_STATE_SKIP_2: - trace->state = TRACE_STATE_SKIP_1; - break; + return TRACE_STATE_SKIP_1; case TRACE_STATE_SKIP_1: - trace->state = TRACE_STATE_IDLE; - break; + return TRACE_STATE_IDLE; default: ELOG("Invalid state %d. This should never happen\n", trace->state); - trace->state = TRACE_STATE_IDLE; + return TRACE_STATE_IDLE; } } @@ -438,7 +442,7 @@ static bool ReadTrace(stlink_t* stlink, st_trace_t* trace) { } for (int i = 0; i < length; i++) { - UpdateTrace(trace, buffer[i]); + trace->state = UpdateTrace(trace, buffer[i]); } return true; @@ -479,10 +483,10 @@ int main(int argc, char** argv) st_settings_t settings; stlink_t* stlink = NULL; - signal(SIGINT, &cleanup); - signal(SIGTERM, &cleanup); - signal(SIGSEGV, &cleanup); - signal(SIGPIPE, &cleanup); + signal(SIGINT, &abort_trace); + signal(SIGTERM, &abort_trace); + signal(SIGSEGV, &abort_trace); + signal(SIGPIPE, &abort_trace); if (!parse_options(argc, argv, &settings)) { usage(); @@ -549,7 +553,7 @@ int main(int argc, char** argv) ILOG("Reading Trace\n"); st_trace_t trace = {}; trace.start_time = time(NULL); - while (!g_done && ReadTrace(stlink, &trace)) { + while (!g_abort_trace && ReadTrace(stlink, &trace)) { CheckForConfigurationError(&trace); } From 793088f4389acf6a3883a3667d7e5fb9cb9a3d76 Mon Sep 17 00:00:00 2001 From: John Hall Date: Tue, 1 Dec 2020 10:25:55 -0800 Subject: [PATCH 1065/1435] Updating to use chip flags instead of multiple boolean values. --- inc/stlink.h | 2 +- src/common.c | 4 ++-- src/stlink-lib/chipid.c | 2 +- src/stlink-lib/chipid.h | 5 ++++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 1c9f6b09a..c369a133a 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -217,7 +217,7 @@ struct _stlink { enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx - bool has_dual_bank; + uint32_t chip_flags; stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() size_t flash_size; // calculated by stlink_load_device_params() diff --git a/src/common.c b/src/common.c index bda2ccf87..0325c85f9 100644 --- a/src/common.c +++ b/src/common.c @@ -868,7 +868,7 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { cr_reg = STM32Gx_FLASH_CR; cr_mer = (1 << STM32Gx_FLASH_CR_MER1); - if (sl->has_dual_bank) { + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); } @@ -1363,7 +1363,7 @@ int stlink_load_device_params(stlink_t *sl) { } sl->flash_type = params->flash_type; - sl->has_dual_bank = params->has_dual_bank; + sl->chip_flags = params->flags; sl->flash_pgsz = params->flash_pagesize; sl->sram_size = params->sram_size; sl->sys_base = params->bootrom_base; diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index a8d160445..ca35c887e 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -593,7 +593,7 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_G4_CAT3, .description = "G4 Category-3", .flash_type = STLINK_FLASH_TYPE_G4, - .has_dual_bank = true, + .flags = CHIP_F_HAS_DUAL_BANK, .flash_size_reg = 0x1FFF75E0, // Section 47.2 .flash_pagesize = 0x800, // 2k (sec 3.3.1) // SRAM1 is 80k at 0x20000000 diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index f717022ca..1573b182e 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -67,12 +67,15 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_WB55 = 0x495 }; +#define CHIP_F_HAS_DUAL_BANK (1 << 0) +#define CHIP_F_HAS_SWO_TRACING (1 << 1) + /** Chipid parameters */ struct stlink_chipid_params { uint32_t chip_id; char *description; enum stlink_flash_type flash_type; - bool has_dual_bank; + uint32_t flags; uint32_t flash_size_reg; uint32_t flash_pagesize; uint32_t sram_size; From 660dee303cd1d1dcab8bea5684d31a99dacb414c Mon Sep 17 00:00:00 2001 From: John Hall Date: Tue, 1 Dec 2020 10:41:40 -0800 Subject: [PATCH 1066/1435] Moved chip trace support into chipid where it belongs. --- src/st-trace/trace.c | 26 +--------- src/stlink-lib/chipid.c | 104 +++++++++++++++++++++++++++------------- 2 files changed, 73 insertions(+), 57 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 08775c226..b8a9f88cb 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -253,30 +253,6 @@ static stlink_t* StLinkConnect(const st_settings_t* settings) { } } -static bool IsDeviceTraceSupported(int chip_id) { - // TODO: Consider moving this to a flag in the device table. - switch (chip_id) { - case STLINK_CHIPID_STM32_F4: - case STLINK_CHIPID_STM32_F4_DSI: - case STLINK_CHIPID_STM32_F4_HD: - case STLINK_CHIPID_STM32_F4_LP: - case STLINK_CHIPID_STM32_F411RE: - case STLINK_CHIPID_STM32_F4_DE: - case STLINK_CHIPID_STM32_F446: - case STLINK_CHIPID_STM32_F410: - case STLINK_CHIPID_STM32_F3: - case STLINK_CHIPID_STM32_F37x: - case STLINK_CHIPID_STM32_F412: - case STLINK_CHIPID_STM32_F413: - case STLINK_CHIPID_STM32_F3_SMALL: - case STLINK_CHIPID_STM32_F334: - case STLINK_CHIPID_STM32_F303_HIGH: - return true; - default: - return false; - } -} - static void Write32(stlink_t* stlink, uint32_t address, uint32_t data) { write_uint32(stlink->q_buf, data); if (stlink_write_mem32(stlink, address, 4)) { @@ -531,7 +507,7 @@ int main(int argc, char** argv) return APP_RESULT_STLINK_UNSUPPORTED_LINK; } - if (!IsDeviceTraceSupported(stlink->chip_id)) { + if (!(stlink->chip_flags & CHIP_F_HAS_SWO_TRACING)) { const struct stlink_chipid_params *params = stlink_chipid_get_params(stlink->chip_id); ELOG("We do not support SWO output for device '%s'\n", params->description); if (!settings.force) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index ca35c887e..d136384f9 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -13,7 +13,8 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x00200000, // ! "System memory" starting address from .bootrom_size = 0xEDC0, // ! @todo "System memory" byte size in hex from .option_base = STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option bytes, writing uses FLASH_F7_OPTCR and FLASH_F7_OPTCR1 - .option_size = 0x20 + .option_size = 0x20, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // RM0385 and DS10916 document was used to find these paramaters @@ -24,7 +25,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, // No flash pages .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 - .bootrom_size = 0xEDC0 // "System memory" byte size in hex from DS Fig 18 + .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 18 + .flags = CHIP_F_HAS_SWO_TRACING, }, { // RM0431 and DS document was used to find these paramaters @@ -35,7 +37,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, // No flash pages .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 - .bootrom_size = 0xEDC0 // "System memory" byte size in hex from DS Fig 24 + .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 24 + .flags = CHIP_F_HAS_SWO_TRACING, }, { // table 2, PM0063 .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, @@ -45,7 +48,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x400, .sram_size = 0x5000, .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .bootrom_size = 0x800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // table 1, PM0059 .chip_id = STLINK_CHIPID_STM32_F2, @@ -58,6 +62,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7800, .option_base = 0x1FFFC000, .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // PM0063 .chip_id = STLINK_CHIPID_STM32_F1_LOW, @@ -67,7 +72,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x400, .sram_size = 0x2800, .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .bootrom_size = 0x800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F4, @@ -80,6 +86,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7800, .option_base = STM32_F4_OPTION_BYTES_BASE, .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F4_DSI, @@ -89,7 +96,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x4000, .sram_size = 0x40000, .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F4_HD, @@ -99,7 +107,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x4000, .sram_size = 0x40000, .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F4_LP, @@ -109,7 +118,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x4000, .sram_size = 0x10000, .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F411RE, @@ -119,7 +129,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x4000, .sram_size = 0x20000, .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F4_DE, @@ -129,7 +140,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x4000, .sram_size = 0x18000, .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F1_HIGH, @@ -139,7 +151,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, .sram_size = 0x10000, .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .bootrom_size = 0x800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // This ignores the EEPROM! (and uses the page erase size, @@ -151,7 +164,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x100, .sram_size = 0x4000, .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 + .bootrom_size = 0x1000, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_L1_CAT2, @@ -161,7 +175,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x100, .sram_size = 0x8000, .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 + .bootrom_size = 0x1000, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM_PLUS, @@ -171,7 +186,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x100, .sram_size = 0x8000, // not completely clear if there are some with 48k .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 + .bootrom_size = 0x1000, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_L1_HIGH, @@ -184,6 +200,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x1000, .option_base = STM32_L1_OPTION_BYTES_BASE, .option_size = 8, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_L152_RE, @@ -193,7 +210,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x100, .sram_size = 0x14000, // not completely clear if there are some with 32k .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 + .bootrom_size = 0x1000, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F1_CONN, @@ -203,7 +221,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, .sram_size = 0x10000, .bootrom_base = 0x1fffb000, - .bootrom_size = 0x4800 + .bootrom_size = 0x4800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // Low and Medium density VL have same chipid. RM0041 25.6.1 .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, @@ -213,7 +232,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x400, .sram_size = 0x2000, // 0x1000 for low density devices .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .bootrom_size = 0x800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32F446x family. Support based on DM00135183.pdf (RM0390) document. @@ -227,6 +247,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7800, .option_base = 0x1FFFC000, .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32F410 MCUs. Support based on DM00180366.pdf (RM0401) document. @@ -237,7 +258,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x4000, .sram_size = 0x8000, .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // This is STK32F303VCT6 device from STM32 F3 Discovery board. @@ -249,7 +271,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, .sram_size = 0xa000, .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .bootrom_size = 0x800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // This is STK32F373VCT6 device from STM32 F373 eval board @@ -261,7 +284,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, .sram_size = 0xa000, .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .bootrom_size = 0x800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F1_VL_HIGH, @@ -271,7 +295,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, .sram_size = 0x8000, .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .bootrom_size = 0x800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F1_XL, @@ -281,7 +306,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, .sram_size = 0x18000, .bootrom_base = 0x1fffe000, - .bootrom_size = 0x1800 + .bootrom_size = 0x1800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // Use this as an example for mapping future chips: @@ -317,7 +343,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x4000, // Table 5. Flash module organization ? .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800 // "System memory" byte size in hex from Table 4 + .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 + .flags = CHIP_F_HAS_SWO_TRACING, }, { // RM0430 DocID029473 Rev 2 document was used to find these parameters @@ -329,7 +356,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector sizes, but 0x4000 is smallest) .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 only says 0x40000) .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800 // "System memory" byte size in hex from Table 4 + .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F09X, @@ -374,7 +402,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, .sram_size = 0xa000, .bootrom_base = 0x1fffd800, - .bootrom_size = 0x2000 + .bootrom_size = 0x2000, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32L0x @@ -428,7 +457,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, .sram_size = 0x3000, .bootrom_base = 0x1fffd800, - .bootrom_size = 0x2000 + .bootrom_size = 0x2000, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // This is STK32F303RET6 device from STM32 F3 Nucelo board. @@ -440,7 +470,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, // 4.2.1 Flash memory organization .sram_size = 0x10000, // 3.3 Embedded SRAM .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory - .bootrom_size = 0x2000 + .bootrom_size = 0x2000, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32L4x6 @@ -459,6 +490,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32L4RX @@ -470,7 +502,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x1000, // 4k, section 3.3, pg 97 .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 .bootrom_base = 0x1fff0000, // 3.3.1, pg 99 - .bootrom_size = 0x7000 // 28k (per bank), same source as base (pg 99) + .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 99) + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STLINK_CHIPID_STM32_L41X @@ -484,7 +517,8 @@ static const struct stlink_chipid_params devices[] = { // SRAM2 is 8k at 0x10000000 and 0x20008000 (DS12469, sec 3.5, page 18) .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) - .bootrom_size = 0x7000 // 28k, same source as base + .bootrom_size = 0x7000, // 28k, same source as base + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STLINK_CHIPID_STM32_L43X @@ -503,6 +537,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STLINK_CHIPID_STM32_L496X @@ -519,6 +554,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STLINK_CHIPID_STM32_L46X @@ -533,7 +569,8 @@ static const struct stlink_chipid_params devices[] = { // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, page 68, also fig 2 on page 63) .sram_size = 0x20000, .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system memory, also fig 2 on page 63) - .bootrom_size = 0x7000 // 28k (per bank), same source as base + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32L011 @@ -587,13 +624,13 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32G471/473/474/483/484 (from RM0440) .chip_id = STLINK_CHIPID_STM32_G4_CAT3, .description = "G4 Category-3", .flash_type = STLINK_FLASH_TYPE_G4, - .flags = CHIP_F_HAS_DUAL_BANK, .flash_size_reg = 0x1FFF75E0, // Section 47.2 .flash_pagesize = 0x800, // 2k (sec 3.3.1) // SRAM1 is 80k at 0x20000000 @@ -604,6 +641,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, .option_size = 4, + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { // STM32WB55 (from RM0434) @@ -628,6 +666,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x20000, // "System memory" byte size in hex from Table 7 .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 + .flags = CHIP_F_HAS_SWO_TRACING, }, { // unknown @@ -638,7 +677,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x0, .sram_size = 0x0, .bootrom_base = 0x0, - .bootrom_size = 0x0 + .bootrom_size = 0x0, + .flags = 0, }, }; From ce7f0a157c1b66216c03977bd1e55291033b1d97 Mon Sep 17 00:00:00 2001 From: John Hall Date: Tue, 1 Dec 2020 10:56:40 -0800 Subject: [PATCH 1067/1435] One last cleanup before I feel this code is ready to submit for CR. --- src/st-trace/trace.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index b8a9f88cb..379c4cec1 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -97,10 +97,6 @@ #define DBGMCU_CR_TRACE_MODE_ASYNC (0x00 << 6) -// We use a global flag to allow communicating to the main thread from the signal handler. -static bool g_abort_trace = false; - - typedef struct { bool show_help; bool show_version; @@ -140,6 +136,13 @@ typedef struct { } st_trace_t; +// We use a global flag to allow communicating to the main thread from the signal handler. +static bool g_abort_trace = false; + +static void abort_trace() { + g_abort_trace = true; +} + static void usage(void) { puts("st-trace - usage:"); puts(" -h, --help Print this help"); @@ -152,10 +155,6 @@ static void usage(void) { puts(" -f, --force Ignore most initialization errors"); } -static void abort_trace() { - g_abort_trace = true; -} - bool parse_options(int argc, char** argv, st_settings_t *settings) { static struct option long_options[] = { @@ -332,9 +331,12 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { } static trace_state UpdateTraceIdle(st_trace_t* trace, uint8_t c) { + // Handle a trace byte when we are in the idle state. + if (TRACE_OP_IS_TARGET_SOURCE(c)) { return TRACE_STATE_TARGET_SOURCE; } + if (TRACE_OP_IS_SOURCE(c)) { uint8_t size = TRACE_OP_GET_SOURCE_SIZE(c); if (TRACE_OP_IS_SW_SOURCE(c)) { @@ -347,13 +349,16 @@ static trace_state UpdateTraceIdle(st_trace_t* trace, uint8_t c) { if (size == 2) return TRACE_STATE_SKIP_2; if (size == 3) return TRACE_STATE_SKIP_4; } + if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { trace->count_time_packets++; return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; } + if (TRACE_OP_IS_EXTENSION(c)) { return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; } + if (TRACE_OP_IS_OVERFLOW(c)) { trace->count_overflow++; } From 4f762501c2c333aacc3e143fd0549bbe16c442e4 Mon Sep 17 00:00:00 2001 From: John Hall Date: Tue, 1 Dec 2020 12:08:29 -0800 Subject: [PATCH 1068/1435] Using debug instead of write. Fixing buffer semantics. --- inc/stlink.h | 2 +- src/st-trace/trace.c | 83 +++++++++++++++++++------------------------- src/stlink-lib/usb.c | 6 ++-- 3 files changed, 40 insertions(+), 51 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index c369a133a..d40fdbb71 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -83,7 +83,7 @@ enum target_state { #define STLINK_V3_MAX_FREQ_NB 10 -#define STLINK_TRACE_BUF_LEN 4096 +#define STLINK_TRACE_BUF_LEN 2048 #define STLINK_TRACE_FREQUENCY 2000000 /* Cortex Debug Control Block */ diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 379c4cec1..868334e49 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -252,20 +252,6 @@ static stlink_t* StLinkConnect(const st_settings_t* settings) { } } -static void Write32(stlink_t* stlink, uint32_t address, uint32_t data) { - write_uint32(stlink->q_buf, data); - if (stlink_write_mem32(stlink, address, 4)) { - ELOG("Unable to set address 0x%08x to 0x%08x\n", address, data); - } -} - -static uint32_t Read32(stlink_t* stlink, uint32_t address) { - if (stlink_read_mem32(stlink, address, 4)) { - ELOG("Unable to read from address 0x%08x\n", address); - } - return read_uint32(stlink->q_buf, 0); -} - static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { if (stlink_force_debug(stlink)) { @@ -274,23 +260,23 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { return false; } - if (settings->reset_board && stlink_reset(stlink)) { + if (settings->reset_board && stlink_jtag_reset(stlink, 2)) { ELOG("Unable to reset device\n"); if (!settings->force) return false; } - Write32(stlink, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT); - Write32(stlink, DCB_DEMCR, DEMCR_TRCENA); - Write32(stlink, FP_CTRL, FP_CTRL_KEY); - Write32(stlink, DWT_FUNCTION0, 0); - Write32(stlink, DWT_FUNCTION1, 0); - Write32(stlink, DWT_FUNCTION2, 0); - Write32(stlink, DWT_FUNCTION3, 0); - Write32(stlink, DWT_CTRL, 0); - Write32(stlink, DBGMCU_CR, DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP | - DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_TRACE_IOEN | - DBGMCU_CR_TRACE_MODE_ASYNC); // Enable async tracing + stlink_write_debug32(stlink, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT); + stlink_write_debug32(stlink, DCB_DEMCR, DEMCR_TRCENA); + stlink_write_debug32(stlink, FP_CTRL, FP_CTRL_KEY); + stlink_write_debug32(stlink, DWT_FUNCTION0, 0); + stlink_write_debug32(stlink, DWT_FUNCTION1, 0); + stlink_write_debug32(stlink, DWT_FUNCTION2, 0); + stlink_write_debug32(stlink, DWT_FUNCTION3, 0); + stlink_write_debug32(stlink, DWT_CTRL, 0); + stlink_write_debug32(stlink, DBGMCU_CR, DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP | + DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_TRACE_IOEN | + DBGMCU_CR_TRACE_MODE_ASYNC); // Enable async tracing if (stlink_trace_enable(stlink)) { ELOG("Unable to turn on tracing in stlink\n"); @@ -298,13 +284,26 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { return false; } - Write32(stlink, TPI_CSPSR, TPI_TPI_CSPSR_PORT_SIZE_1); + stlink_write_debug32(stlink, TPI_CSPSR, TPI_TPI_CSPSR_PORT_SIZE_1); if (settings->core_frequency_mhz) { uint32_t prescaler = settings->core_frequency_mhz * 1000000 / STLINK_TRACE_FREQUENCY - 1; - Write32(stlink, TPI_ACPR, prescaler); // Set TPIU_ACPR clock divisor - } - uint32_t prescaler = Read32(stlink, TPI_ACPR); + stlink_write_debug32(stlink, TPI_ACPR, prescaler); // Set TPIU_ACPR clock divisor + } + stlink_write_debug32(stlink, TPI_FFCR, TPI_FFCR_TRIG_IN); + stlink_write_debug32(stlink, TPI_SPPR, TPI_SPPR_SWO_NRZ); + stlink_write_debug32(stlink, ITM_LAR, ITM_LAR_KEY); + stlink_write_debug32(stlink, ITM_TCC, 0x00000400); // Set sync counter + stlink_write_debug32(stlink, ITM_TCR, ITM_TCR_TRACE_BUS_ID_1 | ITM_TCR_TS_ENA | ITM_TCR_ITM_ENA); + stlink_write_debug32(stlink, ITM_TER, ITM_TER_PORTS_ALL); + stlink_write_debug32(stlink, ITM_TPR, ITM_TPR_PORTS_ALL); + stlink_write_debug32(stlink, DWT_CTRL, 4 * DWT_CTRL_NUM_COMP | DWT_CTRL_CYC_TAP | + 0xF * DWT_CTRL_POST_INIT | 0xF * DWT_CTRL_POST_PRESET | + DWT_CTRL_CYCCNT_ENA); + stlink_write_debug32(stlink, DCB_DEMCR, DEMCR_TRCENA); + + uint32_t prescaler; + stlink_read_debug32(stlink, TPI_ACPR, &prescaler); if (prescaler) { uint32_t system_clock_speed = (prescaler + 1) * STLINK_TRACE_FREQUENCY; uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; @@ -312,21 +311,9 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { } else { WLOG("Trace Port Interface not configured. Specify the system clock with a --clock=XX command\n"); WLOG("line option or set it in your device's clock initialization routine, such as with:\n"); - WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / 2000000 - 1;\n"); + WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / %d - 1;\n", STLINK_TRACE_FREQUENCY); } - Write32(stlink, TPI_FFCR, TPI_FFCR_TRIG_IN); - Write32(stlink, TPI_SPPR, TPI_SPPR_SWO_NRZ); - Write32(stlink, ITM_LAR, ITM_LAR_KEY); - Write32(stlink, ITM_TCC, 0x00000400); // Set sync counter - Write32(stlink, ITM_TCR, ITM_TCR_TRACE_BUS_ID_1 | ITM_TCR_TS_ENA | ITM_TCR_ITM_ENA); - Write32(stlink, ITM_TER, ITM_TER_PORTS_ALL); - Write32(stlink, ITM_TPR, ITM_TPR_PORTS_ALL); - Write32(stlink, DWT_CTRL, 4 * DWT_CTRL_NUM_COMP | DWT_CTRL_CYC_TAP | - 0xF * DWT_CTRL_POST_INIT | 0xF * DWT_CTRL_POST_PRESET | - DWT_CTRL_CYCCNT_ENA); - Write32(stlink, DCB_DEMCR, DEMCR_TRCENA); - return true; } @@ -417,8 +404,9 @@ static bool ReadTrace(stlink_t* stlink, st_trace_t* trace) { return false; } + DLOG("Trace Length %d\n", length); if (length == 0) { - usleep(1000); // Our buffer could fill in around 2ms, so sleep half that. + // usleep(100); return true; } @@ -525,15 +513,16 @@ int main(int argc, char** argv) return APP_RESULT_STLINK_STATE_ERROR; } + ILOG("Reading Trace\n"); + st_trace_t trace = {}; + trace.start_time = time(NULL); + if (stlink_run(stlink)) { ELOG("Unable to run device\n"); if (!settings.force) return APP_RESULT_STLINK_STATE_ERROR; } - ILOG("Reading Trace\n"); - st_trace_t trace = {}; - trace.start_time = time(NULL); while (!g_abort_trace && ReadTrace(stlink, &trace)) { CheckForConfigurationError(&trace); } diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index db187acc5..5b84bb36a 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -982,7 +982,7 @@ int _stlink_usb_enable_trace(stlink_t* sl) { int i = fill_command(sl, SG_DXFER_TO_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_START_TRACE_RX; - write_uint16(&cmd[i + 0], STLINK_TRACE_BUF_LEN); + write_uint16(&cmd[i + 0], 2 * STLINK_TRACE_BUF_LEN); write_uint32(&cmd[i + 2], STLINK_TRACE_FREQUENCY); size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); @@ -1053,8 +1053,8 @@ int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { int res = 0; int t = libusb_bulk_transfer(slu->usb_handle, slu->ep_trace, buf, trace_count, &res, 3000); - if (t) { - ELOG("read_trace read error\n"); + if (t || res != trace_count) { + ELOG("read_trace read error %d\n", t); return(-1); } } From aaaae8a61c3bbe4753c85cbff4830fcade9bd462 Mon Sep 17 00:00:00 2001 From: John Hall Date: Tue, 1 Dec 2020 13:05:19 -0800 Subject: [PATCH 1069/1435] Minor change didn't compile. --- src/stlink-lib/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 5b84bb36a..97b616532 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1053,7 +1053,7 @@ int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { int res = 0; int t = libusb_bulk_transfer(slu->usb_handle, slu->ep_trace, buf, trace_count, &res, 3000); - if (t || res != trace_count) { + if (t || res != (int)trace_count) { ELOG("read_trace read error %d\n", t); return(-1); } From ac104ebabea7ad796eff2e6ebe88f22d113aeafe Mon Sep 17 00:00:00 2001 From: John Hall Date: Tue, 1 Dec 2020 13:47:04 -0800 Subject: [PATCH 1070/1435] Allowed configuring trace frequency. --- inc/backend.h | 2 +- inc/stlink.h | 9 ++++-- src/common.c | 6 ++-- src/st-trace/trace.c | 67 +++++++++++++++++++++++++++++--------------- src/stlink-lib/usb.c | 4 +-- 5 files changed, 57 insertions(+), 31 deletions(-) diff --git a/inc/backend.h b/inc/backend.h index 470702fde..70b3b739f 100644 --- a/inc/backend.h +++ b/inc/backend.h @@ -29,7 +29,7 @@ int (*force_debug) (stlink_t *sl); int32_t (*target_voltage) (stlink_t *sl); int (*set_swdclk) (stlink_t * stl, uint16_t divisor); - int (*trace_enable) (stlink_t * sl); + int (*trace_enable) (stlink_t * sl, uint32_t frequency); int (*trace_disable) (stlink_t * sl); int (*trace_read) (stlink_t * sl, uint8_t* buf, size_t size); diff --git a/inc/stlink.h b/inc/stlink.h index d40fdbb71..653b48e44 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -83,8 +83,10 @@ enum target_state { #define STLINK_V3_MAX_FREQ_NB 10 -#define STLINK_TRACE_BUF_LEN 2048 -#define STLINK_TRACE_FREQUENCY 2000000 +#define STLINK_TRACE_BUF_LEN 2048 +#define STLINK_V2_MAX_TRACE_FREQUENCY 2000000 +#define STLINK_V3_MAX_TRACE_FREQUENCY 24000000 +#define STLINK_DEFAULT_TRACE_FREQUENCY 2000000 /* Cortex Debug Control Block */ #define DCB_DHCSR 0xE000EDF0 @@ -214,6 +216,7 @@ struct _stlink { char serial[STLINK_SERIAL_MAX_SIZE]; int serial_size; int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR + uint32_t max_trace_freq; // set by stlink_open_usb() enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx @@ -267,7 +270,7 @@ int stlink_current_mode(stlink_t *sl); int stlink_force_debug(stlink_t *sl); int stlink_target_voltage(stlink_t *sl); int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); -int stlink_trace_enable(stlink_t* sl); +int stlink_trace_enable(stlink_t* sl, uint32_t frequency); int stlink_trace_disable(stlink_t* sl); int stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size); diff --git a/src/common.c b/src/common.c index 0325c85f9..ac78db089 100644 --- a/src/common.c +++ b/src/common.c @@ -1468,6 +1468,7 @@ void _parse_version(stlink_t *sl, stlink_version_t *slv) { if (sl->version.jtag_v >= 13) { sl->version.flags |= STLINK_F_HAS_TRACE; + sl->max_trace_freq = STLINK_V2_MAX_TRACE_FREQUENCY; } } } else { @@ -1483,6 +1484,7 @@ void _parse_version(stlink_t *sl, stlink_version_t *slv) { /* preferred API to get last R/W status */ sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; sl->version.flags |= STLINK_F_HAS_TRACE; + sl->max_trace_freq = STLINK_V3_MAX_TRACE_FREQUENCY; } return; @@ -1682,9 +1684,9 @@ int stlink_current_mode(stlink_t *sl) { return(STLINK_DEV_UNKNOWN_MODE); } -int stlink_trace_enable(stlink_t* sl) { +int stlink_trace_enable(stlink_t* sl, uint32_t frequency) { DLOG("*** stlink_trace_enable ***\n"); - return(sl->backend->trace_enable(sl)); + return(sl->backend->trace_enable(sl, frequency)); } int stlink_trace_disable(stlink_t* sl) { diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 868334e49..fe4e20fdc 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -22,7 +22,8 @@ #define APP_RESULT_STLINK_MISSING_DEVICE 3 #define APP_RESULT_STLINK_UNSUPPORTED_DEVICE 4 #define APP_RESULT_STLINK_UNSUPPORTED_LINK 5 -#define APP_RESULT_STLINK_STATE_ERROR 6 +#define APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY 6 +#define APP_RESULT_STLINK_STATE_ERROR 7 // See D4.2 of https://developer.arm.com/documentation/ddi0403/ed/ #define TRACE_OP_IS_OVERFLOW(c) ((c) == 0x70) @@ -98,13 +99,14 @@ typedef struct { - bool show_help; - bool show_version; - int logging_level; - int core_frequency_mhz; - bool reset_board; - bool force; - char* serial_number; + bool show_help; + bool show_version; + int logging_level; + uint32_t core_frequency; + uint32_t trace_frequency; + bool reset_board; + bool force; + char* serial_number; } st_settings_t; @@ -150,6 +152,7 @@ static void usage(void) { puts(" -vXX, --verbose=XX Specify a specific verbosity level (0..99)"); puts(" -v, --verbose Specify a generally verbose logging"); puts(" -cXX, --clock=XX Specify the core frequency in MHz"); + puts(" -tXX, --trace=XX Specify the trace frequency in Hz"); puts(" -n, --no-reset Do not reset board on connection"); puts(" -sXX, --serial=XX Use a specific serial number"); puts(" -f, --force Ignore most initialization errors"); @@ -162,6 +165,7 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { {"version", no_argument, NULL, 'V'}, {"verbose", optional_argument, NULL, 'v'}, {"clock", required_argument, NULL, 'c'}, + {"trace", required_argument, NULL, 't'}, {"no-reset", no_argument, NULL, 'n'}, {"serial", required_argument, NULL, 's'}, {"force", no_argument, NULL, 'f'}, @@ -174,7 +178,8 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { settings->show_help = false; settings->show_version = false; settings->logging_level = DEFAULT_LOGGING_LEVEL; - settings->core_frequency_mhz = 0; + settings->core_frequency = 0; + settings->trace_frequency = 0; settings->reset_board = true; settings->force = false; settings->serial_number = NULL; @@ -197,7 +202,10 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { ugly_init(settings->logging_level); break; case 'c': - settings->core_frequency_mhz = atoi(optarg); + settings->core_frequency = atoi(optarg) * 1000000; + break; + case 't': + settings->trace_frequency = atoi(optarg); break; case 'n': settings->reset_board = false; @@ -252,7 +260,7 @@ static stlink_t* StLinkConnect(const st_settings_t* settings) { } } -static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { +static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings, uint32_t trace_frequency) { if (stlink_force_debug(stlink)) { ELOG("Unable to debug device\n"); @@ -278,7 +286,8 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE_ASYNC); // Enable async tracing - if (stlink_trace_enable(stlink)) { + DLOG("Setting trace frequency to %d Hz.\n", trace_frequency); + if (stlink_trace_enable(stlink, trace_frequency)) { ELOG("Unable to turn on tracing in stlink\n"); if (!settings->force) return false; @@ -286,8 +295,8 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { stlink_write_debug32(stlink, TPI_CSPSR, TPI_TPI_CSPSR_PORT_SIZE_1); - if (settings->core_frequency_mhz) { - uint32_t prescaler = settings->core_frequency_mhz * 1000000 / STLINK_TRACE_FREQUENCY - 1; + if (settings->core_frequency) { + uint32_t prescaler = settings->core_frequency / trace_frequency - 1; stlink_write_debug32(stlink, TPI_ACPR, prescaler); // Set TPIU_ACPR clock divisor } stlink_write_debug32(stlink, TPI_FFCR, TPI_FFCR_TRIG_IN); @@ -305,13 +314,13 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings) { uint32_t prescaler; stlink_read_debug32(stlink, TPI_ACPR, &prescaler); if (prescaler) { - uint32_t system_clock_speed = (prescaler + 1) * STLINK_TRACE_FREQUENCY; + uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; ILOG("Trace Port Interface configured to expect a %d MHz system clock.\n", system_clock_speed_mhz); } else { WLOG("Trace Port Interface not configured. Specify the system clock with a --clock=XX command\n"); WLOG("line option or set it in your device's clock initialization routine, such as with:\n"); - WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / %d - 1;\n", STLINK_TRACE_FREQUENCY); + WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / %d - 1;\n", trace_frequency); } return true; @@ -404,12 +413,14 @@ static bool ReadTrace(stlink_t* stlink, st_trace_t* trace) { return false; } - DLOG("Trace Length %d\n", length); if (length == 0) { - // usleep(100); + usleep(100); return true; } + if (length == sizeof(buffer)) { + } + for (int i = 0; i < length; i++) { trace->state = UpdateTrace(trace, buffer[i]); } @@ -417,7 +428,7 @@ static bool ReadTrace(stlink_t* stlink, st_trace_t* trace) { return true; } -static void CheckForConfigurationError(st_trace_t* trace) { +static void CheckForConfigurationError(st_trace_t* trace, uint32_t trace_frequency) { uint32_t elapsed_time_s = time(NULL) - trace->start_time; if (trace->configuration_checked || elapsed_time_s < 10) { return; @@ -442,7 +453,7 @@ static void CheckForConfigurationError(st_trace_t* trace) { WLOG("Unknown Source %d\n", i); WLOG("Check that the clock frequency is set correctly. Either with the --clock=XX\n"); WLOG("command line option, or by adding the following to your device's clock initialization:\n"); - WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / 2000000 - 1;\n"); + WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / %d - 1;\n", trace_frequency); WLOG("****\n"); } } @@ -465,7 +476,8 @@ int main(int argc, char** argv) DLOG("show_help = %s\n", settings.show_help ? "true" : "false"); DLOG("show_version = %s\n", settings.show_version ? "true" : "false"); DLOG("logging_level = %d\n", settings.logging_level); - DLOG("core_frequency = %d MHz\n", settings.core_frequency_mhz); + DLOG("core_frequency = %d Hz\n", settings.core_frequency); + DLOG("trace_frequency = %d Hz\n", settings.trace_frequency); DLOG("reset_board = %s\n", settings.reset_board ? "true" : "false"); DLOG("force = %s\n", settings.force ? "true" : "false"); DLOG("serial_number = %s\n", settings.serial_number ? settings.serial_number : "any"); @@ -507,7 +519,16 @@ int main(int argc, char** argv) return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; } - if (!EnableTrace(stlink, &settings)) { + uint32_t trace_frequency = settings.trace_frequency; + if (!trace_frequency) + trace_frequency = STLINK_DEFAULT_TRACE_FREQUENCY; + if (trace_frequency > stlink->max_trace_freq) { + ELOG("Invalid trace frequency %d (max %d)\n", trace_frequency, stlink->max_trace_freq); + if (!settings.force) + return APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY; + } + + if (!EnableTrace(stlink, &settings, trace_frequency)) { ELOG("Unable to enable trace mode\n"); if (!settings.force) return APP_RESULT_STLINK_STATE_ERROR; @@ -524,7 +545,7 @@ int main(int argc, char** argv) } while (!g_abort_trace && ReadTrace(stlink, &trace)) { - CheckForConfigurationError(&trace); + CheckForConfigurationError(&trace, trace_frequency); } stlink_trace_disable(stlink); diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 97b616532..db11968a6 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -972,7 +972,7 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { return(0); } -int _stlink_usb_enable_trace(stlink_t* sl) { +int _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -983,7 +983,7 @@ int _stlink_usb_enable_trace(stlink_t* sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_START_TRACE_RX; write_uint16(&cmd[i + 0], 2 * STLINK_TRACE_BUF_LEN); - write_uint32(&cmd[i + 2], STLINK_TRACE_FREQUENCY); + write_uint32(&cmd[i + 2], frequency); size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); From a331da4df3e539c39820a4404b3a2f4ee591df84 Mon Sep 17 00:00:00 2001 From: John Hall Date: Tue, 1 Dec 2020 15:54:40 -0800 Subject: [PATCH 1071/1435] Improving diagnostics, especially for sw buffer overruns. --- src/st-trace/trace.c | 88 +++++++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 26 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index fe4e20fdc..f82a804c6 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -130,7 +130,8 @@ typedef struct { uint32_t count_raw_bytes; uint32_t count_target_data; uint32_t count_time_packets; - uint32_t count_overflow; + uint32_t count_hw_overflow; + uint32_t count_sw_overflow; uint32_t count_error; uint8_t unknown_opcodes[256 / 8]; @@ -356,7 +357,7 @@ static trace_state UpdateTraceIdle(st_trace_t* trace, uint8_t c) { } if (TRACE_OP_IS_OVERFLOW(c)) { - trace->count_overflow++; + trace->count_hw_overflow++; } if (!(trace->unknown_opcodes[c / 8] & (1 << c % 8))) @@ -419,6 +420,10 @@ static bool ReadTrace(stlink_t* stlink, st_trace_t* trace) { } if (length == sizeof(buffer)) { + if (trace->count_sw_overflow++) + DLOG("Buffer overflow.\n"); + else + WLOG("Buffer overflow. Try using a slower trace frequency.\n"); } for (int i = 0; i < length; i++) { @@ -428,7 +433,8 @@ static bool ReadTrace(stlink_t* stlink, st_trace_t* trace) { return true; } -static void CheckForConfigurationError(st_trace_t* trace, uint32_t trace_frequency) { +static void CheckForConfigurationError(stlink_t* stlink, st_trace_t* trace, uint32_t trace_frequency) { + // Only check configuration one time after the first 10 seconds of running. uint32_t elapsed_time_s = time(NULL) - trace->start_time; if (trace->configuration_checked || elapsed_time_s < 10) { return; @@ -436,38 +442,68 @@ static void CheckForConfigurationError(st_trace_t* trace, uint32_t trace_frequen trace->configuration_checked = true; // Simple huristic to determine if we are configured poorly. - if (trace->count_raw_bytes < 100 || trace->count_error > 1 || trace->count_time_packets < 10) { - // Output Diagnostic Information - WLOG("****\n"); - WLOG("We do not appear to be retrieving data from the stlink correctly.\n"); - WLOG("Raw Bytes: %d\n", trace->count_raw_bytes); - WLOG("Target Data: %d\n", trace->count_target_data); - WLOG("Time Packets: %d\n", trace->count_time_packets); - WLOG("Overlow Count: %d\n", trace->count_overflow); - WLOG("Errors: %d\n", trace->count_error); - for (uint32_t i = 0; i <= 0xFF; i++) - if (trace->unknown_opcodes[i / 8] & (1 << i % 8)) - WLOG("Unknown Opcode 0x%02x\n", i); - for (uint32_t i = 0; i < 32; i++) - if (trace->unknown_sources & (1 << i)) - WLOG("Unknown Source %d\n", i); - WLOG("Check that the clock frequency is set correctly. Either with the --clock=XX\n"); - WLOG("command line option, or by adding the following to your device's clock initialization:\n"); + bool error_no_data = (trace->count_raw_bytes < 100); + bool error_bad_data = (trace->count_error > 1 || trace->count_time_packets < 10 || trace->unknown_sources > 0); + bool error_dropped_data = (trace->count_sw_overflow > 0); + + if (!error_no_data && !error_bad_data && !error_dropped_data) + return; + + WLOG("****\n"); + WLOG("We do not appear to be retrieving data from the stlink correctly.\n"); + + if (error_dropped_data) { + WLOG("Try setting a slower trace frequency with the --trace=%d command line option.\n", trace_frequency / 2); + } + + if (error_no_data || error_bad_data) { + uint32_t prescaler; + stlink_read_debug32(stlink, TPI_ACPR, &prescaler); + if (prescaler) { + uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; + uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; + WLOG("Verify the system clock is running at %d MHz.\n", system_clock_speed_mhz); + } + WLOG("Try specifying the system clock with the --clock=XX command line option.\n"); + WLOG("Try setting the trace speed in your device's clock initialization routine:\n"); WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / %d - 1;\n", trace_frequency); - WLOG("****\n"); } + + WLOG("Diagnostic Information:\n"); + WLOG("Raw Bytes: %d\n", trace->count_raw_bytes); + WLOG("Target Data: %d\n", trace->count_target_data); + WLOG("Time Packets: %d\n", trace->count_time_packets); + WLOG("Hardware Overflow Count: %d\n", trace->count_hw_overflow); + WLOG("Software Overflow Count: %d\n", trace->count_sw_overflow); + WLOG("Errors: %d\n", trace->count_error); + + char buffer[1024]; + memset(buffer, 0, sizeof(buffer)); + uint32_t offset = 0; + for (uint32_t i = 0; i <= 0xFF; i++) + if (trace->unknown_opcodes[i / 8] & (1 << i % 8)) + offset += snprintf(buffer + offset, sizeof(buffer) - offset, "%02x, ", i); + WLOG("Unknown Opcodes: %s\n", buffer); + + memset(buffer, 0, sizeof(buffer)); + offset = 0; + for (uint32_t i = 0; i < 32; i++) + if (trace->unknown_sources & (1 << i)) + offset += snprintf(buffer + offset, sizeof(buffer) - offset, "%d, ", i); + WLOG("Unknown Sources: %s\n", buffer); + + WLOG("Chip ID: 0x%04x\n", stlink->chip_id); + WLOG("****\n"); } int main(int argc, char** argv) { - st_settings_t settings; - stlink_t* stlink = NULL; - signal(SIGINT, &abort_trace); signal(SIGTERM, &abort_trace); signal(SIGSEGV, &abort_trace); signal(SIGPIPE, &abort_trace); + st_settings_t settings; if (!parse_options(argc, argv, &settings)) { usage(); return APP_RESULT_INVALID_PARAMS; @@ -492,7 +528,7 @@ int main(int argc, char** argv) return APP_RESULT_SUCCESS; } - stlink = StLinkConnect(&settings); + stlink_t* stlink = StLinkConnect(&settings); if (!stlink) { ELOG("Unable to locate an stlink\n"); return APP_RESULT_STLINK_NOT_FOUND; @@ -545,7 +581,7 @@ int main(int argc, char** argv) } while (!g_abort_trace && ReadTrace(stlink, &trace)) { - CheckForConfigurationError(&trace, trace_frequency); + CheckForConfigurationError(stlink, &trace, trace_frequency); } stlink_trace_disable(stlink); From 57f1bc791112ce2cacb3481484747b6332b537fa Mon Sep 17 00:00:00 2001 From: John Hall Date: Tue, 1 Dec 2020 16:28:10 -0800 Subject: [PATCH 1072/1435] Making sure TPI async prescalar is within the available range. Trying to recover from buffer overruns where we may land in the middle of trace output. --- src/st-trace/trace.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index f82a804c6..8368cee34 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -84,6 +84,7 @@ #define TPI_SPPR_SWO_MANCHESTER (0x01 << 0) #define TPI_SPPR_SWO_NRZ (0x02 << 0) #define TPI_FFCR_TRIG_IN (0x01 << 8) +#define TPI_ACPR_MAX (0x1FFF) // Other Registers #define FP_CTRL 0xE0002000 // Flash Patch Control Register @@ -112,6 +113,7 @@ typedef struct { // We use a simple state machine to parse the trace data. typedef enum { + TRACE_STATE_UNKNOWN, TRACE_STATE_IDLE, TRACE_STATE_TARGET_SOURCE, TRACE_STATE_SKIP_FRAME, @@ -298,6 +300,11 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings, uint32_ if (settings->core_frequency) { uint32_t prescaler = settings->core_frequency / trace_frequency - 1; + if (prescaler > TPI_ACPR_MAX) { + ELOG("Trace frequency prescaler %d out of range. Try setting a faster trace frequency.\n", prescaler); + if (!settings->force) + return false; + } stlink_write_debug32(stlink, TPI_ACPR, prescaler); // Set TPIU_ACPR clock divisor } stlink_write_debug32(stlink, TPI_FFCR, TPI_FFCR_TRIG_IN); @@ -372,6 +379,12 @@ static trace_state UpdateTrace(st_trace_t* trace, uint8_t c) { trace->count_raw_bytes++; // Parse the input using a state machine. + + if (trace->state == TRACE_STATE_UNKNOWN) { + if (TRACE_OP_IS_TARGET_SOURCE(c) || TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) + trace->state = TRACE_STATE_IDLE; + } + switch (trace->state) { case TRACE_STATE_IDLE: @@ -399,6 +412,9 @@ static trace_state UpdateTrace(st_trace_t* trace, uint8_t c) { case TRACE_STATE_SKIP_1: return TRACE_STATE_IDLE; + case TRACE_STATE_UNKNOWN: + return TRACE_STATE_UNKNOWN; + default: ELOG("Invalid state %d. This should never happen\n", trace->state); return TRACE_STATE_IDLE; @@ -424,6 +440,7 @@ static bool ReadTrace(stlink_t* stlink, st_trace_t* trace) { DLOG("Buffer overflow.\n"); else WLOG("Buffer overflow. Try using a slower trace frequency.\n"); + trace->state = TRACE_STATE_UNKNOWN; } for (int i = 0; i < length; i++) { From 305b7a4f2b3723af690931b11ac8e81167d14230 Mon Sep 17 00:00:00 2001 From: John Hall Date: Tue, 1 Dec 2020 16:35:40 -0800 Subject: [PATCH 1073/1435] Inproving huristic to handle cases where there is lots of valid data coming in that is starving out the time trace ops. --- src/st-trace/trace.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 8368cee34..1356ceca0 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -289,7 +289,6 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings, uint32_ DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE_ASYNC); // Enable async tracing - DLOG("Setting trace frequency to %d Hz.\n", trace_frequency); if (stlink_trace_enable(stlink, trace_frequency)) { ELOG("Unable to turn on tracing in stlink\n"); if (!settings->force) @@ -330,6 +329,7 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings, uint32_ WLOG("line option or set it in your device's clock initialization routine, such as with:\n"); WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / %d - 1;\n", trace_frequency); } + ILOG("Trace frequency set to %d Hz.\n", trace_frequency); return true; } @@ -460,10 +460,11 @@ static void CheckForConfigurationError(stlink_t* stlink, st_trace_t* trace, uint // Simple huristic to determine if we are configured poorly. bool error_no_data = (trace->count_raw_bytes < 100); - bool error_bad_data = (trace->count_error > 1 || trace->count_time_packets < 10 || trace->unknown_sources > 0); + bool error_low_data = (trace->count_time_packets < 10 && trace->count_target_data < 1000); + bool error_bad_data = (trace->count_error > 1 || trace->unknown_sources > 0); bool error_dropped_data = (trace->count_sw_overflow > 0); - if (!error_no_data && !error_bad_data && !error_dropped_data) + if (!error_no_data && !error_low_data && !error_bad_data && !error_dropped_data) return; WLOG("****\n"); @@ -473,7 +474,7 @@ static void CheckForConfigurationError(stlink_t* stlink, st_trace_t* trace, uint WLOG("Try setting a slower trace frequency with the --trace=%d command line option.\n", trace_frequency / 2); } - if (error_no_data || error_bad_data) { + if (error_no_data || error_low_data || error_bad_data) { uint32_t prescaler; stlink_read_debug32(stlink, TPI_ACPR, &prescaler); if (prescaler) { From fdeb1729d68aa1949f856dc539a444c8c7a1bb06 Mon Sep 17 00:00:00 2001 From: John Hall Date: Wed, 2 Dec 2020 09:52:12 -0800 Subject: [PATCH 1074/1435] When a USB error occurs, chip-id does not appear to be initialized. --- src/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index ac78db089..20d71df32 100644 --- a/src/common.c +++ b/src/common.c @@ -1305,7 +1305,7 @@ int stlink_load_device_params(stlink_t *sl) { DLOG("Loading device parameters....\n"); const struct stlink_chipid_params *params = NULL; stlink_core_id(sl); - uint32_t chip_id; + uint32_t chip_id = 0; uint32_t flash_size; stlink_chip_id(sl, &chip_id); From 1bbdd74c4b1b5ca7fe0bbfe367677503e20dc82d Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Sat, 5 Dec 2020 11:16:39 +0500 Subject: [PATCH 1075/1435] Fix the indentation --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ab43271e..b125803b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,7 +109,7 @@ set(STLINK_HEADERS src/stlink-lib/md5.h src/stlink-lib/sg.h src/stlink-lib/usb.h - src/stlink-lib/helper.h + src/stlink-lib/helper.h ) set(STLINK_SOURCE From 20e1d531153093842c6c37fec5dd4564e92934cd Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Sat, 5 Dec 2020 15:16:14 +0500 Subject: [PATCH 1076/1435] Fix the indentation --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b125803b8..c8ab40257 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,7 +120,7 @@ set(STLINK_SOURCE src/stlink-lib/md5.c src/stlink-lib/sg.c src/stlink-lib/usb.c - src/stlink-lib/helper.c + src/stlink-lib/helper.c ) if (WIN32) From d6c9f8bd1103b1ad9f603e9b38ff7a73e3598c1b Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 5 Dec 2020 13:28:36 +0200 Subject: [PATCH 1077/1435] fix printf format srting --- src/st-info/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st-info/info.c b/src/st-info/info.c index 2e1ce0e96..0fc4d4d8a 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -76,7 +76,7 @@ static void stlink_probe(void) { printf("Found %u stlink programmers\n", (unsigned int)size); for (size_t n = 0; n < size; n++) { - if (size>1) printf("%lu.\n", n+1); + if (size > 1) printf("%u.\n", (unsigned int)n+1); stlink_print_info(stdevs[n]); } From 28c94453485a42290f0830219a1ab3a4f224111c Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 5 Dec 2020 14:10:24 +0200 Subject: [PATCH 1078/1435] fix gettimeofday for msvc --- src/win32/sys_time.c | 31 ++++++++++++++++++++++--------- src/win32/sys_time.h | 5 +---- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/win32/sys_time.c b/src/win32/sys_time.c index ea7c25dda..08da60b85 100644 --- a/src/win32/sys_time.c +++ b/src/win32/sys_time.c @@ -1,20 +1,33 @@ -#include -#include - #include "sys_time.h" +#ifndef STLINK_HAVE_SYS_TIME_H + +#include + /* Simple gettimeofday implementation without converting Windows time to Linux time */ int gettimeofday(struct timeval *tv, struct timezone *tz) { FILETIME ftime; ULARGE_INTEGER ulint; + static int tzflag = 0; + + if(NULL != tv) { + GetSystemTimeAsFileTime(&ftime); + ulint.LowPart = ftime.dwLowDateTime; + ulint.HighPart = ftime.dwHighDateTime; - GetSystemTimeAsFileTime(&ftime); - ulint.LowPart = ftime.dwLowDateTime; - ulint.HighPart = ftime.dwHighDateTime; + tv->tv_sec = (long)(ulint.QuadPart / 10000000L); + tv->tv_usec = (long)(ulint.QuadPart % 10000000L); + } - tv->tv_sec = (long)(ulint.QuadPart / 10000000L); - tv->tv_usec = (long)(ulint.QuadPart % 10000000L); + if(NULL != tz) { + if (!tzflag) { + _tzset(); + tzflag++; + } + tz->tz_minuteswest = _timezone / 60; + tz->tz_dsttime = _daylight; + } return 0; - (void)tz; } +#endif //STLINK_HAVE_SYS_TIME_H diff --git a/src/win32/sys_time.h b/src/win32/sys_time.h index 87c3a42fd..39f97f739 100644 --- a/src/win32/sys_time.h +++ b/src/win32/sys_time.h @@ -5,10 +5,7 @@ #include #else -struct timeval { - long tv_sec; - long tv_usec; -}; +#include struct timezone { int tz_minuteswest; From fc9e7915fc9b783a5e0467d473645ca81ea3c97f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 5 Dec 2020 13:35:23 +0100 Subject: [PATCH 1079/1435] General Project Update - Corrected identation in reg.h - Updated README.md - Updated CHANGELOG.md - Updated list of contributors --- CHANGELOG.md | 16 +++++++- README.md | 19 ++------- contributors.txt | 8 ++-- doc/devices_boards.md | 2 +- src/stlink-lib/reg.h | 90 +++++++++++++++++++++---------------------- 5 files changed, 67 insertions(+), 68 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9dc64a11..4c178a4e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,16 @@ Release date: (TBD) Features: +* Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052)) +* Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) * Option bytes on the STM32F767 ZIT6 Nucleo-144 ([#968](https://github.com/stlink-org/stlink/pull/968), [#997](https://github.com/stlink-org/stlink/pull/997)) +* Use SetConsoleCtrlHandler for Windows ([#1021](https://github.com/stlink-org/stlink/pull/1021)) +* Increase STM32L0 option_size to 20 ([#1046](https://github.com/stlink-org/stlink/pull/1046)) +* st-util: Add specialized memory map for STM32H7 devices ([#1060](https://github.com/stlink-org/stlink/pull/1060)) +* Support for STM32F4 option bytes ([#1062](https://github.com/stlink-org/stlink/pull/1062)) +* Link for WIN32 & APPLE with stlink-static ([#1069](https://github.com/stlink-org/stlink/pull/1069)) +* Extended support for STM32H7 ([#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) +* ITM functionality for ST-Link V2 and STM32Fxx chipsets ([#136](https://github.com/stlink-org/stlink/pull/136), [#179](https://github.com/stlink-org/stlink/pull/179), [#815](https://github.com/stlink-org/stlink/pull/815), [#1072](https://github.com/stlink-org/stlink/pull/1072)) Updates & changes: @@ -16,6 +25,7 @@ Updates & changes: * [refactoring] General maintenance ([#864](https://github.com/stlink-org/stlink/pull/864), [#976](https://github.com/stlink-org/stlink/pull/976), [#978](https://github.com/stlink-org/stlink/pull/978)) * Imported debian pkg-settings ([#986](https://github.com/stlink-org/stlink/pull/986)) * Add support for FreeBSD's libusb reimplementation ([#992](https://github.com/stlink-org/stlink/pull/992), [#993](https://github.com/stlink-org/stlink/pull/993)) +* [doc] Added example for output of 'st-info --probe' ([#1007](https://github.com/stlink-org/stlink/pull/1007), [#1049](https://github.com/stlink-org/stlink/pull/1049)) Fixes: @@ -26,8 +36,10 @@ Fixes: * Fix for static linking of libssp ([#973](https://github.com/stlink-org/stlink/pull/973), [#974](https://github.com/stlink-org/stlink/pull/974)) * Fixed connect under reset for st-flash and st-util ([#983](https://github.com/stlink-org/stlink/pull/983)) * Fix for mmap() size_t overflow in st-flash ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) -* [regression] stlink-gui installation issue on Ubuntu-18.04 ([#1006](https://github.com/stlink-org/stlink/pull/1006)) -* st-util: wrong register values passed to gdb (st-link v2) ([#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027)) +* [regression] stlink-gui installation issue on Ubuntu-18.04 ([#1001](https://github.com/stlink-org/stlink/pull/1001), [#1004](https://github.com/stlink-org/stlink/pull/1004), [#1006](https://github.com/stlink-org/stlink/pull/1006)) +* st-util: wrong register values passed to gdb (st-link v2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027)) +* [doc] Fixed wrong path for rules.d folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) +* Use vl flashloader for all STM32F1 series ([#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) v1.6.1 diff --git a/README.md b/README.md index 5be842156..350c36e34 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ The stlink library and tools are licensed under the **[BSD-3 License](LICENSE.md STLink is an open source toolset to program and debug STM32 devices and boards manufactured by STMicroelectronics. It supports several so called STLINK programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG/SWD. There are four generations available on the market which are _all_ supported by this toolset: -* **STLINK/v1** _(obsolete as of 21-11-2019, continued support by this toolset)_ +* **STLINK/v1** _[obsolete as of 21-11-2019, continued support by this toolset] *)_ - transport layer: SCSI passthru commands over USB - stand-alone programmer and present on STM32VL Discovery boards * **STLINK/v2** @@ -36,6 +36,8 @@ It supports several so called STLINK programmer boards (and clones thereof) whic - transport layer: raw USB commands - stand-alone programmer +_*)_ **Note: Support on macOS is limited to 10.13 - 10.15. Any later versions are no longer compatible with the STLINK/v1 due to technical reasons.** + On the user level there is no difference in handling or operation between these different revisions. The STlink toolset includes: @@ -112,18 +114,3 @@ When there is no executable available for your platform or you need the latest ( * Please start new forks from the develop branch, as pull requests will go into this branch as well. Please also refer to our [Contribution Guidelines](CONTRIBUTING.md). - - -# Current state of the project -## Known missing features - -Some features are currently missing from the `stlink-org/stlink` toolset. -Here we would appreciate any help and would love to welcome new contributors who want to get involved: - -* Instrumentation Trace Macro (ITM) Cell ([#136](https://github.com/stlink-org/stlink/issues/136)) -* OTP & EEPROM area programming ([#202](https://github.com/stlink-org/stlink/issues/202), [#333](https://github.com/stlink-org/stlink/issues/333), [#686](https://github.com/stlink-org/stlink/issues/686)) -* Protection bits area reading ([#346](https://github.com/stlink-org/stlink/issues/346)) -* Writing external memory connected to an STM32 controller (e.g Quad SPI NOR flash) ([#412](https://github.com/stlink-org/stlink/issues/412)) -* MCU hotplug ([#449](https://github.com/stlink-org/stlink/issues/449)) -* Writing options bytes (region) ([#458](https://github.com/stlink-org/stlink/issues/458)) -* Enhanced support for STLINKv3 programmer ([#820](https://github.com/stlink-org/stlink/issues/820)) diff --git a/contributors.txt b/contributors.txt index cc9403456..65b53aed1 100644 --- a/contributors.txt +++ b/contributors.txt @@ -7,6 +7,7 @@ Andrea Mucignat Andrew Andrianov [necromant] Andrey Yurovsky Andy Isaacson +Anton [Ant-ON] Áron Radics A. Sheaff Björn Hauffe @@ -35,7 +36,7 @@ Denis Osterland Dmitry Bravikov [bravikov] Efe Can İçöz Ethan Zonca -Fabien Chouteau +Fabien Chouteau [Fabien-Chouteau] Florian Hars Friedrich Beckmann Gabriel Górski [Glaeqen] @@ -63,6 +64,7 @@ Jim Paris Jiří Netolický Jerry Nosky [jnosky] Jochen Wilhelmy [Jochen0x90h] +Joel Bodenmann [Tectu] Johannes Taelman Jonas Danielsson Jonas Norling @@ -71,7 +73,6 @@ Karl Palsson [karlp] Kevlar Harness Kyle Manna Lari Lehtomäki -Lutz Freitag [nerdmaennchen] Martin Nowak Matteo Collina Max Chen @@ -80,7 +81,6 @@ Maxime Vincent Michael Pratt [prattmic] Michael Sparmann Mike Szczys -Miklós Márton [martonmiklos] Magnus Lundin [mlu] mux Ned Konz @@ -111,7 +111,7 @@ Simon Wright Stany Marcel Stefan Misik Sven Wegener -Joel Bodenmann [Tectu] +Timothy Lee [timothytylee] Tuomo Kaikkonen Theodore A. Roth Thomas Gärtner diff --git a/doc/devices_boards.md b/doc/devices_boards.md index 8291f7532..4402839c5 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -50,7 +50,7 @@ Tested boards [incl. STLink programmers]: | 0x418 | STM32F105xx/107xx | x8 xB xC | | | | | F105
      F107 | | 0x420 | Medium density value | x8 xB | F100 | | | | | | 0x428 | High density Value | xC xD xE | F100 | | | | | -| 0x430 | XL-Density | xF XG | | F101 | | F103 | | +| 0x430 | XL-Density | xF xG | | F101 | | F103 | | Tested boards [incl. STLink programmers]: * STM32VL-Discovery (STM32F100RBT6) with STLink-v1 [v1, v2] diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 2e93dc5b1..fdea175d3 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -1,61 +1,61 @@ #ifndef STLINK_REG_H_ #define STLINK_REG_H_ -#define STLINK_REG_CM3_CPUID 0xE000ED00 +#define STLINK_REG_CM3_CPUID 0xE000ED00 -#define STLINK_REG_CM3_FP_CTRL 0xE0002000 -#define STLINK_REG_CM3_FP_COMPn(n) (0xE0002008 + n*4) -#define STLINK_REG_CM7_FP_LAR 0xE0000FB0 +#define STLINK_REG_CM3_FP_CTRL 0xE0002000 +#define STLINK_REG_CM3_FP_COMPn(n) (0xE0002008 + n*4) +#define STLINK_REG_CM7_FP_LAR 0xE0000FB0 #define STLINK_REG_CM7_FP_LAR_KEY 0xC5ACCE55 -#define STLINK_REG_CM3_DEMCR 0xE000EDFC -#define STLINK_REG_CM3_DEMCR_TRCENA (1 << 24) -#define STLINK_REG_CM3_DEMCR_VC_HARDERR (1 << 10) -#define STLINK_REG_CM3_DEMCR_VC_BUSERR (1 << 8) -#define STLINK_REG_CM3_DEMCR_VC_CORERESET (1 << 0) -#define STLINK_REG_CM3_DWT_COMPn(n) (0xE0001020 + n*16) -#define STLINK_REG_CM3_DWT_MASKn(n) (0xE0001024 + n*16) -#define STLINK_REG_CM3_DWT_FUNn(n) (0xE0001028 + n*16) +#define STLINK_REG_CM3_DEMCR 0xE000EDFC +#define STLINK_REG_CM3_DEMCR_TRCENA (1 << 24) +#define STLINK_REG_CM3_DEMCR_VC_HARDERR (1 << 10) +#define STLINK_REG_CM3_DEMCR_VC_BUSERR (1 << 8) +#define STLINK_REG_CM3_DEMCR_VC_CORERESET (1 << 0) +#define STLINK_REG_CM3_DWT_COMPn(n) (0xE0001020 + n*16) +#define STLINK_REG_CM3_DWT_MASKn(n) (0xE0001024 + n*16) +#define STLINK_REG_CM3_DWT_FUNn(n) (0xE0001028 + n*16) /* Cortex™-M3 Technical Reference Manual */ /* Debug Halting Control and Status Register */ -#define STLINK_REG_DFSR 0xE000ED30 -#define STLINK_REG_DFSR_HALT (1 << 0) -#define STLINK_REG_DFSR_BKPT (1 << 1) -#define STLINK_REG_DFSR_VCATCH (1 << 3) -#define STLINK_REG_DFSR_EXTERNAL (1 << 4) -#define STLINK_REG_DFSR_CLEAR 0x0000001F -#define STLINK_REG_DHCSR 0xe000edf0 -#define STLINK_REG_DHCSR_DBGKEY (0xA05F << 16) -#define STLINK_REG_DHCSR_C_DEBUGEN (1 << 0) -#define STLINK_REG_DHCSR_C_HALT (1 << 1) -#define STLINK_REG_DHCSR_C_STEP (1 << 2) -#define STLINK_REG_DHCSR_C_MASKINTS (1 << 3) -#define STLINK_REG_DHCSR_S_REGRDY (1 << 16) -#define STLINK_REG_DHCSR_S_HALT (1 << 17) -#define STLINK_REG_DHCSR_S_SLEEP (1 << 18) -#define STLINK_REG_DHCSR_S_LOCKUP (1 << 19) -#define STLINK_REG_DHCSR_S_RETIRE_ST (1 << 24) -#define STLINK_REG_DHCSR_S_RESET_ST (1 << 25) -#define STLINK_REG_DCRSR 0xe000edf4 -#define STLINK_REG_DCRDR 0xe000edf8 +#define STLINK_REG_DFSR 0xE000ED30 +#define STLINK_REG_DFSR_HALT (1 << 0) +#define STLINK_REG_DFSR_BKPT (1 << 1) +#define STLINK_REG_DFSR_VCATCH (1 << 3) +#define STLINK_REG_DFSR_EXTERNAL (1 << 4) +#define STLINK_REG_DFSR_CLEAR 0x0000001F +#define STLINK_REG_DHCSR 0xe000edf0 +#define STLINK_REG_DHCSR_DBGKEY (0xA05F << 16) +#define STLINK_REG_DHCSR_C_DEBUGEN (1 << 0) +#define STLINK_REG_DHCSR_C_HALT (1 << 1) +#define STLINK_REG_DHCSR_C_STEP (1 << 2) +#define STLINK_REG_DHCSR_C_MASKINTS (1 << 3) +#define STLINK_REG_DHCSR_S_REGRDY (1 << 16) +#define STLINK_REG_DHCSR_S_HALT (1 << 17) +#define STLINK_REG_DHCSR_S_SLEEP (1 << 18) +#define STLINK_REG_DHCSR_S_LOCKUP (1 << 19) +#define STLINK_REG_DHCSR_S_RETIRE_ST (1 << 24) +#define STLINK_REG_DHCSR_S_RESET_ST (1 << 25) +#define STLINK_REG_DCRSR 0xe000edf4 +#define STLINK_REG_DCRDR 0xe000edf8 /* Application Interrupt and Reset Control Register */ -#define STLINK_REG_AIRCR 0xe000ed0c -#define STLINK_REG_AIRCR_VECTKEY 0x05fa0000 -#define STLINK_REG_AIRCR_SYSRESETREQ 0x00000004 -#define STLINK_REG_AIRCR_VECTRESET 0x00000001 +#define STLINK_REG_AIRCR 0xe000ed0c +#define STLINK_REG_AIRCR_VECTKEY 0x05fa0000 +#define STLINK_REG_AIRCR_SYSRESETREQ 0x00000004 +#define STLINK_REG_AIRCR_VECTRESET 0x00000001 /* ARM Cortex-M7 Processor Technical Reference Manual */ /* Cache Control and Status Register */ -#define STLINK_REG_CM7_CTR 0xE000ED7C -#define STLINK_REG_CM7_CLIDR 0xE000ED78 -#define STLINK_REG_CM7_CCR 0xE000ED14 -#define STLINK_REG_CM7_CCR_DC (1 << 16) -#define STLINK_REG_CM7_CCR_IC (1 << 17) -#define STLINK_REG_CM7_CSSELR 0xE000ED84 -#define STLINK_REG_CM7_DCCSW 0xE000EF6C -#define STLINK_REG_CM7_ICIALLU 0xE000EF50 -#define STLINK_REG_CM7_CCSIDR 0xE000ED80 +#define STLINK_REG_CM7_CTR 0xE000ED7C +#define STLINK_REG_CM7_CLIDR 0xE000ED78 +#define STLINK_REG_CM7_CCR 0xE000ED14 +#define STLINK_REG_CM7_CCR_DC (1 << 16) +#define STLINK_REG_CM7_CCR_IC (1 << 17) +#define STLINK_REG_CM7_CSSELR 0xE000ED84 +#define STLINK_REG_CM7_DCCSW 0xE000EF6C +#define STLINK_REG_CM7_ICIALLU 0xE000EF50 +#define STLINK_REG_CM7_CCSIDR 0xE000ED80 #endif // STLINK_REG_H_ From 373eee2cfebc410efc86b42524f84dc0dd536081 Mon Sep 17 00:00:00 2001 From: John Hall Date: Sat, 5 Dec 2020 10:25:14 -0800 Subject: [PATCH 1080/1435] Adding back has_dual_bank. Replacing flags field with has_swo_tracing. --- inc/backend.h | 2 +- inc/stlink.h | 6 ++- src/common.c | 5 ++- src/st-trace/trace.c | 2 +- src/stlink-lib/chipid.c | 99 +++++++++++++++++++++-------------------- src/stlink-lib/chipid.h | 5 +-- 6 files changed, 62 insertions(+), 57 deletions(-) diff --git a/inc/backend.h b/inc/backend.h index 6a0232849..ebd438127 100644 --- a/inc/backend.h +++ b/inc/backend.h @@ -28,7 +28,7 @@ int (*current_mode) (stlink_t * stl); int (*force_debug) (stlink_t *sl); int32_t (*target_voltage) (stlink_t *sl); - int (*set_swdclk) (stlink_t * stl, uint16_t divisor); + int (*set_swdclk) (stlink_t * stl, int freq_khz); int (*trace_enable) (stlink_t * sl, uint32_t frequency); int (*trace_disable) (stlink_t * sl); int (*trace_read) (stlink_t * sl, uint8_t* buf, size_t size); diff --git a/inc/stlink.h b/inc/stlink.h index 163d5d4b9..17c0bc6f4 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -220,7 +220,7 @@ struct _stlink { enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx - uint32_t chip_flags; + bool has_dual_bank; stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() size_t flash_size; // calculated by stlink_load_device_params() @@ -234,6 +234,8 @@ struct _stlink { stm32_addr_t option_base; size_t option_size; + bool has_swo_tracing; + // bootloader // sys_base and sys_size are not used by the tools, but are only there to download the bootloader code // (see tests/sg.c) @@ -270,7 +272,7 @@ int stlink_step(stlink_t *sl); int stlink_current_mode(stlink_t *sl); int stlink_force_debug(stlink_t *sl); int stlink_target_voltage(stlink_t *sl); -int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); +int stlink_set_swdclk(stlink_t *sl, int freq_khz); int stlink_trace_enable(stlink_t* sl, uint32_t frequency); int stlink_trace_disable(stlink_t* sl); int stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size); diff --git a/src/common.c b/src/common.c index 5e1e61e25..f2d68daf4 100644 --- a/src/common.c +++ b/src/common.c @@ -907,7 +907,7 @@ static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { cr_reg = STM32Gx_FLASH_CR; cr_mer = (1 << STM32Gx_FLASH_CR_MER1); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + if (sl->has_dual_bank) { cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); } @@ -1355,13 +1355,14 @@ int stlink_load_device_params(stlink_t *sl) { } sl->flash_type = params->flash_type; - sl->chip_flags = params->flags; + sl->has_dual_bank = params->has_dual_bank; sl->flash_pgsz = params->flash_pagesize; sl->sram_size = params->sram_size; sl->sys_base = params->bootrom_base; sl->sys_size = params->bootrom_size; sl->option_base = params->option_base; sl->option_size = params->option_size; + sl->has_swo_tracing = params->has_swo_tracing; // medium and low devices have the same chipid. ram size depends on flash size. // STM32F100xx datasheet Doc ID 16455 Table 2 diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 1356ceca0..6a5ccb91d 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -566,7 +566,7 @@ int main(int argc, char** argv) return APP_RESULT_STLINK_UNSUPPORTED_LINK; } - if (!(stlink->chip_flags & CHIP_F_HAS_SWO_TRACING)) { + if (!stlink->has_swo_tracing) { const struct stlink_chipid_params *params = stlink_chipid_get_params(stlink->chip_id); ELOG("We do not support SWO output for device '%s'\n", params->description); if (!settings.force) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 1a0c305c7..cb9276c93 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -14,7 +14,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0xEDC0, // ! @todo "System memory" byte size in hex from .option_base = STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option bytes, writing uses FLASH_F7_OPTCR and FLASH_F7_OPTCR1 .option_size = 0x20, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // RM0385 and DS10916 document was used to find these paramaters @@ -26,7 +26,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 18 - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // RM0431 and DS document was used to find these paramaters @@ -38,7 +38,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 24 - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // table 2, PM0063 .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, @@ -49,7 +49,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x5000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // table 1, PM0059 .chip_id = STLINK_CHIPID_STM32_F2, @@ -62,7 +62,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7800, .option_base = 0x1FFFC000, .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // PM0063 .chip_id = STLINK_CHIPID_STM32_F1_LOW, @@ -73,7 +73,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x2800, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_F4, @@ -86,7 +86,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7800, .option_base = STM32_F4_OPTION_BYTES_BASE, .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_F4_DSI, @@ -97,7 +97,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x40000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_F4_HD, @@ -108,7 +108,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x40000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_F4_LP, @@ -119,7 +119,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x10000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_F411RE, @@ -130,7 +130,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x20000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_F4_DE, @@ -141,7 +141,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x18000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_F1_HIGH, @@ -152,7 +152,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x10000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // This ignores the EEPROM! (and uses the page erase size, @@ -165,7 +165,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x4000, .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_L1_CAT2, @@ -176,7 +176,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x8000, .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM_PLUS, @@ -187,7 +187,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x8000, // not completely clear if there are some with 48k .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_L1_HIGH, @@ -200,7 +200,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x1000, .option_base = STM32_L1_OPTION_BYTES_BASE, .option_size = 8, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_L152_RE, @@ -211,7 +211,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x14000, // not completely clear if there are some with 32k .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_F1_CONN, @@ -222,7 +222,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x10000, .bootrom_base = 0x1fffb000, .bootrom_size = 0x4800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // Low and Medium density VL have same chipid. RM0041 25.6.1 .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, @@ -233,7 +233,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x2000, // 0x1000 for low density devices .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // STM32F446x family. Support based on DM00135183.pdf (RM0390) document. @@ -247,7 +247,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7800, .option_base = 0x1FFFC000, .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // STM32F410 MCUs. Support based on DM00180366.pdf (RM0401) document. @@ -259,7 +259,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x8000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // This is STK32F303VCT6 device from STM32 F3 Discovery board. @@ -272,7 +272,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0xa000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // This is STK32F373VCT6 device from STM32 F373 eval board @@ -285,7 +285,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0xa000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_F1_VL_HIGH, @@ -296,7 +296,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x8000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_F1_XL, @@ -307,7 +307,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x18000, .bootrom_base = 0x1fffe000, .bootrom_size = 0x1800, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // Use this as an example for mapping future chips: @@ -319,7 +319,7 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, // Page sizes listed in Table 4 .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 - .bootrom_size = 0x3000 // "System memory" byte size in hex from Table 2 + .bootrom_size = 0x3000, // "System memory" byte size in hex from Table 2 }, { // Use this as an example for mapping future chips: @@ -331,7 +331,7 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x400, // Page sizes listed in Table 4 .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 }, { // RM0402 document was used to find these parameters @@ -344,7 +344,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // RM0430 DocID029473 Rev 2 document was used to find these parameters @@ -357,7 +357,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 only says 0x40000) .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { .chip_id = STLINK_CHIPID_STM32_F09X, @@ -367,7 +367,7 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 - .bootrom_size = 0x2000 // "System memory" byte size in hex from Table 2 + .bootrom_size = 0x2000, // "System memory" byte size in hex from Table 2 }, { // Use this as an example for mapping future chips: @@ -379,7 +379,7 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x400, // Page sizes listed in Table 4 .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 }, { // Use this as an example for mapping future chips: @@ -391,7 +391,7 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x400, // Page sizes listed in Table 4 .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 }, { // STM32F30x @@ -403,7 +403,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0xa000, .bootrom_base = 0x1fffd800, .bootrom_size = 0x2000, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // STM32L0x @@ -458,7 +458,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x3000, .bootrom_base = 0x1fffd800, .bootrom_size = 0x2000, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // This is STK32F303RET6 device from STM32 F3 Nucelo board. @@ -471,7 +471,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x10000, // 3.3 Embedded SRAM .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory .bootrom_size = 0x2000, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // STM32L4x6 @@ -490,7 +490,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // STM32L4RX @@ -503,7 +503,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 .bootrom_base = 0x1fff0000, // 3.3.1, pg 99 .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 99) - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // STLINK_CHIPID_STM32_L41X @@ -518,7 +518,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) .bootrom_size = 0x7000, // 28k, same source as base - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // STLINK_CHIPID_STM32_L43X @@ -537,7 +537,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // STLINK_CHIPID_STM32_L496X @@ -554,7 +554,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // STLINK_CHIPID_STM32_L46X @@ -570,7 +570,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x20000, .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system memory, also fig 2 on page 63) .bootrom_size = 0x7000, // 28k (per bank), same source as base - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // STM32L011 @@ -581,7 +581,7 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x80, .sram_size = 0x2000, .bootrom_base = 0x1ff00000, - .bootrom_size = 0x2000 + .bootrom_size = 0x2000, }, { // STM32G030/031/041 (from RM0454 & RM0444) @@ -624,13 +624,14 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // STM32G471/473/474/483/484 (from RM0440) .chip_id = STLINK_CHIPID_STM32_G4_CAT3, .description = "G4 Category-3", .flash_type = STLINK_FLASH_TYPE_G4, + .has_dual_bank = true, .flash_size_reg = 0x1FFF75E0, // Section 47.2 .flash_pagesize = 0x800, // 2k (sec 3.3.1) // SRAM1 is 80k at 0x20000000 @@ -641,7 +642,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, .option_size = 4, - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // STM32WB55 (from RM0434) @@ -652,7 +653,8 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x1000, // 4k .sram_size = 0x40000, .bootrom_base = 0x1fff0000, // see the memory map - .bootrom_size = 0x7000 + .bootrom_size = 0x7000, + .has_swo_tracing = true, }, { // STM32H742/743/753 (from RM0433) @@ -667,7 +669,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x20000, // "System memory" byte size in hex from Table 7 .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 - .flags = CHIP_F_HAS_SWO_TRACING, + .has_swo_tracing = true, }, { // STM32H7A3/7B3 (from RM0455) @@ -682,6 +684,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x20000, // "System memory" byte size in hex splitted to two banks (Table 12-14) .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, + .has_swo_tracing = true, }, { // STM32H72x/H73x (from RM0468) @@ -695,6 +698,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x20000, // "System memory" byte size in hex (Table 6) .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, + .has_swo_tracing = true, }, { @@ -707,7 +711,6 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x0, .bootrom_base = 0x0, .bootrom_size = 0x0, - .flags = 0, }, }; diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index 1b54fe140..aab22759c 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -69,15 +69,13 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_WB55 = 0x495 }; -#define CHIP_F_HAS_DUAL_BANK (1 << 0) -#define CHIP_F_HAS_SWO_TRACING (1 << 1) /** Chipid parameters */ struct stlink_chipid_params { uint32_t chip_id; char *description; enum stlink_flash_type flash_type; - uint32_t flags; + bool has_dual_bank; uint32_t flash_size_reg; uint32_t flash_pagesize; uint32_t sram_size; @@ -85,6 +83,7 @@ struct stlink_chipid_params { uint32_t bootrom_size; uint32_t option_base; uint32_t option_size; + bool has_swo_tracing; }; const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); From 5d1f3198a4530ca87e6dc61e21fb259b0e6f8417 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Sun, 6 Dec 2020 14:09:59 +0500 Subject: [PATCH 1081/1435] Fix warning of narrowing issues --- src/stlink-lib/helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/helper.c b/src/stlink-lib/helper.c index 8b2c8e8f7..32d9b6c8d 100644 --- a/src/stlink-lib/helper.c +++ b/src/stlink-lib/helper.c @@ -11,5 +11,5 @@ unsigned time_ms() { struct timeval tv; gettimeofday(&tv, NULL); - return (unsigned)tv.tv_sec * 1000 + tv.tv_usec / 1000; + return (unsigned)(tv.tv_sec * 1000 + tv.tv_usec / 1000); } From 3e9e2bb38a00e7dae1cc97c613a91d2e680cd589 Mon Sep 17 00:00:00 2001 From: John Hall Date: Sun, 6 Dec 2020 11:01:02 -0800 Subject: [PATCH 1082/1435] Adding back flag. --- inc/stlink.h | 6 +-- src/common.c | 2 +- src/st-trace/trace.c | 2 +- src/stlink-lib/chipid.c | 86 ++++++++++++++++++++--------------------- src/stlink-lib/chipid.h | 5 ++- 5 files changed, 52 insertions(+), 49 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 17c0bc6f4..b4fff334f 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -22,7 +22,7 @@ extern "C" { /* Max data transfer size */ // 6kB = max mem32_read block, 8kB sram -// #define Q_BUF_LEN 96 +// #define Q_BUF_LEN 96 #define Q_BUF_LEN (1024 * 100) // STLINK_DEBUG_RESETSYS, etc: @@ -234,8 +234,6 @@ struct _stlink { stm32_addr_t option_base; size_t option_size; - bool has_swo_tracing; - // bootloader // sys_base and sys_size are not used by the tools, but are only there to download the bootloader code // (see tests/sg.c) @@ -243,6 +241,8 @@ struct _stlink { size_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() struct stlink_version_ version; + + uint32_t chip_flags; // stlink_chipid_params.flags, set by stlink_load_device_params(), values: CHIP_F_xxx }; int stlink_enter_swd_mode(stlink_t *sl); diff --git a/src/common.c b/src/common.c index f2d68daf4..a9e907c60 100644 --- a/src/common.c +++ b/src/common.c @@ -1362,7 +1362,7 @@ int stlink_load_device_params(stlink_t *sl) { sl->sys_size = params->bootrom_size; sl->option_base = params->option_base; sl->option_size = params->option_size; - sl->has_swo_tracing = params->has_swo_tracing; + sl->chip_flags = params->flags; // medium and low devices have the same chipid. ram size depends on flash size. // STM32F100xx datasheet Doc ID 16455 Table 2 diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 6a5ccb91d..1356ceca0 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -566,7 +566,7 @@ int main(int argc, char** argv) return APP_RESULT_STLINK_UNSUPPORTED_LINK; } - if (!stlink->has_swo_tracing) { + if (!(stlink->chip_flags & CHIP_F_HAS_SWO_TRACING)) { const struct stlink_chipid_params *params = stlink_chipid_get_params(stlink->chip_id); ELOG("We do not support SWO output for device '%s'\n", params->description); if (!settings.force) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index cb9276c93..dc3218261 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -14,7 +14,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0xEDC0, // ! @todo "System memory" byte size in hex from .option_base = STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option bytes, writing uses FLASH_F7_OPTCR and FLASH_F7_OPTCR1 .option_size = 0x20, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // RM0385 and DS10916 document was used to find these paramaters @@ -26,7 +26,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 18 - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // RM0431 and DS document was used to find these paramaters @@ -38,7 +38,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 24 - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // table 2, PM0063 .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, @@ -49,7 +49,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x5000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // table 1, PM0059 .chip_id = STLINK_CHIPID_STM32_F2, @@ -62,7 +62,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7800, .option_base = 0x1FFFC000, .option_size = 4, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // PM0063 .chip_id = STLINK_CHIPID_STM32_F1_LOW, @@ -73,7 +73,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x2800, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F4, @@ -86,7 +86,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7800, .option_base = STM32_F4_OPTION_BYTES_BASE, .option_size = 4, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F4_DSI, @@ -97,7 +97,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x40000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F4_HD, @@ -108,7 +108,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x40000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F4_LP, @@ -119,7 +119,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x10000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F411RE, @@ -130,7 +130,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x20000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F4_DE, @@ -141,7 +141,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x18000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F1_HIGH, @@ -152,7 +152,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x10000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // This ignores the EEPROM! (and uses the page erase size, @@ -165,7 +165,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x4000, .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_L1_CAT2, @@ -176,7 +176,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x8000, .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM_PLUS, @@ -187,7 +187,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x8000, // not completely clear if there are some with 48k .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_L1_HIGH, @@ -200,7 +200,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x1000, .option_base = STM32_L1_OPTION_BYTES_BASE, .option_size = 8, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_L152_RE, @@ -211,7 +211,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x14000, // not completely clear if there are some with 32k .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F1_CONN, @@ -222,7 +222,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x10000, .bootrom_base = 0x1fffb000, .bootrom_size = 0x4800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // Low and Medium density VL have same chipid. RM0041 25.6.1 .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, @@ -233,7 +233,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x2000, // 0x1000 for low density devices .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32F446x family. Support based on DM00135183.pdf (RM0390) document. @@ -247,7 +247,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7800, .option_base = 0x1FFFC000, .option_size = 4, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32F410 MCUs. Support based on DM00180366.pdf (RM0401) document. @@ -259,7 +259,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x8000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // This is STK32F303VCT6 device from STM32 F3 Discovery board. @@ -272,7 +272,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0xa000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // This is STK32F373VCT6 device from STM32 F373 eval board @@ -285,7 +285,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0xa000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F1_VL_HIGH, @@ -296,7 +296,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x8000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F1_XL, @@ -307,7 +307,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x18000, .bootrom_base = 0x1fffe000, .bootrom_size = 0x1800, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // Use this as an example for mapping future chips: @@ -344,7 +344,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // RM0430 DocID029473 Rev 2 document was used to find these parameters @@ -357,7 +357,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 only says 0x40000) .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F09X, @@ -403,7 +403,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0xa000, .bootrom_base = 0x1fffd800, .bootrom_size = 0x2000, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32L0x @@ -458,7 +458,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x3000, .bootrom_base = 0x1fffd800, .bootrom_size = 0x2000, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // This is STK32F303RET6 device from STM32 F3 Nucelo board. @@ -471,7 +471,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x10000, // 3.3 Embedded SRAM .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory .bootrom_size = 0x2000, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32L4x6 @@ -490,7 +490,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32L4RX @@ -503,7 +503,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 .bootrom_base = 0x1fff0000, // 3.3.1, pg 99 .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 99) - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STLINK_CHIPID_STM32_L41X @@ -518,7 +518,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) .bootrom_size = 0x7000, // 28k, same source as base - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STLINK_CHIPID_STM32_L43X @@ -537,7 +537,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STLINK_CHIPID_STM32_L496X @@ -554,7 +554,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STLINK_CHIPID_STM32_L46X @@ -570,7 +570,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x20000, .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system memory, also fig 2 on page 63) .bootrom_size = 0x7000, // 28k (per bank), same source as base - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32L011 @@ -624,7 +624,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, .option_size = 4, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32G471/473/474/483/484 (from RM0440) @@ -642,7 +642,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, .option_size = 4, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32WB55 (from RM0434) @@ -654,7 +654,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x40000, .bootrom_base = 0x1fff0000, // see the memory map .bootrom_size = 0x7000, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32H742/743/753 (from RM0433) @@ -669,7 +669,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x20000, // "System memory" byte size in hex from Table 7 .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32H7A3/7B3 (from RM0455) @@ -684,7 +684,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x20000, // "System memory" byte size in hex splitted to two banks (Table 12-14) .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { // STM32H72x/H73x (from RM0468) @@ -698,7 +698,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x20000, // "System memory" byte size in hex (Table 6) .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, - .has_swo_tracing = true, + .flags = CHIP_F_HAS_SWO_TRACING, }, { diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index aab22759c..5fee49f87 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -70,6 +70,9 @@ enum stlink_stm32_chipids { }; +#define CHIP_F_HAS_SWO_TRACING (1 << 0) + + /** Chipid parameters */ struct stlink_chipid_params { uint32_t chip_id; @@ -83,7 +86,7 @@ struct stlink_chipid_params { uint32_t bootrom_size; uint32_t option_base; uint32_t option_size; - bool has_swo_tracing; + uint32_t flags; }; const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); From 67bf3906ef509e40c8ad909489701390cab2b89d Mon Sep 17 00:00:00 2001 From: John Hall Date: Sun, 6 Dec 2020 15:56:40 -0800 Subject: [PATCH 1083/1435] Fixing funcation naming convention. --- src/st-trace/trace.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 1356ceca0..450e7c598 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -242,7 +242,7 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { return true; } -static void ConvertSerialNumberTextToBinary(const char* text, char binary_out[STLINK_SERIAL_MAX_SIZE]) { +static void convert_serial_number_text_to_binary(const char* text, char binary_out[STLINK_SERIAL_MAX_SIZE]) { size_t length = 0; for (uint32_t n = 0; n < strlen(text) && length < STLINK_SERIAL_MAX_SIZE; n += 2) { char buffer[3] = { 0 }; @@ -251,11 +251,11 @@ static void ConvertSerialNumberTextToBinary(const char* text, char binary_out[ST } } -static stlink_t* StLinkConnect(const st_settings_t* settings) { +static stlink_t* stlink_connect(const st_settings_t* settings) { if (settings->serial_number) { // Open this specific stlink. char binary_serial_number[STLINK_SERIAL_MAX_SIZE] = { 0 }; - ConvertSerialNumberTextToBinary(settings->serial_number, binary_serial_number); + convert_serial_number_text_to_binary(settings->serial_number, binary_serial_number); return stlink_open_usb(settings->logging_level, false, binary_serial_number, 0); } else { // Otherwise, open any stlink. @@ -263,7 +263,7 @@ static stlink_t* StLinkConnect(const st_settings_t* settings) { } } -static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings, uint32_t trace_frequency) { +static bool enable_trace(stlink_t* stlink, const st_settings_t* settings, uint32_t trace_frequency) { if (stlink_force_debug(stlink)) { ELOG("Unable to debug device\n"); @@ -334,7 +334,7 @@ static bool EnableTrace(stlink_t* stlink, const st_settings_t* settings, uint32_ return true; } -static trace_state UpdateTraceIdle(st_trace_t* trace, uint8_t c) { +static trace_state update_trace_idle(st_trace_t* trace, uint8_t c) { // Handle a trace byte when we are in the idle state. if (TRACE_OP_IS_TARGET_SOURCE(c)) { @@ -375,7 +375,7 @@ static trace_state UpdateTraceIdle(st_trace_t* trace, uint8_t c) { return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; } -static trace_state UpdateTrace(st_trace_t* trace, uint8_t c) { +static trace_state update_trace(st_trace_t* trace, uint8_t c) { trace->count_raw_bytes++; // Parse the input using a state machine. @@ -388,7 +388,7 @@ static trace_state UpdateTrace(st_trace_t* trace, uint8_t c) { switch (trace->state) { case TRACE_STATE_IDLE: - return UpdateTraceIdle(trace, c); + return update_trace_idle(trace, c); case TRACE_STATE_TARGET_SOURCE: putchar(c); @@ -421,7 +421,7 @@ static trace_state UpdateTrace(st_trace_t* trace, uint8_t c) { } } -static bool ReadTrace(stlink_t* stlink, st_trace_t* trace) { +static bool read_trace(stlink_t* stlink, st_trace_t* trace) { uint8_t buffer[STLINK_TRACE_BUF_LEN]; int length = stlink_trace_read(stlink, buffer, sizeof(buffer)); @@ -444,13 +444,13 @@ static bool ReadTrace(stlink_t* stlink, st_trace_t* trace) { } for (int i = 0; i < length; i++) { - trace->state = UpdateTrace(trace, buffer[i]); + trace->state = update_trace(trace, buffer[i]); } return true; } -static void CheckForConfigurationError(stlink_t* stlink, st_trace_t* trace, uint32_t trace_frequency) { +static void check_for_configuration_error(stlink_t* stlink, st_trace_t* trace, uint32_t trace_frequency) { // Only check configuration one time after the first 10 seconds of running. uint32_t elapsed_time_s = time(NULL) - trace->start_time; if (trace->configuration_checked || elapsed_time_s < 10) { @@ -546,7 +546,7 @@ int main(int argc, char** argv) return APP_RESULT_SUCCESS; } - stlink_t* stlink = StLinkConnect(&settings); + stlink_t* stlink = stlink_connect(&settings); if (!stlink) { ELOG("Unable to locate an stlink\n"); return APP_RESULT_STLINK_NOT_FOUND; @@ -582,7 +582,7 @@ int main(int argc, char** argv) return APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY; } - if (!EnableTrace(stlink, &settings, trace_frequency)) { + if (!enable_trace(stlink, &settings, trace_frequency)) { ELOG("Unable to enable trace mode\n"); if (!settings.force) return APP_RESULT_STLINK_STATE_ERROR; @@ -598,8 +598,8 @@ int main(int argc, char** argv) return APP_RESULT_STLINK_STATE_ERROR; } - while (!g_abort_trace && ReadTrace(stlink, &trace)) { - CheckForConfigurationError(stlink, &trace, trace_frequency); + while (!g_abort_trace && read_trace(stlink, &trace)) { + check_for_configuration_error(stlink, &trace, trace_frequency); } stlink_trace_disable(stlink); From 7db0477d8f3da330d429da5ea12fde7cd4a09b7e Mon Sep 17 00:00:00 2001 From: John Hall Date: Sun, 6 Dec 2020 16:01:41 -0800 Subject: [PATCH 1084/1435] Adding windows signal handler type behavior. --- src/st-trace/trace.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 450e7c598..63003df58 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -148,6 +148,13 @@ static void abort_trace() { g_abort_trace = true; } +#if defined(_WIN32) +BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { + abort_trace(); + return FALSE; +} +#endif + static void usage(void) { puts("st-trace - usage:"); puts(" -h, --help Print this help"); @@ -516,10 +523,15 @@ static void check_for_configuration_error(stlink_t* stlink, st_trace_t* trace, u int main(int argc, char** argv) { +#if defined(_WIN32) + SetConsoleCtrlHandler((PHANDLER_ROUTINE)abort_trace, TRUE); +#else signal(SIGINT, &abort_trace); signal(SIGTERM, &abort_trace); signal(SIGSEGV, &abort_trace); signal(SIGPIPE, &abort_trace); +#endif + st_settings_t settings; if (!parse_options(argc, argv, &settings)) { From dc9726cd06bfbe695993951d78943b064560a8bb Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 7 Dec 2020 09:02:00 -0800 Subject: [PATCH 1085/1435] Set abort routine wrong in windows. Found in code review. --- src/st-trace/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 63003df58..a01f0c522 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -524,7 +524,7 @@ static void check_for_configuration_error(stlink_t* stlink, st_trace_t* trace, u int main(int argc, char** argv) { #if defined(_WIN32) - SetConsoleCtrlHandler((PHANDLER_ROUTINE)abort_trace, TRUE); + SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); #else signal(SIGINT, &abort_trace); signal(SIGTERM, &abort_trace); From d1a9fd85e097ce0f03699b3b163fcc96c35e4d57 Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 7 Dec 2020 10:12:23 -0800 Subject: [PATCH 1086/1435] Moved register definitions to common reg.h file. --- inc/stlink.h | 22 -------- src/st-trace/trace.c | 126 +++++++++++++------------------------------ src/stlink-lib/reg.h | 52 +++++++++++++++++- 3 files changed, 89 insertions(+), 111 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index b4fff334f..ef61fd1ba 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -88,28 +88,6 @@ enum target_state { #define STLINK_V3_MAX_TRACE_FREQUENCY 24000000 #define STLINK_DEFAULT_TRACE_FREQUENCY 2000000 -/* Cortex Debug Control Block */ -#define DCB_DHCSR 0xE000EDF0 -#define DCB_DCRSR 0xE000EDF4 -#define DCB_DCRDR 0xE000EDF8 -#define DCB_DEMCR 0xE000EDFC - -/* DCB_DHCSR bit and field definitions */ -#define DBGKEY (0xA05F << 16) -#define C_DEBUGEN (1 << 0) -#define C_HALT (1 << 1) -#define C_STEP (1 << 2) -#define C_MASKINTS (1 << 3) -#define S_REGRDY (1 << 16) -#define S_HALT (1 << 17) -#define S_SLEEP (1 << 18) -#define S_LOCKUP (1 << 19) -#define S_RETIRE_ST (1 << 24) -#define S_RESET_ST (1 << 25) - -/* DCB_DEMCR field definitions */ -#define DEMCR_TRCENA (1 << 24) - /* Map the relevant features, quirks and workaround for specific firmware version of stlink */ #define STLINK_F_HAS_TRACE (1 << 0) #define STLINK_F_HAS_SWD_SET_FREQ (1 << 1) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index a01f0c522..7f586c7c2 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -10,6 +10,7 @@ #include #include +#include #include @@ -39,66 +40,6 @@ #define TRACE_OP_GET_SW_SOURCE_ADDR(c) ((c) >> 3) -// TODO: Ideally all register and field definitions would be in a common header file. - -// Instrumentation Trace Macrocell (ITM) Registers -#define ITM_TER 0xE0000E00 // ITM Trace Enable Register -#define ITM_TPR 0xE0000E40 // ITM Trace Privilege Register -#define ITM_TCR 0xE0000E80 // ITM Trace Control Register -#define ITM_TCC 0xE0000E90 // ITM Trace Cycle Count -#define ITM_LAR 0xE0000FB0 // ITM Lock Access Register - -// ITM field definitions -#define ITM_TER_PORTS_ALL (0xFFFFFFFF) -#define ITM_TPR_PORTS_ALL (0x0F) -#define ITM_TCR_TRACE_BUS_ID_1 (0x01 << 16) -#define ITM_TCR_SWO_ENA (1 << 4) -#define ITM_TCR_DWT_ENA (1 << 3) -#define ITM_TCR_SYNC_ENA (1 << 2) -#define ITM_TCR_TS_ENA (1 << 1) -#define ITM_TCR_ITM_ENA (1 << 0) -#define ITM_LAR_KEY 0xC5ACCE55 - -// Data Watchpoint and Trace (DWT) Registers -#define DWT_CTRL 0xE0001000 // DWT Control Register -#define DWT_FUNCTION0 0xE0001028 // DWT Function Register 0 -#define DWT_FUNCTION1 0xE0001038 // DWT Function Register 1 -#define DWT_FUNCTION2 0xE0001048 // DWT Function Register 2 -#define DWT_FUNCTION3 0xE0001058 // DWT Function Register 3 - -// DWT field definitions -#define DWT_CTRL_NUM_COMP (1 << 28) -#define DWT_CTRL_CYC_TAP (1 << 9) -#define DWT_CTRL_POST_INIT (1 << 5) -#define DWT_CTRL_POST_PRESET (1 << 1) -#define DWT_CTRL_CYCCNT_ENA (1 << 0) - -// Trace Port Interface (TPI) Registers -#define TPI_CSPSR 0xE0040004 // TPI Current Parallel Port Size Register -#define TPI_ACPR 0xE0040010 // TPI Asynchronous Clock Prescaler Register -#define TPI_SPPR 0xE00400F0 // TPI Selected Pin Protocol Register -#define TPI_FFCR 0xE0040304 // TPI Formatter and Flush Control Register - -// TPI field definitions -#define TPI_TPI_CSPSR_PORT_SIZE_1 (0x01 << 0) -#define TPI_SPPR_SWO_MANCHESTER (0x01 << 0) -#define TPI_SPPR_SWO_NRZ (0x02 << 0) -#define TPI_FFCR_TRIG_IN (0x01 << 8) -#define TPI_ACPR_MAX (0x1FFF) - -// Other Registers -#define FP_CTRL 0xE0002000 // Flash Patch Control Register -#define DBGMCU_CR 0xE0042004 // Debug MCU Configuration Register - -// Other register field definitions -#define FP_CTRL_KEY (1 << 1) -#define DBGMCU_CR_DBG_SLEEP (1 << 0) -#define DBGMCU_CR_DBG_STOP (1 << 1) -#define DBGMCU_CR_DBG_STANDBY (1 << 2) -#define DBGMCU_CR_TRACE_IOEN (1 << 5) -#define DBGMCU_CR_TRACE_MODE_ASYNC (0x00 << 6) - - typedef struct { bool show_help; bool show_version; @@ -284,17 +225,22 @@ static bool enable_trace(stlink_t* stlink, const st_settings_t* settings, uint32 return false; } - stlink_write_debug32(stlink, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT); - stlink_write_debug32(stlink, DCB_DEMCR, DEMCR_TRCENA); - stlink_write_debug32(stlink, FP_CTRL, FP_CTRL_KEY); - stlink_write_debug32(stlink, DWT_FUNCTION0, 0); - stlink_write_debug32(stlink, DWT_FUNCTION1, 0); - stlink_write_debug32(stlink, DWT_FUNCTION2, 0); - stlink_write_debug32(stlink, DWT_FUNCTION3, 0); - stlink_write_debug32(stlink, DWT_CTRL, 0); - stlink_write_debug32(stlink, DBGMCU_CR, DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP | - DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_TRACE_IOEN | - DBGMCU_CR_TRACE_MODE_ASYNC); // Enable async tracing + + stlink_write_debug32(stlink, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | + STLINK_REG_DHCSR_C_DEBUGEN | + STLINK_REG_DHCSR_C_HALT); + stlink_write_debug32(stlink, STLINK_REG_DEMCR, STLINK_REG_DEMCR_TRCENA); + stlink_write_debug32(stlink, STLINK_REG_CM3_FP_CTRL, STLINK_REG_CM3_FP_CTRL_KEY); + stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION0, 0); + stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION1, 0); + stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION2, 0); + stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION3, 0); + stlink_write_debug32(stlink, STLINK_REG_DWT_CTRL, 0); + stlink_write_debug32(stlink, STLINK_REG_DBGMCU_CR, STLINK_REG_DBGMCU_CR_DBG_SLEEP | + STLINK_REG_DBGMCU_CR_DBG_STOP | + STLINK_REG_DBGMCU_CR_DBG_STANDBY | + STLINK_REG_DBGMCU_CR_TRACE_IOEN | + STLINK_REG_DBGMCU_CR_TRACE_MODE_ASYNC); if (stlink_trace_enable(stlink, trace_frequency)) { ELOG("Unable to turn on tracing in stlink\n"); @@ -302,31 +248,35 @@ static bool enable_trace(stlink_t* stlink, const st_settings_t* settings, uint32 return false; } - stlink_write_debug32(stlink, TPI_CSPSR, TPI_TPI_CSPSR_PORT_SIZE_1); + stlink_write_debug32(stlink, STLINK_REG_TPI_CSPSR, STLINK_REG_TPI_CSPSR_PORT_SIZE_1); if (settings->core_frequency) { uint32_t prescaler = settings->core_frequency / trace_frequency - 1; - if (prescaler > TPI_ACPR_MAX) { + if (prescaler > STLINK_REG_TPI_ACPR_MAX) { ELOG("Trace frequency prescaler %d out of range. Try setting a faster trace frequency.\n", prescaler); if (!settings->force) return false; } - stlink_write_debug32(stlink, TPI_ACPR, prescaler); // Set TPIU_ACPR clock divisor - } - stlink_write_debug32(stlink, TPI_FFCR, TPI_FFCR_TRIG_IN); - stlink_write_debug32(stlink, TPI_SPPR, TPI_SPPR_SWO_NRZ); - stlink_write_debug32(stlink, ITM_LAR, ITM_LAR_KEY); - stlink_write_debug32(stlink, ITM_TCC, 0x00000400); // Set sync counter - stlink_write_debug32(stlink, ITM_TCR, ITM_TCR_TRACE_BUS_ID_1 | ITM_TCR_TS_ENA | ITM_TCR_ITM_ENA); - stlink_write_debug32(stlink, ITM_TER, ITM_TER_PORTS_ALL); - stlink_write_debug32(stlink, ITM_TPR, ITM_TPR_PORTS_ALL); - stlink_write_debug32(stlink, DWT_CTRL, 4 * DWT_CTRL_NUM_COMP | DWT_CTRL_CYC_TAP | - 0xF * DWT_CTRL_POST_INIT | 0xF * DWT_CTRL_POST_PRESET | - DWT_CTRL_CYCCNT_ENA); - stlink_write_debug32(stlink, DCB_DEMCR, DEMCR_TRCENA); + stlink_write_debug32(stlink, STLINK_REG_TPI_ACPR, prescaler); // Set TPIU_ACPR clock divisor + } + stlink_write_debug32(stlink, STLINK_REG_TPI_FFCR, STLINK_REG_TPI_FFCR_TRIG_IN); + stlink_write_debug32(stlink, STLINK_REG_TPI_SPPR, STLINK_REG_TPI_SPPR_SWO_NRZ); + stlink_write_debug32(stlink, STLINK_REG_ITM_LAR, STLINK_REG_ITM_LAR_KEY); + stlink_write_debug32(stlink, STLINK_REG_ITM_TCC, 0x00000400); // Set sync counter + stlink_write_debug32(stlink, STLINK_REG_ITM_TCR, STLINK_REG_ITM_TCR_TRACE_BUS_ID_1 | + STLINK_REG_ITM_TCR_TS_ENA | + STLINK_REG_ITM_TCR_ITM_ENA); + stlink_write_debug32(stlink, STLINK_REG_ITM_TER, STLINK_REG_ITM_TER_PORTS_ALL); + stlink_write_debug32(stlink, STLINK_REG_ITM_TPR, STLINK_REG_ITM_TPR_PORTS_ALL); + stlink_write_debug32(stlink, STLINK_REG_DWT_CTRL, 4 * STLINK_REG_DWT_CTRL_NUM_COMP | + STLINK_REG_DWT_CTRL_CYC_TAP | + 0xF * STLINK_REG_DWT_CTRL_POST_INIT | + 0xF * STLINK_REG_DWT_CTRL_POST_PRESET | + STLINK_REG_DWT_CTRL_CYCCNT_ENA); + stlink_write_debug32(stlink, STLINK_REG_DEMCR, STLINK_REG_DEMCR_TRCENA); uint32_t prescaler; - stlink_read_debug32(stlink, TPI_ACPR, &prescaler); + stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR_MAX, &prescaler); if (prescaler) { uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; @@ -483,7 +433,7 @@ static void check_for_configuration_error(stlink_t* stlink, st_trace_t* trace, u if (error_no_data || error_low_data || error_bad_data) { uint32_t prescaler; - stlink_read_debug32(stlink, TPI_ACPR, &prescaler); + stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR, &prescaler); if (prescaler) { uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index fdea175d3..6d2c9f1af 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -3,8 +3,9 @@ #define STLINK_REG_CM3_CPUID 0xE000ED00 -#define STLINK_REG_CM3_FP_CTRL 0xE0002000 +#define STLINK_REG_CM3_FP_CTRL 0xE0002000 // Flash Patch Control Register #define STLINK_REG_CM3_FP_COMPn(n) (0xE0002008 + n*4) +#define STLINK_REG_CM3_FP_CTRL_KEY (1 << 1) #define STLINK_REG_CM7_FP_LAR 0xE0000FB0 #define STLINK_REG_CM7_FP_LAR_KEY 0xC5ACCE55 @@ -39,6 +40,55 @@ #define STLINK_REG_DHCSR_S_RESET_ST (1 << 25) #define STLINK_REG_DCRSR 0xe000edf4 #define STLINK_REG_DCRDR 0xe000edf8 +#define STLINK_REG_DEMCR 0xe000edfc +#define STLINK_REG_DEMCR_TRCENA (1 << 24) + +/* MCU Debug Component Registers */ +#define STLINK_REG_DBGMCU_CR 0xE0042004 // Debug MCU Configuration Register +#define STLINK_REG_DBGMCU_CR_DBG_SLEEP (1 << 0) +#define STLINK_REG_DBGMCU_CR_DBG_STOP (1 << 1) +#define STLINK_REG_DBGMCU_CR_DBG_STANDBY (1 << 2) +#define STLINK_REG_DBGMCU_CR_TRACE_IOEN (1 << 5) +#define STLINK_REG_DBGMCU_CR_TRACE_MODE_ASYNC (0x00 << 6) + +/* Data Watchpoint and Trace (DWT) Registers */ +#define STLINK_REG_DWT_CTRL 0xE0001000 // DWT Control Register +#define STLINK_REG_DWT_CTRL_NUM_COMP (1 << 28) +#define STLINK_REG_DWT_CTRL_CYC_TAP (1 << 9) +#define STLINK_REG_DWT_CTRL_POST_INIT (1 << 5) +#define STLINK_REG_DWT_CTRL_POST_PRESET (1 << 1) +#define STLINK_REG_DWT_CTRL_CYCCNT_ENA (1 << 0) +#define STLINK_REG_DWT_FUNCTION0 0xE0001028 // DWT Function Register 0 +#define STLINK_REG_DWT_FUNCTION1 0xE0001038 // DWT Function Register 1 +#define STLINK_REG_DWT_FUNCTION2 0xE0001048 // DWT Function Register 2 +#define STLINK_REG_DWT_FUNCTION3 0xE0001058 // DWT Function Register 3 + +/* Instrumentation Trace Macrocell (ITM) Registers */ +#define STLINK_REG_ITM_TER 0xE0000E00 // ITM Trace Enable Register +#define STLINK_REG_ITM_TER_PORTS_ALL (0xFFFFFFFF) +#define STLINK_REG_ITM_TPR 0xE0000E40 // ITM Trace Privilege Register +#define STLINK_REG_ITM_TPR_PORTS_ALL (0x0F) +#define STLINK_REG_ITM_TCR 0xE0000E80 // ITM Trace Control Register +#define STLINK_REG_ITM_TCR_TRACE_BUS_ID_1 (0x01 << 16) +#define STLINK_REG_ITM_TCR_SWO_ENA (1 << 4) +#define STLINK_REG_ITM_TCR_DWT_ENA (1 << 3) +#define STLINK_REG_ITM_TCR_SYNC_ENA (1 << 2) +#define STLINK_REG_ITM_TCR_TS_ENA (1 << 1) +#define STLINK_REG_ITM_TCR_ITM_ENA (1 << 0) +#define STLINK_REG_ITM_TCC 0xE0000E90 // ITM Trace Cycle Count +#define STLINK_REG_ITM_LAR 0xE0000FB0 // ITM Lock Access Register +#define STLINK_REG_ITM_LAR_KEY 0xC5ACCE55 + +/* Trace Port Interface (TPI) Registers */ +#define STLINK_REG_TPI_CSPSR 0xE0040004 // TPI Current Parallel Port Size Reg +#define STLINK_REG_TPI_CSPSR_PORT_SIZE_1 (0x01 << 0) +#define STLINK_REG_TPI_ACPR 0xE0040010 // TPI Async Clock Prescaler Register +#define STLINK_REG_TPI_ACPR_MAX (0x1FFF) +#define STLINK_REG_TPI_SPPR 0xE00400F0 // TPI Selected Pin Protocol Register +#define STLINK_REG_TPI_SPPR_SWO_MANCHESTER (0x01 << 0) +#define STLINK_REG_TPI_SPPR_SWO_NRZ (0x02 << 0) +#define STLINK_REG_TPI_FFCR 0xE0040304 // TPI Formatter and Flush Control Register +#define STLINK_REG_TPI_FFCR_TRIG_IN (0x01 << 8) /* Application Interrupt and Reset Control Register */ #define STLINK_REG_AIRCR 0xe000ed0c From 08a8474e3dea10a12a9f9b21885b8cdee0bb4a7a Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 7 Dec 2020 10:52:23 -0800 Subject: [PATCH 1087/1435] Removing unused variable warning. --- src/st-trace/trace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 7f586c7c2..7b31900a2 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -91,6 +91,7 @@ static void abort_trace() { #if defined(_WIN32) BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { + (void)fdwCtrlType; abort_trace(); return FALSE; } From d5c63c3b111381d6d58d47f8f05ccc485fa1c494 Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 7 Dec 2020 11:06:59 -0800 Subject: [PATCH 1088/1435] Moving has_dual_bank into the flags field. --- inc/stlink.h | 1 - src/common.c | 34 +++++++++++++++++----------------- src/stlink-lib/chipid.c | 9 +++------ src/stlink-lib/chipid.h | 4 ++-- 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index ef61fd1ba..d66cd74fb 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -198,7 +198,6 @@ struct _stlink { enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx - bool has_dual_bank; stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() size_t flash_size; // calculated by stlink_load_device_params() diff --git a/src/common.c b/src/common.c index a9e907c60..ec9f19b4a 100644 --- a/src/common.c +++ b/src/common.c @@ -511,7 +511,7 @@ static void unlock_flash(stlink_t *sl) { key_reg = STM32WB_FLASH_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { key_reg = FLASH_H7_KEYR1; - if (sl->has_dual_bank) { + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { key2_reg = FLASH_H7_KEYR2; } } else { @@ -575,7 +575,7 @@ static void lock_flash(stlink_t *sl) { cr_lock_shift = STM32WB_FLASH_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { cr_reg = FLASH_H7_CR1; - if (sl->has_dual_bank) { + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { cr2_reg = FLASH_H7_CR2; } cr_lock_shift = FLASH_H7_CR_LOCK; @@ -691,7 +691,7 @@ static int lock_flash_option(stlink_t *sl) { case STLINK_FLASH_TYPE_H7: optcr_reg = FLASH_H7_OPTCR; optlock_shift = FLASH_H7_OPTCR_OPTLOCK; - if (sl->has_dual_bank) + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) optcr2_reg = FLASH_H7_OPTCR2; break; default: @@ -759,7 +759,7 @@ static int unlock_flash_option(stlink_t *sl) { break; case STLINK_FLASH_TYPE_H7: optkey_reg = FLASH_H7_OPT_KEYR; - if (sl->has_dual_bank) + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) optkey2_reg = FLASH_H7_OPT_KEYR2; break; default: @@ -907,7 +907,7 @@ static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { cr_reg = STM32Gx_FLASH_CR; cr_mer = (1 << STM32Gx_FLASH_CR_MER1); - if (sl->has_dual_bank) { + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); } @@ -1034,7 +1034,7 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { res = read_flash_sr(sl, BANK_1) & (1 << sr_busy_shift); if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->has_dual_bank)) { + (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { res |= read_flash_sr(sl, BANK_2) & (1 << sr_busy_shift); } @@ -1085,13 +1085,13 @@ static int check_flash_error(stlink_t *sl) break; case STLINK_FLASH_TYPE_H7: res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; - if (sl->has_dual_bank) { + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; } if (res) { // Clear errors stlink_write_debug32(sl, FLASH_H7_CCR1, res); - if (sl->has_dual_bank) { + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { stlink_write_debug32(sl, FLASH_H7_CCR2, res); } } @@ -1355,7 +1355,6 @@ int stlink_load_device_params(stlink_t *sl) { } sl->flash_type = params->flash_type; - sl->has_dual_bank = params->has_dual_bank; sl->flash_pgsz = params->flash_pagesize; sl->sram_size = params->sram_size; sl->sys_base = params->bootrom_base; @@ -1378,8 +1377,9 @@ int stlink_load_device_params(stlink_t *sl) { } // H7 devices with small flash has one bank - if (sl->has_dual_bank && sl->flash_type == STLINK_FLASH_TYPE_H7) { - sl->has_dual_bank = (flash_size/sl->flash_pgsz) > 1; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK && sl->flash_type == STLINK_FLASH_TYPE_H7) { + if ((flash_size/sl->flash_pgsz) <= 1) + sl->chip_flags &= ~CHIP_F_HAS_DUAL_BANK; } #if 0 @@ -2621,7 +2621,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_id != STLINK_CHIPID_STM32_H7AX) { // set parallelism write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); - if (sl->has_dual_bank) { + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); } } @@ -2630,7 +2630,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { set_flash_cr_strt(sl, BANK_1); // start erase operation, reset by hw with busy bit if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->has_dual_bank)) { + (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { set_flash_cr_mer(sl, 1, BANK_2); // set the mass erase bit in bank 2 set_flash_cr_strt(sl, BANK_2); // start erase operation in bank 2 } @@ -2642,7 +2642,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { // reset the mass erase bit set_flash_cr_mer(sl, 0, BANK_1); if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->has_dual_bank)) { + (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { set_flash_cr_mer(sl, 0, BANK_2); } @@ -2872,13 +2872,13 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { unlock_flash_if(sl); // unlock the cr set_flash_cr_pg(sl, BANK_1); // set programming mode - if (sl->has_dual_bank) { + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { set_flash_cr_pg(sl, BANK_2); } if (sl->chip_id != STLINK_CHIPID_STM32_H7AX) { // set parallelism write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); - if (sl->has_dual_bank) { + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); } } @@ -3047,7 +3047,7 @@ int stlink_flashloader_stop(stlink_t *sl) { (sl->flash_type == STLINK_FLASH_TYPE_H7)) { clear_flash_cr_pg(sl, BANK_1); - if (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->has_dual_bank) { + if (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { clear_flash_cr_pg(sl, BANK_2); } lock_flash(sl); diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index dc3218261..425cc17d5 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -631,7 +631,6 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_G4_CAT3, .description = "G4 Category-3", .flash_type = STLINK_FLASH_TYPE_G4, - .has_dual_bank = true, .flash_size_reg = 0x1FFF75E0, // Section 47.2 .flash_pagesize = 0x800, // 2k (sec 3.3.1) // SRAM1 is 80k at 0x20000000 @@ -642,7 +641,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { // STM32WB55 (from RM0434) @@ -661,7 +660,6 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_H74XXX, .description = "H74x/H75x", .flash_type = STLINK_FLASH_TYPE_H7, - .has_dual_bank = true, .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) .flash_pagesize = 0x20000, // 128k sector (pg147) .sram_size = 0x20000, // 128k "DTCM" from Table 7 @@ -669,14 +667,13 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x20000, // "System memory" byte size in hex from Table 7 .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 - .flags = CHIP_F_HAS_SWO_TRACING, + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { // STM32H7A3/7B3 (from RM0455) .chip_id = STLINK_CHIPID_STM32_H7AX, .description = "H7Ax/H7Bx", .flash_type = STLINK_FLASH_TYPE_H7, - .has_dual_bank = true, .flash_size_reg = 0x08FFF80C, // "Flash size register" (p.2949) .flash_pagesize = 0x2000, // 8k sector (p.146) .sram_size = 0x20000, // 128k "DTCM" (Figure 1) @@ -684,7 +681,7 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x20000, // "System memory" byte size in hex splitted to two banks (Table 12-14) .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, - .flags = CHIP_F_HAS_SWO_TRACING, + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { // STM32H72x/H73x (from RM0468) diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index 5fee49f87..f790e7899 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -70,7 +70,8 @@ enum stlink_stm32_chipids { }; -#define CHIP_F_HAS_SWO_TRACING (1 << 0) +#define CHIP_F_HAS_DUAL_BANK (1 << 0) +#define CHIP_F_HAS_SWO_TRACING (1 << 1) /** Chipid parameters */ @@ -78,7 +79,6 @@ struct stlink_chipid_params { uint32_t chip_id; char *description; enum stlink_flash_type flash_type; - bool has_dual_bank; uint32_t flash_size_reg; uint32_t flash_pagesize; uint32_t sram_size; From cbd2633e64b93644eeec2fefdd10729d1fa02ff2 Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 7 Dec 2020 11:10:19 -0800 Subject: [PATCH 1089/1435] Fixing binary compatibility with the stlink structure. --- inc/stlink.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inc/stlink.h b/inc/stlink.h index d66cd74fb..9b5e56594 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -194,7 +194,6 @@ struct _stlink { char serial[STLINK_SERIAL_MAX_SIZE]; int serial_size; int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR - uint32_t max_trace_freq; // set by stlink_open_usb() enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx @@ -220,6 +219,8 @@ struct _stlink { struct stlink_version_ version; uint32_t chip_flags; // stlink_chipid_params.flags, set by stlink_load_device_params(), values: CHIP_F_xxx + + uint32_t max_trace_freq; // set by stlink_open_usb() }; int stlink_enter_swd_mode(stlink_t *sl); From 4cf8b79099ca28cf97be76b5fdf60e2e83bd06d2 Mon Sep 17 00:00:00 2001 From: John Hall Date: Wed, 9 Dec 2020 14:03:18 -0800 Subject: [PATCH 1090/1435] Fixing build on clang. --- src/st-trace/trace.c | 2 +- src/stlink-lib/helper.c | 2 +- src/stlink-lib/usb.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 7b31900a2..549a1a385 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -410,7 +410,7 @@ static bool read_trace(stlink_t* stlink, st_trace_t* trace) { static void check_for_configuration_error(stlink_t* stlink, st_trace_t* trace, uint32_t trace_frequency) { // Only check configuration one time after the first 10 seconds of running. - uint32_t elapsed_time_s = time(NULL) - trace->start_time; + time_t elapsed_time_s = time(NULL) - trace->start_time; if (trace->configuration_checked || elapsed_time_s < 10) { return; } diff --git a/src/stlink-lib/helper.c b/src/stlink-lib/helper.c index 8b2c8e8f7..32d9b6c8d 100644 --- a/src/stlink-lib/helper.c +++ b/src/stlink-lib/helper.c @@ -11,5 +11,5 @@ unsigned time_ms() { struct timeval tv; gettimeofday(&tv, NULL); - return (unsigned)tv.tv_sec * 1000 + tv.tv_usec / 1000; + return (unsigned)(tv.tv_sec * 1000 + tv.tv_usec / 1000); } diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index ec0720a03..caf31e280 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1109,7 +1109,7 @@ int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { return -1; } - size_t trace_count = read_uint16(sl->q_buf, 0); + uint16_t trace_count = read_uint16(sl->q_buf, 0); if (trace_count > size) { ELOG("read_trace insufficient buffer length\n"); From 95e9c36a85cefa9ca5cfa033dd9a9fe238a2f40d Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 13 Dec 2020 00:04:11 +0100 Subject: [PATCH 1091/1435] General Project Update - Mention support for VS Code (Closes #1057) - Compilation with GCC 11 fails (Closes #1077) - Updated list of contributors - Updated CHANGELOG.md --- CHANGELOG.md | 2 ++ README.md | 11 ++++++----- contributors.txt | 1 + src/st-util/gdb-server.c | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c178a4e4..eed8b8546 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,8 @@ Fixes: * st-util: wrong register values passed to gdb (st-link v2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027)) * [doc] Fixed wrong path for rules.d folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) * Use vl flashloader for all STM32F1 series ([#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) +* Fixed gettimeofday for MSVC ([#1074](https://github.com/stlink-org/stlink/pull/1074)) +* Fixed compilation with GCC 11 ([#1077](https://github.com/stlink-org/stlink/pull/1077)) v1.6.1 diff --git a/README.md b/README.md index 350c36e34..6bb99b892 100644 --- a/README.md +++ b/README.md @@ -42,11 +42,11 @@ On the user level there is no difference in handling or operation between these The STlink toolset includes: -* a communication library (libstlink.a), -* a programmer and chip information tool (st-info), -* a flash manipulation tool (st-flash), -* a GDB server (st-util) and -* a GUI-Interface (stlink-gui) _[optional]_ +* `libstlink` - a communication library +* `st-info` - a programmer and chip information tool +* `st-flash` - a flash manipulation tool +* `st-util` - a GDB server (supported in Visual Studio Code / VSCodium via the [Cortex-Debug](https://github.com/Marus/cortex-debug) plugin +* `stlink-gui` - a GUI-Interface [optional]_ ## Supported operating systems and hardware combinations @@ -58,6 +58,7 @@ Supported operating systems are listed in [version_support.md](doc/version_suppo The `stlink` toolset continues to maintain backwards compatibility with the **STLINK/v1** programmer.
      Please note that on macOS this support is limited to versions 10.13 - 10.15. + ## Tutorial & HOWTO Our [tutorial](doc/tutorial.md) may help you along with some advanced tasks and additional info. diff --git a/contributors.txt b/contributors.txt index 65b53aed1..57801b9ab 100644 --- a/contributors.txt +++ b/contributors.txt @@ -64,6 +64,7 @@ Jim Paris Jiří Netolický Jerry Nosky [jnosky] Jochen Wilhelmy [Jochen0x90h] +John Hall [simplerobot] Joel Bodenmann [Tectu] Johannes Taelman Jonas Danielsson diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index c47a3a9f3..4177cef11 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -43,7 +43,7 @@ static stlink_t *connected_stlink = NULL; static bool semihosting = false; static bool serial_specified = false; -static char serialnumber[28] = {0}; +static char serialnumber[STLINK_SERIAL_MAX_SIZE] = {0}; #if defined(_WIN32) #define close_socket win32_close_socket From a66557a102d48e69feb0a9746e8e42c4baf31fe2 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 13 Dec 2020 16:58:48 +0100 Subject: [PATCH 1092/1435] [doc] STM32F103 fake chips (Closes #1024) --- doc/tutorial.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/doc/tutorial.md b/doc/tutorial.md index 7b8b1d461..1d20c68ee 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -78,6 +78,28 @@ to ensure that the rules actually take effect. Using the trigger command means t If the VID:PID of your device doesn't match those in any of the 3 files, then you may need to create a custom rule file to match your VID:PID. +### b) NOTE: Chinese Fake-Chips CKS32F103C8T6 or CS32F103C8T6 being marked as "STM32F103C8T6" + +In contrast to "Clone chips" which identify themselves as such by their official marking (manufacturer, model, etc.), so called "Fake chips" do not. +Instead counterfeiters try to copy the outer appearance of the original and thus are very hard to detect. +Possible malfunction then may lead to various effects and issues during operation also in in connection with this toolset. + +As of December 2019 several so called "Bluepill-Boards" with a STM32F103C8T6 appeared on the market that do not hold the original part. +In this known example one finds the counterfeited "STM32F103C8T6" MCUs to identify themselves with chip-id `0x2ba01477` instead of `0x1ba01477`. + +In the following you find some hints on how to identify your chip and track down fraud: + +* [How to Detect STM32 Fakes](https://www.cnx-software.com/2020/03/22/how-to-detect-stm32-fakes/) +* [Confirmation by STMicroelectronics](https://www.mikrocontroller.net/attachment/442839/couterfeit_STM.png) (Marking: 991KA 93 MYS 807) + +However it appears that not all counterfeited parts cause problems during operation, but some are known to not even being able to execute a basic "blinky" example binary. Further there can be problems that may not even show up or affect you directly, but somewhen later in time (or maybe never). +This demonstrates there is no guarantee for a proper working chip with equal functionality compared to the original. + +Please keep this in mind and be sceptical when facing problems with this type of boards. +Check your hardware and try to identify what you have in front of you before assuming a bug in the `stlink` toolset. + +Please let us know, if you come across any further websites or tutorials that help to identify STM32 fake chips so we can list them here to help others. + ------ ( Content below is currently unrevised and may be outdated as of Apr 2020. ) From 0b7b1f3b03814a6d09d389697cc420a9de335a3c Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 19 Dec 2020 14:41:26 +0200 Subject: [PATCH 1093/1435] fix msvc build --- CMakeLists.txt | 1 + src/st-trace/trace.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f5c450e93..064aa06d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -249,6 +249,7 @@ if (MSVC) # Add getopt to sources include_directories(src/win32/getopt) set(ST-UTIL_SOURCES "${ST-UTIL_SOURCES};src/win32/getopt/getopt.c") + set(ST-TRACE_SOURCES "${ST-TRACE_SOURCES};src/win32/getopt/getopt.c") endif () add_executable(st-flash ${ST-FLASH_SOURCES}) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 549a1a385..e737e4d4a 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -552,7 +552,7 @@ int main(int argc, char** argv) } ILOG("Reading Trace\n"); - st_trace_t trace = {}; + st_trace_t trace = {0}; trace.start_time = time(NULL); if (stlink_run(stlink)) { From ffbecc4800c2053cf172cdeffa3c9772cb3d9636 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 19 Dec 2020 15:33:03 +0200 Subject: [PATCH 1094/1435] use memset for init struct --- src/st-trace/trace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index e737e4d4a..ee35a5923 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -552,7 +552,8 @@ int main(int argc, char** argv) } ILOG("Reading Trace\n"); - st_trace_t trace = {0}; + st_trace_t trace; + memset(&trace, 0, sizeof(trace)); trace.start_time = time(NULL); if (stlink_run(stlink)) { From e8c1e8a120cafa0a773ef6b93a3617087f322650 Mon Sep 17 00:00:00 2001 From: Luuk van Dijk Date: Sun, 20 Dec 2020 22:53:00 +0100 Subject: [PATCH 1095/1435] correctly handle endianness without reference to host platform --- src/common.c | 72 ++++++++++++---------------------------------------- 1 file changed, 16 insertions(+), 56 deletions(-) diff --git a/src/common.c b/src/common.c index ec9f19b4a..aaa2462a1 100644 --- a/src/common.c +++ b/src/common.c @@ -349,49 +349,32 @@ #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 + +// Endianness +// https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html +// These functions encode and decode little endian uint16 and uint32 values. + void write_uint32(unsigned char* buf, uint32_t ui) { - if (!is_bigendian()) { // le -> le (don't swap) - buf[0] = ((unsigned char*)&ui)[0]; - buf[1] = ((unsigned char*)&ui)[1]; - buf[2] = ((unsigned char*)&ui)[2]; - buf[3] = ((unsigned char*)&ui)[3]; - } else { - buf[0] = ((unsigned char*)&ui)[3]; - buf[1] = ((unsigned char*)&ui)[2]; - buf[2] = ((unsigned char*)&ui)[1]; - buf[3] = ((unsigned char*)&ui)[0]; - } + buf[0] = ui; + buf[1] = ui >> 8; + buf[2] = ui >> 16; + buf[3] = ui >> 24; } void write_uint16(unsigned char* buf, uint16_t ui) { - if (!is_bigendian()) { // le -> le (don't swap) - buf[0] = ((unsigned char*)&ui)[0]; - buf[1] = ((unsigned char*)&ui)[1]; - } else { - buf[0] = ((unsigned char*)&ui)[1]; - buf[1] = ((unsigned char*)&ui)[0]; - } + buf[0] = ui ; + buf[1] = ui >> 8; } uint32_t read_uint32(const unsigned char *c, const int pt) { - uint32_t ui; - char *p = (char *)&ui; - - if (!is_bigendian()) { // le -> le (don't swap) - p[0] = c[pt + 0]; - p[1] = c[pt + 1]; - p[2] = c[pt + 2]; - p[3] = c[pt + 3]; - } else { - p[0] = c[pt + 3]; - p[1] = c[pt + 2]; - p[2] = c[pt + 1]; - p[3] = c[pt + 0]; - } + return ((uint32_t)c[pt]) | ((uint32_t)c[pt+1] << 8) | ((uint32_t)c[pt+2] << 16) | ((uint32_t)c[pt+3] << 24) ; +} - return(ui); +uint16_t read_uint16(const unsigned char *c, const int pt) { + return ((uint16_t)c[pt]) | ((uint16_t)c[pt+1] << 8); } + static uint32_t get_stm32l0_flash_base(stlink_t *sl) { switch (sl->chip_id) { @@ -1779,30 +1762,7 @@ int stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size) { // End of delegates.... Common code below here... -// Endianness -// http://www.ibm.com/developerworks/aix/library/au-endianc/index.html -// const int i = 1; -// #define is_bigendian() ( (*(char*)&i) == 0 ) - -unsigned int is_bigendian(void) { - static volatile const unsigned int i = 1; - return(*(volatile const char*)&i == 0); -} - -uint16_t read_uint16(const unsigned char *c, const int pt) { - uint32_t ui; - char *p = (char *)&ui; - if (!is_bigendian()) { // le -> le (don't swap) - p[0] = c[pt + 0]; - p[1] = c[pt + 1]; - } else { - p[0] = c[pt + 1]; - p[1] = c[pt + 0]; - } - - return(ui); -} // same as above with entrypoint. From ddac731929b0c879a9a6dc9e17811abc88b682c3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 25 Dec 2020 23:33:20 +0100 Subject: [PATCH 1096/1435] Minor formatting fixes --- CHANGELOG.md | 4 ++-- README.md | 6 +++--- src/st-trace/trace.c | 1 - src/stlink-lib/chipid.c | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eed8b8546..ad13e46aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -317,13 +317,13 @@ Major changes and added features: * Added intel hex file reading for `st-flash` ([#110](https://github.com/stlink-org/stlink/pull/110), [#157](https://github.com/stlink-org/stlink/pull/157), [#457](https://github.com/stlink-org/stlink/pull/547), [#459](https://github.com/stlink-org/stlink/pull/549)) * Added support for ARM semihosting to `st-util` ([#147](https://github.com/stlink-org/stlink/pull/147), [#227](https://github.com/stlink-org/stlink/pull/227), [#454](https://github.com/stlink-org/stlink/pull/454), [#455](https://github.com/stlink-org/stlink/pull/455)) * Added manpages (generated with pandoc from Markdown) ([#208](https://github.com/stlink-org/stlink/pull/208), [#464](https://github.com/stlink-org/stlink/pull/464), [#466](https://github.com/stlink-org/stlink/pull/466), [#467](https://github.com/stlink-org/stlink/pull/467)) -* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#228](https://github.com/stlink-org/stlink/pull/228), ([#507](https://github.com/stlink-org/stlink/pull/507), commit [#3fd0f09](https://github.com/stlink-org/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) +* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#228](https://github.com/stlink-org/stlink/pull/228), [#507](https://github.com/stlink-org/stlink/pull/507), commit [#3fd0f09](https://github.com/stlink-org/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) * Support serial numbers argument for `st-util` and `st-flash` to probe and control multiple connected programmers ([#318](https://github.com/stlink-org/stlink/pull/318), [#398](https://github.com/stlink-org/stlink/pull/398), [#541](https://github.com/stlink-org/stlink/pull/541)) * Merge st-probe tool into st-info ([#398](https://github.com/stlink-org/stlink/pull/398)) * Added support for native debian packaging ([#444](https://github.com/stlink-org/stlink/pull/444), [#472](https://github.com/stlink-org/stlink/pull/472), [#473](https://github.com/stlink-org/stlink/pull/473), [#482](https://github.com/stlink-org/stlink/pull/482), [#483](https://github.com/stlink-org/stlink/pull/483), [#484](https://github.com/stlink-org/stlink/pull/484), [#485](https://github.com/stlink-org/stlink/pull/485)) * Rewritten commandline parsing for `st-flash` ([#459](https://github.com/stlink-org/stlink/pull/459)) * Added `--reset` command to `st-flash` ([#505](https://github.com/stlink-org/stlink/pull/505)) -* st-util should detect when USB commands fail ([#525](https://github.com/stlink-org/stlink/pull/525), ([#527](https://github.com/stlink-org/stlink/pull/527), ([#528](https://github.com/stlink-org/stlink/pull/528)) +* st-util should detect when USB commands fail ([#525](https://github.com/stlink-org/stlink/pull/525), [#527](https://github.com/stlink-org/stlink/pull/527), [#528](https://github.com/stlink-org/stlink/pull/528)) Chip support added for: diff --git a/README.md b/README.md index 6bb99b892..d401f2c5d 100644 --- a/README.md +++ b/README.md @@ -42,11 +42,11 @@ On the user level there is no difference in handling or operation between these The STlink toolset includes: -* `libstlink` - a communication library * `st-info` - a programmer and chip information tool * `st-flash` - a flash manipulation tool -* `st-util` - a GDB server (supported in Visual Studio Code / VSCodium via the [Cortex-Debug](https://github.com/Marus/cortex-debug) plugin -* `stlink-gui` - a GUI-Interface [optional]_ +* `st-util` - a GDB server (supported in Visual Studio Code / VSCodium via the [Cortex-Debug](https://github.com/Marus/cortex-debug) plugin) +* `stlink-lib` - a communication library +* `stlink-gui` - a GUI-Interface _[optional]_ ## Supported operating systems and hardware combinations diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index ee35a5923..71ba6b360 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -571,4 +571,3 @@ int main(int argc, char** argv) return APP_RESULT_SUCCESS; } - diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 425cc17d5..221234bbb 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -11,7 +11,7 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, // No flash pages .sram_size = 0x80000, // "SRAM" byte size in hex from .bootrom_base = 0x00200000, // ! "System memory" starting address from - .bootrom_size = 0xEDC0, // ! @todo "System memory" byte size in hex from + .bootrom_size = 0xEDC0, // ! @todo "System memory" byte size in hex from .option_base = STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option bytes, writing uses FLASH_F7_OPTCR and FLASH_F7_OPTCR1 .option_size = 0x20, .flags = CHIP_F_HAS_SWO_TRACING, From 4bfaab0ea993fe86da9f2aef612036adcf8ef58d Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 4 Jan 2021 00:53:24 +0100 Subject: [PATCH 1097/1435] Removed support for STLINK/v1 on macOS 10.13 --- README.md | 2 +- stlinkv1_macos_driver/install.sh | 5 +- .../Contents/Info.plist | 82 ------------- .../Contents/MacOS/stlink_shield_10_13 | Bin 33840 -> 0 bytes .../stlink_shield_10_13.kext/Contents/PkgInfo | 1 - .../Contents/_CodeSignature/CodeResources | 115 ------------------ .../Contents/Info.plist | 2 +- .../Contents/MacOS/stlink_shield_10_14 | Bin 33840 -> 33840 bytes .../Contents/Info.plist | 2 +- .../Contents/MacOS/stlink_shield_10_15 | Bin 33840 -> 33840 bytes .../stlink_shield.xcodeproj/project.pbxproj | 95 +-------------- .../contents.xcworkspacedata | 2 +- .../UserInterfaceState.xcuserstate | Bin 185319 -> 187405 bytes .../WorkspaceSettings.xcsettings | 6 +- .../xcschemes/stlink_shield_10.13.xcscheme | 67 ---------- .../xcschemes/xcschememanagement.plist | 34 +----- 16 files changed, 17 insertions(+), 396 deletions(-) delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/Info.plist delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/MacOS/stlink_shield_10_13 delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/PkgInfo delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/_CodeSignature/CodeResources delete mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.13.xcscheme diff --git a/README.md b/README.md index d401f2c5d..3799f46d2 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ It supports several so called STLINK programmer boards (and clones thereof) whic - transport layer: raw USB commands - stand-alone programmer -_*)_ **Note: Support on macOS is limited to 10.13 - 10.15. Any later versions are no longer compatible with the STLINK/v1 due to technical reasons.** +_*)_ **Note: Support on macOS is limited to 10.14 - 10.15. Any later versions are no longer compatible with the STLINK/v1 due to technical reasons.** On the user level there is no difference in handling or operation between these different revisions. diff --git a/stlinkv1_macos_driver/install.sh b/stlinkv1_macos_driver/install.sh index 19e9f141d..5716281a1 100644 --- a/stlinkv1_macos_driver/install.sh +++ b/stlinkv1_macos_driver/install.sh @@ -2,15 +2,12 @@ ISMACOS=$(sw_vers -productVersion) case $ISMACOS in -10.13*) - KEXT="stlink_shield_10_13.kext" - ;; 10.14*) KEXT="stlink_shield_10_14.kext" ;; 10.15*) KEXT="stlink_shield_10_15.kext" - ;; + ;; *) echo "OS X version not supported." exit 1 diff --git a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/Info.plist b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/Info.plist deleted file mode 100644 index fc759b362..000000000 --- a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/Info.plist +++ /dev/null @@ -1,82 +0,0 @@ - - - - - BuildMachineOSBuild - 18G4032 - CFBundleDevelopmentRegion - English - CFBundleIdentifier - com.libusb.stlink-shield - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - KEXT - CFBundleSignature - ???? - CFBundleSupportedPlatforms - - MacOSX - - CFBundleVersion - 1.0.0 - DTCompiler - com.apple.compilers.llvm.clang.1_0 - DTPlatformBuild - 11C504 - DTPlatformVersion - GM - DTSDKBuild - 19B90 - DTSDKName - macosx10.15 - DTXcode - 1130 - DTXcodeBuild - 11C504 - IOKitPersonalities - - DeviceDriver - - CFBundleIdentifier - com.apple.kpi.iokit - IOClass - IOService - IOProviderClass - IOUSBDevice - bcdDevice - 256 - idProduct - 14148 - idVendor - 1155 - - InterfaceDriver - - CFBundleIdentifier - com.apple.kpi.iokit - IOClass - IOService - IOProviderClass - IOUSBInterface - bConfigurationValue - 1 - bInterfaceNumber - 0 - idProduct - 14148 - idVendor - 1155 - - - LSMinimumSystemVersion - 10.13 - OSBundleLibraries - - com.apple.iokit.IOUSBFamily - 1.8 - com.apple.kpi.libkern - 11.2.0 - - - diff --git a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/MacOS/stlink_shield_10_13 b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/MacOS/stlink_shield_10_13 deleted file mode 100644 index 161c0a829359293dc1189621a2d41dbdc31ab5ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33840 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 diff --git a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/PkgInfo b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/PkgInfo deleted file mode 100644 index bdab95bcc..000000000 --- a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/PkgInfo +++ /dev/null @@ -1 +0,0 @@ -KEXT???? \ No newline at end of file diff --git a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/_CodeSignature/CodeResources b/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/_CodeSignature/CodeResources deleted file mode 100644 index d5d0fd744..000000000 --- a/stlinkv1_macos_driver/stlink_shield_10_13.kext/Contents/_CodeSignature/CodeResources +++ /dev/null @@ -1,115 +0,0 @@ - - - - - files - - files2 - - rules - - ^Resources/ - - ^Resources/.*\.lproj/ - - optional - - weight - 1000 - - ^Resources/.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^Resources/Base\.lproj/ - - weight - 1010 - - ^version.plist$ - - - rules2 - - .*\.dSYM($|/) - - weight - 11 - - ^(.*/)?\.DS_Store$ - - omit - - weight - 2000 - - ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ - - nested - - weight - 10 - - ^.* - - ^Info\.plist$ - - omit - - weight - 20 - - ^PkgInfo$ - - omit - - weight - 20 - - ^Resources/ - - weight - 20 - - ^Resources/.*\.lproj/ - - optional - - weight - 1000 - - ^Resources/.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^Resources/Base\.lproj/ - - weight - 1010 - - ^[^/]+$ - - nested - - weight - 10 - - ^embedded\.provisionprofile$ - - weight - 20 - - ^version\.plist$ - - weight - 20 - - - - diff --git a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist index d43deca2b..fd424ea93 100644 --- a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist +++ b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist @@ -3,7 +3,7 @@ BuildMachineOSBuild - 18G4032 + 18G7016 CFBundleDevelopmentRegion English CFBundleIdentifier diff --git a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 index a49757ef1fc67fcaeb819c141550efa3f275928a..6a32aa4615953f6afe16047f73da9a3bced9b3a3 100644 GIT binary patch delta 4217 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 delta 4337 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 BuildMachineOSBuild - 18G4032 + 18G7016 CFBundleDevelopmentRegion English CFBundleIdentifier diff --git a/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/MacOS/stlink_shield_10_15 b/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/MacOS/stlink_shield_10_15 index 4e64961ae1a6cb922efe525978510783165de57f..8dfd2fb304f4ab6e7e64739030d81ed7202efdc9 100644 GIT binary patch delta 4217 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 + location = "self:/Users/vm-user/Desktop/macOS kext/stlink_shield_xcode/stlink_shield.xcodeproj"> diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/UserInterfaceState.xcuserstate b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/UserInterfaceState.xcuserstate index b06818d2f7b3b1cd51b2e0589a4382c7af8c7b30..913b254d69fcea63feaa9a2379a3365b4b105003 100644 GIT binary patch literal 187405 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�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�S327Hl5@)y@&Lk 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

      Lua8Nv+ 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 diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/WorkspaceSettings.xcsettings b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/WorkspaceSettings.xcsettings index e097e4fe6..8552060d5 100644 --- a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/WorkspaceSettings.xcsettings +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/WorkspaceSettings.xcsettings @@ -3,7 +3,9 @@ BuildLocationStyle - UseAppPreferences + UseTargetSettings + BuildSystemType + Latest CustomBuildIntermediatesPath Build/Intermediates.noindex CustomBuildLocationType @@ -13,7 +15,7 @@ DerivedDataLocationStyle Default IssueFilterStyle - ShowActiveSchemeOnly + ShowAll LiveSourceIssuesEnabled SharedBuildFolderName diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.13.xcscheme b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.13.xcscheme deleted file mode 100644 index d98dd9b97..000000000 --- a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.13.xcscheme +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist index d23112ec9..c9d1a75b6 100644 --- a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist @@ -4,45 +4,15 @@ SchemeUserState - stlink_shield 10.7.xcscheme_^#shared#^_ - - orderHint - 2 - - stlink_shield copy copy.xcscheme_^#shared#^_ - - orderHint - 3 - - stlink_shield copy.xcscheme_^#shared#^_ - - orderHint - 2 - - stlink_shield.xcscheme_^#shared#^_ - - orderHint - 1 - - stlink_shield_10.13.xcscheme_^#shared#^_ - - orderHint - 0 - - stlink_shield_10.14 copy.xcscheme_^#shared#^_ - - orderHint - 4 - stlink_shield_10.14.xcscheme_^#shared#^_ orderHint - 1 + 0 stlink_shield_10.15.xcscheme_^#shared#^_ orderHint - 2 + 1 SuppressBuildableAutocreation From 9fd7e63ec2bcb79ba70521a4918bdf3bfe492adc Mon Sep 17 00:00:00 2001 From: Sebastiaan de Schaetzen Date: Thu, 14 Jan 2021 11:45:49 +0100 Subject: [PATCH 1098/1435] flash_loader: increase wait rounds for slow boards --- src/stlink-lib/flash_loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index b7726e875..b55953406 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -368,7 +368,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe * the OS uses, the wait until the error message is reduced to the same order of magnitude * as what was intended. -- REW. */ -#define WAIT_ROUNDS 30 +#define WAIT_ROUNDS 40 // wait until done (reaches breakpoint) for (i = 0; i < WAIT_ROUNDS; i++) { From 1b29c6529d8723f35afd92dd108988f996d5dcde Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 20 Feb 2021 20:26:39 +0200 Subject: [PATCH 1099/1435] check format string for log messages --- src/common.c | 64 +++++++++++++++++++-------------------- src/st-util/semihosting.c | 6 ++-- src/stlink-lib/logging.h | 16 +++++++--- src/stlink-lib/sg.c | 4 +-- src/stlink-lib/usb.c | 2 +- 5 files changed, 49 insertions(+), 43 deletions(-) diff --git a/src/common.c b/src/common.c index aaa2462a1..99049196d 100644 --- a/src/common.c +++ b/src/common.c @@ -1373,9 +1373,9 @@ int stlink_load_device_params(stlink_t *sl) { sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, (unsigned int)sl->flash_pgsz); #else - ILOG("%s: %zd KiB SRAM, %zd KiB flash in at least %zd %s pages.\n", - params->description, sl->sram_size / 1024, sl->flash_size / 1024, - (sl->flash_pgsz < 1024) ? sl->flash_pgsz : sl->flash_pgsz / 1024, + ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", + params->description, (unsigned)(sl->sram_size / 1024), (unsigned)(sl->flash_size / 1024), + (sl->flash_pgsz < 1024) ? (unsigned)(sl->flash_pgsz) : (unsigned)(sl->flash_pgsz / 1024), (sl->flash_pgsz < 1024) ? "byte" : "KiB"); #endif return(0); @@ -1398,7 +1398,7 @@ int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { DLOG("*** stlink_soft_reset %s***\n", halt_on_reset?"(halt) ":""); - // halt core and enable debugging (if not already done) + // halt core and enable debugging (if not already done) // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_DEBUGEN); @@ -1585,7 +1585,7 @@ int stlink_target_voltage(stlink_t *sl) { voltage = sl->backend->target_voltage(sl); if (voltage != -1) { - DLOG("target voltage = %ldmV\n", voltage); + DLOG("target voltage = %imV\n", voltage); } else { DLOG("error reading target voltage\n"); } @@ -2201,8 +2201,8 @@ static bool stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg* the_ int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size) { // read size bytes from addr to file - ILOG("read from address %#010x size %d\n", addr, size); - + ILOG("read from address %#010x size %u\n", addr, (unsigned)size); + int error; int fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); @@ -2565,7 +2565,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { stm32_addr_t addr = (stm32_addr_t)sl->flash_base + i * (stm32_addr_t)sl->flash_pgsz; if (stlink_erase_flash_page(sl, addr) == -1) { - WLOG("Failed to erase_flash_page(%#zx) == -1\n", addr); + WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); return(-1); } @@ -2701,7 +2701,7 @@ int stm32l1_write_half_pages( for (count = 0; count < num_half_pages; count++) { if (stlink_flash_loader_run( sl, &fl, addr + count * pagesize, base + count * pagesize, pagesize) == -1) { - WLOG("l1_stlink_flash_loader_run(%#zx) failed! == -1\n", addr + count * pagesize); + WLOG("l1_stlink_flash_loader_run(%#x) failed! == -1\n", addr + count * pagesize); stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); @@ -2734,7 +2734,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { (sl->flash_type == STLINK_FLASH_TYPE_F7) || (sl->flash_type == STLINK_FLASH_TYPE_L4)) { ILOG("Starting Flash write for F2/F4/F7/L4\n"); - + // Flash loader initialisation if (stlink_flash_loader_init(sl, fl) == -1) { ELOG("stlink_flash_loader_init() == -1\n"); @@ -2750,7 +2750,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { } else { voltage = stlink_target_voltage(sl); } - + if (voltage == -1) { ELOG("Failed to read Target voltage\n"); return(-1); @@ -2771,7 +2771,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { "using 8-bit flash writes\n", voltage); write_flash_cr_psiz(sl, 0, BANK_1); } - } + } // set programming mode set_flash_cr_pg(sl, BANK_1); @@ -2850,7 +2850,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { return(0); } -int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, +int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len) { size_t off; if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || @@ -2860,7 +2860,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr for (off = 0; off < len;) { size_t size = len - off > buf_size ? buf_size : len - off; if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { - ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); + ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", (unsigned)(addr + off)); return(-1); } @@ -2921,7 +2921,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr // write remaining word in program memory for ( ; off < len; off += sizeof(uint32_t)) { uint32_t data; - + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { fprintf(stdout, "\r%3u/%3u pages written", (unsigned int)(off / sl->flash_pgsz), @@ -2955,7 +2955,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr DLOG("Finished unlocking flash, running loader!\n"); if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { - ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); + ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", (unsigned)(addr + off)); return(-1); } @@ -3003,7 +3003,7 @@ int stlink_flashloader_stop(stlink_t *sl) { (sl->flash_type == STLINK_FLASH_TYPE_L4) || (sl->flash_type == STLINK_FLASH_TYPE_WB) || (sl->flash_type == STLINK_FLASH_TYPE_G0) || - (sl->flash_type == STLINK_FLASH_TYPE_G4) || + (sl->flash_type == STLINK_FLASH_TYPE_G4) || (sl->flash_type == STLINK_FLASH_TYPE_H7)) { clear_flash_cr_pg(sl, BANK_1); @@ -3056,9 +3056,9 @@ int stlink_write_flash( WLOG("unaligned len 0x%x -- padding with zero\n", len); len += 1; } else if (addr & (sl->flash_pgsz - 1)) { - ELOG("addr not a multiple of current pagesize (%zd bytes), not supported, " + ELOG("addr not a multiple of current pagesize (%u bytes), not supported, " "check page start address and compare with flash module organisation " - "in related ST reference manual of your device.\n", sl->flash_pgsz); + "in related ST reference manual of your device.\n", (unsigned)(sl->flash_pgsz)); return(-1); } @@ -3071,7 +3071,7 @@ int stlink_write_flash( for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + (uint32_t)off)) { // addr must be an addr inside the page if (stlink_erase_flash_page(sl, addr + (uint32_t)off) == -1) { - ELOG("Failed to erase_flash_page(%#zx) == -1\n", addr + off); + ELOG("Failed to erase_flash_page(%#x) == -1\n", (unsigned)(addr + off)); return(-1); } @@ -3079,8 +3079,8 @@ int stlink_write_flash( page_count++; } - ILOG("Finished erasing %d pages of %d (%#x) bytes\n", - page_count, sl->flash_pgsz, sl->flash_pgsz); + ILOG("Finished erasing %d pages of %u (%#x) bytes\n", + page_count, (unsigned)(sl->flash_pgsz), (unsigned)(sl->flash_pgsz)); if (eraseonly) { return(0); } @@ -3092,7 +3092,7 @@ int stlink_write_flash( return ret; ret = stlink_flashloader_stop(sl); if (ret) - return ret; + return ret; return(stlink_verify_write_flash(sl, addr, base, len)); } @@ -3145,7 +3145,7 @@ int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, data = calloc(*size, 1); // use calloc to get NULL if out of memory if (!data) { - ELOG("Cannot allocate %d bytes\n", *size); + ELOG("Cannot allocate %u bytes\n", (unsigned)(*size)); res = -1; break; } @@ -3520,7 +3520,7 @@ static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t* base, stm32_addr_ addr = FLASH_F7_OPTCR; ILOG("No address provided, using %#10x\n", addr); } - + if ( addr == FLASH_F7_OPTCR ) { /* write option byte, ensuring we dont lock opt, and set strt bit */ stlink_write_debug32(sl, FLASH_F7_OPTCR, (option_byte & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); @@ -3542,7 +3542,7 @@ static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t* base, stm32_addr_ ret = check_flash_error(sl); if (!ret) ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t*) base, addr); - + /* option bytes are reloaded at reset only, no obl. */ return ret; @@ -3899,7 +3899,7 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui return(-1); } - + if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { ELOG("Option bytes start address out of Option bytes range\n"); return(-1); @@ -3972,7 +3972,7 @@ static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option ILOG("Asked to write option control register 1 %#10x to %#010x.\n", option_control_register, FLASH_F7_OPTCR); //write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); //ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); - + /* write option byte, ensuring we dont lock opt, and set strt bit */ stlink_write_debug32(sl, FLASH_F7_OPTCR, (option_control_register & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); @@ -3981,7 +3981,7 @@ static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option ret = check_flash_error(sl); if (!ret) ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, FLASH_F7_OPTCR1); - + return ret; } @@ -3997,11 +3997,11 @@ static int stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t optio ILOG("Asked to write option control register 1 %#010x to %#010x.\n", option_control_register1, FLASH_F7_OPTCR1); //write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); //ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); - + /* write option byte, ensuring we dont lock opt, and set strt bit */ uint32_t current_control_register_value; stlink_read_debug32(sl, FLASH_F7_OPTCR, ¤t_control_register_value); - + /* write option byte */ stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_control_register1); stlink_write_debug32(sl, FLASH_F7_OPTCR, (current_control_register_value & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); @@ -4011,7 +4011,7 @@ static int stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t optio ret = check_flash_error(sl); if (!ret) ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register1, FLASH_F7_OPTCR1); - + return ret; } diff --git a/src/st-util/semihosting.c b/src/st-util/semihosting.c index 821dcdbbb..32169c812 100644 --- a/src/st-util/semihosting.c +++ b/src/st-util/semihosting.c @@ -256,7 +256,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { return(-1); } - DLOG("Semihosting: write(%d, target_addr:0x%08x, %zu)\n", fd, buffer_address, + DLOG("Semihosting: write(%d, target_addr:0x%08x, %u)\n", fd, buffer_address, buffer_len); *ret = (uint32_t)write(fd, buffer, buffer_len); @@ -305,7 +305,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { return(-1); } - DLOG("Semihosting: read(%d, target_addr:0x%08x, %zu)\n", fd, buffer_address, + DLOG("Semihosting: read(%d, target_addr:0x%08x, %u)\n", fd, buffer_address, buffer_len); read_result = read(fd, buffer, buffer_len); @@ -399,7 +399,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { fd = (int)args[0]; offset = (off_t)args[1]; - DLOG("Semihosting: lseek(%d, %d, SEEK_SET)\n", fd, offset); + DLOG("Semihosting: lseek(%d, %d, SEEK_SET)\n", fd, (int)offset); *ret = (uint32_t)lseek(fd, offset, SEEK_SET); saved_errno = errno; diff --git a/src/stlink-lib/logging.h b/src/stlink-lib/logging.h index 78562b0d9..7f3994492 100644 --- a/src/stlink-lib/logging.h +++ b/src/stlink-lib/logging.h @@ -16,8 +16,14 @@ enum ugly_loglevel { UERROR = 20 }; +#if defined(__GNUC__) +#define PRINTF_ARRT __attribute__ ((format (printf, 3, 4))) +#else +#define PRINTF_ARRT +#endif + int ugly_init(int maximum_threshold); -int ugly_log(int level, const char *tag, const char *format, ...); +int ugly_log(int level, const char *tag, const char *format, ...) PRINTF_ARRT; int ugly_libusb_log_level(enum ugly_loglevel v); #define UGLY_LOG_FILE (strstr(__FILE__, "/") != NULL ? \ @@ -27,13 +33,13 @@ int ugly_libusb_log_level(enum ugly_loglevel v); // TODO: we need to write this in a more generic way, for now this should compile // on visual studio (See http://stackoverflow.com/a/8673872/1836746) #define DLOG_HELPER(format, ...) ugly_log(UDEBUG, UGLY_LOG_FILE, format, __VA_ARGS__) -#define DLOG(...) DLOG_HELPER(__VA_ARGS__, "") +#define DLOG(...) ugly_log(UDEBUG, UGLY_LOG_FILE, __VA_ARGS__) #define ILOG_HELPER(format, ...) ugly_log(UINFO, UGLY_LOG_FILE, format, __VA_ARGS__) -#define ILOG(...) ILOG_HELPER(__VA_ARGS__, "") +#define ILOG(...) ugly_log(UINFO, UGLY_LOG_FILE, __VA_ARGS__) #define WLOG_HELPER(format, ...) ugly_log(UWARN, UGLY_LOG_FILE, format, __VA_ARGS__) -#define WLOG(...) WLOG_HELPER(__VA_ARGS__, "") +#define WLOG(...) ugly_log(UWARN, UGLY_LOG_FILE, __VA_ARGS__) #define ELOG_HELPER(format, ...) ugly_log(UERROR, UGLY_LOG_FILE, format, __VA_ARGS__) -#define ELOG(...) ELOG_HELPER(__VA_ARGS__, "") +#define ELOG(...) ugly_log(UERROR, UGLY_LOG_FILE, __VA_ARGS__) #ifdef __cplusplus } diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index f66864c44..840466e75 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -161,7 +161,7 @@ static int dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) { } sprintf(dbugp, "]\n"); - DLOG(dbugblah); + DLOG("%s",dbugblah); return(0); } @@ -274,7 +274,7 @@ static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t } if (transferred != sizeof(sense)) { - WLOG("received unexpected amount of sense: %d != %d\n", transferred, sizeof(sense)); + WLOG("received unexpected amount of sense: %d != %u\n", transferred, (unsigned)sizeof(sense)); } uint32_t received_tag; diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index caf31e280..0168834ca 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1442,7 +1442,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { if (ret < 0) { if (ret == LIBUSB_ERROR_ACCESS) { - ELOG("Could not open USB device %#06x:%#06x, access error.\n", desc.idVendor, desc.idProduct, ret); + ELOG("Could not open USB device %#06x:%#06x, access error.\n", desc.idVendor, desc.idProduct); } else { ELOG("Failed to open USB device %#06x:%#06x, libusb error: %d)\n", desc.idVendor, desc.idProduct, ret); } From d0416149e0761f3a541b0719f76be327bec26337 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 6 Mar 2021 17:36:26 +0100 Subject: [PATCH 1100/1435] General Project Update - Updated ISSUE_TEMPLATES - Updated .gitignore --- .github/ISSUE_TEMPLATE/bug-report.md | 12 ++++++------ .github/ISSUE_TEMPLATE/feature-request.md | 14 +++++++------- .gitignore | 5 ++++- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index fc30f3993..d76943d1e 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -11,13 +11,13 @@ Thank you for giving feedback to the stlink project. - [ ] I made serious effort to avoid creating duplicate or nearly similar issue -In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out each of the following items appropriate to your specific problem: +In order to allow developers and other contributors to isolate and target your respective issue, please take some time to select the check boxes below and edit each item individually appropriate to your specific problem. -- Programmer/board type: [enter here] (e.g Stlink /v1, /v2, /v2-clone, /v2-1) -- Operating system and version: [enter here] (e.g Linux, Mac OS X, Windows) -- **Stlink tools version** and/or git commit hash: [enter here] (e.g v1.1.0/git-c722056) -- Stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-util`) -- Target chip (and board if applicable): [enter here] (e.g STM32F402VG) +- [ ] Programmer/board type: (e.g ST-Link/v1, ST-Link/v2, ST-Link/v2-onboard, ST-Link/v3) +- [ ] Operating system: (e.g Linux, Mac OS X, Windows (with specific version)) +- [ ] Stlink tools version and/or git commit hash: (e.g v1.1.0/git-c722056) +- [ ] Stlink commandline tool name: (e.g `st-info`, `st-flash`, `st-util`) +- [ ] Target chip (and optional board): (e.g STM32F402VG (STM32Fxxx Discovery)) Futher we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index 133b895b2..c6e236ce1 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -11,15 +11,15 @@ Thank you for giving feedback to the stlink project. - [ ] I made serious effort to avoid creating duplicate or nearly similar issue -In order to allow developers and other contributors to isolate and target your respective issue, please take some time to fill out the check boxes below by setting a 'x' into the checkboxes ( [x] ) and edit each item appropriate to your specific problem. +In order to allow developers and other contributors to isolate and target your respective issue, please take some time to select the check boxes below and edit each item individually appropriate to your specific request. -- [ ] Programmer/board type: e.g Stlink/v1, Stlink/v2, Stlink/v2-onboard -- [ ] Operating system: e.g Linux, Mac OS X, Windows (with specific version) -- [ ] Stlink tools version and/or git commit hash: e.g v1.1.0/git-c722056 -- [ ] Stlink commandline tool name: e.g `st-info`, `st-flash`, `st-util` -- [ ] Target chip (and optional board): e.g STM32F402VG (STM32Fxxx Discovery) +- [ ] Programmer/board type: (e.g ST-Link/v1, ST-Link/v2, ST-Link/v2-onboard, ST-Link/v3) +- [ ] Operating system: (e.g Linux, Mac OS X, Windows (with specific version)) +- [ ] Stlink tools version and/or git commit hash: (e.g v1.1.0/git-c722056) +- [ ] Stlink commandline tool name: (e.g `st-info`, `st-flash`, `st-util`) +- [ ] Target chip (and optional board): (e.g STM32F402VG (STM32Fxxx Discovery)) -Futher we kindly ask you to describe the detected problem as detailled as possible and to add debug output if available, by using the following template: +Futher we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: Commandline-Output: diff --git a/.gitignore b/.gitignore index 09b9b33de..e753cbe42 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ build build-mingw +.cmake/ +.vscode/ +.project + obj-* *.user* -.project From 29be2cf26a0f9dce79f544d48f30b5dfa0568b98 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 8 Mar 2021 23:24:45 +0100 Subject: [PATCH 1101/1435] General Project Update - Updated CHANGELOG.md - Minor formatting & spelling fix - Minor corrections --- CHANGELOG.md | 1 + doc/devices_boards.md | 2 +- doc/flashloaders.md | 2 +- doc/version_support.md | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad13e46aa..d304ab616 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -128,6 +128,7 @@ Fixes: * [regression] Fixed sign-compare (size != rep_len) in usb.c ([#772](https://github.com/stlink-org/stlink/pull/772), [#869](https://github.com/stlink-org/stlink/pull/869), [#872](https://github.com/stlink-org/stlink/pull/872), [#891](https://github.com/stlink-org/stlink/pull/891)) * Fixed dead loop after an unexpected unplug ([#780](https://github.com/stlink-org/stlink/pull/780), [#812](https://github.com/stlink-org/stlink/pull/812), [#913](https://github.com/stlink-org/stlink/pull/913)) * Avoid re-define of O_BINARY on Windows ([#788](https://github.com/stlink-org/stlink/pull/788)) +* Fixed stlink lock-up when not connected to a device via JTAG / SWD ([#835](https://github.com/stlink-org/stlink/pull/835), [#943](https://github.com/stlink-org/stlink/pull/943)) * Fixed st-flash manpage read example ([#858](https://github.com/stlink-org/stlink/pull/858)) * Fixed stlink support with no mass storage ([#861](https://github.com/stlink-org/stlink/pull/861)) * Make Version.cmake more error-resistant ([#872](https://github.com/stlink-org/stlink/pull/872)) diff --git a/doc/devices_boards.md b/doc/devices_boards.md index 4402839c5..97094b972 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -53,7 +53,7 @@ Tested boards [incl. STLink programmers]: | 0x430 | XL-Density | xF xG | | F101 | | F103 | | Tested boards [incl. STLink programmers]: -* STM32VL-Discovery (STM32F100RBT6) with STLink-v1 [v1, v2] +* STM32VL-Discovery (STM32F100RBT6) with STLink-v1 [v1], [v2] * STM32F103-Bluepill: C8Tx & R8xx [v2] * Nucleo-F103RB [v2-1] * HY-STM32 (STM32F103VETx) [v1, v2] diff --git a/doc/flashloaders.md b/doc/flashloaders.md index 6a7cb3504..b1208b6f5 100644 --- a/doc/flashloaders.md +++ b/doc/flashloaders.md @@ -6,7 +6,7 @@ The on-chip FLASH of STM32 needs to be written once a byte/half word/word/double As SRAM is usually less in size than FLASH, `stlink` only flashes one page (may be less if SRAM is insufficient) at a time. The whole flashing process may consist of server launches of flashloaders. -## The flahsing process +## The flashing process 1. `st-flash` loads compiled binary of corresponding flashloader to SRAM by calling `stlink_flash_loader_init` in `src/flash_loader.c` 2. `st-flash` erases corresponding flash page by calling `stlink_erase_flash_page` in `common.c`. diff --git a/doc/version_support.md b/doc/version_support.md index 43c201101..afa2d2bd7 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -21,7 +21,7 @@ Thus no user interaction regarding libusb is necessary. | homebrew | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3 | 10.12 (Sierra)- 10.15 (Catalina) | | MacPorts | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | 10.6 (Snow Leopard) - 10.15 (Catalina) | -NOTE: In order to use a STLINK/v1 programmer on macOS, versions 10.13, 10.14 or 10.15 are required. +NOTE: In order to use a STLINK/v1 programmer on macOS, versions 10.14 or 10.15 are required. ### Linux-/Unix-based: From 70f68e1c62d61c970b937b44eb438f2f49b15dc4 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 10 Mar 2021 16:06:51 +0100 Subject: [PATCH 1102/1435] Updated travis CI build settings. --- .travis.yml | 285 +++++++++++++++++++++++++++++----------------------- 1 file changed, 157 insertions(+), 128 deletions(-) diff --git a/.travis.yml b/.travis.yml index 17db35765..27fbec5f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,140 +1,169 @@ language: c jobs: - include: - ### 64-bit builds on AMD64 ### - - os: linux - dist: bionic - env: BADGE=linux - compiler: gcc-5 - addons: - apt: - sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - - os: linux - dist: bionic - env: BADGE=linux - compiler: gcc-9 - addons: - apt: - sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - - os: linux - dist: xenial - env: BADGE=linux - compiler: clang-3.7 - addons: - apt: - sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-3.7'] - packages: ['clang-3.7', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - - os: linux - dist: bionic - env: BADGE=linux - compiler: clang-6.0 - addons: - apt: - sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] - packages: ['clang-6.0', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - - os: linux - dist: bionic - env: BADGE=linux - compiler: clang-9 - addons: - apt: - sources: ['ubuntu-toolchain-r-test'] - packages: ['clang-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] + include: + ### 64-bit builds on AMD64 ### + - os: linux + dist: bionic + env: BADGE=linux + compiler: gcc-5 + addons: + apt: + sources: ["ubuntu-toolchain-r-test"] + packages: ["gcc-5", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + - os: linux + dist: bionic + env: BADGE=linux + compiler: gcc-9 + addons: + apt: + sources: ["ubuntu-toolchain-r-test"] + packages: ["gcc-9", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + - os: linux + dist: focal + env: BADGE=linux + compiler: gcc-10 + addons: + apt: + sources: ["ubuntu-toolchain-r-test"] + packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + - os: linux + dist: xenial + env: BADGE=linux + compiler: clang-3.7 + addons: + apt: + sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-xenial-3.7"] + packages: ["clang-3.7", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + - os: linux + dist: bionic + env: BADGE=linux + compiler: clang-6.0 + addons: + apt: + sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-bionic-6.0"] + packages: ["clang-6.0", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + - os: linux + dist: bionic + env: BADGE=linux + compiler: clang-9 + addons: + apt: + sources: ["ubuntu-toolchain-r-test"] + packages: ["clang-9", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + - os: linux + dist: focal + env: BADGE=linux + compiler: clang-10 + addons: + apt: + sources: ["ubuntu-toolchain-r-test"] + packages: ["clang-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - - os: linux - dist: bionic - env: BADGE=linux-mingw - name: linux-mingw - compiler: gcc-9 - addons: - apt: - sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm', 'mingw-w64'] + - os: linux + dist: bionic + env: BADGE=linux-mingw + name: linux-mingw + compiler: gcc-9 + addons: + apt: + sources: ["ubuntu-toolchain-r-test"] + packages: + ["gcc-9", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] - ### 32-bit builds on AMD64 ### - - os: linux - dist: bionic - env: BADGE=linux - compiler: gcc-5 - addons: - apt: - sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-5', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: bionic - env: BADGE=linux - compiler: gcc-9 - addons: - apt: - sources: ['ubuntu-toolchain-r-test'] - packages: ['gcc-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: xenial - env: BADGE=linux - compiler: clang-3.7 - addons: - apt: - sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-3.7'] - packages: ['clang-3.7', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: bionic - env: BADGE=linux - compiler: clang-6.0 - addons: - apt: - sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-bionic-6.0'] - packages: ['clang-6.0', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: bionic - env: BADGE=linux - compiler: clang-9 - addons: - apt: - sources: ['ubuntu-toolchain-r-test'] - packages: ['clang-9', 'libusb-1.0.0-dev', 'libgtk-3-dev', 'rpm'] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + ### 32-bit builds on AMD64 ### + - os: linux + dist: bionic + env: BADGE=linux + compiler: gcc-5 + addons: + apt: + sources: ["ubuntu-toolchain-r-test"] + packages: ["gcc-5", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + - os: linux + dist: bionic + env: BADGE=linux + compiler: gcc-9 + addons: + apt: + sources: ["ubuntu-toolchain-r-test"] + packages: ["gcc-9", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + - os: linux + dist: focal + env: BADGE=linux + compiler: gcc-10 + addons: + apt: + sources: ["ubuntu-toolchain-r-test"] + packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + - os: linux + dist: xenial + env: BADGE=linux + compiler: clang-3.7 + addons: + apt: + sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-xenial-3.7"] + packages: ["clang-3.7", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + - os: linux + dist: bionic + env: BADGE=linux + compiler: clang-6.0 + addons: + apt: + sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-bionic-6.0"] + packages: ["clang-6.0", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + - os: linux + dist: bionic + env: BADGE=linux + compiler: clang-9 + addons: + apt: + sources: ["ubuntu-toolchain-r-test"] + packages: ["clang-9", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + before_install: + - os: linux + dist: focal + env: BADGE=linux + compiler: clang-10 + addons: + apt: + sources: ["ubuntu-toolchain-r-test"] + packages: ["clang-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - ### macOS ### - - os: osx - env: BADGE=osx - compiler: gcc - addons: - homebrew: - packages: - - gcc - - libusb - - gtk+3 - - os: osx - env: BADGE=osx - compiler: clang - addons: - homebrew: - packages: - - clang - - libusb - - gtk+3 - - ### Windows ### -# - os: windows -# env: BADGE=windows -# compiler: gcc + ### macOS ### + - os: osx + env: BADGE=osx + compiler: gcc + addons: + homebrew: + packages: + - gcc + - libusb + - gtk+3 + - os: osx + env: BADGE=osx + compiler: clang + addons: + homebrew: + packages: + - clang + - libusb + - gtk+3 script: - git fetch --tags - printenv - cmake --version - if [[ "$TRAVIS_OS_NAME" == "linux" ]] || [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis.sh; fi -# - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then cmd.exe /C 'mingw64-build.bat'; fi From 8429ac078a783ee6d75db6bd8741eba732959c54 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 10 Mar 2021 16:09:10 +0100 Subject: [PATCH 1103/1435] Update and correction for compiling instructions --- doc/compiling.md | 57 ++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/doc/compiling.md b/doc/compiling.md index d8cb62ebb..07193f357 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -108,54 +108,50 @@ or execute (Debian-based systems only): `apt-get install gcc build-essential cma ### Building +#### Installation: + 1. Change into the project source directory: `cd stlink` 2. Run `make clean` -- required by some linux variants. 3. Run `make release` to create the _Release_ target -4. Run `make debug` to create the _Debug_ target (_optional_)
      +4. Run `make install` to full install the package with complete system integration +5. Run `make debug` to create the _Debug_ target (_optional_)
      The debug target is only necessary in order to modify the sources and to run under a debugger. +6. Run `make package`to build a Debian Package. The generated packages can be found in the subdirectory `./build/dist`. -The top level Makefile is just a handy wrapper for: +As an option you may also install to an individual user-defined folder e.g `$HOME` with `make install DESTDIR=$HOME`. -##### MinGW64: -```sh -$ mkdir build && cd build -$ cmake -DCMAKE_BUILD_TYPE=release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw64.cmake -S .. -$ make -``` +#### Removal: -##### MinGW32: +1. Run `make uninstall` to perform a clean uninstall of the package from the system. +2. Run `make clean` to clean the build-folder within the project source and remove all compiled and linked files and libraries. -```sh -$ mkdir build && cd build -$ cmake -DCMAKE_BUILD_TYPE=release -DCMAKE_TOOLCHAIN_FILE=./cmake/linux-mingw32.cmake -S .. -$ make -``` - -As an alternative you may also install -- to a user folder e.g `$HOME` with `cd build/Release && make install DESTDIR=$HOME` -- or system wide with `cd build/Release && sudo make install`. -When installing system-wide, the dynamic library cache needs to be updated with the command `ldconfig`. +### Cross-Building for Windows +Install the following packages from your package repository: -### Build a Debian Package +* `mingw-w64` +* `mingw-w64-common` +* `mingw-w64-i686-dev` +* `mingw-w64-x86-64-dev` -To build the debian package you need the following extra packages: `devscripts debhelper`. +After following the steps for installation above, proceed with from the build dircetory itself: ```sh -$ git archive --prefix=$(git describe)/ HEAD | bzip2 --stdout > ../libstlink_$(sed -En -e "s/.*\((.*)\).*/\1/" -e "1,1 p" debian/changelog).orig.tar.bz2 -$ debuild -uc -us +$ sudo sh ./cmake/packaging/windows/generate_binaries.sh ``` +The generated zip-packages can be found in the subdirectory `./build/dist`. + -### Set permissions with udev +### Set device access permissions and the role of udev By default most distributions don't allow access to USB devices. -Therefore make sure you install udev files which are necessary to run the tools without root permissions.
      -udev rules create devices nodes and set the group of these to `stlink`. +In this context udev rules, which create devices nodes, are necessary to run the tools without root permissions. +To achieve this you need to ensure that the group `plugdev` exists and the user who is trying to access these devices is a member of this group. -The rules are located in the subdirectory `config/udev/rules.d` within the sourcefolder and are automatically installed along with `sudo make install` on linux. +Within the sourcefolder of the project, these rules are located in the subdirectory `config/udev/rules.d` and are automatically installed along with `sudo make install` on linux. Afterwards it may be necessary to reload the udev rules: ```sh @@ -164,13 +160,12 @@ $ sudo udevadm control --reload-rules $ sudo udevadm trigger ``` -Udev will now create device node files `/dev/stlinkv2_XX`, `/dev/stlinkv1_XX`.
      -You need to ensure that the group `stlink` exists and the user who is trying to access these devices is a member of this group. +udev will now create device node files, e.g. `/dev/stlinkv3_XX`, `/dev/stlinkv2_XX`, `/dev/stlinkv1_XX`. -### Note on the use of STLink-v1 programmers (legacy): +### Special note on the use of STLink/V1 programmers (legacy): -As the STLINKv1's SCSI emulation is somehow broken, the best advice possibly is to tell your operating system to completely ignore it.
      +As the STLINKV1's SCSI emulation is somehow broken, the best advice possibly is to tell your operating system to completely ignore it.
      Choose one of the following options _before_ connecting the device to your computer: * `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` From dc6310b469132b2d4210de5fa266571c81df3d82 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 10 Mar 2021 16:45:57 +0100 Subject: [PATCH 1104/1435] Updated travis CI build settings - covered active Ubuntu LTS version trees - gcc: 5 / 6 / 10 - clang: 8 / 10 --- .travis.yml | 51 ++++++++++++++++++--------------------------------- 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/.travis.yml b/.travis.yml index 27fbec5f8..4437b3148 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ jobs: include: ### 64-bit builds on AMD64 ### - os: linux - dist: bionic + dist: xenial env: BADGE=linux compiler: gcc-5 addons: @@ -14,11 +14,11 @@ jobs: - os: linux dist: bionic env: BADGE=linux - compiler: gcc-9 + compiler: gcc-6 addons: apt: sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-9", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + packages: ["gcc-6", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - os: linux dist: focal env: BADGE=linux @@ -30,27 +30,19 @@ jobs: - os: linux dist: xenial env: BADGE=linux - compiler: clang-3.7 + compiler: clang-8 addons: apt: sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-xenial-3.7"] - packages: ["clang-3.7", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - - os: linux - dist: bionic - env: BADGE=linux - compiler: clang-6.0 - addons: - apt: - sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-bionic-6.0"] - packages: ["clang-6.0", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + packages: ["clang-8", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - os: linux dist: bionic env: BADGE=linux - compiler: clang-9 + compiler: clang-10 addons: apt: sources: ["ubuntu-toolchain-r-test"] - packages: ["clang-9", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + packages: ["clang-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - os: linux dist: focal env: BADGE=linux @@ -60,20 +52,21 @@ jobs: sources: ["ubuntu-toolchain-r-test"] packages: ["clang-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + ### cross build on AMD64 ### - os: linux - dist: bionic + dist: focal env: BADGE=linux-mingw name: linux-mingw - compiler: gcc-9 + compiler: gcc-10 addons: apt: sources: ["ubuntu-toolchain-r-test"] packages: - ["gcc-9", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] + ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] ### 32-bit builds on AMD64 ### - os: linux - dist: bionic + dist: xenial env: BADGE=linux compiler: gcc-5 addons: @@ -85,11 +78,11 @@ jobs: - os: linux dist: bionic env: BADGE=linux - compiler: gcc-9 + compiler: gcc-6 addons: apt: sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-9", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + packages: ["gcc-6", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] before_install: - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - os: linux @@ -105,31 +98,23 @@ jobs: - os: linux dist: xenial env: BADGE=linux - compiler: clang-3.7 + compiler: clang-8 addons: apt: sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-xenial-3.7"] - packages: ["clang-3.7", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + packages: ["clang-8", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] before_install: - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - os: linux dist: bionic env: BADGE=linux - compiler: clang-6.0 + compiler: clang-10 addons: apt: sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-bionic-6.0"] - packages: ["clang-6.0", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + packages: ["clang-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] before_install: - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: bionic - env: BADGE=linux - compiler: clang-9 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["clang-9", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] before_install: - os: linux dist: focal From 8f9c5430cbf70192a4b3072b2ba690800cc0d306 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 10 Mar 2021 23:57:10 +0100 Subject: [PATCH 1105/1435] Updated changelog --- CHANGELOG.md | 600 +++++++++++++++++++++++++-------------------------- 1 file changed, 292 insertions(+), 308 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d304ab616..c4adaf2ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,51 +1,49 @@ -stlink ChangeLog -================ +# stlink ChangeLog -v1.6.2 -====== +# v1.6.2 Release date: (TBD) Features: -* Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052)) -* Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) -* Option bytes on the STM32F767 ZIT6 Nucleo-144 ([#968](https://github.com/stlink-org/stlink/pull/968), [#997](https://github.com/stlink-org/stlink/pull/997)) -* Use SetConsoleCtrlHandler for Windows ([#1021](https://github.com/stlink-org/stlink/pull/1021)) -* Increase STM32L0 option_size to 20 ([#1046](https://github.com/stlink-org/stlink/pull/1046)) -* st-util: Add specialized memory map for STM32H7 devices ([#1060](https://github.com/stlink-org/stlink/pull/1060)) -* Support for STM32F4 option bytes ([#1062](https://github.com/stlink-org/stlink/pull/1062)) -* Link for WIN32 & APPLE with stlink-static ([#1069](https://github.com/stlink-org/stlink/pull/1069)) -* Extended support for STM32H7 ([#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) -* ITM functionality for ST-Link V2 and STM32Fxx chipsets ([#136](https://github.com/stlink-org/stlink/pull/136), [#179](https://github.com/stlink-org/stlink/pull/179), [#815](https://github.com/stlink-org/stlink/pull/815), [#1072](https://github.com/stlink-org/stlink/pull/1072)) +- Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052)) +- Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) +- Option bytes on the STM32F767 ZIT6 Nucleo-144 ([#968](https://github.com/stlink-org/stlink/pull/968), [#997](https://github.com/stlink-org/stlink/pull/997)) +- Use SetConsoleCtrlHandler for Windows ([#1021](https://github.com/stlink-org/stlink/pull/1021)) +- Increase STM32L0 `option_size` to 20 ([#1046](https://github.com/stlink-org/stlink/pull/1046)) +- `st-util`: Add specialized memory map for STM32H7 devices ([#1060](https://github.com/stlink-org/stlink/pull/1060)) +- Support for STM32F4 option bytes ([#1062](https://github.com/stlink-org/stlink/pull/1062)) +- Link for WIN32 & APPLE with stlink-static ([#1069](https://github.com/stlink-org/stlink/pull/1069)) +- Extended support for STM32H7 ([#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) +- ITM functionality for STLink/V2 and STM32Fxx chipsets ([#136](https://github.com/stlink-org/stlink/pull/136), [#179](https://github.com/stlink-org/stlink/pull/179), [#815](https://github.com/stlink-org/stlink/pull/815), [#1072](https://github.com/stlink-org/stlink/pull/1072)) Updates & changes: -* [doc] st-flash --reset parameter (one solution for #356) ([#642](https://github.com/stlink-org/stlink/pull/642)) -* [refactoring] General maintenance ([#864](https://github.com/stlink-org/stlink/pull/864), [#976](https://github.com/stlink-org/stlink/pull/976), [#978](https://github.com/stlink-org/stlink/pull/978)) -* Imported debian pkg-settings ([#986](https://github.com/stlink-org/stlink/pull/986)) -* Add support for FreeBSD's libusb reimplementation ([#992](https://github.com/stlink-org/stlink/pull/992), [#993](https://github.com/stlink-org/stlink/pull/993)) -* [doc] Added example for output of 'st-info --probe' ([#1007](https://github.com/stlink-org/stlink/pull/1007), [#1049](https://github.com/stlink-org/stlink/pull/1049)) +- [doc] `st-flash --reset` parameter (one solution for #356) ([#642](https://github.com/stlink-org/stlink/pull/642)) +- [refactoring] General maintenance ([#864](https://github.com/stlink-org/stlink/pull/864), [#976](https://github.com/stlink-org/stlink/pull/976), [#978](https://github.com/stlink-org/stlink/pull/978)) +- Imported debian pkg-settings ([#986](https://github.com/stlink-org/stlink/pull/986)) +- Add support for FreeBSD's `libusb` reimplementation ([#992](https://github.com/stlink-org/stlink/pull/992), [#993](https://github.com/stlink-org/stlink/pull/993)) +- [doc] Added example for output of `st-info --probe` ([#1007](https://github.com/stlink-org/stlink/pull/1007), [#1049](https://github.com/stlink-org/stlink/pull/1049)) Fixes: -* [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) -* cmake compile failure with external CMAKE_MODULE_PATH set ([#962](https://github.com/stlink-org/stlink/pull/962)) -* doc/man: Fixed installation directory ([#970](https://github.com/stlink-org/stlink/pull/970)) -* Fixed installation path for desktop-file and icons ([#972](https://github.com/stlink-org/stlink/pull/972)) -* Fix for static linking of libssp ([#973](https://github.com/stlink-org/stlink/pull/973), [#974](https://github.com/stlink-org/stlink/pull/974)) -* Fixed connect under reset for st-flash and st-util ([#983](https://github.com/stlink-org/stlink/pull/983)) -* Fix for mmap() size_t overflow in st-flash ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) -* [regression] stlink-gui installation issue on Ubuntu-18.04 ([#1001](https://github.com/stlink-org/stlink/pull/1001), [#1004](https://github.com/stlink-org/stlink/pull/1004), [#1006](https://github.com/stlink-org/stlink/pull/1006)) -* st-util: wrong register values passed to gdb (st-link v2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027)) -* [doc] Fixed wrong path for rules.d folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) -* Use vl flashloader for all STM32F1 series ([#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) -* Fixed gettimeofday for MSVC ([#1074](https://github.com/stlink-org/stlink/pull/1074)) -* Fixed compilation with GCC 11 ([#1077](https://github.com/stlink-org/stlink/pull/1077)) - - -v1.6.1 -====== +- [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) +- cmake compile failure with external `CMAKE_MODULE_PATH` set ([#962](https://github.com/stlink-org/stlink/pull/962)) +- doc/man: Fixed installation directory ([#970](https://github.com/stlink-org/stlink/pull/970)) +- Fixed installation path for desktop-file and icons ([#972](https://github.com/stlink-org/stlink/pull/972)) +- Fix for static linking of `libssp` ([#973](https://github.com/stlink-org/stlink/pull/973), [#974](https://github.com/stlink-org/stlink/pull/974)) +- [regression] Fixed wrong formatting for library install path ([#978](https://github.com/stlink-org/stlink/pull/978), [#1089](https://github.com/stlink-org/stlink/pull/1089)) +- Fixed installation of header files needed for compiling with `libstlink.so.1.6.1` ([#982](https://github.com/stlink-org/stlink/pull/982)) +- Fixed `connect under reset` for `st-flash` and `st-util` ([#983](https://github.com/stlink-org/stlink/pull/983)) +- Fix for `mmap() size_t overflow` in `st-flash` ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) +- [regression] `stlink-gui` installation issue on Ubuntu-18.04 ([#1001](https://github.com/stlink-org/stlink/pull/1001), [#1004](https://github.com/stlink-org/stlink/pull/1004), [#1006](https://github.com/stlink-org/stlink/pull/1006)) +- `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027)) +- [doc] Fixed wrong path for `rules.d` folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) +- Use vl flashloader for all STM32F1 series ([#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) +- Fixed `gettimeofday` for MSVC ([#1074](https://github.com/stlink-org/stlink/pull/1074)) +- Fixed compilation with GCC 11 ([#1077](https://github.com/stlink-org/stlink/pull/1077)) + +# v1.6.1 Release date: 2020-06-01 @@ -53,364 +51,350 @@ This release drops support for some older operating systems. Check project READM Features: -* Basic compatibility for STLink-v3 programmer ([#271](https://github.com/stlink-org/stlink/pull/271), [#863](https://github.com/stlink-org/stlink/pull/863), [#954](https://github.com/stlink-org/stlink/pull/954)) +- Basic compatibility for STLink/V3 programmer ([#271](https://github.com/stlink-org/stlink/pull/271), [#863](https://github.com/stlink-org/stlink/pull/863), [#954](https://github.com/stlink-org/stlink/pull/954)) - Added support for JTAG command API v2 & distinguish protocol versions v1 and v2 - - Compatibility with the STLink-v3 firmware which dropped support for the previous API v1 - - As of firmware version J11 the ST-LINK-V1 programmer supports API v2 commands as well -* Display programmer serial when no target is connected ([#432](https://github.com/stlink-org/stlink/pull/432), [#933](https://github.com/stlink-org/stlink/pull/933), [#943](https://github.com/stlink-org/stlink/pull/943)) -* Added connect under reset to stlink_open_usb( ) ([#577](https://github.com/stlink-org/stlink/pull/577), [#963](https://github.com/stlink-org/stlink/pull/963)) -* Support for STM32L1, SM32L4 option bytes write ([#596](https://github.com/stlink-org/stlink/pull/596), [#844](https://github.com/stlink-org/stlink/pull/844), [#847](https://github.com/stlink-org/stlink/pull/847)) -* Added CMAKEFLAGS and install target ([#804](https://github.com/stlink-org/stlink/pull/804), [#935](https://github.com/stlink-org/stlink/pull/935)) -* Support for STM32G4 ([#822](https://github.com/stlink-org/stlink/pull/822)) -* Added aliased SRAM2 region in the L496 memory map ([#824](https://github.com/stlink-org/stlink/pull/824)) -* Improved support for STM32G0 ([#825](https://github.com/stlink-org/stlink/pull/825), [#850](https://github.com/stlink-org/stlink/pull/850), [#856](https://github.com/stlink-org/stlink/pull/856), [#857](https://github.com/stlink-org/stlink/pull/857)) -* Added postinst script with 'depmod -a' for 'make package' ([#845](https://github.com/stlink-org/stlink/pull/845), [#931](https://github.com/stlink-org/stlink/pull/931)) -* Calculate checksums for flash operations ([#862](https://github.com/stlink-org/stlink/pull/862), [#924](https://github.com/stlink-org/stlink/pull/924)) -* Adjust the JTAG/SWD frequency via cmdline option ([#893](https://github.com/stlink-org/stlink/pull/893), [#953](https://github.com/stlink-org/stlink/pull/953)) -* Added usb PID and udev rules for STlink v2.1 found on Nucleo-L432KC and Nucleo-L552ze boards ([#900](https://github.com/stlink-org/stlink/pull/900)) -* STM32G0/G4 improvements ([#910](https://github.com/stlink-org/stlink/pull/910)) + - Compatibility with the STLink/V3 firmware which dropped support for the previous API v1 + - As of firmware version J11 the STLink/V1 programmer supports API v2 commands as well +- Display programmer serial when no target is connected ([#432](https://github.com/stlink-org/stlink/pull/432), [#933](https://github.com/stlink-org/stlink/pull/933), [#943](https://github.com/stlink-org/stlink/pull/943)) +- Added `connect under reset` to `stlink_open_usb( )` ([#577](https://github.com/stlink-org/stlink/pull/577), [#963](https://github.com/stlink-org/stlink/pull/963)) +- Support for STM32L1, SM32L4 option bytes write ([#596](https://github.com/stlink-org/stlink/pull/596), [#844](https://github.com/stlink-org/stlink/pull/844), [#847](https://github.com/stlink-org/stlink/pull/847)) +- Added `CMAKEFLAGS` and install target ([#804](https://github.com/stlink-org/stlink/pull/804), [#935](https://github.com/stlink-org/stlink/pull/935)) +- Support for STM32G4 ([#822](https://github.com/stlink-org/stlink/pull/822)) +- Added aliased SRAM2 region in the L496 memory map ([#824](https://github.com/stlink-org/stlink/pull/824)) +- Improved support for STM32G0 ([#825](https://github.com/stlink-org/stlink/pull/825), [#850](https://github.com/stlink-org/stlink/pull/850), [#856](https://github.com/stlink-org/stlink/pull/856), [#857](https://github.com/stlink-org/stlink/pull/857)) +- Added postinst script with `depmod -a` for `make package` ([#845](https://github.com/stlink-org/stlink/pull/845), [#931](https://github.com/stlink-org/stlink/pull/931)) +- Calculate checksums for flash operations ([#862](https://github.com/stlink-org/stlink/pull/862), [#924](https://github.com/stlink-org/stlink/pull/924)) +- Adjust the JTAG/SWD frequency via cmdline option ([#893](https://github.com/stlink-org/stlink/pull/893), [#953](https://github.com/stlink-org/stlink/pull/953)) +- Added usb PID and udev rules for STLink/V2.1 found on Nucleo-L432KC and Nucleo-L552ze boards ([#900](https://github.com/stlink-org/stlink/pull/900)) +- STM32G0/G4 improvements ([#910](https://github.com/stlink-org/stlink/pull/910)) - Enable mass erase with a flash programming check - Handle G4 Cat3 devices with configurable dual bank flash by using a helper Updates & changes: -* [doc] Updated compiling instructions ([#113](https://github.com/stlink-org/stlink/pull/113), commit [#10ae529](https://github.com/stlink-org/stlink/commit/10ae5294cd03aacfc07312010f026d3cb12ea56c)) -* Defined libusb version compatibility for supported systems via LIBUSB_API_VERSION ([#211](https://github.com/stlink-org/stlink/pull/211), [#782](https://github.com/stlink-org/stlink/pull/782), [#895](https://github.com/stlink-org/stlink/pull/895)) -* Improved argument parsing for CLI tools ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) -* [doc] Updated tutorial: macOS ST-Link-v1 detection ([#574](https://github.com/stlink-org/stlink/pull/574), [#587](https://github.com/stlink-org/stlink/pull/587)) -* Enhanced error log with file path for map_file() ([#650](https://github.com/stlink-org/stlink/pull/650), [#879](https://github.com/stlink-org/stlink/pull/879), [#921](https://github.com/stlink-org/stlink/pull/921)) -* Enhanced output for error msg "addr not a multiple of pagesize, not supported" ([#663](https://github.com/stlink-org/stlink/pull/663), [#945](https://github.com/stlink-org/stlink/pull/945)) -* Updated STLink-v1 driver for macOS ([#735](https://github.com/stlink-org/stlink/pull/735), [#964](https://github.com/stlink-org/stlink/pull/964)) -* Package distribution: Provide Windows binaries via Debian-based cross-build ([#738](https://github.com/stlink-org/stlink/pull/738), [#795](https://github.com/stlink-org/stlink/pull/795), [#798](https://github.com/stlink-org/stlink/pull/798), [#870](https://github.com/stlink-org/stlink/pull/870), [#955](https://github.com/stlink-org/stlink/pull/955)) +- [doc] Updated compiling instructions ([#113](https://github.com/stlink-org/stlink/pull/113), commit [#10ae529](https://github.com/stlink-org/stlink/commit/10ae5294cd03aacfc07312010f026d3cb12ea56c)) +- Defined `libusb` version compatibility for supported systems via `LIBUSB_API_VERSION` ([#211](https://github.com/stlink-org/stlink/pull/211), [#782](https://github.com/stlink-org/stlink/pull/782), [#895](https://github.com/stlink-org/stlink/pull/895)) +- Improved argument parsing for CLI tools ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) +- [doc] Updated tutorial: macOS STLink/V1 detection ([#574](https://github.com/stlink-org/stlink/pull/574), [#587](https://github.com/stlink-org/stlink/pull/587)) +- Enhanced error log with file path for `map_file()` ([#650](https://github.com/stlink-org/stlink/pull/650), [#879](https://github.com/stlink-org/stlink/pull/879), [#921](https://github.com/stlink-org/stlink/pull/921)) +- Enhanced output for error msg `addr not a multiple of pagesize, not supported` ([#663](https://github.com/stlink-org/stlink/pull/663), [#945](https://github.com/stlink-org/stlink/pull/945)) +- Updated STLink/V1 driver for macOS ([#735](https://github.com/stlink-org/stlink/pull/735), [#964](https://github.com/stlink-org/stlink/pull/964)) +- Package distribution: Provide Windows binaries via Debian-based cross-build ([#738](https://github.com/stlink-org/stlink/pull/738), [#795](https://github.com/stlink-org/stlink/pull/795), [#798](https://github.com/stlink-org/stlink/pull/798), [#870](https://github.com/stlink-org/stlink/pull/870), [#955](https://github.com/stlink-org/stlink/pull/955)) - [refactoring] Update, corrections & cleanup for build settings (see #955 for details) - - New cpack package-config for DEB and RPM build - - Update for travis build configuration: builds for clang -m32, clang-9, MinGW-cross on linux + - New `cpack` package-config for DEB and RPM build + - Update for travis build configuration: builds for `clang -m32`, `clang-9`, MinGW-cross on linux - Updated steps for release preparation - Project contributors now listed in separate file - - Test files & gui now use shared stlink-library -* [doc] Verify correct udev configuration for device access ([#764](https://github.com/stlink-org/stlink/pull/764)) -* Added more error info to WLOGs during probe ([#883](https://github.com/stlink-org/stlink/pull/883)) -* [doc] Added missing documentation for stlink-gui ([#884](https://github.com/stlink-org/stlink/pull/884)) -* Added check for libssp during compilation ([#885](https://github.com/stlink-org/stlink/pull/885)) -* Silenced unnecessary messages ([#886](https://github.com/stlink-org/stlink/pull/886)) -* [doc] Defined libusb & cmake version compatibility ([#896](https://github.com/stlink-org/stlink/pull/896), [#897](https://github.com/stlink-org/stlink/pull/897), [#899](https://github.com/stlink-org/stlink/pull/899), commit [#27aa888](https://github.com/stlink-org/stlink/commit/27aa88821197d3ffe82baff4e971c3488ec39899)) -* Update for STM32G471/473/474/483/484 devices ([#901](https://github.com/stlink-org/stlink/pull/901)) -* [doc] st-flash --flash=n[k][m] command line option to override device model ([#902](https://github.com/stlink-org/stlink/pull/902)) -* [refactoring] Improved cmake build process ([#912](https://github.com/stlink-org/stlink/pull/912)) - - Set up a libusb log level accordingly to verbosity ([#894](https://github.com/stlink-org/stlink/pull/894) - - [compatibility] Updated libusb to v1.0.23 ([#895](https://github.com/stlink-org/stlink/pull/895) - - Updated compiling doc & version support ([#896](https://github.com/stlink-org/stlink/pull/896), [#897](https://github.com/stlink-org/stlink/pull/897), [#899](https://github.com/stlink-org/stlink/pull/899)) + - Test files & gui now use shared `stlink-library` +- [doc] Verify correct udev configuration for device access ([#764](https://github.com/stlink-org/stlink/pull/764)) +- Added more error info to `WLOGs` during probe ([#883](https://github.com/stlink-org/stlink/pull/883)) +- [doc] Added missing documentation for stlink-gui ([#884](https://github.com/stlink-org/stlink/pull/884)) +- Added check for `libssp` during compilation ([#885](https://github.com/stlink-org/stlink/pull/885)) +- Silenced unnecessary messages ([#886](https://github.com/stlink-org/stlink/pull/886)) +- [doc] Defined `libusb` & `cmake` version compatibility ([#896](https://github.com/stlink-org/stlink/pull/896), [#897](https://github.com/stlink-org/stlink/pull/897), [#899](https://github.com/stlink-org/stlink/pull/899), commit [#27aa888](https://github.com/stlink-org/stlink/commit/27aa88821197d3ffe82baff4e971c3488ec39899)) +- Update for STM32G471/473/474/483/484 devices ([#901](https://github.com/stlink-org/stlink/pull/901)) +- [doc] `st-flash --flash=n[k][m]` command line option to override device model ([#902](https://github.com/stlink-org/stlink/pull/902)) +- [refactoring] Improved cmake build process ([#912](https://github.com/stlink-org/stlink/pull/912)) + - Set up a `libusb` log level accordingly to verbosity ([#894](https://github.com/stlink-org/stlink/pull/894) + - [compatibility] Updated `libusb` to v1.0.23 ([#895](https://github.com/stlink-org/stlink/pull/895, [#1089](https://github.com/stlink-org/stlink/pull/1089)) + - Updated compiling doc & version support ([#896](https://github.com/stlink-org/stlink/pull/896), [#897](https://github.com/stlink-org/stlink/pull/897), [#899](https://github.com/stlink-org/stlink/pull/899)) - Version requirements & pkg-maintainer - Fixed install paths in build script - - Updated C-flag -std=gnu99 to gnu11) - - Added cmake uninstall target ([#619](https://github.com/stlink-org/stlink/pull/619), [#907](https://github.com/stlink-org/stlink/pull/907)) - - Integrated module GNUInstallDirs.cmake ([#557](https://github.com/stlink-org/stlink/pull/557)) + - Updated C-flag `-std=gnu99` to `gnu11`) + - Added `cmake` uninstall target ([#619](https://github.com/stlink-org/stlink/pull/619), [#907](https://github.com/stlink-org/stlink/pull/907)) + - Integrated module `GNUInstallDirs.cmake` ([#557](https://github.com/stlink-org/stlink/pull/557)) - [doc] Defined version compatibility and installation instructions for macOS - - [refactoring] libusb detection - - Deprecated old appveyor-mingw script -* [refactoring] BSD-License-compliant rewrite of flashloader source files ([#915](https://github.com/stlink-org/stlink/pull/915), [#932](https://github.com/stlink-org/stlink/pull/932)) -* [refactoring] Overall option code rework ([#927](https://github.com/stlink-org/stlink/pull/927)) -* [refactoring] Build settings / GUI-Build on UNIX-based systems if GTK3 is detected ([#929](https://github.com/stlink-org/stlink/pull/929)) -* [refactoring] Reconfiguration of package build process ([#931](https://github.com/stlink-org/stlink/pull/931), [#936](https://github.com/stlink-org/stlink/pull/936), [#940](https://github.com/stlink-org/stlink/pull/940), commit [#9b19f92](https://github.com/stlink-org/stlink/commit/9b19f9225460472af9d98959b7217d0a840ee972)) -* [refactoring] st-util: Removed now useless v1/v2 STLink version stuff ([#934](https://github.com/stlink-org/stlink/pull/934)) -* [refactoring] Cleanup for option bytes and flash settings ([#941](https://github.com/stlink-org/stlink/pull/941)) -* Added compilation guideline for MSVC toolchain ([#942](https://github.com/stlink-org/stlink/pull/942)) -* [refactoring] Cleanup of cmake build process ([#944](https://github.com/stlink-org/stlink/pull/944), [#946](https://github.com/stlink-org/stlink/pull/946), [#947](https://github.com/stlink-org/stlink/pull/947)) - - libusb package extraction no longer requires 7zip as an external unarchiver + - [refactoring] `libusb` detection + - Deprecated old `appveyor-mingw` script +- [refactoring] BSD-License-compliant rewrite of flashloader source files ([#915](https://github.com/stlink-org/stlink/pull/915), [#932](https://github.com/stlink-org/stlink/pull/932)) +- [refactoring] Overall option code rework ([#927](https://github.com/stlink-org/stlink/pull/927)) +- [refactoring] Build settings / GUI-Build on UNIX-based systems if `GTK3` is detected ([#929](https://github.com/stlink-org/stlink/pull/929)) +- [refactoring] Reconfiguration of package build process ([#931](https://github.com/stlink-org/stlink/pull/931), [#936](https://github.com/stlink-org/stlink/pull/936), [#940](https://github.com/stlink-org/stlink/pull/940), commit [#9b19f92](https://github.com/stlink-org/stlink/commit/9b19f9225460472af9d98959b7217d0a840ee972)) +- [refactoring] `st-util`: Removed now useless v1/v2 STLink version stuff ([#934](https://github.com/stlink-org/stlink/pull/934)) +- [refactoring] Cleanup for option bytes and flash settings ([#941](https://github.com/stlink-org/stlink/pull/941)) +- Added compilation guideline for MSVC toolchain ([#942](https://github.com/stlink-org/stlink/pull/942)) +- [refactoring] Cleanup of `cmake` build process ([#944](https://github.com/stlink-org/stlink/pull/944), [#946](https://github.com/stlink-org/stlink/pull/946), [#947](https://github.com/stlink-org/stlink/pull/947)) + - `libusb` package extraction no longer requires `7zip` as an external unarchiver Fixes: -* Fixed wait-loop for flash_loader_run() ([#290](https://github.com/stlink-org/stlink/pull/290)) -* Better argument parsing for CLI tools: stlink_open_usb can address v1, v2, v3 ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) -* Clear the PG bit before setting the PER bit ([#579](https://github.com/stlink-org/stlink/pull/579), [#876](https://github.com/stlink-org/stlink/pull/876)) -* Fixed compilation issues with int length on 32-bit platforms ([#629](https://github.com/stlink-org/stlink/pull/629), [#908](https://github.com/stlink-org/stlink/pull/908)) -* Fixed st-info --probe mechanism ([#679](https://github.com/stlink-org/stlink/pull/679), [#918](https://github.com/stlink-org/stlink/pull/918)) -* [regression] Fixed sign-compare (size != rep_len) in usb.c ([#772](https://github.com/stlink-org/stlink/pull/772), [#869](https://github.com/stlink-org/stlink/pull/869), [#872](https://github.com/stlink-org/stlink/pull/872), [#891](https://github.com/stlink-org/stlink/pull/891)) -* Fixed dead loop after an unexpected unplug ([#780](https://github.com/stlink-org/stlink/pull/780), [#812](https://github.com/stlink-org/stlink/pull/812), [#913](https://github.com/stlink-org/stlink/pull/913)) -* Avoid re-define of O_BINARY on Windows ([#788](https://github.com/stlink-org/stlink/pull/788)) -* Fixed stlink lock-up when not connected to a device via JTAG / SWD ([#835](https://github.com/stlink-org/stlink/pull/835), [#943](https://github.com/stlink-org/stlink/pull/943)) -* Fixed st-flash manpage read example ([#858](https://github.com/stlink-org/stlink/pull/858)) -* Fixed stlink support with no mass storage ([#861](https://github.com/stlink-org/stlink/pull/861)) -* Make Version.cmake more error-resistant ([#872](https://github.com/stlink-org/stlink/pull/872)) -* Error return in failed probe ([#887](https://github.com/stlink-org/stlink/pull/887), [#890](https://github.com/stlink-org/stlink/pull/890)) -* Fixed broken build on 32-bit systems ([#919](https://github.com/stlink-org/stlink/pull/919), [#920](https://github.com/stlink-org/stlink/pull/920)) -* st-flash: Minor usage fix and make cmdline parsing more user friendly ([#925](https://github.com/stlink-org/stlink/pull/925)) -* [regression] Restored functionality of make test builds ([#926](https://github.com/stlink-org/stlink/pull/926), [#929](https://github.com/stlink-org/stlink/pull/929)) -* Fixed compilation error due to uninitialized cpuid ([#937](https://github.com/stlink-org/stlink/pull/937), [#938](https://github.com/stlink-org/stlink/pull/938)) -* Fixes for STM32F0 flashloader ([#958](https://github.com/stlink-org/stlink/pull/958), [#959](https://github.com/stlink-org/stlink/pull/959)) -* Set static link for libssp (stack-smashing protection) ([#960](https://github.com/stlink-org/stlink/pull/960), [#961](https://github.com/stlink-org/stlink/pull/961)) -* Fixed udev rules installing to wrong directory ([#966](https://github.com/stlink-org/stlink/pull/966)) -* Fixed formatting for options display in st-flash & st-info (commits [#c783d0e](https://github.com/stlink-org/stlink/commit/c783d0e777ccc83a7a8be26a4f4d3414e0478560) and [#562cd24](https://github.com/stlink-org/stlink/commit/562cd2496e696dbd22950925866aac662d81ee5f)) - - -v1.6.0 -====== +- Fixed wait-loop for `flash_loader_run()` ([#290](https://github.com/stlink-org/stlink/pull/290)) +- Better argument parsing for CLI tools: `stlink_open_usb` can address v1, v2, v3 ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) +- Clear the PG bit before setting the `PER` bit ([#579](https://github.com/stlink-org/stlink/pull/579), [#876](https://github.com/stlink-org/stlink/pull/876)) +- Fixed compilation issues with int length on 32-bit platforms ([#629](https://github.com/stlink-org/stlink/pull/629), [#908](https://github.com/stlink-org/stlink/pull/908)) +- Fixed `st-info --probe` mechanism ([#679](https://github.com/stlink-org/stlink/pull/679), [#918](https://github.com/stlink-org/stlink/pull/918)) +- [regression] Fixed sign-compare (`size != rep_len`) in `usb.c` ([#772](https://github.com/stlink-org/stlink/pull/772), [#869](https://github.com/stlink-org/stlink/pull/869), [#872](https://github.com/stlink-org/stlink/pull/872), [#891](https://github.com/stlink-org/stlink/pull/891)) +- Fixed dead loop after an unexpected unplug ([#780](https://github.com/stlink-org/stlink/pull/780), [#812](https://github.com/stlink-org/stlink/pull/812), [#913](https://github.com/stlink-org/stlink/pull/913)) +- Avoid re-define of `O_BINARY` on Windows ([#788](https://github.com/stlink-org/stlink/pull/788)) +- Fixed stlink lock-up when not connected to a device via JTAG / SWD ([#835](https://github.com/stlink-org/stlink/pull/835), [#943](https://github.com/stlink-org/stlink/pull/943)) +- Fixed `st-flash` manpage read example ([#858](https://github.com/stlink-org/stlink/pull/858)) +- Fixed stlink support with no mass storage ([#861](https://github.com/stlink-org/stlink/pull/861)) +- Make `version.cmake` more error-resistant ([#872](https://github.com/stlink-org/stlink/pull/872)) +- Error return in failed probe ([#887](https://github.com/stlink-org/stlink/pull/887), [#890](https://github.com/stlink-org/stlink/pull/890)) +- Fixed broken build on 32-bit systems ([#919](https://github.com/stlink-org/stlink/pull/919), [#920](https://github.com/stlink-org/stlink/pull/920)) +- `st-flash`: Minor usage fix and make cmdline parsing more user friendly ([#925](https://github.com/stlink-org/stlink/pull/925)) +- [regression] Restored functionality of make test builds ([#926](https://github.com/stlink-org/stlink/pull/926), [#929](https://github.com/stlink-org/stlink/pull/929)) +- Fixed compilation error due to uninitialized cpuid ([#937](https://github.com/stlink-org/stlink/pull/937), [#938](https://github.com/stlink-org/stlink/pull/938)) +- Fixes for STM32F0 flashloader ([#958](https://github.com/stlink-org/stlink/pull/958), [#959](https://github.com/stlink-org/stlink/pull/959)) +- Set static link for `libssp` (stack-smashing protection) ([#960](https://github.com/stlink-org/stlink/pull/960), [#961](https://github.com/stlink-org/stlink/pull/961)) +- Fixed udev rules installing to wrong directory ([#966](https://github.com/stlink-org/stlink/pull/966)) +- Fixed formatting for options display in `st-flash` & `st-info` (commits [#c783d0e](https://github.com/stlink-org/stlink/commit/c783d0e777ccc83a7a8be26a4f4d3414e0478560) and [#562cd24](https://github.com/stlink-org/stlink/commit/562cd2496e696dbd22950925866aac662d81ee5f)) + +# v1.6.0 Release date: 2020-02-20 Major changes and added features: -* Initial support for STM32L41X ([#754](https://github.com/stlink-org/stlink/pull/754), [#799](https://github.com/stlink-org/stlink/pull/799)) -* Verified support for CKS32F103C8T6 and related CKS devices with Core-ID 0x2ba01477 ([#756](https://github.com/stlink-org/stlink/pull/756), [#757](https://github.com/stlink-org/stlink/pull/757), [#805](https://github.com/stlink-org/stlink/pull/805), [#834](https://github.com/stlink-org/stlink/pull/834), Regression-Fixes: [#761](https://github.com/stlink-org/stlink/pull/761), [#766](https://github.com/stlink-org/stlink/pull/766)) -* Added preliminary support for some STM32G0 chips ([#759](https://github.com/stlink-org/stlink/pull/759), [#760](https://github.com/stlink-org/stlink/pull/760), [#797](https://github.com/stlink-org/stlink/pull/797)) -* Added support for mass erasing second bank on STM32F10x_XL ([#767](https://github.com/stlink-org/stlink/pull/767), [#768](https://github.com/stlink-org/stlink/pull/768)) -* Added call to clear PG bit after writing to flash ([#773](https://github.com/stlink-org/stlink/pull/773)) -* Added support to write option bytes for the STM32G0 ([#778](https://github.com/stlink-org/stlink/pull/778)) -* Added support for STM32WB55 chips ([#786](https://github.com/stlink-org/stlink/pull/786), [#810](https://github.com/stlink-org/stlink/pull/810), [#816](https://github.com/stlink-org/stlink/pull/816)) -* Added STLink V3SET VID:PIDs to the udev rules ([#789](https://github.com/stlink-org/stlink/pull/789)) -* Support for "STM32+Audio" v2-1 firmware ([#790](https://github.com/stlink-org/stlink/pull/790)) -* Build for Windows under Debian/Ubuntu ([#802](https://github.com/stlink-org/stlink/pull/802)) -* Allow for 64 bytes serials ([#809](https://github.com/stlink-org/stlink/pull/809)) -* Added full support for STLINK CHIP ID L4RX ([#814](https://github.com/stlink-org/stlink/pull/814), [#839](https://github.com/stlink-org/stlink/pull/839)) -* Added support for the STLink-v2.1 when flashed with no mass storage (PID 0x3752) ([#819](https://github.com/stlink-org/stlink/pull/819), [#861](https://github.com/stlink-org/stlink/pull/861)) -* Added support for writing option bytes on STM32L0xx ([#830](https://github.com/stlink-org/stlink/pull/830)) -* Added support to read and write option bytes for STM32F2 series ([#836](https://github.com/stlink-org/stlink/pull/836), [#837](https://github.com/stlink-org/stlink/pull/837)) -* Added support to read and write option bytes for STM32F446 ([#843](https://github.com/stlink-org/stlink/pull/843)) +- Initial support for STM32L41X ([#754](https://github.com/stlink-org/stlink/pull/754), [#799](https://github.com/stlink-org/stlink/pull/799)) +- Verified support for CKS32F103C8T6 and related CKS devices with Core-ID 0x2ba01477 ([#756](https://github.com/stlink-org/stlink/pull/756), [#757](https://github.com/stlink-org/stlink/pull/757), [#805](https://github.com/stlink-org/stlink/pull/805), [#834](https://github.com/stlink-org/stlink/pull/834), Regression-Fixes: [#761](https://github.com/stlink-org/stlink/pull/761), [#766](https://github.com/stlink-org/stlink/pull/766)) +- Added preliminary support for some STM32G0 chips ([#759](https://github.com/stlink-org/stlink/pull/759), [#760](https://github.com/stlink-org/stlink/pull/760), [#797](https://github.com/stlink-org/stlink/pull/797)) +- Added support for mass erasing second bank on `STM32F10x_XL` ([#767](https://github.com/stlink-org/stlink/pull/767), [#768](https://github.com/stlink-org/stlink/pull/768)) +- Added call to clear `PG` bit after writing to flash ([#773](https://github.com/stlink-org/stlink/pull/773)) +- Added support to write option bytes for the STM32G0 ([#778](https://github.com/stlink-org/stlink/pull/778)) +- Added support for STM32WB55 chips ([#786](https://github.com/stlink-org/stlink/pull/786), [#810](https://github.com/stlink-org/stlink/pull/810), [#816](https://github.com/stlink-org/stlink/pull/816)) +- Added `STLink V3SET` VID:PIDs to the udev rules ([#789](https://github.com/stlink-org/stlink/pull/789)) +- Support for `STM32+Audio` v2-1 firmware ([#790](https://github.com/stlink-org/stlink/pull/790)) +- Build for Windows under Debian/Ubuntu ([#802](https://github.com/stlink-org/stlink/pull/802)) +- Allow for 64 bytes serials ([#809](https://github.com/stlink-org/stlink/pull/809)) +- Added full support for STLINK CHIP ID L4RX ([#814](https://github.com/stlink-org/stlink/pull/814), [#839](https://github.com/stlink-org/stlink/pull/839)) +- Added support for the STLink/V2.1 when flashed with no mass storage (PID 0x3752) ([#819](https://github.com/stlink-org/stlink/pull/819), [#861](https://github.com/stlink-org/stlink/pull/861)) +- Added support for writing option bytes on STM32L0xx ([#830](https://github.com/stlink-org/stlink/pull/830)) +- Added support to read and write option bytes for STM32F2 series ([#836](https://github.com/stlink-org/stlink/pull/836), [#837](https://github.com/stlink-org/stlink/pull/837)) +- Added support to read and write option bytes for STM32F446 ([#843](https://github.com/stlink-org/stlink/pull/843)) Updates and fixes: -* Fixed "unkown chip id", piped output and st-util -v ([#107](https://github.com/stlink-org/stlink/pull/107), [#665](https://github.com/stlink-org/stlink/pull/665), [#763](https://github.com/stlink-org/stlink/pull/763)) -* Fixed an issue with versioning stuck at 1.4.0 for versions cloned with git ([#563](https://github.com/stlink-org/stlink/pull/563), [#762](https://github.com/stlink-org/stlink/pull/762), [#772](https://github.com/stlink-org/stlink/pull/772)) -* Updated STM32F3xx chip ID that covers a few different devices ([#685](https://github.com/stlink-org/stlink/pull/685), [#758](https://github.com/stlink-org/stlink/pull/758)) -* Made udev rules and modprobe conf installation optional ([#741](https://github.com/stlink-org/stlink/pull/741)) -* Fixed case when __FILE__ don't contain "/" nor "\\" ([#745](https://github.com/stlink-org/stlink/pull/745)) -* Fixed double dash issue in doc/man ([#746](https://github.com/stlink-org/stlink/pull/746), [#747](https://github.com/stlink-org/stlink/pull/747)) -* Compiling documentation: package is called libusb-1.0-0-dev on Debian ([#748](https://github.com/stlink-org/stlink/pull/748)) -* Only do bank calculation on STM32L4 devices with dual banked flash / Added chip-ID 0x464 for STM32L41xxx/L42xxx devices ([#751](https://github.com/stlink-org/stlink/pull/751)) -* Added O_BINARY option to open file ([#753](https://github.com/stlink-org/stlink/pull/753)) -* Fixed versioning when compiling from the checked out git-repo ([#762](https://github.com/stlink-org/stlink/pull/762), [#772](https://github.com/stlink-org/stlink/pull/772)) -* win32: move usleep definition to unistd.h ([#765](https://github.com/stlink-org/stlink/pull/765)) -* Fixed relative path to the UI files needed by stlink-gui-local (GUI) ([#770](https://github.com/stlink-org/stlink/pull/770), [#771](https://github.com/stlink-org/stlink/pull/771)) -* Added howto for sending NRST signal through GDB ([#774](https://github.com/stlink-org/stlink/pull/774), [#776](https://github.com/stlink-org/stlink/pull/776), [#779](https://github.com/stlink-org/stlink/pull/779)) -* Fixed package name "devscripts" in doc/compiling.md ([#775](https://github.com/stlink-org/stlink/pull/775)) -* Fixed few potential memory/resource leaks ([#803](https://github.com/stlink-org/stlink/pull/803), [#831](https://github.com/stlink-org/stlink/pull/831)) -* Updated Linux source repositories in README.md: Debian and Ubuntu ([#821](https://github.com/stlink-org/stlink/pull/821), [#835](https://github.com/stlink-org/stlink/pull/835), [#859](https://github.com/stlink-org/stlink/pull/859)) -* Do not issue JTAG reset on stlink-v1 ([#828](https://github.com/stlink-org/stlink/pull/828)) -* Fixed flash size of STM32 Discovery vl ([#829](https://github.com/stlink-org/stlink/pull/829)) -* Updated documentation on software structure ([#851](https://github.com/stlink-org/stlink/pull/851)) +- Fixed `unkown chip id`, piped output and `st-util -v` ([#107](https://github.com/stlink-org/stlink/pull/107), [#665](https://github.com/stlink-org/stlink/pull/665), [#763](https://github.com/stlink-org/stlink/pull/763)) +- Fixed an issue with versioning stuck at 1.4.0 for versions cloned with git ([#563](https://github.com/stlink-org/stlink/pull/563), [#762](https://github.com/stlink-org/stlink/pull/762), [#772](https://github.com/stlink-org/stlink/pull/772)) +- Updated STM32F3xx chip ID that covers a few different devices ([#685](https://github.com/stlink-org/stlink/pull/685), [#758](https://github.com/stlink-org/stlink/pull/758)) +- Made udev rules and modprobe conf installation optional ([#741](https://github.com/stlink-org/stlink/pull/741)) +- Fixed case when `__FILE__` doesn't contain either `/` nor `\\` ([#745](https://github.com/stlink-org/stlink/pull/745)) +- Fixed double dash issue in doc/man ([#746](https://github.com/stlink-org/stlink/pull/746), [#747](https://github.com/stlink-org/stlink/pull/747)) +- Compiling documentation: package is called `libusb-1.0-0-dev` on Debian ([#748](https://github.com/stlink-org/stlink/pull/748)) +- Only do bank calculation on STM32L4 devices with dual banked flash / Added chip-ID 0x464 for STM32L41xxx/L42xxx devices ([#751](https://github.com/stlink-org/stlink/pull/751)) +- Added `O_BINARY` option to open file ([#753](https://github.com/stlink-org/stlink/pull/753)) +- Fixed versioning when compiling from the checked out git-repo ([#762](https://github.com/stlink-org/stlink/pull/762), [#772](https://github.com/stlink-org/stlink/pull/772)) +- win32: move usleep definition to `unistd.h` ([#765](https://github.com/stlink-org/stlink/pull/765)) +- Fixed relative path to the UI files needed by `stlink-gui-local` (GUI) ([#770](https://github.com/stlink-org/stlink/pull/770), [#771](https://github.com/stlink-org/stlink/pull/771)) +- Added howto for sending `NRST` signal through GDB ([#774](https://github.com/stlink-org/stlink/pull/774), [#776](https://github.com/stlink-org/stlink/pull/776), [#779](https://github.com/stlink-org/stlink/pull/779)) +- Fixed package name `devscripts` in doc/compiling.md ([#775](https://github.com/stlink-org/stlink/pull/775)) +- Fixed few potential memory/resource leaks ([#803](https://github.com/stlink-org/stlink/pull/803), [#831](https://github.com/stlink-org/stlink/pull/831)) +- Updated Linux source repositories in README.md: Debian and Ubuntu ([#821](https://github.com/stlink-org/stlink/pull/821), [#835](https://github.com/stlink-org/stlink/pull/835), [#859](https://github.com/stlink-org/stlink/pull/859)) +- Do not issue JTAG reset on STLink/V1 ([#828](https://github.com/stlink-org/stlink/pull/828)) +- Fixed flash size of STM32 Discovery VL ([#829](https://github.com/stlink-org/stlink/pull/829)) +- Updated documentation on software structure ([#851](https://github.com/stlink-org/stlink/pull/851)) General project updates: -* Updated README.md, CHANGELOG.md and issue templates (Nightwalker-87) -* Fixed travis build config file (Nightwalker-87) -* Added CODE_OF_CONDUCT (Nightwalker-87) -* Archived page from github project wiki to doc/wiki_old.md (Nightwalker-87) +- Updated `README.md`, `CHANGELOG.md` and issue templates (Nightwalker-87) +- Fixed travis build config file (Nightwalker-87) +- Added `CODE_OF_CONDUCT` (Nightwalker-87) +- Archived page from github project wiki to doc/wiki_old.md (Nightwalker-87) - -v1.5.1 -====== +# v1.5.1 Release date: 2018-09-13 Major changes and added features: -* Added reset through AIRCR ([#540](https://github.com/stlink-org/stlink/pull/540), [#712](https://github.com/stlink-org/stlink/pull/712)) -* Added creation of icons for .desktop file ([#684](https://github.com/stlink-org/stlink/pull/684), [#708](https://github.com/stlink-org/stlink/pull/708)) -* Added desktop file for linux ([#688](https://github.com/stlink-org/stlink/pull/688)) -* Added button to export STM32 flash memory to a file ([#691](https://github.com/stlink-org/stlink/pull/691)) -* Updated libusb to 1.0.22 ([#695](https://github.com/stlink-org/stlink/pull/695)) - (related Bugs: [#438](https://github.com/stlink-org/stlink/pull/438), [#632](https://github.com/stlink-org/stlink/pull/632)) -* Added icons for STLink GUI ([#697](https://github.com/stlink-org/stlink/pull/697)) -* Added support for STM32L4R9 target ([#694](https://github.com/stlink-org/stlink/pull/694), [#699](https://github.com/stlink-org/stlink/pull/699)) -* Added memory map for STM32F411RE target ([#709](https://github.com/stlink-org/stlink/pull/709)) -* Implemented intel hex support for GTK GUI ([#713](https://github.com/stlink-org/stlink/pull/713), [#718](https://github.com/stlink-org/stlink/pull/718)) +- Added reset through `AIRCR` ([#540](https://github.com/stlink-org/stlink/pull/540), [#712](https://github.com/stlink-org/stlink/pull/712)) +- Added creation of icons for `.desktop` file ([#684](https://github.com/stlink-org/stlink/pull/684), [#708](https://github.com/stlink-org/stlink/pull/708)) +- Added desktop file for linux ([#688](https://github.com/stlink-org/stlink/pull/688)) +- Added button to export STM32 flash memory to a file ([#691](https://github.com/stlink-org/stlink/pull/691)) +- Updated `libusb` to 1.0.22 ([#695](https://github.com/stlink-org/stlink/pull/695)) - (related Bugs: [#438](https://github.com/stlink-org/stlink/pull/438), [#632](https://github.com/stlink-org/stlink/pull/632)) +- Added icons for stlink GUI ([#697](https://github.com/stlink-org/stlink/pull/697)) +- Added support for STM32L4R9 target ([#694](https://github.com/stlink-org/stlink/pull/694), [#699](https://github.com/stlink-org/stlink/pull/699)) +- Added memory map for STM32F411RE target ([#709](https://github.com/stlink-org/stlink/pull/709)) +- Implemented intel hex support for `GTK` GUI ([#713](https://github.com/stlink-org/stlink/pull/713), [#718](https://github.com/stlink-org/stlink/pull/718)) Updates and fixes: -* Fixed missing flash_loader for STM32L0x ([#269](https://github.com/stlink-org/stlink/pull/269), [#274](https://github.com/stlink-org/stlink/pull/274), [#654](https://github.com/stlink-org/stlink/pull/654), [#675](https://github.com/stlink-org/stlink/pull/675)) -* Fix for stlink library calls exit() or _exit() ([#634](https://github.com/stlink-org/stlink/pull/634), [#696](https://github.com/stlink-org/stlink/pull/696)) -* Added semihosting parameter documentation in doc/man ([#674](https://github.com/stlink-org/stlink/pull/674)) -* Fixed reference to non-exisiting st-term tool in doc/man ([#676](https://github.com/stlink-org/stlink/pull/676)) -* Fixed serial number size mismatch with stlink_open_usb() ([#680](https://github.com/stlink-org/stlink/pull/680)) -* Debian packaging, CMake and README.md fixes ([#682](https://github.com/stlink-org/stlink/pull/682), [#683](https://github.com/stlink-org/stlink/pull/683)) -* Disabled static library installation by default ([#702](https://github.com/stlink-org/stlink/pull/702)) -* Fix for libusb deprecation ([#703](https://github.com/stlink-org/stlink/pull/703), [#704](https://github.com/stlink-org/stlink/pull/704)) -* Renamed STLINK_CHIPID_STM32_L4R9 to STLINK_CHIPID_STM32_L4RX ([#706](https://github.com/stlink-org/stlink/pull/706)) -* [regression] stlink installation under Linux (Debian 9) is broken since #695 ([#700](https://github.com/stlink-org/stlink/pull/700), [#701](https://github.com/stlink-org/stlink/pull/701), [#707](https://github.com/stlink-org/stlink/pull/707)) -* Fixed flash memory map for STM32F72xxx target ([#711](https://github.com/stlink-org/stlink/pull/711)) -* Proper flash page size calculation for STM32F412xx target ([#721](https://github.com/stlink-org/stlink/pull/721)) -* Return correct value on EOF for Semihosting SYS_READ ([#726](https://github.com/stlink-org/stlink/pull/726), [#727](https://github.com/stlink-org/stlink/pull/727), [#728](https://github.com/stlink-org/stlink/pull/728), [#729](https://github.com/stlink-org/stlink/pull/729), [#730](https://github.com/stlink-org/stlink/pull/730), [#731](https://github.com/stlink-org/stlink/pull/731), [#732](https://github.com/stlink-org/stlink/pull/732)) -* FreeBSD defines LIBUSB_API_VERSION instead of LIBUSBX_API_VERSION ([#733](https://github.com/stlink-org/stlink/pull/733)) - - -v1.5.0 -====== +- Fixed missing flash_loader for STM32L0x ([#269](https://github.com/stlink-org/stlink/pull/269), [#274](https://github.com/stlink-org/stlink/pull/274), [#654](https://github.com/stlink-org/stlink/pull/654), [#675](https://github.com/stlink-org/stlink/pull/675)) +- Fix for stlink library calls `exit()` or `_exit()` ([#634](https://github.com/stlink-org/stlink/pull/634), [#696](https://github.com/stlink-org/stlink/pull/696)) +- Added semihosting parameter documentation in doc/man ([#674](https://github.com/stlink-org/stlink/pull/674)) +- Fixed reference to non-exisiting `st-term` tool in doc/man ([#676](https://github.com/stlink-org/stlink/pull/676)) +- Fixed serial number size mismatch with `stlink_open_usb()` ([#680](https://github.com/stlink-org/stlink/pull/680)) +- Debian packaging, `cmake` and `README.md` fixes ([#682](https://github.com/stlink-org/stlink/pull/682), [#683](https://github.com/stlink-org/stlink/pull/683)) +- Disabled static library installation by default ([#702](https://github.com/stlink-org/stlink/pull/702)) +- Fix for `libusb` deprecation ([#703](https://github.com/stlink-org/stlink/pull/703), [#704](https://github.com/stlink-org/stlink/pull/704)) +- Renamed `STLINK_CHIPID_STM32_L4R9` to `STLINK_CHIPID_STM32_L4RX` ([#706](https://github.com/stlink-org/stlink/pull/706)) +- [regression] stlink installation under Linux (Debian 9) is broken since #695 ([#700](https://github.com/stlink-org/stlink/pull/700), [#701](https://github.com/stlink-org/stlink/pull/701), [#707](https://github.com/stlink-org/stlink/pull/707)) +- Fixed flash memory map for STM32F72xxx target ([#711](https://github.com/stlink-org/stlink/pull/711)) +- Proper flash page size calculation for STM32F412xx target ([#721](https://github.com/stlink-org/stlink/pull/721)) +- Return correct value on `EOF` for semihosting `SYS_READ` ([#726](https://github.com/stlink-org/stlink/pull/726), [#727](https://github.com/stlink-org/stlink/pull/727), [#728](https://github.com/stlink-org/stlink/pull/728), [#729](https://github.com/stlink-org/stlink/pull/729), [#730](https://github.com/stlink-org/stlink/pull/730), [#731](https://github.com/stlink-org/stlink/pull/731), [#732](https://github.com/stlink-org/stlink/pull/732)) +- FreeBSD defines `LIBUSB_API_VERSION` instead of `LIBUSBX_API_VERSION` ([#733](https://github.com/stlink-org/stlink/pull/733)) + +# v1.5.0 Release date: 2018-02-16 Major changes and added features: -* Added support of STM32L496xx/4A6xx devices ([#615](https://github.com/stlink-org/stlink/pull/615), [#657](https://github.com/stlink-org/stlink/pull/657)) -* Added unknown chip dummy to obtain the serial of the ST-link by a call to st-info --probe ([#641](https://github.com/stlink-org/stlink/pull/641)) -* Added support for STM32F72xx (chip-ID: 0x452) devices (commit [#1969148](https://github.com/stlink-org/stlink/commit/19691485359afef1a256964afcbb8dcf4b733209)) +- Added support of STM32L496xx/4A6xx devices ([#615](https://github.com/stlink-org/stlink/pull/615), [#657](https://github.com/stlink-org/stlink/pull/657)) +- Added unknown chip dummy to obtain the serial of the STlink by a call to `st-info --probe` ([#641](https://github.com/stlink-org/stlink/pull/641)) +- Added support for STM32F72xx (chip-ID: 0x452) devices (commit [#1969148](https://github.com/stlink-org/stlink/commit/19691485359afef1a256964afcbb8dcf4b733209)) Updates and fixes: -* Fixed verification of flash error for STM32L496x device ([#617](https://github.com/stlink-org/stlink/pull/617), [#618](https://github.com/stlink-org/stlink/pull/618)) -* Updated Linux source repositories in README.md: Gentoo, Fedora and RedHat/CentOS ([#622](https://github.com/stlink-org/stlink/pull/622), [#635](https://github.com/stlink-org/stlink/pull/635)) -* Updated changelog in debian package ([#630](https://github.com/stlink-org/stlink/pull/630)) -* Added LIB_INSTALL_DIR to correct libs install on 64-bit systems ([#633](https://github.com/stlink-org/stlink/pull/633), [#636](https://github.com/stlink-org/stlink/pull/636)) -* Fixed write for microcontroller with RAM size less or equal to 32K ([#637](https://github.com/stlink-org/stlink/pull/637)) -* Fixed memory map for STM32L496xx boards ([#639](https://github.com/stlink-org/stlink/pull/639)) -* Fixed __FILE__ base name extraction ([#624](https://github.com/stlink-org/stlink/pull/624), [#628](https://github.com/stlink-org/stlink/pull/628), [#648](https://github.com/stlink-org/stlink/pull/648)) -* Added debian/triggers to run ldconfig ([#664](https://github.com/stlink-org/stlink/pull/664)) -* Fixed build on Fedora with GCC 8 ([#666](https://github.com/stlink-org/stlink/pull/666), [#667](https://github.com/stlink-org/stlink/pull/667), [#668](https://github.com/stlink-org/stlink/pull/668)) - +- Fixed verification of flash error for STM32L496x device ([#617](https://github.com/stlink-org/stlink/pull/617), [#618](https://github.com/stlink-org/stlink/pull/618)) +- Updated Linux source repositories in README.md: Gentoo, Fedora and RedHat/CentOS ([#622](https://github.com/stlink-org/stlink/pull/622), [#635](https://github.com/stlink-org/stlink/pull/635)) +- Updated changelog in debian package ([#630](https://github.com/stlink-org/stlink/pull/630)) +- Added `LIB_INSTALL_DIR` to correct libs install on 64-bit systems ([#633](https://github.com/stlink-org/stlink/pull/633), [#636](https://github.com/stlink-org/stlink/pull/636)) +- Fixed write for microcontroller with RAM size less or equal to 32K ([#637](https://github.com/stlink-org/stlink/pull/637)) +- Fixed memory map for STM32L496xx boards ([#639](https://github.com/stlink-org/stlink/pull/639)) +- Fixed `__FILE__` base name extraction ([#624](https://github.com/stlink-org/stlink/pull/624), [#628](https://github.com/stlink-org/stlink/pull/628), [#648](https://github.com/stlink-org/stlink/pull/648)) +- Added debian/triggers to run `ldconfig` ([#664](https://github.com/stlink-org/stlink/pull/664)) +- Fixed build on Fedora with GCC 8 ([#666](https://github.com/stlink-org/stlink/pull/666), [#667](https://github.com/stlink-org/stlink/pull/667), [#668](https://github.com/stlink-org/stlink/pull/668)) -v1.4.0 -====== +# v1.4.0 Release date: 2017-07-01 Major changes and added features: -* Allow building of debian package with CPack ([#554](https://github.com/stlink-org/stlink/pull/554), commit [#5b69f25](https://github.com/stlink-org/stlink/commit/5b69f25198a1a8f34e2ee48d1ad20f79447e3d55)) -* Added support for STM32L011 target ([#564](https://github.com/stlink-org/stlink/pull/564), [#565](https://github.com/stlink-org/stlink/pull/565), [#572](https://github.com/stlink-org/stlink/pull/572)) -* Added support for flashing second bank on STM32F10x_XL ([#592](https://github.com/stlink-org/stlink/pull/592)) -* Initial support to compile with Microsoft Visual Studio 2017 ([#602](https://github.com/stlink-org/stlink/pull/602)) -* Added support for STM32L452 target ([#603](https://github.com/stlink-org/stlink/pull/603), [#608](https://github.com/stlink-org/stlink/pull/608)) +- Allow building of debian package with CPack ([#554](https://github.com/stlink-org/stlink/pull/554), commit [#5b69f25](https://github.com/stlink-org/stlink/commit/5b69f25198a1a8f34e2ee48d1ad20f79447e3d55)) +- Added support for STM32L011 target ([#564](https://github.com/stlink-org/stlink/pull/564), [#565](https://github.com/stlink-org/stlink/pull/565), [#572](https://github.com/stlink-org/stlink/pull/572)) +- Added support for flashing second bank on STM32F10x_XL ([#592](https://github.com/stlink-org/stlink/pull/592)) +- Initial support to compile with Microsoft Visual Studio 2017 ([#602](https://github.com/stlink-org/stlink/pull/602)) +- Added support for STM32L452 target ([#603](https://github.com/stlink-org/stlink/pull/603), [#608](https://github.com/stlink-org/stlink/pull/608)) Updates and fixes: -* Fixed gdb-server: STM32L0xx has no FP_CTRL register for breakpoints ([#273](https://github.com/stlink-org/stlink/pull/273)) -* Added --flash=n[k][m] command line option to override device model ([#305](https://github.com/stlink-org/stlink/pull/305), [#516](https://github.com/stlink-org/stlink/pull/516), [#576](https://github.com/stlink-org/stlink/pull/576)) -* Updated libusb to 1.0.21 for Windows ([#562](https://github.com/stlink-org/stlink/pull/562)) -* Fixed low-voltage flashing on STM32F7 devices ([#566](https://github.com/stlink-org/stlink/pull/566), [#567](https://github.com/stlink-org/stlink/pull/567)) -* Fixed building with mingw64 ([#569](https://github.com/stlink-org/stlink/pull/569), [#573](https://github.com/stlink-org/stlink/pull/573), [#578](https://github.com/stlink-org/stlink/pull/578), [#582](https://github.com/stlink-org/stlink/pull/582), [#584](https://github.com/stlink-org/stlink/pull/584), [#610](https://github.com/stlink-org/stlink/pull/610), [#846](https://github.com/stlink-org/stlink/pull/846)) -* Fixed possible memory leak ([#570](https://github.com/stlink-org/stlink/pull/570), [#571](https://github.com/stlink-org/stlink/pull/571)) -* Fixed installation path for shared objects ([#581](https://github.com/stlink-org/stlink/pull/581)) -* Fixed a few -Wformat warnings ([#582](https://github.com/stlink-org/stlink/pull/582)) -* Removed unused defines in mimgw.h ([#583](https://github.com/stlink-org/stlink/pull/583)) -* Skip GTK detection when cross-compiling ([#588](https://github.com/stlink-org/stlink/pull/588)) -* Fixed compilation with GCC 7 ([#590](https://github.com/stlink-org/stlink/pull/590), [#591](https://github.com/stlink-org/stlink/pull/591)) -* Fixed flashing to 'f0 device' targets ([#594](https://github.com/stlink-org/stlink/pull/594), [#595](https://github.com/stlink-org/stlink/pull/595)) -* Fixed wrong counting when flashing ([#605](https://github.com/stlink-org/stlink/pull/605)) - - -v1.3.1 -====== +- Fixed gdb-server: STM32L0xx has no `FP_CTRL` register for breakpoints ([#273](https://github.com/stlink-org/stlink/pull/273)) +- Added `--flash=n[k][m]` command line option to override device model ([#305](https://github.com/stlink-org/stlink/pull/305), [#516](https://github.com/stlink-org/stlink/pull/516), [#576](https://github.com/stlink-org/stlink/pull/576)) +- Updated `libusb` to 1.0.21 for Windows ([#562](https://github.com/stlink-org/stlink/pull/562)) +- Fixed low-voltage flashing on STM32F7 devices ([#566](https://github.com/stlink-org/stlink/pull/566), [#567](https://github.com/stlink-org/stlink/pull/567)) +- Fixed building with mingw64 ([#569](https://github.com/stlink-org/stlink/pull/569), [#573](https://github.com/stlink-org/stlink/pull/573), [#578](https://github.com/stlink-org/stlink/pull/578), [#582](https://github.com/stlink-org/stlink/pull/582), [#584](https://github.com/stlink-org/stlink/pull/584), [#610](https://github.com/stlink-org/stlink/pull/610), [#846](https://github.com/stlink-org/stlink/pull/846)) +- Fixed possible memory leak ([#570](https://github.com/stlink-org/stlink/pull/570), [#571](https://github.com/stlink-org/stlink/pull/571)) +- Fixed installation path for shared objects ([#581](https://github.com/stlink-org/stlink/pull/581)) +- Fixed a few `-Wformat` warnings ([#582](https://github.com/stlink-org/stlink/pull/582)) +- Removed unused defines in `mingw.h` ([#583](https://github.com/stlink-org/stlink/pull/583)) +- Skip `GTK` detection when cross-compiling ([#588](https://github.com/stlink-org/stlink/pull/588)) +- Fixed compilation with GCC 7 ([#590](https://github.com/stlink-org/stlink/pull/590), [#591](https://github.com/stlink-org/stlink/pull/591)) +- Fixed flashing to `F0 device` targets ([#594](https://github.com/stlink-org/stlink/pull/594), [#595](https://github.com/stlink-org/stlink/pull/595)) +- Fixed wrong counting when flashing ([#605](https://github.com/stlink-org/stlink/pull/605)) + +# v1.3.1 Release date: 2017-02-25 Major changes and added features: -* Added support for Semihosting `SYS_READC` ([#546](https://github.com/stlink-org/stlink/pull/546)) -* Added support for STM32F413 ([#549](https://github.com/stlink-org/stlink/pull/549), [#550](https://github.com/stlink-org/stlink/pull/550), [#758](https://github.com/stlink-org/stlink/pull/758)) -* Added preliminary support for STM32L011 to see it after probe (chip-ID 0x457) ([#558](https://github.com/stlink-org/stlink/pull/558), [#598](https://github.com/stlink-org/stlink/pull/598)) +- Added support for Semihosting `SYS_READC` ([#546](https://github.com/stlink-org/stlink/pull/546)) +- Added support for STM32F413 ([#549](https://github.com/stlink-org/stlink/pull/549), [#550](https://github.com/stlink-org/stlink/pull/550), [#758](https://github.com/stlink-org/stlink/pull/758)) +- Added preliminary support for STM32L011 to see it after probe (chip-ID 0x457) ([#558](https://github.com/stlink-org/stlink/pull/558), [#598](https://github.com/stlink-org/stlink/pull/598)) Updates and fixes: -* cmake/CPackConfig.cmake: Fixup OSX zip filename -* Updated source repositories in README.md: Windows, macOS, Alpine Linux -* Compilation fixes ([#547](https://github.com/stlink-org/stlink/pull/547), [#551](https://github.com/stlink-org/stlink/pull/551), [#552](https://github.com/stlink-org/stlink/pull/552)) -* Stripped full paths to source files in log ([#548](https://github.com/stlink-org/stlink/pull/548)) -* Fixed incorrect release folder name in docs ([#560](https://github.com/stlink-org/stlink/pull/560)) -* Fixed compilation when path includes spaces ([#561](https://github.com/stlink-org/stlink/pull/561)) - +- `cmake/CPackConfig.cmake`: Fixup OSX zip filename +- Updated source repositories in README.md: Windows, macOS, Alpine Linux +- Compilation fixes ([#547](https://github.com/stlink-org/stlink/pull/547), [#551](https://github.com/stlink-org/stlink/pull/551), [#552](https://github.com/stlink-org/stlink/pull/552)) +- Stripped full paths to source files in log ([#548](https://github.com/stlink-org/stlink/pull/548)) +- Fixed incorrect release folder name in docs ([#560](https://github.com/stlink-org/stlink/pull/560)) +- Fixed compilation when path includes spaces ([#561](https://github.com/stlink-org/stlink/pull/561)) -v1.3.0 -====== +# v1.3.0 Release date: 2017-01-28 Major changes and added features: -* Deprecation of autotools (autoconf, automake) and fixed build with MinGW ([#83](https://github.com/stlink-org/stlink/pull/83), [#431](https://github.com/stlink-org/stlink/pull/431), [#434](https://github.com/stlink-org/stlink/pull/434), [#465](https://github.com/stlink-org/stlink/pull/465)) -* Added intel hex file reading for `st-flash` ([#110](https://github.com/stlink-org/stlink/pull/110), [#157](https://github.com/stlink-org/stlink/pull/157), [#457](https://github.com/stlink-org/stlink/pull/547), [#459](https://github.com/stlink-org/stlink/pull/549)) -* Added support for ARM semihosting to `st-util` ([#147](https://github.com/stlink-org/stlink/pull/147), [#227](https://github.com/stlink-org/stlink/pull/227), [#454](https://github.com/stlink-org/stlink/pull/454), [#455](https://github.com/stlink-org/stlink/pull/455)) -* Added manpages (generated with pandoc from Markdown) ([#208](https://github.com/stlink-org/stlink/pull/208), [#464](https://github.com/stlink-org/stlink/pull/464), [#466](https://github.com/stlink-org/stlink/pull/466), [#467](https://github.com/stlink-org/stlink/pull/467)) -* Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#228](https://github.com/stlink-org/stlink/pull/228), [#507](https://github.com/stlink-org/stlink/pull/507), commit [#3fd0f09](https://github.com/stlink-org/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) -* Support serial numbers argument for `st-util` and `st-flash` to probe and control multiple connected programmers ([#318](https://github.com/stlink-org/stlink/pull/318), [#398](https://github.com/stlink-org/stlink/pull/398), [#541](https://github.com/stlink-org/stlink/pull/541)) -* Merge st-probe tool into st-info ([#398](https://github.com/stlink-org/stlink/pull/398)) -* Added support for native debian packaging ([#444](https://github.com/stlink-org/stlink/pull/444), [#472](https://github.com/stlink-org/stlink/pull/472), [#473](https://github.com/stlink-org/stlink/pull/473), [#482](https://github.com/stlink-org/stlink/pull/482), [#483](https://github.com/stlink-org/stlink/pull/483), [#484](https://github.com/stlink-org/stlink/pull/484), [#485](https://github.com/stlink-org/stlink/pull/485)) -* Rewritten commandline parsing for `st-flash` ([#459](https://github.com/stlink-org/stlink/pull/459)) -* Added `--reset` command to `st-flash` ([#505](https://github.com/stlink-org/stlink/pull/505)) -* st-util should detect when USB commands fail ([#525](https://github.com/stlink-org/stlink/pull/525), [#527](https://github.com/stlink-org/stlink/pull/527), [#528](https://github.com/stlink-org/stlink/pull/528)) +- Deprecation of autotools (`autoconf`, `automake`) and fixed build with MinGW ([#83](https://github.com/stlink-org/stlink/pull/83), [#431](https://github.com/stlink-org/stlink/pull/431), [#434](https://github.com/stlink-org/stlink/pull/434), [#465](https://github.com/stlink-org/stlink/pull/465)) +- Added intel hex file reading for `st-flash` ([#110](https://github.com/stlink-org/stlink/pull/110), [#157](https://github.com/stlink-org/stlink/pull/157), [#457](https://github.com/stlink-org/stlink/pull/547), [#459](https://github.com/stlink-org/stlink/pull/549)) +- Added support for ARM semihosting to `st-util` ([#147](https://github.com/stlink-org/stlink/pull/147), [#227](https://github.com/stlink-org/stlink/pull/227), [#454](https://github.com/stlink-org/stlink/pull/454), [#455](https://github.com/stlink-org/stlink/pull/455)) +- Added manpages (generated with `pandoc` from Markdown) ([#208](https://github.com/stlink-org/stlink/pull/208), [#464](https://github.com/stlink-org/stlink/pull/464), [#466](https://github.com/stlink-org/stlink/pull/466), [#467](https://github.com/stlink-org/stlink/pull/467)) +- Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#228](https://github.com/stlink-org/stlink/pull/228), [#507](https://github.com/stlink-org/stlink/pull/507), commit [#3fd0f09](https://github.com/stlink-org/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) +- Support serial numbers argument for `st-util` and `st-flash` to probe and control multiple connected programmers ([#318](https://github.com/stlink-org/stlink/pull/318), [#398](https://github.com/stlink-org/stlink/pull/398), [#541](https://github.com/stlink-org/stlink/pull/541)) +- Merge `st-probe` tool into `st-info` ([#398](https://github.com/stlink-org/stlink/pull/398)) +- Added support for native debian packaging ([#444](https://github.com/stlink-org/stlink/pull/444), [#472](https://github.com/stlink-org/stlink/pull/472), [#473](https://github.com/stlink-org/stlink/pull/473), [#482](https://github.com/stlink-org/stlink/pull/482), [#483](https://github.com/stlink-org/stlink/pull/483), [#484](https://github.com/stlink-org/stlink/pull/484), [#485](https://github.com/stlink-org/stlink/pull/485)) +- Rewritten commandline parsing for `st-flash` ([#459](https://github.com/stlink-org/stlink/pull/459)) +- Added `--reset` command to `st-flash` ([#505](https://github.com/stlink-org/stlink/pull/505)) +- st-util should detect when USB commands fail ([#525](https://github.com/stlink-org/stlink/pull/525), [#527](https://github.com/stlink-org/stlink/pull/527), [#528](https://github.com/stlink-org/stlink/pull/528)) Chip support added for: -* STM32F401XE: Added memory map for device ([#460](https://github.com/stlink-org/stlink/pull/460)) -* STM32F410RBTx ([#418](https://github.com/stlink-org/stlink/pull/418)) -* STM32F412 ([#537](https://github.com/stlink-org/stlink/pull/537), [#538](https://github.com/stlink-org/stlink/pull/538)) -* STM32F7xx ([#324](https://github.com/stlink-org/stlink/pull/324), [#326](https://github.com/stlink-org/stlink/pull/326), [#327](https://github.com/stlink-org/stlink/pull/327), [#337](https://github.com/stlink-org/stlink/pull/337)) -* STM32F7x7x ([#433](https://github.com/stlink-org/stlink/pull/433), [#435](https://github.com/stlink-org/stlink/pull/435), [#436](https://github.com/stlink-org/stlink/pull/436), [#509](https://github.com/stlink-org/stlink/pull/509)) -* STM32L0xx Cat2 devices (chip-ID: 0x425) ([#414](https://github.com/stlink-org/stlink/pull/414)) -* STM32L0xx Cat5 devices (chip-ID: 0x447) ([#387](https://github.com/stlink-org/stlink/pull/387), [#406](https://github.com/stlink-org/stlink/pull/406)) -* STM32L4xx ([#321](https://github.com/stlink-org/stlink/pull/321)) -* STM32L432 ([#500](https://github.com/stlink-org/stlink/pull/500), [#501](https://github.com/stlink-org/stlink/pull/501)) +- STM32F401XE: Added memory map for device ([#460](https://github.com/stlink-org/stlink/pull/460)) +- STM32F410RBTx ([#418](https://github.com/stlink-org/stlink/pull/418)) +- STM32F412 ([#537](https://github.com/stlink-org/stlink/pull/537), [#538](https://github.com/stlink-org/stlink/pull/538)) +- STM32F7xx ([#324](https://github.com/stlink-org/stlink/pull/324), [#326](https://github.com/stlink-org/stlink/pull/326), [#327](https://github.com/stlink-org/stlink/pull/327), [#337](https://github.com/stlink-org/stlink/pull/337)) +- STM32F7x7x ([#433](https://github.com/stlink-org/stlink/pull/433), [#435](https://github.com/stlink-org/stlink/pull/435), [#436](https://github.com/stlink-org/stlink/pull/436), [#509](https://github.com/stlink-org/stlink/pull/509)) +- STM32L0xx Cat2 devices (chip-ID: 0x425) ([#414](https://github.com/stlink-org/stlink/pull/414)) +- STM32L0xx Cat5 devices (chip-ID: 0x447) ([#387](https://github.com/stlink-org/stlink/pull/387), [#406](https://github.com/stlink-org/stlink/pull/406)) +- STM32L4xx ([#321](https://github.com/stlink-org/stlink/pull/321)) +- STM32L432 ([#500](https://github.com/stlink-org/stlink/pull/500), [#501](https://github.com/stlink-org/stlink/pull/501)) Updates and fixes: -* Fixed "unaligned addr or size" when trying to write a program in RAM ([#323](https://github.com/stlink-org/stlink/pull/323)) -* Fixed flashing on STM32_F3_SMALL ([#325](https://github.com/stlink-org/stlink/pull/325)) -* Fixed STM32L-problem with flash loader ([#390](https://github.com/stlink-org/stlink/pull/390), [#407](https://github.com/stlink-org/stlink/pull/407), [#408](https://github.com/stlink-org/stlink/pull/408)) -* Don't read the target voltage on startup, because it crashes STM32F100 ([#423](https://github.com/stlink-org/stlink/pull/423), [#424](https://github.com/stlink-org/stlink/pull/424)) -* Added a useful error message instead of "[!] send_recv" ([#425](https://github.com/stlink-org/stlink/pull/425), [#426](https://github.com/stlink-org/stlink/pull/426)) -* Do a JTAG reset prior to reading CPU information when processor is in deep sleep ([#428](https://github.com/stlink-org/stlink/pull/428), [#430](https://github.com/stlink-org/stlink/pull/430), [#451](https://github.com/stlink-org/stlink/pull/451)) -* Fixed STM32F030 erase error ([#442](https://github.com/stlink-org/stlink/pull/442)) -* Fixed memory map for STM32F7xx ([#453](https://github.com/stlink-org/stlink/pull/453), [#456](https://github.com/stlink-org/stlink/pull/456)) -* Redesign of `st-flash` commandline options parsing ([#459](https://github.com/stlink-org/stlink/pull/459)) -* Set SWDCLK and fixed jtag_reset bug ([#462](https://github.com/stlink-org/stlink/pull/462), [#475](https://github.com/stlink-org/stlink/pull/475), [#534](https://github.com/stlink-org/stlink/pull/534)) -* doc/compiling.md: Add note about installation and ldconfig ([#478](https://github.com/stlink-org/stlink/pull/478), commit [#be66bbf](https://github.com/stlink-org/stlink/commit/be66bbf200c718904514b044ba84d64a36456218)) -* Fixed Release target to generate the man-pages with pandoc ([#479](https://github.com/stlink-org/stlink/pull/479)) -* Fixed Cygwin build ([#487](https://github.com/stlink-org/stlink/pull/487), ([#506](https://github.com/stlink-org/stlink/pull/506)) -* Reset flash mass erase (MER) bit after mass erase for safety ([#489](https://github.com/stlink-org/stlink/pull/489)) -* Wrong extract command in FindLibUSB.cmake ([#510](https://github.com/stlink-org/stlink/pull/510), [#511](https://github.com/stlink-org/stlink/pull/511)) -* Fixed compilation error on Ubuntu 16.10 ([#514](https://github.com/stlink-org/stlink/pull/514), [#525](https://github.com/stlink-org/stlink/pull/525)) - - -v1.2.0 -====== +- Fixed `unaligned addr or size` when trying to write a program in RAM ([#323](https://github.com/stlink-org/stlink/pull/323)) +- Fixed flashing on `STM32_F3_SMALL` ([#325](https://github.com/stlink-org/stlink/pull/325)) +- Fixed STM32L-problem with flash loader ([#390](https://github.com/stlink-org/stlink/pull/390), [#407](https://github.com/stlink-org/stlink/pull/407), [#408](https://github.com/stlink-org/stlink/pull/408)) +- Don't read the target voltage on startup, because it crashes STM32F100 ([#423](https://github.com/stlink-org/stlink/pull/423), [#424](https://github.com/stlink-org/stlink/pull/424)) +- Added a useful error message instead of `[!] send_recv` ([#425](https://github.com/stlink-org/stlink/pull/425), [#426](https://github.com/stlink-org/stlink/pull/426)) +- Do a JTAG reset prior to reading CPU information when processor is in deep sleep ([#428](https://github.com/stlink-org/stlink/pull/428), [#430](https://github.com/stlink-org/stlink/pull/430), [#451](https://github.com/stlink-org/stlink/pull/451)) +- Fixed STM32F030 erase error ([#442](https://github.com/stlink-org/stlink/pull/442)) +- Fixed memory map for STM32F7xx ([#453](https://github.com/stlink-org/stlink/pull/453), [#456](https://github.com/stlink-org/stlink/pull/456)) +- Redesign of `st-flash` commandline options parsing ([#459](https://github.com/stlink-org/stlink/pull/459)) +- Set `SWDCLK` and fixed `jtag_reset` bug ([#462](https://github.com/stlink-org/stlink/pull/462), [#475](https://github.com/stlink-org/stlink/pull/475), [#534](https://github.com/stlink-org/stlink/pull/534)) +- doc/compiling.md: Add note about installation and `ldconfig` ([#478](https://github.com/stlink-org/stlink/pull/478), commit [#be66bbf](https://github.com/stlink-org/stlink/commit/be66bbf200c718904514b044ba84d64a36456218)) +- Fixed Release target to generate the man-pages with `pandoc` ([#479](https://github.com/stlink-org/stlink/pull/479)) +- Fixed Cygwin build ([#487](https://github.com/stlink-org/stlink/pull/487), ([#506](https://github.com/stlink-org/stlink/pull/506)) +- Reset flash mass erase (MER) bit after mass erase for safety ([#489](https://github.com/stlink-org/stlink/pull/489)) +- Wrong extract command in `FindLibUSB.cmake` ([#510](https://github.com/stlink-org/stlink/pull/510), [#511](https://github.com/stlink-org/stlink/pull/511)) +- Fixed compilation error on Ubuntu 16.10 ([#514](https://github.com/stlink-org/stlink/pull/514), [#525](https://github.com/stlink-org/stlink/pull/525)) + +# v1.2.0 Release date: 2016-05-16 Features added: -* Added multiple stlink probing (`st-info --probe`, `st-info --hla-serial`) with printing serial in hex and OpenOCD `hla_serial` format (Jerry Jacobs) -* Added stlink usb probe API functions (Jerry Jacobs) -* Added parameter to specify one stlink v2 of many (Georg von Zengen) +- Added multiple stlink probing (`st-info --probe`, `st-info --hla-serial`) with printing serial in hex and OpenOCD `hla_serial` format (Jerry Jacobs) +- Added stlink usb probe API functions (Jerry Jacobs) +- Added parameter to specify one stlink v2 of many (Georg von Zengen) Updates and fixes: -* Refactoring/fixes of flash loader (Maxime Coquelin) -* Synchronized cache for STM32F7 (Tristan Gingold) -* Allow flashing of STM32L4 down to 1.71 V (Greg Meiste) -* Fix on STM32L4 to clear flash mass erase flags on CR (Bruno Dal Bo) -* Proper writing of page 0 of second bank for stm32l476xe (Tobias Badertscher) -* Trace the read data in stlink_read_debug32 and not the address of the variable (Tobias Badertscher) -* Mac OS X El Capitan platform support confirmation (Nikolay) -* Do not send a NUL at end of packets to gdb (Tristan Gingold) -* Correctly compute flash write size for partial pages (Dave Vandervies) -* _stlink_usb_reset use hardreset (mlundinse) -* Make sure MCU is halted before running RAM based flashloaders (mlundinse) -* Could not flash STM32_F3_SMALL (Max Chen) -* STM32F4 8-bit support for 1.8v operation (Andy Isaacson) -* Fixed STM32F2xx memory map (Nicolas Schodet) -* Memory map for STM32F42xxx and STM32F43xxx devices (Craig Lilley) -* Stm32l0x flash loader (Robin Kreis) -* Fixed segfault when programmer is already busy and NULL pointers are in the list ([#256](https://github.com/stlink-org/stlink/pull/256), [#394](https://github.com/stlink-org/stlink/pull/394)) -* Send F4 memory-map and features for STM32F429 ([#188](https://github.com/stlink-org/stlink/pull/188), [#196](https://github.com/stlink-org/stlink/pull/196), [#250](https://github.com/stlink-org/stlink/pull/250), [#251](https://github.com/stlink-org/stlink/pull/251)) (Release v1.1.0) -* Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/stlink-org/stlink/pull/218), [#288](https://github.com/stlink-org/stlink/pull/288)) (Release v1.1.0) -* Corrected flash size register address for STM32F2 devices ([#278](https://github.com/stlink-org/stlink/pull/278)) (Release v1.0.0) +- Refactoring/fixes of flash loader (Maxime Coquelin) +- Synchronized cache for STM32F7 (Tristan Gingold) +- Allow flashing of STM32L4 down to 1.71 V (Greg Meiste) +- Fix on STM32L4 to clear flash mass erase flags on CR (Bruno Dal Bo) +- Proper writing of page 0 of second bank for STM32L476xe (Tobias Badertscher) +- Trace the read data in `stlink_read_debug32` and not the address of the variable (Tobias Badertscher) +- Mac OS X El Capitan platform support confirmation (Nikolay) +- Do not send a `NULL` at end of packets to `gdb` (Tristan Gingold) +- Correctly compute flash write size for partial pages (Dave Vandervies) +- `_stlink_usb_reset` use hardreset (mlundinse) +- Make sure MCU is halted before running RAM based flashloaders (mlundinse) +- Could not flash `STM32_F3_SMALL` (Max Chen) +- STM32F4 8-bit support for 1.8v operation (Andy Isaacson) +- Fixed STM32F2xx memory map (Nicolas Schodet) +- Memory map for STM32F42xxx and STM32F43xxx devices (Craig Lilley) +- Stm32l0x flash loader (Robin Kreis) +- Fixed segfault when programmer is already busy and `NULL` pointers are in the list ([#256](https://github.com/stlink-org/stlink/pull/256), [#394](https://github.com/stlink-org/stlink/pull/394)) +- Send F4 memory-map and features for STM32F429 ([#188](https://github.com/stlink-org/stlink/pull/188), [#196](https://github.com/stlink-org/stlink/pull/196), [#250](https://github.com/stlink-org/stlink/pull/250), [#251](https://github.com/stlink-org/stlink/pull/251)) (Release v1.1.0) +- Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/stlink-org/stlink/pull/218), [#288](https://github.com/stlink-org/stlink/pull/288)) (Release v1.1.0) +- Corrected flash size register address for STM32F2 devices ([#278](https://github.com/stlink-org/stlink/pull/278)) (Release v1.0.0) Chip support added for: -* STM32L053R8 (Jean-Luc Béchennec) -* STM32F7 Support (mlundinse) -* Added STM32L4 to CHIPID #defines and devices[], flash driver and loader (Dave Vandervies) -* Basic support for STM32F446 (Pavel Kirienko) -* STM32F303 High Density -* STM32F469/STM32F479 ([#345](https://github.com/stlink-org/stlink/pull/345), [#555](https://github.com/stlink-org/stlink/pull/555)) (Release v1.2.0) -* STM32L1xx Cat.2 devices (Nicolas Schodet) -* STM32L1xx (chip-ID 0x427) ([#152](https://github.com/stlink-org/stlink/pull/152), [#163](https://github.com/stlink-org/stlink/pull/163), [#165](https://github.com/stlink-org/stlink/pull/165)) (Release v1.0.0) -* Added SIGINT handler for stlink cleanup ([#31](https://github.com/stlink-org/stlink/pull/31), [#135](https://github.com/stlink-org/stlink/pull/135)) (Release v1.0.0) +- STM32L053R8 (Jean-Luc Béchennec) +- STM32F7 Support (mlundinse) +- Added STM32L4 to CHIPID #defines and devices[], flash driver and loader (Dave Vandervies) +- Basic support for STM32F446 (Pavel Kirienko) +- STM32F303 High Density +- STM32F469/STM32F479 ([#345](https://github.com/stlink-org/stlink/pull/345), [#555](https://github.com/stlink-org/stlink/pull/555)) (Release v1.2.0) +- STM32L1xx Cat.2 devices (Nicolas Schodet) +- STM32L1xx (chip-ID 0x427) ([#152](https://github.com/stlink-org/stlink/pull/152), [#163](https://github.com/stlink-org/stlink/pull/163), [#165](https://github.com/stlink-org/stlink/pull/165)) (Release v1.0.0) +- Added `SIGINT` handler for stlink cleanup ([#31](https://github.com/stlink-org/stlink/pull/31), [#135](https://github.com/stlink-org/stlink/pull/135)) (Release v1.0.0) Board support added for: -* Nucleo-F303RE (Kyle Manna) -* Nucleo-F411RE (texane) +- Nucleo-F303RE (Kyle Manna) +- Nucleo-F411RE (texane) Build system: -* Travis: Initial support for Travis continues integration on Linux & Mac OS X (Jerry Jacobs) -* CMake: Document in README.md and add extra strict compiler flags (Jerry Jacobs) -* CMake: First stab at a cmake build (Josh Bialkowski) +- Travis: Initial support for Travis continues integration on Linux & Mac OS X (Jerry Jacobs) +- CMake: Document in README.md and add extra strict compiler flags (Jerry Jacobs) +- CMake: First stab at a `cmake` build (Josh Bialkowski) From 03793d42b6078344a9ef8ad55f1d5d0fc19e486e Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 11 Mar 2021 00:52:03 +0100 Subject: [PATCH 1106/1435] [doc] Added note on gdb 'run' command (Closes #267) --- doc/tutorial.md | 70 +++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 37 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 1d20c68ee..f13c4c6f1 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1,35 +1,37 @@ -stlink Tools Tutorial -===================== +# stlink Tools Tutorial ## Available tools and options -| Option | Tool | Description | Available
      since | -| --- | --- | --- | --- | -| --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k
      for the STM32F103C8T6 to assume 128k of flash being present. This option accepts
      decimal (128k), octal 0200k, or hex 0x80k values. Leaving the multiplier out is
      equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional "k"
      or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | -| --freq=n[k][m] | st-flash,
      st-util | The frequency of the SWD/JTAG interface can be specified, to override the default
      1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
      the unit `Hz` being left out. Valid frequencies are `5K, 15K, 25K, 50K, 100K,`
      `125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | -| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at
      the end of binary file. This may cause some garbage data left after a flash operation.
      This option was enabled by default in earlier releases. | v1.6.1 | -| --reset | st-flash | Trigger a reset both before and after flashing. | v1.0.0 | -| --version | st-info,
      st-flash,
      st-util | Print version information. | | -| --help | st-flash,
      st-util | Print list of available commands. _(To be added to this table.)_ | | +| Option | Tool | Description | Available
      since | +| --------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k
      for the STM32F103C8T6 to assume 128k of flash being present. This option accepts
      decimal (128k), octal 0200k, or hex 0x80k values. Leaving the multiplier out is
      equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional "k"
      or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | +| --freq=n[k][m] | st-flash,
      st-util | The frequency of the SWD/JTAG interface can be specified, to override the default
      1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
      the unit `Hz` being left out. Valid frequencies are `5K, 15K, 25K, 50K, 100K,`
      `125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | +| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at
      the end of binary file. This may cause some garbage data left after a flash operation.
      This option was enabled by default in earlier releases. | v1.6.1 | +| --reset | st-flash | Trigger a reset both before and after flashing. | v1.0.0 | +| --version | st-info,
      st-flash,
      st-util | Print version information. | | +| --help | st-flash,
      st-util | Print list of available commands. _(To be added to this table.)_ | | ### st-flash: Checksum for binary files + When flashing a file, a checksum is calculated for the binary file, both in md5 and the sum algorithm. The latter is also used by the official ST-Link utility tool from STMicroelectronics as described in the document: [`UM0892 - User manual - STM32 ST-LINK utility software description`](https://www.st.com/resource/en/user_manual/cd00262073-stm32-stlink-utility-software-description-stmicroelectronics.pdf). ### stlink-gui + The `stlink` toolset also provides a GUI which is an optional feature. It is only installed if a gtk3 toolset has been detected during package installation or compilation from source. It is not available for Windows. If you prefer to have an user interface on the latter system, please use the official `ST-LINK Utility` instead. The stlink-gui offers the following features: -* Connect/disconnect to a present STlink programmer -* Display basic device information -* Select a binary file from the local filesystem to flash it to the detected device connected to the programmer -* Export the memory of the connected chip to a file which can be saved to the local filesystem -* Display of the memory address map in the main window for each, the device memory and a loaded binary file -Within the GUI main window tooltips explain the available user elements. +- Connect/disconnect to a present STlink programmer +- Display basic device information +- Select a binary file from the local filesystem to flash it to the detected device connected to the programmer +- Export the memory of the connected chip to a file which can be saved to the local filesystem +- Display of the memory address map in the main window for each, the device memory and a loaded binary file +Within the GUI main window tooltips explain the available user elements. ## Solutions to common problems + ### a) Verify if udev rules are set correctly (by Dave Hylands) To investigate, start by plugging your STLINK device into the usb port. Then run `lsusb`. You should see an entry something like the following: @@ -77,7 +79,6 @@ to ensure that the rules actually take effect. Using the trigger command means t If the VID:PID of your device doesn't match those in any of the 3 files, then you may need to create a custom rule file to match your VID:PID. - ### b) NOTE: Chinese Fake-Chips CKS32F103C8T6 or CS32F103C8T6 being marked as "STM32F103C8T6" In contrast to "Clone chips" which identify themselves as such by their official marking (manufacturer, model, etc.), so called "Fake chips" do not. @@ -89,8 +90,8 @@ In this known example one finds the counterfeited "STM32F103C8T6" MCUs to identi In the following you find some hints on how to identify your chip and track down fraud: -* [How to Detect STM32 Fakes](https://www.cnx-software.com/2020/03/22/how-to-detect-stm32-fakes/) -* [Confirmation by STMicroelectronics](https://www.mikrocontroller.net/attachment/442839/couterfeit_STM.png) (Marking: 991KA 93 MYS 807) +- [How to Detect STM32 Fakes](https://www.cnx-software.com/2020/03/22/how-to-detect-stm32-fakes/) +- [Confirmation by STMicroelectronics](https://www.mikrocontroller.net/attachment/442839/couterfeit_STM.png) (Marking: 991KA 93 MYS 807) However it appears that not all counterfeited parts cause problems during operation, but some are known to not even being able to execute a basic "blinky" example binary. Further there can be problems that may not even show up or affect you directly, but somewhen later in time (or maybe never). This demonstrates there is no guarantee for a proper working chip with equal functionality compared to the original. @@ -100,11 +101,11 @@ Check your hardware and try to identify what you have in front of you before ass Please let us know, if you come across any further websites or tutorials that help to identify STM32 fake chips so we can list them here to help others. ------- +--- + ( Content below is currently unrevised and may be outdated as of Apr 2020. ) -Using STM32 discovery kits with open source tools -======== +# Using STM32 discovery kits with open source tools This guide details the use of STMicroelectronics STM32 discovery kits in an open source environment. @@ -121,11 +122,11 @@ from any vendor. It has some good, reliable examples for each of the Discovery b Even if you don’t plan on using libopencm3, the examples they provide will help you verify that: -- Your installed toolchain is capable of compiling for cortex M3/M4 - targets -- stlink is functional -- Your arm-none-eabi-gdb is functional -- Your board is functional +- Your installed toolchain is capable of compiling for cortex M3/M4 + targets +- stlink is functional +- Your arm-none-eabi-gdb is functional +- Your board is functional A GDB server must be started to interact with the STM32 by running st-util tool : @@ -173,7 +174,6 @@ Your program should now be running, and, if you used one of the blinking examples from libopencm3, the LEDs on the board should be blinking for you. - ## Building and flashing a program If you want to simply flash binary files to arbitrary sections of @@ -207,7 +207,6 @@ $> [sudo] ./st-flash write fancy_blink.bin 0x08000000 Upon reset, the board LEDs should be blinking. - ## Using the gdb server To run the gdb server: @@ -252,7 +251,6 @@ Transfer rate: 1 KB/sec, 560 bytes/write. (gdb) continue ``` - ## Resetting the chip from GDB You may reset the chip using GDB if you want. You'll need to use `target @@ -268,6 +266,9 @@ Kill the program being debugged? (y or n) y Starting program: /home/whitequark/ST/apps/bally/firmware.elf ``` +Note that st-link does not support 'run', as it does not load arbitrary programs without explicit commands. +In order to continue, one can use 'monitor reset' to reset the MCU. + Remember that you can shorten the commands. `tar ext :4242` is good enough for GDB. @@ -277,7 +278,6 @@ If you need to send a hard reset signal through `NRST` pin, you can use the foll (gdb) monitor jtag_reset ``` - ## Disassembling THUMB code in GDB By default, the disassemble command in GDB operates in ARM mode. The programs running on CORTEX-M3 are compiled in THUMB mode. @@ -287,7 +287,6 @@ To correctly disassemble them under GDB, uses an odd address. For instance, if y (gdb) disassemble 0x20000001 ``` - ## Running programs from SRAM You can run your firmware directly from SRAM if you want to. Just link @@ -300,7 +299,6 @@ it at 0x20000000 and do It will be loaded, and pc will be adjusted to point to start of the code, if it is linked correctly (i.e. ELF has correct entry point). - ## Writing to flash The GDB stub ships with a correct memory map, including the flash area. @@ -312,18 +310,16 @@ If you would link your executable to `0x08000000` and then do then it would be written to the memory. - ## Writing Option Bytes Example to read and write option bytes (currently writing only supported for STM32G0 and STM32L0) + ``` ./st-flash --debug --reset --format binary --flash=128k read option_bytes_dump.bin 0x1FFF7800 4 ./st-flash --debug --reset --format binary --flash=128k write option_bytes_dump.bin 0x1FFF7800 ``` - -FAQ -=== +# FAQ Q: My breakpoints do not work at all or only work once. From 45e9b5ee6e8e2128b837de064ab1a84f6f24c9c3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 11 Mar 2021 14:15:37 +0100 Subject: [PATCH 1107/1435] General Project Update - Updated CHANGELOG.md - Updated list of contributors - Fixed travis CI build settings --- .travis.yml | 15 +++++++-------- CHANGELOG.md | 10 +++++++++- contributors.txt | 1 + 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4437b3148..fefafbaf1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,11 +30,11 @@ jobs: - os: linux dist: xenial env: BADGE=linux - compiler: clang-8 + compiler: clang addons: apt: - sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-xenial-3.7"] - packages: ["clang-8", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + sources: ["ubuntu-toolchain-r-test"] + packages: ["libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - os: linux dist: bionic env: BADGE=linux @@ -98,11 +98,11 @@ jobs: - os: linux dist: xenial env: BADGE=linux - compiler: clang-8 + compiler: clang addons: apt: - sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-xenial-3.7"] - packages: ["clang-8", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + sources: ["ubuntu-toolchain-r-test"] + packages: ["libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] before_install: - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - os: linux @@ -111,11 +111,10 @@ jobs: compiler: clang-10 addons: apt: - sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-bionic-6.0"] + sources: ["ubuntu-toolchain-r-test"] packages: ["clang-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] before_install: - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - before_install: - os: linux dist: focal env: BADGE=linux diff --git a/CHANGELOG.md b/CHANGELOG.md index c4adaf2ba..912092b65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,14 +16,19 @@ Features: - Link for WIN32 & APPLE with stlink-static ([#1069](https://github.com/stlink-org/stlink/pull/1069)) - Extended support for STM32H7 ([#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) - ITM functionality for STLink/V2 and STM32Fxx chipsets ([#136](https://github.com/stlink-org/stlink/pull/136), [#179](https://github.com/stlink-org/stlink/pull/179), [#815](https://github.com/stlink-org/stlink/pull/815), [#1072](https://github.com/stlink-org/stlink/pull/1072)) +- Included ITM functionality for building with MSVC ([#1080](https://github.com/stlink-org/stlink/pull/1080)) Updates & changes: +- [doc] Added note on `(gdb) run` command (commit [#03793d4](https://github.com/stlink-org/stlink/commit/03793d42b6078344a9ef8ad55f1d5d0fc19e486e), [#276](https://github.com/stlink-org/stlink/pull/276)) - [doc] `st-flash --reset` parameter (one solution for #356) ([#642](https://github.com/stlink-org/stlink/pull/642)) - [refactoring] General maintenance ([#864](https://github.com/stlink-org/stlink/pull/864), [#976](https://github.com/stlink-org/stlink/pull/976), [#978](https://github.com/stlink-org/stlink/pull/978)) - Imported debian pkg-settings ([#986](https://github.com/stlink-org/stlink/pull/986)) - Add support for FreeBSD's `libusb` reimplementation ([#992](https://github.com/stlink-org/stlink/pull/992), [#993](https://github.com/stlink-org/stlink/pull/993)) +- [doc] Added explanation about STM32F103 fake chips (commit [#a66557a](https://github.com/stlink-org/stlink/commit/a66557a102d48e69feb0a9746e8e42c4baf31fe2), [#1024](https://github.com/stlink-org/stlink/pull/1024)) - [doc] Added example for output of `st-info --probe` ([#1007](https://github.com/stlink-org/stlink/pull/1007), [#1049](https://github.com/stlink-org/stlink/pull/1049)) +- [refactoring] Correctly handle endianness without reference to host platform ([#1081](https://github.com/stlink-org/stlink/pull/1081)) +- Check format string for log messages ([#1093](https://github.com/stlink-org/stlink/pull/1093)) Fixes: @@ -33,7 +38,7 @@ Fixes: - Fixed installation path for desktop-file and icons ([#972](https://github.com/stlink-org/stlink/pull/972)) - Fix for static linking of `libssp` ([#973](https://github.com/stlink-org/stlink/pull/973), [#974](https://github.com/stlink-org/stlink/pull/974)) - [regression] Fixed wrong formatting for library install path ([#978](https://github.com/stlink-org/stlink/pull/978), [#1089](https://github.com/stlink-org/stlink/pull/1089)) -- Fixed installation of header files needed for compiling with `libstlink.so.1.6.1` ([#982](https://github.com/stlink-org/stlink/pull/982)) +- Fixed installation of header files needed for compiling with `libstlink.so.1.6.1` (commit [#31b1fa1](https://github.com/stlink-org/stlink/commit/31b1fa16201521e2aaf464576f2f169981abede0), [#982](https://github.com/stlink-org/stlink/pull/982)) - Fixed `connect under reset` for `st-flash` and `st-util` ([#983](https://github.com/stlink-org/stlink/pull/983)) - Fix for `mmap() size_t overflow` in `st-flash` ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) - [regression] `stlink-gui` installation issue on Ubuntu-18.04 ([#1001](https://github.com/stlink-org/stlink/pull/1001), [#1004](https://github.com/stlink-org/stlink/pull/1004), [#1006](https://github.com/stlink-org/stlink/pull/1006)) @@ -41,7 +46,9 @@ Fixes: - [doc] Fixed wrong path for `rules.d` folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) - Use vl flashloader for all STM32F1 series ([#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - Fixed `gettimeofday` for MSVC ([#1074](https://github.com/stlink-org/stlink/pull/1074)) +- Bugfixes for compilation with clang ([#1076](https://github.com/stlink-org/stlink/pull/1076), [#1078](https://github.com/stlink-org/stlink/pull/1078)) - Fixed compilation with GCC 11 ([#1077](https://github.com/stlink-org/stlink/pull/1077)) +- [regression] Flash_loader: increased wait rounds for slow boards ([#1085](https://github.com/stlink-org/stlink/pull/1085)) # v1.6.1 @@ -371,6 +378,7 @@ Updates and fixes: - Fixed STM32F2xx memory map (Nicolas Schodet) - Memory map for STM32F42xxx and STM32F43xxx devices (Craig Lilley) - Stm32l0x flash loader (Robin Kreis) +- Use libusb synchronous api ([#194](https://github.com/stlink-org/stlink/pull/194), [#374](https://github.com/stlink-org/stlink/pull/374)) - Fixed segfault when programmer is already busy and `NULL` pointers are in the list ([#256](https://github.com/stlink-org/stlink/pull/256), [#394](https://github.com/stlink-org/stlink/pull/394)) - Send F4 memory-map and features for STM32F429 ([#188](https://github.com/stlink-org/stlink/pull/188), [#196](https://github.com/stlink-org/stlink/pull/196), [#250](https://github.com/stlink-org/stlink/pull/250), [#251](https://github.com/stlink-org/stlink/pull/251)) (Release v1.1.0) - Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/stlink-org/stlink/pull/218), [#288](https://github.com/stlink-org/stlink/pull/288)) (Release v1.1.0) diff --git a/contributors.txt b/contributors.txt index 57801b9ab..38cc9cd42 100644 --- a/contributors.txt +++ b/contributors.txt @@ -74,6 +74,7 @@ Karl Palsson [karlp] Kevlar Harness Kyle Manna Lari Lehtomäki +Luuk van Dijk [lvdlvd] Martin Nowak Matteo Collina Max Chen From c0236dd12c9f07e78b73f774bf028dc102d8f04b Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Thu, 11 Mar 2021 13:22:00 -0500 Subject: [PATCH 1108/1435] Hopefully fix reading an invalid chip ID on STM32WB55 --- src/common.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/common.c b/src/common.c index 99049196d..242b690af 100644 --- a/src/common.c +++ b/src/common.c @@ -1222,8 +1222,34 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { int ret; if (sl->core_id == STM32H7_CORE_ID) { - // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) - ret = stlink_read_debug32(sl, 0x5c001000, chip_id); + /* STM32H7 chipid in 0x5c001000 (RM0433 pg3189) + * However, the STM32H7 is not the only chip with a JTAG + * IDCODE of 0x6ba02477, so we cannot rely solely on this info + * to select the address to read the chip id */ + + uint32_t chip_id_tmp; + // try reading from 0x5c001000 + ret = stlink_read_debug32(sl, 0x5c001000, &chip_id_tmp); + + // Extract the DEV_ID/CHIPID + uint32_t h7_chip_id = chip_id_tmp & 0xfff; + + if(ret != -1){ + // If we successfully read a H7 chip ID, return that + if((h7_chip_id == STLINK_CHIPID_STM32_H74XXX) || + (h7_chip_id == STLINK_CHIPID_STM32_H7AX) || + (h7_chip_id == STLINK_CHIPID_STM32_H72X)) { + *chip_id = chip_id_tmp; + return(ret); + } + } + + // If we had an error or were unsuccessful at reading an H7 + // series chip ID, try reading the chip ID from the default + // address + ret = stlink_read_debug32(sl, 0xE0042000, chip_id); + + } else { // default chipid address ret = stlink_read_debug32(sl, 0xE0042000, chip_id); From eff18d81d9c64ef9eaf4972d800de09be13ff141 Mon Sep 17 00:00:00 2001 From: 2a17 Date: Thu, 11 Mar 2021 23:04:14 +0000 Subject: [PATCH 1109/1435] option byte support improved --- src/st-flash/flash_opts.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index e74ecc1ce..2ef72c12a 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -337,12 +337,27 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { if (ac == 2) { uint32_t addr; - result = get_integer_from_char_array(av[1], &addr); + result = get_integer_from_char_array(av[0], &addr); if (result != 0) { return bad_arg ("addr"); } else { o->addr = (stm32_addr_t) addr; } + uint32_t val; + result = get_integer_from_char_array(av[1], &val); + if (result != 0) { + return bad_arg ("val"); + } else { + o->val = (uint32_t) val; + } + } else { + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) { + return bad_arg ("val"); + } else { + o->val = (uint32_t) val; + } } } else if (o->area == FLASH_OPTION_BYTES_BOOT_ADD) { // expect option bytes boot address if (ac != 1) { return invalid_args("option bytes boot_add write "); } From 93c59cc5c2bacf5901ad4550bf7a9a4041369dac Mon Sep 17 00:00:00 2001 From: 2a17 Date: Thu, 11 Mar 2021 23:49:51 +0000 Subject: [PATCH 1110/1435] spelling mistake 'feature request' changed to 'bug report' in bug report template --- .github/ISSUE_TEMPLATE/bug-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index a1b9d65a0..0e22c2ce9 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -8,7 +8,7 @@ labels: '' Thank you for giving feedback to the stlink project. **NOTICE: Please read and follow instructions in #906 before submitting a ticket. -This feature request will be deleted without notice when not enough information is provided! So please ensure that all fields are filled out.** +This bug report will be deleted without notice when not enough information is provided! So please ensure that all fields are filled out.** - [ ] I made serious effort to avoid creating duplicate or nearly similar issue From 7729fea5ed2bc743c64578f9690c40fff58a9821 Mon Sep 17 00:00:00 2001 From: 2a17 Date: Fri, 12 Mar 2021 12:22:58 +0000 Subject: [PATCH 1111/1435] unused parameter removed, comment and return message updated --- src/st-flash/flash_opts.c | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 2ef72c12a..2ee19bd48 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -328,36 +328,14 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { case FLASH_CMD_WRITE: // TODO: should be boot add 0 and boot add 1 uint32 - if (o->area == FLASH_OPTION_BYTES) { // expect filename and optional address - if (ac >=1 && ac <= 2) { - o->filename = av[0]; - } else { - return invalid_args("write [addr]"); - } - - if (ac == 2) { - uint32_t addr; - result = get_integer_from_char_array(av[0], &addr); - if (result != 0) { - return bad_arg ("addr"); - } else { - o->addr = (stm32_addr_t) addr; - } - uint32_t val; - result = get_integer_from_char_array(av[1], &val); - if (result != 0) { - return bad_arg ("val"); - } else { - o->val = (uint32_t) val; - } + if (o->area == FLASH_OPTION_BYTES) { // expect option byte value + if (ac != 1) { return invalid_args("option byte write "); } + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) { + return bad_arg ("val"); } else { - uint32_t val; - result = get_integer_from_char_array(av[0], &val); - if (result != 0) { - return bad_arg ("val"); - } else { - o->val = (uint32_t) val; - } + o->val = (uint32_t) val; } } else if (o->area == FLASH_OPTION_BYTES_BOOT_ADD) { // expect option bytes boot address if (ac != 1) { return invalid_args("option bytes boot_add write "); } From e5767681f14de9851aa970a9299930ca68b2ed92 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 12 Mar 2021 18:39:08 +0100 Subject: [PATCH 1112/1435] [doc] Corrected tutorial.md Corrected info on --freq argument (Closes #1055) --- doc/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index f13c4c6f1..3a0f16fd9 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -5,7 +5,7 @@ | Option | Tool | Description | Available
      since | | --------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | | --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k
      for the STM32F103C8T6 to assume 128k of flash being present. This option accepts
      decimal (128k), octal 0200k, or hex 0x80k values. Leaving the multiplier out is
      equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional "k"
      or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | -| --freq=n[k][m] | st-flash,
      st-util | The frequency of the SWD/JTAG interface can be specified, to override the default
      1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
      the unit `Hz` being left out. Valid frequencies are `5K, 15K, 25K, 50K, 100K,`
      `125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | +| --freq=n[k][m] | st-flash | The frequency of the SWD/JTAG interface can be specified, to override the default
      1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
      the unit `Hz` being left out. Valid frequencies are: `5K, 15K, 25K, 50K, 100K,`
      `125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | | --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at
      the end of binary file. This may cause some garbage data left after a flash operation.
      This option was enabled by default in earlier releases. | v1.6.1 | | --reset | st-flash | Trigger a reset both before and after flashing. | v1.0.0 | | --version | st-info,
      st-flash,
      st-util | Print version information. | | From dd877b1883b94f4529f3765883f1ce1fe4744fa1 Mon Sep 17 00:00:00 2001 From: anton Date: Sun, 14 Mar 2021 21:09:40 +0500 Subject: [PATCH 1113/1435] Fixing support of stlink v1 --- src/stlink-lib/usb.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 0168834ca..d2b17fad6 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -301,7 +301,7 @@ int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { if (ret == -1) { return(ret); } - ret = send_only(slu, 0, data, len); + ret = send_only(slu, 1, data, len); if (ret == -1) { return(ret); } @@ -431,6 +431,8 @@ int _stlink_usb_status(stlink_t * sl) { } else { sl->core_stat = TARGET_UNKNOWN; } + } else { + sl->core_stat = TARGET_UNKNOWN; } return(0); @@ -469,19 +471,14 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { unsigned char* const cmd = sl->c_buf; ssize_t size; unsigned char* const data = sl->q_buf; - const uint32_t rep_len = sl->version.stlink_v > 1 ? 2 : 0; + const uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 2; int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; // select correct API-Version for entering SWD mode: V1 API (0x20) or V2 API (0x30). cmd[i++] = sl->version.jtag_api == STLINK_JTAG_API_V1 ? STLINK_DEBUG_APIV1_ENTER : STLINK_DEBUG_APIV2_ENTER; cmd[i++] = STLINK_DEBUG_ENTER_SWD; - - if (rep_len == 0) { - size = send_only(slu, 1, cmd, slu->cmd_len); - } else { - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); - } + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_DEBUG_ENTER\n"); From c39ed921e39519eb30084b22b8539d19ae5df741 Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Sun, 14 Mar 2021 20:53:00 -0400 Subject: [PATCH 1114/1435] Implement changes suggested by Ant-ON to select the chipid register --- src/common.c | 36 ++++++++++++++++-------------------- src/stlink-lib/reg.h | 5 +++++ 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/common.c b/src/common.c index 242b690af..a064254d3 100644 --- a/src/common.c +++ b/src/common.c @@ -1227,28 +1227,24 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { * IDCODE of 0x6ba02477, so we cannot rely solely on this info * to select the address to read the chip id */ - uint32_t chip_id_tmp; - // try reading from 0x5c001000 - ret = stlink_read_debug32(sl, 0x5c001000, &chip_id_tmp); - - // Extract the DEV_ID/CHIPID - uint32_t h7_chip_id = chip_id_tmp & 0xfff; - - if(ret != -1){ - // If we successfully read a H7 chip ID, return that - if((h7_chip_id == STLINK_CHIPID_STM32_H74XXX) || - (h7_chip_id == STLINK_CHIPID_STM32_H7AX) || - (h7_chip_id == STLINK_CHIPID_STM32_H72X)) { - *chip_id = chip_id_tmp; - return(ret); - } + uint32_t cpu_id; + *chip_id = 0; + ret = -1; + + // Read the CPU ID as well to determine if this really is an H7 part + if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &cpu_id)) + cpu_id = 0; + + // If it is, read the chipid from the new address + if (sl->core_id == STM32H7_CORE_ID && cpu_id == STLINK_REG_CMx_CPUID_CM7) { + // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) + ret = stlink_read_debug32(sl, 0x5c001000, chip_id); } - // If we had an error or were unsuccessful at reading an H7 - // series chip ID, try reading the chip ID from the default - // address - ret = stlink_read_debug32(sl, 0xE0042000, chip_id); - + if (*chip_id == 0) { + // default chipid address + ret = stlink_read_debug32(sl, 0xE0042000, chip_id); + } } else { // default chipid address diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 6d2c9f1af..5a796d7e1 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -3,6 +3,11 @@ #define STLINK_REG_CM3_CPUID 0xE000ED00 +#define STLINK_REG_CMx_CPUID_CM0 0x410CC200 +#define STLINK_REG_CMx_CPUID_CM3 0x412FC230 +#define STLINK_REG_CMx_CPUID_CM7 0x411FC272 + + #define STLINK_REG_CM3_FP_CTRL 0xE0002000 // Flash Patch Control Register #define STLINK_REG_CM3_FP_COMPn(n) (0xE0002008 + n*4) #define STLINK_REG_CM3_FP_CTRL_KEY (1 << 1) From 125cb2d7634d5cbc916e9c4bac6ddf80407ab605 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 17 Mar 2021 23:26:48 +0100 Subject: [PATCH 1115/1435] General Project Update - Updated CHANGELOG.md - Updated README.md - Formatting fixes -[doc] Updated tested devices & boards --- CHANGELOG.md | 10 +- README.md | 61 +++++----- doc/devices_boards.md | 253 +++++++++++++++++++++-------------------- doc/version_support.md | 112 +++++++++--------- 4 files changed, 217 insertions(+), 219 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 912092b65..cacd79eef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ Features: Updates & changes: -- [doc] Added note on `(gdb) run` command (commit [#03793d4](https://github.com/stlink-org/stlink/commit/03793d42b6078344a9ef8ad55f1d5d0fc19e486e), [#276](https://github.com/stlink-org/stlink/pull/276)) +- [doc] Added note on `(gdb) run` command (commit [#03793d4](https://github.com/stlink-org/stlink/commit/03793d42b6078344a9ef8ad55f1d5d0fc19e486e), [#267](https://github.com/stlink-org/stlink/pull/267)) - [doc] `st-flash --reset` parameter (one solution for #356) ([#642](https://github.com/stlink-org/stlink/pull/642)) - [refactoring] General maintenance ([#864](https://github.com/stlink-org/stlink/pull/864), [#976](https://github.com/stlink-org/stlink/pull/976), [#978](https://github.com/stlink-org/stlink/pull/978)) - Imported debian pkg-settings ([#986](https://github.com/stlink-org/stlink/pull/986)) @@ -42,13 +42,17 @@ Fixes: - Fixed `connect under reset` for `st-flash` and `st-util` ([#983](https://github.com/stlink-org/stlink/pull/983)) - Fix for `mmap() size_t overflow` in `st-flash` ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) - [regression] `stlink-gui` installation issue on Ubuntu-18.04 ([#1001](https://github.com/stlink-org/stlink/pull/1001), [#1004](https://github.com/stlink-org/stlink/pull/1004), [#1006](https://github.com/stlink-org/stlink/pull/1006)) -- `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027)) +- `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027), [#1064](https://github.com/stlink-org/stlink/pull/1064), [#1065](https://github.com/stlink-org/stlink/pull/1065)) - [doc] Fixed wrong path for `rules.d` folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) - Use vl flashloader for all STM32F1 series ([#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) +- st-util v1.6.1 does not recognize option --freq (commit [#e576768](https://github.com/stlink-org/stlink/commit/e5767681f14de9851aa970a9299930ca68b2ed92), [#1055](https://github.com/stlink-org/stlink/pull/1055)) - Fixed `gettimeofday` for MSVC ([#1074](https://github.com/stlink-org/stlink/pull/1074)) - Bugfixes for compilation with clang ([#1076](https://github.com/stlink-org/stlink/pull/1076), [#1078](https://github.com/stlink-org/stlink/pull/1078)) - Fixed compilation with GCC 11 ([#1077](https://github.com/stlink-org/stlink/pull/1077)) - [regression] Flash_loader: increased wait rounds for slow boards ([#1085](https://github.com/stlink-org/stlink/pull/1085)) +- Fixed support for writing option bytes ([#1102](https://github.com/stlink-org/stlink/pull/1102)) +- [doc] Corrected spelling mistake in bug report template ([#1103](https://github.com/stlink-org/stlink/pull/1103)) +- Fixed support for STLINK/V1 programmer ([#1045](https://github.com/stlink-org/stlink/pull/1045), [#1105](https://github.com/stlink-org/stlink/pull/1105)) # v1.6.1 @@ -380,8 +384,10 @@ Updates and fixes: - Stm32l0x flash loader (Robin Kreis) - Use libusb synchronous api ([#194](https://github.com/stlink-org/stlink/pull/194), [#374](https://github.com/stlink-org/stlink/pull/374)) - Fixed segfault when programmer is already busy and `NULL` pointers are in the list ([#256](https://github.com/stlink-org/stlink/pull/256), [#394](https://github.com/stlink-org/stlink/pull/394)) +- Fixed issue where "unknown chip id!" was seen every other time ([#352](https://github.com/stlink-org/stlink/pull/352), [#367](https://github.com/stlink-org/stlink/pull/367), [#381](https://github.com/stlink-org/stlink/pull/381)) - Send F4 memory-map and features for STM32F429 ([#188](https://github.com/stlink-org/stlink/pull/188), [#196](https://github.com/stlink-org/stlink/pull/196), [#250](https://github.com/stlink-org/stlink/pull/250), [#251](https://github.com/stlink-org/stlink/pull/251)) (Release v1.1.0) - Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/stlink-org/stlink/pull/218), [#288](https://github.com/stlink-org/stlink/pull/288)) (Release v1.1.0) +- Reset: st-flash does not work when CPU is in sleep mode ([#62](https://github.com/stlink-org/stlink/pull/62)) (Release v1.0.0) - Corrected flash size register address for STM32F2 devices ([#278](https://github.com/stlink-org/stlink/pull/278)) (Release v1.0.0) Chip support added for: diff --git a/README.md b/README.md index 3799f46d2..8a8600947 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -Open source version of the STMicroelectronics STlink Tools -========================================================== +# Open source version of the STMicroelectronics STlink Tools [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/stlink-org/stlink.svg)](https://github.com/stlink-org/stlink/releases/latest) @@ -12,42 +11,40 @@ Open source version of the STMicroelectronics STlink Tools Recent new features and bugfixes can be found in the [Changelog](CHANGELOG.md) of this software project. - #### License The stlink library and tools are licensed under the **[BSD-3 License](LICENSE.md)**. - ## Introduction STLink is an open source toolset to program and debug STM32 devices and boards manufactured by STMicroelectronics. It supports several so called STLINK programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG/SWD. There are four generations available on the market which are _all_ supported by this toolset: -* **STLINK/v1** _[obsolete as of 21-11-2019, continued support by this toolset] *)_ +- **STLINK/V1** _[obsolete as of 21-11-2019, continued support by this toolset] \*)_ - transport layer: SCSI passthru commands over USB - stand-alone programmer and present on STM32VL Discovery boards -* **STLINK/v2** +- **STLINK/V2** - transport layer: raw USB commands - stand-alone programmer and present on STM32L Discovery and Nucleo boards -* **STLINK/v2-1** +- **STLINK/V2-1** - transport layer: raw USB commands - present on some STM32 Nucleo boards -* **STLINK/v3** +- **STLINK/V3** - transport layer: raw USB commands - stand-alone programmer -_*)_ **Note: Support on macOS is limited to 10.14 - 10.15. Any later versions are no longer compatible with the STLINK/v1 due to technical reasons.** +_\*)_ **Note: Support for the STLINK/V1 on macOS is limited to 10.14 - 10.15. Due to the deprecation and removal of macOS Kernel Extensions (KEXT) there will be no support for this programmer on macOS 11 or any later version.** On the user level there is no difference in handling or operation between these different revisions. The STlink toolset includes: -* `st-info` - a programmer and chip information tool -* `st-flash` - a flash manipulation tool -* `st-util` - a GDB server (supported in Visual Studio Code / VSCodium via the [Cortex-Debug](https://github.com/Marus/cortex-debug) plugin) -* `stlink-lib` - a communication library -* `stlink-gui` - a GUI-Interface _[optional]_ - +- `st-info` - a programmer and chip information tool +- `st-flash` - a flash manipulation tool +- `st-trace` - a logging tool to record information on execution +- `st-util` - a GDB server (supported in Visual Studio Code / VSCodium via the [Cortex-Debug](https://github.com/Marus/cortex-debug) plugin) +- `stlink-lib` - a communication library +- `stlink-gui` - a GUI-Interface _[optional]_ ## Supported operating systems and hardware combinations @@ -58,12 +55,10 @@ Supported operating systems are listed in [version_support.md](doc/version_suppo The `stlink` toolset continues to maintain backwards compatibility with the **STLINK/v1** programmer.
      Please note that on macOS this support is limited to versions 10.13 - 10.15. - ## Tutorial & HOWTO Our [tutorial](doc/tutorial.md) may help you along with some advanced tasks and additional info. - ## Installation **Windows**: @@ -77,8 +72,8 @@ Alternatively one may compile and install from source as described in our [compi We recommend to install from: -* [homebrew](https://formulae.brew.sh/formula/stlink) or -* [MacPorts](https://ports.macports.org/port/stlink) +- [homebrew](https://formulae.brew.sh/formula/stlink) or +- [MacPorts](https://ports.macports.org/port/stlink) Alternatively one can compile and install from source as described in our [compiling manual](doc/compiling.md#macOS). @@ -88,30 +83,28 @@ We recommend to install `stlink-tools` from the package repository of the used d **Note:** As packages distributed via the [Debian](https://packages.debian.org/buster/stlink-tools) and [Ubuntu](https://packages.ubuntu.com/stlink-tools) repositories differ from our self-maintained deb-package, we recommend to use the latter instead (see link below). It provides the opportunity to handle and fix user-reported package issues directly within the project and is not redundant to any limitations deriving from external maintenance guidelines. -* Debian Linux: [(Link)](https://github.com/stlink-org/stlink/releases) -* Ubuntu Linux: [(Link)](https://github.com/stlink-org/stlink/releases) -* Arch Linux: [(Link)](https://www.archlinux.org/packages/community/x86_64/stlink) -* Alpine Linux: [(Link)](https://pkgs.alpinelinux.org/packages?name=stlink) -* Fedora: [(Link)](https://src.fedoraproject.org/rpms/stlink) -* Gentoo Linux: [(Link)](https://packages.gentoo.org/packages/dev-embedded/stlink) +- Debian Linux: [(Link)](https://github.com/stlink-org/stlink/releases) +- Ubuntu Linux: [(Link)](https://github.com/stlink-org/stlink/releases) +- Arch Linux: [(Link)](https://www.archlinux.org/packages/community/x86_64/stlink) +- Alpine Linux: [(Link)](https://pkgs.alpinelinux.org/packages?name=stlink) +- Fedora: [(Link)](https://src.fedoraproject.org/rpms/stlink) +- Gentoo Linux: [(Link)](https://packages.gentoo.org/packages/dev-embedded/stlink) **Other Operating Systems**: -* RedHat/CentOS 8: Users can install from [EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel8) -* FreeBSD: Users can install from [freshports](https://www.freshports.org/devel/stlink) - +- RedHat/CentOS 8: Users can install from [EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel8) +- FreeBSD: Users can install from [freshports](https://www.freshports.org/devel/stlink) ## Installation from source (advanced users) When there is no executable available for your platform or you need the latest (possible unstable) version you need to compile the toolset yourself. This procedure is explained in the [compiling manual](doc/compiling.md). - ## Contributing and versioning -* The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) -* Before creating a pull request, please _ALWAYS_ open a new issue for the discussion of the intended new features. Bugfixes don't require a discussion via a ticket-issue. However they should always be described in a few words as soon as they appear to help others as well. -* Contributors and/or maintainers may submit comments or request changes to patch-proposals and/or pull-requests. -* **ATTENTION: _NEVER EVER_ use the '#' character to count-up single points within a listing as '#' is _exclusively_ reserved for referencing GitHub issues and pull-requests. Otherwise you accidentally introduce false cross references within the project.** -* Please start new forks from the develop branch, as pull requests will go into this branch as well. +- The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) +- Before creating a pull request, please _ALWAYS_ open a new issue for the discussion of the intended new features. Bugfixes don't require a discussion via a ticket-issue. However they should always be described in a few words as soon as they appear to help others as well. +- Contributors and/or maintainers may submit comments or request changes to patch-proposals and/or pull-requests. +- **ATTENTION: _NEVER EVER_ use the '#' character to count-up single points within a listing as '#' is _exclusively_ reserved for referencing GitHub issues and pull-requests. Otherwise you accidentally introduce false cross references within the project.** +- Please start new forks from the develop branch, as pull requests will go into this branch as well. Please also refer to our [Contribution Guidelines](CONTRIBUTING.md). diff --git a/doc/devices_boards.md b/doc/devices_boards.md index 97094b972..6396738c4 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -1,15 +1,13 @@ -Boards supported by the STlink toolset -====================================== +# Boards supported by the STlink toolset -The following devices are supported by the STlink tools. - -All Boards are expected to work with ST-Link-v2 programmers. +The following devices are supported by the stlink toolset. +All Boards are expected to work with ST-LINK/V2 programmers. **STM32F0 / ARM Cortex M0 / Core-ID: 0x0bb11477 (STM32F0_CORE_ID)** | Chip-ID | Product-Code | -| --- | --- | +| ------- | ------------------- | | 0x440 | STM32F0**30**x**8** | | 0x442 | STM32F0**30**x**C** | | 0x444 | STM32F0**3**xx**4** | @@ -22,19 +20,19 @@ All Boards are expected to work with ST-Link-v2 programmers. | 0x448 | STM32F0**72**xx | | 0x442 | STM32F0**9**xxx | -Tested boards [incl. STLink programmers]: -* Nucleo-F030R8 [v2-1] -* Nucleo-32 [v2-1] -* STM32F0-Discovery [v2] -* STM320518-EVAL -* Nucleo-F072RB [v2-1] -* Nucleo-F091RC [v2-1] +Tested boards [incl. STLINK programmers]: +- Nucleo-F030R8 [v2-1] +- Nucleo-F072RB [v2-1] +- Nucleo-F091RC [v2-1] +- Nucleo-32 [v2-1] +- STM32F0-Discovery [v2] +- STM320518-EVAL **STM32F1 / ARM Cortex M3 / Core-ID: 0x1ba01477 (STM32F1_CORE_ID)** | Product-Code | Product Line | -| --- | --- | +| ----------------- | ----------------------- | | STM32F10**0**yyxx | Value line (V) | | STM32F10**1**yyxx | Access line (A) | | STM32F10**2**yyxx | USB Access line (USB-A) | @@ -42,86 +40,83 @@ Tested boards [incl. STLink programmers]: | STM32F10**5**yyxx | Connectivity line (C) | | STM32F10**7**yyxx | Connectivity line (C) | -| Chip-ID | Product Line | Code (yy) | V | A | USB-A | P | C | -| --- | --- | --- | --- | --- | --- | --- | --- | -| 0x412 | Low-Density | x4 x6 | F100 | F101 | F102 | F103 | | -| 0x410 | Medium Density | x8 xB | | F101 | F102 | F103 | | -| 0x414 | High density | xC xD xE | | F101 | F103 | | | +| Chip-ID | Product Line | Code (yy) | V | A | USB-A | P | C | +| ------- | -------------------- | --------- | ---- | ---- | ----- | ---- | -------------- | +| 0x412 | Low-Density | x4 x6 | F100 | F101 | F102 | F103 | | +| 0x410 | Medium Density | x8 xB | | F101 | F102 | F103 | | +| 0x414 | High density | xC xD xE | | F101 | F103 | | | | 0x418 | STM32F105xx/107xx | x8 xB xC | | | | | F105
      F107 | -| 0x420 | Medium density value | x8 xB | F100 | | | | | -| 0x428 | High density Value | xC xD xE | F100 | | | | | -| 0x430 | XL-Density | xF xG | | F101 | | F103 | | +| 0x420 | Medium density value | x8 xB | F100 | | | | | +| 0x428 | High density Value | xC xD xE | F100 | | | | | +| 0x430 | XL-Density | xF xG | | F101 | | F103 | | -Tested boards [incl. STLink programmers]: -* STM32VL-Discovery (STM32F100RBT6) with STLink-v1 [v1], [v2] -* STM32F103-Bluepill: C8Tx & R8xx [v2] -* Nucleo-F103RB [v2-1] -* HY-STM32 (STM32F103VETx) [v1, v2] -* DecaWave EVB1000 (STM32F105RCTx) [v1, v2] +Tested boards [incl. STLINK programmers]: +- STM32VL-Discovery (STM32F100RBT6) with STLINK/V1 [v1], [v2] +- STM32F103-Bluepill: C8Tx & R8xx [v2] +- Nucleo-F103RB [v2-1] +- HY-STM32 (STM32F103VETx) [v1, v2] +- DecaWave EVB1000 (STM32F105RCTx) [v1, v2] **STM32F2 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32F2_CORE_ID)** -| Chip-ID | Product-Code | Product Line | -| --- | --- | --- | -| 0x411 | STM32F2yyxx | (all devices) | - +| Chip-ID | Product-Code | Product Line | +| ------- | ------------ | ------------- | +| 0x411 | STM32F2yyxx | (all devices) | **STM32F1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM3F1c_CORE_ID)** -| Product-Code | Chip-ID | STLink
      Programmer | Boards | -| --- | --- | --- | --- | -| CKS32F103C8Tx | 0x410 | v2 | "STM32"-Bluepill ( _**Fake-Marking !**_ )
      STM32F103C8T6 clone from China Key Systems (CKS) | -| CKS32F103C8Tx | 0x410 | v2 | CKS32-Bluepill (Clone)
      STM32F103C8T6 clone from China Key Systems (CKS) | - +| Product-Code | Chip-ID | STLink
      Programmer | Boards | +| ------------- | ------- | ---------------------- | ----------------------------------------------------------------------------------------------- | +| CKS32F103C8Tx | 0x410 | v2 | "STM32"-Bluepill ( _**Fake-Marking !**_ )
      STM32F103C8T6 clone from China Key Systems (CKS) | +| CKS32F103C8Tx | 0x410 | v2 | CKS32-Bluepill (Clone)
      STM32F103C8T6 clone from China Key Systems (CKS) | **STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3_CORE_ID)** -| Product-Code | Product Line | -| --- | --- | -| STM32F3**01**yyxx | Access line (A) | -| STM32F3**02**yyxx | USB & CAN line (USB/CAN) | -| STM32F3**03**yyxx | Performance line (P) | -| STM32F3**34**yy | Digital Power line (DP) | -| STM32F3**73**yy | Precision Measurement line (PM) 64k/16k / 128k/24k / 265k/32k | -| STM32F3**18**yy | General Purpose line (GP) 64k/16k | -| STM32F3**28**yy | General Purpose line (GP) 64k/16k | -| STM32F3**58**yy | General Purpose line (GP) 265k/48k | -| STM32F3**78**yy | Precision Measurement line (PM) 265k/32k | -| STM32F3**98**yy | General Purpose line (GP) 512k/80k | - -| Chip-ID | Product Line | Code (yy) | A | USB/CAN | P | others | -| --- | --- | --- | --- | --- | --- | --- | -| 0x422 | _N/A_ | xB xC | | F302 | F303 | | -| 0x422 | _N/A_ | - | | | | F358 | +| Product-Code | Product Line | +| ----------------- | ------------------------------------------------------------- | +| STM32F3**01**yyxx | Access line (A) | +| STM32F3**02**yyxx | USB & CAN line (USB/CAN) | +| STM32F3**03**yyxx | Performance line (P) | +| STM32F3**34**yy | Digital Power line (DP) | +| STM32F3**73**yy | Precision Measurement line (PM) 64k/16k / 128k/24k / 265k/32k | +| STM32F3**18**yy | General Purpose line (GP) 64k/16k | +| STM32F3**28**yy | General Purpose line (GP) 64k/16k | +| STM32F3**58**yy | General Purpose line (GP) 265k/48k | +| STM32F3**78**yy | Precision Measurement line (PM) 265k/32k | +| STM32F3**98**yy | General Purpose line (GP) 512k/80k | + +| Chip-ID | Product Line | Code (yy) | A | USB/CAN | P | others | +| ------- | ------------ | --------- | ---- | ------- | ---- | -------------- | +| 0x422 | _N/A_ | xB xC | | F302 | F303 | | +| 0x422 | _N/A_ | - | | | | F358 | | 0x432 | _N/A_ | - | | | | F373
      F378 | -| 0x438 | _N/A_ | x4 x6 x8 | | | F303 | | +| 0x438 | _N/A_ | x4 x6 x8 | | | F303 | | | 0x438 | _N/A_ | - | | | | F334
      F328 | -| 0x439 | _N/A_ | x4 x6 x8 | F301 | F302 | | | -| 0x439 | _N/A_ | - | | | | F318 | -| 0x446 | _N/A_ | xD xE | | F302 | F303 | | -| 0x446 | _N/A_ | - | | | | F398 | +| 0x439 | _N/A_ | x4 x6 x8 | F301 | F302 | | | +| 0x439 | _N/A_ | - | | | | F318 | +| 0x446 | _N/A_ | xD xE | | F302 | F303 | | +| 0x446 | _N/A_ | - | | | | F398 | -Tested boards [incl. STLink programmers]: -* Nucleo-F302K8 [v2-1] -* Nucleo-F303K8 [v2-1] -* STM32F3348-Discovery [v2-1] -* Nucleo-F334R8 [v2-1] -* STM32F303-Discovery [v2] -* Nucleo-F303RE [v2-1] +Tested boards [incl. STLINK programmers]: +- Nucleo-F302K8 [v2-1] +- Nucleo-F303K8 [v2-1] +- Nucleo-F303RE [v2-1] +- Nucleo-F334R8 [v2-1] +- STM32F303-Discovery [v2] +- STM32F3348-Discovery [v2-1] **STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3c_CORE_ID)** -| Product-Code | Chip-ID | STLink
      Programmer | Boards | -| --- | --- | --- | --- | -| GD32F303VGT6 | 0x430 | _N/A_ | STM32F303 clone from GigaDevice GD)
      _unsupported_ | - +| Product-Code | Chip-ID | STLink
      Programmer | Boards | +| ------------ | ------- | ---------------------- | ------------------------------------------------------ | +| GD32F303VGT6 | 0x430 | _N/A_ | STM32F303 clone from GigaDevice GD)
      _unsupported_ | **STM32F4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F4_CORE_ID)** | Chip-ID | Product-Code | -| --- | --- | +| ------- | ------------------- | | 0x413 | STM32F4**0**xxx | | 0x413 | STM32F4**1**xxx | | 0x419 | STM32F4**2**xxx | @@ -139,20 +134,20 @@ Tested boards [incl. STLink programmers]: | 0x463 | STM32F4**13**xx | | 0x463 | STM32F4**23**xx | -Tested boards [incl. STLink programmers]: -* STM32F407-Discovery [v2] -* 32F411E-Discovery with gyro, audio [v2] -* 32F429I-Discovery with LCD [v2] -* 32F439VIT6-Discovery [v2] (reseated MCU) -* Nucleo-F401RE [v2-1] -* Nucleo-F411RE [v2-1] -* 32F413H-Discovery [v2-1] +Tested boards [incl. STLINK programmers]: +- Nucleo-F401RE [v2-1] +- Nucleo-F411RE [v2-1] +- STM32F407-Discovery [v2] +- STM32F411E-Discovery with gyro, audio [v2] +- STM32F413H-Discovery [v2-1] +- STM32F429I-Discovery with LCD [v2] +- STM32F439VIT6-Discovery [v2] (reseated MCU) **STM32F7 / ARM Cortex M7F / Core-ID: 0x5ba02477 (STM32F7_CORE_ID)** | Chip-ID | Product-Code | -| --- | --- | +| ------- | --------------- | | 0x452 | STM32F7**2**xxx | | 0x452 | STM32F7**3**xxx | | 0x449 | STM32F7**4**xxx | @@ -160,37 +155,45 @@ Tested boards [incl. STLink programmers]: | 0x451 | STM32F7**6**xxx | | 0x451 | STM32F7**7**xxx | -Tested boards [incl. STLink programmers]: -* STM32F756NGHx evaluation board [v2-1] -* 32F769I-Discovery [v2-1] -* Nucleo-F722ZE [v2-1] -* Nucleo-F746ZG [v2-1] +Tested boards [incl. STLINK programmers]: + +- Nucleo-F722ZE [v2-1] +- Nucleo-F746ZG [v2-1] +- STM32F756NGHx evaluation board [v2-1] +- STM32F769I-Discovery [v2-1] + +**STM32H7 / ARM Cortex M7F / Core-ID: 0x6ba02477 (STM32H7_CORE_ID)** + +| Chip-ID | Product-Code | +| ------- | -------------- | +| 0x450 | STM32H74x/H75x | + +Tested boards [incl. STLINK programmers]: +- Nucleo-H745I-Q [v3] **STM32G0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32G0_CORE_ID)** | Chip-ID | Product-Code | -| --- | --- | +| ------- | --------------- | | 0x466 | STM32G0**3**xxx | | 0x466 | STM32G0**4**xxx | | 0x460 | STM32G0**7**xxx | | 0x460 | STM32G0**8**xxx | - **STM32G4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32G4_CORE_ID)** | Chip-ID | Product-Code | -| --- | --- | +| ------- | --------------- | | 0x468 | STM32G4**31**xx | | 0x468 | STM32G4**41**xx | | 0x469 | STM32G4**7**xxx | | 0x469 | STM32G4**8**xxx | - **STM32L0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32L0_CORE_ID)** | Chip-ID | Product-Code | -| --- | --- | +| ------- | --------------- | | 0x457 | STM32L0**1**xxx | | 0x457 | STM32L0**2**xxx | | 0x425 | STM32L0**31**xx | @@ -200,14 +203,14 @@ Tested boards [incl. STLink programmers]: | 0x447 | STM32L0**7**xxx | | 0x447 | STM32L0**8**xxx | -Tested boards [incl. STLink programmers]: -* Nucleo-L053R8 [v2-1] +Tested boards [incl. STLINK programmers]: +- Nucleo-L053R8 [v2-1] **STM32L1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32L1_CORE_ID)** | Chip-ID | Product-Code | -| --- | --- | +| ------- | ---------------- | | 0x416 | STM32L1xxx**6** | | 0x416 | STM32L1xxx**8** | | 0x416 | STM32L1xxx**B** | @@ -218,42 +221,42 @@ Tested boards [incl. STLink programmers]: | 0x436 | STM32L1xxx**D** | | 0x437 | STM32L1xxx**E** | -Tested boards [incl. STLink programmers]: -* Nucleo-L152RE [v2-1] -* 32L152C-Discovery [v2] +Tested boards [incl. STLINK programmers]: +- Nucleo-L152RE [v2-1] +- STM32L152C-Discovery [v2] **STM32L4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32L4_CORE_ID)** -| Chip-ID | Product-Code | -| --- | --- | -| 0x464 | STM32L4**12**xx | -| 0x464 | STM32L4**22**xx | -| 0x435 | STM32L4**3**xxx | -| 0x435 | STM32L4**4**xxx | -| 0x462 | STM32L4**5**xxx | -| 0x462 | STM32L4**6**xxx | -| 0x415 | STM32L4**7**xxx | -| 0x415 | STM32L4**8**xxx | -| 0x461 | STM32L4**96**xx | -| 0x461 | STM32L4**A6**xx | -| 0x470 | STM32L4**R**xx | -| 0x470 | STM32L4**S**xx | -| 0x471 | STM32L4**P5**xx | -| 0x471 | STM32L4**Q5**xx | - -Tested boards [incl. STLink programmers]: -* Nucleo-L432KC [v2-1] -* Nucleo-L452RE [v2-1] -* Nucleo-L476RG [v2-1] -* Nucleo-L496ZG [v2-1] -* 32L4R9I-Discovery [v2-1] - +| Chip-ID | Product-Code | +| ------- | --------------- | +| 0x464 | STM32L4**12**xx | +| 0x464 | STM32L4**22**xx | +| 0x435 | STM32L4**3**xxx | +| 0x435 | STM32L4**4**xxx | +| 0x462 | STM32L4**5**xxx | +| 0x462 | STM32L4**6**xxx | +| 0x415 | STM32L4**7**xxx | +| 0x415 | STM32L4**8**xxx | +| 0x461 | STM32L4**96**xx | +| 0x461 | STM32L4**A6**xx | +| 0x470 | STM32L4**R**xx | +| 0x470 | STM32L4**S**xx | +| 0x471 | STM32L4**P5**xx | +| 0x471 | STM32L4**Q5**xx | + +Tested boards [incl. STLINK programmers]: + +- Nucleo-L432KC [v2-1] +- Nucleo-L452RE [v2-1] +- Nucleo-L476RG [v2-1] +- Nucleo-L496ZG [v2-1] +- STM32L4R9I-Discovery [v2-1] **STM32W / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32W_CORE_ID)** -| Chip-ID | Product-Code | -| --- | --- | -| 0x495 | STM32WB**50**xx | -| 0x495 | STM32WB**55**xx | -| 0x497 | STM32WLE**5**xx | +| Chip-ID | Product-Code | +| ------- | --------------- | +| 0x495 | STM32WB**50**xx | +| 0x495 | STM32WB**55**xx | +| 0x497 | STM32WLE**5**xx | diff --git a/doc/version_support.md b/doc/version_support.md index afa2d2bd7..eca491b79 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -1,8 +1,7 @@ - _Source:_ pkgs.org - [libusb](https://pkgs.org/search/?q=libusb); [cmake](https://pkgs.org/search/?q=cmake); [gtk](https://pkgs.org/search/?q=gtk) (as of Apr 2020) - ## Supported Operating Systems + ### Microsoft Windows On Windows users should ensure that cmake 3.17.0 is installed.
      @@ -10,72 +9,69 @@ Up on compiling c-make will check **automatically**, whether `libusb` 1.0.20 or If this is not the case, the installation routine will download the latest version (1.0.23 at the time of writing).
      Thus no user interaction regarding libusb is necessary. -* Windows 10 -* Windows 8.1 - +- Windows 10 +- Windows 8.1 ### Apple macOS -| Package Repository | libusb
      version | cmake
      version | gtk-3
      version | Supported macOS versions | -| --- | --- | --- | --- | --- | -| homebrew | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3 | 10.12 (Sierra)- 10.15 (Catalina) | -| MacPorts | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | 10.6 (Snow Leopard) - 10.15 (Catalina) | - -NOTE: In order to use a STLINK/v1 programmer on macOS, versions 10.14 or 10.15 are required. +| Package Repository | libusb
      version | cmake
      version | gtk-3
      version | Supported macOS versions | +| ------------------ | ------------------- | ------------------ | ------------------ | -------------------------------------- | +| homebrew | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3 | 10.12 (Sierra)- 10.15 (Catalina) | +| MacPorts | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | 10.6 (Snow Leopard) - 10.15 (Catalina) | +NOTE: In order to use a STLINK/V1 programmer on macOS, versions 10.14 or 10.15 are required. ### Linux-/Unix-based: -| Operating System | libusb
      version | cmake
      version | gtk-3
      version | Notes | -| --- | --- | --- | --- | --- | -| Alpine Edge | 1.0.23 | 3.17.0 | 3.99.0
      gtk+3.0 | | -| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | 3.24.18
      libgtk+3 | | -| Arch Linux | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | -| Fedora Rawhide | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | named `libusbx`, but
      `libusb`-codebase is used | -| KaOS | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | -| OpenMandriva Cooker | 1.0.23 | 3.17.0 | 3.24.18
      libgtk+3.0
      lib64gtk+3.0 | | -| PCLinuxOS | 1.0.23
      lib64usb1.0 | 3.17.0 | 3.24.18
      lib64gtk+3.0 | | -| Slackware Current | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3 | | -| Solus | 1.0.23 | 3.16.5 | 3.24.16
      libgtk-3 | | -| Debian Sid | 1.0.23 | 3.16.3 | 3.24.18
      libgtk-3 | | -| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | 3.24.13
      libgtk+3.0
      lib64gtk+3.0 | | -| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | 3.24.17
      libgtk-3 | | -| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | 3.24.16
      gtk3 | | -| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.13
      gtk+3.0 | | -| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | 3.24.12
      libgtk-3 | | -| Mageia Cauldron | 1.0.22 | 3.17.0 | 3.24.18
      libgtk+3.0
      lib64gtk+3.0 | | -| NetBSD 9.0 | 1.0.22 | 3.16.1 | 3.24.12
      gtk+3 | | -| NetBSD 8.1 | 1.0.22 | 3.16.1 | 3.24.12
      gtk+3 | | -| NetBSD 7.2 | 1.0.22 | 3.16.1 | _N/A_ | | -| Alpine 3.10 | 1.0.22 | 3.14.5 | 3.24.8
      gtk+3.0 | | -| Fedora 31 | 1.0.22 | 3.14.5 | 3.24.12
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | -| Mageia 7.1 | 1.0.22 | 3.14.3 | 3.24.8
      libgtk+3.0
      lib64gtk+3.0 | | -| Fedora 30 | 1.0.22 | 3.14.2 | 3.24.8
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | -| Debian 10 (Buster) | 1.0.22 | 3.13.4 | 3.24.5
      libgtk-3 | | -| Alpine 3.9 | 1.0.22 | 3.13.0 | 3.24.1
      gtk+3.0 | | -| CentOS 8 | 1.0.22 | 3.11.4 | 3.22.30
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | -| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | 3.24.14
      gtk3 | | -| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | 3.22.30
      gtk3 | | -| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | 3.22.30
      libgtk-3 | | -| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | 3.22.11
      libgtk-3 | | -| Slackware 14.2 | **1.0.20** | 3.5.2 | 3.18.9
      gtk+3 | | -| Ubuntu 16.04 LTS (Xenial Xerus) | **1.0.20** | 3.5.1 | 3.18.9
      libgtk-3 | | -| OpenMandriva Lx 3.0 | **1.0.20** | **3.4.2** | 3.18.9
      libgtk+3.0
      lib64gtk+3.0 | | -| FreeBSD 13 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-13.0r358841
      (integrated) | -| FreeBSD 12 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-11.0r261448_4
      (integrated) | -| FreeBSD 11 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-11.0r261448_4
      (integrated) | - +| Operating System | libusb
      version | cmake
      version | gtk-3
      version | Notes | +| -------------------------------- | ----------------------- | ------------------ | ----------------------------------------- | --------------------------------------------------- | --------------------------------------------------- | +| Alpine Edge | 1.0.23 | 3.17.0 | 3.99.0
      gtk+3.0 | | +| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | 3.24.18
      libgtk+3 | | +| Arch Linux | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | +| Fedora Rawhide | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | named `libusbx`, but
      `libusb`-codebase is used | +| KaOS | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | +| OpenMandriva Cooker | 1.0.23 | 3.17.0 | 3.24.18
      libgtk+3.0
      lib64gtk+3.0 | | +| PCLinuxOS | 1.0.23
      lib64usb1.0 | 3.17.0 | 3.24.18
      lib64gtk+3.0 | | +| Slackware Current | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3 | | +| Solus | 1.0.23 | 3.16.5 | 3.24.16
      libgtk-3 | | +| Debian Sid | 1.0.23 | 3.16.3 | 3.24.18
      libgtk-3 | | +| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | 3.24.13
      libgtk+3.0
      lib64gtk+3.0 | | +| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | 3.24.17
      libgtk-3 | | +| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | 3.24.16
      gtk3 | | +| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.13
      gtk+3.0 | | +| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | 3.24.12
      libgtk-3 | | +| Mageia Cauldron | 1.0.22 | 3.17.0 | 3.24.18
      libgtk+3.0
      lib64gtk+3.0 | | +| NetBSD 9.0 | 1.0.22 | 3.16.1 | 3.24.12
      gtk+3 | | +| NetBSD 8.1 | 1.0.22 | 3.16.1 | 3.24.12
      gtk+3 | | +| NetBSD 7.2 | 1.0.22 | 3.16.1 | _N/A_ | | +| Alpine 3.10 | 1.0.22 | 3.14.5 | 3.24.8
      gtk+3.0 | | +| Fedora 31 | 1.0.22 | 3.14.5 | 3.24.12
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | +| Mageia 7.1 | 1.0.22 | 3.14.3 | 3.24.8
      libgtk+3.0
      lib64gtk+3.0 | | +| Fedora 30 | 1.0.22 | 3.14.2 | 3.24.8
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | +| Debian 10 (Buster) | 1.0.22 | 3.13.4 | 3.24.5
      libgtk-3 | | +| Alpine 3.9 | 1.0.22 | 3.13.0 | 3.24.1
      gtk+3.0 | | +| CentOS 8 | 1.0.22 | 3.11.4 | 3.22.30
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | +| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | 3.24.14
      gtk3 | | +| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | 3.22.30
      gtk3 | | +| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | 3.22.30
      libgtk-3 | | +| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | 3.22.11
      libgtk-3 | | +| Slackware 14.2 | **1.0.20** | 3.5.2 | 3.18.9
      gtk+3 | | +| Ubuntu 16.04 LTS (Xenial Xerus) | **1.0.20** | 3.5.1 | 3.18.9
      libgtk-3 | | +| OpenMandriva Lx 3.0 | **1.0.20** | **3.4.2** | 3.18.9
      libgtk+3.0
      lib64gtk+3.0 | | +| FreeBSD 13 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-13.0r358841
      (integrated) | +| FreeBSD 12 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-11.0r261448_4
      (integrated) | +| FreeBSD 11 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-11.0r261448_4
      (integrated) | ## Unsupported Operating Systems (as of Release v1.6.1) -| Operating System | libusb
      version | cmake
      version | End of
      OS-Support | Notes | -| --- | --- | --- | --- | --- | -| CentOS 7 | 1.0.21 | **2.8.12.2** | | named `libusbx`, but
      `libusb`-codebase is used | -| Debian 8 (Jessie) | 1.0.**19** | 3.**0.2** | Jun 2020 | -| Ubuntu 14.04 LTS (Trusty Tahr) | 1.0.**17** | **2.8.12.2** | Apr 2019 | -| CentOS 6 | 1.0.**9** | **2.8.12.2** | Dec 2020 | named `libusbx`, but
      `libusb`-codebase is used | -| Slackware 14.1 | 1.0.**9** | **2.8.12** | | -| Slackware 14.0 | 1.0.**9** | **2.8.8** | | +| Operating System | libusb
      version | cmake
      version | End of
      OS-Support | Notes | +| ------------------------------ | ------------------- | ------------------ | ---------------------- | --------------------------------------------------- | +| CentOS 7 | 1.0.21 | **2.8.12.2** | | named `libusbx`, but
      `libusb`-codebase is used | +| Debian 8 (Jessie) | 1.0.**19** | 3.**0.2** | Jun 2020 | +| Ubuntu 14.04 LTS (Trusty Tahr) | 1.0.**17** | **2.8.12.2** | Apr 2019 | +| CentOS 6 | 1.0.**9** | **2.8.12.2** | Dec 2020 | named `libusbx`, but
      `libusb`-codebase is used | +| Slackware 14.1 | 1.0.**9** | **2.8.12** | | +| Slackware 14.0 | 1.0.**9** | **2.8.8** | | _All other operating systems which are not listed are unsupported._ From dcdbd61fda443c34d416d44237799a1c6e08d018 Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Wed, 17 Mar 2021 20:02:41 -0400 Subject: [PATCH 1116/1435] Consolidate core id read code --- src/common.c | 44 ++++++++++++-------------------------------- 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/src/common.c b/src/common.c index a064254d3..5f2746e3d 100644 --- a/src/common.c +++ b/src/common.c @@ -1221,43 +1221,23 @@ int stlink_core_id(stlink_t *sl) { int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { int ret; - if (sl->core_id == STM32H7_CORE_ID) { - /* STM32H7 chipid in 0x5c001000 (RM0433 pg3189) - * However, the STM32H7 is not the only chip with a JTAG - * IDCODE of 0x6ba02477, so we cannot rely solely on this info - * to select the address to read the chip id */ - - uint32_t cpu_id; - *chip_id = 0; - ret = -1; - - // Read the CPU ID as well to determine if this really is an H7 part - if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &cpu_id)) - cpu_id = 0; - - // If it is, read the chipid from the new address - if (sl->core_id == STM32H7_CORE_ID && cpu_id == STLINK_REG_CMx_CPUID_CM7) { - // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) - ret = stlink_read_debug32(sl, 0x5c001000, chip_id); - } - - if (*chip_id == 0) { - // default chipid address - ret = stlink_read_debug32(sl, 0xE0042000, chip_id); - } + uint32_t cpu_id; + *chip_id = 0; + ret = -1; - } else { - // default chipid address - ret = stlink_read_debug32(sl, 0xE0042000, chip_id); - } + // Read the CPU ID to determine where to read the core id from + if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &cpu_id)) + cpu_id = 0; - if (ret == -1) { - return(ret); + // If the chip is an H7, read the chipid from the new address + if (sl->core_id == STM32H7_CORE_ID && cpu_id == STLINK_REG_CMx_CPUID_CM7) { + // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) + ret = stlink_read_debug32(sl, 0x5c001000, chip_id); } if (*chip_id == 0) { - // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) - ret = stlink_read_debug32(sl, 0x5c001000, chip_id); + // default chipid address + ret = stlink_read_debug32(sl, 0xE0042000, chip_id); } if (*chip_id == 0) { From 9ed3d46c24c2a78d1e49474ec7529e7cd4c46d3b Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Tue, 16 Mar 2021 21:04:31 +0100 Subject: [PATCH 1117/1435] fix for stlink old DFU serial number omit the hla serial aka 'openocd serial' Only one valid serial is used which matches the serial as displayed in STM32CubeProgrammer and official ST tools. Signed-off-by: Tarek BOCHKATI --- doc/man/st-info.1 | 3 --- doc/man/st-info.md | 8 ++---- inc/stlink.h | 6 ++--- src/st-flash/flash.h | 2 +- src/st-flash/flash_opts.c | 12 +-------- src/st-info/info.c | 28 ++------------------- src/st-trace/trace.c | 19 +------------- src/st-util/gdb-server.c | 17 ++----------- src/stlink-lib/usb.c | 52 +++++++++++++++++++++++++++++++++------ src/stlink-lib/usb.h | 2 +- 10 files changed, 57 insertions(+), 92 deletions(-) diff --git a/doc/man/st-info.1 b/doc/man/st-info.1 index a0380f851..776ec7a3f 100644 --- a/doc/man/st-info.1 +++ b/doc/man/st-info.1 @@ -37,9 +37,6 @@ Display the chip ID of the device .B \-\-serial Display the serial code of the device .TP -.B \-\-hla\-serial -Display the hex escaped serial code of the device -.TP .B \-\-probe Display the summarized information of the connected programmers and devices diff --git a/doc/man/st-info.md b/doc/man/st-info.md index 9164642f2..91f9ea0b0 100644 --- a/doc/man/st-info.md +++ b/doc/man/st-info.md @@ -13,7 +13,7 @@ st-info - Provides information about connected STLink and STM32 devices # DESCRIPTION Provides information about connected STLink programmers and STM32 devices: -Serial code, OpenOCD hla-serial, flash, page size, sram, chipid, description. +Serial code, flash, page size, sram, chipid, description. The STLink device to probe can be specified via the environment variable STLINK_DEVICE on the format :. @@ -29,9 +29,6 @@ STLINK_DEVICE on the format :. \--serial : Display the serial code of the device -\--hla-serial -: Display the hex escaped serial code of the device - \--flash : Display amount of flash memory available in the device @@ -53,8 +50,7 @@ Display information about connected programmers and devices $ st-info --probe Found 1 stlink programmers - serial: 303033413030323233343338353130323334333133393339 - hla-serial: "\x30\x30\x33\x41\x30\x30\x32\x32\x33\x34\x33\x38\x35\x31\x30\x32\x33\x34\x33\x31\x33\x39\x33\x39" + serial: 57FF72067265575742132067 flash: 131072 (pagesize: 128) sram: 20480 chipid: 0x0447 diff --git a/inc/stlink.h b/inc/stlink.h index 9b5e56594..7bb1bc51e 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -79,7 +79,8 @@ enum target_state { #define STLINK_SWDCLK_15KHZ_DIVISOR 265 #define STLINK_SWDCLK_5KHZ_DIVISOR 798 -#define STLINK_SERIAL_MAX_SIZE 64 +#define STLINK_SERIAL_LENGTH 24 +#define STLINK_SERIAL_BUFFER_SIZE (STLINK_SERIAL_LENGTH + 1) #define STLINK_V3_MAX_FREQ_NB 10 @@ -191,8 +192,7 @@ struct _stlink { uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram enum target_state core_stat; // set by stlink_status() - char serial[STLINK_SERIAL_MAX_SIZE]; - int serial_size; + char serial[STLINK_SERIAL_BUFFER_SIZE]; int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR enum stlink_flash_type flash_type; diff --git a/src/st-flash/flash.h b/src/st-flash/flash.h index ca0ca2839..8a5c2ad29 100644 --- a/src/st-flash/flash.h +++ b/src/st-flash/flash.h @@ -14,7 +14,7 @@ enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1}; enum flash_area {FLASH_MAIN_MEMORY = 0, FLASH_SYSTEM_MEMORY = 1, FLASH_OTP = 2, FLASH_OPTION_BYTES = 3, FLASH_OPTION_BYTES_BOOT_ADD = 4, FLASH_OPTCR = 5, FLASH_OPTCR1 = 6}; struct flash_opts { enum flash_cmd cmd; - uint8_t serial[STLINK_SERIAL_MAX_SIZE]; + uint8_t serial[STLINK_SERIAL_BUFFER_SIZE]; const char* filename; stm32_addr_t addr; size_t size; diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 2ee19bd48..7d846e425 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -106,18 +106,8 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { serial = av[0] + strlen("--serial="); } - /** @todo This is not really portable, as strlen really returns size_t we need to obey - and not cast it to a signed type. */ - int j = (int)strlen(serial); - int length = j / 2; // the length of the destination-array + memcpy(o->serial, serial, STLINK_SERIAL_BUFFER_SIZE); - if (j % 2 != 0) { return(-1); } - - for (size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { - char buffer[3] = {0}; - memcpy(buffer, serial + j, 2); - o->serial[length - k] = (uint8_t)strtol(buffer, NULL, 16); - } } else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { const char * area; diff --git a/src/st-info/info.c b/src/st-info/info.c index 0fc4d4d8a..c1ac86373 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -9,7 +9,6 @@ static void usage(void) { puts("st-info --version"); puts("st-info --probe"); puts("st-info --serial"); - puts("st-info --hla-serial"); puts("st-info --flash [--connect-under-reset]"); puts("st-info --pagesize [--connect-under-reset]"); puts("st-info --sram [--connect-under-reset]"); @@ -17,24 +16,6 @@ static void usage(void) { puts("st-info --descr [--connect-under-reset]"); } -/* Print normal or OpenOCD hla_serial with newline */ -static void stlink_print_serial(stlink_t *sl, bool openocd) { - const char *fmt; - - if (openocd) { - printf("\""); - fmt = "\\x%02x"; - } else { - fmt = "%02x"; - } - - for (int n = 0; n < sl->serial_size; n++) { printf(fmt, sl->serial[n]); } - - if (openocd) { printf("\""); } - - printf("\n"); -} - static void stlink_print_version(stlink_t *sl) { // Implementation of version printing is minimalistic // but contains all available information from sl->version @@ -53,10 +34,7 @@ static void stlink_print_info(stlink_t *sl) { printf(" version: "); stlink_print_version(sl); - printf(" serial: "); - stlink_print_serial(sl, false); - printf(" hla-serial: "); - stlink_print_serial(sl, true); + printf(" serial: %s\n", sl->serial); printf(" flash: %u (pagesize: %u)\n", (uint32_t)sl->flash_size, (uint32_t)sl->flash_pgsz); printf(" sram: %u\n", (uint32_t)sl->sram_size); @@ -131,9 +109,7 @@ static int print_data(int ac, char **av) { if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } if (strcmp(av[1], "--serial") == 0) { - stlink_print_serial(sl, false); - } else if (strcmp(av[1], "--hla-serial") == 0) { - stlink_print_serial(sl, true); + printf("%s\n", sl->serial); } else if (strcmp(av[1], "--flash") == 0) { printf("0x%x\n", (uint32_t)sl->flash_size); } else if (strcmp(av[1], "--pagesize") == 0) { diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 71ba6b360..3180335a0 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -191,25 +191,8 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { return true; } -static void convert_serial_number_text_to_binary(const char* text, char binary_out[STLINK_SERIAL_MAX_SIZE]) { - size_t length = 0; - for (uint32_t n = 0; n < strlen(text) && length < STLINK_SERIAL_MAX_SIZE; n += 2) { - char buffer[3] = { 0 }; - memcpy(buffer, text + n, 2); - binary_out[length++] = (uint8_t)strtol(buffer, NULL, 16); - } -} - static stlink_t* stlink_connect(const st_settings_t* settings) { - if (settings->serial_number) { - // Open this specific stlink. - char binary_serial_number[STLINK_SERIAL_MAX_SIZE] = { 0 }; - convert_serial_number_text_to_binary(settings->serial_number, binary_serial_number); - return stlink_open_usb(settings->logging_level, false, binary_serial_number, 0); - } else { - // Otherwise, open any stlink. - return stlink_open_usb(settings->logging_level, false, NULL, 0); - } + return stlink_open_usb(settings->logging_level, false, settings->serial_number, 0); } static bool enable_trace(stlink_t* stlink, const st_settings_t* settings, uint32_t trace_frequency) { diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 4177cef11..0f30c688a 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -43,7 +43,7 @@ static stlink_t *connected_stlink = NULL; static bool semihosting = false; static bool serial_specified = false; -static char serialnumber[STLINK_SERIAL_MAX_SIZE] = {0}; +static char serialnumber[STLINK_SERIAL_BUFFER_SIZE] = {0}; #if defined(_WIN32) #define close_socket win32_close_socket @@ -192,20 +192,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { break; case SERIAL_OPTION: printf("use serial %s\n", optarg); - /* TODO: This is not really portable, as strlen really returns size_t, - * we need to obey and not cast it to a signed type. - */ - int j = (int)strlen(optarg); - int length = j / 2; // the length of the destination-array - - if (j % 2 != 0) { return(-1); } - - for (size_t k = 0; j >= 0 && k < sizeof(serialnumber); ++k, j -= 2) { - char buffer[3] = {0}; - memcpy(buffer, optarg + j, 2); - serialnumber[length - k] = (uint8_t)strtol(buffer, NULL, 16); - } - + memcpy(serialnumber, optarg, STLINK_SERIAL_BUFFER_SIZE); serial_specified = true; break; } diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index d2b17fad6..569815665 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1159,7 +1159,44 @@ static stlink_backend_t _stlink_usb_backend = { _stlink_usb_read_trace }; -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq) { +/* return the length of serial or (0) in case of errors */ +size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_descriptor *desc, char *serial) { + unsigned char desc_serial[(STLINK_SERIAL_LENGTH) * 2]; + + /* truncate the string in the serial buffer */ + serial[0] = '\0'; + + /* get the LANGID from String Descriptor Zero */ + int ret = libusb_get_string_descriptor(handle, 0, 0, desc_serial, sizeof(desc_serial)); + if (ret < 4) return 0; + + uint32_t langid = desc_serial[2] | (desc_serial[3] << 8); + + /* get the serial */ + ret = libusb_get_string_descriptor(handle, desc->iSerialNumber, langid, desc_serial, + sizeof(desc_serial)); + if (ret < 0) return 0; // could not read serial + + unsigned char len = desc_serial[0]; + + if (len == ((STLINK_SERIAL_LENGTH + 1) * 2)) { /* len == 50 */ + /* good ST-Link adapter */ + ret = libusb_get_string_descriptor_ascii( + handle, desc->iSerialNumber, (unsigned char *)serial, STLINK_SERIAL_BUFFER_SIZE); + if (ret < 0) return 0; + } else if (len == ((STLINK_SERIAL_LENGTH / 2 + 1) * 2)) { /* len == 26 */ + /* fix-up the buggy serial */ + for (unsigned int i = 0; i < STLINK_SERIAL_LENGTH; i += 2) + sprintf(serial + i, "%02X", desc_serial[i + 2]); + serial[STLINK_SERIAL_LENGTH] = '\0'; + } else { + return 0; + } + + return strlen(serial); +} + +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; int ret = -1; @@ -1236,15 +1273,14 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL if (ret) { continue; } // could not open device - sl->serial_size = libusb_get_string_descriptor_ascii( - handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial)); + size_t serial_len = stlink_serial(handle, &desc, sl->serial); libusb_close(handle); - if (sl->serial_size < 0) { continue; } // could not read serial + if (serial_len != STLINK_SERIAL_LENGTH) { continue; } // could not read the serial // if no serial provided, or if serial match device, fixup version and protocol - if (((serial == NULL) || (*serial == 0)) || (memcmp(serial, &sl->serial, sl->serial_size) == 0)) { + if (((serial == NULL) || (*serial == 0)) || (memcmp(serial, &sl->serial, STLINK_SERIAL_LENGTH) == 0)) { if (STLINK_V1_USB_PID(desc.idProduct)) { slu->protocoll = 1; sl->version.stlink_v = 1; @@ -1433,7 +1469,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { continue; } struct libusb_device_handle* handle; - char serial[STLINK_SERIAL_MAX_SIZE] = {0, }; + char serial[STLINK_SERIAL_BUFFER_SIZE] = {0, }; ret = libusb_open(dev, &handle); @@ -1447,11 +1483,11 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { break; } - ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial)); + size_t serial_len = stlink_serial(handle, &desc, serial); libusb_close(handle); - if (ret < 0) { continue; } + if (serial_len != STLINK_SERIAL_LENGTH) { continue; } stlink_t *sl = stlink_open_usb(0, 1, serial, 0); diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index 717a82f6d..512370a10 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -67,7 +67,7 @@ struct stlink_libusb { * @retval NULL Error while opening the stlink * @retval !NULL Stlink found and ready to use */ -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq); +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq); size_t stlink_probe_usb(stlink_t **stdevs[]); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); From d9726fa86da888f54e463b21f624ee27e208e3a0 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Wed, 17 Mar 2021 12:38:38 +0500 Subject: [PATCH 1118/1435] Updated a target resetting documentation --- doc/man/st-flash.1 | 2 +- doc/man/st-flash.md | 2 +- doc/tutorial.md | 19 ++++++++++--------- src/st-flash/flash.c | 4 ++-- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/doc/man/st-flash.1 b/doc/man/st-flash.1 index c2654f280..086046d2c 100644 --- a/doc/man/st-flash.1 +++ b/doc/man/st-flash.1 @@ -41,7 +41,7 @@ Print version information TODO .TP --reset -TODO +Trigger a reset both before and after flashing .TP --opt Enable ignore ending empty bytes optimization diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md index d5565e923..80130c8f1 100644 --- a/doc/man/st-flash.md +++ b/doc/man/st-flash.md @@ -46,7 +46,7 @@ reset : TODO \--reset -: TODO +: Trigger a reset both before and after flashing \--opt : Enable ignore ending empty bytes optimization diff --git a/doc/tutorial.md b/doc/tutorial.md index 3a0f16fd9..d4cf89ce2 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -2,14 +2,15 @@ ## Available tools and options -| Option | Tool | Description | Available
      since | -| --------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k
      for the STM32F103C8T6 to assume 128k of flash being present. This option accepts
      decimal (128k), octal 0200k, or hex 0x80k values. Leaving the multiplier out is
      equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional "k"
      or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | -| --freq=n[k][m] | st-flash | The frequency of the SWD/JTAG interface can be specified, to override the default
      1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
      the unit `Hz` being left out. Valid frequencies are: `5K, 15K, 25K, 50K, 100K,`
      `125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | -| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at
      the end of binary file. This may cause some garbage data left after a flash operation.
      This option was enabled by default in earlier releases. | v1.6.1 | -| --reset | st-flash | Trigger a reset both before and after flashing. | v1.0.0 | -| --version | st-info,
      st-flash,
      st-util | Print version information. | | -| --help | st-flash,
      st-util | Print list of available commands. _(To be added to this table.)_ | | +| Option | Tool | Description | Available
      since | +| --------------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k
      for the STM32F103C8T6 to assume 128k of flash being present. This option accepts
      decimal (128k), octal 0200k, or hex 0x80k values. Leaving the multiplier out is
      equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional "k"
      or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | +| --freq=n[k][m] | st-flash | The frequency of the SWD/JTAG interface can be specified, to override the default
      1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
      the unit `Hz` being left out. Valid frequencies are: `5K, 15K, 25K, 50K, 100K,`
      `125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | +| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at
      the end of binary file. This may cause some garbage data left after a flash operation.
      This option was enabled by default in earlier releases. | v1.6.1 | +| --reset | st-flash | Trigger a reset both before and after flashing. The default use the hardware reset
      through `NRST` pin. The software system reset is used if the hardware reset failed
      (`NRST` pin not connected). | v1.0.0 | +| --connect-under-reset | st-flash | Connect under reset. Option makes it possible to connect to the device before code
      executing. This is useful when the target contains a code that go device to sleep,
      disables of debug pins or other special code. | v1.6.1 | +| --version | st-info
      st-flash
      st-util | Print version information. | | +| --help | st-flash
      st-util | Print list of available commands. _(To be added to this table.)_ | | ### st-flash: Checksum for binary files @@ -272,7 +273,7 @@ In order to continue, one can use 'monitor reset' to reset the MCU. Remember that you can shorten the commands. `tar ext :4242` is good enough for GDB. -If you need to send a hard reset signal through `NRST` pin, you can use the following command: +If you need to send a reset signal, you can use the following command: ``` (gdb) monitor jtag_reset diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index d8bd8772c..447daa158 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -26,8 +26,8 @@ static void cleanup(int signum) { } static void usage(void) { - puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); - puts("command line: ./st-flash [--debug] [--freq=] [--serial ] erase"); + puts("command line: ./st-flash [--debug] [--reset] [--connect-under-reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); + puts("command line: ./st-flash [--debug] [--connect-under-reset] [--freq=] [--serial ] erase"); puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); puts(" , and : Use hex format."); puts(" : Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); From ebcf04f02bcb47f0d34d0b0a4992007ee19bfe5c Mon Sep 17 00:00:00 2001 From: anton Date: Wed, 17 Mar 2021 20:32:20 +0500 Subject: [PATCH 1119/1435] flash_loader: used timeout in ms --- src/stlink-lib/flash_loader.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index b55953406..1224215e5 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -3,6 +3,7 @@ #include #include +#include #include "flash_loader.h" #define FLASH_REGS_BANK2_OFS 0x40 @@ -313,7 +314,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { struct stlink_reg rr; - int i = 0; + unsigned timeout; size_t count = 0; uint32_t flash_base = 0; const char *error = NULL; @@ -368,16 +369,19 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe * the OS uses, the wait until the error message is reduced to the same order of magnitude * as what was intended. -- REW. */ -#define WAIT_ROUNDS 40 // wait until done (reaches breakpoint) - for (i = 0; i < WAIT_ROUNDS; i++) { + timeout = time_ms() + 500; + while (time_ms() < timeout) { usleep(10000); - if (stlink_is_core_halted(sl)) { break; } + if (stlink_is_core_halted(sl)) { + timeout = 0; + break; + } } - if (i >= WAIT_ROUNDS) { + if (timeout) { error = "Flash loader run error"; goto error; } From 41bbbc2e9650f873fa562977ac89242fd4ac19fe Mon Sep 17 00:00:00 2001 From: anton Date: Thu, 18 Mar 2021 19:28:40 +0500 Subject: [PATCH 1120/1435] flash_loader: fix check BUSY flag, code simplified --- flashloaders/Makefile | 75 ++++++++---- flashloaders/cleanroom.md | 38 +++---- flashloaders/stm32f0.s | 78 +++++++------ flashloaders/stm32f4.s | 32 ++++-- flashloaders/stm32f4lv.s | 38 ++++--- flashloaders/stm32f7.s | 32 ++++-- flashloaders/stm32f7lv.s | 38 ++++--- flashloaders/stm32l0x.s | 22 ---- flashloaders/stm32l4.s | 32 ++++-- flashloaders/stm32lx.s | 26 +++-- src/stlink-lib/flash_loader.c | 207 ++++++++++++++-------------------- src/stlink-lib/reg.h | 6 + 12 files changed, 320 insertions(+), 304 deletions(-) delete mode 100644 flashloaders/stm32l0x.s diff --git a/flashloaders/Makefile b/flashloaders/Makefile index 7b17cb2a0..3517e1499 100644 --- a/flashloaders/Makefile +++ b/flashloaders/Makefile @@ -4,35 +4,60 @@ # This makefile will save your time from dealing with compile errors # Adjust CC if needed -CC = /opt/local/gcc-arm-none-eabi-8-2018-q4-major/bin/arm-none-eabi-gcc - -CFLAGS_thumb1 = -mcpu=Cortex-M0 -Tlinker.ld -ffreestanding -nostdlib -CFLAGS_thumb2 = -mcpu=Cortex-M3 -Tlinker.ld -ffreestanding -nostdlib - -all: stm32vl.o stm32f0.o stm32l.o stm32f4.o stm32f4_lv.o stm32l4.o stm32f7.o stm32f7_lv.o - -stm32vl.o: stm32f0.s - $(CC) stm32f0.s $(CFLAGS_thumb2) -o stm32vl.o -stm32f0.o: stm32f0.s - $(CC) stm32f0.s $(CFLAGS_thumb1) -o stm32f0.o -stm32l.o: stm32lx.s - $(CC) stm32lx.s $(CFLAGS_thumb2) -o stm32l.o -stm32f4.o: stm32f4.s - $(CC) stm32f4.s $(CFLAGS_thumb2) -o stm32f4.o -stm32f4_lv.o: stm32f4lv.s - $(CC) stm32f4lv.s $(CFLAGS_thumb2) -o stm32f4_lv.o -stm32l4.o: stm32l4.s - $(CC) stm32l4.s $(CFLAGS_thumb2) -o stm32l4.o -stm32f7.o: stm32f7.s - $(CC) stm32f7.s $(CFLAGS_thumb2) -o stm32f7.o -stm32f7_lv.o: stm32f7lv.s - $(CC) stm32f7lv.s $(CFLAGS_thumb2) -o stm32f7_lv.o +CROSS_COMPILE ?= /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi- -clean: - rm *.o +CC = $(CROSS_COMPILE)gcc +OBJCOPY = $(CROSS_COMPILE)objcopy + +XXD = xxd +XXDFLAGS = -i -c 4 + +CFLAGS_THUMB1 = -mcpu=Cortex-M0 -Tlinker.ld -ffreestanding -nostdlib +CFLAGS_THUMB2 = -mcpu=Cortex-M3 -Tlinker.ld -ffreestanding -nostdlib + +all: stm32vl.h stm32f0.h stm32lx.h stm32f4.h stm32f4lv.h stm32l4.h stm32f7.h stm32f7lv.h +stm32f0.h: stm32f0.s + $(CC) stm32f0.s $(CFLAGS_THUMB1) -o stm32f0.o + $(OBJCOPY) -O binary stm32f0.o stm32f0.bin + $(XXD) $(XXDFLAGS) stm32f0.bin stm32f0.h +stm32vl.h: stm32f0.s + $(CC) stm32f0.s $(CFLAGS_THUMB2) -o stm32vl.o + $(OBJCOPY) -O binary stm32vl.o stm32vl.bin + $(XXD) $(XXDFLAGS) stm32vl.bin stm32vl.h +stm32lx.h: stm32lx.s + $(CC) stm32lx.s $(CFLAGS_THUMB2) -o stm32lx.o + $(OBJCOPY) -O binary stm32lx.o stm32lx.bin + $(XXD) $(XXDFLAGS) stm32lx.bin stm32lx.h +stm32f4.h: stm32f4.s + $(CC) stm32f4.s $(CFLAGS_THUMB2) -o stm32f4.o + $(OBJCOPY) -O binary stm32f4.o stm32f4.bin + $(XXD) $(XXDFLAGS) stm32f4.bin stm32f4.h +stm32f4lv.h: stm32f4lv.s + $(CC) stm32f4lv.s $(CFLAGS_THUMB2) -o stm32f4lv.o + $(OBJCOPY) -O binary stm32f4lv.o stm32f4lv.bin + $(XXD) $(XXDFLAGS) stm32f4lv.bin stm32f4lv.h +stm32l4.h: stm32l4.s + $(CC) stm32l4.s $(CFLAGS_THUMB2) -o stm32l4.o + $(OBJCOPY) -O binary stm32l4.o stm32l4.bin + $(XXD) $(XXDFLAGS) stm32l4.bin stm32l4.h + +stm32f7.h: stm32f7.s + $(CC) stm32f7.s $(CFLAGS_THUMB2) -o stm32f7.o + $(OBJCOPY) -O binary stm32f7.o stm32f7.bin + $(XXD) $(XXDFLAGS) stm32f7.bin stm32f7.h + +stm32f7lv.h: stm32f7lv.s + $(CC) stm32f7lv.s $(CFLAGS_THUMB2) -o stm32f7lv.o + $(OBJCOPY) -O binary stm32f7lv.o stm32f7lv.bin + $(XXD) $(XXDFLAGS) stm32f7lv.bin stm32f7lv.h + +clean: + rm *.o + rm *.bin + rm *.h diff --git a/flashloaders/cleanroom.md b/flashloaders/cleanroom.md index a468efe49..b2cb9f00d 100644 --- a/flashloaders/cleanroom.md +++ b/flashloaders/cleanroom.md @@ -1,6 +1,4 @@ -Original Chinese version can be found below. - -# Clean Room Documentation English Version +# Flash Loader Documentation Code is situated in section `.text` @@ -12,11 +10,12 @@ All parameters would be passed over registers `r0`: the base address of the copy source `r1`: the base address of the copy destination -`r2`: the total word (4 bytes) count to be copied (with expeptions) +`r2`: the count of byte to be copied +`r3`: flash register offset (used to support two banks) **What the program is expected to do**: -Copy data from source to destination, after which trigger a breakpint to exit. Before exit, `r2` must be cleared to zero to indicate that the copy is done. +Copy data from source to destination, after which trigger a breakpint to exit. Before exit, `r2` must be less or equal to zero to indicate that the copy is done. **Limitation**: No stack operations are permitted. Registers ranging from `r3` to `r12` are free to use. Note that `r13` is `sp`(stack pointer), `r14` is `lr`(commonly used to store jump address), `r15` is `pc`(program counter). @@ -24,8 +23,6 @@ Copy data from source to destination, after which trigger a breakpint to exit. B ## stm32f0.s -**Exception**: `r2` stores the total half word (2 bytes) count to be copied - `flash_base`: 0x40022000 `FLASH_CR`: offset from `flash_base` is 16 @@ -37,11 +34,11 @@ Copy data from source to destination, after which trigger a breakpint to exit. B **Special requirements**: -Before every copy, read a word from FLASH_CR, set the lowest bit to 1 and write back. Copy one half word each time. +Before every copy, read a word from FLASH_CR, set the PG bit to 1 and write back. Copy one half word each time. -How to wait for the write process: read a word from FLASH_SR, loop until the content is not 1. After that, check FLASH_SR, proceed if the content is 4, otherwise exit. +How to wait for the write process: read a word from FLASH_SR, loop until the busy bit is reset. After that, FLASH_SR is check. The process is interrupted if the error bit (0x04) is set. -Exit: after the copying process and before triggering the breakpoint, clear the lowest bit in FLASH_CR. +Exit: after the copying process and before triggering the breakpoint, clear the PG bit in FLASH_CR. ## stm32f4.s @@ -56,7 +53,8 @@ Exit: after the copying process and before triggering the breakpoint, clear the **Special requirements**: Copy one word each time. -How to wait for the write process: read a half word from FLASH_SR, loop until the content is not 1. + +How to wait for the write process: read a word from FLASH_SR, loop until the busy bit is reset. ## stm32f4lv.s @@ -71,7 +69,7 @@ How to wait for the write process: read a half word from FLASH_SR, loop until th Copy one byte each time. -How to wait from the write process: read a half word from FLASH_SR, loop until the content is not 1. +How to wait from the write process: read a half word from FLASH_SR, loop until the busy bit is reset. ## stm32f7.s @@ -89,7 +87,7 @@ Mostly same with `stm32f4.s`. Require establishing a memory barrier after every Mostly same with `stm32f7.s`. Copy one byte each time. -## stm32l0x.s +## stm32lx.s **Special Requirements**: @@ -97,8 +95,6 @@ Copy one word each time. No wait for write. ## stm32l4.s -**Exception**: r2 stores the double word count to be copied. - `flash_base`: 0x40022000 `FLASH_BSY`: offset from `flash_base` is 0x12 @@ -109,14 +105,10 @@ Copy one word each time. No wait for write. Copy one double word each time (More than one registers are allowed). -How to wait for the write process: read a half word from `FLASH_BSY`, loop until the lowest bit turns non-1. - -## stm32lx.s +How to wait for the write process: read a half word from `FLASH_BSY`, loop until the busy bit is reset. -Same with stm32l0x.s. - -# 净室工程文档-原始中文版 +# 净室工程文档-原始中文版 (out of date) 代码位于的section:`.text` 编译制导添加`.syntax unified` @@ -139,8 +131,6 @@ Same with stm32l0x.s. ## stm32f0.s -例外:`r2`:拷贝half word(2字节)数 - 特殊地址定义:`flash_base`:定义为0x40022000 `FLASH_CR`: 相对`flash_base`的offset为16 @@ -230,4 +220,4 @@ Same with stm32l0x.s. ## stm32lx.s -要求与stm32l0x.s相同 \ No newline at end of file +要求与stm32l0x.s相同 diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index f30e4bfc6..e2a4b0f00 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -1,6 +1,14 @@ .syntax unified .text + /* + * Arguments: + * r0 - source memory ptr + * r1 - target memory ptr + * r2 - count of bytes + * r3 - flash register offset + */ + .global copy copy: /* @@ -17,54 +25,56 @@ copy: */ nop nop - ldr r7, =flash_base - ldr r4, [r7] - ldr r7, =flash_off_cr - ldr r6, [r7] - adds r6, r6, r4 - ldr r7, =flash_off_sr - ldr r5, [r7] - adds r5, r5, r4 -loop: - # FLASH_CR ^= 1 + # load flash control register address + # add r3 to flash_base for support dual bank (see flash_loader.c) + ldr r7, flash_base + add r7, r7, r3 + ldr r6, flash_off_cr + add r6, r6, r7 + ldr r5, flash_off_sr + add r5, r5, r7 + + # FLASH_CR |= 0x01 (set PG) ldr r7, =0x1 - ldr r3, [r6] - orrs r3, r3, r7 - str r3, [r6] + ldr r4, [r6] + orrs r4, r4, r7 + str r4, [r6] +loop: # copy 2 bytes - ldrh r3, [r0] - strh r3, [r1] + ldrh r4, [r0] + strh r4, [r1] - ldr r7, =2 - adds r0, r0, r7 - adds r1, r1, r7 + # increment address + adds r0, r0, #0x2 + adds r1, r1, #0x2 - # wait if FLASH_SR == 1 + # BUSY flag + ldr r7, =0x01 wait: - ldr r7, =0x1 - ldr r3, [r5] - tst r3, r7 - beq wait + # get FLASH_SR + ldr r4, [r5] - # exit if FLASH_SR != 4 - ldr r7, =0x4 - tst r3, r7 + # wait until BUSY flag is reset + tst r4, r7 + bne wait + + # test PGERR or WRPRTERR flag is reset + ldr r7, =0x14 + tst r4, r7 bne exit - # loop if r2 != 0 - ldr r7, =0x1 - subs r2, r2, r7 - cmp r2, #0 - bne loop + # loop if count > 0 + subs r2, r2, #0x2 + bgt loop exit: # FLASH_CR &= ~1 ldr r7, =0x1 - ldr r3, [r6] - bics r3, r3, r7 - str r3, [r6] + ldr r4, [r6] + bics r4, r4, r7 + str r4, [r6] bkpt diff --git a/flashloaders/stm32f4.s b/flashloaders/stm32f4.s index a88ad9e02..a66c70dac 100644 --- a/flashloaders/stm32f4.s +++ b/flashloaders/stm32f4.s @@ -1,6 +1,14 @@ .syntax unified .text + /* + * Arguments: + * r0 - source memory ptr + * r1 - target memory ptr + * r2 - count of bytes + * r3 - flash register offset + */ + .global copy copy: ldr r12, flash_base @@ -9,22 +17,24 @@ copy: loop: # copy 4 bytes - ldr r3, [r0] - str r3, [r1] + ldr r4, [r0] + str r4, [r1] + # increment address add r0, r0, #4 add r1, r1, #4 - # wait if FLASH_SR == 1 wait: - ldrh r3, [r10] - tst r3, #0x1 - beq wait - - # loop if r2 != 0 - sub r2, r2, #1 - cmp r2, #0 - bne loop + # get FLASH_SR + ldrh r4, [r10] + + # wait until BUSY flag is reset + tst r4, #0x1 + bne wait + + # loop if count > 0 + subs r2, r2, #4 + bgt loop exit: bkpt diff --git a/flashloaders/stm32f4lv.s b/flashloaders/stm32f4lv.s index 41467a9ef..b8fcfa048 100644 --- a/flashloaders/stm32f4lv.s +++ b/flashloaders/stm32f4lv.s @@ -1,36 +1,40 @@ .syntax unified .text + /* + * Arguments: + * r0 - source memory ptr + * r1 - target memory ptr + * r2 - count of bytes + * r3 - flash register offset + */ + .global copy copy: ldr r12, flash_base ldr r10, flash_off_sr add r10, r10, r12 - # tip 1: original r2 indicates the count of 4 bytes need to copy, - # but we can only copy one byte each time. - # as we have no flash larger than 1GB, we do a little trick here. - # tip 2: r2 is always a power of 2 - mov r2, r2, lsl#2 - loop: # copy 1 byte - ldrb r3, [r0] - strb r3, [r1] + ldrb r4, [r0] + strb r4, [r1] + # increment address add r0, r0, #1 add r1, r1, #1 - # wait if FLASH_SR == 1 wait: - ldrh r3, [r10] - tst r3, #0x1 - beq wait - - # loop if r2 != 0 - sub r2, r2, #1 - cmp r2, #0 - bne loop + # get FLASH_SR + ldrh r4, [r10] + + # wait until BUSY flag is reset + tst r4, #0x1 + bne wait + + # loop if count > 0 + subs r2, r2, #1 + bgt loop exit: bkpt diff --git a/flashloaders/stm32f7.s b/flashloaders/stm32f7.s index 3779a5ea6..4b43cebdc 100644 --- a/flashloaders/stm32f7.s +++ b/flashloaders/stm32f7.s @@ -1,6 +1,14 @@ .syntax unified .text + /* + * Arguments: + * r0 - source memory ptr + * r1 - target memory ptr + * r2 - count of bytes + * r3 - flash register offset + */ + .global copy copy: ldr r12, flash_base @@ -9,25 +17,27 @@ copy: loop: # copy 4 bytes - ldr r3, [r0] - str r3, [r1] + ldr r4, [r0] + str r4, [r1] + # increment address add r0, r0, #4 add r1, r1, #4 # memory barrier dsb sy - # wait if FLASH_SR == 1 wait: - ldrh r3, [r10] - tst r3, #0x1 - beq wait - - # loop if r2 != 0 - sub r2, r2, #1 - cmp r2, #0 - bne loop + # get FLASH_SR + ldrh r4, [r10] + + # wait until BUSY flag is reset + tst r4, #0x1 + bne wait + + # loop if count > 0 + subs r2, r2, #4 + bgt loop exit: bkpt diff --git a/flashloaders/stm32f7lv.s b/flashloaders/stm32f7lv.s index e7b66cc2c..78ff35dbc 100644 --- a/flashloaders/stm32f7lv.s +++ b/flashloaders/stm32f7lv.s @@ -1,39 +1,43 @@ .syntax unified .text + /* + * Arguments: + * r0 - source memory ptr + * r1 - target memory ptr + * r2 - count of bytes + * r3 - flash register offset + */ + .global copy copy: ldr r12, flash_base ldr r10, flash_off_sr add r10, r10, r12 - # tip 1: original r2 indicates the count in 4 bytes need to copy, - # but we can only copy one byte each time. - # as we have no flash larger than 1GB, we do a little trick here. - # tip 2: r2 is always a power of 2 - mov r2, r2, lsl#2 - loop: # copy 1 byte - ldrb r3, [r0] - strb r3, [r1] + ldrb r4, [r0] + strb r4, [r1] + # increment address add r0, r0, #1 add r1, r1, #1 # memory barrier dsb sy - # wait if FLASH_SR == 1 wait: - ldrh r3, [r10] - tst r3, #0x1 - beq wait - - # loop if r2 != 0 - sub r2, r2, #1 - cmp r2, #0 - bne loop + # get FLASH_SR + ldrh r4, [r10] + + # wait until BUSY flag is reset + tst r4, #0x1 + bne wait + + # loop if count > 0 + subs r2, r2, #1 + bgt loop exit: bkpt diff --git a/flashloaders/stm32l0x.s b/flashloaders/stm32l0x.s deleted file mode 100644 index f9c257e2e..000000000 --- a/flashloaders/stm32l0x.s +++ /dev/null @@ -1,22 +0,0 @@ - .syntax unified - .text - - .global copy -copy: -loop: - # copy 4 bytes - ldr r3, [r0] - str r3, [r1] - - ldr r7, =4 - add r0, r0, r7 - add r1, r1, r7 - - # loop if r2 != 0 - ldr r7, =1 - subs r2, r2, r7 - cmp r2, #0 - bne loop - -exit: - bkpt diff --git a/flashloaders/stm32l4.s b/flashloaders/stm32l4.s index 32c27a057..21e926f49 100644 --- a/flashloaders/stm32l4.s +++ b/flashloaders/stm32l4.s @@ -1,6 +1,14 @@ .syntax unified .text + /* + * Arguments: + * r0 - source memory ptr + * r1 - target memory ptr + * r2 - count of bytes + * r3 - flash register offset + */ + .global copy copy: ldr r12, flash_base @@ -9,24 +17,26 @@ copy: loop: # copy 8 bytes - ldr r3, [r0] + ldr r5, [r0] ldr r4, [r0, #4] - str r3, [r1] + str r5, [r1] str r4, [r1, #4] + # increment address add r0, r0, #8 add r1, r1, #8 - # wait if FLASH_BSY[0b] == 1 wait: - ldrh r3, [r10] - tst r3, #0x1 - beq wait - - # loop if r2 != 0 - sub r2, r2, #1 - cmp r2, #0 - bne loop + # get FLASH_SR + ldr r4, [r10] + + # wait until BUSY flag is reset + tst r4, #0x10000 + bne wait + + # loop if count > 0 + subs r2, r2, #8 + bgt loop exit: bkpt diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index f9c257e2e..69acdea7b 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -1,22 +1,28 @@ .syntax unified .text + /* + * Arguments: + * r0 - source memory ptr + * r1 - target memory ptr + * r2 - count of bytes + * r3 - flash register offset + */ + .global copy copy: loop: # copy 4 bytes - ldr r3, [r0] - str r3, [r1] + ldr r4, [r0] + str r4, [r1] - ldr r7, =4 - add r0, r0, r7 - add r1, r1, r7 + # increment address + add r0, r0, #4 + add r1, r1, #4 - # loop if r2 != 0 - ldr r7, =1 - subs r2, r2, r7 - cmp r2, #0 - bne loop + # loop if count > 0 + subs r2, r2, #4 + bgt loop exit: bkpt diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 1224215e5..5bc314b07 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -13,89 +13,72 @@ /* flashloaders/stm32f0.s -- compiled with thumb2 */ static const uint8_t loader_code_stm32vl[] = { - 0x16, 0x4f, 0x3c, 0x68, - 0x16, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x16, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, + 0x00, 0xbf, 0x00, 0xbf, + 0x0f, 0x4f, 0x1f, 0x44, + 0x0f, 0x4e, 0x3e, 0x44, + 0x0f, 0x4d, 0x3d, 0x44, 0x4f, 0xf0, 0x01, 0x07, - 0x33, 0x68, 0x3b, 0x43, - 0x33, 0x60, 0x03, 0x88, - 0x0b, 0x80, 0x4f, 0xf0, - 0x02, 0x07, 0xc0, 0x19, - 0xc9, 0x19, 0x4f, 0xf0, - 0x01, 0x07, 0x2b, 0x68, - 0x3b, 0x42, 0xfa, 0xd0, - 0x4f, 0xf0, 0x04, 0x07, - 0x3b, 0x42, 0x04, 0xd1, + 0x34, 0x68, 0x3c, 0x43, + 0x34, 0x60, 0x04, 0x88, + 0x0c, 0x80, 0x02, 0x30, + 0x02, 0x31, 0x4f, 0xf0, + 0x01, 0x07, 0x2c, 0x68, + 0x3c, 0x42, 0xfc, 0xd1, + 0x4f, 0xf0, 0x14, 0x07, + 0x3c, 0x42, 0x01, 0xd1, + 0x02, 0x3a, 0xf0, 0xdc, 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xe6, 0xd1, 0x4f, 0xf0, - 0x01, 0x07, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0x00, 0xbf, + 0x34, 0x68, 0xbc, 0x43, + 0x34, 0x60, 0x00, 0xbe, 0x00, 0x20, 0x02, 0x40, 0x10, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x20, - 0x54, 0x00, 0x00, 0x20, - 0x58, 0x00, 0x00, 0x20 + 0x0c, 0x00, 0x00, 0x00 }; /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ static const uint8_t loader_code_stm32f0[] = { 0xc0, 0x46, 0xc0, 0x46, - 0x13, 0x4f, 0x3c, 0x68, - 0x13, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x13, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, - 0x12, 0x4f, 0x33, 0x68, - 0x3b, 0x43, 0x33, 0x60, - 0x03, 0x88, 0x0b, 0x80, - 0x10, 0x4f, 0xc0, 0x19, - 0xc9, 0x19, 0x0e, 0x4f, - 0x2b, 0x68, 0x3b, 0x42, - 0xfb, 0xd0, 0x0e, 0x4f, - 0x3b, 0x42, 0x03, 0xd1, - 0x0a, 0x4f, 0xd2, 0x1b, - 0x00, 0x2a, 0xeb, 0xd1, - 0x08, 0x4f, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0xc0, 0x46, + 0x0d, 0x4f, 0x1f, 0x44, + 0x0d, 0x4e, 0x3e, 0x44, + 0x0d, 0x4d, 0x3d, 0x44, + 0x0d, 0x4f, 0x34, 0x68, + 0x3c, 0x43, 0x34, 0x60, + 0x04, 0x88, 0x0c, 0x80, + 0x02, 0x30, 0x02, 0x31, + 0x09, 0x4f, 0x2c, 0x68, + 0x3c, 0x42, 0xfc, 0xd1, + 0x08, 0x4f, 0x3c, 0x42, + 0x01, 0xd1, 0x02, 0x3a, + 0xf2, 0xdc, 0x05, 0x4f, + 0x34, 0x68, 0xbc, 0x43, + 0x34, 0x60, 0x00, 0xbe, 0x00, 0x20, 0x02, 0x40, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x20, - 0x4c, 0x00, 0x00, 0x20, - 0x50, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00 + 0x14, 0x00, 0x00, 0x00 }; -static const uint8_t loader_code_stm32l[] = { +static const uint8_t loader_code_stm32lx[] = { // flashloaders/stm32lx.s - - 0x03, 0x68, 0x0b, 0x60, - 0x4f, 0xf0, 0x04, 0x07, - 0x38, 0x44, 0x39, 0x44, - 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xf4, 0xd1, 0x00, 0xbe, + 0x04, 0x68, 0x0c, 0x60, + 0x00, 0xf1, 0x04, 0x00, + 0x01, 0xf1, 0x04, 0x01, + 0x04, 0x3a, 0xf7, 0xdc, + 0x00, 0xbe }; static const uint8_t loader_code_stm32f4[] = { // flashloaders/stm32f4.s - - 0xdf, 0xf8, 0x28, 0xc0, - 0xdf, 0xf8, 0x28, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, + 0xdf, 0xf8, 0x24, 0xc0, + 0xdf, 0xf8, 0x24, 0xa0, + 0xe2, 0x44, 0x04, 0x68, + 0x0c, 0x60, 0x00, 0xf1, 0x04, 0x00, 0x01, 0xf1, 0x04, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0x40, 0x14, 0xf0, + 0x01, 0x0f, 0xfa, 0xd1, + 0x04, 0x3a, 0xf2, 0xdc, 0x00, 0xbe, 0x00, 0xbf, 0x00, 0x3c, 0x02, 0x40, 0x0e, 0x00, 0x00, 0x00 @@ -103,17 +86,15 @@ static const uint8_t loader_code_stm32f4[] = { static const uint8_t loader_code_stm32f4_lv[] = { // flashloaders/stm32f4lv.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, + 0xdf, 0xf8, 0x24, 0xc0, + 0xdf, 0xf8, 0x24, 0xa0, + 0xe2, 0x44, 0x04, 0x78, + 0x0c, 0x70, 0x00, 0xf1, 0x01, 0x00, 0x01, 0xf1, 0x01, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0x40, 0x14, 0xf0, + 0x01, 0x0f, 0xfa, 0xd1, + 0x01, 0x3a, 0xf2, 0xdc, 0x00, 0xbe, 0x00, 0xbf, 0x00, 0x3c, 0x02, 0x40, 0x0e, 0x00, 0x00, 0x00 @@ -121,17 +102,16 @@ static const uint8_t loader_code_stm32f4_lv[] = { static const uint8_t loader_code_stm32l4[] = { // flashloaders/stm32l4.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x44, 0x68, 0x0b, 0x60, + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x05, 0x68, + 0x44, 0x68, 0x0d, 0x60, 0x4c, 0x60, 0x00, 0xf1, 0x08, 0x00, 0x01, 0xf1, - 0x08, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, + 0x08, 0x01, 0xda, 0xf8, + 0x00, 0x40, 0x14, 0xf4, + 0x80, 0x3f, 0xfa, 0xd1, + 0x08, 0x3a, 0xf0, 0xdc, 0x00, 0xbe, 0x00, 0xbf, 0x00, 0x20, 0x02, 0x40, 0x12, 0x00, 0x00, 0x00 @@ -139,17 +119,16 @@ static const uint8_t loader_code_stm32l4[] = { static const uint8_t loader_code_stm32f7[] = { // flashloaders/stm32f7.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x04, 0x68, + 0x0c, 0x60, 0x00, 0xf1, 0x04, 0x00, 0x01, 0xf1, 0x04, 0x01, 0xbf, 0xf3, 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0x40, 0x14, 0xf0, + 0x01, 0x0f, 0xfa, 0xd1, + 0x04, 0x3a, 0xf0, 0xdc, 0x00, 0xbe, 0x00, 0xbf, 0x00, 0x3c, 0x02, 0x40, 0x0e, 0x00, 0x00, 0x00 @@ -157,18 +136,16 @@ static const uint8_t loader_code_stm32f7[] = { static const uint8_t loader_code_stm32f7_lv[] = { // flashloaders/stm32f7lv.s - 0xdf, 0xf8, 0x30, 0xc0, - 0xdf, 0xf8, 0x30, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x04, 0x78, + 0x0c, 0x70, 0x00, 0xf1, 0x01, 0x00, 0x01, 0xf1, 0x01, 0x01, 0xbf, 0xf3, 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0x40, 0x14, 0xf0, + 0x01, 0x0f, 0xfa, 0xd1, + 0x01, 0x3a, 0xf0, 0xdc, 0x00, 0xbe, 0x00, 0xbf, 0x00, 0x3c, 0x02, 0x40, 0x0e, 0x00, 0x00, 0x00 @@ -234,8 +211,8 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { // STM32l - loader_code = loader_code_stm32l; - loader_size = sizeof(loader_code_stm32l); + loader_code = loader_code_stm32lx; + loader_size = sizeof(loader_code_stm32lx); } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_F1_HIGH || @@ -315,10 +292,9 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { struct stlink_reg rr; unsigned timeout; - size_t count = 0; uint32_t flash_base = 0; const char *error = NULL; - uint32_t dhcsr, dfsr; + uint32_t dhcsr, dfsr, cfsr, hfsr; DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); @@ -329,22 +305,6 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe return(-1); } - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - count = size / sizeof(uint16_t); - - if (size % sizeof(uint16_t)) { ++count; } - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4 || - sl->flash_type == STLINK_FLASH_TYPE_L0) { - count = size / sizeof(uint32_t); - - if (size % sizeof(uint32_t)) { ++count; } - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - count = size / sizeof(uint64_t); - - if (size % sizeof(uint64_t)) { ++count; } - } - if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (target >= FLASH_BANK2_START_ADDR)) { flash_base = FLASH_REGS_BANK2_OFS; } @@ -352,7 +312,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe /* Setup core */ stlink_write_reg(sl, fl->buf_addr, 0); // source stlink_write_reg(sl, target, 1); // target - stlink_write_reg(sl, (uint32_t)count, 2); // count + stlink_write_reg(sl, (uint32_t)size, 2); // count stlink_write_reg(sl, flash_base, 3); // flash register base // only used on VL/F1_XL, but harmless for others stlink_write_reg(sl, fl->loader_addr, 15); // pc register @@ -376,9 +336,9 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe usleep(10000); if (stlink_is_core_halted(sl)) { - timeout = 0; - break; - } + timeout = 0; + break; + } } if (timeout) { @@ -397,11 +357,14 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe return(0); error: - dhcsr = dfsr = 0; + dhcsr = dfsr = cfsr = hfsr = 0; stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); + stlink_read_debug32(sl, STLINK_REG_CFSR, &cfsr); + stlink_read_debug32(sl, STLINK_REG_HFSR, &hfsr); stlink_read_all_regs(sl, &rr); - ELOG("%s (R2 0x%08X R15 0x%08X DHCSR 0x%08X DFSR 0x%08X)\n", error, rr.r[2], rr.r[15], dhcsr, dfsr); + ELOG("%s (R2 0x%X R15 0x%X DHCSR 0x%X DFSR 0x%X CFSR 0x%X HFSR 0x%X)\n", error, rr.r[2], rr.r[15], dhcsr, dfsr, cfsr, hfsr); + ELOG("(R0 0x%X R1 0x%X)\n", rr.r[0], rr.r[1]); return(-1); } diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 6d2c9f1af..473231117 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -19,6 +19,12 @@ #define STLINK_REG_CM3_DWT_FUNn(n) (0xE0001028 + n*16) /* Cortex™-M3 Technical Reference Manual */ +/* Configurable Fault Status Register */ +#define STLINK_REG_CFSR 0xE000ED28 + +/* Hard Fault Status Register */ +#define STLINK_REG_HFSR 0xE000ED2C + /* Debug Halting Control and Status Register */ #define STLINK_REG_DFSR 0xE000ED30 #define STLINK_REG_DFSR_HALT (1 << 0) From 76f153035a90fc72dc075a75c3d0523c0e0f0ddb Mon Sep 17 00:00:00 2001 From: anton Date: Thu, 18 Mar 2021 23:03:10 +0500 Subject: [PATCH 1121/1435] flash_loader: disable interrupt before start --- src/common.c | 16 ++++++++++++++++ src/stlink-lib/flash_loader.c | 13 ++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/common.c b/src/common.c index 99049196d..eeccd5f5b 100644 --- a/src/common.c +++ b/src/common.c @@ -2730,6 +2730,13 @@ int stm32l1_write_half_pages( } int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { + + // force halt and disable interrupt + stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | + STLINK_REG_DHCSR_C_DEBUGEN | + STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_MASKINTS); + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_F7) || (sl->flash_type == STLINK_FLASH_TYPE_L4)) { @@ -2998,6 +3005,8 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr } int stlink_flashloader_stop(stlink_t *sl) { + uint32_t dhcsr; + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_F7) || (sl->flash_type == STLINK_FLASH_TYPE_L4) || @@ -3028,6 +3037,13 @@ int stlink_flashloader_stop(stlink_t *sl) { stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); } + // enable interrupt + if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) { + stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | + STLINK_REG_DHCSR_C_DEBUGEN | + (dhcsr&(~STLINK_REG_DHCSR_C_MASKINTS))); + } + return(0); } diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 5bc314b07..9fa897ccc 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -293,7 +293,6 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe struct stlink_reg rr; unsigned timeout; uint32_t flash_base = 0; - const char *error = NULL; uint32_t dhcsr, dfsr, cfsr, hfsr; DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); @@ -342,7 +341,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe } if (timeout) { - error = "Flash loader run error"; + ELOG("Flash loader run error\n"); goto error; } @@ -350,7 +349,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { - error = "Write error"; + ELOG("Write error\n"); goto error; } @@ -363,8 +362,12 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe stlink_read_debug32(sl, STLINK_REG_CFSR, &cfsr); stlink_read_debug32(sl, STLINK_REG_HFSR, &hfsr); stlink_read_all_regs(sl, &rr); - ELOG("%s (R2 0x%X R15 0x%X DHCSR 0x%X DFSR 0x%X CFSR 0x%X HFSR 0x%X)\n", error, rr.r[2], rr.r[15], dhcsr, dfsr, cfsr, hfsr); - ELOG("(R0 0x%X R1 0x%X)\n", rr.r[0], rr.r[1]); + + WLOG("Loader state: R2 0x%X R15 0x%X\n", rr.r[2], rr.r[15]); + if (dhcsr != 0x3000B || dfsr != 0x3 || cfsr || hfsr) { + WLOG("MCU state: DHCSR 0x%X DFSR 0x%X CFSR 0x%X HFSR 0x%X\n", + dhcsr, dfsr, cfsr, hfsr); + } return(-1); } From bc9062c6c590e603e203567b6bfe14baf4c6a0af Mon Sep 17 00:00:00 2001 From: anton Date: Fri, 19 Mar 2021 18:59:09 +0500 Subject: [PATCH 1122/1435] flash_loader: preventing unpredictable behavior when disabling interrupts --- src/common.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index eeccd5f5b..1fd023962 100644 --- a/src/common.c +++ b/src/common.c @@ -2731,7 +2731,11 @@ int stm32l1_write_half_pages( int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { - // force halt and disable interrupt + // According to DDI0419C, Table C1-7 firstly force halt + stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | + STLINK_REG_DHCSR_C_DEBUGEN | + STLINK_REG_DHCSR_C_HALT); + // and only then disable interrupts stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | STLINK_REG_DHCSR_C_HALT | From de89563057fca8d0aaa6b6dfa8655557523507e6 Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 20 Mar 2021 14:09:52 +0500 Subject: [PATCH 1123/1435] gdb-server: added target description for all mcu --- src/st-util/gdb-server.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 4177cef11..e35e5c2e8 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -288,7 +288,7 @@ int main(int argc, char** argv) { return(0); } -static const char* const target_description_F4 = +static const char* const target_description = "" "" "" @@ -1178,13 +1178,7 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("query: %s;%s\n", queryName, params); if (!strcmp(queryName, "Supported")) { - if (sl->chip_id == STLINK_CHIPID_STM32_F4 || - sl->chip_id == STLINK_CHIPID_STM32_F4_HD || - sl->core_id == STM32F7_CORE_ID) { - reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); - } else { - reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); - } + reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); } else if (!strcmp(queryName, "Xfer")) { char *type, *op, *__s_addr, *s_length; char *tok = params; @@ -1202,14 +1196,15 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", type, op, annex, addr, length); - const char* data = NULL; - - if (!strcmp(type, "memory-map") && !strcmp(op, "read")) { + const char* data; + if (strcmp(op, "read")) { + data = NULL; + } else if (!strcmp(type, "memory-map")) { data = current_memory_map; - } - - if (!strcmp(type, "features") && !strcmp(op, "read")) { - data = target_description_F4; + } else if (!strcmp(type, "features")) { + data = target_description; + } else { + data = NULL; } if (data) { @@ -1592,7 +1587,7 @@ int serve(stlink_t *sl, st_state_t *st) { reply = strdup("E00"); } - if (ret) { DLOG("p packet: stlink_read_unsupported_reg failed with id %u\n", id); } + if (ret) { DLOG("p packet: could not read register with id %u\n", id); } if (reply == NULL) { // if reply is set to "E00", skip From 9083d43d15ed53c575d48c71f6dbf31c8882b4f1 Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 20 Mar 2021 14:48:52 +0500 Subject: [PATCH 1124/1435] gdb-server: fixed initialization of flash segments --- src/st-util/gdb-server.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index e35e5c2e8..080d434b3 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -817,10 +817,11 @@ static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { } struct flash_block* new = malloc(sizeof(struct flash_block)); - new->next = flash_root; + new->next = flash_root; new->addr = addr; new->length = length; - new->data = calloc(length, 1); + new->data = malloc(length); + memset(new->data, stlink_get_erased_pattern(sl), length); flash_root = new; return(0); From 7c5ac5908cf16d1b1b8c7d355ac6856461aab3c4 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 20 Mar 2021 12:18:56 +0100 Subject: [PATCH 1125/1435] Updated travis CI config for macOS --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index fefafbaf1..5d2e5fbdf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -129,6 +129,8 @@ jobs: ### macOS ### - os: osx env: BADGE=osx + osx_image: xcode12.2 + name: macOS 10.15.7 compiler: gcc addons: homebrew: @@ -138,6 +140,8 @@ jobs: - gtk+3 - os: osx env: BADGE=osx + osx_image: xcode12.2 + name: macOS 10.15.7 compiler: clang addons: homebrew: From 5e0a502df812495bfa96fa9116a19f1306152b17 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 20 Mar 2021 15:44:09 +0100 Subject: [PATCH 1126/1435] General Project Update - Updated CHANGELOG.md - Updated README.md - [doc] Official STLINK-V3 support (Closes #820, Closes #1022, Closes #1025) - Updated list of contributors - Updated info on version support - Minor formatting fixes --- CHANGELOG.md | 3 ++ README.md | 18 +++---- contributors.txt | 1 + doc/compiling.md | 113 ++++++++++++++++++++--------------------- doc/version_support.md | 80 ++++++++++++++--------------- 5 files changed, 109 insertions(+), 106 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cacd79eef..7ca94dbc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Release date: (TBD) Features: - Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052)) +- Official support for STLINK-V3 programmers ([#820](https://github.com/stlink-org/stlink/pull/820), [#1022](https://github.com/stlink-org/stlink/pull/1022), [#1025](https://github.com/stlink-org/stlink/pull/1025)) - Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) - Option bytes on the STM32F767 ZIT6 Nucleo-144 ([#968](https://github.com/stlink-org/stlink/pull/968), [#997](https://github.com/stlink-org/stlink/pull/997)) - Use SetConsoleCtrlHandler for Windows ([#1021](https://github.com/stlink-org/stlink/pull/1021)) @@ -32,6 +33,7 @@ Updates & changes: Fixes: +- Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) - cmake compile failure with external `CMAKE_MODULE_PATH` set ([#962](https://github.com/stlink-org/stlink/pull/962)) - doc/man: Fixed installation directory ([#970](https://github.com/stlink-org/stlink/pull/970)) @@ -53,6 +55,7 @@ Fixes: - Fixed support for writing option bytes ([#1102](https://github.com/stlink-org/stlink/pull/1102)) - [doc] Corrected spelling mistake in bug report template ([#1103](https://github.com/stlink-org/stlink/pull/1103)) - Fixed support for STLINK/V1 programmer ([#1045](https://github.com/stlink-org/stlink/pull/1045), [#1105](https://github.com/stlink-org/stlink/pull/1105)) +- Fixed STM32WB55 reading DEBUG IDCODE from the wrong address ([#1100](https://github.com/stlink-org/stlink/pull/1100), [#1101](https://github.com/stlink-org/stlink/pull/1101)) # v1.6.1 diff --git a/README.md b/README.md index 8a8600947..7ddc78005 100644 --- a/README.md +++ b/README.md @@ -17,21 +17,24 @@ The stlink library and tools are licensed under the **[BSD-3 License](LICENSE.md ## Introduction -STLink is an open source toolset to program and debug STM32 devices and boards manufactured by STMicroelectronics. +stlink is an open source toolset to program and debug STM32 devices and boards manufactured by STMicroelectronics. It supports several so called STLINK programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG/SWD. There are four generations available on the market which are _all_ supported by this toolset: - **STLINK/V1** _[obsolete as of 21-11-2019, continued support by this toolset] \*)_ - transport layer: SCSI passthru commands over USB - - stand-alone programmer and present on STM32VL Discovery boards + - stand-alone programmer + - on-board on STM32VL Discovery boards - **STLINK/V2** - transport layer: raw USB commands - - stand-alone programmer and present on STM32L Discovery and Nucleo boards + - stand-alone programmer + - on-board on STM32L Discovery and STM32 Nucleo boards - **STLINK/V2-1** - transport layer: raw USB commands - - present on some STM32 Nucleo boards -- **STLINK/V3** + - on-board on some STM32 Nucleo boards +- **STLINK-V3** - transport layer: raw USB commands - - stand-alone programmer + - stand-alone programmer (STLINK-V3SET, STLINK-V3MINI, STLINK-V3MODS) + - on-board on some STM32 Nucleo boards _\*)_ **Note: Support for the STLINK/V1 on macOS is limited to 10.14 - 10.15. Due to the deprecation and removal of macOS Kernel Extensions (KEXT) there will be no support for this programmer on macOS 11 or any later version.** @@ -52,9 +55,6 @@ Currently known working combinations of programmers and targets are listed in [d Supported operating systems are listed in [version_support.md](doc/version_support.md). -The `stlink` toolset continues to maintain backwards compatibility with the **STLINK/v1** programmer.
      -Please note that on macOS this support is limited to versions 10.13 - 10.15. - ## Tutorial & HOWTO Our [tutorial](doc/tutorial.md) may help you along with some advanced tasks and additional info. diff --git a/contributors.txt b/contributors.txt index 38cc9cd42..88f1f0c89 100644 --- a/contributors.txt +++ b/contributors.txt @@ -113,6 +113,7 @@ Simon Wright Stany Marcel Stefan Misik Sven Wegener +Tarek Bochkati [tarek-bochkati] (STMicroelectronics) Timothy Lee [timothytylee] Tuomo Kaikkonen Theodore A. Roth diff --git a/doc/compiling.md b/doc/compiling.md index 07193f357..eef207f95 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -1,14 +1,14 @@ # Compiling from sources ## Microsoft Windows (10, 8.1) + ### Common Requirements On Windows users should ensure that the following software is installed: -* `git` (_optional, but recommended_) -* `cmake` (3.17.0 or later) -* `MinGW-w64` (7.0.0 or later) with GCC toolchain 8.1.0 - +- `git` (_optional, but recommended_) +- `cmake` (3.17.0 or later) +- `MinGW-w64` (7.0.0 or later) with GCC toolchain 8.1.0 ### Installation @@ -16,12 +16,14 @@ On Windows users should ensure that the following software is installed: 2. Install `cmake` from
      Ensure that you add cmake to the $PATH system variable when following the instructions by the setup assistant. 3. Install - - _EITHER_: **MinGW-w64** from (mingw-w64-install.exe)
      - - _OR_: **MSVC toolchain** from Visual Studio Build Tools 2019 + +- _EITHER_: **MinGW-w64** from (mingw-w64-install.exe)
      +- _OR_: **MSVC toolchain** from Visual Studio Build Tools 2019 + 4. Create a new destination folder at a place of your choice 5. Open the command-line (cmd.exe) and execute `cd C:\$Path-to-your-destination-folder$\` 6. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git`from the command-line (cmd.exe)
      - or download the stlink zip-sourcefolder from the Release page on GitHub + or download the stlink zip-sourcefolder from the Release page on GitHub #### MSVC toolchain - minimal installation @@ -31,15 +33,19 @@ Visual Studio IDE is not necessary, only Windows SDK & build tools are required 2. Navigate through menus as follows (might change overtime) `All downloads > Tools for Visual Studio 2019 > Build Tools for Visual Studio 2019 > Download` + 3. Start downloaded executable. After Visual Studio Installer bootstraps and main window pops up, open `Individual Components` tab, and pick - - latest build tools (eg. `MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.25)`) - - latest Windows SDK (eg. `Windows 10 SDK (10.0.18362.0)`) + +- latest build tools (eg. `MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.25)`) +- latest Windows SDK (eg. `Windows 10 SDK (10.0.18362.0)`) + 4. After installation finishes, you can press `Launch` button in Visual Studio Installer's main menu. - Thus you can open `Developer Command Prompt for VS 2019`. It is `cmd.exe` instance with adjusted PATHs including eg. `msbuild`. - Alternatively, you can use `Developer Powershell for VS 2019` which is the same thing for `powershell.exe`. Both are available from Start menu. - Another option is to add `msbuild` to PATH manually. Its location should be `C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin`. Then, it should be available from any `powershell.exe` or `cmd.exe` session. ### Building + #### MinGW-w64 1. Use the command-line to move to the `scripts` directory within the source-folder: `cd stlink\scripts\` @@ -50,7 +56,6 @@ Per default the build script (currently) uses `C:\Program Files\mingw-w64\x86_64 When installing different toolchains make sure to update the path in the `mingw64-build.bat`.
      This can be achieved by opening the .bat file with a common text editor. - #### MSVC toolchain 1. In a command prompt, change the directory to the folder where the stlink files were cloned (or unzipped) to. @@ -59,12 +64,15 @@ This can be achieved by opening the .bat file with a common text editor. This will create a solution file `stlink.sln` in the build folder. Now, you can build whole `stlink` suite using following command: + ``` msbuild /m /p:Configuration=Release stlink.sln ``` + Options: + - `/m` - compilation runs in parallel utilizing multiple cores -- `/p:Configuration=Release` - generates *Release*, optimized build. +- `/p:Configuration=Release` - generates _Release_, optimized build. Directory `\build\Release` contains final executables. (`st-util.exe` is located in `\build\src\gdbserver\Release`). @@ -79,25 +87,25 @@ It can be copied from: `\build\3rdparty\libusb-{version}\MS{arch}\ [ST-LINK drivers](https://www.st.com/en/development-tools/stsw-link009.html) are required for `stlink` to work. ## Linux + ### Common requirements Install the following packages from your package repository: -* `git` -* `gcc` or `clang` or `mingw32-gcc` or `mingw64-gcc` (C-compiler; very likely gcc is already present) -* `build-essential` (on Debian based distros (Debian, Ubuntu)) -* `cmake` (3.4.2 or later, use the latest version available from the repository) -* `rpm` (on Debian based distros (Debian, Ubuntu), needed for package build with `make package`) -* `libusb-1.0` -* `libusb-1.0-0-dev` (development headers for building) -* `libgtk-3-dev` (_optional_, needed for `stlink-gui`) -* `pandoc` (_optional_, needed for generating manpages from markdown) +- `git` +- `gcc` or `clang` or `mingw32-gcc` or `mingw64-gcc` (C-compiler; very likely gcc is already present) +- `build-essential` (on Debian based distros (Debian, Ubuntu)) +- `cmake` (3.4.2 or later, use the latest version available from the repository) +- `rpm` (on Debian based distros (Debian, Ubuntu), needed for package build with `make package`) +- `libusb-1.0` +- `libusb-1.0-0-dev` (development headers for building) +- `libgtk-3-dev` (_optional_, needed for `stlink-gui`) +- `pandoc` (_optional_, needed for generating manpages from markdown) or execute (Debian-based systems only): `apt-get install gcc build-essential cmake libusb-1.0 libusb-1.0-0-dev libgtk-3-dev pandoc` (Replace gcc with the intended C-compiler if necessary or leave out any optional package not needed.) - ### Installation 1. Open a new terminal console @@ -105,7 +113,6 @@ or execute (Debian-based systems only): `apt-get install gcc build-essential cma 3. Change to this directory: `cd ~/git` 4. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git` - ### Building #### Installation: @@ -120,21 +127,19 @@ or execute (Debian-based systems only): `apt-get install gcc build-essential cma As an option you may also install to an individual user-defined folder e.g `$HOME` with `make install DESTDIR=$HOME`. - -#### Removal: +#### Removal: 1. Run `make uninstall` to perform a clean uninstall of the package from the system. 2. Run `make clean` to clean the build-folder within the project source and remove all compiled and linked files and libraries. - ### Cross-Building for Windows Install the following packages from your package repository: -* `mingw-w64` -* `mingw-w64-common` -* `mingw-w64-i686-dev` -* `mingw-w64-x86-64-dev` +- `mingw-w64` +- `mingw-w64-common` +- `mingw-w64-i686-dev` +- `mingw-w64-x86-64-dev` After following the steps for installation above, proceed with from the build dircetory itself: @@ -144,7 +149,6 @@ $ sudo sh ./cmake/packaging/windows/generate_binaries.sh The generated zip-packages can be found in the subdirectory `./build/dist`. - ### Set device access permissions and the role of udev By default most distributions don't allow access to USB devices. @@ -162,22 +166,21 @@ $ sudo udevadm trigger udev will now create device node files, e.g. `/dev/stlinkv3_XX`, `/dev/stlinkv2_XX`, `/dev/stlinkv1_XX`. - ### Special note on the use of STLink/V1 programmers (legacy): As the STLINKV1's SCSI emulation is somehow broken, the best advice possibly is to tell your operating system to completely ignore it.
      Choose one of the following options _before_ connecting the device to your computer: -* `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` -* _OR_ - 1. `echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.conf` - 2. `modprobe -r usb-storage && modprobe usb-storage` -* _OR_ - 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` - 2. `modprobe -r usb-storage && modprobe usb-storage` - +- `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` +- _OR_ + 1. `echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.conf` + 2. `modprobe -r usb-storage && modprobe usb-storage` +- _OR_ + 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` + 2. `modprobe -r usb-storage && modprobe usb-storage` ## macOS + ### Common requirements The best and recommended way is to install a package manager for open source software, @@ -185,21 +188,20 @@ either [homebrew](https://brew.sh) or [MacPorts](https://www.macports.org/). Then install the following dependencies from the package repository: -* `git` -* `gcc` or `llvm` (for clang) (C-compiler) -* `cmake` -* `libusb` -* `gtk+3` or `gtk3` (_optional_, needed for `stlink-gui`) +- `git` +- `gcc` or `llvm` (for clang) (C-compiler) +- `cmake` +- `libusb` +- `gtk+3` or `gtk3` (_optional_, needed for `stlink-gui`) To do this with only one simple command, type: -* for homebrew: - - with gcc: `sudo brew install git gcc cmake libusb gtk+3` or - - with clang: `sudo brew install git llvm cmake libusb gtk+3` or -* for MacPorts: - - with gcc: `sudo port install git gcc10 cmake libusb gtk3` or - - with clang: `sudo port install git llvm-10 cmake libusb gtk3` - +- for homebrew: + - with gcc: `sudo brew install git gcc cmake libusb gtk+3` or + - with clang: `sudo brew install git llvm cmake libusb gtk+3` or +- for MacPorts: + - with gcc: `sudo port install git gcc10 cmake libusb gtk3` or + - with clang: `sudo port install git llvm-10 cmake libusb gtk3` ### Installation @@ -208,7 +210,6 @@ To do this with only one simple command, type: 3. Change to this directory: `cd ~/git` 4. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git` - ### Building 1. Change into the project source directory: `cd stlink` @@ -217,14 +218,13 @@ To do this with only one simple command, type: 4. Run `make debug` to create the _Debug_ target (_optional_)
      The debug target is only necessary in order to modify the sources and to run under a debugger. - ## Build options + ### Build using a different directory for shared libs To put the compiled shared libs into a different directory during installation, you can use the cmake option `cmake -DLIB_INSTALL_DIR:PATH="/usr/lib64" ..`. - ### Standard installation directories The cmake build system of this toolset includes `GNUInstallDirs` to define GNU standard installation directories. @@ -232,8 +232,7 @@ This module provides install directory variables as defined by the GNU Coding St Below are the preset default cmake options, which apply if none of these options are redefined: -* `-DCMAKE_INSTALL_SYSCONFDIR=/etc` -* `-DCMAKE_INSTALL_PREFIX=/usr/local` - +- `-DCMAKE_INSTALL_SYSCONFDIR=/etc` +- `-DCMAKE_INSTALL_PREFIX=/usr/local` Author: nightwalker-87 diff --git a/doc/version_support.md b/doc/version_support.md index eca491b79..1edf2e19c 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -23,52 +23,52 @@ NOTE: In order to use a STLINK/V1 programmer on macOS, versions 10.14 or 10.15 a ### Linux-/Unix-based: -| Operating System | libusb
      version | cmake
      version | gtk-3
      version | Notes | -| -------------------------------- | ----------------------- | ------------------ | ----------------------------------------- | --------------------------------------------------- | --------------------------------------------------- | -| Alpine Edge | 1.0.23 | 3.17.0 | 3.99.0
      gtk+3.0 | | -| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | 3.24.18
      libgtk+3 | | -| Arch Linux | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | -| Fedora Rawhide | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | named `libusbx`, but
      `libusb`-codebase is used | -| KaOS | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | -| OpenMandriva Cooker | 1.0.23 | 3.17.0 | 3.24.18
      libgtk+3.0
      lib64gtk+3.0 | | -| PCLinuxOS | 1.0.23
      lib64usb1.0 | 3.17.0 | 3.24.18
      lib64gtk+3.0 | | -| Slackware Current | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3 | | -| Solus | 1.0.23 | 3.16.5 | 3.24.16
      libgtk-3 | | -| Debian Sid | 1.0.23 | 3.16.3 | 3.24.18
      libgtk-3 | | -| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | 3.24.13
      libgtk+3.0
      lib64gtk+3.0 | | -| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | 3.24.17
      libgtk-3 | | -| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | 3.24.16
      gtk3 | | -| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.13
      gtk+3.0 | | -| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | 3.24.12
      libgtk-3 | | -| Mageia Cauldron | 1.0.22 | 3.17.0 | 3.24.18
      libgtk+3.0
      lib64gtk+3.0 | | -| NetBSD 9.0 | 1.0.22 | 3.16.1 | 3.24.12
      gtk+3 | | -| NetBSD 8.1 | 1.0.22 | 3.16.1 | 3.24.12
      gtk+3 | | -| NetBSD 7.2 | 1.0.22 | 3.16.1 | _N/A_ | | -| Alpine 3.10 | 1.0.22 | 3.14.5 | 3.24.8
      gtk+3.0 | | -| Fedora 31 | 1.0.22 | 3.14.5 | 3.24.12
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | -| Mageia 7.1 | 1.0.22 | 3.14.3 | 3.24.8
      libgtk+3.0
      lib64gtk+3.0 | | -| Fedora 30 | 1.0.22 | 3.14.2 | 3.24.8
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | -| Debian 10 (Buster) | 1.0.22 | 3.13.4 | 3.24.5
      libgtk-3 | | -| Alpine 3.9 | 1.0.22 | 3.13.0 | 3.24.1
      gtk+3.0 | | -| CentOS 8 | 1.0.22 | 3.11.4 | 3.22.30
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | -| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | 3.24.14
      gtk3 | | -| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | 3.22.30
      gtk3 | | -| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | 3.22.30
      libgtk-3 | | -| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | 3.22.11
      libgtk-3 | | -| Slackware 14.2 | **1.0.20** | 3.5.2 | 3.18.9
      gtk+3 | | -| Ubuntu 16.04 LTS (Xenial Xerus) | **1.0.20** | 3.5.1 | 3.18.9
      libgtk-3 | | -| OpenMandriva Lx 3.0 | **1.0.20** | **3.4.2** | 3.18.9
      libgtk+3.0
      lib64gtk+3.0 | | -| FreeBSD 13 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-13.0r358841
      (integrated) | -| FreeBSD 12 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-11.0r261448_4
      (integrated) | -| FreeBSD 11 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-11.0r261448_4
      (integrated) | +| Operating System | libusb
      version | cmake
      version | gtk-3
      version | Notes | +| -------------------------------- | ----------------------- | ------------------ | ----------------------------------------- | ----------------------------------------------------------------------------- | +| Alpine Edge | 1.0.23 | 3.17.0 | 3.99.0
      gtk+3.0 | | +| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | 3.24.18
      libgtk+3 | | +| Arch Linux | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | +| Fedora Rawhide | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | +| KaOS | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | +| OpenMandriva Cooker | 1.0.23 | 3.17.0 | 3.24.18
      libgtk+3.0
      lib64gtk+3.0 | | +| PCLinuxOS | 1.0.23
      lib64usb1.0 | 3.17.0 | 3.24.18
      lib64gtk+3.0 | | +| Slackware Current | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3 | | +| Solus | 1.0.23 | 3.16.5 | 3.24.16
      libgtk-3 | | +| Debian Sid | 1.0.23 | 3.16.3 | 3.24.18
      libgtk-3 | | +| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | 3.24.13
      libgtk+3.0
      lib64gtk+3.0 | | +| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | 3.24.17
      libgtk-3 | | +| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | 3.24.16
      gtk3 | | +| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.13
      gtk+3.0 | | +| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | 3.24.12
      libgtk-3 | | +| Mageia Cauldron | 1.0.22 | 3.17.0 | 3.24.18
      libgtk+3.0
      lib64gtk+3.0 | | +| NetBSD 9.0 | 1.0.22 | 3.16.1 | 3.24.12
      gtk+3 | | +| NetBSD 8.1 | 1.0.22 | 3.16.1 | 3.24.12
      gtk+3 | | +| NetBSD 7.2 | 1.0.22 | 3.16.1 | _N/A_ | | +| Alpine 3.10 | 1.0.22 | 3.14.5 | 3.24.8
      gtk+3.0 | | +| Fedora 31 | 1.0.22 | 3.14.5 | 3.24.12
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | +| Mageia 7.1 | 1.0.22 | 3.14.3 | 3.24.8
      libgtk+3.0
      lib64gtk+3.0 | | +| Fedora 30 | 1.0.22 | 3.14.2 | 3.24.8
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | +| Debian 10 (Buster) | 1.0.22 | 3.13.4 | 3.24.5
      libgtk-3 | | +| Alpine 3.9 | 1.0.22 | 3.13.0 | 3.24.1
      gtk+3.0 | | +| CentOS 8 | 1.0.22 | 3.11.4 | 3.22.30
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | +| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | 3.24.14
      gtk3 | | +| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | 3.22.30
      gtk3 | | +| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | 3.22.30
      libgtk-3 | | +| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | 3.22.11
      libgtk-3 | | +| Slackware 14.2 | 1.0.20 | 3.5.2 | 3.18.9
      gtk+3 | | +| Ubuntu 16.04 LTS (Xenial Xerus) | 1.0.20 | 3.5.1 | 3.18.9
      libgtk-3 | | +| OpenMandriva Lx 3.0x | 1.0.20 | **3.4.2** | 3.18.9
      libgtk+3.0
      lib64gtk+3.0 | | +| FreeBSD 13 | **1.0.16 - 1.0.18** | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-13.0r358841
      LIBUSB_API_VERSION 0x01000102
      (integrated) | +| FreeBSD 12 | **1.0.16 - 1.0.18** | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-13.0r358841
      LIBUSB_API_VERSION 0x01000102
      (integrated) | +| FreeBSD 11 | **1.0.16 - 1.0.18** | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-13.0r358841
      LIBUSB_API_VERSION 0x01000102
      (integrated) | ## Unsupported Operating Systems (as of Release v1.6.1) | Operating System | libusb
      version | cmake
      version | End of
      OS-Support | Notes | | ------------------------------ | ------------------- | ------------------ | ---------------------- | --------------------------------------------------- | | CentOS 7 | 1.0.21 | **2.8.12.2** | | named `libusbx`, but
      `libusb`-codebase is used | -| Debian 8 (Jessie) | 1.0.**19** | 3.**0.2** | Jun 2020 | -| Ubuntu 14.04 LTS (Trusty Tahr) | 1.0.**17** | **2.8.12.2** | Apr 2019 | +| Debian 8 (Jessie) | 1.0.19 | **3.0.2** | Jun 2020 | +| Ubuntu 14.04 LTS (Trusty Tahr) | 1.0.17 | **2.8.12.2** | Apr 2019 | | CentOS 6 | 1.0.**9** | **2.8.12.2** | Dec 2020 | named `libusbx`, but
      `libusb`-codebase is used | | Slackware 14.1 | 1.0.**9** | **2.8.12** | | | Slackware 14.0 | 1.0.**9** | **2.8.8** | | From 7c7ce954045d9734198d7345477b94bcf58f770e Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 21 Mar 2021 14:17:35 +0100 Subject: [PATCH 1127/1435] Create codeql-analysis.yml Setup for code scanning alerts --- .github/workflows/codeql-analysis.yml | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 000000000..202867cfc --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,67 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ develop, master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ develop ] + schedule: + - cron: '23 20 * * 2' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ 'cpp' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From ab6094a615f31653c1f0b355e05c5a29a338aa39 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 21 Mar 2021 14:26:10 +0100 Subject: [PATCH 1128/1435] Create cmake.yml Added Github Action - CMake Workflow Build and test a CMake based project. --- .github/workflows/cmake.yml | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/cmake.yml diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 000000000..005915e6e --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,46 @@ +name: CMake + +on: [push] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally + # well on Windows or Mac. You can convert this to a matrix build if you need + # cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Create Build Environment + # Some projects don't allow in-source building, so create a separate build directory + # We'll use this as our working directory for all subsequent commands + run: cmake -E make_directory ${{github.workspace}}/build + + - name: Configure CMake + # Use a bash shell so we can use the same syntax for environment variable + # access regardless of the host operating system + shell: bash + working-directory: ${{github.workspace}}/build + # Note the current convention is to use the -S and -B options here to specify source + # and build directories, but this is only available with CMake 3.13 and higher. + # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE + + - name: Build + working-directory: ${{github.workspace}}/build + shell: bash + # Execute the build. You can specify a specific target with "--target " + run: cmake --build . --config $BUILD_TYPE + + - name: Test + working-directory: ${{github.workspace}}/build + shell: bash + # Execute tests defined by the CMake configuration. + # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail + run: ctest -C $BUILD_TYPE From 812bc6ed4fae1078f00616d217a7b91e3480fa0f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 21 Mar 2021 14:58:45 +0100 Subject: [PATCH 1129/1435] Create c-cpp.yml Added Github Action - Make Workflow Build and test a C/C++ project using Make. --- .github/workflows/c-cpp.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/c-cpp.yml diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml new file mode 100644 index 000000000..e211e4e54 --- /dev/null +++ b/.github/workflows/c-cpp.yml @@ -0,0 +1,23 @@ +name: C/C++ CI + +on: + push: + branches: [ testing ] + pull_request: + branches: [ testing ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: configure + run: ./configure + - name: make + run: make + - name: make check + run: make check + - name: make distcheck + run: make distcheck From c677eb2f4dfd669bec7c73f1a324e0624908968a Mon Sep 17 00:00:00 2001 From: anton Date: Tue, 23 Mar 2021 20:06:47 +0500 Subject: [PATCH 1130/1435] flash_loader: makefile simplification --- flashloaders/Makefile | 75 +++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 50 deletions(-) diff --git a/flashloaders/Makefile b/flashloaders/Makefile index 3517e1499..d4ca4d22a 100644 --- a/flashloaders/Makefile +++ b/flashloaders/Makefile @@ -1,10 +1,7 @@ -# Note that according to the original GPLed code, compiling is noted to be -# as simple as gcc -c, this fails with my tests where this will lead to a wrong -# address read by the program. -# This makefile will save your time from dealing with compile errors -# Adjust CC if needed +# The flash loader code cannot be compiled by the system gcc. This +# makefile use arm-none-eabi-gcc for this purpose -CROSS_COMPILE ?= /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi- +CROSS_COMPILE ?= arm-none-eabi- CC = $(CROSS_COMPILE)gcc OBJCOPY = $(CROSS_COMPILE)objcopy @@ -12,52 +9,30 @@ OBJCOPY = $(CROSS_COMPILE)objcopy XXD = xxd XXDFLAGS = -i -c 4 -CFLAGS_THUMB1 = -mcpu=Cortex-M0 -Tlinker.ld -ffreestanding -nostdlib -CFLAGS_THUMB2 = -mcpu=Cortex-M3 -Tlinker.ld -ffreestanding -nostdlib +CFLAGS_ARMV6_M = -mcpu=Cortex-M0 -Tlinker.ld -ffreestanding -nostdlib +CFLAGS_ARMV7_M = -mcpu=Cortex-M3 -Tlinker.ld -ffreestanding -nostdlib all: stm32vl.h stm32f0.h stm32lx.h stm32f4.h stm32f4lv.h stm32l4.h stm32f7.h stm32f7lv.h + -stm32f0.h: stm32f0.s - $(CC) stm32f0.s $(CFLAGS_THUMB1) -o stm32f0.o - $(OBJCOPY) -O binary stm32f0.o stm32f0.bin - $(XXD) $(XXDFLAGS) stm32f0.bin stm32f0.h - -stm32vl.h: stm32f0.s - $(CC) stm32f0.s $(CFLAGS_THUMB2) -o stm32vl.o - $(OBJCOPY) -O binary stm32vl.o stm32vl.bin - $(XXD) $(XXDFLAGS) stm32vl.bin stm32vl.h - -stm32lx.h: stm32lx.s - $(CC) stm32lx.s $(CFLAGS_THUMB2) -o stm32lx.o - $(OBJCOPY) -O binary stm32lx.o stm32lx.bin - $(XXD) $(XXDFLAGS) stm32lx.bin stm32lx.h - -stm32f4.h: stm32f4.s - $(CC) stm32f4.s $(CFLAGS_THUMB2) -o stm32f4.o - $(OBJCOPY) -O binary stm32f4.o stm32f4.bin - $(XXD) $(XXDFLAGS) stm32f4.bin stm32f4.h - -stm32f4lv.h: stm32f4lv.s - $(CC) stm32f4lv.s $(CFLAGS_THUMB2) -o stm32f4lv.o - $(OBJCOPY) -O binary stm32f4lv.o stm32f4lv.bin - $(XXD) $(XXDFLAGS) stm32f4lv.bin stm32f4lv.h - -stm32l4.h: stm32l4.s - $(CC) stm32l4.s $(CFLAGS_THUMB2) -o stm32l4.o - $(OBJCOPY) -O binary stm32l4.o stm32l4.bin - $(XXD) $(XXDFLAGS) stm32l4.bin stm32l4.h - -stm32f7.h: stm32f7.s - $(CC) stm32f7.s $(CFLAGS_THUMB2) -o stm32f7.o - $(OBJCOPY) -O binary stm32f7.o stm32f7.bin - $(XXD) $(XXDFLAGS) stm32f7.bin stm32f7.h - -stm32f7lv.h: stm32f7lv.s - $(CC) stm32f7lv.s $(CFLAGS_THUMB2) -o stm32f7lv.o - $(OBJCOPY) -O binary stm32f7lv.o stm32f7lv.bin - $(XXD) $(XXDFLAGS) stm32f7lv.bin stm32f7lv.h +%.h: %.bin + $(XXD) $(XXDFLAGS) $< $@ + +%.bin: %.o + $(OBJCOPY) -O binary $< $@ + rm $< + +# separate rule for STM32F0 +stm32f0.o: stm32f0.s + $(CC) stm32f0.s $(CFLAGS_ARMV6_M) -o stm32f0.o + +# separate rule for STM32F1/F3 +stm32vl.o: stm32f0.s + $(CC) stm32f0.s $(CFLAGS_ARMV7_M) -o stm32vl.o + +# generic rule for all other ARMv7-M +%.o: *.s + $(CC) $< $(CFLAGS_ARMV7_M) -o $@ clean: - rm *.o - rm *.bin - rm *.h + rm -f *.h From ee2c9f508e3eaa39d72dd8d41dfe642800a4946e Mon Sep 17 00:00:00 2001 From: anton Date: Tue, 23 Mar 2021 22:33:00 +0500 Subject: [PATCH 1131/1435] Core ID reading rework --- inc/stm32.h | 7 ++++--- src/common.c | 41 ++++++++++++++++++++++++++++++++--------- src/stlink-lib/reg.h | 9 ++++++--- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/inc/stm32.h b/inc/stm32.h index ca56a12f5..7d60ab5de 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -8,9 +8,10 @@ #define STM32_H /* Cortex core ids */ -#define STM32VL_CORE_ID 0x1ba01477 -#define STM32F7_CORE_ID 0x5ba02477 -#define STM32H7_CORE_ID 0x6ba02477 // STM32H7 JTAG ID Code (RM0433 pg3065) +#define STM32VL_CORE_ID 0x1ba01477 +#define STM32F7_CORE_ID 0x5ba02477 +#define STM32H7_CORE_ID 0x6ba02477 // STM32H7 SWD ID Code +#define STM32H7_CORE_ID_JTAG 0x6ba00477 // STM32H7 JTAG ID Code (RM0433 pg3065) /* Constant STM32 memory map figures */ #define STM32_FLASH_BASE ((uint32_t)0x08000000) diff --git a/src/common.c b/src/common.c index 5f2746e3d..b5bb67e9e 100644 --- a/src/common.c +++ b/src/common.c @@ -1229,20 +1229,43 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &cpu_id)) cpu_id = 0; - // If the chip is an H7, read the chipid from the new address - if (sl->core_id == STM32H7_CORE_ID && cpu_id == STLINK_REG_CMx_CPUID_CM7) { + /* + * the chip_id register in the reference manual have + * DBGMCU_IDCODE / DBG_IDCODE name + * + */ + + uint32_t part_no = STLINK_REG_CM3_CPUID_PARTNO(cpu_id); + if ((sl->core_id == STM32H7_CORE_ID || + sl->core_id == STM32H7_CORE_ID_JTAG) && + part_no == STLINK_REG_CMx_CPUID_PARTNO_CM7) { // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) ret = stlink_read_debug32(sl, 0x5c001000, chip_id); - } - - if (*chip_id == 0) { + } else if (part_no == STLINK_REG_CMx_CPUID_PARTNO_CM0) { + // STM32F0 (RM0091, pg914; RM0360, pg713) + // STM32L0 (RM0377, pg813; RM0367, pg915; RM0376, pg917) + // STM32G0 (RM0444, pg1367) + ret = stlink_read_debug32(sl, 0x40015800, chip_id); + } else if (part_no == STLINK_REG_CMx_CPUID_PARTNO_CM33) { + // STM32L5 (RM0438, pg2157) + ret = stlink_read_debug32(sl, 0xE0044000, chip_id); + } else /* СM3, СM4, CM7 */ { // default chipid address + + // STM32F1 (RM0008, pg1087; RM0041, pg681) + // STM32F2 (RM0033, pg1326) + // STM32F3 (RM0316, pg1095; RM0313, pg874) + // STM32F7 (RM0385, pg1676; RM0410, pg1912) + // STM32L1 (RM0038, pg861) + // STM32L4 (RM0351, pg1840; RM0394, pg1560) + // STM32G4 (RM0440, pg2086) + // STM32WB (RM0434, pg1406) ret = stlink_read_debug32(sl, 0xE0042000, chip_id); - } - if (*chip_id == 0) { - // Try Corex M0 DBGMCU_IDCODE register address - ret = stlink_read_debug32(sl, 0x40015800, chip_id); + // Fix chip_id for F4 rev A errata, read CPU ID, as CoreID is the same for F2/F4 + if (*chip_id == 0x411 && (cpu_id & 0xfff0) == 0xc240) { + *chip_id = 0x413; + } } return(ret); diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 5a796d7e1..73f608cb6 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -3,9 +3,12 @@ #define STLINK_REG_CM3_CPUID 0xE000ED00 -#define STLINK_REG_CMx_CPUID_CM0 0x410CC200 -#define STLINK_REG_CMx_CPUID_CM3 0x412FC230 -#define STLINK_REG_CMx_CPUID_CM7 0x411FC272 +#define STLINK_REG_CM3_CPUID_PARTNO(cpuid) ((cpuid)&STLINK_REG_CMx_CPUID_PARTNO_MASK) +#define STLINK_REG_CMx_CPUID_PARTNO_MASK 0xFFF0 +#define STLINK_REG_CMx_CPUID_PARTNO_CM0 0xC200 +#define STLINK_REG_CMx_CPUID_PARTNO_CM3 0xC230 +#define STLINK_REG_CMx_CPUID_PARTNO_CM7 0xC270 +#define STLINK_REG_CMx_CPUID_PARTNO_CM33 0xD210 #define STLINK_REG_CM3_FP_CTRL 0xE0002000 // Flash Patch Control Register From 229c721189587760db5509c59b3c02e93e7035c8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 24 Mar 2021 23:26:38 +0100 Subject: [PATCH 1132/1435] General Project Update - Added basic security policy - Updated info on version support for macOS - Updated tutorial.md > Added reference for st-info --probe command > Added section on unknown chip id error (Closes #107, Closes #568, Closes #669) > Added information on HW reset pin issue (Closes #220, Closes #238) --- CHANGELOG.md | 18 ++++++++---- SECURITY.md | 20 +++++++++++++ doc/tutorial.md | 67 ++++++++++++++++++++++++++++++++---------- doc/version_support.md | 8 ++--- 4 files changed, 87 insertions(+), 26 deletions(-) create mode 100644 SECURITY.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ca94dbc8..e3f8e13b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,13 @@ # v1.6.2 -Release date: (TBD) +Release date: (planned H1/2021) Features: +- Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) - Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052)) -- Official support for STLINK-V3 programmers ([#820](https://github.com/stlink-org/stlink/pull/820), [#1022](https://github.com/stlink-org/stlink/pull/1022), [#1025](https://github.com/stlink-org/stlink/pull/1025)) +- Official support for STLINK-V3 programmers (commit [#5e0a502](https://github.com/stlink-org/stlink/commit/5e0a502df812495bfa96fa9116a19f1306152b17), [#820](https://github.com/stlink-org/stlink/pull/820), [#1022](https://github.com/stlink-org/stlink/pull/1022), [#1025](https://github.com/stlink-org/stlink/pull/1025)) - Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) - Option bytes on the STM32F767 ZIT6 Nucleo-144 ([#968](https://github.com/stlink-org/stlink/pull/968), [#997](https://github.com/stlink-org/stlink/pull/997)) - Use SetConsoleCtrlHandler for Windows ([#1021](https://github.com/stlink-org/stlink/pull/1021)) @@ -15,12 +16,13 @@ Features: - `st-util`: Add specialized memory map for STM32H7 devices ([#1060](https://github.com/stlink-org/stlink/pull/1060)) - Support for STM32F4 option bytes ([#1062](https://github.com/stlink-org/stlink/pull/1062)) - Link for WIN32 & APPLE with stlink-static ([#1069](https://github.com/stlink-org/stlink/pull/1069)) -- Extended support for STM32H7 ([#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) - ITM functionality for STLink/V2 and STM32Fxx chipsets ([#136](https://github.com/stlink-org/stlink/pull/136), [#179](https://github.com/stlink-org/stlink/pull/179), [#815](https://github.com/stlink-org/stlink/pull/815), [#1072](https://github.com/stlink-org/stlink/pull/1072)) - Included ITM functionality for building with MSVC ([#1080](https://github.com/stlink-org/stlink/pull/1080)) Updates & changes: +- [doc] Added tutorial section on unknown chip id error ([#107](https://github.com/stlink-org/stlink/pull/107), [#568](https://github.com/stlink-org/stlink/pull/568), +- [doc] Updated documentation on target resetting ([#261](https://github.com/stlink-org/stlink/pull/261), [#533](https://github.com/stlink-org/stlink/pull/533), [#1107](https://github.com/stlink-org/stlink/pull/1107)) - [doc] Added note on `(gdb) run` command (commit [#03793d4](https://github.com/stlink-org/stlink/commit/03793d42b6078344a9ef8ad55f1d5d0fc19e486e), [#267](https://github.com/stlink-org/stlink/pull/267)) - [doc] `st-flash --reset` parameter (one solution for #356) ([#642](https://github.com/stlink-org/stlink/pull/642)) - [refactoring] General maintenance ([#864](https://github.com/stlink-org/stlink/pull/864), [#976](https://github.com/stlink-org/stlink/pull/976), [#978](https://github.com/stlink-org/stlink/pull/978)) @@ -33,6 +35,7 @@ Updates & changes: Fixes: +- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) - Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) - cmake compile failure with external `CMAKE_MODULE_PATH` set ([#962](https://github.com/stlink-org/stlink/pull/962)) @@ -45,8 +48,10 @@ Fixes: - Fix for `mmap() size_t overflow` in `st-flash` ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) - [regression] `stlink-gui` installation issue on Ubuntu-18.04 ([#1001](https://github.com/stlink-org/stlink/pull/1001), [#1004](https://github.com/stlink-org/stlink/pull/1004), [#1006](https://github.com/stlink-org/stlink/pull/1006)) - `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027), [#1064](https://github.com/stlink-org/stlink/pull/1064), [#1065](https://github.com/stlink-org/stlink/pull/1065)) +- GDB: Fixed problems with target description ([#1013](https://github.com/stlink-org/stlink/pull/1013), [#1088](https://github.com/stlink-org/stlink/pull/1088), [#1109](https://github.com/stlink-org/stlink/pull/1109)) - [doc] Fixed wrong path for `rules.d` folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) - Use vl flashloader for all STM32F1 series ([#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) +- Fixed support for STLINK/V1 programmer ([#1045](https://github.com/stlink-org/stlink/pull/1045), [#1105](https://github.com/stlink-org/stlink/pull/1105)) - st-util v1.6.1 does not recognize option --freq (commit [#e576768](https://github.com/stlink-org/stlink/commit/e5767681f14de9851aa970a9299930ca68b2ed92), [#1055](https://github.com/stlink-org/stlink/pull/1055)) - Fixed `gettimeofday` for MSVC ([#1074](https://github.com/stlink-org/stlink/pull/1074)) - Bugfixes for compilation with clang ([#1076](https://github.com/stlink-org/stlink/pull/1076), [#1078](https://github.com/stlink-org/stlink/pull/1078)) @@ -54,7 +59,6 @@ Fixes: - [regression] Flash_loader: increased wait rounds for slow boards ([#1085](https://github.com/stlink-org/stlink/pull/1085)) - Fixed support for writing option bytes ([#1102](https://github.com/stlink-org/stlink/pull/1102)) - [doc] Corrected spelling mistake in bug report template ([#1103](https://github.com/stlink-org/stlink/pull/1103)) -- Fixed support for STLINK/V1 programmer ([#1045](https://github.com/stlink-org/stlink/pull/1045), [#1105](https://github.com/stlink-org/stlink/pull/1105)) - Fixed STM32WB55 reading DEBUG IDCODE from the wrong address ([#1100](https://github.com/stlink-org/stlink/pull/1100), [#1101](https://github.com/stlink-org/stlink/pull/1101)) # v1.6.1 @@ -179,8 +183,8 @@ Major changes and added features: Updates and fixes: -- Fixed `unkown chip id`, piped output and `st-util -v` ([#107](https://github.com/stlink-org/stlink/pull/107), [#665](https://github.com/stlink-org/stlink/pull/665), [#763](https://github.com/stlink-org/stlink/pull/763)) - Fixed an issue with versioning stuck at 1.4.0 for versions cloned with git ([#563](https://github.com/stlink-org/stlink/pull/563), [#762](https://github.com/stlink-org/stlink/pull/762), [#772](https://github.com/stlink-org/stlink/pull/772)) +- Fixed `unkown chip id`, piped output and `st-util -v` ([#665](https://github.com/stlink-org/stlink/pull/665), [#763](https://github.com/stlink-org/stlink/pull/763)) - Updated STM32F3xx chip ID that covers a few different devices ([#685](https://github.com/stlink-org/stlink/pull/685), [#758](https://github.com/stlink-org/stlink/pull/758)) - Made udev rules and modprobe conf installation optional ([#741](https://github.com/stlink-org/stlink/pull/741)) - Fixed case when `__FILE__` doesn't contain either `/` nor `\\` ([#745](https://github.com/stlink-org/stlink/pull/745)) @@ -385,12 +389,14 @@ Updates and fixes: - Fixed STM32F2xx memory map (Nicolas Schodet) - Memory map for STM32F42xxx and STM32F43xxx devices (Craig Lilley) - Stm32l0x flash loader (Robin Kreis) -- Use libusb synchronous api ([#194](https://github.com/stlink-org/stlink/pull/194), [#374](https://github.com/stlink-org/stlink/pull/374)) +- Modified determination of erased byte pattern when flashing ([#193](https://github.com/stlink-org/stlink/pull/193), [#377](https://github.com/stlink-org/stlink/pull/377)) +- Use libusb synchronous api ([#194](https://github.com/stlink-org/stlink/pull/194), [#225](https://github.com/stlink-org/stlink/pull/225), [#374](https://github.com/stlink-org/stlink/pull/374)) - Fixed segfault when programmer is already busy and `NULL` pointers are in the list ([#256](https://github.com/stlink-org/stlink/pull/256), [#394](https://github.com/stlink-org/stlink/pull/394)) - Fixed issue where "unknown chip id!" was seen every other time ([#352](https://github.com/stlink-org/stlink/pull/352), [#367](https://github.com/stlink-org/stlink/pull/367), [#381](https://github.com/stlink-org/stlink/pull/381)) - Send F4 memory-map and features for STM32F429 ([#188](https://github.com/stlink-org/stlink/pull/188), [#196](https://github.com/stlink-org/stlink/pull/196), [#250](https://github.com/stlink-org/stlink/pull/250), [#251](https://github.com/stlink-org/stlink/pull/251)) (Release v1.1.0) - Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/stlink-org/stlink/pull/218), [#288](https://github.com/stlink-org/stlink/pull/288)) (Release v1.1.0) - Reset: st-flash does not work when CPU is in sleep mode ([#62](https://github.com/stlink-org/stlink/pull/62)) (Release v1.0.0) +- Ensure USB device search succeeds if the matched device is at index 0 ([#126](https://github.com/stlink-org/stlink/pull/126), [#151](https://github.com/stlink-org/stlink/pull/151)) (Release v1.0.0) - Corrected flash size register address for STM32F2 devices ([#278](https://github.com/stlink-org/stlink/pull/278)) (Release v1.0.0) Chip support added for: diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..caa2740db --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,20 @@ +# Security Policy + +## Supported Versions + +The following versions of the stlink toolset are currently being supported.
      As this is a development toolset, please note that bugfixes will only be applied to the latest version. + +| Version | Supported | +| ------- | ------------------ | +| develop | :white_check_mark: | +| 1.6.x | :white_check_mark: | +| 1.5.x | :x: | +| 1.4.0 | :x: | +| 1.3.x | :x: | +| 1.2.0 | :x: | +| 1.1.0 | :x: | +| 1.0.0 | :x: | + +## Reporting a Vulnerability + +Detected vulnerabilities in the toolset should be reported by opening a regular bugreport issue. diff --git a/doc/tutorial.md b/doc/tutorial.md index d4cf89ce2..8b1220747 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -2,15 +2,16 @@ ## Available tools and options -| Option | Tool | Description | Available
      since | -| --------------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k
      for the STM32F103C8T6 to assume 128k of flash being present. This option accepts
      decimal (128k), octal 0200k, or hex 0x80k values. Leaving the multiplier out is
      equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional "k"
      or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | -| --freq=n[k][m] | st-flash | The frequency of the SWD/JTAG interface can be specified, to override the default
      1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
      the unit `Hz` being left out. Valid frequencies are: `5K, 15K, 25K, 50K, 100K,`
      `125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | -| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at
      the end of binary file. This may cause some garbage data left after a flash operation.
      This option was enabled by default in earlier releases. | v1.6.1 | -| --reset | st-flash | Trigger a reset both before and after flashing. The default use the hardware reset
      through `NRST` pin. The software system reset is used if the hardware reset failed
      (`NRST` pin not connected). | v1.0.0 | -| --connect-under-reset | st-flash | Connect under reset. Option makes it possible to connect to the device before code
      executing. This is useful when the target contains a code that go device to sleep,
      disables of debug pins or other special code. | v1.6.1 | -| --version | st-info
      st-flash
      st-util | Print version information. | | -| --help | st-flash
      st-util | Print list of available commands. _(To be added to this table.)_ | | +| Option | Tool | Description | Available
      since | +| --------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | +| --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k for the STM32F103C8T6
      to assume 128k of flash being present. This option accepts decimal (128k), octal 0200k, or hex 0x80k values.
      Leaving the multiplier out is equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional
      "k" or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | +| --freq=n[k][m] | st-flash | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
      This option solely accepts decimal values (5K or 1.8M) with the unit `Hz` being left out. Valid frequencies are:
      `5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | +| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
      This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | +| --reset | st-flash | Trigger a reset both before and after flashing. The default uses the hardware reset through `NRST` pin.
      The software reset is used if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | +| --connect-under-reset | st-flash | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
      when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | +| --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | +| --version | st-info
      st-flash
      st-util | Print version information. | v1.3.0 | +| --help | st-flash
      st-util | Print list of available commands. | | ### st-flash: Checksum for binary files @@ -102,17 +103,52 @@ Check your hardware and try to identify what you have in front of you before ass Please let us know, if you come across any further websites or tutorials that help to identify STM32 fake chips so we can list them here to help others. ---- +### c) Appearance of the warning message `WARN src/common.c: unknown chip id!` + +The chip ID is the main identifier for STM32 MCU and their specific type and provides primary information on flash and SRAM architecture. +This so called `DBGMCU_IDCODE` register is allocated either at memory address `0xE0042000` or `0x40015800`. + +A failure of chip identification results in the error `WARN src/common.c: unknown chip id!`. +There are different variants of this message that refer to different issues: + +- `unknown chip id! 0` --> _currently unknown_ +- `unknown chip id! 0x1a` --> _currently unknown_ +- `unknown chip id! 0x001f` --> _currently unknown_ +- `unknown chip id! 0x3e8` --> _currently unknown_ +- `unknown chip id! 0xa05f0000` --> _currently unknown_ +- `unknown chip id! 0x3748` --> A target chip / board cannot be detected. + 1. No target is connected --> In this case `st-info --probe` displays `chip id 0x0748` with STLINK/V2 and `chip id 0x03e8` with STLINK-V3. + 2. The chip is connected but has gone into an undefined state of operation where the SWD pins are unresponsive. --> Try to use `--connect-under-reset` while pressing the reset button on the target board. + 3. A firmware-issue prevents the programmer from normal operation. --> Ensure that your programmer runs the latest firmware version and consider to upgrade any older version by using the official firmware upgrade tool provided by STMicroelectronics. +- `unknown chip id! 0xe0042000` --> The memory register holding the information on the chip ID could not be read. The following problems may lead to this case: + 1. This problem is caused by the SWDIO and SWCLK being configured for other purpose (GPIO, etc) other than Serial Wire configuration or Jtag --> A possible solution to this is to short the `BOOT0` pin with `VDD` (1) and to reset the chip / board by the execuing `st-flash erase` in order to return the MCU back to normal operation. Afterwards `BOOT0` should be set back to `GND` (0). + 2. There is a hardware defect in the connection between the MCU and the used programmer (solder points, cables, connectors). + +### d) Understanding hardware and software reset functionality for `st-flash` and reset-related device recovery + +Typically a reset signal is sent via the reset pin `NRST`. Using `st-flash` for flashing results in the following behaviour: -( Content below is currently unrevised and may be outdated as of Apr 2020. ) +- without the `--reset` option: `st-flash write` results in one reset signal on the `NRST` line +- with the `--reset` option: `st-flash write --reset` results in two subsequent reset signals on the `NRST` line -# Using STM32 discovery kits with open source tools +Depending on the used programmer the hardware reset line is not always connected. +This is especially the case for low-cost STLINK/V2 clone programmers. +Here the SWD connector consists of only 4 pins: `VCC`, `SWCLK`, `GND` and `SWDATA`. -This guide details the use of STMicroelectronics STM32 discovery kits in an open source environment. +When the physical reset line `NRST` is not connected, a reset is initiated by software via `SWD_SWDIO/JTAG_TMS` (software reset). +Just as mentioned above, flashing is possible here eiher with and without the `--reset` option. -## Installing a GNU toolchain +Configuring the STM32 pin `JTAG_TMS/SWD_SWDIO` as an output now also prevents the SWD interface from flashing and resetting the device. +In consequence this constellation typically requires a _hard reset_ to allow for the ST-Link/V2 programmer to reconnect to the target at all. -Any toolchain supporting the cortex m3 should do. +As soon as the device is in DFU mode, the `JTAG_TMS/SWD_SWDIO` pin is left in the default state with all JTAG pins available. +Here flashing of the device is now possible with and without the `--reset` option. + +The debug command `(gdb) monitor jtag_reset` sends a _hard reset_ signal via the `NRST` pin to reset the device and allows for flashing it (again). + +--- + +( Content below is currently unrevised and may be outdated as of Mar 2021. ) ## Using the GDB server @@ -201,7 +237,6 @@ Of course, you can use this instead of the gdb server, if you prefer. Just remember to use the “.bin” image, rather than the .elf file. ``` - # write blink.bin into FLASH $> [sudo] ./st-flash write fancy_blink.bin 0x08000000 ``` diff --git a/doc/version_support.md b/doc/version_support.md index 1edf2e19c..5d2cdd375 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -14,10 +14,10 @@ Thus no user interaction regarding libusb is necessary. ### Apple macOS -| Package Repository | libusb
      version | cmake
      version | gtk-3
      version | Supported macOS versions | -| ------------------ | ------------------- | ------------------ | ------------------ | -------------------------------------- | -| homebrew | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3 | 10.12 (Sierra)- 10.15 (Catalina) | -| MacPorts | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | 10.6 (Snow Leopard) - 10.15 (Catalina) | +| Package Repository | libusb
      version | cmake
      version | gtk-3
      version | Supported macOS versions | +| ------------------ | ------------------- | ------------------ | ------------------ | ------------------------ | +| homebrew | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3 | 10.9 - 10.15 | +| MacPorts | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | 10.4 - 10.15 | NOTE: In order to use a STLINK/V1 programmer on macOS, versions 10.14 or 10.15 are required. From b387c93ee007a2bde37daba8198a2108ec9704e5 Mon Sep 17 00:00:00 2001 From: anton Date: Thu, 25 Mar 2021 19:25:33 +0500 Subject: [PATCH 1133/1435] Extended set of command line arguments st-info: added --freq, --hot-plug and --connect-under-reset to probe st-util: added --freq --- doc/tutorial.md | 7 ++-- src/st-flash/flash.c | 11 +++--- src/st-flash/flash.h | 2 +- src/st-flash/flash_opts.c | 57 ++++++++---------------------- src/st-info/info.c | 74 +++++++++++++++++++++------------------ src/st-util/gdb-server.c | 36 ++++++++++++------- src/stlink-lib/helper.c | 14 ++++++++ src/stlink-lib/helper.h | 2 ++ src/stlink-lib/usb.c | 19 +++++----- src/stlink-lib/usb.h | 12 +++++-- 10 files changed, 122 insertions(+), 112 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 8b1220747..2403590ac 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -5,10 +5,11 @@ | Option | Tool | Description | Available
      since | | --------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | | --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k for the STM32F103C8T6
      to assume 128k of flash being present. This option accepts decimal (128k), octal 0200k, or hex 0x80k values.
      Leaving the multiplier out is equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional
      "k" or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | -| --freq=n[k][m] | st-flash | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
      This option solely accepts decimal values (5K or 1.8M) with the unit `Hz` being left out. Valid frequencies are:
      `5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | +| --freq=n[k][m] | st-info
      st-flash
      st-util | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
      This option solely accepts decimal values (5K or 1.8M) with the unit `Hz` being left out. Valid frequencies are:
      `5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K, 1800K, 4000K(4M)`. | v1.6.1 | | --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
      This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | | --reset | st-flash | Trigger a reset both before and after flashing. The default uses the hardware reset through `NRST` pin.
      The software reset is used if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | -| --connect-under-reset | st-flash | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
      when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | +| --connect-under-reset | st-info
      st-flash | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
      when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | +| --hot-plug | st-info
      st-util | Connect to the target without reset. | v1.6.2 | | --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | | --version | st-info
      st-flash
      st-util | Print version information. | v1.3.0 | | --help | st-flash
      st-util | Print list of available commands. | | @@ -262,7 +263,7 @@ There are a few options: -m, --multi Set gdb server to extended mode. st-util will continue listening for connections after disconnect. - -n, --no-reset + -n, --no-reset, --hot-plug Do not reset board on connection. ``` diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 447daa158..5a226d57b 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -26,9 +26,9 @@ static void cleanup(int signum) { } static void usage(void) { - puts("command line: ./st-flash [--debug] [--reset] [--connect-under-reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); - puts("command line: ./st-flash [--debug] [--connect-under-reset] [--freq=] [--serial ] erase"); - puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); + puts("command line: ./st-flash [--debug] [--reset] [--connect-under-reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); + puts("command line: ./st-flash [--debug] [--connect-under-reset] [--freq=] [--serial ] erase"); + puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); puts(" , and : Use hex format."); puts(" : Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); puts(" : Can be 'binary' (default) or 'ihex', although must be specified for binary format only."); @@ -52,6 +52,7 @@ int main(int ac, char** av) { uint8_t * mem = NULL; o.size = 0; + o.connect = CONNECT_NORMAL; if (flash_get_opts(&o, ac - 1, av + 1) == -1) { printf("invalid command line\n"); @@ -61,9 +62,7 @@ int main(int ac, char** av) { printf("st-flash %s\n", STLINK_VERSION); - sl = stlink_open_usb(o.log_level, - o.connect_under_reset ? 2 : 1, - (char *)o.serial, o.freq); + sl = stlink_open_usb(o.log_level, o.connect, (char *)o.serial, o.freq); if (sl == NULL) { return(-1); } diff --git a/src/st-flash/flash.h b/src/st-flash/flash.h index 8a5c2ad29..cd08db70f 100644 --- a/src/st-flash/flash.h +++ b/src/st-flash/flash.h @@ -26,7 +26,7 @@ struct flash_opts { size_t flash_size; // --flash=n[k][m] int opt; // enable empty tail data drop optimization int freq; // --freq=n[k][m] frequency of JTAG/SWD - bool connect_under_reset; + enum connect_type connect; }; #define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 7d846e425..63774ea25 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -2,6 +2,8 @@ #include #include +#include + #include "flash.h" static bool starts_with(const char * str, const char * prefix) { @@ -140,50 +142,21 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { return(-1); } - } else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) { - const char* freq; - - if (strcmp(av[0], "--freq") == 0) { - ac--; - av++; - - if (ac < 1) { - return(-1); - } + } else if (strcmp(av[0], "--freq") == 0) { + ac--; + av++; - freq = av[0]; - } else { - freq = av[0] + strlen("--freq="); + if (ac < 1) { + return(-1); } - if (strcmp(freq, "5K") == 0 || strcmp(freq, "5k") == 0) { - o->freq = 5; - } else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) { - o->freq = 15; - } else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) { - o->freq = 25; - } else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) { - o->freq = 50; - } else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) { - o->freq = 100; - } else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) { - o->freq = 125; - } else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) { - o->freq = 240; - } else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) { - o->freq = 480; - } else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) { - o->freq = 950; - } else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || - strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) { - o->freq = 1200; - } else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || - strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) { - o->freq = 1800; - } else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || - strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) { - o->freq = 4000; - } else { + o->freq = arg_parse_freq(av[0]); + if (o->freq < 0) { + return(-1); + } + } else if (starts_with(av[0], "--freq=")) { + o->freq = arg_parse_freq(av[0] + strlen("--freq=")); + if (o->freq < 0) { return(-1); } } else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { @@ -219,7 +192,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { o->flash_size = (size_t)flash_size; } } else if (strcmp(av[0], "--connect-under-reset") == 0) { - o->connect_under_reset = true; + o->connect = CONNECT_UNDER_RESET; } else { break; // non-option found diff --git a/src/st-info/info.c b/src/st-info/info.c index c1ac86373..a6b4e85c6 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -4,16 +4,17 @@ #include #include +#include static void usage(void) { puts("st-info --version"); - puts("st-info --probe"); + puts("st-info --probe [--connect-under-reset] [--hot-plug] [--freq=]"); puts("st-info --serial"); - puts("st-info --flash [--connect-under-reset]"); - puts("st-info --pagesize [--connect-under-reset]"); - puts("st-info --sram [--connect-under-reset]"); - puts("st-info --chipid [--connect-under-reset]"); - puts("st-info --descr [--connect-under-reset]"); + puts("st-info --flash [--connect-under-reset] [--hot-plug] [--freq=]"); + puts("st-info --pagesize [--connect-under-reset] [--hot-plug] [--freq=]"); + puts("st-info --sram [--connect-under-reset] [--hot-plug] [--freq=]"); + puts("st-info --chipid [--connect-under-reset] [--hot-plug] [--freq=]"); + puts("st-info --descr [--connect-under-reset] [--hot-plug] [--freq=]"); } static void stlink_print_version(stlink_t *sl) { @@ -45,11 +46,11 @@ static void stlink_print_info(stlink_t *sl) { if (params) { printf(" descr: %s\n", params->description); } } -static void stlink_probe(void) { +static void stlink_probe(enum connect_type connect, int freq) { stlink_t **stdevs; size_t size; - size = stlink_probe_usb(&stdevs); + size = stlink_probe_usb(&stdevs, connect, freq); printf("Found %u stlink programmers\n", (unsigned int)size); @@ -61,44 +62,47 @@ static void stlink_probe(void) { stlink_probe_usb_free(&stdevs, size); } -static stlink_t *stlink_open_first(bool under_reset) { +static int print_data(int ac, char **av) { stlink_t* sl = NULL; - sl = stlink_v1_open(0, 1); + enum connect_type connect = CONNECT_NORMAL; + int freq = 0; - if (sl == NULL) { - if (under_reset) { - sl = stlink_open_usb(0, 2, NULL, 0); - } else { - sl = stlink_open_usb(0, 1, NULL, 0); - } + if (strcmp(av[1], "--version") == 0) { + printf("v%s\n", STLINK_VERSION); + return(0); } - return(sl); -} + for (int i=2; i= 0) { continue; } + } + } else if (strncmp(av[i], "--freq=", 7) == 0) { + freq = arg_parse_freq(av[i] + 7); + if (freq >= 0) { continue; } + } -static int print_data(int ac, char **av) { - stlink_t* sl = NULL; - bool under_reset = false; + printf("Incorrect argument: %s\n\n", av[i]); + usage(); + return(-1); + } // probe needs all devices unclaimed if (strcmp(av[1], "--probe") == 0) { - stlink_probe(); - return(0); - } else if (strcmp(av[1], "--version") == 0) { - printf("v%s\n", STLINK_VERSION); + stlink_probe(connect, freq); return(0); } - if (ac == 3) { - if (strcmp(av[2], "--connect-under-reset") == 0) { - under_reset = true; - } else { - usage(); - return(-1); - } - } - - sl = stlink_open_first(under_reset); + // open first st-link device + sl = stlink_open_usb(0, connect, NULL, freq); if (sl == NULL) { return(-1); } diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index d7ca6d008..3dc3073e5 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -26,6 +26,7 @@ #endif #include +#include #include #include "gdb-remote.h" #include "gdb-server.h" @@ -63,7 +64,8 @@ typedef struct _st_state_t { int logging_level; int listen_port; int persistent; - int reset; + enum connect_type connect_mode; + int freq; } st_state_t; @@ -100,9 +102,9 @@ static stlink_t* do_connect(st_state_t *st) { stlink_t *sl = NULL; if (serial_specified) { - sl = stlink_open_usb(st->logging_level, st->reset, serialnumber, 0); + sl = stlink_open_usb(st->logging_level, st->connect_mode, serialnumber, st->freq); } else { - sl = stlink_open_usb(st->logging_level, st->reset, NULL, 0); + sl = stlink_open_usb(st->logging_level, st->connect_mode, NULL, st->freq); } return(sl); @@ -116,6 +118,8 @@ int parse_options(int argc, char** argv, st_state_t *st) { {"listen_port", required_argument, NULL, 'p'}, {"multi", optional_argument, NULL, 'm'}, {"no-reset", optional_argument, NULL, 'n'}, + {"hot-plug", optional_argument, NULL, 'n'}, + {"freq", optional_argument, NULL, 'F'}, {"version", no_argument, NULL, 'V'}, {"semihosting", no_argument, NULL, SEMIHOSTING_OPTION}, {"serial", required_argument, NULL, SERIAL_OPTION}, @@ -126,16 +130,16 @@ int parse_options(int argc, char** argv, st_state_t *st) { " -V, --version\t\tPrint the version\n" " -vXX, --verbose=XX\tSpecify a specific verbosity level (0..99)\n" " -v, --verbose\t\tSpecify generally verbose logging\n" - "\t\t\tChoose what version of stlink to use, (defaults to 2)\n" - " -1, --stlinkv1\tForce stlink version 1\n" " -p 4242, --listen_port=1234\n" "\t\t\tSet the gdb server listen port. " "(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n" " -m, --multi\n" "\t\t\tSet gdb server to extended mode.\n" "\t\t\tst-util will continue listening for connections after disconnect.\n" - " -n, --no-reset\n" + " -n, --no-reset, --hot-plug\n" "\t\t\tDo not reset board on connection.\n" + " -F 1800K, --freq=1M\n" + "\t\t\tSet the frequency of the SWD/JTAG interface.\n" " --semihosting\n" "\t\t\tEnable semihosting support.\n" " --serial \n" @@ -160,7 +164,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { exit(EXIT_SUCCESS); break; case 'v': - if (optarg) { st->logging_level = atoi(optarg); } else { @@ -170,7 +173,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { break; case 'p': sscanf(optarg, "%i", &q); - if (q < 0) { fprintf(stderr, "Can't use a negative port to listen on: %d\n", q); exit(EXIT_FAILURE); @@ -178,11 +180,19 @@ int parse_options(int argc, char** argv, st_state_t *st) { st->listen_port = q; break; + case 'm': st->persistent = 1; break; case 'n': - st->reset = 0; + st->connect_mode = CONNECT_HOT_PLUG; + break; + case 'F': + st->freq = arg_parse_freq(optarg); + if (st->freq < 0) { + fprintf(stderr, "Can't parse a frequency: %s\n", optarg); + exit(EXIT_FAILURE); + } break; case 'V': printf("v%s\n", STLINK_VERSION); @@ -217,7 +227,7 @@ int main(int argc, char** argv) { // set defaults ... state.logging_level = DEFAULT_LOGGING_LEVEL; state.listen_port = DEFAULT_GDB_LISTEN_PORT; - state.reset = 1; // by default, reset board + state.connect_mode = CONNECT_NORMAL; // by default, reset board parse_options(argc, argv, &state); printf("st-util\n"); @@ -240,7 +250,7 @@ int main(int argc, char** argv) { signal(SIGSEGV, &cleanup); #endif - if (state.reset) { stlink_reset(sl); } + if (state.connect_mode != CONNECT_HOT_PLUG) { stlink_reset(sl); } DLOG("Chip ID is %#010x, Core ID is %#08x.\n", sl->chip_id, sl->core_id); @@ -1111,7 +1121,7 @@ int serve(stlink_t *sl, st_state_t *st) { stlink_force_debug(sl); - if (st->reset) { stlink_reset(sl); } + if (st->connect_mode != CONNECT_HOT_PLUG) { stlink_reset(sl); } init_code_breakpoints(sl); init_data_watchpoints(sl); @@ -1840,7 +1850,7 @@ int serve(stlink_t *sl, st_state_t *st) { connected_stlink = sl; - if (st->reset) { stlink_reset(sl); } + if (st->connect_mode != CONNECT_HOT_PLUG) { stlink_reset(sl); } ret = stlink_force_debug(sl); diff --git a/src/stlink-lib/helper.c b/src/stlink-lib/helper.c index 32d9b6c8d..1f0f71b8d 100644 --- a/src/stlink-lib/helper.c +++ b/src/stlink-lib/helper.c @@ -1,6 +1,7 @@ #include #include +#include #ifdef STLINK_HAVE_SYS_TIME_H #include @@ -13,3 +14,16 @@ unsigned time_ms() { gettimeofday(&tv, NULL); return (unsigned)(tv.tv_sec * 1000 + tv.tv_usec / 1000); } + +int arg_parse_freq(const char *str) { + char *tail; + int value = (int)strtol(str, &tail, 10); + + if ((tail[0] == 'm' || tail[0] == 'M') && tail[1] == '\0') { + value = value*1000; + } else if (((tail[0] != 'k' && tail[0] != 'K') || tail[1] != '\0') && tail[0] != '\0') { + return -1; + } + + return value; +} diff --git a/src/stlink-lib/helper.h b/src/stlink-lib/helper.h index 12c2ea2a7..96467377a 100644 --- a/src/stlink-lib/helper.h +++ b/src/stlink-lib/helper.h @@ -3,4 +3,6 @@ unsigned time_ms(); +int arg_parse_freq(const char *str); + #endif /* SYS_HELPER_H */ diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 569815665..ce0d672c8 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -46,7 +46,7 @@ static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, u // get abs value for comparison current_diff = (current_diff > 0) ? current_diff : -current_diff; - if ((current_diff < speed_diff) && khz >= map[i]) { + if (current_diff < speed_diff) { speed_diff = current_diff; speed_index = i; } @@ -741,6 +741,8 @@ int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { } return(0); + } else if (clk_freq) { + WLOG("ST-Link firmware does not support frequency setup\n"); } return(-1); @@ -1196,7 +1198,7 @@ size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_d return strlen(serial); } -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq) { +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; int ret = -1; @@ -1380,7 +1382,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL DLOG("JTAG/SWD freq set to %d\n", freq); stlink_set_swdclk(sl, freq); - if (reset == 2) { + if (connect == CONNECT_UNDER_RESET) { stlink_jtag_reset(sl, 0); if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } @@ -1390,10 +1392,9 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL usleep(10000); } - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } - if (reset == 1) { + if (connect == CONNECT_NORMAL) { if ( sl->version.stlink_v > 1) { stlink_jtag_reset(sl, 2); } stlink_reset(sl); @@ -1420,7 +1421,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL return(NULL); } -static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { +static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], enum connect_type connect, int freq) { stlink_t **_sldevs; libusb_device *dev; int i = 0; @@ -1489,7 +1490,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { if (serial_len != STLINK_SERIAL_LENGTH) { continue; } - stlink_t *sl = stlink_open_usb(0, 1, serial, 0); + stlink_t *sl = stlink_open_usb(0, connect, serial, freq); if (!sl) { ELOG("Failed to open USB device %#06x:%#06x\n", desc.idVendor, desc.idProduct); @@ -1504,7 +1505,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { return(slcur); } -size_t stlink_probe_usb(stlink_t **stdevs[]) { +size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int freq) { libusb_device **devs; stlink_t **sldevs; @@ -1520,7 +1521,7 @@ size_t stlink_probe_usb(stlink_t **stdevs[]) { if (cnt < 0) { return(0); } - slcnt = stlink_probe_usb_devs(devs, &sldevs); + slcnt = stlink_probe_usb_devs(devs, &sldevs, connect, freq); libusb_free_device_list(devs, 1); libusb_exit(NULL); diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index 512370a10..f48ef225d 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -48,6 +48,12 @@ extern "C" { #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 +enum connect_type { + CONNECT_HOT_PLUG = 0, + CONNECT_NORMAL = 1, + CONNECT_UNDER_RESET = 2, +}; + struct stlink_libusb { libusb_context* libusb_ctx; libusb_device_handle* usb_handle; @@ -62,13 +68,13 @@ struct stlink_libusb { /** * Open a stlink * @param verbose Verbosity loglevel - * @param reset Reset stlink programmer + * @param connect Type of connect to target * @param serial Serial number to search for, when NULL the first stlink found is opened (binary format) * @retval NULL Error while opening the stlink * @retval !NULL Stlink found and ready to use */ -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq); -size_t stlink_probe_usb(stlink_t **stdevs[]); +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq); +size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int freq); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); #ifdef __cplusplus From 5b8ee390eec6e83bfb67c026248f0cffc9e84ab0 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 27 Mar 2021 12:27:43 +0200 Subject: [PATCH 1134/1435] remove abort() from lib. related to #634 --- src/common.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/common.c b/src/common.c index 8fae08a09..72150953b 100644 --- a/src/common.c +++ b/src/common.c @@ -980,7 +980,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { sr_reg = (bank==BANK_1)?FLASH_H7_SR1:FLASH_H7_SR2; } else { - ELOG("unsupported flash method, abort"); + ELOG("unsupported flash method, abort\n"); return(-1); } @@ -1010,7 +1010,7 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { sr_busy_shift = FLASH_H7_SR_QW; } else { - ELOG("unsupported flash method, abort"); + ELOG("unsupported flash method, abort\n"); return(-1); } @@ -1617,9 +1617,8 @@ int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); if (len % 4 != 0) { - fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", - len % 4); - abort(); + ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); + return(-1); } return(sl->backend->write_mem32(sl, addr, len)); @@ -1629,9 +1628,8 @@ int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_read_mem32 ***\n"); if (len % 4 != 0) { // !!! never ever: fw gives just wrong values - fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", - len % 4); - abort(); + ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); + return(-1); } return(sl->backend->read_mem32(sl, addr, len)); @@ -1641,9 +1639,8 @@ int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem8 ***\n"); if (len > 0x40) { // !!! never ever: Writing more then 0x40 bytes gives unexpected behaviour - fprintf(stderr, "Error: Data length > 64: +%d byte.\n", - len); - abort(); + ELOG("Data length > 64: +%d byte.\n", len); + return(-1); } return(sl->backend->write_mem8(sl, addr, len)); From 0b7221076a9b66cfb9647e4f06d55d66229e0799 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 27 Mar 2021 11:41:09 +0100 Subject: [PATCH 1135/1435] General Project Update - Updated CHANGELOG.md - [doc] Update for GD32F303VGT6 in device list - [doc] Updated tutorial.md > Added refs for unknown chip id! 0 > Minor update for tool option table --- CHANGELOG.md | 8 ++++---- doc/devices_boards.md | 6 +++--- doc/tutorial.md | 8 +++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3f8e13b5..ee46901e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # v1.6.2 -Release date: (planned H1/2021) +Release date: (planned Q2/2021) Features: @@ -21,7 +21,7 @@ Features: Updates & changes: -- [doc] Added tutorial section on unknown chip id error ([#107](https://github.com/stlink-org/stlink/pull/107), [#568](https://github.com/stlink-org/stlink/pull/568), +- [doc] Added tutorial section on unknown chip id error (commit [#229c721](https://github.com/stlink-org/stlink/commit/229c721189587760db5509c59b3c02e93e7035c8), [#107](https://github.com/stlink-org/stlink/pull/107), [#568](https://github.com/stlink-org/stlink/pull/568)) - [doc] Updated documentation on target resetting ([#261](https://github.com/stlink-org/stlink/pull/261), [#533](https://github.com/stlink-org/stlink/pull/533), [#1107](https://github.com/stlink-org/stlink/pull/1107)) - [doc] Added note on `(gdb) run` command (commit [#03793d4](https://github.com/stlink-org/stlink/commit/03793d42b6078344a9ef8ad55f1d5d0fc19e486e), [#267](https://github.com/stlink-org/stlink/pull/267)) - [doc] `st-flash --reset` parameter (one solution for #356) ([#642](https://github.com/stlink-org/stlink/pull/642)) @@ -35,8 +35,9 @@ Updates & changes: Fixes: -- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) +- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) - Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106)) +- Use vl flashloader for all STM32F1 series ([#769](https://github.com/stlink-org/stlink/pull/769), [#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) - cmake compile failure with external `CMAKE_MODULE_PATH` set ([#962](https://github.com/stlink-org/stlink/pull/962)) - doc/man: Fixed installation directory ([#970](https://github.com/stlink-org/stlink/pull/970)) @@ -50,7 +51,6 @@ Fixes: - `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027), [#1064](https://github.com/stlink-org/stlink/pull/1064), [#1065](https://github.com/stlink-org/stlink/pull/1065)) - GDB: Fixed problems with target description ([#1013](https://github.com/stlink-org/stlink/pull/1013), [#1088](https://github.com/stlink-org/stlink/pull/1088), [#1109](https://github.com/stlink-org/stlink/pull/1109)) - [doc] Fixed wrong path for `rules.d` folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) -- Use vl flashloader for all STM32F1 series ([#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - Fixed support for STLINK/V1 programmer ([#1045](https://github.com/stlink-org/stlink/pull/1045), [#1105](https://github.com/stlink-org/stlink/pull/1105)) - st-util v1.6.1 does not recognize option --freq (commit [#e576768](https://github.com/stlink-org/stlink/commit/e5767681f14de9851aa970a9299930ca68b2ed92), [#1055](https://github.com/stlink-org/stlink/pull/1055)) - Fixed `gettimeofday` for MSVC ([#1074](https://github.com/stlink-org/stlink/pull/1074)) diff --git a/doc/devices_boards.md b/doc/devices_boards.md index 6396738c4..df4b5ed29 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -109,9 +109,9 @@ Tested boards [incl. STLINK programmers]: **STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3c_CORE_ID)** -| Product-Code | Chip-ID | STLink
      Programmer | Boards | -| ------------ | ------- | ---------------------- | ------------------------------------------------------ | -| GD32F303VGT6 | 0x430 | _N/A_ | STM32F303 clone from GigaDevice GD)
      _unsupported_ | +| Product-Code | Chip-ID | STLINK
      Programmer | Boards | +| ------------ | ------- | ---------------------- | ---------------------------------- | +| GD32F303VGT6 | 0x430 | [v2] | STM32F303 clone from GigaDevice GD | **STM32F4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F4_CORE_ID)** diff --git a/doc/tutorial.md b/doc/tutorial.md index 2403590ac..37c29ab6a 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -7,7 +7,7 @@ | --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k for the STM32F103C8T6
      to assume 128k of flash being present. This option accepts decimal (128k), octal 0200k, or hex 0x80k values.
      Leaving the multiplier out is equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional
      "k" or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | | --freq=n[k][m] | st-info
      st-flash
      st-util | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
      This option solely accepts decimal values (5K or 1.8M) with the unit `Hz` being left out. Valid frequencies are:
      `5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K, 1800K, 4000K(4M)`. | v1.6.1 | | --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
      This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | -| --reset | st-flash | Trigger a reset both before and after flashing. The default uses the hardware reset through `NRST` pin.
      The software reset is used if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | +| --reset | st-flash | Trigger a reset both before and after flashing. The default uses the hardware reset through `NRST` pin.
      A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | | --connect-under-reset | st-info
      st-flash | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
      when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | | --hot-plug | st-info
      st-util | Connect to the target without reset. | v1.6.2 | | --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | @@ -112,12 +112,14 @@ This so called `DBGMCU_IDCODE` register is allocated either at memory address `0 A failure of chip identification results in the error `WARN src/common.c: unknown chip id!`. There are different variants of this message that refer to different issues: -- `unknown chip id! 0` --> _currently unknown_ +- `unknown chip id! 0` --> Target chip (board) is unknown. + 1. Microcontroller is in stop/standby mode. + 2. The signals `DIO` and `CLK` are reversed on the SWD-Interface. - `unknown chip id! 0x1a` --> _currently unknown_ - `unknown chip id! 0x001f` --> _currently unknown_ - `unknown chip id! 0x3e8` --> _currently unknown_ - `unknown chip id! 0xa05f0000` --> _currently unknown_ -- `unknown chip id! 0x3748` --> A target chip / board cannot be detected. +- `unknown chip id! 0x3748` --> A target chip (board) cannot be detected. 1. No target is connected --> In this case `st-info --probe` displays `chip id 0x0748` with STLINK/V2 and `chip id 0x03e8` with STLINK-V3. 2. The chip is connected but has gone into an undefined state of operation where the SWD pins are unresponsive. --> Try to use `--connect-under-reset` while pressing the reset button on the target board. 3. A firmware-issue prevents the programmer from normal operation. --> Ensure that your programmer runs the latest firmware version and consider to upgrade any older version by using the official firmware upgrade tool provided by STMicroelectronics. From 36434d5785bc752465b47b5b058e33da1df90794 Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 27 Mar 2021 15:54:54 +0500 Subject: [PATCH 1136/1435] Added addition check of connected target --- src/common.c | 58 ++++++++++++++++++-------------------------- src/stlink-lib/reg.h | 12 ++++----- 2 files changed, 29 insertions(+), 41 deletions(-) diff --git a/src/common.c b/src/common.c index b5bb67e9e..f621a4b6d 100644 --- a/src/common.c +++ b/src/common.c @@ -1220,14 +1220,14 @@ int stlink_core_id(stlink_t *sl) { // do not call this procedure directly. int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { int ret; + cortex_m3_cpuid_t cpu_id; - uint32_t cpu_id; - *chip_id = 0; - ret = -1; - - // Read the CPU ID to determine where to read the core id from - if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &cpu_id)) - cpu_id = 0; + // Read the CPU ID to determine where to read the core id + if (stlink_cpu_id(sl, &cpu_id) || + cpu_id.implementer_id != STLINK_REG_CMx_CPUID_IMPL_ARM) { + ELOG("Can not connect to target. Please use \'connect under reset\' and try again\n"); + return -1; + } /* * the chip_id register in the reference manual have @@ -1235,18 +1235,17 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { * */ - uint32_t part_no = STLINK_REG_CM3_CPUID_PARTNO(cpu_id); if ((sl->core_id == STM32H7_CORE_ID || sl->core_id == STM32H7_CORE_ID_JTAG) && - part_no == STLINK_REG_CMx_CPUID_PARTNO_CM7) { + cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) ret = stlink_read_debug32(sl, 0x5c001000, chip_id); - } else if (part_no == STLINK_REG_CMx_CPUID_PARTNO_CM0) { + } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0) { // STM32F0 (RM0091, pg914; RM0360, pg713) // STM32L0 (RM0377, pg813; RM0367, pg915; RM0376, pg917) // STM32G0 (RM0444, pg1367) ret = stlink_read_debug32(sl, 0x40015800, chip_id); - } else if (part_no == STLINK_REG_CMx_CPUID_PARTNO_CM33) { + } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM33) { // STM32L5 (RM0438, pg2157) ret = stlink_read_debug32(sl, 0xE0044000, chip_id); } else /* СM3, СM4, CM7 */ { @@ -1261,9 +1260,16 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { // STM32G4 (RM0440, pg2086) // STM32WB (RM0434, pg1406) ret = stlink_read_debug32(sl, 0xE0042000, chip_id); + } + + if (ret || !(*chip_id)) { + *chip_id = 0; + ELOG("Could not find chip id!\n"); + } else { + *chip_id = (*chip_id) & 0xfff; // Fix chip_id for F4 rev A errata, read CPU ID, as CoreID is the same for F2/F4 - if (*chip_id == 0x411 && (cpu_id & 0xfff0) == 0xc240) { + if (*chip_id == 0x411 && cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM4) { *chip_id = 0x413; } } @@ -1272,7 +1278,7 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { } /** - * Cortex m3 tech ref manual, CPUID register description + * Cortex M tech ref manual, CPUID register description * @param sl stlink context * @param cpuid pointer to the result object */ @@ -1305,26 +1311,16 @@ int stlink_load_device_params(stlink_t *sl) { DLOG("Loading device parameters....\n"); const struct stlink_chipid_params *params = NULL; stlink_core_id(sl); - uint32_t chip_id = 0; uint32_t flash_size; - stlink_chip_id(sl, &chip_id); - sl->chip_id = chip_id & 0xfff; - - // Fix chip_id for F4 rev A errata , Read CPU ID, as CoreID is the same for F2/F4 - if (sl->chip_id == 0x411) { - uint32_t cpuid; - stlink_read_debug32(sl, 0xE000ED00, &cpuid); - - if ((cpuid & 0xfff0) == 0xc240) { - sl->chip_id = 0x413; - } + if (stlink_chip_id(sl, &sl->chip_id)) { + return(-1); } params = stlink_chipid_get_params(sl->chip_id); if (params == NULL) { - WLOG("unknown chip id! %#x\n", chip_id); + WLOG("unknown chip id! %#x\n", sl->chip_id); return(-1); } @@ -1390,19 +1386,11 @@ int stlink_load_device_params(stlink_t *sl) { sl->chip_flags &= ~CHIP_F_HAS_DUAL_BANK; } -#if 0 - // Old code -- REW - ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); - // TODO: make note of variable page size here..... - ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %u bytes\n", - sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, - (unsigned int)sl->flash_pgsz); -#else ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", params->description, (unsigned)(sl->sram_size / 1024), (unsigned)(sl->flash_size / 1024), (sl->flash_pgsz < 1024) ? (unsigned)(sl->flash_pgsz) : (unsigned)(sl->flash_pgsz / 1024), (sl->flash_pgsz < 1024) ? "byte" : "KiB"); -#endif + return(0); } diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 73f608cb6..79570aa34 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -3,12 +3,12 @@ #define STLINK_REG_CM3_CPUID 0xE000ED00 -#define STLINK_REG_CM3_CPUID_PARTNO(cpuid) ((cpuid)&STLINK_REG_CMx_CPUID_PARTNO_MASK) -#define STLINK_REG_CMx_CPUID_PARTNO_MASK 0xFFF0 -#define STLINK_REG_CMx_CPUID_PARTNO_CM0 0xC200 -#define STLINK_REG_CMx_CPUID_PARTNO_CM3 0xC230 -#define STLINK_REG_CMx_CPUID_PARTNO_CM7 0xC270 -#define STLINK_REG_CMx_CPUID_PARTNO_CM33 0xD210 +#define STLINK_REG_CMx_CPUID_PARTNO_CM0 0xC20 +#define STLINK_REG_CMx_CPUID_PARTNO_CM3 0xC23 +#define STLINK_REG_CMx_CPUID_PARTNO_CM4 0xC24 +#define STLINK_REG_CMx_CPUID_PARTNO_CM7 0xC27 +#define STLINK_REG_CMx_CPUID_PARTNO_CM33 0xD21 +#define STLINK_REG_CMx_CPUID_IMPL_ARM 0x41 #define STLINK_REG_CM3_FP_CTRL 0xE0002000 // Flash Patch Control Register From da37fec19ee378d076fae2d615ea7082d99e110e Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 27 Mar 2021 21:12:00 +0500 Subject: [PATCH 1137/1435] Applied missing changes to tests --- tests/flash.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/tests/flash.c b/tests/flash.c index a8d479b2d..132066aba 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -131,17 +131,6 @@ static struct Test tests[] = { .freq = 5, .format = FLASH_FORMAT_BINARY } }, - { "--debug --freq=6k --reset write test.bin 0x80000000", -1, - { .cmd = FLASH_CMD_WRITE, - .serial = { 0 }, - .filename = "test.bin", - .addr = 0x80000000, - .size = 0, - .reset = 1, - .log_level = DEBUG_LOG_LEVEL, - .freq = 6, - .format = FLASH_FORMAT_BINARY } - }, { "--debug --reset read test.bin 0x80000000 1000", 0, { .cmd = FLASH_CMD_READ, .serial = { 0 }, @@ -211,10 +200,10 @@ static struct Test tests[] = { { "--debug --reset --format=binary write test.hex", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset --format=ihex write test.hex 0x80000000", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset write test.hex sometext", -1, FLASH_OPTS_INITIALIZER }, - { "--serial A1020304 erase sometext", -1, FLASH_OPTS_INITIALIZER }, - { "--serial A1020304 erase", 0, + { "--serial ABCEFF544851717867216044 erase sometext", -1, FLASH_OPTS_INITIALIZER }, + { "--serial ABCEFF544851717867216044 erase", 0, { .cmd = FLASH_CMD_ERASE, - .serial = "\xA1\x02\x03\x04", + .serial = "ABCEFF544851717867216044", .filename = NULL, .addr = 0, .size = 0, @@ -223,9 +212,9 @@ static struct Test tests[] = { .freq = 0, .format = FLASH_FORMAT_BINARY } }, - { "--serial=A1020304 erase", 0, + { "--serial=ABCEFF544851717867216044 erase", 0, { .cmd = FLASH_CMD_ERASE, - .serial = "\xA1\x02\x03\x04", + .serial = "ABCEFF544851717867216044", .filename = NULL, .addr = 0, .size = 0, From 878df31761f449e5846bb841085a320420c77c15 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 27 Mar 2021 17:46:22 +0100 Subject: [PATCH 1138/1435] Updated CI config & issue templates - Initial support for GitHub CI workflows - Cleanup for Travis CI config - Minor fixes for issue templates --- .github/ISSUE_TEMPLATE/bug-report.md | 18 +- .github/ISSUE_TEMPLATE/feature-request.md | 16 +- .github/workflows/c-cpp.yml | 334 +++++++++++++++++++++- .github/workflows/cmake.yml | 46 --- .travis.sh | 13 - .travis.yml | 2 +- README.md | 1 + 7 files changed, 338 insertions(+), 92 deletions(-) delete mode 100644 .github/workflows/cmake.yml diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 0e22c2ce9..16e0477f0 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -1,8 +1,8 @@ --- name: "Bug Report" about: "Report a bug" -title: "[STM32 device name]: [_$YourTitle_]" -labels: '' +title: "[STM32 device name]: $YourTitle" +labels: "" --- Thank you for giving feedback to the stlink project. @@ -12,18 +12,17 @@ This bug report will be deleted without notice when not enough information is pr - [ ] I made serious effort to avoid creating duplicate or nearly similar issue -In order to allow developers and other contributors to isolate and target your respective issue, please take some time to select the check boxes below -and fill out each of the following items appropriate to your specific problem. +In order to allow developers and other contributors to isolate and target your respective issue, please take some time to select the check boxes below and fill out each of the following items appropriate to your specific problem. -- [ ] Programmer/board type: [enter here] (e.g STLink /V1, /V2, /V2-onboard, /V2-clone, /V3) +- [ ] Programmer/board type: [enter here] (e.g STLINK /V1, /V2, /V2-onboard, /V2-clone, /V3) - [ ] Operating system an version: [enter here] (e.g Linux, macOS, Windows) -- [ ] **Stlink tools version** and/or git commit hash: [enter here] (e.g v1.6.1/git-d0416149) -- [ ] Stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-util`) +- [ ] **stlink tools version** and/or git commit hash: [enter here] (e.g v1.6.1/git-d0416149) +- [ ] stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-trace`, `st-util`) - [ ] Target chip (and board, if applicable): [enter here] (e.g STM32F103C8T6 (NUCLEO-F103RB)) -Futher we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: +Further we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: -Commandline-Output: +Commandline output: ``` OUTPUT/ERROR of the commandline tool(s) @@ -33,7 +32,6 @@ Expected/description: `short description of the expected value` - Thank you for your support. The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index 3de593aa6..ddeb79357 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -1,7 +1,7 @@ --- name: "Feature Request" about: "Suggest an idea for this project" -title: "[feature] [_$YourTitle_]" +title: "[feature] $YourTitle" labels: code/feature-request --- @@ -12,18 +12,17 @@ This feature request will be deleted without notice when not enough information - [ ] I made serious effort to avoid creating duplicate or nearly similar issue -In order to allow developers and other contributors to isolate and target your respective issue, please take some time to select the check boxes below -and fill out each of the following items appropriate to your specific request. +In order to allow developers and other contributors to isolate and target your respective issue, please take some time to select the check boxes below and fill out each of the following items appropriate to your specific request. -- [ ] Programmer/board type: [enter here] (e.g STLink /V1, /V2, /V2-onboard, /V2-clone, /V3) +- [ ] Programmer/board type: [enter here] (e.g STLINK /V1, /V2, /V2-onboard, /V2-clone, /V3) - [ ] Operating system an version: [enter here] (e.g Linux, macOS, Windows) -- [ ] **Stlink tools version** and/or git commit hash: [enter here] (e.g v1.6.1/git-d0416149) -- [ ] Stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-util`) +- [ ] **stlink tools version** and/or git commit hash: [enter here] (e.g v1.6.1/git-d0416149) +- [ ] stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-trace`, `st-util`) - [ ] Target chip (and board, if applicable): [enter here] (e.g STM32F103C8T6 (NUCLEO-F103RB)) -Futher we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: +Further we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: -Commandline-Output: +Commandline output: ``` OUTPUT/ERROR of the commandline tool(s) @@ -33,7 +32,6 @@ Expected/description: `short description of the expected value` - Thank you for your support. The stlink project maintainers diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index e211e4e54..c792612c2 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -2,22 +2,330 @@ name: C/C++ CI on: push: - branches: [ testing ] + branches: [develop, testing] pull_request: - branches: [ testing ] + branches: [develop, testing] jobs: - build: + job_linux_1a: + name: ubuntu-20.04 gcc + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_2a: + name: ubuntu-18.04 gcc + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: install dependencies + run: sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_3a: + name: ubuntu-16.04 gcc + runs-on: ubuntu-16.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_1b: + name: ubuntu-20.04 clang + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_2b: + name: ubuntu-18.04 clang + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: install dependencies + run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_3b: + name: ubuntu-16.04 clang + runs-on: ubuntu-16.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install clang libusb-1.0.0-dev libgtk-3-dev rpm + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_1c: + name: ubuntu-20.04 gcc 32-bit + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_2c: + name: ubuntu-18.04 gcc 32-bit + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: install dependencies + run: sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_3c: + name: ubuntu-16.04 gcc 32-bit + runs-on: ubuntu-16.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_4: + name: ubuntu-20.04 mingw64 + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm mingw-w64 + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + # job_macos_1a: + # name: macos-11.0 gcc + # runs-on: macos-11.0 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: brew install gcc libusb gtk+3 + # - name: make debug + # run: make debug + # - name: make test + # run: make test + # - name: make release + # run: make release + # - name: make install + # run: make install + # - name: make package + # run: make package + # - name: make uninstall + # run: make uninstall + # - name: make clean + # run: make clean + + job_macos_2a: + name: macos-10.15 gcc + runs-on: macos-10.15 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: brew install gcc libusb gtk+3 + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean - runs-on: ubuntu-latest + # job_macos_1b: + # name: macos-11.0 clang + # runs-on: macos-11.0 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: brew install llvm libusb gtk+3 + # - name: make debug + # run: make debug + # - name: make test + # run: make test + # - name: make release + # run: make release + # - name: make install + # run: make install + # - name: make package + # run: make package + # - name: make uninstall + # run: make uninstall + # - name: make clean + # run: make clean + job_macos_2b: + name: macos-10.15 clang + runs-on: macos-10.15 steps: - - uses: actions/checkout@v2 - - name: configure - run: ./configure - - name: make - run: make - - name: make check - run: make check - - name: make distcheck - run: make distcheck + - uses: actions/checkout@v2 + - name: Install dependencies + run: brew install llvm libusb gtk+3 + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml deleted file mode 100644 index 005915e6e..000000000 --- a/.github/workflows/cmake.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: CMake - -on: [push] - -env: - # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) - BUILD_TYPE: Release - -jobs: - build: - # The CMake configure and build commands are platform agnostic and should work equally - # well on Windows or Mac. You can convert this to a matrix build if you need - # cross-platform coverage. - # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Create Build Environment - # Some projects don't allow in-source building, so create a separate build directory - # We'll use this as our working directory for all subsequent commands - run: cmake -E make_directory ${{github.workspace}}/build - - - name: Configure CMake - # Use a bash shell so we can use the same syntax for environment variable - # access regardless of the host operating system - shell: bash - working-directory: ${{github.workspace}}/build - # Note the current convention is to use the -S and -B options here to specify source - # and build directories, but this is only available with CMake 3.13 and higher. - # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 - run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE - - - name: Build - working-directory: ${{github.workspace}}/build - shell: bash - # Execute the build. You can specify a specific target with "--target " - run: cmake --build . --config $BUILD_TYPE - - - name: Test - working-directory: ${{github.workspace}}/build - shell: bash - # Execute tests defined by the CMake configuration. - # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: ctest -C $BUILD_TYPE diff --git a/.travis.sh b/.travis.sh index cc0958bf5..7683af001 100755 --- a/.travis.sh +++ b/.travis.sh @@ -11,61 +11,48 @@ DIR=$PWD if [ "$TRAVIS_JOB_NAME" == "linux-mingw" ]; then echo "--> Building Release for Windows (x86-64) ..." mkdir -p build-mingw && cd build-mingw - echo "-DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR" cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && rm -rf build-mingw && cd - echo "--> Building Release for Windows (i686) ..." mkdir -p build-mingw && cd build-mingw - echo "-DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR" cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && rm -rf build-mingw && cd - elif [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq || true - sudo apt-get install -qq -y --no-install-recommends libgtk-3-dev echo "--> Building Debug..." mkdir -p build/Debug && cd build/Debug - echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && cd - echo "--> Building Release with package..." mkdir -p build/Release && cd build/Release - echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make package && cd - elif [ "$TRAVIS_OS_NAME" == "osx" ]; then - brew install libusb - echo "--> Building Debug..." mkdir -p build/Debug && cd build/Debug - echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && cd - echo "--> Building Release with package..." mkdir -p build/Release && cd build/Release - echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make package && cd - else # local test-build echo "--> Building Debug..." mkdir -p build/Debug && cd build/Debug - echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install ../../ make && cd - echo "--> Building Release with package..." mkdir -p build/Release && cd build/Release - echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install ../../ make package && cd - fi diff --git a/.travis.yml b/.travis.yml index 5d2e5fbdf..e866cc6ab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -146,7 +146,7 @@ jobs: addons: homebrew: packages: - - clang + - llvm - libusb - gtk+3 diff --git a/README.md b/README.md index 7ddc78005..aafba5988 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ ![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.1/develop) ![GitHub activity](https://img.shields.io/github/commit-activity/m/stlink-org/stlink) ![GitHub contributors](https://img.shields.io/github/contributors/stlink-org/stlink) +[![C/C++ CI](https://github.com/stlink-org/stlink/actions/workflows/c-cpp.yml/badge.svg?branch=testing)](https://github.com/stlink-org/stlink/actions/workflows/c-cpp.yml) [![Linux Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=linux&label=linux)](https://travis-ci.org/stlink-org/stlink) [![macOS Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=osx&label=osx)](https://travis-ci.org/stlink-org/stlink) From a5a4a687c42045a139d9950036c5adddaa317bf6 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 27 Mar 2021 21:01:31 +0100 Subject: [PATCH 1139/1435] Updated config for GitHub Actions CI workflow --- .github/workflows/c-cpp.yml | 228 ++++++++++++++++++------------------ 1 file changed, 114 insertions(+), 114 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index c792612c2..b42d001af 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -2,9 +2,9 @@ name: C/C++ CI on: push: - branches: [develop, testing] + branches: [master, develop, testing] pull_request: - branches: [develop, testing] + branches: [master, develop, testing] jobs: job_linux_1a: @@ -20,14 +20,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_2a: name: ubuntu-18.04 gcc @@ -42,14 +42,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_3a: name: ubuntu-16.04 gcc @@ -64,14 +64,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_1b: name: ubuntu-20.04 clang @@ -86,14 +86,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_2b: name: ubuntu-18.04 clang @@ -108,14 +108,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_3b: name: ubuntu-16.04 clang @@ -130,14 +130,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_1c: name: ubuntu-20.04 gcc 32-bit @@ -157,14 +157,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_2c: name: ubuntu-18.04 gcc 32-bit @@ -184,14 +184,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_3c: name: ubuntu-16.04 gcc 32-bit @@ -211,14 +211,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_4: name: ubuntu-20.04 mingw64 @@ -233,14 +233,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean # job_macos_1a: # name: macos-11.0 gcc @@ -255,14 +255,14 @@ jobs: # run: make test # - name: make release # run: make release - # - name: make install - # run: make install - # - name: make package - # run: make package - # - name: make uninstall - # run: make uninstall - # - name: make clean - # run: make clean + # - name: sudo make install + # run: sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall + # - name: sudo make clean + # run: sudo make clean job_macos_2a: name: macos-10.15 gcc @@ -277,14 +277,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean # job_macos_1b: # name: macos-11.0 clang @@ -299,14 +299,14 @@ jobs: # run: make test # - name: make release # run: make release - # - name: make install - # run: make install - # - name: make package - # run: make package - # - name: make uninstall - # run: make uninstall - # - name: make clean - # run: make clean + # - name: sudo make install + # run: sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall + # - name: sudo make clean + # run: sudo make clean job_macos_2b: name: macos-10.15 clang @@ -321,11 +321,11 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean From face74262f879bba5a330c8326064a383cac2b42 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 28 Mar 2021 00:30:33 +0100 Subject: [PATCH 1140/1435] Updated config for GitHub code scanning alerts --- .github/workflows/codeql-analysis.yml | 60 ++++++++++++++------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 202867cfc..bab5fb048 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,12 +13,12 @@ name: "CodeQL" on: push: - branches: [ develop, master ] + branches: [develop, master] pull_request: # The branches below must be a subset of the branches above - branches: [ develop ] + branches: [develop] schedule: - - cron: '23 20 * * 2' + - cron: "23 20 * * 2" jobs: analyze: @@ -28,40 +28,42 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'cpp' ] + language: ["cpp"] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed steps: - - name: Checkout repository - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Checkout repository + uses: actions/checkout@v2 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language - #- run: | - # make bootstrap - # make release + #- run: | + # make bootstrap + # make release - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From d10a4f8def8189d4b14fad20b25b75bcf010e563 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 28 Mar 2021 00:35:03 +0100 Subject: [PATCH 1141/1435] Updated libusb to v1.0.24 --- cmake/modules/Findlibusb.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index bc613779d..b3e5c7e2b 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -75,7 +75,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) if (NOT LIBUSB_FOUND) # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.24) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) @@ -92,7 +92,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download - ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 + ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 5c944b1c8aa9d43e026a94302d0f8ac4 ) endif () From 0496ecff48b7c122c243c4d449e44ad34e8ecba6 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 2 Apr 2021 16:43:54 +0200 Subject: [PATCH 1142/1435] Updated config for GitHub code scanning alerts --- .github/workflows/codeql-analysis.yml | 8 ++++---- README.md | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index bab5fb048..26313ecb5 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,12 +13,12 @@ name: "CodeQL" on: push: - branches: [develop, master] + branches: [ testing, develop, master ] pull_request: # The branches below must be a subset of the branches above - branches: [develop] + branches: [ testing, develop ] schedule: - - cron: "23 20 * * 2" + - cron: '00 20 * * 1' jobs: analyze: @@ -28,7 +28,7 @@ jobs: strategy: fail-fast: false matrix: - language: ["cpp"] + language: [ 'cpp' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed diff --git a/README.md b/README.md index aafba5988..644c3fd86 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ ![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.1/develop) ![GitHub activity](https://img.shields.io/github/commit-activity/m/stlink-org/stlink) ![GitHub contributors](https://img.shields.io/github/contributors/stlink-org/stlink) +[![CodeQL](https://github.com/stlink-org/stlink/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/stlink-org/stlink/actions/workflows/codeql-analysis.yml) [![C/C++ CI](https://github.com/stlink-org/stlink/actions/workflows/c-cpp.yml/badge.svg?branch=testing)](https://github.com/stlink-org/stlink/actions/workflows/c-cpp.yml) [![Linux Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=linux&label=linux)](https://travis-ci.org/stlink-org/stlink) [![macOS Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=osx&label=osx)](https://travis-ci.org/stlink-org/stlink) From eebcb1acc8a29a156276852eb730e961883a9e71 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 2 Apr 2021 18:34:31 +0200 Subject: [PATCH 1143/1435] Revert "Updated libusb to v1.0.24" This reverts commit d10a4f8def8189d4b14fad20b25b75bcf010e563. --- cmake/modules/Findlibusb.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index b3e5c7e2b..bc613779d 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -75,7 +75,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) if (NOT LIBUSB_FOUND) # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.24) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) @@ -92,7 +92,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download - ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 5c944b1c8aa9d43e026a94302d0f8ac4 + ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 ) endif () From 32ba234b305a8fa3ffdd5cd825a72973ad94a512 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 2 Apr 2021 18:36:05 +0200 Subject: [PATCH 1144/1435] Revert "Updated libusb to v1.0.24" This reverts commit d10a4f8def8189d4b14fad20b25b75bcf010e563. --- cmake/modules/Findlibusb.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index b3e5c7e2b..bc613779d 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -75,7 +75,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) if (NOT LIBUSB_FOUND) # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.24) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) @@ -92,7 +92,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download - ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 5c944b1c8aa9d43e026a94302d0f8ac4 + ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 ) endif () From e0f7552fc1a13990f70da863c5fdaa1f64be649f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 3 Apr 2021 14:53:16 +0200 Subject: [PATCH 1145/1435] Updated CI build configuration - Ensure clean build system for all build targets - Rearranged & renamed build jobs - Completed set of 32-bit & 64-bit builds - Updated notifications for MinGW cross build - Added macOS 10.14 build environment for Travis CI --- .github/workflows/c-cpp.yml | 387 +++++++++++++++++++-------------- .travis.sh | 4 +- .travis.yml | 177 +++++---------- cmake/modules/Findlibusb.cmake | 2 + 4 files changed, 281 insertions(+), 289 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index b42d001af..4769450ae 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -7,95 +7,145 @@ on: branches: [master, develop, testing] jobs: - job_linux_1a: - name: ubuntu-20.04 gcc - runs-on: ubuntu-20.04 + +# Linux + + job_linux_16_04_64_gcc: + name: ubuntu-16.04 gcc + runs-on: ubuntu-16.04 steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_2a: - name: ubuntu-18.04 gcc - runs-on: ubuntu-18.04 + job_linux_16_04_32_gcc: + name: ubuntu-16.04 gcc 32-bit + runs-on: ubuntu-16.04 steps: - uses: actions/checkout@v2 - - name: install dependencies - run: sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Install dependencies + run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_3a: - name: ubuntu-16.04 gcc + job_linux_16_04_64_clang: + name: ubuntu-16.04 clang runs-on: ubuntu-16.04 steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_1b: - name: ubuntu-20.04 clang - runs-on: ubuntu-20.04 + job_linux_16_04_32_clang: + name: ubuntu-16.04 clang 32-bit + runs-on: ubuntu-16.04 steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean + + job_linux_18_04_64_gcc: + name: ubuntu-18.04 gcc + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: install dependencies + run: sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_2b: + job_linux_18_04_32_gcc: + name: ubuntu-18.04 gcc 32-bit + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: install dependencies + run: sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean + + job_linux_18_04_64_clang: name: ubuntu-18.04 clang runs-on: ubuntu-18.04 steps: @@ -103,43 +153,64 @@ jobs: - name: install dependencies run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_3b: - name: ubuntu-16.04 clang - runs-on: ubuntu-16.04 + job_linux_18_04_32_clang: + name: ubuntu-18.04 clang 32-bit + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean + + job_linux_20_04_64_gcc: + name: ubuntu-20.04 gcc + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install clang libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_1c: + job_linux_20_04_32_gcc: name: ubuntu-20.04 gcc 32-bit runs-on: ubuntu-20.04 steps: @@ -152,97 +223,106 @@ jobs: CXXFLAGS="$CXXFLAGS -m32" LDFLAGS="$LDFLAGS -m32" - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_2c: - name: ubuntu-18.04 gcc 32-bit - runs-on: ubuntu-18.04 + job_linux_20_04_64_clang: + name: ubuntu-20.04 clang + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - - name: install dependencies - run: sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm - - name: Set compiler flags - run: | - CFLAGS="$CFLAGS -m32" - CXXFLAGS="$CXXFLAGS -m32" - LDFLAGS="$LDFLAGS -m32" + - name: Install dependencies + run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_3c: - name: ubuntu-16.04 gcc 32-bit - runs-on: ubuntu-16.04 + job_linux_20_04_32_clang: + name: ubuntu-20.04 clang 32-bit + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: Set compiler flags run: | CFLAGS="$CFLAGS -m32" CXXFLAGS="$CXXFLAGS -m32" LDFLAGS="$LDFLAGS -m32" - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_4: - name: ubuntu-20.04 mingw64 - runs-on: ubuntu-20.04 +# macOS + + job_macos_10_15_gcc: + name: macos-10.15 gcc + runs-on: macos-10.15 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: brew install gcc libusb gtk+3 + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean + + job_macos_10_15_clang: + name: macos-10.15 clang + runs-on: macos-10.15 steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm mingw-w64 + run: brew install llvm libusb gtk+3 - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - # job_macos_1a: + # job_macos_11_gcc: # name: macos-11.0 gcc # runs-on: macos-11.0 # steps: @@ -250,43 +330,19 @@ jobs: # - name: Install dependencies # run: brew install gcc libusb gtk+3 # - name: make debug - # run: make debug + # run: sudo make clean && make debug # - name: make test - # run: make test + # run: sudo make clean && make test # - name: make release - # run: make release + # run: sudo make clean && make release # - name: sudo make install - # run: sudo make install + # run: sudo make clean && sudo make install # - name: sudo make package # run: sudo make package # - name: sudo make uninstall - # run: sudo make uninstall - # - name: sudo make clean - # run: sudo make clean + # run: sudo make uninstall && sudo make clean - job_macos_2a: - name: macos-10.15 gcc - runs-on: macos-10.15 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: brew install gcc libusb gtk+3 - - name: make debug - run: make debug - - name: make test - run: make test - - name: make release - run: make release - - name: sudo make install - run: sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean - - # job_macos_1b: + # job_macos_11_clang: # name: macos-11.0 clang # runs-on: macos-11.0 # steps: @@ -294,38 +350,31 @@ jobs: # - name: Install dependencies # run: brew install llvm libusb gtk+3 # - name: make debug - # run: make debug + # run: sudo make clean && make debug # - name: make test - # run: make test + # run: sudo make clean && make test # - name: make release - # run: make release + # run: sudo make clean && make release # - name: sudo make install - # run: sudo make install + # run: sudo make clean && sudo make install # - name: sudo make package # run: sudo make package # - name: sudo make uninstall - # run: sudo make uninstall - # - name: sudo make clean - # run: sudo make clean + # run: sudo make uninstall && sudo make clean - job_macos_2b: - name: macos-10.15 clang - runs-on: macos-10.15 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: brew install llvm libusb gtk+3 - - name: make debug - run: make debug - - name: make test - run: make test - - name: make release - run: make release - - name: sudo make install - run: sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean +# Linux MinGW cross compliation + + # job_linux_20_04_cross: + # name: ubuntu-20.04 mingw64 + # runs-on: ubuntu-20.04 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm mingw-w64 + # - name: Building Release for Windows (x86-64) ... + # run: sudo mkdir -p build-mingw && cd build-mingw && sudo cmake \ + # -DCMAKE_SYSTEM_NAME=Windows \ + # -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ + # -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake \ + # -DCMAKE_INSTALL_PREFIX=$PWD/install $PWD && \ + # sudo make && sudo rm -rf build-mingw && cd - diff --git a/.travis.sh b/.travis.sh index 7683af001..de2a42372 100755 --- a/.travis.sh +++ b/.travis.sh @@ -9,13 +9,13 @@ echo "WORK DIR:$DIR" DIR=$PWD if [ "$TRAVIS_JOB_NAME" == "linux-mingw" ]; then - echo "--> Building Release for Windows (x86-64) ..." + echo "--> Building for Windows (x86-64) ..." mkdir -p build-mingw && cd build-mingw cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && rm -rf build-mingw && cd - - echo "--> Building Release for Windows (i686) ..." + echo "--> Building for Windows (i686) ..." mkdir -p build-mingw && cd build-mingw cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR diff --git a/.travis.yml b/.travis.yml index e866cc6ab..2a788fd69 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,23 +2,7 @@ language: c jobs: include: - ### 64-bit builds on AMD64 ### - - os: linux - dist: xenial - env: BADGE=linux - compiler: gcc-5 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-5", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - - os: linux - dist: bionic - env: BADGE=linux - compiler: gcc-6 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-6", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + ### 64-bit build on AMD64 ### - os: linux dist: focal env: BADGE=linux @@ -27,30 +11,18 @@ jobs: apt: sources: ["ubuntu-toolchain-r-test"] packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - - os: linux - dist: xenial - env: BADGE=linux - compiler: clang - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - - os: linux - dist: bionic - env: BADGE=linux - compiler: clang-10 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["clang-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + + ### 32-bit build on AMD64 ### - os: linux dist: focal env: BADGE=linux - compiler: clang-10 + compiler: gcc-10 addons: apt: sources: ["ubuntu-toolchain-r-test"] - packages: ["clang-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; ### cross build on AMD64 ### - os: linux @@ -63,92 +35,61 @@ jobs: sources: ["ubuntu-toolchain-r-test"] packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] - - ### 32-bit builds on AMD64 ### - - os: linux - dist: xenial - env: BADGE=linux - compiler: gcc-5 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-5", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: bionic - env: BADGE=linux - compiler: gcc-6 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-6", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: focal - env: BADGE=linux - compiler: gcc-10 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: xenial - env: BADGE=linux - compiler: clang - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: bionic - env: BADGE=linux - compiler: clang-10 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["clang-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: focal - env: BADGE=linux - compiler: clang-10 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["clang-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + - LDFLAGS="$LDFLAGS -NDEBUG"; ### macOS ### - - os: osx - env: BADGE=osx - osx_image: xcode12.2 - name: macOS 10.15.7 - compiler: gcc - addons: - homebrew: - packages: - - gcc - - libusb - - gtk+3 - - os: osx - env: BADGE=osx - osx_image: xcode12.2 - name: macOS 10.15.7 - compiler: clang - addons: - homebrew: - packages: - - llvm - - libusb - - gtk+3 + # - os: osx + # env: BADGE=osx + # osx_image: xcode11.3 + # name: macOS 10.14.6 gcc + # compiler: gcc + # addons: + # homebrew: + # packages: + # - gcc + # - libusb + # - gtk+3 + + # - os: osx + # env: BADGE=osx + # osx_image: xcode11.3 + # name: macOS 10.14.6 gcc 32-bit + # compiler: gcc + # addons: + # homebrew: + # packages: + # - gcc + # - libusb + # - gtk+3 + # before_install: + # - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + + # - os: osx + # env: BADGE=osx + # osx_image: xcode11.3 + # name: macOS 10.14.6 clang + # compiler: clang + # addons: + # homebrew: + # packages: + # - llvm + # - libusb + # - gtk+3 + + # - os: osx + # env: BADGE=osx + # osx_image: xcode11.3 + # name: macOS 10.14.6 clang 32-bit + # compiler: clang + # addons: + # homebrew: + # packages: + # - llvm + # - libusb + # - gtk+3 + # before_install: + # - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; script: - git fetch --tags diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index bc613779d..3082a9509 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -46,8 +46,10 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-toolchain on Debian # for MinGW/MSYS/MSVC: 64-bit or 32-bit? if (CMAKE_SIZEOF_VOID_P EQUAL 8) + message(STATUS "=== Building for Windows (x86-64) ===") set(ARCH 64) else () + message(STATUS "=== Building for Windowsm (i686) ===") set(ARCH 32) endif () From 7cfab876e73f994c95697ba1b09a0a18c2602597 Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 27 Mar 2021 19:14:37 +0500 Subject: [PATCH 1146/1435] flash_loader: fix typo in the stm32l4 loader --- flashloaders/stm32l4.s | 6 +++--- src/stlink-lib/flash_loader.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/flashloaders/stm32l4.s b/flashloaders/stm32l4.s index 21e926f49..50676be9a 100644 --- a/flashloaders/stm32l4.s +++ b/flashloaders/stm32l4.s @@ -12,7 +12,7 @@ .global copy copy: ldr r12, flash_base - ldr r10, flash_off_bsy + ldr r10, flash_off_sr add r10, r10, r12 loop: @@ -44,5 +44,5 @@ exit: .align 2 flash_base: .word 0x40022000 -flash_off_bsy: - .word 0x12 +flash_off_sr: + .word 0x10 diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 9fa897ccc..20fd6aeed 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -114,7 +114,7 @@ static const uint8_t loader_code_stm32l4[] = { 0x08, 0x3a, 0xf0, 0xdc, 0x00, 0xbe, 0x00, 0xbf, 0x00, 0x20, 0x02, 0x40, - 0x12, 0x00, 0x00, 0x00 + 0x10, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32f7[] = { From c0653f6595e1c564f5a762982ef0c23a00ff3dea Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 27 Mar 2021 19:17:13 +0500 Subject: [PATCH 1147/1435] flash_loader: improved handling errors --- flashloaders/Makefile | 2 +- src/stlink-lib/flash_loader.c | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/flashloaders/Makefile b/flashloaders/Makefile index d4ca4d22a..8b01d5293 100644 --- a/flashloaders/Makefile +++ b/flashloaders/Makefile @@ -31,7 +31,7 @@ stm32vl.o: stm32f0.s $(CC) stm32f0.s $(CFLAGS_ARMV7_M) -o stm32vl.o # generic rule for all other ARMv7-M -%.o: *.s +%.o: %.s $(CC) $< $(CFLAGS_ARMV7_M) -o $@ clean: diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 20fd6aeed..aea60f258 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -154,6 +154,7 @@ static const uint8_t loader_code_stm32f7_lv[] = { int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { size_t size = 0; + uint32_t dfsr, cfsr, hfsr; // allocate the loader in SRAM if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { @@ -165,6 +166,20 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { fl->buf_addr = fl->loader_addr + (uint32_t)size; ILOG("Successfully loaded flash loader in sram\n"); + /* Clear Fault Status Register for handling flash loader error */ + if (!stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr) && dfsr) { + ILOG("Clear DFSR\n"); + stlink_write_debug32(sl, STLINK_REG_DFSR, dfsr); + } + if (!stlink_read_debug32(sl, STLINK_REG_CFSR, &cfsr) && cfsr) { + ILOG("Clear CFSR\n"); + stlink_write_debug32(sl, STLINK_REG_CFSR, cfsr); + } + if (!stlink_read_debug32(sl, STLINK_REG_HFSR, &hfsr) && hfsr) { + ILOG("Clear HFSR\n"); + stlink_write_debug32(sl, STLINK_REG_HFSR, hfsr); + } + return(0); } @@ -348,7 +363,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe // check written byte count stlink_read_reg(sl, 2, &rr); - if (rr.r[2] != 0) { + if ((int32_t)rr.r[2] > 0) { ELOG("Write error\n"); goto error; } @@ -364,7 +379,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe stlink_read_all_regs(sl, &rr); WLOG("Loader state: R2 0x%X R15 0x%X\n", rr.r[2], rr.r[15]); - if (dhcsr != 0x3000B || dfsr != 0x3 || cfsr || hfsr) { + if (dhcsr != 0x3000B || dfsr || cfsr || hfsr) { WLOG("MCU state: DHCSR 0x%X DFSR 0x%X CFSR 0x%X HFSR 0x%X\n", dhcsr, dfsr, cfsr, hfsr); } From bb96d613dd78f34b112dcbc91af0363315b7d0ff Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 27 Mar 2021 19:37:20 +0500 Subject: [PATCH 1148/1435] Fix is_flash_busy on STM32F1 XL device --- src/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common.c b/src/common.c index a17392cf1..640f37799 100644 --- a/src/common.c +++ b/src/common.c @@ -993,7 +993,7 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { unsigned int res; if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || (sl->flash_type == STLINK_FLASH_TYPE_L0)) { sr_busy_shift = FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { @@ -1010,7 +1010,7 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { sr_busy_shift = FLASH_H7_SR_QW; } else { - ELOG("unsupported flash method, abort\n"); + ELOG("unsupported flash method\n"); return(-1); } From be9c9dec7661f2b9e30fb26b85808bc132ee2c80 Mon Sep 17 00:00:00 2001 From: anton Date: Sun, 28 Mar 2021 21:36:12 +0500 Subject: [PATCH 1149/1435] flash_loader: fixed check of the flash loader results --- src/stlink-lib/flash_loader.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index aea60f258..992f0a827 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -363,7 +363,13 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe // check written byte count stlink_read_reg(sl, 2, &rr); - if ((int32_t)rr.r[2] > 0) { + /* The chunk size for loading is not rounded. The flash loader + * subtracts the size of the written block (1-8 bytes) from + * the remaining size each time. A negative value may mean that + * several bytes garbage has been written due to the unaligned + * firmware size. + */ + if ((int32_t)rr.r[2] > 0 || (int32_t)rr.r[2] < -7) { ELOG("Write error\n"); goto error; } From d0d52690d680d603264b90f6328e54aec4be793c Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 29 Mar 2021 19:51:55 +0500 Subject: [PATCH 1150/1435] Added error checking in the FLASH_SR register after write and erase operations --- src/common.c | 214 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 175 insertions(+), 39 deletions(-) diff --git a/src/common.c b/src/common.c index 640f37799..7ebbb8d11 100644 --- a/src/common.c +++ b/src/common.c @@ -159,6 +159,9 @@ // G0/G4 FLASH status register #define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) +#define STM32Gx_FLASH_SR_PROGERR (3) +#define STM32Gx_FLASH_SR_WRPERR (4) +#define STM32Gx_FLASH_SR_PGAERR (5) #define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ #define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ @@ -188,11 +191,15 @@ #define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) // WB Flash control register. -#define STM32WB_FLASH_CR_STRT (16) /* FLASH_CR Start */ -#define STM32WB_FLASH_CR_OPTLOCK (30) /* FLASH_CR Option Lock */ -#define STM32WB_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ +#define STM32WB_FLASH_CR_STRT (16) /* Start */ +#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ +#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ // WB Flash status register. -#define STM32WB_FLASH_SR_BSY (16) /* FLASH_SR Busy */ +#define STM32WB_FLASH_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ +#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ +#define STM32WB_FLASH_SR_WRPERR (4) /* Write protection error */ +#define STM32WB_FLASH_SR_PGAERR (5) /* Programming error */ +#define STM32WB_FLASH_SR_BSY (16) /* Busy */ // 32L4 register base is at FLASH_REGS_ADDR (0x40022000) #define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) @@ -201,8 +208,11 @@ #define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) #define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) +#define STM32L4_FLASH_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ +#define STM32L4_FLASH_SR_PROGERR 3 +#define STM32L4_FLASH_SR_WRPERR 4 +#define STM32L4_FLASH_SR_PGAERR 5 #define STM32L4_FLASH_SR_BSY 16 -#define STM32L4_FLASH_SR_ERRMASK 0x3f8 /* SR [9:3] */ #define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ #define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ @@ -234,7 +244,10 @@ #define STM32L0_FLASH_OPTLOCK (2) #define STM32L0_FLASH_OBL_LAUNCH (18) -#define STM32L0_FLASH_SR_ERROR_MASK 0x00003F00 +#define STM32L0_FLASH_SR_ERROR_MASK 0x00013F00 +#define STM32L0_FLASH_SR_WRPERR 8 +#define STM32L0_FLASH_SR_PGAERR 9 +#define STM32L0_FLASH_SR_NOTZEROERR 16 #define FLASH_ACR_OFF ((uint32_t) 0x00) #define FLASH_PECR_OFF ((uint32_t) 0x04) @@ -287,7 +300,10 @@ #define FLASH_F4_CR_SER 1 #define FLASH_F4_CR_SNB 3 #define FLASH_F4_CR_SNB_MASK 0xf8 -#define FLASH_F4_SR_BSY 16 +#define FLASH_F4_SR_ERROR_MASK 0x000000F0 +#define FLASH_F4_SR_PGAERR 5 +#define FLASH_F4_SR_WRPERR 4 +#define FLASH_F4_SR_BSY 16 // STM32F2 #define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) @@ -980,7 +996,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { sr_reg = (bank==BANK_1)?FLASH_H7_SR1:FLASH_H7_SR2; } else { - ELOG("unsupported flash method, abort\n"); + ELOG("method 'read_flash_sr' is unsupported\n"); return(-1); } @@ -988,6 +1004,35 @@ static inline uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { return(res); } +static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { + uint32_t sr_reg; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + sr_reg = (bank==BANK_1)?FLASH_SR:FLASH_SR2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + sr_reg = FLASH_F4_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_reg = FLASH_F7_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + sr_reg = STM32L4_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + sr_reg = STM32Gx_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + sr_reg = STM32WB_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_reg = (bank==BANK_1)?FLASH_H7_SR1:FLASH_H7_SR2; + } else { + ELOG("method 'write_flash_sr' is unsupported\n"); + return(-1); + } + + return stlink_write_debug32(sl, sr_reg, val); +} + static inline unsigned int is_flash_busy(stlink_t *sl) { uint32_t sr_busy_shift; unsigned int res; @@ -1010,7 +1055,7 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { sr_busy_shift = FLASH_H7_SR_QW; } else { - ELOG("unsupported flash method\n"); + ELOG("method 'is_flash_busy' is unsupported\n"); return(-1); } @@ -1048,43 +1093,120 @@ static void wait_flash_busy_progress(stlink_t *sl) { fprintf(stdout, "\n"); } +static void clear_flash_error(stlink_t *sl) +{ + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_F4: + write_flash_sr(sl, BANK_1, FLASH_F4_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_F7: + write_flash_sr(sl, BANK_1, FLASH_F7_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_L0: + write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_L4: + write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_H7: + write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_sr(sl, BANK_2, FLASH_H7_SR_ERROR_MASK); + } + break; + case STLINK_FLASH_TYPE_WB: + write_flash_sr(sl, BANK_1, STM32WB_FLASH_SR_ERROR_MASK); + break; + default: + break; + } +} + static int check_flash_error(stlink_t *sl) { uint32_t res = 0; + uint32_t WRPERR, PROGERR, PGAERR; + + WRPERR = PROGERR = PGAERR = 0; switch (sl->flash_type) { case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + res |= read_flash_sr(sl, BANK_2) & FLASH_SR_ERROR_MASK; + } + WRPERR = (1 << FLASH_SR_WRPRT_ERR); + PROGERR = (1 << FLASH_SR_PG_ERR); + break; + case STLINK_FLASH_TYPE_F4: + res = read_flash_sr(sl, BANK_1) & FLASH_F4_SR_ERROR_MASK; + WRPERR = (1 << FLASH_F4_SR_WRPERR); + PGAERR = (1 << FLASH_F4_SR_PGAERR); break; case STLINK_FLASH_TYPE_F7: res = read_flash_sr(sl, BANK_1) & FLASH_F7_SR_ERROR_MASK; + WRPERR = (1 << FLASH_F7_SR_WRP_ERR); + PROGERR = (1 << FLASH_F7_SR_PGP_ERR); break; case STLINK_FLASH_TYPE_G0: case STLINK_FLASH_TYPE_G4: res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32Gx_FLASH_SR_WRPERR); + PROGERR = (1 << STM32Gx_FLASH_SR_PROGERR); + PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); break; case STLINK_FLASH_TYPE_L0: res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); + PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); + PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); + break; + case STLINK_FLASH_TYPE_L4: + res = read_flash_sr(sl, BANK_1) & STM32L4_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32L4_FLASH_SR_WRPERR); + PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); + PGAERR = (1 << STM32L4_FLASH_SR_PGAERR); break; case STLINK_FLASH_TYPE_H7: res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; } - if (res) { - // Clear errors - stlink_write_debug32(sl, FLASH_H7_CCR1, res); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - stlink_write_debug32(sl, FLASH_H7_CCR2, res); - } - } + WRPERR = (1 << FLASH_H7_SR_WRPERR); + break; + case STLINK_FLASH_TYPE_WB: + res = read_flash_sr(sl, BANK_1) & STM32WB_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32WB_FLASH_SR_WRPERR); + PROGERR = (1 << STM32WB_FLASH_SR_PROGERR); + PGAERR = (1 << STM32WB_FLASH_SR_PGAERR); break; default: break; } if (res) { - ELOG("Flash programming error : %#010x\n", res); + if (WRPERR && (WRPERR&res)==WRPERR) { + ELOG("Flash memory is write protected\n"); + res &= ~WRPERR; + } else if (PROGERR && (PROGERR&res)==PROGERR) { + ELOG("Flash memory contains a non-erased value\n"); + res &= ~PROGERR; + } else if (PGAERR && (PGAERR&res)==PGAERR) { + ELOG("Invalid flash address\n"); + res &= ~PGAERR; + } + + if (res) { + ELOG("Flash programming error: %#010x\n", res); + } return(-1); } @@ -2372,12 +2494,14 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { * @return 0 on success -ve on failure */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { + // wait for ongoing op to finish + wait_flash_busy(sl); + // clear flash IO errors + clear_flash_error(sl); + if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_F7 || sl->flash_type == STLINK_FLASH_TYPE_L4) { - // wait for ongoing op to finish - wait_flash_busy(sl); - // unlock if locked unlock_flash_if(sl); @@ -2498,7 +2622,6 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { uint32_t val; - wait_flash_busy(sl); // wait for any ongoing Flash operation to finish unlock_flash_if(sl); set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit @@ -2535,7 +2658,6 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } else if (sl->flash_type == STLINK_FLASH_TYPE_F0 || sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { unsigned bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE)?BANK_1:BANK_2; - wait_flash_busy(sl); unlock_flash_if(sl); clear_flash_cr_pg(sl, bank); // clear the pg bit set_flash_cr_per(sl, bank); // set the page erase bit @@ -2545,7 +2667,6 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { lock_flash(sl); } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE)?BANK_1:BANK_2; - wait_flash_busy(sl); // wait for ongoing op to finish unlock_flash_if(sl); // unlock if locked uint32_t sector = calculate_H7_sectornum(sl, flashaddr, bank);// calculate the actual page from the address write_flash_cr_snb(sl, sector, bank); // select the page to erase @@ -2557,8 +2678,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { return(-1); } - // TODO: verify the erased page - return(0); + return check_flash_error(sl); } int stlink_erase_flash_mass(stlink_t *sl) { @@ -2574,7 +2694,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { // addr must be an addr inside the page stm32_addr_t addr = (stm32_addr_t)sl->flash_base + i * (stm32_addr_t)sl->flash_pgsz; - if (stlink_erase_flash_page(sl, addr) == -1) { + if (stlink_erase_flash_page(sl, addr)) { WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); return(-1); } @@ -2586,6 +2706,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { fprintf(stdout, "\n"); } else { wait_flash_busy(sl); + clear_flash_error(sl); unlock_flash_if(sl); if (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_id != STLINK_CHIPID_STM32_H7AX) { @@ -2596,7 +2717,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { } } - set_flash_cr_mer(sl, 1, BANK_1); // set the mass erase bit + set_flash_cr_mer(sl, 1, BANK_1); // set the mass erase bit set_flash_cr_strt(sl, BANK_1); // start erase operation, reset by hw with busy bit if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || @@ -2606,7 +2727,6 @@ int stlink_erase_flash_mass(stlink_t *sl) { } wait_flash_busy_progress(sl); - err = check_flash_error(sl); lock_flash(sl); // reset the mass erase bit @@ -2616,7 +2736,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { set_flash_cr_mer(sl, 0, BANK_2); } - // TODO: verify the erased memory + err = check_flash_error(sl); } return(err); @@ -2751,6 +2871,11 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_MASKINTS); + // wait for ongoing op to finish + wait_flash_busy(sl); + // Clear errors + clear_flash_error(sl); + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_F7) || (sl->flash_type == STLINK_FLASH_TYPE_L4)) { @@ -2801,7 +2926,6 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { sl->flash_type == STLINK_FLASH_TYPE_G4) { ILOG("Starting Flash write for WB/G0/G4\n"); - wait_flash_busy(sl); unlock_flash_if(sl); // unlock flash if necessary set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { @@ -2882,6 +3006,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr size_t size = len - off > buf_size ? buf_size : len - off; if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", (unsigned)(addr + off)); + check_flash_error(sl); return(-1); } @@ -2977,6 +3102,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", (unsigned)(addr + off)); + check_flash_error(sl); return(-1); } @@ -3015,7 +3141,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr return(-1); } - return(0); + return check_flash_error(sl); } int stlink_flashloader_stop(stlink_t *sl) { @@ -3405,6 +3531,8 @@ static int stlink_write_option_bytes_gx( (void)len; uint32_t data; + clear_flash_error(sl); + write_uint32((unsigned char*)&data, *(uint32_t*)(base)); WLOG("Writing option bytes %#10x to %#10x\n", data, addr); stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); @@ -3441,7 +3569,7 @@ static int stlink_write_option_bytes_l0( int ret = 0; // Clear errors - stlink_write_debug32(sl, flash_base + FLASH_SR_OFF, STM32L0_FLASH_REGS_ADDR); + clear_flash_error(sl); while (len != 0) { write_uint32((unsigned char*)&data, *(uint32_t*)(base)); // write options bytes @@ -3480,6 +3608,9 @@ static int stlink_write_option_bytes_l4( (void)addr; (void)len; + // Clear errors + clear_flash_error(sl); + // write options bytes uint32_t data; write_uint32((unsigned char*)&data, *(uint32_t*)(base)); @@ -3516,6 +3647,9 @@ static int stlink_write_option_bytes_f4( (void)addr; (void)len; + // Clear errors + clear_flash_error(sl); + write_uint32((unsigned char*)&option_byte, *(uint32_t*)(base)); // write option byte, ensuring we dont lock opt, and set strt bit @@ -3539,8 +3673,8 @@ static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t* base, stm32_addr_ uint32_t option_byte; int ret = 0; - //(void) addr; - //(void) len; + // Clear errors + clear_flash_error(sl); ILOG("Asked to write option byte %#10x to %#010x.\n", *(uint32_t*) (base), addr); write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); @@ -3999,9 +4133,10 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option_control_register) { int ret = 0; + // Clear errors + clear_flash_error(sl); + ILOG("Asked to write option control register 1 %#10x to %#010x.\n", option_control_register, FLASH_F7_OPTCR); - //write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); - //ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); /* write option byte, ensuring we dont lock opt, and set strt bit */ stlink_write_debug32(sl, FLASH_F7_OPTCR, (option_control_register & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); @@ -4010,7 +4145,7 @@ static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option ret = check_flash_error(sl); if (!ret) - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, FLASH_F7_OPTCR1); + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, FLASH_F7_OPTCR); return ret; } @@ -4024,9 +4159,10 @@ static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option static int stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t option_control_register1) { int ret = 0; + // Clear errors + clear_flash_error(sl); + ILOG("Asked to write option control register 1 %#010x to %#010x.\n", option_control_register1, FLASH_F7_OPTCR1); - //write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); - //ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); /* write option byte, ensuring we dont lock opt, and set strt bit */ uint32_t current_control_register_value; From 817c8ad436eada97294fa93e6cc8e57fb1be9504 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 29 Mar 2021 20:31:57 +0500 Subject: [PATCH 1151/1435] flash_loader: fixed setup PG flag in F0/VL flash loaders, code cleared --- flashloaders/stm32f0.s | 6 ++-- src/common.c | 58 ++++++++++------------------------- src/stlink-lib/flash_loader.c | 18 +++++------ 3 files changed, 26 insertions(+), 56 deletions(-) diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index e2a4b0f00..23f1c43fe 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -35,10 +35,8 @@ copy: ldr r5, flash_off_sr add r5, r5, r7 - # FLASH_CR |= 0x01 (set PG) - ldr r7, =0x1 - ldr r4, [r6] - orrs r4, r4, r7 + # FLASH_CR = 0x01 (set PG) + ldr r4, =0x1 str r4, [r6] loop: diff --git a/src/common.c b/src/common.c index 7ebbb8d11..8585ff881 100644 --- a/src/common.c +++ b/src/common.c @@ -394,13 +394,21 @@ uint16_t read_uint16(const unsigned char *c, const int pt) { static uint32_t get_stm32l0_flash_base(stlink_t *sl) { switch (sl->chip_id) { + case STLINK_CHIPID_STM32_L0: + case STLINK_CHIPID_STM32_L0_CAT5: + case STLINK_CHIPID_STM32_L0_CAT2: + case STLINK_CHIPID_STM32_L011: + return(STM32L0_FLASH_REGS_ADDR); + case STLINK_CHIPID_STM32_L1_CAT2: case STLINK_CHIPID_STM32_L1_MEDIUM: case STLINK_CHIPID_STM32_L1_MEDIUM_PLUS: case STLINK_CHIPID_STM32_L1_HIGH: return(STM32L1_FLASH_REGS_ADDR); + default: - return(STM32L0_FLASH_REGS_ADDR); + WLOG("Flash base use default L0 address"); + return(STM32L0_FLASH_REGS_ADDR); } } @@ -2549,16 +2557,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { uint32_t val; - uint32_t flash_regs_base; - - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L011) { - flash_regs_base = STM32L0_FLASH_REGS_ADDR; - } else { - flash_regs_base = STM32L_FLASH_REGS_ADDR; - } + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); // check if the locks are set stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -2592,15 +2591,6 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { // set pecr.{erase,prog} val |= (1 << 9) | (1 << 3); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); -#if 0 - /* Wait for sr.busy to be cleared - * MP: Test shows that busy bit is not set here. Perhaps, PM0062 is wrong - * and we do not need to wait here for clearing the busy bit. - */ - do { - stlink_read_debug32(sl, STM32L_FLASH_SR, &val) - } while ((val & (1 << 0)) != 0); -#endif // write 0 to the first word of the page to be erased stlink_write_debug32(sl, flashaddr, 0); @@ -2610,9 +2600,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { * Test shows that a few iterations is performed in the following loop * before busy bit is cleared. */ - do - stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); - while ((val & (1 << 0)) != 0); + wait_flash_busy(sl); // reset lock bits stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -2652,7 +2640,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit - wait_flash_busy(sl); // wait for the 'busy' bit to clear + wait_flash_busy(sl); // wait for the 'busy' bit to clear clear_flash_cr_per(sl, BANK_1); // clear the 'enable page erase' bit lock_flash(sl); } else if (sl->flash_type == STLINK_FLASH_TYPE_F0 || @@ -2664,6 +2652,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { write_flash_ar(sl, flashaddr, bank); // select the page to erase set_flash_cr_strt(sl, bank); // start erase operation, reset by hw with busy bit wait_flash_busy(sl); + clear_flash_cr_per(sl, bank); // clear the page erase bit lock_flash(sl); } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE)?BANK_1:BANK_2; @@ -2796,18 +2785,9 @@ int stm32l1_write_half_pages( unsigned int count; unsigned int num_half_pages = len / pagesize; uint32_t val; - uint32_t flash_regs_base; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); flash_loader_t fl; - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L011) { - flash_regs_base = STM32L0_FLASH_REGS_ADDR; - } else { - flash_regs_base = STM32L_FLASH_REGS_ADDR; - } - ILOG("Starting Half page flash write for STM32L core id\n"); /* Flash loader initialisation */ @@ -2824,9 +2804,7 @@ int stm32l1_write_half_pages( val |= (1 << FLASH_L1_PROG); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - do { - stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); - } while ((val & (1 << 0)) != 0); + wait_flash_busy(sl); for (count = 0; count < num_half_pages; count++) { if (stlink_flash_loader_run( @@ -2845,9 +2823,7 @@ int stm32l1_write_half_pages( fflush(stdout); } - do { - stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); - } while ((val & (1 << 0)) != 0); + wait_flash_busy(sl); } stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -3096,8 +3072,6 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr // unlock and set programming mode unlock_flash_if(sl); - if (sl->flash_type != STLINK_FLASH_TYPE_F1_XL) { set_flash_cr_pg(sl, BANK_1); } - DLOG("Finished unlocking flash, running loader!\n"); if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 992f0a827..e3b1a12ea 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -14,11 +14,10 @@ /* flashloaders/stm32f0.s -- compiled with thumb2 */ static const uint8_t loader_code_stm32vl[] = { 0x00, 0xbf, 0x00, 0xbf, - 0x0f, 0x4f, 0x1f, 0x44, - 0x0f, 0x4e, 0x3e, 0x44, - 0x0f, 0x4d, 0x3d, 0x44, - 0x4f, 0xf0, 0x01, 0x07, - 0x34, 0x68, 0x3c, 0x43, + 0x0e, 0x4f, 0x1f, 0x44, + 0x0e, 0x4e, 0x3e, 0x44, + 0x0e, 0x4d, 0x3d, 0x44, + 0x4f, 0xf0, 0x01, 0x04, 0x34, 0x60, 0x04, 0x88, 0x0c, 0x80, 0x02, 0x30, 0x02, 0x31, 0x4f, 0xf0, @@ -38,11 +37,10 @@ static const uint8_t loader_code_stm32vl[] = { /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ static const uint8_t loader_code_stm32f0[] = { 0xc0, 0x46, 0xc0, 0x46, - 0x0d, 0x4f, 0x1f, 0x44, - 0x0d, 0x4e, 0x3e, 0x44, - 0x0d, 0x4d, 0x3d, 0x44, - 0x0d, 0x4f, 0x34, 0x68, - 0x3c, 0x43, 0x34, 0x60, + 0x0c, 0x4f, 0x1f, 0x44, + 0x0c, 0x4e, 0x3e, 0x44, + 0x0c, 0x4d, 0x3d, 0x44, + 0x0c, 0x4c, 0x34, 0x60, 0x04, 0x88, 0x0c, 0x80, 0x02, 0x30, 0x02, 0x31, 0x09, 0x4f, 0x2c, 0x68, From b62cdcfab70e362b34b5875ad86b31c9e6fd6c73 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 29 Mar 2021 20:40:22 +0500 Subject: [PATCH 1152/1435] Added disabling the IWDG and WWDG in halt state --- src/common.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 8585ff881..26a3b3859 100644 --- a/src/common.c +++ b/src/common.c @@ -362,6 +362,25 @@ #define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) #define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) +#define STM32F0_DBGMCU_CR 0xE0042004 +#define STM32F0_DBGMCU_CR_IWDG_STOP 8 +#define STM32F0_DBGMCU_CR_WWDG_STOP 9 + +#define STM32F4_DBGMCU_APB1FZR1 0xE0042008 +#define STM32F4_DBGMCU_APB1FZR1_WWDG_STOP 11 +#define STM32F4_DBGMCU_APB1FZR1_IWDG_STOP 12 + +#define STM32L0_DBGMCU_APB1_FZ 0x40015808 +#define STM32L0_DBGMCU_APB1_FZ_WWDG_STOP 11 +#define STM32L0_DBGMCU_APB1_FZ_IWDG_STOP 12 + +#define STM32H7_DBGMCU_APB1HFZ 0x5C001054 +#define STM32H7_DBGMCU_APB1HFZ_IWDG_STOP 18 + +#define STM32WB_DBGMCU_APB1FZR1 0xE004203C +#define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11 +#define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12 + #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 @@ -1221,6 +1240,50 @@ static int check_flash_error(stlink_t *sl) return(0); } +static void stop_wdg_in_debug(stlink_t *sl) { + uint32_t dbgmcu_cr; + uint32_t set; + uint32_t value; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + case STLINK_FLASH_TYPE_G4: + dbgmcu_cr = STM32F0_DBGMCU_CR; + set = (1< halted state. int stlink_force_debug(stlink_t *sl) { DLOG("*** stlink_force_debug_mode ***\n"); - return(sl->backend->force_debug(sl)); + int res = sl->backend->force_debug(sl); + // Stop the watchdogs in the halted state for suppress target reboot + stop_wdg_in_debug(sl); + return(res); } int stlink_exit_dfu_mode(stlink_t *sl) { From b0192478c8262476ead421890b1550d6a7b72ecc Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 29 Mar 2021 20:56:03 +0500 Subject: [PATCH 1153/1435] Added disabling the DMA channels --- inc/stlink.h | 3 +- src/common.c | 83 +++++++++++++++++++++++++++++++++++++++- src/st-flash/flash.c | 13 ------- src/st-util/gdb-server.c | 2 +- src/stlink-gui/gui.c | 12 ------ 5 files changed, 84 insertions(+), 29 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 7bb1bc51e..61b8472f1 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -137,6 +137,7 @@ typedef uint32_t stm32_addr_t; typedef struct flash_loader { stm32_addr_t loader_addr; // loader sram addr stm32_addr_t buf_addr; // buffer sram address + uint32_t rcc_dma_bkp; // backup RCC DMA enable state } flash_loader_t; typedef struct _cortex_m3_cpuid_ { @@ -297,7 +298,7 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len); -int stlink_flashloader_stop(stlink_t *sl); +int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl); #include #include diff --git a/src/common.c b/src/common.c index 26a3b3859..60d7ff145 100644 --- a/src/common.c +++ b/src/common.c @@ -381,6 +381,27 @@ #define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11 #define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12 +#define STM32F1_RCC_AHBENR 0x40021014 +#define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32F4_RCC_AHB1ENR 0x40023830 +#define STM32F4_RCC_DMAEN 0x00600000 // DMA2EN | DMA1EN + +#define STM32G0_RCC_AHBENR 0x40021038 +#define STM32G0_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32G4_RCC_AHB1ENR 0x40021048 +#define STM32G4_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32L0_RCC_AHBENR 0x40021030 +#define STM32L0_RCC_DMAEN 0x00000001 // DMAEN + +#define STM32H7_RCC_AHB1ENR 0x58024538 +#define STM32H7_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32WB_RCC_AHB1ENR 0x58000048 +#define STM32WB_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 @@ -1284,6 +1305,58 @@ static void stop_wdg_in_debug(stlink_t *sl) { } } +static void set_dma_state(stlink_t *sl, flash_loader_t* fl, int bckpRstr) { + uint32_t rcc, rcc_dma_mask, value; + + rcc = rcc_dma_mask = value = 0; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + rcc = STM32F1_RCC_AHBENR; + rcc_dma_mask = STM32F1_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_F4: + case STLINK_FLASH_TYPE_F7: + rcc = STM32F4_RCC_AHB1ENR; + rcc_dma_mask = STM32F4_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_G0: + rcc = STM32G0_RCC_AHBENR; + rcc_dma_mask = STM32G0_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_G4: + case STLINK_FLASH_TYPE_L4: + rcc = STM32G4_RCC_AHB1ENR; + rcc_dma_mask = STM32G4_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_L0: + rcc = STM32L0_RCC_AHBENR; + rcc_dma_mask = STM32L0_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_H7: + rcc = STM32H7_RCC_AHB1ENR; + rcc_dma_mask = STM32H7_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_WB: + rcc = STM32WB_RCC_AHB1ENR; + rcc_dma_mask = STM32WB_RCC_DMAEN; + break; + default: + return; + } + + if (!stlink_read_debug32(sl, rcc, &value)) { + if (bckpRstr) { + value = (value&(~rcc_dma_mask)) | fl->rcc_dma_bkp; + } else { + fl->rcc_dma_bkp = value&rcc_dma_mask; + value &= ~rcc_dma_mask; + } + stlink_write_debug32(sl, rcc, value); + } +} + static inline void write_flash_ar(stlink_t *sl, uint32_t n, unsigned bank) { stlink_write_debug32(sl, (bank==BANK_1)?FLASH_AR:FLASH_AR2, n); } @@ -2913,6 +2986,9 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_MASKINTS); + // disable DMA + set_dma_state(sl, fl, 0); + // wait for ongoing op to finish wait_flash_busy(sl); // Clear errors @@ -3184,7 +3260,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr return check_flash_error(sl); } -int stlink_flashloader_stop(stlink_t *sl) { +int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { uint32_t dhcsr; if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || @@ -3224,6 +3300,9 @@ int stlink_flashloader_stop(stlink_t *sl) { (dhcsr&(~STLINK_REG_DHCSR_C_MASKINTS))); } + // restore DMA state + set_dma_state(sl, fl, 1); + return(0); } @@ -3286,7 +3365,7 @@ int stlink_write_flash( ret = stlink_flashloader_write(sl, &fl, addr, base, len); if (ret) return ret; - ret = stlink_flashloader_stop(sl); + ret = stlink_flashloader_stop(sl, &fl); if (ret) return ret; diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 5a226d57b..e870e116c 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -112,19 +112,6 @@ int main(int ac, char** av) { } } - // disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 - if (sl->chip_id == STLINK_CHIPID_STM32_F4) { - memset(sl->q_buf, 0, 4); - - for (int i = 0; i < 8; i++) { - stlink_write_mem32(sl, 0x40026000 + 0x10 + 0x18 * i, 4); - stlink_write_mem32(sl, 0x40026400 + 0x10 + 0x18 * i, 4); - stlink_write_mem32(sl, 0x40026000 + 0x24 + 0x18 * i, 4); - stlink_write_mem32(sl, 0x40026400 + 0x24 + 0x18 * i, 4); - - } - } - // core must be halted to use RAM based flashloaders if (stlink_force_debug(sl)) { printf("Failed to halt the core\n"); diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 3dc3073e5..8d63d9ee0 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -908,7 +908,7 @@ static int flash_go(stlink_t *sl) { } } - stlink_flashloader_stop(sl); + stlink_flashloader_stop(sl, &fl); stlink_soft_reset(sl, 1 /* halt on reset */); error = 0; diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index ed38fcc7c..d264cf9a5 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -514,18 +514,6 @@ static void connect_button_cb(GtkWidget *widget, gpointer data) { stlink_enter_swd_mode(gui->sl); } - // disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 - if (gui->sl->chip_id == STLINK_CHIPID_STM32_F4) { - memset(gui->sl->q_buf, 0, 4); - - for (i = 0; i < 8; i++) { - stlink_write_mem32(gui->sl, 0x40026000 + 0x10 + 0x18 * i, 4); - stlink_write_mem32(gui->sl, 0x40026400 + 0x10 + 0x18 * i, 4); - stlink_write_mem32(gui->sl, 0x40026000 + 0x24 + 0x18 * i, 4); - stlink_write_mem32(gui->sl, 0x40026400 + 0x24 + 0x18 * i, 4); - } - } - stlink_gui_set_connected(gui); } From c793ca348fab43711cc3d24e8b9956ba90ca03d3 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 29 Mar 2021 22:19:48 +0500 Subject: [PATCH 1154/1435] Fixed GUI compilation --- src/stlink-gui/gui.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index d264cf9a5..03e999b7f 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -489,7 +489,6 @@ static void stlink_gui_set_connected(STlinkGUI *gui) { static void connect_button_cb(GtkWidget *widget, gpointer data) { STlinkGUI *gui; - gint i; (void)widget; gui = STLINK_GUI(data); From 4334ce48b2c03497a6d415f8982fdb986409398c Mon Sep 17 00:00:00 2001 From: anton Date: Sun, 4 Apr 2021 11:45:21 +0500 Subject: [PATCH 1155/1435] flash_loader: added reset of IWDG If IWDG is enabled by hardware, then IWDG cannot be disabled by software --- inc/stlink.h | 1 + src/stlink-lib/flash_loader.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/inc/stlink.h b/inc/stlink.h index 61b8472f1..855e5126d 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -138,6 +138,7 @@ typedef struct flash_loader { stm32_addr_t loader_addr; // loader sram addr stm32_addr_t buf_addr; // buffer sram address uint32_t rcc_dma_bkp; // backup RCC DMA enable state + uint32_t iwdg_kr; // IWDG key register address } flash_loader_t; typedef struct _cortex_m3_cpuid_ { diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index e3b1a12ea..80262cf07 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -9,6 +9,11 @@ #define FLASH_REGS_BANK2_OFS 0x40 #define FLASH_BANK2_START_ADDR 0x08080000 +#define STM32F0_WDG_KR 0x40003000 +#define STM32H7_WDG_KR 0x58004800 + +#define STM32F0_WDG_KR_KEY_RELOAD 0xAAAA + /* DO NOT MODIFY SOURCECODE DIRECTLY, EDIT ASSEMBLY FILES INSTEAD */ /* flashloaders/stm32f0.s -- compiled with thumb2 */ @@ -164,6 +169,13 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { fl->buf_addr = fl->loader_addr + (uint32_t)size; ILOG("Successfully loaded flash loader in sram\n"); + // set address of IWDG key register for reset it + if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + fl->iwdg_kr = STM32H7_WDG_KR; + } else { + fl->iwdg_kr = STM32F0_WDG_KR; + } + /* Clear Fault Status Register for handling flash loader error */ if (!stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr) && dfsr) { ILOG("Clear DFSR\n"); @@ -329,6 +341,11 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe // only used on VL/F1_XL, but harmless for others stlink_write_reg(sl, fl->loader_addr, 15); // pc register + /* Reset IWDG */ + if (fl->iwdg_kr) { + stlink_write_debug32(sl, fl->iwdg_kr, STM32F0_WDG_KR_KEY_RELOAD); + } + /* Run loader */ stlink_run(sl); From a3b1247d141592bd87fdb1f0aeec879e1b061eef Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 4 Apr 2021 23:40:10 +0200 Subject: [PATCH 1156/1435] General Project Update - Updated CHANGELOG.md - Added STLINK-V3E to supported programmers --- CHANGELOG.md | 22 ++++++++++++++-------- README.md | 2 +- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee46901e7..57426342a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,14 @@ -# stlink ChangeLog +# stlink Changelog # v1.6.2 -Release date: (planned Q2/2021) +Release date: 2020-04-xx + +This release drops support for the STLINK/V1 programmer on macOS 10.13. Features: -- Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) +- Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#868](https://github.com/stlink-org/stlink/pull/868), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) - Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052)) - Official support for STLINK-V3 programmers (commit [#5e0a502](https://github.com/stlink-org/stlink/commit/5e0a502df812495bfa96fa9116a19f1306152b17), [#820](https://github.com/stlink-org/stlink/pull/820), [#1022](https://github.com/stlink-org/stlink/pull/1022), [#1025](https://github.com/stlink-org/stlink/pull/1025)) - Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) @@ -18,6 +20,7 @@ Features: - Link for WIN32 & APPLE with stlink-static ([#1069](https://github.com/stlink-org/stlink/pull/1069)) - ITM functionality for STLink/V2 and STM32Fxx chipsets ([#136](https://github.com/stlink-org/stlink/pull/136), [#179](https://github.com/stlink-org/stlink/pull/179), [#815](https://github.com/stlink-org/stlink/pull/815), [#1072](https://github.com/stlink-org/stlink/pull/1072)) - Included ITM functionality for building with MSVC ([#1080](https://github.com/stlink-org/stlink/pull/1080)) +- Update for CI integration (commit [#0eebc9a](https://github.com/stlink-org/stlink/commit/0eebc9a74506e84d5c460ec325ae98064a81885e), [#1118](https://github.com/stlink-org/stlink/pull/1118)) Updates & changes: @@ -32,10 +35,11 @@ Updates & changes: - [doc] Added example for output of `st-info --probe` ([#1007](https://github.com/stlink-org/stlink/pull/1007), [#1049](https://github.com/stlink-org/stlink/pull/1049)) - [refactoring] Correctly handle endianness without reference to host platform ([#1081](https://github.com/stlink-org/stlink/pull/1081)) - Check format string for log messages ([#1093](https://github.com/stlink-org/stlink/pull/1093)) +- Removed abort() from stlink-lib ([#1116](https://github.com/stlink-org/stlink/pull/1116)) Fixes: -- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) +- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) - Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106)) - Use vl flashloader for all STM32F1 series ([#769](https://github.com/stlink-org/stlink/pull/769), [#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) @@ -60,6 +64,8 @@ Fixes: - Fixed support for writing option bytes ([#1102](https://github.com/stlink-org/stlink/pull/1102)) - [doc] Corrected spelling mistake in bug report template ([#1103](https://github.com/stlink-org/stlink/pull/1103)) - Fixed STM32WB55 reading DEBUG IDCODE from the wrong address ([#1100](https://github.com/stlink-org/stlink/pull/1100), [#1101](https://github.com/stlink-org/stlink/pull/1101)) +- Applied missing changes to tests ([#1119](https://github.com/stlink-org/stlink/pull/1119)) +- Improvements for Chip_ID read ([#1120](https://github.com/stlink-org/stlink/pull/1120)) # v1.6.1 @@ -216,7 +222,7 @@ Release date: 2018-09-13 Major changes and added features: -- Added reset through `AIRCR` ([#540](https://github.com/stlink-org/stlink/pull/540), [#712](https://github.com/stlink-org/stlink/pull/712)) +- Added reset through `AIRCR` ([#254](https://github.com/stlink-org/stlink/pull/254), [#540](https://github.com/stlink-org/stlink/pull/540), [#712](https://github.com/stlink-org/stlink/pull/712)) - Added creation of icons for `.desktop` file ([#684](https://github.com/stlink-org/stlink/pull/684), [#708](https://github.com/stlink-org/stlink/pull/708)) - Added desktop file for linux ([#688](https://github.com/stlink-org/stlink/pull/688)) - Added button to export STM32 flash memory to a file ([#691](https://github.com/stlink-org/stlink/pull/691)) @@ -279,7 +285,6 @@ Major changes and added features: Updates and fixes: -- Fixed gdb-server: STM32L0xx has no `FP_CTRL` register for breakpoints ([#273](https://github.com/stlink-org/stlink/pull/273)) - Added `--flash=n[k][m]` command line option to override device model ([#305](https://github.com/stlink-org/stlink/pull/305), [#516](https://github.com/stlink-org/stlink/pull/516), [#576](https://github.com/stlink-org/stlink/pull/576)) - Updated `libusb` to 1.0.21 for Windows ([#562](https://github.com/stlink-org/stlink/pull/562)) - Fixed low-voltage flashing on STM32F7 devices ([#566](https://github.com/stlink-org/stlink/pull/566), [#567](https://github.com/stlink-org/stlink/pull/567)) @@ -324,11 +329,11 @@ Major changes and added features: - Added manpages (generated with `pandoc` from Markdown) ([#208](https://github.com/stlink-org/stlink/pull/208), [#464](https://github.com/stlink-org/stlink/pull/464), [#466](https://github.com/stlink-org/stlink/pull/466), [#467](https://github.com/stlink-org/stlink/pull/467)) - Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#228](https://github.com/stlink-org/stlink/pull/228), [#507](https://github.com/stlink-org/stlink/pull/507), commit [#3fd0f09](https://github.com/stlink-org/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) - Support serial numbers argument for `st-util` and `st-flash` to probe and control multiple connected programmers ([#318](https://github.com/stlink-org/stlink/pull/318), [#398](https://github.com/stlink-org/stlink/pull/398), [#541](https://github.com/stlink-org/stlink/pull/541)) +- Added 'k' (kill) command to gdb-server, which resets the connection ([#358](https://github.com/stlink-org/stlink/pull/358), [#525](https://github.com/stlink-org/stlink/pull/525), [#527](https://github.com/stlink-org/stlink/pull/527), [#528](https://github.com/stlink-org/stlink/pull/528)) - Merge `st-probe` tool into `st-info` ([#398](https://github.com/stlink-org/stlink/pull/398)) - Added support for native debian packaging ([#444](https://github.com/stlink-org/stlink/pull/444), [#472](https://github.com/stlink-org/stlink/pull/472), [#473](https://github.com/stlink-org/stlink/pull/473), [#482](https://github.com/stlink-org/stlink/pull/482), [#483](https://github.com/stlink-org/stlink/pull/483), [#484](https://github.com/stlink-org/stlink/pull/484), [#485](https://github.com/stlink-org/stlink/pull/485)) - Rewritten commandline parsing for `st-flash` ([#459](https://github.com/stlink-org/stlink/pull/459)) - Added `--reset` command to `st-flash` ([#505](https://github.com/stlink-org/stlink/pull/505)) -- st-util should detect when USB commands fail ([#525](https://github.com/stlink-org/stlink/pull/525), [#527](https://github.com/stlink-org/stlink/pull/527), [#528](https://github.com/stlink-org/stlink/pull/528)) Chip support added for: @@ -344,12 +349,12 @@ Chip support added for: Updates and fixes: +- Do a JTAG reset prior to reading CPU information when processor is in deep sleep ([#291](https://github.com/stlink-org/stlink/pull/291), [#428](https://github.com/stlink-org/stlink/pull/428), [#430](https://github.com/stlink-org/stlink/pull/430), [#451](https://github.com/stlink-org/stlink/pull/451)) - Fixed `unaligned addr or size` when trying to write a program in RAM ([#323](https://github.com/stlink-org/stlink/pull/323)) - Fixed flashing on `STM32_F3_SMALL` ([#325](https://github.com/stlink-org/stlink/pull/325)) - Fixed STM32L-problem with flash loader ([#390](https://github.com/stlink-org/stlink/pull/390), [#407](https://github.com/stlink-org/stlink/pull/407), [#408](https://github.com/stlink-org/stlink/pull/408)) - Don't read the target voltage on startup, because it crashes STM32F100 ([#423](https://github.com/stlink-org/stlink/pull/423), [#424](https://github.com/stlink-org/stlink/pull/424)) - Added a useful error message instead of `[!] send_recv` ([#425](https://github.com/stlink-org/stlink/pull/425), [#426](https://github.com/stlink-org/stlink/pull/426)) -- Do a JTAG reset prior to reading CPU information when processor is in deep sleep ([#428](https://github.com/stlink-org/stlink/pull/428), [#430](https://github.com/stlink-org/stlink/pull/430), [#451](https://github.com/stlink-org/stlink/pull/451)) - Fixed STM32F030 erase error ([#442](https://github.com/stlink-org/stlink/pull/442)) - Fixed memory map for STM32F7xx ([#453](https://github.com/stlink-org/stlink/pull/453), [#456](https://github.com/stlink-org/stlink/pull/456)) - Redesign of `st-flash` commandline options parsing ([#459](https://github.com/stlink-org/stlink/pull/459)) @@ -392,6 +397,7 @@ Updates and fixes: - Modified determination of erased byte pattern when flashing ([#193](https://github.com/stlink-org/stlink/pull/193), [#377](https://github.com/stlink-org/stlink/pull/377)) - Use libusb synchronous api ([#194](https://github.com/stlink-org/stlink/pull/194), [#225](https://github.com/stlink-org/stlink/pull/225), [#374](https://github.com/stlink-org/stlink/pull/374)) - Fixed segfault when programmer is already busy and `NULL` pointers are in the list ([#256](https://github.com/stlink-org/stlink/pull/256), [#394](https://github.com/stlink-org/stlink/pull/394)) +- Fixed gdb-server: Cortex M0 chips have no `FP_CTRL` register for breakpoints ([#266](https://github.com/stlink-org/stlink/pull/266), [#273](https://github.com/stlink-org/stlink/pull/273), [#341](https://github.com/stlink-org/stlink/pull/341)) - Fixed issue where "unknown chip id!" was seen every other time ([#352](https://github.com/stlink-org/stlink/pull/352), [#367](https://github.com/stlink-org/stlink/pull/367), [#381](https://github.com/stlink-org/stlink/pull/381)) - Send F4 memory-map and features for STM32F429 ([#188](https://github.com/stlink-org/stlink/pull/188), [#196](https://github.com/stlink-org/stlink/pull/196), [#250](https://github.com/stlink-org/stlink/pull/250), [#251](https://github.com/stlink-org/stlink/pull/251)) (Release v1.1.0) - Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/stlink-org/stlink/pull/218), [#288](https://github.com/stlink-org/stlink/pull/288)) (Release v1.1.0) diff --git a/README.md b/README.md index 644c3fd86..93994db49 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ It supports several so called STLINK programmer boards (and clones thereof) whic - **STLINK-V3** - transport layer: raw USB commands - stand-alone programmer (STLINK-V3SET, STLINK-V3MINI, STLINK-V3MODS) - - on-board on some STM32 Nucleo boards + - on-board on some STM32 Nucleo boards (STLINK-V3E) _\*)_ **Note: Support for the STLINK/V1 on macOS is limited to 10.14 - 10.15. Due to the deprecation and removal of macOS Kernel Extensions (KEXT) there will be no support for this programmer on macOS 11 or any later version.** From 9a8e0aa6457640e27a0dbee5d994c3f8249fddf6 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 5 Apr 2021 21:15:18 +0500 Subject: [PATCH 1157/1435] Added the hot plug option to st-flash --- doc/tutorial.md | 2 +- src/st-flash/flash.c | 4 ++-- src/st-flash/flash_opts.c | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 37c29ab6a..256513bc4 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -9,7 +9,7 @@ | --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
      This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | | --reset | st-flash | Trigger a reset both before and after flashing. The default uses the hardware reset through `NRST` pin.
      A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | | --connect-under-reset | st-info
      st-flash | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
      when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | -| --hot-plug | st-info
      st-util | Connect to the target without reset. | v1.6.2 | +| --hot-plug | st-info
      st-flash
      st-util | Connect to the target without reset. | v1.6.2 | | --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | | --version | st-info
      st-flash
      st-util | Print version information. | v1.3.0 | | --help | st-flash
      st-util | Print list of available commands. | | diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index e870e116c..356515ac4 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -26,8 +26,8 @@ static void cleanup(int signum) { } static void usage(void) { - puts("command line: ./st-flash [--debug] [--reset] [--connect-under-reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); - puts("command line: ./st-flash [--debug] [--connect-under-reset] [--freq=] [--serial ] erase"); + puts("command line: ./st-flash [--debug] [--reset] [--connect-under-reset] [--hot-plug] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); + puts("command line: ./st-flash [--debug] [--connect-under-reset] [--hot-plug] [--freq=] [--serial ] erase"); puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); puts(" , and : Use hex format."); puts(" : Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 63774ea25..172a24468 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -193,6 +193,8 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } } else if (strcmp(av[0], "--connect-under-reset") == 0) { o->connect = CONNECT_UNDER_RESET; + } else if (strcmp(av[0], "--hot-plug") == 0) { + o->connect = CONNECT_HOT_PLUG; } else { break; // non-option found From 696ea923ce7517a604d43adfe017c1cdda3b7339 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 5 Apr 2021 21:23:16 +0500 Subject: [PATCH 1158/1435] Changed the behavior of the st-flash reset option. The reset option conflicted with the connection type options (connect under reset, hot plug). Now reset of target is performed only after the completion of the firmware if the reset options is used. --- src/st-flash/flash.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 356515ac4..edb54e195 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -98,20 +98,6 @@ int main(int ac, char** av) { } } - if (o.reset) { - if (sl->version.stlink_v > 1) { - if (stlink_jtag_reset(sl, 2)) { - printf("Failed to reset JTAG\n"); - goto on_error; - } - } - - if (stlink_reset(sl)) { - printf("Failed to reset device\n"); - goto on_error; - } - } - // core must be halted to use RAM based flashloaders if (stlink_force_debug(sl)) { printf("Failed to halt the core\n"); From d3bc853209a6785a1f87a2359839e80c15735563 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 5 Apr 2021 21:53:57 +0500 Subject: [PATCH 1159/1435] Update tutorial --- doc/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 256513bc4..21f1498ee 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -7,7 +7,7 @@ | --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k for the STM32F103C8T6
      to assume 128k of flash being present. This option accepts decimal (128k), octal 0200k, or hex 0x80k values.
      Leaving the multiplier out is equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional
      "k" or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | | --freq=n[k][m] | st-info
      st-flash
      st-util | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
      This option solely accepts decimal values (5K or 1.8M) with the unit `Hz` being left out. Valid frequencies are:
      `5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K, 1800K, 4000K(4M)`. | v1.6.1 | | --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
      This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | -| --reset | st-flash | Trigger a reset both before and after flashing. The default uses the hardware reset through `NRST` pin.
      A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | +| --reset | st-flash | Trigger a reset after flashing. The default uses the hardware reset through `NRST` pin.
      A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | | --connect-under-reset | st-info
      st-flash | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
      when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | | --hot-plug | st-info
      st-flash
      st-util | Connect to the target without reset. | v1.6.2 | | --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | From 4fc6344d44681a0add3bdce69ecf2d0e4e70db49 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 5 Apr 2021 22:13:17 +0500 Subject: [PATCH 1160/1435] flash_loader: fixed alignment of size of the lx loader --- src/stlink-lib/flash_loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 80262cf07..cd7096490 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -68,7 +68,7 @@ static const uint8_t loader_code_stm32lx[] = { 0x00, 0xf1, 0x04, 0x00, 0x01, 0xf1, 0x04, 0x01, 0x04, 0x3a, 0xf7, 0xdc, - 0x00, 0xbe + 0x00, 0xbe, 0x00, 0x00 }; static const uint8_t loader_code_stm32f4[] = { From 5ce54824a5ca819a7ff630b880268febb07ff3e3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 5 Apr 2021 21:55:54 +0200 Subject: [PATCH 1161/1435] Updated CI & MinGW64 cross build configuration - Moved config for macOS 10.14 to GitHub Actions (Note: preparation only, yet inactive) - Removed macOS 10.14 builds from Travis CI - Removed Linux build config from Travis CI - Split 32- & 64-bit cross builds to separate jobs - Minor fixes for MinGW64 cross build config --- .github/workflows/c-cpp.yml | 90 ++++++++++++++++++++ .travis.sh | 22 ++--- .travis.yml | 79 ++--------------- cmake/modules/Findlibusb.cmake | 18 ++-- cmake/modules/c_flags.cmake | 2 +- cmake/packaging/windows/generate_binaries.sh | 18 ++-- 6 files changed, 123 insertions(+), 106 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 4769450ae..97f48d88d 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -282,6 +282,96 @@ jobs: # macOS + # job_macos_10_14_64_gcc: + # name: macos-10.14 gcc + # runs-on: macos-10.14 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: brew install gcc libusb gtk+3 + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean + + # job_macos_10_14_32_gcc: + # name: macos-10.14 gcc 32-bit + # runs-on: macos-10.14 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: brew install gcc libusb gtk+3 + # - name: Set compiler flags + # run: | + # CFLAGS="$CFLAGS -m32" + # CXXFLAGS="$CXXFLAGS -m32" + # LDFLAGS="$LDFLAGS -m32" + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean + + # job_macos_10_14_64_clang: + # name: macos-10.14 clang + # runs-on: macos-10.14 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: brew install llvm libusb gtk+3 + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean + + # job_macos_10_14_32_clang: + # name: macos-10.14 clang 32-bit + # runs-on: macos-10.14 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: brew install llvm libusb gtk+3 + # - name: Set compiler flags + # run: | + # CFLAGS="$CFLAGS -m32" + # CXXFLAGS="$CXXFLAGS -m32" + # LDFLAGS="$LDFLAGS -m32" + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean + job_macos_10_15_gcc: name: macos-10.15 gcc runs-on: macos-10.15 diff --git a/.travis.sh b/.travis.sh index de2a42372..e45cd3609 100755 --- a/.travis.sh +++ b/.travis.sh @@ -8,18 +8,19 @@ echo "----" echo "WORK DIR:$DIR" DIR=$PWD -if [ "$TRAVIS_JOB_NAME" == "linux-mingw" ]; then +if [ "$TRAVIS_JOB_NAME" == "linux-mingw-64" ]; then echo "--> Building for Windows (x86-64) ..." - mkdir -p build-mingw && cd build-mingw + mkdir -p build-mingw && cd build-mingw-64 cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && rm -rf build-mingw && cd - + make && rm -rf build-mingw-64 && cd - +elif [ "$TRAVIS_JOB_NAME" == "linux-mingw-32" ]; then echo "--> Building for Windows (i686) ..." - mkdir -p build-mingw && cd build-mingw + mkdir -p build-mingw && cd build-mingw-32 cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && rm -rf build-mingw && cd - + make && rm -rf build-mingw-32 && cd - elif [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq || true @@ -34,17 +35,6 @@ elif [ "$TRAVIS_OS_NAME" == "linux" ]; then cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make package && cd - -elif [ "$TRAVIS_OS_NAME" == "osx" ]; then - echo "--> Building Debug..." - mkdir -p build/Debug && cd build/Debug - cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && cd - - - echo "--> Building Release with package..." - mkdir -p build/Release && cd build/Release - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make package && cd - - else # local test-build echo "--> Building Debug..." mkdir -p build/Debug && cd build/Debug diff --git a/.travis.yml b/.travis.yml index 2a788fd69..a733019a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,32 +2,22 @@ language: c jobs: include: - ### 64-bit build on AMD64 ### - - os: linux - dist: focal - env: BADGE=linux - compiler: gcc-10 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + ### cross builds on AMD64 ### - ### 32-bit build on AMD64 ### - os: linux dist: focal - env: BADGE=linux + env: BADGE=linux-mingw-64 + name: linux-mingw compiler: gcc-10 addons: apt: sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + packages: + ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] - ### cross build on AMD64 ### - os: linux dist: focal - env: BADGE=linux-mingw + env: BADGE=linux-mingw-32 name: linux-mingw compiler: gcc-10 addons: @@ -35,64 +25,9 @@ jobs: sources: ["ubuntu-toolchain-r-test"] packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] - before_install: - - LDFLAGS="$LDFLAGS -NDEBUG"; - - ### macOS ### - # - os: osx - # env: BADGE=osx - # osx_image: xcode11.3 - # name: macOS 10.14.6 gcc - # compiler: gcc - # addons: - # homebrew: - # packages: - # - gcc - # - libusb - # - gtk+3 - - # - os: osx - # env: BADGE=osx - # osx_image: xcode11.3 - # name: macOS 10.14.6 gcc 32-bit - # compiler: gcc - # addons: - # homebrew: - # packages: - # - gcc - # - libusb - # - gtk+3 - # before_install: - # - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - # - os: osx - # env: BADGE=osx - # osx_image: xcode11.3 - # name: macOS 10.14.6 clang - # compiler: clang - # addons: - # homebrew: - # packages: - # - llvm - # - libusb - # - gtk+3 - - # - os: osx - # env: BADGE=osx - # osx_image: xcode11.3 - # name: macOS 10.14.6 clang 32-bit - # compiler: clang - # addons: - # homebrew: - # packages: - # - llvm - # - libusb - # - gtk+3 - # before_install: - # - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; script: - git fetch --tags - printenv - cmake --version - - if [[ "$TRAVIS_OS_NAME" == "linux" ]] || [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis.sh; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./.travis.sh; fi diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index 3082a9509..257c682ce 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -10,7 +10,7 @@ include(FindPackageHandleStandardArgs) -if (APPLE) # macOS +if (APPLE) # macOS FIND_PATH( LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr /usr/local /opt @@ -27,7 +27,7 @@ if (APPLE) message(FATAL_ERROR "No libusb library found on your system! Install libusb-1.0 from Homebrew or MacPorts") endif () -elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated into the system +elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated into the system FIND_PATH( LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr/include @@ -43,13 +43,13 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") message(FATAL_ERROR "Expected libusb library not found on your system! Verify your system integrity.") endif () -elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-toolchain on Debian - # for MinGW/MSYS/MSVC: 64-bit or 32-bit? +elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-toolchain on Debian + # MinGW/MSYS/MSVC: 64-bit or 32-bit? if (CMAKE_SIZEOF_VOID_P EQUAL 8) message(STATUS "=== Building for Windows (x86-64) ===") set(ARCH 64) else () - message(STATUS "=== Building for Windowsm (i686) ===") + message(STATUS "=== Building for Windows (i686) ===") set(ARCH 32) endif () @@ -77,14 +77,14 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) if (NOT LIBUSB_FOUND) # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3rdparty/libusb-${LIBUSB_WIN_VERSION}) - else (EXISTS "/etc/debian_version" AND MINGW) # ... only for cross-building on Debian - set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_SOURCE_DIR}/build-mingw/${LIBUSB_WIN_ARCHIVE}) - set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_SOURCE_DIR}/build-mingw/3rdparty/libusb-${LIBUSB_WIN_VERSION}) + else (EXISTS "/etc/debian_version" AND MINGW) # ... only for cross-building on Debian + set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_SOURCE_DIR}/build-mingw-${ARCH}/${LIBUSB_WIN_ARCHIVE}) + set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_SOURCE_DIR}/build-mingw-${ARCH}/3rdparty/libusb-${LIBUSB_WIN_VERSION}) endif () # Get libusb package diff --git a/cmake/modules/c_flags.cmake b/cmake/modules/c_flags.cmake index 8291ea0ee..5ed0c4d7d 100644 --- a/cmake/modules/c_flags.cmake +++ b/cmake/modules/c_flags.cmake @@ -41,7 +41,7 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") add_cflag_if_supported("-Wredundant-decls") endif () -if (NOT WIN32) +if (NOT (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW))) add_cflag_if_supported("-fPIC") endif () diff --git a/cmake/packaging/windows/generate_binaries.sh b/cmake/packaging/windows/generate_binaries.sh index d38f8d62f..bf2453d10 100644 --- a/cmake/packaging/windows/generate_binaries.sh +++ b/cmake/packaging/windows/generate_binaries.sh @@ -6,23 +6,25 @@ #sudo apt-get install mingw-w64 # x86_64 -mkdir build-mingw -cd build-mingw +mkdir build-mingw-64 +cd build-mingw-64 cmake -DCMAKE_SYSTEM_NAME=Windows \ -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=./cmake/modules/set_toolchain.cmake .. + -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. make package cp dist/*.zip ../build/Release/dist +make clean cd .. -rm -rf build-mingw +rm -rf build-mingw-64 # i686 -mkdir build-mingw -cd build-mingw +mkdir build-mingw-32 +cd build-mingw-32 cmake -DCMAKE_SYSTEM_NAME=Windows \ -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=./cmake/modules/set_toolchain.cmake .. + -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. make package cp dist/*.zip ../build/Release/dist +make clean cd .. -rm -rf build-mingw +rm -rf build-mingw-32 From 89a495d169a15f42d8cfd1a68c6738c984d052f8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 6 Apr 2021 00:46:44 +0200 Subject: [PATCH 1162/1435] Updated libusb to v1.0.24 Note: Due to a compilation bug in libusb v1.0.24, building of x86-64 windows binaries is currently not possible and has been deactivated. --- .gitignore | 1 + .travis.sh | 18 +++++++-------- .travis.yml | 24 ++++++++++---------- cmake/modules/Findlibusb.cmake | 6 ++--- cmake/packaging/windows/generate_binaries.sh | 24 ++++++++++---------- 5 files changed, 37 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index a07eed9ca..82c1195e4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ build build-mingw +build-mingw-* .project .cmake/ diff --git a/.travis.sh b/.travis.sh index e45cd3609..58cea5746 100755 --- a/.travis.sh +++ b/.travis.sh @@ -8,20 +8,20 @@ echo "----" echo "WORK DIR:$DIR" DIR=$PWD -if [ "$TRAVIS_JOB_NAME" == "linux-mingw-64" ]; then - echo "--> Building for Windows (x86-64) ..." - mkdir -p build-mingw && cd build-mingw-64 - cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && rm -rf build-mingw-64 && cd - - -elif [ "$TRAVIS_JOB_NAME" == "linux-mingw-32" ]; then +if [ "$TRAVIS_JOB_NAME" == "linux-mingw-32" ]; then echo "--> Building for Windows (i686) ..." - mkdir -p build-mingw && cd build-mingw-32 + mkdir -p build-mingw-32 && cd build-mingw-32 cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && rm -rf build-mingw-32 && cd - +# elif [ "$TRAVIS_JOB_NAME" == "linux-mingw-64" ]; then +# echo "--> Building for Windows (x86-64) ..." +# mkdir -p build-mingw-64 && cd build-mingw-64 +# cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ +# -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR +# make && rm -rf build-mingw-64 && cd - + elif [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq || true diff --git a/.travis.yml b/.travis.yml index a733019a1..307c0bfa0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,21 +4,10 @@ jobs: include: ### cross builds on AMD64 ### - - os: linux - dist: focal - env: BADGE=linux-mingw-64 - name: linux-mingw - compiler: gcc-10 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: - ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] - - os: linux dist: focal env: BADGE=linux-mingw-32 - name: linux-mingw + name: linux-mingw-32 compiler: gcc-10 addons: apt: @@ -26,6 +15,17 @@ jobs: packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] + # - os: linux + # dist: focal + # env: BADGE=linux-mingw-64 + # name: linux-mingw-64 + # compiler: gcc-10 + # addons: + # apt: + # sources: ["ubuntu-toolchain-r-test"] + # packages: + # ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] + script: - git fetch --tags - printenv diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index 257c682ce..99f4d56ec 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -77,7 +77,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to if (NOT LIBUSB_FOUND) # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.24) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) @@ -94,7 +94,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download - ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 + ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 5c944b1c8aa9d43e026a94302d0f8ac4 ) endif () @@ -128,7 +128,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to set(LIBUSB_NAME libusb-1.0.lib) find_library( LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS${ARCH}/dll + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/**/MS${ARCH}/dll NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) diff --git a/cmake/packaging/windows/generate_binaries.sh b/cmake/packaging/windows/generate_binaries.sh index bf2453d10..5616ecb38 100644 --- a/cmake/packaging/windows/generate_binaries.sh +++ b/cmake/packaging/windows/generate_binaries.sh @@ -5,18 +5,6 @@ # Install this cross-compiler toolchain: #sudo apt-get install mingw-w64 -# x86_64 -mkdir build-mingw-64 -cd build-mingw-64 -cmake -DCMAKE_SYSTEM_NAME=Windows \ - -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. -make package -cp dist/*.zip ../build/Release/dist -make clean -cd .. -rm -rf build-mingw-64 - # i686 mkdir build-mingw-32 cd build-mingw-32 @@ -28,3 +16,15 @@ cp dist/*.zip ../build/Release/dist make clean cd .. rm -rf build-mingw-32 + +# x86_64 +# mkdir build-mingw-64 +# cd build-mingw-64 +# cmake -DCMAKE_SYSTEM_NAME=Windows \ +# -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ +# -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. +# make package +# cp dist/*.zip ../build/Release/dist +# make clean +# cd .. +# rm -rf build-mingw-64 From ee43e3b3571c8c7d253b158bbab2d330b3ef19cb Mon Sep 17 00:00:00 2001 From: anton Date: Tue, 6 Apr 2021 21:13:54 +0500 Subject: [PATCH 1163/1435] Unification of the reset function --- inc/stlink.h | 24 +++++++++-- src/common.c | 91 +++++++++++++++++++++++++++++++++++++-- src/st-flash/flash.c | 13 +----- src/st-trace/trace.c | 2 +- src/st-util/gdb-server.c | 92 +++++++++++++--------------------------- src/stlink-lib/sg.c | 2 +- src/stlink-lib/usb.c | 51 +--------------------- src/stlink-lib/usb.h | 6 --- tests/sg.c | 2 +- tests/usb.c | 2 +- 10 files changed, 145 insertions(+), 140 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 855e5126d..8fe6033d6 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -58,6 +58,11 @@ enum target_state { #define STLINK_JTAG_READDEBUG_32BIT 0x36 #define STLINK_JTAG_DRIVE_NRST 0x3C +/* NRST pin states */ +#define STLINK_JTAG_DRIVE_NRST_LOW 0x00 +#define STLINK_JTAG_DRIVE_NRST_HIGH 0x01 +#define STLINK_JTAG_DRIVE_NRST_PULSE 0x02 + #define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43 #define STLINK_APIV3_SET_COM_FREQ 0x61 @@ -173,6 +178,19 @@ enum transport_type { TRANSPORT_TYPE_INVALID }; +enum connect_type { + CONNECT_HOT_PLUG = 0, + CONNECT_NORMAL = 1, + CONNECT_UNDER_RESET = 2, +}; + +enum reset_type { + RESET_AUTO = 0, + RESET_HARD = 1, + RESET_SOFT = 2, + RESET_SOFT_AND_HALT = 3, +}; + typedef struct _stlink stlink_t; #include @@ -231,9 +249,7 @@ int stlink_exit_debug_mode(stlink_t *sl); int stlink_exit_dfu_mode(stlink_t *sl); void stlink_close(stlink_t *sl); int stlink_core_id(stlink_t *sl); -int stlink_reset(stlink_t *sl); -int stlink_jtag_reset(stlink_t *sl, int value); -int stlink_soft_reset(stlink_t *sl, int halt_on_reset); +int stlink_reset(stlink_t *sl, enum reset_type type); int stlink_run(stlink_t *sl); int stlink_status(stlink_t *sl); int stlink_version(stlink_t *sl); @@ -301,6 +317,8 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len); int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl); +int stlink_target_connect(stlink_t *sl, enum connect_type connect); + #include #include #include diff --git a/src/common.c b/src/common.c index 60d7ff145..928091eb4 100644 --- a/src/common.c +++ b/src/common.c @@ -1663,10 +1663,6 @@ int stlink_load_device_params(stlink_t *sl) { return(0); } -int stlink_reset(stlink_t *sl) { - DLOG("*** stlink_reset ***\n"); - return(sl->backend->reset(sl)); -} int stlink_jtag_reset(stlink_t *sl, int value) { DLOG("*** stlink_jtag_reset ***\n"); @@ -1742,6 +1738,59 @@ int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { return(0); } +int stlink_reset(stlink_t *sl, enum reset_type type) { + uint32_t dhcsr; + unsigned timeout; + + DLOG("*** stlink_reset ***\n"); + + if (type == RESET_AUTO) { + // clear S_RESET_ST in DHCSR register for reset state detection + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + } + + if (type == RESET_HARD || type == RESET_AUTO) { + // hardware target reset + if (sl->version.stlink_v > 1) { stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_PULSE); } + if (sl->backend->reset(sl)) { return(-1); } + usleep(10000); + } + + if (type == RESET_AUTO) { + /* Check if the S_RESET_ST bit is set in DHCSR + * This means that a reset has occurred + * DDI0337E, p. 10-4, Debug Halting Control and Status Register */ + + dhcsr = 0; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + // reset not done yet + // try reset through AIRCR so that NRST does not need to be connected + + WLOG("NRST is not connected\n"); + DLOG("Using reset through SYSRESETREQ\n"); + return stlink_soft_reset(sl, 0); + } + + // waiting for reset the S_RESET_ST bit within 500ms + timeout = time_ms() + 500; + while (time_ms() < timeout) { + dhcsr = STLINK_REG_DHCSR_S_RESET_ST; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) + return(0); + } + + return(-1); + } + + if (type == RESET_SOFT || type == RESET_SOFT_AND_HALT) { + return stlink_soft_reset(sl, (type==RESET_SOFT_AND_HALT)); + } + + return(0); +} + int stlink_run(stlink_t *sl) { struct stlink_reg rr; DLOG("*** stlink_run ***\n"); @@ -4467,3 +4516,37 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr return(err); } +int stlink_target_connect(stlink_t *sl, enum connect_type connect) { + uint32_t dhcsr; + + if (connect == CONNECT_UNDER_RESET) { + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); + + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } + stlink_force_debug(sl); + + // clear S_RESET_ST in DHCSR register + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); + usleep(10000); + + // check NRST connection + dhcsr = 0; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + WLOG("NRST is not connected\n"); + } + + // addition soft reset for halt before the first instruction + stlink_soft_reset(sl, 1 /* halt on reset */); + } + + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } + + if (connect == CONNECT_NORMAL) { + stlink_reset(sl, RESET_AUTO); + } + + return stlink_load_device_params(sl); +} diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index edb54e195..5eb607758 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -188,14 +188,7 @@ int main(int ac, char** av) { goto on_error; } } else if (o.cmd == CMD_RESET) { - if (sl->version.stlink_v > 1) { - if (stlink_jtag_reset(sl, 2)) { - printf("Failed to reset JTAG\n"); - goto on_error; - } - } - - if (stlink_reset(sl)) { + if (stlink_reset(sl, RESET_AUTO)) { printf("Failed to reset device\n"); goto on_error; } @@ -263,9 +256,7 @@ int main(int ac, char** av) { } if (o.reset) { - if (sl->version.stlink_v > 1) { stlink_jtag_reset(sl, 2); } - - stlink_reset(sl); + stlink_reset(sl, RESET_AUTO); } err = 0; // success diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 3180335a0..f40a9d683 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -203,7 +203,7 @@ static bool enable_trace(stlink_t* stlink, const st_settings_t* settings, uint32 return false; } - if (settings->reset_board && stlink_jtag_reset(stlink, 2)) { + if (settings->reset_board && stlink_reset(stlink, RESET_AUTO)) { ELOG("Unable to reset device\n"); if (!settings->force) return false; diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 8d63d9ee0..c2a220df3 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -42,9 +42,6 @@ #define FLASH_PAGE (sl->flash_pgsz) static stlink_t *connected_stlink = NULL; -static bool semihosting = false; -static bool serial_specified = false; -static char serialnumber[STLINK_SERIAL_BUFFER_SIZE] = {0}; #if defined(_WIN32) #define close_socket win32_close_socket @@ -57,8 +54,6 @@ static char serialnumber[STLINK_SERIAL_BUFFER_SIZE] = {0}; static const char hex[] = "0123456789abcdef"; -static const char* current_memory_map = NULL; - typedef struct _st_state_t { // things from command line, bleh int logging_level; @@ -66,6 +61,9 @@ typedef struct _st_state_t { int persistent; enum connect_type connect_mode; int freq; + char serialnumber[STLINK_SERIAL_BUFFER_SIZE]; + bool semihosting; + const char* current_memory_map; } st_state_t; @@ -97,20 +95,6 @@ BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { } #endif - -static stlink_t* do_connect(st_state_t *st) { - stlink_t *sl = NULL; - - if (serial_specified) { - sl = stlink_open_usb(st->logging_level, st->connect_mode, serialnumber, st->freq); - } else { - sl = stlink_open_usb(st->logging_level, st->connect_mode, NULL, st->freq); - } - - return(sl); -} - - int parse_options(int argc, char** argv, st_state_t *st) { static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, @@ -119,6 +103,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { {"multi", optional_argument, NULL, 'm'}, {"no-reset", optional_argument, NULL, 'n'}, {"hot-plug", optional_argument, NULL, 'n'}, + {"connect-under-reset", optional_argument, NULL, 'u'}, {"freq", optional_argument, NULL, 'F'}, {"version", no_argument, NULL, 'V'}, {"semihosting", no_argument, NULL, SEMIHOSTING_OPTION}, @@ -138,6 +123,8 @@ int parse_options(int argc, char** argv, st_state_t *st) { "\t\t\tst-util will continue listening for connections after disconnect.\n" " -n, --no-reset, --hot-plug\n" "\t\t\tDo not reset board on connection.\n" + " -u, --connect-under-reset\n" + "\t\t\tConnect to the board before executing any instructions.\n" " -F 1800K, --freq=1M\n" "\t\t\tSet the frequency of the SWD/JTAG interface.\n" " --semihosting\n" @@ -182,11 +169,14 @@ int parse_options(int argc, char** argv, st_state_t *st) { break; case 'm': - st->persistent = 1; + st->persistent = true; break; case 'n': st->connect_mode = CONNECT_HOT_PLUG; break; + case 'u': + st->connect_mode = CONNECT_UNDER_RESET; + break; case 'F': st->freq = arg_parse_freq(optarg); if (st->freq < 0) { @@ -198,12 +188,11 @@ int parse_options(int argc, char** argv, st_state_t *st) { printf("v%s\n", STLINK_VERSION); exit(EXIT_SUCCESS); case SEMIHOSTING_OPTION: - semihosting = true; + st->semihosting = true; break; case SERIAL_OPTION: printf("use serial %s\n", optarg); - memcpy(serialnumber, optarg, STLINK_SERIAL_BUFFER_SIZE); - serial_specified = true; + memcpy(st->serialnumber, optarg, STLINK_SERIAL_BUFFER_SIZE); break; } @@ -232,8 +221,7 @@ int main(int argc, char** argv) { printf("st-util\n"); - sl = do_connect(&state); - + sl = stlink_open_usb(state.logging_level, state.connect_mode, state.serialnumber, state.freq); if (sl == NULL) { return(1); } if (sl->chip_id == STLINK_CHIPID_UNKNOWN) { @@ -241,7 +229,9 @@ int main(int argc, char** argv) { return(1); } + sl->verbose = 0; connected_stlink = sl; + #if defined(_WIN32) SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE); #else @@ -250,18 +240,14 @@ int main(int argc, char** argv) { signal(SIGSEGV, &cleanup); #endif - if (state.connect_mode != CONNECT_HOT_PLUG) { stlink_reset(sl); } - DLOG("Chip ID is %#010x, Core ID is %#08x.\n", sl->chip_id, sl->core_id); - sl->verbose = 0; - current_memory_map = make_memory_map(sl); + state.current_memory_map = make_memory_map(sl); #if defined(_WIN32) WSADATA wsadata; if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) { goto winsock_error; } - #endif init_cache(sl); @@ -865,16 +851,13 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { return(0); } -static int flash_go(stlink_t *sl) { +static int flash_go(stlink_t *sl, st_state_t *st) { int error = -1; int ret; flash_loader_t fl; - // some kinds of clock settings do not allow writing to flash. - stlink_reset(sl); + stlink_target_connect(sl, st->connect_mode); stlink_force_debug(sl); - // delay to ensure that STM32 HSI clock and others have started up fully - usleep(10000); for (struct flash_block* fb = flash_root; fb; fb = fb->next) { ILOG("flash_erase: block %08x -> %04x\n", fb->addr, fb->length); @@ -909,7 +892,7 @@ static int flash_go(stlink_t *sl) { } stlink_flashloader_stop(sl, &fl); - stlink_soft_reset(sl, 1 /* halt on reset */); + stlink_reset(sl, RESET_SOFT_AND_HALT); error = 0; error: @@ -1119,10 +1102,9 @@ int serve(stlink_t *sl, st_state_t *st) { close_socket(sock); + stlink_target_connect(sl, st->connect_mode); stlink_force_debug(sl); - if (st->connect_mode != CONNECT_HOT_PLUG) { stlink_reset(sl); } - init_code_breakpoints(sl); init_data_watchpoints(sl); @@ -1198,7 +1180,7 @@ int serve(stlink_t *sl, st_state_t *st) { if (strcmp(op, "read")) { data = NULL; } else if (!strcmp(type, "memory-map")) { - data = current_memory_map; + data = st->current_memory_map; } else if (!strcmp(type, "features")) { data = target_description; } else { @@ -1269,22 +1251,14 @@ int serve(stlink_t *sl, st_state_t *st) { } else if (!strncmp(cmd, "jtag_reset", 10)) { // jtag_reset reply = strdup("OK"); - ret = stlink_jtag_reset(sl, 0); - - if (ret) { - DLOG("Rcmd: jtag_reset failed with jtag_reset\n"); - reply = strdup("E00"); - } - - ret = stlink_jtag_reset(sl, 1); + ret = stlink_reset(sl, RESET_HARD); if (ret) { DLOG("Rcmd: jtag_reset failed with jtag_reset\n"); reply = strdup("E00"); } ret = stlink_force_debug(sl); - if (ret) { DLOG("Rcmd: jtag_reset failed with force_debug\n"); reply = strdup("E00"); @@ -1297,14 +1271,12 @@ int serve(stlink_t *sl, st_state_t *st) { } else if (!strncmp(cmd, "reset", 5)) { // reset ret = stlink_force_debug(sl); - if (ret) { DLOG("Rcmd: reset failed with force_debug\n"); reply = strdup("E00"); } - ret = stlink_reset(sl); - + ret = stlink_reset(sl, RESET_AUTO); if (ret) { DLOG("Rcmd: reset failed with reset\n"); reply = strdup("E00"); @@ -1325,10 +1297,10 @@ int serve(stlink_t *sl, st_state_t *st) { while (isspace(*arg)) { arg++; } // skip whitespaces if (!strncmp(arg, "enable", 6) || !strncmp(arg, "1", 1)) { - semihosting = true; + st->semihosting = true; reply = strdup("OK"); } else if (!strncmp(arg, "disable", 7) || !strncmp(arg, "0", 1)) { - semihosting = false; + st->semihosting = false; reply = strdup("OK"); } else { DLOG("Rcmd: unknown semihosting arg: '%s'\n", arg); @@ -1407,7 +1379,7 @@ int serve(stlink_t *sl, st_state_t *st) { free(decoded); } else if (!strcmp(cmdName, "FlashDone")) { - if (flash_go(sl)) { + if (flash_go(sl, st)) { reply = strdup("E08"); } else { reply = strdup("OK"); @@ -1453,7 +1425,7 @@ int serve(stlink_t *sl, st_state_t *st) { int offset = 0; uint16_t insn; - if (!semihosting) { break; } + if (!st->semihosting) { break; } ret = stlink_read_all_regs (sl, ®); @@ -1821,7 +1793,7 @@ int serve(stlink_t *sl, st_state_t *st) { case 'R': { // reset the core. - ret = stlink_reset(sl); + ret = stlink_reset(sl, RESET_AUTO); if (ret) { DLOG("R packet : stlink_reset failed\n"); } init_code_breakpoints(sl); @@ -1835,25 +1807,19 @@ int serve(stlink_t *sl, st_state_t *st) { case 'k': // kill request - reset the connection itself ret = stlink_run(sl); - if (ret) { DLOG("Kill: stlink_run failed\n"); } ret = stlink_exit_debug_mode(sl); - if (ret) { DLOG("Kill: stlink_exit_debug_mode failed\n"); } stlink_close(sl); - sl = do_connect(st); - + sl = stlink_open_usb(st->logging_level, st->connect_mode, st->serialnumber, st->freq); if (sl == NULL || sl->chip_id == STLINK_CHIPID_UNKNOWN) { cleanup(0); } connected_stlink = sl; - if (st->connect_mode != CONNECT_HOT_PLUG) { stlink_reset(sl); } - ret = stlink_force_debug(sl); - if (ret) { DLOG("Kill: stlink_force_debug failed\n"); } init_cache(sl); diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index 840466e75..c5946ed19 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -1114,7 +1114,7 @@ stlink_t* stlink_v1_open(const int verbose, int reset) { stlink_enter_swd_mode(sl); // now we are ready to read the parameters - if (reset) { stlink_reset(sl); } + if (reset) { stlink_reset(sl, RESET_AUTO); } stlink_load_device_params(sl); ILOG("Successfully opened a stlink v1 debugger\n"); diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index ce0d672c8..99b5f51ef 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -512,13 +512,8 @@ int _stlink_usb_reset(stlink_t * sl) { unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; - uint32_t dhcsr; - unsigned timeout; int i, rep_len = 2; - // clear S_RESET_ST in DHCSR registr - _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - // send reset command i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; @@ -536,30 +531,7 @@ int _stlink_usb_reset(stlink_t * sl) { return((int)size); } - usleep(10000); - - dhcsr = 0; - _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { - // reset not done yet - // try reset through AIRCR so that NRST does not need to be connected - - WLOG("NRST is not connected\n"); - DLOG("Using reset through SYSRESETREQ\n"); - return stlink_soft_reset(sl, 0); - } - - // waiting for a reset within 500ms - timeout = time_ms() + 500; - while (time_ms() < timeout) { - // DDI0337E, p. 10-4, Debug Halting Control and Status Register - dhcsr = STLINK_REG_DHCSR_S_RESET_ST; - _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) - return(0); - } - - return(-1); + return(0); } int _stlink_usb_jtag_reset(stlink_t * sl, int value) { @@ -1382,26 +1354,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, DLOG("JTAG/SWD freq set to %d\n", freq); stlink_set_swdclk(sl, freq); - if (connect == CONNECT_UNDER_RESET) { - stlink_jtag_reset(sl, 0); - - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } - - stlink_force_debug(sl); - stlink_jtag_reset(sl, 1); - usleep(10000); - } - - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } - - if (connect == CONNECT_NORMAL) { - if ( sl->version.stlink_v > 1) { stlink_jtag_reset(sl, 2); } - - stlink_reset(sl); - usleep(10000); - } - - stlink_load_device_params(sl); + stlink_target_connect(sl, connect); return(sl); on_libusb_error: diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index f48ef225d..27de32700 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -48,12 +48,6 @@ extern "C" { #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 -enum connect_type { - CONNECT_HOT_PLUG = 0, - CONNECT_NORMAL = 1, - CONNECT_UNDER_RESET = 2, -}; - struct stlink_libusb { libusb_context* libusb_ctx; libusb_device_handle* usb_handle; diff --git a/tests/sg.c b/tests/sg.c index 745df845f..7584ab5d4 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -46,7 +46,7 @@ int main(void) { // main() ripped out of old stlink-hw.c stlink_core_id(sl); stlink_status(sl); // stlink_force_debug(sl); - stlink_reset(sl); + stlink_reset(sl, RESET_AUTO); stlink_status(sl); // core system control block stlink_read_mem32(sl, 0xe000ed00, 4); diff --git a/tests/usb.c b/tests/usb.c index 03c135f00..5c5c2077d 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -93,7 +93,7 @@ int main(int ac, char** av) { stlink_status(sl); printf("-- reset\n"); - stlink_reset(sl); + stlink_reset(sl, RESET_AUTO); stlink_force_debug(sl); /* Test reg write */ stlink_write_reg(sl, 0x01234567, 3); From 6bd99d4b55cd33c7f3773eda8aadea10e1288b5e Mon Sep 17 00:00:00 2001 From: anton Date: Tue, 6 Apr 2021 22:03:52 +0500 Subject: [PATCH 1164/1435] flash_loader: fixed interrupt masking --- doc/dev/developer.txt | 7 ++++--- doc/tutorial.md | 2 +- inc/backend.h | 2 +- inc/stlink.h | 8 +++++++- src/common.c | 8 ++++---- src/st-flash/flash.c | 2 +- src/st-trace/trace.c | 2 +- src/st-util/gdb-server.c | 16 ++++++++-------- src/stlink-lib/flash_loader.c | 2 +- src/stlink-lib/sg.c | 3 ++- src/stlink-lib/usb.c | 7 +++++-- tests/sg.c | 4 ++-- tests/usb.c | 2 +- 13 files changed, 38 insertions(+), 27 deletions(-) diff --git a/doc/dev/developer.txt b/doc/dev/developer.txt index 9c4da22f7..e3091c003 100644 --- a/doc/dev/developer.txt +++ b/doc/dev/developer.txt @@ -244,18 +244,19 @@ Description: Backend: "jtag_reset" Arguments: sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() - value: 0: drive low, 1: drive high, 2: ???? + value: 0: drive low, 1: drive high, 2: pulse Return: -1 for error. 0 for success. Include: inc/stlink.h -Prototype: int stlink_run(stlink_t *sl); +Prototype: int stlink_run(stlink_t *sl, enum run_type type); Definition: src/common.c Description: Just calls the backend "run" procedure. Backend: "run" Arguments: - sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() + sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() + type: RUN_NORMAL - run target, RUN_FLASH_LOADER - run target with masking interrupts Return: -1 for error. 0 for success. Include: inc/stlink.h diff --git a/doc/tutorial.md b/doc/tutorial.md index 21f1498ee..71af3d45e 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -8,7 +8,7 @@ | --freq=n[k][m] | st-info
      st-flash
      st-util | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
      This option solely accepts decimal values (5K or 1.8M) with the unit `Hz` being left out. Valid frequencies are:
      `5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K, 1800K, 4000K(4M)`. | v1.6.1 | | --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
      This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | | --reset | st-flash | Trigger a reset after flashing. The default uses the hardware reset through `NRST` pin.
      A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | -| --connect-under-reset | st-info
      st-flash | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
      when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | +| --connect-under-reset | st-info
      st-flash
      st-util | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
      when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | | --hot-plug | st-info
      st-flash
      st-util | Connect to the target without reset. | v1.6.2 | | --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | | --version | st-info
      st-flash
      st-util | Print version information. | v1.3.0 | diff --git a/inc/backend.h b/inc/backend.h index ebd438127..a45dccd82 100644 --- a/inc/backend.h +++ b/inc/backend.h @@ -10,7 +10,7 @@ int (*core_id) (stlink_t * stl); int (*reset) (stlink_t * stl); int (*jtag_reset) (stlink_t * stl, int value); - int (*run) (stlink_t * stl); + int (*run) (stlink_t * stl, enum run_type type); int (*status) (stlink_t * stl); int (*version) (stlink_t *sl); int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); diff --git a/inc/stlink.h b/inc/stlink.h index 8fe6033d6..ec119c145 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -191,6 +191,12 @@ enum reset_type { RESET_SOFT_AND_HALT = 3, }; +enum run_type { + RUN_NORMAL = 0, + RUN_FLASH_LOADER = 1, +}; + + typedef struct _stlink stlink_t; #include @@ -250,7 +256,7 @@ int stlink_exit_dfu_mode(stlink_t *sl); void stlink_close(stlink_t *sl); int stlink_core_id(stlink_t *sl); int stlink_reset(stlink_t *sl, enum reset_type type); -int stlink_run(stlink_t *sl); +int stlink_run(stlink_t *sl, enum run_type type); int stlink_status(stlink_t *sl); int stlink_version(stlink_t *sl); int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); diff --git a/src/common.c b/src/common.c index 928091eb4..63086ab22 100644 --- a/src/common.c +++ b/src/common.c @@ -1791,7 +1791,7 @@ int stlink_reset(stlink_t *sl, enum reset_type type) { return(0); } -int stlink_run(stlink_t *sl) { +int stlink_run(stlink_t *sl, enum run_type type) { struct stlink_reg rr; DLOG("*** stlink_run ***\n"); @@ -1804,7 +1804,7 @@ int stlink_run(stlink_t *sl) { stlink_write_reg(sl, rr.xpsr | (1 << 24), 16); } - return(sl->backend->run(sl)); + return(sl->backend->run(sl, type)); } int stlink_set_swdclk(stlink_t *sl, int freq_khz) { @@ -2096,7 +2096,7 @@ int stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size) { void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { stlink_write_reg(sl, addr, 15); /* pc register */ - stlink_run(sl); + stlink_run(sl, RUN_NORMAL); while (stlink_is_core_halted(sl)) { usleep(3000000); } } @@ -2258,7 +2258,7 @@ static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { // set PC to the reset routine stlink_read_debug32(sl, addr + 4, &val); stlink_write_reg(sl, val, 15); - stlink_run(sl); + stlink_run(sl, RUN_NORMAL); } int stlink_mwrite_sram(stlink_t * sl, uint8_t* data, uint32_t length, stm32_addr_t addr) { diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 5eb607758..ede0f1179 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -17,7 +17,7 @@ static void cleanup(int signum) { (void)signum; if (connected_stlink) { // switch back to mass storage mode before closing - stlink_run(connected_stlink); + stlink_run(connected_stlink, RUN_NORMAL); stlink_exit_debug_mode(connected_stlink); stlink_close(connected_stlink); } diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index f40a9d683..f28624475 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -539,7 +539,7 @@ int main(int argc, char** argv) memset(&trace, 0, sizeof(trace)); trace.start_time = time(NULL); - if (stlink_run(stlink)) { + if (stlink_run(stlink, RUN_NORMAL)) { ELOG("Unable to run device\n"); if (!settings.force) return APP_RESULT_STLINK_STATE_ERROR; diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index c2a220df3..c6d329456 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -74,7 +74,7 @@ static void init_cache(stlink_t *sl); static void _cleanup() { if (connected_stlink) { // Switch back to mass storage mode before closing - stlink_run(connected_stlink); + stlink_run(connected_stlink, RUN_NORMAL); stlink_exit_debug_mode(connected_stlink); stlink_close(connected_stlink); } @@ -252,11 +252,11 @@ int main(int argc, char** argv) { init_cache(sl); - do { // don't go beserk if serve() returns with error + do { // don't go beserk if serve() returns with error if (serve(sl, &state)) { usleep (1 * 1000); } - sl = connected_stlink; // in case serve() changed the connection - stlink_run(sl); // continue + sl = connected_stlink; // in case serve() changed the connection + stlink_run(sl, RUN_NORMAL); // continue } while (state.persistent); #if defined(_WIN32) @@ -1229,7 +1229,7 @@ int serve(stlink_t *sl, st_state_t *st) { if (!strncmp(cmd, "resume", 6)) { // resume DLOG("Rcmd: resume\n"); cache_sync(sl); - ret = stlink_run(sl); + ret = stlink_run(sl, RUN_NORMAL); if (ret) { DLOG("Rcmd: resume failed\n"); @@ -1396,7 +1396,7 @@ int serve(stlink_t *sl, st_state_t *st) { case 'c': cache_sync(sl); - ret = stlink_run(sl); + ret = stlink_run(sl, RUN_NORMAL); if (ret) { DLOG("Semihost: run failed\n"); } @@ -1466,7 +1466,7 @@ int serve(stlink_t *sl, st_state_t *st) { // continue execution cache_sync(sl); - ret = stlink_run(sl); + ret = stlink_run(sl, RUN_NORMAL); if (ret) { DLOG("Semihost: continue execution failed with stlink_run\n"); } } else { @@ -1806,7 +1806,7 @@ int serve(stlink_t *sl, st_state_t *st) { } case 'k': // kill request - reset the connection itself - ret = stlink_run(sl); + ret = stlink_run(sl, RUN_NORMAL); if (ret) { DLOG("Kill: stlink_run failed\n"); } ret = stlink_exit_debug_mode(sl); diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index cd7096490..ba5efdb8e 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -347,7 +347,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe } /* Run loader */ - stlink_run(sl); + stlink_run(sl, RUN_FLASH_LOADER); /* This piece of code used to try to spin for .1 second by waiting doing 10000 rounds of 10 µs. * But because this usually runs on Unix-like OSes, the 10 µs get rounded up to the "tick" diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index c5946ed19..07971284f 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -731,8 +731,9 @@ void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { } // force the core exit the debug mode. -int _stlink_sg_run(stlink_t *sl) { +int _stlink_sg_run(stlink_t *sl, enum run_type type) { struct stlink_libsg *sg = sl->backend_data; + (void)(type); //unused clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_RUNCORE; sl->q_len = 2; diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 99b5f51ef..2754db06f 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -590,14 +590,17 @@ int _stlink_usb_step(stlink_t* sl) { /** * This seems to do a good job of restarting things from the beginning? * @param sl + * @param type */ -int _stlink_usb_run(stlink_t* sl) { +int _stlink_usb_run(stlink_t* sl, enum run_type type) { struct stlink_libusb * const slu = sl->backend_data; int res; if (sl->version.jtag_api != STLINK_JTAG_API_V1) { - res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN); + res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + ((type==RUN_FLASH_LOADER)?STLINK_REG_DHCSR_C_MASKINTS:0)); return(res); } diff --git a/tests/sg.c b/tests/sg.c index 7584ab5d4..d88fbe760 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -159,7 +159,7 @@ int main(void) { // main() ripped out of old stlink-hw.c #endif #if 0 - stlink_run(sl); + stlink_run(sl, RUN_NORMAL); stlink_status(sl); stlink_force_debug(sl); stlink_status(sl); @@ -196,7 +196,7 @@ int main(void) { // main() ripped out of old stlink-hw.c #endif #if 0 - stlink_run(sl); + stlink_run(sl, RUN_NORMAL); stlink_status(sl); // back to mass mode, just in case ... stlink_exit_debug_mode(sl); diff --git a/tests/usb.c b/tests/usb.c index 5c5c2077d..742f5c578 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -111,7 +111,7 @@ int main(int ac, char** av) { stlink_step(sl); printf("-- run\n"); - stlink_run(sl); + stlink_run(sl, RUN_NORMAL); printf("-- exit_debug_mode\n"); stlink_exit_debug_mode(sl); From c2e898c9228e2b13378987354f602745e1ca7b1c Mon Sep 17 00:00:00 2001 From: anton Date: Tue, 6 Apr 2021 22:43:15 +0500 Subject: [PATCH 1165/1435] Manual NRST pulse shaping Automatic generation via argument two of the jtag_reset function seem doesn't to work --- src/common.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 63086ab22..1cb5c6db0 100644 --- a/src/common.c +++ b/src/common.c @@ -1751,7 +1751,12 @@ int stlink_reset(stlink_t *sl, enum reset_type type) { if (type == RESET_HARD || type == RESET_AUTO) { // hardware target reset - if (sl->version.stlink_v > 1) { stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_PULSE); } + if (sl->version.stlink_v > 1) { + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); + // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) + usleep(100); + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); + } if (sl->backend->reset(sl)) { return(-1); } usleep(10000); } @@ -4522,6 +4527,9 @@ int stlink_target_connect(stlink_t *sl, enum connect_type connect) { if (connect == CONNECT_UNDER_RESET) { stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); + // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) + usleep(20); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } stlink_force_debug(sl); From 31738583967b89cf6416fd45a17ca8a7adfe12e2 Mon Sep 17 00:00:00 2001 From: anton Date: Wed, 7 Apr 2021 20:57:17 +0500 Subject: [PATCH 1166/1435] gdb-server: set target configuration after client connects --- src/st-util/gdb-server.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index c6d329456..006a0e3aa 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -242,16 +242,12 @@ int main(int argc, char** argv) { DLOG("Chip ID is %#010x, Core ID is %#08x.\n", sl->chip_id, sl->core_id); - state.current_memory_map = make_memory_map(sl); - #if defined(_WIN32) WSADATA wsadata; if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) { goto winsock_error; } #endif - init_cache(sl); - do { // don't go beserk if serve() returns with error if (serve(sl, &state)) { usleep (1 * 1000); } @@ -1102,12 +1098,22 @@ int serve(stlink_t *sl, st_state_t *st) { close_socket(sock); + uint32_t chip_id = sl->chip_id; + stlink_target_connect(sl, st->connect_mode); stlink_force_debug(sl); + if (sl->chip_id != chip_id) { + WLOG("Target has changed!\n"); + } + init_code_breakpoints(sl); init_data_watchpoints(sl); + init_cache(sl); + + st->current_memory_map = make_memory_map(sl); + ILOG("GDB connected.\n"); /* From d2a2c9825a739d92f2c4b7604ca732a2c1e3161e Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 12 Apr 2021 22:34:44 +0500 Subject: [PATCH 1167/1435] Fixed chipid detection on Cortex-MO+ core --- src/common.c | 3 ++- src/stlink-lib/reg.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index a17392cf1..f230bee64 100644 --- a/src/common.c +++ b/src/common.c @@ -1240,7 +1240,8 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) ret = stlink_read_debug32(sl, 0x5c001000, chip_id); - } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0) { + } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0 || + cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0P) { // STM32F0 (RM0091, pg914; RM0360, pg713) // STM32L0 (RM0377, pg813; RM0367, pg915; RM0376, pg917) // STM32G0 (RM0444, pg1367) diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 4849806d7..b581a269c 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -4,6 +4,7 @@ #define STLINK_REG_CM3_CPUID 0xE000ED00 #define STLINK_REG_CMx_CPUID_PARTNO_CM0 0xC20 +#define STLINK_REG_CMx_CPUID_PARTNO_CM0P 0xC60 #define STLINK_REG_CMx_CPUID_PARTNO_CM3 0xC23 #define STLINK_REG_CMx_CPUID_PARTNO_CM4 0xC24 #define STLINK_REG_CMx_CPUID_PARTNO_CM7 0xC27 From dfb00775a3e332c8575d8d5dfc86365de04ed2e3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 15 Apr 2021 22:39:24 +0200 Subject: [PATCH 1168/1435] Updated changelog --- CHANGELOG.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57426342a..0ac52da73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # stlink Changelog -# v1.6.2 +# v1.7.0 Release date: 2020-04-xx @@ -8,7 +8,8 @@ This release drops support for the STLINK/V1 programmer on macOS 10.13. Features: -- Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#868](https://github.com/stlink-org/stlink/pull/868), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) +- Extended set of cmd line arguments for st-info and st-util ([#332](https://github.com/stlink-org/stlink/pull/332), [#990](https://github.com/stlink-org/stlink/pull/990), [#1091](https://github.com/stlink-org/stlink/pull/1091), [#1114](https://github.com/stlink-org/stlink/pull/1114)) +- Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#801](https://github.com/stlink-org/stlink/pull/801), [#868](https://github.com/stlink-org/stlink/pull/868), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) - Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052)) - Official support for STLINK-V3 programmers (commit [#5e0a502](https://github.com/stlink-org/stlink/commit/5e0a502df812495bfa96fa9116a19f1306152b17), [#820](https://github.com/stlink-org/stlink/pull/820), [#1022](https://github.com/stlink-org/stlink/pull/1022), [#1025](https://github.com/stlink-org/stlink/pull/1025)) - Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) @@ -39,7 +40,7 @@ Updates & changes: Fixes: -- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) +- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#807](https://github.com/stlink-org/stlink/pull/807), [#817](https://github.com/stlink-org/stlink/pull/817), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) - Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106)) - Use vl flashloader for all STM32F1 series ([#769](https://github.com/stlink-org/stlink/pull/769), [#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) @@ -52,7 +53,7 @@ Fixes: - Fixed `connect under reset` for `st-flash` and `st-util` ([#983](https://github.com/stlink-org/stlink/pull/983)) - Fix for `mmap() size_t overflow` in `st-flash` ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) - [regression] `stlink-gui` installation issue on Ubuntu-18.04 ([#1001](https://github.com/stlink-org/stlink/pull/1001), [#1004](https://github.com/stlink-org/stlink/pull/1004), [#1006](https://github.com/stlink-org/stlink/pull/1006)) -- `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027), [#1064](https://github.com/stlink-org/stlink/pull/1064), [#1065](https://github.com/stlink-org/stlink/pull/1065)) +- `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027), [#1038](https://github.com/stlink-org/stlink/pull/1038),[#1064](https://github.com/stlink-org/stlink/pull/1064), [#1065](https://github.com/stlink-org/stlink/pull/1065)) - GDB: Fixed problems with target description ([#1013](https://github.com/stlink-org/stlink/pull/1013), [#1088](https://github.com/stlink-org/stlink/pull/1088), [#1109](https://github.com/stlink-org/stlink/pull/1109)) - [doc] Fixed wrong path for `rules.d` folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) - Fixed support for STLINK/V1 programmer ([#1045](https://github.com/stlink-org/stlink/pull/1045), [#1105](https://github.com/stlink-org/stlink/pull/1105)) @@ -61,7 +62,7 @@ Fixes: - Bugfixes for compilation with clang ([#1076](https://github.com/stlink-org/stlink/pull/1076), [#1078](https://github.com/stlink-org/stlink/pull/1078)) - Fixed compilation with GCC 11 ([#1077](https://github.com/stlink-org/stlink/pull/1077)) - [regression] Flash_loader: increased wait rounds for slow boards ([#1085](https://github.com/stlink-org/stlink/pull/1085)) -- Fixed support for writing option bytes ([#1102](https://github.com/stlink-org/stlink/pull/1102)) +- Fixed support for writing option bytes ([#1102](https://github.com/stlink-org/stlink/pull/1102), [#1128](https://github.com/stlink-org/stlink/pull/1128)) - [doc] Corrected spelling mistake in bug report template ([#1103](https://github.com/stlink-org/stlink/pull/1103)) - Fixed STM32WB55 reading DEBUG IDCODE from the wrong address ([#1100](https://github.com/stlink-org/stlink/pull/1100), [#1101](https://github.com/stlink-org/stlink/pull/1101)) - Applied missing changes to tests ([#1119](https://github.com/stlink-org/stlink/pull/1119)) @@ -75,7 +76,7 @@ This release drops support for some older operating systems. Check project READM Features: -- Basic compatibility for STLink/V3 programmer ([#271](https://github.com/stlink-org/stlink/pull/271), [#863](https://github.com/stlink-org/stlink/pull/863), [#954](https://github.com/stlink-org/stlink/pull/954)) +- Basic compatibility for STLink/V3 programmer ([#271](https://github.com/stlink-org/stlink/pull/271), [#863](https://github.com/stlink-org/stlink/pull/863), [#954](https://github.com/stlink-org/stlink/pull/954), [#1023](https://github.com/stlink-org/stlink/pull/1023)) - Added support for JTAG command API v2 & distinguish protocol versions v1 and v2 - Compatibility with the STLink/V3 firmware which dropped support for the previous API v1 - As of firmware version J11 the STLink/V1 programmer supports API v2 commands as well @@ -142,6 +143,7 @@ Updates & changes: Fixes: +- Improvements and fixes of the flash loaders, unification of the reset function ([#244](https://github.com/stlink-org/stlink/pull/244), [#382](https://github.com/stlink-org/stlink/pull/382), [#705](https://github.com/stlink-org/stlink/pull/705), [#980](https://github.com/stlink-org/stlink/pull/980), [#995](https://github.com/stlink-org/stlink/pull/995), [#1115](https://github.com/stlink-org/stlink/pull/1115), [#1117](https://github.com/stlink-org/stlink/pull/1117), [#1122](https://github.com/stlink-org/stlink/pull/1122), [#1124](https://github.com/stlink-org/stlink/pull/1124)) - Fixed wait-loop for `flash_loader_run()` ([#290](https://github.com/stlink-org/stlink/pull/290)) - Better argument parsing for CLI tools: `stlink_open_usb` can address v1, v2, v3 ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) - Clear the PG bit before setting the `PER` bit ([#579](https://github.com/stlink-org/stlink/pull/579), [#876](https://github.com/stlink-org/stlink/pull/876)) @@ -163,6 +165,7 @@ Fixes: - Set static link for `libssp` (stack-smashing protection) ([#960](https://github.com/stlink-org/stlink/pull/960), [#961](https://github.com/stlink-org/stlink/pull/961)) - Fixed udev rules installing to wrong directory ([#966](https://github.com/stlink-org/stlink/pull/966)) - Fixed formatting for options display in `st-flash` & `st-info` (commits [#c783d0e](https://github.com/stlink-org/stlink/commit/c783d0e777ccc83a7a8be26a4f4d3414e0478560) and [#562cd24](https://github.com/stlink-org/stlink/commit/562cd2496e696dbd22950925866aac662d81ee5f)) +- Fixed reading of chip ID on Cortex-M0+ core ([#1125](https://github.com/stlink-org/stlink/pull/1125), [#1126](https://github.com/stlink-org/stlink/pull/1126)) # v1.6.0 From 9c1315a73296841ed3c25b4ea9500c187ab8236d Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 16 Apr 2021 00:10:20 +0200 Subject: [PATCH 1169/1435] Fixed GitHub Actions code scanning alerts --- src/common.c | 6800 ++++++++++++++++++++------------------ src/st-trace/trace.c | 990 +++--- src/stlink-lib/logging.c | 127 +- 3 files changed, 4089 insertions(+), 3828 deletions(-) diff --git a/src/common.c b/src/common.c index 57322cefd..4541aa31c 100644 --- a/src/common.c +++ b/src/common.c @@ -1,20 +1,20 @@ #define DEBUG_FLASH 0 #include +#include #include #include #include -#include #include -#include #include -#include #include +#include +#include -#include +#include #include #include -#include +#include #ifdef STLINK_HAVE_SYS_MMAN_H #include @@ -35,7 +35,8 @@ /* stm32f FPEC flash controller interface, pm0063 manual */ // TODO - all of this needs to be abstracted out.... -// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, August 2012) +// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, +// August 2012) #define FLASH_REGS_ADDR 0x40022000 #define FLASH_REGS_SIZE 0x28 @@ -48,7 +49,8 @@ #define FLASH_OBR (FLASH_REGS_ADDR + 0x1c) #define FLASH_WRPR (FLASH_REGS_ADDR + 0x20) -// STM32F10x_XL has two flash memory banks with separate registers to control the second bank. +// STM32F10x_XL has two flash memory banks with separate registers to control +// the second bank. #define FLASH_KEYR2 (FLASH_REGS_ADDR + 0x44) #define FLASH_SR2 (FLASH_REGS_ADDR + 0x4c) #define FLASH_CR2 (FLASH_REGS_ADDR + 0x50) @@ -128,113 +130,112 @@ // Mostly the same as STM32G0 chips, but there are a few extra // registers because 'cat 3' devices can have two Flash banks. #define STM32G4_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) -#define STM32G4_FLASH_PDKEYR (STM32G4_FLASH_REGS_ADDR + 0x04) -#define STM32G4_FLASH_PCROP1SR (STM32G4_FLASH_REGS_ADDR + 0x24) -#define STM32G4_FLASH_PCROP1ER (STM32G4_FLASH_REGS_ADDR + 0x28) -#define STM32G4_FLASH_WRP1AR (STM32G4_FLASH_REGS_ADDR + 0x2C) -#define STM32G4_FLASH_WRP1BR (STM32G4_FLASH_REGS_ADDR + 0x30) -#define STM32G4_FLASH_PCROP2SR (STM32G4_FLASH_REGS_ADDR + 0x44) -#define STM32G4_FLASH_PCROP2ER (STM32G4_FLASH_REGS_ADDR + 0x48) -#define STM32G4_FLASH_WRP2AR (STM32G4_FLASH_REGS_ADDR + 0x4C) -#define STM32G4_FLASH_WRP2BR (STM32G4_FLASH_REGS_ADDR + 0x50) -#define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70) -#define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74) +#define STM32G4_FLASH_PDKEYR (STM32G4_FLASH_REGS_ADDR + 0x04) +#define STM32G4_FLASH_PCROP1SR (STM32G4_FLASH_REGS_ADDR + 0x24) +#define STM32G4_FLASH_PCROP1ER (STM32G4_FLASH_REGS_ADDR + 0x28) +#define STM32G4_FLASH_WRP1AR (STM32G4_FLASH_REGS_ADDR + 0x2C) +#define STM32G4_FLASH_WRP1BR (STM32G4_FLASH_REGS_ADDR + 0x30) +#define STM32G4_FLASH_PCROP2SR (STM32G4_FLASH_REGS_ADDR + 0x44) +#define STM32G4_FLASH_PCROP2ER (STM32G4_FLASH_REGS_ADDR + 0x48) +#define STM32G4_FLASH_WRP2AR (STM32G4_FLASH_REGS_ADDR + 0x4C) +#define STM32G4_FLASH_WRP2BR (STM32G4_FLASH_REGS_ADDR + 0x50) +#define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70) +#define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74) // G0/G4 FLASH control register -#define STM32Gx_FLASH_CR_PG (0) /* Program */ -#define STM32Gx_FLASH_CR_PER (1) /* Page erase */ -#define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */ -#define STM32Gx_FLASH_CR_PNB (3) /* Page number */ -#define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ -#define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ -#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ -#define STM32Gx_FLASH_CR_STRT (16) /* Start */ -#define STM32Gx_FLASH_CR_OPTSTRT (17) /* Start of modification of option bytes */ -#define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ -#define STM32Gx_FLASH_CR_EOPIE (24) /* End of operation interrupt enable */ -#define STM32Gx_FLASH_CR_ERRIE (25) /* Error interrupt enable */ -#define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ -#define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ -#define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ +#define STM32Gx_FLASH_CR_PG (0) /* Program */ +#define STM32Gx_FLASH_CR_PER (1) /* Page erase */ +#define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */ +#define STM32Gx_FLASH_CR_PNB (3) /* Page number */ +#define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ +#define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ +#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ +#define STM32Gx_FLASH_CR_STRT (16) /* Start */ +#define STM32Gx_FLASH_CR_OPTSTRT \ + (17) /* Start of modification of option bytes */ +#define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ +#define STM32Gx_FLASH_CR_EOPIE (24) /* End of operation interrupt enable */ +#define STM32Gx_FLASH_CR_ERRIE (25) /* Error interrupt enable */ +#define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ +#define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ +#define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ // G0/G4 FLASH status register #define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) -#define STM32Gx_FLASH_SR_PROGERR (3) -#define STM32Gx_FLASH_SR_WRPERR (4) -#define STM32Gx_FLASH_SR_PGAERR (5) -#define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ -#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ +#define STM32Gx_FLASH_SR_PROGERR (3) +#define STM32Gx_FLASH_SR_WRPERR (4) +#define STM32Gx_FLASH_SR_PGAERR (5) +#define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ +#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ // G4 FLASH option register -#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ +#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ // WB (RM0434) #define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) -#define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) -#define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) -#define STM32WB_FLASH_OPT_KEYR (STM32WB_FLASH_REGS_ADDR + 0x0C) -#define STM32WB_FLASH_SR (STM32WB_FLASH_REGS_ADDR + 0x10) -#define STM32WB_FLASH_CR (STM32WB_FLASH_REGS_ADDR + 0x14) -#define STM32WB_FLASH_ECCR (STM32WB_FLASH_REGS_ADDR + 0x18) -#define STM32WB_FLASH_OPTR (STM32WB_FLASH_REGS_ADDR + 0x20) +#define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) +#define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) +#define STM32WB_FLASH_OPT_KEYR (STM32WB_FLASH_REGS_ADDR + 0x0C) +#define STM32WB_FLASH_SR (STM32WB_FLASH_REGS_ADDR + 0x10) +#define STM32WB_FLASH_CR (STM32WB_FLASH_REGS_ADDR + 0x14) +#define STM32WB_FLASH_ECCR (STM32WB_FLASH_REGS_ADDR + 0x18) +#define STM32WB_FLASH_OPTR (STM32WB_FLASH_REGS_ADDR + 0x20) #define STM32WB_FLASH_PCROP1ASR (STM32WB_FLASH_REGS_ADDR + 0x24) #define STM32WB_FLASH_PCROP1AER (STM32WB_FLASH_REGS_ADDR + 0x28) -#define STM32WB_FLASH_WRP1AR (STM32WB_FLASH_REGS_ADDR + 0x2C) -#define STM32WB_FLASH_WRP1BR (STM32WB_FLASH_REGS_ADDR + 0x30) +#define STM32WB_FLASH_WRP1AR (STM32WB_FLASH_REGS_ADDR + 0x2C) +#define STM32WB_FLASH_WRP1BR (STM32WB_FLASH_REGS_ADDR + 0x30) #define STM32WB_FLASH_PCROP1BSR (STM32WB_FLASH_REGS_ADDR + 0x34) #define STM32WB_FLASH_PCROP1BER (STM32WB_FLASH_REGS_ADDR + 0x38) -#define STM32WB_FLASH_IPCCBR (STM32WB_FLASH_REGS_ADDR + 0x3C) -#define STM32WB_FLASH_C2ACR (STM32WB_FLASH_REGS_ADDR + 0x5C) -#define STM32WB_FLASH_C2SR (STM32WB_FLASH_REGS_ADDR + 0x60) -#define STM32WB_FLASH_C2CR (STM32WB_FLASH_REGS_ADDR + 0x64) -#define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) -#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) +#define STM32WB_FLASH_IPCCBR (STM32WB_FLASH_REGS_ADDR + 0x3C) +#define STM32WB_FLASH_C2ACR (STM32WB_FLASH_REGS_ADDR + 0x5C) +#define STM32WB_FLASH_C2SR (STM32WB_FLASH_REGS_ADDR + 0x60) +#define STM32WB_FLASH_C2CR (STM32WB_FLASH_REGS_ADDR + 0x64) +#define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) +#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) // WB Flash control register. -#define STM32WB_FLASH_CR_STRT (16) /* Start */ -#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ -#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ +#define STM32WB_FLASH_CR_STRT (16) /* Start */ +#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ +#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ // WB Flash status register. #define STM32WB_FLASH_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ -#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ -#define STM32WB_FLASH_SR_WRPERR (4) /* Write protection error */ -#define STM32WB_FLASH_SR_PGAERR (5) /* Programming error */ -#define STM32WB_FLASH_SR_BSY (16) /* Busy */ +#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ +#define STM32WB_FLASH_SR_WRPERR (4) /* Write protection error */ +#define STM32WB_FLASH_SR_PGAERR (5) /* Programming error */ +#define STM32WB_FLASH_SR_BSY (16) /* Busy */ // 32L4 register base is at FLASH_REGS_ADDR (0x40022000) -#define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) -#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) -#define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) -#define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) -#define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) +#define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) +#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) +#define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) +#define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) +#define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) #define STM32L4_FLASH_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ -#define STM32L4_FLASH_SR_PROGERR 3 -#define STM32L4_FLASH_SR_WRPERR 4 -#define STM32L4_FLASH_SR_PGAERR 5 -#define STM32L4_FLASH_SR_BSY 16 - -#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ -#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ -#define STM32L4_FLASH_CR_PG 0 /* Program */ -#define STM32L4_FLASH_CR_PER 1 /* Page erase */ -#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ -#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ -#define STM32L4_FLASH_CR_STRT 16 /* Start command */ -#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ -#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ -#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ +#define STM32L4_FLASH_SR_PROGERR 3 +#define STM32L4_FLASH_SR_WRPERR 4 +#define STM32L4_FLASH_SR_PGAERR 5 +#define STM32L4_FLASH_SR_BSY 16 + +#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ +#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ +#define STM32L4_FLASH_CR_PG 0 /* Program */ +#define STM32L4_FLASH_CR_PER 1 /* Page erase */ +#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ +#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ +#define STM32L4_FLASH_CR_STRT 16 /* Start command */ +#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ +#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ +#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ #define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ // Bits requesting flash operations (useful when we want to clear them) -#define STM32L4_FLASH_CR_OPBITS \ - (uint32_t)((1lu << STM32L4_FLASH_CR_PG) | \ - (1lu << STM32L4_FLASH_CR_PER) | \ - (1lu << STM32L4_FLASH_CR_MER1) | \ - (1lu << STM32L4_FLASH_CR_MER1)) +#define STM32L4_FLASH_CR_OPBITS \ + (uint32_t)((1lu << STM32L4_FLASH_CR_PG) | (1lu << STM32L4_FLASH_CR_PER) | \ + (1lu << STM32L4_FLASH_CR_MER1) | (1lu << STM32L4_FLASH_CR_MER1)) // Page is fully specified by BKER and PNB #define STM32L4_FLASH_CR_PAGEMASK (uint32_t)(0x1fflu << STM32L4_FLASH_CR_PNB) -#define STM32L4_FLASH_OPTR_DUALBANK 21 +#define STM32L4_FLASH_OPTR_DUALBANK 21 // STM32L0x flash register base and offsets RM0090 - DM00031020.pdf #define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) @@ -245,21 +246,21 @@ #define STM32L0_FLASH_OBL_LAUNCH (18) #define STM32L0_FLASH_SR_ERROR_MASK 0x00013F00 -#define STM32L0_FLASH_SR_WRPERR 8 -#define STM32L0_FLASH_SR_PGAERR 9 +#define STM32L0_FLASH_SR_WRPERR 8 +#define STM32L0_FLASH_SR_PGAERR 9 #define STM32L0_FLASH_SR_NOTZEROERR 16 -#define FLASH_ACR_OFF ((uint32_t) 0x00) -#define FLASH_PECR_OFF ((uint32_t) 0x04) -#define FLASH_PDKEYR_OFF ((uint32_t) 0x08) -#define FLASH_PEKEYR_OFF ((uint32_t) 0x0c) -#define FLASH_PRGKEYR_OFF ((uint32_t) 0x10) -#define FLASH_OPTKEYR_OFF ((uint32_t) 0x14) -#define FLASH_SR_OFF ((uint32_t) 0x18) -#define FLASH_OBR_OFF ((uint32_t) 0x1c) -#define FLASH_WRPR_OFF ((uint32_t) 0x20) - -//STM32F7 +#define FLASH_ACR_OFF ((uint32_t)0x00) +#define FLASH_PECR_OFF ((uint32_t)0x04) +#define FLASH_PDKEYR_OFF ((uint32_t)0x08) +#define FLASH_PEKEYR_OFF ((uint32_t)0x0c) +#define FLASH_PRGKEYR_OFF ((uint32_t)0x10) +#define FLASH_OPTKEYR_OFF ((uint32_t)0x14) +#define FLASH_SR_OFF ((uint32_t)0x18) +#define FLASH_OBR_OFF ((uint32_t)0x1c) +#define FLASH_WRPR_OFF ((uint32_t)0x20) + +// STM32F7 #define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) #define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) @@ -279,14 +280,17 @@ #define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ #define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ #define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ -#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ -#define FLASH_F7_SR_EOP 0 /* End of operation */ +#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ +#define FLASH_F7_SR_EOP 0 /* End of operation */ #define FLASH_F7_OPTCR1_BOOT_ADD0 0 #define FLASH_F7_OPTCR1_BOOT_ADD1 16 -#define FLASH_F7_SR_ERROR_MASK ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | (1 << FLASH_F7_SR_OP_ERR)) +#define FLASH_F7_SR_ERROR_MASK \ + ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | \ + (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | \ + (1 << FLASH_F7_SR_OP_ERR)) -//STM32F4 +// STM32F4 #define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) #define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08) @@ -301,9 +305,9 @@ #define FLASH_F4_CR_SNB 3 #define FLASH_F4_CR_SNB_MASK 0xf8 #define FLASH_F4_SR_ERROR_MASK 0x000000F0 -#define FLASH_F4_SR_PGAERR 5 -#define FLASH_F4_SR_WRPERR 4 -#define FLASH_F4_SR_BSY 16 +#define FLASH_F4_SR_PGAERR 5 +#define FLASH_F4_SR_WRPERR 4 +#define FLASH_F4_SR_BSY 16 // STM32F2 #define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) @@ -327,15 +331,17 @@ #define FLASH_H7_CR_SER 2 #define FLASH_H7_CR_BER 3 #define FLASH_H7_CR_PSIZE 4 -#define FLASH_H7_CR_START(chipid) (chipid==STLINK_CHIPID_STM32_H7AX?5:7) +#define FLASH_H7_CR_START(chipid) (chipid == STLINK_CHIPID_STM32_H7AX ? 5 : 7) #define FLASH_H7_CR_SNB 8 #define FLASH_H7_CR_SNB_MASK 0x700 -#define FLASH_H7_SR_QW 2 +#define FLASH_H7_SR_QW 2 #define FLASH_H7_SR_WRPERR 17 #define FLASH_H7_SR_PGSERR 18 #define FLASH_H7_SR_STRBERR 19 -#define FLASH_H7_SR_ERROR_MASK ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | (1 << FLASH_H7_SR_WRPERR)) +#define FLASH_H7_SR_ERROR_MASK \ + ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | \ + (1 << FLASH_H7_SR_WRPERR)) #define FLASH_H7_OPTCR_OPTLOCK 0 #define FLASH_H7_OPTCR_OPTSTART 1 @@ -362,1189 +368,1188 @@ #define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) #define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) -#define STM32F0_DBGMCU_CR 0xE0042004 -#define STM32F0_DBGMCU_CR_IWDG_STOP 8 -#define STM32F0_DBGMCU_CR_WWDG_STOP 9 +#define STM32F0_DBGMCU_CR 0xE0042004 +#define STM32F0_DBGMCU_CR_IWDG_STOP 8 +#define STM32F0_DBGMCU_CR_WWDG_STOP 9 -#define STM32F4_DBGMCU_APB1FZR1 0xE0042008 +#define STM32F4_DBGMCU_APB1FZR1 0xE0042008 #define STM32F4_DBGMCU_APB1FZR1_WWDG_STOP 11 #define STM32F4_DBGMCU_APB1FZR1_IWDG_STOP 12 -#define STM32L0_DBGMCU_APB1_FZ 0x40015808 -#define STM32L0_DBGMCU_APB1_FZ_WWDG_STOP 11 -#define STM32L0_DBGMCU_APB1_FZ_IWDG_STOP 12 +#define STM32L0_DBGMCU_APB1_FZ 0x40015808 +#define STM32L0_DBGMCU_APB1_FZ_WWDG_STOP 11 +#define STM32L0_DBGMCU_APB1_FZ_IWDG_STOP 12 -#define STM32H7_DBGMCU_APB1HFZ 0x5C001054 -#define STM32H7_DBGMCU_APB1HFZ_IWDG_STOP 18 +#define STM32H7_DBGMCU_APB1HFZ 0x5C001054 +#define STM32H7_DBGMCU_APB1HFZ_IWDG_STOP 18 -#define STM32WB_DBGMCU_APB1FZR1 0xE004203C +#define STM32WB_DBGMCU_APB1FZR1 0xE004203C #define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11 #define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12 -#define STM32F1_RCC_AHBENR 0x40021014 -#define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN +#define STM32F1_RCC_AHBENR 0x40021014 +#define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN -#define STM32F4_RCC_AHB1ENR 0x40023830 -#define STM32F4_RCC_DMAEN 0x00600000 // DMA2EN | DMA1EN +#define STM32F4_RCC_AHB1ENR 0x40023830 +#define STM32F4_RCC_DMAEN 0x00600000 // DMA2EN | DMA1EN -#define STM32G0_RCC_AHBENR 0x40021038 -#define STM32G0_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN +#define STM32G0_RCC_AHBENR 0x40021038 +#define STM32G0_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN -#define STM32G4_RCC_AHB1ENR 0x40021048 -#define STM32G4_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN +#define STM32G4_RCC_AHB1ENR 0x40021048 +#define STM32G4_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN -#define STM32L0_RCC_AHBENR 0x40021030 -#define STM32L0_RCC_DMAEN 0x00000001 // DMAEN +#define STM32L0_RCC_AHBENR 0x40021030 +#define STM32L0_RCC_DMAEN 0x00000001 // DMAEN -#define STM32H7_RCC_AHB1ENR 0x58024538 -#define STM32H7_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN +#define STM32H7_RCC_AHB1ENR 0x58024538 +#define STM32H7_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN -#define STM32WB_RCC_AHB1ENR 0x58000048 -#define STM32WB_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN +#define STM32WB_RCC_AHB1ENR 0x58000048 +#define STM32WB_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 - // Endianness // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html // These functions encode and decode little endian uint16 and uint32 values. -void write_uint32(unsigned char* buf, uint32_t ui) { - buf[0] = ui; - buf[1] = ui >> 8; - buf[2] = ui >> 16; - buf[3] = ui >> 24; +void write_uint32(unsigned char *buf, uint32_t ui) { + buf[0] = ui; + buf[1] = ui >> 8; + buf[2] = ui >> 16; + buf[3] = ui >> 24; } -void write_uint16(unsigned char* buf, uint16_t ui) { - buf[0] = ui ; - buf[1] = ui >> 8; +void write_uint16(unsigned char *buf, uint16_t ui) { + buf[0] = ui; + buf[1] = ui >> 8; } uint32_t read_uint32(const unsigned char *c, const int pt) { - return ((uint32_t)c[pt]) | ((uint32_t)c[pt+1] << 8) | ((uint32_t)c[pt+2] << 16) | ((uint32_t)c[pt+3] << 24) ; + return ((uint32_t)c[pt]) | ((uint32_t)c[pt + 1] << 8) | + ((uint32_t)c[pt + 2] << 16) | ((uint32_t)c[pt + 3] << 24); } uint16_t read_uint16(const unsigned char *c, const int pt) { - return ((uint16_t)c[pt]) | ((uint16_t)c[pt+1] << 8); + return ((uint16_t)c[pt]) | ((uint16_t)c[pt + 1] << 8); } +static uint32_t get_stm32l0_flash_base(stlink_t *sl) { + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_L0: + case STLINK_CHIPID_STM32_L0_CAT5: + case STLINK_CHIPID_STM32_L0_CAT2: + case STLINK_CHIPID_STM32_L011: + return (STM32L0_FLASH_REGS_ADDR); -static uint32_t get_stm32l0_flash_base(stlink_t *sl) -{ - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_L0: - case STLINK_CHIPID_STM32_L0_CAT5: - case STLINK_CHIPID_STM32_L0_CAT2: - case STLINK_CHIPID_STM32_L011: - return(STM32L0_FLASH_REGS_ADDR); - - case STLINK_CHIPID_STM32_L1_CAT2: - case STLINK_CHIPID_STM32_L1_MEDIUM: - case STLINK_CHIPID_STM32_L1_MEDIUM_PLUS: - case STLINK_CHIPID_STM32_L1_HIGH: - return(STM32L1_FLASH_REGS_ADDR); + case STLINK_CHIPID_STM32_L1_CAT2: + case STLINK_CHIPID_STM32_L1_MEDIUM: + case STLINK_CHIPID_STM32_L1_MEDIUM_PLUS: + case STLINK_CHIPID_STM32_L1_HIGH: + return (STM32L1_FLASH_REGS_ADDR); - default: - WLOG("Flash base use default L0 address"); - return(STM32L0_FLASH_REGS_ADDR); - } + default: + WLOG("Flash base use default L0 address"); + return (STM32L0_FLASH_REGS_ADDR); + } } static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { - uint32_t rdp; - stlink_read_debug32(sl, FLASH_WRPR, &rdp); - return(rdp & 0xff); + uint32_t rdp; + stlink_read_debug32(sl, FLASH_WRPR, &rdp); + return (rdp & 0xff); } static inline uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { - uint32_t reg, res; - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - reg = FLASH_F4_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - reg = FLASH_F7_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - reg = STM32L4_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - reg = STM32WB_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - reg = (bank == BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; - } else { - reg = (bank == BANK_1)?FLASH_CR:FLASH_CR2; - } - - stlink_read_debug32(sl, reg, &res); + uint32_t reg, res; + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + reg = FLASH_F4_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + reg = FLASH_F7_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + reg = STM32L4_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + reg = STM32WB_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + } else { + reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + } + + stlink_read_debug32(sl, reg, &res); #if DEBUG_FLASH - fprintf(stdout, "CR:0x%x\n", res); + fprintf(stdout, "CR:0x%x\n", res); #endif - return(res); + return (res); } static inline unsigned int is_flash_locked(stlink_t *sl) { - /* return non zero for true */ - uint32_t cr_lock_shift; - uint32_t cr_reg; - uint32_t n; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - cr_reg = FLASH_CR; - cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - cr_lock_shift = FLASH_F4_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_lock_shift = FLASH_F7_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - cr_lock_shift = STM32L0_FLASH_PELOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_lock_shift = STM32Gx_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - cr_lock_shift = STM32WB_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; - cr_lock_shift = FLASH_H7_CR_LOCK; - } else { - ELOG("unsupported flash method, abort\n"); - return(-1); - } - - stlink_read_debug32(sl, cr_reg, &n); - return(n & (1u << cr_lock_shift)); + /* return non zero for true */ + uint32_t cr_lock_shift; + uint32_t cr_reg; + uint32_t n; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_lock_shift = FLASH_F4_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_lock_shift = FLASH_F7_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + cr_lock_shift = STM32L0_FLASH_PELOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_lock_shift = STM32L4_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_lock_shift = STM32WB_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + cr_lock_shift = FLASH_H7_CR_LOCK; + } else { + ELOG("unsupported flash method, abort\n"); + return (-1); + } + + stlink_read_debug32(sl, cr_reg, &n); + return (n & (1u << cr_lock_shift)); } static void unlock_flash(stlink_t *sl) { - uint32_t key_reg, key2_reg = 0; - uint32_t flash_key1 = FLASH_KEY1; - uint32_t flash_key2 = FLASH_KEY2; - /* The unlock sequence consists of 2 write cycles where 2 key values are written - * to the FLASH_KEYR register. - * An invalid sequence results in a definitive lock of the FPEC block until next reset. - */ - - if (sl->flash_type == STLINK_FLASH_TYPE_F0) { - key_reg = FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - key_reg = FLASH_KEYR; - key2_reg = FLASH_KEYR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - key_reg = FLASH_F4_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - key_reg = FLASH_F7_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; - flash_key1 = FLASH_L0_PEKEY1; - flash_key2 = FLASH_L0_PEKEY2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - key_reg = STM32L4_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - key_reg = STM32Gx_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - key_reg = STM32WB_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - key_reg = FLASH_H7_KEYR1; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - key2_reg = FLASH_H7_KEYR2; - } - } else { - ELOG("unsupported flash method, abort\n"); - return; - } + uint32_t key_reg, key2_reg = 0; + uint32_t flash_key1 = FLASH_KEY1; + uint32_t flash_key2 = FLASH_KEY2; + /* The unlock sequence consists of 2 write cycles where 2 key values are + * written to the FLASH_KEYR register. An invalid sequence results in a + * definitive lock of the FPEC block until next reset. + */ + + if (sl->flash_type == STLINK_FLASH_TYPE_F0) { + key_reg = FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + key_reg = FLASH_KEYR; + key2_reg = FLASH_KEYR2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + key_reg = FLASH_F4_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + key_reg = FLASH_F7_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; + flash_key1 = FLASH_L0_PEKEY1; + flash_key2 = FLASH_L0_PEKEY2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + key_reg = STM32L4_FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + key_reg = STM32Gx_FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + key_reg = STM32WB_FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + key_reg = FLASH_H7_KEYR1; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + key2_reg = FLASH_H7_KEYR2; + } + } else { + ELOG("unsupported flash method, abort\n"); + return; + } - stlink_write_debug32(sl, key_reg, flash_key1); - stlink_write_debug32(sl, key_reg, flash_key2); + stlink_write_debug32(sl, key_reg, flash_key1); + stlink_write_debug32(sl, key_reg, flash_key2); - if (key2_reg) { - stlink_write_debug32(sl, key2_reg, flash_key1); - stlink_write_debug32(sl, key2_reg, flash_key2); - } + if (key2_reg) { + stlink_write_debug32(sl, key2_reg, flash_key1); + stlink_write_debug32(sl, key2_reg, flash_key2); + } } /* unlock flash if already locked */ static int unlock_flash_if(stlink_t *sl) { - if (is_flash_locked(sl)) { - unlock_flash(sl); + if (is_flash_locked(sl)) { + unlock_flash(sl); - if (is_flash_locked(sl)) { - WLOG("Failed to unlock flash!\n"); - return(-1); - } + if (is_flash_locked(sl)) { + WLOG("Failed to unlock flash!\n"); + return (-1); } + } - DLOG("Successfully unlocked flash\n"); - return(0); + DLOG("Successfully unlocked flash\n"); + return (0); } static void lock_flash(stlink_t *sl) { - uint32_t cr_lock_shift, cr_reg, n, cr2_reg = 0; - uint32_t cr_mask = 0xffffffffu; - - if (sl->flash_type == STLINK_FLASH_TYPE_F0) { - cr_reg = FLASH_CR; - cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - cr_reg = FLASH_CR; - cr2_reg = FLASH_CR2; - cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - cr_lock_shift = FLASH_F4_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_lock_shift = FLASH_F7_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - cr_lock_shift = STM32L0_FLASH_PELOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_lock_shift = STM32Gx_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - cr_lock_shift = STM32WB_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - cr2_reg = FLASH_H7_CR2; - } - cr_lock_shift = FLASH_H7_CR_LOCK; - cr_mask = ~(1u << FLASH_H7_CR_SER); - } else { - ELOG("unsupported flash method, abort\n"); - return; - } + uint32_t cr_lock_shift, cr_reg, n, cr2_reg = 0; + uint32_t cr_mask = 0xffffffffu; + + if (sl->flash_type == STLINK_FLASH_TYPE_F0) { + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + cr_reg = FLASH_CR; + cr2_reg = FLASH_CR2; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_lock_shift = FLASH_F4_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_lock_shift = FLASH_F7_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + cr_lock_shift = STM32L0_FLASH_PELOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_lock_shift = STM32L4_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_lock_shift = STM32WB_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + cr2_reg = FLASH_H7_CR2; + } + cr_lock_shift = FLASH_H7_CR_LOCK; + cr_mask = ~(1u << FLASH_H7_CR_SER); + } else { + ELOG("unsupported flash method, abort\n"); + return; + } - stlink_read_debug32(sl, cr_reg, &n); - n &= cr_mask; - n |= (1u << cr_lock_shift); - stlink_write_debug32(sl, cr_reg, n); + stlink_read_debug32(sl, cr_reg, &n); + n &= cr_mask; + n |= (1u << cr_lock_shift); + stlink_write_debug32(sl, cr_reg, n); - if (cr2_reg) { - n = read_flash_cr(sl, BANK_2) | (1u << cr_lock_shift); - stlink_write_debug32(sl, cr2_reg, n); - } + if (cr2_reg) { + n = read_flash_cr(sl, BANK_2) | (1u << cr_lock_shift); + stlink_write_debug32(sl, cr2_reg, n); + } } static bool is_flash_option_locked(stlink_t *sl) { - uint32_t optlock_shift, optcr_reg; - int active_bit_level = 1; - uint32_t n; - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - optcr_reg = FLASH_CR; - optlock_shift = FLASH_CR_OPTWRE; - active_bit_level = 0; /* bit is "option write enable", not lock */ - break; - case STLINK_FLASH_TYPE_F4: - optcr_reg = FLASH_F4_OPTCR; - optlock_shift = FLASH_F4_OPTCR_LOCK; - break; - case STLINK_FLASH_TYPE_F7: - optcr_reg = FLASH_F7_OPTCR; - optlock_shift = FLASH_F7_OPTCR_LOCK; - break; - case STLINK_FLASH_TYPE_L0: - optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - optlock_shift = STM32L0_FLASH_OPTLOCK; - break; - case STLINK_FLASH_TYPE_L4: - optcr_reg = STM32L4_FLASH_CR; - optlock_shift = STM32L4_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_WB: - optcr_reg = STM32WB_FLASH_CR; - optlock_shift = STM32WB_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_H7: - optcr_reg = FLASH_H7_OPTCR; - optlock_shift = FLASH_H7_OPTCR_OPTLOCK; - break; - default: - ELOG("unsupported flash method, abort\n"); - return -1; - } - - stlink_read_debug32(sl, optcr_reg, &n); - - if (active_bit_level == 0) { - return(!(n & (1u << optlock_shift))); - } - - return(n & (1u << optlock_shift)); - + uint32_t optlock_shift, optcr_reg; + int active_bit_level = 1; + uint32_t n; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; + optlock_shift = FLASH_CR_OPTWRE; + active_bit_level = 0; /* bit is "option write enable", not lock */ + break; + case STLINK_FLASH_TYPE_F4: + optcr_reg = FLASH_F4_OPTCR; + optlock_shift = FLASH_F4_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_F7: + optcr_reg = FLASH_F7_OPTCR; + optlock_shift = FLASH_F7_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_L0: + optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + optlock_shift = STM32L0_FLASH_OPTLOCK; + break; + case STLINK_FLASH_TYPE_L4: + optcr_reg = STM32L4_FLASH_CR; + optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_WB: + optcr_reg = STM32WB_FLASH_CR; + optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_H7: + optcr_reg = FLASH_H7_OPTCR; + optlock_shift = FLASH_H7_OPTCR_OPTLOCK; + break; + default: + ELOG("unsupported flash method, abort\n"); + return -1; + } + + stlink_read_debug32(sl, optcr_reg, &n); + + if (active_bit_level == 0) { + return (!(n & (1u << optlock_shift))); + } + + return (n & (1u << optlock_shift)); } static int lock_flash_option(stlink_t *sl) { - uint32_t optlock_shift, optcr_reg, n, optcr2_reg = 0; - int active_bit_level = 1; - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - optcr_reg = FLASH_CR; - optlock_shift = FLASH_CR_OPTWRE; - active_bit_level = 0; - break; - case STLINK_FLASH_TYPE_F4: - optcr_reg = FLASH_F4_OPTCR; - optlock_shift = FLASH_F4_OPTCR_LOCK; - break; - case STLINK_FLASH_TYPE_F7: - optcr_reg = FLASH_F7_OPTCR; - optlock_shift = FLASH_F7_OPTCR_LOCK; - break; - case STLINK_FLASH_TYPE_L0: - optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - optlock_shift = STM32L0_FLASH_OPTLOCK; - break; - case STLINK_FLASH_TYPE_L4: - optcr_reg = STM32L4_FLASH_CR; - optlock_shift = STM32L4_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_WB: - optcr_reg = STM32WB_FLASH_CR; - optlock_shift = STM32WB_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_H7: - optcr_reg = FLASH_H7_OPTCR; - optlock_shift = FLASH_H7_OPTCR_OPTLOCK; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) - optcr2_reg = FLASH_H7_OPTCR2; - break; - default: - ELOG("unsupported flash method, abort\n"); - return -1; - } - - stlink_read_debug32(sl, optcr_reg, &n); + uint32_t optlock_shift, optcr_reg, n, optcr2_reg = 0; + int active_bit_level = 1; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; + optlock_shift = FLASH_CR_OPTWRE; + active_bit_level = 0; + break; + case STLINK_FLASH_TYPE_F4: + optcr_reg = FLASH_F4_OPTCR; + optlock_shift = FLASH_F4_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_F7: + optcr_reg = FLASH_F7_OPTCR; + optlock_shift = FLASH_F7_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_L0: + optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + optlock_shift = STM32L0_FLASH_OPTLOCK; + break; + case STLINK_FLASH_TYPE_L4: + optcr_reg = STM32L4_FLASH_CR; + optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_WB: + optcr_reg = STM32WB_FLASH_CR; + optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_H7: + optcr_reg = FLASH_H7_OPTCR; + optlock_shift = FLASH_H7_OPTCR_OPTLOCK; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) + optcr2_reg = FLASH_H7_OPTCR2; + break; + default: + ELOG("unsupported flash method, abort\n"); + return -1; + } + + stlink_read_debug32(sl, optcr_reg, &n); + + if (active_bit_level == 0) { + n &= ~(1u << optlock_shift); + } else { + n |= (1u << optlock_shift); + } + + stlink_write_debug32(sl, optcr_reg, n); + + if (optcr2_reg) { + stlink_read_debug32(sl, optcr2_reg, &n); if (active_bit_level == 0) { - n &= ~(1u << optlock_shift); + n &= ~(1u << optlock_shift); } else { - n |= (1u << optlock_shift); + n |= (1u << optlock_shift); } - stlink_write_debug32(sl, optcr_reg, n); + stlink_write_debug32(sl, optcr2_reg, n); + } - if (optcr2_reg) { - stlink_read_debug32(sl, optcr2_reg, &n); - - if (active_bit_level == 0) { - n &= ~(1u << optlock_shift); - } else { - n |= (1u << optlock_shift); - } - - stlink_write_debug32(sl, optcr2_reg, n); - } - - return(0); + return (0); } static int unlock_flash_option(stlink_t *sl) { - uint32_t optkey_reg, optkey2_reg = 0; - uint32_t optkey1 = FLASH_OPTKEY1; - uint32_t optkey2 = FLASH_OPTKEY2; - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - optkey_reg = FLASH_OPTKEYR; - optkey1 = FLASH_F0_OPTKEY1; - optkey2 = FLASH_F0_OPTKEY2; - break; - case STLINK_FLASH_TYPE_F4: - optkey_reg = FLASH_F4_OPT_KEYR; - break; - case STLINK_FLASH_TYPE_F7: - optkey_reg = FLASH_F7_OPT_KEYR; - break; - case STLINK_FLASH_TYPE_L0: - optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; - optkey1 = FLASH_L0_OPTKEY1; - optkey2 = FLASH_L0_OPTKEY2; - break; - case STLINK_FLASH_TYPE_L4: - optkey_reg = STM32L4_FLASH_OPTKEYR; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optkey_reg = STM32Gx_FLASH_OPTKEYR; - break; - case STLINK_FLASH_TYPE_WB: - optkey_reg = STM32WB_FLASH_OPT_KEYR; - break; - case STLINK_FLASH_TYPE_H7: - optkey_reg = FLASH_H7_OPT_KEYR; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) - optkey2_reg = FLASH_H7_OPT_KEYR2; - break; - default: - ELOG("unsupported flash method, abort\n"); - return(-1); - } - - stlink_write_debug32(sl, optkey_reg, optkey1); - stlink_write_debug32(sl, optkey_reg, optkey2); - - if (optkey2_reg) { - stlink_write_debug32(sl, optkey2_reg, optkey1); - stlink_write_debug32(sl, optkey2_reg, optkey2); - } - - return(0); + uint32_t optkey_reg, optkey2_reg = 0; + uint32_t optkey1 = FLASH_OPTKEY1; + uint32_t optkey2 = FLASH_OPTKEY2; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optkey_reg = FLASH_OPTKEYR; + optkey1 = FLASH_F0_OPTKEY1; + optkey2 = FLASH_F0_OPTKEY2; + break; + case STLINK_FLASH_TYPE_F4: + optkey_reg = FLASH_F4_OPT_KEYR; + break; + case STLINK_FLASH_TYPE_F7: + optkey_reg = FLASH_F7_OPT_KEYR; + break; + case STLINK_FLASH_TYPE_L0: + optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; + optkey1 = FLASH_L0_OPTKEY1; + optkey2 = FLASH_L0_OPTKEY2; + break; + case STLINK_FLASH_TYPE_L4: + optkey_reg = STM32L4_FLASH_OPTKEYR; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optkey_reg = STM32Gx_FLASH_OPTKEYR; + break; + case STLINK_FLASH_TYPE_WB: + optkey_reg = STM32WB_FLASH_OPT_KEYR; + break; + case STLINK_FLASH_TYPE_H7: + optkey_reg = FLASH_H7_OPT_KEYR; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) + optkey2_reg = FLASH_H7_OPT_KEYR2; + break; + default: + ELOG("unsupported flash method, abort\n"); + return (-1); + } + + stlink_write_debug32(sl, optkey_reg, optkey1); + stlink_write_debug32(sl, optkey_reg, optkey2); + + if (optkey2_reg) { + stlink_write_debug32(sl, optkey2_reg, optkey1); + stlink_write_debug32(sl, optkey2_reg, optkey2); + } + + return (0); } static int unlock_flash_option_if(stlink_t *sl) { - if (is_flash_option_locked(sl)) { - if (unlock_flash_option(sl)) { - ELOG("Could not unlock flash option!\n"); - return(-1); - } + if (is_flash_option_locked(sl)) { + if (unlock_flash_option(sl)) { + ELOG("Could not unlock flash option!\n"); + return (-1); + } - if (is_flash_option_locked(sl)) { - ELOG("Failed to unlock flash option!\n"); - return(-1); - } + if (is_flash_option_locked(sl)) { + ELOG("Failed to unlock flash option!\n"); + return (-1); } + } - DLOG("Successfully unlocked flash option\n"); - return(0); + DLOG("Successfully unlocked flash option\n"); + return (0); } static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { - uint32_t cr_reg, x; - - x = read_flash_cr(sl, bank); - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - x &= ~STM32L4_FLASH_CR_OPBITS; - x |= (1 << STM32L4_FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; - x |= (1 << FLASH_H7_CR_PG); - } else { - cr_reg = FLASH_CR; - x = (1 << FLASH_CR_PG); - } - - stlink_write_debug32(sl, cr_reg, x); + uint32_t cr_reg, x; + + x = read_flash_cr(sl, bank); + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + x |= 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + x |= 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + x &= ~STM32L4_FLASH_CR_OPBITS; + x |= (1 << STM32L4_FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + x |= (1 << FLASH_H7_CR_PG); + } else { + cr_reg = FLASH_CR; + x = (1 << FLASH_CR_PG); + } + + stlink_write_debug32(sl, cr_reg, x); } static void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { - uint32_t cr_reg, n; - uint32_t bit = FLASH_CR_PG; - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; - bit = FLASH_H7_CR_PG; - } else { - cr_reg = FLASH_CR; - } - - n = read_flash_cr(sl, bank) & ~(1 << bit); - stlink_write_debug32(sl, cr_reg, n); + uint32_t cr_reg, n; + uint32_t bit = FLASH_CR_PG; + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + bit = FLASH_H7_CR_PG; + } else { + cr_reg = FLASH_CR; + } + + n = read_flash_cr(sl, bank) & ~(1 << bit); + stlink_write_debug32(sl, cr_reg, n); } static void set_flash_cr_per(stlink_t *sl, unsigned bank) { - uint32_t cr_reg, val; + uint32_t cr_reg, val; - if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - } else { - cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; - } + if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + } - stlink_read_debug32(sl, cr_reg, &val); - val |= (1 << FLASH_CR_PER); - stlink_write_debug32(sl, cr_reg, val); + stlink_read_debug32(sl, cr_reg, &val); + val |= (1 << FLASH_CR_PER); + stlink_write_debug32(sl, cr_reg, val); } static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { - uint32_t cr_reg; + uint32_t cr_reg; - if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - } else { - cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; - } + if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + } - const uint32_t n = read_flash_cr(sl, bank) & ~(1 << FLASH_CR_PER); - stlink_write_debug32(sl, cr_reg, n); + const uint32_t n = read_flash_cr(sl, bank) & ~(1 << FLASH_CR_PER); + stlink_write_debug32(sl, cr_reg, n); } static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { - uint32_t val, cr_reg, cr_mer, cr_pg; - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - cr_mer = 1 << FLASH_CR_MER; - cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_mer = 1 << FLASH_CR_MER; - cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); - cr_pg = (1 << STM32L4_FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_mer = (1 << STM32Gx_FLASH_CR_MER1); - - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); - } - - cr_pg = (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - cr_mer = (1 << FLASH_CR_MER); - cr_pg = (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank==BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; - cr_mer = (1 << FLASH_H7_CR_BER); - cr_pg = (1 << FLASH_H7_CR_PG); - } else { - cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; - cr_mer = (1 << FLASH_CR_MER); - cr_pg = (1 << FLASH_CR_PG); - } - - stlink_read_debug32(sl, cr_reg, &val); - - if (val & cr_pg) { - // STM32F030 will drop MER bit if PG was set - val &= ~cr_pg; - stlink_write_debug32(sl, cr_reg, val); - } + uint32_t val, cr_reg, cr_mer, cr_pg; + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_mer = 1 << FLASH_CR_MER; + cr_pg = 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_mer = 1 << FLASH_CR_MER; + cr_pg = 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); + cr_pg = (1 << STM32L4_FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_mer = (1 << STM32Gx_FLASH_CR_MER1); + + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); + } + + cr_pg = (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + cr_mer = (1 << FLASH_H7_CR_BER); + cr_pg = (1 << FLASH_H7_CR_PG); + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); + } + + stlink_read_debug32(sl, cr_reg, &val); + + if (val & cr_pg) { + // STM32F030 will drop MER bit if PG was set + val &= ~cr_pg; + stlink_write_debug32(sl, cr_reg, val); + } - if (v) { - val |= cr_mer; - } else { - val &= ~cr_mer; - } + if (v) { + val |= cr_mer; + } else { + val &= ~cr_mer; + } - stlink_write_debug32(sl, cr_reg, val); + stlink_write_debug32(sl, cr_reg, val); } static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { - uint32_t val, cr_reg, cr_strt; - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - cr_strt = 1 << FLASH_F4_CR_STRT; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_strt = 1 << FLASH_F7_CR_STRT; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_strt = (1 << STM32L4_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_strt = (1 << STM32Gx_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - cr_strt = (1 << STM32WB_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank==BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; - cr_strt = 1 << FLASH_H7_CR_START(sl->chip_id); - } else { - cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; - cr_strt = (1 << FLASH_CR_STRT); - } - - stlink_read_debug32(sl, cr_reg, &val); - val |= cr_strt; - stlink_write_debug32(sl, cr_reg, val); + uint32_t val, cr_reg, cr_strt; + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_strt = 1 << FLASH_F4_CR_STRT; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_strt = 1 << FLASH_F7_CR_STRT; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_strt = (1 << STM32L4_FLASH_CR_STRT); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_strt = (1 << STM32Gx_FLASH_CR_STRT); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_strt = (1 << STM32WB_FLASH_CR_STRT); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + cr_strt = 1 << FLASH_H7_CR_START(sl->chip_id); + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + cr_strt = (1 << FLASH_CR_STRT); + } + + stlink_read_debug32(sl, cr_reg, &val); + val |= cr_strt; + stlink_write_debug32(sl, cr_reg, val); } static inline uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { - uint32_t res, sr_reg; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - sr_reg = (bank==BANK_1)?FLASH_SR:FLASH_SR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - sr_reg = FLASH_F4_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - sr_reg = STM32L4_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - sr_reg = STM32Gx_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - sr_reg = STM32WB_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - sr_reg = (bank==BANK_1)?FLASH_H7_SR1:FLASH_H7_SR2; - } else { - ELOG("method 'read_flash_sr' is unsupported\n"); - return(-1); - } - - stlink_read_debug32(sl, sr_reg, &res); - return(res); + uint32_t res, sr_reg; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + sr_reg = FLASH_F4_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_reg = FLASH_F7_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + sr_reg = STM32L4_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + sr_reg = STM32Gx_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + sr_reg = STM32WB_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; + } else { + ELOG("method 'read_flash_sr' is unsupported\n"); + return (-1); + } + + stlink_read_debug32(sl, sr_reg, &res); + return (res); } static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { - uint32_t sr_reg; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - sr_reg = (bank==BANK_1)?FLASH_SR:FLASH_SR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - sr_reg = FLASH_F4_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - sr_reg = STM32L4_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - sr_reg = STM32Gx_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - sr_reg = STM32WB_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - sr_reg = (bank==BANK_1)?FLASH_H7_SR1:FLASH_H7_SR2; - } else { - ELOG("method 'write_flash_sr' is unsupported\n"); - return(-1); - } - - return stlink_write_debug32(sl, sr_reg, val); + uint32_t sr_reg; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + sr_reg = FLASH_F4_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_reg = FLASH_F7_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + sr_reg = STM32L4_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + sr_reg = STM32Gx_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + sr_reg = STM32WB_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; + } else { + ELOG("method 'write_flash_sr' is unsupported\n"); + return (-1); + } + + return stlink_write_debug32(sl, sr_reg, val); } static inline unsigned int is_flash_busy(stlink_t *sl) { - uint32_t sr_busy_shift; - unsigned int res; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || - (sl->flash_type == STLINK_FLASH_TYPE_L0)) { - sr_busy_shift = FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - sr_busy_shift = FLASH_F4_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - sr_busy_shift = FLASH_F7_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - sr_busy_shift = STM32L4_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - sr_busy_shift = STM32Gx_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - sr_busy_shift = STM32WB_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - sr_busy_shift = FLASH_H7_SR_QW; - } else { - ELOG("method 'is_flash_busy' is unsupported\n"); - return(-1); - } - - res = read_flash_sr(sl, BANK_1) & (1 << sr_busy_shift); - - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { - res |= read_flash_sr(sl, BANK_2) & (1 << sr_busy_shift); - } - - return(res); + uint32_t sr_busy_shift; + unsigned int res; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || + (sl->flash_type == STLINK_FLASH_TYPE_L0)) { + sr_busy_shift = FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + sr_busy_shift = FLASH_F4_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_busy_shift = FLASH_F7_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + sr_busy_shift = STM32L4_FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + sr_busy_shift = STM32Gx_FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + sr_busy_shift = STM32WB_FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_busy_shift = FLASH_H7_SR_QW; + } else { + ELOG("method 'is_flash_busy' is unsupported\n"); + return (-1); + } + + res = read_flash_sr(sl, BANK_1) & (1 << sr_busy_shift); + + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || + (sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { + res |= read_flash_sr(sl, BANK_2) & (1 << sr_busy_shift); + } + + return (res); } static void wait_flash_busy(stlink_t *sl) { - // TODO: add some delays here - while (is_flash_busy(sl)) - ; + // TODO: add some delays here + while (is_flash_busy(sl)) + ; } static void wait_flash_busy_progress(stlink_t *sl) { - int i = 0; - fprintf(stdout, "Mass erasing"); - fflush(stdout); - - while (is_flash_busy(sl)) { - usleep(10000); - i++; - - if (i % 100 == 0) { - fprintf(stdout, "."); - fflush(stdout); - } - } - - fprintf(stdout, "\n"); -} - -static void clear_flash_error(stlink_t *sl) -{ - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_F4: - write_flash_sr(sl, BANK_1, FLASH_F4_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_F7: - write_flash_sr(sl, BANK_1, FLASH_F7_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_L0: - write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_L4: - write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_H7: - write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_sr(sl, BANK_2, FLASH_H7_SR_ERROR_MASK); - } - break; - case STLINK_FLASH_TYPE_WB: - write_flash_sr(sl, BANK_1, STM32WB_FLASH_SR_ERROR_MASK); - break; - default: - break; - } -} - -static int check_flash_error(stlink_t *sl) -{ - uint32_t res = 0; - uint32_t WRPERR, PROGERR, PGAERR; - - WRPERR = PROGERR = PGAERR = 0; - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - res |= read_flash_sr(sl, BANK_2) & FLASH_SR_ERROR_MASK; - } - WRPERR = (1 << FLASH_SR_WRPRT_ERR); - PROGERR = (1 << FLASH_SR_PG_ERR); - break; - case STLINK_FLASH_TYPE_F4: - res = read_flash_sr(sl, BANK_1) & FLASH_F4_SR_ERROR_MASK; - WRPERR = (1 << FLASH_F4_SR_WRPERR); - PGAERR = (1 << FLASH_F4_SR_PGAERR); - break; - case STLINK_FLASH_TYPE_F7: - res = read_flash_sr(sl, BANK_1) & FLASH_F7_SR_ERROR_MASK; - WRPERR = (1 << FLASH_F7_SR_WRP_ERR); - PROGERR = (1 << FLASH_F7_SR_PGP_ERR); - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32Gx_FLASH_SR_WRPERR); - PROGERR = (1 << STM32Gx_FLASH_SR_PROGERR); - PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); - break; - case STLINK_FLASH_TYPE_L0: - res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); - PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); - PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); - break; - case STLINK_FLASH_TYPE_L4: - res = read_flash_sr(sl, BANK_1) & STM32L4_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32L4_FLASH_SR_WRPERR); - PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); - PGAERR = (1 << STM32L4_FLASH_SR_PGAERR); - break; - case STLINK_FLASH_TYPE_H7: - res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; - } - WRPERR = (1 << FLASH_H7_SR_WRPERR); - break; - case STLINK_FLASH_TYPE_WB: - res = read_flash_sr(sl, BANK_1) & STM32WB_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32WB_FLASH_SR_WRPERR); - PROGERR = (1 << STM32WB_FLASH_SR_PROGERR); - PGAERR = (1 << STM32WB_FLASH_SR_PGAERR); - break; - default: - break; + int i = 0; + fprintf(stdout, "Mass erasing"); + fflush(stdout); + + while (is_flash_busy(sl)) { + usleep(10000); + i++; + + if (i % 100 == 0) { + fprintf(stdout, "."); + fflush(stdout); + } + } + + fprintf(stdout, "\n"); +} + +static void clear_flash_error(stlink_t *sl) { + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_F4: + write_flash_sr(sl, BANK_1, FLASH_F4_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_F7: + write_flash_sr(sl, BANK_1, FLASH_F7_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_L0: + write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_L4: + write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_H7: + write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_sr(sl, BANK_2, FLASH_H7_SR_ERROR_MASK); + } + break; + case STLINK_FLASH_TYPE_WB: + write_flash_sr(sl, BANK_1, STM32WB_FLASH_SR_ERROR_MASK); + break; + default: + break; + } +} + +static int check_flash_error(stlink_t *sl) { + uint32_t res = 0; + uint32_t WRPERR, PROGERR, PGAERR; + + WRPERR = PROGERR = PGAERR = 0; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + res |= read_flash_sr(sl, BANK_2) & FLASH_SR_ERROR_MASK; + } + WRPERR = (1 << FLASH_SR_WRPRT_ERR); + PROGERR = (1 << FLASH_SR_PG_ERR); + break; + case STLINK_FLASH_TYPE_F4: + res = read_flash_sr(sl, BANK_1) & FLASH_F4_SR_ERROR_MASK; + WRPERR = (1 << FLASH_F4_SR_WRPERR); + PGAERR = (1 << FLASH_F4_SR_PGAERR); + break; + case STLINK_FLASH_TYPE_F7: + res = read_flash_sr(sl, BANK_1) & FLASH_F7_SR_ERROR_MASK; + WRPERR = (1 << FLASH_F7_SR_WRP_ERR); + PROGERR = (1 << FLASH_F7_SR_PGP_ERR); + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32Gx_FLASH_SR_WRPERR); + PROGERR = (1 << STM32Gx_FLASH_SR_PROGERR); + PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); + break; + case STLINK_FLASH_TYPE_L0: + res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); + PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); + PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); + break; + case STLINK_FLASH_TYPE_L4: + res = read_flash_sr(sl, BANK_1) & STM32L4_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32L4_FLASH_SR_WRPERR); + PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); + PGAERR = (1 << STM32L4_FLASH_SR_PGAERR); + break; + case STLINK_FLASH_TYPE_H7: + res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; + } + WRPERR = (1 << FLASH_H7_SR_WRPERR); + break; + case STLINK_FLASH_TYPE_WB: + res = read_flash_sr(sl, BANK_1) & STM32WB_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32WB_FLASH_SR_WRPERR); + PROGERR = (1 << STM32WB_FLASH_SR_PROGERR); + PGAERR = (1 << STM32WB_FLASH_SR_PGAERR); + break; + default: + break; + } + + if (res) { + if (WRPERR && (WRPERR & res) == WRPERR) { + ELOG("Flash memory is write protected\n"); + res &= ~WRPERR; + } else if (PROGERR && (PROGERR & res) == PROGERR) { + ELOG("Flash memory contains a non-erased value\n"); + res &= ~PROGERR; + } else if (PGAERR && (PGAERR & res) == PGAERR) { + ELOG("Invalid flash address\n"); + res &= ~PGAERR; } if (res) { - if (WRPERR && (WRPERR&res)==WRPERR) { - ELOG("Flash memory is write protected\n"); - res &= ~WRPERR; - } else if (PROGERR && (PROGERR&res)==PROGERR) { - ELOG("Flash memory contains a non-erased value\n"); - res &= ~PROGERR; - } else if (PGAERR && (PGAERR&res)==PGAERR) { - ELOG("Invalid flash address\n"); - res &= ~PGAERR; - } - - if (res) { - ELOG("Flash programming error: %#010x\n", res); - } - return(-1); + ELOG("Flash programming error: %#010x\n", res); } + return (-1); + } - return(0); + return (0); } static void stop_wdg_in_debug(stlink_t *sl) { - uint32_t dbgmcu_cr; - uint32_t set; - uint32_t value; - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - case STLINK_FLASH_TYPE_G4: - dbgmcu_cr = STM32F0_DBGMCU_CR; - set = (1<flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - rcc = STM32F1_RCC_AHBENR; - rcc_dma_mask = STM32F1_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_F4: - case STLINK_FLASH_TYPE_F7: - rcc = STM32F4_RCC_AHB1ENR; - rcc_dma_mask = STM32F4_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_G0: - rcc = STM32G0_RCC_AHBENR; - rcc_dma_mask = STM32G0_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_G4: - case STLINK_FLASH_TYPE_L4: - rcc = STM32G4_RCC_AHB1ENR; - rcc_dma_mask = STM32G4_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_L0: - rcc = STM32L0_RCC_AHBENR; - rcc_dma_mask = STM32L0_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_H7: - rcc = STM32H7_RCC_AHB1ENR; - rcc_dma_mask = STM32H7_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_WB: - rcc = STM32WB_RCC_AHB1ENR; - rcc_dma_mask = STM32WB_RCC_DMAEN; - break; - default: - return; - } + uint32_t dbgmcu_cr; + uint32_t set; + uint32_t value; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + case STLINK_FLASH_TYPE_G4: + dbgmcu_cr = STM32F0_DBGMCU_CR; + set = + (1 << STM32F0_DBGMCU_CR_IWDG_STOP) | (1 << STM32F0_DBGMCU_CR_WWDG_STOP); + break; + case STLINK_FLASH_TYPE_F4: + case STLINK_FLASH_TYPE_F7: + case STLINK_FLASH_TYPE_L4: + dbgmcu_cr = STM32F4_DBGMCU_APB1FZR1; + set = (1 << STM32F4_DBGMCU_APB1FZR1_IWDG_STOP) | + (1 << STM32F4_DBGMCU_APB1FZR1_WWDG_STOP); + break; + case STLINK_FLASH_TYPE_L0: + case STLINK_FLASH_TYPE_G0: + dbgmcu_cr = STM32L0_DBGMCU_APB1_FZ; + set = (1 << STM32L0_DBGMCU_APB1_FZ_IWDG_STOP) | + (1 << STM32L0_DBGMCU_APB1_FZ_WWDG_STOP); + break; + case STLINK_FLASH_TYPE_H7: + dbgmcu_cr = STM32H7_DBGMCU_APB1HFZ; + set = (1 << STM32H7_DBGMCU_APB1HFZ_IWDG_STOP); + break; + case STLINK_FLASH_TYPE_WB: + dbgmcu_cr = STM32WB_DBGMCU_APB1FZR1; + set = (1 << STM32WB_DBGMCU_APB1FZR1_IWDG_STOP) | + (1 << STM32WB_DBGMCU_APB1FZR1_WWDG_STOP); + break; + default: + return; + } + + if (!stlink_read_debug32(sl, dbgmcu_cr, &value)) { + stlink_write_debug32(sl, dbgmcu_cr, value | set); + } +} + +static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { + uint32_t rcc, rcc_dma_mask, value; + + rcc = rcc_dma_mask = value = 0; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + rcc = STM32F1_RCC_AHBENR; + rcc_dma_mask = STM32F1_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_F4: + case STLINK_FLASH_TYPE_F7: + rcc = STM32F4_RCC_AHB1ENR; + rcc_dma_mask = STM32F4_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_G0: + rcc = STM32G0_RCC_AHBENR; + rcc_dma_mask = STM32G0_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_G4: + case STLINK_FLASH_TYPE_L4: + rcc = STM32G4_RCC_AHB1ENR; + rcc_dma_mask = STM32G4_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_L0: + rcc = STM32L0_RCC_AHBENR; + rcc_dma_mask = STM32L0_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_H7: + rcc = STM32H7_RCC_AHB1ENR; + rcc_dma_mask = STM32H7_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_WB: + rcc = STM32WB_RCC_AHB1ENR; + rcc_dma_mask = STM32WB_RCC_DMAEN; + break; + default: + return; + } - if (!stlink_read_debug32(sl, rcc, &value)) { - if (bckpRstr) { - value = (value&(~rcc_dma_mask)) | fl->rcc_dma_bkp; - } else { - fl->rcc_dma_bkp = value&rcc_dma_mask; - value &= ~rcc_dma_mask; - } - stlink_write_debug32(sl, rcc, value); + if (!stlink_read_debug32(sl, rcc, &value)) { + if (bckpRstr) { + value = (value & (~rcc_dma_mask)) | fl->rcc_dma_bkp; + } else { + fl->rcc_dma_bkp = value & rcc_dma_mask; + value &= ~rcc_dma_mask; } + stlink_write_debug32(sl, rcc, value); + } } static inline void write_flash_ar(stlink_t *sl, uint32_t n, unsigned bank) { - stlink_write_debug32(sl, (bank==BANK_1)?FLASH_AR:FLASH_AR2, n); + stlink_write_debug32(sl, (bank == BANK_1) ? FLASH_AR : FLASH_AR2, n); } -static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n, unsigned bank) { - uint32_t cr_reg, psize_shift; - uint32_t x = read_flash_cr(sl, bank); +static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n, + unsigned bank) { + uint32_t cr_reg, psize_shift; + uint32_t x = read_flash_cr(sl, bank); - if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank==BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; - psize_shift = FLASH_H7_CR_PSIZE; - } else { - cr_reg = FLASH_F4_CR; - psize_shift = 8; - } + if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + psize_shift = FLASH_H7_CR_PSIZE; + } else { + cr_reg = FLASH_F4_CR; + psize_shift = 8; + } - x &= ~(0x03 << psize_shift); - x |= (n << psize_shift); + x &= ~(0x03 << psize_shift); + x |= (n << psize_shift); #if DEBUG_FLASH - fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n); + fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n); #endif - stlink_write_debug32(sl, cr_reg, x); + stlink_write_debug32(sl, cr_reg, x); } static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, unsigned bank) { - uint32_t cr_reg, snb_mask, snb_shift, ser_shift; - uint32_t x = read_flash_cr(sl, bank); - - if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank==BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; - snb_mask = FLASH_H7_CR_SNB_MASK; - snb_shift = FLASH_H7_CR_SNB; - ser_shift = FLASH_H7_CR_SER; - } else { - cr_reg = FLASH_F4_CR; - snb_mask = FLASH_F4_CR_SNB_MASK; - snb_shift = FLASH_F4_CR_SNB; - ser_shift = FLASH_F4_CR_SER; - } - - x &= ~snb_mask; - x |= (n << snb_shift); - x |= (1 << ser_shift); + uint32_t cr_reg, snb_mask, snb_shift, ser_shift; + uint32_t x = read_flash_cr(sl, bank); + + if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + snb_mask = FLASH_H7_CR_SNB_MASK; + snb_shift = FLASH_H7_CR_SNB; + ser_shift = FLASH_H7_CR_SER; + } else { + cr_reg = FLASH_F4_CR; + snb_mask = FLASH_F4_CR_SNB_MASK; + snb_shift = FLASH_F4_CR_SNB; + ser_shift = FLASH_F4_CR_SER; + } + + x &= ~snb_mask; + x |= (n << snb_shift); + x |= (1 << ser_shift); #if DEBUG_FLASH - fprintf(stdout, "SNB:0x%x 0x%x\n", x, n); + fprintf(stdout, "SNB:0x%x 0x%x\n", x, n); #endif - stlink_write_debug32(sl, cr_reg, x); + stlink_write_debug32(sl, cr_reg, x); } static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { - stlink_write_debug32(sl, STM32L4_FLASH_SR, 0xFFFFFFFF & ~(1 << STM32L4_FLASH_SR_BSY)); - uint32_t x = read_flash_cr(sl, BANK_1); - x &= ~STM32L4_FLASH_CR_OPBITS; - x &= ~STM32L4_FLASH_CR_PAGEMASK; - x &= ~(1 << STM32L4_FLASH_CR_MER1); - x &= ~(1 << STM32L4_FLASH_CR_MER2); - x |= (n << STM32L4_FLASH_CR_PNB); - x |= (uint32_t)(1lu << STM32L4_FLASH_CR_PER); + stlink_write_debug32(sl, STM32L4_FLASH_SR, + 0xFFFFFFFF & ~(1 << STM32L4_FLASH_SR_BSY)); + uint32_t x = read_flash_cr(sl, BANK_1); + x &= ~STM32L4_FLASH_CR_OPBITS; + x &= ~STM32L4_FLASH_CR_PAGEMASK; + x &= ~(1 << STM32L4_FLASH_CR_MER1); + x &= ~(1 << STM32L4_FLASH_CR_MER2); + x |= (n << STM32L4_FLASH_CR_PNB); + x |= (uint32_t)(1lu << STM32L4_FLASH_CR_PER); #if DEBUG_FLASH - fprintf(stdout, "BKER:PNB:0x%x 0x%x\n", x, n); + fprintf(stdout, "BKER:PNB:0x%x 0x%x\n", x, n); #endif - stlink_write_debug32(sl, STM32L4_FLASH_CR, x); + stlink_write_debug32(sl, STM32L4_FLASH_CR, x); } // Delegates to the backends... void stlink_close(stlink_t *sl) { - DLOG("*** stlink_close ***\n"); + DLOG("*** stlink_close ***\n"); - if (!sl) { - return; - } + if (!sl) { + return; + } - sl->backend->close(sl); - free(sl); + sl->backend->close(sl); + free(sl); } int stlink_exit_debug_mode(stlink_t *sl) { - int ret; + int ret; - DLOG("*** stlink_exit_debug_mode ***\n"); - ret = stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); + DLOG("*** stlink_exit_debug_mode ***\n"); + ret = stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); - if (ret == -1) { - return(ret); - } + if (ret == -1) { + return (ret); + } - return(sl->backend->exit_debug_mode(sl)); + return (sl->backend->exit_debug_mode(sl)); } int stlink_enter_swd_mode(stlink_t *sl) { - DLOG("*** stlink_enter_swd_mode ***\n"); - return(sl->backend->enter_swd_mode(sl)); + DLOG("*** stlink_enter_swd_mode ***\n"); + return (sl->backend->enter_swd_mode(sl)); } // Force the core into the debug mode -> halted state. int stlink_force_debug(stlink_t *sl) { - DLOG("*** stlink_force_debug_mode ***\n"); - int res = sl->backend->force_debug(sl); - // Stop the watchdogs in the halted state for suppress target reboot - stop_wdg_in_debug(sl); - return(res); + DLOG("*** stlink_force_debug_mode ***\n"); + int res = sl->backend->force_debug(sl); + // Stop the watchdogs in the halted state for suppress target reboot + stop_wdg_in_debug(sl); + return (res); } int stlink_exit_dfu_mode(stlink_t *sl) { - DLOG("*** stlink_exit_dfu_mode ***\n"); - return(sl->backend->exit_dfu_mode(sl)); + DLOG("*** stlink_exit_dfu_mode ***\n"); + return (sl->backend->exit_dfu_mode(sl)); } int stlink_core_id(stlink_t *sl) { - int ret; + int ret; - DLOG("*** stlink_core_id ***\n"); - ret = sl->backend->core_id(sl); + DLOG("*** stlink_core_id ***\n"); + ret = sl->backend->core_id(sl); - if (ret == -1) { - ELOG("Failed to read core_id\n"); - return(ret); - } + if (ret == -1) { + ELOG("Failed to read core_id\n"); + return (ret); + } - if (sl->verbose > 2) { - stlink_print_data(sl); - } + if (sl->verbose > 2) { + stlink_print_data(sl); + } - DLOG("core_id = 0x%08x\n", sl->core_id); - return(ret); + DLOG("core_id = 0x%08x\n", sl->core_id); + return (ret); } // stlink_chip_id() is called by stlink_load_device_params() // do not call this procedure directly. int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { - int ret; - cortex_m3_cpuid_t cpu_id; - - // Read the CPU ID to determine where to read the core id - if (stlink_cpu_id(sl, &cpu_id) || - cpu_id.implementer_id != STLINK_REG_CMx_CPUID_IMPL_ARM) { - ELOG("Can not connect to target. Please use \'connect under reset\' and try again\n"); - return -1; - } - - /* - * the chip_id register in the reference manual have - * DBGMCU_IDCODE / DBG_IDCODE name - * - */ - - if ((sl->core_id == STM32H7_CORE_ID || - sl->core_id == STM32H7_CORE_ID_JTAG) && - cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { - // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) - ret = stlink_read_debug32(sl, 0x5c001000, chip_id); - } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0 || - cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0P) { - // STM32F0 (RM0091, pg914; RM0360, pg713) - // STM32L0 (RM0377, pg813; RM0367, pg915; RM0376, pg917) - // STM32G0 (RM0444, pg1367) - ret = stlink_read_debug32(sl, 0x40015800, chip_id); - } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM33) { - // STM32L5 (RM0438, pg2157) - ret = stlink_read_debug32(sl, 0xE0044000, chip_id); - } else /* СM3, СM4, CM7 */ { - // default chipid address - - // STM32F1 (RM0008, pg1087; RM0041, pg681) - // STM32F2 (RM0033, pg1326) - // STM32F3 (RM0316, pg1095; RM0313, pg874) - // STM32F7 (RM0385, pg1676; RM0410, pg1912) - // STM32L1 (RM0038, pg861) - // STM32L4 (RM0351, pg1840; RM0394, pg1560) - // STM32G4 (RM0440, pg2086) - // STM32WB (RM0434, pg1406) - ret = stlink_read_debug32(sl, 0xE0042000, chip_id); - } - - if (ret || !(*chip_id)) { - *chip_id = 0; - ELOG("Could not find chip id!\n"); - } else { - *chip_id = (*chip_id) & 0xfff; - - // Fix chip_id for F4 rev A errata, read CPU ID, as CoreID is the same for F2/F4 - if (*chip_id == 0x411 && cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM4) { - *chip_id = 0x413; - } - } - - return(ret); + int ret; + cortex_m3_cpuid_t cpu_id; + + // Read the CPU ID to determine where to read the core id + if (stlink_cpu_id(sl, &cpu_id) || + cpu_id.implementer_id != STLINK_REG_CMx_CPUID_IMPL_ARM) { + ELOG("Can not connect to target. Please use \'connect under reset\' and " + "try again\n"); + return -1; + } + + /* + * the chip_id register in the reference manual have + * DBGMCU_IDCODE / DBG_IDCODE name + * + */ + + if ((sl->core_id == STM32H7_CORE_ID || sl->core_id == STM32H7_CORE_ID_JTAG) && + cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { + // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) + ret = stlink_read_debug32(sl, 0x5c001000, chip_id); + } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0 || + cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0P) { + // STM32F0 (RM0091, pg914; RM0360, pg713) + // STM32L0 (RM0377, pg813; RM0367, pg915; RM0376, pg917) + // STM32G0 (RM0444, pg1367) + ret = stlink_read_debug32(sl, 0x40015800, chip_id); + } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM33) { + // STM32L5 (RM0438, pg2157) + ret = stlink_read_debug32(sl, 0xE0044000, chip_id); + } else /* СM3, СM4, CM7 */ { + // default chipid address + + // STM32F1 (RM0008, pg1087; RM0041, pg681) + // STM32F2 (RM0033, pg1326) + // STM32F3 (RM0316, pg1095; RM0313, pg874) + // STM32F7 (RM0385, pg1676; RM0410, pg1912) + // STM32L1 (RM0038, pg861) + // STM32L4 (RM0351, pg1840; RM0394, pg1560) + // STM32G4 (RM0440, pg2086) + // STM32WB (RM0434, pg1406) + ret = stlink_read_debug32(sl, 0xE0042000, chip_id); + } + + if (ret || !(*chip_id)) { + *chip_id = 0; + ELOG("Could not find chip id!\n"); + } else { + *chip_id = (*chip_id) & 0xfff; + + // Fix chip_id for F4 rev A errata, read CPU ID, as CoreID is the same for + // F2/F4 + if (*chip_id == 0x411 && cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM4) { + *chip_id = 0x413; + } + } + + return (ret); } /** @@ -1553,21 +1558,21 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { * @param cpuid pointer to the result object */ int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { - uint32_t raw; - - if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &raw)) { - cpuid->implementer_id = 0; - cpuid->variant = 0; - cpuid->part = 0; - cpuid->revision = 0; - return(-1); - } + uint32_t raw; - cpuid->implementer_id = (raw >> 24) & 0x7f; - cpuid->variant = (raw >> 20) & 0xf; - cpuid->part = (raw >> 4) & 0xfff; - cpuid->revision = raw & 0xf; - return(0); + if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &raw)) { + cpuid->implementer_id = 0; + cpuid->variant = 0; + cpuid->part = 0; + cpuid->revision = 0; + return (-1); + } + + cpuid->implementer_id = (raw >> 24) & 0x7f; + cpuid->variant = (raw >> 20) & 0xf; + cpuid->part = (raw >> 4) & 0xfff; + cpuid->revision = raw & 0xf; + return (0); } /** @@ -1576,256 +1581,269 @@ int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { * @return 0 for success, or -1 for unsupported core type. */ int stlink_load_device_params(stlink_t *sl) { - // This seems to normally work so is unnecessary info for a normal user. - // Demoted to debug. -- REW - DLOG("Loading device parameters....\n"); - const struct stlink_chipid_params *params = NULL; - stlink_core_id(sl); - uint32_t flash_size; - - if (stlink_chip_id(sl, &sl->chip_id)) { - return(-1); - } + // This seems to normally work so is unnecessary info for a normal user. + // Demoted to debug. -- REW + DLOG("Loading device parameters....\n"); + const struct stlink_chipid_params *params = NULL; + stlink_core_id(sl); + uint32_t flash_size; + + if (stlink_chip_id(sl, &sl->chip_id)) { + return (-1); + } + + params = stlink_chipid_get_params(sl->chip_id); + + if (params == NULL) { + WLOG("unknown chip id! %#x\n", sl->chip_id); + return (-1); + } + + if (params->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { + WLOG("Invalid flash type, please check device declaration\n"); + sl->flash_size = 0; + return (0); + } + + // These are fixed... + sl->flash_base = STM32_FLASH_BASE; + sl->sram_base = STM32_SRAM_BASE; + stlink_read_debug32(sl, (params->flash_size_reg) & ~3, &flash_size); + + if (params->flash_size_reg & 2) { + flash_size = flash_size >> 16; + } + + flash_size = flash_size & 0xffff; + + if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || + sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW || + sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS) && + (flash_size == 0)) { + sl->flash_size = 128 * 1024; + } else if (sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2) { + sl->flash_size = (flash_size & 0xff) * 1024; + } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_HIGH) { + // 0 is 384k and 1 is 256k + if (flash_size == 0) { + sl->flash_size = 384 * 1024; + } else { + sl->flash_size = 256 * 1024; + } + } else { + sl->flash_size = flash_size * 1024; + } + + sl->flash_type = params->flash_type; + sl->flash_pgsz = params->flash_pagesize; + sl->sram_size = params->sram_size; + sl->sys_base = params->bootrom_base; + sl->sys_size = params->bootrom_size; + sl->option_base = params->option_base; + sl->option_size = params->option_size; + sl->chip_flags = params->flags; + + // medium and low devices have the same chipid. ram size depends on flash + // size. STM32F100xx datasheet Doc ID 16455 Table 2 + if (sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW && + sl->flash_size < 64 * 1024) { + sl->sram_size = 0x1000; + } + + if (sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3) { + uint32_t flash_optr; + stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); + + if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { + sl->flash_pgsz <<= 1; + } + } + + // H7 devices with small flash has one bank + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK && + sl->flash_type == STLINK_FLASH_TYPE_H7) { + if ((flash_size / sl->flash_pgsz) <= 1) + sl->chip_flags &= ~CHIP_F_HAS_DUAL_BANK; + } + + ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", + params->description, (unsigned)(sl->sram_size / 1024), + (unsigned)(sl->flash_size / 1024), + (sl->flash_pgsz < 1024) ? (unsigned)(sl->flash_pgsz) + : (unsigned)(sl->flash_pgsz / 1024), + (sl->flash_pgsz < 1024) ? "byte" : "KiB"); + + return (0); +} - params = stlink_chipid_get_params(sl->chip_id); +int stlink_jtag_reset(stlink_t *sl, int value) { + DLOG("*** stlink_jtag_reset ***\n"); + return (sl->backend->jtag_reset(sl, value)); +} - if (params == NULL) { - WLOG("unknown chip id! %#x\n", sl->chip_id); - return(-1); +int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { + int ret; + unsigned timeout; + uint32_t dhcsr, dfsr; + + DLOG("*** stlink_soft_reset %s***\n", halt_on_reset ? "(halt) " : ""); + + // halt core and enable debugging (if not already done) + // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_DEBUGEN); + + // enable Halt on reset by set VC_CORERESET and TRCENA (DDI0337E, p. 10-10) + if (halt_on_reset) { + stlink_write_debug32( + sl, STLINK_REG_CM3_DEMCR, + STLINK_REG_CM3_DEMCR_TRCENA | STLINK_REG_CM3_DEMCR_VC_HARDERR | + STLINK_REG_CM3_DEMCR_VC_BUSERR | STLINK_REG_CM3_DEMCR_VC_CORERESET); + + // clear VCATCH in the DFSR register + stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_VCATCH); + } else { + stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, + STLINK_REG_CM3_DEMCR_TRCENA | + STLINK_REG_CM3_DEMCR_VC_HARDERR | + STLINK_REG_CM3_DEMCR_VC_BUSERR); + } + + // clear S_RESET_ST in the DHCSR register + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + + // soft reset (core reset) by SYSRESETREQ (DDI0337E, p. 8-23) + ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, + STLINK_REG_AIRCR_VECTKEY | + STLINK_REG_AIRCR_SYSRESETREQ); + if (ret) { + ELOG("Soft reset failed: error write to AIRCR\n"); + return (ret); + } + + // waiting for a reset within 500ms + // DDI0337E, p. 10-4, Debug Halting Control and Status Register + timeout = time_ms() + 500; + while (time_ms() < timeout) { + // DDI0337E, p. 10-4, Debug Halting Control and Status Register + dhcsr = STLINK_REG_DHCSR_S_RESET_ST; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + if (halt_on_reset) { + // waiting halt by the SYSRESETREQ exception + // DDI0403E, p. C1-699, Debug Fault Status Register + dfsr = 0; + stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); + if ((dfsr & STLINK_REG_DFSR_VCATCH) == 0) { + continue; + } + } + timeout = 0; + break; } + } - if (params->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { - WLOG("Invalid flash type, please check device declaration\n"); - sl->flash_size = 0; - return(0); - } + // reset DFSR register. DFSR is power-on reset only (DDI0337H, p. 7-5) + stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_CLEAR); - // These are fixed... - sl->flash_base = STM32_FLASH_BASE; - sl->sram_base = STM32_SRAM_BASE; - stlink_read_debug32(sl, (params->flash_size_reg) & ~3, &flash_size); + if (timeout) { + ELOG("Soft reset failed: timeout\n"); + return (-1); + } - if (params->flash_size_reg & 2) { - flash_size = flash_size >> 16; - } + return (0); +} - flash_size = flash_size & 0xffff; - - if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || - sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW || - sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS) && (flash_size == 0)) { - sl->flash_size = 128 * 1024; - } else if (sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2) { - sl->flash_size = (flash_size & 0xff) * 1024; - } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_HIGH) { - // 0 is 384k and 1 is 256k - if (flash_size == 0) { - sl->flash_size = 384 * 1024; - } else { - sl->flash_size = 256 * 1024; - } - } else { - sl->flash_size = flash_size * 1024; - } +int stlink_reset(stlink_t *sl, enum reset_type type) { + uint32_t dhcsr; + unsigned timeout; + + DLOG("*** stlink_reset ***\n"); + + if (type == RESET_AUTO) { + // clear S_RESET_ST in DHCSR register for reset state detection + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + } - sl->flash_type = params->flash_type; - sl->flash_pgsz = params->flash_pagesize; - sl->sram_size = params->sram_size; - sl->sys_base = params->bootrom_base; - sl->sys_size = params->bootrom_size; - sl->option_base = params->option_base; - sl->option_size = params->option_size; - sl->chip_flags = params->flags; - - // medium and low devices have the same chipid. ram size depends on flash size. - // STM32F100xx datasheet Doc ID 16455 Table 2 - if (sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW && sl->flash_size < 64 * 1024) { - sl->sram_size = 0x1000; + if (type == RESET_HARD || type == RESET_AUTO) { + // hardware target reset + if (sl->version.stlink_v > 1) { + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); + // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) + usleep(100); + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); + } + if (sl->backend->reset(sl)) { + return (-1); } + usleep(10000); + } - if (sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3) { - uint32_t flash_optr; - stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); + if (type == RESET_AUTO) { + /* Check if the S_RESET_ST bit is set in DHCSR + * This means that a reset has occurred + * DDI0337E, p. 10-4, Debug Halting Control and Status Register */ + + dhcsr = 0; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + // reset not done yet + // try reset through AIRCR so that NRST does not need to be connected - if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { sl->flash_pgsz <<= 1; } + WLOG("NRST is not connected\n"); + DLOG("Using reset through SYSRESETREQ\n"); + return stlink_soft_reset(sl, 0); } - // H7 devices with small flash has one bank - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK && sl->flash_type == STLINK_FLASH_TYPE_H7) { - if ((flash_size/sl->flash_pgsz) <= 1) - sl->chip_flags &= ~CHIP_F_HAS_DUAL_BANK; + // waiting for reset the S_RESET_ST bit within 500ms + timeout = time_ms() + 500; + while (time_ms() < timeout) { + dhcsr = STLINK_REG_DHCSR_S_RESET_ST; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) + return (0); } - ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", - params->description, (unsigned)(sl->sram_size / 1024), (unsigned)(sl->flash_size / 1024), - (sl->flash_pgsz < 1024) ? (unsigned)(sl->flash_pgsz) : (unsigned)(sl->flash_pgsz / 1024), - (sl->flash_pgsz < 1024) ? "byte" : "KiB"); + return (-1); + } - return(0); + if (type == RESET_SOFT || type == RESET_SOFT_AND_HALT) { + return stlink_soft_reset(sl, (type == RESET_SOFT_AND_HALT)); + } + + return (0); } +int stlink_run(stlink_t *sl, enum run_type type) { + struct stlink_reg rr; + DLOG("*** stlink_run ***\n"); + + /* Make sure we are in Thumb mode + * Cortex-M chips don't support ARM mode instructions + * xPSR may be incorrect if the vector table has invalid data */ + stlink_read_reg(sl, 16, &rr); + if ((rr.xpsr & (1 << 24)) == 0) { + ILOG("Go to Thumb mode\n"); + stlink_write_reg(sl, rr.xpsr | (1 << 24), 16); + } -int stlink_jtag_reset(stlink_t *sl, int value) { - DLOG("*** stlink_jtag_reset ***\n"); - return(sl->backend->jtag_reset(sl, value)); + return (sl->backend->run(sl, type)); } -int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { - int ret; - unsigned timeout; - uint32_t dhcsr, dfsr; - - DLOG("*** stlink_soft_reset %s***\n", halt_on_reset?"(halt) ":""); +int stlink_set_swdclk(stlink_t *sl, int freq_khz) { + DLOG("*** set_swdclk ***\n"); + return (sl->backend->set_swdclk(sl, freq_khz)); +} - // halt core and enable debugging (if not already done) - // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) - stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | - STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_DEBUGEN); +int stlink_status(stlink_t *sl) { + int ret; - // enable Halt on reset by set VC_CORERESET and TRCENA (DDI0337E, p. 10-10) - if (halt_on_reset) { - stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, STLINK_REG_CM3_DEMCR_TRCENA | - STLINK_REG_CM3_DEMCR_VC_HARDERR | STLINK_REG_CM3_DEMCR_VC_BUSERR | - STLINK_REG_CM3_DEMCR_VC_CORERESET); - - // clear VCATCH in the DFSR register - stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_VCATCH); - } else { - stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, STLINK_REG_CM3_DEMCR_TRCENA | - STLINK_REG_CM3_DEMCR_VC_HARDERR | STLINK_REG_CM3_DEMCR_VC_BUSERR); - } - - // clear S_RESET_ST in the DHCSR register - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - - // soft reset (core reset) by SYSRESETREQ (DDI0337E, p. 8-23) - ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | - STLINK_REG_AIRCR_SYSRESETREQ); - if (ret) { - ELOG("Soft reset failed: error write to AIRCR\n"); - return(ret); - } - - // waiting for a reset within 500ms - // DDI0337E, p. 10-4, Debug Halting Control and Status Register - timeout = time_ms() + 500; - while (time_ms() < timeout) { - // DDI0337E, p. 10-4, Debug Halting Control and Status Register - dhcsr = STLINK_REG_DHCSR_S_RESET_ST; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) { - if (halt_on_reset) { - // waiting halt by the SYSRESETREQ exception - // DDI0403E, p. C1-699, Debug Fault Status Register - dfsr = 0; - stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); - if ((dfsr&STLINK_REG_DFSR_VCATCH) == 0) { - continue; - } - } - timeout = 0; - break; - } - } - - // reset DFSR register. DFSR is power-on reset only (DDI0337H, p. 7-5) - stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_CLEAR); - - if (timeout) { - ELOG("Soft reset failed: timeout\n"); - return(-1); - } - - return(0); -} - -int stlink_reset(stlink_t *sl, enum reset_type type) { - uint32_t dhcsr; - unsigned timeout; - - DLOG("*** stlink_reset ***\n"); - - if (type == RESET_AUTO) { - // clear S_RESET_ST in DHCSR register for reset state detection - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - } - - if (type == RESET_HARD || type == RESET_AUTO) { - // hardware target reset - if (sl->version.stlink_v > 1) { - stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); - // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) - usleep(100); - stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); - } - if (sl->backend->reset(sl)) { return(-1); } - usleep(10000); - } - - if (type == RESET_AUTO) { - /* Check if the S_RESET_ST bit is set in DHCSR - * This means that a reset has occurred - * DDI0337E, p. 10-4, Debug Halting Control and Status Register */ - - dhcsr = 0; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { - // reset not done yet - // try reset through AIRCR so that NRST does not need to be connected - - WLOG("NRST is not connected\n"); - DLOG("Using reset through SYSRESETREQ\n"); - return stlink_soft_reset(sl, 0); - } - - // waiting for reset the S_RESET_ST bit within 500ms - timeout = time_ms() + 500; - while (time_ms() < timeout) { - dhcsr = STLINK_REG_DHCSR_S_RESET_ST; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) - return(0); - } - - return(-1); - } - - if (type == RESET_SOFT || type == RESET_SOFT_AND_HALT) { - return stlink_soft_reset(sl, (type==RESET_SOFT_AND_HALT)); - } - - return(0); -} - -int stlink_run(stlink_t *sl, enum run_type type) { - struct stlink_reg rr; - DLOG("*** stlink_run ***\n"); - - /* Make sure we are in Thumb mode - * Cortex-M chips don't support ARM mode instructions - * xPSR may be incorrect if the vector table has invalid data */ - stlink_read_reg(sl, 16, &rr); - if ((rr.xpsr & (1 << 24)) == 0) { - ILOG("Go to Thumb mode\n"); - stlink_write_reg(sl, rr.xpsr | (1 << 24), 16); - } - - return(sl->backend->run(sl, type)); -} - -int stlink_set_swdclk(stlink_t *sl, int freq_khz) { - DLOG("*** set_swdclk ***\n"); - return(sl->backend->set_swdclk(sl, freq_khz)); -} - -int stlink_status(stlink_t *sl) { - int ret; - - DLOG("*** stlink_status ***\n"); - ret = sl->backend->status(sl); - stlink_core_stat(sl); - return(ret); -} + DLOG("*** stlink_status ***\n"); + ret = sl->backend->status(sl); + stlink_core_stat(sl); + return (ret); +} /** * Decode the version bits, originally from -sg, verified with usb @@ -1833,1109 +1851,1192 @@ int stlink_status(stlink_t *sl) { * @param slv output parsed version object */ void _parse_version(stlink_t *sl, stlink_version_t *slv) { - sl->version.flags = 0; - - if (sl->version.stlink_v < 3) { - uint32_t b0 = sl->q_buf[0]; // lsb - uint32_t b1 = sl->q_buf[1]; - uint32_t b2 = sl->q_buf[2]; - uint32_t b3 = sl->q_buf[3]; - uint32_t b4 = sl->q_buf[4]; - uint32_t b5 = sl->q_buf[5]; // msb - - // b0 b1 || b2 b3 | b4 b5 - // 4b | 6b | 6b || 2B | 2B - // stlink_v | jtag_v | swim_v || st_vid | stlink_pid - - slv->stlink_v = (b0 & 0xf0) >> 4; - slv->jtag_v = ((b0 & 0x0f) << 2) | ((b1 & 0xc0) >> 6); - slv->swim_v = b1 & 0x3f; - slv->st_vid = (b3 << 8) | b2; - slv->stlink_pid = (b5 << 8) | b4; - - // ST-LINK/V1 from J11 switch to api-v2 (and support SWD) - if (slv->stlink_v == 1) { - slv->jtag_api = slv->jtag_v > 11 ? STLINK_JTAG_API_V2 : STLINK_JTAG_API_V1; - } else { - slv->jtag_api = STLINK_JTAG_API_V2; - - // preferred API to get last R/W status from J15 - if (sl->version.jtag_v >= 15) { - sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; - } - - if (sl->version.jtag_v >= 13) { - sl->version.flags |= STLINK_F_HAS_TRACE; - sl->max_trace_freq = STLINK_V2_MAX_TRACE_FREQUENCY; - } - } + sl->version.flags = 0; + + if (sl->version.stlink_v < 3) { + uint32_t b0 = sl->q_buf[0]; // lsb + uint32_t b1 = sl->q_buf[1]; + uint32_t b2 = sl->q_buf[2]; + uint32_t b3 = sl->q_buf[3]; + uint32_t b4 = sl->q_buf[4]; + uint32_t b5 = sl->q_buf[5]; // msb + + // b0 b1 || b2 b3 | b4 b5 + // 4b | 6b | 6b || 2B | 2B + // stlink_v | jtag_v | swim_v || st_vid | stlink_pid + + slv->stlink_v = (b0 & 0xf0) >> 4; + slv->jtag_v = ((b0 & 0x0f) << 2) | ((b1 & 0xc0) >> 6); + slv->swim_v = b1 & 0x3f; + slv->st_vid = (b3 << 8) | b2; + slv->stlink_pid = (b5 << 8) | b4; + + // ST-LINK/V1 from J11 switch to api-v2 (and support SWD) + if (slv->stlink_v == 1) { + slv->jtag_api = + slv->jtag_v > 11 ? STLINK_JTAG_API_V2 : STLINK_JTAG_API_V1; } else { - // V3 uses different version format, for reference see OpenOCD source - // (that was written from docs available from ST under NDA): - // https://github.com/ntfreak/openocd/blob/a6dacdff58ef36fcdac00c53ec27f19de1fbce0d/src/jtag/drivers/stlink_usb.c#L965 - slv->stlink_v = sl->q_buf[0]; - slv->swim_v = sl->q_buf[1]; - slv->jtag_v = sl->q_buf[2]; - slv->st_vid = (uint32_t)((sl->q_buf[9] << 8) | sl->q_buf[8]); - slv->stlink_pid = (uint32_t)((sl->q_buf[11] << 8) | sl->q_buf[10]); - slv->jtag_api = STLINK_JTAG_API_V3; - /* preferred API to get last R/W status */ + slv->jtag_api = STLINK_JTAG_API_V2; + + // preferred API to get last R/W status from J15 + if (sl->version.jtag_v >= 15) { sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; - sl->version.flags |= STLINK_F_HAS_TRACE; - sl->max_trace_freq = STLINK_V3_MAX_TRACE_FREQUENCY; - } + } - return; + if (sl->version.jtag_v >= 13) { + sl->version.flags |= STLINK_F_HAS_TRACE; + sl->max_trace_freq = STLINK_V2_MAX_TRACE_FREQUENCY; + } + } + } else { + // V3 uses different version format, for reference see OpenOCD source + // (that was written from docs available from ST under NDA): + // https://github.com/ntfreak/openocd/blob/a6dacdff58ef36fcdac00c53ec27f19de1fbce0d/src/jtag/drivers/stlink_usb.c#L965 + slv->stlink_v = sl->q_buf[0]; + slv->swim_v = sl->q_buf[1]; + slv->jtag_v = sl->q_buf[2]; + slv->st_vid = (uint32_t)((sl->q_buf[9] << 8) | sl->q_buf[8]); + slv->stlink_pid = (uint32_t)((sl->q_buf[11] << 8) | sl->q_buf[10]); + slv->jtag_api = STLINK_JTAG_API_V3; + /* preferred API to get last R/W status */ + sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; + sl->version.flags |= STLINK_F_HAS_TRACE; + sl->max_trace_freq = STLINK_V3_MAX_TRACE_FREQUENCY; + } + + return; } int stlink_version(stlink_t *sl) { - DLOG("*** looking up stlink version\n"); + DLOG("*** looking up stlink version\n"); - if (sl->backend->version(sl)) { - return(-1); - } + if (sl->backend->version(sl)) { + return (-1); + } - _parse_version(sl, &sl->version); + _parse_version(sl, &sl->version); - DLOG("st vid = 0x%04x (expect 0x%04x)\n", sl->version.st_vid, STLINK_USB_VID_ST); - DLOG("stlink pid = 0x%04x\n", sl->version.stlink_pid); - DLOG("stlink version = 0x%x\n", sl->version.stlink_v); - DLOG("jtag version = 0x%x\n", sl->version.jtag_v); - DLOG("swim version = 0x%x\n", sl->version.swim_v); + DLOG("st vid = 0x%04x (expect 0x%04x)\n", sl->version.st_vid, + STLINK_USB_VID_ST); + DLOG("stlink pid = 0x%04x\n", sl->version.stlink_pid); + DLOG("stlink version = 0x%x\n", sl->version.stlink_v); + DLOG("jtag version = 0x%x\n", sl->version.jtag_v); + DLOG("swim version = 0x%x\n", sl->version.swim_v); - if (sl->version.jtag_v == 0) { - DLOG(" notice: the firmware doesn't support a jtag/swd interface\n"); - } + if (sl->version.jtag_v == 0) { + DLOG(" notice: the firmware doesn't support a jtag/swd interface\n"); + } - if (sl->version.swim_v == 0) { - DLOG(" notice: the firmware doesn't support a swim interface\n"); - } + if (sl->version.swim_v == 0) { + DLOG(" notice: the firmware doesn't support a swim interface\n"); + } - return(0); + return (0); } int stlink_target_voltage(stlink_t *sl) { - int voltage = -1; - DLOG("*** reading target voltage\n"); + int voltage = -1; + DLOG("*** reading target voltage\n"); - if (sl->backend->target_voltage != NULL) { - voltage = sl->backend->target_voltage(sl); + if (sl->backend->target_voltage != NULL) { + voltage = sl->backend->target_voltage(sl); - if (voltage != -1) { - DLOG("target voltage = %imV\n", voltage); - } else { - DLOG("error reading target voltage\n"); - } + if (voltage != -1) { + DLOG("target voltage = %imV\n", voltage); } else { - DLOG("reading voltage not supported by backend\n"); + DLOG("error reading target voltage\n"); } + } else { + DLOG("reading voltage not supported by backend\n"); + } - return(voltage); + return (voltage); } int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { - int ret; + int ret; - ret = sl->backend->read_debug32(sl, addr, data); - if (!ret) - DLOG("*** stlink_read_debug32 %#010x at %#010x\n", *data, addr); + ret = sl->backend->read_debug32(sl, addr, data); + if (!ret) + DLOG("*** stlink_read_debug32 %#010x at %#010x\n", *data, addr); - return(ret); + return (ret); } int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { - DLOG("*** stlink_write_debug32 %#010x to %#010x\n", data, addr); - return sl->backend->write_debug32(sl, addr, data); + DLOG("*** stlink_write_debug32 %#010x to %#010x\n", data, addr); + return sl->backend->write_debug32(sl, addr, data); } int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); + DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); - if (len % 4 != 0) { - ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); - return(-1); - } + if (len % 4 != 0) { + ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); + return (-1); + } - return(sl->backend->write_mem32(sl, addr, len)); + return (sl->backend->write_mem32(sl, addr, len)); } int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_read_mem32 ***\n"); + DLOG("*** stlink_read_mem32 ***\n"); - if (len % 4 != 0) { // !!! never ever: fw gives just wrong values - ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); - return(-1); - } + if (len % 4 != 0) { // !!! never ever: fw gives just wrong values + ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); + return (-1); + } - return(sl->backend->read_mem32(sl, addr, len)); + return (sl->backend->read_mem32(sl, addr, len)); } int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_write_mem8 ***\n"); + DLOG("*** stlink_write_mem8 ***\n"); - if (len > 0x40) { // !!! never ever: Writing more then 0x40 bytes gives unexpected behaviour - ELOG("Data length > 64: +%d byte.\n", len); - return(-1); - } + if (len > 0x40) { // !!! never ever: Writing more then 0x40 bytes gives + // unexpected behaviour + ELOG("Data length > 64: +%d byte.\n", len); + return (-1); + } - return(sl->backend->write_mem8(sl, addr, len)); + return (sl->backend->write_mem8(sl, addr, len)); } int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { - DLOG("*** stlink_read_all_regs ***\n"); - return(sl->backend->read_all_regs(sl, regp)); + DLOG("*** stlink_read_all_regs ***\n"); + return (sl->backend->read_all_regs(sl, regp)); } int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { - DLOG("*** stlink_read_all_unsupported_regs ***\n"); - return(sl->backend->read_all_unsupported_regs(sl, regp)); + DLOG("*** stlink_read_all_unsupported_regs ***\n"); + return (sl->backend->read_all_unsupported_regs(sl, regp)); } int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) { - DLOG("*** stlink_write_reg\n"); - return(sl->backend->write_reg(sl, reg, idx)); + DLOG("*** stlink_write_reg\n"); + return (sl->backend->write_reg(sl, reg, idx)); } int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { - DLOG("*** stlink_read_reg\n"); - DLOG(" (%d) ***\n", r_idx); + DLOG("*** stlink_read_reg\n"); + DLOG(" (%d) ***\n", r_idx); - if (r_idx > 20 || r_idx < 0) { - fprintf(stderr, "Error: register index must be in [0..20]\n"); - return(-1); - } + if (r_idx > 20 || r_idx < 0) { + fprintf(stderr, "Error: register index must be in [0..20]\n"); + return (-1); + } - return(sl->backend->read_reg(sl, r_idx, regp)); + return (sl->backend->read_reg(sl, r_idx, regp)); } -int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { - int r_convert; +int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, + struct stlink_reg *regp) { + int r_convert; - DLOG("*** stlink_read_unsupported_reg\n"); - DLOG(" (%d) ***\n", r_idx); + DLOG("*** stlink_read_unsupported_reg\n"); + DLOG(" (%d) ***\n", r_idx); - /* Convert to values used by STLINK_REG_DCRSR */ - if (r_idx >= 0x1C && r_idx <= 0x1F) { // primask, basepri, faultmask, or control - r_convert = 0x14; - } else if (r_idx == 0x40) { // FPSCR - r_convert = 0x21; - } else if (r_idx >= 0x20 && r_idx < 0x40) { - r_convert = 0x40 + (r_idx - 0x20); - } else { - fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); - return(-1); - } + /* Convert to values used by STLINK_REG_DCRSR */ + if (r_idx >= 0x1C && + r_idx <= 0x1F) { // primask, basepri, faultmask, or control + r_convert = 0x14; + } else if (r_idx == 0x40) { // FPSCR + r_convert = 0x21; + } else if (r_idx >= 0x20 && r_idx < 0x40) { + r_convert = 0x40 + (r_idx - 0x20); + } else { + fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); + return (-1); + } - return(sl->backend->read_unsupported_reg(sl, r_convert, regp)); + return (sl->backend->read_unsupported_reg(sl, r_convert, regp)); } -int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, struct stlink_reg *regp) { - int r_convert; +int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, + struct stlink_reg *regp) { + int r_convert; - DLOG("*** stlink_write_unsupported_reg\n"); - DLOG(" (%d) ***\n", r_idx); + DLOG("*** stlink_write_unsupported_reg\n"); + DLOG(" (%d) ***\n", r_idx); - /* Convert to values used by STLINK_REG_DCRSR */ - if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ - r_convert = r_idx; // the backend function handles this - } else if (r_idx == 0x40) { // FPSCR - r_convert = 0x21; - } else if (r_idx >= 0x20 && r_idx < 0x40) { - r_convert = 0x40 + (r_idx - 0x20); - } else { - fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); - return(-1); - } + /* Convert to values used by STLINK_REG_DCRSR */ + if (r_idx >= 0x1C && + r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ + r_convert = r_idx; // the backend function handles this + } else if (r_idx == 0x40) { // FPSCR + r_convert = 0x21; + } else if (r_idx >= 0x20 && r_idx < 0x40) { + r_convert = 0x40 + (r_idx - 0x20); + } else { + fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); + return (-1); + } - return(sl->backend->write_unsupported_reg(sl, val, r_convert, regp)); + return (sl->backend->write_unsupported_reg(sl, val, r_convert, regp)); } bool stlink_is_core_halted(stlink_t *sl) { - stlink_status(sl); - return(sl->core_stat == TARGET_HALTED); + stlink_status(sl); + return (sl->core_stat == TARGET_HALTED); } int stlink_step(stlink_t *sl) { - DLOG("*** stlink_step ***\n"); - return(sl->backend->step(sl)); + DLOG("*** stlink_step ***\n"); + return (sl->backend->step(sl)); } int stlink_current_mode(stlink_t *sl) { - int mode = sl->backend->current_mode(sl); - - switch (mode) { - case STLINK_DEV_DFU_MODE: - DLOG("stlink current mode: dfu\n"); - return(mode); - case STLINK_DEV_DEBUG_MODE: - DLOG("stlink current mode: debug (jtag or swd)\n"); - return(mode); - case STLINK_DEV_MASS_MODE: - DLOG("stlink current mode: mass\n"); - return(mode); - } + int mode = sl->backend->current_mode(sl); - DLOG("stlink mode: unknown!\n"); - return(STLINK_DEV_UNKNOWN_MODE); -} + switch (mode) { + case STLINK_DEV_DFU_MODE: + DLOG("stlink current mode: dfu\n"); + return (mode); + case STLINK_DEV_DEBUG_MODE: + DLOG("stlink current mode: debug (jtag or swd)\n"); + return (mode); + case STLINK_DEV_MASS_MODE: + DLOG("stlink current mode: mass\n"); + return (mode); + } -int stlink_trace_enable(stlink_t* sl, uint32_t frequency) { - DLOG("*** stlink_trace_enable ***\n"); - return(sl->backend->trace_enable(sl, frequency)); + DLOG("stlink mode: unknown!\n"); + return (STLINK_DEV_UNKNOWN_MODE); } -int stlink_trace_disable(stlink_t* sl) { - DLOG("*** stlink_trace_disable ***\n"); - return(sl->backend->trace_disable(sl)); +int stlink_trace_enable(stlink_t *sl, uint32_t frequency) { + DLOG("*** stlink_trace_enable ***\n"); + return (sl->backend->trace_enable(sl, frequency)); } -int stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size) { - return(sl->backend->trace_read(sl, buf, size)); +int stlink_trace_disable(stlink_t *sl) { + DLOG("*** stlink_trace_disable ***\n"); + return (sl->backend->trace_disable(sl)); } +int stlink_trace_read(stlink_t *sl, uint8_t *buf, size_t size) { + return (sl->backend->trace_read(sl, buf, size)); +} // End of delegates.... Common code below here... - - // same as above with entrypoint. void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { - stlink_write_reg(sl, addr, 15); /* pc register */ - stlink_run(sl, RUN_NORMAL); + stlink_write_reg(sl, addr, 15); /* pc register */ + stlink_run(sl, RUN_NORMAL); - while (stlink_is_core_halted(sl)) { usleep(3000000); } + while (stlink_is_core_halted(sl)) { + usleep(3000000); + } } - // this function is called by stlink_status() // do not call stlink_core_stat() directly, always use stlink_status() void stlink_core_stat(stlink_t *sl) { - switch (sl->core_stat ) { - case TARGET_RUNNING: - DLOG(" core status: running\n"); - return; - case TARGET_HALTED: - DLOG(" core status: halted\n"); - return; - case TARGET_RESET: - DLOG(" core status: reset\n"); - return; - case TARGET_DEBUG_RUNNING: - DLOG(" core status: debug running\n"); - return; - default: - DLOG(" core status: unknown\n"); - } + switch (sl->core_stat) { + case TARGET_RUNNING: + DLOG(" core status: running\n"); + return; + case TARGET_HALTED: + DLOG(" core status: halted\n"); + return; + case TARGET_RESET: + DLOG(" core status: reset\n"); + return; + case TARGET_DEBUG_RUNNING: + DLOG(" core status: debug running\n"); + return; + default: + DLOG(" core status: unknown\n"); + } } -void stlink_print_data(stlink_t * sl) { - if (sl->q_len <= 0 || sl->verbose < UDEBUG) { return; } +void stlink_print_data(stlink_t *sl) { + if (sl->q_len <= 0 || sl->verbose < UDEBUG) { + return; + } - if (sl->verbose > 2) { DLOG("data_len = %d 0x%x\n", sl->q_len, sl->q_len); } + if (sl->verbose > 2) { + DLOG("data_len = %d 0x%x\n", sl->q_len, sl->q_len); + } - for (int i = 0; i < sl->q_len; i++) { - if (i % 16 == 0) { - /* - if (sl->q_data_dir == Q_DATA_OUT) { - fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i); - } else { - fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); - } - */ - } - //DLOG(" %02x", (unsigned int) sl->q_buf[i]); - fprintf(stderr, " %02x", (unsigned int) sl->q_buf[i]); + for (int i = 0; i < sl->q_len; i++) { + if (i % 16 == 0) { + /* + if (sl->q_data_dir == Q_DATA_OUT) { + fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i); + } else { + fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); + } + */ } - //DLOG("\n\n"); - fprintf(stderr, "\n"); + // DLOG(" %02x", (unsigned int) sl->q_buf[i]); + fprintf(stderr, " %02x", (unsigned int)sl->q_buf[i]); + } + // DLOG("\n\n"); + fprintf(stderr, "\n"); } /* Memory mapped file */ typedef struct mapped_file { - uint8_t* base; - size_t len; + uint8_t *base; + size_t len; } mapped_file_t; -#define MAPPED_FILE_INITIALIZER { NULL, 0 } +#define MAPPED_FILE_INITIALIZER \ + { NULL, 0 } -static int map_file(mapped_file_t* mf, const char* path) { - int error = -1; - struct stat st; +static int map_file(mapped_file_t *mf, const char *path) { + int error = -1; + struct stat st; - const int fd = open(path, O_RDONLY | O_BINARY); + const int fd = open(path, O_RDONLY | O_BINARY); - if (fd == -1) { - fprintf(stderr, "open(%s) == -1\n", path); - return(-1); - } + if (fd == -1) { + fprintf(stderr, "open(%s) == -1\n", path); + return (-1); + } - if (fstat(fd, &st) == -1) { - fprintf(stderr, "fstat(%s) == -1\n", path); - goto on_error; - } + if (fstat(fd, &st) == -1) { + fprintf(stderr, "fstat(%s) == -1\n", path); + goto on_error; + } - if (sizeof(st.st_size) != sizeof(size_t)) { - // on 32 bit systems, check if there is an overflow - if (st.st_size > (off_t)INT32_MAX) { - fprintf(stderr, "mmap() size_t overflow for file %s\n", path); - goto on_error; - } + if (sizeof(st.st_size) != sizeof(size_t)) { + // on 32 bit systems, check if there is an overflow + if (st.st_size > (off_t)INT32_MAX) { + fprintf(stderr, "mmap() size_t overflow for file %s\n", path); + goto on_error; } + } - mf->base = (uint8_t*)mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); + mf->base = + (uint8_t *)mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); - if (mf->base == MAP_FAILED) { - fprintf(stderr, "mmap() == MAP_FAILED for file %s\n", path); - goto on_error; - } + if (mf->base == MAP_FAILED) { + fprintf(stderr, "mmap() == MAP_FAILED for file %s\n", path); + goto on_error; + } - mf->len = st.st_size; - error = 0; // success + mf->len = st.st_size; + error = 0; // success on_error: - close(fd); - return(error); + close(fd); + return (error); } -static void unmap_file(mapped_file_t * mf) { - munmap((void*)mf->base, mf->len); - mf->base = (unsigned char*)MAP_FAILED; - mf->len = 0; +static void unmap_file(mapped_file_t *mf) { + munmap((void *)mf->base, mf->len); + mf->base = (unsigned char *)MAP_FAILED; + mf->len = 0; } -/* Limit the block size to compare to 0x1800 as anything larger will stall the STLINK2 - * Maybe STLINK V1 needs smaller value! +/* Limit the block size to compare to 0x1800 as anything larger will stall the + * STLINK2 Maybe STLINK V1 needs smaller value! */ -static int check_file(stlink_t* sl, mapped_file_t* mf, stm32_addr_t addr) { - size_t off; - size_t n_cmp = sl->flash_pgsz; +static int check_file(stlink_t *sl, mapped_file_t *mf, stm32_addr_t addr) { + size_t off; + size_t n_cmp = sl->flash_pgsz; - if ( n_cmp > 0x1800) { n_cmp = 0x1800; } + if (n_cmp > 0x1800) { + n_cmp = 0x1800; + } - for (off = 0; off < mf->len; off += n_cmp) { - size_t aligned_size; + for (off = 0; off < mf->len; off += n_cmp) { + size_t aligned_size; - size_t cmp_size = n_cmp; // adjust last page size + size_t cmp_size = n_cmp; // adjust last page size - if ((off + n_cmp) > mf->len) { cmp_size = mf->len - off; } + if ((off + n_cmp) > mf->len) { + cmp_size = mf->len - off; + } - aligned_size = cmp_size; + aligned_size = cmp_size; - if (aligned_size & (4 - 1)) { aligned_size = (cmp_size + 4) & ~(4 - 1); } + if (aligned_size & (4 - 1)) { + aligned_size = (cmp_size + 4) & ~(4 - 1); + } - stlink_read_mem32(sl, addr + (uint32_t)off, aligned_size); + stlink_read_mem32(sl, addr + (uint32_t)off, aligned_size); - if (memcmp(sl->q_buf, mf->base + off, cmp_size)) { return(-1); } + if (memcmp(sl->q_buf, mf->base + off, cmp_size)) { + return (-1); } + } - return(0); + return (0); } static void md5_calculate(mapped_file_t *mf) { - // calculate md5 checksum of given binary file - Md5Context md5Context; - MD5_HASH md5Hash; - Md5Initialise(&md5Context); - Md5Update(&md5Context, mf->base, (uint32_t)mf->len); - Md5Finalise(&md5Context, &md5Hash); - printf("md5 checksum: "); + // calculate md5 checksum of given binary file + Md5Context md5Context; + MD5_HASH md5Hash; + Md5Initialise(&md5Context); + Md5Update(&md5Context, mf->base, (uint32_t)mf->len); + Md5Finalise(&md5Context, &md5Hash); + printf("md5 checksum: "); - for (int i = 0; i < (int)sizeof(md5Hash); i++) { printf("%x", md5Hash.bytes[i]); } + for (int i = 0; i < (int)sizeof(md5Hash); i++) { + printf("%x", md5Hash.bytes[i]); + } - printf(", "); + printf(", "); } static void stlink_checksum(mapped_file_t *mp) { - /* checksum that backward compatible with official ST tools */ - uint32_t sum = 0; - uint8_t *mp_byte = (uint8_t *)mp->base; + /* checksum that backward compatible with official ST tools */ + uint32_t sum = 0; + uint8_t *mp_byte = (uint8_t *)mp->base; - for (size_t i = 0; i < mp->len; ++i) { sum += mp_byte[i]; } + for (size_t i = 0; i < mp->len; ++i) { + sum += mp_byte[i]; + } - printf("stlink checksum: 0x%08x\n", sum); + printf("stlink checksum: 0x%08x\n", sum); } static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { - unsigned int val; - // set stack - stlink_read_debug32(sl, addr, &val); - stlink_write_reg(sl, val, 13); - // set PC to the reset routine - stlink_read_debug32(sl, addr + 4, &val); - stlink_write_reg(sl, val, 15); - stlink_run(sl, RUN_NORMAL); -} - -int stlink_mwrite_sram(stlink_t * sl, uint8_t* data, uint32_t length, stm32_addr_t addr) { - // write the file in sram at addr - - int error = -1; - size_t off; - size_t len; - - // check addr range is inside the sram - if (addr < sl->sram_base) { - fprintf(stderr, "addr too low\n"); - goto on_error; - } else if ((addr + length) < addr) { - fprintf(stderr, "addr overruns\n"); - goto on_error; - } else if ((addr + length) > (sl->sram_base + sl->sram_size)) { - fprintf(stderr, "addr too high\n"); - goto on_error; - } else if (addr & 3) { - fprintf(stderr, "unaligned addr\n"); - goto on_error; - } - - len = length; - - if (len & 3) { len -= len & 3; } - - // do the copy by 1kB blocks - for (off = 0; off < len; off += 1024) { - size_t size = 1024; - - if ((off + size) > len) { size = len - off; } - - memcpy(sl->q_buf, data + off, size); - - if (size & 3) { size += 2; } // round size if needed - - stlink_write_mem32(sl, addr + (uint32_t)off, size); - } - - if (length > len) { - memcpy(sl->q_buf, data + len, length - len); - stlink_write_mem8(sl, addr + (uint32_t)len, length - len); - } - - - error = 0; // success - stlink_fwrite_finalize(sl, addr); + unsigned int val; + // set stack + stlink_read_debug32(sl, addr, &val); + stlink_write_reg(sl, val, 13); + // set PC to the reset routine + stlink_read_debug32(sl, addr + 4, &val); + stlink_write_reg(sl, val, 15); + stlink_run(sl, RUN_NORMAL); +} + +int stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, + stm32_addr_t addr) { + // write the file in sram at addr + + int error = -1; + size_t off; + size_t len; + + // check addr range is inside the sram + if (addr < sl->sram_base) { + fprintf(stderr, "addr too low\n"); + goto on_error; + } else if ((addr + length) < addr) { + fprintf(stderr, "addr overruns\n"); + goto on_error; + } else if ((addr + length) > (sl->sram_base + sl->sram_size)) { + fprintf(stderr, "addr too high\n"); + goto on_error; + } else if (addr & 3) { + fprintf(stderr, "unaligned addr\n"); + goto on_error; + } + + len = length; + + if (len & 3) { + len -= len & 3; + } + + // do the copy by 1kB blocks + for (off = 0; off < len; off += 1024) { + size_t size = 1024; + + if ((off + size) > len) { + size = len - off; + } + + memcpy(sl->q_buf, data + off, size); + + if (size & 3) { + size += 2; + } // round size if needed + + stlink_write_mem32(sl, addr + (uint32_t)off, size); + } + + if (length > len) { + memcpy(sl->q_buf, data + len, length - len); + stlink_write_mem8(sl, addr + (uint32_t)len, length - len); + } + + error = 0; // success + stlink_fwrite_finalize(sl, addr); on_error: - return(error); + return (error); } -int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { - // write the file in sram at addr +int stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { + // write the file in sram at addr - int error = -1; - size_t off; - size_t len; - mapped_file_t mf = MAPPED_FILE_INITIALIZER; + int error = -1; + size_t off; + size_t len; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; - if (map_file(&mf, path) == -1) { - fprintf(stderr, "map_file() == -1\n"); - return(-1); - } + if (map_file(&mf, path) == -1) { + fprintf(stderr, "map_file() == -1\n"); + return (-1); + } - printf("file %s ", path); - md5_calculate(&mf); - stlink_checksum(&mf); - - // check if addr range is inside the SRAM - if (addr < sl->sram_base) { - fprintf(stderr, "addr too low\n"); - goto on_error; - } else if ((addr + mf.len) < addr) { - fprintf(stderr, "addr overruns\n"); - goto on_error; - } else if ((addr + mf.len) > (sl->sram_base + sl->sram_size)) { - fprintf(stderr, "addr too high\n"); - goto on_error; - } else if (addr & 3) { - fprintf(stderr, "unaligned addr\n"); - goto on_error; - } + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); - len = mf.len; + // check if addr range is inside the SRAM + if (addr < sl->sram_base) { + fprintf(stderr, "addr too low\n"); + goto on_error; + } else if ((addr + mf.len) < addr) { + fprintf(stderr, "addr overruns\n"); + goto on_error; + } else if ((addr + mf.len) > (sl->sram_base + sl->sram_size)) { + fprintf(stderr, "addr too high\n"); + goto on_error; + } else if (addr & 3) { + fprintf(stderr, "unaligned addr\n"); + goto on_error; + } - if (len & 3) { len -= len & 3; } + len = mf.len; - // do the copy by 1kB blocks - for (off = 0; off < len; off += 1024) { - size_t size = 1024; + if (len & 3) { + len -= len & 3; + } - if ((off + size) > len) { size = len - off; } + // do the copy by 1kB blocks + for (off = 0; off < len; off += 1024) { + size_t size = 1024; - memcpy(sl->q_buf, mf.base + off, size); + if ((off + size) > len) { + size = len - off; + } - if (size & 3) { size += 2; } // round size if needed + memcpy(sl->q_buf, mf.base + off, size); - stlink_write_mem32(sl, addr + (uint32_t)off, size); - } + if (size & 3) { + size += 2; + } // round size if needed - if (mf.len > len) { - memcpy(sl->q_buf, mf.base + len, mf.len - len); - stlink_write_mem8(sl, addr + (uint32_t)len, mf.len - len); - } + stlink_write_mem32(sl, addr + (uint32_t)off, size); + } - // check the file has been written - if (check_file(sl, &mf, addr) == -1) { - fprintf(stderr, "check_file() == -1\n"); - goto on_error; - } + if (mf.len > len) { + memcpy(sl->q_buf, mf.base + len, mf.len - len); + stlink_write_mem8(sl, addr + (uint32_t)len, mf.len - len); + } - error = 0; // success - stlink_fwrite_finalize(sl, addr); + // check the file has been written + if (check_file(sl, &mf, addr) == -1) { + fprintf(stderr, "check_file() == -1\n"); + goto on_error; + } + + error = 0; // success + stlink_fwrite_finalize(sl, addr); on_error: - unmap_file(&mf); - return(error); + unmap_file(&mf); + return (error); } -typedef bool (*save_block_fn)(void* arg, uint8_t* block, ssize_t len); +typedef bool (*save_block_fn)(void *arg, uint8_t *block, ssize_t len); -static int stlink_read( - stlink_t* sl, stm32_addr_t addr, size_t size, save_block_fn fn, void* fn_arg) { +static int stlink_read(stlink_t *sl, stm32_addr_t addr, size_t size, + save_block_fn fn, void *fn_arg) { - int error = -1; + int error = -1; - if (size < 1) { size = sl->flash_size; } + if (size < 1) { + size = sl->flash_size; + } - if (size > sl->flash_size) { - size = sl->flash_size; - } + if (size > sl->flash_size) { + size = sl->flash_size; + } - size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; + size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; - for (size_t off = 0; off < size; off += cmp_size) { - size_t aligned_size; + for (size_t off = 0; off < size; off += cmp_size) { + size_t aligned_size; - // adjust last page size - if ((off + cmp_size) > size) { cmp_size = size - off; } + // adjust last page size + if ((off + cmp_size) > size) { + cmp_size = size - off; + } - aligned_size = cmp_size; + aligned_size = cmp_size; - if (aligned_size & (4 - 1)) { aligned_size = (cmp_size + 4) & ~(4 - 1); } + if (aligned_size & (4 - 1)) { + aligned_size = (cmp_size + 4) & ~(4 - 1); + } - stlink_read_mem32(sl, addr + (uint32_t)off, aligned_size); + stlink_read_mem32(sl, addr + (uint32_t)off, aligned_size); - if (!fn(fn_arg, sl->q_buf, aligned_size)) { goto on_error; } + if (!fn(fn_arg, sl->q_buf, aligned_size)) { + goto on_error; } + } - error = 0; // success + error = 0; // success on_error: - return(error); + return (error); } struct stlink_fread_worker_arg { - int fd; + int fd; }; -static bool stlink_fread_worker(void* arg, uint8_t* block, ssize_t len) { - struct stlink_fread_worker_arg* the_arg = (struct stlink_fread_worker_arg*)arg; +static bool stlink_fread_worker(void *arg, uint8_t *block, ssize_t len) { + struct stlink_fread_worker_arg *the_arg = + (struct stlink_fread_worker_arg *)arg; - if (write(the_arg->fd, block, len) != len) { - fprintf(stderr, "write() != aligned_size\n"); - return(false); - } else { - return(true); - } + if (write(the_arg->fd, block, len) != len) { + fprintf(stderr, "write() != aligned_size\n"); + return (false); + } else { + return (true); + } } struct stlink_fread_ihex_worker_arg { - FILE* file; - uint32_t addr; - uint32_t lba; - uint8_t buf[16]; - uint8_t buf_pos; + FILE *file; + uint32_t addr; + uint32_t lba; + uint8_t buf[16]; + uint8_t buf_pos; }; -static bool stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg* the_arg) { - uint32_t addr = the_arg->addr; - uint8_t sum = 2 + 4 + (uint8_t)((addr & 0xFF000000) >> 24) + (uint8_t)((addr & 0x00FF0000) >> 16); +static bool +stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg *the_arg) { + uint32_t addr = the_arg->addr; + uint8_t sum = 2 + 4 + (uint8_t)((addr & 0xFF000000) >> 24) + + (uint8_t)((addr & 0x00FF0000) >> 16); - if (17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", (addr & 0xFFFF0000) >> 16, - (uint8_t)(0x100 - sum))) { - return(false); - } + if (17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", + (addr & 0xFFFF0000) >> 16, (uint8_t)(0x100 - sum))) { + return (false); + } - the_arg->lba = (addr & 0xFFFF0000); - return(true); + the_arg->lba = (addr & 0xFFFF0000); + return (true); } -static bool stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg* the_arg) { - uint8_t count = the_arg->buf_pos; +static bool +stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg *the_arg) { + uint8_t count = the_arg->buf_pos; - if (count == 0) { return(true); } + if (count == 0) { + return (true); + } - uint32_t addr = the_arg->addr; + uint32_t addr = the_arg->addr; - if (the_arg->lba != (addr & 0xFFFF0000)) { // segment changed - if (!stlink_fread_ihex_newsegment(the_arg)) { - return(false); - } + if (the_arg->lba != (addr & 0xFFFF0000)) { // segment changed + if (!stlink_fread_ihex_newsegment(the_arg)) { + return (false); } + } - uint8_t sum = count + (uint8_t)((addr & 0x0000FF00) >> 8) + (uint8_t)(addr & 0x000000FF); + uint8_t sum = count + (uint8_t)((addr & 0x0000FF00) >> 8) + + (uint8_t)(addr & 0x000000FF); - if (9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) { - return(false); - } + if (9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) { + return (false); + } - for (uint8_t i = 0; i < count; ++i) { - uint8_t b = the_arg->buf[i]; - sum += b; + for (uint8_t i = 0; i < count; ++i) { + uint8_t b = the_arg->buf[i]; + sum += b; - if (2 != fprintf(the_arg->file, "%02X", b)) { - return(false); - } + if (2 != fprintf(the_arg->file, "%02X", b)) { + return (false); } + } - if (4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) { - return(false); - } + if (4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) { + return (false); + } - the_arg->addr += count; - the_arg->buf_pos = 0; + the_arg->addr += count; + the_arg->buf_pos = 0; - return(true); + return (true); } -static bool stlink_fread_ihex_init( - struct stlink_fread_ihex_worker_arg* the_arg, int fd, stm32_addr_t addr) { - the_arg->file = fdopen(fd, "w"); - the_arg->addr = addr; - the_arg->lba = 0; - the_arg->buf_pos = 0; +static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg *the_arg, + int fd, stm32_addr_t addr) { + the_arg->file = fdopen(fd, "w"); + the_arg->addr = addr; + the_arg->lba = 0; + the_arg->buf_pos = 0; - return (the_arg->file != NULL); + return (the_arg->file != NULL); } -static bool stlink_fread_ihex_worker(void* arg, uint8_t* block, ssize_t len) { - struct stlink_fread_ihex_worker_arg* the_arg = (struct stlink_fread_ihex_worker_arg*)arg; - - for (ssize_t i = 0; i < len; ++i) { - if (the_arg->buf_pos == sizeof(the_arg->buf)) { // line is full - if (!stlink_fread_ihex_writeline(the_arg)) { return(false); } - } +static bool stlink_fread_ihex_worker(void *arg, uint8_t *block, ssize_t len) { + struct stlink_fread_ihex_worker_arg *the_arg = + (struct stlink_fread_ihex_worker_arg *)arg; - the_arg->buf[the_arg->buf_pos++] = block[i]; + for (ssize_t i = 0; i < len; ++i) { + if (the_arg->buf_pos == sizeof(the_arg->buf)) { // line is full + if (!stlink_fread_ihex_writeline(the_arg)) { + return (false); + } } - return(true); + the_arg->buf[the_arg->buf_pos++] = block[i]; + } + + return (true); } -static bool stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg* the_arg) { - if (!stlink_fread_ihex_writeline(the_arg)) { return(false); } +static bool +stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg *the_arg) { + if (!stlink_fread_ihex_writeline(the_arg)) { + return (false); + } - // FIXME: do we need the Start Linear Address? + // FIXME: do we need the Start Linear Address? - if (13 != fprintf(the_arg->file, ":00000001FF\r\n")) { // EoF - return(false); - } + if (13 != fprintf(the_arg->file, ":00000001FF\r\n")) { // EoF + return (false); + } - return (0 == fclose(the_arg->file)); + return (0 == fclose(the_arg->file)); } -int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size) { - // read size bytes from addr to file - ILOG("read from address %#010x size %u\n", addr, (unsigned)size); +int stlink_fread(stlink_t *sl, const char *path, bool is_ihex, + stm32_addr_t addr, size_t size) { + // read size bytes from addr to file + ILOG("read from address %#010x size %u\n", addr, (unsigned)size); - int error; - int fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); + int error; + int fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); - if (fd == -1) { - fprintf(stderr, "open(%s) == -1\n", path); - return(-1); - } + if (fd == -1) { + fprintf(stderr, "open(%s) == -1\n", path); + return (-1); + } - if (is_ihex) { - struct stlink_fread_ihex_worker_arg arg; + if (is_ihex) { + struct stlink_fread_ihex_worker_arg arg; - if (stlink_fread_ihex_init(&arg, fd, addr)) { - error = stlink_read(sl, addr, size, &stlink_fread_ihex_worker, &arg); + if (stlink_fread_ihex_init(&arg, fd, addr)) { + error = stlink_read(sl, addr, size, &stlink_fread_ihex_worker, &arg); - if (!stlink_fread_ihex_finalize(&arg)) { error = -1; } - } else { - error = -1; - } + if (!stlink_fread_ihex_finalize(&arg)) { + error = -1; + } } else { - struct stlink_fread_worker_arg arg = { fd }; - error = stlink_read(sl, addr, size, &stlink_fread_worker, &arg); + error = -1; } + } else { + struct stlink_fread_worker_arg arg = {fd}; + error = stlink_read(sl, addr, size, &stlink_fread_worker, &arg); + } - close(fd); - return(error); + close(fd); + return (error); } -int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size) { - // write the buffer right after the loader - size_t chunk = size & ~0x3; - size_t rem = size & 0x3; +int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, + size_t size) { + // write the buffer right after the loader + size_t chunk = size & ~0x3; + size_t rem = size & 0x3; - if (chunk) { - memcpy(sl->q_buf, buf, chunk); - stlink_write_mem32(sl, fl->buf_addr, chunk); - } + if (chunk) { + memcpy(sl->q_buf, buf, chunk); + stlink_write_mem32(sl, fl->buf_addr, chunk); + } - if (rem) { - memcpy(sl->q_buf, buf + chunk, rem); - stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, rem); - } + if (rem) { + memcpy(sl->q_buf, buf + chunk, rem); + stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, rem); + } - return(0); + return (0); } uint32_t calculate_F4_sectornum(uint32_t flashaddr) { - uint32_t offset = 0; - flashaddr &= ~STM32_FLASH_BASE; // page now holding the actual flash address - - if (flashaddr >= 0x100000) { - offset = 12; - flashaddr -= 0x100000; - } - - if (flashaddr < 0x4000) { - return (offset + 0); - } else if (flashaddr < 0x8000) { - return(offset + 1); - } else if (flashaddr < 0xc000) { - return(offset + 2); - } else if (flashaddr < 0x10000) { - return(offset + 3); - } else if (flashaddr < 0x20000) { - return(offset + 4); - } else { - return(offset + (flashaddr / 0x20000) + 4); - } - + uint32_t offset = 0; + flashaddr &= ~STM32_FLASH_BASE; // page now holding the actual flash address + + if (flashaddr >= 0x100000) { + offset = 12; + flashaddr -= 0x100000; + } + + if (flashaddr < 0x4000) { + return (offset + 0); + } else if (flashaddr < 0x8000) { + return (offset + 1); + } else if (flashaddr < 0xc000) { + return (offset + 2); + } else if (flashaddr < 0x10000) { + return (offset + 3); + } else if (flashaddr < 0x20000) { + return (offset + 4); + } else { + return (offset + (flashaddr / 0x20000) + 4); + } } uint32_t calculate_F7_sectornum(uint32_t flashaddr) { - flashaddr &= ~STM32_FLASH_BASE; // Page now holding the actual flash address - - if (flashaddr < 0x20000) { - return(flashaddr / 0x8000); - } else if (flashaddr < 0x40000) { - return(4); - } else { - return((flashaddr / 0x40000) + 4); - } + flashaddr &= ~STM32_FLASH_BASE; // Page now holding the actual flash address + if (flashaddr < 0x20000) { + return (flashaddr / 0x8000); + } else if (flashaddr < 0x40000) { + return (4); + } else { + return ((flashaddr / 0x40000) + 4); + } } -uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, unsigned bank) { - flashaddr &= ~((bank==BANK_1)?STM32_FLASH_BASE:STM32_H7_FLASH_BANK2_BASE); // sector holding the flash address - return(flashaddr / sl->flash_pgsz); +uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, + unsigned bank) { + flashaddr &= + ~((bank == BANK_1) + ? STM32_FLASH_BASE + : STM32_H7_FLASH_BANK2_BASE); // sector holding the flash address + return (flashaddr / sl->flash_pgsz); } // returns BKER:PNB for the given page address uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { - uint32_t bker = 0; - uint32_t flashopt; - stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); - flashaddr -= STM32_FLASH_BASE; - - if (sl->chip_id == STLINK_CHIPID_STM32_L4 || - sl->chip_id == STLINK_CHIPID_STM32_L496X || - sl->chip_id == STLINK_CHIPID_STM32_L4RX) { - // this chip use dual banked flash - if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { - uint32_t banksize = (uint32_t)sl->flash_size / 2; - - if (flashaddr >= banksize) { - flashaddr -= banksize; - bker = 0x100; - } - } + uint32_t bker = 0; + uint32_t flashopt; + stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); + flashaddr -= STM32_FLASH_BASE; + + if (sl->chip_id == STLINK_CHIPID_STM32_L4 || + sl->chip_id == STLINK_CHIPID_STM32_L496X || + sl->chip_id == STLINK_CHIPID_STM32_L4RX) { + // this chip use dual banked flash + if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { + uint32_t banksize = (uint32_t)sl->flash_size / 2; + + if (flashaddr >= banksize) { + flashaddr -= banksize; + bker = 0x100; + } } + } - // For 1MB chips without the dual-bank option set, the page address will overflow - // into the BKER bit, which gives us the correct bank:page value. - return(bker | flashaddr / (uint32_t)sl->flash_pgsz); + // For 1MB chips without the dual-bank option set, the page address will + // overflow into the BKER bit, which gives us the correct bank:page value. + return (bker | flashaddr / (uint32_t)sl->flash_pgsz); } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { - if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || - (sl->chip_id == STLINK_CHIPID_STM32_F4) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || - (sl->chip_id == STLINK_CHIPID_STM32_F411RE) || - (sl->chip_id == STLINK_CHIPID_STM32_F446) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || - (sl->chip_id == STLINK_CHIPID_STM32_F72XXX) || - (sl->chip_id == STLINK_CHIPID_STM32_F412)) { - uint32_t sector = calculate_F4_sectornum(flashaddr); - - if (sector >= 12) { sector -= 12; } - - if (sector < 4) { - sl->flash_pgsz = 0x4000; - } else if (sector < 5) { - sl->flash_pgsz = 0x10000; - } else { - sl->flash_pgsz = 0x20000; - } - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { - uint32_t sector = calculate_F7_sectornum(flashaddr); + if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || + (sl->chip_id == STLINK_CHIPID_STM32_F4) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || + (sl->chip_id == STLINK_CHIPID_STM32_F411RE) || + (sl->chip_id == STLINK_CHIPID_STM32_F446) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || + (sl->chip_id == STLINK_CHIPID_STM32_F72XXX) || + (sl->chip_id == STLINK_CHIPID_STM32_F412)) { + uint32_t sector = calculate_F4_sectornum(flashaddr); + + if (sector >= 12) { + sector -= 12; + } + + if (sector < 4) { + sl->flash_pgsz = 0x4000; + } else if (sector < 5) { + sl->flash_pgsz = 0x10000; + } else { + sl->flash_pgsz = 0x20000; + } + } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || + sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { + uint32_t sector = calculate_F7_sectornum(flashaddr); - if (sector < 4) { - sl->flash_pgsz = 0x8000; - } else if (sector < 5) { - sl->flash_pgsz = 0x20000; - } else { - sl->flash_pgsz = 0x40000; - } + if (sector < 4) { + sl->flash_pgsz = 0x8000; + } else if (sector < 5) { + sl->flash_pgsz = 0x20000; + } else { + sl->flash_pgsz = 0x40000; } + } - return((uint32_t)sl->flash_pgsz); + return ((uint32_t)sl->flash_pgsz); } /** - * Erase a page of flash, assumes sl is fully populated with things like chip/core ids + * Erase a page of flash, assumes sl is fully populated with things like + * chip/core ids * @param sl stlink context * @param flashaddr an address in the flash page to erase * @return 0 on success -ve on failure */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - // wait for ongoing op to finish - wait_flash_busy(sl); - // clear flash IO errors - clear_flash_error(sl); + // wait for ongoing op to finish + wait_flash_busy(sl); + // clear flash IO errors + clear_flash_error(sl); + + if (sl->flash_type == STLINK_FLASH_TYPE_F4 || + sl->flash_type == STLINK_FLASH_TYPE_F7 || + sl->flash_type == STLINK_FLASH_TYPE_L4) { + // unlock if locked + unlock_flash_if(sl); + + // select the page to erase + if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || + (sl->chip_id == STLINK_CHIPID_STM32_L43X) || + (sl->chip_id == STLINK_CHIPID_STM32_L46X) || + (sl->chip_id == STLINK_CHIPID_STM32_L496X) || + (sl->chip_id == STLINK_CHIPID_STM32_L4RX)) { + // calculate the actual bank+page from the address + uint32_t page = calculate_L4_page(sl, flashaddr); + + fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", page, + stlink_calculate_pagesize(sl, flashaddr)); + + write_flash_cr_bker_pnb(sl, page); + } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || + sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { + // calculate the actual page from the address + uint32_t sector = calculate_F7_sectornum(flashaddr); - if (sl->flash_type == STLINK_FLASH_TYPE_F4 || - sl->flash_type == STLINK_FLASH_TYPE_F7 || - sl->flash_type == STLINK_FLASH_TYPE_L4) { - // unlock if locked - unlock_flash_if(sl); - - // select the page to erase - if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || - (sl->chip_id == STLINK_CHIPID_STM32_L43X) || - (sl->chip_id == STLINK_CHIPID_STM32_L46X) || - (sl->chip_id == STLINK_CHIPID_STM32_L496X) || - (sl->chip_id == STLINK_CHIPID_STM32_L4RX)) { - // calculate the actual bank+page from the address - uint32_t page = calculate_L4_page(sl, flashaddr); - - fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", - page, stlink_calculate_pagesize(sl, flashaddr)); - - write_flash_cr_bker_pnb(sl, page); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { - // calculate the actual page from the address - uint32_t sector = calculate_F7_sectornum(flashaddr); - - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", - sector, stlink_calculate_pagesize(sl, flashaddr)); - write_flash_cr_snb(sl, sector, BANK_1); - } else { - // calculate the actual page from the address - uint32_t sector = calculate_F4_sectornum(flashaddr); + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, + stlink_calculate_pagesize(sl, flashaddr)); + write_flash_cr_snb(sl, sector, BANK_1); + } else { + // calculate the actual page from the address + uint32_t sector = calculate_F4_sectornum(flashaddr); - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", - sector, stlink_calculate_pagesize(sl, flashaddr)); + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, + stlink_calculate_pagesize(sl, flashaddr)); - // the SNB values for flash sectors in the second bank do not directly - // follow the values for the first bank on 2mb devices... - if (sector >= 12) { sector += 4; } + // the SNB values for flash sectors in the second bank do not directly + // follow the values for the first bank on 2mb devices... + if (sector >= 12) { + sector += 4; + } - write_flash_cr_snb(sl, sector, BANK_1); - } + write_flash_cr_snb(sl, sector, BANK_1); + } - set_flash_cr_strt(sl, BANK_1); // start erase operation - wait_flash_busy(sl); // wait for completion - lock_flash(sl); // TODO: fails to program if this is in + set_flash_cr_strt(sl, BANK_1); // start erase operation + wait_flash_busy(sl); // wait for completion + lock_flash(sl); // TODO: fails to program if this is in #if DEBUG_FLASH - fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl, BANK_1)); + fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl, BANK_1)); #endif - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - // check if the locks are set - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + // check if the locks are set + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if ((val & (1 << 0)) || (val & (1 << 1))) { - // disable pecr protection - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY2); + if ((val & (1 << 0)) || (val & (1 << 1))) { + // disable pecr protection + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY2); - // check pecr.pelock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + // check pecr.pelock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if (val & (1 << 0)) { - WLOG("pecr.pelock not clear (%#x)\n", val); - return(-1); - } + if (val & (1 << 0)) { + WLOG("pecr.pelock not clear (%#x)\n", val); + return (-1); + } - // unlock program memory - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY2); + // unlock program memory + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY2); - // check pecr.prglock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + // check pecr.prglock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if (val & (1 << 1)) { - WLOG("pecr.prglock not clear (%#x)\n", val); - return(-1); - } - } + if (val & (1 << 1)) { + WLOG("pecr.prglock not clear (%#x)\n", val); + return (-1); + } + } - // set pecr.{erase,prog} - val |= (1 << 9) | (1 << 3); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - - // write 0 to the first word of the page to be erased - stlink_write_debug32(sl, flashaddr, 0); - - /* MP: It is better to wait for clearing the busy bit after issuing page - * erase command, even though PM0062 recommends to wait before it. - * Test shows that a few iterations is performed in the following loop - * before busy bit is cleared. - */ - wait_flash_busy(sl); - - // reset lock bits - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - uint32_t val; - unlock_flash_if(sl); - set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit - - // set the page to erase - if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - - // sec 3.10.5 - PNB[7:0] is offset by 3. - val &= ~(0xFF << 3); // Clear previously set page number (if any) - val |= ((flash_page & 0xFF) << 3); - - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. - val &= ~(0x3F << 3); - val |= ((flash_page & 0x3F) << 3) | (1 << FLASH_CR_PER); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G4) { - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. - val &= ~(0x7F << 3); - val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - } + // set pecr.{erase,prog} + val |= (1 << 9) | (1 << 3); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit - wait_flash_busy(sl); // wait for the 'busy' bit to clear - clear_flash_cr_per(sl, BANK_1); // clear the 'enable page erase' bit - lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_F0 || - sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - unsigned bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE)?BANK_1:BANK_2; - unlock_flash_if(sl); - clear_flash_cr_pg(sl, bank); // clear the pg bit - set_flash_cr_per(sl, bank); // set the page erase bit - write_flash_ar(sl, flashaddr, bank); // select the page to erase - set_flash_cr_strt(sl, bank); // start erase operation, reset by hw with busy bit - wait_flash_busy(sl); - clear_flash_cr_per(sl, bank); // clear the page erase bit - lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE)?BANK_1:BANK_2; - unlock_flash_if(sl); // unlock if locked - uint32_t sector = calculate_H7_sectornum(sl, flashaddr, bank);// calculate the actual page from the address - write_flash_cr_snb(sl, sector, bank); // select the page to erase - set_flash_cr_strt(sl, bank); // start erase operation - wait_flash_busy(sl); // wait for completion - lock_flash(sl); - } else { - WLOG("unknown coreid %x, page erase failed\n", sl->core_id); - return(-1); - } + // write 0 to the first word of the page to be erased + stlink_write_debug32(sl, flashaddr, 0); + + /* MP: It is better to wait for clearing the busy bit after issuing page + * erase command, even though PM0062 recommends to wait before it. + * Test shows that a few iterations is performed in the following loop + * before busy bit is cleared. + */ + wait_flash_busy(sl); + + // reset lock bits + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + uint32_t val; + unlock_flash_if(sl); + set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit + + // set the page to erase + if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + uint32_t flash_page = + ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + + // sec 3.10.5 - PNB[7:0] is offset by 3. + val &= ~(0xFF << 3); // Clear previously set page number (if any) + val |= ((flash_page & 0xFF) << 3); + + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + uint32_t flash_page = + ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. + val &= ~(0x3F << 3); + val |= ((flash_page & 0x3F) << 3) | (1 << FLASH_CR_PER); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G4) { + uint32_t flash_page = + ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. + val &= ~(0x7F << 3); + val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + } + + set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit + wait_flash_busy(sl); // wait for the 'busy' bit to clear + clear_flash_cr_per(sl, BANK_1); // clear the 'enable page erase' bit + lock_flash(sl); + } else if (sl->flash_type == STLINK_FLASH_TYPE_F0 || + sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + unsigned bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; + unlock_flash_if(sl); + clear_flash_cr_pg(sl, bank); // clear the pg bit + set_flash_cr_per(sl, bank); // set the page erase bit + write_flash_ar(sl, flashaddr, bank); // select the page to erase + set_flash_cr_strt(sl, + bank); // start erase operation, reset by hw with busy bit + wait_flash_busy(sl); + clear_flash_cr_per(sl, bank); // clear the page erase bit + lock_flash(sl); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; + unlock_flash_if(sl); // unlock if locked + uint32_t sector = calculate_H7_sectornum( + sl, flashaddr, bank); // calculate the actual page from the address + write_flash_cr_snb(sl, sector, bank); // select the page to erase + set_flash_cr_strt(sl, bank); // start erase operation + wait_flash_busy(sl); // wait for completion + lock_flash(sl); + } else { + WLOG("unknown coreid %x, page erase failed\n", sl->core_id); + return (-1); + } - return check_flash_error(sl); + return check_flash_error(sl); } int stlink_erase_flash_mass(stlink_t *sl) { - int err = 0; + int err = 0; - // TODO: User MER bit to mass-erase WB series. - if (sl->flash_type == STLINK_FLASH_TYPE_L0 || - sl->flash_type == STLINK_FLASH_TYPE_WB) { - // erase each page - int i = 0, num_pages = (int)(sl->flash_size / sl->flash_pgsz); + // TODO: User MER bit to mass-erase WB series. + if (sl->flash_type == STLINK_FLASH_TYPE_L0 || + sl->flash_type == STLINK_FLASH_TYPE_WB) { + // erase each page + int i = 0, num_pages = (int)(sl->flash_size / sl->flash_pgsz); - for (i = 0; i < num_pages; i++) { - // addr must be an addr inside the page - stm32_addr_t addr = (stm32_addr_t)sl->flash_base + i * (stm32_addr_t)sl->flash_pgsz; + for (i = 0; i < num_pages; i++) { + // addr must be an addr inside the page + stm32_addr_t addr = + (stm32_addr_t)sl->flash_base + i * (stm32_addr_t)sl->flash_pgsz; - if (stlink_erase_flash_page(sl, addr)) { - WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); - return(-1); - } + if (stlink_erase_flash_page(sl, addr)) { + WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); + return (-1); + } - fprintf(stdout, "-> Flash page at %5d/%5d erased\n", i, num_pages); - fflush(stdout); - } + fprintf(stdout, "-> Flash page at %5d/%5d erased\n", i, num_pages); + fflush(stdout); + } - fprintf(stdout, "\n"); - } else { - wait_flash_busy(sl); - clear_flash_error(sl); - unlock_flash_if(sl); - - if (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_id != STLINK_CHIPID_STM32_H7AX) { - // set parallelism - write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); - } - } + fprintf(stdout, "\n"); + } else { + wait_flash_busy(sl); + clear_flash_error(sl); + unlock_flash_if(sl); - set_flash_cr_mer(sl, 1, BANK_1); // set the mass erase bit - set_flash_cr_strt(sl, BANK_1); // start erase operation, reset by hw with busy bit + if (sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_id != STLINK_CHIPID_STM32_H7AX) { + // set parallelism + write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); + } + } - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { - set_flash_cr_mer(sl, 1, BANK_2); // set the mass erase bit in bank 2 - set_flash_cr_strt(sl, BANK_2); // start erase operation in bank 2 - } + set_flash_cr_mer(sl, 1, BANK_1); // set the mass erase bit + set_flash_cr_strt( + sl, BANK_1); // start erase operation, reset by hw with busy bit - wait_flash_busy_progress(sl); - lock_flash(sl); + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || + (sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { + set_flash_cr_mer(sl, 1, BANK_2); // set the mass erase bit in bank 2 + set_flash_cr_strt(sl, BANK_2); // start erase operation in bank 2 + } - // reset the mass erase bit - set_flash_cr_mer(sl, 0, BANK_1); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { - set_flash_cr_mer(sl, 0, BANK_2); - } + wait_flash_busy_progress(sl); + lock_flash(sl); - err = check_flash_error(sl); + // reset the mass erase bit + set_flash_cr_mer(sl, 0, BANK_1); + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || + (sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { + set_flash_cr_mer(sl, 0, BANK_2); } - return(err); + err = check_flash_error(sl); + } + + return (err); } -int stlink_fcheck_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { - // check the contents of path are at addr +int stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { + // check the contents of path are at addr - int res; - mapped_file_t mf = MAPPED_FILE_INITIALIZER; + int res; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; - if (map_file(&mf, path) == -1) { return(-1); } + if (map_file(&mf, path) == -1) { + return (-1); + } - res = check_file(sl, &mf, addr); - unmap_file(&mf); - return(res); + res = check_file(sl, &mf, addr); + unmap_file(&mf); + return (res); } /** @@ -2946,696 +3047,741 @@ int stlink_fcheck_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { * @param length how much * @return 0 for success, -ve for failure */ -int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, unsigned length) { - size_t off; - size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; - ILOG("Starting verification of write complete\n"); +int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, + unsigned length) { + size_t off; + size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; + ILOG("Starting verification of write complete\n"); - for (off = 0; off < length; off += cmp_size) { - size_t aligned_size; + for (off = 0; off < length; off += cmp_size) { + size_t aligned_size; - // adjust last page size - if ((off + cmp_size) > length) { cmp_size = length - off; } - - aligned_size = cmp_size; - - if (aligned_size & (4 - 1)) { aligned_size = (cmp_size + 4) & ~(4 - 1); } - - stlink_read_mem32(sl, address + (uint32_t)off, aligned_size); - - if (memcmp(sl->q_buf, data + off, cmp_size)) { - ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); - return(-1); - } + // adjust last page size + if ((off + cmp_size) > length) { + cmp_size = length - off; } - ILOG("Flash written and verified! jolly good!\n"); - return(0); + aligned_size = cmp_size; -} - -int stm32l1_write_half_pages( - stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len, uint32_t pagesize) { - unsigned int count; - unsigned int num_half_pages = len / pagesize; - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - flash_loader_t fl; - - ILOG("Starting Half page flash write for STM32L core id\n"); - - /* Flash loader initialisation */ - if (stlink_flash_loader_init(sl, &fl) == -1) { - WLOG("stlink_flash_loader_init() == -1\n"); - return(-1); + if (aligned_size & (4 - 1)) { + aligned_size = (cmp_size + 4) & ~(4 - 1); } - // unlock already done - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << FLASH_L1_FPRG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - - val |= (1 << FLASH_L1_PROG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - - wait_flash_busy(sl); - - for (count = 0; count < num_half_pages; count++) { - if (stlink_flash_loader_run( - sl, &fl, addr + count * pagesize, base + count * pagesize, pagesize) == -1) { - WLOG("l1_stlink_flash_loader_run(%#x) failed! == -1\n", addr + count * pagesize); - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - return(-1); - } + stlink_read_mem32(sl, address + (uint32_t)off, aligned_size); - // wait for sr.busy to be cleared - if (sl->verbose >= 1) { - // show progress; writing procedure is slow and previous errors are misleading - fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); - fflush(stdout); - } - - wait_flash_busy(sl); + if (memcmp(sl->q_buf, data + off, cmp_size)) { + ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); + return (-1); } + } - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val &= ~(1 << FLASH_L1_PROG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val &= ~(1 << FLASH_L1_FPRG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - return(0); + ILOG("Flash written and verified! jolly good!\n"); + return (0); } -int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { - - // According to DDI0419C, Table C1-7 firstly force halt - stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | - STLINK_REG_DHCSR_C_DEBUGEN | - STLINK_REG_DHCSR_C_HALT); - // and only then disable interrupts - stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | - STLINK_REG_DHCSR_C_DEBUGEN | - STLINK_REG_DHCSR_C_HALT | - STLINK_REG_DHCSR_C_MASKINTS); - - // disable DMA - set_dma_state(sl, fl, 0); - - // wait for ongoing op to finish - wait_flash_busy(sl); - // Clear errors - clear_flash_error(sl); - - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4)) { - ILOG("Starting Flash write for F2/F4/F7/L4\n"); - - // Flash loader initialisation - if (stlink_flash_loader_init(sl, fl) == -1) { - ELOG("stlink_flash_loader_init() == -1\n"); - return(-1); - } - - unlock_flash_if(sl); // first unlock the cr - - int voltage; - if (sl->version.stlink_v == 1) { - WLOG("STLINK V1 cannot read voltage, use default voltage 3.2V\n"); - voltage = 3200; - } else { - voltage = stlink_target_voltage(sl); - } - - if (voltage == -1) { - ELOG("Failed to read Target voltage\n"); - return(-1); - } - - if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - // L4 does not have a byte-write mode - if (voltage < 1710) { - ELOG("Target voltage (%d mV) too low for flash writes!\n", voltage); - return(-1); - } - } else { - if (voltage > 2700) { - ILOG("enabling 32-bit flash writes\n"); - write_flash_cr_psiz(sl, 2, BANK_1); - } else { - ILOG("Target voltage (%d mV) too low for 32-bit flash, " - "using 8-bit flash writes\n", voltage); - write_flash_cr_psiz(sl, 0, BANK_1); - } - } - - // set programming mode - set_flash_cr_pg(sl, BANK_1); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - ILOG("Starting Flash write for WB/G0/G4\n"); - - unlock_flash_if(sl); // unlock flash if necessary - set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - ILOG("Starting Flash write for L0\n"); - - uint32_t val; - uint32_t flash_regs_base; - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L011) { - flash_regs_base = STM32L0_FLASH_REGS_ADDR; - } else { - flash_regs_base = STM32L_FLASH_REGS_ADDR; - } - - // disable pecr protection - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY2); - - // check pecr.pelock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if (val & (1 << 0)) { - ELOG("pecr.pelock not clear\n"); - return(-1); - } - - // unlock program memory - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY2); +int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, + uint32_t len, uint32_t pagesize) { + unsigned int count; + unsigned int num_half_pages = len / pagesize; + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + flash_loader_t fl; - // check pecr.prglock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if (val & (1 << 1)) { - ELOG("pecr.prglock not clear\n"); - return(-1); - } - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - ILOG("Starting Flash write for VL/F0/F3/F1_XL\n"); - - // flash loader initialisation - if (stlink_flash_loader_init(sl, fl) == -1) { - ELOG("stlink_flash_loader_init() == -1\n"); - return(-1); - } - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - ILOG("Starting Flash write for H7\n"); + ILOG("Starting Half page flash write for STM32L core id\n"); - unlock_flash_if(sl); // unlock the cr - set_flash_cr_pg(sl, BANK_1); // set programming mode - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - set_flash_cr_pg(sl, BANK_2); - } - if (sl->chip_id != STLINK_CHIPID_STM32_H7AX) { - // set parallelism - write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); - } - } - } else { - ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); - return(-1); - } + /* Flash loader initialisation */ + if (stlink_flash_loader_init(sl, &fl) == -1) { + WLOG("stlink_flash_loader_init() == -1\n"); + return (-1); + } - return(0); -} - -int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, - uint8_t* base, uint32_t len) { - size_t off; - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4)) { - size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; - for (off = 0; off < len;) { - size_t size = len - off > buf_size ? buf_size : len - off; - if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { - ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", (unsigned)(addr + off)); - check_flash_error(sl); - return(-1); - } + // unlock already done + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << FLASH_L1_FPRG); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - off += size; - } - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); - for (off = 0; off < len; off += sizeof(uint32_t)) { - uint32_t data; - - if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { - fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off / sl->flash_pgsz), - (unsigned int)(len / sl->flash_pgsz)); - fflush(stdout); - } - - write_uint32((unsigned char*)&data, *(uint32_t*)(base + off)); - stlink_write_debug32(sl, addr + (uint32_t)off, data); - wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear - } - fprintf(stdout, "\n"); - - // flash writes happen as 2 words at a time - if ((off / sizeof(uint32_t)) % 2 != 0) { - stlink_write_debug32(sl, addr + (uint32_t)off, 0); // write a single word of zeros - wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear - } - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - uint32_t val; - uint32_t flash_regs_base; - uint32_t pagesize; - - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L011) { - flash_regs_base = STM32L0_FLASH_REGS_ADDR; - pagesize = L0_WRITE_BLOCK_SIZE; - } else { - flash_regs_base = STM32L_FLASH_REGS_ADDR; - pagesize = L1_WRITE_BLOCK_SIZE; - } + val |= (1 << FLASH_L1_PROG); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - off = 0; + wait_flash_busy(sl); - if (len > pagesize) { - if (stm32l1_write_half_pages(sl, addr, base, len, pagesize) == -1) { - // this may happen on a blank device! - WLOG("\nwrite_half_pages failed == -1\n"); - } else { - off = (len / pagesize) * pagesize; - } - } + for (count = 0; count < num_half_pages; count++) { + if (stlink_flash_loader_run(sl, &fl, addr + count * pagesize, + base + count * pagesize, pagesize) == -1) { + WLOG("l1_stlink_flash_loader_run(%#x) failed! == -1\n", + addr + count * pagesize); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + return (-1); + } - // write remaining word in program memory - for ( ; off < len; off += sizeof(uint32_t)) { - uint32_t data; + // wait for sr.busy to be cleared + if (sl->verbose >= 1) { + // show progress; writing procedure is slow and previous errors are + // misleading + fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); + fflush(stdout); + } - if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { - fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off / sl->flash_pgsz), - (unsigned int)(len / sl->flash_pgsz)); - fflush(stdout); - } + wait_flash_busy(sl); + } - write_uint32((unsigned char*)&data, *(uint32_t*)(base + off)); - stlink_write_debug32(sl, addr + (uint32_t)off, data); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val &= ~(1 << FLASH_L1_PROG); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val &= ~(1 << FLASH_L1_FPRG); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + return (0); +} - // wait for sr.busy to be cleared - do { - stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); - } while ((val & (1 << 0)) != 0); +int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { - // TODO: check redo write operation - } - fprintf(stdout, "\n"); - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - int write_block_count = 0; - for (off = 0; off < len; off += sl->flash_pgsz) { - // adjust last write size - size_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; - - // unlock and set programming mode - unlock_flash_if(sl); - - DLOG("Finished unlocking flash, running loader!\n"); - - if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { - ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", (unsigned)(addr + off)); - check_flash_error(sl); - return(-1); - } + // According to DDI0419C, Table C1-7 firstly force halt + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + STLINK_REG_DHCSR_C_HALT); + // and only then disable interrupts + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_MASKINTS); + + // disable DMA + set_dma_state(sl, fl, 0); + + // wait for ongoing op to finish + wait_flash_busy(sl); + // Clear errors + clear_flash_error(sl); + + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + (sl->flash_type == STLINK_FLASH_TYPE_F7) || + (sl->flash_type == STLINK_FLASH_TYPE_L4)) { + ILOG("Starting Flash write for F2/F4/F7/L4\n"); + + // Flash loader initialisation + if (stlink_flash_loader_init(sl, fl) == -1) { + ELOG("stlink_flash_loader_init() == -1\n"); + return (-1); + } + + unlock_flash_if(sl); // first unlock the cr + + int voltage; + if (sl->version.stlink_v == 1) { + WLOG("STLINK V1 cannot read voltage, use default voltage 3.2V\n"); + voltage = 3200; + } else { + voltage = stlink_target_voltage(sl); + } - lock_flash(sl); + if (voltage == -1) { + ELOG("Failed to read Target voltage\n"); + return (-1); + } - if (sl->verbose >= 1) { - // show progress; writing procedure is slow and previous errors are misleading - fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, - (unsigned int)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); - fflush(stdout); - } - } - if (sl->verbose >= 1) { - fprintf(stdout, "\n"); - } - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - for (off = 0; off < len;) { - // Program STM32H7x with 64-byte Flash words - size_t chunk = (len - off > 64) ? 64 : len - off; - memcpy(sl->q_buf, base + off, chunk); - stlink_write_mem32(sl, addr + (uint32_t)off, 64); - wait_flash_busy(sl); - - off += chunk; - - if (sl->verbose >= 1) { - // show progress - fprintf(stdout, "\r%u/%u bytes written", (unsigned int)off, (unsigned int)len); - fflush(stdout); - } - } - if (sl->verbose >= 1) { - fprintf(stdout, "\n"); - } + if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + // L4 does not have a byte-write mode + if (voltage < 1710) { + ELOG("Target voltage (%d mV) too low for flash writes!\n", voltage); + return (-1); + } + } else { + if (voltage > 2700) { + ILOG("enabling 32-bit flash writes\n"); + write_flash_cr_psiz(sl, 2, BANK_1); + } else { + ILOG("Target voltage (%d mV) too low for 32-bit flash, " + "using 8-bit flash writes\n", + voltage); + write_flash_cr_psiz(sl, 0, BANK_1); + } + } + + // set programming mode + set_flash_cr_pg(sl, BANK_1); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + ILOG("Starting Flash write for WB/G0/G4\n"); + + unlock_flash_if(sl); // unlock flash if necessary + set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + ILOG("Starting Flash write for L0\n"); + + uint32_t val; + uint32_t flash_regs_base; + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || + sl->chip_id == STLINK_CHIPID_STM32_L011) { + flash_regs_base = STM32L0_FLASH_REGS_ADDR; } else { - return(-1); + flash_regs_base = STM32L_FLASH_REGS_ADDR; } - return check_flash_error(sl); -} + // disable pecr protection + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY2); -int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { - uint32_t dhcsr; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4) || - (sl->flash_type == STLINK_FLASH_TYPE_WB) || - (sl->flash_type == STLINK_FLASH_TYPE_G0) || - (sl->flash_type == STLINK_FLASH_TYPE_G4) || - (sl->flash_type == STLINK_FLASH_TYPE_H7)) { - - clear_flash_cr_pg(sl, BANK_1); - if (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - clear_flash_cr_pg(sl, BANK_2); - } - lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - uint32_t val; - uint32_t flash_regs_base; - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L011) { - flash_regs_base = STM32L0_FLASH_REGS_ADDR; - } else { - flash_regs_base = STM32L_FLASH_REGS_ADDR; - } - // reset lock bits - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + // check pecr.pelock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 0)) { + ELOG("pecr.pelock not clear\n"); + return (-1); + } + + // unlock program memory + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY2); + + // check pecr.prglock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 1)) { + ELOG("pecr.prglock not clear\n"); + return (-1); + } + } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + ILOG("Starting Flash write for VL/F0/F3/F1_XL\n"); + + // flash loader initialisation + if (stlink_flash_loader_init(sl, fl) == -1) { + ELOG("stlink_flash_loader_init() == -1\n"); + return (-1); + } + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + ILOG("Starting Flash write for H7\n"); + + unlock_flash_if(sl); // unlock the cr + set_flash_cr_pg(sl, BANK_1); // set programming mode + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + set_flash_cr_pg(sl, BANK_2); + } + if (sl->chip_id != STLINK_CHIPID_STM32_H7AX) { + // set parallelism + write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); + } + } + } else { + ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); + return (-1); + } + + return (0); +} + +int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, + stm32_addr_t addr, uint8_t *base, uint32_t len) { + size_t off; + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + (sl->flash_type == STLINK_FLASH_TYPE_F7) || + (sl->flash_type == STLINK_FLASH_TYPE_L4)) { + size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; + for (off = 0; off < len;) { + size_t size = len - off > buf_size ? buf_size : len - off; + if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, + size) == -1) { + ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", + (unsigned)(addr + off)); + check_flash_error(sl); + return (-1); + } + + off += size; + } + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); + for (off = 0; off < len; off += sizeof(uint32_t)) { + uint32_t data; + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { + fprintf(stdout, "\r%3u/%3u pages written", + (unsigned int)(off / sl->flash_pgsz), + (unsigned int)(len / sl->flash_pgsz)); + fflush(stdout); + } + + write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); + stlink_write_debug32(sl, addr + (uint32_t)off, data); + wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear } + fprintf(stdout, "\n"); - // enable interrupt - if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) { - stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | - STLINK_REG_DHCSR_C_DEBUGEN | - (dhcsr&(~STLINK_REG_DHCSR_C_MASKINTS))); + // flash writes happen as 2 words at a time + if ((off / sizeof(uint32_t)) % 2 != 0) { + stlink_write_debug32(sl, addr + (uint32_t)off, + 0); // write a single word of zeros + wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear + } + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + uint32_t val; + uint32_t flash_regs_base; + uint32_t pagesize; + + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || + sl->chip_id == STLINK_CHIPID_STM32_L011) { + flash_regs_base = STM32L0_FLASH_REGS_ADDR; + pagesize = L0_WRITE_BLOCK_SIZE; + } else { + flash_regs_base = STM32L_FLASH_REGS_ADDR; + pagesize = L1_WRITE_BLOCK_SIZE; } - // restore DMA state - set_dma_state(sl, fl, 1); - - return(0); -} - -int stlink_write_flash( - stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len, uint8_t eraseonly) { - size_t off; - int ret; - flash_loader_t fl; - ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr); - // check addr range is inside the flash - stlink_calculate_pagesize(sl, addr); - - if (addr < sl->flash_base) { - ELOG("addr too low %#x < %#x\n", addr, sl->flash_base); - return(-1); - } else if ((addr + len) < addr) { - ELOG("addr overruns\n"); - return(-1); - } else if ((addr + len) > (sl->flash_base + sl->flash_size)) { - ELOG("addr too high\n"); - return(-1); - } else if (addr & 1) { - ELOG("unaligned addr 0x%x\n", addr); - return(-1); - } else if (len & 1) { - WLOG("unaligned len 0x%x -- padding with zero\n", len); - len += 1; - } else if (addr & (sl->flash_pgsz - 1)) { - ELOG("addr not a multiple of current pagesize (%u bytes), not supported, " - "check page start address and compare with flash module organisation " - "in related ST reference manual of your device.\n", (unsigned)(sl->flash_pgsz)); - return(-1); + off = 0; + + if (len > pagesize) { + if (stm32l1_write_half_pages(sl, addr, base, len, pagesize) == -1) { + // this may happen on a blank device! + WLOG("\nwrite_half_pages failed == -1\n"); + } else { + off = (size_t)(len / pagesize) * pagesize; + } } - // make sure we've loaded the context with the chip details - stlink_core_id(sl); + // write remaining word in program memory + for (; off < len; off += sizeof(uint32_t)) { + uint32_t data; - // Erase each page - int page_count = 0; + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { + fprintf(stdout, "\r%3u/%3u pages written", + (unsigned int)(off / sl->flash_pgsz), + (unsigned int)(len / sl->flash_pgsz)); + fflush(stdout); + } - for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + (uint32_t)off)) { - // addr must be an addr inside the page - if (stlink_erase_flash_page(sl, addr + (uint32_t)off) == -1) { - ELOG("Failed to erase_flash_page(%#x) == -1\n", (unsigned)(addr + off)); - return(-1); - } + write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); + stlink_write_debug32(sl, addr + (uint32_t)off, data); - ILOG("Flash page at addr: 0x%08lx erased\n", (unsigned long)(addr + off)); - page_count++; + // wait for sr.busy to be cleared + do { + stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); + } while ((val & (1 << 0)) != 0); + + // TODO: check redo write operation } + fprintf(stdout, "\n"); + } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + int write_block_count = 0; + for (off = 0; off < len; off += sl->flash_pgsz) { + // adjust last write size + size_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; + + // unlock and set programming mode + unlock_flash_if(sl); + + DLOG("Finished unlocking flash, running loader!\n"); + + if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, + size) == -1) { + ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", + (unsigned)(addr + off)); + check_flash_error(sl); + return (-1); + } + + lock_flash(sl); + + if (sl->verbose >= 1) { + // show progress; writing procedure is slow and previous errors are + // misleading + fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, + (unsigned int)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); + fflush(stdout); + } + } + if (sl->verbose >= 1) { + fprintf(stdout, "\n"); + } + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + for (off = 0; off < len;) { + // Program STM32H7x with 64-byte Flash words + size_t chunk = (len - off > 64) ? 64 : len - off; + memcpy(sl->q_buf, base + off, chunk); + stlink_write_mem32(sl, addr + (uint32_t)off, 64); + wait_flash_busy(sl); + + off += chunk; + + if (sl->verbose >= 1) { + // show progress + fprintf(stdout, "\r%u/%u bytes written", (unsigned int)off, + (unsigned int)len); + fflush(stdout); + } + } + if (sl->verbose >= 1) { + fprintf(stdout, "\n"); + } + } else { + return (-1); + } + + return check_flash_error(sl); +} - ILOG("Finished erasing %d pages of %u (%#x) bytes\n", - page_count, (unsigned)(sl->flash_pgsz), (unsigned)(sl->flash_pgsz)); +int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { + uint32_t dhcsr; - if (eraseonly) { return(0); } + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + (sl->flash_type == STLINK_FLASH_TYPE_F7) || + (sl->flash_type == STLINK_FLASH_TYPE_L4) || + (sl->flash_type == STLINK_FLASH_TYPE_WB) || + (sl->flash_type == STLINK_FLASH_TYPE_G0) || + (sl->flash_type == STLINK_FLASH_TYPE_G4) || + (sl->flash_type == STLINK_FLASH_TYPE_H7)) { - ret = stlink_flashloader_start(sl, &fl); - if (ret) - return ret; - ret = stlink_flashloader_write(sl, &fl, addr, base, len); - if (ret) - return ret; - ret = stlink_flashloader_stop(sl, &fl); - if (ret) - return ret; + clear_flash_cr_pg(sl, BANK_1); + if (sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + clear_flash_cr_pg(sl, BANK_2); + } + lock_flash(sl); + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + uint32_t val; + uint32_t flash_regs_base; + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || + sl->chip_id == STLINK_CHIPID_STM32_L011) { + flash_regs_base = STM32L0_FLASH_REGS_ADDR; + } else { + flash_regs_base = STM32L_FLASH_REGS_ADDR; + } + // reset lock bits + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + } + + // enable interrupt + if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) { + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + (dhcsr & (~STLINK_REG_DHCSR_C_MASKINTS))); + } + + // restore DMA state + set_dma_state(sl, fl, 1); + + return (0); +} + +int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, + uint32_t len, uint8_t eraseonly) { + size_t off; + int ret; + flash_loader_t fl; + ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, + len, addr, addr); + // check addr range is inside the flash + stlink_calculate_pagesize(sl, addr); + + if (addr < sl->flash_base) { + ELOG("addr too low %#x < %#x\n", addr, sl->flash_base); + return (-1); + } else if ((addr + len) < addr) { + ELOG("addr overruns\n"); + return (-1); + } else if ((addr + len) > (sl->flash_base + sl->flash_size)) { + ELOG("addr too high\n"); + return (-1); + } else if (addr & 1) { + ELOG("unaligned addr 0x%x\n", addr); + return (-1); + } else if (len & 1) { + WLOG("unaligned len 0x%x -- padding with zero\n", len); + len += 1; + } else if (addr & (sl->flash_pgsz - 1)) { + ELOG("addr not a multiple of current pagesize (%u bytes), not supported, " + "check page start address and compare with flash module organisation " + "in related ST reference manual of your device.\n", + (unsigned)(sl->flash_pgsz)); + return (-1); + } + + // make sure we've loaded the context with the chip details + stlink_core_id(sl); + + // Erase each page + int page_count = 0; + + for (off = 0; off < len; + off += stlink_calculate_pagesize(sl, addr + (uint32_t)off)) { + // addr must be an addr inside the page + if (stlink_erase_flash_page(sl, addr + (uint32_t)off) == -1) { + ELOG("Failed to erase_flash_page(%#x) == -1\n", (unsigned)(addr + off)); + return (-1); + } + + ILOG("Flash page at addr: 0x%08lx erased\n", (unsigned long)(addr + off)); + page_count++; + } + + ILOG("Finished erasing %d pages of %u (%#x) bytes\n", page_count, + (unsigned)(sl->flash_pgsz), (unsigned)(sl->flash_pgsz)); + + if (eraseonly) { + return (0); + } + + ret = stlink_flashloader_start(sl, &fl); + if (ret) + return ret; + ret = stlink_flashloader_write(sl, &fl, addr, base, len); + if (ret) + return ret; + ret = stlink_flashloader_stop(sl, &fl); + if (ret) + return ret; - return(stlink_verify_write_flash(sl, addr, base, len)); + return (stlink_verify_write_flash(sl, addr, base, len)); } // TODO: length not checked -static uint8_t stlink_parse_hex(const char* hex) { - uint8_t d[2]; - - for (int i = 0; i < 2; ++i) { - char c = *(hex + i); - - if (c >= '0' && c <= '9') { - d[i] = c - '0'; - } else if (c >= 'A' && c <= 'F') { - d[i] = c - 'A' + 10; - } else if (c >= 'a' && c <= 'f') { - d[i] = c - 'a' + 10; - } else { - return(0); // error - } +static uint8_t stlink_parse_hex(const char *hex) { + uint8_t d[2]; + + for (int i = 0; i < 2; ++i) { + char c = *(hex + i); + + if (c >= '0' && c <= '9') { + d[i] = c - '0'; + } else if (c >= 'A' && c <= 'F') { + d[i] = c - 'A' + 10; + } else if (c >= 'a' && c <= 'f') { + d[i] = c - 'a' + 10; + } else { + return (0); // error } + } - return((d[0] << 4) | (d[1])); + return ((d[0] << 4) | (d[1])); } -int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, - uint32_t * begin) { - int res = 0; - *begin = UINT32_MAX; - uint8_t* data = NULL; - uint32_t end = 0; - bool eof_found = false; +int stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **mem, + size_t *size, uint32_t *begin) { + int res = 0; + *begin = UINT32_MAX; + uint8_t *data = NULL; + uint32_t end = 0; + bool eof_found = false; - for (int scan = 0; (res == 0) && (scan < 2); ++scan) { - // parse file two times - first to find memory range, second - to fill it - if (scan == 1) { - if (!eof_found) { - ELOG("No EoF recond\n"); - res = -1; - break; - } + for (int scan = 0; (res == 0) && (scan < 2); ++scan) { + // parse file two times - first to find memory range, second - to fill it + if (scan == 1) { + if (!eof_found) { + ELOG("No EoF recond\n"); + res = -1; + break; + } - if (*begin >= end) { - ELOG("No data found in file\n"); - res = -1; - break; - } + if (*begin >= end) { + ELOG("No data found in file\n"); + res = -1; + break; + } - *size = (end - *begin) + 1; - data = calloc(*size, 1); // use calloc to get NULL if out of memory + *size = (end - *begin) + 1; + data = calloc(*size, 1); // use calloc to get NULL if out of memory - if (!data) { - ELOG("Cannot allocate %u bytes\n", (unsigned)(*size)); - res = -1; - break; - } + if (!data) { + ELOG("Cannot allocate %u bytes\n", (unsigned)(*size)); + res = -1; + break; + } - memset(data, erased_pattern, *size); - } + memset(data, erased_pattern, *size); + } - FILE* file = fopen(path, "r"); + FILE *file = fopen(path, "r"); - if (!file) { - ELOG("Cannot open file\n"); - res = -1; - break; - } + if (!file) { + ELOG("Cannot open file\n"); + res = -1; + break; + } - uint32_t lba = 0; - char line[1 + 5 * 2 + 255 * 2 + 2]; + uint32_t lba = 0; + char line[1 + 5 * 2 + 255 * 2 + 2]; - while (fgets(line, sizeof(line), file)) { - if (line[0] == '\n' || line[0] == '\r') { continue; } // skip empty lines + while (fgets(line, sizeof(line), file)) { + if (line[0] == '\n' || line[0] == '\r') { + continue; + } // skip empty lines - if (line[0] != ':') { // no marker - wrong file format - ELOG("Wrong file format - no marker\n"); - res = -1; - break; - } + if (line[0] != ':') { // no marker - wrong file format + ELOG("Wrong file format - no marker\n"); + res = -1; + break; + } - size_t l = strlen(line); + size_t l = strlen(line); - while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r')) { --l; } // trim EoL + while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r')) { + --l; + } // trim EoL - if ((l < 11) || (l == (sizeof(line) - 1))) { // line too short or long - wrong file format - ELOG("Wrong file format - wrong line length\n"); - res = -1; - break; - } + if ((l < 11) || + (l == + (sizeof(line) - 1))) { // line too short or long - wrong file format + ELOG("Wrong file format - wrong line length\n"); + res = -1; + break; + } - uint8_t chksum = 0; // check sum + uint8_t chksum = 0; // check sum - for (size_t i = 1; i < l; i += 2) { chksum += stlink_parse_hex(line + i); } + for (size_t i = 1; i < l; i += 2) { + chksum += stlink_parse_hex(line + i); + } - if (chksum != 0) { - ELOG("Wrong file format - checksum mismatch\n"); - res = -1; - break; - } + if (chksum != 0) { + ELOG("Wrong file format - checksum mismatch\n"); + res = -1; + break; + } - uint8_t reclen = stlink_parse_hex(line + 1); + uint8_t reclen = stlink_parse_hex(line + 1); - if (((uint32_t)reclen + 5) * 2 + 1 != l) { - ELOG("Wrong file format - record length mismatch\n"); - res = -1; - break; - } + if (((uint32_t)reclen + 5) * 2 + 1 != l) { + ELOG("Wrong file format - record length mismatch\n"); + res = -1; + break; + } - uint16_t offset = ((uint16_t)stlink_parse_hex(line + 3) << 8) | - ((uint16_t)stlink_parse_hex(line + 5)); - uint8_t rectype = stlink_parse_hex(line + 7); - - switch (rectype) { - case 0: /* Data */ - if (scan == 0) { - uint32_t b = lba + offset; - uint32_t e = b + reclen - 1; - - if (b < *begin) { *begin = b; } - - if (e > end) { end = e; } - } else { - for (uint8_t i = 0; i < reclen; ++i) { - uint8_t b = stlink_parse_hex(line + 9 + i * 2); - uint32_t addr = lba + offset + i; - - if (addr >= *begin && addr <= end) { data[addr - *begin] = b; } - } - } - break; - case 1: /* EoF */ - eof_found = true; - break; - case 2: /* Extended Segment Address, unexpected */ - res = -1; - break; - case 3: /* Start Segment Address, unexpected */ - res = -1; - break; - case 4: /* Extended Linear Address */ - if (reclen == 2) { - lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | - ((uint32_t)stlink_parse_hex(line + 11) << 16); - } else { - ELOG("Wrong file format - wrong LBA length\n"); - res = -1; - } - break; - case 5: /* Start Linear Address - expected, but ignore */ - break; - default: - ELOG("Wrong file format - unexpected record type %d\n", rectype); - res = -1; - } + uint16_t offset = ((uint16_t)stlink_parse_hex(line + 3) << 8) | + ((uint16_t)stlink_parse_hex(line + 5)); + uint8_t rectype = stlink_parse_hex(line + 7); - if (res != 0) { break; } - } + switch (rectype) { + case 0: /* Data */ + if (scan == 0) { + uint32_t b = lba + offset; + uint32_t e = b + reclen - 1; - fclose(file); - } + if (b < *begin) { + *begin = b; + } - if (res == 0) { - *mem = data; - } else { - free(data); - } + if (e > end) { + end = e; + } + } else { + for (uint8_t i = 0; i < reclen; ++i) { + uint8_t b = stlink_parse_hex(line + 9 + i * 2); + uint32_t addr = lba + offset + i; - return(res); -} + if (addr >= *begin && addr <= end) { + data[addr - *begin] = b; + } + } + } + break; + case 1: /* EoF */ + eof_found = true; + break; + case 2: /* Extended Segment Address, unexpected */ + res = -1; + break; + case 3: /* Start Segment Address, unexpected */ + res = -1; + break; + case 4: /* Extended Linear Address */ + if (reclen == 2) { + lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | + ((uint32_t)stlink_parse_hex(line + 11) << 16); + } else { + ELOG("Wrong file format - wrong LBA length\n"); + res = -1; + } + break; + case 5: /* Start Linear Address - expected, but ignore */ + break; + default: + ELOG("Wrong file format - unexpected record type %d\n", rectype); + res = -1; + } -uint8_t stlink_get_erased_pattern(stlink_t *sl) { - if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - return(0x00); - } else { - return(0xff); + if (res != 0) { + break; + } } -} -int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr) { - /* Write the block in flash at addr */ - int err; - unsigned int num_empty, idx; - uint8_t erased_pattern = stlink_get_erased_pattern(sl); + fclose(file); + } - /* - * This optimisation may cause unexpected garbage data remaining. - * Therfore it is turned off by default. - */ - if (sl->opt) { - idx = (unsigned int)length; + if (res == 0) { + *mem = data; + } else { + free(data); + } + + return (res); +} - for (num_empty = 0; num_empty != length; ++num_empty) - if (data[--idx] != erased_pattern) { break; } +uint8_t stlink_get_erased_pattern(stlink_t *sl) { + if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + return (0x00); + } else { + return (0xff); + } +} + +int stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, + stm32_addr_t addr) { + /* Write the block in flash at addr */ + int err; + unsigned int num_empty, idx; + uint8_t erased_pattern = stlink_get_erased_pattern(sl); + + /* + * This optimisation may cause unexpected garbage data remaining. + * Therfore it is turned off by default. + */ + if (sl->opt) { + idx = (unsigned int)length; + + for (num_empty = 0; num_empty != length; ++num_empty) + if (data[--idx] != erased_pattern) { + break; + } - num_empty -= (num_empty & 3); // Round down to words + num_empty -= (num_empty & 3); // Round down to words - if (num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); - } - } else { - num_empty = 0; + if (num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, + erased_pattern); } + } else { + num_empty = 0; + } - /* - * TODO: investigate a kind of weird behaviour here: - * If the file is identified to be all-empty and four-bytes aligned, - * still flash the whole file even if ignoring message is printed. - */ - err = stlink_write_flash(sl, addr, data, - (num_empty == length) ? (uint32_t)length : (uint32_t)length - num_empty, - num_empty == length); - stlink_fwrite_finalize(sl, addr); - return(err); + /* + * TODO: investigate a kind of weird behaviour here: + * If the file is identified to be all-empty and four-bytes aligned, + * still flash the whole file even if ignoring message is printed. + */ + err = stlink_write_flash(sl, addr, data, + (num_empty == length) ? (uint32_t)length + : (uint32_t)length - num_empty, + num_empty == length); + stlink_fwrite_finalize(sl, addr); + return (err); } /** @@ -3645,49 +3791,53 @@ int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr * @param addr where to start writing * @return 0 on success, -ve on failure. */ -int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { - /* Write the file in flash at addr */ - int err; - unsigned int num_empty, idx; - uint8_t erased_pattern = stlink_get_erased_pattern(sl); - mapped_file_t mf = MAPPED_FILE_INITIALIZER; - - if (map_file(&mf, path) == -1) { - ELOG("map_file() == -1\n"); - return(-1); +int stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { + /* Write the file in flash at addr */ + int err; + unsigned int num_empty, idx; + uint8_t erased_pattern = stlink_get_erased_pattern(sl); + mapped_file_t mf = MAPPED_FILE_INITIALIZER; + + if (map_file(&mf, path) == -1) { + ELOG("map_file() == -1\n"); + return (-1); + } + + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); + + if (sl->opt) { + idx = (unsigned int)mf.len; + + for (num_empty = 0; num_empty != mf.len; ++num_empty) { + if (mf.base[--idx] != erased_pattern) { + break; + } } - printf("file %s ", path); - md5_calculate(&mf); - stlink_checksum(&mf); - - if (sl->opt) { - idx = (unsigned int)mf.len; + num_empty -= (num_empty & 3); // round down to words - for (num_empty = 0; num_empty != mf.len; ++num_empty) { - if (mf.base[--idx] != erased_pattern) { break; } - } - - num_empty -= (num_empty & 3); // round down to words - - if (num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); - } - } else { - num_empty = 0; + if (num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, + erased_pattern); } + } else { + num_empty = 0; + } - /* - * TODO: investigate a kind of weird behaviour here: - * If the file is identified to be all-empty and four-bytes aligned, - * still flash the whole file even if ignoring message is printed. - */ - err = stlink_write_flash(sl, addr, mf.base, - (num_empty == mf.len) ? (uint32_t)mf.len : (uint32_t)mf.len - num_empty, - num_empty == mf.len); - stlink_fwrite_finalize(sl, addr); - unmap_file(&mf); - return(err); + /* + * TODO: investigate a kind of weird behaviour here: + * If the file is identified to be all-empty and four-bytes aligned, + * still flash the whole file even if ignoring message is printed. + */ + err = stlink_write_flash(sl, addr, mf.base, + (num_empty == mf.len) ? (uint32_t)mf.len + : (uint32_t)mf.len - num_empty, + num_empty == mf.len); + stlink_fwrite_finalize(sl, addr); + unmap_file(&mf); + return (err); } /** @@ -3697,35 +3847,35 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_gx( - stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - /* Write options bytes */ - uint32_t val; - int ret = 0; - (void)len; - uint32_t data; +static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + /* Write options bytes */ + uint32_t val; + int ret = 0; + (void)len; + uint32_t data; - clear_flash_error(sl); + clear_flash_error(sl); - write_uint32((unsigned char*)&data, *(uint32_t*)(base)); - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); + write_uint32((unsigned char *)&data, *(uint32_t *)(base)); + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); - // Set Options Start bit - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + // Set Options Start bit + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - wait_flash_busy(sl); + wait_flash_busy(sl); - ret = check_flash_error(sl); + ret = check_flash_error(sl); - // Reload options - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + // Reload options + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - return(ret); + return (ret); } /** @@ -3735,36 +3885,39 @@ static int stlink_write_option_bytes_gx( * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l0( - stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - uint32_t flash_base = get_stm32l0_flash_base(sl); - uint32_t val; - uint32_t data; - int ret = 0; - - // Clear errors - clear_flash_error(sl); +static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t flash_base = get_stm32l0_flash_base(sl); + uint32_t val; + uint32_t data; + int ret = 0; - while (len != 0) { - write_uint32((unsigned char*)&data, *(uint32_t*)(base)); // write options bytes + // Clear errors + clear_flash_error(sl); - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - stlink_write_debug32(sl, addr, data); - wait_flash_busy(sl); + while (len != 0) { + write_uint32((unsigned char *)&data, + *(uint32_t *)(base)); // write options bytes - if ((ret = check_flash_error(sl))) { break; } + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + stlink_write_debug32(sl, addr, data); + wait_flash_busy(sl); - len -= 4; - addr += 4; - base += 4; + if ((ret = check_flash_error(sl))) { + break; } - // Reload options - stlink_read_debug32(sl, flash_base + FLASH_PECR_OFF, &val); - val |= (1 << STM32L0_FLASH_OBL_LAUNCH); - stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); + len -= 4; + addr += 4; + base += 4; + } + + // Reload options + stlink_read_debug32(sl, flash_base + FLASH_PECR_OFF, &val); + val |= (1 << STM32L0_FLASH_OBL_LAUNCH); + stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); - return(ret); + return (ret); } /** @@ -3774,67 +3927,67 @@ static int stlink_write_option_bytes_l0( * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l4( - stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { +static int stlink_write_option_bytes_l4(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { - uint32_t val; - int ret = 0; - (void)addr; - (void)len; + uint32_t val; + int ret = 0; + (void)addr; + (void)len; - // Clear errors - clear_flash_error(sl); + // Clear errors + clear_flash_error(sl); - // write options bytes - uint32_t data; - write_uint32((unsigned char*)&data, *(uint32_t*)(base)); - WLOG("Writing option bytes 0x%04x\n", data); - stlink_write_debug32(sl, STM32L4_FLASH_OPTR, data); + // write options bytes + uint32_t data; + write_uint32((unsigned char *)&data, *(uint32_t *)(base)); + WLOG("Writing option bytes 0x%04x\n", data); + stlink_write_debug32(sl, STM32L4_FLASH_OPTR, data); - // set options start bit - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1 << STM32L4_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + // set options start bit + stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); + val |= (1 << STM32L4_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - wait_flash_busy(sl); - ret = check_flash_error(sl); + wait_flash_busy(sl); + ret = check_flash_error(sl); - // apply options bytes immediate - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + // apply options bytes immediate + stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); + val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); + stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - return(ret); + return (ret); } - /** * Write option bytes * @param sl * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f4( - stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - uint32_t option_byte; - int ret = 0; - (void)addr; - (void)len; - - // Clear errors - clear_flash_error(sl); +static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t option_byte; + int ret = 0; + (void)addr; + (void)len; - write_uint32((unsigned char*)&option_byte, *(uint32_t*)(base)); + // Clear errors + clear_flash_error(sl); - // write option byte, ensuring we dont lock opt, and set strt bit - stlink_write_debug32(sl, FLASH_F4_OPTCR, - (option_byte & ~(1 << FLASH_F4_OPTCR_LOCK)) | (1 << FLASH_F4_OPTCR_START)); + write_uint32((unsigned char *)&option_byte, *(uint32_t *)(base)); - wait_flash_busy(sl); - ret = check_flash_error(sl); + // write option byte, ensuring we dont lock opt, and set strt bit + stlink_write_debug32(sl, FLASH_F4_OPTCR, + (option_byte & ~(1 << FLASH_F4_OPTCR_LOCK)) | + (1 << FLASH_F4_OPTCR_START)); - // option bytes are reloaded at reset only, no obl. */ - return(ret); + wait_flash_busy(sl); + ret = check_flash_error(sl); + + // option bytes are reloaded at reset only, no obl. */ + return (ret); } /** @@ -3843,47 +3996,54 @@ static int stlink_write_option_bytes_f4( * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - uint32_t option_byte; - int ret = 0; +static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t option_byte; + int ret = 0; - // Clear errors - clear_flash_error(sl); + // Clear errors + clear_flash_error(sl); - ILOG("Asked to write option byte %#10x to %#010x.\n", *(uint32_t*) (base), addr); - write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); - ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); + ILOG("Asked to write option byte %#10x to %#010x.\n", *(uint32_t *)(base), + addr); + write_uint32((unsigned char *)&option_byte, *(uint32_t *)(base)); + ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); - if ( addr == 0 ) { - addr = FLASH_F7_OPTCR; - ILOG("No address provided, using %#10x\n", addr); - } + if (addr == 0) { + addr = FLASH_F7_OPTCR; + ILOG("No address provided, using %#10x\n", addr); + } - if ( addr == FLASH_F7_OPTCR ) { - /* write option byte, ensuring we dont lock opt, and set strt bit */ - stlink_write_debug32(sl, FLASH_F7_OPTCR, (option_byte & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); - } else if ( addr == FLASH_F7_OPTCR1 ) { - // Read FLASH_F7_OPTCR - uint32_t oldvalue; - stlink_read_debug32(sl, FLASH_F7_OPTCR, &oldvalue); - /* write option byte */ - stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_byte); - // Write FLASH_F7_OPTCR lock and start address - stlink_write_debug32(sl, FLASH_F7_OPTCR, (oldvalue & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); - } else { - WLOG("WIP: write %#010x to address %#010x\n", option_byte, addr); - stlink_write_debug32(sl, addr, option_byte); - } + if (addr == FLASH_F7_OPTCR) { + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F7_OPTCR, + (option_byte & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); + } else if (addr == FLASH_F7_OPTCR1) { + // Read FLASH_F7_OPTCR + uint32_t oldvalue; + stlink_read_debug32(sl, FLASH_F7_OPTCR, &oldvalue); + /* write option byte */ + stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_byte); + // Write FLASH_F7_OPTCR lock and start address + stlink_write_debug32(sl, FLASH_F7_OPTCR, + (oldvalue & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); + } else { + WLOG("WIP: write %#010x to address %#010x\n", option_byte, addr); + stlink_write_debug32(sl, addr, option_byte); + } - wait_flash_busy(sl); + wait_flash_busy(sl); - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t*) base, addr); + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t *)base, + addr); - /* option bytes are reloaded at reset only, no obl. */ + /* option bytes are reloaded at reset only, no obl. */ - return ret; + return ret; } /** @@ -3894,64 +4054,67 @@ static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t* base, stm32_addr_ * @param len number of bytes to write (must be multiple of 4) * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_h7( - stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - uint32_t val; - uint32_t data; - - // Wait until previous flash option has completed - wait_flash_busy(sl); - - // Clear previous error - stlink_write_debug32(sl, FLASH_H7_OPTCCR, 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); - - while (len != 0) { - switch (addr) { - case FLASH_H7_REGS_ADDR + 0x20: // FLASH_OPTSR_PRG - case FLASH_H7_REGS_ADDR + 0x2c: // FLASH_PRAR_PRG1 - case FLASH_H7_REGS_ADDR + 0x34: // FLASH_SCAR_PRG1 - case FLASH_H7_REGS_ADDR + 0x3c: // FLASH_WPSN_PRG1 - case FLASH_H7_REGS_ADDR + 0x44: // FLASH_BOOT_PRG - /* Write to FLASH_xxx_PRG registers */ - write_uint32((unsigned char*)&data, *(uint32_t*)(base)); // write options bytes - - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - - /* Skip if the value in the CUR register is identical */ - stlink_read_debug32(sl, addr - 4, &val); - if (val == data) { - break; - } - - /* Write new option byte values and start modification */ - stlink_write_debug32(sl, addr, data); - stlink_read_debug32(sl, FLASH_H7_OPTCR, &val); - val |= (1 << FLASH_H7_OPTCR_OPTSTART); - stlink_write_debug32(sl, FLASH_H7_OPTCR, val); - - /* Wait for the option bytes modification to complete */ - do { - stlink_read_debug32(sl, FLASH_H7_OPTSR_CUR, &val); - } while ((val & (1 << FLASH_H7_OPTSR_OPT_BUSY)) != 0); - - /* Check for errors */ - if ((val & (1 << FLASH_H7_OPTSR_OPTCHANGEERR)) != 0) { - stlink_write_debug32(sl, FLASH_H7_OPTCCR, 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); - return -1; - } - break; - - default: - /* Skip non-programmable registers */ - break; - } +static int stlink_write_option_bytes_h7(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t val; + uint32_t data; + + // Wait until previous flash option has completed + wait_flash_busy(sl); + + // Clear previous error + stlink_write_debug32(sl, FLASH_H7_OPTCCR, + 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); + + while (len != 0) { + switch (addr) { + case FLASH_H7_REGS_ADDR + 0x20: // FLASH_OPTSR_PRG + case FLASH_H7_REGS_ADDR + 0x2c: // FLASH_PRAR_PRG1 + case FLASH_H7_REGS_ADDR + 0x34: // FLASH_SCAR_PRG1 + case FLASH_H7_REGS_ADDR + 0x3c: // FLASH_WPSN_PRG1 + case FLASH_H7_REGS_ADDR + 0x44: // FLASH_BOOT_PRG + /* Write to FLASH_xxx_PRG registers */ + write_uint32((unsigned char *)&data, + *(uint32_t *)(base)); // write options bytes + + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + + /* Skip if the value in the CUR register is identical */ + stlink_read_debug32(sl, addr - 4, &val); + if (val == data) { + break; + } + + /* Write new option byte values and start modification */ + stlink_write_debug32(sl, addr, data); + stlink_read_debug32(sl, FLASH_H7_OPTCR, &val); + val |= (1 << FLASH_H7_OPTCR_OPTSTART); + stlink_write_debug32(sl, FLASH_H7_OPTCR, val); + + /* Wait for the option bytes modification to complete */ + do { + stlink_read_debug32(sl, FLASH_H7_OPTSR_CUR, &val); + } while ((val & (1 << FLASH_H7_OPTSR_OPT_BUSY)) != 0); + + /* Check for errors */ + if ((val & (1 << FLASH_H7_OPTSR_OPTCHANGEERR)) != 0) { + stlink_write_debug32(sl, FLASH_H7_OPTCCR, + 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); + return -1; + } + break; - len -= 4; - addr += 4; - base += 4; + default: + /* Skip non-programmable registers */ + break; } - return 0; + len -= 4; + addr += 4; + base += 4; + } + + return 0; } /** @@ -3960,8 +4123,9 @@ static int stlink_write_option_bytes_h7( * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_Gx(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); +int stlink_read_option_control_register_Gx(stlink_t *sl, + uint32_t *option_byte) { + return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); } /** @@ -3970,8 +4134,8 @@ int stlink_read_option_control_register_Gx(stlink_t *sl, uint32_t* option_byte) * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_option_control_register_Gx(sl, option_byte); +int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_Gx(sl, option_byte); } /** @@ -3980,8 +4144,9 @@ int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) { * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_f2(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); +int stlink_read_option_control_register_f2(stlink_t *sl, + uint32_t *option_byte) { + return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); } /** @@ -3990,8 +4155,8 @@ int stlink_read_option_control_register_f2(stlink_t *sl, uint32_t* option_byte) * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_option_control_register_f2(sl, option_byte); +int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_f2(sl, option_byte); } /** @@ -4000,8 +4165,9 @@ int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { * @param option_byte value to read * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_f4(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); +int stlink_read_option_control_register_f4(stlink_t *sl, + uint32_t *option_byte) { + return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); } /** @@ -4010,8 +4176,8 @@ int stlink_read_option_control_register_f4(stlink_t *sl, uint32_t* option_byte) * @param option_byte value to read * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_option_control_register_f4(sl, option_byte); +int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_f4(sl, option_byte); } /** @@ -4020,9 +4186,10 @@ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { * @param option_byte value to read * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_f7(stlink_t *sl, uint32_t* option_byte) { - DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_F7_OPTCR); - return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte); +int stlink_read_option_control_register_f7(stlink_t *sl, + uint32_t *option_byte) { + DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_F7_OPTCR); + return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte); } /** @@ -4031,9 +4198,11 @@ int stlink_read_option_control_register_f7(stlink_t *sl, uint32_t* option_byte) * @param option_byte value to read * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register1_f7(stlink_t *sl, uint32_t* option_byte) { - DLOG("@@@@ Read option control register 1 byte from %#10x\n", FLASH_F7_OPTCR1); - return stlink_read_debug32(sl, FLASH_F7_OPTCR1, option_byte); +int stlink_read_option_control_register1_f7(stlink_t *sl, + uint32_t *option_byte) { + DLOG("@@@@ Read option control register 1 byte from %#10x\n", + FLASH_F7_OPTCR1); + return stlink_read_debug32(sl, FLASH_F7_OPTCR1, option_byte); } /** @@ -4042,9 +4211,9 @@ int stlink_read_option_control_register1_f7(stlink_t *sl, uint32_t* option_byte) * @param option_byte value to read * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t* option_byte) { - DLOG("@@@@ Read option byte boot address\n"); - return stlink_read_option_control_register1_f7(sl, option_byte); +int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t *option_byte) { + DLOG("@@@@ Read option byte boot address\n"); + return stlink_read_option_control_register1_f7(sl, option_byte); } /** @@ -4056,18 +4225,22 @@ int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t* option_byte) { * Since multiple bytes can be read, we read and print all but one here * and then return the last one just like other devices */ -int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t* option_byte) { - int err = -1; - for (uint8_t counter = 0; counter < (sl->option_size / 4 - 1); counter++) { - err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), option_byte); - if (err == -1) { - return err; - } else { - printf("%08x\n", *option_byte); - } +int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t *option_byte) { + int err = -1; + for (uint32_t counter = 0; counter < (sl->option_size / 4 - 1); counter++) { + err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), + option_byte); + if (err == -1) { + return err; + } else { + printf("%08x\n", *option_byte); } + } - return stlink_read_debug32(sl, sl->option_base + (uint32_t) (sl->option_size / 4 - 1) * sizeof(uint32_t), option_byte); + return stlink_read_debug32( + sl, + sl->option_base + (uint32_t)(sl->option_size / 4 - 1) * sizeof(uint32_t), + option_byte); } /** @@ -4076,9 +4249,9 @@ int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t* option_byte) { * @param option_byte option value * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { - DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); - return stlink_read_debug32(sl, sl->option_base, option_byte); +int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte) { + DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); + return stlink_read_debug32(sl, sl->option_base, option_byte); } /** @@ -4087,7 +4260,8 @@ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { * @param option_byte value to read * @return 0 on success, -ve on failure. */ -//int stlink_read_option_bytes_boot_add_generic(stlink_t *sl, uint32_t* option_byte) { +// int stlink_read_option_bytes_boot_add_generic(stlink_t *sl, uint32_t* +// option_byte) { // DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); // return stlink_read_debug32(sl, sl->option_base, option_byte); //} @@ -4098,9 +4272,11 @@ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { * @param option_byte value to read * @return 0 on success, -ve on failure. */ -//int stlink_read_option_control_register_generic(stlink_t *sl, uint32_t* option_byte) { -// DLOG("@@@@ Read option control register byte from %#10x\n", sl->option_base); -// return stlink_read_debug32(sl, sl->option_base, option_byte); +// int stlink_read_option_control_register_generic(stlink_t *sl, uint32_t* +// option_byte) { +// DLOG("@@@@ Read option control register byte from %#10x\n", +// sl->option_base); return stlink_read_debug32(sl, sl->option_base, +// option_byte); //} /** @@ -4109,9 +4285,11 @@ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { * @param option_byte value to read * @return 0 on success, -ve on failure. */ -//int stlink_read_option_control_register1_generic(stlink_t *sl, uint32_t* option_byte) { -// DLOG("@@@@ Read option control register 1 byte from %#10x\n", sl->option_base); -// return stlink_read_debug32(sl, sl->option_base, option_byte); +// int stlink_read_option_control_register1_generic(stlink_t *sl, uint32_t* +// option_byte) { +// DLOG("@@@@ Read option control register 1 byte from %#10x\n", +// sl->option_base); return stlink_read_debug32(sl, sl->option_base, +// option_byte); //} /** @@ -4120,28 +4298,28 @@ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { * @param option_byte option value * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) { - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); - return(-1); - } - - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F2: - return stlink_read_option_bytes_f2(sl, option_byte); - case STLINK_CHIPID_STM32_F4: - case STLINK_CHIPID_STM32_F446: - return stlink_read_option_bytes_f4(sl, option_byte); - case STLINK_CHIPID_STM32_F7XXXX: - return stlink_read_option_bytes_f7(sl, option_byte); - case STLINK_CHIPID_STM32_G0_CAT1: - case STLINK_CHIPID_STM32_G0_CAT2: - case STLINK_CHIPID_STM32_G4_CAT2: - case STLINK_CHIPID_STM32_G4_CAT3: - return stlink_read_option_bytes_Gx(sl, option_byte); - default: - return stlink_read_option_bytes_generic(sl, option_byte); - } +int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return (-1); + } + + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F2: + return stlink_read_option_bytes_f2(sl, option_byte); + case STLINK_CHIPID_STM32_F4: + case STLINK_CHIPID_STM32_F446: + return stlink_read_option_bytes_f4(sl, option_byte); + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_bytes_f7(sl, option_byte); + case STLINK_CHIPID_STM32_G0_CAT1: + case STLINK_CHIPID_STM32_G0_CAT2: + case STLINK_CHIPID_STM32_G4_CAT2: + case STLINK_CHIPID_STM32_G4_CAT3: + return stlink_read_option_bytes_Gx(sl, option_byte); + default: + return stlink_read_option_bytes_generic(sl, option_byte); + } } /** @@ -4150,20 +4328,20 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) { * @param option_byte option value * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte) -{ - if (sl->option_base == 0) { - ELOG("Option bytes boot address read is currently not supported for connected chip\n"); - return -1; - } - - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F7XXXX: - return stlink_read_option_bytes_boot_add_f7(sl, option_byte); - default: - return -1; - //return stlink_read_option_bytes_boot_add_generic(sl, option_byte); - } +int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes boot address read is currently not supported for " + "connected chip\n"); + return -1; + } + + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_bytes_boot_add_f7(sl, option_byte); + default: + return -1; + // return stlink_read_option_bytes_boot_add_generic(sl, option_byte); + } } /** @@ -4172,20 +4350,19 @@ int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte) * @param option_byte option value * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register32(stlink_t *sl, uint32_t* option_byte) -{ - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); - return -1; - } +int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F7XXXX: - return stlink_read_option_control_register_f7(sl, option_byte); - default: - return -1; - //return stlink_read_option_control_register_generic(sl, option_byte); - } + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_control_register_f7(sl, option_byte); + default: + return -1; + // return stlink_read_option_control_register_generic(sl, option_byte); + } } /** @@ -4194,20 +4371,20 @@ int stlink_read_option_control_register32(stlink_t *sl, uint32_t* option_byte) * @param option_byte option value * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register1_32(stlink_t *sl, uint32_t* option_byte) -{ - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); - return -1; - } - - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F7XXXX: - return stlink_read_option_control_register1_f7(sl, option_byte); - default: - return -1; - //return stlink_read_option_control_register1_generic(sl, option_byte); - } +int stlink_read_option_control_register1_32(stlink_t *sl, + uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } + + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_control_register1_f7(sl, option_byte); + default: + return -1; + // return stlink_read_option_control_register1_generic(sl, option_byte); + } } /** @@ -4216,10 +4393,11 @@ int stlink_read_option_control_register1_32(stlink_t *sl, uint32_t* option_byte) * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) -{ - WLOG("About to write option byte %#10x to %#10x.\n", option_byte, sl->option_base); - return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *) &option_byte, 4); +int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { + WLOG("About to write option byte %#10x to %#10x.\n", option_byte, + sl->option_base); + return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *)&option_byte, + 4); } /** @@ -4229,73 +4407,76 @@ int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) * @param base option bytes to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { - int ret = -1; - - if (sl->option_base == 0) { - ELOG("Option bytes writing is currently not supported for connected chip\n"); - return(-1); - } - - - if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { - ELOG("Option bytes start address out of Option bytes range\n"); - return(-1); - } - - if (addr + len > sl->option_base + sl->option_size) { - ELOG("Option bytes data too long\n"); - return(-1); - } - - wait_flash_busy(sl); - - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return(-1); - } - - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return(-1); - } - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F4: - ret = stlink_write_option_bytes_f4(sl, base, addr, len); - break; - case STLINK_FLASH_TYPE_F7: - ret = stlink_write_option_bytes_f7(sl, base, addr, len); - break; - case STLINK_FLASH_TYPE_L0: - ret = stlink_write_option_bytes_l0(sl, base, addr, len); - break; - case STLINK_FLASH_TYPE_L4: - ret = stlink_write_option_bytes_l4(sl, base, addr, len); - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - ret = stlink_write_option_bytes_gx(sl, base, addr, len); - break; - case STLINK_FLASH_TYPE_H7: - ret = stlink_write_option_bytes_h7(sl, base, addr, len); - break; - default: - ELOG("Option bytes writing is currently not implemented for connected chip\n"); - break; - } - - if (ret) { - ELOG("Flash option write failed!\n"); - } else { - ILOG("Wrote %d option bytes to %#010x!\n", len, addr); - } - - /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); - - return ret; +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, + uint32_t len) { + int ret = -1; + + if (sl->option_base == 0) { + ELOG( + "Option bytes writing is currently not supported for connected chip\n"); + return (-1); + } + + if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { + ELOG("Option bytes start address out of Option bytes range\n"); + return (-1); + } + + if (addr + len > sl->option_base + sl->option_size) { + ELOG("Option bytes data too long\n"); + return (-1); + } + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return (-1); + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return (-1); + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F4: + ret = stlink_write_option_bytes_f4(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_bytes_f7(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_L0: + ret = stlink_write_option_bytes_l0(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_L4: + ret = stlink_write_option_bytes_l4(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + ret = stlink_write_option_bytes_gx(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_H7: + ret = stlink_write_option_bytes_h7(sl, base, addr, len); + break; + default: + ELOG("Option bytes writing is currently not implemented for connected " + "chip\n"); + break; + } + + if (ret) { + ELOG("Flash option write failed!\n"); + } else { + ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + } + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; } /** @@ -4304,24 +4485,30 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option_control_register) { - int ret = 0; +static int +stlink_write_option_control_register_f7(stlink_t *sl, + uint32_t option_control_register) { + int ret = 0; - // Clear errors - clear_flash_error(sl); + // Clear errors + clear_flash_error(sl); - ILOG("Asked to write option control register 1 %#10x to %#010x.\n", option_control_register, FLASH_F7_OPTCR); + ILOG("Asked to write option control register 1 %#10x to %#010x.\n", + option_control_register, FLASH_F7_OPTCR); - /* write option byte, ensuring we dont lock opt, and set strt bit */ - stlink_write_debug32(sl, FLASH_F7_OPTCR, (option_control_register & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F7_OPTCR, + (option_control_register & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); - wait_flash_busy(sl); + wait_flash_busy(sl); - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, FLASH_F7_OPTCR); + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, + FLASH_F7_OPTCR); - return ret; + return ret; } /** @@ -4330,29 +4517,36 @@ static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t option_control_register1) { - int ret = 0; +static int +stlink_write_option_control_register1_f7(stlink_t *sl, + uint32_t option_control_register1) { + int ret = 0; - // Clear errors - clear_flash_error(sl); + // Clear errors + clear_flash_error(sl); - ILOG("Asked to write option control register 1 %#010x to %#010x.\n", option_control_register1, FLASH_F7_OPTCR1); + ILOG("Asked to write option control register 1 %#010x to %#010x.\n", + option_control_register1, FLASH_F7_OPTCR1); - /* write option byte, ensuring we dont lock opt, and set strt bit */ - uint32_t current_control_register_value; - stlink_read_debug32(sl, FLASH_F7_OPTCR, ¤t_control_register_value); + /* write option byte, ensuring we dont lock opt, and set strt bit */ + uint32_t current_control_register_value; + stlink_read_debug32(sl, FLASH_F7_OPTCR, ¤t_control_register_value); - /* write option byte */ - stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_control_register1); - stlink_write_debug32(sl, FLASH_F7_OPTCR, (current_control_register_value & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); + /* write option byte */ + stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_control_register1); + stlink_write_debug32( + sl, FLASH_F7_OPTCR, + (current_control_register_value & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); - wait_flash_busy(sl); + wait_flash_busy(sl); - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register1, FLASH_F7_OPTCR1); + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register1, + FLASH_F7_OPTCR1); - return ret; + return ret; } /** @@ -4361,9 +4555,11 @@ static int stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t optio * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_boot_add_f7(stlink_t *sl, uint32_t option_byte_boot_add) { - ILOG("Asked to write option byte boot add %#010x.\n", option_byte_boot_add); - return stlink_write_option_control_register1_f7(sl, option_byte_boot_add); +static int +stlink_write_option_bytes_boot_add_f7(stlink_t *sl, + uint32_t option_byte_boot_add) { + ILOG("Asked to write option byte boot add %#010x.\n", option_byte_boot_add); + return stlink_write_option_control_register1_f7(sl, option_byte_boot_add); } /** @@ -4372,41 +4568,43 @@ static int stlink_write_option_bytes_boot_add_f7(stlink_t *sl, uint32_t option_b * @param option bytes boot address to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add) -{ - int ret = -1; +int stlink_write_option_bytes_boot_add32(stlink_t *sl, + uint32_t option_bytes_boot_add) { + int ret = -1; - wait_flash_busy(sl); + wait_flash_busy(sl); - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return -1; + } - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; - } + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: - ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); - break; - default: - ELOG("Option bytes boot address writing is currently not implemented for connected chip\n"); - break; - } + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); + break; + default: + ELOG("Option bytes boot address writing is currently not implemented for " + "connected chip\n"); + break; + } - if (ret) - ELOG("Flash option write failed!\n"); - else - ILOG("Wrote option bytes boot address %#010x!\n", option_bytes_boot_add); + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option bytes boot address %#010x!\n", option_bytes_boot_add); - /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); - return ret; + return ret; } /** @@ -4415,41 +4613,43 @@ int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boo * @param option bytes boot address to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_control_register) -{ - int ret = -1; +int stlink_write_option_control_register32(stlink_t *sl, + uint32_t option_control_register) { + int ret = -1; - wait_flash_busy(sl); + wait_flash_busy(sl); - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return -1; + } - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; - } + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: - ret = stlink_write_option_control_register_f7(sl, option_control_register); - break; - default: - ELOG("Option control register writing is currently not implemented for connected chip\n"); - break; - } + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_control_register_f7(sl, option_control_register); + break; + default: + ELOG("Option control register writing is currently not implemented for " + "connected chip\n"); + break; + } - if (ret) - ELOG("Flash option write failed!\n"); - else - ILOG("Wrote option control register %#010x!\n", option_control_register); + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option control register %#010x!\n", option_control_register); - /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); - return ret; + return ret; } /** @@ -4458,40 +4658,43 @@ int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_control * @param option bytes boot address to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_control_register1) -{ - int ret = -1; +int stlink_write_option_control_register1_32( + stlink_t *sl, uint32_t option_control_register1) { + int ret = -1; - wait_flash_busy(sl); + wait_flash_busy(sl); - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return -1; + } - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; - } + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: - ret = stlink_write_option_control_register1_f7(sl, option_control_register1); - break; - default: - ELOG("Option control register 1 writing is currently not implemented for connected chip\n"); - break; - } + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + ret = + stlink_write_option_control_register1_f7(sl, option_control_register1); + break; + default: + ELOG("Option control register 1 writing is currently not implemented for " + "connected chip\n"); + break; + } - if (ret) - ELOG("Flash option write failed!\n"); - else - ILOG("Wrote option control register 1 %#010x!\n", option_control_register1); + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option control register 1 %#010x!\n", option_control_register1); - lock_flash_option(sl); - lock_flash(sl); + lock_flash_option(sl); + lock_flash(sl); - return(ret); + return (ret); } /** @@ -4501,61 +4704,66 @@ int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_contr * @param addr of the memory mapped option bytes * @return 0 on success, -ve on failure. */ -int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr) { - /* Write the file in flash at addr */ - int err; - mapped_file_t mf = MAPPED_FILE_INITIALIZER; - - if (map_file(&mf, path) == -1) { - ELOG("map_file() == -1\n"); - return(-1); - } +int stlink_fwrite_option_bytes(stlink_t *sl, const char *path, + stm32_addr_t addr) { + /* Write the file in flash at addr */ + int err; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; - printf("file %s ", path); - md5_calculate(&mf); - stlink_checksum(&mf); + if (map_file(&mf, path) == -1) { + ELOG("map_file() == -1\n"); + return (-1); + } - err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t)mf.len); - stlink_fwrite_finalize(sl, addr); - unmap_file(&mf); + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); - return(err); + err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t)mf.len); + stlink_fwrite_finalize(sl, addr); + unmap_file(&mf); + + return (err); } int stlink_target_connect(stlink_t *sl, enum connect_type connect) { - uint32_t dhcsr; - - if (connect == CONNECT_UNDER_RESET) { - stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); + uint32_t dhcsr; - // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) - usleep(20); + if (connect == CONNECT_UNDER_RESET) { + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } - stlink_force_debug(sl); + // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) + usleep(20); - // clear S_RESET_ST in DHCSR register - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { + stlink_enter_swd_mode(sl); + } + stlink_force_debug(sl); - stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); - usleep(10000); + // clear S_RESET_ST in DHCSR register + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - // check NRST connection - dhcsr = 0; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { - WLOG("NRST is not connected\n"); - } + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); + usleep(10000); - // addition soft reset for halt before the first instruction - stlink_soft_reset(sl, 1 /* halt on reset */); + // check NRST connection + dhcsr = 0; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + WLOG("NRST is not connected\n"); } - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } + // addition soft reset for halt before the first instruction + stlink_soft_reset(sl, 1 /* halt on reset */); + } - if (connect == CONNECT_NORMAL) { - stlink_reset(sl, RESET_AUTO); - } + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { + stlink_enter_swd_mode(sl); + } + + if (connect == CONNECT_NORMAL) { + stlink_reset(sl, RESET_AUTO); + } - return stlink_load_device_params(sl); + return stlink_load_device_params(sl); } diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index f28624475..a02c64701 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -1,556 +1,596 @@ +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include #include +#include -#include -#include #include - +#include +#include #define DEFAULT_LOGGING_LEVEL 50 #define DEBUG_LOGGING_LEVEL 100 -#define APP_RESULT_SUCCESS 0 -#define APP_RESULT_INVALID_PARAMS 1 -#define APP_RESULT_STLINK_NOT_FOUND 2 -#define APP_RESULT_STLINK_MISSING_DEVICE 3 -#define APP_RESULT_STLINK_UNSUPPORTED_DEVICE 4 -#define APP_RESULT_STLINK_UNSUPPORTED_LINK 5 -#define APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY 6 -#define APP_RESULT_STLINK_STATE_ERROR 7 +#define APP_RESULT_SUCCESS 0 +#define APP_RESULT_INVALID_PARAMS 1 +#define APP_RESULT_STLINK_NOT_FOUND 2 +#define APP_RESULT_STLINK_MISSING_DEVICE 3 +#define APP_RESULT_STLINK_UNSUPPORTED_DEVICE 4 +#define APP_RESULT_STLINK_UNSUPPORTED_LINK 5 +#define APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY 6 +#define APP_RESULT_STLINK_STATE_ERROR 7 // See D4.2 of https://developer.arm.com/documentation/ddi0403/ed/ -#define TRACE_OP_IS_OVERFLOW(c) ((c) == 0x70) -#define TRACE_OP_IS_LOCAL_TIME(c) (((c) & 0x0f) == 0x00 && ((c) & 0x70) != 0x00) -#define TRACE_OP_IS_EXTENSION(c) (((c) & 0x0b) == 0x08) -#define TRACE_OP_IS_GLOBAL_TIME(c) (((c) & 0xdf) == 0x94) -#define TRACE_OP_IS_SOURCE(c) (((c) & 0x03) != 0x00) -#define TRACE_OP_IS_SW_SOURCE(c) (((c) & 0x03) != 0x00 && ((c) & 0x04) == 0x00) -#define TRACE_OP_IS_HW_SOURCE(c) (((c) & 0x03) != 0x00 && ((c) & 0x04) == 0x04) -#define TRACE_OP_IS_TARGET_SOURCE(c) ((c) == 0x01) -#define TRACE_OP_GET_CONTINUATION(c) ((c) & 0x80) -#define TRACE_OP_GET_SOURCE_SIZE(c) ((c) & 0x03) -#define TRACE_OP_GET_SW_SOURCE_ADDR(c) ((c) >> 3) - +#define TRACE_OP_IS_OVERFLOW(c) ((c) == 0x70) +#define TRACE_OP_IS_LOCAL_TIME(c) (((c)&0x0f) == 0x00 && ((c)&0x70) != 0x00) +#define TRACE_OP_IS_EXTENSION(c) (((c)&0x0b) == 0x08) +#define TRACE_OP_IS_GLOBAL_TIME(c) (((c)&0xdf) == 0x94) +#define TRACE_OP_IS_SOURCE(c) (((c)&0x03) != 0x00) +#define TRACE_OP_IS_SW_SOURCE(c) (((c)&0x03) != 0x00 && ((c)&0x04) == 0x00) +#define TRACE_OP_IS_HW_SOURCE(c) (((c)&0x03) != 0x00 && ((c)&0x04) == 0x04) +#define TRACE_OP_IS_TARGET_SOURCE(c) ((c) == 0x01) +#define TRACE_OP_GET_CONTINUATION(c) ((c)&0x80) +#define TRACE_OP_GET_SOURCE_SIZE(c) ((c)&0x03) +#define TRACE_OP_GET_SW_SOURCE_ADDR(c) ((c) >> 3) typedef struct { - bool show_help; - bool show_version; - int logging_level; - uint32_t core_frequency; - uint32_t trace_frequency; - bool reset_board; - bool force; - char* serial_number; + bool show_help; + bool show_version; + int logging_level; + uint32_t core_frequency; + uint32_t trace_frequency; + bool reset_board; + bool force; + char *serial_number; } st_settings_t; - // We use a simple state machine to parse the trace data. typedef enum { - TRACE_STATE_UNKNOWN, - TRACE_STATE_IDLE, - TRACE_STATE_TARGET_SOURCE, - TRACE_STATE_SKIP_FRAME, - TRACE_STATE_SKIP_4, - TRACE_STATE_SKIP_3, - TRACE_STATE_SKIP_2, - TRACE_STATE_SKIP_1, + TRACE_STATE_UNKNOWN, + TRACE_STATE_IDLE, + TRACE_STATE_TARGET_SOURCE, + TRACE_STATE_SKIP_FRAME, + TRACE_STATE_SKIP_4, + TRACE_STATE_SKIP_3, + TRACE_STATE_SKIP_2, + TRACE_STATE_SKIP_1, } trace_state; typedef struct { - time_t start_time; - bool configuration_checked; + time_t start_time; + bool configuration_checked; - trace_state state; + trace_state state; - uint32_t count_raw_bytes; - uint32_t count_target_data; - uint32_t count_time_packets; - uint32_t count_hw_overflow; - uint32_t count_sw_overflow; - uint32_t count_error; + uint32_t count_raw_bytes; + uint32_t count_target_data; + uint32_t count_time_packets; + uint32_t count_hw_overflow; + uint32_t count_sw_overflow; + uint32_t count_error; - uint8_t unknown_opcodes[256 / 8]; - uint32_t unknown_sources; + uint8_t unknown_opcodes[256 / 8]; + uint32_t unknown_sources; } st_trace_t; - -// We use a global flag to allow communicating to the main thread from the signal handler. +// We use a global flag to allow communicating to the main thread from the +// signal handler. static bool g_abort_trace = false; -static void abort_trace() { - g_abort_trace = true; -} +static void abort_trace() { g_abort_trace = true; } #if defined(_WIN32) BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { - (void)fdwCtrlType; - abort_trace(); - return FALSE; + (void)fdwCtrlType; + abort_trace(); + return FALSE; } #endif static void usage(void) { - puts("st-trace - usage:"); - puts(" -h, --help Print this help"); - puts(" -V, --version Print this version"); - puts(" -vXX, --verbose=XX Specify a specific verbosity level (0..99)"); - puts(" -v, --verbose Specify a generally verbose logging"); - puts(" -cXX, --clock=XX Specify the core frequency in MHz"); - puts(" -tXX, --trace=XX Specify the trace frequency in Hz"); - puts(" -n, --no-reset Do not reset board on connection"); - puts(" -sXX, --serial=XX Use a specific serial number"); - puts(" -f, --force Ignore most initialization errors"); + puts("st-trace - usage:"); + puts(" -h, --help Print this help"); + puts(" -V, --version Print this version"); + puts(" -vXX, --verbose=XX Specify a specific verbosity level (0..99)"); + puts(" -v, --verbose Specify a generally verbose logging"); + puts(" -cXX, --clock=XX Specify the core frequency in MHz"); + puts(" -tXX, --trace=XX Specify the trace frequency in Hz"); + puts(" -n, --no-reset Do not reset board on connection"); + puts(" -sXX, --serial=XX Use a specific serial number"); + puts(" -f, --force Ignore most initialization errors"); } -bool parse_options(int argc, char** argv, st_settings_t *settings) { - - static struct option long_options[] = { - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'V'}, - {"verbose", optional_argument, NULL, 'v'}, - {"clock", required_argument, NULL, 'c'}, - {"trace", required_argument, NULL, 't'}, - {"no-reset", no_argument, NULL, 'n'}, - {"serial", required_argument, NULL, 's'}, - {"force", no_argument, NULL, 'f'}, - {0, 0, 0, 0}, - }; - int option_index = 0; - int c; - bool error = false; - - settings->show_help = false; - settings->show_version = false; - settings->logging_level = DEFAULT_LOGGING_LEVEL; - settings->core_frequency = 0; - settings->trace_frequency = 0; - settings->reset_board = true; - settings->force = false; - settings->serial_number = NULL; - ugly_init(settings->logging_level); - - while ((c = getopt_long(argc, argv, "hVv::c:ns:f", long_options, &option_index)) != -1) { - switch (c) { - case 'h': - settings->show_help = true; - break; - case 'V': - settings->show_version = true; - break; - case 'v': - if (optarg) { - settings->logging_level = atoi(optarg); - } else { - settings->logging_level = DEBUG_LOGGING_LEVEL; - } - ugly_init(settings->logging_level); - break; - case 'c': - settings->core_frequency = atoi(optarg) * 1000000; - break; - case 't': - settings->trace_frequency = atoi(optarg); - break; - case 'n': - settings->reset_board = false; - break; - case 'f': - settings->force = true; - break; - case 's': - settings->serial_number = optarg; - break; - case '?': - error = true; - break; - default: - ELOG("Unknown command line option: '%c' (0x%02x)\n", c, c); - error = true; - break; - } +bool parse_options(int argc, char **argv, st_settings_t *settings) { + + static struct option long_options[] = { + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'V'}, + {"verbose", optional_argument, NULL, 'v'}, + {"clock", required_argument, NULL, 'c'}, + {"trace", required_argument, NULL, 't'}, + {"no-reset", no_argument, NULL, 'n'}, + {"serial", required_argument, NULL, 's'}, + {"force", no_argument, NULL, 'f'}, + {0, 0, 0, 0}, + }; + int option_index = 0; + int c; + bool error = false; + + settings->show_help = false; + settings->show_version = false; + settings->logging_level = DEFAULT_LOGGING_LEVEL; + settings->core_frequency = 0; + settings->trace_frequency = 0; + settings->reset_board = true; + settings->force = false; + settings->serial_number = NULL; + ugly_init(settings->logging_level); + + while ((c = getopt_long(argc, argv, "hVv::c:ns:f", long_options, + &option_index)) != -1) { + switch (c) { + case 'h': + settings->show_help = true; + break; + case 'V': + settings->show_version = true; + break; + case 'v': + if (optarg) { + settings->logging_level = atoi(optarg); + } else { + settings->logging_level = DEBUG_LOGGING_LEVEL; + } + ugly_init(settings->logging_level); + break; + case 'c': + settings->core_frequency = atoi(optarg) * 1000000; + break; + case 't': + settings->trace_frequency = atoi(optarg); + break; + case 'n': + settings->reset_board = false; + break; + case 'f': + settings->force = true; + break; + case 's': + settings->serial_number = optarg; + break; + case '?': + error = true; + break; + default: + ELOG("Unknown command line option: '%c' (0x%02x)\n", c, c); + error = true; + break; } + } - if (optind < argc) { - while (optind < argc) { - ELOG("Unknown command line argument: '%s'\n", argv[optind++]); - } - error = true; + if (optind < argc) { + while (optind < argc) { + ELOG("Unknown command line argument: '%s'\n", argv[optind++]); } + error = true; + } - if (error && !settings->force) - return false; + if (error && !settings->force) + return false; - return true; + return true; } -static stlink_t* stlink_connect(const st_settings_t* settings) { - return stlink_open_usb(settings->logging_level, false, settings->serial_number, 0); +static stlink_t *stlink_connect(const st_settings_t *settings) { + return stlink_open_usb(settings->logging_level, false, + settings->serial_number, 0); } -static bool enable_trace(stlink_t* stlink, const st_settings_t* settings, uint32_t trace_frequency) { - - if (stlink_force_debug(stlink)) { - ELOG("Unable to debug device\n"); - if (!settings->force) - return false; - } - - if (settings->reset_board && stlink_reset(stlink, RESET_AUTO)) { - ELOG("Unable to reset device\n"); - if (!settings->force) - return false; - } - - - stlink_write_debug32(stlink, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | - STLINK_REG_DHCSR_C_DEBUGEN | - STLINK_REG_DHCSR_C_HALT); - stlink_write_debug32(stlink, STLINK_REG_DEMCR, STLINK_REG_DEMCR_TRCENA); - stlink_write_debug32(stlink, STLINK_REG_CM3_FP_CTRL, STLINK_REG_CM3_FP_CTRL_KEY); - stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION0, 0); - stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION1, 0); - stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION2, 0); - stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION3, 0); - stlink_write_debug32(stlink, STLINK_REG_DWT_CTRL, 0); - stlink_write_debug32(stlink, STLINK_REG_DBGMCU_CR, STLINK_REG_DBGMCU_CR_DBG_SLEEP | - STLINK_REG_DBGMCU_CR_DBG_STOP | - STLINK_REG_DBGMCU_CR_DBG_STANDBY | - STLINK_REG_DBGMCU_CR_TRACE_IOEN | - STLINK_REG_DBGMCU_CR_TRACE_MODE_ASYNC); - - if (stlink_trace_enable(stlink, trace_frequency)) { - ELOG("Unable to turn on tracing in stlink\n"); - if (!settings->force) - return false; - } - - stlink_write_debug32(stlink, STLINK_REG_TPI_CSPSR, STLINK_REG_TPI_CSPSR_PORT_SIZE_1); - - if (settings->core_frequency) { - uint32_t prescaler = settings->core_frequency / trace_frequency - 1; - if (prescaler > STLINK_REG_TPI_ACPR_MAX) { - ELOG("Trace frequency prescaler %d out of range. Try setting a faster trace frequency.\n", prescaler); - if (!settings->force) - return false; - } - stlink_write_debug32(stlink, STLINK_REG_TPI_ACPR, prescaler); // Set TPIU_ACPR clock divisor - } - stlink_write_debug32(stlink, STLINK_REG_TPI_FFCR, STLINK_REG_TPI_FFCR_TRIG_IN); - stlink_write_debug32(stlink, STLINK_REG_TPI_SPPR, STLINK_REG_TPI_SPPR_SWO_NRZ); - stlink_write_debug32(stlink, STLINK_REG_ITM_LAR, STLINK_REG_ITM_LAR_KEY); - stlink_write_debug32(stlink, STLINK_REG_ITM_TCC, 0x00000400); // Set sync counter - stlink_write_debug32(stlink, STLINK_REG_ITM_TCR, STLINK_REG_ITM_TCR_TRACE_BUS_ID_1 | - STLINK_REG_ITM_TCR_TS_ENA | - STLINK_REG_ITM_TCR_ITM_ENA); - stlink_write_debug32(stlink, STLINK_REG_ITM_TER, STLINK_REG_ITM_TER_PORTS_ALL); - stlink_write_debug32(stlink, STLINK_REG_ITM_TPR, STLINK_REG_ITM_TPR_PORTS_ALL); - stlink_write_debug32(stlink, STLINK_REG_DWT_CTRL, 4 * STLINK_REG_DWT_CTRL_NUM_COMP | - STLINK_REG_DWT_CTRL_CYC_TAP | - 0xF * STLINK_REG_DWT_CTRL_POST_INIT | - 0xF * STLINK_REG_DWT_CTRL_POST_PRESET | - STLINK_REG_DWT_CTRL_CYCCNT_ENA); - stlink_write_debug32(stlink, STLINK_REG_DEMCR, STLINK_REG_DEMCR_TRCENA); - - uint32_t prescaler; - stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR_MAX, &prescaler); - if (prescaler) { - uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; - uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; - ILOG("Trace Port Interface configured to expect a %d MHz system clock.\n", system_clock_speed_mhz); - } else { - WLOG("Trace Port Interface not configured. Specify the system clock with a --clock=XX command\n"); - WLOG("line option or set it in your device's clock initialization routine, such as with:\n"); - WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / %d - 1;\n", trace_frequency); +static bool enable_trace(stlink_t *stlink, const st_settings_t *settings, + uint32_t trace_frequency) { + + if (stlink_force_debug(stlink)) { + ELOG("Unable to debug device\n"); + if (!settings->force) + return false; + } + + if (settings->reset_board && stlink_reset(stlink, RESET_AUTO)) { + ELOG("Unable to reset device\n"); + if (!settings->force) + return false; + } + + stlink_write_debug32(stlink, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + STLINK_REG_DHCSR_C_HALT); + stlink_write_debug32(stlink, STLINK_REG_DEMCR, STLINK_REG_DEMCR_TRCENA); + stlink_write_debug32(stlink, STLINK_REG_CM3_FP_CTRL, + STLINK_REG_CM3_FP_CTRL_KEY); + stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION0, 0); + stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION1, 0); + stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION2, 0); + stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION3, 0); + stlink_write_debug32(stlink, STLINK_REG_DWT_CTRL, 0); + stlink_write_debug32( + stlink, STLINK_REG_DBGMCU_CR, + STLINK_REG_DBGMCU_CR_DBG_SLEEP | STLINK_REG_DBGMCU_CR_DBG_STOP | + STLINK_REG_DBGMCU_CR_DBG_STANDBY | STLINK_REG_DBGMCU_CR_TRACE_IOEN | + STLINK_REG_DBGMCU_CR_TRACE_MODE_ASYNC); + + if (stlink_trace_enable(stlink, trace_frequency)) { + ELOG("Unable to turn on tracing in stlink\n"); + if (!settings->force) + return false; + } + + stlink_write_debug32(stlink, STLINK_REG_TPI_CSPSR, + STLINK_REG_TPI_CSPSR_PORT_SIZE_1); + + if (settings->core_frequency) { + uint32_t prescaler = settings->core_frequency / trace_frequency - 1; + if (prescaler > STLINK_REG_TPI_ACPR_MAX) { + ELOG("Trace frequency prescaler %d out of range. Try setting a faster " + "trace frequency.\n", + prescaler); + if (!settings->force) + return false; } - ILOG("Trace frequency set to %d Hz.\n", trace_frequency); - - return true; + stlink_write_debug32(stlink, STLINK_REG_TPI_ACPR, + prescaler); // Set TPIU_ACPR clock divisor + } + stlink_write_debug32(stlink, STLINK_REG_TPI_FFCR, + STLINK_REG_TPI_FFCR_TRIG_IN); + stlink_write_debug32(stlink, STLINK_REG_TPI_SPPR, + STLINK_REG_TPI_SPPR_SWO_NRZ); + stlink_write_debug32(stlink, STLINK_REG_ITM_LAR, STLINK_REG_ITM_LAR_KEY); + stlink_write_debug32(stlink, STLINK_REG_ITM_TCC, + 0x00000400); // Set sync counter + stlink_write_debug32(stlink, STLINK_REG_ITM_TCR, + STLINK_REG_ITM_TCR_TRACE_BUS_ID_1 | + STLINK_REG_ITM_TCR_TS_ENA | + STLINK_REG_ITM_TCR_ITM_ENA); + stlink_write_debug32(stlink, STLINK_REG_ITM_TER, + STLINK_REG_ITM_TER_PORTS_ALL); + stlink_write_debug32(stlink, STLINK_REG_ITM_TPR, + STLINK_REG_ITM_TPR_PORTS_ALL); + stlink_write_debug32(stlink, STLINK_REG_DWT_CTRL, + 4 * STLINK_REG_DWT_CTRL_NUM_COMP | + STLINK_REG_DWT_CTRL_CYC_TAP | + 0xF * STLINK_REG_DWT_CTRL_POST_INIT | + 0xF * STLINK_REG_DWT_CTRL_POST_PRESET | + STLINK_REG_DWT_CTRL_CYCCNT_ENA); + stlink_write_debug32(stlink, STLINK_REG_DEMCR, STLINK_REG_DEMCR_TRCENA); + + uint32_t prescaler; + stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR_MAX, &prescaler); + if (prescaler) { + uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; + uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; + ILOG("Trace Port Interface configured to expect a %d MHz system clock.\n", + system_clock_speed_mhz); + } else { + WLOG("Trace Port Interface not configured. Specify the system clock with " + "a --clock=XX command\n"); + WLOG("line option or set it in your device's clock initialization routine, " + "such as with:\n"); + WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / %d - 1;\n", trace_frequency); + } + ILOG("Trace frequency set to %d Hz.\n", trace_frequency); + + return true; } -static trace_state update_trace_idle(st_trace_t* trace, uint8_t c) { - // Handle a trace byte when we are in the idle state. - - if (TRACE_OP_IS_TARGET_SOURCE(c)) { - return TRACE_STATE_TARGET_SOURCE; - } - - if (TRACE_OP_IS_SOURCE(c)) { - uint8_t size = TRACE_OP_GET_SOURCE_SIZE(c); - if (TRACE_OP_IS_SW_SOURCE(c)) { - uint8_t addr = TRACE_OP_GET_SW_SOURCE_ADDR(c); - if (!(trace->unknown_sources & (1 << addr))) - WLOG("Unsupported source 0x%x size %d\n", addr, size); - trace->unknown_sources |= (1 << addr); - } - if (size == 1) return TRACE_STATE_SKIP_1; - if (size == 2) return TRACE_STATE_SKIP_2; - if (size == 3) return TRACE_STATE_SKIP_4; - } - - if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { - trace->count_time_packets++; - return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; - } - - if (TRACE_OP_IS_EXTENSION(c)) { - return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; - } - - if (TRACE_OP_IS_OVERFLOW(c)) { - trace->count_hw_overflow++; - } - - if (!(trace->unknown_opcodes[c / 8] & (1 << c % 8))) - WLOG("Unknown opcode 0x%02x\n", c); - trace->unknown_opcodes[c / 8] |= (1 << c % 8); - - trace->count_error++; - return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; +static trace_state update_trace_idle(st_trace_t *trace, uint8_t c) { + // Handle a trace byte when we are in the idle state. + + if (TRACE_OP_IS_TARGET_SOURCE(c)) { + return TRACE_STATE_TARGET_SOURCE; + } + + if (TRACE_OP_IS_SOURCE(c)) { + uint8_t size = TRACE_OP_GET_SOURCE_SIZE(c); + if (TRACE_OP_IS_SW_SOURCE(c)) { + uint8_t addr = TRACE_OP_GET_SW_SOURCE_ADDR(c); + if (!(trace->unknown_sources & (1 << addr))) + WLOG("Unsupported source 0x%x size %d\n", addr, size); + trace->unknown_sources |= (1 << addr); + } + if (size == 1) + return TRACE_STATE_SKIP_1; + if (size == 2) + return TRACE_STATE_SKIP_2; + if (size == 3) + return TRACE_STATE_SKIP_4; + } + + if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { + trace->count_time_packets++; + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME + : TRACE_STATE_IDLE; + } + + if (TRACE_OP_IS_EXTENSION(c)) { + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME + : TRACE_STATE_IDLE; + } + + if (TRACE_OP_IS_OVERFLOW(c)) { + trace->count_hw_overflow++; + } + + if (!(trace->unknown_opcodes[c / 8] & (1 << c % 8))) + WLOG("Unknown opcode 0x%02x\n", c); + trace->unknown_opcodes[c / 8] |= (1 << c % 8); + + trace->count_error++; + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME + : TRACE_STATE_IDLE; } -static trace_state update_trace(st_trace_t* trace, uint8_t c) { - trace->count_raw_bytes++; +static trace_state update_trace(st_trace_t *trace, uint8_t c) { + trace->count_raw_bytes++; - // Parse the input using a state machine. + // Parse the input using a state machine. - if (trace->state == TRACE_STATE_UNKNOWN) { - if (TRACE_OP_IS_TARGET_SOURCE(c) || TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) - trace->state = TRACE_STATE_IDLE; - } + if (trace->state == TRACE_STATE_UNKNOWN) { + if (TRACE_OP_IS_TARGET_SOURCE(c) || TRACE_OP_IS_LOCAL_TIME(c) || + TRACE_OP_IS_GLOBAL_TIME(c)) + trace->state = TRACE_STATE_IDLE; + } - switch (trace->state) - { - case TRACE_STATE_IDLE: - return update_trace_idle(trace, c); + switch (trace->state) { + case TRACE_STATE_IDLE: + return update_trace_idle(trace, c); - case TRACE_STATE_TARGET_SOURCE: - putchar(c); - if (c == '\n') - fflush(stdout); - trace->count_target_data++; - return TRACE_STATE_IDLE; + case TRACE_STATE_TARGET_SOURCE: + putchar(c); + if (c == '\n') + fflush(stdout); + trace->count_target_data++; + return TRACE_STATE_IDLE; - case TRACE_STATE_SKIP_FRAME: - return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; + case TRACE_STATE_SKIP_FRAME: + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME + : TRACE_STATE_IDLE; - case TRACE_STATE_SKIP_4: - return TRACE_STATE_SKIP_3; + case TRACE_STATE_SKIP_4: + return TRACE_STATE_SKIP_3; - case TRACE_STATE_SKIP_3: - return TRACE_STATE_SKIP_2; + case TRACE_STATE_SKIP_3: + return TRACE_STATE_SKIP_2; - case TRACE_STATE_SKIP_2: - return TRACE_STATE_SKIP_1; + case TRACE_STATE_SKIP_2: + return TRACE_STATE_SKIP_1; - case TRACE_STATE_SKIP_1: - return TRACE_STATE_IDLE; + case TRACE_STATE_SKIP_1: + return TRACE_STATE_IDLE; - case TRACE_STATE_UNKNOWN: - return TRACE_STATE_UNKNOWN; + case TRACE_STATE_UNKNOWN: + return TRACE_STATE_UNKNOWN; - default: - ELOG("Invalid state %d. This should never happen\n", trace->state); - return TRACE_STATE_IDLE; - } + default: + ELOG("Invalid state %d. This should never happen\n", trace->state); + return TRACE_STATE_IDLE; + } } -static bool read_trace(stlink_t* stlink, st_trace_t* trace) { - uint8_t buffer[STLINK_TRACE_BUF_LEN]; - int length = stlink_trace_read(stlink, buffer, sizeof(buffer)); - - if (length < 0) { - ELOG("Error reading trace (%d)\n", length); - return false; - } - - if (length == 0) { - usleep(100); - return true; - } - - if (length == sizeof(buffer)) { - if (trace->count_sw_overflow++) - DLOG("Buffer overflow.\n"); - else - WLOG("Buffer overflow. Try using a slower trace frequency.\n"); - trace->state = TRACE_STATE_UNKNOWN; - } +static bool read_trace(stlink_t *stlink, st_trace_t *trace) { + uint8_t buffer[STLINK_TRACE_BUF_LEN]; + int length = stlink_trace_read(stlink, buffer, sizeof(buffer)); - for (int i = 0; i < length; i++) { - trace->state = update_trace(trace, buffer[i]); - } + if (length < 0) { + ELOG("Error reading trace (%d)\n", length); + return false; + } + if (length == 0) { + usleep(100); return true; -} - -static void check_for_configuration_error(stlink_t* stlink, st_trace_t* trace, uint32_t trace_frequency) { - // Only check configuration one time after the first 10 seconds of running. - time_t elapsed_time_s = time(NULL) - trace->start_time; - if (trace->configuration_checked || elapsed_time_s < 10) { - return; - } - trace->configuration_checked = true; + } - // Simple huristic to determine if we are configured poorly. - bool error_no_data = (trace->count_raw_bytes < 100); - bool error_low_data = (trace->count_time_packets < 10 && trace->count_target_data < 1000); - bool error_bad_data = (trace->count_error > 1 || trace->unknown_sources > 0); - bool error_dropped_data = (trace->count_sw_overflow > 0); + if (length == sizeof(buffer)) { + if (trace->count_sw_overflow++) + DLOG("Buffer overflow.\n"); + else + WLOG("Buffer overflow. Try using a slower trace frequency.\n"); + trace->state = TRACE_STATE_UNKNOWN; + } - if (!error_no_data && !error_low_data && !error_bad_data && !error_dropped_data) - return; - - WLOG("****\n"); - WLOG("We do not appear to be retrieving data from the stlink correctly.\n"); - - if (error_dropped_data) { - WLOG("Try setting a slower trace frequency with the --trace=%d command line option.\n", trace_frequency / 2); - } + for (int i = 0; i < length; i++) { + trace->state = update_trace(trace, buffer[i]); + } - if (error_no_data || error_low_data || error_bad_data) { - uint32_t prescaler; - stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR, &prescaler); - if (prescaler) { - uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; - uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; - WLOG("Verify the system clock is running at %d MHz.\n", system_clock_speed_mhz); - } - WLOG("Try specifying the system clock with the --clock=XX command line option.\n"); - WLOG("Try setting the trace speed in your device's clock initialization routine:\n"); - WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / %d - 1;\n", trace_frequency); - } + return true; +} - WLOG("Diagnostic Information:\n"); - WLOG("Raw Bytes: %d\n", trace->count_raw_bytes); - WLOG("Target Data: %d\n", trace->count_target_data); - WLOG("Time Packets: %d\n", trace->count_time_packets); - WLOG("Hardware Overflow Count: %d\n", trace->count_hw_overflow); - WLOG("Software Overflow Count: %d\n", trace->count_sw_overflow); - WLOG("Errors: %d\n", trace->count_error); - - char buffer[1024]; - memset(buffer, 0, sizeof(buffer)); - uint32_t offset = 0; - for (uint32_t i = 0; i <= 0xFF; i++) - if (trace->unknown_opcodes[i / 8] & (1 << i % 8)) - offset += snprintf(buffer + offset, sizeof(buffer) - offset, "%02x, ", i); - WLOG("Unknown Opcodes: %s\n", buffer); - - memset(buffer, 0, sizeof(buffer)); - offset = 0; - for (uint32_t i = 0; i < 32; i++) - if (trace->unknown_sources & (1 << i)) - offset += snprintf(buffer + offset, sizeof(buffer) - offset, "%d, ", i); - WLOG("Unknown Sources: %s\n", buffer); - - WLOG("Chip ID: 0x%04x\n", stlink->chip_id); - WLOG("****\n"); +static void check_for_configuration_error(stlink_t *stlink, st_trace_t *trace, + uint32_t trace_frequency) { + // Only check configuration one time after the first 10 seconds of running. + time_t elapsed_time_s = time(NULL) - trace->start_time; + if (trace->configuration_checked || elapsed_time_s < 10) { + return; + } + trace->configuration_checked = true; + + // Simple huristic to determine if we are configured poorly. + bool error_no_data = (trace->count_raw_bytes < 100); + bool error_low_data = + (trace->count_time_packets < 10 && trace->count_target_data < 1000); + bool error_bad_data = (trace->count_error > 1 || trace->unknown_sources > 0); + bool error_dropped_data = (trace->count_sw_overflow > 0); + + if (!error_no_data && !error_low_data && !error_bad_data && + !error_dropped_data) + return; + + WLOG("****\n"); + WLOG("We do not appear to be retrieving data from the stlink correctly.\n"); + + if (error_dropped_data) { + WLOG("Try setting a slower trace frequency with the --trace=%d command " + "line option.\n", + trace_frequency / 2); + } + + if (error_no_data || error_low_data || error_bad_data) { + uint32_t prescaler; + stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR, &prescaler); + if (prescaler) { + uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; + uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; + WLOG("Verify the system clock is running at %d MHz.\n", + system_clock_speed_mhz); + } + WLOG("Try specifying the system clock with the --clock=XX command line " + "option.\n"); + WLOG("Try setting the trace speed in your device's clock initialization " + "routine:\n"); + WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / %d - 1;\n", trace_frequency); + } + + WLOG("Diagnostic Information:\n"); + WLOG("Raw Bytes: %d\n", trace->count_raw_bytes); + WLOG("Target Data: %d\n", trace->count_target_data); + WLOG("Time Packets: %d\n", trace->count_time_packets); + WLOG("Hardware Overflow Count: %d\n", trace->count_hw_overflow); + WLOG("Software Overflow Count: %d\n", trace->count_sw_overflow); + WLOG("Errors: %d\n", trace->count_error); + + char buffer[1024]; + memset(buffer, 0, sizeof(buffer)); + uint32_t offset = 0; + for (uint32_t i = 0; i <= 0xFF; i++) + if (trace->unknown_opcodes[i / 8] & (1 << i % 8)) { + uint32_t n = + snprintf(buffer + offset, sizeof(buffer) - offset, "%02x, ", i); + if (n >= sizeof(buffer) - offset) { + break; + } + offset += n; + } + WLOG("Unknown Opcodes: %s\n", buffer); + + memset(buffer, 0, sizeof(buffer)); + offset = 0; + for (uint32_t i = 0; i < 32; i++) + if (trace->unknown_sources & (1 << i)) { + uint32_t n = + snprintf(buffer + offset, sizeof(buffer) - offset, "%d, ", i); + if (n >= sizeof(buffer) - offset) { + break; + } + offset += n; + } + WLOG("Unknown Sources: %s\n", buffer); + + WLOG("Chip ID: 0x%04x\n", stlink->chip_id); + WLOG("****\n"); } -int main(int argc, char** argv) -{ +int main(int argc, char **argv) { #if defined(_WIN32) - SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); + SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); #else - signal(SIGINT, &abort_trace); - signal(SIGTERM, &abort_trace); - signal(SIGSEGV, &abort_trace); - signal(SIGPIPE, &abort_trace); + signal(SIGINT, &abort_trace); + signal(SIGTERM, &abort_trace); + signal(SIGSEGV, &abort_trace); + signal(SIGPIPE, &abort_trace); #endif + st_settings_t settings; + if (!parse_options(argc, argv, &settings)) { + usage(); + return APP_RESULT_INVALID_PARAMS; + } + + DLOG("show_help = %s\n", settings.show_help ? "true" : "false"); + DLOG("show_version = %s\n", settings.show_version ? "true" : "false"); + DLOG("logging_level = %d\n", settings.logging_level); + DLOG("core_frequency = %d Hz\n", settings.core_frequency); + DLOG("trace_frequency = %d Hz\n", settings.trace_frequency); + DLOG("reset_board = %s\n", settings.reset_board ? "true" : "false"); + DLOG("force = %s\n", settings.force ? "true" : "false"); + DLOG("serial_number = %s\n", + settings.serial_number ? settings.serial_number : "any"); + + if (settings.show_help) { + usage(); + return APP_RESULT_SUCCESS; + } - st_settings_t settings; - if (!parse_options(argc, argv, &settings)) { - usage(); - return APP_RESULT_INVALID_PARAMS; - } - - DLOG("show_help = %s\n", settings.show_help ? "true" : "false"); - DLOG("show_version = %s\n", settings.show_version ? "true" : "false"); - DLOG("logging_level = %d\n", settings.logging_level); - DLOG("core_frequency = %d Hz\n", settings.core_frequency); - DLOG("trace_frequency = %d Hz\n", settings.trace_frequency); - DLOG("reset_board = %s\n", settings.reset_board ? "true" : "false"); - DLOG("force = %s\n", settings.force ? "true" : "false"); - DLOG("serial_number = %s\n", settings.serial_number ? settings.serial_number : "any"); - - if (settings.show_help) { - usage(); - return APP_RESULT_SUCCESS; - } - - if (settings.show_version) { - printf("v%s\n", STLINK_VERSION); - return APP_RESULT_SUCCESS; - } - - stlink_t* stlink = stlink_connect(&settings); - if (!stlink) { - ELOG("Unable to locate an stlink\n"); - return APP_RESULT_STLINK_NOT_FOUND; - } - - stlink->verbose = settings.logging_level; - - if (stlink->chip_id == STLINK_CHIPID_UNKNOWN) { - ELOG("Your stlink is not connected to a device\n"); - if (!settings.force) - return APP_RESULT_STLINK_MISSING_DEVICE; - } - - if (!(stlink->version.flags & STLINK_F_HAS_TRACE)) { - ELOG("Your stlink does not support tracing\n"); - if (!settings.force) - return APP_RESULT_STLINK_UNSUPPORTED_LINK; - } - - if (!(stlink->chip_flags & CHIP_F_HAS_SWO_TRACING)) { - const struct stlink_chipid_params *params = stlink_chipid_get_params(stlink->chip_id); - ELOG("We do not support SWO output for device '%s'\n", params->description); - if (!settings.force) - return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; - } - - uint32_t trace_frequency = settings.trace_frequency; - if (!trace_frequency) - trace_frequency = STLINK_DEFAULT_TRACE_FREQUENCY; - if (trace_frequency > stlink->max_trace_freq) { - ELOG("Invalid trace frequency %d (max %d)\n", trace_frequency, stlink->max_trace_freq); - if (!settings.force) - return APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY; - } - - if (!enable_trace(stlink, &settings, trace_frequency)) { - ELOG("Unable to enable trace mode\n"); - if (!settings.force) - return APP_RESULT_STLINK_STATE_ERROR; - } - - ILOG("Reading Trace\n"); - st_trace_t trace; - memset(&trace, 0, sizeof(trace)); - trace.start_time = time(NULL); - - if (stlink_run(stlink, RUN_NORMAL)) { - ELOG("Unable to run device\n"); - if (!settings.force) - return APP_RESULT_STLINK_STATE_ERROR; - } - - while (!g_abort_trace && read_trace(stlink, &trace)) { - check_for_configuration_error(stlink, &trace, trace_frequency); - } - - stlink_trace_disable(stlink); - stlink_close(stlink); - + if (settings.show_version) { + printf("v%s\n", STLINK_VERSION); return APP_RESULT_SUCCESS; + } + + stlink_t *stlink = stlink_connect(&settings); + if (!stlink) { + ELOG("Unable to locate an stlink\n"); + return APP_RESULT_STLINK_NOT_FOUND; + } + + stlink->verbose = settings.logging_level; + + if (stlink->chip_id == STLINK_CHIPID_UNKNOWN) { + ELOG("Your stlink is not connected to a device\n"); + if (!settings.force) + return APP_RESULT_STLINK_MISSING_DEVICE; + } + + if (!(stlink->version.flags & STLINK_F_HAS_TRACE)) { + ELOG("Your stlink does not support tracing\n"); + if (!settings.force) + return APP_RESULT_STLINK_UNSUPPORTED_LINK; + } + + if (!(stlink->chip_flags & CHIP_F_HAS_SWO_TRACING)) { + const struct stlink_chipid_params *params = + stlink_chipid_get_params(stlink->chip_id); + ELOG("We do not support SWO output for device '%s'\n", params->description); + if (!settings.force) + return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; + } + + uint32_t trace_frequency = settings.trace_frequency; + if (!trace_frequency) + trace_frequency = STLINK_DEFAULT_TRACE_FREQUENCY; + if (trace_frequency > stlink->max_trace_freq) { + ELOG("Invalid trace frequency %d (max %d)\n", trace_frequency, + stlink->max_trace_freq); + if (!settings.force) + return APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY; + } + + if (!enable_trace(stlink, &settings, trace_frequency)) { + ELOG("Unable to enable trace mode\n"); + if (!settings.force) + return APP_RESULT_STLINK_STATE_ERROR; + } + + ILOG("Reading Trace\n"); + st_trace_t trace; + memset(&trace, 0, sizeof(trace)); + trace.start_time = time(NULL); + + if (stlink_run(stlink, RUN_NORMAL)) { + ELOG("Unable to run device\n"); + if (!settings.force) + return APP_RESULT_STLINK_STATE_ERROR; + } + + while (!g_abort_trace && read_trace(stlink, &trace)) { + check_for_configuration_error(stlink, &trace, trace_frequency); + } + + stlink_trace_disable(stlink); + stlink_close(stlink); + + return APP_RESULT_SUCCESS; } diff --git a/src/stlink-lib/logging.c b/src/stlink-lib/logging.c index ce0a2baab..87978230d 100644 --- a/src/stlink-lib/logging.c +++ b/src/stlink-lib/logging.c @@ -1,12 +1,13 @@ /* * UglyLogging * - * Slow, yet another wheel reinvented, but enough to make the rest of our code pretty enough. + * Slow, yet another wheel reinvented, but enough to make the rest of our code + * pretty enough. */ +#include #include #include #include -#include #include #include "logging.h" @@ -14,77 +15,89 @@ static int max_level = UDEBUG; int ugly_init(int maximum_threshold) { - max_level = maximum_threshold; - return(0); + max_level = maximum_threshold; + return (0); } int ugly_log(int level, const char *tag, const char *format, ...) { - if (level > max_level) { - return(0); - } + if (level > max_level) { + return (0); + } - fflush(stdout); // flush to maintain order of streams + fflush(stdout); // flush to maintain order of streams - va_list args; - va_start(args, format); - time_t mytt = time(NULL); - struct tm *tt; - tt = localtime(&mytt); - fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", tt->tm_year + 1900, tt->tm_mon + 1, - tt->tm_mday, tt->tm_hour, tt->tm_min, tt->tm_sec); + va_list args; + va_start(args, format); + time_t mytt = time(NULL); + struct tm *tt; + tt = localtime(&mytt); + fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", tt->tm_year + 1900, + tt->tm_mon + 1, tt->tm_mday, tt->tm_hour, tt->tm_min, tt->tm_sec); - switch (level) { - case UDEBUG: - fprintf(stderr, "DEBUG %s: ", tag); - break; - case UINFO: - fprintf(stderr, "INFO %s: ", tag); - break; - case UWARN: - fprintf(stderr, "WARN %s: ", tag); - break; - case UERROR: - fprintf(stderr, "ERROR %s: ", tag); - break; - default: - fprintf(stderr, "%d %s: ", level, tag); - break; - } + switch (level) { + case UDEBUG: + fprintf(stderr, "DEBUG %s: ", tag); + break; + case UINFO: + fprintf(stderr, "INFO %s: ", tag); + break; + case UWARN: + fprintf(stderr, "WARN %s: ", tag); + break; + case UERROR: + fprintf(stderr, "ERROR %s: ", tag); + break; + default: + fprintf(stderr, "%d %s: ", level, tag); + break; + } - vfprintf(stderr, format, args); - fflush(stderr); - va_end(args); - return(1); + vfprintf(stderr, format, args); + fflush(stderr); + va_end(args); + return (1); } /* * Log message levels. - * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default) + * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library + * (default) * - LIBUSB_LOG_LEVEL_ERROR (1) : error messages are printed to stderr - * - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to stderr - * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to stderr - * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stderr + * - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to + * stderr + * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to + * stderr + * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are + * printed to stderr */ int ugly_libusb_log_level(enum ugly_loglevel v) { #ifdef __FreeBSD__ - // FreeBSD includes its own reimplementation of libusb. - // Its libusb_set_debug() function expects a lib_debug_level - // instead of a lib_log_level and is verbose enough to drown out - // all other output. - switch (v) { - case UDEBUG: return (3); // LIBUSB_DEBUG_FUNCTION + LIBUSB_DEBUG_TRANSFER - case UINFO: return (1); // LIBUSB_DEBUG_FUNCTION only - case UWARN: return (0); // LIBUSB_DEBUG_NO - case UERROR: return (0); // LIBUSB_DEBUG_NO - } - return (0); + // FreeBSD includes its own reimplementation of libusb. + // Its libusb_set_debug() function expects a lib_debug_level + // instead of a lib_log_level and is verbose enough to drown out + // all other output. + switch (v) { + case UDEBUG: + return (3); // LIBUSB_DEBUG_FUNCTION + LIBUSB_DEBUG_TRANSFER + case UINFO: + return (1); // LIBUSB_DEBUG_FUNCTION only + case UWARN: + return (0); // LIBUSB_DEBUG_NO + case UERROR: + return (0); // LIBUSB_DEBUG_NO + } + return (0); #else - switch (v) { - case UDEBUG: return (4); - case UINFO: return (3); - case UWARN: return (2); - case UERROR: return (1); - } + switch (v) { + case UDEBUG: + return (4); + case UINFO: + return (3); + case UWARN: return (2); + case UERROR: + return (1); + } + return (2); #endif } From 553590b31b91f6edaafd75c895f0e87163037b42 Mon Sep 17 00:00:00 2001 From: "R.E. Wolff" Date: Fri, 16 Apr 2021 19:09:06 +0200 Subject: [PATCH 1170/1435] chipid in files code --- src/st-util/gdb-server.c | 1 + src/stlink-lib/chipid.c | 192 ++++++++++++++++++++++++++++++++++++++- src/stlink-lib/chipid.h | 5 +- 3 files changed, 194 insertions(+), 4 deletions(-) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 006a0e3aa..797f4391b 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -220,6 +220,7 @@ int main(int argc, char** argv) { parse_options(argc, argv, &state); printf("st-util\n"); + init_chipids (NULL); sl = stlink_open_usb(state.logging_level, state.connect_mode, state.serialnumber, state.freq); if (sl == NULL) { return(1); } diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 221234bbb..e51e00201 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1,7 +1,14 @@ #include #include "chipid.h" -static const struct stlink_chipid_params devices[] = { +#include +#include +#include +#include +#include +#include + +static struct stlink_chipid_params devices[] = { { // RM0410 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F7XXXX, @@ -711,8 +718,9 @@ static const struct stlink_chipid_params devices[] = { }, }; -const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { - const struct stlink_chipid_params *params = NULL; + +struct stlink_chipid_params *stlink_chipid_get_params_old(uint32_t chipid) { + struct stlink_chipid_params *params = NULL; for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) if (devices[n].chip_id == chipid) { @@ -722,3 +730,181 @@ const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { return(params); } + +struct stlink_chipid_params *devicelist; + + + +void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) +{ + fprintf (fp, "# Chipid file for %s\n", dev->description); + fprintf (fp, "#\n"); + fprintf (fp, "chip_id %x\n", dev->chip_id); + fprintf (fp, "description %s\n", dev->description); + fprintf (fp, "flash_type %x\n", dev->flash_type); + fprintf (fp, "flash_pagesize %x\n", dev->flash_pagesize); + fprintf (fp, "sram_size %x\n", dev->sram_size); + fprintf (fp, "bootrom_base %x\n", dev->bootrom_base); + fprintf (fp, "bootrom_size %x\n", dev->bootrom_size); + fprintf (fp, "option_base %x\n", dev->option_base); + fprintf (fp, "option_size %x\n", dev->option_size); + fprintf (fp, "flags %x\n\n", dev->flags); +} + + + +struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { + struct stlink_chipid_params *params = NULL; + struct stlink_chipid_params *p2; + + // fprintf (stderr, "getparams: %x\n", chipid); + for (params = devicelist ; params != NULL ; params = params -> next) + if (params->chip_id == chipid) break; + + p2 = stlink_chipid_get_params_old (chipid); + + if (memcmp (p2, params, sizeof (struct stlink_chipid_params) - sizeof (struct stlink_chipid_params *)) != 0) { + //fprintf (stderr, "Error, chipid params not identical\n"); + //return NULL; + fprintf (stderr, "---------- old ------------\n"); + dump_a_chip (stderr, p2); + fprintf (stderr, "---------- new ------------\n"); + dump_a_chip (stderr, params); + } + return(params); +} + + +void process_chipfile (char *fname) +{ + FILE *fp; + char *p, buf[1025]; + char word[64], value[64]; + struct stlink_chipid_params *ts; + int nc; + + fprintf (stderr, "processing chipfile %s.\n", fname); + fp = fopen (fname, "r"); + if (!fp) { + perror (fname); + return; + } + + ts = calloc (sizeof (struct stlink_chipid_params), 1); + while (fgets (buf, 1024, fp) != NULL) { + for (p=buf;isspace (*p);p++); + if (!*p) continue; // we hit end-of-line wiht only whitespace + if (*p == '#') continue; // ignore comments. + + sscanf (p, "%s %s", word, value); + if (strcmp (word, "chip_id") == 0) { + sscanf (value, "%x", &ts->chip_id); + } else if (strcmp (word, "description") == 0) { + //ts->description = strdup (value); + buf[strlen(p)-1] = 0; // chomp newline + sscanf (p, "%*s %n", &nc); + ts->description = strdup (p+nc); + } else if (strcmp (word, "flash_type") == 0) { + sscanf (value, "%x", &ts->flash_type); + } else if (strcmp (word, "flash_size_reg") == 0) { + sscanf (value, "%x", &ts->flash_size_reg); + } else if (strcmp (word, "flash_pagesize") == 0) { + sscanf (value, "%x", &ts->flash_pagesize); + } else if (strcmp (word, "sram_size") == 0) { + sscanf (value, "%x", &ts->sram_size); + } else if (strcmp (word, "bootrom_base") == 0) { + sscanf (value, "%x", &ts->bootrom_base); + } else if (strcmp (word, "bootrom_size") == 0) { + sscanf (value, "%x", &ts->bootrom_size); + } else if (strcmp (word, "option_base") == 0) { + sscanf (value, "%x", &ts->option_base); + } else if (strcmp (word, "option_size") == 0) { + sscanf (value, "%x", &ts->option_size); + } else if (strcmp (word, "flags") == 0) { + sscanf (value, "%x", &ts->flags); + } else { + fprintf (stderr, "Unknown keyword in %s: %s\n", + fname, word); + } + } + ts->next = devicelist; + devicelist = ts; +} + + +void dump_chips (void) +{ + struct stlink_chipid_params *ts; + char *p, buf[100]; + FILE *fp; + + for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) { + ts = &devices[n]; + + strcpy (buf, ts->description); + while ((p = strchr (buf, '/'))) // change slashes to underscore. + *p = '_'; + strcat (buf, ".chip"); + fp = fopen (buf, "w"); + fprintf (fp, "# Chipid file for %s\n", ts->description); + fprintf (fp, "#\n"); + fprintf (fp, "chip_id %x\n", ts->chip_id); + fprintf (fp, "description %s\n", ts->description); + fprintf (fp, "flash_type %x\n", ts->flash_type); + fprintf (fp, "flash_pagesize %x\n", ts->flash_pagesize); + fprintf (fp, "sram_size %x\n", ts->sram_size); + fprintf (fp, "bootrom_base %x\n", ts->bootrom_base); + fprintf (fp, "bootrom_size %x\n", ts->bootrom_size); + fprintf (fp, "option_base %x\n", ts->option_base); + fprintf (fp, "option_size %x\n", ts->option_size); + fprintf (fp, "flags %x\n\n", ts->flags); + fclose (fp); + } +} + + + +void init_chipids (char *dir_to_scan) +{ + DIR *d; + int nl; // namelen + struct dirent *dir; + if (!dir_to_scan) dir_to_scan = "./"; + + devicelist = NULL; + fprintf (stderr, "stlink_chipid_params %ld\n", sizeof (struct stlink_chipid_params)); + //dump_chips (); + d = opendir("."); + if (d) { + while ((dir = readdir(d)) != NULL) { + nl = strlen (dir->d_name); + if (strcmp (dir->d_name + nl - 5, ".chip") == 0) { + char buf[1024]; + sprintf (buf, "%s/%s", dir_to_scan, dir->d_name); + process_chipfile (buf); + } + } + closedir(d); + } else { + perror (dir_to_scan); + return; // XXX + } +#if 0 + { + struct stlink_chipid_params *p, *op; + int i; + p = devicelist; + for (i=0;i<5;i++, p = p->next) { + op = stlink_chipid_get_params_old (p->chip_id); + fprintf (stderr, "---------- old ------------\n"); + dump_a_chip (stderr, op); + fprintf (stderr, "---------- new ------------\n"); + dump_a_chip (stderr, p); + + } + } +#endif +} + + + diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index f790e7899..d398b5c97 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -87,9 +87,12 @@ struct stlink_chipid_params { uint32_t option_base; uint32_t option_size; uint32_t flags; + struct stlink_chipid_params * next; }; -const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); + +struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); + void init_chipids (char *dir_to_scan); #ifdef __cplusplus } From 9396e4ee1e03b427b4ec501dabce8d4eb6952089 Mon Sep 17 00:00:00 2001 From: "R.E. Wolff" Date: Fri, 16 Apr 2021 19:11:57 +0200 Subject: [PATCH 1171/1435] Added chips.zip --- src/chips.zip | Bin 0 -> 16336 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/chips.zip diff --git a/src/chips.zip b/src/chips.zip new file mode 100644 index 0000000000000000000000000000000000000000..e11e5cc6a4b9adb265d7aacbd718588f4720ae12 GIT binary patch literal 16336 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 Y@ZToF1>^+`3>fey8^~tq_z=JSAJ`js!2kdN literal 0 HcmV?d00001 From 3279f5abd623caf5dc5f0d5a77b6a60b5fcea090 Mon Sep 17 00:00:00 2001 From: "R.E. Wolff" Date: Fri, 16 Apr 2021 21:15:22 +0200 Subject: [PATCH 1172/1435] fixed a couple of warnings that macos compiler reports. --- src/stlink-lib/chipid.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index e51e00201..2d4237934 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -731,8 +731,7 @@ struct stlink_chipid_params *stlink_chipid_get_params_old(uint32_t chipid) { return(params); } -struct stlink_chipid_params *devicelist; - +static struct stlink_chipid_params *devicelist; void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) @@ -867,7 +866,7 @@ void dump_chips (void) void init_chipids (char *dir_to_scan) { DIR *d; - int nl; // namelen + size_t nl; // namelen struct dirent *dir; if (!dir_to_scan) dir_to_scan = "./"; From e4078b118f288d869907f664eb4db42870dd4c33 Mon Sep 17 00:00:00 2001 From: "R.E. Wolff" Date: Fri, 16 Apr 2021 21:25:44 +0200 Subject: [PATCH 1173/1435] removed unnecessary debug statement that didn't work on windows --- src/stlink-lib/chipid.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 2d4237934..e094f910f 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -871,7 +871,6 @@ void init_chipids (char *dir_to_scan) if (!dir_to_scan) dir_to_scan = "./"; devicelist = NULL; - fprintf (stderr, "stlink_chipid_params %ld\n", sizeof (struct stlink_chipid_params)); //dump_chips (); d = opendir("."); if (d) { From 6993491f90b15581668088a6e522b8fb9a3bb84e Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 21 Apr 2021 00:00:33 +0200 Subject: [PATCH 1174/1435] Revert "Updated libusb to v1.0.24" This reverts commit 89a495d169a15f42d8cfd1a68c6738c984d052f8. --- .gitignore | 1 - .travis.sh | 18 +++++++-------- .travis.yml | 24 ++++++++++---------- cmake/modules/Findlibusb.cmake | 6 ++--- cmake/packaging/windows/generate_binaries.sh | 24 ++++++++++---------- 5 files changed, 36 insertions(+), 37 deletions(-) diff --git a/.gitignore b/.gitignore index 82c1195e4..a07eed9ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ build build-mingw -build-mingw-* .project .cmake/ diff --git a/.travis.sh b/.travis.sh index 58cea5746..e45cd3609 100755 --- a/.travis.sh +++ b/.travis.sh @@ -8,20 +8,20 @@ echo "----" echo "WORK DIR:$DIR" DIR=$PWD -if [ "$TRAVIS_JOB_NAME" == "linux-mingw-32" ]; then +if [ "$TRAVIS_JOB_NAME" == "linux-mingw-64" ]; then + echo "--> Building for Windows (x86-64) ..." + mkdir -p build-mingw && cd build-mingw-64 + cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR + make && rm -rf build-mingw-64 && cd - + +elif [ "$TRAVIS_JOB_NAME" == "linux-mingw-32" ]; then echo "--> Building for Windows (i686) ..." - mkdir -p build-mingw-32 && cd build-mingw-32 + mkdir -p build-mingw && cd build-mingw-32 cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && rm -rf build-mingw-32 && cd - -# elif [ "$TRAVIS_JOB_NAME" == "linux-mingw-64" ]; then -# echo "--> Building for Windows (x86-64) ..." -# mkdir -p build-mingw-64 && cd build-mingw-64 -# cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ -# -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR -# make && rm -rf build-mingw-64 && cd - - elif [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq || true diff --git a/.travis.yml b/.travis.yml index 307c0bfa0..a733019a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,8 @@ jobs: - os: linux dist: focal - env: BADGE=linux-mingw-32 - name: linux-mingw-32 + env: BADGE=linux-mingw-64 + name: linux-mingw compiler: gcc-10 addons: apt: @@ -15,16 +15,16 @@ jobs: packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] - # - os: linux - # dist: focal - # env: BADGE=linux-mingw-64 - # name: linux-mingw-64 - # compiler: gcc-10 - # addons: - # apt: - # sources: ["ubuntu-toolchain-r-test"] - # packages: - # ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] + - os: linux + dist: focal + env: BADGE=linux-mingw-32 + name: linux-mingw + compiler: gcc-10 + addons: + apt: + sources: ["ubuntu-toolchain-r-test"] + packages: + ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] script: - git fetch --tags diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index 99f4d56ec..257c682ce 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -77,7 +77,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to if (NOT LIBUSB_FOUND) # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.24) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) @@ -94,7 +94,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download - ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 5c944b1c8aa9d43e026a94302d0f8ac4 + ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 ) endif () @@ -128,7 +128,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to set(LIBUSB_NAME libusb-1.0.lib) find_library( LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/**/MS${ARCH}/dll + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS${ARCH}/dll NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) diff --git a/cmake/packaging/windows/generate_binaries.sh b/cmake/packaging/windows/generate_binaries.sh index 5616ecb38..bf2453d10 100644 --- a/cmake/packaging/windows/generate_binaries.sh +++ b/cmake/packaging/windows/generate_binaries.sh @@ -5,6 +5,18 @@ # Install this cross-compiler toolchain: #sudo apt-get install mingw-w64 +# x86_64 +mkdir build-mingw-64 +cd build-mingw-64 +cmake -DCMAKE_SYSTEM_NAME=Windows \ + -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. +make package +cp dist/*.zip ../build/Release/dist +make clean +cd .. +rm -rf build-mingw-64 + # i686 mkdir build-mingw-32 cd build-mingw-32 @@ -16,15 +28,3 @@ cp dist/*.zip ../build/Release/dist make clean cd .. rm -rf build-mingw-32 - -# x86_64 -# mkdir build-mingw-64 -# cd build-mingw-64 -# cmake -DCMAKE_SYSTEM_NAME=Windows \ -# -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ -# -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. -# make package -# cp dist/*.zip ../build/Release/dist -# make clean -# cd .. -# rm -rf build-mingw-64 From c115ab2e0fcc3103e2ceb848c18b12641cfe7d0e Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 24 Apr 2021 14:16:29 +0200 Subject: [PATCH 1175/1435] General Project Update - Formatting fixes - Commented CI build setting for Ubuntu 16.04 - Updated CHANGELOG.md --- .github/workflows/c-cpp.yml | 210 +++++++++++---------- CHANGELOG.md | 4 +- inc/stm32.h | 31 ++-- src/stlink-lib/chipid.c | 353 ++++++++++++++++++++---------------- 4 files changed, 323 insertions(+), 275 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 97f48d88d..ef9e5f172 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -7,98 +7,97 @@ on: branches: [master, develop, testing] jobs: + # Linux -# Linux - - job_linux_16_04_64_gcc: - name: ubuntu-16.04 gcc - runs-on: ubuntu-16.04 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean + # job_linux_16_04_64_gcc: + # name: ubuntu-16.04 gcc + # runs-on: ubuntu-16.04 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean - job_linux_16_04_32_gcc: - name: ubuntu-16.04 gcc 32-bit - runs-on: ubuntu-16.04 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm - - name: Set compiler flags - run: | - CFLAGS="$CFLAGS -m32" - CXXFLAGS="$CXXFLAGS -m32" - LDFLAGS="$LDFLAGS -m32" - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean + # job_linux_16_04_32_gcc: + # name: ubuntu-16.04 gcc 32-bit + # runs-on: ubuntu-16.04 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + # - name: Set compiler flags + # run: | + # CFLAGS="$CFLAGS -m32" + # CXXFLAGS="$CXXFLAGS -m32" + # LDFLAGS="$LDFLAGS -m32" + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean - job_linux_16_04_64_clang: - name: ubuntu-16.04 clang - runs-on: ubuntu-16.04 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean + # job_linux_16_04_64_clang: + # name: ubuntu-16.04 clang + # runs-on: ubuntu-16.04 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean - job_linux_16_04_32_clang: - name: ubuntu-16.04 clang 32-bit - runs-on: ubuntu-16.04 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm - - name: Set compiler flags - run: | - CFLAGS="$CFLAGS -m32" - CXXFLAGS="$CXXFLAGS -m32" - LDFLAGS="$LDFLAGS -m32" - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean + # job_linux_16_04_32_clang: + # name: ubuntu-16.04 clang 32-bit + # runs-on: ubuntu-16.04 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm + # - name: Set compiler flags + # run: | + # CFLAGS="$CFLAGS -m32" + # CXXFLAGS="$CXXFLAGS -m32" + # LDFLAGS="$LDFLAGS -m32" + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean job_linux_18_04_64_gcc: name: ubuntu-18.04 gcc @@ -144,7 +143,7 @@ jobs: run: sudo make package - name: sudo make uninstall run: sudo make uninstall && sudo make clean - + job_linux_18_04_64_clang: name: ubuntu-18.04 clang runs-on: ubuntu-18.04 @@ -280,7 +279,7 @@ jobs: - name: sudo make uninstall run: sudo make uninstall && sudo make clean -# macOS + # macOS # job_macos_10_14_64_gcc: # name: macos-10.14 gcc @@ -411,7 +410,6 @@ jobs: run: sudo make package - name: sudo make uninstall run: sudo make uninstall && sudo make clean - # job_macos_11_gcc: # name: macos-11.0 gcc # runs-on: macos-11.0 @@ -431,7 +429,6 @@ jobs: # run: sudo make package # - name: sudo make uninstall # run: sudo make uninstall && sudo make clean - # job_macos_11_clang: # name: macos-11.0 clang # runs-on: macos-11.0 @@ -451,20 +448,19 @@ jobs: # run: sudo make package # - name: sudo make uninstall # run: sudo make uninstall && sudo make clean - # Linux MinGW cross compliation - # job_linux_20_04_cross: - # name: ubuntu-20.04 mingw64 - # runs-on: ubuntu-20.04 - # steps: - # - uses: actions/checkout@v2 - # - name: Install dependencies - # run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm mingw-w64 - # - name: Building Release for Windows (x86-64) ... - # run: sudo mkdir -p build-mingw && cd build-mingw && sudo cmake \ - # -DCMAKE_SYSTEM_NAME=Windows \ - # -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ - # -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake \ - # -DCMAKE_INSTALL_PREFIX=$PWD/install $PWD && \ - # sudo make && sudo rm -rf build-mingw && cd - +# job_linux_20_04_cross: +# name: ubuntu-20.04 mingw64 +# runs-on: ubuntu-20.04 +# steps: +# - uses: actions/checkout@v2 +# - name: Install dependencies +# run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm mingw-w64 +# - name: Building Release for Windows (x86-64) ... +# run: sudo mkdir -p build-mingw && cd build-mingw && sudo cmake \ +# -DCMAKE_SYSTEM_NAME=Windows \ +# -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ +# -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake \ +# -DCMAKE_INSTALL_PREFIX=$PWD/install $PWD && \ +# sudo make && sudo rm -rf build-mingw && cd - diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ac52da73..a3e7dbafc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,7 @@ Updates & changes: Fixes: - Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#807](https://github.com/stlink-org/stlink/pull/807), [#817](https://github.com/stlink-org/stlink/pull/817), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) -- Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106)) +- Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106), [#1121](https://github.com/stlink-org/stlink/pull/1121)) - Use vl flashloader for all STM32F1 series ([#769](https://github.com/stlink-org/stlink/pull/769), [#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) - cmake compile failure with external `CMAKE_MODULE_PATH` set ([#962](https://github.com/stlink-org/stlink/pull/962)) @@ -165,7 +165,7 @@ Fixes: - Set static link for `libssp` (stack-smashing protection) ([#960](https://github.com/stlink-org/stlink/pull/960), [#961](https://github.com/stlink-org/stlink/pull/961)) - Fixed udev rules installing to wrong directory ([#966](https://github.com/stlink-org/stlink/pull/966)) - Fixed formatting for options display in `st-flash` & `st-info` (commits [#c783d0e](https://github.com/stlink-org/stlink/commit/c783d0e777ccc83a7a8be26a4f4d3414e0478560) and [#562cd24](https://github.com/stlink-org/stlink/commit/562cd2496e696dbd22950925866aac662d81ee5f)) -- Fixed reading of chip ID on Cortex-M0+ core ([#1125](https://github.com/stlink-org/stlink/pull/1125), [#1126](https://github.com/stlink-org/stlink/pull/1126)) +- Fixed reading of chip ID on Cortex-M0+ core ([#1125](https://github.com/stlink-org/stlink/pull/1125), [#1126](https://github.com/stlink-org/stlink/pull/1126), [#1133](https://github.com/stlink-org/stlink/pull/1133)) # v1.6.0 diff --git a/inc/stm32.h b/inc/stm32.h index 7d60ab5de..21da2f563 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -8,24 +8,31 @@ #define STM32_H /* Cortex core ids */ -#define STM32VL_CORE_ID 0x1ba01477 -#define STM32F7_CORE_ID 0x5ba02477 -#define STM32H7_CORE_ID 0x6ba02477 // STM32H7 SWD ID Code +#define STM32VL_CORE_ID 0x1ba01477 +#define STM32F7_CORE_ID 0x5ba02477 +#define STM32H7_CORE_ID 0x6ba02477 // STM32H7 SWD ID Code #define STM32H7_CORE_ID_JTAG 0x6ba00477 // STM32H7 JTAG ID Code (RM0433 pg3065) /* Constant STM32 memory map figures */ -#define STM32_FLASH_BASE ((uint32_t)0x08000000) -#define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) -#define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) -#define STM32_SRAM_BASE ((uint32_t)0x20000000) -#define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) -#define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) -#define STM32_L0_CATx_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) +#define STM32_SRAM_BASE ((uint32_t)0x20000000) +#define STM32_FLASH_BASE ((uint32_t)0x08000000) +#define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) +#define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) + #define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) -#define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) -#define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) #define STM32_F4_OPTION_BYTES_BASE ((uint32_t)0x40023C14) #define STM32_F7_OPTION_BYTES_BASE ((uint32_t)0x1FFF0000) #define STM32_H7_OPTION_BYTES_BASE ((uint32_t)0x5200201C) +#define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) +#define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) + +#define STM32_L0_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) +#define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) + +#define STM32_F0_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) +#define STM32_F1_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) +#define STM32_F3_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) +#define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) + #endif // STM32_H diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 221234bbb..187a6d957 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -7,12 +7,15 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F7XXXX, .description = "F76xxx", .flash_type = STLINK_FLASH_TYPE_F7, - .flash_size_reg = 0x1ff0f442, // section 45.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x80000, // "SRAM" byte size in hex from - .bootrom_base = 0x00200000, // ! "System memory" starting address from - .bootrom_size = 0xEDC0, // ! @todo "System memory" byte size in hex from - .option_base = STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option bytes, writing uses FLASH_F7_OPTCR and FLASH_F7_OPTCR1 + .flash_size_reg = 0x1ff0f442, // section 45.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x80000, // "SRAM" byte size in hex from + .bootrom_base = 0x00200000, // ! "System memory" starting address from + .bootrom_size = 0xEDC0, // ! @todo "System memory" byte size in hex from + .option_base = + STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option + // bytes, writing uses FLASH_F7_OPTCR + // and FLASH_F7_OPTCR1 .option_size = 0x20, .flags = CHIP_F_HAS_SWO_TRACING, }, @@ -21,11 +24,13 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F7, .description = "F7xx", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff0f442, // section 41.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 - .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 18 + .flash_size_reg = 0x1ff0f442, // section 41.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 + .bootrom_base = + 0x00100000, // "System memory" starting address from DS Fig 18 + .bootrom_size = + 0xEDC0, // "System memory" byte size in hex from DS Fig 18 .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -33,14 +38,17 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F72XXX, .description = "F72x/F73x", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff07a22, // section 35.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 - .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 24 + .flash_size_reg = 0x1ff07a22, // section 35.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 + .bootrom_base = + 0x00100000, // "System memory" starting address from DS Fig 24 + .bootrom_size = + 0xEDC0, // "System memory" byte size in hex from DS Fig 24 .flags = CHIP_F_HAS_SWO_TRACING, }, - { // table 2, PM0063 + { + // table 2, PM0063 .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, .description = "F1xx Medium-density", .flash_type = STLINK_FLASH_TYPE_F0, @@ -51,11 +59,12 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x800, .flags = CHIP_F_HAS_SWO_TRACING, }, - { // table 1, PM0059 + { + // table 1, PM0059 .chip_id = STLINK_CHIPID_STM32_F2, .description = "F2xx", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, // as in RM0033 Rev 5 + .flash_size_reg = 0x1fff7a22, // as in RM0033 Rev 5 .flash_pagesize = 0x20000, .sram_size = 0x20000, .bootrom_base = 0x1fff0000, @@ -64,7 +73,8 @@ static const struct stlink_chipid_params devices[] = { .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, }, - { // PM0063 + { + // PM0063 .chip_id = STLINK_CHIPID_STM32_F1_LOW, .description = "F1 Low-density device", .flash_type = STLINK_FLASH_TYPE_F0, @@ -79,7 +89,7 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F4, .description = "F4xx", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 .flash_pagesize = 0x4000, .sram_size = 0x30000, .bootrom_base = 0x1fff0000, @@ -92,7 +102,7 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F4_DSI, .description = "F46x/F47x", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 .flash_pagesize = 0x4000, .sram_size = 0x40000, .bootrom_base = 0x1fff0000, @@ -103,7 +113,7 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F4_HD, .description = "F42x/F43x", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 .flash_pagesize = 0x4000, .sram_size = 0x40000, .bootrom_base = 0x1fff0000, @@ -224,7 +234,8 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x4800, .flags = CHIP_F_HAS_SWO_TRACING, }, - { // Low and Medium density VL have same chipid. RM0041 25.6.1 + { + // Low and Medium density VL have same chipid. RM0041 25.6.1 .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, .description = "F1xx Value Line", .flash_type = STLINK_FLASH_TYPE_F0, @@ -315,11 +326,12 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F0_CAN, .description = "F07x", .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 - .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 - .bootrom_size = 0x3000, // "System memory" byte size in hex from Table 2 + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 + .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = + 0x1fffC800, // "System memory" starting address from Table 2 + .bootrom_size = 0x3000, // "System memory" byte size in hex from Table 2 }, { // Use this as an example for mapping future chips: @@ -327,11 +339,12 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F0, .description = "F0xx", .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = + 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 }, { // RM0402 document was used to find these parameters @@ -339,11 +352,12 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F412, .description = "F412", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) - .flash_pagesize = 0x4000, // Table 5. Flash module organization ? - .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 - .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 + .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) + .flash_pagesize = 0x4000, // Table 5. Flash module organization ? + .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 + .bootrom_base = + 0x1FFF0000, // "System memory" starting address from Table 4 + .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -352,22 +366,27 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F413, .description = "F413", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 - .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector sizes, but 0x4000 is smallest) - .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 only says 0x40000) - .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 + .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 + .flash_pagesize = + 0x4000, // Table 5. Flash module organization (variable sector + // sizes, but 0x4000 is smallest) + .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 + // only says 0x40000) + .bootrom_base = + 0x1FFF0000, // "System memory" starting address from Table 4 + .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F09X, .description = "F09X", .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) - .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) - .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 - .bootrom_size = 0x2000, // "System memory" byte size in hex from Table 2 + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) + .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) + .bootrom_base = + 0x1fffd800, // "System memory" starting address from Table 2 + .bootrom_size = 0x2000, // "System memory" byte size in hex from Table 2 }, { // Use this as an example for mapping future chips: @@ -375,11 +394,12 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F04, .description = "F04x", .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 + .bootrom_base = + 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 }, { // Use this as an example for mapping future chips: @@ -387,11 +407,12 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F0_SMALL, .description = "F0xx small", .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = + 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 }, { // STM32F30x @@ -416,7 +437,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x2000, .bootrom_base = 0x1ff0000, .bootrom_size = 0x1000, - .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, + .option_base = STM32_L0_OPTION_BYTES_BASE, .option_size = 20, }, { @@ -430,7 +451,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x5000, .bootrom_base = 0x1ff0000, .bootrom_size = 0x2000, - .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, + .option_base = STM32_L0_OPTION_BYTES_BASE, .option_size = 20, }, { @@ -444,7 +465,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x2000, .bootrom_base = 0x1ff0000, .bootrom_size = 0x1000, - .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, + .option_base = STM32_L0_OPTION_BYTES_BASE, .option_size = 20, }, { @@ -466,10 +487,10 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F303_HIGH, .description = "F303 high density", .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register - .flash_pagesize = 0x800, // 4.2.1 Flash memory organization - .sram_size = 0x10000, // 3.3 Embedded SRAM - .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory + .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register + .flash_pagesize = 0x800, // 4.2.1 Flash memory organization + .sram_size = 0x10000, // 3.3 Embedded SRAM + .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory .bootrom_size = 0x2000, .flags = CHIP_F_HAS_SWO_TRACING, }, @@ -479,15 +500,18 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L4, .description = "L4xx", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 - // and tables 4-6 on pages 79-81) - // SRAM1 is "up to" 96k in the standard Cortex-M memory map; - // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) + .flash_size_reg = + 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) + .flash_pagesize = + 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 + // and tables 4-6 on pages 79-81) + // SRAM1 is "up to" 96k in the standard Cortex-M memory map; + // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base + .bootrom_base = + 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, @@ -498,11 +522,13 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L4RX, .description = "L4Rx", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 52.2, page 2049) - .flash_pagesize = 0x1000, // 4k, section 3.3, pg 97 - .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 - .bootrom_base = 0x1fff0000, // 3.3.1, pg 99 - .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 99) + .flash_size_reg = + 0x1fff75e0, // "Flash size data register" (sec 52.2, page 2049) + .flash_pagesize = 0x1000, // 4k, section 3.3, pg 97 + .sram_size = + 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 + .bootrom_base = 0x1fff0000, // 3.3.1, pg 99 + .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 99) .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -511,13 +537,16 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L41X, .description = "L41x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, sec 47.2, page 1586) - .flash_pagesize = 0x800, // 2k (DS12469, sec 3.4, page 17) - // SRAM1 is 32k at 0x20000000 - // SRAM2 is 8k at 0x10000000 and 0x20008000 (DS12469, sec 3.5, page 18) - .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) - .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) - .bootrom_size = 0x7000, // 28k, same source as base + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, + // sec 47.2, page 1586) + .flash_pagesize = 0x800, // 2k (DS12469, sec 3.4, page 17) + // SRAM1 is 32k at 0x20000000 + // SRAM2 is 8k at 0x10000000 and 0x20008000 + // (DS12469, sec 3.5, page 18) + .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) + .bootrom_base = + 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) + .bootrom_size = 0x7000, // 28k, same source as base .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -526,15 +555,18 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L43X, .description = "L43x/L44x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 - // and tables 7-8 on pages 75-76) - // SRAM1 is "up to" 64k in the standard Cortex-M memory map; - // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) + .flash_size_reg = + 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) + .flash_pagesize = + 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 + // and tables 7-8 on pages 75-76) + // SRAM1 is "up to" 64k in the standard Cortex-M memory map; + // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) .sram_size = 0xc000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base + .bootrom_base = + 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, @@ -545,13 +577,15 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L496X, .description = "L496x/L4A6x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) - .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) - // SRAM1 is 256k at 0x20000000 - // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) - .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) - .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) - .bootrom_size = 0x7000, // 28k (per bank), same source as base + .flash_size_reg = + 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) + .flash_pagesize = + 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) + // SRAM1 is 256k at 0x20000000 + // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) + .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) + .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) + .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, @@ -562,14 +596,18 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L46X, .description = "L45x/46x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 - // and tables 7 on pages 73-74) - // SRAM1 is 128k at 0x20000000; - // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, page 68, also fig 2 on page 63) + .flash_size_reg = + 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) + .flash_pagesize = + 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 + // and tables 7 on pages 73-74) + // SRAM1 is 128k at 0x20000000; + // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, + // page 68, also fig 2 on page 63) .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system memory, also fig 2 on page 63) - .bootrom_size = 0x7000, // 28k (per bank), same source as base + .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system + // memory, also fig 2 on page 63) + .bootrom_size = 0x7000, // 28k (per bank), same source as base .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -588,11 +626,11 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_G0_CAT1, .description = "G030/G031/G041", .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x2000, // 8k (sec 2.3) + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (sec 3.2) + .sram_size = 0x2000, // 8k (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 3) + .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 3) .option_base = STM32_G0_OPTION_BYTES_BASE, .option_size = 4, }, @@ -601,11 +639,11 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_G0_CAT2, .description = "G070/G071/G081", .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x9000, // 36k (sec 2.3) + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (sec 3.2) + .sram_size = 0x9000, // 36k (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) + .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) .option_base = STM32_G0_OPTION_BYTES_BASE, .option_size = 4, }, @@ -614,14 +652,15 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_G4_CAT2, .description = "G4 Category-2", .flash_type = STLINK_FLASH_TYPE_G4, - .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = 0x800, // 2k (sec 3.3.1) - // SRAM1 is 16k at 0x20000000 - // SRAM2 is 6k at 0x20014000 - // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x8000, // 32k (sec 2.4) + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = + 0x800, // 2k (sec 3.3.1) + // SRAM1 is 16k at 0x20000000 + // SRAM2 is 6k at 0x20014000 + // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 + .sram_size = 0x8000, // 32k (sec 2.4) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (table 2) + .bootrom_size = 0x7000, // 28k (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, @@ -631,14 +670,15 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_G4_CAT3, .description = "G4 Category-3", .flash_type = STLINK_FLASH_TYPE_G4, - .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = 0x800, // 2k (sec 3.3.1) - // SRAM1 is 80k at 0x20000000 - // SRAM2 is 16k at 0x20014000 - // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x18000, // 128k (sec 2.4) + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = + 0x800, // 2k (sec 3.3.1) + // SRAM1 is 80k at 0x20000000 + // SRAM2 is 16k at 0x20014000 + // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 + .sram_size = 0x18000, // 128k (sec 2.4) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (table 2) + .bootrom_size = 0x7000, // 28k (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, .option_size = 4, .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, @@ -649,7 +689,7 @@ static const struct stlink_chipid_params devices[] = { .description = "WB55", .flash_type = STLINK_FLASH_TYPE_WB, .flash_size_reg = 0x1FFF75E0, - .flash_pagesize = 0x1000, // 4k + .flash_pagesize = 0x1000, // 4k .sram_size = 0x40000, .bootrom_base = 0x1fff0000, // see the memory map .bootrom_size = 0x7000, @@ -660,13 +700,15 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_H74XXX, .description = "H74x/H75x", .flash_type = STLINK_FLASH_TYPE_H7, - .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) - .flash_pagesize = 0x20000, // 128k sector (pg147) - .sram_size = 0x20000, // 128k "DTCM" from Table 7 - .bootrom_base = 0x1ff00000, // "System memory" starting address from Table 7 - .bootrom_size = 0x20000, // "System memory" byte size in hex from Table 7 + .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) + .flash_pagesize = 0x20000, // 128k sector (pg147) + .sram_size = 0x20000, // 128k "DTCM" from Table 7 + .bootrom_base = + 0x1ff00000, // "System memory" starting address from Table 7 + .bootrom_size = + 0x20000, // "System memory" byte size in hex from Table 7 .option_base = STM32_H7_OPTION_BYTES_BASE, - .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 + .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { @@ -674,11 +716,13 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_H7AX, .description = "H7Ax/H7Bx", .flash_type = STLINK_FLASH_TYPE_H7, - .flash_size_reg = 0x08FFF80C, // "Flash size register" (p.2949) - .flash_pagesize = 0x2000, // 8k sector (p.146) - .sram_size = 0x20000, // 128k "DTCM" (Figure 1) - .bootrom_base = 0x1FF00000, // "System memory" starting address (Table 12-14) - .bootrom_size = 0x20000, // "System memory" byte size in hex splitted to two banks (Table 12-14) + .flash_size_reg = 0x08FFF80C, // "Flash size register" (p.2949) + .flash_pagesize = 0x2000, // 8k sector (p.146) + .sram_size = 0x20000, // 128k "DTCM" (Figure 1) + .bootrom_base = + 0x1FF00000, // "System memory" starting address (Table 12-14) + .bootrom_size = 0x20000, // "System memory" byte size in hex splitted to + // two banks (Table 12-14) .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, @@ -688,11 +732,12 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_H72X, .description = "H72x/H73x", .flash_type = STLINK_FLASH_TYPE_H7, - .flash_size_reg = 0x1FF1E880, // "Flash size register" (p.3286) - .flash_pagesize = 0x20000, // 128k sector (p.152) - .sram_size = 0x20000, // 128k "DTCM" (Figure 1) - .bootrom_base = 0x1FF00000, // "System memory" starting address (Table 6) - .bootrom_size = 0x20000, // "System memory" byte size in hex (Table 6) + .flash_size_reg = 0x1FF1E880, // "Flash size register" (p.3286) + .flash_pagesize = 0x20000, // 128k sector (p.152) + .sram_size = 0x20000, // 128k "DTCM" (Figure 1) + .bootrom_base = + 0x1FF00000, // "System memory" starting address (Table 6) + .bootrom_size = 0x20000, // "System memory" byte size in hex (Table 6) .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, .flags = CHIP_F_HAS_SWO_TRACING, @@ -712,13 +757,13 @@ static const struct stlink_chipid_params devices[] = { }; const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { - const struct stlink_chipid_params *params = NULL; + const struct stlink_chipid_params *params = NULL; - for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) - if (devices[n].chip_id == chipid) { - params = &devices[n]; - break; - } + for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) + if (devices[n].chip_id == chipid) { + params = &devices[n]; + break; + } - return(params); + return (params); } From b97296be8f22421b5beb21a4462bf8e515f74ab8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 24 Apr 2021 22:47:02 +0200 Subject: [PATCH 1176/1435] Release v1.7.0 --- .gitignore | 3 ++- .version | 2 +- CHANGELOG.md | 12 ++++++------ README.md | 4 ++-- cmake/packaging/windows/generate_binaries.sh | 4 ++-- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index a07eed9ca..1a5fd5ab1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ build -build-mingw +build-mingw-32 +build-mingw-64 .project .cmake/ diff --git a/.version b/.version index 9c6d6293b..bd8bf882d 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.6.1 +1.7.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index a3e7dbafc..9f63eca81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,14 @@ # v1.7.0 -Release date: 2020-04-xx +Release date: 2021-04-25 This release drops support for the STLINK/V1 programmer on macOS 10.13. Features: - Extended set of cmd line arguments for st-info and st-util ([#332](https://github.com/stlink-org/stlink/pull/332), [#990](https://github.com/stlink-org/stlink/pull/990), [#1091](https://github.com/stlink-org/stlink/pull/1091), [#1114](https://github.com/stlink-org/stlink/pull/1114)) -- Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#801](https://github.com/stlink-org/stlink/pull/801), [#868](https://github.com/stlink-org/stlink/pull/868), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) +- Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#801](https://github.com/stlink-org/stlink/pull/801), [#868](https://github.com/stlink-org/stlink/pull/868), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) - Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052)) - Official support for STLINK-V3 programmers (commit [#5e0a502](https://github.com/stlink-org/stlink/commit/5e0a502df812495bfa96fa9116a19f1306152b17), [#820](https://github.com/stlink-org/stlink/pull/820), [#1022](https://github.com/stlink-org/stlink/pull/1022), [#1025](https://github.com/stlink-org/stlink/pull/1025)) - Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) @@ -40,7 +40,8 @@ Updates & changes: Fixes: -- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#807](https://github.com/stlink-org/stlink/pull/807), [#817](https://github.com/stlink-org/stlink/pull/817), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) +- Improvements and fixes of the flash loaders, unification of the reset function ([#244](https://github.com/stlink-org/stlink/pull/244), [#382](https://github.com/stlink-org/stlink/pull/382), [#705](https://github.com/stlink-org/stlink/pull/705), [#980](https://github.com/stlink-org/stlink/pull/980), [#995](https://github.com/stlink-org/stlink/pull/995), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1115](https://github.com/stlink-org/stlink/pull/1115), [#1117](https://github.com/stlink-org/stlink/pull/1117), [#1122](https://github.com/stlink-org/stlink/pull/1122), [#1124](https://github.com/stlink-org/stlink/pull/1124)) +- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#807](https://github.com/stlink-org/stlink/pull/807), [#817](https://github.com/stlink-org/stlink/pull/817), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) - Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106), [#1121](https://github.com/stlink-org/stlink/pull/1121)) - Use vl flashloader for all STM32F1 series ([#769](https://github.com/stlink-org/stlink/pull/769), [#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) @@ -53,7 +54,7 @@ Fixes: - Fixed `connect under reset` for `st-flash` and `st-util` ([#983](https://github.com/stlink-org/stlink/pull/983)) - Fix for `mmap() size_t overflow` in `st-flash` ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) - [regression] `stlink-gui` installation issue on Ubuntu-18.04 ([#1001](https://github.com/stlink-org/stlink/pull/1001), [#1004](https://github.com/stlink-org/stlink/pull/1004), [#1006](https://github.com/stlink-org/stlink/pull/1006)) -- `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027), [#1038](https://github.com/stlink-org/stlink/pull/1038),[#1064](https://github.com/stlink-org/stlink/pull/1064), [#1065](https://github.com/stlink-org/stlink/pull/1065)) +- `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027), [#1038](https://github.com/stlink-org/stlink/pull/1038), [#1064](https://github.com/stlink-org/stlink/pull/1064), [#1065](https://github.com/stlink-org/stlink/pull/1065)) - GDB: Fixed problems with target description ([#1013](https://github.com/stlink-org/stlink/pull/1013), [#1088](https://github.com/stlink-org/stlink/pull/1088), [#1109](https://github.com/stlink-org/stlink/pull/1109)) - [doc] Fixed wrong path for `rules.d` folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) - Fixed support for STLINK/V1 programmer ([#1045](https://github.com/stlink-org/stlink/pull/1045), [#1105](https://github.com/stlink-org/stlink/pull/1105)) @@ -66,7 +67,7 @@ Fixes: - [doc] Corrected spelling mistake in bug report template ([#1103](https://github.com/stlink-org/stlink/pull/1103)) - Fixed STM32WB55 reading DEBUG IDCODE from the wrong address ([#1100](https://github.com/stlink-org/stlink/pull/1100), [#1101](https://github.com/stlink-org/stlink/pull/1101)) - Applied missing changes to tests ([#1119](https://github.com/stlink-org/stlink/pull/1119)) -- Improvements for Chip_ID read ([#1120](https://github.com/stlink-org/stlink/pull/1120)) +- Improvements for Chip_ID read ([#1008](https://github.com/stlink-org/stlink/pull/1008), [#1120](https://github.com/stlink-org/stlink/pull/1120)) # v1.6.1 @@ -143,7 +144,6 @@ Updates & changes: Fixes: -- Improvements and fixes of the flash loaders, unification of the reset function ([#244](https://github.com/stlink-org/stlink/pull/244), [#382](https://github.com/stlink-org/stlink/pull/382), [#705](https://github.com/stlink-org/stlink/pull/705), [#980](https://github.com/stlink-org/stlink/pull/980), [#995](https://github.com/stlink-org/stlink/pull/995), [#1115](https://github.com/stlink-org/stlink/pull/1115), [#1117](https://github.com/stlink-org/stlink/pull/1117), [#1122](https://github.com/stlink-org/stlink/pull/1122), [#1124](https://github.com/stlink-org/stlink/pull/1124)) - Fixed wait-loop for `flash_loader_run()` ([#290](https://github.com/stlink-org/stlink/pull/290)) - Better argument parsing for CLI tools: `stlink_open_usb` can address v1, v2, v3 ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) - Clear the PG bit before setting the `PER` bit ([#579](https://github.com/stlink-org/stlink/pull/579), [#876](https://github.com/stlink-org/stlink/pull/876)) diff --git a/README.md b/README.md index 93994db49..600879580 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/stlink-org/stlink.svg)](https://github.com/stlink-org/stlink/releases/latest) [![Downloads](https://img.shields.io/github/downloads/stlink-org/stlink/total)](https://github.com/stlink-org/stlink/releases/latest) -![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.1/develop) +![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.7.0/develop) ![GitHub activity](https://img.shields.io/github/commit-activity/m/stlink-org/stlink) ![GitHub contributors](https://img.shields.io/github/contributors/stlink-org/stlink) [![CodeQL](https://github.com/stlink-org/stlink/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/stlink-org/stlink/actions/workflows/codeql-analysis.yml) @@ -66,7 +66,7 @@ Our [tutorial](doc/tutorial.md) may help you along with some advanced tasks and **Windows**: As of Release v1.6.1 stand-alone Windows binaries are made available (again) on the release page of the project. -Please ensure to select the correct version for your system (i686 or x86_64). The archive file can be unzipped to any desired location as it does not contain any hardcoded paths. However we suggest to move the unzipped application folder to `C:\Program Files\` on 32-bit systems and to `C:\Program Files (x86)\` on 64-bit systems (the toolset is a 32-bit). +Please ensure to select the correct version for your system (i686 or x86_64). The archive file can be unzipped to any desired location as it does not contain any hardcoded paths. However we suggest to move the unzipped application folder to `C:\Program Files\` on 32-bit systems and to `C:\Program Files (x86)\` on 64-bit systems (the toolset is 32-bit). Alternatively one may compile and install from source as described in our [compiling manual](doc/compiling.md#Windows). diff --git a/cmake/packaging/windows/generate_binaries.sh b/cmake/packaging/windows/generate_binaries.sh index bf2453d10..f3642c316 100644 --- a/cmake/packaging/windows/generate_binaries.sh +++ b/cmake/packaging/windows/generate_binaries.sh @@ -12,7 +12,7 @@ cmake -DCMAKE_SYSTEM_NAME=Windows \ -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. make package -cp dist/*.zip ../build/Release/dist +sudo cp dist/*.zip ../build/Release/dist make clean cd .. rm -rf build-mingw-64 @@ -24,7 +24,7 @@ cmake -DCMAKE_SYSTEM_NAME=Windows \ -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. make package -cp dist/*.zip ../build/Release/dist +sudo cp dist/*.zip ../build/Release/dist make clean cd .. rm -rf build-mingw-32 From 80c31a15a4ae447e0e300b5564a7c61f839f8b7f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 25 Apr 2021 01:43:12 +0200 Subject: [PATCH 1177/1435] General Project Update - Updated issue templates - Updated CONTRIBUTING.md (Closes #906) - Updated changelogs for deb and rpm packages - Updated CHANGELOG.md --- .github/ISSUE_TEMPLATE/bug-report.md | 17 +++++++++-------- .github/ISSUE_TEMPLATE/feature-request.md | 17 +++++++++-------- CHANGELOG.md | 12 ++++++++++++ CONTRIBUTING.md | 11 +++++++++++ cmake/packaging/deb/changelog | 6 ++++++ cmake/packaging/rpm/changelog | 3 +++ doc/release.md | 2 +- 7 files changed, 51 insertions(+), 17 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 16e0477f0..c733c2c2e 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -5,14 +5,19 @@ title: "[STM32 device name]: $YourTitle" labels: "" --- -Thank you for giving feedback to the stlink project. +**Thank you for giving feedback to the stlink project.** -**NOTICE: Please read and follow instructions in #906 before submitting a ticket. -This bug report will be deleted without notice when not enough information is provided! So please ensure that all fields are filled out.** +--- + +**NOTE: In order to offer sufficient and the best possible support, please read /CONTRIBUTING.md and follow the given instructions _before_ submitting a ticket.** + +**Bug reports and/or feature requests will be deleted, if they violate our contribution guidelines and if no issue-template is used!** Thank you for your support. + +--- - [ ] I made serious effort to avoid creating duplicate or nearly similar issue -In order to allow developers and other contributors to isolate and target your respective issue, please take some time to select the check boxes below and fill out each of the following items appropriate to your specific problem. +In order to allow developers to isolate and target your respective issue, please take some time to select the check boxes below and fill out each of the following items appropriate to your specific problem. - [ ] Programmer/board type: [enter here] (e.g STLINK /V1, /V2, /V2-onboard, /V2-clone, /V3) - [ ] Operating system an version: [enter here] (e.g Linux, macOS, Windows) @@ -31,7 +36,3 @@ OUTPUT/ERROR of the commandline tool(s) Expected/description: `short description of the expected value` - -Thank you for your support. - -The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index ddeb79357..d57dbefed 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -5,14 +5,19 @@ title: "[feature] $YourTitle" labels: code/feature-request --- -Thank you for giving feedback to the stlink project. +**Thank you for giving feedback to the stlink project.** -**NOTICE: Please read and follow instructions in #906 before submitting a ticket. -This feature request will be deleted without notice when not enough information is provided! So please ensure that all fields are filled out.** +--- + +**NOTE: In order to offer sufficient and the best possible support, please read /CONTRIBUTING.md and follow the given instructions _before_ submitting a ticket.** + +**Bug reports and/or feature requests will be deleted, if they violate our contribution guidelines and if no issue-template is used!** Thank you for your support. + +--- - [ ] I made serious effort to avoid creating duplicate or nearly similar issue -In order to allow developers and other contributors to isolate and target your respective issue, please take some time to select the check boxes below and fill out each of the following items appropriate to your specific request. +In order to allow developers to isolate and target your respective issue, please take some time to select the check boxes below and fill out each of the following items appropriate to your specific request. - [ ] Programmer/board type: [enter here] (e.g STLINK /V1, /V2, /V2-onboard, /V2-clone, /V3) - [ ] Operating system an version: [enter here] (e.g Linux, macOS, Windows) @@ -31,7 +36,3 @@ OUTPUT/ERROR of the commandline tool(s) Expected/description: `short description of the expected value` - -Thank you for your support. - -The stlink project maintainers diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f63eca81..1b003d97e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # stlink Changelog +# v1.7.1 + +Release date: 2021-xx-xx + +Features: + +Updates & changes: + +- Added instructions for bug-reports and feature-requests to contribution guidelines ([#906](https://github.com/stlink-org/stlink/pull/906)) + +Fixes: + # v1.7.0 Release date: 2021-04-25 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a9bb02661..6c1842aca 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,6 +12,17 @@ We love your input! We want to make contributing to this project as easy and tra We use GitHub to host code, to track issues and feature requests, as well as accept pull requests. Report a bug by [opening a new issue]() with one of the available templates. It's that easy! +**NOTE: In order to offer sufficient and the best possible support, please read and follow the instructions below before submitting a ticket:** + +1) If using a ST-Link-v2 programmer: Convince yourself that it is recognised as an USB device by your computer, thus reporting device and manufacturer ID. Use a diagnostic tool to probe for enumerated USB devices, e.g [`lsusb -v`](https://linux.die.net/man/8/lsusb) on unix-based systems. +2) **Use the [ST-Link firmware upgrade tool](https://www.st.com/en/development-tools/stsw-link007.html) based on Java to read out the current firmware version and update to the latest available version. This also works for _non-genuine_ ST programmers and boards.** +3) Try to make sure you have a working toolchain before starting to build. +4) **Update to the _latest_ release version or maybe even use the `develop` branch.** +5) Search for your problem in the available open issues, _before_ opening a new ticket. +6) Make sure to **use the available issue templates** to submit a bug-report or a feature-request. **Do not replace the prepared text, edit the placeholders instead. _Describe_ your problem.** +7) Avoid to add new comments to closed issues unless they confirm a solution already available. +8) Don't comment on tickets which do not specifically address your device or hardware - open a new ticket instead. +9) Consider if you can help to solve other issues (e.g. you have the same hardware) ## Coding conventions To read code written by other contributors can turn out to be quite demanding - a variable which seems to self-explaining, may appear cryptic to other readers. If you plan to contribute, please take this into account and feel encouraged to help others understand your code. In order to help you along, we have composed some contribution guidelines for this project. As this project already has a history you may find parts in the codebase that do not seem to comply with these guidelines, but we are trying to improve continuosly. However we can do even better, if every contributor considers the following points: diff --git a/cmake/packaging/deb/changelog b/cmake/packaging/deb/changelog index 24bb0152b..4d4d86c2b 100644 --- a/cmake/packaging/deb/changelog +++ b/cmake/packaging/deb/changelog @@ -1,3 +1,9 @@ +stlink (1.7.0) unstable; urgency=medium + + * Release v1.7.0 + + -- Nightwalker-87 Sun, 25 Apr 2021 00:00:00 +0100 + stlink (1.6.1) unstable; urgency=medium * Initial cpack-based package release for Debian/Ubuntu diff --git a/cmake/packaging/rpm/changelog b/cmake/packaging/rpm/changelog index 564bd95ae..3d1c76996 100644 --- a/cmake/packaging/rpm/changelog +++ b/cmake/packaging/rpm/changelog @@ -1,2 +1,5 @@ +* Sun Apr 25 2021 Nightwalker-87 - 1.7.0 +- Release v1.7.0 + * Mon Jun 01 2020 Nightwalker-87 - 1.6.1 - Initial cpack-based RPM package release diff --git a/doc/release.md b/doc/release.md index b44183b80..a67fcd743 100644 --- a/doc/release.md +++ b/doc/release.md @@ -3,7 +3,7 @@ Release This document describes the necessary steps for developers to create a release: -1. Update `CHANGELOG.md` +1. Update `CHANGELOG.md`, `cmake/packaging/deb/changelog` & `cmake/packaging/rpm/changelog` 2. Update `.version` with semantic version: `x.x.x` 3. Update `README.md` with semantic version `x.x.x` in commits badge 4. Create and push git tag and commits `git tag x.x.x` From 2b3a31609cc25a8248cab9beb2d19f5818f1d3ab Mon Sep 17 00:00:00 2001 From: anton Date: Sun, 25 Apr 2021 12:25:15 +0500 Subject: [PATCH 1178/1435] Moved set the PG flag from loader to code --- flashloaders/stm32f0.s | 14 ------------- src/common.c | 18 +++++++++++++--- src/stlink-lib/flash_loader.c | 39 +++++++++++++---------------------- 3 files changed, 29 insertions(+), 42 deletions(-) diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index 23f1c43fe..76bfd9b95 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -30,15 +30,9 @@ copy: # add r3 to flash_base for support dual bank (see flash_loader.c) ldr r7, flash_base add r7, r7, r3 - ldr r6, flash_off_cr - add r6, r6, r7 ldr r5, flash_off_sr add r5, r5, r7 - # FLASH_CR = 0x01 (set PG) - ldr r4, =0x1 - str r4, [r6] - loop: # copy 2 bytes ldrh r4, [r0] @@ -68,18 +62,10 @@ wait: bgt loop exit: - # FLASH_CR &= ~1 - ldr r7, =0x1 - ldr r4, [r6] - bics r4, r4, r7 - str r4, [r6] - bkpt .align 2 flash_base: .word 0x40022000 -flash_off_cr: - .word 0x10 flash_off_sr: .word 0x0c diff --git a/src/common.c b/src/common.c index 4541aa31c..fcd54e93e 100644 --- a/src/common.c +++ b/src/common.c @@ -3257,6 +3257,15 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { ELOG("stlink_flash_loader_init() == -1\n"); return (-1); } + + // unlock flash + unlock_flash_if(sl); + + // set programming mode + set_flash_cr_pg(sl, BANK_1); + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + set_flash_cr_pg(sl, BANK_2); + } } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { ILOG("Starting Flash write for H7\n"); @@ -3437,7 +3446,9 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { uint32_t dhcsr; - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || + (sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_F7) || (sl->flash_type == STLINK_FLASH_TYPE_L4) || (sl->flash_type == STLINK_FLASH_TYPE_WB) || @@ -3446,8 +3457,9 @@ int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { (sl->flash_type == STLINK_FLASH_TYPE_H7)) { clear_flash_cr_pg(sl, BANK_1); - if (sl->flash_type == STLINK_FLASH_TYPE_H7 && - sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + if ((sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK) || + sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { clear_flash_cr_pg(sl, BANK_2); } lock_flash(sl); diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index ba5efdb8e..c9e7661e9 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -19,44 +19,33 @@ /* flashloaders/stm32f0.s -- compiled with thumb2 */ static const uint8_t loader_code_stm32vl[] = { 0x00, 0xbf, 0x00, 0xbf, - 0x0e, 0x4f, 0x1f, 0x44, - 0x0e, 0x4e, 0x3e, 0x44, - 0x0e, 0x4d, 0x3d, 0x44, - 0x4f, 0xf0, 0x01, 0x04, - 0x34, 0x60, 0x04, 0x88, - 0x0c, 0x80, 0x02, 0x30, - 0x02, 0x31, 0x4f, 0xf0, - 0x01, 0x07, 0x2c, 0x68, - 0x3c, 0x42, 0xfc, 0xd1, - 0x4f, 0xf0, 0x14, 0x07, - 0x3c, 0x42, 0x01, 0xd1, - 0x02, 0x3a, 0xf0, 0xdc, + 0x09, 0x4f, 0x1f, 0x44, + 0x09, 0x4d, 0x3d, 0x44, + 0x04, 0x88, 0x0c, 0x80, + 0x02, 0x30, 0x02, 0x31, 0x4f, 0xf0, 0x01, 0x07, - 0x34, 0x68, 0xbc, 0x43, - 0x34, 0x60, 0x00, 0xbe, + 0x2c, 0x68, 0x3c, 0x42, + 0xfc, 0xd1, 0x4f, 0xf0, + 0x14, 0x07, 0x3c, 0x42, + 0x01, 0xd1, 0x02, 0x3a, + 0xf0, 0xdc, 0x00, 0xbe, 0x00, 0x20, 0x02, 0x40, - 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00 }; /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ static const uint8_t loader_code_stm32f0[] = { 0xc0, 0x46, 0xc0, 0x46, - 0x0c, 0x4f, 0x1f, 0x44, - 0x0c, 0x4e, 0x3e, 0x44, - 0x0c, 0x4d, 0x3d, 0x44, - 0x0c, 0x4c, 0x34, 0x60, + 0x08, 0x4f, 0x1f, 0x44, + 0x08, 0x4d, 0x3d, 0x44, 0x04, 0x88, 0x0c, 0x80, 0x02, 0x30, 0x02, 0x31, - 0x09, 0x4f, 0x2c, 0x68, + 0x06, 0x4f, 0x2c, 0x68, 0x3c, 0x42, 0xfc, 0xd1, - 0x08, 0x4f, 0x3c, 0x42, + 0x05, 0x4f, 0x3c, 0x42, 0x01, 0xd1, 0x02, 0x3a, - 0xf2, 0xdc, 0x05, 0x4f, - 0x34, 0x68, 0xbc, 0x43, - 0x34, 0x60, 0x00, 0xbe, + 0xf2, 0xdc, 0x00, 0xbe, 0x00, 0x20, 0x02, 0x40, - 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 From 498d11b12be197392b8939d82549941beb87c52a Mon Sep 17 00:00:00 2001 From: anton Date: Sun, 25 Apr 2021 12:25:45 +0500 Subject: [PATCH 1179/1435] Moved the interrupt masking into flash loader init function --- src/common.c | 11 ----------- src/stlink-lib/flash_loader.c | 11 +++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/common.c b/src/common.c index fcd54e93e..d694ace8f 100644 --- a/src/common.c +++ b/src/common.c @@ -3137,17 +3137,6 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, } int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { - - // According to DDI0419C, Table C1-7 firstly force halt - stlink_write_debug32(sl, STLINK_REG_DHCSR, - STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | - STLINK_REG_DHCSR_C_HALT); - // and only then disable interrupts - stlink_write_debug32(sl, STLINK_REG_DHCSR, - STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | - STLINK_REG_DHCSR_C_HALT | - STLINK_REG_DHCSR_C_MASKINTS); - // disable DMA set_dma_state(sl, fl, 0); diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index c9e7661e9..4ec91258b 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -148,6 +148,17 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { size_t size = 0; uint32_t dfsr, cfsr, hfsr; + /* Interrupt masking. + * According to DDI0419C, Table C1-7 firstly force halt */ + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + STLINK_REG_DHCSR_C_HALT); + /* and only then disable interrupts */ + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_MASKINTS); + // allocate the loader in SRAM if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { WLOG("Failed to write flash loader to sram!\n"); From c959f348132ab3607a9ca8a23348f8d961e7852b Mon Sep 17 00:00:00 2001 From: anton Date: Sun, 25 Apr 2021 12:34:02 +0500 Subject: [PATCH 1180/1435] Added support for writing option bytes of F0/F1/F3 targets --- src/common.c | 185 ++++++++++++++++++++++++++++++++++++++-- src/stlink-lib/chipid.c | 36 +++++++- 2 files changed, 212 insertions(+), 9 deletions(-) diff --git a/src/common.c b/src/common.c index d694ace8f..7ddd37032 100644 --- a/src/common.c +++ b/src/common.c @@ -87,9 +87,11 @@ #define FLASH_CR_PER 1 #define FLASH_CR_MER 2 #define FLASH_CR_OPTPG 4 +#define FLASH_CR_OPTER 5 #define FLASH_CR_STRT 6 #define FLASH_CR_LOCK 7 #define FLASH_CR_OPTWRE 9 +#define FLASH_CR_OBL_LAUNCH 13 #define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00) #define STM32L_FLASH_ACR (STM32L_FLASH_REGS_ADDR + 0x00) @@ -3841,6 +3843,64 @@ int stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { return (err); } +/** + * Write option bytes + * @param sl + * @param base option bytes to write + * @param addr of the memory mapped option bytes + * @param len of options bytes to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_f0( + stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { + int ret = 0; + + if (len < 12 || addr != STM32_F0_OPTION_BYTES_BASE) { + WLOG("Only full write of option bytes area is supported\n"); + return -1; + } + + clear_flash_error(sl); + + WLOG("Erasing option bytes\n"); + + /* erase option bytes */ + stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTER) | (1 << FLASH_CR_OPTWRE)); + ret = stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTER) | (1 << FLASH_CR_STRT) | (1 << FLASH_CR_OPTWRE)); + if (ret) { + return ret; + } + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (ret) { + return ret; + } + + WLOG("Writing option bytes to %#10x\n", addr); + + /* Set the Option PG bit to enable programming */ + stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTPG) | (1 << FLASH_CR_OPTWRE)); + + /* Use flash loader for write OP + * because flash memory writable by half word */ + flash_loader_t fl; + ret = stlink_flash_loader_init(sl, &fl); + if (ret) { + return ret; + } + ret = stlink_flash_loader_run(sl, &fl, addr, base, len); + if (ret) { + return ret; + } + + /* Reload option bytes */ + stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OBL_LAUNCH)); + + return check_flash_error(sl); +} + /** * Write option bytes * @param sl @@ -4193,6 +4253,18 @@ int stlink_read_option_control_register_f7(stlink_t *sl, return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte); } +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f0(stlink_t *sl, + uint32_t *option_byte) { + DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_OBR); + return stlink_read_debug32(sl, FLASH_OBR, option_byte); +} + /** * Read option bytes * @param sl @@ -4336,8 +4408,8 @@ int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { return -1; } - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F7XXXX: + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: return stlink_read_option_bytes_boot_add_f7(sl, option_byte); default: return -1; @@ -4357,12 +4429,14 @@ int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { return -1; } - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F7XXXX: + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + return stlink_read_option_control_register_f0(sl, option_byte); + case STLINK_FLASH_TYPE_F7: return stlink_read_option_control_register_f7(sl, option_byte); default: return -1; - // return stlink_read_option_control_register_generic(sl, option_byte); } } @@ -4379,8 +4453,8 @@ int stlink_read_option_control_register1_32(stlink_t *sl, return -1; } - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F7XXXX: + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: return stlink_read_option_control_register1_f7(sl, option_byte); default: return -1; @@ -4442,6 +4516,10 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, } switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + ret = stlink_write_option_bytes_f0(sl, base, addr, len); + break; case STLINK_FLASH_TYPE_F4: ret = stlink_write_option_bytes_f4(sl, base, addr, len); break; @@ -4512,6 +4590,95 @@ stlink_write_option_control_register_f7(stlink_t *sl, return ret; } + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int +stlink_write_option_control_register_f0(stlink_t *sl, + uint32_t option_control_register) { + int ret = 0; + uint16_t opt_val[8]; + unsigned protection, optiondata; + uint16_t user_options, user_data, rdp; + unsigned option_offset, user_data_offset; + + ILOG("Asked to write option control register %#10x to %#010x.\n", + option_control_register, FLASH_OBR); + + /* Clear errors */ + clear_flash_error(sl); + + /* Retrieve current values */ + ret = stlink_read_debug32(sl, FLASH_OBR, &optiondata); + if (ret) { + return ret; + } + ret = stlink_read_debug32(sl, FLASH_WRPR, &protection); + if (ret) { + return ret; + } + + /* Translate OBR value to flash store structure + * F0: RM0091, Option byte description, pp. 75-78 + * F1: PM0075, Option byte description, pp. 19-22 + * F3: RM0316, Option byte description, pp. 85-87 */ + switch(sl->chip_id) + { + case 0x422: /* STM32F30x */ + case 0x432: /* STM32F37x */ + case 0x438: /* STM32F303x6/8 and STM32F328 */ + case 0x446: /* STM32F303xD/E and STM32F398xE */ + case 0x439: /* stm32f302x6/8 */ + case 0x440: /* stm32f05x */ + case 0x444: /* stm32f03x */ + case 0x445: /* stm32f04x */ + case 0x448: /* stm32f07x */ + case 0x442: /* stm32f09x */ + option_offset = 6; + user_data_offset = 16; + rdp = 0x55AA; + break; + default: + option_offset = 0; + user_data_offset = 10; + rdp = 0x5AA5; + break; + } + + user_options = (option_control_register >> option_offset >> 2) & 0xFFFF; + user_data = (option_control_register >> user_data_offset) & 0xFFFF; + +#define VAL_WITH_COMPLEMENT(v) (uint16_t)(((v)&0xFF) | (((~(v))<<8)&0xFF00)) + + opt_val[0] = (option_control_register & (1 << 1/*OPT_READOUT*/)) ? 0xFFFF : rdp; + opt_val[1] = VAL_WITH_COMPLEMENT(user_options); + opt_val[2] = VAL_WITH_COMPLEMENT(user_data); + opt_val[3] = VAL_WITH_COMPLEMENT(user_data >> 8); + opt_val[4] = VAL_WITH_COMPLEMENT(protection); + opt_val[5] = VAL_WITH_COMPLEMENT(protection >> 8); + opt_val[6] = VAL_WITH_COMPLEMENT(protection >> 16); + opt_val[7] = VAL_WITH_COMPLEMENT(protection >> 24); + +#undef VAL_WITH_COMPLEMENT + + /* Write bytes and check errors */ + ret = stlink_write_option_bytes_f0(sl, (uint8_t*)opt_val, STM32_F0_OPTION_BYTES_BASE, sizeof(opt_val)); + if (ret) + return ret; + + ret = check_flash_error(sl); + if (!ret) { + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, + FLASH_OBR); + } + + return ret; +} + /** * Write option bytes * @param sl @@ -4632,6 +4799,10 @@ int stlink_write_option_control_register32(stlink_t *sl, } switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + ret = stlink_write_option_control_register_f0(sl, option_control_register); + break; case STLINK_FLASH_TYPE_F7: ret = stlink_write_option_control_register_f7(sl, option_control_register); break; diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 187a6d957..3d4339526 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -57,6 +57,8 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x5000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -83,6 +85,8 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x2800, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -162,6 +166,8 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x10000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -232,6 +238,8 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x10000, .bootrom_base = 0x1fffb000, .bootrom_size = 0x4800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -244,6 +252,8 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x2000, // 0x1000 for low density devices .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -283,6 +293,8 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0xa000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -296,6 +308,8 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0xa000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -307,6 +321,8 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x8000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -332,12 +348,14 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 .bootrom_size = 0x3000, // "System memory" byte size in hex from Table 2 + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, }, { // Use this as an example for mapping future chips: // RM0091 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F0, - .description = "F0xx", + .description = "F05x", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 @@ -345,6 +363,8 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, }, { // RM0402 document was used to find these parameters @@ -387,6 +407,8 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 .bootrom_size = 0x2000, // "System memory" byte size in hex from Table 2 + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, }, { // Use this as an example for mapping future chips: @@ -400,12 +422,14 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, }, { // Use this as an example for mapping future chips: // RM0091 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F0_SMALL, - .description = "F0xx small", + .description = "F03x", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 @@ -413,6 +437,8 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, }, { // STM32F30x @@ -424,6 +450,8 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0xa000, .bootrom_base = 0x1fffd800, .bootrom_size = 0x2000, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -479,6 +507,8 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x3000, .bootrom_base = 0x1fffd800, .bootrom_size = 0x2000, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -492,6 +522,8 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x10000, // 3.3 Embedded SRAM .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory .bootrom_size = 0x2000, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, .flags = CHIP_F_HAS_SWO_TRACING, }, { From eeaef981a5dcf6bec6d9b6cada398abcf34b8737 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 25 Apr 2021 19:58:09 +0200 Subject: [PATCH 1181/1435] Re-enabled GitHub Actions CI for Ubuntu 16.04 --- .github/workflows/c-cpp.yml | 174 ++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 86 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index ef9e5f172..f68a9e53c 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -9,95 +9,95 @@ on: jobs: # Linux - # job_linux_16_04_64_gcc: - # name: ubuntu-16.04 gcc - # runs-on: ubuntu-16.04 - # steps: - # - uses: actions/checkout@v2 - # - name: Install dependencies - # run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm - # - name: make debug - # run: sudo make clean && make debug - # - name: make test - # run: sudo make clean && make test - # - name: make release - # run: sudo make clean && make release - # - name: sudo make install - # run: sudo make clean && sudo make install - # - name: sudo make package - # run: sudo make package - # - name: sudo make uninstall - # run: sudo make uninstall && sudo make clean + job_linux_16_04_64_gcc: + name: ubuntu-16.04 gcc + runs-on: ubuntu-16.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean - # job_linux_16_04_32_gcc: - # name: ubuntu-16.04 gcc 32-bit - # runs-on: ubuntu-16.04 - # steps: - # - uses: actions/checkout@v2 - # - name: Install dependencies - # run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm - # - name: Set compiler flags - # run: | - # CFLAGS="$CFLAGS -m32" - # CXXFLAGS="$CXXFLAGS -m32" - # LDFLAGS="$LDFLAGS -m32" - # - name: make debug - # run: sudo make clean && make debug - # - name: make test - # run: sudo make clean && make test - # - name: make release - # run: sudo make clean && make release - # - name: sudo make install - # run: sudo make clean && sudo make install - # - name: sudo make package - # run: sudo make package - # - name: sudo make uninstall - # run: sudo make uninstall && sudo make clean + job_linux_16_04_32_gcc: + name: ubuntu-16.04 gcc 32-bit + runs-on: ubuntu-16.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean - # job_linux_16_04_64_clang: - # name: ubuntu-16.04 clang - # runs-on: ubuntu-16.04 - # steps: - # - uses: actions/checkout@v2 - # - name: Install dependencies - # run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm - # - name: make debug - # run: sudo make clean && make debug - # - name: make test - # run: sudo make clean && make test - # - name: make release - # run: sudo make clean && make release - # - name: sudo make install - # run: sudo make clean && sudo make install - # - name: sudo make package - # run: sudo make package - # - name: sudo make uninstall - # run: sudo make uninstall && sudo make clean + job_linux_16_04_64_clang: + name: ubuntu-16.04 clang + runs-on: ubuntu-16.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean - # job_linux_16_04_32_clang: - # name: ubuntu-16.04 clang 32-bit - # runs-on: ubuntu-16.04 - # steps: - # - uses: actions/checkout@v2 - # - name: Install dependencies - # run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm - # - name: Set compiler flags - # run: | - # CFLAGS="$CFLAGS -m32" - # CXXFLAGS="$CXXFLAGS -m32" - # LDFLAGS="$LDFLAGS -m32" - # - name: make debug - # run: sudo make clean && make debug - # - name: make test - # run: sudo make clean && make test - # - name: make release - # run: sudo make clean && make release - # - name: sudo make install - # run: sudo make clean && sudo make install - # - name: sudo make package - # run: sudo make package - # - name: sudo make uninstall - # run: sudo make uninstall && sudo make clean + job_linux_16_04_32_clang: + name: ubuntu-16.04 clang 32-bit + runs-on: ubuntu-16.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean job_linux_18_04_64_gcc: name: ubuntu-18.04 gcc @@ -410,6 +410,7 @@ jobs: run: sudo make package - name: sudo make uninstall run: sudo make uninstall && sudo make clean + # job_macos_11_gcc: # name: macos-11.0 gcc # runs-on: macos-11.0 @@ -448,6 +449,7 @@ jobs: # run: sudo make package # - name: sudo make uninstall # run: sudo make uninstall && sudo make clean + # Linux MinGW cross compliation # job_linux_20_04_cross: From 1e8333e8ac8b7767a83bde6e3e43cd90f3fe0faf Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 25 Apr 2021 20:39:12 +0200 Subject: [PATCH 1182/1435] Fix for failed merge conflict resolve --- src/stlink-lib/chipid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index c505ed23a..f260af168 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -763,8 +763,8 @@ static struct stlink_chipid_params devices[] = { }, }; -const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { - const struct stlink_chipid_params *params = NULL; +struct stlink_chipid_params *stlink_chipid_get_params_old(uint32_t chipid) { + struct stlink_chipid_params *params = NULL; for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) if (devices[n].chip_id == chipid) { From 939998de76a904d82ba8248baacf4fc26d98badc Mon Sep 17 00:00:00 2001 From: anton Date: Tue, 27 Apr 2021 19:46:28 +0500 Subject: [PATCH 1183/1435] Fixed security warning --- src/stlink-lib/logging.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/stlink-lib/logging.c b/src/stlink-lib/logging.c index 87978230d..d7ce13473 100644 --- a/src/stlink-lib/logging.c +++ b/src/stlink-lib/logging.c @@ -29,10 +29,10 @@ int ugly_log(int level, const char *tag, const char *format, ...) { va_list args; va_start(args, format); time_t mytt = time(NULL); - struct tm *tt; - tt = localtime(&mytt); - fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", tt->tm_year + 1900, - tt->tm_mon + 1, tt->tm_mday, tt->tm_hour, tt->tm_min, tt->tm_sec); + struct tm tt; + localtime_r(&mytt, &tt); + fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", tt.tm_year + 1900, + tt.tm_mon + 1, tt.tm_mday, tt.tm_hour, tt.tm_min, tt.tm_sec); switch (level) { case UDEBUG: From b652bc48549009a9d85ce7b1fc2449c146c05ae4 Mon Sep 17 00:00:00 2001 From: "R.E. Wolff" Date: Wed, 28 Apr 2021 17:31:34 +0200 Subject: [PATCH 1184/1435] Chips files in the right place in the sources --- config/chips/F04x.chip | 13 +++++++++++++ config/chips/F07x.chip | 13 +++++++++++++ config/chips/F09X.chip | 13 +++++++++++++ config/chips/F0xx small.chip | 13 +++++++++++++ config/chips/F0xx.chip | 13 +++++++++++++ config/chips/F1 Connectivity line.chip | 13 +++++++++++++ config/chips/F1 Low-density device.chip | 13 +++++++++++++ config/chips/F1xx High-density value line.chip | 13 +++++++++++++ config/chips/F1xx High-density.chip | 13 +++++++++++++ config/chips/F1xx Medium-density.chip | 13 +++++++++++++ config/chips/F1xx Value Line.chip | 13 +++++++++++++ config/chips/F1xx XL-density.chip | 13 +++++++++++++ config/chips/F2xx.chip | 13 +++++++++++++ config/chips/F303 high density.chip | 13 +++++++++++++ config/chips/F334 medium density.chip | 13 +++++++++++++ config/chips/F3xx small.chip | 13 +++++++++++++ config/chips/F3xx.chip | 13 +++++++++++++ config/chips/F410.chip | 13 +++++++++++++ config/chips/F412.chip | 13 +++++++++++++ config/chips/F413.chip | 13 +++++++++++++ config/chips/F42x_F43x.chip | 13 +++++++++++++ config/chips/F446.chip | 13 +++++++++++++ config/chips/F46x_F47x.chip | 13 +++++++++++++ config/chips/F4xx (Dynamic Efficency).chip | 13 +++++++++++++ config/chips/F4xx (low power).chip | 13 +++++++++++++ config/chips/F4xx.chip | 13 +++++++++++++ config/chips/F72x_F73x.chip | 13 +++++++++++++ config/chips/F76xxx.chip | 13 +++++++++++++ config/chips/F7xx.chip | 13 +++++++++++++ config/chips/G030_G031_G041.chip | 13 +++++++++++++ config/chips/G070_G071_G081.chip | 13 +++++++++++++ config/chips/G4 Category-2.chip | 13 +++++++++++++ config/chips/G4 Category-3.chip | 13 +++++++++++++ config/chips/H72x_H73x.chip | 13 +++++++++++++ config/chips/H74x_H75x.chip | 13 +++++++++++++ config/chips/H7Ax_H7Bx.chip | 13 +++++++++++++ config/chips/L011.chip | 13 +++++++++++++ config/chips/L0x3.chip | 13 +++++++++++++ config/chips/L0xx Category 2.chip | 13 +++++++++++++ config/chips/L0xx Category 5.chip | 13 +++++++++++++ config/chips/L152RE.chip | 13 +++++++++++++ config/chips/L1xx Cat.2.chip | 13 +++++++++++++ config/chips/L1xx High-density.chip | 13 +++++++++++++ config/chips/L1xx Medium-Plus-density.chip | 13 +++++++++++++ config/chips/L1xx Medium-density.chip | 13 +++++++++++++ config/chips/L41x.chip | 13 +++++++++++++ config/chips/L43x_L44x.chip | 13 +++++++++++++ config/chips/L45x_46x.chip | 13 +++++++++++++ config/chips/L496x_L4A6x.chip | 13 +++++++++++++ config/chips/L4Rx.chip | 13 +++++++++++++ config/chips/L4xx.chip | 13 +++++++++++++ config/chips/WB55.chip | 13 +++++++++++++ config/chips/stm32f411re.chip | 13 +++++++++++++ config/chips/unknown device.chip | 13 +++++++++++++ src/chips.zip | Bin 16336 -> 0 bytes 55 files changed, 702 insertions(+) create mode 100644 config/chips/F04x.chip create mode 100644 config/chips/F07x.chip create mode 100644 config/chips/F09X.chip create mode 100644 config/chips/F0xx small.chip create mode 100644 config/chips/F0xx.chip create mode 100644 config/chips/F1 Connectivity line.chip create mode 100644 config/chips/F1 Low-density device.chip create mode 100644 config/chips/F1xx High-density value line.chip create mode 100644 config/chips/F1xx High-density.chip create mode 100644 config/chips/F1xx Medium-density.chip create mode 100644 config/chips/F1xx Value Line.chip create mode 100644 config/chips/F1xx XL-density.chip create mode 100644 config/chips/F2xx.chip create mode 100644 config/chips/F303 high density.chip create mode 100644 config/chips/F334 medium density.chip create mode 100644 config/chips/F3xx small.chip create mode 100644 config/chips/F3xx.chip create mode 100644 config/chips/F410.chip create mode 100644 config/chips/F412.chip create mode 100644 config/chips/F413.chip create mode 100644 config/chips/F42x_F43x.chip create mode 100644 config/chips/F446.chip create mode 100644 config/chips/F46x_F47x.chip create mode 100644 config/chips/F4xx (Dynamic Efficency).chip create mode 100644 config/chips/F4xx (low power).chip create mode 100644 config/chips/F4xx.chip create mode 100644 config/chips/F72x_F73x.chip create mode 100644 config/chips/F76xxx.chip create mode 100644 config/chips/F7xx.chip create mode 100644 config/chips/G030_G031_G041.chip create mode 100644 config/chips/G070_G071_G081.chip create mode 100644 config/chips/G4 Category-2.chip create mode 100644 config/chips/G4 Category-3.chip create mode 100644 config/chips/H72x_H73x.chip create mode 100644 config/chips/H74x_H75x.chip create mode 100644 config/chips/H7Ax_H7Bx.chip create mode 100644 config/chips/L011.chip create mode 100644 config/chips/L0x3.chip create mode 100644 config/chips/L0xx Category 2.chip create mode 100644 config/chips/L0xx Category 5.chip create mode 100644 config/chips/L152RE.chip create mode 100644 config/chips/L1xx Cat.2.chip create mode 100644 config/chips/L1xx High-density.chip create mode 100644 config/chips/L1xx Medium-Plus-density.chip create mode 100644 config/chips/L1xx Medium-density.chip create mode 100644 config/chips/L41x.chip create mode 100644 config/chips/L43x_L44x.chip create mode 100644 config/chips/L45x_46x.chip create mode 100644 config/chips/L496x_L4A6x.chip create mode 100644 config/chips/L4Rx.chip create mode 100644 config/chips/L4xx.chip create mode 100644 config/chips/WB55.chip create mode 100644 config/chips/stm32f411re.chip create mode 100644 config/chips/unknown device.chip delete mode 100644 src/chips.zip diff --git a/config/chips/F04x.chip b/config/chips/F04x.chip new file mode 100644 index 000000000..72db26f8c --- /dev/null +++ b/config/chips/F04x.chip @@ -0,0 +1,13 @@ +# Chipid file for F04x +# +chip_id 445 +description F04x +flash_type 1 +flash_pagesize 400 +sram_size 1800 +bootrom_base 1fffec00 +bootrom_size c00 +option_base 0 +option_size 0 +flags 0 + diff --git a/config/chips/F07x.chip b/config/chips/F07x.chip new file mode 100644 index 000000000..cfedfa76f --- /dev/null +++ b/config/chips/F07x.chip @@ -0,0 +1,13 @@ +# Chipid file for F07x +# +chip_id 448 +description F07x +flash_type 1 +flash_pagesize 800 +sram_size 4000 +bootrom_base 1fffc800 +bootrom_size 3000 +option_base 0 +option_size 0 +flags 0 + diff --git a/config/chips/F09X.chip b/config/chips/F09X.chip new file mode 100644 index 000000000..a622cf2f5 --- /dev/null +++ b/config/chips/F09X.chip @@ -0,0 +1,13 @@ +# Chipid file for F09X +# +chip_id 442 +description F09X +flash_type 1 +flash_pagesize 800 +sram_size 8000 +bootrom_base 1fffd800 +bootrom_size 2000 +option_base 0 +option_size 0 +flags 0 + diff --git a/config/chips/F0xx small.chip b/config/chips/F0xx small.chip new file mode 100644 index 000000000..65aea58ac --- /dev/null +++ b/config/chips/F0xx small.chip @@ -0,0 +1,13 @@ +# Chipid file for F0xx small +# +chip_id 444 +description F0xx small +flash_type 1 +flash_pagesize 400 +sram_size 1000 +bootrom_base 1fffec00 +bootrom_size c00 +option_base 0 +option_size 0 +flags 0 + diff --git a/config/chips/F0xx.chip b/config/chips/F0xx.chip new file mode 100644 index 000000000..5a5529412 --- /dev/null +++ b/config/chips/F0xx.chip @@ -0,0 +1,13 @@ +# Chipid file for F0xx +# +chip_id 440 +description F0xx +flash_type 1 +flash_pagesize 400 +sram_size 2000 +bootrom_base 1fffec00 +bootrom_size c00 +option_base 0 +option_size 0 +flags 0 + diff --git a/config/chips/F1 Connectivity line.chip b/config/chips/F1 Connectivity line.chip new file mode 100644 index 000000000..676fd1945 --- /dev/null +++ b/config/chips/F1 Connectivity line.chip @@ -0,0 +1,13 @@ +# Chipid file for F1 Connectivity line +# +chip_id 418 +description F1 Connectivity line +flash_type 1 +flash_pagesize 800 +sram_size 10000 +bootrom_base 1fffb000 +bootrom_size 4800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F1 Low-density device.chip b/config/chips/F1 Low-density device.chip new file mode 100644 index 000000000..dcb5e279e --- /dev/null +++ b/config/chips/F1 Low-density device.chip @@ -0,0 +1,13 @@ +# Chipid file for F1 Low-density device +# +chip_id 412 +description F1 Low-density device +flash_type 1 +flash_pagesize 400 +sram_size 2800 +bootrom_base 1ffff000 +bootrom_size 800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F1xx High-density value line.chip b/config/chips/F1xx High-density value line.chip new file mode 100644 index 000000000..f30014122 --- /dev/null +++ b/config/chips/F1xx High-density value line.chip @@ -0,0 +1,13 @@ +# Chipid file for F1xx High-density value line +# +chip_id 428 +description F1xx High-density value line +flash_type 1 +flash_pagesize 800 +sram_size 8000 +bootrom_base 1ffff000 +bootrom_size 800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F1xx High-density.chip b/config/chips/F1xx High-density.chip new file mode 100644 index 000000000..ed02e691a --- /dev/null +++ b/config/chips/F1xx High-density.chip @@ -0,0 +1,13 @@ +# Chipid file for F1xx High-density +# +chip_id 414 +description F1xx High-density +flash_type 1 +flash_pagesize 800 +sram_size 10000 +bootrom_base 1ffff000 +bootrom_size 800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F1xx Medium-density.chip b/config/chips/F1xx Medium-density.chip new file mode 100644 index 000000000..32266b74e --- /dev/null +++ b/config/chips/F1xx Medium-density.chip @@ -0,0 +1,13 @@ +# Chipid file for F1xx Medium-density +# +chip_id 410 +description F1xx Medium-density +flash_type 1 +flash_pagesize 400 +sram_size 5000 +bootrom_base 1ffff000 +bootrom_size 800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F1xx Value Line.chip b/config/chips/F1xx Value Line.chip new file mode 100644 index 000000000..929b95496 --- /dev/null +++ b/config/chips/F1xx Value Line.chip @@ -0,0 +1,13 @@ +# Chipid file for F1xx Value Line +# +chip_id 420 +description F1xx Value Line +flash_type 1 +flash_pagesize 400 +sram_size 2000 +bootrom_base 1ffff000 +bootrom_size 800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F1xx XL-density.chip b/config/chips/F1xx XL-density.chip new file mode 100644 index 000000000..a7125a429 --- /dev/null +++ b/config/chips/F1xx XL-density.chip @@ -0,0 +1,13 @@ +# Chipid file for F1xx XL-density +# +chip_id 430 +description F1xx XL-density +flash_type 2 +flash_pagesize 800 +sram_size 18000 +bootrom_base 1fffe000 +bootrom_size 1800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F2xx.chip b/config/chips/F2xx.chip new file mode 100644 index 000000000..b31be46f3 --- /dev/null +++ b/config/chips/F2xx.chip @@ -0,0 +1,13 @@ +# Chipid file for F2xx +# +chip_id 411 +description F2xx +flash_type 3 +flash_pagesize 20000 +sram_size 20000 +bootrom_base 1fff0000 +bootrom_size 7800 +option_base 1fffc000 +option_size 4 +flags 2 + diff --git a/config/chips/F303 high density.chip b/config/chips/F303 high density.chip new file mode 100644 index 000000000..716c37c1e --- /dev/null +++ b/config/chips/F303 high density.chip @@ -0,0 +1,13 @@ +# Chipid file for F303 high density +# +chip_id 446 +description F303 high density +flash_type 1 +flash_pagesize 800 +sram_size 10000 +bootrom_base 1fffd800 +bootrom_size 2000 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F334 medium density.chip b/config/chips/F334 medium density.chip new file mode 100644 index 000000000..424f1063c --- /dev/null +++ b/config/chips/F334 medium density.chip @@ -0,0 +1,13 @@ +# Chipid file for F334 medium density +# +chip_id 438 +description F334 medium density +flash_type 1 +flash_pagesize 800 +sram_size 3000 +bootrom_base 1fffd800 +bootrom_size 2000 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F3xx small.chip b/config/chips/F3xx small.chip new file mode 100644 index 000000000..7f6f5159c --- /dev/null +++ b/config/chips/F3xx small.chip @@ -0,0 +1,13 @@ +# Chipid file for F3xx small +# +chip_id 439 +description F3xx small +flash_type 1 +flash_pagesize 800 +sram_size a000 +bootrom_base 1fffd800 +bootrom_size 2000 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F3xx.chip b/config/chips/F3xx.chip new file mode 100644 index 000000000..4195f9007 --- /dev/null +++ b/config/chips/F3xx.chip @@ -0,0 +1,13 @@ +# Chipid file for F3xx +# +chip_id 432 +description F3xx +flash_type 1 +flash_pagesize 800 +sram_size a000 +bootrom_base 1ffff000 +bootrom_size 800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F410.chip b/config/chips/F410.chip new file mode 100644 index 000000000..3fb1b3d2a --- /dev/null +++ b/config/chips/F410.chip @@ -0,0 +1,13 @@ +# Chipid file for F410 +# +chip_id 458 +description F410 +flash_type 3 +flash_pagesize 4000 +sram_size 8000 +bootrom_base 1fff0000 +bootrom_size 7800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F412.chip b/config/chips/F412.chip new file mode 100644 index 000000000..138e6c273 --- /dev/null +++ b/config/chips/F412.chip @@ -0,0 +1,13 @@ +# Chipid file for F412 +# +chip_id 441 +description F412 +flash_type 3 +flash_pagesize 4000 +sram_size 40000 +bootrom_base 1fff0000 +bootrom_size 7800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F413.chip b/config/chips/F413.chip new file mode 100644 index 000000000..305a808dc --- /dev/null +++ b/config/chips/F413.chip @@ -0,0 +1,13 @@ +# Chipid file for F413 +# +chip_id 463 +description F413 +flash_type 3 +flash_pagesize 4000 +sram_size 50000 +bootrom_base 1fff0000 +bootrom_size 7800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F42x_F43x.chip b/config/chips/F42x_F43x.chip new file mode 100644 index 000000000..c279a0e1d --- /dev/null +++ b/config/chips/F42x_F43x.chip @@ -0,0 +1,13 @@ +# Chipid file for F42x/F43x +# +chip_id 419 +description F42x/F43x +flash_type 3 +flash_pagesize 4000 +sram_size 40000 +bootrom_base 1fff0000 +bootrom_size 7800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F446.chip b/config/chips/F446.chip new file mode 100644 index 000000000..6f372c067 --- /dev/null +++ b/config/chips/F446.chip @@ -0,0 +1,13 @@ +# Chipid file for F446 +# +chip_id 421 +description F446 +flash_type 3 +flash_pagesize 20000 +sram_size 20000 +bootrom_base 1fff0000 +bootrom_size 7800 +option_base 1fffc000 +option_size 4 +flags 2 + diff --git a/config/chips/F46x_F47x.chip b/config/chips/F46x_F47x.chip new file mode 100644 index 000000000..6d03bbea2 --- /dev/null +++ b/config/chips/F46x_F47x.chip @@ -0,0 +1,13 @@ +# Chipid file for F46x/F47x +# +chip_id 434 +description F46x/F47x +flash_type 3 +flash_pagesize 4000 +sram_size 40000 +bootrom_base 1fff0000 +bootrom_size 7800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F4xx (Dynamic Efficency).chip b/config/chips/F4xx (Dynamic Efficency).chip new file mode 100644 index 000000000..fda012826 --- /dev/null +++ b/config/chips/F4xx (Dynamic Efficency).chip @@ -0,0 +1,13 @@ +# Chipid file for F4xx (Dynamic Efficency) +# +chip_id 433 +description F4xx (Dynamic Efficency) +flash_type 3 +flash_pagesize 4000 +sram_size 18000 +bootrom_base 1fff0000 +bootrom_size 7800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F4xx (low power).chip b/config/chips/F4xx (low power).chip new file mode 100644 index 000000000..db9e99ffa --- /dev/null +++ b/config/chips/F4xx (low power).chip @@ -0,0 +1,13 @@ +# Chipid file for F4xx (low power) +# +chip_id 423 +description F4xx (low power) +flash_type 3 +flash_pagesize 4000 +sram_size 10000 +bootrom_base 1fff0000 +bootrom_size 7800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F4xx.chip b/config/chips/F4xx.chip new file mode 100644 index 000000000..a9dd110c5 --- /dev/null +++ b/config/chips/F4xx.chip @@ -0,0 +1,13 @@ +# Chipid file for F4xx +# +chip_id 413 +description F4xx +flash_type 3 +flash_pagesize 4000 +sram_size 30000 +bootrom_base 1fff0000 +bootrom_size 7800 +option_base 40023c14 +option_size 4 +flags 2 + diff --git a/config/chips/F72x_F73x.chip b/config/chips/F72x_F73x.chip new file mode 100644 index 000000000..a673b04f0 --- /dev/null +++ b/config/chips/F72x_F73x.chip @@ -0,0 +1,13 @@ +# Chipid file for F72x/F73x +# +chip_id 452 +description F72x/F73x +flash_type 3 +flash_pagesize 800 +sram_size 40000 +bootrom_base 100000 +bootrom_size edc0 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/F76xxx.chip b/config/chips/F76xxx.chip new file mode 100644 index 000000000..c8f9ee108 --- /dev/null +++ b/config/chips/F76xxx.chip @@ -0,0 +1,13 @@ +# Chipid file for F76xxx +# +chip_id 451 +description F76xxx +flash_type 4 +flash_pagesize 800 +sram_size 80000 +bootrom_base 200000 +bootrom_size edc0 +option_base 1fff0000 +option_size 20 +flags 2 + diff --git a/config/chips/F7xx.chip b/config/chips/F7xx.chip new file mode 100644 index 000000000..c704ce2e2 --- /dev/null +++ b/config/chips/F7xx.chip @@ -0,0 +1,13 @@ +# Chipid file for F7xx +# +chip_id 449 +description F7xx +flash_type 3 +flash_pagesize 800 +sram_size 50000 +bootrom_base 100000 +bootrom_size edc0 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/G030_G031_G041.chip b/config/chips/G030_G031_G041.chip new file mode 100644 index 000000000..c6553904e --- /dev/null +++ b/config/chips/G030_G031_G041.chip @@ -0,0 +1,13 @@ +# Chipid file for G030/G031/G041 +# +chip_id 466 +description G030/G031/G041 +flash_type 7 +flash_pagesize 800 +sram_size 2000 +bootrom_base 1fff0000 +bootrom_size 2000 +option_base 1fff7800 +option_size 4 +flags 0 + diff --git a/config/chips/G070_G071_G081.chip b/config/chips/G070_G071_G081.chip new file mode 100644 index 000000000..ab57bbd27 --- /dev/null +++ b/config/chips/G070_G071_G081.chip @@ -0,0 +1,13 @@ +# Chipid file for G070/G071/G081 +# +chip_id 460 +description G070/G071/G081 +flash_type 7 +flash_pagesize 800 +sram_size 9000 +bootrom_base 1fff0000 +bootrom_size 7000 +option_base 1fff7800 +option_size 4 +flags 0 + diff --git a/config/chips/G4 Category-2.chip b/config/chips/G4 Category-2.chip new file mode 100644 index 000000000..400152cd6 --- /dev/null +++ b/config/chips/G4 Category-2.chip @@ -0,0 +1,13 @@ +# Chipid file for G4 Category-2 +# +chip_id 468 +description G4 Category-2 +flash_type 8 +flash_pagesize 800 +sram_size 8000 +bootrom_base 1fff0000 +bootrom_size 7000 +option_base 1ffff800 +option_size 4 +flags 2 + diff --git a/config/chips/G4 Category-3.chip b/config/chips/G4 Category-3.chip new file mode 100644 index 000000000..f8ea053f7 --- /dev/null +++ b/config/chips/G4 Category-3.chip @@ -0,0 +1,13 @@ +# Chipid file for G4 Category-3 +# +chip_id 469 +description G4 Category-3 +flash_type 8 +flash_pagesize 800 +sram_size 18000 +bootrom_base 1fff0000 +bootrom_size 7000 +option_base 1ffff800 +option_size 4 +flags 3 + diff --git a/config/chips/H72x_H73x.chip b/config/chips/H72x_H73x.chip new file mode 100644 index 000000000..e63c855c8 --- /dev/null +++ b/config/chips/H72x_H73x.chip @@ -0,0 +1,13 @@ +# Chipid file for H72x/H73x +# +chip_id 483 +description H72x/H73x +flash_type a +flash_pagesize 20000 +sram_size 20000 +bootrom_base 1ff00000 +bootrom_size 20000 +option_base 5200201c +option_size 2c +flags 2 + diff --git a/config/chips/H74x_H75x.chip b/config/chips/H74x_H75x.chip new file mode 100644 index 000000000..24e85ff66 --- /dev/null +++ b/config/chips/H74x_H75x.chip @@ -0,0 +1,13 @@ +# Chipid file for H74x/H75x +# +chip_id 450 +description H74x/H75x +flash_type a +flash_pagesize 20000 +sram_size 20000 +bootrom_base 1ff00000 +bootrom_size 20000 +option_base 5200201c +option_size 2c +flags 3 + diff --git a/config/chips/H7Ax_H7Bx.chip b/config/chips/H7Ax_H7Bx.chip new file mode 100644 index 000000000..bffd23603 --- /dev/null +++ b/config/chips/H7Ax_H7Bx.chip @@ -0,0 +1,13 @@ +# Chipid file for H7Ax/H7Bx +# +chip_id 480 +description H7Ax/H7Bx +flash_type a +flash_pagesize 2000 +sram_size 20000 +bootrom_base 1ff00000 +bootrom_size 20000 +option_base 5200201c +option_size 2c +flags 3 + diff --git a/config/chips/L011.chip b/config/chips/L011.chip new file mode 100644 index 000000000..02223ddcf --- /dev/null +++ b/config/chips/L011.chip @@ -0,0 +1,13 @@ +# Chipid file for L011 +# +chip_id 457 +description L011 +flash_type 5 +flash_pagesize 80 +sram_size 2000 +bootrom_base 1ff00000 +bootrom_size 2000 +option_base 0 +option_size 0 +flags 0 + diff --git a/config/chips/L0x3.chip b/config/chips/L0x3.chip new file mode 100644 index 000000000..60d75e863 --- /dev/null +++ b/config/chips/L0x3.chip @@ -0,0 +1,13 @@ +# Chipid file for L0x3 +# +chip_id 417 +description L0x3 +flash_type 5 +flash_pagesize 80 +sram_size 2000 +bootrom_base 1ff0000 +bootrom_size 1000 +option_base 1ff80000 +option_size 14 +flags 0 + diff --git a/config/chips/L0xx Category 2.chip b/config/chips/L0xx Category 2.chip new file mode 100644 index 000000000..1cb9e1307 --- /dev/null +++ b/config/chips/L0xx Category 2.chip @@ -0,0 +1,13 @@ +# Chipid file for L0xx Category 2 +# +chip_id 425 +description L0xx Category 2 +flash_type 5 +flash_pagesize 80 +sram_size 2000 +bootrom_base 1ff0000 +bootrom_size 1000 +option_base 1ff80000 +option_size 14 +flags 0 + diff --git a/config/chips/L0xx Category 5.chip b/config/chips/L0xx Category 5.chip new file mode 100644 index 000000000..35df2fb02 --- /dev/null +++ b/config/chips/L0xx Category 5.chip @@ -0,0 +1,13 @@ +# Chipid file for L0xx Category 5 +# +chip_id 447 +description L0xx Category 5 +flash_type 5 +flash_pagesize 80 +sram_size 5000 +bootrom_base 1ff0000 +bootrom_size 2000 +option_base 1ff80000 +option_size 14 +flags 0 + diff --git a/config/chips/L152RE.chip b/config/chips/L152RE.chip new file mode 100644 index 000000000..ec9d24442 --- /dev/null +++ b/config/chips/L152RE.chip @@ -0,0 +1,13 @@ +# Chipid file for L152RE +# +chip_id 437 +description L152RE +flash_type 5 +flash_pagesize 100 +sram_size 14000 +bootrom_base 1ff00000 +bootrom_size 1000 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/L1xx Cat.2.chip b/config/chips/L1xx Cat.2.chip new file mode 100644 index 000000000..7a3080c60 --- /dev/null +++ b/config/chips/L1xx Cat.2.chip @@ -0,0 +1,13 @@ +# Chipid file for L1xx Cat.2 +# +chip_id 429 +description L1xx Cat.2 +flash_type 5 +flash_pagesize 100 +sram_size 8000 +bootrom_base 1ff00000 +bootrom_size 1000 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/L1xx High-density.chip b/config/chips/L1xx High-density.chip new file mode 100644 index 000000000..4f6c85929 --- /dev/null +++ b/config/chips/L1xx High-density.chip @@ -0,0 +1,13 @@ +# Chipid file for L1xx High-density +# +chip_id 436 +description L1xx High-density +flash_type 5 +flash_pagesize 100 +sram_size c000 +bootrom_base 1ff00000 +bootrom_size 1000 +option_base 1ff80000 +option_size 8 +flags 2 + diff --git a/config/chips/L1xx Medium-Plus-density.chip b/config/chips/L1xx Medium-Plus-density.chip new file mode 100644 index 000000000..30ce11e92 --- /dev/null +++ b/config/chips/L1xx Medium-Plus-density.chip @@ -0,0 +1,13 @@ +# Chipid file for L1xx Medium-Plus-density +# +chip_id 427 +description L1xx Medium-Plus-density +flash_type 5 +flash_pagesize 100 +sram_size 8000 +bootrom_base 1ff00000 +bootrom_size 1000 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/L1xx Medium-density.chip b/config/chips/L1xx Medium-density.chip new file mode 100644 index 000000000..a1817c5d6 --- /dev/null +++ b/config/chips/L1xx Medium-density.chip @@ -0,0 +1,13 @@ +# Chipid file for L1xx Medium-density +# +chip_id 416 +description L1xx Medium-density +flash_type 5 +flash_pagesize 100 +sram_size 4000 +bootrom_base 1ff00000 +bootrom_size 1000 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/L41x.chip b/config/chips/L41x.chip new file mode 100644 index 000000000..008c9bfa2 --- /dev/null +++ b/config/chips/L41x.chip @@ -0,0 +1,13 @@ +# Chipid file for L41x +# +chip_id 464 +description L41x +flash_type 6 +flash_pagesize 800 +sram_size a000 +bootrom_base 1fff0000 +bootrom_size 7000 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/L43x_L44x.chip b/config/chips/L43x_L44x.chip new file mode 100644 index 000000000..1d956c15e --- /dev/null +++ b/config/chips/L43x_L44x.chip @@ -0,0 +1,13 @@ +# Chipid file for L43x/L44x +# +chip_id 435 +description L43x/L44x +flash_type 6 +flash_pagesize 800 +sram_size c000 +bootrom_base 1fff0000 +bootrom_size 7000 +option_base 1fff7800 +option_size 4 +flags 2 + diff --git a/config/chips/L45x_46x.chip b/config/chips/L45x_46x.chip new file mode 100644 index 000000000..438821fcc --- /dev/null +++ b/config/chips/L45x_46x.chip @@ -0,0 +1,13 @@ +# Chipid file for L45x/46x +# +chip_id 462 +description L45x/46x +flash_type 6 +flash_pagesize 800 +sram_size 20000 +bootrom_base 1fff0000 +bootrom_size 7000 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/L496x_L4A6x.chip b/config/chips/L496x_L4A6x.chip new file mode 100644 index 000000000..b607e18cc --- /dev/null +++ b/config/chips/L496x_L4A6x.chip @@ -0,0 +1,13 @@ +# Chipid file for L496x/L4A6x +# +chip_id 461 +description L496x/L4A6x +flash_type 6 +flash_pagesize 800 +sram_size 40000 +bootrom_base 1fff0000 +bootrom_size 7000 +option_base 1fff7800 +option_size 4 +flags 2 + diff --git a/config/chips/L4Rx.chip b/config/chips/L4Rx.chip new file mode 100644 index 000000000..e42aba017 --- /dev/null +++ b/config/chips/L4Rx.chip @@ -0,0 +1,13 @@ +# Chipid file for L4Rx +# +chip_id 470 +description L4Rx +flash_type 6 +flash_pagesize 1000 +sram_size a0000 +bootrom_base 1fff0000 +bootrom_size 7000 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/L4xx.chip b/config/chips/L4xx.chip new file mode 100644 index 000000000..10ec24455 --- /dev/null +++ b/config/chips/L4xx.chip @@ -0,0 +1,13 @@ +# Chipid file for L4xx +# +chip_id 415 +description L4xx +flash_type 6 +flash_pagesize 800 +sram_size 18000 +bootrom_base 1fff0000 +bootrom_size 7000 +option_base 1fff7800 +option_size 4 +flags 2 + diff --git a/config/chips/WB55.chip b/config/chips/WB55.chip new file mode 100644 index 000000000..bdc0d4449 --- /dev/null +++ b/config/chips/WB55.chip @@ -0,0 +1,13 @@ +# Chipid file for WB55 +# +chip_id 495 +description WB55 +flash_type 9 +flash_pagesize 1000 +sram_size 40000 +bootrom_base 1fff0000 +bootrom_size 7000 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/stm32f411re.chip b/config/chips/stm32f411re.chip new file mode 100644 index 000000000..ef889c139 --- /dev/null +++ b/config/chips/stm32f411re.chip @@ -0,0 +1,13 @@ +# Chipid file for stm32f411re +# +chip_id 431 +description stm32f411re +flash_type 3 +flash_pagesize 4000 +sram_size 20000 +bootrom_base 1fff0000 +bootrom_size 7800 +option_base 0 +option_size 0 +flags 2 + diff --git a/config/chips/unknown device.chip b/config/chips/unknown device.chip new file mode 100644 index 000000000..63ba47a30 --- /dev/null +++ b/config/chips/unknown device.chip @@ -0,0 +1,13 @@ +# Chipid file for unknown device +# +chip_id 0 +description unknown device +flash_type 0 +flash_pagesize 0 +sram_size 0 +bootrom_base 0 +bootrom_size 0 +option_base 0 +option_size 0 +flags 0 + diff --git a/src/chips.zip b/src/chips.zip deleted file mode 100644 index e11e5cc6a4b9adb265d7aacbd718588f4720ae12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16336 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 Y@ZToF1>^+`3>fey8^~tq_z=JSAJ`js!2kdN From 09157fa926fd5b41cefb0f99f2b9e59eede75020 Mon Sep 17 00:00:00 2001 From: "R.E. Wolff" Date: Wed, 28 Apr 2021 18:41:16 +0200 Subject: [PATCH 1185/1435] Moved the chips files to our own etc directory. --- CMakeLists.txt | 8 ++++++++ src/st-util/gdb-server.c | 3 +-- src/stlink-lib/chipid.c | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 064aa06d5..feca0431a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,11 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +set(CMAKE_STLINK_ETC_DIR etc) +set(CMAKE_ETC_CHIPS_DIR ${CMAKE_STLINK_ETC_DIR}/stlink/chips) +set(CMAKE_ETC_CHIPS_DIR_ABS ${CMAKE_INSTALL_PREFIX}/${CMAKE_ETC_CHIPS_DIR}) +add_definitions( -DETC_STLINK_DIR="${CMAKE_ETC_CHIPS_DIR_ABS}" ) + ### # General project settings @@ -274,6 +279,9 @@ install(TARGETS st-info DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS st-util DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS st-trace DESTINATION ${CMAKE_INSTALL_BINDIR}) +file(GLOB CHIP_FILES ${CMAKE_SOURCE_DIR}/config/chips/*.chip) +install(FILES ${CHIP_FILES} DESTINATION ${CMAKE_ETC_CHIPS_DIR}) + ### # Device configuration (Linux only) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 797f4391b..6fe8774f7 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -219,8 +219,7 @@ int main(int argc, char** argv) { state.connect_mode = CONNECT_NORMAL; // by default, reset board parse_options(argc, argv, &state); - printf("st-util\n"); - init_chipids (NULL); + init_chipids (ETC_STLINK_DIR); sl = stlink_open_usb(state.logging_level, state.connect_mode, state.serialnumber, state.freq); if (sl == NULL) { return(1); } diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index e094f910f..bcb017740 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -782,7 +782,7 @@ void process_chipfile (char *fname) struct stlink_chipid_params *ts; int nc; - fprintf (stderr, "processing chipfile %s.\n", fname); + //fprintf (stderr, "processing chipfile %s.\n", fname); fp = fopen (fname, "r"); if (!fp) { perror (fname); @@ -872,7 +872,7 @@ void init_chipids (char *dir_to_scan) devicelist = NULL; //dump_chips (); - d = opendir("."); + d = opendir(dir_to_scan); if (d) { while ((dir = readdir(d)) != NULL) { nl = strlen (dir->d_name); From 7ee9fbcbd3c2e74253249f92ebfbb28204d131e4 Mon Sep 17 00:00:00 2001 From: "R.E. Wolff" Date: Wed, 28 Apr 2021 18:52:43 +0200 Subject: [PATCH 1186/1435] Added init to other programs --- src/st-flash/flash.c | 1 + src/st-info/info.c | 2 ++ src/st-trace/trace.c | 2 ++ src/st-util/gdb-server.c | 2 ++ src/stlink-gui/gui.c | 2 ++ 5 files changed, 9 insertions(+) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index ede0f1179..cbcd00f47 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -61,6 +61,7 @@ int main(int ac, char** av) { } printf("st-flash %s\n", STLINK_VERSION); + init_chipids (ETC_STLINK_DIR); sl = stlink_open_usb(o.log_level, o.connect, (char *)o.serial, o.freq); diff --git a/src/st-info/info.c b/src/st-info/info.c index a6b4e85c6..7e3e47374 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -146,6 +146,8 @@ int main(int ac, char** av) { return(-1); } + init_chipids (ETC_STLINK_DIR); + err = print_data(ac, av); return(err); diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index a02c64701..754a55c72 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -509,6 +509,8 @@ int main(int argc, char **argv) { usage(); return APP_RESULT_INVALID_PARAMS; } + init_chipids (ETC_STLINK_DIR); + DLOG("show_help = %s\n", settings.show_help ? "true" : "false"); DLOG("show_version = %s\n", settings.show_version ? "true" : "false"); diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 6fe8774f7..49daa9799 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -219,6 +219,8 @@ int main(int argc, char** argv) { state.connect_mode = CONNECT_NORMAL; // by default, reset board parse_options(argc, argv, &state); + printf("st-util %s\n", STLINK_VERSION); + init_chipids (ETC_STLINK_DIR); sl = stlink_open_usb(state.logging_level, state.connect_mode, state.serialnumber, state.freq); diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index 03e999b7f..354ca1088 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -894,6 +894,8 @@ int main(int argc, char **argv) { gtk_init(&argc, &argv); + init_chipids (ETC_STLINK_DIR); + gui = g_object_new(STLINK_TYPE_GUI, NULL); stlink_gui_build_ui(gui); stlink_gui_init_dnd(gui); From 7e7bd7403efbcf5761465b003ed17ab09a74202f Mon Sep 17 00:00:00 2001 From: anton Date: Thu, 29 Apr 2021 22:47:18 +0500 Subject: [PATCH 1187/1435] Using localtime instead safe variant in case of compiler below C11 --- src/stlink-lib/logging.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/stlink-lib/logging.c b/src/stlink-lib/logging.c index d7ce13473..817f3d68e 100644 --- a/src/stlink-lib/logging.c +++ b/src/stlink-lib/logging.c @@ -8,6 +8,7 @@ #include #include #include +#define __STDC_WANT_LIB_EXT1__ 1 #include #include "logging.h" @@ -29,10 +30,22 @@ int ugly_log(int level, const char *tag, const char *format, ...) { va_list args; va_start(args, format); time_t mytt = time(NULL); + + struct tm *ptt; +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) // C11 struct tm tt; + ptt = &tt; +# if defined (_WIN32) || defined(__STDC_LIB_EXT1__) + localtime_s(&tt, &mytt); +# else localtime_r(&mytt, &tt); - fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", tt.tm_year + 1900, - tt.tm_mon + 1, tt.tm_mday, tt.tm_hour, tt.tm_min, tt.tm_sec); +# endif +#else + ptt = localtime(&mytt); +#endif + + fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", ptt->tm_year + 1900, + ptt->tm_mon + 1, ptt->tm_mday, ptt->tm_hour, ptt->tm_min, ptt->tm_sec); switch (level) { case UDEBUG: From a06d13552da5884bd994fddf2655db243e3a6a48 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 2 May 2021 20:38:40 +0200 Subject: [PATCH 1188/1435] General Project Update - [doc] Minor spelling fixes. - [doc] Updated tool options in tutorial.md - [doc] Clean-up in tutorial.md - Corrected memory size supplements - [doc] Addtional link on STM32 Clone MCUs --- README.md | 2 +- doc/tutorial.md | 76 ++++++++-------------------------------- src/st-flash/flash.c | 6 ++-- src/st-flash/flash.h | 4 +-- src/st-info/info.c | 12 +++---- src/st-util/gdb-server.c | 4 +-- src/stlink-lib/helper.c | 4 +-- tests/flash.c | 2 +- 8 files changed, 31 insertions(+), 79 deletions(-) diff --git a/README.md b/README.md index 600879580..acc2441f8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Open source version of the STMicroelectronics STlink Tools +# Open source version of the STMicroelectronics STLINK Tools [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/stlink-org/stlink.svg)](https://github.com/stlink-org/stlink/releases/latest) diff --git a/doc/tutorial.md b/doc/tutorial.md index 71af3d45e..f8f0cbb05 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -4,8 +4,9 @@ | Option | Tool | Description | Available
      since | | --------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | -| --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k for the STM32F103C8T6
      to assume 128k of flash being present. This option accepts decimal (128k), octal 0200k, or hex 0x80k values.
      Leaving the multiplier out is equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional
      "k" or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | -| --freq=n[k][m] | st-info
      st-flash
      st-util | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
      This option solely accepts decimal values (5K or 1.8M) with the unit `Hz` being left out. Valid frequencies are:
      `5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K, 1800K, 4000K(4M)`. | v1.6.1 | +| --flash=n[k, M] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k for the STM32F103C8T6
      to assume 128k of flash being present. This option accepts decimal (128k), octal 0200k, or hex 0x80k values.
      Leaving the multiplier out is equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional
      "k" or "M" to multiply the given value by 1k (1024) or 1M (1024 x 1024) respectively.
      One can read arbitary addresses of memory out to a binary file with: `st-flash read out.bin 0x8000000 4096`.
      In this example `4096 bytes` are read and subsequently written to `out.bin`.
      Binary files (here: `in.bin`) are written into flash memory with: `st-flash write in.bin 0x8000000` | v1.4.0 | +| --format | st-flash | Specify file image format to read or write. Valid formats are `binary` and `ihex`. | v1.3.0 +| --freq=n[k, M] | st-info
      st-flash
      st-util | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
      This option solely accepts decimal values with the unit `Hz` being left out. Valid frequencies are:
      `5k, 15k, 25k, 50k, 100k, 125k, 240k, 480k, 950k, 1200k (1.2M), 1800k (1.8M), 4000k (4M)`. | v1.6.1 | | --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
      This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | | --reset | st-flash | Trigger a reset after flashing. The default uses the hardware reset through `NRST` pin.
      A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | | --connect-under-reset | st-info
      st-flash
      st-util | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
      when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | @@ -14,10 +15,19 @@ | --version | st-info
      st-flash
      st-util | Print version information. | v1.3.0 | | --help | st-flash
      st-util | Print list of available commands. | | +### Reading & Writing Option Bytes + +Example to read and write option bytes: + +``` +./st-flash --debug read option_bytes_dump.bin 0x1FFF7800 4 +./st-flash --debug write option_bytes_dump.bin 0x1FFF7800 +``` + ### st-flash: Checksum for binary files When flashing a file, a checksum is calculated for the binary file, both in md5 and the sum algorithm. -The latter is also used by the official ST-Link utility tool from STMicroelectronics as described in the document: [`UM0892 - User manual - STM32 ST-LINK utility software description`](https://www.st.com/resource/en/user_manual/cd00262073-stm32-stlink-utility-software-description-stmicroelectronics.pdf). +The latter is also used by the official ST-LINK utility tool from STMicroelectronics as described in the document: [`UM0892 - User manual STM32 ST-LINK utility software description`](https://www.st.com/resource/en/user_manual/cd00262073-stm32-stlink-utility-software-description-stmicroelectronics.pdf). ### stlink-gui @@ -95,6 +105,7 @@ In the following you find some hints on how to identify your chip and track down - [How to Detect STM32 Fakes](https://www.cnx-software.com/2020/03/22/how-to-detect-stm32-fakes/) - [Confirmation by STMicroelectronics](https://www.mikrocontroller.net/attachment/442839/couterfeit_STM.png) (Marking: 991KA 93 MYS 807) +- [STM32 Clones: The Good, The Bad And The Ugly](https://hackaday.com/2020/10/22/stm32-clones-the-good-the-bad-and-the-ugly/) However it appears that not all counterfeited parts cause problems during operation, but some are known to not even being able to execute a basic "blinky" example binary. Further there can be problems that may not even show up or affect you directly, but somewhen later in time (or maybe never). This demonstrates there is no guarantee for a proper working chip with equal functionality compared to the original. @@ -115,10 +126,6 @@ There are different variants of this message that refer to different issues: - `unknown chip id! 0` --> Target chip (board) is unknown. 1. Microcontroller is in stop/standby mode. 2. The signals `DIO` and `CLK` are reversed on the SWD-Interface. -- `unknown chip id! 0x1a` --> _currently unknown_ -- `unknown chip id! 0x001f` --> _currently unknown_ -- `unknown chip id! 0x3e8` --> _currently unknown_ -- `unknown chip id! 0xa05f0000` --> _currently unknown_ - `unknown chip id! 0x3748` --> A target chip (board) cannot be detected. 1. No target is connected --> In this case `st-info --probe` displays `chip id 0x0748` with STLINK/V2 and `chip id 0x03e8` with STLINK-V3. 2. The chip is connected but has gone into an undefined state of operation where the SWD pins are unresponsive. --> Try to use `--connect-under-reset` while pressing the reset button on the target board. @@ -214,38 +221,6 @@ Your program should now be running, and, if you used one of the blinking examples from libopencm3, the LEDs on the board should be blinking for you. -## Building and flashing a program - -If you want to simply flash binary files to arbitrary sections of -memory, or read arbitary addresses of memory out to a binary file, use -the st-flash tool, as shown below: - -``` -# stlink command to read 4096 from flash into out.bin -$> ./st-flash read out.bin 0x8000000 4096 - -# stlinkv command to write the file in.bin into flash -$> ./st-flash write in.bin 0x8000000 -``` - -It is also possible to write a hexfile which is more convinient: - -``` -$> ./st-flash --format ihex write myapp.hex -``` - -#### - -Of course, you can use this instead of the gdb server, if you prefer. -Just remember to use the “.bin” image, rather than the .elf file. - -``` -# write blink.bin into FLASH -$> [sudo] ./st-flash write fancy_blink.bin 0x08000000 -``` - -Upon reset, the board LEDs should be blinking. - ## Using the gdb server To run the gdb server: @@ -348,26 +323,3 @@ If you would link your executable to `0x08000000` and then do ``` then it would be written to the memory. - -## Writing Option Bytes - -Example to read and write option bytes (currently writing only supported for STM32G0 and STM32L0) - -``` -./st-flash --debug --reset --format binary --flash=128k read option_bytes_dump.bin 0x1FFF7800 4 -./st-flash --debug --reset --format binary --flash=128k write option_bytes_dump.bin 0x1FFF7800 -``` - -# FAQ - -Q: My breakpoints do not work at all or only work once. - -A: Optimizations can cause severe instruction reordering. For example, if you are doing something like `REG = 0x100;' in a loop, the code may be split into two parts: loading 0x100 into some intermediate register and moving that value to REG. When you set up a breakpoint, GDB will hook to the first instruction, which may be called only once if there are enough unused registers. In my experience, -O3 causes that frequently. - -Q: At some point I use GDB command `next', and it hangs. - -A: Sometimes when you will try to use GDB `next` command to skip a loop, it will use a rather inefficient single-stepping way of doing that. Set up a breakpoint manually in that case and do `continue`. - -Q: Load command does not work in GDB. - -A: Some people report XML/EXPAT is not enabled by default when compiling GDB. Memory map parsing thus fail. Use --enable-expat. diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index ede0f1179..a94d78254 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -26,9 +26,9 @@ static void cleanup(int signum) { } static void usage(void) { - puts("command line: ./st-flash [--debug] [--reset] [--connect-under-reset] [--hot-plug] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); - puts("command line: ./st-flash [--debug] [--connect-under-reset] [--hot-plug] [--freq=] [--serial ] erase"); - puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); + puts("command line: ./st-flash [--debug] [--reset] [--connect-under-reset] [--hot-plug] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); + puts("command line: ./st-flash [--debug] [--connect-under-reset] [--hot-plug] [--freq=] [--serial ] erase"); + puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); puts(" , and : Use hex format."); puts(" : Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); puts(" : Can be 'binary' (default) or 'ihex', although must be specified for binary format only."); diff --git a/src/st-flash/flash.h b/src/st-flash/flash.h index cd08db70f..f3d431d65 100644 --- a/src/st-flash/flash.h +++ b/src/st-flash/flash.h @@ -23,9 +23,9 @@ struct flash_opts { enum flash_format format; enum flash_area area; uint32_t val; - size_t flash_size; // --flash=n[k][m] + size_t flash_size; // --flash=n[k, M] int opt; // enable empty tail data drop optimization - int freq; // --freq=n[k][m] frequency of JTAG/SWD + int freq; // --freq=n[k, M] frequency of JTAG/SWD enum connect_type connect; }; diff --git a/src/st-info/info.c b/src/st-info/info.c index a6b4e85c6..a9551cd49 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -8,13 +8,13 @@ static void usage(void) { puts("st-info --version"); - puts("st-info --probe [--connect-under-reset] [--hot-plug] [--freq=]"); + puts("st-info --probe [--connect-under-reset] [--hot-plug] [--freq=]"); puts("st-info --serial"); - puts("st-info --flash [--connect-under-reset] [--hot-plug] [--freq=]"); - puts("st-info --pagesize [--connect-under-reset] [--hot-plug] [--freq=]"); - puts("st-info --sram [--connect-under-reset] [--hot-plug] [--freq=]"); - puts("st-info --chipid [--connect-under-reset] [--hot-plug] [--freq=]"); - puts("st-info --descr [--connect-under-reset] [--hot-plug] [--freq=]"); + puts("st-info --flash [--connect-under-reset] [--hot-plug] [--freq=]"); + puts("st-info --pagesize [--connect-under-reset] [--hot-plug] [--freq=]"); + puts("st-info --sram [--connect-under-reset] [--hot-plug] [--freq=]"); + puts("st-info --chipid [--connect-under-reset] [--hot-plug] [--freq=]"); + puts("st-info --descr [--connect-under-reset] [--hot-plug] [--freq=]"); } static void stlink_print_version(stlink_t *sl) { diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 006a0e3aa..83d8c3746 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -113,7 +113,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { const char * help_str = "%s - usage:\n\n" " -h, --help\t\tPrint this help\n" " -V, --version\t\tPrint the version\n" - " -vXX, --verbose=XX\tSpecify a specific verbosity level (0..99)\n" + " -vXX, --verbose=XX\tSpecify a specific verbosity level (0...99)\n" " -v, --verbose\t\tSpecify generally verbose logging\n" " -p 4242, --listen_port=1234\n" "\t\t\tSet the gdb server listen port. " @@ -125,7 +125,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { "\t\t\tDo not reset board on connection.\n" " -u, --connect-under-reset\n" "\t\t\tConnect to the board before executing any instructions.\n" - " -F 1800K, --freq=1M\n" + " -F 1800k, --freq=1M\n" "\t\t\tSet the frequency of the SWD/JTAG interface.\n" " --semihosting\n" "\t\t\tEnable semihosting support.\n" diff --git a/src/stlink-lib/helper.c b/src/stlink-lib/helper.c index 1f0f71b8d..15e6397bf 100644 --- a/src/stlink-lib/helper.c +++ b/src/stlink-lib/helper.c @@ -19,9 +19,9 @@ int arg_parse_freq(const char *str) { char *tail; int value = (int)strtol(str, &tail, 10); - if ((tail[0] == 'm' || tail[0] == 'M') && tail[1] == '\0') { + if (tail[0] == 'M' && tail[1] == '\0') { value = value*1000; - } else if (((tail[0] != 'k' && tail[0] != 'K') || tail[1] != '\0') && tail[0] != '\0') { + } else if ((tail[0] != 'k' || tail[1] != '\0') && tail[0] != '\0') { return -1; } diff --git a/tests/flash.c b/tests/flash.c index 132066aba..1140566af 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -109,7 +109,7 @@ static struct Test tests[] = { .freq = 5, .format = FLASH_FORMAT_BINARY } }, - { "--debug --freq 15K --reset write test.bin 0x80000000", 0, + { "--debug --freq 15k --reset write test.bin 0x80000000", 0, { .cmd = FLASH_CMD_WRITE, .serial = { 0 }, .filename = "test.bin", From afad37cc7e80efb1dc460bd9edd0b974d1cce449 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 3 May 2021 22:27:27 +0200 Subject: [PATCH 1189/1435] Added Travis CI build test for macOS 10.14 --- .travis.sh | 4 +--- .travis.yml | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/.travis.sh b/.travis.sh index e45cd3609..a156db203 100755 --- a/.travis.sh +++ b/.travis.sh @@ -22,9 +22,7 @@ elif [ "$TRAVIS_JOB_NAME" == "linux-mingw-32" ]; then -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && rm -rf build-mingw-32 && cd - -elif [ "$TRAVIS_OS_NAME" == "linux" ]; then - sudo apt-get update -qq || true - +elif [ "$TRAVIS_OS_NAME" == "osx" ]; then echo "--> Building Debug..." mkdir -p build/Debug && cd build/Debug cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR diff --git a/.travis.yml b/.travis.yml index a733019a1..c54c0c6f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,8 +26,62 @@ jobs: packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] + ### macOS ### + + - os: osx + env: BADGE=osx + osx_image: xcode10.3 + name: macOS 10.14.4 gcc + compiler: gcc + addons: + homebrew: + packages: + - gcc + - libusb + - gtk+3 + + - os: osx + env: BADGE=osx + osx_image: xcode10.3 + name: macOS 10.14.4 gcc 32-bit + compiler: gcc + addons: + homebrew: + packages: + - gcc + - libusb + - gtk+3 + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + + - os: osx + env: BADGE=osx + osx_image: xcode10.3 + name: macOS 10.14.4 clang + compiler: clang + addons: + homebrew: + packages: + - clang + - libusb + - gtk+3 + + - os: osx + env: BADGE=osx + osx_image: xcode10.3 + name: macOS 10.14.4 clang 32-bit + compiler: gcc + addons: + homebrew: + packages: + - clang + - libusb + - gtk+3 + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + script: - git fetch --tags - printenv - cmake --version - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./.travis.sh; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]] || [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis.sh; fi From df69dfa93c77aaeefd1d011f400343c18a836a6b Mon Sep 17 00:00:00 2001 From: Jipeng Zhang Date: Sun, 9 May 2021 23:42:00 -0700 Subject: [PATCH 1190/1435] add chipids of STM32G0B0/G0B1/G0C1/G050/G051/G061 --- src/stlink-lib/chipid.c | 32 +++++++++++++++++++++++++++++--- src/stlink-lib/chipid.h | 2 ++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 187a6d957..46cfc267f 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -630,12 +630,12 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, // 2k (sec 3.2) .sram_size = 0x2000, // 8k (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 3) + .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 5 on RM0444 & table 4 on RM0454) .option_base = STM32_G0_OPTION_BYTES_BASE, .option_size = 4, }, { - // STM32G071/081 (from RM0444) + // STM32G070/071/081 (from RM0454 & RM0444) .chip_id = STLINK_CHIPID_STM32_G0_CAT2, .description = "G070/G071/G081", .flash_type = STLINK_FLASH_TYPE_G0, @@ -643,7 +643,33 @@ static const struct stlink_chipid_params devices[] = { .flash_pagesize = 0x800, // 2k (sec 3.2) .sram_size = 0x9000, // 36k (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) + .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 3 on RM0444 & table 3 on RM0454) + .option_base = STM32_G0_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STM32G0B0/0B1/0C1 (from RM0454 & RM0444) + .chip_id = STLINK_CHIPID_STM32_G0_CAT3, + .description = "G0B0/G0B1/G0C1", + .flash_type = STLINK_FLASH_TYPE_G0, + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (sec 3.2) + .sram_size = 0x24000, // 144k (sec 2.3) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2 on RM0444 & table 2 on RM0454) + .option_base = STM32_G0_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STM32G050/051/061 (from RM0454 & RM0444) + .chip_id = STLINK_CHIPID_STM32_G0_CAT4, + .description = "G050/G051/G061", + .flash_type = STLINK_FLASH_TYPE_G0, + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (sec 3.2) + .sram_size = 0x4800, // 18k (sec 2.3) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 4 on RM0444 & table 4 on RM0454) .option_base = STM32_G0_OPTION_BYTES_BASE, .option_size = 4, }, diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index f790e7899..bb575a287 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -56,11 +56,13 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_H74XXX = 0x450, /* Found on page 3189 in the RM0433*/ STLINK_CHIPID_STM32_F7XXXX = 0x451, STLINK_CHIPID_STM32_F72XXX = 0x452, /* ID found on the NucleoF722ZE board */ + STLINK_CHIPID_STM32_G0_CAT4 = 0x456, /* G050/G051/G061 found on RM0444/RM0454 */ STLINK_CHIPID_STM32_L011 = 0x457, STLINK_CHIPID_STM32_F410 = 0x458, STLINK_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/081 */ STLINK_CHIPID_STM32_F413 = 0x463, STLINK_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/041 */ + STLINK_CHIPID_STM32_G0_CAT3 = 0x467, /* G0B0/G0B1/G0C1 found on RM0444/RM0454 */ STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* See: RM 0440 s46.6.1 "MCU device ID code" */ STLINK_CHIPID_STM32_G4_CAT3 = 0x469, STLINK_CHIPID_STM32_L4RX = 0x470, /* ID found on the STM32L4R9I-DISCO board */ From f02618c53c3d312aad8bb1cf8f0fb369b1af6ba3 Mon Sep 17 00:00:00 2001 From: Kristie Simpson Date: Tue, 11 May 2021 08:45:05 -0600 Subject: [PATCH 1191/1435] Adding option byte info for STM32F411XX --- src/common.c | 2 +- src/st-util/gdb-server.c | 2 +- src/stlink-lib/chipid.c | 6 ++++-- src/stlink-lib/chipid.h | 2 +- src/stlink-lib/flash_loader.c | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/common.c b/src/common.c index 7ddd37032..80190f756 100644 --- a/src/common.c +++ b/src/common.c @@ -2739,7 +2739,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || - (sl->chip_id == STLINK_CHIPID_STM32_F411RE) || + (sl->chip_id == STLINK_CHIPID_STM32_F411XX) || (sl->chip_id == STLINK_CHIPID_STM32_F446) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || (sl->chip_id == STLINK_CHIPID_STM32_F72XXX) || diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 83d8c3746..6b68c8143 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -533,7 +533,7 @@ char* make_memory_map(stlink_t *sl) { if (sl->chip_id == STLINK_CHIPID_STM32_F4 || sl->chip_id == STLINK_CHIPID_STM32_F446 || - sl->chip_id == STLINK_CHIPID_STM32_F411RE) { + sl->chip_id == STLINK_CHIPID_STM32_F411XX) { strcpy(map, memory_map_template_F4); } else if (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) { strcpy(map, memory_map_template_F4_DE); diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 3d4339526..3a653701d 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -136,14 +136,16 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - .chip_id = STLINK_CHIPID_STM32_F411RE, - .description = "stm32f411re", + .chip_id = STLINK_CHIPID_STM32_F411XX, + .description = "STM32F411xC/E", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, .sram_size = 0x20000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800, + .option_base = STM32_F4_OPTION_BYTES_BASE, + .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, }, { diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index f790e7899..23aca5bd2 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -32,7 +32,7 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F1_VL_HIGH = 0x428, STLINK_CHIPID_STM32_L1_CAT2 = 0x429, STLINK_CHIPID_STM32_F1_XL = 0x430, - STLINK_CHIPID_STM32_F411RE = 0x431, + STLINK_CHIPID_STM32_F411XX = 0x431, STLINK_CHIPID_STM32_F37x = 0x432, STLINK_CHIPID_STM32_F4_DE = 0x433, STLINK_CHIPID_STM32_F4_DSI = 0x434, diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 4ec91258b..d492716db 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -260,7 +260,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_F4_HD || sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || sl->chip_id == STLINK_CHIPID_STM32_F410 || - sl->chip_id == STLINK_CHIPID_STM32_F411RE || + sl->chip_id == STLINK_CHIPID_STM32_F411XX || sl->chip_id == STLINK_CHIPID_STM32_F412 || sl->chip_id == STLINK_CHIPID_STM32_F413 || sl->chip_id == STLINK_CHIPID_STM32_F446) { From aa5dd2ccd2413d0fc6ea2f5035ec3d11119239ac Mon Sep 17 00:00:00 2001 From: anton Date: Thu, 13 May 2021 23:06:02 +0500 Subject: [PATCH 1192/1435] Reworked connection under reset --- src/common.c | 17 +++++++++++------ src/st-flash/flash.c | 2 +- src/stlink-lib/usb.c | 11 ++++++++++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/common.c b/src/common.c index 80190f756..556008d4d 100644 --- a/src/common.c +++ b/src/common.c @@ -4902,21 +4902,26 @@ int stlink_target_connect(stlink_t *sl, enum connect_type connect) { uint32_t dhcsr; if (connect == CONNECT_UNDER_RESET) { + stlink_enter_swd_mode(sl); + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); + stlink_force_debug(sl); + // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) usleep(20); - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { - stlink_enter_swd_mode(sl); - } - stlink_force_debug(sl); - // clear S_RESET_ST in DHCSR register stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); - usleep(10000); + + // try to halted core after reset + unsigned timeout = time_ms() + 10; + while (time_ms() < timeout) { + sl->backend->force_debug(sl); + usleep(100); + } // check NRST connection dhcsr = 0; diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index a94d78254..262784e1e 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -68,7 +68,7 @@ int main(int ac, char** av) { if (sl->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { printf("Failed to connect to target\n"); - return(-1); + goto on_error; } if ( o.flash_size != 0u && o.flash_size != sl->flash_size ) { diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 2754db06f..1d26508eb 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1343,11 +1343,20 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, // initialize stlink version (sl->version) stlink_version(sl); - if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { + int mode = stlink_current_mode(sl); + if (mode == STLINK_DEV_DFU_MODE) { // this seems to work, and is unnecessary information for the user. // demoted to debug -- REW DLOG("-- exit_dfu_mode\n"); stlink_exit_dfu_mode(sl); + } else if (mode == STLINK_DEV_DEBUG_MODE && + connect == CONNECT_UNDER_RESET) { + // for the connect under reset only + // OpenOСD says (official documentation is not available) that + // the NRST pin must be pull down before selecting the SWD/JTAG mode + WLOG("-- exit_debug_mode\n"); + stlink_exit_debug_mode(sl); + _stlink_usb_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); } sl->freq = freq; From 616fd437d48044ddffad729f818960cabfd53911 Mon Sep 17 00:00:00 2001 From: anton Date: Fri, 14 May 2021 21:49:17 +0500 Subject: [PATCH 1193/1435] Removed warning that could mislead the user --- src/common.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/common.c b/src/common.c index 556008d4d..3931a8b42 100644 --- a/src/common.c +++ b/src/common.c @@ -1926,11 +1926,7 @@ int stlink_version(stlink_t *sl) { DLOG("swim version = 0x%x\n", sl->version.swim_v); if (sl->version.jtag_v == 0) { - DLOG(" notice: the firmware doesn't support a jtag/swd interface\n"); - } - - if (sl->version.swim_v == 0) { - DLOG(" notice: the firmware doesn't support a swim interface\n"); + WLOG(" warning: stlink doesn't support JTAG/SWD interface\n"); } return (0); From 22fba0249fe51bdcae607101c5b8a637345eeca8 Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 15 May 2021 22:32:57 +0500 Subject: [PATCH 1194/1435] Cleaned up code, made minor fixes --- inc/stlink.h | 31 +++------------- src/common.c | 48 +++++++++++++------------ src/st-flash/flash.c | 14 -------- src/st-info/info.c | 9 ----- src/stlink-gui/gui.c | 13 +------ src/stlink-lib/commands.h | 22 ++++++++++-- src/stlink-lib/sg.c | 8 ++--- src/stlink-lib/usb.c | 76 ++++++++++++++++++--------------------- 8 files changed, 89 insertions(+), 132 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index ec119c145..3bc518c87 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -25,7 +25,7 @@ extern "C" { // #define Q_BUF_LEN 96 #define Q_BUF_LEN (1024 * 100) -// STLINK_DEBUG_RESETSYS, etc: +/* Statuses of core */ enum target_state { TARGET_UNKNOWN = 0, TARGET_RUNNING = 1, @@ -37,38 +37,15 @@ enum target_state { #define STLINK_CORE_RUNNING 0x80 #define STLINK_CORE_HALTED 0x81 -#define STLINK_GET_VERSION 0xF1 -#define STLINK_GET_CURRENT_MODE 0xF5 -#define STLINK_GET_TARGET_VOLTAGE 0xF7 - -#define STLINK_DEBUG_COMMAND 0xF2 -#define STLINK_DFU_COMMAND 0xF3 -#define STLINK_DFU_EXIT 0x07 - -// STLINK_GET_CURRENT_MODE +/* STLINK modes */ #define STLINK_DEV_DFU_MODE 0x00 #define STLINK_DEV_MASS_MODE 0x01 #define STLINK_DEV_DEBUG_MODE 0x02 #define STLINK_DEV_UNKNOWN_MODE -1 -// TODO - possible poor names... -#define STLINK_SWD_ENTER 0x30 -#define STLINK_SWD_READCOREID 0x32 // TBD -#define STLINK_JTAG_WRITEDEBUG_32BIT 0x35 -#define STLINK_JTAG_READDEBUG_32BIT 0x36 -#define STLINK_JTAG_DRIVE_NRST 0x3C - /* NRST pin states */ -#define STLINK_JTAG_DRIVE_NRST_LOW 0x00 -#define STLINK_JTAG_DRIVE_NRST_HIGH 0x01 -#define STLINK_JTAG_DRIVE_NRST_PULSE 0x02 - -#define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43 - -#define STLINK_APIV3_SET_COM_FREQ 0x61 -#define STLINK_APIV3_GET_COM_FREQ 0x62 - -#define STLINK_APIV3_GET_VERSION_EX 0xFB +#define STLINK_DEBUG_APIV2_DRIVE_NRST_LOW 0x00 +#define STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH 0x01 /* Baud rate divisors for SWDCLK */ #define STLINK_SWDCLK_4MHZ_DIVISOR 0 diff --git a/src/common.c b/src/common.c index 3931a8b42..ee91fa487 100644 --- a/src/common.c +++ b/src/common.c @@ -1275,8 +1275,8 @@ static void stop_wdg_in_debug(stlink_t *sl) { case STLINK_FLASH_TYPE_F1_XL: case STLINK_FLASH_TYPE_G4: dbgmcu_cr = STM32F0_DBGMCU_CR; - set = - (1 << STM32F0_DBGMCU_CR_IWDG_STOP) | (1 << STM32F0_DBGMCU_CR_WWDG_STOP); + set = (1 << STM32F0_DBGMCU_CR_IWDG_STOP) | + (1 << STM32F0_DBGMCU_CR_WWDG_STOP); break; case STLINK_FLASH_TYPE_F4: case STLINK_FLASH_TYPE_F7: @@ -1441,13 +1441,14 @@ void stlink_close(stlink_t *sl) { } int stlink_exit_debug_mode(stlink_t *sl) { - int ret; - DLOG("*** stlink_exit_debug_mode ***\n"); - ret = stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); - if (ret == -1) { - return (ret); + if (sl->flash_type != STLINK_FLASH_TYPE_UNKNOWN) { + // stop debugging if the target has been identified + int ret = stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); + if (ret == -1) { + return (ret); + } } return (sl->backend->exit_debug_mode(sl)); @@ -1462,9 +1463,12 @@ int stlink_enter_swd_mode(stlink_t *sl) { int stlink_force_debug(stlink_t *sl) { DLOG("*** stlink_force_debug_mode ***\n"); int res = sl->backend->force_debug(sl); + if (res) { + return (res); + } // Stop the watchdogs in the halted state for suppress target reboot stop_wdg_in_debug(sl); - return (res); + return (0); } int stlink_exit_dfu_mode(stlink_t *sl) { @@ -1540,6 +1544,7 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { if (ret || !(*chip_id)) { *chip_id = 0; + ret = ret?:-1; ELOG("Could not find chip id!\n"); } else { *chip_id = (*chip_id) & 0xfff; @@ -1771,10 +1776,10 @@ int stlink_reset(stlink_t *sl, enum reset_type type) { if (type == RESET_HARD || type == RESET_AUTO) { // hardware target reset if (sl->version.stlink_v > 1) { - stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); + stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) usleep(100); - stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); + stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH); } if (sl->backend->reset(sl)) { return (-1); @@ -4895,24 +4900,21 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char *path, } int stlink_target_connect(stlink_t *sl, enum connect_type connect) { - uint32_t dhcsr; - if (connect == CONNECT_UNDER_RESET) { stlink_enter_swd_mode(sl); - stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); + stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); - stlink_force_debug(sl); + // try to halt the core before reset + // this is useful if the NRST pin is not connected + sl->backend->force_debug(sl); // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) usleep(20); - // clear S_RESET_ST in DHCSR register - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - - stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); + stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH); - // try to halted core after reset + // try to halt the core after reset unsigned timeout = time_ms() + 10; while (time_ms() < timeout) { sl->backend->force_debug(sl); @@ -4920,7 +4922,7 @@ int stlink_target_connect(stlink_t *sl, enum connect_type connect) { } // check NRST connection - dhcsr = 0; + uint32_t dhcsr = 0; stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { WLOG("NRST is not connected\n"); @@ -4930,8 +4932,10 @@ int stlink_target_connect(stlink_t *sl, enum connect_type connect) { stlink_soft_reset(sl, 1 /* halt on reset */); } - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { - stlink_enter_swd_mode(sl); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE && + stlink_enter_swd_mode(sl)) { + printf("Failed to enter SWD mode\n"); + return -1; } if (connect == CONNECT_NORMAL) { diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 262784e1e..be1ef60c2 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -84,20 +84,6 @@ int main(int ac, char** av) { signal(SIGTERM, &cleanup); signal(SIGSEGV, &cleanup); - if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { - if (stlink_exit_dfu_mode(sl)) { - printf("Failed to exit DFU mode\n"); - goto on_error; - } - } - - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { - if (stlink_enter_swd_mode(sl)) { - printf("Failed to enter SWD mode\n"); - goto on_error; - } - } - // core must be halted to use RAM based flashloaders if (stlink_force_debug(sl)) { printf("Failed to halt the core\n"); diff --git a/src/st-info/info.c b/src/st-info/info.c index a9551cd49..7eda5d6ff 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -42,7 +42,6 @@ static void stlink_print_info(stlink_t *sl) { printf(" chipid: 0x%.4x\n", sl->chip_id); params = stlink_chipid_get_params(sl->chip_id); - if (params) { printf(" descr: %s\n", params->description); } } @@ -103,15 +102,8 @@ static int print_data(int ac, char **av) { // open first st-link device sl = stlink_open_usb(0, connect, NULL, freq); - if (sl == NULL) { return(-1); } - sl->verbose = 0; - - 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); } - if (strcmp(av[1], "--serial") == 0) { printf("%s\n", sl->serial); } else if (strcmp(av[1], "--flash") == 0) { @@ -124,7 +116,6 @@ static int print_data(int ac, char **av) { printf("0x%.4x\n", sl->chip_id); } else if (strcmp(av[1], "--descr") == 0) { const struct stlink_chipid_params *params = stlink_chipid_get_params(sl->chip_id); - if (params == NULL) { return(-1); } printf("%s\n", params->description); diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index 03e999b7f..653428735 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -495,24 +495,13 @@ static void connect_button_cb(GtkWidget *widget, gpointer data) { if (gui->sl != NULL) { return; } - gui->sl = stlink_v1_open(0, 1); // try version 1 then version 2 - - if (gui->sl == NULL) { gui->sl = stlink_open_usb(0, 1, NULL, 0); } + gui->sl = stlink_open_usb(0, 1, NULL, 0); if (gui->sl == NULL) { stlink_gui_set_info_error_message(gui, "Failed to connect to STLink."); return; } - // code below taken from flash/main.c, refactoring might be in order - if (stlink_current_mode(gui->sl) == STLINK_DEV_DFU_MODE) { - stlink_exit_dfu_mode(gui->sl); - } - - if (stlink_current_mode(gui->sl) != STLINK_DEV_DEBUG_MODE) { - stlink_enter_swd_mode(gui->sl); - } - stlink_gui_set_connected(gui); } diff --git a/src/stlink-lib/commands.h b/src/stlink-lib/commands.h index dac82b8e6..136adf80e 100644 --- a/src/stlink-lib/commands.h +++ b/src/stlink-lib/commands.h @@ -1,8 +1,17 @@ #ifndef STLINK_COMMANDS_H_ #define STLINK_COMMANDS_H_ +enum stlink_commands { + STLINK_GET_VERSION = 0xF1, + STLINK_DEBUG_COMMAND = 0xF2, + STLINK_DFU_COMMAND = 0xF3, + STLINK_GET_CURRENT_MODE = 0xF5, + STLINK_GET_TARGET_VOLTAGE = 0xF7, + STLINK_GET_VERSION_APIV3 = 0xFB +}; + enum stlink_debug_commands { - STLINK_DEBUG_ENTER_JTAG = 0x00, + STLINK_DEBUG_ENTER_JTAG_RESET = 0x00, STLINK_DEBUG_GETSTATUS = 0x01, STLINK_DEBUG_FORCEDEBUG = 0x02, STLINK_DEBUG_APIV1_RESETSYS = 0x03, @@ -29,11 +38,20 @@ enum stlink_debug_commands { STLINK_DEBUG_APIV2_READDEBUGREG = 0x36, STLINK_DEBUG_APIV2_READALLREGS = 0x3A, STLINK_DEBUG_APIV2_GETLASTRWSTATUS = 0x3B, + STLINK_DEBUG_APIV2_DRIVE_NRST = 0x3C, STLINK_DEBUG_APIV2_GETLASTRWSTATUS2 = 0x3E, STLINK_DEBUG_APIV2_START_TRACE_RX = 0x40, STLINK_DEBUG_APIV2_STOP_TRACE_RX = 0x41, STLINK_DEBUG_APIV2_GET_TRACE_NB = 0x42, - STLINK_DEBUG_ENTER_SWD = 0xa3 + STLINK_DEBUG_APIV2_SWD_SET_FREQ = 0x43, + STLINK_DEBUG_APIV3_SET_COM_FREQ = 0x61, + STLINK_DEBUG_APIV3_GET_COM_FREQ = 0x62, + STLINK_DEBUG_ENTER_SWD = 0xa3, + STLINK_DEBUG_ENTER_JTAG_NO_RESET = 0xa4, +}; + +enum stlink_dfu_commands { + STLINK_DFU_EXIT = 0x07 }; #endif // STLINK_COMMANDS_H_ diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index 07971284f..18792c89f 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -470,7 +470,7 @@ int _stlink_sg_enter_jtag_mode(stlink_t *sl) { DLOG("\n*** stlink_enter_jtag_mode ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_ENTER; - sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_JTAG; + sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_JTAG_RESET; sl->q_len = 0; return(stlink_q(sl)); } @@ -570,7 +570,7 @@ int _stlink_sg_reset(stlink_t *sl) { int _stlink_sg_jtag_reset(stlink_t *sl, int value) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_JTAG_DRIVE_NRST; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV2_DRIVE_NRST; sg->cdb_cmd_blk[2] = (value) ? 0 : 1; sl->q_len = 3; sg->q_addr = 2; @@ -876,7 +876,7 @@ int _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { int _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_JTAG_WRITEDEBUG_32BIT; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV2_WRITEDEBUGREG; // 2-5: addr write_uint32(sg->cdb_cmd_blk + 2, addr); write_uint32(sg->cdb_cmd_blk + 6, data); @@ -888,7 +888,7 @@ int _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { int _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); - sg->cdb_cmd_blk[1] = STLINK_JTAG_READDEBUG_32BIT; + sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV2_READDEBUGREG; // 2-5: addr write_uint32(sg->cdb_cmd_blk + 2, addr); sl->q_len = 8; diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 1d26508eb..bbdc2c27b 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -158,30 +158,24 @@ int _stlink_usb_version(stlink_t *sl) { 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); - - cmd[i++] = STLINK_GET_VERSION; - - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); - - if (size == -1) { - printf("[!] send_recv STLINK_GET_VERSION\n"); - return((int)size); - } + uint32_t rep_len; + int i; - /* STLINK-V3 requires a specific command */ if (sl->version.stlink_v == 3) { + // STLINK-V3 version is determined by another command rep_len = 12; i = fill_command(sl, SG_DXFER_FROM_DEV, 16); - cmd[i++] = STLINK_APIV3_GET_VERSION_EX; - - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + cmd[i++] = STLINK_GET_VERSION_APIV3; + } else { + rep_len = 6; + i = fill_command(sl, SG_DXFER_FROM_DEV, 6); + cmd[i++] = STLINK_GET_VERSION; + } - if (size != (ssize_t)rep_len) { - printf("[!] send_recv STLINK_APIV3_GET_VERSION_EX\n"); - return((int)size); - } + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + if (size != (ssize_t)rep_len) { + printf("[!] send_recv STLINK_GET_VERSION\n"); + return((int)size); } return(0); @@ -225,12 +219,12 @@ int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_JTAG_READDEBUG_32BIT; + cmd[i++] = STLINK_DEBUG_APIV2_READDEBUGREG; write_uint32(&cmd[i], addr); size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { - printf("[!] send_recv STLINK_JTAG_READDEBUG_32BIT\n"); + printf("[!] send_recv STLINK_DEBUG_APIV2_READDEBUGREG\n"); return((int)size); } @@ -248,13 +242,13 @@ int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_JTAG_WRITEDEBUG_32BIT; + cmd[i++] = STLINK_DEBUG_APIV2_WRITEDEBUGREG; write_uint32(&cmd[i], addr); write_uint32(&cmd[i + 4], data); size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { - printf("[!] send_recv STLINK_JTAG_WRITEDEBUG_32BIT\n"); + printf("[!] send_recv STLINK_DEBUG_APIV2_WRITEDEBUGREG\n"); return((int)size); } @@ -543,12 +537,12 @@ int _stlink_usb_jtag_reset(stlink_t * sl, int value) { int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_JTAG_DRIVE_NRST; + cmd[i++] = STLINK_DEBUG_APIV2_DRIVE_NRST; cmd[i++] = value; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { - printf("[!] send_recv STLINK_JTAG_DRIVE_NRST\n"); + printf("[!] send_recv STLINK_DEBUG_APIV2_DRIVE_NRST\n"); return((int)size); } @@ -675,7 +669,7 @@ int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { i = fill_command(sl, SG_DXFER_FROM_DEV, 16); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_APIV3_GET_COM_FREQ; + cmd[i++] = STLINK_DEBUG_APIV3_GET_COM_FREQ; cmd[i++] = 0; // SWD mode size = send_recv(slu, 1, cmd, slu->cmd_len, data, 52); @@ -694,13 +688,13 @@ int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { // Set to zero all the next entries for (i = speeds_size; i < STLINK_V3_MAX_FREQ_NB; i++) map[i] = 0; - if (!clk_freq) clk_freq = 1800; // set default frequency + if (!clk_freq) clk_freq = 1000; // set default frequency speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), clk_freq); i = fill_command(sl, SG_DXFER_FROM_DEV, 16); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_APIV3_SET_COM_FREQ; + cmd[i++] = STLINK_DEBUG_APIV3_SET_COM_FREQ; cmd[i++] = 0; // SWD mode cmd[i++] = 0; cmd[i++] = (uint8_t)((map[speed_index] >> 0) & 0xFF); @@ -1180,10 +1174,9 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, int config; sl = calloc(1, sizeof(stlink_t)); - slu = calloc(1, sizeof(struct stlink_libusb)); - if (sl == NULL) { goto on_malloc_error; } + slu = calloc(1, sizeof(struct stlink_libusb)); if (slu == NULL) { goto on_malloc_error; } ugly_init(verbose); @@ -1345,18 +1338,20 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, int mode = stlink_current_mode(sl); if (mode == STLINK_DEV_DFU_MODE) { - // this seems to work, and is unnecessary information for the user. - // demoted to debug -- REW DLOG("-- exit_dfu_mode\n"); - stlink_exit_dfu_mode(sl); - } else if (mode == STLINK_DEV_DEBUG_MODE && - connect == CONNECT_UNDER_RESET) { + _stlink_usb_exit_dfu_mode(sl); + } + + if (connect == CONNECT_UNDER_RESET) { // for the connect under reset only // OpenOСD says (official documentation is not available) that // the NRST pin must be pull down before selecting the SWD/JTAG mode - WLOG("-- exit_debug_mode\n"); - stlink_exit_debug_mode(sl); - _stlink_usb_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); + if (mode == STLINK_DEV_DEBUG_MODE) { + DLOG("-- exit_debug_mode\n"); + _stlink_usb_exit_dfu_mode(sl); + } + + _stlink_usb_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); } sl->freq = freq; @@ -1364,7 +1359,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, // should be done at this speed too // set the stlink clock speed (default is 1800kHz) DLOG("JTAG/SWD freq set to %d\n", freq); - stlink_set_swdclk(sl, freq); + _stlink_usb_set_swdclk(sl, freq); stlink_target_connect(sl, connect); return(sl); @@ -1374,13 +1369,10 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, return(NULL); on_error: - if (slu->libusb_ctx) { libusb_exit(slu->libusb_ctx); } on_malloc_error: - if (sl != NULL) { free(sl); } - if (slu != NULL) { free(slu); } return(NULL); From ebba0f35e2ca971b929d8bd19484ec30cc54eabe Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 16 May 2021 18:26:52 +0200 Subject: [PATCH 1195/1435] General Project Update - [doc] Updated steps for release procedure - [doc] Removed outdated lists of supported devices - [doc] Updated list of supported OS - [doc] Updated version requirements - Cleanup for libusb installation routine on Windows - Updated list of contributors - Updated CHANGELOG.md - Updated README.md --- CHANGELOG.md | 7 ++ CMakeLists.txt | 2 +- README.md | 4 +- cmake/modules/Findlibusb.cmake | 22 ------ contributors.txt | 3 +- doc/devices_boards.md | 64 +----------------- doc/release.md | 8 ++- doc/version_support.md | 119 +++++++++++++++++++-------------- 8 files changed, 86 insertions(+), 143 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b003d97e..b43d58da7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,15 @@ Release date: 2021-xx-xx +This release drops support for some older operating systems. Check project README for details. +Updated system requirements: Raised minimum version for `cmake` to 3.7.2. + Features: +- Support for writing option bytes on STM32F0/F1/F3 ([#346](https://github.com/stlink-org/stlink/pull/346), [#458](https://github.com/stlink-org/stlink/pull/458), [#808](https://github.com/stlink-org/stlink/pull/808), [#1084](https://github.com/stlink-org/stlink/pull/1084), [#1112](https://github.com/stlink-org/stlink/pull/1112)) +- Added chip-IDs for STM32G0B0/G0B1/G0C1/G050/G051/G061 ([#1140](https://github.com/stlink-org/stlink/pull/1140)) +- Added option byte info for STM32F411XX ([#1141](https://github.com/stlink-org/stlink/pull/1141)) + Updates & changes: - Added instructions for bug-reports and feature-requests to contribution guidelines ([#906](https://github.com/stlink-org/stlink/pull/906)) diff --git a/CMakeLists.txt b/CMakeLists.txt index 064aa06d5..4bd76ebfb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # General cmake settings ### -cmake_minimum_required(VERSION 3.4.2) +cmake_minimum_required(VERSION 3.7.2) cmake_policy(SET CMP0042 NEW) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) diff --git a/README.md b/README.md index acc2441f8..0b124d21d 100644 --- a/README.md +++ b/README.md @@ -53,9 +53,9 @@ The STlink toolset includes: ## Supported operating systems and hardware combinations -Currently known working combinations of programmers and targets are listed in [devices_boards.md](doc/devices_boards.md). +Currently known working MCU targets are listed in [devices_boards.md](doc/devices_boards.md). -Supported operating systems are listed in [version_support.md](doc/version_support.md). +A list of supported operating can be found in [version_support.md](doc/version_support.md). ## Tutorial & HOWTO diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index 257c682ce..d861bdd5f 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -54,28 +54,6 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to endif () if (WIN32 AND NOT EXISTS "/etc/debian_version") # Skip this for Debian... - FIND_PATH( - LIBUSB_INCLUDE_DIR NAMES libusb.h - HINTS /usr /usr/local /opt - PATH_SUFFIXES libusb-1.0 - ) - - if (MINGW OR MSYS) - set(LIBUSB_NAME usb-1.0) - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW${ARCH}/static - ) - else (MSVC) - set(LIBUSB_NAME libusb-1.0.lib) - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS${ARCH}/dll - ) - endif () - endif () - - if (NOT LIBUSB_FOUND) # Preparations for installing libusb library set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) diff --git a/contributors.txt b/contributors.txt index 88f1f0c89..e7fc0f601 100644 --- a/contributors.txt +++ b/contributors.txt @@ -40,7 +40,7 @@ Fabien Chouteau [Fabien-Chouteau] Florian Hars Friedrich Beckmann Gabriel Górski [Glaeqen] -Geoffrey Brown +Geoffrey Brown [geoffreymbrown] George Talusan [gtalusan] Georg von Zengen Giuseppe Barba @@ -100,6 +100,7 @@ Peter Torelli [petertorelli] Peter Zotov Petteri Aimonen Piotr Haber +[RafaelLeeImg] Rene Hopf [rene-dev] Robin Kreis Roger Wolff [rewolff] diff --git a/doc/devices_boards.md b/doc/devices_boards.md index df4b5ed29..6548bc734 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -1,9 +1,7 @@ -# Boards supported by the STlink toolset +# MCUs supported by the STlink toolset The following devices are supported by the stlink toolset. -All Boards are expected to work with ST-LINK/V2 programmers. - **STM32F0 / ARM Cortex M0 / Core-ID: 0x0bb11477 (STM32F0_CORE_ID)** | Chip-ID | Product-Code | @@ -20,14 +18,6 @@ All Boards are expected to work with ST-LINK/V2 programmers. | 0x448 | STM32F0**72**xx | | 0x442 | STM32F0**9**xxx | -Tested boards [incl. STLINK programmers]: - -- Nucleo-F030R8 [v2-1] -- Nucleo-F072RB [v2-1] -- Nucleo-F091RC [v2-1] -- Nucleo-32 [v2-1] -- STM32F0-Discovery [v2] -- STM320518-EVAL **STM32F1 / ARM Cortex M3 / Core-ID: 0x1ba01477 (STM32F1_CORE_ID)** @@ -50,11 +40,8 @@ Tested boards [incl. STLINK programmers]: | 0x428 | High density Value | xC xD xE | F100 | | | | | | 0x430 | XL-Density | xF xG | | F101 | | F103 | | -Tested boards [incl. STLINK programmers]: +Tested non-official ST boards [incl. STLINK programmers]: -- STM32VL-Discovery (STM32F100RBT6) with STLINK/V1 [v1], [v2] -- STM32F103-Bluepill: C8Tx & R8xx [v2] -- Nucleo-F103RB [v2-1] - HY-STM32 (STM32F103VETx) [v1, v2] - DecaWave EVB1000 (STM32F105RCTx) [v1, v2] @@ -98,15 +85,6 @@ Tested boards [incl. STLINK programmers]: | 0x446 | _N/A_ | xD xE | | F302 | F303 | | | 0x446 | _N/A_ | - | | | | F398 | -Tested boards [incl. STLINK programmers]: - -- Nucleo-F302K8 [v2-1] -- Nucleo-F303K8 [v2-1] -- Nucleo-F303RE [v2-1] -- Nucleo-F334R8 [v2-1] -- STM32F303-Discovery [v2] -- STM32F3348-Discovery [v2-1] - **STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3c_CORE_ID)** | Product-Code | Chip-ID | STLINK
      Programmer | Boards | @@ -134,16 +112,6 @@ Tested boards [incl. STLINK programmers]: | 0x463 | STM32F4**13**xx | | 0x463 | STM32F4**23**xx | -Tested boards [incl. STLINK programmers]: - -- Nucleo-F401RE [v2-1] -- Nucleo-F411RE [v2-1] -- STM32F407-Discovery [v2] -- STM32F411E-Discovery with gyro, audio [v2] -- STM32F413H-Discovery [v2-1] -- STM32F429I-Discovery with LCD [v2] -- STM32F439VIT6-Discovery [v2] (reseated MCU) - **STM32F7 / ARM Cortex M7F / Core-ID: 0x5ba02477 (STM32F7_CORE_ID)** | Chip-ID | Product-Code | @@ -155,23 +123,12 @@ Tested boards [incl. STLINK programmers]: | 0x451 | STM32F7**6**xxx | | 0x451 | STM32F7**7**xxx | -Tested boards [incl. STLINK programmers]: - -- Nucleo-F722ZE [v2-1] -- Nucleo-F746ZG [v2-1] -- STM32F756NGHx evaluation board [v2-1] -- STM32F769I-Discovery [v2-1] - **STM32H7 / ARM Cortex M7F / Core-ID: 0x6ba02477 (STM32H7_CORE_ID)** | Chip-ID | Product-Code | | ------- | -------------- | | 0x450 | STM32H74x/H75x | -Tested boards [incl. STLINK programmers]: - -- Nucleo-H745I-Q [v3] - **STM32G0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32G0_CORE_ID)** | Chip-ID | Product-Code | @@ -203,10 +160,6 @@ Tested boards [incl. STLINK programmers]: | 0x447 | STM32L0**7**xxx | | 0x447 | STM32L0**8**xxx | -Tested boards [incl. STLINK programmers]: - -- Nucleo-L053R8 [v2-1] - **STM32L1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32L1_CORE_ID)** | Chip-ID | Product-Code | @@ -221,11 +174,6 @@ Tested boards [incl. STLINK programmers]: | 0x436 | STM32L1xxx**D** | | 0x437 | STM32L1xxx**E** | -Tested boards [incl. STLINK programmers]: - -- Nucleo-L152RE [v2-1] -- STM32L152C-Discovery [v2] - **STM32L4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32L4_CORE_ID)** | Chip-ID | Product-Code | @@ -245,14 +193,6 @@ Tested boards [incl. STLINK programmers]: | 0x471 | STM32L4**P5**xx | | 0x471 | STM32L4**Q5**xx | -Tested boards [incl. STLINK programmers]: - -- Nucleo-L432KC [v2-1] -- Nucleo-L452RE [v2-1] -- Nucleo-L476RG [v2-1] -- Nucleo-L496ZG [v2-1] -- STM32L4R9I-Discovery [v2-1] - **STM32W / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32W_CORE_ID)** | Chip-ID | Product-Code | diff --git a/doc/release.md b/doc/release.md index a67fcd743..6321e8ab2 100644 --- a/doc/release.md +++ b/doc/release.md @@ -6,6 +6,8 @@ This document describes the necessary steps for developers to create a release: 1. Update `CHANGELOG.md`, `cmake/packaging/deb/changelog` & `cmake/packaging/rpm/changelog` 2. Update `.version` with semantic version: `x.x.x` 3. Update `README.md` with semantic version `x.x.x` in commits badge -4. Create and push git tag and commits `git tag x.x.x` -5. Create binary packages (.rpm / .deb / .zip) with `make package && sh ./cmake/packaging/windows/generate_binaries.sh` -6. Upload packages to the [release page](https://github.com/stlink-org/stlink/releases) of this project +4. Merge `develop` into `master` +5. Create and push git tag and commits `git tag x.x.x` +6. Create binary packages (.rpm / .deb / .zip) with `make package && sh ./cmake/packaging/windows/generate_binaries.sh` +7. Upload packages to the [release page](https://github.com/stlink-org/stlink/releases) of this project +8. Merge `master` into `develop` diff --git a/doc/version_support.md b/doc/version_support.md index 5d2cdd375..6aafc8112 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -1,13 +1,11 @@ -_Source:_ pkgs.org - [libusb](https://pkgs.org/search/?q=libusb); [cmake](https://pkgs.org/search/?q=cmake); [gtk](https://pkgs.org/search/?q=gtk) (as of Apr 2020) +_Source:_ pkgs.org - [libusb](https://pkgs.org/search/?q=libusb); [cmake](https://pkgs.org/search/?q=cmake); [gtk](https://pkgs.org/search/?q=gtk) (as of May 2021) ## Supported Operating Systems ### Microsoft Windows -On Windows users should ensure that cmake 3.17.0 is installed.
      -Up on compiling c-make will check **automatically**, whether `libusb` 1.0.20 or later is present.
      -If this is not the case, the installation routine will download the latest version (1.0.23 at the time of writing).
      -Thus no user interaction regarding libusb is necessary. +On Windows users should ensure that cmake 3.17.0 or any later version is installed.
      +Up on compiling c-make will **automatically** download and install the latest compatible version of `libusb` (1.0.23 at the time of writing). - Windows 10 - Windows 8.1 @@ -23,55 +21,72 @@ NOTE: In order to use a STLINK/V1 programmer on macOS, versions 10.14 or 10.15 a ### Linux-/Unix-based: -| Operating System | libusb
      version | cmake
      version | gtk-3
      version | Notes | -| -------------------------------- | ----------------------- | ------------------ | ----------------------------------------- | ----------------------------------------------------------------------------- | -| Alpine Edge | 1.0.23 | 3.17.0 | 3.99.0
      gtk+3.0 | | -| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | 3.24.18
      libgtk+3 | | -| Arch Linux | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | -| Fedora Rawhide | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | -| KaOS | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | | -| OpenMandriva Cooker | 1.0.23 | 3.17.0 | 3.24.18
      libgtk+3.0
      lib64gtk+3.0 | | -| PCLinuxOS | 1.0.23
      lib64usb1.0 | 3.17.0 | 3.24.18
      lib64gtk+3.0 | | -| Slackware Current | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3 | | -| Solus | 1.0.23 | 3.16.5 | 3.24.16
      libgtk-3 | | -| Debian Sid | 1.0.23 | 3.16.3 | 3.24.18
      libgtk-3 | | -| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | 3.24.13
      libgtk+3.0
      lib64gtk+3.0 | | -| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | 3.24.17
      libgtk-3 | | -| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | 3.24.16
      gtk3 | | -| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.13
      gtk+3.0 | | -| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | 3.24.12
      libgtk-3 | | -| Mageia Cauldron | 1.0.22 | 3.17.0 | 3.24.18
      libgtk+3.0
      lib64gtk+3.0 | | -| NetBSD 9.0 | 1.0.22 | 3.16.1 | 3.24.12
      gtk+3 | | -| NetBSD 8.1 | 1.0.22 | 3.16.1 | 3.24.12
      gtk+3 | | -| NetBSD 7.2 | 1.0.22 | 3.16.1 | _N/A_ | | -| Alpine 3.10 | 1.0.22 | 3.14.5 | 3.24.8
      gtk+3.0 | | -| Fedora 31 | 1.0.22 | 3.14.5 | 3.24.12
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | -| Mageia 7.1 | 1.0.22 | 3.14.3 | 3.24.8
      libgtk+3.0
      lib64gtk+3.0 | | -| Fedora 30 | 1.0.22 | 3.14.2 | 3.24.8
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | -| Debian 10 (Buster) | 1.0.22 | 3.13.4 | 3.24.5
      libgtk-3 | | -| Alpine 3.9 | 1.0.22 | 3.13.0 | 3.24.1
      gtk+3.0 | | -| CentOS 8 | 1.0.22 | 3.11.4 | 3.22.30
      gtk3 | named `libusbx`, but
      `libusb`-codebase is used | -| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | 3.24.14
      gtk3 | | -| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | 3.22.30
      gtk3 | | -| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | 3.22.30
      libgtk-3 | | -| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | 3.22.11
      libgtk-3 | | -| Slackware 14.2 | 1.0.20 | 3.5.2 | 3.18.9
      gtk+3 | | -| Ubuntu 16.04 LTS (Xenial Xerus) | 1.0.20 | 3.5.1 | 3.18.9
      libgtk-3 | | -| OpenMandriva Lx 3.0x | 1.0.20 | **3.4.2** | 3.18.9
      libgtk+3.0
      lib64gtk+3.0 | | -| FreeBSD 13 | **1.0.16 - 1.0.18** | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-13.0r358841
      LIBUSB_API_VERSION 0x01000102
      (integrated) | -| FreeBSD 12 | **1.0.16 - 1.0.18** | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-13.0r358841
      LIBUSB_API_VERSION 0x01000102
      (integrated) | -| FreeBSD 11 | **1.0.16 - 1.0.18** | 3.15.5 | 3.24.10
      gtk3 | linux_libusb-13.0r358841
      LIBUSB_API_VERSION 0x01000102
      (integrated) | +| Operating System | libusb | cmake | gtk-3 | Notes | +| ------------------------- | ------------------ | --------- | ----------- | ----------------------------- | +| Arch Linux | 1.0.24 | 3.20.2 | 3.24.29 | | +| Fedora Rawhide [x64] | 1.0.24 (`libusbx`) | 3.20.2 | 3.24.29 | | +| KaOS [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | +| Mageia Cauldron | 1.0.24 | 3.20.2 | 3.24.29 | | +| OpenMandriva Cooker | 1.0.24 | 3.20.2 | 3.24.29 | | +| OpenMandriva Rolling | 1.0.24 | 3.20.2 | 3.24.29 | | +| PCLinuxOS [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | +| Slackware Current | 1.0.24 | 3.20.2 | 3.24.28 | | +| Solus [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | +| openSUSE Tumbleweed [x64] | 1.0.24 | 3.20.1 | 3.24.29 | | +| ALT Linux Sisyphus | 1.0.24 | 3.19.7 | 3.24.29 | | +| Fedora 34 [x64] | 1.0.24 (`libusbx`) | 3.19.7 | 3.24.28 | | +| NetBSD 9.x | 1.0.24 | 3.19.7 | 3.24.27 | | +| NetBSD 8.x | 1.0.24 | 3.19.7 | 3.24.27 | | +| OpenMandriva Lx 4.2 | 1.0.24 | 3.19.3 | 3.24.24 | | +| Mageia 8 | 1.0.24 | 3.19.2 | 3.24.24 | | +| Alpine 3.13 | 1.0.24 | 3.18.4 | 3.24.23 | | +| Debian Sid | 1.0.24 | 3.18.4 | 3.24.24 | | +| Debian 11 (Bullseye) | 1.0.24 | 3.18.4 | 3.24.24 | | +| Ubuntu 21.04 (Hirsute) | 1.0.24 | 3.18.4 | 3.24.25 | | +| Fedora 33 [x64] | 1.0.23 (`libusbx`) | 3.18.3 | 3.24.23 | | +| CentOS 8 Stream [x64] | 1.0.23 (`libusbx`) | 3.18.2 | **3.22.30** | | +| Alpine 3.12 | 1.0.23 | 3.17.2 | 3.24.22 | | +| openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.17.0 | 3.24.20 | | +| openSUSE Leap 15.2 [x64] | 1.0.**21** | 3.17.0 | 3.24.**14** | | +| Adélie 1.0 | 1.0.23 | 3.16.4 | 3.24.23 | | +| Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.16.3 | 3.24.**18** | | +| ALT Linux P9 | 1.0.**22** | 3.16.3 | 3.24.**11** | | +| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.**13** | | +| Mageia 7.1 | 1.0.**22** | 3.14.3 | 3.24.**8** | | +| Debian 10 (Buster) | 1.0.**22** | 3.13.4 | 3.24.**5** | | +| AlmaLinux 8 | 1.0.23 (`libusbx`) | 3.11.4 | 3.24.32 | | +| CentOS 8 [x64] | 1.0.23 (`libusbx`) | 3.11.4 | **3.22.30** | | +| Ubuntu 18.04 LTS (Bionic) | 1.0.**21** | 3.10.2 | **3.22.30** | | +| Debian 9 (Stretch) | 1.0.**21** | **3.7.2** | **3.22.11** | | +| | | | | | +| FreeBSD 13.x | 1.0.**16 - 18** | 3.20.2 | 3.24.27 | LIBUSB_API_VERSION 0x01000102 | +| FreeBSD 12.x | 1.0.**16 - 18** | 3.19.6 | 3.24.27 | LIBUSB_API_VERSION 0x01000102 | +| FreeBSD 11.x | 1.0.**16 - 18** | 3.15.5 | 3.24.27 | LIBUSB_API_VERSION 0x01000102 | -## Unsupported Operating Systems (as of Release v1.6.1) +## Unsupported Operating Systems (as of Release v1.7.1) -| Operating System | libusb
      version | cmake
      version | End of
      OS-Support | Notes | -| ------------------------------ | ------------------- | ------------------ | ---------------------- | --------------------------------------------------- | -| CentOS 7 | 1.0.21 | **2.8.12.2** | | named `libusbx`, but
      `libusb`-codebase is used | -| Debian 8 (Jessie) | 1.0.19 | **3.0.2** | Jun 2020 | -| Ubuntu 14.04 LTS (Trusty Tahr) | 1.0.17 | **2.8.12.2** | Apr 2019 | -| CentOS 6 | 1.0.**9** | **2.8.12.2** | Dec 2020 | named `libusbx`, but
      `libusb`-codebase is used | -| Slackware 14.1 | 1.0.**9** | **2.8.12** | | -| Slackware 14.0 | 1.0.**9** | **2.8.8** | | +Systems with highlighted versions remain compatible with this toolset. + +| Operating System | libusb | cmake | End of
      OS-Support | +| ------------------------- | ---------------------- | ---------- | ---------------------- | +| Fedora 32 [x64] | **1.0.23** (`libusbx`) | **3.17.0** | May 2021 | +| Ubuntu 20.10 (Groovy) | **1.0.23** | **3.16.3** | Jul 2021 | +| NetBSD 7.x | **1.0.22** | **3.16.1** | Jun 2020 | +| Alpine 3.10 | **1.0.22** | **3.14.5** | May 2021 | +| Fedora 31 [x64] | **1.0.22** (`libusbx`) | **3.14.5** | Nov 2020 | +| Ubuntu 19.10 (Eoan) | **1.0.23** | **3.13.4** | Jul 2020 | +| Fedora 30 | **1.0.22** (`libusbx`) | **3.14.2** | May 2020 | +| Alpine 3.9 | **1.0.22** | **3.13.0** | Jan 2021 | +| openSUSE Leap 15.1 [x64] | **1.0.21** | **3.10.2** | Feb 2021 | +| Slackware 14.2 | 1.0.20 | 3.5.2 | | +| Ubuntu 16.04 LTS (Xenial) | 1.0.20 | 3.5.1 | Apr 2021 | +| OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | | +| Debian 8 (Jessie) | 1.0.19 | 3.0.2 | Jun 2020 | +| CentOS 7 [x64] | 1.0.21 (`libusbx`) | 2.8.12.2 | | +| Ubuntu 14.04 LTS (Trusty) | 1.0.17 | 2.8.12.2 | Apr 2019 | +| CentOS 6 | 1.0.9 (`libusbx`) | 2.8.12.2 | Dec 2020 | +| Slackware 14.1 | 1.0.9 | 2.8.12 | | +| Slackware 14.0 | 1.0.9 | 2.8.8 | | _All other operating systems which are not listed are unsupported._ From 03ad4a434d4d6496a05885ddce9568b5884a2c2d Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 17 May 2021 00:20:54 +0500 Subject: [PATCH 1196/1435] Added checking the command execution status --- inc/stlink.h | 13 +++ src/common.c | 23 +++-- src/stlink-lib/usb.c | 211 ++++++++++++++++++++++--------------------- 3 files changed, 132 insertions(+), 115 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 3bc518c87..69a4799f5 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -83,6 +83,19 @@ enum target_state { #define STLINK_F_HAS_DPBANKSEL (1 << 8) #define STLINK_F_HAS_RW8_512BYTES (1 << 9) +/* Error code */ +#define STLINK_DEBUG_ERR_OK 0x80 +#define STLINK_DEBUG_ERR_FAULT 0x81 +#define STLINK_DEBUG_ERR_AP_WAIT 0x10 +#define STLINK_DEBUG_ERR_AP_FAULT 0x11 +#define STLINK_DEBUG_ERR_AP_ERROR 0x12 +#define STLINK_DEBUG_ERR_DP_WAIT 0x14 +#define STLINK_DEBUG_ERR_DP_FAULT 0x15 +#define STLINK_DEBUG_ERR_DP_ERROR 0x16 + +#define CMD_NO_RETRY 0 +#define CMD_USE_RETRY 3 + #define C_BUF_LEN 32 enum stlink_flash_type { diff --git a/src/common.c b/src/common.c index ee91fa487..661ee34ec 100644 --- a/src/common.c +++ b/src/common.c @@ -1443,12 +1443,10 @@ void stlink_close(stlink_t *sl) { int stlink_exit_debug_mode(stlink_t *sl) { DLOG("*** stlink_exit_debug_mode ***\n"); - if (sl->flash_type != STLINK_FLASH_TYPE_UNKNOWN) { + if (sl->flash_type != STLINK_FLASH_TYPE_UNKNOWN && + sl->core_stat != TARGET_RESET) { // stop debugging if the target has been identified - int ret = stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); - if (ret == -1) { - return (ret); - } + stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); } return (sl->backend->exit_debug_mode(sl)); @@ -1684,7 +1682,7 @@ int stlink_load_device_params(stlink_t *sl) { } int stlink_jtag_reset(stlink_t *sl, int value) { - DLOG("*** stlink_jtag_reset ***\n"); + DLOG("*** stlink_jtag_reset %d ***\n", value); return (sl->backend->jtag_reset(sl, value)); } @@ -1768,6 +1766,8 @@ int stlink_reset(stlink_t *sl, enum reset_type type) { DLOG("*** stlink_reset ***\n"); + sl->core_stat = TARGET_RESET; + if (type == RESET_AUTO) { // clear S_RESET_ST in DHCSR register for reset state detection stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); @@ -1781,9 +1781,7 @@ int stlink_reset(stlink_t *sl, enum reset_type type) { usleep(100); stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH); } - if (sl->backend->reset(sl)) { - return (-1); - } + sl->backend->reset(sl); usleep(10000); } @@ -1793,8 +1791,8 @@ int stlink_reset(stlink_t *sl, enum reset_type type) { * DDI0337E, p. 10-4, Debug Halting Control and Status Register */ dhcsr = 0; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + int res = stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0 && !res) { // reset not done yet // try reset through AIRCR so that NRST does not need to be connected @@ -1808,8 +1806,9 @@ int stlink_reset(stlink_t *sl, enum reset_type type) { while (time_ms() < timeout) { dhcsr = STLINK_REG_DHCSR_S_RESET_ST; stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { return (0); + } } return (-1); diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index bbdc2c27b..5e17189c6 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -84,50 +84,80 @@ void _stlink_usb_close(stlink_t* sl) { } ssize_t send_recv(struct stlink_libusb* handle, int terminate, - unsigned char* txbuf, size_t txsize, unsigned char* rxbuf, size_t rxsize) { + unsigned char* txbuf, size_t txsize, unsigned char* rxbuf, + size_t rxsize, bool check_error, int retry_cnt) { // Note: txbuf and rxbuf can point to the same area - int res = 0; - int t; + int res, t, retry = 0; + int cmd = read_uint16(txbuf, (handle->protocoll == 1)?15:0); - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, (int)txsize, &res, 3000); - - if (t) { - printf("[!] send_recv send request failed: %s\n", libusb_error_name(t)); - return(-1); - } else if ((size_t)res != txsize) { - printf("[!] send_recv send request wrote %u bytes (instead of %u).\n", - (unsigned int)res, (unsigned int)txsize); - } - - if (rxsize != 0) { - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int)rxsize, &res, 3000); + while (1) { + res = 0; + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, (int)txsize, &res, 3000); if (t) { - printf("[!] send_recv read reply failed: %s\n", libusb_error_name(t)); + ELOG("[!] send_recv send request failed: %s (command 0x%02X)\n", libusb_error_name(t), cmd); return(-1); + } else if ((size_t)res != txsize) { + ELOG("[!] send_recv send request wrote %u bytes, instead of %u (command 0x%02X)\n", + (unsigned int)res, (unsigned int)txsize, cmd); } - } - if ((handle->protocoll == 1) && terminate) { - // read the SG reply - unsigned char sg_buf[13]; - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, sg_buf, 13, &res, 3000); + if (rxsize != 0) { + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int)rxsize, &res, 3000); - if (t) { - printf("[!] send_recv read storage failed: %s\n", libusb_error_name(t)); - return(-1); + if (t) { + ELOG("[!] send_recv read reply failed: %s (command 0x%02X)\n", libusb_error_name(t), cmd); + return(-1); + } + + /* Checking the command execution status stored in the first byte of the response */ + if (handle->protocoll != 1 && check_error && + rxbuf[0] != STLINK_DEBUG_ERR_OK) { + switch(rxbuf[0]) { + case STLINK_DEBUG_ERR_AP_WAIT: + case STLINK_DEBUG_ERR_DP_WAIT: + if (retry < retry_cnt) { + unsigned int delay_us = (1<sg_transfer_idx++; - } + if ((handle->protocoll == 1) && terminate) { + // read the SG reply + unsigned char sg_buf[13]; + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, sg_buf, 13, &res, 3000); + + if (t) { + ELOG("[!] send_recv read storage failed: %s (command 0x%02X)\n", libusb_error_name(t), cmd); + return(-1); + } + + // The STLink doesn't seem to evaluate the sequence number. + handle->sg_transfer_idx++; + } - return(res); + return(res); + } } static inline int send_only(struct stlink_libusb* handle, int terminate, unsigned char* txbuf, size_t txsize) { - return((int)send_recv(handle, terminate, txbuf, txsize, NULL, 0)); + return((int)send_recv(handle, terminate, txbuf, txsize, NULL, 0, false, CMD_NO_RETRY)); } @@ -149,7 +179,6 @@ static int fill_command(stlink_t * sl, enum SCSI_Generic_Direction dir, uint32_t cmd[i++] = 0; // logical unit cmd[i++] = 0xa; // command length } - return(i); } @@ -172,9 +201,8 @@ int _stlink_usb_version(stlink_t *sl) { cmd[i++] = STLINK_GET_VERSION; } - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, false, CMD_USE_RETRY); if (size != (ssize_t)rep_len) { - printf("[!] send_recv STLINK_GET_VERSION\n"); return((int)size); } @@ -193,10 +221,9 @@ int32_t _stlink_usb_target_voltage(stlink_t *sl) { cmd[i++] = STLINK_GET_TARGET_VOLTAGE; - size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, false, CMD_NO_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_GET_TARGET_VOLTAGE\n"); + if (size < 0) { return(-1); } else if (size != 8) { printf("[!] wrong length STLINK_GET_TARGET_VOLTAGE\n"); @@ -221,10 +248,9 @@ int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_READDEBUGREG; write_uint32(&cmd[i], addr); - size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, true, CMD_USE_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_APIV2_READDEBUGREG\n"); + if (size < 0) { return((int)size); } @@ -245,10 +271,9 @@ int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { cmd[i++] = STLINK_DEBUG_APIV2_WRITEDEBUGREG; write_uint32(&cmd[i], addr); write_uint32(&cmd[i + 4], data); - size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, true, CMD_USE_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_APIV2_WRITEDEBUGREG\n"); + if (size < 0) { return((int)size); } @@ -269,10 +294,10 @@ int _stlink_usb_get_rw_status(stlink_t *sl) { if (sl->version.flags & STLINK_F_HAS_GETLASTRWSTATUS2) { cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS2; - ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 12); + ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 12, true, CMD_NO_RETRY); } else { cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS; - ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 2); + ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 2, true, CMD_NO_RETRY); } if (ret < 0) { return(-1); } @@ -334,10 +359,9 @@ int _stlink_usb_current_mode(stlink_t * sl) { 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); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, false, CMD_NO_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_GET_CURRENT_MODE\n"); + if (size < 0) { return(-1); } @@ -362,10 +386,9 @@ int _stlink_usb_core_id(stlink_t * sl) { offset = 4; } - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_NO_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_READCOREID\n"); + if (size < 0) { return(-1); } @@ -408,10 +431,9 @@ int _stlink_usb_status(stlink_t * sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_GETSTATUS; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, false, CMD_NO_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_GETSTATUS\n"); + if (size < 0) { return((int)size); } @@ -450,10 +472,9 @@ int _stlink_usb_force_debug(stlink_t *sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_FORCEDEBUG; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_FORCEDEBUG\n"); + if (size < 0) { return((int)size); } @@ -472,10 +493,9 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { // select correct API-Version for entering SWD mode: V1 API (0x20) or V2 API (0x30). cmd[i++] = sl->version.jtag_api == STLINK_JTAG_API_V1 ? STLINK_DEBUG_APIV1_ENTER : STLINK_DEBUG_APIV2_ENTER; cmd[i++] = STLINK_DEBUG_ENTER_SWD; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_ENTER\n"); + if (size < 0) { return((int)size); } @@ -518,10 +538,9 @@ int _stlink_usb_reset(stlink_t * sl) { cmd[i++] = STLINK_DEBUG_APIV2_RESETSYS; } - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_RESETSYS\n"); + if (size < 0) { return((int)size); } @@ -539,10 +558,9 @@ int _stlink_usb_jtag_reset(stlink_t * sl, int value) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_DRIVE_NRST; cmd[i++] = value; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_APIV2_DRIVE_NRST\n"); + if (size < 0) { return((int)size); } @@ -571,10 +589,9 @@ int _stlink_usb_step(stlink_t* sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_STEPCORE; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_STEPCORE\n"); + if (size < 0) { return((int)size); } @@ -607,10 +624,9 @@ int _stlink_usb_run(stlink_t* sl, enum run_type type) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_RUNCORE; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_RUNCORE\n"); + if (size < 0) { return((int)size); } @@ -655,10 +671,9 @@ int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { cmd[i++] = STLINK_DEBUG_APIV2_SWD_SET_FREQ; cmd[i++] = clk_divisor & 0xFF; cmd[i++] = (clk_divisor >> 8) & 0xFF; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_APIV2_SWD_SET_FREQ\n"); + if (size < 0) { return((int)size); } @@ -671,10 +686,9 @@ int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV3_GET_COM_FREQ; cmd[i++] = 0; // SWD mode - size = send_recv(slu, 1, cmd, slu->cmd_len, data, 52); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, 52, true, CMD_NO_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_APIV3_GET_COM_FREQ\n"); + if (size < 0) { return((int)size); } @@ -702,10 +716,9 @@ int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { cmd[i++] = (uint8_t)((map[speed_index] >> 16) & 0xFF); cmd[i++] = (uint8_t)((map[speed_index] >> 24) & 0xFF); - size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8, true, CMD_NO_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_APIV3_SET_COM_FREQ\n"); + if (size < 0) { return((int)size); } @@ -747,10 +760,9 @@ int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { cmd[i++] = STLINK_DEBUG_READMEM_32BIT; write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); - size = send_recv(slu, 1, cmd, slu->cmd_len, data, len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, len, false, CMD_NO_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_READMEM_32BIT\n"); + if (size < 0) { return((int)size); } @@ -776,10 +788,9 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { cmd[i++] = STLINK_DEBUG_APIV2_READALLREGS; } - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_NO_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_READALLREGS\n"); + if (size < 0) { return((int)size); } @@ -827,10 +838,9 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { } cmd[i++] = (uint8_t)r_idx; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_READREG\n"); + if (size < 0) { return((int)size); } @@ -994,10 +1004,9 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { cmd[i++] = idx; write_uint32(&cmd[i], reg); - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - if (size == -1) { - printf("[!] send_recv STLINK_DEBUG_WRITEREG\n"); + if (size < 0) { return((int)size); } @@ -1020,10 +1029,9 @@ int _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { write_uint16(&cmd[i + 0], 2 * STLINK_TRACE_BUF_LEN); write_uint32(&cmd[i + 2], frequency); - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_NO_RETRY); - if (size == -1) { - printf("[!] send_only STLINK_DEBUG_APIV2_START_TRACE_RX\n"); + if (size < 0) { return((int)size); } @@ -1044,10 +1052,9 @@ int _stlink_usb_disable_trace(stlink_t* sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_STOP_TRACE_RX; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_NO_RETRY); - if (size == -1) { - printf("[!] send_only STLINK_DEBUG_APIV2_STOP_TRACE_RX\n"); + if (size < 0) { return((int)size); } @@ -1066,14 +1073,12 @@ int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_GET_TRACE_NB; - ssize_t send_size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + ssize_t send_size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, false, CMD_NO_RETRY); - if (send_size == -1) { - printf("[!] send_recv STLINK_DEBUG_APIV2_GET_TRACE_NB\n"); + if (send_size < 0) { return((int)send_size); - } - if (send_size != 2) { - printf("[!] send_recv STLINK_DEBUG_APIV2_GET_TRACE_NB %d\n", (int)send_size); + } else if (send_size != 2) { + ELOG("STLINK_DEBUG_APIV2_GET_TRACE_NB reply size %d\n", (int)send_size); return -1; } From 620b52995667e5c39e8260e579e76b8d6d1a4fc5 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 16 May 2021 22:27:14 +0200 Subject: [PATCH 1197/1435] Aligned naming scheme for chip-ID files --- config/chips/F04x.chip | 4 +- config/chips/F07x.chip | 4 +- config/chips/{F09X.chip => F09x.chip} | 6 +- config/chips/F0xx small.chip | 4 +- config/chips/F0xx.chip | 4 +- ...1xx XL-density.chip => F1 XL-density.chip} | 6 +- ...ty line.chip => F1 connectivity line.chip} | 6 +- ...High-density.chip => F1 high-density.chip} | 6 +- ...ensity device.chip => F1 low-density.chip} | 6 +- ...um-density.chip => F1 medium-density.chip} | 6 +- ...e.chip => F1 value line high-density.chip} | 6 +- ...1xx Value Line.chip => F1 value line.chip} | 6 +- config/chips/{F2xx.chip => F2.chip} | 6 +- config/chips/F303 high density.chip | 4 +- config/chips/F334 medium density.chip | 4 +- config/chips/{F3xx.chip => F37x.chip} | 6 +- config/chips/F3xx small.chip | 4 +- config/chips/F410.chip | 4 +- .../chips/{stm32f411re.chip => F411xx.chip} | 6 +- config/chips/F412.chip | 4 +- config/chips/F413.chip | 4 +- config/chips/F42x_F43x.chip | 4 +- config/chips/F446.chip | 4 +- config/chips/F46x_F47x.chip | 4 +- ...ncy).chip => F4xx dynamic efficiency.chip} | 6 +- ...x (low power).chip => F4xx low power.chip} | 6 +- config/chips/F4xx.chip | 4 +- config/chips/F72x_F73x.chip | 4 +- config/chips/F76xxx.chip | 4 +- config/chips/F7xx.chip | 4 +- config/chips/G030_G031_G041.chip | 4 +- config/chips/G070_G071_G081.chip | 4 +- .../{G4 Category-2.chip => G4 cat2.chip} | 6 +- .../{G4 Category-3.chip => G4 cat3.chip} | 6 +- config/chips/H72x_H73x.chip | 4 +- config/chips/H74x_H75x.chip | 4 +- config/chips/H7Ax_H7Bx.chip | 4 +- config/chips/L011.chip | 4 +- config/chips/L0x3.chip | 4 +- .../{L0xx Category 2.chip => L0xx cat2.chip} | 6 +- .../{L0xx Category 5.chip => L0xx cat5.chip} | 6 +- config/chips/L152RE.chip | 4 +- .../chips/{L1xx Cat.2.chip => L1xx cat2.chip} | 6 +- ...gh-density.chip => L1xx high-density.chip} | 6 +- ...-density.chip => L1xx medium-density.chip} | 6 +- ...ity.chip => L1xx medium-plus-density.chip} | 6 +- config/chips/L41x.chip | 4 +- config/chips/L43x_L44x.chip | 4 +- .../chips/{L45x_46x.chip => L45x_L46x.chip} | 6 +- config/chips/L496x_L4A6x.chip | 4 +- config/chips/L4Rx.chip | 4 +- config/chips/L4xx.chip | 4 +- config/chips/WB55.chip | 4 +- config/chips/unknown device.chip | 4 +- config/udev/rules.d/49-stlinkv1.rules | 2 +- config/udev/rules.d/49-stlinkv2-1.rules | 2 +- config/udev/rules.d/49-stlinkv2.rules | 2 +- doc/tutorial.md | 26 +-- src/common.c | 56 +++--- src/st-util/gdb-server.c | 10 +- src/stlink-lib/chipid.c | 177 +++++++++--------- src/stlink-lib/chipid.h | 66 ++++--- src/stlink-lib/flash_loader.c | 42 ++--- 63 files changed, 319 insertions(+), 324 deletions(-) rename config/chips/{F09X.chip => F09x.chip} (69%) rename config/chips/{F1xx XL-density.chip => F1 XL-density.chip} (62%) rename config/chips/{F1 Connectivity line.chip => F1 connectivity line.chip} (59%) rename config/chips/{F1xx High-density.chip => F1 high-density.chip} (60%) rename config/chips/{F1 Low-density device.chip => F1 low-density.chip} (58%) rename config/chips/{F1xx Medium-density.chip => F1 medium-density.chip} (59%) rename config/chips/{F1xx High-density value line.chip => F1 value line high-density.chip} (54%) rename config/chips/{F1xx Value Line.chip => F1 value line.chip} (62%) rename config/chips/{F2xx.chip => F2.chip} (71%) rename config/chips/{F3xx.chip => F37x.chip} (69%) rename config/chips/{stm32f411re.chip => F411xx.chip} (65%) rename config/chips/{F4xx (Dynamic Efficency).chip => F4xx dynamic efficiency.chip} (57%) rename config/chips/{F4xx (low power).chip => F4xx low power.chip} (61%) rename config/chips/{G4 Category-2.chip => G4 cat2.chip} (64%) rename config/chips/{G4 Category-3.chip => G4 cat3.chip} (64%) rename config/chips/{L0xx Category 2.chip => L0xx cat2.chip} (63%) rename config/chips/{L0xx Category 5.chip => L0xx cat5.chip} (63%) rename config/chips/{L1xx Cat.2.chip => L1xx cat2.chip} (65%) rename config/chips/{L1xx High-density.chip => L1xx high-density.chip} (62%) rename config/chips/{L1xx Medium-density.chip => L1xx medium-density.chip} (59%) rename config/chips/{L1xx Medium-Plus-density.chip => L1xx medium-plus-density.chip} (57%) rename config/chips/{L45x_46x.chip => L45x_L46x.chip} (66%) diff --git a/config/chips/F04x.chip b/config/chips/F04x.chip index 72db26f8c..059ae5bc6 100644 --- a/config/chips/F04x.chip +++ b/config/chips/F04x.chip @@ -1,8 +1,8 @@ -# Chipid file for F04x +# Chip-ID file for F04x # chip_id 445 description F04x -flash_type 1 +flash_type 1 flash_pagesize 400 sram_size 1800 bootrom_base 1fffec00 diff --git a/config/chips/F07x.chip b/config/chips/F07x.chip index cfedfa76f..ba839baed 100644 --- a/config/chips/F07x.chip +++ b/config/chips/F07x.chip @@ -1,8 +1,8 @@ -# Chipid file for F07x +# Chip-ID file for F07x # chip_id 448 description F07x -flash_type 1 +flash_type 1 flash_pagesize 800 sram_size 4000 bootrom_base 1fffc800 diff --git a/config/chips/F09X.chip b/config/chips/F09x.chip similarity index 69% rename from config/chips/F09X.chip rename to config/chips/F09x.chip index a622cf2f5..727fc1fa4 100644 --- a/config/chips/F09X.chip +++ b/config/chips/F09x.chip @@ -1,8 +1,8 @@ -# Chipid file for F09X +# Chip-ID file for F09x # chip_id 442 -description F09X -flash_type 1 +description F09x +flash_type 1 flash_pagesize 800 sram_size 8000 bootrom_base 1fffd800 diff --git a/config/chips/F0xx small.chip b/config/chips/F0xx small.chip index 65aea58ac..efa51c284 100644 --- a/config/chips/F0xx small.chip +++ b/config/chips/F0xx small.chip @@ -1,8 +1,8 @@ -# Chipid file for F0xx small +# Chip-ID file for F0xx small # chip_id 444 description F0xx small -flash_type 1 +flash_type 1 flash_pagesize 400 sram_size 1000 bootrom_base 1fffec00 diff --git a/config/chips/F0xx.chip b/config/chips/F0xx.chip index 5a5529412..9c0f60bd9 100644 --- a/config/chips/F0xx.chip +++ b/config/chips/F0xx.chip @@ -1,8 +1,8 @@ -# Chipid file for F0xx +# Chip-ID file for F0xx # chip_id 440 description F0xx -flash_type 1 +flash_type 1 flash_pagesize 400 sram_size 2000 bootrom_base 1fffec00 diff --git a/config/chips/F1xx XL-density.chip b/config/chips/F1 XL-density.chip similarity index 62% rename from config/chips/F1xx XL-density.chip rename to config/chips/F1 XL-density.chip index a7125a429..70cdfd3bb 100644 --- a/config/chips/F1xx XL-density.chip +++ b/config/chips/F1 XL-density.chip @@ -1,8 +1,8 @@ -# Chipid file for F1xx XL-density +# Chip-ID file for F1 XL-density # chip_id 430 -description F1xx XL-density -flash_type 2 +description F1 XL-density +flash_type 2 flash_pagesize 800 sram_size 18000 bootrom_base 1fffe000 diff --git a/config/chips/F1 Connectivity line.chip b/config/chips/F1 connectivity line.chip similarity index 59% rename from config/chips/F1 Connectivity line.chip rename to config/chips/F1 connectivity line.chip index 676fd1945..14678112d 100644 --- a/config/chips/F1 Connectivity line.chip +++ b/config/chips/F1 connectivity line.chip @@ -1,8 +1,8 @@ -# Chipid file for F1 Connectivity line +# Chip-ID file for F1 connectivity line # chip_id 418 -description F1 Connectivity line -flash_type 1 +description F1 connectivity line +flash_type 1 flash_pagesize 800 sram_size 10000 bootrom_base 1fffb000 diff --git a/config/chips/F1xx High-density.chip b/config/chips/F1 high-density.chip similarity index 60% rename from config/chips/F1xx High-density.chip rename to config/chips/F1 high-density.chip index ed02e691a..3d4cff724 100644 --- a/config/chips/F1xx High-density.chip +++ b/config/chips/F1 high-density.chip @@ -1,8 +1,8 @@ -# Chipid file for F1xx High-density +# Chip-ID file for F1 high-density # chip_id 414 -description F1xx High-density -flash_type 1 +description F1 high-density +flash_type 1 flash_pagesize 800 sram_size 10000 bootrom_base 1ffff000 diff --git a/config/chips/F1 Low-density device.chip b/config/chips/F1 low-density.chip similarity index 58% rename from config/chips/F1 Low-density device.chip rename to config/chips/F1 low-density.chip index dcb5e279e..9905ce405 100644 --- a/config/chips/F1 Low-density device.chip +++ b/config/chips/F1 low-density.chip @@ -1,8 +1,8 @@ -# Chipid file for F1 Low-density device +# Chip-ID file for F1 low-density # chip_id 412 -description F1 Low-density device -flash_type 1 +description F1 low-density +flash_type 1 flash_pagesize 400 sram_size 2800 bootrom_base 1ffff000 diff --git a/config/chips/F1xx Medium-density.chip b/config/chips/F1 medium-density.chip similarity index 59% rename from config/chips/F1xx Medium-density.chip rename to config/chips/F1 medium-density.chip index 32266b74e..00af4f18d 100644 --- a/config/chips/F1xx Medium-density.chip +++ b/config/chips/F1 medium-density.chip @@ -1,8 +1,8 @@ -# Chipid file for F1xx Medium-density +# Chip-ID file for F1 medium-density # chip_id 410 -description F1xx Medium-density -flash_type 1 +description F1 medium-density +flash_type 1 flash_pagesize 400 sram_size 5000 bootrom_base 1ffff000 diff --git a/config/chips/F1xx High-density value line.chip b/config/chips/F1 value line high-density.chip similarity index 54% rename from config/chips/F1xx High-density value line.chip rename to config/chips/F1 value line high-density.chip index f30014122..c076e284c 100644 --- a/config/chips/F1xx High-density value line.chip +++ b/config/chips/F1 value line high-density.chip @@ -1,8 +1,8 @@ -# Chipid file for F1xx High-density value line +# Chip-ID file for F1 value line high-density # chip_id 428 -description F1xx High-density value line -flash_type 1 +description F1 value line high-density +flash_type 1 flash_pagesize 800 sram_size 8000 bootrom_base 1ffff000 diff --git a/config/chips/F1xx Value Line.chip b/config/chips/F1 value line.chip similarity index 62% rename from config/chips/F1xx Value Line.chip rename to config/chips/F1 value line.chip index 929b95496..8356357b0 100644 --- a/config/chips/F1xx Value Line.chip +++ b/config/chips/F1 value line.chip @@ -1,8 +1,8 @@ -# Chipid file for F1xx Value Line +# Chip-ID file for F1 value line # chip_id 420 -description F1xx Value Line -flash_type 1 +description F1 value line +flash_type 1 flash_pagesize 400 sram_size 2000 bootrom_base 1ffff000 diff --git a/config/chips/F2xx.chip b/config/chips/F2.chip similarity index 71% rename from config/chips/F2xx.chip rename to config/chips/F2.chip index b31be46f3..8830363d2 100644 --- a/config/chips/F2xx.chip +++ b/config/chips/F2.chip @@ -1,8 +1,8 @@ -# Chipid file for F2xx +# Chip-ID file for F2 # chip_id 411 -description F2xx -flash_type 3 +description F2 +flash_type 3 flash_pagesize 20000 sram_size 20000 bootrom_base 1fff0000 diff --git a/config/chips/F303 high density.chip b/config/chips/F303 high density.chip index 716c37c1e..e8b57ee24 100644 --- a/config/chips/F303 high density.chip +++ b/config/chips/F303 high density.chip @@ -1,8 +1,8 @@ -# Chipid file for F303 high density +# Chip-ID file for F303 high density # chip_id 446 description F303 high density -flash_type 1 +flash_type 1 flash_pagesize 800 sram_size 10000 bootrom_base 1fffd800 diff --git a/config/chips/F334 medium density.chip b/config/chips/F334 medium density.chip index 424f1063c..460e22a67 100644 --- a/config/chips/F334 medium density.chip +++ b/config/chips/F334 medium density.chip @@ -1,8 +1,8 @@ -# Chipid file for F334 medium density +# Chip-ID file for F334 medium density # chip_id 438 description F334 medium density -flash_type 1 +flash_type 1 flash_pagesize 800 sram_size 3000 bootrom_base 1fffd800 diff --git a/config/chips/F3xx.chip b/config/chips/F37x.chip similarity index 69% rename from config/chips/F3xx.chip rename to config/chips/F37x.chip index 4195f9007..424209a03 100644 --- a/config/chips/F3xx.chip +++ b/config/chips/F37x.chip @@ -1,8 +1,8 @@ -# Chipid file for F3xx +# Chip-ID file for F37x # chip_id 432 -description F3xx -flash_type 1 +description F37x +flash_type 1 flash_pagesize 800 sram_size a000 bootrom_base 1ffff000 diff --git a/config/chips/F3xx small.chip b/config/chips/F3xx small.chip index 7f6f5159c..91722905c 100644 --- a/config/chips/F3xx small.chip +++ b/config/chips/F3xx small.chip @@ -1,8 +1,8 @@ -# Chipid file for F3xx small +# Chip-ID file for F3xx small # chip_id 439 description F3xx small -flash_type 1 +flash_type 1 flash_pagesize 800 sram_size a000 bootrom_base 1fffd800 diff --git a/config/chips/F410.chip b/config/chips/F410.chip index 3fb1b3d2a..53f01c669 100644 --- a/config/chips/F410.chip +++ b/config/chips/F410.chip @@ -1,8 +1,8 @@ -# Chipid file for F410 +# Chip-ID file for F410 # chip_id 458 description F410 -flash_type 3 +flash_type 3 flash_pagesize 4000 sram_size 8000 bootrom_base 1fff0000 diff --git a/config/chips/stm32f411re.chip b/config/chips/F411xx.chip similarity index 65% rename from config/chips/stm32f411re.chip rename to config/chips/F411xx.chip index ef889c139..26390d0e6 100644 --- a/config/chips/stm32f411re.chip +++ b/config/chips/F411xx.chip @@ -1,8 +1,8 @@ -# Chipid file for stm32f411re +# Chip-ID file for F411xx # chip_id 431 -description stm32f411re -flash_type 3 +description F411xx +flash_type 3 flash_pagesize 4000 sram_size 20000 bootrom_base 1fff0000 diff --git a/config/chips/F412.chip b/config/chips/F412.chip index 138e6c273..e78b81ee1 100644 --- a/config/chips/F412.chip +++ b/config/chips/F412.chip @@ -1,8 +1,8 @@ -# Chipid file for F412 +# Chip-ID file for F412 # chip_id 441 description F412 -flash_type 3 +flash_type 3 flash_pagesize 4000 sram_size 40000 bootrom_base 1fff0000 diff --git a/config/chips/F413.chip b/config/chips/F413.chip index 305a808dc..4ea974f2c 100644 --- a/config/chips/F413.chip +++ b/config/chips/F413.chip @@ -1,8 +1,8 @@ -# Chipid file for F413 +# Chip-ID file for F413 # chip_id 463 description F413 -flash_type 3 +flash_type 3 flash_pagesize 4000 sram_size 50000 bootrom_base 1fff0000 diff --git a/config/chips/F42x_F43x.chip b/config/chips/F42x_F43x.chip index c279a0e1d..2073486cf 100644 --- a/config/chips/F42x_F43x.chip +++ b/config/chips/F42x_F43x.chip @@ -1,8 +1,8 @@ -# Chipid file for F42x/F43x +# Chip-ID file for F42x/F43x # chip_id 419 description F42x/F43x -flash_type 3 +flash_type 3 flash_pagesize 4000 sram_size 40000 bootrom_base 1fff0000 diff --git a/config/chips/F446.chip b/config/chips/F446.chip index 6f372c067..7d2ded465 100644 --- a/config/chips/F446.chip +++ b/config/chips/F446.chip @@ -1,8 +1,8 @@ -# Chipid file for F446 +# Chip-ID file for F446 # chip_id 421 description F446 -flash_type 3 +flash_type 3 flash_pagesize 20000 sram_size 20000 bootrom_base 1fff0000 diff --git a/config/chips/F46x_F47x.chip b/config/chips/F46x_F47x.chip index 6d03bbea2..75e1ea045 100644 --- a/config/chips/F46x_F47x.chip +++ b/config/chips/F46x_F47x.chip @@ -1,8 +1,8 @@ -# Chipid file for F46x/F47x +# Chip-ID file for F46x/F47x # chip_id 434 description F46x/F47x -flash_type 3 +flash_type 3 flash_pagesize 4000 sram_size 40000 bootrom_base 1fff0000 diff --git a/config/chips/F4xx (Dynamic Efficency).chip b/config/chips/F4xx dynamic efficiency.chip similarity index 57% rename from config/chips/F4xx (Dynamic Efficency).chip rename to config/chips/F4xx dynamic efficiency.chip index fda012826..33bfa23c2 100644 --- a/config/chips/F4xx (Dynamic Efficency).chip +++ b/config/chips/F4xx dynamic efficiency.chip @@ -1,8 +1,8 @@ -# Chipid file for F4xx (Dynamic Efficency) +# Chip-ID file for F4xx dynamic efficiency # chip_id 433 -description F4xx (Dynamic Efficency) -flash_type 3 +description F4xx dynamic efficiency +flash_type 3 flash_pagesize 4000 sram_size 18000 bootrom_base 1fff0000 diff --git a/config/chips/F4xx (low power).chip b/config/chips/F4xx low power.chip similarity index 61% rename from config/chips/F4xx (low power).chip rename to config/chips/F4xx low power.chip index db9e99ffa..f52595d5d 100644 --- a/config/chips/F4xx (low power).chip +++ b/config/chips/F4xx low power.chip @@ -1,8 +1,8 @@ -# Chipid file for F4xx (low power) +# Chip-ID file for F4xx low power # chip_id 423 -description F4xx (low power) -flash_type 3 +description F4xx low power +flash_type 3 flash_pagesize 4000 sram_size 10000 bootrom_base 1fff0000 diff --git a/config/chips/F4xx.chip b/config/chips/F4xx.chip index a9dd110c5..70f298b79 100644 --- a/config/chips/F4xx.chip +++ b/config/chips/F4xx.chip @@ -1,8 +1,8 @@ -# Chipid file for F4xx +# Chip-ID file for F4xx # chip_id 413 description F4xx -flash_type 3 +flash_type 3 flash_pagesize 4000 sram_size 30000 bootrom_base 1fff0000 diff --git a/config/chips/F72x_F73x.chip b/config/chips/F72x_F73x.chip index a673b04f0..ba275bb0b 100644 --- a/config/chips/F72x_F73x.chip +++ b/config/chips/F72x_F73x.chip @@ -1,8 +1,8 @@ -# Chipid file for F72x/F73x +# Chip-ID file for F72x/F73x # chip_id 452 description F72x/F73x -flash_type 3 +flash_type 3 flash_pagesize 800 sram_size 40000 bootrom_base 100000 diff --git a/config/chips/F76xxx.chip b/config/chips/F76xxx.chip index c8f9ee108..7f8cfdaf0 100644 --- a/config/chips/F76xxx.chip +++ b/config/chips/F76xxx.chip @@ -1,8 +1,8 @@ -# Chipid file for F76xxx +# Chip-ID file for F76xxx # chip_id 451 description F76xxx -flash_type 4 +flash_type 4 flash_pagesize 800 sram_size 80000 bootrom_base 200000 diff --git a/config/chips/F7xx.chip b/config/chips/F7xx.chip index c704ce2e2..c031b5f4a 100644 --- a/config/chips/F7xx.chip +++ b/config/chips/F7xx.chip @@ -1,8 +1,8 @@ -# Chipid file for F7xx +# Chip-ID file for F7xx # chip_id 449 description F7xx -flash_type 3 +flash_type 3 flash_pagesize 800 sram_size 50000 bootrom_base 100000 diff --git a/config/chips/G030_G031_G041.chip b/config/chips/G030_G031_G041.chip index c6553904e..a1c42f58f 100644 --- a/config/chips/G030_G031_G041.chip +++ b/config/chips/G030_G031_G041.chip @@ -1,8 +1,8 @@ -# Chipid file for G030/G031/G041 +# Chip-ID file for G030/G031/G041 # chip_id 466 description G030/G031/G041 -flash_type 7 +flash_type 7 flash_pagesize 800 sram_size 2000 bootrom_base 1fff0000 diff --git a/config/chips/G070_G071_G081.chip b/config/chips/G070_G071_G081.chip index ab57bbd27..58eb16b16 100644 --- a/config/chips/G070_G071_G081.chip +++ b/config/chips/G070_G071_G081.chip @@ -1,8 +1,8 @@ -# Chipid file for G070/G071/G081 +# Chip-ID file for G070/G071/G081 # chip_id 460 description G070/G071/G081 -flash_type 7 +flash_type 7 flash_pagesize 800 sram_size 9000 bootrom_base 1fff0000 diff --git a/config/chips/G4 Category-2.chip b/config/chips/G4 cat2.chip similarity index 64% rename from config/chips/G4 Category-2.chip rename to config/chips/G4 cat2.chip index 400152cd6..309cbb83f 100644 --- a/config/chips/G4 Category-2.chip +++ b/config/chips/G4 cat2.chip @@ -1,8 +1,8 @@ -# Chipid file for G4 Category-2 +# Chip-ID file for G4 cat2 # chip_id 468 -description G4 Category-2 -flash_type 8 +description G4 cat2 +flash_type 8 flash_pagesize 800 sram_size 8000 bootrom_base 1fff0000 diff --git a/config/chips/G4 Category-3.chip b/config/chips/G4 cat3.chip similarity index 64% rename from config/chips/G4 Category-3.chip rename to config/chips/G4 cat3.chip index f8ea053f7..357522b31 100644 --- a/config/chips/G4 Category-3.chip +++ b/config/chips/G4 cat3.chip @@ -1,8 +1,8 @@ -# Chipid file for G4 Category-3 +# Chip-ID file for G4 cat3 # chip_id 469 -description G4 Category-3 -flash_type 8 +description G4 cat3 +flash_type 8 flash_pagesize 800 sram_size 18000 bootrom_base 1fff0000 diff --git a/config/chips/H72x_H73x.chip b/config/chips/H72x_H73x.chip index e63c855c8..43c8ae67b 100644 --- a/config/chips/H72x_H73x.chip +++ b/config/chips/H72x_H73x.chip @@ -1,8 +1,8 @@ -# Chipid file for H72x/H73x +# Chip-ID file for H72x/H73x # chip_id 483 description H72x/H73x -flash_type a +flash_type a flash_pagesize 20000 sram_size 20000 bootrom_base 1ff00000 diff --git a/config/chips/H74x_H75x.chip b/config/chips/H74x_H75x.chip index 24e85ff66..c4d374e60 100644 --- a/config/chips/H74x_H75x.chip +++ b/config/chips/H74x_H75x.chip @@ -1,8 +1,8 @@ -# Chipid file for H74x/H75x +# Chip-ID file for H74x/H75x # chip_id 450 description H74x/H75x -flash_type a +flash_type a flash_pagesize 20000 sram_size 20000 bootrom_base 1ff00000 diff --git a/config/chips/H7Ax_H7Bx.chip b/config/chips/H7Ax_H7Bx.chip index bffd23603..b17631385 100644 --- a/config/chips/H7Ax_H7Bx.chip +++ b/config/chips/H7Ax_H7Bx.chip @@ -1,8 +1,8 @@ -# Chipid file for H7Ax/H7Bx +# Chip-ID file for H7Ax/H7Bx # chip_id 480 description H7Ax/H7Bx -flash_type a +flash_type a flash_pagesize 2000 sram_size 20000 bootrom_base 1ff00000 diff --git a/config/chips/L011.chip b/config/chips/L011.chip index 02223ddcf..6d8298848 100644 --- a/config/chips/L011.chip +++ b/config/chips/L011.chip @@ -1,8 +1,8 @@ -# Chipid file for L011 +# Chip-ID file for L011 # chip_id 457 description L011 -flash_type 5 +flash_type 5 flash_pagesize 80 sram_size 2000 bootrom_base 1ff00000 diff --git a/config/chips/L0x3.chip b/config/chips/L0x3.chip index 60d75e863..4bfc318c0 100644 --- a/config/chips/L0x3.chip +++ b/config/chips/L0x3.chip @@ -1,8 +1,8 @@ -# Chipid file for L0x3 +# Chip-ID file for L0x3 # chip_id 417 description L0x3 -flash_type 5 +flash_type 5 flash_pagesize 80 sram_size 2000 bootrom_base 1ff0000 diff --git a/config/chips/L0xx Category 2.chip b/config/chips/L0xx cat2.chip similarity index 63% rename from config/chips/L0xx Category 2.chip rename to config/chips/L0xx cat2.chip index 1cb9e1307..8b24634cf 100644 --- a/config/chips/L0xx Category 2.chip +++ b/config/chips/L0xx cat2.chip @@ -1,8 +1,8 @@ -# Chipid file for L0xx Category 2 +# Chip-ID file for L0xx cat2 # chip_id 425 -description L0xx Category 2 -flash_type 5 +description L0xx cat2 +flash_type 5 flash_pagesize 80 sram_size 2000 bootrom_base 1ff0000 diff --git a/config/chips/L0xx Category 5.chip b/config/chips/L0xx cat5.chip similarity index 63% rename from config/chips/L0xx Category 5.chip rename to config/chips/L0xx cat5.chip index 35df2fb02..b52f97363 100644 --- a/config/chips/L0xx Category 5.chip +++ b/config/chips/L0xx cat5.chip @@ -1,8 +1,8 @@ -# Chipid file for L0xx Category 5 +# Chip-ID file for L0xx cat5 # chip_id 447 -description L0xx Category 5 -flash_type 5 +description L0xx cat5 +flash_type 5 flash_pagesize 80 sram_size 5000 bootrom_base 1ff0000 diff --git a/config/chips/L152RE.chip b/config/chips/L152RE.chip index ec9d24442..c073ade93 100644 --- a/config/chips/L152RE.chip +++ b/config/chips/L152RE.chip @@ -1,8 +1,8 @@ -# Chipid file for L152RE +# Chip-ID file for L152RE # chip_id 437 description L152RE -flash_type 5 +flash_type 5 flash_pagesize 100 sram_size 14000 bootrom_base 1ff00000 diff --git a/config/chips/L1xx Cat.2.chip b/config/chips/L1xx cat2.chip similarity index 65% rename from config/chips/L1xx Cat.2.chip rename to config/chips/L1xx cat2.chip index 7a3080c60..dd89c981c 100644 --- a/config/chips/L1xx Cat.2.chip +++ b/config/chips/L1xx cat2.chip @@ -1,8 +1,8 @@ -# Chipid file for L1xx Cat.2 +# Chip-ID file for L1xx cat2 # chip_id 429 -description L1xx Cat.2 -flash_type 5 +description L1xx cat2 +flash_type 5 flash_pagesize 100 sram_size 8000 bootrom_base 1ff00000 diff --git a/config/chips/L1xx High-density.chip b/config/chips/L1xx high-density.chip similarity index 62% rename from config/chips/L1xx High-density.chip rename to config/chips/L1xx high-density.chip index 4f6c85929..8e5b0cd44 100644 --- a/config/chips/L1xx High-density.chip +++ b/config/chips/L1xx high-density.chip @@ -1,8 +1,8 @@ -# Chipid file for L1xx High-density +# Chip-ID file for L1xx high-density # chip_id 436 -description L1xx High-density -flash_type 5 +description L1xx high-density +flash_type 5 flash_pagesize 100 sram_size c000 bootrom_base 1ff00000 diff --git a/config/chips/L1xx Medium-density.chip b/config/chips/L1xx medium-density.chip similarity index 59% rename from config/chips/L1xx Medium-density.chip rename to config/chips/L1xx medium-density.chip index a1817c5d6..feb53b846 100644 --- a/config/chips/L1xx Medium-density.chip +++ b/config/chips/L1xx medium-density.chip @@ -1,8 +1,8 @@ -# Chipid file for L1xx Medium-density +# Chip-ID file for L1xx medium-density # chip_id 416 -description L1xx Medium-density -flash_type 5 +description L1xx medium-density +flash_type 5 flash_pagesize 100 sram_size 4000 bootrom_base 1ff00000 diff --git a/config/chips/L1xx Medium-Plus-density.chip b/config/chips/L1xx medium-plus-density.chip similarity index 57% rename from config/chips/L1xx Medium-Plus-density.chip rename to config/chips/L1xx medium-plus-density.chip index 30ce11e92..bdce4adc2 100644 --- a/config/chips/L1xx Medium-Plus-density.chip +++ b/config/chips/L1xx medium-plus-density.chip @@ -1,8 +1,8 @@ -# Chipid file for L1xx Medium-Plus-density +# Chip-ID file for L1xx medium-plus-density # chip_id 427 -description L1xx Medium-Plus-density -flash_type 5 +description L1xx medium-plus-density +flash_type 5 flash_pagesize 100 sram_size 8000 bootrom_base 1ff00000 diff --git a/config/chips/L41x.chip b/config/chips/L41x.chip index 008c9bfa2..a05034af4 100644 --- a/config/chips/L41x.chip +++ b/config/chips/L41x.chip @@ -1,8 +1,8 @@ -# Chipid file for L41x +# Chip-ID file for L41x # chip_id 464 description L41x -flash_type 6 +flash_type 6 flash_pagesize 800 sram_size a000 bootrom_base 1fff0000 diff --git a/config/chips/L43x_L44x.chip b/config/chips/L43x_L44x.chip index 1d956c15e..4c41ac69b 100644 --- a/config/chips/L43x_L44x.chip +++ b/config/chips/L43x_L44x.chip @@ -1,8 +1,8 @@ -# Chipid file for L43x/L44x +# Chip-ID file for L43x/L44x # chip_id 435 description L43x/L44x -flash_type 6 +flash_type 6 flash_pagesize 800 sram_size c000 bootrom_base 1fff0000 diff --git a/config/chips/L45x_46x.chip b/config/chips/L45x_L46x.chip similarity index 66% rename from config/chips/L45x_46x.chip rename to config/chips/L45x_L46x.chip index 438821fcc..da1594995 100644 --- a/config/chips/L45x_46x.chip +++ b/config/chips/L45x_L46x.chip @@ -1,8 +1,8 @@ -# Chipid file for L45x/46x +# Chip-ID file for L45x/L46x # chip_id 462 -description L45x/46x -flash_type 6 +description L45x/L46x +flash_type 6 flash_pagesize 800 sram_size 20000 bootrom_base 1fff0000 diff --git a/config/chips/L496x_L4A6x.chip b/config/chips/L496x_L4A6x.chip index b607e18cc..9bfcdb366 100644 --- a/config/chips/L496x_L4A6x.chip +++ b/config/chips/L496x_L4A6x.chip @@ -1,8 +1,8 @@ -# Chipid file for L496x/L4A6x +# Chip-ID file for L496x/L4A6x # chip_id 461 description L496x/L4A6x -flash_type 6 +flash_type 6 flash_pagesize 800 sram_size 40000 bootrom_base 1fff0000 diff --git a/config/chips/L4Rx.chip b/config/chips/L4Rx.chip index e42aba017..a9b082128 100644 --- a/config/chips/L4Rx.chip +++ b/config/chips/L4Rx.chip @@ -1,8 +1,8 @@ -# Chipid file for L4Rx +# Chip-ID file for L4Rx # chip_id 470 description L4Rx -flash_type 6 +flash_type 6 flash_pagesize 1000 sram_size a0000 bootrom_base 1fff0000 diff --git a/config/chips/L4xx.chip b/config/chips/L4xx.chip index 10ec24455..b66df6b31 100644 --- a/config/chips/L4xx.chip +++ b/config/chips/L4xx.chip @@ -1,8 +1,8 @@ -# Chipid file for L4xx +# Chip-ID file for L4xx # chip_id 415 description L4xx -flash_type 6 +flash_type 6 flash_pagesize 800 sram_size 18000 bootrom_base 1fff0000 diff --git a/config/chips/WB55.chip b/config/chips/WB55.chip index bdc0d4449..4ad4d08d0 100644 --- a/config/chips/WB55.chip +++ b/config/chips/WB55.chip @@ -1,8 +1,8 @@ -# Chipid file for WB55 +# Chip-ID file for WB55 # chip_id 495 description WB55 -flash_type 9 +flash_type 9 flash_pagesize 1000 sram_size 40000 bootrom_base 1fff0000 diff --git a/config/chips/unknown device.chip b/config/chips/unknown device.chip index 63ba47a30..ea4fe5f02 100644 --- a/config/chips/unknown device.chip +++ b/config/chips/unknown device.chip @@ -1,8 +1,8 @@ -# Chipid file for unknown device +# Chip-ID file for unknown device # chip_id 0 description unknown device -flash_type 0 +flash_type 0 flash_pagesize 0 sram_size 0 bootrom_base 0 diff --git a/config/udev/rules.d/49-stlinkv1.rules b/config/udev/rules.d/49-stlinkv1.rules index d474d6a40..9b30f1f09 100644 --- a/config/udev/rules.d/49-stlinkv1.rules +++ b/config/udev/rules.d/49-stlinkv1.rules @@ -1,4 +1,4 @@ -# stm32 discovery boards, with onboard st/linkv1 +# STM32 discovery boards, with onboard st/linkv1 # ie, STM32VL SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3744", \ diff --git a/config/udev/rules.d/49-stlinkv2-1.rules b/config/udev/rules.d/49-stlinkv2-1.rules index b89b84012..ef51f4e88 100644 --- a/config/udev/rules.d/49-stlinkv2-1.rules +++ b/config/udev/rules.d/49-stlinkv2-1.rules @@ -1,4 +1,4 @@ -# stm32 nucleo boards, with onboard st/linkv2-1 +# STM32 nucleo boards, with onboard st/linkv2-1 # ie, STM32F0, STM32F4. # STM32VL has st/linkv1, which is quite different diff --git a/config/udev/rules.d/49-stlinkv2.rules b/config/udev/rules.d/49-stlinkv2.rules index a11215c57..b4c388464 100644 --- a/config/udev/rules.d/49-stlinkv2.rules +++ b/config/udev/rules.d/49-stlinkv2.rules @@ -1,4 +1,4 @@ -# stm32 discovery boards, with onboard st/linkv2 +# STM32 discovery boards, with onboard st/linkv2 # ie, STM32L, STM32F4. # STM32VL has st/linkv1, which is quite different diff --git a/doc/tutorial.md b/doc/tutorial.md index f8f0cbb05..7e0b3901b 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -2,18 +2,18 @@ ## Available tools and options -| Option | Tool | Description | Available
      since | -| --------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | +| Option | Tool | Description | Available
      since | +| --------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | | --flash=n[k, M] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k for the STM32F103C8T6
      to assume 128k of flash being present. This option accepts decimal (128k), octal 0200k, or hex 0x80k values.
      Leaving the multiplier out is equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional
      "k" or "M" to multiply the given value by 1k (1024) or 1M (1024 x 1024) respectively.
      One can read arbitary addresses of memory out to a binary file with: `st-flash read out.bin 0x8000000 4096`.
      In this example `4096 bytes` are read and subsequently written to `out.bin`.
      Binary files (here: `in.bin`) are written into flash memory with: `st-flash write in.bin 0x8000000` | v1.4.0 | -| --format | st-flash | Specify file image format to read or write. Valid formats are `binary` and `ihex`. | v1.3.0 -| --freq=n[k, M] | st-info
      st-flash
      st-util | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
      This option solely accepts decimal values with the unit `Hz` being left out. Valid frequencies are:
      `5k, 15k, 25k, 50k, 100k, 125k, 240k, 480k, 950k, 1200k (1.2M), 1800k (1.8M), 4000k (4M)`. | v1.6.1 | -| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
      This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | -| --reset | st-flash | Trigger a reset after flashing. The default uses the hardware reset through `NRST` pin.
      A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | -| --connect-under-reset | st-info
      st-flash
      st-util | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
      when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | -| --hot-plug | st-info
      st-flash
      st-util | Connect to the target without reset. | v1.6.2 | -| --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | -| --version | st-info
      st-flash
      st-util | Print version information. | v1.3.0 | -| --help | st-flash
      st-util | Print list of available commands. | | +| --format | st-flash | Specify file image format to read or write. Valid formats are `binary` and `ihex`. | v1.3.0 | +| --freq=n[k, M] | st-info
      st-flash
      st-util | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
      This option solely accepts decimal values with the unit `Hz` being left out. Valid frequencies are:
      `5k, 15k, 25k, 50k, 100k, 125k, 240k, 480k, 950k, 1200k (1.2M), 1800k (1.8M), 4000k (4M)`. | v1.6.1 | +| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
      This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | +| --reset | st-flash | Trigger a reset after flashing. The default uses the hardware reset through `NRST` pin.
      A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | +| --connect-under-reset | st-info
      st-flash
      st-util | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
      when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | +| --hot-plug | st-info
      st-flash
      st-util | Connect to the target without reset. | v1.6.2 | +| --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | +| --version | st-info
      st-flash
      st-util | Print version information. | v1.3.0 | +| --help | st-flash
      st-util | Print list of available commands. | | ### Reading & Writing Option Bytes @@ -65,9 +65,9 @@ crw-rw-rw- 1 root root 189, 528 Jan 24 17:52 /dev/bus/usb/005/017 which is world writable (this is from the `MODE:="0666"` below). I have several files in my `/etc/udev/rules.d` directory. In this particular case, the `49-stlinkv2-1.rules` file contains the following: ``` -# stm32 nucleo boards, with onboard st/linkv2-1 +# STM32 nucleo boards, with onboard STLINK/V2-1 # ie, STM32F0, STM32F4. -# STM32VL has st/linkv1, which is quite different +# STM32VL has STLINK/V1, which is quite different SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", \ MODE:="0666", \ diff --git a/src/common.c b/src/common.c index 80190f756..49a048039 100644 --- a/src/common.c +++ b/src/common.c @@ -333,7 +333,7 @@ #define FLASH_H7_CR_SER 2 #define FLASH_H7_CR_BER 3 #define FLASH_H7_CR_PSIZE 4 -#define FLASH_H7_CR_START(chipid) (chipid == STLINK_CHIPID_STM32_H7AX ? 5 : 7) +#define FLASH_H7_CR_START(chipid) (chipid == STLINK_CHIPID_STM32_H7Ax ? 5 : 7) #define FLASH_H7_CR_SNB 8 #define FLASH_H7_CR_SNB_MASK 0x700 @@ -447,9 +447,9 @@ static uint32_t get_stm32l0_flash_base(stlink_t *sl) { return (STM32L0_FLASH_REGS_ADDR); case STLINK_CHIPID_STM32_L1_CAT2: - case STLINK_CHIPID_STM32_L1_MEDIUM: - case STLINK_CHIPID_STM32_L1_MEDIUM_PLUS: - case STLINK_CHIPID_STM32_L1_HIGH: + case STLINK_CHIPID_STM32_L1_MD: + case STLINK_CHIPID_STM32_L1_MD_PLUS: + case STLINK_CHIPID_STM32_L1_MD_PLUS_HD: return (STM32L1_FLASH_REGS_ADDR); default: @@ -1618,14 +1618,14 @@ int stlink_load_device_params(stlink_t *sl) { flash_size = flash_size & 0xffff; - if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || - sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW || - sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS) && + if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MD || + sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MD_LD || + sl->chip_id == STLINK_CHIPID_STM32_L1_MD_PLUS) && (flash_size == 0)) { sl->flash_size = 128 * 1024; } else if (sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2) { sl->flash_size = (flash_size & 0xff) * 1024; - } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_HIGH) { + } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_MD_PLUS_HD) { // 0 is 384k and 1 is 256k if (flash_size == 0) { sl->flash_size = 384 * 1024; @@ -1647,7 +1647,7 @@ int stlink_load_device_params(stlink_t *sl) { // medium and low devices have the same chipid. ram size depends on flash // size. STM32F100xx datasheet Doc ID 16455 Table 2 - if (sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW && + if (sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MD_LD && sl->flash_size < 64 * 1024) { sl->sram_size = 0x1000; } @@ -2715,8 +2715,8 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { flashaddr -= STM32_FLASH_BASE; if (sl->chip_id == STLINK_CHIPID_STM32_L4 || - sl->chip_id == STLINK_CHIPID_STM32_L496X || - sl->chip_id == STLINK_CHIPID_STM32_L4RX) { + sl->chip_id == STLINK_CHIPID_STM32_L496x_L4A6x || + sl->chip_id == STLINK_CHIPID_STM32_L4Rx) { // this chip use dual banked flash if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { uint32_t banksize = (uint32_t)sl->flash_size / 2; @@ -2739,10 +2739,10 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || - (sl->chip_id == STLINK_CHIPID_STM32_F411XX) || + (sl->chip_id == STLINK_CHIPID_STM32_F411xx) || (sl->chip_id == STLINK_CHIPID_STM32_F446) || (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || - (sl->chip_id == STLINK_CHIPID_STM32_F72XXX) || + (sl->chip_id == STLINK_CHIPID_STM32_F72xxx) || (sl->chip_id == STLINK_CHIPID_STM32_F412)) { uint32_t sector = calculate_F4_sectornum(flashaddr); @@ -2758,7 +2758,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { sl->flash_pgsz = 0x20000; } } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { + sl->chip_id == STLINK_CHIPID_STM32_F76xxx) { uint32_t sector = calculate_F7_sectornum(flashaddr); if (sector < 4) { @@ -2794,10 +2794,10 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { // select the page to erase if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || - (sl->chip_id == STLINK_CHIPID_STM32_L43X) || - (sl->chip_id == STLINK_CHIPID_STM32_L46X) || - (sl->chip_id == STLINK_CHIPID_STM32_L496X) || - (sl->chip_id == STLINK_CHIPID_STM32_L4RX)) { + (sl->chip_id == STLINK_CHIPID_STM32_L43x_L44x) || + (sl->chip_id == STLINK_CHIPID_STM32_L45x_L46x) || + (sl->chip_id == STLINK_CHIPID_STM32_L496x_L4A6x) || + (sl->chip_id == STLINK_CHIPID_STM32_L4Rx)) { // calculate the actual bank+page from the address uint32_t page = calculate_L4_page(sl, flashaddr); @@ -2806,7 +2806,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { write_flash_cr_bker_pnb(sl, page); } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { + sl->chip_id == STLINK_CHIPID_STM32_F76xxx) { // calculate the actual page from the address uint32_t sector = calculate_F7_sectornum(flashaddr); @@ -2990,7 +2990,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { unlock_flash_if(sl); if (sl->flash_type == STLINK_FLASH_TYPE_H7 && - sl->chip_id != STLINK_CHIPID_STM32_H7AX) { + sl->chip_id != STLINK_CHIPID_STM32_H7Ax) { // set parallelism write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { @@ -3265,7 +3265,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { set_flash_cr_pg(sl, BANK_2); } - if (sl->chip_id != STLINK_CHIPID_STM32_H7AX) { + if (sl->chip_id != STLINK_CHIPID_STM32_H7Ax) { // set parallelism write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { @@ -4383,7 +4383,7 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { case STLINK_CHIPID_STM32_F4: case STLINK_CHIPID_STM32_F446: return stlink_read_option_bytes_f4(sl, option_byte); - case STLINK_CHIPID_STM32_F7XXXX: + case STLINK_CHIPID_STM32_F76xxx: return stlink_read_option_bytes_f7(sl, option_byte); case STLINK_CHIPID_STM32_G0_CAT1: case STLINK_CHIPID_STM32_G0_CAT2: @@ -4632,12 +4632,12 @@ stlink_write_option_control_register_f0(stlink_t *sl, case 0x432: /* STM32F37x */ case 0x438: /* STM32F303x6/8 and STM32F328 */ case 0x446: /* STM32F303xD/E and STM32F398xE */ - case 0x439: /* stm32f302x6/8 */ - case 0x440: /* stm32f05x */ - case 0x444: /* stm32f03x */ - case 0x445: /* stm32f04x */ - case 0x448: /* stm32f07x */ - case 0x442: /* stm32f09x */ + case 0x439: /* STM32F302x6/8 */ + case 0x440: /* STM32F05x */ + case 0x444: /* STM32F03x */ + case 0x445: /* STM32F04x */ + case 0x448: /* STM32F07x */ + case 0x442: /* STM32F09x */ option_offset = 6; user_data_offset = 16; rdp = 0x55AA; diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 87c6c77e1..27ed81da4 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -535,14 +535,14 @@ char* make_memory_map(stlink_t *sl) { if (sl->chip_id == STLINK_CHIPID_STM32_F4 || sl->chip_id == STLINK_CHIPID_STM32_F446 || - sl->chip_id == STLINK_CHIPID_STM32_F411XX) { + sl->chip_id == STLINK_CHIPID_STM32_F411xx) { strcpy(map, memory_map_template_F4); } else if (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) { strcpy(map, memory_map_template_F4_DE); } else if (sl->core_id == STM32F7_CORE_ID) { snprintf(map, sz, memory_map_template_F7, (unsigned int)sl->sram_size); - } else if (sl->chip_id == STLINK_CHIPID_STM32_H74XXX) { + } else if (sl->chip_id == STLINK_CHIPID_STM32_H74xxx) { snprintf(map, sz, memory_map_template_H7, (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz); @@ -556,12 +556,12 @@ char* make_memory_map(stlink_t *sl) { (unsigned int)sl->sys_base, (unsigned int)sl->sys_size); } else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || - (sl->chip_id == STLINK_CHIPID_STM32_L43X) || - (sl->chip_id == STLINK_CHIPID_STM32_L46X)) { + (sl->chip_id == STLINK_CHIPID_STM32_L43x_L44x) || + (sl->chip_id == STLINK_CHIPID_STM32_L45x_L46x)) { snprintf(map, sz, memory_map_template_L4, (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); - } else if (sl->chip_id == STLINK_CHIPID_STM32_L496X) { + } else if (sl->chip_id == STLINK_CHIPID_STM32_L496x_L4A6x) { snprintf(map, sz, memory_map_template_L496, (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 8ef6e17c2..a9f19a155 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -11,7 +11,7 @@ static struct stlink_chipid_params devices[] = { { // RM0410 document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F7XXXX, + .chip_id = STLINK_CHIPID_STM32_F76xxx, .description = "F76xxx", .flash_type = STLINK_FLASH_TYPE_F7, .flash_size_reg = 0x1ff0f442, // section 45.2 @@ -42,7 +42,7 @@ static struct stlink_chipid_params devices[] = { }, { // RM0431 and DS document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F72XXX, + .chip_id = STLINK_CHIPID_STM32_F72xxx, .description = "F72x/F73x", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1ff07a22, // section 35.2 @@ -56,7 +56,7 @@ static struct stlink_chipid_params devices[] = { }, { // table 2, PM0063 - .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, + .chip_id = STLINK_CHIPID_STM32_F1_MD, .description = "F1xx Medium-density", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, @@ -84,7 +84,7 @@ static struct stlink_chipid_params devices[] = { }, { // PM0063 - .chip_id = STLINK_CHIPID_STM32_F1_LOW, + .chip_id = STLINK_CHIPID_STM32_F1_LD, .description = "F1 Low-density device", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, @@ -143,7 +143,7 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - .chip_id = STLINK_CHIPID_STM32_F411XX, + .chip_id = STLINK_CHIPID_STM32_F411xx, .description = "STM32F411xC/E", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, @@ -167,7 +167,7 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - .chip_id = STLINK_CHIPID_STM32_F1_HIGH, + .chip_id = STLINK_CHIPID_STM32_F1_HD, .description = "F1xx High-density", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, @@ -182,7 +182,7 @@ static struct stlink_chipid_params devices[] = { { // This ignores the EEPROM! (and uses the page erase size, // not the sector write protection...) - .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM, + .chip_id = STLINK_CHIPID_STM32_L1_MD, .description = "L1xx Medium-density", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8004c, @@ -204,7 +204,7 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM_PLUS, + .chip_id = STLINK_CHIPID_STM32_L1_MD_PLUS, .description = "L1xx Medium-Plus-density", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, @@ -215,7 +215,7 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - .chip_id = STLINK_CHIPID_STM32_L1_HIGH, + .chip_id = STLINK_CHIPID_STM32_L1_MD_PLUS_HD, .description = "L1xx High-density", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, @@ -253,7 +253,7 @@ static struct stlink_chipid_params devices[] = { }, { // Low and Medium density VL have same chipid. RM0041 25.6.1 - .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, + .chip_id = STLINK_CHIPID_STM32_F1_VL_MD_LD, .description = "F1xx Value Line", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, @@ -322,7 +322,7 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - .chip_id = STLINK_CHIPID_STM32_F1_VL_HIGH, + .chip_id = STLINK_CHIPID_STM32_F1_VL_HD, .description = "F1xx High-density value line", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, @@ -335,7 +335,7 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - .chip_id = STLINK_CHIPID_STM32_F1_XL, + .chip_id = STLINK_CHIPID_STM32_F1_XLD, .description = "F1xx XL-density", .flash_type = STLINK_FLASH_TYPE_F1_XL, .flash_size_reg = 0x1ffff7e0, @@ -407,7 +407,7 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - .chip_id = STLINK_CHIPID_STM32_F09X, + .chip_id = STLINK_CHIPID_STM32_F09x, .description = "F09X", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) @@ -437,7 +437,7 @@ static struct stlink_chipid_params devices[] = { { // Use this as an example for mapping future chips: // RM0091 document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F0_SMALL, + .chip_id = STLINK_CHIPID_STM32_F0xx_SMALL, .description = "F03x", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) @@ -451,7 +451,7 @@ static struct stlink_chipid_params devices[] = { }, { // STM32F30x - .chip_id = STLINK_CHIPID_STM32_F3_SMALL, + .chip_id = STLINK_CHIPID_STM32_F3xx_SMALL, .description = "F3xx small", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, @@ -523,7 +523,7 @@ static struct stlink_chipid_params devices[] = { { // This is STK32F303RET6 device from STM32 F3 Nucelo board. // Support based on DM00043574.pdf (RM0316) document rev 5. - .chip_id = STLINK_CHIPID_STM32_F303_HIGH, + .chip_id = STLINK_CHIPID_STM32_F303_HD, .description = "F303 high density", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register @@ -560,7 +560,7 @@ static struct stlink_chipid_params devices[] = { { // STM32L4RX // From DM00310109.pdf - .chip_id = STLINK_CHIPID_STM32_L4RX, + .chip_id = STLINK_CHIPID_STM32_L4Rx, .description = "L4Rx", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = @@ -573,9 +573,9 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STLINK_CHIPID_STM32_L41X + // STLINK_CHIPID_STM32_L41x_L42x // From RM0394 Rev 4 and DS12469 Rev 5 - .chip_id = STLINK_CHIPID_STM32_L41X, + .chip_id = STLINK_CHIPID_STM32_L41x_L42x, .description = "L41x", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, @@ -591,9 +591,9 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STLINK_CHIPID_STM32_L43X + // STLINK_CHIPID_STM32_L43x_L44x // From RM0392. - .chip_id = STLINK_CHIPID_STM32_L43X, + .chip_id = STLINK_CHIPID_STM32_L43x_L44x, .description = "L43x/L44x", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = @@ -613,9 +613,9 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STLINK_CHIPID_STM32_L496X + // STLINK_CHIPID_STM32_L496x_L4A6x // Support based on en.DM00083560.pdf (RM0351) document rev 5. - .chip_id = STLINK_CHIPID_STM32_L496X, + .chip_id = STLINK_CHIPID_STM32_L496x_L4A6x, .description = "L496x/L4A6x", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = @@ -632,9 +632,9 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STLINK_CHIPID_STM32_L46X + // STLINK_CHIPID_STM32_L45x_L46x // From RM0394 (updated version of RM0392?). - .chip_id = STLINK_CHIPID_STM32_L46X, + .chip_id = STLINK_CHIPID_STM32_L45x_L46x, .description = "L45x/46x", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = @@ -764,7 +764,7 @@ static struct stlink_chipid_params devices[] = { }, { // STM32H742/743/753 (from RM0433) - .chip_id = STLINK_CHIPID_STM32_H74XXX, + .chip_id = STLINK_CHIPID_STM32_H74xxx, .description = "H74x/H75x", .flash_type = STLINK_FLASH_TYPE_H7, .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) @@ -780,7 +780,7 @@ static struct stlink_chipid_params devices[] = { }, { // STM32H7A3/7B3 (from RM0455) - .chip_id = STLINK_CHIPID_STM32_H7AX, + .chip_id = STLINK_CHIPID_STM32_H7Ax, .description = "H7Ax/H7Bx", .flash_type = STLINK_FLASH_TYPE_H7, .flash_size_reg = 0x08FFF80C, // "Flash size register" (p.2949) @@ -796,7 +796,7 @@ static struct stlink_chipid_params devices[] = { }, { // STM32H72x/H73x (from RM0468) - .chip_id = STLINK_CHIPID_STM32_H72X, + .chip_id = STLINK_CHIPID_STM32_H72x, .description = "H72x/H73x", .flash_type = STLINK_FLASH_TYPE_H7, .flash_size_reg = 0x1FF1E880, // "Flash size register" (p.3286) @@ -840,18 +840,18 @@ static struct stlink_chipid_params *devicelist; void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { - fprintf (fp, "# Chipid file for %s\n", dev->description); - fprintf (fp, "#\n"); - fprintf (fp, "chip_id %x\n", dev->chip_id); - fprintf (fp, "description %s\n", dev->description); - fprintf (fp, "flash_type %x\n", dev->flash_type); - fprintf (fp, "flash_pagesize %x\n", dev->flash_pagesize); - fprintf (fp, "sram_size %x\n", dev->sram_size); - fprintf (fp, "bootrom_base %x\n", dev->bootrom_base); - fprintf (fp, "bootrom_size %x\n", dev->bootrom_size); - fprintf (fp, "option_base %x\n", dev->option_base); - fprintf (fp, "option_size %x\n", dev->option_size); - fprintf (fp, "flags %x\n\n", dev->flags); + fprintf(fp, "# Chip-ID file for %s\n", dev->description); + fprintf(fp, "#\n"); + fprintf(fp, "chip_id %x\n", dev->chip_id); + fprintf(fp, "description %s\n", dev->description); + fprintf(fp, "flash_type %x\n", dev->flash_type); + fprintf(fp, "flash_pagesize %x\n", dev->flash_pagesize); + fprintf(fp, "sram_size %x\n", dev->sram_size); + fprintf(fp, "bootrom_base %x\n", dev->bootrom_base); + fprintf(fp, "bootrom_size %x\n", dev->bootrom_size); + fprintf(fp, "option_base %x\n", dev->option_base); + fprintf(fp, "option_size %x\n", dev->option_size); + fprintf(fp, "flags %x\n\n", dev->flags); } @@ -864,21 +864,21 @@ struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { for (params = devicelist ; params != NULL ; params = params -> next) if (params->chip_id == chipid) break; - p2 = stlink_chipid_get_params_old (chipid); + p2 = stlink_chipid_get_params_old(chipid); - if (memcmp (p2, params, sizeof (struct stlink_chipid_params) - sizeof (struct stlink_chipid_params *)) != 0) { + if (memcmp(p2, params, sizeof (struct stlink_chipid_params) - sizeof (struct stlink_chipid_params *)) != 0) { //fprintf (stderr, "Error, chipid params not identical\n"); //return NULL; - fprintf (stderr, "---------- old ------------\n"); - dump_a_chip (stderr, p2); - fprintf (stderr, "---------- new ------------\n"); - dump_a_chip (stderr, params); + fprintf(stderr, "---------- old ------------\n"); + dump_a_chip(stderr, p2); + fprintf(stderr, "---------- new ------------\n"); + dump_a_chip(stderr, params); } return(params); } -void process_chipfile (char *fname) +void process_chipfile(char *fname) { FILE *fp; char *p, buf[1025]; @@ -887,44 +887,44 @@ void process_chipfile (char *fname) int nc; //fprintf (stderr, "processing chipfile %s.\n", fname); - fp = fopen (fname, "r"); + fp = fopen(fname, "r"); if (!fp) { - perror (fname); + perror(fname); return; } - ts = calloc (sizeof (struct stlink_chipid_params), 1); - while (fgets (buf, 1024, fp) != NULL) { + ts = calloc(sizeof (struct stlink_chipid_params), 1); + while (fgets(buf, 1024, fp) != NULL) { for (p=buf;isspace (*p);p++); if (!*p) continue; // we hit end-of-line wiht only whitespace if (*p == '#') continue; // ignore comments. - sscanf (p, "%s %s", word, value); - if (strcmp (word, "chip_id") == 0) { - sscanf (value, "%x", &ts->chip_id); + sscanf(p, "%s %s", word, value); + if (strcmp(word, "chip_id") == 0) { + sscanf(value, "%x", &ts->chip_id); } else if (strcmp (word, "description") == 0) { //ts->description = strdup (value); buf[strlen(p)-1] = 0; // chomp newline - sscanf (p, "%*s %n", &nc); - ts->description = strdup (p+nc); + sscanf(p, "%*s %n", &nc); + ts->description = strdup(p+nc); } else if (strcmp (word, "flash_type") == 0) { - sscanf (value, "%x", &ts->flash_type); + sscanf(value, "%x", &ts->flash_type); } else if (strcmp (word, "flash_size_reg") == 0) { - sscanf (value, "%x", &ts->flash_size_reg); + sscanf(value, "%x", &ts->flash_size_reg); } else if (strcmp (word, "flash_pagesize") == 0) { - sscanf (value, "%x", &ts->flash_pagesize); + sscanf(value, "%x", &ts->flash_pagesize); } else if (strcmp (word, "sram_size") == 0) { - sscanf (value, "%x", &ts->sram_size); + sscanf(value, "%x", &ts->sram_size); } else if (strcmp (word, "bootrom_base") == 0) { - sscanf (value, "%x", &ts->bootrom_base); + sscanf(value, "%x", &ts->bootrom_base); } else if (strcmp (word, "bootrom_size") == 0) { - sscanf (value, "%x", &ts->bootrom_size); + sscanf(value, "%x", &ts->bootrom_size); } else if (strcmp (word, "option_base") == 0) { - sscanf (value, "%x", &ts->option_base); + sscanf(value, "%x", &ts->option_base); } else if (strcmp (word, "option_size") == 0) { - sscanf (value, "%x", &ts->option_size); + sscanf(value, "%x", &ts->option_size); } else if (strcmp (word, "flags") == 0) { - sscanf (value, "%x", &ts->flags); + sscanf(value, "%x", &ts->flags); } else { fprintf (stderr, "Unknown keyword in %s: %s\n", fname, word); @@ -934,7 +934,6 @@ void process_chipfile (char *fname) devicelist = ts; } - void dump_chips (void) { struct stlink_chipid_params *ts; @@ -944,30 +943,28 @@ void dump_chips (void) for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) { ts = &devices[n]; - strcpy (buf, ts->description); - while ((p = strchr (buf, '/'))) // change slashes to underscore. + strcpy(buf, ts->description); + while ((p = strchr(buf, '/'))) // change slashes to underscore. *p = '_'; - strcat (buf, ".chip"); - fp = fopen (buf, "w"); - fprintf (fp, "# Chipid file for %s\n", ts->description); - fprintf (fp, "#\n"); - fprintf (fp, "chip_id %x\n", ts->chip_id); - fprintf (fp, "description %s\n", ts->description); - fprintf (fp, "flash_type %x\n", ts->flash_type); - fprintf (fp, "flash_pagesize %x\n", ts->flash_pagesize); - fprintf (fp, "sram_size %x\n", ts->sram_size); - fprintf (fp, "bootrom_base %x\n", ts->bootrom_base); - fprintf (fp, "bootrom_size %x\n", ts->bootrom_size); - fprintf (fp, "option_base %x\n", ts->option_base); - fprintf (fp, "option_size %x\n", ts->option_size); - fprintf (fp, "flags %x\n\n", ts->flags); - fclose (fp); + strcat(buf, ".chip"); + fp = fopen(buf, "w"); + fprintf(fp, "# Chip-ID file for %s\n", ts->description); + fprintf(fp, "#\n"); + fprintf(fp, "chip_id %x\n", ts->chip_id); + fprintf(fp, "description %s\n", ts->description); + fprintf(fp, "flash_type %x\n", ts->flash_type); + fprintf(fp, "flash_pagesize %x\n", ts->flash_pagesize); + fprintf(fp, "sram_size %x\n", ts->sram_size); + fprintf(fp, "bootrom_base %x\n", ts->bootrom_base); + fprintf(fp, "bootrom_size %x\n", ts->bootrom_size); + fprintf(fp, "option_base %x\n", ts->option_base); + fprintf(fp, "option_size %x\n", ts->option_size); + fprintf(fp, "flags %x\n\n", ts->flags); + fclose(fp); } } - - -void init_chipids (char *dir_to_scan) +void init_chipids(char *dir_to_scan) { DIR *d; size_t nl; // namelen @@ -979,11 +976,11 @@ void init_chipids (char *dir_to_scan) d = opendir(dir_to_scan); if (d) { while ((dir = readdir(d)) != NULL) { - nl = strlen (dir->d_name); - if (strcmp (dir->d_name + nl - 5, ".chip") == 0) { + nl = strlen(dir->d_name); + if (strcmp(dir->d_name + nl - 5, ".chip") == 0) { char buf[1024]; - sprintf (buf, "%s/%s", dir_to_scan, dir->d_name); - process_chipfile (buf); + sprintf(buf, "%s/%s", dir_to_scan, dir->d_name); + process_chipfile(buf); } } closedir(d); diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index f80c06732..f1342dd61 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -13,68 +13,66 @@ extern "C" { enum stlink_stm32_chipids { STLINK_CHIPID_UNKNOWN = 0x000, - STLINK_CHIPID_STM32_F1_MEDIUM = 0x410, + STLINK_CHIPID_STM32_F1_MD = 0x410, /* medium density */ STLINK_CHIPID_STM32_F2 = 0x411, - STLINK_CHIPID_STM32_F1_LOW = 0x412, + STLINK_CHIPID_STM32_F1_LD = 0x412, /* low density */ STLINK_CHIPID_STM32_F4 = 0x413, - STLINK_CHIPID_STM32_F1_HIGH = 0x414, + STLINK_CHIPID_STM32_F1_HD = 0x414, /* high density */ STLINK_CHIPID_STM32_L4 = 0x415, - STLINK_CHIPID_STM32_L1_MEDIUM = 0x416, + STLINK_CHIPID_STM32_L1_MD = 0x416, /* medium density */ STLINK_CHIPID_STM32_L0 = 0x417, - STLINK_CHIPID_STM32_F1_CONN = 0x418, - STLINK_CHIPID_STM32_F4_HD = 0x419, - STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW = 0x420, + STLINK_CHIPID_STM32_F1_CONN = 0x418, /* connectivity line */ + STLINK_CHIPID_STM32_F4_HD = 0x419, /* high density */ + STLINK_CHIPID_STM32_F1_VL_MD_LD = 0x420, /* value line medium & low density */ STLINK_CHIPID_STM32_F446 = 0x421, STLINK_CHIPID_STM32_F3 = 0x422, STLINK_CHIPID_STM32_F4_LP = 0x423, STLINK_CHIPID_STM32_L0_CAT2 = 0x425, - STLINK_CHIPID_STM32_L1_MEDIUM_PLUS = 0x427, /* assigned to some L1 "Medium-plus" chips */ - STLINK_CHIPID_STM32_F1_VL_HIGH = 0x428, + STLINK_CHIPID_STM32_L1_MD_PLUS = 0x427, /* medium density plus */ + STLINK_CHIPID_STM32_F1_VL_HD = 0x428, /* value line high density */ STLINK_CHIPID_STM32_L1_CAT2 = 0x429, - STLINK_CHIPID_STM32_F1_XL = 0x430, - STLINK_CHIPID_STM32_F411XX = 0x431, + STLINK_CHIPID_STM32_F1_XLD = 0x430, /* extra low density plus */ + STLINK_CHIPID_STM32_F411xx = 0x431, STLINK_CHIPID_STM32_F37x = 0x432, STLINK_CHIPID_STM32_F4_DE = 0x433, STLINK_CHIPID_STM32_F4_DSI = 0x434, - STLINK_CHIPID_STM32_L43X = 0x435, /* covers STM32L43xxx and STM32L44xxx devices */ - STLINK_CHIPID_STM32_L496X = 0x461, /* covers STM32L496xx and STM32L4A6xx devices */ - STLINK_CHIPID_STM32_L46X = 0x462, /* covers STM32L45xxx and STM32L46xxx devices */ - STLINK_CHIPID_STM32_L41X = 0x464, /* covers STM32L41xxx and STM32L42xxx devices */ - STLINK_CHIPID_STM32_L1_HIGH = 0x436, /* assigned to some L1 "Medium-Plus" and "High" chips */ + STLINK_CHIPID_STM32_L43x_L44x = 0x435, + STLINK_CHIPID_STM32_L1_MD_PLUS_HD = 0x436, /* medium density plus & high density */ STLINK_CHIPID_STM32_L152_RE = 0x437, STLINK_CHIPID_STM32_F334 = 0x438, - STLINK_CHIPID_STM32_F3_SMALL = 0x439, + STLINK_CHIPID_STM32_F3xx_SMALL = 0x439, STLINK_CHIPID_STM32_F0 = 0x440, STLINK_CHIPID_STM32_F412 = 0x441, - STLINK_CHIPID_STM32_F09X = 0x442, - STLINK_CHIPID_STM32_F0_SMALL = 0x444, + STLINK_CHIPID_STM32_F09x = 0x442, + STLINK_CHIPID_STM32_F0xx_SMALL = 0x444, STLINK_CHIPID_STM32_F04 = 0x445, - STLINK_CHIPID_STM32_F303_HIGH = 0x446, + STLINK_CHIPID_STM32_F303_HD = 0x446, /* high density */ STLINK_CHIPID_STM32_L0_CAT5 = 0x447, STLINK_CHIPID_STM32_F0_CAN = 0x448, STLINK_CHIPID_STM32_F7 = 0x449, /* ID found on the NucleoF746ZG board */ - STLINK_CHIPID_STM32_H74XXX = 0x450, /* Found on page 3189 in the RM0433*/ - STLINK_CHIPID_STM32_F7XXXX = 0x451, - STLINK_CHIPID_STM32_F72XXX = 0x452, /* ID found on the NucleoF722ZE board */ - STLINK_CHIPID_STM32_G0_CAT4 = 0x456, /* G050/G051/G061 found on RM0444/RM0454 */ + STLINK_CHIPID_STM32_H74xxx = 0x450, /* RM0433, p.3189 */ + STLINK_CHIPID_STM32_F76xxx = 0x451, + STLINK_CHIPID_STM32_F72xxx = 0x452, /* ID found on the NucleoF722ZE board */ + STLINK_CHIPID_STM32_G0_CAT4 = 0x456, /* G050/G051/G061 found in RM0444/RM0454 */ STLINK_CHIPID_STM32_L011 = 0x457, STLINK_CHIPID_STM32_F410 = 0x458, STLINK_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/081 */ + STLINK_CHIPID_STM32_L496x_L4A6x = 0x461, + STLINK_CHIPID_STM32_L45x_L46x = 0x462, STLINK_CHIPID_STM32_F413 = 0x463, + STLINK_CHIPID_STM32_L41x_L42x = 0x464, STLINK_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/041 */ - STLINK_CHIPID_STM32_G0_CAT3 = 0x467, /* G0B0/G0B1/G0C1 found on RM0444/RM0454 */ - STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* See: RM 0440 s46.6.1 "MCU device ID code" */ + STLINK_CHIPID_STM32_G0_CAT3 = 0x467, /* G0B0/G0B1/G0C1 found in RM0444/RM0454 */ + STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* RM0440, s46.6.1 "MCU device ID code" */ STLINK_CHIPID_STM32_G4_CAT3 = 0x469, - STLINK_CHIPID_STM32_L4RX = 0x470, /* ID found on the STM32L4R9I-DISCO board */ - STLINK_CHIPID_STM32_H7AX = 0x480, /* RM0455, p. 2863 */ - STLINK_CHIPID_STM32_H72X = 0x483, /* RM0468, p. 3199 */ + STLINK_CHIPID_STM32_L4Rx = 0x470, /* ID found on the STM32L4R9I-DISCO board */ + STLINK_CHIPID_STM32_H7Ax = 0x480, /* RM0455, p.2863 */ + STLINK_CHIPID_STM32_H72x = 0x483, /* RM0468, p.3199 */ STLINK_CHIPID_STM32_WB55 = 0x495 }; - -#define CHIP_F_HAS_DUAL_BANK (1 << 0) -#define CHIP_F_HAS_SWO_TRACING (1 << 1) - +#define CHIP_F_HAS_DUAL_BANK (1 << 0) +#define CHIP_F_HAS_SWO_TRACING (1 << 1) /** Chipid parameters */ struct stlink_chipid_params { @@ -94,7 +92,7 @@ struct stlink_chipid_params { struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); - void init_chipids (char *dir_to_scan); + void init_chipids(char *dir_to_scan); #ifdef __cplusplus } diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index d492716db..9a1e86681 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -227,10 +227,10 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* const uint8_t* loader_code; size_t loader_size; - if (sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || + if (sl->chip_id == STLINK_CHIPID_STM32_L1_MD || sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS || - sl->chip_id == STLINK_CHIPID_STM32_L1_HIGH || + sl->chip_id == STLINK_CHIPID_STM32_L1_MD_PLUS || + sl->chip_id == STLINK_CHIPID_STM32_L1_MD_PLUS_HD || sl->chip_id == STLINK_CHIPID_STM32_L152_RE || sl->chip_id == STLINK_CHIPID_STM32_L011 || sl->chip_id == STLINK_CHIPID_STM32_L0 || @@ -239,16 +239,16 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code = loader_code_stm32lx; loader_size = sizeof(loader_code_stm32lx); } else if (sl->core_id == STM32VL_CORE_ID || - sl->chip_id == STLINK_CHIPID_STM32_F1_MEDIUM || - sl->chip_id == STLINK_CHIPID_STM32_F1_HIGH || - sl->chip_id == STLINK_CHIPID_STM32_F1_LOW || - sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW || - sl->chip_id == STLINK_CHIPID_STM32_F1_VL_HIGH || - sl->chip_id == STLINK_CHIPID_STM32_F1_XL || + sl->chip_id == STLINK_CHIPID_STM32_F1_MD || + sl->chip_id == STLINK_CHIPID_STM32_F1_HD || + sl->chip_id == STLINK_CHIPID_STM32_F1_LD || + sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MD_LD || + sl->chip_id == STLINK_CHIPID_STM32_F1_VL_HD || + sl->chip_id == STLINK_CHIPID_STM32_F1_XLD || sl->chip_id == STLINK_CHIPID_STM32_F1_CONN || sl->chip_id == STLINK_CHIPID_STM32_F3 || - sl->chip_id == STLINK_CHIPID_STM32_F3_SMALL || - sl->chip_id == STLINK_CHIPID_STM32_F303_HIGH || + sl->chip_id == STLINK_CHIPID_STM32_F3xx_SMALL || + sl->chip_id == STLINK_CHIPID_STM32_F303_HD || sl->chip_id == STLINK_CHIPID_STM32_F37x || sl->chip_id == STLINK_CHIPID_STM32_F334) { loader_code = loader_code_stm32vl; @@ -260,7 +260,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_F4_HD || sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || sl->chip_id == STLINK_CHIPID_STM32_F410 || - sl->chip_id == STLINK_CHIPID_STM32_F411XX || + sl->chip_id == STLINK_CHIPID_STM32_F411xx || sl->chip_id == STLINK_CHIPID_STM32_F412 || sl->chip_id == STLINK_CHIPID_STM32_F413 || sl->chip_id == STLINK_CHIPID_STM32_F446) { @@ -273,8 +273,8 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* if (retval == -1) { return(retval); } } else if (sl->core_id == STM32F7_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F7XXXX || - sl->chip_id == STLINK_CHIPID_STM32_F72XXX) { + sl->chip_id == STLINK_CHIPID_STM32_F76xxx || + sl->chip_id == STLINK_CHIPID_STM32_F72xxx) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, @@ -285,16 +285,16 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || sl->chip_id == STLINK_CHIPID_STM32_F04 || sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || - sl->chip_id == STLINK_CHIPID_STM32_F0_SMALL || - sl->chip_id == STLINK_CHIPID_STM32_F09X) { + sl->chip_id == STLINK_CHIPID_STM32_F0xx_SMALL || + sl->chip_id == STLINK_CHIPID_STM32_F09x) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); } else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || - (sl->chip_id == STLINK_CHIPID_STM32_L41X) || - (sl->chip_id == STLINK_CHIPID_STM32_L43X) || - (sl->chip_id == STLINK_CHIPID_STM32_L46X) || - (sl->chip_id == STLINK_CHIPID_STM32_L4RX) || - (sl->chip_id == STLINK_CHIPID_STM32_L496X)) { + (sl->chip_id == STLINK_CHIPID_STM32_L41x_L42x) || + (sl->chip_id == STLINK_CHIPID_STM32_L43x_L44x) || + (sl->chip_id == STLINK_CHIPID_STM32_L45x_L46x) || + (sl->chip_id == STLINK_CHIPID_STM32_L4Rx) || + (sl->chip_id == STLINK_CHIPID_STM32_L496x_L4A6x)) { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); } else { From 9d93531ac1a014eddd5efe3b1ca7bde8ec3bcc73 Mon Sep 17 00:00:00 2001 From: Biswapriyo Nath Date: Tue, 18 May 2021 19:46:45 +0530 Subject: [PATCH 1198/1435] cmake: Install shared libraries in proper directories. This fixes the installation of DLL file in mingw. --- CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bd76ebfb..43c5dbac1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -194,8 +194,11 @@ else () target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB}) endif () -install(TARGETS ${STLINK_LIB_SHARED} DESTINATION ${STLINK_LIBRARY_PATH}) - +install(TARGETS ${STLINK_LIB_SHARED} + ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH} + LIBRARY DESTINATION ${STLINK_LIBRARY_PATH} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) ### # Static library From 553713d911e07fe6e02e907e2c9ab2b012f28d32 Mon Sep 17 00:00:00 2001 From: Biswapriyo Nath Date: Tue, 18 May 2021 19:47:33 +0530 Subject: [PATCH 1199/1435] win32: Fix socket fd type. --- src/win32/win32_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win32/win32_socket.c b/src/win32/win32_socket.c index 9138a7679..bfdcac5ce 100644 --- a/src/win32/win32_socket.c +++ b/src/win32/win32_socket.c @@ -70,7 +70,7 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) { if (rc > 0) { for ( i = 0; i < nfds; ++i) { - int fd = fds[i].fd; + SOCKET fd = fds[i].fd; if (fds[i].events & (POLLIN | POLLPRI) && FD_ISSET(fd, &ifds)) { fds[i].revents |= POLLIN; From a9adf9cb29d90af9d53c8adef673bcdc7d2490ae Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 18 May 2021 22:53:33 +0200 Subject: [PATCH 1200/1435] General Project Update - Updated CHANGELOG.md - Updated CI configs for macOS 11 & 10.14 --- .travis.yml | 34 +++++++++++++++++++++++++++++----- CHANGELOG.md | 10 ++++++---- doc/version_support.md | 4 ++-- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index c54c0c6f4..469094892 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,7 @@ jobs: - os: osx env: BADGE=osx - osx_image: xcode10.3 + osx_image: xcode10.3 # xcode11.3 to xcode11.3.1 fail to compile name: macOS 10.14.4 gcc compiler: gcc addons: @@ -42,7 +42,7 @@ jobs: - os: osx env: BADGE=osx - osx_image: xcode10.3 + osx_image: xcode10.3 # xcode11.3 to xcode11.3.1 fail to compile name: macOS 10.14.4 gcc 32-bit compiler: gcc addons: @@ -56,7 +56,7 @@ jobs: - os: osx env: BADGE=osx - osx_image: xcode10.3 + osx_image: xcode10.3 # xcode11.3 to xcode11.3.1 fail to compile name: macOS 10.14.4 clang compiler: clang addons: @@ -68,9 +68,9 @@ jobs: - os: osx env: BADGE=osx - osx_image: xcode10.3 + osx_image: xcode10.3 # xcode11.3 to xcode11.3.1 fail to compile name: macOS 10.14.4 clang 32-bit - compiler: gcc + compiler: clang addons: homebrew: packages: @@ -80,6 +80,30 @@ jobs: before_install: - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + - os: osx + env: BADGE=osx + osx_image: xcode12.5 + name: macOS 11.3 gcc + compiler: gcc + addons: + homebrew: + packages: + - gcc + - libusb + - gtk+3 + + - os: osx + env: BADGE=osx + osx_image: xcode12.5 + name: macOS 11.3 clang + compiler: clang + addons: + homebrew: + packages: + - clang + - libusb + - gtk+3 + script: - git fetch --tags - printenv diff --git a/CHANGELOG.md b/CHANGELOG.md index b43d58da7..5314ea912 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,8 +16,10 @@ Features: Updates & changes: - Added instructions for bug-reports and feature-requests to contribution guidelines ([#906](https://github.com/stlink-org/stlink/pull/906)) +- Added travis CI configuration for macOS 10.14 to maintain capability for 32-bit compilation ([#f5ada94](https://github.com/stlink-org/stlink/commit/f5ada9474cdb87ff37de0d4eb9e75622b5870646)) Fixes: +- cmake: Install shared libraries in proper directories ([#1142](https://github.com/stlink-org/stlink/pull/1142)) # v1.7.0 @@ -59,10 +61,10 @@ Updates & changes: Fixes: -- Improvements and fixes of the flash loaders, unification of the reset function ([#244](https://github.com/stlink-org/stlink/pull/244), [#382](https://github.com/stlink-org/stlink/pull/382), [#705](https://github.com/stlink-org/stlink/pull/705), [#980](https://github.com/stlink-org/stlink/pull/980), [#995](https://github.com/stlink-org/stlink/pull/995), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1115](https://github.com/stlink-org/stlink/pull/1115), [#1117](https://github.com/stlink-org/stlink/pull/1117), [#1122](https://github.com/stlink-org/stlink/pull/1122), [#1124](https://github.com/stlink-org/stlink/pull/1124)) -- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#807](https://github.com/stlink-org/stlink/pull/807), [#817](https://github.com/stlink-org/stlink/pull/817), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) +- Improvements and fixes of the flash loaders, unification of the reset function ([#244](https://github.com/stlink-org/stlink/pull/244), [#382](https://github.com/stlink-org/stlink/pull/382), [#705](https://github.com/stlink-org/stlink/pull/705), [#724](https://github.com/stlink-org/stlink/pull/724), [#980](https://github.com/stlink-org/stlink/pull/980), [#995](https://github.com/stlink-org/stlink/pull/995), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1115](https://github.com/stlink-org/stlink/pull/1115), [#1117](https://github.com/stlink-org/stlink/pull/1117), [#1122](https://github.com/stlink-org/stlink/pull/1122), [#1124](https://github.com/stlink-org/stlink/pull/1124)) +- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#724](https://github.com/stlink-org/stlink/pull/724), [#807](https://github.com/stlink-org/stlink/pull/807), [#817](https://github.com/stlink-org/stlink/pull/817), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) - Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106), [#1121](https://github.com/stlink-org/stlink/pull/1121)) -- Use vl flashloader for all STM32F1 series ([#769](https://github.com/stlink-org/stlink/pull/769), [#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) +- Use vl flashloader for all STM32F1 series ([#724](https://github.com/stlink-org/stlink/pull/724), [#769](https://github.com/stlink-org/stlink/pull/769), [#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) - cmake compile failure with external `CMAKE_MODULE_PATH` set ([#962](https://github.com/stlink-org/stlink/pull/962)) - doc/man: Fixed installation directory ([#970](https://github.com/stlink-org/stlink/pull/970)) @@ -264,7 +266,7 @@ Updates and fixes: - Debian packaging, `cmake` and `README.md` fixes ([#682](https://github.com/stlink-org/stlink/pull/682), [#683](https://github.com/stlink-org/stlink/pull/683)) - Disabled static library installation by default ([#702](https://github.com/stlink-org/stlink/pull/702)) - Fix for `libusb` deprecation ([#703](https://github.com/stlink-org/stlink/pull/703), [#704](https://github.com/stlink-org/stlink/pull/704)) -- Renamed `STLINK_CHIPID_STM32_L4R9` to `STLINK_CHIPID_STM32_L4RX` ([#706](https://github.com/stlink-org/stlink/pull/706)) +- Renamed `STLINK_CHIPID_STM32_L4R9` to `STLINK_CHIPID_STM32_L4Rx` ([#706](https://github.com/stlink-org/stlink/pull/706)) - [regression] stlink installation under Linux (Debian 9) is broken since #695 ([#700](https://github.com/stlink-org/stlink/pull/700), [#701](https://github.com/stlink-org/stlink/pull/701), [#707](https://github.com/stlink-org/stlink/pull/707)) - Fixed flash memory map for STM32F72xxx target ([#711](https://github.com/stlink-org/stlink/pull/711)) - Proper flash page size calculation for STM32F412xx target ([#721](https://github.com/stlink-org/stlink/pull/721)) diff --git a/doc/version_support.md b/doc/version_support.md index 6aafc8112..408c1be85 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -14,8 +14,8 @@ Up on compiling c-make will **automatically** download and install the latest co | Package Repository | libusb
      version | cmake
      version | gtk-3
      version | Supported macOS versions | | ------------------ | ------------------- | ------------------ | ------------------ | ------------------------ | -| homebrew | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3 | 10.9 - 10.15 | -| MacPorts | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | 10.4 - 10.15 | +| homebrew | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3 | 10.9 - 11.x | +| MacPorts | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | 10.4 - 11.x | NOTE: In order to use a STLINK/V1 programmer on macOS, versions 10.14 or 10.15 are required. From eafb4d17925296cf8c31f4309294c424d7174186 Mon Sep 17 00:00:00 2001 From: Jonathan Giles Date: Wed, 19 May 2021 10:40:40 -0400 Subject: [PATCH 1201/1435] Change description of chip id 0x0457 to L01x/L02x. --- src/stlink-lib/chipid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 13d065a27..711bf24b0 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -647,7 +647,7 @@ static const struct stlink_chipid_params devices[] = { { // STM32L011 .chip_id = STLINK_CHIPID_STM32_L011, - .description = "L011", + .description = "L01x/L02x", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, From 69239406344fbfe14b80af1cad8b91c3dea01950 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 21 May 2021 14:50:11 +0200 Subject: [PATCH 1202/1435] Corrected CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5314ea912..57ed15e98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,6 +89,7 @@ Fixes: - Fixed STM32WB55 reading DEBUG IDCODE from the wrong address ([#1100](https://github.com/stlink-org/stlink/pull/1100), [#1101](https://github.com/stlink-org/stlink/pull/1101)) - Applied missing changes to tests ([#1119](https://github.com/stlink-org/stlink/pull/1119)) - Improvements for Chip_ID read ([#1008](https://github.com/stlink-org/stlink/pull/1008), [#1120](https://github.com/stlink-org/stlink/pull/1120)) +- Fixed reading of chip ID on Cortex-M0+ core ([#1017](https://github.com/stlink-org/stlink/pull/1017), [#1125](https://github.com/stlink-org/stlink/pull/1125), [#1126](https://github.com/stlink-org/stlink/pull/1126), [#1133](https://github.com/stlink-org/stlink/pull/1133)) # v1.6.1 @@ -186,7 +187,6 @@ Fixes: - Set static link for `libssp` (stack-smashing protection) ([#960](https://github.com/stlink-org/stlink/pull/960), [#961](https://github.com/stlink-org/stlink/pull/961)) - Fixed udev rules installing to wrong directory ([#966](https://github.com/stlink-org/stlink/pull/966)) - Fixed formatting for options display in `st-flash` & `st-info` (commits [#c783d0e](https://github.com/stlink-org/stlink/commit/c783d0e777ccc83a7a8be26a4f4d3414e0478560) and [#562cd24](https://github.com/stlink-org/stlink/commit/562cd2496e696dbd22950925866aac662d81ee5f)) -- Fixed reading of chip ID on Cortex-M0+ core ([#1125](https://github.com/stlink-org/stlink/pull/1125), [#1126](https://github.com/stlink-org/stlink/pull/1126), [#1133](https://github.com/stlink-org/stlink/pull/1133)) # v1.6.0 From cab9fc4210ac090da6b7e45d91ffd300549a9436 Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 22 May 2021 23:40:36 +0500 Subject: [PATCH 1203/1435] Improved command error messages --- inc/stlink.h | 8 +- src/common.c | 3 - src/stlink-lib/usb.c | 238 +++++++++++++++---------------------------- 3 files changed, 88 insertions(+), 161 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 69a4799f5..f70060b05 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -86,6 +86,8 @@ enum target_state { /* Error code */ #define STLINK_DEBUG_ERR_OK 0x80 #define STLINK_DEBUG_ERR_FAULT 0x81 +#define STLINK_DEBUG_ERR_WRITE 0x0c +#define STLINK_DEBUG_ERR_WRITE_VERIFY 0x0d #define STLINK_DEBUG_ERR_AP_WAIT 0x10 #define STLINK_DEBUG_ERR_AP_FAULT 0x11 #define STLINK_DEBUG_ERR_AP_ERROR 0x12 @@ -93,8 +95,10 @@ enum target_state { #define STLINK_DEBUG_ERR_DP_FAULT 0x15 #define STLINK_DEBUG_ERR_DP_ERROR 0x16 -#define CMD_NO_RETRY 0 -#define CMD_USE_RETRY 3 +#define CMD_CHECK_NO 0 +#define CMD_CHECK_REP_LEN 1 +#define CMD_CHECK_STATUS 2 +#define CMD_CHECK_RETRY 3 /* check status and retry if wait error */ #define C_BUF_LEN 32 diff --git a/src/common.c b/src/common.c index 661ee34ec..6333ff408 100644 --- a/src/common.c +++ b/src/common.c @@ -2301,9 +2301,6 @@ static void stlink_checksum(mapped_file_t *mp) { static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { unsigned int val; - // set stack - stlink_read_debug32(sl, addr, &val); - stlink_write_reg(sl, val, 13); // set PC to the reset routine stlink_read_debug32(sl, addr + 4, &val); stlink_write_reg(sl, val, 15); diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 5e17189c6..a58681702 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -85,56 +85,62 @@ void _stlink_usb_close(stlink_t* sl) { ssize_t send_recv(struct stlink_libusb* handle, int terminate, unsigned char* txbuf, size_t txsize, unsigned char* rxbuf, - size_t rxsize, bool check_error, int retry_cnt) { + size_t rxsize, int check_error, const char *cmd) { // Note: txbuf and rxbuf can point to the same area int res, t, retry = 0; - int cmd = read_uint16(txbuf, (handle->protocoll == 1)?15:0); while (1) { res = 0; t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, (int)txsize, &res, 3000); if (t) { - ELOG("[!] send_recv send request failed: %s (command 0x%02X)\n", libusb_error_name(t), cmd); + ELOG("%s send request failed: %s\n", cmd, libusb_error_name(t)); return(-1); } else if ((size_t)res != txsize) { - ELOG("[!] send_recv send request wrote %u bytes, instead of %u (command 0x%02X)\n", - (unsigned int)res, (unsigned int)txsize, cmd); + ELOG("%s send request wrote %u bytes, instead of %u\n", + cmd, (unsigned int)res, (unsigned int)txsize); } if (rxsize != 0) { t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int)rxsize, &res, 3000); if (t) { - ELOG("[!] send_recv read reply failed: %s (command 0x%02X)\n", libusb_error_name(t), cmd); + ELOG("%s read reply failed: %s\n", cmd, libusb_error_name(t)); return(-1); } /* Checking the command execution status stored in the first byte of the response */ - if (handle->protocoll != 1 && check_error && + if (handle->protocoll != 1 && check_error >= CMD_CHECK_STATUS && rxbuf[0] != STLINK_DEBUG_ERR_OK) { switch(rxbuf[0]) { case STLINK_DEBUG_ERR_AP_WAIT: case STLINK_DEBUG_ERR_DP_WAIT: - if (retry < retry_cnt) { + if (check_error == CMD_CHECK_RETRY && retry < 3) { unsigned int delay_us = (1<protocoll == 1) && terminate) { @@ -143,7 +149,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, sg_buf, 13, &res, 3000); if (t) { - ELOG("[!] send_recv read storage failed: %s (command 0x%02X)\n", libusb_error_name(t), cmd); + ELOG("stlink: %s read storage failed: %s\n", cmd, libusb_error_name(t)); return(-1); } @@ -156,8 +162,9 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, } static inline int send_only(struct stlink_libusb* handle, int terminate, - unsigned char* txbuf, size_t txsize) { - return((int)send_recv(handle, terminate, txbuf, txsize, NULL, 0, false, CMD_NO_RETRY)); + unsigned char* txbuf, size_t txsize, + const char *cmd) { + return((int)send_recv(handle, terminate, txbuf, txsize, NULL, 0, CMD_CHECK_NO, cmd)); } @@ -201,12 +208,9 @@ int _stlink_usb_version(stlink_t *sl) { cmd[i++] = STLINK_GET_VERSION; } - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, false, CMD_USE_RETRY); - if (size != (ssize_t)rep_len) { - return((int)size); - } + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_REP_LEN, "GET_VERSION"); - return(0); + return(size<0?-1:0); } int32_t _stlink_usb_target_voltage(stlink_t *sl) { @@ -221,13 +225,10 @@ int32_t _stlink_usb_target_voltage(stlink_t *sl) { cmd[i++] = STLINK_GET_TARGET_VOLTAGE; - size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, false, CMD_NO_RETRY); + size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, CMD_CHECK_REP_LEN, "GET_TARGET_VOLTAGE"); if (size < 0) { return(-1); - } else if (size != 8) { - printf("[!] wrong length STLINK_GET_TARGET_VOLTAGE\n"); - return(-1); } factor = (rdata[3] << 24) | (rdata[2] << 16) | (rdata[1] << 8) | (rdata[0] << 0); @@ -248,10 +249,10 @@ int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_READDEBUGREG; write_uint32(&cmd[i], addr); - size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, true, CMD_USE_RETRY); + size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, CMD_CHECK_RETRY, "READDEBUGREG"); if (size < 0) { - return((int)size); + return(-1); } *data = read_uint32(rdata, 4); @@ -271,13 +272,9 @@ int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { cmd[i++] = STLINK_DEBUG_APIV2_WRITEDEBUGREG; write_uint32(&cmd[i], addr); write_uint32(&cmd[i + 4], data); - size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, true, CMD_USE_RETRY); + size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, CMD_CHECK_RETRY, "WRITEDEBUGREG"); - if (size < 0) { - return((int)size); - } - - return(0); + return(size<0?-1:0); } int _stlink_usb_get_rw_status(stlink_t *sl) { @@ -294,15 +291,13 @@ int _stlink_usb_get_rw_status(stlink_t *sl) { if (sl->version.flags & STLINK_F_HAS_GETLASTRWSTATUS2) { cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS2; - ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 12, true, CMD_NO_RETRY); + ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 12, CMD_CHECK_STATUS, "GETLASTRWSTATUS2"); } else { cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS; - ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 2, true, CMD_NO_RETRY); + ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 2, CMD_CHECK_STATUS, "GETLASTRWSTATUS"); } - if (ret < 0) { return(-1); } - - return(0); + return(ret<0?-1:0); } int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { @@ -316,11 +311,11 @@ int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { cmd[i++] = STLINK_DEBUG_WRITEMEM_32BIT; write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); - ret = send_only(slu, 0, cmd, slu->cmd_len); + ret = send_only(slu, 0, cmd, slu->cmd_len, "WRITEMEM_32BIT"); if (ret == -1) { return(ret); } - ret = send_only(slu, 1, data, len); + ret = send_only(slu, 1, data, len, "WRITEMEM_32BIT"); if (ret == -1) { return(ret); } @@ -338,11 +333,11 @@ int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { cmd[i++] = STLINK_DEBUG_WRITEMEM_8BIT; write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); - ret = send_only(slu, 0, cmd, slu->cmd_len); + ret = send_only(slu, 0, cmd, slu->cmd_len, "WRITEMEM_32BIT"); if (ret == -1) { return(ret); } - ret = send_only(slu, 1, data, len); + ret = send_only(slu, 1, data, len, "WRITEMEM_32BIT"); if (ret == -1) { return(ret); } @@ -359,7 +354,7 @@ int _stlink_usb_current_mode(stlink_t * sl) { 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, false, CMD_NO_RETRY); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_NO, "GET_CURRENT_MODE"); if (size < 0) { return(-1); @@ -386,7 +381,7 @@ int _stlink_usb_core_id(stlink_t * sl) { offset = 4; } - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_NO_RETRY); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "READ_IDCODES"); if (size < 0) { return(-1); @@ -431,15 +426,9 @@ int _stlink_usb_status(stlink_t * sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_GETSTATUS; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, false, CMD_NO_RETRY); - - if (size < 0) { - return((int)size); - } - - sl->q_len = (int)size; + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_NO, "GETSTATUS"); - if (sl->q_len > 1) { + if (size > 1) { if (sl->q_buf[0] == STLINK_CORE_RUNNING) { sl->core_stat = TARGET_RUNNING; } else if (sl->q_buf[0] == STLINK_CORE_HALTED) { @@ -451,7 +440,7 @@ int _stlink_usb_status(stlink_t * sl) { sl->core_stat = TARGET_UNKNOWN; } - return(0); + return(size<0?-1:0); } int _stlink_usb_force_debug(stlink_t *sl) { @@ -472,13 +461,9 @@ int _stlink_usb_force_debug(stlink_t *sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_FORCEDEBUG; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - - if (size < 0) { - return((int)size); - } + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "FORCEDEBUG"); - return(0); + return(size<0?-1:0); } int _stlink_usb_enter_swd_mode(stlink_t * sl) { @@ -493,13 +478,9 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { // select correct API-Version for entering SWD mode: V1 API (0x20) or V2 API (0x30). cmd[i++] = sl->version.jtag_api == STLINK_JTAG_API_V1 ? STLINK_DEBUG_APIV1_ENTER : STLINK_DEBUG_APIV2_ENTER; cmd[i++] = STLINK_DEBUG_ENTER_SWD; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - - if (size < 0) { - return((int)size); - } + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "ENTER_SWD"); - return(0); + return(size<0?-1:0); } int _stlink_usb_exit_dfu_mode(stlink_t* sl) { @@ -510,14 +491,9 @@ int _stlink_usb_exit_dfu_mode(stlink_t* sl) { cmd[i++] = STLINK_DFU_COMMAND; cmd[i++] = STLINK_DFU_EXIT; - size = send_only(slu, 1, cmd, slu->cmd_len); + size = send_only(slu, 1, cmd, slu->cmd_len, "DFU_EXIT"); - if (size == -1) { - printf("[!] send_recv STLINK_DFU_EXIT\n"); - return((int)size); - } - - return(0); + return(size<0?-1:0); } @@ -538,13 +514,9 @@ int _stlink_usb_reset(stlink_t * sl) { cmd[i++] = STLINK_DEBUG_APIV2_RESETSYS; } - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - - if (size < 0) { - return((int)size); - } + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "RESETSYS"); - return(0); + return(size<0?-1:0); } int _stlink_usb_jtag_reset(stlink_t * sl, int value) { @@ -558,13 +530,9 @@ int _stlink_usb_jtag_reset(stlink_t * sl, int value) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_DRIVE_NRST; cmd[i++] = value; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "DRIVE_NRST"); - if (size < 0) { - return((int)size); - } - - return(0); + return(size<0?-1:0); } @@ -589,13 +557,9 @@ int _stlink_usb_step(stlink_t* sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_STEPCORE; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "STEPCORE"); - if (size < 0) { - return((int)size); - } - - return(0); + return(size<0?-1:0); } /** @@ -624,13 +588,9 @@ int _stlink_usb_run(stlink_t* sl, enum run_type type) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_RUNCORE; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - - if (size < 0) { - return((int)size); - } + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "RUNCORE"); - return(0); + return(size<0?-1:0); } int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { @@ -671,13 +631,9 @@ int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { cmd[i++] = STLINK_DEBUG_APIV2_SWD_SET_FREQ; cmd[i++] = clk_divisor & 0xFF; cmd[i++] = (clk_divisor >> 8) & 0xFF; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - - if (size < 0) { - return((int)size); - } + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "SWD_SET_FREQ"); - return(0); + return(size<0?-1:0); } else if (sl->version.stlink_v == 3) { int speed_index; uint32_t map[STLINK_V3_MAX_FREQ_NB]; @@ -686,10 +642,10 @@ int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV3_GET_COM_FREQ; cmd[i++] = 0; // SWD mode - size = send_recv(slu, 1, cmd, slu->cmd_len, data, 52, true, CMD_NO_RETRY); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, 52, CMD_CHECK_STATUS, "GET_COM_FREQ"); if (size < 0) { - return((int)size); + return(-1); } int speeds_size = data[8]; @@ -716,13 +672,9 @@ int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { cmd[i++] = (uint8_t)((map[speed_index] >> 16) & 0xFF); cmd[i++] = (uint8_t)((map[speed_index] >> 24) & 0xFF); - size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8, true, CMD_NO_RETRY); - - if (size < 0) { - return((int)size); - } + size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8, CMD_CHECK_STATUS, "SET_COM_FREQ"); - return(0); + return(size<0?-1:0); } else if (clk_freq) { WLOG("ST-Link firmware does not support frequency setup\n"); } @@ -739,14 +691,9 @@ int _stlink_usb_exit_debug_mode(stlink_t *sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_EXIT; - size = send_only(slu, 1, cmd, slu->cmd_len); - - if (size == -1) { - printf("[!] send_only STLINK_DEBUG_EXIT\n"); - return((int)size); - } + size = send_only(slu, 1, cmd, slu->cmd_len, "DEBUG_EXIT"); - return(0); + return(size<0?-1:0); } int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { @@ -760,10 +707,10 @@ int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { cmd[i++] = STLINK_DEBUG_READMEM_32BIT; write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); - size = send_recv(slu, 1, cmd, slu->cmd_len, data, len, false, CMD_NO_RETRY); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, len, CMD_CHECK_NO, "READMEM_32BIT"); if (size < 0) { - return((int)size); + return(-1); } sl->q_len = (int)size; @@ -788,10 +735,10 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { cmd[i++] = STLINK_DEBUG_APIV2_READALLREGS; } - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_NO_RETRY); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "READALLREGS"); if (size < 0) { - return((int)size); + return(-1); } /* V1: regs data from offset 0 */ @@ -838,10 +785,10 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { } cmd[i++] = (uint8_t)r_idx; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "READREG"); if (size < 0) { - return((int)size); + return(-1); } sl->q_len = (int)size; @@ -1004,16 +951,9 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { cmd[i++] = idx; write_uint32(&cmd[i], reg); - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_USE_RETRY); - - if (size < 0) { - return((int)size); - } + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "WRITEREG"); - sl->q_len = (int)size; - stlink_print_data(sl); - - return(0); + return(size<0?-1:0); } int _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { @@ -1029,16 +969,9 @@ int _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { write_uint16(&cmd[i + 0], 2 * STLINK_TRACE_BUF_LEN); write_uint32(&cmd[i + 2], frequency); - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_NO_RETRY); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "START_TRACE_RX"); - if (size < 0) { - return((int)size); - } - - sl->q_len = (int)size; - stlink_print_data(sl); - - return(0); + return(size<0?-1:0); } int _stlink_usb_disable_trace(stlink_t* sl) { @@ -1052,16 +985,9 @@ int _stlink_usb_disable_trace(stlink_t* sl) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_STOP_TRACE_RX; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, true, CMD_NO_RETRY); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "STOP_TRACE_RX"); - if (size < 0) { - return((int)size); - } - - sl->q_len = (int)size; - stlink_print_data(sl); - - return(0); + return(size<0?-1:0); } int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { @@ -1073,13 +999,13 @@ int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_GET_TRACE_NB; - ssize_t send_size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, false, CMD_NO_RETRY); + ssize_t send_size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_NO, "GET_TRACE_NB"); if (send_size < 0) { - return((int)send_size); + return(-1); } else if (send_size != 2) { ELOG("STLINK_DEBUG_APIV2_GET_TRACE_NB reply size %d\n", (int)send_size); - return -1; + return(-1); } uint16_t trace_count = read_uint16(sl->q_buf, 0); From 90887edb2eef946d3bd0bda7769a95c076667f7b Mon Sep 17 00:00:00 2001 From: "R.E. Wolff" Date: Sun, 23 May 2021 08:42:36 +0200 Subject: [PATCH 1204/1435] removed debug dump --- src/stlink-lib/chipid.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 51da33322..02f117416 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -806,6 +806,7 @@ struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { p2 = stlink_chipid_get_params_old (chipid); +#if 1 if (memcmp (p2, params, sizeof (struct stlink_chipid_params) - sizeof (struct stlink_chipid_params *)) != 0) { //fprintf (stderr, "Error, chipid params not identical\n"); //return NULL; @@ -814,6 +815,7 @@ struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { fprintf (stderr, "---------- new ------------\n"); dump_a_chip (stderr, params); } +#endif return(params); } From d5b901b89957641a46ef4865620f989bf94e01d6 Mon Sep 17 00:00:00 2001 From: "R.E. Wolff" Date: Sun, 23 May 2021 08:52:36 +0200 Subject: [PATCH 1205/1435] removed filename-spaces --- config/chips/{F0xx small.chip => F0xx_small.chip} | 0 config/chips/{F1 XL-density.chip => F1_XL-density.chip} | 0 .../{F1 connectivity line.chip => F1_connectivity_line.chip} | 0 config/chips/{F1 high-density.chip => F1_high-density.chip} | 0 config/chips/{F1 low-density.chip => F1_low-density.chip} | 0 config/chips/{F1 medium-density.chip => F1_medium-density.chip} | 0 config/chips/{F1 value line.chip => F1_value_line.chip} | 0 ...lue line high-density.chip => F1_value_line_high-density.chip} | 0 config/chips/{F303 high density.chip => F303_high_density.chip} | 0 .../chips/{F334 medium density.chip => F334_medium_density.chip} | 0 ...{F4xx dynamic efficiency.chip => F4xx_dynamic_efficiency.chip} | 0 config/chips/{F4xx low power.chip => F4xx_low_power.chip} | 0 config/chips/{G4 cat2.chip => G4_cat2.chip} | 0 config/chips/{G4 cat3.chip => G4_cat3.chip} | 0 config/chips/{L0xx cat2.chip => L0xx_cat2.chip} | 0 config/chips/{L0xx cat5.chip => L0xx_cat5.chip} | 0 config/chips/{L1xx cat2.chip => L1xx_cat2.chip} | 0 config/chips/{L1xx high-density.chip => L1xx_high-density.chip} | 0 .../chips/{L1xx medium-density.chip => L1xx_medium-density.chip} | 0 ...1xx medium-plus-density.chip => L1xx_medium-plus-density.chip} | 0 config/chips/{unknown device.chip => unknown_device.chip} | 0 21 files changed, 0 insertions(+), 0 deletions(-) rename config/chips/{F0xx small.chip => F0xx_small.chip} (100%) rename config/chips/{F1 XL-density.chip => F1_XL-density.chip} (100%) rename config/chips/{F1 connectivity line.chip => F1_connectivity_line.chip} (100%) rename config/chips/{F1 high-density.chip => F1_high-density.chip} (100%) rename config/chips/{F1 low-density.chip => F1_low-density.chip} (100%) rename config/chips/{F1 medium-density.chip => F1_medium-density.chip} (100%) rename config/chips/{F1 value line.chip => F1_value_line.chip} (100%) rename config/chips/{F1 value line high-density.chip => F1_value_line_high-density.chip} (100%) rename config/chips/{F303 high density.chip => F303_high_density.chip} (100%) rename config/chips/{F334 medium density.chip => F334_medium_density.chip} (100%) rename config/chips/{F4xx dynamic efficiency.chip => F4xx_dynamic_efficiency.chip} (100%) rename config/chips/{F4xx low power.chip => F4xx_low_power.chip} (100%) rename config/chips/{G4 cat2.chip => G4_cat2.chip} (100%) rename config/chips/{G4 cat3.chip => G4_cat3.chip} (100%) rename config/chips/{L0xx cat2.chip => L0xx_cat2.chip} (100%) rename config/chips/{L0xx cat5.chip => L0xx_cat5.chip} (100%) rename config/chips/{L1xx cat2.chip => L1xx_cat2.chip} (100%) rename config/chips/{L1xx high-density.chip => L1xx_high-density.chip} (100%) rename config/chips/{L1xx medium-density.chip => L1xx_medium-density.chip} (100%) rename config/chips/{L1xx medium-plus-density.chip => L1xx_medium-plus-density.chip} (100%) rename config/chips/{unknown device.chip => unknown_device.chip} (100%) diff --git a/config/chips/F0xx small.chip b/config/chips/F0xx_small.chip similarity index 100% rename from config/chips/F0xx small.chip rename to config/chips/F0xx_small.chip diff --git a/config/chips/F1 XL-density.chip b/config/chips/F1_XL-density.chip similarity index 100% rename from config/chips/F1 XL-density.chip rename to config/chips/F1_XL-density.chip diff --git a/config/chips/F1 connectivity line.chip b/config/chips/F1_connectivity_line.chip similarity index 100% rename from config/chips/F1 connectivity line.chip rename to config/chips/F1_connectivity_line.chip diff --git a/config/chips/F1 high-density.chip b/config/chips/F1_high-density.chip similarity index 100% rename from config/chips/F1 high-density.chip rename to config/chips/F1_high-density.chip diff --git a/config/chips/F1 low-density.chip b/config/chips/F1_low-density.chip similarity index 100% rename from config/chips/F1 low-density.chip rename to config/chips/F1_low-density.chip diff --git a/config/chips/F1 medium-density.chip b/config/chips/F1_medium-density.chip similarity index 100% rename from config/chips/F1 medium-density.chip rename to config/chips/F1_medium-density.chip diff --git a/config/chips/F1 value line.chip b/config/chips/F1_value_line.chip similarity index 100% rename from config/chips/F1 value line.chip rename to config/chips/F1_value_line.chip diff --git a/config/chips/F1 value line high-density.chip b/config/chips/F1_value_line_high-density.chip similarity index 100% rename from config/chips/F1 value line high-density.chip rename to config/chips/F1_value_line_high-density.chip diff --git a/config/chips/F303 high density.chip b/config/chips/F303_high_density.chip similarity index 100% rename from config/chips/F303 high density.chip rename to config/chips/F303_high_density.chip diff --git a/config/chips/F334 medium density.chip b/config/chips/F334_medium_density.chip similarity index 100% rename from config/chips/F334 medium density.chip rename to config/chips/F334_medium_density.chip diff --git a/config/chips/F4xx dynamic efficiency.chip b/config/chips/F4xx_dynamic_efficiency.chip similarity index 100% rename from config/chips/F4xx dynamic efficiency.chip rename to config/chips/F4xx_dynamic_efficiency.chip diff --git a/config/chips/F4xx low power.chip b/config/chips/F4xx_low_power.chip similarity index 100% rename from config/chips/F4xx low power.chip rename to config/chips/F4xx_low_power.chip diff --git a/config/chips/G4 cat2.chip b/config/chips/G4_cat2.chip similarity index 100% rename from config/chips/G4 cat2.chip rename to config/chips/G4_cat2.chip diff --git a/config/chips/G4 cat3.chip b/config/chips/G4_cat3.chip similarity index 100% rename from config/chips/G4 cat3.chip rename to config/chips/G4_cat3.chip diff --git a/config/chips/L0xx cat2.chip b/config/chips/L0xx_cat2.chip similarity index 100% rename from config/chips/L0xx cat2.chip rename to config/chips/L0xx_cat2.chip diff --git a/config/chips/L0xx cat5.chip b/config/chips/L0xx_cat5.chip similarity index 100% rename from config/chips/L0xx cat5.chip rename to config/chips/L0xx_cat5.chip diff --git a/config/chips/L1xx cat2.chip b/config/chips/L1xx_cat2.chip similarity index 100% rename from config/chips/L1xx cat2.chip rename to config/chips/L1xx_cat2.chip diff --git a/config/chips/L1xx high-density.chip b/config/chips/L1xx_high-density.chip similarity index 100% rename from config/chips/L1xx high-density.chip rename to config/chips/L1xx_high-density.chip diff --git a/config/chips/L1xx medium-density.chip b/config/chips/L1xx_medium-density.chip similarity index 100% rename from config/chips/L1xx medium-density.chip rename to config/chips/L1xx_medium-density.chip diff --git a/config/chips/L1xx medium-plus-density.chip b/config/chips/L1xx_medium-plus-density.chip similarity index 100% rename from config/chips/L1xx medium-plus-density.chip rename to config/chips/L1xx_medium-plus-density.chip diff --git a/config/chips/unknown device.chip b/config/chips/unknown_device.chip similarity index 100% rename from config/chips/unknown device.chip rename to config/chips/unknown_device.chip From 157c587b93fb8e0f46696610b6f78d4a24609ef9 Mon Sep 17 00:00:00 2001 From: "R.E. Wolff" Date: Sun, 23 May 2021 10:50:43 +0200 Subject: [PATCH 1206/1435] cleanup integer handling in chipid and text flags --- config/chips/F04x.chip | 14 ++--- config/chips/F07x.chip | 14 ++--- config/chips/F09x.chip | 14 ++--- config/chips/F0xx.chip | 14 ++--- config/chips/F0xx_small.chip | 14 ++--- config/chips/F1_XL-density.chip | 14 ++--- config/chips/F1_connectivity_line.chip | 14 ++--- config/chips/F1_high-density.chip | 14 ++--- config/chips/F1_low-density.chip | 14 ++--- config/chips/F1_medium-density.chip | 14 ++--- config/chips/F1_value_line.chip | 14 ++--- config/chips/F1_value_line_high-density.chip | 14 ++--- config/chips/F2.chip | 14 ++--- config/chips/F303_high_density.chip | 14 ++--- config/chips/F334_medium_density.chip | 14 ++--- config/chips/F37x.chip | 14 ++--- config/chips/F3xx_small.chip | 14 ++--- config/chips/F410.chip | 14 ++--- config/chips/F411xx.chip | 14 ++--- config/chips/F412.chip | 14 ++--- config/chips/F413.chip | 14 ++--- config/chips/F42x_F43x.chip | 14 ++--- config/chips/F446.chip | 14 ++--- config/chips/F46x_F47x.chip | 14 ++--- config/chips/F4xx.chip | 14 ++--- config/chips/F4xx_dynamic_efficiency.chip | 14 ++--- config/chips/F4xx_low_power.chip | 14 ++--- config/chips/F72x_F73x.chip | 14 ++--- config/chips/F76xxx.chip | 14 ++--- config/chips/F7xx.chip | 14 ++--- config/chips/G030_G031_G041.chip | 14 ++--- config/chips/G070_G071_G081.chip | 14 ++--- config/chips/G4_cat2.chip | 14 ++--- config/chips/G4_cat3.chip | 14 ++--- config/chips/H72x_H73x.chip | 16 +++--- config/chips/H74x_H75x.chip | 16 +++--- config/chips/H7Ax_H7Bx.chip | 16 +++--- config/chips/L011.chip | 14 ++--- config/chips/L0x3.chip | 16 +++--- config/chips/L0xx_cat2.chip | 14 ++--- config/chips/L0xx_cat5.chip | 14 ++--- config/chips/L152RE.chip | 14 ++--- config/chips/L1xx_cat2.chip | 14 ++--- config/chips/L1xx_high-density.chip | 14 ++--- config/chips/L1xx_medium-density.chip | 14 ++--- config/chips/L1xx_medium-plus-density.chip | 14 ++--- config/chips/L41x.chip | 14 ++--- config/chips/L43x_L44x.chip | 14 ++--- config/chips/L45x_L46x.chip | 14 ++--- config/chips/L496x_L4A6x.chip | 14 ++--- config/chips/L4Rx.chip | 14 ++--- config/chips/L4xx.chip | 14 ++--- config/chips/WB55.chip | 14 ++--- config/chips/unknown_device.chip | 14 ++--- src/stlink-lib/chipid.c | 56 +++++++++++++------- 55 files changed, 418 insertions(+), 402 deletions(-) diff --git a/config/chips/F04x.chip b/config/chips/F04x.chip index 059ae5bc6..b42d420fa 100644 --- a/config/chips/F04x.chip +++ b/config/chips/F04x.chip @@ -1,13 +1,13 @@ # Chip-ID file for F04x # -chip_id 445 +chip_id 0x445 description F04x flash_type 1 flash_pagesize 400 -sram_size 1800 -bootrom_base 1fffec00 -bootrom_size c00 -option_base 0 -option_size 0 -flags 0 +sram_size 0x1800 +bootrom_base 0x1fffec00 +bootrom_size 0xc00 +option_base 0x0 +option_size 0x0 +flags none diff --git a/config/chips/F07x.chip b/config/chips/F07x.chip index ba839baed..d8c71f0ea 100644 --- a/config/chips/F07x.chip +++ b/config/chips/F07x.chip @@ -1,13 +1,13 @@ # Chip-ID file for F07x # -chip_id 448 +chip_id 0x448 description F07x flash_type 1 flash_pagesize 800 -sram_size 4000 -bootrom_base 1fffc800 -bootrom_size 3000 -option_base 0 -option_size 0 -flags 0 +sram_size 0x4000 +bootrom_base 0x1fffc800 +bootrom_size 0x3000 +option_base 0x0 +option_size 0x0 +flags none diff --git a/config/chips/F09x.chip b/config/chips/F09x.chip index 727fc1fa4..ca97d53e4 100644 --- a/config/chips/F09x.chip +++ b/config/chips/F09x.chip @@ -1,13 +1,13 @@ # Chip-ID file for F09x # -chip_id 442 +chip_id 0x442 description F09x flash_type 1 flash_pagesize 800 -sram_size 8000 -bootrom_base 1fffd800 -bootrom_size 2000 -option_base 0 -option_size 0 -flags 0 +sram_size 0x8000 +bootrom_base 0x1fffd800 +bootrom_size 0x2000 +option_base 0x0 +option_size 0x0 +flags none diff --git a/config/chips/F0xx.chip b/config/chips/F0xx.chip index 9c0f60bd9..a1700eef3 100644 --- a/config/chips/F0xx.chip +++ b/config/chips/F0xx.chip @@ -1,13 +1,13 @@ # Chip-ID file for F0xx # -chip_id 440 +chip_id 0x440 description F0xx flash_type 1 flash_pagesize 400 -sram_size 2000 -bootrom_base 1fffec00 -bootrom_size c00 -option_base 0 -option_size 0 -flags 0 +sram_size 0x2000 +bootrom_base 0x1fffec00 +bootrom_size 0xc00 +option_base 0x0 +option_size 0x0 +flags none diff --git a/config/chips/F0xx_small.chip b/config/chips/F0xx_small.chip index efa51c284..3ab256feb 100644 --- a/config/chips/F0xx_small.chip +++ b/config/chips/F0xx_small.chip @@ -1,13 +1,13 @@ # Chip-ID file for F0xx small # -chip_id 444 +chip_id 0x444 description F0xx small flash_type 1 flash_pagesize 400 -sram_size 1000 -bootrom_base 1fffec00 -bootrom_size c00 -option_base 0 -option_size 0 -flags 0 +sram_size 0x1000 +bootrom_base 0x1fffec00 +bootrom_size 0xc00 +option_base 0x0 +option_size 0x0 +flags none diff --git a/config/chips/F1_XL-density.chip b/config/chips/F1_XL-density.chip index 70cdfd3bb..97bb580e3 100644 --- a/config/chips/F1_XL-density.chip +++ b/config/chips/F1_XL-density.chip @@ -1,13 +1,13 @@ # Chip-ID file for F1 XL-density # -chip_id 430 +chip_id 0x430 description F1 XL-density flash_type 2 flash_pagesize 800 -sram_size 18000 -bootrom_base 1fffe000 -bootrom_size 1800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x18000 +bootrom_base 0x1fffe000 +bootrom_size 0x1800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F1_connectivity_line.chip b/config/chips/F1_connectivity_line.chip index 14678112d..a030fd58d 100644 --- a/config/chips/F1_connectivity_line.chip +++ b/config/chips/F1_connectivity_line.chip @@ -1,13 +1,13 @@ # Chip-ID file for F1 connectivity line # -chip_id 418 +chip_id 0x418 description F1 connectivity line flash_type 1 flash_pagesize 800 -sram_size 10000 -bootrom_base 1fffb000 -bootrom_size 4800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x10000 +bootrom_base 0x1fffb000 +bootrom_size 0x4800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F1_high-density.chip b/config/chips/F1_high-density.chip index 3d4cff724..00e4942b0 100644 --- a/config/chips/F1_high-density.chip +++ b/config/chips/F1_high-density.chip @@ -1,13 +1,13 @@ # Chip-ID file for F1 high-density # -chip_id 414 +chip_id 0x414 description F1 high-density flash_type 1 flash_pagesize 800 -sram_size 10000 -bootrom_base 1ffff000 -bootrom_size 800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x10000 +bootrom_base 0x1ffff000 +bootrom_size 0x800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F1_low-density.chip b/config/chips/F1_low-density.chip index 9905ce405..1562c7589 100644 --- a/config/chips/F1_low-density.chip +++ b/config/chips/F1_low-density.chip @@ -1,13 +1,13 @@ # Chip-ID file for F1 low-density # -chip_id 412 +chip_id 0x412 description F1 low-density flash_type 1 flash_pagesize 400 -sram_size 2800 -bootrom_base 1ffff000 -bootrom_size 800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x2800 +bootrom_base 0x1ffff000 +bootrom_size 0x800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F1_medium-density.chip b/config/chips/F1_medium-density.chip index 00af4f18d..1f3d89234 100644 --- a/config/chips/F1_medium-density.chip +++ b/config/chips/F1_medium-density.chip @@ -1,13 +1,13 @@ # Chip-ID file for F1 medium-density # -chip_id 410 +chip_id 0x410 description F1 medium-density flash_type 1 flash_pagesize 400 -sram_size 5000 -bootrom_base 1ffff000 -bootrom_size 800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x5000 +bootrom_base 0x1ffff000 +bootrom_size 0x800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F1_value_line.chip b/config/chips/F1_value_line.chip index 8356357b0..d9f04f00a 100644 --- a/config/chips/F1_value_line.chip +++ b/config/chips/F1_value_line.chip @@ -1,13 +1,13 @@ # Chip-ID file for F1 value line # -chip_id 420 +chip_id 0x420 description F1 value line flash_type 1 flash_pagesize 400 -sram_size 2000 -bootrom_base 1ffff000 -bootrom_size 800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x2000 +bootrom_base 0x1ffff000 +bootrom_size 0x800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F1_value_line_high-density.chip b/config/chips/F1_value_line_high-density.chip index c076e284c..2ecf6b4f5 100644 --- a/config/chips/F1_value_line_high-density.chip +++ b/config/chips/F1_value_line_high-density.chip @@ -1,13 +1,13 @@ # Chip-ID file for F1 value line high-density # -chip_id 428 +chip_id 0x428 description F1 value line high-density flash_type 1 flash_pagesize 800 -sram_size 8000 -bootrom_base 1ffff000 -bootrom_size 800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x8000 +bootrom_base 0x1ffff000 +bootrom_size 0x800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F2.chip b/config/chips/F2.chip index 8830363d2..098ddc863 100644 --- a/config/chips/F2.chip +++ b/config/chips/F2.chip @@ -1,13 +1,13 @@ # Chip-ID file for F2 # -chip_id 411 +chip_id 0x411 description F2 flash_type 3 flash_pagesize 20000 -sram_size 20000 -bootrom_base 1fff0000 -bootrom_size 7800 -option_base 1fffc000 -option_size 4 -flags 2 +sram_size 0x20000 +bootrom_base 0x1fff0000 +bootrom_size 0x7800 +option_base 0x1fffc000 +option_size 0x4 +flags swo diff --git a/config/chips/F303_high_density.chip b/config/chips/F303_high_density.chip index e8b57ee24..19cc2ad2a 100644 --- a/config/chips/F303_high_density.chip +++ b/config/chips/F303_high_density.chip @@ -1,13 +1,13 @@ # Chip-ID file for F303 high density # -chip_id 446 +chip_id 0x446 description F303 high density flash_type 1 flash_pagesize 800 -sram_size 10000 -bootrom_base 1fffd800 -bootrom_size 2000 -option_base 0 -option_size 0 -flags 2 +sram_size 0x10000 +bootrom_base 0x1fffd800 +bootrom_size 0x2000 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F334_medium_density.chip b/config/chips/F334_medium_density.chip index 460e22a67..ba4cf9688 100644 --- a/config/chips/F334_medium_density.chip +++ b/config/chips/F334_medium_density.chip @@ -1,13 +1,13 @@ # Chip-ID file for F334 medium density # -chip_id 438 +chip_id 0x438 description F334 medium density flash_type 1 flash_pagesize 800 -sram_size 3000 -bootrom_base 1fffd800 -bootrom_size 2000 -option_base 0 -option_size 0 -flags 2 +sram_size 0x3000 +bootrom_base 0x1fffd800 +bootrom_size 0x2000 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F37x.chip b/config/chips/F37x.chip index 424209a03..d0081e68a 100644 --- a/config/chips/F37x.chip +++ b/config/chips/F37x.chip @@ -1,13 +1,13 @@ # Chip-ID file for F37x # -chip_id 432 +chip_id 0x432 description F37x flash_type 1 flash_pagesize 800 -sram_size a000 -bootrom_base 1ffff000 -bootrom_size 800 -option_base 0 -option_size 0 -flags 2 +sram_size 0xa000 +bootrom_base 0x1ffff000 +bootrom_size 0x800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F3xx_small.chip b/config/chips/F3xx_small.chip index 91722905c..34d1940ac 100644 --- a/config/chips/F3xx_small.chip +++ b/config/chips/F3xx_small.chip @@ -1,13 +1,13 @@ # Chip-ID file for F3xx small # -chip_id 439 +chip_id 0x439 description F3xx small flash_type 1 flash_pagesize 800 -sram_size a000 -bootrom_base 1fffd800 -bootrom_size 2000 -option_base 0 -option_size 0 -flags 2 +sram_size 0xa000 +bootrom_base 0x1fffd800 +bootrom_size 0x2000 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F410.chip b/config/chips/F410.chip index 53f01c669..3cd382845 100644 --- a/config/chips/F410.chip +++ b/config/chips/F410.chip @@ -1,13 +1,13 @@ # Chip-ID file for F410 # -chip_id 458 +chip_id 0x458 description F410 flash_type 3 flash_pagesize 4000 -sram_size 8000 -bootrom_base 1fff0000 -bootrom_size 7800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x8000 +bootrom_base 0x1fff0000 +bootrom_size 0x7800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F411xx.chip b/config/chips/F411xx.chip index 26390d0e6..301e6cb91 100644 --- a/config/chips/F411xx.chip +++ b/config/chips/F411xx.chip @@ -1,13 +1,13 @@ # Chip-ID file for F411xx # -chip_id 431 +chip_id 0x431 description F411xx flash_type 3 flash_pagesize 4000 -sram_size 20000 -bootrom_base 1fff0000 -bootrom_size 7800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x20000 +bootrom_base 0x1fff0000 +bootrom_size 0x7800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F412.chip b/config/chips/F412.chip index e78b81ee1..186a43427 100644 --- a/config/chips/F412.chip +++ b/config/chips/F412.chip @@ -1,13 +1,13 @@ # Chip-ID file for F412 # -chip_id 441 +chip_id 0x441 description F412 flash_type 3 flash_pagesize 4000 -sram_size 40000 -bootrom_base 1fff0000 -bootrom_size 7800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x40000 +bootrom_base 0x1fff0000 +bootrom_size 0x7800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F413.chip b/config/chips/F413.chip index 4ea974f2c..367344aaa 100644 --- a/config/chips/F413.chip +++ b/config/chips/F413.chip @@ -1,13 +1,13 @@ # Chip-ID file for F413 # -chip_id 463 +chip_id 0x463 description F413 flash_type 3 flash_pagesize 4000 -sram_size 50000 -bootrom_base 1fff0000 -bootrom_size 7800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x50000 +bootrom_base 0x1fff0000 +bootrom_size 0x7800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F42x_F43x.chip b/config/chips/F42x_F43x.chip index 2073486cf..4557a731c 100644 --- a/config/chips/F42x_F43x.chip +++ b/config/chips/F42x_F43x.chip @@ -1,13 +1,13 @@ # Chip-ID file for F42x/F43x # -chip_id 419 +chip_id 0x419 description F42x/F43x flash_type 3 flash_pagesize 4000 -sram_size 40000 -bootrom_base 1fff0000 -bootrom_size 7800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x40000 +bootrom_base 0x1fff0000 +bootrom_size 0x7800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F446.chip b/config/chips/F446.chip index 7d2ded465..9f7ae0bc5 100644 --- a/config/chips/F446.chip +++ b/config/chips/F446.chip @@ -1,13 +1,13 @@ # Chip-ID file for F446 # -chip_id 421 +chip_id 0x421 description F446 flash_type 3 flash_pagesize 20000 -sram_size 20000 -bootrom_base 1fff0000 -bootrom_size 7800 -option_base 1fffc000 -option_size 4 -flags 2 +sram_size 0x20000 +bootrom_base 0x1fff0000 +bootrom_size 0x7800 +option_base 0x1fffc000 +option_size 0x4 +flags swo diff --git a/config/chips/F46x_F47x.chip b/config/chips/F46x_F47x.chip index 75e1ea045..8ae43eb2e 100644 --- a/config/chips/F46x_F47x.chip +++ b/config/chips/F46x_F47x.chip @@ -1,13 +1,13 @@ # Chip-ID file for F46x/F47x # -chip_id 434 +chip_id 0x434 description F46x/F47x flash_type 3 flash_pagesize 4000 -sram_size 40000 -bootrom_base 1fff0000 -bootrom_size 7800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x40000 +bootrom_base 0x1fff0000 +bootrom_size 0x7800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F4xx.chip b/config/chips/F4xx.chip index 70f298b79..17ec62d68 100644 --- a/config/chips/F4xx.chip +++ b/config/chips/F4xx.chip @@ -1,13 +1,13 @@ # Chip-ID file for F4xx # -chip_id 413 +chip_id 0x413 description F4xx flash_type 3 flash_pagesize 4000 -sram_size 30000 -bootrom_base 1fff0000 -bootrom_size 7800 -option_base 40023c14 -option_size 4 -flags 2 +sram_size 0x30000 +bootrom_base 0x1fff0000 +bootrom_size 0x7800 +option_base 0x40023c14 +option_size 0x4 +flags swo diff --git a/config/chips/F4xx_dynamic_efficiency.chip b/config/chips/F4xx_dynamic_efficiency.chip index 33bfa23c2..6d06bcb8e 100644 --- a/config/chips/F4xx_dynamic_efficiency.chip +++ b/config/chips/F4xx_dynamic_efficiency.chip @@ -1,13 +1,13 @@ # Chip-ID file for F4xx dynamic efficiency # -chip_id 433 +chip_id 0x433 description F4xx dynamic efficiency flash_type 3 flash_pagesize 4000 -sram_size 18000 -bootrom_base 1fff0000 -bootrom_size 7800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x18000 +bootrom_base 0x1fff0000 +bootrom_size 0x7800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F4xx_low_power.chip b/config/chips/F4xx_low_power.chip index f52595d5d..ad8c3ce90 100644 --- a/config/chips/F4xx_low_power.chip +++ b/config/chips/F4xx_low_power.chip @@ -1,13 +1,13 @@ # Chip-ID file for F4xx low power # -chip_id 423 +chip_id 0x423 description F4xx low power flash_type 3 flash_pagesize 4000 -sram_size 10000 -bootrom_base 1fff0000 -bootrom_size 7800 -option_base 0 -option_size 0 -flags 2 +sram_size 0x10000 +bootrom_base 0x1fff0000 +bootrom_size 0x7800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F72x_F73x.chip b/config/chips/F72x_F73x.chip index ba275bb0b..b6f706994 100644 --- a/config/chips/F72x_F73x.chip +++ b/config/chips/F72x_F73x.chip @@ -1,13 +1,13 @@ # Chip-ID file for F72x/F73x # -chip_id 452 +chip_id 0x452 description F72x/F73x flash_type 3 flash_pagesize 800 -sram_size 40000 -bootrom_base 100000 -bootrom_size edc0 -option_base 0 -option_size 0 -flags 2 +sram_size 0x40000 +bootrom_base 0x100000 +bootrom_size 0xedc0 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F76xxx.chip b/config/chips/F76xxx.chip index 7f8cfdaf0..49ac1ec21 100644 --- a/config/chips/F76xxx.chip +++ b/config/chips/F76xxx.chip @@ -1,13 +1,13 @@ # Chip-ID file for F76xxx # -chip_id 451 +chip_id 0x451 description F76xxx flash_type 4 flash_pagesize 800 -sram_size 80000 -bootrom_base 200000 -bootrom_size edc0 -option_base 1fff0000 -option_size 20 -flags 2 +sram_size 0x80000 +bootrom_base 0x200000 +bootrom_size 0xedc0 +option_base 0x1fff0000 +option_size 0x20 +flags swo diff --git a/config/chips/F7xx.chip b/config/chips/F7xx.chip index c031b5f4a..87420f2ab 100644 --- a/config/chips/F7xx.chip +++ b/config/chips/F7xx.chip @@ -1,13 +1,13 @@ # Chip-ID file for F7xx # -chip_id 449 +chip_id 0x449 description F7xx flash_type 3 flash_pagesize 800 -sram_size 50000 -bootrom_base 100000 -bootrom_size edc0 -option_base 0 -option_size 0 -flags 2 +sram_size 0x50000 +bootrom_base 0x100000 +bootrom_size 0xedc0 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/G030_G031_G041.chip b/config/chips/G030_G031_G041.chip index a1c42f58f..7d47e7aed 100644 --- a/config/chips/G030_G031_G041.chip +++ b/config/chips/G030_G031_G041.chip @@ -1,13 +1,13 @@ # Chip-ID file for G030/G031/G041 # -chip_id 466 +chip_id 0x466 description G030/G031/G041 flash_type 7 flash_pagesize 800 -sram_size 2000 -bootrom_base 1fff0000 -bootrom_size 2000 -option_base 1fff7800 -option_size 4 -flags 0 +sram_size 0x2000 +bootrom_base 0x1fff0000 +bootrom_size 0x2000 +option_base 0x1fff7800 +option_size 0x4 +flags none diff --git a/config/chips/G070_G071_G081.chip b/config/chips/G070_G071_G081.chip index 58eb16b16..9905fc682 100644 --- a/config/chips/G070_G071_G081.chip +++ b/config/chips/G070_G071_G081.chip @@ -1,13 +1,13 @@ # Chip-ID file for G070/G071/G081 # -chip_id 460 +chip_id 0x460 description G070/G071/G081 flash_type 7 flash_pagesize 800 -sram_size 9000 -bootrom_base 1fff0000 -bootrom_size 7000 -option_base 1fff7800 -option_size 4 -flags 0 +sram_size 0x9000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x1fff7800 +option_size 0x4 +flags none diff --git a/config/chips/G4_cat2.chip b/config/chips/G4_cat2.chip index 309cbb83f..47745e715 100644 --- a/config/chips/G4_cat2.chip +++ b/config/chips/G4_cat2.chip @@ -1,13 +1,13 @@ # Chip-ID file for G4 cat2 # -chip_id 468 +chip_id 0x468 description G4 cat2 flash_type 8 flash_pagesize 800 -sram_size 8000 -bootrom_base 1fff0000 -bootrom_size 7000 -option_base 1ffff800 -option_size 4 -flags 2 +sram_size 0x8000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x1ffff800 +option_size 0x4 +flags swo diff --git a/config/chips/G4_cat3.chip b/config/chips/G4_cat3.chip index 357522b31..f883b9176 100644 --- a/config/chips/G4_cat3.chip +++ b/config/chips/G4_cat3.chip @@ -1,13 +1,13 @@ # Chip-ID file for G4 cat3 # -chip_id 469 +chip_id 0x469 description G4 cat3 flash_type 8 flash_pagesize 800 -sram_size 18000 -bootrom_base 1fff0000 -bootrom_size 7000 -option_base 1ffff800 -option_size 4 -flags 3 +sram_size 0x18000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x1ffff800 +option_size 0x4 +flags dualbank swo diff --git a/config/chips/H72x_H73x.chip b/config/chips/H72x_H73x.chip index 43c8ae67b..81c1b71c9 100644 --- a/config/chips/H72x_H73x.chip +++ b/config/chips/H72x_H73x.chip @@ -1,13 +1,13 @@ # Chip-ID file for H72x/H73x # -chip_id 483 +chip_id 0x483 description H72x/H73x -flash_type a +flash_type 10 flash_pagesize 20000 -sram_size 20000 -bootrom_base 1ff00000 -bootrom_size 20000 -option_base 5200201c -option_size 2c -flags 2 +sram_size 0x20000 +bootrom_base 0x1ff00000 +bootrom_size 0x20000 +option_base 0x5200201c +option_size 0x2c +flags swo diff --git a/config/chips/H74x_H75x.chip b/config/chips/H74x_H75x.chip index c4d374e60..7753cfe03 100644 --- a/config/chips/H74x_H75x.chip +++ b/config/chips/H74x_H75x.chip @@ -1,13 +1,13 @@ # Chip-ID file for H74x/H75x # -chip_id 450 +chip_id 0x450 description H74x/H75x -flash_type a +flash_type 10 flash_pagesize 20000 -sram_size 20000 -bootrom_base 1ff00000 -bootrom_size 20000 -option_base 5200201c -option_size 2c -flags 3 +sram_size 0x20000 +bootrom_base 0x1ff00000 +bootrom_size 0x20000 +option_base 0x5200201c +option_size 0x2c +flags dualbank swo diff --git a/config/chips/H7Ax_H7Bx.chip b/config/chips/H7Ax_H7Bx.chip index b17631385..df6c13726 100644 --- a/config/chips/H7Ax_H7Bx.chip +++ b/config/chips/H7Ax_H7Bx.chip @@ -1,13 +1,13 @@ # Chip-ID file for H7Ax/H7Bx # -chip_id 480 +chip_id 0x480 description H7Ax/H7Bx -flash_type a +flash_type 10 flash_pagesize 2000 -sram_size 20000 -bootrom_base 1ff00000 -bootrom_size 20000 -option_base 5200201c -option_size 2c -flags 3 +sram_size 0x20000 +bootrom_base 0x1ff00000 +bootrom_size 0x20000 +option_base 0x5200201c +option_size 0x2c +flags dualbank swo diff --git a/config/chips/L011.chip b/config/chips/L011.chip index 6d8298848..2f1fa7b56 100644 --- a/config/chips/L011.chip +++ b/config/chips/L011.chip @@ -1,13 +1,13 @@ # Chip-ID file for L011 # -chip_id 457 +chip_id 0x457 description L011 flash_type 5 flash_pagesize 80 -sram_size 2000 -bootrom_base 1ff00000 -bootrom_size 2000 -option_base 0 -option_size 0 -flags 0 +sram_size 0x2000 +bootrom_base 0x1ff00000 +bootrom_size 0x2000 +option_base 0x0 +option_size 0x0 +flags none diff --git a/config/chips/L0x3.chip b/config/chips/L0x3.chip index 4bfc318c0..cbdc6cace 100644 --- a/config/chips/L0x3.chip +++ b/config/chips/L0x3.chip @@ -1,13 +1,13 @@ # Chip-ID file for L0x3 # -chip_id 417 +chip_id 0x417 description L0x3 flash_type 5 -flash_pagesize 80 -sram_size 2000 -bootrom_base 1ff0000 -bootrom_size 1000 -option_base 1ff80000 -option_size 14 -flags 0 +flash_pagesize 0x80 +sram_size 0x2000 +bootrom_base 0x1ff0000 +bootrom_size 0x1000 +option_base 0x1ff80000 +option_size 0x14 +flags none diff --git a/config/chips/L0xx_cat2.chip b/config/chips/L0xx_cat2.chip index 8b24634cf..43a301b27 100644 --- a/config/chips/L0xx_cat2.chip +++ b/config/chips/L0xx_cat2.chip @@ -1,13 +1,13 @@ # Chip-ID file for L0xx cat2 # -chip_id 425 +chip_id 0x425 description L0xx cat2 flash_type 5 flash_pagesize 80 -sram_size 2000 -bootrom_base 1ff0000 -bootrom_size 1000 -option_base 1ff80000 -option_size 14 -flags 0 +sram_size 0x2000 +bootrom_base 0x1ff0000 +bootrom_size 0x1000 +option_base 0x1ff80000 +option_size 0x14 +flags none diff --git a/config/chips/L0xx_cat5.chip b/config/chips/L0xx_cat5.chip index b52f97363..8ab0a50f8 100644 --- a/config/chips/L0xx_cat5.chip +++ b/config/chips/L0xx_cat5.chip @@ -1,13 +1,13 @@ # Chip-ID file for L0xx cat5 # -chip_id 447 +chip_id 0x447 description L0xx cat5 flash_type 5 flash_pagesize 80 -sram_size 5000 -bootrom_base 1ff0000 -bootrom_size 2000 -option_base 1ff80000 -option_size 14 -flags 0 +sram_size 0x5000 +bootrom_base 0x1ff0000 +bootrom_size 0x2000 +option_base 0x1ff80000 +option_size 0x14 +flags none diff --git a/config/chips/L152RE.chip b/config/chips/L152RE.chip index c073ade93..ebe012c5a 100644 --- a/config/chips/L152RE.chip +++ b/config/chips/L152RE.chip @@ -1,13 +1,13 @@ # Chip-ID file for L152RE # -chip_id 437 +chip_id 0x437 description L152RE flash_type 5 flash_pagesize 100 -sram_size 14000 -bootrom_base 1ff00000 -bootrom_size 1000 -option_base 0 -option_size 0 -flags 2 +sram_size 0x14000 +bootrom_base 0x1ff00000 +bootrom_size 0x1000 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/L1xx_cat2.chip b/config/chips/L1xx_cat2.chip index dd89c981c..02012078a 100644 --- a/config/chips/L1xx_cat2.chip +++ b/config/chips/L1xx_cat2.chip @@ -1,13 +1,13 @@ # Chip-ID file for L1xx cat2 # -chip_id 429 +chip_id 0x429 description L1xx cat2 flash_type 5 flash_pagesize 100 -sram_size 8000 -bootrom_base 1ff00000 -bootrom_size 1000 -option_base 0 -option_size 0 -flags 2 +sram_size 0x8000 +bootrom_base 0x1ff00000 +bootrom_size 0x1000 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/L1xx_high-density.chip b/config/chips/L1xx_high-density.chip index 8e5b0cd44..130b4e456 100644 --- a/config/chips/L1xx_high-density.chip +++ b/config/chips/L1xx_high-density.chip @@ -1,13 +1,13 @@ # Chip-ID file for L1xx high-density # -chip_id 436 +chip_id 0x436 description L1xx high-density flash_type 5 flash_pagesize 100 -sram_size c000 -bootrom_base 1ff00000 -bootrom_size 1000 -option_base 1ff80000 -option_size 8 -flags 2 +sram_size 0xc000 +bootrom_base 0x1ff00000 +bootrom_size 0x1000 +option_base 0x1ff80000 +option_size 0x8 +flags swo diff --git a/config/chips/L1xx_medium-density.chip b/config/chips/L1xx_medium-density.chip index feb53b846..409b4dacc 100644 --- a/config/chips/L1xx_medium-density.chip +++ b/config/chips/L1xx_medium-density.chip @@ -1,13 +1,13 @@ # Chip-ID file for L1xx medium-density # -chip_id 416 +chip_id 0x416 description L1xx medium-density flash_type 5 flash_pagesize 100 -sram_size 4000 -bootrom_base 1ff00000 -bootrom_size 1000 -option_base 0 -option_size 0 -flags 2 +sram_size 0x4000 +bootrom_base 0x1ff00000 +bootrom_size 0x1000 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/L1xx_medium-plus-density.chip b/config/chips/L1xx_medium-plus-density.chip index bdce4adc2..374f2e914 100644 --- a/config/chips/L1xx_medium-plus-density.chip +++ b/config/chips/L1xx_medium-plus-density.chip @@ -1,13 +1,13 @@ # Chip-ID file for L1xx medium-plus-density # -chip_id 427 +chip_id 0x427 description L1xx medium-plus-density flash_type 5 flash_pagesize 100 -sram_size 8000 -bootrom_base 1ff00000 -bootrom_size 1000 -option_base 0 -option_size 0 -flags 2 +sram_size 0x8000 +bootrom_base 0x1ff00000 +bootrom_size 0x1000 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/L41x.chip b/config/chips/L41x.chip index a05034af4..cf51b4b02 100644 --- a/config/chips/L41x.chip +++ b/config/chips/L41x.chip @@ -1,13 +1,13 @@ # Chip-ID file for L41x # -chip_id 464 +chip_id 0x464 description L41x flash_type 6 flash_pagesize 800 -sram_size a000 -bootrom_base 1fff0000 -bootrom_size 7000 -option_base 0 -option_size 0 -flags 2 +sram_size 0xa000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/L43x_L44x.chip b/config/chips/L43x_L44x.chip index 4c41ac69b..1953a6a99 100644 --- a/config/chips/L43x_L44x.chip +++ b/config/chips/L43x_L44x.chip @@ -1,13 +1,13 @@ # Chip-ID file for L43x/L44x # -chip_id 435 +chip_id 0x435 description L43x/L44x flash_type 6 flash_pagesize 800 -sram_size c000 -bootrom_base 1fff0000 -bootrom_size 7000 -option_base 1fff7800 -option_size 4 -flags 2 +sram_size 0xc000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x1fff7800 +option_size 0x4 +flags swo diff --git a/config/chips/L45x_L46x.chip b/config/chips/L45x_L46x.chip index da1594995..79a90fcac 100644 --- a/config/chips/L45x_L46x.chip +++ b/config/chips/L45x_L46x.chip @@ -1,13 +1,13 @@ # Chip-ID file for L45x/L46x # -chip_id 462 +chip_id 0x462 description L45x/L46x flash_type 6 flash_pagesize 800 -sram_size 20000 -bootrom_base 1fff0000 -bootrom_size 7000 -option_base 0 -option_size 0 -flags 2 +sram_size 0x20000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/L496x_L4A6x.chip b/config/chips/L496x_L4A6x.chip index 9bfcdb366..f94c0c582 100644 --- a/config/chips/L496x_L4A6x.chip +++ b/config/chips/L496x_L4A6x.chip @@ -1,13 +1,13 @@ # Chip-ID file for L496x/L4A6x # -chip_id 461 +chip_id 0x461 description L496x/L4A6x flash_type 6 flash_pagesize 800 -sram_size 40000 -bootrom_base 1fff0000 -bootrom_size 7000 -option_base 1fff7800 -option_size 4 -flags 2 +sram_size 0x40000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x1fff7800 +option_size 0x4 +flags swo diff --git a/config/chips/L4Rx.chip b/config/chips/L4Rx.chip index a9b082128..355f22470 100644 --- a/config/chips/L4Rx.chip +++ b/config/chips/L4Rx.chip @@ -1,13 +1,13 @@ # Chip-ID file for L4Rx # -chip_id 470 +chip_id 0x470 description L4Rx flash_type 6 flash_pagesize 1000 -sram_size a0000 -bootrom_base 1fff0000 -bootrom_size 7000 -option_base 0 -option_size 0 -flags 2 +sram_size 0xa0000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/L4xx.chip b/config/chips/L4xx.chip index b66df6b31..3360a446e 100644 --- a/config/chips/L4xx.chip +++ b/config/chips/L4xx.chip @@ -1,13 +1,13 @@ # Chip-ID file for L4xx # -chip_id 415 +chip_id 0x415 description L4xx flash_type 6 flash_pagesize 800 -sram_size 18000 -bootrom_base 1fff0000 -bootrom_size 7000 -option_base 1fff7800 -option_size 4 -flags 2 +sram_size 0x18000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x1fff7800 +option_size 0x4 +flags swo diff --git a/config/chips/WB55.chip b/config/chips/WB55.chip index 4ad4d08d0..9cf1d4380 100644 --- a/config/chips/WB55.chip +++ b/config/chips/WB55.chip @@ -1,13 +1,13 @@ # Chip-ID file for WB55 # -chip_id 495 +chip_id 0x495 description WB55 flash_type 9 flash_pagesize 1000 -sram_size 40000 -bootrom_base 1fff0000 -bootrom_size 7000 -option_base 0 -option_size 0 -flags 2 +sram_size 0x40000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/unknown_device.chip b/config/chips/unknown_device.chip index ea4fe5f02..2235d0072 100644 --- a/config/chips/unknown_device.chip +++ b/config/chips/unknown_device.chip @@ -1,13 +1,13 @@ # Chip-ID file for unknown device # -chip_id 0 +chip_id 0x0 description unknown device flash_type 0 flash_pagesize 0 -sram_size 0 -bootrom_base 0 -bootrom_size 0 -option_base 0 -option_size 0 -flags 0 +sram_size 0x0 +bootrom_base 0x0 +bootrom_size 0x0 +option_base 0x0 +option_size 0x0 +flags none diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 1543041c2..772a722aa 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -8,6 +8,13 @@ #include #include +// This is the old chipid "database". +// It is kept here for now to be able to compare the +// result between the "old code" and the "new code". +// For now if you need to change something, please +// change it both here and in the corresponding +// config/chips/*.chip file. + static struct stlink_chipid_params devices[] = { { // RM0410 document was used to find these paramaters @@ -842,16 +849,16 @@ void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { fprintf(fp, "# Chip-ID file for %s\n", dev->description); fprintf(fp, "#\n"); - fprintf(fp, "chip_id %x\n", dev->chip_id); + fprintf(fp, "chip_id 0x%x\n", dev->chip_id); fprintf(fp, "description %s\n", dev->description); - fprintf(fp, "flash_type %x\n", dev->flash_type); - fprintf(fp, "flash_pagesize %x\n", dev->flash_pagesize); - fprintf(fp, "sram_size %x\n", dev->sram_size); - fprintf(fp, "bootrom_base %x\n", dev->bootrom_base); - fprintf(fp, "bootrom_size %x\n", dev->bootrom_size); - fprintf(fp, "option_base %x\n", dev->option_base); - fprintf(fp, "option_size %x\n", dev->option_size); - fprintf(fp, "flags %x\n\n", dev->flags); + fprintf(fp, "flash_type %d\n", dev->flash_type); + fprintf(fp, "flash_pagesize 0x%x\n", dev->flash_pagesize); + fprintf(fp, "sram_size 0x%x\n", dev->sram_size); + fprintf(fp, "bootrom_base 0x%x\n", dev->bootrom_base); + fprintf(fp, "bootrom_size 0x%x\n", dev->bootrom_size); + fprintf(fp, "option_base 0x%x\n", dev->option_base); + fprintf(fp, "option_size 0x%x\n", dev->option_size); + fprintf(fp, "flags %d\n\n", dev->flags); } @@ -883,10 +890,10 @@ struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { void process_chipfile(char *fname) { FILE *fp; - char *p, buf[1025]; + char *p, *pp, buf[1025]; char word[64], value[64]; struct stlink_chipid_params *ts; - int nc; + int nc, ival; //fprintf (stderr, "processing chipfile %s.\n", fname); fp = fopen(fname, "r"); @@ -902,30 +909,39 @@ void process_chipfile(char *fname) if (*p == '#') continue; // ignore comments. sscanf(p, "%s %s", word, value); + ival = atoi (value); if (strcmp(word, "chip_id") == 0) { - sscanf(value, "%x", &ts->chip_id); + ts->chip_id = ival; } else if (strcmp (word, "description") == 0) { //ts->description = strdup (value); buf[strlen(p)-1] = 0; // chomp newline sscanf(p, "%*s %n", &nc); ts->description = strdup(p+nc); } else if (strcmp (word, "flash_type") == 0) { - sscanf(value, "%x", &ts->flash_type); + ts->flash_type = ival; } else if (strcmp (word, "flash_size_reg") == 0) { - sscanf(value, "%x", &ts->flash_size_reg); + ts->flash_size_reg = ival; } else if (strcmp (word, "flash_pagesize") == 0) { - sscanf(value, "%x", &ts->flash_pagesize); + ts->flash_pagesize = ival; } else if (strcmp (word, "sram_size") == 0) { - sscanf(value, "%x", &ts->sram_size); + ts->sram_size = ival; } else if (strcmp (word, "bootrom_base") == 0) { - sscanf(value, "%x", &ts->bootrom_base); + ts->bootrom_base = ival; } else if (strcmp (word, "bootrom_size") == 0) { - sscanf(value, "%x", &ts->bootrom_size); + ts->bootrom_size = ival; } else if (strcmp (word, "option_base") == 0) { - sscanf(value, "%x", &ts->option_base); + ts->option_base = ival; } else if (strcmp (word, "option_size") == 0) { - sscanf(value, "%x", &ts->option_size); + ts->option_size = ival; } else if (strcmp (word, "flags") == 0) { + pp = strtok (p, " \t\n"); + while ((pp = strtok (NULL, " \t\n")) ) { + if (strcmp (pp, "none") == 0) ts->flags = 0; // not necessary: calloc did this already. + else if (strcmp (pp, "dualbank") == 0) ts->flags |= CHIP_F_HAS_DUAL_BANK; + else if (strcmp (pp, "swo") == 0) ts->flags |= CHIP_F_HAS_SWO_TRACING; + else fprintf (stderr, "Unknown flags word in %s: '%s'\n", + fname, pp); + } sscanf(value, "%x", &ts->flags); } else { fprintf (stderr, "Unknown keyword in %s: %s\n", From f88509130505748831ded417031a14cd033bdb63 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 24 May 2021 12:13:56 +0200 Subject: [PATCH 1207/1435] General Project Update - Updated CHANGELOG.md - Updated GitHub security policy - [doc] Updated steps for release procedure - [doc] Updated list of supported OS - Removed old clang_analyze script - Minor fix in travis build script --- .travis.sh | 6 +++--- CHANGELOG.md | 1 + SECURITY.md | 3 ++- doc/release.md | 1 + doc/version_support.md | 6 +++--- run_clang_analyze.sh | 9 --------- 6 files changed, 10 insertions(+), 16 deletions(-) delete mode 100755 run_clang_analyze.sh diff --git a/.travis.sh b/.travis.sh index a156db203..d8c5377de 100755 --- a/.travis.sh +++ b/.travis.sh @@ -23,12 +23,12 @@ elif [ "$TRAVIS_JOB_NAME" == "linux-mingw-32" ]; then make && rm -rf build-mingw-32 && cd - elif [ "$TRAVIS_OS_NAME" == "osx" ]; then - echo "--> Building Debug..." + echo "--> make debug..." mkdir -p build/Debug && cd build/Debug cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && cd - + make debug && cd - - echo "--> Building Release with package..." + echo "--> make package..." mkdir -p build/Release && cd build/Release cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make package && cd - diff --git a/CHANGELOG.md b/CHANGELOG.md index 57ed15e98..b711f3890 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Updates & changes: - Added instructions for bug-reports and feature-requests to contribution guidelines ([#906](https://github.com/stlink-org/stlink/pull/906)) - Added travis CI configuration for macOS 10.14 to maintain capability for 32-bit compilation ([#f5ada94](https://github.com/stlink-org/stlink/commit/f5ada9474cdb87ff37de0d4eb9e75622b5870646)) +- Updated description of chip id 0x0457 to L01x/L02x ([#1143](https://github.com/stlink-org/stlink/pull/1143), [#1144](https://github.com/stlink-org/stlink/pull/1144)) Fixes: - cmake: Install shared libraries in proper directories ([#1142](https://github.com/stlink-org/stlink/pull/1142)) diff --git a/SECURITY.md b/SECURITY.md index caa2740db..9ace47066 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -7,7 +7,8 @@ The following versions of the stlink toolset are currently being supported.
      +On Windows users should ensure that cmake 3.20.2 or any later version is installed.
      Up on compiling c-make will **automatically** download and install the latest compatible version of `libusb` (1.0.23 at the time of writing). - Windows 10 @@ -14,8 +14,8 @@ Up on compiling c-make will **automatically** download and install the latest co | Package Repository | libusb
      version | cmake
      version | gtk-3
      version | Supported macOS versions | | ------------------ | ------------------- | ------------------ | ------------------ | ------------------------ | -| homebrew | 1.0.23 | 3.17.0 | 3.24.18
      gtk+3 | 10.9 - 11.x | -| MacPorts | 1.0.23 | 3.17.0 | 3.24.18
      gtk3 | 10.4 - 11.x | +| homebrew | 1.0.24 | 3.20.2 | 3.24.29
      gtk+3 | 10.9 - 11.x | +| MacPorts | 1.0.24 | 3.20.2 | 3.24.29
      gtk3 | 10.4 - 11.x | NOTE: In order to use a STLINK/V1 programmer on macOS, versions 10.14 or 10.15 are required. diff --git a/run_clang_analyze.sh b/run_clang_analyze.sh deleted file mode 100755 index fd1b78b55..000000000 --- a/run_clang_analyze.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Run this hacky script in project root directory to start clang static analysis. -# Adjust ccc-analyzer path if necessary - -CCC_ANALYZER=/usr/share/clang/scan-build-3.5/ccc-analyzer -mkdir -p build-clang-analyze/reports -cd build-clang-analyze -cmake -DCMAKE_C_COMPILER=${CCC_ANALYZER} $* .. -scan-build -o ./reports --keep-empty make From 9eb81e1e0adc6a5bf7a1c68cbbaf3fd35ec85be0 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 24 May 2021 21:35:02 +0500 Subject: [PATCH 1208/1435] Expanded and revised list of chips --- src/stlink-lib/chipid.c | 326 +++++++++++++++++++++++++--------------- src/stlink-lib/chipid.h | 18 ++- 2 files changed, 213 insertions(+), 131 deletions(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 711bf24b0..283f6faec 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -3,26 +3,28 @@ static const struct stlink_chipid_params devices[] = { { - // RM0410 document was used to find these paramaters + // STM32F76x/F77x + // RM0410 .chip_id = STLINK_CHIPID_STM32_F7XXXX, - .description = "F76xxx", + .description = "F76x/F77x", .flash_type = STLINK_FLASH_TYPE_F7, .flash_size_reg = 0x1ff0f442, // section 45.2 .flash_pagesize = 0x800, // No flash pages .sram_size = 0x80000, // "SRAM" byte size in hex from - .bootrom_base = 0x00200000, // ! "System memory" starting address from - .bootrom_size = 0xEDC0, // ! @todo "System memory" byte size in hex from + .bootrom_base = 0x00200000, // "System memory" starting address from + .bootrom_size = 0xEDC0, .option_base = STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option // bytes, writing uses FLASH_F7_OPTCR // and FLASH_F7_OPTCR1 .option_size = 0x20, - .flags = CHIP_F_HAS_SWO_TRACING, + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { - // RM0385 and DS10916 document was used to find these paramaters + // STM32F74x/F75x + // RM0385, DS10916 .chip_id = STLINK_CHIPID_STM32_F7, - .description = "F7xx", + .description = "F74x/F75x", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1ff0f442, // section 41.2 .flash_pagesize = 0x800, // No flash pages @@ -34,7 +36,8 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // RM0431 and DS document was used to find these paramaters + // STM32F72x/F73x + // RM0431 .chip_id = STLINK_CHIPID_STM32_F72XXX, .description = "F72x/F73x", .flash_type = STLINK_FLASH_TYPE_F4, @@ -48,25 +51,27 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // table 2, PM0063 + // STM32F1xx medium-density devices + // RM0008 .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, - .description = "F1xx Medium-density", + .description = "F1xx MD", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, .sram_size = 0x5000, - .bootrom_base = 0x1ffff000, + .bootrom_base = 0x1ffff000, // 2.3.3 "Embedded Flash memory" .bootrom_size = 0x800, .option_base = STM32_F0_OPTION_BYTES_BASE, .option_size = 16, .flags = CHIP_F_HAS_SWO_TRACING, }, { - // table 1, PM0059 + // STM32F205xx, STM32F207xx, STM32F215xx, STM32F217xx + // RM0033 (rev 5) .chip_id = STLINK_CHIPID_STM32_F2, .description = "F2xx", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, // as in RM0033 Rev 5 + .flash_size_reg = 0x1fff7a22, .flash_pagesize = 0x20000, .sram_size = 0x20000, .bootrom_base = 0x1fff0000, @@ -76,9 +81,10 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // PM0063 + // STM32F1xx low-density devices + // RM0008 .chip_id = STLINK_CHIPID_STM32_F1_LOW, - .description = "F1 Low-density device", + .description = "F1xx LD", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, @@ -90,10 +96,12 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { + // STM32F4x5/F4x7 + // RM0090 (rev 2) .chip_id = STLINK_CHIPID_STM32_F4, - .description = "F4xx", + .description = "F4x5/F4x7", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, .sram_size = 0x30000, .bootrom_base = 0x1fff0000, @@ -103,10 +111,12 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { + // STM32F46x/F47x + // RM0090 (rev 2) .chip_id = STLINK_CHIPID_STM32_F4_DSI, .description = "F46x/F47x", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, .sram_size = 0x40000, .bootrom_base = 0x1fff0000, @@ -114,10 +124,12 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { + // STM32F42x/F43x + // RM0090 (rev 2) .chip_id = STLINK_CHIPID_STM32_F4_HD, .description = "F42x/F43x", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, .sram_size = 0x40000, .bootrom_base = 0x1fff0000, @@ -126,7 +138,7 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F4_LP, - .description = "F4xx (low power)", + .description = "F401xB/C", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, @@ -137,20 +149,18 @@ static const struct stlink_chipid_params devices[] = { }, { .chip_id = STLINK_CHIPID_STM32_F411XX, - .description = "STM32F411xC/E", + .description = "F411xC/E", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, .sram_size = 0x20000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800, - .option_base = STM32_F4_OPTION_BYTES_BASE, - .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F4_DE, - .description = "F4xx (Dynamic Efficency)", + .description = "F401xD/E", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, @@ -160,8 +170,10 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { + // STM32F1xx high-density devices + // RM0008 .chip_id = STLINK_CHIPID_STM32_F1_HIGH, - .description = "F1xx High-density", + .description = "F1xx HD", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -173,47 +185,53 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // This ignores the EEPROM! (and uses the page erase size, - // not the sector write protection...) + // STM32L100/L15x/L16x Cat.1 + // RM0038 .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM, - .description = "L1xx Medium-density", + .description = "L1xx Cat.1", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8004c, .flash_pagesize = 0x100, - .sram_size = 0x4000, + .sram_size = 0x4000, // up to 16k .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000, .flags = CHIP_F_HAS_SWO_TRACING, }, { + // STM32L100/L15x/L16x Cat.2 + // RM0038 .chip_id = STLINK_CHIPID_STM32_L1_CAT2, .description = "L1xx Cat.2", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8004c, .flash_pagesize = 0x100, - .sram_size = 0x8000, + .sram_size = 0x8000, // up to 32k .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000, .flags = CHIP_F_HAS_SWO_TRACING, }, { + // STM32L100/L15x/L16x Cat.3 + // RM0038 .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM_PLUS, - .description = "L1xx Medium-Plus-density", + .description = "L1xx Cat.3", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, .flash_pagesize = 0x100, - .sram_size = 0x8000, // not completely clear if there are some with 48k + .sram_size = 0x8000, // up to 32k .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000, .flags = CHIP_F_HAS_SWO_TRACING, }, { + // STM32L100/L15x/L16x Cat.4 + // RM0038 .chip_id = STLINK_CHIPID_STM32_L1_HIGH, - .description = "L1xx High-density", + .description = "L1xx Cat.4", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, .flash_pagesize = 0x100, - .sram_size = 0xC000, // not completely clear if there are some with 32k + .sram_size = 0xC000, // up to 48k .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000, .option_base = STM32_L1_OPTION_BYTES_BASE, @@ -221,19 +239,23 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { + // STM32L100/L15x/L16x Cat.5 + // RM0038 .chip_id = STLINK_CHIPID_STM32_L152_RE, - .description = "L152RE", + .description = "L1xx Cat.5", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff800cc, .flash_pagesize = 0x100, - .sram_size = 0x14000, // not completely clear if there are some with 32k + .sram_size = 0x14000, // up to 80k .bootrom_base = 0x1ff00000, .bootrom_size = 0x1000, .flags = CHIP_F_HAS_SWO_TRACING, }, { + // STM32F1xx connectivity devices + // RM0008 .chip_id = STLINK_CHIPID_STM32_F1_CONN, - .description = "F1 Connectivity line", + .description = "F1xx CL", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -245,9 +267,10 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // Low and Medium density VL have same chipid. RM0041 25.6.1 + // STM32F1xx low- and medium-density value line devices + // RM0041 .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, - .description = "F1xx Value Line", + .description = "F1xx VL", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x400, @@ -259,7 +282,8 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32F446x family. Support based on DM00135183.pdf (RM0390) document. + // STM32F446x family + // RM0390 .chip_id = STLINK_CHIPID_STM32_F446, .description = "F446", .flash_type = STLINK_FLASH_TYPE_F4, @@ -273,7 +297,8 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32F410 MCUs. Support based on DM00180366.pdf (RM0401) document. + // STM32F410 + // RM0401 .chip_id = STLINK_CHIPID_STM32_F410, .description = "F410", .flash_type = STLINK_FLASH_TYPE_F4, @@ -285,10 +310,10 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // This is STK32F303VCT6 device from STM32 F3 Discovery board. - // Support based on DM00043574.pdf (RM0316) document. + // STM32F303xB/C, STM32F358, STM32F302xBxC + // RM0316, RM0365 .chip_id = STLINK_CHIPID_STM32_F3, - .description = "F3xx", + .description = "F302/F303/F358", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, @@ -300,10 +325,10 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // This is STK32F373VCT6 device from STM32 F373 eval board - // Support based on 303 above (37x and 30x have same memory map) + // STM32F373Cx/Rx/Vx, STM32F378Cx/Rx/Vx + // RM0313 .chip_id = STLINK_CHIPID_STM32_F37x, - .description = "F3xx", + .description = "F37x", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, @@ -315,8 +340,10 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { + // STM32F1xx high-density value line devices + // RM0041 .chip_id = STLINK_CHIPID_STM32_F1_VL_HIGH, - .description = "F1xx High-density value line", + .description = "F1xx HD VL", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -328,8 +355,10 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { + // STM32F1xx XL-density devices + // RM0008 .chip_id = STLINK_CHIPID_STM32_F1_XL, - .description = "F1xx XL-density", + .description = "F1xx XL", .flash_type = STLINK_FLASH_TYPE_F1_XL, .flash_size_reg = 0x1ffff7e0, .flash_pagesize = 0x800, @@ -339,8 +368,8 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // Use this as an example for mapping future chips: - // RM0091 document was used to find these paramaters + // STM32F07x + // RM0091 .chip_id = STLINK_CHIPID_STM32_F0_CAN, .description = "F07x", .flash_type = STLINK_FLASH_TYPE_F0, @@ -354,8 +383,8 @@ static const struct stlink_chipid_params devices[] = { .option_size = 16, }, { - // Use this as an example for mapping future chips: - // RM0091 document was used to find these paramaters + // STM32F05x + // RM0091 .chip_id = STLINK_CHIPID_STM32_F0, .description = "F05x", .flash_type = STLINK_FLASH_TYPE_F0, @@ -369,8 +398,8 @@ static const struct stlink_chipid_params devices[] = { .option_size = 16, }, { - // RM0402 document was used to find these parameters - // Table 4. + // STM32F412 + // RM0402 .chip_id = STLINK_CHIPID_STM32_F412, .description = "F412", .flash_type = STLINK_FLASH_TYPE_F4, @@ -383,10 +412,10 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // RM0430 DocID029473 Rev 2 document was used to find these parameters - // Figure 2, Table 4, Table 5, Section 35.2 + // STM32F413/F423 + // RM0430 (rev 2) .chip_id = STLINK_CHIPID_STM32_F413, - .description = "F413", + .description = "F413/F423", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 .flash_pagesize = @@ -400,8 +429,10 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { + // STM32F09x + // RM0091 .chip_id = STLINK_CHIPID_STM32_F09X, - .description = "F09X", + .description = "F09x", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) @@ -413,8 +444,8 @@ static const struct stlink_chipid_params devices[] = { .option_size = 16, }, { - // Use this as an example for mapping future chips: - // RM0091 document was used to find these paramaters + // STM32F04x + // RM0091 .chip_id = STLINK_CHIPID_STM32_F04, .description = "F04x", .flash_type = STLINK_FLASH_TYPE_F0, @@ -428,8 +459,8 @@ static const struct stlink_chipid_params devices[] = { .option_size = 16, }, { - // Use this as an example for mapping future chips: - // RM0091 document was used to find these paramaters + // STM32F03x + // RM0091 .chip_id = STLINK_CHIPID_STM32_F0_SMALL, .description = "F03x", .flash_type = STLINK_FLASH_TYPE_F0, @@ -443,9 +474,10 @@ static const struct stlink_chipid_params devices[] = { .option_size = 16, }, { - // STM32F30x + // STM32F301x6/8, STM32F318x8, STM32F302x6x8 + // RM0366, RM0365 .chip_id = STLINK_CHIPID_STM32_F3_SMALL, - .description = "F3xx small", + .description = "F301/F302/F318", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, @@ -457,10 +489,10 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32L0x - // RM0367,RM0377 documents was used to find these parameters + // STM32L0xx Category 3 + // RM0367, RM0377, RM0451 .chip_id = STLINK_CHIPID_STM32_L0, - .description = "L0x3", + .description = "L0xx Cat.3", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, @@ -472,9 +504,9 @@ static const struct stlink_chipid_params devices[] = { }, { // STM32L0x Category 5 - // RM0367,RM0377 documents was used to find these parameters + // RM0367, RM0377, RM0451 .chip_id = STLINK_CHIPID_STM32_L0_CAT5, - .description = "L0xx Category 5", + .description = "L0xx Cat.5", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, @@ -483,12 +515,13 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x2000, .option_base = STM32_L0_OPTION_BYTES_BASE, .option_size = 20, + .flags = CHIP_F_HAS_DUAL_BANK, }, { // STM32L0x Category 2 - // RM0367,RM0377 documents was used to find these parameters + // RM0367, RM0377 .chip_id = STLINK_CHIPID_STM32_L0_CAT2, - .description = "L0xx Category 2", + .description = "L0xx Cat.2", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, @@ -499,10 +532,10 @@ static const struct stlink_chipid_params devices[] = { .option_size = 20, }, { - // STM32F334, STM32F303x6/8, and STM32F328 - // From RM0364 and RM0316 + // STM32F334, STM32F303x6/8, STM32F328 + // RM0364, RM0316 .chip_id = STLINK_CHIPID_STM32_F334, - .description = "F334 medium density", // (RM0316 sec 33.6.1) + .description = "F303/F328/F334", // (RM0316 sec 33.6.1) .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, .flash_pagesize = 0x800, @@ -514,10 +547,10 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // This is STK32F303RET6 device from STM32 F3 Nucelo board. - // Support based on DM00043574.pdf (RM0316) document rev 5. + // STM32F303xD/E, STM32F398xE, STM32F302xD/E + // RM0316 (rev 5), RM0365 .chip_id = STLINK_CHIPID_STM32_F303_HIGH, - .description = "F303 high density", + .description = "F302/F303/F398", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register .flash_pagesize = 0x800, // 4.2.1 Flash memory organization @@ -529,10 +562,10 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32L4x6 - // From RM0351. + // STM32L47x/L48x + // RM0351 .chip_id = STLINK_CHIPID_STM32_L4, - .description = "L4xx", + .description = "L47x/L48x", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) @@ -552,24 +585,41 @@ static const struct stlink_chipid_params devices[] = { }, { // STM32L4RX - // From DM00310109.pdf + // RM0432 .chip_id = STLINK_CHIPID_STM32_L4RX, - .description = "L4Rx", + .description = "L4Rx/L4Sx", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = - 0x1fff75e0, // "Flash size data register" (sec 52.2, page 2049) - .flash_pagesize = 0x1000, // 4k, section 3.3, pg 97 + 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) + .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 + //TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 - .bootrom_base = 0x1fff0000, // 3.3.1, pg 99 - .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 99) - .flags = CHIP_F_HAS_SWO_TRACING, + .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 + .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L4PX + // RM0432 + .chip_id = STLINK_CHIPID_STM32_L4PX, + .description = "L4Px", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = + 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) + .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 + //TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size + .sram_size = + 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 + .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 + .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { // STLINK_CHIPID_STM32_L41X - // From RM0394 Rev 4 and DS12469 Rev 5 + // RM0394 (rev 4), DS12469 (rev 5) .chip_id = STLINK_CHIPID_STM32_L41X, - .description = "L41x", + .description = "L41x/L42x", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, // sec 47.2, page 1586) @@ -585,7 +635,7 @@ static const struct stlink_chipid_params devices[] = { }, { // STLINK_CHIPID_STM32_L43X - // From RM0392. + // RM0392 .chip_id = STLINK_CHIPID_STM32_L43X, .description = "L43x/L44x", .flash_type = STLINK_FLASH_TYPE_L4, @@ -607,9 +657,9 @@ static const struct stlink_chipid_params devices[] = { }, { // STLINK_CHIPID_STM32_L496X - // Support based on en.DM00083560.pdf (RM0351) document rev 5. + // RM0351 (rev 5) .chip_id = STLINK_CHIPID_STM32_L496X, - .description = "L496x/L4A6x", + .description = "L49x/L4Ax", .flash_type = STLINK_FLASH_TYPE_L4, .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) @@ -626,7 +676,7 @@ static const struct stlink_chipid_params devices[] = { }, { // STLINK_CHIPID_STM32_L46X - // From RM0394 (updated version of RM0392?). + // RM0394 (updated version of RM0392?) .chip_id = STLINK_CHIPID_STM32_L46X, .description = "L45x/46x", .flash_type = STLINK_FLASH_TYPE_L4, @@ -645,7 +695,8 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32L011 + // STM32L0xx Category 1 + // RM0451, RM0377 .chip_id = STLINK_CHIPID_STM32_L011, .description = "L01x/L02x", .flash_type = STLINK_FLASH_TYPE_L0, @@ -656,61 +707,67 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x2000, }, { - // STM32G030/031/041 (from RM0454 & RM0444) + // STM32G030/031/041 + // RM0454, RM0444 .chip_id = STLINK_CHIPID_STM32_G0_CAT1, - .description = "G030/G031/G041", + .description = "G03x/G04x", .flash_type = STLINK_FLASH_TYPE_G0, .flash_size_reg = 0x1FFF75E0, // Section 38.2 .flash_pagesize = 0x800, // 2k (sec 3.2) .sram_size = 0x2000, // 8k (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 5 on RM0444 & table 4 on RM0454) + .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 3) .option_base = STM32_G0_OPTION_BYTES_BASE, .option_size = 4, }, { - // STM32G070/071/081 (from RM0454 & RM0444) + // STM32G071/081 + // RM0444 .chip_id = STLINK_CHIPID_STM32_G0_CAT2, - .description = "G070/G071/G081", + .description = "G07x/G08x", .flash_type = STLINK_FLASH_TYPE_G0, .flash_size_reg = 0x1FFF75E0, // Section 38.2 .flash_pagesize = 0x800, // 2k (sec 3.2) .sram_size = 0x9000, // 36k (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 3 on RM0444 & table 3 on RM0454) + .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) .option_base = STM32_G0_OPTION_BYTES_BASE, .option_size = 4, - }, + }, { - // STM32G0B0/0B1/0C1 (from RM0454 & RM0444) + // STM32G0B1/G0C1 + // RM0444 .chip_id = STLINK_CHIPID_STM32_G0_CAT3, - .description = "G0B0/G0B1/G0C1", + .description = "G0Bx/G0Cx", .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x24000, // 144k (sec 2.3) + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (sec 3.2) + .sram_size = 0x9000, // 36k (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2 on RM0444 & table 2 on RM0454) + .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) .option_base = STM32_G0_OPTION_BYTES_BASE, .option_size = 4, + .flags = CHIP_F_HAS_DUAL_BANK, }, { - // STM32G050/051/061 (from RM0454 & RM0444) + // STM32G051/G061 + // RM0444 .chip_id = STLINK_CHIPID_STM32_G0_CAT4, - .description = "G050/G051/G061", + .description = "G05x/G06x", .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x4800, // 18k (sec 2.3) + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (sec 3.2) + .sram_size = 0x9000, // 36k (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 4 on RM0444 & table 4 on RM0454) + .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) .option_base = STM32_G0_OPTION_BYTES_BASE, .option_size = 4, }, { - // STM32G431/441 (from RM0440) + // STM32G431/441 + // RM0440 .chip_id = STLINK_CHIPID_STM32_G4_CAT2, - .description = "G4 Category-2", + .description = "G43x/G44x", .flash_type = STLINK_FLASH_TYPE_G4, .flash_size_reg = 0x1FFF75E0, // Section 47.2 .flash_pagesize = @@ -726,9 +783,10 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32G471/473/474/483/484 (from RM0440) + // STM32G471/473/474/483/484 + // RM0440 .chip_id = STLINK_CHIPID_STM32_G4_CAT3, - .description = "G4 Category-3", + .description = "G47x/G48x", .flash_type = STLINK_FLASH_TYPE_G4, .flash_size_reg = 0x1FFF75E0, // Section 47.2 .flash_pagesize = @@ -736,7 +794,7 @@ static const struct stlink_chipid_params devices[] = { // SRAM1 is 80k at 0x20000000 // SRAM2 is 16k at 0x20014000 // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x18000, // 128k (sec 2.4) + .sram_size = 0x20000, // 128k (sec 2.4) .bootrom_base = 0x1fff0000, .bootrom_size = 0x7000, // 28k (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, @@ -744,9 +802,29 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { - // STM32WB55 (from RM0434) + // STM32G491/G4A1 + // RM0440 + .chip_id = STLINK_CHIPID_STM32_G4_CAT4, + .description = "G49x/G4Ax", + .flash_type = STLINK_FLASH_TYPE_G4, + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = + 0x800, // 2k (sec 3.3.1) + // SRAM1 is 80k at 0x20000000 + // SRAM2 is 16k at 0x20014000 + // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 + .sram_size = 0x1C000, // 112k (sec 2.4) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28k (table 2) + .option_base = STM32_G4_OPTION_BYTES_BASE, + .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32WB55xx, STM32WB35xx, STM32WB50CG/30CE + // RM0434, RM0471 .chip_id = STLINK_CHIPID_STM32_WB55, - .description = "WB55", + .description = "WB5x/3x", .flash_type = STLINK_FLASH_TYPE_WB, .flash_size_reg = 0x1FFF75E0, .flash_pagesize = 0x1000, // 4k @@ -772,7 +850,8 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { - // STM32H7A3/7B3 (from RM0455) + // STM32H7A3/7B3 + // RM0455 .chip_id = STLINK_CHIPID_STM32_H7AX, .description = "H7Ax/H7Bx", .flash_type = STLINK_FLASH_TYPE_H7, @@ -788,7 +867,8 @@ static const struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { - // STM32H72x/H73x (from RM0468) + // STM32H72x/H73x + // RM0468 .chip_id = STLINK_CHIPID_STM32_H72X, .description = "H72x/H73x", .flash_type = STLINK_FLASH_TYPE_H7, diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index 16a6a5797..b240ecf72 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -37,9 +37,6 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F4_DE = 0x433, STLINK_CHIPID_STM32_F4_DSI = 0x434, STLINK_CHIPID_STM32_L43X = 0x435, /* covers STM32L43xxx and STM32L44xxx devices */ - STLINK_CHIPID_STM32_L496X = 0x461, /* covers STM32L496xx and STM32L4A6xx devices */ - STLINK_CHIPID_STM32_L46X = 0x462, /* covers STM32L45xxx and STM32L46xxx devices */ - STLINK_CHIPID_STM32_L41X = 0x464, /* covers STM32L41xxx and STM32L42xxx devices */ STLINK_CHIPID_STM32_L1_HIGH = 0x436, /* assigned to some L1 "Medium-Plus" and "High" chips */ STLINK_CHIPID_STM32_L152_RE = 0x437, STLINK_CHIPID_STM32_F334 = 0x438, @@ -52,20 +49,25 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F303_HIGH = 0x446, STLINK_CHIPID_STM32_L0_CAT5 = 0x447, STLINK_CHIPID_STM32_F0_CAN = 0x448, - STLINK_CHIPID_STM32_F7 = 0x449, /* ID found on the NucleoF746ZG board */ + STLINK_CHIPID_STM32_F7 = 0x449, STLINK_CHIPID_STM32_H74XXX = 0x450, /* Found on page 3189 in the RM0433*/ STLINK_CHIPID_STM32_F7XXXX = 0x451, - STLINK_CHIPID_STM32_F72XXX = 0x452, /* ID found on the NucleoF722ZE board */ - STLINK_CHIPID_STM32_G0_CAT4 = 0x456, /* G050/G051/G061 found on RM0444/RM0454 */ + STLINK_CHIPID_STM32_F72XXX = 0x452, + STLINK_CHIPID_STM32_G0_CAT4 = 0x456, /* G051/G061 */ STLINK_CHIPID_STM32_L011 = 0x457, STLINK_CHIPID_STM32_F410 = 0x458, STLINK_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/081 */ + STLINK_CHIPID_STM32_L496X = 0x461, /* covers STM32L496xx and STM32L4A6xx devices */ + STLINK_CHIPID_STM32_L46X = 0x462, /* covers STM32L45xxx and STM32L46xxx devices */ STLINK_CHIPID_STM32_F413 = 0x463, + STLINK_CHIPID_STM32_L41X = 0x464, /* covers STM32L41xxx and STM32L42xxx devices */ STLINK_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/041 */ - STLINK_CHIPID_STM32_G0_CAT3 = 0x467, /* G0B0/G0B1/G0C1 found on RM0444/RM0454 */ + STLINK_CHIPID_STM32_G0_CAT3 = 0x467, /* G0B1/G0C1 */ STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* See: RM 0440 s46.6.1 "MCU device ID code" */ STLINK_CHIPID_STM32_G4_CAT3 = 0x469, - STLINK_CHIPID_STM32_L4RX = 0x470, /* ID found on the STM32L4R9I-DISCO board */ + STLINK_CHIPID_STM32_L4RX = 0x470, /* RM0432, p. 2247 */ + STLINK_CHIPID_STM32_L4PX = 0x471, /* RM0432, p. 2247 */ + STLINK_CHIPID_STM32_G4_CAT4 = 0x479, STLINK_CHIPID_STM32_H7AX = 0x480, /* RM0455, p. 2863 */ STLINK_CHIPID_STM32_H72X = 0x483, /* RM0468, p. 3199 */ STLINK_CHIPID_STM32_WB55 = 0x495 From b93f8b220467247af799f6c094cc08972422ae3d Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 24 May 2021 23:10:26 +0500 Subject: [PATCH 1209/1435] Added half page write fallback for stm32L0/L1 --- src/common.c | 55 ++++++++++++++++++++++++++------------------ src/stlink-lib/usb.c | 6 +++++ 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/common.c b/src/common.c index 6333ff408..2d200ba27 100644 --- a/src/common.c +++ b/src/common.c @@ -1994,13 +1994,6 @@ int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem8 ***\n"); - - if (len > 0x40) { // !!! never ever: Writing more then 0x40 bytes gives - // unexpected behaviour - ELOG("Data length > 64: +%d byte.\n", len); - return (-1); - } - return (sl->backend->write_mem8(sl, addr, len)); } @@ -3080,11 +3073,13 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint32_t pagesize) { - unsigned int count; + unsigned int count, size; unsigned int num_half_pages = len / pagesize; uint32_t val; uint32_t flash_regs_base = get_stm32l0_flash_base(sl); flash_loader_t fl; + bool use_loader = false; + int ret = 0; ILOG("Starting Half page flash write for STM32L core id\n"); @@ -3105,17 +3100,34 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, wait_flash_busy(sl); for (count = 0; count < num_half_pages; count++) { - if (stlink_flash_loader_run(sl, &fl, addr + count * pagesize, - base + count * pagesize, pagesize) == -1) { + if (use_loader) { + ret = stlink_flash_loader_run(sl, &fl, addr + count * pagesize, + base + count * pagesize, pagesize); + if (ret && count == 0) { + /* It seems that stm32lx devices have a problem when it is blank */ + WLOG("Failed to use flash loader, fallback to soft write\n"); + use_loader = false; + } + } + if (!use_loader) { + if ((pagesize%64) != 0) { + ELOG("Page size not supported\n"); + break; + } + ret = 0; + for (size = 0; size < pagesize && !ret; size += 64) + { + memcpy(sl->q_buf, base + count * pagesize + size, 64); + ret = stlink_write_mem8(sl, addr + count * pagesize + size, 64); + } + } + + if (ret) { WLOG("l1_stlink_flash_loader_run(%#x) failed! == -1\n", addr + count * pagesize); - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - return (-1); + break; } - // wait for sr.busy to be cleared if (sl->verbose >= 1) { // show progress; writing procedure is slow and previous errors are // misleading @@ -3123,16 +3135,14 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, fflush(stdout); } + // wait for sr.busy to be cleared wait_flash_busy(sl); } stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val &= ~(1 << FLASH_L1_PROG); + val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val &= ~(1 << FLASH_L1_FPRG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - return (0); + return (ret); } int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { @@ -3341,9 +3351,8 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, off = 0; if (len > pagesize) { - if (stm32l1_write_half_pages(sl, addr, base, len, pagesize) == -1) { - // this may happen on a blank device! - WLOG("\nwrite_half_pages failed == -1\n"); + if (stm32l1_write_half_pages(sl, addr, base, len, pagesize)) { + return (-1); } else { off = (size_t)(len / pagesize) * pagesize; } diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index a58681702..1d50bb202 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -328,6 +328,12 @@ int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { unsigned char* const cmd = sl->c_buf; int i, ret; + if ((sl->version.jtag_api < STLINK_JTAG_API_V3 && len > 64) || + (sl->version.jtag_api >= STLINK_JTAG_API_V3 && len > 512)) { + ELOG("WRITEMEM_32BIT: bulk packet limits exceeded (data len %d byte)\n", len); + return (-1); + } + i = fill_command(sl, SG_DXFER_TO_DEV, 0); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_WRITEMEM_8BIT; From 293db13e1daa2c77295a3460a0d46d0ffbd7c82b Mon Sep 17 00:00:00 2001 From: anton Date: Tue, 25 May 2021 22:25:29 +0500 Subject: [PATCH 1210/1435] Changed the half page write fallback to 32 bit write mode --- src/common.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/common.c b/src/common.c index 2d200ba27..d2387d08b 100644 --- a/src/common.c +++ b/src/common.c @@ -3073,27 +3073,18 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint32_t pagesize) { - unsigned int count, size; + unsigned int count, off; unsigned int num_half_pages = len / pagesize; - uint32_t val; + uint32_t val, data; uint32_t flash_regs_base = get_stm32l0_flash_base(sl); flash_loader_t fl; - bool use_loader = false; + bool use_loader = true; int ret = 0; - ILOG("Starting Half page flash write for STM32L core id\n"); - - /* Flash loader initialisation */ - if (stlink_flash_loader_init(sl, &fl) == -1) { - WLOG("stlink_flash_loader_init() == -1\n"); - return (-1); - } - - // unlock already done + // enable half page write stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << FLASH_L1_FPRG); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - val |= (1 << FLASH_L1_PROG); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); @@ -3110,15 +3101,11 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, } } if (!use_loader) { - if ((pagesize%64) != 0) { - ELOG("Page size not supported\n"); - break; - } ret = 0; - for (size = 0; size < pagesize && !ret; size += 64) + for (off = 0; off < pagesize && !ret; off += 4) { - memcpy(sl->q_buf, base + count * pagesize + size, 64); - ret = stlink_write_mem8(sl, addr + count * pagesize + size, 64); + write_uint32((unsigned char *)&data, *(uint32_t *)(base + count * pagesize + off)); + ret = stlink_write_debug32(sl, addr + count * pagesize + off, data); } } @@ -3139,6 +3126,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, wait_flash_busy(sl); } + // disable half page write stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); @@ -3246,6 +3234,12 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { ELOG("pecr.prglock not clear\n"); return (-1); } + + /* Flash loader initialisation */ + if (stlink_flash_loader_init(sl, fl) == -1) { + ELOG("stlink_flash_loader_init() == -1\n"); + return (-1); + } } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { ILOG("Starting Flash write for VL/F0/F3/F1_XL\n"); @@ -3348,6 +3342,8 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, pagesize = L1_WRITE_BLOCK_SIZE; } + DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); + off = 0; if (len > pagesize) { From 9acf539c70e35643be2dc63b0789ff86d878615a Mon Sep 17 00:00:00 2001 From: anton Date: Wed, 26 May 2021 23:04:39 +0500 Subject: [PATCH 1211/1435] Optimizing the half page write fallback --- src/common.c | 23 ++++++++++++----------- src/stlink-lib/flash_loader.c | 10 +++++++--- src/stlink-lib/usb.c | 32 +++++++++++++++++++------------- 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/common.c b/src/common.c index d2387d08b..6d81bf743 100644 --- a/src/common.c +++ b/src/common.c @@ -2636,20 +2636,21 @@ int stlink_fread(stlink_t *sl, const char *path, bool is_ihex, int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, size_t size) { // write the buffer right after the loader + int ret = 0; size_t chunk = size & ~0x3; size_t rem = size & 0x3; if (chunk) { memcpy(sl->q_buf, buf, chunk); - stlink_write_mem32(sl, fl->buf_addr, chunk); + ret = stlink_write_mem32(sl, fl->buf_addr, chunk); } - if (rem) { + if (rem && !ret) { memcpy(sl->q_buf, buf + chunk, rem); - stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, rem); + ret = stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, rem); } - return (0); + return (ret); } uint32_t calculate_F4_sectornum(uint32_t flashaddr) { @@ -3075,7 +3076,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint32_t pagesize) { unsigned int count, off; unsigned int num_half_pages = len / pagesize; - uint32_t val, data; + uint32_t val; uint32_t flash_regs_base = get_stm32l0_flash_base(sl); flash_loader_t fl; bool use_loader = true; @@ -3102,10 +3103,10 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, } if (!use_loader) { ret = 0; - for (off = 0; off < pagesize && !ret; off += 4) - { - write_uint32((unsigned char *)&data, *(uint32_t *)(base + count * pagesize + off)); - ret = stlink_write_debug32(sl, addr + count * pagesize + off, data); + for (off = 0; off < pagesize && !ret; off += 64) { + size_t chunk = (pagesize - off > 64) ? 64 : pagesize - off; + memcpy(sl->q_buf, base + count * pagesize + off, chunk); + ret = stlink_write_mem32(sl, addr + count * pagesize + off, chunk); } } @@ -3237,8 +3238,8 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { /* Flash loader initialisation */ if (stlink_flash_loader_init(sl, fl) == -1) { - ELOG("stlink_flash_loader_init() == -1\n"); - return (-1); + // L0/L1 have fallback to soft write + WLOG("stlink_flash_loader_init() == -1\n"); } } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index d492716db..355223146 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -14,7 +14,13 @@ #define STM32F0_WDG_KR_KEY_RELOAD 0xAAAA -/* DO NOT MODIFY SOURCECODE DIRECTLY, EDIT ASSEMBLY FILES INSTEAD */ +/* !!! + * !!! DO NOT MODIFY FLASH LOADERS DIRECTLY! + * !!! + * + * Edit assembly files in the '/flashloaders' instead. The sizes of binary + * flash loaders must be aligned by 4 (it's written by stlink_write_mem32) + */ /* flashloaders/stm32f0.s -- compiled with thumb2 */ static const uint8_t loader_code_stm32vl[] = { @@ -322,9 +328,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); - // TODO: This can never return -1 if (write_buffer_to_sram(sl, fl, buf, size) == -1) { - // IMPOSSIBLE! ELOG("write_buffer_to_sram() == -1\n"); return(-1); } diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 1d50bb202..5e5f042d5 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -122,16 +122,16 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, retry++; continue; } - WLOG("%s wait error (0x%02X)\n", cmd, rxbuf[0]); + DLOG("%s wait error (0x%02X)\n", cmd, rxbuf[0]); break; - case STLINK_DEBUG_ERR_FAULT: WLOG("%s response fault\n", cmd); break; - case STLINK_DEBUG_ERR_AP_FAULT: WLOG("%s access port fault\n", cmd); break; - case STLINK_DEBUG_ERR_DP_FAULT: WLOG("%s debug port fault\n", cmd); break; - case STLINK_DEBUG_ERR_AP_ERROR: WLOG("%s access port error\n", cmd); break; - case STLINK_DEBUG_ERR_DP_ERROR: WLOG("%s debug port error\n", cmd); break; - case STLINK_DEBUG_ERR_WRITE_VERIFY: WLOG("%s verification error\n", cmd); break; - case STLINK_DEBUG_ERR_WRITE: WLOG("%s write error\n", cmd); break; - default: WLOG("%s error (0x%02X)\n", cmd, rxbuf[0]); break; + case STLINK_DEBUG_ERR_FAULT: DLOG("%s response fault\n", cmd); break; + case STLINK_DEBUG_ERR_AP_FAULT: DLOG("%s access port fault\n", cmd); break; + case STLINK_DEBUG_ERR_DP_FAULT: DLOG("%s debug port fault\n", cmd); break; + case STLINK_DEBUG_ERR_AP_ERROR: DLOG("%s access port error\n", cmd); break; + case STLINK_DEBUG_ERR_DP_ERROR: DLOG("%s debug port error\n", cmd); break; + case STLINK_DEBUG_ERR_WRITE_VERIFY: DLOG("%s verification error\n", cmd); break; + case STLINK_DEBUG_ERR_WRITE: DLOG("%s write error\n", cmd); break; + default: DLOG("%s error (0x%02X)\n", cmd, rxbuf[0]); break; } return(-1); @@ -149,7 +149,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, sg_buf, 13, &res, 3000); if (t) { - ELOG("stlink: %s read storage failed: %s\n", cmd, libusb_error_name(t)); + ELOG("%s read storage failed: %s\n", cmd, libusb_error_name(t)); return(-1); } @@ -306,6 +306,12 @@ int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { unsigned char* const cmd = sl->c_buf; int i, ret; + if ((sl->version.jtag_api < STLINK_JTAG_API_V3 && len > 64) || + (sl->version.jtag_api >= STLINK_JTAG_API_V3 && len > 512)) { + ELOG("WRITEMEM_32BIT: bulk packet limits exceeded (data len %d byte)\n", len); + return (-1); + } + i = fill_command(sl, SG_DXFER_TO_DEV, len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_WRITEMEM_32BIT; @@ -330,7 +336,7 @@ int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { if ((sl->version.jtag_api < STLINK_JTAG_API_V3 && len > 64) || (sl->version.jtag_api >= STLINK_JTAG_API_V3 && len > 512)) { - ELOG("WRITEMEM_32BIT: bulk packet limits exceeded (data len %d byte)\n", len); + ELOG("WRITEMEM_8BIT: bulk packet limits exceeded (data len %d byte)\n", len); return (-1); } @@ -339,11 +345,11 @@ int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { cmd[i++] = STLINK_DEBUG_WRITEMEM_8BIT; write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); - ret = send_only(slu, 0, cmd, slu->cmd_len, "WRITEMEM_32BIT"); + ret = send_only(slu, 0, cmd, slu->cmd_len, "WRITEMEM_8BIT"); if (ret == -1) { return(ret); } - ret = send_only(slu, 1, data, len, "WRITEMEM_32BIT"); + ret = send_only(slu, 1, data, len, "WRITEMEM_8BIT"); if (ret == -1) { return(ret); } From 1d35f95ae088472aad3d246800da34b01a7ed720 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 26 May 2021 23:16:59 +0200 Subject: [PATCH 1212/1435] Updated chip-id descriptions --- src/stlink-lib/chipid.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index f1342dd61..75288093a 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -49,23 +49,25 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_F303_HD = 0x446, /* high density */ STLINK_CHIPID_STM32_L0_CAT5 = 0x447, STLINK_CHIPID_STM32_F0_CAN = 0x448, - STLINK_CHIPID_STM32_F7 = 0x449, /* ID found on the NucleoF746ZG board */ + STLINK_CHIPID_STM32_F7 = 0x449, /* ID found on the Nucleo F746ZG board */ STLINK_CHIPID_STM32_H74xxx = 0x450, /* RM0433, p.3189 */ STLINK_CHIPID_STM32_F76xxx = 0x451, - STLINK_CHIPID_STM32_F72xxx = 0x452, /* ID found on the NucleoF722ZE board */ - STLINK_CHIPID_STM32_G0_CAT4 = 0x456, /* G050/G051/G061 found in RM0444/RM0454 */ + STLINK_CHIPID_STM32_F72xxx = 0x452, /* ID found on the Nucleo F722ZE board */ + STLINK_CHIPID_STM32_G0_CAT4 = 0x456, /* G051/G061 */ STLINK_CHIPID_STM32_L011 = 0x457, STLINK_CHIPID_STM32_F410 = 0x458, - STLINK_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/081 */ + STLINK_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/G081 */ STLINK_CHIPID_STM32_L496x_L4A6x = 0x461, STLINK_CHIPID_STM32_L45x_L46x = 0x462, STLINK_CHIPID_STM32_F413 = 0x463, STLINK_CHIPID_STM32_L41x_L42x = 0x464, - STLINK_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/041 */ - STLINK_CHIPID_STM32_G0_CAT3 = 0x467, /* G0B0/G0B1/G0C1 found in RM0444/RM0454 */ + STLINK_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/G041 */ + STLINK_CHIPID_STM32_G0_CAT3 = 0x467, /* G0B1/G0C1 */ STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* RM0440, s46.6.1 "MCU device ID code" */ STLINK_CHIPID_STM32_G4_CAT3 = 0x469, - STLINK_CHIPID_STM32_L4Rx = 0x470, /* ID found on the STM32L4R9I-DISCO board */ + STLINK_CHIPID_STM32_L4Rx = 0x470, /* RM0432, p. 2247, found on the STM32L4R9I-DISCO board */ + STLINK_CHIPID_STM32_L4PX = 0x471, /* RM0432, p. 2247 */ + STLINK_CHIPID_STM32_G4_CAT4 = 0x479, STLINK_CHIPID_STM32_H7Ax = 0x480, /* RM0455, p.2863 */ STLINK_CHIPID_STM32_H72x = 0x483, /* RM0468, p.3199 */ STLINK_CHIPID_STM32_WB55 = 0x495 From 4949c23771b8348d33719a4275e04861e5068135 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 28 May 2021 09:04:57 +0500 Subject: [PATCH 1213/1435] Fixed clear the H7 dual bank flag --- src/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 80190f756..f347fbc46 100644 --- a/src/common.c +++ b/src/common.c @@ -1664,7 +1664,7 @@ int stlink_load_device_params(stlink_t *sl) { // H7 devices with small flash has one bank if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK && sl->flash_type == STLINK_FLASH_TYPE_H7) { - if ((flash_size / sl->flash_pgsz) <= 1) + if ((sl->flash_size / sl->flash_pgsz) <= 1) sl->chip_flags &= ~CHIP_F_HAS_DUAL_BANK; } From 2e6c909c3e1b32340bdc4f2d2fee4bcdfc0a15f1 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 30 May 2021 23:51:12 +0200 Subject: [PATCH 1214/1435] General Project Update - Removed GitHub-CI VE for Ubuntu 16.04 (deprecated) - Minor fixes for some comments --- .github/workflows/c-cpp.yml | 90 ----------------------------------- doc/devices_boards.md | 2 +- src/stlink-lib/flash_loader.c | 2 +- 3 files changed, 2 insertions(+), 92 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index f68a9e53c..ee06d5469 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -9,96 +9,6 @@ on: jobs: # Linux - job_linux_16_04_64_gcc: - name: ubuntu-16.04 gcc - runs-on: ubuntu-16.04 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean - - job_linux_16_04_32_gcc: - name: ubuntu-16.04 gcc 32-bit - runs-on: ubuntu-16.04 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm - - name: Set compiler flags - run: | - CFLAGS="$CFLAGS -m32" - CXXFLAGS="$CXXFLAGS -m32" - LDFLAGS="$LDFLAGS -m32" - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean - - job_linux_16_04_64_clang: - name: ubuntu-16.04 clang - runs-on: ubuntu-16.04 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean - - job_linux_16_04_32_clang: - name: ubuntu-16.04 clang 32-bit - runs-on: ubuntu-16.04 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm - - name: Set compiler flags - run: | - CFLAGS="$CFLAGS -m32" - CXXFLAGS="$CXXFLAGS -m32" - LDFLAGS="$LDFLAGS -m32" - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean - job_linux_18_04_64_gcc: name: ubuntu-18.04 gcc runs-on: ubuntu-18.04 diff --git a/doc/devices_boards.md b/doc/devices_boards.md index 6548bc734..d93ec7a81 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -51,7 +51,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | ------- | ------------ | ------------- | | 0x411 | STM32F2yyxx | (all devices) | -**STM32F1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM3F1c_CORE_ID)** +**STM32F1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32F1c_CORE_ID)** | Product-Code | Chip-ID | STLink
      Programmer | Boards | | ------------- | ------- | ---------------------- | ----------------------------------------------------------------------------------------------- | diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index d492716db..f013772e3 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -235,7 +235,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_L011 || sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { // STM32l + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { loader_code = loader_code_stm32lx; loader_size = sizeof(loader_code_stm32lx); } else if (sl->core_id == STM32VL_CORE_ID || From 007f39333e884b00c01939eb81757dd0d42c3507 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 31 May 2021 23:35:37 +0200 Subject: [PATCH 1215/1435] Corrected false character in some defines --- src/stlink-lib/chipid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 6fbfce696..8f8f91a9c 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -866,7 +866,7 @@ static struct stlink_chipid_params devices[] = { { // STM32H7A3/7B3 // RM0455 - .chip_id = STLINK_CHIPID_STM32_H7AX, + .chip_id = STLINK_CHIPID_STM32_H7Ax, .description = "H7Ax/H7Bx", .flash_type = STLINK_FLASH_TYPE_H7, .flash_size_reg = 0x08FFF80C, // "Flash size register" (p.2949) @@ -883,7 +883,7 @@ static struct stlink_chipid_params devices[] = { { // STM32H72x/H73x // RM0468 - .chip_id = STLINK_CHIPID_STM32_H72X, + .chip_id = STLINK_CHIPID_STM32_H72x, .description = "H72x/H73x", .flash_type = STLINK_FLASH_TYPE_H7, .flash_size_reg = 0x1FF1E880, // "Flash size register" (p.3286) From 93db93a0ad6ff058d45ef1cccd3a7ece800a5aa4 Mon Sep 17 00:00:00 2001 From: Gustavo Date: Sun, 6 Jun 2021 13:03:59 +0200 Subject: [PATCH 1216/1435] fix for 'libusb_devices were leaked' when no stlink was found --- src/stlink-lib/usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 2754db06f..68e6302b9 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1273,6 +1273,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, if (cnt < 0) { WLOG ("Couldn't find %s ST-Link devices\n", (devBus && devAddr) ? "matched" : "any"); + libusb_free_device_list(list, 1); goto on_error; } else { ret = libusb_open(list[cnt], &slu->usb_handle); From ca896108eedde4a1a4c1ce00a1917771757bf514 Mon Sep 17 00:00:00 2001 From: Gustavo Date: Tue, 15 Jun 2021 20:45:19 +0200 Subject: [PATCH 1217/1435] fix for when the device list was not initialized --- src/stlink-lib/usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 68e6302b9..9f83ace4a 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1203,7 +1203,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, libusb_set_option(slu->libusb_ctx, LIBUSB_OPTION_LOG_LEVEL, ugly_libusb_log_level(verbose)); #endif - libusb_device **list; + libusb_device **list = NULL; // TODO: We should use ssize_t and use it as a counter if > 0. // As per libusb API: ssize_t libusb_get_device_list (libusb_context *ctx, libusb_device ***list) int cnt = (int)libusb_get_device_list(slu->libusb_ctx, &list); @@ -1232,7 +1232,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, ILOG("bus %03d dev %03d\n", devBus, devAddr); } - while (cnt--) { + while (cnt-- > 0) { struct libusb_device_handle *handle; libusb_get_device_descriptor(list[cnt], &desc); From aa70b89b6e33eac460b9e7d0a73231d8a438ee10 Mon Sep 17 00:00:00 2001 From: anton Date: Wed, 23 Jun 2021 22:06:16 +0500 Subject: [PATCH 1218/1435] WRITEMEM_32BIT: removed checks limit --- src/stlink-lib/usb.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 5e5f042d5..0a4cfb489 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -306,12 +306,6 @@ int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { unsigned char* const cmd = sl->c_buf; int i, ret; - if ((sl->version.jtag_api < STLINK_JTAG_API_V3 && len > 64) || - (sl->version.jtag_api >= STLINK_JTAG_API_V3 && len > 512)) { - ELOG("WRITEMEM_32BIT: bulk packet limits exceeded (data len %d byte)\n", len); - return (-1); - } - i = fill_command(sl, SG_DXFER_TO_DEV, len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_WRITEMEM_32BIT; From 88398228a747a72831bcd7e515a965b84a13e79c Mon Sep 17 00:00:00 2001 From: c-grant <60671494+c-grant@users.noreply.github.com> Date: Tue, 13 Jul 2021 22:10:04 -0400 Subject: [PATCH 1219/1435] Update gdb-server.c --- src/st-util/gdb-server.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 6b68c8143..10aaea93a 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -501,6 +501,24 @@ static const char* const memory_map_template_H7 = " " // bootrom ""; +static const char* const memory_map_template_H72X3X = + "" + "" + "" + " " // ITCMRAM 64kB + Optional remap + " " // DTCMRAM 128kB + " " // RAM D1 320kB + " " // RAM D2 23kB + " " // RAM D3 16kB + " " // Backup RAM 4kB + " " + " 0x%x" + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + ""; static const char* const memory_map_template_F4_DE = "" @@ -563,7 +581,11 @@ char* make_memory_map(stlink_t *sl) { snprintf(map, sz, memory_map_template_L496, (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); - } else { + } else if (sl->chip_id == STLINK_CHIPID_STM32_H72X) { + snprintf(map, sz, memory_map_template_H72X3X, + (unsigned int)sl->flash_size, + (unsigned int)sl->flash_pgsz); + } else { snprintf(map, sz, memory_map_template, (unsigned int)sl->flash_size, (unsigned int)sl->sram_size, From 2a3c57747fd0caefca37f81f55be43ad175ffa2d Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 15 Jul 2021 15:59:35 +0500 Subject: [PATCH 1220/1435] Fixed get flash base address for STM32L152RE --- src/common.c | 43 +++++++++---------------------------------- 1 file changed, 9 insertions(+), 34 deletions(-) diff --git a/src/common.c b/src/common.c index f347fbc46..6cec3fde1 100644 --- a/src/common.c +++ b/src/common.c @@ -241,7 +241,6 @@ // STM32L0x flash register base and offsets RM0090 - DM00031020.pdf #define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) -#define STM32L1_FLASH_REGS_ADDR ((uint32_t)0x40023c00) #define STM32L0_FLASH_PELOCK (0) #define STM32L0_FLASH_OPTLOCK (2) @@ -450,10 +449,11 @@ static uint32_t get_stm32l0_flash_base(stlink_t *sl) { case STLINK_CHIPID_STM32_L1_MEDIUM: case STLINK_CHIPID_STM32_L1_MEDIUM_PLUS: case STLINK_CHIPID_STM32_L1_HIGH: - return (STM32L1_FLASH_REGS_ADDR); + case STLINK_CHIPID_STM32_L152_RE: + return (STM32L_FLASH_REGS_ADDR); default: - WLOG("Flash base use default L0 address"); + WLOG("Flash base use default L0 address\n"); return (STM32L0_FLASH_REGS_ADDR); } } @@ -3204,15 +3204,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { ILOG("Starting Flash write for L0\n"); uint32_t val; - uint32_t flash_regs_base; - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L011) { - flash_regs_base = STM32L0_FLASH_REGS_ADDR; - } else { - flash_regs_base = STM32L_FLASH_REGS_ADDR; - } + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); // disable pecr protection stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, @@ -3327,19 +3319,9 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, } } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { uint32_t val; - uint32_t flash_regs_base; - uint32_t pagesize; - - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L011) { - flash_regs_base = STM32L0_FLASH_REGS_ADDR; - pagesize = L0_WRITE_BLOCK_SIZE; - } else { - flash_regs_base = STM32L_FLASH_REGS_ADDR; - pagesize = L1_WRITE_BLOCK_SIZE; - } + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + uint32_t pagesize = (flash_regs_base==STM32L0_FLASH_REGS_ADDR)? + L0_WRITE_BLOCK_SIZE:L1_WRITE_BLOCK_SIZE; off = 0; @@ -3456,15 +3438,8 @@ int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { lock_flash(sl); } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { uint32_t val; - uint32_t flash_regs_base; - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L011) { - flash_regs_base = STM32L0_FLASH_REGS_ADDR; - } else { - flash_regs_base = STM32L_FLASH_REGS_ADDR; - } + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + // reset lock bits stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); From 6e0dbfe97250b6ecba1f86c14d91d01c159b812c Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 16 Jun 2021 13:12:19 +0200 Subject: [PATCH 1221/1435] Removed Travis CI integration Free Trial plan is no longer usable as credits are used up. --- .travis.sh | 46 ---------------------- .travis.yml | 111 ---------------------------------------------------- 2 files changed, 157 deletions(-) delete mode 100755 .travis.sh delete mode 100644 .travis.yml diff --git a/.travis.sh b/.travis.sh deleted file mode 100755 index d8c5377de..000000000 --- a/.travis.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash -echo "-- C compilers available" -ls -1 /usr/bin/gcc* -ls -1 /usr/bin/clang* -ls -1 /usr/bin/scan-build* -echo "----" - -echo "WORK DIR:$DIR" -DIR=$PWD - -if [ "$TRAVIS_JOB_NAME" == "linux-mingw-64" ]; then - echo "--> Building for Windows (x86-64) ..." - mkdir -p build-mingw && cd build-mingw-64 - cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && rm -rf build-mingw-64 && cd - - -elif [ "$TRAVIS_JOB_NAME" == "linux-mingw-32" ]; then - echo "--> Building for Windows (i686) ..." - mkdir -p build-mingw && cd build-mingw-32 - cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && rm -rf build-mingw-32 && cd - - -elif [ "$TRAVIS_OS_NAME" == "osx" ]; then - echo "--> make debug..." - mkdir -p build/Debug && cd build/Debug - cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make debug && cd - - - echo "--> make package..." - mkdir -p build/Release && cd build/Release - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make package && cd - - -else # local test-build - echo "--> Building Debug..." - mkdir -p build/Debug && cd build/Debug - cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install ../../ - make && cd - - - echo "--> Building Release with package..." - mkdir -p build/Release && cd build/Release - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install ../../ - make package && cd - -fi diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 469094892..000000000 --- a/.travis.yml +++ /dev/null @@ -1,111 +0,0 @@ -language: c - -jobs: - include: - ### cross builds on AMD64 ### - - - os: linux - dist: focal - env: BADGE=linux-mingw-64 - name: linux-mingw - compiler: gcc-10 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: - ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] - - - os: linux - dist: focal - env: BADGE=linux-mingw-32 - name: linux-mingw - compiler: gcc-10 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: - ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] - - ### macOS ### - - - os: osx - env: BADGE=osx - osx_image: xcode10.3 # xcode11.3 to xcode11.3.1 fail to compile - name: macOS 10.14.4 gcc - compiler: gcc - addons: - homebrew: - packages: - - gcc - - libusb - - gtk+3 - - - os: osx - env: BADGE=osx - osx_image: xcode10.3 # xcode11.3 to xcode11.3.1 fail to compile - name: macOS 10.14.4 gcc 32-bit - compiler: gcc - addons: - homebrew: - packages: - - gcc - - libusb - - gtk+3 - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - - os: osx - env: BADGE=osx - osx_image: xcode10.3 # xcode11.3 to xcode11.3.1 fail to compile - name: macOS 10.14.4 clang - compiler: clang - addons: - homebrew: - packages: - - clang - - libusb - - gtk+3 - - - os: osx - env: BADGE=osx - osx_image: xcode10.3 # xcode11.3 to xcode11.3.1 fail to compile - name: macOS 10.14.4 clang 32-bit - compiler: clang - addons: - homebrew: - packages: - - clang - - libusb - - gtk+3 - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - - os: osx - env: BADGE=osx - osx_image: xcode12.5 - name: macOS 11.3 gcc - compiler: gcc - addons: - homebrew: - packages: - - gcc - - libusb - - gtk+3 - - - os: osx - env: BADGE=osx - osx_image: xcode12.5 - name: macOS 11.3 clang - compiler: clang - addons: - homebrew: - packages: - - clang - - libusb - - gtk+3 - -script: - - git fetch --tags - - printenv - - cmake --version - - if [[ "$TRAVIS_OS_NAME" == "linux" ]] || [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis.sh; fi From a52e1bc5489e23f3c1071c6912820efacaa3b22c Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 16 Jul 2021 16:00:27 +0200 Subject: [PATCH 1222/1435] Minor bugfixes --- src/common.c | 2 +- src/st-util/gdb-server.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common.c b/src/common.c index 354075d8d..1457d640c 100644 --- a/src/common.c +++ b/src/common.c @@ -449,7 +449,7 @@ static uint32_t get_stm32l0_flash_base(stlink_t *sl) { case STLINK_CHIPID_STM32_L1_MD: case STLINK_CHIPID_STM32_L1_MD_PLUS: case STLINK_CHIPID_STM32_L1_MD_PLUS_HD: - return (STM32L1_FLASH_REGS_ADDR); + return (STM32L_FLASH_REGS_ADDR); default: WLOG("Flash base use default L0 address\n"); diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 2f5ff1143..653c7bcec 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -503,7 +503,7 @@ static const char* const memory_map_template_H7 = " " // bootrom ""; -static const char* const memory_map_template_H72X3X = +static const char* const memory_map_template_H72x3x = "" "" @@ -583,8 +583,8 @@ char* make_memory_map(stlink_t *sl) { snprintf(map, sz, memory_map_template_L496, (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); - } else if (sl->chip_id == STLINK_CHIPID_STM32_H72X) { - snprintf(map, sz, memory_map_template_H72X3X, + } else if (sl->chip_id == STLINK_CHIPID_STM32_H72x) { + snprintf(map, sz, memory_map_template_H72x3x, (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz); } else { From 1dd94a16a8090f17d9c595daf1e899d95c0511ab Mon Sep 17 00:00:00 2001 From: Grzegorz Szymaszek Date: Wed, 28 Jul 2021 16:26:33 +0200 Subject: [PATCH 1223/1435] Do not segfault if cannot find chip in config files stlink_chipid_get_params() used to segfault on memcmp() when struct stlink_chipid_params *params was NULL. This could happen if either: - there were no chip config files (*.chip), or - process_chipfile() failed to parse chip_id from the chip config files. The latter case is caused by the usage of atoi() to parse the chip id. Since the chip id is stored in hex, atoi() returns 0; such id cannot be matched to any actual chip. The segfault occurs on commit a52e1bc5489e23f3c1071c6912820efacaa3b22c, in file src/stlink-lib/chipid.c:957 (https://github.com/stlink-org/stlink/blob/a52e1bc5489e23f3c1071c6912820efacaa3b22c/src/stlink-lib/chipid.c#L957). Check if params is NULL, in such case, set it to p2, which should not be NULL as long as struct stlink_chipid_params devices[] exists. May fix (workaround) #1163. --- src/stlink-lib/chipid.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 8f8f91a9c..ebc3f4e20 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -954,7 +954,9 @@ struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { p2 = stlink_chipid_get_params_old(chipid); #if 1 - if (memcmp (p2, params, sizeof (struct stlink_chipid_params) - sizeof (struct stlink_chipid_params *)) != 0) { + if (params == NULL) { + params = p2; + } else if (memcmp (p2, params, sizeof (struct stlink_chipid_params) - sizeof (struct stlink_chipid_params *)) != 0) { //fprintf (stderr, "Error, chipid params not identical\n"); //return NULL; fprintf(stderr, "---------- old ------------\n"); From 35156b186d7915db52a7fef802d3d10be37bae0b Mon Sep 17 00:00:00 2001 From: Grzegorz Szymaszek Date: Wed, 28 Jul 2021 18:47:25 +0200 Subject: [PATCH 1224/1435] Drop execute bits from source code files --- src/stlink-lib/md5.c | 0 src/stlink-lib/md5.h | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 src/stlink-lib/md5.c mode change 100755 => 100644 src/stlink-lib/md5.h diff --git a/src/stlink-lib/md5.c b/src/stlink-lib/md5.c old mode 100755 new mode 100644 diff --git a/src/stlink-lib/md5.h b/src/stlink-lib/md5.h old mode 100755 new mode 100644 From 26a63c11a4125b7c5b3a2677f342cf13c37f1244 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 28 Jul 2021 22:03:03 +0200 Subject: [PATCH 1225/1435] [doc] Updated list of devices & boards (Closes #1164) --- doc/devices_boards.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/devices_boards.md b/doc/devices_boards.md index d93ec7a81..26bad9150 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -125,9 +125,12 @@ Tested non-official ST boards [incl. STLINK programmers]: **STM32H7 / ARM Cortex M7F / Core-ID: 0x6ba02477 (STM32H7_CORE_ID)** -| Chip-ID | Product-Code | -| ------- | -------------- | -| 0x450 | STM32H74x/H75x | +| Chip-ID | Product-Code | +| ------- | ------------- | +| 0x450 | STM32H7**4**x | +| 0x450 | STM32H7**5**x | +| 0x480 | STM32H7**A**x | +| 0x480 | STM32H7**B**x | **STM32G0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32G0_CORE_ID)** @@ -146,6 +149,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x468 | STM32G4**41**xx | | 0x469 | STM32G4**7**xxx | | 0x469 | STM32G4**8**xxx | +| 0x479 | STM32G4**91**xx | **STM32L0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32L0_CORE_ID)** From b4245eadd0877546a5287a0365211d2d5c24273f Mon Sep 17 00:00:00 2001 From: Grzegorz Szymaszek Date: Thu, 29 Jul 2021 15:46:53 +0200 Subject: [PATCH 1226/1435] Use proper Markdown headers for supported MCUs Use actual level 2 headers[1] instead of emulating them with bold/strong tags[2]. [1]: https://spec.commonmark.org/0.29/#atx-headings [2]: https://spec.commonmark.org/0.29/#emphasis-and-strong-emphasis --- doc/devices_boards.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/doc/devices_boards.md b/doc/devices_boards.md index 26bad9150..a8a366448 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -2,7 +2,7 @@ The following devices are supported by the stlink toolset. -**STM32F0 / ARM Cortex M0 / Core-ID: 0x0bb11477 (STM32F0_CORE_ID)** +## STM32F0 / ARM Cortex M0 / Core-ID: 0x0bb11477 (STM32F0_CORE_ID) | Chip-ID | Product-Code | | ------- | ------------------- | @@ -19,7 +19,7 @@ The following devices are supported by the stlink toolset. | 0x442 | STM32F0**9**xxx | -**STM32F1 / ARM Cortex M3 / Core-ID: 0x1ba01477 (STM32F1_CORE_ID)** +## STM32F1 / ARM Cortex M3 / Core-ID: 0x1ba01477 (STM32F1_CORE_ID) | Product-Code | Product Line | | ----------------- | ----------------------- | @@ -45,20 +45,20 @@ Tested non-official ST boards [incl. STLINK programmers]: - HY-STM32 (STM32F103VETx) [v1, v2] - DecaWave EVB1000 (STM32F105RCTx) [v1, v2] -**STM32F2 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32F2_CORE_ID)** +## STM32F2 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32F2_CORE_ID) | Chip-ID | Product-Code | Product Line | | ------- | ------------ | ------------- | | 0x411 | STM32F2yyxx | (all devices) | -**STM32F1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32F1c_CORE_ID)** +## STM32F1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32F1c_CORE_ID) | Product-Code | Chip-ID | STLink
      Programmer | Boards | | ------------- | ------- | ---------------------- | ----------------------------------------------------------------------------------------------- | | CKS32F103C8Tx | 0x410 | v2 | "STM32"-Bluepill ( _**Fake-Marking !**_ )
      STM32F103C8T6 clone from China Key Systems (CKS) | | CKS32F103C8Tx | 0x410 | v2 | CKS32-Bluepill (Clone)
      STM32F103C8T6 clone from China Key Systems (CKS) | -**STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3_CORE_ID)** +## STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3_CORE_ID) | Product-Code | Product Line | | ----------------- | ------------------------------------------------------------- | @@ -85,13 +85,13 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x446 | _N/A_ | xD xE | | F302 | F303 | | | 0x446 | _N/A_ | - | | | | F398 | -**STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3c_CORE_ID)** +## STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3c_CORE_ID) | Product-Code | Chip-ID | STLINK
      Programmer | Boards | | ------------ | ------- | ---------------------- | ---------------------------------- | | GD32F303VGT6 | 0x430 | [v2] | STM32F303 clone from GigaDevice GD | -**STM32F4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F4_CORE_ID)** +## STM32F4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F4_CORE_ID) | Chip-ID | Product-Code | | ------- | ------------------- | @@ -112,7 +112,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x463 | STM32F4**13**xx | | 0x463 | STM32F4**23**xx | -**STM32F7 / ARM Cortex M7F / Core-ID: 0x5ba02477 (STM32F7_CORE_ID)** +## STM32F7 / ARM Cortex M7F / Core-ID: 0x5ba02477 (STM32F7_CORE_ID) | Chip-ID | Product-Code | | ------- | --------------- | @@ -123,7 +123,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x451 | STM32F7**6**xxx | | 0x451 | STM32F7**7**xxx | -**STM32H7 / ARM Cortex M7F / Core-ID: 0x6ba02477 (STM32H7_CORE_ID)** +## STM32H7 / ARM Cortex M7F / Core-ID: 0x6ba02477 (STM32H7_CORE_ID) | Chip-ID | Product-Code | | ------- | ------------- | @@ -132,7 +132,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x480 | STM32H7**A**x | | 0x480 | STM32H7**B**x | -**STM32G0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32G0_CORE_ID)** +## STM32G0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32G0_CORE_ID) | Chip-ID | Product-Code | | ------- | --------------- | @@ -141,7 +141,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x460 | STM32G0**7**xxx | | 0x460 | STM32G0**8**xxx | -**STM32G4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32G4_CORE_ID)** +## STM32G4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32G4_CORE_ID) | Chip-ID | Product-Code | | ------- | --------------- | @@ -151,7 +151,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x469 | STM32G4**8**xxx | | 0x479 | STM32G4**91**xx | -**STM32L0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32L0_CORE_ID)** +## STM32L0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32L0_CORE_ID) | Chip-ID | Product-Code | | ------- | --------------- | @@ -164,7 +164,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x447 | STM32L0**7**xxx | | 0x447 | STM32L0**8**xxx | -**STM32L1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32L1_CORE_ID)** +## STM32L1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32L1_CORE_ID) | Chip-ID | Product-Code | | ------- | ---------------- | @@ -178,7 +178,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x436 | STM32L1xxx**D** | | 0x437 | STM32L1xxx**E** | -**STM32L4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32L4_CORE_ID)** +## STM32L4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32L4_CORE_ID) | Chip-ID | Product-Code | | ------- | --------------- | @@ -197,7 +197,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x471 | STM32L4**P5**xx | | 0x471 | STM32L4**Q5**xx | -**STM32W / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32W_CORE_ID)** +## STM32W / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32W_CORE_ID) | Chip-ID | Product-Code | | ------- | --------------- | From e4b17475d179b37e60b686027d338891641effc1 Mon Sep 17 00:00:00 2001 From: Grzegorz Szymaszek Date: Thu, 29 Jul 2021 21:48:53 +0200 Subject: [PATCH 1227/1435] Fix parsing hex numbers in chip config files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit process_chipfile() used to improperly parse hex numbers in chip config files (*.chip), because it used atoi(), which read all such numbers as 0. This resulted, among other issues, in chip_id being set to 0 for all read chips. Such chip id could not match any actual MCU. Replace the atoi() calls with sscanf(…, "%i", …), where %i should match integers in base 10, 8 and 16, depending on the number prefix. --- src/stlink-lib/chipid.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 8f8f91a9c..2e99c580e 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -973,7 +973,7 @@ void process_chipfile(char *fname) char *p, *pp, buf[1025]; char word[64], value[64]; struct stlink_chipid_params *ts; - int nc, ival; + int nc; //fprintf (stderr, "processing chipfile %s.\n", fname); fp = fopen(fname, "r"); @@ -989,30 +989,39 @@ void process_chipfile(char *fname) if (*p == '#') continue; // ignore comments. sscanf(p, "%s %s", word, value); - ival = atoi (value); if (strcmp(word, "chip_id") == 0) { - ts->chip_id = ival; + if (sscanf(value, "%i", &ts->chip_id) < 1) + fprintf(stderr, "Failed to parse chip id\n"); } else if (strcmp (word, "description") == 0) { //ts->description = strdup (value); buf[strlen(p)-1] = 0; // chomp newline sscanf(p, "%*s %n", &nc); ts->description = strdup(p+nc); } else if (strcmp (word, "flash_type") == 0) { - ts->flash_type = ival; + // may set invalid flash types (not defined in enum stlink_flash_type) + if (sscanf(value, "%i", (int *) &ts->flash_type) < 1) + fprintf(stderr, "Failed to parse flash type\n"); } else if (strcmp (word, "flash_size_reg") == 0) { - ts->flash_size_reg = ival; + if (sscanf(value, "%i", &ts->flash_size_reg) < 1) + fprintf(stderr, "Failed to parse flash size reg\n"); } else if (strcmp (word, "flash_pagesize") == 0) { - ts->flash_pagesize = ival; + if (sscanf(value, "%i", &ts->flash_pagesize) < 1) + fprintf(stderr, "Failed to parse flash page size\n"); } else if (strcmp (word, "sram_size") == 0) { - ts->sram_size = ival; + if (sscanf(value, "%i", &ts->sram_size) < 1) + fprintf(stderr, "Failed to parse SRAM size\n"); } else if (strcmp (word, "bootrom_base") == 0) { - ts->bootrom_base = ival; + if (sscanf(value, "%i", &ts->bootrom_base) < 1) + fprintf(stderr, "Failed to parse BootROM base\n"); } else if (strcmp (word, "bootrom_size") == 0) { - ts->bootrom_size = ival; + if (sscanf(value, "%i", &ts->bootrom_size) < 1) + fprintf(stderr, "Failed to parse BootROM size\n"); } else if (strcmp (word, "option_base") == 0) { - ts->option_base = ival; + if (sscanf(value, "%i", &ts->option_base) < 1) + fprintf(stderr, "Failed to parse option base\n"); } else if (strcmp (word, "option_size") == 0) { - ts->option_size = ival; + if (sscanf(value, "%i", &ts->option_size) < 1) + fprintf(stderr, "Failed to parse option size\n"); } else if (strcmp (word, "flags") == 0) { pp = strtok (p, " \t\n"); while ((pp = strtok (NULL, " \t\n")) ) { From 929af2b047b7dfc54750842100a285646fb4a417 Mon Sep 17 00:00:00 2001 From: Grzegorz Szymaszek Date: Fri, 30 Jul 2021 10:14:17 +0200 Subject: [PATCH 1228/1435] Add a constant for the valid flash types range Add a STLINK_FLASH_TYPE_MAX constant that can be used to check if a flash type (an integer) is in the range of valid enum stlink_flash_type values. --- inc/stlink.h | 1 + 1 file changed, 1 insertion(+) diff --git a/inc/stlink.h b/inc/stlink.h index f70060b05..81dc7902e 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -114,6 +114,7 @@ enum stlink_flash_type { STLINK_FLASH_TYPE_G4, STLINK_FLASH_TYPE_WB, STLINK_FLASH_TYPE_H7, + STLINK_FLASH_TYPE_MAX, }; struct stlink_reg { From ebac01c8d4e436f45afcc35c4452ffdb3750a13f Mon Sep 17 00:00:00 2001 From: Grzegorz Szymaszek Date: Fri, 30 Jul 2021 10:18:02 +0200 Subject: [PATCH 1229/1435] Warn if chip config file contains unrecognized flash type --- src/stlink-lib/chipid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 2e99c580e..5080ef756 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -998,9 +998,10 @@ void process_chipfile(char *fname) sscanf(p, "%*s %n", &nc); ts->description = strdup(p+nc); } else if (strcmp (word, "flash_type") == 0) { - // may set invalid flash types (not defined in enum stlink_flash_type) if (sscanf(value, "%i", (int *) &ts->flash_type) < 1) fprintf(stderr, "Failed to parse flash type\n"); + else if (ts->flash_type <= STLINK_FLASH_TYPE_UNKNOWN || ts->flash_type >= STLINK_FLASH_TYPE_MAX) + fprintf(stderr, "Unrecognized flash type\n"); } else if (strcmp (word, "flash_size_reg") == 0) { if (sscanf(value, "%i", &ts->flash_size_reg) < 1) fprintf(stderr, "Failed to parse flash size reg\n"); From 1e674cff1a3557969b9dd55db9d13d9d40c2de93 Mon Sep 17 00:00:00 2001 From: Sam Bazley Date: Sun, 1 Aug 2021 21:36:40 +0100 Subject: [PATCH 1230/1435] Correct flash_pagesize to use hex format --- config/chips/F04x.chip | 2 +- config/chips/F07x.chip | 2 +- config/chips/F09x.chip | 2 +- config/chips/F0xx.chip | 2 +- config/chips/F0xx_small.chip | 2 +- config/chips/F1_XL-density.chip | 2 +- config/chips/F1_connectivity_line.chip | 2 +- config/chips/F1_high-density.chip | 2 +- config/chips/F1_low-density.chip | 2 +- config/chips/F1_medium-density.chip | 2 +- config/chips/F1_value_line.chip | 2 +- config/chips/F1_value_line_high-density.chip | 2 +- config/chips/F2.chip | 2 +- config/chips/F303_high_density.chip | 2 +- config/chips/F334_medium_density.chip | 2 +- config/chips/F37x.chip | 2 +- config/chips/F3xx_small.chip | 2 +- config/chips/F410.chip | 2 +- config/chips/F411xx.chip | 2 +- config/chips/F412.chip | 2 +- config/chips/F413.chip | 2 +- config/chips/F42x_F43x.chip | 2 +- config/chips/F446.chip | 2 +- config/chips/F46x_F47x.chip | 2 +- config/chips/F4xx.chip | 2 +- config/chips/F4xx_dynamic_efficiency.chip | 2 +- config/chips/F4xx_low_power.chip | 2 +- config/chips/F72x_F73x.chip | 2 +- config/chips/F76xxx.chip | 2 +- config/chips/F7xx.chip | 2 +- config/chips/G030_G031_G041.chip | 2 +- config/chips/G070_G071_G081.chip | 2 +- config/chips/G4_cat2.chip | 2 +- config/chips/G4_cat3.chip | 2 +- config/chips/H72x_H73x.chip | 2 +- config/chips/H74x_H75x.chip | 2 +- config/chips/H7Ax_H7Bx.chip | 2 +- config/chips/L011.chip | 2 +- config/chips/L0xx_cat2.chip | 2 +- config/chips/L0xx_cat5.chip | 2 +- config/chips/L152RE.chip | 2 +- config/chips/L1xx_cat2.chip | 2 +- config/chips/L1xx_high-density.chip | 2 +- config/chips/L1xx_medium-density.chip | 2 +- config/chips/L1xx_medium-plus-density.chip | 2 +- config/chips/L41x.chip | 2 +- config/chips/L43x_L44x.chip | 2 +- config/chips/L45x_L46x.chip | 2 +- config/chips/L496x_L4A6x.chip | 2 +- config/chips/L4Rx.chip | 2 +- config/chips/L4xx.chip | 2 +- config/chips/WB55.chip | 2 +- config/chips/unknown_device.chip | 2 +- 53 files changed, 53 insertions(+), 53 deletions(-) diff --git a/config/chips/F04x.chip b/config/chips/F04x.chip index b42d420fa..033c034e2 100644 --- a/config/chips/F04x.chip +++ b/config/chips/F04x.chip @@ -3,7 +3,7 @@ chip_id 0x445 description F04x flash_type 1 -flash_pagesize 400 +flash_pagesize 0x400 sram_size 0x1800 bootrom_base 0x1fffec00 bootrom_size 0xc00 diff --git a/config/chips/F07x.chip b/config/chips/F07x.chip index d8c71f0ea..dd697af40 100644 --- a/config/chips/F07x.chip +++ b/config/chips/F07x.chip @@ -3,7 +3,7 @@ chip_id 0x448 description F07x flash_type 1 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x4000 bootrom_base 0x1fffc800 bootrom_size 0x3000 diff --git a/config/chips/F09x.chip b/config/chips/F09x.chip index ca97d53e4..adb000030 100644 --- a/config/chips/F09x.chip +++ b/config/chips/F09x.chip @@ -3,7 +3,7 @@ chip_id 0x442 description F09x flash_type 1 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x8000 bootrom_base 0x1fffd800 bootrom_size 0x2000 diff --git a/config/chips/F0xx.chip b/config/chips/F0xx.chip index a1700eef3..309bbee34 100644 --- a/config/chips/F0xx.chip +++ b/config/chips/F0xx.chip @@ -3,7 +3,7 @@ chip_id 0x440 description F0xx flash_type 1 -flash_pagesize 400 +flash_pagesize 0x400 sram_size 0x2000 bootrom_base 0x1fffec00 bootrom_size 0xc00 diff --git a/config/chips/F0xx_small.chip b/config/chips/F0xx_small.chip index 3ab256feb..0a8ec265e 100644 --- a/config/chips/F0xx_small.chip +++ b/config/chips/F0xx_small.chip @@ -3,7 +3,7 @@ chip_id 0x444 description F0xx small flash_type 1 -flash_pagesize 400 +flash_pagesize 0x400 sram_size 0x1000 bootrom_base 0x1fffec00 bootrom_size 0xc00 diff --git a/config/chips/F1_XL-density.chip b/config/chips/F1_XL-density.chip index 97bb580e3..3b3c95ab0 100644 --- a/config/chips/F1_XL-density.chip +++ b/config/chips/F1_XL-density.chip @@ -3,7 +3,7 @@ chip_id 0x430 description F1 XL-density flash_type 2 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x18000 bootrom_base 0x1fffe000 bootrom_size 0x1800 diff --git a/config/chips/F1_connectivity_line.chip b/config/chips/F1_connectivity_line.chip index a030fd58d..b6fd9c93a 100644 --- a/config/chips/F1_connectivity_line.chip +++ b/config/chips/F1_connectivity_line.chip @@ -3,7 +3,7 @@ chip_id 0x418 description F1 connectivity line flash_type 1 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x10000 bootrom_base 0x1fffb000 bootrom_size 0x4800 diff --git a/config/chips/F1_high-density.chip b/config/chips/F1_high-density.chip index 00e4942b0..f88413fc8 100644 --- a/config/chips/F1_high-density.chip +++ b/config/chips/F1_high-density.chip @@ -3,7 +3,7 @@ chip_id 0x414 description F1 high-density flash_type 1 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x10000 bootrom_base 0x1ffff000 bootrom_size 0x800 diff --git a/config/chips/F1_low-density.chip b/config/chips/F1_low-density.chip index 1562c7589..3995cad96 100644 --- a/config/chips/F1_low-density.chip +++ b/config/chips/F1_low-density.chip @@ -3,7 +3,7 @@ chip_id 0x412 description F1 low-density flash_type 1 -flash_pagesize 400 +flash_pagesize 0x400 sram_size 0x2800 bootrom_base 0x1ffff000 bootrom_size 0x800 diff --git a/config/chips/F1_medium-density.chip b/config/chips/F1_medium-density.chip index 1f3d89234..25cbec2dc 100644 --- a/config/chips/F1_medium-density.chip +++ b/config/chips/F1_medium-density.chip @@ -3,7 +3,7 @@ chip_id 0x410 description F1 medium-density flash_type 1 -flash_pagesize 400 +flash_pagesize 0x400 sram_size 0x5000 bootrom_base 0x1ffff000 bootrom_size 0x800 diff --git a/config/chips/F1_value_line.chip b/config/chips/F1_value_line.chip index d9f04f00a..5515d9acd 100644 --- a/config/chips/F1_value_line.chip +++ b/config/chips/F1_value_line.chip @@ -3,7 +3,7 @@ chip_id 0x420 description F1 value line flash_type 1 -flash_pagesize 400 +flash_pagesize 0x400 sram_size 0x2000 bootrom_base 0x1ffff000 bootrom_size 0x800 diff --git a/config/chips/F1_value_line_high-density.chip b/config/chips/F1_value_line_high-density.chip index 2ecf6b4f5..6a49c2699 100644 --- a/config/chips/F1_value_line_high-density.chip +++ b/config/chips/F1_value_line_high-density.chip @@ -3,7 +3,7 @@ chip_id 0x428 description F1 value line high-density flash_type 1 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x8000 bootrom_base 0x1ffff000 bootrom_size 0x800 diff --git a/config/chips/F2.chip b/config/chips/F2.chip index 098ddc863..31a4d34a8 100644 --- a/config/chips/F2.chip +++ b/config/chips/F2.chip @@ -3,7 +3,7 @@ chip_id 0x411 description F2 flash_type 3 -flash_pagesize 20000 +flash_pagesize 0x20000 sram_size 0x20000 bootrom_base 0x1fff0000 bootrom_size 0x7800 diff --git a/config/chips/F303_high_density.chip b/config/chips/F303_high_density.chip index 19cc2ad2a..afbdf63b5 100644 --- a/config/chips/F303_high_density.chip +++ b/config/chips/F303_high_density.chip @@ -3,7 +3,7 @@ chip_id 0x446 description F303 high density flash_type 1 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x10000 bootrom_base 0x1fffd800 bootrom_size 0x2000 diff --git a/config/chips/F334_medium_density.chip b/config/chips/F334_medium_density.chip index ba4cf9688..365931a01 100644 --- a/config/chips/F334_medium_density.chip +++ b/config/chips/F334_medium_density.chip @@ -3,7 +3,7 @@ chip_id 0x438 description F334 medium density flash_type 1 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x3000 bootrom_base 0x1fffd800 bootrom_size 0x2000 diff --git a/config/chips/F37x.chip b/config/chips/F37x.chip index d0081e68a..5d5723b14 100644 --- a/config/chips/F37x.chip +++ b/config/chips/F37x.chip @@ -3,7 +3,7 @@ chip_id 0x432 description F37x flash_type 1 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0xa000 bootrom_base 0x1ffff000 bootrom_size 0x800 diff --git a/config/chips/F3xx_small.chip b/config/chips/F3xx_small.chip index 34d1940ac..31fd136a8 100644 --- a/config/chips/F3xx_small.chip +++ b/config/chips/F3xx_small.chip @@ -3,7 +3,7 @@ chip_id 0x439 description F3xx small flash_type 1 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0xa000 bootrom_base 0x1fffd800 bootrom_size 0x2000 diff --git a/config/chips/F410.chip b/config/chips/F410.chip index 3cd382845..ae199d9c4 100644 --- a/config/chips/F410.chip +++ b/config/chips/F410.chip @@ -3,7 +3,7 @@ chip_id 0x458 description F410 flash_type 3 -flash_pagesize 4000 +flash_pagesize 0x4000 sram_size 0x8000 bootrom_base 0x1fff0000 bootrom_size 0x7800 diff --git a/config/chips/F411xx.chip b/config/chips/F411xx.chip index 301e6cb91..e41288de7 100644 --- a/config/chips/F411xx.chip +++ b/config/chips/F411xx.chip @@ -3,7 +3,7 @@ chip_id 0x431 description F411xx flash_type 3 -flash_pagesize 4000 +flash_pagesize 0x4000 sram_size 0x20000 bootrom_base 0x1fff0000 bootrom_size 0x7800 diff --git a/config/chips/F412.chip b/config/chips/F412.chip index 186a43427..3212a340c 100644 --- a/config/chips/F412.chip +++ b/config/chips/F412.chip @@ -3,7 +3,7 @@ chip_id 0x441 description F412 flash_type 3 -flash_pagesize 4000 +flash_pagesize 0x4000 sram_size 0x40000 bootrom_base 0x1fff0000 bootrom_size 0x7800 diff --git a/config/chips/F413.chip b/config/chips/F413.chip index 367344aaa..94813647f 100644 --- a/config/chips/F413.chip +++ b/config/chips/F413.chip @@ -3,7 +3,7 @@ chip_id 0x463 description F413 flash_type 3 -flash_pagesize 4000 +flash_pagesize 0x4000 sram_size 0x50000 bootrom_base 0x1fff0000 bootrom_size 0x7800 diff --git a/config/chips/F42x_F43x.chip b/config/chips/F42x_F43x.chip index 4557a731c..3184d0d4f 100644 --- a/config/chips/F42x_F43x.chip +++ b/config/chips/F42x_F43x.chip @@ -3,7 +3,7 @@ chip_id 0x419 description F42x/F43x flash_type 3 -flash_pagesize 4000 +flash_pagesize 0x4000 sram_size 0x40000 bootrom_base 0x1fff0000 bootrom_size 0x7800 diff --git a/config/chips/F446.chip b/config/chips/F446.chip index 9f7ae0bc5..86cee6a56 100644 --- a/config/chips/F446.chip +++ b/config/chips/F446.chip @@ -3,7 +3,7 @@ chip_id 0x421 description F446 flash_type 3 -flash_pagesize 20000 +flash_pagesize 0x20000 sram_size 0x20000 bootrom_base 0x1fff0000 bootrom_size 0x7800 diff --git a/config/chips/F46x_F47x.chip b/config/chips/F46x_F47x.chip index 8ae43eb2e..ee5f6a5a7 100644 --- a/config/chips/F46x_F47x.chip +++ b/config/chips/F46x_F47x.chip @@ -3,7 +3,7 @@ chip_id 0x434 description F46x/F47x flash_type 3 -flash_pagesize 4000 +flash_pagesize 0x4000 sram_size 0x40000 bootrom_base 0x1fff0000 bootrom_size 0x7800 diff --git a/config/chips/F4xx.chip b/config/chips/F4xx.chip index 17ec62d68..1c6d087a5 100644 --- a/config/chips/F4xx.chip +++ b/config/chips/F4xx.chip @@ -3,7 +3,7 @@ chip_id 0x413 description F4xx flash_type 3 -flash_pagesize 4000 +flash_pagesize 0x4000 sram_size 0x30000 bootrom_base 0x1fff0000 bootrom_size 0x7800 diff --git a/config/chips/F4xx_dynamic_efficiency.chip b/config/chips/F4xx_dynamic_efficiency.chip index 6d06bcb8e..02a886c26 100644 --- a/config/chips/F4xx_dynamic_efficiency.chip +++ b/config/chips/F4xx_dynamic_efficiency.chip @@ -3,7 +3,7 @@ chip_id 0x433 description F4xx dynamic efficiency flash_type 3 -flash_pagesize 4000 +flash_pagesize 0x4000 sram_size 0x18000 bootrom_base 0x1fff0000 bootrom_size 0x7800 diff --git a/config/chips/F4xx_low_power.chip b/config/chips/F4xx_low_power.chip index ad8c3ce90..7c1cc1243 100644 --- a/config/chips/F4xx_low_power.chip +++ b/config/chips/F4xx_low_power.chip @@ -3,7 +3,7 @@ chip_id 0x423 description F4xx low power flash_type 3 -flash_pagesize 4000 +flash_pagesize 0x4000 sram_size 0x10000 bootrom_base 0x1fff0000 bootrom_size 0x7800 diff --git a/config/chips/F72x_F73x.chip b/config/chips/F72x_F73x.chip index b6f706994..2836040ac 100644 --- a/config/chips/F72x_F73x.chip +++ b/config/chips/F72x_F73x.chip @@ -3,7 +3,7 @@ chip_id 0x452 description F72x/F73x flash_type 3 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x40000 bootrom_base 0x100000 bootrom_size 0xedc0 diff --git a/config/chips/F76xxx.chip b/config/chips/F76xxx.chip index 49ac1ec21..ef17fc557 100644 --- a/config/chips/F76xxx.chip +++ b/config/chips/F76xxx.chip @@ -3,7 +3,7 @@ chip_id 0x451 description F76xxx flash_type 4 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x80000 bootrom_base 0x200000 bootrom_size 0xedc0 diff --git a/config/chips/F7xx.chip b/config/chips/F7xx.chip index 87420f2ab..b6e3774f7 100644 --- a/config/chips/F7xx.chip +++ b/config/chips/F7xx.chip @@ -3,7 +3,7 @@ chip_id 0x449 description F7xx flash_type 3 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x50000 bootrom_base 0x100000 bootrom_size 0xedc0 diff --git a/config/chips/G030_G031_G041.chip b/config/chips/G030_G031_G041.chip index 7d47e7aed..16a9a79ff 100644 --- a/config/chips/G030_G031_G041.chip +++ b/config/chips/G030_G031_G041.chip @@ -3,7 +3,7 @@ chip_id 0x466 description G030/G031/G041 flash_type 7 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x2000 bootrom_base 0x1fff0000 bootrom_size 0x2000 diff --git a/config/chips/G070_G071_G081.chip b/config/chips/G070_G071_G081.chip index 9905fc682..7fb81eb1f 100644 --- a/config/chips/G070_G071_G081.chip +++ b/config/chips/G070_G071_G081.chip @@ -3,7 +3,7 @@ chip_id 0x460 description G070/G071/G081 flash_type 7 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x9000 bootrom_base 0x1fff0000 bootrom_size 0x7000 diff --git a/config/chips/G4_cat2.chip b/config/chips/G4_cat2.chip index 47745e715..ea144114d 100644 --- a/config/chips/G4_cat2.chip +++ b/config/chips/G4_cat2.chip @@ -3,7 +3,7 @@ chip_id 0x468 description G4 cat2 flash_type 8 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x8000 bootrom_base 0x1fff0000 bootrom_size 0x7000 diff --git a/config/chips/G4_cat3.chip b/config/chips/G4_cat3.chip index f883b9176..7e34e001c 100644 --- a/config/chips/G4_cat3.chip +++ b/config/chips/G4_cat3.chip @@ -3,7 +3,7 @@ chip_id 0x469 description G4 cat3 flash_type 8 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x18000 bootrom_base 0x1fff0000 bootrom_size 0x7000 diff --git a/config/chips/H72x_H73x.chip b/config/chips/H72x_H73x.chip index 81c1b71c9..df20037d3 100644 --- a/config/chips/H72x_H73x.chip +++ b/config/chips/H72x_H73x.chip @@ -3,7 +3,7 @@ chip_id 0x483 description H72x/H73x flash_type 10 -flash_pagesize 20000 +flash_pagesize 0x20000 sram_size 0x20000 bootrom_base 0x1ff00000 bootrom_size 0x20000 diff --git a/config/chips/H74x_H75x.chip b/config/chips/H74x_H75x.chip index 7753cfe03..7a4bc86e3 100644 --- a/config/chips/H74x_H75x.chip +++ b/config/chips/H74x_H75x.chip @@ -3,7 +3,7 @@ chip_id 0x450 description H74x/H75x flash_type 10 -flash_pagesize 20000 +flash_pagesize 0x20000 sram_size 0x20000 bootrom_base 0x1ff00000 bootrom_size 0x20000 diff --git a/config/chips/H7Ax_H7Bx.chip b/config/chips/H7Ax_H7Bx.chip index df6c13726..b9202bd1a 100644 --- a/config/chips/H7Ax_H7Bx.chip +++ b/config/chips/H7Ax_H7Bx.chip @@ -3,7 +3,7 @@ chip_id 0x480 description H7Ax/H7Bx flash_type 10 -flash_pagesize 2000 +flash_pagesize 0x2000 sram_size 0x20000 bootrom_base 0x1ff00000 bootrom_size 0x20000 diff --git a/config/chips/L011.chip b/config/chips/L011.chip index 2f1fa7b56..719185558 100644 --- a/config/chips/L011.chip +++ b/config/chips/L011.chip @@ -3,7 +3,7 @@ chip_id 0x457 description L011 flash_type 5 -flash_pagesize 80 +flash_pagesize 0x80 sram_size 0x2000 bootrom_base 0x1ff00000 bootrom_size 0x2000 diff --git a/config/chips/L0xx_cat2.chip b/config/chips/L0xx_cat2.chip index 43a301b27..cdcff81cc 100644 --- a/config/chips/L0xx_cat2.chip +++ b/config/chips/L0xx_cat2.chip @@ -3,7 +3,7 @@ chip_id 0x425 description L0xx cat2 flash_type 5 -flash_pagesize 80 +flash_pagesize 0x80 sram_size 0x2000 bootrom_base 0x1ff0000 bootrom_size 0x1000 diff --git a/config/chips/L0xx_cat5.chip b/config/chips/L0xx_cat5.chip index 8ab0a50f8..2c755a0d8 100644 --- a/config/chips/L0xx_cat5.chip +++ b/config/chips/L0xx_cat5.chip @@ -3,7 +3,7 @@ chip_id 0x447 description L0xx cat5 flash_type 5 -flash_pagesize 80 +flash_pagesize 0x80 sram_size 0x5000 bootrom_base 0x1ff0000 bootrom_size 0x2000 diff --git a/config/chips/L152RE.chip b/config/chips/L152RE.chip index ebe012c5a..4d9658ee9 100644 --- a/config/chips/L152RE.chip +++ b/config/chips/L152RE.chip @@ -3,7 +3,7 @@ chip_id 0x437 description L152RE flash_type 5 -flash_pagesize 100 +flash_pagesize 0x100 sram_size 0x14000 bootrom_base 0x1ff00000 bootrom_size 0x1000 diff --git a/config/chips/L1xx_cat2.chip b/config/chips/L1xx_cat2.chip index 02012078a..7f949923e 100644 --- a/config/chips/L1xx_cat2.chip +++ b/config/chips/L1xx_cat2.chip @@ -3,7 +3,7 @@ chip_id 0x429 description L1xx cat2 flash_type 5 -flash_pagesize 100 +flash_pagesize 0x100 sram_size 0x8000 bootrom_base 0x1ff00000 bootrom_size 0x1000 diff --git a/config/chips/L1xx_high-density.chip b/config/chips/L1xx_high-density.chip index 130b4e456..409c04062 100644 --- a/config/chips/L1xx_high-density.chip +++ b/config/chips/L1xx_high-density.chip @@ -3,7 +3,7 @@ chip_id 0x436 description L1xx high-density flash_type 5 -flash_pagesize 100 +flash_pagesize 0x100 sram_size 0xc000 bootrom_base 0x1ff00000 bootrom_size 0x1000 diff --git a/config/chips/L1xx_medium-density.chip b/config/chips/L1xx_medium-density.chip index 409b4dacc..f77c19cac 100644 --- a/config/chips/L1xx_medium-density.chip +++ b/config/chips/L1xx_medium-density.chip @@ -3,7 +3,7 @@ chip_id 0x416 description L1xx medium-density flash_type 5 -flash_pagesize 100 +flash_pagesize 0x100 sram_size 0x4000 bootrom_base 0x1ff00000 bootrom_size 0x1000 diff --git a/config/chips/L1xx_medium-plus-density.chip b/config/chips/L1xx_medium-plus-density.chip index 374f2e914..da557e3c8 100644 --- a/config/chips/L1xx_medium-plus-density.chip +++ b/config/chips/L1xx_medium-plus-density.chip @@ -3,7 +3,7 @@ chip_id 0x427 description L1xx medium-plus-density flash_type 5 -flash_pagesize 100 +flash_pagesize 0x100 sram_size 0x8000 bootrom_base 0x1ff00000 bootrom_size 0x1000 diff --git a/config/chips/L41x.chip b/config/chips/L41x.chip index cf51b4b02..5b491ccd4 100644 --- a/config/chips/L41x.chip +++ b/config/chips/L41x.chip @@ -3,7 +3,7 @@ chip_id 0x464 description L41x flash_type 6 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0xa000 bootrom_base 0x1fff0000 bootrom_size 0x7000 diff --git a/config/chips/L43x_L44x.chip b/config/chips/L43x_L44x.chip index 1953a6a99..383c42f3f 100644 --- a/config/chips/L43x_L44x.chip +++ b/config/chips/L43x_L44x.chip @@ -3,7 +3,7 @@ chip_id 0x435 description L43x/L44x flash_type 6 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0xc000 bootrom_base 0x1fff0000 bootrom_size 0x7000 diff --git a/config/chips/L45x_L46x.chip b/config/chips/L45x_L46x.chip index 79a90fcac..8b5f91ec3 100644 --- a/config/chips/L45x_L46x.chip +++ b/config/chips/L45x_L46x.chip @@ -3,7 +3,7 @@ chip_id 0x462 description L45x/L46x flash_type 6 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x20000 bootrom_base 0x1fff0000 bootrom_size 0x7000 diff --git a/config/chips/L496x_L4A6x.chip b/config/chips/L496x_L4A6x.chip index f94c0c582..57f539db3 100644 --- a/config/chips/L496x_L4A6x.chip +++ b/config/chips/L496x_L4A6x.chip @@ -3,7 +3,7 @@ chip_id 0x461 description L496x/L4A6x flash_type 6 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x40000 bootrom_base 0x1fff0000 bootrom_size 0x7000 diff --git a/config/chips/L4Rx.chip b/config/chips/L4Rx.chip index 355f22470..11780ce27 100644 --- a/config/chips/L4Rx.chip +++ b/config/chips/L4Rx.chip @@ -3,7 +3,7 @@ chip_id 0x470 description L4Rx flash_type 6 -flash_pagesize 1000 +flash_pagesize 0x1000 sram_size 0xa0000 bootrom_base 0x1fff0000 bootrom_size 0x7000 diff --git a/config/chips/L4xx.chip b/config/chips/L4xx.chip index 3360a446e..c665c245f 100644 --- a/config/chips/L4xx.chip +++ b/config/chips/L4xx.chip @@ -3,7 +3,7 @@ chip_id 0x415 description L4xx flash_type 6 -flash_pagesize 800 +flash_pagesize 0x800 sram_size 0x18000 bootrom_base 0x1fff0000 bootrom_size 0x7000 diff --git a/config/chips/WB55.chip b/config/chips/WB55.chip index 9cf1d4380..585b576bc 100644 --- a/config/chips/WB55.chip +++ b/config/chips/WB55.chip @@ -3,7 +3,7 @@ chip_id 0x495 description WB55 flash_type 9 -flash_pagesize 1000 +flash_pagesize 0x1000 sram_size 0x40000 bootrom_base 0x1fff0000 bootrom_size 0x7000 diff --git a/config/chips/unknown_device.chip b/config/chips/unknown_device.chip index 2235d0072..c71206951 100644 --- a/config/chips/unknown_device.chip +++ b/config/chips/unknown_device.chip @@ -3,7 +3,7 @@ chip_id 0x0 description unknown device flash_type 0 -flash_pagesize 0 +flash_pagesize 0x0 sram_size 0x0 bootrom_base 0x0 bootrom_size 0x0 From fe48a98cb1802732edb117fe60cd9b2fa0689145 Mon Sep 17 00:00:00 2001 From: Sam Bazley Date: Sun, 1 Aug 2021 21:25:06 +0100 Subject: [PATCH 1231/1435] Add STM32WLEx support --- config/chips/WLE.chip | 13 +++++++++++++ src/stlink-lib/chipid.c | 12 ++++++++++++ src/stlink-lib/chipid.h | 3 ++- 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 config/chips/WLE.chip diff --git a/config/chips/WLE.chip b/config/chips/WLE.chip new file mode 100644 index 000000000..dbdf66d59 --- /dev/null +++ b/config/chips/WLE.chip @@ -0,0 +1,13 @@ +# Chip-ID file for WLE +# +chip_id 0x497 +description WLE +flash_type 9 +flash_pagesize 0x800 +sram_size 0x10000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x0 +option_size 0x0 +flags swo + diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 212328f86..28e4e91e9 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -847,6 +847,18 @@ static struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, .flags = CHIP_F_HAS_SWO_TRACING, }, + { + // STM32WLEx + .chip_id = STLINK_CHIPID_STM32_WLE, + .description = "WLEx", + .flash_type = STLINK_FLASH_TYPE_WB, + .flash_size_reg = 0x1FFF75E0, + .flash_pagesize = 0x800, // 2k + .sram_size = 0x10000, + .bootrom_base = 0x1fff0000, // see the memory map + .bootrom_size = 0x7000, + .flags = CHIP_F_HAS_SWO_TRACING, + }, { // STM32H742/743/753 (from RM0433) .chip_id = STLINK_CHIPID_STM32_H74xxx, diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index 75288093a..20cfcf52d 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -70,7 +70,8 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_G4_CAT4 = 0x479, STLINK_CHIPID_STM32_H7Ax = 0x480, /* RM0455, p.2863 */ STLINK_CHIPID_STM32_H72x = 0x483, /* RM0468, p.3199 */ - STLINK_CHIPID_STM32_WB55 = 0x495 + STLINK_CHIPID_STM32_WB55 = 0x495, + STLINK_CHIPID_STM32_WLE = 0x497 }; #define CHIP_F_HAS_DUAL_BANK (1 << 0) From 41d7ca710eace2b52b5e224a9f238be151477004 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Fri, 13 Aug 2021 20:02:26 +0300 Subject: [PATCH 1232/1435] fix compilation for MSVC --- CMakeLists.txt | 5 +++++ src/common.c | 2 +- src/stlink-lib/chipid.c | 45 ++++++++++++++++++++++++++++++++++++----- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 09e0a1bac..5c8aaa60c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,11 @@ if (STLINK_HAVE_UNISTD_H) add_definitions(-DSTLINK_HAVE_UNISTD_H) endif () +CHECK_INCLUDE_FILE(dirent.h STLINK_HAVE_DIRENT_H) +if (STLINK_HAVE_DIRENT_H) + add_definitions(-DSTLINK_HAVE_DIRENT_H) +endif () + if (MSVC) # Use string.h rather than strings.h and disable annoying warnings add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) diff --git a/src/common.c b/src/common.c index 1457d640c..af96b70b8 100644 --- a/src/common.c +++ b/src/common.c @@ -1541,7 +1541,7 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { if (ret || !(*chip_id)) { *chip_id = 0; - ret = ret?:-1; + ret = ret?ret:-1; ELOG("Could not find chip id!\n"); } else { *chip_id = (*chip_id) & 0xfff; diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 28e4e91e9..0ed774218 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1,7 +1,6 @@ #include #include "chipid.h" -#include #include #include #include @@ -962,7 +961,7 @@ struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { // fprintf (stderr, "getparams: %x\n", chipid); for (params = devicelist ; params != NULL ; params = params -> next) if (params->chip_id == chipid) break; - + p2 = stlink_chipid_get_params_old(chipid); #if 1 @@ -1061,7 +1060,7 @@ void dump_chips (void) struct stlink_chipid_params *ts; char *p, buf[100]; FILE *fp; - + for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) { ts = &devices[n]; @@ -1086,7 +1085,9 @@ void dump_chips (void) } } -void init_chipids(char *dir_to_scan) +#if defined(STLINK_HAVE_DIRENT_H) +#include +void init_chipids(char *dir_to_scan) { DIR *d; size_t nl; // namelen @@ -1121,11 +1122,45 @@ void init_chipids(char *dir_to_scan) dump_a_chip (stderr, op); fprintf (stderr, "---------- new ------------\n"); dump_a_chip (stderr, p); - + } } #endif } +#endif //STLINK_HAVE_DIRENT_H + +#if defined(_WIN32) && !defined(STLINK_HAVE_DIRENT_H) +#include +#include +void init_chipids(char *dir_to_scan) +{ + HANDLE hFind = INVALID_HANDLE_VALUE; + WIN32_FIND_DATAA ffd; + char file_pattern[MAX_PATH] = {0}; + char filepath[MAX_PATH] = {0}; + StringCchCopyA(file_pattern, STLINK_ARRAY_SIZE(file_pattern), dir_to_scan); + if (FAILED(StringCchCatA(file_pattern, STLINK_ARRAY_SIZE(file_pattern), "\\*.chip"))) { + ELOG("Path to chips's dir too long.\n"); + return; + }; + hFind = FindFirstFileA(file_pattern, &ffd); + if (INVALID_HANDLE_VALUE == hFind){ + ELOG("Can't find any chip description file in %s.\n", file_pattern); + return; + } + + do { + memset(filepath, 0, STLINK_ARRAY_SIZE(filepath)); + StringCchCopyA(filepath, STLINK_ARRAY_SIZE(filepath), dir_to_scan); + StringCchCatA(filepath, STLINK_ARRAY_SIZE(file_pattern), "\\"); + StringCchCatA(filepath, STLINK_ARRAY_SIZE(file_pattern), ffd.cFileName); + process_chipfile(filepath); + } while(FindNextFileA(hFind, &ffd) != 0); + + FindClose(hFind); +} +#endif //defined(_WIN32) && !defined(STLINK_HAVE_DIRENT_H) + From af384e96930f09e5032f79afca03155d86e9759a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 13 Aug 2021 21:23:00 +0200 Subject: [PATCH 1233/1435] Update src/stlink-lib/chipid.c Co-authored-by: Grzegorz Szymaszek --- src/stlink-lib/chipid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 0ed774218..bd5a7b9e2 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1155,7 +1155,7 @@ void init_chipids(char *dir_to_scan) StringCchCatA(filepath, STLINK_ARRAY_SIZE(file_pattern), "\\"); StringCchCatA(filepath, STLINK_ARRAY_SIZE(file_pattern), ffd.cFileName); process_chipfile(filepath); - } while(FindNextFileA(hFind, &ffd) != 0); + } while (FindNextFileA(hFind, &ffd) != 0); FindClose(hFind); } From 274be86616801d65cdc0e1f1bf380c98a7aa5b85 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Fri, 13 Aug 2021 22:40:24 +0300 Subject: [PATCH 1234/1435] Update src/stlink-lib/chipid.c Co-authored-by: Grzegorz Szymaszek --- src/stlink-lib/chipid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index bd5a7b9e2..d7e7f1328 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1144,7 +1144,7 @@ void init_chipids(char *dir_to_scan) return; }; hFind = FindFirstFileA(file_pattern, &ffd); - if (INVALID_HANDLE_VALUE == hFind){ + if (INVALID_HANDLE_VALUE == hFind) { ELOG("Can't find any chip description file in %s.\n", file_pattern); return; } From 9ec951c008b84f89debd69929a0aba6d1e4f4a22 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Fri, 13 Aug 2021 23:18:46 +0300 Subject: [PATCH 1235/1435] uncrustify chipid.c --- src/stlink-lib/chipid.c | 554 ++++++++++++++++++++-------------------- 1 file changed, 276 insertions(+), 278 deletions(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index d7e7f1328..dcf677909 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1,18 +1,18 @@ #include #include "chipid.h" -#include -#include +#include +#include #include #include #include -// This is the old chipid "database". +// This is the old chipid "database". // It is kept here for now to be able to compare the -// result between the "old code" and the "new code". -// For now if you need to change something, please -// change it both here and in the corresponding -// config/chips/*.chip file. +// result between the "old code" and the "new code". +// For now if you need to change something, please +// change it both here and in the corresponding +// config/chips/*.chip file. static struct stlink_chipid_params devices[] = { { @@ -26,10 +26,9 @@ static struct stlink_chipid_params devices[] = { .sram_size = 0x80000, // "SRAM" byte size in hex from .bootrom_base = 0x00200000, // "System memory" starting address from .bootrom_size = 0xEDC0, - .option_base = - STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option - // bytes, writing uses FLASH_F7_OPTCR - // and FLASH_F7_OPTCR1 + .option_base = STM32_F7_OPTION_BYTES_BASE, /* Used for reading back the option + bytes, writing uses FLASH_F7_OPTCR + and FLASH_F7_OPTCR1 */ .option_size = 0x20, .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, @@ -42,10 +41,8 @@ static struct stlink_chipid_params devices[] = { .flash_size_reg = 0x1ff0f442, // section 41.2 .flash_pagesize = 0x800, // No flash pages .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 - .bootrom_base = - 0x00100000, // "System memory" starting address from DS Fig 18 - .bootrom_size = - 0xEDC0, // "System memory" byte size in hex from DS Fig 18 + .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 + .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 18 .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -57,10 +54,8 @@ static struct stlink_chipid_params devices[] = { .flash_size_reg = 0x1ff07a22, // section 35.2 .flash_pagesize = 0x800, // No flash pages .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 - .bootrom_base = - 0x00100000, // "System memory" starting address from DS Fig 24 - .bootrom_size = - 0xEDC0, // "System memory" byte size in hex from DS Fig 24 + .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 + .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 24 .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -323,7 +318,7 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32F303xB/C, STM32F358, STM32F302xBxC + // STM32F303xB/C, STM32F358, STM32F302xBxC // RM0316, RM0365 .chip_id = STLINK_CHIPID_STM32_F3, .description = "F302/F303/F358", @@ -389,8 +384,7 @@ static struct stlink_chipid_params devices[] = { .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x800, // Page sizes listed in Table 4 .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = - 0x1fffC800, // "System memory" starting address from Table 2 + .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 .bootrom_size = 0x3000, // "System memory" byte size in hex from Table 2 .option_base = STM32_F0_OPTION_BYTES_BASE, .option_size = 16, @@ -404,8 +398,7 @@ static struct stlink_chipid_params devices[] = { .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = - 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 .option_base = STM32_F0_OPTION_BYTES_BASE, .option_size = 16, @@ -419,8 +412,7 @@ static struct stlink_chipid_params devices[] = { .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) .flash_pagesize = 0x4000, // Table 5. Flash module organization ? .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 - .bootrom_base = - 0x1FFF0000, // "System memory" starting address from Table 4 + .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 .flags = CHIP_F_HAS_SWO_TRACING, }, @@ -431,13 +423,11 @@ static struct stlink_chipid_params devices[] = { .description = "F413/F423", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 - .flash_pagesize = - 0x4000, // Table 5. Flash module organization (variable sector - // sizes, but 0x4000 is smallest) + .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector + // sizes, but 0x4000 is smallest) .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 // only says 0x40000) - .bootrom_base = - 0x1FFF0000, // "System memory" starting address from Table 4 + .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 .flags = CHIP_F_HAS_SWO_TRACING, }, @@ -450,8 +440,7 @@ static struct stlink_chipid_params devices[] = { .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) - .bootrom_base = - 0x1fffd800, // "System memory" starting address from Table 2 + .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 .bootrom_size = 0x2000, // "System memory" byte size in hex from Table 2 .option_base = STM32_F0_OPTION_BYTES_BASE, .option_size = 16, @@ -465,8 +454,7 @@ static struct stlink_chipid_params devices[] = { .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 - .bootrom_base = - 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 .option_base = STM32_F0_OPTION_BYTES_BASE, .option_size = 16, @@ -480,8 +468,7 @@ static struct stlink_chipid_params devices[] = { .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = - 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 .option_base = STM32_F0_OPTION_BYTES_BASE, .option_size = 16, @@ -580,17 +567,14 @@ static struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L4, .description = "L47x/L48x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = - 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) - .flash_pagesize = - 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 + .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 // and tables 4-6 on pages 79-81) // SRAM1 is "up to" 96k in the standard Cortex-M memory map; // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for // sizes; table 2, page 74 for SRAM2 location) .sram_size = 0x18000, - .bootrom_base = - 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, @@ -602,12 +586,10 @@ static struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L4Rx, .description = "L4Rx", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = - 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 - //TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size - .sram_size = - 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 + // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size + .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, @@ -618,12 +600,10 @@ static struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L4PX, .description = "L4Px", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = - 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 - //TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size - .sram_size = - 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 + // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size + .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, @@ -638,11 +618,10 @@ static struct stlink_chipid_params devices[] = { // sec 47.2, page 1586) .flash_pagesize = 0x800, // 2k (DS12469, sec 3.4, page 17) // SRAM1 is 32k at 0x20000000 - // SRAM2 is 8k at 0x10000000 and 0x20008000 - // (DS12469, sec 3.5, page 18) + // SRAM2 is 8k at 0x10000000 and 0x20008000 + // (DS12469, sec 3.5, page 18) .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) - .bootrom_base = - 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) + .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) .bootrom_size = 0x7000, // 28k, same source as base .flags = CHIP_F_HAS_SWO_TRACING, }, @@ -652,17 +631,14 @@ static struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L43x_L44x, .description = "L43x/L44x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = - 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) - .flash_pagesize = - 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 // and tables 7-8 on pages 75-76) // SRAM1 is "up to" 64k in the standard Cortex-M memory map; // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for // sizes; table 2, page 74 for SRAM2 location) .sram_size = 0xc000, - .bootrom_base = - 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, @@ -674,10 +650,8 @@ static struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L496x_L4A6x, .description = "L496x/L4A6x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = - 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) - .flash_pagesize = - 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) + .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) // SRAM1 is 256k at 0x20000000 // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) @@ -693,10 +667,8 @@ static struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L45x_L46x, .description = "L45x/46x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = - 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) - .flash_pagesize = - 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 // and tables 7 on pages 73-74) // SRAM1 is 128k at 0x20000000; // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, @@ -783,8 +755,7 @@ static struct stlink_chipid_params devices[] = { .description = "G43x/G44x", .flash_type = STLINK_FLASH_TYPE_G4, .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = - 0x800, // 2k (sec 3.3.1) + .flash_pagesize = 0x800, // 2k (sec 3.3.1) // SRAM1 is 16k at 0x20000000 // SRAM2 is 6k at 0x20014000 // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 @@ -802,8 +773,7 @@ static struct stlink_chipid_params devices[] = { .description = "G47x/G48x", .flash_type = STLINK_FLASH_TYPE_G4, .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = - 0x800, // 2k (sec 3.3.1) + .flash_pagesize = 0x800, // 2k (sec 3.3.1) // SRAM1 is 80k at 0x20000000 // SRAM2 is 16k at 0x20014000 // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 @@ -821,8 +791,7 @@ static struct stlink_chipid_params devices[] = { .description = "G49x/G4Ax", .flash_type = STLINK_FLASH_TYPE_G4, .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = - 0x800, // 2k (sec 3.3.1) + .flash_pagesize = 0x800, // 2k (sec 3.3.1) // SRAM1 is 80k at 0x20000000 // SRAM2 is 16k at 0x20014000 // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 @@ -866,10 +835,8 @@ static struct stlink_chipid_params devices[] = { .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) .flash_pagesize = 0x20000, // 128k sector (pg147) .sram_size = 0x20000, // 128k "DTCM" from Table 7 - .bootrom_base = - 0x1ff00000, // "System memory" starting address from Table 7 - .bootrom_size = - 0x20000, // "System memory" byte size in hex from Table 7 + .bootrom_base = 0x1ff00000, // "System memory" starting address from Table 7 + .bootrom_size = 0x20000, // "System memory" byte size in hex from Table 7 .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, @@ -883,8 +850,7 @@ static struct stlink_chipid_params devices[] = { .flash_size_reg = 0x08FFF80C, // "Flash size register" (p.2949) .flash_pagesize = 0x2000, // 8k sector (p.146) .sram_size = 0x20000, // 128k "DTCM" (Figure 1) - .bootrom_base = - 0x1FF00000, // "System memory" starting address (Table 12-14) + .bootrom_base = 0x1FF00000, // "System memory" starting address (Table 12-14) .bootrom_size = 0x20000, // "System memory" byte size in hex splitted to // two banks (Table 12-14) .option_base = STM32_H7_OPTION_BYTES_BASE, @@ -900,8 +866,7 @@ static struct stlink_chipid_params devices[] = { .flash_size_reg = 0x1FF1E880, // "Flash size register" (p.3286) .flash_pagesize = 0x20000, // 128k sector (p.152) .sram_size = 0x20000, // 128k "DTCM" (Figure 1) - .bootrom_base = - 0x1FF00000, // "System memory" starting address (Table 6) + .bootrom_base = 0x1FF00000, // "System memory" starting address (Table 6) .bootrom_size = 0x20000, // "System memory" byte size in hex (Table 6) .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, @@ -922,209 +887,239 @@ static struct stlink_chipid_params devices[] = { }; struct stlink_chipid_params *stlink_chipid_get_params_old(uint32_t chipid) { - struct stlink_chipid_params *params = NULL; + struct stlink_chipid_params *params = NULL; - for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) - if (devices[n].chip_id == chipid) { - params = &devices[n]; - break; - } + for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) + if (devices[n].chip_id == chipid) { + params = &devices[n]; + break; + } - return (params); + return (params); } static struct stlink_chipid_params *devicelist; - -void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) -{ - fprintf(fp, "# Chip-ID file for %s\n", dev->description); - fprintf(fp, "#\n"); - fprintf(fp, "chip_id 0x%x\n", dev->chip_id); - fprintf(fp, "description %s\n", dev->description); - fprintf(fp, "flash_type %d\n", dev->flash_type); - fprintf(fp, "flash_pagesize 0x%x\n", dev->flash_pagesize); - fprintf(fp, "sram_size 0x%x\n", dev->sram_size); - fprintf(fp, "bootrom_base 0x%x\n", dev->bootrom_base); - fprintf(fp, "bootrom_size 0x%x\n", dev->bootrom_size); - fprintf(fp, "option_base 0x%x\n", dev->option_base); - fprintf(fp, "option_size 0x%x\n", dev->option_size); - fprintf(fp, "flags %d\n\n", dev->flags); +void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { + fprintf(fp, "# Chip-ID file for %s\n", dev->description); + fprintf(fp, "#\n"); + fprintf(fp, "chip_id 0x%x\n", dev->chip_id); + fprintf(fp, "description %s\n", dev->description); + fprintf(fp, "flash_type %d\n", dev->flash_type); + fprintf(fp, "flash_pagesize 0x%x\n", dev->flash_pagesize); + fprintf(fp, "sram_size 0x%x\n", dev->sram_size); + fprintf(fp, "bootrom_base 0x%x\n", dev->bootrom_base); + fprintf(fp, "bootrom_size 0x%x\n", dev->bootrom_size); + fprintf(fp, "option_base 0x%x\n", dev->option_base); + fprintf(fp, "option_size 0x%x\n", dev->option_size); + fprintf(fp, "flags %d\n\n", dev->flags); } - - struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { - struct stlink_chipid_params *params = NULL; - struct stlink_chipid_params *p2; + struct stlink_chipid_params *params = NULL; + struct stlink_chipid_params *p2; - // fprintf (stderr, "getparams: %x\n", chipid); - for (params = devicelist ; params != NULL ; params = params -> next) - if (params->chip_id == chipid) break; + //fprintf (stderr, "getparams: %x\n", chipid); + for (params = devicelist; params != NULL; params = params->next) + if (params->chip_id == chipid) { + break; + } - p2 = stlink_chipid_get_params_old(chipid); + p2 = stlink_chipid_get_params_old(chipid); #if 1 - if (params == NULL) { - params = p2; - } else if (memcmp (p2, params, sizeof (struct stlink_chipid_params) - sizeof (struct stlink_chipid_params *)) != 0) { - //fprintf (stderr, "Error, chipid params not identical\n"); - //return NULL; - fprintf(stderr, "---------- old ------------\n"); - dump_a_chip(stderr, p2); - fprintf(stderr, "---------- new ------------\n"); - dump_a_chip(stderr, params); - } + if (params == NULL) { + params = p2; + } else if (memcmp (p2, params, sizeof(struct stlink_chipid_params) - sizeof(struct stlink_chipid_params *)) != 0) { + // fprintf (stderr, "Error, chipid params not identical\n"); + // return NULL; + fprintf(stderr, "---------- old ------------\n"); + dump_a_chip(stderr, p2); + fprintf(stderr, "---------- new ------------\n"); + dump_a_chip(stderr, params); + } #endif - return(params); + return(params); } +void process_chipfile(char *fname) { + FILE *fp; + char *p, *pp, buf[1025]; + char word[64], value[64]; + struct stlink_chipid_params *ts; + int nc; + + // fprintf (stderr, "processing chipfile %s.\n", fname); + fp = fopen(fname, "r"); -void process_chipfile(char *fname) -{ - FILE *fp; - char *p, *pp, buf[1025]; - char word[64], value[64]; - struct stlink_chipid_params *ts; - int nc; + if (!fp) { + perror(fname); + return; + } - //fprintf (stderr, "processing chipfile %s.\n", fname); - fp = fopen(fname, "r"); - if (!fp) { - perror(fname); - return; - } + ts = calloc(sizeof(struct stlink_chipid_params), 1); - ts = calloc(sizeof (struct stlink_chipid_params), 1); - while (fgets(buf, 1024, fp) != NULL) { - for (p=buf;isspace (*p);p++); - if (!*p) continue; // we hit end-of-line wiht only whitespace - if (*p == '#') continue; // ignore comments. + while (fgets(buf, 1024, fp) != NULL) { + for (p = buf; isspace (*p); p++); - sscanf(p, "%s %s", word, value); - if (strcmp(word, "chip_id") == 0) { - if (sscanf(value, "%i", &ts->chip_id) < 1) - fprintf(stderr, "Failed to parse chip id\n"); - } else if (strcmp (word, "description") == 0) { - //ts->description = strdup (value); - buf[strlen(p)-1] = 0; // chomp newline - sscanf(p, "%*s %n", &nc); - ts->description = strdup(p+nc); - } else if (strcmp (word, "flash_type") == 0) { - if (sscanf(value, "%i", (int *) &ts->flash_type) < 1) - fprintf(stderr, "Failed to parse flash type\n"); - else if (ts->flash_type <= STLINK_FLASH_TYPE_UNKNOWN || ts->flash_type >= STLINK_FLASH_TYPE_MAX) - fprintf(stderr, "Unrecognized flash type\n"); - } else if (strcmp (word, "flash_size_reg") == 0) { - if (sscanf(value, "%i", &ts->flash_size_reg) < 1) - fprintf(stderr, "Failed to parse flash size reg\n"); - } else if (strcmp (word, "flash_pagesize") == 0) { - if (sscanf(value, "%i", &ts->flash_pagesize) < 1) - fprintf(stderr, "Failed to parse flash page size\n"); - } else if (strcmp (word, "sram_size") == 0) { - if (sscanf(value, "%i", &ts->sram_size) < 1) - fprintf(stderr, "Failed to parse SRAM size\n"); - } else if (strcmp (word, "bootrom_base") == 0) { - if (sscanf(value, "%i", &ts->bootrom_base) < 1) - fprintf(stderr, "Failed to parse BootROM base\n"); - } else if (strcmp (word, "bootrom_size") == 0) { - if (sscanf(value, "%i", &ts->bootrom_size) < 1) - fprintf(stderr, "Failed to parse BootROM size\n"); - } else if (strcmp (word, "option_base") == 0) { - if (sscanf(value, "%i", &ts->option_base) < 1) - fprintf(stderr, "Failed to parse option base\n"); - } else if (strcmp (word, "option_size") == 0) { - if (sscanf(value, "%i", &ts->option_size) < 1) - fprintf(stderr, "Failed to parse option size\n"); - } else if (strcmp (word, "flags") == 0) { - pp = strtok (p, " \t\n"); - while ((pp = strtok (NULL, " \t\n")) ) { - if (strcmp (pp, "none") == 0) ts->flags = 0; // not necessary: calloc did this already. - else if (strcmp (pp, "dualbank") == 0) ts->flags |= CHIP_F_HAS_DUAL_BANK; - else if (strcmp (pp, "swo") == 0) ts->flags |= CHIP_F_HAS_SWO_TRACING; - else fprintf (stderr, "Unknown flags word in %s: '%s'\n", - fname, pp); - } - sscanf(value, "%x", &ts->flags); - } else { - fprintf (stderr, "Unknown keyword in %s: %s\n", - fname, word); + if (!*p) { + continue; // we hit end-of-line wiht only whitespace + } + + if (*p == '#') { + continue; // ignore comments. + } + + sscanf(p, "%s %s", word, value); + + if (strcmp(word, "chip_id") == 0) { + if (sscanf(value, "%i", &ts->chip_id) < 1) { + fprintf(stderr, "Failed to parse chip id\n"); + } + } else if (strcmp (word, "description") == 0) { + // ts->description = strdup (value); + buf[strlen(p) - 1] = 0; // chomp newline + sscanf(p, "%*s %n", &nc); + ts->description = strdup(p + nc); + } else if (strcmp (word, "flash_type") == 0) { + if (sscanf(value, "%i", (int *)&ts->flash_type) < 1) { + fprintf(stderr, "Failed to parse flash type\n"); + } else if (ts->flash_type <= STLINK_FLASH_TYPE_UNKNOWN || ts->flash_type >= STLINK_FLASH_TYPE_MAX) { + fprintf(stderr, "Unrecognized flash type\n"); + } + } else if (strcmp (word, "flash_size_reg") == 0) { + if (sscanf(value, "%i", &ts->flash_size_reg) < 1) { + fprintf(stderr, "Failed to parse flash size reg\n"); + } + } else if (strcmp (word, "flash_pagesize") == 0) { + if (sscanf(value, "%i", &ts->flash_pagesize) < 1) { + fprintf(stderr, "Failed to parse flash page size\n"); + } + } else if (strcmp (word, "sram_size") == 0) { + if (sscanf(value, "%i", &ts->sram_size) < 1) { + fprintf(stderr, "Failed to parse SRAM size\n"); + } + } else if (strcmp (word, "bootrom_base") == 0) { + if (sscanf(value, "%i", &ts->bootrom_base) < 1) { + fprintf(stderr, "Failed to parse BootROM base\n"); + } + } else if (strcmp (word, "bootrom_size") == 0) { + if (sscanf(value, "%i", &ts->bootrom_size) < 1) { + fprintf(stderr, "Failed to parse BootROM size\n"); + } + } else if (strcmp (word, "option_base") == 0) { + if (sscanf(value, "%i", &ts->option_base) < 1) { + fprintf(stderr, "Failed to parse option base\n"); + } + } else if (strcmp (word, "option_size") == 0) { + if (sscanf(value, "%i", &ts->option_size) < 1) { + fprintf(stderr, "Failed to parse option size\n"); + } + } else if (strcmp (word, "flags") == 0) { + pp = strtok (p, " \t\n"); + + while ((pp = strtok (NULL, " \t\n"))) { + if (strcmp (pp, "none") == 0) { + ts->flags = 0; // not necessary: calloc did this already. + } else if (strcmp (pp, "dualbank") == 0) { + ts->flags |= CHIP_F_HAS_DUAL_BANK; + } else if (strcmp (pp, "swo") == 0) { + ts->flags |= CHIP_F_HAS_SWO_TRACING; + } else { + fprintf (stderr, "Unknown flags word in %s: '%s'\n", + fname, pp); + } + } + + sscanf(value, "%x", &ts->flags); + } else { + fprintf (stderr, "Unknown keyword in %s: %s\n", + fname, word); + } } - } - ts->next = devicelist; - devicelist = ts; + + ts->next = devicelist; + devicelist = ts; } -void dump_chips (void) -{ - struct stlink_chipid_params *ts; - char *p, buf[100]; - FILE *fp; +void dump_chips (void) { + struct stlink_chipid_params *ts; + char *p, buf[100]; + FILE *fp; - for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) { - ts = &devices[n]; + for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) { + ts = &devices[n]; - strcpy(buf, ts->description); - while ((p = strchr(buf, '/'))) // change slashes to underscore. - *p = '_'; - strcat(buf, ".chip"); - fp = fopen(buf, "w"); - fprintf(fp, "# Chip-ID file for %s\n", ts->description); - fprintf(fp, "#\n"); - fprintf(fp, "chip_id %x\n", ts->chip_id); - fprintf(fp, "description %s\n", ts->description); - fprintf(fp, "flash_type %x\n", ts->flash_type); - fprintf(fp, "flash_pagesize %x\n", ts->flash_pagesize); - fprintf(fp, "sram_size %x\n", ts->sram_size); - fprintf(fp, "bootrom_base %x\n", ts->bootrom_base); - fprintf(fp, "bootrom_size %x\n", ts->bootrom_size); - fprintf(fp, "option_base %x\n", ts->option_base); - fprintf(fp, "option_size %x\n", ts->option_size); - fprintf(fp, "flags %x\n\n", ts->flags); - fclose(fp); - } + strcpy(buf, ts->description); + + while ((p = strchr(buf, '/'))) // change slashes to underscore. + *p = '_'; + + strcat(buf, ".chip"); + fp = fopen(buf, "w"); + fprintf(fp, "# Chip-ID file for %s\n", ts->description); + fprintf(fp, "#\n"); + fprintf(fp, "chip_id %x\n", ts->chip_id); + fprintf(fp, "description %s\n", ts->description); + fprintf(fp, "flash_type %x\n", ts->flash_type); + fprintf(fp, "flash_pagesize %x\n", ts->flash_pagesize); + fprintf(fp, "sram_size %x\n", ts->sram_size); + fprintf(fp, "bootrom_base %x\n", ts->bootrom_base); + fprintf(fp, "bootrom_size %x\n", ts->bootrom_size); + fprintf(fp, "option_base %x\n", ts->option_base); + fprintf(fp, "option_size %x\n", ts->option_size); + fprintf(fp, "flags %x\n\n", ts->flags); + fclose(fp); + } } #if defined(STLINK_HAVE_DIRENT_H) #include -void init_chipids(char *dir_to_scan) -{ - DIR *d; - size_t nl; // namelen - struct dirent *dir; - if (!dir_to_scan) dir_to_scan = "./"; +void init_chipids(char *dir_to_scan) { + DIR *d; + size_t nl; // namelen + struct dirent *dir; + + if (!dir_to_scan) { + dir_to_scan = "./"; + } - devicelist = NULL; - //dump_chips (); - d = opendir(dir_to_scan); - if (d) { - while ((dir = readdir(d)) != NULL) { - nl = strlen(dir->d_name); - if (strcmp(dir->d_name + nl - 5, ".chip") == 0) { - char buf[1024]; - sprintf(buf, "%s/%s", dir_to_scan, dir->d_name); - process_chipfile(buf); - } + devicelist = NULL; + // dump_chips (); + d = opendir(dir_to_scan); + + if (d) { + while ((dir = readdir(d)) != NULL) { + nl = strlen(dir->d_name); + + if (strcmp(dir->d_name + nl - 5, ".chip") == 0) { + char buf[1024]; + sprintf(buf, "%s/%s", dir_to_scan, dir->d_name); + process_chipfile(buf); + } + } + + closedir(d); + } else { + perror (dir_to_scan); + return; // XXX } - closedir(d); - } else { - perror (dir_to_scan); - return; // XXX - } + #if 0 - { - struct stlink_chipid_params *p, *op; - int i; - p = devicelist; - for (i=0;i<5;i++, p = p->next) { - op = stlink_chipid_get_params_old (p->chip_id); - fprintf (stderr, "---------- old ------------\n"); - dump_a_chip (stderr, op); - fprintf (stderr, "---------- new ------------\n"); - dump_a_chip (stderr, p); + { + struct stlink_chipid_params *p, *op; + int i; + p = devicelist; + for (i = 0; i < 5; i++, p = p->next) { + op = stlink_chipid_get_params_old (p->chip_id); + fprintf (stderr, "---------- old ------------\n"); + dump_a_chip (stderr, op); + fprintf (stderr, "---------- new ------------\n"); + dump_a_chip (stderr, p); + + } } - } #endif } #endif //STLINK_HAVE_DIRENT_H @@ -1132,32 +1127,35 @@ void init_chipids(char *dir_to_scan) #if defined(_WIN32) && !defined(STLINK_HAVE_DIRENT_H) #include #include -void init_chipids(char *dir_to_scan) -{ - HANDLE hFind = INVALID_HANDLE_VALUE; - WIN32_FIND_DATAA ffd; - char file_pattern[MAX_PATH] = {0}; - char filepath[MAX_PATH] = {0}; - StringCchCopyA(file_pattern, STLINK_ARRAY_SIZE(file_pattern), dir_to_scan); - if (FAILED(StringCchCatA(file_pattern, STLINK_ARRAY_SIZE(file_pattern), "\\*.chip"))) { - ELOG("Path to chips's dir too long.\n"); - return; - }; - hFind = FindFirstFileA(file_pattern, &ffd); - if (INVALID_HANDLE_VALUE == hFind) { - ELOG("Can't find any chip description file in %s.\n", file_pattern); - return; - } +void init_chipids(char *dir_to_scan) { + HANDLE hFind = INVALID_HANDLE_VALUE; + WIN32_FIND_DATAA ffd; + char file_pattern[MAX_PATH] = {0}; + char filepath[MAX_PATH] = {0}; + StringCchCopyA(file_pattern, STLINK_ARRAY_SIZE(file_pattern), dir_to_scan); + + if (FAILED(StringCchCatA(file_pattern, STLINK_ARRAY_SIZE(file_pattern), "\\*.chip"))) { + ELOG("Path to chips's dir too long.\n"); + return; + } + + ; + hFind = FindFirstFileA(file_pattern, &ffd); + + if (INVALID_HANDLE_VALUE == hFind) { + ELOG("Can't find any chip description file in %s.\n", file_pattern); + return; + } - do { - memset(filepath, 0, STLINK_ARRAY_SIZE(filepath)); - StringCchCopyA(filepath, STLINK_ARRAY_SIZE(filepath), dir_to_scan); - StringCchCatA(filepath, STLINK_ARRAY_SIZE(file_pattern), "\\"); - StringCchCatA(filepath, STLINK_ARRAY_SIZE(file_pattern), ffd.cFileName); - process_chipfile(filepath); - } while (FindNextFileA(hFind, &ffd) != 0); + do { + memset(filepath, 0, STLINK_ARRAY_SIZE(filepath)); + StringCchCopyA(filepath, STLINK_ARRAY_SIZE(filepath), dir_to_scan); + StringCchCatA(filepath, STLINK_ARRAY_SIZE(file_pattern), "\\"); + StringCchCatA(filepath, STLINK_ARRAY_SIZE(file_pattern), ffd.cFileName); + process_chipfile(filepath); + } while (FindNextFileA(hFind, &ffd) != 0); - FindClose(hFind); + FindClose(hFind); } #endif //defined(_WIN32) && !defined(STLINK_HAVE_DIRENT_H) From e5152c45c3f9b27116be9d9d07250e6088d85c5a Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Fri, 13 Aug 2021 23:22:50 +0300 Subject: [PATCH 1236/1435] chipid.c: drop empty lines at end --- src/stlink-lib/chipid.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index dcf677909..42e4e92ae 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1158,7 +1158,3 @@ void init_chipids(char *dir_to_scan) { FindClose(hFind); } #endif //defined(_WIN32) && !defined(STLINK_HAVE_DIRENT_H) - - - - From 03153d083c46d33295e5bd905d08c35472a21048 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 14 Aug 2021 10:57:13 +0300 Subject: [PATCH 1237/1435] removed redundant array --- src/stlink-lib/chipid.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 42e4e92ae..d51a0edcb 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1130,28 +1130,26 @@ void init_chipids(char *dir_to_scan) { void init_chipids(char *dir_to_scan) { HANDLE hFind = INVALID_HANDLE_VALUE; WIN32_FIND_DATAA ffd; - char file_pattern[MAX_PATH] = {0}; char filepath[MAX_PATH] = {0}; - StringCchCopyA(file_pattern, STLINK_ARRAY_SIZE(file_pattern), dir_to_scan); + StringCchCopyA(filepath, STLINK_ARRAY_SIZE(filepath), dir_to_scan); - if (FAILED(StringCchCatA(file_pattern, STLINK_ARRAY_SIZE(file_pattern), "\\*.chip"))) { + if (FAILED(StringCchCatA(filepath, STLINK_ARRAY_SIZE(filepath), "\\*.chip"))) { ELOG("Path to chips's dir too long.\n"); return; } - ; - hFind = FindFirstFileA(file_pattern, &ffd); + hFind = FindFirstFileA(filepath, &ffd); if (INVALID_HANDLE_VALUE == hFind) { - ELOG("Can't find any chip description file in %s.\n", file_pattern); + ELOG("Can't find any chip description file in %s.\n", filepath); return; } do { memset(filepath, 0, STLINK_ARRAY_SIZE(filepath)); StringCchCopyA(filepath, STLINK_ARRAY_SIZE(filepath), dir_to_scan); - StringCchCatA(filepath, STLINK_ARRAY_SIZE(file_pattern), "\\"); - StringCchCatA(filepath, STLINK_ARRAY_SIZE(file_pattern), ffd.cFileName); + StringCchCatA(filepath, STLINK_ARRAY_SIZE(filepath), "\\"); + StringCchCatA(filepath, STLINK_ARRAY_SIZE(filepath), ffd.cFileName); process_chipfile(filepath); } while (FindNextFileA(hFind, &ffd) != 0); From bef3321ea45e939003ef7802bdd2d3368f57b676 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sun, 15 Aug 2021 12:18:46 +0300 Subject: [PATCH 1238/1435] Fixes few warnings for msvc about type conversion with possible lost data. --- src/common.c | 28 ++++++++++++++-------------- src/st-flash/flash.c | 10 +++++----- src/st-util/gdb-server.c | 22 +++++++++++----------- src/stlink-lib/flash_loader.c | 14 +++++++------- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/common.c b/src/common.c index af96b70b8..601fac0b6 100644 --- a/src/common.c +++ b/src/common.c @@ -424,8 +424,8 @@ void write_uint32(unsigned char *buf, uint32_t ui) { } void write_uint16(unsigned char *buf, uint16_t ui) { - buf[0] = ui; - buf[1] = ui >> 8; + buf[0] = (uint8_t)ui; + buf[1] = (uint8_t)(ui >> 8); } uint32_t read_uint32(const unsigned char *c, const int pt) { @@ -1274,7 +1274,7 @@ static void stop_wdg_in_debug(stlink_t *sl) { case STLINK_FLASH_TYPE_F1_XL: case STLINK_FLASH_TYPE_G4: dbgmcu_cr = STM32F0_DBGMCU_CR; - set = (1 << STM32F0_DBGMCU_CR_IWDG_STOP) | + set = (1 << STM32F0_DBGMCU_CR_IWDG_STOP) | (1 << STM32F0_DBGMCU_CR_WWDG_STOP); break; case STLINK_FLASH_TYPE_F4: @@ -1442,7 +1442,7 @@ void stlink_close(stlink_t *sl) { int stlink_exit_debug_mode(stlink_t *sl) { DLOG("*** stlink_exit_debug_mode ***\n"); - if (sl->flash_type != STLINK_FLASH_TYPE_UNKNOWN && + if (sl->flash_type != STLINK_FLASH_TYPE_UNKNOWN && sl->core_stat != TARGET_RESET) { // stop debugging if the target has been identified stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); @@ -2253,7 +2253,7 @@ static int check_file(stlink_t *sl, mapped_file_t *mf, stm32_addr_t addr) { aligned_size = (cmp_size + 4) & ~(4 - 1); } - stlink_read_mem32(sl, addr + (uint32_t)off, aligned_size); + stlink_read_mem32(sl, addr + (uint32_t)off, (uint16_t)aligned_size); if (memcmp(sl->q_buf, mf->base + off, cmp_size)) { return (-1); @@ -2342,12 +2342,12 @@ int stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, size += 2; } // round size if needed - stlink_write_mem32(sl, addr + (uint32_t)off, size); + stlink_write_mem32(sl, addr + (uint32_t)off, (uint16_t)size); } if (length > len) { memcpy(sl->q_buf, data + len, length - len); - stlink_write_mem8(sl, addr + (uint32_t)len, length - len); + stlink_write_mem8(sl, addr + (uint32_t)len, (uint16_t)(length - len)); } error = 0; // success @@ -2409,12 +2409,12 @@ int stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { size += 2; } // round size if needed - stlink_write_mem32(sl, addr + (uint32_t)off, size); + stlink_write_mem32(sl, addr + (uint32_t)off, (uint16_t)size); } if (mf.len > len) { memcpy(sl->q_buf, mf.base + len, mf.len - len); - stlink_write_mem8(sl, addr + (uint32_t)len, mf.len - len); + stlink_write_mem8(sl, addr + (uint32_t)len, (uint16_t)(mf.len - len)); } // check the file has been written @@ -2462,7 +2462,7 @@ static int stlink_read(stlink_t *sl, stm32_addr_t addr, size_t size, aligned_size = (cmp_size + 4) & ~(4 - 1); } - stlink_read_mem32(sl, addr + (uint32_t)off, aligned_size); + stlink_read_mem32(sl, addr + (uint32_t)off, (uint16_t)aligned_size); if (!fn(fn_arg, sl->q_buf, aligned_size)) { goto on_error; @@ -2641,12 +2641,12 @@ int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, if (chunk) { memcpy(sl->q_buf, buf, chunk); - ret = stlink_write_mem32(sl, fl->buf_addr, chunk); + ret = stlink_write_mem32(sl, fl->buf_addr, (uint16_t)chunk); } if (rem && !ret) { memcpy(sl->q_buf, buf + chunk, rem); - ret = stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, rem); + ret = stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, (uint16_t)rem); } return (ret); @@ -3059,7 +3059,7 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, aligned_size = (cmp_size + 4) & ~(4 - 1); } - stlink_read_mem32(sl, address + (uint32_t)off, aligned_size); + stlink_read_mem32(sl, address + (uint32_t)off, (uint16_t)aligned_size); if (memcmp(sl->q_buf, data + off, cmp_size)) { ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); @@ -3105,7 +3105,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, for (off = 0; off < pagesize && !ret; off += 64) { size_t chunk = (pagesize - off > 64) ? 64 : pagesize - off; memcpy(sl->q_buf, base + count * pagesize + off, chunk); - ret = stlink_write_mem32(sl, addr + count * pagesize + off, chunk); + ret = stlink_write_mem32(sl, addr + count * pagesize + off, (uint16_t)chunk); } } diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 814c981b4..ef184239f 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -152,15 +152,15 @@ int main(int ac, char** av) { } } else if (o.area == FLASH_OPTCR) { DLOG("@@@@ Write %d (%0#10x) to option control register\n", o.val, o.val); - + err = stlink_write_option_control_register32(sl, o.val); } else if (o.area == FLASH_OPTCR1) { DLOG("@@@@ Write %d (%0#10x) to option control register 1\n", o.val, o.val); - + err = stlink_write_option_control_register1_32(sl, o.val); } else if (o.area == FLASH_OPTION_BYTES_BOOT_ADD) { DLOG("@@@@ Write %d (%0#10x) to option bytes boot address\n", o.val, o.val); - + err = stlink_write_option_bytes_boot_add32(sl, o.val); } else { err = -1; @@ -194,9 +194,9 @@ int main(int ac, char** av) { goto on_error; } } else if (o.area == FLASH_OPTION_BYTES) { - uint8_t remaining_option_length = sl->option_size / 4; + size_t remaining_option_length = sl->option_size / 4; DLOG("@@@@ Read %d (%#x) option bytes from %#10x\n", remaining_option_length, remaining_option_length, sl->option_base); - + if (NULL != o.filename) { if (0 == o.size) { o.size = sl->option_size; diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 653c7bcec..a651014c0 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -124,7 +124,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { " -n, --no-reset, --hot-plug\n" "\t\t\tDo not reset board on connection.\n" " -u, --connect-under-reset\n" - "\t\t\tConnect to the board before executing any instructions.\n" + "\t\t\tConnect to the board before executing any instructions.\n" " -F 1800k, --freq=1M\n" "\t\t\tSet the frequency of the SWD/JTAG interface.\n" " --semihosting\n" @@ -167,7 +167,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { st->listen_port = q; break; - + case 'm': st->persistent = true; break; @@ -586,7 +586,7 @@ char* make_memory_map(stlink_t *sl) { } else if (sl->chip_id == STLINK_CHIPID_STM32_H72x) { snprintf(map, sz, memory_map_template_H72x3x, (unsigned int)sl->flash_size, - (unsigned int)sl->flash_pgsz); + (unsigned int)sl->flash_pgsz); } else { snprintf(map, sz, memory_map_template, (unsigned int)sl->flash_size, @@ -726,7 +726,7 @@ static void init_code_breakpoints(stlink_t *sl) { // IHI0029D, p. 48, Lock Access Register stlink_write_debug32(sl, STLINK_REG_CM7_FP_LAR, STLINK_REG_CM7_FP_LAR_KEY); } - + for (int i = 0; i < code_break_num; i++) { code_breaks[i].type = 0; stlink_write_debug32(sl, STLINK_REG_CM3_FP_COMPn(i), 0); @@ -757,7 +757,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { type = CODE_BREAK_REMAP; fpb_addr = addr; } - + int id = -1; for (int i = 0; i < code_break_num; i++) if (fpb_addr == code_breaks[i].addr || (set && code_breaks[i].type == 0)) { @@ -778,7 +778,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { bp->type |= type; else bp->type &= ~type; - + // DDI0403E, p. 759, FP_COMPn register description mask = ((bp->type&0x03) << 30) | bp->addr | 1; @@ -936,7 +936,7 @@ struct cache_level_desc { struct cache_desc_t { unsigned used; - + // minimal line size in bytes unsigned int dminline; unsigned int iminline; @@ -988,7 +988,7 @@ static void init_cache (stlink_t *sl) { cache_desc.used = 1; cache_desc.dminline = 4 << ((ctr >> 16) & 0x0f); cache_desc.iminline = 4 << (ctr & 0x0f); - + stlink_read_debug32(sl, STLINK_REG_CM7_CLIDR, &clidr); cache_desc.louu = (clidr >> 27) & 7; @@ -1698,7 +1698,7 @@ int serve(stlink_t *sl, st_state_t *st) { for (unsigned int i = 0; i < align_count; i++) { char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 }; - uint8_t byte = strtoul(hextmp, NULL, 16); + uint8_t byte = (uint8_t)strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; } @@ -1714,7 +1714,7 @@ int serve(stlink_t *sl, st_state_t *st) { for (unsigned int i = 0; i < aligned_count; i++) { char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 }; - uint8_t byte = strtoul(hextmp, NULL, 16); + uint8_t byte = (uint8_t)strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; } @@ -1728,7 +1728,7 @@ int serve(stlink_t *sl, st_state_t *st) { if (count) { for (unsigned int i = 0; i < count; i++) { char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 }; - uint8_t byte = strtoul(hextmp, NULL, 16); + uint8_t byte = (uint8_t)strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; } diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index d2bf32563..f683c4d65 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -17,8 +17,8 @@ /* !!! * !!! DO NOT MODIFY FLASH LOADERS DIRECTLY! * !!! - * - * Edit assembly files in the '/flashloaders' instead. The sizes of binary + * + * Edit assembly files in the '/flashloaders' instead. The sizes of binary * flash loaders must be aligned by 4 (it's written by stlink_write_mem32) */ @@ -310,7 +310,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* } memcpy(sl->q_buf, loader_code, loader_size); - int ret = stlink_write_mem32(sl, sl->sram_base, loader_size); + int ret = stlink_write_mem32(sl, sl->sram_base, (uint16_t)loader_size); if (ret) { return(ret); } @@ -382,10 +382,10 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe // check written byte count stlink_read_reg(sl, 2, &rr); - /* The chunk size for loading is not rounded. The flash loader - * subtracts the size of the written block (1-8 bytes) from - * the remaining size each time. A negative value may mean that - * several bytes garbage has been written due to the unaligned + /* The chunk size for loading is not rounded. The flash loader + * subtracts the size of the written block (1-8 bytes) from + * the remaining size each time. A negative value may mean that + * several bytes garbage has been written due to the unaligned * firmware size. */ if ((int32_t)rr.r[2] > 0 || (int32_t)rr.r[2] < -7) { From 698b97bbddd4505c3fa4e0af366484e29b2739e4 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sun, 15 Aug 2021 12:30:09 +0300 Subject: [PATCH 1239/1435] fixes printf format formating --- src/st-flash/flash.c | 5 ++++- src/stlink-lib/flash_loader.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index ef184239f..51702b683 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -195,7 +195,10 @@ int main(int ac, char** av) { } } else if (o.area == FLASH_OPTION_BYTES) { size_t remaining_option_length = sl->option_size / 4; - DLOG("@@@@ Read %d (%#x) option bytes from %#10x\n", remaining_option_length, remaining_option_length, sl->option_base); + DLOG("@@@@ Read %u (%#x) option bytes from %#10x\n", + (unsigned)remaining_option_length, + (unsigned)remaining_option_length, + sl->option_base); if (NULL != o.filename) { if (0 == o.size) { diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index f683c4d65..7076a2cfa 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -280,7 +280,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* } else if (sl->core_id == STM32F7_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F76xxx || - sl->chip_id == STLINK_CHIPID_STM32_F72xxx) { + sl->chip_id == STLINK_CHIPID_STM32_F72xxx) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, From e768f737cd9f97097370cedbc3061aaf606bd700 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 15 Aug 2021 14:10:49 +0100 Subject: [PATCH 1240/1435] Bump Standards-Version to 4.5.1, no changes --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 3ac6af91f..e28f7c5b5 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: stlink Priority: optional Maintainer: Luca Boccassi Build-Depends: debhelper-compat (= 12), cmake (>= 3.4.2), libusb-1.0-0-dev, libgtk-3-dev -Standards-Version: 4.5.0 +Standards-Version: 4.5.1 Rules-Requires-Root: no Section: electronics Homepage: https://github.com/stlink-org/stlink From 1fab90289ffabcda7c3123ee7106cc032c2c619e Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 15 Aug 2021 14:11:09 +0100 Subject: [PATCH 1241/1435] Bump debhelper-compat to 13, no changes --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index e28f7c5b5..faed0302c 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,7 @@ Source: stlink Priority: optional Maintainer: Luca Boccassi -Build-Depends: debhelper-compat (= 12), cmake (>= 3.4.2), libusb-1.0-0-dev, libgtk-3-dev +Build-Depends: debhelper-compat (= 13), cmake (>= 3.4.2), libusb-1.0-0-dev, libgtk-3-dev Standards-Version: 4.5.1 Rules-Requires-Root: no Section: electronics From 607d1d3b854b0dc3fb84455f6efa21dffc578fe4 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 15 Aug 2021 15:14:45 +0200 Subject: [PATCH 1242/1435] General Project Update - Updated CHANGELOG.md - Updated list of contributors --- CHANGELOG.md | 18 +++++++++++++++++- contributors.txt | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b711f3890..9bbb41a98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,15 +12,31 @@ Features: - Support for writing option bytes on STM32F0/F1/F3 ([#346](https://github.com/stlink-org/stlink/pull/346), [#458](https://github.com/stlink-org/stlink/pull/458), [#808](https://github.com/stlink-org/stlink/pull/808), [#1084](https://github.com/stlink-org/stlink/pull/1084), [#1112](https://github.com/stlink-org/stlink/pull/1112)) - Added chip-IDs for STM32G0B0/G0B1/G0C1/G050/G051/G061 ([#1140](https://github.com/stlink-org/stlink/pull/1140)) - Added option byte info for STM32F411XX ([#1141](https://github.com/stlink-org/stlink/pull/1141)) +- Expanded and revised list of chips ([#1145](https://github.com/stlink-org/stlink/pull/1145), [#1164](https://github.com/stlink-org/stlink/pull/1164)) +- [STM32H72X/3X]: Added full access to all device memory ([#1158](https://github.com/stlink-org/stlink/pull/1158), [#1159](https://github.com/stlink-org/stlink/pull/1159)) +- Added support for STM32WLEx ([#1173](https://github.com/stlink-org/stlink/pull/1173)) Updates & changes: +- [refactoring] Moved chip-specific parameters into separate files ([#237](https://github.com/stlink-org/stlink/pull/237), [#1129](https://github.com/stlink-org/stlink/pull/1129)) - Added instructions for bug-reports and feature-requests to contribution guidelines ([#906](https://github.com/stlink-org/stlink/pull/906)) - Added travis CI configuration for macOS 10.14 to maintain capability for 32-bit compilation ([#f5ada94](https://github.com/stlink-org/stlink/commit/f5ada9474cdb87ff37de0d4eb9e75622b5870646)) - Updated description of chip id 0x0457 to L01x/L02x ([#1143](https://github.com/stlink-org/stlink/pull/1143), [#1144](https://github.com/stlink-org/stlink/pull/1144)) +- Drop execute bits from source code files ([#1167](https://github.com/stlink-org/stlink/pull/1167)) +- Use proper Markdown headers for supported MCUs ([#1168](https://github.com/stlink-org/stlink/pull/1168)) +- Removed redundant array ([#1178](https://github.com/stlink-org/stlink/pull/1178)) Fixes: - cmake: Install shared libraries in proper directories ([#1142](https://github.com/stlink-org/stlink/pull/1142)) +- Fixed clearance of the H7 dual bank flag ([#1146](https://github.com/stlink-org/stlink/pull/1146), [#1147](https://github.com/stlink-org/stlink/pull/1147)) +- Fix for 'libusb_devices were leaked' when no ST-LINK programmer was found ([#1150](https://github.com/stlink-org/stlink/pull/1150)) +- Set of fixes and improvements ([#1154](https://github.com/stlink-org/stlink/pull/1154)) +- Removed limit check for WRITEMEM_32BIT ([#1157](https://github.com/stlink-org/stlink/pull/1157)) +- Fixed get_stm32l0_flash_base address for STM32L152RE ([#1161](https://github.com/stlink-org/stlink/pull/1161), [#1162](https://github.com/stlink-org/stlink/pull/1162)) +- Fixed segfault if chip was not found in chip config files ([#1138](https://github.com/stlink-org/stlink/pull/1138), [#1163](https://github.com/stlink-org/stlink/pull/1163), [#1165](https://github.com/stlink-org/stlink/pull/1165), [#1166](https://github.com/stlink-org/stlink/pull/1166), [#1170](https://github.com/stlink-org/stlink/pull/1170)) +- Fixed parsing hex numbers in chip config files ([#1169](https://github.com/stlink-org/stlink/pull/1169)) +- Corrected flash_pagesize to use hex format ([#1172](https://github.com/stlink-org/stlink/pull/1172)) +- Fixed compilation for MSVC ([#1176](https://github.com/stlink-org/stlink/pull/1176)) # v1.7.0 @@ -65,6 +81,7 @@ Fixes: - Improvements and fixes of the flash loaders, unification of the reset function ([#244](https://github.com/stlink-org/stlink/pull/244), [#382](https://github.com/stlink-org/stlink/pull/382), [#705](https://github.com/stlink-org/stlink/pull/705), [#724](https://github.com/stlink-org/stlink/pull/724), [#980](https://github.com/stlink-org/stlink/pull/980), [#995](https://github.com/stlink-org/stlink/pull/995), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1115](https://github.com/stlink-org/stlink/pull/1115), [#1117](https://github.com/stlink-org/stlink/pull/1117), [#1122](https://github.com/stlink-org/stlink/pull/1122), [#1124](https://github.com/stlink-org/stlink/pull/1124)) - Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#724](https://github.com/stlink-org/stlink/pull/724), [#807](https://github.com/stlink-org/stlink/pull/807), [#817](https://github.com/stlink-org/stlink/pull/817), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) - Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106), [#1121](https://github.com/stlink-org/stlink/pull/1121)) +- Improvements for Chip_ID read ([#620](https://github.com/stlink-org/stlink/pull/620), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1120](https://github.com/stlink-org/stlink/pull/1120)) - Use vl flashloader for all STM32F1 series ([#724](https://github.com/stlink-org/stlink/pull/724), [#769](https://github.com/stlink-org/stlink/pull/769), [#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) - cmake compile failure with external `CMAKE_MODULE_PATH` set ([#962](https://github.com/stlink-org/stlink/pull/962)) @@ -89,7 +106,6 @@ Fixes: - [doc] Corrected spelling mistake in bug report template ([#1103](https://github.com/stlink-org/stlink/pull/1103)) - Fixed STM32WB55 reading DEBUG IDCODE from the wrong address ([#1100](https://github.com/stlink-org/stlink/pull/1100), [#1101](https://github.com/stlink-org/stlink/pull/1101)) - Applied missing changes to tests ([#1119](https://github.com/stlink-org/stlink/pull/1119)) -- Improvements for Chip_ID read ([#1008](https://github.com/stlink-org/stlink/pull/1008), [#1120](https://github.com/stlink-org/stlink/pull/1120)) - Fixed reading of chip ID on Cortex-M0+ core ([#1017](https://github.com/stlink-org/stlink/pull/1017), [#1125](https://github.com/stlink-org/stlink/pull/1125), [#1126](https://github.com/stlink-org/stlink/pull/1126), [#1133](https://github.com/stlink-org/stlink/pull/1133)) # v1.6.1 diff --git a/contributors.txt b/contributors.txt index e7fc0f601..bcaa0b538 100644 --- a/contributors.txt +++ b/contributors.txt @@ -46,6 +46,7 @@ Georg von Zengen Giuseppe Barba Greg Alexander [galexander1] Greg Meiste [meisteg] +Grzegorz Szymaszek [gszy] Guillaume Revaillot [grevaillot] Hakkavélin Halt Hammerzeit From 30396b2803697617e2087c4f4b2a66187b58902c Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 15 Aug 2021 14:31:09 +0100 Subject: [PATCH 1243/1435] Drop guipath.patch and refresh cross.patch for v1.7.0 --- debian/patches/cross.patch | 12 ++++++------ debian/patches/guipath.patch | 11 ----------- debian/patches/series | 1 - 3 files changed, 6 insertions(+), 18 deletions(-) delete mode 100644 debian/patches/guipath.patch diff --git a/debian/patches/cross.patch b/debian/patches/cross.patch index 8d927ba4b..d55e9f9d2 100644 --- a/debian/patches/cross.patch +++ b/debian/patches/cross.patch @@ -1,11 +1,11 @@ ---- stlink-1.6.1+ds.orig/CMakeLists.txt -+++ stlink-1.6.1+ds/CMakeLists.txt -@@ -48,7 +48,7 @@ - find_package(libusb REQUIRED) +--- a/src/stlink-gui/CMakeLists.txt ++++ b/src/stlink-gui/CMakeLists.txt +@@ -2,7 +2,7 @@ + # Build GUI + ### - ## Package configuration (pkg-config) on unix-based systems -if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) +if (NOT WIN32) - #add_subdirectory(cmake/pkgconfig) find_package(PkgConfig) pkg_check_modules(GTK3 gtk+-3.0) + diff --git a/debian/patches/guipath.patch b/debian/patches/guipath.patch deleted file mode 100644 index d3effc92b..000000000 --- a/debian/patches/guipath.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/src/stlink-gui/CMakeLists.txt -+++ b/src/stlink-gui/CMakeLists.txt -@@ -32,7 +32,7 @@ - add_executable(stlink-gui ${GUI_SOURCES}) - install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_BINDIR}) - set_target_properties(stlink-gui PROPERTIES -- COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_PREFIX}/bin") -+ COMPILE_DEFINITIONS STLINK_UI_DIR="/usr/share/stlink") - target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) - install(TARGETS stlink-gui DESTINATION ${CMAKE_INSTALL_BINDIR}) - diff --git a/debian/patches/series b/debian/patches/series index b3c28e7e1..def274a02 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,2 +1 @@ -guipath.patch cross.patch From 78b510ee3da0087033529956f5bc2d81359bc121 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 15 Aug 2021 14:38:00 +0100 Subject: [PATCH 1244/1435] Update install files, paths have been fixed upstream --- debian/stlink-gui.install | 6 +++--- debian/stlink-tools.manpages | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/debian/stlink-gui.install b/debian/stlink-gui.install index 5620a25e5..1474d7f8c 100644 --- a/debian/stlink-gui.install +++ b/debian/stlink-gui.install @@ -1,4 +1,4 @@ /usr/bin/stlink-gui -/usr/bin/stlink-gui.ui /usr/share/stlink/ -/usr/share/stlink/applications/stlink-gui.desktop /usr/share/applications/ -/usr/share/stlink/icons/hicolor/scalable/apps/stlink-gui.svg /usr/share/icons/hicolor/scalable/apps/stlink-gui.svg +/usr/share/applications/stlink-gui.desktop +/usr/share/icons/hicolor/scalable/apps/stlink-gui.svg +/usr/share/stlink/stlink-gui.ui diff --git a/debian/stlink-tools.manpages b/debian/stlink-tools.manpages index 049509abe..68112ddf2 100644 --- a/debian/stlink-tools.manpages +++ b/debian/stlink-tools.manpages @@ -1,3 +1,3 @@ -usr/share/stlink/man/man1/st-flash.1 -usr/share/stlink/man/man1/st-info.1 -usr/share/stlink/man/man1/st-util.1 +usr/share/man/man1/st-flash.1 +usr/share/man/man1/st-info.1 +usr/share/man/man1/st-util.1 From 9e3fac499e4a7c854f3cb691d29d10f7f8091eb5 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 15 Aug 2021 14:43:43 +0100 Subject: [PATCH 1245/1435] Update symbols file for 1.7.0 --- debian/libstlink1.symbols | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/debian/libstlink1.symbols b/debian/libstlink1.symbols index 159f27d0f..bc4e62f0e 100644 --- a/debian/libstlink1.symbols +++ b/debian/libstlink1.symbols @@ -29,6 +29,8 @@ libstlink.so.1 libstlink1 #MINVER# _stlink_usb_close@Base 1.5.0 _stlink_usb_core_id@Base 1.5.0 _stlink_usb_current_mode@Base 1.5.0 + _stlink_usb_disable_trace@Base 1.7.0 + _stlink_usb_enable_trace@Base 1.7.0 _stlink_usb_enter_swd_mode@Base 1.5.0 _stlink_usb_exit_debug_mode@Base 1.5.0 _stlink_usb_exit_dfu_mode@Base 1.5.0 @@ -40,6 +42,7 @@ libstlink.so.1 libstlink1 #MINVER# _stlink_usb_read_debug32@Base 1.5.0 _stlink_usb_read_mem32@Base 1.5.0 _stlink_usb_read_reg@Base 1.5.0 + _stlink_usb_read_trace@Base 1.7.0 _stlink_usb_read_unsupported_reg@Base 1.5.0 _stlink_usb_reset@Base 1.5.0 _stlink_usb_run@Base 1.5.0 @@ -54,10 +57,12 @@ libstlink.so.1 libstlink1 #MINVER# _stlink_usb_write_mem8@Base 1.5.0 _stlink_usb_write_reg@Base 1.5.0 _stlink_usb_write_unsupported_reg@Base 1.5.0 + arg_parse_freq@Base 1.7.0 calculate_F4_sectornum@Base 1.5.0 calculate_F7_sectornum@Base 1.5.0 + calculate_H7_sectornum@Base 1.7.0 calculate_L4_page@Base 1.5.0 - is_bigendian@Base 1.5.0 +#MISSING: 1.7.0# is_bigendian@Base 1.5.0 read_uint16@Base 1.5.0 read_uint32@Base 1.5.0 send_recv@Base 1.5.0 @@ -81,6 +86,9 @@ libstlink.so.1 libstlink1 #MINVER# stlink_flash_loader_init@Base 1.5.0 stlink_flash_loader_run@Base 1.5.0 stlink_flash_loader_write_to_sram@Base 1.5.0 + stlink_flashloader_start@Base 1.7.0 + stlink_flashloader_stop@Base 1.7.0 + stlink_flashloader_write@Base 1.7.0 stlink_force_debug@Base 1.5.0 stlink_fread@Base 1.5.0 stlink_fwrite_flash@Base 1.5.0 @@ -105,20 +113,36 @@ libstlink.so.1 libstlink1 #MINVER# stlink_read_mem32@Base 1.5.0 stlink_read_option_bytes32@Base 1.6.1 stlink_read_option_bytes_Gx@Base 1.6.1 + stlink_read_option_bytes_boot_add32@Base 1.7.0 + stlink_read_option_bytes_boot_add_f7@Base 1.7.0 stlink_read_option_bytes_f2@Base 1.6.0 stlink_read_option_bytes_f4@Base 1.6.0 + stlink_read_option_bytes_f7@Base 1.7.0 stlink_read_option_bytes_generic@Base 1.6.1 + stlink_read_option_control_register1_32@Base 1.7.0 + stlink_read_option_control_register1_f7@Base 1.7.0 + stlink_read_option_control_register32@Base 1.7.0 + stlink_read_option_control_register_Gx@Base 1.7.0 + stlink_read_option_control_register_f2@Base 1.7.0 + stlink_read_option_control_register_f4@Base 1.7.0 + stlink_read_option_control_register_f7@Base 1.7.0 stlink_read_reg@Base 1.5.0 stlink_read_unsupported_reg@Base 1.5.0 stlink_reset@Base 1.5.0 stlink_run@Base 1.5.0 stlink_run_at@Base 1.5.0 + stlink_serial@Base 1.7.0 stlink_set_hw_bp@Base 1.5.0 stlink_set_swdclk@Base 1.5.0 + stlink_soft_reset@Base 1.7.0 stlink_stat@Base 1.5.0 stlink_status@Base 1.5.0 stlink_step@Base 1.5.0 + stlink_target_connect@Base 1.7.0 stlink_target_voltage@Base 1.5.0 + stlink_trace_disable@Base 1.7.0 + stlink_trace_enable@Base 1.7.0 + stlink_trace_read@Base 1.7.0 stlink_v1_open@Base 1.5.0 stlink_v1_open_inner@Base 1.5.0 stlink_verify_write_flash@Base 1.5.0 @@ -130,9 +154,13 @@ libstlink.so.1 libstlink1 #MINVER# stlink_write_mem8@Base 1.5.0 stlink_write_option_bytes32@Base 1.6.1 stlink_write_option_bytes@Base 1.6.0 + stlink_write_option_bytes_boot_add32@Base 1.7.0 + stlink_write_option_control_register1_32@Base 1.7.0 + stlink_write_option_control_register32@Base 1.7.0 stlink_write_reg@Base 1.5.0 stlink_write_unsupported_reg@Base 1.5.0 stm32l1_write_half_pages@Base 1.5.0 + time_ms@Base 1.7.0 ugly_init@Base 1.5.0 ugly_libusb_log_level@Base 1.6.1 ugly_log@Base 1.5.0 From 4f40a424567e7f114753ac3ef56ba7e8b4d644a0 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 15 Aug 2021 14:24:44 +0100 Subject: [PATCH 1246/1435] Update changelog for 1.7.0+ds-1 --- debian/changelog | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/debian/changelog b/debian/changelog index ac046a5f4..7a7b4e54a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +stlink (1.7.0+ds-1) unstable; urgency=medium + + * Merge tag 'v1.7.0' into debian. (Closes: #984356) + * Bump Standards-Version to 4.5.1, no changes. + * Bump debhelper-compat to 13, no changes. + * Update install files, paths have been fixed upstream. + * Update symbols file for 1.7.0. + + -- Luca Boccassi Sun, 15 Aug 2021 14:23:25 +0100 + stlink (1.6.1+ds-3) unstable; urgency=medium * Add cross.patch to fix cross-compilation. Thanks Helmut! (Closes: From e662da00ca294c874655c65cffae3edde97343e5 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 22 Aug 2021 12:44:01 +0200 Subject: [PATCH 1247/1435] Updated debian pkg config for distribution --- debian/.gitignore | 4 +- debian/control | 36 +++-- debian/copyright | 128 +----------------- debian/patches/cross.patch | 11 -- debian/patches/series | 1 - ...ink-dev.install => stlink-lib-dev.install} | 0 ...{libstlink1.install => stlink-lib.install} | 0 ...{libstlink1.symbols => stlink-lib.symbols} | 2 +- debian/stlink.pc.in | 2 +- src/stlink-gui/CMakeLists.txt | 2 +- 10 files changed, 28 insertions(+), 158 deletions(-) delete mode 100644 debian/patches/cross.patch delete mode 100644 debian/patches/series rename debian/{libstlink-dev.install => stlink-lib-dev.install} (100%) rename debian/{libstlink1.install => stlink-lib.install} (100%) rename debian/{libstlink1.symbols => stlink-lib.symbols} (99%) diff --git a/debian/.gitignore b/debian/.gitignore index 7624d1c9b..6531851ff 100644 --- a/debian/.gitignore +++ b/debian/.gitignore @@ -1,8 +1,8 @@ .debhelper -files -debhelper-build-stamp *.log *.substvars +debhelper-build-stamp +files libstlink-dev libstlink stlink-gui diff --git a/debian/control b/debian/control index faed0302c..c3e654ec5 100644 --- a/debian/control +++ b/debian/control @@ -9,44 +9,40 @@ Homepage: https://github.com/stlink-org/stlink Vcs-Git: https://github.com/bluca/stlink.git -b debian Vcs-Browser: https://github.com/bluca/stlink -Package: libstlink-dev +Package: stlink-lib-dev Section: libdevel Architecture: linux-any Multi-Arch: same -Depends: libstlink1 (= ${binary:Version}), ${misc:Depends} -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. +Depends: stlink-lib (= ${binary:Version}), ${misc:Depends} +Replaces: libstlink-dev (<< 1.7.0+ds-1) +Breaks: libstlink-dev (<< 1.7.0+ds-1) +Description: Open source version of the STMicroelectronics STLINK Tools . - This package contains the development files for stlink. + This package contains development files for stlink. -Package: libstlink1 +Package: stlink-lib Section: libs Architecture: linux-any Multi-Arch: same Depends: ${shlibs:Depends}, ${misc:Depends} -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. +Replaces: libstlink1 (<< 1.7.0+ds-1) +Breaks: libstlink1 (<< 1.7.0+ds-1) +Description: Open source version of the STMicroelectronics STLINK Tools . This package contains the shared library for stlink. Package: stlink-tools Architecture: linux-any -Depends: libstlink1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. +Depends: stlink-lib (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} +Description: Open source version of the STMicroelectronics STLINK Tools . - This package contains commandline utilities for stlink, and modprobe and - udev rules. + This package contains commandline utilities for stlink, as well as modprobe + and udev rules. Package: stlink-gui Architecture: linux-any -Depends: libstlink1 (= ${binary:Version}), stlink-tools (= ${binary:Version}), +Depends: stlink-lib (= ${binary:Version}), stlink-tools (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} -Description: OpenSource ST-Link tools replacement. - Flashing tools for STMicroelectronics STM32VL and STM32L. The transport layers - STLINKv1 and STLINKv2 are supported. +Description: Open source version of the STMicroelectronics STLINK Tools . This package contains a GUI tool for stlink. diff --git a/debian/copyright b/debian/copyright index 1a0febd9c..b7f9c3106 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,132 +1,18 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: stlink -Upstream-Contact: Andrew 'Necromant' Andrianov +Upstream-Contact: Nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Source: https://github.com/stlink-org/stlink Comment: Upstream tarball has been repackaged to remove binary OSX kernel drivers that are of unknown license and of no use to Debian. Files-Excluded: stlinkv1_macos_driver Files: * -Copyright: 2011-2018 agpanarin - 2011-2018 Alexey Cherevatenko - 2011-2018 Anatoli - 2011-2018 Andrea Mucignat - 2011-2018 Andrew 'Necromant' Andrianov - 2011-2018 Andrey Yurovsky - 2011-2018 Andy Isaacson - 2011-2018 Áron RADICS - 2011-2018 A Sheaff - 2011-2018 Björn Hauffe - 2011-2018 bob - 2011-2018 Breton M. Saunders - 2011-2018 Bruno Dal Bo - 2011-2018 Burns - 2011-2018 Chris Dew - 2011-2018 Chris Hiszpanski - 2011-2018 Chris Li - 2011-2018 Chris Samuelson - 2011-2018 Christophe Levantis - 2011-2018 Craig Lilley - 2011-2018 dandev37 - 2011-2018 Dan Hepler - 2011-2018 Daniel Campoverde [alx741] - 2011-2018 Daniel O'Connor - 2011-2018 Dave Flogeras - 2011-2018 Dave Murphy - 2011-2018 Dave Vandervies - 2011-2018 Denis Fokin - 2011-2018 Denis Osterland - 2011-2018 Dmitry Bravikov - 2011-2018 Efe Can İçöz - 2011-2018 Ethan Zonca - 2011-2018 Fabien Chouteau - 2011-2018 Fabien Le Mentec - 2011-2018 fhars - 2011-2018 Friedrich Beckmann - 2011-2018 Geoffrey Brown - 2011-2018 George Talusan - 2011-2018 Georg von Zengen - 2011-2018 giuseppe barba - 2011-2018 Greg Alexander - 2011-2018 Greg Meiste - 2011-2018 Hakkavélin - 2011-2018 htk - 2011-2018 Ian Griffiths <6thimage@gmail.com> - 2011-2018 Jack Peel - 2011-2018 Jakub Tyszkowski - 2011-2018 Jan Sarenik - 2011-2018 Jean-Luc Béchennec - 2011-2018 Jean-Marie Lemetayer - 2011-2018 Jeff Kent - 2011-2018 Jeffrey Nelson - 2011-2018 Jens Hoffmann - 2011-2018 Jerome Lambourg - 2011-2018 Jerry Jacobs - 2011-2018 Jim Paris - 2011-2018 Jiří Netolický - 2011-2018 jnosky - 2011-2018 jnosky - 2011-2018 JohannesTaelman - 2011-2018 Jonas Danielsson - 2011-2018 Jonas Norling - 2011-2018 Josh Bialkowski - 2011-2018 Karl Palsson - 2011-2018 kevin - 2011-2018 Kyle Manna - 2011-2018 Lari Lehtomäki - 2011-2018 le mentec fabien - 2011-2018 Martin Nowak - 2011-2018 Matteo Collina - 2011-2018 Max Chen - 2011-2018 Maxime Coquelin - 2011-2018 Maxime Vincent - 2011-2018 Michael Pratt - 2011-2018 Michael Sparmann - 2011-2018 Mike Szczys - 2011-2018 mlundinse - 2011-2018 mux - 2011-2018 Ned Konz - 2011-2018 Nic McDonald - 2011-2018 Nicolas Schodet - 2011-2018 Nikolay - 2011-2018 nullsub - 2011-2018 Olivier Croquette - 2011-2018 Olivier Gay - 2011-2018 Onno Kortmann - 2011-2018 orangeudav - 2011-2018 Pavel Kirienko - 2011-2018 Pekka Nikander - 2011-2018 Pete - 2011-2018 Peter Zotov - 2011-2018 Petteri Aimonen - 2011-2018 Piotr Haber - 2011-2018 Rene Hopf - 2011-2018 Robin Kreis - 2011-2018 Rob Spanton - 2011-2018 Rytis Karpuska - 2011-2018 Sean Simmons - 2011-2018 Sergey Alirzaev - 2011-2018 Simon Wright - 2011-2018 Stany MARCEL - 2011-2018 Stefan Misik - 2011-2018 Sven Wegener - 2011-2018 Tectu - 2011-2018 tekaikko - 2011-2018 texane - 2011-2018 Theodore A. Roth - 2011-2018 Thomas Gärtner - 2011-2018 Tobias Badertscher - 2011-2018 Tom de Boer - 2011-2018 Tristan Gingold - 2011-2018 Uli Köhler - 2011-2018 Uwe Bonnes - 2011-2018 Vadim Kaushan - 2011-2018 Vegard Storheil Eriksen - 2011-2018 Viacheslav Dobromyslov - 2011-2018 Victor Mayoral Vilches - 2011-2018 Wojciech A. Koszek - 2011-2018 Woodrow Douglass - 2011-2018 The "Capt'ns Missing Link" Authors. +Copyright: 2011-2021 The stlink project maintainers + Martin Capitanio + Fabien Lementec + Jerry Jacobs + Nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> + and many other contributors... License: BSD-3-clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/debian/patches/cross.patch b/debian/patches/cross.patch deleted file mode 100644 index d55e9f9d2..000000000 --- a/debian/patches/cross.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/src/stlink-gui/CMakeLists.txt -+++ b/src/stlink-gui/CMakeLists.txt -@@ -2,7 +2,7 @@ - # Build GUI - ### - --if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) -+if (NOT WIN32) - find_package(PkgConfig) - pkg_check_modules(GTK3 gtk+-3.0) - diff --git a/debian/patches/series b/debian/patches/series deleted file mode 100644 index def274a02..000000000 --- a/debian/patches/series +++ /dev/null @@ -1 +0,0 @@ -cross.patch diff --git a/debian/libstlink-dev.install b/debian/stlink-lib-dev.install similarity index 100% rename from debian/libstlink-dev.install rename to debian/stlink-lib-dev.install diff --git a/debian/libstlink1.install b/debian/stlink-lib.install similarity index 100% rename from debian/libstlink1.install rename to debian/stlink-lib.install diff --git a/debian/libstlink1.symbols b/debian/stlink-lib.symbols similarity index 99% rename from debian/libstlink1.symbols rename to debian/stlink-lib.symbols index bc4e62f0e..9fb371d64 100644 --- a/debian/libstlink1.symbols +++ b/debian/stlink-lib.symbols @@ -1,4 +1,4 @@ -libstlink.so.1 libstlink1 #MINVER# +stlink-lib.so.1 stlink-lib #MINVER# Md5Calculate@Base 1.6.1 Md5Finalise@Base 1.6.1 Md5Initialise@Base 1.6.1 diff --git a/debian/stlink.pc.in b/debian/stlink.pc.in index 7fde2d968..b5f994bad 100644 --- a/debian/stlink.pc.in +++ b/debian/stlink.pc.in @@ -3,7 +3,7 @@ includedir=${prefix}/include/stlink libdir=${prefix}/lib/@DEB_HOST_MULTIARCH@ Name: stlink -Description: Open source version of the STMicroelectronics Stlink Tools +Description: Open source version of the STMicroelectronics STLINK Tools Version: @VERSION@ Requires: libusb-1.0 Libs: -L${libdir} -lstlink diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index 22a22f59d..80e3762c3 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -2,7 +2,7 @@ # Build GUI ### -if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) +if (NOT WIN32) find_package(PkgConfig) pkg_check_modules(GTK3 gtk+-3.0) From c8fc6561fead79ad49c09d82bab864745086792c Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 29 Aug 2021 15:08:54 +0200 Subject: [PATCH 1248/1435] Bugfixes - Corrected paths for chip-id files (Closes #1180) - Fixed 32-bit build (Closes #985) (Closes #1175) - Patch for GitHub Actions Workflow (Ubuntu) --- .github/workflows/c-cpp.yml | 106 ++------------------------ .github/workflows/codeql-analysis.yml | 2 +- CMakeLists.txt | 13 ++-- src/common.c | 4 +- 4 files changed, 18 insertions(+), 107 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index ee06d5469..442b3ba43 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: install dependencies - run: sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt update && sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug run: sudo make clean && make debug - name: make test @@ -35,7 +35,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: install dependencies - run: sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt update && sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm - name: Set compiler flags run: | CFLAGS="$CFLAGS -m32" @@ -60,7 +60,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: install dependencies - run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt update && sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug run: sudo make clean && make debug - name: make test @@ -80,7 +80,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt update && sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: Set compiler flags run: | CFLAGS="$CFLAGS -m32" @@ -105,7 +105,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt update && sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug run: sudo make clean && make debug - name: make test @@ -125,7 +125,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt update && sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: Set compiler flags run: | CFLAGS="$CFLAGS -m32" @@ -150,7 +150,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt update && sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug run: sudo make clean && make debug - name: make test @@ -170,7 +170,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt update && sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: Set compiler flags run: | CFLAGS="$CFLAGS -m32" @@ -191,96 +191,6 @@ jobs: # macOS - # job_macos_10_14_64_gcc: - # name: macos-10.14 gcc - # runs-on: macos-10.14 - # steps: - # - uses: actions/checkout@v2 - # - name: Install dependencies - # run: brew install gcc libusb gtk+3 - # - name: make debug - # run: sudo make clean && make debug - # - name: make test - # run: sudo make clean && make test - # - name: make release - # run: sudo make clean && make release - # - name: sudo make install - # run: sudo make clean && sudo make install - # - name: sudo make package - # run: sudo make package - # - name: sudo make uninstall - # run: sudo make uninstall && sudo make clean - - # job_macos_10_14_32_gcc: - # name: macos-10.14 gcc 32-bit - # runs-on: macos-10.14 - # steps: - # - uses: actions/checkout@v2 - # - name: Install dependencies - # run: brew install gcc libusb gtk+3 - # - name: Set compiler flags - # run: | - # CFLAGS="$CFLAGS -m32" - # CXXFLAGS="$CXXFLAGS -m32" - # LDFLAGS="$LDFLAGS -m32" - # - name: make debug - # run: sudo make clean && make debug - # - name: make test - # run: sudo make clean && make test - # - name: make release - # run: sudo make clean && make release - # - name: sudo make install - # run: sudo make clean && sudo make install - # - name: sudo make package - # run: sudo make package - # - name: sudo make uninstall - # run: sudo make uninstall && sudo make clean - - # job_macos_10_14_64_clang: - # name: macos-10.14 clang - # runs-on: macos-10.14 - # steps: - # - uses: actions/checkout@v2 - # - name: Install dependencies - # run: brew install llvm libusb gtk+3 - # - name: make debug - # run: sudo make clean && make debug - # - name: make test - # run: sudo make clean && make test - # - name: make release - # run: sudo make clean && make release - # - name: sudo make install - # run: sudo make clean && sudo make install - # - name: sudo make package - # run: sudo make package - # - name: sudo make uninstall - # run: sudo make uninstall && sudo make clean - - # job_macos_10_14_32_clang: - # name: macos-10.14 clang 32-bit - # runs-on: macos-10.14 - # steps: - # - uses: actions/checkout@v2 - # - name: Install dependencies - # run: brew install llvm libusb gtk+3 - # - name: Set compiler flags - # run: | - # CFLAGS="$CFLAGS -m32" - # CXXFLAGS="$CXXFLAGS -m32" - # LDFLAGS="$LDFLAGS -m32" - # - name: make debug - # run: sudo make clean && make debug - # - name: make test - # run: sudo make clean && make test - # - name: make release - # run: sudo make clean && make release - # - name: sudo make install - # run: sudo make clean && sudo make install - # - name: sudo make package - # run: sudo make package - # - name: sudo make uninstall - # run: sudo make uninstall && sudo make clean - job_macos_10_15_gcc: name: macos-10.15 gcc runs-on: macos-10.15 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 26313ecb5..55a21294f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -35,7 +35,7 @@ jobs: steps: - name: Install dependencies - run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt update && sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: Checkout repository uses: actions/checkout@v2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c8aaa60c..fd17d47cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,11 +9,6 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -set(CMAKE_STLINK_ETC_DIR etc) -set(CMAKE_ETC_CHIPS_DIR ${CMAKE_STLINK_ETC_DIR}/stlink/chips) -set(CMAKE_ETC_CHIPS_DIR_ABS ${CMAKE_INSTALL_PREFIX}/${CMAKE_ETC_CHIPS_DIR}) -add_definitions( -DETC_STLINK_DIR="${CMAKE_ETC_CHIPS_DIR_ABS}" ) - ### # General project settings @@ -23,6 +18,11 @@ project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics ST-LINK Tools") include(GNUInstallDirs) # Define GNU standard installation directories +## MCU configuration files +set(CMAKE_CHIPS_SUBDIR stlink/chips) +set(CMAKE_CHIPS_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_CHIPS_SUBDIR}) +add_definitions( -DETC_STLINK_DIR="${CMAKE_CHIPS_DIR}" ) + ## Determine project version include(${CMAKE_MODULE_PATH}/get_version.cmake) @@ -287,8 +287,9 @@ install(TARGETS st-info DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS st-util DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS st-trace DESTINATION ${CMAKE_INSTALL_BINDIR}) +# Install MCU configuration files file(GLOB CHIP_FILES ${CMAKE_SOURCE_DIR}/config/chips/*.chip) -install(FILES ${CHIP_FILES} DESTINATION ${CMAKE_ETC_CHIPS_DIR}) +install(FILES ${CHIP_FILES} DESTINATION ${CMAKE_CHIPS_DIR}) ### diff --git a/src/common.c b/src/common.c index 601fac0b6..c40f6aa79 100644 --- a/src/common.c +++ b/src/common.c @@ -2199,7 +2199,7 @@ static int map_file(mapped_file_t *mf, const char *path) { if (sizeof(st.st_size) != sizeof(size_t)) { // on 32 bit systems, check if there is an overflow - if (st.st_size > (off_t)INT32_MAX) { + if (st.st_size > (off_t)SSIZE_MAX) { fprintf(stderr, "mmap() size_t overflow for file %s\n", path); goto on_error; } @@ -2213,7 +2213,7 @@ static int map_file(mapped_file_t *mf, const char *path) { goto on_error; } - mf->len = st.st_size; + mf->len = (size_t)st.st_size; error = 0; // success on_error: From e51309f8428c4f1eea3ef1840c4fd5116c64279c Mon Sep 17 00:00:00 2001 From: Grzegorz Szymaszek Date: Sat, 21 Aug 2021 16:43:26 +0200 Subject: [PATCH 1249/1435] Update chip config files from the library structs In general, the chip config files should be kept in sync with the old library structs. Regenerate the files (using an ad hoc script) from the current library. The file name is generated from the chip description, all non-alphanumeric characters are replaced with underscores. It turns out some files have to have their names changed. --- config/chips/{F0xx_small.chip => F03x.chip} | 8 ++++---- config/chips/F04x.chip | 4 ++-- config/chips/{F0xx.chip => F05x.chip} | 8 ++++---- config/chips/F07x.chip | 4 ++-- config/chips/F09x.chip | 4 ++-- ..._low-density.chip => F1_Low_density_device.chip} | 8 ++++---- config/chips/F1_value_line_high-density.chip | 13 ------------- .../{F1_connectivity_line.chip => F1xx_CL.chip} | 8 ++++---- ...{F1_high-density.chip => F1xx_High_density.chip} | 8 ++++---- config/chips/F1xx_High_density_value_line.chip | 13 +++++++++++++ ...medium-density.chip => F1xx_Medium_density.chip} | 8 ++++---- .../{F1_value_line.chip => F1xx_Value_Line.chip} | 8 ++++---- .../{F1_XL-density.chip => F1xx_XL_density.chip} | 4 ++-- config/chips/{F2.chip => F2xx.chip} | 4 ++-- .../chips/{F3xx_small.chip => F301_F302_F318.chip} | 8 ++++---- config/chips/F302_F303_F358.chip | 13 +++++++++++++ ...F334_medium_density.chip => F303_F328_F334.chip} | 8 ++++---- config/chips/F303_high_density.chip | 4 ++-- config/chips/F37x.chip | 4 ++-- config/chips/{F4xx_low_power.chip => F401xB_C.chip} | 4 ++-- .../{F4xx_dynamic_efficiency.chip => F401xD_E.chip} | 4 ++-- config/chips/{F411xx.chip => F411xC_E.chip} | 4 ++-- config/chips/{F413.chip => F413_F423.chip} | 4 ++-- config/chips/{F4xx.chip => F4x5_F4x7.chip} | 4 ++-- config/chips/{F7xx.chip => F74x_F75x.chip} | 4 ++-- config/chips/{F76xxx.chip => F76x_F77x.chip} | 6 +++--- .../chips/{G030_G031_G041.chip => G03x_G04x.chip} | 4 ++-- config/chips/G05x_G06x.chip | 13 +++++++++++++ .../chips/{G070_G071_G081.chip => G07x_G08x.chip} | 4 ++-- config/chips/G0Bx_G0Cx.chip | 13 +++++++++++++ config/chips/{G4_cat2.chip => G43x_G44x.chip} | 4 ++-- config/chips/{G4_cat3.chip => G47x_G48x.chip} | 6 +++--- config/chips/G49x_G4Ax.chip | 13 +++++++++++++ config/chips/{L011.chip => L01x_L02x.chip} | 4 ++-- config/chips/{L0xx_cat2.chip => L0xx_Cat_2.chip} | 4 ++-- config/chips/{L0x3.chip => L0xx_Cat_3.chip} | 4 ++-- config/chips/{L0xx_cat5.chip => L0xx_Cat_5.chip} | 6 +++--- .../{L1xx_medium-density.chip => L1xx_Cat_1.chip} | 4 ++-- config/chips/{L1xx_cat2.chip => L1xx_Cat_2.chip} | 4 ++-- ...1xx_medium-plus-density.chip => L1xx_Cat_3.chip} | 4 ++-- .../{L1xx_high-density.chip => L1xx_Cat_4.chip} | 4 ++-- config/chips/{L152RE.chip => L1xx_Cat_5.chip} | 4 ++-- config/chips/{L41x.chip => L41x_L42x.chip} | 4 ++-- config/chips/{L45x_L46x.chip => L45x_46x.chip} | 4 ++-- config/chips/{L4xx.chip => L47x_L48x.chip} | 4 ++-- config/chips/L4Px.chip | 13 +++++++++++++ config/chips/L4Rx.chip | 2 +- config/chips/{WB55.chip => WB5x_3x.chip} | 4 ++-- config/chips/{WLE.chip => WLEx.chip} | 4 ++-- 49 files changed, 182 insertions(+), 117 deletions(-) rename config/chips/{F0xx_small.chip => F03x.chip} (58%) rename config/chips/{F0xx.chip => F05x.chip} (60%) rename config/chips/{F1_low-density.chip => F1_Low_density_device.chip} (51%) delete mode 100644 config/chips/F1_value_line_high-density.chip rename config/chips/{F1_connectivity_line.chip => F1xx_CL.chip} (53%) rename config/chips/{F1_high-density.chip => F1xx_High_density.chip} (53%) create mode 100644 config/chips/F1xx_High_density_value_line.chip rename config/chips/{F1_medium-density.chip => F1xx_Medium_density.chip} (52%) rename config/chips/{F1_value_line.chip => F1xx_Value_Line.chip} (54%) rename config/chips/{F1_XL-density.chip => F1xx_XL_density.chip} (71%) rename config/chips/{F2.chip => F2xx.chip} (80%) rename config/chips/{F3xx_small.chip => F301_F302_F318.chip} (54%) create mode 100644 config/chips/F302_F303_F358.chip rename config/chips/{F334_medium_density.chip => F303_F328_F334.chip} (54%) rename config/chips/{F4xx_low_power.chip => F401xB_C.chip} (71%) rename config/chips/{F4xx_dynamic_efficiency.chip => F401xD_E.chip} (66%) rename config/chips/{F411xx.chip => F411xC_E.chip} (76%) rename config/chips/{F413.chip => F413_F423.chip} (75%) rename config/chips/{F4xx.chip => F4x5_F4x7.chip} (76%) rename config/chips/{F7xx.chip => F74x_F75x.chip} (75%) rename config/chips/{F76xxx.chip => F76x_F77x.chip} (68%) rename config/chips/{G030_G031_G041.chip => G03x_G04x.chip} (72%) create mode 100644 config/chips/G05x_G06x.chip rename config/chips/{G070_G071_G081.chip => G07x_G08x.chip} (72%) create mode 100644 config/chips/G0Bx_G0Cx.chip rename config/chips/{G4_cat2.chip => G43x_G44x.chip} (75%) rename config/chips/{G4_cat3.chip => G47x_G48x.chip} (68%) create mode 100644 config/chips/G49x_G4Ax.chip rename config/chips/{L011.chip => L01x_L02x.chip} (75%) rename config/chips/{L0xx_cat2.chip => L0xx_Cat_2.chip} (75%) rename config/chips/{L0x3.chip => L0xx_Cat_3.chip} (75%) rename config/chips/{L0xx_cat5.chip => L0xx_Cat_5.chip} (68%) rename config/chips/{L1xx_medium-density.chip => L1xx_Cat_1.chip} (68%) rename config/chips/{L1xx_cat2.chip => L1xx_Cat_2.chip} (74%) rename config/chips/{L1xx_medium-plus-density.chip => L1xx_Cat_3.chip} (65%) rename config/chips/{L1xx_high-density.chip => L1xx_Cat_4.chip} (70%) rename config/chips/{L152RE.chip => L1xx_Cat_5.chip} (74%) rename config/chips/{L41x.chip => L41x_L42x.chip} (75%) rename config/chips/{L45x_L46x.chip => L45x_46x.chip} (75%) rename config/chips/{L4xx.chip => L47x_L48x.chip} (76%) create mode 100644 config/chips/L4Px.chip rename config/chips/{WB55.chip => WB5x_3x.chip} (76%) rename config/chips/{WLE.chip => WLEx.chip} (79%) diff --git a/config/chips/F0xx_small.chip b/config/chips/F03x.chip similarity index 58% rename from config/chips/F0xx_small.chip rename to config/chips/F03x.chip index 0a8ec265e..eed78e4e2 100644 --- a/config/chips/F0xx_small.chip +++ b/config/chips/F03x.chip @@ -1,13 +1,13 @@ -# Chip-ID file for F0xx small +# Chip-ID file for F03x # chip_id 0x444 -description F0xx small +description F03x flash_type 1 flash_pagesize 0x400 sram_size 0x1000 bootrom_base 0x1fffec00 bootrom_size 0xc00 -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 +option_size 0x10 flags none diff --git a/config/chips/F04x.chip b/config/chips/F04x.chip index 033c034e2..1f2a2043e 100644 --- a/config/chips/F04x.chip +++ b/config/chips/F04x.chip @@ -7,7 +7,7 @@ flash_pagesize 0x400 sram_size 0x1800 bootrom_base 0x1fffec00 bootrom_size 0xc00 -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 +option_size 0x10 flags none diff --git a/config/chips/F0xx.chip b/config/chips/F05x.chip similarity index 60% rename from config/chips/F0xx.chip rename to config/chips/F05x.chip index 309bbee34..787adb6bf 100644 --- a/config/chips/F0xx.chip +++ b/config/chips/F05x.chip @@ -1,13 +1,13 @@ -# Chip-ID file for F0xx +# Chip-ID file for F05x # chip_id 0x440 -description F0xx +description F05x flash_type 1 flash_pagesize 0x400 sram_size 0x2000 bootrom_base 0x1fffec00 bootrom_size 0xc00 -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 +option_size 0x10 flags none diff --git a/config/chips/F07x.chip b/config/chips/F07x.chip index dd697af40..e893a5457 100644 --- a/config/chips/F07x.chip +++ b/config/chips/F07x.chip @@ -7,7 +7,7 @@ flash_pagesize 0x800 sram_size 0x4000 bootrom_base 0x1fffc800 bootrom_size 0x3000 -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 +option_size 0x10 flags none diff --git a/config/chips/F09x.chip b/config/chips/F09x.chip index adb000030..267a2612f 100644 --- a/config/chips/F09x.chip +++ b/config/chips/F09x.chip @@ -7,7 +7,7 @@ flash_pagesize 0x800 sram_size 0x8000 bootrom_base 0x1fffd800 bootrom_size 0x2000 -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 +option_size 0x10 flags none diff --git a/config/chips/F1_low-density.chip b/config/chips/F1_Low_density_device.chip similarity index 51% rename from config/chips/F1_low-density.chip rename to config/chips/F1_Low_density_device.chip index 3995cad96..33fa03e1b 100644 --- a/config/chips/F1_low-density.chip +++ b/config/chips/F1_Low_density_device.chip @@ -1,13 +1,13 @@ -# Chip-ID file for F1 low-density +# Chip-ID file for F1 Low-density device # chip_id 0x412 -description F1 low-density +description F1 Low-density device flash_type 1 flash_pagesize 0x400 sram_size 0x2800 bootrom_base 0x1ffff000 bootrom_size 0x800 -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 +option_size 0x10 flags swo diff --git a/config/chips/F1_value_line_high-density.chip b/config/chips/F1_value_line_high-density.chip deleted file mode 100644 index 6a49c2699..000000000 --- a/config/chips/F1_value_line_high-density.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for F1 value line high-density -# -chip_id 0x428 -description F1 value line high-density -flash_type 1 -flash_pagesize 0x800 -sram_size 0x8000 -bootrom_base 0x1ffff000 -bootrom_size 0x800 -option_base 0x0 -option_size 0x0 -flags swo - diff --git a/config/chips/F1_connectivity_line.chip b/config/chips/F1xx_CL.chip similarity index 53% rename from config/chips/F1_connectivity_line.chip rename to config/chips/F1xx_CL.chip index b6fd9c93a..c2a3b2e69 100644 --- a/config/chips/F1_connectivity_line.chip +++ b/config/chips/F1xx_CL.chip @@ -1,13 +1,13 @@ -# Chip-ID file for F1 connectivity line +# Chip-ID file for F1xx CL # chip_id 0x418 -description F1 connectivity line +description F1xx CL flash_type 1 flash_pagesize 0x800 sram_size 0x10000 bootrom_base 0x1fffb000 bootrom_size 0x4800 -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 +option_size 0x10 flags swo diff --git a/config/chips/F1_high-density.chip b/config/chips/F1xx_High_density.chip similarity index 53% rename from config/chips/F1_high-density.chip rename to config/chips/F1xx_High_density.chip index f88413fc8..1deb5f01b 100644 --- a/config/chips/F1_high-density.chip +++ b/config/chips/F1xx_High_density.chip @@ -1,13 +1,13 @@ -# Chip-ID file for F1 high-density +# Chip-ID file for F1xx High-density # chip_id 0x414 -description F1 high-density +description F1xx High-density flash_type 1 flash_pagesize 0x800 sram_size 0x10000 bootrom_base 0x1ffff000 bootrom_size 0x800 -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 +option_size 0x10 flags swo diff --git a/config/chips/F1xx_High_density_value_line.chip b/config/chips/F1xx_High_density_value_line.chip new file mode 100644 index 000000000..9e467c9d7 --- /dev/null +++ b/config/chips/F1xx_High_density_value_line.chip @@ -0,0 +1,13 @@ +# Chip-ID file for F1xx High-density value line +# +chip_id 0x428 +description F1xx High-density value line +flash_type 1 +flash_pagesize 0x800 +sram_size 0x8000 +bootrom_base 0x1ffff000 +bootrom_size 0x800 +option_base 0x1ffff800 +option_size 0x10 +flags swo + diff --git a/config/chips/F1_medium-density.chip b/config/chips/F1xx_Medium_density.chip similarity index 52% rename from config/chips/F1_medium-density.chip rename to config/chips/F1xx_Medium_density.chip index 25cbec2dc..a6d81d6f6 100644 --- a/config/chips/F1_medium-density.chip +++ b/config/chips/F1xx_Medium_density.chip @@ -1,13 +1,13 @@ -# Chip-ID file for F1 medium-density +# Chip-ID file for F1xx Medium-density # chip_id 0x410 -description F1 medium-density +description F1xx Medium-density flash_type 1 flash_pagesize 0x400 sram_size 0x5000 bootrom_base 0x1ffff000 bootrom_size 0x800 -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 +option_size 0x10 flags swo diff --git a/config/chips/F1_value_line.chip b/config/chips/F1xx_Value_Line.chip similarity index 54% rename from config/chips/F1_value_line.chip rename to config/chips/F1xx_Value_Line.chip index 5515d9acd..463cc2d9c 100644 --- a/config/chips/F1_value_line.chip +++ b/config/chips/F1xx_Value_Line.chip @@ -1,13 +1,13 @@ -# Chip-ID file for F1 value line +# Chip-ID file for F1xx Value Line # chip_id 0x420 -description F1 value line +description F1xx Value Line flash_type 1 flash_pagesize 0x400 sram_size 0x2000 bootrom_base 0x1ffff000 bootrom_size 0x800 -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 +option_size 0x10 flags swo diff --git a/config/chips/F1_XL-density.chip b/config/chips/F1xx_XL_density.chip similarity index 71% rename from config/chips/F1_XL-density.chip rename to config/chips/F1xx_XL_density.chip index 3b3c95ab0..318efbff0 100644 --- a/config/chips/F1_XL-density.chip +++ b/config/chips/F1xx_XL_density.chip @@ -1,7 +1,7 @@ -# Chip-ID file for F1 XL-density +# Chip-ID file for F1xx XL-density # chip_id 0x430 -description F1 XL-density +description F1xx XL-density flash_type 2 flash_pagesize 0x800 sram_size 0x18000 diff --git a/config/chips/F2.chip b/config/chips/F2xx.chip similarity index 80% rename from config/chips/F2.chip rename to config/chips/F2xx.chip index 31a4d34a8..30808f1aa 100644 --- a/config/chips/F2.chip +++ b/config/chips/F2xx.chip @@ -1,7 +1,7 @@ -# Chip-ID file for F2 +# Chip-ID file for F2xx # chip_id 0x411 -description F2 +description F2xx flash_type 3 flash_pagesize 0x20000 sram_size 0x20000 diff --git a/config/chips/F3xx_small.chip b/config/chips/F301_F302_F318.chip similarity index 54% rename from config/chips/F3xx_small.chip rename to config/chips/F301_F302_F318.chip index 31fd136a8..429c836b4 100644 --- a/config/chips/F3xx_small.chip +++ b/config/chips/F301_F302_F318.chip @@ -1,13 +1,13 @@ -# Chip-ID file for F3xx small +# Chip-ID file for F301/F302/F318 # chip_id 0x439 -description F3xx small +description F301/F302/F318 flash_type 1 flash_pagesize 0x800 sram_size 0xa000 bootrom_base 0x1fffd800 bootrom_size 0x2000 -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 +option_size 0x10 flags swo diff --git a/config/chips/F302_F303_F358.chip b/config/chips/F302_F303_F358.chip new file mode 100644 index 000000000..ffd1491ff --- /dev/null +++ b/config/chips/F302_F303_F358.chip @@ -0,0 +1,13 @@ +# Chip-ID file for F302/F303/F358 +# +chip_id 0x422 +description F302/F303/F358 +flash_type 1 +flash_pagesize 0x800 +sram_size 0xa000 +bootrom_base 0x1ffff000 +bootrom_size 0x800 +option_base 0x1ffff800 +option_size 0x10 +flags swo + diff --git a/config/chips/F334_medium_density.chip b/config/chips/F303_F328_F334.chip similarity index 54% rename from config/chips/F334_medium_density.chip rename to config/chips/F303_F328_F334.chip index 365931a01..5df2a9bbb 100644 --- a/config/chips/F334_medium_density.chip +++ b/config/chips/F303_F328_F334.chip @@ -1,13 +1,13 @@ -# Chip-ID file for F334 medium density +# Chip-ID file for F303/F328/F334 # chip_id 0x438 -description F334 medium density +description F303/F328/F334 flash_type 1 flash_pagesize 0x800 sram_size 0x3000 bootrom_base 0x1fffd800 bootrom_size 0x2000 -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 +option_size 0x10 flags swo diff --git a/config/chips/F303_high_density.chip b/config/chips/F303_high_density.chip index afbdf63b5..748c27cbc 100644 --- a/config/chips/F303_high_density.chip +++ b/config/chips/F303_high_density.chip @@ -7,7 +7,7 @@ flash_pagesize 0x800 sram_size 0x10000 bootrom_base 0x1fffd800 bootrom_size 0x2000 -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 +option_size 0x10 flags swo diff --git a/config/chips/F37x.chip b/config/chips/F37x.chip index 5d5723b14..92201657d 100644 --- a/config/chips/F37x.chip +++ b/config/chips/F37x.chip @@ -7,7 +7,7 @@ flash_pagesize 0x800 sram_size 0xa000 bootrom_base 0x1ffff000 bootrom_size 0x800 -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 +option_size 0x10 flags swo diff --git a/config/chips/F4xx_low_power.chip b/config/chips/F401xB_C.chip similarity index 71% rename from config/chips/F4xx_low_power.chip rename to config/chips/F401xB_C.chip index 7c1cc1243..09e998dba 100644 --- a/config/chips/F4xx_low_power.chip +++ b/config/chips/F401xB_C.chip @@ -1,7 +1,7 @@ -# Chip-ID file for F4xx low power +# Chip-ID file for F401xB/C # chip_id 0x423 -description F4xx low power +description F401xB/C flash_type 3 flash_pagesize 0x4000 sram_size 0x10000 diff --git a/config/chips/F4xx_dynamic_efficiency.chip b/config/chips/F401xD_E.chip similarity index 66% rename from config/chips/F4xx_dynamic_efficiency.chip rename to config/chips/F401xD_E.chip index 02a886c26..5b70d7d86 100644 --- a/config/chips/F4xx_dynamic_efficiency.chip +++ b/config/chips/F401xD_E.chip @@ -1,7 +1,7 @@ -# Chip-ID file for F4xx dynamic efficiency +# Chip-ID file for F401xD/E # chip_id 0x433 -description F4xx dynamic efficiency +description F401xD/E flash_type 3 flash_pagesize 0x4000 sram_size 0x18000 diff --git a/config/chips/F411xx.chip b/config/chips/F411xC_E.chip similarity index 76% rename from config/chips/F411xx.chip rename to config/chips/F411xC_E.chip index e41288de7..d344489c5 100644 --- a/config/chips/F411xx.chip +++ b/config/chips/F411xC_E.chip @@ -1,7 +1,7 @@ -# Chip-ID file for F411xx +# Chip-ID file for F411xC/E # chip_id 0x431 -description F411xx +description F411xC/E flash_type 3 flash_pagesize 0x4000 sram_size 0x20000 diff --git a/config/chips/F413.chip b/config/chips/F413_F423.chip similarity index 75% rename from config/chips/F413.chip rename to config/chips/F413_F423.chip index 94813647f..647775eeb 100644 --- a/config/chips/F413.chip +++ b/config/chips/F413_F423.chip @@ -1,7 +1,7 @@ -# Chip-ID file for F413 +# Chip-ID file for F413/F423 # chip_id 0x463 -description F413 +description F413/F423 flash_type 3 flash_pagesize 0x4000 sram_size 0x50000 diff --git a/config/chips/F4xx.chip b/config/chips/F4x5_F4x7.chip similarity index 76% rename from config/chips/F4xx.chip rename to config/chips/F4x5_F4x7.chip index 1c6d087a5..b19e4a5b3 100644 --- a/config/chips/F4xx.chip +++ b/config/chips/F4x5_F4x7.chip @@ -1,7 +1,7 @@ -# Chip-ID file for F4xx +# Chip-ID file for F4x5/F4x7 # chip_id 0x413 -description F4xx +description F4x5/F4x7 flash_type 3 flash_pagesize 0x4000 sram_size 0x30000 diff --git a/config/chips/F7xx.chip b/config/chips/F74x_F75x.chip similarity index 75% rename from config/chips/F7xx.chip rename to config/chips/F74x_F75x.chip index b6e3774f7..0604b299d 100644 --- a/config/chips/F7xx.chip +++ b/config/chips/F74x_F75x.chip @@ -1,7 +1,7 @@ -# Chip-ID file for F7xx +# Chip-ID file for F74x/F75x # chip_id 0x449 -description F7xx +description F74x/F75x flash_type 3 flash_pagesize 0x800 sram_size 0x50000 diff --git a/config/chips/F76xxx.chip b/config/chips/F76x_F77x.chip similarity index 68% rename from config/chips/F76xxx.chip rename to config/chips/F76x_F77x.chip index ef17fc557..304c99191 100644 --- a/config/chips/F76xxx.chip +++ b/config/chips/F76x_F77x.chip @@ -1,7 +1,7 @@ -# Chip-ID file for F76xxx +# Chip-ID file for F76x/F77x # chip_id 0x451 -description F76xxx +description F76x/F77x flash_type 4 flash_pagesize 0x800 sram_size 0x80000 @@ -9,5 +9,5 @@ bootrom_base 0x200000 bootrom_size 0xedc0 option_base 0x1fff0000 option_size 0x20 -flags swo +flags dualbank swo diff --git a/config/chips/G030_G031_G041.chip b/config/chips/G03x_G04x.chip similarity index 72% rename from config/chips/G030_G031_G041.chip rename to config/chips/G03x_G04x.chip index 16a9a79ff..7c5a00c58 100644 --- a/config/chips/G030_G031_G041.chip +++ b/config/chips/G03x_G04x.chip @@ -1,7 +1,7 @@ -# Chip-ID file for G030/G031/G041 +# Chip-ID file for G03x/G04x # chip_id 0x466 -description G030/G031/G041 +description G03x/G04x flash_type 7 flash_pagesize 0x800 sram_size 0x2000 diff --git a/config/chips/G05x_G06x.chip b/config/chips/G05x_G06x.chip new file mode 100644 index 000000000..45295ec6e --- /dev/null +++ b/config/chips/G05x_G06x.chip @@ -0,0 +1,13 @@ +# Chip-ID file for G05x/G06x +# +chip_id 0x456 +description G05x/G06x +flash_type 7 +flash_pagesize 0x800 +sram_size 0x9000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x1fff7800 +option_size 0x4 +flags none + diff --git a/config/chips/G070_G071_G081.chip b/config/chips/G07x_G08x.chip similarity index 72% rename from config/chips/G070_G071_G081.chip rename to config/chips/G07x_G08x.chip index 7fb81eb1f..7bddcd82c 100644 --- a/config/chips/G070_G071_G081.chip +++ b/config/chips/G07x_G08x.chip @@ -1,7 +1,7 @@ -# Chip-ID file for G070/G071/G081 +# Chip-ID file for G07x/G08x # chip_id 0x460 -description G070/G071/G081 +description G07x/G08x flash_type 7 flash_pagesize 0x800 sram_size 0x9000 diff --git a/config/chips/G0Bx_G0Cx.chip b/config/chips/G0Bx_G0Cx.chip new file mode 100644 index 000000000..98e503569 --- /dev/null +++ b/config/chips/G0Bx_G0Cx.chip @@ -0,0 +1,13 @@ +# Chip-ID file for G0Bx/G0Cx +# +chip_id 0x467 +description G0Bx/G0Cx +flash_type 7 +flash_pagesize 0x800 +sram_size 0x9000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x1fff7800 +option_size 0x4 +flags dualbank + diff --git a/config/chips/G4_cat2.chip b/config/chips/G43x_G44x.chip similarity index 75% rename from config/chips/G4_cat2.chip rename to config/chips/G43x_G44x.chip index ea144114d..033f1dd80 100644 --- a/config/chips/G4_cat2.chip +++ b/config/chips/G43x_G44x.chip @@ -1,7 +1,7 @@ -# Chip-ID file for G4 cat2 +# Chip-ID file for G43x/G44x # chip_id 0x468 -description G4 cat2 +description G43x/G44x flash_type 8 flash_pagesize 0x800 sram_size 0x8000 diff --git a/config/chips/G4_cat3.chip b/config/chips/G47x_G48x.chip similarity index 68% rename from config/chips/G4_cat3.chip rename to config/chips/G47x_G48x.chip index 7e34e001c..fa331650f 100644 --- a/config/chips/G4_cat3.chip +++ b/config/chips/G47x_G48x.chip @@ -1,10 +1,10 @@ -# Chip-ID file for G4 cat3 +# Chip-ID file for G47x/G48x # chip_id 0x469 -description G4 cat3 +description G47x/G48x flash_type 8 flash_pagesize 0x800 -sram_size 0x18000 +sram_size 0x20000 bootrom_base 0x1fff0000 bootrom_size 0x7000 option_base 0x1ffff800 diff --git a/config/chips/G49x_G4Ax.chip b/config/chips/G49x_G4Ax.chip new file mode 100644 index 000000000..b764572db --- /dev/null +++ b/config/chips/G49x_G4Ax.chip @@ -0,0 +1,13 @@ +# Chip-ID file for G49x/G4Ax +# +chip_id 0x479 +description G49x/G4Ax +flash_type 8 +flash_pagesize 0x800 +sram_size 0x1c000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x1ffff800 +option_size 0x4 +flags swo + diff --git a/config/chips/L011.chip b/config/chips/L01x_L02x.chip similarity index 75% rename from config/chips/L011.chip rename to config/chips/L01x_L02x.chip index 719185558..c3d2074b9 100644 --- a/config/chips/L011.chip +++ b/config/chips/L01x_L02x.chip @@ -1,7 +1,7 @@ -# Chip-ID file for L011 +# Chip-ID file for L01x/L02x # chip_id 0x457 -description L011 +description L01x/L02x flash_type 5 flash_pagesize 0x80 sram_size 0x2000 diff --git a/config/chips/L0xx_cat2.chip b/config/chips/L0xx_Cat_2.chip similarity index 75% rename from config/chips/L0xx_cat2.chip rename to config/chips/L0xx_Cat_2.chip index cdcff81cc..47183b8ef 100644 --- a/config/chips/L0xx_cat2.chip +++ b/config/chips/L0xx_Cat_2.chip @@ -1,7 +1,7 @@ -# Chip-ID file for L0xx cat2 +# Chip-ID file for L0xx Cat.2 # chip_id 0x425 -description L0xx cat2 +description L0xx Cat.2 flash_type 5 flash_pagesize 0x80 sram_size 0x2000 diff --git a/config/chips/L0x3.chip b/config/chips/L0xx_Cat_3.chip similarity index 75% rename from config/chips/L0x3.chip rename to config/chips/L0xx_Cat_3.chip index cbdc6cace..6d9fcc105 100644 --- a/config/chips/L0x3.chip +++ b/config/chips/L0xx_Cat_3.chip @@ -1,7 +1,7 @@ -# Chip-ID file for L0x3 +# Chip-ID file for L0xx Cat.3 # chip_id 0x417 -description L0x3 +description L0xx Cat.3 flash_type 5 flash_pagesize 0x80 sram_size 0x2000 diff --git a/config/chips/L0xx_cat5.chip b/config/chips/L0xx_Cat_5.chip similarity index 68% rename from config/chips/L0xx_cat5.chip rename to config/chips/L0xx_Cat_5.chip index 2c755a0d8..545c1c2ef 100644 --- a/config/chips/L0xx_cat5.chip +++ b/config/chips/L0xx_Cat_5.chip @@ -1,7 +1,7 @@ -# Chip-ID file for L0xx cat5 +# Chip-ID file for L0xx Cat.5 # chip_id 0x447 -description L0xx cat5 +description L0xx Cat.5 flash_type 5 flash_pagesize 0x80 sram_size 0x5000 @@ -9,5 +9,5 @@ bootrom_base 0x1ff0000 bootrom_size 0x2000 option_base 0x1ff80000 option_size 0x14 -flags none +flags dualbank diff --git a/config/chips/L1xx_medium-density.chip b/config/chips/L1xx_Cat_1.chip similarity index 68% rename from config/chips/L1xx_medium-density.chip rename to config/chips/L1xx_Cat_1.chip index f77c19cac..6c8b211c4 100644 --- a/config/chips/L1xx_medium-density.chip +++ b/config/chips/L1xx_Cat_1.chip @@ -1,7 +1,7 @@ -# Chip-ID file for L1xx medium-density +# Chip-ID file for L1xx Cat.1 # chip_id 0x416 -description L1xx medium-density +description L1xx Cat.1 flash_type 5 flash_pagesize 0x100 sram_size 0x4000 diff --git a/config/chips/L1xx_cat2.chip b/config/chips/L1xx_Cat_2.chip similarity index 74% rename from config/chips/L1xx_cat2.chip rename to config/chips/L1xx_Cat_2.chip index 7f949923e..1ff71edef 100644 --- a/config/chips/L1xx_cat2.chip +++ b/config/chips/L1xx_Cat_2.chip @@ -1,7 +1,7 @@ -# Chip-ID file for L1xx cat2 +# Chip-ID file for L1xx Cat.2 # chip_id 0x429 -description L1xx cat2 +description L1xx Cat.2 flash_type 5 flash_pagesize 0x100 sram_size 0x8000 diff --git a/config/chips/L1xx_medium-plus-density.chip b/config/chips/L1xx_Cat_3.chip similarity index 65% rename from config/chips/L1xx_medium-plus-density.chip rename to config/chips/L1xx_Cat_3.chip index da557e3c8..f417e07f9 100644 --- a/config/chips/L1xx_medium-plus-density.chip +++ b/config/chips/L1xx_Cat_3.chip @@ -1,7 +1,7 @@ -# Chip-ID file for L1xx medium-plus-density +# Chip-ID file for L1xx Cat.3 # chip_id 0x427 -description L1xx medium-plus-density +description L1xx Cat.3 flash_type 5 flash_pagesize 0x100 sram_size 0x8000 diff --git a/config/chips/L1xx_high-density.chip b/config/chips/L1xx_Cat_4.chip similarity index 70% rename from config/chips/L1xx_high-density.chip rename to config/chips/L1xx_Cat_4.chip index 409c04062..dbf7869ad 100644 --- a/config/chips/L1xx_high-density.chip +++ b/config/chips/L1xx_Cat_4.chip @@ -1,7 +1,7 @@ -# Chip-ID file for L1xx high-density +# Chip-ID file for L1xx Cat.4 # chip_id 0x436 -description L1xx high-density +description L1xx Cat.4 flash_type 5 flash_pagesize 0x100 sram_size 0xc000 diff --git a/config/chips/L152RE.chip b/config/chips/L1xx_Cat_5.chip similarity index 74% rename from config/chips/L152RE.chip rename to config/chips/L1xx_Cat_5.chip index 4d9658ee9..12342d14f 100644 --- a/config/chips/L152RE.chip +++ b/config/chips/L1xx_Cat_5.chip @@ -1,7 +1,7 @@ -# Chip-ID file for L152RE +# Chip-ID file for L1xx Cat.5 # chip_id 0x437 -description L152RE +description L1xx Cat.5 flash_type 5 flash_pagesize 0x100 sram_size 0x14000 diff --git a/config/chips/L41x.chip b/config/chips/L41x_L42x.chip similarity index 75% rename from config/chips/L41x.chip rename to config/chips/L41x_L42x.chip index 5b491ccd4..3e086e159 100644 --- a/config/chips/L41x.chip +++ b/config/chips/L41x_L42x.chip @@ -1,7 +1,7 @@ -# Chip-ID file for L41x +# Chip-ID file for L41x/L42x # chip_id 0x464 -description L41x +description L41x/L42x flash_type 6 flash_pagesize 0x800 sram_size 0xa000 diff --git a/config/chips/L45x_L46x.chip b/config/chips/L45x_46x.chip similarity index 75% rename from config/chips/L45x_L46x.chip rename to config/chips/L45x_46x.chip index 8b5f91ec3..943b275d5 100644 --- a/config/chips/L45x_L46x.chip +++ b/config/chips/L45x_46x.chip @@ -1,7 +1,7 @@ -# Chip-ID file for L45x/L46x +# Chip-ID file for L45x/46x # chip_id 0x462 -description L45x/L46x +description L45x/46x flash_type 6 flash_pagesize 0x800 sram_size 0x20000 diff --git a/config/chips/L4xx.chip b/config/chips/L47x_L48x.chip similarity index 76% rename from config/chips/L4xx.chip rename to config/chips/L47x_L48x.chip index c665c245f..7069229f3 100644 --- a/config/chips/L4xx.chip +++ b/config/chips/L47x_L48x.chip @@ -1,7 +1,7 @@ -# Chip-ID file for L4xx +# Chip-ID file for L47x/L48x # chip_id 0x415 -description L4xx +description L47x/L48x flash_type 6 flash_pagesize 0x800 sram_size 0x18000 diff --git a/config/chips/L4Px.chip b/config/chips/L4Px.chip new file mode 100644 index 000000000..3e0fbea50 --- /dev/null +++ b/config/chips/L4Px.chip @@ -0,0 +1,13 @@ +# Chip-ID file for L4Px +# +chip_id 0x471 +description L4Px +flash_type 6 +flash_pagesize 0x1000 +sram_size 0xa0000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x0 +option_size 0x0 +flags dualbank swo + diff --git a/config/chips/L4Rx.chip b/config/chips/L4Rx.chip index 11780ce27..a9a26f419 100644 --- a/config/chips/L4Rx.chip +++ b/config/chips/L4Rx.chip @@ -9,5 +9,5 @@ bootrom_base 0x1fff0000 bootrom_size 0x7000 option_base 0x0 option_size 0x0 -flags swo +flags dualbank swo diff --git a/config/chips/WB55.chip b/config/chips/WB5x_3x.chip similarity index 76% rename from config/chips/WB55.chip rename to config/chips/WB5x_3x.chip index 585b576bc..0627bdeec 100644 --- a/config/chips/WB55.chip +++ b/config/chips/WB5x_3x.chip @@ -1,7 +1,7 @@ -# Chip-ID file for WB55 +# Chip-ID file for WB5x/3x # chip_id 0x495 -description WB55 +description WB5x/3x flash_type 9 flash_pagesize 0x1000 sram_size 0x40000 diff --git a/config/chips/WLE.chip b/config/chips/WLEx.chip similarity index 79% rename from config/chips/WLE.chip rename to config/chips/WLEx.chip index dbdf66d59..19d0678e5 100644 --- a/config/chips/WLE.chip +++ b/config/chips/WLEx.chip @@ -1,7 +1,7 @@ -# Chip-ID file for WLE +# Chip-ID file for WLEx # chip_id 0x497 -description WLE +description WLEx flash_type 9 flash_pagesize 0x800 sram_size 0x10000 From 0489af7d4d40ae32413fb449d064dad49ba227ee Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 29 Aug 2021 18:08:18 +0200 Subject: [PATCH 1250/1435] General Project Update - [doc] Updated version requirements - Updated CHANGELOG.md --- CHANGELOG.md | 4 ++ doc/version_support.md | 95 ++++++++++++++++++++++-------------------- 2 files changed, 54 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bbb41a98..06f995d21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Updates & changes: - Drop execute bits from source code files ([#1167](https://github.com/stlink-org/stlink/pull/1167)) - Use proper Markdown headers for supported MCUs ([#1168](https://github.com/stlink-org/stlink/pull/1168)) - Removed redundant array ([#1178](https://github.com/stlink-org/stlink/pull/1178)) +- Updated chip config files from the library structs ([#1181](https://github.com/stlink-org/stlink/pull/1181)) Fixes: - cmake: Install shared libraries in proper directories ([#1142](https://github.com/stlink-org/stlink/pull/1142)) @@ -37,6 +38,9 @@ Fixes: - Fixed parsing hex numbers in chip config files ([#1169](https://github.com/stlink-org/stlink/pull/1169)) - Corrected flash_pagesize to use hex format ([#1172](https://github.com/stlink-org/stlink/pull/1172)) - Fixed compilation for MSVC ([#1176](https://github.com/stlink-org/stlink/pull/1176)) +- Fixed few warnings for msvc about type conversion with possible lost data ([#1179](https://github.com/stlink-org/stlink/pull/1179)) +- st-flash and other utilities search for chip files in the wrong directory ([#1180](https://github.com/stlink-org/stlink/pull/1180), commit [#c8fc656](https://github.com/stlink-org/stlink/commit/c8fc6561fead79ad49c09d82bab864745086792c)) +- Fixed broken build on 32 bit systems ([#985](https://github.com/stlink-org/stlink/pull/985), [#1175](https://github.com/stlink-org/stlink/pull/1175), commit [#c8fc656](https://github.com/stlink-org/stlink/commit/c8fc6561fead79ad49c09d82bab864745086792c)) # v1.7.0 diff --git a/doc/version_support.md b/doc/version_support.md index bf4bc1e5e..2c5df7461 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -21,47 +21,51 @@ NOTE: In order to use a STLINK/V1 programmer on macOS, versions 10.14 or 10.15 a ### Linux-/Unix-based: -| Operating System | libusb | cmake | gtk-3 | Notes | -| ------------------------- | ------------------ | --------- | ----------- | ----------------------------- | -| Arch Linux | 1.0.24 | 3.20.2 | 3.24.29 | | -| Fedora Rawhide [x64] | 1.0.24 (`libusbx`) | 3.20.2 | 3.24.29 | | -| KaOS [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | -| Mageia Cauldron | 1.0.24 | 3.20.2 | 3.24.29 | | -| OpenMandriva Cooker | 1.0.24 | 3.20.2 | 3.24.29 | | -| OpenMandriva Rolling | 1.0.24 | 3.20.2 | 3.24.29 | | -| PCLinuxOS [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | -| Slackware Current | 1.0.24 | 3.20.2 | 3.24.28 | | -| Solus [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | -| openSUSE Tumbleweed [x64] | 1.0.24 | 3.20.1 | 3.24.29 | | -| ALT Linux Sisyphus | 1.0.24 | 3.19.7 | 3.24.29 | | -| Fedora 34 [x64] | 1.0.24 (`libusbx`) | 3.19.7 | 3.24.28 | | -| NetBSD 9.x | 1.0.24 | 3.19.7 | 3.24.27 | | -| NetBSD 8.x | 1.0.24 | 3.19.7 | 3.24.27 | | -| OpenMandriva Lx 4.2 | 1.0.24 | 3.19.3 | 3.24.24 | | -| Mageia 8 | 1.0.24 | 3.19.2 | 3.24.24 | | -| Alpine 3.13 | 1.0.24 | 3.18.4 | 3.24.23 | | -| Debian Sid | 1.0.24 | 3.18.4 | 3.24.24 | | -| Debian 11 (Bullseye) | 1.0.24 | 3.18.4 | 3.24.24 | | -| Ubuntu 21.04 (Hirsute) | 1.0.24 | 3.18.4 | 3.24.25 | | -| Fedora 33 [x64] | 1.0.23 (`libusbx`) | 3.18.3 | 3.24.23 | | -| CentOS 8 Stream [x64] | 1.0.23 (`libusbx`) | 3.18.2 | **3.22.30** | | -| Alpine 3.12 | 1.0.23 | 3.17.2 | 3.24.22 | | -| openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.17.0 | 3.24.20 | | -| openSUSE Leap 15.2 [x64] | 1.0.**21** | 3.17.0 | 3.24.**14** | | -| Adélie 1.0 | 1.0.23 | 3.16.4 | 3.24.23 | | -| Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.16.3 | 3.24.**18** | | -| ALT Linux P9 | 1.0.**22** | 3.16.3 | 3.24.**11** | | -| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.**13** | | -| Mageia 7.1 | 1.0.**22** | 3.14.3 | 3.24.**8** | | -| Debian 10 (Buster) | 1.0.**22** | 3.13.4 | 3.24.**5** | | -| AlmaLinux 8 | 1.0.23 (`libusbx`) | 3.11.4 | 3.24.32 | | -| CentOS 8 [x64] | 1.0.23 (`libusbx`) | 3.11.4 | **3.22.30** | | -| Ubuntu 18.04 LTS (Bionic) | 1.0.**21** | 3.10.2 | **3.22.30** | | -| Debian 9 (Stretch) | 1.0.**21** | **3.7.2** | **3.22.11** | | -| | | | | | -| FreeBSD 13.x | 1.0.**16 - 18** | 3.20.2 | 3.24.27 | LIBUSB_API_VERSION 0x01000102 | -| FreeBSD 12.x | 1.0.**16 - 18** | 3.19.6 | 3.24.27 | LIBUSB_API_VERSION 0x01000102 | -| FreeBSD 11.x | 1.0.**16 - 18** | 3.15.5 | 3.24.27 | LIBUSB_API_VERSION 0x01000102 | +| Operating System | libusb | cmake | gtk-3 | Notes | +| ------------------------- | -------------------------------- | --------- | ----------- | ------------------------ | +| Debian Sid | 1.0.24 | 3.18.4 | 3.24.24 | | +| Debian 11 (Bullseye) | 1.0.24 | 3.18.4 | 3.24.24 | | +| Debian 10 (Buster) | 1.0.**22** | 3.13.4 | 3.24.**5** | | +| Debian 9 (Stretch) | 1.0.**21** | **3.7.2** | **3.22.11** | End of Support: Jun 2022 | +| | | | | | +| Ubuntu 21.04 (Hirsute) | 1.0.24 | 3.18.4 | 3.24.25 | End of Support: Jan 2022 | +| Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.16.3 | 3.24.**18** | | +| Ubuntu 18.04 LTS (Bionic) | 1.0.**21** | 3.10.2 | **3.22.30** | End of Support: Apr 2023 | +| | | | | | +| Fedora Rawhide [x64] | 1.0.24 (`libusbx`) | 3.20.2 | 3.24.29 | | +| Fedora 34 [x64] | 1.0.24 (`libusbx`) | 3.19.7 | 3.24.28 | | +| Fedora 33 [x64] | 1.0.23 (`libusbx`) | 3.18.3 | 3.24.23 | | +| | | | | | +| openSUSE Tumbleweed [x64] | 1.0.24 | 3.20.1 | 3.24.29 | | +| openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.17.0 | 3.24.20 | | +| openSUSE Leap 15.2 [x64] | 1.0.**21** | 3.17.0 | 3.24.**14** | End of Support: Dec 2021 | +| | | | | | +| Alpine 3.14 | 1.0.24 | 3.20.3 | 4.2.1 | | +| Alpine 3.13 | 1.0.24 | 3.18.4 | 3.24.23 | End of Support: Nov 2022 | +| Alpine 3.12 | 1.0.23 | 3.17.2 | 3.24.22 | End of Support: May 2022 | +| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.**13** | End of Support: Nov 2021 | +| | | | | | +| FreeBSD 13.x | 1.0.**16 - 18** (API 0x01000102) | 3.20.2 | 3.24.27 | | +| FreeBSD 12.x | 1.0.**16 - 18** (API 0x01000102) | 3.19.6 | 3.24.27 | | +| FreeBSD 11.x | 1.0.**16 - 18** (API 0x01000102) | 3.15.5 | 3.24.27 | End of Support: Sep 2021 | +| | | | | | +| Arch Linux | 1.0.24 | 3.20.2 | 3.24.29 | | +| KaOS [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | +| Mageia Cauldron | 1.0.24 | 3.20.2 | 3.24.29 | | +| OpenMandriva Cooker | 1.0.24 | 3.20.2 | 3.24.29 | | +| PCLinuxOS [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | +| Slackware Current | 1.0.24 | 3.20.2 | 3.24.28 | | +| Solus [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | +| ALT Linux Sisyphus | 1.0.24 | 3.19.7 | 3.24.29 | | +| NetBSD 9.x | 1.0.24 | 3.19.7 | 3.24.27 | | +| NetBSD 8.x | 1.0.24 | 3.19.7 | 3.24.27 | | +| OpenMandriva Lx 4.2 | 1.0.24 | 3.19.3 | 3.24.24 | | +| Mageia 8 | 1.0.24 | 3.19.2 | 3.24.24 | End of Support: Aug 2022 | +| CentOS 8 Stream [x64] | 1.0.23 (`libusbx`) | 3.18.2 | **3.22.30** | | +| Adélie 1.0 | 1.0.23 | 3.16.4 | 3.24.23 | | +| ALT Linux P9 | 1.0.**22** | 3.16.3 | 3.24.**11** | | +| AlmaLinux 8 | 1.0.23 (`libusbx`) | 3.11.4 | 3.24.32 | | +| CentOS 8 [x64] | 1.0.23 (`libusbx`) | 3.11.4 | **3.22.30** | End of Support: Dec 2021 | ## Unsupported Operating Systems (as of Release v1.7.1) @@ -74,17 +78,18 @@ Systems with highlighted versions remain compatible with this toolset. | NetBSD 7.x | **1.0.22** | **3.16.1** | Jun 2020 | | Alpine 3.10 | **1.0.22** | **3.14.5** | May 2021 | | Fedora 31 [x64] | **1.0.22** (`libusbx`) | **3.14.5** | Nov 2020 | -| Ubuntu 19.10 (Eoan) | **1.0.23** | **3.13.4** | Jul 2020 | +| Mageia 7.1 | **1.0.22** | **3.14.3** | Jun 2021 | | Fedora 30 | **1.0.22** (`libusbx`) | **3.14.2** | May 2020 | +| Ubuntu 19.10 (Eoan) | **1.0.23** | **3.13.4** | Jul 2020 | | Alpine 3.9 | **1.0.22** | **3.13.0** | Jan 2021 | -| openSUSE Leap 15.1 [x64] | **1.0.21** | **3.10.2** | Feb 2021 | +| openSUSE Leap 15.1 [x64] | **1.0.21** | **3.10.2** | Jan 2021 | | Slackware 14.2 | 1.0.20 | 3.5.2 | | | Ubuntu 16.04 LTS (Xenial) | 1.0.20 | 3.5.1 | Apr 2021 | | OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | | | Debian 8 (Jessie) | 1.0.19 | 3.0.2 | Jun 2020 | -| CentOS 7 [x64] | 1.0.21 (`libusbx`) | 2.8.12.2 | | +| CentOS 7 [x64] | 1.0.21 (`libusbx`) | 2.8.12.2 | Jun 2024 | | Ubuntu 14.04 LTS (Trusty) | 1.0.17 | 2.8.12.2 | Apr 2019 | -| CentOS 6 | 1.0.9 (`libusbx`) | 2.8.12.2 | Dec 2020 | +| CentOS 6 | 1.0.9 (`libusbx`) | 2.8.12.2 | Nov 2020 | | Slackware 14.1 | 1.0.9 | 2.8.12 | | | Slackware 14.0 | 1.0.9 | 2.8.8 | | From 7c582b75260fc2af16541d6b1c762ecc5817c906 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Wed, 1 Sep 2021 07:55:26 +0300 Subject: [PATCH 1251/1435] define SSIZE_MAX if not defined --- src/win32/unistd/unistd.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/win32/unistd/unistd.h b/src/win32/unistd/unistd.h index ac9d0add3..389c44664 100644 --- a/src/win32/unistd/unistd.h +++ b/src/win32/unistd/unistd.h @@ -51,6 +51,9 @@ */ #define ssize_t int +#ifndef SSIZE_MAX +#define SSIZE_MAX ((sizeof(ssize_t) == 4) ? 2147483647 : 9223372036854775807) +#endif #define STDIN_FILENO 0 #define STDOUT_FILENO 1 From 95ccd02207f7ba9b3323726bf16478879d956de1 Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Tue, 7 Sep 2021 23:12:46 +0100 Subject: [PATCH 1252/1435] Add support for V3 devices with no MSD Add support for ST-Link V3 devices without MSD that identify using USB PID 0x3754. This PID has been observed on a Nucleo board where MSD was disabled. --- src/stlink-lib/usb.c | 3 ++- src/stlink-lib/usb.h | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 58a07f1a6..e07918800 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1260,7 +1260,8 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER || desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID || desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID || - desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID) { + desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID || + desc.idProduct == STLINK_USB_PID_STLINK_V3_NO_MSD_PID) { slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; slu->ep_trace = 2 | LIBUSB_ENDPOINT_IN; } else { diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index 27de32700..c6b71ba4e 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -26,6 +26,7 @@ extern "C" { #define STLINK_USB_PID_STLINK_V3E_PID 0x374e #define STLINK_USB_PID_STLINK_V3S_PID 0x374f #define STLINK_USB_PID_STLINK_V3_2VCP_PID 0x3753 +#define STLINK_USB_PID_STLINK_V3_NO_MSD_PID 0x3754 #define STLINK_V1_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK) @@ -38,7 +39,8 @@ extern "C" { #define STLINK_V3_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK_V3_USBLOADER || \ (pid) == STLINK_USB_PID_STLINK_V3E_PID || \ (pid) == STLINK_USB_PID_STLINK_V3S_PID || \ - (pid) == STLINK_USB_PID_STLINK_V3_2VCP_PID) + (pid) == STLINK_USB_PID_STLINK_V3_2VCP_PID || \ + (pid) == STLINK_USB_PID_STLINK_V3_NO_MSD_PID) #define STLINK_SUPPORTED_USB_PID(pid) (STLINK_V1_USB_PID(pid) || \ STLINK_V2_USB_PID(pid) || \ From 6471a60460a4659134cf80d8864a022dc09b8447 Mon Sep 17 00:00:00 2001 From: pcnorden <7767295+pcnorden@users.noreply.github.com> Date: Wed, 8 Sep 2021 17:20:58 +0200 Subject: [PATCH 1253/1435] Changed broken link to new address of udev rules Changed and checked that it should work with the new link. Also changed the number of files to 4 since there are 4 udev rule files in the directory. --- doc/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 7e0b3901b..955f85611 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -81,7 +81,7 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", \ and the `idVendor` of `0483` and `idProduct` of `374b` matches the vendor id from the `lsusb` output. -Make sure that you have all 3 files from here: https://github.com/stlink-org/stlink/tree/master/etc/udev/rules.d in your `/etc/udev/rules.d` directory. After copying new files or editing excisting files in `/etc/udev/ruled.d` you should run the following: +Make sure that you have all 4 files from here: https://github.com/stlink-org/stlink/tree/master/config/udev/rules.d in your `/etc/udev/rules.d` directory. After copying new files or editing excisting files in `/etc/udev/ruled.d` you should run the following: ``` sudo udevadm control --reload-rules From 478cf82aed3463566ba34399b8a283f7e57b3fcc Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Wed, 8 Sep 2021 22:09:24 +0100 Subject: [PATCH 1254/1435] Include flash_size_reg in chipid params dumps --- src/stlink-lib/chipid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index d51a0edcb..0fc1270a2 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -906,6 +906,7 @@ void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { fprintf(fp, "chip_id 0x%x\n", dev->chip_id); fprintf(fp, "description %s\n", dev->description); fprintf(fp, "flash_type %d\n", dev->flash_type); + fprintf(fp, "flash_size_reg 0x%x\n", dev->flash_size_reg); fprintf(fp, "flash_pagesize 0x%x\n", dev->flash_pagesize); fprintf(fp, "sram_size 0x%x\n", dev->sram_size); fprintf(fp, "bootrom_base 0x%x\n", dev->bootrom_base); From c676779988c65658cf3e67a60f46f767dfa4421a Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Wed, 8 Sep 2021 22:10:25 +0100 Subject: [PATCH 1255/1435] Fix incorrect chipid params comparison The current chipid params comparison code is based on a simple memcmp. This doesn't work since the structure contains a string pointer. Replace it with a simple field-by-field comparison. --- src/stlink-lib/chipid.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 0fc1270a2..3e89ec0c1 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -916,6 +916,22 @@ void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { fprintf(fp, "flags %d\n\n", dev->flags); } +static int chipid_params_eq(struct stlink_chipid_params *p1, struct stlink_chipid_params *p2) +{ + return p1->chip_id == p2->chip_id && + p1->description && p2->description && + strcmp(p1->description, p2->description) == 0 && + p1->flash_type == p2->flash_type && + p1->flash_size_reg == p2->flash_size_reg && + p1->flash_pagesize == p2->flash_pagesize && + p1->sram_size == p2->sram_size && + p1->bootrom_base == p2->bootrom_base && + p1->bootrom_size == p2->bootrom_size && + p1->option_base == p2->option_base && + p1->option_size == p2->option_size && + p1->flags == p2->flags; +} + struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { struct stlink_chipid_params *params = NULL; struct stlink_chipid_params *p2; @@ -931,7 +947,7 @@ struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { #if 1 if (params == NULL) { params = p2; - } else if (memcmp (p2, params, sizeof(struct stlink_chipid_params) - sizeof(struct stlink_chipid_params *)) != 0) { + } else if (!chipid_params_eq(params, p2)) { // fprintf (stderr, "Error, chipid params not identical\n"); // return NULL; fprintf(stderr, "---------- old ------------\n"); From b29a740b15df4c44258db4e3ae8bfba6676b851d Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Wed, 8 Sep 2021 22:11:59 +0100 Subject: [PATCH 1256/1435] Silence warning chipid files with STLINK_FLASH_TYPE_UNKNOWN The chipid configuration parser currently emits a warning when it encounters a file with the flash type set to STLINK_FLASH_TYPE_UNKNOWN. In practice, this means that the warning will always be printed since 'unknown_device.chip' uses this value. Make STLINK_FLASH_TYPE_UNKNOWN a permitted value in the config file parser. --- src/stlink-lib/chipid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 3e89ec0c1..74e1a1647 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1001,7 +1001,7 @@ void process_chipfile(char *fname) { } else if (strcmp (word, "flash_type") == 0) { if (sscanf(value, "%i", (int *)&ts->flash_type) < 1) { fprintf(stderr, "Failed to parse flash type\n"); - } else if (ts->flash_type <= STLINK_FLASH_TYPE_UNKNOWN || ts->flash_type >= STLINK_FLASH_TYPE_MAX) { + } else if (ts->flash_type < STLINK_FLASH_TYPE_UNKNOWN || ts->flash_type >= STLINK_FLASH_TYPE_MAX) { fprintf(stderr, "Unrecognized flash type\n"); } } else if (strcmp (word, "flash_size_reg") == 0) { From 4d556ce150e4048beb6fb6e886b29e2f8962e690 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 16 Sep 2021 00:57:54 +0200 Subject: [PATCH 1257/1435] Update src/stlink-lib/chipid.c Co-authored-by: Grzegorz Szymaszek --- src/stlink-lib/chipid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 74e1a1647..43a55a495 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -916,7 +916,7 @@ void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { fprintf(fp, "flags %d\n\n", dev->flags); } -static int chipid_params_eq(struct stlink_chipid_params *p1, struct stlink_chipid_params *p2) +static int chipid_params_eq(const struct stlink_chipid_params *p1, const struct stlink_chipid_params *p2) { return p1->chip_id == p2->chip_id && p1->description && p2->description && From ce8e1c4942eace3d7d84e770a9401a21b41f72af Mon Sep 17 00:00:00 2001 From: c-grant <60671494+c-grant@users.noreply.github.com> Date: Thu, 4 Nov 2021 21:50:12 -0400 Subject: [PATCH 1258/1435] Update gdb-server.c --- src/st-util/gdb-server.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index a651014c0..ad39ab14a 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -518,6 +518,8 @@ static const char* const memory_map_template_H72x3x = " 0x%x" "
      " " " // peripheral regs + " " // External Memory + " " // External device " " // cortex regs " " // bootrom ""; From e94b5db1b474268785a856e0859d21d6e2967a79 Mon Sep 17 00:00:00 2001 From: c-grant <60671494+c-grant@users.noreply.github.com> Date: Fri, 5 Nov 2021 23:45:52 -0400 Subject: [PATCH 1259/1435] Update gdb-server.c --- src/st-util/gdb-server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index ad39ab14a..81c0aa83a 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -513,13 +513,13 @@ static const char* const memory_map_template_H72x3x = " " // RAM D1 320kB " " // RAM D2 23kB " " // RAM D3 16kB - " " // Backup RAM 4kB + " " // Backup RAM 4kB " " " 0x%x" " " " " // peripheral regs " " // External Memory - " " // External device + " " // External device " " // cortex regs " " // bootrom ""; From f95aec79944c9963daa932a2af51838e396ff77c Mon Sep 17 00:00:00 2001 From: Jan Bramkamp Date: Wed, 24 Nov 2021 01:45:24 +0100 Subject: [PATCH 1260/1435] Teach cmake to find libusb-1.0 port/pkg on OpenBSD On OpenBSD libusb is provided by the libusb1 port/package. --- cmake/modules/Findlibusb.cmake | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index d861bdd5f..cd52026f5 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -43,6 +43,23 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is message(FATAL_ERROR "Expected libusb library not found on your system! Verify your system integrity.") endif () +elseif (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") # OpenBSD; libusb-1.0 is available from ports + FIND_PATH( + LIBUSB_INCLUDE_DIR NAMES libusb.h + HINTS /usr/local/include + PATH_SUFFIXES libusb-1.0 + ) + set(LIBUSB_NAME usb-1.0) + find_library( + LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} + HINTS /usr/local + ) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) + mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) + if (NOT LIBUSB_FOUND) + message(FATAL_ERROR "No libusb-1.0 library found on your system! Install libusb-1.0 from ports or packages.") + endif () + elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-toolchain on Debian # MinGW/MSYS/MSVC: 64-bit or 32-bit? if (CMAKE_SIZEOF_VOID_P EQUAL 8) From 8dfebbe5898f4245b044c72330d3f2e2adf5177a Mon Sep 17 00:00:00 2001 From: Jan Bramkamp Date: Wed, 24 Nov 2021 01:48:12 +0100 Subject: [PATCH 1261/1435] Define the MINIMUM_API_LEVEL for OpenBSD Every platform has to declare the minimum libusb API level required by libstlink on it. --- src/stlink-lib/libusb_settings.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/stlink-lib/libusb_settings.h b/src/stlink-lib/libusb_settings.h index fea28237b..a2dfc6d26 100644 --- a/src/stlink-lib/libusb_settings.h +++ b/src/stlink-lib/libusb_settings.h @@ -31,6 +31,8 @@ #if defined (__FreeBSD__) #define MINIMAL_API_VERSION 0x01000102 // v1.0.16 +#elif defined (__OpenBSD__) + #define MINIMAL_API_VERSION 0x01000104 // v1.0.20 #elif defined (__linux__) #define MINIMAL_API_VERSION 0x01000104 // v1.0.20 #elif defined (__APPLE__) From 60edcf811b89f9eef9aac431095582f9b8fa6be4 Mon Sep 17 00:00:00 2001 From: Crest da Zoltral Date: Thu, 23 Dec 2021 20:27:38 +0100 Subject: [PATCH 1262/1435] Include SSIZE_MAX from limits.h The existing includes don't pull in limits.h on FreeBSD breaking the build on FreeBSD. --- src/common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common.c b/src/common.c index c40f6aa79..bdd6f5bab 100644 --- a/src/common.c +++ b/src/common.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include From 2b106912c9b06e4c434f2c20b7897953e70dc5d3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 1 Jan 2022 20:24:59 +0100 Subject: [PATCH 1263/1435] Added user review to README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 0b124d21d..7f797a7d9 100644 --- a/README.md +++ b/README.md @@ -110,3 +110,9 @@ When there is no executable available for your platform or you need the latest ( - Please start new forks from the develop branch, as pull requests will go into this branch as well. Please also refer to our [Contribution Guidelines](CONTRIBUTING.md). + +## User Reviews + +*I hope it's not to out of topic, but I've been so frustrated with AVR related things on OpenBSD, the fact that stlink built out of the box without needing to touch anything was so relieving. Literally made my whole weekend better! +I take it's thanks to @Crest and also to the stlink-org team (@Nightwalker-87 and @xor-gate it seems) to have made a software that's not unfriendly to the "fringe" OSes. +Thank you <3"* - nbonfils, 11.12.2021 \ No newline at end of file From 0d02a46a8f013d4f4d6ce9f163a0625710ff27c2 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 2 Jan 2022 22:51:30 +0100 Subject: [PATCH 1264/1435] [refactoring] Clean-up for chipid files - Spelling fix in tutorial.md - REN param description --> dev_type - ADD param ref_manual_id - CHNG stlink_chipid_params - MV old chipids to chipid_db_old.h - Updated chipid files (F1, F2, WB, WLE) --- config/chips/F1_Low_density_device.chip | 13 - config/chips/F1xx_CL.chip | 14 +- config/chips/F1xx_HD.chip | 14 + config/chips/F1xx_High_density.chip | 13 - .../chips/F1xx_High_density_value_line.chip | 13 - config/chips/F1xx_LD.chip | 14 + config/chips/F1xx_MD.chip | 14 + config/chips/F1xx_Medium_density.chip | 13 - config/chips/F1xx_VL_HD.chip | 14 + config/chips/F1xx_VL_MD_LD.chip | 14 + config/chips/F1xx_Value_Line.chip | 13 - config/chips/F1xx_XLD.chip | 14 + config/chips/F1xx_XL_density.chip | 13 - config/chips/F2xx.chip | 15 +- config/chips/WB5x_3x.chip | 13 - config/chips/WBx5_WBx0.chip | 14 + config/chips/WLEx.chip | 13 +- config/chips/unknown_device.chip | 9 +- doc/tutorial.md | 2 +- src/common.c | 2 +- src/st-info/info.c | 4 +- src/st-trace/trace.c | 2 +- src/stlink-gui/gui.c | 2 +- src/stlink-lib/chipid.c | 936 +----------------- src/stlink-lib/chipid.h | 4 +- src/stlink-lib/chipid_db_old.h | 879 ++++++++++++++++ 26 files changed, 1037 insertions(+), 1034 deletions(-) delete mode 100644 config/chips/F1_Low_density_device.chip create mode 100644 config/chips/F1xx_HD.chip delete mode 100644 config/chips/F1xx_High_density.chip delete mode 100644 config/chips/F1xx_High_density_value_line.chip create mode 100644 config/chips/F1xx_LD.chip create mode 100644 config/chips/F1xx_MD.chip delete mode 100644 config/chips/F1xx_Medium_density.chip create mode 100644 config/chips/F1xx_VL_HD.chip create mode 100644 config/chips/F1xx_VL_MD_LD.chip delete mode 100644 config/chips/F1xx_Value_Line.chip create mode 100644 config/chips/F1xx_XLD.chip delete mode 100644 config/chips/F1xx_XL_density.chip delete mode 100644 config/chips/WB5x_3x.chip create mode 100644 config/chips/WBx5_WBx0.chip create mode 100644 src/stlink-lib/chipid_db_old.h diff --git a/config/chips/F1_Low_density_device.chip b/config/chips/F1_Low_density_device.chip deleted file mode 100644 index 33fa03e1b..000000000 --- a/config/chips/F1_Low_density_device.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for F1 Low-density device -# -chip_id 0x412 -description F1 Low-density device -flash_type 1 -flash_pagesize 0x400 -sram_size 0x2800 -bootrom_base 0x1ffff000 -bootrom_size 0x800 -option_base 0x1ffff800 -option_size 0x10 -flags swo - diff --git a/config/chips/F1xx_CL.chip b/config/chips/F1xx_CL.chip index c2a3b2e69..6282bc2ee 100644 --- a/config/chips/F1xx_CL.chip +++ b/config/chips/F1xx_CL.chip @@ -1,13 +1,15 @@ -# Chip-ID file for F1xx CL +# Chip-ID file for STM32F1xx CL device # -chip_id 0x418 -description F1xx CL -flash_type 1 +dev_type STM32F1xx Connectivity Line device +ref_manual_id 0008 +chip_id 0x418 // STLINK_CHIPID_STM32_F1_CONN +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 sram_size 0x10000 bootrom_base 0x1fffb000 bootrom_size 0x4800 -option_base 0x1ffff800 -option_size 0x10 +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 flags swo diff --git a/config/chips/F1xx_HD.chip b/config/chips/F1xx_HD.chip new file mode 100644 index 000000000..72ad9fa75 --- /dev/null +++ b/config/chips/F1xx_HD.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32F1xx high density device +# +dev_type F1xx high density device +ref_manual_id 0008 +chip_id 0x414 // STLINK_CHIPID_STM32_F1_HD +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7e0 +flash_pagesize 0x800 +sram_size 0x10000 +bootrom_base 0x1ffff000 +bootrom_size 0x800 +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 +flags swo diff --git a/config/chips/F1xx_High_density.chip b/config/chips/F1xx_High_density.chip deleted file mode 100644 index 1deb5f01b..000000000 --- a/config/chips/F1xx_High_density.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for F1xx High-density -# -chip_id 0x414 -description F1xx High-density -flash_type 1 -flash_pagesize 0x800 -sram_size 0x10000 -bootrom_base 0x1ffff000 -bootrom_size 0x800 -option_base 0x1ffff800 -option_size 0x10 -flags swo - diff --git a/config/chips/F1xx_High_density_value_line.chip b/config/chips/F1xx_High_density_value_line.chip deleted file mode 100644 index 9e467c9d7..000000000 --- a/config/chips/F1xx_High_density_value_line.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for F1xx High-density value line -# -chip_id 0x428 -description F1xx High-density value line -flash_type 1 -flash_pagesize 0x800 -sram_size 0x8000 -bootrom_base 0x1ffff000 -bootrom_size 0x800 -option_base 0x1ffff800 -option_size 0x10 -flags swo - diff --git a/config/chips/F1xx_LD.chip b/config/chips/F1xx_LD.chip new file mode 100644 index 000000000..8a3682755 --- /dev/null +++ b/config/chips/F1xx_LD.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32F1 low density device +# +dev_type STM32F1xx low density device +ref_manual_id 0008 +chip_id 0x412 // STLINK_CHIPID_STM32_F1_LD +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7e0 +flash_pagesize 0x400 +sram_size 0x2800 +bootrom_base 0x1ffff000 +bootrom_size 0x800 +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 +flags swo diff --git a/config/chips/F1xx_MD.chip b/config/chips/F1xx_MD.chip new file mode 100644 index 000000000..f3da99493 --- /dev/null +++ b/config/chips/F1xx_MD.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32F1xx medium density device +# +dev_type STM32F1xx medium density device +ref_manual_id 0008 +chip_id 0x410 // STLINK_CHIPID_STM32_F1_MD +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7e0 +flash_pagesize 0x400 +sram_size 0x5000 +bootrom_base 0x1ffff000 // Section 2.3.3 "Embedded Flash memory" +bootrom_size 0x800 +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 +flags swo diff --git a/config/chips/F1xx_Medium_density.chip b/config/chips/F1xx_Medium_density.chip deleted file mode 100644 index a6d81d6f6..000000000 --- a/config/chips/F1xx_Medium_density.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for F1xx Medium-density -# -chip_id 0x410 -description F1xx Medium-density -flash_type 1 -flash_pagesize 0x400 -sram_size 0x5000 -bootrom_base 0x1ffff000 -bootrom_size 0x800 -option_base 0x1ffff800 -option_size 0x10 -flags swo - diff --git a/config/chips/F1xx_VL_HD.chip b/config/chips/F1xx_VL_HD.chip new file mode 100644 index 000000000..f46945a94 --- /dev/null +++ b/config/chips/F1xx_VL_HD.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32F1xx high density Value Line device +# +dev_type STM32F1xx Value Line high density device +ref_manual_id 0041 +chip_id 0x428 // STLINK_CHIPID_STM32_F1_VL_HD +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7e0 +flash_pagesize 0x800 +sram_size 0x8000 +bootrom_base 0x1ffff000 +bootrom_size 0x800 +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 +flags swo diff --git a/config/chips/F1xx_VL_MD_LD.chip b/config/chips/F1xx_VL_MD_LD.chip new file mode 100644 index 000000000..2bff05b82 --- /dev/null +++ b/config/chips/F1xx_VL_MD_LD.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STMF1xx Value Line medium & low density device +# +dev_type STM32F1xx Value Line medium & low density device +ref_manual_id 0041 +chip_id 0x420 // STLINK_CHIPID_STM32_F1_VL_MD_LD +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7e0 +flash_pagesize 0x400 +sram_size 0x2000 // 0x1000 for low density devices +bootrom_base 0x1ffff000 +bootrom_size 0x800 +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 +flags swo diff --git a/config/chips/F1xx_Value_Line.chip b/config/chips/F1xx_Value_Line.chip deleted file mode 100644 index 463cc2d9c..000000000 --- a/config/chips/F1xx_Value_Line.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for F1xx Value Line -# -chip_id 0x420 -description F1xx Value Line -flash_type 1 -flash_pagesize 0x400 -sram_size 0x2000 -bootrom_base 0x1ffff000 -bootrom_size 0x800 -option_base 0x1ffff800 -option_size 0x10 -flags swo - diff --git a/config/chips/F1xx_XLD.chip b/config/chips/F1xx_XLD.chip new file mode 100644 index 000000000..90264ce0f --- /dev/null +++ b/config/chips/F1xx_XLD.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32F1xx XL density device +# +dev_type STM32F1xx XL density device +ref_manual_id 0008 +chip_id 0x430 // STLINK_CHIPID_STM32_F1_XLD +flash_type 2 // STLINK_FLASH_TYPE_F1_XL +flash_size_reg 0x1ffff7e0 +flash_pagesize 0x800 +sram_size 0x18000 +bootrom_base 0x1fffe000 +bootrom_size 0x1800 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F1xx_XL_density.chip b/config/chips/F1xx_XL_density.chip deleted file mode 100644 index 318efbff0..000000000 --- a/config/chips/F1xx_XL_density.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for F1xx XL-density -# -chip_id 0x430 -description F1xx XL-density -flash_type 2 -flash_pagesize 0x800 -sram_size 0x18000 -bootrom_base 0x1fffe000 -bootrom_size 0x1800 -option_base 0x0 -option_size 0x0 -flags swo - diff --git a/config/chips/F2xx.chip b/config/chips/F2xx.chip index 30808f1aa..ce2e9e698 100644 --- a/config/chips/F2xx.chip +++ b/config/chips/F2xx.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F2xx +# Chip-ID file for STM32F2xx device (STM32F205xx, STM32F207xx, STM32F215xx, STM32F217xx) # -chip_id 0x411 -description F2xx -flash_type 3 +dev_type STM32F2xx device +ref_manual_id 0033 +chip_id 0x411 // STLINK_CHIPID_STM32_F2 +flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_size_reg 0x1fff7a22 flash_pagesize 0x20000 sram_size 0x20000 bootrom_base 0x1fff0000 bootrom_size 0x7800 -option_base 0x1fffc000 -option_size 0x4 +option_base 0x1fffc000 // STM32_F2_OPTION_BYTES_BASE +option_size 0x4 // 4 flags swo - diff --git a/config/chips/WB5x_3x.chip b/config/chips/WB5x_3x.chip deleted file mode 100644 index 0627bdeec..000000000 --- a/config/chips/WB5x_3x.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for WB5x/3x -# -chip_id 0x495 -description WB5x/3x -flash_type 9 -flash_pagesize 0x1000 -sram_size 0x40000 -bootrom_base 0x1fff0000 -bootrom_size 0x7000 -option_base 0x0 -option_size 0x0 -flags swo - diff --git a/config/chips/WBx5_WBx0.chip b/config/chips/WBx5_WBx0.chip new file mode 100644 index 000000000..5bd2501e6 --- /dev/null +++ b/config/chips/WBx5_WBx0.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32WBx0 device (STM32WB55xx, STM32WB35xx, STM32WB50CG, STM32WB30CE) +# +dev_type STM32WBx0 device +ref_manual_id 0434 // also RM0471 +chip_id 0x495 // STLINK_CHIPID_STM32_WB55 +flash_type 9 // STLINK_FLASH_TYPE_WB +flash_size_reg 0x1fff75e0 +flash_pagesize 0x1000 // 4k +sram_size 0x40000 +bootrom_base 0x1fff0000 +bootrom_size 0x7000 +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/WLEx.chip b/config/chips/WLEx.chip index 19d0678e5..e9b6248f6 100644 --- a/config/chips/WLEx.chip +++ b/config/chips/WLEx.chip @@ -1,13 +1,14 @@ -# Chip-ID file for WLEx +# Chip-ID file for STM32WLEx device # -chip_id 0x497 -description WLEx -flash_type 9 -flash_pagesize 0x800 +dev_type STM32WLEx device +ref_manual_id 0033 +chip_id 0x497 // STLINK_CHIPID_STM32_WLE +flash_type 9 // STLINK_FLASH_TYPE_WB +flash_size_reg 0x1fff75e0 +flash_pagesize 0x800 // 2k sram_size 0x10000 bootrom_base 0x1fff0000 bootrom_size 0x7000 option_base 0x0 option_size 0x0 flags swo - diff --git a/config/chips/unknown_device.chip b/config/chips/unknown_device.chip index c71206951..8f3772e53 100644 --- a/config/chips/unknown_device.chip +++ b/config/chips/unknown_device.chip @@ -1,8 +1,10 @@ # Chip-ID file for unknown device # -chip_id 0x0 -description unknown device -flash_type 0 +dev_type unknown device +ref_manual_id 0000 +chip_id 0x0 // STLINK_CHIPID_UNKNOWN +flash_type 0 // STLINK_FLASH_TYPE_UNKNOWN +flash_size_reg 0x0 flash_pagesize 0x0 sram_size 0x0 bootrom_base 0x0 @@ -10,4 +12,3 @@ bootrom_size 0x0 option_base 0x0 option_size 0x0 flags none - diff --git a/doc/tutorial.md b/doc/tutorial.md index 7e0b3901b..9ca6bef5b 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -81,7 +81,7 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", \ and the `idVendor` of `0483` and `idProduct` of `374b` matches the vendor id from the `lsusb` output. -Make sure that you have all 3 files from here: https://github.com/stlink-org/stlink/tree/master/etc/udev/rules.d in your `/etc/udev/rules.d` directory. After copying new files or editing excisting files in `/etc/udev/ruled.d` you should run the following: +Make sure that you have all 3 files from here: https://github.com/stlink-org/stlink/tree/master/etc/udev/rules.d in your `/etc/udev/rules.d` directory. After copying new files or editing existing files in `/etc/udev/ruled.d` you should run the following: ``` sudo udevadm control --reload-rules diff --git a/src/common.c b/src/common.c index c40f6aa79..9bfbfc52b 100644 --- a/src/common.c +++ b/src/common.c @@ -1671,7 +1671,7 @@ int stlink_load_device_params(stlink_t *sl) { } ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", - params->description, (unsigned)(sl->sram_size / 1024), + params->dev_type, (unsigned)(sl->sram_size / 1024), (unsigned)(sl->flash_size / 1024), (sl->flash_pgsz < 1024) ? (unsigned)(sl->flash_pgsz) : (unsigned)(sl->flash_pgsz / 1024), diff --git a/src/st-info/info.c b/src/st-info/info.c index ceb406cda..416d27f56 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -42,7 +42,7 @@ static void stlink_print_info(stlink_t *sl) { printf(" chipid: 0x%.4x\n", sl->chip_id); params = stlink_chipid_get_params(sl->chip_id); - if (params) { printf(" descr: %s\n", params->description); } + if (params) { printf(" dev-type: %s\n", params->dev_type); } } static void stlink_probe(enum connect_type connect, int freq) { @@ -118,7 +118,7 @@ static int print_data(int ac, char **av) { const struct stlink_chipid_params *params = stlink_chipid_get_params(sl->chip_id); if (params == NULL) { return(-1); } - printf("%s\n", params->description); + printf("%s\n", params->dev_type); } if (sl) { diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 754a55c72..46304d7d9 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -555,7 +555,7 @@ int main(int argc, char **argv) { if (!(stlink->chip_flags & CHIP_F_HAS_SWO_TRACING)) { const struct stlink_chipid_params *params = stlink_chipid_get_params(stlink->chip_id); - ELOG("We do not support SWO output for device '%s'\n", params->description); + ELOG("We do not support SWO output for device '%s'\n", params->dev_type); if (!settings.force) return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; } diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index f9de46f37..387d3ac68 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -429,7 +429,7 @@ static gchar *dev_format_chip_id(guint32 chip_id) { if (!params) { return(g_strdup_printf("0x%x", chip_id)); } - return(g_strdup(params->description)); + return(g_strdup(params->dev_type)); } static gchar *dev_format_mem_size(gsize flash_size) { diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index d51a0edcb..a991e0921 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1,5 +1,6 @@ #include #include "chipid.h" +#include "chipid_db_old.h" #include #include @@ -7,884 +8,6 @@ #include #include -// This is the old chipid "database". -// It is kept here for now to be able to compare the -// result between the "old code" and the "new code". -// For now if you need to change something, please -// change it both here and in the corresponding -// config/chips/*.chip file. - -static struct stlink_chipid_params devices[] = { - { - // STM32F76x/F77x - // RM0410 - .chip_id = STLINK_CHIPID_STM32_F76xxx, - .description = "F76x/F77x", - .flash_type = STLINK_FLASH_TYPE_F7, - .flash_size_reg = 0x1ff0f442, // section 45.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x80000, // "SRAM" byte size in hex from - .bootrom_base = 0x00200000, // "System memory" starting address from - .bootrom_size = 0xEDC0, - .option_base = STM32_F7_OPTION_BYTES_BASE, /* Used for reading back the option - bytes, writing uses FLASH_F7_OPTCR - and FLASH_F7_OPTCR1 */ - .option_size = 0x20, - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F74x/F75x - // RM0385, DS10916 - .chip_id = STLINK_CHIPID_STM32_F7, - .description = "F74x/F75x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff0f442, // section 41.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 - .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 18 - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F72x/F73x - // RM0431 - .chip_id = STLINK_CHIPID_STM32_F72xxx, - .description = "F72x/F73x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff07a22, // section 35.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 - .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 24 - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F1xx medium-density devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_MD, - .description = "F1xx Medium-density", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x5000, - .bootrom_base = 0x1ffff000, // 2.3.3 "Embedded Flash memory" - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F205xx, STM32F207xx, STM32F215xx, STM32F217xx - // RM0033 (rev 5) - .chip_id = STLINK_CHIPID_STM32_F2, - .description = "F2xx", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, - .flash_pagesize = 0x20000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .option_base = 0x1FFFC000, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F1xx low-density devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_LD, - .description = "F1 Low-density device", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2800, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F4x5/F4x7 - // RM0090 (rev 2) - .chip_id = STLINK_CHIPID_STM32_F4, - .description = "F4x5/F4x7", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x30000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .option_base = STM32_F4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F46x/F47x - // RM0090 (rev 2) - .chip_id = STLINK_CHIPID_STM32_F4_DSI, - .description = "F46x/F47x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x40000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F42x/F43x - // RM0090 (rev 2) - .chip_id = STLINK_CHIPID_STM32_F4_HD, - .description = "F42x/F43x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x40000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - .chip_id = STLINK_CHIPID_STM32_F4_LP, - .description = "F401xB/C", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x10000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - .chip_id = STLINK_CHIPID_STM32_F411xx, - .description = "F411xC/E", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - .chip_id = STLINK_CHIPID_STM32_F4_DE, - .description = "F401xD/E", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F1xx high-density devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_HD, - .description = "F1xx High-density", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L100/L15x/L16x Cat.1 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L1_MD, - .description = "L1xx Cat.1", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8004c, - .flash_pagesize = 0x100, - .sram_size = 0x4000, // up to 16k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L100/L15x/L16x Cat.2 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L1_CAT2, - .description = "L1xx Cat.2", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8004c, - .flash_pagesize = 0x100, - .sram_size = 0x8000, // up to 32k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L100/L15x/L16x Cat.3 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L1_MD_PLUS, - .description = "L1xx Cat.3", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x8000, // up to 32k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L100/L15x/L16x Cat.4 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L1_MD_PLUS_HD, - .description = "L1xx Cat.4", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0xC000, // up to 48k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .option_base = STM32_L1_OPTION_BYTES_BASE, - .option_size = 8, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L100/L15x/L16x Cat.5 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L152_RE, - .description = "L1xx Cat.5", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x14000, // up to 80k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F1xx connectivity devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_CONN, - .description = "F1xx CL", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1fffb000, - .bootrom_size = 0x4800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F1xx low- and medium-density value line devices - // RM0041 - .chip_id = STLINK_CHIPID_STM32_F1_VL_MD_LD, - .description = "F1xx Value Line", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2000, // 0x1000 for low density devices - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F446x family - // RM0390 - .chip_id = STLINK_CHIPID_STM32_F446, - .description = "F446", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, - .flash_pagesize = 0x20000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .option_base = 0x1FFFC000, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F410 - // RM0401 - .chip_id = STLINK_CHIPID_STM32_F410, - .description = "F410", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, - .flash_pagesize = 0x4000, - .sram_size = 0x8000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F303xB/C, STM32F358, STM32F302xBxC - // RM0316, RM0365 - .chip_id = STLINK_CHIPID_STM32_F3, - .description = "F302/F303/F358", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F373Cx/Rx/Vx, STM32F378Cx/Rx/Vx - // RM0313 - .chip_id = STLINK_CHIPID_STM32_F37x, - .description = "F37x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F1xx high-density value line devices - // RM0041 - .chip_id = STLINK_CHIPID_STM32_F1_VL_HD, - .description = "F1xx High-density value line", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x8000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F1xx XL-density devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_XLD, - .description = "F1xx XL-density", - .flash_type = STLINK_FLASH_TYPE_F1_XL, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x18000, - .bootrom_base = 0x1fffe000, - .bootrom_size = 0x1800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F07x - // RM0091 - .chip_id = STLINK_CHIPID_STM32_F0_CAN, - .description = "F07x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 - .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 - .bootrom_size = 0x3000, // "System memory" byte size in hex from Table 2 - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - }, - { - // STM32F05x - // RM0091 - .chip_id = STLINK_CHIPID_STM32_F0, - .description = "F05x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - }, - { - // STM32F412 - // RM0402 - .chip_id = STLINK_CHIPID_STM32_F412, - .description = "F412", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) - .flash_pagesize = 0x4000, // Table 5. Flash module organization ? - .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 - .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F413/F423 - // RM0430 (rev 2) - .chip_id = STLINK_CHIPID_STM32_F413, - .description = "F413/F423", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 - .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector - // sizes, but 0x4000 is smallest) - .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 - // only says 0x40000) - .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F09x - // RM0091 - .chip_id = STLINK_CHIPID_STM32_F09x, - .description = "F09x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) - .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) - .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 - .bootrom_size = 0x2000, // "System memory" byte size in hex from Table 2 - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - }, - { - // STM32F04x - // RM0091 - .chip_id = STLINK_CHIPID_STM32_F04, - .description = "F04x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - }, - { - // STM32F03x - // RM0091 - .chip_id = STLINK_CHIPID_STM32_F0xx_SMALL, - .description = "F03x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - }, - { - // STM32F301x6/8, STM32F302x6x8, STM32F318x8 - // RM0366, RM0365 - .chip_id = STLINK_CHIPID_STM32_F3xx_SMALL, - .description = "F301/F302/F318", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1fffd800, - .bootrom_size = 0x2000, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L0xx Category 3 - // RM0367, RM0377, RM0451 - .chip_id = STLINK_CHIPID_STM32_L0, - .description = "L0xx Cat.3", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000, - .option_base = STM32_L0_OPTION_BYTES_BASE, - .option_size = 20, - }, - { - // STM32L0x Category 5 - // RM0367, RM0377, RM0451 - .chip_id = STLINK_CHIPID_STM32_L0_CAT5, - .description = "L0xx Cat.5", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x5000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x2000, - .option_base = STM32_L0_OPTION_BYTES_BASE, - .option_size = 20, - .flags = CHIP_F_HAS_DUAL_BANK, - }, - { - // STM32L0x Category 2 - // RM0367, RM0377 - .chip_id = STLINK_CHIPID_STM32_L0_CAT2, - .description = "L0xx Cat.2", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000, - .option_base = STM32_L0_OPTION_BYTES_BASE, - .option_size = 20, - }, - { - // STM32F334, STM32F303x6/8, STM32F328 - // RM0364, RM0316 - .chip_id = STLINK_CHIPID_STM32_F334, - .description = "F303/F328/F334", // (RM0316 sec 33.6.1) - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0x3000, - .bootrom_base = 0x1fffd800, - .bootrom_size = 0x2000, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F303xD/E, STM32F398xE, STM32F302xD/E - // RM0316 (rev 5), RM0365 - .chip_id = STLINK_CHIPID_STM32_F303_HD, - .description = "F303 high density", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register - .flash_pagesize = 0x800, // 4.2.1 Flash memory organization - .sram_size = 0x10000, // 3.3 Embedded SRAM - .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory - .bootrom_size = 0x2000, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L47x/L48x - // RM0351 - .chip_id = STLINK_CHIPID_STM32_L4, - .description = "L47x/L48x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 - // and tables 4-6 on pages 79-81) - // SRAM1 is "up to" 96k in the standard Cortex-M memory map; - // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) - .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L4RX - // RM0432 - .chip_id = STLINK_CHIPID_STM32_L4Rx, - .description = "L4Rx", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) - .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 - // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size - .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 - .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 - .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L4PX - // RM0432 - .chip_id = STLINK_CHIPID_STM32_L4PX, - .description = "L4Px", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) - .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 - // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size - .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 - .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 - .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STLINK_CHIPID_STM32_L41x_L42x - // RM0394 (rev 4), DS12469 (rev 5) - .chip_id = STLINK_CHIPID_STM32_L41x_L42x, - .description = "L41x/L42x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, - // sec 47.2, page 1586) - .flash_pagesize = 0x800, // 2k (DS12469, sec 3.4, page 17) - // SRAM1 is 32k at 0x20000000 - // SRAM2 is 8k at 0x10000000 and 0x20008000 - // (DS12469, sec 3.5, page 18) - .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) - .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) - .bootrom_size = 0x7000, // 28k, same source as base - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STLINK_CHIPID_STM32_L43x_L44x - // RM0392 - .chip_id = STLINK_CHIPID_STM32_L43x_L44x, - .description = "L43x/L44x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 - // and tables 7-8 on pages 75-76) - // SRAM1 is "up to" 64k in the standard Cortex-M memory map; - // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) - .sram_size = 0xc000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STLINK_CHIPID_STM32_L496x_L4A6x - // RM0351 (rev 5) - .chip_id = STLINK_CHIPID_STM32_L496x_L4A6x, - .description = "L496x/L4A6x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) - .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) - // SRAM1 is 256k at 0x20000000 - // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) - .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) - .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STLINK_CHIPID_STM32_L45x_L46x - // RM0394 (updated version of RM0392?) - .chip_id = STLINK_CHIPID_STM32_L45x_L46x, - .description = "L45x/46x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 - // and tables 7 on pages 73-74) - // SRAM1 is 128k at 0x20000000; - // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, - // page 68, also fig 2 on page 63) - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system - // memory, also fig 2 on page 63) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L0xx Category 1 - // RM0451, RM0377 - .chip_id = STLINK_CHIPID_STM32_L011, - .description = "L01x/L02x", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x2000, - }, - { - // STM32G030/031/041 - // RM0454, RM0444 - .chip_id = STLINK_CHIPID_STM32_G0_CAT1, - .description = "G03x/G04x", - .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x2000, // 8k (sec 2.3) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 3) - .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32G071/081 - // RM0444 - .chip_id = STLINK_CHIPID_STM32_G0_CAT2, - .description = "G07x/G08x", - .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x9000, // 36k (sec 2.3) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) - .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32G0B1/G0C1 - // RM0444 - .chip_id = STLINK_CHIPID_STM32_G0_CAT3, - .description = "G0Bx/G0Cx", - .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x9000, // 36k (sec 2.3) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) - .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_DUAL_BANK, - }, - { - // STM32G051/G061 - // RM0444 - .chip_id = STLINK_CHIPID_STM32_G0_CAT4, - .description = "G05x/G06x", - .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x9000, // 36k (sec 2.3) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) - .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32G431/441 - // RM0440 - .chip_id = STLINK_CHIPID_STM32_G4_CAT2, - .description = "G43x/G44x", - .flash_type = STLINK_FLASH_TYPE_G4, - .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = 0x800, // 2k (sec 3.3.1) - // SRAM1 is 16k at 0x20000000 - // SRAM2 is 6k at 0x20014000 - // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x8000, // 32k (sec 2.4) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (table 2) - .option_base = STM32_G4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32G471/473/474/483/484 - // RM0440 - .chip_id = STLINK_CHIPID_STM32_G4_CAT3, - .description = "G47x/G48x", - .flash_type = STLINK_FLASH_TYPE_G4, - .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = 0x800, // 2k (sec 3.3.1) - // SRAM1 is 80k at 0x20000000 - // SRAM2 is 16k at 0x20014000 - // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x20000, // 128k (sec 2.4) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (table 2) - .option_base = STM32_G4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32G491/G4A1 - // RM0440 - .chip_id = STLINK_CHIPID_STM32_G4_CAT4, - .description = "G49x/G4Ax", - .flash_type = STLINK_FLASH_TYPE_G4, - .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = 0x800, // 2k (sec 3.3.1) - // SRAM1 is 80k at 0x20000000 - // SRAM2 is 16k at 0x20014000 - // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x1C000, // 112k (sec 2.4) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (table 2) - .option_base = STM32_G4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32WB55xx, STM32WB35xx, STM32WB50CG/30CE - // RM0434, RM0471 - .chip_id = STLINK_CHIPID_STM32_WB55, - .description = "WB5x/3x", - .flash_type = STLINK_FLASH_TYPE_WB, - .flash_size_reg = 0x1FFF75E0, - .flash_pagesize = 0x1000, // 4k - .sram_size = 0x40000, - .bootrom_base = 0x1fff0000, // see the memory map - .bootrom_size = 0x7000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32WLEx - .chip_id = STLINK_CHIPID_STM32_WLE, - .description = "WLEx", - .flash_type = STLINK_FLASH_TYPE_WB, - .flash_size_reg = 0x1FFF75E0, - .flash_pagesize = 0x800, // 2k - .sram_size = 0x10000, - .bootrom_base = 0x1fff0000, // see the memory map - .bootrom_size = 0x7000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32H742/743/753 (from RM0433) - .chip_id = STLINK_CHIPID_STM32_H74xxx, - .description = "H74x/H75x", - .flash_type = STLINK_FLASH_TYPE_H7, - .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) - .flash_pagesize = 0x20000, // 128k sector (pg147) - .sram_size = 0x20000, // 128k "DTCM" from Table 7 - .bootrom_base = 0x1ff00000, // "System memory" starting address from Table 7 - .bootrom_size = 0x20000, // "System memory" byte size in hex from Table 7 - .option_base = STM32_H7_OPTION_BYTES_BASE, - .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32H7A3/7B3 - // RM0455 - .chip_id = STLINK_CHIPID_STM32_H7Ax, - .description = "H7Ax/H7Bx", - .flash_type = STLINK_FLASH_TYPE_H7, - .flash_size_reg = 0x08FFF80C, // "Flash size register" (p.2949) - .flash_pagesize = 0x2000, // 8k sector (p.146) - .sram_size = 0x20000, // 128k "DTCM" (Figure 1) - .bootrom_base = 0x1FF00000, // "System memory" starting address (Table 12-14) - .bootrom_size = 0x20000, // "System memory" byte size in hex splitted to - // two banks (Table 12-14) - .option_base = STM32_H7_OPTION_BYTES_BASE, - .option_size = 44, - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32H72x/H73x - // RM0468 - .chip_id = STLINK_CHIPID_STM32_H72x, - .description = "H72x/H73x", - .flash_type = STLINK_FLASH_TYPE_H7, - .flash_size_reg = 0x1FF1E880, // "Flash size register" (p.3286) - .flash_pagesize = 0x20000, // 128k sector (p.152) - .sram_size = 0x20000, // 128k "DTCM" (Figure 1) - .bootrom_base = 0x1FF00000, // "System memory" starting address (Table 6) - .bootrom_size = 0x20000, // "System memory" byte size in hex (Table 6) - .option_base = STM32_H7_OPTION_BYTES_BASE, - .option_size = 44, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - - { - // unknown - .chip_id = STLINK_CHIPID_UNKNOWN, - .description = "unknown device", - .flash_type = STLINK_FLASH_TYPE_UNKNOWN, - .flash_size_reg = 0x0, - .flash_pagesize = 0x0, - .sram_size = 0x0, - .bootrom_base = 0x0, - .bootrom_size = 0x0, - }, -}; struct stlink_chipid_params *stlink_chipid_get_params_old(uint32_t chipid) { struct stlink_chipid_params *params = NULL; @@ -901,11 +24,12 @@ struct stlink_chipid_params *stlink_chipid_get_params_old(uint32_t chipid) { static struct stlink_chipid_params *devicelist; void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { - fprintf(fp, "# Chip-ID file for %s\n", dev->description); + fprintf(fp, "# Device Type: %s\n", dev->dev_type); + fprintf(fp, "# Reference Manual: RM%s\n", dev->ref_manual_id); fprintf(fp, "#\n"); fprintf(fp, "chip_id 0x%x\n", dev->chip_id); - fprintf(fp, "description %s\n", dev->description); fprintf(fp, "flash_type %d\n", dev->flash_type); + fprintf(fp, "flash_size_reg %x\n", dev->flash_size_reg); fprintf(fp, "flash_pagesize 0x%x\n", dev->flash_pagesize); fprintf(fp, "sram_size 0x%x\n", dev->sram_size); fprintf(fp, "bootrom_base 0x%x\n", dev->bootrom_base); @@ -919,7 +43,6 @@ struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { struct stlink_chipid_params *params = NULL; struct stlink_chipid_params *p2; - //fprintf (stderr, "getparams: %x\n", chipid); for (params = devicelist; params != NULL; params = params->next) if (params->chip_id == chipid) { break; @@ -949,7 +72,7 @@ void process_chipfile(char *fname) { struct stlink_chipid_params *ts; int nc; - // fprintf (stderr, "processing chipfile %s.\n", fname); + // fprintf (stderr, "processing chip-id file %s.\n", fname); fp = fopen(fname, "r"); if (!fp) { @@ -963,28 +86,33 @@ void process_chipfile(char *fname) { for (p = buf; isspace (*p); p++); if (!*p) { - continue; // we hit end-of-line wiht only whitespace + continue; // we hit end-of-line with only whitespace } if (*p == '#') { - continue; // ignore comments. + continue; // ignore comments } sscanf(p, "%s %s", word, value); - if (strcmp(word, "chip_id") == 0) { - if (sscanf(value, "%i", &ts->chip_id) < 1) { - fprintf(stderr, "Failed to parse chip id\n"); - } - } else if (strcmp (word, "description") == 0) { - // ts->description = strdup (value); + if (strcmp (word, "dev_type") == 0) { + // ts->dev_type = strdup (value); buf[strlen(p) - 1] = 0; // chomp newline sscanf(p, "%*s %n", &nc); - ts->description = strdup(p + nc); + ts->dev_type = strdup(p + nc); + } else if (strcmp (word, "ref_manual_id") == 0) { + // ts->ref_manual_id = strdup (value); + buf[strlen(p) - 1] = 0; // chomp newline + sscanf(p, "%*s %n", &nc); + ts->ref_manual_id = strdup(p + nc); + } else if (strcmp(word, "chip_id") == 0) { + if (sscanf(value, "%i", &ts->chip_id) < 1) { + fprintf(stderr, "Failed to parse chip-id\n"); + } } else if (strcmp (word, "flash_type") == 0) { if (sscanf(value, "%i", (int *)&ts->flash_type) < 1) { fprintf(stderr, "Failed to parse flash type\n"); - } else if (ts->flash_type <= STLINK_FLASH_TYPE_UNKNOWN || ts->flash_type >= STLINK_FLASH_TYPE_MAX) { + } else if ((ts->flash_type < STLINK_FLASH_TYPE_UNKNOWN) || (ts->flash_type >= STLINK_FLASH_TYPE_MAX)) { fprintf(stderr, "Unrecognized flash type\n"); } } else if (strcmp (word, "flash_size_reg") == 0) { @@ -1050,18 +178,19 @@ void dump_chips (void) { for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) { ts = &devices[n]; - strcpy(buf, ts->description); + strcpy(buf, ts->dev_type); while ((p = strchr(buf, '/'))) // change slashes to underscore. *p = '_'; strcat(buf, ".chip"); fp = fopen(buf, "w"); - fprintf(fp, "# Chip-ID file for %s\n", ts->description); + fprintf(fp, "# Device Type: %s\n", ts->dev_type); + fprintf(fp, "# Reference Manual: RM%s\n", ts->ref_manual_id); fprintf(fp, "#\n"); fprintf(fp, "chip_id %x\n", ts->chip_id); - fprintf(fp, "description %s\n", ts->description); fprintf(fp, "flash_type %x\n", ts->flash_type); + fprintf(fp, "flash_size_reg %x\n", ts->flash_size_reg); fprintf(fp, "flash_pagesize %x\n", ts->flash_pagesize); fprintf(fp, "sram_size %x\n", ts->sram_size); fprintf(fp, "bootrom_base %x\n", ts->bootrom_base); @@ -1104,23 +233,6 @@ void init_chipids(char *dir_to_scan) { perror (dir_to_scan); return; // XXX } - -#if 0 - { - struct stlink_chipid_params *p, *op; - int i; - p = devicelist; - - for (i = 0; i < 5; i++, p = p->next) { - op = stlink_chipid_get_params_old (p->chip_id); - fprintf (stderr, "---------- old ------------\n"); - dump_a_chip (stderr, op); - fprintf (stderr, "---------- new ------------\n"); - dump_a_chip (stderr, p); - - } - } -#endif } #endif //STLINK_HAVE_DIRENT_H diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index 20cfcf52d..426c22428 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -79,8 +79,9 @@ enum stlink_stm32_chipids { /** Chipid parameters */ struct stlink_chipid_params { + char *dev_type; + char *ref_manual_id; uint32_t chip_id; - char *description; enum stlink_flash_type flash_type; uint32_t flash_size_reg; uint32_t flash_pagesize; @@ -93,7 +94,6 @@ struct stlink_chipid_params { struct stlink_chipid_params * next; }; - struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); void init_chipids(char *dir_to_scan); diff --git a/src/stlink-lib/chipid_db_old.h b/src/stlink-lib/chipid_db_old.h new file mode 100644 index 000000000..bc6491ad4 --- /dev/null +++ b/src/stlink-lib/chipid_db_old.h @@ -0,0 +1,879 @@ +// This is the old chipid "database". +// It is kept here for now to be able to compare the +// result between the "old code" and the "new code". +// For now if you need to change something, please +// change it both here and in the corresponding +// config/chips/*.chip file. + +static struct stlink_chipid_params devices[] = { + { + // STM32F76x/F77x + // RM0410 + .chip_id = STLINK_CHIPID_STM32_F76xxx, + .dev_type = "F76x/F77x", + .flash_type = STLINK_FLASH_TYPE_F7, + .flash_size_reg = 0x1ff0f442, // section 45.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x80000, // "SRAM" byte size in hex from + .bootrom_base = 0x00200000, // "System memory" starting address from + .bootrom_size = 0xEDC0, + .option_base = STM32_F7_OPTION_BYTES_BASE, /* Used for reading back the option + bytes, writing uses FLASH_F7_OPTCR + and FLASH_F7_OPTCR1 */ + .option_size = 0x20, + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F74x/F75x + // RM0385, DS10916 + .chip_id = STLINK_CHIPID_STM32_F7, + .dev_type = "F74x/F75x", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1ff0f442, // section 41.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 + .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 + .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 18 + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F72x/F73x + // RM0431 + .chip_id = STLINK_CHIPID_STM32_F72xxx, + .dev_type = "F72x/F73x", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1ff07a22, // section 35.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 + .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 + .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 24 + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F4x5/F4x7 + // RM0090 (rev 2) + .chip_id = STLINK_CHIPID_STM32_F4, + .dev_type = "F4x5/F4x7", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x30000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .option_base = STM32_F4_OPTION_BYTES_BASE, + .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F46x/F47x + // RM0090 (rev 2) + .chip_id = STLINK_CHIPID_STM32_F4_DSI, + .dev_type = "F46x/F47x", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x40000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F42x/F43x + // RM0090 (rev 2) + .chip_id = STLINK_CHIPID_STM32_F4_HD, + .dev_type = "F42x/F43x", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x40000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + .chip_id = STLINK_CHIPID_STM32_F4_LP, + .dev_type = "F401xB/C", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x10000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + .chip_id = STLINK_CHIPID_STM32_F411xx, + .dev_type = "F411xC/E", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + .chip_id = STLINK_CHIPID_STM32_F4_DE, + .dev_type = "F401xD/E", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x18000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L100/L15x/L16x Cat.1 + // RM0038 + .chip_id = STLINK_CHIPID_STM32_L1_MD, + .dev_type = "L1xx Cat.1", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8004c, + .flash_pagesize = 0x100, + .sram_size = 0x4000, // up to 16k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L100/L15x/L16x Cat.2 + // RM0038 + .chip_id = STLINK_CHIPID_STM32_L1_CAT2, + .dev_type = "L1xx Cat.2", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8004c, + .flash_pagesize = 0x100, + .sram_size = 0x8000, // up to 32k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L100/L15x/L16x Cat.3 + // RM0038 + .chip_id = STLINK_CHIPID_STM32_L1_MD_PLUS, + .dev_type = "L1xx Cat.3", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0x8000, // up to 32k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L100/L15x/L16x Cat.4 + // RM0038 + .chip_id = STLINK_CHIPID_STM32_L1_MD_PLUS_HD, + .dev_type = "L1xx Cat.4", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0xC000, // up to 48k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000, + .option_base = STM32_L1_OPTION_BYTES_BASE, + .option_size = 8, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L100/L15x/L16x Cat.5 + // RM0038 + .chip_id = STLINK_CHIPID_STM32_L152_RE, + .dev_type = "L1xx Cat.5", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0x14000, // up to 80k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F446x family + // RM0390 + .chip_id = STLINK_CHIPID_STM32_F446, + .dev_type = "F446", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1fff7a22, + .flash_pagesize = 0x20000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .option_base = 0x1FFFC000, + .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F410 + // RM0401 + .chip_id = STLINK_CHIPID_STM32_F410, + .dev_type = "F410", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1fff7a22, + .flash_pagesize = 0x4000, + .sram_size = 0x8000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F303xB/C, STM32F358, STM32F302xBxC + // RM0316, RM0365 + .chip_id = STLINK_CHIPID_STM32_F3, + .dev_type = "F302/F303/F358", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F373Cx/Rx/Vx, STM32F378Cx/Rx/Vx + // RM0313 + .chip_id = STLINK_CHIPID_STM32_F37x, + .dev_type = "F37x", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F07x + // RM0091 + .chip_id = STLINK_CHIPID_STM32_F0_CAN, + .dev_type = "F07x", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 + .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 + .bootrom_size = 0x3000, // "System memory" byte size in hex from Table 2 + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + }, + { + // STM32F05x + // RM0091 + .chip_id = STLINK_CHIPID_STM32_F0, + .dev_type = "F05x", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + }, + { + // STM32F412 + // RM0402 + .chip_id = STLINK_CHIPID_STM32_F412, + .dev_type = "F412", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) + .flash_pagesize = 0x4000, // Table 5. Flash module organization ? + .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 + .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 + .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F413/F423 + // RM0430 (rev 2) + .chip_id = STLINK_CHIPID_STM32_F413, + .dev_type = "F413/F423", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 + .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector + // sizes, but 0x4000 is smallest) + .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 + // only says 0x40000) + .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 + .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F09x + // RM0091 + .chip_id = STLINK_CHIPID_STM32_F09x, + .dev_type = "F09x", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) + .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) + .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 + .bootrom_size = 0x2000, // "System memory" byte size in hex from Table 2 + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + }, + { + // STM32F04x + // RM0091 + .chip_id = STLINK_CHIPID_STM32_F04, + .dev_type = "F04x", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + }, + { + // STM32F03x + // RM0091 + .chip_id = STLINK_CHIPID_STM32_F0xx_SMALL, + .dev_type = "F03x", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + }, + { + // STM32F301x6/8, STM32F302x6x8, STM32F318x8 + // RM0366, RM0365 + .chip_id = STLINK_CHIPID_STM32_F3xx_SMALL, + .dev_type = "F301/F302/F318", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1fffd800, + .bootrom_size = 0x2000, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L0xx Category 3 + // RM0367, RM0377, RM0451 + .chip_id = STLINK_CHIPID_STM32_L0, + .dev_type = "L0xx Cat.3", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x2000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x1000, + .option_base = STM32_L0_OPTION_BYTES_BASE, + .option_size = 20, + }, + { + // STM32L0x Category 5 + // RM0367, RM0377, RM0451 + .chip_id = STLINK_CHIPID_STM32_L0_CAT5, + .dev_type = "L0xx Cat.5", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x5000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x2000, + .option_base = STM32_L0_OPTION_BYTES_BASE, + .option_size = 20, + .flags = CHIP_F_HAS_DUAL_BANK, + }, + { + // STM32L0x Category 2 + // RM0367, RM0377 + .chip_id = STLINK_CHIPID_STM32_L0_CAT2, + .dev_type = "L0xx Cat.2", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x2000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x1000, + .option_base = STM32_L0_OPTION_BYTES_BASE, + .option_size = 20, + }, + { + // STM32F334, STM32F303x6/8, STM32F328 + // RM0364, RM0316 + .chip_id = STLINK_CHIPID_STM32_F334, + .dev_type = "F303/F328/F334", // (RM0316 sec 33.6.1) + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0x3000, + .bootrom_base = 0x1fffd800, + .bootrom_size = 0x2000, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F303xD/E, STM32F398xE, STM32F302xD/E + // RM0316 (rev 5), RM0365 + .chip_id = STLINK_CHIPID_STM32_F303_HD, + .dev_type = "F303 high density", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register + .flash_pagesize = 0x800, // 4.2.1 Flash memory organization + .sram_size = 0x10000, // 3.3 Embedded SRAM + .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory + .bootrom_size = 0x2000, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L47x/L48x + // RM0351 + .chip_id = STLINK_CHIPID_STM32_L4, + .dev_type = "L47x/L48x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 + // and tables 4-6 on pages 79-81) + // SRAM1 is "up to" 96k in the standard Cortex-M memory map; + // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) + .sram_size = 0x18000, + .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L4RX + // RM0432 + .chip_id = STLINK_CHIPID_STM32_L4Rx, + .dev_type = "L4Rx", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) + .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 + // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size + .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 + .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 + .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L4PX + // RM0432 + .chip_id = STLINK_CHIPID_STM32_L4PX, + .dev_type = "L4Px", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) + .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 + // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size + .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 + .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 + .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, + }, + { + // STLINK_CHIPID_STM32_L41x_L42x + // RM0394 (rev 4), DS12469 (rev 5) + .chip_id = STLINK_CHIPID_STM32_L41x_L42x, + .dev_type = "L41x/L42x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, + // sec 47.2, page 1586) + .flash_pagesize = 0x800, // 2k (DS12469, sec 3.4, page 17) + // SRAM1 is 32k at 0x20000000 + // SRAM2 is 8k at 0x10000000 and 0x20008000 + // (DS12469, sec 3.5, page 18) + .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) + .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) + .bootrom_size = 0x7000, // 28k, same source as base + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STLINK_CHIPID_STM32_L43x_L44x + // RM0392 + .chip_id = STLINK_CHIPID_STM32_L43x_L44x, + .dev_type = "L43x/L44x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 + // and tables 7-8 on pages 75-76) + // SRAM1 is "up to" 64k in the standard Cortex-M memory map; + // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) + .sram_size = 0xc000, + .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STLINK_CHIPID_STM32_L496x_L4A6x + // RM0351 (rev 5) + .chip_id = STLINK_CHIPID_STM32_L496x_L4A6x, + .dev_type = "L496x/L4A6x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) + .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) + // SRAM1 is 256k at 0x20000000 + // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) + .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) + .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STLINK_CHIPID_STM32_L45x_L46x + // RM0394 (updated version of RM0392?) + .chip_id = STLINK_CHIPID_STM32_L45x_L46x, + .dev_type = "L45x/46x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 + // and tables 7 on pages 73-74) + // SRAM1 is 128k at 0x20000000; + // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, + // page 68, also fig 2 on page 63) + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system + // memory, also fig 2 on page 63) + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L0xx Category 1 + // RM0451, RM0377 + .chip_id = STLINK_CHIPID_STM32_L011, + .dev_type = "L01x/L02x", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x2000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x2000, + }, + { + // STM32G030/031/041 + // RM0454, RM0444 + .chip_id = STLINK_CHIPID_STM32_G0_CAT1, + .dev_type = "G03x/G04x", + .flash_type = STLINK_FLASH_TYPE_G0, + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (sec 3.2) + .sram_size = 0x2000, // 8k (sec 2.3) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 3) + .option_base = STM32_G0_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STM32G071/081 + // RM0444 + .chip_id = STLINK_CHIPID_STM32_G0_CAT2, + .dev_type = "G07x/G08x", + .flash_type = STLINK_FLASH_TYPE_G0, + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (sec 3.2) + .sram_size = 0x9000, // 36k (sec 2.3) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) + .option_base = STM32_G0_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STM32G0B1/G0C1 + // RM0444 + .chip_id = STLINK_CHIPID_STM32_G0_CAT3, + .dev_type = "G0Bx/G0Cx", + .flash_type = STLINK_FLASH_TYPE_G0, + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (sec 3.2) + .sram_size = 0x9000, // 36k (sec 2.3) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) + .option_base = STM32_G0_OPTION_BYTES_BASE, + .option_size = 4, + .flags = CHIP_F_HAS_DUAL_BANK, + }, + { + // STM32G051/G061 + // RM0444 + .chip_id = STLINK_CHIPID_STM32_G0_CAT4, + .dev_type = "G05x/G06x", + .flash_type = STLINK_FLASH_TYPE_G0, + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (sec 3.2) + .sram_size = 0x9000, // 36k (sec 2.3) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) + .option_base = STM32_G0_OPTION_BYTES_BASE, + .option_size = 4, + }, + { + // STM32G431/441 + // RM0440 + .chip_id = STLINK_CHIPID_STM32_G4_CAT2, + .dev_type = "G43x/G44x", + .flash_type = STLINK_FLASH_TYPE_G4, + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = 0x800, // 2k (sec 3.3.1) + // SRAM1 is 16k at 0x20000000 + // SRAM2 is 6k at 0x20014000 + // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 + .sram_size = 0x8000, // 32k (sec 2.4) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28k (table 2) + .option_base = STM32_G4_OPTION_BYTES_BASE, + .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32G471/473/474/483/484 + // RM0440 + .chip_id = STLINK_CHIPID_STM32_G4_CAT3, + .dev_type = "G47x/G48x", + .flash_type = STLINK_FLASH_TYPE_G4, + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = 0x800, // 2k (sec 3.3.1) + // SRAM1 is 80k at 0x20000000 + // SRAM2 is 16k at 0x20014000 + // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 + .sram_size = 0x20000, // 128k (sec 2.4) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28k (table 2) + .option_base = STM32_G4_OPTION_BYTES_BASE, + .option_size = 4, + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32G491/G4A1 + // RM0440 + .chip_id = STLINK_CHIPID_STM32_G4_CAT4, + .dev_type = "G49x/G4Ax", + .flash_type = STLINK_FLASH_TYPE_G4, + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = 0x800, // 2k (sec 3.3.1) + // SRAM1 is 80k at 0x20000000 + // SRAM2 is 16k at 0x20014000 + // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 + .sram_size = 0x1C000, // 112k (sec 2.4) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28k (table 2) + .option_base = STM32_G4_OPTION_BYTES_BASE, + .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32H742/743/753 (from RM0433) + .chip_id = STLINK_CHIPID_STM32_H74xxx, + .dev_type = "H74x/H75x", + .flash_type = STLINK_FLASH_TYPE_H7, + .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) + .flash_pagesize = 0x20000, // 128k sector (pg147) + .sram_size = 0x20000, // 128k "DTCM" from Table 7 + .bootrom_base = 0x1ff00000, // "System memory" starting address from Table 7 + .bootrom_size = 0x20000, // "System memory" byte size in hex from Table 7 + .option_base = STM32_H7_OPTION_BYTES_BASE, + .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32H7A3/7B3 + // RM0455 + .chip_id = STLINK_CHIPID_STM32_H7Ax, + .dev_type = "H7Ax/H7Bx", + .flash_type = STLINK_FLASH_TYPE_H7, + .flash_size_reg = 0x08FFF80C, // "Flash size register" (p.2949) + .flash_pagesize = 0x2000, // 8k sector (p.146) + .sram_size = 0x20000, // 128k "DTCM" (Figure 1) + .bootrom_base = 0x1FF00000, // "System memory" starting address (Table 12-14) + .bootrom_size = 0x20000, // "System memory" byte size in hex splitted to + // two banks (Table 12-14) + .option_base = STM32_H7_OPTION_BYTES_BASE, + .option_size = 44, + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32H72x/H73x + // RM0468 + .chip_id = STLINK_CHIPID_STM32_H72x, + .dev_type = "H72x/H73x", + .flash_type = STLINK_FLASH_TYPE_H7, + .flash_size_reg = 0x1FF1E880, // "Flash size register" (p.3286) + .flash_pagesize = 0x20000, // 128k sector (p.152) + .sram_size = 0x20000, // 128k "DTCM" (Figure 1) + .bootrom_base = 0x1FF00000, // "System memory" starting address (Table 6) + .bootrom_size = 0x20000, // "System memory" byte size in hex (Table 6) + .option_base = STM32_H7_OPTION_BYTES_BASE, + .option_size = 44, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + + + { + // STM32F1xx medium-density devices + // RM0008 + .chip_id = STLINK_CHIPID_STM32_F1_MD, + .dev_type = "F1xx Medium-density", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x5000, + .bootrom_base = 0x1ffff000, // 2.3.3 "Embedded Flash memory" + .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F205xx, STM32F207xx, STM32F215xx, STM32F217xx + // RM0033 (rev 5) + .chip_id = STLINK_CHIPID_STM32_F2, + .dev_type = "F2xx", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1fff7a22, + .flash_pagesize = 0x20000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .option_base = 0x1FFFC000, + .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F1xx low-density devices + // RM0008 + .chip_id = STLINK_CHIPID_STM32_F1_LD, + .dev_type = "F1 Low-density device", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2800, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F1xx high-density devices + // RM0008 + .chip_id = STLINK_CHIPID_STM32_F1_HD, + .dev_type = "F1xx High-density", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F1xx connectivity devices + // RM0008 + .chip_id = STLINK_CHIPID_STM32_F1_CONN, + .dev_type = "F1xx CL", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1fffb000, + .bootrom_size = 0x4800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F1xx low- and medium-density value line devices + // RM0041 + .chip_id = STLINK_CHIPID_STM32_F1_VL_MD_LD, + .dev_type = "F1xx Value Line", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2000, // 0x1000 for low density devices + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F1xx high-density value line devices + // RM0041 + .chip_id = STLINK_CHIPID_STM32_F1_VL_HD, + .dev_type = "F1xx High-density value line", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x8000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F1xx XL-density devices + // RM0008 + .chip_id = STLINK_CHIPID_STM32_F1_XLD, + .dev_type = "F1xx XL-density", + .flash_type = STLINK_FLASH_TYPE_F1_XL, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x18000, + .bootrom_base = 0x1fffe000, + .bootrom_size = 0x1800, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32WB55xx, STM32WB35xx, STM32WB50CG/30CE + // RM0434, RM0471 + .chip_id = STLINK_CHIPID_STM32_WB55, + .dev_type = "WB5x/3x", + .flash_type = STLINK_FLASH_TYPE_WB, + .flash_size_reg = 0x1FFF75E0, + .flash_pagesize = 0x1000, // 4k + .sram_size = 0x40000, + .bootrom_base = 0x1fff0000, // see the memory map + .bootrom_size = 0x7000, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32WLEx + .chip_id = STLINK_CHIPID_STM32_WLE, + .dev_type = "WLEx", + .flash_type = STLINK_FLASH_TYPE_WB, + .flash_size_reg = 0x1FFF75E0, + .flash_pagesize = 0x800, // 2k + .sram_size = 0x10000, + .bootrom_base = 0x1fff0000, // see the memory map + .bootrom_size = 0x7000, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // unknown + .chip_id = STLINK_CHIPID_UNKNOWN, + .dev_type = "unknown device", + .flash_type = STLINK_FLASH_TYPE_UNKNOWN, + .flash_size_reg = 0x0, + .flash_pagesize = 0x0, + .sram_size = 0x0, + .bootrom_base = 0x0, + .bootrom_size = 0x0, + }, +}; \ No newline at end of file From 89f54e088417cacdf937f92e7a5e5f55728e03c7 Mon Sep 17 00:00:00 2001 From: hydroconstructor Date: Wed, 5 Jan 2022 13:51:47 +0400 Subject: [PATCH 1265/1435] Update usb.c --- src/stlink-lib/usb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index e07918800..793a1f68d 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1221,6 +1221,8 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, libusb_free_device_list(list, 1); +// libusb_kernel_driver_active is not available on Windows. +#if !defined(_WIN32) if (libusb_kernel_driver_active(slu->usb_handle, 0) == 1) { ret = libusb_detach_kernel_driver(slu->usb_handle, 0); @@ -1229,6 +1231,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, goto on_libusb_error; } } +#endif if (libusb_get_configuration(slu->usb_handle, &config)) { // this may fail for a previous configured device From ab5c47b6cec32a3f0b80708cc8f2d7a1821dd512 Mon Sep 17 00:00:00 2001 From: hydroconstructor Date: Thu, 6 Jan 2022 20:19:01 +0400 Subject: [PATCH 1266/1435] Update usb.c (correct typo) There are 2 calls _stlink_usb_exit_dfu_mode In usb.c (at lines 1284 and 1293) and no single call _stlink_usb_exit_debug_mode. Apparently typo on line 1293 --- src/stlink-lib/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 793a1f68d..65e8f4e25 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1290,7 +1290,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, // the NRST pin must be pull down before selecting the SWD/JTAG mode if (mode == STLINK_DEV_DEBUG_MODE) { DLOG("-- exit_debug_mode\n"); - _stlink_usb_exit_dfu_mode(sl); + _stlink_usb_exit_debug_mode(sl); } _stlink_usb_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); From e62b9e1f2a1b6dea7e9ccb053c14c2c6ad0b57d7 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 6 Jan 2022 19:30:49 +0100 Subject: [PATCH 1267/1435] [refactoring] Clean-up & update for chipid files - F0, F1, F2, F3, F4, F7 - G0, G4 - H7 - L0, L5, U5 - WB, WL --- config/chips/F03x.chip | 21 +- config/chips/F04x.chip | 21 +- config/chips/F05x.chip | 21 +- config/chips/F07x.chip | 21 +- config/chips/F09x.chip | 20 +- config/chips/F1xx_CL.chip | 12 +- config/chips/F1xx_HD.chip | 10 +- config/chips/F1xx_LD.chip | 10 +- config/chips/F1xx_MD.chip | 12 +- config/chips/F1xx_VL_HD.chip | 10 +- config/chips/F1xx_VL_MD_LD.chip | 10 +- config/chips/F1xx_XLD.chip | 12 +- config/chips/F2xx.chip | 12 +- config/chips/F301_F302_F318.chip | 21 +- config/chips/F302_F303_F358.chip | 21 +- config/chips/F302_F303_F398_HD.chip | 14 + config/chips/F303_F328_F334.chip | 21 +- config/chips/F303_high_density.chip | 13 - config/chips/F37x.chip | 21 +- config/chips/F401xB_C.chip | 13 - config/chips/F401xB_xC.chip | 14 + config/chips/F401xD_E.chip | 13 - config/chips/F401xD_xE.chip | 14 + config/chips/F410.chip | 17 +- config/chips/F411xC_E.chip | 13 - config/chips/F411xC_xE.chip | 14 + config/chips/F412.chip | 17 +- config/chips/F413_F423.chip | 17 +- config/chips/F42x_F43x.chip | 17 +- config/chips/F446.chip | 21 +- config/chips/F46x_F47x.chip | 17 +- config/chips/F4x5_F4x7.chip | 21 +- config/chips/F72x_F73x.chip | 21 +- config/chips/F74x_F75x.chip | 21 +- config/chips/F76x_F77x.chip | 23 +- config/chips/G03x_G04x.chip | 21 +- config/chips/G05x_G06x.chip | 21 +- config/chips/G07x_G08x.chip | 21 +- config/chips/G0Bx_G0Cx.chip | 21 +- config/chips/G43x_G44x.chip | 21 +- config/chips/G47x_G48x.chip | 23 +- config/chips/G49x_G4Ax.chip | 21 +- config/chips/H72x_H73x.chip | 21 +- config/chips/H74x_H75x.chip | 23 +- config/chips/H7Ax_H7Bx.chip | 23 +- config/chips/L01x_L02x.chip | 13 - config/chips/L0xx_Cat_2.chip | 13 - config/chips/L0xx_Cat_3.chip | 13 - config/chips/L0xx_Cat_5.chip | 13 - config/chips/L0xxx_Cat_1.chip | 14 + config/chips/L0xxx_Cat_2.chip | 14 + config/chips/L0xxx_Cat_3.chip | 14 + config/chips/L0xxx_Cat_5.chip | 14 + config/chips/L5x5.chip | 15 + config/chips/U5x5.chip | 15 + config/chips/WBx0_WBx5.chip | 14 + config/chips/WBx5_WBx0.chip | 14 - config/chips/{WLEx.chip => WLx5.chip} | 12 +- config/chips/unknown_device.chip | 2 +- inc/stm32.h | 13 +- src/stlink-lib/chipid.c | 12 +- src/stlink-lib/chipid_db_old.h | 1023 +++++++++++++------------ 62 files changed, 1047 insertions(+), 973 deletions(-) create mode 100644 config/chips/F302_F303_F398_HD.chip delete mode 100644 config/chips/F303_high_density.chip delete mode 100644 config/chips/F401xB_C.chip create mode 100644 config/chips/F401xB_xC.chip delete mode 100644 config/chips/F401xD_E.chip create mode 100644 config/chips/F401xD_xE.chip delete mode 100644 config/chips/F411xC_E.chip create mode 100644 config/chips/F411xC_xE.chip delete mode 100644 config/chips/L01x_L02x.chip delete mode 100644 config/chips/L0xx_Cat_2.chip delete mode 100644 config/chips/L0xx_Cat_3.chip delete mode 100644 config/chips/L0xx_Cat_5.chip create mode 100644 config/chips/L0xxx_Cat_1.chip create mode 100644 config/chips/L0xxx_Cat_2.chip create mode 100644 config/chips/L0xxx_Cat_3.chip create mode 100644 config/chips/L0xxx_Cat_5.chip create mode 100644 config/chips/L5x5.chip create mode 100644 config/chips/U5x5.chip create mode 100644 config/chips/WBx0_WBx5.chip delete mode 100644 config/chips/WBx5_WBx0.chip rename config/chips/{WLEx.chip => WLx5.chip} (54%) diff --git a/config/chips/F03x.chip b/config/chips/F03x.chip index eed78e4e2..ea7fdb9e2 100644 --- a/config/chips/F03x.chip +++ b/config/chips/F03x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F03x +# Chip-ID file for STM32F03x device # -chip_id 0x444 -description F03x -flash_type 1 -flash_pagesize 0x400 -sram_size 0x1000 +dev_type STM32F03x +ref_manual_id 0091 +chip_id 0x444 // STLINK_CHIPID_STM32_F0xx_SMALL +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7cc +flash_pagesize 0x400 // 1 KB +sram_size 0x1000 // 4 KB bootrom_base 0x1fffec00 -bootrom_size 0xc00 -option_base 0x1ffff800 -option_size 0x10 +bootrom_size 0xc00 // 3 KB +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 B flags none - diff --git a/config/chips/F04x.chip b/config/chips/F04x.chip index 1f2a2043e..3e702585b 100644 --- a/config/chips/F04x.chip +++ b/config/chips/F04x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F04x +# Chip-ID file for STM32F04x device # -chip_id 0x445 -description F04x -flash_type 1 -flash_pagesize 0x400 -sram_size 0x1800 +dev_type STM32F04x +ref_manual_id 0091 +chip_id 0x445 // STLINK_CHIPID_STM32_F04 +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7cc +flash_pagesize 0x400 // 1 KB +sram_size 0x1800 // 6 KB bootrom_base 0x1fffec00 -bootrom_size 0xc00 -option_base 0x1ffff800 -option_size 0x10 +bootrom_size 0xc00 // 3 KB +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 B flags none - diff --git a/config/chips/F05x.chip b/config/chips/F05x.chip index 787adb6bf..1a4f61386 100644 --- a/config/chips/F05x.chip +++ b/config/chips/F05x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F05x +# Chip-ID file for STM32F05x device # -chip_id 0x440 -description F05x -flash_type 1 -flash_pagesize 0x400 -sram_size 0x2000 +dev_type STM32F05x +ref_manual_id 0091 +chip_id 0x440 // STLINK_CHIPID_STM32_F0 +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7cc +flash_pagesize 0x400 // 1 KB +sram_size 0x2000 // 8 KB bootrom_base 0x1fffec00 -bootrom_size 0xc00 -option_base 0x1ffff800 -option_size 0x10 +bootrom_size 0xc00 // 3 KB +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 B flags none - diff --git a/config/chips/F07x.chip b/config/chips/F07x.chip index e893a5457..2a577b7b4 100644 --- a/config/chips/F07x.chip +++ b/config/chips/F07x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F07x +# Chip-ID file for STM32F07x device # -chip_id 0x448 -description F07x -flash_type 1 -flash_pagesize 0x800 -sram_size 0x4000 +dev_type STM32F07x +ref_manual_id 0091 +chip_id 0x448 // STLINK_CHIPID_STM32_F0_CAN +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7cc +flash_pagesize 0x800 // 2 KB +sram_size 0x4000 // 16 KB bootrom_base 0x1fffc800 -bootrom_size 0x3000 -option_base 0x1ffff800 -option_size 0x10 +bootrom_size 0x3000 // 12 KB +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 B flags none - diff --git a/config/chips/F09x.chip b/config/chips/F09x.chip index 267a2612f..9f419893e 100644 --- a/config/chips/F09x.chip +++ b/config/chips/F09x.chip @@ -1,13 +1,15 @@ -# Chip-ID file for F09x +# Chip-ID file for STM32F09x device # -chip_id 0x442 -description F09x -flash_type 1 -flash_pagesize 0x800 -sram_size 0x8000 +dev_type STM32F09x +ref_manual_id 0091 +chip_id 0x442 // STLINK_CHIPID_STM32_F09x +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7cc +flash_pagesize 0x800 // 2 KB +sram_size 0x8000 // 32 KB bootrom_base 0x1fffd800 -bootrom_size 0x2000 -option_base 0x1ffff800 -option_size 0x10 +bootrom_size 0x2000 // 8 KB +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 B flags none diff --git a/config/chips/F1xx_CL.chip b/config/chips/F1xx_CL.chip index 6282bc2ee..4c8bb0b8d 100644 --- a/config/chips/F1xx_CL.chip +++ b/config/chips/F1xx_CL.chip @@ -1,15 +1,15 @@ -# Chip-ID file for STM32F1xx CL device +# Chip-ID file for STM32F1xx Connectivity Line device # -dev_type STM32F1xx Connectivity Line device +dev_type STM32F1xx_CL ref_manual_id 0008 chip_id 0x418 // STLINK_CHIPID_STM32_F1_CONN flash_type 1 // STLINK_FLASH_TYPE_F0 flash_size_reg 0x1ffff7e0 -flash_pagesize 0x800 -sram_size 0x10000 +flash_pagesize 0x800 // 2 KB +sram_size 0x10000 // 64 KB bootrom_base 0x1fffb000 -bootrom_size 0x4800 +bootrom_size 0x4800 // 18 KB option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE -option_size 0x10 // 16 +option_size 0x10 // 16 B flags swo diff --git a/config/chips/F1xx_HD.chip b/config/chips/F1xx_HD.chip index 72ad9fa75..18757029a 100644 --- a/config/chips/F1xx_HD.chip +++ b/config/chips/F1xx_HD.chip @@ -1,14 +1,14 @@ # Chip-ID file for STM32F1xx high density device # -dev_type F1xx high density device +dev_type F1xx_HD ref_manual_id 0008 chip_id 0x414 // STLINK_CHIPID_STM32_F1_HD flash_type 1 // STLINK_FLASH_TYPE_F0 flash_size_reg 0x1ffff7e0 -flash_pagesize 0x800 -sram_size 0x10000 +flash_pagesize 0x800 // 2 KB +sram_size 0x10000 // 64 KB bootrom_base 0x1ffff000 -bootrom_size 0x800 +bootrom_size 0x800 // 2 KB option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE -option_size 0x10 // 16 +option_size 0x10 // 16 B flags swo diff --git a/config/chips/F1xx_LD.chip b/config/chips/F1xx_LD.chip index 8a3682755..8a8f5867d 100644 --- a/config/chips/F1xx_LD.chip +++ b/config/chips/F1xx_LD.chip @@ -1,14 +1,14 @@ # Chip-ID file for STM32F1 low density device # -dev_type STM32F1xx low density device +dev_type STM32F1xx_LD ref_manual_id 0008 chip_id 0x412 // STLINK_CHIPID_STM32_F1_LD flash_type 1 // STLINK_FLASH_TYPE_F0 flash_size_reg 0x1ffff7e0 -flash_pagesize 0x400 -sram_size 0x2800 +flash_pagesize 0x400 // 1 KB +sram_size 0x2800 // 10 KB bootrom_base 0x1ffff000 -bootrom_size 0x800 +bootrom_size 0x800 // 2 KB option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE -option_size 0x10 // 16 +option_size 0x10 // 16 B flags swo diff --git a/config/chips/F1xx_MD.chip b/config/chips/F1xx_MD.chip index f3da99493..be492f54a 100644 --- a/config/chips/F1xx_MD.chip +++ b/config/chips/F1xx_MD.chip @@ -1,14 +1,14 @@ # Chip-ID file for STM32F1xx medium density device # -dev_type STM32F1xx medium density device +dev_type STM32F1xx_MD ref_manual_id 0008 chip_id 0x410 // STLINK_CHIPID_STM32_F1_MD flash_type 1 // STLINK_FLASH_TYPE_F0 flash_size_reg 0x1ffff7e0 -flash_pagesize 0x400 -sram_size 0x5000 -bootrom_base 0x1ffff000 // Section 2.3.3 "Embedded Flash memory" -bootrom_size 0x800 +flash_pagesize 0x400 // 1 KB +sram_size 0x5000 // 20 KB +bootrom_base 0x1ffff000 +bootrom_size 0x800 // 2 KB option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE -option_size 0x10 // 16 +option_size 0x10 // 16 B flags swo diff --git a/config/chips/F1xx_VL_HD.chip b/config/chips/F1xx_VL_HD.chip index f46945a94..f5ca6b023 100644 --- a/config/chips/F1xx_VL_HD.chip +++ b/config/chips/F1xx_VL_HD.chip @@ -1,14 +1,14 @@ # Chip-ID file for STM32F1xx high density Value Line device # -dev_type STM32F1xx Value Line high density device +dev_type STM32F1xx_VL_HD ref_manual_id 0041 chip_id 0x428 // STLINK_CHIPID_STM32_F1_VL_HD flash_type 1 // STLINK_FLASH_TYPE_F0 flash_size_reg 0x1ffff7e0 -flash_pagesize 0x800 -sram_size 0x8000 +flash_pagesize 0x800 // 2 KB +sram_size 0x8000 // 32 KB bootrom_base 0x1ffff000 -bootrom_size 0x800 +bootrom_size 0x800 // 2 KB option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE -option_size 0x10 // 16 +option_size 0x10 // 16 B flags swo diff --git a/config/chips/F1xx_VL_MD_LD.chip b/config/chips/F1xx_VL_MD_LD.chip index 2bff05b82..e79668c70 100644 --- a/config/chips/F1xx_VL_MD_LD.chip +++ b/config/chips/F1xx_VL_MD_LD.chip @@ -1,14 +1,14 @@ # Chip-ID file for STMF1xx Value Line medium & low density device # -dev_type STM32F1xx Value Line medium & low density device +dev_type STM32F1xx_VL_MD_LD ref_manual_id 0041 chip_id 0x420 // STLINK_CHIPID_STM32_F1_VL_MD_LD flash_type 1 // STLINK_FLASH_TYPE_F0 flash_size_reg 0x1ffff7e0 -flash_pagesize 0x400 -sram_size 0x2000 // 0x1000 for low density devices +flash_pagesize 0x400 // 1 KB +sram_size 0x2000 // 8 KB /* 0x1000 for low density devices */ bootrom_base 0x1ffff000 -bootrom_size 0x800 +bootrom_size 0x800 // 2 KB option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE -option_size 0x10 // 16 +option_size 0x10 // 16 B flags swo diff --git a/config/chips/F1xx_XLD.chip b/config/chips/F1xx_XLD.chip index 90264ce0f..d7d8cf2b7 100644 --- a/config/chips/F1xx_XLD.chip +++ b/config/chips/F1xx_XLD.chip @@ -1,14 +1,14 @@ # Chip-ID file for STM32F1xx XL density device # -dev_type STM32F1xx XL density device +dev_type STM32F1xx_XLD ref_manual_id 0008 -chip_id 0x430 // STLINK_CHIPID_STM32_F1_XLD -flash_type 2 // STLINK_FLASH_TYPE_F1_XL +chip_id 0x430 // STLINK_CHIPID_STM32_F1_XLD +flash_type 2 // STLINK_FLASH_TYPE_F1_XL flash_size_reg 0x1ffff7e0 -flash_pagesize 0x800 -sram_size 0x18000 +flash_pagesize 0x800 // 2 KB +sram_size 0x18000 // 96 KB bootrom_base 0x1fffe000 -bootrom_size 0x1800 +bootrom_size 0x1800 // 6 KB option_base 0x0 option_size 0x0 flags swo diff --git a/config/chips/F2xx.chip b/config/chips/F2xx.chip index ce2e9e698..67c225af5 100644 --- a/config/chips/F2xx.chip +++ b/config/chips/F2xx.chip @@ -1,14 +1,14 @@ -# Chip-ID file for STM32F2xx device (STM32F205xx, STM32F207xx, STM32F215xx, STM32F217xx) +# Chip-ID file for STM32F2xx device # -dev_type STM32F2xx device +dev_type STM32F2xx ref_manual_id 0033 chip_id 0x411 // STLINK_CHIPID_STM32_F2 flash_type 3 // STLINK_FLASH_TYPE_F4 flash_size_reg 0x1fff7a22 -flash_pagesize 0x20000 -sram_size 0x20000 +flash_pagesize 0x20000 // 128 KB +sram_size 0x20000 // 128 KB bootrom_base 0x1fff0000 -bootrom_size 0x7800 +bootrom_size 0x7800 // 30 KB option_base 0x1fffc000 // STM32_F2_OPTION_BYTES_BASE -option_size 0x4 // 4 +option_size 0x4 // 4 B flags swo diff --git a/config/chips/F301_F302_F318.chip b/config/chips/F301_F302_F318.chip index 429c836b4..ee71dfe90 100644 --- a/config/chips/F301_F302_F318.chip +++ b/config/chips/F301_F302_F318.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F301/F302/F318 +# Chip-ID file for STM32F3xx device (F301x6/8, F302x6x8, F318x8) # -chip_id 0x439 -description F301/F302/F318 -flash_type 1 -flash_pagesize 0x800 -sram_size 0xa000 +dev_type STM32F301_F302_F318 +ref_manual_id 0365 // also RM0366 +chip_id 0x439 // STLINK_CHIPID_STM32_F3xx_SMALL +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7cc +flash_pagesize 0x800 // 2 KB +sram_size 0xa000 // 40 KB bootrom_base 0x1fffd800 -bootrom_size 0x2000 -option_base 0x1ffff800 -option_size 0x10 +bootrom_size 0x2000 // 8 KB +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 B flags swo - diff --git a/config/chips/F302_F303_F358.chip b/config/chips/F302_F303_F358.chip index ffd1491ff..64d0651f2 100644 --- a/config/chips/F302_F303_F358.chip +++ b/config/chips/F302_F303_F358.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F302/F303/F358 +# Chip-ID file for STM32F3xx device (F302xBxC, F303xB/C, F358) # -chip_id 0x422 -description F302/F303/F358 -flash_type 1 -flash_pagesize 0x800 -sram_size 0xa000 +dev_type STM32F302_F303_358 +ref_manual_id 0365 // also RM0316 +chip_id 0x422 // STLINK_CHIPID_STM32_F3 +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7cc +flash_pagesize 0x800 // 2 KB +sram_size 0xa000 // 40 KB bootrom_base 0x1ffff000 -bootrom_size 0x800 -option_base 0x1ffff800 -option_size 0x10 +bootrom_size 0x800 // 2 KB +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 B flags swo - diff --git a/config/chips/F302_F303_F398_HD.chip b/config/chips/F302_F303_F398_HD.chip new file mode 100644 index 000000000..eaf36b74c --- /dev/null +++ b/config/chips/F302_F303_F398_HD.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32F3xx high density device (F302xD/E, F303xD/E, F398xE) +# +dev_type STM32F302_F303_F398_HD +ref_manual_id 0365 // also RM0316 (Rev 5) +chip_id 0x446 // STLINK_CHIPID_STM32_F303_HD +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7cc +flash_pagesize 0x800 // 2 KB +sram_size 0x10000 // 64 KB +bootrom_base 0x1fffd800 +bootrom_size 0x2000 // 8 KB +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 B +flags swo diff --git a/config/chips/F303_F328_F334.chip b/config/chips/F303_F328_F334.chip index 5df2a9bbb..2ecdbfb71 100644 --- a/config/chips/F303_F328_F334.chip +++ b/config/chips/F303_F328_F334.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F303/F328/F334 +# Chip-ID file for STM32F3xx device (F303x6/8, F328, F334) # -chip_id 0x438 -description F303/F328/F334 -flash_type 1 -flash_pagesize 0x800 -sram_size 0x3000 +dev_type STM32F303_F328_F334 +ref_manual_id 0364 // also RM0316 +chip_id 0x438 // STLINK_CHIPID_STM32_F334 +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7cc +flash_pagesize 0x800 // 2 KB +sram_size 0x3000 // 12 KB bootrom_base 0x1fffd800 -bootrom_size 0x2000 -option_base 0x1ffff800 -option_size 0x10 +bootrom_size 0x2000 // 8 KB +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 B flags swo - diff --git a/config/chips/F303_high_density.chip b/config/chips/F303_high_density.chip deleted file mode 100644 index 748c27cbc..000000000 --- a/config/chips/F303_high_density.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for F303 high density -# -chip_id 0x446 -description F303 high density -flash_type 1 -flash_pagesize 0x800 -sram_size 0x10000 -bootrom_base 0x1fffd800 -bootrom_size 0x2000 -option_base 0x1ffff800 -option_size 0x10 -flags swo - diff --git a/config/chips/F37x.chip b/config/chips/F37x.chip index 92201657d..1bd7ac421 100644 --- a/config/chips/F37x.chip +++ b/config/chips/F37x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F37x +# Chip-ID file for STM32F37x device # -chip_id 0x432 -description F37x -flash_type 1 -flash_pagesize 0x800 -sram_size 0xa000 +dev_type STM32F37x +ref_manual_id 0313 +chip_id 0x432 // STLINK_CHIPID_STM32_F37x +flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_size_reg 0x1ffff7cc +flash_pagesize 0x800 // 2 KB +sram_size 0xa000 // 40 KB bootrom_base 0x1ffff000 -bootrom_size 0x800 -option_base 0x1ffff800 -option_size 0x10 +bootrom_size 0x800 // 2 KB +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 B flags swo - diff --git a/config/chips/F401xB_C.chip b/config/chips/F401xB_C.chip deleted file mode 100644 index 09e998dba..000000000 --- a/config/chips/F401xB_C.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for F401xB/C -# -chip_id 0x423 -description F401xB/C -flash_type 3 -flash_pagesize 0x4000 -sram_size 0x10000 -bootrom_base 0x1fff0000 -bootrom_size 0x7800 -option_base 0x0 -option_size 0x0 -flags swo - diff --git a/config/chips/F401xB_xC.chip b/config/chips/F401xB_xC.chip new file mode 100644 index 000000000..fc93c2f1a --- /dev/null +++ b/config/chips/F401xB_xC.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32F401xB/xC device +# +dev_type STM32F401xB_xC +ref_manual_id 0368 +chip_id 0x423 // STLINK_CHIPID_STM32_F4_LP +flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_size_reg 0x1fff7a22 +flash_pagesize 0x4000 // 16 KB +sram_size 0x10000 // 64 KB +bootrom_base 0x1fff0000 +bootrom_size 0x7800 // 30 KB +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F401xD_E.chip b/config/chips/F401xD_E.chip deleted file mode 100644 index 5b70d7d86..000000000 --- a/config/chips/F401xD_E.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for F401xD/E -# -chip_id 0x433 -description F401xD/E -flash_type 3 -flash_pagesize 0x4000 -sram_size 0x18000 -bootrom_base 0x1fff0000 -bootrom_size 0x7800 -option_base 0x0 -option_size 0x0 -flags swo - diff --git a/config/chips/F401xD_xE.chip b/config/chips/F401xD_xE.chip new file mode 100644 index 000000000..e31d5eace --- /dev/null +++ b/config/chips/F401xD_xE.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32F401xD/xE device +# +dev_type STM32F401xD_xE +ref_manual_id 0368 +chip_id 0x433 // STLINK_CHIPID_STM32_F4_DE +flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_size_reg 0x1fff7a22 +flash_pagesize 0x4000 // 16 KB +sram_size 0x18000 // 96 KB +bootrom_base 0x1fff0000 +bootrom_size 0x7800 // 30 KB +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F410.chip b/config/chips/F410.chip index ae199d9c4..a8a7fbad0 100644 --- a/config/chips/F410.chip +++ b/config/chips/F410.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F410 +# Chip-ID file for STM32F410 device # -chip_id 0x458 -description F410 -flash_type 3 -flash_pagesize 0x4000 -sram_size 0x8000 +dev_type STM32F410 +ref_manual_id 0401 +chip_id 0x458 // STLINK_CHIPID_STM32_F410 +flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_size_reg 0x1fff7a22 +flash_pagesize 0x4000 // 16 KB +sram_size 0x8000 // 32 KB bootrom_base 0x1fff0000 -bootrom_size 0x7800 +bootrom_size 0x7800 // 30 KB option_base 0x0 option_size 0x0 flags swo - diff --git a/config/chips/F411xC_E.chip b/config/chips/F411xC_E.chip deleted file mode 100644 index d344489c5..000000000 --- a/config/chips/F411xC_E.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for F411xC/E -# -chip_id 0x431 -description F411xC/E -flash_type 3 -flash_pagesize 0x4000 -sram_size 0x20000 -bootrom_base 0x1fff0000 -bootrom_size 0x7800 -option_base 0x0 -option_size 0x0 -flags swo - diff --git a/config/chips/F411xC_xE.chip b/config/chips/F411xC_xE.chip new file mode 100644 index 000000000..cf2cbd2c1 --- /dev/null +++ b/config/chips/F411xC_xE.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32F411xC/xE device +# +dev_type STM32F411xC_xE +ref_manual_id 0383 +chip_id 0x431 // STLINK_CHIPID_STM32_F411xx +flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_size_reg 0x1fff7a22 +flash_pagesize 0x4000 // 16 KB +sram_size 0x20000 // 128 KB +bootrom_base 0x1fff0000 +bootrom_size 0x7800 // 30 KB +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/F412.chip b/config/chips/F412.chip index 3212a340c..4c866a3c5 100644 --- a/config/chips/F412.chip +++ b/config/chips/F412.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F412 +# Chip-ID file for STM32F412 device # -chip_id 0x441 -description F412 -flash_type 3 -flash_pagesize 0x4000 -sram_size 0x40000 +dev_type STM32F412 +ref_manual_id 0402 +chip_id 0x441 // STLINK_CHIPID_STM32_F412 +flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_size_reg 0x1fff7a22 +flash_pagesize 0x4000 // 16 KB +sram_size 0x40000 // 256 KB bootrom_base 0x1fff0000 -bootrom_size 0x7800 +bootrom_size 0x7800 // 30 KB option_base 0x0 option_size 0x0 flags swo - diff --git a/config/chips/F413_F423.chip b/config/chips/F413_F423.chip index 647775eeb..81ca585f6 100644 --- a/config/chips/F413_F423.chip +++ b/config/chips/F413_F423.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F413/F423 +# Chip-ID file for STM32F413 / STM32F423 device # -chip_id 0x463 -description F413/F423 -flash_type 3 -flash_pagesize 0x4000 -sram_size 0x50000 +dev_type STM32F413_F423 +ref_manual_id 0430 // RM0430 (Rev 2) +chip_id 0x463 // STLINK_CHIPID_STM32_F413 +flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_size_reg 0x1fff7a22 +flash_pagesize 0x4000 // 16 KB +sram_size 0x50000 // 320 KB bootrom_base 0x1fff0000 -bootrom_size 0x7800 +bootrom_size 0x7800 // 30 KB option_base 0x0 option_size 0x0 flags swo - diff --git a/config/chips/F42x_F43x.chip b/config/chips/F42x_F43x.chip index 3184d0d4f..2ec8fb8e8 100644 --- a/config/chips/F42x_F43x.chip +++ b/config/chips/F42x_F43x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F42x/F43x +# Chip-ID file for STM32F42x / STM32F43x device # -chip_id 0x419 -description F42x/F43x -flash_type 3 -flash_pagesize 0x4000 -sram_size 0x40000 +dev_type STM32F42x_F43x +ref_manual_id 0090 // RM0090 (Rev. 2) +chip_id 0x463 // STLINK_CHIPID_STM32_F4_HD +flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_size_reg 0x1fff7a22 +flash_pagesize 0x4000 // 16 KB +sram_size 0x40000 // 256 KB bootrom_base 0x1fff0000 -bootrom_size 0x7800 +bootrom_size 0x7800 // 30 KB option_base 0x0 option_size 0x0 flags swo - diff --git a/config/chips/F446.chip b/config/chips/F446.chip index 86cee6a56..8cebe358e 100644 --- a/config/chips/F446.chip +++ b/config/chips/F446.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F446 +# Chip-ID file for STM32F446 device # -chip_id 0x421 -description F446 -flash_type 3 -flash_pagesize 0x20000 -sram_size 0x20000 +dev_type STM32F446 +ref_manual_id 0390 +chip_id 0x421 // STLINK_CHIPID_STM32_F446 +flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_size_reg 0x1fff7a22 +flash_pagesize 0x20000 // 128 KB +sram_size 0x20000 // 128 KB bootrom_base 0x1fff0000 -bootrom_size 0x7800 -option_base 0x1fffc000 -option_size 0x4 +bootrom_size 0x7800 // 30 KB +option_base 0x40023c14 // STM32_F4_OPTION_BYTES_BASE +option_size 0x4 // 4 B flags swo - diff --git a/config/chips/F46x_F47x.chip b/config/chips/F46x_F47x.chip index ee5f6a5a7..2e4055f2c 100644 --- a/config/chips/F46x_F47x.chip +++ b/config/chips/F46x_F47x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F46x/F47x +# Chip-ID file for STM32F46x / STM32F47x device # -chip_id 0x434 -description F46x/F47x -flash_type 3 -flash_pagesize 0x4000 -sram_size 0x40000 +dev_type STM32F46x_F47x +ref_manual_id 0090 // RM0090 (Rev. 2) +chip_id 0x434 // STLINK_CHIPID_STM32_F4_DSI +flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_size_reg 0x1fff7a22 +flash_pagesize 0x4000 // 16 KB +sram_size 0x40000 // 256 KB bootrom_base 0x1fff0000 -bootrom_size 0x7800 +bootrom_size 0x7800 // 30 KB option_base 0x0 option_size 0x0 flags swo - diff --git a/config/chips/F4x5_F4x7.chip b/config/chips/F4x5_F4x7.chip index b19e4a5b3..9313c8ae1 100644 --- a/config/chips/F4x5_F4x7.chip +++ b/config/chips/F4x5_F4x7.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F4x5/F4x7 +# Chip-ID file for STM32F4x5 / STM32F4x7 device # -chip_id 0x413 -description F4x5/F4x7 -flash_type 3 -flash_pagesize 0x4000 -sram_size 0x30000 +dev_type STM32F4x5_F4x7 +ref_manual_id 0090 // RM0090 (Rev. 2) +chip_id 0x413 // STLINK_CHIPID_STM32_F4 +flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_size_reg 0x1fff7a22 +flash_pagesize 0x4000 // 16 KB +sram_size 0x30000 // 192 KB bootrom_base 0x1fff0000 -bootrom_size 0x7800 -option_base 0x40023c14 -option_size 0x4 +bootrom_size 0x7800 // 30 KB +option_base 0x40023c14 // STM32_F4_OPTION_BYTES_BASE +option_size 0x4 // 4 B flags swo - diff --git a/config/chips/F72x_F73x.chip b/config/chips/F72x_F73x.chip index 2836040ac..37dcd1234 100644 --- a/config/chips/F72x_F73x.chip +++ b/config/chips/F72x_F73x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F72x/F73x +# Chip-ID file for STM32F72x / STM32F73x device # -chip_id 0x452 -description F72x/F73x -flash_type 3 -flash_pagesize 0x800 -sram_size 0x40000 +dev_type STM32F72x_F73x +ref_manual_id 0431 +chip_id 0x452 // STLINK_CHIPID_STM32_F72xxx +flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_size_reg 0x1ff07a22 +flash_pagesize 0x800 // 2 KB +sram_size 0x40000 // 256 KB bootrom_base 0x100000 -bootrom_size 0xedc0 -option_base 0x0 -option_size 0x0 +bootrom_size 0xedc0 // 59.4375 KB +option_base 0x1fff0000 // STM32_F7_OPTION_BYTES_BASE +option_size 0x20 // 32 B flags swo - diff --git a/config/chips/F74x_F75x.chip b/config/chips/F74x_F75x.chip index 0604b299d..96cc95217 100644 --- a/config/chips/F74x_F75x.chip +++ b/config/chips/F74x_F75x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F74x/F75x +# Chip-ID file for STM32F74x / STM32F75x device # -chip_id 0x449 -description F74x/F75x -flash_type 3 -flash_pagesize 0x800 -sram_size 0x50000 +dev_type STM32F74x_F75x +ref_manual_id 0385 +chip_id 0x449 // STLINK_CHIPID_STM32_F7 +flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_size_reg 0x1ff0f442 +flash_pagesize 0x800 // 2 KB +sram_size 0x50000 // 320 KB bootrom_base 0x100000 -bootrom_size 0xedc0 -option_base 0x0 -option_size 0x0 +bootrom_size 0xedc0 // 59.4375 KB +option_base 0x1fff0000 // STM32_F7_OPTION_BYTES_BASE +option_size 0x20 // 32 B flags swo - diff --git a/config/chips/F76x_F77x.chip b/config/chips/F76x_F77x.chip index 304c99191..a93aba2be 100644 --- a/config/chips/F76x_F77x.chip +++ b/config/chips/F76x_F77x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for F76x/F77x +# Chip-ID file for STM32F76x / STM32F77x device # -chip_id 0x451 -description F76x/F77x -flash_type 4 -flash_pagesize 0x800 -sram_size 0x80000 +dev_type STM32F76x_F77x +ref_manual_id 0410 +chip_id 0x451 // STLINK_CHIPID_STM32_F76xxx +flash_type 4 // STLINK_FLASH_TYPE_F7 +flash_size_reg 0x1ff0f442 +flash_pagesize 0x800 // 2 KB +sram_size 0x80000 // 512 KB bootrom_base 0x200000 -bootrom_size 0xedc0 -option_base 0x1fff0000 -option_size 0x20 -flags dualbank swo - +bootrom_size 0xedc0 // 59.4375 KB +option_base 0x1fff0000 // STM32_F7_OPTION_BYTES_BASE /* Used for reading back option bytes, writing uses FLASH_F7_OPTCR and FLASH_F7_OPTCR1 */ +option_size 0x20 // 32 B +flags swo dualbank diff --git a/config/chips/G03x_G04x.chip b/config/chips/G03x_G04x.chip index 7c5a00c58..a21a9898f 100644 --- a/config/chips/G03x_G04x.chip +++ b/config/chips/G03x_G04x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for G03x/G04x +# Chip-ID file for STM32G030 / STM32G031 / STM32G041 device # -chip_id 0x466 -description G03x/G04x -flash_type 7 -flash_pagesize 0x800 -sram_size 0x2000 +dev_type STM32G03x_G04x +ref_manual_id 0444 // also RM454 +chip_id 0x466 // STLINK_CHIPID_STM32_G0_CAT1 +flash_type 7 // STLINK_FLASH_TYPE_G0 +flash_size_reg 0x1fff75e0 +flash_pagesize 0x800 // 2 KB +sram_size 0x2000 // 8 KB bootrom_base 0x1fff0000 -bootrom_size 0x2000 -option_base 0x1fff7800 -option_size 0x4 +bootrom_size 0x2000 // 8 KB +option_base 0x1fff7800 // STM32_G0_OPTION_BYTES_BASE +option_size 0x4 // 4 B flags none - diff --git a/config/chips/G05x_G06x.chip b/config/chips/G05x_G06x.chip index 45295ec6e..89af0825c 100644 --- a/config/chips/G05x_G06x.chip +++ b/config/chips/G05x_G06x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for G05x/G06x +# Chip-ID file for STM32G05x / STM32G06x device # -chip_id 0x456 -description G05x/G06x -flash_type 7 -flash_pagesize 0x800 -sram_size 0x9000 +dev_type STM32G05x_G06x +ref_manual_id 0444 +chip_id 0x456 // STLINK_CHIPID_STM32_G0_CAT4 +flash_type 7 // STLINK_FLASH_TYPE_G0 +flash_size_reg 0x1fff75e0 +flash_pagesize 0x800 // 2 KB +sram_size 0x9000 // 36 KB bootrom_base 0x1fff0000 -bootrom_size 0x7000 -option_base 0x1fff7800 -option_size 0x4 +bootrom_size 0x7000 // 28 KB +option_base 0x1fff7800 // STM32_G0_OPTION_BYTES_BASE +option_size 0x4 // 4 B flags none - diff --git a/config/chips/G07x_G08x.chip b/config/chips/G07x_G08x.chip index 7bddcd82c..c54de398f 100644 --- a/config/chips/G07x_G08x.chip +++ b/config/chips/G07x_G08x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for G07x/G08x +# Chip-ID file for STM32G07x / STM32G08x device # -chip_id 0x460 -description G07x/G08x -flash_type 7 -flash_pagesize 0x800 -sram_size 0x9000 +dev_type STM32G07x_G08x +ref_manual_id 0444 +chip_id 0x460 // STLINK_CHIPID_STM32_G0_CAT2 +flash_type 7 // STLINK_FLASH_TYPE_G0 +flash_size_reg 0x1fff75e0 +flash_pagesize 0x800 // 2 KB +sram_size 0x9000 // 36 KB bootrom_base 0x1fff0000 -bootrom_size 0x7000 -option_base 0x1fff7800 -option_size 0x4 +bootrom_size 0x7000 // 28 KB +option_base 0x1fff7800 // STM32_G0_OPTION_BYTES_BASE +option_size 0x4 // 4 B flags none - diff --git a/config/chips/G0Bx_G0Cx.chip b/config/chips/G0Bx_G0Cx.chip index 98e503569..d8e0eb042 100644 --- a/config/chips/G0Bx_G0Cx.chip +++ b/config/chips/G0Bx_G0Cx.chip @@ -1,13 +1,14 @@ -# Chip-ID file for G0Bx/G0Cx +# Chip-ID file for STM32G0Bx / STM32G0Cx device # -chip_id 0x467 -description G0Bx/G0Cx -flash_type 7 -flash_pagesize 0x800 -sram_size 0x9000 +dev_type STM32G0Bx_G0Cx +ref_manual_id 0444 +chip_id 0x467 // STLINK_CHIPID_STM32_G0_CAT3 +flash_type 7 // STLINK_FLASH_TYPE_G0 +flash_size_reg 0x1fff75e0 +flash_pagesize 0x800 // 2 KB +sram_size 0x9000 // 36 KB bootrom_base 0x1fff0000 -bootrom_size 0x7000 -option_base 0x1fff7800 -option_size 0x4 +bootrom_size 0x7000 // 28 KB +option_base 0x1fff7800 // STM32_G0_OPTION_BYTES_BASE +option_size 0x4 // 4 B flags dualbank - diff --git a/config/chips/G43x_G44x.chip b/config/chips/G43x_G44x.chip index 033f1dd80..455d65b8c 100644 --- a/config/chips/G43x_G44x.chip +++ b/config/chips/G43x_G44x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for G43x/G44x +# Chip-ID file for STM32G43x / STM32G44x device # -chip_id 0x468 -description G43x/G44x -flash_type 8 -flash_pagesize 0x800 -sram_size 0x8000 +dev_type STM32G43x_G44x +ref_manual_id 0440 +chip_id 0x468 // STLINK_CHIPID_STM32_G4_CAT2 +flash_type 8 // STLINK_FLASH_TYPE_G4 +flash_size_reg 0x1fff75e0 +flash_pagesize 0x800 // 2 KB +sram_size 0x8000 // 32 KB bootrom_base 0x1fff0000 -bootrom_size 0x7000 -option_base 0x1ffff800 -option_size 0x4 +bootrom_size 0x7000 // 28 KB +option_base 0x1ffff800 // STM32_G4_OPTION_BYTES_BASE +option_size 0x4 // 4 B flags swo - diff --git a/config/chips/G47x_G48x.chip b/config/chips/G47x_G48x.chip index fa331650f..250905c68 100644 --- a/config/chips/G47x_G48x.chip +++ b/config/chips/G47x_G48x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for G47x/G48x +# Chip-ID file for STM32G47x / STM32G48x device # -chip_id 0x469 -description G47x/G48x -flash_type 8 -flash_pagesize 0x800 -sram_size 0x20000 +dev_type STM32G47x_G48x +ref_manual_id 0440 +chip_id 0x469 // STLINK_CHIPID_STM32_G4_CAT3 +flash_type 8 // STLINK_FLASH_TYPE_G4 +flash_size_reg 0x1fff75e0 +flash_pagesize 0x800 // 2 KB +sram_size 0x20000 // 128 KB bootrom_base 0x1fff0000 -bootrom_size 0x7000 -option_base 0x1ffff800 -option_size 0x4 -flags dualbank swo - +bootrom_size 0x7000 // 28 KB +option_base 0x1ffff800 // STM32_G4_OPTION_BYTES_BASE +option_size 0x4 // 4 B +flags swo dualbank diff --git a/config/chips/G49x_G4Ax.chip b/config/chips/G49x_G4Ax.chip index b764572db..9702541a8 100644 --- a/config/chips/G49x_G4Ax.chip +++ b/config/chips/G49x_G4Ax.chip @@ -1,13 +1,14 @@ -# Chip-ID file for G49x/G4Ax +# Chip-ID file for STM32G49x / STM32G4Ax device # -chip_id 0x479 -description G49x/G4Ax -flash_type 8 -flash_pagesize 0x800 -sram_size 0x1c000 +dev_type STM32G49x_G4Ax +ref_manual_id 0440 +chip_id 0x479 // STLINK_CHIPID_STM32_G4_CAT4 +flash_type 8 // STLINK_FLASH_TYPE_G4 +flash_size_reg 0x1fff75e0 +flash_pagesize 0x800 // 2 KB +sram_size 0x1c000 // 112 KB bootrom_base 0x1fff0000 -bootrom_size 0x7000 -option_base 0x1ffff800 -option_size 0x4 +bootrom_size 0x7000 // 28 KB +option_base 0x1ffff800 // STM32_G4_OPTION_BYTES_BASE +option_size 0x4 // 4 B flags swo - diff --git a/config/chips/H72x_H73x.chip b/config/chips/H72x_H73x.chip index df20037d3..183c7d197 100644 --- a/config/chips/H72x_H73x.chip +++ b/config/chips/H72x_H73x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for H72x/H73x +# Chip-ID file for STM32H72x / STM32H73x device # -chip_id 0x483 -description H72x/H73x -flash_type 10 -flash_pagesize 0x20000 -sram_size 0x20000 +dev_type STM32H72x_H73x +ref_manual_id 0468 +chip_id 0x483 // STLINK_CHIPID_STM32_H72x +flash_type 10 // STLINK_FLASH_TYPE_H7 +flash_size_reg 0x1ff1e880 +flash_pagesize 0x20000 // 128 KB +sram_size 0x20000 // 128 KB "DTCM" bootrom_base 0x1ff00000 -bootrom_size 0x20000 -option_base 0x5200201c -option_size 0x2c +bootrom_size 0x20000 // 128 KB +option_base 0x5200201c // STM32_H7_OPTION_BYTES_BASE +option_size 0x2c // 44 B flags swo - diff --git a/config/chips/H74x_H75x.chip b/config/chips/H74x_H75x.chip index 7a4bc86e3..2e543b197 100644 --- a/config/chips/H74x_H75x.chip +++ b/config/chips/H74x_H75x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for H74x/H75x +# Chip-ID file for STM32H74x / STM32H75x device # -chip_id 0x450 -description H74x/H75x -flash_type 10 -flash_pagesize 0x20000 -sram_size 0x20000 +dev_type STM32H74x_H75x +ref_manual_id 0433 +chip_id 0x450 // STLINK_CHIPID_STM32_H74xxx +flash_type 10 // STLINK_FLASH_TYPE_H7 +flash_size_reg 0x1ff1e880 +flash_pagesize 0x20000 // 128 KB +sram_size 0x20000 // 128 KB "DTCM" bootrom_base 0x1ff00000 -bootrom_size 0x20000 -option_base 0x5200201c -option_size 0x2c -flags dualbank swo - +bootrom_size 0x20000 // 128 KB +option_base 0x5200201c // STM32_H7_OPTION_BYTES_BASE +option_size 0x2c // 44 B /* FLASH_OPTSR_CUR to FLASH_BOOT_PRGR */ +flags swo dualbank diff --git a/config/chips/H7Ax_H7Bx.chip b/config/chips/H7Ax_H7Bx.chip index b9202bd1a..b5fe72119 100644 --- a/config/chips/H7Ax_H7Bx.chip +++ b/config/chips/H7Ax_H7Bx.chip @@ -1,13 +1,14 @@ -# Chip-ID file for H7Ax/H7Bx +# Chip-ID file for STM32H7Ax / STM32H7Bx device # -chip_id 0x480 -description H7Ax/H7Bx -flash_type 10 -flash_pagesize 0x2000 -sram_size 0x20000 +dev_type STM32H7Ax_H7Bx +ref_manual_id 0455 +chip_id 0x480 // STLINK_CHIPID_STM32_H7Ax +flash_type 10 // STLINK_FLASH_TYPE_H7 +flash_size_reg 0x08fff80c +flash_pagesize 0x2000 // 8 KB +sram_size 0x20000 // 128 KB "DTCM" bootrom_base 0x1ff00000 -bootrom_size 0x20000 -option_base 0x5200201c -option_size 0x2c -flags dualbank swo - +bootrom_size 0x20000 // 128 KB +option_base 0x5200201c // STM32_H7_OPTION_BYTES_BASE +option_size 0x2c // 44 B +flags swo dualbank diff --git a/config/chips/L01x_L02x.chip b/config/chips/L01x_L02x.chip deleted file mode 100644 index c3d2074b9..000000000 --- a/config/chips/L01x_L02x.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for L01x/L02x -# -chip_id 0x457 -description L01x/L02x -flash_type 5 -flash_pagesize 0x80 -sram_size 0x2000 -bootrom_base 0x1ff00000 -bootrom_size 0x2000 -option_base 0x0 -option_size 0x0 -flags none - diff --git a/config/chips/L0xx_Cat_2.chip b/config/chips/L0xx_Cat_2.chip deleted file mode 100644 index 47183b8ef..000000000 --- a/config/chips/L0xx_Cat_2.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for L0xx Cat.2 -# -chip_id 0x425 -description L0xx Cat.2 -flash_type 5 -flash_pagesize 0x80 -sram_size 0x2000 -bootrom_base 0x1ff0000 -bootrom_size 0x1000 -option_base 0x1ff80000 -option_size 0x14 -flags none - diff --git a/config/chips/L0xx_Cat_3.chip b/config/chips/L0xx_Cat_3.chip deleted file mode 100644 index 6d9fcc105..000000000 --- a/config/chips/L0xx_Cat_3.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for L0xx Cat.3 -# -chip_id 0x417 -description L0xx Cat.3 -flash_type 5 -flash_pagesize 0x80 -sram_size 0x2000 -bootrom_base 0x1ff0000 -bootrom_size 0x1000 -option_base 0x1ff80000 -option_size 0x14 -flags none - diff --git a/config/chips/L0xx_Cat_5.chip b/config/chips/L0xx_Cat_5.chip deleted file mode 100644 index 545c1c2ef..000000000 --- a/config/chips/L0xx_Cat_5.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for L0xx Cat.5 -# -chip_id 0x447 -description L0xx Cat.5 -flash_type 5 -flash_pagesize 0x80 -sram_size 0x5000 -bootrom_base 0x1ff0000 -bootrom_size 0x2000 -option_base 0x1ff80000 -option_size 0x14 -flags dualbank - diff --git a/config/chips/L0xxx_Cat_1.chip b/config/chips/L0xxx_Cat_1.chip new file mode 100644 index 000000000..1dd8a1acb --- /dev/null +++ b/config/chips/L0xxx_Cat_1.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32L0xxx (Cat.1) device (L010x3 / L010x4 / L011x / L021x) +# +dev_type STM32L0xxx_Cat_1 +ref_manual_id 0451 // also RM0377 +chip_id 0x457 // STLINK_CHIPID_STM32_L011 +flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_size_reg 0x1ff8007c +flash_pagesize 0x80 // 128 B +sram_size 0x2000 // 8 KB +bootrom_base 0x1ff00000 +bootrom_size 0x2000 // 8 KB +option_base 0x1ff80000 // STM32_L0_OPTION_BYTES_BASE +option_size 0x20 // 32 B +flags none diff --git a/config/chips/L0xxx_Cat_2.chip b/config/chips/L0xxx_Cat_2.chip new file mode 100644 index 000000000..58d6439ba --- /dev/null +++ b/config/chips/L0xxx_Cat_2.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32L0xxx (Cat.2) device (L010x6 / L031x / L041x) +# +dev_type STM32L0xxx_Cat_2 +ref_manual_id 0451 // also RM0377 +chip_id 0x425 // STLINK_CHIPID_STM32_L0_CAT2 +flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_size_reg 0x1ff8007c +flash_pagesize 0x80 // 128 B +sram_size 0x2000 // 8 KB +bootrom_base 0x1ff00000 +bootrom_size 0x1000 // 4 KB +option_base 0x1ff80000 // STM32_L0_OPTION_BYTES_BASE +option_size 0x20 // 32 B +flags none diff --git a/config/chips/L0xxx_Cat_3.chip b/config/chips/L0xxx_Cat_3.chip new file mode 100644 index 000000000..406c1a037 --- /dev/null +++ b/config/chips/L0xxx_Cat_3.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32L0xxx (Cat.3) device (L010x8 / L051x / L053x / L063x) +# +dev_type STM32L0xxx_Cat_3 +ref_manual_id 0451 // also RM0367 & RM0377 +chip_id 0x417 // STLINK_CHIPID_STM32_L0 +flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_size_reg 0x1ff8007c +flash_pagesize 0x80 // 128 B +sram_size 0x2000 // 8 KB +bootrom_base 0x1ff00000 +bootrom_size 0x1000 // 4 KB +option_base 0x1ff80000 // STM32_L0_OPTION_BYTES_BASE +option_size 0x20 // 32 B +flags none diff --git a/config/chips/L0xxx_Cat_5.chip b/config/chips/L0xxx_Cat_5.chip new file mode 100644 index 000000000..1a0c387a7 --- /dev/null +++ b/config/chips/L0xxx_Cat_5.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32L0xxx (Cat.5) device (L010xB / L071x / L081x / L073x / L083x) +# +dev_type STM32L0xxx_Cat_5 +ref_manual_id 0451 // also RM0367 & RM0377 +chip_id 0x447 // STLINK_CHIPID_STM32_L0_CAT5 +flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_size_reg 0x1ff8007c +flash_pagesize 0x80 // 128 B +sram_size 0x5000 // 20 KB +bootrom_base 0x1ff00000 +bootrom_size 0x2000 // 8 KB +option_base 0x1ff80000 // STM32_L0_OPTION_BYTES_BASE +option_size 0x20 // 32 B +flags dualbank diff --git a/config/chips/L5x5.chip b/config/chips/L5x5.chip new file mode 100644 index 000000000..ce268148b --- /dev/null +++ b/config/chips/L5x5.chip @@ -0,0 +1,15 @@ +# Chip-ID file for STM32L5x2 device +# +dev_type STM32L5x2 +ref_manual_id 0438 +chip_id 0x0 // (temporary setting only!) +flash_type 0 // (temporary setting only!) +flash_size_reg 0x0bfa07a0 +flash_pagesize 0x2000 // 8 KB +sram_size 0x40000 // 256 KB +bootrom_base 0x0bf90000 +bootrom_size 0x8000 // 32 KB +option_base 0x0 +option_size 0x0 +flags none + diff --git a/config/chips/U5x5.chip b/config/chips/U5x5.chip new file mode 100644 index 000000000..177359cc3 --- /dev/null +++ b/config/chips/U5x5.chip @@ -0,0 +1,15 @@ +# Chip-ID file for STM32U5x5 device +# +dev_type STM32U5x5 +ref_manual_id 0456 +chip_id 0x0 // (temporary setting only!) +flash_type 0 // (temporary setting only!) +flash_size_reg 0x0bfa07a0 +flash_pagesize 0x2000 // 8 KB +sram_size 0xc4800 // 786 KB +bootrom_base 0x0bf90000 +bootrom_size 0x8000 // 32 KB +option_base 0x0 +option_size 0x0 +flags none + diff --git a/config/chips/WBx0_WBx5.chip b/config/chips/WBx0_WBx5.chip new file mode 100644 index 000000000..ba5fee778 --- /dev/null +++ b/config/chips/WBx0_WBx5.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32WBx0 / STM32WBx5 device +# +dev_type STM32WBx0_WBx5 +ref_manual_id 0434 // also RM0471 +chip_id 0x495 // STLINK_CHIPID_STM32_WB55 +flash_type 9 // STLINK_FLASH_TYPE_WB +flash_size_reg 0x1fff75e0 +flash_pagesize 0x1000 // 4 KB +sram_size 0x40000 // 256 KB +bootrom_base 0x1fff0000 +bootrom_size 0x7000 // 28 KB +option_base 0x1fff8000 +option_size 0x80 // 128 B +flags swo diff --git a/config/chips/WBx5_WBx0.chip b/config/chips/WBx5_WBx0.chip deleted file mode 100644 index 5bd2501e6..000000000 --- a/config/chips/WBx5_WBx0.chip +++ /dev/null @@ -1,14 +0,0 @@ -# Chip-ID file for STM32WBx0 device (STM32WB55xx, STM32WB35xx, STM32WB50CG, STM32WB30CE) -# -dev_type STM32WBx0 device -ref_manual_id 0434 // also RM0471 -chip_id 0x495 // STLINK_CHIPID_STM32_WB55 -flash_type 9 // STLINK_FLASH_TYPE_WB -flash_size_reg 0x1fff75e0 -flash_pagesize 0x1000 // 4k -sram_size 0x40000 -bootrom_base 0x1fff0000 -bootrom_size 0x7000 -option_base 0x0 -option_size 0x0 -flags swo diff --git a/config/chips/WLEx.chip b/config/chips/WLx5.chip similarity index 54% rename from config/chips/WLEx.chip rename to config/chips/WLx5.chip index e9b6248f6..2dc9ce648 100644 --- a/config/chips/WLEx.chip +++ b/config/chips/WLx5.chip @@ -1,14 +1,14 @@ # Chip-ID file for STM32WLEx device # -dev_type STM32WLEx device +dev_type STM32WLEx ref_manual_id 0033 chip_id 0x497 // STLINK_CHIPID_STM32_WLE flash_type 9 // STLINK_FLASH_TYPE_WB flash_size_reg 0x1fff75e0 -flash_pagesize 0x800 // 2k -sram_size 0x10000 +flash_pagesize 0x800 // 2 KB +sram_size 0x10000 // 64 KB bootrom_base 0x1fff0000 -bootrom_size 0x7000 -option_base 0x0 -option_size 0x0 +bootrom_size 0x7000 // 28 KB +option_base 0x1fffc000 +option_size 0x10 // 16 B flags swo diff --git a/config/chips/unknown_device.chip b/config/chips/unknown_device.chip index 8f3772e53..1b74f22fa 100644 --- a/config/chips/unknown_device.chip +++ b/config/chips/unknown_device.chip @@ -1,6 +1,6 @@ # Chip-ID file for unknown device # -dev_type unknown device +dev_type unknown ref_manual_id 0000 chip_id 0x0 // STLINK_CHIPID_UNKNOWN flash_type 0 // STLINK_FLASH_TYPE_UNKNOWN diff --git a/inc/stm32.h b/inc/stm32.h index 21da2f563..15e0ff147 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -16,19 +16,24 @@ /* Constant STM32 memory map figures */ #define STM32_SRAM_BASE ((uint32_t)0x20000000) #define STM32_FLASH_BASE ((uint32_t)0x08000000) + #define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) + #define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) -#define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) #define STM32_F4_OPTION_BYTES_BASE ((uint32_t)0x40023C14) -#define STM32_F7_OPTION_BYTES_BASE ((uint32_t)0x1FFF0000) + #define STM32_H7_OPTION_BYTES_BASE ((uint32_t)0x5200201C) +#define STM32_L0_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) +#define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) + +#define STM32_F7_OPTION_BYTES_BASE ((uint32_t)0x1FFF0000) + #define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) -#define STM32_L0_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) -#define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) +#define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) #define STM32_F0_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) #define STM32_F1_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 3dd82a1b2..213d43f8c 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -28,8 +28,8 @@ void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { fprintf(fp, "# Reference Manual: RM%s\n", dev->ref_manual_id); fprintf(fp, "#\n"); fprintf(fp, "chip_id 0x%x\n", dev->chip_id); - fprintf(fp, "flash_type %d\n", dev->flash_type); - fprintf(fp, "flash_size_reg %x\n", dev->flash_size_reg); + fprintf(fp, "flash_type %d\n", dev->flash_type); + fprintf(fp, "flash_size_reg 0x%x\n", dev->flash_size_reg); fprintf(fp, "flash_pagesize 0x%x\n", dev->flash_pagesize); fprintf(fp, "sram_size 0x%x\n", dev->sram_size); fprintf(fp, "bootrom_base 0x%x\n", dev->bootrom_base); @@ -42,8 +42,8 @@ void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { static int chipid_params_eq(const struct stlink_chipid_params *p1, const struct stlink_chipid_params *p2) { return p1->chip_id == p2->chip_id && - p1->description && p2->description && - strcmp(p1->description, p2->description) == 0 && + p1->dev_type && p2->dev_type && + strcmp(p1->dev_type, p2->dev_type) == 0 && p1->flash_type == p2->flash_type && p1->flash_size_reg == p2->flash_size_reg && p1->flash_pagesize == p2->flash_pagesize && @@ -205,8 +205,8 @@ void dump_chips (void) { fprintf(fp, "# Reference Manual: RM%s\n", ts->ref_manual_id); fprintf(fp, "#\n"); fprintf(fp, "chip_id %x\n", ts->chip_id); - fprintf(fp, "flash_type %x\n", ts->flash_type); - fprintf(fp, "flash_size_reg %x\n", ts->flash_size_reg); + fprintf(fp, "flash_type %x\n", ts->flash_type); + fprintf(fp, "flash_size_reg %x\n", ts->flash_size_reg); fprintf(fp, "flash_pagesize %x\n", ts->flash_pagesize); fprintf(fp, "sram_size %x\n", ts->sram_size); fprintf(fp, "bootrom_base %x\n", ts->bootrom_base); diff --git a/src/stlink-lib/chipid_db_old.h b/src/stlink-lib/chipid_db_old.h index bc6491ad4..b86b13289 100644 --- a/src/stlink-lib/chipid_db_old.h +++ b/src/stlink-lib/chipid_db_old.h @@ -6,123 +6,6 @@ // config/chips/*.chip file. static struct stlink_chipid_params devices[] = { - { - // STM32F76x/F77x - // RM0410 - .chip_id = STLINK_CHIPID_STM32_F76xxx, - .dev_type = "F76x/F77x", - .flash_type = STLINK_FLASH_TYPE_F7, - .flash_size_reg = 0x1ff0f442, // section 45.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x80000, // "SRAM" byte size in hex from - .bootrom_base = 0x00200000, // "System memory" starting address from - .bootrom_size = 0xEDC0, - .option_base = STM32_F7_OPTION_BYTES_BASE, /* Used for reading back the option - bytes, writing uses FLASH_F7_OPTCR - and FLASH_F7_OPTCR1 */ - .option_size = 0x20, - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F74x/F75x - // RM0385, DS10916 - .chip_id = STLINK_CHIPID_STM32_F7, - .dev_type = "F74x/F75x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff0f442, // section 41.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 - .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 18 - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F72x/F73x - // RM0431 - .chip_id = STLINK_CHIPID_STM32_F72xxx, - .dev_type = "F72x/F73x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff07a22, // section 35.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 - .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 24 - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F4x5/F4x7 - // RM0090 (rev 2) - .chip_id = STLINK_CHIPID_STM32_F4, - .dev_type = "F4x5/F4x7", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x30000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .option_base = STM32_F4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F46x/F47x - // RM0090 (rev 2) - .chip_id = STLINK_CHIPID_STM32_F4_DSI, - .dev_type = "F46x/F47x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x40000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F42x/F43x - // RM0090 (rev 2) - .chip_id = STLINK_CHIPID_STM32_F4_HD, - .dev_type = "F42x/F43x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x40000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - .chip_id = STLINK_CHIPID_STM32_F4_LP, - .dev_type = "F401xB/C", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x10000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - .chip_id = STLINK_CHIPID_STM32_F411xx, - .dev_type = "F411xC/E", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - .chip_id = STLINK_CHIPID_STM32_F4_DE, - .dev_type = "F401xD/E", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, { // STM32L100/L15x/L16x Cat.1 // RM0038 @@ -191,130 +74,137 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32F446x family - // RM0390 - .chip_id = STLINK_CHIPID_STM32_F446, - .dev_type = "F446", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, - .flash_pagesize = 0x20000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .option_base = 0x1FFFC000, + // STM32L47x/L48x + // RM0351 + .chip_id = STLINK_CHIPID_STM32_L4, + .dev_type = "L47x/L48x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 + // and tables 4-6 on pages 79-81) + // SRAM1 is "up to" 96k in the standard Cortex-M memory map; + // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) + .sram_size = 0x18000, + .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32F410 - // RM0401 - .chip_id = STLINK_CHIPID_STM32_F410, - .dev_type = "F410", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, - .flash_pagesize = 0x4000, - .sram_size = 0x8000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, + // STM32L4RX + // RM0432 + .chip_id = STLINK_CHIPID_STM32_L4Rx, + .dev_type = "L4Rx", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) + .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 + // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size + .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 + .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 + .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { - // STM32F303xB/C, STM32F358, STM32F302xBxC - // RM0316, RM0365 - .chip_id = STLINK_CHIPID_STM32_F3, - .dev_type = "F302/F303/F358", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, + // STM32L4PX + // RM0432 + .chip_id = STLINK_CHIPID_STM32_L4PX, + .dev_type = "L4Px", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) + .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 + // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size + .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 + .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 + .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { - // STM32F373Cx/Rx/Vx, STM32F378Cx/Rx/Vx - // RM0313 - .chip_id = STLINK_CHIPID_STM32_F37x, - .dev_type = "F37x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, + // STLINK_CHIPID_STM32_L41x_L42x + // RM0394 (rev 4), DS12469 (rev 5) + .chip_id = STLINK_CHIPID_STM32_L41x_L42x, + .dev_type = "L41x/L42x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, + // sec 47.2, page 1586) + .flash_pagesize = 0x800, // 2k (DS12469, sec 3.4, page 17) + // SRAM1 is 32k at 0x20000000 + // SRAM2 is 8k at 0x10000000 and 0x20008000 + // (DS12469, sec 3.5, page 18) + .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) + .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) + .bootrom_size = 0x7000, // 28k, same source as base .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32F07x - // RM0091 - .chip_id = STLINK_CHIPID_STM32_F0_CAN, - .dev_type = "F07x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 - .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 - .bootrom_size = 0x3000, // "System memory" byte size in hex from Table 2 - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, + // STLINK_CHIPID_STM32_L43x_L44x + // RM0392 + .chip_id = STLINK_CHIPID_STM32_L43x_L44x, + .dev_type = "L43x/L44x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 + // and tables 7-8 on pages 75-76) + // SRAM1 is "up to" 64k in the standard Cortex-M memory map; + // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) + .sram_size = 0xc000, + .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32F05x - // RM0091 - .chip_id = STLINK_CHIPID_STM32_F0, - .dev_type = "F05x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - }, - { - // STM32F412 - // RM0402 - .chip_id = STLINK_CHIPID_STM32_F412, - .dev_type = "F412", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) - .flash_pagesize = 0x4000, // Table 5. Flash module organization ? - .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 - .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 + // STLINK_CHIPID_STM32_L496x_L4A6x + // RM0351 (rev 5) + .chip_id = STLINK_CHIPID_STM32_L496x_L4A6x, + .dev_type = "L496x/L4A6x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) + .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) + // SRAM1 is 256k at 0x20000000 + // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) + .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) + .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32F413/F423 - // RM0430 (rev 2) - .chip_id = STLINK_CHIPID_STM32_F413, - .dev_type = "F413/F423", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 - .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector - // sizes, but 0x4000 is smallest) - .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 - // only says 0x40000) - .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 + // STLINK_CHIPID_STM32_L45x_L46x + // RM0394 (updated version of RM0392?) + .chip_id = STLINK_CHIPID_STM32_L45x_L46x, + .dev_type = "L45x/46x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 + // and tables 7 on pages 73-74) + // SRAM1 is 128k at 0x20000000; + // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, + // page 68, also fig 2 on page 63) + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system + // memory, also fig 2 on page 63) + .bootrom_size = 0x7000, // 28k (per bank), same source as base .flags = CHIP_F_HAS_SWO_TRACING, }, +// ######################################################################## +// ######################################################################## +// ######################################################################## { - // STM32F09x + // STM32F03x // RM0091 - .chip_id = STLINK_CHIPID_STM32_F09x, - .dev_type = "F09x", + .chip_id = STLINK_CHIPID_STM32_F0xx_SMALL, + .dev_type = "F03x", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) - .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) - .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 - .bootrom_size = 0x2000, // "System memory" byte size in hex from Table 2 + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 .option_base = STM32_F0_OPTION_BYTES_BASE, .option_size = 16, }, @@ -333,19 +223,165 @@ static struct stlink_chipid_params devices[] = { .option_size = 16, }, { - // STM32F03x + // STM32F05x // RM0091 - .chip_id = STLINK_CHIPID_STM32_F0xx_SMALL, - .dev_type = "F03x", + .chip_id = STLINK_CHIPID_STM32_F0, + .dev_type = "F05x", .flash_type = STLINK_FLASH_TYPE_F0, .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 + .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 .option_base = STM32_F0_OPTION_BYTES_BASE, .option_size = 16, }, + { + // STM32F07x + // RM0091 + .chip_id = STLINK_CHIPID_STM32_F0_CAN, + .dev_type = "F07x", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 + .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 + .bootrom_size = 0x3000, // "System memory" byte size in hex from Table 2 + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + }, + { + // STM32F09x + // RM0091 + .chip_id = STLINK_CHIPID_STM32_F09x, + .dev_type = "F09x", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) + .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) + .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 + .bootrom_size = 0x2000, // "System memory" byte size in hex from Table 2 + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + }, + { + // STM32F1xx low- and medium-density value line devices + // RM0041 + .chip_id = STLINK_CHIPID_STM32_F1_VL_MD_LD, + .dev_type = "F1xx Value Line", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2000, // 0x1000 for low density devices + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F1xx high-density value line devices + // RM0041 + .chip_id = STLINK_CHIPID_STM32_F1_VL_HD, + .dev_type = "F1xx High-density value line", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x8000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F1xx low-density devices + // RM0008 + .chip_id = STLINK_CHIPID_STM32_F1_LD, + .dev_type = "F1 Low-density device", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2800, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F1xx medium-density devices + // RM0008 + .chip_id = STLINK_CHIPID_STM32_F1_MD, + .dev_type = "F1xx Medium-density", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x5000, + .bootrom_base = 0x1ffff000, // 2.3.3 "Embedded Flash memory" + .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F1xx high-density devices + // RM0008 + .chip_id = STLINK_CHIPID_STM32_F1_HD, + .dev_type = "F1xx High-density", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F1xx XL-density devices + // RM0008 + .chip_id = STLINK_CHIPID_STM32_F1_XLD, + .dev_type = "F1xx XL-density", + .flash_type = STLINK_FLASH_TYPE_F1_XL, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x18000, + .bootrom_base = 0x1fffe000, + .bootrom_size = 0x1800, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F1xx connectivity devices + // RM0008 + .chip_id = STLINK_CHIPID_STM32_F1_CONN, + .dev_type = "F1xx CL", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1fffb000, + .bootrom_size = 0x4800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F205xx, STM32F207xx, STM32F215xx, STM32F217xx + // RM0033 (rev 5) + .chip_id = STLINK_CHIPID_STM32_F2, + .dev_type = "F2xx", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1fff7a22, + .flash_pagesize = 0x20000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .option_base = 0x1FFFC000, + .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, + }, { // STM32F301x6/8, STM32F302x6x8, STM32F318x8 // RM0366, RM0365 @@ -362,50 +398,37 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32L0xx Category 3 - // RM0367, RM0377, RM0451 - .chip_id = STLINK_CHIPID_STM32_L0, - .dev_type = "L0xx Cat.3", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000, - .option_base = STM32_L0_OPTION_BYTES_BASE, - .option_size = 20, + // STM32F302xBxC, STM32F303xB/C, STM32F358 + // RM0316, RM0365 + .chip_id = STLINK_CHIPID_STM32_F3, + .dev_type = "F302/F303/F358", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32L0x Category 5 - // RM0367, RM0377, RM0451 - .chip_id = STLINK_CHIPID_STM32_L0_CAT5, - .dev_type = "L0xx Cat.5", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x5000, - .bootrom_base = 0x1ff0000, + // STM32F302xD/E, STM32F303xD/E, STM32F398xE, + // RM0316 (rev 5), RM0365 + .chip_id = STLINK_CHIPID_STM32_F303_HD, + .dev_type = "F303 high density", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register + .flash_pagesize = 0x800, // 4.2.1 Flash memory organization + .sram_size = 0x10000, // 3.3 Embedded SRAM + .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory .bootrom_size = 0x2000, - .option_base = STM32_L0_OPTION_BYTES_BASE, - .option_size = 20, - .flags = CHIP_F_HAS_DUAL_BANK, - }, - { - // STM32L0x Category 2 - // RM0367, RM0377 - .chip_id = STLINK_CHIPID_STM32_L0_CAT2, - .dev_type = "L0xx Cat.2", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000, - .option_base = STM32_L0_OPTION_BYTES_BASE, - .option_size = 20, + .option_base = STM32_F0_OPTION_BYTES_BASE, + .option_size = 16, + .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32F334, STM32F303x6/8, STM32F328 + // STM32F303x6/8, STM32F328, STM32F334 // RM0364, RM0316 .chip_id = STLINK_CHIPID_STM32_F334, .dev_type = "F303/F328/F334", // (RM0316 sec 33.6.1) @@ -420,149 +443,192 @@ static struct stlink_chipid_params devices[] = { .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32F303xD/E, STM32F398xE, STM32F302xD/E - // RM0316 (rev 5), RM0365 - .chip_id = STLINK_CHIPID_STM32_F303_HD, - .dev_type = "F303 high density", + // STM32F373Cx/Rx/Vx, STM32F378Cx/Rx/Vx + // RM0313 + .chip_id = STLINK_CHIPID_STM32_F37x, + .dev_type = "F37x", .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register - .flash_pagesize = 0x800, // 4.2.1 Flash memory organization - .sram_size = 0x10000, // 3.3 Embedded SRAM - .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory - .bootrom_size = 0x2000, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800, .option_base = STM32_F0_OPTION_BYTES_BASE, .option_size = 16, .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32L47x/L48x - // RM0351 - .chip_id = STLINK_CHIPID_STM32_L4, - .dev_type = "L47x/L48x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 - // and tables 4-6 on pages 79-81) - // SRAM1 is "up to" 96k in the standard Cortex-M memory map; - // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) + .chip_id = STLINK_CHIPID_STM32_F4_LP, + .dev_type = "F401xB/C", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x10000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + .chip_id = STLINK_CHIPID_STM32_F4_DE, + .dev_type = "F401xD/E", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, - .option_size = 4, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32L4RX - // RM0432 - .chip_id = STLINK_CHIPID_STM32_L4Rx, - .dev_type = "L4Rx", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) - .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 - // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size - .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 - .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 - .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, + // STM32F410 + // RM0401 + .chip_id = STLINK_CHIPID_STM32_F410, + .dev_type = "F410", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1fff7a22, + .flash_pagesize = 0x4000, + .sram_size = 0x8000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32L4PX - // RM0432 - .chip_id = STLINK_CHIPID_STM32_L4PX, - .dev_type = "L4Px", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) - .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 - // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size - .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 - .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 - .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, + .chip_id = STLINK_CHIPID_STM32_F411xx, + .dev_type = "F411xC/E", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STLINK_CHIPID_STM32_L41x_L42x - // RM0394 (rev 4), DS12469 (rev 5) - .chip_id = STLINK_CHIPID_STM32_L41x_L42x, - .dev_type = "L41x/L42x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, - // sec 47.2, page 1586) - .flash_pagesize = 0x800, // 2k (DS12469, sec 3.4, page 17) - // SRAM1 is 32k at 0x20000000 - // SRAM2 is 8k at 0x10000000 and 0x20008000 - // (DS12469, sec 3.5, page 18) - .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) - .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) - .bootrom_size = 0x7000, // 28k, same source as base + // STM32F412 + // RM0402 + .chip_id = STLINK_CHIPID_STM32_F412, + .dev_type = "F412", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) + .flash_pagesize = 0x4000, // Table 5. Flash module organization ? + .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 + .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 + .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STLINK_CHIPID_STM32_L43x_L44x - // RM0392 - .chip_id = STLINK_CHIPID_STM32_L43x_L44x, - .dev_type = "L43x/L44x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 - // and tables 7-8 on pages 75-76) - // SRAM1 is "up to" 64k in the standard Cortex-M memory map; - // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) - .sram_size = 0xc000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, + // STM32F413/F423 + // RM0430 (rev 2) + .chip_id = STLINK_CHIPID_STM32_F413, + .dev_type = "F413/F423", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 + .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector + // sizes, but 0x4000 is smallest) + .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 + // only says 0x40000) + .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 + .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F42x/F43x + // RM0090 (rev 2) + .chip_id = STLINK_CHIPID_STM32_F4_HD, + .dev_type = "F42x/F43x", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x40000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F446x family + // RM0390 + .chip_id = STLINK_CHIPID_STM32_F446, + .dev_type = "F446", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1fff7a22, + .flash_pagesize = 0x20000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .option_base = 0x1FFFC000, .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STLINK_CHIPID_STM32_L496x_L4A6x - // RM0351 (rev 5) - .chip_id = STLINK_CHIPID_STM32_L496x_L4A6x, - .dev_type = "L496x/L4A6x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) - .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) - // SRAM1 is 256k at 0x20000000 - // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) - .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) - .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, + // STM32F46x/F47x + // RM0090 (rev 2) + .chip_id = STLINK_CHIPID_STM32_F4_DSI, + .dev_type = "F46x/F47x", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x40000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F4x5/F4x7 + // RM0090 (rev 2) + .chip_id = STLINK_CHIPID_STM32_F4, + .dev_type = "F4x5/F4x7", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x30000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800, + .option_base = STM32_F4_OPTION_BYTES_BASE, .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STLINK_CHIPID_STM32_L45x_L46x - // RM0394 (updated version of RM0392?) - .chip_id = STLINK_CHIPID_STM32_L45x_L46x, - .dev_type = "L45x/46x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 - // and tables 7 on pages 73-74) - // SRAM1 is 128k at 0x20000000; - // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, - // page 68, also fig 2 on page 63) - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system - // memory, also fig 2 on page 63) - .bootrom_size = 0x7000, // 28k (per bank), same source as base + // STM32F72x/F73x + // RM0431 + .chip_id = STLINK_CHIPID_STM32_F72xxx, + .dev_type = "F72x/F73x", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1ff07a22, // section 35.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 + .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 + .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 24 + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32F74x/F75x + // RM0385, DS10916 + .chip_id = STLINK_CHIPID_STM32_F7, + .dev_type = "F74x/F75x", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1ff0f442, // section 41.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 + .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 + .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 18 .flags = CHIP_F_HAS_SWO_TRACING, }, { - // STM32L0xx Category 1 - // RM0451, RM0377 - .chip_id = STLINK_CHIPID_STM32_L011, - .dev_type = "L01x/L02x", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x2000, + // STM32F76x/F77x + // RM0410 + .chip_id = STLINK_CHIPID_STM32_F76xxx, + .dev_type = "F76x/F77x", + .flash_type = STLINK_FLASH_TYPE_F7, + .flash_size_reg = 0x1ff0f442, // section 45.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x80000, // "SRAM" byte size in hex from + .bootrom_base = 0x00200000, // "System memory" starting address from + .bootrom_size = 0xEDC0, + .option_base = STM32_F7_OPTION_BYTES_BASE, /* Used for reading back the option + bytes, writing uses FLASH_F7_OPTCR + and FLASH_F7_OPTCR1 */ + .option_size = 0x20, + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { // STM32G030/031/041 @@ -579,10 +645,10 @@ static struct stlink_chipid_params devices[] = { .option_size = 4, }, { - // STM32G071/081 + // STM32G051/G061 // RM0444 - .chip_id = STLINK_CHIPID_STM32_G0_CAT2, - .dev_type = "G07x/G08x", + .chip_id = STLINK_CHIPID_STM32_G0_CAT4, + .dev_type = "G05x/G06x", .flash_type = STLINK_FLASH_TYPE_G0, .flash_size_reg = 0x1FFF75E0, // Section 38.2 .flash_pagesize = 0x800, // 2k (sec 3.2) @@ -593,10 +659,10 @@ static struct stlink_chipid_params devices[] = { .option_size = 4, }, { - // STM32G0B1/G0C1 + // STM32G071/081 // RM0444 - .chip_id = STLINK_CHIPID_STM32_G0_CAT3, - .dev_type = "G0Bx/G0Cx", + .chip_id = STLINK_CHIPID_STM32_G0_CAT2, + .dev_type = "G07x/G08x", .flash_type = STLINK_FLASH_TYPE_G0, .flash_size_reg = 0x1FFF75E0, // Section 38.2 .flash_pagesize = 0x800, // 2k (sec 3.2) @@ -605,13 +671,12 @@ static struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) .option_base = STM32_G0_OPTION_BYTES_BASE, .option_size = 4, - .flags = CHIP_F_HAS_DUAL_BANK, }, { - // STM32G051/G061 + // STM32G0B1/G0C1 // RM0444 - .chip_id = STLINK_CHIPID_STM32_G0_CAT4, - .dev_type = "G05x/G06x", + .chip_id = STLINK_CHIPID_STM32_G0_CAT3, + .dev_type = "G0Bx/G0Cx", .flash_type = STLINK_FLASH_TYPE_G0, .flash_size_reg = 0x1FFF75E0, // Section 38.2 .flash_pagesize = 0x800, // 2k (sec 3.2) @@ -620,6 +685,7 @@ static struct stlink_chipid_params devices[] = { .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) .option_base = STM32_G0_OPTION_BYTES_BASE, .option_size = 4, + .flags = CHIP_F_HAS_DUAL_BANK, }, { // STM32G431/441 @@ -675,20 +741,6 @@ static struct stlink_chipid_params devices[] = { .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, }, - { - // STM32H742/743/753 (from RM0433) - .chip_id = STLINK_CHIPID_STM32_H74xxx, - .dev_type = "H74x/H75x", - .flash_type = STLINK_FLASH_TYPE_H7, - .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) - .flash_pagesize = 0x20000, // 128k sector (pg147) - .sram_size = 0x20000, // 128k "DTCM" from Table 7 - .bootrom_base = 0x1ff00000, // "System memory" starting address from Table 7 - .bootrom_size = 0x20000, // "System memory" byte size in hex from Table 7 - .option_base = STM32_H7_OPTION_BYTES_BASE, - .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, { // STM32H7A3/7B3 // RM0455 @@ -720,125 +772,74 @@ static struct stlink_chipid_params devices[] = { .option_size = 44, .flags = CHIP_F_HAS_SWO_TRACING, }, - - - { - // STM32F1xx medium-density devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_MD, - .dev_type = "F1xx Medium-density", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x5000, - .bootrom_base = 0x1ffff000, // 2.3.3 "Embedded Flash memory" - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F205xx, STM32F207xx, STM32F215xx, STM32F217xx - // RM0033 (rev 5) - .chip_id = STLINK_CHIPID_STM32_F2, - .dev_type = "F2xx", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, - .flash_pagesize = 0x20000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .option_base = 0x1FFFC000, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F1xx low-density devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_LD, - .dev_type = "F1 Low-density device", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2800, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, { - // STM32F1xx high-density devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_HD, - .dev_type = "F1xx High-density", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, + // STM32H742/743/753 (from RM0433) + .chip_id = STLINK_CHIPID_STM32_H74xxx, + .dev_type = "H74x/H75x", + .flash_type = STLINK_FLASH_TYPE_H7, + .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) + .flash_pagesize = 0x20000, // 128k sector (pg147) + .sram_size = 0x20000, // 128k "DTCM" from Table 7 + .bootrom_base = 0x1ff00000, // "System memory" starting address from Table 7 + .bootrom_size = 0x20000, // "System memory" byte size in hex from Table 7 + .option_base = STM32_H7_OPTION_BYTES_BASE, + .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { - // STM32F1xx connectivity devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_CONN, - .dev_type = "F1xx CL", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1fffb000, - .bootrom_size = 0x4800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, + // STM32L0xx Category 1 + // RM0451, RM0377 + .chip_id = STLINK_CHIPID_STM32_L011, + .dev_type = "L01x/L02x", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x2000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x2000, }, { - // STM32F1xx low- and medium-density value line devices - // RM0041 - .chip_id = STLINK_CHIPID_STM32_F1_VL_MD_LD, - .dev_type = "F1xx Value Line", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2000, // 0x1000 for low density devices - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, + // STM32L0x Category 2 + // RM0367, RM0377 + .chip_id = STLINK_CHIPID_STM32_L0_CAT2, + .dev_type = "L0xx Cat.2", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x2000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x1000, + .option_base = STM32_L0_OPTION_BYTES_BASE, + .option_size = 20, }, { - // STM32F1xx high-density value line devices - // RM0041 - .chip_id = STLINK_CHIPID_STM32_F1_VL_HD, - .dev_type = "F1xx High-density value line", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x8000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, + // STM32L0xx Category 3 + // RM0367, RM0377, RM0451 + .chip_id = STLINK_CHIPID_STM32_L0, + .dev_type = "L0xx Cat.3", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x2000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x1000, + .option_base = STM32_L0_OPTION_BYTES_BASE, + .option_size = 20, }, { - // STM32F1xx XL-density devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_XLD, - .dev_type = "F1xx XL-density", - .flash_type = STLINK_FLASH_TYPE_F1_XL, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x18000, - .bootrom_base = 0x1fffe000, - .bootrom_size = 0x1800, - .flags = CHIP_F_HAS_SWO_TRACING, + // STM32L0x Category 5 + // RM0367, RM0377, RM0451 + .chip_id = STLINK_CHIPID_STM32_L0_CAT5, + .dev_type = "L0xx Cat.5", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x5000, + .bootrom_base = 0x1ff0000, + .bootrom_size = 0x2000, + .option_base = STM32_L0_OPTION_BYTES_BASE, + .option_size = 20, + .flags = CHIP_F_HAS_DUAL_BANK, }, { // STM32WB55xx, STM32WB35xx, STM32WB50CG/30CE From f55dd8d08f5cd414b9569b8d16a0f7841cec6db9 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 6 Jan 2022 21:24:29 +0100 Subject: [PATCH 1268/1435] [refactoring] Clean-up for chipid files (L1, L4) --- config/chips/L1xx_Cat_1.chip | 17 +- config/chips/L1xx_Cat_2.chip | 17 +- config/chips/L1xx_Cat_3.chip | 17 +- config/chips/L1xx_Cat_4.chip | 21 +- config/chips/L1xx_Cat_5.chip | 17 +- config/chips/L41x_L42x.chip | 17 +- config/chips/L43x_L44x.chip | 21 +- config/chips/L45x_46x.chip | 13 -- config/chips/L45x_L46x.chip | 14 ++ config/chips/L47x_L48x.chip | 21 +- config/chips/L496x_L4A6x.chip | 21 +- config/chips/L4Px.chip | 19 +- config/chips/L4Rx.chip | 19 +- src/stlink-lib/chipid_db_old.h | 373 ++++++++++++++++----------------- 14 files changed, 308 insertions(+), 299 deletions(-) delete mode 100644 config/chips/L45x_46x.chip create mode 100644 config/chips/L45x_L46x.chip diff --git a/config/chips/L1xx_Cat_1.chip b/config/chips/L1xx_Cat_1.chip index 6c8b211c4..1d0b9282f 100644 --- a/config/chips/L1xx_Cat_1.chip +++ b/config/chips/L1xx_Cat_1.chip @@ -1,13 +1,14 @@ -# Chip-ID file for L1xx Cat.1 +# Chip-ID file for STM32L1xx (Cat.1) device (L100C6 / L100R8 / L100RB) # -chip_id 0x416 -description L1xx Cat.1 -flash_type 5 -flash_pagesize 0x100 -sram_size 0x4000 +dev_type STM32L1xx_Cat_1 +ref_manual_id 0038 +chip_id 0x416 // STLINK_CHIPID_STM32_L1_MD +flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_size_reg 0x1ff8004c +flash_pagesize 0x100 // 128 B +sram_size 0x4000 // 16 KB bootrom_base 0x1ff00000 -bootrom_size 0x1000 +bootrom_size 0x1000 // 4 KB option_base 0x0 option_size 0x0 flags swo - diff --git a/config/chips/L1xx_Cat_2.chip b/config/chips/L1xx_Cat_2.chip index 1ff71edef..f311e702c 100644 --- a/config/chips/L1xx_Cat_2.chip +++ b/config/chips/L1xx_Cat_2.chip @@ -1,13 +1,14 @@ -# Chip-ID file for L1xx Cat.2 +# Chip-ID file for STM32L1xx (Cat.2) device (L100C6-A / L100R8-A / L100RB-A) # -chip_id 0x429 -description L1xx Cat.2 -flash_type 5 -flash_pagesize 0x100 -sram_size 0x8000 +dev_type STM32L1xx_Cat_2 +ref_manual_id 0038 +chip_id 0x429 // STLINK_CHIPID_STM32_L1_CAT2 +flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_size_reg 0x1ff8004c +flash_pagesize 0x100 // 128 B +sram_size 0x8000 // 32 KB bootrom_base 0x1ff00000 -bootrom_size 0x1000 +bootrom_size 0x1000 // 4 KB option_base 0x0 option_size 0x0 flags swo - diff --git a/config/chips/L1xx_Cat_3.chip b/config/chips/L1xx_Cat_3.chip index f417e07f9..e6ecaf49e 100644 --- a/config/chips/L1xx_Cat_3.chip +++ b/config/chips/L1xx_Cat_3.chip @@ -1,13 +1,14 @@ -# Chip-ID file for L1xx Cat.3 +# Chip-ID file for STM32L1xx (Cat.3) device (L100RC / L15xxC) # -chip_id 0x427 -description L1xx Cat.3 -flash_type 5 -flash_pagesize 0x100 -sram_size 0x8000 +dev_type STM32L1xx_Cat_3 +ref_manual_id 0038 +chip_id 0x427 // STLINK_CHIPID_STM32_L1_MD_PLUS +flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_size_reg 0x1ff800cc +flash_pagesize 0x100 // 128 B +sram_size 0x8000 // 32 KB bootrom_base 0x1ff00000 -bootrom_size 0x1000 +bootrom_size 0x1000 // 4 KB option_base 0x0 option_size 0x0 flags swo - diff --git a/config/chips/L1xx_Cat_4.chip b/config/chips/L1xx_Cat_4.chip index dbf7869ad..8ed0e004a 100644 --- a/config/chips/L1xx_Cat_4.chip +++ b/config/chips/L1xx_Cat_4.chip @@ -1,13 +1,14 @@ -# Chip-ID file for L1xx Cat.4 +# Chip-ID file for STM32L1xx (Cat.4) device (L15xxD / L162xD) # -chip_id 0x436 -description L1xx Cat.4 -flash_type 5 -flash_pagesize 0x100 -sram_size 0xc000 +dev_type STM32L1xx_Cat_4 +ref_manual_id 0038 +chip_id 0x436 // STLINK_CHIPID_STM32_L1_MD_PLUS_HD +flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_size_reg 0x1ff800cc +flash_pagesize 0x100 // 128 B +sram_size 0xc000 // 48 KB bootrom_base 0x1ff00000 -bootrom_size 0x1000 -option_base 0x1ff80000 -option_size 0x8 +bootrom_size 0x1000 // 4 KB +option_base 0x1ff80000 // STM32_L1_OPTION_BYTES_BASE +option_size 0x8 // 8 B flags swo - diff --git a/config/chips/L1xx_Cat_5.chip b/config/chips/L1xx_Cat_5.chip index 12342d14f..75cebd94c 100644 --- a/config/chips/L1xx_Cat_5.chip +++ b/config/chips/L1xx_Cat_5.chip @@ -1,13 +1,14 @@ -# Chip-ID file for L1xx Cat.5 +# Chip-ID file for STM32L1xx (Cat.5) device (L15xxE / L162xE) # -chip_id 0x437 -description L1xx Cat.5 -flash_type 5 -flash_pagesize 0x100 -sram_size 0x14000 +dev_type STM32L1xx_Cat_5 +ref_manual_id 0038 +chip_id 0x437 // STLINK_CHIPID_STM32_L152_RE +flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_size_reg 0x1ff800cc +flash_pagesize 0x100 // 128 B +sram_size 0x14000 // 80 KB bootrom_base 0x1ff00000 -bootrom_size 0x1000 +bootrom_size 0x1000 // 4 KB option_base 0x0 option_size 0x0 flags swo - diff --git a/config/chips/L41x_L42x.chip b/config/chips/L41x_L42x.chip index 3e086e159..97d0939ab 100644 --- a/config/chips/L41x_L42x.chip +++ b/config/chips/L41x_L42x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for L41x/L42x +# Chip-ID file for STM32L41x / STM32L42x device # -chip_id 0x464 -description L41x/L42x -flash_type 6 -flash_pagesize 0x800 -sram_size 0xa000 +dev_type STM32L41x_L42x +ref_manual_id 0394 +chip_id 0x464 // STLINK_CHIPID_STM32_L41x_L42x +flash_type 6 // STLINK_FLASH_TYPE_L4 +flash_size_reg 0x1fff75e0 +flash_pagesize 0x800 // 2 KB +sram_size 0xa000 // 40 KB bootrom_base 0x1fff0000 -bootrom_size 0x7000 +bootrom_size 0x7000 // 28 KB option_base 0x0 option_size 0x0 flags swo - diff --git a/config/chips/L43x_L44x.chip b/config/chips/L43x_L44x.chip index 383c42f3f..369fdfa1e 100644 --- a/config/chips/L43x_L44x.chip +++ b/config/chips/L43x_L44x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for L43x/L44x +# Chip-ID file for STM32L43x / STM32L44x device # -chip_id 0x435 -description L43x/L44x -flash_type 6 -flash_pagesize 0x800 -sram_size 0xc000 +dev_type STM32L41x_L42x +ref_manual_id 0392 +chip_id 0x435 // STLINK_CHIPID_STM32_L43x_L44x +flash_type 6 // STLINK_FLASH_TYPE_L4 +flash_size_reg 0x1fff75e0 +flash_pagesize 0x800 // 2 KB +sram_size 0xc000 // 48 KB bootrom_base 0x1fff0000 -bootrom_size 0x7000 -option_base 0x1fff7800 -option_size 0x4 +bootrom_size 0x7000 // 28 KB +option_base 0x1fff7800 // STM32_L4_OPTION_BYTES_BASE +option_size 0x4 // 4 B flags swo - diff --git a/config/chips/L45x_46x.chip b/config/chips/L45x_46x.chip deleted file mode 100644 index 943b275d5..000000000 --- a/config/chips/L45x_46x.chip +++ /dev/null @@ -1,13 +0,0 @@ -# Chip-ID file for L45x/46x -# -chip_id 0x462 -description L45x/46x -flash_type 6 -flash_pagesize 0x800 -sram_size 0x20000 -bootrom_base 0x1fff0000 -bootrom_size 0x7000 -option_base 0x0 -option_size 0x0 -flags swo - diff --git a/config/chips/L45x_L46x.chip b/config/chips/L45x_L46x.chip new file mode 100644 index 000000000..2d1cda441 --- /dev/null +++ b/config/chips/L45x_L46x.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32L45x / STM32L46x device +# +dev_type STM32L45x_L46x +ref_manual_id 0394 +chip_id 0x462 // STLINK_CHIPID_STM32_L45x_L46x +flash_type 6 // STLINK_FLASH_TYPE_L4 +flash_size_reg 0x1fff75e0 +flash_pagesize 0x800 // 2 KB +sram_size 0x20000 // 128 KB +bootrom_base 0x1fff0000 +bootrom_size 0x7000 // 28 KB +option_base 0x0 +option_size 0x0 +flags swo diff --git a/config/chips/L47x_L48x.chip b/config/chips/L47x_L48x.chip index 7069229f3..4af25cf5c 100644 --- a/config/chips/L47x_L48x.chip +++ b/config/chips/L47x_L48x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for L47x/L48x +# Chip-ID file for STM32L47x / STM32L48x device # -chip_id 0x415 -description L47x/L48x -flash_type 6 -flash_pagesize 0x800 -sram_size 0x18000 +dev_type STM32L47x_L48x +ref_manual_id 0351 +chip_id 0x415 // STLINK_CHIPID_STM32_L4 +flash_type 6 // STLINK_FLASH_TYPE_L4 +flash_size_reg 0x1fff75e0 +flash_pagesize 0x800 // 2 KB +sram_size 0x18000 // 96 KB bootrom_base 0x1fff0000 -bootrom_size 0x7000 -option_base 0x1fff7800 -option_size 0x4 +bootrom_size 0x7000 // 28 KB +option_base 0x1fff7800 // STM32_L4_OPTION_BYTES_BASE +option_size 0x4 // 4 B flags swo - diff --git a/config/chips/L496x_L4A6x.chip b/config/chips/L496x_L4A6x.chip index 57f539db3..822914c96 100644 --- a/config/chips/L496x_L4A6x.chip +++ b/config/chips/L496x_L4A6x.chip @@ -1,13 +1,14 @@ -# Chip-ID file for L496x/L4A6x +# Chip-ID file for STM32L496x / STM32L4A6x device # -chip_id 0x461 -description L496x/L4A6x -flash_type 6 -flash_pagesize 0x800 -sram_size 0x40000 +dev_type STM32L496x_L4A6x +ref_manual_id 0351 +chip_id 0x461 // STLINK_CHIPID_STM32_L496x_L4A6x +flash_type 6 // STLINK_FLASH_TYPE_L4 +flash_size_reg 0x1fff75e0 +flash_pagesize 0x800 // 2 KB +sram_size 0x40000 // 256 KB bootrom_base 0x1fff0000 -bootrom_size 0x7000 -option_base 0x1fff7800 -option_size 0x4 +bootrom_size 0x7000 // 28 KB +option_base 0x1fff7800 // STM32_L4_OPTION_BYTES_BASE +option_size 0x4 // 4 B flags swo - diff --git a/config/chips/L4Px.chip b/config/chips/L4Px.chip index 3e0fbea50..8366621e2 100644 --- a/config/chips/L4Px.chip +++ b/config/chips/L4Px.chip @@ -1,13 +1,14 @@ -# Chip-ID file for L4Px +# Chip-ID file for STM32L4Px device # -chip_id 0x471 -description L4Px -flash_type 6 -flash_pagesize 0x1000 -sram_size 0xa0000 +dev_type STM32L4Px +ref_manual_id 0432 +chip_id 0x471 // STLINK_CHIPID_STM32_L4PX +flash_type 6 // STLINK_FLASH_TYPE_L4 +flash_size_reg 0x1fff75e0 +flash_pagesize 0x1000 // 4 KB +sram_size 0xa0000 // 640 KB bootrom_base 0x1fff0000 -bootrom_size 0x7000 +bootrom_size 0x7000 // 28 KB option_base 0x0 option_size 0x0 -flags dualbank swo - +flags swo diff --git a/config/chips/L4Rx.chip b/config/chips/L4Rx.chip index a9a26f419..734f39199 100644 --- a/config/chips/L4Rx.chip +++ b/config/chips/L4Rx.chip @@ -1,13 +1,14 @@ -# Chip-ID file for L4Rx +# Chip-ID file for STM32L4Rx device # -chip_id 0x470 -description L4Rx -flash_type 6 -flash_pagesize 0x1000 -sram_size 0xa0000 +dev_type STM32L4Rx +ref_manual_id 0432 +chip_id 0x470 // STLINK_CHIPID_STM32_L4RX +flash_type 6 // STLINK_FLASH_TYPE_L4 +flash_size_reg 0x1fff75e0 +flash_pagesize 0x1000 // 4 KB +sram_size 0xa0000 // 640 KB bootrom_base 0x1fff0000 -bootrom_size 0x7000 +bootrom_size 0x7000 // 28 KB option_base 0x0 option_size 0x0 -flags dualbank swo - +flags swo diff --git a/src/stlink-lib/chipid_db_old.h b/src/stlink-lib/chipid_db_old.h index b86b13289..7acfef409 100644 --- a/src/stlink-lib/chipid_db_old.h +++ b/src/stlink-lib/chipid_db_old.h @@ -6,194 +6,6 @@ // config/chips/*.chip file. static struct stlink_chipid_params devices[] = { - { - // STM32L100/L15x/L16x Cat.1 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L1_MD, - .dev_type = "L1xx Cat.1", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8004c, - .flash_pagesize = 0x100, - .sram_size = 0x4000, // up to 16k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L100/L15x/L16x Cat.2 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L1_CAT2, - .dev_type = "L1xx Cat.2", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8004c, - .flash_pagesize = 0x100, - .sram_size = 0x8000, // up to 32k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L100/L15x/L16x Cat.3 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L1_MD_PLUS, - .dev_type = "L1xx Cat.3", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x8000, // up to 32k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L100/L15x/L16x Cat.4 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L1_MD_PLUS_HD, - .dev_type = "L1xx Cat.4", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0xC000, // up to 48k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .option_base = STM32_L1_OPTION_BYTES_BASE, - .option_size = 8, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L100/L15x/L16x Cat.5 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L152_RE, - .dev_type = "L1xx Cat.5", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x14000, // up to 80k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L47x/L48x - // RM0351 - .chip_id = STLINK_CHIPID_STM32_L4, - .dev_type = "L47x/L48x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 - // and tables 4-6 on pages 79-81) - // SRAM1 is "up to" 96k in the standard Cortex-M memory map; - // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) - .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L4RX - // RM0432 - .chip_id = STLINK_CHIPID_STM32_L4Rx, - .dev_type = "L4Rx", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) - .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 - // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size - .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 - .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 - .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L4PX - // RM0432 - .chip_id = STLINK_CHIPID_STM32_L4PX, - .dev_type = "L4Px", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) - .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 - // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size - .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 - .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 - .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STLINK_CHIPID_STM32_L41x_L42x - // RM0394 (rev 4), DS12469 (rev 5) - .chip_id = STLINK_CHIPID_STM32_L41x_L42x, - .dev_type = "L41x/L42x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, - // sec 47.2, page 1586) - .flash_pagesize = 0x800, // 2k (DS12469, sec 3.4, page 17) - // SRAM1 is 32k at 0x20000000 - // SRAM2 is 8k at 0x10000000 and 0x20008000 - // (DS12469, sec 3.5, page 18) - .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) - .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) - .bootrom_size = 0x7000, // 28k, same source as base - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STLINK_CHIPID_STM32_L43x_L44x - // RM0392 - .chip_id = STLINK_CHIPID_STM32_L43x_L44x, - .dev_type = "L43x/L44x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 - // and tables 7-8 on pages 75-76) - // SRAM1 is "up to" 64k in the standard Cortex-M memory map; - // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) - .sram_size = 0xc000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STLINK_CHIPID_STM32_L496x_L4A6x - // RM0351 (rev 5) - .chip_id = STLINK_CHIPID_STM32_L496x_L4A6x, - .dev_type = "L496x/L4A6x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) - .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) - // SRAM1 is 256k at 0x20000000 - // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) - .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) - .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STLINK_CHIPID_STM32_L45x_L46x - // RM0394 (updated version of RM0392?) - .chip_id = STLINK_CHIPID_STM32_L45x_L46x, - .dev_type = "L45x/46x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 - // and tables 7 on pages 73-74) - // SRAM1 is 128k at 0x20000000; - // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, - // page 68, also fig 2 on page 63) - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system - // memory, also fig 2 on page 63) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .flags = CHIP_F_HAS_SWO_TRACING, - }, -// ######################################################################## -// ######################################################################## -// ######################################################################## { // STM32F03x // RM0091 @@ -841,6 +653,191 @@ static struct stlink_chipid_params devices[] = { .option_size = 20, .flags = CHIP_F_HAS_DUAL_BANK, }, + { + // STM32L100/L15x/L16x Cat.1 + // RM0038 + .chip_id = STLINK_CHIPID_STM32_L1_MD, + .dev_type = "L1xx Cat.1", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8004c, + .flash_pagesize = 0x100, + .sram_size = 0x4000, // up to 16k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L100/L15x/L16x Cat.2 + // RM0038 + .chip_id = STLINK_CHIPID_STM32_L1_CAT2, + .dev_type = "L1xx Cat.2", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8004c, + .flash_pagesize = 0x100, + .sram_size = 0x8000, // up to 32k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L100/L15x/L16x Cat.3 + // RM0038 + .chip_id = STLINK_CHIPID_STM32_L1_MD_PLUS, + .dev_type = "L1xx Cat.3", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0x8000, // up to 32k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L100/L15x/L16x Cat.4 + // RM0038 + .chip_id = STLINK_CHIPID_STM32_L1_MD_PLUS_HD, + .dev_type = "L1xx Cat.4", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0xC000, // up to 48k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000, + .option_base = STM32_L1_OPTION_BYTES_BASE, + .option_size = 8, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L100/L15x/L16x Cat.5 + // RM0038 + .chip_id = STLINK_CHIPID_STM32_L152_RE, + .dev_type = "L1xx Cat.5", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0x14000, // up to 80k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STLINK_CHIPID_STM32_L41x_L42x + // RM0394 (rev 4), DS12469 (rev 5) + .chip_id = STLINK_CHIPID_STM32_L41x_L42x, + .dev_type = "L41x/L42x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, + // sec 47.2, page 1586) + .flash_pagesize = 0x800, // 2k (DS12469, sec 3.4, page 17) + // SRAM1 is 32k at 0x20000000 + // SRAM2 is 8k at 0x10000000 and 0x20008000 + // (DS12469, sec 3.5, page 18) + .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) + .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) + .bootrom_size = 0x7000, // 28k, same source as base + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STLINK_CHIPID_STM32_L43x_L44x + // RM0392 + .chip_id = STLINK_CHIPID_STM32_L43x_L44x, + .dev_type = "L43x/L44x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 + // and tables 7-8 on pages 75-76) + // SRAM1 is "up to" 64k in the standard Cortex-M memory map; + // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) + .sram_size = 0xc000, + .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STLINK_CHIPID_STM32_L45x_L46x + // RM0394 (updated version of RM0392?) + .chip_id = STLINK_CHIPID_STM32_L45x_L46x, + .dev_type = "L45x/46x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 + // and tables 7 on pages 73-74) + // SRAM1 is 128k at 0x20000000; + // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, + // page 68, also fig 2 on page 63) + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system + // memory, also fig 2 on page 63) + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L47x/L48x + // RM0351 + .chip_id = STLINK_CHIPID_STM32_L4, + .dev_type = "L47x/L48x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) + .flash_pagesize = 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 + // and tables 4-6 on pages 79-81) + // SRAM1 is "up to" 96k in the standard Cortex-M memory map; + // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) + .sram_size = 0x18000, + .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STLINK_CHIPID_STM32_L496x_L4A6x + // RM0351 (rev 5) + .chip_id = STLINK_CHIPID_STM32_L496x_L4A6x, + .dev_type = "L496x/L4A6x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) + .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) + // SRAM1 is 256k at 0x20000000 + // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) + .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) + .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) + .bootrom_size = 0x7000, // 28k (per bank), same source as base + .option_base = STM32_L4_OPTION_BYTES_BASE, + .option_size = 4, + .flags = CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L4PX + // RM0432 + .chip_id = STLINK_CHIPID_STM32_L4PX, + .dev_type = "L4Px", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) + .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 + // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size + .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 + .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 + .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, + }, + { + // STM32L4RX + // RM0432 + .chip_id = STLINK_CHIPID_STM32_L4Rx, + .dev_type = "L4Rx", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) + .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 + // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size + .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 + .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 + .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) + .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, + }, { // STM32WB55xx, STM32WB35xx, STM32WB50CG/30CE // RM0434, RM0471 From 4132973ddfcf48abb3046d0f15c2ec4321a43891 Mon Sep 17 00:00:00 2001 From: hydroconstructor Date: Fri, 7 Jan 2022 00:45:25 +0400 Subject: [PATCH 1269/1435] usb.c refactoring request: remove getenv("STLINK_DEVICE") There is no enironment variable "STLINK_DEVICE" in user system, and program do not set it. So I removed all code which works with it. --- src/stlink-lib/usb.c | 36 ++---------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 65e8f4e25..2e99e82be 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1134,33 +1134,8 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, #endif libusb_device **list = NULL; - // TODO: We should use ssize_t and use it as a counter if > 0. - // As per libusb API: ssize_t libusb_get_device_list (libusb_context *ctx, libusb_device ***list) - int cnt = (int)libusb_get_device_list(slu->libusb_ctx, &list); + ssize_t cnt = libusb_get_device_list(slu->libusb_ctx, &list); struct libusb_device_descriptor desc; - int devBus = 0; - int devAddr = 0; - - // TODO: Reading a environment variable in a usb open function is not very nice, this should - // be refactored and moved into the CLI tools, and instead of giving USB_BUS:USB_ADDR a real - // stlink serial string should be passed to this function. Probably people are using this - // but this is very odd because as programmer can change to multiple busses and it is better - // to detect them based on serial. - char *device = getenv("STLINK_DEVICE"); - - if (device) { - char *c = strchr(device, ':'); - - if (c == NULL) { - WLOG("STLINK_DEVICE must be : format\n"); - goto on_error; - } - - devBus = atoi(device); - *c++ = 0; - devAddr = atoi(c); - ILOG("bus %03d dev %03d\n", devBus, devAddr); - } while (cnt-- > 0) { struct libusb_device_handle *handle; @@ -1169,13 +1144,6 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, if (desc.idVendor != STLINK_USB_VID_ST) { continue; } - if (devBus && devAddr) { - if ((libusb_get_bus_number(list[cnt]) != devBus) || - (libusb_get_device_address(list[cnt]) != devAddr)) { - continue; - } - } - ret = libusb_open(list[cnt], &handle); if (ret) { continue; } // could not open device @@ -1202,7 +1170,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, } if (cnt < 0) { - WLOG ("Couldn't find %s ST-Link devices\n", (devBus && devAddr) ? "matched" : "any"); + WLOG ("Couldn't find any ST-Link devices\n"); libusb_free_device_list(list, 1); goto on_error; } else { From 42790f3f169e10d51dfe4bb982d64b24389a62ab Mon Sep 17 00:00:00 2001 From: Antoine Faure Date: Tue, 21 Dec 2021 09:48:10 +1300 Subject: [PATCH 1270/1435] st-flash erase addr size --- inc/stlink.h | 1 + src/common.c | 24 +++++++++++++++--------- src/st-flash/flash.c | 7 +++++-- src/st-flash/flash_opts.c | 19 ++++++++++++++++++- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 81dc7902e..852e95e42 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -274,6 +274,7 @@ int stlink_trace_enable(stlink_t* sl, uint32_t frequency); int stlink_trace_disable(stlink_t* sl); int stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size); int stlink_erase_flash_mass(stlink_t* sl); +int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size); int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); uint8_t stlink_get_erased_pattern(stlink_t *sl); diff --git a/src/common.c b/src/common.c index bdd6f5bab..fb5e431fa 100644 --- a/src/common.c +++ b/src/common.c @@ -2951,19 +2951,13 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { return check_flash_error(sl); } -int stlink_erase_flash_mass(stlink_t *sl) { - int err = 0; - - // TODO: User MER bit to mass-erase WB series. - if (sl->flash_type == STLINK_FLASH_TYPE_L0 || - sl->flash_type == STLINK_FLASH_TYPE_WB) { +int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size) { // erase each page - int i = 0, num_pages = (int)(sl->flash_size / sl->flash_pgsz); - + int i = 0, num_pages = (int)(size / sl->flash_pgsz); for (i = 0; i < num_pages; i++) { // addr must be an addr inside the page stm32_addr_t addr = - (stm32_addr_t)sl->flash_base + i * (stm32_addr_t)sl->flash_pgsz; + (stm32_addr_t)base_addr + i * (stm32_addr_t)sl->flash_pgsz; if (stlink_erase_flash_page(sl, addr)) { WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); @@ -2975,6 +2969,18 @@ int stlink_erase_flash_mass(stlink_t *sl) { } fprintf(stdout, "\n"); + return 0; +} + +int stlink_erase_flash_mass(stlink_t *sl) { + int err = 0; + + // TODO: User MER bit to mass-erase WB series. + if (sl->flash_type == STLINK_FLASH_TYPE_L0 || + sl->flash_type == STLINK_FLASH_TYPE_WB) { + + stlink_erase_flash_section(sl, sl->flash_base, sl->flash_size); + } else { wait_flash_busy(sl); clear_flash_error(sl); diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 51702b683..b4b596cfc 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -27,7 +27,7 @@ static void cleanup(int signum) { static void usage(void) { puts("command line: ./st-flash [--debug] [--reset] [--connect-under-reset] [--hot-plug] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); - puts("command line: ./st-flash [--debug] [--connect-under-reset] [--hot-plug] [--freq=] [--serial ] erase"); + puts("command line: ./st-flash [--debug] [--connect-under-reset] [--hot-plug] [--freq=] [--serial ] erase [addr] [size]"); puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); puts(" , and : Use hex format."); puts(" : Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); @@ -168,7 +168,10 @@ int main(int ac, char** av) { goto on_error; } } else if (o.cmd == FLASH_CMD_ERASE) { - err = stlink_erase_flash_mass(sl); + if (o.size != 0 && o.addr >= sl->flash_base && (o.addr + o.size) <= (sl->flash_base + sl->flash_size)) + err = stlink_erase_flash_section(sl, o.addr, o.size); + else + err = stlink_erase_flash_mass(sl); if (err == -1) { printf("stlink_erase_flash_mass() == -1\n"); diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 172a24468..984156aa3 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -234,7 +234,24 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { return(-1); case FLASH_CMD_ERASE: // no more arguments expected - if (ac != 0) { return(-1); } + if (ac != 0 && ac != 2) { return(-1); } + if (ac == 2) { + uint32_t address; + result = get_integer_from_char_array(av[0], &address); + if (result != 0) { + return bad_arg ("addr"); + } else { + o->addr = (stm32_addr_t) address; + } + + uint32_t size; + result = get_integer_from_char_array(av[1], &size); + if (result != 0) { + return bad_arg ("size"); + } else { + o->size = (size_t) size; + } + } break; From b519c63e500de3d146132ffafb67d058d9ecf974 Mon Sep 17 00:00:00 2001 From: hydroconstructor Date: Sun, 9 Jan 2022 19:02:22 +0400 Subject: [PATCH 1271/1435] #1214 issue fix Error in file size comparizon. Due to type casting, instead of compare file size with max. singed int value, it compares with -1. Then function returns with error message. --- src/common.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/common.c b/src/common.c index bdd6f5bab..99fdde325 100644 --- a/src/common.c +++ b/src/common.c @@ -27,6 +27,10 @@ #define O_BINARY 0 #endif +#ifndef MAX_FILE_SIZE +#define MAX_FILE_SIZE (1<<20) // signed long int max value +#endif + #ifdef _MSC_VER #define __attribute__(x) #endif @@ -2200,8 +2204,9 @@ static int map_file(mapped_file_t *mf, const char *path) { if (sizeof(st.st_size) != sizeof(size_t)) { // on 32 bit systems, check if there is an overflow - if (st.st_size > (off_t)SSIZE_MAX) { - fprintf(stderr, "mmap() size_t overflow for file %s\n", path); + if (st.st_size > (off_t)MAX_FILE_SIZE /*1 GB*/ ) { + // limit file size to 1 GB + fprintf(stderr, "mmap() file %s too big\n", path); goto on_error; } } From 14498bb3c011c70d5ba66f26de2a8c11eed68b8d Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 9 Jan 2022 16:39:54 +0100 Subject: [PATCH 1272/1435] Restructuring of STM32 definitions - Moved enum stlink_stm32_chipids to stm32.h - Moved additional MCU defines to stlink.h - Minor formatting improvements - Commented comparison for old/new chipid db --- inc/stlink.h | 4 ++ inc/stm32.h | 118 ++++++++++++++++++++++++++++++++-------- src/stlink-lib/chipid.c | 69 +++++++++++------------ src/stlink-lib/chipid.h | 77 ++------------------------ 4 files changed, 139 insertions(+), 129 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 81dc7902e..d7cc0006e 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -83,6 +83,10 @@ enum target_state { #define STLINK_F_HAS_DPBANKSEL (1 << 8) #define STLINK_F_HAS_RW8_512BYTES (1 << 9) +/* Additional MCU features */ +#define CHIP_F_HAS_DUAL_BANK (1 << 0) +#define CHIP_F_HAS_SWO_TRACING (1 << 1) + /* Error code */ #define STLINK_DEBUG_ERR_OK 0x80 #define STLINK_DEBUG_ERR_FAULT 0x81 diff --git a/inc/stm32.h b/inc/stm32.h index 15e0ff147..7a5e983a4 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -7,37 +7,111 @@ #ifndef STM32_H #define STM32_H -/* Cortex core ids */ -#define STM32VL_CORE_ID 0x1ba01477 -#define STM32F7_CORE_ID 0x5ba02477 -#define STM32H7_CORE_ID 0x6ba02477 // STM32H7 SWD ID Code -#define STM32H7_CORE_ID_JTAG 0x6ba00477 // STM32H7 JTAG ID Code (RM0433 pg3065) +/* Cortex-M core ids */ +#define STM32VL_CORE_ID 0x1ba01477 +#define STM32F7_CORE_ID 0x5ba02477 +#define STM32H7_CORE_ID 0x6ba02477 // STM32H7 SWD ID Code +#define STM32H7_CORE_ID_JTAG 0x6ba00477 // STM32H7 JTAG ID Code (RM0433 p.3065) -/* Constant STM32 memory map figures */ -#define STM32_SRAM_BASE ((uint32_t)0x20000000) -#define STM32_FLASH_BASE ((uint32_t)0x08000000) -#define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) +/* Constant STM32 memory address */ +#define STM32_SRAM_BASE ((uint32_t)0x20000000) +#define STM32_FLASH_BASE ((uint32_t)0x08000000) -#define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) +#define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) +#define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) -#define STM32_F4_OPTION_BYTES_BASE ((uint32_t)0x40023C14) -#define STM32_H7_OPTION_BYTES_BASE ((uint32_t)0x5200201C) +/* Constant STM32 option bytes base memory address */ +#define STM32_F4_OPTION_BYTES_BASE ((uint32_t)0x40023c14) -#define STM32_L0_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) -#define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) +#define STM32_H7_OPTION_BYTES_BASE ((uint32_t)0x5200201c) -#define STM32_F7_OPTION_BYTES_BASE ((uint32_t)0x1FFF0000) +#define STM32_L0_OPTION_BYTES_BASE ((uint32_t)0x1ff80000) +#define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1ff80000) -#define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) -#define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) +#define STM32_F7_OPTION_BYTES_BASE ((uint32_t)0x1fff0000) -#define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) +#define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1fff7800) +#define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1fff7800) -#define STM32_F0_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) -#define STM32_F1_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) -#define STM32_F3_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) -#define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) +#define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1fffc000) + +#define STM32_F0_OPTION_BYTES_BASE ((uint32_t)0x1ffff800) +#define STM32_F1_OPTION_BYTES_BASE ((uint32_t)0x1ffff800) +#define STM32_F3_OPTION_BYTES_BASE ((uint32_t)0x1ffff800) +#define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1ffff800) + + +/* + * Chip IDs + * See DBGMCU_IDCODE register (0xE0042000) in appropriate programming manual + */ + +// stm32 chipids, only lower 12 bits... + +enum stlink_stm32_chipids { + STLINK_CHIPID_UNKNOWN = 0x000, + + STLINK_CHIPID_STM32_F1_MD = 0x410, /* medium density */ + STLINK_CHIPID_STM32_F2 = 0x411, + STLINK_CHIPID_STM32_F1_LD = 0x412, /* low density */ + STLINK_CHIPID_STM32_F4 = 0x413, + STLINK_CHIPID_STM32_F1_HD = 0x414, /* high density */ + STLINK_CHIPID_STM32_L4 = 0x415, + STLINK_CHIPID_STM32_L1_MD = 0x416, /* medium density */ + STLINK_CHIPID_STM32_L0 = 0x417, + STLINK_CHIPID_STM32_F1_CONN = 0x418, /* connectivity line */ + STLINK_CHIPID_STM32_F4_HD = 0x419, /* high density */ + STLINK_CHIPID_STM32_F1_VL_MD_LD = 0x420, /* value line medium & low density */ + STLINK_CHIPID_STM32_F446 = 0x421, + STLINK_CHIPID_STM32_F3 = 0x422, + STLINK_CHIPID_STM32_F4_LP = 0x423, + STLINK_CHIPID_STM32_L0_CAT2 = 0x425, + STLINK_CHIPID_STM32_L1_MD_PLUS = 0x427, /* medium density plus */ + STLINK_CHIPID_STM32_F1_VL_HD = 0x428, /* value line high density */ + STLINK_CHIPID_STM32_L1_CAT2 = 0x429, + STLINK_CHIPID_STM32_F1_XLD = 0x430, /* extra low density plus */ + STLINK_CHIPID_STM32_F411xx = 0x431, + STLINK_CHIPID_STM32_F37x = 0x432, + STLINK_CHIPID_STM32_F4_DE = 0x433, + STLINK_CHIPID_STM32_F4_DSI = 0x434, + STLINK_CHIPID_STM32_L43x_L44x = 0x435, + STLINK_CHIPID_STM32_L1_MD_PLUS_HD = 0x436, /* medium density plus & high density */ + STLINK_CHIPID_STM32_L152_RE = 0x437, + STLINK_CHIPID_STM32_F334 = 0x438, + STLINK_CHIPID_STM32_F3xx_SMALL = 0x439, + STLINK_CHIPID_STM32_F0 = 0x440, + STLINK_CHIPID_STM32_F412 = 0x441, + STLINK_CHIPID_STM32_F09x = 0x442, + STLINK_CHIPID_STM32_F0xx_SMALL = 0x444, + STLINK_CHIPID_STM32_F04 = 0x445, + STLINK_CHIPID_STM32_F303_HD = 0x446, /* high density */ + STLINK_CHIPID_STM32_L0_CAT5 = 0x447, + STLINK_CHIPID_STM32_F0_CAN = 0x448, + STLINK_CHIPID_STM32_F7 = 0x449, /* Nucleo F746ZG board */ + STLINK_CHIPID_STM32_H74xxx = 0x450, /* RM0433, p.3189 */ + STLINK_CHIPID_STM32_F76xxx = 0x451, + STLINK_CHIPID_STM32_F72xxx = 0x452, /* Nucleo F722ZE board */ + STLINK_CHIPID_STM32_G0_CAT4 = 0x456, /* G051/G061 */ + STLINK_CHIPID_STM32_L011 = 0x457, + STLINK_CHIPID_STM32_F410 = 0x458, + STLINK_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/G081 */ + STLINK_CHIPID_STM32_L496x_L4A6x = 0x461, + STLINK_CHIPID_STM32_L45x_L46x = 0x462, + STLINK_CHIPID_STM32_F413 = 0x463, + STLINK_CHIPID_STM32_L41x_L42x = 0x464, + STLINK_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/G041 */ + STLINK_CHIPID_STM32_G0_CAT3 = 0x467, /* G0B1/G0C1 */ + STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* RM0440, section 46.6.1 "MCU device ID code" */ + STLINK_CHIPID_STM32_G4_CAT3 = 0x469, + STLINK_CHIPID_STM32_L4Rx = 0x470, /* RM0432, p.2247, found on the STM32L4R9I-DISCO board */ + STLINK_CHIPID_STM32_L4PX = 0x471, /* RM0432, p.2247 */ + STLINK_CHIPID_STM32_G4_CAT4 = 0x479, + STLINK_CHIPID_STM32_H7Ax = 0x480, /* RM0455, p.2863 */ + STLINK_CHIPID_STM32_H72x = 0x483, /* RM0468, p.3199 */ + STLINK_CHIPID_STM32_WB55 = 0x495, + STLINK_CHIPID_STM32_WLE = 0x497, +}; #endif // STM32_H diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 213d43f8c..e3556ca57 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -39,45 +39,46 @@ void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { fprintf(fp, "flags %d\n\n", dev->flags); } -static int chipid_params_eq(const struct stlink_chipid_params *p1, const struct stlink_chipid_params *p2) -{ - return p1->chip_id == p2->chip_id && - p1->dev_type && p2->dev_type && - strcmp(p1->dev_type, p2->dev_type) == 0 && - p1->flash_type == p2->flash_type && - p1->flash_size_reg == p2->flash_size_reg && - p1->flash_pagesize == p2->flash_pagesize && - p1->sram_size == p2->sram_size && - p1->bootrom_base == p2->bootrom_base && - p1->bootrom_size == p2->bootrom_size && - p1->option_base == p2->option_base && - p1->option_size == p2->option_size && - p1->flags == p2->flags; -} - -struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { +// static int chipid_params_eq(const struct stlink_chipid_params *p1, const struct stlink_chipid_params *p2) +// { +// return p1->chip_id == p2->chip_id && +// p1->dev_type && p2->dev_type && +// strcmp(p1->dev_type, p2->dev_type) == 0 && +// p1->flash_type == p2->flash_type && +// p1->flash_size_reg == p2->flash_size_reg && +// p1->flash_pagesize == p2->flash_pagesize && +// p1->sram_size == p2->sram_size && +// p1->bootrom_base == p2->bootrom_base && +// p1->bootrom_size == p2->bootrom_size && +// p1->option_base == p2->option_base && +// p1->option_size == p2->option_size && +// p1->flags == p2->flags; +// } + +struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chip_id) { struct stlink_chipid_params *params = NULL; - struct stlink_chipid_params *p2; - +// struct stlink_chipid_params *p2; for (params = devicelist; params != NULL; params = params->next) - if (params->chip_id == chipid) { + if (params->chip_id == chip_id) { + fprintf(stderr, "\ndetected chip_id parametres\n\n"); + dump_a_chip(stderr, params); break; } - p2 = stlink_chipid_get_params_old(chipid); - -#if 1 - if (params == NULL) { - params = p2; - } else if (!chipid_params_eq(params, p2)) { - // fprintf (stderr, "Error, chipid params not identical\n"); - // return NULL; - fprintf(stderr, "---------- old ------------\n"); - dump_a_chip(stderr, p2); - fprintf(stderr, "---------- new ------------\n"); - dump_a_chip(stderr, params); - } -#endif +// p2 = stlink_chipid_get_params_old(chipid); + +// #if 1 +// if (params == NULL) { +// params = p2; +// } else if (!chipid_params_eq(params, p2)) { +// // fprintf (stderr, "Error, chipid params not identical\n"); +// // return NULL; +// fprintf(stderr, "---------- old ------------\n"); +// dump_a_chip(stderr, p2); +// fprintf(stderr, "---------- new ------------\n"); +// dump_a_chip(stderr, params); +// } +// #endif return(params); } diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index 426c22428..e821f0b57 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -1,83 +1,14 @@ #ifndef STLINK_CHIPID_H_ #define STLINK_CHIPID_H_ +#include +#include + #ifdef __cplusplus extern "C" { #endif -/** - * Chip IDs are explained in the appropriate programming manual for the - * DBGMCU_IDCODE register (0xE0042000) - * stm32 chipids, only lower 12 bits... - */ -enum stlink_stm32_chipids { - STLINK_CHIPID_UNKNOWN = 0x000, - - STLINK_CHIPID_STM32_F1_MD = 0x410, /* medium density */ - STLINK_CHIPID_STM32_F2 = 0x411, - STLINK_CHIPID_STM32_F1_LD = 0x412, /* low density */ - STLINK_CHIPID_STM32_F4 = 0x413, - STLINK_CHIPID_STM32_F1_HD = 0x414, /* high density */ - STLINK_CHIPID_STM32_L4 = 0x415, - STLINK_CHIPID_STM32_L1_MD = 0x416, /* medium density */ - STLINK_CHIPID_STM32_L0 = 0x417, - STLINK_CHIPID_STM32_F1_CONN = 0x418, /* connectivity line */ - STLINK_CHIPID_STM32_F4_HD = 0x419, /* high density */ - STLINK_CHIPID_STM32_F1_VL_MD_LD = 0x420, /* value line medium & low density */ - STLINK_CHIPID_STM32_F446 = 0x421, - STLINK_CHIPID_STM32_F3 = 0x422, - STLINK_CHIPID_STM32_F4_LP = 0x423, - STLINK_CHIPID_STM32_L0_CAT2 = 0x425, - STLINK_CHIPID_STM32_L1_MD_PLUS = 0x427, /* medium density plus */ - STLINK_CHIPID_STM32_F1_VL_HD = 0x428, /* value line high density */ - STLINK_CHIPID_STM32_L1_CAT2 = 0x429, - STLINK_CHIPID_STM32_F1_XLD = 0x430, /* extra low density plus */ - STLINK_CHIPID_STM32_F411xx = 0x431, - STLINK_CHIPID_STM32_F37x = 0x432, - STLINK_CHIPID_STM32_F4_DE = 0x433, - STLINK_CHIPID_STM32_F4_DSI = 0x434, - STLINK_CHIPID_STM32_L43x_L44x = 0x435, - STLINK_CHIPID_STM32_L1_MD_PLUS_HD = 0x436, /* medium density plus & high density */ - STLINK_CHIPID_STM32_L152_RE = 0x437, - STLINK_CHIPID_STM32_F334 = 0x438, - STLINK_CHIPID_STM32_F3xx_SMALL = 0x439, - STLINK_CHIPID_STM32_F0 = 0x440, - STLINK_CHIPID_STM32_F412 = 0x441, - STLINK_CHIPID_STM32_F09x = 0x442, - STLINK_CHIPID_STM32_F0xx_SMALL = 0x444, - STLINK_CHIPID_STM32_F04 = 0x445, - STLINK_CHIPID_STM32_F303_HD = 0x446, /* high density */ - STLINK_CHIPID_STM32_L0_CAT5 = 0x447, - STLINK_CHIPID_STM32_F0_CAN = 0x448, - STLINK_CHIPID_STM32_F7 = 0x449, /* ID found on the Nucleo F746ZG board */ - STLINK_CHIPID_STM32_H74xxx = 0x450, /* RM0433, p.3189 */ - STLINK_CHIPID_STM32_F76xxx = 0x451, - STLINK_CHIPID_STM32_F72xxx = 0x452, /* ID found on the Nucleo F722ZE board */ - STLINK_CHIPID_STM32_G0_CAT4 = 0x456, /* G051/G061 */ - STLINK_CHIPID_STM32_L011 = 0x457, - STLINK_CHIPID_STM32_F410 = 0x458, - STLINK_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/G081 */ - STLINK_CHIPID_STM32_L496x_L4A6x = 0x461, - STLINK_CHIPID_STM32_L45x_L46x = 0x462, - STLINK_CHIPID_STM32_F413 = 0x463, - STLINK_CHIPID_STM32_L41x_L42x = 0x464, - STLINK_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/G041 */ - STLINK_CHIPID_STM32_G0_CAT3 = 0x467, /* G0B1/G0C1 */ - STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* RM0440, s46.6.1 "MCU device ID code" */ - STLINK_CHIPID_STM32_G4_CAT3 = 0x469, - STLINK_CHIPID_STM32_L4Rx = 0x470, /* RM0432, p. 2247, found on the STM32L4R9I-DISCO board */ - STLINK_CHIPID_STM32_L4PX = 0x471, /* RM0432, p. 2247 */ - STLINK_CHIPID_STM32_G4_CAT4 = 0x479, - STLINK_CHIPID_STM32_H7Ax = 0x480, /* RM0455, p.2863 */ - STLINK_CHIPID_STM32_H72x = 0x483, /* RM0468, p.3199 */ - STLINK_CHIPID_STM32_WB55 = 0x495, - STLINK_CHIPID_STM32_WLE = 0x497 -}; - -#define CHIP_F_HAS_DUAL_BANK (1 << 0) -#define CHIP_F_HAS_SWO_TRACING (1 << 1) - -/** Chipid parameters */ +/** Chipid parametres */ struct stlink_chipid_params { char *dev_type; char *ref_manual_id; From 5cde863c0382d92ca0d6ea027a7a3b24926a44e0 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 9 Jan 2022 21:52:55 +0100 Subject: [PATCH 1273/1435] Switch-over to new chip-files --- inc/stlink.h | 26 +++++----- src/stlink-lib/chipid.c | 86 +++++++++++++++++----------------- src/stlink-lib/chipid_db_old.h | 4 +- 3 files changed, 59 insertions(+), 57 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index d7cc0006e..0c1ca73a4 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -106,19 +106,21 @@ enum target_state { #define C_BUF_LEN 32 +/* Old flash type definitions */ +// TODO: Transition to the new defines in stm32.h enum stlink_flash_type { - STLINK_FLASH_TYPE_UNKNOWN = 0, - STLINK_FLASH_TYPE_F0, // used by f0, f1 (except f1xl),f3. */ - STLINK_FLASH_TYPE_F1_XL, // f0 flash with dual bank, apparently */ - STLINK_FLASH_TYPE_F4, // used by f2, f4 */ - STLINK_FLASH_TYPE_F7, - STLINK_FLASH_TYPE_L0, // l0, l1 */ - STLINK_FLASH_TYPE_L4, // l4, l4+ */ - STLINK_FLASH_TYPE_G0, - STLINK_FLASH_TYPE_G4, - STLINK_FLASH_TYPE_WB, - STLINK_FLASH_TYPE_H7, - STLINK_FLASH_TYPE_MAX, + /* 0 */ STLINK_FLASH_TYPE_UNKNOWN = 0, + /* 1 */ STLINK_FLASH_TYPE_F0, // used by f0, f1 (except f1xl),f3. */ + /* 2 */ STLINK_FLASH_TYPE_F1_XL, // f0 flash with dual bank */ + /* 3 */ STLINK_FLASH_TYPE_F4, // used by f2, f4 */ + /* 4 */ STLINK_FLASH_TYPE_F7, + /* 5 */ STLINK_FLASH_TYPE_L0, // l0, l1 */ + /* 6 */ STLINK_FLASH_TYPE_L4, // l4, l4+ */ + /* 7 */ STLINK_FLASH_TYPE_G0, + /* 8 */ STLINK_FLASH_TYPE_G4, + /* 9 */ STLINK_FLASH_TYPE_WB, + /* 10 */ STLINK_FLASH_TYPE_H7, + /* 11 */ STLINK_FLASH_TYPE_MAX, }; struct stlink_reg { diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index e3556ca57..4ab83ba3d 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1,6 +1,6 @@ #include #include "chipid.h" -#include "chipid_db_old.h" +//#include "chipid_db_old.h" #include #include @@ -9,17 +9,17 @@ #include -struct stlink_chipid_params *stlink_chipid_get_params_old(uint32_t chipid) { - struct stlink_chipid_params *params = NULL; +// struct stlink_chipid_params *stlink_chipid_get_params_old(uint32_t chipid) { +// struct stlink_chipid_params *params = NULL; - for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) - if (devices[n].chip_id == chipid) { - params = &devices[n]; - break; - } +// for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) +// if (devices[n].chip_id == chipid) { +// params = &devices[n]; +// break; +// } - return (params); -} +// return (params); +// } static struct stlink_chipid_params *devicelist; @@ -165,7 +165,7 @@ void process_chipfile(char *fname) { while ((pp = strtok (NULL, " \t\n"))) { if (strcmp (pp, "none") == 0) { - ts->flags = 0; // not necessary: calloc did this already. + // NOP } else if (strcmp (pp, "dualbank") == 0) { ts->flags |= CHIP_F_HAS_DUAL_BANK; } else if (strcmp (pp, "swo") == 0) { @@ -187,37 +187,37 @@ void process_chipfile(char *fname) { devicelist = ts; } -void dump_chips (void) { - struct stlink_chipid_params *ts; - char *p, buf[100]; - FILE *fp; - - for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) { - ts = &devices[n]; - - strcpy(buf, ts->dev_type); - - while ((p = strchr(buf, '/'))) // change slashes to underscore. - *p = '_'; - - strcat(buf, ".chip"); - fp = fopen(buf, "w"); - fprintf(fp, "# Device Type: %s\n", ts->dev_type); - fprintf(fp, "# Reference Manual: RM%s\n", ts->ref_manual_id); - fprintf(fp, "#\n"); - fprintf(fp, "chip_id %x\n", ts->chip_id); - fprintf(fp, "flash_type %x\n", ts->flash_type); - fprintf(fp, "flash_size_reg %x\n", ts->flash_size_reg); - fprintf(fp, "flash_pagesize %x\n", ts->flash_pagesize); - fprintf(fp, "sram_size %x\n", ts->sram_size); - fprintf(fp, "bootrom_base %x\n", ts->bootrom_base); - fprintf(fp, "bootrom_size %x\n", ts->bootrom_size); - fprintf(fp, "option_base %x\n", ts->option_base); - fprintf(fp, "option_size %x\n", ts->option_size); - fprintf(fp, "flags %x\n\n", ts->flags); - fclose(fp); - } -} +// void dump_chips (void) { +// struct stlink_chipid_params *ts; +// char *p, buf[100]; +// FILE *fp; + +// for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) { +// ts = &devices[n]; + +// strcpy(buf, ts->dev_type); + +// while ((p = strchr(buf, '/'))) // change slashes to underscore. +// *p = '_'; + +// strcat(buf, ".chip"); +// fp = fopen(buf, "w"); +// fprintf(fp, "# Device Type: %s\n", ts->dev_type); +// fprintf(fp, "# Reference Manual: RM%s\n", ts->ref_manual_id); +// fprintf(fp, "#\n"); +// fprintf(fp, "chip_id %x\n", ts->chip_id); +// fprintf(fp, "flash_type %x\n", ts->flash_type); +// fprintf(fp, "flash_size_reg %x\n", ts->flash_size_reg); +// fprintf(fp, "flash_pagesize %x\n", ts->flash_pagesize); +// fprintf(fp, "sram_size %x\n", ts->sram_size); +// fprintf(fp, "bootrom_base %x\n", ts->bootrom_base); +// fprintf(fp, "bootrom_size %x\n", ts->bootrom_size); +// fprintf(fp, "option_base %x\n", ts->option_base); +// fprintf(fp, "option_size %x\n", ts->option_size); +// fprintf(fp, "flags %x\n\n", ts->flags); +// fclose(fp); +// } +// } #if defined(STLINK_HAVE_DIRENT_H) #include @@ -248,7 +248,7 @@ void init_chipids(char *dir_to_scan) { closedir(d); } else { perror (dir_to_scan); - return; // XXX + return; } } #endif //STLINK_HAVE_DIRENT_H diff --git a/src/stlink-lib/chipid_db_old.h b/src/stlink-lib/chipid_db_old.h index 7acfef409..6578e35be 100644 --- a/src/stlink-lib/chipid_db_old.h +++ b/src/stlink-lib/chipid_db_old.h @@ -5,7 +5,7 @@ // change it both here and in the corresponding // config/chips/*.chip file. -static struct stlink_chipid_params devices[] = { +//static struct stlink_chipid_params devices[] = { { // STM32F03x // RM0091 @@ -874,4 +874,4 @@ static struct stlink_chipid_params devices[] = { .bootrom_base = 0x0, .bootrom_size = 0x0, }, -}; \ No newline at end of file +//}; \ No newline at end of file From 9b07c1dc191181b2d4311b2767a5731db1526f0c Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 9 Jan 2022 22:55:56 +0100 Subject: [PATCH 1274/1435] Transition to new enum stm32_flash_type --- config/chips/F03x.chip | 2 +- config/chips/F04x.chip | 2 +- config/chips/F05x.chip | 2 +- config/chips/F07x.chip | 2 +- config/chips/F09x.chip | 2 +- config/chips/F1xx_CL.chip | 2 +- config/chips/F1xx_HD.chip | 2 +- config/chips/F1xx_LD.chip | 2 +- config/chips/F1xx_MD.chip | 2 +- config/chips/F1xx_VL_HD.chip | 2 +- config/chips/F1xx_VL_MD_LD.chip | 2 +- config/chips/F1xx_XLD.chip | 2 +- config/chips/F2xx.chip | 2 +- config/chips/F301_F302_F318.chip | 2 +- config/chips/F302_F303_F358.chip | 2 +- config/chips/F302_F303_F398_HD.chip | 2 +- config/chips/F303_F328_F334.chip | 2 +- config/chips/F37x.chip | 2 +- config/chips/F401xB_xC.chip | 2 +- config/chips/F401xD_xE.chip | 2 +- config/chips/F410.chip | 2 +- config/chips/F411xC_xE.chip | 2 +- config/chips/F412.chip | 2 +- config/chips/F413_F423.chip | 2 +- config/chips/F42x_F43x.chip | 2 +- config/chips/F446.chip | 2 +- config/chips/F46x_F47x.chip | 2 +- config/chips/F4x5_F4x7.chip | 2 +- config/chips/F72x_F73x.chip | 2 +- config/chips/F74x_F75x.chip | 2 +- config/chips/F76x_F77x.chip | 2 +- config/chips/G03x_G04x.chip | 2 +- config/chips/G05x_G06x.chip | 2 +- config/chips/G07x_G08x.chip | 2 +- config/chips/G0Bx_G0Cx.chip | 2 +- config/chips/G43x_G44x.chip | 2 +- config/chips/G47x_G48x.chip | 2 +- config/chips/G49x_G4Ax.chip | 2 +- config/chips/H72x_H73x.chip | 2 +- config/chips/H74x_H75x.chip | 2 +- config/chips/H7Ax_H7Bx.chip | 2 +- config/chips/L0xxx_Cat_1.chip | 2 +- config/chips/L0xxx_Cat_2.chip | 2 +- config/chips/L0xxx_Cat_3.chip | 2 +- config/chips/L0xxx_Cat_5.chip | 2 +- config/chips/L1xx_Cat_1.chip | 2 +- config/chips/L1xx_Cat_2.chip | 2 +- config/chips/L1xx_Cat_3.chip | 2 +- config/chips/L1xx_Cat_4.chip | 2 +- config/chips/L1xx_Cat_5.chip | 2 +- config/chips/L41x_L42x.chip | 2 +- config/chips/L43x_L44x.chip | 2 +- config/chips/L45x_L46x.chip | 2 +- config/chips/L47x_L48x.chip | 2 +- config/chips/L496x_L4A6x.chip | 2 +- config/chips/L4Px.chip | 2 +- config/chips/L4Rx.chip | 2 +- config/chips/L5x5.chip | 2 +- config/chips/U5x5.chip | 2 +- config/chips/WBx0_WBx5.chip | 2 +- config/chips/WLx5.chip | 2 +- config/chips/unknown_device.chip | 2 +- inc/stlink.h | 5 +- inc/stm32.h | 18 + src/common.c | 505 ++++++++++++++-------------- src/st-flash/flash.c | 3 +- src/stlink-lib/chipid.c | 2 +- src/stlink-lib/chipid.h | 2 +- src/stlink-lib/flash_loader.c | 5 +- 69 files changed, 343 insertions(+), 321 deletions(-) diff --git a/config/chips/F03x.chip b/config/chips/F03x.chip index ea7fdb9e2..d19e6a657 100644 --- a/config/chips/F03x.chip +++ b/config/chips/F03x.chip @@ -3,7 +3,7 @@ dev_type STM32F03x ref_manual_id 0091 chip_id 0x444 // STLINK_CHIPID_STM32_F0xx_SMALL -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x400 // 1 KB sram_size 0x1000 // 4 KB diff --git a/config/chips/F04x.chip b/config/chips/F04x.chip index 3e702585b..7012d6d7e 100644 --- a/config/chips/F04x.chip +++ b/config/chips/F04x.chip @@ -3,7 +3,7 @@ dev_type STM32F04x ref_manual_id 0091 chip_id 0x445 // STLINK_CHIPID_STM32_F04 -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x400 // 1 KB sram_size 0x1800 // 6 KB diff --git a/config/chips/F05x.chip b/config/chips/F05x.chip index 1a4f61386..e987cf725 100644 --- a/config/chips/F05x.chip +++ b/config/chips/F05x.chip @@ -3,7 +3,7 @@ dev_type STM32F05x ref_manual_id 0091 chip_id 0x440 // STLINK_CHIPID_STM32_F0 -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x400 // 1 KB sram_size 0x2000 // 8 KB diff --git a/config/chips/F07x.chip b/config/chips/F07x.chip index 2a577b7b4..0f7513e1b 100644 --- a/config/chips/F07x.chip +++ b/config/chips/F07x.chip @@ -3,7 +3,7 @@ dev_type STM32F07x ref_manual_id 0091 chip_id 0x448 // STLINK_CHIPID_STM32_F0_CAN -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB sram_size 0x4000 // 16 KB diff --git a/config/chips/F09x.chip b/config/chips/F09x.chip index 9f419893e..3d3cc8c89 100644 --- a/config/chips/F09x.chip +++ b/config/chips/F09x.chip @@ -3,7 +3,7 @@ dev_type STM32F09x ref_manual_id 0091 chip_id 0x442 // STLINK_CHIPID_STM32_F09x -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB sram_size 0x8000 // 32 KB diff --git a/config/chips/F1xx_CL.chip b/config/chips/F1xx_CL.chip index 4c8bb0b8d..eb417132a 100644 --- a/config/chips/F1xx_CL.chip +++ b/config/chips/F1xx_CL.chip @@ -3,7 +3,7 @@ dev_type STM32F1xx_CL ref_manual_id 0008 chip_id 0x418 // STLINK_CHIPID_STM32_F1_CONN -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB sram_size 0x10000 // 64 KB diff --git a/config/chips/F1xx_HD.chip b/config/chips/F1xx_HD.chip index 18757029a..5def8ebb9 100644 --- a/config/chips/F1xx_HD.chip +++ b/config/chips/F1xx_HD.chip @@ -3,7 +3,7 @@ dev_type F1xx_HD ref_manual_id 0008 chip_id 0x414 // STLINK_CHIPID_STM32_F1_HD -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB sram_size 0x10000 // 64 KB diff --git a/config/chips/F1xx_LD.chip b/config/chips/F1xx_LD.chip index 8a8f5867d..33efe063a 100644 --- a/config/chips/F1xx_LD.chip +++ b/config/chips/F1xx_LD.chip @@ -3,7 +3,7 @@ dev_type STM32F1xx_LD ref_manual_id 0008 chip_id 0x412 // STLINK_CHIPID_STM32_F1_LD -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x400 // 1 KB sram_size 0x2800 // 10 KB diff --git a/config/chips/F1xx_MD.chip b/config/chips/F1xx_MD.chip index be492f54a..5b250d9cd 100644 --- a/config/chips/F1xx_MD.chip +++ b/config/chips/F1xx_MD.chip @@ -3,7 +3,7 @@ dev_type STM32F1xx_MD ref_manual_id 0008 chip_id 0x410 // STLINK_CHIPID_STM32_F1_MD -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x400 // 1 KB sram_size 0x5000 // 20 KB diff --git a/config/chips/F1xx_VL_HD.chip b/config/chips/F1xx_VL_HD.chip index f5ca6b023..1ceade91a 100644 --- a/config/chips/F1xx_VL_HD.chip +++ b/config/chips/F1xx_VL_HD.chip @@ -3,7 +3,7 @@ dev_type STM32F1xx_VL_HD ref_manual_id 0041 chip_id 0x428 // STLINK_CHIPID_STM32_F1_VL_HD -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB sram_size 0x8000 // 32 KB diff --git a/config/chips/F1xx_VL_MD_LD.chip b/config/chips/F1xx_VL_MD_LD.chip index e79668c70..3f577f74e 100644 --- a/config/chips/F1xx_VL_MD_LD.chip +++ b/config/chips/F1xx_VL_MD_LD.chip @@ -3,7 +3,7 @@ dev_type STM32F1xx_VL_MD_LD ref_manual_id 0041 chip_id 0x420 // STLINK_CHIPID_STM32_F1_VL_MD_LD -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x400 // 1 KB sram_size 0x2000 // 8 KB /* 0x1000 for low density devices */ diff --git a/config/chips/F1xx_XLD.chip b/config/chips/F1xx_XLD.chip index d7d8cf2b7..964105747 100644 --- a/config/chips/F1xx_XLD.chip +++ b/config/chips/F1xx_XLD.chip @@ -3,7 +3,7 @@ dev_type STM32F1xx_XLD ref_manual_id 0008 chip_id 0x430 // STLINK_CHIPID_STM32_F1_XLD -flash_type 2 // STLINK_FLASH_TYPE_F1_XL +flash_type 2 // STM32_FLASH_TYPE_F1_XL flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB sram_size 0x18000 // 96 KB diff --git a/config/chips/F2xx.chip b/config/chips/F2xx.chip index 67c225af5..4cb99b2fc 100644 --- a/config/chips/F2xx.chip +++ b/config/chips/F2xx.chip @@ -3,7 +3,7 @@ dev_type STM32F2xx ref_manual_id 0033 chip_id 0x411 // STLINK_CHIPID_STM32_F2 -flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x20000 // 128 KB sram_size 0x20000 // 128 KB diff --git a/config/chips/F301_F302_F318.chip b/config/chips/F301_F302_F318.chip index ee71dfe90..b35de12bf 100644 --- a/config/chips/F301_F302_F318.chip +++ b/config/chips/F301_F302_F318.chip @@ -3,7 +3,7 @@ dev_type STM32F301_F302_F318 ref_manual_id 0365 // also RM0366 chip_id 0x439 // STLINK_CHIPID_STM32_F3xx_SMALL -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB sram_size 0xa000 // 40 KB diff --git a/config/chips/F302_F303_F358.chip b/config/chips/F302_F303_F358.chip index 64d0651f2..6226ca8e8 100644 --- a/config/chips/F302_F303_F358.chip +++ b/config/chips/F302_F303_F358.chip @@ -3,7 +3,7 @@ dev_type STM32F302_F303_358 ref_manual_id 0365 // also RM0316 chip_id 0x422 // STLINK_CHIPID_STM32_F3 -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB sram_size 0xa000 // 40 KB diff --git a/config/chips/F302_F303_F398_HD.chip b/config/chips/F302_F303_F398_HD.chip index eaf36b74c..b4ad3aed8 100644 --- a/config/chips/F302_F303_F398_HD.chip +++ b/config/chips/F302_F303_F398_HD.chip @@ -3,7 +3,7 @@ dev_type STM32F302_F303_F398_HD ref_manual_id 0365 // also RM0316 (Rev 5) chip_id 0x446 // STLINK_CHIPID_STM32_F303_HD -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB sram_size 0x10000 // 64 KB diff --git a/config/chips/F303_F328_F334.chip b/config/chips/F303_F328_F334.chip index 2ecdbfb71..010c3b622 100644 --- a/config/chips/F303_F328_F334.chip +++ b/config/chips/F303_F328_F334.chip @@ -3,7 +3,7 @@ dev_type STM32F303_F328_F334 ref_manual_id 0364 // also RM0316 chip_id 0x438 // STLINK_CHIPID_STM32_F334 -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB sram_size 0x3000 // 12 KB diff --git a/config/chips/F37x.chip b/config/chips/F37x.chip index 1bd7ac421..9ca9d72f8 100644 --- a/config/chips/F37x.chip +++ b/config/chips/F37x.chip @@ -3,7 +3,7 @@ dev_type STM32F37x ref_manual_id 0313 chip_id 0x432 // STLINK_CHIPID_STM32_F37x -flash_type 1 // STLINK_FLASH_TYPE_F0 +flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB sram_size 0xa000 // 40 KB diff --git a/config/chips/F401xB_xC.chip b/config/chips/F401xB_xC.chip index fc93c2f1a..e1f37d94b 100644 --- a/config/chips/F401xB_xC.chip +++ b/config/chips/F401xB_xC.chip @@ -3,7 +3,7 @@ dev_type STM32F401xB_xC ref_manual_id 0368 chip_id 0x423 // STLINK_CHIPID_STM32_F4_LP -flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x10000 // 64 KB diff --git a/config/chips/F401xD_xE.chip b/config/chips/F401xD_xE.chip index e31d5eace..f03661495 100644 --- a/config/chips/F401xD_xE.chip +++ b/config/chips/F401xD_xE.chip @@ -3,7 +3,7 @@ dev_type STM32F401xD_xE ref_manual_id 0368 chip_id 0x433 // STLINK_CHIPID_STM32_F4_DE -flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x18000 // 96 KB diff --git a/config/chips/F410.chip b/config/chips/F410.chip index a8a7fbad0..6f7727921 100644 --- a/config/chips/F410.chip +++ b/config/chips/F410.chip @@ -3,7 +3,7 @@ dev_type STM32F410 ref_manual_id 0401 chip_id 0x458 // STLINK_CHIPID_STM32_F410 -flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x8000 // 32 KB diff --git a/config/chips/F411xC_xE.chip b/config/chips/F411xC_xE.chip index cf2cbd2c1..5d624b7d9 100644 --- a/config/chips/F411xC_xE.chip +++ b/config/chips/F411xC_xE.chip @@ -3,7 +3,7 @@ dev_type STM32F411xC_xE ref_manual_id 0383 chip_id 0x431 // STLINK_CHIPID_STM32_F411xx -flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x20000 // 128 KB diff --git a/config/chips/F412.chip b/config/chips/F412.chip index 4c866a3c5..bd18ec2ea 100644 --- a/config/chips/F412.chip +++ b/config/chips/F412.chip @@ -3,7 +3,7 @@ dev_type STM32F412 ref_manual_id 0402 chip_id 0x441 // STLINK_CHIPID_STM32_F412 -flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/F413_F423.chip b/config/chips/F413_F423.chip index 81ca585f6..c7e036a2d 100644 --- a/config/chips/F413_F423.chip +++ b/config/chips/F413_F423.chip @@ -3,7 +3,7 @@ dev_type STM32F413_F423 ref_manual_id 0430 // RM0430 (Rev 2) chip_id 0x463 // STLINK_CHIPID_STM32_F413 -flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x50000 // 320 KB diff --git a/config/chips/F42x_F43x.chip b/config/chips/F42x_F43x.chip index 2ec8fb8e8..cbb77e152 100644 --- a/config/chips/F42x_F43x.chip +++ b/config/chips/F42x_F43x.chip @@ -3,7 +3,7 @@ dev_type STM32F42x_F43x ref_manual_id 0090 // RM0090 (Rev. 2) chip_id 0x463 // STLINK_CHIPID_STM32_F4_HD -flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/F446.chip b/config/chips/F446.chip index 8cebe358e..2ac868ddd 100644 --- a/config/chips/F446.chip +++ b/config/chips/F446.chip @@ -3,7 +3,7 @@ dev_type STM32F446 ref_manual_id 0390 chip_id 0x421 // STLINK_CHIPID_STM32_F446 -flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x20000 // 128 KB sram_size 0x20000 // 128 KB diff --git a/config/chips/F46x_F47x.chip b/config/chips/F46x_F47x.chip index 2e4055f2c..e8d66cbd7 100644 --- a/config/chips/F46x_F47x.chip +++ b/config/chips/F46x_F47x.chip @@ -3,7 +3,7 @@ dev_type STM32F46x_F47x ref_manual_id 0090 // RM0090 (Rev. 2) chip_id 0x434 // STLINK_CHIPID_STM32_F4_DSI -flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/F4x5_F4x7.chip b/config/chips/F4x5_F4x7.chip index 9313c8ae1..d75f74103 100644 --- a/config/chips/F4x5_F4x7.chip +++ b/config/chips/F4x5_F4x7.chip @@ -3,7 +3,7 @@ dev_type STM32F4x5_F4x7 ref_manual_id 0090 // RM0090 (Rev. 2) chip_id 0x413 // STLINK_CHIPID_STM32_F4 -flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x30000 // 192 KB diff --git a/config/chips/F72x_F73x.chip b/config/chips/F72x_F73x.chip index 37dcd1234..c0f2df155 100644 --- a/config/chips/F72x_F73x.chip +++ b/config/chips/F72x_F73x.chip @@ -3,7 +3,7 @@ dev_type STM32F72x_F73x ref_manual_id 0431 chip_id 0x452 // STLINK_CHIPID_STM32_F72xxx -flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_type 4 // STM32_FLASH_TYPE_F7 flash_size_reg 0x1ff07a22 flash_pagesize 0x800 // 2 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/F74x_F75x.chip b/config/chips/F74x_F75x.chip index 96cc95217..fa0b6ddc2 100644 --- a/config/chips/F74x_F75x.chip +++ b/config/chips/F74x_F75x.chip @@ -3,7 +3,7 @@ dev_type STM32F74x_F75x ref_manual_id 0385 chip_id 0x449 // STLINK_CHIPID_STM32_F7 -flash_type 3 // STLINK_FLASH_TYPE_F4 +flash_type 4 // STM32_FLASH_TYPE_F7 flash_size_reg 0x1ff0f442 flash_pagesize 0x800 // 2 KB sram_size 0x50000 // 320 KB diff --git a/config/chips/F76x_F77x.chip b/config/chips/F76x_F77x.chip index a93aba2be..c1a5a9cf2 100644 --- a/config/chips/F76x_F77x.chip +++ b/config/chips/F76x_F77x.chip @@ -3,7 +3,7 @@ dev_type STM32F76x_F77x ref_manual_id 0410 chip_id 0x451 // STLINK_CHIPID_STM32_F76xxx -flash_type 4 // STLINK_FLASH_TYPE_F7 +flash_type 4 // STM32_FLASH_TYPE_F7 flash_size_reg 0x1ff0f442 flash_pagesize 0x800 // 2 KB sram_size 0x80000 // 512 KB diff --git a/config/chips/G03x_G04x.chip b/config/chips/G03x_G04x.chip index a21a9898f..aee016e0d 100644 --- a/config/chips/G03x_G04x.chip +++ b/config/chips/G03x_G04x.chip @@ -3,7 +3,7 @@ dev_type STM32G03x_G04x ref_manual_id 0444 // also RM454 chip_id 0x466 // STLINK_CHIPID_STM32_G0_CAT1 -flash_type 7 // STLINK_FLASH_TYPE_G0 +flash_type 5 // STM32_FLASH_TYPE_G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x2000 // 8 KB diff --git a/config/chips/G05x_G06x.chip b/config/chips/G05x_G06x.chip index 89af0825c..f92cad889 100644 --- a/config/chips/G05x_G06x.chip +++ b/config/chips/G05x_G06x.chip @@ -3,7 +3,7 @@ dev_type STM32G05x_G06x ref_manual_id 0444 chip_id 0x456 // STLINK_CHIPID_STM32_G0_CAT4 -flash_type 7 // STLINK_FLASH_TYPE_G0 +flash_type 5 // STM32_FLASH_TYPE_G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x9000 // 36 KB diff --git a/config/chips/G07x_G08x.chip b/config/chips/G07x_G08x.chip index c54de398f..29f527e73 100644 --- a/config/chips/G07x_G08x.chip +++ b/config/chips/G07x_G08x.chip @@ -3,7 +3,7 @@ dev_type STM32G07x_G08x ref_manual_id 0444 chip_id 0x460 // STLINK_CHIPID_STM32_G0_CAT2 -flash_type 7 // STLINK_FLASH_TYPE_G0 +flash_type 5 // STM32_FLASH_TYPE_G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x9000 // 36 KB diff --git a/config/chips/G0Bx_G0Cx.chip b/config/chips/G0Bx_G0Cx.chip index d8e0eb042..67254fbbd 100644 --- a/config/chips/G0Bx_G0Cx.chip +++ b/config/chips/G0Bx_G0Cx.chip @@ -3,7 +3,7 @@ dev_type STM32G0Bx_G0Cx ref_manual_id 0444 chip_id 0x467 // STLINK_CHIPID_STM32_G0_CAT3 -flash_type 7 // STLINK_FLASH_TYPE_G0 +flash_type 5 // STM32_FLASH_TYPE_G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x9000 // 36 KB diff --git a/config/chips/G43x_G44x.chip b/config/chips/G43x_G44x.chip index 455d65b8c..b33a1a0f8 100644 --- a/config/chips/G43x_G44x.chip +++ b/config/chips/G43x_G44x.chip @@ -3,7 +3,7 @@ dev_type STM32G43x_G44x ref_manual_id 0440 chip_id 0x468 // STLINK_CHIPID_STM32_G4_CAT2 -flash_type 8 // STLINK_FLASH_TYPE_G4 +flash_type 6 // STM32_FLASH_TYPE_G4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x8000 // 32 KB diff --git a/config/chips/G47x_G48x.chip b/config/chips/G47x_G48x.chip index 250905c68..abf6a6f2d 100644 --- a/config/chips/G47x_G48x.chip +++ b/config/chips/G47x_G48x.chip @@ -3,7 +3,7 @@ dev_type STM32G47x_G48x ref_manual_id 0440 chip_id 0x469 // STLINK_CHIPID_STM32_G4_CAT3 -flash_type 8 // STLINK_FLASH_TYPE_G4 +flash_type 6 // STM32_FLASH_TYPE_G4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x20000 // 128 KB diff --git a/config/chips/G49x_G4Ax.chip b/config/chips/G49x_G4Ax.chip index 9702541a8..3d8110f19 100644 --- a/config/chips/G49x_G4Ax.chip +++ b/config/chips/G49x_G4Ax.chip @@ -3,7 +3,7 @@ dev_type STM32G49x_G4Ax ref_manual_id 0440 chip_id 0x479 // STLINK_CHIPID_STM32_G4_CAT4 -flash_type 8 // STLINK_FLASH_TYPE_G4 +flash_type 6 // STM32_FLASH_TYPE_G4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x1c000 // 112 KB diff --git a/config/chips/H72x_H73x.chip b/config/chips/H72x_H73x.chip index 183c7d197..1417cdb27 100644 --- a/config/chips/H72x_H73x.chip +++ b/config/chips/H72x_H73x.chip @@ -3,7 +3,7 @@ dev_type STM32H72x_H73x ref_manual_id 0468 chip_id 0x483 // STLINK_CHIPID_STM32_H72x -flash_type 10 // STLINK_FLASH_TYPE_H7 +flash_type 7 // STM32_FLASH_TYPE_H7 flash_size_reg 0x1ff1e880 flash_pagesize 0x20000 // 128 KB sram_size 0x20000 // 128 KB "DTCM" diff --git a/config/chips/H74x_H75x.chip b/config/chips/H74x_H75x.chip index 2e543b197..53a3e921a 100644 --- a/config/chips/H74x_H75x.chip +++ b/config/chips/H74x_H75x.chip @@ -3,7 +3,7 @@ dev_type STM32H74x_H75x ref_manual_id 0433 chip_id 0x450 // STLINK_CHIPID_STM32_H74xxx -flash_type 10 // STLINK_FLASH_TYPE_H7 +flash_type 7 // STM32_FLASH_TYPE_H7 flash_size_reg 0x1ff1e880 flash_pagesize 0x20000 // 128 KB sram_size 0x20000 // 128 KB "DTCM" diff --git a/config/chips/H7Ax_H7Bx.chip b/config/chips/H7Ax_H7Bx.chip index b5fe72119..516c4260e 100644 --- a/config/chips/H7Ax_H7Bx.chip +++ b/config/chips/H7Ax_H7Bx.chip @@ -3,7 +3,7 @@ dev_type STM32H7Ax_H7Bx ref_manual_id 0455 chip_id 0x480 // STLINK_CHIPID_STM32_H7Ax -flash_type 10 // STLINK_FLASH_TYPE_H7 +flash_type 7 // STM32_FLASH_TYPE_H7 flash_size_reg 0x08fff80c flash_pagesize 0x2000 // 8 KB sram_size 0x20000 // 128 KB "DTCM" diff --git a/config/chips/L0xxx_Cat_1.chip b/config/chips/L0xxx_Cat_1.chip index 1dd8a1acb..6dc227024 100644 --- a/config/chips/L0xxx_Cat_1.chip +++ b/config/chips/L0xxx_Cat_1.chip @@ -3,7 +3,7 @@ dev_type STM32L0xxx_Cat_1 ref_manual_id 0451 // also RM0377 chip_id 0x457 // STLINK_CHIPID_STM32_L011 -flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B sram_size 0x2000 // 8 KB diff --git a/config/chips/L0xxx_Cat_2.chip b/config/chips/L0xxx_Cat_2.chip index 58d6439ba..74a3d6157 100644 --- a/config/chips/L0xxx_Cat_2.chip +++ b/config/chips/L0xxx_Cat_2.chip @@ -3,7 +3,7 @@ dev_type STM32L0xxx_Cat_2 ref_manual_id 0451 // also RM0377 chip_id 0x425 // STLINK_CHIPID_STM32_L0_CAT2 -flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B sram_size 0x2000 // 8 KB diff --git a/config/chips/L0xxx_Cat_3.chip b/config/chips/L0xxx_Cat_3.chip index 406c1a037..0cfcc53bb 100644 --- a/config/chips/L0xxx_Cat_3.chip +++ b/config/chips/L0xxx_Cat_3.chip @@ -3,7 +3,7 @@ dev_type STM32L0xxx_Cat_3 ref_manual_id 0451 // also RM0367 & RM0377 chip_id 0x417 // STLINK_CHIPID_STM32_L0 -flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B sram_size 0x2000 // 8 KB diff --git a/config/chips/L0xxx_Cat_5.chip b/config/chips/L0xxx_Cat_5.chip index 1a0c387a7..cbb1e6632 100644 --- a/config/chips/L0xxx_Cat_5.chip +++ b/config/chips/L0xxx_Cat_5.chip @@ -3,7 +3,7 @@ dev_type STM32L0xxx_Cat_5 ref_manual_id 0451 // also RM0367 & RM0377 chip_id 0x447 // STLINK_CHIPID_STM32_L0_CAT5 -flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B sram_size 0x5000 // 20 KB diff --git a/config/chips/L1xx_Cat_1.chip b/config/chips/L1xx_Cat_1.chip index 1d0b9282f..cecc32996 100644 --- a/config/chips/L1xx_Cat_1.chip +++ b/config/chips/L1xx_Cat_1.chip @@ -3,7 +3,7 @@ dev_type STM32L1xx_Cat_1 ref_manual_id 0038 chip_id 0x416 // STLINK_CHIPID_STM32_L1_MD -flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8004c flash_pagesize 0x100 // 128 B sram_size 0x4000 // 16 KB diff --git a/config/chips/L1xx_Cat_2.chip b/config/chips/L1xx_Cat_2.chip index f311e702c..1981d58a5 100644 --- a/config/chips/L1xx_Cat_2.chip +++ b/config/chips/L1xx_Cat_2.chip @@ -3,7 +3,7 @@ dev_type STM32L1xx_Cat_2 ref_manual_id 0038 chip_id 0x429 // STLINK_CHIPID_STM32_L1_CAT2 -flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8004c flash_pagesize 0x100 // 128 B sram_size 0x8000 // 32 KB diff --git a/config/chips/L1xx_Cat_3.chip b/config/chips/L1xx_Cat_3.chip index e6ecaf49e..1d551c8a4 100644 --- a/config/chips/L1xx_Cat_3.chip +++ b/config/chips/L1xx_Cat_3.chip @@ -3,7 +3,7 @@ dev_type STM32L1xx_Cat_3 ref_manual_id 0038 chip_id 0x427 // STLINK_CHIPID_STM32_L1_MD_PLUS -flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff800cc flash_pagesize 0x100 // 128 B sram_size 0x8000 // 32 KB diff --git a/config/chips/L1xx_Cat_4.chip b/config/chips/L1xx_Cat_4.chip index 8ed0e004a..1e9cfe91c 100644 --- a/config/chips/L1xx_Cat_4.chip +++ b/config/chips/L1xx_Cat_4.chip @@ -3,7 +3,7 @@ dev_type STM32L1xx_Cat_4 ref_manual_id 0038 chip_id 0x436 // STLINK_CHIPID_STM32_L1_MD_PLUS_HD -flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff800cc flash_pagesize 0x100 // 128 B sram_size 0xc000 // 48 KB diff --git a/config/chips/L1xx_Cat_5.chip b/config/chips/L1xx_Cat_5.chip index 75cebd94c..a51356d7a 100644 --- a/config/chips/L1xx_Cat_5.chip +++ b/config/chips/L1xx_Cat_5.chip @@ -3,7 +3,7 @@ dev_type STM32L1xx_Cat_5 ref_manual_id 0038 chip_id 0x437 // STLINK_CHIPID_STM32_L152_RE -flash_type 5 // STLINK_FLASH_TYPE_L0 +flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff800cc flash_pagesize 0x100 // 128 B sram_size 0x14000 // 80 KB diff --git a/config/chips/L41x_L42x.chip b/config/chips/L41x_L42x.chip index 97d0939ab..2de859b0c 100644 --- a/config/chips/L41x_L42x.chip +++ b/config/chips/L41x_L42x.chip @@ -3,7 +3,7 @@ dev_type STM32L41x_L42x ref_manual_id 0394 chip_id 0x464 // STLINK_CHIPID_STM32_L41x_L42x -flash_type 6 // STLINK_FLASH_TYPE_L4 +flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0xa000 // 40 KB diff --git a/config/chips/L43x_L44x.chip b/config/chips/L43x_L44x.chip index 369fdfa1e..2dad90844 100644 --- a/config/chips/L43x_L44x.chip +++ b/config/chips/L43x_L44x.chip @@ -3,7 +3,7 @@ dev_type STM32L41x_L42x ref_manual_id 0392 chip_id 0x435 // STLINK_CHIPID_STM32_L43x_L44x -flash_type 6 // STLINK_FLASH_TYPE_L4 +flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0xc000 // 48 KB diff --git a/config/chips/L45x_L46x.chip b/config/chips/L45x_L46x.chip index 2d1cda441..f856e1315 100644 --- a/config/chips/L45x_L46x.chip +++ b/config/chips/L45x_L46x.chip @@ -3,7 +3,7 @@ dev_type STM32L45x_L46x ref_manual_id 0394 chip_id 0x462 // STLINK_CHIPID_STM32_L45x_L46x -flash_type 6 // STLINK_FLASH_TYPE_L4 +flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x20000 // 128 KB diff --git a/config/chips/L47x_L48x.chip b/config/chips/L47x_L48x.chip index 4af25cf5c..51257a37c 100644 --- a/config/chips/L47x_L48x.chip +++ b/config/chips/L47x_L48x.chip @@ -3,7 +3,7 @@ dev_type STM32L47x_L48x ref_manual_id 0351 chip_id 0x415 // STLINK_CHIPID_STM32_L4 -flash_type 6 // STLINK_FLASH_TYPE_L4 +flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x18000 // 96 KB diff --git a/config/chips/L496x_L4A6x.chip b/config/chips/L496x_L4A6x.chip index 822914c96..32d75b571 100644 --- a/config/chips/L496x_L4A6x.chip +++ b/config/chips/L496x_L4A6x.chip @@ -3,7 +3,7 @@ dev_type STM32L496x_L4A6x ref_manual_id 0351 chip_id 0x461 // STLINK_CHIPID_STM32_L496x_L4A6x -flash_type 6 // STLINK_FLASH_TYPE_L4 +flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/L4Px.chip b/config/chips/L4Px.chip index 8366621e2..ff3f05b81 100644 --- a/config/chips/L4Px.chip +++ b/config/chips/L4Px.chip @@ -3,7 +3,7 @@ dev_type STM32L4Px ref_manual_id 0432 chip_id 0x471 // STLINK_CHIPID_STM32_L4PX -flash_type 6 // STLINK_FLASH_TYPE_L4 +flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x1000 // 4 KB sram_size 0xa0000 // 640 KB diff --git a/config/chips/L4Rx.chip b/config/chips/L4Rx.chip index 734f39199..535e282c9 100644 --- a/config/chips/L4Rx.chip +++ b/config/chips/L4Rx.chip @@ -3,7 +3,7 @@ dev_type STM32L4Rx ref_manual_id 0432 chip_id 0x470 // STLINK_CHIPID_STM32_L4RX -flash_type 6 // STLINK_FLASH_TYPE_L4 +flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x1000 // 4 KB sram_size 0xa0000 // 640 KB diff --git a/config/chips/L5x5.chip b/config/chips/L5x5.chip index ce268148b..9a5b2fdbf 100644 --- a/config/chips/L5x5.chip +++ b/config/chips/L5x5.chip @@ -3,7 +3,7 @@ dev_type STM32L5x2 ref_manual_id 0438 chip_id 0x0 // (temporary setting only!) -flash_type 0 // (temporary setting only!) +flash_type 10 // (temporary setting only!) flash_size_reg 0x0bfa07a0 flash_pagesize 0x2000 // 8 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/U5x5.chip b/config/chips/U5x5.chip index 177359cc3..55dfdaf7d 100644 --- a/config/chips/U5x5.chip +++ b/config/chips/U5x5.chip @@ -3,7 +3,7 @@ dev_type STM32U5x5 ref_manual_id 0456 chip_id 0x0 // (temporary setting only!) -flash_type 0 // (temporary setting only!) +flash_type 10 // (temporary setting only!) flash_size_reg 0x0bfa07a0 flash_pagesize 0x2000 // 8 KB sram_size 0xc4800 // 786 KB diff --git a/config/chips/WBx0_WBx5.chip b/config/chips/WBx0_WBx5.chip index ba5fee778..5fa76ec75 100644 --- a/config/chips/WBx0_WBx5.chip +++ b/config/chips/WBx0_WBx5.chip @@ -3,7 +3,7 @@ dev_type STM32WBx0_WBx5 ref_manual_id 0434 // also RM0471 chip_id 0x495 // STLINK_CHIPID_STM32_WB55 -flash_type 9 // STLINK_FLASH_TYPE_WB +flash_type 11 // STM32_FLASH_TYPE_WB_WL flash_size_reg 0x1fff75e0 flash_pagesize 0x1000 // 4 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/WLx5.chip b/config/chips/WLx5.chip index 2dc9ce648..62ff4f72f 100644 --- a/config/chips/WLx5.chip +++ b/config/chips/WLx5.chip @@ -3,7 +3,7 @@ dev_type STM32WLEx ref_manual_id 0033 chip_id 0x497 // STLINK_CHIPID_STM32_WLE -flash_type 9 // STLINK_FLASH_TYPE_WB +flash_type 11 // STM32_FLASH_TYPE_WB_WL flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x10000 // 64 KB diff --git a/config/chips/unknown_device.chip b/config/chips/unknown_device.chip index 1b74f22fa..512211092 100644 --- a/config/chips/unknown_device.chip +++ b/config/chips/unknown_device.chip @@ -3,7 +3,7 @@ dev_type unknown ref_manual_id 0000 chip_id 0x0 // STLINK_CHIPID_UNKNOWN -flash_type 0 // STLINK_FLASH_TYPE_UNKNOWN +flash_type 0 // STM32_FLASH_TYPE_UNKNOWN flash_size_reg 0x0 flash_pagesize 0x0 sram_size 0x0 diff --git a/inc/stlink.h b/inc/stlink.h index 0c1ca73a4..b387881ae 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -200,6 +200,7 @@ enum run_type { typedef struct _stlink stlink_t; +#include #include struct _stlink { @@ -222,8 +223,8 @@ struct _stlink { char serial[STLINK_SERIAL_BUFFER_SIZE]; int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR - enum stlink_flash_type flash_type; - // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx + enum stm32_flash_type flash_type; + // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STM32_FLASH_TYPE_xx stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() size_t flash_size; // calculated by stlink_load_device_params() diff --git a/inc/stm32.h b/inc/stm32.h index 7a5e983a4..280a61107 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -13,6 +13,24 @@ #define STM32H7_CORE_ID 0x6ba02477 // STM32H7 SWD ID Code #define STM32H7_CORE_ID_JTAG 0x6ba00477 // STM32H7 JTAG ID Code (RM0433 p.3065) +/* STM32 flash types */ +// New flash type definitions must go before STM32_FLASH_TYPE_UNDEFINED +// with the latter updated to the highest enum value. +enum stm32_flash_type { + STM32_FLASH_TYPE_UNKNOWN = 0, + STM32_FLASH_TYPE_F0_F1_F3 = 1, + STM32_FLASH_TYPE_F1_XL = 2, + STM32_FLASH_TYPE_F2_F4 = 3, + STM32_FLASH_TYPE_F7 = 4, + STM32_FLASH_TYPE_G0 = 5, // 7 + STM32_FLASH_TYPE_G4 = 6, // 8 + STM32_FLASH_TYPE_H7 = 7, // 10 + STM32_FLASH_TYPE_L0_L1 = 8, // 5 + STM32_FLASH_TYPE_L4_L4P = 9, // 6 + STM32_FLASH_TYPE_L5_U5 = 10, // new + STM32_FLASH_TYPE_WB_WL = 11, // 9 + STM32_FLASH_TYPE_UNDEFINED = 12, // max. value exceeded +}; /* Constant STM32 memory address */ #define STM32_SRAM_BASE ((uint32_t)0x20000000) diff --git a/src/common.c b/src/common.c index 48ff6120b..e73955f31 100644 --- a/src/common.c +++ b/src/common.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #ifdef STLINK_HAVE_SYS_MMAN_H @@ -467,18 +468,18 @@ static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { static inline uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { uint32_t reg, res; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { reg = FLASH_F4_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { reg = FLASH_F7_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { reg = STM32L4_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { reg = STM32WB_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; } else { reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; @@ -498,30 +499,30 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { uint32_t cr_reg; uint32_t n; - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { cr_reg = FLASH_CR; cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; cr_lock_shift = FLASH_F4_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; cr_lock_shift = FLASH_F7_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = STM32L0_FLASH_PELOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_lock_shift = STM32Gx_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = FLASH_H7_CR1; cr_lock_shift = FLASH_H7_CR_LOCK; } else { @@ -542,27 +543,27 @@ static void unlock_flash(stlink_t *sl) { * definitive lock of the FPEC block until next reset. */ - if (sl->flash_type == STLINK_FLASH_TYPE_F0) { + if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { key_reg = FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { key_reg = FLASH_KEYR; key2_reg = FLASH_KEYR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { key_reg = FLASH_F4_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { key_reg = FLASH_F7_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; flash_key1 = FLASH_L0_PEKEY1; flash_key2 = FLASH_L0_PEKEY2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { key_reg = STM32L4_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { key_reg = STM32Gx_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { key_reg = STM32WB_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { key_reg = FLASH_H7_KEYR1; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { key2_reg = FLASH_H7_KEYR2; @@ -600,33 +601,33 @@ static void lock_flash(stlink_t *sl) { uint32_t cr_lock_shift, cr_reg, n, cr2_reg = 0; uint32_t cr_mask = 0xffffffffu; - if (sl->flash_type == STLINK_FLASH_TYPE_F0) { + if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { cr_reg = FLASH_CR; cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { cr_reg = FLASH_CR; cr2_reg = FLASH_CR2; cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; cr_lock_shift = FLASH_F4_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; cr_lock_shift = FLASH_F7_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = STM32L0_FLASH_PELOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_lock_shift = STM32Gx_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = FLASH_H7_CR1; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { cr2_reg = FLASH_H7_CR2; @@ -655,38 +656,38 @@ static bool is_flash_option_locked(stlink_t *sl) { uint32_t n; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: optcr_reg = FLASH_CR; optlock_shift = FLASH_CR_OPTWRE; active_bit_level = 0; /* bit is "option write enable", not lock */ break; - case STLINK_FLASH_TYPE_F4: + case STM32_FLASH_TYPE_F2_F4: optcr_reg = FLASH_F4_OPTCR; optlock_shift = FLASH_F4_OPTCR_LOCK; break; - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: optcr_reg = FLASH_F7_OPTCR; optlock_shift = FLASH_F7_OPTCR_LOCK; break; - case STLINK_FLASH_TYPE_L0: + case STM32_FLASH_TYPE_L0_L1: optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; optlock_shift = STM32L0_FLASH_OPTLOCK; break; - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_L4_L4P: optcr_reg = STM32L4_FLASH_CR; optlock_shift = STM32L4_FLASH_CR_OPTLOCK; break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: optcr_reg = STM32Gx_FLASH_CR; optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; break; - case STLINK_FLASH_TYPE_WB: + case STM32_FLASH_TYPE_WB_WL: optcr_reg = STM32WB_FLASH_CR; optlock_shift = STM32WB_FLASH_CR_OPTLOCK; break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: optcr_reg = FLASH_H7_OPTCR; optlock_shift = FLASH_H7_OPTCR_OPTLOCK; break; @@ -709,38 +710,38 @@ static int lock_flash_option(stlink_t *sl) { int active_bit_level = 1; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: optcr_reg = FLASH_CR; optlock_shift = FLASH_CR_OPTWRE; active_bit_level = 0; break; - case STLINK_FLASH_TYPE_F4: + case STM32_FLASH_TYPE_F2_F4: optcr_reg = FLASH_F4_OPTCR; optlock_shift = FLASH_F4_OPTCR_LOCK; break; - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: optcr_reg = FLASH_F7_OPTCR; optlock_shift = FLASH_F7_OPTCR_LOCK; break; - case STLINK_FLASH_TYPE_L0: + case STM32_FLASH_TYPE_L0_L1: optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; optlock_shift = STM32L0_FLASH_OPTLOCK; break; - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_L4_L4P: optcr_reg = STM32L4_FLASH_CR; optlock_shift = STM32L4_FLASH_CR_OPTLOCK; break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: optcr_reg = STM32Gx_FLASH_CR; optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; break; - case STLINK_FLASH_TYPE_WB: + case STM32_FLASH_TYPE_WB_WL: optcr_reg = STM32WB_FLASH_CR; optlock_shift = STM32WB_FLASH_CR_OPTLOCK; break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: optcr_reg = FLASH_H7_OPTCR; optlock_shift = FLASH_H7_OPTCR_OPTLOCK; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) @@ -782,34 +783,34 @@ static int unlock_flash_option(stlink_t *sl) { uint32_t optkey2 = FLASH_OPTKEY2; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: optkey_reg = FLASH_OPTKEYR; optkey1 = FLASH_F0_OPTKEY1; optkey2 = FLASH_F0_OPTKEY2; break; - case STLINK_FLASH_TYPE_F4: + case STM32_FLASH_TYPE_F2_F4: optkey_reg = FLASH_F4_OPT_KEYR; break; - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: optkey_reg = FLASH_F7_OPT_KEYR; break; - case STLINK_FLASH_TYPE_L0: + case STM32_FLASH_TYPE_L0_L1: optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; optkey1 = FLASH_L0_OPTKEY1; optkey2 = FLASH_L0_OPTKEY2; break; - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_L4_L4P: optkey_reg = STM32L4_FLASH_OPTKEYR; break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: optkey_reg = STM32Gx_FLASH_OPTKEYR; break; - case STLINK_FLASH_TYPE_WB: + case STM32_FLASH_TYPE_WB_WL: optkey_reg = STM32WB_FLASH_OPT_KEYR; break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: optkey_reg = FLASH_H7_OPT_KEYR; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) optkey2_reg = FLASH_H7_OPT_KEYR2; @@ -852,24 +853,24 @@ static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { x = read_flash_cr(sl, bank); - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { cr_reg = STM32L4_FLASH_CR; x &= ~STM32L4_FLASH_CR_OPBITS; x |= (1 << STM32L4_FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; x |= (1 << FLASH_H7_CR_PG); } else { @@ -884,18 +885,18 @@ static void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { uint32_t cr_reg, n; uint32_t bit = FLASH_CR_PG; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { cr_reg = STM32L4_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; bit = FLASH_H7_CR_PG; } else { @@ -909,10 +910,10 @@ static void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { static void set_flash_cr_per(stlink_t *sl, unsigned bank) { uint32_t cr_reg, val; - if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; } else { cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; @@ -926,10 +927,10 @@ static void set_flash_cr_per(stlink_t *sl, unsigned bank) { static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { uint32_t cr_reg; - if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; } else { cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; @@ -942,20 +943,20 @@ static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { uint32_t val, cr_reg, cr_mer, cr_pg; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; cr_mer = 1 << FLASH_CR_MER; cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; cr_mer = 1 << FLASH_CR_MER; cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); cr_pg = (1 << STM32L4_FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_mer = (1 << STM32Gx_FLASH_CR_MER1); @@ -964,11 +965,11 @@ static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { } cr_pg = (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; cr_mer = (1 << FLASH_CR_MER); cr_pg = (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; cr_mer = (1 << FLASH_H7_CR_BER); cr_pg = (1 << FLASH_H7_CR_PG); @@ -998,23 +999,23 @@ static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { uint32_t val, cr_reg, cr_strt; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; cr_strt = 1 << FLASH_F4_CR_STRT; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; cr_strt = 1 << FLASH_F7_CR_STRT; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { cr_reg = STM32L4_FLASH_CR; cr_strt = (1 << STM32L4_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_strt = (1 << STM32Gx_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; cr_strt = (1 << STM32WB_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; cr_strt = 1 << FLASH_H7_CR_START(sl->chip_id); } else { @@ -1030,23 +1031,23 @@ static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { static inline uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { uint32_t res, sr_reg; - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { sr_reg = FLASH_F4_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { sr_reg = STM32L4_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { sr_reg = STM32Gx_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { sr_reg = STM32WB_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; } else { ELOG("method 'read_flash_sr' is unsupported\n"); @@ -1060,23 +1061,23 @@ static inline uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { uint32_t sr_reg; - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { sr_reg = FLASH_F4_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { sr_reg = STM32L4_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { sr_reg = STM32Gx_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { sr_reg = STM32WB_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; } else { ELOG("method 'write_flash_sr' is unsupported\n"); @@ -1090,22 +1091,22 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { uint32_t sr_busy_shift; unsigned int res; - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || - (sl->flash_type == STLINK_FLASH_TYPE_L0)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || + (sl->flash_type == STM32_FLASH_TYPE_L0_L1)) { sr_busy_shift = FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { sr_busy_shift = FLASH_F4_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { sr_busy_shift = FLASH_F7_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { sr_busy_shift = STM32L4_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { sr_busy_shift = STM32Gx_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { sr_busy_shift = STM32WB_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { sr_busy_shift = FLASH_H7_SR_QW; } else { ELOG("method 'is_flash_busy' is unsupported\n"); @@ -1114,8 +1115,8 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { res = read_flash_sr(sl, BANK_1) & (1 << sr_busy_shift); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || + (sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { res |= read_flash_sr(sl, BANK_2) & (1 << sr_busy_shift); } @@ -1149,32 +1150,32 @@ static void wait_flash_busy_progress(stlink_t *sl) { static void clear_flash_error(stlink_t *sl) { switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: + case STM32_FLASH_TYPE_F0_F1_F3: write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); break; - case STLINK_FLASH_TYPE_F4: + case STM32_FLASH_TYPE_F2_F4: write_flash_sr(sl, BANK_1, FLASH_F4_SR_ERROR_MASK); break; - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: write_flash_sr(sl, BANK_1, FLASH_F7_SR_ERROR_MASK); break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); break; - case STLINK_FLASH_TYPE_L0: + case STM32_FLASH_TYPE_L0_L1: write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); break; - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_L4_L4P: write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { write_flash_sr(sl, BANK_2, FLASH_H7_SR_ERROR_MASK); } break; - case STLINK_FLASH_TYPE_WB: + case STM32_FLASH_TYPE_WB_WL: write_flash_sr(sl, BANK_1, STM32WB_FLASH_SR_ERROR_MASK); break; default: @@ -1189,52 +1190,52 @@ static int check_flash_error(stlink_t *sl) { WRPERR = PROGERR = PGAERR = 0; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { res |= read_flash_sr(sl, BANK_2) & FLASH_SR_ERROR_MASK; } WRPERR = (1 << FLASH_SR_WRPRT_ERR); PROGERR = (1 << FLASH_SR_PG_ERR); break; - case STLINK_FLASH_TYPE_F4: + case STM32_FLASH_TYPE_F2_F4: res = read_flash_sr(sl, BANK_1) & FLASH_F4_SR_ERROR_MASK; WRPERR = (1 << FLASH_F4_SR_WRPERR); PGAERR = (1 << FLASH_F4_SR_PGAERR); break; - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: res = read_flash_sr(sl, BANK_1) & FLASH_F7_SR_ERROR_MASK; WRPERR = (1 << FLASH_F7_SR_WRP_ERR); PROGERR = (1 << FLASH_F7_SR_PGP_ERR); break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; WRPERR = (1 << STM32Gx_FLASH_SR_WRPERR); PROGERR = (1 << STM32Gx_FLASH_SR_PROGERR); PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); break; - case STLINK_FLASH_TYPE_L0: + case STM32_FLASH_TYPE_L0_L1: res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); break; - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_L4_L4P: res = read_flash_sr(sl, BANK_1) & STM32L4_FLASH_SR_ERROR_MASK; WRPERR = (1 << STM32L4_FLASH_SR_WRPERR); PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); PGAERR = (1 << STM32L4_FLASH_SR_PGAERR); break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; } WRPERR = (1 << FLASH_H7_SR_WRPERR); break; - case STLINK_FLASH_TYPE_WB: + case STM32_FLASH_TYPE_WB_WL: res = read_flash_sr(sl, BANK_1) & STM32WB_FLASH_SR_ERROR_MASK; WRPERR = (1 << STM32WB_FLASH_SR_WRPERR); PROGERR = (1 << STM32WB_FLASH_SR_PROGERR); @@ -1271,31 +1272,31 @@ static void stop_wdg_in_debug(stlink_t *sl) { uint32_t value; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - case STLINK_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_G4: dbgmcu_cr = STM32F0_DBGMCU_CR; set = (1 << STM32F0_DBGMCU_CR_IWDG_STOP) | (1 << STM32F0_DBGMCU_CR_WWDG_STOP); break; - case STLINK_FLASH_TYPE_F4: - case STLINK_FLASH_TYPE_F7: - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_F2_F4: + case STM32_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_L4_L4P: dbgmcu_cr = STM32F4_DBGMCU_APB1FZR1; set = (1 << STM32F4_DBGMCU_APB1FZR1_IWDG_STOP) | (1 << STM32F4_DBGMCU_APB1FZR1_WWDG_STOP); break; - case STLINK_FLASH_TYPE_L0: - case STLINK_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_L0_L1: + case STM32_FLASH_TYPE_G0: dbgmcu_cr = STM32L0_DBGMCU_APB1_FZ; set = (1 << STM32L0_DBGMCU_APB1_FZ_IWDG_STOP) | (1 << STM32L0_DBGMCU_APB1_FZ_WWDG_STOP); break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: dbgmcu_cr = STM32H7_DBGMCU_APB1HFZ; set = (1 << STM32H7_DBGMCU_APB1HFZ_IWDG_STOP); break; - case STLINK_FLASH_TYPE_WB: + case STM32_FLASH_TYPE_WB_WL: dbgmcu_cr = STM32WB_DBGMCU_APB1FZR1; set = (1 << STM32WB_DBGMCU_APB1FZR1_IWDG_STOP) | (1 << STM32WB_DBGMCU_APB1FZR1_WWDG_STOP); @@ -1315,34 +1316,34 @@ static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { rcc = rcc_dma_mask = value = 0; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: rcc = STM32F1_RCC_AHBENR; rcc_dma_mask = STM32F1_RCC_DMAEN; break; - case STLINK_FLASH_TYPE_F4: - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F2_F4: + case STM32_FLASH_TYPE_F7: rcc = STM32F4_RCC_AHB1ENR; rcc_dma_mask = STM32F4_RCC_DMAEN; break; - case STLINK_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G0: rcc = STM32G0_RCC_AHBENR; rcc_dma_mask = STM32G0_RCC_DMAEN; break; - case STLINK_FLASH_TYPE_G4: - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_L4_L4P: rcc = STM32G4_RCC_AHB1ENR; rcc_dma_mask = STM32G4_RCC_DMAEN; break; - case STLINK_FLASH_TYPE_L0: + case STM32_FLASH_TYPE_L0_L1: rcc = STM32L0_RCC_AHBENR; rcc_dma_mask = STM32L0_RCC_DMAEN; break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: rcc = STM32H7_RCC_AHB1ENR; rcc_dma_mask = STM32H7_RCC_DMAEN; break; - case STLINK_FLASH_TYPE_WB: + case STM32_FLASH_TYPE_WB_WL: rcc = STM32WB_RCC_AHB1ENR; rcc_dma_mask = STM32WB_RCC_DMAEN; break; @@ -1370,7 +1371,7 @@ static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n, uint32_t cr_reg, psize_shift; uint32_t x = read_flash_cr(sl, bank); - if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; psize_shift = FLASH_H7_CR_PSIZE; } else { @@ -1390,7 +1391,7 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, unsigned bank) { uint32_t cr_reg, snb_mask, snb_shift, ser_shift; uint32_t x = read_flash_cr(sl, bank); - if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; snb_mask = FLASH_H7_CR_SNB_MASK; snb_shift = FLASH_H7_CR_SNB; @@ -1443,7 +1444,7 @@ void stlink_close(stlink_t *sl) { int stlink_exit_debug_mode(stlink_t *sl) { DLOG("*** stlink_exit_debug_mode ***\n"); - if (sl->flash_type != STLINK_FLASH_TYPE_UNKNOWN && + if (sl->flash_type != STM32_FLASH_TYPE_UNKNOWN && sl->core_stat != TARGET_RESET) { // stop debugging if the target has been identified stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); @@ -1604,7 +1605,7 @@ int stlink_load_device_params(stlink_t *sl) { return (-1); } - if (params->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { + if (params->flash_type == STM32_FLASH_TYPE_UNKNOWN) { WLOG("Invalid flash type, please check device declaration\n"); sl->flash_size = 0; return (0); @@ -1666,7 +1667,7 @@ int stlink_load_device_params(stlink_t *sl) { // H7 devices with small flash has one bank if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK && - sl->flash_type == STLINK_FLASH_TYPE_H7) { + sl->flash_type == STM32_FLASH_TYPE_H7) { if ((sl->flash_size / sl->flash_pgsz) <= 1) sl->chip_flags &= ~CHIP_F_HAS_DUAL_BANK; } @@ -2777,9 +2778,9 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { // clear flash IO errors clear_flash_error(sl); - if (sl->flash_type == STLINK_FLASH_TYPE_F4 || - sl->flash_type == STLINK_FLASH_TYPE_F7 || - sl->flash_type == STLINK_FLASH_TYPE_L4) { + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4 || + sl->flash_type == STM32_FLASH_TYPE_F7 || + sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { // unlock if locked unlock_flash_if(sl); @@ -2826,7 +2827,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { #if DEBUG_FLASH fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl, BANK_1)); #endif - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { uint32_t val; uint32_t flash_regs_base = get_stm32l0_flash_base(sl); @@ -2882,15 +2883,15 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || + sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { uint32_t val; unlock_flash_if(sl); set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit // set the page to erase - if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); @@ -2900,7 +2901,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { val |= ((flash_page & 0xFF) << 3); stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); @@ -2908,7 +2909,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { val &= ~(0x3F << 3); val |= ((flash_page & 0x3F) << 3) | (1 << FLASH_CR_PER); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G4) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); @@ -2922,8 +2923,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { wait_flash_busy(sl); // wait for the 'busy' bit to clear clear_flash_cr_per(sl, BANK_1); // clear the 'enable page erase' bit lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_F0 || - sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3 || + sl->flash_type == STM32_FLASH_TYPE_F1_XL) { unsigned bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; unlock_flash_if(sl); clear_flash_cr_pg(sl, bank); // clear the pg bit @@ -2934,7 +2935,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { wait_flash_busy(sl); clear_flash_cr_per(sl, bank); // clear the page erase bit lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; unlock_flash_if(sl); // unlock if locked uint32_t sector = calculate_H7_sectornum( @@ -2955,8 +2956,8 @@ int stlink_erase_flash_mass(stlink_t *sl) { int err = 0; // TODO: User MER bit to mass-erase WB series. - if (sl->flash_type == STLINK_FLASH_TYPE_L0 || - sl->flash_type == STLINK_FLASH_TYPE_WB) { + if (sl->flash_type == STM32_FLASH_TYPE_L0_L1 || + sl->flash_type == STM32_FLASH_TYPE_WB_WL) { // erase each page int i = 0, num_pages = (int)(sl->flash_size / sl->flash_pgsz); @@ -2980,7 +2981,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { clear_flash_error(sl); unlock_flash_if(sl); - if (sl->flash_type == STLINK_FLASH_TYPE_H7 && + if (sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_id != STLINK_CHIPID_STM32_H7Ax) { // set parallelism write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); @@ -2993,8 +2994,8 @@ int stlink_erase_flash_mass(stlink_t *sl) { set_flash_cr_strt( sl, BANK_1); // start erase operation, reset by hw with busy bit - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || + (sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { set_flash_cr_mer(sl, 1, BANK_2); // set the mass erase bit in bank 2 set_flash_cr_strt(sl, BANK_2); // start erase operation in bank 2 @@ -3005,8 +3006,8 @@ int stlink_erase_flash_mass(stlink_t *sl) { // reset the mass erase bit set_flash_cr_mer(sl, 0, BANK_1); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || + (sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { set_flash_cr_mer(sl, 0, BANK_2); } @@ -3143,9 +3144,9 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { // Clear errors clear_flash_error(sl); - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || + (sl->flash_type == STM32_FLASH_TYPE_F7) || + (sl->flash_type == STM32_FLASH_TYPE_L4_L4P)) { ILOG("Starting Flash write for F2/F4/F7/L4\n"); // Flash loader initialisation @@ -3169,7 +3170,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { return (-1); } - if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { // L4 does not have a byte-write mode if (voltage < 1710) { ELOG("Target voltage (%d mV) too low for flash writes!\n", voltage); @@ -3189,14 +3190,14 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { // set programming mode set_flash_cr_pg(sl, BANK_1); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || + sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { ILOG("Starting Flash write for WB/G0/G4\n"); unlock_flash_if(sl); // unlock flash if necessary set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { ILOG("Starting Flash write for L0\n"); uint32_t val; @@ -3233,8 +3234,8 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { // L0/L1 have fallback to soft write WLOG("stlink_flash_loader_init() == -1\n"); } - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { ILOG("Starting Flash write for VL/F0/F3/F1_XL\n"); // flash loader initialisation @@ -3248,10 +3249,10 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { // set programming mode set_flash_cr_pg(sl, BANK_1); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { set_flash_cr_pg(sl, BANK_2); } - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { ILOG("Starting Flash write for H7\n"); unlock_flash_if(sl); // unlock the cr @@ -3277,9 +3278,9 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t *base, uint32_t len) { size_t off; - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || + (sl->flash_type == STM32_FLASH_TYPE_F7) || + (sl->flash_type == STM32_FLASH_TYPE_L4_L4P)) { size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; for (off = 0; off < len;) { size_t size = len - off > buf_size ? buf_size : len - off; @@ -3293,9 +3294,9 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, off += size; } - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || + sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); for (off = 0; off < len; off += sizeof(uint32_t)) { uint32_t data; @@ -3319,7 +3320,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, 0); // write a single word of zeros wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear } - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { uint32_t val; uint32_t flash_regs_base = get_stm32l0_flash_base(sl); uint32_t pagesize = (flash_regs_base==STM32L0_FLASH_REGS_ADDR)? @@ -3359,8 +3360,8 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, // TODO: check redo write operation } fprintf(stdout, "\n"); - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { int write_block_count = 0; for (off = 0; off < len; off += sl->flash_pgsz) { // adjust last write size @@ -3392,7 +3393,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, if (sl->verbose >= 1) { fprintf(stdout, "\n"); } - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { for (off = 0; off < len;) { // Program STM32H7x with 64-byte Flash words size_t chunk = (len - off > 64) ? 64 : len - off; @@ -3422,24 +3423,24 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { uint32_t dhcsr; - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || - (sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4) || - (sl->flash_type == STLINK_FLASH_TYPE_WB) || - (sl->flash_type == STLINK_FLASH_TYPE_G0) || - (sl->flash_type == STLINK_FLASH_TYPE_G4) || - (sl->flash_type == STLINK_FLASH_TYPE_H7)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || + (sl->flash_type == STM32_FLASH_TYPE_F2_F4) || + (sl->flash_type == STM32_FLASH_TYPE_F7) || + (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) || + (sl->flash_type == STM32_FLASH_TYPE_WB_WL) || + (sl->flash_type == STM32_FLASH_TYPE_G0) || + (sl->flash_type == STM32_FLASH_TYPE_G4) || + (sl->flash_type == STM32_FLASH_TYPE_H7)) { clear_flash_cr_pg(sl, BANK_1); - if ((sl->flash_type == STLINK_FLASH_TYPE_H7 && + if ((sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK) || - sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + sl->flash_type == STM32_FLASH_TYPE_F1_XL) { clear_flash_cr_pg(sl, BANK_2); } lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { uint32_t val; uint32_t flash_regs_base = get_stm32l0_flash_base(sl); @@ -3716,7 +3717,7 @@ int stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **mem, } uint8_t stlink_get_erased_pattern(stlink_t *sl) { - if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { return (0x00); } else { return (0xff); @@ -4387,7 +4388,7 @@ int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: return stlink_read_option_bytes_boot_add_f7(sl, option_byte); default: return -1; @@ -4408,10 +4409,10 @@ int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: return stlink_read_option_control_register_f0(sl, option_byte); - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: return stlink_read_option_control_register_f7(sl, option_byte); default: return -1; @@ -4432,7 +4433,7 @@ int stlink_read_option_control_register1_32(stlink_t *sl, } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: return stlink_read_option_control_register1_f7(sl, option_byte); default: return -1; @@ -4494,27 +4495,27 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: ret = stlink_write_option_bytes_f0(sl, base, addr, len); break; - case STLINK_FLASH_TYPE_F4: + case STM32_FLASH_TYPE_F2_F4: ret = stlink_write_option_bytes_f4(sl, base, addr, len); break; - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: ret = stlink_write_option_bytes_f7(sl, base, addr, len); break; - case STLINK_FLASH_TYPE_L0: + case STM32_FLASH_TYPE_L0_L1: ret = stlink_write_option_bytes_l0(sl, base, addr, len); break; - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_L4_L4P: ret = stlink_write_option_bytes_l4(sl, base, addr, len); break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: ret = stlink_write_option_bytes_gx(sl, base, addr, len); break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: ret = stlink_write_option_bytes_h7(sl, base, addr, len); break; default: @@ -4732,7 +4733,7 @@ int stlink_write_option_bytes_boot_add32(stlink_t *sl, } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); break; default: @@ -4777,11 +4778,11 @@ int stlink_write_option_control_register32(stlink_t *sl, } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: ret = stlink_write_option_control_register_f0(sl, option_control_register); break; - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: ret = stlink_write_option_control_register_f7(sl, option_control_register); break; default: @@ -4826,7 +4827,7 @@ int stlink_write_option_control_register1_32( } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: ret = stlink_write_option_control_register1_f7(sl, option_control_register1); break; diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 51702b683..dfc972c4e 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -8,6 +8,7 @@ #include #include +#include #include #include "flash.h" @@ -67,7 +68,7 @@ int main(int ac, char** av) { if (sl == NULL) { return(-1); } - if (sl->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { + if (sl->flash_type == STM32_FLASH_TYPE_UNKNOWN) { printf("Failed to connect to target\n"); goto on_error; } diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 4ab83ba3d..78233ec1c 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -129,7 +129,7 @@ void process_chipfile(char *fname) { } else if (strcmp (word, "flash_type") == 0) { if (sscanf(value, "%i", (int *)&ts->flash_type) < 1) { fprintf(stderr, "Failed to parse flash type\n"); - } else if ((ts->flash_type < STLINK_FLASH_TYPE_UNKNOWN) || (ts->flash_type >= STLINK_FLASH_TYPE_MAX)) { + } else if ((ts->flash_type < STM32_FLASH_TYPE_UNKNOWN) || (ts->flash_type >= STM32_FLASH_TYPE_UNDEFINED)) { fprintf(stderr, "Unrecognized flash type\n"); } } else if (strcmp (word, "flash_size_reg") == 0) { diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index e821f0b57..86cd49ddb 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -13,7 +13,7 @@ struct stlink_chipid_params { char *dev_type; char *ref_manual_id; uint32_t chip_id; - enum stlink_flash_type flash_type; + enum stm32_flash_type flash_type; uint32_t flash_size_reg; uint32_t flash_pagesize; uint32_t sram_size; diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 7076a2cfa..6b318dc46 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include "flash_loader.h" @@ -176,7 +177,7 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { ILOG("Successfully loaded flash loader in sram\n"); // set address of IWDG key register for reset it - if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + if (sl->flash_type == STM32_FLASH_TYPE_H7) { fl->iwdg_kr = STM32H7_WDG_KR; } else { fl->iwdg_kr = STM32F0_WDG_KR; @@ -333,7 +334,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe return(-1); } - if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (target >= FLASH_BANK2_START_ADDR)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F1_XL) && (target >= FLASH_BANK2_START_ADDR)) { flash_base = FLASH_REGS_BANK2_OFS; } From 115f7c846adf612c1ee818713530dbf17287ed9b Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 9 Jan 2022 23:53:30 +0100 Subject: [PATCH 1275/1435] Transition to new enum stm32_chipids --- config/chips/F03x.chip | 2 +- config/chips/F04x.chip | 2 +- config/chips/F05x.chip | 2 +- config/chips/F07x.chip | 2 +- config/chips/F09x.chip | 2 +- config/chips/F1xx_CL.chip | 2 +- config/chips/F1xx_HD.chip | 2 +- config/chips/F1xx_LD.chip | 2 +- config/chips/F1xx_MD.chip | 2 +- config/chips/F1xx_VL_HD.chip | 2 +- config/chips/F1xx_VL_MD_LD.chip | 2 +- config/chips/F1xx_XLD.chip | 2 +- config/chips/F2xx.chip | 2 +- config/chips/F301_F302_F318.chip | 2 +- config/chips/F302_F303_F358.chip | 2 +- config/chips/F302_F303_F398_HD.chip | 2 +- config/chips/F303_F328_F334.chip | 2 +- config/chips/F37x.chip | 2 +- config/chips/F401xB_xC.chip | 2 +- config/chips/F401xD_xE.chip | 2 +- config/chips/F410.chip | 2 +- config/chips/F411xC_xE.chip | 2 +- config/chips/F412.chip | 2 +- config/chips/F413_F423.chip | 2 +- config/chips/F42x_F43x.chip | 2 +- config/chips/F446.chip | 2 +- config/chips/F46x_F47x.chip | 2 +- config/chips/F4x5_F4x7.chip | 2 +- config/chips/F72x_F73x.chip | 2 +- config/chips/F74x_F75x.chip | 2 +- config/chips/F76x_F77x.chip | 2 +- config/chips/G03x_G04x.chip | 2 +- config/chips/G05x_G06x.chip | 2 +- config/chips/G07x_G08x.chip | 2 +- config/chips/G0Bx_G0Cx.chip | 2 +- config/chips/G43x_G44x.chip | 2 +- config/chips/G47x_G48x.chip | 2 +- config/chips/G49x_G4Ax.chip | 2 +- config/chips/H72x_H73x.chip | 2 +- config/chips/H74x_H75x.chip | 2 +- config/chips/H7Ax_H7Bx.chip | 2 +- config/chips/L0xxx_Cat_1.chip | 2 +- config/chips/L0xxx_Cat_2.chip | 2 +- config/chips/L0xxx_Cat_3.chip | 2 +- config/chips/L0xxx_Cat_5.chip | 2 +- config/chips/L1xx_Cat_1.chip | 2 +- config/chips/L1xx_Cat_2.chip | 2 +- config/chips/L1xx_Cat_3.chip | 2 +- config/chips/L1xx_Cat_4.chip | 2 +- config/chips/L1xx_Cat_5.chip | 2 +- config/chips/L41x_L42x.chip | 2 +- config/chips/L43x_L44x.chip | 2 +- config/chips/L45x_L46x.chip | 2 +- config/chips/L47x_L48x.chip | 2 +- config/chips/L496x_L4A6x.chip | 2 +- config/chips/L4Px.chip | 2 +- config/chips/L4Rx.chip | 2 +- config/chips/WBx0_WBx5.chip | 2 +- config/chips/WLx5.chip | 2 +- config/chips/unknown_device.chip | 2 +- inc/stlink.h | 32 +- inc/stm32.h | 142 +++-- src/common.c | 96 +-- src/st-trace/trace.c | 2 +- src/st-util/gdb-server.c | 28 +- src/stlink-lib/chipid_db_old.h | 877 ---------------------------- src/stlink-lib/flash_loader.c | 92 +-- 67 files changed, 254 insertions(+), 1135 deletions(-) delete mode 100644 src/stlink-lib/chipid_db_old.h diff --git a/config/chips/F03x.chip b/config/chips/F03x.chip index d19e6a657..3b4ff2a74 100644 --- a/config/chips/F03x.chip +++ b/config/chips/F03x.chip @@ -2,7 +2,7 @@ # dev_type STM32F03x ref_manual_id 0091 -chip_id 0x444 // STLINK_CHIPID_STM32_F0xx_SMALL +chip_id 0x444 // STM32_CHIPID_STM32_F0xx_SMALL flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x400 // 1 KB diff --git a/config/chips/F04x.chip b/config/chips/F04x.chip index 7012d6d7e..267c93765 100644 --- a/config/chips/F04x.chip +++ b/config/chips/F04x.chip @@ -2,7 +2,7 @@ # dev_type STM32F04x ref_manual_id 0091 -chip_id 0x445 // STLINK_CHIPID_STM32_F04 +chip_id 0x445 // STM32_CHIPID_STM32_F04 flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x400 // 1 KB diff --git a/config/chips/F05x.chip b/config/chips/F05x.chip index e987cf725..dc511e1a2 100644 --- a/config/chips/F05x.chip +++ b/config/chips/F05x.chip @@ -2,7 +2,7 @@ # dev_type STM32F05x ref_manual_id 0091 -chip_id 0x440 // STLINK_CHIPID_STM32_F0 +chip_id 0x440 // STM32_CHIPID_STM32_F0 flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x400 // 1 KB diff --git a/config/chips/F07x.chip b/config/chips/F07x.chip index 0f7513e1b..b12ef1bab 100644 --- a/config/chips/F07x.chip +++ b/config/chips/F07x.chip @@ -2,7 +2,7 @@ # dev_type STM32F07x ref_manual_id 0091 -chip_id 0x448 // STLINK_CHIPID_STM32_F0_CAN +chip_id 0x448 // STM32_CHIPID_STM32_F0_CAN flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F09x.chip b/config/chips/F09x.chip index 3d3cc8c89..97f1a1a75 100644 --- a/config/chips/F09x.chip +++ b/config/chips/F09x.chip @@ -2,7 +2,7 @@ # dev_type STM32F09x ref_manual_id 0091 -chip_id 0x442 // STLINK_CHIPID_STM32_F09x +chip_id 0x442 // STM32_CHIPID_STM32_F09x flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F1xx_CL.chip b/config/chips/F1xx_CL.chip index eb417132a..dd316dca3 100644 --- a/config/chips/F1xx_CL.chip +++ b/config/chips/F1xx_CL.chip @@ -2,7 +2,7 @@ # dev_type STM32F1xx_CL ref_manual_id 0008 -chip_id 0x418 // STLINK_CHIPID_STM32_F1_CONN +chip_id 0x418 // STM32_CHIPID_STM32_F1_CONN flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F1xx_HD.chip b/config/chips/F1xx_HD.chip index 5def8ebb9..696b284ba 100644 --- a/config/chips/F1xx_HD.chip +++ b/config/chips/F1xx_HD.chip @@ -2,7 +2,7 @@ # dev_type F1xx_HD ref_manual_id 0008 -chip_id 0x414 // STLINK_CHIPID_STM32_F1_HD +chip_id 0x414 // STM32_CHIPID_STM32_F1_HD flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F1xx_LD.chip b/config/chips/F1xx_LD.chip index 33efe063a..898af4c8c 100644 --- a/config/chips/F1xx_LD.chip +++ b/config/chips/F1xx_LD.chip @@ -2,7 +2,7 @@ # dev_type STM32F1xx_LD ref_manual_id 0008 -chip_id 0x412 // STLINK_CHIPID_STM32_F1_LD +chip_id 0x412 // STM32_CHIPID_STM32_F1_LD flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x400 // 1 KB diff --git a/config/chips/F1xx_MD.chip b/config/chips/F1xx_MD.chip index 5b250d9cd..a611f3f2d 100644 --- a/config/chips/F1xx_MD.chip +++ b/config/chips/F1xx_MD.chip @@ -2,7 +2,7 @@ # dev_type STM32F1xx_MD ref_manual_id 0008 -chip_id 0x410 // STLINK_CHIPID_STM32_F1_MD +chip_id 0x410 // STM32_CHIPID_STM32_F1_MD flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x400 // 1 KB diff --git a/config/chips/F1xx_VL_HD.chip b/config/chips/F1xx_VL_HD.chip index 1ceade91a..d59fa4814 100644 --- a/config/chips/F1xx_VL_HD.chip +++ b/config/chips/F1xx_VL_HD.chip @@ -2,7 +2,7 @@ # dev_type STM32F1xx_VL_HD ref_manual_id 0041 -chip_id 0x428 // STLINK_CHIPID_STM32_F1_VL_HD +chip_id 0x428 // STM32_CHIPID_STM32_F1_VL_HD flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F1xx_VL_MD_LD.chip b/config/chips/F1xx_VL_MD_LD.chip index 3f577f74e..aac2244fd 100644 --- a/config/chips/F1xx_VL_MD_LD.chip +++ b/config/chips/F1xx_VL_MD_LD.chip @@ -2,7 +2,7 @@ # dev_type STM32F1xx_VL_MD_LD ref_manual_id 0041 -chip_id 0x420 // STLINK_CHIPID_STM32_F1_VL_MD_LD +chip_id 0x420 // STM32_CHIPID_STM32_F1_VL_MD_LD flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x400 // 1 KB diff --git a/config/chips/F1xx_XLD.chip b/config/chips/F1xx_XLD.chip index 964105747..7627dd883 100644 --- a/config/chips/F1xx_XLD.chip +++ b/config/chips/F1xx_XLD.chip @@ -2,7 +2,7 @@ # dev_type STM32F1xx_XLD ref_manual_id 0008 -chip_id 0x430 // STLINK_CHIPID_STM32_F1_XLD +chip_id 0x430 // STM32_CHIPID_STM32_F1_XLD flash_type 2 // STM32_FLASH_TYPE_F1_XL flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F2xx.chip b/config/chips/F2xx.chip index 4cb99b2fc..5e6aac5a0 100644 --- a/config/chips/F2xx.chip +++ b/config/chips/F2xx.chip @@ -2,7 +2,7 @@ # dev_type STM32F2xx ref_manual_id 0033 -chip_id 0x411 // STLINK_CHIPID_STM32_F2 +chip_id 0x411 // STM32_CHIPID_STM32_F2 flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x20000 // 128 KB diff --git a/config/chips/F301_F302_F318.chip b/config/chips/F301_F302_F318.chip index b35de12bf..3a3d8bb45 100644 --- a/config/chips/F301_F302_F318.chip +++ b/config/chips/F301_F302_F318.chip @@ -2,7 +2,7 @@ # dev_type STM32F301_F302_F318 ref_manual_id 0365 // also RM0366 -chip_id 0x439 // STLINK_CHIPID_STM32_F3xx_SMALL +chip_id 0x439 // STM32_CHIPID_STM32_F3xx_SMALL flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F302_F303_F358.chip b/config/chips/F302_F303_F358.chip index 6226ca8e8..922387292 100644 --- a/config/chips/F302_F303_F358.chip +++ b/config/chips/F302_F303_F358.chip @@ -2,7 +2,7 @@ # dev_type STM32F302_F303_358 ref_manual_id 0365 // also RM0316 -chip_id 0x422 // STLINK_CHIPID_STM32_F3 +chip_id 0x422 // STM32_CHIPID_STM32_F3 flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F302_F303_F398_HD.chip b/config/chips/F302_F303_F398_HD.chip index b4ad3aed8..44cec8a6d 100644 --- a/config/chips/F302_F303_F398_HD.chip +++ b/config/chips/F302_F303_F398_HD.chip @@ -2,7 +2,7 @@ # dev_type STM32F302_F303_F398_HD ref_manual_id 0365 // also RM0316 (Rev 5) -chip_id 0x446 // STLINK_CHIPID_STM32_F303_HD +chip_id 0x446 // STM32_CHIPID_STM32_F303_HD flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F303_F328_F334.chip b/config/chips/F303_F328_F334.chip index 010c3b622..fb77e3117 100644 --- a/config/chips/F303_F328_F334.chip +++ b/config/chips/F303_F328_F334.chip @@ -2,7 +2,7 @@ # dev_type STM32F303_F328_F334 ref_manual_id 0364 // also RM0316 -chip_id 0x438 // STLINK_CHIPID_STM32_F334 +chip_id 0x438 // STM32_CHIPID_STM32_F334 flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F37x.chip b/config/chips/F37x.chip index 9ca9d72f8..5363da8fa 100644 --- a/config/chips/F37x.chip +++ b/config/chips/F37x.chip @@ -2,7 +2,7 @@ # dev_type STM32F37x ref_manual_id 0313 -chip_id 0x432 // STLINK_CHIPID_STM32_F37x +chip_id 0x432 // STM32_CHIPID_STM32_F37x flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F401xB_xC.chip b/config/chips/F401xB_xC.chip index e1f37d94b..e75b27d09 100644 --- a/config/chips/F401xB_xC.chip +++ b/config/chips/F401xB_xC.chip @@ -2,7 +2,7 @@ # dev_type STM32F401xB_xC ref_manual_id 0368 -chip_id 0x423 // STLINK_CHIPID_STM32_F4_LP +chip_id 0x423 // STM32_CHIPID_STM32_F4_LP flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F401xD_xE.chip b/config/chips/F401xD_xE.chip index f03661495..022d5072a 100644 --- a/config/chips/F401xD_xE.chip +++ b/config/chips/F401xD_xE.chip @@ -2,7 +2,7 @@ # dev_type STM32F401xD_xE ref_manual_id 0368 -chip_id 0x433 // STLINK_CHIPID_STM32_F4_DE +chip_id 0x433 // STM32_CHIPID_STM32_F4_DE flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F410.chip b/config/chips/F410.chip index 6f7727921..84c9c00bf 100644 --- a/config/chips/F410.chip +++ b/config/chips/F410.chip @@ -2,7 +2,7 @@ # dev_type STM32F410 ref_manual_id 0401 -chip_id 0x458 // STLINK_CHIPID_STM32_F410 +chip_id 0x458 // STM32_CHIPID_STM32_F410 flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F411xC_xE.chip b/config/chips/F411xC_xE.chip index 5d624b7d9..d028a874c 100644 --- a/config/chips/F411xC_xE.chip +++ b/config/chips/F411xC_xE.chip @@ -2,7 +2,7 @@ # dev_type STM32F411xC_xE ref_manual_id 0383 -chip_id 0x431 // STLINK_CHIPID_STM32_F411xx +chip_id 0x431 // STM32_CHIPID_STM32_F411xx flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F412.chip b/config/chips/F412.chip index bd18ec2ea..b4c1cb418 100644 --- a/config/chips/F412.chip +++ b/config/chips/F412.chip @@ -2,7 +2,7 @@ # dev_type STM32F412 ref_manual_id 0402 -chip_id 0x441 // STLINK_CHIPID_STM32_F412 +chip_id 0x441 // STM32_CHIPID_STM32_F412 flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F413_F423.chip b/config/chips/F413_F423.chip index c7e036a2d..f042bce76 100644 --- a/config/chips/F413_F423.chip +++ b/config/chips/F413_F423.chip @@ -2,7 +2,7 @@ # dev_type STM32F413_F423 ref_manual_id 0430 // RM0430 (Rev 2) -chip_id 0x463 // STLINK_CHIPID_STM32_F413 +chip_id 0x463 // STM32_CHIPID_STM32_F413 flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F42x_F43x.chip b/config/chips/F42x_F43x.chip index cbb77e152..69aff7c88 100644 --- a/config/chips/F42x_F43x.chip +++ b/config/chips/F42x_F43x.chip @@ -2,7 +2,7 @@ # dev_type STM32F42x_F43x ref_manual_id 0090 // RM0090 (Rev. 2) -chip_id 0x463 // STLINK_CHIPID_STM32_F4_HD +chip_id 0x463 // STM32_CHIPID_STM32_F4_HD flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F446.chip b/config/chips/F446.chip index 2ac868ddd..5fa2edbcb 100644 --- a/config/chips/F446.chip +++ b/config/chips/F446.chip @@ -2,7 +2,7 @@ # dev_type STM32F446 ref_manual_id 0390 -chip_id 0x421 // STLINK_CHIPID_STM32_F446 +chip_id 0x421 // STM32_CHIPID_STM32_F446 flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x20000 // 128 KB diff --git a/config/chips/F46x_F47x.chip b/config/chips/F46x_F47x.chip index e8d66cbd7..e8364ead5 100644 --- a/config/chips/F46x_F47x.chip +++ b/config/chips/F46x_F47x.chip @@ -2,7 +2,7 @@ # dev_type STM32F46x_F47x ref_manual_id 0090 // RM0090 (Rev. 2) -chip_id 0x434 // STLINK_CHIPID_STM32_F4_DSI +chip_id 0x434 // STM32_CHIPID_STM32_F4_DSI flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F4x5_F4x7.chip b/config/chips/F4x5_F4x7.chip index d75f74103..e78b552c4 100644 --- a/config/chips/F4x5_F4x7.chip +++ b/config/chips/F4x5_F4x7.chip @@ -2,7 +2,7 @@ # dev_type STM32F4x5_F4x7 ref_manual_id 0090 // RM0090 (Rev. 2) -chip_id 0x413 // STLINK_CHIPID_STM32_F4 +chip_id 0x413 // STM32_CHIPID_STM32_F4 flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F72x_F73x.chip b/config/chips/F72x_F73x.chip index c0f2df155..5e1131d2e 100644 --- a/config/chips/F72x_F73x.chip +++ b/config/chips/F72x_F73x.chip @@ -2,7 +2,7 @@ # dev_type STM32F72x_F73x ref_manual_id 0431 -chip_id 0x452 // STLINK_CHIPID_STM32_F72xxx +chip_id 0x452 // STM32_CHIPID_STM32_F72xxx flash_type 4 // STM32_FLASH_TYPE_F7 flash_size_reg 0x1ff07a22 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F74x_F75x.chip b/config/chips/F74x_F75x.chip index fa0b6ddc2..391ae124d 100644 --- a/config/chips/F74x_F75x.chip +++ b/config/chips/F74x_F75x.chip @@ -2,7 +2,7 @@ # dev_type STM32F74x_F75x ref_manual_id 0385 -chip_id 0x449 // STLINK_CHIPID_STM32_F7 +chip_id 0x449 // STM32_CHIPID_STM32_F7 flash_type 4 // STM32_FLASH_TYPE_F7 flash_size_reg 0x1ff0f442 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F76x_F77x.chip b/config/chips/F76x_F77x.chip index c1a5a9cf2..bb87dce7a 100644 --- a/config/chips/F76x_F77x.chip +++ b/config/chips/F76x_F77x.chip @@ -2,7 +2,7 @@ # dev_type STM32F76x_F77x ref_manual_id 0410 -chip_id 0x451 // STLINK_CHIPID_STM32_F76xxx +chip_id 0x451 // STM32_CHIPID_STM32_F76xxx flash_type 4 // STM32_FLASH_TYPE_F7 flash_size_reg 0x1ff0f442 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/G03x_G04x.chip b/config/chips/G03x_G04x.chip index aee016e0d..4a7e11fcd 100644 --- a/config/chips/G03x_G04x.chip +++ b/config/chips/G03x_G04x.chip @@ -2,7 +2,7 @@ # dev_type STM32G03x_G04x ref_manual_id 0444 // also RM454 -chip_id 0x466 // STLINK_CHIPID_STM32_G0_CAT1 +chip_id 0x466 // STM32_CHIPID_STM32_G0_CAT1 flash_type 5 // STM32_FLASH_TYPE_G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/G05x_G06x.chip b/config/chips/G05x_G06x.chip index f92cad889..81f97b58d 100644 --- a/config/chips/G05x_G06x.chip +++ b/config/chips/G05x_G06x.chip @@ -2,7 +2,7 @@ # dev_type STM32G05x_G06x ref_manual_id 0444 -chip_id 0x456 // STLINK_CHIPID_STM32_G0_CAT4 +chip_id 0x456 // STM32_CHIPID_STM32_G0_CAT4 flash_type 5 // STM32_FLASH_TYPE_G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/G07x_G08x.chip b/config/chips/G07x_G08x.chip index 29f527e73..cac804a78 100644 --- a/config/chips/G07x_G08x.chip +++ b/config/chips/G07x_G08x.chip @@ -2,7 +2,7 @@ # dev_type STM32G07x_G08x ref_manual_id 0444 -chip_id 0x460 // STLINK_CHIPID_STM32_G0_CAT2 +chip_id 0x460 // STM32_CHIPID_STM32_G0_CAT2 flash_type 5 // STM32_FLASH_TYPE_G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/G0Bx_G0Cx.chip b/config/chips/G0Bx_G0Cx.chip index 67254fbbd..845cf8280 100644 --- a/config/chips/G0Bx_G0Cx.chip +++ b/config/chips/G0Bx_G0Cx.chip @@ -2,7 +2,7 @@ # dev_type STM32G0Bx_G0Cx ref_manual_id 0444 -chip_id 0x467 // STLINK_CHIPID_STM32_G0_CAT3 +chip_id 0x467 // STM32_CHIPID_STM32_G0_CAT3 flash_type 5 // STM32_FLASH_TYPE_G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/G43x_G44x.chip b/config/chips/G43x_G44x.chip index b33a1a0f8..6b19d4fb4 100644 --- a/config/chips/G43x_G44x.chip +++ b/config/chips/G43x_G44x.chip @@ -2,7 +2,7 @@ # dev_type STM32G43x_G44x ref_manual_id 0440 -chip_id 0x468 // STLINK_CHIPID_STM32_G4_CAT2 +chip_id 0x468 // STM32_CHIPID_STM32_G4_CAT2 flash_type 6 // STM32_FLASH_TYPE_G4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/G47x_G48x.chip b/config/chips/G47x_G48x.chip index abf6a6f2d..d3330da59 100644 --- a/config/chips/G47x_G48x.chip +++ b/config/chips/G47x_G48x.chip @@ -2,7 +2,7 @@ # dev_type STM32G47x_G48x ref_manual_id 0440 -chip_id 0x469 // STLINK_CHIPID_STM32_G4_CAT3 +chip_id 0x469 // STM32_CHIPID_STM32_G4_CAT3 flash_type 6 // STM32_FLASH_TYPE_G4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/G49x_G4Ax.chip b/config/chips/G49x_G4Ax.chip index 3d8110f19..a39237142 100644 --- a/config/chips/G49x_G4Ax.chip +++ b/config/chips/G49x_G4Ax.chip @@ -2,7 +2,7 @@ # dev_type STM32G49x_G4Ax ref_manual_id 0440 -chip_id 0x479 // STLINK_CHIPID_STM32_G4_CAT4 +chip_id 0x479 // STM32_CHIPID_STM32_G4_CAT4 flash_type 6 // STM32_FLASH_TYPE_G4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/H72x_H73x.chip b/config/chips/H72x_H73x.chip index 1417cdb27..998aa9812 100644 --- a/config/chips/H72x_H73x.chip +++ b/config/chips/H72x_H73x.chip @@ -2,7 +2,7 @@ # dev_type STM32H72x_H73x ref_manual_id 0468 -chip_id 0x483 // STLINK_CHIPID_STM32_H72x +chip_id 0x483 // STM32_CHIPID_STM32_H72x flash_type 7 // STM32_FLASH_TYPE_H7 flash_size_reg 0x1ff1e880 flash_pagesize 0x20000 // 128 KB diff --git a/config/chips/H74x_H75x.chip b/config/chips/H74x_H75x.chip index 53a3e921a..0bfea13a4 100644 --- a/config/chips/H74x_H75x.chip +++ b/config/chips/H74x_H75x.chip @@ -2,7 +2,7 @@ # dev_type STM32H74x_H75x ref_manual_id 0433 -chip_id 0x450 // STLINK_CHIPID_STM32_H74xxx +chip_id 0x450 // STM32_CHIPID_STM32_H74xxx flash_type 7 // STM32_FLASH_TYPE_H7 flash_size_reg 0x1ff1e880 flash_pagesize 0x20000 // 128 KB diff --git a/config/chips/H7Ax_H7Bx.chip b/config/chips/H7Ax_H7Bx.chip index 516c4260e..2e784193c 100644 --- a/config/chips/H7Ax_H7Bx.chip +++ b/config/chips/H7Ax_H7Bx.chip @@ -2,7 +2,7 @@ # dev_type STM32H7Ax_H7Bx ref_manual_id 0455 -chip_id 0x480 // STLINK_CHIPID_STM32_H7Ax +chip_id 0x480 // STM32_CHIPID_STM32_H7Ax flash_type 7 // STM32_FLASH_TYPE_H7 flash_size_reg 0x08fff80c flash_pagesize 0x2000 // 8 KB diff --git a/config/chips/L0xxx_Cat_1.chip b/config/chips/L0xxx_Cat_1.chip index 6dc227024..4b108b4f4 100644 --- a/config/chips/L0xxx_Cat_1.chip +++ b/config/chips/L0xxx_Cat_1.chip @@ -2,7 +2,7 @@ # dev_type STM32L0xxx_Cat_1 ref_manual_id 0451 // also RM0377 -chip_id 0x457 // STLINK_CHIPID_STM32_L011 +chip_id 0x457 // STM32_CHIPID_STM32_L011 flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B diff --git a/config/chips/L0xxx_Cat_2.chip b/config/chips/L0xxx_Cat_2.chip index 74a3d6157..5665e8df1 100644 --- a/config/chips/L0xxx_Cat_2.chip +++ b/config/chips/L0xxx_Cat_2.chip @@ -2,7 +2,7 @@ # dev_type STM32L0xxx_Cat_2 ref_manual_id 0451 // also RM0377 -chip_id 0x425 // STLINK_CHIPID_STM32_L0_CAT2 +chip_id 0x425 // STM32_CHIPID_STM32_L0_CAT2 flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B diff --git a/config/chips/L0xxx_Cat_3.chip b/config/chips/L0xxx_Cat_3.chip index 0cfcc53bb..e8cd7c685 100644 --- a/config/chips/L0xxx_Cat_3.chip +++ b/config/chips/L0xxx_Cat_3.chip @@ -2,7 +2,7 @@ # dev_type STM32L0xxx_Cat_3 ref_manual_id 0451 // also RM0367 & RM0377 -chip_id 0x417 // STLINK_CHIPID_STM32_L0 +chip_id 0x417 // STM32_CHIPID_STM32_L0 flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B diff --git a/config/chips/L0xxx_Cat_5.chip b/config/chips/L0xxx_Cat_5.chip index cbb1e6632..284057091 100644 --- a/config/chips/L0xxx_Cat_5.chip +++ b/config/chips/L0xxx_Cat_5.chip @@ -2,7 +2,7 @@ # dev_type STM32L0xxx_Cat_5 ref_manual_id 0451 // also RM0367 & RM0377 -chip_id 0x447 // STLINK_CHIPID_STM32_L0_CAT5 +chip_id 0x447 // STM32_CHIPID_STM32_L0_CAT5 flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B diff --git a/config/chips/L1xx_Cat_1.chip b/config/chips/L1xx_Cat_1.chip index cecc32996..f6a11288f 100644 --- a/config/chips/L1xx_Cat_1.chip +++ b/config/chips/L1xx_Cat_1.chip @@ -2,7 +2,7 @@ # dev_type STM32L1xx_Cat_1 ref_manual_id 0038 -chip_id 0x416 // STLINK_CHIPID_STM32_L1_MD +chip_id 0x416 // STM32_CHIPID_STM32_L1_MD flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8004c flash_pagesize 0x100 // 128 B diff --git a/config/chips/L1xx_Cat_2.chip b/config/chips/L1xx_Cat_2.chip index 1981d58a5..c8c796111 100644 --- a/config/chips/L1xx_Cat_2.chip +++ b/config/chips/L1xx_Cat_2.chip @@ -2,7 +2,7 @@ # dev_type STM32L1xx_Cat_2 ref_manual_id 0038 -chip_id 0x429 // STLINK_CHIPID_STM32_L1_CAT2 +chip_id 0x429 // STM32_CHIPID_STM32_L1_CAT2 flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8004c flash_pagesize 0x100 // 128 B diff --git a/config/chips/L1xx_Cat_3.chip b/config/chips/L1xx_Cat_3.chip index 1d551c8a4..f2615f952 100644 --- a/config/chips/L1xx_Cat_3.chip +++ b/config/chips/L1xx_Cat_3.chip @@ -2,7 +2,7 @@ # dev_type STM32L1xx_Cat_3 ref_manual_id 0038 -chip_id 0x427 // STLINK_CHIPID_STM32_L1_MD_PLUS +chip_id 0x427 // STM32_CHIPID_STM32_L1_MD_PLUS flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff800cc flash_pagesize 0x100 // 128 B diff --git a/config/chips/L1xx_Cat_4.chip b/config/chips/L1xx_Cat_4.chip index 1e9cfe91c..6a1df1267 100644 --- a/config/chips/L1xx_Cat_4.chip +++ b/config/chips/L1xx_Cat_4.chip @@ -2,7 +2,7 @@ # dev_type STM32L1xx_Cat_4 ref_manual_id 0038 -chip_id 0x436 // STLINK_CHIPID_STM32_L1_MD_PLUS_HD +chip_id 0x436 // STM32_CHIPID_STM32_L1_MD_PLUS_HD flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff800cc flash_pagesize 0x100 // 128 B diff --git a/config/chips/L1xx_Cat_5.chip b/config/chips/L1xx_Cat_5.chip index a51356d7a..4fccd99da 100644 --- a/config/chips/L1xx_Cat_5.chip +++ b/config/chips/L1xx_Cat_5.chip @@ -2,7 +2,7 @@ # dev_type STM32L1xx_Cat_5 ref_manual_id 0038 -chip_id 0x437 // STLINK_CHIPID_STM32_L152_RE +chip_id 0x437 // STM32_CHIPID_STM32_L152_RE flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff800cc flash_pagesize 0x100 // 128 B diff --git a/config/chips/L41x_L42x.chip b/config/chips/L41x_L42x.chip index 2de859b0c..40085d828 100644 --- a/config/chips/L41x_L42x.chip +++ b/config/chips/L41x_L42x.chip @@ -2,7 +2,7 @@ # dev_type STM32L41x_L42x ref_manual_id 0394 -chip_id 0x464 // STLINK_CHIPID_STM32_L41x_L42x +chip_id 0x464 // STM32_CHIPID_STM32_L41x_L42x flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/L43x_L44x.chip b/config/chips/L43x_L44x.chip index 2dad90844..22045c372 100644 --- a/config/chips/L43x_L44x.chip +++ b/config/chips/L43x_L44x.chip @@ -2,7 +2,7 @@ # dev_type STM32L41x_L42x ref_manual_id 0392 -chip_id 0x435 // STLINK_CHIPID_STM32_L43x_L44x +chip_id 0x435 // STM32_CHIPID_STM32_L43x_L44x flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/L45x_L46x.chip b/config/chips/L45x_L46x.chip index f856e1315..99e9beca1 100644 --- a/config/chips/L45x_L46x.chip +++ b/config/chips/L45x_L46x.chip @@ -2,7 +2,7 @@ # dev_type STM32L45x_L46x ref_manual_id 0394 -chip_id 0x462 // STLINK_CHIPID_STM32_L45x_L46x +chip_id 0x462 // STM32_CHIPID_STM32_L45x_L46x flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/L47x_L48x.chip b/config/chips/L47x_L48x.chip index 51257a37c..44e5282ce 100644 --- a/config/chips/L47x_L48x.chip +++ b/config/chips/L47x_L48x.chip @@ -2,7 +2,7 @@ # dev_type STM32L47x_L48x ref_manual_id 0351 -chip_id 0x415 // STLINK_CHIPID_STM32_L4 +chip_id 0x415 // STM32_CHIPID_STM32_L4 flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/L496x_L4A6x.chip b/config/chips/L496x_L4A6x.chip index 32d75b571..b983eb9eb 100644 --- a/config/chips/L496x_L4A6x.chip +++ b/config/chips/L496x_L4A6x.chip @@ -2,7 +2,7 @@ # dev_type STM32L496x_L4A6x ref_manual_id 0351 -chip_id 0x461 // STLINK_CHIPID_STM32_L496x_L4A6x +chip_id 0x461 // STM32_CHIPID_STM32_L496x_L4A6x flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/L4Px.chip b/config/chips/L4Px.chip index ff3f05b81..41805c768 100644 --- a/config/chips/L4Px.chip +++ b/config/chips/L4Px.chip @@ -2,7 +2,7 @@ # dev_type STM32L4Px ref_manual_id 0432 -chip_id 0x471 // STLINK_CHIPID_STM32_L4PX +chip_id 0x471 // STM32_CHIPID_STM32_L4PX flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x1000 // 4 KB diff --git a/config/chips/L4Rx.chip b/config/chips/L4Rx.chip index 535e282c9..d0495f083 100644 --- a/config/chips/L4Rx.chip +++ b/config/chips/L4Rx.chip @@ -2,7 +2,7 @@ # dev_type STM32L4Rx ref_manual_id 0432 -chip_id 0x470 // STLINK_CHIPID_STM32_L4RX +chip_id 0x470 // STM32_CHIPID_STM32_L4RX flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x1000 // 4 KB diff --git a/config/chips/WBx0_WBx5.chip b/config/chips/WBx0_WBx5.chip index 5fa76ec75..e34c70815 100644 --- a/config/chips/WBx0_WBx5.chip +++ b/config/chips/WBx0_WBx5.chip @@ -2,7 +2,7 @@ # dev_type STM32WBx0_WBx5 ref_manual_id 0434 // also RM0471 -chip_id 0x495 // STLINK_CHIPID_STM32_WB55 +chip_id 0x495 // STM32_CHIPID_STM32_WB55 flash_type 11 // STM32_FLASH_TYPE_WB_WL flash_size_reg 0x1fff75e0 flash_pagesize 0x1000 // 4 KB diff --git a/config/chips/WLx5.chip b/config/chips/WLx5.chip index 62ff4f72f..b27e03dfe 100644 --- a/config/chips/WLx5.chip +++ b/config/chips/WLx5.chip @@ -2,7 +2,7 @@ # dev_type STM32WLEx ref_manual_id 0033 -chip_id 0x497 // STLINK_CHIPID_STM32_WLE +chip_id 0x497 // STM32_CHIPID_STM32_WLE flash_type 11 // STM32_FLASH_TYPE_WB_WL flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/unknown_device.chip b/config/chips/unknown_device.chip index 512211092..bc50e7a00 100644 --- a/config/chips/unknown_device.chip +++ b/config/chips/unknown_device.chip @@ -2,7 +2,7 @@ # dev_type unknown ref_manual_id 0000 -chip_id 0x0 // STLINK_CHIPID_UNKNOWN +chip_id 0x0 // STM32_CHIPID_UNKNOWN flash_type 0 // STM32_FLASH_TYPE_UNKNOWN flash_size_reg 0x0 flash_pagesize 0x0 diff --git a/inc/stlink.h b/inc/stlink.h index b387881ae..f6bd5cb0d 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -106,22 +106,22 @@ enum target_state { #define C_BUF_LEN 32 -/* Old flash type definitions */ -// TODO: Transition to the new defines in stm32.h -enum stlink_flash_type { - /* 0 */ STLINK_FLASH_TYPE_UNKNOWN = 0, - /* 1 */ STLINK_FLASH_TYPE_F0, // used by f0, f1 (except f1xl),f3. */ - /* 2 */ STLINK_FLASH_TYPE_F1_XL, // f0 flash with dual bank */ - /* 3 */ STLINK_FLASH_TYPE_F4, // used by f2, f4 */ - /* 4 */ STLINK_FLASH_TYPE_F7, - /* 5 */ STLINK_FLASH_TYPE_L0, // l0, l1 */ - /* 6 */ STLINK_FLASH_TYPE_L4, // l4, l4+ */ - /* 7 */ STLINK_FLASH_TYPE_G0, - /* 8 */ STLINK_FLASH_TYPE_G4, - /* 9 */ STLINK_FLASH_TYPE_WB, - /* 10 */ STLINK_FLASH_TYPE_H7, - /* 11 */ STLINK_FLASH_TYPE_MAX, -}; +// /* Old flash type definitions */ +// // TODO: Transition to the new defines in stm32.h +// enum stlink_flash_type { +// /* 0 */ STLINK_FLASH_TYPE_UNKNOWN = 0, +// /* 1 */ STLINK_FLASH_TYPE_F0, // used by f0, f1 (except f1xl),f3. */ +// /* 2 */ STLINK_FLASH_TYPE_F1_XL, // f0 flash with dual bank */ +// /* 3 */ STLINK_FLASH_TYPE_F4, // used by f2, f4 */ +// /* 4 */ STLINK_FLASH_TYPE_F7, +// /* 5 */ STLINK_FLASH_TYPE_L0, // l0, l1 */ +// /* 6 */ STLINK_FLASH_TYPE_L4, // l4, l4+ */ +// /* 7 */ STLINK_FLASH_TYPE_G0, +// /* 8 */ STLINK_FLASH_TYPE_G4, +// /* 9 */ STLINK_FLASH_TYPE_WB, +// /* 10 */ STLINK_FLASH_TYPE_H7, +// /* 11 */ STLINK_FLASH_TYPE_MAX, +// }; struct stlink_reg { uint32_t r[16]; diff --git a/inc/stm32.h b/inc/stm32.h index 280a61107..8dff2a7d7 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -1,7 +1,7 @@ /* * File: stm32.h * - * STM32-specific defines + * STM32-specific defines & identification parametres */ #ifndef STM32_H @@ -32,6 +32,74 @@ enum stm32_flash_type { STM32_FLASH_TYPE_UNDEFINED = 12, // max. value exceeded }; +/* STM32 chip-ids */ +// See DBGMCU_IDCODE register (0xE0042000) in appropriate programming manual +// stm32 chipids, only lower 12 bits... + +enum stm32_chipids { + STM32_CHIPID_UNKNOWN = 0x000, + + STM32_CHIPID_STM32_F1_MD = 0x410, /* medium density */ + STM32_CHIPID_STM32_F2 = 0x411, + STM32_CHIPID_STM32_F1_LD = 0x412, /* low density */ + STM32_CHIPID_STM32_F4 = 0x413, + STM32_CHIPID_STM32_F1_HD = 0x414, /* high density */ + STM32_CHIPID_STM32_L4 = 0x415, + STM32_CHIPID_STM32_L1_MD = 0x416, /* medium density */ + STM32_CHIPID_STM32_L0 = 0x417, + STM32_CHIPID_STM32_F1_CONN = 0x418, /* connectivity line */ + STM32_CHIPID_STM32_F4_HD = 0x419, /* high density */ + STM32_CHIPID_STM32_F1_VL_MD_LD = 0x420, /* value line medium & low density */ + STM32_CHIPID_STM32_F446 = 0x421, + STM32_CHIPID_STM32_F3 = 0x422, + STM32_CHIPID_STM32_F4_LP = 0x423, + STM32_CHIPID_STM32_L0_CAT2 = 0x425, + STM32_CHIPID_STM32_L1_MD_PLUS = 0x427, /* medium density plus */ + STM32_CHIPID_STM32_F1_VL_HD = 0x428, /* value line high density */ + STM32_CHIPID_STM32_L1_CAT2 = 0x429, + STM32_CHIPID_STM32_F1_XLD = 0x430, /* extra low density plus */ + STM32_CHIPID_STM32_F411xx = 0x431, + STM32_CHIPID_STM32_F37x = 0x432, + STM32_CHIPID_STM32_F4_DE = 0x433, + STM32_CHIPID_STM32_F4_DSI = 0x434, + STM32_CHIPID_STM32_L43x_L44x = 0x435, + STM32_CHIPID_STM32_L1_MD_PLUS_HD = 0x436, /* medium density plus & high density */ + STM32_CHIPID_STM32_L152_RE = 0x437, + STM32_CHIPID_STM32_F334 = 0x438, + STM32_CHIPID_STM32_F3xx_SMALL = 0x439, + STM32_CHIPID_STM32_F0 = 0x440, + STM32_CHIPID_STM32_F412 = 0x441, + STM32_CHIPID_STM32_F09x = 0x442, + STM32_CHIPID_STM32_F0xx_SMALL = 0x444, + STM32_CHIPID_STM32_F04 = 0x445, + STM32_CHIPID_STM32_F303_HD = 0x446, /* high density */ + STM32_CHIPID_STM32_L0_CAT5 = 0x447, + STM32_CHIPID_STM32_F0_CAN = 0x448, + STM32_CHIPID_STM32_F7 = 0x449, /* Nucleo F746ZG board */ + STM32_CHIPID_STM32_H74xxx = 0x450, /* RM0433, p.3189 */ + STM32_CHIPID_STM32_F76xxx = 0x451, + STM32_CHIPID_STM32_F72xxx = 0x452, /* Nucleo F722ZE board */ + STM32_CHIPID_STM32_G0_CAT4 = 0x456, /* G051/G061 */ + STM32_CHIPID_STM32_L011 = 0x457, + STM32_CHIPID_STM32_F410 = 0x458, + STM32_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/G081 */ + STM32_CHIPID_STM32_L496x_L4A6x = 0x461, + STM32_CHIPID_STM32_L45x_L46x = 0x462, + STM32_CHIPID_STM32_F413 = 0x463, + STM32_CHIPID_STM32_L41x_L42x = 0x464, + STM32_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/G041 */ + STM32_CHIPID_STM32_G0_CAT3 = 0x467, /* G0B1/G0C1 */ + STM32_CHIPID_STM32_G4_CAT2 = 0x468, /* RM0440, section 46.6.1 "MCU device ID code" */ + STM32_CHIPID_STM32_G4_CAT3 = 0x469, + STM32_CHIPID_STM32_L4Rx = 0x470, /* RM0432, p.2247, found on the STM32L4R9I-DISCO board */ + STM32_CHIPID_STM32_L4PX = 0x471, /* RM0432, p.2247 */ + STM32_CHIPID_STM32_G4_CAT4 = 0x479, + STM32_CHIPID_STM32_H7Ax = 0x480, /* RM0455, p.2863 */ + STM32_CHIPID_STM32_H72x = 0x483, /* RM0468, p.3199 */ + STM32_CHIPID_STM32_WB55 = 0x495, + STM32_CHIPID_STM32_WLE = 0x497, +}; + /* Constant STM32 memory address */ #define STM32_SRAM_BASE ((uint32_t)0x20000000) #define STM32_FLASH_BASE ((uint32_t)0x08000000) @@ -60,76 +128,4 @@ enum stm32_flash_type { #define STM32_F3_OPTION_BYTES_BASE ((uint32_t)0x1ffff800) #define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1ffff800) - -/* - * Chip IDs - * See DBGMCU_IDCODE register (0xE0042000) in appropriate programming manual - */ - -// stm32 chipids, only lower 12 bits... - -enum stlink_stm32_chipids { - STLINK_CHIPID_UNKNOWN = 0x000, - - STLINK_CHIPID_STM32_F1_MD = 0x410, /* medium density */ - STLINK_CHIPID_STM32_F2 = 0x411, - STLINK_CHIPID_STM32_F1_LD = 0x412, /* low density */ - STLINK_CHIPID_STM32_F4 = 0x413, - STLINK_CHIPID_STM32_F1_HD = 0x414, /* high density */ - STLINK_CHIPID_STM32_L4 = 0x415, - STLINK_CHIPID_STM32_L1_MD = 0x416, /* medium density */ - STLINK_CHIPID_STM32_L0 = 0x417, - STLINK_CHIPID_STM32_F1_CONN = 0x418, /* connectivity line */ - STLINK_CHIPID_STM32_F4_HD = 0x419, /* high density */ - STLINK_CHIPID_STM32_F1_VL_MD_LD = 0x420, /* value line medium & low density */ - STLINK_CHIPID_STM32_F446 = 0x421, - STLINK_CHIPID_STM32_F3 = 0x422, - STLINK_CHIPID_STM32_F4_LP = 0x423, - STLINK_CHIPID_STM32_L0_CAT2 = 0x425, - STLINK_CHIPID_STM32_L1_MD_PLUS = 0x427, /* medium density plus */ - STLINK_CHIPID_STM32_F1_VL_HD = 0x428, /* value line high density */ - STLINK_CHIPID_STM32_L1_CAT2 = 0x429, - STLINK_CHIPID_STM32_F1_XLD = 0x430, /* extra low density plus */ - STLINK_CHIPID_STM32_F411xx = 0x431, - STLINK_CHIPID_STM32_F37x = 0x432, - STLINK_CHIPID_STM32_F4_DE = 0x433, - STLINK_CHIPID_STM32_F4_DSI = 0x434, - STLINK_CHIPID_STM32_L43x_L44x = 0x435, - STLINK_CHIPID_STM32_L1_MD_PLUS_HD = 0x436, /* medium density plus & high density */ - STLINK_CHIPID_STM32_L152_RE = 0x437, - STLINK_CHIPID_STM32_F334 = 0x438, - STLINK_CHIPID_STM32_F3xx_SMALL = 0x439, - STLINK_CHIPID_STM32_F0 = 0x440, - STLINK_CHIPID_STM32_F412 = 0x441, - STLINK_CHIPID_STM32_F09x = 0x442, - STLINK_CHIPID_STM32_F0xx_SMALL = 0x444, - STLINK_CHIPID_STM32_F04 = 0x445, - STLINK_CHIPID_STM32_F303_HD = 0x446, /* high density */ - STLINK_CHIPID_STM32_L0_CAT5 = 0x447, - STLINK_CHIPID_STM32_F0_CAN = 0x448, - STLINK_CHIPID_STM32_F7 = 0x449, /* Nucleo F746ZG board */ - STLINK_CHIPID_STM32_H74xxx = 0x450, /* RM0433, p.3189 */ - STLINK_CHIPID_STM32_F76xxx = 0x451, - STLINK_CHIPID_STM32_F72xxx = 0x452, /* Nucleo F722ZE board */ - STLINK_CHIPID_STM32_G0_CAT4 = 0x456, /* G051/G061 */ - STLINK_CHIPID_STM32_L011 = 0x457, - STLINK_CHIPID_STM32_F410 = 0x458, - STLINK_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/G081 */ - STLINK_CHIPID_STM32_L496x_L4A6x = 0x461, - STLINK_CHIPID_STM32_L45x_L46x = 0x462, - STLINK_CHIPID_STM32_F413 = 0x463, - STLINK_CHIPID_STM32_L41x_L42x = 0x464, - STLINK_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/G041 */ - STLINK_CHIPID_STM32_G0_CAT3 = 0x467, /* G0B1/G0C1 */ - STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* RM0440, section 46.6.1 "MCU device ID code" */ - STLINK_CHIPID_STM32_G4_CAT3 = 0x469, - STLINK_CHIPID_STM32_L4Rx = 0x470, /* RM0432, p.2247, found on the STM32L4R9I-DISCO board */ - STLINK_CHIPID_STM32_L4PX = 0x471, /* RM0432, p.2247 */ - STLINK_CHIPID_STM32_G4_CAT4 = 0x479, - STLINK_CHIPID_STM32_H7Ax = 0x480, /* RM0455, p.2863 */ - STLINK_CHIPID_STM32_H72x = 0x483, /* RM0468, p.3199 */ - STLINK_CHIPID_STM32_WB55 = 0x495, - STLINK_CHIPID_STM32_WLE = 0x497, -}; - #endif // STM32_H diff --git a/src/common.c b/src/common.c index e73955f31..5a6d0d86b 100644 --- a/src/common.c +++ b/src/common.c @@ -334,7 +334,7 @@ #define FLASH_H7_CR_SER 2 #define FLASH_H7_CR_BER 3 #define FLASH_H7_CR_PSIZE 4 -#define FLASH_H7_CR_START(chipid) (chipid == STLINK_CHIPID_STM32_H7Ax ? 5 : 7) +#define FLASH_H7_CR_START(chipid) (chipid == STM32_CHIPID_STM32_H7Ax ? 5 : 7) #define FLASH_H7_CR_SNB 8 #define FLASH_H7_CR_SNB_MASK 0x700 @@ -441,16 +441,16 @@ uint16_t read_uint16(const unsigned char *c, const int pt) { static uint32_t get_stm32l0_flash_base(stlink_t *sl) { switch (sl->chip_id) { - case STLINK_CHIPID_STM32_L0: - case STLINK_CHIPID_STM32_L0_CAT5: - case STLINK_CHIPID_STM32_L0_CAT2: - case STLINK_CHIPID_STM32_L011: + case STM32_CHIPID_STM32_L0: + case STM32_CHIPID_STM32_L0_CAT5: + case STM32_CHIPID_STM32_L0_CAT2: + case STM32_CHIPID_STM32_L011: return (STM32L0_FLASH_REGS_ADDR); - case STLINK_CHIPID_STM32_L1_CAT2: - case STLINK_CHIPID_STM32_L1_MD: - case STLINK_CHIPID_STM32_L1_MD_PLUS: - case STLINK_CHIPID_STM32_L1_MD_PLUS_HD: + case STM32_CHIPID_STM32_L1_CAT2: + case STM32_CHIPID_STM32_L1_MD: + case STM32_CHIPID_STM32_L1_MD_PLUS: + case STM32_CHIPID_STM32_L1_MD_PLUS_HD: return (STM32L_FLASH_REGS_ADDR); default: @@ -1622,14 +1622,14 @@ int stlink_load_device_params(stlink_t *sl) { flash_size = flash_size & 0xffff; - if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MD || - sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MD_LD || - sl->chip_id == STLINK_CHIPID_STM32_L1_MD_PLUS) && + if ((sl->chip_id == STM32_CHIPID_STM32_L1_MD || + sl->chip_id == STM32_CHIPID_STM32_F1_VL_MD_LD || + sl->chip_id == STM32_CHIPID_STM32_L1_MD_PLUS) && (flash_size == 0)) { sl->flash_size = 128 * 1024; - } else if (sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2) { + } else if (sl->chip_id == STM32_CHIPID_STM32_L1_CAT2) { sl->flash_size = (flash_size & 0xff) * 1024; - } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_MD_PLUS_HD) { + } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_STM32_L1_MD_PLUS_HD) { // 0 is 384k and 1 is 256k if (flash_size == 0) { sl->flash_size = 384 * 1024; @@ -1651,12 +1651,12 @@ int stlink_load_device_params(stlink_t *sl) { // medium and low devices have the same chipid. ram size depends on flash // size. STM32F100xx datasheet Doc ID 16455 Table 2 - if (sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MD_LD && + if (sl->chip_id == STM32_CHIPID_STM32_F1_VL_MD_LD && sl->flash_size < 64 * 1024) { sl->sram_size = 0x1000; } - if (sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3) { + if (sl->chip_id == STM32_CHIPID_STM32_G4_CAT3) { uint32_t flash_optr; stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); @@ -2706,9 +2706,9 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); flashaddr -= STM32_FLASH_BASE; - if (sl->chip_id == STLINK_CHIPID_STM32_L4 || - sl->chip_id == STLINK_CHIPID_STM32_L496x_L4A6x || - sl->chip_id == STLINK_CHIPID_STM32_L4Rx) { + if (sl->chip_id == STM32_CHIPID_STM32_L4 || + sl->chip_id == STM32_CHIPID_STM32_L496x_L4A6x || + sl->chip_id == STM32_CHIPID_STM32_L4Rx) { // this chip use dual banked flash if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { uint32_t banksize = (uint32_t)sl->flash_size / 2; @@ -2726,16 +2726,16 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { - if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || - (sl->chip_id == STLINK_CHIPID_STM32_F4) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || - (sl->chip_id == STLINK_CHIPID_STM32_F411xx) || - (sl->chip_id == STLINK_CHIPID_STM32_F446) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || - (sl->chip_id == STLINK_CHIPID_STM32_F72xxx) || - (sl->chip_id == STLINK_CHIPID_STM32_F412)) { + if ((sl->chip_id == STM32_CHIPID_STM32_F2) || + (sl->chip_id == STM32_CHIPID_STM32_F4) || + (sl->chip_id == STM32_CHIPID_STM32_F4_DE) || + (sl->chip_id == STM32_CHIPID_STM32_F4_LP) || + (sl->chip_id == STM32_CHIPID_STM32_F4_HD) || + (sl->chip_id == STM32_CHIPID_STM32_F411xx) || + (sl->chip_id == STM32_CHIPID_STM32_F446) || + (sl->chip_id == STM32_CHIPID_STM32_F4_DSI) || + (sl->chip_id == STM32_CHIPID_STM32_F72xxx) || + (sl->chip_id == STM32_CHIPID_STM32_F412)) { uint32_t sector = calculate_F4_sectornum(flashaddr); if (sector >= 12) { @@ -2749,8 +2749,8 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { } else { sl->flash_pgsz = 0x20000; } - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F76xxx) { + } else if (sl->chip_id == STM32_CHIPID_STM32_F7 || + sl->chip_id == STM32_CHIPID_STM32_F76xxx) { uint32_t sector = calculate_F7_sectornum(flashaddr); if (sector < 4) { @@ -2785,11 +2785,11 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { unlock_flash_if(sl); // select the page to erase - if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || - (sl->chip_id == STLINK_CHIPID_STM32_L43x_L44x) || - (sl->chip_id == STLINK_CHIPID_STM32_L45x_L46x) || - (sl->chip_id == STLINK_CHIPID_STM32_L496x_L4A6x) || - (sl->chip_id == STLINK_CHIPID_STM32_L4Rx)) { + if ((sl->chip_id == STM32_CHIPID_STM32_L4) || + (sl->chip_id == STM32_CHIPID_STM32_L43x_L44x) || + (sl->chip_id == STM32_CHIPID_STM32_L45x_L46x) || + (sl->chip_id == STM32_CHIPID_STM32_L496x_L4A6x) || + (sl->chip_id == STM32_CHIPID_STM32_L4Rx)) { // calculate the actual bank+page from the address uint32_t page = calculate_L4_page(sl, flashaddr); @@ -2797,8 +2797,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { stlink_calculate_pagesize(sl, flashaddr)); write_flash_cr_bker_pnb(sl, page); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F76xxx) { + } else if (sl->chip_id == STM32_CHIPID_STM32_F7 || + sl->chip_id == STM32_CHIPID_STM32_F76xxx) { // calculate the actual page from the address uint32_t sector = calculate_F7_sectornum(flashaddr); @@ -2982,7 +2982,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { unlock_flash_if(sl); if (sl->flash_type == STM32_FLASH_TYPE_H7 && - sl->chip_id != STLINK_CHIPID_STM32_H7Ax) { + sl->chip_id != STM32_CHIPID_STM32_H7Ax) { // set parallelism write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { @@ -3260,7 +3260,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { set_flash_cr_pg(sl, BANK_2); } - if (sl->chip_id != STLINK_CHIPID_STM32_H7Ax) { + if (sl->chip_id != STM32_CHIPID_STM32_H7Ax) { // set parallelism write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { @@ -4357,17 +4357,17 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { } switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F2: + case STM32_CHIPID_STM32_F2: return stlink_read_option_bytes_f2(sl, option_byte); - case STLINK_CHIPID_STM32_F4: - case STLINK_CHIPID_STM32_F446: + case STM32_CHIPID_STM32_F4: + case STM32_CHIPID_STM32_F446: return stlink_read_option_bytes_f4(sl, option_byte); - case STLINK_CHIPID_STM32_F76xxx: + case STM32_CHIPID_STM32_F76xxx: return stlink_read_option_bytes_f7(sl, option_byte); - case STLINK_CHIPID_STM32_G0_CAT1: - case STLINK_CHIPID_STM32_G0_CAT2: - case STLINK_CHIPID_STM32_G4_CAT2: - case STLINK_CHIPID_STM32_G4_CAT3: + case STM32_CHIPID_STM32_G0_CAT1: + case STM32_CHIPID_STM32_G0_CAT2: + case STM32_CHIPID_STM32_G4_CAT2: + case STM32_CHIPID_STM32_G4_CAT3: return stlink_read_option_bytes_Gx(sl, option_byte); default: return stlink_read_option_bytes_generic(sl, option_byte); diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 46304d7d9..28a585071 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -540,7 +540,7 @@ int main(int argc, char **argv) { stlink->verbose = settings.logging_level; - if (stlink->chip_id == STLINK_CHIPID_UNKNOWN) { + if (stlink->chip_id == STM32_CHIPID_UNKNOWN) { ELOG("Your stlink is not connected to a device\n"); if (!settings.force) return APP_RESULT_STLINK_MISSING_DEVICE; diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 81c0aa83a..4babef0cc 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -226,7 +226,7 @@ int main(int argc, char** argv) { sl = stlink_open_usb(state.logging_level, state.connect_mode, state.serialnumber, state.freq); if (sl == NULL) { return(1); } - if (sl->chip_id == STLINK_CHIPID_UNKNOWN) { + if (sl->chip_id == STM32_CHIPID_UNKNOWN) { ELOG("Unsupported Target (Chip ID is %#010x, Core ID is %#010x).\n", sl->chip_id, sl->core_id); return(1); } @@ -553,39 +553,39 @@ char* make_memory_map(stlink_t *sl) { char* map = malloc(sz); map[0] = '\0'; - if (sl->chip_id == STLINK_CHIPID_STM32_F4 || - sl->chip_id == STLINK_CHIPID_STM32_F446 || - sl->chip_id == STLINK_CHIPID_STM32_F411xx) { + if (sl->chip_id == STM32_CHIPID_STM32_F4 || + sl->chip_id == STM32_CHIPID_STM32_F446 || + sl->chip_id == STM32_CHIPID_STM32_F411xx) { strcpy(map, memory_map_template_F4); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) { + } else if (sl->chip_id == STM32_CHIPID_STM32_F4_DE) { strcpy(map, memory_map_template_F4_DE); } else if (sl->core_id == STM32F7_CORE_ID) { snprintf(map, sz, memory_map_template_F7, (unsigned int)sl->sram_size); - } else if (sl->chip_id == STLINK_CHIPID_STM32_H74xxx) { + } else if (sl->chip_id == STM32_CHIPID_STM32_H74xxx) { snprintf(map, sz, memory_map_template_H7, (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) { + } else if (sl->chip_id == STM32_CHIPID_STM32_F4_HD) { strcpy(map, memory_map_template_F4_HD); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F2) { + } else if (sl->chip_id == STM32_CHIPID_STM32_F2) { snprintf(map, sz, memory_map_template_F2, (unsigned int)sl->flash_size, (unsigned int)sl->sram_size, (unsigned int)sl->flash_size - 0x20000, (unsigned int)sl->sys_base, (unsigned int)sl->sys_size); - } else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || - (sl->chip_id == STLINK_CHIPID_STM32_L43x_L44x) || - (sl->chip_id == STLINK_CHIPID_STM32_L45x_L46x)) { + } else if ((sl->chip_id == STM32_CHIPID_STM32_L4) || + (sl->chip_id == STM32_CHIPID_STM32_L43x_L44x) || + (sl->chip_id == STM32_CHIPID_STM32_L45x_L46x)) { snprintf(map, sz, memory_map_template_L4, (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); - } else if (sl->chip_id == STLINK_CHIPID_STM32_L496x_L4A6x) { + } else if (sl->chip_id == STM32_CHIPID_STM32_L496x_L4A6x) { snprintf(map, sz, memory_map_template_L496, (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); - } else if (sl->chip_id == STLINK_CHIPID_STM32_H72x) { + } else if (sl->chip_id == STM32_CHIPID_STM32_H72x) { snprintf(map, sz, memory_map_template_H72x3x, (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz); @@ -1847,7 +1847,7 @@ int serve(stlink_t *sl, st_state_t *st) { stlink_close(sl); sl = stlink_open_usb(st->logging_level, st->connect_mode, st->serialnumber, st->freq); - if (sl == NULL || sl->chip_id == STLINK_CHIPID_UNKNOWN) { cleanup(0); } + if (sl == NULL || sl->chip_id == STM32_CHIPID_UNKNOWN) { cleanup(0); } connected_stlink = sl; diff --git a/src/stlink-lib/chipid_db_old.h b/src/stlink-lib/chipid_db_old.h deleted file mode 100644 index 6578e35be..000000000 --- a/src/stlink-lib/chipid_db_old.h +++ /dev/null @@ -1,877 +0,0 @@ -// This is the old chipid "database". -// It is kept here for now to be able to compare the -// result between the "old code" and the "new code". -// For now if you need to change something, please -// change it both here and in the corresponding -// config/chips/*.chip file. - -//static struct stlink_chipid_params devices[] = { - { - // STM32F03x - // RM0091 - .chip_id = STLINK_CHIPID_STM32_F0xx_SMALL, - .dev_type = "F03x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - }, - { - // STM32F04x - // RM0091 - .chip_id = STLINK_CHIPID_STM32_F04, - .dev_type = "F04x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - }, - { - // STM32F05x - // RM0091 - .chip_id = STLINK_CHIPID_STM32_F0, - .dev_type = "F05x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - }, - { - // STM32F07x - // RM0091 - .chip_id = STLINK_CHIPID_STM32_F0_CAN, - .dev_type = "F07x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 - .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 - .bootrom_size = 0x3000, // "System memory" byte size in hex from Table 2 - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - }, - { - // STM32F09x - // RM0091 - .chip_id = STLINK_CHIPID_STM32_F09x, - .dev_type = "F09x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) - .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) - .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 - .bootrom_size = 0x2000, // "System memory" byte size in hex from Table 2 - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - }, - { - // STM32F1xx low- and medium-density value line devices - // RM0041 - .chip_id = STLINK_CHIPID_STM32_F1_VL_MD_LD, - .dev_type = "F1xx Value Line", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2000, // 0x1000 for low density devices - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F1xx high-density value line devices - // RM0041 - .chip_id = STLINK_CHIPID_STM32_F1_VL_HD, - .dev_type = "F1xx High-density value line", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x8000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F1xx low-density devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_LD, - .dev_type = "F1 Low-density device", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2800, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F1xx medium-density devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_MD, - .dev_type = "F1xx Medium-density", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x5000, - .bootrom_base = 0x1ffff000, // 2.3.3 "Embedded Flash memory" - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F1xx high-density devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_HD, - .dev_type = "F1xx High-density", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F1xx XL-density devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_XLD, - .dev_type = "F1xx XL-density", - .flash_type = STLINK_FLASH_TYPE_F1_XL, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x18000, - .bootrom_base = 0x1fffe000, - .bootrom_size = 0x1800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F1xx connectivity devices - // RM0008 - .chip_id = STLINK_CHIPID_STM32_F1_CONN, - .dev_type = "F1xx CL", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1fffb000, - .bootrom_size = 0x4800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F205xx, STM32F207xx, STM32F215xx, STM32F217xx - // RM0033 (rev 5) - .chip_id = STLINK_CHIPID_STM32_F2, - .dev_type = "F2xx", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, - .flash_pagesize = 0x20000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .option_base = 0x1FFFC000, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F301x6/8, STM32F302x6x8, STM32F318x8 - // RM0366, RM0365 - .chip_id = STLINK_CHIPID_STM32_F3xx_SMALL, - .dev_type = "F301/F302/F318", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1fffd800, - .bootrom_size = 0x2000, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F302xBxC, STM32F303xB/C, STM32F358 - // RM0316, RM0365 - .chip_id = STLINK_CHIPID_STM32_F3, - .dev_type = "F302/F303/F358", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F302xD/E, STM32F303xD/E, STM32F398xE, - // RM0316 (rev 5), RM0365 - .chip_id = STLINK_CHIPID_STM32_F303_HD, - .dev_type = "F303 high density", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register - .flash_pagesize = 0x800, // 4.2.1 Flash memory organization - .sram_size = 0x10000, // 3.3 Embedded SRAM - .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory - .bootrom_size = 0x2000, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F303x6/8, STM32F328, STM32F334 - // RM0364, RM0316 - .chip_id = STLINK_CHIPID_STM32_F334, - .dev_type = "F303/F328/F334", // (RM0316 sec 33.6.1) - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0x3000, - .bootrom_base = 0x1fffd800, - .bootrom_size = 0x2000, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F373Cx/Rx/Vx, STM32F378Cx/Rx/Vx - // RM0313 - .chip_id = STLINK_CHIPID_STM32_F37x, - .dev_type = "F37x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800, - .option_base = STM32_F0_OPTION_BYTES_BASE, - .option_size = 16, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - .chip_id = STLINK_CHIPID_STM32_F4_LP, - .dev_type = "F401xB/C", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x10000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - .chip_id = STLINK_CHIPID_STM32_F4_DE, - .dev_type = "F401xD/E", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F410 - // RM0401 - .chip_id = STLINK_CHIPID_STM32_F410, - .dev_type = "F410", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, - .flash_pagesize = 0x4000, - .sram_size = 0x8000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - .chip_id = STLINK_CHIPID_STM32_F411xx, - .dev_type = "F411xC/E", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F412 - // RM0402 - .chip_id = STLINK_CHIPID_STM32_F412, - .dev_type = "F412", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) - .flash_pagesize = 0x4000, // Table 5. Flash module organization ? - .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 - .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F413/F423 - // RM0430 (rev 2) - .chip_id = STLINK_CHIPID_STM32_F413, - .dev_type = "F413/F423", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 - .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector - // sizes, but 0x4000 is smallest) - .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 - // only says 0x40000) - .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F42x/F43x - // RM0090 (rev 2) - .chip_id = STLINK_CHIPID_STM32_F4_HD, - .dev_type = "F42x/F43x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x40000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F446x family - // RM0390 - .chip_id = STLINK_CHIPID_STM32_F446, - .dev_type = "F446", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, - .flash_pagesize = 0x20000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .option_base = 0x1FFFC000, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F46x/F47x - // RM0090 (rev 2) - .chip_id = STLINK_CHIPID_STM32_F4_DSI, - .dev_type = "F46x/F47x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x40000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F4x5/F4x7 - // RM0090 (rev 2) - .chip_id = STLINK_CHIPID_STM32_F4, - .dev_type = "F4x5/F4x7", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x30000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800, - .option_base = STM32_F4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F72x/F73x - // RM0431 - .chip_id = STLINK_CHIPID_STM32_F72xxx, - .dev_type = "F72x/F73x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff07a22, // section 35.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 - .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 24 - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F74x/F75x - // RM0385, DS10916 - .chip_id = STLINK_CHIPID_STM32_F7, - .dev_type = "F74x/F75x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff0f442, // section 41.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 - .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 18 - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32F76x/F77x - // RM0410 - .chip_id = STLINK_CHIPID_STM32_F76xxx, - .dev_type = "F76x/F77x", - .flash_type = STLINK_FLASH_TYPE_F7, - .flash_size_reg = 0x1ff0f442, // section 45.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x80000, // "SRAM" byte size in hex from - .bootrom_base = 0x00200000, // "System memory" starting address from - .bootrom_size = 0xEDC0, - .option_base = STM32_F7_OPTION_BYTES_BASE, /* Used for reading back the option - bytes, writing uses FLASH_F7_OPTCR - and FLASH_F7_OPTCR1 */ - .option_size = 0x20, - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32G030/031/041 - // RM0454, RM0444 - .chip_id = STLINK_CHIPID_STM32_G0_CAT1, - .dev_type = "G03x/G04x", - .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x2000, // 8k (sec 2.3) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 3) - .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32G051/G061 - // RM0444 - .chip_id = STLINK_CHIPID_STM32_G0_CAT4, - .dev_type = "G05x/G06x", - .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x9000, // 36k (sec 2.3) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) - .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32G071/081 - // RM0444 - .chip_id = STLINK_CHIPID_STM32_G0_CAT2, - .dev_type = "G07x/G08x", - .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x9000, // 36k (sec 2.3) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) - .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32G0B1/G0C1 - // RM0444 - .chip_id = STLINK_CHIPID_STM32_G0_CAT3, - .dev_type = "G0Bx/G0Cx", - .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x9000, // 36k (sec 2.3) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) - .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_DUAL_BANK, - }, - { - // STM32G431/441 - // RM0440 - .chip_id = STLINK_CHIPID_STM32_G4_CAT2, - .dev_type = "G43x/G44x", - .flash_type = STLINK_FLASH_TYPE_G4, - .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = 0x800, // 2k (sec 3.3.1) - // SRAM1 is 16k at 0x20000000 - // SRAM2 is 6k at 0x20014000 - // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x8000, // 32k (sec 2.4) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (table 2) - .option_base = STM32_G4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32G471/473/474/483/484 - // RM0440 - .chip_id = STLINK_CHIPID_STM32_G4_CAT3, - .dev_type = "G47x/G48x", - .flash_type = STLINK_FLASH_TYPE_G4, - .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = 0x800, // 2k (sec 3.3.1) - // SRAM1 is 80k at 0x20000000 - // SRAM2 is 16k at 0x20014000 - // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x20000, // 128k (sec 2.4) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (table 2) - .option_base = STM32_G4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32G491/G4A1 - // RM0440 - .chip_id = STLINK_CHIPID_STM32_G4_CAT4, - .dev_type = "G49x/G4Ax", - .flash_type = STLINK_FLASH_TYPE_G4, - .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = 0x800, // 2k (sec 3.3.1) - // SRAM1 is 80k at 0x20000000 - // SRAM2 is 16k at 0x20014000 - // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x1C000, // 112k (sec 2.4) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (table 2) - .option_base = STM32_G4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32H7A3/7B3 - // RM0455 - .chip_id = STLINK_CHIPID_STM32_H7Ax, - .dev_type = "H7Ax/H7Bx", - .flash_type = STLINK_FLASH_TYPE_H7, - .flash_size_reg = 0x08FFF80C, // "Flash size register" (p.2949) - .flash_pagesize = 0x2000, // 8k sector (p.146) - .sram_size = 0x20000, // 128k "DTCM" (Figure 1) - .bootrom_base = 0x1FF00000, // "System memory" starting address (Table 12-14) - .bootrom_size = 0x20000, // "System memory" byte size in hex splitted to - // two banks (Table 12-14) - .option_base = STM32_H7_OPTION_BYTES_BASE, - .option_size = 44, - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32H72x/H73x - // RM0468 - .chip_id = STLINK_CHIPID_STM32_H72x, - .dev_type = "H72x/H73x", - .flash_type = STLINK_FLASH_TYPE_H7, - .flash_size_reg = 0x1FF1E880, // "Flash size register" (p.3286) - .flash_pagesize = 0x20000, // 128k sector (p.152) - .sram_size = 0x20000, // 128k "DTCM" (Figure 1) - .bootrom_base = 0x1FF00000, // "System memory" starting address (Table 6) - .bootrom_size = 0x20000, // "System memory" byte size in hex (Table 6) - .option_base = STM32_H7_OPTION_BYTES_BASE, - .option_size = 44, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32H742/743/753 (from RM0433) - .chip_id = STLINK_CHIPID_STM32_H74xxx, - .dev_type = "H74x/H75x", - .flash_type = STLINK_FLASH_TYPE_H7, - .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) - .flash_pagesize = 0x20000, // 128k sector (pg147) - .sram_size = 0x20000, // 128k "DTCM" from Table 7 - .bootrom_base = 0x1ff00000, // "System memory" starting address from Table 7 - .bootrom_size = 0x20000, // "System memory" byte size in hex from Table 7 - .option_base = STM32_H7_OPTION_BYTES_BASE, - .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L0xx Category 1 - // RM0451, RM0377 - .chip_id = STLINK_CHIPID_STM32_L011, - .dev_type = "L01x/L02x", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x2000, - }, - { - // STM32L0x Category 2 - // RM0367, RM0377 - .chip_id = STLINK_CHIPID_STM32_L0_CAT2, - .dev_type = "L0xx Cat.2", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000, - .option_base = STM32_L0_OPTION_BYTES_BASE, - .option_size = 20, - }, - { - // STM32L0xx Category 3 - // RM0367, RM0377, RM0451 - .chip_id = STLINK_CHIPID_STM32_L0, - .dev_type = "L0xx Cat.3", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x1000, - .option_base = STM32_L0_OPTION_BYTES_BASE, - .option_size = 20, - }, - { - // STM32L0x Category 5 - // RM0367, RM0377, RM0451 - .chip_id = STLINK_CHIPID_STM32_L0_CAT5, - .dev_type = "L0xx Cat.5", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x5000, - .bootrom_base = 0x1ff0000, - .bootrom_size = 0x2000, - .option_base = STM32_L0_OPTION_BYTES_BASE, - .option_size = 20, - .flags = CHIP_F_HAS_DUAL_BANK, - }, - { - // STM32L100/L15x/L16x Cat.1 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L1_MD, - .dev_type = "L1xx Cat.1", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8004c, - .flash_pagesize = 0x100, - .sram_size = 0x4000, // up to 16k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L100/L15x/L16x Cat.2 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L1_CAT2, - .dev_type = "L1xx Cat.2", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8004c, - .flash_pagesize = 0x100, - .sram_size = 0x8000, // up to 32k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L100/L15x/L16x Cat.3 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L1_MD_PLUS, - .dev_type = "L1xx Cat.3", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x8000, // up to 32k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L100/L15x/L16x Cat.4 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L1_MD_PLUS_HD, - .dev_type = "L1xx Cat.4", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0xC000, // up to 48k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .option_base = STM32_L1_OPTION_BYTES_BASE, - .option_size = 8, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L100/L15x/L16x Cat.5 - // RM0038 - .chip_id = STLINK_CHIPID_STM32_L152_RE, - .dev_type = "L1xx Cat.5", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x14000, // up to 80k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STLINK_CHIPID_STM32_L41x_L42x - // RM0394 (rev 4), DS12469 (rev 5) - .chip_id = STLINK_CHIPID_STM32_L41x_L42x, - .dev_type = "L41x/L42x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, - // sec 47.2, page 1586) - .flash_pagesize = 0x800, // 2k (DS12469, sec 3.4, page 17) - // SRAM1 is 32k at 0x20000000 - // SRAM2 is 8k at 0x10000000 and 0x20008000 - // (DS12469, sec 3.5, page 18) - .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) - .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) - .bootrom_size = 0x7000, // 28k, same source as base - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STLINK_CHIPID_STM32_L43x_L44x - // RM0392 - .chip_id = STLINK_CHIPID_STM32_L43x_L44x, - .dev_type = "L43x/L44x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 - // and tables 7-8 on pages 75-76) - // SRAM1 is "up to" 64k in the standard Cortex-M memory map; - // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) - .sram_size = 0xc000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STLINK_CHIPID_STM32_L45x_L46x - // RM0394 (updated version of RM0392?) - .chip_id = STLINK_CHIPID_STM32_L45x_L46x, - .dev_type = "L45x/46x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 - // and tables 7 on pages 73-74) - // SRAM1 is 128k at 0x20000000; - // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, - // page 68, also fig 2 on page 63) - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system - // memory, also fig 2 on page 63) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L47x/L48x - // RM0351 - .chip_id = STLINK_CHIPID_STM32_L4, - .dev_type = "L47x/L48x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 - // and tables 4-6 on pages 79-81) - // SRAM1 is "up to" 96k in the standard Cortex-M memory map; - // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) - .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STLINK_CHIPID_STM32_L496x_L4A6x - // RM0351 (rev 5) - .chip_id = STLINK_CHIPID_STM32_L496x_L4A6x, - .dev_type = "L496x/L4A6x", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) - .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) - // SRAM1 is 256k at 0x20000000 - // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) - .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) - .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) - .bootrom_size = 0x7000, // 28k (per bank), same source as base - .option_base = STM32_L4_OPTION_BYTES_BASE, - .option_size = 4, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L4PX - // RM0432 - .chip_id = STLINK_CHIPID_STM32_L4PX, - .dev_type = "L4Px", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) - .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 - // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size - .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 - .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 - .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32L4RX - // RM0432 - .chip_id = STLINK_CHIPID_STM32_L4Rx, - .dev_type = "L4Rx", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 58.2, page 2274) - .flash_pagesize = 0x1000, // 4k, section 3.3, pg 117-120 - // TODO: flash_pagesize can be 8k depend on the dual-bank mode and flash size - .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 - .bootrom_base = 0x1fff0000, // 3.3.1, pg 117 - .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 117) - .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32WB55xx, STM32WB35xx, STM32WB50CG/30CE - // RM0434, RM0471 - .chip_id = STLINK_CHIPID_STM32_WB55, - .dev_type = "WB5x/3x", - .flash_type = STLINK_FLASH_TYPE_WB, - .flash_size_reg = 0x1FFF75E0, - .flash_pagesize = 0x1000, // 4k - .sram_size = 0x40000, - .bootrom_base = 0x1fff0000, // see the memory map - .bootrom_size = 0x7000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // STM32WLEx - .chip_id = STLINK_CHIPID_STM32_WLE, - .dev_type = "WLEx", - .flash_type = STLINK_FLASH_TYPE_WB, - .flash_size_reg = 0x1FFF75E0, - .flash_pagesize = 0x800, // 2k - .sram_size = 0x10000, - .bootrom_base = 0x1fff0000, // see the memory map - .bootrom_size = 0x7000, - .flags = CHIP_F_HAS_SWO_TRACING, - }, - { - // unknown - .chip_id = STLINK_CHIPID_UNKNOWN, - .dev_type = "unknown device", - .flash_type = STLINK_FLASH_TYPE_UNKNOWN, - .flash_size_reg = 0x0, - .flash_pagesize = 0x0, - .sram_size = 0x0, - .bootrom_base = 0x0, - .bootrom_size = 0x0, - }, -//}; \ No newline at end of file diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 6b318dc46..1796c388c 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -234,43 +234,43 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* const uint8_t* loader_code; size_t loader_size; - if (sl->chip_id == STLINK_CHIPID_STM32_L1_MD || - sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L1_MD_PLUS || - sl->chip_id == STLINK_CHIPID_STM32_L1_MD_PLUS_HD || - sl->chip_id == STLINK_CHIPID_STM32_L152_RE || - sl->chip_id == STLINK_CHIPID_STM32_L011 || - sl->chip_id == STLINK_CHIPID_STM32_L0 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { + if (sl->chip_id == STM32_CHIPID_STM32_L1_MD || + sl->chip_id == STM32_CHIPID_STM32_L1_CAT2 || + sl->chip_id == STM32_CHIPID_STM32_L1_MD_PLUS || + sl->chip_id == STM32_CHIPID_STM32_L1_MD_PLUS_HD || + sl->chip_id == STM32_CHIPID_STM32_L152_RE || + sl->chip_id == STM32_CHIPID_STM32_L011 || + sl->chip_id == STM32_CHIPID_STM32_L0 || + sl->chip_id == STM32_CHIPID_STM32_L0_CAT5 || + sl->chip_id == STM32_CHIPID_STM32_L0_CAT2) { loader_code = loader_code_stm32lx; loader_size = sizeof(loader_code_stm32lx); } else if (sl->core_id == STM32VL_CORE_ID || - sl->chip_id == STLINK_CHIPID_STM32_F1_MD || - sl->chip_id == STLINK_CHIPID_STM32_F1_HD || - sl->chip_id == STLINK_CHIPID_STM32_F1_LD || - sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MD_LD || - sl->chip_id == STLINK_CHIPID_STM32_F1_VL_HD || - sl->chip_id == STLINK_CHIPID_STM32_F1_XLD || - sl->chip_id == STLINK_CHIPID_STM32_F1_CONN || - sl->chip_id == STLINK_CHIPID_STM32_F3 || - sl->chip_id == STLINK_CHIPID_STM32_F3xx_SMALL || - sl->chip_id == STLINK_CHIPID_STM32_F303_HD || - sl->chip_id == STLINK_CHIPID_STM32_F37x || - sl->chip_id == STLINK_CHIPID_STM32_F334) { + sl->chip_id == STM32_CHIPID_STM32_F1_MD || + sl->chip_id == STM32_CHIPID_STM32_F1_HD || + sl->chip_id == STM32_CHIPID_STM32_F1_LD || + sl->chip_id == STM32_CHIPID_STM32_F1_VL_MD_LD || + sl->chip_id == STM32_CHIPID_STM32_F1_VL_HD || + sl->chip_id == STM32_CHIPID_STM32_F1_XLD || + sl->chip_id == STM32_CHIPID_STM32_F1_CONN || + sl->chip_id == STM32_CHIPID_STM32_F3 || + sl->chip_id == STM32_CHIPID_STM32_F3xx_SMALL || + sl->chip_id == STM32_CHIPID_STM32_F303_HD || + sl->chip_id == STM32_CHIPID_STM32_F37x || + sl->chip_id == STM32_CHIPID_STM32_F334) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F2 || - sl->chip_id == STLINK_CHIPID_STM32_F4 || - sl->chip_id == STLINK_CHIPID_STM32_F4_DE || - sl->chip_id == STLINK_CHIPID_STM32_F4_LP || - sl->chip_id == STLINK_CHIPID_STM32_F4_HD || - sl->chip_id == STLINK_CHIPID_STM32_F4_DSI || - sl->chip_id == STLINK_CHIPID_STM32_F410 || - sl->chip_id == STLINK_CHIPID_STM32_F411xx || - sl->chip_id == STLINK_CHIPID_STM32_F412 || - sl->chip_id == STLINK_CHIPID_STM32_F413 || - sl->chip_id == STLINK_CHIPID_STM32_F446) { + } else if (sl->chip_id == STM32_CHIPID_STM32_F2 || + sl->chip_id == STM32_CHIPID_STM32_F4 || + sl->chip_id == STM32_CHIPID_STM32_F4_DE || + sl->chip_id == STM32_CHIPID_STM32_F4_LP || + sl->chip_id == STM32_CHIPID_STM32_F4_HD || + sl->chip_id == STM32_CHIPID_STM32_F4_DSI || + sl->chip_id == STM32_CHIPID_STM32_F410 || + sl->chip_id == STM32_CHIPID_STM32_F411xx || + sl->chip_id == STM32_CHIPID_STM32_F412 || + sl->chip_id == STM32_CHIPID_STM32_F413 || + sl->chip_id == STM32_CHIPID_STM32_F446) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, @@ -279,9 +279,9 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* if (retval == -1) { return(retval); } } else if (sl->core_id == STM32F7_CORE_ID || - sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F76xxx || - sl->chip_id == STLINK_CHIPID_STM32_F72xxx) { + sl->chip_id == STM32_CHIPID_STM32_F7 || + sl->chip_id == STM32_CHIPID_STM32_F76xxx || + sl->chip_id == STM32_CHIPID_STM32_F72xxx) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, @@ -289,19 +289,19 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code_stm32f7_lv, sizeof(loader_code_stm32f7_lv)); if (retval == -1) { return(retval); } - } else if (sl->chip_id == STLINK_CHIPID_STM32_F0 || - sl->chip_id == STLINK_CHIPID_STM32_F04 || - sl->chip_id == STLINK_CHIPID_STM32_F0_CAN || - sl->chip_id == STLINK_CHIPID_STM32_F0xx_SMALL || - sl->chip_id == STLINK_CHIPID_STM32_F09x) { + } else if (sl->chip_id == STM32_CHIPID_STM32_F0 || + sl->chip_id == STM32_CHIPID_STM32_F04 || + sl->chip_id == STM32_CHIPID_STM32_F0_CAN || + sl->chip_id == STM32_CHIPID_STM32_F0xx_SMALL || + sl->chip_id == STM32_CHIPID_STM32_F09x) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); - } else if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || - (sl->chip_id == STLINK_CHIPID_STM32_L41x_L42x) || - (sl->chip_id == STLINK_CHIPID_STM32_L43x_L44x) || - (sl->chip_id == STLINK_CHIPID_STM32_L45x_L46x) || - (sl->chip_id == STLINK_CHIPID_STM32_L4Rx) || - (sl->chip_id == STLINK_CHIPID_STM32_L496x_L4A6x)) { + } else if ((sl->chip_id == STM32_CHIPID_STM32_L4) || + (sl->chip_id == STM32_CHIPID_STM32_L41x_L42x) || + (sl->chip_id == STM32_CHIPID_STM32_L43x_L44x) || + (sl->chip_id == STM32_CHIPID_STM32_L45x_L46x) || + (sl->chip_id == STM32_CHIPID_STM32_L4Rx) || + (sl->chip_id == STM32_CHIPID_STM32_L496x_L4A6x)) { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); } else { From d3bf1453fd8c2f57faaa91bec01f24f0b00af347 Mon Sep 17 00:00:00 2001 From: Antoine Faure Date: Mon, 10 Jan 2022 09:49:41 +1300 Subject: [PATCH 1276/1435] Get each page size before erasing --- src/common.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/common.c b/src/common.c index fb5e431fa..de22ad851 100644 --- a/src/common.c +++ b/src/common.c @@ -2952,24 +2952,25 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size) { - // erase each page - int i = 0, num_pages = (int)(size / sl->flash_pgsz); - for (i = 0; i < num_pages; i++) { - // addr must be an addr inside the page - stm32_addr_t addr = - (stm32_addr_t)base_addr + i * (stm32_addr_t)sl->flash_pgsz; - - if (stlink_erase_flash_page(sl, addr)) { - WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); - return (-1); - } + stm32_addr_t addr = (stm32_addr_t)base_addr; - fprintf(stdout, "-> Flash page at %5d/%5d erased\n", i, num_pages); - fflush(stdout); + do { + size_t page_size = stlink_calculate_pagesize(sl, addr); + + if (stlink_erase_flash_page(sl, addr)) { + WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); + return (-1); } - fprintf(stdout, "\n"); - return 0; + fprintf(stdout, "-> Flash page at %#x erased (size: %#lx)\n", addr, page_size); + fflush(stdout); + + // check the next page is within the range to erase + addr += page_size; + } while (addr < (base_addr + size)); + + fprintf(stdout, "\n"); + return 0; } int stlink_erase_flash_mass(stlink_t *sl) { From 8a1535e2d2589a6594026b07ee3f4490533de692 Mon Sep 17 00:00:00 2001 From: Antoine Faure Date: Mon, 10 Jan 2022 10:26:14 +1300 Subject: [PATCH 1277/1435] Check parameters validity --- src/common.c | 5 +++++ src/st-flash/flash.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index de22ad851..ec44f2f9c 100644 --- a/src/common.c +++ b/src/common.c @@ -2952,6 +2952,11 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size) { + if (base_addr < sl->flash_base || (base_addr + size) > (sl->flash_base + sl->flash_size)) { + ELOG("Invalid address or flash size\n"); + return (-1); + } + stm32_addr_t addr = (stm32_addr_t)base_addr; do { diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index b4b596cfc..b1cdd02b7 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -168,7 +168,7 @@ int main(int ac, char** av) { goto on_error; } } else if (o.cmd == FLASH_CMD_ERASE) { - if (o.size != 0 && o.addr >= sl->flash_base && (o.addr + o.size) <= (sl->flash_base + sl->flash_size)) + if (o.size > 0 && o.addr > 0) err = stlink_erase_flash_section(sl, o.addr, o.size); else err = stlink_erase_flash_mass(sl); From f277fdb67750033716101ec0d0c48add46c5e075 Mon Sep 17 00:00:00 2001 From: Antoine Faure Date: Mon, 10 Jan 2022 12:51:44 +1300 Subject: [PATCH 1278/1435] Make sure address and size are each aligned with a page --- src/common.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index ec44f2f9c..a5d008abd 100644 --- a/src/common.c +++ b/src/common.c @@ -2957,11 +2957,26 @@ int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size return (-1); } - stm32_addr_t addr = (stm32_addr_t)base_addr; + stm32_addr_t addr = sl->flash_base; + + // Make sure the requested address is aligned with the beginning of a page + while (addr < base_addr) { + addr += stlink_calculate_pagesize(sl, addr); + } + if (addr != base_addr) { + ELOG("The address to erase is not aligned with the beginning of a page\n"); + return -1; + } do { size_t page_size = stlink_calculate_pagesize(sl, addr); + // Check if we are going further than the requested size + if ((addr + page_size) > (base_addr + size)) { + ELOG("Invalid size (not aligned with a page). Page size at address %#x is %#lx\n", addr, page_size); + return -1; + } + if (stlink_erase_flash_page(sl, addr)) { WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); return (-1); From 1e7d89fc1323f26cd566e059639448e21d66e638 Mon Sep 17 00:00:00 2001 From: hydroconstructor Date: Mon, 10 Jan 2022 20:24:29 +0400 Subject: [PATCH 1279/1435] Removing env. var. STLINK_DEVICE from docs In #1210 from codebase was removed functionality to specify ST-LINK by environment variable. This still mentioned in documentation, so I updated it. --- doc/man/st-flash.md | 5 ++--- doc/man/st-info.md | 3 --- doc/man/st-util.1 | 2 -- doc/man/st-util.md | 3 +-- doc/tutorial.md | 3 +-- 5 files changed, 4 insertions(+), 12 deletions(-) diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md index 80130c8f1..9b2cfcad5 100644 --- a/doc/man/st-flash.md +++ b/doc/man/st-flash.md @@ -20,8 +20,7 @@ You can use this instead of st-util(1) if you prefer, but remember to use the Use hexadecimal format for the *ADDR* and *SIZE*. -The STLink device to use can be specified using the --serial parameter, or via -the environment variable STLINK_DEVICE on the format :. +The STLink device to use can be specified using the --serial parameter. # COMMANDS @@ -52,7 +51,7 @@ reset : Enable ignore ending empty bytes optimization \--serial *iSerial* -: TODO +: Serial number of ST-LINK device to use \--flash=fsize : Where fsize is the size in decimal, octal, or hex followed by an optional multiplier diff --git a/doc/man/st-info.md b/doc/man/st-info.md index 91f9ea0b0..2cca61f83 100644 --- a/doc/man/st-info.md +++ b/doc/man/st-info.md @@ -15,9 +15,6 @@ st-info - Provides information about connected STLink and STM32 devices Provides information about connected STLink programmers and STM32 devices: Serial code, flash, page size, sram, chipid, description. -The STLink device to probe can be specified via the environment variable -STLINK_DEVICE on the format :. - # OPTIONS \--version diff --git a/doc/man/st-util.1 b/doc/man/st-util.1 index 9b46b4d65..2f718bb2b 100644 --- a/doc/man/st-util.1 +++ b/doc/man/st-util.1 @@ -19,8 +19,6 @@ option, the default \f[B]4242\f[R] port will be used. Stlink version 2 is used by default unless the option \f[B]\[en]stlinkv1\f[R] is given. .PP -The STLinkV2 device to use can be specified in the environment variable -STLINK_DEVICE on the format :. .SH OPTIONS .TP .B \-h, \-\-help diff --git a/doc/man/st-util.md b/doc/man/st-util.md index 9a54fb309..62f850203 100644 --- a/doc/man/st-util.md +++ b/doc/man/st-util.md @@ -17,8 +17,7 @@ Run the main binary of the local package (src/main.rs). If a port number is not specified using the **--listen_port** option, the default **4242** port will be used. -The STLink device to use can be specified using the --serial parameter, or via -the environment variable STLINK_DEVICE on the format :. +The STLink device to use can be specified using the --serial parameter. # OPTIONS diff --git a/doc/tutorial.md b/doc/tutorial.md index 955f85611..685325c37 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -244,8 +244,7 @@ There are a few options: Do not reset board on connection. ``` -The STLink device to use can be specified using the --serial parameter, or via -the environment variable STLINK_DEVICE on the format :. +The STLink device to use can be specified using the --serial parameter. Then, in your project directory, someting like this... (remember, you need to run an _ARM_ gdb, not an x86 gdb) From 77b3319fc91120cc7d053e14363c41eb123c8fa3 Mon Sep 17 00:00:00 2001 From: Antoine Faure Date: Thu, 13 Jan 2022 09:12:39 +1300 Subject: [PATCH 1280/1435] Use stlink_erase_flash_section in stlink_write_flash --- src/common.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/common.c b/src/common.c index a5d008abd..af2222c5b 100644 --- a/src/common.c +++ b/src/common.c @@ -3491,7 +3491,6 @@ int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint8_t eraseonly) { - size_t off; int ret; flash_loader_t fl; ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, @@ -3525,23 +3524,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, // make sure we've loaded the context with the chip details stlink_core_id(sl); - // Erase each page - int page_count = 0; - - for (off = 0; off < len; - off += stlink_calculate_pagesize(sl, addr + (uint32_t)off)) { - // addr must be an addr inside the page - if (stlink_erase_flash_page(sl, addr + (uint32_t)off) == -1) { - ELOG("Failed to erase_flash_page(%#x) == -1\n", (unsigned)(addr + off)); - return (-1); - } - - ILOG("Flash page at addr: 0x%08lx erased\n", (unsigned long)(addr + off)); - page_count++; - } - - ILOG("Finished erasing %d pages of %u (%#x) bytes\n", page_count, - (unsigned)(sl->flash_pgsz), (unsigned)(sl->flash_pgsz)); + // Erase this section of the flash + stlink_erase_flash_section(sl, addr, len); if (eraseonly) { return (0); From a2a04dd1b79b5f8c00002d4a914dc3a82f04ea82 Mon Sep 17 00:00:00 2001 From: Antoine Faure Date: Thu, 13 Jan 2022 09:22:14 +1300 Subject: [PATCH 1281/1435] Update log --- src/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index af2222c5b..4e276d23b 100644 --- a/src/common.c +++ b/src/common.c @@ -2953,7 +2953,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size) { if (base_addr < sl->flash_base || (base_addr + size) > (sl->flash_base + sl->flash_size)) { - ELOG("Invalid address or flash size\n"); + ELOG("Invalid address or size\n"); return (-1); } From 8667990506da8642344adb5da7f1b76c9d6cbfec Mon Sep 17 00:00:00 2001 From: Antoine Faure Date: Thu, 13 Jan 2022 11:41:14 +1300 Subject: [PATCH 1282/1435] Allow to completely erase a page when size is not aligned --- inc/stlink.h | 2 +- src/common.c | 13 ++++++++----- src/st-flash/flash.c | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 852e95e42..083b3466c 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -274,7 +274,7 @@ int stlink_trace_enable(stlink_t* sl, uint32_t frequency); int stlink_trace_disable(stlink_t* sl); int stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size); int stlink_erase_flash_mass(stlink_t* sl); -int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size); +int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size); int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); uint8_t stlink_get_erased_pattern(stlink_t *sl); diff --git a/src/common.c b/src/common.c index 4e276d23b..f72cad582 100644 --- a/src/common.c +++ b/src/common.c @@ -2951,7 +2951,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { return check_flash_error(sl); } -int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size) { +int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size) { if (base_addr < sl->flash_base || (base_addr + size) > (sl->flash_base + sl->flash_size)) { ELOG("Invalid address or size\n"); return (-1); @@ -2971,8 +2971,8 @@ int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size do { size_t page_size = stlink_calculate_pagesize(sl, addr); - // Check if we are going further than the requested size - if ((addr + page_size) > (base_addr + size)) { + // Check if size is aligned with a page, unless we want to completely erase the last page + if ((addr + page_size) > (base_addr + size) && !align_size) { ELOG("Invalid size (not aligned with a page). Page size at address %#x is %#lx\n", addr, page_size); return -1; } @@ -3000,7 +3000,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_L0 || sl->flash_type == STLINK_FLASH_TYPE_WB) { - stlink_erase_flash_section(sl, sl->flash_base, sl->flash_size); + err = stlink_erase_flash_section(sl, sl->flash_base, sl->flash_size, false); } else { wait_flash_busy(sl); @@ -3525,7 +3525,10 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, stlink_core_id(sl); // Erase this section of the flash - stlink_erase_flash_section(sl, addr, len); + if (stlink_erase_flash_section(sl, addr, len, true) < 0) { + ELOG("Failed to erase the flash prior to writing\n"); + return (-1); + } if (eraseonly) { return (0); diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index b1cdd02b7..6ac2ba48b 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -169,7 +169,7 @@ int main(int ac, char** av) { } } else if (o.cmd == FLASH_CMD_ERASE) { if (o.size > 0 && o.addr > 0) - err = stlink_erase_flash_section(sl, o.addr, o.size); + err = stlink_erase_flash_section(sl, o.addr, o.size, false); else err = stlink_erase_flash_mass(sl); From 2c62079ed1d07c9236c08cc1f0e6cf118dd4fb4a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 14 Jan 2022 00:17:44 +0100 Subject: [PATCH 1283/1435] Removed stlink/v1 support for macOS 10.14 --- CHANGELOG.md | 2 +- README.md | 2 +- doc/version_support.md | 2 +- stlinkv1_macos_driver/install.sh | 3 - .../Contents/Info.plist | 82 ------------- .../Contents/MacOS/stlink_shield_10_14 | Bin 33840 -> 0 bytes .../stlink_shield_10_14.kext/Contents/PkgInfo | 1 - .../Contents/_CodeSignature/CodeResources | 115 ------------------ .../stlink_shield.xcodeproj/project.pbxproj | 50 -------- 9 files changed, 3 insertions(+), 254 deletions(-) delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/PkgInfo delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/_CodeSignature/CodeResources diff --git a/CHANGELOG.md b/CHANGELOG.md index 06f995d21..039ca7848 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # v1.7.1 -Release date: 2021-xx-xx +Release date: 2022-xx-xx This release drops support for some older operating systems. Check project README for details. Updated system requirements: Raised minimum version for `cmake` to 3.7.2. diff --git a/README.md b/README.md index 7f797a7d9..bc491189e 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ It supports several so called STLINK programmer boards (and clones thereof) whic - stand-alone programmer (STLINK-V3SET, STLINK-V3MINI, STLINK-V3MODS) - on-board on some STM32 Nucleo boards (STLINK-V3E) -_\*)_ **Note: Support for the STLINK/V1 on macOS is limited to 10.14 - 10.15. Due to the deprecation and removal of macOS Kernel Extensions (KEXT) there will be no support for this programmer on macOS 11 or any later version.** +_\*)_ *Note: Support for the STLINK/V1 on macOS is limited to 10.15. Due to the deprecation and removal of macOS Kernel Extensions (KEXT) there will be no support for this programmer on macOS 11 or any later version.* On the user level there is no difference in handling or operation between these different revisions. diff --git a/doc/version_support.md b/doc/version_support.md index 2c5df7461..4eeb5074a 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -17,7 +17,7 @@ Up on compiling c-make will **automatically** download and install the latest co | homebrew | 1.0.24 | 3.20.2 | 3.24.29
      gtk+3 | 10.9 - 11.x | | MacPorts | 1.0.24 | 3.20.2 | 3.24.29
      gtk3 | 10.4 - 11.x | -NOTE: In order to use a STLINK/V1 programmer on macOS, versions 10.14 or 10.15 are required. +NOTE: In order to use a STLINK/V1 programmer on macOS, version 10.15 is required. ### Linux-/Unix-based: diff --git a/stlinkv1_macos_driver/install.sh b/stlinkv1_macos_driver/install.sh index 5716281a1..f9878bd46 100644 --- a/stlinkv1_macos_driver/install.sh +++ b/stlinkv1_macos_driver/install.sh @@ -2,9 +2,6 @@ ISMACOS=$(sw_vers -productVersion) case $ISMACOS in -10.14*) - KEXT="stlink_shield_10_14.kext" - ;; 10.15*) KEXT="stlink_shield_10_15.kext" ;; diff --git a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist deleted file mode 100644 index fd424ea93..000000000 --- a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist +++ /dev/null @@ -1,82 +0,0 @@ - - - - - BuildMachineOSBuild - 18G7016 - CFBundleDevelopmentRegion - English - CFBundleIdentifier - com.libusb.stlink-shield - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - KEXT - CFBundleSignature - ???? - CFBundleSupportedPlatforms - - MacOSX - - CFBundleVersion - 1.0.0 - DTCompiler - com.apple.compilers.llvm.clang.1_0 - DTPlatformBuild - 11C504 - DTPlatformVersion - GM - DTSDKBuild - 19B90 - DTSDKName - macosx10.15 - DTXcode - 1130 - DTXcodeBuild - 11C504 - IOKitPersonalities - - DeviceDriver - - CFBundleIdentifier - com.apple.kpi.iokit - IOClass - IOService - IOProviderClass - IOUSBDevice - bcdDevice - 256 - idProduct - 14148 - idVendor - 1155 - - InterfaceDriver - - CFBundleIdentifier - com.apple.kpi.iokit - IOClass - IOService - IOProviderClass - IOUSBInterface - bConfigurationValue - 1 - bInterfaceNumber - 0 - idProduct - 14148 - idVendor - 1155 - - - LSMinimumSystemVersion - 10.14 - OSBundleLibraries - - com.apple.iokit.IOUSBFamily - 1.8 - com.apple.kpi.libkern - 11.2.0 - - - diff --git a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 deleted file mode 100644 index 6a32aa4615953f6afe16047f73da9a3bced9b3a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33840 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 - - - - files - - files2 - - rules - - ^Resources/ - - ^Resources/.*\.lproj/ - - optional - - weight - 1000 - - ^Resources/.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^Resources/Base\.lproj/ - - weight - 1010 - - ^version.plist$ - - - rules2 - - .*\.dSYM($|/) - - weight - 11 - - ^(.*/)?\.DS_Store$ - - omit - - weight - 2000 - - ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ - - nested - - weight - 10 - - ^.* - - ^Info\.plist$ - - omit - - weight - 20 - - ^PkgInfo$ - - omit - - weight - 20 - - ^Resources/ - - weight - 20 - - ^Resources/.*\.lproj/ - - optional - - weight - 1000 - - ^Resources/.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^Resources/Base\.lproj/ - - weight - 1010 - - ^[^/]+$ - - nested - - weight - 10 - - ^embedded\.provisionprofile$ - - weight - 20 - - ^version\.plist$ - - weight - 20 - - - - diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj index 4f2b80254..373600c64 100644 --- a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXFileReference section */ 8CD33C31149BB80D0033D618 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = stlink_shield_10_14.kext; sourceTree = BUILT_PRODUCTS_DIR; }; 8F90850924786F39009109AD /* stlink_shield_10_15.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = stlink_shield_10_15.kext; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -34,7 +33,6 @@ 19C28FB6FE9D52B211CA2CBB /* Products */ = { isa = PBXGroup; children = ( - 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */, 8F90850924786F39009109AD /* stlink_shield_10_15.kext */, ); name = Products; @@ -60,26 +58,6 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 8F9084F324786F0F009109AD /* stlink_shield_10_14 */ = { - isa = PBXNativeTarget; - buildConfigurationList = 8F9084FA24786F0F009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_14" */; - buildPhases = ( - 8F9084F424786F0F009109AD /* ShellScript */, - 8F9084F524786F0F009109AD /* Headers */, - 8F9084F624786F0F009109AD /* Resources */, - 8F9084F824786F0F009109AD /* Sources */, - 8F9084F924786F0F009109AD /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = stlink_shield_10_14; - productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; - productName = NanosMouse; - productReference = 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */; - productType = "com.apple.product-type.kernel-extension.iokit"; - }; 8F9084FF24786F39009109AD /* stlink_shield_10_15 */ = { isa = PBXNativeTarget; buildConfigurationList = 8F90850624786F39009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_15" */; @@ -120,7 +98,6 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 8F9084F324786F0F009109AD /* stlink_shield_10_14 */, 8F9084FF24786F39009109AD /* stlink_shield_10_15 */, ); }; @@ -458,24 +435,6 @@ }; name = Release; }; - 8F9084FB24786F0F009109AD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - MACOSX_DEPLOYMENT_TARGET = 10.14; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 8F9084FC24786F0F009109AD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - MACOSX_DEPLOYMENT_TARGET = 10.14; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; 8F90850724786F39009109AD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -506,15 +465,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 8F9084FA24786F0F009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_14" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 8F9084FB24786F0F009109AD /* Debug */, - 8F9084FC24786F0F009109AD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 8F90850624786F39009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_15" */ = { isa = XCConfigurationList; buildConfigurations = ( From 74957efc9dafb3569c4ef4d0ab9d9007d7989af4 Mon Sep 17 00:00:00 2001 From: Antoine Faure Date: Fri, 14 Jan 2022 14:50:35 +1300 Subject: [PATCH 1284/1435] Factorize address checks --- inc/stlink.h | 2 ++ src/common.c | 55 +++++++++++++++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 083b3466c..df13aa7c9 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -289,6 +289,8 @@ int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); +int stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size); +int stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr); uint16_t read_uint16(const unsigned char *c, const int pt); void stlink_core_stat(stlink_t *sl); void stlink_print_data(stlink_t *sl); diff --git a/src/common.c b/src/common.c index f72cad582..6cbd217ef 100644 --- a/src/common.c +++ b/src/common.c @@ -2951,23 +2951,47 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { return check_flash_error(sl); } -int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size) { - if (base_addr < sl->flash_base || (base_addr + size) > (sl->flash_base + sl->flash_size)) { - ELOG("Invalid address or size\n"); +// Check if an address and size are within the flash +int stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size) { + if (addr < sl->flash_base || addr >= (sl->flash_base + sl->flash_size)) { + ELOG("Invalid address, it should be within 0x%08x - 0x%08lx\n", sl->flash_base, (sl->flash_base + sl->flash_size -1)); + return (-1); + } + if ((addr + size) > (sl->flash_base + sl->flash_size)) { + ELOG("The size exceeds the size of the flash (0x%08lx bytes available)\n", (sl->flash_base + sl->flash_size - addr)); return (-1); } + return 0; +} - stm32_addr_t addr = sl->flash_base; +// Check if an address is aligned with the beginning of a page +int stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr) { + stm32_addr_t page = sl->flash_base; - // Make sure the requested address is aligned with the beginning of a page - while (addr < base_addr) { - addr += stlink_calculate_pagesize(sl, addr); + while (page < addr) { + page += stlink_calculate_pagesize(sl, page); } - if (addr != base_addr) { + + if (page != addr) { + return -1; + } + + return 0; +} + +int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size) { + // Check the address and size validity + if (stlink_check_address_range_validity(sl, base_addr, size) < 0) { + return -1; + } + + // Make sure the requested address is aligned with the beginning of a page + if (stlink_check_address_alignment(sl, base_addr) < 0) { ELOG("The address to erase is not aligned with the beginning of a page\n"); return -1; } + stm32_addr_t addr = base_addr; do { size_t page_size = stlink_calculate_pagesize(sl, addr); @@ -3498,22 +3522,13 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, // check addr range is inside the flash stlink_calculate_pagesize(sl, addr); - if (addr < sl->flash_base) { - ELOG("addr too low %#x < %#x\n", addr, sl->flash_base); - return (-1); - } else if ((addr + len) < addr) { - ELOG("addr overruns\n"); - return (-1); - } else if ((addr + len) > (sl->flash_base + sl->flash_size)) { - ELOG("addr too high\n"); - return (-1); - } else if (addr & 1) { - ELOG("unaligned addr 0x%x\n", addr); + // Check the address and size validity + if (stlink_check_address_range_validity(sl, addr, len) < 0) { return (-1); } else if (len & 1) { WLOG("unaligned len 0x%x -- padding with zero\n", len); len += 1; - } else if (addr & (sl->flash_pgsz - 1)) { + } else if (stlink_check_address_alignment(sl, addr) < 0) { ELOG("addr not a multiple of current pagesize (%u bytes), not supported, " "check page start address and compare with flash module organisation " "in related ST reference manual of your device.\n", From c854df5edd1285c1016e6181bcd54acf6f2e0bcd Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 15 Jan 2022 01:58:42 +0100 Subject: [PATCH 1285/1435] Updated MCU core-ids --- doc/devices_boards.md | 30 +++++++++++++++--------------- inc/stm32.h | 33 +++++++++++++++++++++------------ src/common.c | 2 +- src/st-util/gdb-server.c | 2 +- src/stlink-lib/flash_loader.c | 4 ++-- 5 files changed, 40 insertions(+), 31 deletions(-) diff --git a/doc/devices_boards.md b/doc/devices_boards.md index a8a366448..63569881a 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -2,7 +2,7 @@ The following devices are supported by the stlink toolset. -## STM32F0 / ARM Cortex M0 / Core-ID: 0x0bb11477 (STM32F0_CORE_ID) +## STM32F0 / ARM Cortex M0 | Chip-ID | Product-Code | | ------- | ------------------- | @@ -19,7 +19,7 @@ The following devices are supported by the stlink toolset. | 0x442 | STM32F0**9**xxx | -## STM32F1 / ARM Cortex M3 / Core-ID: 0x1ba01477 (STM32F1_CORE_ID) +## STM32F1 / ARM Cortex M3 | Product-Code | Product Line | | ----------------- | ----------------------- | @@ -45,20 +45,20 @@ Tested non-official ST boards [incl. STLINK programmers]: - HY-STM32 (STM32F103VETx) [v1, v2] - DecaWave EVB1000 (STM32F105RCTx) [v1, v2] -## STM32F2 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32F2_CORE_ID) +## STM32F2 / ARM Cortex M3 | Chip-ID | Product-Code | Product Line | | ------- | ------------ | ------------- | | 0x411 | STM32F2yyxx | (all devices) | -## STM32F1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32F1c_CORE_ID) +## STM32F1 Clone / ARM Cortex M3 (Core-ID: 0x2ba01477) | Product-Code | Chip-ID | STLink
      Programmer | Boards | | ------------- | ------- | ---------------------- | ----------------------------------------------------------------------------------------------- | | CKS32F103C8Tx | 0x410 | v2 | "STM32"-Bluepill ( _**Fake-Marking !**_ )
      STM32F103C8T6 clone from China Key Systems (CKS) | | CKS32F103C8Tx | 0x410 | v2 | CKS32-Bluepill (Clone)
      STM32F103C8T6 clone from China Key Systems (CKS) | -## STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3_CORE_ID) +## STM32F3 / ARM Cortex M4F | Product-Code | Product Line | | ----------------- | ------------------------------------------------------------- | @@ -85,13 +85,13 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x446 | _N/A_ | xD xE | | F302 | F303 | | | 0x446 | _N/A_ | - | | | | F398 | -## STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3c_CORE_ID) +## STM32F3 Clone / ARM Cortex M4F (Core-ID: 0x2ba01477) | Product-Code | Chip-ID | STLINK
      Programmer | Boards | | ------------ | ------- | ---------------------- | ---------------------------------- | | GD32F303VGT6 | 0x430 | [v2] | STM32F303 clone from GigaDevice GD | -## STM32F4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F4_CORE_ID) +## STM32F4 / ARM Cortex M4F | Chip-ID | Product-Code | | ------- | ------------------- | @@ -112,7 +112,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x463 | STM32F4**13**xx | | 0x463 | STM32F4**23**xx | -## STM32F7 / ARM Cortex M7F / Core-ID: 0x5ba02477 (STM32F7_CORE_ID) +## STM32F7 / ARM Cortex M7F | Chip-ID | Product-Code | | ------- | --------------- | @@ -123,7 +123,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x451 | STM32F7**6**xxx | | 0x451 | STM32F7**7**xxx | -## STM32H7 / ARM Cortex M7F / Core-ID: 0x6ba02477 (STM32H7_CORE_ID) +## STM32H7 / ARM Cortex M7F | Chip-ID | Product-Code | | ------- | ------------- | @@ -132,7 +132,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x480 | STM32H7**A**x | | 0x480 | STM32H7**B**x | -## STM32G0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32G0_CORE_ID) +## STM32G0 / ARM Cortex M0+ | Chip-ID | Product-Code | | ------- | --------------- | @@ -141,7 +141,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x460 | STM32G0**7**xxx | | 0x460 | STM32G0**8**xxx | -## STM32G4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32G4_CORE_ID) +## STM32G4 / ARM Cortex M4F | Chip-ID | Product-Code | | ------- | --------------- | @@ -151,7 +151,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x469 | STM32G4**8**xxx | | 0x479 | STM32G4**91**xx | -## STM32L0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32L0_CORE_ID) +## STM32L0 / ARM Cortex M0+ | Chip-ID | Product-Code | | ------- | --------------- | @@ -164,7 +164,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x447 | STM32L0**7**xxx | | 0x447 | STM32L0**8**xxx | -## STM32L1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32L1_CORE_ID) +## STM32L1 / ARM Cortex M3 | Chip-ID | Product-Code | | ------- | ---------------- | @@ -178,7 +178,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x436 | STM32L1xxx**D** | | 0x437 | STM32L1xxx**E** | -## STM32L4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32L4_CORE_ID) +## STM32L4 / ARM Cortex M4F | Chip-ID | Product-Code | | ------- | --------------- | @@ -197,7 +197,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x471 | STM32L4**P5**xx | | 0x471 | STM32L4**Q5**xx | -## STM32W / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32W_CORE_ID) +## STM32W / ARM Cortex M3 | Chip-ID | Product-Code | | ------- | --------------- | diff --git a/inc/stm32.h b/inc/stm32.h index 8dff2a7d7..d6faff12e 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -7,11 +7,20 @@ #ifndef STM32_H #define STM32_H -/* Cortex-M core ids */ -#define STM32VL_CORE_ID 0x1ba01477 -#define STM32F7_CORE_ID 0x5ba02477 -#define STM32H7_CORE_ID 0x6ba02477 // STM32H7 SWD ID Code -#define STM32H7_CORE_ID_JTAG 0x6ba00477 // STM32H7 JTAG ID Code (RM0433 p.3065) +/* Cortex-M core ids (CPUTAPID) */ +#define STM32_CORE_ID_M3_F2_JTAG 0x0ba00477 // unused // F2 JTAG (RM0033 p.1326) +//#define STM32_CORE_ID_M33_JTAG 0x0ba04477 // unused // L5 JTAG +#define STM32_CORE_ID_M0 0x0bb11477 // unused // F0 +#define STM32_CORE_ID_M0P 0x0bc11477 // unused // L0, G0 +#define STM32_CORE_ID_M33 0x0be01477 // unused // L5 SWD (RM0351 p.2029) +#define STM32_CORE_ID_M33_JTAG 0x0be02477 // unused // L5 JTAG (RM0438 p.2029) +#define STM32_CORE_ID_M3_F1 0x1ba01477 // F1 (RM0008 p.1092) +#define STM32_CORE_ID_M4F_L4 0x1ba01477 // unused // L4 (RM0351 p.1845) +#define STM32_CORE_ID_M4F_F4 0x2ba01477 // unused // F4 (RM0090 p.1695) +#define STM32_CORE_ID_M4F_F4_JTAG 0x4ba00477 // unused // F4 JTAG (RM090 p.1691) +#define STM32_CORE_ID_M7_F7 0x5ba02477 // F7 +#define STM32_CORE_ID_M7_H7 0x6ba02477 // H7 +#define STM32_CORE_ID_M7_H7_JTAG 0x6ba00477 // H7 JTAG (RM0433 p.3065) /* STM32 flash types */ // New flash type definitions must go before STM32_FLASH_TYPE_UNDEFINED @@ -22,13 +31,13 @@ enum stm32_flash_type { STM32_FLASH_TYPE_F1_XL = 2, STM32_FLASH_TYPE_F2_F4 = 3, STM32_FLASH_TYPE_F7 = 4, - STM32_FLASH_TYPE_G0 = 5, // 7 - STM32_FLASH_TYPE_G4 = 6, // 8 - STM32_FLASH_TYPE_H7 = 7, // 10 - STM32_FLASH_TYPE_L0_L1 = 8, // 5 - STM32_FLASH_TYPE_L4_L4P = 9, // 6 - STM32_FLASH_TYPE_L5_U5 = 10, // new - STM32_FLASH_TYPE_WB_WL = 11, // 9 + STM32_FLASH_TYPE_G0 = 5, + STM32_FLASH_TYPE_G4 = 6, + STM32_FLASH_TYPE_H7 = 7, + STM32_FLASH_TYPE_L0_L1 = 8, + STM32_FLASH_TYPE_L4_L4P = 9, + STM32_FLASH_TYPE_L5_U5 = 10, + STM32_FLASH_TYPE_WB_WL = 11, STM32_FLASH_TYPE_UNDEFINED = 12, // max. value exceeded }; diff --git a/src/common.c b/src/common.c index 5a6d0d86b..5a9c43c96 100644 --- a/src/common.c +++ b/src/common.c @@ -1514,7 +1514,7 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { * */ - if ((sl->core_id == STM32H7_CORE_ID || sl->core_id == STM32H7_CORE_ID_JTAG) && + if ((sl->core_id == STM32_CORE_ID_M7_H7 || sl->core_id == STM32_CORE_ID_M7_H7_JTAG) && cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) ret = stlink_read_debug32(sl, 0x5c001000, chip_id); diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 4babef0cc..19819a6cb 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -559,7 +559,7 @@ char* make_memory_map(stlink_t *sl) { strcpy(map, memory_map_template_F4); } else if (sl->chip_id == STM32_CHIPID_STM32_F4_DE) { strcpy(map, memory_map_template_F4_DE); - } else if (sl->core_id == STM32F7_CORE_ID) { + } else if (sl->core_id == STM32_CORE_ID_M7_F7) { snprintf(map, sz, memory_map_template_F7, (unsigned int)sl->sram_size); } else if (sl->chip_id == STM32_CHIPID_STM32_H74xxx) { diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 1796c388c..ad52d6567 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -245,7 +245,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STM32_CHIPID_STM32_L0_CAT2) { loader_code = loader_code_stm32lx; loader_size = sizeof(loader_code_stm32lx); - } else if (sl->core_id == STM32VL_CORE_ID || + } else if (sl->core_id == STM32_CORE_ID_M3_F1 || sl->chip_id == STM32_CHIPID_STM32_F1_MD || sl->chip_id == STM32_CHIPID_STM32_F1_HD || sl->chip_id == STM32_CHIPID_STM32_F1_LD || @@ -278,7 +278,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code_stm32f4_lv, sizeof(loader_code_stm32f4_lv)); if (retval == -1) { return(retval); } - } else if (sl->core_id == STM32F7_CORE_ID || + } else if (sl->core_id == STM32_CORE_ID_M7_F7 || sl->chip_id == STM32_CHIPID_STM32_F7 || sl->chip_id == STM32_CHIPID_STM32_F76xxx || sl->chip_id == STM32_CHIPID_STM32_F72xxx) { From 3be2c70a675e1cfec5d1a6c35621dcc1d1517566 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 16 Jan 2022 18:10:01 +0100 Subject: [PATCH 1286/1435] General Project Update - [doc] Updated system requirements -> cmake >= 3.10.2 -> libusb >= 1.0.21 (except for FreeBSD) -> gtk >= 3.22.30 - Updated CHANGELOG.md - Updated list of contributors --- CHANGELOG.md | 16 ++- CMakeLists.txt | 2 +- cmake/modules/Findlibusb.cmake | 2 +- cmake/packaging/cpack_config.cmake | 2 +- cmake/packaging/deb/control | 2 +- contributors.txt | 3 + doc/compiling.md | 4 +- doc/version_support.md | 153 +++++++++++++++-------------- 8 files changed, 103 insertions(+), 81 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 039ca7848..d744ff564 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,11 @@ Release date: 2022-xx-xx This release drops support for some older operating systems. Check project README for details. -Updated system requirements: Raised minimum version for `cmake` to 3.7.2. + +Updated system requirements: +- `cmake` >= 3.10.2 +- `libusb` >= 1.0.21 +- `libgtk-dev` >= 3.22.30 Features: @@ -15,6 +19,9 @@ Features: - Expanded and revised list of chips ([#1145](https://github.com/stlink-org/stlink/pull/1145), [#1164](https://github.com/stlink-org/stlink/pull/1164)) - [STM32H72X/3X]: Added full access to all device memory ([#1158](https://github.com/stlink-org/stlink/pull/1158), [#1159](https://github.com/stlink-org/stlink/pull/1159)) - Added support for STM32WLEx ([#1173](https://github.com/stlink-org/stlink/pull/1173)) +- Added support for STLINK-V3 devices with no MSD ([#1185](https://github.com/stlink-org/stlink/pull/1185)) +- Updated gdb-server.c to allow external memory access on STM32H73xx ([#1196](https://github.com/stlink-org/stlink/pull/1196), [#1197](https://github.com/stlink-org/stlink/pull/1197)) +- Erase addr size / section of the flash memory with st-flash ([#1213](https://github.com/stlink-org/stlink/pull/1213)) Updates & changes: @@ -22,10 +29,12 @@ Updates & changes: - Added instructions for bug-reports and feature-requests to contribution guidelines ([#906](https://github.com/stlink-org/stlink/pull/906)) - Added travis CI configuration for macOS 10.14 to maintain capability for 32-bit compilation ([#f5ada94](https://github.com/stlink-org/stlink/commit/f5ada9474cdb87ff37de0d4eb9e75622b5870646)) - Updated description of chip id 0x0457 to L01x/L02x ([#1143](https://github.com/stlink-org/stlink/pull/1143), [#1144](https://github.com/stlink-org/stlink/pull/1144)) -- Drop execute bits from source code files ([#1167](https://github.com/stlink-org/stlink/pull/1167)) +- Dropped execute bits from source code files ([#1167](https://github.com/stlink-org/stlink/pull/1167)) - Use proper Markdown headers for supported MCUs ([#1168](https://github.com/stlink-org/stlink/pull/1168)) - Removed redundant array ([#1178](https://github.com/stlink-org/stlink/pull/1178)) - Updated chip config files from the library structs ([#1181](https://github.com/stlink-org/stlink/pull/1181)) +- [doc] Corrected file path in tutorial ([#1186](https://github.com/stlink-org/stlink/pull/1186)) +- Improved chipid checks and printouts ([#1188](https://github.com/stlink-org/stlink/pull/1188)) Fixes: - cmake: Install shared libraries in proper directories ([#1142](https://github.com/stlink-org/stlink/pull/1142)) @@ -41,6 +50,9 @@ Fixes: - Fixed few warnings for msvc about type conversion with possible lost data ([#1179](https://github.com/stlink-org/stlink/pull/1179)) - st-flash and other utilities search for chip files in the wrong directory ([#1180](https://github.com/stlink-org/stlink/pull/1180), commit [#c8fc656](https://github.com/stlink-org/stlink/commit/c8fc6561fead79ad49c09d82bab864745086792c)) - Fixed broken build on 32 bit systems ([#985](https://github.com/stlink-org/stlink/pull/985), [#1175](https://github.com/stlink-org/stlink/pull/1175), commit [#c8fc656](https://github.com/stlink-org/stlink/commit/c8fc6561fead79ad49c09d82bab864745086792c)) +- Define 'SSIZE_MAX' if not defined ([#1183](https://github.com/stlink-org/stlink/pull/1183)) +- Fixed compliation for OpenBSD 7.0 ([#1202](https://github.com/stlink-org/stlink/pull/1202)) +- Included 'SSIZE_MAX' from 'limits.h' in 'src/common.c' ([#1207](https://github.com/stlink-org/stlink/pull/1207)) # v1.7.0 diff --git a/CMakeLists.txt b/CMakeLists.txt index fd17d47cc..66bf34e3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # General cmake settings ### -cmake_minimum_required(VERSION 3.7.2) +cmake_minimum_required(VERSION 3.10.2) cmake_policy(SET CMP0042 NEW) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index cd52026f5..bc04f848d 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -72,7 +72,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to if (WIN32 AND NOT EXISTS "/etc/debian_version") # Skip this for Debian... # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.24) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake index acd5630fa..587ff5fb5 100644 --- a/cmake/packaging/cpack_config.cmake +++ b/cmake/packaging/cpack_config.cmake @@ -53,7 +53,7 @@ elseif (EXISTS "/etc/debian_version" AND NOT EXISTS WIN32) # Package-build is av set(CPACK_DEBIAN_PACKAGE_RELEASE "1") # CPACK_DEBIAN_PACKAGE_ARCHITECTURE --> Default: Output of dpkg --print-architecture - set(CPACK_DEBIAN_PACKAGE_DEPENDS "pkg-config, build-essential, debhelper (>=9), cmake (>= 3.4.2), libusb-1.0-0-dev (>= 1.0.20)") + set(CPACK_DEBIAN_PACKAGE_DEPENDS "pkg-config, build-essential, debhelper (>=9), cmake (>= 3.10.2), libusb-1.0-0-dev (>= 1.0.21)") set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Nightwalker-87 ") # CPACK_DEBIAN_PACKAGE_DESCRIPTION --> Default: CPACK_DEBIAN_PACKAGE_DESCRIPTION (as it is set) # CPACK_DEBIAN_PACKAGE_SECTION --> Default: “devel” diff --git a/cmake/packaging/deb/control b/cmake/packaging/deb/control index ef51a6cea..7c8d13e47 100644 --- a/cmake/packaging/deb/control +++ b/cmake/packaging/deb/control @@ -1,7 +1,7 @@ Source: stlink Priority: optional Maintainer: Nightwalker-87 -Build-Depends: cmake, dh-cmake, debhelper (>= 9), libusb-1.0-0-dev, libgtk-3-dev +Build-Depends: cmake (>= 3.10.2), dh-cmake, debhelper (>= 9), libusb-1.0-0-dev (>= 1.0.21), libgtk-3-dev (>= 3.22.30) Standards-Version: 4.5.0 Rules-Requires-Root: no Section: electronics diff --git a/contributors.txt b/contributors.txt index bcaa0b538..cffef89f6 100644 --- a/contributors.txt +++ b/contributors.txt @@ -7,6 +7,8 @@ Andrea Mucignat Andrew Andrianov [necromant] Andrey Yurovsky Andy Isaacson +Andreas Sandberg [andysan] +Antoine Faure [antoinefaure] Anton [Ant-ON] Áron Radics A. Sheaff @@ -24,6 +26,7 @@ Chris Samuelson Christian Deussen [nullsub] Christophe Levantis Craig Lilley +Crest [Crest] Dan Dev Dan Hepler Daniel Campoverde [alx741] diff --git a/doc/compiling.md b/doc/compiling.md index eef207f95..0931c278a 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -7,7 +7,7 @@ On Windows users should ensure that the following software is installed: - `git` (_optional, but recommended_) -- `cmake` (3.17.0 or later) +- `cmake` - `MinGW-w64` (7.0.0 or later) with GCC toolchain 8.1.0 ### Installation @@ -95,7 +95,7 @@ Install the following packages from your package repository: - `git` - `gcc` or `clang` or `mingw32-gcc` or `mingw64-gcc` (C-compiler; very likely gcc is already present) - `build-essential` (on Debian based distros (Debian, Ubuntu)) -- `cmake` (3.4.2 or later, use the latest version available from the repository) +- `cmake` - `rpm` (on Debian based distros (Debian, Ubuntu), needed for package build with `make package`) - `libusb-1.0` - `libusb-1.0-0-dev` (development headers for building) diff --git a/doc/version_support.md b/doc/version_support.md index 4eeb5074a..d7ba5c102 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -1,97 +1,104 @@ -_Source:_ pkgs.org - [libusb](https://pkgs.org/search/?q=libusb); [cmake](https://pkgs.org/search/?q=cmake); [gtk](https://pkgs.org/search/?q=gtk) (as of May 2021) +_Source:_ [pkgs.org](https://pkgs.org/search) - libusb, cmake, gtk, libgtk) (as of Jan 2022) ## Supported Operating Systems ### Microsoft Windows -On Windows users should ensure that cmake 3.20.2 or any later version is installed.
      -Up on compiling c-make will **automatically** download and install the latest compatible version of `libusb` (1.0.23 at the time of writing). +On Windows users should ensure that cmake **3.10.2** or any later version is installed.
      +Up on compiling c-make will **automatically** download and install the latest compatible version of `libusb`. - Windows 10 - Windows 8.1 ### Apple macOS -| Package Repository | libusb
      version | cmake
      version | gtk-3
      version | Supported macOS versions | -| ------------------ | ------------------- | ------------------ | ------------------ | ------------------------ | -| homebrew | 1.0.24 | 3.20.2 | 3.24.29
      gtk+3 | 10.9 - 11.x | -| MacPorts | 1.0.24 | 3.20.2 | 3.24.29
      gtk3 | 10.4 - 11.x | +| Package Repository | libusb | cmake | gtk-3-dev | Supported macOS versions | +| ------------------ | ------ | ------ | ------------------ | ------------------------ | +| homebrew | 1.0.24 | 3.22.1 | 3.24.30
      gtk+3 | **10.10 - 12.x** | +| MacPorts | 1.0.24 | 3.22.1 | 3.24.31
      gtk3 | **10.4 - 12.x** | NOTE: In order to use a STLINK/V1 programmer on macOS, version 10.15 is required. ### Linux-/Unix-based: -| Operating System | libusb | cmake | gtk-3 | Notes | -| ------------------------- | -------------------------------- | --------- | ----------- | ------------------------ | -| Debian Sid | 1.0.24 | 3.18.4 | 3.24.24 | | -| Debian 11 (Bullseye) | 1.0.24 | 3.18.4 | 3.24.24 | | -| Debian 10 (Buster) | 1.0.**22** | 3.13.4 | 3.24.**5** | | -| Debian 9 (Stretch) | 1.0.**21** | **3.7.2** | **3.22.11** | End of Support: Jun 2022 | -| | | | | | -| Ubuntu 21.04 (Hirsute) | 1.0.24 | 3.18.4 | 3.24.25 | End of Support: Jan 2022 | -| Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.16.3 | 3.24.**18** | | -| Ubuntu 18.04 LTS (Bionic) | 1.0.**21** | 3.10.2 | **3.22.30** | End of Support: Apr 2023 | -| | | | | | -| Fedora Rawhide [x64] | 1.0.24 (`libusbx`) | 3.20.2 | 3.24.29 | | -| Fedora 34 [x64] | 1.0.24 (`libusbx`) | 3.19.7 | 3.24.28 | | -| Fedora 33 [x64] | 1.0.23 (`libusbx`) | 3.18.3 | 3.24.23 | | -| | | | | | -| openSUSE Tumbleweed [x64] | 1.0.24 | 3.20.1 | 3.24.29 | | -| openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.17.0 | 3.24.20 | | -| openSUSE Leap 15.2 [x64] | 1.0.**21** | 3.17.0 | 3.24.**14** | End of Support: Dec 2021 | -| | | | | | -| Alpine 3.14 | 1.0.24 | 3.20.3 | 4.2.1 | | -| Alpine 3.13 | 1.0.24 | 3.18.4 | 3.24.23 | End of Support: Nov 2022 | -| Alpine 3.12 | 1.0.23 | 3.17.2 | 3.24.22 | End of Support: May 2022 | -| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.**13** | End of Support: Nov 2021 | -| | | | | | -| FreeBSD 13.x | 1.0.**16 - 18** (API 0x01000102) | 3.20.2 | 3.24.27 | | -| FreeBSD 12.x | 1.0.**16 - 18** (API 0x01000102) | 3.19.6 | 3.24.27 | | -| FreeBSD 11.x | 1.0.**16 - 18** (API 0x01000102) | 3.15.5 | 3.24.27 | End of Support: Sep 2021 | -| | | | | | -| Arch Linux | 1.0.24 | 3.20.2 | 3.24.29 | | -| KaOS [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | -| Mageia Cauldron | 1.0.24 | 3.20.2 | 3.24.29 | | -| OpenMandriva Cooker | 1.0.24 | 3.20.2 | 3.24.29 | | -| PCLinuxOS [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | -| Slackware Current | 1.0.24 | 3.20.2 | 3.24.28 | | -| Solus [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | -| ALT Linux Sisyphus | 1.0.24 | 3.19.7 | 3.24.29 | | -| NetBSD 9.x | 1.0.24 | 3.19.7 | 3.24.27 | | -| NetBSD 8.x | 1.0.24 | 3.19.7 | 3.24.27 | | -| OpenMandriva Lx 4.2 | 1.0.24 | 3.19.3 | 3.24.24 | | -| Mageia 8 | 1.0.24 | 3.19.2 | 3.24.24 | End of Support: Aug 2022 | -| CentOS 8 Stream [x64] | 1.0.23 (`libusbx`) | 3.18.2 | **3.22.30** | | -| Adélie 1.0 | 1.0.23 | 3.16.4 | 3.24.23 | | -| ALT Linux P9 | 1.0.**22** | 3.16.3 | 3.24.**11** | | -| AlmaLinux 8 | 1.0.23 (`libusbx`) | 3.11.4 | 3.24.32 | | -| CentOS 8 [x64] | 1.0.23 (`libusbx`) | 3.11.4 | **3.22.30** | End of Support: Dec 2021 | +| Operating System | libusb | cmake | libgtk-dev | Notes | +| ------------------------- | ------------------------------ | ---------- | ----------- | ------------------------ | +| Debian Sid | 1.0.24 | 3.22.1 | 3.24.31 | | +| Debian 11 (Bullseye) | 1.0.24 | 3.18.4 | 3.24.24 | | +| Debian 10 (Buster) | 1.0.**22** | **3.13.4** | 3.24.**5** | | +| | | | | | +| Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.16.3 | 3.24.**18** | | +| Ubuntu 18.04 LTS (Bionic) | 1.0.**21** | **3.10.2** | 3.**22.30** | End of Support: Apr 2023 | +| | | | | | +| Fedora Rawhide [x64] | 1.0.24 | 3.22.3 | 3.24.31 | | +| Fedora 35 [x64] | 1.0.24 | 3.21.3 | 3.24.30 | | +| Fedora 34 [x64] | 1.0.24 (`libusbx`) | 3.19.7 | 3.24.28 | | +| | | | | | +| openSUSE Tumbleweed [x64] | 1.0.24 | 3.22.1 | 3.24.31 | | +| openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.17.0 | 3.24.20 | End of Support: Dec 2022 | +| | | | | | +| Alpine 3.15 | 1.0.24 | 3.21.3 | 3.24.30 | | +| Alpine 3.14 | 1.0.24 | 3.20.3 | 3.24.28 | | +| Alpine 3.13 | 1.0.24 | 3.18.4 | 3.24.23 | End of Support: Nov 2022 | +| Alpine 3.12 | 1.0.23 | 3.17.2 | 3.24.22 | End of Support: May 2022 | +| | | | | | +| FreeBSD 13.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | +| FreeBSD 12.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | +| | | | | | +| NetBSD 9.x | 1.0.24 | 3.21.2 | 3.24.30 | | +| NetBSD 8.x | 1.0.24 | 3.19.7 | 3.24.27 | | +| | | | | | +| CentOS 9 Stream [x64] | 1.0.24 (`libusbx`) | 3.20.3 | 3.24.30 | | +| CentOS 8 Stream [x64] | 1.0.23 (`libusbx`) | 3.20.2 | 3.**22.30** | | +| | | | | | +| ALT Linux Sisyphus | 1.0.24 | 3.22.1 | 3.24.31 | | +| ALT Linux P10 | 1.0.24 | 3.20.5 | 3.24.31 | | +| ALT Linux P9 | 1.0.**22** | 3.16.3 | 3.24.29 | | +| | | | | | +| OpenMandriva Rolling | 1.0.24 | 3.22.1 | 3.24.31 | | +| OpenMandriva Cooker | 1.0.24 | 3.22.1 | 3.24.31 | | +| OpenMandriva Lx 4.2 | 1.0.24 | 3.19.3 | 3.24.24 | | +| | | | | | +| Arch Linux | 1.0.24 | 3.22.1 | - | | +| KaOS [x64] | 1.0.24 | 3.22.1 | 3.24.31 | | +| Mageia Cauldron | 1.0.24 | 3.22.1 | 3.24.31 | | +| PCLinuxOS [x64] | ? | 3.22.1 | 3.24.31 | | +| Solus [x64] | 1.0.24 | 3.22.1 | 3.24.30 | | +| Void Linux | 1.0.24 | 3.22.1 | 3.24.31 | | +| Slackware Current | 1.0.24 | 3.21.4 | 3.24.31 | | +| AlmaLinux 8 | 1.0.23 (`libusbx`) | 3.20.2 | 3.**22.30** | | +| Rocky Linux 8 [x64] | 1.0.23 | 3.20.2 | 3.**22.30** | | +| Mageia 8 | 1.0.24 | 3.19.2 | 3.24.24 | End of Support: Aug 2022 | +| Adélie 1.0 | 1.0.23 | 3.16.4 | 3.24.23 | | ## Unsupported Operating Systems (as of Release v1.7.1) Systems with highlighted versions remain compatible with this toolset. -| Operating System | libusb | cmake | End of
      OS-Support | -| ------------------------- | ---------------------- | ---------- | ---------------------- | -| Fedora 32 [x64] | **1.0.23** (`libusbx`) | **3.17.0** | May 2021 | -| Ubuntu 20.10 (Groovy) | **1.0.23** | **3.16.3** | Jul 2021 | -| NetBSD 7.x | **1.0.22** | **3.16.1** | Jun 2020 | -| Alpine 3.10 | **1.0.22** | **3.14.5** | May 2021 | -| Fedora 31 [x64] | **1.0.22** (`libusbx`) | **3.14.5** | Nov 2020 | -| Mageia 7.1 | **1.0.22** | **3.14.3** | Jun 2021 | -| Fedora 30 | **1.0.22** (`libusbx`) | **3.14.2** | May 2020 | -| Ubuntu 19.10 (Eoan) | **1.0.23** | **3.13.4** | Jul 2020 | -| Alpine 3.9 | **1.0.22** | **3.13.0** | Jan 2021 | -| openSUSE Leap 15.1 [x64] | **1.0.21** | **3.10.2** | Jan 2021 | -| Slackware 14.2 | 1.0.20 | 3.5.2 | | -| Ubuntu 16.04 LTS (Xenial) | 1.0.20 | 3.5.1 | Apr 2021 | -| OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | | -| Debian 8 (Jessie) | 1.0.19 | 3.0.2 | Jun 2020 | -| CentOS 7 [x64] | 1.0.21 (`libusbx`) | 2.8.12.2 | Jun 2024 | -| Ubuntu 14.04 LTS (Trusty) | 1.0.17 | 2.8.12.2 | Apr 2019 | -| CentOS 6 | 1.0.9 (`libusbx`) | 2.8.12.2 | Nov 2020 | -| Slackware 14.1 | 1.0.9 | 2.8.12 | | -| Slackware 14.0 | 1.0.9 | 2.8.8 | | +| Operating System | libusb | cmake | End of
      OS-Support | +| ------------------------ | ------------------------------ | ---------- | ---------------------- | +| CentOS 8 [x64] | 1.0.**23** (`libusbx`) | 3.**20.3** | Dec 2021 | +| Ubuntu 21.04 (Hirsute) | 1.0.**24** | 3.**18.4** | Jan 2022 | +| Fedora 33 [x64] | 1.0.**23** (`libusbx`) | 3.**18.3** | Nov 2021 | +| Fedora 32 [x64] | 1.0.**23** (`libusbx`) | 3.**17.0** | May 2021 | +| openSUSE Leap 15.2 [x64] | 1.0.**21** | 3.**17.0** | Dec 2021 | +| Ubuntu 20.10 (Groovy) | 1.0.**23** | 3.**16.3** | Jul 2021 | +| NetBSD 7.x | 1.0.**22** | 3.**16.1** | Jun 2020 | +| Alpine 3.11 | 1.0.**23** | 3.**15.5** | Nov 2021 | +| FreeBSD 11.x | 1.0.**16-18** (API 0x01000102) | 3.**15.5** | Sep 2021 | +| Alpine 3.10 | 1.0.**22** | 3.**14.5** | May 2021 | +| Fedora 31 [x64] | 1.0.**22**(`libusbx`) | 3.**14.5** | Nov 2020 | +| Mageia 7.1 | 1.0.**22** | 3.**14.3** | Jun 2021 | +| Fedora 30 | 1.0.**22**(`libusbx`) | 3.**14.2** | May 2020 | +| Ubuntu 19.10 (Eoan) | 1.0.**23** | 3.**13.4** | Jul 2020 | +| Alpine 3.9 | 1.0.**22** | 3.**13.0** | Jan 2021 | +| openSUSE Leap 15.1 [x64] | 1.0.**21** | 3.**10.2** | Jan 2021 | +| Debian 9 (Stretch) | 1.0.**21** | 3.7.2 | Jun 2022 | +| Slackware 14.2 | 1.0.20 | 3.5.2 | | +| OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | | +| CentOS 7 [x64] | 1.0.**21** (`libusbx`) | 2.8.12.2 | Jun 2024 | +| Slackware 14.1 | 1.0.9 | 2.8.12 | | +| Slackware 14.0 | 1.0.9 | 2.8.8 | | _All other operating systems which are not listed are unsupported._ From 75092952226682788c394e12c2b90ec121b2054a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 16 Jan 2022 19:31:22 +0100 Subject: [PATCH 1287/1435] [refactoring] Clean-up for headers & defines - Removed additional extern "C" linkage specs - Removed commented sections - Moved out further device specific defines - Renamed defines STM32_CHIP_ID_* --- config/chips/F03x.chip | 2 +- config/chips/F04x.chip | 2 +- config/chips/F05x.chip | 2 +- config/chips/F07x.chip | 2 +- config/chips/F09x.chip | 2 +- config/chips/F1xx_CL.chip | 2 +- config/chips/F1xx_HD.chip | 2 +- config/chips/F1xx_LD.chip | 2 +- config/chips/F1xx_MD.chip | 2 +- config/chips/F1xx_VL_HD.chip | 2 +- config/chips/F1xx_VL_MD_LD.chip | 2 +- config/chips/F1xx_XLD.chip | 2 +- config/chips/F2xx.chip | 2 +- config/chips/F301_F302_F318.chip | 2 +- config/chips/F302_F303_F358.chip | 2 +- config/chips/F302_F303_F398_HD.chip | 2 +- config/chips/F303_F328_F334.chip | 2 +- config/chips/F37x.chip | 2 +- config/chips/F401xB_xC.chip | 2 +- config/chips/F401xD_xE.chip | 2 +- config/chips/F410.chip | 2 +- config/chips/F411xC_xE.chip | 2 +- config/chips/F412.chip | 2 +- config/chips/F413_F423.chip | 2 +- config/chips/F42x_F43x.chip | 2 +- config/chips/F446.chip | 2 +- config/chips/F46x_F47x.chip | 2 +- config/chips/F4x5_F4x7.chip | 2 +- config/chips/F72x_F73x.chip | 2 +- config/chips/F74x_F75x.chip | 2 +- config/chips/F76x_F77x.chip | 2 +- config/chips/G03x_G04x.chip | 2 +- config/chips/G05x_G06x.chip | 2 +- config/chips/G07x_G08x.chip | 2 +- config/chips/G0Bx_G0Cx.chip | 2 +- config/chips/G43x_G44x.chip | 2 +- config/chips/G47x_G48x.chip | 2 +- config/chips/G49x_G4Ax.chip | 2 +- config/chips/H72x_H73x.chip | 2 +- config/chips/H74x_H75x.chip | 2 +- config/chips/H7Ax_H7Bx.chip | 2 +- config/chips/L0xxx_Cat_1.chip | 2 +- config/chips/L0xxx_Cat_2.chip | 2 +- config/chips/L0xxx_Cat_3.chip | 2 +- config/chips/L0xxx_Cat_5.chip | 2 +- config/chips/L1xx_Cat_1.chip | 2 +- config/chips/L1xx_Cat_2.chip | 2 +- config/chips/L1xx_Cat_3.chip | 2 +- config/chips/L1xx_Cat_4.chip | 2 +- config/chips/L1xx_Cat_5.chip | 2 +- config/chips/L41x_L42x.chip | 2 +- config/chips/L43x_L44x.chip | 2 +- config/chips/L45x_L46x.chip | 2 +- config/chips/L47x_L48x.chip | 2 +- config/chips/L496x_L4A6x.chip | 2 +- config/chips/L4Px.chip | 2 +- config/chips/L4Rx.chip | 2 +- config/chips/WBx0_WBx5.chip | 2 +- config/chips/WLx5.chip | 2 +- inc/stlink.h | 17 - inc/stm32.h | 514 ++++++++++++++++++++++++---- src/common.c | 473 +++---------------------- src/st-util/gdb-server.c | 24 +- src/stlink-lib/chipid.c | 74 ---- src/stlink-lib/chipid.h | 6 - src/stlink-lib/flash_loader.c | 92 ++--- src/stlink-lib/flash_loader.h | 6 - src/stlink-lib/sg.h | 6 - src/stlink-lib/usb.h | 6 - src/win32/mmap.h | 6 - src/win32/sys_time.h | 7 - 71 files changed, 612 insertions(+), 737 deletions(-) diff --git a/config/chips/F03x.chip b/config/chips/F03x.chip index 3b4ff2a74..c0a6e5200 100644 --- a/config/chips/F03x.chip +++ b/config/chips/F03x.chip @@ -2,7 +2,7 @@ # dev_type STM32F03x ref_manual_id 0091 -chip_id 0x444 // STM32_CHIPID_STM32_F0xx_SMALL +chip_id 0x444 // STM32_CHIPID_F0xx_SMALL flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x400 // 1 KB diff --git a/config/chips/F04x.chip b/config/chips/F04x.chip index 267c93765..9b2ee5586 100644 --- a/config/chips/F04x.chip +++ b/config/chips/F04x.chip @@ -2,7 +2,7 @@ # dev_type STM32F04x ref_manual_id 0091 -chip_id 0x445 // STM32_CHIPID_STM32_F04 +chip_id 0x445 // STM32_CHIPID_F04 flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x400 // 1 KB diff --git a/config/chips/F05x.chip b/config/chips/F05x.chip index dc511e1a2..c32ba0b46 100644 --- a/config/chips/F05x.chip +++ b/config/chips/F05x.chip @@ -2,7 +2,7 @@ # dev_type STM32F05x ref_manual_id 0091 -chip_id 0x440 // STM32_CHIPID_STM32_F0 +chip_id 0x440 // STM32_CHIPID_F0 flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x400 // 1 KB diff --git a/config/chips/F07x.chip b/config/chips/F07x.chip index b12ef1bab..5ba832058 100644 --- a/config/chips/F07x.chip +++ b/config/chips/F07x.chip @@ -2,7 +2,7 @@ # dev_type STM32F07x ref_manual_id 0091 -chip_id 0x448 // STM32_CHIPID_STM32_F0_CAN +chip_id 0x448 // STM32_CHIPID_F0_CAN flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F09x.chip b/config/chips/F09x.chip index 97f1a1a75..ca987123d 100644 --- a/config/chips/F09x.chip +++ b/config/chips/F09x.chip @@ -2,7 +2,7 @@ # dev_type STM32F09x ref_manual_id 0091 -chip_id 0x442 // STM32_CHIPID_STM32_F09x +chip_id 0x442 // STM32_CHIPID_F09x flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F1xx_CL.chip b/config/chips/F1xx_CL.chip index dd316dca3..0f56362f0 100644 --- a/config/chips/F1xx_CL.chip +++ b/config/chips/F1xx_CL.chip @@ -2,7 +2,7 @@ # dev_type STM32F1xx_CL ref_manual_id 0008 -chip_id 0x418 // STM32_CHIPID_STM32_F1_CONN +chip_id 0x418 // STM32_CHIPID_F1_CONN flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F1xx_HD.chip b/config/chips/F1xx_HD.chip index 696b284ba..2af8582e6 100644 --- a/config/chips/F1xx_HD.chip +++ b/config/chips/F1xx_HD.chip @@ -2,7 +2,7 @@ # dev_type F1xx_HD ref_manual_id 0008 -chip_id 0x414 // STM32_CHIPID_STM32_F1_HD +chip_id 0x414 // STM32_CHIPID_F1_HD flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F1xx_LD.chip b/config/chips/F1xx_LD.chip index 898af4c8c..ffd34fd4a 100644 --- a/config/chips/F1xx_LD.chip +++ b/config/chips/F1xx_LD.chip @@ -2,7 +2,7 @@ # dev_type STM32F1xx_LD ref_manual_id 0008 -chip_id 0x412 // STM32_CHIPID_STM32_F1_LD +chip_id 0x412 // STM32_CHIPID_F1_LD flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x400 // 1 KB diff --git a/config/chips/F1xx_MD.chip b/config/chips/F1xx_MD.chip index a611f3f2d..f27a7a062 100644 --- a/config/chips/F1xx_MD.chip +++ b/config/chips/F1xx_MD.chip @@ -2,7 +2,7 @@ # dev_type STM32F1xx_MD ref_manual_id 0008 -chip_id 0x410 // STM32_CHIPID_STM32_F1_MD +chip_id 0x410 // STM32_CHIPID_F1_MD flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x400 // 1 KB diff --git a/config/chips/F1xx_VL_HD.chip b/config/chips/F1xx_VL_HD.chip index d59fa4814..4f2566949 100644 --- a/config/chips/F1xx_VL_HD.chip +++ b/config/chips/F1xx_VL_HD.chip @@ -2,7 +2,7 @@ # dev_type STM32F1xx_VL_HD ref_manual_id 0041 -chip_id 0x428 // STM32_CHIPID_STM32_F1_VL_HD +chip_id 0x428 // STM32_CHIPID_F1_VL_HD flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F1xx_VL_MD_LD.chip b/config/chips/F1xx_VL_MD_LD.chip index aac2244fd..1705bc8e3 100644 --- a/config/chips/F1xx_VL_MD_LD.chip +++ b/config/chips/F1xx_VL_MD_LD.chip @@ -2,7 +2,7 @@ # dev_type STM32F1xx_VL_MD_LD ref_manual_id 0041 -chip_id 0x420 // STM32_CHIPID_STM32_F1_VL_MD_LD +chip_id 0x420 // STM32_CHIPID_F1_VL_MD_LD flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x400 // 1 KB diff --git a/config/chips/F1xx_XLD.chip b/config/chips/F1xx_XLD.chip index 7627dd883..37c900f28 100644 --- a/config/chips/F1xx_XLD.chip +++ b/config/chips/F1xx_XLD.chip @@ -2,7 +2,7 @@ # dev_type STM32F1xx_XLD ref_manual_id 0008 -chip_id 0x430 // STM32_CHIPID_STM32_F1_XLD +chip_id 0x430 // STM32_CHIPID_F1_XLD flash_type 2 // STM32_FLASH_TYPE_F1_XL flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F2xx.chip b/config/chips/F2xx.chip index 5e6aac5a0..314df7d6d 100644 --- a/config/chips/F2xx.chip +++ b/config/chips/F2xx.chip @@ -2,7 +2,7 @@ # dev_type STM32F2xx ref_manual_id 0033 -chip_id 0x411 // STM32_CHIPID_STM32_F2 +chip_id 0x411 // STM32_CHIPID_F2 flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x20000 // 128 KB diff --git a/config/chips/F301_F302_F318.chip b/config/chips/F301_F302_F318.chip index 3a3d8bb45..f620364b2 100644 --- a/config/chips/F301_F302_F318.chip +++ b/config/chips/F301_F302_F318.chip @@ -2,7 +2,7 @@ # dev_type STM32F301_F302_F318 ref_manual_id 0365 // also RM0366 -chip_id 0x439 // STM32_CHIPID_STM32_F3xx_SMALL +chip_id 0x439 // STM32_CHIPID_F3xx_SMALL flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F302_F303_F358.chip b/config/chips/F302_F303_F358.chip index 922387292..e48370159 100644 --- a/config/chips/F302_F303_F358.chip +++ b/config/chips/F302_F303_F358.chip @@ -2,7 +2,7 @@ # dev_type STM32F302_F303_358 ref_manual_id 0365 // also RM0316 -chip_id 0x422 // STM32_CHIPID_STM32_F3 +chip_id 0x422 // STM32_CHIPID_F3 flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F302_F303_F398_HD.chip b/config/chips/F302_F303_F398_HD.chip index 44cec8a6d..181fdfa72 100644 --- a/config/chips/F302_F303_F398_HD.chip +++ b/config/chips/F302_F303_F398_HD.chip @@ -2,7 +2,7 @@ # dev_type STM32F302_F303_F398_HD ref_manual_id 0365 // also RM0316 (Rev 5) -chip_id 0x446 // STM32_CHIPID_STM32_F303_HD +chip_id 0x446 // STM32_CHIPID_F303_HD flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F303_F328_F334.chip b/config/chips/F303_F328_F334.chip index fb77e3117..069de07fb 100644 --- a/config/chips/F303_F328_F334.chip +++ b/config/chips/F303_F328_F334.chip @@ -2,7 +2,7 @@ # dev_type STM32F303_F328_F334 ref_manual_id 0364 // also RM0316 -chip_id 0x438 // STM32_CHIPID_STM32_F334 +chip_id 0x438 // STM32_CHIPID_F334 flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F37x.chip b/config/chips/F37x.chip index 5363da8fa..dfe59af0f 100644 --- a/config/chips/F37x.chip +++ b/config/chips/F37x.chip @@ -2,7 +2,7 @@ # dev_type STM32F37x ref_manual_id 0313 -chip_id 0x432 // STM32_CHIPID_STM32_F37x +chip_id 0x432 // STM32_CHIPID_F37x flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F401xB_xC.chip b/config/chips/F401xB_xC.chip index e75b27d09..d961e82b0 100644 --- a/config/chips/F401xB_xC.chip +++ b/config/chips/F401xB_xC.chip @@ -2,7 +2,7 @@ # dev_type STM32F401xB_xC ref_manual_id 0368 -chip_id 0x423 // STM32_CHIPID_STM32_F4_LP +chip_id 0x423 // STM32_CHIPID_F4_LP flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F401xD_xE.chip b/config/chips/F401xD_xE.chip index 022d5072a..1b58cb5ad 100644 --- a/config/chips/F401xD_xE.chip +++ b/config/chips/F401xD_xE.chip @@ -2,7 +2,7 @@ # dev_type STM32F401xD_xE ref_manual_id 0368 -chip_id 0x433 // STM32_CHIPID_STM32_F4_DE +chip_id 0x433 // STM32_CHIPID_F4_DE flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F410.chip b/config/chips/F410.chip index 84c9c00bf..55dbb749d 100644 --- a/config/chips/F410.chip +++ b/config/chips/F410.chip @@ -2,7 +2,7 @@ # dev_type STM32F410 ref_manual_id 0401 -chip_id 0x458 // STM32_CHIPID_STM32_F410 +chip_id 0x458 // STM32_CHIPID_F410 flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F411xC_xE.chip b/config/chips/F411xC_xE.chip index d028a874c..51081d338 100644 --- a/config/chips/F411xC_xE.chip +++ b/config/chips/F411xC_xE.chip @@ -2,7 +2,7 @@ # dev_type STM32F411xC_xE ref_manual_id 0383 -chip_id 0x431 // STM32_CHIPID_STM32_F411xx +chip_id 0x431 // STM32_CHIPID_F411xx flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F412.chip b/config/chips/F412.chip index b4c1cb418..6e7aefd19 100644 --- a/config/chips/F412.chip +++ b/config/chips/F412.chip @@ -2,7 +2,7 @@ # dev_type STM32F412 ref_manual_id 0402 -chip_id 0x441 // STM32_CHIPID_STM32_F412 +chip_id 0x441 // STM32_CHIPID_F412 flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F413_F423.chip b/config/chips/F413_F423.chip index f042bce76..3a865d304 100644 --- a/config/chips/F413_F423.chip +++ b/config/chips/F413_F423.chip @@ -2,7 +2,7 @@ # dev_type STM32F413_F423 ref_manual_id 0430 // RM0430 (Rev 2) -chip_id 0x463 // STM32_CHIPID_STM32_F413 +chip_id 0x463 // STM32_CHIPID_F413 flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F42x_F43x.chip b/config/chips/F42x_F43x.chip index 69aff7c88..64f459064 100644 --- a/config/chips/F42x_F43x.chip +++ b/config/chips/F42x_F43x.chip @@ -2,7 +2,7 @@ # dev_type STM32F42x_F43x ref_manual_id 0090 // RM0090 (Rev. 2) -chip_id 0x463 // STM32_CHIPID_STM32_F4_HD +chip_id 0x463 // STM32_CHIPID_F4_HD flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F446.chip b/config/chips/F446.chip index 5fa2edbcb..51ee52517 100644 --- a/config/chips/F446.chip +++ b/config/chips/F446.chip @@ -2,7 +2,7 @@ # dev_type STM32F446 ref_manual_id 0390 -chip_id 0x421 // STM32_CHIPID_STM32_F446 +chip_id 0x421 // STM32_CHIPID_F446 flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x20000 // 128 KB diff --git a/config/chips/F46x_F47x.chip b/config/chips/F46x_F47x.chip index e8364ead5..4d3931091 100644 --- a/config/chips/F46x_F47x.chip +++ b/config/chips/F46x_F47x.chip @@ -2,7 +2,7 @@ # dev_type STM32F46x_F47x ref_manual_id 0090 // RM0090 (Rev. 2) -chip_id 0x434 // STM32_CHIPID_STM32_F4_DSI +chip_id 0x434 // STM32_CHIPID_F4_DSI flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F4x5_F4x7.chip b/config/chips/F4x5_F4x7.chip index e78b552c4..f65281272 100644 --- a/config/chips/F4x5_F4x7.chip +++ b/config/chips/F4x5_F4x7.chip @@ -2,7 +2,7 @@ # dev_type STM32F4x5_F4x7 ref_manual_id 0090 // RM0090 (Rev. 2) -chip_id 0x413 // STM32_CHIPID_STM32_F4 +chip_id 0x413 // STM32_CHIPID_F4 flash_type 3 // STM32_FLASH_TYPE_F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/config/chips/F72x_F73x.chip b/config/chips/F72x_F73x.chip index 5e1131d2e..acd411bed 100644 --- a/config/chips/F72x_F73x.chip +++ b/config/chips/F72x_F73x.chip @@ -2,7 +2,7 @@ # dev_type STM32F72x_F73x ref_manual_id 0431 -chip_id 0x452 // STM32_CHIPID_STM32_F72xxx +chip_id 0x452 // STM32_CHIPID_F72xxx flash_type 4 // STM32_FLASH_TYPE_F7 flash_size_reg 0x1ff07a22 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F74x_F75x.chip b/config/chips/F74x_F75x.chip index 391ae124d..e081da39d 100644 --- a/config/chips/F74x_F75x.chip +++ b/config/chips/F74x_F75x.chip @@ -2,7 +2,7 @@ # dev_type STM32F74x_F75x ref_manual_id 0385 -chip_id 0x449 // STM32_CHIPID_STM32_F7 +chip_id 0x449 // STM32_CHIPID_F7 flash_type 4 // STM32_FLASH_TYPE_F7 flash_size_reg 0x1ff0f442 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/F76x_F77x.chip b/config/chips/F76x_F77x.chip index bb87dce7a..c6d04ff78 100644 --- a/config/chips/F76x_F77x.chip +++ b/config/chips/F76x_F77x.chip @@ -2,7 +2,7 @@ # dev_type STM32F76x_F77x ref_manual_id 0410 -chip_id 0x451 // STM32_CHIPID_STM32_F76xxx +chip_id 0x451 // STM32_CHIPID_F76xxx flash_type 4 // STM32_FLASH_TYPE_F7 flash_size_reg 0x1ff0f442 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/G03x_G04x.chip b/config/chips/G03x_G04x.chip index 4a7e11fcd..fd6dc3bcf 100644 --- a/config/chips/G03x_G04x.chip +++ b/config/chips/G03x_G04x.chip @@ -2,7 +2,7 @@ # dev_type STM32G03x_G04x ref_manual_id 0444 // also RM454 -chip_id 0x466 // STM32_CHIPID_STM32_G0_CAT1 +chip_id 0x466 // STM32_CHIPID_G0_CAT1 flash_type 5 // STM32_FLASH_TYPE_G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/G05x_G06x.chip b/config/chips/G05x_G06x.chip index 81f97b58d..ce5e52de4 100644 --- a/config/chips/G05x_G06x.chip +++ b/config/chips/G05x_G06x.chip @@ -2,7 +2,7 @@ # dev_type STM32G05x_G06x ref_manual_id 0444 -chip_id 0x456 // STM32_CHIPID_STM32_G0_CAT4 +chip_id 0x456 // STM32_CHIPID_G0_CAT4 flash_type 5 // STM32_FLASH_TYPE_G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/G07x_G08x.chip b/config/chips/G07x_G08x.chip index cac804a78..7a10fc052 100644 --- a/config/chips/G07x_G08x.chip +++ b/config/chips/G07x_G08x.chip @@ -2,7 +2,7 @@ # dev_type STM32G07x_G08x ref_manual_id 0444 -chip_id 0x460 // STM32_CHIPID_STM32_G0_CAT2 +chip_id 0x460 // STM32_CHIPID_G0_CAT2 flash_type 5 // STM32_FLASH_TYPE_G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/G0Bx_G0Cx.chip b/config/chips/G0Bx_G0Cx.chip index 845cf8280..6ab8ca55a 100644 --- a/config/chips/G0Bx_G0Cx.chip +++ b/config/chips/G0Bx_G0Cx.chip @@ -2,7 +2,7 @@ # dev_type STM32G0Bx_G0Cx ref_manual_id 0444 -chip_id 0x467 // STM32_CHIPID_STM32_G0_CAT3 +chip_id 0x467 // STM32_CHIPID_G0_CAT3 flash_type 5 // STM32_FLASH_TYPE_G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/G43x_G44x.chip b/config/chips/G43x_G44x.chip index 6b19d4fb4..a7eb86d34 100644 --- a/config/chips/G43x_G44x.chip +++ b/config/chips/G43x_G44x.chip @@ -2,7 +2,7 @@ # dev_type STM32G43x_G44x ref_manual_id 0440 -chip_id 0x468 // STM32_CHIPID_STM32_G4_CAT2 +chip_id 0x468 // STM32_CHIPID_G4_CAT2 flash_type 6 // STM32_FLASH_TYPE_G4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/G47x_G48x.chip b/config/chips/G47x_G48x.chip index d3330da59..1b2b386fd 100644 --- a/config/chips/G47x_G48x.chip +++ b/config/chips/G47x_G48x.chip @@ -2,7 +2,7 @@ # dev_type STM32G47x_G48x ref_manual_id 0440 -chip_id 0x469 // STM32_CHIPID_STM32_G4_CAT3 +chip_id 0x469 // STM32_CHIPID_G4_CAT3 flash_type 6 // STM32_FLASH_TYPE_G4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/G49x_G4Ax.chip b/config/chips/G49x_G4Ax.chip index a39237142..1defbfff8 100644 --- a/config/chips/G49x_G4Ax.chip +++ b/config/chips/G49x_G4Ax.chip @@ -2,7 +2,7 @@ # dev_type STM32G49x_G4Ax ref_manual_id 0440 -chip_id 0x479 // STM32_CHIPID_STM32_G4_CAT4 +chip_id 0x479 // STM32_CHIPID_G4_CAT4 flash_type 6 // STM32_FLASH_TYPE_G4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/H72x_H73x.chip b/config/chips/H72x_H73x.chip index 998aa9812..50925fdcd 100644 --- a/config/chips/H72x_H73x.chip +++ b/config/chips/H72x_H73x.chip @@ -2,7 +2,7 @@ # dev_type STM32H72x_H73x ref_manual_id 0468 -chip_id 0x483 // STM32_CHIPID_STM32_H72x +chip_id 0x483 // STM32_CHIPID_H72x flash_type 7 // STM32_FLASH_TYPE_H7 flash_size_reg 0x1ff1e880 flash_pagesize 0x20000 // 128 KB diff --git a/config/chips/H74x_H75x.chip b/config/chips/H74x_H75x.chip index 0bfea13a4..20bfcd2cb 100644 --- a/config/chips/H74x_H75x.chip +++ b/config/chips/H74x_H75x.chip @@ -2,7 +2,7 @@ # dev_type STM32H74x_H75x ref_manual_id 0433 -chip_id 0x450 // STM32_CHIPID_STM32_H74xxx +chip_id 0x450 // STM32_CHIPID_H74xxx flash_type 7 // STM32_FLASH_TYPE_H7 flash_size_reg 0x1ff1e880 flash_pagesize 0x20000 // 128 KB diff --git a/config/chips/H7Ax_H7Bx.chip b/config/chips/H7Ax_H7Bx.chip index 2e784193c..b31e4fb88 100644 --- a/config/chips/H7Ax_H7Bx.chip +++ b/config/chips/H7Ax_H7Bx.chip @@ -2,7 +2,7 @@ # dev_type STM32H7Ax_H7Bx ref_manual_id 0455 -chip_id 0x480 // STM32_CHIPID_STM32_H7Ax +chip_id 0x480 // STM32_CHIPID_H7Ax flash_type 7 // STM32_FLASH_TYPE_H7 flash_size_reg 0x08fff80c flash_pagesize 0x2000 // 8 KB diff --git a/config/chips/L0xxx_Cat_1.chip b/config/chips/L0xxx_Cat_1.chip index 4b108b4f4..d612143d5 100644 --- a/config/chips/L0xxx_Cat_1.chip +++ b/config/chips/L0xxx_Cat_1.chip @@ -2,7 +2,7 @@ # dev_type STM32L0xxx_Cat_1 ref_manual_id 0451 // also RM0377 -chip_id 0x457 // STM32_CHIPID_STM32_L011 +chip_id 0x457 // STM32_CHIPID_L011 flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B diff --git a/config/chips/L0xxx_Cat_2.chip b/config/chips/L0xxx_Cat_2.chip index 5665e8df1..49d3e8b07 100644 --- a/config/chips/L0xxx_Cat_2.chip +++ b/config/chips/L0xxx_Cat_2.chip @@ -2,7 +2,7 @@ # dev_type STM32L0xxx_Cat_2 ref_manual_id 0451 // also RM0377 -chip_id 0x425 // STM32_CHIPID_STM32_L0_CAT2 +chip_id 0x425 // STM32_CHIPID_L0_CAT2 flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B diff --git a/config/chips/L0xxx_Cat_3.chip b/config/chips/L0xxx_Cat_3.chip index e8cd7c685..c1b6c3bf4 100644 --- a/config/chips/L0xxx_Cat_3.chip +++ b/config/chips/L0xxx_Cat_3.chip @@ -2,7 +2,7 @@ # dev_type STM32L0xxx_Cat_3 ref_manual_id 0451 // also RM0367 & RM0377 -chip_id 0x417 // STM32_CHIPID_STM32_L0 +chip_id 0x417 // STM32_CHIPID_L0 flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B diff --git a/config/chips/L0xxx_Cat_5.chip b/config/chips/L0xxx_Cat_5.chip index 284057091..94e14dfe0 100644 --- a/config/chips/L0xxx_Cat_5.chip +++ b/config/chips/L0xxx_Cat_5.chip @@ -2,7 +2,7 @@ # dev_type STM32L0xxx_Cat_5 ref_manual_id 0451 // also RM0367 & RM0377 -chip_id 0x447 // STM32_CHIPID_STM32_L0_CAT5 +chip_id 0x447 // STM32_CHIPID_L0_CAT5 flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B diff --git a/config/chips/L1xx_Cat_1.chip b/config/chips/L1xx_Cat_1.chip index f6a11288f..16f2ff8c9 100644 --- a/config/chips/L1xx_Cat_1.chip +++ b/config/chips/L1xx_Cat_1.chip @@ -2,7 +2,7 @@ # dev_type STM32L1xx_Cat_1 ref_manual_id 0038 -chip_id 0x416 // STM32_CHIPID_STM32_L1_MD +chip_id 0x416 // STM32_CHIPID_L1_MD flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8004c flash_pagesize 0x100 // 128 B diff --git a/config/chips/L1xx_Cat_2.chip b/config/chips/L1xx_Cat_2.chip index c8c796111..82d7dfe44 100644 --- a/config/chips/L1xx_Cat_2.chip +++ b/config/chips/L1xx_Cat_2.chip @@ -2,7 +2,7 @@ # dev_type STM32L1xx_Cat_2 ref_manual_id 0038 -chip_id 0x429 // STM32_CHIPID_STM32_L1_CAT2 +chip_id 0x429 // STM32_CHIPID_L1_CAT2 flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff8004c flash_pagesize 0x100 // 128 B diff --git a/config/chips/L1xx_Cat_3.chip b/config/chips/L1xx_Cat_3.chip index f2615f952..2241e5bde 100644 --- a/config/chips/L1xx_Cat_3.chip +++ b/config/chips/L1xx_Cat_3.chip @@ -2,7 +2,7 @@ # dev_type STM32L1xx_Cat_3 ref_manual_id 0038 -chip_id 0x427 // STM32_CHIPID_STM32_L1_MD_PLUS +chip_id 0x427 // STM32_CHIPID_L1_MD_PLUS flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff800cc flash_pagesize 0x100 // 128 B diff --git a/config/chips/L1xx_Cat_4.chip b/config/chips/L1xx_Cat_4.chip index 6a1df1267..7933d7121 100644 --- a/config/chips/L1xx_Cat_4.chip +++ b/config/chips/L1xx_Cat_4.chip @@ -2,7 +2,7 @@ # dev_type STM32L1xx_Cat_4 ref_manual_id 0038 -chip_id 0x436 // STM32_CHIPID_STM32_L1_MD_PLUS_HD +chip_id 0x436 // STM32_CHIPID_L1_MD_PLUS_HD flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff800cc flash_pagesize 0x100 // 128 B diff --git a/config/chips/L1xx_Cat_5.chip b/config/chips/L1xx_Cat_5.chip index 4fccd99da..0e95e54e8 100644 --- a/config/chips/L1xx_Cat_5.chip +++ b/config/chips/L1xx_Cat_5.chip @@ -2,7 +2,7 @@ # dev_type STM32L1xx_Cat_5 ref_manual_id 0038 -chip_id 0x437 // STM32_CHIPID_STM32_L152_RE +chip_id 0x437 // STM32_CHIPID_L152_RE flash_type 8 // STM32_FLASH_TYPE_L0_L1 flash_size_reg 0x1ff800cc flash_pagesize 0x100 // 128 B diff --git a/config/chips/L41x_L42x.chip b/config/chips/L41x_L42x.chip index 40085d828..726645552 100644 --- a/config/chips/L41x_L42x.chip +++ b/config/chips/L41x_L42x.chip @@ -2,7 +2,7 @@ # dev_type STM32L41x_L42x ref_manual_id 0394 -chip_id 0x464 // STM32_CHIPID_STM32_L41x_L42x +chip_id 0x464 // STM32_CHIPID_L41x_L42x flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/L43x_L44x.chip b/config/chips/L43x_L44x.chip index 22045c372..baba13e55 100644 --- a/config/chips/L43x_L44x.chip +++ b/config/chips/L43x_L44x.chip @@ -2,7 +2,7 @@ # dev_type STM32L41x_L42x ref_manual_id 0392 -chip_id 0x435 // STM32_CHIPID_STM32_L43x_L44x +chip_id 0x435 // STM32_CHIPID_L43x_L44x flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/L45x_L46x.chip b/config/chips/L45x_L46x.chip index 99e9beca1..8886633e2 100644 --- a/config/chips/L45x_L46x.chip +++ b/config/chips/L45x_L46x.chip @@ -2,7 +2,7 @@ # dev_type STM32L45x_L46x ref_manual_id 0394 -chip_id 0x462 // STM32_CHIPID_STM32_L45x_L46x +chip_id 0x462 // STM32_CHIPID_L45x_L46x flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/L47x_L48x.chip b/config/chips/L47x_L48x.chip index 44e5282ce..df96ee2fb 100644 --- a/config/chips/L47x_L48x.chip +++ b/config/chips/L47x_L48x.chip @@ -2,7 +2,7 @@ # dev_type STM32L47x_L48x ref_manual_id 0351 -chip_id 0x415 // STM32_CHIPID_STM32_L4 +chip_id 0x415 // STM32_CHIPID_L4 flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/L496x_L4A6x.chip b/config/chips/L496x_L4A6x.chip index b983eb9eb..0f4bd285d 100644 --- a/config/chips/L496x_L4A6x.chip +++ b/config/chips/L496x_L4A6x.chip @@ -2,7 +2,7 @@ # dev_type STM32L496x_L4A6x ref_manual_id 0351 -chip_id 0x461 // STM32_CHIPID_STM32_L496x_L4A6x +chip_id 0x461 // STM32_CHIPID_L496x_L4A6x flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/config/chips/L4Px.chip b/config/chips/L4Px.chip index 41805c768..2d1a59806 100644 --- a/config/chips/L4Px.chip +++ b/config/chips/L4Px.chip @@ -2,7 +2,7 @@ # dev_type STM32L4Px ref_manual_id 0432 -chip_id 0x471 // STM32_CHIPID_STM32_L4PX +chip_id 0x471 // STM32_CHIPID_L4PX flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x1000 // 4 KB diff --git a/config/chips/L4Rx.chip b/config/chips/L4Rx.chip index d0495f083..f0593a97e 100644 --- a/config/chips/L4Rx.chip +++ b/config/chips/L4Rx.chip @@ -2,7 +2,7 @@ # dev_type STM32L4Rx ref_manual_id 0432 -chip_id 0x470 // STM32_CHIPID_STM32_L4RX +chip_id 0x470 // STM32_CHIPID_L4RX flash_type 9 // STM32_FLASH_TYPE_L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x1000 // 4 KB diff --git a/config/chips/WBx0_WBx5.chip b/config/chips/WBx0_WBx5.chip index e34c70815..3d27edd6d 100644 --- a/config/chips/WBx0_WBx5.chip +++ b/config/chips/WBx0_WBx5.chip @@ -2,7 +2,7 @@ # dev_type STM32WBx0_WBx5 ref_manual_id 0434 // also RM0471 -chip_id 0x495 // STM32_CHIPID_STM32_WB55 +chip_id 0x495 // STM32_CHIPID_WB55 flash_type 11 // STM32_FLASH_TYPE_WB_WL flash_size_reg 0x1fff75e0 flash_pagesize 0x1000 // 4 KB diff --git a/config/chips/WLx5.chip b/config/chips/WLx5.chip index b27e03dfe..9669fe27f 100644 --- a/config/chips/WLx5.chip +++ b/config/chips/WLx5.chip @@ -2,7 +2,7 @@ # dev_type STM32WLEx ref_manual_id 0033 -chip_id 0x497 // STM32_CHIPID_STM32_WLE +chip_id 0x497 // STM32_CHIPID_WLE flash_type 11 // STM32_FLASH_TYPE_WB_WL flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB diff --git a/inc/stlink.h b/inc/stlink.h index f6bd5cb0d..4899533ec 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -106,23 +106,6 @@ enum target_state { #define C_BUF_LEN 32 -// /* Old flash type definitions */ -// // TODO: Transition to the new defines in stm32.h -// enum stlink_flash_type { -// /* 0 */ STLINK_FLASH_TYPE_UNKNOWN = 0, -// /* 1 */ STLINK_FLASH_TYPE_F0, // used by f0, f1 (except f1xl),f3. */ -// /* 2 */ STLINK_FLASH_TYPE_F1_XL, // f0 flash with dual bank */ -// /* 3 */ STLINK_FLASH_TYPE_F4, // used by f2, f4 */ -// /* 4 */ STLINK_FLASH_TYPE_F7, -// /* 5 */ STLINK_FLASH_TYPE_L0, // l0, l1 */ -// /* 6 */ STLINK_FLASH_TYPE_L4, // l4, l4+ */ -// /* 7 */ STLINK_FLASH_TYPE_G0, -// /* 8 */ STLINK_FLASH_TYPE_G4, -// /* 9 */ STLINK_FLASH_TYPE_WB, -// /* 10 */ STLINK_FLASH_TYPE_H7, -// /* 11 */ STLINK_FLASH_TYPE_MAX, -// }; - struct stlink_reg { uint32_t r[16]; uint32_t s[32]; diff --git a/inc/stm32.h b/inc/stm32.h index d6faff12e..2e8ed6889 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -48,75 +48,67 @@ enum stm32_flash_type { enum stm32_chipids { STM32_CHIPID_UNKNOWN = 0x000, - STM32_CHIPID_STM32_F1_MD = 0x410, /* medium density */ - STM32_CHIPID_STM32_F2 = 0x411, - STM32_CHIPID_STM32_F1_LD = 0x412, /* low density */ - STM32_CHIPID_STM32_F4 = 0x413, - STM32_CHIPID_STM32_F1_HD = 0x414, /* high density */ - STM32_CHIPID_STM32_L4 = 0x415, - STM32_CHIPID_STM32_L1_MD = 0x416, /* medium density */ - STM32_CHIPID_STM32_L0 = 0x417, - STM32_CHIPID_STM32_F1_CONN = 0x418, /* connectivity line */ - STM32_CHIPID_STM32_F4_HD = 0x419, /* high density */ - STM32_CHIPID_STM32_F1_VL_MD_LD = 0x420, /* value line medium & low density */ - STM32_CHIPID_STM32_F446 = 0x421, - STM32_CHIPID_STM32_F3 = 0x422, - STM32_CHIPID_STM32_F4_LP = 0x423, - STM32_CHIPID_STM32_L0_CAT2 = 0x425, - STM32_CHIPID_STM32_L1_MD_PLUS = 0x427, /* medium density plus */ - STM32_CHIPID_STM32_F1_VL_HD = 0x428, /* value line high density */ - STM32_CHIPID_STM32_L1_CAT2 = 0x429, - STM32_CHIPID_STM32_F1_XLD = 0x430, /* extra low density plus */ - STM32_CHIPID_STM32_F411xx = 0x431, - STM32_CHIPID_STM32_F37x = 0x432, - STM32_CHIPID_STM32_F4_DE = 0x433, - STM32_CHIPID_STM32_F4_DSI = 0x434, - STM32_CHIPID_STM32_L43x_L44x = 0x435, - STM32_CHIPID_STM32_L1_MD_PLUS_HD = 0x436, /* medium density plus & high density */ - STM32_CHIPID_STM32_L152_RE = 0x437, - STM32_CHIPID_STM32_F334 = 0x438, - STM32_CHIPID_STM32_F3xx_SMALL = 0x439, - STM32_CHIPID_STM32_F0 = 0x440, - STM32_CHIPID_STM32_F412 = 0x441, - STM32_CHIPID_STM32_F09x = 0x442, - STM32_CHIPID_STM32_F0xx_SMALL = 0x444, - STM32_CHIPID_STM32_F04 = 0x445, - STM32_CHIPID_STM32_F303_HD = 0x446, /* high density */ - STM32_CHIPID_STM32_L0_CAT5 = 0x447, - STM32_CHIPID_STM32_F0_CAN = 0x448, - STM32_CHIPID_STM32_F7 = 0x449, /* Nucleo F746ZG board */ - STM32_CHIPID_STM32_H74xxx = 0x450, /* RM0433, p.3189 */ - STM32_CHIPID_STM32_F76xxx = 0x451, - STM32_CHIPID_STM32_F72xxx = 0x452, /* Nucleo F722ZE board */ - STM32_CHIPID_STM32_G0_CAT4 = 0x456, /* G051/G061 */ - STM32_CHIPID_STM32_L011 = 0x457, - STM32_CHIPID_STM32_F410 = 0x458, - STM32_CHIPID_STM32_G0_CAT2 = 0x460, /* G070/G071/G081 */ - STM32_CHIPID_STM32_L496x_L4A6x = 0x461, - STM32_CHIPID_STM32_L45x_L46x = 0x462, - STM32_CHIPID_STM32_F413 = 0x463, - STM32_CHIPID_STM32_L41x_L42x = 0x464, - STM32_CHIPID_STM32_G0_CAT1 = 0x466, /* G030/G031/G041 */ - STM32_CHIPID_STM32_G0_CAT3 = 0x467, /* G0B1/G0C1 */ - STM32_CHIPID_STM32_G4_CAT2 = 0x468, /* RM0440, section 46.6.1 "MCU device ID code" */ - STM32_CHIPID_STM32_G4_CAT3 = 0x469, - STM32_CHIPID_STM32_L4Rx = 0x470, /* RM0432, p.2247, found on the STM32L4R9I-DISCO board */ - STM32_CHIPID_STM32_L4PX = 0x471, /* RM0432, p.2247 */ - STM32_CHIPID_STM32_G4_CAT4 = 0x479, - STM32_CHIPID_STM32_H7Ax = 0x480, /* RM0455, p.2863 */ - STM32_CHIPID_STM32_H72x = 0x483, /* RM0468, p.3199 */ - STM32_CHIPID_STM32_WB55 = 0x495, - STM32_CHIPID_STM32_WLE = 0x497, + STM32_CHIPID_F1_MD = 0x410, /* medium density */ + STM32_CHIPID_F2 = 0x411, + STM32_CHIPID_F1_LD = 0x412, /* low density */ + STM32_CHIPID_F4 = 0x413, + STM32_CHIPID_F1_HD = 0x414, /* high density */ + STM32_CHIPID_L4 = 0x415, + STM32_CHIPID_L1_MD = 0x416, /* medium density */ + STM32_CHIPID_L0 = 0x417, + STM32_CHIPID_F1_CONN = 0x418, /* connectivity line */ + STM32_CHIPID_F4_HD = 0x419, /* high density */ + STM32_CHIPID_F1_VL_MD_LD = 0x420, /* value line medium & low density */ + STM32_CHIPID_F446 = 0x421, + STM32_CHIPID_F3 = 0x422, + STM32_CHIPID_F4_LP = 0x423, + STM32_CHIPID_L0_CAT2 = 0x425, + STM32_CHIPID_L1_MD_PLUS = 0x427, /* medium density plus */ + STM32_CHIPID_F1_VL_HD = 0x428, /* value line high density */ + STM32_CHIPID_L1_CAT2 = 0x429, + STM32_CHIPID_F1_XLD = 0x430, /* extra low density plus */ + STM32_CHIPID_F411xx = 0x431, + STM32_CHIPID_F37x = 0x432, + STM32_CHIPID_F4_DE = 0x433, + STM32_CHIPID_F4_DSI = 0x434, + STM32_CHIPID_L43x_L44x = 0x435, + STM32_CHIPID_L1_MD_PLUS_HD = 0x436, /* medium density plus & high density */ + STM32_CHIPID_L152_RE = 0x437, + STM32_CHIPID_F334 = 0x438, + STM32_CHIPID_F3xx_SMALL = 0x439, + STM32_CHIPID_F0 = 0x440, + STM32_CHIPID_F412 = 0x441, + STM32_CHIPID_F09x = 0x442, + STM32_CHIPID_F0xx_SMALL = 0x444, + STM32_CHIPID_F04 = 0x445, + STM32_CHIPID_F303_HD = 0x446, /* high density */ + STM32_CHIPID_L0_CAT5 = 0x447, + STM32_CHIPID_F0_CAN = 0x448, + STM32_CHIPID_F7 = 0x449, /* Nucleo F746ZG board */ + STM32_CHIPID_H74xxx = 0x450, /* RM0433, p.3189 */ + STM32_CHIPID_F76xxx = 0x451, + STM32_CHIPID_F72xxx = 0x452, /* Nucleo F722ZE board */ + STM32_CHIPID_G0_CAT4 = 0x456, /* G051/G061 */ + STM32_CHIPID_L011 = 0x457, + STM32_CHIPID_F410 = 0x458, + STM32_CHIPID_G0_CAT2 = 0x460, /* G070/G071/G081 */ + STM32_CHIPID_L496x_L4A6x = 0x461, + STM32_CHIPID_L45x_L46x = 0x462, + STM32_CHIPID_F413 = 0x463, + STM32_CHIPID_L41x_L42x = 0x464, + STM32_CHIPID_G0_CAT1 = 0x466, /* G030/G031/G041 */ + STM32_CHIPID_G0_CAT3 = 0x467, /* G0B1/G0C1 */ + STM32_CHIPID_G4_CAT2 = 0x468, /* RM0440, section 46.6.1 "MCU device ID code" */ + STM32_CHIPID_G4_CAT3 = 0x469, + STM32_CHIPID_L4Rx = 0x470, /* RM0432, p.2247, found on the STM32L4R9I-DISCO board */ + STM32_CHIPID_L4PX = 0x471, /* RM0432, p.2247 */ + STM32_CHIPID_G4_CAT4 = 0x479, + STM32_CHIPID_H7Ax = 0x480, /* RM0455, p.2863 */ + STM32_CHIPID_H72x = 0x483, /* RM0468, p.3199 */ + STM32_CHIPID_WB55 = 0x495, + STM32_CHIPID_WLE = 0x497, }; -/* Constant STM32 memory address */ -#define STM32_SRAM_BASE ((uint32_t)0x20000000) -#define STM32_FLASH_BASE ((uint32_t)0x08000000) - -#define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) -#define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) - - /* Constant STM32 option bytes base memory address */ #define STM32_F4_OPTION_BYTES_BASE ((uint32_t)0x40023c14) @@ -137,4 +129,392 @@ enum stm32_chipids { #define STM32_F3_OPTION_BYTES_BASE ((uint32_t)0x1ffff800) #define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1ffff800) +/* ============ */ +/* Old defines from common.c are below */ +/* ============ */ + +/* Constant STM32 memory address */ +#define STM32_SRAM_BASE ((uint32_t)0x20000000) +#define STM32_FLASH_BASE ((uint32_t)0x08000000) + +#define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) +#define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) + +/* stm32f FPEC flash controller interface, pm0063 manual */ +// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, August 2012) +#define FLASH_REGS_ADDR 0x40022000 +#define FLASH_REGS_SIZE 0x28 + +#define FLASH_ACR (FLASH_REGS_ADDR + 0x00) +#define FLASH_KEYR (FLASH_REGS_ADDR + 0x04) +#define FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x08) +#define FLASH_SR (FLASH_REGS_ADDR + 0x0c) +#define FLASH_CR (FLASH_REGS_ADDR + 0x10) +#define FLASH_AR (FLASH_REGS_ADDR + 0x14) +#define FLASH_OBR (FLASH_REGS_ADDR + 0x1c) +#define FLASH_WRPR (FLASH_REGS_ADDR + 0x20) + +// STM32F10x_XL has two flash memory banks with separate registers to control +// the second bank. +#define FLASH_KEYR2 (FLASH_REGS_ADDR + 0x44) +#define FLASH_SR2 (FLASH_REGS_ADDR + 0x4c) +#define FLASH_CR2 (FLASH_REGS_ADDR + 0x50) +#define FLASH_AR2 (FLASH_REGS_ADDR + 0x54) + +// For STM32F05x, the RDPTR_KEY may be wrong, but as it is not used anywhere... +#define FLASH_RDPTR_KEY 0x00a5 +#define FLASH_KEY1 0x45670123 +#define FLASH_KEY2 0xcdef89ab + +#define FLASH_L0_PRGKEY1 0x8c9daebf +#define FLASH_L0_PRGKEY2 0x13141516 + +#define FLASH_L0_PEKEY1 0x89abcdef +#define FLASH_L0_PEKEY2 0x02030405 + +#define FLASH_OPTKEY1 0x08192A3B +#define FLASH_OPTKEY2 0x4C5D6E7F + +#define FLASH_F0_OPTKEY1 0x45670123 +#define FLASH_F0_OPTKEY2 0xCDEF89AB + +#define FLASH_L0_OPTKEY1 0xFBEAD9C8 +#define FLASH_L0_OPTKEY2 0x24252627 + +#define FLASH_SR_BSY 0 +#define FLASH_SR_PG_ERR 2 +#define FLASH_SR_WRPRT_ERR 4 +#define FLASH_SR_EOP 5 + +#define FLASH_SR_ERROR_MASK ((1 << FLASH_SR_PG_ERR) | (1 << FLASH_SR_WRPRT_ERR)) + +#define FLASH_CR_PG 0 +#define FLASH_CR_PER 1 +#define FLASH_CR_MER 2 +#define FLASH_CR_OPTPG 4 +#define FLASH_CR_OPTER 5 +#define FLASH_CR_STRT 6 +#define FLASH_CR_LOCK 7 +#define FLASH_CR_OPTWRE 9 +#define FLASH_CR_OBL_LAUNCH 13 + +#define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00) +#define STM32L_FLASH_ACR (STM32L_FLASH_REGS_ADDR + 0x00) +#define STM32L_FLASH_PECR (STM32L_FLASH_REGS_ADDR + 0x04) +#define STM32L_FLASH_PDKEYR (STM32L_FLASH_REGS_ADDR + 0x08) +#define STM32L_FLASH_PEKEYR (STM32L_FLASH_REGS_ADDR + 0x0c) +#define STM32L_FLASH_PRGKEYR (STM32L_FLASH_REGS_ADDR + 0x10) +#define STM32L_FLASH_OPTKEYR (STM32L_FLASH_REGS_ADDR + 0x14) +#define STM32L_FLASH_SR (STM32L_FLASH_REGS_ADDR + 0x18) +#define STM32L_FLASH_OBR (STM32L_FLASH_REGS_ADDR + 0x1c) +#define STM32L_FLASH_WRPR (STM32L_FLASH_REGS_ADDR + 0x20) +#define FLASH_L1_FPRG 10 +#define FLASH_L1_PROG 3 + +// Flash registers common to STM32G0 and STM32G4 series. +#define STM32Gx_FLASH_REGS_ADDR ((uint32_t)0x40022000) +#define STM32Gx_FLASH_ACR (STM32Gx_FLASH_REGS_ADDR + 0x00) +#define STM32Gx_FLASH_KEYR (STM32Gx_FLASH_REGS_ADDR + 0x08) +#define STM32Gx_FLASH_OPTKEYR (STM32Gx_FLASH_REGS_ADDR + 0x0c) +#define STM32Gx_FLASH_SR (STM32Gx_FLASH_REGS_ADDR + 0x10) +#define STM32Gx_FLASH_CR (STM32Gx_FLASH_REGS_ADDR + 0x14) +#define STM32Gx_FLASH_ECCR (STM32Gx_FLASH_REGS_ADDR + 0x18) +#define STM32Gx_FLASH_OPTR (STM32Gx_FLASH_REGS_ADDR + 0x20) + +// G0 (RM0444 Table 1, sec 3.7) +// Mostly the same as G4 chips, but the notation +// varies a bit after the 'OPTR' register. +#define STM32G0_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) +#define STM32G0_FLASH_PCROP1ASR (STM32G0_FLASH_REGS_ADDR + 0x24) +#define STM32G0_FLASH_PCROP1AER (STM32G0_FLASH_REGS_ADDR + 0x28) +#define STM32G0_FLASH_WRP1AR (STM32G0_FLASH_REGS_ADDR + 0x2C) +#define STM32G0_FLASH_WRP1BR (STM32G0_FLASH_REGS_ADDR + 0x30) +#define STM32G0_FLASH_PCROP1BSR (STM32G0_FLASH_REGS_ADDR + 0x34) +#define STM32G0_FLASH_PCROP1BER (STM32G0_FLASH_REGS_ADDR + 0x38) +#define STM32G0_FLASH_SECR (STM32G0_FLASH_REGS_ADDR + 0x80) + +// G4 (RM0440 Table 17, sec 3.7.19) +// Mostly the same as STM32G0 chips, but there are a few extra +// registers because 'cat 3' devices can have two Flash banks. +#define STM32G4_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) +#define STM32G4_FLASH_PDKEYR (STM32G4_FLASH_REGS_ADDR + 0x04) +#define STM32G4_FLASH_PCROP1SR (STM32G4_FLASH_REGS_ADDR + 0x24) +#define STM32G4_FLASH_PCROP1ER (STM32G4_FLASH_REGS_ADDR + 0x28) +#define STM32G4_FLASH_WRP1AR (STM32G4_FLASH_REGS_ADDR + 0x2C) +#define STM32G4_FLASH_WRP1BR (STM32G4_FLASH_REGS_ADDR + 0x30) +#define STM32G4_FLASH_PCROP2SR (STM32G4_FLASH_REGS_ADDR + 0x44) +#define STM32G4_FLASH_PCROP2ER (STM32G4_FLASH_REGS_ADDR + 0x48) +#define STM32G4_FLASH_WRP2AR (STM32G4_FLASH_REGS_ADDR + 0x4C) +#define STM32G4_FLASH_WRP2BR (STM32G4_FLASH_REGS_ADDR + 0x50) +#define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70) +#define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74) + +// G0/G4 FLASH control register +#define STM32Gx_FLASH_CR_PG (0) /* Program */ +#define STM32Gx_FLASH_CR_PER (1) /* Page erase */ +#define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */ +#define STM32Gx_FLASH_CR_PNB (3) /* Page number */ +#define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ +#define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ +#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ +#define STM32Gx_FLASH_CR_STRT (16) /* Start */ +#define STM32Gx_FLASH_CR_OPTSTRT \ + (17) /* Start of modification of option bytes */ +#define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ +#define STM32Gx_FLASH_CR_EOPIE (24) /* End of operation interrupt enable */ +#define STM32Gx_FLASH_CR_ERRIE (25) /* Error interrupt enable */ +#define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ +#define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ +#define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ + +// G0/G4 FLASH status register +#define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) +#define STM32Gx_FLASH_SR_PROGERR (3) +#define STM32Gx_FLASH_SR_WRPERR (4) +#define STM32Gx_FLASH_SR_PGAERR (5) +#define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ +#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ + +// G4 FLASH option register +#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ + +// WB (RM0434) +#define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) +#define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) +#define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) +#define STM32WB_FLASH_OPT_KEYR (STM32WB_FLASH_REGS_ADDR + 0x0C) +#define STM32WB_FLASH_SR (STM32WB_FLASH_REGS_ADDR + 0x10) +#define STM32WB_FLASH_CR (STM32WB_FLASH_REGS_ADDR + 0x14) +#define STM32WB_FLASH_ECCR (STM32WB_FLASH_REGS_ADDR + 0x18) +#define STM32WB_FLASH_OPTR (STM32WB_FLASH_REGS_ADDR + 0x20) +#define STM32WB_FLASH_PCROP1ASR (STM32WB_FLASH_REGS_ADDR + 0x24) +#define STM32WB_FLASH_PCROP1AER (STM32WB_FLASH_REGS_ADDR + 0x28) +#define STM32WB_FLASH_WRP1AR (STM32WB_FLASH_REGS_ADDR + 0x2C) +#define STM32WB_FLASH_WRP1BR (STM32WB_FLASH_REGS_ADDR + 0x30) +#define STM32WB_FLASH_PCROP1BSR (STM32WB_FLASH_REGS_ADDR + 0x34) +#define STM32WB_FLASH_PCROP1BER (STM32WB_FLASH_REGS_ADDR + 0x38) +#define STM32WB_FLASH_IPCCBR (STM32WB_FLASH_REGS_ADDR + 0x3C) +#define STM32WB_FLASH_C2ACR (STM32WB_FLASH_REGS_ADDR + 0x5C) +#define STM32WB_FLASH_C2SR (STM32WB_FLASH_REGS_ADDR + 0x60) +#define STM32WB_FLASH_C2CR (STM32WB_FLASH_REGS_ADDR + 0x64) +#define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) +#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) + +// WB Flash control register. +#define STM32WB_FLASH_CR_STRT (16) /* Start */ +#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ +#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ +// WB Flash status register. +#define STM32WB_FLASH_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ +#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ +#define STM32WB_FLASH_SR_WRPERR (4) /* Write protection error */ +#define STM32WB_FLASH_SR_PGAERR (5) /* Programming error */ +#define STM32WB_FLASH_SR_BSY (16) /* Busy */ + +// 32L4 register base is at FLASH_REGS_ADDR (0x40022000) +#define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) +#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) +#define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) +#define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) +#define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) + +#define STM32L4_FLASH_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ +#define STM32L4_FLASH_SR_PROGERR 3 +#define STM32L4_FLASH_SR_WRPERR 4 +#define STM32L4_FLASH_SR_PGAERR 5 +#define STM32L4_FLASH_SR_BSY 16 + +#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ +#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ +#define STM32L4_FLASH_CR_PG 0 /* Program */ +#define STM32L4_FLASH_CR_PER 1 /* Page erase */ +#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ +#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ +#define STM32L4_FLASH_CR_STRT 16 /* Start command */ +#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ +#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ +#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ +#define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ +// Bits requesting flash operations (useful when we want to clear them) +#define STM32L4_FLASH_CR_OPBITS \ + (uint32_t)((1lu << STM32L4_FLASH_CR_PG) | (1lu << STM32L4_FLASH_CR_PER) | \ + (1lu << STM32L4_FLASH_CR_MER1) | (1lu << STM32L4_FLASH_CR_MER1)) +// Page is fully specified by BKER and PNB +#define STM32L4_FLASH_CR_PAGEMASK (uint32_t)(0x1fflu << STM32L4_FLASH_CR_PNB) + +#define STM32L4_FLASH_OPTR_DUALBANK 21 + +// STM32L0x flash register base and offsets RM0090 - DM00031020.pdf +#define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) + +#define STM32L0_FLASH_PELOCK (0) +#define STM32L0_FLASH_OPTLOCK (2) +#define STM32L0_FLASH_OBL_LAUNCH (18) + +#define STM32L0_FLASH_SR_ERROR_MASK 0x00013F00 +#define STM32L0_FLASH_SR_WRPERR 8 +#define STM32L0_FLASH_SR_PGAERR 9 +#define STM32L0_FLASH_SR_NOTZEROERR 16 + +#define FLASH_ACR_OFF ((uint32_t)0x00) +#define FLASH_PECR_OFF ((uint32_t)0x04) +#define FLASH_PDKEYR_OFF ((uint32_t)0x08) +#define FLASH_PEKEYR_OFF ((uint32_t)0x0c) +#define FLASH_PRGKEYR_OFF ((uint32_t)0x10) +#define FLASH_OPTKEYR_OFF ((uint32_t)0x14) +#define FLASH_SR_OFF ((uint32_t)0x18) +#define FLASH_OBR_OFF ((uint32_t)0x1c) +#define FLASH_WRPR_OFF ((uint32_t)0x20) + +// STM32F7 +#define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) +#define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) +#define FLASH_F7_SR (FLASH_F7_REGS_ADDR + 0x0c) +#define FLASH_F7_CR (FLASH_F7_REGS_ADDR + 0x10) +#define FLASH_F7_OPTCR (FLASH_F7_REGS_ADDR + 0x14) +#define FLASH_F7_OPTCR1 (FLASH_F7_REGS_ADDR + 0x18) +#define FLASH_F7_OPTCR_LOCK 0 +#define FLASH_F7_OPTCR_START 1 +#define FLASH_F7_CR_STRT 16 +#define FLASH_F7_CR_LOCK 31 +#define FLASH_F7_CR_SER 1 +#define FLASH_F7_CR_SNB 3 +#define FLASH_F7_CR_SNB_MASK 0xf8 +#define FLASH_F7_SR_BSY 16 +#define FLASH_F7_SR_ERS_ERR 7 /* Erase Sequence Error */ +#define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ +#define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ +#define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ +#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ +#define FLASH_F7_SR_EOP 0 /* End of operation */ +#define FLASH_F7_OPTCR1_BOOT_ADD0 0 +#define FLASH_F7_OPTCR1_BOOT_ADD1 16 + +#define FLASH_F7_SR_ERROR_MASK \ + ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | \ + (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | \ + (1 << FLASH_F7_SR_OP_ERR)) + +// STM32F4 +#define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) +#define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08) +#define FLASH_F4_SR (FLASH_F4_REGS_ADDR + 0x0c) +#define FLASH_F4_CR (FLASH_F4_REGS_ADDR + 0x10) +#define FLASH_F4_OPTCR (FLASH_F4_REGS_ADDR + 0x14) +#define FLASH_F4_OPTCR_LOCK 0 +#define FLASH_F4_OPTCR_START 1 +#define FLASH_F4_CR_STRT 16 +#define FLASH_F4_CR_LOCK 31 +#define FLASH_F4_CR_SER 1 +#define FLASH_F4_CR_SNB 3 +#define FLASH_F4_CR_SNB_MASK 0xf8 +#define FLASH_F4_SR_ERROR_MASK 0x000000F0 +#define FLASH_F4_SR_PGAERR 5 +#define FLASH_F4_SR_WRPERR 4 +#define FLASH_F4_SR_BSY 16 + +// STM32F2 +#define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F2_KEYR (FLASH_F2_REGS_ADDR + 0x04) +#define FLASH_F2_OPT_KEYR (FLASH_F2_REGS_ADDR + 0x08) +#define FLASH_F2_SR (FLASH_F2_REGS_ADDR + 0x0c) +#define FLASH_F2_CR (FLASH_F2_REGS_ADDR + 0x10) +#define FLASH_F2_OPT_CR (FLASH_F2_REGS_ADDR + 0x14) +#define FLASH_F2_OPT_LOCK_BIT (1u << 0) +#define FLASH_F2_CR_STRT 16 +#define FLASH_F2_CR_LOCK 31 + +#define FLASH_F2_CR_SER 1 +#define FLASH_F2_CR_SNB 3 +#define FLASH_F2_CR_SNB_MASK 0x78 +#define FLASH_F2_SR_BSY 16 + +// STM32H7xx +#define FLASH_H7_CR_LOCK 0 +#define FLASH_H7_CR_PG 1 +#define FLASH_H7_CR_SER 2 +#define FLASH_H7_CR_BER 3 +#define FLASH_H7_CR_PSIZE 4 +#define FLASH_H7_CR_START(chipid) (chipid == STM32_CHIPID_H7Ax ? 5 : 7) +#define FLASH_H7_CR_SNB 8 +#define FLASH_H7_CR_SNB_MASK 0x700 + +#define FLASH_H7_SR_QW 2 +#define FLASH_H7_SR_WRPERR 17 +#define FLASH_H7_SR_PGSERR 18 +#define FLASH_H7_SR_STRBERR 19 +#define FLASH_H7_SR_ERROR_MASK \ + ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | \ + (1 << FLASH_H7_SR_WRPERR)) + +#define FLASH_H7_OPTCR_OPTLOCK 0 +#define FLASH_H7_OPTCR_OPTSTART 1 +#define FLASH_H7_OPTCR_MER 4 + +#define FLASH_H7_OPTSR_OPT_BUSY 0 +#define FLASH_H7_OPTSR_OPTCHANGEERR 30 + +#define FLASH_H7_OPTCCR_CLR_OPTCHANGEERR 30 + +#define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) +#define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) +#define FLASH_H7_KEYR2 (FLASH_H7_REGS_ADDR + 0x104) +#define FLASH_H7_OPT_KEYR (FLASH_H7_REGS_ADDR + 0x08) +#define FLASH_H7_OPT_KEYR2 (FLASH_H7_REGS_ADDR + 0x108) +#define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c) +#define FLASH_H7_CR2 (FLASH_H7_REGS_ADDR + 0x10c) +#define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) +#define FLASH_H7_SR2 (FLASH_H7_REGS_ADDR + 0x110) +#define FLASH_H7_CCR1 (FLASH_H7_REGS_ADDR + 0x14) +#define FLASH_H7_CCR2 (FLASH_H7_REGS_ADDR + 0x114) +#define FLASH_H7_OPTCR (FLASH_H7_REGS_ADDR + 0x18) +#define FLASH_H7_OPTCR2 (FLASH_H7_REGS_ADDR + 0x118) +#define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) +#define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) + +#define STM32F0_DBGMCU_CR 0xE0042004 +#define STM32F0_DBGMCU_CR_IWDG_STOP 8 +#define STM32F0_DBGMCU_CR_WWDG_STOP 9 + +#define STM32F4_DBGMCU_APB1FZR1 0xE0042008 +#define STM32F4_DBGMCU_APB1FZR1_WWDG_STOP 11 +#define STM32F4_DBGMCU_APB1FZR1_IWDG_STOP 12 + +#define STM32L0_DBGMCU_APB1_FZ 0x40015808 +#define STM32L0_DBGMCU_APB1_FZ_WWDG_STOP 11 +#define STM32L0_DBGMCU_APB1_FZ_IWDG_STOP 12 + +#define STM32H7_DBGMCU_APB1HFZ 0x5C001054 +#define STM32H7_DBGMCU_APB1HFZ_IWDG_STOP 18 + +#define STM32WB_DBGMCU_APB1FZR1 0xE004203C +#define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11 +#define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12 + +#define STM32F1_RCC_AHBENR 0x40021014 +#define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32F4_RCC_AHB1ENR 0x40023830 +#define STM32F4_RCC_DMAEN 0x00600000 // DMA2EN | DMA1EN + +#define STM32G0_RCC_AHBENR 0x40021038 +#define STM32G0_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32G4_RCC_AHB1ENR 0x40021048 +#define STM32G4_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32L0_RCC_AHBENR 0x40021030 +#define STM32L0_RCC_DMAEN 0x00000001 // DMAEN + +#define STM32H7_RCC_AHB1ENR 0x58024538 +#define STM32H7_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32WB_RCC_AHB1ENR 0x58000048 +#define STM32WB_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define L1_WRITE_BLOCK_SIZE 0x80 +#define L0_WRITE_BLOCK_SIZE 0x40 + #endif // STM32_H diff --git a/src/common.c b/src/common.c index 5a9c43c96..bdd38b21a 100644 --- a/src/common.c +++ b/src/common.c @@ -35,384 +35,7 @@ #define BANK_1 0 #define BANK_2 1 -/* stm32f FPEC flash controller interface, pm0063 manual */ -// TODO - all of this needs to be abstracted out.... -// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, -// August 2012) -#define FLASH_REGS_ADDR 0x40022000 -#define FLASH_REGS_SIZE 0x28 - -#define FLASH_ACR (FLASH_REGS_ADDR + 0x00) -#define FLASH_KEYR (FLASH_REGS_ADDR + 0x04) -#define FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x08) -#define FLASH_SR (FLASH_REGS_ADDR + 0x0c) -#define FLASH_CR (FLASH_REGS_ADDR + 0x10) -#define FLASH_AR (FLASH_REGS_ADDR + 0x14) -#define FLASH_OBR (FLASH_REGS_ADDR + 0x1c) -#define FLASH_WRPR (FLASH_REGS_ADDR + 0x20) - -// STM32F10x_XL has two flash memory banks with separate registers to control -// the second bank. -#define FLASH_KEYR2 (FLASH_REGS_ADDR + 0x44) -#define FLASH_SR2 (FLASH_REGS_ADDR + 0x4c) -#define FLASH_CR2 (FLASH_REGS_ADDR + 0x50) -#define FLASH_AR2 (FLASH_REGS_ADDR + 0x54) - -// For STM32F05x, the RDPTR_KEY may be wrong, but as it is not used anywhere... -#define FLASH_RDPTR_KEY 0x00a5 -#define FLASH_KEY1 0x45670123 -#define FLASH_KEY2 0xcdef89ab - -#define FLASH_L0_PRGKEY1 0x8c9daebf -#define FLASH_L0_PRGKEY2 0x13141516 - -#define FLASH_L0_PEKEY1 0x89abcdef -#define FLASH_L0_PEKEY2 0x02030405 - -#define FLASH_OPTKEY1 0x08192A3B -#define FLASH_OPTKEY2 0x4C5D6E7F - -#define FLASH_F0_OPTKEY1 0x45670123 -#define FLASH_F0_OPTKEY2 0xCDEF89AB - -#define FLASH_L0_OPTKEY1 0xFBEAD9C8 -#define FLASH_L0_OPTKEY2 0x24252627 - -#define FLASH_SR_BSY 0 -#define FLASH_SR_PG_ERR 2 -#define FLASH_SR_WRPRT_ERR 4 -#define FLASH_SR_EOP 5 - -#define FLASH_SR_ERROR_MASK ((1 << FLASH_SR_PG_ERR) | (1 << FLASH_SR_WRPRT_ERR)) - -#define FLASH_CR_PG 0 -#define FLASH_CR_PER 1 -#define FLASH_CR_MER 2 -#define FLASH_CR_OPTPG 4 -#define FLASH_CR_OPTER 5 -#define FLASH_CR_STRT 6 -#define FLASH_CR_LOCK 7 -#define FLASH_CR_OPTWRE 9 -#define FLASH_CR_OBL_LAUNCH 13 - -#define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00) -#define STM32L_FLASH_ACR (STM32L_FLASH_REGS_ADDR + 0x00) -#define STM32L_FLASH_PECR (STM32L_FLASH_REGS_ADDR + 0x04) -#define STM32L_FLASH_PDKEYR (STM32L_FLASH_REGS_ADDR + 0x08) -#define STM32L_FLASH_PEKEYR (STM32L_FLASH_REGS_ADDR + 0x0c) -#define STM32L_FLASH_PRGKEYR (STM32L_FLASH_REGS_ADDR + 0x10) -#define STM32L_FLASH_OPTKEYR (STM32L_FLASH_REGS_ADDR + 0x14) -#define STM32L_FLASH_SR (STM32L_FLASH_REGS_ADDR + 0x18) -#define STM32L_FLASH_OBR (STM32L_FLASH_REGS_ADDR + 0x1c) -#define STM32L_FLASH_WRPR (STM32L_FLASH_REGS_ADDR + 0x20) -#define FLASH_L1_FPRG 10 -#define FLASH_L1_PROG 3 - -// Flash registers common to STM32G0 and STM32G4 series. -#define STM32Gx_FLASH_REGS_ADDR ((uint32_t)0x40022000) -#define STM32Gx_FLASH_ACR (STM32Gx_FLASH_REGS_ADDR + 0x00) -#define STM32Gx_FLASH_KEYR (STM32Gx_FLASH_REGS_ADDR + 0x08) -#define STM32Gx_FLASH_OPTKEYR (STM32Gx_FLASH_REGS_ADDR + 0x0c) -#define STM32Gx_FLASH_SR (STM32Gx_FLASH_REGS_ADDR + 0x10) -#define STM32Gx_FLASH_CR (STM32Gx_FLASH_REGS_ADDR + 0x14) -#define STM32Gx_FLASH_ECCR (STM32Gx_FLASH_REGS_ADDR + 0x18) -#define STM32Gx_FLASH_OPTR (STM32Gx_FLASH_REGS_ADDR + 0x20) - -// G0 (RM0444 Table 1, sec 3.7) -// Mostly the same as G4 chips, but the notation -// varies a bit after the 'OPTR' register. -#define STM32G0_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) -#define STM32G0_FLASH_PCROP1ASR (STM32G0_FLASH_REGS_ADDR + 0x24) -#define STM32G0_FLASH_PCROP1AER (STM32G0_FLASH_REGS_ADDR + 0x28) -#define STM32G0_FLASH_WRP1AR (STM32G0_FLASH_REGS_ADDR + 0x2C) -#define STM32G0_FLASH_WRP1BR (STM32G0_FLASH_REGS_ADDR + 0x30) -#define STM32G0_FLASH_PCROP1BSR (STM32G0_FLASH_REGS_ADDR + 0x34) -#define STM32G0_FLASH_PCROP1BER (STM32G0_FLASH_REGS_ADDR + 0x38) -#define STM32G0_FLASH_SECR (STM32G0_FLASH_REGS_ADDR + 0x80) - -// G4 (RM0440 Table 17, sec 3.7.19) -// Mostly the same as STM32G0 chips, but there are a few extra -// registers because 'cat 3' devices can have two Flash banks. -#define STM32G4_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) -#define STM32G4_FLASH_PDKEYR (STM32G4_FLASH_REGS_ADDR + 0x04) -#define STM32G4_FLASH_PCROP1SR (STM32G4_FLASH_REGS_ADDR + 0x24) -#define STM32G4_FLASH_PCROP1ER (STM32G4_FLASH_REGS_ADDR + 0x28) -#define STM32G4_FLASH_WRP1AR (STM32G4_FLASH_REGS_ADDR + 0x2C) -#define STM32G4_FLASH_WRP1BR (STM32G4_FLASH_REGS_ADDR + 0x30) -#define STM32G4_FLASH_PCROP2SR (STM32G4_FLASH_REGS_ADDR + 0x44) -#define STM32G4_FLASH_PCROP2ER (STM32G4_FLASH_REGS_ADDR + 0x48) -#define STM32G4_FLASH_WRP2AR (STM32G4_FLASH_REGS_ADDR + 0x4C) -#define STM32G4_FLASH_WRP2BR (STM32G4_FLASH_REGS_ADDR + 0x50) -#define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70) -#define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74) - -// G0/G4 FLASH control register -#define STM32Gx_FLASH_CR_PG (0) /* Program */ -#define STM32Gx_FLASH_CR_PER (1) /* Page erase */ -#define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */ -#define STM32Gx_FLASH_CR_PNB (3) /* Page number */ -#define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ -#define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ -#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ -#define STM32Gx_FLASH_CR_STRT (16) /* Start */ -#define STM32Gx_FLASH_CR_OPTSTRT \ - (17) /* Start of modification of option bytes */ -#define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ -#define STM32Gx_FLASH_CR_EOPIE (24) /* End of operation interrupt enable */ -#define STM32Gx_FLASH_CR_ERRIE (25) /* Error interrupt enable */ -#define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ -#define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ -#define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ - -// G0/G4 FLASH status register -#define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) -#define STM32Gx_FLASH_SR_PROGERR (3) -#define STM32Gx_FLASH_SR_WRPERR (4) -#define STM32Gx_FLASH_SR_PGAERR (5) -#define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ -#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ - -// G4 FLASH option register -#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ - -// WB (RM0434) -#define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) -#define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) -#define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) -#define STM32WB_FLASH_OPT_KEYR (STM32WB_FLASH_REGS_ADDR + 0x0C) -#define STM32WB_FLASH_SR (STM32WB_FLASH_REGS_ADDR + 0x10) -#define STM32WB_FLASH_CR (STM32WB_FLASH_REGS_ADDR + 0x14) -#define STM32WB_FLASH_ECCR (STM32WB_FLASH_REGS_ADDR + 0x18) -#define STM32WB_FLASH_OPTR (STM32WB_FLASH_REGS_ADDR + 0x20) -#define STM32WB_FLASH_PCROP1ASR (STM32WB_FLASH_REGS_ADDR + 0x24) -#define STM32WB_FLASH_PCROP1AER (STM32WB_FLASH_REGS_ADDR + 0x28) -#define STM32WB_FLASH_WRP1AR (STM32WB_FLASH_REGS_ADDR + 0x2C) -#define STM32WB_FLASH_WRP1BR (STM32WB_FLASH_REGS_ADDR + 0x30) -#define STM32WB_FLASH_PCROP1BSR (STM32WB_FLASH_REGS_ADDR + 0x34) -#define STM32WB_FLASH_PCROP1BER (STM32WB_FLASH_REGS_ADDR + 0x38) -#define STM32WB_FLASH_IPCCBR (STM32WB_FLASH_REGS_ADDR + 0x3C) -#define STM32WB_FLASH_C2ACR (STM32WB_FLASH_REGS_ADDR + 0x5C) -#define STM32WB_FLASH_C2SR (STM32WB_FLASH_REGS_ADDR + 0x60) -#define STM32WB_FLASH_C2CR (STM32WB_FLASH_REGS_ADDR + 0x64) -#define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) -#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) - -// WB Flash control register. -#define STM32WB_FLASH_CR_STRT (16) /* Start */ -#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ -#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ -// WB Flash status register. -#define STM32WB_FLASH_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ -#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ -#define STM32WB_FLASH_SR_WRPERR (4) /* Write protection error */ -#define STM32WB_FLASH_SR_PGAERR (5) /* Programming error */ -#define STM32WB_FLASH_SR_BSY (16) /* Busy */ - -// 32L4 register base is at FLASH_REGS_ADDR (0x40022000) -#define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) -#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) -#define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) -#define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) -#define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) - -#define STM32L4_FLASH_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ -#define STM32L4_FLASH_SR_PROGERR 3 -#define STM32L4_FLASH_SR_WRPERR 4 -#define STM32L4_FLASH_SR_PGAERR 5 -#define STM32L4_FLASH_SR_BSY 16 - -#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ -#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ -#define STM32L4_FLASH_CR_PG 0 /* Program */ -#define STM32L4_FLASH_CR_PER 1 /* Page erase */ -#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ -#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ -#define STM32L4_FLASH_CR_STRT 16 /* Start command */ -#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ -#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ -#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ -#define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ -// Bits requesting flash operations (useful when we want to clear them) -#define STM32L4_FLASH_CR_OPBITS \ - (uint32_t)((1lu << STM32L4_FLASH_CR_PG) | (1lu << STM32L4_FLASH_CR_PER) | \ - (1lu << STM32L4_FLASH_CR_MER1) | (1lu << STM32L4_FLASH_CR_MER1)) -// Page is fully specified by BKER and PNB -#define STM32L4_FLASH_CR_PAGEMASK (uint32_t)(0x1fflu << STM32L4_FLASH_CR_PNB) - -#define STM32L4_FLASH_OPTR_DUALBANK 21 - -// STM32L0x flash register base and offsets RM0090 - DM00031020.pdf -#define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) - -#define STM32L0_FLASH_PELOCK (0) -#define STM32L0_FLASH_OPTLOCK (2) -#define STM32L0_FLASH_OBL_LAUNCH (18) - -#define STM32L0_FLASH_SR_ERROR_MASK 0x00013F00 -#define STM32L0_FLASH_SR_WRPERR 8 -#define STM32L0_FLASH_SR_PGAERR 9 -#define STM32L0_FLASH_SR_NOTZEROERR 16 - -#define FLASH_ACR_OFF ((uint32_t)0x00) -#define FLASH_PECR_OFF ((uint32_t)0x04) -#define FLASH_PDKEYR_OFF ((uint32_t)0x08) -#define FLASH_PEKEYR_OFF ((uint32_t)0x0c) -#define FLASH_PRGKEYR_OFF ((uint32_t)0x10) -#define FLASH_OPTKEYR_OFF ((uint32_t)0x14) -#define FLASH_SR_OFF ((uint32_t)0x18) -#define FLASH_OBR_OFF ((uint32_t)0x1c) -#define FLASH_WRPR_OFF ((uint32_t)0x20) - -// STM32F7 -#define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) -#define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) -#define FLASH_F7_SR (FLASH_F7_REGS_ADDR + 0x0c) -#define FLASH_F7_CR (FLASH_F7_REGS_ADDR + 0x10) -#define FLASH_F7_OPTCR (FLASH_F7_REGS_ADDR + 0x14) -#define FLASH_F7_OPTCR1 (FLASH_F7_REGS_ADDR + 0x18) -#define FLASH_F7_OPTCR_LOCK 0 -#define FLASH_F7_OPTCR_START 1 -#define FLASH_F7_CR_STRT 16 -#define FLASH_F7_CR_LOCK 31 -#define FLASH_F7_CR_SER 1 -#define FLASH_F7_CR_SNB 3 -#define FLASH_F7_CR_SNB_MASK 0xf8 -#define FLASH_F7_SR_BSY 16 -#define FLASH_F7_SR_ERS_ERR 7 /* Erase Sequence Error */ -#define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ -#define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ -#define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ -#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ -#define FLASH_F7_SR_EOP 0 /* End of operation */ -#define FLASH_F7_OPTCR1_BOOT_ADD0 0 -#define FLASH_F7_OPTCR1_BOOT_ADD1 16 - -#define FLASH_F7_SR_ERROR_MASK \ - ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | \ - (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | \ - (1 << FLASH_F7_SR_OP_ERR)) - -// STM32F4 -#define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) -#define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08) -#define FLASH_F4_SR (FLASH_F4_REGS_ADDR + 0x0c) -#define FLASH_F4_CR (FLASH_F4_REGS_ADDR + 0x10) -#define FLASH_F4_OPTCR (FLASH_F4_REGS_ADDR + 0x14) -#define FLASH_F4_OPTCR_LOCK 0 -#define FLASH_F4_OPTCR_START 1 -#define FLASH_F4_CR_STRT 16 -#define FLASH_F4_CR_LOCK 31 -#define FLASH_F4_CR_SER 1 -#define FLASH_F4_CR_SNB 3 -#define FLASH_F4_CR_SNB_MASK 0xf8 -#define FLASH_F4_SR_ERROR_MASK 0x000000F0 -#define FLASH_F4_SR_PGAERR 5 -#define FLASH_F4_SR_WRPERR 4 -#define FLASH_F4_SR_BSY 16 - -// STM32F2 -#define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F2_KEYR (FLASH_F2_REGS_ADDR + 0x04) -#define FLASH_F2_OPT_KEYR (FLASH_F2_REGS_ADDR + 0x08) -#define FLASH_F2_SR (FLASH_F2_REGS_ADDR + 0x0c) -#define FLASH_F2_CR (FLASH_F2_REGS_ADDR + 0x10) -#define FLASH_F2_OPT_CR (FLASH_F2_REGS_ADDR + 0x14) -#define FLASH_F2_OPT_LOCK_BIT (1u << 0) -#define FLASH_F2_CR_STRT 16 -#define FLASH_F2_CR_LOCK 31 - -#define FLASH_F2_CR_SER 1 -#define FLASH_F2_CR_SNB 3 -#define FLASH_F2_CR_SNB_MASK 0x78 -#define FLASH_F2_SR_BSY 16 - -// STM32H7xx -#define FLASH_H7_CR_LOCK 0 -#define FLASH_H7_CR_PG 1 -#define FLASH_H7_CR_SER 2 -#define FLASH_H7_CR_BER 3 -#define FLASH_H7_CR_PSIZE 4 -#define FLASH_H7_CR_START(chipid) (chipid == STM32_CHIPID_STM32_H7Ax ? 5 : 7) -#define FLASH_H7_CR_SNB 8 -#define FLASH_H7_CR_SNB_MASK 0x700 - -#define FLASH_H7_SR_QW 2 -#define FLASH_H7_SR_WRPERR 17 -#define FLASH_H7_SR_PGSERR 18 -#define FLASH_H7_SR_STRBERR 19 -#define FLASH_H7_SR_ERROR_MASK \ - ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | \ - (1 << FLASH_H7_SR_WRPERR)) - -#define FLASH_H7_OPTCR_OPTLOCK 0 -#define FLASH_H7_OPTCR_OPTSTART 1 -#define FLASH_H7_OPTCR_MER 4 - -#define FLASH_H7_OPTSR_OPT_BUSY 0 -#define FLASH_H7_OPTSR_OPTCHANGEERR 30 - -#define FLASH_H7_OPTCCR_CLR_OPTCHANGEERR 30 - -#define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) -#define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) -#define FLASH_H7_KEYR2 (FLASH_H7_REGS_ADDR + 0x104) -#define FLASH_H7_OPT_KEYR (FLASH_H7_REGS_ADDR + 0x08) -#define FLASH_H7_OPT_KEYR2 (FLASH_H7_REGS_ADDR + 0x108) -#define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c) -#define FLASH_H7_CR2 (FLASH_H7_REGS_ADDR + 0x10c) -#define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) -#define FLASH_H7_SR2 (FLASH_H7_REGS_ADDR + 0x110) -#define FLASH_H7_CCR1 (FLASH_H7_REGS_ADDR + 0x14) -#define FLASH_H7_CCR2 (FLASH_H7_REGS_ADDR + 0x114) -#define FLASH_H7_OPTCR (FLASH_H7_REGS_ADDR + 0x18) -#define FLASH_H7_OPTCR2 (FLASH_H7_REGS_ADDR + 0x118) -#define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) -#define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) - -#define STM32F0_DBGMCU_CR 0xE0042004 -#define STM32F0_DBGMCU_CR_IWDG_STOP 8 -#define STM32F0_DBGMCU_CR_WWDG_STOP 9 - -#define STM32F4_DBGMCU_APB1FZR1 0xE0042008 -#define STM32F4_DBGMCU_APB1FZR1_WWDG_STOP 11 -#define STM32F4_DBGMCU_APB1FZR1_IWDG_STOP 12 - -#define STM32L0_DBGMCU_APB1_FZ 0x40015808 -#define STM32L0_DBGMCU_APB1_FZ_WWDG_STOP 11 -#define STM32L0_DBGMCU_APB1_FZ_IWDG_STOP 12 - -#define STM32H7_DBGMCU_APB1HFZ 0x5C001054 -#define STM32H7_DBGMCU_APB1HFZ_IWDG_STOP 18 - -#define STM32WB_DBGMCU_APB1FZR1 0xE004203C -#define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11 -#define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12 - -#define STM32F1_RCC_AHBENR 0x40021014 -#define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -#define STM32F4_RCC_AHB1ENR 0x40023830 -#define STM32F4_RCC_DMAEN 0x00600000 // DMA2EN | DMA1EN - -#define STM32G0_RCC_AHBENR 0x40021038 -#define STM32G0_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -#define STM32G4_RCC_AHB1ENR 0x40021048 -#define STM32G4_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -#define STM32L0_RCC_AHBENR 0x40021030 -#define STM32L0_RCC_DMAEN 0x00000001 // DMAEN - -#define STM32H7_RCC_AHB1ENR 0x58024538 -#define STM32H7_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -#define STM32WB_RCC_AHB1ENR 0x58000048 -#define STM32WB_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -#define L1_WRITE_BLOCK_SIZE 0x80 -#define L0_WRITE_BLOCK_SIZE 0x40 + // Endianness // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html @@ -441,16 +64,16 @@ uint16_t read_uint16(const unsigned char *c, const int pt) { static uint32_t get_stm32l0_flash_base(stlink_t *sl) { switch (sl->chip_id) { - case STM32_CHIPID_STM32_L0: - case STM32_CHIPID_STM32_L0_CAT5: - case STM32_CHIPID_STM32_L0_CAT2: - case STM32_CHIPID_STM32_L011: + case STM32_CHIPID_L0: + case STM32_CHIPID_L0_CAT5: + case STM32_CHIPID_L0_CAT2: + case STM32_CHIPID_L011: return (STM32L0_FLASH_REGS_ADDR); - case STM32_CHIPID_STM32_L1_CAT2: - case STM32_CHIPID_STM32_L1_MD: - case STM32_CHIPID_STM32_L1_MD_PLUS: - case STM32_CHIPID_STM32_L1_MD_PLUS_HD: + case STM32_CHIPID_L1_CAT2: + case STM32_CHIPID_L1_MD: + case STM32_CHIPID_L1_MD_PLUS: + case STM32_CHIPID_L1_MD_PLUS_HD: return (STM32L_FLASH_REGS_ADDR); default: @@ -1622,14 +1245,14 @@ int stlink_load_device_params(stlink_t *sl) { flash_size = flash_size & 0xffff; - if ((sl->chip_id == STM32_CHIPID_STM32_L1_MD || - sl->chip_id == STM32_CHIPID_STM32_F1_VL_MD_LD || - sl->chip_id == STM32_CHIPID_STM32_L1_MD_PLUS) && + if ((sl->chip_id == STM32_CHIPID_L1_MD || + sl->chip_id == STM32_CHIPID_F1_VL_MD_LD || + sl->chip_id == STM32_CHIPID_L1_MD_PLUS) && (flash_size == 0)) { sl->flash_size = 128 * 1024; - } else if (sl->chip_id == STM32_CHIPID_STM32_L1_CAT2) { + } else if (sl->chip_id == STM32_CHIPID_L1_CAT2) { sl->flash_size = (flash_size & 0xff) * 1024; - } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_STM32_L1_MD_PLUS_HD) { + } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_L1_MD_PLUS_HD) { // 0 is 384k and 1 is 256k if (flash_size == 0) { sl->flash_size = 384 * 1024; @@ -1651,12 +1274,12 @@ int stlink_load_device_params(stlink_t *sl) { // medium and low devices have the same chipid. ram size depends on flash // size. STM32F100xx datasheet Doc ID 16455 Table 2 - if (sl->chip_id == STM32_CHIPID_STM32_F1_VL_MD_LD && + if (sl->chip_id == STM32_CHIPID_F1_VL_MD_LD && sl->flash_size < 64 * 1024) { sl->sram_size = 0x1000; } - if (sl->chip_id == STM32_CHIPID_STM32_G4_CAT3) { + if (sl->chip_id == STM32_CHIPID_G4_CAT3) { uint32_t flash_optr; stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); @@ -2706,9 +2329,9 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); flashaddr -= STM32_FLASH_BASE; - if (sl->chip_id == STM32_CHIPID_STM32_L4 || - sl->chip_id == STM32_CHIPID_STM32_L496x_L4A6x || - sl->chip_id == STM32_CHIPID_STM32_L4Rx) { + if (sl->chip_id == STM32_CHIPID_L4 || + sl->chip_id == STM32_CHIPID_L496x_L4A6x || + sl->chip_id == STM32_CHIPID_L4Rx) { // this chip use dual banked flash if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { uint32_t banksize = (uint32_t)sl->flash_size / 2; @@ -2726,16 +2349,16 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { - if ((sl->chip_id == STM32_CHIPID_STM32_F2) || - (sl->chip_id == STM32_CHIPID_STM32_F4) || - (sl->chip_id == STM32_CHIPID_STM32_F4_DE) || - (sl->chip_id == STM32_CHIPID_STM32_F4_LP) || - (sl->chip_id == STM32_CHIPID_STM32_F4_HD) || - (sl->chip_id == STM32_CHIPID_STM32_F411xx) || - (sl->chip_id == STM32_CHIPID_STM32_F446) || - (sl->chip_id == STM32_CHIPID_STM32_F4_DSI) || - (sl->chip_id == STM32_CHIPID_STM32_F72xxx) || - (sl->chip_id == STM32_CHIPID_STM32_F412)) { + if ((sl->chip_id == STM32_CHIPID_F2) || + (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_DE) || + (sl->chip_id == STM32_CHIPID_F4_LP) || + (sl->chip_id == STM32_CHIPID_F4_HD) || + (sl->chip_id == STM32_CHIPID_F411xx) || + (sl->chip_id == STM32_CHIPID_F446) || + (sl->chip_id == STM32_CHIPID_F4_DSI) || + (sl->chip_id == STM32_CHIPID_F72xxx) || + (sl->chip_id == STM32_CHIPID_F412)) { uint32_t sector = calculate_F4_sectornum(flashaddr); if (sector >= 12) { @@ -2749,8 +2372,8 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { } else { sl->flash_pgsz = 0x20000; } - } else if (sl->chip_id == STM32_CHIPID_STM32_F7 || - sl->chip_id == STM32_CHIPID_STM32_F76xxx) { + } else if (sl->chip_id == STM32_CHIPID_F7 || + sl->chip_id == STM32_CHIPID_F76xxx) { uint32_t sector = calculate_F7_sectornum(flashaddr); if (sector < 4) { @@ -2785,11 +2408,11 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { unlock_flash_if(sl); // select the page to erase - if ((sl->chip_id == STM32_CHIPID_STM32_L4) || - (sl->chip_id == STM32_CHIPID_STM32_L43x_L44x) || - (sl->chip_id == STM32_CHIPID_STM32_L45x_L46x) || - (sl->chip_id == STM32_CHIPID_STM32_L496x_L4A6x) || - (sl->chip_id == STM32_CHIPID_STM32_L4Rx)) { + if ((sl->chip_id == STM32_CHIPID_L4) || + (sl->chip_id == STM32_CHIPID_L43x_L44x) || + (sl->chip_id == STM32_CHIPID_L45x_L46x) || + (sl->chip_id == STM32_CHIPID_L496x_L4A6x) || + (sl->chip_id == STM32_CHIPID_L4Rx)) { // calculate the actual bank+page from the address uint32_t page = calculate_L4_page(sl, flashaddr); @@ -2797,8 +2420,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { stlink_calculate_pagesize(sl, flashaddr)); write_flash_cr_bker_pnb(sl, page); - } else if (sl->chip_id == STM32_CHIPID_STM32_F7 || - sl->chip_id == STM32_CHIPID_STM32_F76xxx) { + } else if (sl->chip_id == STM32_CHIPID_F7 || + sl->chip_id == STM32_CHIPID_F76xxx) { // calculate the actual page from the address uint32_t sector = calculate_F7_sectornum(flashaddr); @@ -2982,7 +2605,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { unlock_flash_if(sl); if (sl->flash_type == STM32_FLASH_TYPE_H7 && - sl->chip_id != STM32_CHIPID_STM32_H7Ax) { + sl->chip_id != STM32_CHIPID_H7Ax) { // set parallelism write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { @@ -3260,7 +2883,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { set_flash_cr_pg(sl, BANK_2); } - if (sl->chip_id != STM32_CHIPID_STM32_H7Ax) { + if (sl->chip_id != STM32_CHIPID_H7Ax) { // set parallelism write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { @@ -4357,17 +3980,17 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { } switch (sl->chip_id) { - case STM32_CHIPID_STM32_F2: + case STM32_CHIPID_F2: return stlink_read_option_bytes_f2(sl, option_byte); - case STM32_CHIPID_STM32_F4: - case STM32_CHIPID_STM32_F446: + case STM32_CHIPID_F4: + case STM32_CHIPID_F446: return stlink_read_option_bytes_f4(sl, option_byte); - case STM32_CHIPID_STM32_F76xxx: + case STM32_CHIPID_F76xxx: return stlink_read_option_bytes_f7(sl, option_byte); - case STM32_CHIPID_STM32_G0_CAT1: - case STM32_CHIPID_STM32_G0_CAT2: - case STM32_CHIPID_STM32_G4_CAT2: - case STM32_CHIPID_STM32_G4_CAT3: + case STM32_CHIPID_G0_CAT1: + case STM32_CHIPID_G0_CAT2: + case STM32_CHIPID_G4_CAT2: + case STM32_CHIPID_G4_CAT3: return stlink_read_option_bytes_Gx(sl, option_byte); default: return stlink_read_option_bytes_generic(sl, option_byte); diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 19819a6cb..2b6875d9f 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -553,39 +553,39 @@ char* make_memory_map(stlink_t *sl) { char* map = malloc(sz); map[0] = '\0'; - if (sl->chip_id == STM32_CHIPID_STM32_F4 || - sl->chip_id == STM32_CHIPID_STM32_F446 || - sl->chip_id == STM32_CHIPID_STM32_F411xx) { + if (sl->chip_id == STM32_CHIPID_F4 || + sl->chip_id == STM32_CHIPID_F446 || + sl->chip_id == STM32_CHIPID_F411xx) { strcpy(map, memory_map_template_F4); - } else if (sl->chip_id == STM32_CHIPID_STM32_F4_DE) { + } else if (sl->chip_id == STM32_CHIPID_F4_DE) { strcpy(map, memory_map_template_F4_DE); } else if (sl->core_id == STM32_CORE_ID_M7_F7) { snprintf(map, sz, memory_map_template_F7, (unsigned int)sl->sram_size); - } else if (sl->chip_id == STM32_CHIPID_STM32_H74xxx) { + } else if (sl->chip_id == STM32_CHIPID_H74xxx) { snprintf(map, sz, memory_map_template_H7, (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz); - } else if (sl->chip_id == STM32_CHIPID_STM32_F4_HD) { + } else if (sl->chip_id == STM32_CHIPID_F4_HD) { strcpy(map, memory_map_template_F4_HD); - } else if (sl->chip_id == STM32_CHIPID_STM32_F2) { + } else if (sl->chip_id == STM32_CHIPID_F2) { snprintf(map, sz, memory_map_template_F2, (unsigned int)sl->flash_size, (unsigned int)sl->sram_size, (unsigned int)sl->flash_size - 0x20000, (unsigned int)sl->sys_base, (unsigned int)sl->sys_size); - } else if ((sl->chip_id == STM32_CHIPID_STM32_L4) || - (sl->chip_id == STM32_CHIPID_STM32_L43x_L44x) || - (sl->chip_id == STM32_CHIPID_STM32_L45x_L46x)) { + } else if ((sl->chip_id == STM32_CHIPID_L4) || + (sl->chip_id == STM32_CHIPID_L43x_L44x) || + (sl->chip_id == STM32_CHIPID_L45x_L46x)) { snprintf(map, sz, memory_map_template_L4, (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); - } else if (sl->chip_id == STM32_CHIPID_STM32_L496x_L4A6x) { + } else if (sl->chip_id == STM32_CHIPID_L496x_L4A6x) { snprintf(map, sz, memory_map_template_L496, (unsigned int)sl->flash_size, (unsigned int)sl->flash_size); - } else if (sl->chip_id == STM32_CHIPID_STM32_H72x) { + } else if (sl->chip_id == STM32_CHIPID_H72x) { snprintf(map, sz, memory_map_template_H72x3x, (unsigned int)sl->flash_size, (unsigned int)sl->flash_pgsz); diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 78233ec1c..c8147229b 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -9,18 +9,6 @@ #include -// struct stlink_chipid_params *stlink_chipid_get_params_old(uint32_t chipid) { -// struct stlink_chipid_params *params = NULL; - -// for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) -// if (devices[n].chip_id == chipid) { -// params = &devices[n]; -// break; -// } - -// return (params); -// } - static struct stlink_chipid_params *devicelist; void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { @@ -39,22 +27,6 @@ void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { fprintf(fp, "flags %d\n\n", dev->flags); } -// static int chipid_params_eq(const struct stlink_chipid_params *p1, const struct stlink_chipid_params *p2) -// { -// return p1->chip_id == p2->chip_id && -// p1->dev_type && p2->dev_type && -// strcmp(p1->dev_type, p2->dev_type) == 0 && -// p1->flash_type == p2->flash_type && -// p1->flash_size_reg == p2->flash_size_reg && -// p1->flash_pagesize == p2->flash_pagesize && -// p1->sram_size == p2->sram_size && -// p1->bootrom_base == p2->bootrom_base && -// p1->bootrom_size == p2->bootrom_size && -// p1->option_base == p2->option_base && -// p1->option_size == p2->option_size && -// p1->flags == p2->flags; -// } - struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chip_id) { struct stlink_chipid_params *params = NULL; // struct stlink_chipid_params *p2; @@ -65,20 +37,6 @@ struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chip_id) { break; } -// p2 = stlink_chipid_get_params_old(chipid); - -// #if 1 -// if (params == NULL) { -// params = p2; -// } else if (!chipid_params_eq(params, p2)) { -// // fprintf (stderr, "Error, chipid params not identical\n"); -// // return NULL; -// fprintf(stderr, "---------- old ------------\n"); -// dump_a_chip(stderr, p2); -// fprintf(stderr, "---------- new ------------\n"); -// dump_a_chip(stderr, params); -// } -// #endif return(params); } @@ -187,38 +145,6 @@ void process_chipfile(char *fname) { devicelist = ts; } -// void dump_chips (void) { -// struct stlink_chipid_params *ts; -// char *p, buf[100]; -// FILE *fp; - -// for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) { -// ts = &devices[n]; - -// strcpy(buf, ts->dev_type); - -// while ((p = strchr(buf, '/'))) // change slashes to underscore. -// *p = '_'; - -// strcat(buf, ".chip"); -// fp = fopen(buf, "w"); -// fprintf(fp, "# Device Type: %s\n", ts->dev_type); -// fprintf(fp, "# Reference Manual: RM%s\n", ts->ref_manual_id); -// fprintf(fp, "#\n"); -// fprintf(fp, "chip_id %x\n", ts->chip_id); -// fprintf(fp, "flash_type %x\n", ts->flash_type); -// fprintf(fp, "flash_size_reg %x\n", ts->flash_size_reg); -// fprintf(fp, "flash_pagesize %x\n", ts->flash_pagesize); -// fprintf(fp, "sram_size %x\n", ts->sram_size); -// fprintf(fp, "bootrom_base %x\n", ts->bootrom_base); -// fprintf(fp, "bootrom_size %x\n", ts->bootrom_size); -// fprintf(fp, "option_base %x\n", ts->option_base); -// fprintf(fp, "option_size %x\n", ts->option_size); -// fprintf(fp, "flags %x\n\n", ts->flags); -// fclose(fp); -// } -// } - #if defined(STLINK_HAVE_DIRENT_H) #include void init_chipids(char *dir_to_scan) { diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index 86cd49ddb..8efcd653e 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -4,9 +4,6 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /** Chipid parametres */ struct stlink_chipid_params { @@ -28,8 +25,5 @@ struct stlink_chipid_params { struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); void init_chipids(char *dir_to_scan); -#ifdef __cplusplus -} -#endif #endif // STLINK_CHIPID_H_ diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index ad52d6567..92b6f0f4b 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -234,43 +234,43 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* const uint8_t* loader_code; size_t loader_size; - if (sl->chip_id == STM32_CHIPID_STM32_L1_MD || - sl->chip_id == STM32_CHIPID_STM32_L1_CAT2 || - sl->chip_id == STM32_CHIPID_STM32_L1_MD_PLUS || - sl->chip_id == STM32_CHIPID_STM32_L1_MD_PLUS_HD || - sl->chip_id == STM32_CHIPID_STM32_L152_RE || - sl->chip_id == STM32_CHIPID_STM32_L011 || - sl->chip_id == STM32_CHIPID_STM32_L0 || - sl->chip_id == STM32_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STM32_CHIPID_STM32_L0_CAT2) { + if (sl->chip_id == STM32_CHIPID_L1_MD || + sl->chip_id == STM32_CHIPID_L1_CAT2 || + sl->chip_id == STM32_CHIPID_L1_MD_PLUS || + sl->chip_id == STM32_CHIPID_L1_MD_PLUS_HD || + sl->chip_id == STM32_CHIPID_L152_RE || + sl->chip_id == STM32_CHIPID_L011 || + sl->chip_id == STM32_CHIPID_L0 || + sl->chip_id == STM32_CHIPID_L0_CAT5 || + sl->chip_id == STM32_CHIPID_L0_CAT2) { loader_code = loader_code_stm32lx; loader_size = sizeof(loader_code_stm32lx); } else if (sl->core_id == STM32_CORE_ID_M3_F1 || - sl->chip_id == STM32_CHIPID_STM32_F1_MD || - sl->chip_id == STM32_CHIPID_STM32_F1_HD || - sl->chip_id == STM32_CHIPID_STM32_F1_LD || - sl->chip_id == STM32_CHIPID_STM32_F1_VL_MD_LD || - sl->chip_id == STM32_CHIPID_STM32_F1_VL_HD || - sl->chip_id == STM32_CHIPID_STM32_F1_XLD || - sl->chip_id == STM32_CHIPID_STM32_F1_CONN || - sl->chip_id == STM32_CHIPID_STM32_F3 || - sl->chip_id == STM32_CHIPID_STM32_F3xx_SMALL || - sl->chip_id == STM32_CHIPID_STM32_F303_HD || - sl->chip_id == STM32_CHIPID_STM32_F37x || - sl->chip_id == STM32_CHIPID_STM32_F334) { + sl->chip_id == STM32_CHIPID_F1_MD || + sl->chip_id == STM32_CHIPID_F1_HD || + sl->chip_id == STM32_CHIPID_F1_LD || + sl->chip_id == STM32_CHIPID_F1_VL_MD_LD || + sl->chip_id == STM32_CHIPID_F1_VL_HD || + sl->chip_id == STM32_CHIPID_F1_XLD || + sl->chip_id == STM32_CHIPID_F1_CONN || + sl->chip_id == STM32_CHIPID_F3 || + sl->chip_id == STM32_CHIPID_F3xx_SMALL || + sl->chip_id == STM32_CHIPID_F303_HD || + sl->chip_id == STM32_CHIPID_F37x || + sl->chip_id == STM32_CHIPID_F334) { loader_code = loader_code_stm32vl; loader_size = sizeof(loader_code_stm32vl); - } else if (sl->chip_id == STM32_CHIPID_STM32_F2 || - sl->chip_id == STM32_CHIPID_STM32_F4 || - sl->chip_id == STM32_CHIPID_STM32_F4_DE || - sl->chip_id == STM32_CHIPID_STM32_F4_LP || - sl->chip_id == STM32_CHIPID_STM32_F4_HD || - sl->chip_id == STM32_CHIPID_STM32_F4_DSI || - sl->chip_id == STM32_CHIPID_STM32_F410 || - sl->chip_id == STM32_CHIPID_STM32_F411xx || - sl->chip_id == STM32_CHIPID_STM32_F412 || - sl->chip_id == STM32_CHIPID_STM32_F413 || - sl->chip_id == STM32_CHIPID_STM32_F446) { + } else if (sl->chip_id == STM32_CHIPID_F2 || + sl->chip_id == STM32_CHIPID_F4 || + sl->chip_id == STM32_CHIPID_F4_DE || + sl->chip_id == STM32_CHIPID_F4_LP || + sl->chip_id == STM32_CHIPID_F4_HD || + sl->chip_id == STM32_CHIPID_F4_DSI || + sl->chip_id == STM32_CHIPID_F410 || + sl->chip_id == STM32_CHIPID_F411xx || + sl->chip_id == STM32_CHIPID_F412 || + sl->chip_id == STM32_CHIPID_F413 || + sl->chip_id == STM32_CHIPID_F446) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, @@ -279,9 +279,9 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* if (retval == -1) { return(retval); } } else if (sl->core_id == STM32_CORE_ID_M7_F7 || - sl->chip_id == STM32_CHIPID_STM32_F7 || - sl->chip_id == STM32_CHIPID_STM32_F76xxx || - sl->chip_id == STM32_CHIPID_STM32_F72xxx) { + sl->chip_id == STM32_CHIPID_F7 || + sl->chip_id == STM32_CHIPID_F76xxx || + sl->chip_id == STM32_CHIPID_F72xxx) { int retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, @@ -289,19 +289,19 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code_stm32f7_lv, sizeof(loader_code_stm32f7_lv)); if (retval == -1) { return(retval); } - } else if (sl->chip_id == STM32_CHIPID_STM32_F0 || - sl->chip_id == STM32_CHIPID_STM32_F04 || - sl->chip_id == STM32_CHIPID_STM32_F0_CAN || - sl->chip_id == STM32_CHIPID_STM32_F0xx_SMALL || - sl->chip_id == STM32_CHIPID_STM32_F09x) { + } else if (sl->chip_id == STM32_CHIPID_F0 || + sl->chip_id == STM32_CHIPID_F04 || + sl->chip_id == STM32_CHIPID_F0_CAN || + sl->chip_id == STM32_CHIPID_F0xx_SMALL || + sl->chip_id == STM32_CHIPID_F09x) { loader_code = loader_code_stm32f0; loader_size = sizeof(loader_code_stm32f0); - } else if ((sl->chip_id == STM32_CHIPID_STM32_L4) || - (sl->chip_id == STM32_CHIPID_STM32_L41x_L42x) || - (sl->chip_id == STM32_CHIPID_STM32_L43x_L44x) || - (sl->chip_id == STM32_CHIPID_STM32_L45x_L46x) || - (sl->chip_id == STM32_CHIPID_STM32_L4Rx) || - (sl->chip_id == STM32_CHIPID_STM32_L496x_L4A6x)) { + } else if ((sl->chip_id == STM32_CHIPID_L4) || + (sl->chip_id == STM32_CHIPID_L41x_L42x) || + (sl->chip_id == STM32_CHIPID_L43x_L44x) || + (sl->chip_id == STM32_CHIPID_L45x_L46x) || + (sl->chip_id == STM32_CHIPID_L4Rx) || + (sl->chip_id == STM32_CHIPID_L496x_L4A6x)) { loader_code = loader_code_stm32l4; loader_size = sizeof(loader_code_stm32l4); } else { diff --git a/src/stlink-lib/flash_loader.h b/src/stlink-lib/flash_loader.h index 29fd5b068..bac99bdb4 100644 --- a/src/stlink-lib/flash_loader.h +++ b/src/stlink-lib/flash_loader.h @@ -12,16 +12,10 @@ #include -#ifdef __cplusplus -extern "C" { -#endif int stlink_flash_loader_init(stlink_t *sl, flash_loader_t* fl); int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size); -#ifdef __cplusplus -} -#endif #endif // STLINK_FLASH_LOADER_H_ diff --git a/src/stlink-lib/sg.h b/src/stlink-lib/sg.h index f34b2e122..4161d3967 100644 --- a/src/stlink-lib/sg.h +++ b/src/stlink-lib/sg.h @@ -9,9 +9,6 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /* Device access */ #define RDWR 0 @@ -60,8 +57,5 @@ struct stlink_libsg { stlink_t* stlink_v1_open(const int verbose, int reset); -#ifdef __cplusplus -} -#endif #endif // STLINK_SG_H diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index c6b71ba4e..d04ef2dca 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -12,9 +12,6 @@ #include #include "logging.h" -#ifdef __cplusplus -extern "C" { -#endif #define STLINK_USB_VID_ST 0x0483 #define STLINK_USB_PID_STLINK 0x3744 @@ -73,8 +70,5 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int freq); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); -#ifdef __cplusplus -} -#endif #endif // STLINK_USB_H diff --git a/src/win32/mmap.h b/src/win32/mmap.h index 1f2e756cb..67558b0cc 100644 --- a/src/win32/mmap.h +++ b/src/win32/mmap.h @@ -13,16 +13,10 @@ #define MAP_ANONYMOUS (1 << 5) #define MAP_FAILED ((void *)-1) -#ifdef __cplusplus -extern "C" { -#endif void *mmap(void *addr, size_t len, int prot, int flags, int fd, long long offset); int munmap(void *addr, size_t len); -#ifdef __cplusplus -} -#endif #endif /* HAVE_SYS_MMAN_H */ diff --git a/src/win32/sys_time.h b/src/win32/sys_time.h index 39f97f739..3f35390c3 100644 --- a/src/win32/sys_time.h +++ b/src/win32/sys_time.h @@ -12,15 +12,8 @@ struct timezone { int tz_dsttime; }; -#ifdef __cplusplus -extern "C" { -#endif - int gettimeofday(struct timeval *tv, struct timezone *tz); -#ifdef __cplusplus -} -#endif #endif /* STLINK_HAVE_SYS_TIME_H */ From a5d644160b071fb0ef8f79d38043a3c1299ee750 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 16 Jan 2022 20:28:53 +0100 Subject: [PATCH 1288/1435] Fixed define names and removed old include. --- src/common.c | 4 ++-- src/stlink-lib/chipid.c | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/common.c b/src/common.c index 1a6c89c63..08f2c5dc1 100644 --- a/src/common.c +++ b/src/common.c @@ -2645,8 +2645,8 @@ int stlink_erase_flash_mass(stlink_t *sl) { int err = 0; // TODO: User MER bit to mass-erase WB series. - if (sl->flash_type == STLINK_FLASH_TYPE_L0_L1 || - sl->flash_type == STLINK_FLASH_TYPE_WB_WL) { + if (sl->flash_type == STM32_FLASH_TYPE_L0_L1 || + sl->flash_type == STM32_FLASH_TYPE_WB_WL) { err = stlink_erase_flash_section(sl, sl->flash_base, sl->flash_size, false); diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index c8147229b..dbfd2882d 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1,6 +1,5 @@ #include #include "chipid.h" -//#include "chipid_db_old.h" #include #include From 80b05c547e34a214ffd9171e600051e8474a9f0a Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 17 Jan 2022 00:39:57 +0100 Subject: [PATCH 1289/1435] Updated MCU core-ids --- inc/stm32.h | 52 +++++++++++++++++++++++++---------- src/common.c | 2 +- src/st-util/gdb-server.c | 2 +- src/stlink-lib/flash_loader.c | 4 +-- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/inc/stm32.h b/inc/stm32.h index 2e8ed6889..56176bd6f 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -7,20 +7,44 @@ #ifndef STM32_H #define STM32_H -/* Cortex-M core ids (CPUTAPID) */ -#define STM32_CORE_ID_M3_F2_JTAG 0x0ba00477 // unused // F2 JTAG (RM0033 p.1326) -//#define STM32_CORE_ID_M33_JTAG 0x0ba04477 // unused // L5 JTAG -#define STM32_CORE_ID_M0 0x0bb11477 // unused // F0 -#define STM32_CORE_ID_M0P 0x0bc11477 // unused // L0, G0 -#define STM32_CORE_ID_M33 0x0be01477 // unused // L5 SWD (RM0351 p.2029) -#define STM32_CORE_ID_M33_JTAG 0x0be02477 // unused // L5 JTAG (RM0438 p.2029) -#define STM32_CORE_ID_M3_F1 0x1ba01477 // F1 (RM0008 p.1092) -#define STM32_CORE_ID_M4F_L4 0x1ba01477 // unused // L4 (RM0351 p.1845) -#define STM32_CORE_ID_M4F_F4 0x2ba01477 // unused // F4 (RM0090 p.1695) -#define STM32_CORE_ID_M4F_F4_JTAG 0x4ba00477 // unused // F4 JTAG (RM090 p.1691) -#define STM32_CORE_ID_M7_F7 0x5ba02477 // F7 -#define STM32_CORE_ID_M7_H7 0x6ba02477 // H7 -#define STM32_CORE_ID_M7_H7_JTAG 0x6ba00477 // H7 JTAG (RM0433 p.3065) +/* STM32 Cortex-M core ids (CPUTAPID) */ +#define STM32_CORE_ID_M0_SWD 0x0bb11477 // (RM0091 Section 32.5.3) F0 SW-DP + // (RM0444 Section 40.5.3) G0 SW-DP + +#define STM32_CORE_ID_M0P_SWD 0x0bc11477 // (RM0385 Section 27.5.3) L0 SW-DP + +#define STM32_CORE_ID_M3_r1p1_SWD 0x1ba01477 // (RM0008 Section 31.8.3) F1 SW-DP +#define STM32_CORE_ID_M3_r1p1_JTAG 0x3ba00477 // (RM0008 Section 31.6.3) F1 JTAG + +#define STM32_CORE_ID_M3_r2p0_SWD 0x2ba01477 // (RM0033 Section 32.8.3) F2 SW-DP + // (RM0038 Section 30.8.3) L1 SW-DP +#define STM32_CORE_ID_M3_r2p0_JTAG 0x0ba00477 // (RM0033 Section 32.6.3) F2 JTAG + // (RM0038 Section 30.6.2) L1 JTAG + +#define STM32_CORE_ID_M4_r0p1_SWD 0x1ba01477 // (RM0316 Section 33.8.3) F3 SW-DP + // (RM0351 Section 48.8.3) L4 SW-DP + // (RM0432 Section 57.8.3) L4+ SW-DP +#define STM32_CORE_ID_M4_r0p1_JTAG 0x4ba00477 // (RM0316 Section 33.6.3) F3 JTAG + // (RM0351 Section 48.6.3) L4 JTAG + // (RM0432 Section 57.6.3) L4+ JTAG + +#define STM32_CORE_ID_M4F_r0p1_SWD 0x2ba01477 // (RM0090 Section 38.8.3) F4 SW-DP + // (RM0090 Section 47.8.3) G4 SW-DP +#define STM32_CORE_ID_M4F_r0p1_JTAG 0x4ba00477 // (RM0090 Section 38.6.3) F4 JTAG + // (RM0090 Section 47.6.3) G4 JTAG + +#define STM32_CORE_ID_M7F_SWD 0x5ba02477 // (RM0385 Section 40.8.3) F7 SW-DP +#define STM32_CORE_ID_M7F_JTAG 0x5ba00477 // (RM0385 Section 40.6.3) F7 JTAG + +#define STM32_CORE_ID_M7F_H7_SWD 0x6ba02477 // (RM0433 Section 60.4.1) H7 SW-DP +#define STM32_CORE_ID_M7F_H7_JTAG 0x6ba00477 // (RM0433 Section 60.4.1) H7 JTAG + +#define STM32_CORE_ID_M33_SWD 0x0be02477 // (RM0438 Section 52.2.10) L5 SW-DP + // (RM0456 Section 65.3.3) U5 SW-DP +#define STM32_CORE_ID_M33_JTAGD 0x0be01477 // (RM0438 Section 52.2.10) L5 JTAG-DP + // (RM0456 Section 65.3.3) U5 JTAG-DP +#define STM32_CORE_ID_M33_JTAG 0x0ba04477 // (RM0438 Section 52.2.8) L5 JTAG + // (RM0456 Section 56.3.1) U5 JTAG /* STM32 flash types */ // New flash type definitions must go before STM32_FLASH_TYPE_UNDEFINED diff --git a/src/common.c b/src/common.c index 08f2c5dc1..266722b91 100644 --- a/src/common.c +++ b/src/common.c @@ -1137,7 +1137,7 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { * */ - if ((sl->core_id == STM32_CORE_ID_M7_H7 || sl->core_id == STM32_CORE_ID_M7_H7_JTAG) && + if ((sl->core_id == STM32_CORE_ID_M7F_H7_SWD || sl->core_id == STM32_CORE_ID_M7F_H7_JTAG) && cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) ret = stlink_read_debug32(sl, 0x5c001000, chip_id); diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 2b6875d9f..4f7a1fe2e 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -559,7 +559,7 @@ char* make_memory_map(stlink_t *sl) { strcpy(map, memory_map_template_F4); } else if (sl->chip_id == STM32_CHIPID_F4_DE) { strcpy(map, memory_map_template_F4_DE); - } else if (sl->core_id == STM32_CORE_ID_M7_F7) { + } else if (sl->core_id == STM32_CORE_ID_M7F_SWD) { snprintf(map, sz, memory_map_template_F7, (unsigned int)sl->sram_size); } else if (sl->chip_id == STM32_CHIPID_H74xxx) { diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 92b6f0f4b..2b47c1114 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -245,7 +245,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STM32_CHIPID_L0_CAT2) { loader_code = loader_code_stm32lx; loader_size = sizeof(loader_code_stm32lx); - } else if (sl->core_id == STM32_CORE_ID_M3_F1 || + } else if (sl->core_id == STM32_CORE_ID_M3_r1p1_SWD || sl->chip_id == STM32_CHIPID_F1_MD || sl->chip_id == STM32_CHIPID_F1_HD || sl->chip_id == STM32_CHIPID_F1_LD || @@ -278,7 +278,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* loader_code_stm32f4_lv, sizeof(loader_code_stm32f4_lv)); if (retval == -1) { return(retval); } - } else if (sl->core_id == STM32_CORE_ID_M7_F7 || + } else if (sl->core_id == STM32_CORE_ID_M7F_SWD || sl->chip_id == STM32_CHIPID_F7 || sl->chip_id == STM32_CHIPID_F76xxx || sl->chip_id == STM32_CHIPID_F72xxx) { From e5ff479d4829843d04fe51931256ac095ad4c0b8 Mon Sep 17 00:00:00 2001 From: hydroconstructor Date: Thu, 20 Jan 2022 12:54:14 +0400 Subject: [PATCH 1290/1435] #1216 refactoring of common.c File divided to some parts. Functions with "flash" in names extracted to common_flash.c, with "option" extracted to option.c etc. Removed unnecessary headers. Removed one single function which was used nowhere. And so on. Project built under Windows and seems to be working. --- CMakeLists.txt | 10 +- inc/stlink.h | 6 +- inc/stm32flash.h | 340 +++++++++++ src/calculate.c | 74 +++ src/calculate.h | 15 + src/common.h | 15 + src/common_flash.c | 1374 ++++++++++++++++++++++++++++++++++++++++++++ src/common_flash.h | 27 + src/flashloader.c | 481 ++++++++++++++++ src/map_file.c | 57 ++ src/map_file.h | 28 + src/option.c | 1026 +++++++++++++++++++++++++++++++++ src/read_write.c | 142 +++++ 13 files changed, 3592 insertions(+), 3 deletions(-) create mode 100644 inc/stm32flash.h create mode 100644 src/calculate.c create mode 100644 src/calculate.h create mode 100644 src/common.h create mode 100644 src/common_flash.c create mode 100644 src/common_flash.h create mode 100644 src/flashloader.c create mode 100644 src/map_file.c create mode 100644 src/map_file.h create mode 100644 src/option.c create mode 100644 src/read_write.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 66bf34e3e..a3338df71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # General cmake settings ### -cmake_minimum_required(VERSION 3.10.2) +cmake_minimum_required(VERSION 3.7.2) cmake_policy(SET CMP0042 NEW) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) @@ -110,6 +110,8 @@ add_subdirectory(inc) set(STLINK_HEADERS inc/backend.h inc/stlink.h + src/common_flash.h + src/calculate.h src/stlink-lib/commands.h src/stlink-lib/libusb_settings.h src/stlink-lib/reg.h @@ -123,7 +125,13 @@ set(STLINK_HEADERS ) set(STLINK_SOURCE + src/read_write.c src/common.c + src/option.c + src/common_flash.c + src/map_file.c + src/flashloader.c + src/calculate.c src/stlink-lib/chipid.c src/stlink-lib/flash_loader.c src/stlink-lib/logging.c diff --git a/inc/stlink.h b/inc/stlink.h index df13aa7c9..a8a52458d 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -1,3 +1,4 @@ + /* * File: stlink.h * @@ -13,6 +14,7 @@ #include #include "stm32.h" +#include "stm32flash.h" #ifdef __cplusplus extern "C" { @@ -284,7 +286,7 @@ int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, stm32_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); -int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); +//int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); @@ -292,7 +294,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); int stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size); int stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr); uint16_t read_uint16(const unsigned char *c, const int pt); -void stlink_core_stat(stlink_t *sl); +//void stlink_core_stat(stlink_t *sl); void stlink_print_data(stlink_t *sl); unsigned int is_bigendian(void); uint32_t read_uint32(const unsigned char *c, const int pt); diff --git a/inc/stm32flash.h b/inc/stm32flash.h new file mode 100644 index 000000000..01c76946c --- /dev/null +++ b/inc/stm32flash.h @@ -0,0 +1,340 @@ +#ifndef STM32FLASH_H +#define STM32FLASH_H + +/* stm32f FPEC flash controller interface, pm0063 manual */ +// TODO - all of this needs to be abstracted out.... +// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, +// August 2012) +#define FLASH_REGS_ADDR 0x40022000 +#define FLASH_REGS_SIZE 0x28 + +#define FLASH_ACR (FLASH_REGS_ADDR + 0x00) +#define FLASH_KEYR (FLASH_REGS_ADDR + 0x04) +#define FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x08) +#define FLASH_SR (FLASH_REGS_ADDR + 0x0c) +#define FLASH_CR (FLASH_REGS_ADDR + 0x10) +#define FLASH_AR (FLASH_REGS_ADDR + 0x14) +#define FLASH_OBR (FLASH_REGS_ADDR + 0x1c) +#define FLASH_WRPR (FLASH_REGS_ADDR + 0x20) + +// STM32F10x_XL has two flash memory banks with separate registers to control +// the second bank. +#define FLASH_KEYR2 (FLASH_REGS_ADDR + 0x44) +#define FLASH_SR2 (FLASH_REGS_ADDR + 0x4c) +#define FLASH_CR2 (FLASH_REGS_ADDR + 0x50) +#define FLASH_AR2 (FLASH_REGS_ADDR + 0x54) + +// For STM32F05x, the RDPTR_KEY may be wrong, but as it is not used anywhere... +#define FLASH_RDPTR_KEY 0x00a5 +#define FLASH_KEY1 0x45670123 +#define FLASH_KEY2 0xcdef89ab + +#define FLASH_L0_PRGKEY1 0x8c9daebf +#define FLASH_L0_PRGKEY2 0x13141516 + +#define FLASH_L0_PEKEY1 0x89abcdef +#define FLASH_L0_PEKEY2 0x02030405 + +#define FLASH_OPTKEY1 0x08192A3B +#define FLASH_OPTKEY2 0x4C5D6E7F + +#define FLASH_F0_OPTKEY1 0x45670123 +#define FLASH_F0_OPTKEY2 0xCDEF89AB + +#define FLASH_L0_OPTKEY1 0xFBEAD9C8 +#define FLASH_L0_OPTKEY2 0x24252627 + +#define FLASH_SR_BSY 0 +#define FLASH_SR_PG_ERR 2 +#define FLASH_SR_WRPRT_ERR 4 +#define FLASH_SR_EOP 5 + +#define FLASH_SR_ERROR_MASK ((1 << FLASH_SR_PG_ERR) | (1 << FLASH_SR_WRPRT_ERR)) + +#define FLASH_CR_PG 0 +#define FLASH_CR_PER 1 +#define FLASH_CR_MER 2 +#define FLASH_CR_OPTPG 4 +#define FLASH_CR_OPTER 5 +#define FLASH_CR_STRT 6 +#define FLASH_CR_LOCK 7 +#define FLASH_CR_OPTWRE 9 +#define FLASH_CR_OBL_LAUNCH 13 + +#define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00) +#define STM32L_FLASH_ACR (STM32L_FLASH_REGS_ADDR + 0x00) +#define STM32L_FLASH_PECR (STM32L_FLASH_REGS_ADDR + 0x04) +#define STM32L_FLASH_PDKEYR (STM32L_FLASH_REGS_ADDR + 0x08) +#define STM32L_FLASH_PEKEYR (STM32L_FLASH_REGS_ADDR + 0x0c) +#define STM32L_FLASH_PRGKEYR (STM32L_FLASH_REGS_ADDR + 0x10) +#define STM32L_FLASH_OPTKEYR (STM32L_FLASH_REGS_ADDR + 0x14) +#define STM32L_FLASH_SR (STM32L_FLASH_REGS_ADDR + 0x18) +#define STM32L_FLASH_OBR (STM32L_FLASH_REGS_ADDR + 0x1c) +#define STM32L_FLASH_WRPR (STM32L_FLASH_REGS_ADDR + 0x20) +#define FLASH_L1_FPRG 10 +#define FLASH_L1_PROG 3 + +// Flash registers common to STM32G0 and STM32G4 series. +#define STM32Gx_FLASH_REGS_ADDR ((uint32_t)0x40022000) +#define STM32Gx_FLASH_ACR (STM32Gx_FLASH_REGS_ADDR + 0x00) +#define STM32Gx_FLASH_KEYR (STM32Gx_FLASH_REGS_ADDR + 0x08) +#define STM32Gx_FLASH_OPTKEYR (STM32Gx_FLASH_REGS_ADDR + 0x0c) +#define STM32Gx_FLASH_SR (STM32Gx_FLASH_REGS_ADDR + 0x10) +#define STM32Gx_FLASH_CR (STM32Gx_FLASH_REGS_ADDR + 0x14) +#define STM32Gx_FLASH_ECCR (STM32Gx_FLASH_REGS_ADDR + 0x18) +#define STM32Gx_FLASH_OPTR (STM32Gx_FLASH_REGS_ADDR + 0x20) + +// G0 (RM0444 Table 1, sec 3.7) +// Mostly the same as G4 chips, but the notation +// varies a bit after the 'OPTR' register. +#define STM32G0_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) +#define STM32G0_FLASH_PCROP1ASR (STM32G0_FLASH_REGS_ADDR + 0x24) +#define STM32G0_FLASH_PCROP1AER (STM32G0_FLASH_REGS_ADDR + 0x28) +#define STM32G0_FLASH_WRP1AR (STM32G0_FLASH_REGS_ADDR + 0x2C) +#define STM32G0_FLASH_WRP1BR (STM32G0_FLASH_REGS_ADDR + 0x30) +#define STM32G0_FLASH_PCROP1BSR (STM32G0_FLASH_REGS_ADDR + 0x34) +#define STM32G0_FLASH_PCROP1BER (STM32G0_FLASH_REGS_ADDR + 0x38) +#define STM32G0_FLASH_SECR (STM32G0_FLASH_REGS_ADDR + 0x80) + +// G4 (RM0440 Table 17, sec 3.7.19) +// Mostly the same as STM32G0 chips, but there are a few extra +// registers because 'cat 3' devices can have two Flash banks. +#define STM32G4_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) +#define STM32G4_FLASH_PDKEYR (STM32G4_FLASH_REGS_ADDR + 0x04) +#define STM32G4_FLASH_PCROP1SR (STM32G4_FLASH_REGS_ADDR + 0x24) +#define STM32G4_FLASH_PCROP1ER (STM32G4_FLASH_REGS_ADDR + 0x28) +#define STM32G4_FLASH_WRP1AR (STM32G4_FLASH_REGS_ADDR + 0x2C) +#define STM32G4_FLASH_WRP1BR (STM32G4_FLASH_REGS_ADDR + 0x30) +#define STM32G4_FLASH_PCROP2SR (STM32G4_FLASH_REGS_ADDR + 0x44) +#define STM32G4_FLASH_PCROP2ER (STM32G4_FLASH_REGS_ADDR + 0x48) +#define STM32G4_FLASH_WRP2AR (STM32G4_FLASH_REGS_ADDR + 0x4C) +#define STM32G4_FLASH_WRP2BR (STM32G4_FLASH_REGS_ADDR + 0x50) +#define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70) +#define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74) + +// G0/G4 FLASH control register +#define STM32Gx_FLASH_CR_PG (0) /* Program */ +#define STM32Gx_FLASH_CR_PER (1) /* Page erase */ +#define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */ +#define STM32Gx_FLASH_CR_PNB (3) /* Page number */ +#define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ +#define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ +#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ +#define STM32Gx_FLASH_CR_STRT (16) /* Start */ +#define STM32Gx_FLASH_CR_OPTSTRT \ + (17) /* Start of modification of option bytes */ +#define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ +#define STM32Gx_FLASH_CR_EOPIE (24) /* End of operation interrupt enable */ +#define STM32Gx_FLASH_CR_ERRIE (25) /* Error interrupt enable */ +#define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ +#define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ +#define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ + +// G0/G4 FLASH status register +#define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) +#define STM32Gx_FLASH_SR_PROGERR (3) +#define STM32Gx_FLASH_SR_WRPERR (4) +#define STM32Gx_FLASH_SR_PGAERR (5) +#define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ +#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ + +// G4 FLASH option register +#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ + +// WB (RM0434) +#define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) +#define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) +#define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) +#define STM32WB_FLASH_OPT_KEYR (STM32WB_FLASH_REGS_ADDR + 0x0C) +#define STM32WB_FLASH_SR (STM32WB_FLASH_REGS_ADDR + 0x10) +#define STM32WB_FLASH_CR (STM32WB_FLASH_REGS_ADDR + 0x14) +#define STM32WB_FLASH_ECCR (STM32WB_FLASH_REGS_ADDR + 0x18) +#define STM32WB_FLASH_OPTR (STM32WB_FLASH_REGS_ADDR + 0x20) +#define STM32WB_FLASH_PCROP1ASR (STM32WB_FLASH_REGS_ADDR + 0x24) +#define STM32WB_FLASH_PCROP1AER (STM32WB_FLASH_REGS_ADDR + 0x28) +#define STM32WB_FLASH_WRP1AR (STM32WB_FLASH_REGS_ADDR + 0x2C) +#define STM32WB_FLASH_WRP1BR (STM32WB_FLASH_REGS_ADDR + 0x30) +#define STM32WB_FLASH_PCROP1BSR (STM32WB_FLASH_REGS_ADDR + 0x34) +#define STM32WB_FLASH_PCROP1BER (STM32WB_FLASH_REGS_ADDR + 0x38) +#define STM32WB_FLASH_IPCCBR (STM32WB_FLASH_REGS_ADDR + 0x3C) +#define STM32WB_FLASH_C2ACR (STM32WB_FLASH_REGS_ADDR + 0x5C) +#define STM32WB_FLASH_C2SR (STM32WB_FLASH_REGS_ADDR + 0x60) +#define STM32WB_FLASH_C2CR (STM32WB_FLASH_REGS_ADDR + 0x64) +#define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) +#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) + +// WB Flash control register. +#define STM32WB_FLASH_CR_STRT (16) /* Start */ +#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ +#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ +// WB Flash status register. +#define STM32WB_FLASH_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ +#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ +#define STM32WB_FLASH_SR_WRPERR (4) /* Write protection error */ +#define STM32WB_FLASH_SR_PGAERR (5) /* Programming error */ +#define STM32WB_FLASH_SR_BSY (16) /* Busy */ + +// 32L4 register base is at FLASH_REGS_ADDR (0x40022000) +#define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) +#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) +#define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) +#define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) +#define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) + +#define STM32L4_FLASH_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ +#define STM32L4_FLASH_SR_PROGERR 3 +#define STM32L4_FLASH_SR_WRPERR 4 +#define STM32L4_FLASH_SR_PGAERR 5 +#define STM32L4_FLASH_SR_BSY 16 + +#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ +#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ +#define STM32L4_FLASH_CR_PG 0 /* Program */ +#define STM32L4_FLASH_CR_PER 1 /* Page erase */ +#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ +#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ +#define STM32L4_FLASH_CR_STRT 16 /* Start command */ +#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ +#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ +#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ +#define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ +// Bits requesting flash operations (useful when we want to clear them) +#define STM32L4_FLASH_CR_OPBITS \ + (uint32_t)((1lu << STM32L4_FLASH_CR_PG) | (1lu << STM32L4_FLASH_CR_PER) | \ + (1lu << STM32L4_FLASH_CR_MER1) | (1lu << STM32L4_FLASH_CR_MER1)) +// Page is fully specified by BKER and PNB +#define STM32L4_FLASH_CR_PAGEMASK (uint32_t)(0x1fflu << STM32L4_FLASH_CR_PNB) + +#define STM32L4_FLASH_OPTR_DUALBANK 21 + +// STM32L0x flash register base and offsets RM0090 - DM00031020.pdf +#define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) + +#define STM32L0_FLASH_PELOCK (0) +#define STM32L0_FLASH_OPTLOCK (2) +#define STM32L0_FLASH_OBL_LAUNCH (18) + +#define STM32L0_FLASH_SR_ERROR_MASK 0x00013F00 +#define STM32L0_FLASH_SR_WRPERR 8 +#define STM32L0_FLASH_SR_PGAERR 9 +#define STM32L0_FLASH_SR_NOTZEROERR 16 + +#define FLASH_ACR_OFF ((uint32_t)0x00) +#define FLASH_PECR_OFF ((uint32_t)0x04) +#define FLASH_PDKEYR_OFF ((uint32_t)0x08) +#define FLASH_PEKEYR_OFF ((uint32_t)0x0c) +#define FLASH_PRGKEYR_OFF ((uint32_t)0x10) +#define FLASH_OPTKEYR_OFF ((uint32_t)0x14) +#define FLASH_SR_OFF ((uint32_t)0x18) +#define FLASH_OBR_OFF ((uint32_t)0x1c) +#define FLASH_WRPR_OFF ((uint32_t)0x20) + +// STM32F7 +#define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) +#define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) +#define FLASH_F7_SR (FLASH_F7_REGS_ADDR + 0x0c) +#define FLASH_F7_CR (FLASH_F7_REGS_ADDR + 0x10) +#define FLASH_F7_OPTCR (FLASH_F7_REGS_ADDR + 0x14) +#define FLASH_F7_OPTCR1 (FLASH_F7_REGS_ADDR + 0x18) +#define FLASH_F7_OPTCR_LOCK 0 +#define FLASH_F7_OPTCR_START 1 +#define FLASH_F7_CR_STRT 16 +#define FLASH_F7_CR_LOCK 31 +#define FLASH_F7_CR_SER 1 +#define FLASH_F7_CR_SNB 3 +#define FLASH_F7_CR_SNB_MASK 0xf8 +#define FLASH_F7_SR_BSY 16 +#define FLASH_F7_SR_ERS_ERR 7 /* Erase Sequence Error */ +#define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ +#define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ +#define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ +#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ +#define FLASH_F7_SR_EOP 0 /* End of operation */ +#define FLASH_F7_OPTCR1_BOOT_ADD0 0 +#define FLASH_F7_OPTCR1_BOOT_ADD1 16 + +#define FLASH_F7_SR_ERROR_MASK \ + ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | \ + (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | \ + (1 << FLASH_F7_SR_OP_ERR)) + +// STM32F4 +#define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) +#define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08) +#define FLASH_F4_SR (FLASH_F4_REGS_ADDR + 0x0c) +#define FLASH_F4_CR (FLASH_F4_REGS_ADDR + 0x10) +#define FLASH_F4_OPTCR (FLASH_F4_REGS_ADDR + 0x14) +#define FLASH_F4_OPTCR_LOCK 0 +#define FLASH_F4_OPTCR_START 1 +#define FLASH_F4_CR_STRT 16 +#define FLASH_F4_CR_LOCK 31 +#define FLASH_F4_CR_SER 1 +#define FLASH_F4_CR_SNB 3 +#define FLASH_F4_CR_SNB_MASK 0xf8 +#define FLASH_F4_SR_ERROR_MASK 0x000000F0 +#define FLASH_F4_SR_PGAERR 5 +#define FLASH_F4_SR_WRPERR 4 +#define FLASH_F4_SR_BSY 16 + +// STM32F2 +#define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F2_KEYR (FLASH_F2_REGS_ADDR + 0x04) +#define FLASH_F2_OPT_KEYR (FLASH_F2_REGS_ADDR + 0x08) +#define FLASH_F2_SR (FLASH_F2_REGS_ADDR + 0x0c) +#define FLASH_F2_CR (FLASH_F2_REGS_ADDR + 0x10) +#define FLASH_F2_OPT_CR (FLASH_F2_REGS_ADDR + 0x14) +#define FLASH_F2_OPT_LOCK_BIT (1u << 0) +#define FLASH_F2_CR_STRT 16 +#define FLASH_F2_CR_LOCK 31 + +#define FLASH_F2_CR_SER 1 +#define FLASH_F2_CR_SNB 3 +#define FLASH_F2_CR_SNB_MASK 0x78 +#define FLASH_F2_SR_BSY 16 + +// STM32H7xx +#define FLASH_H7_CR_LOCK 0 +#define FLASH_H7_CR_PG 1 +#define FLASH_H7_CR_SER 2 +#define FLASH_H7_CR_BER 3 +#define FLASH_H7_CR_PSIZE 4 +#define FLASH_H7_CR_START(chipid) (chipid == STLINK_CHIPID_STM32_H7Ax ? 5 : 7) +#define FLASH_H7_CR_SNB 8 +#define FLASH_H7_CR_SNB_MASK 0x700 + +#define FLASH_H7_SR_QW 2 +#define FLASH_H7_SR_WRPERR 17 +#define FLASH_H7_SR_PGSERR 18 +#define FLASH_H7_SR_STRBERR 19 +#define FLASH_H7_SR_ERROR_MASK \ + ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | \ + (1 << FLASH_H7_SR_WRPERR)) + +#define FLASH_H7_OPTCR_OPTLOCK 0 +#define FLASH_H7_OPTCR_OPTSTART 1 +#define FLASH_H7_OPTCR_MER 4 + +#define FLASH_H7_OPTSR_OPT_BUSY 0 +#define FLASH_H7_OPTSR_OPTCHANGEERR 30 + +#define FLASH_H7_OPTCCR_CLR_OPTCHANGEERR 30 + +#define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) +#define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) +#define FLASH_H7_KEYR2 (FLASH_H7_REGS_ADDR + 0x104) +#define FLASH_H7_OPT_KEYR (FLASH_H7_REGS_ADDR + 0x08) +#define FLASH_H7_OPT_KEYR2 (FLASH_H7_REGS_ADDR + 0x108) +#define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c) +#define FLASH_H7_CR2 (FLASH_H7_REGS_ADDR + 0x10c) +#define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) +#define FLASH_H7_SR2 (FLASH_H7_REGS_ADDR + 0x110) +#define FLASH_H7_CCR1 (FLASH_H7_REGS_ADDR + 0x14) +#define FLASH_H7_CCR2 (FLASH_H7_REGS_ADDR + 0x114) +#define FLASH_H7_OPTCR (FLASH_H7_REGS_ADDR + 0x18) +#define FLASH_H7_OPTCR2 (FLASH_H7_REGS_ADDR + 0x118) +#define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) +#define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) + +#endif // STM32FLASH_H \ No newline at end of file diff --git a/src/calculate.c b/src/calculate.c new file mode 100644 index 000000000..22f6e3a5b --- /dev/null +++ b/src/calculate.c @@ -0,0 +1,74 @@ +#include +#include "calculate.h" +#include "common_flash.h" + +uint32_t calculate_F4_sectornum(uint32_t flashaddr) { + uint32_t offset = 0; + flashaddr &= ~STM32_FLASH_BASE; // page now holding the actual flash address + + if (flashaddr >= 0x100000) { + offset = 12; + flashaddr -= 0x100000; + } + + if (flashaddr < 0x4000) { + return (offset + 0); + } else if (flashaddr < 0x8000) { + return (offset + 1); + } else if (flashaddr < 0xc000) { + return (offset + 2); + } else if (flashaddr < 0x10000) { + return (offset + 3); + } else if (flashaddr < 0x20000) { + return (offset + 4); + } else { + return (offset + (flashaddr / 0x20000) + 4); + } +} + +uint32_t calculate_F7_sectornum(uint32_t flashaddr) { + flashaddr &= ~STM32_FLASH_BASE; // Page now holding the actual flash address + + if (flashaddr < 0x20000) { + return (flashaddr / 0x8000); + } else if (flashaddr < 0x40000) { + return (4); + } else { + return ((flashaddr / 0x40000) + 4); + } +} + +uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, + unsigned bank) { + flashaddr &= + ~((bank == BANK_1) + ? STM32_FLASH_BASE + : STM32_H7_FLASH_BANK2_BASE); // sector holding the flash address + return (flashaddr / sl->flash_pgsz); +} + +// returns BKER:PNB for the given page address +uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { + uint32_t bker = 0; + uint32_t flashopt; + stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); + flashaddr -= STM32_FLASH_BASE; + + if (sl->chip_id == STLINK_CHIPID_STM32_L4 || + sl->chip_id == STLINK_CHIPID_STM32_L496x_L4A6x || + sl->chip_id == STLINK_CHIPID_STM32_L4Rx) { + // this chip use dual banked flash + if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { + uint32_t banksize = (uint32_t)sl->flash_size / 2; + + if (flashaddr >= banksize) { + flashaddr -= banksize; + bker = 0x100; + } + } + } + + // For 1MB chips without the dual-bank option set, the page address will + // overflow into the BKER bit, which gives us the correct bank:page value. + return (bker | flashaddr / (uint32_t)sl->flash_pgsz); +} diff --git a/src/calculate.h b/src/calculate.h new file mode 100644 index 000000000..68c1fb988 --- /dev/null +++ b/src/calculate.h @@ -0,0 +1,15 @@ +/* + * File: calculate.h + * + * TODO: add a description + */ + +#ifndef CALCULATE_H +#define CALCULATE_H + +uint32_t calculate_F4_sectornum(uint32_t); +uint32_t calculate_F7_sectornum(uint32_t); +uint32_t calculate_H7_sectornum(stlink_t *, uint32_t, unsigned); +uint32_t calculate_L4_page(stlink_t *, uint32_t); + +#endif // CALCULATE_H diff --git a/src/common.h b/src/common.h new file mode 100644 index 000000000..6c22d58c0 --- /dev/null +++ b/src/common.h @@ -0,0 +1,15 @@ +/* + * File: common.h + * + * TODO: add a description + */ + +#ifndef COMMON_H +#define COMMON_H + +int check_file(stlink_t *, mapped_file_t *, stm32_addr_t); +void md5_calculate(mapped_file_t *); +void stlink_checksum(mapped_file_t *); +void stlink_fwrite_finalize(stlink_t *, stm32_addr_t); + +#endif // COMMON_H diff --git a/src/common_flash.c b/src/common_flash.c new file mode 100644 index 000000000..4f7f46257 --- /dev/null +++ b/src/common_flash.c @@ -0,0 +1,1374 @@ +#include +#include +#include +#include "calculate.h" +#include "common_flash.h" +#include "map_file.h" +#include "common.h" + +#define DEBUG_FLASH 0 + +uint32_t get_stm32l0_flash_base(stlink_t *sl) { + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_L0: + case STLINK_CHIPID_STM32_L0_CAT5: + case STLINK_CHIPID_STM32_L0_CAT2: + case STLINK_CHIPID_STM32_L011: + return (STM32L0_FLASH_REGS_ADDR); + + case STLINK_CHIPID_STM32_L1_CAT2: + case STLINK_CHIPID_STM32_L1_MD: + case STLINK_CHIPID_STM32_L1_MD_PLUS: + case STLINK_CHIPID_STM32_L1_MD_PLUS_HD: + return (STM32L_FLASH_REGS_ADDR); + + default: + WLOG("Flash base use default L0 address\n"); + return (STM32L0_FLASH_REGS_ADDR); + } +} + +uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { + uint32_t reg, res; + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + reg = FLASH_F4_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + reg = FLASH_F7_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + reg = STM32L4_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + reg = STM32WB_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + } else { + reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + } + + stlink_read_debug32(sl, reg, &res); + +#if DEBUG_FLASH + fprintf(stdout, "CR:0x%x\n", res); +#endif + return (res); +} + +void lock_flash(stlink_t *sl) { + uint32_t cr_lock_shift, cr_reg, n, cr2_reg = 0; + uint32_t cr_mask = 0xffffffffu; + + if (sl->flash_type == STLINK_FLASH_TYPE_F0) { + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + cr_reg = FLASH_CR; + cr2_reg = FLASH_CR2; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_lock_shift = FLASH_F4_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_lock_shift = FLASH_F7_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + cr_lock_shift = STM32L0_FLASH_PELOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_lock_shift = STM32L4_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_lock_shift = STM32WB_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + cr2_reg = FLASH_H7_CR2; + } + cr_lock_shift = FLASH_H7_CR_LOCK; + cr_mask = ~(1u << FLASH_H7_CR_SER); + } else { + ELOG("unsupported flash method, abort\n"); + return; + } + + stlink_read_debug32(sl, cr_reg, &n); + n &= cr_mask; + n |= (1u << cr_lock_shift); + stlink_write_debug32(sl, cr_reg, n); + + if (cr2_reg) { + n = read_flash_cr(sl, BANK_2) | (1u << cr_lock_shift); + stlink_write_debug32(sl, cr2_reg, n); + } +} + +static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { + uint32_t sr_reg; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + sr_reg = FLASH_F4_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_reg = FLASH_F7_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + sr_reg = STM32L4_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + sr_reg = STM32Gx_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + sr_reg = STM32WB_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; + } else { + ELOG("method 'write_flash_sr' is unsupported\n"); + return (-1); + } + + return stlink_write_debug32(sl, sr_reg, val); +} + +void clear_flash_error(stlink_t *sl) { + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_F4: + write_flash_sr(sl, BANK_1, FLASH_F4_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_F7: + write_flash_sr(sl, BANK_1, FLASH_F7_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_L0: + write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_L4: + write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_H7: + write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_sr(sl, BANK_2, FLASH_H7_SR_ERROR_MASK); + } + break; + case STLINK_FLASH_TYPE_WB: + write_flash_sr(sl, BANK_1, STM32WB_FLASH_SR_ERROR_MASK); + break; + default: + break; + } +} + +uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { + uint32_t res, sr_reg; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + sr_reg = FLASH_F4_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_reg = FLASH_F7_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + sr_reg = STM32L4_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + sr_reg = STM32Gx_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + sr_reg = STM32WB_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; + } else { + ELOG("method 'read_flash_sr' is unsupported\n"); + return (-1); + } + + stlink_read_debug32(sl, sr_reg, &res); + return (res); +} + +unsigned int is_flash_busy(stlink_t *sl) { + uint32_t sr_busy_shift; + unsigned int res; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || + (sl->flash_type == STLINK_FLASH_TYPE_L0)) { + sr_busy_shift = FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + sr_busy_shift = FLASH_F4_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_busy_shift = FLASH_F7_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + sr_busy_shift = STM32L4_FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + sr_busy_shift = STM32Gx_FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + sr_busy_shift = STM32WB_FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_busy_shift = FLASH_H7_SR_QW; + } else { + ELOG("method 'is_flash_busy' is unsupported\n"); + return (-1); + } + + res = read_flash_sr(sl, BANK_1) & (1 << sr_busy_shift); + + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || + (sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { + res |= read_flash_sr(sl, BANK_2) & (1 << sr_busy_shift); + } + + return (res); +} + +void wait_flash_busy(stlink_t *sl) { + // TODO: add some delays here + while (is_flash_busy(sl)) + ; +} + +int check_flash_error(stlink_t *sl) { + uint32_t res = 0; + uint32_t WRPERR, PROGERR, PGAERR; + + WRPERR = PROGERR = PGAERR = 0; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + res |= read_flash_sr(sl, BANK_2) & FLASH_SR_ERROR_MASK; + } + WRPERR = (1 << FLASH_SR_WRPRT_ERR); + PROGERR = (1 << FLASH_SR_PG_ERR); + break; + case STLINK_FLASH_TYPE_F4: + res = read_flash_sr(sl, BANK_1) & FLASH_F4_SR_ERROR_MASK; + WRPERR = (1 << FLASH_F4_SR_WRPERR); + PGAERR = (1 << FLASH_F4_SR_PGAERR); + break; + case STLINK_FLASH_TYPE_F7: + res = read_flash_sr(sl, BANK_1) & FLASH_F7_SR_ERROR_MASK; + WRPERR = (1 << FLASH_F7_SR_WRP_ERR); + PROGERR = (1 << FLASH_F7_SR_PGP_ERR); + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32Gx_FLASH_SR_WRPERR); + PROGERR = (1 << STM32Gx_FLASH_SR_PROGERR); + PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); + break; + case STLINK_FLASH_TYPE_L0: + res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); + PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); + PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); + break; + case STLINK_FLASH_TYPE_L4: + res = read_flash_sr(sl, BANK_1) & STM32L4_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32L4_FLASH_SR_WRPERR); + PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); + PGAERR = (1 << STM32L4_FLASH_SR_PGAERR); + break; + case STLINK_FLASH_TYPE_H7: + res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; + } + WRPERR = (1 << FLASH_H7_SR_WRPERR); + break; + case STLINK_FLASH_TYPE_WB: + res = read_flash_sr(sl, BANK_1) & STM32WB_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32WB_FLASH_SR_WRPERR); + PROGERR = (1 << STM32WB_FLASH_SR_PROGERR); + PGAERR = (1 << STM32WB_FLASH_SR_PGAERR); + break; + default: + break; + } + + if (res) { + if (WRPERR && (WRPERR & res) == WRPERR) { + ELOG("Flash memory is write protected\n"); + res &= ~WRPERR; + } else if (PROGERR && (PROGERR & res) == PROGERR) { + ELOG("Flash memory contains a non-erased value\n"); + res &= ~PROGERR; + } else if (PGAERR && (PGAERR & res) == PGAERR) { + ELOG("Invalid flash address\n"); + res &= ~PGAERR; + } + + if (res) { + ELOG("Flash programming error: %#010x\n", res); + } + return (-1); + } + + return (0); +} + +static inline unsigned int is_flash_locked(stlink_t *sl) { + /* return non zero for true */ + uint32_t cr_lock_shift; + uint32_t cr_reg; + uint32_t n; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_lock_shift = FLASH_F4_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_lock_shift = FLASH_F7_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + cr_lock_shift = STM32L0_FLASH_PELOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_lock_shift = STM32L4_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_lock_shift = STM32WB_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + cr_lock_shift = FLASH_H7_CR_LOCK; + } else { + ELOG("unsupported flash method, abort\n"); + return (-1); + } + + stlink_read_debug32(sl, cr_reg, &n); + return (n & (1u << cr_lock_shift)); +} + +static void unlock_flash(stlink_t *sl) { + uint32_t key_reg, key2_reg = 0; + uint32_t flash_key1 = FLASH_KEY1; + uint32_t flash_key2 = FLASH_KEY2; + /* The unlock sequence consists of 2 write cycles where 2 key values are + * written to the FLASH_KEYR register. An invalid sequence results in a + * definitive lock of the FPEC block until next reset. + */ + + if (sl->flash_type == STLINK_FLASH_TYPE_F0) { + key_reg = FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + key_reg = FLASH_KEYR; + key2_reg = FLASH_KEYR2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + key_reg = FLASH_F4_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + key_reg = FLASH_F7_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; + flash_key1 = FLASH_L0_PEKEY1; + flash_key2 = FLASH_L0_PEKEY2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + key_reg = STM32L4_FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + key_reg = STM32Gx_FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + key_reg = STM32WB_FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + key_reg = FLASH_H7_KEYR1; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + key2_reg = FLASH_H7_KEYR2; + } + } else { + ELOG("unsupported flash method, abort\n"); + return; + } + + stlink_write_debug32(sl, key_reg, flash_key1); + stlink_write_debug32(sl, key_reg, flash_key2); + + if (key2_reg) { + stlink_write_debug32(sl, key2_reg, flash_key1); + stlink_write_debug32(sl, key2_reg, flash_key2); + } +} + +/* unlock flash if already locked */ +int unlock_flash_if(stlink_t *sl) { + if (is_flash_locked(sl)) { + unlock_flash(sl); + + if (is_flash_locked(sl)) { + WLOG("Failed to unlock flash!\n"); + return (-1); + } + } + + DLOG("Successfully unlocked flash\n"); + return (0); +} + +int lock_flash_option(stlink_t *sl) { + uint32_t optlock_shift, optcr_reg, n, optcr2_reg = 0; + int active_bit_level = 1; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; + optlock_shift = FLASH_CR_OPTWRE; + active_bit_level = 0; + break; + case STLINK_FLASH_TYPE_F4: + optcr_reg = FLASH_F4_OPTCR; + optlock_shift = FLASH_F4_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_F7: + optcr_reg = FLASH_F7_OPTCR; + optlock_shift = FLASH_F7_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_L0: + optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + optlock_shift = STM32L0_FLASH_OPTLOCK; + break; + case STLINK_FLASH_TYPE_L4: + optcr_reg = STM32L4_FLASH_CR; + optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_WB: + optcr_reg = STM32WB_FLASH_CR; + optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_H7: + optcr_reg = FLASH_H7_OPTCR; + optlock_shift = FLASH_H7_OPTCR_OPTLOCK; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) + optcr2_reg = FLASH_H7_OPTCR2; + break; + default: + ELOG("unsupported flash method, abort\n"); + return -1; + } + + stlink_read_debug32(sl, optcr_reg, &n); + + if (active_bit_level == 0) { + n &= ~(1u << optlock_shift); + } else { + n |= (1u << optlock_shift); + } + + stlink_write_debug32(sl, optcr_reg, n); + + if (optcr2_reg) { + stlink_read_debug32(sl, optcr2_reg, &n); + + if (active_bit_level == 0) { + n &= ~(1u << optlock_shift); + } else { + n |= (1u << optlock_shift); + } + + stlink_write_debug32(sl, optcr2_reg, n); + } + + return (0); +} + +static bool is_flash_option_locked(stlink_t *sl) { + uint32_t optlock_shift, optcr_reg; + int active_bit_level = 1; + uint32_t n; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; + optlock_shift = FLASH_CR_OPTWRE; + active_bit_level = 0; /* bit is "option write enable", not lock */ + break; + case STLINK_FLASH_TYPE_F4: + optcr_reg = FLASH_F4_OPTCR; + optlock_shift = FLASH_F4_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_F7: + optcr_reg = FLASH_F7_OPTCR; + optlock_shift = FLASH_F7_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_L0: + optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + optlock_shift = STM32L0_FLASH_OPTLOCK; + break; + case STLINK_FLASH_TYPE_L4: + optcr_reg = STM32L4_FLASH_CR; + optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_WB: + optcr_reg = STM32WB_FLASH_CR; + optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_H7: + optcr_reg = FLASH_H7_OPTCR; + optlock_shift = FLASH_H7_OPTCR_OPTLOCK; + break; + default: + ELOG("unsupported flash method, abort\n"); + return -1; + } + + stlink_read_debug32(sl, optcr_reg, &n); + + if (active_bit_level == 0) { + return (!(n & (1u << optlock_shift))); + } + + return (n & (1u << optlock_shift)); +} + +static int unlock_flash_option(stlink_t *sl) { + uint32_t optkey_reg, optkey2_reg = 0; + uint32_t optkey1 = FLASH_OPTKEY1; + uint32_t optkey2 = FLASH_OPTKEY2; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optkey_reg = FLASH_OPTKEYR; + optkey1 = FLASH_F0_OPTKEY1; + optkey2 = FLASH_F0_OPTKEY2; + break; + case STLINK_FLASH_TYPE_F4: + optkey_reg = FLASH_F4_OPT_KEYR; + break; + case STLINK_FLASH_TYPE_F7: + optkey_reg = FLASH_F7_OPT_KEYR; + break; + case STLINK_FLASH_TYPE_L0: + optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; + optkey1 = FLASH_L0_OPTKEY1; + optkey2 = FLASH_L0_OPTKEY2; + break; + case STLINK_FLASH_TYPE_L4: + optkey_reg = STM32L4_FLASH_OPTKEYR; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optkey_reg = STM32Gx_FLASH_OPTKEYR; + break; + case STLINK_FLASH_TYPE_WB: + optkey_reg = STM32WB_FLASH_OPT_KEYR; + break; + case STLINK_FLASH_TYPE_H7: + optkey_reg = FLASH_H7_OPT_KEYR; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) + optkey2_reg = FLASH_H7_OPT_KEYR2; + break; + default: + ELOG("unsupported flash method, abort\n"); + return (-1); + } + + stlink_write_debug32(sl, optkey_reg, optkey1); + stlink_write_debug32(sl, optkey_reg, optkey2); + + if (optkey2_reg) { + stlink_write_debug32(sl, optkey2_reg, optkey1); + stlink_write_debug32(sl, optkey2_reg, optkey2); + } + + return (0); +} + +int unlock_flash_option_if(stlink_t *sl) { + if (is_flash_option_locked(sl)) { + if (unlock_flash_option(sl)) { + ELOG("Could not unlock flash option!\n"); + return (-1); + } + + if (is_flash_option_locked(sl)) { + ELOG("Failed to unlock flash option!\n"); + return (-1); + } + } + + DLOG("Successfully unlocked flash option\n"); + return (0); +} + +void write_flash_cr_psiz(stlink_t *sl, uint32_t n, + unsigned bank) { + uint32_t cr_reg, psize_shift; + uint32_t x = read_flash_cr(sl, bank); + + if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + psize_shift = FLASH_H7_CR_PSIZE; + } else { + cr_reg = FLASH_F4_CR; + psize_shift = 8; + } + + x &= ~(0x03 << psize_shift); + x |= (n << psize_shift); +#if DEBUG_FLASH + fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n); +#endif + stlink_write_debug32(sl, cr_reg, x); +} + +void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { + uint32_t cr_reg, n; + uint32_t bit = FLASH_CR_PG; + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + bit = FLASH_H7_CR_PG; + } else { + cr_reg = FLASH_CR; + } + + n = read_flash_cr(sl, bank) & ~(1 << bit); + stlink_write_debug32(sl, cr_reg, n); +} +/* ------------------------------------------------------------------------ */ + +static void wait_flash_busy_progress(stlink_t *sl) { + int i = 0; + fprintf(stdout, "Mass erasing"); + fflush(stdout); + + while (is_flash_busy(sl)) { + usleep(10000); + i++; + + if (i % 100 == 0) { + fprintf(stdout, "."); + fflush(stdout); + } + } + + fprintf(stdout, "\n"); +} + +static inline void write_flash_ar(stlink_t *sl, uint32_t n, unsigned bank) { + stlink_write_debug32(sl, (bank == BANK_1) ? FLASH_AR : FLASH_AR2, n); +} + +static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, unsigned bank) { + uint32_t cr_reg, snb_mask, snb_shift, ser_shift; + uint32_t x = read_flash_cr(sl, bank); + + if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + snb_mask = FLASH_H7_CR_SNB_MASK; + snb_shift = FLASH_H7_CR_SNB; + ser_shift = FLASH_H7_CR_SER; + } else { + cr_reg = FLASH_F4_CR; + snb_mask = FLASH_F4_CR_SNB_MASK; + snb_shift = FLASH_F4_CR_SNB; + ser_shift = FLASH_F4_CR_SER; + } + + x &= ~snb_mask; + x |= (n << snb_shift); + x |= (1 << ser_shift); +#if DEBUG_FLASH + fprintf(stdout, "SNB:0x%x 0x%x\n", x, n); +#endif + stlink_write_debug32(sl, cr_reg, x); +} + +static void set_flash_cr_per(stlink_t *sl, unsigned bank) { + uint32_t cr_reg, val; + + if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + } + + stlink_read_debug32(sl, cr_reg, &val); + val |= (1 << FLASH_CR_PER); + stlink_write_debug32(sl, cr_reg, val); +} + +static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { + uint32_t cr_reg; + + if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + } + + const uint32_t n = read_flash_cr(sl, bank) & ~(1 << FLASH_CR_PER); + stlink_write_debug32(sl, cr_reg, n); +} + +static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { + stlink_write_debug32(sl, STM32L4_FLASH_SR, + 0xFFFFFFFF & ~(1 << STM32L4_FLASH_SR_BSY)); + uint32_t x = read_flash_cr(sl, BANK_1); + x &= ~STM32L4_FLASH_CR_OPBITS; + x &= ~STM32L4_FLASH_CR_PAGEMASK; + x &= ~(1 << STM32L4_FLASH_CR_MER1); + x &= ~(1 << STM32L4_FLASH_CR_MER2); + x |= (n << STM32L4_FLASH_CR_PNB); + x |= (uint32_t)(1lu << STM32L4_FLASH_CR_PER); +#if DEBUG_FLASH + fprintf(stdout, "BKER:PNB:0x%x 0x%x\n", x, n); +#endif + stlink_write_debug32(sl, STM32L4_FLASH_CR, x); +} + +static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { + uint32_t val, cr_reg, cr_strt; + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_strt = 1 << FLASH_F4_CR_STRT; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_strt = 1 << FLASH_F7_CR_STRT; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_strt = (1 << STM32L4_FLASH_CR_STRT); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_strt = (1 << STM32Gx_FLASH_CR_STRT); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_strt = (1 << STM32WB_FLASH_CR_STRT); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + cr_strt = 1 << FLASH_H7_CR_START(sl->chip_id); + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + cr_strt = (1 << FLASH_CR_STRT); + } + + stlink_read_debug32(sl, cr_reg, &val); + val |= cr_strt; + stlink_write_debug32(sl, cr_reg, val); +} + +static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { + uint32_t val, cr_reg, cr_mer, cr_pg; + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_mer = 1 << FLASH_CR_MER; + cr_pg = 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_mer = 1 << FLASH_CR_MER; + cr_pg = 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); + cr_pg = (1 << STM32L4_FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_mer = (1 << STM32Gx_FLASH_CR_MER1); + + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); + } + + cr_pg = (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + cr_mer = (1 << FLASH_H7_CR_BER); + cr_pg = (1 << FLASH_H7_CR_PG); + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); + } + + stlink_read_debug32(sl, cr_reg, &val); + + if (val & cr_pg) { + // STM32F030 will drop MER bit if PG was set + val &= ~cr_pg; + stlink_write_debug32(sl, cr_reg, val); + } + + if (v) { + val |= cr_mer; + } else { + val &= ~cr_mer; + } + + stlink_write_debug32(sl, cr_reg, val); +} + +/** + * Erase a page of flash, assumes sl is fully populated with things like + * chip/core ids + * @param sl stlink context + * @param flashaddr an address in the flash page to erase + * @return 0 on success -ve on failure + */ +int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { + // wait for ongoing op to finish + wait_flash_busy(sl); + // clear flash IO errors + clear_flash_error(sl); + + if (sl->flash_type == STLINK_FLASH_TYPE_F4 || + sl->flash_type == STLINK_FLASH_TYPE_F7 || + sl->flash_type == STLINK_FLASH_TYPE_L4) { + // unlock if locked + unlock_flash_if(sl); + + // select the page to erase + if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || + (sl->chip_id == STLINK_CHIPID_STM32_L43x_L44x) || + (sl->chip_id == STLINK_CHIPID_STM32_L45x_L46x) || + (sl->chip_id == STLINK_CHIPID_STM32_L496x_L4A6x) || + (sl->chip_id == STLINK_CHIPID_STM32_L4Rx)) { + // calculate the actual bank+page from the address + uint32_t page = calculate_L4_page(sl, flashaddr); + + fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", page, + stlink_calculate_pagesize(sl, flashaddr)); + + write_flash_cr_bker_pnb(sl, page); + } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || + sl->chip_id == STLINK_CHIPID_STM32_F76xxx) { + // calculate the actual page from the address + uint32_t sector = calculate_F7_sectornum(flashaddr); + + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, + stlink_calculate_pagesize(sl, flashaddr)); + write_flash_cr_snb(sl, sector, BANK_1); + } else { + // calculate the actual page from the address + uint32_t sector = calculate_F4_sectornum(flashaddr); + + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, + stlink_calculate_pagesize(sl, flashaddr)); + + // the SNB values for flash sectors in the second bank do not directly + // follow the values for the first bank on 2mb devices... + if (sector >= 12) { + sector += 4; + } + + write_flash_cr_snb(sl, sector, BANK_1); + } + + set_flash_cr_strt(sl, BANK_1); // start erase operation + wait_flash_busy(sl); // wait for completion + lock_flash(sl); // TODO: fails to program if this is in +#if DEBUG_FLASH + fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl, BANK_1)); +#endif + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + + // check if the locks are set + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + + if ((val & (1 << 0)) || (val & (1 << 1))) { + // disable pecr protection + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY2); + + // check pecr.pelock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + + if (val & (1 << 0)) { + WLOG("pecr.pelock not clear (%#x)\n", val); + return (-1); + } + + // unlock program memory + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY2); + + // check pecr.prglock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + + if (val & (1 << 1)) { + WLOG("pecr.prglock not clear (%#x)\n", val); + return (-1); + } + } + + // set pecr.{erase,prog} + val |= (1 << 9) | (1 << 3); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + + // write 0 to the first word of the page to be erased + stlink_write_debug32(sl, flashaddr, 0); + + /* MP: It is better to wait for clearing the busy bit after issuing page + * erase command, even though PM0062 recommends to wait before it. + * Test shows that a few iterations is performed in the following loop + * before busy bit is cleared. + */ + wait_flash_busy(sl); + + // reset lock bits + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + uint32_t val; + unlock_flash_if(sl); + set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit + + // set the page to erase + if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + uint32_t flash_page = + ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + + // sec 3.10.5 - PNB[7:0] is offset by 3. + val &= ~(0xFF << 3); // Clear previously set page number (if any) + val |= ((flash_page & 0xFF) << 3); + + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + uint32_t flash_page = + ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. + val &= ~(0x3F << 3); + val |= ((flash_page & 0x3F) << 3) | (1 << FLASH_CR_PER); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G4) { + uint32_t flash_page = + ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. + val &= ~(0x7F << 3); + val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + } + + set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit + wait_flash_busy(sl); // wait for the 'busy' bit to clear + clear_flash_cr_per(sl, BANK_1); // clear the 'enable page erase' bit + lock_flash(sl); + } else if (sl->flash_type == STLINK_FLASH_TYPE_F0 || + sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + unsigned bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; + unlock_flash_if(sl); + clear_flash_cr_pg(sl, bank); // clear the pg bit + set_flash_cr_per(sl, bank); // set the page erase bit + write_flash_ar(sl, flashaddr, bank); // select the page to erase + set_flash_cr_strt(sl, + bank); // start erase operation, reset by hw with busy bit + wait_flash_busy(sl); + clear_flash_cr_per(sl, bank); // clear the page erase bit + lock_flash(sl); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; + unlock_flash_if(sl); // unlock if locked + uint32_t sector = calculate_H7_sectornum( + sl, flashaddr, bank); // calculate the actual page from the address + write_flash_cr_snb(sl, sector, bank); // select the page to erase + set_flash_cr_strt(sl, bank); // start erase operation + wait_flash_busy(sl); // wait for completion + lock_flash(sl); + } else { + WLOG("unknown coreid %x, page erase failed\n", sl->core_id); + return (-1); + } + + return check_flash_error(sl); +} + +int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size) { + // Check the address and size validity + if (stlink_check_address_range_validity(sl, base_addr, size) < 0) { + return -1; + } + + // Make sure the requested address is aligned with the beginning of a page + if (stlink_check_address_alignment(sl, base_addr) < 0) { + ELOG("The address to erase is not aligned with the beginning of a page\n"); + return -1; + } + + stm32_addr_t addr = base_addr; + do { + long unsigned int page_size = stlink_calculate_pagesize(sl, addr); + + // Check if size is aligned with a page, unless we want to completely erase the last page + if ((addr + page_size) > (base_addr + size) && !align_size) { + ELOG("Invalid size (not aligned with a page). Page size at address %#x is %#lx\n", addr, page_size); + return -1; + } + + if (stlink_erase_flash_page(sl, addr)) { + WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); + return (-1); + } + + fprintf(stdout, "-> Flash page at %#x erased (size: %#lx)\n", addr, page_size); + fflush(stdout); + + // check the next page is within the range to erase + addr += page_size; + } while (addr < (base_addr + size)); + + fprintf(stdout, "\n"); + return 0; +} + +int stlink_erase_flash_mass(stlink_t *sl) { + int err = 0; + + // TODO: User MER bit to mass-erase WB series. + if (sl->flash_type == STLINK_FLASH_TYPE_L0 || + sl->flash_type == STLINK_FLASH_TYPE_WB) { + + err = stlink_erase_flash_section(sl, sl->flash_base, sl->flash_size, false); + + } else { + wait_flash_busy(sl); + clear_flash_error(sl); + unlock_flash_if(sl); + + if (sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_id != STLINK_CHIPID_STM32_H7Ax) { + // set parallelism + write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); + } + } + + set_flash_cr_mer(sl, 1, BANK_1); // set the mass erase bit + set_flash_cr_strt( + sl, BANK_1); // start erase operation, reset by hw with busy bit + + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || + (sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { + set_flash_cr_mer(sl, 1, BANK_2); // set the mass erase bit in bank 2 + set_flash_cr_strt(sl, BANK_2); // start erase operation in bank 2 + } + + wait_flash_busy_progress(sl); + lock_flash(sl); + + // reset the mass erase bit + set_flash_cr_mer(sl, 0, BANK_1); + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || + (sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { + set_flash_cr_mer(sl, 0, BANK_2); + } + + err = check_flash_error(sl); + } + + return (err); +} + +int stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, + stm32_addr_t addr) { + /* Write the block in flash at addr */ + int err; + unsigned int num_empty, idx; + uint8_t erased_pattern = stlink_get_erased_pattern(sl); + + /* + * This optimisation may cause unexpected garbage data remaining. + * Therfore it is turned off by default. + */ + if (sl->opt) { + idx = (unsigned int)length; + + for (num_empty = 0; num_empty != length; ++num_empty) + if (data[--idx] != erased_pattern) { + break; + } + + num_empty -= (num_empty & 3); // Round down to words + + if (num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, + erased_pattern); + } + } else { + num_empty = 0; + } + + /* + * TODO: investigate a kind of weird behaviour here: + * If the file is identified to be all-empty and four-bytes aligned, + * still flash the whole file even if ignoring message is printed. + */ + err = stlink_write_flash(sl, addr, data, + (num_empty == length) ? (uint32_t)length + : (uint32_t)length - num_empty, + num_empty == length); + stlink_fwrite_finalize(sl, addr); + return (err); +} + +/** + * Write the given binary file into flash at address "addr" + * @param sl + * @param path readable file path, should be binary image + * @param addr where to start writing + * @return 0 on success, -ve on failure. + */ +int stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { + /* Write the file in flash at addr */ + int err; + unsigned int num_empty, idx; + uint8_t erased_pattern = stlink_get_erased_pattern(sl); + mapped_file_t mf = MAPPED_FILE_INITIALIZER; + + if (map_file(&mf, path) == -1) { + ELOG("map_file() == -1\n"); + return (-1); + } + + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); + + if (sl->opt) { + idx = (unsigned int)mf.len; + + for (num_empty = 0; num_empty != mf.len; ++num_empty) { + if (mf.base[--idx] != erased_pattern) { + break; + } + } + + num_empty -= (num_empty & 3); // round down to words + + if (num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, + erased_pattern); + } + } else { + num_empty = 0; + } + + /* + * TODO: investigate a kind of weird behaviour here: + * If the file is identified to be all-empty and four-bytes aligned, + * still flash the whole file even if ignoring message is printed. + */ + err = stlink_write_flash(sl, addr, mf.base, + (num_empty == mf.len) ? (uint32_t)mf.len + : (uint32_t)mf.len - num_empty, + num_empty == mf.len); + stlink_fwrite_finalize(sl, addr); + unmap_file(&mf); + return (err); +} + + +int stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { + // check the contents of path are at addr + + int res; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; + + if (map_file(&mf, path) == -1) { + return (-1); + } + + res = check_file(sl, &mf, addr); + unmap_file(&mf); + return (res); +} + +/** + * Verify addr..addr+len is binary identical to base...base+len + * @param sl stlink context + * @param address stm device address + * @param data host side buffer to check against + * @param length how much + * @return 0 for success, -ve for failure + */ +int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, + unsigned length) { + size_t off; + size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; + ILOG("Starting verification of write complete\n"); + + for (off = 0; off < length; off += cmp_size) { + size_t aligned_size; + + // adjust last page size + if ((off + cmp_size) > length) { + cmp_size = length - off; + } + + aligned_size = cmp_size; + + if (aligned_size & (4 - 1)) { + aligned_size = (cmp_size + 4) & ~(4 - 1); + } + + stlink_read_mem32(sl, address + (uint32_t)off, (uint16_t)aligned_size); + + if (memcmp(sl->q_buf, data + off, cmp_size)) { + ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); + return (-1); + } + } + + ILOG("Flash written and verified! jolly good!\n"); + return (0); +} + +// Check if an address and size are within the flash +int stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size) { + long unsigned int logvar; + if (addr < sl->flash_base || addr >= (sl->flash_base + sl->flash_size)) { + logvar = sl->flash_base + sl->flash_size - 1; + ELOG("Invalid address, it should be within 0x%08x - 0x%08lx\n", sl->flash_base, logvar); + return (-1); + } + if ((addr + size) > (sl->flash_base + sl->flash_size)) { + logvar = sl->flash_base + sl->flash_size - addr; + ELOG("The size exceeds the size of the flash (0x%08lx bytes available)\n", logvar); + return (-1); + } + return 0; +} + +// Check if an address is aligned with the beginning of a page +int stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr) { + stm32_addr_t page = sl->flash_base; + + while (page < addr) { + page += stlink_calculate_pagesize(sl, page); + } + + if (page != addr) { + return -1; + } + + return 0; +} + +int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, + uint32_t len, uint8_t eraseonly) { + int ret; + flash_loader_t fl; + ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, + len, addr, addr); + // check addr range is inside the flash + stlink_calculate_pagesize(sl, addr); + + // Check the address and size validity + if (stlink_check_address_range_validity(sl, addr, len) < 0) { + return (-1); + } else if (len & 1) { + WLOG("unaligned len 0x%x -- padding with zero\n", len); + len += 1; + } else if (stlink_check_address_alignment(sl, addr) < 0) { + ELOG("addr not a multiple of current pagesize (%u bytes), not supported, " + "check page start address and compare with flash module organisation " + "in related ST reference manual of your device.\n", + (unsigned)(sl->flash_pgsz)); + return (-1); + } + + // make sure we've loaded the context with the chip details + stlink_core_id(sl); + + // Erase this section of the flash + if (stlink_erase_flash_section(sl, addr, len, true) < 0) { + ELOG("Failed to erase the flash prior to writing\n"); + return (-1); + } + + if (eraseonly) { + return (0); + } + + ret = stlink_flashloader_start(sl, &fl); + if (ret) + return ret; + ret = stlink_flashloader_write(sl, &fl, addr, base, len); + if (ret) + return ret; + ret = stlink_flashloader_stop(sl, &fl); + if (ret) + return ret; + + return (stlink_verify_write_flash(sl, addr, base, len)); +} diff --git a/src/common_flash.h b/src/common_flash.h new file mode 100644 index 000000000..70a6f0e04 --- /dev/null +++ b/src/common_flash.h @@ -0,0 +1,27 @@ +/* + * File: common_flash.h + * + * TODO: add a description + */ + +#ifndef COMMON_FLASH_H +#define COMMON_FLASH_H + +void lock_flash(stlink_t *); +void clear_flash_error(stlink_t *); +void wait_flash_busy(stlink_t *); +int check_flash_error(stlink_t *); +int unlock_flash_if(stlink_t *); +int lock_flash_option(stlink_t *); +int unlock_flash_option_if(stlink_t *); +void write_flash_cr_psiz(stlink_t *, uint32_t, unsigned); +void clear_flash_cr_pg(stlink_t *, unsigned); + +// TODO: move to private defines if possible + +#define BANK_1 0 +#define BANK_2 1 + +uint32_t read_flash_cr(stlink_t *, unsigned); +uint32_t get_stm32l0_flash_base(stlink_t *); +#endif // STLINK_H diff --git a/src/flashloader.c b/src/flashloader.c new file mode 100644 index 000000000..df14e506c --- /dev/null +++ b/src/flashloader.c @@ -0,0 +1,481 @@ +#include +#include +#include "common_flash.h" + +#define L1_WRITE_BLOCK_SIZE 0x80 +#define L0_WRITE_BLOCK_SIZE 0x40 + +int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, + uint32_t len, uint32_t pagesize) { + unsigned int count, off; + unsigned int num_half_pages = len / pagesize; + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + flash_loader_t fl; + bool use_loader = true; + int ret = 0; + + // enable half page write + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << FLASH_L1_FPRG); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + val |= (1 << FLASH_L1_PROG); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + + wait_flash_busy(sl); + + for (count = 0; count < num_half_pages; count++) { + if (use_loader) { + ret = stlink_flash_loader_run(sl, &fl, addr + count * pagesize, + base + count * pagesize, pagesize); + if (ret && count == 0) { + /* It seems that stm32lx devices have a problem when it is blank */ + WLOG("Failed to use flash loader, fallback to soft write\n"); + use_loader = false; + } + } + if (!use_loader) { + ret = 0; + for (off = 0; off < pagesize && !ret; off += 64) { + size_t chunk = (pagesize - off > 64) ? 64 : pagesize - off; + memcpy(sl->q_buf, base + count * pagesize + off, chunk); + ret = stlink_write_mem32(sl, addr + count * pagesize + off, (uint16_t)chunk); + } + } + + if (ret) { + WLOG("l1_stlink_flash_loader_run(%#x) failed! == -1\n", + addr + count * pagesize); + break; + } + + if (sl->verbose >= 1) { + // show progress; writing procedure is slow and previous errors are + // misleading + fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); + fflush(stdout); + } + + // wait for sr.busy to be cleared + wait_flash_busy(sl); + } + + // disable half page write + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + return (ret); +} + +static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { + uint32_t cr_reg, x; + + x = read_flash_cr(sl, bank); + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + x |= 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + x |= 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + x &= ~STM32L4_FLASH_CR_OPBITS; + x |= (1 << STM32L4_FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + x |= (1 << FLASH_H7_CR_PG); + } else { + cr_reg = FLASH_CR; + x = (1 << FLASH_CR_PG); + } + + stlink_write_debug32(sl, cr_reg, x); +} + +static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { + uint32_t rcc, rcc_dma_mask, value; + + rcc = rcc_dma_mask = value = 0; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + rcc = STM32F1_RCC_AHBENR; + rcc_dma_mask = STM32F1_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_F4: + case STLINK_FLASH_TYPE_F7: + rcc = STM32F4_RCC_AHB1ENR; + rcc_dma_mask = STM32F4_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_G0: + rcc = STM32G0_RCC_AHBENR; + rcc_dma_mask = STM32G0_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_G4: + case STLINK_FLASH_TYPE_L4: + rcc = STM32G4_RCC_AHB1ENR; + rcc_dma_mask = STM32G4_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_L0: + rcc = STM32L0_RCC_AHBENR; + rcc_dma_mask = STM32L0_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_H7: + rcc = STM32H7_RCC_AHB1ENR; + rcc_dma_mask = STM32H7_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_WB: + rcc = STM32WB_RCC_AHB1ENR; + rcc_dma_mask = STM32WB_RCC_DMAEN; + break; + default: + return; + } + + if (!stlink_read_debug32(sl, rcc, &value)) { + if (bckpRstr) { + value = (value & (~rcc_dma_mask)) | fl->rcc_dma_bkp; + } else { + fl->rcc_dma_bkp = value & rcc_dma_mask; + value &= ~rcc_dma_mask; + } + stlink_write_debug32(sl, rcc, value); + } +} + +int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { + // disable DMA + set_dma_state(sl, fl, 0); + + // wait for ongoing op to finish + wait_flash_busy(sl); + // Clear errors + clear_flash_error(sl); + + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + (sl->flash_type == STLINK_FLASH_TYPE_F7) || + (sl->flash_type == STLINK_FLASH_TYPE_L4)) { + ILOG("Starting Flash write for F2/F4/F7/L4\n"); + + // Flash loader initialisation + if (stlink_flash_loader_init(sl, fl) == -1) { + ELOG("stlink_flash_loader_init() == -1\n"); + return (-1); + } + + unlock_flash_if(sl); // first unlock the cr + + int voltage; + if (sl->version.stlink_v == 1) { + WLOG("STLINK V1 cannot read voltage, use default voltage 3.2V\n"); + voltage = 3200; + } else { + voltage = stlink_target_voltage(sl); + } + + if (voltage == -1) { + ELOG("Failed to read Target voltage\n"); + return (-1); + } + + if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + // L4 does not have a byte-write mode + if (voltage < 1710) { + ELOG("Target voltage (%d mV) too low for flash writes!\n", voltage); + return (-1); + } + } else { + if (voltage > 2700) { + ILOG("enabling 32-bit flash writes\n"); + write_flash_cr_psiz(sl, 2, BANK_1); + } else { + ILOG("Target voltage (%d mV) too low for 32-bit flash, " + "using 8-bit flash writes\n", + voltage); + write_flash_cr_psiz(sl, 0, BANK_1); + } + } + + // set programming mode + set_flash_cr_pg(sl, BANK_1); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + ILOG("Starting Flash write for WB/G0/G4\n"); + + unlock_flash_if(sl); // unlock flash if necessary + set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + ILOG("Starting Flash write for L0\n"); + + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + + // disable pecr protection + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY2); + + // check pecr.pelock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 0)) { + ELOG("pecr.pelock not clear\n"); + return (-1); + } + + // unlock program memory + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY2); + + // check pecr.prglock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 1)) { + ELOG("pecr.prglock not clear\n"); + return (-1); + } + + /* Flash loader initialisation */ + if (stlink_flash_loader_init(sl, fl) == -1) { + // L0/L1 have fallback to soft write + WLOG("stlink_flash_loader_init() == -1\n"); + } + } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + ILOG("Starting Flash write for VL/F0/F3/F1_XL\n"); + + // flash loader initialisation + if (stlink_flash_loader_init(sl, fl) == -1) { + ELOG("stlink_flash_loader_init() == -1\n"); + return (-1); + } + + // unlock flash + unlock_flash_if(sl); + + // set programming mode + set_flash_cr_pg(sl, BANK_1); + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + set_flash_cr_pg(sl, BANK_2); + } + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + ILOG("Starting Flash write for H7\n"); + + unlock_flash_if(sl); // unlock the cr + set_flash_cr_pg(sl, BANK_1); // set programming mode + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + set_flash_cr_pg(sl, BANK_2); + } + if (sl->chip_id != STLINK_CHIPID_STM32_H7Ax) { + // set parallelism + write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); + } + } + } else { + ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); + return (-1); + } + + return (0); +} + +int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, + stm32_addr_t addr, uint8_t *base, uint32_t len) { + size_t off; + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + (sl->flash_type == STLINK_FLASH_TYPE_F7) || + (sl->flash_type == STLINK_FLASH_TYPE_L4)) { + size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; + for (off = 0; off < len;) { + size_t size = len - off > buf_size ? buf_size : len - off; + if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, + size) == -1) { + ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", + (unsigned)(addr + off)); + check_flash_error(sl); + return (-1); + } + + off += size; + } + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); + for (off = 0; off < len; off += sizeof(uint32_t)) { + uint32_t data; + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { + fprintf(stdout, "\r%3u/%3u pages written", + (unsigned int)(off / sl->flash_pgsz), + (unsigned int)(len / sl->flash_pgsz)); + fflush(stdout); + } + + write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); + stlink_write_debug32(sl, addr + (uint32_t)off, data); + wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear + } + fprintf(stdout, "\n"); + + // flash writes happen as 2 words at a time + if ((off / sizeof(uint32_t)) % 2 != 0) { + stlink_write_debug32(sl, addr + (uint32_t)off, + 0); // write a single word of zeros + wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear + } + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + uint32_t pagesize = (flash_regs_base==STM32L0_FLASH_REGS_ADDR)? + L0_WRITE_BLOCK_SIZE:L1_WRITE_BLOCK_SIZE; + + DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); + + off = 0; + + if (len > pagesize) { + if (stm32l1_write_half_pages(sl, addr, base, len, pagesize)) { + return (-1); + } else { + off = (size_t)(len / pagesize) * pagesize; + } + } + + // write remaining word in program memory + for (; off < len; off += sizeof(uint32_t)) { + uint32_t data; + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { + fprintf(stdout, "\r%3u/%3u pages written", + (unsigned int)(off / sl->flash_pgsz), + (unsigned int)(len / sl->flash_pgsz)); + fflush(stdout); + } + + write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); + stlink_write_debug32(sl, addr + (uint32_t)off, data); + + // wait for sr.busy to be cleared + do { + stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); + } while ((val & (1 << 0)) != 0); + + // TODO: check redo write operation + } + fprintf(stdout, "\n"); + } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + int write_block_count = 0; + for (off = 0; off < len; off += sl->flash_pgsz) { + // adjust last write size + size_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; + + // unlock and set programming mode + unlock_flash_if(sl); + + DLOG("Finished unlocking flash, running loader!\n"); + + if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, + size) == -1) { + ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", + (unsigned)(addr + off)); + check_flash_error(sl); + return (-1); + } + + lock_flash(sl); + + if (sl->verbose >= 1) { + // show progress; writing procedure is slow and previous errors are + // misleading + fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, + (unsigned int)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); + fflush(stdout); + } + } + if (sl->verbose >= 1) { + fprintf(stdout, "\n"); + } + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + for (off = 0; off < len;) { + // Program STM32H7x with 64-byte Flash words + size_t chunk = (len - off > 64) ? 64 : len - off; + memcpy(sl->q_buf, base + off, chunk); + stlink_write_mem32(sl, addr + (uint32_t)off, 64); + wait_flash_busy(sl); + + off += chunk; + + if (sl->verbose >= 1) { + // show progress + fprintf(stdout, "\r%u/%u bytes written", (unsigned int)off, + (unsigned int)len); + fflush(stdout); + } + } + if (sl->verbose >= 1) { + fprintf(stdout, "\n"); + } + } else { + return (-1); + } + + return check_flash_error(sl); +} + +int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { + uint32_t dhcsr; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || + (sl->flash_type == STLINK_FLASH_TYPE_F4) || + (sl->flash_type == STLINK_FLASH_TYPE_F7) || + (sl->flash_type == STLINK_FLASH_TYPE_L4) || + (sl->flash_type == STLINK_FLASH_TYPE_WB) || + (sl->flash_type == STLINK_FLASH_TYPE_G0) || + (sl->flash_type == STLINK_FLASH_TYPE_G4) || + (sl->flash_type == STLINK_FLASH_TYPE_H7)) { + + clear_flash_cr_pg(sl, BANK_1); + if ((sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK) || + sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + clear_flash_cr_pg(sl, BANK_2); + } + lock_flash(sl); + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + + // reset lock bits + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + } + + // enable interrupt + if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) { + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + (dhcsr & (~STLINK_REG_DHCSR_C_MASKINTS))); + } + + // restore DMA state + set_dma_state(sl, fl, 1); + + return (0); +} diff --git a/src/map_file.c b/src/map_file.c new file mode 100644 index 000000000..5282fae27 --- /dev/null +++ b/src/map_file.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include + +#include "map_file.h" + +#ifndef MAX_FILE_SIZE +#define MAX_FILE_SIZE (1<<20) // 1 GB max file size +#endif + +int map_file(mapped_file_t *mf, const char *path) { + int error = -1; + struct stat st; + + const int fd = open(path, O_RDONLY | O_BINARY); + + if (fd == -1) { + fprintf(stderr, "open(%s) == -1\n", path); + return (-1); + } + + if (fstat(fd, &st) == -1) { + fprintf(stderr, "fstat(%s) == -1\n", path); + goto on_error; + } + + if (sizeof(st.st_size) != sizeof(size_t)) { + // on 32 bit systems, check if there is an overflow + if (st.st_size > (off_t)MAX_FILE_SIZE /*1 GB*/ ) { + // limit file size to 1 GB + fprintf(stderr, "mmap() size_t overflow for file %s\n", path); + goto on_error; + } + } + + mf->base = + (uint8_t *)mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); + + if (mf->base == MAP_FAILED) { + fprintf(stderr, "mmap() == MAP_FAILED for file %s\n", path); + goto on_error; + } + + mf->len = (size_t)st.st_size; + error = 0; // success + +on_error: + close(fd); + return (error); +} + +void unmap_file(mapped_file_t *mf) { + munmap((void *)mf->base, mf->len); + mf->base = (unsigned char *)MAP_FAILED; + mf->len = 0; +} diff --git a/src/map_file.h b/src/map_file.h new file mode 100644 index 000000000..b35f24ad0 --- /dev/null +++ b/src/map_file.h @@ -0,0 +1,28 @@ +/* + * File: map_file.h + * + * TODO: add a description + */ + +#ifndef MAP_FILE_H +#define MAP_FILE_H + +#ifdef STLINK_HAVE_SYS_MMAN_H +#include +#else +#include +#endif + +/* Memory mapped file */ +typedef struct mapped_file { + uint8_t *base; + size_t len; +} mapped_file_t; + +#define MAPPED_FILE_INITIALIZER \ + { NULL, 0 } + +int map_file(mapped_file_t *, const char *); +void unmap_file(mapped_file_t *); + +#endif // MAP_FILE_H diff --git a/src/option.c b/src/option.c new file mode 100644 index 000000000..b70f7a533 --- /dev/null +++ b/src/option.c @@ -0,0 +1,1026 @@ +#include +#include +#include "common_flash.h" +#include "map_file.h" +#include "common.h" + +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_Gx(stlink_t *sl, + uint32_t *option_byte) { + return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_Gx(sl, option_byte); +} + +/** + * Read first option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte) { + DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); + return stlink_read_debug32(sl, sl->option_base, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f2(stlink_t *sl, + uint32_t *option_byte) { + return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_f2(sl, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f4(stlink_t *sl, + uint32_t *option_byte) { + return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_f4(sl, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + * + * Since multiple bytes can be read, we read and print all but one here + * and then return the last one just like other devices + */ +int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t *option_byte) { + int err = -1; + for (uint32_t counter = 0; counter < (sl->option_size / 4 - 1); counter++) { + err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), + option_byte); + if (err == -1) { + return err; + } else { + printf("%08x\n", *option_byte); + } + } + + return stlink_read_debug32( + sl, + sl->option_base + (uint32_t)(sl->option_size / 4 - 1) * sizeof(uint32_t), + option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return (-1); + } + + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F2: + return stlink_read_option_bytes_f2(sl, option_byte); + case STLINK_CHIPID_STM32_F4: + case STLINK_CHIPID_STM32_F446: + return stlink_read_option_bytes_f4(sl, option_byte); + case STLINK_CHIPID_STM32_F76xxx: + return stlink_read_option_bytes_f7(sl, option_byte); + case STLINK_CHIPID_STM32_G0_CAT1: + case STLINK_CHIPID_STM32_G0_CAT2: + case STLINK_CHIPID_STM32_G4_CAT2: + case STLINK_CHIPID_STM32_G4_CAT3: + return stlink_read_option_bytes_Gx(sl, option_byte); + default: + return stlink_read_option_bytes_generic(sl, option_byte); + } +} + + +/** + * Write option bytes + * @param sl + * @param base option bytes to write + * @param addr of the memory mapped option bytes + * @param len of options bytes to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_f0( + stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { + int ret = 0; + + if (len < 12 || addr != STM32_F0_OPTION_BYTES_BASE) { + WLOG("Only full write of option bytes area is supported\n"); + return -1; + } + + clear_flash_error(sl); + + WLOG("Erasing option bytes\n"); + + /* erase option bytes */ + stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTER) | (1 << FLASH_CR_OPTWRE)); + ret = stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTER) | (1 << FLASH_CR_STRT) | (1 << FLASH_CR_OPTWRE)); + if (ret) { + return ret; + } + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (ret) { + return ret; + } + + WLOG("Writing option bytes to %#10x\n", addr); + + /* Set the Option PG bit to enable programming */ + stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTPG) | (1 << FLASH_CR_OPTWRE)); + + /* Use flash loader for write OP + * because flash memory writable by half word */ + flash_loader_t fl; + ret = stlink_flash_loader_init(sl, &fl); + if (ret) { + return ret; + } + ret = stlink_flash_loader_run(sl, &fl, addr, base, len); + if (ret) { + return ret; + } + + /* Reload option bytes */ + stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OBL_LAUNCH)); + + return check_flash_error(sl); +} + +/** + * Write option bytes + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + /* Write options bytes */ + uint32_t val; + int ret = 0; + (void)len; + uint32_t data; + + clear_flash_error(sl); + + write_uint32((unsigned char *)&data, *(uint32_t *)(base)); + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); + + // Set Options Start bit + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + + // Reload options + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + + return (ret); +} + +/** + * Write option bytes + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t flash_base = get_stm32l0_flash_base(sl); + uint32_t val; + uint32_t data; + int ret = 0; + + // Clear errors + clear_flash_error(sl); + + while (len != 0) { + write_uint32((unsigned char *)&data, + *(uint32_t *)(base)); // write options bytes + + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + stlink_write_debug32(sl, addr, data); + wait_flash_busy(sl); + + if ((ret = check_flash_error(sl))) { + break; + } + + len -= 4; + addr += 4; + base += 4; + } + + // Reload options + stlink_read_debug32(sl, flash_base + FLASH_PECR_OFF, &val); + val |= (1 << STM32L0_FLASH_OBL_LAUNCH); + stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); + + return (ret); +} + +/** + * Write option bytes + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_l4(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + + uint32_t val; + int ret = 0; + (void)addr; + (void)len; + + // Clear errors + clear_flash_error(sl); + + // write options bytes + uint32_t data; + write_uint32((unsigned char *)&data, *(uint32_t *)(base)); + WLOG("Writing option bytes 0x%04x\n", data); + stlink_write_debug32(sl, STM32L4_FLASH_OPTR, data); + + // set options start bit + stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); + val |= (1 << STM32L4_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + + wait_flash_busy(sl); + ret = check_flash_error(sl); + + // apply options bytes immediate + stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); + val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); + stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + + return (ret); +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t option_byte; + int ret = 0; + (void)addr; + (void)len; + + // Clear errors + clear_flash_error(sl); + + write_uint32((unsigned char *)&option_byte, *(uint32_t *)(base)); + + // write option byte, ensuring we dont lock opt, and set strt bit + stlink_write_debug32(sl, FLASH_F4_OPTCR, + (option_byte & ~(1 << FLASH_F4_OPTCR_LOCK)) | + (1 << FLASH_F4_OPTCR_START)); + + wait_flash_busy(sl); + ret = check_flash_error(sl); + + // option bytes are reloaded at reset only, no obl. */ + return (ret); +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t option_byte; + int ret = 0; + + // Clear errors + clear_flash_error(sl); + + ILOG("Asked to write option byte %#10x to %#010x.\n", *(uint32_t *)(base), + addr); + write_uint32((unsigned char *)&option_byte, *(uint32_t *)(base)); + ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); + + if (addr == 0) { + addr = FLASH_F7_OPTCR; + ILOG("No address provided, using %#10x\n", addr); + } + + if (addr == FLASH_F7_OPTCR) { + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F7_OPTCR, + (option_byte & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); + } else if (addr == FLASH_F7_OPTCR1) { + // Read FLASH_F7_OPTCR + uint32_t oldvalue; + stlink_read_debug32(sl, FLASH_F7_OPTCR, &oldvalue); + /* write option byte */ + stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_byte); + // Write FLASH_F7_OPTCR lock and start address + stlink_write_debug32(sl, FLASH_F7_OPTCR, + (oldvalue & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); + } else { + WLOG("WIP: write %#010x to address %#010x\n", option_byte, addr); + stlink_write_debug32(sl, addr, option_byte); + } + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t *)base, + addr); + + /* option bytes are reloaded at reset only, no obl. */ + + return ret; +} + +/** + * Write STM32H7xx option bytes + * @param sl + * @param base option bytes to write + * @param addr of the memory mapped option bytes + * @param len number of bytes to write (must be multiple of 4) + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_h7(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t val; + uint32_t data; + + // Wait until previous flash option has completed + wait_flash_busy(sl); + + // Clear previous error + stlink_write_debug32(sl, FLASH_H7_OPTCCR, + 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); + + while (len != 0) { + switch (addr) { + case FLASH_H7_REGS_ADDR + 0x20: // FLASH_OPTSR_PRG + case FLASH_H7_REGS_ADDR + 0x2c: // FLASH_PRAR_PRG1 + case FLASH_H7_REGS_ADDR + 0x34: // FLASH_SCAR_PRG1 + case FLASH_H7_REGS_ADDR + 0x3c: // FLASH_WPSN_PRG1 + case FLASH_H7_REGS_ADDR + 0x44: // FLASH_BOOT_PRG + /* Write to FLASH_xxx_PRG registers */ + write_uint32((unsigned char *)&data, + *(uint32_t *)(base)); // write options bytes + + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + + /* Skip if the value in the CUR register is identical */ + stlink_read_debug32(sl, addr - 4, &val); + if (val == data) { + break; + } + + /* Write new option byte values and start modification */ + stlink_write_debug32(sl, addr, data); + stlink_read_debug32(sl, FLASH_H7_OPTCR, &val); + val |= (1 << FLASH_H7_OPTCR_OPTSTART); + stlink_write_debug32(sl, FLASH_H7_OPTCR, val); + + /* Wait for the option bytes modification to complete */ + do { + stlink_read_debug32(sl, FLASH_H7_OPTSR_CUR, &val); + } while ((val & (1 << FLASH_H7_OPTSR_OPT_BUSY)) != 0); + + /* Check for errors */ + if ((val & (1 << FLASH_H7_OPTSR_OPTCHANGEERR)) != 0) { + stlink_write_debug32(sl, FLASH_H7_OPTCCR, + 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); + return -1; + } + break; + + default: + /* Skip non-programmable registers */ + break; + } + + len -= 4; + addr += 4; + base += 4; + } + + return 0; +} + +/** + * Write option bytes + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, + uint32_t len) { + int ret = -1; + + if (sl->option_base == 0) { + ELOG( + "Option bytes writing is currently not supported for connected chip\n"); + return (-1); + } + + if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { + ELOG("Option bytes start address out of Option bytes range\n"); + return (-1); + } + + if (addr + len > sl->option_base + sl->option_size) { + ELOG("Option bytes data too long\n"); + return (-1); + } + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return (-1); + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return (-1); + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + ret = stlink_write_option_bytes_f0(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_F4: + ret = stlink_write_option_bytes_f4(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_bytes_f7(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_L0: + ret = stlink_write_option_bytes_l0(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_L4: + ret = stlink_write_option_bytes_l4(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + ret = stlink_write_option_bytes_gx(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_H7: + ret = stlink_write_option_bytes_h7(sl, base, addr, len); + break; + default: + ELOG("Option bytes writing is currently not implemented for connected " + "chip\n"); + break; + } + + if (ret) { + ELOG("Flash option write failed!\n"); + } else { + ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + } + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; +} + + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int +stlink_write_option_control_register_f0(stlink_t *sl, + uint32_t option_control_register) { + int ret = 0; + uint16_t opt_val[8]; + unsigned protection, optiondata; + uint16_t user_options, user_data, rdp; + unsigned option_offset, user_data_offset; + + ILOG("Asked to write option control register %#10x to %#010x.\n", + option_control_register, FLASH_OBR); + + /* Clear errors */ + clear_flash_error(sl); + + /* Retrieve current values */ + ret = stlink_read_debug32(sl, FLASH_OBR, &optiondata); + if (ret) { + return ret; + } + ret = stlink_read_debug32(sl, FLASH_WRPR, &protection); + if (ret) { + return ret; + } + + /* Translate OBR value to flash store structure + * F0: RM0091, Option byte description, pp. 75-78 + * F1: PM0075, Option byte description, pp. 19-22 + * F3: RM0316, Option byte description, pp. 85-87 */ + switch(sl->chip_id) + { + case 0x422: /* STM32F30x */ + case 0x432: /* STM32F37x */ + case 0x438: /* STM32F303x6/8 and STM32F328 */ + case 0x446: /* STM32F303xD/E and STM32F398xE */ + case 0x439: /* STM32F302x6/8 */ + case 0x440: /* STM32F05x */ + case 0x444: /* STM32F03x */ + case 0x445: /* STM32F04x */ + case 0x448: /* STM32F07x */ + case 0x442: /* STM32F09x */ + option_offset = 6; + user_data_offset = 16; + rdp = 0x55AA; + break; + default: + option_offset = 0; + user_data_offset = 10; + rdp = 0x5AA5; + break; + } + + user_options = (option_control_register >> option_offset >> 2) & 0xFFFF; + user_data = (option_control_register >> user_data_offset) & 0xFFFF; + +#define VAL_WITH_COMPLEMENT(v) (uint16_t)(((v)&0xFF) | (((~(v))<<8)&0xFF00)) + + opt_val[0] = (option_control_register & (1 << 1/*OPT_READOUT*/)) ? 0xFFFF : rdp; + opt_val[1] = VAL_WITH_COMPLEMENT(user_options); + opt_val[2] = VAL_WITH_COMPLEMENT(user_data); + opt_val[3] = VAL_WITH_COMPLEMENT(user_data >> 8); + opt_val[4] = VAL_WITH_COMPLEMENT(protection); + opt_val[5] = VAL_WITH_COMPLEMENT(protection >> 8); + opt_val[6] = VAL_WITH_COMPLEMENT(protection >> 16); + opt_val[7] = VAL_WITH_COMPLEMENT(protection >> 24); + +#undef VAL_WITH_COMPLEMENT + + /* Write bytes and check errors */ + ret = stlink_write_option_bytes_f0(sl, (uint8_t*)opt_val, STM32_F0_OPTION_BYTES_BASE, sizeof(opt_val)); + if (ret) + return ret; + + ret = check_flash_error(sl); + if (!ret) { + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, + FLASH_OBR); + } + + return ret; +} + + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int +stlink_write_option_control_register1_f7(stlink_t *sl, + uint32_t option_control_register1) { + int ret = 0; + + // Clear errors + clear_flash_error(sl); + + ILOG("Asked to write option control register 1 %#010x to %#010x.\n", + option_control_register1, FLASH_F7_OPTCR1); + + /* write option byte, ensuring we dont lock opt, and set strt bit */ + uint32_t current_control_register_value; + stlink_read_debug32(sl, FLASH_F7_OPTCR, ¤t_control_register_value); + + /* write option byte */ + stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_control_register1); + stlink_write_debug32( + sl, FLASH_F7_OPTCR, + (current_control_register_value & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register1, + FLASH_F7_OPTCR1); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int +stlink_write_option_control_register_f7(stlink_t *sl, + uint32_t option_control_register) { + int ret = 0; + + // Clear errors + clear_flash_error(sl); + + ILOG("Asked to write option control register 1 %#10x to %#010x.\n", + option_control_register, FLASH_F7_OPTCR); + + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F7_OPTCR, + (option_control_register & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, + FLASH_F7_OPTCR); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option bytes boot address to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_control_register32(stlink_t *sl, + uint32_t option_control_register) { + int ret = -1; + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return -1; + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + ret = stlink_write_option_control_register_f0(sl, option_control_register); + break; + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_control_register_f7(sl, option_control_register); + break; + default: + ELOG("Option control register writing is currently not implemented for " + "connected chip\n"); + break; + } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option control register %#010x!\n", option_control_register); + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option bytes boot address to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_control_register1_32( + stlink_t *sl, uint32_t option_control_register1) { + int ret = -1; + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return -1; + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + ret = + stlink_write_option_control_register1_f7(sl, option_control_register1); + break; + default: + ELOG("Option control register 1 writing is currently not implemented for " + "connected chip\n"); + break; + } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option control register 1 %#010x!\n", option_control_register1); + + lock_flash_option(sl); + lock_flash(sl); + + return (ret); +} + + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int +stlink_write_option_bytes_boot_add_f7(stlink_t *sl, + uint32_t option_byte_boot_add) { + ILOG("Asked to write option byte boot add %#010x.\n", option_byte_boot_add); + return stlink_write_option_control_register1_f7(sl, option_byte_boot_add); +} + +/** + * Write option bytes + * @param sl + * @param option bytes boot address to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_bytes_boot_add32(stlink_t *sl, + uint32_t option_bytes_boot_add) { + int ret = -1; + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return -1; + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); + break; + default: + ELOG("Option bytes boot address writing is currently not implemented for " + "connected chip\n"); + break; + } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option bytes boot address %#010x!\n", option_bytes_boot_add); + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { + WLOG("About to write option byte %#10x to %#10x.\n", option_byte, + sl->option_base); + return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *)&option_byte, + 4); +} + +/** + * Write the given binary file with option bytes + * @param sl + * @param path readable file path, should be binary image + * @param addr of the memory mapped option bytes + * @return 0 on success, -ve on failure. + */ +int stlink_fwrite_option_bytes(stlink_t *sl, const char *path, + stm32_addr_t addr) { + /* Write the file in flash at addr */ + int err; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; + + if (map_file(&mf, path) == -1) { + ELOG("map_file() == -1\n"); + return (-1); + } + + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); + + err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t)mf.len); + stlink_fwrite_finalize(sl, addr); + unmap_file(&mf); + + return (err); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register1_f7(stlink_t *sl, + uint32_t *option_byte) { + DLOG("@@@@ Read option control register 1 byte from %#10x\n", + FLASH_F7_OPTCR1); + return stlink_read_debug32(sl, FLASH_F7_OPTCR1, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register1_32(stlink_t *sl, + uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + return stlink_read_option_control_register1_f7(sl, option_byte); + default: + return -1; + // return stlink_read_option_control_register1_generic(sl, option_byte); + } +} + + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t *option_byte) { + DLOG("@@@@ Read option byte boot address\n"); + return stlink_read_option_control_register1_f7(sl, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes boot address read is currently not supported for " + "connected chip\n"); + return -1; + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + return stlink_read_option_bytes_boot_add_f7(sl, option_byte); + default: + return -1; + // return stlink_read_option_bytes_boot_add_generic(sl, option_byte); + } +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f7(stlink_t *sl, + uint32_t *option_byte) { + DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_F7_OPTCR); + return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f0(stlink_t *sl, + uint32_t *option_byte) { + DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_OBR); + return stlink_read_debug32(sl, FLASH_OBR, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + return stlink_read_option_control_register_f0(sl, option_byte); + case STLINK_FLASH_TYPE_F7: + return stlink_read_option_control_register_f7(sl, option_byte); + default: + return -1; + } +} diff --git a/src/read_write.c b/src/read_write.c new file mode 100644 index 000000000..adcda6f3b --- /dev/null +++ b/src/read_write.c @@ -0,0 +1,142 @@ +#include +#include + +// Endianness +// https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html +// These functions encode and decode little endian uint16 and uint32 values. + +void write_uint32(unsigned char *buf, uint32_t ui) { + buf[0] = ui; + buf[1] = ui >> 8; + buf[2] = ui >> 16; + buf[3] = ui >> 24; +} + +void write_uint16(unsigned char *buf, uint16_t ui) { + buf[0] = (uint8_t)ui; + buf[1] = (uint8_t)(ui >> 8); +} + +uint32_t read_uint32(const unsigned char *c, const int pt) { + return ((uint32_t)c[pt]) | ((uint32_t)c[pt + 1] << 8) | + ((uint32_t)c[pt + 2] << 16) | ((uint32_t)c[pt + 3] << 24); +} + +uint16_t read_uint16(const unsigned char *c, const int pt) { + return ((uint16_t)c[pt]) | ((uint16_t)c[pt + 1] << 8); +} + +int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { + int ret; + + ret = sl->backend->read_debug32(sl, addr, data); + if (!ret) + DLOG("*** stlink_read_debug32 %#010x at %#010x\n", *data, addr); + + return (ret); +} + +int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { + DLOG("*** stlink_write_debug32 %#010x to %#010x\n", data, addr); + return sl->backend->write_debug32(sl, addr, data); +} + +int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { + DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); + + if (len % 4 != 0) { + ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); + return (-1); + } + + return (sl->backend->write_mem32(sl, addr, len)); +} + +int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { + DLOG("*** stlink_read_mem32 ***\n"); + + if (len % 4 != 0) { // !!! never ever: fw gives just wrong values + ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); + return (-1); + } + + return (sl->backend->read_mem32(sl, addr, len)); +} + +int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { + DLOG("*** stlink_write_mem8 ***\n"); + return (sl->backend->write_mem8(sl, addr, len)); +} + +int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { + DLOG("*** stlink_read_all_regs ***\n"); + return (sl->backend->read_all_regs(sl, regp)); +} + +int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { + DLOG("*** stlink_read_all_unsupported_regs ***\n"); + return (sl->backend->read_all_unsupported_regs(sl, regp)); +} + +int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) { + DLOG("*** stlink_write_reg\n"); + return (sl->backend->write_reg(sl, reg, idx)); +} + +int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { + DLOG("*** stlink_read_reg\n"); + DLOG(" (%d) ***\n", r_idx); + + if (r_idx > 20 || r_idx < 0) { + fprintf(stderr, "Error: register index must be in [0..20]\n"); + return (-1); + } + + return (sl->backend->read_reg(sl, r_idx, regp)); +} + +int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, + struct stlink_reg *regp) { + int r_convert; + + DLOG("*** stlink_read_unsupported_reg\n"); + DLOG(" (%d) ***\n", r_idx); + + /* Convert to values used by STLINK_REG_DCRSR */ + if (r_idx >= 0x1C && + r_idx <= 0x1F) { // primask, basepri, faultmask, or control + r_convert = 0x14; + } else if (r_idx == 0x40) { // FPSCR + r_convert = 0x21; + } else if (r_idx >= 0x20 && r_idx < 0x40) { + r_convert = 0x40 + (r_idx - 0x20); + } else { + fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); + return (-1); + } + + return (sl->backend->read_unsupported_reg(sl, r_convert, regp)); +} + +int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, + struct stlink_reg *regp) { + int r_convert; + + DLOG("*** stlink_write_unsupported_reg\n"); + DLOG(" (%d) ***\n", r_idx); + + /* Convert to values used by STLINK_REG_DCRSR */ + if (r_idx >= 0x1C && + r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ + r_convert = r_idx; // the backend function handles this + } else if (r_idx == 0x40) { // FPSCR + r_convert = 0x21; + } else if (r_idx >= 0x20 && r_idx < 0x40) { + r_convert = 0x40 + (r_idx - 0x20); + } else { + fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); + return (-1); + } + + return (sl->backend->write_unsupported_reg(sl, val, r_convert, regp)); +} From 4ce20d07e0fedd103a0f24f583ea591f8eb12694 Mon Sep 17 00:00:00 2001 From: hydroconstructor Date: Thu, 20 Jan 2022 13:46:42 +0400 Subject: [PATCH 1291/1435] stlink-org#1216 refactoring of common.c File divided to some parts. Functions with "flash" in names extracted to common_flash.c, with "option" extracted to option.c etc. Removed unnecessary headers. Removed one single function which was used nowhere. And so on. Project built under Windows and seems to be working. --- src/common.c | 5701 +++++++++----------------------------------- src/common_flash.c | 1 + src/flashloader.c | 1 + src/map_file.c | 7 + src/option.c | 1 + src/read_write.c | 1 + 6 files changed, 1090 insertions(+), 4622 deletions(-) diff --git a/src/common.c b/src/common.c index 6cbd217ef..0f8117fea 100644 --- a/src/common.c +++ b/src/common.c @@ -1,27 +1,17 @@ -#define DEBUG_FLASH 0 -#include -#include -#include -#include -#include - -#include +#include #include -#include #include #include #include - -#include -#include +#include +#include #include +#include #include - -#ifdef STLINK_HAVE_SYS_MMAN_H -#include -#else -#include -#endif +#include "common_flash.h" +#include "calculate.h" +#include "map_file.h" +#include "common.h" #ifndef O_BINARY #define O_BINARY 0 @@ -31,4922 +21,1389 @@ #define __attribute__(x) #endif -#define BANK_1 0 -#define BANK_2 1 - -/* stm32f FPEC flash controller interface, pm0063 manual */ -// TODO - all of this needs to be abstracted out.... -// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, -// August 2012) -#define FLASH_REGS_ADDR 0x40022000 -#define FLASH_REGS_SIZE 0x28 - -#define FLASH_ACR (FLASH_REGS_ADDR + 0x00) -#define FLASH_KEYR (FLASH_REGS_ADDR + 0x04) -#define FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x08) -#define FLASH_SR (FLASH_REGS_ADDR + 0x0c) -#define FLASH_CR (FLASH_REGS_ADDR + 0x10) -#define FLASH_AR (FLASH_REGS_ADDR + 0x14) -#define FLASH_OBR (FLASH_REGS_ADDR + 0x1c) -#define FLASH_WRPR (FLASH_REGS_ADDR + 0x20) - -// STM32F10x_XL has two flash memory banks with separate registers to control -// the second bank. -#define FLASH_KEYR2 (FLASH_REGS_ADDR + 0x44) -#define FLASH_SR2 (FLASH_REGS_ADDR + 0x4c) -#define FLASH_CR2 (FLASH_REGS_ADDR + 0x50) -#define FLASH_AR2 (FLASH_REGS_ADDR + 0x54) - -// For STM32F05x, the RDPTR_KEY may be wrong, but as it is not used anywhere... -#define FLASH_RDPTR_KEY 0x00a5 -#define FLASH_KEY1 0x45670123 -#define FLASH_KEY2 0xcdef89ab - -#define FLASH_L0_PRGKEY1 0x8c9daebf -#define FLASH_L0_PRGKEY2 0x13141516 - -#define FLASH_L0_PEKEY1 0x89abcdef -#define FLASH_L0_PEKEY2 0x02030405 - -#define FLASH_OPTKEY1 0x08192A3B -#define FLASH_OPTKEY2 0x4C5D6E7F - -#define FLASH_F0_OPTKEY1 0x45670123 -#define FLASH_F0_OPTKEY2 0xCDEF89AB - -#define FLASH_L0_OPTKEY1 0xFBEAD9C8 -#define FLASH_L0_OPTKEY2 0x24252627 - -#define FLASH_SR_BSY 0 -#define FLASH_SR_PG_ERR 2 -#define FLASH_SR_WRPRT_ERR 4 -#define FLASH_SR_EOP 5 - -#define FLASH_SR_ERROR_MASK ((1 << FLASH_SR_PG_ERR) | (1 << FLASH_SR_WRPRT_ERR)) - -#define FLASH_CR_PG 0 -#define FLASH_CR_PER 1 -#define FLASH_CR_MER 2 -#define FLASH_CR_OPTPG 4 -#define FLASH_CR_OPTER 5 -#define FLASH_CR_STRT 6 -#define FLASH_CR_LOCK 7 -#define FLASH_CR_OPTWRE 9 -#define FLASH_CR_OBL_LAUNCH 13 - -#define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00) -#define STM32L_FLASH_ACR (STM32L_FLASH_REGS_ADDR + 0x00) -#define STM32L_FLASH_PECR (STM32L_FLASH_REGS_ADDR + 0x04) -#define STM32L_FLASH_PDKEYR (STM32L_FLASH_REGS_ADDR + 0x08) -#define STM32L_FLASH_PEKEYR (STM32L_FLASH_REGS_ADDR + 0x0c) -#define STM32L_FLASH_PRGKEYR (STM32L_FLASH_REGS_ADDR + 0x10) -#define STM32L_FLASH_OPTKEYR (STM32L_FLASH_REGS_ADDR + 0x14) -#define STM32L_FLASH_SR (STM32L_FLASH_REGS_ADDR + 0x18) -#define STM32L_FLASH_OBR (STM32L_FLASH_REGS_ADDR + 0x1c) -#define STM32L_FLASH_WRPR (STM32L_FLASH_REGS_ADDR + 0x20) -#define FLASH_L1_FPRG 10 -#define FLASH_L1_PROG 3 - -// Flash registers common to STM32G0 and STM32G4 series. -#define STM32Gx_FLASH_REGS_ADDR ((uint32_t)0x40022000) -#define STM32Gx_FLASH_ACR (STM32Gx_FLASH_REGS_ADDR + 0x00) -#define STM32Gx_FLASH_KEYR (STM32Gx_FLASH_REGS_ADDR + 0x08) -#define STM32Gx_FLASH_OPTKEYR (STM32Gx_FLASH_REGS_ADDR + 0x0c) -#define STM32Gx_FLASH_SR (STM32Gx_FLASH_REGS_ADDR + 0x10) -#define STM32Gx_FLASH_CR (STM32Gx_FLASH_REGS_ADDR + 0x14) -#define STM32Gx_FLASH_ECCR (STM32Gx_FLASH_REGS_ADDR + 0x18) -#define STM32Gx_FLASH_OPTR (STM32Gx_FLASH_REGS_ADDR + 0x20) - -// G0 (RM0444 Table 1, sec 3.7) -// Mostly the same as G4 chips, but the notation -// varies a bit after the 'OPTR' register. -#define STM32G0_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) -#define STM32G0_FLASH_PCROP1ASR (STM32G0_FLASH_REGS_ADDR + 0x24) -#define STM32G0_FLASH_PCROP1AER (STM32G0_FLASH_REGS_ADDR + 0x28) -#define STM32G0_FLASH_WRP1AR (STM32G0_FLASH_REGS_ADDR + 0x2C) -#define STM32G0_FLASH_WRP1BR (STM32G0_FLASH_REGS_ADDR + 0x30) -#define STM32G0_FLASH_PCROP1BSR (STM32G0_FLASH_REGS_ADDR + 0x34) -#define STM32G0_FLASH_PCROP1BER (STM32G0_FLASH_REGS_ADDR + 0x38) -#define STM32G0_FLASH_SECR (STM32G0_FLASH_REGS_ADDR + 0x80) - -// G4 (RM0440 Table 17, sec 3.7.19) -// Mostly the same as STM32G0 chips, but there are a few extra -// registers because 'cat 3' devices can have two Flash banks. -#define STM32G4_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) -#define STM32G4_FLASH_PDKEYR (STM32G4_FLASH_REGS_ADDR + 0x04) -#define STM32G4_FLASH_PCROP1SR (STM32G4_FLASH_REGS_ADDR + 0x24) -#define STM32G4_FLASH_PCROP1ER (STM32G4_FLASH_REGS_ADDR + 0x28) -#define STM32G4_FLASH_WRP1AR (STM32G4_FLASH_REGS_ADDR + 0x2C) -#define STM32G4_FLASH_WRP1BR (STM32G4_FLASH_REGS_ADDR + 0x30) -#define STM32G4_FLASH_PCROP2SR (STM32G4_FLASH_REGS_ADDR + 0x44) -#define STM32G4_FLASH_PCROP2ER (STM32G4_FLASH_REGS_ADDR + 0x48) -#define STM32G4_FLASH_WRP2AR (STM32G4_FLASH_REGS_ADDR + 0x4C) -#define STM32G4_FLASH_WRP2BR (STM32G4_FLASH_REGS_ADDR + 0x50) -#define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70) -#define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74) - -// G0/G4 FLASH control register -#define STM32Gx_FLASH_CR_PG (0) /* Program */ -#define STM32Gx_FLASH_CR_PER (1) /* Page erase */ -#define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */ -#define STM32Gx_FLASH_CR_PNB (3) /* Page number */ -#define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ -#define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ -#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ -#define STM32Gx_FLASH_CR_STRT (16) /* Start */ -#define STM32Gx_FLASH_CR_OPTSTRT \ - (17) /* Start of modification of option bytes */ -#define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ -#define STM32Gx_FLASH_CR_EOPIE (24) /* End of operation interrupt enable */ -#define STM32Gx_FLASH_CR_ERRIE (25) /* Error interrupt enable */ -#define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ -#define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ -#define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ - -// G0/G4 FLASH status register -#define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) -#define STM32Gx_FLASH_SR_PROGERR (3) -#define STM32Gx_FLASH_SR_WRPERR (4) -#define STM32Gx_FLASH_SR_PGAERR (5) -#define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ -#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ - -// G4 FLASH option register -#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ - -// WB (RM0434) -#define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) -#define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) -#define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) -#define STM32WB_FLASH_OPT_KEYR (STM32WB_FLASH_REGS_ADDR + 0x0C) -#define STM32WB_FLASH_SR (STM32WB_FLASH_REGS_ADDR + 0x10) -#define STM32WB_FLASH_CR (STM32WB_FLASH_REGS_ADDR + 0x14) -#define STM32WB_FLASH_ECCR (STM32WB_FLASH_REGS_ADDR + 0x18) -#define STM32WB_FLASH_OPTR (STM32WB_FLASH_REGS_ADDR + 0x20) -#define STM32WB_FLASH_PCROP1ASR (STM32WB_FLASH_REGS_ADDR + 0x24) -#define STM32WB_FLASH_PCROP1AER (STM32WB_FLASH_REGS_ADDR + 0x28) -#define STM32WB_FLASH_WRP1AR (STM32WB_FLASH_REGS_ADDR + 0x2C) -#define STM32WB_FLASH_WRP1BR (STM32WB_FLASH_REGS_ADDR + 0x30) -#define STM32WB_FLASH_PCROP1BSR (STM32WB_FLASH_REGS_ADDR + 0x34) -#define STM32WB_FLASH_PCROP1BER (STM32WB_FLASH_REGS_ADDR + 0x38) -#define STM32WB_FLASH_IPCCBR (STM32WB_FLASH_REGS_ADDR + 0x3C) -#define STM32WB_FLASH_C2ACR (STM32WB_FLASH_REGS_ADDR + 0x5C) -#define STM32WB_FLASH_C2SR (STM32WB_FLASH_REGS_ADDR + 0x60) -#define STM32WB_FLASH_C2CR (STM32WB_FLASH_REGS_ADDR + 0x64) -#define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) -#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) - -// WB Flash control register. -#define STM32WB_FLASH_CR_STRT (16) /* Start */ -#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ -#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ -// WB Flash status register. -#define STM32WB_FLASH_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ -#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ -#define STM32WB_FLASH_SR_WRPERR (4) /* Write protection error */ -#define STM32WB_FLASH_SR_PGAERR (5) /* Programming error */ -#define STM32WB_FLASH_SR_BSY (16) /* Busy */ - -// 32L4 register base is at FLASH_REGS_ADDR (0x40022000) -#define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) -#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) -#define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) -#define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) -#define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) - -#define STM32L4_FLASH_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ -#define STM32L4_FLASH_SR_PROGERR 3 -#define STM32L4_FLASH_SR_WRPERR 4 -#define STM32L4_FLASH_SR_PGAERR 5 -#define STM32L4_FLASH_SR_BSY 16 - -#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ -#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ -#define STM32L4_FLASH_CR_PG 0 /* Program */ -#define STM32L4_FLASH_CR_PER 1 /* Page erase */ -#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ -#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ -#define STM32L4_FLASH_CR_STRT 16 /* Start command */ -#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ -#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ -#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ -#define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ -// Bits requesting flash operations (useful when we want to clear them) -#define STM32L4_FLASH_CR_OPBITS \ - (uint32_t)((1lu << STM32L4_FLASH_CR_PG) | (1lu << STM32L4_FLASH_CR_PER) | \ - (1lu << STM32L4_FLASH_CR_MER1) | (1lu << STM32L4_FLASH_CR_MER1)) -// Page is fully specified by BKER and PNB -#define STM32L4_FLASH_CR_PAGEMASK (uint32_t)(0x1fflu << STM32L4_FLASH_CR_PNB) - -#define STM32L4_FLASH_OPTR_DUALBANK 21 - -// STM32L0x flash register base and offsets RM0090 - DM00031020.pdf -#define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) - -#define STM32L0_FLASH_PELOCK (0) -#define STM32L0_FLASH_OPTLOCK (2) -#define STM32L0_FLASH_OBL_LAUNCH (18) - -#define STM32L0_FLASH_SR_ERROR_MASK 0x00013F00 -#define STM32L0_FLASH_SR_WRPERR 8 -#define STM32L0_FLASH_SR_PGAERR 9 -#define STM32L0_FLASH_SR_NOTZEROERR 16 - -#define FLASH_ACR_OFF ((uint32_t)0x00) -#define FLASH_PECR_OFF ((uint32_t)0x04) -#define FLASH_PDKEYR_OFF ((uint32_t)0x08) -#define FLASH_PEKEYR_OFF ((uint32_t)0x0c) -#define FLASH_PRGKEYR_OFF ((uint32_t)0x10) -#define FLASH_OPTKEYR_OFF ((uint32_t)0x14) -#define FLASH_SR_OFF ((uint32_t)0x18) -#define FLASH_OBR_OFF ((uint32_t)0x1c) -#define FLASH_WRPR_OFF ((uint32_t)0x20) - -// STM32F7 -#define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) -#define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) -#define FLASH_F7_SR (FLASH_F7_REGS_ADDR + 0x0c) -#define FLASH_F7_CR (FLASH_F7_REGS_ADDR + 0x10) -#define FLASH_F7_OPTCR (FLASH_F7_REGS_ADDR + 0x14) -#define FLASH_F7_OPTCR1 (FLASH_F7_REGS_ADDR + 0x18) -#define FLASH_F7_OPTCR_LOCK 0 -#define FLASH_F7_OPTCR_START 1 -#define FLASH_F7_CR_STRT 16 -#define FLASH_F7_CR_LOCK 31 -#define FLASH_F7_CR_SER 1 -#define FLASH_F7_CR_SNB 3 -#define FLASH_F7_CR_SNB_MASK 0xf8 -#define FLASH_F7_SR_BSY 16 -#define FLASH_F7_SR_ERS_ERR 7 /* Erase Sequence Error */ -#define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ -#define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ -#define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ -#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ -#define FLASH_F7_SR_EOP 0 /* End of operation */ -#define FLASH_F7_OPTCR1_BOOT_ADD0 0 -#define FLASH_F7_OPTCR1_BOOT_ADD1 16 - -#define FLASH_F7_SR_ERROR_MASK \ - ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | \ - (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | \ - (1 << FLASH_F7_SR_OP_ERR)) - -// STM32F4 -#define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) -#define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08) -#define FLASH_F4_SR (FLASH_F4_REGS_ADDR + 0x0c) -#define FLASH_F4_CR (FLASH_F4_REGS_ADDR + 0x10) -#define FLASH_F4_OPTCR (FLASH_F4_REGS_ADDR + 0x14) -#define FLASH_F4_OPTCR_LOCK 0 -#define FLASH_F4_OPTCR_START 1 -#define FLASH_F4_CR_STRT 16 -#define FLASH_F4_CR_LOCK 31 -#define FLASH_F4_CR_SER 1 -#define FLASH_F4_CR_SNB 3 -#define FLASH_F4_CR_SNB_MASK 0xf8 -#define FLASH_F4_SR_ERROR_MASK 0x000000F0 -#define FLASH_F4_SR_PGAERR 5 -#define FLASH_F4_SR_WRPERR 4 -#define FLASH_F4_SR_BSY 16 - -// STM32F2 -#define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F2_KEYR (FLASH_F2_REGS_ADDR + 0x04) -#define FLASH_F2_OPT_KEYR (FLASH_F2_REGS_ADDR + 0x08) -#define FLASH_F2_SR (FLASH_F2_REGS_ADDR + 0x0c) -#define FLASH_F2_CR (FLASH_F2_REGS_ADDR + 0x10) -#define FLASH_F2_OPT_CR (FLASH_F2_REGS_ADDR + 0x14) -#define FLASH_F2_OPT_LOCK_BIT (1u << 0) -#define FLASH_F2_CR_STRT 16 -#define FLASH_F2_CR_LOCK 31 - -#define FLASH_F2_CR_SER 1 -#define FLASH_F2_CR_SNB 3 -#define FLASH_F2_CR_SNB_MASK 0x78 -#define FLASH_F2_SR_BSY 16 - -// STM32H7xx -#define FLASH_H7_CR_LOCK 0 -#define FLASH_H7_CR_PG 1 -#define FLASH_H7_CR_SER 2 -#define FLASH_H7_CR_BER 3 -#define FLASH_H7_CR_PSIZE 4 -#define FLASH_H7_CR_START(chipid) (chipid == STLINK_CHIPID_STM32_H7Ax ? 5 : 7) -#define FLASH_H7_CR_SNB 8 -#define FLASH_H7_CR_SNB_MASK 0x700 - -#define FLASH_H7_SR_QW 2 -#define FLASH_H7_SR_WRPERR 17 -#define FLASH_H7_SR_PGSERR 18 -#define FLASH_H7_SR_STRBERR 19 -#define FLASH_H7_SR_ERROR_MASK \ - ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | \ - (1 << FLASH_H7_SR_WRPERR)) - -#define FLASH_H7_OPTCR_OPTLOCK 0 -#define FLASH_H7_OPTCR_OPTSTART 1 -#define FLASH_H7_OPTCR_MER 4 - -#define FLASH_H7_OPTSR_OPT_BUSY 0 -#define FLASH_H7_OPTSR_OPTCHANGEERR 30 - -#define FLASH_H7_OPTCCR_CLR_OPTCHANGEERR 30 - -#define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) -#define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) -#define FLASH_H7_KEYR2 (FLASH_H7_REGS_ADDR + 0x104) -#define FLASH_H7_OPT_KEYR (FLASH_H7_REGS_ADDR + 0x08) -#define FLASH_H7_OPT_KEYR2 (FLASH_H7_REGS_ADDR + 0x108) -#define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c) -#define FLASH_H7_CR2 (FLASH_H7_REGS_ADDR + 0x10c) -#define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) -#define FLASH_H7_SR2 (FLASH_H7_REGS_ADDR + 0x110) -#define FLASH_H7_CCR1 (FLASH_H7_REGS_ADDR + 0x14) -#define FLASH_H7_CCR2 (FLASH_H7_REGS_ADDR + 0x114) -#define FLASH_H7_OPTCR (FLASH_H7_REGS_ADDR + 0x18) -#define FLASH_H7_OPTCR2 (FLASH_H7_REGS_ADDR + 0x118) -#define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) -#define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) - -#define STM32F0_DBGMCU_CR 0xE0042004 -#define STM32F0_DBGMCU_CR_IWDG_STOP 8 -#define STM32F0_DBGMCU_CR_WWDG_STOP 9 - -#define STM32F4_DBGMCU_APB1FZR1 0xE0042008 -#define STM32F4_DBGMCU_APB1FZR1_WWDG_STOP 11 -#define STM32F4_DBGMCU_APB1FZR1_IWDG_STOP 12 - -#define STM32L0_DBGMCU_APB1_FZ 0x40015808 -#define STM32L0_DBGMCU_APB1_FZ_WWDG_STOP 11 -#define STM32L0_DBGMCU_APB1_FZ_IWDG_STOP 12 - -#define STM32H7_DBGMCU_APB1HFZ 0x5C001054 -#define STM32H7_DBGMCU_APB1HFZ_IWDG_STOP 18 - -#define STM32WB_DBGMCU_APB1FZR1 0xE004203C -#define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11 -#define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12 - -#define STM32F1_RCC_AHBENR 0x40021014 -#define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -#define STM32F4_RCC_AHB1ENR 0x40023830 -#define STM32F4_RCC_DMAEN 0x00600000 // DMA2EN | DMA1EN - -#define STM32G0_RCC_AHBENR 0x40021038 -#define STM32G0_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -#define STM32G4_RCC_AHB1ENR 0x40021048 -#define STM32G4_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -#define STM32L0_RCC_AHBENR 0x40021030 -#define STM32L0_RCC_DMAEN 0x00000001 // DMAEN - -#define STM32H7_RCC_AHB1ENR 0x58024538 -#define STM32H7_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -#define STM32WB_RCC_AHB1ENR 0x58000048 -#define STM32WB_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -#define L1_WRITE_BLOCK_SIZE 0x80 -#define L0_WRITE_BLOCK_SIZE 0x40 - -// Endianness -// https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html -// These functions encode and decode little endian uint16 and uint32 values. - -void write_uint32(unsigned char *buf, uint32_t ui) { - buf[0] = ui; - buf[1] = ui >> 8; - buf[2] = ui >> 16; - buf[3] = ui >> 24; -} +// Private structs and functions defines +struct stlink_fread_worker_arg { + int fd; +}; -void write_uint16(unsigned char *buf, uint16_t ui) { - buf[0] = (uint8_t)ui; - buf[1] = (uint8_t)(ui >> 8); -} +struct stlink_fread_ihex_worker_arg { + FILE *file; + uint32_t addr; + uint32_t lba; + uint8_t buf[16]; + uint8_t buf_pos; +}; -uint32_t read_uint32(const unsigned char *c, const int pt) { - return ((uint32_t)c[pt]) | ((uint32_t)c[pt + 1] << 8) | - ((uint32_t)c[pt + 2] << 16) | ((uint32_t)c[pt + 3] << 24); -} +typedef bool (*save_block_fn)(void *arg, uint8_t *block, ssize_t len); -uint16_t read_uint16(const unsigned char *c, const int pt) { - return ((uint16_t)c[pt]) | ((uint16_t)c[pt + 1] << 8); -} +static void stop_wdg_in_debug(stlink_t *); +int stlink_jtag_reset(stlink_t *, int); +int stlink_soft_reset(stlink_t *, int); +void _parse_version(stlink_t *, stlink_version_t *); +static uint8_t stlink_parse_hex(const char *); +static int stlink_read(stlink_t *, stm32_addr_t, size_t, save_block_fn, void *); +static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg *, int, stm32_addr_t); +static bool stlink_fread_ihex_worker(void *, uint8_t *, ssize_t); +static bool stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg *); +static bool stlink_fread_worker(void *, uint8_t *, ssize_t); +// End of private structs and functions defines + +// Functions below are defined in stlink.h (see line num before function) +// 252 +void stlink_close(stlink_t *sl) { + DLOG("*** stlink_close ***\n"); -static uint32_t get_stm32l0_flash_base(stlink_t *sl) { - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_L0: - case STLINK_CHIPID_STM32_L0_CAT5: - case STLINK_CHIPID_STM32_L0_CAT2: - case STLINK_CHIPID_STM32_L011: - return (STM32L0_FLASH_REGS_ADDR); + if (!sl) { + return; + } - case STLINK_CHIPID_STM32_L1_CAT2: - case STLINK_CHIPID_STM32_L1_MD: - case STLINK_CHIPID_STM32_L1_MD_PLUS: - case STLINK_CHIPID_STM32_L1_MD_PLUS_HD: - return (STM32L_FLASH_REGS_ADDR); + sl->backend->close(sl); + free(sl); +} +// 250 +int stlink_exit_debug_mode(stlink_t *sl) { + DLOG("*** stlink_exit_debug_mode ***\n"); - default: - WLOG("Flash base use default L0 address\n"); - return (STM32L0_FLASH_REGS_ADDR); + if (sl->flash_type != STLINK_FLASH_TYPE_UNKNOWN && + sl->core_stat != TARGET_RESET) { + // stop debugging if the target has been identified + stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); } -} -static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { - uint32_t rdp; - stlink_read_debug32(sl, FLASH_WRPR, &rdp); - return (rdp & 0xff); + return (sl->backend->exit_debug_mode(sl)); } - -static inline uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { - uint32_t reg, res; - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - reg = FLASH_F4_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - reg = FLASH_F7_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - reg = STM32L4_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - reg = STM32WB_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - } else { - reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; +//248 +int stlink_enter_swd_mode(stlink_t *sl) { + DLOG("*** stlink_enter_swd_mode ***\n"); + return (sl->backend->enter_swd_mode(sl)); +} +// 271 +// Force the core into the debug mode -> halted state. +int stlink_force_debug(stlink_t *sl) { + DLOG("*** stlink_force_debug_mode ***\n"); + int res = sl->backend->force_debug(sl); + if (res) { + return (res); } + // Stop the watchdogs in the halted state for suppress target reboot + stop_wdg_in_debug(sl); + return (0); +} +// 251 +int stlink_exit_dfu_mode(stlink_t *sl) { + DLOG("*** stlink_exit_dfu_mode ***\n"); + return (sl->backend->exit_dfu_mode(sl)); +} +// 253 +int stlink_core_id(stlink_t *sl) { + int ret; - stlink_read_debug32(sl, reg, &res); + DLOG("*** stlink_core_id ***\n"); + ret = sl->backend->core_id(sl); -#if DEBUG_FLASH - fprintf(stdout, "CR:0x%x\n", res); -#endif - return (res); -} + if (ret == -1) { + ELOG("Failed to read core_id\n"); + return (ret); + } -static inline unsigned int is_flash_locked(stlink_t *sl) { - /* return non zero for true */ - uint32_t cr_lock_shift; - uint32_t cr_reg; - uint32_t n; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - cr_reg = FLASH_CR; - cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - cr_lock_shift = FLASH_F4_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_lock_shift = FLASH_F7_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - cr_lock_shift = STM32L0_FLASH_PELOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_lock_shift = STM32Gx_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - cr_lock_shift = STM32WB_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; - cr_lock_shift = FLASH_H7_CR_LOCK; - } else { - ELOG("unsupported flash method, abort\n"); - return (-1); + if (sl->verbose > 2) { + stlink_print_data(sl); } - stlink_read_debug32(sl, cr_reg, &n); - return (n & (1u << cr_lock_shift)); + DLOG("core_id = 0x%08x\n", sl->core_id); + return (ret); } +// 287 +// stlink_chip_id() is called by stlink_load_device_params() +// do not call this procedure directly. +int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { + int ret; + cortex_m3_cpuid_t cpu_id; -static void unlock_flash(stlink_t *sl) { - uint32_t key_reg, key2_reg = 0; - uint32_t flash_key1 = FLASH_KEY1; - uint32_t flash_key2 = FLASH_KEY2; - /* The unlock sequence consists of 2 write cycles where 2 key values are - * written to the FLASH_KEYR register. An invalid sequence results in a - * definitive lock of the FPEC block until next reset. - */ - - if (sl->flash_type == STLINK_FLASH_TYPE_F0) { - key_reg = FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - key_reg = FLASH_KEYR; - key2_reg = FLASH_KEYR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - key_reg = FLASH_F4_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - key_reg = FLASH_F7_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; - flash_key1 = FLASH_L0_PEKEY1; - flash_key2 = FLASH_L0_PEKEY2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - key_reg = STM32L4_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - key_reg = STM32Gx_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - key_reg = STM32WB_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - key_reg = FLASH_H7_KEYR1; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - key2_reg = FLASH_H7_KEYR2; - } - } else { - ELOG("unsupported flash method, abort\n"); - return; + // Read the CPU ID to determine where to read the core id + if (stlink_cpu_id(sl, &cpu_id) || + cpu_id.implementer_id != STLINK_REG_CMx_CPUID_IMPL_ARM) { + ELOG("Can not connect to target. Please use \'connect under reset\' and " + "try again\n"); + return -1; } - stlink_write_debug32(sl, key_reg, flash_key1); - stlink_write_debug32(sl, key_reg, flash_key2); + /* + * the chip_id register in the reference manual have + * DBGMCU_IDCODE / DBG_IDCODE name + * + */ + + if ((sl->core_id == STM32H7_CORE_ID || sl->core_id == STM32H7_CORE_ID_JTAG) && + cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { + // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) + ret = stlink_read_debug32(sl, 0x5c001000, chip_id); + } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0 || + cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0P) { + // STM32F0 (RM0091, pg914; RM0360, pg713) + // STM32L0 (RM0377, pg813; RM0367, pg915; RM0376, pg917) + // STM32G0 (RM0444, pg1367) + ret = stlink_read_debug32(sl, 0x40015800, chip_id); + } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM33) { + // STM32L5 (RM0438, pg2157) + ret = stlink_read_debug32(sl, 0xE0044000, chip_id); + } else /* СM3, СM4, CM7 */ { + // default chipid address - if (key2_reg) { - stlink_write_debug32(sl, key2_reg, flash_key1); - stlink_write_debug32(sl, key2_reg, flash_key2); + // STM32F1 (RM0008, pg1087; RM0041, pg681) + // STM32F2 (RM0033, pg1326) + // STM32F3 (RM0316, pg1095; RM0313, pg874) + // STM32F7 (RM0385, pg1676; RM0410, pg1912) + // STM32L1 (RM0038, pg861) + // STM32L4 (RM0351, pg1840; RM0394, pg1560) + // STM32G4 (RM0440, pg2086) + // STM32WB (RM0434, pg1406) + ret = stlink_read_debug32(sl, 0xE0042000, chip_id); } -} -/* unlock flash if already locked */ -static int unlock_flash_if(stlink_t *sl) { - if (is_flash_locked(sl)) { - unlock_flash(sl); + if (ret || !(*chip_id)) { + *chip_id = 0; + ret = ret?ret:-1; + ELOG("Could not find chip id!\n"); + } else { + *chip_id = (*chip_id) & 0xfff; - if (is_flash_locked(sl)) { - WLOG("Failed to unlock flash!\n"); - return (-1); + // Fix chip_id for F4 rev A errata, read CPU ID, as CoreID is the same for + // F2/F4 + if (*chip_id == 0x411 && cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM4) { + *chip_id = 0x413; } } - DLOG("Successfully unlocked flash\n"); - return (0); + return (ret); } +// 288 +/** + * Cortex M tech ref manual, CPUID register description + * @param sl stlink context + * @param cpuid pointer to the result object + */ +int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { + uint32_t raw; -static void lock_flash(stlink_t *sl) { - uint32_t cr_lock_shift, cr_reg, n, cr2_reg = 0; - uint32_t cr_mask = 0xffffffffu; - - if (sl->flash_type == STLINK_FLASH_TYPE_F0) { - cr_reg = FLASH_CR; - cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - cr_reg = FLASH_CR; - cr2_reg = FLASH_CR2; - cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - cr_lock_shift = FLASH_F4_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_lock_shift = FLASH_F7_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - cr_lock_shift = STM32L0_FLASH_PELOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_lock_shift = STM32Gx_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - cr_lock_shift = STM32WB_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - cr2_reg = FLASH_H7_CR2; - } - cr_lock_shift = FLASH_H7_CR_LOCK; - cr_mask = ~(1u << FLASH_H7_CR_SER); - } else { - ELOG("unsupported flash method, abort\n"); - return; + if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &raw)) { + cpuid->implementer_id = 0; + cpuid->variant = 0; + cpuid->part = 0; + cpuid->revision = 0; + return (-1); } - stlink_read_debug32(sl, cr_reg, &n); - n &= cr_mask; - n |= (1u << cr_lock_shift); - stlink_write_debug32(sl, cr_reg, n); - - if (cr2_reg) { - n = read_flash_cr(sl, BANK_2) | (1u << cr_lock_shift); - stlink_write_debug32(sl, cr2_reg, n); - } + cpuid->implementer_id = (raw >> 24) & 0x7f; + cpuid->variant = (raw >> 20) & 0xf; + cpuid->part = (raw >> 4) & 0xfff; + cpuid->revision = raw & 0xf; + return (0); } +// 303 +/** + * Reads and decodes the flash parameters, as dynamically as possible + * @param sl + * @return 0 for success, or -1 for unsupported core type. + */ +int stlink_load_device_params(stlink_t *sl) { + // This seems to normally work so is unnecessary info for a normal user. + // Demoted to debug. -- REW + DLOG("Loading device parameters....\n"); + const struct stlink_chipid_params *params = NULL; + stlink_core_id(sl); + uint32_t flash_size; -static bool is_flash_option_locked(stlink_t *sl) { - uint32_t optlock_shift, optcr_reg; - int active_bit_level = 1; - uint32_t n; - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - optcr_reg = FLASH_CR; - optlock_shift = FLASH_CR_OPTWRE; - active_bit_level = 0; /* bit is "option write enable", not lock */ - break; - case STLINK_FLASH_TYPE_F4: - optcr_reg = FLASH_F4_OPTCR; - optlock_shift = FLASH_F4_OPTCR_LOCK; - break; - case STLINK_FLASH_TYPE_F7: - optcr_reg = FLASH_F7_OPTCR; - optlock_shift = FLASH_F7_OPTCR_LOCK; - break; - case STLINK_FLASH_TYPE_L0: - optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - optlock_shift = STM32L0_FLASH_OPTLOCK; - break; - case STLINK_FLASH_TYPE_L4: - optcr_reg = STM32L4_FLASH_CR; - optlock_shift = STM32L4_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_WB: - optcr_reg = STM32WB_FLASH_CR; - optlock_shift = STM32WB_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_H7: - optcr_reg = FLASH_H7_OPTCR; - optlock_shift = FLASH_H7_OPTCR_OPTLOCK; - break; - default: - ELOG("unsupported flash method, abort\n"); - return -1; + if (stlink_chip_id(sl, &sl->chip_id)) { + return (-1); } - stlink_read_debug32(sl, optcr_reg, &n); + params = stlink_chipid_get_params(sl->chip_id); - if (active_bit_level == 0) { - return (!(n & (1u << optlock_shift))); + if (params == NULL) { + WLOG("unknown chip id! %#x\n", sl->chip_id); + return (-1); } - return (n & (1u << optlock_shift)); -} - -static int lock_flash_option(stlink_t *sl) { - uint32_t optlock_shift, optcr_reg, n, optcr2_reg = 0; - int active_bit_level = 1; - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - optcr_reg = FLASH_CR; - optlock_shift = FLASH_CR_OPTWRE; - active_bit_level = 0; - break; - case STLINK_FLASH_TYPE_F4: - optcr_reg = FLASH_F4_OPTCR; - optlock_shift = FLASH_F4_OPTCR_LOCK; - break; - case STLINK_FLASH_TYPE_F7: - optcr_reg = FLASH_F7_OPTCR; - optlock_shift = FLASH_F7_OPTCR_LOCK; - break; - case STLINK_FLASH_TYPE_L0: - optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - optlock_shift = STM32L0_FLASH_OPTLOCK; - break; - case STLINK_FLASH_TYPE_L4: - optcr_reg = STM32L4_FLASH_CR; - optlock_shift = STM32L4_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_WB: - optcr_reg = STM32WB_FLASH_CR; - optlock_shift = STM32WB_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_H7: - optcr_reg = FLASH_H7_OPTCR; - optlock_shift = FLASH_H7_OPTCR_OPTLOCK; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) - optcr2_reg = FLASH_H7_OPTCR2; - break; - default: - ELOG("unsupported flash method, abort\n"); - return -1; + if (params->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { + WLOG("Invalid flash type, please check device declaration\n"); + sl->flash_size = 0; + return (0); } - stlink_read_debug32(sl, optcr_reg, &n); + // These are fixed... + sl->flash_base = STM32_FLASH_BASE; + sl->sram_base = STM32_SRAM_BASE; + stlink_read_debug32(sl, (params->flash_size_reg) & ~3, &flash_size); - if (active_bit_level == 0) { - n &= ~(1u << optlock_shift); - } else { - n |= (1u << optlock_shift); + if (params->flash_size_reg & 2) { + flash_size = flash_size >> 16; } - stlink_write_debug32(sl, optcr_reg, n); - - if (optcr2_reg) { - stlink_read_debug32(sl, optcr2_reg, &n); + flash_size = flash_size & 0xffff; - if (active_bit_level == 0) { - n &= ~(1u << optlock_shift); + if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MD || + sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MD_LD || + sl->chip_id == STLINK_CHIPID_STM32_L1_MD_PLUS) && + (flash_size == 0)) { + sl->flash_size = 128 * 1024; + } else if (sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2) { + sl->flash_size = (flash_size & 0xff) * 1024; + } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_MD_PLUS_HD) { + // 0 is 384k and 1 is 256k + if (flash_size == 0) { + sl->flash_size = 384 * 1024; } else { - n |= (1u << optlock_shift); + sl->flash_size = 256 * 1024; } - - stlink_write_debug32(sl, optcr2_reg, n); + } else { + sl->flash_size = flash_size * 1024; } - return (0); -} - -static int unlock_flash_option(stlink_t *sl) { - uint32_t optkey_reg, optkey2_reg = 0; - uint32_t optkey1 = FLASH_OPTKEY1; - uint32_t optkey2 = FLASH_OPTKEY2; - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - optkey_reg = FLASH_OPTKEYR; - optkey1 = FLASH_F0_OPTKEY1; - optkey2 = FLASH_F0_OPTKEY2; - break; - case STLINK_FLASH_TYPE_F4: - optkey_reg = FLASH_F4_OPT_KEYR; - break; - case STLINK_FLASH_TYPE_F7: - optkey_reg = FLASH_F7_OPT_KEYR; - break; - case STLINK_FLASH_TYPE_L0: - optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; - optkey1 = FLASH_L0_OPTKEY1; - optkey2 = FLASH_L0_OPTKEY2; - break; - case STLINK_FLASH_TYPE_L4: - optkey_reg = STM32L4_FLASH_OPTKEYR; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optkey_reg = STM32Gx_FLASH_OPTKEYR; - break; - case STLINK_FLASH_TYPE_WB: - optkey_reg = STM32WB_FLASH_OPT_KEYR; - break; - case STLINK_FLASH_TYPE_H7: - optkey_reg = FLASH_H7_OPT_KEYR; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) - optkey2_reg = FLASH_H7_OPT_KEYR2; - break; - default: - ELOG("unsupported flash method, abort\n"); - return (-1); - } - - stlink_write_debug32(sl, optkey_reg, optkey1); - stlink_write_debug32(sl, optkey_reg, optkey2); + sl->flash_type = params->flash_type; + sl->flash_pgsz = params->flash_pagesize; + sl->sram_size = params->sram_size; + sl->sys_base = params->bootrom_base; + sl->sys_size = params->bootrom_size; + sl->option_base = params->option_base; + sl->option_size = params->option_size; + sl->chip_flags = params->flags; - if (optkey2_reg) { - stlink_write_debug32(sl, optkey2_reg, optkey1); - stlink_write_debug32(sl, optkey2_reg, optkey2); + // medium and low devices have the same chipid. ram size depends on flash + // size. STM32F100xx datasheet Doc ID 16455 Table 2 + if (sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MD_LD && + sl->flash_size < 64 * 1024) { + sl->sram_size = 0x1000; } - return (0); -} + if (sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3) { + uint32_t flash_optr; + stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); -static int unlock_flash_option_if(stlink_t *sl) { - if (is_flash_option_locked(sl)) { - if (unlock_flash_option(sl)) { - ELOG("Could not unlock flash option!\n"); - return (-1); + if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { + sl->flash_pgsz <<= 1; } + } - if (is_flash_option_locked(sl)) { - ELOG("Failed to unlock flash option!\n"); - return (-1); - } + // H7 devices with small flash has one bank + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK && + sl->flash_type == STLINK_FLASH_TYPE_H7) { + if ((sl->flash_size / sl->flash_pgsz) <= 1) + sl->chip_flags &= ~CHIP_F_HAS_DUAL_BANK; } - DLOG("Successfully unlocked flash option\n"); + ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", + params->description, (unsigned)(sl->sram_size / 1024), + (unsigned)(sl->flash_size / 1024), + (sl->flash_pgsz < 1024) ? (unsigned)(sl->flash_pgsz) + : (unsigned)(sl->flash_pgsz / 1024), + (sl->flash_pgsz < 1024) ? "byte" : "KiB"); + return (0); } +// 254 +int stlink_reset(stlink_t *sl, enum reset_type type) { + uint32_t dhcsr; + unsigned timeout; -static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { - uint32_t cr_reg, x; - - x = read_flash_cr(sl, bank); - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - x &= ~STM32L4_FLASH_CR_OPBITS; - x |= (1 << STM32L4_FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - x |= (1 << FLASH_H7_CR_PG); - } else { - cr_reg = FLASH_CR; - x = (1 << FLASH_CR_PG); - } + DLOG("*** stlink_reset ***\n"); - stlink_write_debug32(sl, cr_reg, x); -} + sl->core_stat = TARGET_RESET; -static void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { - uint32_t cr_reg, n; - uint32_t bit = FLASH_CR_PG; - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - bit = FLASH_H7_CR_PG; - } else { - cr_reg = FLASH_CR; + if (type == RESET_AUTO) { + // clear S_RESET_ST in DHCSR register for reset state detection + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); } - n = read_flash_cr(sl, bank) & ~(1 << bit); - stlink_write_debug32(sl, cr_reg, n); -} - -static void set_flash_cr_per(stlink_t *sl, unsigned bank) { - uint32_t cr_reg, val; - - if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - } else { - cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + if (type == RESET_HARD || type == RESET_AUTO) { + // hardware target reset + if (sl->version.stlink_v > 1) { + stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); + // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) + usleep(100); + stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH); + } + sl->backend->reset(sl); + usleep(10000); } - stlink_read_debug32(sl, cr_reg, &val); - val |= (1 << FLASH_CR_PER); - stlink_write_debug32(sl, cr_reg, val); -} - -static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { - uint32_t cr_reg; + if (type == RESET_AUTO) { + /* Check if the S_RESET_ST bit is set in DHCSR + * This means that a reset has occurred + * DDI0337E, p. 10-4, Debug Halting Control and Status Register */ - if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - } else { - cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; - } + dhcsr = 0; + int res = stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0 && !res) { + // reset not done yet + // try reset through AIRCR so that NRST does not need to be connected - const uint32_t n = read_flash_cr(sl, bank) & ~(1 << FLASH_CR_PER); - stlink_write_debug32(sl, cr_reg, n); -} + WLOG("NRST is not connected\n"); + DLOG("Using reset through SYSRESETREQ\n"); + return stlink_soft_reset(sl, 0); + } -static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { - uint32_t val, cr_reg, cr_mer, cr_pg; - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - cr_mer = 1 << FLASH_CR_MER; - cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_mer = 1 << FLASH_CR_MER; - cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); - cr_pg = (1 << STM32L4_FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_mer = (1 << STM32Gx_FLASH_CR_MER1); - - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); + // waiting for reset the S_RESET_ST bit within 500ms + timeout = time_ms() + 500; + while (time_ms() < timeout) { + dhcsr = STLINK_REG_DHCSR_S_RESET_ST; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + return (0); + } } - cr_pg = (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - cr_mer = (1 << FLASH_CR_MER); - cr_pg = (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - cr_mer = (1 << FLASH_H7_CR_BER); - cr_pg = (1 << FLASH_H7_CR_PG); - } else { - cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; - cr_mer = (1 << FLASH_CR_MER); - cr_pg = (1 << FLASH_CR_PG); + return (-1); } - stlink_read_debug32(sl, cr_reg, &val); - - if (val & cr_pg) { - // STM32F030 will drop MER bit if PG was set - val &= ~cr_pg; - stlink_write_debug32(sl, cr_reg, val); + if (type == RESET_SOFT || type == RESET_SOFT_AND_HALT) { + return stlink_soft_reset(sl, (type == RESET_SOFT_AND_HALT)); } - if (v) { - val |= cr_mer; - } else { - val &= ~cr_mer; + return (0); +} +// 255 +int stlink_run(stlink_t *sl, enum run_type type) { + struct stlink_reg rr; + DLOG("*** stlink_run ***\n"); + + /* Make sure we are in Thumb mode + * Cortex-M chips don't support ARM mode instructions + * xPSR may be incorrect if the vector table has invalid data */ + stlink_read_reg(sl, 16, &rr); + if ((rr.xpsr & (1 << 24)) == 0) { + ILOG("Go to Thumb mode\n"); + stlink_write_reg(sl, rr.xpsr | (1 << 24), 16); } - stlink_write_debug32(sl, cr_reg, val); + return (sl->backend->run(sl, type)); } - -static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { - uint32_t val, cr_reg, cr_strt; - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - cr_strt = 1 << FLASH_F4_CR_STRT; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_strt = 1 << FLASH_F7_CR_STRT; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_strt = (1 << STM32L4_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_strt = (1 << STM32Gx_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - cr_strt = (1 << STM32WB_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - cr_strt = 1 << FLASH_H7_CR_START(sl->chip_id); - } else { - cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; - cr_strt = (1 << FLASH_CR_STRT); +// 273 +int stlink_set_swdclk(stlink_t *sl, int freq_khz) { + DLOG("*** set_swdclk ***\n"); + return (sl->backend->set_swdclk(sl, freq_khz)); +} +// 293 +// this function is called by stlink_status() +// do not call stlink_core_stat() directly, always use stlink_status() +void stlink_core_stat(stlink_t *sl) { + switch (sl->core_stat) { + case TARGET_RUNNING: + DLOG(" core status: running\n"); + return; + case TARGET_HALTED: + DLOG(" core status: halted\n"); + return; + case TARGET_RESET: + DLOG(" core status: reset\n"); + return; + case TARGET_DEBUG_RUNNING: + DLOG(" core status: debug running\n"); + return; + default: + DLOG(" core status: unknown\n"); } +} +// 256 +int stlink_status(stlink_t *sl) { + int ret; - stlink_read_debug32(sl, cr_reg, &val); - val |= cr_strt; - stlink_write_debug32(sl, cr_reg, val); + DLOG("*** stlink_status ***\n"); + ret = sl->backend->status(sl); + stlink_core_stat(sl); + return (ret); } +// 257 +int stlink_version(stlink_t *sl) { + DLOG("*** looking up stlink version\n"); -static inline uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { - uint32_t res, sr_reg; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - sr_reg = FLASH_F4_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - sr_reg = STM32L4_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - sr_reg = STM32Gx_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - sr_reg = STM32WB_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; - } else { - ELOG("method 'read_flash_sr' is unsupported\n"); + if (sl->backend->version(sl)) { return (-1); } - stlink_read_debug32(sl, sr_reg, &res); - return (res); -} + _parse_version(sl, &sl->version); -static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { - uint32_t sr_reg; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - sr_reg = FLASH_F4_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - sr_reg = STM32L4_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - sr_reg = STM32Gx_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - sr_reg = STM32WB_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; - } else { - ELOG("method 'write_flash_sr' is unsupported\n"); - return (-1); + DLOG("st vid = 0x%04x (expect 0x%04x)\n", sl->version.st_vid, + STLINK_USB_VID_ST); + DLOG("stlink pid = 0x%04x\n", sl->version.stlink_pid); + DLOG("stlink version = 0x%x\n", sl->version.stlink_v); + DLOG("jtag version = 0x%x\n", sl->version.jtag_v); + DLOG("swim version = 0x%x\n", sl->version.swim_v); + + if (sl->version.jtag_v == 0) { + WLOG(" warning: stlink doesn't support JTAG/SWD interface\n"); } - return stlink_write_debug32(sl, sr_reg, val); + return (0); } +// 272 +int stlink_target_voltage(stlink_t *sl) { + int voltage = -1; + DLOG("*** reading target voltage\n"); -static inline unsigned int is_flash_busy(stlink_t *sl) { - uint32_t sr_busy_shift; - unsigned int res; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || - (sl->flash_type == STLINK_FLASH_TYPE_L0)) { - sr_busy_shift = FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - sr_busy_shift = FLASH_F4_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - sr_busy_shift = FLASH_F7_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - sr_busy_shift = STM32L4_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - sr_busy_shift = STM32Gx_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - sr_busy_shift = STM32WB_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - sr_busy_shift = FLASH_H7_SR_QW; + if (sl->backend->target_voltage != NULL) { + voltage = sl->backend->target_voltage(sl); + + if (voltage != -1) { + DLOG("target voltage = %imV\n", voltage); + } else { + DLOG("error reading target voltage\n"); + } } else { - ELOG("method 'is_flash_busy' is unsupported\n"); - return (-1); + DLOG("reading voltage not supported by backend\n"); } - res = read_flash_sr(sl, BANK_1) & (1 << sr_busy_shift); + return (voltage); +} +// 299 +bool stlink_is_core_halted(stlink_t *sl) { + stlink_status(sl); + return (sl->core_stat == TARGET_HALTED); +} +// 269 +int stlink_step(stlink_t *sl) { + DLOG("*** stlink_step ***\n"); + return (sl->backend->step(sl)); +} +// 270 +int stlink_current_mode(stlink_t *sl) { + int mode = sl->backend->current_mode(sl); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && - sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { - res |= read_flash_sr(sl, BANK_2) & (1 << sr_busy_shift); + switch (mode) { + case STLINK_DEV_DFU_MODE: + DLOG("stlink current mode: dfu\n"); + return (mode); + case STLINK_DEV_DEBUG_MODE: + DLOG("stlink current mode: debug (jtag or swd)\n"); + return (mode); + case STLINK_DEV_MASS_MODE: + DLOG("stlink current mode: mass\n"); + return (mode); } - return (res); + DLOG("stlink mode: unknown!\n"); + return (STLINK_DEV_UNKNOWN_MODE); } - -static void wait_flash_busy(stlink_t *sl) { - // TODO: add some delays here - while (is_flash_busy(sl)) - ; +// 274 +int stlink_trace_enable(stlink_t *sl, uint32_t frequency) { + DLOG("*** stlink_trace_enable ***\n"); + return (sl->backend->trace_enable(sl, frequency)); } +// 275 +int stlink_trace_disable(stlink_t *sl) { + DLOG("*** stlink_trace_disable ***\n"); + return (sl->backend->trace_disable(sl)); +} +// 276 +int stlink_trace_read(stlink_t *sl, uint8_t *buf, size_t size) { + return (sl->backend->trace_read(sl, buf, size)); +} +// 294 +void stlink_print_data(stlink_t *sl) { + if (sl->q_len <= 0 || sl->verbose < UDEBUG) { + return; + } -static void wait_flash_busy_progress(stlink_t *sl) { - int i = 0; - fprintf(stdout, "Mass erasing"); - fflush(stdout); - - while (is_flash_busy(sl)) { - usleep(10000); - i++; + if (sl->verbose > 2) { + DLOG("data_len = %d 0x%x\n", sl->q_len, sl->q_len); + } - if (i % 100 == 0) { - fprintf(stdout, "."); - fflush(stdout); + for (int i = 0; i < sl->q_len; i++) { + if (i % 16 == 0) { + /* + if (sl->q_data_dir == Q_DATA_OUT) { + fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i); + } else { + fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); + } + */ } + // DLOG(" %02x", (unsigned int) sl->q_buf[i]); + fprintf(stderr, " %02x", (unsigned int)sl->q_buf[i]); } - - fprintf(stdout, "\n"); -} - -static void clear_flash_error(stlink_t *sl) { - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_F4: - write_flash_sr(sl, BANK_1, FLASH_F4_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_F7: - write_flash_sr(sl, BANK_1, FLASH_F7_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_L0: - write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_L4: - write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_H7: - write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_sr(sl, BANK_2, FLASH_H7_SR_ERROR_MASK); - } - break; - case STLINK_FLASH_TYPE_WB: - write_flash_sr(sl, BANK_1, STM32WB_FLASH_SR_ERROR_MASK); - break; - default: - break; - } + // DLOG("\n\n"); + fprintf(stderr, "\n"); } +// 283 +int stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, + stm32_addr_t addr) { + // write the file in sram at addr -static int check_flash_error(stlink_t *sl) { - uint32_t res = 0; - uint32_t WRPERR, PROGERR, PGAERR; + int error = -1; + size_t off; + size_t len; - WRPERR = PROGERR = PGAERR = 0; + // check addr range is inside the sram + if (addr < sl->sram_base) { + fprintf(stderr, "addr too low\n"); + goto on_error; + } else if ((addr + length) < addr) { + fprintf(stderr, "addr overruns\n"); + goto on_error; + } else if ((addr + length) > (sl->sram_base + sl->sram_size)) { + fprintf(stderr, "addr too high\n"); + goto on_error; + } else if (addr & 3) { + fprintf(stderr, "unaligned addr\n"); + goto on_error; + } - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - res |= read_flash_sr(sl, BANK_2) & FLASH_SR_ERROR_MASK; - } - WRPERR = (1 << FLASH_SR_WRPRT_ERR); - PROGERR = (1 << FLASH_SR_PG_ERR); - break; - case STLINK_FLASH_TYPE_F4: - res = read_flash_sr(sl, BANK_1) & FLASH_F4_SR_ERROR_MASK; - WRPERR = (1 << FLASH_F4_SR_WRPERR); - PGAERR = (1 << FLASH_F4_SR_PGAERR); - break; - case STLINK_FLASH_TYPE_F7: - res = read_flash_sr(sl, BANK_1) & FLASH_F7_SR_ERROR_MASK; - WRPERR = (1 << FLASH_F7_SR_WRP_ERR); - PROGERR = (1 << FLASH_F7_SR_PGP_ERR); - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32Gx_FLASH_SR_WRPERR); - PROGERR = (1 << STM32Gx_FLASH_SR_PROGERR); - PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); - break; - case STLINK_FLASH_TYPE_L0: - res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); - PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); - PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); - break; - case STLINK_FLASH_TYPE_L4: - res = read_flash_sr(sl, BANK_1) & STM32L4_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32L4_FLASH_SR_WRPERR); - PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); - PGAERR = (1 << STM32L4_FLASH_SR_PGAERR); - break; - case STLINK_FLASH_TYPE_H7: - res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; - } - WRPERR = (1 << FLASH_H7_SR_WRPERR); - break; - case STLINK_FLASH_TYPE_WB: - res = read_flash_sr(sl, BANK_1) & STM32WB_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32WB_FLASH_SR_WRPERR); - PROGERR = (1 << STM32WB_FLASH_SR_PROGERR); - PGAERR = (1 << STM32WB_FLASH_SR_PGAERR); - break; - default: - break; + len = length; + + if (len & 3) { + len -= len & 3; } - if (res) { - if (WRPERR && (WRPERR & res) == WRPERR) { - ELOG("Flash memory is write protected\n"); - res &= ~WRPERR; - } else if (PROGERR && (PROGERR & res) == PROGERR) { - ELOG("Flash memory contains a non-erased value\n"); - res &= ~PROGERR; - } else if (PGAERR && (PGAERR & res) == PGAERR) { - ELOG("Invalid flash address\n"); - res &= ~PGAERR; - } + // do the copy by 1kB blocks + for (off = 0; off < len; off += 1024) { + size_t size = 1024; - if (res) { - ELOG("Flash programming error: %#010x\n", res); + if ((off + size) > len) { + size = len - off; } - return (-1); - } - return (0); -} + memcpy(sl->q_buf, data + off, size); -static void stop_wdg_in_debug(stlink_t *sl) { - uint32_t dbgmcu_cr; - uint32_t set; - uint32_t value; + if (size & 3) { + size += 2; + } // round size if needed - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - case STLINK_FLASH_TYPE_G4: - dbgmcu_cr = STM32F0_DBGMCU_CR; - set = (1 << STM32F0_DBGMCU_CR_IWDG_STOP) | - (1 << STM32F0_DBGMCU_CR_WWDG_STOP); - break; - case STLINK_FLASH_TYPE_F4: - case STLINK_FLASH_TYPE_F7: - case STLINK_FLASH_TYPE_L4: - dbgmcu_cr = STM32F4_DBGMCU_APB1FZR1; - set = (1 << STM32F4_DBGMCU_APB1FZR1_IWDG_STOP) | - (1 << STM32F4_DBGMCU_APB1FZR1_WWDG_STOP); - break; - case STLINK_FLASH_TYPE_L0: - case STLINK_FLASH_TYPE_G0: - dbgmcu_cr = STM32L0_DBGMCU_APB1_FZ; - set = (1 << STM32L0_DBGMCU_APB1_FZ_IWDG_STOP) | - (1 << STM32L0_DBGMCU_APB1_FZ_WWDG_STOP); - break; - case STLINK_FLASH_TYPE_H7: - dbgmcu_cr = STM32H7_DBGMCU_APB1HFZ; - set = (1 << STM32H7_DBGMCU_APB1HFZ_IWDG_STOP); - break; - case STLINK_FLASH_TYPE_WB: - dbgmcu_cr = STM32WB_DBGMCU_APB1FZR1; - set = (1 << STM32WB_DBGMCU_APB1FZR1_IWDG_STOP) | - (1 << STM32WB_DBGMCU_APB1FZR1_WWDG_STOP); - break; - default: - return; + stlink_write_mem32(sl, addr + (uint32_t)off, (uint16_t)size); } - if (!stlink_read_debug32(sl, dbgmcu_cr, &value)) { - stlink_write_debug32(sl, dbgmcu_cr, value | set); + if (length > len) { + memcpy(sl->q_buf, data + len, length - len); + stlink_write_mem8(sl, addr + (uint32_t)len, (uint16_t)(length - len)); } -} -static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { - uint32_t rcc, rcc_dma_mask, value; + error = 0; // success + stlink_fwrite_finalize(sl, addr); - rcc = rcc_dma_mask = value = 0; +on_error: + return (error); +} +//284 +int stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { + // write the file in sram at addr - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - rcc = STM32F1_RCC_AHBENR; - rcc_dma_mask = STM32F1_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_F4: - case STLINK_FLASH_TYPE_F7: - rcc = STM32F4_RCC_AHB1ENR; - rcc_dma_mask = STM32F4_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_G0: - rcc = STM32G0_RCC_AHBENR; - rcc_dma_mask = STM32G0_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_G4: - case STLINK_FLASH_TYPE_L4: - rcc = STM32G4_RCC_AHB1ENR; - rcc_dma_mask = STM32G4_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_L0: - rcc = STM32L0_RCC_AHBENR; - rcc_dma_mask = STM32L0_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_H7: - rcc = STM32H7_RCC_AHB1ENR; - rcc_dma_mask = STM32H7_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_WB: - rcc = STM32WB_RCC_AHB1ENR; - rcc_dma_mask = STM32WB_RCC_DMAEN; - break; - default: - return; - } + int error = -1; + size_t off; + size_t len; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; - if (!stlink_read_debug32(sl, rcc, &value)) { - if (bckpRstr) { - value = (value & (~rcc_dma_mask)) | fl->rcc_dma_bkp; - } else { - fl->rcc_dma_bkp = value & rcc_dma_mask; - value &= ~rcc_dma_mask; - } - stlink_write_debug32(sl, rcc, value); + if (map_file(&mf, path) == -1) { + fprintf(stderr, "map_file() == -1\n"); + return (-1); } -} -static inline void write_flash_ar(stlink_t *sl, uint32_t n, unsigned bank) { - stlink_write_debug32(sl, (bank == BANK_1) ? FLASH_AR : FLASH_AR2, n); -} - -static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n, - unsigned bank) { - uint32_t cr_reg, psize_shift; - uint32_t x = read_flash_cr(sl, bank); + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); - if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - psize_shift = FLASH_H7_CR_PSIZE; - } else { - cr_reg = FLASH_F4_CR; - psize_shift = 8; + // check if addr range is inside the SRAM + if (addr < sl->sram_base) { + fprintf(stderr, "addr too low\n"); + goto on_error; + } else if ((addr + mf.len) < addr) { + fprintf(stderr, "addr overruns\n"); + goto on_error; + } else if ((addr + mf.len) > (sl->sram_base + sl->sram_size)) { + fprintf(stderr, "addr too high\n"); + goto on_error; + } else if (addr & 3) { + fprintf(stderr, "unaligned addr\n"); + goto on_error; } - x &= ~(0x03 << psize_shift); - x |= (n << psize_shift); -#if DEBUG_FLASH - fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n); -#endif - stlink_write_debug32(sl, cr_reg, x); -} - -static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, unsigned bank) { - uint32_t cr_reg, snb_mask, snb_shift, ser_shift; - uint32_t x = read_flash_cr(sl, bank); + len = mf.len; - if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - snb_mask = FLASH_H7_CR_SNB_MASK; - snb_shift = FLASH_H7_CR_SNB; - ser_shift = FLASH_H7_CR_SER; - } else { - cr_reg = FLASH_F4_CR; - snb_mask = FLASH_F4_CR_SNB_MASK; - snb_shift = FLASH_F4_CR_SNB; - ser_shift = FLASH_F4_CR_SER; + if (len & 3) { + len -= len & 3; } - x &= ~snb_mask; - x |= (n << snb_shift); - x |= (1 << ser_shift); -#if DEBUG_FLASH - fprintf(stdout, "SNB:0x%x 0x%x\n", x, n); -#endif - stlink_write_debug32(sl, cr_reg, x); -} + // do the copy by 1kB blocks + for (off = 0; off < len; off += 1024) { + size_t size = 1024; -static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { - stlink_write_debug32(sl, STM32L4_FLASH_SR, - 0xFFFFFFFF & ~(1 << STM32L4_FLASH_SR_BSY)); - uint32_t x = read_flash_cr(sl, BANK_1); - x &= ~STM32L4_FLASH_CR_OPBITS; - x &= ~STM32L4_FLASH_CR_PAGEMASK; - x &= ~(1 << STM32L4_FLASH_CR_MER1); - x &= ~(1 << STM32L4_FLASH_CR_MER2); - x |= (n << STM32L4_FLASH_CR_PNB); - x |= (uint32_t)(1lu << STM32L4_FLASH_CR_PER); -#if DEBUG_FLASH - fprintf(stdout, "BKER:PNB:0x%x 0x%x\n", x, n); -#endif - stlink_write_debug32(sl, STM32L4_FLASH_CR, x); -} + if ((off + size) > len) { + size = len - off; + } -// Delegates to the backends... + memcpy(sl->q_buf, mf.base + off, size); -void stlink_close(stlink_t *sl) { - DLOG("*** stlink_close ***\n"); + if (size & 3) { + size += 2; + } // round size if needed - if (!sl) { - return; + stlink_write_mem32(sl, addr + (uint32_t)off, (uint16_t)size); } - sl->backend->close(sl); - free(sl); -} - -int stlink_exit_debug_mode(stlink_t *sl) { - DLOG("*** stlink_exit_debug_mode ***\n"); + if (mf.len > len) { + memcpy(sl->q_buf, mf.base + len, mf.len - len); + stlink_write_mem8(sl, addr + (uint32_t)len, (uint16_t)(mf.len - len)); + } - if (sl->flash_type != STLINK_FLASH_TYPE_UNKNOWN && - sl->core_stat != TARGET_RESET) { - // stop debugging if the target has been identified - stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); + // check the file has been written + if (check_file(sl, &mf, addr) == -1) { + fprintf(stderr, "check_file() == -1\n"); + goto on_error; } - return (sl->backend->exit_debug_mode(sl)); -} + error = 0; // success + stlink_fwrite_finalize(sl, addr); -int stlink_enter_swd_mode(stlink_t *sl) { - DLOG("*** stlink_enter_swd_mode ***\n"); - return (sl->backend->enter_swd_mode(sl)); +on_error: + unmap_file(&mf); + return (error); } +// 302 +int stlink_fread(stlink_t *sl, const char *path, bool is_ihex, + stm32_addr_t addr, size_t size) { + // read size bytes from addr to file + ILOG("read from address %#010x size %u\n", addr, (unsigned)size); -// Force the core into the debug mode -> halted state. -int stlink_force_debug(stlink_t *sl) { - DLOG("*** stlink_force_debug_mode ***\n"); - int res = sl->backend->force_debug(sl); - if (res) { - return (res); - } - // Stop the watchdogs in the halted state for suppress target reboot - stop_wdg_in_debug(sl); - return (0); -} - -int stlink_exit_dfu_mode(stlink_t *sl) { - DLOG("*** stlink_exit_dfu_mode ***\n"); - return (sl->backend->exit_dfu_mode(sl)); -} - -int stlink_core_id(stlink_t *sl) { - int ret; - - DLOG("*** stlink_core_id ***\n"); - ret = sl->backend->core_id(sl); - - if (ret == -1) { - ELOG("Failed to read core_id\n"); - return (ret); - } - - if (sl->verbose > 2) { - stlink_print_data(sl); - } - - DLOG("core_id = 0x%08x\n", sl->core_id); - return (ret); -} - -// stlink_chip_id() is called by stlink_load_device_params() -// do not call this procedure directly. -int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { - int ret; - cortex_m3_cpuid_t cpu_id; - - // Read the CPU ID to determine where to read the core id - if (stlink_cpu_id(sl, &cpu_id) || - cpu_id.implementer_id != STLINK_REG_CMx_CPUID_IMPL_ARM) { - ELOG("Can not connect to target. Please use \'connect under reset\' and " - "try again\n"); - return -1; - } - - /* - * the chip_id register in the reference manual have - * DBGMCU_IDCODE / DBG_IDCODE name - * - */ - - if ((sl->core_id == STM32H7_CORE_ID || sl->core_id == STM32H7_CORE_ID_JTAG) && - cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { - // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) - ret = stlink_read_debug32(sl, 0x5c001000, chip_id); - } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0 || - cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0P) { - // STM32F0 (RM0091, pg914; RM0360, pg713) - // STM32L0 (RM0377, pg813; RM0367, pg915; RM0376, pg917) - // STM32G0 (RM0444, pg1367) - ret = stlink_read_debug32(sl, 0x40015800, chip_id); - } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM33) { - // STM32L5 (RM0438, pg2157) - ret = stlink_read_debug32(sl, 0xE0044000, chip_id); - } else /* СM3, СM4, CM7 */ { - // default chipid address - - // STM32F1 (RM0008, pg1087; RM0041, pg681) - // STM32F2 (RM0033, pg1326) - // STM32F3 (RM0316, pg1095; RM0313, pg874) - // STM32F7 (RM0385, pg1676; RM0410, pg1912) - // STM32L1 (RM0038, pg861) - // STM32L4 (RM0351, pg1840; RM0394, pg1560) - // STM32G4 (RM0440, pg2086) - // STM32WB (RM0434, pg1406) - ret = stlink_read_debug32(sl, 0xE0042000, chip_id); - } - - if (ret || !(*chip_id)) { - *chip_id = 0; - ret = ret?ret:-1; - ELOG("Could not find chip id!\n"); - } else { - *chip_id = (*chip_id) & 0xfff; - - // Fix chip_id for F4 rev A errata, read CPU ID, as CoreID is the same for - // F2/F4 - if (*chip_id == 0x411 && cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM4) { - *chip_id = 0x413; - } - } - - return (ret); -} - -/** - * Cortex M tech ref manual, CPUID register description - * @param sl stlink context - * @param cpuid pointer to the result object - */ -int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { - uint32_t raw; - - if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &raw)) { - cpuid->implementer_id = 0; - cpuid->variant = 0; - cpuid->part = 0; - cpuid->revision = 0; - return (-1); - } - - cpuid->implementer_id = (raw >> 24) & 0x7f; - cpuid->variant = (raw >> 20) & 0xf; - cpuid->part = (raw >> 4) & 0xfff; - cpuid->revision = raw & 0xf; - return (0); -} - -/** - * Reads and decodes the flash parameters, as dynamically as possible - * @param sl - * @return 0 for success, or -1 for unsupported core type. - */ -int stlink_load_device_params(stlink_t *sl) { - // This seems to normally work so is unnecessary info for a normal user. - // Demoted to debug. -- REW - DLOG("Loading device parameters....\n"); - const struct stlink_chipid_params *params = NULL; - stlink_core_id(sl); - uint32_t flash_size; - - if (stlink_chip_id(sl, &sl->chip_id)) { - return (-1); - } - - params = stlink_chipid_get_params(sl->chip_id); - - if (params == NULL) { - WLOG("unknown chip id! %#x\n", sl->chip_id); - return (-1); - } - - if (params->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { - WLOG("Invalid flash type, please check device declaration\n"); - sl->flash_size = 0; - return (0); - } - - // These are fixed... - sl->flash_base = STM32_FLASH_BASE; - sl->sram_base = STM32_SRAM_BASE; - stlink_read_debug32(sl, (params->flash_size_reg) & ~3, &flash_size); - - if (params->flash_size_reg & 2) { - flash_size = flash_size >> 16; - } - - flash_size = flash_size & 0xffff; - - if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MD || - sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MD_LD || - sl->chip_id == STLINK_CHIPID_STM32_L1_MD_PLUS) && - (flash_size == 0)) { - sl->flash_size = 128 * 1024; - } else if (sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2) { - sl->flash_size = (flash_size & 0xff) * 1024; - } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_MD_PLUS_HD) { - // 0 is 384k and 1 is 256k - if (flash_size == 0) { - sl->flash_size = 384 * 1024; - } else { - sl->flash_size = 256 * 1024; - } - } else { - sl->flash_size = flash_size * 1024; - } - - sl->flash_type = params->flash_type; - sl->flash_pgsz = params->flash_pagesize; - sl->sram_size = params->sram_size; - sl->sys_base = params->bootrom_base; - sl->sys_size = params->bootrom_size; - sl->option_base = params->option_base; - sl->option_size = params->option_size; - sl->chip_flags = params->flags; - - // medium and low devices have the same chipid. ram size depends on flash - // size. STM32F100xx datasheet Doc ID 16455 Table 2 - if (sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MD_LD && - sl->flash_size < 64 * 1024) { - sl->sram_size = 0x1000; - } - - if (sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3) { - uint32_t flash_optr; - stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); - - if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { - sl->flash_pgsz <<= 1; - } - } - - // H7 devices with small flash has one bank - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK && - sl->flash_type == STLINK_FLASH_TYPE_H7) { - if ((sl->flash_size / sl->flash_pgsz) <= 1) - sl->chip_flags &= ~CHIP_F_HAS_DUAL_BANK; - } - - ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", - params->description, (unsigned)(sl->sram_size / 1024), - (unsigned)(sl->flash_size / 1024), - (sl->flash_pgsz < 1024) ? (unsigned)(sl->flash_pgsz) - : (unsigned)(sl->flash_pgsz / 1024), - (sl->flash_pgsz < 1024) ? "byte" : "KiB"); - - return (0); -} - -int stlink_jtag_reset(stlink_t *sl, int value) { - DLOG("*** stlink_jtag_reset %d ***\n", value); - return (sl->backend->jtag_reset(sl, value)); -} - -int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { - int ret; - unsigned timeout; - uint32_t dhcsr, dfsr; - - DLOG("*** stlink_soft_reset %s***\n", halt_on_reset ? "(halt) " : ""); - - // halt core and enable debugging (if not already done) - // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) - stlink_write_debug32(sl, STLINK_REG_DHCSR, - STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | - STLINK_REG_DHCSR_C_DEBUGEN); - - // enable Halt on reset by set VC_CORERESET and TRCENA (DDI0337E, p. 10-10) - if (halt_on_reset) { - stlink_write_debug32( - sl, STLINK_REG_CM3_DEMCR, - STLINK_REG_CM3_DEMCR_TRCENA | STLINK_REG_CM3_DEMCR_VC_HARDERR | - STLINK_REG_CM3_DEMCR_VC_BUSERR | STLINK_REG_CM3_DEMCR_VC_CORERESET); - - // clear VCATCH in the DFSR register - stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_VCATCH); - } else { - stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, - STLINK_REG_CM3_DEMCR_TRCENA | - STLINK_REG_CM3_DEMCR_VC_HARDERR | - STLINK_REG_CM3_DEMCR_VC_BUSERR); - } - - // clear S_RESET_ST in the DHCSR register - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - - // soft reset (core reset) by SYSRESETREQ (DDI0337E, p. 8-23) - ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, - STLINK_REG_AIRCR_VECTKEY | - STLINK_REG_AIRCR_SYSRESETREQ); - if (ret) { - ELOG("Soft reset failed: error write to AIRCR\n"); - return (ret); - } - - // waiting for a reset within 500ms - // DDI0337E, p. 10-4, Debug Halting Control and Status Register - timeout = time_ms() + 500; - while (time_ms() < timeout) { - // DDI0337E, p. 10-4, Debug Halting Control and Status Register - dhcsr = STLINK_REG_DHCSR_S_RESET_ST; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { - if (halt_on_reset) { - // waiting halt by the SYSRESETREQ exception - // DDI0403E, p. C1-699, Debug Fault Status Register - dfsr = 0; - stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); - if ((dfsr & STLINK_REG_DFSR_VCATCH) == 0) { - continue; - } - } - timeout = 0; - break; - } - } - - // reset DFSR register. DFSR is power-on reset only (DDI0337H, p. 7-5) - stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_CLEAR); - - if (timeout) { - ELOG("Soft reset failed: timeout\n"); - return (-1); - } - - return (0); -} - -int stlink_reset(stlink_t *sl, enum reset_type type) { - uint32_t dhcsr; - unsigned timeout; - - DLOG("*** stlink_reset ***\n"); - - sl->core_stat = TARGET_RESET; - - if (type == RESET_AUTO) { - // clear S_RESET_ST in DHCSR register for reset state detection - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - } - - if (type == RESET_HARD || type == RESET_AUTO) { - // hardware target reset - if (sl->version.stlink_v > 1) { - stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); - // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) - usleep(100); - stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH); - } - sl->backend->reset(sl); - usleep(10000); - } - - if (type == RESET_AUTO) { - /* Check if the S_RESET_ST bit is set in DHCSR - * This means that a reset has occurred - * DDI0337E, p. 10-4, Debug Halting Control and Status Register */ - - dhcsr = 0; - int res = stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0 && !res) { - // reset not done yet - // try reset through AIRCR so that NRST does not need to be connected - - WLOG("NRST is not connected\n"); - DLOG("Using reset through SYSRESETREQ\n"); - return stlink_soft_reset(sl, 0); - } - - // waiting for reset the S_RESET_ST bit within 500ms - timeout = time_ms() + 500; - while (time_ms() < timeout) { - dhcsr = STLINK_REG_DHCSR_S_RESET_ST; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { - return (0); - } - } - - return (-1); - } - - if (type == RESET_SOFT || type == RESET_SOFT_AND_HALT) { - return stlink_soft_reset(sl, (type == RESET_SOFT_AND_HALT)); - } - - return (0); -} - -int stlink_run(stlink_t *sl, enum run_type type) { - struct stlink_reg rr; - DLOG("*** stlink_run ***\n"); - - /* Make sure we are in Thumb mode - * Cortex-M chips don't support ARM mode instructions - * xPSR may be incorrect if the vector table has invalid data */ - stlink_read_reg(sl, 16, &rr); - if ((rr.xpsr & (1 << 24)) == 0) { - ILOG("Go to Thumb mode\n"); - stlink_write_reg(sl, rr.xpsr | (1 << 24), 16); - } - - return (sl->backend->run(sl, type)); -} - -int stlink_set_swdclk(stlink_t *sl, int freq_khz) { - DLOG("*** set_swdclk ***\n"); - return (sl->backend->set_swdclk(sl, freq_khz)); -} - -int stlink_status(stlink_t *sl) { - int ret; - - DLOG("*** stlink_status ***\n"); - ret = sl->backend->status(sl); - stlink_core_stat(sl); - return (ret); -} - -/** - * Decode the version bits, originally from -sg, verified with usb - * @param sl stlink context, assumed to contain valid data in the buffer - * @param slv output parsed version object - */ -void _parse_version(stlink_t *sl, stlink_version_t *slv) { - sl->version.flags = 0; - - if (sl->version.stlink_v < 3) { - uint32_t b0 = sl->q_buf[0]; // lsb - uint32_t b1 = sl->q_buf[1]; - uint32_t b2 = sl->q_buf[2]; - uint32_t b3 = sl->q_buf[3]; - uint32_t b4 = sl->q_buf[4]; - uint32_t b5 = sl->q_buf[5]; // msb - - // b0 b1 || b2 b3 | b4 b5 - // 4b | 6b | 6b || 2B | 2B - // stlink_v | jtag_v | swim_v || st_vid | stlink_pid - - slv->stlink_v = (b0 & 0xf0) >> 4; - slv->jtag_v = ((b0 & 0x0f) << 2) | ((b1 & 0xc0) >> 6); - slv->swim_v = b1 & 0x3f; - slv->st_vid = (b3 << 8) | b2; - slv->stlink_pid = (b5 << 8) | b4; - - // ST-LINK/V1 from J11 switch to api-v2 (and support SWD) - if (slv->stlink_v == 1) { - slv->jtag_api = - slv->jtag_v > 11 ? STLINK_JTAG_API_V2 : STLINK_JTAG_API_V1; - } else { - slv->jtag_api = STLINK_JTAG_API_V2; - - // preferred API to get last R/W status from J15 - if (sl->version.jtag_v >= 15) { - sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; - } - - if (sl->version.jtag_v >= 13) { - sl->version.flags |= STLINK_F_HAS_TRACE; - sl->max_trace_freq = STLINK_V2_MAX_TRACE_FREQUENCY; - } - } - } else { - // V3 uses different version format, for reference see OpenOCD source - // (that was written from docs available from ST under NDA): - // https://github.com/ntfreak/openocd/blob/a6dacdff58ef36fcdac00c53ec27f19de1fbce0d/src/jtag/drivers/stlink_usb.c#L965 - slv->stlink_v = sl->q_buf[0]; - slv->swim_v = sl->q_buf[1]; - slv->jtag_v = sl->q_buf[2]; - slv->st_vid = (uint32_t)((sl->q_buf[9] << 8) | sl->q_buf[8]); - slv->stlink_pid = (uint32_t)((sl->q_buf[11] << 8) | sl->q_buf[10]); - slv->jtag_api = STLINK_JTAG_API_V3; - /* preferred API to get last R/W status */ - sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; - sl->version.flags |= STLINK_F_HAS_TRACE; - sl->max_trace_freq = STLINK_V3_MAX_TRACE_FREQUENCY; - } - - return; -} - -int stlink_version(stlink_t *sl) { - DLOG("*** looking up stlink version\n"); - - if (sl->backend->version(sl)) { - return (-1); - } - - _parse_version(sl, &sl->version); - - DLOG("st vid = 0x%04x (expect 0x%04x)\n", sl->version.st_vid, - STLINK_USB_VID_ST); - DLOG("stlink pid = 0x%04x\n", sl->version.stlink_pid); - DLOG("stlink version = 0x%x\n", sl->version.stlink_v); - DLOG("jtag version = 0x%x\n", sl->version.jtag_v); - DLOG("swim version = 0x%x\n", sl->version.swim_v); - - if (sl->version.jtag_v == 0) { - WLOG(" warning: stlink doesn't support JTAG/SWD interface\n"); - } - - return (0); -} - -int stlink_target_voltage(stlink_t *sl) { - int voltage = -1; - DLOG("*** reading target voltage\n"); - - if (sl->backend->target_voltage != NULL) { - voltage = sl->backend->target_voltage(sl); - - if (voltage != -1) { - DLOG("target voltage = %imV\n", voltage); - } else { - DLOG("error reading target voltage\n"); - } - } else { - DLOG("reading voltage not supported by backend\n"); - } - - return (voltage); -} - -int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { - int ret; - - ret = sl->backend->read_debug32(sl, addr, data); - if (!ret) - DLOG("*** stlink_read_debug32 %#010x at %#010x\n", *data, addr); - - return (ret); -} - -int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { - DLOG("*** stlink_write_debug32 %#010x to %#010x\n", data, addr); - return sl->backend->write_debug32(sl, addr, data); -} - -int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); - - if (len % 4 != 0) { - ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); - return (-1); - } - - return (sl->backend->write_mem32(sl, addr, len)); -} - -int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_read_mem32 ***\n"); - - if (len % 4 != 0) { // !!! never ever: fw gives just wrong values - ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); - return (-1); - } - - return (sl->backend->read_mem32(sl, addr, len)); -} - -int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_write_mem8 ***\n"); - return (sl->backend->write_mem8(sl, addr, len)); -} - -int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { - DLOG("*** stlink_read_all_regs ***\n"); - return (sl->backend->read_all_regs(sl, regp)); -} - -int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { - DLOG("*** stlink_read_all_unsupported_regs ***\n"); - return (sl->backend->read_all_unsupported_regs(sl, regp)); -} - -int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) { - DLOG("*** stlink_write_reg\n"); - return (sl->backend->write_reg(sl, reg, idx)); -} - -int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { - DLOG("*** stlink_read_reg\n"); - DLOG(" (%d) ***\n", r_idx); - - if (r_idx > 20 || r_idx < 0) { - fprintf(stderr, "Error: register index must be in [0..20]\n"); - return (-1); - } - - return (sl->backend->read_reg(sl, r_idx, regp)); -} - -int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, - struct stlink_reg *regp) { - int r_convert; - - DLOG("*** stlink_read_unsupported_reg\n"); - DLOG(" (%d) ***\n", r_idx); - - /* Convert to values used by STLINK_REG_DCRSR */ - if (r_idx >= 0x1C && - r_idx <= 0x1F) { // primask, basepri, faultmask, or control - r_convert = 0x14; - } else if (r_idx == 0x40) { // FPSCR - r_convert = 0x21; - } else if (r_idx >= 0x20 && r_idx < 0x40) { - r_convert = 0x40 + (r_idx - 0x20); - } else { - fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); - return (-1); - } - - return (sl->backend->read_unsupported_reg(sl, r_convert, regp)); -} - -int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, - struct stlink_reg *regp) { - int r_convert; - - DLOG("*** stlink_write_unsupported_reg\n"); - DLOG(" (%d) ***\n", r_idx); - - /* Convert to values used by STLINK_REG_DCRSR */ - if (r_idx >= 0x1C && - r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ - r_convert = r_idx; // the backend function handles this - } else if (r_idx == 0x40) { // FPSCR - r_convert = 0x21; - } else if (r_idx >= 0x20 && r_idx < 0x40) { - r_convert = 0x40 + (r_idx - 0x20); - } else { - fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); - return (-1); - } - - return (sl->backend->write_unsupported_reg(sl, val, r_convert, regp)); -} - -bool stlink_is_core_halted(stlink_t *sl) { - stlink_status(sl); - return (sl->core_stat == TARGET_HALTED); -} - -int stlink_step(stlink_t *sl) { - DLOG("*** stlink_step ***\n"); - return (sl->backend->step(sl)); -} - -int stlink_current_mode(stlink_t *sl) { - int mode = sl->backend->current_mode(sl); - - switch (mode) { - case STLINK_DEV_DFU_MODE: - DLOG("stlink current mode: dfu\n"); - return (mode); - case STLINK_DEV_DEBUG_MODE: - DLOG("stlink current mode: debug (jtag or swd)\n"); - return (mode); - case STLINK_DEV_MASS_MODE: - DLOG("stlink current mode: mass\n"); - return (mode); - } - - DLOG("stlink mode: unknown!\n"); - return (STLINK_DEV_UNKNOWN_MODE); -} - -int stlink_trace_enable(stlink_t *sl, uint32_t frequency) { - DLOG("*** stlink_trace_enable ***\n"); - return (sl->backend->trace_enable(sl, frequency)); -} - -int stlink_trace_disable(stlink_t *sl) { - DLOG("*** stlink_trace_disable ***\n"); - return (sl->backend->trace_disable(sl)); -} - -int stlink_trace_read(stlink_t *sl, uint8_t *buf, size_t size) { - return (sl->backend->trace_read(sl, buf, size)); -} - -// End of delegates.... Common code below here... - -// same as above with entrypoint. - -void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { - stlink_write_reg(sl, addr, 15); /* pc register */ - stlink_run(sl, RUN_NORMAL); - - while (stlink_is_core_halted(sl)) { - usleep(3000000); - } -} - -// this function is called by stlink_status() -// do not call stlink_core_stat() directly, always use stlink_status() -void stlink_core_stat(stlink_t *sl) { - switch (sl->core_stat) { - case TARGET_RUNNING: - DLOG(" core status: running\n"); - return; - case TARGET_HALTED: - DLOG(" core status: halted\n"); - return; - case TARGET_RESET: - DLOG(" core status: reset\n"); - return; - case TARGET_DEBUG_RUNNING: - DLOG(" core status: debug running\n"); - return; - default: - DLOG(" core status: unknown\n"); - } -} - -void stlink_print_data(stlink_t *sl) { - if (sl->q_len <= 0 || sl->verbose < UDEBUG) { - return; - } - - if (sl->verbose > 2) { - DLOG("data_len = %d 0x%x\n", sl->q_len, sl->q_len); - } - - for (int i = 0; i < sl->q_len; i++) { - if (i % 16 == 0) { - /* - if (sl->q_data_dir == Q_DATA_OUT) { - fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i); - } else { - fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); - } - */ - } - // DLOG(" %02x", (unsigned int) sl->q_buf[i]); - fprintf(stderr, " %02x", (unsigned int)sl->q_buf[i]); - } - // DLOG("\n\n"); - fprintf(stderr, "\n"); -} - -/* Memory mapped file */ -typedef struct mapped_file { - uint8_t *base; - size_t len; -} mapped_file_t; - -#define MAPPED_FILE_INITIALIZER \ - { NULL, 0 } - -static int map_file(mapped_file_t *mf, const char *path) { - int error = -1; - struct stat st; - - const int fd = open(path, O_RDONLY | O_BINARY); - - if (fd == -1) { - fprintf(stderr, "open(%s) == -1\n", path); - return (-1); - } - - if (fstat(fd, &st) == -1) { - fprintf(stderr, "fstat(%s) == -1\n", path); - goto on_error; - } - - if (sizeof(st.st_size) != sizeof(size_t)) { - // on 32 bit systems, check if there is an overflow - if (st.st_size > (off_t)SSIZE_MAX) { - fprintf(stderr, "mmap() size_t overflow for file %s\n", path); - goto on_error; - } - } - - mf->base = - (uint8_t *)mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); - - if (mf->base == MAP_FAILED) { - fprintf(stderr, "mmap() == MAP_FAILED for file %s\n", path); - goto on_error; - } - - mf->len = (size_t)st.st_size; - error = 0; // success - -on_error: - close(fd); - return (error); -} - -static void unmap_file(mapped_file_t *mf) { - munmap((void *)mf->base, mf->len); - mf->base = (unsigned char *)MAP_FAILED; - mf->len = 0; -} - -/* Limit the block size to compare to 0x1800 as anything larger will stall the - * STLINK2 Maybe STLINK V1 needs smaller value! - */ -static int check_file(stlink_t *sl, mapped_file_t *mf, stm32_addr_t addr) { - size_t off; - size_t n_cmp = sl->flash_pgsz; - - if (n_cmp > 0x1800) { - n_cmp = 0x1800; - } - - for (off = 0; off < mf->len; off += n_cmp) { - size_t aligned_size; - - size_t cmp_size = n_cmp; // adjust last page size - - if ((off + n_cmp) > mf->len) { - cmp_size = mf->len - off; - } - - aligned_size = cmp_size; - - if (aligned_size & (4 - 1)) { - aligned_size = (cmp_size + 4) & ~(4 - 1); - } - - stlink_read_mem32(sl, addr + (uint32_t)off, (uint16_t)aligned_size); - - if (memcmp(sl->q_buf, mf->base + off, cmp_size)) { - return (-1); - } - } - - return (0); -} - -static void md5_calculate(mapped_file_t *mf) { - // calculate md5 checksum of given binary file - Md5Context md5Context; - MD5_HASH md5Hash; - Md5Initialise(&md5Context); - Md5Update(&md5Context, mf->base, (uint32_t)mf->len); - Md5Finalise(&md5Context, &md5Hash); - printf("md5 checksum: "); - - for (int i = 0; i < (int)sizeof(md5Hash); i++) { - printf("%x", md5Hash.bytes[i]); - } - - printf(", "); -} - -static void stlink_checksum(mapped_file_t *mp) { - /* checksum that backward compatible with official ST tools */ - uint32_t sum = 0; - uint8_t *mp_byte = (uint8_t *)mp->base; - - for (size_t i = 0; i < mp->len; ++i) { - sum += mp_byte[i]; - } - - printf("stlink checksum: 0x%08x\n", sum); -} - -static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { - unsigned int val; - // set PC to the reset routine - stlink_read_debug32(sl, addr + 4, &val); - stlink_write_reg(sl, val, 15); - stlink_run(sl, RUN_NORMAL); -} - -int stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, - stm32_addr_t addr) { - // write the file in sram at addr - - int error = -1; - size_t off; - size_t len; - - // check addr range is inside the sram - if (addr < sl->sram_base) { - fprintf(stderr, "addr too low\n"); - goto on_error; - } else if ((addr + length) < addr) { - fprintf(stderr, "addr overruns\n"); - goto on_error; - } else if ((addr + length) > (sl->sram_base + sl->sram_size)) { - fprintf(stderr, "addr too high\n"); - goto on_error; - } else if (addr & 3) { - fprintf(stderr, "unaligned addr\n"); - goto on_error; - } - - len = length; - - if (len & 3) { - len -= len & 3; - } - - // do the copy by 1kB blocks - for (off = 0; off < len; off += 1024) { - size_t size = 1024; - - if ((off + size) > len) { - size = len - off; - } - - memcpy(sl->q_buf, data + off, size); - - if (size & 3) { - size += 2; - } // round size if needed - - stlink_write_mem32(sl, addr + (uint32_t)off, (uint16_t)size); - } - - if (length > len) { - memcpy(sl->q_buf, data + len, length - len); - stlink_write_mem8(sl, addr + (uint32_t)len, (uint16_t)(length - len)); - } - - error = 0; // success - stlink_fwrite_finalize(sl, addr); - -on_error: - return (error); -} - -int stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { - // write the file in sram at addr - - int error = -1; - size_t off; - size_t len; - mapped_file_t mf = MAPPED_FILE_INITIALIZER; - - if (map_file(&mf, path) == -1) { - fprintf(stderr, "map_file() == -1\n"); - return (-1); - } - - printf("file %s ", path); - md5_calculate(&mf); - stlink_checksum(&mf); - - // check if addr range is inside the SRAM - if (addr < sl->sram_base) { - fprintf(stderr, "addr too low\n"); - goto on_error; - } else if ((addr + mf.len) < addr) { - fprintf(stderr, "addr overruns\n"); - goto on_error; - } else if ((addr + mf.len) > (sl->sram_base + sl->sram_size)) { - fprintf(stderr, "addr too high\n"); - goto on_error; - } else if (addr & 3) { - fprintf(stderr, "unaligned addr\n"); - goto on_error; - } - - len = mf.len; - - if (len & 3) { - len -= len & 3; - } - - // do the copy by 1kB blocks - for (off = 0; off < len; off += 1024) { - size_t size = 1024; - - if ((off + size) > len) { - size = len - off; - } - - memcpy(sl->q_buf, mf.base + off, size); - - if (size & 3) { - size += 2; - } // round size if needed - - stlink_write_mem32(sl, addr + (uint32_t)off, (uint16_t)size); - } - - if (mf.len > len) { - memcpy(sl->q_buf, mf.base + len, mf.len - len); - stlink_write_mem8(sl, addr + (uint32_t)len, (uint16_t)(mf.len - len)); - } - - // check the file has been written - if (check_file(sl, &mf, addr) == -1) { - fprintf(stderr, "check_file() == -1\n"); - goto on_error; - } - - error = 0; // success - stlink_fwrite_finalize(sl, addr); - -on_error: - unmap_file(&mf); - return (error); -} - -typedef bool (*save_block_fn)(void *arg, uint8_t *block, ssize_t len); - -static int stlink_read(stlink_t *sl, stm32_addr_t addr, size_t size, - save_block_fn fn, void *fn_arg) { - - int error = -1; - - if (size < 1) { - size = sl->flash_size; - } - - if (size > sl->flash_size) { - size = sl->flash_size; - } - - size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; - - for (size_t off = 0; off < size; off += cmp_size) { - size_t aligned_size; - - // adjust last page size - if ((off + cmp_size) > size) { - cmp_size = size - off; - } - - aligned_size = cmp_size; - - if (aligned_size & (4 - 1)) { - aligned_size = (cmp_size + 4) & ~(4 - 1); - } - - stlink_read_mem32(sl, addr + (uint32_t)off, (uint16_t)aligned_size); - - if (!fn(fn_arg, sl->q_buf, aligned_size)) { - goto on_error; - } - } - - error = 0; // success - -on_error: - return (error); -} - -struct stlink_fread_worker_arg { - int fd; -}; - -static bool stlink_fread_worker(void *arg, uint8_t *block, ssize_t len) { - struct stlink_fread_worker_arg *the_arg = - (struct stlink_fread_worker_arg *)arg; - - if (write(the_arg->fd, block, len) != len) { - fprintf(stderr, "write() != aligned_size\n"); - return (false); - } else { - return (true); - } -} - -struct stlink_fread_ihex_worker_arg { - FILE *file; - uint32_t addr; - uint32_t lba; - uint8_t buf[16]; - uint8_t buf_pos; -}; - -static bool -stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg *the_arg) { - uint32_t addr = the_arg->addr; - uint8_t sum = 2 + 4 + (uint8_t)((addr & 0xFF000000) >> 24) + - (uint8_t)((addr & 0x00FF0000) >> 16); - - if (17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", - (addr & 0xFFFF0000) >> 16, (uint8_t)(0x100 - sum))) { - return (false); - } - - the_arg->lba = (addr & 0xFFFF0000); - return (true); -} - -static bool -stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg *the_arg) { - uint8_t count = the_arg->buf_pos; - - if (count == 0) { - return (true); - } - - uint32_t addr = the_arg->addr; - - if (the_arg->lba != (addr & 0xFFFF0000)) { // segment changed - if (!stlink_fread_ihex_newsegment(the_arg)) { - return (false); - } - } - - uint8_t sum = count + (uint8_t)((addr & 0x0000FF00) >> 8) + - (uint8_t)(addr & 0x000000FF); - - if (9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) { - return (false); - } - - for (uint8_t i = 0; i < count; ++i) { - uint8_t b = the_arg->buf[i]; - sum += b; - - if (2 != fprintf(the_arg->file, "%02X", b)) { - return (false); - } - } - - if (4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) { - return (false); - } - - the_arg->addr += count; - the_arg->buf_pos = 0; - - return (true); -} - -static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg *the_arg, - int fd, stm32_addr_t addr) { - the_arg->file = fdopen(fd, "w"); - the_arg->addr = addr; - the_arg->lba = 0; - the_arg->buf_pos = 0; - - return (the_arg->file != NULL); -} - -static bool stlink_fread_ihex_worker(void *arg, uint8_t *block, ssize_t len) { - struct stlink_fread_ihex_worker_arg *the_arg = - (struct stlink_fread_ihex_worker_arg *)arg; - - for (ssize_t i = 0; i < len; ++i) { - if (the_arg->buf_pos == sizeof(the_arg->buf)) { // line is full - if (!stlink_fread_ihex_writeline(the_arg)) { - return (false); - } - } - - the_arg->buf[the_arg->buf_pos++] = block[i]; - } - - return (true); -} - -static bool -stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg *the_arg) { - if (!stlink_fread_ihex_writeline(the_arg)) { - return (false); - } - - // FIXME: do we need the Start Linear Address? - - if (13 != fprintf(the_arg->file, ":00000001FF\r\n")) { // EoF - return (false); - } - - return (0 == fclose(the_arg->file)); -} - -int stlink_fread(stlink_t *sl, const char *path, bool is_ihex, - stm32_addr_t addr, size_t size) { - // read size bytes from addr to file - ILOG("read from address %#010x size %u\n", addr, (unsigned)size); - - int error; - int fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); - - if (fd == -1) { - fprintf(stderr, "open(%s) == -1\n", path); - return (-1); - } - - if (is_ihex) { - struct stlink_fread_ihex_worker_arg arg; - - if (stlink_fread_ihex_init(&arg, fd, addr)) { - error = stlink_read(sl, addr, size, &stlink_fread_ihex_worker, &arg); - - if (!stlink_fread_ihex_finalize(&arg)) { - error = -1; - } - } else { - error = -1; - } - } else { - struct stlink_fread_worker_arg arg = {fd}; - error = stlink_read(sl, addr, size, &stlink_fread_worker, &arg); - } - - close(fd); - return (error); -} - -int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, - size_t size) { - // write the buffer right after the loader - int ret = 0; - size_t chunk = size & ~0x3; - size_t rem = size & 0x3; - - if (chunk) { - memcpy(sl->q_buf, buf, chunk); - ret = stlink_write_mem32(sl, fl->buf_addr, (uint16_t)chunk); - } - - if (rem && !ret) { - memcpy(sl->q_buf, buf + chunk, rem); - ret = stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, (uint16_t)rem); - } - - return (ret); -} - -uint32_t calculate_F4_sectornum(uint32_t flashaddr) { - uint32_t offset = 0; - flashaddr &= ~STM32_FLASH_BASE; // page now holding the actual flash address - - if (flashaddr >= 0x100000) { - offset = 12; - flashaddr -= 0x100000; - } - - if (flashaddr < 0x4000) { - return (offset + 0); - } else if (flashaddr < 0x8000) { - return (offset + 1); - } else if (flashaddr < 0xc000) { - return (offset + 2); - } else if (flashaddr < 0x10000) { - return (offset + 3); - } else if (flashaddr < 0x20000) { - return (offset + 4); - } else { - return (offset + (flashaddr / 0x20000) + 4); - } -} - -uint32_t calculate_F7_sectornum(uint32_t flashaddr) { - flashaddr &= ~STM32_FLASH_BASE; // Page now holding the actual flash address - - if (flashaddr < 0x20000) { - return (flashaddr / 0x8000); - } else if (flashaddr < 0x40000) { - return (4); - } else { - return ((flashaddr / 0x40000) + 4); - } -} - -uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, - unsigned bank) { - flashaddr &= - ~((bank == BANK_1) - ? STM32_FLASH_BASE - : STM32_H7_FLASH_BANK2_BASE); // sector holding the flash address - return (flashaddr / sl->flash_pgsz); -} - -// returns BKER:PNB for the given page address -uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { - uint32_t bker = 0; - uint32_t flashopt; - stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); - flashaddr -= STM32_FLASH_BASE; - - if (sl->chip_id == STLINK_CHIPID_STM32_L4 || - sl->chip_id == STLINK_CHIPID_STM32_L496x_L4A6x || - sl->chip_id == STLINK_CHIPID_STM32_L4Rx) { - // this chip use dual banked flash - if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { - uint32_t banksize = (uint32_t)sl->flash_size / 2; - - if (flashaddr >= banksize) { - flashaddr -= banksize; - bker = 0x100; - } - } - } - - // For 1MB chips without the dual-bank option set, the page address will - // overflow into the BKER bit, which gives us the correct bank:page value. - return (bker | flashaddr / (uint32_t)sl->flash_pgsz); -} - -uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { - if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || - (sl->chip_id == STLINK_CHIPID_STM32_F4) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || - (sl->chip_id == STLINK_CHIPID_STM32_F411xx) || - (sl->chip_id == STLINK_CHIPID_STM32_F446) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || - (sl->chip_id == STLINK_CHIPID_STM32_F72xxx) || - (sl->chip_id == STLINK_CHIPID_STM32_F412)) { - uint32_t sector = calculate_F4_sectornum(flashaddr); - - if (sector >= 12) { - sector -= 12; - } - - if (sector < 4) { - sl->flash_pgsz = 0x4000; - } else if (sector < 5) { - sl->flash_pgsz = 0x10000; - } else { - sl->flash_pgsz = 0x20000; - } - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F76xxx) { - uint32_t sector = calculate_F7_sectornum(flashaddr); - - if (sector < 4) { - sl->flash_pgsz = 0x8000; - } else if (sector < 5) { - sl->flash_pgsz = 0x20000; - } else { - sl->flash_pgsz = 0x40000; - } - } - - return ((uint32_t)sl->flash_pgsz); -} - -/** - * Erase a page of flash, assumes sl is fully populated with things like - * chip/core ids - * @param sl stlink context - * @param flashaddr an address in the flash page to erase - * @return 0 on success -ve on failure - */ -int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - // wait for ongoing op to finish - wait_flash_busy(sl); - // clear flash IO errors - clear_flash_error(sl); - - if (sl->flash_type == STLINK_FLASH_TYPE_F4 || - sl->flash_type == STLINK_FLASH_TYPE_F7 || - sl->flash_type == STLINK_FLASH_TYPE_L4) { - // unlock if locked - unlock_flash_if(sl); - - // select the page to erase - if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || - (sl->chip_id == STLINK_CHIPID_STM32_L43x_L44x) || - (sl->chip_id == STLINK_CHIPID_STM32_L45x_L46x) || - (sl->chip_id == STLINK_CHIPID_STM32_L496x_L4A6x) || - (sl->chip_id == STLINK_CHIPID_STM32_L4Rx)) { - // calculate the actual bank+page from the address - uint32_t page = calculate_L4_page(sl, flashaddr); - - fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", page, - stlink_calculate_pagesize(sl, flashaddr)); - - write_flash_cr_bker_pnb(sl, page); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F76xxx) { - // calculate the actual page from the address - uint32_t sector = calculate_F7_sectornum(flashaddr); - - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, - stlink_calculate_pagesize(sl, flashaddr)); - write_flash_cr_snb(sl, sector, BANK_1); - } else { - // calculate the actual page from the address - uint32_t sector = calculate_F4_sectornum(flashaddr); - - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, - stlink_calculate_pagesize(sl, flashaddr)); - - // the SNB values for flash sectors in the second bank do not directly - // follow the values for the first bank on 2mb devices... - if (sector >= 12) { - sector += 4; - } - - write_flash_cr_snb(sl, sector, BANK_1); - } - - set_flash_cr_strt(sl, BANK_1); // start erase operation - wait_flash_busy(sl); // wait for completion - lock_flash(sl); // TODO: fails to program if this is in -#if DEBUG_FLASH - fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl, BANK_1)); -#endif - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - - // check if the locks are set - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - - if ((val & (1 << 0)) || (val & (1 << 1))) { - // disable pecr protection - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, - FLASH_L0_PEKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, - FLASH_L0_PEKEY2); - - // check pecr.pelock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - - if (val & (1 << 0)) { - WLOG("pecr.pelock not clear (%#x)\n", val); - return (-1); - } - - // unlock program memory - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, - FLASH_L0_PRGKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, - FLASH_L0_PRGKEY2); - - // check pecr.prglock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - - if (val & (1 << 1)) { - WLOG("pecr.prglock not clear (%#x)\n", val); - return (-1); - } - } - - // set pecr.{erase,prog} - val |= (1 << 9) | (1 << 3); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - - // write 0 to the first word of the page to be erased - stlink_write_debug32(sl, flashaddr, 0); - - /* MP: It is better to wait for clearing the busy bit after issuing page - * erase command, even though PM0062 recommends to wait before it. - * Test shows that a few iterations is performed in the following loop - * before busy bit is cleared. - */ - wait_flash_busy(sl); - - // reset lock bits - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - uint32_t val; - unlock_flash_if(sl); - set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit - - // set the page to erase - if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - uint32_t flash_page = - ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - - // sec 3.10.5 - PNB[7:0] is offset by 3. - val &= ~(0xFF << 3); // Clear previously set page number (if any) - val |= ((flash_page & 0xFF) << 3); - - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { - uint32_t flash_page = - ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. - val &= ~(0x3F << 3); - val |= ((flash_page & 0x3F) << 3) | (1 << FLASH_CR_PER); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G4) { - uint32_t flash_page = - ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. - val &= ~(0x7F << 3); - val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - } - - set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit - wait_flash_busy(sl); // wait for the 'busy' bit to clear - clear_flash_cr_per(sl, BANK_1); // clear the 'enable page erase' bit - lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_F0 || - sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - unsigned bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; - unlock_flash_if(sl); - clear_flash_cr_pg(sl, bank); // clear the pg bit - set_flash_cr_per(sl, bank); // set the page erase bit - write_flash_ar(sl, flashaddr, bank); // select the page to erase - set_flash_cr_strt(sl, - bank); // start erase operation, reset by hw with busy bit - wait_flash_busy(sl); - clear_flash_cr_per(sl, bank); // clear the page erase bit - lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; - unlock_flash_if(sl); // unlock if locked - uint32_t sector = calculate_H7_sectornum( - sl, flashaddr, bank); // calculate the actual page from the address - write_flash_cr_snb(sl, sector, bank); // select the page to erase - set_flash_cr_strt(sl, bank); // start erase operation - wait_flash_busy(sl); // wait for completion - lock_flash(sl); - } else { - WLOG("unknown coreid %x, page erase failed\n", sl->core_id); - return (-1); - } - - return check_flash_error(sl); -} - -// Check if an address and size are within the flash -int stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size) { - if (addr < sl->flash_base || addr >= (sl->flash_base + sl->flash_size)) { - ELOG("Invalid address, it should be within 0x%08x - 0x%08lx\n", sl->flash_base, (sl->flash_base + sl->flash_size -1)); - return (-1); - } - if ((addr + size) > (sl->flash_base + sl->flash_size)) { - ELOG("The size exceeds the size of the flash (0x%08lx bytes available)\n", (sl->flash_base + sl->flash_size - addr)); - return (-1); - } - return 0; -} - -// Check if an address is aligned with the beginning of a page -int stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr) { - stm32_addr_t page = sl->flash_base; - - while (page < addr) { - page += stlink_calculate_pagesize(sl, page); - } - - if (page != addr) { - return -1; - } - - return 0; -} - -int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size) { - // Check the address and size validity - if (stlink_check_address_range_validity(sl, base_addr, size) < 0) { - return -1; - } - - // Make sure the requested address is aligned with the beginning of a page - if (stlink_check_address_alignment(sl, base_addr) < 0) { - ELOG("The address to erase is not aligned with the beginning of a page\n"); - return -1; - } - - stm32_addr_t addr = base_addr; - do { - size_t page_size = stlink_calculate_pagesize(sl, addr); - - // Check if size is aligned with a page, unless we want to completely erase the last page - if ((addr + page_size) > (base_addr + size) && !align_size) { - ELOG("Invalid size (not aligned with a page). Page size at address %#x is %#lx\n", addr, page_size); - return -1; - } - - if (stlink_erase_flash_page(sl, addr)) { - WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); - return (-1); - } - - fprintf(stdout, "-> Flash page at %#x erased (size: %#lx)\n", addr, page_size); - fflush(stdout); - - // check the next page is within the range to erase - addr += page_size; - } while (addr < (base_addr + size)); - - fprintf(stdout, "\n"); - return 0; -} - -int stlink_erase_flash_mass(stlink_t *sl) { - int err = 0; - - // TODO: User MER bit to mass-erase WB series. - if (sl->flash_type == STLINK_FLASH_TYPE_L0 || - sl->flash_type == STLINK_FLASH_TYPE_WB) { - - err = stlink_erase_flash_section(sl, sl->flash_base, sl->flash_size, false); - - } else { - wait_flash_busy(sl); - clear_flash_error(sl); - unlock_flash_if(sl); - - if (sl->flash_type == STLINK_FLASH_TYPE_H7 && - sl->chip_id != STLINK_CHIPID_STM32_H7Ax) { - // set parallelism - write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); - } - } - - set_flash_cr_mer(sl, 1, BANK_1); // set the mass erase bit - set_flash_cr_strt( - sl, BANK_1); // start erase operation, reset by hw with busy bit - - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && - sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { - set_flash_cr_mer(sl, 1, BANK_2); // set the mass erase bit in bank 2 - set_flash_cr_strt(sl, BANK_2); // start erase operation in bank 2 - } - - wait_flash_busy_progress(sl); - lock_flash(sl); - - // reset the mass erase bit - set_flash_cr_mer(sl, 0, BANK_1); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && - sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { - set_flash_cr_mer(sl, 0, BANK_2); - } - - err = check_flash_error(sl); - } - - return (err); -} - -int stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { - // check the contents of path are at addr - - int res; - mapped_file_t mf = MAPPED_FILE_INITIALIZER; - - if (map_file(&mf, path) == -1) { - return (-1); - } - - res = check_file(sl, &mf, addr); - unmap_file(&mf); - return (res); -} - -/** - * Verify addr..addr+len is binary identical to base...base+len - * @param sl stlink context - * @param address stm device address - * @param data host side buffer to check against - * @param length how much - * @return 0 for success, -ve for failure - */ -int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, - unsigned length) { - size_t off; - size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; - ILOG("Starting verification of write complete\n"); - - for (off = 0; off < length; off += cmp_size) { - size_t aligned_size; - - // adjust last page size - if ((off + cmp_size) > length) { - cmp_size = length - off; - } - - aligned_size = cmp_size; - - if (aligned_size & (4 - 1)) { - aligned_size = (cmp_size + 4) & ~(4 - 1); - } - - stlink_read_mem32(sl, address + (uint32_t)off, (uint16_t)aligned_size); - - if (memcmp(sl->q_buf, data + off, cmp_size)) { - ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); - return (-1); - } - } - - ILOG("Flash written and verified! jolly good!\n"); - return (0); -} - -int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, - uint32_t len, uint32_t pagesize) { - unsigned int count, off; - unsigned int num_half_pages = len / pagesize; - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - flash_loader_t fl; - bool use_loader = true; - int ret = 0; - - // enable half page write - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << FLASH_L1_FPRG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - val |= (1 << FLASH_L1_PROG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - - wait_flash_busy(sl); - - for (count = 0; count < num_half_pages; count++) { - if (use_loader) { - ret = stlink_flash_loader_run(sl, &fl, addr + count * pagesize, - base + count * pagesize, pagesize); - if (ret && count == 0) { - /* It seems that stm32lx devices have a problem when it is blank */ - WLOG("Failed to use flash loader, fallback to soft write\n"); - use_loader = false; - } - } - if (!use_loader) { - ret = 0; - for (off = 0; off < pagesize && !ret; off += 64) { - size_t chunk = (pagesize - off > 64) ? 64 : pagesize - off; - memcpy(sl->q_buf, base + count * pagesize + off, chunk); - ret = stlink_write_mem32(sl, addr + count * pagesize + off, (uint16_t)chunk); - } - } - - if (ret) { - WLOG("l1_stlink_flash_loader_run(%#x) failed! == -1\n", - addr + count * pagesize); - break; - } - - if (sl->verbose >= 1) { - // show progress; writing procedure is slow and previous errors are - // misleading - fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); - fflush(stdout); - } - - // wait for sr.busy to be cleared - wait_flash_busy(sl); - } - - // disable half page write - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - return (ret); -} - -int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { - // disable DMA - set_dma_state(sl, fl, 0); - - // wait for ongoing op to finish - wait_flash_busy(sl); - // Clear errors - clear_flash_error(sl); - - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4)) { - ILOG("Starting Flash write for F2/F4/F7/L4\n"); - - // Flash loader initialisation - if (stlink_flash_loader_init(sl, fl) == -1) { - ELOG("stlink_flash_loader_init() == -1\n"); - return (-1); - } - - unlock_flash_if(sl); // first unlock the cr - - int voltage; - if (sl->version.stlink_v == 1) { - WLOG("STLINK V1 cannot read voltage, use default voltage 3.2V\n"); - voltage = 3200; - } else { - voltage = stlink_target_voltage(sl); - } - - if (voltage == -1) { - ELOG("Failed to read Target voltage\n"); - return (-1); - } - - if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - // L4 does not have a byte-write mode - if (voltage < 1710) { - ELOG("Target voltage (%d mV) too low for flash writes!\n", voltage); - return (-1); - } - } else { - if (voltage > 2700) { - ILOG("enabling 32-bit flash writes\n"); - write_flash_cr_psiz(sl, 2, BANK_1); - } else { - ILOG("Target voltage (%d mV) too low for 32-bit flash, " - "using 8-bit flash writes\n", - voltage); - write_flash_cr_psiz(sl, 0, BANK_1); - } - } - - // set programming mode - set_flash_cr_pg(sl, BANK_1); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - ILOG("Starting Flash write for WB/G0/G4\n"); - - unlock_flash_if(sl); // unlock flash if necessary - set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - ILOG("Starting Flash write for L0\n"); - - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - - // disable pecr protection - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, - FLASH_L0_PEKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, - FLASH_L0_PEKEY2); - - // check pecr.pelock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if (val & (1 << 0)) { - ELOG("pecr.pelock not clear\n"); - return (-1); - } - - // unlock program memory - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, - FLASH_L0_PRGKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, - FLASH_L0_PRGKEY2); - - // check pecr.prglock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if (val & (1 << 1)) { - ELOG("pecr.prglock not clear\n"); - return (-1); - } - - /* Flash loader initialisation */ - if (stlink_flash_loader_init(sl, fl) == -1) { - // L0/L1 have fallback to soft write - WLOG("stlink_flash_loader_init() == -1\n"); - } - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - ILOG("Starting Flash write for VL/F0/F3/F1_XL\n"); - - // flash loader initialisation - if (stlink_flash_loader_init(sl, fl) == -1) { - ELOG("stlink_flash_loader_init() == -1\n"); - return (-1); - } - - // unlock flash - unlock_flash_if(sl); - - // set programming mode - set_flash_cr_pg(sl, BANK_1); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - set_flash_cr_pg(sl, BANK_2); - } - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - ILOG("Starting Flash write for H7\n"); - - unlock_flash_if(sl); // unlock the cr - set_flash_cr_pg(sl, BANK_1); // set programming mode - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - set_flash_cr_pg(sl, BANK_2); - } - if (sl->chip_id != STLINK_CHIPID_STM32_H7Ax) { - // set parallelism - write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); - } - } - } else { - ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); - return (-1); - } - - return (0); -} - -int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, - stm32_addr_t addr, uint8_t *base, uint32_t len) { - size_t off; - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4)) { - size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; - for (off = 0; off < len;) { - size_t size = len - off > buf_size ? buf_size : len - off; - if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, - size) == -1) { - ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", - (unsigned)(addr + off)); - check_flash_error(sl); - return (-1); - } - - off += size; - } - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); - for (off = 0; off < len; off += sizeof(uint32_t)) { - uint32_t data; - - if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { - fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off / sl->flash_pgsz), - (unsigned int)(len / sl->flash_pgsz)); - fflush(stdout); - } - - write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); - stlink_write_debug32(sl, addr + (uint32_t)off, data); - wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear - } - fprintf(stdout, "\n"); - - // flash writes happen as 2 words at a time - if ((off / sizeof(uint32_t)) % 2 != 0) { - stlink_write_debug32(sl, addr + (uint32_t)off, - 0); // write a single word of zeros - wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear - } - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - uint32_t pagesize = (flash_regs_base==STM32L0_FLASH_REGS_ADDR)? - L0_WRITE_BLOCK_SIZE:L1_WRITE_BLOCK_SIZE; - - DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); - - off = 0; - - if (len > pagesize) { - if (stm32l1_write_half_pages(sl, addr, base, len, pagesize)) { - return (-1); - } else { - off = (size_t)(len / pagesize) * pagesize; - } - } - - // write remaining word in program memory - for (; off < len; off += sizeof(uint32_t)) { - uint32_t data; - - if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { - fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off / sl->flash_pgsz), - (unsigned int)(len / sl->flash_pgsz)); - fflush(stdout); - } - - write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); - stlink_write_debug32(sl, addr + (uint32_t)off, data); - - // wait for sr.busy to be cleared - do { - stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); - } while ((val & (1 << 0)) != 0); - - // TODO: check redo write operation - } - fprintf(stdout, "\n"); - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - int write_block_count = 0; - for (off = 0; off < len; off += sl->flash_pgsz) { - // adjust last write size - size_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; - - // unlock and set programming mode - unlock_flash_if(sl); - - DLOG("Finished unlocking flash, running loader!\n"); - - if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, - size) == -1) { - ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", - (unsigned)(addr + off)); - check_flash_error(sl); - return (-1); - } - - lock_flash(sl); - - if (sl->verbose >= 1) { - // show progress; writing procedure is slow and previous errors are - // misleading - fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, - (unsigned int)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); - fflush(stdout); - } - } - if (sl->verbose >= 1) { - fprintf(stdout, "\n"); - } - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - for (off = 0; off < len;) { - // Program STM32H7x with 64-byte Flash words - size_t chunk = (len - off > 64) ? 64 : len - off; - memcpy(sl->q_buf, base + off, chunk); - stlink_write_mem32(sl, addr + (uint32_t)off, 64); - wait_flash_busy(sl); - - off += chunk; - - if (sl->verbose >= 1) { - // show progress - fprintf(stdout, "\r%u/%u bytes written", (unsigned int)off, - (unsigned int)len); - fflush(stdout); - } - } - if (sl->verbose >= 1) { - fprintf(stdout, "\n"); - } - } else { - return (-1); - } - - return check_flash_error(sl); -} - -int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { - uint32_t dhcsr; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || - (sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4) || - (sl->flash_type == STLINK_FLASH_TYPE_WB) || - (sl->flash_type == STLINK_FLASH_TYPE_G0) || - (sl->flash_type == STLINK_FLASH_TYPE_G4) || - (sl->flash_type == STLINK_FLASH_TYPE_H7)) { - - clear_flash_cr_pg(sl, BANK_1); - if ((sl->flash_type == STLINK_FLASH_TYPE_H7 && - sl->chip_flags & CHIP_F_HAS_DUAL_BANK) || - sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - clear_flash_cr_pg(sl, BANK_2); - } - lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - - // reset lock bits - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } - - // enable interrupt - if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) { - stlink_write_debug32(sl, STLINK_REG_DHCSR, - STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | - (dhcsr & (~STLINK_REG_DHCSR_C_MASKINTS))); - } - - // restore DMA state - set_dma_state(sl, fl, 1); - - return (0); -} - -int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, - uint32_t len, uint8_t eraseonly) { - int ret; - flash_loader_t fl; - ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, - len, addr, addr); - // check addr range is inside the flash - stlink_calculate_pagesize(sl, addr); - - // Check the address and size validity - if (stlink_check_address_range_validity(sl, addr, len) < 0) { - return (-1); - } else if (len & 1) { - WLOG("unaligned len 0x%x -- padding with zero\n", len); - len += 1; - } else if (stlink_check_address_alignment(sl, addr) < 0) { - ELOG("addr not a multiple of current pagesize (%u bytes), not supported, " - "check page start address and compare with flash module organisation " - "in related ST reference manual of your device.\n", - (unsigned)(sl->flash_pgsz)); - return (-1); - } - - // make sure we've loaded the context with the chip details - stlink_core_id(sl); - - // Erase this section of the flash - if (stlink_erase_flash_section(sl, addr, len, true) < 0) { - ELOG("Failed to erase the flash prior to writing\n"); - return (-1); - } - - if (eraseonly) { - return (0); - } - - ret = stlink_flashloader_start(sl, &fl); - if (ret) - return ret; - ret = stlink_flashloader_write(sl, &fl, addr, base, len); - if (ret) - return ret; - ret = stlink_flashloader_stop(sl, &fl); - if (ret) - return ret; - - return (stlink_verify_write_flash(sl, addr, base, len)); -} - -// TODO: length not checked -static uint8_t stlink_parse_hex(const char *hex) { - uint8_t d[2]; - - for (int i = 0; i < 2; ++i) { - char c = *(hex + i); - - if (c >= '0' && c <= '9') { - d[i] = c - '0'; - } else if (c >= 'A' && c <= 'F') { - d[i] = c - 'A' + 10; - } else if (c >= 'a' && c <= 'f') { - d[i] = c - 'a' + 10; - } else { - return (0); // error - } - } - - return ((d[0] << 4) | (d[1])); -} - -int stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **mem, - size_t *size, uint32_t *begin) { - int res = 0; - *begin = UINT32_MAX; - uint8_t *data = NULL; - uint32_t end = 0; - bool eof_found = false; - - for (int scan = 0; (res == 0) && (scan < 2); ++scan) { - // parse file two times - first to find memory range, second - to fill it - if (scan == 1) { - if (!eof_found) { - ELOG("No EoF recond\n"); - res = -1; - break; - } - - if (*begin >= end) { - ELOG("No data found in file\n"); - res = -1; - break; - } - - *size = (end - *begin) + 1; - data = calloc(*size, 1); // use calloc to get NULL if out of memory - - if (!data) { - ELOG("Cannot allocate %u bytes\n", (unsigned)(*size)); - res = -1; - break; - } - - memset(data, erased_pattern, *size); - } - - FILE *file = fopen(path, "r"); - - if (!file) { - ELOG("Cannot open file\n"); - res = -1; - break; - } - - uint32_t lba = 0; - char line[1 + 5 * 2 + 255 * 2 + 2]; - - while (fgets(line, sizeof(line), file)) { - if (line[0] == '\n' || line[0] == '\r') { - continue; - } // skip empty lines - - if (line[0] != ':') { // no marker - wrong file format - ELOG("Wrong file format - no marker\n"); - res = -1; - break; - } - - size_t l = strlen(line); - - while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r')) { - --l; - } // trim EoL - - if ((l < 11) || - (l == - (sizeof(line) - 1))) { // line too short or long - wrong file format - ELOG("Wrong file format - wrong line length\n"); - res = -1; - break; - } - - uint8_t chksum = 0; // check sum - - for (size_t i = 1; i < l; i += 2) { - chksum += stlink_parse_hex(line + i); - } - - if (chksum != 0) { - ELOG("Wrong file format - checksum mismatch\n"); - res = -1; - break; - } - - uint8_t reclen = stlink_parse_hex(line + 1); - - if (((uint32_t)reclen + 5) * 2 + 1 != l) { - ELOG("Wrong file format - record length mismatch\n"); - res = -1; - break; - } - - uint16_t offset = ((uint16_t)stlink_parse_hex(line + 3) << 8) | - ((uint16_t)stlink_parse_hex(line + 5)); - uint8_t rectype = stlink_parse_hex(line + 7); - - switch (rectype) { - case 0: /* Data */ - if (scan == 0) { - uint32_t b = lba + offset; - uint32_t e = b + reclen - 1; - - if (b < *begin) { - *begin = b; - } - - if (e > end) { - end = e; - } - } else { - for (uint8_t i = 0; i < reclen; ++i) { - uint8_t b = stlink_parse_hex(line + 9 + i * 2); - uint32_t addr = lba + offset + i; - - if (addr >= *begin && addr <= end) { - data[addr - *begin] = b; - } - } - } - break; - case 1: /* EoF */ - eof_found = true; - break; - case 2: /* Extended Segment Address, unexpected */ - res = -1; - break; - case 3: /* Start Segment Address, unexpected */ - res = -1; - break; - case 4: /* Extended Linear Address */ - if (reclen == 2) { - lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | - ((uint32_t)stlink_parse_hex(line + 11) << 16); - } else { - ELOG("Wrong file format - wrong LBA length\n"); - res = -1; - } - break; - case 5: /* Start Linear Address - expected, but ignore */ - break; - default: - ELOG("Wrong file format - unexpected record type %d\n", rectype); - res = -1; - } - - if (res != 0) { - break; - } - } - - fclose(file); - } - - if (res == 0) { - *mem = data; - } else { - free(data); - } - - return (res); -} - -uint8_t stlink_get_erased_pattern(stlink_t *sl) { - if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - return (0x00); - } else { - return (0xff); - } -} - -int stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, - stm32_addr_t addr) { - /* Write the block in flash at addr */ - int err; - unsigned int num_empty, idx; - uint8_t erased_pattern = stlink_get_erased_pattern(sl); - - /* - * This optimisation may cause unexpected garbage data remaining. - * Therfore it is turned off by default. - */ - if (sl->opt) { - idx = (unsigned int)length; - - for (num_empty = 0; num_empty != length; ++num_empty) - if (data[--idx] != erased_pattern) { - break; - } - - num_empty -= (num_empty & 3); // Round down to words - - if (num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, - erased_pattern); - } - } else { - num_empty = 0; - } - - /* - * TODO: investigate a kind of weird behaviour here: - * If the file is identified to be all-empty and four-bytes aligned, - * still flash the whole file even if ignoring message is printed. - */ - err = stlink_write_flash(sl, addr, data, - (num_empty == length) ? (uint32_t)length - : (uint32_t)length - num_empty, - num_empty == length); - stlink_fwrite_finalize(sl, addr); - return (err); -} - -/** - * Write the given binary file into flash at address "addr" - * @param sl - * @param path readable file path, should be binary image - * @param addr where to start writing - * @return 0 on success, -ve on failure. - */ -int stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { - /* Write the file in flash at addr */ - int err; - unsigned int num_empty, idx; - uint8_t erased_pattern = stlink_get_erased_pattern(sl); - mapped_file_t mf = MAPPED_FILE_INITIALIZER; + int error; + int fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); - if (map_file(&mf, path) == -1) { - ELOG("map_file() == -1\n"); + if (fd == -1) { + fprintf(stderr, "open(%s) == -1\n", path); return (-1); } - printf("file %s ", path); - md5_calculate(&mf); - stlink_checksum(&mf); + if (is_ihex) { + struct stlink_fread_ihex_worker_arg arg; - if (sl->opt) { - idx = (unsigned int)mf.len; + if (stlink_fread_ihex_init(&arg, fd, addr)) { + error = stlink_read(sl, addr, size, &stlink_fread_ihex_worker, &arg); - for (num_empty = 0; num_empty != mf.len; ++num_empty) { - if (mf.base[--idx] != erased_pattern) { - break; + if (!stlink_fread_ihex_finalize(&arg)) { + error = -1; } - } - - num_empty -= (num_empty & 3); // round down to words - - if (num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, - erased_pattern); + } else { + error = -1; } } else { - num_empty = 0; + struct stlink_fread_worker_arg arg = {fd}; + error = stlink_read(sl, addr, size, &stlink_fread_worker, &arg); } - /* - * TODO: investigate a kind of weird behaviour here: - * If the file is identified to be all-empty and four-bytes aligned, - * still flash the whole file even if ignoring message is printed. - */ - err = stlink_write_flash(sl, addr, mf.base, - (num_empty == mf.len) ? (uint32_t)mf.len - : (uint32_t)mf.len - num_empty, - num_empty == mf.len); - stlink_fwrite_finalize(sl, addr); - unmap_file(&mf); - return (err); + close(fd); + return (error); } - -/** - * Write option bytes - * @param sl - * @param base option bytes to write - * @param addr of the memory mapped option bytes - * @param len of options bytes to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_f0( - stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { +// 300 +int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, + size_t size) { + // write the buffer right after the loader int ret = 0; + size_t chunk = size & ~0x3; + size_t rem = size & 0x3; - if (len < 12 || addr != STM32_F0_OPTION_BYTES_BASE) { - WLOG("Only full write of option bytes area is supported\n"); - return -1; - } - - clear_flash_error(sl); - - WLOG("Erasing option bytes\n"); - - /* erase option bytes */ - stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTER) | (1 << FLASH_CR_OPTWRE)); - ret = stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTER) | (1 << FLASH_CR_STRT) | (1 << FLASH_CR_OPTWRE)); - if (ret) { - return ret; - } - - wait_flash_busy(sl); - - ret = check_flash_error(sl); - if (ret) { - return ret; - } - - WLOG("Writing option bytes to %#10x\n", addr); - - /* Set the Option PG bit to enable programming */ - stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTPG) | (1 << FLASH_CR_OPTWRE)); - - /* Use flash loader for write OP - * because flash memory writable by half word */ - flash_loader_t fl; - ret = stlink_flash_loader_init(sl, &fl); - if (ret) { - return ret; - } - ret = stlink_flash_loader_run(sl, &fl, addr, base, len); - if (ret) { - return ret; + if (chunk) { + memcpy(sl->q_buf, buf, chunk); + ret = stlink_write_mem32(sl, fl->buf_addr, (uint16_t)chunk); } - /* Reload option bytes */ - stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OBL_LAUNCH)); - - return check_flash_error(sl); -} - -/** - * Write option bytes - * @param sl - * @param addr of the memory mapped option bytes - * @param base option bytes to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - /* Write options bytes */ - uint32_t val; - int ret = 0; - (void)len; - uint32_t data; - - clear_flash_error(sl); - - write_uint32((unsigned char *)&data, *(uint32_t *)(base)); - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); - - // Set Options Start bit - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - - wait_flash_busy(sl); - - ret = check_flash_error(sl); - - // Reload options - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - - return (ret); -} - -/** - * Write option bytes - * @param sl - * @param addr of the memory mapped option bytes - * @param base option bytes to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - uint32_t flash_base = get_stm32l0_flash_base(sl); - uint32_t val; - uint32_t data; - int ret = 0; - - // Clear errors - clear_flash_error(sl); - - while (len != 0) { - write_uint32((unsigned char *)&data, - *(uint32_t *)(base)); // write options bytes - - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - stlink_write_debug32(sl, addr, data); - wait_flash_busy(sl); - - if ((ret = check_flash_error(sl))) { - break; - } - - len -= 4; - addr += 4; - base += 4; + if (rem && !ret) { + memcpy(sl->q_buf, buf + chunk, rem); + ret = stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, (uint16_t)rem); } - // Reload options - stlink_read_debug32(sl, flash_base + FLASH_PECR_OFF, &val); - val |= (1 << STM32L0_FLASH_OBL_LAUNCH); - stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); - - return (ret); -} - -/** - * Write option bytes - * @param sl - * @param addr of the memory mapped option bytes - * @param base option bytes to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_l4(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - - uint32_t val; - int ret = 0; - (void)addr; - (void)len; - - // Clear errors - clear_flash_error(sl); - - // write options bytes - uint32_t data; - write_uint32((unsigned char *)&data, *(uint32_t *)(base)); - WLOG("Writing option bytes 0x%04x\n", data); - stlink_write_debug32(sl, STM32L4_FLASH_OPTR, data); - - // set options start bit - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1 << STM32L4_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - - wait_flash_busy(sl); - ret = check_flash_error(sl); - - // apply options bytes immediate - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - - return (ret); -} - -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - uint32_t option_byte; - int ret = 0; - (void)addr; - (void)len; - - // Clear errors - clear_flash_error(sl); - - write_uint32((unsigned char *)&option_byte, *(uint32_t *)(base)); - - // write option byte, ensuring we dont lock opt, and set strt bit - stlink_write_debug32(sl, FLASH_F4_OPTCR, - (option_byte & ~(1 << FLASH_F4_OPTCR_LOCK)) | - (1 << FLASH_F4_OPTCR_START)); - - wait_flash_busy(sl); - ret = check_flash_error(sl); - - // option bytes are reloaded at reset only, no obl. */ return (ret); } +// 291 +uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { + if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || + (sl->chip_id == STLINK_CHIPID_STM32_F4) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || + (sl->chip_id == STLINK_CHIPID_STM32_F411xx) || + (sl->chip_id == STLINK_CHIPID_STM32_F446) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || + (sl->chip_id == STLINK_CHIPID_STM32_F72xxx) || + (sl->chip_id == STLINK_CHIPID_STM32_F412)) { + uint32_t sector = calculate_F4_sectornum(flashaddr); -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - uint32_t option_byte; - int ret = 0; - - // Clear errors - clear_flash_error(sl); - - ILOG("Asked to write option byte %#10x to %#010x.\n", *(uint32_t *)(base), - addr); - write_uint32((unsigned char *)&option_byte, *(uint32_t *)(base)); - ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); + if (sector >= 12) { + sector -= 12; + } - if (addr == 0) { - addr = FLASH_F7_OPTCR; - ILOG("No address provided, using %#10x\n", addr); - } + if (sector < 4) { + sl->flash_pgsz = 0x4000; + } else if (sector < 5) { + sl->flash_pgsz = 0x10000; + } else { + sl->flash_pgsz = 0x20000; + } + } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || + sl->chip_id == STLINK_CHIPID_STM32_F76xxx) { + uint32_t sector = calculate_F7_sectornum(flashaddr); - if (addr == FLASH_F7_OPTCR) { - /* write option byte, ensuring we dont lock opt, and set strt bit */ - stlink_write_debug32(sl, FLASH_F7_OPTCR, - (option_byte & ~(1 << FLASH_F7_OPTCR_LOCK)) | - (1 << FLASH_F7_OPTCR_START)); - } else if (addr == FLASH_F7_OPTCR1) { - // Read FLASH_F7_OPTCR - uint32_t oldvalue; - stlink_read_debug32(sl, FLASH_F7_OPTCR, &oldvalue); - /* write option byte */ - stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_byte); - // Write FLASH_F7_OPTCR lock and start address - stlink_write_debug32(sl, FLASH_F7_OPTCR, - (oldvalue & ~(1 << FLASH_F7_OPTCR_LOCK)) | - (1 << FLASH_F7_OPTCR_START)); - } else { - WLOG("WIP: write %#010x to address %#010x\n", option_byte, addr); - stlink_write_debug32(sl, addr, option_byte); + if (sector < 4) { + sl->flash_pgsz = 0x8000; + } else if (sector < 5) { + sl->flash_pgsz = 0x20000; + } else { + sl->flash_pgsz = 0x40000; + } } - wait_flash_busy(sl); - - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t *)base, - addr); - - /* option bytes are reloaded at reset only, no obl. */ - - return ret; + return ((uint32_t)sl->flash_pgsz); } +// 279 +int stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **mem, + size_t *size, uint32_t *begin) { + int res = 0; + *begin = UINT32_MAX; + uint8_t *data = NULL; + uint32_t end = 0; + bool eof_found = false; -/** - * Write STM32H7xx option bytes - * @param sl - * @param base option bytes to write - * @param addr of the memory mapped option bytes - * @param len number of bytes to write (must be multiple of 4) - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_h7(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - uint32_t val; - uint32_t data; - - // Wait until previous flash option has completed - wait_flash_busy(sl); - - // Clear previous error - stlink_write_debug32(sl, FLASH_H7_OPTCCR, - 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); - - while (len != 0) { - switch (addr) { - case FLASH_H7_REGS_ADDR + 0x20: // FLASH_OPTSR_PRG - case FLASH_H7_REGS_ADDR + 0x2c: // FLASH_PRAR_PRG1 - case FLASH_H7_REGS_ADDR + 0x34: // FLASH_SCAR_PRG1 - case FLASH_H7_REGS_ADDR + 0x3c: // FLASH_WPSN_PRG1 - case FLASH_H7_REGS_ADDR + 0x44: // FLASH_BOOT_PRG - /* Write to FLASH_xxx_PRG registers */ - write_uint32((unsigned char *)&data, - *(uint32_t *)(base)); // write options bytes - - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - - /* Skip if the value in the CUR register is identical */ - stlink_read_debug32(sl, addr - 4, &val); - if (val == data) { + for (int scan = 0; (res == 0) && (scan < 2); ++scan) { + // parse file two times - first to find memory range, second - to fill it + if (scan == 1) { + if (!eof_found) { + ELOG("No EoF recond\n"); + res = -1; break; } - /* Write new option byte values and start modification */ - stlink_write_debug32(sl, addr, data); - stlink_read_debug32(sl, FLASH_H7_OPTCR, &val); - val |= (1 << FLASH_H7_OPTCR_OPTSTART); - stlink_write_debug32(sl, FLASH_H7_OPTCR, val); - - /* Wait for the option bytes modification to complete */ - do { - stlink_read_debug32(sl, FLASH_H7_OPTSR_CUR, &val); - } while ((val & (1 << FLASH_H7_OPTSR_OPT_BUSY)) != 0); - - /* Check for errors */ - if ((val & (1 << FLASH_H7_OPTSR_OPTCHANGEERR)) != 0) { - stlink_write_debug32(sl, FLASH_H7_OPTCCR, - 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); - return -1; + if (*begin >= end) { + ELOG("No data found in file\n"); + res = -1; + break; } - break; - - default: - /* Skip non-programmable registers */ - break; - } - - len -= 4; - addr += 4; - base += 4; - } - return 0; -} + *size = (end - *begin) + 1; + data = calloc(*size, 1); // use calloc to get NULL if out of memory -/** - * Read option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_Gx(stlink_t *sl, - uint32_t *option_byte) { - return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); -} + if (!data) { + ELOG("Cannot allocate %u bytes\n", (unsigned)(*size)); + res = -1; + break; + } -/** - * Read option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t *option_byte) { - return stlink_read_option_control_register_Gx(sl, option_byte); -} + memset(data, erased_pattern, *size); + } -/** - * Read option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_f2(stlink_t *sl, - uint32_t *option_byte) { - return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); -} + FILE *file = fopen(path, "r"); -/** - * Read option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t *option_byte) { - return stlink_read_option_control_register_f2(sl, option_byte); -} + if (!file) { + ELOG("Cannot open file\n"); + res = -1; + break; + } -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_f4(stlink_t *sl, - uint32_t *option_byte) { - return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); -} + uint32_t lba = 0; + char line[1 + 5 * 2 + 255 * 2 + 2]; -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t *option_byte) { - return stlink_read_option_control_register_f4(sl, option_byte); -} + while (fgets(line, sizeof(line), file)) { + if (line[0] == '\n' || line[0] == '\r') { + continue; + } // skip empty lines -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_f7(stlink_t *sl, - uint32_t *option_byte) { - DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_F7_OPTCR); - return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte); -} + if (line[0] != ':') { // no marker - wrong file format + ELOG("Wrong file format - no marker\n"); + res = -1; + break; + } -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_f0(stlink_t *sl, - uint32_t *option_byte) { - DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_OBR); - return stlink_read_debug32(sl, FLASH_OBR, option_byte); -} + size_t l = strlen(line); -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register1_f7(stlink_t *sl, - uint32_t *option_byte) { - DLOG("@@@@ Read option control register 1 byte from %#10x\n", - FLASH_F7_OPTCR1); - return stlink_read_debug32(sl, FLASH_F7_OPTCR1, option_byte); -} + while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r')) { + --l; + } // trim EoL -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t *option_byte) { - DLOG("@@@@ Read option byte boot address\n"); - return stlink_read_option_control_register1_f7(sl, option_byte); -} + if ((l < 11) || + (l == + (sizeof(line) - 1))) { // line too short or long - wrong file format + ELOG("Wrong file format - wrong line length\n"); + res = -1; + break; + } -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - * - * Since multiple bytes can be read, we read and print all but one here - * and then return the last one just like other devices - */ -int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t *option_byte) { - int err = -1; - for (uint32_t counter = 0; counter < (sl->option_size / 4 - 1); counter++) { - err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), - option_byte); - if (err == -1) { - return err; - } else { - printf("%08x\n", *option_byte); - } - } + uint8_t chksum = 0; // check sum - return stlink_read_debug32( - sl, - sl->option_base + (uint32_t)(sl->option_size / 4 - 1) * sizeof(uint32_t), - option_byte); -} + for (size_t i = 1; i < l; i += 2) { + chksum += stlink_parse_hex(line + i); + } -/** - * Read first option bytes - * @param sl - * @param option_byte option value - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte) { - DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); - return stlink_read_debug32(sl, sl->option_base, option_byte); -} + if (chksum != 0) { + ELOG("Wrong file format - checksum mismatch\n"); + res = -1; + break; + } -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -// int stlink_read_option_bytes_boot_add_generic(stlink_t *sl, uint32_t* -// option_byte) { -// DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); -// return stlink_read_debug32(sl, sl->option_base, option_byte); -//} + uint8_t reclen = stlink_parse_hex(line + 1); -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -// int stlink_read_option_control_register_generic(stlink_t *sl, uint32_t* -// option_byte) { -// DLOG("@@@@ Read option control register byte from %#10x\n", -// sl->option_base); return stlink_read_debug32(sl, sl->option_base, -// option_byte); -//} + if (((uint32_t)reclen + 5) * 2 + 1 != l) { + ELOG("Wrong file format - record length mismatch\n"); + res = -1; + break; + } -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -// int stlink_read_option_control_register1_generic(stlink_t *sl, uint32_t* -// option_byte) { -// DLOG("@@@@ Read option control register 1 byte from %#10x\n", -// sl->option_base); return stlink_read_debug32(sl, sl->option_base, -// option_byte); -//} + uint16_t offset = ((uint16_t)stlink_parse_hex(line + 3) << 8) | + ((uint16_t)stlink_parse_hex(line + 5)); + uint8_t rectype = stlink_parse_hex(line + 7); -/** - * Read option bytes - * @param sl - * @param option_byte option value - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); - return (-1); - } + switch (rectype) { + case 0: /* Data */ + if (scan == 0) { + uint32_t b = lba + offset; + uint32_t e = b + reclen - 1; - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F2: - return stlink_read_option_bytes_f2(sl, option_byte); - case STLINK_CHIPID_STM32_F4: - case STLINK_CHIPID_STM32_F446: - return stlink_read_option_bytes_f4(sl, option_byte); - case STLINK_CHIPID_STM32_F76xxx: - return stlink_read_option_bytes_f7(sl, option_byte); - case STLINK_CHIPID_STM32_G0_CAT1: - case STLINK_CHIPID_STM32_G0_CAT2: - case STLINK_CHIPID_STM32_G4_CAT2: - case STLINK_CHIPID_STM32_G4_CAT3: - return stlink_read_option_bytes_Gx(sl, option_byte); - default: - return stlink_read_option_bytes_generic(sl, option_byte); - } -} + if (b < *begin) { + *begin = b; + } -/** - * Read option bytes - * @param sl - * @param option_byte option value - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { - if (sl->option_base == 0) { - ELOG("Option bytes boot address read is currently not supported for " - "connected chip\n"); - return -1; - } + if (e > end) { + end = e; + } + } else { + for (uint8_t i = 0; i < reclen; ++i) { + uint8_t b = stlink_parse_hex(line + 9 + i * 2); + uint32_t addr = lba + offset + i; - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: - return stlink_read_option_bytes_boot_add_f7(sl, option_byte); - default: - return -1; - // return stlink_read_option_bytes_boot_add_generic(sl, option_byte); - } -} + if (addr >= *begin && addr <= end) { + data[addr - *begin] = b; + } + } + } + break; + case 1: /* EoF */ + eof_found = true; + break; + case 2: /* Extended Segment Address, unexpected */ + res = -1; + break; + case 3: /* Start Segment Address, unexpected */ + res = -1; + break; + case 4: /* Extended Linear Address */ + if (reclen == 2) { + lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | + ((uint32_t)stlink_parse_hex(line + 11) << 16); + } else { + ELOG("Wrong file format - wrong LBA length\n"); + res = -1; + } + break; + case 5: /* Start Linear Address - expected, but ignore */ + break; + default: + ELOG("Wrong file format - unexpected record type %d\n", rectype); + res = -1; + } -/** - * Read option bytes - * @param sl - * @param option_byte option value - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); - return -1; - } + if (res != 0) { + break; + } + } - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - return stlink_read_option_control_register_f0(sl, option_byte); - case STLINK_FLASH_TYPE_F7: - return stlink_read_option_control_register_f7(sl, option_byte); - default: - return -1; + fclose(file); } -} -/** - * Read option bytes - * @param sl - * @param option_byte option value - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register1_32(stlink_t *sl, - uint32_t *option_byte) { - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); - return -1; + if (res == 0) { + *mem = data; + } else { + free(data); } - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: - return stlink_read_option_control_register1_f7(sl, option_byte); - default: - return -1; - // return stlink_read_option_control_register1_generic(sl, option_byte); + return (res); +} +// 280 +uint8_t stlink_get_erased_pattern(stlink_t *sl) { + if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + return (0x00); + } else { + return (0xff); } } +// 322 +int stlink_target_connect(stlink_t *sl, enum connect_type connect) { + if (connect == CONNECT_UNDER_RESET) { + stlink_enter_swd_mode(sl); -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { - WLOG("About to write option byte %#10x to %#10x.\n", option_byte, - sl->option_base); - return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *)&option_byte, - 4); -} + stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); -/** - * Write option bytes - * @param sl - * @param addr of the memory mapped option bytes - * @param base option bytes to write - * @return 0 on success, -ve on failure. - */ -int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, - uint32_t len) { - int ret = -1; + // try to halt the core before reset + // this is useful if the NRST pin is not connected + sl->backend->force_debug(sl); - if (sl->option_base == 0) { - ELOG( - "Option bytes writing is currently not supported for connected chip\n"); - return (-1); + // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) + usleep(20); + + stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH); + + // try to halt the core after reset + unsigned timeout = time_ms() + 10; + while (time_ms() < timeout) { + sl->backend->force_debug(sl); + usleep(100); + } + + // check NRST connection + uint32_t dhcsr = 0; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + WLOG("NRST is not connected\n"); + } + + // addition soft reset for halt before the first instruction + stlink_soft_reset(sl, 1 /* halt on reset */); } - if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { - ELOG("Option bytes start address out of Option bytes range\n"); - return (-1); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE && + stlink_enter_swd_mode(sl)) { + printf("Failed to enter SWD mode\n"); + return -1; } - if (addr + len > sl->option_base + sl->option_size) { - ELOG("Option bytes data too long\n"); - return (-1); + if (connect == CONNECT_NORMAL) { + stlink_reset(sl, RESET_AUTO); } - wait_flash_busy(sl); + return stlink_load_device_params(sl); +} - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it " - "again!\n"); - return (-1); - } +// End of delegates.... functions below are private to this module +// same as above with entrypoint. - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return (-1); - } +static void stop_wdg_in_debug(stlink_t *sl) { + uint32_t dbgmcu_cr; + uint32_t set; + uint32_t value; switch (sl->flash_type) { case STLINK_FLASH_TYPE_F0: case STLINK_FLASH_TYPE_F1_XL: - ret = stlink_write_option_bytes_f0(sl, base, addr, len); + case STLINK_FLASH_TYPE_G4: + dbgmcu_cr = STM32F0_DBGMCU_CR; + set = (1 << STM32F0_DBGMCU_CR_IWDG_STOP) | + (1 << STM32F0_DBGMCU_CR_WWDG_STOP); break; case STLINK_FLASH_TYPE_F4: - ret = stlink_write_option_bytes_f4(sl, base, addr, len); - break; case STLINK_FLASH_TYPE_F7: - ret = stlink_write_option_bytes_f7(sl, base, addr, len); - break; - case STLINK_FLASH_TYPE_L0: - ret = stlink_write_option_bytes_l0(sl, base, addr, len); - break; case STLINK_FLASH_TYPE_L4: - ret = stlink_write_option_bytes_l4(sl, base, addr, len); + dbgmcu_cr = STM32F4_DBGMCU_APB1FZR1; + set = (1 << STM32F4_DBGMCU_APB1FZR1_IWDG_STOP) | + (1 << STM32F4_DBGMCU_APB1FZR1_WWDG_STOP); break; + case STLINK_FLASH_TYPE_L0: case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - ret = stlink_write_option_bytes_gx(sl, base, addr, len); + dbgmcu_cr = STM32L0_DBGMCU_APB1_FZ; + set = (1 << STM32L0_DBGMCU_APB1_FZ_IWDG_STOP) | + (1 << STM32L0_DBGMCU_APB1_FZ_WWDG_STOP); break; case STLINK_FLASH_TYPE_H7: - ret = stlink_write_option_bytes_h7(sl, base, addr, len); + dbgmcu_cr = STM32H7_DBGMCU_APB1HFZ; + set = (1 << STM32H7_DBGMCU_APB1HFZ_IWDG_STOP); break; - default: - ELOG("Option bytes writing is currently not implemented for connected " - "chip\n"); + case STLINK_FLASH_TYPE_WB: + dbgmcu_cr = STM32WB_DBGMCU_APB1FZR1; + set = (1 << STM32WB_DBGMCU_APB1FZR1_IWDG_STOP) | + (1 << STM32WB_DBGMCU_APB1FZR1_WWDG_STOP); break; + default: + return; } - if (ret) { - ELOG("Flash option write failed!\n"); - } else { - ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + if (!stlink_read_debug32(sl, dbgmcu_cr, &value)) { + stlink_write_debug32(sl, dbgmcu_cr, value | set); } +} - /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); - - return ret; +int stlink_jtag_reset(stlink_t *sl, int value) { + DLOG("*** stlink_jtag_reset %d ***\n", value); + return (sl->backend->jtag_reset(sl, value)); } -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -static int -stlink_write_option_control_register_f7(stlink_t *sl, - uint32_t option_control_register) { - int ret = 0; +int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { + int ret; + unsigned timeout; + uint32_t dhcsr, dfsr; + + DLOG("*** stlink_soft_reset %s***\n", halt_on_reset ? "(halt) " : ""); + + // halt core and enable debugging (if not already done) + // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_DEBUGEN); - // Clear errors - clear_flash_error(sl); + // enable Halt on reset by set VC_CORERESET and TRCENA (DDI0337E, p. 10-10) + if (halt_on_reset) { + stlink_write_debug32( + sl, STLINK_REG_CM3_DEMCR, + STLINK_REG_CM3_DEMCR_TRCENA | STLINK_REG_CM3_DEMCR_VC_HARDERR | + STLINK_REG_CM3_DEMCR_VC_BUSERR | STLINK_REG_CM3_DEMCR_VC_CORERESET); - ILOG("Asked to write option control register 1 %#10x to %#010x.\n", - option_control_register, FLASH_F7_OPTCR); + // clear VCATCH in the DFSR register + stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_VCATCH); + } else { + stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, + STLINK_REG_CM3_DEMCR_TRCENA | + STLINK_REG_CM3_DEMCR_VC_HARDERR | + STLINK_REG_CM3_DEMCR_VC_BUSERR); + } - /* write option byte, ensuring we dont lock opt, and set strt bit */ - stlink_write_debug32(sl, FLASH_F7_OPTCR, - (option_control_register & ~(1 << FLASH_F7_OPTCR_LOCK)) | - (1 << FLASH_F7_OPTCR_START)); + // clear S_RESET_ST in the DHCSR register + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - wait_flash_busy(sl); + // soft reset (core reset) by SYSRESETREQ (DDI0337E, p. 8-23) + ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, + STLINK_REG_AIRCR_VECTKEY | + STLINK_REG_AIRCR_SYSRESETREQ); + if (ret) { + ELOG("Soft reset failed: error write to AIRCR\n"); + return (ret); + } - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, - FLASH_F7_OPTCR); + // waiting for a reset within 500ms + // DDI0337E, p. 10-4, Debug Halting Control and Status Register + timeout = time_ms() + 500; + while (time_ms() < timeout) { + // DDI0337E, p. 10-4, Debug Halting Control and Status Register + dhcsr = STLINK_REG_DHCSR_S_RESET_ST; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + if (halt_on_reset) { + // waiting halt by the SYSRESETREQ exception + // DDI0403E, p. C1-699, Debug Fault Status Register + dfsr = 0; + stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); + if ((dfsr & STLINK_REG_DFSR_VCATCH) == 0) { + continue; + } + } + timeout = 0; + break; + } + } - return ret; -} + // reset DFSR register. DFSR is power-on reset only (DDI0337H, p. 7-5) + stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_CLEAR); + if (timeout) { + ELOG("Soft reset failed: timeout\n"); + return (-1); + } + return (0); +} /** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. + * Decode the version bits, originally from -sg, verified with usb + * @param sl stlink context, assumed to contain valid data in the buffer + * @param slv output parsed version object */ -static int -stlink_write_option_control_register_f0(stlink_t *sl, - uint32_t option_control_register) { - int ret = 0; - uint16_t opt_val[8]; - unsigned protection, optiondata; - uint16_t user_options, user_data, rdp; - unsigned option_offset, user_data_offset; +void _parse_version(stlink_t *sl, stlink_version_t *slv) { + sl->version.flags = 0; + + if (sl->version.stlink_v < 3) { + uint32_t b0 = sl->q_buf[0]; // lsb + uint32_t b1 = sl->q_buf[1]; + uint32_t b2 = sl->q_buf[2]; + uint32_t b3 = sl->q_buf[3]; + uint32_t b4 = sl->q_buf[4]; + uint32_t b5 = sl->q_buf[5]; // msb - ILOG("Asked to write option control register %#10x to %#010x.\n", - option_control_register, FLASH_OBR); + // b0 b1 || b2 b3 | b4 b5 + // 4b | 6b | 6b || 2B | 2B + // stlink_v | jtag_v | swim_v || st_vid | stlink_pid - /* Clear errors */ - clear_flash_error(sl); + slv->stlink_v = (b0 & 0xf0) >> 4; + slv->jtag_v = ((b0 & 0x0f) << 2) | ((b1 & 0xc0) >> 6); + slv->swim_v = b1 & 0x3f; + slv->st_vid = (b3 << 8) | b2; + slv->stlink_pid = (b5 << 8) | b4; - /* Retrieve current values */ - ret = stlink_read_debug32(sl, FLASH_OBR, &optiondata); - if (ret) { - return ret; + // ST-LINK/V1 from J11 switch to api-v2 (and support SWD) + if (slv->stlink_v == 1) { + slv->jtag_api = + slv->jtag_v > 11 ? STLINK_JTAG_API_V2 : STLINK_JTAG_API_V1; + } else { + slv->jtag_api = STLINK_JTAG_API_V2; + + // preferred API to get last R/W status from J15 + if (sl->version.jtag_v >= 15) { + sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; + } + + if (sl->version.jtag_v >= 13) { + sl->version.flags |= STLINK_F_HAS_TRACE; + sl->max_trace_freq = STLINK_V2_MAX_TRACE_FREQUENCY; + } + } + } else { + // V3 uses different version format, for reference see OpenOCD source + // (that was written from docs available from ST under NDA): + // https://github.com/ntfreak/openocd/blob/a6dacdff58ef36fcdac00c53ec27f19de1fbce0d/src/jtag/drivers/stlink_usb.c#L965 + slv->stlink_v = sl->q_buf[0]; + slv->swim_v = sl->q_buf[1]; + slv->jtag_v = sl->q_buf[2]; + slv->st_vid = (uint32_t)((sl->q_buf[9] << 8) | sl->q_buf[8]); + slv->stlink_pid = (uint32_t)((sl->q_buf[11] << 8) | sl->q_buf[10]); + slv->jtag_api = STLINK_JTAG_API_V3; + /* preferred API to get last R/W status */ + sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; + sl->version.flags |= STLINK_F_HAS_TRACE; + sl->max_trace_freq = STLINK_V3_MAX_TRACE_FREQUENCY; } - ret = stlink_read_debug32(sl, FLASH_WRPR, &protection); - if (ret) { - return ret; + + return; +} + +void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { + stlink_write_reg(sl, addr, 15); /* pc register */ + stlink_run(sl, RUN_NORMAL); + + while (stlink_is_core_halted(sl)) { + usleep(3000000); } +} - /* Translate OBR value to flash store structure - * F0: RM0091, Option byte description, pp. 75-78 - * F1: PM0075, Option byte description, pp. 19-22 - * F3: RM0316, Option byte description, pp. 85-87 */ - switch(sl->chip_id) - { - case 0x422: /* STM32F30x */ - case 0x432: /* STM32F37x */ - case 0x438: /* STM32F303x6/8 and STM32F328 */ - case 0x446: /* STM32F303xD/E and STM32F398xE */ - case 0x439: /* STM32F302x6/8 */ - case 0x440: /* STM32F05x */ - case 0x444: /* STM32F03x */ - case 0x445: /* STM32F04x */ - case 0x448: /* STM32F07x */ - case 0x442: /* STM32F09x */ - option_offset = 6; - user_data_offset = 16; - rdp = 0x55AA; - break; - default: - option_offset = 0; - user_data_offset = 10; - rdp = 0x5AA5; - break; +/* Limit the block size to compare to 0x1800 as anything larger will stall the + * STLINK2 Maybe STLINK V1 needs smaller value! + */ +int check_file(stlink_t *sl, mapped_file_t *mf, stm32_addr_t addr) { + size_t off; + size_t n_cmp = sl->flash_pgsz; + + if (n_cmp > 0x1800) { + n_cmp = 0x1800; } - user_options = (option_control_register >> option_offset >> 2) & 0xFFFF; - user_data = (option_control_register >> user_data_offset) & 0xFFFF; + for (off = 0; off < mf->len; off += n_cmp) { + size_t aligned_size; + + size_t cmp_size = n_cmp; // adjust last page size -#define VAL_WITH_COMPLEMENT(v) (uint16_t)(((v)&0xFF) | (((~(v))<<8)&0xFF00)) + if ((off + n_cmp) > mf->len) { + cmp_size = mf->len - off; + } - opt_val[0] = (option_control_register & (1 << 1/*OPT_READOUT*/)) ? 0xFFFF : rdp; - opt_val[1] = VAL_WITH_COMPLEMENT(user_options); - opt_val[2] = VAL_WITH_COMPLEMENT(user_data); - opt_val[3] = VAL_WITH_COMPLEMENT(user_data >> 8); - opt_val[4] = VAL_WITH_COMPLEMENT(protection); - opt_val[5] = VAL_WITH_COMPLEMENT(protection >> 8); - opt_val[6] = VAL_WITH_COMPLEMENT(protection >> 16); - opt_val[7] = VAL_WITH_COMPLEMENT(protection >> 24); + aligned_size = cmp_size; -#undef VAL_WITH_COMPLEMENT + if (aligned_size & (4 - 1)) { + aligned_size = (cmp_size + 4) & ~(4 - 1); + } - /* Write bytes and check errors */ - ret = stlink_write_option_bytes_f0(sl, (uint8_t*)opt_val, STM32_F0_OPTION_BYTES_BASE, sizeof(opt_val)); - if (ret) - return ret; + stlink_read_mem32(sl, addr + (uint32_t)off, (uint16_t)aligned_size); - ret = check_flash_error(sl); - if (!ret) { - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, - FLASH_OBR); + if (memcmp(sl->q_buf, mf->base + off, cmp_size)) { + return (-1); + } } - return ret; + return (0); } -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -static int -stlink_write_option_control_register1_f7(stlink_t *sl, - uint32_t option_control_register1) { - int ret = 0; - - // Clear errors - clear_flash_error(sl); - - ILOG("Asked to write option control register 1 %#010x to %#010x.\n", - option_control_register1, FLASH_F7_OPTCR1); +void md5_calculate(mapped_file_t *mf) { + // calculate md5 checksum of given binary file + Md5Context md5Context; + MD5_HASH md5Hash; + Md5Initialise(&md5Context); + Md5Update(&md5Context, mf->base, (uint32_t)mf->len); + Md5Finalise(&md5Context, &md5Hash); + printf("md5 checksum: "); - /* write option byte, ensuring we dont lock opt, and set strt bit */ - uint32_t current_control_register_value; - stlink_read_debug32(sl, FLASH_F7_OPTCR, ¤t_control_register_value); + for (int i = 0; i < (int)sizeof(md5Hash); i++) { + printf("%x", md5Hash.bytes[i]); + } - /* write option byte */ - stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_control_register1); - stlink_write_debug32( - sl, FLASH_F7_OPTCR, - (current_control_register_value & ~(1 << FLASH_F7_OPTCR_LOCK)) | - (1 << FLASH_F7_OPTCR_START)); + printf(", "); +} - wait_flash_busy(sl); +void stlink_checksum(mapped_file_t *mp) { + /* checksum that backward compatible with official ST tools */ + uint32_t sum = 0; + uint8_t *mp_byte = (uint8_t *)mp->base; - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register1, - FLASH_F7_OPTCR1); + for (size_t i = 0; i < mp->len; ++i) { + sum += mp_byte[i]; + } - return ret; + printf("stlink checksum: 0x%08x\n", sum); } -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -static int -stlink_write_option_bytes_boot_add_f7(stlink_t *sl, - uint32_t option_byte_boot_add) { - ILOG("Asked to write option byte boot add %#010x.\n", option_byte_boot_add); - return stlink_write_option_control_register1_f7(sl, option_byte_boot_add); +void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { + unsigned int val; + // set PC to the reset routine + stlink_read_debug32(sl, addr + 4, &val); + stlink_write_reg(sl, val, 15); + stlink_run(sl, RUN_NORMAL); } -/** - * Write option bytes - * @param sl - * @param option bytes boot address to write - * @return 0 on success, -ve on failure. - */ -int stlink_write_option_bytes_boot_add32(stlink_t *sl, - uint32_t option_bytes_boot_add) { - int ret = -1; - - wait_flash_busy(sl); +static int stlink_read(stlink_t *sl, stm32_addr_t addr, size_t size, + save_block_fn fn, void *fn_arg) { - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it " - "again!\n"); - return -1; - } + int error = -1; - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; + if (size < 1) { + size = sl->flash_size; } - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: - ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); - break; - default: - ELOG("Option bytes boot address writing is currently not implemented for " - "connected chip\n"); - break; + if (size > sl->flash_size) { + size = sl->flash_size; } - if (ret) - ELOG("Flash option write failed!\n"); - else - ILOG("Wrote option bytes boot address %#010x!\n", option_bytes_boot_add); + size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; - /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); + for (size_t off = 0; off < size; off += cmp_size) { + size_t aligned_size; - return ret; -} + // adjust last page size + if ((off + cmp_size) > size) { + cmp_size = size - off; + } -/** - * Write option bytes - * @param sl - * @param option bytes boot address to write - * @return 0 on success, -ve on failure. - */ -int stlink_write_option_control_register32(stlink_t *sl, - uint32_t option_control_register) { - int ret = -1; + aligned_size = cmp_size; - wait_flash_busy(sl); + if (aligned_size & (4 - 1)) { + aligned_size = (cmp_size + 4) & ~(4 - 1); + } - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it " - "again!\n"); - return -1; - } + stlink_read_mem32(sl, addr + (uint32_t)off, (uint16_t)aligned_size); - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; + if (!fn(fn_arg, sl->q_buf, aligned_size)) { + goto on_error; + } } - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - ret = stlink_write_option_control_register_f0(sl, option_control_register); - break; - case STLINK_FLASH_TYPE_F7: - ret = stlink_write_option_control_register_f7(sl, option_control_register); - break; - default: - ELOG("Option control register writing is currently not implemented for " - "connected chip\n"); - break; - } + error = 0; // success - if (ret) - ELOG("Flash option write failed!\n"); - else - ILOG("Wrote option control register %#010x!\n", option_control_register); +on_error: + return (error); +} - /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); +static bool stlink_fread_worker(void *arg, uint8_t *block, ssize_t len) { + struct stlink_fread_worker_arg *the_arg = + (struct stlink_fread_worker_arg *)arg; - return ret; + if (write(the_arg->fd, block, len) != len) { + fprintf(stderr, "write() != aligned_size\n"); + return (false); + } else { + return (true); + } } -/** - * Write option bytes - * @param sl - * @param option bytes boot address to write - * @return 0 on success, -ve on failure. - */ -int stlink_write_option_control_register1_32( - stlink_t *sl, uint32_t option_control_register1) { - int ret = -1; +// TODO: length not checked +static uint8_t stlink_parse_hex(const char *hex) { + uint8_t d[2]; - wait_flash_busy(sl); + for (int i = 0; i < 2; ++i) { + char c = *(hex + i); - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it " - "again!\n"); - return -1; + if (c >= '0' && c <= '9') { + d[i] = c - '0'; + } else if (c >= 'A' && c <= 'F') { + d[i] = c - 'A' + 10; + } else if (c >= 'a' && c <= 'f') { + d[i] = c - 'a' + 10; + } else { + return (0); // error + } } - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; - } + return ((d[0] << 4) | (d[1])); +} - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: - ret = - stlink_write_option_control_register1_f7(sl, option_control_register1); - break; - default: - ELOG("Option control register 1 writing is currently not implemented for " - "connected chip\n"); - break; +static bool +stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg *the_arg) { + uint32_t addr = the_arg->addr; + uint8_t sum = 2 + 4 + (uint8_t)((addr & 0xFF000000) >> 24) + + (uint8_t)((addr & 0x00FF0000) >> 16); + + if (17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", + (addr & 0xFFFF0000) >> 16, (uint8_t)(0x100 - sum))) { + return (false); } - if (ret) - ELOG("Flash option write failed!\n"); - else - ILOG("Wrote option control register 1 %#010x!\n", option_control_register1); + the_arg->lba = (addr & 0xFFFF0000); + return (true); +} - lock_flash_option(sl); - lock_flash(sl); +static bool +stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg *the_arg) { + uint8_t count = the_arg->buf_pos; - return (ret); -} + if (count == 0) { + return (true); + } -/** - * Write the given binary file with option bytes - * @param sl - * @param path readable file path, should be binary image - * @param addr of the memory mapped option bytes - * @return 0 on success, -ve on failure. - */ -int stlink_fwrite_option_bytes(stlink_t *sl, const char *path, - stm32_addr_t addr) { - /* Write the file in flash at addr */ - int err; - mapped_file_t mf = MAPPED_FILE_INITIALIZER; + uint32_t addr = the_arg->addr; - if (map_file(&mf, path) == -1) { - ELOG("map_file() == -1\n"); - return (-1); + if (the_arg->lba != (addr & 0xFFFF0000)) { // segment changed + if (!stlink_fread_ihex_newsegment(the_arg)) { + return (false); + } } - printf("file %s ", path); - md5_calculate(&mf); - stlink_checksum(&mf); + uint8_t sum = count + (uint8_t)((addr & 0x0000FF00) >> 8) + + (uint8_t)(addr & 0x000000FF); - err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t)mf.len); - stlink_fwrite_finalize(sl, addr); - unmap_file(&mf); + if (9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) { + return (false); + } - return (err); -} + for (uint8_t i = 0; i < count; ++i) { + uint8_t b = the_arg->buf[i]; + sum += b; -int stlink_target_connect(stlink_t *sl, enum connect_type connect) { - if (connect == CONNECT_UNDER_RESET) { - stlink_enter_swd_mode(sl); + if (2 != fprintf(the_arg->file, "%02X", b)) { + return (false); + } + } - stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); + if (4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) { + return (false); + } - // try to halt the core before reset - // this is useful if the NRST pin is not connected - sl->backend->force_debug(sl); + the_arg->addr += count; + the_arg->buf_pos = 0; - // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) - usleep(20); + return (true); +} - stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH); +static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg *the_arg, + int fd, stm32_addr_t addr) { + the_arg->file = fdopen(fd, "w"); + the_arg->addr = addr; + the_arg->lba = 0; + the_arg->buf_pos = 0; - // try to halt the core after reset - unsigned timeout = time_ms() + 10; - while (time_ms() < timeout) { - sl->backend->force_debug(sl); - usleep(100); - } + return (the_arg->file != NULL); +} - // check NRST connection - uint32_t dhcsr = 0; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { - WLOG("NRST is not connected\n"); +static bool stlink_fread_ihex_worker(void *arg, uint8_t *block, ssize_t len) { + struct stlink_fread_ihex_worker_arg *the_arg = + (struct stlink_fread_ihex_worker_arg *)arg; + + for (ssize_t i = 0; i < len; ++i) { + if (the_arg->buf_pos == sizeof(the_arg->buf)) { // line is full + if (!stlink_fread_ihex_writeline(the_arg)) { + return (false); + } } - // addition soft reset for halt before the first instruction - stlink_soft_reset(sl, 1 /* halt on reset */); + the_arg->buf[the_arg->buf_pos++] = block[i]; } - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE && - stlink_enter_swd_mode(sl)) { - printf("Failed to enter SWD mode\n"); - return -1; + return (true); +} + +static bool +stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg *the_arg) { + if (!stlink_fread_ihex_writeline(the_arg)) { + return (false); } - if (connect == CONNECT_NORMAL) { - stlink_reset(sl, RESET_AUTO); + // FIXME: do we need the Start Linear Address? + + if (13 != fprintf(the_arg->file, ":00000001FF\r\n")) { // EoF + return (false); } - return stlink_load_device_params(sl); + return (0 == fclose(the_arg->file)); } diff --git a/src/common_flash.c b/src/common_flash.c index 4f7f46257..1f438c74f 100644 --- a/src/common_flash.c +++ b/src/common_flash.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "calculate.h" #include "common_flash.h" #include "map_file.h" diff --git a/src/flashloader.c b/src/flashloader.c index df14e506c..f84e16ef0 100644 --- a/src/flashloader.c +++ b/src/flashloader.c @@ -1,4 +1,5 @@ #include +#include #include #include "common_flash.h" diff --git a/src/map_file.c b/src/map_file.c index 5282fae27..cb7d4f525 100644 --- a/src/map_file.c +++ b/src/map_file.c @@ -1,10 +1,17 @@ #include #include #include +#include // for close #include +#include + #include "map_file.h" +#ifndef O_BINARY +#define O_BINARY 0 +#endif + #ifndef MAX_FILE_SIZE #define MAX_FILE_SIZE (1<<20) // 1 GB max file size #endif diff --git a/src/option.c b/src/option.c index b70f7a533..ed9ee4f39 100644 --- a/src/option.c +++ b/src/option.c @@ -1,4 +1,5 @@ #include +#include #include #include "common_flash.h" #include "map_file.h" diff --git a/src/read_write.c b/src/read_write.c index adcda6f3b..efaa5a25f 100644 --- a/src/read_write.c +++ b/src/read_write.c @@ -1,4 +1,5 @@ #include +#include #include // Endianness From 8d96e769f32d1c85be913f77e6aab4b1d84b80b1 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 20 Jan 2022 23:19:10 +0100 Subject: [PATCH 1292/1435] Updated device parametres - Human-readable FLASH_TYPE in .chip files - Added enum for STM32_CORE_IDs --- config/chips/F03x.chip | 2 +- config/chips/F04x.chip | 2 +- config/chips/F05x.chip | 2 +- config/chips/F07x.chip | 2 +- config/chips/F09x.chip | 2 +- config/chips/F1xx_CL.chip | 2 +- config/chips/F1xx_HD.chip | 2 +- config/chips/F1xx_LD.chip | 2 +- config/chips/F1xx_MD.chip | 2 +- config/chips/F1xx_VL_HD.chip | 2 +- config/chips/F1xx_VL_MD_LD.chip | 2 +- config/chips/F1xx_XLD.chip | 2 +- config/chips/F2xx.chip | 2 +- config/chips/F301_F302_F318.chip | 2 +- config/chips/F302_F303_F358.chip | 2 +- config/chips/F302_F303_F398_HD.chip | 2 +- config/chips/F303_F328_F334.chip | 2 +- config/chips/F37x.chip | 2 +- config/chips/F401xB_xC.chip | 2 +- config/chips/F401xD_xE.chip | 2 +- config/chips/F410.chip | 2 +- config/chips/F411xC_xE.chip | 2 +- config/chips/F412.chip | 2 +- config/chips/F413_F423.chip | 2 +- config/chips/F42x_F43x.chip | 2 +- config/chips/F446.chip | 2 +- config/chips/F46x_F47x.chip | 2 +- config/chips/F4x5_F4x7.chip | 2 +- config/chips/F72x_F73x.chip | 2 +- config/chips/F74x_F75x.chip | 2 +- config/chips/F76x_F77x.chip | 2 +- config/chips/G03x_G04x.chip | 2 +- config/chips/G05x_G06x.chip | 2 +- config/chips/G07x_G08x.chip | 2 +- config/chips/G0Bx_G0Cx.chip | 2 +- config/chips/G43x_G44x.chip | 2 +- config/chips/G47x_G48x.chip | 2 +- config/chips/G49x_G4Ax.chip | 2 +- config/chips/H72x_H73x.chip | 2 +- config/chips/H74x_H75x.chip | 2 +- config/chips/H7Ax_H7Bx.chip | 2 +- config/chips/L0xxx_Cat_1.chip | 2 +- config/chips/L0xxx_Cat_2.chip | 2 +- config/chips/L0xxx_Cat_3.chip | 2 +- config/chips/L0xxx_Cat_5.chip | 2 +- config/chips/L1xx_Cat_1.chip | 2 +- config/chips/L1xx_Cat_2.chip | 2 +- config/chips/L1xx_Cat_3.chip | 2 +- config/chips/L1xx_Cat_4.chip | 2 +- config/chips/L1xx_Cat_5.chip | 2 +- config/chips/L41x_L42x.chip | 2 +- config/chips/L43x_L44x.chip | 2 +- config/chips/L45x_L46x.chip | 2 +- config/chips/L47x_L48x.chip | 2 +- config/chips/L496x_L4A6x.chip | 2 +- config/chips/L4Px.chip | 2 +- config/chips/L4Rx.chip | 2 +- config/chips/{L5x5.chip => L5x5.chip.txt} | 2 +- config/chips/{U5x5.chip => U5x5.chip.txt} | 2 +- config/chips/WBx0_WBx5.chip | 2 +- config/chips/WLx5.chip | 2 +- config/chips/unknown_device.chip | 2 +- inc/stm32.h | 49 +++++++----------- src/stlink-lib/chipid.c | 63 +++++++++++++++-------- 64 files changed, 123 insertions(+), 113 deletions(-) rename config/chips/{L5x5.chip => L5x5.chip.txt} (85%) rename config/chips/{U5x5.chip => U5x5.chip.txt} (85%) diff --git a/config/chips/F03x.chip b/config/chips/F03x.chip index c0a6e5200..84543dc23 100644 --- a/config/chips/F03x.chip +++ b/config/chips/F03x.chip @@ -3,7 +3,7 @@ dev_type STM32F03x ref_manual_id 0091 chip_id 0x444 // STM32_CHIPID_F0xx_SMALL -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x400 // 1 KB sram_size 0x1000 // 4 KB diff --git a/config/chips/F04x.chip b/config/chips/F04x.chip index 9b2ee5586..322e61e51 100644 --- a/config/chips/F04x.chip +++ b/config/chips/F04x.chip @@ -3,7 +3,7 @@ dev_type STM32F04x ref_manual_id 0091 chip_id 0x445 // STM32_CHIPID_F04 -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x400 // 1 KB sram_size 0x1800 // 6 KB diff --git a/config/chips/F05x.chip b/config/chips/F05x.chip index c32ba0b46..3ba9566eb 100644 --- a/config/chips/F05x.chip +++ b/config/chips/F05x.chip @@ -3,7 +3,7 @@ dev_type STM32F05x ref_manual_id 0091 chip_id 0x440 // STM32_CHIPID_F0 -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x400 // 1 KB sram_size 0x2000 // 8 KB diff --git a/config/chips/F07x.chip b/config/chips/F07x.chip index 5ba832058..4b1465ca6 100644 --- a/config/chips/F07x.chip +++ b/config/chips/F07x.chip @@ -3,7 +3,7 @@ dev_type STM32F07x ref_manual_id 0091 chip_id 0x448 // STM32_CHIPID_F0_CAN -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB sram_size 0x4000 // 16 KB diff --git a/config/chips/F09x.chip b/config/chips/F09x.chip index ca987123d..eb6dec428 100644 --- a/config/chips/F09x.chip +++ b/config/chips/F09x.chip @@ -3,7 +3,7 @@ dev_type STM32F09x ref_manual_id 0091 chip_id 0x442 // STM32_CHIPID_F09x -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB sram_size 0x8000 // 32 KB diff --git a/config/chips/F1xx_CL.chip b/config/chips/F1xx_CL.chip index 0f56362f0..d774412e1 100644 --- a/config/chips/F1xx_CL.chip +++ b/config/chips/F1xx_CL.chip @@ -3,7 +3,7 @@ dev_type STM32F1xx_CL ref_manual_id 0008 chip_id 0x418 // STM32_CHIPID_F1_CONN -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB sram_size 0x10000 // 64 KB diff --git a/config/chips/F1xx_HD.chip b/config/chips/F1xx_HD.chip index 2af8582e6..f454e2a1c 100644 --- a/config/chips/F1xx_HD.chip +++ b/config/chips/F1xx_HD.chip @@ -3,7 +3,7 @@ dev_type F1xx_HD ref_manual_id 0008 chip_id 0x414 // STM32_CHIPID_F1_HD -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB sram_size 0x10000 // 64 KB diff --git a/config/chips/F1xx_LD.chip b/config/chips/F1xx_LD.chip index ffd34fd4a..50f115148 100644 --- a/config/chips/F1xx_LD.chip +++ b/config/chips/F1xx_LD.chip @@ -3,7 +3,7 @@ dev_type STM32F1xx_LD ref_manual_id 0008 chip_id 0x412 // STM32_CHIPID_F1_LD -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x400 // 1 KB sram_size 0x2800 // 10 KB diff --git a/config/chips/F1xx_MD.chip b/config/chips/F1xx_MD.chip index f27a7a062..17af311c1 100644 --- a/config/chips/F1xx_MD.chip +++ b/config/chips/F1xx_MD.chip @@ -3,7 +3,7 @@ dev_type STM32F1xx_MD ref_manual_id 0008 chip_id 0x410 // STM32_CHIPID_F1_MD -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x400 // 1 KB sram_size 0x5000 // 20 KB diff --git a/config/chips/F1xx_VL_HD.chip b/config/chips/F1xx_VL_HD.chip index 4f2566949..c77e013ce 100644 --- a/config/chips/F1xx_VL_HD.chip +++ b/config/chips/F1xx_VL_HD.chip @@ -3,7 +3,7 @@ dev_type STM32F1xx_VL_HD ref_manual_id 0041 chip_id 0x428 // STM32_CHIPID_F1_VL_HD -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB sram_size 0x8000 // 32 KB diff --git a/config/chips/F1xx_VL_MD_LD.chip b/config/chips/F1xx_VL_MD_LD.chip index 1705bc8e3..467fb786f 100644 --- a/config/chips/F1xx_VL_MD_LD.chip +++ b/config/chips/F1xx_VL_MD_LD.chip @@ -3,7 +3,7 @@ dev_type STM32F1xx_VL_MD_LD ref_manual_id 0041 chip_id 0x420 // STM32_CHIPID_F1_VL_MD_LD -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7e0 flash_pagesize 0x400 // 1 KB sram_size 0x2000 // 8 KB /* 0x1000 for low density devices */ diff --git a/config/chips/F1xx_XLD.chip b/config/chips/F1xx_XLD.chip index 37c900f28..622bd9d02 100644 --- a/config/chips/F1xx_XLD.chip +++ b/config/chips/F1xx_XLD.chip @@ -3,7 +3,7 @@ dev_type STM32F1xx_XLD ref_manual_id 0008 chip_id 0x430 // STM32_CHIPID_F1_XLD -flash_type 2 // STM32_FLASH_TYPE_F1_XL +flash_type F1_XL flash_size_reg 0x1ffff7e0 flash_pagesize 0x800 // 2 KB sram_size 0x18000 // 96 KB diff --git a/config/chips/F2xx.chip b/config/chips/F2xx.chip index 314df7d6d..30ea174ee 100644 --- a/config/chips/F2xx.chip +++ b/config/chips/F2xx.chip @@ -3,7 +3,7 @@ dev_type STM32F2xx ref_manual_id 0033 chip_id 0x411 // STM32_CHIPID_F2 -flash_type 3 // STM32_FLASH_TYPE_F2_F4 +flash_type F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x20000 // 128 KB sram_size 0x20000 // 128 KB diff --git a/config/chips/F301_F302_F318.chip b/config/chips/F301_F302_F318.chip index f620364b2..408f1435e 100644 --- a/config/chips/F301_F302_F318.chip +++ b/config/chips/F301_F302_F318.chip @@ -3,7 +3,7 @@ dev_type STM32F301_F302_F318 ref_manual_id 0365 // also RM0366 chip_id 0x439 // STM32_CHIPID_F3xx_SMALL -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB sram_size 0xa000 // 40 KB diff --git a/config/chips/F302_F303_F358.chip b/config/chips/F302_F303_F358.chip index e48370159..08c6dc371 100644 --- a/config/chips/F302_F303_F358.chip +++ b/config/chips/F302_F303_F358.chip @@ -3,7 +3,7 @@ dev_type STM32F302_F303_358 ref_manual_id 0365 // also RM0316 chip_id 0x422 // STM32_CHIPID_F3 -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB sram_size 0xa000 // 40 KB diff --git a/config/chips/F302_F303_F398_HD.chip b/config/chips/F302_F303_F398_HD.chip index 181fdfa72..7b254c486 100644 --- a/config/chips/F302_F303_F398_HD.chip +++ b/config/chips/F302_F303_F398_HD.chip @@ -3,7 +3,7 @@ dev_type STM32F302_F303_F398_HD ref_manual_id 0365 // also RM0316 (Rev 5) chip_id 0x446 // STM32_CHIPID_F303_HD -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB sram_size 0x10000 // 64 KB diff --git a/config/chips/F303_F328_F334.chip b/config/chips/F303_F328_F334.chip index 069de07fb..daf299cea 100644 --- a/config/chips/F303_F328_F334.chip +++ b/config/chips/F303_F328_F334.chip @@ -3,7 +3,7 @@ dev_type STM32F303_F328_F334 ref_manual_id 0364 // also RM0316 chip_id 0x438 // STM32_CHIPID_F334 -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB sram_size 0x3000 // 12 KB diff --git a/config/chips/F37x.chip b/config/chips/F37x.chip index dfe59af0f..ac249f24f 100644 --- a/config/chips/F37x.chip +++ b/config/chips/F37x.chip @@ -3,7 +3,7 @@ dev_type STM32F37x ref_manual_id 0313 chip_id 0x432 // STM32_CHIPID_F37x -flash_type 1 // STM32_FLASH_TYPE_F0_F1_F3 +flash_type F0_F1_F3 flash_size_reg 0x1ffff7cc flash_pagesize 0x800 // 2 KB sram_size 0xa000 // 40 KB diff --git a/config/chips/F401xB_xC.chip b/config/chips/F401xB_xC.chip index d961e82b0..1022f0fe9 100644 --- a/config/chips/F401xB_xC.chip +++ b/config/chips/F401xB_xC.chip @@ -3,7 +3,7 @@ dev_type STM32F401xB_xC ref_manual_id 0368 chip_id 0x423 // STM32_CHIPID_F4_LP -flash_type 3 // STM32_FLASH_TYPE_F2_F4 +flash_type F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x10000 // 64 KB diff --git a/config/chips/F401xD_xE.chip b/config/chips/F401xD_xE.chip index 1b58cb5ad..39748a604 100644 --- a/config/chips/F401xD_xE.chip +++ b/config/chips/F401xD_xE.chip @@ -3,7 +3,7 @@ dev_type STM32F401xD_xE ref_manual_id 0368 chip_id 0x433 // STM32_CHIPID_F4_DE -flash_type 3 // STM32_FLASH_TYPE_F2_F4 +flash_type F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x18000 // 96 KB diff --git a/config/chips/F410.chip b/config/chips/F410.chip index 55dbb749d..5c19450f6 100644 --- a/config/chips/F410.chip +++ b/config/chips/F410.chip @@ -3,7 +3,7 @@ dev_type STM32F410 ref_manual_id 0401 chip_id 0x458 // STM32_CHIPID_F410 -flash_type 3 // STM32_FLASH_TYPE_F2_F4 +flash_type F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x8000 // 32 KB diff --git a/config/chips/F411xC_xE.chip b/config/chips/F411xC_xE.chip index 51081d338..ce93aea26 100644 --- a/config/chips/F411xC_xE.chip +++ b/config/chips/F411xC_xE.chip @@ -3,7 +3,7 @@ dev_type STM32F411xC_xE ref_manual_id 0383 chip_id 0x431 // STM32_CHIPID_F411xx -flash_type 3 // STM32_FLASH_TYPE_F2_F4 +flash_type F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x20000 // 128 KB diff --git a/config/chips/F412.chip b/config/chips/F412.chip index 6e7aefd19..a04268349 100644 --- a/config/chips/F412.chip +++ b/config/chips/F412.chip @@ -3,7 +3,7 @@ dev_type STM32F412 ref_manual_id 0402 chip_id 0x441 // STM32_CHIPID_F412 -flash_type 3 // STM32_FLASH_TYPE_F2_F4 +flash_type F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/F413_F423.chip b/config/chips/F413_F423.chip index 3a865d304..bb5dd5880 100644 --- a/config/chips/F413_F423.chip +++ b/config/chips/F413_F423.chip @@ -3,7 +3,7 @@ dev_type STM32F413_F423 ref_manual_id 0430 // RM0430 (Rev 2) chip_id 0x463 // STM32_CHIPID_F413 -flash_type 3 // STM32_FLASH_TYPE_F2_F4 +flash_type F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x50000 // 320 KB diff --git a/config/chips/F42x_F43x.chip b/config/chips/F42x_F43x.chip index 64f459064..4452780b3 100644 --- a/config/chips/F42x_F43x.chip +++ b/config/chips/F42x_F43x.chip @@ -3,7 +3,7 @@ dev_type STM32F42x_F43x ref_manual_id 0090 // RM0090 (Rev. 2) chip_id 0x463 // STM32_CHIPID_F4_HD -flash_type 3 // STM32_FLASH_TYPE_F2_F4 +flash_type F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/F446.chip b/config/chips/F446.chip index 51ee52517..e4d0bdec2 100644 --- a/config/chips/F446.chip +++ b/config/chips/F446.chip @@ -3,7 +3,7 @@ dev_type STM32F446 ref_manual_id 0390 chip_id 0x421 // STM32_CHIPID_F446 -flash_type 3 // STM32_FLASH_TYPE_F2_F4 +flash_type F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x20000 // 128 KB sram_size 0x20000 // 128 KB diff --git a/config/chips/F46x_F47x.chip b/config/chips/F46x_F47x.chip index 4d3931091..f20715ded 100644 --- a/config/chips/F46x_F47x.chip +++ b/config/chips/F46x_F47x.chip @@ -3,7 +3,7 @@ dev_type STM32F46x_F47x ref_manual_id 0090 // RM0090 (Rev. 2) chip_id 0x434 // STM32_CHIPID_F4_DSI -flash_type 3 // STM32_FLASH_TYPE_F2_F4 +flash_type F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/F4x5_F4x7.chip b/config/chips/F4x5_F4x7.chip index f65281272..586ff0b8f 100644 --- a/config/chips/F4x5_F4x7.chip +++ b/config/chips/F4x5_F4x7.chip @@ -3,7 +3,7 @@ dev_type STM32F4x5_F4x7 ref_manual_id 0090 // RM0090 (Rev. 2) chip_id 0x413 // STM32_CHIPID_F4 -flash_type 3 // STM32_FLASH_TYPE_F2_F4 +flash_type F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB sram_size 0x30000 // 192 KB diff --git a/config/chips/F72x_F73x.chip b/config/chips/F72x_F73x.chip index acd411bed..04af2bb3e 100644 --- a/config/chips/F72x_F73x.chip +++ b/config/chips/F72x_F73x.chip @@ -3,7 +3,7 @@ dev_type STM32F72x_F73x ref_manual_id 0431 chip_id 0x452 // STM32_CHIPID_F72xxx -flash_type 4 // STM32_FLASH_TYPE_F7 +flash_type F7 flash_size_reg 0x1ff07a22 flash_pagesize 0x800 // 2 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/F74x_F75x.chip b/config/chips/F74x_F75x.chip index e081da39d..0664bb2d0 100644 --- a/config/chips/F74x_F75x.chip +++ b/config/chips/F74x_F75x.chip @@ -3,7 +3,7 @@ dev_type STM32F74x_F75x ref_manual_id 0385 chip_id 0x449 // STM32_CHIPID_F7 -flash_type 4 // STM32_FLASH_TYPE_F7 +flash_type F7 flash_size_reg 0x1ff0f442 flash_pagesize 0x800 // 2 KB sram_size 0x50000 // 320 KB diff --git a/config/chips/F76x_F77x.chip b/config/chips/F76x_F77x.chip index c6d04ff78..dfc983254 100644 --- a/config/chips/F76x_F77x.chip +++ b/config/chips/F76x_F77x.chip @@ -3,7 +3,7 @@ dev_type STM32F76x_F77x ref_manual_id 0410 chip_id 0x451 // STM32_CHIPID_F76xxx -flash_type 4 // STM32_FLASH_TYPE_F7 +flash_type F7 flash_size_reg 0x1ff0f442 flash_pagesize 0x800 // 2 KB sram_size 0x80000 // 512 KB diff --git a/config/chips/G03x_G04x.chip b/config/chips/G03x_G04x.chip index fd6dc3bcf..a414b52ab 100644 --- a/config/chips/G03x_G04x.chip +++ b/config/chips/G03x_G04x.chip @@ -3,7 +3,7 @@ dev_type STM32G03x_G04x ref_manual_id 0444 // also RM454 chip_id 0x466 // STM32_CHIPID_G0_CAT1 -flash_type 5 // STM32_FLASH_TYPE_G0 +flash_type G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x2000 // 8 KB diff --git a/config/chips/G05x_G06x.chip b/config/chips/G05x_G06x.chip index ce5e52de4..ae074e584 100644 --- a/config/chips/G05x_G06x.chip +++ b/config/chips/G05x_G06x.chip @@ -3,7 +3,7 @@ dev_type STM32G05x_G06x ref_manual_id 0444 chip_id 0x456 // STM32_CHIPID_G0_CAT4 -flash_type 5 // STM32_FLASH_TYPE_G0 +flash_type G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x9000 // 36 KB diff --git a/config/chips/G07x_G08x.chip b/config/chips/G07x_G08x.chip index 7a10fc052..82b3992c2 100644 --- a/config/chips/G07x_G08x.chip +++ b/config/chips/G07x_G08x.chip @@ -3,7 +3,7 @@ dev_type STM32G07x_G08x ref_manual_id 0444 chip_id 0x460 // STM32_CHIPID_G0_CAT2 -flash_type 5 // STM32_FLASH_TYPE_G0 +flash_type G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x9000 // 36 KB diff --git a/config/chips/G0Bx_G0Cx.chip b/config/chips/G0Bx_G0Cx.chip index 6ab8ca55a..f21fd65a0 100644 --- a/config/chips/G0Bx_G0Cx.chip +++ b/config/chips/G0Bx_G0Cx.chip @@ -3,7 +3,7 @@ dev_type STM32G0Bx_G0Cx ref_manual_id 0444 chip_id 0x467 // STM32_CHIPID_G0_CAT3 -flash_type 5 // STM32_FLASH_TYPE_G0 +flash_type G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x9000 // 36 KB diff --git a/config/chips/G43x_G44x.chip b/config/chips/G43x_G44x.chip index a7eb86d34..26d1b2f1f 100644 --- a/config/chips/G43x_G44x.chip +++ b/config/chips/G43x_G44x.chip @@ -3,7 +3,7 @@ dev_type STM32G43x_G44x ref_manual_id 0440 chip_id 0x468 // STM32_CHIPID_G4_CAT2 -flash_type 6 // STM32_FLASH_TYPE_G4 +flash_type G4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x8000 // 32 KB diff --git a/config/chips/G47x_G48x.chip b/config/chips/G47x_G48x.chip index 1b2b386fd..707727aca 100644 --- a/config/chips/G47x_G48x.chip +++ b/config/chips/G47x_G48x.chip @@ -3,7 +3,7 @@ dev_type STM32G47x_G48x ref_manual_id 0440 chip_id 0x469 // STM32_CHIPID_G4_CAT3 -flash_type 6 // STM32_FLASH_TYPE_G4 +flash_type G4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x20000 // 128 KB diff --git a/config/chips/G49x_G4Ax.chip b/config/chips/G49x_G4Ax.chip index 1defbfff8..3e8aacf4b 100644 --- a/config/chips/G49x_G4Ax.chip +++ b/config/chips/G49x_G4Ax.chip @@ -3,7 +3,7 @@ dev_type STM32G49x_G4Ax ref_manual_id 0440 chip_id 0x479 // STM32_CHIPID_G4_CAT4 -flash_type 6 // STM32_FLASH_TYPE_G4 +flash_type G4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x1c000 // 112 KB diff --git a/config/chips/H72x_H73x.chip b/config/chips/H72x_H73x.chip index 50925fdcd..194b740d4 100644 --- a/config/chips/H72x_H73x.chip +++ b/config/chips/H72x_H73x.chip @@ -3,7 +3,7 @@ dev_type STM32H72x_H73x ref_manual_id 0468 chip_id 0x483 // STM32_CHIPID_H72x -flash_type 7 // STM32_FLASH_TYPE_H7 +flash_type H7 flash_size_reg 0x1ff1e880 flash_pagesize 0x20000 // 128 KB sram_size 0x20000 // 128 KB "DTCM" diff --git a/config/chips/H74x_H75x.chip b/config/chips/H74x_H75x.chip index 20bfcd2cb..2b829f792 100644 --- a/config/chips/H74x_H75x.chip +++ b/config/chips/H74x_H75x.chip @@ -3,7 +3,7 @@ dev_type STM32H74x_H75x ref_manual_id 0433 chip_id 0x450 // STM32_CHIPID_H74xxx -flash_type 7 // STM32_FLASH_TYPE_H7 +flash_type H7 flash_size_reg 0x1ff1e880 flash_pagesize 0x20000 // 128 KB sram_size 0x20000 // 128 KB "DTCM" diff --git a/config/chips/H7Ax_H7Bx.chip b/config/chips/H7Ax_H7Bx.chip index b31e4fb88..0f66d2c77 100644 --- a/config/chips/H7Ax_H7Bx.chip +++ b/config/chips/H7Ax_H7Bx.chip @@ -3,7 +3,7 @@ dev_type STM32H7Ax_H7Bx ref_manual_id 0455 chip_id 0x480 // STM32_CHIPID_H7Ax -flash_type 7 // STM32_FLASH_TYPE_H7 +flash_type H7 flash_size_reg 0x08fff80c flash_pagesize 0x2000 // 8 KB sram_size 0x20000 // 128 KB "DTCM" diff --git a/config/chips/L0xxx_Cat_1.chip b/config/chips/L0xxx_Cat_1.chip index d612143d5..2cce4e23c 100644 --- a/config/chips/L0xxx_Cat_1.chip +++ b/config/chips/L0xxx_Cat_1.chip @@ -3,7 +3,7 @@ dev_type STM32L0xxx_Cat_1 ref_manual_id 0451 // also RM0377 chip_id 0x457 // STM32_CHIPID_L011 -flash_type 8 // STM32_FLASH_TYPE_L0_L1 +flash_type L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B sram_size 0x2000 // 8 KB diff --git a/config/chips/L0xxx_Cat_2.chip b/config/chips/L0xxx_Cat_2.chip index 49d3e8b07..aae0fac7b 100644 --- a/config/chips/L0xxx_Cat_2.chip +++ b/config/chips/L0xxx_Cat_2.chip @@ -3,7 +3,7 @@ dev_type STM32L0xxx_Cat_2 ref_manual_id 0451 // also RM0377 chip_id 0x425 // STM32_CHIPID_L0_CAT2 -flash_type 8 // STM32_FLASH_TYPE_L0_L1 +flash_type L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B sram_size 0x2000 // 8 KB diff --git a/config/chips/L0xxx_Cat_3.chip b/config/chips/L0xxx_Cat_3.chip index c1b6c3bf4..a04dc8376 100644 --- a/config/chips/L0xxx_Cat_3.chip +++ b/config/chips/L0xxx_Cat_3.chip @@ -3,7 +3,7 @@ dev_type STM32L0xxx_Cat_3 ref_manual_id 0451 // also RM0367 & RM0377 chip_id 0x417 // STM32_CHIPID_L0 -flash_type 8 // STM32_FLASH_TYPE_L0_L1 +flash_type L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B sram_size 0x2000 // 8 KB diff --git a/config/chips/L0xxx_Cat_5.chip b/config/chips/L0xxx_Cat_5.chip index 94e14dfe0..22cbb200a 100644 --- a/config/chips/L0xxx_Cat_5.chip +++ b/config/chips/L0xxx_Cat_5.chip @@ -3,7 +3,7 @@ dev_type STM32L0xxx_Cat_5 ref_manual_id 0451 // also RM0367 & RM0377 chip_id 0x447 // STM32_CHIPID_L0_CAT5 -flash_type 8 // STM32_FLASH_TYPE_L0_L1 +flash_type L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B sram_size 0x5000 // 20 KB diff --git a/config/chips/L1xx_Cat_1.chip b/config/chips/L1xx_Cat_1.chip index 16f2ff8c9..b1b3e85e7 100644 --- a/config/chips/L1xx_Cat_1.chip +++ b/config/chips/L1xx_Cat_1.chip @@ -3,7 +3,7 @@ dev_type STM32L1xx_Cat_1 ref_manual_id 0038 chip_id 0x416 // STM32_CHIPID_L1_MD -flash_type 8 // STM32_FLASH_TYPE_L0_L1 +flash_type L0_L1 flash_size_reg 0x1ff8004c flash_pagesize 0x100 // 128 B sram_size 0x4000 // 16 KB diff --git a/config/chips/L1xx_Cat_2.chip b/config/chips/L1xx_Cat_2.chip index 82d7dfe44..695f60d7f 100644 --- a/config/chips/L1xx_Cat_2.chip +++ b/config/chips/L1xx_Cat_2.chip @@ -3,7 +3,7 @@ dev_type STM32L1xx_Cat_2 ref_manual_id 0038 chip_id 0x429 // STM32_CHIPID_L1_CAT2 -flash_type 8 // STM32_FLASH_TYPE_L0_L1 +flash_type L0_L1 flash_size_reg 0x1ff8004c flash_pagesize 0x100 // 128 B sram_size 0x8000 // 32 KB diff --git a/config/chips/L1xx_Cat_3.chip b/config/chips/L1xx_Cat_3.chip index 2241e5bde..43e21f517 100644 --- a/config/chips/L1xx_Cat_3.chip +++ b/config/chips/L1xx_Cat_3.chip @@ -3,7 +3,7 @@ dev_type STM32L1xx_Cat_3 ref_manual_id 0038 chip_id 0x427 // STM32_CHIPID_L1_MD_PLUS -flash_type 8 // STM32_FLASH_TYPE_L0_L1 +flash_type L0_L1 flash_size_reg 0x1ff800cc flash_pagesize 0x100 // 128 B sram_size 0x8000 // 32 KB diff --git a/config/chips/L1xx_Cat_4.chip b/config/chips/L1xx_Cat_4.chip index 7933d7121..a36118937 100644 --- a/config/chips/L1xx_Cat_4.chip +++ b/config/chips/L1xx_Cat_4.chip @@ -3,7 +3,7 @@ dev_type STM32L1xx_Cat_4 ref_manual_id 0038 chip_id 0x436 // STM32_CHIPID_L1_MD_PLUS_HD -flash_type 8 // STM32_FLASH_TYPE_L0_L1 +flash_type L0_L1 flash_size_reg 0x1ff800cc flash_pagesize 0x100 // 128 B sram_size 0xc000 // 48 KB diff --git a/config/chips/L1xx_Cat_5.chip b/config/chips/L1xx_Cat_5.chip index 0e95e54e8..a487b22bc 100644 --- a/config/chips/L1xx_Cat_5.chip +++ b/config/chips/L1xx_Cat_5.chip @@ -3,7 +3,7 @@ dev_type STM32L1xx_Cat_5 ref_manual_id 0038 chip_id 0x437 // STM32_CHIPID_L152_RE -flash_type 8 // STM32_FLASH_TYPE_L0_L1 +flash_type L0_L1 flash_size_reg 0x1ff800cc flash_pagesize 0x100 // 128 B sram_size 0x14000 // 80 KB diff --git a/config/chips/L41x_L42x.chip b/config/chips/L41x_L42x.chip index 726645552..11e545bb7 100644 --- a/config/chips/L41x_L42x.chip +++ b/config/chips/L41x_L42x.chip @@ -3,7 +3,7 @@ dev_type STM32L41x_L42x ref_manual_id 0394 chip_id 0x464 // STM32_CHIPID_L41x_L42x -flash_type 9 // STM32_FLASH_TYPE_L4_L4P +flash_type L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0xa000 // 40 KB diff --git a/config/chips/L43x_L44x.chip b/config/chips/L43x_L44x.chip index baba13e55..f0a959693 100644 --- a/config/chips/L43x_L44x.chip +++ b/config/chips/L43x_L44x.chip @@ -3,7 +3,7 @@ dev_type STM32L41x_L42x ref_manual_id 0392 chip_id 0x435 // STM32_CHIPID_L43x_L44x -flash_type 9 // STM32_FLASH_TYPE_L4_L4P +flash_type L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0xc000 // 48 KB diff --git a/config/chips/L45x_L46x.chip b/config/chips/L45x_L46x.chip index 8886633e2..267122f87 100644 --- a/config/chips/L45x_L46x.chip +++ b/config/chips/L45x_L46x.chip @@ -3,7 +3,7 @@ dev_type STM32L45x_L46x ref_manual_id 0394 chip_id 0x462 // STM32_CHIPID_L45x_L46x -flash_type 9 // STM32_FLASH_TYPE_L4_L4P +flash_type L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x20000 // 128 KB diff --git a/config/chips/L47x_L48x.chip b/config/chips/L47x_L48x.chip index df96ee2fb..421663e58 100644 --- a/config/chips/L47x_L48x.chip +++ b/config/chips/L47x_L48x.chip @@ -3,7 +3,7 @@ dev_type STM32L47x_L48x ref_manual_id 0351 chip_id 0x415 // STM32_CHIPID_L4 -flash_type 9 // STM32_FLASH_TYPE_L4_L4P +flash_type L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x18000 // 96 KB diff --git a/config/chips/L496x_L4A6x.chip b/config/chips/L496x_L4A6x.chip index 0f4bd285d..df1f084ff 100644 --- a/config/chips/L496x_L4A6x.chip +++ b/config/chips/L496x_L4A6x.chip @@ -3,7 +3,7 @@ dev_type STM32L496x_L4A6x ref_manual_id 0351 chip_id 0x461 // STM32_CHIPID_L496x_L4A6x -flash_type 9 // STM32_FLASH_TYPE_L4_L4P +flash_type L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/L4Px.chip b/config/chips/L4Px.chip index 2d1a59806..39788eabe 100644 --- a/config/chips/L4Px.chip +++ b/config/chips/L4Px.chip @@ -3,7 +3,7 @@ dev_type STM32L4Px ref_manual_id 0432 chip_id 0x471 // STM32_CHIPID_L4PX -flash_type 9 // STM32_FLASH_TYPE_L4_L4P +flash_type L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x1000 // 4 KB sram_size 0xa0000 // 640 KB diff --git a/config/chips/L4Rx.chip b/config/chips/L4Rx.chip index f0593a97e..b5c2d0d80 100644 --- a/config/chips/L4Rx.chip +++ b/config/chips/L4Rx.chip @@ -3,7 +3,7 @@ dev_type STM32L4Rx ref_manual_id 0432 chip_id 0x470 // STM32_CHIPID_L4RX -flash_type 9 // STM32_FLASH_TYPE_L4_L4P +flash_type L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x1000 // 4 KB sram_size 0xa0000 // 640 KB diff --git a/config/chips/L5x5.chip b/config/chips/L5x5.chip.txt similarity index 85% rename from config/chips/L5x5.chip rename to config/chips/L5x5.chip.txt index 9a5b2fdbf..ce268148b 100644 --- a/config/chips/L5x5.chip +++ b/config/chips/L5x5.chip.txt @@ -3,7 +3,7 @@ dev_type STM32L5x2 ref_manual_id 0438 chip_id 0x0 // (temporary setting only!) -flash_type 10 // (temporary setting only!) +flash_type 0 // (temporary setting only!) flash_size_reg 0x0bfa07a0 flash_pagesize 0x2000 // 8 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/U5x5.chip b/config/chips/U5x5.chip.txt similarity index 85% rename from config/chips/U5x5.chip rename to config/chips/U5x5.chip.txt index 55dfdaf7d..177359cc3 100644 --- a/config/chips/U5x5.chip +++ b/config/chips/U5x5.chip.txt @@ -3,7 +3,7 @@ dev_type STM32U5x5 ref_manual_id 0456 chip_id 0x0 // (temporary setting only!) -flash_type 10 // (temporary setting only!) +flash_type 0 // (temporary setting only!) flash_size_reg 0x0bfa07a0 flash_pagesize 0x2000 // 8 KB sram_size 0xc4800 // 786 KB diff --git a/config/chips/WBx0_WBx5.chip b/config/chips/WBx0_WBx5.chip index 3d27edd6d..2747386f8 100644 --- a/config/chips/WBx0_WBx5.chip +++ b/config/chips/WBx0_WBx5.chip @@ -3,7 +3,7 @@ dev_type STM32WBx0_WBx5 ref_manual_id 0434 // also RM0471 chip_id 0x495 // STM32_CHIPID_WB55 -flash_type 11 // STM32_FLASH_TYPE_WB_WL +flash_type WB_WL flash_size_reg 0x1fff75e0 flash_pagesize 0x1000 // 4 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/WLx5.chip b/config/chips/WLx5.chip index 9669fe27f..5bc9d90dc 100644 --- a/config/chips/WLx5.chip +++ b/config/chips/WLx5.chip @@ -3,7 +3,7 @@ dev_type STM32WLEx ref_manual_id 0033 chip_id 0x497 // STM32_CHIPID_WLE -flash_type 11 // STM32_FLASH_TYPE_WB_WL +flash_type WB_WL flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x10000 // 64 KB diff --git a/config/chips/unknown_device.chip b/config/chips/unknown_device.chip index bc50e7a00..4eb0c6cbf 100644 --- a/config/chips/unknown_device.chip +++ b/config/chips/unknown_device.chip @@ -3,7 +3,7 @@ dev_type unknown ref_manual_id 0000 chip_id 0x0 // STM32_CHIPID_UNKNOWN -flash_type 0 // STM32_FLASH_TYPE_UNKNOWN +flash_type UNKNOWN flash_size_reg 0x0 flash_pagesize 0x0 sram_size 0x0 diff --git a/inc/stm32.h b/inc/stm32.h index 56176bd6f..d6bbe506c 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -8,47 +8,39 @@ #define STM32_H /* STM32 Cortex-M core ids (CPUTAPID) */ -#define STM32_CORE_ID_M0_SWD 0x0bb11477 // (RM0091 Section 32.5.3) F0 SW-DP +enum stm32_core_id { + STM32_CORE_ID_M0_SWD = 0x0bb11477, // (RM0091 Section 32.5.3) F0 SW-DP // (RM0444 Section 40.5.3) G0 SW-DP - -#define STM32_CORE_ID_M0P_SWD 0x0bc11477 // (RM0385 Section 27.5.3) L0 SW-DP - -#define STM32_CORE_ID_M3_r1p1_SWD 0x1ba01477 // (RM0008 Section 31.8.3) F1 SW-DP -#define STM32_CORE_ID_M3_r1p1_JTAG 0x3ba00477 // (RM0008 Section 31.6.3) F1 JTAG - -#define STM32_CORE_ID_M3_r2p0_SWD 0x2ba01477 // (RM0033 Section 32.8.3) F2 SW-DP + STM32_CORE_ID_M0P_SWD = 0x0bc11477, // (RM0385 Section 27.5.3) L0 SW-DP + STM32_CORE_ID_M3_r1p1_SWD = 0x1ba01477, // (RM0008 Section 31.8.3) F1 SW-DP + STM32_CORE_ID_M3_r1p1_JTAG = 0x3ba00477, // (RM0008 Section 31.6.3) F1 JTAG + STM32_CORE_ID_M3_r2p0_SWD = 0x2ba01477, // (RM0033 Section 32.8.3) F2 SW-DP // (RM0038 Section 30.8.3) L1 SW-DP -#define STM32_CORE_ID_M3_r2p0_JTAG 0x0ba00477 // (RM0033 Section 32.6.3) F2 JTAG + STM32_CORE_ID_M3_r2p0_JTAG = 0x0ba00477, // (RM0033 Section 32.6.3) F2 JTAG // (RM0038 Section 30.6.2) L1 JTAG - -#define STM32_CORE_ID_M4_r0p1_SWD 0x1ba01477 // (RM0316 Section 33.8.3) F3 SW-DP + STM32_CORE_ID_M4_r0p1_SWD = 0x1ba01477, // (RM0316 Section 33.8.3) F3 SW-DP // (RM0351 Section 48.8.3) L4 SW-DP // (RM0432 Section 57.8.3) L4+ SW-DP -#define STM32_CORE_ID_M4_r0p1_JTAG 0x4ba00477 // (RM0316 Section 33.6.3) F3 JTAG + STM32_CORE_ID_M4_r0p1_JTAG = 0x4ba00477, // (RM0316 Section 33.6.3) F3 JTAG // (RM0351 Section 48.6.3) L4 JTAG // (RM0432 Section 57.6.3) L4+ JTAG - -#define STM32_CORE_ID_M4F_r0p1_SWD 0x2ba01477 // (RM0090 Section 38.8.3) F4 SW-DP + STM32_CORE_ID_M4F_r0p1_SWD = 0x2ba01477, // (RM0090 Section 38.8.3) F4 SW-DP // (RM0090 Section 47.8.3) G4 SW-DP -#define STM32_CORE_ID_M4F_r0p1_JTAG 0x4ba00477 // (RM0090 Section 38.6.3) F4 JTAG + STM32_CORE_ID_M4F_r0p1_JTAG = 0x4ba00477, // (RM0090 Section 38.6.3) F4 JTAG // (RM0090 Section 47.6.3) G4 JTAG - -#define STM32_CORE_ID_M7F_SWD 0x5ba02477 // (RM0385 Section 40.8.3) F7 SW-DP -#define STM32_CORE_ID_M7F_JTAG 0x5ba00477 // (RM0385 Section 40.6.3) F7 JTAG - -#define STM32_CORE_ID_M7F_H7_SWD 0x6ba02477 // (RM0433 Section 60.4.1) H7 SW-DP -#define STM32_CORE_ID_M7F_H7_JTAG 0x6ba00477 // (RM0433 Section 60.4.1) H7 JTAG - -#define STM32_CORE_ID_M33_SWD 0x0be02477 // (RM0438 Section 52.2.10) L5 SW-DP + STM32_CORE_ID_M7F_SWD = 0x5ba02477, // (RM0385 Section 40.8.3) F7 SW-DP + STM32_CORE_ID_M7F_JTAG = 0x5ba00477, // (RM0385 Section 40.6.3) F7 JTAG + STM32_CORE_ID_M7F_H7_SWD = 0x6ba02477, // (RM0433 Section 60.4.1) H7 SW-DP + STM32_CORE_ID_M7F_H7_JTAG = 0x6ba00477, // (RM0433 Section 60.4.1) H7 JTAG + STM32_CORE_ID_M33_SWD = 0x0be02477, // (RM0438 Section 52.2.10) L5 SW-DP // (RM0456 Section 65.3.3) U5 SW-DP -#define STM32_CORE_ID_M33_JTAGD 0x0be01477 // (RM0438 Section 52.2.10) L5 JTAG-DP + STM32_CORE_ID_M33_JTAGD = 0x0be01477, // (RM0438 Section 52.2.10) L5 JTAG-DP // (RM0456 Section 65.3.3) U5 JTAG-DP -#define STM32_CORE_ID_M33_JTAG 0x0ba04477 // (RM0438 Section 52.2.8) L5 JTAG + STM32_CORE_ID_M33_JTAG = 0x0ba04477, // (RM0438 Section 52.2.8) L5 JTAG // (RM0456 Section 56.3.1) U5 JTAG +}; /* STM32 flash types */ -// New flash type definitions must go before STM32_FLASH_TYPE_UNDEFINED -// with the latter updated to the highest enum value. enum stm32_flash_type { STM32_FLASH_TYPE_UNKNOWN = 0, STM32_FLASH_TYPE_F0_F1_F3 = 1, @@ -62,7 +54,6 @@ enum stm32_flash_type { STM32_FLASH_TYPE_L4_L4P = 9, STM32_FLASH_TYPE_L5_U5 = 10, STM32_FLASH_TYPE_WB_WL = 11, - STM32_FLASH_TYPE_UNDEFINED = 12, // max. value exceeded }; /* STM32 chip-ids */ @@ -70,7 +61,7 @@ enum stm32_flash_type { // stm32 chipids, only lower 12 bits... enum stm32_chipids { - STM32_CHIPID_UNKNOWN = 0x000, + STM32_CHIPID_UNKNOWN = 0x000, STM32_CHIPID_F1_MD = 0x410, /* medium density */ STM32_CHIPID_F2 = 0x411, diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index dbfd2882d..e68f6e371 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1,3 +1,4 @@ +#include #include #include "chipid.h" @@ -7,7 +8,6 @@ #include #include - static struct stlink_chipid_params *devicelist; void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { @@ -28,7 +28,6 @@ void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chip_id) { struct stlink_chipid_params *params = NULL; -// struct stlink_chipid_params *p2; for (params = devicelist; params != NULL; params = params->next) if (params->chip_id == chip_id) { fprintf(stderr, "\ndetected chip_id parametres\n\n"); @@ -74,7 +73,7 @@ void process_chipfile(char *fname) { buf[strlen(p) - 1] = 0; // chomp newline sscanf(p, "%*s %n", &nc); ts->dev_type = strdup(p + nc); - } else if (strcmp (word, "ref_manual_id") == 0) { + } else if (strcmp(word, "ref_manual_id") == 0) { // ts->ref_manual_id = strdup (value); buf[strlen(p) - 1] = 0; // chomp newline sscanf(p, "%*s %n", &nc); @@ -83,59 +82,80 @@ void process_chipfile(char *fname) { if (sscanf(value, "%i", &ts->chip_id) < 1) { fprintf(stderr, "Failed to parse chip-id\n"); } - } else if (strcmp (word, "flash_type") == 0) { - if (sscanf(value, "%i", (int *)&ts->flash_type) < 1) { - fprintf(stderr, "Failed to parse flash type\n"); - } else if ((ts->flash_type < STM32_FLASH_TYPE_UNKNOWN) || (ts->flash_type >= STM32_FLASH_TYPE_UNDEFINED)) { - fprintf(stderr, "Unrecognized flash type\n"); + } else if (strcmp(word, "flash_type") == 0) { + if (strcmp(value, "F0_F1_F3") == 0) { + ts->flash_type = STM32_FLASH_TYPE_F0_F1_F3; + } else if (strcmp(value, "F1_XL") == 0) { + ts->flash_type = STM32_FLASH_TYPE_F1_XL; + } else if (strcmp(value, "F2_F4") == 0) { + ts->flash_type = STM32_FLASH_TYPE_F2_F4; + } else if (strcmp(value, "F7") == 0) { + ts->flash_type = STM32_FLASH_TYPE_F7; + } else if (strcmp(value, "G0") == 0) { + ts->flash_type = STM32_FLASH_TYPE_G0; + } else if (strcmp(value, "G4") == 0) { + ts->flash_type = STM32_FLASH_TYPE_G4; + } else if (strcmp(value, "H7") == 0) { + ts->flash_type = STM32_FLASH_TYPE_H7; + } else if (strcmp(value, "L0_L1") == 0) { + ts->flash_type = STM32_FLASH_TYPE_L0_L1; + } else if (strcmp(value, "L4_L4P") == 0) { + ts->flash_type = STM32_FLASH_TYPE_L4_L4P; + } else if (strcmp(value, "L5_U5") == 0) { + ts->flash_type = STM32_FLASH_TYPE_L5_U5; + } else if (strcmp(value, "WB_WL") == 0) { + ts->flash_type = STM32_FLASH_TYPE_WB_WL; + } else { + ts->flash_type = STM32_FLASH_TYPE_UNKNOWN; + fprintf(stderr, "Failed to parse flash type or unrecognized flash type\n"); } - } else if (strcmp (word, "flash_size_reg") == 0) { + } else if (strcmp(word, "flash_size_reg") == 0) { if (sscanf(value, "%i", &ts->flash_size_reg) < 1) { fprintf(stderr, "Failed to parse flash size reg\n"); } - } else if (strcmp (word, "flash_pagesize") == 0) { + } else if (strcmp(word, "flash_pagesize") == 0) { if (sscanf(value, "%i", &ts->flash_pagesize) < 1) { fprintf(stderr, "Failed to parse flash page size\n"); } - } else if (strcmp (word, "sram_size") == 0) { + } else if (strcmp(word, "sram_size") == 0) { if (sscanf(value, "%i", &ts->sram_size) < 1) { fprintf(stderr, "Failed to parse SRAM size\n"); } - } else if (strcmp (word, "bootrom_base") == 0) { + } else if (strcmp(word, "bootrom_base") == 0) { if (sscanf(value, "%i", &ts->bootrom_base) < 1) { fprintf(stderr, "Failed to parse BootROM base\n"); } - } else if (strcmp (word, "bootrom_size") == 0) { + } else if (strcmp(word, "bootrom_size") == 0) { if (sscanf(value, "%i", &ts->bootrom_size) < 1) { fprintf(stderr, "Failed to parse BootROM size\n"); } - } else if (strcmp (word, "option_base") == 0) { + } else if (strcmp(word, "option_base") == 0) { if (sscanf(value, "%i", &ts->option_base) < 1) { fprintf(stderr, "Failed to parse option base\n"); } - } else if (strcmp (word, "option_size") == 0) { + } else if (strcmp(word, "option_size") == 0) { if (sscanf(value, "%i", &ts->option_size) < 1) { fprintf(stderr, "Failed to parse option size\n"); } - } else if (strcmp (word, "flags") == 0) { + } else if (strcmp(word, "flags") == 0) { pp = strtok (p, " \t\n"); while ((pp = strtok (NULL, " \t\n"))) { - if (strcmp (pp, "none") == 0) { + if (strcmp(pp, "none") == 0) { // NOP - } else if (strcmp (pp, "dualbank") == 0) { + } else if (strcmp(pp, "dualbank") == 0) { ts->flags |= CHIP_F_HAS_DUAL_BANK; - } else if (strcmp (pp, "swo") == 0) { + } else if (strcmp(pp, "swo") == 0) { ts->flags |= CHIP_F_HAS_SWO_TRACING; } else { - fprintf (stderr, "Unknown flags word in %s: '%s'\n", + fprintf(stderr, "Unknown flags word in %s: '%s'\n", fname, pp); } } sscanf(value, "%x", &ts->flags); } else { - fprintf (stderr, "Unknown keyword in %s: %s\n", + fprintf(stderr, "Unknown keyword in %s: %s\n", fname, word); } } @@ -156,7 +176,6 @@ void init_chipids(char *dir_to_scan) { } devicelist = NULL; - // dump_chips (); d = opendir(dir_to_scan); if (d) { From fecd2baeae8afc4c69d3dce19ab99fff5ee37bef Mon Sep 17 00:00:00 2001 From: hydroconstructor Date: Fri, 21 Jan 2022 23:26:44 +0400 Subject: [PATCH 1293/1435] Refactoring common.c Added forgotten defines --- inc/stm32.h | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/inc/stm32.h b/inc/stm32.h index 21da2f563..17b27918c 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -35,4 +35,44 @@ #define STM32_F3_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) #define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) +#define STM32F0_DBGMCU_CR 0xE0042004 +#define STM32F0_DBGMCU_CR_IWDG_STOP 8 +#define STM32F0_DBGMCU_CR_WWDG_STOP 9 + +#define STM32F4_DBGMCU_APB1FZR1 0xE0042008 +#define STM32F4_DBGMCU_APB1FZR1_WWDG_STOP 11 +#define STM32F4_DBGMCU_APB1FZR1_IWDG_STOP 12 + +#define STM32L0_DBGMCU_APB1_FZ 0x40015808 +#define STM32L0_DBGMCU_APB1_FZ_WWDG_STOP 11 +#define STM32L0_DBGMCU_APB1_FZ_IWDG_STOP 12 + +#define STM32H7_DBGMCU_APB1HFZ 0x5C001054 +#define STM32H7_DBGMCU_APB1HFZ_IWDG_STOP 18 + +#define STM32WB_DBGMCU_APB1FZR1 0xE004203C +#define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11 +#define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12 + +#define STM32F1_RCC_AHBENR 0x40021014 +#define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32F4_RCC_AHB1ENR 0x40023830 +#define STM32F4_RCC_DMAEN 0x00600000 // DMA2EN | DMA1EN + +#define STM32G0_RCC_AHBENR 0x40021038 +#define STM32G0_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32G4_RCC_AHB1ENR 0x40021048 +#define STM32G4_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32L0_RCC_AHBENR 0x40021030 +#define STM32L0_RCC_DMAEN 0x00000001 // DMAEN + +#define STM32H7_RCC_AHB1ENR 0x58024538 +#define STM32H7_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32WB_RCC_AHB1ENR 0x58000048 +#define STM32WB_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + #endif // STM32_H From da3d9e3f1e1a6d116df5830cf506f30ff56196b3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 21 Jan 2022 21:31:54 +0100 Subject: [PATCH 1294/1435] Formatting and whitespace clean-up --- src/stlink-lib/chipid.c | 1 + src/stlink-lib/chipid.h | 2 -- src/stlink-lib/flash_loader.c | 18 +++++++++--------- src/stlink-lib/flash_loader.h | 3 +-- src/stlink-lib/libusb_settings.h | 28 +++++++++++++--------------- src/stlink-lib/logging.c | 1 + src/stlink-lib/sg.c | 1 - src/stlink-lib/sg.h | 2 -- src/stlink-lib/usb.h | 2 +- src/win32/mmap.h | 2 -- src/win32/sys_time.c | 1 + src/win32/sys_time.h | 1 - src/win32/win32_socket.c | 6 ++++-- src/win32/win32_socket.h | 6 ++++-- 14 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index e68f6e371..06e8571aa 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -228,4 +228,5 @@ void init_chipids(char *dir_to_scan) { FindClose(hFind); } + #endif //defined(_WIN32) && !defined(STLINK_HAVE_DIRENT_H) diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index 8efcd653e..458e7c3e2 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -4,7 +4,6 @@ #include #include - /** Chipid parametres */ struct stlink_chipid_params { char *dev_type; @@ -25,5 +24,4 @@ struct stlink_chipid_params { struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); void init_chipids(char *dir_to_scan); - #endif // STLINK_CHIPID_H_ diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 2b47c1114..94978a51f 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -7,17 +7,16 @@ #include #include "flash_loader.h" -#define FLASH_REGS_BANK2_OFS 0x40 -#define FLASH_BANK2_START_ADDR 0x08080000 +#define FLASH_REGS_BANK2_OFS 0x40 +#define FLASH_BANK2_START_ADDR 0x08080000 #define STM32F0_WDG_KR 0x40003000 #define STM32H7_WDG_KR 0x58004800 #define STM32F0_WDG_KR_KEY_RELOAD 0xAAAA -/* !!! - * !!! DO NOT MODIFY FLASH LOADERS DIRECTLY! - * !!! +/* + * !!! DO NOT MODIFY FLASH LOADERS DIRECTLY !!! * * Edit assembly files in the '/flashloaders' instead. The sizes of binary * flash loaders must be aligned by 4 (it's written by stlink_write_mem32) @@ -155,8 +154,7 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { size_t size = 0; uint32_t dfsr, cfsr, hfsr; - /* Interrupt masking. - * According to DDI0419C, Table C1-7 firstly force halt */ + /* Interrupt masking according to DDI0419C, Table C1-7 firstly force halt */ stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | STLINK_REG_DHCSR_C_HALT); @@ -354,7 +352,8 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe /* Run loader */ stlink_run(sl, RUN_FLASH_LOADER); -/* This piece of code used to try to spin for .1 second by waiting doing 10000 rounds of 10 µs. +/* + * This piece of code used to try to spin for .1 second by waiting doing 10000 rounds of 10 µs. * But because this usually runs on Unix-like OSes, the 10 µs get rounded up to the "tick" * (actually almost two ticks) of the system. 1 ms. Thus, the ten thousand attempts, when * "something goes wrong" that requires the error message "flash loader run error" would wait @@ -383,7 +382,8 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe // check written byte count stlink_read_reg(sl, 2, &rr); - /* The chunk size for loading is not rounded. The flash loader + /* + * The chunk size for loading is not rounded. The flash loader * subtracts the size of the written block (1-8 bytes) from * the remaining size each time. A negative value may mean that * several bytes garbage has been written due to the unaligned diff --git a/src/stlink-lib/flash_loader.h b/src/stlink-lib/flash_loader.h index bac99bdb4..85b92bef3 100644 --- a/src/stlink-lib/flash_loader.h +++ b/src/stlink-lib/flash_loader.h @@ -4,6 +4,7 @@ * This should contain all the common top level stlink interfaces, * regardless of how the backend does the work.... */ + #ifndef STLINK_FLASH_LOADER_H_ #define STLINK_FLASH_LOADER_H_ @@ -12,10 +13,8 @@ #include - int stlink_flash_loader_init(stlink_t *sl, flash_loader_t* fl); int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size); - #endif // STLINK_FLASH_LOADER_H_ diff --git a/src/stlink-lib/libusb_settings.h b/src/stlink-lib/libusb_settings.h index a2dfc6d26..cc44736f9 100644 --- a/src/stlink-lib/libusb_settings.h +++ b/src/stlink-lib/libusb_settings.h @@ -4,21 +4,19 @@ #include /* - - libusb ver | LIBUSB_API_VERSION - -----------+-------------------- - v1.0.13 | 0x01000100 - v1.0.14 | 0x010000FF - v1.0.15 | 0x01000101 - v1.0.16 | 0x01000102 - v1.0.17 | 0x01000102 - v1.0.18 | 0x01000102 - v1.0.19 | 0x01000103 - v1.0.20 | 0x01000104 - v1.0.21 | 0x01000105 - v1.0.22 | 0x01000106 - v1.0.23 | 0x01000107 - + * libusb ver | LIBUSB_API_VERSION + * -----------+-------------------- + * v1.0.13 | 0x01000100 + * v1.0.14 | 0x010000FF + * v1.0.15 | 0x01000101 + * v1.0.16 | 0x01000102 + * v1.0.17 | 0x01000102 + * v1.0.18 | 0x01000102 + * v1.0.19 | 0x01000103 + * v1.0.20 | 0x01000104 + * v1.0.21 | 0x01000105 + * v1.0.22 | 0x01000106 + * v1.0.23 | 0x01000107 */ #if defined (__FreeBSD__) diff --git a/src/stlink-lib/logging.c b/src/stlink-lib/logging.c index 817f3d68e..79924fc20 100644 --- a/src/stlink-lib/logging.c +++ b/src/stlink-lib/logging.c @@ -4,6 +4,7 @@ * Slow, yet another wheel reinvented, but enough to make the rest of our code * pretty enough. */ + #include #include #include diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index 18792c89f..feab40c13 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -74,7 +74,6 @@ * part to an existing options line for usb-storage). */ - #define __USE_GNU #include #include diff --git a/src/stlink-lib/sg.h b/src/stlink-lib/sg.h index 4161d3967..212d03b27 100644 --- a/src/stlink-lib/sg.h +++ b/src/stlink-lib/sg.h @@ -9,7 +9,6 @@ #include #include - /* Device access */ #define RDWR 0 #define RO 1 @@ -57,5 +56,4 @@ struct stlink_libsg { stlink_t* stlink_v1_open(const int verbose, int reset); - #endif // STLINK_SG_H diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index d04ef2dca..885e8cfc5 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -66,9 +66,9 @@ struct stlink_libusb { * @retval NULL Error while opening the stlink * @retval !NULL Stlink found and ready to use */ + stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq); size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int freq); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); - #endif // STLINK_USB_H diff --git a/src/win32/mmap.h b/src/win32/mmap.h index 67558b0cc..06079a9bc 100644 --- a/src/win32/mmap.h +++ b/src/win32/mmap.h @@ -13,11 +13,9 @@ #define MAP_ANONYMOUS (1 << 5) #define MAP_FAILED ((void *)-1) - void *mmap(void *addr, size_t len, int prot, int flags, int fd, long long offset); int munmap(void *addr, size_t len); - #endif /* HAVE_SYS_MMAN_H */ #endif /* STLINK_MMAP_H */ diff --git a/src/win32/sys_time.c b/src/win32/sys_time.c index 08da60b85..422731b3f 100644 --- a/src/win32/sys_time.c +++ b/src/win32/sys_time.c @@ -30,4 +30,5 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) { return 0; } + #endif //STLINK_HAVE_SYS_TIME_H diff --git a/src/win32/sys_time.h b/src/win32/sys_time.h index 3f35390c3..d314509b7 100644 --- a/src/win32/sys_time.h +++ b/src/win32/sys_time.h @@ -14,7 +14,6 @@ struct timezone { int gettimeofday(struct timeval *tv, struct timezone *tz); - #endif /* STLINK_HAVE_SYS_TIME_H */ #endif /* STLINK_TIME_H */ diff --git a/src/win32/win32_socket.c b/src/win32/win32_socket.c index bfdcac5ce..3f4d28bbd 100644 --- a/src/win32/win32_socket.c +++ b/src/win32/win32_socket.c @@ -123,7 +123,8 @@ static void set_socket_errno(int winsock_err) { } } -/* A wrapper around the socket() function. +/* + * A wrapper around the socket() function. * The purpose of this wrapper is to ensure that the global errno symbol is set if an error occurs, * even if we are using winsock. */ @@ -135,7 +136,8 @@ SOCKET win32_socket(int domain, int type, int protocol) { return(fd); } -/* A wrapper around the connect() function. +/* + * A wrapper around the connect() function. * The purpose of this wrapper is to ensure that the global errno symbol is set if an error occurs, * even if we are using winsock. */ diff --git a/src/win32/win32_socket.h b/src/win32/win32_socket.h index 5f8f09589..614046a6f 100644 --- a/src/win32/win32_socket.h +++ b/src/win32/win32_socket.h @@ -20,7 +20,8 @@ #pragma warning(pop) #endif -/* winsock doesn't feature poll(), so there is a version implemented in terms of select() in win32_socket.c. +/* + * winsock doesn't feature poll(), so there is a version implemented in terms of select() in win32_socket.c. * The following definitions are copied from linux man pages. * A poll() macro is defined to call the version in win32_socket.c. */ @@ -40,7 +41,8 @@ struct pollfd { #endif #define poll(x, y, z) win32_poll(x, y, z) -/* These wrappers do nothing special except set the global errno variable if an error occurs +/* + * These wrappers do nothing special except set the global errno variable if an error occurs * (winsock doesn't do this by default). * They set errno to unix-like values (i.e. WSAEWOULDBLOCK is mapped to EAGAIN), * so code outside of this file "shouldn't" have to worry about winsock specific error handling. From 3f5d9bd0f616060f284aced40fbc8153ef0c0801 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 23 Jan 2022 13:13:57 +0100 Subject: [PATCH 1295/1435] Bugfixes and minor additions - Fixed wrong chip id for F42x_F43x boards. - Added support note for STM32 clones. - Minor formatting improvements. - Updated libusb API_VERSION list. --- config/chips/F42x_F43x.chip | 2 +- doc/devices_boards.md | 4 ++-- src/st-info/info.c | 8 +++----- src/stlink-lib/libusb_settings.h | 1 + src/stlink-lib/usb.h | 1 - 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/config/chips/F42x_F43x.chip b/config/chips/F42x_F43x.chip index 4452780b3..9dc81a120 100644 --- a/config/chips/F42x_F43x.chip +++ b/config/chips/F42x_F43x.chip @@ -2,7 +2,7 @@ # dev_type STM32F42x_F43x ref_manual_id 0090 // RM0090 (Rev. 2) -chip_id 0x463 // STM32_CHIPID_F4_HD +chip_id 0x419 // STM32_CHIPID_F4_HD flash_type F2_F4 flash_size_reg 0x1fff7a22 flash_pagesize 0x4000 // 16 KB diff --git a/doc/devices_boards.md b/doc/devices_boards.md index 63569881a..51b9a0739 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -51,7 +51,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | ------- | ------------ | ------------- | | 0x411 | STM32F2yyxx | (all devices) | -## STM32F1 Clone / ARM Cortex M3 (Core-ID: 0x2ba01477) +## STM32F1 Clone / ARM Cortex M3 (Core-ID: 0x2ba01477) [may work, but without support!] | Product-Code | Chip-ID | STLink
      Programmer | Boards | | ------------- | ------- | ---------------------- | ----------------------------------------------------------------------------------------------- | @@ -85,7 +85,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | 0x446 | _N/A_ | xD xE | | F302 | F303 | | | 0x446 | _N/A_ | - | | | | F398 | -## STM32F3 Clone / ARM Cortex M4F (Core-ID: 0x2ba01477) +## STM32F3 Clone / ARM Cortex M4F (Core-ID: 0x2ba01477) [may work, but without support!] | Product-Code | Chip-ID | STLINK
      Programmer | Boards | | ------------ | ------- | ---------------------- | ---------------------------------- | diff --git a/src/st-info/info.c b/src/st-info/info.c index 416d27f56..618046ddd 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -33,13 +33,11 @@ static void stlink_print_info(stlink_t *sl) { if (!sl) { return; } - printf(" version: "); - stlink_print_version(sl); + printf(" version: "); stlink_print_version(sl); printf(" serial: %s\n", sl->serial); - printf(" flash: %u (pagesize: %u)\n", - (uint32_t)sl->flash_size, (uint32_t)sl->flash_pgsz); + printf(" flash: %u (pagesize: %u)\n", (uint32_t)sl->flash_size, (uint32_t)sl->flash_pgsz); printf(" sram: %u\n", (uint32_t)sl->sram_size); - printf(" chipid: 0x%.4x\n", sl->chip_id); + printf(" chipid: 0x%.3x\n", sl->chip_id); params = stlink_chipid_get_params(sl->chip_id); if (params) { printf(" dev-type: %s\n", params->dev_type); } diff --git a/src/stlink-lib/libusb_settings.h b/src/stlink-lib/libusb_settings.h index cc44736f9..c7562e290 100644 --- a/src/stlink-lib/libusb_settings.h +++ b/src/stlink-lib/libusb_settings.h @@ -17,6 +17,7 @@ * v1.0.21 | 0x01000105 * v1.0.22 | 0x01000106 * v1.0.23 | 0x01000107 + * v1.0.24 | 0x01000108 */ #if defined (__FreeBSD__) diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index 885e8cfc5..3f4b71e51 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -12,7 +12,6 @@ #include #include "logging.h" - #define STLINK_USB_VID_ST 0x0483 #define STLINK_USB_PID_STLINK 0x3744 #define STLINK_USB_PID_STLINK_32L 0x3748 From f6cfd1bfe3eb50b90befe03293808727c66cb8bd Mon Sep 17 00:00:00 2001 From: hydroconstructor Date: Sun, 23 Jan 2022 23:22:05 +0400 Subject: [PATCH 1296/1435] user gszy comment Comment was: removing the MAX_FILE_SIZE ifdef/define/endif, replacing the st.st_size > (off_t)SSIZE_MAX test with st.st_size > (intmax_t) SIZE_MAX, perhaps removing the sizeof(st.st_size) != sizeof(size_t) test as well. done here --- src/common.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/common.c b/src/common.c index 32f718c02..d562f0f00 100644 --- a/src/common.c +++ b/src/common.c @@ -27,10 +27,6 @@ #define O_BINARY 0 #endif -#ifndef MAX_FILE_SIZE -#define MAX_FILE_SIZE (1<<20) // signed long int max value -#endif - #ifdef _MSC_VER #define __attribute__(x) #endif @@ -2202,15 +2198,12 @@ static int map_file(mapped_file_t *mf, const char *path) { goto on_error; } - if (sizeof(st.st_size) != sizeof(size_t)) { - // on 32 bit systems, check if there is an overflow - if (st.st_size > (off_t)MAX_FILE_SIZE /*1 GB*/ ) { - // limit file size to 1 GB - fprintf(stderr, "mmap() file %s too big\n", path); - goto on_error; - } + if (st.st_size > (intmax_t) SIZE_MAX ) { + fprintf(stderr, "mmap() file %s too big\n", path); + goto on_error; } + mf->base = (uint8_t *)mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); From d0ed1253cea96e286d02470f0c2d90d5cb352465 Mon Sep 17 00:00:00 2001 From: hydroconstructor <96923701+hydroconstructor@users.noreply.github.com> Date: Sun, 23 Jan 2022 23:28:07 +0400 Subject: [PATCH 1297/1435] Update doc/man/st-util.1 Co-authored-by: Grzegorz Szymaszek --- doc/man/st-util.1 | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/man/st-util.1 b/doc/man/st-util.1 index 2f718bb2b..bb2e36f5c 100644 --- a/doc/man/st-util.1 +++ b/doc/man/st-util.1 @@ -18,7 +18,6 @@ option, the default \f[B]4242\f[R] port will be used. .PP Stlink version 2 is used by default unless the option \f[B]\[en]stlinkv1\f[R] is given. -.PP .SH OPTIONS .TP .B \-h, \-\-help From 618a03a5dfe4a91d4174dba1b2bfcdcf75ae4d7d Mon Sep 17 00:00:00 2001 From: hydroconstructor Date: Sat, 29 Jan 2022 00:36:16 +0400 Subject: [PATCH 1298/1435] common c refactor Try to resolve conflicts with chipid_cleanup branch --- CHANGELOG.md | 18 +- CMakeLists.txt | 10 +- README.md | 2 +- cmake/modules/Findlibusb.cmake | 2 +- cmake/packaging/cpack_config.cmake | 2 +- cmake/packaging/deb/control | 2 +- contributors.txt | 3 - doc/compiling.md | 4 +- doc/version_support.md | 155 +- inc/stlink.h | 8 +- inc/stm32.h | 345 +- inc/stm32flash.h | 338 ++ src/calculate.c | 74 + src/calculate.h | 15 + src/common.c | 5380 ++++------------- src/common.h | 15 + src/common_flash.c | 1375 +++++ src/common_flash.h | 27 + src/flashloader.c | 482 ++ src/map_file.c | 62 + src/map_file.h | 32 + src/option.c | 1027 ++++ src/read_write.c | 143 + src/stlink-lib/chipid.h | 5 +- src/stlink-lib/usb.c | 41 +- src/stlink-lib/usb.c.bak | 1410 +++++ src/win32/unistd/unistd.h | 2 +- src/win32/unistd/unistd.h.bak | 76 + ...1\201\320\260\320\275\320\270\320\265.txt" | 129 + stlinkv1_macos_driver/install.sh | 3 + .../Contents/Info.plist | 82 + .../Contents/MacOS/stlink_shield_10_14 | Bin 0 -> 33840 bytes .../stlink_shield_10_14.kext/Contents/PkgInfo | 1 + .../Contents/_CodeSignature/CodeResources | 115 + .../stlink_shield.xcodeproj/project.pbxproj | 50 + 35 files changed, 6671 insertions(+), 4764 deletions(-) create mode 100644 inc/stm32flash.h create mode 100644 src/calculate.c create mode 100644 src/calculate.h create mode 100644 src/common.h create mode 100644 src/common_flash.c create mode 100644 src/common_flash.h create mode 100644 src/flashloader.c create mode 100644 src/map_file.c create mode 100644 src/map_file.h create mode 100644 src/option.c create mode 100644 src/read_write.c create mode 100644 src/stlink-lib/usb.c.bak create mode 100644 src/win32/unistd/unistd.h.bak create mode 100644 "src/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265.txt" create mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist create mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 create mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/PkgInfo create mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/_CodeSignature/CodeResources diff --git a/CHANGELOG.md b/CHANGELOG.md index d744ff564..06f995d21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,10 @@ # v1.7.1 -Release date: 2022-xx-xx +Release date: 2021-xx-xx This release drops support for some older operating systems. Check project README for details. - -Updated system requirements: -- `cmake` >= 3.10.2 -- `libusb` >= 1.0.21 -- `libgtk-dev` >= 3.22.30 +Updated system requirements: Raised minimum version for `cmake` to 3.7.2. Features: @@ -19,9 +15,6 @@ Features: - Expanded and revised list of chips ([#1145](https://github.com/stlink-org/stlink/pull/1145), [#1164](https://github.com/stlink-org/stlink/pull/1164)) - [STM32H72X/3X]: Added full access to all device memory ([#1158](https://github.com/stlink-org/stlink/pull/1158), [#1159](https://github.com/stlink-org/stlink/pull/1159)) - Added support for STM32WLEx ([#1173](https://github.com/stlink-org/stlink/pull/1173)) -- Added support for STLINK-V3 devices with no MSD ([#1185](https://github.com/stlink-org/stlink/pull/1185)) -- Updated gdb-server.c to allow external memory access on STM32H73xx ([#1196](https://github.com/stlink-org/stlink/pull/1196), [#1197](https://github.com/stlink-org/stlink/pull/1197)) -- Erase addr size / section of the flash memory with st-flash ([#1213](https://github.com/stlink-org/stlink/pull/1213)) Updates & changes: @@ -29,12 +22,10 @@ Updates & changes: - Added instructions for bug-reports and feature-requests to contribution guidelines ([#906](https://github.com/stlink-org/stlink/pull/906)) - Added travis CI configuration for macOS 10.14 to maintain capability for 32-bit compilation ([#f5ada94](https://github.com/stlink-org/stlink/commit/f5ada9474cdb87ff37de0d4eb9e75622b5870646)) - Updated description of chip id 0x0457 to L01x/L02x ([#1143](https://github.com/stlink-org/stlink/pull/1143), [#1144](https://github.com/stlink-org/stlink/pull/1144)) -- Dropped execute bits from source code files ([#1167](https://github.com/stlink-org/stlink/pull/1167)) +- Drop execute bits from source code files ([#1167](https://github.com/stlink-org/stlink/pull/1167)) - Use proper Markdown headers for supported MCUs ([#1168](https://github.com/stlink-org/stlink/pull/1168)) - Removed redundant array ([#1178](https://github.com/stlink-org/stlink/pull/1178)) - Updated chip config files from the library structs ([#1181](https://github.com/stlink-org/stlink/pull/1181)) -- [doc] Corrected file path in tutorial ([#1186](https://github.com/stlink-org/stlink/pull/1186)) -- Improved chipid checks and printouts ([#1188](https://github.com/stlink-org/stlink/pull/1188)) Fixes: - cmake: Install shared libraries in proper directories ([#1142](https://github.com/stlink-org/stlink/pull/1142)) @@ -50,9 +41,6 @@ Fixes: - Fixed few warnings for msvc about type conversion with possible lost data ([#1179](https://github.com/stlink-org/stlink/pull/1179)) - st-flash and other utilities search for chip files in the wrong directory ([#1180](https://github.com/stlink-org/stlink/pull/1180), commit [#c8fc656](https://github.com/stlink-org/stlink/commit/c8fc6561fead79ad49c09d82bab864745086792c)) - Fixed broken build on 32 bit systems ([#985](https://github.com/stlink-org/stlink/pull/985), [#1175](https://github.com/stlink-org/stlink/pull/1175), commit [#c8fc656](https://github.com/stlink-org/stlink/commit/c8fc6561fead79ad49c09d82bab864745086792c)) -- Define 'SSIZE_MAX' if not defined ([#1183](https://github.com/stlink-org/stlink/pull/1183)) -- Fixed compliation for OpenBSD 7.0 ([#1202](https://github.com/stlink-org/stlink/pull/1202)) -- Included 'SSIZE_MAX' from 'limits.h' in 'src/common.c' ([#1207](https://github.com/stlink-org/stlink/pull/1207)) # v1.7.0 diff --git a/CMakeLists.txt b/CMakeLists.txt index 66bf34e3e..a3338df71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # General cmake settings ### -cmake_minimum_required(VERSION 3.10.2) +cmake_minimum_required(VERSION 3.7.2) cmake_policy(SET CMP0042 NEW) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) @@ -110,6 +110,8 @@ add_subdirectory(inc) set(STLINK_HEADERS inc/backend.h inc/stlink.h + src/common_flash.h + src/calculate.h src/stlink-lib/commands.h src/stlink-lib/libusb_settings.h src/stlink-lib/reg.h @@ -123,7 +125,13 @@ set(STLINK_HEADERS ) set(STLINK_SOURCE + src/read_write.c src/common.c + src/option.c + src/common_flash.c + src/map_file.c + src/flashloader.c + src/calculate.c src/stlink-lib/chipid.c src/stlink-lib/flash_loader.c src/stlink-lib/logging.c diff --git a/README.md b/README.md index bc491189e..7f797a7d9 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ It supports several so called STLINK programmer boards (and clones thereof) whic - stand-alone programmer (STLINK-V3SET, STLINK-V3MINI, STLINK-V3MODS) - on-board on some STM32 Nucleo boards (STLINK-V3E) -_\*)_ *Note: Support for the STLINK/V1 on macOS is limited to 10.15. Due to the deprecation and removal of macOS Kernel Extensions (KEXT) there will be no support for this programmer on macOS 11 or any later version.* +_\*)_ **Note: Support for the STLINK/V1 on macOS is limited to 10.14 - 10.15. Due to the deprecation and removal of macOS Kernel Extensions (KEXT) there will be no support for this programmer on macOS 11 or any later version.** On the user level there is no difference in handling or operation between these different revisions. diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index bc04f848d..cd52026f5 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -72,7 +72,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to if (WIN32 AND NOT EXISTS "/etc/debian_version") # Skip this for Debian... # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.24) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake index 587ff5fb5..acd5630fa 100644 --- a/cmake/packaging/cpack_config.cmake +++ b/cmake/packaging/cpack_config.cmake @@ -53,7 +53,7 @@ elseif (EXISTS "/etc/debian_version" AND NOT EXISTS WIN32) # Package-build is av set(CPACK_DEBIAN_PACKAGE_RELEASE "1") # CPACK_DEBIAN_PACKAGE_ARCHITECTURE --> Default: Output of dpkg --print-architecture - set(CPACK_DEBIAN_PACKAGE_DEPENDS "pkg-config, build-essential, debhelper (>=9), cmake (>= 3.10.2), libusb-1.0-0-dev (>= 1.0.21)") + set(CPACK_DEBIAN_PACKAGE_DEPENDS "pkg-config, build-essential, debhelper (>=9), cmake (>= 3.4.2), libusb-1.0-0-dev (>= 1.0.20)") set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Nightwalker-87 ") # CPACK_DEBIAN_PACKAGE_DESCRIPTION --> Default: CPACK_DEBIAN_PACKAGE_DESCRIPTION (as it is set) # CPACK_DEBIAN_PACKAGE_SECTION --> Default: “devel” diff --git a/cmake/packaging/deb/control b/cmake/packaging/deb/control index 7c8d13e47..ef51a6cea 100644 --- a/cmake/packaging/deb/control +++ b/cmake/packaging/deb/control @@ -1,7 +1,7 @@ Source: stlink Priority: optional Maintainer: Nightwalker-87 -Build-Depends: cmake (>= 3.10.2), dh-cmake, debhelper (>= 9), libusb-1.0-0-dev (>= 1.0.21), libgtk-3-dev (>= 3.22.30) +Build-Depends: cmake, dh-cmake, debhelper (>= 9), libusb-1.0-0-dev, libgtk-3-dev Standards-Version: 4.5.0 Rules-Requires-Root: no Section: electronics diff --git a/contributors.txt b/contributors.txt index cffef89f6..bcaa0b538 100644 --- a/contributors.txt +++ b/contributors.txt @@ -7,8 +7,6 @@ Andrea Mucignat Andrew Andrianov [necromant] Andrey Yurovsky Andy Isaacson -Andreas Sandberg [andysan] -Antoine Faure [antoinefaure] Anton [Ant-ON] Áron Radics A. Sheaff @@ -26,7 +24,6 @@ Chris Samuelson Christian Deussen [nullsub] Christophe Levantis Craig Lilley -Crest [Crest] Dan Dev Dan Hepler Daniel Campoverde [alx741] diff --git a/doc/compiling.md b/doc/compiling.md index 0931c278a..eef207f95 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -7,7 +7,7 @@ On Windows users should ensure that the following software is installed: - `git` (_optional, but recommended_) -- `cmake` +- `cmake` (3.17.0 or later) - `MinGW-w64` (7.0.0 or later) with GCC toolchain 8.1.0 ### Installation @@ -95,7 +95,7 @@ Install the following packages from your package repository: - `git` - `gcc` or `clang` or `mingw32-gcc` or `mingw64-gcc` (C-compiler; very likely gcc is already present) - `build-essential` (on Debian based distros (Debian, Ubuntu)) -- `cmake` +- `cmake` (3.4.2 or later, use the latest version available from the repository) - `rpm` (on Debian based distros (Debian, Ubuntu), needed for package build with `make package`) - `libusb-1.0` - `libusb-1.0-0-dev` (development headers for building) diff --git a/doc/version_support.md b/doc/version_support.md index d7ba5c102..2c5df7461 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -1,104 +1,97 @@ -_Source:_ [pkgs.org](https://pkgs.org/search) - libusb, cmake, gtk, libgtk) (as of Jan 2022) +_Source:_ pkgs.org - [libusb](https://pkgs.org/search/?q=libusb); [cmake](https://pkgs.org/search/?q=cmake); [gtk](https://pkgs.org/search/?q=gtk) (as of May 2021) ## Supported Operating Systems ### Microsoft Windows -On Windows users should ensure that cmake **3.10.2** or any later version is installed.
      -Up on compiling c-make will **automatically** download and install the latest compatible version of `libusb`. +On Windows users should ensure that cmake 3.20.2 or any later version is installed.
      +Up on compiling c-make will **automatically** download and install the latest compatible version of `libusb` (1.0.23 at the time of writing). - Windows 10 - Windows 8.1 ### Apple macOS -| Package Repository | libusb | cmake | gtk-3-dev | Supported macOS versions | -| ------------------ | ------ | ------ | ------------------ | ------------------------ | -| homebrew | 1.0.24 | 3.22.1 | 3.24.30
      gtk+3 | **10.10 - 12.x** | -| MacPorts | 1.0.24 | 3.22.1 | 3.24.31
      gtk3 | **10.4 - 12.x** | +| Package Repository | libusb
      version | cmake
      version | gtk-3
      version | Supported macOS versions | +| ------------------ | ------------------- | ------------------ | ------------------ | ------------------------ | +| homebrew | 1.0.24 | 3.20.2 | 3.24.29
      gtk+3 | 10.9 - 11.x | +| MacPorts | 1.0.24 | 3.20.2 | 3.24.29
      gtk3 | 10.4 - 11.x | -NOTE: In order to use a STLINK/V1 programmer on macOS, version 10.15 is required. +NOTE: In order to use a STLINK/V1 programmer on macOS, versions 10.14 or 10.15 are required. ### Linux-/Unix-based: -| Operating System | libusb | cmake | libgtk-dev | Notes | -| ------------------------- | ------------------------------ | ---------- | ----------- | ------------------------ | -| Debian Sid | 1.0.24 | 3.22.1 | 3.24.31 | | -| Debian 11 (Bullseye) | 1.0.24 | 3.18.4 | 3.24.24 | | -| Debian 10 (Buster) | 1.0.**22** | **3.13.4** | 3.24.**5** | | -| | | | | | -| Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.16.3 | 3.24.**18** | | -| Ubuntu 18.04 LTS (Bionic) | 1.0.**21** | **3.10.2** | 3.**22.30** | End of Support: Apr 2023 | -| | | | | | -| Fedora Rawhide [x64] | 1.0.24 | 3.22.3 | 3.24.31 | | -| Fedora 35 [x64] | 1.0.24 | 3.21.3 | 3.24.30 | | -| Fedora 34 [x64] | 1.0.24 (`libusbx`) | 3.19.7 | 3.24.28 | | -| | | | | | -| openSUSE Tumbleweed [x64] | 1.0.24 | 3.22.1 | 3.24.31 | | -| openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.17.0 | 3.24.20 | End of Support: Dec 2022 | -| | | | | | -| Alpine 3.15 | 1.0.24 | 3.21.3 | 3.24.30 | | -| Alpine 3.14 | 1.0.24 | 3.20.3 | 3.24.28 | | -| Alpine 3.13 | 1.0.24 | 3.18.4 | 3.24.23 | End of Support: Nov 2022 | -| Alpine 3.12 | 1.0.23 | 3.17.2 | 3.24.22 | End of Support: May 2022 | -| | | | | | -| FreeBSD 13.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | -| FreeBSD 12.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | -| | | | | | -| NetBSD 9.x | 1.0.24 | 3.21.2 | 3.24.30 | | -| NetBSD 8.x | 1.0.24 | 3.19.7 | 3.24.27 | | -| | | | | | -| CentOS 9 Stream [x64] | 1.0.24 (`libusbx`) | 3.20.3 | 3.24.30 | | -| CentOS 8 Stream [x64] | 1.0.23 (`libusbx`) | 3.20.2 | 3.**22.30** | | -| | | | | | -| ALT Linux Sisyphus | 1.0.24 | 3.22.1 | 3.24.31 | | -| ALT Linux P10 | 1.0.24 | 3.20.5 | 3.24.31 | | -| ALT Linux P9 | 1.0.**22** | 3.16.3 | 3.24.29 | | -| | | | | | -| OpenMandriva Rolling | 1.0.24 | 3.22.1 | 3.24.31 | | -| OpenMandriva Cooker | 1.0.24 | 3.22.1 | 3.24.31 | | -| OpenMandriva Lx 4.2 | 1.0.24 | 3.19.3 | 3.24.24 | | -| | | | | | -| Arch Linux | 1.0.24 | 3.22.1 | - | | -| KaOS [x64] | 1.0.24 | 3.22.1 | 3.24.31 | | -| Mageia Cauldron | 1.0.24 | 3.22.1 | 3.24.31 | | -| PCLinuxOS [x64] | ? | 3.22.1 | 3.24.31 | | -| Solus [x64] | 1.0.24 | 3.22.1 | 3.24.30 | | -| Void Linux | 1.0.24 | 3.22.1 | 3.24.31 | | -| Slackware Current | 1.0.24 | 3.21.4 | 3.24.31 | | -| AlmaLinux 8 | 1.0.23 (`libusbx`) | 3.20.2 | 3.**22.30** | | -| Rocky Linux 8 [x64] | 1.0.23 | 3.20.2 | 3.**22.30** | | -| Mageia 8 | 1.0.24 | 3.19.2 | 3.24.24 | End of Support: Aug 2022 | -| Adélie 1.0 | 1.0.23 | 3.16.4 | 3.24.23 | | +| Operating System | libusb | cmake | gtk-3 | Notes | +| ------------------------- | -------------------------------- | --------- | ----------- | ------------------------ | +| Debian Sid | 1.0.24 | 3.18.4 | 3.24.24 | | +| Debian 11 (Bullseye) | 1.0.24 | 3.18.4 | 3.24.24 | | +| Debian 10 (Buster) | 1.0.**22** | 3.13.4 | 3.24.**5** | | +| Debian 9 (Stretch) | 1.0.**21** | **3.7.2** | **3.22.11** | End of Support: Jun 2022 | +| | | | | | +| Ubuntu 21.04 (Hirsute) | 1.0.24 | 3.18.4 | 3.24.25 | End of Support: Jan 2022 | +| Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.16.3 | 3.24.**18** | | +| Ubuntu 18.04 LTS (Bionic) | 1.0.**21** | 3.10.2 | **3.22.30** | End of Support: Apr 2023 | +| | | | | | +| Fedora Rawhide [x64] | 1.0.24 (`libusbx`) | 3.20.2 | 3.24.29 | | +| Fedora 34 [x64] | 1.0.24 (`libusbx`) | 3.19.7 | 3.24.28 | | +| Fedora 33 [x64] | 1.0.23 (`libusbx`) | 3.18.3 | 3.24.23 | | +| | | | | | +| openSUSE Tumbleweed [x64] | 1.0.24 | 3.20.1 | 3.24.29 | | +| openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.17.0 | 3.24.20 | | +| openSUSE Leap 15.2 [x64] | 1.0.**21** | 3.17.0 | 3.24.**14** | End of Support: Dec 2021 | +| | | | | | +| Alpine 3.14 | 1.0.24 | 3.20.3 | 4.2.1 | | +| Alpine 3.13 | 1.0.24 | 3.18.4 | 3.24.23 | End of Support: Nov 2022 | +| Alpine 3.12 | 1.0.23 | 3.17.2 | 3.24.22 | End of Support: May 2022 | +| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.**13** | End of Support: Nov 2021 | +| | | | | | +| FreeBSD 13.x | 1.0.**16 - 18** (API 0x01000102) | 3.20.2 | 3.24.27 | | +| FreeBSD 12.x | 1.0.**16 - 18** (API 0x01000102) | 3.19.6 | 3.24.27 | | +| FreeBSD 11.x | 1.0.**16 - 18** (API 0x01000102) | 3.15.5 | 3.24.27 | End of Support: Sep 2021 | +| | | | | | +| Arch Linux | 1.0.24 | 3.20.2 | 3.24.29 | | +| KaOS [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | +| Mageia Cauldron | 1.0.24 | 3.20.2 | 3.24.29 | | +| OpenMandriva Cooker | 1.0.24 | 3.20.2 | 3.24.29 | | +| PCLinuxOS [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | +| Slackware Current | 1.0.24 | 3.20.2 | 3.24.28 | | +| Solus [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | +| ALT Linux Sisyphus | 1.0.24 | 3.19.7 | 3.24.29 | | +| NetBSD 9.x | 1.0.24 | 3.19.7 | 3.24.27 | | +| NetBSD 8.x | 1.0.24 | 3.19.7 | 3.24.27 | | +| OpenMandriva Lx 4.2 | 1.0.24 | 3.19.3 | 3.24.24 | | +| Mageia 8 | 1.0.24 | 3.19.2 | 3.24.24 | End of Support: Aug 2022 | +| CentOS 8 Stream [x64] | 1.0.23 (`libusbx`) | 3.18.2 | **3.22.30** | | +| Adélie 1.0 | 1.0.23 | 3.16.4 | 3.24.23 | | +| ALT Linux P9 | 1.0.**22** | 3.16.3 | 3.24.**11** | | +| AlmaLinux 8 | 1.0.23 (`libusbx`) | 3.11.4 | 3.24.32 | | +| CentOS 8 [x64] | 1.0.23 (`libusbx`) | 3.11.4 | **3.22.30** | End of Support: Dec 2021 | ## Unsupported Operating Systems (as of Release v1.7.1) Systems with highlighted versions remain compatible with this toolset. -| Operating System | libusb | cmake | End of
      OS-Support | -| ------------------------ | ------------------------------ | ---------- | ---------------------- | -| CentOS 8 [x64] | 1.0.**23** (`libusbx`) | 3.**20.3** | Dec 2021 | -| Ubuntu 21.04 (Hirsute) | 1.0.**24** | 3.**18.4** | Jan 2022 | -| Fedora 33 [x64] | 1.0.**23** (`libusbx`) | 3.**18.3** | Nov 2021 | -| Fedora 32 [x64] | 1.0.**23** (`libusbx`) | 3.**17.0** | May 2021 | -| openSUSE Leap 15.2 [x64] | 1.0.**21** | 3.**17.0** | Dec 2021 | -| Ubuntu 20.10 (Groovy) | 1.0.**23** | 3.**16.3** | Jul 2021 | -| NetBSD 7.x | 1.0.**22** | 3.**16.1** | Jun 2020 | -| Alpine 3.11 | 1.0.**23** | 3.**15.5** | Nov 2021 | -| FreeBSD 11.x | 1.0.**16-18** (API 0x01000102) | 3.**15.5** | Sep 2021 | -| Alpine 3.10 | 1.0.**22** | 3.**14.5** | May 2021 | -| Fedora 31 [x64] | 1.0.**22**(`libusbx`) | 3.**14.5** | Nov 2020 | -| Mageia 7.1 | 1.0.**22** | 3.**14.3** | Jun 2021 | -| Fedora 30 | 1.0.**22**(`libusbx`) | 3.**14.2** | May 2020 | -| Ubuntu 19.10 (Eoan) | 1.0.**23** | 3.**13.4** | Jul 2020 | -| Alpine 3.9 | 1.0.**22** | 3.**13.0** | Jan 2021 | -| openSUSE Leap 15.1 [x64] | 1.0.**21** | 3.**10.2** | Jan 2021 | -| Debian 9 (Stretch) | 1.0.**21** | 3.7.2 | Jun 2022 | -| Slackware 14.2 | 1.0.20 | 3.5.2 | | -| OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | | -| CentOS 7 [x64] | 1.0.**21** (`libusbx`) | 2.8.12.2 | Jun 2024 | -| Slackware 14.1 | 1.0.9 | 2.8.12 | | -| Slackware 14.0 | 1.0.9 | 2.8.8 | | +| Operating System | libusb | cmake | End of
      OS-Support | +| ------------------------- | ---------------------- | ---------- | ---------------------- | +| Fedora 32 [x64] | **1.0.23** (`libusbx`) | **3.17.0** | May 2021 | +| Ubuntu 20.10 (Groovy) | **1.0.23** | **3.16.3** | Jul 2021 | +| NetBSD 7.x | **1.0.22** | **3.16.1** | Jun 2020 | +| Alpine 3.10 | **1.0.22** | **3.14.5** | May 2021 | +| Fedora 31 [x64] | **1.0.22** (`libusbx`) | **3.14.5** | Nov 2020 | +| Mageia 7.1 | **1.0.22** | **3.14.3** | Jun 2021 | +| Fedora 30 | **1.0.22** (`libusbx`) | **3.14.2** | May 2020 | +| Ubuntu 19.10 (Eoan) | **1.0.23** | **3.13.4** | Jul 2020 | +| Alpine 3.9 | **1.0.22** | **3.13.0** | Jan 2021 | +| openSUSE Leap 15.1 [x64] | **1.0.21** | **3.10.2** | Jan 2021 | +| Slackware 14.2 | 1.0.20 | 3.5.2 | | +| Ubuntu 16.04 LTS (Xenial) | 1.0.20 | 3.5.1 | Apr 2021 | +| OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | | +| Debian 8 (Jessie) | 1.0.19 | 3.0.2 | Jun 2020 | +| CentOS 7 [x64] | 1.0.21 (`libusbx`) | 2.8.12.2 | Jun 2024 | +| Ubuntu 14.04 LTS (Trusty) | 1.0.17 | 2.8.12.2 | Apr 2019 | +| CentOS 6 | 1.0.9 (`libusbx`) | 2.8.12.2 | Nov 2020 | +| Slackware 14.1 | 1.0.9 | 2.8.12 | | +| Slackware 14.0 | 1.0.9 | 2.8.8 | | _All other operating systems which are not listed are unsupported._ diff --git a/inc/stlink.h b/inc/stlink.h index 2d0fa5007..e3fd632f2 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -1,6 +1,5 @@ /* * File: stlink.h - * * This should contain all the common top level stlink interfaces, * regardless of how the backend does the work.... */ @@ -13,6 +12,7 @@ #include #include "stm32.h" +#include "stm32flash.h" #ifdef __cplusplus extern "C" { @@ -183,7 +183,7 @@ enum run_type { typedef struct _stlink stlink_t; -#include +#include // Is it really need? #include struct _stlink { @@ -274,7 +274,7 @@ int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, stm32_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); -int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); +//int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); @@ -282,7 +282,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); int stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size); int stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr); uint16_t read_uint16(const unsigned char *c, const int pt); -void stlink_core_stat(stlink_t *sl); +//void stlink_core_stat(stlink_t *sl); void stlink_print_data(stlink_t *sl); unsigned int is_bigendian(void); uint32_t read_uint32(const unsigned char *c, const int pt); diff --git a/inc/stm32.h b/inc/stm32.h index d6bbe506c..19ba3fca0 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -149,345 +149,11 @@ enum stm32_chipids { /* ============ */ /* Constant STM32 memory address */ -#define STM32_SRAM_BASE ((uint32_t)0x20000000) -#define STM32_FLASH_BASE ((uint32_t)0x08000000) +#define STM32_SRAM_BASE ((uint32_t)0x20000000) +#define STM32_FLASH_BASE ((uint32_t)0x08000000) -#define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) -#define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) - -/* stm32f FPEC flash controller interface, pm0063 manual */ -// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, August 2012) -#define FLASH_REGS_ADDR 0x40022000 -#define FLASH_REGS_SIZE 0x28 - -#define FLASH_ACR (FLASH_REGS_ADDR + 0x00) -#define FLASH_KEYR (FLASH_REGS_ADDR + 0x04) -#define FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x08) -#define FLASH_SR (FLASH_REGS_ADDR + 0x0c) -#define FLASH_CR (FLASH_REGS_ADDR + 0x10) -#define FLASH_AR (FLASH_REGS_ADDR + 0x14) -#define FLASH_OBR (FLASH_REGS_ADDR + 0x1c) -#define FLASH_WRPR (FLASH_REGS_ADDR + 0x20) - -// STM32F10x_XL has two flash memory banks with separate registers to control -// the second bank. -#define FLASH_KEYR2 (FLASH_REGS_ADDR + 0x44) -#define FLASH_SR2 (FLASH_REGS_ADDR + 0x4c) -#define FLASH_CR2 (FLASH_REGS_ADDR + 0x50) -#define FLASH_AR2 (FLASH_REGS_ADDR + 0x54) - -// For STM32F05x, the RDPTR_KEY may be wrong, but as it is not used anywhere... -#define FLASH_RDPTR_KEY 0x00a5 -#define FLASH_KEY1 0x45670123 -#define FLASH_KEY2 0xcdef89ab - -#define FLASH_L0_PRGKEY1 0x8c9daebf -#define FLASH_L0_PRGKEY2 0x13141516 - -#define FLASH_L0_PEKEY1 0x89abcdef -#define FLASH_L0_PEKEY2 0x02030405 - -#define FLASH_OPTKEY1 0x08192A3B -#define FLASH_OPTKEY2 0x4C5D6E7F - -#define FLASH_F0_OPTKEY1 0x45670123 -#define FLASH_F0_OPTKEY2 0xCDEF89AB - -#define FLASH_L0_OPTKEY1 0xFBEAD9C8 -#define FLASH_L0_OPTKEY2 0x24252627 - -#define FLASH_SR_BSY 0 -#define FLASH_SR_PG_ERR 2 -#define FLASH_SR_WRPRT_ERR 4 -#define FLASH_SR_EOP 5 - -#define FLASH_SR_ERROR_MASK ((1 << FLASH_SR_PG_ERR) | (1 << FLASH_SR_WRPRT_ERR)) - -#define FLASH_CR_PG 0 -#define FLASH_CR_PER 1 -#define FLASH_CR_MER 2 -#define FLASH_CR_OPTPG 4 -#define FLASH_CR_OPTER 5 -#define FLASH_CR_STRT 6 -#define FLASH_CR_LOCK 7 -#define FLASH_CR_OPTWRE 9 -#define FLASH_CR_OBL_LAUNCH 13 - -#define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00) -#define STM32L_FLASH_ACR (STM32L_FLASH_REGS_ADDR + 0x00) -#define STM32L_FLASH_PECR (STM32L_FLASH_REGS_ADDR + 0x04) -#define STM32L_FLASH_PDKEYR (STM32L_FLASH_REGS_ADDR + 0x08) -#define STM32L_FLASH_PEKEYR (STM32L_FLASH_REGS_ADDR + 0x0c) -#define STM32L_FLASH_PRGKEYR (STM32L_FLASH_REGS_ADDR + 0x10) -#define STM32L_FLASH_OPTKEYR (STM32L_FLASH_REGS_ADDR + 0x14) -#define STM32L_FLASH_SR (STM32L_FLASH_REGS_ADDR + 0x18) -#define STM32L_FLASH_OBR (STM32L_FLASH_REGS_ADDR + 0x1c) -#define STM32L_FLASH_WRPR (STM32L_FLASH_REGS_ADDR + 0x20) -#define FLASH_L1_FPRG 10 -#define FLASH_L1_PROG 3 - -// Flash registers common to STM32G0 and STM32G4 series. -#define STM32Gx_FLASH_REGS_ADDR ((uint32_t)0x40022000) -#define STM32Gx_FLASH_ACR (STM32Gx_FLASH_REGS_ADDR + 0x00) -#define STM32Gx_FLASH_KEYR (STM32Gx_FLASH_REGS_ADDR + 0x08) -#define STM32Gx_FLASH_OPTKEYR (STM32Gx_FLASH_REGS_ADDR + 0x0c) -#define STM32Gx_FLASH_SR (STM32Gx_FLASH_REGS_ADDR + 0x10) -#define STM32Gx_FLASH_CR (STM32Gx_FLASH_REGS_ADDR + 0x14) -#define STM32Gx_FLASH_ECCR (STM32Gx_FLASH_REGS_ADDR + 0x18) -#define STM32Gx_FLASH_OPTR (STM32Gx_FLASH_REGS_ADDR + 0x20) - -// G0 (RM0444 Table 1, sec 3.7) -// Mostly the same as G4 chips, but the notation -// varies a bit after the 'OPTR' register. -#define STM32G0_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) -#define STM32G0_FLASH_PCROP1ASR (STM32G0_FLASH_REGS_ADDR + 0x24) -#define STM32G0_FLASH_PCROP1AER (STM32G0_FLASH_REGS_ADDR + 0x28) -#define STM32G0_FLASH_WRP1AR (STM32G0_FLASH_REGS_ADDR + 0x2C) -#define STM32G0_FLASH_WRP1BR (STM32G0_FLASH_REGS_ADDR + 0x30) -#define STM32G0_FLASH_PCROP1BSR (STM32G0_FLASH_REGS_ADDR + 0x34) -#define STM32G0_FLASH_PCROP1BER (STM32G0_FLASH_REGS_ADDR + 0x38) -#define STM32G0_FLASH_SECR (STM32G0_FLASH_REGS_ADDR + 0x80) - -// G4 (RM0440 Table 17, sec 3.7.19) -// Mostly the same as STM32G0 chips, but there are a few extra -// registers because 'cat 3' devices can have two Flash banks. -#define STM32G4_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) -#define STM32G4_FLASH_PDKEYR (STM32G4_FLASH_REGS_ADDR + 0x04) -#define STM32G4_FLASH_PCROP1SR (STM32G4_FLASH_REGS_ADDR + 0x24) -#define STM32G4_FLASH_PCROP1ER (STM32G4_FLASH_REGS_ADDR + 0x28) -#define STM32G4_FLASH_WRP1AR (STM32G4_FLASH_REGS_ADDR + 0x2C) -#define STM32G4_FLASH_WRP1BR (STM32G4_FLASH_REGS_ADDR + 0x30) -#define STM32G4_FLASH_PCROP2SR (STM32G4_FLASH_REGS_ADDR + 0x44) -#define STM32G4_FLASH_PCROP2ER (STM32G4_FLASH_REGS_ADDR + 0x48) -#define STM32G4_FLASH_WRP2AR (STM32G4_FLASH_REGS_ADDR + 0x4C) -#define STM32G4_FLASH_WRP2BR (STM32G4_FLASH_REGS_ADDR + 0x50) -#define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70) -#define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74) - -// G0/G4 FLASH control register -#define STM32Gx_FLASH_CR_PG (0) /* Program */ -#define STM32Gx_FLASH_CR_PER (1) /* Page erase */ -#define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */ -#define STM32Gx_FLASH_CR_PNB (3) /* Page number */ -#define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ -#define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ -#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ -#define STM32Gx_FLASH_CR_STRT (16) /* Start */ -#define STM32Gx_FLASH_CR_OPTSTRT \ - (17) /* Start of modification of option bytes */ -#define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ -#define STM32Gx_FLASH_CR_EOPIE (24) /* End of operation interrupt enable */ -#define STM32Gx_FLASH_CR_ERRIE (25) /* Error interrupt enable */ -#define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ -#define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ -#define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ - -// G0/G4 FLASH status register -#define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) -#define STM32Gx_FLASH_SR_PROGERR (3) -#define STM32Gx_FLASH_SR_WRPERR (4) -#define STM32Gx_FLASH_SR_PGAERR (5) -#define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ -#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ - -// G4 FLASH option register -#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ - -// WB (RM0434) -#define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) -#define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) -#define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) -#define STM32WB_FLASH_OPT_KEYR (STM32WB_FLASH_REGS_ADDR + 0x0C) -#define STM32WB_FLASH_SR (STM32WB_FLASH_REGS_ADDR + 0x10) -#define STM32WB_FLASH_CR (STM32WB_FLASH_REGS_ADDR + 0x14) -#define STM32WB_FLASH_ECCR (STM32WB_FLASH_REGS_ADDR + 0x18) -#define STM32WB_FLASH_OPTR (STM32WB_FLASH_REGS_ADDR + 0x20) -#define STM32WB_FLASH_PCROP1ASR (STM32WB_FLASH_REGS_ADDR + 0x24) -#define STM32WB_FLASH_PCROP1AER (STM32WB_FLASH_REGS_ADDR + 0x28) -#define STM32WB_FLASH_WRP1AR (STM32WB_FLASH_REGS_ADDR + 0x2C) -#define STM32WB_FLASH_WRP1BR (STM32WB_FLASH_REGS_ADDR + 0x30) -#define STM32WB_FLASH_PCROP1BSR (STM32WB_FLASH_REGS_ADDR + 0x34) -#define STM32WB_FLASH_PCROP1BER (STM32WB_FLASH_REGS_ADDR + 0x38) -#define STM32WB_FLASH_IPCCBR (STM32WB_FLASH_REGS_ADDR + 0x3C) -#define STM32WB_FLASH_C2ACR (STM32WB_FLASH_REGS_ADDR + 0x5C) -#define STM32WB_FLASH_C2SR (STM32WB_FLASH_REGS_ADDR + 0x60) -#define STM32WB_FLASH_C2CR (STM32WB_FLASH_REGS_ADDR + 0x64) -#define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) -#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) - -// WB Flash control register. -#define STM32WB_FLASH_CR_STRT (16) /* Start */ -#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ -#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ -// WB Flash status register. -#define STM32WB_FLASH_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ -#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ -#define STM32WB_FLASH_SR_WRPERR (4) /* Write protection error */ -#define STM32WB_FLASH_SR_PGAERR (5) /* Programming error */ -#define STM32WB_FLASH_SR_BSY (16) /* Busy */ - -// 32L4 register base is at FLASH_REGS_ADDR (0x40022000) -#define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) -#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) -#define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) -#define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) -#define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) - -#define STM32L4_FLASH_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ -#define STM32L4_FLASH_SR_PROGERR 3 -#define STM32L4_FLASH_SR_WRPERR 4 -#define STM32L4_FLASH_SR_PGAERR 5 -#define STM32L4_FLASH_SR_BSY 16 - -#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ -#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ -#define STM32L4_FLASH_CR_PG 0 /* Program */ -#define STM32L4_FLASH_CR_PER 1 /* Page erase */ -#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ -#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ -#define STM32L4_FLASH_CR_STRT 16 /* Start command */ -#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ -#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ -#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ -#define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ -// Bits requesting flash operations (useful when we want to clear them) -#define STM32L4_FLASH_CR_OPBITS \ - (uint32_t)((1lu << STM32L4_FLASH_CR_PG) | (1lu << STM32L4_FLASH_CR_PER) | \ - (1lu << STM32L4_FLASH_CR_MER1) | (1lu << STM32L4_FLASH_CR_MER1)) -// Page is fully specified by BKER and PNB -#define STM32L4_FLASH_CR_PAGEMASK (uint32_t)(0x1fflu << STM32L4_FLASH_CR_PNB) - -#define STM32L4_FLASH_OPTR_DUALBANK 21 - -// STM32L0x flash register base and offsets RM0090 - DM00031020.pdf -#define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) - -#define STM32L0_FLASH_PELOCK (0) -#define STM32L0_FLASH_OPTLOCK (2) -#define STM32L0_FLASH_OBL_LAUNCH (18) - -#define STM32L0_FLASH_SR_ERROR_MASK 0x00013F00 -#define STM32L0_FLASH_SR_WRPERR 8 -#define STM32L0_FLASH_SR_PGAERR 9 -#define STM32L0_FLASH_SR_NOTZEROERR 16 - -#define FLASH_ACR_OFF ((uint32_t)0x00) -#define FLASH_PECR_OFF ((uint32_t)0x04) -#define FLASH_PDKEYR_OFF ((uint32_t)0x08) -#define FLASH_PEKEYR_OFF ((uint32_t)0x0c) -#define FLASH_PRGKEYR_OFF ((uint32_t)0x10) -#define FLASH_OPTKEYR_OFF ((uint32_t)0x14) -#define FLASH_SR_OFF ((uint32_t)0x18) -#define FLASH_OBR_OFF ((uint32_t)0x1c) -#define FLASH_WRPR_OFF ((uint32_t)0x20) - -// STM32F7 -#define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) -#define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) -#define FLASH_F7_SR (FLASH_F7_REGS_ADDR + 0x0c) -#define FLASH_F7_CR (FLASH_F7_REGS_ADDR + 0x10) -#define FLASH_F7_OPTCR (FLASH_F7_REGS_ADDR + 0x14) -#define FLASH_F7_OPTCR1 (FLASH_F7_REGS_ADDR + 0x18) -#define FLASH_F7_OPTCR_LOCK 0 -#define FLASH_F7_OPTCR_START 1 -#define FLASH_F7_CR_STRT 16 -#define FLASH_F7_CR_LOCK 31 -#define FLASH_F7_CR_SER 1 -#define FLASH_F7_CR_SNB 3 -#define FLASH_F7_CR_SNB_MASK 0xf8 -#define FLASH_F7_SR_BSY 16 -#define FLASH_F7_SR_ERS_ERR 7 /* Erase Sequence Error */ -#define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ -#define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ -#define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ -#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ -#define FLASH_F7_SR_EOP 0 /* End of operation */ -#define FLASH_F7_OPTCR1_BOOT_ADD0 0 -#define FLASH_F7_OPTCR1_BOOT_ADD1 16 - -#define FLASH_F7_SR_ERROR_MASK \ - ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | \ - (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | \ - (1 << FLASH_F7_SR_OP_ERR)) - -// STM32F4 -#define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) -#define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08) -#define FLASH_F4_SR (FLASH_F4_REGS_ADDR + 0x0c) -#define FLASH_F4_CR (FLASH_F4_REGS_ADDR + 0x10) -#define FLASH_F4_OPTCR (FLASH_F4_REGS_ADDR + 0x14) -#define FLASH_F4_OPTCR_LOCK 0 -#define FLASH_F4_OPTCR_START 1 -#define FLASH_F4_CR_STRT 16 -#define FLASH_F4_CR_LOCK 31 -#define FLASH_F4_CR_SER 1 -#define FLASH_F4_CR_SNB 3 -#define FLASH_F4_CR_SNB_MASK 0xf8 -#define FLASH_F4_SR_ERROR_MASK 0x000000F0 -#define FLASH_F4_SR_PGAERR 5 -#define FLASH_F4_SR_WRPERR 4 -#define FLASH_F4_SR_BSY 16 - -// STM32F2 -#define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F2_KEYR (FLASH_F2_REGS_ADDR + 0x04) -#define FLASH_F2_OPT_KEYR (FLASH_F2_REGS_ADDR + 0x08) -#define FLASH_F2_SR (FLASH_F2_REGS_ADDR + 0x0c) -#define FLASH_F2_CR (FLASH_F2_REGS_ADDR + 0x10) -#define FLASH_F2_OPT_CR (FLASH_F2_REGS_ADDR + 0x14) -#define FLASH_F2_OPT_LOCK_BIT (1u << 0) -#define FLASH_F2_CR_STRT 16 -#define FLASH_F2_CR_LOCK 31 - -#define FLASH_F2_CR_SER 1 -#define FLASH_F2_CR_SNB 3 -#define FLASH_F2_CR_SNB_MASK 0x78 -#define FLASH_F2_SR_BSY 16 - -// STM32H7xx -#define FLASH_H7_CR_LOCK 0 -#define FLASH_H7_CR_PG 1 -#define FLASH_H7_CR_SER 2 -#define FLASH_H7_CR_BER 3 -#define FLASH_H7_CR_PSIZE 4 -#define FLASH_H7_CR_START(chipid) (chipid == STM32_CHIPID_H7Ax ? 5 : 7) -#define FLASH_H7_CR_SNB 8 -#define FLASH_H7_CR_SNB_MASK 0x700 - -#define FLASH_H7_SR_QW 2 -#define FLASH_H7_SR_WRPERR 17 -#define FLASH_H7_SR_PGSERR 18 -#define FLASH_H7_SR_STRBERR 19 -#define FLASH_H7_SR_ERROR_MASK \ - ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | \ - (1 << FLASH_H7_SR_WRPERR)) - -#define FLASH_H7_OPTCR_OPTLOCK 0 -#define FLASH_H7_OPTCR_OPTSTART 1 -#define FLASH_H7_OPTCR_MER 4 - -#define FLASH_H7_OPTSR_OPT_BUSY 0 -#define FLASH_H7_OPTSR_OPTCHANGEERR 30 - -#define FLASH_H7_OPTCCR_CLR_OPTCHANGEERR 30 - -#define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) -#define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) -#define FLASH_H7_KEYR2 (FLASH_H7_REGS_ADDR + 0x104) -#define FLASH_H7_OPT_KEYR (FLASH_H7_REGS_ADDR + 0x08) -#define FLASH_H7_OPT_KEYR2 (FLASH_H7_REGS_ADDR + 0x108) -#define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c) -#define FLASH_H7_CR2 (FLASH_H7_REGS_ADDR + 0x10c) -#define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) -#define FLASH_H7_SR2 (FLASH_H7_REGS_ADDR + 0x110) -#define FLASH_H7_CCR1 (FLASH_H7_REGS_ADDR + 0x14) -#define FLASH_H7_CCR2 (FLASH_H7_REGS_ADDR + 0x114) -#define FLASH_H7_OPTCR (FLASH_H7_REGS_ADDR + 0x18) -#define FLASH_H7_OPTCR2 (FLASH_H7_REGS_ADDR + 0x118) -#define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) -#define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) +#define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) +#define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) #define STM32F0_DBGMCU_CR 0xE0042004 #define STM32F0_DBGMCU_CR_IWDG_STOP 8 @@ -529,7 +195,4 @@ enum stm32_chipids { #define STM32WB_RCC_AHB1ENR 0x58000048 #define STM32WB_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN -#define L1_WRITE_BLOCK_SIZE 0x80 -#define L0_WRITE_BLOCK_SIZE 0x40 - #endif // STM32_H diff --git a/inc/stm32flash.h b/inc/stm32flash.h new file mode 100644 index 000000000..c28d67c28 --- /dev/null +++ b/inc/stm32flash.h @@ -0,0 +1,338 @@ +#ifndef STM32FLASH_H +#define STM32FLASH_H + +/* stm32f FPEC flash controller interface, pm0063 manual */ +// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, August 2012) +#define FLASH_REGS_ADDR 0x40022000 +#define FLASH_REGS_SIZE 0x28 + +#define FLASH_ACR (FLASH_REGS_ADDR + 0x00) +#define FLASH_KEYR (FLASH_REGS_ADDR + 0x04) +#define FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x08) +#define FLASH_SR (FLASH_REGS_ADDR + 0x0c) +#define FLASH_CR (FLASH_REGS_ADDR + 0x10) +#define FLASH_AR (FLASH_REGS_ADDR + 0x14) +#define FLASH_OBR (FLASH_REGS_ADDR + 0x1c) +#define FLASH_WRPR (FLASH_REGS_ADDR + 0x20) + +// STM32F10x_XL has two flash memory banks with separate registers to control +// the second bank. +#define FLASH_KEYR2 (FLASH_REGS_ADDR + 0x44) +#define FLASH_SR2 (FLASH_REGS_ADDR + 0x4c) +#define FLASH_CR2 (FLASH_REGS_ADDR + 0x50) +#define FLASH_AR2 (FLASH_REGS_ADDR + 0x54) + +// For STM32F05x, the RDPTR_KEY may be wrong, but as it is not used anywhere... +#define FLASH_RDPTR_KEY 0x00a5 +#define FLASH_KEY1 0x45670123 +#define FLASH_KEY2 0xcdef89ab + +#define FLASH_L0_PRGKEY1 0x8c9daebf +#define FLASH_L0_PRGKEY2 0x13141516 + +#define FLASH_L0_PEKEY1 0x89abcdef +#define FLASH_L0_PEKEY2 0x02030405 + +#define FLASH_OPTKEY1 0x08192A3B +#define FLASH_OPTKEY2 0x4C5D6E7F + +#define FLASH_F0_OPTKEY1 0x45670123 +#define FLASH_F0_OPTKEY2 0xCDEF89AB + +#define FLASH_L0_OPTKEY1 0xFBEAD9C8 +#define FLASH_L0_OPTKEY2 0x24252627 + +#define FLASH_SR_BSY 0 +#define FLASH_SR_PG_ERR 2 +#define FLASH_SR_WRPRT_ERR 4 +#define FLASH_SR_EOP 5 + +#define FLASH_SR_ERROR_MASK ((1 << FLASH_SR_PG_ERR) | (1 << FLASH_SR_WRPRT_ERR)) + +#define FLASH_CR_PG 0 +#define FLASH_CR_PER 1 +#define FLASH_CR_MER 2 +#define FLASH_CR_OPTPG 4 +#define FLASH_CR_OPTER 5 +#define FLASH_CR_STRT 6 +#define FLASH_CR_LOCK 7 +#define FLASH_CR_OPTWRE 9 +#define FLASH_CR_OBL_LAUNCH 13 + +#define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00) +#define STM32L_FLASH_ACR (STM32L_FLASH_REGS_ADDR + 0x00) +#define STM32L_FLASH_PECR (STM32L_FLASH_REGS_ADDR + 0x04) +#define STM32L_FLASH_PDKEYR (STM32L_FLASH_REGS_ADDR + 0x08) +#define STM32L_FLASH_PEKEYR (STM32L_FLASH_REGS_ADDR + 0x0c) +#define STM32L_FLASH_PRGKEYR (STM32L_FLASH_REGS_ADDR + 0x10) +#define STM32L_FLASH_OPTKEYR (STM32L_FLASH_REGS_ADDR + 0x14) +#define STM32L_FLASH_SR (STM32L_FLASH_REGS_ADDR + 0x18) +#define STM32L_FLASH_OBR (STM32L_FLASH_REGS_ADDR + 0x1c) +#define STM32L_FLASH_WRPR (STM32L_FLASH_REGS_ADDR + 0x20) +#define FLASH_L1_FPRG 10 +#define FLASH_L1_PROG 3 + +// Flash registers common to STM32G0 and STM32G4 series. +#define STM32Gx_FLASH_REGS_ADDR ((uint32_t)0x40022000) +#define STM32Gx_FLASH_ACR (STM32Gx_FLASH_REGS_ADDR + 0x00) +#define STM32Gx_FLASH_KEYR (STM32Gx_FLASH_REGS_ADDR + 0x08) +#define STM32Gx_FLASH_OPTKEYR (STM32Gx_FLASH_REGS_ADDR + 0x0c) +#define STM32Gx_FLASH_SR (STM32Gx_FLASH_REGS_ADDR + 0x10) +#define STM32Gx_FLASH_CR (STM32Gx_FLASH_REGS_ADDR + 0x14) +#define STM32Gx_FLASH_ECCR (STM32Gx_FLASH_REGS_ADDR + 0x18) +#define STM32Gx_FLASH_OPTR (STM32Gx_FLASH_REGS_ADDR + 0x20) + +// G0 (RM0444 Table 1, sec 3.7) +// Mostly the same as G4 chips, but the notation +// varies a bit after the 'OPTR' register. +#define STM32G0_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) +#define STM32G0_FLASH_PCROP1ASR (STM32G0_FLASH_REGS_ADDR + 0x24) +#define STM32G0_FLASH_PCROP1AER (STM32G0_FLASH_REGS_ADDR + 0x28) +#define STM32G0_FLASH_WRP1AR (STM32G0_FLASH_REGS_ADDR + 0x2C) +#define STM32G0_FLASH_WRP1BR (STM32G0_FLASH_REGS_ADDR + 0x30) +#define STM32G0_FLASH_PCROP1BSR (STM32G0_FLASH_REGS_ADDR + 0x34) +#define STM32G0_FLASH_PCROP1BER (STM32G0_FLASH_REGS_ADDR + 0x38) +#define STM32G0_FLASH_SECR (STM32G0_FLASH_REGS_ADDR + 0x80) + +// G4 (RM0440 Table 17, sec 3.7.19) +// Mostly the same as STM32G0 chips, but there are a few extra +// registers because 'cat 3' devices can have two Flash banks. +#define STM32G4_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) +#define STM32G4_FLASH_PDKEYR (STM32G4_FLASH_REGS_ADDR + 0x04) +#define STM32G4_FLASH_PCROP1SR (STM32G4_FLASH_REGS_ADDR + 0x24) +#define STM32G4_FLASH_PCROP1ER (STM32G4_FLASH_REGS_ADDR + 0x28) +#define STM32G4_FLASH_WRP1AR (STM32G4_FLASH_REGS_ADDR + 0x2C) +#define STM32G4_FLASH_WRP1BR (STM32G4_FLASH_REGS_ADDR + 0x30) +#define STM32G4_FLASH_PCROP2SR (STM32G4_FLASH_REGS_ADDR + 0x44) +#define STM32G4_FLASH_PCROP2ER (STM32G4_FLASH_REGS_ADDR + 0x48) +#define STM32G4_FLASH_WRP2AR (STM32G4_FLASH_REGS_ADDR + 0x4C) +#define STM32G4_FLASH_WRP2BR (STM32G4_FLASH_REGS_ADDR + 0x50) +#define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70) +#define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74) + +// G0/G4 FLASH control register +#define STM32Gx_FLASH_CR_PG (0) /* Program */ +#define STM32Gx_FLASH_CR_PER (1) /* Page erase */ +#define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */ +#define STM32Gx_FLASH_CR_PNB (3) /* Page number */ +#define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ +#define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ +#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ +#define STM32Gx_FLASH_CR_STRT (16) /* Start */ +#define STM32Gx_FLASH_CR_OPTSTRT \ + (17) /* Start of modification of option bytes */ +#define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ +#define STM32Gx_FLASH_CR_EOPIE (24) /* End of operation interrupt enable */ +#define STM32Gx_FLASH_CR_ERRIE (25) /* Error interrupt enable */ +#define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ +#define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ +#define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ + +// G0/G4 FLASH status register +#define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) +#define STM32Gx_FLASH_SR_PROGERR (3) +#define STM32Gx_FLASH_SR_WRPERR (4) +#define STM32Gx_FLASH_SR_PGAERR (5) +#define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ +#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ + +// G4 FLASH option register +#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ + +// WB (RM0434) +#define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) +#define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) +#define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) +#define STM32WB_FLASH_OPT_KEYR (STM32WB_FLASH_REGS_ADDR + 0x0C) +#define STM32WB_FLASH_SR (STM32WB_FLASH_REGS_ADDR + 0x10) +#define STM32WB_FLASH_CR (STM32WB_FLASH_REGS_ADDR + 0x14) +#define STM32WB_FLASH_ECCR (STM32WB_FLASH_REGS_ADDR + 0x18) +#define STM32WB_FLASH_OPTR (STM32WB_FLASH_REGS_ADDR + 0x20) +#define STM32WB_FLASH_PCROP1ASR (STM32WB_FLASH_REGS_ADDR + 0x24) +#define STM32WB_FLASH_PCROP1AER (STM32WB_FLASH_REGS_ADDR + 0x28) +#define STM32WB_FLASH_WRP1AR (STM32WB_FLASH_REGS_ADDR + 0x2C) +#define STM32WB_FLASH_WRP1BR (STM32WB_FLASH_REGS_ADDR + 0x30) +#define STM32WB_FLASH_PCROP1BSR (STM32WB_FLASH_REGS_ADDR + 0x34) +#define STM32WB_FLASH_PCROP1BER (STM32WB_FLASH_REGS_ADDR + 0x38) +#define STM32WB_FLASH_IPCCBR (STM32WB_FLASH_REGS_ADDR + 0x3C) +#define STM32WB_FLASH_C2ACR (STM32WB_FLASH_REGS_ADDR + 0x5C) +#define STM32WB_FLASH_C2SR (STM32WB_FLASH_REGS_ADDR + 0x60) +#define STM32WB_FLASH_C2CR (STM32WB_FLASH_REGS_ADDR + 0x64) +#define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) +#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) + +// WB Flash control register. +#define STM32WB_FLASH_CR_STRT (16) /* Start */ +#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ +#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ +// WB Flash status register. +#define STM32WB_FLASH_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ +#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ +#define STM32WB_FLASH_SR_WRPERR (4) /* Write protection error */ +#define STM32WB_FLASH_SR_PGAERR (5) /* Programming error */ +#define STM32WB_FLASH_SR_BSY (16) /* Busy */ + +// 32L4 register base is at FLASH_REGS_ADDR (0x40022000) +#define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) +#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) +#define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) +#define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) +#define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) + +#define STM32L4_FLASH_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ +#define STM32L4_FLASH_SR_PROGERR 3 +#define STM32L4_FLASH_SR_WRPERR 4 +#define STM32L4_FLASH_SR_PGAERR 5 +#define STM32L4_FLASH_SR_BSY 16 + +#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ +#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ +#define STM32L4_FLASH_CR_PG 0 /* Program */ +#define STM32L4_FLASH_CR_PER 1 /* Page erase */ +#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ +#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ +#define STM32L4_FLASH_CR_STRT 16 /* Start command */ +#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ +#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ +#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ +#define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ +// Bits requesting flash operations (useful when we want to clear them) +#define STM32L4_FLASH_CR_OPBITS \ + (uint32_t)((1lu << STM32L4_FLASH_CR_PG) | (1lu << STM32L4_FLASH_CR_PER) | \ + (1lu << STM32L4_FLASH_CR_MER1) | (1lu << STM32L4_FLASH_CR_MER1)) +// Page is fully specified by BKER and PNB +#define STM32L4_FLASH_CR_PAGEMASK (uint32_t)(0x1fflu << STM32L4_FLASH_CR_PNB) + +#define STM32L4_FLASH_OPTR_DUALBANK 21 + +// STM32L0x flash register base and offsets RM0090 - DM00031020.pdf +#define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) + +#define STM32L0_FLASH_PELOCK (0) +#define STM32L0_FLASH_OPTLOCK (2) +#define STM32L0_FLASH_OBL_LAUNCH (18) + +#define STM32L0_FLASH_SR_ERROR_MASK 0x00013F00 +#define STM32L0_FLASH_SR_WRPERR 8 +#define STM32L0_FLASH_SR_PGAERR 9 +#define STM32L0_FLASH_SR_NOTZEROERR 16 + +#define FLASH_ACR_OFF ((uint32_t)0x00) +#define FLASH_PECR_OFF ((uint32_t)0x04) +#define FLASH_PDKEYR_OFF ((uint32_t)0x08) +#define FLASH_PEKEYR_OFF ((uint32_t)0x0c) +#define FLASH_PRGKEYR_OFF ((uint32_t)0x10) +#define FLASH_OPTKEYR_OFF ((uint32_t)0x14) +#define FLASH_SR_OFF ((uint32_t)0x18) +#define FLASH_OBR_OFF ((uint32_t)0x1c) +#define FLASH_WRPR_OFF ((uint32_t)0x20) + +// STM32F7 +#define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) +#define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) +#define FLASH_F7_SR (FLASH_F7_REGS_ADDR + 0x0c) +#define FLASH_F7_CR (FLASH_F7_REGS_ADDR + 0x10) +#define FLASH_F7_OPTCR (FLASH_F7_REGS_ADDR + 0x14) +#define FLASH_F7_OPTCR1 (FLASH_F7_REGS_ADDR + 0x18) +#define FLASH_F7_OPTCR_LOCK 0 +#define FLASH_F7_OPTCR_START 1 +#define FLASH_F7_CR_STRT 16 +#define FLASH_F7_CR_LOCK 31 +#define FLASH_F7_CR_SER 1 +#define FLASH_F7_CR_SNB 3 +#define FLASH_F7_CR_SNB_MASK 0xf8 +#define FLASH_F7_SR_BSY 16 +#define FLASH_F7_SR_ERS_ERR 7 /* Erase Sequence Error */ +#define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ +#define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ +#define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ +#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ +#define FLASH_F7_SR_EOP 0 /* End of operation */ +#define FLASH_F7_OPTCR1_BOOT_ADD0 0 +#define FLASH_F7_OPTCR1_BOOT_ADD1 16 + +#define FLASH_F7_SR_ERROR_MASK \ + ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | \ + (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | \ + (1 << FLASH_F7_SR_OP_ERR)) + +// STM32F4 +#define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) +#define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08) +#define FLASH_F4_SR (FLASH_F4_REGS_ADDR + 0x0c) +#define FLASH_F4_CR (FLASH_F4_REGS_ADDR + 0x10) +#define FLASH_F4_OPTCR (FLASH_F4_REGS_ADDR + 0x14) +#define FLASH_F4_OPTCR_LOCK 0 +#define FLASH_F4_OPTCR_START 1 +#define FLASH_F4_CR_STRT 16 +#define FLASH_F4_CR_LOCK 31 +#define FLASH_F4_CR_SER 1 +#define FLASH_F4_CR_SNB 3 +#define FLASH_F4_CR_SNB_MASK 0xf8 +#define FLASH_F4_SR_ERROR_MASK 0x000000F0 +#define FLASH_F4_SR_PGAERR 5 +#define FLASH_F4_SR_WRPERR 4 +#define FLASH_F4_SR_BSY 16 + +// STM32F2 +#define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F2_KEYR (FLASH_F2_REGS_ADDR + 0x04) +#define FLASH_F2_OPT_KEYR (FLASH_F2_REGS_ADDR + 0x08) +#define FLASH_F2_SR (FLASH_F2_REGS_ADDR + 0x0c) +#define FLASH_F2_CR (FLASH_F2_REGS_ADDR + 0x10) +#define FLASH_F2_OPT_CR (FLASH_F2_REGS_ADDR + 0x14) +#define FLASH_F2_OPT_LOCK_BIT (1u << 0) +#define FLASH_F2_CR_STRT 16 +#define FLASH_F2_CR_LOCK 31 + +#define FLASH_F2_CR_SER 1 +#define FLASH_F2_CR_SNB 3 +#define FLASH_F2_CR_SNB_MASK 0x78 +#define FLASH_F2_SR_BSY 16 + +// STM32H7xx +#define FLASH_H7_CR_LOCK 0 +#define FLASH_H7_CR_PG 1 +#define FLASH_H7_CR_SER 2 +#define FLASH_H7_CR_BER 3 +#define FLASH_H7_CR_PSIZE 4 +#define FLASH_H7_CR_START(chipid) (chipid == STM32_CHIPID_H7Ax ? 5 : 7) +#define FLASH_H7_CR_SNB 8 +#define FLASH_H7_CR_SNB_MASK 0x700 + +#define FLASH_H7_SR_QW 2 +#define FLASH_H7_SR_WRPERR 17 +#define FLASH_H7_SR_PGSERR 18 +#define FLASH_H7_SR_STRBERR 19 +#define FLASH_H7_SR_ERROR_MASK \ + ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | \ + (1 << FLASH_H7_SR_WRPERR)) + +#define FLASH_H7_OPTCR_OPTLOCK 0 +#define FLASH_H7_OPTCR_OPTSTART 1 +#define FLASH_H7_OPTCR_MER 4 + +#define FLASH_H7_OPTSR_OPT_BUSY 0 +#define FLASH_H7_OPTSR_OPTCHANGEERR 30 + +#define FLASH_H7_OPTCCR_CLR_OPTCHANGEERR 30 + +#define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) +#define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) +#define FLASH_H7_KEYR2 (FLASH_H7_REGS_ADDR + 0x104) +#define FLASH_H7_OPT_KEYR (FLASH_H7_REGS_ADDR + 0x08) +#define FLASH_H7_OPT_KEYR2 (FLASH_H7_REGS_ADDR + 0x108) +#define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c) +#define FLASH_H7_CR2 (FLASH_H7_REGS_ADDR + 0x10c) +#define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) +#define FLASH_H7_SR2 (FLASH_H7_REGS_ADDR + 0x110) +#define FLASH_H7_CCR1 (FLASH_H7_REGS_ADDR + 0x14) +#define FLASH_H7_CCR2 (FLASH_H7_REGS_ADDR + 0x114) +#define FLASH_H7_OPTCR (FLASH_H7_REGS_ADDR + 0x18) +#define FLASH_H7_OPTCR2 (FLASH_H7_REGS_ADDR + 0x118) +#define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) +#define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) + +#endif // STM32FLASH_H diff --git a/src/calculate.c b/src/calculate.c new file mode 100644 index 000000000..ed3b65873 --- /dev/null +++ b/src/calculate.c @@ -0,0 +1,74 @@ +#include +#include "calculate.h" +#include "common_flash.h" + +uint32_t calculate_F4_sectornum(uint32_t flashaddr) { + uint32_t offset = 0; + flashaddr &= ~STM32_FLASH_BASE; // page now holding the actual flash address + + if (flashaddr >= 0x100000) { + offset = 12; + flashaddr -= 0x100000; + } + + if (flashaddr < 0x4000) { + return (offset + 0); + } else if (flashaddr < 0x8000) { + return (offset + 1); + } else if (flashaddr < 0xc000) { + return (offset + 2); + } else if (flashaddr < 0x10000) { + return (offset + 3); + } else if (flashaddr < 0x20000) { + return (offset + 4); + } else { + return (offset + (flashaddr / 0x20000) + 4); + } +} + +uint32_t calculate_F7_sectornum(uint32_t flashaddr) { + flashaddr &= ~STM32_FLASH_BASE; // Page now holding the actual flash address + + if (flashaddr < 0x20000) { + return (flashaddr / 0x8000); + } else if (flashaddr < 0x40000) { + return (4); + } else { + return ((flashaddr / 0x40000) + 4); + } +} + +uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, + unsigned bank) { + flashaddr &= + ~((bank == BANK_1) + ? STM32_FLASH_BASE + : STM32_H7_FLASH_BANK2_BASE); // sector holding the flash address + return (flashaddr / sl->flash_pgsz); +} + +// returns BKER:PNB for the given page address +uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { + uint32_t bker = 0; + uint32_t flashopt; + stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); + flashaddr -= STM32_FLASH_BASE; + + if (sl->chip_id == STM32_CHIPID_L4 || + sl->chip_id == STM32_CHIPID_L496x_L4A6x || + sl->chip_id == STM32_CHIPID_L4Rx) { + // this chip use dual banked flash + if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { + uint32_t banksize = (uint32_t)sl->flash_size / 2; + + if (flashaddr >= banksize) { + flashaddr -= banksize; + bker = 0x100; + } + } + } + + // For 1MB chips without the dual-bank option set, the page address will + // overflow into the BKER bit, which gives us the correct bank:page value. + return (bker | flashaddr / (uint32_t)sl->flash_pgsz); +} diff --git a/src/calculate.h b/src/calculate.h new file mode 100644 index 000000000..68c1fb988 --- /dev/null +++ b/src/calculate.h @@ -0,0 +1,15 @@ +/* + * File: calculate.h + * + * TODO: add a description + */ + +#ifndef CALCULATE_H +#define CALCULATE_H + +uint32_t calculate_F4_sectornum(uint32_t); +uint32_t calculate_F7_sectornum(uint32_t); +uint32_t calculate_H7_sectornum(stlink_t *, uint32_t, unsigned); +uint32_t calculate_L4_page(stlink_t *, uint32_t); + +#endif // CALCULATE_H diff --git a/src/common.c b/src/common.c index 266722b91..97f41a533 100644 --- a/src/common.c +++ b/src/common.c @@ -1,4576 +1,1406 @@ -#define DEBUG_FLASH 0 -#include -#include -#include -#include -#include - -#include +#include #include -#include #include #include #include - -#include -#include +#include #include -#include #include - -#ifdef STLINK_HAVE_SYS_MMAN_H -#include -#else -#include -#endif - -#ifndef O_BINARY -#define O_BINARY 0 -#endif +#include +#include +#include +#include "common_flash.h" +#include "calculate.h" +#include "map_file.h" +#include "common.h" #ifdef _MSC_VER #define __attribute__(x) #endif -#define BANK_1 0 -#define BANK_2 1 +// Private structs and functions defines +struct stlink_fread_worker_arg { + int fd; +}; +struct stlink_fread_ihex_worker_arg { + FILE *file; + uint32_t addr; + uint32_t lba; + uint8_t buf[16]; + uint8_t buf_pos; +}; +typedef bool (*save_block_fn)(void *arg, uint8_t *block, ssize_t len); -// Endianness -// https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html -// These functions encode and decode little endian uint16 and uint32 values. +static void stop_wdg_in_debug(stlink_t *); +int stlink_jtag_reset(stlink_t *, int); +int stlink_soft_reset(stlink_t *, int); +void _parse_version(stlink_t *, stlink_version_t *); +static uint8_t stlink_parse_hex(const char *); +static int stlink_read(stlink_t *, stm32_addr_t, size_t, save_block_fn, void *); +static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg *, int, stm32_addr_t); +static bool stlink_fread_ihex_worker(void *, uint8_t *, ssize_t); +static bool stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg *); +static bool stlink_fread_worker(void *, uint8_t *, ssize_t); +// End of private structs and functions defines + +// Functions below are defined in stlink.h (see line num before function) +// 252 +void stlink_close(stlink_t *sl) { + DLOG("*** stlink_close ***\n"); -void write_uint32(unsigned char *buf, uint32_t ui) { - buf[0] = ui; - buf[1] = ui >> 8; - buf[2] = ui >> 16; - buf[3] = ui >> 24; -} + if (!sl) { + return; + } -void write_uint16(unsigned char *buf, uint16_t ui) { - buf[0] = (uint8_t)ui; - buf[1] = (uint8_t)(ui >> 8); + sl->backend->close(sl); + free(sl); } +// 250 +int stlink_exit_debug_mode(stlink_t *sl) { + DLOG("*** stlink_exit_debug_mode ***\n"); -uint32_t read_uint32(const unsigned char *c, const int pt) { - return ((uint32_t)c[pt]) | ((uint32_t)c[pt + 1] << 8) | - ((uint32_t)c[pt + 2] << 16) | ((uint32_t)c[pt + 3] << 24); -} + if (sl->flash_type != STM32_FLASH_TYPE_UNKNOWN && + sl->core_stat != TARGET_RESET) { + // stop debugging if the target has been identified + stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); + } -uint16_t read_uint16(const unsigned char *c, const int pt) { - return ((uint16_t)c[pt]) | ((uint16_t)c[pt + 1] << 8); + return (sl->backend->exit_debug_mode(sl)); } - -static uint32_t get_stm32l0_flash_base(stlink_t *sl) { - switch (sl->chip_id) { - case STM32_CHIPID_L0: - case STM32_CHIPID_L0_CAT5: - case STM32_CHIPID_L0_CAT2: - case STM32_CHIPID_L011: - return (STM32L0_FLASH_REGS_ADDR); - - case STM32_CHIPID_L1_CAT2: - case STM32_CHIPID_L1_MD: - case STM32_CHIPID_L1_MD_PLUS: - case STM32_CHIPID_L1_MD_PLUS_HD: - return (STM32L_FLASH_REGS_ADDR); - - default: - WLOG("Flash base use default L0 address\n"); - return (STM32L0_FLASH_REGS_ADDR); +//248 +int stlink_enter_swd_mode(stlink_t *sl) { + DLOG("*** stlink_enter_swd_mode ***\n"); + return (sl->backend->enter_swd_mode(sl)); +} +// 271 +// Force the core into the debug mode -> halted state. +int stlink_force_debug(stlink_t *sl) { + DLOG("*** stlink_force_debug_mode ***\n"); + int res = sl->backend->force_debug(sl); + if (res) { + return (res); } + // Stop the watchdogs in the halted state for suppress target reboot + stop_wdg_in_debug(sl); + return (0); } - -static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { - uint32_t rdp; - stlink_read_debug32(sl, FLASH_WRPR, &rdp); - return (rdp & 0xff); +// 251 +int stlink_exit_dfu_mode(stlink_t *sl) { + DLOG("*** stlink_exit_dfu_mode ***\n"); + return (sl->backend->exit_dfu_mode(sl)); } +// 253 +int stlink_core_id(stlink_t *sl) { + int ret; -static inline uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { - uint32_t reg, res; - - if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - reg = FLASH_F4_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - reg = FLASH_F7_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { - reg = STM32L4_FLASH_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - reg = STM32WB_FLASH_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - } else { - reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; - } - - stlink_read_debug32(sl, reg, &res); + DLOG("*** stlink_core_id ***\n"); + ret = sl->backend->core_id(sl); -#if DEBUG_FLASH - fprintf(stdout, "CR:0x%x\n", res); -#endif - return (res); -} + if (ret == -1) { + ELOG("Failed to read core_id\n"); + return (ret); + } -static inline unsigned int is_flash_locked(stlink_t *sl) { - /* return non zero for true */ - uint32_t cr_lock_shift; - uint32_t cr_reg; - uint32_t n; - - if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { - cr_reg = FLASH_CR; - cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - cr_reg = FLASH_F4_CR; - cr_lock_shift = FLASH_F4_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_lock_shift = FLASH_F7_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - cr_lock_shift = STM32L0_FLASH_PELOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { - cr_reg = STM32L4_FLASH_CR; - cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_lock_shift = STM32Gx_FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; - cr_lock_shift = STM32WB_FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; - cr_lock_shift = FLASH_H7_CR_LOCK; - } else { - ELOG("unsupported flash method, abort\n"); - return (-1); + if (sl->verbose > 2) { + stlink_print_data(sl); } - stlink_read_debug32(sl, cr_reg, &n); - return (n & (1u << cr_lock_shift)); + DLOG("core_id = 0x%08x\n", sl->core_id); + return (ret); } -static void unlock_flash(stlink_t *sl) { - uint32_t key_reg, key2_reg = 0; - uint32_t flash_key1 = FLASH_KEY1; - uint32_t flash_key2 = FLASH_KEY2; - /* The unlock sequence consists of 2 write cycles where 2 key values are - * written to the FLASH_KEYR register. An invalid sequence results in a - * definitive lock of the FPEC block until next reset. - */ +// stlink_chip_id() is called by stlink_load_device_params() +// do not call this procedure directly. +int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { + int ret; + cortex_m3_cpuid_t cpu_id; - if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { - key_reg = FLASH_KEYR; - } else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { - key_reg = FLASH_KEYR; - key2_reg = FLASH_KEYR2; - } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - key_reg = FLASH_F4_KEYR; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - key_reg = FLASH_F7_KEYR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; - flash_key1 = FLASH_L0_PEKEY1; - flash_key2 = FLASH_L0_PEKEY2; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { - key_reg = STM32L4_FLASH_KEYR; - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - key_reg = STM32Gx_FLASH_KEYR; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - key_reg = STM32WB_FLASH_KEYR; - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - key_reg = FLASH_H7_KEYR1; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - key2_reg = FLASH_H7_KEYR2; - } - } else { - ELOG("unsupported flash method, abort\n"); - return; + // Read the CPU ID to determine where to read the core id + if (stlink_cpu_id(sl, &cpu_id) || + cpu_id.implementer_id != STLINK_REG_CMx_CPUID_IMPL_ARM) { + ELOG("Can not connect to target. Please use \'connect under reset\' and " + "try again\n"); + return -1; } - stlink_write_debug32(sl, key_reg, flash_key1); - stlink_write_debug32(sl, key_reg, flash_key2); - - if (key2_reg) { - stlink_write_debug32(sl, key2_reg, flash_key1); - stlink_write_debug32(sl, key2_reg, flash_key2); - } -} + /* + * the chip_id register in the reference manual have + * DBGMCU_IDCODE / DBG_IDCODE name + * + */ -/* unlock flash if already locked */ -static int unlock_flash_if(stlink_t *sl) { - if (is_flash_locked(sl)) { - unlock_flash(sl); + if ((sl->core_id == STM32_CORE_ID_M7F_H7_SWD || sl->core_id == STM32_CORE_ID_M7F_H7_JTAG) && + cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { + // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) + ret = stlink_read_debug32(sl, 0x5c001000, chip_id); + } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0 || + cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0P) { + // STM32F0 (RM0091, pg914; RM0360, pg713) + // STM32L0 (RM0377, pg813; RM0367, pg915; RM0376, pg917) + // STM32G0 (RM0444, pg1367) + ret = stlink_read_debug32(sl, 0x40015800, chip_id); + } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM33) { + // STM32L5 (RM0438, pg2157) + ret = stlink_read_debug32(sl, 0xE0044000, chip_id); + } else /* СM3, СM4, CM7 */ { + // default chipid address - if (is_flash_locked(sl)) { - WLOG("Failed to unlock flash!\n"); - return (-1); - } + // STM32F1 (RM0008, pg1087; RM0041, pg681) + // STM32F2 (RM0033, pg1326) + // STM32F3 (RM0316, pg1095; RM0313, pg874) + // STM32F7 (RM0385, pg1676; RM0410, pg1912) + // STM32L1 (RM0038, pg861) + // STM32L4 (RM0351, pg1840; RM0394, pg1560) + // STM32G4 (RM0440, pg2086) + // STM32WB (RM0434, pg1406) + ret = stlink_read_debug32(sl, 0xE0042000, chip_id); } - DLOG("Successfully unlocked flash\n"); - return (0); -} + if (ret || !(*chip_id)) { + *chip_id = 0; + ret = ret?ret:-1; + ELOG("Could not find chip id!\n"); + } else { + *chip_id = (*chip_id) & 0xfff; -static void lock_flash(stlink_t *sl) { - uint32_t cr_lock_shift, cr_reg, n, cr2_reg = 0; - uint32_t cr_mask = 0xffffffffu; - - if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { - cr_reg = FLASH_CR; - cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { - cr_reg = FLASH_CR; - cr2_reg = FLASH_CR2; - cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - cr_reg = FLASH_F4_CR; - cr_lock_shift = FLASH_F4_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_lock_shift = FLASH_F7_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - cr_lock_shift = STM32L0_FLASH_PELOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { - cr_reg = STM32L4_FLASH_CR; - cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_lock_shift = STM32Gx_FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; - cr_lock_shift = STM32WB_FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - cr2_reg = FLASH_H7_CR2; + // Fix chip_id for F4 rev A errata, read CPU ID, as CoreID is the same for + // F2/F4 + if (*chip_id == 0x411 && cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM4) { + *chip_id = 0x413; } - cr_lock_shift = FLASH_H7_CR_LOCK; - cr_mask = ~(1u << FLASH_H7_CR_SER); - } else { - ELOG("unsupported flash method, abort\n"); - return; } - stlink_read_debug32(sl, cr_reg, &n); - n &= cr_mask; - n |= (1u << cr_lock_shift); - stlink_write_debug32(sl, cr_reg, n); - - if (cr2_reg) { - n = read_flash_cr(sl, BANK_2) | (1u << cr_lock_shift); - stlink_write_debug32(sl, cr2_reg, n); - } + return (ret); } -static bool is_flash_option_locked(stlink_t *sl) { - uint32_t optlock_shift, optcr_reg; - int active_bit_level = 1; - uint32_t n; - - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - optcr_reg = FLASH_CR; - optlock_shift = FLASH_CR_OPTWRE; - active_bit_level = 0; /* bit is "option write enable", not lock */ - break; - case STM32_FLASH_TYPE_F2_F4: - optcr_reg = FLASH_F4_OPTCR; - optlock_shift = FLASH_F4_OPTCR_LOCK; - break; - case STM32_FLASH_TYPE_F7: - optcr_reg = FLASH_F7_OPTCR; - optlock_shift = FLASH_F7_OPTCR_LOCK; - break; - case STM32_FLASH_TYPE_L0_L1: - optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - optlock_shift = STM32L0_FLASH_OPTLOCK; - break; - case STM32_FLASH_TYPE_L4_L4P: - optcr_reg = STM32L4_FLASH_CR; - optlock_shift = STM32L4_FLASH_CR_OPTLOCK; - break; - case STM32_FLASH_TYPE_G0: - case STM32_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; - break; - case STM32_FLASH_TYPE_WB_WL: - optcr_reg = STM32WB_FLASH_CR; - optlock_shift = STM32WB_FLASH_CR_OPTLOCK; - break; - case STM32_FLASH_TYPE_H7: - optcr_reg = FLASH_H7_OPTCR; - optlock_shift = FLASH_H7_OPTCR_OPTLOCK; - break; - default: - ELOG("unsupported flash method, abort\n"); - return -1; - } - - stlink_read_debug32(sl, optcr_reg, &n); +/** + * Cortex M tech ref manual, CPUID register description + * @param sl stlink context + * @param cpuid pointer to the result object + */ +int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { + uint32_t raw; - if (active_bit_level == 0) { - return (!(n & (1u << optlock_shift))); + if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &raw)) { + cpuid->implementer_id = 0; + cpuid->variant = 0; + cpuid->part = 0; + cpuid->revision = 0; + return (-1); } - return (n & (1u << optlock_shift)); + cpuid->implementer_id = (raw >> 24) & 0x7f; + cpuid->variant = (raw >> 20) & 0xf; + cpuid->part = (raw >> 4) & 0xfff; + cpuid->revision = raw & 0xf; + return (0); } +// 303 +/** + * Reads and decodes the flash parameters, as dynamically as possible + * @param sl + * @return 0 for success, or -1 for unsupported core type. + */ + int stlink_load_device_params(stlink_t *sl) { + // This seems to normally work so is unnecessary info for a normal user. + // Demoted to debug. -- REW + DLOG("Loading device parameters....\n"); + const struct stlink_chipid_params *params = NULL; + stlink_core_id(sl); + uint32_t flash_size; + + if (stlink_chip_id(sl, &sl->chip_id)) { + return (-1); + } + + params = stlink_chipid_get_params(sl->chip_id); + + if (params == NULL) { + WLOG("unknown chip id! %#x\n", sl->chip_id); + return (-1); + } + + if (params->flash_type == STM32_FLASH_TYPE_UNKNOWN) { + WLOG("Invalid flash type, please check device declaration\n"); + sl->flash_size = 0; + return (0); + } + + // These are fixed... + sl->flash_base = STM32_FLASH_BASE; + sl->sram_base = STM32_SRAM_BASE; + stlink_read_debug32(sl, (params->flash_size_reg) & ~3, &flash_size); + + if (params->flash_size_reg & 2) { + flash_size = flash_size >> 16; + } + + flash_size = flash_size & 0xffff; + + if ((sl->chip_id == STM32_CHIPID_L1_MD || + sl->chip_id == STM32_CHIPID_F1_VL_MD_LD || + sl->chip_id == STM32_CHIPID_L1_MD_PLUS) && + (flash_size == 0)) { + sl->flash_size = 128 * 1024; + } else if (sl->chip_id == STM32_CHIPID_L1_CAT2) { + sl->flash_size = (flash_size & 0xff) * 1024; + } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_L1_MD_PLUS_HD) { + // 0 is 384k and 1 is 256k + if (flash_size == 0) { + sl->flash_size = 384 * 1024; + } else { + sl->flash_size = 256 * 1024; + } + } else { + sl->flash_size = flash_size * 1024; + } + + sl->flash_type = params->flash_type; + sl->flash_pgsz = params->flash_pagesize; + sl->sram_size = params->sram_size; + sl->sys_base = params->bootrom_base; + sl->sys_size = params->bootrom_size; + sl->option_base = params->option_base; + sl->option_size = params->option_size; + sl->chip_flags = params->flags; + + // medium and low devices have the same chipid. ram size depends on flash + // size. STM32F100xx datasheet Doc ID 16455 Table 2 + if (sl->chip_id == STM32_CHIPID_F1_VL_MD_LD && + sl->flash_size < 64 * 1024) { + sl->sram_size = 0x1000; + } + + if (sl->chip_id == STM32_CHIPID_G4_CAT3) { + uint32_t flash_optr; + stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); + + if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { + sl->flash_pgsz <<= 1; + } + } + + // H7 devices with small flash has one bank + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK && + sl->flash_type == STM32_FLASH_TYPE_H7) { + if ((sl->flash_size / sl->flash_pgsz) <= 1) + sl->chip_flags &= ~CHIP_F_HAS_DUAL_BANK; + } + + ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", + params->dev_type, (unsigned)(sl->sram_size / 1024), + (unsigned)(sl->flash_size / 1024), + (sl->flash_pgsz < 1024) ? (unsigned)(sl->flash_pgsz) + : (unsigned)(sl->flash_pgsz / 1024), + (sl->flash_pgsz < 1024) ? "byte" : "KiB"); + + return (0); + } -static int lock_flash_option(stlink_t *sl) { - uint32_t optlock_shift, optcr_reg, n, optcr2_reg = 0; - int active_bit_level = 1; +int stlink_reset(stlink_t *sl, enum reset_type type) { + uint32_t dhcsr; + unsigned timeout; - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - optcr_reg = FLASH_CR; - optlock_shift = FLASH_CR_OPTWRE; - active_bit_level = 0; - break; - case STM32_FLASH_TYPE_F2_F4: - optcr_reg = FLASH_F4_OPTCR; - optlock_shift = FLASH_F4_OPTCR_LOCK; - break; - case STM32_FLASH_TYPE_F7: - optcr_reg = FLASH_F7_OPTCR; - optlock_shift = FLASH_F7_OPTCR_LOCK; - break; - case STM32_FLASH_TYPE_L0_L1: - optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - optlock_shift = STM32L0_FLASH_OPTLOCK; - break; - case STM32_FLASH_TYPE_L4_L4P: - optcr_reg = STM32L4_FLASH_CR; - optlock_shift = STM32L4_FLASH_CR_OPTLOCK; - break; - case STM32_FLASH_TYPE_G0: - case STM32_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; - break; - case STM32_FLASH_TYPE_WB_WL: - optcr_reg = STM32WB_FLASH_CR; - optlock_shift = STM32WB_FLASH_CR_OPTLOCK; - break; - case STM32_FLASH_TYPE_H7: - optcr_reg = FLASH_H7_OPTCR; - optlock_shift = FLASH_H7_OPTCR_OPTLOCK; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) - optcr2_reg = FLASH_H7_OPTCR2; - break; - default: - ELOG("unsupported flash method, abort\n"); - return -1; - } + DLOG("*** stlink_reset ***\n"); - stlink_read_debug32(sl, optcr_reg, &n); + sl->core_stat = TARGET_RESET; - if (active_bit_level == 0) { - n &= ~(1u << optlock_shift); - } else { - n |= (1u << optlock_shift); + if (type == RESET_AUTO) { + // clear S_RESET_ST in DHCSR register for reset state detection + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); } - stlink_write_debug32(sl, optcr_reg, n); - - if (optcr2_reg) { - stlink_read_debug32(sl, optcr2_reg, &n); - - if (active_bit_level == 0) { - n &= ~(1u << optlock_shift); - } else { - n |= (1u << optlock_shift); + if (type == RESET_HARD || type == RESET_AUTO) { + // hardware target reset + if (sl->version.stlink_v > 1) { + stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); + // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) + usleep(100); + stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH); } - - stlink_write_debug32(sl, optcr2_reg, n); + sl->backend->reset(sl); + usleep(10000); } - return (0); -} + if (type == RESET_AUTO) { + /* Check if the S_RESET_ST bit is set in DHCSR + * This means that a reset has occurred + * DDI0337E, p. 10-4, Debug Halting Control and Status Register */ -static int unlock_flash_option(stlink_t *sl) { - uint32_t optkey_reg, optkey2_reg = 0; - uint32_t optkey1 = FLASH_OPTKEY1; - uint32_t optkey2 = FLASH_OPTKEY2; + dhcsr = 0; + int res = stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0 && !res) { + // reset not done yet + // try reset through AIRCR so that NRST does not need to be connected + + WLOG("NRST is not connected\n"); + DLOG("Using reset through SYSRESETREQ\n"); + return stlink_soft_reset(sl, 0); + } + + // waiting for reset the S_RESET_ST bit within 500ms + timeout = time_ms() + 500; + while (time_ms() < timeout) { + dhcsr = STLINK_REG_DHCSR_S_RESET_ST; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + return (0); + } + } - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - optkey_reg = FLASH_OPTKEYR; - optkey1 = FLASH_F0_OPTKEY1; - optkey2 = FLASH_F0_OPTKEY2; - break; - case STM32_FLASH_TYPE_F2_F4: - optkey_reg = FLASH_F4_OPT_KEYR; - break; - case STM32_FLASH_TYPE_F7: - optkey_reg = FLASH_F7_OPT_KEYR; - break; - case STM32_FLASH_TYPE_L0_L1: - optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; - optkey1 = FLASH_L0_OPTKEY1; - optkey2 = FLASH_L0_OPTKEY2; - break; - case STM32_FLASH_TYPE_L4_L4P: - optkey_reg = STM32L4_FLASH_OPTKEYR; - break; - case STM32_FLASH_TYPE_G0: - case STM32_FLASH_TYPE_G4: - optkey_reg = STM32Gx_FLASH_OPTKEYR; - break; - case STM32_FLASH_TYPE_WB_WL: - optkey_reg = STM32WB_FLASH_OPT_KEYR; - break; - case STM32_FLASH_TYPE_H7: - optkey_reg = FLASH_H7_OPT_KEYR; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) - optkey2_reg = FLASH_H7_OPT_KEYR2; - break; - default: - ELOG("unsupported flash method, abort\n"); return (-1); } - stlink_write_debug32(sl, optkey_reg, optkey1); - stlink_write_debug32(sl, optkey_reg, optkey2); - - if (optkey2_reg) { - stlink_write_debug32(sl, optkey2_reg, optkey1); - stlink_write_debug32(sl, optkey2_reg, optkey2); + if (type == RESET_SOFT || type == RESET_SOFT_AND_HALT) { + return stlink_soft_reset(sl, (type == RESET_SOFT_AND_HALT)); } return (0); } +// 255 +int stlink_run(stlink_t *sl, enum run_type type) { + struct stlink_reg rr; + DLOG("*** stlink_run ***\n"); -static int unlock_flash_option_if(stlink_t *sl) { - if (is_flash_option_locked(sl)) { - if (unlock_flash_option(sl)) { - ELOG("Could not unlock flash option!\n"); - return (-1); - } - - if (is_flash_option_locked(sl)) { - ELOG("Failed to unlock flash option!\n"); - return (-1); - } + /* Make sure we are in Thumb mode + * Cortex-M chips don't support ARM mode instructions + * xPSR may be incorrect if the vector table has invalid data */ + stlink_read_reg(sl, 16, &rr); + if ((rr.xpsr & (1 << 24)) == 0) { + ILOG("Go to Thumb mode\n"); + stlink_write_reg(sl, rr.xpsr | (1 << 24), 16); } - DLOG("Successfully unlocked flash option\n"); - return (0); + return (sl->backend->run(sl, type)); } - -static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { - uint32_t cr_reg, x; - - x = read_flash_cr(sl, bank); - - if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - cr_reg = FLASH_F4_CR; - x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { - cr_reg = STM32L4_FLASH_CR; - x &= ~STM32L4_FLASH_CR_OPBITS; - x |= (1 << STM32L4_FLASH_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; - x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - x |= (1 << FLASH_H7_CR_PG); - } else { - cr_reg = FLASH_CR; - x = (1 << FLASH_CR_PG); +// 273 +int stlink_set_swdclk(stlink_t *sl, int freq_khz) { + DLOG("*** set_swdclk ***\n"); + return (sl->backend->set_swdclk(sl, freq_khz)); +} +// 293 +// this function is called by stlink_status() +// do not call stlink_core_stat() directly, always use stlink_status() +void stlink_core_stat(stlink_t *sl) { + switch (sl->core_stat) { + case TARGET_RUNNING: + DLOG(" core status: running\n"); + return; + case TARGET_HALTED: + DLOG(" core status: halted\n"); + return; + case TARGET_RESET: + DLOG(" core status: reset\n"); + return; + case TARGET_DEBUG_RUNNING: + DLOG(" core status: debug running\n"); + return; + default: + DLOG(" core status: unknown\n"); } +} +// 256 +int stlink_status(stlink_t *sl) { + int ret; - stlink_write_debug32(sl, cr_reg, x); + DLOG("*** stlink_status ***\n"); + ret = sl->backend->status(sl); + stlink_core_stat(sl); + return (ret); } +// 257 +int stlink_version(stlink_t *sl) { + DLOG("*** looking up stlink version\n"); -static void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { - uint32_t cr_reg, n; - uint32_t bit = FLASH_CR_PG; - - if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - cr_reg = FLASH_F4_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { - cr_reg = STM32L4_FLASH_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - bit = FLASH_H7_CR_PG; - } else { - cr_reg = FLASH_CR; + if (sl->backend->version(sl)) { + return (-1); } - n = read_flash_cr(sl, bank) & ~(1 << bit); - stlink_write_debug32(sl, cr_reg, n); -} + _parse_version(sl, &sl->version); -static void set_flash_cr_per(stlink_t *sl, unsigned bank) { - uint32_t cr_reg, val; + DLOG("st vid = 0x%04x (expect 0x%04x)\n", sl->version.st_vid, + STLINK_USB_VID_ST); + DLOG("stlink pid = 0x%04x\n", sl->version.stlink_pid); + DLOG("stlink version = 0x%x\n", sl->version.stlink_v); + DLOG("jtag version = 0x%x\n", sl->version.jtag_v); + DLOG("swim version = 0x%x\n", sl->version.swim_v); - if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; - } else { - cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + if (sl->version.jtag_v == 0) { + WLOG(" warning: stlink doesn't support JTAG/SWD interface\n"); } - stlink_read_debug32(sl, cr_reg, &val); - val |= (1 << FLASH_CR_PER); - stlink_write_debug32(sl, cr_reg, val); + return (0); } +// 272 +int stlink_target_voltage(stlink_t *sl) { + int voltage = -1; + DLOG("*** reading target voltage\n"); -static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { - uint32_t cr_reg; + if (sl->backend->target_voltage != NULL) { + voltage = sl->backend->target_voltage(sl); - if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; + if (voltage != -1) { + DLOG("target voltage = %imV\n", voltage); + } else { + DLOG("error reading target voltage\n"); + } } else { - cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + DLOG("reading voltage not supported by backend\n"); } - const uint32_t n = read_flash_cr(sl, bank) & ~(1 << FLASH_CR_PER); - stlink_write_debug32(sl, cr_reg, n); + return (voltage); } +// 299 +bool stlink_is_core_halted(stlink_t *sl) { + stlink_status(sl); + return (sl->core_stat == TARGET_HALTED); +} +// 269 +int stlink_step(stlink_t *sl) { + DLOG("*** stlink_step ***\n"); + return (sl->backend->step(sl)); +} +// 270 +int stlink_current_mode(stlink_t *sl) { + int mode = sl->backend->current_mode(sl); -static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { - uint32_t val, cr_reg, cr_mer, cr_pg; - - if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - cr_reg = FLASH_F4_CR; - cr_mer = 1 << FLASH_CR_MER; - cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_mer = 1 << FLASH_CR_MER; - cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { - cr_reg = STM32L4_FLASH_CR; - cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); - cr_pg = (1 << STM32L4_FLASH_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_mer = (1 << STM32Gx_FLASH_CR_MER1); - - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); - } - - cr_pg = (1 << FLASH_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; - cr_mer = (1 << FLASH_CR_MER); - cr_pg = (1 << FLASH_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - cr_mer = (1 << FLASH_H7_CR_BER); - cr_pg = (1 << FLASH_H7_CR_PG); - } else { - cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; - cr_mer = (1 << FLASH_CR_MER); - cr_pg = (1 << FLASH_CR_PG); + switch (mode) { + case STLINK_DEV_DFU_MODE: + DLOG("stlink current mode: dfu\n"); + return (mode); + case STLINK_DEV_DEBUG_MODE: + DLOG("stlink current mode: debug (jtag or swd)\n"); + return (mode); + case STLINK_DEV_MASS_MODE: + DLOG("stlink current mode: mass\n"); + return (mode); } - stlink_read_debug32(sl, cr_reg, &val); - - if (val & cr_pg) { - // STM32F030 will drop MER bit if PG was set - val &= ~cr_pg; - stlink_write_debug32(sl, cr_reg, val); + DLOG("stlink mode: unknown!\n"); + return (STLINK_DEV_UNKNOWN_MODE); +} +// 274 +int stlink_trace_enable(stlink_t *sl, uint32_t frequency) { + DLOG("*** stlink_trace_enable ***\n"); + return (sl->backend->trace_enable(sl, frequency)); +} +// 275 +int stlink_trace_disable(stlink_t *sl) { + DLOG("*** stlink_trace_disable ***\n"); + return (sl->backend->trace_disable(sl)); +} +// 276 +int stlink_trace_read(stlink_t *sl, uint8_t *buf, size_t size) { + return (sl->backend->trace_read(sl, buf, size)); +} +// 294 +void stlink_print_data(stlink_t *sl) { + if (sl->q_len <= 0 || sl->verbose < UDEBUG) { + return; } - if (v) { - val |= cr_mer; - } else { - val &= ~cr_mer; + if (sl->verbose > 2) { + DLOG("data_len = %d 0x%x\n", sl->q_len, sl->q_len); } - stlink_write_debug32(sl, cr_reg, val); + for (int i = 0; i < sl->q_len; i++) { + if (i % 16 == 0) { + /* + if (sl->q_data_dir == Q_DATA_OUT) { + fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i); + } else { + fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); + } + */ + } + // DLOG(" %02x", (unsigned int) sl->q_buf[i]); + fprintf(stderr, " %02x", (unsigned int)sl->q_buf[i]); + } + // DLOG("\n\n"); + fprintf(stderr, "\n"); } +// 283 +int stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, + stm32_addr_t addr) { + // write the file in sram at addr -static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { - uint32_t val, cr_reg, cr_strt; - - if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - cr_reg = FLASH_F4_CR; - cr_strt = 1 << FLASH_F4_CR_STRT; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_strt = 1 << FLASH_F7_CR_STRT; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { - cr_reg = STM32L4_FLASH_CR; - cr_strt = (1 << STM32L4_FLASH_CR_STRT); - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_strt = (1 << STM32Gx_FLASH_CR_STRT); - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; - cr_strt = (1 << STM32WB_FLASH_CR_STRT); - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - cr_strt = 1 << FLASH_H7_CR_START(sl->chip_id); - } else { - cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; - cr_strt = (1 << FLASH_CR_STRT); + int error = -1; + size_t off; + size_t len; + + // check addr range is inside the sram + if (addr < sl->sram_base) { + fprintf(stderr, "addr too low\n"); + goto on_error; + } else if ((addr + length) < addr) { + fprintf(stderr, "addr overruns\n"); + goto on_error; + } else if ((addr + length) > (sl->sram_base + sl->sram_size)) { + fprintf(stderr, "addr too high\n"); + goto on_error; + } else if (addr & 3) { + fprintf(stderr, "unaligned addr\n"); + goto on_error; } - stlink_read_debug32(sl, cr_reg, &val); - val |= cr_strt; - stlink_write_debug32(sl, cr_reg, val); -} + len = length; -static inline uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { - uint32_t res, sr_reg; - - if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { - sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; - } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - sr_reg = FLASH_F4_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { - sr_reg = STM32L4_FLASH_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - sr_reg = STM32Gx_FLASH_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - sr_reg = STM32WB_FLASH_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; - } else { - ELOG("method 'read_flash_sr' is unsupported\n"); - return (-1); + if (len & 3) { + len -= len & 3; } - stlink_read_debug32(sl, sr_reg, &res); - return (res); -} + // do the copy by 1kB blocks + for (off = 0; off < len; off += 1024) { + size_t size = 1024; -static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { - uint32_t sr_reg; - - if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { - sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; - } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - sr_reg = FLASH_F4_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { - sr_reg = STM32L4_FLASH_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - sr_reg = STM32Gx_FLASH_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - sr_reg = STM32WB_FLASH_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; - } else { - ELOG("method 'write_flash_sr' is unsupported\n"); - return (-1); - } + if ((off + size) > len) { + size = len - off; + } - return stlink_write_debug32(sl, sr_reg, val); -} + memcpy(sl->q_buf, data + off, size); -static inline unsigned int is_flash_busy(stlink_t *sl) { - uint32_t sr_busy_shift; - unsigned int res; - - if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || - (sl->flash_type == STM32_FLASH_TYPE_L0_L1)) { - sr_busy_shift = FLASH_SR_BSY; - } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - sr_busy_shift = FLASH_F4_SR_BSY; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - sr_busy_shift = FLASH_F7_SR_BSY; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { - sr_busy_shift = STM32L4_FLASH_SR_BSY; - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - sr_busy_shift = STM32Gx_FLASH_SR_BSY; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - sr_busy_shift = STM32WB_FLASH_SR_BSY; - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - sr_busy_shift = FLASH_H7_SR_QW; - } else { - ELOG("method 'is_flash_busy' is unsupported\n"); - return (-1); - } + if (size & 3) { + size += 2; + } // round size if needed - res = read_flash_sr(sl, BANK_1) & (1 << sr_busy_shift); + stlink_write_mem32(sl, addr + (uint32_t)off, (uint16_t)size); + } - if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || - (sl->flash_type == STM32_FLASH_TYPE_H7 && - sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { - res |= read_flash_sr(sl, BANK_2) & (1 << sr_busy_shift); + if (length > len) { + memcpy(sl->q_buf, data + len, length - len); + stlink_write_mem8(sl, addr + (uint32_t)len, (uint16_t)(length - len)); } - return (res); -} + error = 0; // success + stlink_fwrite_finalize(sl, addr); -static void wait_flash_busy(stlink_t *sl) { - // TODO: add some delays here - while (is_flash_busy(sl)) - ; +on_error: + return (error); } +//284 +int stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { + // write the file in sram at addr -static void wait_flash_busy_progress(stlink_t *sl) { - int i = 0; - fprintf(stdout, "Mass erasing"); - fflush(stdout); - - while (is_flash_busy(sl)) { - usleep(10000); - i++; + int error = -1; + size_t off; + size_t len; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; - if (i % 100 == 0) { - fprintf(stdout, "."); - fflush(stdout); - } + if (map_file(&mf, path) == -1) { + fprintf(stderr, "map_file() == -1\n"); + return (-1); } - fprintf(stdout, "\n"); -} + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); -static void clear_flash_error(stlink_t *sl) { - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F0_F1_F3: - write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); - break; - case STM32_FLASH_TYPE_F2_F4: - write_flash_sr(sl, BANK_1, FLASH_F4_SR_ERROR_MASK); - break; - case STM32_FLASH_TYPE_F7: - write_flash_sr(sl, BANK_1, FLASH_F7_SR_ERROR_MASK); - break; - case STM32_FLASH_TYPE_G0: - case STM32_FLASH_TYPE_G4: - write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); - break; - case STM32_FLASH_TYPE_L0_L1: - write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); - break; - case STM32_FLASH_TYPE_L4_L4P: - write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); - break; - case STM32_FLASH_TYPE_H7: - write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_sr(sl, BANK_2, FLASH_H7_SR_ERROR_MASK); - } - break; - case STM32_FLASH_TYPE_WB_WL: - write_flash_sr(sl, BANK_1, STM32WB_FLASH_SR_ERROR_MASK); - break; - default: - break; + // check if addr range is inside the SRAM + if (addr < sl->sram_base) { + fprintf(stderr, "addr too low\n"); + goto on_error; + } else if ((addr + mf.len) < addr) { + fprintf(stderr, "addr overruns\n"); + goto on_error; + } else if ((addr + mf.len) > (sl->sram_base + sl->sram_size)) { + fprintf(stderr, "addr too high\n"); + goto on_error; + } else if (addr & 3) { + fprintf(stderr, "unaligned addr\n"); + goto on_error; } -} - -static int check_flash_error(stlink_t *sl) { - uint32_t res = 0; - uint32_t WRPERR, PROGERR, PGAERR; - WRPERR = PROGERR = PGAERR = 0; + len = mf.len; - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; - if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { - res |= read_flash_sr(sl, BANK_2) & FLASH_SR_ERROR_MASK; - } - WRPERR = (1 << FLASH_SR_WRPRT_ERR); - PROGERR = (1 << FLASH_SR_PG_ERR); - break; - case STM32_FLASH_TYPE_F2_F4: - res = read_flash_sr(sl, BANK_1) & FLASH_F4_SR_ERROR_MASK; - WRPERR = (1 << FLASH_F4_SR_WRPERR); - PGAERR = (1 << FLASH_F4_SR_PGAERR); - break; - case STM32_FLASH_TYPE_F7: - res = read_flash_sr(sl, BANK_1) & FLASH_F7_SR_ERROR_MASK; - WRPERR = (1 << FLASH_F7_SR_WRP_ERR); - PROGERR = (1 << FLASH_F7_SR_PGP_ERR); - break; - case STM32_FLASH_TYPE_G0: - case STM32_FLASH_TYPE_G4: - res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32Gx_FLASH_SR_WRPERR); - PROGERR = (1 << STM32Gx_FLASH_SR_PROGERR); - PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); - break; - case STM32_FLASH_TYPE_L0_L1: - res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); - PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); - PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); - break; - case STM32_FLASH_TYPE_L4_L4P: - res = read_flash_sr(sl, BANK_1) & STM32L4_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32L4_FLASH_SR_WRPERR); - PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); - PGAERR = (1 << STM32L4_FLASH_SR_PGAERR); - break; - case STM32_FLASH_TYPE_H7: - res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; - } - WRPERR = (1 << FLASH_H7_SR_WRPERR); - break; - case STM32_FLASH_TYPE_WB_WL: - res = read_flash_sr(sl, BANK_1) & STM32WB_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32WB_FLASH_SR_WRPERR); - PROGERR = (1 << STM32WB_FLASH_SR_PROGERR); - PGAERR = (1 << STM32WB_FLASH_SR_PGAERR); - break; - default: - break; + if (len & 3) { + len -= len & 3; } - if (res) { - if (WRPERR && (WRPERR & res) == WRPERR) { - ELOG("Flash memory is write protected\n"); - res &= ~WRPERR; - } else if (PROGERR && (PROGERR & res) == PROGERR) { - ELOG("Flash memory contains a non-erased value\n"); - res &= ~PROGERR; - } else if (PGAERR && (PGAERR & res) == PGAERR) { - ELOG("Invalid flash address\n"); - res &= ~PGAERR; - } + // do the copy by 1kB blocks + for (off = 0; off < len; off += 1024) { + size_t size = 1024; - if (res) { - ELOG("Flash programming error: %#010x\n", res); + if ((off + size) > len) { + size = len - off; } - return (-1); - } - return (0); -} + memcpy(sl->q_buf, mf.base + off, size); -static void stop_wdg_in_debug(stlink_t *sl) { - uint32_t dbgmcu_cr; - uint32_t set; - uint32_t value; + if (size & 3) { + size += 2; + } // round size if needed - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - case STM32_FLASH_TYPE_G4: - dbgmcu_cr = STM32F0_DBGMCU_CR; - set = (1 << STM32F0_DBGMCU_CR_IWDG_STOP) | - (1 << STM32F0_DBGMCU_CR_WWDG_STOP); - break; - case STM32_FLASH_TYPE_F2_F4: - case STM32_FLASH_TYPE_F7: - case STM32_FLASH_TYPE_L4_L4P: - dbgmcu_cr = STM32F4_DBGMCU_APB1FZR1; - set = (1 << STM32F4_DBGMCU_APB1FZR1_IWDG_STOP) | - (1 << STM32F4_DBGMCU_APB1FZR1_WWDG_STOP); - break; - case STM32_FLASH_TYPE_L0_L1: - case STM32_FLASH_TYPE_G0: - dbgmcu_cr = STM32L0_DBGMCU_APB1_FZ; - set = (1 << STM32L0_DBGMCU_APB1_FZ_IWDG_STOP) | - (1 << STM32L0_DBGMCU_APB1_FZ_WWDG_STOP); - break; - case STM32_FLASH_TYPE_H7: - dbgmcu_cr = STM32H7_DBGMCU_APB1HFZ; - set = (1 << STM32H7_DBGMCU_APB1HFZ_IWDG_STOP); - break; - case STM32_FLASH_TYPE_WB_WL: - dbgmcu_cr = STM32WB_DBGMCU_APB1FZR1; - set = (1 << STM32WB_DBGMCU_APB1FZR1_IWDG_STOP) | - (1 << STM32WB_DBGMCU_APB1FZR1_WWDG_STOP); - break; - default: - return; + stlink_write_mem32(sl, addr + (uint32_t)off, (uint16_t)size); } - if (!stlink_read_debug32(sl, dbgmcu_cr, &value)) { - stlink_write_debug32(sl, dbgmcu_cr, value | set); + if (mf.len > len) { + memcpy(sl->q_buf, mf.base + len, mf.len - len); + stlink_write_mem8(sl, addr + (uint32_t)len, (uint16_t)(mf.len - len)); } -} -static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { - uint32_t rcc, rcc_dma_mask, value; - - rcc = rcc_dma_mask = value = 0; - - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - rcc = STM32F1_RCC_AHBENR; - rcc_dma_mask = STM32F1_RCC_DMAEN; - break; - case STM32_FLASH_TYPE_F2_F4: - case STM32_FLASH_TYPE_F7: - rcc = STM32F4_RCC_AHB1ENR; - rcc_dma_mask = STM32F4_RCC_DMAEN; - break; - case STM32_FLASH_TYPE_G0: - rcc = STM32G0_RCC_AHBENR; - rcc_dma_mask = STM32G0_RCC_DMAEN; - break; - case STM32_FLASH_TYPE_G4: - case STM32_FLASH_TYPE_L4_L4P: - rcc = STM32G4_RCC_AHB1ENR; - rcc_dma_mask = STM32G4_RCC_DMAEN; - break; - case STM32_FLASH_TYPE_L0_L1: - rcc = STM32L0_RCC_AHBENR; - rcc_dma_mask = STM32L0_RCC_DMAEN; - break; - case STM32_FLASH_TYPE_H7: - rcc = STM32H7_RCC_AHB1ENR; - rcc_dma_mask = STM32H7_RCC_DMAEN; - break; - case STM32_FLASH_TYPE_WB_WL: - rcc = STM32WB_RCC_AHB1ENR; - rcc_dma_mask = STM32WB_RCC_DMAEN; - break; - default: - return; + // check the file has been written + if (check_file(sl, &mf, addr) == -1) { + fprintf(stderr, "check_file() == -1\n"); + goto on_error; } - if (!stlink_read_debug32(sl, rcc, &value)) { - if (bckpRstr) { - value = (value & (~rcc_dma_mask)) | fl->rcc_dma_bkp; - } else { - fl->rcc_dma_bkp = value & rcc_dma_mask; - value &= ~rcc_dma_mask; - } - stlink_write_debug32(sl, rcc, value); - } -} + error = 0; // success + stlink_fwrite_finalize(sl, addr); -static inline void write_flash_ar(stlink_t *sl, uint32_t n, unsigned bank) { - stlink_write_debug32(sl, (bank == BANK_1) ? FLASH_AR : FLASH_AR2, n); +on_error: + unmap_file(&mf); + return (error); } +// 302 +int stlink_fread(stlink_t *sl, const char *path, bool is_ihex, + stm32_addr_t addr, size_t size) { + // read size bytes from addr to file + ILOG("read from address %#010x size %u\n", addr, (unsigned)size); -static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n, - unsigned bank) { - uint32_t cr_reg, psize_shift; - uint32_t x = read_flash_cr(sl, bank); + int error; + int fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); - if (sl->flash_type == STM32_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - psize_shift = FLASH_H7_CR_PSIZE; - } else { - cr_reg = FLASH_F4_CR; - psize_shift = 8; + if (fd == -1) { + fprintf(stderr, "open(%s) == -1\n", path); + return (-1); } - x &= ~(0x03 << psize_shift); - x |= (n << psize_shift); -#if DEBUG_FLASH - fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n); -#endif - stlink_write_debug32(sl, cr_reg, x); -} + if (is_ihex) { + struct stlink_fread_ihex_worker_arg arg; -static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, unsigned bank) { - uint32_t cr_reg, snb_mask, snb_shift, ser_shift; - uint32_t x = read_flash_cr(sl, bank); + if (stlink_fread_ihex_init(&arg, fd, addr)) { + error = stlink_read(sl, addr, size, &stlink_fread_ihex_worker, &arg); - if (sl->flash_type == STM32_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - snb_mask = FLASH_H7_CR_SNB_MASK; - snb_shift = FLASH_H7_CR_SNB; - ser_shift = FLASH_H7_CR_SER; + if (!stlink_fread_ihex_finalize(&arg)) { + error = -1; + } + } else { + error = -1; + } } else { - cr_reg = FLASH_F4_CR; - snb_mask = FLASH_F4_CR_SNB_MASK; - snb_shift = FLASH_F4_CR_SNB; - ser_shift = FLASH_F4_CR_SER; + struct stlink_fread_worker_arg arg = {fd}; + error = stlink_read(sl, addr, size, &stlink_fread_worker, &arg); } - x &= ~snb_mask; - x |= (n << snb_shift); - x |= (1 << ser_shift); -#if DEBUG_FLASH - fprintf(stdout, "SNB:0x%x 0x%x\n", x, n); -#endif - stlink_write_debug32(sl, cr_reg, x); -} - -static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { - stlink_write_debug32(sl, STM32L4_FLASH_SR, - 0xFFFFFFFF & ~(1 << STM32L4_FLASH_SR_BSY)); - uint32_t x = read_flash_cr(sl, BANK_1); - x &= ~STM32L4_FLASH_CR_OPBITS; - x &= ~STM32L4_FLASH_CR_PAGEMASK; - x &= ~(1 << STM32L4_FLASH_CR_MER1); - x &= ~(1 << STM32L4_FLASH_CR_MER2); - x |= (n << STM32L4_FLASH_CR_PNB); - x |= (uint32_t)(1lu << STM32L4_FLASH_CR_PER); -#if DEBUG_FLASH - fprintf(stdout, "BKER:PNB:0x%x 0x%x\n", x, n); -#endif - stlink_write_debug32(sl, STM32L4_FLASH_CR, x); + close(fd); + return (error); } +// 300 +int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, + size_t size) { + // write the buffer right after the loader + int ret = 0; + size_t chunk = size & ~0x3; + size_t rem = size & 0x3; -// Delegates to the backends... - -void stlink_close(stlink_t *sl) { - DLOG("*** stlink_close ***\n"); + if (chunk) { + memcpy(sl->q_buf, buf, chunk); + ret = stlink_write_mem32(sl, fl->buf_addr, (uint16_t)chunk); + } - if (!sl) { - return; + if (rem && !ret) { + memcpy(sl->q_buf, buf + chunk, rem); + ret = stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, (uint16_t)rem); } - sl->backend->close(sl); - free(sl); + return (ret); } +// 291 +uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { + if ((sl->chip_id == STM32_CHIPID_F2) || + (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_DE) || + (sl->chip_id == STM32_CHIPID_F4_LP) || + (sl->chip_id == STM32_CHIPID_F4_HD) || + (sl->chip_id == STM32_CHIPID_F411xx) || + (sl->chip_id == STM32_CHIPID_F446) || + (sl->chip_id == STM32_CHIPID_F4_DSI) || + (sl->chip_id == STM32_CHIPID_F72xxx) || + (sl->chip_id == STM32_CHIPID_F412)) { + uint32_t sector = calculate_F4_sectornum(flashaddr); -int stlink_exit_debug_mode(stlink_t *sl) { - DLOG("*** stlink_exit_debug_mode ***\n"); + if (sector >= 12) { + sector -= 12; + } - if (sl->flash_type != STM32_FLASH_TYPE_UNKNOWN && - sl->core_stat != TARGET_RESET) { - // stop debugging if the target has been identified - stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); + if (sector < 4) { + sl->flash_pgsz = 0x4000; + } else if (sector < 5) { + sl->flash_pgsz = 0x10000; + } else { + sl->flash_pgsz = 0x20000; + } + } else if (sl->chip_id == STM32_CHIPID_F7 || + sl->chip_id == STM32_CHIPID_F76xxx) { + uint32_t sector = calculate_F7_sectornum(flashaddr); + + if (sector < 4) { + sl->flash_pgsz = 0x8000; + } else if (sector < 5) { + sl->flash_pgsz = 0x20000; + } else { + sl->flash_pgsz = 0x40000; + } } - return (sl->backend->exit_debug_mode(sl)); + return ((uint32_t)sl->flash_pgsz); } +// 279 +int stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **mem, + size_t *size, uint32_t *begin) { + int res = 0; + *begin = UINT32_MAX; + uint8_t *data = NULL; + uint32_t end = 0; + bool eof_found = false; -int stlink_enter_swd_mode(stlink_t *sl) { - DLOG("*** stlink_enter_swd_mode ***\n"); - return (sl->backend->enter_swd_mode(sl)); -} + for (int scan = 0; (res == 0) && (scan < 2); ++scan) { + // parse file two times - first to find memory range, second - to fill it + if (scan == 1) { + if (!eof_found) { + ELOG("No EoF recond\n"); + res = -1; + break; + } -// Force the core into the debug mode -> halted state. -int stlink_force_debug(stlink_t *sl) { - DLOG("*** stlink_force_debug_mode ***\n"); - int res = sl->backend->force_debug(sl); - if (res) { - return (res); - } - // Stop the watchdogs in the halted state for suppress target reboot - stop_wdg_in_debug(sl); - return (0); -} - -int stlink_exit_dfu_mode(stlink_t *sl) { - DLOG("*** stlink_exit_dfu_mode ***\n"); - return (sl->backend->exit_dfu_mode(sl)); -} - -int stlink_core_id(stlink_t *sl) { - int ret; - - DLOG("*** stlink_core_id ***\n"); - ret = sl->backend->core_id(sl); - - if (ret == -1) { - ELOG("Failed to read core_id\n"); - return (ret); - } - - if (sl->verbose > 2) { - stlink_print_data(sl); - } - - DLOG("core_id = 0x%08x\n", sl->core_id); - return (ret); -} - -// stlink_chip_id() is called by stlink_load_device_params() -// do not call this procedure directly. -int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { - int ret; - cortex_m3_cpuid_t cpu_id; - - // Read the CPU ID to determine where to read the core id - if (stlink_cpu_id(sl, &cpu_id) || - cpu_id.implementer_id != STLINK_REG_CMx_CPUID_IMPL_ARM) { - ELOG("Can not connect to target. Please use \'connect under reset\' and " - "try again\n"); - return -1; - } - - /* - * the chip_id register in the reference manual have - * DBGMCU_IDCODE / DBG_IDCODE name - * - */ - - if ((sl->core_id == STM32_CORE_ID_M7F_H7_SWD || sl->core_id == STM32_CORE_ID_M7F_H7_JTAG) && - cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { - // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) - ret = stlink_read_debug32(sl, 0x5c001000, chip_id); - } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0 || - cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0P) { - // STM32F0 (RM0091, pg914; RM0360, pg713) - // STM32L0 (RM0377, pg813; RM0367, pg915; RM0376, pg917) - // STM32G0 (RM0444, pg1367) - ret = stlink_read_debug32(sl, 0x40015800, chip_id); - } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM33) { - // STM32L5 (RM0438, pg2157) - ret = stlink_read_debug32(sl, 0xE0044000, chip_id); - } else /* СM3, СM4, CM7 */ { - // default chipid address - - // STM32F1 (RM0008, pg1087; RM0041, pg681) - // STM32F2 (RM0033, pg1326) - // STM32F3 (RM0316, pg1095; RM0313, pg874) - // STM32F7 (RM0385, pg1676; RM0410, pg1912) - // STM32L1 (RM0038, pg861) - // STM32L4 (RM0351, pg1840; RM0394, pg1560) - // STM32G4 (RM0440, pg2086) - // STM32WB (RM0434, pg1406) - ret = stlink_read_debug32(sl, 0xE0042000, chip_id); - } - - if (ret || !(*chip_id)) { - *chip_id = 0; - ret = ret?ret:-1; - ELOG("Could not find chip id!\n"); - } else { - *chip_id = (*chip_id) & 0xfff; - - // Fix chip_id for F4 rev A errata, read CPU ID, as CoreID is the same for - // F2/F4 - if (*chip_id == 0x411 && cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM4) { - *chip_id = 0x413; - } - } - - return (ret); -} - -/** - * Cortex M tech ref manual, CPUID register description - * @param sl stlink context - * @param cpuid pointer to the result object - */ -int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { - uint32_t raw; - - if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &raw)) { - cpuid->implementer_id = 0; - cpuid->variant = 0; - cpuid->part = 0; - cpuid->revision = 0; - return (-1); - } - - cpuid->implementer_id = (raw >> 24) & 0x7f; - cpuid->variant = (raw >> 20) & 0xf; - cpuid->part = (raw >> 4) & 0xfff; - cpuid->revision = raw & 0xf; - return (0); -} - -/** - * Reads and decodes the flash parameters, as dynamically as possible - * @param sl - * @return 0 for success, or -1 for unsupported core type. - */ -int stlink_load_device_params(stlink_t *sl) { - // This seems to normally work so is unnecessary info for a normal user. - // Demoted to debug. -- REW - DLOG("Loading device parameters....\n"); - const struct stlink_chipid_params *params = NULL; - stlink_core_id(sl); - uint32_t flash_size; - - if (stlink_chip_id(sl, &sl->chip_id)) { - return (-1); - } - - params = stlink_chipid_get_params(sl->chip_id); - - if (params == NULL) { - WLOG("unknown chip id! %#x\n", sl->chip_id); - return (-1); - } - - if (params->flash_type == STM32_FLASH_TYPE_UNKNOWN) { - WLOG("Invalid flash type, please check device declaration\n"); - sl->flash_size = 0; - return (0); - } - - // These are fixed... - sl->flash_base = STM32_FLASH_BASE; - sl->sram_base = STM32_SRAM_BASE; - stlink_read_debug32(sl, (params->flash_size_reg) & ~3, &flash_size); - - if (params->flash_size_reg & 2) { - flash_size = flash_size >> 16; - } - - flash_size = flash_size & 0xffff; - - if ((sl->chip_id == STM32_CHIPID_L1_MD || - sl->chip_id == STM32_CHIPID_F1_VL_MD_LD || - sl->chip_id == STM32_CHIPID_L1_MD_PLUS) && - (flash_size == 0)) { - sl->flash_size = 128 * 1024; - } else if (sl->chip_id == STM32_CHIPID_L1_CAT2) { - sl->flash_size = (flash_size & 0xff) * 1024; - } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_L1_MD_PLUS_HD) { - // 0 is 384k and 1 is 256k - if (flash_size == 0) { - sl->flash_size = 384 * 1024; - } else { - sl->flash_size = 256 * 1024; - } - } else { - sl->flash_size = flash_size * 1024; - } - - sl->flash_type = params->flash_type; - sl->flash_pgsz = params->flash_pagesize; - sl->sram_size = params->sram_size; - sl->sys_base = params->bootrom_base; - sl->sys_size = params->bootrom_size; - sl->option_base = params->option_base; - sl->option_size = params->option_size; - sl->chip_flags = params->flags; - - // medium and low devices have the same chipid. ram size depends on flash - // size. STM32F100xx datasheet Doc ID 16455 Table 2 - if (sl->chip_id == STM32_CHIPID_F1_VL_MD_LD && - sl->flash_size < 64 * 1024) { - sl->sram_size = 0x1000; - } - - if (sl->chip_id == STM32_CHIPID_G4_CAT3) { - uint32_t flash_optr; - stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); - - if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { - sl->flash_pgsz <<= 1; - } - } - - // H7 devices with small flash has one bank - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK && - sl->flash_type == STM32_FLASH_TYPE_H7) { - if ((sl->flash_size / sl->flash_pgsz) <= 1) - sl->chip_flags &= ~CHIP_F_HAS_DUAL_BANK; - } - - ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", - params->dev_type, (unsigned)(sl->sram_size / 1024), - (unsigned)(sl->flash_size / 1024), - (sl->flash_pgsz < 1024) ? (unsigned)(sl->flash_pgsz) - : (unsigned)(sl->flash_pgsz / 1024), - (sl->flash_pgsz < 1024) ? "byte" : "KiB"); - - return (0); -} - -int stlink_jtag_reset(stlink_t *sl, int value) { - DLOG("*** stlink_jtag_reset %d ***\n", value); - return (sl->backend->jtag_reset(sl, value)); -} - -int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { - int ret; - unsigned timeout; - uint32_t dhcsr, dfsr; - - DLOG("*** stlink_soft_reset %s***\n", halt_on_reset ? "(halt) " : ""); - - // halt core and enable debugging (if not already done) - // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) - stlink_write_debug32(sl, STLINK_REG_DHCSR, - STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | - STLINK_REG_DHCSR_C_DEBUGEN); - - // enable Halt on reset by set VC_CORERESET and TRCENA (DDI0337E, p. 10-10) - if (halt_on_reset) { - stlink_write_debug32( - sl, STLINK_REG_CM3_DEMCR, - STLINK_REG_CM3_DEMCR_TRCENA | STLINK_REG_CM3_DEMCR_VC_HARDERR | - STLINK_REG_CM3_DEMCR_VC_BUSERR | STLINK_REG_CM3_DEMCR_VC_CORERESET); - - // clear VCATCH in the DFSR register - stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_VCATCH); - } else { - stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, - STLINK_REG_CM3_DEMCR_TRCENA | - STLINK_REG_CM3_DEMCR_VC_HARDERR | - STLINK_REG_CM3_DEMCR_VC_BUSERR); - } - - // clear S_RESET_ST in the DHCSR register - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - - // soft reset (core reset) by SYSRESETREQ (DDI0337E, p. 8-23) - ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, - STLINK_REG_AIRCR_VECTKEY | - STLINK_REG_AIRCR_SYSRESETREQ); - if (ret) { - ELOG("Soft reset failed: error write to AIRCR\n"); - return (ret); - } - - // waiting for a reset within 500ms - // DDI0337E, p. 10-4, Debug Halting Control and Status Register - timeout = time_ms() + 500; - while (time_ms() < timeout) { - // DDI0337E, p. 10-4, Debug Halting Control and Status Register - dhcsr = STLINK_REG_DHCSR_S_RESET_ST; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { - if (halt_on_reset) { - // waiting halt by the SYSRESETREQ exception - // DDI0403E, p. C1-699, Debug Fault Status Register - dfsr = 0; - stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); - if ((dfsr & STLINK_REG_DFSR_VCATCH) == 0) { - continue; - } - } - timeout = 0; - break; - } - } - - // reset DFSR register. DFSR is power-on reset only (DDI0337H, p. 7-5) - stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_CLEAR); - - if (timeout) { - ELOG("Soft reset failed: timeout\n"); - return (-1); - } - - return (0); -} - -int stlink_reset(stlink_t *sl, enum reset_type type) { - uint32_t dhcsr; - unsigned timeout; - - DLOG("*** stlink_reset ***\n"); - - sl->core_stat = TARGET_RESET; - - if (type == RESET_AUTO) { - // clear S_RESET_ST in DHCSR register for reset state detection - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - } - - if (type == RESET_HARD || type == RESET_AUTO) { - // hardware target reset - if (sl->version.stlink_v > 1) { - stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); - // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) - usleep(100); - stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH); - } - sl->backend->reset(sl); - usleep(10000); - } - - if (type == RESET_AUTO) { - /* Check if the S_RESET_ST bit is set in DHCSR - * This means that a reset has occurred - * DDI0337E, p. 10-4, Debug Halting Control and Status Register */ - - dhcsr = 0; - int res = stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0 && !res) { - // reset not done yet - // try reset through AIRCR so that NRST does not need to be connected - - WLOG("NRST is not connected\n"); - DLOG("Using reset through SYSRESETREQ\n"); - return stlink_soft_reset(sl, 0); - } - - // waiting for reset the S_RESET_ST bit within 500ms - timeout = time_ms() + 500; - while (time_ms() < timeout) { - dhcsr = STLINK_REG_DHCSR_S_RESET_ST; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { - return (0); - } - } - - return (-1); - } - - if (type == RESET_SOFT || type == RESET_SOFT_AND_HALT) { - return stlink_soft_reset(sl, (type == RESET_SOFT_AND_HALT)); - } - - return (0); -} - -int stlink_run(stlink_t *sl, enum run_type type) { - struct stlink_reg rr; - DLOG("*** stlink_run ***\n"); - - /* Make sure we are in Thumb mode - * Cortex-M chips don't support ARM mode instructions - * xPSR may be incorrect if the vector table has invalid data */ - stlink_read_reg(sl, 16, &rr); - if ((rr.xpsr & (1 << 24)) == 0) { - ILOG("Go to Thumb mode\n"); - stlink_write_reg(sl, rr.xpsr | (1 << 24), 16); - } - - return (sl->backend->run(sl, type)); -} - -int stlink_set_swdclk(stlink_t *sl, int freq_khz) { - DLOG("*** set_swdclk ***\n"); - return (sl->backend->set_swdclk(sl, freq_khz)); -} - -int stlink_status(stlink_t *sl) { - int ret; - - DLOG("*** stlink_status ***\n"); - ret = sl->backend->status(sl); - stlink_core_stat(sl); - return (ret); -} - -/** - * Decode the version bits, originally from -sg, verified with usb - * @param sl stlink context, assumed to contain valid data in the buffer - * @param slv output parsed version object - */ -void _parse_version(stlink_t *sl, stlink_version_t *slv) { - sl->version.flags = 0; - - if (sl->version.stlink_v < 3) { - uint32_t b0 = sl->q_buf[0]; // lsb - uint32_t b1 = sl->q_buf[1]; - uint32_t b2 = sl->q_buf[2]; - uint32_t b3 = sl->q_buf[3]; - uint32_t b4 = sl->q_buf[4]; - uint32_t b5 = sl->q_buf[5]; // msb - - // b0 b1 || b2 b3 | b4 b5 - // 4b | 6b | 6b || 2B | 2B - // stlink_v | jtag_v | swim_v || st_vid | stlink_pid - - slv->stlink_v = (b0 & 0xf0) >> 4; - slv->jtag_v = ((b0 & 0x0f) << 2) | ((b1 & 0xc0) >> 6); - slv->swim_v = b1 & 0x3f; - slv->st_vid = (b3 << 8) | b2; - slv->stlink_pid = (b5 << 8) | b4; - - // ST-LINK/V1 from J11 switch to api-v2 (and support SWD) - if (slv->stlink_v == 1) { - slv->jtag_api = - slv->jtag_v > 11 ? STLINK_JTAG_API_V2 : STLINK_JTAG_API_V1; - } else { - slv->jtag_api = STLINK_JTAG_API_V2; - - // preferred API to get last R/W status from J15 - if (sl->version.jtag_v >= 15) { - sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; - } - - if (sl->version.jtag_v >= 13) { - sl->version.flags |= STLINK_F_HAS_TRACE; - sl->max_trace_freq = STLINK_V2_MAX_TRACE_FREQUENCY; - } - } - } else { - // V3 uses different version format, for reference see OpenOCD source - // (that was written from docs available from ST under NDA): - // https://github.com/ntfreak/openocd/blob/a6dacdff58ef36fcdac00c53ec27f19de1fbce0d/src/jtag/drivers/stlink_usb.c#L965 - slv->stlink_v = sl->q_buf[0]; - slv->swim_v = sl->q_buf[1]; - slv->jtag_v = sl->q_buf[2]; - slv->st_vid = (uint32_t)((sl->q_buf[9] << 8) | sl->q_buf[8]); - slv->stlink_pid = (uint32_t)((sl->q_buf[11] << 8) | sl->q_buf[10]); - slv->jtag_api = STLINK_JTAG_API_V3; - /* preferred API to get last R/W status */ - sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; - sl->version.flags |= STLINK_F_HAS_TRACE; - sl->max_trace_freq = STLINK_V3_MAX_TRACE_FREQUENCY; - } - - return; -} - -int stlink_version(stlink_t *sl) { - DLOG("*** looking up stlink version\n"); - - if (sl->backend->version(sl)) { - return (-1); - } - - _parse_version(sl, &sl->version); - - DLOG("st vid = 0x%04x (expect 0x%04x)\n", sl->version.st_vid, - STLINK_USB_VID_ST); - DLOG("stlink pid = 0x%04x\n", sl->version.stlink_pid); - DLOG("stlink version = 0x%x\n", sl->version.stlink_v); - DLOG("jtag version = 0x%x\n", sl->version.jtag_v); - DLOG("swim version = 0x%x\n", sl->version.swim_v); - - if (sl->version.jtag_v == 0) { - WLOG(" warning: stlink doesn't support JTAG/SWD interface\n"); - } - - return (0); -} - -int stlink_target_voltage(stlink_t *sl) { - int voltage = -1; - DLOG("*** reading target voltage\n"); - - if (sl->backend->target_voltage != NULL) { - voltage = sl->backend->target_voltage(sl); - - if (voltage != -1) { - DLOG("target voltage = %imV\n", voltage); - } else { - DLOG("error reading target voltage\n"); - } - } else { - DLOG("reading voltage not supported by backend\n"); - } - - return (voltage); -} - -int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { - int ret; - - ret = sl->backend->read_debug32(sl, addr, data); - if (!ret) - DLOG("*** stlink_read_debug32 %#010x at %#010x\n", *data, addr); - - return (ret); -} - -int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { - DLOG("*** stlink_write_debug32 %#010x to %#010x\n", data, addr); - return sl->backend->write_debug32(sl, addr, data); -} - -int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); - - if (len % 4 != 0) { - ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); - return (-1); - } - - return (sl->backend->write_mem32(sl, addr, len)); -} - -int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_read_mem32 ***\n"); - - if (len % 4 != 0) { // !!! never ever: fw gives just wrong values - ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); - return (-1); - } - - return (sl->backend->read_mem32(sl, addr, len)); -} - -int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_write_mem8 ***\n"); - return (sl->backend->write_mem8(sl, addr, len)); -} - -int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { - DLOG("*** stlink_read_all_regs ***\n"); - return (sl->backend->read_all_regs(sl, regp)); -} - -int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { - DLOG("*** stlink_read_all_unsupported_regs ***\n"); - return (sl->backend->read_all_unsupported_regs(sl, regp)); -} - -int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) { - DLOG("*** stlink_write_reg\n"); - return (sl->backend->write_reg(sl, reg, idx)); -} - -int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { - DLOG("*** stlink_read_reg\n"); - DLOG(" (%d) ***\n", r_idx); - - if (r_idx > 20 || r_idx < 0) { - fprintf(stderr, "Error: register index must be in [0..20]\n"); - return (-1); - } - - return (sl->backend->read_reg(sl, r_idx, regp)); -} - -int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, - struct stlink_reg *regp) { - int r_convert; - - DLOG("*** stlink_read_unsupported_reg\n"); - DLOG(" (%d) ***\n", r_idx); - - /* Convert to values used by STLINK_REG_DCRSR */ - if (r_idx >= 0x1C && - r_idx <= 0x1F) { // primask, basepri, faultmask, or control - r_convert = 0x14; - } else if (r_idx == 0x40) { // FPSCR - r_convert = 0x21; - } else if (r_idx >= 0x20 && r_idx < 0x40) { - r_convert = 0x40 + (r_idx - 0x20); - } else { - fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); - return (-1); - } - - return (sl->backend->read_unsupported_reg(sl, r_convert, regp)); -} - -int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, - struct stlink_reg *regp) { - int r_convert; - - DLOG("*** stlink_write_unsupported_reg\n"); - DLOG(" (%d) ***\n", r_idx); - - /* Convert to values used by STLINK_REG_DCRSR */ - if (r_idx >= 0x1C && - r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ - r_convert = r_idx; // the backend function handles this - } else if (r_idx == 0x40) { // FPSCR - r_convert = 0x21; - } else if (r_idx >= 0x20 && r_idx < 0x40) { - r_convert = 0x40 + (r_idx - 0x20); - } else { - fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); - return (-1); - } - - return (sl->backend->write_unsupported_reg(sl, val, r_convert, regp)); -} - -bool stlink_is_core_halted(stlink_t *sl) { - stlink_status(sl); - return (sl->core_stat == TARGET_HALTED); -} - -int stlink_step(stlink_t *sl) { - DLOG("*** stlink_step ***\n"); - return (sl->backend->step(sl)); -} - -int stlink_current_mode(stlink_t *sl) { - int mode = sl->backend->current_mode(sl); - - switch (mode) { - case STLINK_DEV_DFU_MODE: - DLOG("stlink current mode: dfu\n"); - return (mode); - case STLINK_DEV_DEBUG_MODE: - DLOG("stlink current mode: debug (jtag or swd)\n"); - return (mode); - case STLINK_DEV_MASS_MODE: - DLOG("stlink current mode: mass\n"); - return (mode); - } - - DLOG("stlink mode: unknown!\n"); - return (STLINK_DEV_UNKNOWN_MODE); -} - -int stlink_trace_enable(stlink_t *sl, uint32_t frequency) { - DLOG("*** stlink_trace_enable ***\n"); - return (sl->backend->trace_enable(sl, frequency)); -} - -int stlink_trace_disable(stlink_t *sl) { - DLOG("*** stlink_trace_disable ***\n"); - return (sl->backend->trace_disable(sl)); -} - -int stlink_trace_read(stlink_t *sl, uint8_t *buf, size_t size) { - return (sl->backend->trace_read(sl, buf, size)); -} - -// End of delegates.... Common code below here... - -// same as above with entrypoint. - -void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { - stlink_write_reg(sl, addr, 15); /* pc register */ - stlink_run(sl, RUN_NORMAL); - - while (stlink_is_core_halted(sl)) { - usleep(3000000); - } -} - -// this function is called by stlink_status() -// do not call stlink_core_stat() directly, always use stlink_status() -void stlink_core_stat(stlink_t *sl) { - switch (sl->core_stat) { - case TARGET_RUNNING: - DLOG(" core status: running\n"); - return; - case TARGET_HALTED: - DLOG(" core status: halted\n"); - return; - case TARGET_RESET: - DLOG(" core status: reset\n"); - return; - case TARGET_DEBUG_RUNNING: - DLOG(" core status: debug running\n"); - return; - default: - DLOG(" core status: unknown\n"); - } -} - -void stlink_print_data(stlink_t *sl) { - if (sl->q_len <= 0 || sl->verbose < UDEBUG) { - return; - } - - if (sl->verbose > 2) { - DLOG("data_len = %d 0x%x\n", sl->q_len, sl->q_len); - } - - for (int i = 0; i < sl->q_len; i++) { - if (i % 16 == 0) { - /* - if (sl->q_data_dir == Q_DATA_OUT) { - fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i); - } else { - fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); - } - */ - } - // DLOG(" %02x", (unsigned int) sl->q_buf[i]); - fprintf(stderr, " %02x", (unsigned int)sl->q_buf[i]); - } - // DLOG("\n\n"); - fprintf(stderr, "\n"); -} - -/* Memory mapped file */ -typedef struct mapped_file { - uint8_t *base; - size_t len; -} mapped_file_t; - -#define MAPPED_FILE_INITIALIZER \ - { NULL, 0 } - -static int map_file(mapped_file_t *mf, const char *path) { - int error = -1; - struct stat st; - - const int fd = open(path, O_RDONLY | O_BINARY); - - if (fd == -1) { - fprintf(stderr, "open(%s) == -1\n", path); - return (-1); - } - - if (fstat(fd, &st) == -1) { - fprintf(stderr, "fstat(%s) == -1\n", path); - goto on_error; - } - - if (sizeof(st.st_size) != sizeof(size_t)) { - // on 32 bit systems, check if there is an overflow - if (st.st_size > (off_t)SSIZE_MAX) { - fprintf(stderr, "mmap() size_t overflow for file %s\n", path); - goto on_error; - } - } - - mf->base = - (uint8_t *)mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); - - if (mf->base == MAP_FAILED) { - fprintf(stderr, "mmap() == MAP_FAILED for file %s\n", path); - goto on_error; - } - - mf->len = (size_t)st.st_size; - error = 0; // success - -on_error: - close(fd); - return (error); -} - -static void unmap_file(mapped_file_t *mf) { - munmap((void *)mf->base, mf->len); - mf->base = (unsigned char *)MAP_FAILED; - mf->len = 0; -} - -/* Limit the block size to compare to 0x1800 as anything larger will stall the - * STLINK2 Maybe STLINK V1 needs smaller value! - */ -static int check_file(stlink_t *sl, mapped_file_t *mf, stm32_addr_t addr) { - size_t off; - size_t n_cmp = sl->flash_pgsz; - - if (n_cmp > 0x1800) { - n_cmp = 0x1800; - } - - for (off = 0; off < mf->len; off += n_cmp) { - size_t aligned_size; - - size_t cmp_size = n_cmp; // adjust last page size - - if ((off + n_cmp) > mf->len) { - cmp_size = mf->len - off; - } - - aligned_size = cmp_size; - - if (aligned_size & (4 - 1)) { - aligned_size = (cmp_size + 4) & ~(4 - 1); - } - - stlink_read_mem32(sl, addr + (uint32_t)off, (uint16_t)aligned_size); - - if (memcmp(sl->q_buf, mf->base + off, cmp_size)) { - return (-1); - } - } - - return (0); -} - -static void md5_calculate(mapped_file_t *mf) { - // calculate md5 checksum of given binary file - Md5Context md5Context; - MD5_HASH md5Hash; - Md5Initialise(&md5Context); - Md5Update(&md5Context, mf->base, (uint32_t)mf->len); - Md5Finalise(&md5Context, &md5Hash); - printf("md5 checksum: "); - - for (int i = 0; i < (int)sizeof(md5Hash); i++) { - printf("%x", md5Hash.bytes[i]); - } - - printf(", "); -} - -static void stlink_checksum(mapped_file_t *mp) { - /* checksum that backward compatible with official ST tools */ - uint32_t sum = 0; - uint8_t *mp_byte = (uint8_t *)mp->base; - - for (size_t i = 0; i < mp->len; ++i) { - sum += mp_byte[i]; - } - - printf("stlink checksum: 0x%08x\n", sum); -} - -static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { - unsigned int val; - // set PC to the reset routine - stlink_read_debug32(sl, addr + 4, &val); - stlink_write_reg(sl, val, 15); - stlink_run(sl, RUN_NORMAL); -} - -int stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, - stm32_addr_t addr) { - // write the file in sram at addr - - int error = -1; - size_t off; - size_t len; - - // check addr range is inside the sram - if (addr < sl->sram_base) { - fprintf(stderr, "addr too low\n"); - goto on_error; - } else if ((addr + length) < addr) { - fprintf(stderr, "addr overruns\n"); - goto on_error; - } else if ((addr + length) > (sl->sram_base + sl->sram_size)) { - fprintf(stderr, "addr too high\n"); - goto on_error; - } else if (addr & 3) { - fprintf(stderr, "unaligned addr\n"); - goto on_error; - } - - len = length; - - if (len & 3) { - len -= len & 3; - } - - // do the copy by 1kB blocks - for (off = 0; off < len; off += 1024) { - size_t size = 1024; - - if ((off + size) > len) { - size = len - off; - } - - memcpy(sl->q_buf, data + off, size); - - if (size & 3) { - size += 2; - } // round size if needed - - stlink_write_mem32(sl, addr + (uint32_t)off, (uint16_t)size); - } - - if (length > len) { - memcpy(sl->q_buf, data + len, length - len); - stlink_write_mem8(sl, addr + (uint32_t)len, (uint16_t)(length - len)); - } - - error = 0; // success - stlink_fwrite_finalize(sl, addr); - -on_error: - return (error); -} - -int stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { - // write the file in sram at addr - - int error = -1; - size_t off; - size_t len; - mapped_file_t mf = MAPPED_FILE_INITIALIZER; - - if (map_file(&mf, path) == -1) { - fprintf(stderr, "map_file() == -1\n"); - return (-1); - } - - printf("file %s ", path); - md5_calculate(&mf); - stlink_checksum(&mf); - - // check if addr range is inside the SRAM - if (addr < sl->sram_base) { - fprintf(stderr, "addr too low\n"); - goto on_error; - } else if ((addr + mf.len) < addr) { - fprintf(stderr, "addr overruns\n"); - goto on_error; - } else if ((addr + mf.len) > (sl->sram_base + sl->sram_size)) { - fprintf(stderr, "addr too high\n"); - goto on_error; - } else if (addr & 3) { - fprintf(stderr, "unaligned addr\n"); - goto on_error; - } - - len = mf.len; - - if (len & 3) { - len -= len & 3; - } - - // do the copy by 1kB blocks - for (off = 0; off < len; off += 1024) { - size_t size = 1024; - - if ((off + size) > len) { - size = len - off; - } - - memcpy(sl->q_buf, mf.base + off, size); - - if (size & 3) { - size += 2; - } // round size if needed - - stlink_write_mem32(sl, addr + (uint32_t)off, (uint16_t)size); - } - - if (mf.len > len) { - memcpy(sl->q_buf, mf.base + len, mf.len - len); - stlink_write_mem8(sl, addr + (uint32_t)len, (uint16_t)(mf.len - len)); - } - - // check the file has been written - if (check_file(sl, &mf, addr) == -1) { - fprintf(stderr, "check_file() == -1\n"); - goto on_error; - } - - error = 0; // success - stlink_fwrite_finalize(sl, addr); - -on_error: - unmap_file(&mf); - return (error); -} - -typedef bool (*save_block_fn)(void *arg, uint8_t *block, ssize_t len); - -static int stlink_read(stlink_t *sl, stm32_addr_t addr, size_t size, - save_block_fn fn, void *fn_arg) { - - int error = -1; - - if (size < 1) { - size = sl->flash_size; - } - - if (size > sl->flash_size) { - size = sl->flash_size; - } - - size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; - - for (size_t off = 0; off < size; off += cmp_size) { - size_t aligned_size; - - // adjust last page size - if ((off + cmp_size) > size) { - cmp_size = size - off; - } - - aligned_size = cmp_size; - - if (aligned_size & (4 - 1)) { - aligned_size = (cmp_size + 4) & ~(4 - 1); - } - - stlink_read_mem32(sl, addr + (uint32_t)off, (uint16_t)aligned_size); - - if (!fn(fn_arg, sl->q_buf, aligned_size)) { - goto on_error; - } - } - - error = 0; // success - -on_error: - return (error); -} - -struct stlink_fread_worker_arg { - int fd; -}; - -static bool stlink_fread_worker(void *arg, uint8_t *block, ssize_t len) { - struct stlink_fread_worker_arg *the_arg = - (struct stlink_fread_worker_arg *)arg; - - if (write(the_arg->fd, block, len) != len) { - fprintf(stderr, "write() != aligned_size\n"); - return (false); - } else { - return (true); - } -} - -struct stlink_fread_ihex_worker_arg { - FILE *file; - uint32_t addr; - uint32_t lba; - uint8_t buf[16]; - uint8_t buf_pos; -}; - -static bool -stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg *the_arg) { - uint32_t addr = the_arg->addr; - uint8_t sum = 2 + 4 + (uint8_t)((addr & 0xFF000000) >> 24) + - (uint8_t)((addr & 0x00FF0000) >> 16); - - if (17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", - (addr & 0xFFFF0000) >> 16, (uint8_t)(0x100 - sum))) { - return (false); - } - - the_arg->lba = (addr & 0xFFFF0000); - return (true); -} - -static bool -stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg *the_arg) { - uint8_t count = the_arg->buf_pos; - - if (count == 0) { - return (true); - } - - uint32_t addr = the_arg->addr; - - if (the_arg->lba != (addr & 0xFFFF0000)) { // segment changed - if (!stlink_fread_ihex_newsegment(the_arg)) { - return (false); - } - } - - uint8_t sum = count + (uint8_t)((addr & 0x0000FF00) >> 8) + - (uint8_t)(addr & 0x000000FF); - - if (9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) { - return (false); - } - - for (uint8_t i = 0; i < count; ++i) { - uint8_t b = the_arg->buf[i]; - sum += b; - - if (2 != fprintf(the_arg->file, "%02X", b)) { - return (false); - } - } - - if (4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) { - return (false); - } - - the_arg->addr += count; - the_arg->buf_pos = 0; - - return (true); -} - -static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg *the_arg, - int fd, stm32_addr_t addr) { - the_arg->file = fdopen(fd, "w"); - the_arg->addr = addr; - the_arg->lba = 0; - the_arg->buf_pos = 0; - - return (the_arg->file != NULL); -} - -static bool stlink_fread_ihex_worker(void *arg, uint8_t *block, ssize_t len) { - struct stlink_fread_ihex_worker_arg *the_arg = - (struct stlink_fread_ihex_worker_arg *)arg; - - for (ssize_t i = 0; i < len; ++i) { - if (the_arg->buf_pos == sizeof(the_arg->buf)) { // line is full - if (!stlink_fread_ihex_writeline(the_arg)) { - return (false); - } - } - - the_arg->buf[the_arg->buf_pos++] = block[i]; - } - - return (true); -} - -static bool -stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg *the_arg) { - if (!stlink_fread_ihex_writeline(the_arg)) { - return (false); - } - - // FIXME: do we need the Start Linear Address? - - if (13 != fprintf(the_arg->file, ":00000001FF\r\n")) { // EoF - return (false); - } - - return (0 == fclose(the_arg->file)); -} - -int stlink_fread(stlink_t *sl, const char *path, bool is_ihex, - stm32_addr_t addr, size_t size) { - // read size bytes from addr to file - ILOG("read from address %#010x size %u\n", addr, (unsigned)size); - - int error; - int fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); - - if (fd == -1) { - fprintf(stderr, "open(%s) == -1\n", path); - return (-1); - } - - if (is_ihex) { - struct stlink_fread_ihex_worker_arg arg; - - if (stlink_fread_ihex_init(&arg, fd, addr)) { - error = stlink_read(sl, addr, size, &stlink_fread_ihex_worker, &arg); - - if (!stlink_fread_ihex_finalize(&arg)) { - error = -1; - } - } else { - error = -1; - } - } else { - struct stlink_fread_worker_arg arg = {fd}; - error = stlink_read(sl, addr, size, &stlink_fread_worker, &arg); - } - - close(fd); - return (error); -} - -int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, - size_t size) { - // write the buffer right after the loader - int ret = 0; - size_t chunk = size & ~0x3; - size_t rem = size & 0x3; - - if (chunk) { - memcpy(sl->q_buf, buf, chunk); - ret = stlink_write_mem32(sl, fl->buf_addr, (uint16_t)chunk); - } - - if (rem && !ret) { - memcpy(sl->q_buf, buf + chunk, rem); - ret = stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, (uint16_t)rem); - } - - return (ret); -} - -uint32_t calculate_F4_sectornum(uint32_t flashaddr) { - uint32_t offset = 0; - flashaddr &= ~STM32_FLASH_BASE; // page now holding the actual flash address - - if (flashaddr >= 0x100000) { - offset = 12; - flashaddr -= 0x100000; - } - - if (flashaddr < 0x4000) { - return (offset + 0); - } else if (flashaddr < 0x8000) { - return (offset + 1); - } else if (flashaddr < 0xc000) { - return (offset + 2); - } else if (flashaddr < 0x10000) { - return (offset + 3); - } else if (flashaddr < 0x20000) { - return (offset + 4); - } else { - return (offset + (flashaddr / 0x20000) + 4); - } -} - -uint32_t calculate_F7_sectornum(uint32_t flashaddr) { - flashaddr &= ~STM32_FLASH_BASE; // Page now holding the actual flash address - - if (flashaddr < 0x20000) { - return (flashaddr / 0x8000); - } else if (flashaddr < 0x40000) { - return (4); - } else { - return ((flashaddr / 0x40000) + 4); - } -} - -uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, - unsigned bank) { - flashaddr &= - ~((bank == BANK_1) - ? STM32_FLASH_BASE - : STM32_H7_FLASH_BANK2_BASE); // sector holding the flash address - return (flashaddr / sl->flash_pgsz); -} - -// returns BKER:PNB for the given page address -uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { - uint32_t bker = 0; - uint32_t flashopt; - stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); - flashaddr -= STM32_FLASH_BASE; - - if (sl->chip_id == STM32_CHIPID_L4 || - sl->chip_id == STM32_CHIPID_L496x_L4A6x || - sl->chip_id == STM32_CHIPID_L4Rx) { - // this chip use dual banked flash - if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { - uint32_t banksize = (uint32_t)sl->flash_size / 2; - - if (flashaddr >= banksize) { - flashaddr -= banksize; - bker = 0x100; - } - } - } - - // For 1MB chips without the dual-bank option set, the page address will - // overflow into the BKER bit, which gives us the correct bank:page value. - return (bker | flashaddr / (uint32_t)sl->flash_pgsz); -} - -uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { - if ((sl->chip_id == STM32_CHIPID_F2) || - (sl->chip_id == STM32_CHIPID_F4) || - (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || - (sl->chip_id == STM32_CHIPID_F4_HD) || - (sl->chip_id == STM32_CHIPID_F411xx) || - (sl->chip_id == STM32_CHIPID_F446) || - (sl->chip_id == STM32_CHIPID_F4_DSI) || - (sl->chip_id == STM32_CHIPID_F72xxx) || - (sl->chip_id == STM32_CHIPID_F412)) { - uint32_t sector = calculate_F4_sectornum(flashaddr); - - if (sector >= 12) { - sector -= 12; - } - - if (sector < 4) { - sl->flash_pgsz = 0x4000; - } else if (sector < 5) { - sl->flash_pgsz = 0x10000; - } else { - sl->flash_pgsz = 0x20000; - } - } else if (sl->chip_id == STM32_CHIPID_F7 || - sl->chip_id == STM32_CHIPID_F76xxx) { - uint32_t sector = calculate_F7_sectornum(flashaddr); - - if (sector < 4) { - sl->flash_pgsz = 0x8000; - } else if (sector < 5) { - sl->flash_pgsz = 0x20000; - } else { - sl->flash_pgsz = 0x40000; - } - } - - return ((uint32_t)sl->flash_pgsz); -} - -/** - * Erase a page of flash, assumes sl is fully populated with things like - * chip/core ids - * @param sl stlink context - * @param flashaddr an address in the flash page to erase - * @return 0 on success -ve on failure - */ -int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - // wait for ongoing op to finish - wait_flash_busy(sl); - // clear flash IO errors - clear_flash_error(sl); - - if (sl->flash_type == STM32_FLASH_TYPE_F2_F4 || - sl->flash_type == STM32_FLASH_TYPE_F7 || - sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { - // unlock if locked - unlock_flash_if(sl); - - // select the page to erase - if ((sl->chip_id == STM32_CHIPID_L4) || - (sl->chip_id == STM32_CHIPID_L43x_L44x) || - (sl->chip_id == STM32_CHIPID_L45x_L46x) || - (sl->chip_id == STM32_CHIPID_L496x_L4A6x) || - (sl->chip_id == STM32_CHIPID_L4Rx)) { - // calculate the actual bank+page from the address - uint32_t page = calculate_L4_page(sl, flashaddr); - - fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", page, - stlink_calculate_pagesize(sl, flashaddr)); - - write_flash_cr_bker_pnb(sl, page); - } else if (sl->chip_id == STM32_CHIPID_F7 || - sl->chip_id == STM32_CHIPID_F76xxx) { - // calculate the actual page from the address - uint32_t sector = calculate_F7_sectornum(flashaddr); - - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, - stlink_calculate_pagesize(sl, flashaddr)); - write_flash_cr_snb(sl, sector, BANK_1); - } else { - // calculate the actual page from the address - uint32_t sector = calculate_F4_sectornum(flashaddr); - - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, - stlink_calculate_pagesize(sl, flashaddr)); - - // the SNB values for flash sectors in the second bank do not directly - // follow the values for the first bank on 2mb devices... - if (sector >= 12) { - sector += 4; - } - - write_flash_cr_snb(sl, sector, BANK_1); - } - - set_flash_cr_strt(sl, BANK_1); // start erase operation - wait_flash_busy(sl); // wait for completion - lock_flash(sl); // TODO: fails to program if this is in -#if DEBUG_FLASH - fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl, BANK_1)); -#endif - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - - // check if the locks are set - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - - if ((val & (1 << 0)) || (val & (1 << 1))) { - // disable pecr protection - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, - FLASH_L0_PEKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, - FLASH_L0_PEKEY2); - - // check pecr.pelock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - - if (val & (1 << 0)) { - WLOG("pecr.pelock not clear (%#x)\n", val); - return (-1); - } - - // unlock program memory - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, - FLASH_L0_PRGKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, - FLASH_L0_PRGKEY2); - - // check pecr.prglock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - - if (val & (1 << 1)) { - WLOG("pecr.prglock not clear (%#x)\n", val); - return (-1); - } - } - - // set pecr.{erase,prog} - val |= (1 << 9) | (1 << 3); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - - // write 0 to the first word of the page to be erased - stlink_write_debug32(sl, flashaddr, 0); - - /* MP: It is better to wait for clearing the busy bit after issuing page - * erase command, even though PM0062 recommends to wait before it. - * Test shows that a few iterations is performed in the following loop - * before busy bit is cleared. - */ - wait_flash_busy(sl); - - // reset lock bits - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || - sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - uint32_t val; - unlock_flash_if(sl); - set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit - - // set the page to erase - if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - uint32_t flash_page = - ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - - // sec 3.10.5 - PNB[7:0] is offset by 3. - val &= ~(0xFF << 3); // Clear previously set page number (if any) - val |= ((flash_page & 0xFF) << 3); - - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - } else if (sl->flash_type == STM32_FLASH_TYPE_G0) { - uint32_t flash_page = - ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. - val &= ~(0x3F << 3); - val |= ((flash_page & 0x3F) << 3) | (1 << FLASH_CR_PER); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - } else if (sl->flash_type == STM32_FLASH_TYPE_G4) { - uint32_t flash_page = - ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. - val &= ~(0x7F << 3); - val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - } - - set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit - wait_flash_busy(sl); // wait for the 'busy' bit to clear - clear_flash_cr_per(sl, BANK_1); // clear the 'enable page erase' bit - lock_flash(sl); - } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3 || - sl->flash_type == STM32_FLASH_TYPE_F1_XL) { - unsigned bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; - unlock_flash_if(sl); - clear_flash_cr_pg(sl, bank); // clear the pg bit - set_flash_cr_per(sl, bank); // set the page erase bit - write_flash_ar(sl, flashaddr, bank); // select the page to erase - set_flash_cr_strt(sl, - bank); // start erase operation, reset by hw with busy bit - wait_flash_busy(sl); - clear_flash_cr_per(sl, bank); // clear the page erase bit - lock_flash(sl); - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; - unlock_flash_if(sl); // unlock if locked - uint32_t sector = calculate_H7_sectornum( - sl, flashaddr, bank); // calculate the actual page from the address - write_flash_cr_snb(sl, sector, bank); // select the page to erase - set_flash_cr_strt(sl, bank); // start erase operation - wait_flash_busy(sl); // wait for completion - lock_flash(sl); - } else { - WLOG("unknown coreid %x, page erase failed\n", sl->core_id); - return (-1); - } - - return check_flash_error(sl); -} - -// Check if an address and size are within the flash -int stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size) { - if (addr < sl->flash_base || addr >= (sl->flash_base + sl->flash_size)) { - ELOG("Invalid address, it should be within 0x%08x - 0x%08lx\n", sl->flash_base, (sl->flash_base + sl->flash_size -1)); - return (-1); - } - if ((addr + size) > (sl->flash_base + sl->flash_size)) { - ELOG("The size exceeds the size of the flash (0x%08lx bytes available)\n", (sl->flash_base + sl->flash_size - addr)); - return (-1); - } - return 0; -} - -// Check if an address is aligned with the beginning of a page -int stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr) { - stm32_addr_t page = sl->flash_base; - - while (page < addr) { - page += stlink_calculate_pagesize(sl, page); - } - - if (page != addr) { - return -1; - } - - return 0; -} - -int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size) { - // Check the address and size validity - if (stlink_check_address_range_validity(sl, base_addr, size) < 0) { - return -1; - } - - // Make sure the requested address is aligned with the beginning of a page - if (stlink_check_address_alignment(sl, base_addr) < 0) { - ELOG("The address to erase is not aligned with the beginning of a page\n"); - return -1; - } - - stm32_addr_t addr = base_addr; - do { - size_t page_size = stlink_calculate_pagesize(sl, addr); - - // Check if size is aligned with a page, unless we want to completely erase the last page - if ((addr + page_size) > (base_addr + size) && !align_size) { - ELOG("Invalid size (not aligned with a page). Page size at address %#x is %#lx\n", addr, page_size); - return -1; - } - - if (stlink_erase_flash_page(sl, addr)) { - WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); - return (-1); - } - - fprintf(stdout, "-> Flash page at %#x erased (size: %#lx)\n", addr, page_size); - fflush(stdout); - - // check the next page is within the range to erase - addr += page_size; - } while (addr < (base_addr + size)); - - fprintf(stdout, "\n"); - return 0; -} - -int stlink_erase_flash_mass(stlink_t *sl) { - int err = 0; - - // TODO: User MER bit to mass-erase WB series. - if (sl->flash_type == STM32_FLASH_TYPE_L0_L1 || - sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - - err = stlink_erase_flash_section(sl, sl->flash_base, sl->flash_size, false); - - } else { - wait_flash_busy(sl); - clear_flash_error(sl); - unlock_flash_if(sl); - - if (sl->flash_type == STM32_FLASH_TYPE_H7 && - sl->chip_id != STM32_CHIPID_H7Ax) { - // set parallelism - write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); - } - } - - set_flash_cr_mer(sl, 1, BANK_1); // set the mass erase bit - set_flash_cr_strt( - sl, BANK_1); // start erase operation, reset by hw with busy bit - - if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || - (sl->flash_type == STM32_FLASH_TYPE_H7 && - sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { - set_flash_cr_mer(sl, 1, BANK_2); // set the mass erase bit in bank 2 - set_flash_cr_strt(sl, BANK_2); // start erase operation in bank 2 - } - - wait_flash_busy_progress(sl); - lock_flash(sl); - - // reset the mass erase bit - set_flash_cr_mer(sl, 0, BANK_1); - if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || - (sl->flash_type == STM32_FLASH_TYPE_H7 && - sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { - set_flash_cr_mer(sl, 0, BANK_2); - } - - err = check_flash_error(sl); - } - - return (err); -} - -int stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { - // check the contents of path are at addr - - int res; - mapped_file_t mf = MAPPED_FILE_INITIALIZER; - - if (map_file(&mf, path) == -1) { - return (-1); - } - - res = check_file(sl, &mf, addr); - unmap_file(&mf); - return (res); -} - -/** - * Verify addr..addr+len is binary identical to base...base+len - * @param sl stlink context - * @param address stm device address - * @param data host side buffer to check against - * @param length how much - * @return 0 for success, -ve for failure - */ -int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, - unsigned length) { - size_t off; - size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; - ILOG("Starting verification of write complete\n"); - - for (off = 0; off < length; off += cmp_size) { - size_t aligned_size; - - // adjust last page size - if ((off + cmp_size) > length) { - cmp_size = length - off; - } - - aligned_size = cmp_size; - - if (aligned_size & (4 - 1)) { - aligned_size = (cmp_size + 4) & ~(4 - 1); - } - - stlink_read_mem32(sl, address + (uint32_t)off, (uint16_t)aligned_size); - - if (memcmp(sl->q_buf, data + off, cmp_size)) { - ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); - return (-1); - } - } - - ILOG("Flash written and verified! jolly good!\n"); - return (0); -} - -int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, - uint32_t len, uint32_t pagesize) { - unsigned int count, off; - unsigned int num_half_pages = len / pagesize; - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - flash_loader_t fl; - bool use_loader = true; - int ret = 0; - - // enable half page write - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << FLASH_L1_FPRG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - val |= (1 << FLASH_L1_PROG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - - wait_flash_busy(sl); - - for (count = 0; count < num_half_pages; count++) { - if (use_loader) { - ret = stlink_flash_loader_run(sl, &fl, addr + count * pagesize, - base + count * pagesize, pagesize); - if (ret && count == 0) { - /* It seems that stm32lx devices have a problem when it is blank */ - WLOG("Failed to use flash loader, fallback to soft write\n"); - use_loader = false; - } - } - if (!use_loader) { - ret = 0; - for (off = 0; off < pagesize && !ret; off += 64) { - size_t chunk = (pagesize - off > 64) ? 64 : pagesize - off; - memcpy(sl->q_buf, base + count * pagesize + off, chunk); - ret = stlink_write_mem32(sl, addr + count * pagesize + off, (uint16_t)chunk); - } - } - - if (ret) { - WLOG("l1_stlink_flash_loader_run(%#x) failed! == -1\n", - addr + count * pagesize); - break; - } - - if (sl->verbose >= 1) { - // show progress; writing procedure is slow and previous errors are - // misleading - fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); - fflush(stdout); - } - - // wait for sr.busy to be cleared - wait_flash_busy(sl); - } - - // disable half page write - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - return (ret); -} - -int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { - // disable DMA - set_dma_state(sl, fl, 0); - - // wait for ongoing op to finish - wait_flash_busy(sl); - // Clear errors - clear_flash_error(sl); - - if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || - (sl->flash_type == STM32_FLASH_TYPE_F7) || - (sl->flash_type == STM32_FLASH_TYPE_L4_L4P)) { - ILOG("Starting Flash write for F2/F4/F7/L4\n"); - - // Flash loader initialisation - if (stlink_flash_loader_init(sl, fl) == -1) { - ELOG("stlink_flash_loader_init() == -1\n"); - return (-1); - } - - unlock_flash_if(sl); // first unlock the cr - - int voltage; - if (sl->version.stlink_v == 1) { - WLOG("STLINK V1 cannot read voltage, use default voltage 3.2V\n"); - voltage = 3200; - } else { - voltage = stlink_target_voltage(sl); - } - - if (voltage == -1) { - ELOG("Failed to read Target voltage\n"); - return (-1); - } - - if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { - // L4 does not have a byte-write mode - if (voltage < 1710) { - ELOG("Target voltage (%d mV) too low for flash writes!\n", voltage); - return (-1); - } - } else { - if (voltage > 2700) { - ILOG("enabling 32-bit flash writes\n"); - write_flash_cr_psiz(sl, 2, BANK_1); - } else { - ILOG("Target voltage (%d mV) too low for 32-bit flash, " - "using 8-bit flash writes\n", - voltage); - write_flash_cr_psiz(sl, 0, BANK_1); - } - } - - // set programming mode - set_flash_cr_pg(sl, BANK_1); - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || - sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - ILOG("Starting Flash write for WB/G0/G4\n"); - - unlock_flash_if(sl); // unlock flash if necessary - set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - ILOG("Starting Flash write for L0\n"); - - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - - // disable pecr protection - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, - FLASH_L0_PEKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, - FLASH_L0_PEKEY2); - - // check pecr.pelock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if (val & (1 << 0)) { - ELOG("pecr.pelock not clear\n"); - return (-1); - } - - // unlock program memory - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, - FLASH_L0_PRGKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, - FLASH_L0_PRGKEY2); - - // check pecr.prglock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if (val & (1 << 1)) { - ELOG("pecr.prglock not clear\n"); - return (-1); - } - - /* Flash loader initialisation */ - if (stlink_flash_loader_init(sl, fl) == -1) { - // L0/L1 have fallback to soft write - WLOG("stlink_flash_loader_init() == -1\n"); - } - } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { - ILOG("Starting Flash write for VL/F0/F3/F1_XL\n"); - - // flash loader initialisation - if (stlink_flash_loader_init(sl, fl) == -1) { - ELOG("stlink_flash_loader_init() == -1\n"); - return (-1); - } - - // unlock flash - unlock_flash_if(sl); - - // set programming mode - set_flash_cr_pg(sl, BANK_1); - if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { - set_flash_cr_pg(sl, BANK_2); - } - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - ILOG("Starting Flash write for H7\n"); - - unlock_flash_if(sl); // unlock the cr - set_flash_cr_pg(sl, BANK_1); // set programming mode - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - set_flash_cr_pg(sl, BANK_2); - } - if (sl->chip_id != STM32_CHIPID_H7Ax) { - // set parallelism - write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); - } - } - } else { - ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); - return (-1); - } - - return (0); -} - -int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, - stm32_addr_t addr, uint8_t *base, uint32_t len) { - size_t off; - if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || - (sl->flash_type == STM32_FLASH_TYPE_F7) || - (sl->flash_type == STM32_FLASH_TYPE_L4_L4P)) { - size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; - for (off = 0; off < len;) { - size_t size = len - off > buf_size ? buf_size : len - off; - if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, - size) == -1) { - ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", - (unsigned)(addr + off)); - check_flash_error(sl); - return (-1); - } - - off += size; - } - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || - sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); - for (off = 0; off < len; off += sizeof(uint32_t)) { - uint32_t data; - - if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { - fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off / sl->flash_pgsz), - (unsigned int)(len / sl->flash_pgsz)); - fflush(stdout); - } - - write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); - stlink_write_debug32(sl, addr + (uint32_t)off, data); - wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear - } - fprintf(stdout, "\n"); - - // flash writes happen as 2 words at a time - if ((off / sizeof(uint32_t)) % 2 != 0) { - stlink_write_debug32(sl, addr + (uint32_t)off, - 0); // write a single word of zeros - wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear - } - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - uint32_t pagesize = (flash_regs_base==STM32L0_FLASH_REGS_ADDR)? - L0_WRITE_BLOCK_SIZE:L1_WRITE_BLOCK_SIZE; - - DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); - - off = 0; - - if (len > pagesize) { - if (stm32l1_write_half_pages(sl, addr, base, len, pagesize)) { - return (-1); - } else { - off = (size_t)(len / pagesize) * pagesize; - } - } - - // write remaining word in program memory - for (; off < len; off += sizeof(uint32_t)) { - uint32_t data; - - if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { - fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off / sl->flash_pgsz), - (unsigned int)(len / sl->flash_pgsz)); - fflush(stdout); - } - - write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); - stlink_write_debug32(sl, addr + (uint32_t)off, data); - - // wait for sr.busy to be cleared - do { - stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); - } while ((val & (1 << 0)) != 0); - - // TODO: check redo write operation - } - fprintf(stdout, "\n"); - } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { - int write_block_count = 0; - for (off = 0; off < len; off += sl->flash_pgsz) { - // adjust last write size - size_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; - - // unlock and set programming mode - unlock_flash_if(sl); - - DLOG("Finished unlocking flash, running loader!\n"); - - if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, - size) == -1) { - ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", - (unsigned)(addr + off)); - check_flash_error(sl); - return (-1); - } - - lock_flash(sl); - - if (sl->verbose >= 1) { - // show progress; writing procedure is slow and previous errors are - // misleading - fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, - (unsigned int)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); - fflush(stdout); - } - } - if (sl->verbose >= 1) { - fprintf(stdout, "\n"); - } - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - for (off = 0; off < len;) { - // Program STM32H7x with 64-byte Flash words - size_t chunk = (len - off > 64) ? 64 : len - off; - memcpy(sl->q_buf, base + off, chunk); - stlink_write_mem32(sl, addr + (uint32_t)off, 64); - wait_flash_busy(sl); - - off += chunk; - - if (sl->verbose >= 1) { - // show progress - fprintf(stdout, "\r%u/%u bytes written", (unsigned int)off, - (unsigned int)len); - fflush(stdout); - } - } - if (sl->verbose >= 1) { - fprintf(stdout, "\n"); - } - } else { - return (-1); - } - - return check_flash_error(sl); -} - -int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { - uint32_t dhcsr; - - if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || - (sl->flash_type == STM32_FLASH_TYPE_F2_F4) || - (sl->flash_type == STM32_FLASH_TYPE_F7) || - (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) || - (sl->flash_type == STM32_FLASH_TYPE_WB_WL) || - (sl->flash_type == STM32_FLASH_TYPE_G0) || - (sl->flash_type == STM32_FLASH_TYPE_G4) || - (sl->flash_type == STM32_FLASH_TYPE_H7)) { - - clear_flash_cr_pg(sl, BANK_1); - if ((sl->flash_type == STM32_FLASH_TYPE_H7 && - sl->chip_flags & CHIP_F_HAS_DUAL_BANK) || - sl->flash_type == STM32_FLASH_TYPE_F1_XL) { - clear_flash_cr_pg(sl, BANK_2); - } - lock_flash(sl); - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - - // reset lock bits - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } - - // enable interrupt - if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) { - stlink_write_debug32(sl, STLINK_REG_DHCSR, - STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | - (dhcsr & (~STLINK_REG_DHCSR_C_MASKINTS))); - } - - // restore DMA state - set_dma_state(sl, fl, 1); - - return (0); -} - -int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, - uint32_t len, uint8_t eraseonly) { - int ret; - flash_loader_t fl; - ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, - len, addr, addr); - // check addr range is inside the flash - stlink_calculate_pagesize(sl, addr); - - // Check the address and size validity - if (stlink_check_address_range_validity(sl, addr, len) < 0) { - return (-1); - } else if (len & 1) { - WLOG("unaligned len 0x%x -- padding with zero\n", len); - len += 1; - } else if (stlink_check_address_alignment(sl, addr) < 0) { - ELOG("addr not a multiple of current pagesize (%u bytes), not supported, " - "check page start address and compare with flash module organisation " - "in related ST reference manual of your device.\n", - (unsigned)(sl->flash_pgsz)); - return (-1); - } - - // make sure we've loaded the context with the chip details - stlink_core_id(sl); - - // Erase this section of the flash - if (stlink_erase_flash_section(sl, addr, len, true) < 0) { - ELOG("Failed to erase the flash prior to writing\n"); - return (-1); - } - - if (eraseonly) { - return (0); - } - - ret = stlink_flashloader_start(sl, &fl); - if (ret) - return ret; - ret = stlink_flashloader_write(sl, &fl, addr, base, len); - if (ret) - return ret; - ret = stlink_flashloader_stop(sl, &fl); - if (ret) - return ret; - - return (stlink_verify_write_flash(sl, addr, base, len)); -} - -// TODO: length not checked -static uint8_t stlink_parse_hex(const char *hex) { - uint8_t d[2]; - - for (int i = 0; i < 2; ++i) { - char c = *(hex + i); - - if (c >= '0' && c <= '9') { - d[i] = c - '0'; - } else if (c >= 'A' && c <= 'F') { - d[i] = c - 'A' + 10; - } else if (c >= 'a' && c <= 'f') { - d[i] = c - 'a' + 10; - } else { - return (0); // error - } - } - - return ((d[0] << 4) | (d[1])); -} - -int stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **mem, - size_t *size, uint32_t *begin) { - int res = 0; - *begin = UINT32_MAX; - uint8_t *data = NULL; - uint32_t end = 0; - bool eof_found = false; - - for (int scan = 0; (res == 0) && (scan < 2); ++scan) { - // parse file two times - first to find memory range, second - to fill it - if (scan == 1) { - if (!eof_found) { - ELOG("No EoF recond\n"); - res = -1; - break; - } - - if (*begin >= end) { - ELOG("No data found in file\n"); - res = -1; - break; - } - - *size = (end - *begin) + 1; - data = calloc(*size, 1); // use calloc to get NULL if out of memory - - if (!data) { - ELOG("Cannot allocate %u bytes\n", (unsigned)(*size)); - res = -1; - break; - } - - memset(data, erased_pattern, *size); - } - - FILE *file = fopen(path, "r"); - - if (!file) { - ELOG("Cannot open file\n"); - res = -1; - break; - } - - uint32_t lba = 0; - char line[1 + 5 * 2 + 255 * 2 + 2]; - - while (fgets(line, sizeof(line), file)) { - if (line[0] == '\n' || line[0] == '\r') { - continue; - } // skip empty lines - - if (line[0] != ':') { // no marker - wrong file format - ELOG("Wrong file format - no marker\n"); - res = -1; - break; - } - - size_t l = strlen(line); - - while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r')) { - --l; - } // trim EoL - - if ((l < 11) || - (l == - (sizeof(line) - 1))) { // line too short or long - wrong file format - ELOG("Wrong file format - wrong line length\n"); - res = -1; - break; - } - - uint8_t chksum = 0; // check sum - - for (size_t i = 1; i < l; i += 2) { - chksum += stlink_parse_hex(line + i); - } - - if (chksum != 0) { - ELOG("Wrong file format - checksum mismatch\n"); - res = -1; - break; - } - - uint8_t reclen = stlink_parse_hex(line + 1); - - if (((uint32_t)reclen + 5) * 2 + 1 != l) { - ELOG("Wrong file format - record length mismatch\n"); - res = -1; - break; - } - - uint16_t offset = ((uint16_t)stlink_parse_hex(line + 3) << 8) | - ((uint16_t)stlink_parse_hex(line + 5)); - uint8_t rectype = stlink_parse_hex(line + 7); - - switch (rectype) { - case 0: /* Data */ - if (scan == 0) { - uint32_t b = lba + offset; - uint32_t e = b + reclen - 1; - - if (b < *begin) { - *begin = b; - } - - if (e > end) { - end = e; - } - } else { - for (uint8_t i = 0; i < reclen; ++i) { - uint8_t b = stlink_parse_hex(line + 9 + i * 2); - uint32_t addr = lba + offset + i; - - if (addr >= *begin && addr <= end) { - data[addr - *begin] = b; - } - } - } - break; - case 1: /* EoF */ - eof_found = true; - break; - case 2: /* Extended Segment Address, unexpected */ - res = -1; - break; - case 3: /* Start Segment Address, unexpected */ - res = -1; - break; - case 4: /* Extended Linear Address */ - if (reclen == 2) { - lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | - ((uint32_t)stlink_parse_hex(line + 11) << 16); - } else { - ELOG("Wrong file format - wrong LBA length\n"); - res = -1; - } - break; - case 5: /* Start Linear Address - expected, but ignore */ - break; - default: - ELOG("Wrong file format - unexpected record type %d\n", rectype); - res = -1; - } - - if (res != 0) { - break; - } - } - - fclose(file); - } - - if (res == 0) { - *mem = data; - } else { - free(data); - } - - return (res); -} - -uint8_t stlink_get_erased_pattern(stlink_t *sl) { - if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - return (0x00); - } else { - return (0xff); - } -} - -int stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, - stm32_addr_t addr) { - /* Write the block in flash at addr */ - int err; - unsigned int num_empty, idx; - uint8_t erased_pattern = stlink_get_erased_pattern(sl); - - /* - * This optimisation may cause unexpected garbage data remaining. - * Therfore it is turned off by default. - */ - if (sl->opt) { - idx = (unsigned int)length; - - for (num_empty = 0; num_empty != length; ++num_empty) - if (data[--idx] != erased_pattern) { - break; - } - - num_empty -= (num_empty & 3); // Round down to words - - if (num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, - erased_pattern); - } - } else { - num_empty = 0; - } - - /* - * TODO: investigate a kind of weird behaviour here: - * If the file is identified to be all-empty and four-bytes aligned, - * still flash the whole file even if ignoring message is printed. - */ - err = stlink_write_flash(sl, addr, data, - (num_empty == length) ? (uint32_t)length - : (uint32_t)length - num_empty, - num_empty == length); - stlink_fwrite_finalize(sl, addr); - return (err); -} - -/** - * Write the given binary file into flash at address "addr" - * @param sl - * @param path readable file path, should be binary image - * @param addr where to start writing - * @return 0 on success, -ve on failure. - */ -int stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { - /* Write the file in flash at addr */ - int err; - unsigned int num_empty, idx; - uint8_t erased_pattern = stlink_get_erased_pattern(sl); - mapped_file_t mf = MAPPED_FILE_INITIALIZER; - - if (map_file(&mf, path) == -1) { - ELOG("map_file() == -1\n"); - return (-1); - } - - printf("file %s ", path); - md5_calculate(&mf); - stlink_checksum(&mf); - - if (sl->opt) { - idx = (unsigned int)mf.len; - - for (num_empty = 0; num_empty != mf.len; ++num_empty) { - if (mf.base[--idx] != erased_pattern) { - break; - } - } - - num_empty -= (num_empty & 3); // round down to words - - if (num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, - erased_pattern); - } - } else { - num_empty = 0; - } - - /* - * TODO: investigate a kind of weird behaviour here: - * If the file is identified to be all-empty and four-bytes aligned, - * still flash the whole file even if ignoring message is printed. - */ - err = stlink_write_flash(sl, addr, mf.base, - (num_empty == mf.len) ? (uint32_t)mf.len - : (uint32_t)mf.len - num_empty, - num_empty == mf.len); - stlink_fwrite_finalize(sl, addr); - unmap_file(&mf); - return (err); -} - -/** - * Write option bytes - * @param sl - * @param base option bytes to write - * @param addr of the memory mapped option bytes - * @param len of options bytes to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_f0( - stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - int ret = 0; - - if (len < 12 || addr != STM32_F0_OPTION_BYTES_BASE) { - WLOG("Only full write of option bytes area is supported\n"); - return -1; - } - - clear_flash_error(sl); - - WLOG("Erasing option bytes\n"); - - /* erase option bytes */ - stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTER) | (1 << FLASH_CR_OPTWRE)); - ret = stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTER) | (1 << FLASH_CR_STRT) | (1 << FLASH_CR_OPTWRE)); - if (ret) { - return ret; - } - - wait_flash_busy(sl); - - ret = check_flash_error(sl); - if (ret) { - return ret; - } - - WLOG("Writing option bytes to %#10x\n", addr); - - /* Set the Option PG bit to enable programming */ - stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTPG) | (1 << FLASH_CR_OPTWRE)); - - /* Use flash loader for write OP - * because flash memory writable by half word */ - flash_loader_t fl; - ret = stlink_flash_loader_init(sl, &fl); - if (ret) { - return ret; - } - ret = stlink_flash_loader_run(sl, &fl, addr, base, len); - if (ret) { - return ret; - } - - /* Reload option bytes */ - stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OBL_LAUNCH)); - - return check_flash_error(sl); -} - -/** - * Write option bytes - * @param sl - * @param addr of the memory mapped option bytes - * @param base option bytes to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - /* Write options bytes */ - uint32_t val; - int ret = 0; - (void)len; - uint32_t data; - - clear_flash_error(sl); - - write_uint32((unsigned char *)&data, *(uint32_t *)(base)); - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); - - // Set Options Start bit - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - - wait_flash_busy(sl); - - ret = check_flash_error(sl); - - // Reload options - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - - return (ret); -} - -/** - * Write option bytes - * @param sl - * @param addr of the memory mapped option bytes - * @param base option bytes to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - uint32_t flash_base = get_stm32l0_flash_base(sl); - uint32_t val; - uint32_t data; - int ret = 0; - - // Clear errors - clear_flash_error(sl); - - while (len != 0) { - write_uint32((unsigned char *)&data, - *(uint32_t *)(base)); // write options bytes - - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - stlink_write_debug32(sl, addr, data); - wait_flash_busy(sl); - - if ((ret = check_flash_error(sl))) { - break; - } - - len -= 4; - addr += 4; - base += 4; - } - - // Reload options - stlink_read_debug32(sl, flash_base + FLASH_PECR_OFF, &val); - val |= (1 << STM32L0_FLASH_OBL_LAUNCH); - stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); - - return (ret); -} - -/** - * Write option bytes - * @param sl - * @param addr of the memory mapped option bytes - * @param base option bytes to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_l4(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - - uint32_t val; - int ret = 0; - (void)addr; - (void)len; - - // Clear errors - clear_flash_error(sl); - - // write options bytes - uint32_t data; - write_uint32((unsigned char *)&data, *(uint32_t *)(base)); - WLOG("Writing option bytes 0x%04x\n", data); - stlink_write_debug32(sl, STM32L4_FLASH_OPTR, data); - - // set options start bit - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1 << STM32L4_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - - wait_flash_busy(sl); - ret = check_flash_error(sl); - - // apply options bytes immediate - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - - return (ret); -} - -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - uint32_t option_byte; - int ret = 0; - (void)addr; - (void)len; - - // Clear errors - clear_flash_error(sl); - - write_uint32((unsigned char *)&option_byte, *(uint32_t *)(base)); - - // write option byte, ensuring we dont lock opt, and set strt bit - stlink_write_debug32(sl, FLASH_F4_OPTCR, - (option_byte & ~(1 << FLASH_F4_OPTCR_LOCK)) | - (1 << FLASH_F4_OPTCR_START)); - - wait_flash_busy(sl); - ret = check_flash_error(sl); - - // option bytes are reloaded at reset only, no obl. */ - return (ret); -} - -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - uint32_t option_byte; - int ret = 0; - - // Clear errors - clear_flash_error(sl); - - ILOG("Asked to write option byte %#10x to %#010x.\n", *(uint32_t *)(base), - addr); - write_uint32((unsigned char *)&option_byte, *(uint32_t *)(base)); - ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); - - if (addr == 0) { - addr = FLASH_F7_OPTCR; - ILOG("No address provided, using %#10x\n", addr); - } - - if (addr == FLASH_F7_OPTCR) { - /* write option byte, ensuring we dont lock opt, and set strt bit */ - stlink_write_debug32(sl, FLASH_F7_OPTCR, - (option_byte & ~(1 << FLASH_F7_OPTCR_LOCK)) | - (1 << FLASH_F7_OPTCR_START)); - } else if (addr == FLASH_F7_OPTCR1) { - // Read FLASH_F7_OPTCR - uint32_t oldvalue; - stlink_read_debug32(sl, FLASH_F7_OPTCR, &oldvalue); - /* write option byte */ - stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_byte); - // Write FLASH_F7_OPTCR lock and start address - stlink_write_debug32(sl, FLASH_F7_OPTCR, - (oldvalue & ~(1 << FLASH_F7_OPTCR_LOCK)) | - (1 << FLASH_F7_OPTCR_START)); - } else { - WLOG("WIP: write %#010x to address %#010x\n", option_byte, addr); - stlink_write_debug32(sl, addr, option_byte); - } - - wait_flash_busy(sl); - - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t *)base, - addr); - - /* option bytes are reloaded at reset only, no obl. */ - - return ret; -} - -/** - * Write STM32H7xx option bytes - * @param sl - * @param base option bytes to write - * @param addr of the memory mapped option bytes - * @param len number of bytes to write (must be multiple of 4) - * @return 0 on success, -ve on failure. - */ -static int stlink_write_option_bytes_h7(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - uint32_t val; - uint32_t data; - - // Wait until previous flash option has completed - wait_flash_busy(sl); - - // Clear previous error - stlink_write_debug32(sl, FLASH_H7_OPTCCR, - 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); - - while (len != 0) { - switch (addr) { - case FLASH_H7_REGS_ADDR + 0x20: // FLASH_OPTSR_PRG - case FLASH_H7_REGS_ADDR + 0x2c: // FLASH_PRAR_PRG1 - case FLASH_H7_REGS_ADDR + 0x34: // FLASH_SCAR_PRG1 - case FLASH_H7_REGS_ADDR + 0x3c: // FLASH_WPSN_PRG1 - case FLASH_H7_REGS_ADDR + 0x44: // FLASH_BOOT_PRG - /* Write to FLASH_xxx_PRG registers */ - write_uint32((unsigned char *)&data, - *(uint32_t *)(base)); // write options bytes - - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - - /* Skip if the value in the CUR register is identical */ - stlink_read_debug32(sl, addr - 4, &val); - if (val == data) { + if (*begin >= end) { + ELOG("No data found in file\n"); + res = -1; break; } - /* Write new option byte values and start modification */ - stlink_write_debug32(sl, addr, data); - stlink_read_debug32(sl, FLASH_H7_OPTCR, &val); - val |= (1 << FLASH_H7_OPTCR_OPTSTART); - stlink_write_debug32(sl, FLASH_H7_OPTCR, val); - - /* Wait for the option bytes modification to complete */ - do { - stlink_read_debug32(sl, FLASH_H7_OPTSR_CUR, &val); - } while ((val & (1 << FLASH_H7_OPTSR_OPT_BUSY)) != 0); - - /* Check for errors */ - if ((val & (1 << FLASH_H7_OPTSR_OPTCHANGEERR)) != 0) { - stlink_write_debug32(sl, FLASH_H7_OPTCCR, - 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); - return -1; + *size = (end - *begin) + 1; + data = calloc(*size, 1); // use calloc to get NULL if out of memory + + if (!data) { + ELOG("Cannot allocate %u bytes\n", (unsigned)(*size)); + res = -1; + break; } - break; - default: - /* Skip non-programmable registers */ - break; + memset(data, erased_pattern, *size); } - len -= 4; - addr += 4; - base += 4; - } - - return 0; -} - -/** - * Read option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_Gx(stlink_t *sl, - uint32_t *option_byte) { - return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); -} - -/** - * Read option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t *option_byte) { - return stlink_read_option_control_register_Gx(sl, option_byte); -} - -/** - * Read option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_f2(stlink_t *sl, - uint32_t *option_byte) { - return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); -} - -/** - * Read option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t *option_byte) { - return stlink_read_option_control_register_f2(sl, option_byte); -} - -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_f4(stlink_t *sl, - uint32_t *option_byte) { - return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); -} + FILE *file = fopen(path, "r"); -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t *option_byte) { - return stlink_read_option_control_register_f4(sl, option_byte); -} + if (!file) { + ELOG("Cannot open file\n"); + res = -1; + break; + } -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_f7(stlink_t *sl, - uint32_t *option_byte) { - DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_F7_OPTCR); - return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte); -} + uint32_t lba = 0; + char line[1 + 5 * 2 + 255 * 2 + 2]; -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_f0(stlink_t *sl, - uint32_t *option_byte) { - DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_OBR); - return stlink_read_debug32(sl, FLASH_OBR, option_byte); -} + while (fgets(line, sizeof(line), file)) { + if (line[0] == '\n' || line[0] == '\r') { + continue; + } // skip empty lines -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register1_f7(stlink_t *sl, - uint32_t *option_byte) { - DLOG("@@@@ Read option control register 1 byte from %#10x\n", - FLASH_F7_OPTCR1); - return stlink_read_debug32(sl, FLASH_F7_OPTCR1, option_byte); -} + if (line[0] != ':') { // no marker - wrong file format + ELOG("Wrong file format - no marker\n"); + res = -1; + break; + } -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t *option_byte) { - DLOG("@@@@ Read option byte boot address\n"); - return stlink_read_option_control_register1_f7(sl, option_byte); -} + size_t l = strlen(line); -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - * - * Since multiple bytes can be read, we read and print all but one here - * and then return the last one just like other devices - */ -int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t *option_byte) { - int err = -1; - for (uint32_t counter = 0; counter < (sl->option_size / 4 - 1); counter++) { - err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), - option_byte); - if (err == -1) { - return err; - } else { - printf("%08x\n", *option_byte); - } - } + while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r')) { + --l; + } // trim EoL - return stlink_read_debug32( - sl, - sl->option_base + (uint32_t)(sl->option_size / 4 - 1) * sizeof(uint32_t), - option_byte); -} + if ((l < 11) || + (l == + (sizeof(line) - 1))) { // line too short or long - wrong file format + ELOG("Wrong file format - wrong line length\n"); + res = -1; + break; + } -/** - * Read first option bytes - * @param sl - * @param option_byte option value - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte) { - DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); - return stlink_read_debug32(sl, sl->option_base, option_byte); -} + uint8_t chksum = 0; // check sum -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -// int stlink_read_option_bytes_boot_add_generic(stlink_t *sl, uint32_t* -// option_byte) { -// DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); -// return stlink_read_debug32(sl, sl->option_base, option_byte); -//} + for (size_t i = 1; i < l; i += 2) { + chksum += stlink_parse_hex(line + i); + } -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -// int stlink_read_option_control_register_generic(stlink_t *sl, uint32_t* -// option_byte) { -// DLOG("@@@@ Read option control register byte from %#10x\n", -// sl->option_base); return stlink_read_debug32(sl, sl->option_base, -// option_byte); -//} + if (chksum != 0) { + ELOG("Wrong file format - checksum mismatch\n"); + res = -1; + break; + } -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -// int stlink_read_option_control_register1_generic(stlink_t *sl, uint32_t* -// option_byte) { -// DLOG("@@@@ Read option control register 1 byte from %#10x\n", -// sl->option_base); return stlink_read_debug32(sl, sl->option_base, -// option_byte); -//} + uint8_t reclen = stlink_parse_hex(line + 1); -/** - * Read option bytes - * @param sl - * @param option_byte option value - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); - return (-1); - } + if (((uint32_t)reclen + 5) * 2 + 1 != l) { + ELOG("Wrong file format - record length mismatch\n"); + res = -1; + break; + } - switch (sl->chip_id) { - case STM32_CHIPID_F2: - return stlink_read_option_bytes_f2(sl, option_byte); - case STM32_CHIPID_F4: - case STM32_CHIPID_F446: - return stlink_read_option_bytes_f4(sl, option_byte); - case STM32_CHIPID_F76xxx: - return stlink_read_option_bytes_f7(sl, option_byte); - case STM32_CHIPID_G0_CAT1: - case STM32_CHIPID_G0_CAT2: - case STM32_CHIPID_G4_CAT2: - case STM32_CHIPID_G4_CAT3: - return stlink_read_option_bytes_Gx(sl, option_byte); - default: - return stlink_read_option_bytes_generic(sl, option_byte); - } -} + uint16_t offset = ((uint16_t)stlink_parse_hex(line + 3) << 8) | + ((uint16_t)stlink_parse_hex(line + 5)); + uint8_t rectype = stlink_parse_hex(line + 7); -/** - * Read option bytes - * @param sl - * @param option_byte option value - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { - if (sl->option_base == 0) { - ELOG("Option bytes boot address read is currently not supported for " - "connected chip\n"); - return -1; - } + switch (rectype) { + case 0: /* Data */ + if (scan == 0) { + uint32_t b = lba + offset; + uint32_t e = b + reclen - 1; - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F7: - return stlink_read_option_bytes_boot_add_f7(sl, option_byte); - default: - return -1; - // return stlink_read_option_bytes_boot_add_generic(sl, option_byte); - } -} + if (b < *begin) { + *begin = b; + } -/** - * Read option bytes - * @param sl - * @param option_byte option value - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); - return -1; - } + if (e > end) { + end = e; + } + } else { + for (uint8_t i = 0; i < reclen; ++i) { + uint8_t b = stlink_parse_hex(line + 9 + i * 2); + uint32_t addr = lba + offset + i; - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - return stlink_read_option_control_register_f0(sl, option_byte); - case STM32_FLASH_TYPE_F7: - return stlink_read_option_control_register_f7(sl, option_byte); - default: - return -1; - } -} + if (addr >= *begin && addr <= end) { + data[addr - *begin] = b; + } + } + } + break; + case 1: /* EoF */ + eof_found = true; + break; + case 2: /* Extended Segment Address, unexpected */ + res = -1; + break; + case 3: /* Start Segment Address, unexpected */ + res = -1; + break; + case 4: /* Extended Linear Address */ + if (reclen == 2) { + lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | + ((uint32_t)stlink_parse_hex(line + 11) << 16); + } else { + ELOG("Wrong file format - wrong LBA length\n"); + res = -1; + } + break; + case 5: /* Start Linear Address - expected, but ignore */ + break; + default: + ELOG("Wrong file format - unexpected record type %d\n", rectype); + res = -1; + } -/** - * Read option bytes - * @param sl - * @param option_byte option value - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register1_32(stlink_t *sl, - uint32_t *option_byte) { - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); - return -1; + if (res != 0) { + break; + } + } + + fclose(file); } - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F7: - return stlink_read_option_control_register1_f7(sl, option_byte); - default: - return -1; - // return stlink_read_option_control_register1_generic(sl, option_byte); + if (res == 0) { + *mem = data; + } else { + free(data); } + + return (res); } -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { - WLOG("About to write option byte %#10x to %#10x.\n", option_byte, - sl->option_base); - return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *)&option_byte, - 4); +uint8_t stlink_get_erased_pattern(stlink_t *sl) { + if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + return (0x00); + } else { + return (0xff); + } } -/** - * Write option bytes - * @param sl - * @param addr of the memory mapped option bytes - * @param base option bytes to write - * @return 0 on success, -ve on failure. - */ -int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, - uint32_t len) { - int ret = -1; +int stlink_target_connect(stlink_t *sl, enum connect_type connect) { + if (connect == CONNECT_UNDER_RESET) { + stlink_enter_swd_mode(sl); - if (sl->option_base == 0) { - ELOG( - "Option bytes writing is currently not supported for connected chip\n"); - return (-1); + stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); + + // try to halt the core before reset + // this is useful if the NRST pin is not connected + sl->backend->force_debug(sl); + + // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) + usleep(20); + + stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH); + + // try to halt the core after reset + unsigned timeout = time_ms() + 10; + while (time_ms() < timeout) { + sl->backend->force_debug(sl); + usleep(100); + } + + // check NRST connection + uint32_t dhcsr = 0; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + WLOG("NRST is not connected\n"); + } + + // addition soft reset for halt before the first instruction + stlink_soft_reset(sl, 1 /* halt on reset */); } - if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { - ELOG("Option bytes start address out of Option bytes range\n"); - return (-1); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE && + stlink_enter_swd_mode(sl)) { + printf("Failed to enter SWD mode\n"); + return -1; } - if (addr + len > sl->option_base + sl->option_size) { - ELOG("Option bytes data too long\n"); - return (-1); + if (connect == CONNECT_NORMAL) { + stlink_reset(sl, RESET_AUTO); } - wait_flash_busy(sl); + return stlink_load_device_params(sl); +} - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it " - "again!\n"); - return (-1); - } +// End of delegates.... functions below are private to this module +// same as above with entrypoint. - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return (-1); - } +static void stop_wdg_in_debug(stlink_t *sl) { + uint32_t dbgmcu_cr; + uint32_t set; + uint32_t value; switch (sl->flash_type) { case STM32_FLASH_TYPE_F0_F1_F3: case STM32_FLASH_TYPE_F1_XL: - ret = stlink_write_option_bytes_f0(sl, base, addr, len); + case STM32_FLASH_TYPE_G4: + dbgmcu_cr = STM32F0_DBGMCU_CR; + set = (1 << STM32F0_DBGMCU_CR_IWDG_STOP) | + (1 << STM32F0_DBGMCU_CR_WWDG_STOP); break; case STM32_FLASH_TYPE_F2_F4: - ret = stlink_write_option_bytes_f4(sl, base, addr, len); - break; case STM32_FLASH_TYPE_F7: - ret = stlink_write_option_bytes_f7(sl, base, addr, len); - break; - case STM32_FLASH_TYPE_L0_L1: - ret = stlink_write_option_bytes_l0(sl, base, addr, len); - break; case STM32_FLASH_TYPE_L4_L4P: - ret = stlink_write_option_bytes_l4(sl, base, addr, len); + dbgmcu_cr = STM32F4_DBGMCU_APB1FZR1; + set = (1 << STM32F4_DBGMCU_APB1FZR1_IWDG_STOP) | + (1 << STM32F4_DBGMCU_APB1FZR1_WWDG_STOP); break; + case STM32_FLASH_TYPE_L0_L1: case STM32_FLASH_TYPE_G0: - case STM32_FLASH_TYPE_G4: - ret = stlink_write_option_bytes_gx(sl, base, addr, len); + dbgmcu_cr = STM32L0_DBGMCU_APB1_FZ; + set = (1 << STM32L0_DBGMCU_APB1_FZ_IWDG_STOP) | + (1 << STM32L0_DBGMCU_APB1_FZ_WWDG_STOP); break; case STM32_FLASH_TYPE_H7: - ret = stlink_write_option_bytes_h7(sl, base, addr, len); + dbgmcu_cr = STM32H7_DBGMCU_APB1HFZ; + set = (1 << STM32H7_DBGMCU_APB1HFZ_IWDG_STOP); break; - default: - ELOG("Option bytes writing is currently not implemented for connected " - "chip\n"); + case STM32_FLASH_TYPE_WB_WL: + dbgmcu_cr = STM32WB_DBGMCU_APB1FZR1; + set = (1 << STM32WB_DBGMCU_APB1FZR1_IWDG_STOP) | + (1 << STM32WB_DBGMCU_APB1FZR1_WWDG_STOP); break; + default: + return; } - if (ret) { - ELOG("Flash option write failed!\n"); - } else { - ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + if (!stlink_read_debug32(sl, dbgmcu_cr, &value)) { + stlink_write_debug32(sl, dbgmcu_cr, value | set); } +} - /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); - - return ret; +int stlink_jtag_reset(stlink_t *sl, int value) { + DLOG("*** stlink_jtag_reset %d ***\n", value); + return (sl->backend->jtag_reset(sl, value)); } -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -static int -stlink_write_option_control_register_f7(stlink_t *sl, - uint32_t option_control_register) { - int ret = 0; +int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { + int ret; + unsigned timeout; + uint32_t dhcsr, dfsr; + + DLOG("*** stlink_soft_reset %s***\n", halt_on_reset ? "(halt) " : ""); + + // halt core and enable debugging (if not already done) + // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_DEBUGEN); - // Clear errors - clear_flash_error(sl); + // enable Halt on reset by set VC_CORERESET and TRCENA (DDI0337E, p. 10-10) + if (halt_on_reset) { + stlink_write_debug32( + sl, STLINK_REG_CM3_DEMCR, + STLINK_REG_CM3_DEMCR_TRCENA | STLINK_REG_CM3_DEMCR_VC_HARDERR | + STLINK_REG_CM3_DEMCR_VC_BUSERR | STLINK_REG_CM3_DEMCR_VC_CORERESET); - ILOG("Asked to write option control register 1 %#10x to %#010x.\n", - option_control_register, FLASH_F7_OPTCR); + // clear VCATCH in the DFSR register + stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_VCATCH); + } else { + stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, + STLINK_REG_CM3_DEMCR_TRCENA | + STLINK_REG_CM3_DEMCR_VC_HARDERR | + STLINK_REG_CM3_DEMCR_VC_BUSERR); + } - /* write option byte, ensuring we dont lock opt, and set strt bit */ - stlink_write_debug32(sl, FLASH_F7_OPTCR, - (option_control_register & ~(1 << FLASH_F7_OPTCR_LOCK)) | - (1 << FLASH_F7_OPTCR_START)); + // clear S_RESET_ST in the DHCSR register + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - wait_flash_busy(sl); + // soft reset (core reset) by SYSRESETREQ (DDI0337E, p. 8-23) + ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, + STLINK_REG_AIRCR_VECTKEY | + STLINK_REG_AIRCR_SYSRESETREQ); + if (ret) { + ELOG("Soft reset failed: error write to AIRCR\n"); + return (ret); + } - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, - FLASH_F7_OPTCR); + // waiting for a reset within 500ms + // DDI0337E, p. 10-4, Debug Halting Control and Status Register + timeout = time_ms() + 500; + while (time_ms() < timeout) { + // DDI0337E, p. 10-4, Debug Halting Control and Status Register + dhcsr = STLINK_REG_DHCSR_S_RESET_ST; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + if (halt_on_reset) { + // waiting halt by the SYSRESETREQ exception + // DDI0403E, p. C1-699, Debug Fault Status Register + dfsr = 0; + stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); + if ((dfsr & STLINK_REG_DFSR_VCATCH) == 0) { + continue; + } + } + timeout = 0; + break; + } + } - return ret; -} + // reset DFSR register. DFSR is power-on reset only (DDI0337H, p. 7-5) + stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_CLEAR); + if (timeout) { + ELOG("Soft reset failed: timeout\n"); + return (-1); + } + return (0); +} /** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. + * Decode the version bits, originally from -sg, verified with usb + * @param sl stlink context, assumed to contain valid data in the buffer + * @param slv output parsed version object */ -static int -stlink_write_option_control_register_f0(stlink_t *sl, - uint32_t option_control_register) { - int ret = 0; - uint16_t opt_val[8]; - unsigned protection, optiondata; - uint16_t user_options, user_data, rdp; - unsigned option_offset, user_data_offset; +void _parse_version(stlink_t *sl, stlink_version_t *slv) { + sl->version.flags = 0; + + if (sl->version.stlink_v < 3) { + uint32_t b0 = sl->q_buf[0]; // lsb + uint32_t b1 = sl->q_buf[1]; + uint32_t b2 = sl->q_buf[2]; + uint32_t b3 = sl->q_buf[3]; + uint32_t b4 = sl->q_buf[4]; + uint32_t b5 = sl->q_buf[5]; // msb - ILOG("Asked to write option control register %#10x to %#010x.\n", - option_control_register, FLASH_OBR); + // b0 b1 || b2 b3 | b4 b5 + // 4b | 6b | 6b || 2B | 2B + // stlink_v | jtag_v | swim_v || st_vid | stlink_pid - /* Clear errors */ - clear_flash_error(sl); + slv->stlink_v = (b0 & 0xf0) >> 4; + slv->jtag_v = ((b0 & 0x0f) << 2) | ((b1 & 0xc0) >> 6); + slv->swim_v = b1 & 0x3f; + slv->st_vid = (b3 << 8) | b2; + slv->stlink_pid = (b5 << 8) | b4; - /* Retrieve current values */ - ret = stlink_read_debug32(sl, FLASH_OBR, &optiondata); - if (ret) { - return ret; + // ST-LINK/V1 from J11 switch to api-v2 (and support SWD) + if (slv->stlink_v == 1) { + slv->jtag_api = + slv->jtag_v > 11 ? STLINK_JTAG_API_V2 : STLINK_JTAG_API_V1; + } else { + slv->jtag_api = STLINK_JTAG_API_V2; + + // preferred API to get last R/W status from J15 + if (sl->version.jtag_v >= 15) { + sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; + } + + if (sl->version.jtag_v >= 13) { + sl->version.flags |= STLINK_F_HAS_TRACE; + sl->max_trace_freq = STLINK_V2_MAX_TRACE_FREQUENCY; + } + } + } else { + // V3 uses different version format, for reference see OpenOCD source + // (that was written from docs available from ST under NDA): + // https://github.com/ntfreak/openocd/blob/a6dacdff58ef36fcdac00c53ec27f19de1fbce0d/src/jtag/drivers/stlink_usb.c#L965 + slv->stlink_v = sl->q_buf[0]; + slv->swim_v = sl->q_buf[1]; + slv->jtag_v = sl->q_buf[2]; + slv->st_vid = (uint32_t)((sl->q_buf[9] << 8) | sl->q_buf[8]); + slv->stlink_pid = (uint32_t)((sl->q_buf[11] << 8) | sl->q_buf[10]); + slv->jtag_api = STLINK_JTAG_API_V3; + /* preferred API to get last R/W status */ + sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; + sl->version.flags |= STLINK_F_HAS_TRACE; + sl->max_trace_freq = STLINK_V3_MAX_TRACE_FREQUENCY; } - ret = stlink_read_debug32(sl, FLASH_WRPR, &protection); - if (ret) { - return ret; + + return; +} + +void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { + stlink_write_reg(sl, addr, 15); /* pc register */ + stlink_run(sl, RUN_NORMAL); + + while (stlink_is_core_halted(sl)) { + usleep(3000000); } +} - /* Translate OBR value to flash store structure - * F0: RM0091, Option byte description, pp. 75-78 - * F1: PM0075, Option byte description, pp. 19-22 - * F3: RM0316, Option byte description, pp. 85-87 */ - switch(sl->chip_id) - { - case 0x422: /* STM32F30x */ - case 0x432: /* STM32F37x */ - case 0x438: /* STM32F303x6/8 and STM32F328 */ - case 0x446: /* STM32F303xD/E and STM32F398xE */ - case 0x439: /* STM32F302x6/8 */ - case 0x440: /* STM32F05x */ - case 0x444: /* STM32F03x */ - case 0x445: /* STM32F04x */ - case 0x448: /* STM32F07x */ - case 0x442: /* STM32F09x */ - option_offset = 6; - user_data_offset = 16; - rdp = 0x55AA; - break; - default: - option_offset = 0; - user_data_offset = 10; - rdp = 0x5AA5; - break; +/* Limit the block size to compare to 0x1800 as anything larger will stall the + * STLINK2 Maybe STLINK V1 needs smaller value! + */ +int check_file(stlink_t *sl, mapped_file_t *mf, stm32_addr_t addr) { + size_t off; + size_t n_cmp = sl->flash_pgsz; + + if (n_cmp > 0x1800) { + n_cmp = 0x1800; } - user_options = (option_control_register >> option_offset >> 2) & 0xFFFF; - user_data = (option_control_register >> user_data_offset) & 0xFFFF; + for (off = 0; off < mf->len; off += n_cmp) { + size_t aligned_size; + + size_t cmp_size = n_cmp; // adjust last page size -#define VAL_WITH_COMPLEMENT(v) (uint16_t)(((v)&0xFF) | (((~(v))<<8)&0xFF00)) + if ((off + n_cmp) > mf->len) { + cmp_size = mf->len - off; + } - opt_val[0] = (option_control_register & (1 << 1/*OPT_READOUT*/)) ? 0xFFFF : rdp; - opt_val[1] = VAL_WITH_COMPLEMENT(user_options); - opt_val[2] = VAL_WITH_COMPLEMENT(user_data); - opt_val[3] = VAL_WITH_COMPLEMENT(user_data >> 8); - opt_val[4] = VAL_WITH_COMPLEMENT(protection); - opt_val[5] = VAL_WITH_COMPLEMENT(protection >> 8); - opt_val[6] = VAL_WITH_COMPLEMENT(protection >> 16); - opt_val[7] = VAL_WITH_COMPLEMENT(protection >> 24); + aligned_size = cmp_size; -#undef VAL_WITH_COMPLEMENT + if (aligned_size & (4 - 1)) { + aligned_size = (cmp_size + 4) & ~(4 - 1); + } - /* Write bytes and check errors */ - ret = stlink_write_option_bytes_f0(sl, (uint8_t*)opt_val, STM32_F0_OPTION_BYTES_BASE, sizeof(opt_val)); - if (ret) - return ret; + stlink_read_mem32(sl, addr + (uint32_t)off, (uint16_t)aligned_size); - ret = check_flash_error(sl); - if (!ret) { - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, - FLASH_OBR); + if (memcmp(sl->q_buf, mf->base + off, cmp_size)) { + return (-1); + } } - return ret; + return (0); } -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -static int -stlink_write_option_control_register1_f7(stlink_t *sl, - uint32_t option_control_register1) { - int ret = 0; - - // Clear errors - clear_flash_error(sl); - - ILOG("Asked to write option control register 1 %#010x to %#010x.\n", - option_control_register1, FLASH_F7_OPTCR1); +void md5_calculate(mapped_file_t *mf) { + // calculate md5 checksum of given binary file + Md5Context md5Context; + MD5_HASH md5Hash; + Md5Initialise(&md5Context); + Md5Update(&md5Context, mf->base, (uint32_t)mf->len); + Md5Finalise(&md5Context, &md5Hash); + printf("md5 checksum: "); - /* write option byte, ensuring we dont lock opt, and set strt bit */ - uint32_t current_control_register_value; - stlink_read_debug32(sl, FLASH_F7_OPTCR, ¤t_control_register_value); + for (int i = 0; i < (int)sizeof(md5Hash); i++) { + printf("%x", md5Hash.bytes[i]); + } - /* write option byte */ - stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_control_register1); - stlink_write_debug32( - sl, FLASH_F7_OPTCR, - (current_control_register_value & ~(1 << FLASH_F7_OPTCR_LOCK)) | - (1 << FLASH_F7_OPTCR_START)); + printf(", "); +} - wait_flash_busy(sl); +void stlink_checksum(mapped_file_t *mp) { + /* checksum that backward compatible with official ST tools */ + uint32_t sum = 0; + uint8_t *mp_byte = (uint8_t *)mp->base; - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register1, - FLASH_F7_OPTCR1); + for (size_t i = 0; i < mp->len; ++i) { + sum += mp_byte[i]; + } - return ret; + printf("stlink checksum: 0x%08x\n", sum); } -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -static int -stlink_write_option_bytes_boot_add_f7(stlink_t *sl, - uint32_t option_byte_boot_add) { - ILOG("Asked to write option byte boot add %#010x.\n", option_byte_boot_add); - return stlink_write_option_control_register1_f7(sl, option_byte_boot_add); +void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { + unsigned int val; + // set PC to the reset routine + stlink_read_debug32(sl, addr + 4, &val); + stlink_write_reg(sl, val, 15); + stlink_run(sl, RUN_NORMAL); } -/** - * Write option bytes - * @param sl - * @param option bytes boot address to write - * @return 0 on success, -ve on failure. - */ -int stlink_write_option_bytes_boot_add32(stlink_t *sl, - uint32_t option_bytes_boot_add) { - int ret = -1; - - wait_flash_busy(sl); +static int stlink_read(stlink_t *sl, stm32_addr_t addr, size_t size, + save_block_fn fn, void *fn_arg) { - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it " - "again!\n"); - return -1; - } + int error = -1; - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; + if (size < 1) { + size = sl->flash_size; } - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F7: - ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); - break; - default: - ELOG("Option bytes boot address writing is currently not implemented for " - "connected chip\n"); - break; + if (size > sl->flash_size) { + size = sl->flash_size; } - if (ret) - ELOG("Flash option write failed!\n"); - else - ILOG("Wrote option bytes boot address %#010x!\n", option_bytes_boot_add); + size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; - /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); + for (size_t off = 0; off < size; off += cmp_size) { + size_t aligned_size; - return ret; -} + // adjust last page size + if ((off + cmp_size) > size) { + cmp_size = size - off; + } -/** - * Write option bytes - * @param sl - * @param option bytes boot address to write - * @return 0 on success, -ve on failure. - */ -int stlink_write_option_control_register32(stlink_t *sl, - uint32_t option_control_register) { - int ret = -1; + aligned_size = cmp_size; - wait_flash_busy(sl); + if (aligned_size & (4 - 1)) { + aligned_size = (cmp_size + 4) & ~(4 - 1); + } - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it " - "again!\n"); - return -1; - } + stlink_read_mem32(sl, addr + (uint32_t)off, (uint16_t)aligned_size); - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; + if (!fn(fn_arg, sl->q_buf, aligned_size)) { + goto on_error; + } } - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - ret = stlink_write_option_control_register_f0(sl, option_control_register); - break; - case STM32_FLASH_TYPE_F7: - ret = stlink_write_option_control_register_f7(sl, option_control_register); - break; - default: - ELOG("Option control register writing is currently not implemented for " - "connected chip\n"); - break; - } + error = 0; // success - if (ret) - ELOG("Flash option write failed!\n"); - else - ILOG("Wrote option control register %#010x!\n", option_control_register); +on_error: + return (error); +} - /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); +static bool stlink_fread_worker(void *arg, uint8_t *block, ssize_t len) { + struct stlink_fread_worker_arg *the_arg = + (struct stlink_fread_worker_arg *)arg; - return ret; + if (write(the_arg->fd, block, len) != len) { + fprintf(stderr, "write() != aligned_size\n"); + return (false); + } else { + return (true); + } } -/** - * Write option bytes - * @param sl - * @param option bytes boot address to write - * @return 0 on success, -ve on failure. - */ -int stlink_write_option_control_register1_32( - stlink_t *sl, uint32_t option_control_register1) { - int ret = -1; +// TODO: length not checked +static uint8_t stlink_parse_hex(const char *hex) { + uint8_t d[2]; - wait_flash_busy(sl); + for (int i = 0; i < 2; ++i) { + char c = *(hex + i); - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it " - "again!\n"); - return -1; + if (c >= '0' && c <= '9') { + d[i] = c - '0'; + } else if (c >= 'A' && c <= 'F') { + d[i] = c - 'A' + 10; + } else if (c >= 'a' && c <= 'f') { + d[i] = c - 'a' + 10; + } else { + return (0); // error + } } - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; - } + return ((d[0] << 4) | (d[1])); +} - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F7: - ret = - stlink_write_option_control_register1_f7(sl, option_control_register1); - break; - default: - ELOG("Option control register 1 writing is currently not implemented for " - "connected chip\n"); - break; +static bool +stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg *the_arg) { + uint32_t addr = the_arg->addr; + uint8_t sum = 2 + 4 + (uint8_t)((addr & 0xFF000000) >> 24) + + (uint8_t)((addr & 0x00FF0000) >> 16); + + if (17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", + (addr & 0xFFFF0000) >> 16, (uint8_t)(0x100 - sum))) { + return (false); } - if (ret) - ELOG("Flash option write failed!\n"); - else - ILOG("Wrote option control register 1 %#010x!\n", option_control_register1); + the_arg->lba = (addr & 0xFFFF0000); + return (true); +} - lock_flash_option(sl); - lock_flash(sl); +static bool +stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg *the_arg) { + uint8_t count = the_arg->buf_pos; - return (ret); -} + if (count == 0) { + return (true); + } -/** - * Write the given binary file with option bytes - * @param sl - * @param path readable file path, should be binary image - * @param addr of the memory mapped option bytes - * @return 0 on success, -ve on failure. - */ -int stlink_fwrite_option_bytes(stlink_t *sl, const char *path, - stm32_addr_t addr) { - /* Write the file in flash at addr */ - int err; - mapped_file_t mf = MAPPED_FILE_INITIALIZER; + uint32_t addr = the_arg->addr; - if (map_file(&mf, path) == -1) { - ELOG("map_file() == -1\n"); - return (-1); + if (the_arg->lba != (addr & 0xFFFF0000)) { // segment changed + if (!stlink_fread_ihex_newsegment(the_arg)) { + return (false); + } } - printf("file %s ", path); - md5_calculate(&mf); - stlink_checksum(&mf); + uint8_t sum = count + (uint8_t)((addr & 0x0000FF00) >> 8) + + (uint8_t)(addr & 0x000000FF); - err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t)mf.len); - stlink_fwrite_finalize(sl, addr); - unmap_file(&mf); + if (9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) { + return (false); + } - return (err); -} + for (uint8_t i = 0; i < count; ++i) { + uint8_t b = the_arg->buf[i]; + sum += b; -int stlink_target_connect(stlink_t *sl, enum connect_type connect) { - if (connect == CONNECT_UNDER_RESET) { - stlink_enter_swd_mode(sl); + if (2 != fprintf(the_arg->file, "%02X", b)) { + return (false); + } + } - stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); + if (4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) { + return (false); + } - // try to halt the core before reset - // this is useful if the NRST pin is not connected - sl->backend->force_debug(sl); + the_arg->addr += count; + the_arg->buf_pos = 0; - // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) - usleep(20); + return (true); +} - stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH); +static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg *the_arg, + int fd, stm32_addr_t addr) { + the_arg->file = fdopen(fd, "w"); + the_arg->addr = addr; + the_arg->lba = 0; + the_arg->buf_pos = 0; - // try to halt the core after reset - unsigned timeout = time_ms() + 10; - while (time_ms() < timeout) { - sl->backend->force_debug(sl); - usleep(100); - } + return (the_arg->file != NULL); +} - // check NRST connection - uint32_t dhcsr = 0; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { - WLOG("NRST is not connected\n"); +static bool stlink_fread_ihex_worker(void *arg, uint8_t *block, ssize_t len) { + struct stlink_fread_ihex_worker_arg *the_arg = + (struct stlink_fread_ihex_worker_arg *)arg; + + for (ssize_t i = 0; i < len; ++i) { + if (the_arg->buf_pos == sizeof(the_arg->buf)) { // line is full + if (!stlink_fread_ihex_writeline(the_arg)) { + return (false); + } } - // addition soft reset for halt before the first instruction - stlink_soft_reset(sl, 1 /* halt on reset */); + the_arg->buf[the_arg->buf_pos++] = block[i]; } - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE && - stlink_enter_swd_mode(sl)) { - printf("Failed to enter SWD mode\n"); - return -1; + return (true); +} + +static bool +stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg *the_arg) { + if (!stlink_fread_ihex_writeline(the_arg)) { + return (false); } - if (connect == CONNECT_NORMAL) { - stlink_reset(sl, RESET_AUTO); + // FIXME: do we need the Start Linear Address? + + if (13 != fprintf(the_arg->file, ":00000001FF\r\n")) { // EoF + return (false); } - return stlink_load_device_params(sl); + return (0 == fclose(the_arg->file)); } diff --git a/src/common.h b/src/common.h new file mode 100644 index 000000000..6c22d58c0 --- /dev/null +++ b/src/common.h @@ -0,0 +1,15 @@ +/* + * File: common.h + * + * TODO: add a description + */ + +#ifndef COMMON_H +#define COMMON_H + +int check_file(stlink_t *, mapped_file_t *, stm32_addr_t); +void md5_calculate(mapped_file_t *); +void stlink_checksum(mapped_file_t *); +void stlink_fwrite_finalize(stlink_t *, stm32_addr_t); + +#endif // COMMON_H diff --git a/src/common_flash.c b/src/common_flash.c new file mode 100644 index 000000000..e2a9ebbc3 --- /dev/null +++ b/src/common_flash.c @@ -0,0 +1,1375 @@ +#include +#include +#include +#include +#include "calculate.h" +#include "common_flash.h" +#include "map_file.h" +#include "common.h" + +#define DEBUG_FLASH 0 + +uint32_t get_stm32l0_flash_base(stlink_t *sl) { + switch (sl->chip_id) { + case STM32_CHIPID_L0: + case STM32_CHIPID_L0_CAT5: + case STM32_CHIPID_L0_CAT2: + case STM32_CHIPID_L011: + return (STM32L0_FLASH_REGS_ADDR); + + case STM32_CHIPID_L1_CAT2: + case STM32_CHIPID_L1_MD: + case STM32_CHIPID_L1_MD_PLUS: + case STM32_CHIPID_L1_MD_PLUS_HD: + return (STM32L_FLASH_REGS_ADDR); + + default: + WLOG("Flash base use default L0 address\n"); + return (STM32L0_FLASH_REGS_ADDR); + } +} + +uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { + uint32_t reg, res; + + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + reg = FLASH_F4_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + reg = FLASH_F7_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + reg = STM32L4_FLASH_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + reg = STM32WB_FLASH_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + } else { + reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + } + + stlink_read_debug32(sl, reg, &res); + +#if DEBUG_FLASH + fprintf(stdout, "CR:0x%x\n", res); +#endif + return (res); +} + +void lock_flash(stlink_t *sl) { + uint32_t cr_lock_shift, cr_reg, n, cr2_reg = 0; + uint32_t cr_mask = 0xffffffffu; + + if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { + cr_reg = FLASH_CR; + cr2_reg = FLASH_CR2; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + cr_reg = FLASH_F4_CR; + cr_lock_shift = FLASH_F4_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_lock_shift = FLASH_F7_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + cr_lock_shift = STM32L0_FLASH_PELOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + cr_reg = STM32L4_FLASH_CR; + cr_lock_shift = STM32L4_FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + cr_reg = STM32WB_FLASH_CR; + cr_lock_shift = STM32WB_FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + cr2_reg = FLASH_H7_CR2; + } + cr_lock_shift = FLASH_H7_CR_LOCK; + cr_mask = ~(1u << FLASH_H7_CR_SER); + } else { + ELOG("unsupported flash method, abort\n"); + return; + } + + stlink_read_debug32(sl, cr_reg, &n); + n &= cr_mask; + n |= (1u << cr_lock_shift); + stlink_write_debug32(sl, cr_reg, n); + + if (cr2_reg) { + n = read_flash_cr(sl, BANK_2) | (1u << cr_lock_shift); + stlink_write_debug32(sl, cr2_reg, n); + } +} + +static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { + uint32_t sr_reg; + + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { + sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + sr_reg = FLASH_F4_SR; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + sr_reg = FLASH_F7_SR; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + sr_reg = STM32L4_FLASH_SR; + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + sr_reg = STM32Gx_FLASH_SR; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + sr_reg = STM32WB_FLASH_SR; + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; + } else { + ELOG("method 'write_flash_sr' is unsupported\n"); + return (-1); + } + + return stlink_write_debug32(sl, sr_reg, val); +} + +void clear_flash_error(stlink_t *sl) { + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F0_F1_F3: + write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); + break; + case STM32_FLASH_TYPE_F2_F4: + write_flash_sr(sl, BANK_1, FLASH_F4_SR_ERROR_MASK); + break; + case STM32_FLASH_TYPE_F7: + write_flash_sr(sl, BANK_1, FLASH_F7_SR_ERROR_MASK); + break; + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: + write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); + break; + case STM32_FLASH_TYPE_L0_L1: + write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); + break; + case STM32_FLASH_TYPE_L4_L4P: + write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); + break; + case STM32_FLASH_TYPE_H7: + write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_sr(sl, BANK_2, FLASH_H7_SR_ERROR_MASK); + } + break; + case STM32_FLASH_TYPE_WB_WL: + write_flash_sr(sl, BANK_1, STM32WB_FLASH_SR_ERROR_MASK); + break; + default: + break; + } +} + +uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { + uint32_t res, sr_reg; + + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { + sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + sr_reg = FLASH_F4_SR; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + sr_reg = FLASH_F7_SR; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + sr_reg = STM32L4_FLASH_SR; + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + sr_reg = STM32Gx_FLASH_SR; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + sr_reg = STM32WB_FLASH_SR; + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; + } else { + ELOG("method 'read_flash_sr' is unsupported\n"); + return (-1); + } + + stlink_read_debug32(sl, sr_reg, &res); + return (res); +} + +unsigned int is_flash_busy(stlink_t *sl) { + uint32_t sr_busy_shift; + unsigned int res; + + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || + (sl->flash_type == STM32_FLASH_TYPE_L0_L1)) { + sr_busy_shift = FLASH_SR_BSY; + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + sr_busy_shift = FLASH_F4_SR_BSY; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + sr_busy_shift = FLASH_F7_SR_BSY; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + sr_busy_shift = STM32L4_FLASH_SR_BSY; + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + sr_busy_shift = STM32Gx_FLASH_SR_BSY; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + sr_busy_shift = STM32WB_FLASH_SR_BSY; + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + sr_busy_shift = FLASH_H7_SR_QW; + } else { + ELOG("method 'is_flash_busy' is unsupported\n"); + return (-1); + } + + res = read_flash_sr(sl, BANK_1) & (1 << sr_busy_shift); + + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || + (sl->flash_type == STM32_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { + res |= read_flash_sr(sl, BANK_2) & (1 << sr_busy_shift); + } + + return (res); +} + +void wait_flash_busy(stlink_t *sl) { + // TODO: add some delays here + while (is_flash_busy(sl)) + ; +} + +int check_flash_error(stlink_t *sl) { + uint32_t res = 0; + uint32_t WRPERR, PROGERR, PGAERR; + + WRPERR = PROGERR = PGAERR = 0; + + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { + res |= read_flash_sr(sl, BANK_2) & FLASH_SR_ERROR_MASK; + } + WRPERR = (1 << FLASH_SR_WRPRT_ERR); + PROGERR = (1 << FLASH_SR_PG_ERR); + break; + case STM32_FLASH_TYPE_F2_F4: + res = read_flash_sr(sl, BANK_1) & FLASH_F4_SR_ERROR_MASK; + WRPERR = (1 << FLASH_F4_SR_WRPERR); + PGAERR = (1 << FLASH_F4_SR_PGAERR); + break; + case STM32_FLASH_TYPE_F7: + res = read_flash_sr(sl, BANK_1) & FLASH_F7_SR_ERROR_MASK; + WRPERR = (1 << FLASH_F7_SR_WRP_ERR); + PROGERR = (1 << FLASH_F7_SR_PGP_ERR); + break; + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: + res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32Gx_FLASH_SR_WRPERR); + PROGERR = (1 << STM32Gx_FLASH_SR_PROGERR); + PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); + break; + case STM32_FLASH_TYPE_L0_L1: + res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); + PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); + PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); + break; + case STM32_FLASH_TYPE_L4_L4P: + res = read_flash_sr(sl, BANK_1) & STM32L4_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32L4_FLASH_SR_WRPERR); + PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); + PGAERR = (1 << STM32L4_FLASH_SR_PGAERR); + break; + case STM32_FLASH_TYPE_H7: + res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; + } + WRPERR = (1 << FLASH_H7_SR_WRPERR); + break; + case STM32_FLASH_TYPE_WB_WL: + res = read_flash_sr(sl, BANK_1) & STM32WB_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32WB_FLASH_SR_WRPERR); + PROGERR = (1 << STM32WB_FLASH_SR_PROGERR); + PGAERR = (1 << STM32WB_FLASH_SR_PGAERR); + break; + default: + break; + } + + if (res) { + if (WRPERR && (WRPERR & res) == WRPERR) { + ELOG("Flash memory is write protected\n"); + res &= ~WRPERR; + } else if (PROGERR && (PROGERR & res) == PROGERR) { + ELOG("Flash memory contains a non-erased value\n"); + res &= ~PROGERR; + } else if (PGAERR && (PGAERR & res) == PGAERR) { + ELOG("Invalid flash address\n"); + res &= ~PGAERR; + } + + if (res) { + ELOG("Flash programming error: %#010x\n", res); + } + return (-1); + } + + return (0); +} + +static inline unsigned int is_flash_locked(stlink_t *sl) { + /* return non zero for true */ + uint32_t cr_lock_shift; + uint32_t cr_reg; + uint32_t n; + + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + cr_reg = FLASH_F4_CR; + cr_lock_shift = FLASH_F4_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_lock_shift = FLASH_F7_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + cr_lock_shift = STM32L0_FLASH_PELOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + cr_reg = STM32L4_FLASH_CR; + cr_lock_shift = STM32L4_FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + cr_reg = STM32WB_FLASH_CR; + cr_lock_shift = STM32WB_FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + cr_lock_shift = FLASH_H7_CR_LOCK; + } else { + ELOG("unsupported flash method, abort\n"); + return (-1); + } + + stlink_read_debug32(sl, cr_reg, &n); + return (n & (1u << cr_lock_shift)); +} + +static void unlock_flash(stlink_t *sl) { + uint32_t key_reg, key2_reg = 0; + uint32_t flash_key1 = FLASH_KEY1; + uint32_t flash_key2 = FLASH_KEY2; + /* The unlock sequence consists of 2 write cycles where 2 key values are + * written to the FLASH_KEYR register. An invalid sequence results in a + * definitive lock of the FPEC block until next reset. + */ + + if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { + key_reg = FLASH_KEYR; + } else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { + key_reg = FLASH_KEYR; + key2_reg = FLASH_KEYR2; + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + key_reg = FLASH_F4_KEYR; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + key_reg = FLASH_F7_KEYR; + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; + flash_key1 = FLASH_L0_PEKEY1; + flash_key2 = FLASH_L0_PEKEY2; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + key_reg = STM32L4_FLASH_KEYR; + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + key_reg = STM32Gx_FLASH_KEYR; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + key_reg = STM32WB_FLASH_KEYR; + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + key_reg = FLASH_H7_KEYR1; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + key2_reg = FLASH_H7_KEYR2; + } + } else { + ELOG("unsupported flash method, abort\n"); + return; + } + + stlink_write_debug32(sl, key_reg, flash_key1); + stlink_write_debug32(sl, key_reg, flash_key2); + + if (key2_reg) { + stlink_write_debug32(sl, key2_reg, flash_key1); + stlink_write_debug32(sl, key2_reg, flash_key2); + } +} + +/* unlock flash if already locked */ +int unlock_flash_if(stlink_t *sl) { + if (is_flash_locked(sl)) { + unlock_flash(sl); + + if (is_flash_locked(sl)) { + WLOG("Failed to unlock flash!\n"); + return (-1); + } + } + + DLOG("Successfully unlocked flash\n"); + return (0); +} + +int lock_flash_option(stlink_t *sl) { + uint32_t optlock_shift, optcr_reg, n, optcr2_reg = 0; + int active_bit_level = 1; + + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; + optlock_shift = FLASH_CR_OPTWRE; + active_bit_level = 0; + break; + case STM32_FLASH_TYPE_F2_F4: + optcr_reg = FLASH_F4_OPTCR; + optlock_shift = FLASH_F4_OPTCR_LOCK; + break; + case STM32_FLASH_TYPE_F7: + optcr_reg = FLASH_F7_OPTCR; + optlock_shift = FLASH_F7_OPTCR_LOCK; + break; + case STM32_FLASH_TYPE_L0_L1: + optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + optlock_shift = STM32L0_FLASH_OPTLOCK; + break; + case STM32_FLASH_TYPE_L4_L4P: + optcr_reg = STM32L4_FLASH_CR; + optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + break; + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STM32_FLASH_TYPE_WB_WL: + optcr_reg = STM32WB_FLASH_CR; + optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + break; + case STM32_FLASH_TYPE_H7: + optcr_reg = FLASH_H7_OPTCR; + optlock_shift = FLASH_H7_OPTCR_OPTLOCK; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) + optcr2_reg = FLASH_H7_OPTCR2; + break; + default: + ELOG("unsupported flash method, abort\n"); + return -1; + } + + stlink_read_debug32(sl, optcr_reg, &n); + + if (active_bit_level == 0) { + n &= ~(1u << optlock_shift); + } else { + n |= (1u << optlock_shift); + } + + stlink_write_debug32(sl, optcr_reg, n); + + if (optcr2_reg) { + stlink_read_debug32(sl, optcr2_reg, &n); + + if (active_bit_level == 0) { + n &= ~(1u << optlock_shift); + } else { + n |= (1u << optlock_shift); + } + + stlink_write_debug32(sl, optcr2_reg, n); + } + + return (0); +} + +static bool is_flash_option_locked(stlink_t *sl) { + uint32_t optlock_shift, optcr_reg; + int active_bit_level = 1; + uint32_t n; + + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; + optlock_shift = FLASH_CR_OPTWRE; + active_bit_level = 0; /* bit is "option write enable", not lock */ + break; + case STM32_FLASH_TYPE_F2_F4: + optcr_reg = FLASH_F4_OPTCR; + optlock_shift = FLASH_F4_OPTCR_LOCK; + break; + case STM32_FLASH_TYPE_F7: + optcr_reg = FLASH_F7_OPTCR; + optlock_shift = FLASH_F7_OPTCR_LOCK; + break; + case STM32_FLASH_TYPE_L0_L1: + optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + optlock_shift = STM32L0_FLASH_OPTLOCK; + break; + case STM32_FLASH_TYPE_L4_L4P: + optcr_reg = STM32L4_FLASH_CR; + optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + break; + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STM32_FLASH_TYPE_WB_WL: + optcr_reg = STM32WB_FLASH_CR; + optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + break; + case STM32_FLASH_TYPE_H7: + optcr_reg = FLASH_H7_OPTCR; + optlock_shift = FLASH_H7_OPTCR_OPTLOCK; + break; + default: + ELOG("unsupported flash method, abort\n"); + return -1; + } + + stlink_read_debug32(sl, optcr_reg, &n); + + if (active_bit_level == 0) { + return (!(n & (1u << optlock_shift))); + } + + return (n & (1u << optlock_shift)); +} + +static int unlock_flash_option(stlink_t *sl) { + uint32_t optkey_reg, optkey2_reg = 0; + uint32_t optkey1 = FLASH_OPTKEY1; + uint32_t optkey2 = FLASH_OPTKEY2; + + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + optkey_reg = FLASH_OPTKEYR; + optkey1 = FLASH_F0_OPTKEY1; + optkey2 = FLASH_F0_OPTKEY2; + break; + case STM32_FLASH_TYPE_F2_F4: + optkey_reg = FLASH_F4_OPT_KEYR; + break; + case STM32_FLASH_TYPE_F7: + optkey_reg = FLASH_F7_OPT_KEYR; + break; + case STM32_FLASH_TYPE_L0_L1: + optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; + optkey1 = FLASH_L0_OPTKEY1; + optkey2 = FLASH_L0_OPTKEY2; + break; + case STM32_FLASH_TYPE_L4_L4P: + optkey_reg = STM32L4_FLASH_OPTKEYR; + break; + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: + optkey_reg = STM32Gx_FLASH_OPTKEYR; + break; + case STM32_FLASH_TYPE_WB_WL: + optkey_reg = STM32WB_FLASH_OPT_KEYR; + break; + case STM32_FLASH_TYPE_H7: + optkey_reg = FLASH_H7_OPT_KEYR; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) + optkey2_reg = FLASH_H7_OPT_KEYR2; + break; + default: + ELOG("unsupported flash method, abort\n"); + return (-1); + } + + stlink_write_debug32(sl, optkey_reg, optkey1); + stlink_write_debug32(sl, optkey_reg, optkey2); + + if (optkey2_reg) { + stlink_write_debug32(sl, optkey2_reg, optkey1); + stlink_write_debug32(sl, optkey2_reg, optkey2); + } + + return (0); +} + +int unlock_flash_option_if(stlink_t *sl) { + if (is_flash_option_locked(sl)) { + if (unlock_flash_option(sl)) { + ELOG("Could not unlock flash option!\n"); + return (-1); + } + + if (is_flash_option_locked(sl)) { + ELOG("Failed to unlock flash option!\n"); + return (-1); + } + } + + DLOG("Successfully unlocked flash option\n"); + return (0); +} + +void write_flash_cr_psiz(stlink_t *sl, uint32_t n, + unsigned bank) { + uint32_t cr_reg, psize_shift; + uint32_t x = read_flash_cr(sl, bank); + + if (sl->flash_type == STM32_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + psize_shift = FLASH_H7_CR_PSIZE; + } else { + cr_reg = FLASH_F4_CR; + psize_shift = 8; + } + + x &= ~(0x03 << psize_shift); + x |= (n << psize_shift); +#if DEBUG_FLASH + fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n); +#endif + stlink_write_debug32(sl, cr_reg, x); +} + +void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { + uint32_t cr_reg, n; + uint32_t bit = FLASH_CR_PG; + + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + cr_reg = FLASH_F4_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + cr_reg = STM32L4_FLASH_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + cr_reg = STM32WB_FLASH_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + bit = FLASH_H7_CR_PG; + } else { + cr_reg = FLASH_CR; + } + + n = read_flash_cr(sl, bank) & ~(1 << bit); + stlink_write_debug32(sl, cr_reg, n); +} +/* ------------------------------------------------------------------------ */ + +static void wait_flash_busy_progress(stlink_t *sl) { + int i = 0; + fprintf(stdout, "Mass erasing"); + fflush(stdout); + + while (is_flash_busy(sl)) { + usleep(10000); + i++; + + if (i % 100 == 0) { + fprintf(stdout, "."); + fflush(stdout); + } + } + + fprintf(stdout, "\n"); +} + +static inline void write_flash_ar(stlink_t *sl, uint32_t n, unsigned bank) { + stlink_write_debug32(sl, (bank == BANK_1) ? FLASH_AR : FLASH_AR2, n); +} + +static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, unsigned bank) { + uint32_t cr_reg, snb_mask, snb_shift, ser_shift; + uint32_t x = read_flash_cr(sl, bank); + + if (sl->flash_type == STM32_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + snb_mask = FLASH_H7_CR_SNB_MASK; + snb_shift = FLASH_H7_CR_SNB; + ser_shift = FLASH_H7_CR_SER; + } else { + cr_reg = FLASH_F4_CR; + snb_mask = FLASH_F4_CR_SNB_MASK; + snb_shift = FLASH_F4_CR_SNB; + ser_shift = FLASH_F4_CR_SER; + } + + x &= ~snb_mask; + x |= (n << snb_shift); + x |= (1 << ser_shift); +#if DEBUG_FLASH + fprintf(stdout, "SNB:0x%x 0x%x\n", x, n); +#endif + stlink_write_debug32(sl, cr_reg, x); +} + +static void set_flash_cr_per(stlink_t *sl, unsigned bank) { + uint32_t cr_reg, val; + + if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + cr_reg = STM32WB_FLASH_CR; + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + } + + stlink_read_debug32(sl, cr_reg, &val); + val |= (1 << FLASH_CR_PER); + stlink_write_debug32(sl, cr_reg, val); +} + +static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { + uint32_t cr_reg; + + if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + cr_reg = STM32WB_FLASH_CR; + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + } + + const uint32_t n = read_flash_cr(sl, bank) & ~(1 << FLASH_CR_PER); + stlink_write_debug32(sl, cr_reg, n); +} + +static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { + stlink_write_debug32(sl, STM32L4_FLASH_SR, + 0xFFFFFFFF & ~(1 << STM32L4_FLASH_SR_BSY)); + uint32_t x = read_flash_cr(sl, BANK_1); + x &= ~STM32L4_FLASH_CR_OPBITS; + x &= ~STM32L4_FLASH_CR_PAGEMASK; + x &= ~(1 << STM32L4_FLASH_CR_MER1); + x &= ~(1 << STM32L4_FLASH_CR_MER2); + x |= (n << STM32L4_FLASH_CR_PNB); + x |= (uint32_t)(1lu << STM32L4_FLASH_CR_PER); +#if DEBUG_FLASH + fprintf(stdout, "BKER:PNB:0x%x 0x%x\n", x, n); +#endif + stlink_write_debug32(sl, STM32L4_FLASH_CR, x); +} + +static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { + uint32_t val, cr_reg, cr_strt; + + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + cr_reg = FLASH_F4_CR; + cr_strt = 1 << FLASH_F4_CR_STRT; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_strt = 1 << FLASH_F7_CR_STRT; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + cr_reg = STM32L4_FLASH_CR; + cr_strt = (1 << STM32L4_FLASH_CR_STRT); + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_strt = (1 << STM32Gx_FLASH_CR_STRT); + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + cr_reg = STM32WB_FLASH_CR; + cr_strt = (1 << STM32WB_FLASH_CR_STRT); + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + cr_strt = 1 << FLASH_H7_CR_START(sl->chip_id); + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + cr_strt = (1 << FLASH_CR_STRT); + } + + stlink_read_debug32(sl, cr_reg, &val); + val |= cr_strt; + stlink_write_debug32(sl, cr_reg, val); +} + +static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { + uint32_t val, cr_reg, cr_mer, cr_pg; + + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + cr_reg = FLASH_F4_CR; + cr_mer = 1 << FLASH_CR_MER; + cr_pg = 1 << FLASH_CR_PG; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_mer = 1 << FLASH_CR_MER; + cr_pg = 1 << FLASH_CR_PG; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + cr_reg = STM32L4_FLASH_CR; + cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); + cr_pg = (1 << STM32L4_FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_mer = (1 << STM32Gx_FLASH_CR_MER1); + + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); + } + + cr_pg = (1 << FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + cr_reg = STM32WB_FLASH_CR; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + cr_mer = (1 << FLASH_H7_CR_BER); + cr_pg = (1 << FLASH_H7_CR_PG); + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); + } + + stlink_read_debug32(sl, cr_reg, &val); + + if (val & cr_pg) { + // STM32F030 will drop MER bit if PG was set + val &= ~cr_pg; + stlink_write_debug32(sl, cr_reg, val); + } + + if (v) { + val |= cr_mer; + } else { + val &= ~cr_mer; + } + + stlink_write_debug32(sl, cr_reg, val); +} + +/** + * Erase a page of flash, assumes sl is fully populated with things like + * chip/core ids + * @param sl stlink context + * @param flashaddr an address in the flash page to erase + * @return 0 on success -ve on failure + */ +int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { + // wait for ongoing op to finish + wait_flash_busy(sl); + // clear flash IO errors + clear_flash_error(sl); + + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4 || + sl->flash_type == STM32_FLASH_TYPE_F7 || + sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + // unlock if locked + unlock_flash_if(sl); + + // select the page to erase + if ((sl->chip_id == STM32_CHIPID_L4) || + (sl->chip_id == STM32_CHIPID_L43x_L44x) || + (sl->chip_id == STM32_CHIPID_L45x_L46x) || + (sl->chip_id == STM32_CHIPID_L496x_L4A6x) || + (sl->chip_id == STM32_CHIPID_L4Rx)) { + // calculate the actual bank+page from the address + uint32_t page = calculate_L4_page(sl, flashaddr); + + fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", page, + stlink_calculate_pagesize(sl, flashaddr)); + + write_flash_cr_bker_pnb(sl, page); + } else if (sl->chip_id == STM32_CHIPID_F7 || + sl->chip_id == STM32_CHIPID_F76xxx) { + // calculate the actual page from the address + uint32_t sector = calculate_F7_sectornum(flashaddr); + + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, + stlink_calculate_pagesize(sl, flashaddr)); + write_flash_cr_snb(sl, sector, BANK_1); + } else { + // calculate the actual page from the address + uint32_t sector = calculate_F4_sectornum(flashaddr); + + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, + stlink_calculate_pagesize(sl, flashaddr)); + + // the SNB values for flash sectors in the second bank do not directly + // follow the values for the first bank on 2mb devices... + if (sector >= 12) { + sector += 4; + } + + write_flash_cr_snb(sl, sector, BANK_1); + } + + set_flash_cr_strt(sl, BANK_1); // start erase operation + wait_flash_busy(sl); // wait for completion + lock_flash(sl); // TODO: fails to program if this is in +#if DEBUG_FLASH + fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl, BANK_1)); +#endif + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + + // check if the locks are set + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + + if ((val & (1 << 0)) || (val & (1 << 1))) { + // disable pecr protection + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY2); + + // check pecr.pelock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + + if (val & (1 << 0)) { + WLOG("pecr.pelock not clear (%#x)\n", val); + return (-1); + } + + // unlock program memory + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY2); + + // check pecr.prglock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + + if (val & (1 << 1)) { + WLOG("pecr.prglock not clear (%#x)\n", val); + return (-1); + } + } + + // set pecr.{erase,prog} + val |= (1 << 9) | (1 << 3); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + + // write 0 to the first word of the page to be erased + stlink_write_debug32(sl, flashaddr, 0); + + /* MP: It is better to wait for clearing the busy bit after issuing page + * erase command, even though PM0062 recommends to wait before it. + * Test shows that a few iterations is performed in the following loop + * before busy bit is cleared. + */ + wait_flash_busy(sl); + + // reset lock bits + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || + sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + uint32_t val; + unlock_flash_if(sl); + set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit + + // set the page to erase + if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + uint32_t flash_page = + ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + + // sec 3.10.5 - PNB[7:0] is offset by 3. + val &= ~(0xFF << 3); // Clear previously set page number (if any) + val |= ((flash_page & 0xFF) << 3); + + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + } else if (sl->flash_type == STM32_FLASH_TYPE_G0) { + uint32_t flash_page = + ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. + val &= ~(0x3F << 3); + val |= ((flash_page & 0x3F) << 3) | (1 << FLASH_CR_PER); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + } else if (sl->flash_type == STM32_FLASH_TYPE_G4) { + uint32_t flash_page = + ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. + val &= ~(0x7F << 3); + val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + } + + set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit + wait_flash_busy(sl); // wait for the 'busy' bit to clear + clear_flash_cr_per(sl, BANK_1); // clear the 'enable page erase' bit + lock_flash(sl); + } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3 || + sl->flash_type == STM32_FLASH_TYPE_F1_XL) { + unsigned bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; + unlock_flash_if(sl); + clear_flash_cr_pg(sl, bank); // clear the pg bit + set_flash_cr_per(sl, bank); // set the page erase bit + write_flash_ar(sl, flashaddr, bank); // select the page to erase + set_flash_cr_strt(sl, + bank); // start erase operation, reset by hw with busy bit + wait_flash_busy(sl); + clear_flash_cr_per(sl, bank); // clear the page erase bit + lock_flash(sl); + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; + unlock_flash_if(sl); // unlock if locked + uint32_t sector = calculate_H7_sectornum( + sl, flashaddr, bank); // calculate the actual page from the address + write_flash_cr_snb(sl, sector, bank); // select the page to erase + set_flash_cr_strt(sl, bank); // start erase operation + wait_flash_busy(sl); // wait for completion + lock_flash(sl); + } else { + WLOG("unknown coreid %x, page erase failed\n", sl->core_id); + return (-1); + } + + return check_flash_error(sl); +} + +int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size) { + // Check the address and size validity + if (stlink_check_address_range_validity(sl, base_addr, size) < 0) { + return -1; + } + + // Make sure the requested address is aligned with the beginning of a page + if (stlink_check_address_alignment(sl, base_addr) < 0) { + ELOG("The address to erase is not aligned with the beginning of a page\n"); + return -1; + } + + stm32_addr_t addr = base_addr; + do { + long unsigned int page_size = stlink_calculate_pagesize(sl, addr); + + // Check if size is aligned with a page, unless we want to completely erase the last page + if ((addr + page_size) > (base_addr + size) && !align_size) { + ELOG("Invalid size (not aligned with a page). Page size at address %#x is %#lx\n", addr, page_size); + return -1; + } + + if (stlink_erase_flash_page(sl, addr)) { + WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); + return (-1); + } + + fprintf(stdout, "-> Flash page at %#x erased (size: %#lx)\n", addr, page_size); + fflush(stdout); + + // check the next page is within the range to erase + addr += page_size; + } while (addr < (base_addr + size)); + + fprintf(stdout, "\n"); + return 0; +} + +int stlink_erase_flash_mass(stlink_t *sl) { + int err = 0; + + // TODO: User MER bit to mass-erase WB series. + if (sl->flash_type == STM32_FLASH_TYPE_L0_L1 || + sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + + err = stlink_erase_flash_section(sl, sl->flash_base, sl->flash_size, false); + + } else { + wait_flash_busy(sl); + clear_flash_error(sl); + unlock_flash_if(sl); + + if (sl->flash_type == STM32_FLASH_TYPE_H7 && + sl->chip_id != STM32_CHIPID_H7Ax) { + // set parallelism + write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); + } + } + + set_flash_cr_mer(sl, 1, BANK_1); // set the mass erase bit + set_flash_cr_strt( + sl, BANK_1); // start erase operation, reset by hw with busy bit + + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || + (sl->flash_type == STM32_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { + set_flash_cr_mer(sl, 1, BANK_2); // set the mass erase bit in bank 2 + set_flash_cr_strt(sl, BANK_2); // start erase operation in bank 2 + } + + wait_flash_busy_progress(sl); + lock_flash(sl); + + // reset the mass erase bit + set_flash_cr_mer(sl, 0, BANK_1); + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || + (sl->flash_type == STM32_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { + set_flash_cr_mer(sl, 0, BANK_2); + } + + err = check_flash_error(sl); + } + + return (err); +} + +int stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, + stm32_addr_t addr) { + /* Write the block in flash at addr */ + int err; + unsigned int num_empty, idx; + uint8_t erased_pattern = stlink_get_erased_pattern(sl); + + /* + * This optimisation may cause unexpected garbage data remaining. + * Therfore it is turned off by default. + */ + if (sl->opt) { + idx = (unsigned int)length; + + for (num_empty = 0; num_empty != length; ++num_empty) + if (data[--idx] != erased_pattern) { + break; + } + + num_empty -= (num_empty & 3); // Round down to words + + if (num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, + erased_pattern); + } + } else { + num_empty = 0; + } + + /* + * TODO: investigate a kind of weird behaviour here: + * If the file is identified to be all-empty and four-bytes aligned, + * still flash the whole file even if ignoring message is printed. + */ + err = stlink_write_flash(sl, addr, data, + (num_empty == length) ? (uint32_t)length + : (uint32_t)length - num_empty, + num_empty == length); + stlink_fwrite_finalize(sl, addr); + return (err); +} + +/** + * Write the given binary file into flash at address "addr" + * @param sl + * @param path readable file path, should be binary image + * @param addr where to start writing + * @return 0 on success, -ve on failure. + */ +int stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { + /* Write the file in flash at addr */ + int err; + unsigned int num_empty, idx; + uint8_t erased_pattern = stlink_get_erased_pattern(sl); + mapped_file_t mf = MAPPED_FILE_INITIALIZER; + + if (map_file(&mf, path) == -1) { + ELOG("map_file() == -1\n"); + return (-1); + } + + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); + + if (sl->opt) { + idx = (unsigned int)mf.len; + + for (num_empty = 0; num_empty != mf.len; ++num_empty) { + if (mf.base[--idx] != erased_pattern) { + break; + } + } + + num_empty -= (num_empty & 3); // round down to words + + if (num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, + erased_pattern); + } + } else { + num_empty = 0; + } + + /* + * TODO: investigate a kind of weird behaviour here: + * If the file is identified to be all-empty and four-bytes aligned, + * still flash the whole file even if ignoring message is printed. + */ + err = stlink_write_flash(sl, addr, mf.base, + (num_empty == mf.len) ? (uint32_t)mf.len + : (uint32_t)mf.len - num_empty, + num_empty == mf.len); + stlink_fwrite_finalize(sl, addr); + unmap_file(&mf); + return (err); +} + + +int stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { + // check the contents of path are at addr + + int res; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; + + if (map_file(&mf, path) == -1) { + return (-1); + } + + res = check_file(sl, &mf, addr); + unmap_file(&mf); + return (res); +} + +/** + * Verify addr..addr+len is binary identical to base...base+len + * @param sl stlink context + * @param address stm device address + * @param data host side buffer to check against + * @param length how much + * @return 0 for success, -ve for failure + */ +int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, + unsigned length) { + size_t off; + size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; + ILOG("Starting verification of write complete\n"); + + for (off = 0; off < length; off += cmp_size) { + size_t aligned_size; + + // adjust last page size + if ((off + cmp_size) > length) { + cmp_size = length - off; + } + + aligned_size = cmp_size; + + if (aligned_size & (4 - 1)) { + aligned_size = (cmp_size + 4) & ~(4 - 1); + } + + stlink_read_mem32(sl, address + (uint32_t)off, (uint16_t)aligned_size); + + if (memcmp(sl->q_buf, data + off, cmp_size)) { + ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); + return (-1); + } + } + + ILOG("Flash written and verified! jolly good!\n"); + return (0); +} + +// Check if an address and size are within the flash +int stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size) { + long unsigned int logvar; + if (addr < sl->flash_base || addr >= (sl->flash_base + sl->flash_size)) { + logvar = sl->flash_base + sl->flash_size - 1; + ELOG("Invalid address, it should be within 0x%08x - 0x%08lx\n", sl->flash_base, logvar); + return (-1); + } + if ((addr + size) > (sl->flash_base + sl->flash_size)) { + logvar = sl->flash_base + sl->flash_size - addr; + ELOG("The size exceeds the size of the flash (0x%08lx bytes available)\n", logvar); + return (-1); + } + return 0; +} + +// Check if an address is aligned with the beginning of a page +int stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr) { + stm32_addr_t page = sl->flash_base; + + while (page < addr) { + page += stlink_calculate_pagesize(sl, page); + } + + if (page != addr) { + return -1; + } + + return 0; +} + +int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, + uint32_t len, uint8_t eraseonly) { + int ret; + flash_loader_t fl; + ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, + len, addr, addr); + // check addr range is inside the flash + stlink_calculate_pagesize(sl, addr); + + // Check the address and size validity + if (stlink_check_address_range_validity(sl, addr, len) < 0) { + return (-1); + } else if (len & 1) { + WLOG("unaligned len 0x%x -- padding with zero\n", len); + len += 1; + } else if (stlink_check_address_alignment(sl, addr) < 0) { + ELOG("addr not a multiple of current pagesize (%u bytes), not supported, " + "check page start address and compare with flash module organisation " + "in related ST reference manual of your device.\n", + (unsigned)(sl->flash_pgsz)); + return (-1); + } + + // make sure we've loaded the context with the chip details + stlink_core_id(sl); + + // Erase this section of the flash + if (stlink_erase_flash_section(sl, addr, len, true) < 0) { + ELOG("Failed to erase the flash prior to writing\n"); + return (-1); + } + + if (eraseonly) { + return (0); + } + + ret = stlink_flashloader_start(sl, &fl); + if (ret) + return ret; + ret = stlink_flashloader_write(sl, &fl, addr, base, len); + if (ret) + return ret; + ret = stlink_flashloader_stop(sl, &fl); + if (ret) + return ret; + + return (stlink_verify_write_flash(sl, addr, base, len)); +} diff --git a/src/common_flash.h b/src/common_flash.h new file mode 100644 index 000000000..70a6f0e04 --- /dev/null +++ b/src/common_flash.h @@ -0,0 +1,27 @@ +/* + * File: common_flash.h + * + * TODO: add a description + */ + +#ifndef COMMON_FLASH_H +#define COMMON_FLASH_H + +void lock_flash(stlink_t *); +void clear_flash_error(stlink_t *); +void wait_flash_busy(stlink_t *); +int check_flash_error(stlink_t *); +int unlock_flash_if(stlink_t *); +int lock_flash_option(stlink_t *); +int unlock_flash_option_if(stlink_t *); +void write_flash_cr_psiz(stlink_t *, uint32_t, unsigned); +void clear_flash_cr_pg(stlink_t *, unsigned); + +// TODO: move to private defines if possible + +#define BANK_1 0 +#define BANK_2 1 + +uint32_t read_flash_cr(stlink_t *, unsigned); +uint32_t get_stm32l0_flash_base(stlink_t *); +#endif // STLINK_H diff --git a/src/flashloader.c b/src/flashloader.c new file mode 100644 index 000000000..ce230d7ab --- /dev/null +++ b/src/flashloader.c @@ -0,0 +1,482 @@ +#include +#include +#include +#include "common_flash.h" + +#define L1_WRITE_BLOCK_SIZE 0x80 +#define L0_WRITE_BLOCK_SIZE 0x40 + +int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, + uint32_t len, uint32_t pagesize) { + unsigned int count, off; + unsigned int num_half_pages = len / pagesize; + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + flash_loader_t fl; + bool use_loader = true; + int ret = 0; + + // enable half page write + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << FLASH_L1_FPRG); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + val |= (1 << FLASH_L1_PROG); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + + wait_flash_busy(sl); + + for (count = 0; count < num_half_pages; count++) { + if (use_loader) { + ret = stlink_flash_loader_run(sl, &fl, addr + count * pagesize, + base + count * pagesize, pagesize); + if (ret && count == 0) { + /* It seems that stm32lx devices have a problem when it is blank */ + WLOG("Failed to use flash loader, fallback to soft write\n"); + use_loader = false; + } + } + if (!use_loader) { + ret = 0; + for (off = 0; off < pagesize && !ret; off += 64) { + size_t chunk = (pagesize - off > 64) ? 64 : pagesize - off; + memcpy(sl->q_buf, base + count * pagesize + off, chunk); + ret = stlink_write_mem32(sl, addr + count * pagesize + off, (uint16_t)chunk); + } + } + + if (ret) { + WLOG("l1_stlink_flash_loader_run(%#x) failed! == -1\n", + addr + count * pagesize); + break; + } + + if (sl->verbose >= 1) { + // show progress; writing procedure is slow and previous errors are + // misleading + fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); + fflush(stdout); + } + + // wait for sr.busy to be cleared + wait_flash_busy(sl); + } + + // disable half page write + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + return (ret); +} + +static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { + uint32_t cr_reg, x; + + x = read_flash_cr(sl, bank); + + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + cr_reg = FLASH_F4_CR; + x |= 1 << FLASH_CR_PG; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + x |= 1 << FLASH_CR_PG; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + cr_reg = STM32L4_FLASH_CR; + x &= ~STM32L4_FLASH_CR_OPBITS; + x |= (1 << STM32L4_FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + cr_reg = STM32WB_FLASH_CR; + x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + x |= (1 << FLASH_H7_CR_PG); + } else { + cr_reg = FLASH_CR; + x = (1 << FLASH_CR_PG); + } + + stlink_write_debug32(sl, cr_reg, x); +} + +static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { + uint32_t rcc, rcc_dma_mask, value; + + rcc = rcc_dma_mask = value = 0; + + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + rcc = STM32F1_RCC_AHBENR; + rcc_dma_mask = STM32F1_RCC_DMAEN; + break; + case STM32_FLASH_TYPE_F2_F4: + case STM32_FLASH_TYPE_F7: + rcc = STM32F4_RCC_AHB1ENR; + rcc_dma_mask = STM32F4_RCC_DMAEN; + break; + case STM32_FLASH_TYPE_G0: + rcc = STM32G0_RCC_AHBENR; + rcc_dma_mask = STM32G0_RCC_DMAEN; + break; + case STM32_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_L4_L4P: + rcc = STM32G4_RCC_AHB1ENR; + rcc_dma_mask = STM32G4_RCC_DMAEN; + break; + case STM32_FLASH_TYPE_L0_L1: + rcc = STM32L0_RCC_AHBENR; + rcc_dma_mask = STM32L0_RCC_DMAEN; + break; + case STM32_FLASH_TYPE_H7: + rcc = STM32H7_RCC_AHB1ENR; + rcc_dma_mask = STM32H7_RCC_DMAEN; + break; + case STM32_FLASH_TYPE_WB_WL: + rcc = STM32WB_RCC_AHB1ENR; + rcc_dma_mask = STM32WB_RCC_DMAEN; + break; + default: + return; + } + + if (!stlink_read_debug32(sl, rcc, &value)) { + if (bckpRstr) { + value = (value & (~rcc_dma_mask)) | fl->rcc_dma_bkp; + } else { + fl->rcc_dma_bkp = value & rcc_dma_mask; + value &= ~rcc_dma_mask; + } + stlink_write_debug32(sl, rcc, value); + } +} + +int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { + // disable DMA + set_dma_state(sl, fl, 0); + + // wait for ongoing op to finish + wait_flash_busy(sl); + // Clear errors + clear_flash_error(sl); + + if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || + (sl->flash_type == STM32_FLASH_TYPE_F7) || + (sl->flash_type == STM32_FLASH_TYPE_L4_L4P)) { + ILOG("Starting Flash write for F2/F4/F7/L4\n"); + + // Flash loader initialisation + if (stlink_flash_loader_init(sl, fl) == -1) { + ELOG("stlink_flash_loader_init() == -1\n"); + return (-1); + } + + unlock_flash_if(sl); // first unlock the cr + + int voltage; + if (sl->version.stlink_v == 1) { + WLOG("STLINK V1 cannot read voltage, use default voltage 3.2V\n"); + voltage = 3200; + } else { + voltage = stlink_target_voltage(sl); + } + + if (voltage == -1) { + ELOG("Failed to read Target voltage\n"); + return (-1); + } + + if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + // L4 does not have a byte-write mode + if (voltage < 1710) { + ELOG("Target voltage (%d mV) too low for flash writes!\n", voltage); + return (-1); + } + } else { + if (voltage > 2700) { + ILOG("enabling 32-bit flash writes\n"); + write_flash_cr_psiz(sl, 2, BANK_1); + } else { + ILOG("Target voltage (%d mV) too low for 32-bit flash, " + "using 8-bit flash writes\n", + voltage); + write_flash_cr_psiz(sl, 0, BANK_1); + } + } + + // set programming mode + set_flash_cr_pg(sl, BANK_1); + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || + sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + ILOG("Starting Flash write for WB/G0/G4\n"); + + unlock_flash_if(sl); // unlock flash if necessary + set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + ILOG("Starting Flash write for L0\n"); + + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + + // disable pecr protection + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY2); + + // check pecr.pelock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 0)) { + ELOG("pecr.pelock not clear\n"); + return (-1); + } + + // unlock program memory + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY2); + + // check pecr.prglock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 1)) { + ELOG("pecr.prglock not clear\n"); + return (-1); + } + + /* Flash loader initialisation */ + if (stlink_flash_loader_init(sl, fl) == -1) { + // L0/L1 have fallback to soft write + WLOG("stlink_flash_loader_init() == -1\n"); + } + } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { + ILOG("Starting Flash write for VL/F0/F3/F1_XL\n"); + + // flash loader initialisation + if (stlink_flash_loader_init(sl, fl) == -1) { + ELOG("stlink_flash_loader_init() == -1\n"); + return (-1); + } + + // unlock flash + unlock_flash_if(sl); + + // set programming mode + set_flash_cr_pg(sl, BANK_1); + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { + set_flash_cr_pg(sl, BANK_2); + } + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + ILOG("Starting Flash write for H7\n"); + + unlock_flash_if(sl); // unlock the cr + set_flash_cr_pg(sl, BANK_1); // set programming mode + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + set_flash_cr_pg(sl, BANK_2); + } + if (sl->chip_id != STM32_CHIPID_H7Ax) { + // set parallelism + write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); + } + } + } else { + ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); + return (-1); + } + + return (0); +} + +int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, + stm32_addr_t addr, uint8_t *base, uint32_t len) { + size_t off; + if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || + (sl->flash_type == STM32_FLASH_TYPE_F7) || + (sl->flash_type == STM32_FLASH_TYPE_L4_L4P)) { + size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; + for (off = 0; off < len;) { + size_t size = len - off > buf_size ? buf_size : len - off; + if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, + size) == -1) { + ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", + (unsigned)(addr + off)); + check_flash_error(sl); + return (-1); + } + + off += size; + } + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || + sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); + for (off = 0; off < len; off += sizeof(uint32_t)) { + uint32_t data; + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { + fprintf(stdout, "\r%3u/%3u pages written", + (unsigned int)(off / sl->flash_pgsz), + (unsigned int)(len / sl->flash_pgsz)); + fflush(stdout); + } + + write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); + stlink_write_debug32(sl, addr + (uint32_t)off, data); + wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear + } + fprintf(stdout, "\n"); + + // flash writes happen as 2 words at a time + if ((off / sizeof(uint32_t)) % 2 != 0) { + stlink_write_debug32(sl, addr + (uint32_t)off, + 0); // write a single word of zeros + wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear + } + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + uint32_t pagesize = (flash_regs_base==STM32L0_FLASH_REGS_ADDR)? + L0_WRITE_BLOCK_SIZE:L1_WRITE_BLOCK_SIZE; + + DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); + + off = 0; + + if (len > pagesize) { + if (stm32l1_write_half_pages(sl, addr, base, len, pagesize)) { + return (-1); + } else { + off = (size_t)(len / pagesize) * pagesize; + } + } + + // write remaining word in program memory + for (; off < len; off += sizeof(uint32_t)) { + uint32_t data; + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { + fprintf(stdout, "\r%3u/%3u pages written", + (unsigned int)(off / sl->flash_pgsz), + (unsigned int)(len / sl->flash_pgsz)); + fflush(stdout); + } + + write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); + stlink_write_debug32(sl, addr + (uint32_t)off, data); + + // wait for sr.busy to be cleared + do { + stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); + } while ((val & (1 << 0)) != 0); + + // TODO: check redo write operation + } + fprintf(stdout, "\n"); + } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { + int write_block_count = 0; + for (off = 0; off < len; off += sl->flash_pgsz) { + // adjust last write size + size_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; + + // unlock and set programming mode + unlock_flash_if(sl); + + DLOG("Finished unlocking flash, running loader!\n"); + + if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, + size) == -1) { + ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", + (unsigned)(addr + off)); + check_flash_error(sl); + return (-1); + } + + lock_flash(sl); + + if (sl->verbose >= 1) { + // show progress; writing procedure is slow and previous errors are + // misleading + fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, + (unsigned int)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); + fflush(stdout); + } + } + if (sl->verbose >= 1) { + fprintf(stdout, "\n"); + } + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + for (off = 0; off < len;) { + // Program STM32H7x with 64-byte Flash words + size_t chunk = (len - off > 64) ? 64 : len - off; + memcpy(sl->q_buf, base + off, chunk); + stlink_write_mem32(sl, addr + (uint32_t)off, 64); + wait_flash_busy(sl); + + off += chunk; + + if (sl->verbose >= 1) { + // show progress + fprintf(stdout, "\r%u/%u bytes written", (unsigned int)off, + (unsigned int)len); + fflush(stdout); + } + } + if (sl->verbose >= 1) { + fprintf(stdout, "\n"); + } + } else { + return (-1); + } + + return check_flash_error(sl); +} + +int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { + uint32_t dhcsr; + + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || + (sl->flash_type == STM32_FLASH_TYPE_F2_F4) || + (sl->flash_type == STM32_FLASH_TYPE_F7) || + (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) || + (sl->flash_type == STM32_FLASH_TYPE_WB_WL) || + (sl->flash_type == STM32_FLASH_TYPE_G0) || + (sl->flash_type == STM32_FLASH_TYPE_G4) || + (sl->flash_type == STM32_FLASH_TYPE_H7)) { + + clear_flash_cr_pg(sl, BANK_1); + if ((sl->flash_type == STM32_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK) || + sl->flash_type == STM32_FLASH_TYPE_F1_XL) { + clear_flash_cr_pg(sl, BANK_2); + } + lock_flash(sl); + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + + // reset lock bits + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + } + + // enable interrupt + if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) { + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + (dhcsr & (~STLINK_REG_DHCSR_C_MASKINTS))); + } + + // restore DMA state + set_dma_state(sl, fl, 1); + + return (0); +} diff --git a/src/map_file.c b/src/map_file.c new file mode 100644 index 000000000..17697c1da --- /dev/null +++ b/src/map_file.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include + +#include "map_file.h" + +#ifndef MAX_FILE_SIZE +#define MAX_FILE_SIZE (1<<20) // 1 GB max file size +#endif + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +int map_file(mapped_file_t *mf, const char *path) { + int error = -1; + struct stat st; + + const int fd = open(path, O_RDONLY | O_BINARY); + + if (fd == -1) { + fprintf(stderr, "open(%s) == -1\n", path); + return (-1); + } + + if (fstat(fd, &st) == -1) { + fprintf(stderr, "fstat(%s) == -1\n", path); + goto on_error; + } + + if (sizeof(st.st_size) != sizeof(size_t)) { + // on 32 bit systems, check if there is an overflow + if (st.st_size > (off_t)MAX_FILE_SIZE /*1 GB*/ ) { + // limit file size to 1 GB + fprintf(stderr, "mmap() size_t overflow for file %s\n", path); + goto on_error; + } + } + + mf->base = + (uint8_t *)mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); + + if (mf->base == MAP_FAILED) { + fprintf(stderr, "mmap() == MAP_FAILED for file %s\n", path); + goto on_error; + } + + mf->len = (size_t)st.st_size; + error = 0; // success + +on_error: + close(fd); + return (error); +} + +void unmap_file(mapped_file_t *mf) { + munmap((void *)mf->base, mf->len); + mf->base = (unsigned char *)MAP_FAILED; + mf->len = 0; +} diff --git a/src/map_file.h b/src/map_file.h new file mode 100644 index 000000000..9cdd745e6 --- /dev/null +++ b/src/map_file.h @@ -0,0 +1,32 @@ +/* + * File: map_file.h + * + * TODO: add a description + */ + +#ifndef MAP_FILE_H +#define MAP_FILE_H + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#ifdef STLINK_HAVE_SYS_MMAN_H +#include +#else +#include +#endif + +/* Memory mapped file */ +typedef struct mapped_file { + uint8_t *base; + size_t len; +} mapped_file_t; + +#define MAPPED_FILE_INITIALIZER \ + { NULL, 0 } + +int map_file(mapped_file_t *, const char *); +void unmap_file(mapped_file_t *); + +#endif // MAP_FILE_H diff --git a/src/option.c b/src/option.c new file mode 100644 index 000000000..bd792b4a9 --- /dev/null +++ b/src/option.c @@ -0,0 +1,1027 @@ +#include +#include +#include +#include "common_flash.h" +#include "map_file.h" +#include "common.h" + +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_Gx(stlink_t *sl, + uint32_t *option_byte) { + return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_Gx(sl, option_byte); +} + +/** + * Read first option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte) { + DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); + return stlink_read_debug32(sl, sl->option_base, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f2(stlink_t *sl, + uint32_t *option_byte) { + return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_f2(sl, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f4(stlink_t *sl, + uint32_t *option_byte) { + return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_f4(sl, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + * + * Since multiple bytes can be read, we read and print all but one here + * and then return the last one just like other devices + */ +int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t *option_byte) { + int err = -1; + for (uint32_t counter = 0; counter < (sl->option_size / 4 - 1); counter++) { + err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), + option_byte); + if (err == -1) { + return err; + } else { + printf("%08x\n", *option_byte); + } + } + + return stlink_read_debug32( + sl, + sl->option_base + (uint32_t)(sl->option_size / 4 - 1) * sizeof(uint32_t), + option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return (-1); + } + + switch (sl->chip_id) { + case STM32_CHIPID_F2: + return stlink_read_option_bytes_f2(sl, option_byte); + case STM32_CHIPID_F4: + case STM32_CHIPID_F446: + return stlink_read_option_bytes_f4(sl, option_byte); + case STM32_CHIPID_F76xxx: + return stlink_read_option_bytes_f7(sl, option_byte); + case STM32_CHIPID_G0_CAT1: + case STM32_CHIPID_G0_CAT2: + case STM32_CHIPID_G4_CAT2: + case STM32_CHIPID_G4_CAT3: + return stlink_read_option_bytes_Gx(sl, option_byte); + default: + return stlink_read_option_bytes_generic(sl, option_byte); + } +} + + +/** + * Write option bytes + * @param sl + * @param base option bytes to write + * @param addr of the memory mapped option bytes + * @param len of options bytes to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_f0( + stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { + int ret = 0; + + if (len < 12 || addr != STM32_F0_OPTION_BYTES_BASE) { + WLOG("Only full write of option bytes area is supported\n"); + return -1; + } + + clear_flash_error(sl); + + WLOG("Erasing option bytes\n"); + + /* erase option bytes */ + stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTER) | (1 << FLASH_CR_OPTWRE)); + ret = stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTER) | (1 << FLASH_CR_STRT) | (1 << FLASH_CR_OPTWRE)); + if (ret) { + return ret; + } + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (ret) { + return ret; + } + + WLOG("Writing option bytes to %#10x\n", addr); + + /* Set the Option PG bit to enable programming */ + stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OPTPG) | (1 << FLASH_CR_OPTWRE)); + + /* Use flash loader for write OP + * because flash memory writable by half word */ + flash_loader_t fl; + ret = stlink_flash_loader_init(sl, &fl); + if (ret) { + return ret; + } + ret = stlink_flash_loader_run(sl, &fl, addr, base, len); + if (ret) { + return ret; + } + + /* Reload option bytes */ + stlink_write_debug32(sl, FLASH_CR, (1 << FLASH_CR_OBL_LAUNCH)); + + return check_flash_error(sl); +} + +/** + * Write option bytes + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + /* Write options bytes */ + uint32_t val; + int ret = 0; + (void)len; + uint32_t data; + + clear_flash_error(sl); + + write_uint32((unsigned char *)&data, *(uint32_t *)(base)); + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); + + // Set Options Start bit + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + + // Reload options + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + + return (ret); +} + +/** + * Write option bytes + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t flash_base = get_stm32l0_flash_base(sl); + uint32_t val; + uint32_t data; + int ret = 0; + + // Clear errors + clear_flash_error(sl); + + while (len != 0) { + write_uint32((unsigned char *)&data, + *(uint32_t *)(base)); // write options bytes + + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + stlink_write_debug32(sl, addr, data); + wait_flash_busy(sl); + + if ((ret = check_flash_error(sl))) { + break; + } + + len -= 4; + addr += 4; + base += 4; + } + + // Reload options + stlink_read_debug32(sl, flash_base + FLASH_PECR_OFF, &val); + val |= (1 << STM32L0_FLASH_OBL_LAUNCH); + stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); + + return (ret); +} + +/** + * Write option bytes + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_l4(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + + uint32_t val; + int ret = 0; + (void)addr; + (void)len; + + // Clear errors + clear_flash_error(sl); + + // write options bytes + uint32_t data; + write_uint32((unsigned char *)&data, *(uint32_t *)(base)); + WLOG("Writing option bytes 0x%04x\n", data); + stlink_write_debug32(sl, STM32L4_FLASH_OPTR, data); + + // set options start bit + stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); + val |= (1 << STM32L4_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + + wait_flash_busy(sl); + ret = check_flash_error(sl); + + // apply options bytes immediate + stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); + val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); + stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + + return (ret); +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t option_byte; + int ret = 0; + (void)addr; + (void)len; + + // Clear errors + clear_flash_error(sl); + + write_uint32((unsigned char *)&option_byte, *(uint32_t *)(base)); + + // write option byte, ensuring we dont lock opt, and set strt bit + stlink_write_debug32(sl, FLASH_F4_OPTCR, + (option_byte & ~(1 << FLASH_F4_OPTCR_LOCK)) | + (1 << FLASH_F4_OPTCR_START)); + + wait_flash_busy(sl); + ret = check_flash_error(sl); + + // option bytes are reloaded at reset only, no obl. */ + return (ret); +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t option_byte; + int ret = 0; + + // Clear errors + clear_flash_error(sl); + + ILOG("Asked to write option byte %#10x to %#010x.\n", *(uint32_t *)(base), + addr); + write_uint32((unsigned char *)&option_byte, *(uint32_t *)(base)); + ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); + + if (addr == 0) { + addr = FLASH_F7_OPTCR; + ILOG("No address provided, using %#10x\n", addr); + } + + if (addr == FLASH_F7_OPTCR) { + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F7_OPTCR, + (option_byte & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); + } else if (addr == FLASH_F7_OPTCR1) { + // Read FLASH_F7_OPTCR + uint32_t oldvalue; + stlink_read_debug32(sl, FLASH_F7_OPTCR, &oldvalue); + /* write option byte */ + stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_byte); + // Write FLASH_F7_OPTCR lock and start address + stlink_write_debug32(sl, FLASH_F7_OPTCR, + (oldvalue & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); + } else { + WLOG("WIP: write %#010x to address %#010x\n", option_byte, addr); + stlink_write_debug32(sl, addr, option_byte); + } + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t *)base, + addr); + + /* option bytes are reloaded at reset only, no obl. */ + + return ret; +} + +/** + * Write STM32H7xx option bytes + * @param sl + * @param base option bytes to write + * @param addr of the memory mapped option bytes + * @param len number of bytes to write (must be multiple of 4) + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_h7(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t val; + uint32_t data; + + // Wait until previous flash option has completed + wait_flash_busy(sl); + + // Clear previous error + stlink_write_debug32(sl, FLASH_H7_OPTCCR, + 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); + + while (len != 0) { + switch (addr) { + case FLASH_H7_REGS_ADDR + 0x20: // FLASH_OPTSR_PRG + case FLASH_H7_REGS_ADDR + 0x2c: // FLASH_PRAR_PRG1 + case FLASH_H7_REGS_ADDR + 0x34: // FLASH_SCAR_PRG1 + case FLASH_H7_REGS_ADDR + 0x3c: // FLASH_WPSN_PRG1 + case FLASH_H7_REGS_ADDR + 0x44: // FLASH_BOOT_PRG + /* Write to FLASH_xxx_PRG registers */ + write_uint32((unsigned char *)&data, + *(uint32_t *)(base)); // write options bytes + + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + + /* Skip if the value in the CUR register is identical */ + stlink_read_debug32(sl, addr - 4, &val); + if (val == data) { + break; + } + + /* Write new option byte values and start modification */ + stlink_write_debug32(sl, addr, data); + stlink_read_debug32(sl, FLASH_H7_OPTCR, &val); + val |= (1 << FLASH_H7_OPTCR_OPTSTART); + stlink_write_debug32(sl, FLASH_H7_OPTCR, val); + + /* Wait for the option bytes modification to complete */ + do { + stlink_read_debug32(sl, FLASH_H7_OPTSR_CUR, &val); + } while ((val & (1 << FLASH_H7_OPTSR_OPT_BUSY)) != 0); + + /* Check for errors */ + if ((val & (1 << FLASH_H7_OPTSR_OPTCHANGEERR)) != 0) { + stlink_write_debug32(sl, FLASH_H7_OPTCCR, + 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); + return -1; + } + break; + + default: + /* Skip non-programmable registers */ + break; + } + + len -= 4; + addr += 4; + base += 4; + } + + return 0; +} + +/** + * Write option bytes + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, + uint32_t len) { + int ret = -1; + + if (sl->option_base == 0) { + ELOG( + "Option bytes writing is currently not supported for connected chip\n"); + return (-1); + } + + if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { + ELOG("Option bytes start address out of Option bytes range\n"); + return (-1); + } + + if (addr + len > sl->option_base + sl->option_size) { + ELOG("Option bytes data too long\n"); + return (-1); + } + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return (-1); + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return (-1); + } + + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + ret = stlink_write_option_bytes_f0(sl, base, addr, len); + break; + case STM32_FLASH_TYPE_F2_F4: + ret = stlink_write_option_bytes_f4(sl, base, addr, len); + break; + case STM32_FLASH_TYPE_F7: + ret = stlink_write_option_bytes_f7(sl, base, addr, len); + break; + case STM32_FLASH_TYPE_L0_L1: + ret = stlink_write_option_bytes_l0(sl, base, addr, len); + break; + case STM32_FLASH_TYPE_L4_L4P: + ret = stlink_write_option_bytes_l4(sl, base, addr, len); + break; + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: + ret = stlink_write_option_bytes_gx(sl, base, addr, len); + break; + case STM32_FLASH_TYPE_H7: + ret = stlink_write_option_bytes_h7(sl, base, addr, len); + break; + default: + ELOG("Option bytes writing is currently not implemented for connected " + "chip\n"); + break; + } + + if (ret) { + ELOG("Flash option write failed!\n"); + } else { + ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + } + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; +} + + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int +stlink_write_option_control_register_f0(stlink_t *sl, + uint32_t option_control_register) { + int ret = 0; + uint16_t opt_val[8]; + unsigned protection, optiondata; + uint16_t user_options, user_data, rdp; + unsigned option_offset, user_data_offset; + + ILOG("Asked to write option control register %#10x to %#010x.\n", + option_control_register, FLASH_OBR); + + /* Clear errors */ + clear_flash_error(sl); + + /* Retrieve current values */ + ret = stlink_read_debug32(sl, FLASH_OBR, &optiondata); + if (ret) { + return ret; + } + ret = stlink_read_debug32(sl, FLASH_WRPR, &protection); + if (ret) { + return ret; + } + + /* Translate OBR value to flash store structure + * F0: RM0091, Option byte description, pp. 75-78 + * F1: PM0075, Option byte description, pp. 19-22 + * F3: RM0316, Option byte description, pp. 85-87 */ + switch(sl->chip_id) + { + case 0x422: /* STM32F30x */ + case 0x432: /* STM32F37x */ + case 0x438: /* STM32F303x6/8 and STM32F328 */ + case 0x446: /* STM32F303xD/E and STM32F398xE */ + case 0x439: /* STM32F302x6/8 */ + case 0x440: /* STM32F05x */ + case 0x444: /* STM32F03x */ + case 0x445: /* STM32F04x */ + case 0x448: /* STM32F07x */ + case 0x442: /* STM32F09x */ + option_offset = 6; + user_data_offset = 16; + rdp = 0x55AA; + break; + default: + option_offset = 0; + user_data_offset = 10; + rdp = 0x5AA5; + break; + } + + user_options = (option_control_register >> option_offset >> 2) & 0xFFFF; + user_data = (option_control_register >> user_data_offset) & 0xFFFF; + +#define VAL_WITH_COMPLEMENT(v) (uint16_t)(((v)&0xFF) | (((~(v))<<8)&0xFF00)) + + opt_val[0] = (option_control_register & (1 << 1/*OPT_READOUT*/)) ? 0xFFFF : rdp; + opt_val[1] = VAL_WITH_COMPLEMENT(user_options); + opt_val[2] = VAL_WITH_COMPLEMENT(user_data); + opt_val[3] = VAL_WITH_COMPLEMENT(user_data >> 8); + opt_val[4] = VAL_WITH_COMPLEMENT(protection); + opt_val[5] = VAL_WITH_COMPLEMENT(protection >> 8); + opt_val[6] = VAL_WITH_COMPLEMENT(protection >> 16); + opt_val[7] = VAL_WITH_COMPLEMENT(protection >> 24); + +#undef VAL_WITH_COMPLEMENT + + /* Write bytes and check errors */ + ret = stlink_write_option_bytes_f0(sl, (uint8_t*)opt_val, STM32_F0_OPTION_BYTES_BASE, sizeof(opt_val)); + if (ret) + return ret; + + ret = check_flash_error(sl); + if (!ret) { + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, + FLASH_OBR); + } + + return ret; +} + + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int +stlink_write_option_control_register1_f7(stlink_t *sl, + uint32_t option_control_register1) { + int ret = 0; + + // Clear errors + clear_flash_error(sl); + + ILOG("Asked to write option control register 1 %#010x to %#010x.\n", + option_control_register1, FLASH_F7_OPTCR1); + + /* write option byte, ensuring we dont lock opt, and set strt bit */ + uint32_t current_control_register_value; + stlink_read_debug32(sl, FLASH_F7_OPTCR, ¤t_control_register_value); + + /* write option byte */ + stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_control_register1); + stlink_write_debug32( + sl, FLASH_F7_OPTCR, + (current_control_register_value & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register1, + FLASH_F7_OPTCR1); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int +stlink_write_option_control_register_f7(stlink_t *sl, + uint32_t option_control_register) { + int ret = 0; + + // Clear errors + clear_flash_error(sl); + + ILOG("Asked to write option control register 1 %#10x to %#010x.\n", + option_control_register, FLASH_F7_OPTCR); + + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F7_OPTCR, + (option_control_register & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, + FLASH_F7_OPTCR); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option bytes boot address to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_control_register32(stlink_t *sl, + uint32_t option_control_register) { + int ret = -1; + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return -1; + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } + + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + ret = stlink_write_option_control_register_f0(sl, option_control_register); + break; + case STM32_FLASH_TYPE_F7: + ret = stlink_write_option_control_register_f7(sl, option_control_register); + break; + default: + ELOG("Option control register writing is currently not implemented for " + "connected chip\n"); + break; + } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option control register %#010x!\n", option_control_register); + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option bytes boot address to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_control_register1_32( + stlink_t *sl, uint32_t option_control_register1) { + int ret = -1; + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return -1; + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } + + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F7: + ret = + stlink_write_option_control_register1_f7(sl, option_control_register1); + break; + default: + ELOG("Option control register 1 writing is currently not implemented for " + "connected chip\n"); + break; + } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option control register 1 %#010x!\n", option_control_register1); + + lock_flash_option(sl); + lock_flash(sl); + + return (ret); +} + + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int +stlink_write_option_bytes_boot_add_f7(stlink_t *sl, + uint32_t option_byte_boot_add) { + ILOG("Asked to write option byte boot add %#010x.\n", option_byte_boot_add); + return stlink_write_option_control_register1_f7(sl, option_byte_boot_add); +} + +/** + * Write option bytes + * @param sl + * @param option bytes boot address to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_bytes_boot_add32(stlink_t *sl, + uint32_t option_bytes_boot_add) { + int ret = -1; + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return -1; + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } + + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F7: + ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); + break; + default: + ELOG("Option bytes boot address writing is currently not implemented for " + "connected chip\n"); + break; + } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option bytes boot address %#010x!\n", option_bytes_boot_add); + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; +} + +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { + WLOG("About to write option byte %#10x to %#10x.\n", option_byte, + sl->option_base); + return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *)&option_byte, + 4); +} + +/** + * Write the given binary file with option bytes + * @param sl + * @param path readable file path, should be binary image + * @param addr of the memory mapped option bytes + * @return 0 on success, -ve on failure. + */ +int stlink_fwrite_option_bytes(stlink_t *sl, const char *path, + stm32_addr_t addr) { + /* Write the file in flash at addr */ + int err; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; + + if (map_file(&mf, path) == -1) { + ELOG("map_file() == -1\n"); + return (-1); + } + + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); + + err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t)mf.len); + stlink_fwrite_finalize(sl, addr); + unmap_file(&mf); + + return (err); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register1_f7(stlink_t *sl, + uint32_t *option_byte) { + DLOG("@@@@ Read option control register 1 byte from %#10x\n", + FLASH_F7_OPTCR1); + return stlink_read_debug32(sl, FLASH_F7_OPTCR1, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register1_32(stlink_t *sl, + uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } + + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F7: + return stlink_read_option_control_register1_f7(sl, option_byte); + default: + return -1; + // return stlink_read_option_control_register1_generic(sl, option_byte); + } +} + + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t *option_byte) { + DLOG("@@@@ Read option byte boot address\n"); + return stlink_read_option_control_register1_f7(sl, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes boot address read is currently not supported for " + "connected chip\n"); + return -1; + } + + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F7: + return stlink_read_option_bytes_boot_add_f7(sl, option_byte); + default: + return -1; + // return stlink_read_option_bytes_boot_add_generic(sl, option_byte); + } +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f7(stlink_t *sl, + uint32_t *option_byte) { + DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_F7_OPTCR); + return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f0(stlink_t *sl, + uint32_t *option_byte) { + DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_OBR); + return stlink_read_debug32(sl, FLASH_OBR, option_byte); +} + +/** + * Read option bytes + * @param sl + * @param option_byte option value + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } + + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + return stlink_read_option_control_register_f0(sl, option_byte); + case STM32_FLASH_TYPE_F7: + return stlink_read_option_control_register_f7(sl, option_byte); + default: + return -1; + } +} diff --git a/src/read_write.c b/src/read_write.c new file mode 100644 index 000000000..f20d76aab --- /dev/null +++ b/src/read_write.c @@ -0,0 +1,143 @@ +#include +#include +#include + +// Endianness +// https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html +// These functions encode and decode little endian uint16 and uint32 values. + +void write_uint32(unsigned char *buf, uint32_t ui) { + buf[0] = ui; + buf[1] = ui >> 8; + buf[2] = ui >> 16; + buf[3] = ui >> 24; +} + +void write_uint16(unsigned char *buf, uint16_t ui) { + buf[0] = (uint8_t)ui; + buf[1] = (uint8_t)(ui >> 8); +} + +uint32_t read_uint32(const unsigned char *c, const int pt) { + return ((uint32_t)c[pt]) | ((uint32_t)c[pt + 1] << 8) | + ((uint32_t)c[pt + 2] << 16) | ((uint32_t)c[pt + 3] << 24); +} + +uint16_t read_uint16(const unsigned char *c, const int pt) { + return ((uint16_t)c[pt]) | ((uint16_t)c[pt + 1] << 8); +} + +int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { + int ret; + + ret = sl->backend->read_debug32(sl, addr, data); + if (!ret) + DLOG("*** stlink_read_debug32 %#010x at %#010x\n", *data, addr); + + return (ret); +} + +int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { + DLOG("*** stlink_write_debug32 %#010x to %#010x\n", data, addr); + return sl->backend->write_debug32(sl, addr, data); +} + +int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { + DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); + + if (len % 4 != 0) { + ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); + return (-1); + } + + return (sl->backend->write_mem32(sl, addr, len)); +} + +int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { + DLOG("*** stlink_read_mem32 ***\n"); + + if (len % 4 != 0) { // !!! never ever: fw gives just wrong values + ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); + return (-1); + } + + return (sl->backend->read_mem32(sl, addr, len)); +} + +int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { + DLOG("*** stlink_write_mem8 ***\n"); + return (sl->backend->write_mem8(sl, addr, len)); +} + +int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { + DLOG("*** stlink_read_all_regs ***\n"); + return (sl->backend->read_all_regs(sl, regp)); +} + +int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { + DLOG("*** stlink_read_all_unsupported_regs ***\n"); + return (sl->backend->read_all_unsupported_regs(sl, regp)); +} + +int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) { + DLOG("*** stlink_write_reg\n"); + return (sl->backend->write_reg(sl, reg, idx)); +} + +int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { + DLOG("*** stlink_read_reg\n"); + DLOG(" (%d) ***\n", r_idx); + + if (r_idx > 20 || r_idx < 0) { + fprintf(stderr, "Error: register index must be in [0..20]\n"); + return (-1); + } + + return (sl->backend->read_reg(sl, r_idx, regp)); +} + +int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, + struct stlink_reg *regp) { + int r_convert; + + DLOG("*** stlink_read_unsupported_reg\n"); + DLOG(" (%d) ***\n", r_idx); + + /* Convert to values used by STLINK_REG_DCRSR */ + if (r_idx >= 0x1C && + r_idx <= 0x1F) { // primask, basepri, faultmask, or control + r_convert = 0x14; + } else if (r_idx == 0x40) { // FPSCR + r_convert = 0x21; + } else if (r_idx >= 0x20 && r_idx < 0x40) { + r_convert = 0x40 + (r_idx - 0x20); + } else { + fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); + return (-1); + } + + return (sl->backend->read_unsupported_reg(sl, r_convert, regp)); +} + +int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, + struct stlink_reg *regp) { + int r_convert; + + DLOG("*** stlink_write_unsupported_reg\n"); + DLOG(" (%d) ***\n", r_idx); + + /* Convert to values used by STLINK_REG_DCRSR */ + if (r_idx >= 0x1C && + r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ + r_convert = r_idx; // the backend function handles this + } else if (r_idx == 0x40) { // FPSCR + r_convert = 0x21; + } else if (r_idx >= 0x20 && r_idx < 0x40) { + r_convert = 0x40 + (r_idx - 0x20); + } else { + fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); + return (-1); + } + + return (sl->backend->write_unsupported_reg(sl, val, r_convert, regp)); +} diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index 458e7c3e2..f8e1b3444 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -4,7 +4,8 @@ #include #include -/** Chipid parametres */ + +/** Chipid parameters */ struct stlink_chipid_params { char *dev_type; char *ref_manual_id; @@ -22,6 +23,6 @@ struct stlink_chipid_params { }; struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); - void init_chipids(char *dir_to_scan); + void init_chipids(char *dir_to_scan); #endif // STLINK_CHIPID_H_ diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index e07918800..2e99e82be 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1134,33 +1134,8 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, #endif libusb_device **list = NULL; - // TODO: We should use ssize_t and use it as a counter if > 0. - // As per libusb API: ssize_t libusb_get_device_list (libusb_context *ctx, libusb_device ***list) - int cnt = (int)libusb_get_device_list(slu->libusb_ctx, &list); + ssize_t cnt = libusb_get_device_list(slu->libusb_ctx, &list); struct libusb_device_descriptor desc; - int devBus = 0; - int devAddr = 0; - - // TODO: Reading a environment variable in a usb open function is not very nice, this should - // be refactored and moved into the CLI tools, and instead of giving USB_BUS:USB_ADDR a real - // stlink serial string should be passed to this function. Probably people are using this - // but this is very odd because as programmer can change to multiple busses and it is better - // to detect them based on serial. - char *device = getenv("STLINK_DEVICE"); - - if (device) { - char *c = strchr(device, ':'); - - if (c == NULL) { - WLOG("STLINK_DEVICE must be : format\n"); - goto on_error; - } - - devBus = atoi(device); - *c++ = 0; - devAddr = atoi(c); - ILOG("bus %03d dev %03d\n", devBus, devAddr); - } while (cnt-- > 0) { struct libusb_device_handle *handle; @@ -1169,13 +1144,6 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, if (desc.idVendor != STLINK_USB_VID_ST) { continue; } - if (devBus && devAddr) { - if ((libusb_get_bus_number(list[cnt]) != devBus) || - (libusb_get_device_address(list[cnt]) != devAddr)) { - continue; - } - } - ret = libusb_open(list[cnt], &handle); if (ret) { continue; } // could not open device @@ -1202,7 +1170,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, } if (cnt < 0) { - WLOG ("Couldn't find %s ST-Link devices\n", (devBus && devAddr) ? "matched" : "any"); + WLOG ("Couldn't find any ST-Link devices\n"); libusb_free_device_list(list, 1); goto on_error; } else { @@ -1221,6 +1189,8 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, libusb_free_device_list(list, 1); +// libusb_kernel_driver_active is not available on Windows. +#if !defined(_WIN32) if (libusb_kernel_driver_active(slu->usb_handle, 0) == 1) { ret = libusb_detach_kernel_driver(slu->usb_handle, 0); @@ -1229,6 +1199,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, goto on_libusb_error; } } +#endif if (libusb_get_configuration(slu->usb_handle, &config)) { // this may fail for a previous configured device @@ -1287,7 +1258,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, // the NRST pin must be pull down before selecting the SWD/JTAG mode if (mode == STLINK_DEV_DEBUG_MODE) { DLOG("-- exit_debug_mode\n"); - _stlink_usb_exit_dfu_mode(sl); + _stlink_usb_exit_debug_mode(sl); } _stlink_usb_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); diff --git a/src/stlink-lib/usb.c.bak b/src/stlink-lib/usb.c.bak new file mode 100644 index 000000000..32ceff71f --- /dev/null +++ b/src/stlink-lib/usb.c.bak @@ -0,0 +1,1410 @@ +#include +#include +#include +#include +#include + +#if !defined(_MSC_VER) +#include +#endif + +#include +#include +#include + +#if defined(_WIN32) +#include +#endif + +#include +#include +#include "usb.h" + +enum SCSI_Generic_Direction {SG_DXFER_TO_DEV = 0, SG_DXFER_FROM_DEV = 0x80}; + +static inline uint32_t le_to_h_u32(const uint8_t* buf) { + return((uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24)); +} + +static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, uint32_t khz) { + unsigned int i; + int speed_index = -1; + int speed_diff = INT_MAX; + int last_valid_speed = -1; + bool match = true; + + for (i = 0; i < map_size; i++) { + if (!map[i]) { continue; } + + last_valid_speed = i; + + if (khz == map[i]) { + speed_index = i; + break; + } else { + int current_diff = khz - map[i]; + // get abs value for comparison + current_diff = (current_diff > 0) ? current_diff : -current_diff; + + if (current_diff < speed_diff) { + speed_diff = current_diff; + speed_index = i; + } + } + } + + if (speed_index == -1) { + // This will only be here if we cannot match the slow speed. + // Use the slowest speed we support. + speed_index = last_valid_speed; + match = false; + } else if (i == map_size) { + match = false; + } + + if (!match) { + ILOG("Unable to match requested speed %d kHz, using %d kHz\n", khz, map[speed_index]); + } + + return(speed_index); +} + +void _stlink_usb_close(stlink_t* sl) { + if (!sl) { return; } + + struct stlink_libusb * const handle = sl->backend_data; + + // maybe we couldn't even get the usb device? + if (handle != NULL) { + if (handle->usb_handle != NULL) { libusb_close(handle->usb_handle); } + + libusb_exit(handle->libusb_ctx); + free(handle); + } +} + +ssize_t send_recv(struct stlink_libusb* handle, int terminate, + unsigned char* txbuf, size_t txsize, unsigned char* rxbuf, + size_t rxsize, int check_error, const char *cmd) { + // Note: txbuf and rxbuf can point to the same area + int res, t, retry = 0; + + while (1) { + res = 0; + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, (int)txsize, &res, 3000); + + if (t) { + ELOG("%s send request failed: %s\n", cmd, libusb_error_name(t)); + return(-1); + } else if ((size_t)res != txsize) { + ELOG("%s send request wrote %u bytes, instead of %u\n", + cmd, (unsigned int)res, (unsigned int)txsize); + } + + if (rxsize != 0) { + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int)rxsize, &res, 3000); + + if (t) { + ELOG("%s read reply failed: %s\n", cmd, libusb_error_name(t)); + return(-1); + } + + /* Checking the command execution status stored in the first byte of the response */ + if (handle->protocoll != 1 && check_error >= CMD_CHECK_STATUS && + rxbuf[0] != STLINK_DEBUG_ERR_OK) { + switch(rxbuf[0]) { + case STLINK_DEBUG_ERR_AP_WAIT: + case STLINK_DEBUG_ERR_DP_WAIT: + if (check_error == CMD_CHECK_RETRY && retry < 3) { + unsigned int delay_us = (1<protocoll == 1) && terminate) { + // read the SG reply + unsigned char sg_buf[13]; + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, sg_buf, 13, &res, 3000); + + if (t) { + ELOG("%s read storage failed: %s\n", cmd, libusb_error_name(t)); + return(-1); + } + + // The STLink doesn't seem to evaluate the sequence number. + handle->sg_transfer_idx++; + } + + return(res); + } +} + +static inline int send_only(struct stlink_libusb* handle, int terminate, + unsigned char* txbuf, size_t txsize, + const char *cmd) { + return((int)send_recv(handle, terminate, txbuf, txsize, NULL, 0, CMD_CHECK_NO, cmd)); +} + + +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); +} + +int _stlink_usb_version(stlink_t *sl) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + uint32_t rep_len; + int i; + + if (sl->version.stlink_v == 3) { + // STLINK-V3 version is determined by another command + rep_len = 12; + i = fill_command(sl, SG_DXFER_FROM_DEV, 16); + cmd[i++] = STLINK_GET_VERSION_APIV3; + } else { + rep_len = 6; + i = fill_command(sl, SG_DXFER_FROM_DEV, 6); + cmd[i++] = STLINK_GET_VERSION; + } + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_REP_LEN, "GET_VERSION"); + + return(size<0?-1:0); +} + +int32_t _stlink_usb_target_voltage(stlink_t *sl) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const rdata = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + uint32_t rep_len = 8; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + uint32_t factor, reading; + int voltage; + + cmd[i++] = STLINK_GET_TARGET_VOLTAGE; + + size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, CMD_CHECK_REP_LEN, "GET_TARGET_VOLTAGE"); + + if (size < 0) { + return(-1); + } + + factor = (rdata[3] << 24) | (rdata[2] << 16) | (rdata[1] << 8) | (rdata[0] << 0); + reading = (rdata[7] << 24) | (rdata[6] << 16) | (rdata[5] << 8) | (rdata[4] << 0); + voltage = 2400 * reading / factor; + + return(voltage); +} + +int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const rdata = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + const int rep_len = 8; + + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_APIV2_READDEBUGREG; + write_uint32(&cmd[i], addr); + size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, CMD_CHECK_RETRY, "READDEBUGREG"); + + if (size < 0) { + return(-1); + } + + *data = read_uint32(rdata, 4); + + return(0); +} + +int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const rdata = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + const int rep_len = 2; + + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_APIV2_WRITEDEBUGREG; + write_uint32(&cmd[i], addr); + write_uint32(&cmd[i + 4], data); + size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, CMD_CHECK_RETRY, "WRITEDEBUGREG"); + + return(size<0?-1:0); +} + +int _stlink_usb_get_rw_status(stlink_t *sl) { + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { return(0); } + + unsigned char* const rdata = sl->q_buf; + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const cmd = sl->c_buf; + int i; + int16_t ret = 0; + + i = fill_command(sl, SG_DXFER_FROM_DEV, 12); + cmd[i++] = STLINK_DEBUG_COMMAND; + + if (sl->version.flags & STLINK_F_HAS_GETLASTRWSTATUS2) { + cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS2; + ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 12, CMD_CHECK_STATUS, "GETLASTRWSTATUS2"); + } else { + cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS; + ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 2, CMD_CHECK_STATUS, "GETLASTRWSTATUS"); + } + + return(ret<0?-1:0); +} + +int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + int i, ret; + + 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); + ret = send_only(slu, 0, cmd, slu->cmd_len, "WRITEMEM_32BIT"); + + if (ret == -1) { return(ret); } + + ret = send_only(slu, 1, data, len, "WRITEMEM_32BIT"); + + if (ret == -1) { return(ret); } + + return(_stlink_usb_get_rw_status(sl)); +} + +int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + int i, ret; + + if ((sl->version.jtag_api < STLINK_JTAG_API_V3 && len > 64) || + (sl->version.jtag_api >= STLINK_JTAG_API_V3 && len > 512)) { + ELOG("WRITEMEM_8BIT: bulk packet limits exceeded (data len %d byte)\n", len); + return (-1); + } + + 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); + ret = send_only(slu, 0, cmd, slu->cmd_len, "WRITEMEM_8BIT"); + + if (ret == -1) { return(ret); } + + ret = send_only(slu, 1, data, len, "WRITEMEM_8BIT"); + + if (ret == -1) { return(ret); } + + return(0); +} + + +int _stlink_usb_current_mode(stlink_t * sl) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const cmd = sl->c_buf; + unsigned char* const data = sl->q_buf; + ssize_t size; + 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, CMD_CHECK_NO, "GET_CURRENT_MODE"); + + if (size < 0) { + return(-1); + } + + return(sl->q_buf[0]); +} + +int _stlink_usb_core_id(stlink_t * sl) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const cmd = sl->c_buf; + unsigned char* const data = sl->q_buf; + ssize_t size; + int offset, rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 12; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + + cmd[i++] = STLINK_DEBUG_COMMAND; + + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { + cmd[i++] = STLINK_DEBUG_READCOREID; + offset = 0; + } else { + cmd[i++] = STLINK_DEBUG_APIV2_READ_IDCODES; + offset = 4; + } + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "READ_IDCODES"); + + if (size < 0) { + return(-1); + } + + sl->core_id = read_uint32(data, offset); + + return(0); +} + +int _stlink_usb_status_v2(stlink_t *sl) { + int result; + uint32_t status = 0; + + result = _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &status); + DLOG("core status: %08X\n", status); + + if (result != 0) { + sl->core_stat = TARGET_UNKNOWN; + } else { + if (status & STLINK_REG_DHCSR_C_HALT) { + sl->core_stat = TARGET_HALTED; + } else if (status & STLINK_REG_DHCSR_S_RESET_ST) { + sl->core_stat = TARGET_RESET; + } else { + sl->core_stat = TARGET_RUNNING; + } + } + + return(result); +} + +int _stlink_usb_status(stlink_t * sl) { + if (sl->version.jtag_api != STLINK_JTAG_API_V1) { return(_stlink_usb_status_v2(sl)); } + + struct stlink_libusb * const slu = sl->backend_data; + 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); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_GETSTATUS; + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_NO, "GETSTATUS"); + + if (size > 1) { + if (sl->q_buf[0] == STLINK_CORE_RUNNING) { + sl->core_stat = TARGET_RUNNING; + } else if (sl->q_buf[0] == STLINK_CORE_HALTED) { + sl->core_stat = TARGET_HALTED; + } else { + sl->core_stat = TARGET_UNKNOWN; + } + } else { + sl->core_stat = TARGET_UNKNOWN; + } + + return(size<0?-1:0); +} + +int _stlink_usb_force_debug(stlink_t *sl) { + struct stlink_libusb *slu = sl->backend_data; + + int res; + + if (sl->version.jtag_api != STLINK_JTAG_API_V1) { + res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_DEBUGEN); + return(res); + } + + 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); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_FORCEDEBUG; + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "FORCEDEBUG"); + + return(size<0?-1:0); +} + +int _stlink_usb_enter_swd_mode(stlink_t * sl) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + unsigned char* const data = sl->q_buf; + const uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 2; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + + cmd[i++] = STLINK_DEBUG_COMMAND; + // select correct API-Version for entering SWD mode: V1 API (0x20) or V2 API (0x30). + cmd[i++] = sl->version.jtag_api == STLINK_JTAG_API_V1 ? STLINK_DEBUG_APIV1_ENTER : STLINK_DEBUG_APIV2_ENTER; + cmd[i++] = STLINK_DEBUG_ENTER_SWD; + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "ENTER_SWD"); + + return(size<0?-1:0); +} + +int _stlink_usb_exit_dfu_mode(stlink_t* sl) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + int i = fill_command(sl, SG_DXFER_FROM_DEV, 0); + + cmd[i++] = STLINK_DFU_COMMAND; + cmd[i++] = STLINK_DFU_EXIT; + size = send_only(slu, 1, cmd, slu->cmd_len, "DFU_EXIT"); + + return(size<0?-1:0); +} + + +int _stlink_usb_reset(stlink_t * sl) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + int i, rep_len = 2; + + // send reset command + i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + cmd[i++] = STLINK_DEBUG_COMMAND; + + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { + cmd[i++] = STLINK_DEBUG_APIV1_RESETSYS; + } else { + cmd[i++] = STLINK_DEBUG_APIV2_RESETSYS; + } + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "RESETSYS"); + + return(size<0?-1:0); +} + +int _stlink_usb_jtag_reset(stlink_t * sl, int value) { + struct stlink_libusb * const slu = sl->backend_data; + 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); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_APIV2_DRIVE_NRST; + cmd[i++] = value; + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "DRIVE_NRST"); + + return(size<0?-1:0); +} + + +int _stlink_usb_step(stlink_t* sl) { + struct stlink_libusb * const slu = sl->backend_data; + + if (sl->version.jtag_api != STLINK_JTAG_API_V1) { + // emulates the JTAG v1 API by using DHCSR + _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_MASKINTS | STLINK_REG_DHCSR_C_DEBUGEN); + _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_STEP | + STLINK_REG_DHCSR_C_MASKINTS | STLINK_REG_DHCSR_C_DEBUGEN); + return _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_DEBUGEN); + } + + 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); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_STEPCORE; + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "STEPCORE"); + + return(size<0?-1:0); +} + +/** + * This seems to do a good job of restarting things from the beginning? + * @param sl + * @param type + */ +int _stlink_usb_run(stlink_t* sl, enum run_type type) { + struct stlink_libusb * const slu = sl->backend_data; + + int res; + + if (sl->version.jtag_api != STLINK_JTAG_API_V1) { + res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + ((type==RUN_FLASH_LOADER)?STLINK_REG_DHCSR_C_MASKINTS:0)); + return(res); + } + + + 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); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_RUNCORE; + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "RUNCORE"); + + return(size<0?-1:0); +} + +int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + int rep_len = 2; + int i; + + // clock speed only supported by stlink/v2 and for firmware >= 22 + if (sl->version.stlink_v == 2 && sl->version.jtag_v >= 22) { + uint16_t clk_divisor; + if (clk_freq) { + const uint32_t map[] = {5, 15, 25, 50, 100, 125, 240, 480, 950, 1200, 1800, 4000}; + int speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), clk_freq); + switch (map[speed_index]) { + case 5: clk_divisor = STLINK_SWDCLK_5KHZ_DIVISOR; break; + case 15: clk_divisor = STLINK_SWDCLK_15KHZ_DIVISOR; break; + case 25: clk_divisor = STLINK_SWDCLK_25KHZ_DIVISOR; break; + case 50: clk_divisor = STLINK_SWDCLK_50KHZ_DIVISOR; break; + case 100: clk_divisor = STLINK_SWDCLK_100KHZ_DIVISOR; break; + case 125: clk_divisor = STLINK_SWDCLK_125KHZ_DIVISOR; break; + case 240: clk_divisor = STLINK_SWDCLK_240KHZ_DIVISOR; break; + case 480: clk_divisor = STLINK_SWDCLK_480KHZ_DIVISOR; break; + case 950: clk_divisor = STLINK_SWDCLK_950KHZ_DIVISOR; break; + case 1200: clk_divisor = STLINK_SWDCLK_1P2MHZ_DIVISOR; break; + default: + case 1800: clk_divisor = STLINK_SWDCLK_1P8MHZ_DIVISOR; break; + case 4000: clk_divisor = STLINK_SWDCLK_4MHZ_DIVISOR; break; + } + } else + clk_divisor = STLINK_SWDCLK_1P8MHZ_DIVISOR; + + i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_APIV2_SWD_SET_FREQ; + cmd[i++] = clk_divisor & 0xFF; + cmd[i++] = (clk_divisor >> 8) & 0xFF; + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "SWD_SET_FREQ"); + + return(size<0?-1:0); + } else if (sl->version.stlink_v == 3) { + int speed_index; + uint32_t map[STLINK_V3_MAX_FREQ_NB]; + i = fill_command(sl, SG_DXFER_FROM_DEV, 16); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_APIV3_GET_COM_FREQ; + cmd[i++] = 0; // SWD mode + size = send_recv(slu, 1, cmd, slu->cmd_len, data, 52, CMD_CHECK_STATUS, "GET_COM_FREQ"); + + if (size < 0) { + return(-1); + } + + int speeds_size = data[8]; + if (speeds_size > STLINK_V3_MAX_FREQ_NB) { + speeds_size = STLINK_V3_MAX_FREQ_NB; + } + + for (i = 0; i < speeds_size; i++) map[i] = le_to_h_u32(&data[12 + 4 * i]); + + // Set to zero all the next entries + for (i = speeds_size; i < STLINK_V3_MAX_FREQ_NB; i++) map[i] = 0; + + if (!clk_freq) clk_freq = 1000; // set default frequency + speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), clk_freq); + + i = fill_command(sl, SG_DXFER_FROM_DEV, 16); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_APIV3_SET_COM_FREQ; + cmd[i++] = 0; // SWD mode + cmd[i++] = 0; + cmd[i++] = (uint8_t)((map[speed_index] >> 0) & 0xFF); + cmd[i++] = (uint8_t)((map[speed_index] >> 8) & 0xFF); + cmd[i++] = (uint8_t)((map[speed_index] >> 16) & 0xFF); + cmd[i++] = (uint8_t)((map[speed_index] >> 24) & 0xFF); + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8, CMD_CHECK_STATUS, "SET_COM_FREQ"); + + return(size<0?-1:0); + } else if (clk_freq) { + WLOG("ST-Link firmware does not support frequency setup\n"); + } + + return(-1); +} + +int _stlink_usb_exit_debug_mode(stlink_t *sl) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + int i = fill_command(sl, SG_DXFER_FROM_DEV, 0); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_EXIT; + + size = send_only(slu, 1, cmd, slu->cmd_len, "DEBUG_EXIT"); + + return(size<0?-1:0); +} + +int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { + struct stlink_libusb * const slu = sl->backend_data; + 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); + + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_READMEM_32BIT; + write_uint32(&cmd[i], addr); + write_uint16(&cmd[i + 4], len); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, len, CMD_CHECK_NO, "READMEM_32BIT"); + + if (size < 0) { + return(-1); + } + + sl->q_len = (int)size; + stlink_print_data(sl); + + return(0); +} + +int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const cmd = sl->c_buf; + unsigned char* const data = sl->q_buf; + ssize_t size; + uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 84 : 88; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + + cmd[i++] = STLINK_DEBUG_COMMAND; + + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { + cmd[i++] = STLINK_DEBUG_APIV1_READALLREGS; + } else { + cmd[i++] = STLINK_DEBUG_APIV2_READALLREGS; + } + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "READALLREGS"); + + if (size < 0) { + return(-1); + } + + /* V1: regs data from offset 0 */ + /* V2: status at offset 0, regs data from offset 4 */ + int reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; + sl->q_len = (int)size; + stlink_print_data(sl); + + for (i = 0; i < 16; i++) regp->r[i] = read_uint32(sl->q_buf, reg_offset + i * 4); + + regp->xpsr = read_uint32(sl->q_buf, reg_offset + 64); + regp->main_sp = read_uint32(sl->q_buf, reg_offset + 68); + regp->process_sp = read_uint32(sl->q_buf, reg_offset + 72); + regp->rw = read_uint32(sl->q_buf, reg_offset + 76); + regp->rw2 = read_uint32(sl->q_buf, reg_offset + 80); + + if (sl->verbose < 2) { return(0); } + + DLOG("xpsr = 0x%08x\n", regp->xpsr); + DLOG("main_sp = 0x%08x\n", regp->main_sp); + DLOG("process_sp = 0x%08x\n", regp->process_sp); + DLOG("rw = 0x%08x\n", regp->rw); + DLOG("rw2 = 0x%08x\n", regp->rw2); + + return(0); +} + +int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + uint32_t r; + uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 8; + int reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + + cmd[i++] = STLINK_DEBUG_COMMAND; + + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { + cmd[i++] = STLINK_DEBUG_APIV1_READREG; + } else { + cmd[i++] = STLINK_DEBUG_APIV2_READREG; + } + + cmd[i++] = (uint8_t)r_idx; + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "READREG"); + + if (size < 0) { + return(-1); + } + + sl->q_len = (int)size; + stlink_print_data(sl); + r = read_uint32(sl->q_buf, reg_offset); + DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); + + switch (r_idx) { + case 16: + regp->xpsr = r; + break; + case 17: + regp->main_sp = r; + break; + case 18: + regp->process_sp = r; + break; + case 19: + regp->rw = r; // XXX ?(primask, basemask etc.) + break; + case 20: + regp->rw2 = r; // XXX ?(primask, basemask etc.) + break; + default: + regp->r[r_idx] = r; + } + + return(0); +} + +/* See section C1.6 of the ARMv7-M Architecture Reference Manual */ +int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { + uint32_t r; + int ret; + + sl->q_buf[0] = (unsigned char)r_idx; + + for (int i = 1; i < 4; i++) sl->q_buf[i] = 0; + + ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4); + + if (ret == -1) { return(ret); } + + ret = _stlink_usb_read_mem32(sl, STLINK_REG_DCRDR, 4); + + if (ret == -1) { return(ret); } + + r = read_uint32(sl->q_buf, 0); + DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); + + switch (r_idx) { + case 0x14: + regp->primask = (uint8_t)(r & 0xFF); + regp->basepri = (uint8_t)((r >> 8) & 0xFF); + regp->faultmask = (uint8_t)((r >> 16) & 0xFF); + regp->control = (uint8_t)((r >> 24) & 0xFF); + break; + case 0x21: + regp->fpscr = r; + break; + default: + regp->s[r_idx - 0x40] = r; + break; + } + + return(0); +} + +int _stlink_usb_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { + int ret; + + ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); + + if (ret == -1) { return(ret); } + + ret = _stlink_usb_read_unsupported_reg(sl, 0x21, regp); + + if (ret == -1) { return(ret); } + + for (int i = 0; i < 32; i++) { + ret = _stlink_usb_read_unsupported_reg(sl, 0x40 + i, regp); + + if (ret == -1) { return(ret); } + } + + return(0); +} + +/* See section C1.6 of the ARMv7-M Architecture Reference Manual */ +int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, struct stlink_reg *regp) { + int ret; + + if (r_idx >= 0x1C && r_idx <= 0x1F) { // primask, basepri, faultmask, or control + /* These are held in the same register */ + ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); + + if (ret == -1) { return(ret); } + + val = (uint8_t)(val >> 24); + + switch (r_idx) { + case 0x1C: /* control */ + val = (((uint32_t)val) << 24) | + (((uint32_t)regp->faultmask) << 16) | + (((uint32_t)regp->basepri) << 8) | + ((uint32_t)regp->primask); + break; + case 0x1D: /* faultmask */ + val = (((uint32_t)regp->control) << 24) | + (((uint32_t)val) << 16) | + (((uint32_t)regp->basepri) << 8) | + ((uint32_t)regp->primask); + break; + case 0x1E: /* basepri */ + val = (((uint32_t)regp->control) << 24) | + (((uint32_t)regp->faultmask) << 16) | + (((uint32_t)val) << 8) | + ((uint32_t)regp->primask); + break; + case 0x1F: /* primask */ + val = (((uint32_t)regp->control) << 24) | + (((uint32_t)regp->faultmask) << 16) | + (((uint32_t)regp->basepri) << 8) | + ((uint32_t)val); + break; + } + + r_idx = 0x14; + } + + write_uint32(sl->q_buf, val); + + ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRDR, 4); + + if (ret == -1) { return(ret); } + + sl->q_buf[0] = (unsigned char)r_idx; + sl->q_buf[1] = 0; + sl->q_buf[2] = 0x01; + sl->q_buf[3] = 0; + + return(_stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4)); +} + +int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + uint32_t rep_len = 2; + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + + cmd[i++] = STLINK_DEBUG_COMMAND; + + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { + cmd[i++] = STLINK_DEBUG_APIV1_WRITEREG; + } else { + cmd[i++] = STLINK_DEBUG_APIV2_WRITEREG; + } + + cmd[i++] = idx; + write_uint32(&cmd[i], reg); + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "WRITEREG"); + + return(size<0?-1:0); +} + +int _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + uint32_t rep_len = 2; + + int i = fill_command(sl, SG_DXFER_TO_DEV, rep_len); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_APIV2_START_TRACE_RX; + write_uint16(&cmd[i + 0], 2 * STLINK_TRACE_BUF_LEN); + write_uint32(&cmd[i + 2], frequency); + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "START_TRACE_RX"); + + return(size<0?-1:0); +} + +int _stlink_usb_disable_trace(stlink_t* sl) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + uint32_t rep_len = 2; + + int i = fill_command(sl, SG_DXFER_TO_DEV, rep_len); + cmd[i++] = STLINK_DEBUG_COMMAND; + cmd[i++] = STLINK_DEBUG_APIV2_STOP_TRACE_RX; + + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "STOP_TRACE_RX"); + + return(size<0?-1:0); +} + +int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + 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_APIV2_GET_TRACE_NB; + ssize_t send_size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_NO, "GET_TRACE_NB"); + + if (send_size < 0) { + return(-1); + } else if (send_size != 2) { + ELOG("STLINK_DEBUG_APIV2_GET_TRACE_NB reply size %d\n", (int)send_size); + return(-1); + } + + uint16_t trace_count = read_uint16(sl->q_buf, 0); + + if (trace_count > size) { + ELOG("read_trace insufficient buffer length\n"); + return -1; + } + + if (trace_count != 0) { + int res = 0; + int t = libusb_bulk_transfer(slu->usb_handle, slu->ep_trace, buf, trace_count, &res, 3000); + + if (t || res != (int)trace_count) { + ELOG("read_trace read error %d\n", t); + return(-1); + } + } + + return trace_count; +} + +static stlink_backend_t _stlink_usb_backend = { + _stlink_usb_close, + _stlink_usb_exit_debug_mode, + _stlink_usb_enter_swd_mode, + NULL, // don't enter_jtag_mode here... + _stlink_usb_exit_dfu_mode, + _stlink_usb_core_id, + _stlink_usb_reset, + _stlink_usb_jtag_reset, + _stlink_usb_run, + _stlink_usb_status, + _stlink_usb_version, + _stlink_usb_read_debug32, + _stlink_usb_read_mem32, + _stlink_usb_write_debug32, + _stlink_usb_write_mem32, + _stlink_usb_write_mem8, + _stlink_usb_read_all_regs, + _stlink_usb_read_reg, + _stlink_usb_read_all_unsupported_regs, + _stlink_usb_read_unsupported_reg, + _stlink_usb_write_unsupported_reg, + _stlink_usb_write_reg, + _stlink_usb_step, + _stlink_usb_current_mode, + _stlink_usb_force_debug, + _stlink_usb_target_voltage, + _stlink_usb_set_swdclk, + _stlink_usb_enable_trace, + _stlink_usb_disable_trace, + _stlink_usb_read_trace +}; + +/* return the length of serial or (0) in case of errors */ +size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_descriptor *desc, char *serial) { + unsigned char desc_serial[(STLINK_SERIAL_LENGTH) * 2]; + + /* truncate the string in the serial buffer */ + serial[0] = '\0'; + + /* get the LANGID from String Descriptor Zero */ + int ret = libusb_get_string_descriptor(handle, 0, 0, desc_serial, sizeof(desc_serial)); + if (ret < 4) return 0; + + uint32_t langid = desc_serial[2] | (desc_serial[3] << 8); + + /* get the serial */ + ret = libusb_get_string_descriptor(handle, desc->iSerialNumber, langid, desc_serial, + sizeof(desc_serial)); + if (ret < 0) return 0; // could not read serial + + unsigned char len = desc_serial[0]; + + if (len == ((STLINK_SERIAL_LENGTH + 1) * 2)) { /* len == 50 */ + /* good ST-Link adapter */ + ret = libusb_get_string_descriptor_ascii( + handle, desc->iSerialNumber, (unsigned char *)serial, STLINK_SERIAL_BUFFER_SIZE); + if (ret < 0) return 0; + } else if (len == ((STLINK_SERIAL_LENGTH / 2 + 1) * 2)) { /* len == 26 */ + /* fix-up the buggy serial */ + for (unsigned int i = 0; i < STLINK_SERIAL_LENGTH; i += 2) + sprintf(serial + i, "%02X", desc_serial[i + 2]); + serial[STLINK_SERIAL_LENGTH] = '\0'; + } else { + return 0; + } + + return strlen(serial); +} + +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq) { + stlink_t* sl = NULL; + struct stlink_libusb* slu = NULL; + int ret = -1; + int config; + + sl = calloc(1, sizeof(stlink_t)); + if (sl == NULL) { goto on_malloc_error; } + + slu = calloc(1, sizeof(struct stlink_libusb)); + if (slu == NULL) { goto on_malloc_error; } + + ugly_init(verbose); + sl->backend = &_stlink_usb_backend; + sl->backend_data = slu; + + sl->core_stat = TARGET_UNKNOWN; + + if (libusb_init(&(slu->libusb_ctx))) { + WLOG("failed to init libusb context, wrong version of libraries?\n"); + goto on_error; + } + +#if LIBUSB_API_VERSION < 0x01000106 + libusb_set_debug(slu->libusb_ctx, ugly_libusb_log_level(verbose)); +#else + libusb_set_option(slu->libusb_ctx, LIBUSB_OPTION_LOG_LEVEL, ugly_libusb_log_level(verbose)); +#endif + + libusb_device **list = NULL; + // TODO: We should use ssize_t and use it as a counter if > 0. + // As per libusb API: ssize_t libusb_get_device_list (libusb_context *ctx, libusb_device ***list) + ssize_t cnt = libusb_get_device_list(slu->libusb_ctx, &list); + struct libusb_device_descriptor desc; + + while (cnt-- > 0) { + struct libusb_device_handle *handle; + + libusb_get_device_descriptor(list[cnt], &desc); + + if (desc.idVendor != STLINK_USB_VID_ST) { continue; } + + ret = libusb_open(list[cnt], &handle); + + if (ret) { continue; } // could not open device + + size_t serial_len = stlink_serial(handle, &desc, sl->serial); + + libusb_close(handle); + + if (serial_len != STLINK_SERIAL_LENGTH) { continue; } // could not read the serial + + // if no serial provided, or if serial match device, fixup version and protocol + if (((serial == NULL) || (*serial == 0)) || (memcmp(serial, &sl->serial, STLINK_SERIAL_LENGTH) == 0)) { + if (STLINK_V1_USB_PID(desc.idProduct)) { + slu->protocoll = 1; + sl->version.stlink_v = 1; + } else if (STLINK_V2_USB_PID(desc.idProduct) || STLINK_V2_1_USB_PID(desc.idProduct)) { + sl->version.stlink_v = 2; + } else if (STLINK_V3_USB_PID(desc.idProduct)) { + sl->version.stlink_v = 3; + } + + break; + } + } + + if (cnt < 0) { + WLOG ("Couldn't find any ST-Link devices\n"); + libusb_free_device_list(list, 1); + goto on_error; + } else { + ret = libusb_open(list[cnt], &slu->usb_handle); + + if (ret != 0) { + WLOG("Error %d (%s) opening ST-Link v%d device %03d:%03d\n", ret, + strerror(errno), + sl->version.stlink_v, + libusb_get_bus_number(list[cnt]), + libusb_get_device_address(list[cnt])); + libusb_free_device_list(list, 1); + goto on_error; + } + } + + libusb_free_device_list(list, 1); + +// libusb_kernel_driver_active is not available on Windows. +#if !defined(_WIN32) + if (libusb_kernel_driver_active(slu->usb_handle, 0) == 1) { + ret = libusb_detach_kernel_driver(slu->usb_handle, 0); + + if (ret < 0) { + WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-ret)); + goto on_libusb_error; + } + } +#endif + + if (libusb_get_configuration(slu->usb_handle, &config)) { + // this may fail for a previous configured device + WLOG("libusb_get_configuration()\n"); + goto on_libusb_error; + } + + if (config != 1) { + printf("setting new configuration (%d -> 1)\n", config); + + if (libusb_set_configuration(slu->usb_handle, 1)) { + // this may fail for a previous configured device + WLOG("libusb_set_configuration() failed\n"); + goto on_libusb_error; + } + } + + if (libusb_claim_interface(slu->usb_handle, 0)) { + WLOG("Stlink usb device found, but unable to claim (probably already in use?)\n"); + goto on_libusb_error; + } + + // TODO: Could use the scanning technique from STM8 code here... + slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; + + if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO || + desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO || + desc.idProduct == STLINK_USB_PID_STLINK_V2_1 || + desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER || + desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID || + desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID || + desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID || + desc.idProduct == STLINK_USB_PID_STLINK_V3_NO_MSD_PID) { + slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; + slu->ep_trace = 2 | LIBUSB_ENDPOINT_IN; + } else { + slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; + slu->ep_trace = 3 | LIBUSB_ENDPOINT_IN; + } + + slu->sg_transfer_idx = 0; + slu->cmd_len = (slu->protocoll == 1) ? STLINK_SG_SIZE : STLINK_CMD_SIZE; + + // initialize stlink version (sl->version) + stlink_version(sl); + + int mode = stlink_current_mode(sl); + if (mode == STLINK_DEV_DFU_MODE) { + DLOG("-- exit_dfu_mode\n"); + _stlink_usb_exit_dfu_mode(sl); + } + + if (connect == CONNECT_UNDER_RESET) { + // for the connect under reset only + // OpenOСD says (official documentation is not available) that + // the NRST pin must be pull down before selecting the SWD/JTAG mode + if (mode == STLINK_DEV_DEBUG_MODE) { + DLOG("-- exit_debug_mode\n"); + _stlink_usb_exit_debug_mode(sl); + } + + _stlink_usb_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); + } + + sl->freq = freq; + // set the speed before entering the mode as the chip discovery phase + // should be done at this speed too + // set the stlink clock speed (default is 1800kHz) + DLOG("JTAG/SWD freq set to %d\n", freq); + _stlink_usb_set_swdclk(sl, freq); + + stlink_target_connect(sl, connect); + return(sl); + +on_libusb_error: + stlink_close(sl); + return(NULL); + +on_error: + if (slu->libusb_ctx) { libusb_exit(slu->libusb_ctx); } + +on_malloc_error: + if (sl != NULL) { free(sl); } + if (slu != NULL) { free(slu); } + + return(NULL); +} + +static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], enum connect_type connect, int freq) { + stlink_t **_sldevs; + libusb_device *dev; + int i = 0; + size_t slcnt = 0; + size_t slcur = 0; + + /* Count STLINKs */ + while ((dev = devs[i++]) != NULL) { + struct libusb_device_descriptor desc; + int ret = libusb_get_device_descriptor(dev, &desc); + + if (ret < 0) { + WLOG("failed to get libusb device descriptor (libusb error: %d)\n", ret); + break; + } + + if (desc.idVendor != STLINK_USB_VID_ST) { continue; } + + if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { + WLOG("skipping ST device : %#04x:%#04x)\n", desc.idVendor, desc.idProduct); + continue; + } + + slcnt++; + } + + _sldevs = calloc(slcnt, sizeof(stlink_t *)); // allocate list of pointers + + if (!_sldevs) { + *sldevs = NULL; + return(0); + } + + /* Open STLINKS and attach them to list */ + i = 0; + + while ((dev = devs[i++]) != NULL) { + struct libusb_device_descriptor desc; + int ret = libusb_get_device_descriptor(dev, &desc); + + if (ret < 0) { + WLOG("failed to get libusb device descriptor (libusb error: %d)\n", ret); + break; + } + + if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { continue; } + + struct libusb_device_handle* handle; + char serial[STLINK_SERIAL_BUFFER_SIZE] = {0, }; + + ret = libusb_open(dev, &handle); + + if (ret < 0) { + if (ret == LIBUSB_ERROR_ACCESS) { + ELOG("Could not open USB device %#06x:%#06x, access error.\n", desc.idVendor, desc.idProduct); + } else { + ELOG("Failed to open USB device %#06x:%#06x, libusb error: %d)\n", desc.idVendor, desc.idProduct, ret); + } + + break; + } + + size_t serial_len = stlink_serial(handle, &desc, serial); + + libusb_close(handle); + + if (serial_len != STLINK_SERIAL_LENGTH) { continue; } + + stlink_t *sl = stlink_open_usb(0, connect, serial, freq); + + if (!sl) { + ELOG("Failed to open USB device %#06x:%#06x\n", desc.idVendor, desc.idProduct); + continue; + } + + _sldevs[slcur++] = sl; + } + + *sldevs = _sldevs; + + return(slcur); +} + +size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int freq) { + libusb_device **devs; + stlink_t **sldevs; + + size_t slcnt = 0; + int r; + ssize_t cnt; + + r = libusb_init(NULL); + + if (r < 0) { return(0); } + + cnt = libusb_get_device_list(NULL, &devs); + + if (cnt < 0) { return(0); } + + slcnt = stlink_probe_usb_devs(devs, &sldevs, connect, freq); + libusb_free_device_list(devs, 1); + + libusb_exit(NULL); + + *stdevs = sldevs; + + return(slcnt); +} + +void stlink_probe_usb_free(stlink_t ***stdevs, size_t size) { + if (stdevs == NULL || *stdevs == NULL || size == 0) { return; } + + for (size_t n = 0; n < size; n++) { stlink_close((*stdevs)[n]); } + + free(*stdevs); + *stdevs = NULL; +} diff --git a/src/win32/unistd/unistd.h b/src/win32/unistd/unistd.h index 389c44664..cb6da4b8a 100644 --- a/src/win32/unistd/unistd.h +++ b/src/win32/unistd/unistd.h @@ -52,7 +52,7 @@ #define ssize_t int #ifndef SSIZE_MAX -#define SSIZE_MAX ((sizeof(ssize_t) == 4) ? 2147483647 : 9223372036854775807) +#define SSIZE_MAX ((sizeof(ssize_t) == 4) ? 1073741824 : ‭4611686018427387904‬) #endif #define STDIN_FILENO 0 diff --git a/src/win32/unistd/unistd.h.bak b/src/win32/unistd/unistd.h.bak new file mode 100644 index 000000000..47967e45e --- /dev/null +++ b/src/win32/unistd/unistd.h.bak @@ -0,0 +1,76 @@ +#ifndef _UNISTD_H +#define _UNISTD_H 1 + +/* + * This file intended to serve as a drop-in replacement for unistd.h on Windows + * Please add functionality as needed. + */ + +#include +#include + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4820) +#endif + +#include + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#include // getopt at: https://gist.github.com/ashelly/7776712 +#include // for getpid() and the exec..() family +#include // for _getcwd() and _chdir() + +#define srandom srand +#define random rand + +/* Values for the second argument to access. These may be OR'd together. */ +#define R_OK 4 // Test for read permission +#define W_OK 2 // Test for write permission +// #define X_OK 1 // execute permission - unsupported in windows +#define F_OK 0 // Test for existence + +#define access _access +#define dup2 _dup2 +#define execve _execve +#define ftruncate _chsize +#define unlink _unlink +#define fileno _fileno +#define getcwd _getcwd +#define chdir _chdir +#define isatty _isatty +#define lseek _lseek + +/* + * Read, write, and close are NOT being defined here, + * because while there are file handle specific versions for Windows, they probably don't work for sockets. + * You need to look at your app and consider whether to call e.g. closesocket(). + */ + +#define ssize_t int +#ifndef SSIZE_MAX +//#define SSIZE_MAX ((sizeof(ssize_t) == 4) ? 2147483647 : 9223372036854775807) +#define SSIZE_MAX ((sizeof(ssize_t) == 4) ? 1073741824 : ‭4611686018427387904‬) +#endif + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +// should be in some equivalent to +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; + +#ifndef STLINK_HAVE_UNISTD_H +int usleep(unsigned int waitTime); +#endif + +#endif // _UNISTD_H diff --git "a/src/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265.txt" "b/src/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265.txt" new file mode 100644 index 000000000..d4111a8b2 --- /dev/null +++ "b/src/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265.txt" @@ -0,0 +1,129 @@ +--------------------------------------------------------------------------------- +Файл info.c: + +main: +- проверяю количество параметров +- инициализирую список структур devicelist, объявленный в файле chipid.c +- вызываю функцию print_data (и передаю ей параметры программы). + +print_data: +Смотрю, какие параметры переданы программе. +Если параметр --probe - вызываю функцию stlink_probe с параметрами по умолчанию +(connect: NORMAL, freq: 0) + +stlink_probe: +Объявляю список структур для каждого подключенного ST-LINK'a +(stdevs: указатель на список указателей, указывающих на структуры). +Вызываю stlink_probe_usb с параметрами: +- адрес stdevs'а (тройной указатель), +- connect, +- freq + +Функция stlink_probe_usb заполняет stdevs и возвращает его размер. +Для каждого указателя вызываю функцию stlink_print_info. + +Потом освобождаю память, отведённую под stdevs. + +stlink_print_info: просто печатаю в терминал информацию из переданной структуры +ST-LINK'а. + +--------------------------------------------------------------------------------- +Файл usb.c: + +stlink_probe_usb: +Инициализирую libusb +Получаю список USB-устройств (libusb_get_device_list). +Для полученного списка вызываю функцию stlink_probe_usb_devs. +Передаю ей: +- указатель на список указателей на структуры libusb_device (двойной указатель) devs +- адрес указателя на список указателей на структуры ST-LINK (тройной указатель) sldevs +- connect, freq. +Потом освобождаю память, занятую структурами libusb_device. +Список указателей на структуры ST-LINK возвращаю на выход (в функцию stlink_probe). + +stlink_probe_usb_devs: +Определяю количество подключенных ST-LINK'ов: +Прохожу по списку USB-устройств. +Для каждого USB-устройства получаю дескриптор desc. +Если в дескрипторе указаны idVendor и idProduct, соответствующие ST-LINK'у - увеличиваю счётчик. +Выделяю память под нужное количество структур ST-LINK'ов. + +Ещё раз прохожу по списку USB-устройств и получаю дескриптор каждого. +Если idProduct соответствует ST-LINK'у: +- открываю ST-LINK (libusb_open), +- читаю его серийник (stlink_serial); +- закрываю (libusb_close). + +Если длина серийника правильная - открываю его функцией stlink_open_usb. +Она возвращает ссылку на структуру stlink_t. Пристёгиваю эту ссылку к списку структур. +Перехожу к следюущему USB-устройству. Потом записываю ссылку на список структур stlink_t +в указатель и возвращаю количество структур по списку. + +stlink_serial: +Получаю дескриптор нулевой строки USB-устройства, беру из него LANGID (libusb_get_string_descriptor). +Получаю дескриптор строки серийника (для него нужен LANGID) (libusb_get_string_descriptor). +Если серийник длиной 50 символов - беру его же в формате ascii. +Если серийник длиной 26 символов - для каждого символа выполняю строку: +sprintf(serial + i, "%02X", desc_serial[i + 2]) +В конце ставлю ноль. +Возвращаю длину серийника и сам серийник, записанный в память по адресу из параметра. + +stlink_open_usb: +Выделяю в куче память под структуры sl (stlink_t) и slu (stlink_libusb). +Записываю в sl ссылку на список каких-то функций и ссылку на slu, указываю статус ядра +целевого MCU: TARGET_UNKNOWN. +Инициализирую libusb с контекстом, указываю LOG_LEVEL. +Получаю список USB-устройств. +Для каждого устройства получаю дескриптор и проверяю его idVendor. +Открываю устройство и пытаюсь получить серийник. +Если не получил серийник либо получил серийник, соответствующий заданному в параметре - +- выставляю в структуре sl версию и протокол по idProduct, после чего заканчиваю просмотр +устройств USB. + +Просмотрев все устройства, открываю найденный ST-LINK и освобождаю память, занятую +списком USB-устройств. + +Читаю конфигурацию ST-LINK'а, потом устанавливаю её. Делаю заявку на интерфейс (libusb_claim_interface). +Потом выставляю поля ep_rep, ep_req, ep_trace, sg_transfer_idx и cmd_len. +Инициализирую версию ST-LINK'а (stlink_version). +Получаю режим работы ST-LINK'а. Если он в режиме dfu - выхожу из него. +Если CONNECT_UNDER_RESET: выхожу из debug mode, если в нём. Выполняю JTAG reset. +Выставляю поле freq по параметру функции, устанавливаю SWD clock (_stlink_usb_set_swdclk). +Выполняю stlink_target_connect и возвращаю структуру sl. + +_stlink_usb_version: +Заполняю структуру stlink командой fill_command (по-разному для ST-LINK v. 3 и предыдущих версий) +Выполняю функцию send_recv + + +_stlink_usb_current_mode: +Заполняю структуру stlink командой fill_command, ставлю в i-тую позицию команду STLINK_GET_CURRENT_MODE +Вызываю функцию send_recv +Возвращаю первый символ буфера, или -1 при ошибке. + +_stlink_usb_exit_debug_mode, _stlink_usb_exit_debug_mode: +Заполняю структуру stlink командой fill_command, ставлю в i-тую позицию команды: +STLINK_DFU_COMMAND +STLINK_DFU_EXIT +Вызываю функцию send_only +Возвращаю 0, или -1 при ошибке. +То же самое для debug + +fill_command: +Для ST-LINK v. 1 заполняю поле c_buf структуры stlink. Для всех остальных заполняю его нулями. + +send_recv: +Отправляю функцией libusb_bulk_transfer данные в параметре txbuf и команду в cmd. +Проверяю ответ на ошибки и если указан rxsize - принимаю данные той же функцией. +Возвращаю количество принятого после проверки на ошибки. + +--------------------------------------------------------------------------------- +Файл common.c: + +stlink_version: +Запускаю функцию version из backend (вызывается _stlink_usb_version из usb.c) +Выполняю _parse_version. + +stlink_current_mode: +возвращаю результат выполнения функции sl->backend->current_mode(sl) после проверки на ошибки. +При этом запускается функция _stlink_usb_current_mode. \ No newline at end of file diff --git a/stlinkv1_macos_driver/install.sh b/stlinkv1_macos_driver/install.sh index f9878bd46..5716281a1 100644 --- a/stlinkv1_macos_driver/install.sh +++ b/stlinkv1_macos_driver/install.sh @@ -2,6 +2,9 @@ ISMACOS=$(sw_vers -productVersion) case $ISMACOS in +10.14*) + KEXT="stlink_shield_10_14.kext" + ;; 10.15*) KEXT="stlink_shield_10_15.kext" ;; diff --git a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist new file mode 100644 index 000000000..fd424ea93 --- /dev/null +++ b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist @@ -0,0 +1,82 @@ + + + + + BuildMachineOSBuild + 18G7016 + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.libusb.stlink-shield + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + KEXT + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1.0.0 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 11C504 + DTPlatformVersion + GM + DTSDKBuild + 19B90 + DTSDKName + macosx10.15 + DTXcode + 1130 + DTXcodeBuild + 11C504 + IOKitPersonalities + + DeviceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBDevice + bcdDevice + 256 + idProduct + 14148 + idVendor + 1155 + + InterfaceDriver + + CFBundleIdentifier + com.apple.kpi.iokit + IOClass + IOService + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 14148 + idVendor + 1155 + + + LSMinimumSystemVersion + 10.14 + OSBundleLibraries + + com.apple.iokit.IOUSBFamily + 1.8 + com.apple.kpi.libkern + 11.2.0 + + + diff --git a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 new file mode 100644 index 0000000000000000000000000000000000000000..6a32aa4615953f6afe16047f73da9a3bced9b3a3 GIT binary patch literal 33840 zcmeHOdwf$>p1)}uC}>G^QR*WS>I=j+ty12BhPH46DO6ez1iYqA3Yj)ZNp7Gx=tfJ` zYp8Tb@dY}d4$kQ4>aHsfUv;V!Mn}FxJ?&-tC-@0{;B_mTT}_t-ZldkcagQxJr+uw`Qtvjm|fYCuj9F2HsdvXWF?KC7A) zb^mAWP6f`5D5edrSdt{!+az-WNcUGrfss1TQIWXTmX%})QME?>FG;n*Ksf0z-Jfuw zYA0%qz`Oa=$~nScSPuCD^Ao)Lct!3nn4ubITyw*VHHz_h7f5v>x8JK4rT1^c#oP}G zk3^hj)q=GDG!GxMc_?#KJ5nmGJa6Wh#>ppbG#8X4X?`%N8u6a}Y3^t~f2m)Ril00tNoyxoS&x-bx-c~^%o~}KwVnFM}?+*sF zvh?vDKzmAsDzN{l{WGMLQ&y5{!r_#%bbr=CYGq}L%`f?*d8IWfNiOHqDdlBOZ6DJ* zbQ5>Pc_FW-ex>$}G|0tfgt59afrX>q9#Lc78r^#BWj=BQ60{@p4m?0{EbzJY5 z>6qcDt`eK~=Q@-RoyrlXazbpqxur$GP?^8J_kJ&SOZngh>W^P*c3>+$*d*6n2%>E%tMP(-+mGL8T-D&&) zKndCRlG%57HfnzoIYVT~Yjg(Fnm&Ot*soze8onJG2?;rP#(*zP)@KZ zD;5&oTZ_NI!5pf)l!KU}3T2O|yv~)}Z2TP24CwSOASGnK)Uq+lSICOD9T$X?@kmxt zyz5HwwvKo_6J=jh8JzNdb&87dcVw(s)&bbiSyj}23%DUNUW{4pBZJn`EOCtSHe?qK zg||%7h;Xj3Iosun% z$+-Y*(KU$EyIY)Nq*gLc7o(Q_Ohe;0401jMIAQ~o{#b{WPpC`{^A56QN@QEq{y1{U zP|t$(5NZXrOooawYPpRdX1tw2PCXztV;hBPHu^!b#O610=Q!p%<~eS3Nb@?Flx&`} z`%}YQSFHFF*s1Eb7EkC$L1>1PbKCV2+uvu>o^BSK?LVQVU|N>fiyT<8(K>4XlFH<% zd{Xvj>d=X^d3YIrMjC}0uT(PwZ6La2bu-lHJ zX01FzHE%u|mv6%ONB0f0^mUVh0Kx&4&$TnR2dKRC0!pJH?U*=*+^=Kv;_&_NPL168lg^`F^^B zjoP=P7s+|t4c5avc2ZZ93T$B1vXLNW+{7T~aX@Uwes#&LqcSzxDr6B2!4S<4l8n{_ z)%Wh657OMp2m>tpM3XH2NKrjCK}S57GA1MNcx? z4n{3I31Y_28RTpMB%-}VWooo`WTSSvY)USVC%}3L(?YG1VHPoJSxgW!HZjO?13I(l zi267VShZBB#+gMG+9BjBkmRU}!FmXHJ~d8;>&>Von;>TF!yxA%&KrDG&Bh-ou4ETgbdY|UPBX2=j%>OV(@gfEvw~@08LFD?55fW`nVA>?Kl?=O zOUWU-0JxX6FU5)37)6#{0CYbwyU8Ni>FJDGst97nG6p#n1h@jAxMHk$9MR^@I5iYs z%M9!n1EO{#{u?3##aK=ja+^p~^>i7tAIFGTzAFp|7OKX|P>bk#au};*=i3L*rXX~_ zeO7A(1)jmr@bvR7t~(!RN)^*}r5dW!xEy&(xUPC$%f{>>%_3&M9s&0L8!q+GevVcQ z>nWObr%~itnh;oB4$4H=&hM?p3>2Z4V#{`Uu&cFr45(?K;2L$Ue3lrSV@7%8U{}AQ z_BhU=VBas;l7SS#-=98z;8Je|GZWOj`j zFAtz!5X$EiWq;R%q=j?LIC-FR%&pmSUPa3;+2~Z}US?K>QLSI?>hDx8A&bb)3Z*U^ zR*_G;cF=_nyX;B2V(W|gS5+yt8Z*^Nq2XSTv}x-$zJpkw*>mP~q||pG->bO2(tUhc z{{Z82%&c-Mhe`A)qH_E-x^&@+&B_)#OK6#57tEQB&WlPma=j_ndL8CEViAvVdik8E&m~`e+8dIH}opAP4-!pI)wSNUOK{m1#wAuIpm_cl{ zKXNi2SNqy(fBvUreg^Vn%GPXKO48<|s?w>P6k8>OD`qdmCE4AXV{MVMy3As{gR*k( zW$lsgyUuIdoGCa=>qoehBP`73Ok3AyY?js4(#HI;>s_mIysoo+H}-<-+f75tw=sLA z{0kKB$`oAqrE3~kBH)K8q6xTa=0AsM-@lmIHjm7bzfcFGyuKlh)I6#}&R|D9D;u}A zznnH+#{X_S{C+3B4m*`NG%v@2gLkt7bb>~mow&@$C2=R+FT_vF?efr~tQ@B zG~w4MYgM$hrQPJ*;!sec{*-eny}B}rwu{QgDax7#M#+sfU$}eVRNi$eABf8Ln7Q(n z_FEk|O&N-|CU-W{*Yu(}ddw#0E_+`dB*xpzM!mjtf7gJdP5gBcHwV;;|HQ1aI|;{F z$4aA1$Hr}PcIoD!H|MX@IeImPj5f+Hh#FPsdMe9H9RWD0+Wy-@juS z9y%D0&)O#)jmMLr+3{rGTbS2mSsR*fLi?;4;eRFb zAOA7c*O~awfq#+|2edpopTyWLfXsREFN)gdb?_SV&ubEWDj9s~kjm-PCQWx#j1J2U zzCgVcUf}aKc%-62sc4whipt65rPbXl^J(YpmO?{ogvHnzL%}*9+{_CQ^QHY4l}g>8%c`4MDnW!`YT9Bj1t-L=!Ito3*}X6vqhQ*F@Wwbev? z4W8~b1!`HDw
      bdyP70ynY%}ESw(*hWzdZThqwl((qwD*-MMiuY&ot9=CASHHE|e zfjjC8)CJX!3i$2KlHum*f}zQ5FrVE!yA9W8SEH03t$M>Ccj{mge{l;-rR zXzsndSF7=!tQD;0GE};-H`You#IO4GRC(xlyL z6#xFPYFEmP@K5u{?Wmt`VB5y+{w3XRQgg56iC(Jle}GNN5!G*Ty8VP^HXb&9^lcWm zI}^Vy*l*$XyVCvg{+>#2(uMSH!l8@OwDk59o7pJHt_<56Zs$+8OVPOjb$idi?mpNR z;*d;fNxDBCm-KiU+g;r5(R8~soliAR8Y69Aa6f}m{7{za#$r3b>$T^tR7Z*G=VH^^ z<0eYCbh@}(P80Xz)5O)?pevv&pevv&pevv&pevv&pevv&pevv& z@c&f-vz7g(@0H7O7st;ydhmn)5^UQ0`8RWJJzHSuH=MWOMF>jkIM;5_y~H`an?vby z&I|GG5KFiTPX4!XZsxolFI`b8NbO5FzmRj0^Gi9esgN8t4YCX9Em6&WPD|7PkP6)v+969l{tE|}2g68=2}-4i3O zeXnsVariTHe{J9hcM`zTL-?P{A4}uUr1Aeq<1eN0jx_$~H2!`X|1^z%oyPa2@dIi6 zNE)Y`SgGUb4U)=9>r_4|S+00eBUb z;u<_D8Y~F;nZO~yE<7hDoP!&Ygx6!gC3JJ_fXuHNX=b=}ko9_v5%k zxE}tl1$F?30k45wF)$nb7!Dl3aVX-C0AIzi32S*IxPo?sE$9c~Uic-X7fuO3$`yoB zKm(35gvU{ieI@@Jv>OAw4)Jh*IsXx$9r!x@jsyO{@haF6{}lem11CUd!e=;!F>c}! zyw*YZHOK4l;tKJXInrxE#2@6?%dB#l<5wIj&r!?QbEH@4sNHssYtgR~@ImO014yr1 z5Qfoz!T{;-km>?bgAX5kN%iUnM|D9#YM`f$ zWxh}ao|FkvxBJlQqp+EHvgHc~rbhfV-q0^uRH@&7NsB{1*&B@DV~>;YC6u5AuzI{g2Yu*hZ9_1Oj?~o#}?=p7Fm$ydu4B65yM8GN09L7t|5res{CGmZQ~MPy~l?>`2B8#_tUdSKqSDZ z8ZPAJP4GRNCju)V?>TaK;0fIt7WpBu$BjC72!r)CphGF85%>=+!Dn4e<%G32;7PSj ziiP%J?!e=1zz|Y|#8+W5=77&03&L%fF6^_hbOSd1^idh9&6=psmAz8PTN}ZgF7j$h zur=Tc*49siT8zvHK(Qp9c@!2`8&)EA>S9bapr*4reJK-FfT!m8*bPt3z32jrL*9Ta(Hi0ti#>{ZT%aymDdeWLiNLCR z+VPN%?L503U+C2%t3ATP;ZDfFSqO(oDl_2lgM)xzI7TNX*w&&A>V=<#3=|m1R-n^x zAvW@XONP)%MN4 zvoO@_{`3FxcG005{qm*R{-)89!`qE5L;By-f5)wBUkI&ke{^g3g@1pb!TG1lZ(0BH z_d7P#4_bZcO2_U)V};IVb;N8b}nfv}ayujY;jokN} z%Kmxsqbshyev4Rh?xY13H%?l8NyT?35AS@o-?-HqXDiRW6AQ1AuW9<7so>+kV(=sb z8{Dy-3l}2)%GmKu{st>OR>#7(=iymbp4A(`^L)G)Vb7aUJu!b|-uQ8S#||o+R$4u~ zvfSE8hc;{Fj0rAhsWmU(W}^k_wb{z5%dC|yXH~ToK5Vw~sd?7C1+v^Y+Gbn4cyWQ7 ztO_6}8HR0@Ashih@)8%E<)cA?NA~0)jOx8xcTno_)yg)Yja859tIndqmokg{Fqm$$ zXw5i-S^Q?r*Ump=zW?jTUwH49?P1TCBVNA!H;@+`i zx9!V|hQGDJ|JEP3T>0)Be>eJqSk*4Lw$!ngQKJ{18 z*E%nJJpae{N30uAdi0KsMOPG^xZSZ!dMwa?&bo==CmRjtm(QqpuJ8I6+h2aY>GkN)Ri8Y(zj5ZJ9Y_AO+kfc7Ref*2 zbIRJevgxUH|N6+A`<~oTaNl)rKaly6!Le<}n_bs>X1~5+ + + + + files + + files2 + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj index 373600c64..4f2b80254 100644 --- a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXFileReference section */ 8CD33C31149BB80D0033D618 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = stlink_shield_10_14.kext; sourceTree = BUILT_PRODUCTS_DIR; }; 8F90850924786F39009109AD /* stlink_shield_10_15.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = stlink_shield_10_15.kext; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -33,6 +34,7 @@ 19C28FB6FE9D52B211CA2CBB /* Products */ = { isa = PBXGroup; children = ( + 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */, 8F90850924786F39009109AD /* stlink_shield_10_15.kext */, ); name = Products; @@ -58,6 +60,26 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 8F9084F324786F0F009109AD /* stlink_shield_10_14 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8F9084FA24786F0F009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_14" */; + buildPhases = ( + 8F9084F424786F0F009109AD /* ShellScript */, + 8F9084F524786F0F009109AD /* Headers */, + 8F9084F624786F0F009109AD /* Resources */, + 8F9084F824786F0F009109AD /* Sources */, + 8F9084F924786F0F009109AD /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = stlink_shield_10_14; + productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; + productName = NanosMouse; + productReference = 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */; + productType = "com.apple.product-type.kernel-extension.iokit"; + }; 8F9084FF24786F39009109AD /* stlink_shield_10_15 */ = { isa = PBXNativeTarget; buildConfigurationList = 8F90850624786F39009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_15" */; @@ -98,6 +120,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( + 8F9084F324786F0F009109AD /* stlink_shield_10_14 */, 8F9084FF24786F39009109AD /* stlink_shield_10_15 */, ); }; @@ -435,6 +458,24 @@ }; name = Release; }; + 8F9084FB24786F0F009109AD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + MACOSX_DEPLOYMENT_TARGET = 10.14; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 8F9084FC24786F0F009109AD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + MACOSX_DEPLOYMENT_TARGET = 10.14; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; 8F90850724786F39009109AD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -465,6 +506,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 8F9084FA24786F0F009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_14" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8F9084FB24786F0F009109AD /* Debug */, + 8F9084FC24786F0F009109AD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 8F90850624786F39009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_15" */ = { isa = XCConfigurationList; buildConfigurations = ( From 5b320357a64458d102e190e4aeff2d58a3011e60 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 29 Jan 2022 17:56:26 +0100 Subject: [PATCH 1299/1435] Minor formatting fixes & clean-up --- CMakeLists.txt | 6 +- src/calculate.h | 2 +- src/common.h | 2 +- src/common_flash.h | 2 +- src/map_file.h | 2 +- src/{option.c => option_bytes.c} | 0 ...1\201\320\260\320\275\320\270\320\265.txt" | 129 ------------------ 7 files changed, 7 insertions(+), 136 deletions(-) rename src/{option.c => option_bytes.c} (100%) delete mode 100644 "src/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265.txt" diff --git a/CMakeLists.txt b/CMakeLists.txt index a3338df71..abfc0be47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # General cmake settings ### -cmake_minimum_required(VERSION 3.7.2) +cmake_minimum_required(VERSION 3.10.2) cmake_policy(SET CMP0042 NEW) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) @@ -127,8 +127,8 @@ set(STLINK_HEADERS set(STLINK_SOURCE src/read_write.c src/common.c - src/option.c - src/common_flash.c + src/option_bytes.c + src/common_flash.c src/map_file.c src/flashloader.c src/calculate.c diff --git a/src/calculate.h b/src/calculate.h index 68c1fb988..64dfb51b2 100644 --- a/src/calculate.h +++ b/src/calculate.h @@ -1,7 +1,7 @@ /* * File: calculate.h * - * TODO: add a description + * Calculation of sector numbers and pages */ #ifndef CALCULATE_H diff --git a/src/common.h b/src/common.h index 6c22d58c0..dd6cf95b2 100644 --- a/src/common.h +++ b/src/common.h @@ -1,7 +1,7 @@ /* * File: common.h * - * TODO: add a description + * General helper functions */ #ifndef COMMON_H diff --git a/src/common_flash.h b/src/common_flash.h index 70a6f0e04..3b6b0404a 100644 --- a/src/common_flash.h +++ b/src/common_flash.h @@ -1,7 +1,7 @@ /* * File: common_flash.h * - * TODO: add a description + * Flash operations */ #ifndef COMMON_FLASH_H diff --git a/src/map_file.h b/src/map_file.h index 9cdd745e6..f50a201f0 100644 --- a/src/map_file.h +++ b/src/map_file.h @@ -1,7 +1,7 @@ /* * File: map_file.h * - * TODO: add a description + * File mapping */ #ifndef MAP_FILE_H diff --git a/src/option.c b/src/option_bytes.c similarity index 100% rename from src/option.c rename to src/option_bytes.c diff --git "a/src/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265.txt" "b/src/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265.txt" deleted file mode 100644 index d4111a8b2..000000000 --- "a/src/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265.txt" +++ /dev/null @@ -1,129 +0,0 @@ ---------------------------------------------------------------------------------- -Файл info.c: - -main: -- проверяю количество параметров -- инициализирую список структур devicelist, объявленный в файле chipid.c -- вызываю функцию print_data (и передаю ей параметры программы). - -print_data: -Смотрю, какие параметры переданы программе. -Если параметр --probe - вызываю функцию stlink_probe с параметрами по умолчанию -(connect: NORMAL, freq: 0) - -stlink_probe: -Объявляю список структур для каждого подключенного ST-LINK'a -(stdevs: указатель на список указателей, указывающих на структуры). -Вызываю stlink_probe_usb с параметрами: -- адрес stdevs'а (тройной указатель), -- connect, -- freq - -Функция stlink_probe_usb заполняет stdevs и возвращает его размер. -Для каждого указателя вызываю функцию stlink_print_info. - -Потом освобождаю память, отведённую под stdevs. - -stlink_print_info: просто печатаю в терминал информацию из переданной структуры -ST-LINK'а. - ---------------------------------------------------------------------------------- -Файл usb.c: - -stlink_probe_usb: -Инициализирую libusb -Получаю список USB-устройств (libusb_get_device_list). -Для полученного списка вызываю функцию stlink_probe_usb_devs. -Передаю ей: -- указатель на список указателей на структуры libusb_device (двойной указатель) devs -- адрес указателя на список указателей на структуры ST-LINK (тройной указатель) sldevs -- connect, freq. -Потом освобождаю память, занятую структурами libusb_device. -Список указателей на структуры ST-LINK возвращаю на выход (в функцию stlink_probe). - -stlink_probe_usb_devs: -Определяю количество подключенных ST-LINK'ов: -Прохожу по списку USB-устройств. -Для каждого USB-устройства получаю дескриптор desc. -Если в дескрипторе указаны idVendor и idProduct, соответствующие ST-LINK'у - увеличиваю счётчик. -Выделяю память под нужное количество структур ST-LINK'ов. - -Ещё раз прохожу по списку USB-устройств и получаю дескриптор каждого. -Если idProduct соответствует ST-LINK'у: -- открываю ST-LINK (libusb_open), -- читаю его серийник (stlink_serial); -- закрываю (libusb_close). - -Если длина серийника правильная - открываю его функцией stlink_open_usb. -Она возвращает ссылку на структуру stlink_t. Пристёгиваю эту ссылку к списку структур. -Перехожу к следюущему USB-устройству. Потом записываю ссылку на список структур stlink_t -в указатель и возвращаю количество структур по списку. - -stlink_serial: -Получаю дескриптор нулевой строки USB-устройства, беру из него LANGID (libusb_get_string_descriptor). -Получаю дескриптор строки серийника (для него нужен LANGID) (libusb_get_string_descriptor). -Если серийник длиной 50 символов - беру его же в формате ascii. -Если серийник длиной 26 символов - для каждого символа выполняю строку: -sprintf(serial + i, "%02X", desc_serial[i + 2]) -В конце ставлю ноль. -Возвращаю длину серийника и сам серийник, записанный в память по адресу из параметра. - -stlink_open_usb: -Выделяю в куче память под структуры sl (stlink_t) и slu (stlink_libusb). -Записываю в sl ссылку на список каких-то функций и ссылку на slu, указываю статус ядра -целевого MCU: TARGET_UNKNOWN. -Инициализирую libusb с контекстом, указываю LOG_LEVEL. -Получаю список USB-устройств. -Для каждого устройства получаю дескриптор и проверяю его idVendor. -Открываю устройство и пытаюсь получить серийник. -Если не получил серийник либо получил серийник, соответствующий заданному в параметре - -- выставляю в структуре sl версию и протокол по idProduct, после чего заканчиваю просмотр -устройств USB. - -Просмотрев все устройства, открываю найденный ST-LINK и освобождаю память, занятую -списком USB-устройств. - -Читаю конфигурацию ST-LINK'а, потом устанавливаю её. Делаю заявку на интерфейс (libusb_claim_interface). -Потом выставляю поля ep_rep, ep_req, ep_trace, sg_transfer_idx и cmd_len. -Инициализирую версию ST-LINK'а (stlink_version). -Получаю режим работы ST-LINK'а. Если он в режиме dfu - выхожу из него. -Если CONNECT_UNDER_RESET: выхожу из debug mode, если в нём. Выполняю JTAG reset. -Выставляю поле freq по параметру функции, устанавливаю SWD clock (_stlink_usb_set_swdclk). -Выполняю stlink_target_connect и возвращаю структуру sl. - -_stlink_usb_version: -Заполняю структуру stlink командой fill_command (по-разному для ST-LINK v. 3 и предыдущих версий) -Выполняю функцию send_recv - - -_stlink_usb_current_mode: -Заполняю структуру stlink командой fill_command, ставлю в i-тую позицию команду STLINK_GET_CURRENT_MODE -Вызываю функцию send_recv -Возвращаю первый символ буфера, или -1 при ошибке. - -_stlink_usb_exit_debug_mode, _stlink_usb_exit_debug_mode: -Заполняю структуру stlink командой fill_command, ставлю в i-тую позицию команды: -STLINK_DFU_COMMAND -STLINK_DFU_EXIT -Вызываю функцию send_only -Возвращаю 0, или -1 при ошибке. -То же самое для debug - -fill_command: -Для ST-LINK v. 1 заполняю поле c_buf структуры stlink. Для всех остальных заполняю его нулями. - -send_recv: -Отправляю функцией libusb_bulk_transfer данные в параметре txbuf и команду в cmd. -Проверяю ответ на ошибки и если указан rxsize - принимаю данные той же функцией. -Возвращаю количество принятого после проверки на ошибки. - ---------------------------------------------------------------------------------- -Файл common.c: - -stlink_version: -Запускаю функцию version из backend (вызывается _stlink_usb_version из usb.c) -Выполняю _parse_version. - -stlink_current_mode: -возвращаю результат выполнения функции sl->backend->current_mode(sl) после проверки на ошибки. -При этом запускается функция _stlink_usb_current_mode. \ No newline at end of file From d98d3a50edbbf984b1fe842908e1420d26c3ff0f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 29 Jan 2022 17:56:26 +0100 Subject: [PATCH 1300/1435] Minor formatting fixes & clean-up --- CMakeLists.txt | 6 +++--- src/calculate.h | 2 +- src/common.h | 2 +- src/common_flash.h | 2 +- src/map_file.h | 2 +- src/{option.c => option_bytes.c} | 0 6 files changed, 7 insertions(+), 7 deletions(-) rename src/{option.c => option_bytes.c} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index a3338df71..abfc0be47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # General cmake settings ### -cmake_minimum_required(VERSION 3.7.2) +cmake_minimum_required(VERSION 3.10.2) cmake_policy(SET CMP0042 NEW) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) @@ -127,8 +127,8 @@ set(STLINK_HEADERS set(STLINK_SOURCE src/read_write.c src/common.c - src/option.c - src/common_flash.c + src/option_bytes.c + src/common_flash.c src/map_file.c src/flashloader.c src/calculate.c diff --git a/src/calculate.h b/src/calculate.h index 68c1fb988..64dfb51b2 100644 --- a/src/calculate.h +++ b/src/calculate.h @@ -1,7 +1,7 @@ /* * File: calculate.h * - * TODO: add a description + * Calculation of sector numbers and pages */ #ifndef CALCULATE_H diff --git a/src/common.h b/src/common.h index 6c22d58c0..dd6cf95b2 100644 --- a/src/common.h +++ b/src/common.h @@ -1,7 +1,7 @@ /* * File: common.h * - * TODO: add a description + * General helper functions */ #ifndef COMMON_H diff --git a/src/common_flash.h b/src/common_flash.h index 70a6f0e04..3b6b0404a 100644 --- a/src/common_flash.h +++ b/src/common_flash.h @@ -1,7 +1,7 @@ /* * File: common_flash.h * - * TODO: add a description + * Flash operations */ #ifndef COMMON_FLASH_H diff --git a/src/map_file.h b/src/map_file.h index b35f24ad0..08cf98b6c 100644 --- a/src/map_file.h +++ b/src/map_file.h @@ -1,7 +1,7 @@ /* * File: map_file.h * - * TODO: add a description + * File mapping */ #ifndef MAP_FILE_H diff --git a/src/option.c b/src/option_bytes.c similarity index 100% rename from src/option.c rename to src/option_bytes.c From e2dcf074d51aaf2ec2a77617475a8a5e8ffebd6f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 29 Jan 2022 19:33:19 +0100 Subject: [PATCH 1301/1435] Fixed defines (CHIPID + COREID) & duplicates --- inc/stm32.h | 374 --------------------------------------------- inc/stm32flash.h | 4 +- src/calculate.c | 6 +- src/common.c | 46 +++--- src/common_flash.c | 368 ++++++++++++++++++++++---------------------- src/flashloader.c | 104 ++++++------- src/option_bytes.c | 54 +++---- 7 files changed, 291 insertions(+), 665 deletions(-) diff --git a/inc/stm32.h b/inc/stm32.h index 08cd3cd2a..d764e2f97 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -155,340 +155,6 @@ enum stm32_chipids { #define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) #define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) -/* stm32f FPEC flash controller interface, pm0063 manual */ -// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, August 2012) -#define FLASH_REGS_ADDR 0x40022000 -#define FLASH_REGS_SIZE 0x28 - -#define FLASH_ACR (FLASH_REGS_ADDR + 0x00) -#define FLASH_KEYR (FLASH_REGS_ADDR + 0x04) -#define FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x08) -#define FLASH_SR (FLASH_REGS_ADDR + 0x0c) -#define FLASH_CR (FLASH_REGS_ADDR + 0x10) -#define FLASH_AR (FLASH_REGS_ADDR + 0x14) -#define FLASH_OBR (FLASH_REGS_ADDR + 0x1c) -#define FLASH_WRPR (FLASH_REGS_ADDR + 0x20) - -// STM32F10x_XL has two flash memory banks with separate registers to control -// the second bank. -#define FLASH_KEYR2 (FLASH_REGS_ADDR + 0x44) -#define FLASH_SR2 (FLASH_REGS_ADDR + 0x4c) -#define FLASH_CR2 (FLASH_REGS_ADDR + 0x50) -#define FLASH_AR2 (FLASH_REGS_ADDR + 0x54) - -// For STM32F05x, the RDPTR_KEY may be wrong, but as it is not used anywhere... -#define FLASH_RDPTR_KEY 0x00a5 -#define FLASH_KEY1 0x45670123 -#define FLASH_KEY2 0xcdef89ab - -#define FLASH_L0_PRGKEY1 0x8c9daebf -#define FLASH_L0_PRGKEY2 0x13141516 - -#define FLASH_L0_PEKEY1 0x89abcdef -#define FLASH_L0_PEKEY2 0x02030405 - -#define FLASH_OPTKEY1 0x08192A3B -#define FLASH_OPTKEY2 0x4C5D6E7F - -#define FLASH_F0_OPTKEY1 0x45670123 -#define FLASH_F0_OPTKEY2 0xCDEF89AB - -#define FLASH_L0_OPTKEY1 0xFBEAD9C8 -#define FLASH_L0_OPTKEY2 0x24252627 - -#define FLASH_SR_BSY 0 -#define FLASH_SR_PG_ERR 2 -#define FLASH_SR_WRPRT_ERR 4 -#define FLASH_SR_EOP 5 - -#define FLASH_SR_ERROR_MASK ((1 << FLASH_SR_PG_ERR) | (1 << FLASH_SR_WRPRT_ERR)) - -#define FLASH_CR_PG 0 -#define FLASH_CR_PER 1 -#define FLASH_CR_MER 2 -#define FLASH_CR_OPTPG 4 -#define FLASH_CR_OPTER 5 -#define FLASH_CR_STRT 6 -#define FLASH_CR_LOCK 7 -#define FLASH_CR_OPTWRE 9 -#define FLASH_CR_OBL_LAUNCH 13 - -#define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00) -#define STM32L_FLASH_ACR (STM32L_FLASH_REGS_ADDR + 0x00) -#define STM32L_FLASH_PECR (STM32L_FLASH_REGS_ADDR + 0x04) -#define STM32L_FLASH_PDKEYR (STM32L_FLASH_REGS_ADDR + 0x08) -#define STM32L_FLASH_PEKEYR (STM32L_FLASH_REGS_ADDR + 0x0c) -#define STM32L_FLASH_PRGKEYR (STM32L_FLASH_REGS_ADDR + 0x10) -#define STM32L_FLASH_OPTKEYR (STM32L_FLASH_REGS_ADDR + 0x14) -#define STM32L_FLASH_SR (STM32L_FLASH_REGS_ADDR + 0x18) -#define STM32L_FLASH_OBR (STM32L_FLASH_REGS_ADDR + 0x1c) -#define STM32L_FLASH_WRPR (STM32L_FLASH_REGS_ADDR + 0x20) -#define FLASH_L1_FPRG 10 -#define FLASH_L1_PROG 3 - -// Flash registers common to STM32G0 and STM32G4 series. -#define STM32Gx_FLASH_REGS_ADDR ((uint32_t)0x40022000) -#define STM32Gx_FLASH_ACR (STM32Gx_FLASH_REGS_ADDR + 0x00) -#define STM32Gx_FLASH_KEYR (STM32Gx_FLASH_REGS_ADDR + 0x08) -#define STM32Gx_FLASH_OPTKEYR (STM32Gx_FLASH_REGS_ADDR + 0x0c) -#define STM32Gx_FLASH_SR (STM32Gx_FLASH_REGS_ADDR + 0x10) -#define STM32Gx_FLASH_CR (STM32Gx_FLASH_REGS_ADDR + 0x14) -#define STM32Gx_FLASH_ECCR (STM32Gx_FLASH_REGS_ADDR + 0x18) -#define STM32Gx_FLASH_OPTR (STM32Gx_FLASH_REGS_ADDR + 0x20) - -// G0 (RM0444 Table 1, sec 3.7) -// Mostly the same as G4 chips, but the notation -// varies a bit after the 'OPTR' register. -#define STM32G0_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) -#define STM32G0_FLASH_PCROP1ASR (STM32G0_FLASH_REGS_ADDR + 0x24) -#define STM32G0_FLASH_PCROP1AER (STM32G0_FLASH_REGS_ADDR + 0x28) -#define STM32G0_FLASH_WRP1AR (STM32G0_FLASH_REGS_ADDR + 0x2C) -#define STM32G0_FLASH_WRP1BR (STM32G0_FLASH_REGS_ADDR + 0x30) -#define STM32G0_FLASH_PCROP1BSR (STM32G0_FLASH_REGS_ADDR + 0x34) -#define STM32G0_FLASH_PCROP1BER (STM32G0_FLASH_REGS_ADDR + 0x38) -#define STM32G0_FLASH_SECR (STM32G0_FLASH_REGS_ADDR + 0x80) - -// G4 (RM0440 Table 17, sec 3.7.19) -// Mostly the same as STM32G0 chips, but there are a few extra -// registers because 'cat 3' devices can have two Flash banks. -#define STM32G4_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) -#define STM32G4_FLASH_PDKEYR (STM32G4_FLASH_REGS_ADDR + 0x04) -#define STM32G4_FLASH_PCROP1SR (STM32G4_FLASH_REGS_ADDR + 0x24) -#define STM32G4_FLASH_PCROP1ER (STM32G4_FLASH_REGS_ADDR + 0x28) -#define STM32G4_FLASH_WRP1AR (STM32G4_FLASH_REGS_ADDR + 0x2C) -#define STM32G4_FLASH_WRP1BR (STM32G4_FLASH_REGS_ADDR + 0x30) -#define STM32G4_FLASH_PCROP2SR (STM32G4_FLASH_REGS_ADDR + 0x44) -#define STM32G4_FLASH_PCROP2ER (STM32G4_FLASH_REGS_ADDR + 0x48) -#define STM32G4_FLASH_WRP2AR (STM32G4_FLASH_REGS_ADDR + 0x4C) -#define STM32G4_FLASH_WRP2BR (STM32G4_FLASH_REGS_ADDR + 0x50) -#define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70) -#define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74) - -// G0/G4 FLASH control register -#define STM32Gx_FLASH_CR_PG (0) /* Program */ -#define STM32Gx_FLASH_CR_PER (1) /* Page erase */ -#define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */ -#define STM32Gx_FLASH_CR_PNB (3) /* Page number */ -#define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ -#define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ -#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ -#define STM32Gx_FLASH_CR_STRT (16) /* Start */ -#define STM32Gx_FLASH_CR_OPTSTRT \ - (17) /* Start of modification of option bytes */ -#define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ -#define STM32Gx_FLASH_CR_EOPIE (24) /* End of operation interrupt enable */ -#define STM32Gx_FLASH_CR_ERRIE (25) /* Error interrupt enable */ -#define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ -#define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ -#define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ - -// G0/G4 FLASH status register -#define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) -#define STM32Gx_FLASH_SR_PROGERR (3) -#define STM32Gx_FLASH_SR_WRPERR (4) -#define STM32Gx_FLASH_SR_PGAERR (5) -#define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ -#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ - -// G4 FLASH option register -#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ - -// WB (RM0434) -#define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) -#define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) -#define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) -#define STM32WB_FLASH_OPT_KEYR (STM32WB_FLASH_REGS_ADDR + 0x0C) -#define STM32WB_FLASH_SR (STM32WB_FLASH_REGS_ADDR + 0x10) -#define STM32WB_FLASH_CR (STM32WB_FLASH_REGS_ADDR + 0x14) -#define STM32WB_FLASH_ECCR (STM32WB_FLASH_REGS_ADDR + 0x18) -#define STM32WB_FLASH_OPTR (STM32WB_FLASH_REGS_ADDR + 0x20) -#define STM32WB_FLASH_PCROP1ASR (STM32WB_FLASH_REGS_ADDR + 0x24) -#define STM32WB_FLASH_PCROP1AER (STM32WB_FLASH_REGS_ADDR + 0x28) -#define STM32WB_FLASH_WRP1AR (STM32WB_FLASH_REGS_ADDR + 0x2C) -#define STM32WB_FLASH_WRP1BR (STM32WB_FLASH_REGS_ADDR + 0x30) -#define STM32WB_FLASH_PCROP1BSR (STM32WB_FLASH_REGS_ADDR + 0x34) -#define STM32WB_FLASH_PCROP1BER (STM32WB_FLASH_REGS_ADDR + 0x38) -#define STM32WB_FLASH_IPCCBR (STM32WB_FLASH_REGS_ADDR + 0x3C) -#define STM32WB_FLASH_C2ACR (STM32WB_FLASH_REGS_ADDR + 0x5C) -#define STM32WB_FLASH_C2SR (STM32WB_FLASH_REGS_ADDR + 0x60) -#define STM32WB_FLASH_C2CR (STM32WB_FLASH_REGS_ADDR + 0x64) -#define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) -#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) - -// WB Flash control register. -#define STM32WB_FLASH_CR_STRT (16) /* Start */ -#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ -#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ -// WB Flash status register. -#define STM32WB_FLASH_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ -#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ -#define STM32WB_FLASH_SR_WRPERR (4) /* Write protection error */ -#define STM32WB_FLASH_SR_PGAERR (5) /* Programming error */ -#define STM32WB_FLASH_SR_BSY (16) /* Busy */ - -// 32L4 register base is at FLASH_REGS_ADDR (0x40022000) -#define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) -#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) -#define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) -#define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) -#define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) - -#define STM32L4_FLASH_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ -#define STM32L4_FLASH_SR_PROGERR 3 -#define STM32L4_FLASH_SR_WRPERR 4 -#define STM32L4_FLASH_SR_PGAERR 5 -#define STM32L4_FLASH_SR_BSY 16 - -#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ -#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ -#define STM32L4_FLASH_CR_PG 0 /* Program */ -#define STM32L4_FLASH_CR_PER 1 /* Page erase */ -#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ -#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ -#define STM32L4_FLASH_CR_STRT 16 /* Start command */ -#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ -#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ -#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ -#define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ -// Bits requesting flash operations (useful when we want to clear them) -#define STM32L4_FLASH_CR_OPBITS \ - (uint32_t)((1lu << STM32L4_FLASH_CR_PG) | (1lu << STM32L4_FLASH_CR_PER) | \ - (1lu << STM32L4_FLASH_CR_MER1) | (1lu << STM32L4_FLASH_CR_MER1)) -// Page is fully specified by BKER and PNB -#define STM32L4_FLASH_CR_PAGEMASK (uint32_t)(0x1fflu << STM32L4_FLASH_CR_PNB) - -#define STM32L4_FLASH_OPTR_DUALBANK 21 - -// STM32L0x flash register base and offsets RM0090 - DM00031020.pdf -#define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) - -#define STM32L0_FLASH_PELOCK (0) -#define STM32L0_FLASH_OPTLOCK (2) -#define STM32L0_FLASH_OBL_LAUNCH (18) - -#define STM32L0_FLASH_SR_ERROR_MASK 0x00013F00 -#define STM32L0_FLASH_SR_WRPERR 8 -#define STM32L0_FLASH_SR_PGAERR 9 -#define STM32L0_FLASH_SR_NOTZEROERR 16 - -#define FLASH_ACR_OFF ((uint32_t)0x00) -#define FLASH_PECR_OFF ((uint32_t)0x04) -#define FLASH_PDKEYR_OFF ((uint32_t)0x08) -#define FLASH_PEKEYR_OFF ((uint32_t)0x0c) -#define FLASH_PRGKEYR_OFF ((uint32_t)0x10) -#define FLASH_OPTKEYR_OFF ((uint32_t)0x14) -#define FLASH_SR_OFF ((uint32_t)0x18) -#define FLASH_OBR_OFF ((uint32_t)0x1c) -#define FLASH_WRPR_OFF ((uint32_t)0x20) - -// STM32F7 -#define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) -#define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) -#define FLASH_F7_SR (FLASH_F7_REGS_ADDR + 0x0c) -#define FLASH_F7_CR (FLASH_F7_REGS_ADDR + 0x10) -#define FLASH_F7_OPTCR (FLASH_F7_REGS_ADDR + 0x14) -#define FLASH_F7_OPTCR1 (FLASH_F7_REGS_ADDR + 0x18) -#define FLASH_F7_OPTCR_LOCK 0 -#define FLASH_F7_OPTCR_START 1 -#define FLASH_F7_CR_STRT 16 -#define FLASH_F7_CR_LOCK 31 -#define FLASH_F7_CR_SER 1 -#define FLASH_F7_CR_SNB 3 -#define FLASH_F7_CR_SNB_MASK 0xf8 -#define FLASH_F7_SR_BSY 16 -#define FLASH_F7_SR_ERS_ERR 7 /* Erase Sequence Error */ -#define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ -#define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ -#define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ -#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ -#define FLASH_F7_SR_EOP 0 /* End of operation */ -#define FLASH_F7_OPTCR1_BOOT_ADD0 0 -#define FLASH_F7_OPTCR1_BOOT_ADD1 16 - -#define FLASH_F7_SR_ERROR_MASK \ - ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | \ - (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | \ - (1 << FLASH_F7_SR_OP_ERR)) - -// STM32F4 -#define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) -#define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08) -#define FLASH_F4_SR (FLASH_F4_REGS_ADDR + 0x0c) -#define FLASH_F4_CR (FLASH_F4_REGS_ADDR + 0x10) -#define FLASH_F4_OPTCR (FLASH_F4_REGS_ADDR + 0x14) -#define FLASH_F4_OPTCR_LOCK 0 -#define FLASH_F4_OPTCR_START 1 -#define FLASH_F4_CR_STRT 16 -#define FLASH_F4_CR_LOCK 31 -#define FLASH_F4_CR_SER 1 -#define FLASH_F4_CR_SNB 3 -#define FLASH_F4_CR_SNB_MASK 0xf8 -#define FLASH_F4_SR_ERROR_MASK 0x000000F0 -#define FLASH_F4_SR_PGAERR 5 -#define FLASH_F4_SR_WRPERR 4 -#define FLASH_F4_SR_BSY 16 - -// STM32F2 -#define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F2_KEYR (FLASH_F2_REGS_ADDR + 0x04) -#define FLASH_F2_OPT_KEYR (FLASH_F2_REGS_ADDR + 0x08) -#define FLASH_F2_SR (FLASH_F2_REGS_ADDR + 0x0c) -#define FLASH_F2_CR (FLASH_F2_REGS_ADDR + 0x10) -#define FLASH_F2_OPT_CR (FLASH_F2_REGS_ADDR + 0x14) -#define FLASH_F2_OPT_LOCK_BIT (1u << 0) -#define FLASH_F2_CR_STRT 16 -#define FLASH_F2_CR_LOCK 31 - -#define FLASH_F2_CR_SER 1 -#define FLASH_F2_CR_SNB 3 -#define FLASH_F2_CR_SNB_MASK 0x78 -#define FLASH_F2_SR_BSY 16 - -// STM32H7xx -#define FLASH_H7_CR_LOCK 0 -#define FLASH_H7_CR_PG 1 -#define FLASH_H7_CR_SER 2 -#define FLASH_H7_CR_BER 3 -#define FLASH_H7_CR_PSIZE 4 -#define FLASH_H7_CR_START(chipid) (chipid == STM32_CHIPID_H7Ax ? 5 : 7) -#define FLASH_H7_CR_SNB 8 -#define FLASH_H7_CR_SNB_MASK 0x700 - -#define FLASH_H7_SR_QW 2 -#define FLASH_H7_SR_WRPERR 17 -#define FLASH_H7_SR_PGSERR 18 -#define FLASH_H7_SR_STRBERR 19 -#define FLASH_H7_SR_ERROR_MASK \ - ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | \ - (1 << FLASH_H7_SR_WRPERR)) - -#define FLASH_H7_OPTCR_OPTLOCK 0 -#define FLASH_H7_OPTCR_OPTSTART 1 -#define FLASH_H7_OPTCR_MER 4 - -#define FLASH_H7_OPTSR_OPT_BUSY 0 -#define FLASH_H7_OPTSR_OPTCHANGEERR 30 - -#define FLASH_H7_OPTCCR_CLR_OPTCHANGEERR 30 - -#define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) -#define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) -#define FLASH_H7_KEYR2 (FLASH_H7_REGS_ADDR + 0x104) -#define FLASH_H7_OPT_KEYR (FLASH_H7_REGS_ADDR + 0x08) -#define FLASH_H7_OPT_KEYR2 (FLASH_H7_REGS_ADDR + 0x108) -#define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c) -#define FLASH_H7_CR2 (FLASH_H7_REGS_ADDR + 0x10c) -#define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) -#define FLASH_H7_SR2 (FLASH_H7_REGS_ADDR + 0x110) -#define FLASH_H7_CCR1 (FLASH_H7_REGS_ADDR + 0x14) -#define FLASH_H7_CCR2 (FLASH_H7_REGS_ADDR + 0x114) -#define FLASH_H7_OPTCR (FLASH_H7_REGS_ADDR + 0x18) -#define FLASH_H7_OPTCR2 (FLASH_H7_REGS_ADDR + 0x118) -#define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) -#define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) - #define STM32F0_DBGMCU_CR 0xE0042004 #define STM32F0_DBGMCU_CR_IWDG_STOP 8 #define STM32F0_DBGMCU_CR_WWDG_STOP 9 @@ -532,44 +198,4 @@ enum stm32_chipids { #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 -#define STM32F0_DBGMCU_CR 0xE0042004 -#define STM32F0_DBGMCU_CR_IWDG_STOP 8 -#define STM32F0_DBGMCU_CR_WWDG_STOP 9 - -#define STM32F4_DBGMCU_APB1FZR1 0xE0042008 -#define STM32F4_DBGMCU_APB1FZR1_WWDG_STOP 11 -#define STM32F4_DBGMCU_APB1FZR1_IWDG_STOP 12 - -#define STM32L0_DBGMCU_APB1_FZ 0x40015808 -#define STM32L0_DBGMCU_APB1_FZ_WWDG_STOP 11 -#define STM32L0_DBGMCU_APB1_FZ_IWDG_STOP 12 - -#define STM32H7_DBGMCU_APB1HFZ 0x5C001054 -#define STM32H7_DBGMCU_APB1HFZ_IWDG_STOP 18 - -#define STM32WB_DBGMCU_APB1FZR1 0xE004203C -#define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11 -#define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12 - -#define STM32F1_RCC_AHBENR 0x40021014 -#define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -#define STM32F4_RCC_AHB1ENR 0x40023830 -#define STM32F4_RCC_DMAEN 0x00600000 // DMA2EN | DMA1EN - -#define STM32G0_RCC_AHBENR 0x40021038 -#define STM32G0_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -#define STM32G4_RCC_AHB1ENR 0x40021048 -#define STM32G4_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -#define STM32L0_RCC_AHBENR 0x40021030 -#define STM32L0_RCC_DMAEN 0x00000001 // DMAEN - -#define STM32H7_RCC_AHB1ENR 0x58024538 -#define STM32H7_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -#define STM32WB_RCC_AHB1ENR 0x58000048 -#define STM32WB_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - #endif // STM32_H diff --git a/inc/stm32flash.h b/inc/stm32flash.h index 01c76946c..73d1bbc21 100644 --- a/inc/stm32flash.h +++ b/inc/stm32flash.h @@ -300,7 +300,7 @@ #define FLASH_H7_CR_SER 2 #define FLASH_H7_CR_BER 3 #define FLASH_H7_CR_PSIZE 4 -#define FLASH_H7_CR_START(chipid) (chipid == STLINK_CHIPID_STM32_H7Ax ? 5 : 7) +#define FLASH_H7_CR_START(chipid) (chipid == STM32_CHIPID_H7Ax ? 5 : 7) #define FLASH_H7_CR_SNB 8 #define FLASH_H7_CR_SNB_MASK 0x700 @@ -337,4 +337,4 @@ #define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) #define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) -#endif // STM32FLASH_H \ No newline at end of file +#endif // STM32FLASH_H diff --git a/src/calculate.c b/src/calculate.c index 22f6e3a5b..ed3b65873 100644 --- a/src/calculate.c +++ b/src/calculate.c @@ -54,9 +54,9 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); flashaddr -= STM32_FLASH_BASE; - if (sl->chip_id == STLINK_CHIPID_STM32_L4 || - sl->chip_id == STLINK_CHIPID_STM32_L496x_L4A6x || - sl->chip_id == STLINK_CHIPID_STM32_L4Rx) { + if (sl->chip_id == STM32_CHIPID_L4 || + sl->chip_id == STM32_CHIPID_L496x_L4A6x || + sl->chip_id == STM32_CHIPID_L4Rx) { // this chip use dual banked flash if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { uint32_t banksize = (uint32_t)sl->flash_size / 2; diff --git a/src/common.c b/src/common.c index 7b4f1e14b..4e5052522 100644 --- a/src/common.c +++ b/src/common.c @@ -134,7 +134,7 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { * */ - if ((sl->core_id == STM32H7_CORE_ID || sl->core_id == STM32H7_CORE_ID_JTAG) && + if ((sl->core_id == STM32_CORE_ID_M7F_H7_SWD || sl->core_id == STM32_CORE_ID_M7F_H7_JTAG) && cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) ret = stlink_read_debug32(sl, 0x5c001000, chip_id); @@ -242,14 +242,14 @@ int stlink_load_device_params(stlink_t *sl) { flash_size = flash_size & 0xffff; - if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MD || - sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MD_LD || - sl->chip_id == STLINK_CHIPID_STM32_L1_MD_PLUS) && + if ((sl->chip_id == STM32_CHIPID_L1_MD || + sl->chip_id == STM32_CHIPID_F1_VL_MD_LD || + sl->chip_id == STM32_CHIPID_L1_MD_PLUS) && (flash_size == 0)) { sl->flash_size = 128 * 1024; - } else if (sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2) { + } else if (sl->chip_id == STM32_CHIPID_L1_CAT2) { sl->flash_size = (flash_size & 0xff) * 1024; - } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_MD_PLUS_HD) { + } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_L1_MD_PLUS_HD) { // 0 is 384k and 1 is 256k if (flash_size == 0) { sl->flash_size = 384 * 1024; @@ -271,12 +271,12 @@ int stlink_load_device_params(stlink_t *sl) { // medium and low devices have the same chipid. ram size depends on flash // size. STM32F100xx datasheet Doc ID 16455 Table 2 - if (sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MD_LD && + if (sl->chip_id == STM32_CHIPID_F1_VL_MD_LD && sl->flash_size < 64 * 1024) { sl->sram_size = 0x1000; } - if (sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3) { + if (sl->chip_id == STM32_CHIPID_G4_CAT3) { uint32_t flash_optr; stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); @@ -293,7 +293,7 @@ int stlink_load_device_params(stlink_t *sl) { } ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", - params->description, (unsigned)(sl->sram_size / 1024), + params->dev_type, (unsigned)(sl->sram_size / 1024), (unsigned)(sl->flash_size / 1024), (sl->flash_pgsz < 1024) ? (unsigned)(sl->flash_pgsz) : (unsigned)(sl->flash_pgsz / 1024), @@ -712,16 +712,16 @@ int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, } // 291 uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { - if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || - (sl->chip_id == STLINK_CHIPID_STM32_F4) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || - (sl->chip_id == STLINK_CHIPID_STM32_F411xx) || - (sl->chip_id == STLINK_CHIPID_STM32_F446) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || - (sl->chip_id == STLINK_CHIPID_STM32_F72xxx) || - (sl->chip_id == STLINK_CHIPID_STM32_F412)) { + if ((sl->chip_id == STM32_CHIPID_F2) || + (sl->chip_id == STM32_CHIPID_F4) || + (sl->chip_id == STM32_CHIPID_F4_DE) || + (sl->chip_id == STM32_CHIPID_F4_LP) || + (sl->chip_id == STM32_CHIPID_F4_HD) || + (sl->chip_id == STM32_CHIPID_F411xx) || + (sl->chip_id == STM32_CHIPID_F446) || + (sl->chip_id == STM32_CHIPID_F4_DSI) || + (sl->chip_id == STM32_CHIPID_F72xxx) || + (sl->chip_id == STM32_CHIPID_F412)) { uint32_t sector = calculate_F4_sectornum(flashaddr); if (sector >= 12) { @@ -735,8 +735,8 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { } else { sl->flash_pgsz = 0x20000; } - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F76xxx) { + } else if (sl->chip_id == STM32_CHIPID_F7 || + sl->chip_id == STM32_CHIPID_F76xxx) { uint32_t sector = calculate_F7_sectornum(flashaddr); if (sector < 4) { @@ -984,7 +984,7 @@ static void stop_wdg_in_debug(stlink_t *sl) { break; case STM32_FLASH_TYPE_F2_F4: case STM32_FLASH_TYPE_F7: - case STM32_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_L4_L4P: dbgmcu_cr = STM32F4_DBGMCU_APB1FZR1; set = (1 << STM32F4_DBGMCU_APB1FZR1_IWDG_STOP) | (1 << STM32F4_DBGMCU_APB1FZR1_WWDG_STOP); @@ -999,7 +999,7 @@ static void stop_wdg_in_debug(stlink_t *sl) { dbgmcu_cr = STM32H7_DBGMCU_APB1HFZ; set = (1 << STM32H7_DBGMCU_APB1HFZ_IWDG_STOP); break; - case STM32_FLASH_TYPE_WB: + case STM32_FLASH_TYPE_WB_WL: dbgmcu_cr = STM32WB_DBGMCU_APB1FZR1; set = (1 << STM32WB_DBGMCU_APB1FZR1_IWDG_STOP) | (1 << STM32WB_DBGMCU_APB1FZR1_WWDG_STOP); diff --git a/src/common_flash.c b/src/common_flash.c index 1f438c74f..e2a9ebbc3 100644 --- a/src/common_flash.c +++ b/src/common_flash.c @@ -11,16 +11,16 @@ uint32_t get_stm32l0_flash_base(stlink_t *sl) { switch (sl->chip_id) { - case STLINK_CHIPID_STM32_L0: - case STLINK_CHIPID_STM32_L0_CAT5: - case STLINK_CHIPID_STM32_L0_CAT2: - case STLINK_CHIPID_STM32_L011: + case STM32_CHIPID_L0: + case STM32_CHIPID_L0_CAT5: + case STM32_CHIPID_L0_CAT2: + case STM32_CHIPID_L011: return (STM32L0_FLASH_REGS_ADDR); - case STLINK_CHIPID_STM32_L1_CAT2: - case STLINK_CHIPID_STM32_L1_MD: - case STLINK_CHIPID_STM32_L1_MD_PLUS: - case STLINK_CHIPID_STM32_L1_MD_PLUS_HD: + case STM32_CHIPID_L1_CAT2: + case STM32_CHIPID_L1_MD: + case STM32_CHIPID_L1_MD_PLUS: + case STM32_CHIPID_L1_MD_PLUS_HD: return (STM32L_FLASH_REGS_ADDR); default: @@ -32,18 +32,18 @@ uint32_t get_stm32l0_flash_base(stlink_t *sl) { uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { uint32_t reg, res; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { reg = FLASH_F4_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { reg = FLASH_F7_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { reg = STM32L4_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { reg = STM32WB_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; } else { reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; @@ -61,33 +61,33 @@ void lock_flash(stlink_t *sl) { uint32_t cr_lock_shift, cr_reg, n, cr2_reg = 0; uint32_t cr_mask = 0xffffffffu; - if (sl->flash_type == STLINK_FLASH_TYPE_F0) { + if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { cr_reg = FLASH_CR; cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { cr_reg = FLASH_CR; cr2_reg = FLASH_CR2; cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; cr_lock_shift = FLASH_F4_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; cr_lock_shift = FLASH_F7_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = STM32L0_FLASH_PELOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_lock_shift = STM32Gx_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = FLASH_H7_CR1; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { cr2_reg = FLASH_H7_CR2; @@ -113,23 +113,23 @@ void lock_flash(stlink_t *sl) { static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { uint32_t sr_reg; - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { sr_reg = FLASH_F4_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { sr_reg = STM32L4_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { sr_reg = STM32Gx_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { sr_reg = STM32WB_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; } else { ELOG("method 'write_flash_sr' is unsupported\n"); @@ -141,32 +141,32 @@ static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { void clear_flash_error(stlink_t *sl) { switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: + case STM32_FLASH_TYPE_F0_F1_F3: write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); break; - case STLINK_FLASH_TYPE_F4: + case STM32_FLASH_TYPE_F2_F4: write_flash_sr(sl, BANK_1, FLASH_F4_SR_ERROR_MASK); break; - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: write_flash_sr(sl, BANK_1, FLASH_F7_SR_ERROR_MASK); break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); break; - case STLINK_FLASH_TYPE_L0: + case STM32_FLASH_TYPE_L0_L1: write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); break; - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_L4_L4P: write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { write_flash_sr(sl, BANK_2, FLASH_H7_SR_ERROR_MASK); } break; - case STLINK_FLASH_TYPE_WB: + case STM32_FLASH_TYPE_WB_WL: write_flash_sr(sl, BANK_1, STM32WB_FLASH_SR_ERROR_MASK); break; default: @@ -177,23 +177,23 @@ void clear_flash_error(stlink_t *sl) { uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { uint32_t res, sr_reg; - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { sr_reg = FLASH_F4_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { sr_reg = STM32L4_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { sr_reg = STM32Gx_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { sr_reg = STM32WB_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; } else { ELOG("method 'read_flash_sr' is unsupported\n"); @@ -208,22 +208,22 @@ unsigned int is_flash_busy(stlink_t *sl) { uint32_t sr_busy_shift; unsigned int res; - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || - (sl->flash_type == STLINK_FLASH_TYPE_L0)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || + (sl->flash_type == STM32_FLASH_TYPE_L0_L1)) { sr_busy_shift = FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { sr_busy_shift = FLASH_F4_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { sr_busy_shift = FLASH_F7_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { sr_busy_shift = STM32L4_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { sr_busy_shift = STM32Gx_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { sr_busy_shift = STM32WB_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { sr_busy_shift = FLASH_H7_SR_QW; } else { ELOG("method 'is_flash_busy' is unsupported\n"); @@ -232,8 +232,8 @@ unsigned int is_flash_busy(stlink_t *sl) { res = read_flash_sr(sl, BANK_1) & (1 << sr_busy_shift); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || + (sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { res |= read_flash_sr(sl, BANK_2) & (1 << sr_busy_shift); } @@ -254,52 +254,52 @@ int check_flash_error(stlink_t *sl) { WRPERR = PROGERR = PGAERR = 0; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { res |= read_flash_sr(sl, BANK_2) & FLASH_SR_ERROR_MASK; } WRPERR = (1 << FLASH_SR_WRPRT_ERR); PROGERR = (1 << FLASH_SR_PG_ERR); break; - case STLINK_FLASH_TYPE_F4: + case STM32_FLASH_TYPE_F2_F4: res = read_flash_sr(sl, BANK_1) & FLASH_F4_SR_ERROR_MASK; WRPERR = (1 << FLASH_F4_SR_WRPERR); PGAERR = (1 << FLASH_F4_SR_PGAERR); break; - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: res = read_flash_sr(sl, BANK_1) & FLASH_F7_SR_ERROR_MASK; WRPERR = (1 << FLASH_F7_SR_WRP_ERR); PROGERR = (1 << FLASH_F7_SR_PGP_ERR); break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; WRPERR = (1 << STM32Gx_FLASH_SR_WRPERR); PROGERR = (1 << STM32Gx_FLASH_SR_PROGERR); PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); break; - case STLINK_FLASH_TYPE_L0: + case STM32_FLASH_TYPE_L0_L1: res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); break; - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_L4_L4P: res = read_flash_sr(sl, BANK_1) & STM32L4_FLASH_SR_ERROR_MASK; WRPERR = (1 << STM32L4_FLASH_SR_WRPERR); PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); PGAERR = (1 << STM32L4_FLASH_SR_PGAERR); break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; } WRPERR = (1 << FLASH_H7_SR_WRPERR); break; - case STLINK_FLASH_TYPE_WB: + case STM32_FLASH_TYPE_WB_WL: res = read_flash_sr(sl, BANK_1) & STM32WB_FLASH_SR_ERROR_MASK; WRPERR = (1 << STM32WB_FLASH_SR_WRPERR); PROGERR = (1 << STM32WB_FLASH_SR_PROGERR); @@ -336,30 +336,30 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { uint32_t cr_reg; uint32_t n; - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { cr_reg = FLASH_CR; cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; cr_lock_shift = FLASH_F4_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; cr_lock_shift = FLASH_F7_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = STM32L0_FLASH_PELOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_lock_shift = STM32Gx_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = FLASH_H7_CR1; cr_lock_shift = FLASH_H7_CR_LOCK; } else { @@ -380,27 +380,27 @@ static void unlock_flash(stlink_t *sl) { * definitive lock of the FPEC block until next reset. */ - if (sl->flash_type == STLINK_FLASH_TYPE_F0) { + if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { key_reg = FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { key_reg = FLASH_KEYR; key2_reg = FLASH_KEYR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { key_reg = FLASH_F4_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { key_reg = FLASH_F7_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; flash_key1 = FLASH_L0_PEKEY1; flash_key2 = FLASH_L0_PEKEY2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { key_reg = STM32L4_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { key_reg = STM32Gx_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { key_reg = STM32WB_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { key_reg = FLASH_H7_KEYR1; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { key2_reg = FLASH_H7_KEYR2; @@ -439,38 +439,38 @@ int lock_flash_option(stlink_t *sl) { int active_bit_level = 1; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: optcr_reg = FLASH_CR; optlock_shift = FLASH_CR_OPTWRE; active_bit_level = 0; break; - case STLINK_FLASH_TYPE_F4: + case STM32_FLASH_TYPE_F2_F4: optcr_reg = FLASH_F4_OPTCR; optlock_shift = FLASH_F4_OPTCR_LOCK; break; - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: optcr_reg = FLASH_F7_OPTCR; optlock_shift = FLASH_F7_OPTCR_LOCK; break; - case STLINK_FLASH_TYPE_L0: + case STM32_FLASH_TYPE_L0_L1: optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; optlock_shift = STM32L0_FLASH_OPTLOCK; break; - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_L4_L4P: optcr_reg = STM32L4_FLASH_CR; optlock_shift = STM32L4_FLASH_CR_OPTLOCK; break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: optcr_reg = STM32Gx_FLASH_CR; optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; break; - case STLINK_FLASH_TYPE_WB: + case STM32_FLASH_TYPE_WB_WL: optcr_reg = STM32WB_FLASH_CR; optlock_shift = STM32WB_FLASH_CR_OPTLOCK; break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: optcr_reg = FLASH_H7_OPTCR; optlock_shift = FLASH_H7_OPTCR_OPTLOCK; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) @@ -512,38 +512,38 @@ static bool is_flash_option_locked(stlink_t *sl) { uint32_t n; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: optcr_reg = FLASH_CR; optlock_shift = FLASH_CR_OPTWRE; active_bit_level = 0; /* bit is "option write enable", not lock */ break; - case STLINK_FLASH_TYPE_F4: + case STM32_FLASH_TYPE_F2_F4: optcr_reg = FLASH_F4_OPTCR; optlock_shift = FLASH_F4_OPTCR_LOCK; break; - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: optcr_reg = FLASH_F7_OPTCR; optlock_shift = FLASH_F7_OPTCR_LOCK; break; - case STLINK_FLASH_TYPE_L0: + case STM32_FLASH_TYPE_L0_L1: optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; optlock_shift = STM32L0_FLASH_OPTLOCK; break; - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_L4_L4P: optcr_reg = STM32L4_FLASH_CR; optlock_shift = STM32L4_FLASH_CR_OPTLOCK; break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: optcr_reg = STM32Gx_FLASH_CR; optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; break; - case STLINK_FLASH_TYPE_WB: + case STM32_FLASH_TYPE_WB_WL: optcr_reg = STM32WB_FLASH_CR; optlock_shift = STM32WB_FLASH_CR_OPTLOCK; break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: optcr_reg = FLASH_H7_OPTCR; optlock_shift = FLASH_H7_OPTCR_OPTLOCK; break; @@ -567,34 +567,34 @@ static int unlock_flash_option(stlink_t *sl) { uint32_t optkey2 = FLASH_OPTKEY2; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: optkey_reg = FLASH_OPTKEYR; optkey1 = FLASH_F0_OPTKEY1; optkey2 = FLASH_F0_OPTKEY2; break; - case STLINK_FLASH_TYPE_F4: + case STM32_FLASH_TYPE_F2_F4: optkey_reg = FLASH_F4_OPT_KEYR; break; - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: optkey_reg = FLASH_F7_OPT_KEYR; break; - case STLINK_FLASH_TYPE_L0: + case STM32_FLASH_TYPE_L0_L1: optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; optkey1 = FLASH_L0_OPTKEY1; optkey2 = FLASH_L0_OPTKEY2; break; - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_L4_L4P: optkey_reg = STM32L4_FLASH_OPTKEYR; break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: optkey_reg = STM32Gx_FLASH_OPTKEYR; break; - case STLINK_FLASH_TYPE_WB: + case STM32_FLASH_TYPE_WB_WL: optkey_reg = STM32WB_FLASH_OPT_KEYR; break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: optkey_reg = FLASH_H7_OPT_KEYR; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) optkey2_reg = FLASH_H7_OPT_KEYR2; @@ -637,7 +637,7 @@ void write_flash_cr_psiz(stlink_t *sl, uint32_t n, uint32_t cr_reg, psize_shift; uint32_t x = read_flash_cr(sl, bank); - if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; psize_shift = FLASH_H7_CR_PSIZE; } else { @@ -657,18 +657,18 @@ void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { uint32_t cr_reg, n; uint32_t bit = FLASH_CR_PG; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { cr_reg = STM32L4_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; bit = FLASH_H7_CR_PG; } else { @@ -706,7 +706,7 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, unsigned bank) { uint32_t cr_reg, snb_mask, snb_shift, ser_shift; uint32_t x = read_flash_cr(sl, bank); - if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; snb_mask = FLASH_H7_CR_SNB_MASK; snb_shift = FLASH_H7_CR_SNB; @@ -730,10 +730,10 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, unsigned bank) { static void set_flash_cr_per(stlink_t *sl, unsigned bank) { uint32_t cr_reg, val; - if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; } else { cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; @@ -747,10 +747,10 @@ static void set_flash_cr_per(stlink_t *sl, unsigned bank) { static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { uint32_t cr_reg; - if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; } else { cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; @@ -779,23 +779,23 @@ static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { uint32_t val, cr_reg, cr_strt; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; cr_strt = 1 << FLASH_F4_CR_STRT; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; cr_strt = 1 << FLASH_F7_CR_STRT; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { cr_reg = STM32L4_FLASH_CR; cr_strt = (1 << STM32L4_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_strt = (1 << STM32Gx_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; cr_strt = (1 << STM32WB_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; cr_strt = 1 << FLASH_H7_CR_START(sl->chip_id); } else { @@ -811,20 +811,20 @@ static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { uint32_t val, cr_reg, cr_mer, cr_pg; - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; cr_mer = 1 << FLASH_CR_MER; cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; cr_mer = 1 << FLASH_CR_MER; cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); cr_pg = (1 << STM32L4_FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_mer = (1 << STM32Gx_FLASH_CR_MER1); @@ -833,11 +833,11 @@ static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { } cr_pg = (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; cr_mer = (1 << FLASH_CR_MER); cr_pg = (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; cr_mer = (1 << FLASH_H7_CR_BER); cr_pg = (1 << FLASH_H7_CR_PG); @@ -877,18 +877,18 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { // clear flash IO errors clear_flash_error(sl); - if (sl->flash_type == STLINK_FLASH_TYPE_F4 || - sl->flash_type == STLINK_FLASH_TYPE_F7 || - sl->flash_type == STLINK_FLASH_TYPE_L4) { + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4 || + sl->flash_type == STM32_FLASH_TYPE_F7 || + sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { // unlock if locked unlock_flash_if(sl); // select the page to erase - if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || - (sl->chip_id == STLINK_CHIPID_STM32_L43x_L44x) || - (sl->chip_id == STLINK_CHIPID_STM32_L45x_L46x) || - (sl->chip_id == STLINK_CHIPID_STM32_L496x_L4A6x) || - (sl->chip_id == STLINK_CHIPID_STM32_L4Rx)) { + if ((sl->chip_id == STM32_CHIPID_L4) || + (sl->chip_id == STM32_CHIPID_L43x_L44x) || + (sl->chip_id == STM32_CHIPID_L45x_L46x) || + (sl->chip_id == STM32_CHIPID_L496x_L4A6x) || + (sl->chip_id == STM32_CHIPID_L4Rx)) { // calculate the actual bank+page from the address uint32_t page = calculate_L4_page(sl, flashaddr); @@ -896,8 +896,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { stlink_calculate_pagesize(sl, flashaddr)); write_flash_cr_bker_pnb(sl, page); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F76xxx) { + } else if (sl->chip_id == STM32_CHIPID_F7 || + sl->chip_id == STM32_CHIPID_F76xxx) { // calculate the actual page from the address uint32_t sector = calculate_F7_sectornum(flashaddr); @@ -926,7 +926,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { #if DEBUG_FLASH fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl, BANK_1)); #endif - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { uint32_t val; uint32_t flash_regs_base = get_stm32l0_flash_base(sl); @@ -982,15 +982,15 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || + sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { uint32_t val; unlock_flash_if(sl); set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit // set the page to erase - if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); @@ -1000,7 +1000,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { val |= ((flash_page & 0xFF) << 3); stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); @@ -1008,7 +1008,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { val &= ~(0x3F << 3); val |= ((flash_page & 0x3F) << 3) | (1 << FLASH_CR_PER); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G4) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); @@ -1022,8 +1022,8 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { wait_flash_busy(sl); // wait for the 'busy' bit to clear clear_flash_cr_per(sl, BANK_1); // clear the 'enable page erase' bit lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_F0 || - sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3 || + sl->flash_type == STM32_FLASH_TYPE_F1_XL) { unsigned bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; unlock_flash_if(sl); clear_flash_cr_pg(sl, bank); // clear the pg bit @@ -1034,7 +1034,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { wait_flash_busy(sl); clear_flash_cr_per(sl, bank); // clear the page erase bit lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; unlock_flash_if(sl); // unlock if locked uint32_t sector = calculate_H7_sectornum( @@ -1093,8 +1093,8 @@ int stlink_erase_flash_mass(stlink_t *sl) { int err = 0; // TODO: User MER bit to mass-erase WB series. - if (sl->flash_type == STLINK_FLASH_TYPE_L0 || - sl->flash_type == STLINK_FLASH_TYPE_WB) { + if (sl->flash_type == STM32_FLASH_TYPE_L0_L1 || + sl->flash_type == STM32_FLASH_TYPE_WB_WL) { err = stlink_erase_flash_section(sl, sl->flash_base, sl->flash_size, false); @@ -1103,8 +1103,8 @@ int stlink_erase_flash_mass(stlink_t *sl) { clear_flash_error(sl); unlock_flash_if(sl); - if (sl->flash_type == STLINK_FLASH_TYPE_H7 && - sl->chip_id != STLINK_CHIPID_STM32_H7Ax) { + if (sl->flash_type == STM32_FLASH_TYPE_H7 && + sl->chip_id != STM32_CHIPID_H7Ax) { // set parallelism write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { @@ -1116,8 +1116,8 @@ int stlink_erase_flash_mass(stlink_t *sl) { set_flash_cr_strt( sl, BANK_1); // start erase operation, reset by hw with busy bit - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || + (sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { set_flash_cr_mer(sl, 1, BANK_2); // set the mass erase bit in bank 2 set_flash_cr_strt(sl, BANK_2); // start erase operation in bank 2 @@ -1128,8 +1128,8 @@ int stlink_erase_flash_mass(stlink_t *sl) { // reset the mass erase bit set_flash_cr_mer(sl, 0, BANK_1); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || + (sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { set_flash_cr_mer(sl, 0, BANK_2); } diff --git a/src/flashloader.c b/src/flashloader.c index f84e16ef0..e4c7d7200 100644 --- a/src/flashloader.c +++ b/src/flashloader.c @@ -73,24 +73,24 @@ static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { x = read_flash_cr(sl, bank); - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { cr_reg = STM32L4_FLASH_CR; x &= ~STM32L4_FLASH_CR_OPBITS; x |= (1 << STM32L4_FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; x |= (1 << FLASH_H7_CR_PG); } else { @@ -107,34 +107,34 @@ static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { rcc = rcc_dma_mask = value = 0; switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: rcc = STM32F1_RCC_AHBENR; rcc_dma_mask = STM32F1_RCC_DMAEN; break; - case STLINK_FLASH_TYPE_F4: - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F2_F4: + case STM32_FLASH_TYPE_F7: rcc = STM32F4_RCC_AHB1ENR; rcc_dma_mask = STM32F4_RCC_DMAEN; break; - case STLINK_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G0: rcc = STM32G0_RCC_AHBENR; rcc_dma_mask = STM32G0_RCC_DMAEN; break; - case STLINK_FLASH_TYPE_G4: - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_L4_L4P: rcc = STM32G4_RCC_AHB1ENR; rcc_dma_mask = STM32G4_RCC_DMAEN; break; - case STLINK_FLASH_TYPE_L0: + case STM32_FLASH_TYPE_L0_L1: rcc = STM32L0_RCC_AHBENR; rcc_dma_mask = STM32L0_RCC_DMAEN; break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: rcc = STM32H7_RCC_AHB1ENR; rcc_dma_mask = STM32H7_RCC_DMAEN; break; - case STLINK_FLASH_TYPE_WB: + case STM32_FLASH_TYPE_WB_WL: rcc = STM32WB_RCC_AHB1ENR; rcc_dma_mask = STM32WB_RCC_DMAEN; break; @@ -162,9 +162,9 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { // Clear errors clear_flash_error(sl); - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || + (sl->flash_type == STM32_FLASH_TYPE_F7) || + (sl->flash_type == STM32_FLASH_TYPE_L4_L4P)) { ILOG("Starting Flash write for F2/F4/F7/L4\n"); // Flash loader initialisation @@ -188,7 +188,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { return (-1); } - if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { // L4 does not have a byte-write mode if (voltage < 1710) { ELOG("Target voltage (%d mV) too low for flash writes!\n", voltage); @@ -208,14 +208,14 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { // set programming mode set_flash_cr_pg(sl, BANK_1); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || + sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { ILOG("Starting Flash write for WB/G0/G4\n"); unlock_flash_if(sl); // unlock flash if necessary set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { ILOG("Starting Flash write for L0\n"); uint32_t val; @@ -252,8 +252,8 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { // L0/L1 have fallback to soft write WLOG("stlink_flash_loader_init() == -1\n"); } - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { ILOG("Starting Flash write for VL/F0/F3/F1_XL\n"); // flash loader initialisation @@ -267,10 +267,10 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { // set programming mode set_flash_cr_pg(sl, BANK_1); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { set_flash_cr_pg(sl, BANK_2); } - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { ILOG("Starting Flash write for H7\n"); unlock_flash_if(sl); // unlock the cr @@ -278,7 +278,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { set_flash_cr_pg(sl, BANK_2); } - if (sl->chip_id != STLINK_CHIPID_STM32_H7Ax) { + if (sl->chip_id != STM32_CHIPID_H7Ax) { // set parallelism write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { @@ -296,9 +296,9 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t *base, uint32_t len) { size_t off; - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || + (sl->flash_type == STM32_FLASH_TYPE_F7) || + (sl->flash_type == STM32_FLASH_TYPE_L4_L4P)) { size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; for (off = 0; off < len;) { size_t size = len - off > buf_size ? buf_size : len - off; @@ -312,9 +312,9 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, off += size; } - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || + sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); for (off = 0; off < len; off += sizeof(uint32_t)) { uint32_t data; @@ -338,7 +338,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, 0); // write a single word of zeros wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear } - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { uint32_t val; uint32_t flash_regs_base = get_stm32l0_flash_base(sl); uint32_t pagesize = (flash_regs_base==STM32L0_FLASH_REGS_ADDR)? @@ -378,8 +378,8 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, // TODO: check redo write operation } fprintf(stdout, "\n"); - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { int write_block_count = 0; for (off = 0; off < len; off += sl->flash_pgsz) { // adjust last write size @@ -411,7 +411,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, if (sl->verbose >= 1) { fprintf(stdout, "\n"); } - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { for (off = 0; off < len;) { // Program STM32H7x with 64-byte Flash words size_t chunk = (len - off > 64) ? 64 : len - off; @@ -441,24 +441,24 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { uint32_t dhcsr; - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || - (sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4) || - (sl->flash_type == STLINK_FLASH_TYPE_WB) || - (sl->flash_type == STLINK_FLASH_TYPE_G0) || - (sl->flash_type == STLINK_FLASH_TYPE_G4) || - (sl->flash_type == STLINK_FLASH_TYPE_H7)) { + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || + (sl->flash_type == STM32_FLASH_TYPE_F2_F4) || + (sl->flash_type == STM32_FLASH_TYPE_F7) || + (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) || + (sl->flash_type == STM32_FLASH_TYPE_WB_WL) || + (sl->flash_type == STM32_FLASH_TYPE_G0) || + (sl->flash_type == STM32_FLASH_TYPE_G4) || + (sl->flash_type == STM32_FLASH_TYPE_H7)) { clear_flash_cr_pg(sl, BANK_1); - if ((sl->flash_type == STLINK_FLASH_TYPE_H7 && + if ((sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK) || - sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + sl->flash_type == STM32_FLASH_TYPE_F1_XL) { clear_flash_cr_pg(sl, BANK_2); } lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { uint32_t val; uint32_t flash_regs_base = get_stm32l0_flash_base(sl); diff --git a/src/option_bytes.c b/src/option_bytes.c index ed9ee4f39..f5d8c00a0 100644 --- a/src/option_bytes.c +++ b/src/option_bytes.c @@ -119,17 +119,17 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { } switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F2: + case STM32_CHIPID_F2: return stlink_read_option_bytes_f2(sl, option_byte); - case STLINK_CHIPID_STM32_F4: - case STLINK_CHIPID_STM32_F446: + case STM32_CHIPID_F4: + case STM32_CHIPID_F446: return stlink_read_option_bytes_f4(sl, option_byte); - case STLINK_CHIPID_STM32_F76xxx: + case STM32_CHIPID_F76xxx: return stlink_read_option_bytes_f7(sl, option_byte); - case STLINK_CHIPID_STM32_G0_CAT1: - case STLINK_CHIPID_STM32_G0_CAT2: - case STLINK_CHIPID_STM32_G4_CAT2: - case STLINK_CHIPID_STM32_G4_CAT3: + case STM32_CHIPID_G0_CAT1: + case STM32_CHIPID_G0_CAT2: + case STM32_CHIPID_G4_CAT2: + case STM32_CHIPID_G4_CAT3: return stlink_read_option_bytes_Gx(sl, option_byte); default: return stlink_read_option_bytes_generic(sl, option_byte); @@ -513,27 +513,27 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: ret = stlink_write_option_bytes_f0(sl, base, addr, len); break; - case STLINK_FLASH_TYPE_F4: + case STM32_FLASH_TYPE_F2_F4: ret = stlink_write_option_bytes_f4(sl, base, addr, len); break; - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: ret = stlink_write_option_bytes_f7(sl, base, addr, len); break; - case STLINK_FLASH_TYPE_L0: + case STM32_FLASH_TYPE_L0_L1: ret = stlink_write_option_bytes_l0(sl, base, addr, len); break; - case STLINK_FLASH_TYPE_L4: + case STM32_FLASH_TYPE_L4_L4P: ret = stlink_write_option_bytes_l4(sl, base, addr, len); break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: ret = stlink_write_option_bytes_gx(sl, base, addr, len); break; - case STLINK_FLASH_TYPE_H7: + case STM32_FLASH_TYPE_H7: ret = stlink_write_option_bytes_h7(sl, base, addr, len); break; default: @@ -739,11 +739,11 @@ int stlink_write_option_control_register32(stlink_t *sl, } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: ret = stlink_write_option_control_register_f0(sl, option_control_register); break; - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: ret = stlink_write_option_control_register_f7(sl, option_control_register); break; default: @@ -788,7 +788,7 @@ int stlink_write_option_control_register1_32( } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: ret = stlink_write_option_control_register1_f7(sl, option_control_register1); break; @@ -847,7 +847,7 @@ int stlink_write_option_bytes_boot_add32(stlink_t *sl, } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); break; default: @@ -937,7 +937,7 @@ int stlink_read_option_control_register1_32(stlink_t *sl, } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: return stlink_read_option_control_register1_f7(sl, option_byte); default: return -1; @@ -971,7 +971,7 @@ int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: return stlink_read_option_bytes_boot_add_f7(sl, option_byte); default: return -1; @@ -1016,10 +1016,10 @@ int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { } switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: return stlink_read_option_control_register_f0(sl, option_byte); - case STLINK_FLASH_TYPE_F7: + case STM32_FLASH_TYPE_F7: return stlink_read_option_control_register_f7(sl, option_byte); default: return -1; From 935c6af9b48fe5fbe730c6801cf3720a4d8ae3f4 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 30 Jan 2022 14:54:46 +0100 Subject: [PATCH 1302/1435] Updated description for F1 CL chip --- config/chips/F1xx_CL.chip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/chips/F1xx_CL.chip b/config/chips/F1xx_CL.chip index d774412e1..45f06d386 100644 --- a/config/chips/F1xx_CL.chip +++ b/config/chips/F1xx_CL.chip @@ -1,4 +1,4 @@ -# Chip-ID file for STM32F1xx Connectivity Line device +# Chip-ID file for STM32F1xx Connectivity Line device (F105 / F107) # dev_type STM32F1xx_CL ref_manual_id 0008 From 0011064797cd710f9b684e07c0083b5464e9a031 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 30 Jan 2022 15:47:55 +0100 Subject: [PATCH 1303/1435] Rolled-back deletion of recent changes --- CHANGELOG.md | 18 +- README.md | 2 +- cmake/modules/Findlibusb.cmake | 2 +- cmake/packaging/cpack_config.cmake | 2 +- cmake/packaging/deb/control | 2 +- contributors.txt | 3 + doc/compiling.md | 4 +- doc/version_support.md | 155 +- inc/stlink.h | 3 +- inc/stm32.h | 8 +- src/stlink-lib/chipid.h | 3 +- src/stlink-lib/usb.c.bak | 1410 ----------------- src/win32/unistd/unistd.h | 2 +- src/win32/unistd/unistd.h.bak | 76 - stlinkv1_macos_driver/install.sh | 3 - .../Contents/Info.plist | 82 - .../Contents/MacOS/stlink_shield_10_14 | Bin 33840 -> 0 bytes .../stlink_shield_10_14.kext/Contents/PkgInfo | 1 - .../Contents/_CodeSignature/CodeResources | 115 -- .../stlink_shield.xcodeproj/project.pbxproj | 50 - 20 files changed, 113 insertions(+), 1828 deletions(-) delete mode 100644 src/stlink-lib/usb.c.bak delete mode 100644 src/win32/unistd/unistd.h.bak delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/PkgInfo delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/_CodeSignature/CodeResources diff --git a/CHANGELOG.md b/CHANGELOG.md index 06f995d21..71188afb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,14 @@ # v1.7.1 -Release date: 2021-xx-xx +Release date: 2022-xx-xx This release drops support for some older operating systems. Check project README for details. -Updated system requirements: Raised minimum version for `cmake` to 3.7.2. + +Updated system requirements: +- `cmake` >= 3.10.2 +- `libusb` >= 1.0.21 +- `libgtk-dev` >= 3.22.30 Features: @@ -15,6 +19,9 @@ Features: - Expanded and revised list of chips ([#1145](https://github.com/stlink-org/stlink/pull/1145), [#1164](https://github.com/stlink-org/stlink/pull/1164)) - [STM32H72X/3X]: Added full access to all device memory ([#1158](https://github.com/stlink-org/stlink/pull/1158), [#1159](https://github.com/stlink-org/stlink/pull/1159)) - Added support for STM32WLEx ([#1173](https://github.com/stlink-org/stlink/pull/1173)) +- Added support for STLINK-V3 devices with no MSD ([#1185](https://github.com/stlink-org/stlink/pull/1185)) +- Updated gdb-server.c to allow external memory access on STM32H73xx ([#1196](https://github.com/stlink-org/stlink/pull/1196), [#1197](https://github.com/stlink-org/stlink/pull/1197)) +- Erase addr size / section of the flash memory with st-flash ([#1213](https://github.com/stlink-org/stlink/pull/1213)) Updates & changes: @@ -22,10 +29,12 @@ Updates & changes: - Added instructions for bug-reports and feature-requests to contribution guidelines ([#906](https://github.com/stlink-org/stlink/pull/906)) - Added travis CI configuration for macOS 10.14 to maintain capability for 32-bit compilation ([#f5ada94](https://github.com/stlink-org/stlink/commit/f5ada9474cdb87ff37de0d4eb9e75622b5870646)) - Updated description of chip id 0x0457 to L01x/L02x ([#1143](https://github.com/stlink-org/stlink/pull/1143), [#1144](https://github.com/stlink-org/stlink/pull/1144)) -- Drop execute bits from source code files ([#1167](https://github.com/stlink-org/stlink/pull/1167)) +- Dropped execute bits from source code files ([#1167](https://github.com/stlink-org/stlink/pull/1167)) - Use proper Markdown headers for supported MCUs ([#1168](https://github.com/stlink-org/stlink/pull/1168)) - Removed redundant array ([#1178](https://github.com/stlink-org/stlink/pull/1178)) - Updated chip config files from the library structs ([#1181](https://github.com/stlink-org/stlink/pull/1181)) +- [doc] Corrected file path in tutorial ([#1186](https://github.com/stlink-org/stlink/pull/1186)) +- Improved chipid checks and printouts ([#1188](https://github.com/stlink-org/stlink/pull/1188)) Fixes: - cmake: Install shared libraries in proper directories ([#1142](https://github.com/stlink-org/stlink/pull/1142)) @@ -41,6 +50,9 @@ Fixes: - Fixed few warnings for msvc about type conversion with possible lost data ([#1179](https://github.com/stlink-org/stlink/pull/1179)) - st-flash and other utilities search for chip files in the wrong directory ([#1180](https://github.com/stlink-org/stlink/pull/1180), commit [#c8fc656](https://github.com/stlink-org/stlink/commit/c8fc6561fead79ad49c09d82bab864745086792c)) - Fixed broken build on 32 bit systems ([#985](https://github.com/stlink-org/stlink/pull/985), [#1175](https://github.com/stlink-org/stlink/pull/1175), commit [#c8fc656](https://github.com/stlink-org/stlink/commit/c8fc6561fead79ad49c09d82bab864745086792c)) +- Define 'SSIZE_MAX' if not defined ([#1183](https://github.com/stlink-org/stlink/pull/1183)) +- Fixed compliation for OpenBSD 7.0 ([#1202](https://github.com/stlink-org/stlink/pull/1202)) +- Included 'SSIZE_MAX' from 'limits.h' in 'src/common.c' ([#1207](https://github.com/stlink-org/stlink/pull/1207)) # v1.7.0 diff --git a/README.md b/README.md index 7f797a7d9..bc491189e 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ It supports several so called STLINK programmer boards (and clones thereof) whic - stand-alone programmer (STLINK-V3SET, STLINK-V3MINI, STLINK-V3MODS) - on-board on some STM32 Nucleo boards (STLINK-V3E) -_\*)_ **Note: Support for the STLINK/V1 on macOS is limited to 10.14 - 10.15. Due to the deprecation and removal of macOS Kernel Extensions (KEXT) there will be no support for this programmer on macOS 11 or any later version.** +_\*)_ *Note: Support for the STLINK/V1 on macOS is limited to 10.15. Due to the deprecation and removal of macOS Kernel Extensions (KEXT) there will be no support for this programmer on macOS 11 or any later version.* On the user level there is no difference in handling or operation between these different revisions. diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index cd52026f5..bc04f848d 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -72,7 +72,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to if (WIN32 AND NOT EXISTS "/etc/debian_version") # Skip this for Debian... # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.24) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake index acd5630fa..587ff5fb5 100644 --- a/cmake/packaging/cpack_config.cmake +++ b/cmake/packaging/cpack_config.cmake @@ -53,7 +53,7 @@ elseif (EXISTS "/etc/debian_version" AND NOT EXISTS WIN32) # Package-build is av set(CPACK_DEBIAN_PACKAGE_RELEASE "1") # CPACK_DEBIAN_PACKAGE_ARCHITECTURE --> Default: Output of dpkg --print-architecture - set(CPACK_DEBIAN_PACKAGE_DEPENDS "pkg-config, build-essential, debhelper (>=9), cmake (>= 3.4.2), libusb-1.0-0-dev (>= 1.0.20)") + set(CPACK_DEBIAN_PACKAGE_DEPENDS "pkg-config, build-essential, debhelper (>=9), cmake (>= 3.10.2), libusb-1.0-0-dev (>= 1.0.21)") set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Nightwalker-87 ") # CPACK_DEBIAN_PACKAGE_DESCRIPTION --> Default: CPACK_DEBIAN_PACKAGE_DESCRIPTION (as it is set) # CPACK_DEBIAN_PACKAGE_SECTION --> Default: “devel” diff --git a/cmake/packaging/deb/control b/cmake/packaging/deb/control index ef51a6cea..7c8d13e47 100644 --- a/cmake/packaging/deb/control +++ b/cmake/packaging/deb/control @@ -1,7 +1,7 @@ Source: stlink Priority: optional Maintainer: Nightwalker-87 -Build-Depends: cmake, dh-cmake, debhelper (>= 9), libusb-1.0-0-dev, libgtk-3-dev +Build-Depends: cmake (>= 3.10.2), dh-cmake, debhelper (>= 9), libusb-1.0-0-dev (>= 1.0.21), libgtk-3-dev (>= 3.22.30) Standards-Version: 4.5.0 Rules-Requires-Root: no Section: electronics diff --git a/contributors.txt b/contributors.txt index bcaa0b538..cffef89f6 100644 --- a/contributors.txt +++ b/contributors.txt @@ -7,6 +7,8 @@ Andrea Mucignat Andrew Andrianov [necromant] Andrey Yurovsky Andy Isaacson +Andreas Sandberg [andysan] +Antoine Faure [antoinefaure] Anton [Ant-ON] Áron Radics A. Sheaff @@ -24,6 +26,7 @@ Chris Samuelson Christian Deussen [nullsub] Christophe Levantis Craig Lilley +Crest [Crest] Dan Dev Dan Hepler Daniel Campoverde [alx741] diff --git a/doc/compiling.md b/doc/compiling.md index eef207f95..0931c278a 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -7,7 +7,7 @@ On Windows users should ensure that the following software is installed: - `git` (_optional, but recommended_) -- `cmake` (3.17.0 or later) +- `cmake` - `MinGW-w64` (7.0.0 or later) with GCC toolchain 8.1.0 ### Installation @@ -95,7 +95,7 @@ Install the following packages from your package repository: - `git` - `gcc` or `clang` or `mingw32-gcc` or `mingw64-gcc` (C-compiler; very likely gcc is already present) - `build-essential` (on Debian based distros (Debian, Ubuntu)) -- `cmake` (3.4.2 or later, use the latest version available from the repository) +- `cmake` - `rpm` (on Debian based distros (Debian, Ubuntu), needed for package build with `make package`) - `libusb-1.0` - `libusb-1.0-0-dev` (development headers for building) diff --git a/doc/version_support.md b/doc/version_support.md index 2c5df7461..d7ba5c102 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -1,97 +1,104 @@ -_Source:_ pkgs.org - [libusb](https://pkgs.org/search/?q=libusb); [cmake](https://pkgs.org/search/?q=cmake); [gtk](https://pkgs.org/search/?q=gtk) (as of May 2021) +_Source:_ [pkgs.org](https://pkgs.org/search) - libusb, cmake, gtk, libgtk) (as of Jan 2022) ## Supported Operating Systems ### Microsoft Windows -On Windows users should ensure that cmake 3.20.2 or any later version is installed.
      -Up on compiling c-make will **automatically** download and install the latest compatible version of `libusb` (1.0.23 at the time of writing). +On Windows users should ensure that cmake **3.10.2** or any later version is installed.
      +Up on compiling c-make will **automatically** download and install the latest compatible version of `libusb`. - Windows 10 - Windows 8.1 ### Apple macOS -| Package Repository | libusb
      version | cmake
      version | gtk-3
      version | Supported macOS versions | -| ------------------ | ------------------- | ------------------ | ------------------ | ------------------------ | -| homebrew | 1.0.24 | 3.20.2 | 3.24.29
      gtk+3 | 10.9 - 11.x | -| MacPorts | 1.0.24 | 3.20.2 | 3.24.29
      gtk3 | 10.4 - 11.x | +| Package Repository | libusb | cmake | gtk-3-dev | Supported macOS versions | +| ------------------ | ------ | ------ | ------------------ | ------------------------ | +| homebrew | 1.0.24 | 3.22.1 | 3.24.30
      gtk+3 | **10.10 - 12.x** | +| MacPorts | 1.0.24 | 3.22.1 | 3.24.31
      gtk3 | **10.4 - 12.x** | -NOTE: In order to use a STLINK/V1 programmer on macOS, versions 10.14 or 10.15 are required. +NOTE: In order to use a STLINK/V1 programmer on macOS, version 10.15 is required. ### Linux-/Unix-based: -| Operating System | libusb | cmake | gtk-3 | Notes | -| ------------------------- | -------------------------------- | --------- | ----------- | ------------------------ | -| Debian Sid | 1.0.24 | 3.18.4 | 3.24.24 | | -| Debian 11 (Bullseye) | 1.0.24 | 3.18.4 | 3.24.24 | | -| Debian 10 (Buster) | 1.0.**22** | 3.13.4 | 3.24.**5** | | -| Debian 9 (Stretch) | 1.0.**21** | **3.7.2** | **3.22.11** | End of Support: Jun 2022 | -| | | | | | -| Ubuntu 21.04 (Hirsute) | 1.0.24 | 3.18.4 | 3.24.25 | End of Support: Jan 2022 | -| Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.16.3 | 3.24.**18** | | -| Ubuntu 18.04 LTS (Bionic) | 1.0.**21** | 3.10.2 | **3.22.30** | End of Support: Apr 2023 | -| | | | | | -| Fedora Rawhide [x64] | 1.0.24 (`libusbx`) | 3.20.2 | 3.24.29 | | -| Fedora 34 [x64] | 1.0.24 (`libusbx`) | 3.19.7 | 3.24.28 | | -| Fedora 33 [x64] | 1.0.23 (`libusbx`) | 3.18.3 | 3.24.23 | | -| | | | | | -| openSUSE Tumbleweed [x64] | 1.0.24 | 3.20.1 | 3.24.29 | | -| openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.17.0 | 3.24.20 | | -| openSUSE Leap 15.2 [x64] | 1.0.**21** | 3.17.0 | 3.24.**14** | End of Support: Dec 2021 | -| | | | | | -| Alpine 3.14 | 1.0.24 | 3.20.3 | 4.2.1 | | -| Alpine 3.13 | 1.0.24 | 3.18.4 | 3.24.23 | End of Support: Nov 2022 | -| Alpine 3.12 | 1.0.23 | 3.17.2 | 3.24.22 | End of Support: May 2022 | -| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.**13** | End of Support: Nov 2021 | -| | | | | | -| FreeBSD 13.x | 1.0.**16 - 18** (API 0x01000102) | 3.20.2 | 3.24.27 | | -| FreeBSD 12.x | 1.0.**16 - 18** (API 0x01000102) | 3.19.6 | 3.24.27 | | -| FreeBSD 11.x | 1.0.**16 - 18** (API 0x01000102) | 3.15.5 | 3.24.27 | End of Support: Sep 2021 | -| | | | | | -| Arch Linux | 1.0.24 | 3.20.2 | 3.24.29 | | -| KaOS [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | -| Mageia Cauldron | 1.0.24 | 3.20.2 | 3.24.29 | | -| OpenMandriva Cooker | 1.0.24 | 3.20.2 | 3.24.29 | | -| PCLinuxOS [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | -| Slackware Current | 1.0.24 | 3.20.2 | 3.24.28 | | -| Solus [x64] | 1.0.24 | 3.20.2 | 3.24.29 | | -| ALT Linux Sisyphus | 1.0.24 | 3.19.7 | 3.24.29 | | -| NetBSD 9.x | 1.0.24 | 3.19.7 | 3.24.27 | | -| NetBSD 8.x | 1.0.24 | 3.19.7 | 3.24.27 | | -| OpenMandriva Lx 4.2 | 1.0.24 | 3.19.3 | 3.24.24 | | -| Mageia 8 | 1.0.24 | 3.19.2 | 3.24.24 | End of Support: Aug 2022 | -| CentOS 8 Stream [x64] | 1.0.23 (`libusbx`) | 3.18.2 | **3.22.30** | | -| Adélie 1.0 | 1.0.23 | 3.16.4 | 3.24.23 | | -| ALT Linux P9 | 1.0.**22** | 3.16.3 | 3.24.**11** | | -| AlmaLinux 8 | 1.0.23 (`libusbx`) | 3.11.4 | 3.24.32 | | -| CentOS 8 [x64] | 1.0.23 (`libusbx`) | 3.11.4 | **3.22.30** | End of Support: Dec 2021 | +| Operating System | libusb | cmake | libgtk-dev | Notes | +| ------------------------- | ------------------------------ | ---------- | ----------- | ------------------------ | +| Debian Sid | 1.0.24 | 3.22.1 | 3.24.31 | | +| Debian 11 (Bullseye) | 1.0.24 | 3.18.4 | 3.24.24 | | +| Debian 10 (Buster) | 1.0.**22** | **3.13.4** | 3.24.**5** | | +| | | | | | +| Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.16.3 | 3.24.**18** | | +| Ubuntu 18.04 LTS (Bionic) | 1.0.**21** | **3.10.2** | 3.**22.30** | End of Support: Apr 2023 | +| | | | | | +| Fedora Rawhide [x64] | 1.0.24 | 3.22.3 | 3.24.31 | | +| Fedora 35 [x64] | 1.0.24 | 3.21.3 | 3.24.30 | | +| Fedora 34 [x64] | 1.0.24 (`libusbx`) | 3.19.7 | 3.24.28 | | +| | | | | | +| openSUSE Tumbleweed [x64] | 1.0.24 | 3.22.1 | 3.24.31 | | +| openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.17.0 | 3.24.20 | End of Support: Dec 2022 | +| | | | | | +| Alpine 3.15 | 1.0.24 | 3.21.3 | 3.24.30 | | +| Alpine 3.14 | 1.0.24 | 3.20.3 | 3.24.28 | | +| Alpine 3.13 | 1.0.24 | 3.18.4 | 3.24.23 | End of Support: Nov 2022 | +| Alpine 3.12 | 1.0.23 | 3.17.2 | 3.24.22 | End of Support: May 2022 | +| | | | | | +| FreeBSD 13.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | +| FreeBSD 12.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | +| | | | | | +| NetBSD 9.x | 1.0.24 | 3.21.2 | 3.24.30 | | +| NetBSD 8.x | 1.0.24 | 3.19.7 | 3.24.27 | | +| | | | | | +| CentOS 9 Stream [x64] | 1.0.24 (`libusbx`) | 3.20.3 | 3.24.30 | | +| CentOS 8 Stream [x64] | 1.0.23 (`libusbx`) | 3.20.2 | 3.**22.30** | | +| | | | | | +| ALT Linux Sisyphus | 1.0.24 | 3.22.1 | 3.24.31 | | +| ALT Linux P10 | 1.0.24 | 3.20.5 | 3.24.31 | | +| ALT Linux P9 | 1.0.**22** | 3.16.3 | 3.24.29 | | +| | | | | | +| OpenMandriva Rolling | 1.0.24 | 3.22.1 | 3.24.31 | | +| OpenMandriva Cooker | 1.0.24 | 3.22.1 | 3.24.31 | | +| OpenMandriva Lx 4.2 | 1.0.24 | 3.19.3 | 3.24.24 | | +| | | | | | +| Arch Linux | 1.0.24 | 3.22.1 | - | | +| KaOS [x64] | 1.0.24 | 3.22.1 | 3.24.31 | | +| Mageia Cauldron | 1.0.24 | 3.22.1 | 3.24.31 | | +| PCLinuxOS [x64] | ? | 3.22.1 | 3.24.31 | | +| Solus [x64] | 1.0.24 | 3.22.1 | 3.24.30 | | +| Void Linux | 1.0.24 | 3.22.1 | 3.24.31 | | +| Slackware Current | 1.0.24 | 3.21.4 | 3.24.31 | | +| AlmaLinux 8 | 1.0.23 (`libusbx`) | 3.20.2 | 3.**22.30** | | +| Rocky Linux 8 [x64] | 1.0.23 | 3.20.2 | 3.**22.30** | | +| Mageia 8 | 1.0.24 | 3.19.2 | 3.24.24 | End of Support: Aug 2022 | +| Adélie 1.0 | 1.0.23 | 3.16.4 | 3.24.23 | | ## Unsupported Operating Systems (as of Release v1.7.1) Systems with highlighted versions remain compatible with this toolset. -| Operating System | libusb | cmake | End of
      OS-Support | -| ------------------------- | ---------------------- | ---------- | ---------------------- | -| Fedora 32 [x64] | **1.0.23** (`libusbx`) | **3.17.0** | May 2021 | -| Ubuntu 20.10 (Groovy) | **1.0.23** | **3.16.3** | Jul 2021 | -| NetBSD 7.x | **1.0.22** | **3.16.1** | Jun 2020 | -| Alpine 3.10 | **1.0.22** | **3.14.5** | May 2021 | -| Fedora 31 [x64] | **1.0.22** (`libusbx`) | **3.14.5** | Nov 2020 | -| Mageia 7.1 | **1.0.22** | **3.14.3** | Jun 2021 | -| Fedora 30 | **1.0.22** (`libusbx`) | **3.14.2** | May 2020 | -| Ubuntu 19.10 (Eoan) | **1.0.23** | **3.13.4** | Jul 2020 | -| Alpine 3.9 | **1.0.22** | **3.13.0** | Jan 2021 | -| openSUSE Leap 15.1 [x64] | **1.0.21** | **3.10.2** | Jan 2021 | -| Slackware 14.2 | 1.0.20 | 3.5.2 | | -| Ubuntu 16.04 LTS (Xenial) | 1.0.20 | 3.5.1 | Apr 2021 | -| OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | | -| Debian 8 (Jessie) | 1.0.19 | 3.0.2 | Jun 2020 | -| CentOS 7 [x64] | 1.0.21 (`libusbx`) | 2.8.12.2 | Jun 2024 | -| Ubuntu 14.04 LTS (Trusty) | 1.0.17 | 2.8.12.2 | Apr 2019 | -| CentOS 6 | 1.0.9 (`libusbx`) | 2.8.12.2 | Nov 2020 | -| Slackware 14.1 | 1.0.9 | 2.8.12 | | -| Slackware 14.0 | 1.0.9 | 2.8.8 | | +| Operating System | libusb | cmake | End of
      OS-Support | +| ------------------------ | ------------------------------ | ---------- | ---------------------- | +| CentOS 8 [x64] | 1.0.**23** (`libusbx`) | 3.**20.3** | Dec 2021 | +| Ubuntu 21.04 (Hirsute) | 1.0.**24** | 3.**18.4** | Jan 2022 | +| Fedora 33 [x64] | 1.0.**23** (`libusbx`) | 3.**18.3** | Nov 2021 | +| Fedora 32 [x64] | 1.0.**23** (`libusbx`) | 3.**17.0** | May 2021 | +| openSUSE Leap 15.2 [x64] | 1.0.**21** | 3.**17.0** | Dec 2021 | +| Ubuntu 20.10 (Groovy) | 1.0.**23** | 3.**16.3** | Jul 2021 | +| NetBSD 7.x | 1.0.**22** | 3.**16.1** | Jun 2020 | +| Alpine 3.11 | 1.0.**23** | 3.**15.5** | Nov 2021 | +| FreeBSD 11.x | 1.0.**16-18** (API 0x01000102) | 3.**15.5** | Sep 2021 | +| Alpine 3.10 | 1.0.**22** | 3.**14.5** | May 2021 | +| Fedora 31 [x64] | 1.0.**22**(`libusbx`) | 3.**14.5** | Nov 2020 | +| Mageia 7.1 | 1.0.**22** | 3.**14.3** | Jun 2021 | +| Fedora 30 | 1.0.**22**(`libusbx`) | 3.**14.2** | May 2020 | +| Ubuntu 19.10 (Eoan) | 1.0.**23** | 3.**13.4** | Jul 2020 | +| Alpine 3.9 | 1.0.**22** | 3.**13.0** | Jan 2021 | +| openSUSE Leap 15.1 [x64] | 1.0.**21** | 3.**10.2** | Jan 2021 | +| Debian 9 (Stretch) | 1.0.**21** | 3.7.2 | Jun 2022 | +| Slackware 14.2 | 1.0.20 | 3.5.2 | | +| OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | | +| CentOS 7 [x64] | 1.0.**21** (`libusbx`) | 2.8.12.2 | Jun 2024 | +| Slackware 14.1 | 1.0.9 | 2.8.12 | | +| Slackware 14.0 | 1.0.9 | 2.8.8 | | _All other operating systems which are not listed are unsupported._ diff --git a/inc/stlink.h b/inc/stlink.h index 7dfd8a71e..17601fda8 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -1,6 +1,7 @@ /* * File: stlink.h + * * This should contain all the common top level stlink interfaces, * regardless of how the backend does the work.... */ @@ -184,7 +185,7 @@ enum run_type { typedef struct _stlink stlink_t; -#include // Is it really need? +#include #include struct _stlink { diff --git a/inc/stm32.h b/inc/stm32.h index 19ba3fca0..473f65a56 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -149,11 +149,11 @@ enum stm32_chipids { /* ============ */ /* Constant STM32 memory address */ -#define STM32_SRAM_BASE ((uint32_t)0x20000000) -#define STM32_FLASH_BASE ((uint32_t)0x08000000) +#define STM32_SRAM_BASE ((uint32_t)0x20000000) +#define STM32_FLASH_BASE ((uint32_t)0x08000000) -#define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) -#define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) +#define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) +#define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) #define STM32F0_DBGMCU_CR 0xE0042004 #define STM32F0_DBGMCU_CR_IWDG_STOP 8 diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index f8e1b3444..1eae2cc34 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -4,8 +4,7 @@ #include #include - -/** Chipid parameters */ +/* Chipid parametres */ struct stlink_chipid_params { char *dev_type; char *ref_manual_id; diff --git a/src/stlink-lib/usb.c.bak b/src/stlink-lib/usb.c.bak deleted file mode 100644 index 32ceff71f..000000000 --- a/src/stlink-lib/usb.c.bak +++ /dev/null @@ -1,1410 +0,0 @@ -#include -#include -#include -#include -#include - -#if !defined(_MSC_VER) -#include -#endif - -#include -#include -#include - -#if defined(_WIN32) -#include -#endif - -#include -#include -#include "usb.h" - -enum SCSI_Generic_Direction {SG_DXFER_TO_DEV = 0, SG_DXFER_FROM_DEV = 0x80}; - -static inline uint32_t le_to_h_u32(const uint8_t* buf) { - return((uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24)); -} - -static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, uint32_t khz) { - unsigned int i; - int speed_index = -1; - int speed_diff = INT_MAX; - int last_valid_speed = -1; - bool match = true; - - for (i = 0; i < map_size; i++) { - if (!map[i]) { continue; } - - last_valid_speed = i; - - if (khz == map[i]) { - speed_index = i; - break; - } else { - int current_diff = khz - map[i]; - // get abs value for comparison - current_diff = (current_diff > 0) ? current_diff : -current_diff; - - if (current_diff < speed_diff) { - speed_diff = current_diff; - speed_index = i; - } - } - } - - if (speed_index == -1) { - // This will only be here if we cannot match the slow speed. - // Use the slowest speed we support. - speed_index = last_valid_speed; - match = false; - } else if (i == map_size) { - match = false; - } - - if (!match) { - ILOG("Unable to match requested speed %d kHz, using %d kHz\n", khz, map[speed_index]); - } - - return(speed_index); -} - -void _stlink_usb_close(stlink_t* sl) { - if (!sl) { return; } - - struct stlink_libusb * const handle = sl->backend_data; - - // maybe we couldn't even get the usb device? - if (handle != NULL) { - if (handle->usb_handle != NULL) { libusb_close(handle->usb_handle); } - - libusb_exit(handle->libusb_ctx); - free(handle); - } -} - -ssize_t send_recv(struct stlink_libusb* handle, int terminate, - unsigned char* txbuf, size_t txsize, unsigned char* rxbuf, - size_t rxsize, int check_error, const char *cmd) { - // Note: txbuf and rxbuf can point to the same area - int res, t, retry = 0; - - while (1) { - res = 0; - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, (int)txsize, &res, 3000); - - if (t) { - ELOG("%s send request failed: %s\n", cmd, libusb_error_name(t)); - return(-1); - } else if ((size_t)res != txsize) { - ELOG("%s send request wrote %u bytes, instead of %u\n", - cmd, (unsigned int)res, (unsigned int)txsize); - } - - if (rxsize != 0) { - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int)rxsize, &res, 3000); - - if (t) { - ELOG("%s read reply failed: %s\n", cmd, libusb_error_name(t)); - return(-1); - } - - /* Checking the command execution status stored in the first byte of the response */ - if (handle->protocoll != 1 && check_error >= CMD_CHECK_STATUS && - rxbuf[0] != STLINK_DEBUG_ERR_OK) { - switch(rxbuf[0]) { - case STLINK_DEBUG_ERR_AP_WAIT: - case STLINK_DEBUG_ERR_DP_WAIT: - if (check_error == CMD_CHECK_RETRY && retry < 3) { - unsigned int delay_us = (1<protocoll == 1) && terminate) { - // read the SG reply - unsigned char sg_buf[13]; - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, sg_buf, 13, &res, 3000); - - if (t) { - ELOG("%s read storage failed: %s\n", cmd, libusb_error_name(t)); - return(-1); - } - - // The STLink doesn't seem to evaluate the sequence number. - handle->sg_transfer_idx++; - } - - return(res); - } -} - -static inline int send_only(struct stlink_libusb* handle, int terminate, - unsigned char* txbuf, size_t txsize, - const char *cmd) { - return((int)send_recv(handle, terminate, txbuf, txsize, NULL, 0, CMD_CHECK_NO, cmd)); -} - - -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); -} - -int _stlink_usb_version(stlink_t *sl) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const data = sl->q_buf; - unsigned char* const cmd = sl->c_buf; - ssize_t size; - uint32_t rep_len; - int i; - - if (sl->version.stlink_v == 3) { - // STLINK-V3 version is determined by another command - rep_len = 12; - i = fill_command(sl, SG_DXFER_FROM_DEV, 16); - cmd[i++] = STLINK_GET_VERSION_APIV3; - } else { - rep_len = 6; - i = fill_command(sl, SG_DXFER_FROM_DEV, 6); - cmd[i++] = STLINK_GET_VERSION; - } - - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_REP_LEN, "GET_VERSION"); - - return(size<0?-1:0); -} - -int32_t _stlink_usb_target_voltage(stlink_t *sl) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const rdata = sl->q_buf; - unsigned char* const cmd = sl->c_buf; - ssize_t size; - uint32_t rep_len = 8; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - uint32_t factor, reading; - int voltage; - - cmd[i++] = STLINK_GET_TARGET_VOLTAGE; - - size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, CMD_CHECK_REP_LEN, "GET_TARGET_VOLTAGE"); - - if (size < 0) { - return(-1); - } - - factor = (rdata[3] << 24) | (rdata[2] << 16) | (rdata[1] << 8) | (rdata[0] << 0); - reading = (rdata[7] << 24) | (rdata[6] << 16) | (rdata[5] << 8) | (rdata[4] << 0); - voltage = 2400 * reading / factor; - - return(voltage); -} - -int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const rdata = sl->q_buf; - unsigned char* const cmd = sl->c_buf; - ssize_t size; - const int rep_len = 8; - - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_APIV2_READDEBUGREG; - write_uint32(&cmd[i], addr); - size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, CMD_CHECK_RETRY, "READDEBUGREG"); - - if (size < 0) { - return(-1); - } - - *data = read_uint32(rdata, 4); - - return(0); -} - -int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const rdata = sl->q_buf; - unsigned char* const cmd = sl->c_buf; - ssize_t size; - const int rep_len = 2; - - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_APIV2_WRITEDEBUGREG; - write_uint32(&cmd[i], addr); - write_uint32(&cmd[i + 4], data); - size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, CMD_CHECK_RETRY, "WRITEDEBUGREG"); - - return(size<0?-1:0); -} - -int _stlink_usb_get_rw_status(stlink_t *sl) { - if (sl->version.jtag_api == STLINK_JTAG_API_V1) { return(0); } - - unsigned char* const rdata = sl->q_buf; - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const cmd = sl->c_buf; - int i; - int16_t ret = 0; - - i = fill_command(sl, SG_DXFER_FROM_DEV, 12); - cmd[i++] = STLINK_DEBUG_COMMAND; - - if (sl->version.flags & STLINK_F_HAS_GETLASTRWSTATUS2) { - cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS2; - ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 12, CMD_CHECK_STATUS, "GETLASTRWSTATUS2"); - } else { - cmd[i++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS; - ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 2, CMD_CHECK_STATUS, "GETLASTRWSTATUS"); - } - - return(ret<0?-1:0); -} - -int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const data = sl->q_buf; - unsigned char* const cmd = sl->c_buf; - int i, ret; - - 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); - ret = send_only(slu, 0, cmd, slu->cmd_len, "WRITEMEM_32BIT"); - - if (ret == -1) { return(ret); } - - ret = send_only(slu, 1, data, len, "WRITEMEM_32BIT"); - - if (ret == -1) { return(ret); } - - return(_stlink_usb_get_rw_status(sl)); -} - -int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const data = sl->q_buf; - unsigned char* const cmd = sl->c_buf; - int i, ret; - - if ((sl->version.jtag_api < STLINK_JTAG_API_V3 && len > 64) || - (sl->version.jtag_api >= STLINK_JTAG_API_V3 && len > 512)) { - ELOG("WRITEMEM_8BIT: bulk packet limits exceeded (data len %d byte)\n", len); - return (-1); - } - - 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); - ret = send_only(slu, 0, cmd, slu->cmd_len, "WRITEMEM_8BIT"); - - if (ret == -1) { return(ret); } - - ret = send_only(slu, 1, data, len, "WRITEMEM_8BIT"); - - if (ret == -1) { return(ret); } - - return(0); -} - - -int _stlink_usb_current_mode(stlink_t * sl) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const cmd = sl->c_buf; - unsigned char* const data = sl->q_buf; - ssize_t size; - 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, CMD_CHECK_NO, "GET_CURRENT_MODE"); - - if (size < 0) { - return(-1); - } - - return(sl->q_buf[0]); -} - -int _stlink_usb_core_id(stlink_t * sl) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const cmd = sl->c_buf; - unsigned char* const data = sl->q_buf; - ssize_t size; - int offset, rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 12; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - - cmd[i++] = STLINK_DEBUG_COMMAND; - - if (sl->version.jtag_api == STLINK_JTAG_API_V1) { - cmd[i++] = STLINK_DEBUG_READCOREID; - offset = 0; - } else { - cmd[i++] = STLINK_DEBUG_APIV2_READ_IDCODES; - offset = 4; - } - - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "READ_IDCODES"); - - if (size < 0) { - return(-1); - } - - sl->core_id = read_uint32(data, offset); - - return(0); -} - -int _stlink_usb_status_v2(stlink_t *sl) { - int result; - uint32_t status = 0; - - result = _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &status); - DLOG("core status: %08X\n", status); - - if (result != 0) { - sl->core_stat = TARGET_UNKNOWN; - } else { - if (status & STLINK_REG_DHCSR_C_HALT) { - sl->core_stat = TARGET_HALTED; - } else if (status & STLINK_REG_DHCSR_S_RESET_ST) { - sl->core_stat = TARGET_RESET; - } else { - sl->core_stat = TARGET_RUNNING; - } - } - - return(result); -} - -int _stlink_usb_status(stlink_t * sl) { - if (sl->version.jtag_api != STLINK_JTAG_API_V1) { return(_stlink_usb_status_v2(sl)); } - - struct stlink_libusb * const slu = sl->backend_data; - 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); - - cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_GETSTATUS; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_NO, "GETSTATUS"); - - if (size > 1) { - if (sl->q_buf[0] == STLINK_CORE_RUNNING) { - sl->core_stat = TARGET_RUNNING; - } else if (sl->q_buf[0] == STLINK_CORE_HALTED) { - sl->core_stat = TARGET_HALTED; - } else { - sl->core_stat = TARGET_UNKNOWN; - } - } else { - sl->core_stat = TARGET_UNKNOWN; - } - - return(size<0?-1:0); -} - -int _stlink_usb_force_debug(stlink_t *sl) { - struct stlink_libusb *slu = sl->backend_data; - - int res; - - if (sl->version.jtag_api != STLINK_JTAG_API_V1) { - res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_DEBUGEN); - return(res); - } - - 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); - - cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_FORCEDEBUG; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "FORCEDEBUG"); - - return(size<0?-1:0); -} - -int _stlink_usb_enter_swd_mode(stlink_t * sl) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const cmd = sl->c_buf; - ssize_t size; - unsigned char* const data = sl->q_buf; - const uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 2; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - - cmd[i++] = STLINK_DEBUG_COMMAND; - // select correct API-Version for entering SWD mode: V1 API (0x20) or V2 API (0x30). - cmd[i++] = sl->version.jtag_api == STLINK_JTAG_API_V1 ? STLINK_DEBUG_APIV1_ENTER : STLINK_DEBUG_APIV2_ENTER; - cmd[i++] = STLINK_DEBUG_ENTER_SWD; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "ENTER_SWD"); - - return(size<0?-1:0); -} - -int _stlink_usb_exit_dfu_mode(stlink_t* sl) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const cmd = sl->c_buf; - ssize_t size; - int i = fill_command(sl, SG_DXFER_FROM_DEV, 0); - - cmd[i++] = STLINK_DFU_COMMAND; - cmd[i++] = STLINK_DFU_EXIT; - size = send_only(slu, 1, cmd, slu->cmd_len, "DFU_EXIT"); - - return(size<0?-1:0); -} - - -int _stlink_usb_reset(stlink_t * sl) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const data = sl->q_buf; - unsigned char* const cmd = sl->c_buf; - ssize_t size; - int i, rep_len = 2; - - // send reset command - i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - cmd[i++] = STLINK_DEBUG_COMMAND; - - if (sl->version.jtag_api == STLINK_JTAG_API_V1) { - cmd[i++] = STLINK_DEBUG_APIV1_RESETSYS; - } else { - cmd[i++] = STLINK_DEBUG_APIV2_RESETSYS; - } - - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "RESETSYS"); - - return(size<0?-1:0); -} - -int _stlink_usb_jtag_reset(stlink_t * sl, int value) { - struct stlink_libusb * const slu = sl->backend_data; - 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); - - cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_APIV2_DRIVE_NRST; - cmd[i++] = value; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "DRIVE_NRST"); - - return(size<0?-1:0); -} - - -int _stlink_usb_step(stlink_t* sl) { - struct stlink_libusb * const slu = sl->backend_data; - - if (sl->version.jtag_api != STLINK_JTAG_API_V1) { - // emulates the JTAG v1 API by using DHCSR - _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | - STLINK_REG_DHCSR_C_MASKINTS | STLINK_REG_DHCSR_C_DEBUGEN); - _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_STEP | - STLINK_REG_DHCSR_C_MASKINTS | STLINK_REG_DHCSR_C_DEBUGEN); - return _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | - STLINK_REG_DHCSR_C_DEBUGEN); - } - - 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); - - cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_STEPCORE; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "STEPCORE"); - - return(size<0?-1:0); -} - -/** - * This seems to do a good job of restarting things from the beginning? - * @param sl - * @param type - */ -int _stlink_usb_run(stlink_t* sl, enum run_type type) { - struct stlink_libusb * const slu = sl->backend_data; - - int res; - - if (sl->version.jtag_api != STLINK_JTAG_API_V1) { - res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, - STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | - ((type==RUN_FLASH_LOADER)?STLINK_REG_DHCSR_C_MASKINTS:0)); - return(res); - } - - - 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); - - cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_RUNCORE; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "RUNCORE"); - - return(size<0?-1:0); -} - -int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const data = sl->q_buf; - unsigned char* const cmd = sl->c_buf; - ssize_t size; - int rep_len = 2; - int i; - - // clock speed only supported by stlink/v2 and for firmware >= 22 - if (sl->version.stlink_v == 2 && sl->version.jtag_v >= 22) { - uint16_t clk_divisor; - if (clk_freq) { - const uint32_t map[] = {5, 15, 25, 50, 100, 125, 240, 480, 950, 1200, 1800, 4000}; - int speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), clk_freq); - switch (map[speed_index]) { - case 5: clk_divisor = STLINK_SWDCLK_5KHZ_DIVISOR; break; - case 15: clk_divisor = STLINK_SWDCLK_15KHZ_DIVISOR; break; - case 25: clk_divisor = STLINK_SWDCLK_25KHZ_DIVISOR; break; - case 50: clk_divisor = STLINK_SWDCLK_50KHZ_DIVISOR; break; - case 100: clk_divisor = STLINK_SWDCLK_100KHZ_DIVISOR; break; - case 125: clk_divisor = STLINK_SWDCLK_125KHZ_DIVISOR; break; - case 240: clk_divisor = STLINK_SWDCLK_240KHZ_DIVISOR; break; - case 480: clk_divisor = STLINK_SWDCLK_480KHZ_DIVISOR; break; - case 950: clk_divisor = STLINK_SWDCLK_950KHZ_DIVISOR; break; - case 1200: clk_divisor = STLINK_SWDCLK_1P2MHZ_DIVISOR; break; - default: - case 1800: clk_divisor = STLINK_SWDCLK_1P8MHZ_DIVISOR; break; - case 4000: clk_divisor = STLINK_SWDCLK_4MHZ_DIVISOR; break; - } - } else - clk_divisor = STLINK_SWDCLK_1P8MHZ_DIVISOR; - - i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - - cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_APIV2_SWD_SET_FREQ; - cmd[i++] = clk_divisor & 0xFF; - cmd[i++] = (clk_divisor >> 8) & 0xFF; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "SWD_SET_FREQ"); - - return(size<0?-1:0); - } else if (sl->version.stlink_v == 3) { - int speed_index; - uint32_t map[STLINK_V3_MAX_FREQ_NB]; - i = fill_command(sl, SG_DXFER_FROM_DEV, 16); - - cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_APIV3_GET_COM_FREQ; - cmd[i++] = 0; // SWD mode - size = send_recv(slu, 1, cmd, slu->cmd_len, data, 52, CMD_CHECK_STATUS, "GET_COM_FREQ"); - - if (size < 0) { - return(-1); - } - - int speeds_size = data[8]; - if (speeds_size > STLINK_V3_MAX_FREQ_NB) { - speeds_size = STLINK_V3_MAX_FREQ_NB; - } - - for (i = 0; i < speeds_size; i++) map[i] = le_to_h_u32(&data[12 + 4 * i]); - - // Set to zero all the next entries - for (i = speeds_size; i < STLINK_V3_MAX_FREQ_NB; i++) map[i] = 0; - - if (!clk_freq) clk_freq = 1000; // set default frequency - speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), clk_freq); - - i = fill_command(sl, SG_DXFER_FROM_DEV, 16); - - cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_APIV3_SET_COM_FREQ; - cmd[i++] = 0; // SWD mode - cmd[i++] = 0; - cmd[i++] = (uint8_t)((map[speed_index] >> 0) & 0xFF); - cmd[i++] = (uint8_t)((map[speed_index] >> 8) & 0xFF); - cmd[i++] = (uint8_t)((map[speed_index] >> 16) & 0xFF); - cmd[i++] = (uint8_t)((map[speed_index] >> 24) & 0xFF); - - size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8, CMD_CHECK_STATUS, "SET_COM_FREQ"); - - return(size<0?-1:0); - } else if (clk_freq) { - WLOG("ST-Link firmware does not support frequency setup\n"); - } - - return(-1); -} - -int _stlink_usb_exit_debug_mode(stlink_t *sl) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const cmd = sl->c_buf; - ssize_t size; - int i = fill_command(sl, SG_DXFER_FROM_DEV, 0); - - cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_EXIT; - - size = send_only(slu, 1, cmd, slu->cmd_len, "DEBUG_EXIT"); - - return(size<0?-1:0); -} - -int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - struct stlink_libusb * const slu = sl->backend_data; - 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); - - cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_READMEM_32BIT; - write_uint32(&cmd[i], addr); - write_uint16(&cmd[i + 4], len); - size = send_recv(slu, 1, cmd, slu->cmd_len, data, len, CMD_CHECK_NO, "READMEM_32BIT"); - - if (size < 0) { - return(-1); - } - - sl->q_len = (int)size; - stlink_print_data(sl); - - return(0); -} - -int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const cmd = sl->c_buf; - unsigned char* const data = sl->q_buf; - ssize_t size; - uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 84 : 88; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - - cmd[i++] = STLINK_DEBUG_COMMAND; - - if (sl->version.jtag_api == STLINK_JTAG_API_V1) { - cmd[i++] = STLINK_DEBUG_APIV1_READALLREGS; - } else { - cmd[i++] = STLINK_DEBUG_APIV2_READALLREGS; - } - - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "READALLREGS"); - - if (size < 0) { - return(-1); - } - - /* V1: regs data from offset 0 */ - /* V2: status at offset 0, regs data from offset 4 */ - int reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; - sl->q_len = (int)size; - stlink_print_data(sl); - - for (i = 0; i < 16; i++) regp->r[i] = read_uint32(sl->q_buf, reg_offset + i * 4); - - regp->xpsr = read_uint32(sl->q_buf, reg_offset + 64); - regp->main_sp = read_uint32(sl->q_buf, reg_offset + 68); - regp->process_sp = read_uint32(sl->q_buf, reg_offset + 72); - regp->rw = read_uint32(sl->q_buf, reg_offset + 76); - regp->rw2 = read_uint32(sl->q_buf, reg_offset + 80); - - if (sl->verbose < 2) { return(0); } - - DLOG("xpsr = 0x%08x\n", regp->xpsr); - DLOG("main_sp = 0x%08x\n", regp->main_sp); - DLOG("process_sp = 0x%08x\n", regp->process_sp); - DLOG("rw = 0x%08x\n", regp->rw); - DLOG("rw2 = 0x%08x\n", regp->rw2); - - return(0); -} - -int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const data = sl->q_buf; - unsigned char* const cmd = sl->c_buf; - ssize_t size; - uint32_t r; - uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 8; - int reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - - cmd[i++] = STLINK_DEBUG_COMMAND; - - if (sl->version.jtag_api == STLINK_JTAG_API_V1) { - cmd[i++] = STLINK_DEBUG_APIV1_READREG; - } else { - cmd[i++] = STLINK_DEBUG_APIV2_READREG; - } - - cmd[i++] = (uint8_t)r_idx; - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "READREG"); - - if (size < 0) { - return(-1); - } - - sl->q_len = (int)size; - stlink_print_data(sl); - r = read_uint32(sl->q_buf, reg_offset); - DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); - - switch (r_idx) { - case 16: - regp->xpsr = r; - break; - case 17: - regp->main_sp = r; - break; - case 18: - regp->process_sp = r; - break; - case 19: - regp->rw = r; // XXX ?(primask, basemask etc.) - break; - case 20: - regp->rw2 = r; // XXX ?(primask, basemask etc.) - break; - default: - regp->r[r_idx] = r; - } - - return(0); -} - -/* See section C1.6 of the ARMv7-M Architecture Reference Manual */ -int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { - uint32_t r; - int ret; - - sl->q_buf[0] = (unsigned char)r_idx; - - for (int i = 1; i < 4; i++) sl->q_buf[i] = 0; - - ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4); - - if (ret == -1) { return(ret); } - - ret = _stlink_usb_read_mem32(sl, STLINK_REG_DCRDR, 4); - - if (ret == -1) { return(ret); } - - r = read_uint32(sl->q_buf, 0); - DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); - - switch (r_idx) { - case 0x14: - regp->primask = (uint8_t)(r & 0xFF); - regp->basepri = (uint8_t)((r >> 8) & 0xFF); - regp->faultmask = (uint8_t)((r >> 16) & 0xFF); - regp->control = (uint8_t)((r >> 24) & 0xFF); - break; - case 0x21: - regp->fpscr = r; - break; - default: - regp->s[r_idx - 0x40] = r; - break; - } - - return(0); -} - -int _stlink_usb_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { - int ret; - - ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); - - if (ret == -1) { return(ret); } - - ret = _stlink_usb_read_unsupported_reg(sl, 0x21, regp); - - if (ret == -1) { return(ret); } - - for (int i = 0; i < 32; i++) { - ret = _stlink_usb_read_unsupported_reg(sl, 0x40 + i, regp); - - if (ret == -1) { return(ret); } - } - - return(0); -} - -/* See section C1.6 of the ARMv7-M Architecture Reference Manual */ -int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, struct stlink_reg *regp) { - int ret; - - if (r_idx >= 0x1C && r_idx <= 0x1F) { // primask, basepri, faultmask, or control - /* These are held in the same register */ - ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); - - if (ret == -1) { return(ret); } - - val = (uint8_t)(val >> 24); - - switch (r_idx) { - case 0x1C: /* control */ - val = (((uint32_t)val) << 24) | - (((uint32_t)regp->faultmask) << 16) | - (((uint32_t)regp->basepri) << 8) | - ((uint32_t)regp->primask); - break; - case 0x1D: /* faultmask */ - val = (((uint32_t)regp->control) << 24) | - (((uint32_t)val) << 16) | - (((uint32_t)regp->basepri) << 8) | - ((uint32_t)regp->primask); - break; - case 0x1E: /* basepri */ - val = (((uint32_t)regp->control) << 24) | - (((uint32_t)regp->faultmask) << 16) | - (((uint32_t)val) << 8) | - ((uint32_t)regp->primask); - break; - case 0x1F: /* primask */ - val = (((uint32_t)regp->control) << 24) | - (((uint32_t)regp->faultmask) << 16) | - (((uint32_t)regp->basepri) << 8) | - ((uint32_t)val); - break; - } - - r_idx = 0x14; - } - - write_uint32(sl->q_buf, val); - - ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRDR, 4); - - if (ret == -1) { return(ret); } - - sl->q_buf[0] = (unsigned char)r_idx; - sl->q_buf[1] = 0; - sl->q_buf[2] = 0x01; - sl->q_buf[3] = 0; - - return(_stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4)); -} - -int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const data = sl->q_buf; - unsigned char* const cmd = sl->c_buf; - ssize_t size; - uint32_t rep_len = 2; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - - cmd[i++] = STLINK_DEBUG_COMMAND; - - if (sl->version.jtag_api == STLINK_JTAG_API_V1) { - cmd[i++] = STLINK_DEBUG_APIV1_WRITEREG; - } else { - cmd[i++] = STLINK_DEBUG_APIV2_WRITEREG; - } - - cmd[i++] = idx; - write_uint32(&cmd[i], reg); - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "WRITEREG"); - - return(size<0?-1:0); -} - -int _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const data = sl->q_buf; - unsigned char* const cmd = sl->c_buf; - ssize_t size; - uint32_t rep_len = 2; - - int i = fill_command(sl, SG_DXFER_TO_DEV, rep_len); - cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_APIV2_START_TRACE_RX; - write_uint16(&cmd[i + 0], 2 * STLINK_TRACE_BUF_LEN); - write_uint32(&cmd[i + 2], frequency); - - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "START_TRACE_RX"); - - return(size<0?-1:0); -} - -int _stlink_usb_disable_trace(stlink_t* sl) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const data = sl->q_buf; - unsigned char* const cmd = sl->c_buf; - ssize_t size; - uint32_t rep_len = 2; - - int i = fill_command(sl, SG_DXFER_TO_DEV, rep_len); - cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_DEBUG_APIV2_STOP_TRACE_RX; - - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "STOP_TRACE_RX"); - - return(size<0?-1:0); -} - -int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { - struct stlink_libusb * const slu = sl->backend_data; - unsigned char* const data = sl->q_buf; - unsigned char* const cmd = sl->c_buf; - 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_APIV2_GET_TRACE_NB; - ssize_t send_size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_NO, "GET_TRACE_NB"); - - if (send_size < 0) { - return(-1); - } else if (send_size != 2) { - ELOG("STLINK_DEBUG_APIV2_GET_TRACE_NB reply size %d\n", (int)send_size); - return(-1); - } - - uint16_t trace_count = read_uint16(sl->q_buf, 0); - - if (trace_count > size) { - ELOG("read_trace insufficient buffer length\n"); - return -1; - } - - if (trace_count != 0) { - int res = 0; - int t = libusb_bulk_transfer(slu->usb_handle, slu->ep_trace, buf, trace_count, &res, 3000); - - if (t || res != (int)trace_count) { - ELOG("read_trace read error %d\n", t); - return(-1); - } - } - - return trace_count; -} - -static stlink_backend_t _stlink_usb_backend = { - _stlink_usb_close, - _stlink_usb_exit_debug_mode, - _stlink_usb_enter_swd_mode, - NULL, // don't enter_jtag_mode here... - _stlink_usb_exit_dfu_mode, - _stlink_usb_core_id, - _stlink_usb_reset, - _stlink_usb_jtag_reset, - _stlink_usb_run, - _stlink_usb_status, - _stlink_usb_version, - _stlink_usb_read_debug32, - _stlink_usb_read_mem32, - _stlink_usb_write_debug32, - _stlink_usb_write_mem32, - _stlink_usb_write_mem8, - _stlink_usb_read_all_regs, - _stlink_usb_read_reg, - _stlink_usb_read_all_unsupported_regs, - _stlink_usb_read_unsupported_reg, - _stlink_usb_write_unsupported_reg, - _stlink_usb_write_reg, - _stlink_usb_step, - _stlink_usb_current_mode, - _stlink_usb_force_debug, - _stlink_usb_target_voltage, - _stlink_usb_set_swdclk, - _stlink_usb_enable_trace, - _stlink_usb_disable_trace, - _stlink_usb_read_trace -}; - -/* return the length of serial or (0) in case of errors */ -size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_descriptor *desc, char *serial) { - unsigned char desc_serial[(STLINK_SERIAL_LENGTH) * 2]; - - /* truncate the string in the serial buffer */ - serial[0] = '\0'; - - /* get the LANGID from String Descriptor Zero */ - int ret = libusb_get_string_descriptor(handle, 0, 0, desc_serial, sizeof(desc_serial)); - if (ret < 4) return 0; - - uint32_t langid = desc_serial[2] | (desc_serial[3] << 8); - - /* get the serial */ - ret = libusb_get_string_descriptor(handle, desc->iSerialNumber, langid, desc_serial, - sizeof(desc_serial)); - if (ret < 0) return 0; // could not read serial - - unsigned char len = desc_serial[0]; - - if (len == ((STLINK_SERIAL_LENGTH + 1) * 2)) { /* len == 50 */ - /* good ST-Link adapter */ - ret = libusb_get_string_descriptor_ascii( - handle, desc->iSerialNumber, (unsigned char *)serial, STLINK_SERIAL_BUFFER_SIZE); - if (ret < 0) return 0; - } else if (len == ((STLINK_SERIAL_LENGTH / 2 + 1) * 2)) { /* len == 26 */ - /* fix-up the buggy serial */ - for (unsigned int i = 0; i < STLINK_SERIAL_LENGTH; i += 2) - sprintf(serial + i, "%02X", desc_serial[i + 2]); - serial[STLINK_SERIAL_LENGTH] = '\0'; - } else { - return 0; - } - - return strlen(serial); -} - -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq) { - stlink_t* sl = NULL; - struct stlink_libusb* slu = NULL; - int ret = -1; - int config; - - sl = calloc(1, sizeof(stlink_t)); - if (sl == NULL) { goto on_malloc_error; } - - slu = calloc(1, sizeof(struct stlink_libusb)); - if (slu == NULL) { goto on_malloc_error; } - - ugly_init(verbose); - sl->backend = &_stlink_usb_backend; - sl->backend_data = slu; - - sl->core_stat = TARGET_UNKNOWN; - - if (libusb_init(&(slu->libusb_ctx))) { - WLOG("failed to init libusb context, wrong version of libraries?\n"); - goto on_error; - } - -#if LIBUSB_API_VERSION < 0x01000106 - libusb_set_debug(slu->libusb_ctx, ugly_libusb_log_level(verbose)); -#else - libusb_set_option(slu->libusb_ctx, LIBUSB_OPTION_LOG_LEVEL, ugly_libusb_log_level(verbose)); -#endif - - libusb_device **list = NULL; - // TODO: We should use ssize_t and use it as a counter if > 0. - // As per libusb API: ssize_t libusb_get_device_list (libusb_context *ctx, libusb_device ***list) - ssize_t cnt = libusb_get_device_list(slu->libusb_ctx, &list); - struct libusb_device_descriptor desc; - - while (cnt-- > 0) { - struct libusb_device_handle *handle; - - libusb_get_device_descriptor(list[cnt], &desc); - - if (desc.idVendor != STLINK_USB_VID_ST) { continue; } - - ret = libusb_open(list[cnt], &handle); - - if (ret) { continue; } // could not open device - - size_t serial_len = stlink_serial(handle, &desc, sl->serial); - - libusb_close(handle); - - if (serial_len != STLINK_SERIAL_LENGTH) { continue; } // could not read the serial - - // if no serial provided, or if serial match device, fixup version and protocol - if (((serial == NULL) || (*serial == 0)) || (memcmp(serial, &sl->serial, STLINK_SERIAL_LENGTH) == 0)) { - if (STLINK_V1_USB_PID(desc.idProduct)) { - slu->protocoll = 1; - sl->version.stlink_v = 1; - } else if (STLINK_V2_USB_PID(desc.idProduct) || STLINK_V2_1_USB_PID(desc.idProduct)) { - sl->version.stlink_v = 2; - } else if (STLINK_V3_USB_PID(desc.idProduct)) { - sl->version.stlink_v = 3; - } - - break; - } - } - - if (cnt < 0) { - WLOG ("Couldn't find any ST-Link devices\n"); - libusb_free_device_list(list, 1); - goto on_error; - } else { - ret = libusb_open(list[cnt], &slu->usb_handle); - - if (ret != 0) { - WLOG("Error %d (%s) opening ST-Link v%d device %03d:%03d\n", ret, - strerror(errno), - sl->version.stlink_v, - libusb_get_bus_number(list[cnt]), - libusb_get_device_address(list[cnt])); - libusb_free_device_list(list, 1); - goto on_error; - } - } - - libusb_free_device_list(list, 1); - -// libusb_kernel_driver_active is not available on Windows. -#if !defined(_WIN32) - if (libusb_kernel_driver_active(slu->usb_handle, 0) == 1) { - ret = libusb_detach_kernel_driver(slu->usb_handle, 0); - - if (ret < 0) { - WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-ret)); - goto on_libusb_error; - } - } -#endif - - if (libusb_get_configuration(slu->usb_handle, &config)) { - // this may fail for a previous configured device - WLOG("libusb_get_configuration()\n"); - goto on_libusb_error; - } - - if (config != 1) { - printf("setting new configuration (%d -> 1)\n", config); - - if (libusb_set_configuration(slu->usb_handle, 1)) { - // this may fail for a previous configured device - WLOG("libusb_set_configuration() failed\n"); - goto on_libusb_error; - } - } - - if (libusb_claim_interface(slu->usb_handle, 0)) { - WLOG("Stlink usb device found, but unable to claim (probably already in use?)\n"); - goto on_libusb_error; - } - - // TODO: Could use the scanning technique from STM8 code here... - slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; - - if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO || - desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO || - desc.idProduct == STLINK_USB_PID_STLINK_V2_1 || - desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER || - desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID || - desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID || - desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID || - desc.idProduct == STLINK_USB_PID_STLINK_V3_NO_MSD_PID) { - slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; - slu->ep_trace = 2 | LIBUSB_ENDPOINT_IN; - } else { - slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; - slu->ep_trace = 3 | LIBUSB_ENDPOINT_IN; - } - - slu->sg_transfer_idx = 0; - slu->cmd_len = (slu->protocoll == 1) ? STLINK_SG_SIZE : STLINK_CMD_SIZE; - - // initialize stlink version (sl->version) - stlink_version(sl); - - int mode = stlink_current_mode(sl); - if (mode == STLINK_DEV_DFU_MODE) { - DLOG("-- exit_dfu_mode\n"); - _stlink_usb_exit_dfu_mode(sl); - } - - if (connect == CONNECT_UNDER_RESET) { - // for the connect under reset only - // OpenOСD says (official documentation is not available) that - // the NRST pin must be pull down before selecting the SWD/JTAG mode - if (mode == STLINK_DEV_DEBUG_MODE) { - DLOG("-- exit_debug_mode\n"); - _stlink_usb_exit_debug_mode(sl); - } - - _stlink_usb_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_LOW); - } - - sl->freq = freq; - // set the speed before entering the mode as the chip discovery phase - // should be done at this speed too - // set the stlink clock speed (default is 1800kHz) - DLOG("JTAG/SWD freq set to %d\n", freq); - _stlink_usb_set_swdclk(sl, freq); - - stlink_target_connect(sl, connect); - return(sl); - -on_libusb_error: - stlink_close(sl); - return(NULL); - -on_error: - if (slu->libusb_ctx) { libusb_exit(slu->libusb_ctx); } - -on_malloc_error: - if (sl != NULL) { free(sl); } - if (slu != NULL) { free(slu); } - - return(NULL); -} - -static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], enum connect_type connect, int freq) { - stlink_t **_sldevs; - libusb_device *dev; - int i = 0; - size_t slcnt = 0; - size_t slcur = 0; - - /* Count STLINKs */ - while ((dev = devs[i++]) != NULL) { - struct libusb_device_descriptor desc; - int ret = libusb_get_device_descriptor(dev, &desc); - - if (ret < 0) { - WLOG("failed to get libusb device descriptor (libusb error: %d)\n", ret); - break; - } - - if (desc.idVendor != STLINK_USB_VID_ST) { continue; } - - if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { - WLOG("skipping ST device : %#04x:%#04x)\n", desc.idVendor, desc.idProduct); - continue; - } - - slcnt++; - } - - _sldevs = calloc(slcnt, sizeof(stlink_t *)); // allocate list of pointers - - if (!_sldevs) { - *sldevs = NULL; - return(0); - } - - /* Open STLINKS and attach them to list */ - i = 0; - - while ((dev = devs[i++]) != NULL) { - struct libusb_device_descriptor desc; - int ret = libusb_get_device_descriptor(dev, &desc); - - if (ret < 0) { - WLOG("failed to get libusb device descriptor (libusb error: %d)\n", ret); - break; - } - - if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { continue; } - - struct libusb_device_handle* handle; - char serial[STLINK_SERIAL_BUFFER_SIZE] = {0, }; - - ret = libusb_open(dev, &handle); - - if (ret < 0) { - if (ret == LIBUSB_ERROR_ACCESS) { - ELOG("Could not open USB device %#06x:%#06x, access error.\n", desc.idVendor, desc.idProduct); - } else { - ELOG("Failed to open USB device %#06x:%#06x, libusb error: %d)\n", desc.idVendor, desc.idProduct, ret); - } - - break; - } - - size_t serial_len = stlink_serial(handle, &desc, serial); - - libusb_close(handle); - - if (serial_len != STLINK_SERIAL_LENGTH) { continue; } - - stlink_t *sl = stlink_open_usb(0, connect, serial, freq); - - if (!sl) { - ELOG("Failed to open USB device %#06x:%#06x\n", desc.idVendor, desc.idProduct); - continue; - } - - _sldevs[slcur++] = sl; - } - - *sldevs = _sldevs; - - return(slcur); -} - -size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int freq) { - libusb_device **devs; - stlink_t **sldevs; - - size_t slcnt = 0; - int r; - ssize_t cnt; - - r = libusb_init(NULL); - - if (r < 0) { return(0); } - - cnt = libusb_get_device_list(NULL, &devs); - - if (cnt < 0) { return(0); } - - slcnt = stlink_probe_usb_devs(devs, &sldevs, connect, freq); - libusb_free_device_list(devs, 1); - - libusb_exit(NULL); - - *stdevs = sldevs; - - return(slcnt); -} - -void stlink_probe_usb_free(stlink_t ***stdevs, size_t size) { - if (stdevs == NULL || *stdevs == NULL || size == 0) { return; } - - for (size_t n = 0; n < size; n++) { stlink_close((*stdevs)[n]); } - - free(*stdevs); - *stdevs = NULL; -} diff --git a/src/win32/unistd/unistd.h b/src/win32/unistd/unistd.h index cb6da4b8a..389c44664 100644 --- a/src/win32/unistd/unistd.h +++ b/src/win32/unistd/unistd.h @@ -52,7 +52,7 @@ #define ssize_t int #ifndef SSIZE_MAX -#define SSIZE_MAX ((sizeof(ssize_t) == 4) ? 1073741824 : ‭4611686018427387904‬) +#define SSIZE_MAX ((sizeof(ssize_t) == 4) ? 2147483647 : 9223372036854775807) #endif #define STDIN_FILENO 0 diff --git a/src/win32/unistd/unistd.h.bak b/src/win32/unistd/unistd.h.bak deleted file mode 100644 index 47967e45e..000000000 --- a/src/win32/unistd/unistd.h.bak +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef _UNISTD_H -#define _UNISTD_H 1 - -/* - * This file intended to serve as a drop-in replacement for unistd.h on Windows - * Please add functionality as needed. - */ - -#include -#include - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable: 4820) -#endif - -#include - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - -#include // getopt at: https://gist.github.com/ashelly/7776712 -#include // for getpid() and the exec..() family -#include // for _getcwd() and _chdir() - -#define srandom srand -#define random rand - -/* Values for the second argument to access. These may be OR'd together. */ -#define R_OK 4 // Test for read permission -#define W_OK 2 // Test for write permission -// #define X_OK 1 // execute permission - unsupported in windows -#define F_OK 0 // Test for existence - -#define access _access -#define dup2 _dup2 -#define execve _execve -#define ftruncate _chsize -#define unlink _unlink -#define fileno _fileno -#define getcwd _getcwd -#define chdir _chdir -#define isatty _isatty -#define lseek _lseek - -/* - * Read, write, and close are NOT being defined here, - * because while there are file handle specific versions for Windows, they probably don't work for sockets. - * You need to look at your app and consider whether to call e.g. closesocket(). - */ - -#define ssize_t int -#ifndef SSIZE_MAX -//#define SSIZE_MAX ((sizeof(ssize_t) == 4) ? 2147483647 : 9223372036854775807) -#define SSIZE_MAX ((sizeof(ssize_t) == 4) ? 1073741824 : ‭4611686018427387904‬) -#endif - -#define STDIN_FILENO 0 -#define STDOUT_FILENO 1 -#define STDERR_FILENO 2 -// should be in some equivalent to -typedef __int8 int8_t; -typedef __int16 int16_t; -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int8 uint8_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int64 uint64_t; - -#ifndef STLINK_HAVE_UNISTD_H -int usleep(unsigned int waitTime); -#endif - -#endif // _UNISTD_H diff --git a/stlinkv1_macos_driver/install.sh b/stlinkv1_macos_driver/install.sh index 5716281a1..f9878bd46 100644 --- a/stlinkv1_macos_driver/install.sh +++ b/stlinkv1_macos_driver/install.sh @@ -2,9 +2,6 @@ ISMACOS=$(sw_vers -productVersion) case $ISMACOS in -10.14*) - KEXT="stlink_shield_10_14.kext" - ;; 10.15*) KEXT="stlink_shield_10_15.kext" ;; diff --git a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist deleted file mode 100644 index fd424ea93..000000000 --- a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/Info.plist +++ /dev/null @@ -1,82 +0,0 @@ - - - - - BuildMachineOSBuild - 18G7016 - CFBundleDevelopmentRegion - English - CFBundleIdentifier - com.libusb.stlink-shield - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - KEXT - CFBundleSignature - ???? - CFBundleSupportedPlatforms - - MacOSX - - CFBundleVersion - 1.0.0 - DTCompiler - com.apple.compilers.llvm.clang.1_0 - DTPlatformBuild - 11C504 - DTPlatformVersion - GM - DTSDKBuild - 19B90 - DTSDKName - macosx10.15 - DTXcode - 1130 - DTXcodeBuild - 11C504 - IOKitPersonalities - - DeviceDriver - - CFBundleIdentifier - com.apple.kpi.iokit - IOClass - IOService - IOProviderClass - IOUSBDevice - bcdDevice - 256 - idProduct - 14148 - idVendor - 1155 - - InterfaceDriver - - CFBundleIdentifier - com.apple.kpi.iokit - IOClass - IOService - IOProviderClass - IOUSBInterface - bConfigurationValue - 1 - bInterfaceNumber - 0 - idProduct - 14148 - idVendor - 1155 - - - LSMinimumSystemVersion - 10.14 - OSBundleLibraries - - com.apple.iokit.IOUSBFamily - 1.8 - com.apple.kpi.libkern - 11.2.0 - - - diff --git a/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 b/stlinkv1_macos_driver/stlink_shield_10_14.kext/Contents/MacOS/stlink_shield_10_14 deleted file mode 100644 index 6a32aa4615953f6afe16047f73da9a3bced9b3a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33840 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 - - - - files - - files2 - - rules - - ^Resources/ - - ^Resources/.*\.lproj/ - - optional - - weight - 1000 - - ^Resources/.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^Resources/Base\.lproj/ - - weight - 1010 - - ^version.plist$ - - - rules2 - - .*\.dSYM($|/) - - weight - 11 - - ^(.*/)?\.DS_Store$ - - omit - - weight - 2000 - - ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ - - nested - - weight - 10 - - ^.* - - ^Info\.plist$ - - omit - - weight - 20 - - ^PkgInfo$ - - omit - - weight - 20 - - ^Resources/ - - weight - 20 - - ^Resources/.*\.lproj/ - - optional - - weight - 1000 - - ^Resources/.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^Resources/Base\.lproj/ - - weight - 1010 - - ^[^/]+$ - - nested - - weight - 10 - - ^embedded\.provisionprofile$ - - weight - 20 - - ^version\.plist$ - - weight - 20 - - - - diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj index 4f2b80254..373600c64 100644 --- a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj +++ b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXFileReference section */ 8CD33C31149BB80D0033D618 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = stlink_shield_10_14.kext; sourceTree = BUILT_PRODUCTS_DIR; }; 8F90850924786F39009109AD /* stlink_shield_10_15.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = stlink_shield_10_15.kext; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -34,7 +33,6 @@ 19C28FB6FE9D52B211CA2CBB /* Products */ = { isa = PBXGroup; children = ( - 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */, 8F90850924786F39009109AD /* stlink_shield_10_15.kext */, ); name = Products; @@ -60,26 +58,6 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 8F9084F324786F0F009109AD /* stlink_shield_10_14 */ = { - isa = PBXNativeTarget; - buildConfigurationList = 8F9084FA24786F0F009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_14" */; - buildPhases = ( - 8F9084F424786F0F009109AD /* ShellScript */, - 8F9084F524786F0F009109AD /* Headers */, - 8F9084F624786F0F009109AD /* Resources */, - 8F9084F824786F0F009109AD /* Sources */, - 8F9084F924786F0F009109AD /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = stlink_shield_10_14; - productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; - productName = NanosMouse; - productReference = 8F9084FD24786F0F009109AD /* stlink_shield_10_14.kext */; - productType = "com.apple.product-type.kernel-extension.iokit"; - }; 8F9084FF24786F39009109AD /* stlink_shield_10_15 */ = { isa = PBXNativeTarget; buildConfigurationList = 8F90850624786F39009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_15" */; @@ -120,7 +98,6 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 8F9084F324786F0F009109AD /* stlink_shield_10_14 */, 8F9084FF24786F39009109AD /* stlink_shield_10_15 */, ); }; @@ -458,24 +435,6 @@ }; name = Release; }; - 8F9084FB24786F0F009109AD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - MACOSX_DEPLOYMENT_TARGET = 10.14; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 8F9084FC24786F0F009109AD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - MACOSX_DEPLOYMENT_TARGET = 10.14; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; 8F90850724786F39009109AD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -506,15 +465,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 8F9084FA24786F0F009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_14" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 8F9084FB24786F0F009109AD /* Debug */, - 8F9084FC24786F0F009109AD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 8F90850624786F39009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_15" */ = { isa = XCConfigurationList; buildConfigurations = ( From cf6bdbfe4ba9fa3dd4ea58b81a3d290a39c2a55a Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Mon, 31 Jan 2022 13:01:06 +0200 Subject: [PATCH 1304/1435] set C standart through cmake variables, remove redundant -Ox options --- CMakeLists.txt | 4 ++++ cmake/modules/c_flags.cmake | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index abfc0be47..52c00ea29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,10 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) + ### # General project settings diff --git a/cmake/modules/c_flags.cmake b/cmake/modules/c_flags.cmake index 5ed0c4d7d..44052bba8 100644 --- a/cmake/modules/c_flags.cmake +++ b/cmake/modules/c_flags.cmake @@ -17,8 +17,6 @@ function(add_cflag_if_supported flag) endif () endfunction() -add_cflag_if_supported("-std=gnu11") -add_cflag_if_supported("-std=gnu18") add_cflag_if_supported("-Wall") add_cflag_if_supported("-Wextra") add_cflag_if_supported("-Wshadow") @@ -47,8 +45,6 @@ endif () if (${CMAKE_BUILD_TYPE} MATCHES "Debug") add_cflag_if_supported("-ggdb") - add_cflag_if_supported("-O0") else () - add_cflag_if_supported("-O2") add_cflag_if_supported("-Werror") endif () From 978462d048bbb74842c75dcc0539e8c28da3ebb1 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 4 Feb 2022 21:53:00 +0100 Subject: [PATCH 1305/1435] Updated libusb to v1.0.25 (macOS + Windows) --- cmake/modules/Findlibusb.cmake | 2 +- doc/version_support.md | 4 ++-- src/stlink-lib/libusb_settings.h | 9 +++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index bc04f848d..de3712eca 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -72,7 +72,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to if (WIN32 AND NOT EXISTS "/etc/debian_version") # Skip this for Debian... # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.24) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.25) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) diff --git a/doc/version_support.md b/doc/version_support.md index d7ba5c102..01d9dddb1 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -14,8 +14,8 @@ Up on compiling c-make will **automatically** download and install the latest co | Package Repository | libusb | cmake | gtk-3-dev | Supported macOS versions | | ------------------ | ------ | ------ | ------------------ | ------------------------ | -| homebrew | 1.0.24 | 3.22.1 | 3.24.30
      gtk+3 | **10.10 - 12.x** | -| MacPorts | 1.0.24 | 3.22.1 | 3.24.31
      gtk3 | **10.4 - 12.x** | +| homebrew | 1.0.25 | 3.22.1 | 3.24.30
      gtk+3 | **10.10 - 12.x** | +| MacPorts | 1.0.25 | 3.22.1 | 3.24.31
      gtk3 | **10.4 - 12.x** | NOTE: In order to use a STLINK/V1 programmer on macOS, version 10.15 is required. diff --git a/src/stlink-lib/libusb_settings.h b/src/stlink-lib/libusb_settings.h index c7562e290..2a595238a 100644 --- a/src/stlink-lib/libusb_settings.h +++ b/src/stlink-lib/libusb_settings.h @@ -18,6 +18,7 @@ * v1.0.22 | 0x01000106 * v1.0.23 | 0x01000107 * v1.0.24 | 0x01000108 + * v1.0.25 | 0x01000109 */ #if defined (__FreeBSD__) @@ -31,13 +32,13 @@ #if defined (__FreeBSD__) #define MINIMAL_API_VERSION 0x01000102 // v1.0.16 #elif defined (__OpenBSD__) - #define MINIMAL_API_VERSION 0x01000104 // v1.0.20 + #define MINIMAL_API_VERSION 0x01000105 // v1.0.21 #elif defined (__linux__) - #define MINIMAL_API_VERSION 0x01000104 // v1.0.20 + #define MINIMAL_API_VERSION 0x01000105 // v1.0.21 #elif defined (__APPLE__) - #define MINIMAL_API_VERSION 0x01000104 // v1.0.20 + #define MINIMAL_API_VERSION 0x01000109 // v1.0.25 #elif defined (_WIN32) - #define MINIMAL_API_VERSION 0x01000104 // v1.0.20 + #define MINIMAL_API_VERSION 0x01000109 // v1.0.25 #endif #if (LIBUSB_API_VERSION < MINIMAL_API_VERSION) From 468b1d2daa853b975c33ab69876c486734f2c6a7 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 4 Feb 2022 22:24:42 +0100 Subject: [PATCH 1306/1435] [libusb] Added Security framework for macOS --- CMakeLists.txt | 6 ++++-- cmake/packaging/cpack_config.cmake | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 52c00ea29..67f76ec08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,7 +209,8 @@ if (APPLE) # ... with Apple macOS libraries find_library(ObjC objc) find_library(CoreFoundation CoreFoundation) find_library(IOKit IOKit) - target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB} ${ObjC} ${CoreFoundation} ${IOKit}) + find_library(Security Security) + target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB} ${ObjC} ${CoreFoundation} ${IOKit} ${Security}) elseif (WIN32) # ... with Windows libraries target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB} wsock32 ws2_32) else () @@ -251,7 +252,8 @@ if (APPLE) # ... with Apple macOS libraries find_library(ObjC objc) find_library(CoreFoundation CoreFoundation) find_library(IOKit IOKit) - target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB} ${ObjC} ${CoreFoundation} ${IOKit}) + find_library(Security Security) + target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB} ${ObjC} ${CoreFoundation} ${IOKit} ${Security}) elseif (WIN32) # ... with Windows libraries target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB} wsock32 ws2_32) else () diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake index 587ff5fb5..a4f1ae073 100644 --- a/cmake/packaging/cpack_config.cmake +++ b/cmake/packaging/cpack_config.cmake @@ -17,7 +17,7 @@ set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist") if (APPLE) # macOS set(CPACK_GENERATOR "ZIP") - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-macosx-amd64") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-macos-amd64") set(CPACK_INSTALL_PREFIX "") elseif (WIN32 AND (NOT EXISTS "/etc/debian_version")) # Windows From 77fff346aa9d075e7fd01668d8418818f9c262ac Mon Sep 17 00:00:00 2001 From: Alex Klimaj Date: Tue, 15 Feb 2022 22:28:19 -0700 Subject: [PATCH 1307/1435] Add writing and reading STM32WL option bytes --- config/chips/WLx5.chip | 2 +- inc/stm32flash.h | 8 +-- src/option_bytes.c | 108 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 4 deletions(-) diff --git a/config/chips/WLx5.chip b/config/chips/WLx5.chip index 5bc9d90dc..8337b0aee 100644 --- a/config/chips/WLx5.chip +++ b/config/chips/WLx5.chip @@ -9,6 +9,6 @@ flash_pagesize 0x800 // 2 KB sram_size 0x10000 // 64 KB bootrom_base 0x1fff0000 bootrom_size 0x7000 // 28 KB -option_base 0x1fffc000 +option_base 0x1fff7800 option_size 0x10 // 16 B flags swo diff --git a/inc/stm32flash.h b/inc/stm32flash.h index c28d67c28..7e96d3f70 100644 --- a/inc/stm32flash.h +++ b/inc/stm32flash.h @@ -162,9 +162,11 @@ #define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) // WB Flash control register. -#define STM32WB_FLASH_CR_STRT (16) /* Start */ -#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ -#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ +#define STM32WB_FLASH_CR_STRT (16) /* Start */ +#define STM32WB_FLASH_CR_OPTSTRT (17) /* Start writing option bytes */ +#define STM32WB_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ +#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ +#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ // WB Flash status register. #define STM32WB_FLASH_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ #define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ diff --git a/src/option_bytes.c b/src/option_bytes.c index f5d8c00a0..c1a418232 100644 --- a/src/option_bytes.c +++ b/src/option_bytes.c @@ -472,6 +472,57 @@ static int stlink_write_option_bytes_h7(stlink_t *sl, uint8_t *base, return 0; } +/** + * Write option bytes + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes to write + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_wb(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + /* Write options bytes */ + uint32_t val; + int ret = 0; + (void)len; + uint32_t data; + + clear_flash_error(sl); + + while (len != 0) { + write_uint32((unsigned char *)&data, + *(uint32_t *)(base)); // write options bytes + + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + stlink_write_debug32(sl, addr, data); + wait_flash_busy(sl); + + if ((ret = check_flash_error(sl))) { + break; + } + + len -= 4; + addr += 4; + base += 4; + } + + // Set Options Start bit + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + val |= (1 << STM32WB_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + + // Reload options + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + val |= (1 << STM32WB_FLASH_CR_OBL_LAUNCH); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + + return (ret); +} + /** * Write option bytes * @param sl @@ -536,6 +587,9 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, case STM32_FLASH_TYPE_H7: ret = stlink_write_option_bytes_h7(sl, base, addr, len); break; + case STM32_FLASH_TYPE_WB_WL: + ret = stlink_write_option_bytes_wb(sl, base, addr, len); + break; default: ELOG("Option bytes writing is currently not implemented for connected " "chip\n"); @@ -715,6 +769,42 @@ stlink_write_option_control_register_f7(stlink_t *sl, return ret; } +/** + * Write option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +static int +stlink_write_option_control_register_wb(stlink_t *sl, + uint32_t option_control_register) { + int ret = 0; + + // Clear errors + clear_flash_error(sl); + + ILOG("Asked to write option control register 1 %#10x to %#010x.\n", + option_control_register, STM32WB_FLASH_OPTR); + + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, STM32WB_FLASH_OPTR, option_control_register); + + wait_flash_busy(sl); + + // Set Options Start bit + uint32_t val = (1 << STM32WB_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, + STM32WB_FLASH_OPTR); + + return ret; +} + /** * Write option bytes * @param sl @@ -746,6 +836,10 @@ int stlink_write_option_control_register32(stlink_t *sl, case STM32_FLASH_TYPE_F7: ret = stlink_write_option_control_register_f7(sl, option_control_register); break; + case STM32_FLASH_TYPE_WB_WL: + ret = + stlink_write_option_control_register_wb(sl, option_control_register); + break; default: ELOG("Option control register writing is currently not implemented for " "connected chip\n"); @@ -1003,6 +1097,18 @@ int stlink_read_option_control_register_f0(stlink_t *sl, return stlink_read_debug32(sl, FLASH_OBR, option_byte); } +/** + * Read option bytes + * @param sl + * @param option_byte value to read + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_wb(stlink_t *sl, + uint32_t *option_byte) { + DLOG("@@@@ Read option control register byte from %#10x\n", STM32WB_FLASH_OPTR); + return stlink_read_debug32(sl, STM32WB_FLASH_OPTR, option_byte); +} + /** * Read option bytes * @param sl @@ -1021,6 +1127,8 @@ int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { return stlink_read_option_control_register_f0(sl, option_byte); case STM32_FLASH_TYPE_F7: return stlink_read_option_control_register_f7(sl, option_byte); + case STM32_FLASH_TYPE_WB_WL: + return stlink_read_option_control_register_wb(sl, option_byte); default: return -1; } From a6939cb9d491d8e3aa2aa54d0e35fb72519b7d8f Mon Sep 17 00:00:00 2001 From: Lucas Sinn Date: Tue, 8 Mar 2022 11:21:23 +0100 Subject: [PATCH 1308/1435] init chipids only when actually interacting with device --- src/st-info/info.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/st-info/info.c b/src/st-info/info.c index 618046ddd..a939a03cf 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -29,7 +29,6 @@ static void stlink_print_version(stlink_t *sl) { } static void stlink_print_info(stlink_t *sl) { - const struct stlink_chipid_params *params = NULL; if (!sl) { return; } @@ -38,9 +37,6 @@ static void stlink_print_info(stlink_t *sl) { printf(" flash: %u (pagesize: %u)\n", (uint32_t)sl->flash_size, (uint32_t)sl->flash_pgsz); printf(" sram: %u\n", (uint32_t)sl->sram_size); printf(" chipid: 0x%.3x\n", sl->chip_id); - - params = stlink_chipid_get_params(sl->chip_id); - if (params) { printf(" dev-type: %s\n", params->dev_type); } } static void stlink_probe(enum connect_type connect, int freq) { @@ -69,6 +65,8 @@ static int print_data(int ac, char **av) { return(0); } + init_chipids(ETC_STLINK_DIR); + for (int i=2; i Date: Tue, 8 Mar 2022 11:24:06 +0100 Subject: [PATCH 1309/1435] optimized processing of chipidfile 'moved chip dump to stdout instead of stderr' 'closing open fd after file is fully read' 'reduced file read buffer size' --- src/stlink-lib/chipid.c | 44 ++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 06e8571aa..8fcaa4100 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -30,8 +30,8 @@ struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chip_id) { struct stlink_chipid_params *params = NULL; for (params = devicelist; params != NULL; params = params->next) if (params->chip_id == chip_id) { - fprintf(stderr, "\ndetected chip_id parametres\n\n"); - dump_a_chip(stderr, params); + fprintf(stdout, "\ndetected chip_id parametres\n\n"); + dump_a_chip(stdout, params); break; } @@ -40,7 +40,7 @@ struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chip_id) { void process_chipfile(char *fname) { FILE *fp; - char *p, *pp, buf[1025]; + char *p, buf[128]; char word[64], value[64]; struct stlink_chipid_params *ts; int nc; @@ -55,29 +55,23 @@ void process_chipfile(char *fname) { ts = calloc(sizeof(struct stlink_chipid_params), 1); - while (fgets(buf, 1024, fp) != NULL) { - for (p = buf; isspace (*p); p++); + while (fgets(buf, sizeof(buf), fp) != NULL) { - if (!*p) { - continue; // we hit end-of-line with only whitespace - } - - if (*p == '#') { + if(strncmp(buf, "#", strlen("#")) == 0) continue; // ignore comments - } - sscanf(p, "%s %s", word, value); + sscanf(buf, "%s %s", word, value); if (strcmp (word, "dev_type") == 0) { // ts->dev_type = strdup (value); - buf[strlen(p) - 1] = 0; // chomp newline - sscanf(p, "%*s %n", &nc); - ts->dev_type = strdup(p + nc); + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + ts->dev_type = strdup(buf + nc); } else if (strcmp(word, "ref_manual_id") == 0) { // ts->ref_manual_id = strdup (value); - buf[strlen(p) - 1] = 0; // chomp newline - sscanf(p, "%*s %n", &nc); - ts->ref_manual_id = strdup(p + nc); + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + ts->ref_manual_id = strdup(buf + nc); } else if (strcmp(word, "chip_id") == 0) { if (sscanf(value, "%i", &ts->chip_id) < 1) { fprintf(stderr, "Failed to parse chip-id\n"); @@ -138,18 +132,18 @@ void process_chipfile(char *fname) { fprintf(stderr, "Failed to parse option size\n"); } } else if (strcmp(word, "flags") == 0) { - pp = strtok (p, " \t\n"); + p = strtok (buf, " \t\n"); - while ((pp = strtok (NULL, " \t\n"))) { - if (strcmp(pp, "none") == 0) { + while ((p = strtok (NULL, " \t\n"))) { + if (strcmp(p, "none") == 0) { // NOP - } else if (strcmp(pp, "dualbank") == 0) { + } else if (strcmp(p, "dualbank") == 0) { ts->flags |= CHIP_F_HAS_DUAL_BANK; - } else if (strcmp(pp, "swo") == 0) { + } else if (strcmp(p, "swo") == 0) { ts->flags |= CHIP_F_HAS_SWO_TRACING; } else { fprintf(stderr, "Unknown flags word in %s: '%s'\n", - fname, pp); + fname, p); } } @@ -159,7 +153,7 @@ void process_chipfile(char *fname) { fname, word); } } - + fclose(fp); ts->next = devicelist; devicelist = ts; } From 564434297cfadcea44eb3c275bc4d95c5f210d1d Mon Sep 17 00:00:00 2001 From: Lucas Sinn Date: Mon, 14 Mar 2022 12:47:23 +0100 Subject: [PATCH 1310/1435] readded get chipid parameters on print info --- src/st-info/info.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/st-info/info.c b/src/st-info/info.c index a939a03cf..d02653bc5 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -29,7 +29,7 @@ static void stlink_print_version(stlink_t *sl) { } static void stlink_print_info(stlink_t *sl) { - + const struct stlink_chipid_params *params = NULL; if (!sl) { return; } printf(" version: "); stlink_print_version(sl); @@ -37,6 +37,9 @@ static void stlink_print_info(stlink_t *sl) { printf(" flash: %u (pagesize: %u)\n", (uint32_t)sl->flash_size, (uint32_t)sl->flash_pgsz); printf(" sram: %u\n", (uint32_t)sl->sram_size); printf(" chipid: 0x%.3x\n", sl->chip_id); + + params = stlink_chipid_get_params(sl->chip_id); + if (params) { printf(" dev-type: %s\n", params->dev_type); } } static void stlink_probe(enum connect_type connect, int freq) { From a99a626e6948b684515fe068e7b01b53b74c4678 Mon Sep 17 00:00:00 2001 From: Lucas Sinn Date: Mon, 14 Mar 2022 12:48:47 +0100 Subject: [PATCH 1311/1435] moved dump_a_chip to debug output, minor code style fix --- src/stlink-lib/chipid.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 8fcaa4100..02b610bb1 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -10,28 +10,28 @@ static struct stlink_chipid_params *devicelist; -void dump_a_chip (FILE *fp, struct stlink_chipid_params *dev) { - fprintf(fp, "# Device Type: %s\n", dev->dev_type); - fprintf(fp, "# Reference Manual: RM%s\n", dev->ref_manual_id); - fprintf(fp, "#\n"); - fprintf(fp, "chip_id 0x%x\n", dev->chip_id); - fprintf(fp, "flash_type %d\n", dev->flash_type); - fprintf(fp, "flash_size_reg 0x%x\n", dev->flash_size_reg); - fprintf(fp, "flash_pagesize 0x%x\n", dev->flash_pagesize); - fprintf(fp, "sram_size 0x%x\n", dev->sram_size); - fprintf(fp, "bootrom_base 0x%x\n", dev->bootrom_base); - fprintf(fp, "bootrom_size 0x%x\n", dev->bootrom_size); - fprintf(fp, "option_base 0x%x\n", dev->option_base); - fprintf(fp, "option_size 0x%x\n", dev->option_size); - fprintf(fp, "flags %d\n\n", dev->flags); +void dump_a_chip (struct stlink_chipid_params *dev) { + DLOG("# Device Type: %s\n", dev->dev_type); + DLOG("# Reference Manual: RM%s\n", dev->ref_manual_id); + DLOG("#\n"); + DLOG("chip_id 0x%x\n", dev->chip_id); + DLOG("flash_type %d\n", dev->flash_type); + DLOG("flash_size_reg 0x%x\n", dev->flash_size_reg); + DLOG("flash_pagesize 0x%x\n", dev->flash_pagesize); + DLOG("sram_size 0x%x\n", dev->sram_size); + DLOG("bootrom_base 0x%x\n", dev->bootrom_base); + DLOG("bootrom_size 0x%x\n", dev->bootrom_size); + DLOG("option_base 0x%x\n", dev->option_base); + DLOG("option_size 0x%x\n", dev->option_size); + DLOG("flags %d\n\n", dev->flags); } struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chip_id) { struct stlink_chipid_params *params = NULL; for (params = devicelist; params != NULL; params = params->next) if (params->chip_id == chip_id) { - fprintf(stdout, "\ndetected chip_id parametres\n\n"); - dump_a_chip(stdout, params); + DLOG("detected chip_id parameters\n\n"); + dump_a_chip(params); break; } @@ -57,7 +57,7 @@ void process_chipfile(char *fname) { while (fgets(buf, sizeof(buf), fp) != NULL) { - if(strncmp(buf, "#", strlen("#")) == 0) + if (strncmp(buf, "#", strlen("#")) == 0) continue; // ignore comments sscanf(buf, "%s %s", word, value); From 86a37544f1c3e98c36432dd8df85c99536ea9acf Mon Sep 17 00:00:00 2001 From: Lucas Sinn Date: Mon, 14 Mar 2022 13:00:07 +0100 Subject: [PATCH 1312/1435] added option_base, option_size for F401xD_xE --- config/chips/F401xD_xE.chip | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/chips/F401xD_xE.chip b/config/chips/F401xD_xE.chip index 39748a604..f817175f4 100644 --- a/config/chips/F401xD_xE.chip +++ b/config/chips/F401xD_xE.chip @@ -9,6 +9,6 @@ flash_pagesize 0x4000 // 16 KB sram_size 0x18000 // 96 KB bootrom_base 0x1fff0000 bootrom_size 0x7800 // 30 KB -option_base 0x0 -option_size 0x0 +option_base 0x40023C14 +option_size 0x4 flags swo From 3b328b26bd5eb0e07f78b8ba48e10c2581a1239a Mon Sep 17 00:00:00 2001 From: Lucas Sinn Date: Wed, 16 Mar 2022 09:31:19 +0100 Subject: [PATCH 1313/1435] adding additional check if .chip files contain empty lines --- src/stlink-lib/chipid.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 02b610bb1..fe60ebf64 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -60,6 +60,10 @@ void process_chipfile(char *fname) { if (strncmp(buf, "#", strlen("#")) == 0) continue; // ignore comments + if ((strncmp(buf, "\n", strlen("\n")) == 0) || + (strncmp(buf, " ", strlen(" ")) == 0)) + continue; // ignore empty lines + sscanf(buf, "%s %s", word, value); if (strcmp (word, "dev_type") == 0) { From 8dfb7973e712ab2ed982cd241f9240ac9e432da7 Mon Sep 17 00:00:00 2001 From: Lucas Sinn Date: Mon, 28 Mar 2022 09:18:30 +0200 Subject: [PATCH 1314/1435] made chipfile buffer size bigger --- src/stlink-lib/chipid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index fe60ebf64..e36c150a6 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -40,7 +40,7 @@ struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chip_id) { void process_chipfile(char *fname) { FILE *fp; - char *p, buf[128]; + char *p, buf[256]; char word[64], value[64]; struct stlink_chipid_params *ts; int nc; From a5696f2668105aa7ae3f61f77193423617c25099 Mon Sep 17 00:00:00 2001 From: simon-wh Date: Fri, 20 May 2022 11:01:32 +0200 Subject: [PATCH 1315/1435] Define option byte properties for F1xx_XLD --- config/chips/F1xx_XLD.chip | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/chips/F1xx_XLD.chip b/config/chips/F1xx_XLD.chip index 622bd9d02..4f8c9ee27 100644 --- a/config/chips/F1xx_XLD.chip +++ b/config/chips/F1xx_XLD.chip @@ -9,6 +9,6 @@ flash_pagesize 0x800 // 2 KB sram_size 0x18000 // 96 KB bootrom_base 0x1fffe000 bootrom_size 0x1800 // 6 KB -option_base 0x0 -option_size 0x0 +option_base 0x1ffff800 // STM32_F0_OPTION_BYTES_BASE +option_size 0x10 // 16 B flags swo From 9a7805ede51839cb8d76074c595997045c5c1e95 Mon Sep 17 00:00:00 2001 From: simon-wh Date: Fri, 20 May 2022 11:02:50 +0200 Subject: [PATCH 1316/1435] Include GD32F303CGT6 in devices_boards.md --- doc/devices_boards.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/devices_boards.md b/doc/devices_boards.md index 51b9a0739..1a5099b72 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -90,6 +90,7 @@ Tested non-official ST boards [incl. STLINK programmers]: | Product-Code | Chip-ID | STLINK
      Programmer | Boards | | ------------ | ------- | ---------------------- | ---------------------------------- | | GD32F303VGT6 | 0x430 | [v2] | STM32F303 clone from GigaDevice GD | +| GD32F303CGT6 | 0x430 | [v2] | STM32F303 clone from GigaDevice GD | ## STM32F4 / ARM Cortex M4F From f8d1603be40ddf6ed0701061f4aef8bdcc227070 Mon Sep 17 00:00:00 2001 From: John Hall Date: Wed, 8 Jun 2022 13:48:13 -0700 Subject: [PATCH 1317/1435] Updating to allow frequency units for clock and trace flags. Making sure trace frequency is not less than 1/5 of the system frequency. Showing minimum and maximum available trace speed when out of range. Making sure MCU is stopped after reset to avoid missing data. Making sure variables are intiallized. --- src/st-trace/trace.c | 84 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 19 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 28a585071..8c36ae6f0 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -98,13 +98,52 @@ static void usage(void) { puts(" -V, --version Print this version"); puts(" -vXX, --verbose=XX Specify a specific verbosity level (0..99)"); puts(" -v, --verbose Specify a generally verbose logging"); - puts(" -cXX, --clock=XX Specify the core frequency in MHz"); - puts(" -tXX, --trace=XX Specify the trace frequency in Hz"); + puts(" -cXX, --clock=XX Specify the core frequency, optionally followed by"); + puts(" k=kHz, m=MHz, or g=GHz (eg. --clock=180m)"); + puts(" -tXX, --trace=XX Specify the trace frequency, optionally followed by"); + puts(" k=kHz, m=MHz, or g=GHz (eg. --trace=2m)"); puts(" -n, --no-reset Do not reset board on connection"); puts(" -sXX, --serial=XX Use a specific serial number"); puts(" -f, --force Ignore most initialization errors"); } +static bool parse_frequency(char* text, uint32_t* result) +{ + if (text == NULL) { + ELOG("Invalid frequency.\n"); + return false; + } + + char* suffix = text; + double value = strtod(text, &suffix); + + if (value == 0.0) { + ELOG("Invalid frequency.\n"); + return false; + } + + double scale = 1.0; + if (*suffix == 'k') + scale = 1000; + else if (*suffix == 'm') + scale = 1000000; + else if (*suffix == 'g') + scale = 1000000000; + else if (*suffix != '\0') { + ELOG("Unknown frequency suffix '%s'.\n", suffix); + return false; + } + + value *= scale; + if (value <= 0 || value > 0xFFFFFFFFul) { + ELOG("Frequency is out of valid range.\n"); + return false; + } + + *result = (uint32_t)value; + return true; +} + bool parse_options(int argc, char **argv, st_settings_t *settings) { static struct option long_options[] = { @@ -150,10 +189,12 @@ bool parse_options(int argc, char **argv, st_settings_t *settings) { ugly_init(settings->logging_level); break; case 'c': - settings->core_frequency = atoi(optarg) * 1000000; + if (!parse_frequency(optarg, &settings->core_frequency)) + error = true; break; case 't': - settings->trace_frequency = atoi(optarg); + if (!parse_frequency(optarg, &settings->trace_frequency)) + error = true; break; case 'n': settings->reset_board = false; @@ -200,8 +241,7 @@ static bool enable_trace(stlink_t *stlink, const st_settings_t *settings, if (!settings->force) return false; } - - if (settings->reset_board && stlink_reset(stlink, RESET_AUTO)) { + if (settings->reset_board && stlink_reset(stlink, RESET_SOFT_AND_HALT)) { ELOG("Unable to reset device\n"); if (!settings->force) return false; @@ -268,13 +308,12 @@ static bool enable_trace(stlink_t *stlink, const st_settings_t *settings, STLINK_REG_DWT_CTRL_CYCCNT_ENA); stlink_write_debug32(stlink, STLINK_REG_DEMCR, STLINK_REG_DEMCR_TRCENA); - uint32_t prescaler; - stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR_MAX, &prescaler); + uint32_t prescaler = 0; + stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR, &prescaler); if (prescaler) { uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; - uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; - ILOG("Trace Port Interface configured to expect a %d MHz system clock.\n", - system_clock_speed_mhz); + ILOG("Trace Port Interface configured to expect a %d Hz system clock.\n", + system_clock_speed); } else { WLOG("Trace Port Interface not configured. Specify the system clock with " "a --clock=XX command\n"); @@ -440,13 +479,12 @@ static void check_for_configuration_error(stlink_t *stlink, st_trace_t *trace, } if (error_no_data || error_low_data || error_bad_data) { - uint32_t prescaler; + uint32_t prescaler = 0; stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR, &prescaler); if (prescaler) { uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; - uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; - WLOG("Verify the system clock is running at %d MHz.\n", - system_clock_speed_mhz); + WLOG("Verify the system clock is running at %d Hz.\n", + system_clock_speed); } WLOG("Try specifying the system clock with the --clock=XX command line " "option.\n"); @@ -511,7 +549,6 @@ int main(int argc, char **argv) { } init_chipids (ETC_STLINK_DIR); - DLOG("show_help = %s\n", settings.show_help ? "true" : "false"); DLOG("show_version = %s\n", settings.show_version ? "true" : "false"); DLOG("logging_level = %d\n", settings.logging_level); @@ -563,9 +600,18 @@ int main(int argc, char **argv) { uint32_t trace_frequency = settings.trace_frequency; if (!trace_frequency) trace_frequency = STLINK_DEFAULT_TRACE_FREQUENCY; - if (trace_frequency > stlink->max_trace_freq) { - ELOG("Invalid trace frequency %d (max %d)\n", trace_frequency, - stlink->max_trace_freq); + uint32_t max_trace_freq = stlink->max_trace_freq; + uint32_t min_trace_freq = 0; + + if (settings.core_frequency != 0) { + if (max_trace_freq > settings.core_frequency / 5) + max_trace_freq = settings.core_frequency / 5; + min_trace_freq = settings.core_frequency / (STLINK_REG_TPI_ACPR_MAX + 1); + } + if (trace_frequency > max_trace_freq || + trace_frequency < min_trace_freq) { + ELOG("Invalid trace frequency %d (min %d max %d)\n", trace_frequency, + min_trace_freq, max_trace_freq); if (!settings.force) return APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY; } From 0729558f2c9a5354b3d259cf887b9801678282b0 Mon Sep 17 00:00:00 2001 From: bauen1 Date: Mon, 9 May 2022 22:10:54 +0200 Subject: [PATCH 1318/1435] L4Rx: fix option byte address --- config/chips/L4Rx.chip | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/chips/L4Rx.chip b/config/chips/L4Rx.chip index b5c2d0d80..428a0c21e 100644 --- a/config/chips/L4Rx.chip +++ b/config/chips/L4Rx.chip @@ -9,6 +9,6 @@ flash_pagesize 0x1000 // 4 KB sram_size 0xa0000 // 640 KB bootrom_base 0x1fff0000 bootrom_size 0x7000 // 28 KB -option_base 0x0 -option_size 0x0 +option_base 0x1ff00000 +option_size 0x4 // 4 B flags swo From 54e82342f9b4f2e504fce501e30ab10045e8a166 Mon Sep 17 00:00:00 2001 From: simon-wh Date: Thu, 30 Jun 2022 17:55:27 +0100 Subject: [PATCH 1319/1435] Fix writing to 'BANK_2' in flash type F1_XL --- src/flashloader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flashloader.c b/src/flashloader.c index e4c7d7200..5592db477 100644 --- a/src/flashloader.c +++ b/src/flashloader.c @@ -94,7 +94,7 @@ static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; x |= (1 << FLASH_H7_CR_PG); } else { - cr_reg = FLASH_CR; + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; x = (1 << FLASH_CR_PG); } From 8956051ed5fc8ea124f48259e935aa90d9d95108 Mon Sep 17 00:00:00 2001 From: Jeroen de Bruijn Date: Thu, 14 Jul 2022 11:57:01 +0200 Subject: [PATCH 1320/1435] add `make install` to the MacOS building instructions This is required to get the `chips` directory in place. References #1237. --- doc/compiling.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/compiling.md b/doc/compiling.md index 0931c278a..ec98fa5d5 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -215,7 +215,8 @@ To do this with only one simple command, type: 1. Change into the project source directory: `cd stlink` 2. Run `make clean` to clean remnants of any previous builds. 3. Run `make release` to create the _Release_ target -4. Run `make debug` to create the _Debug_ target (_optional_)
      +4. Run `make install` to full install the package with complete system integration. This might require sudo permissions. +5. Run `make debug` to create the _Debug_ target (_optional_)
      The debug target is only necessary in order to modify the sources and to run under a debugger. ## Build options From 9f0521016c415e58ce9bd27fd865b33d84aca980 Mon Sep 17 00:00:00 2001 From: Jeroen de Bruijn Date: Thu, 14 Jul 2022 16:34:51 +0200 Subject: [PATCH 1321/1435] add optional installation folder for macOS to compiling documentation --- doc/compiling.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/compiling.md b/doc/compiling.md index ec98fa5d5..ec9d572ff 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -120,12 +120,12 @@ or execute (Debian-based systems only): `apt-get install gcc build-essential cma 1. Change into the project source directory: `cd stlink` 2. Run `make clean` -- required by some linux variants. 3. Run `make release` to create the _Release_ target -4. Run `make install` to full install the package with complete system integration +4. Run `make install` to full install the package with complete system integration. This might require sudo permissions. 5. Run `make debug` to create the _Debug_ target (_optional_)
      The debug target is only necessary in order to modify the sources and to run under a debugger. 6. Run `make package`to build a Debian Package. The generated packages can be found in the subdirectory `./build/dist`. -As an option you may also install to an individual user-defined folder e.g `$HOME` with `make install DESTDIR=$HOME`. +> **Note** As an option you may also install to an individual user-defined folder e.g `$HOME` with `make install DESTDIR=$HOME`. #### Removal: @@ -219,6 +219,8 @@ To do this with only one simple command, type: 5. Run `make debug` to create the _Debug_ target (_optional_)
      The debug target is only necessary in order to modify the sources and to run under a debugger. +> **Note** As an option you may also install to an individual user-defined folder e.g `$HOME` with `make install DESTDIR=$HOME`. + ## Build options ### Build using a different directory for shared libs From 87b21219a295e5080dcaf9e4b9ca38866eb14b5c Mon Sep 17 00:00:00 2001 From: Jeroen de Bruijn Date: Fri, 15 Jul 2022 08:16:57 +0200 Subject: [PATCH 1322/1435] remove note block from compiling docs note --- doc/compiling.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/compiling.md b/doc/compiling.md index ec9d572ff..a82941e8a 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -125,7 +125,7 @@ or execute (Debian-based systems only): `apt-get install gcc build-essential cma The debug target is only necessary in order to modify the sources and to run under a debugger. 6. Run `make package`to build a Debian Package. The generated packages can be found in the subdirectory `./build/dist`. -> **Note** As an option you may also install to an individual user-defined folder e.g `$HOME` with `make install DESTDIR=$HOME`. +As an option you may also install to an individual user-defined folder e.g `$HOME` with `make install DESTDIR=$HOME`. #### Removal: @@ -219,7 +219,7 @@ To do this with only one simple command, type: 5. Run `make debug` to create the _Debug_ target (_optional_)
      The debug target is only necessary in order to modify the sources and to run under a debugger. -> **Note** As an option you may also install to an individual user-defined folder e.g `$HOME` with `make install DESTDIR=$HOME`. +As an option you may also install to an individual user-defined folder e.g `$HOME` with `make install DESTDIR=$HOME`. ## Build options From 0e734a541b96dbf92be7b12c35cc7b2ce5e46569 Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Mon, 22 Aug 2022 10:47:05 +0200 Subject: [PATCH 1323/1435] src/common_flash: fix flash regs addr for STM32L152RET6 --- src/common_flash.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common_flash.c b/src/common_flash.c index e2a9ebbc3..72a36a288 100644 --- a/src/common_flash.c +++ b/src/common_flash.c @@ -21,6 +21,7 @@ uint32_t get_stm32l0_flash_base(stlink_t *sl) { case STM32_CHIPID_L1_MD: case STM32_CHIPID_L1_MD_PLUS: case STM32_CHIPID_L1_MD_PLUS_HD: + case STM32_CHIPID_L152_RE: return (STM32L_FLASH_REGS_ADDR); default: From c94b74e56a1522766937440c51a89a2cd968aeb2 Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Thu, 25 Aug 2022 19:18:31 +0200 Subject: [PATCH 1324/1435] stm32l1: fix flash, dbgmcu and rcc registers --- inc/stm32.h | 7 +++++++ inc/stm32flash.h | 4 ++++ src/common.c | 12 +++++++++--- src/common_flash.c | 15 ++++++++++++--- src/flashloader.c | 9 +++++++-- 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/inc/stm32.h b/inc/stm32.h index 473f65a56..2d533eca2 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -167,6 +167,10 @@ enum stm32_chipids { #define STM32L0_DBGMCU_APB1_FZ_WWDG_STOP 11 #define STM32L0_DBGMCU_APB1_FZ_IWDG_STOP 12 +#define STM32L1_DBGMCU_APB1_FZ 0xE0042008 +#define STM32L1_DBGMCU_APB1_FZ_WWDG_STOP 11 +#define STM32L1_DBGMCU_APB1_FZ_IWDG_STOP 12 + #define STM32H7_DBGMCU_APB1HFZ 0x5C001054 #define STM32H7_DBGMCU_APB1HFZ_IWDG_STOP 18 @@ -189,6 +193,9 @@ enum stm32_chipids { #define STM32L0_RCC_AHBENR 0x40021030 #define STM32L0_RCC_DMAEN 0x00000001 // DMAEN +#define STM32L1_RCC_AHBENR 0x4002381C +#define STM32L1_RCC_DMAEN 0x30000000 // DMA2EN | DMA1EN + #define STM32H7_RCC_AHB1ENR 0x58024538 #define STM32H7_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN diff --git a/inc/stm32flash.h b/inc/stm32flash.h index 7e96d3f70..5e7ad2e4a 100644 --- a/inc/stm32flash.h +++ b/inc/stm32flash.h @@ -219,6 +219,10 @@ #define STM32L0_FLASH_SR_PGAERR 9 #define STM32L0_FLASH_SR_NOTZEROERR 16 +#define STM32L1_FLASH_SR_ERROR_MASK 0x00003F00 +#define STM32L1_FLASH_SR_WRPERR 8 +#define STM32L1_FLASH_SR_PGAERR 9 + #define FLASH_ACR_OFF ((uint32_t)0x00) #define FLASH_PECR_OFF ((uint32_t)0x04) #define FLASH_PDKEYR_OFF ((uint32_t)0x08) diff --git a/src/common.c b/src/common.c index c49830154..d360b5d03 100644 --- a/src/common.c +++ b/src/common.c @@ -991,9 +991,15 @@ static void stop_wdg_in_debug(stlink_t *sl) { break; case STM32_FLASH_TYPE_L0_L1: case STM32_FLASH_TYPE_G0: - dbgmcu_cr = STM32L0_DBGMCU_APB1_FZ; - set = (1 << STM32L0_DBGMCU_APB1_FZ_IWDG_STOP) | - (1 << STM32L0_DBGMCU_APB1_FZ_WWDG_STOP); + if (get_stm32l0_flash_base(sl) == STM32L_FLASH_REGS_ADDR) { + dbgmcu_cr = STM32L1_DBGMCU_APB1_FZ; + set = (1 << STM32L1_DBGMCU_APB1_FZ_IWDG_STOP) | + (1 << STM32L1_DBGMCU_APB1_FZ_WWDG_STOP); + } else { + dbgmcu_cr = STM32L0_DBGMCU_APB1_FZ; + set = (1 << STM32L0_DBGMCU_APB1_FZ_IWDG_STOP) | + (1 << STM32L0_DBGMCU_APB1_FZ_WWDG_STOP); + } break; case STM32_FLASH_TYPE_H7: dbgmcu_cr = STM32H7_DBGMCU_APB1HFZ; diff --git a/src/common_flash.c b/src/common_flash.c index e2a9ebbc3..df2619cad 100644 --- a/src/common_flash.c +++ b/src/common_flash.c @@ -155,7 +155,11 @@ void clear_flash_error(stlink_t *sl) { write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); break; case STM32_FLASH_TYPE_L0_L1: - write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); + if (get_stm32l0_flash_base(sl) == STM32L_FLASH_REGS_ADDR) { + write_flash_sr(sl, BANK_1, STM32L1_FLASH_SR_ERROR_MASK); + } else { + write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); + } break; case STM32_FLASH_TYPE_L4_L4P: write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); @@ -281,9 +285,14 @@ int check_flash_error(stlink_t *sl) { PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); break; case STM32_FLASH_TYPE_L0_L1: - res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; + res = read_flash_sr(sl, BANK_1); + if (get_stm32l0_flash_base(sl) == STM32L_FLASH_REGS_ADDR) { + res &= STM32L1_FLASH_SR_ERROR_MASK; + } else { + res &= STM32L0_FLASH_SR_ERROR_MASK; + PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); + } WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); - PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); break; case STM32_FLASH_TYPE_L4_L4P: diff --git a/src/flashloader.c b/src/flashloader.c index 5592db477..b9c26bf4c 100644 --- a/src/flashloader.c +++ b/src/flashloader.c @@ -127,8 +127,13 @@ static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { rcc_dma_mask = STM32G4_RCC_DMAEN; break; case STM32_FLASH_TYPE_L0_L1: - rcc = STM32L0_RCC_AHBENR; - rcc_dma_mask = STM32L0_RCC_DMAEN; + if (get_stm32l0_flash_base(sl) == STM32L_FLASH_REGS_ADDR) { + rcc = STM32L1_RCC_AHBENR; + rcc_dma_mask = STM32L1_RCC_DMAEN; + } else { + rcc = STM32L0_RCC_AHBENR; + rcc_dma_mask = STM32L0_RCC_DMAEN; + } break; case STM32_FLASH_TYPE_H7: rcc = STM32H7_RCC_AHB1ENR; From 43498dedf651260ef34197e512d35e3ad7142401 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 27 Aug 2022 12:23:02 +0200 Subject: [PATCH 1325/1435] General Project Update - Closes #1263. - Updated CHANGELOG.md - Updated list of contributors --- CHANGELOG.md | 14 +++++++++++++- contributors.txt | 3 +++ doc/compiling.md | 8 ++++++-- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71188afb0..629b53233 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,12 +22,16 @@ Features: - Added support for STLINK-V3 devices with no MSD ([#1185](https://github.com/stlink-org/stlink/pull/1185)) - Updated gdb-server.c to allow external memory access on STM32H73xx ([#1196](https://github.com/stlink-org/stlink/pull/1196), [#1197](https://github.com/stlink-org/stlink/pull/1197)) - Erase addr size / section of the flash memory with st-flash ([#1213](https://github.com/stlink-org/stlink/pull/1213)) +- Added writing and reading for STM32WL option bytes ([#1226](https://github.com/stlink-org/stlink/pull/1226), [#1227](https://github.com/stlink-org/stlink/pull/1227)) +- Added parametres option_base, option_size for F401xD_xE ([#1235](https://github.com/stlink-org/stlink/pull/1235)) +- Added support for option bytes to F1xx_XLD (GD32F30x) ([#1250](https://github.com/stlink-org/stlink/pull/1250)) +- Added option byte address for L4Rx devices ([#1254](https://github.com/stlink-org/stlink/pull/1254)) Updates & changes: - [refactoring] Moved chip-specific parameters into separate files ([#237](https://github.com/stlink-org/stlink/pull/237), [#1129](https://github.com/stlink-org/stlink/pull/1129)) - Added instructions for bug-reports and feature-requests to contribution guidelines ([#906](https://github.com/stlink-org/stlink/pull/906)) -- Added travis CI configuration for macOS 10.14 to maintain capability for 32-bit compilation ([#f5ada94](https://github.com/stlink-org/stlink/commit/f5ada9474cdb87ff37de0d4eb9e75622b5870646)) +- Added travis CI configuration for macOS 10.14 to maintain capability for 32-bit compilation (commit [#f5ada94](https://github.com/stlink-org/stlink/commit/f5ada9474cdb87ff37de0d4eb9e75622b5870646)) - Updated description of chip id 0x0457 to L01x/L02x ([#1143](https://github.com/stlink-org/stlink/pull/1143), [#1144](https://github.com/stlink-org/stlink/pull/1144)) - Dropped execute bits from source code files ([#1167](https://github.com/stlink-org/stlink/pull/1167)) - Use proper Markdown headers for supported MCUs ([#1168](https://github.com/stlink-org/stlink/pull/1168)) @@ -35,6 +39,10 @@ Updates & changes: - Updated chip config files from the library structs ([#1181](https://github.com/stlink-org/stlink/pull/1181)) - [doc] Corrected file path in tutorial ([#1186](https://github.com/stlink-org/stlink/pull/1186)) - Improved chipid checks and printouts ([#1188](https://github.com/stlink-org/stlink/pull/1188)) +- [refactoring] Sourcefile 'common.c' ([#1218](https://github.com/stlink-org/stlink/pull/1218), [#1220](https://github.com/stlink-org/stlink/pull/1220)) +- Set C standard through cmake variables ([#1221](https://github.com/stlink-org/stlink/pull/1221)) +- [doc] Added make install to the macOS compiling instructions ([#1259](https://github.com/stlink-org/stlink/pull/1259)) +- [doc] Linux Install from code Documentation improvement ([#1263](https://github.com/stlink-org/stlink/pull/1263), (commit [#2926648](https://github.com/stlink-org/stlink/commit/2926648be78f32919c0624bf1060b17fffde8b0d)) Fixes: - cmake: Install shared libraries in proper directories ([#1142](https://github.com/stlink-org/stlink/pull/1142)) @@ -53,6 +61,10 @@ Fixes: - Define 'SSIZE_MAX' if not defined ([#1183](https://github.com/stlink-org/stlink/pull/1183)) - Fixed compliation for OpenBSD 7.0 ([#1202](https://github.com/stlink-org/stlink/pull/1202)) - Included 'SSIZE_MAX' from 'limits.h' in 'src/common.c' ([#1207](https://github.com/stlink-org/stlink/pull/1207)) +- Fix for libusb_kernel_driver_active & error handling for st.st_size () ([#1210](https://github.com/stlink-org/stlink/pull/1210), [#1211](https://github.com/stlink-org/stlink/pull/1211), [#1214](https://github.com/stlink-org/stlink/pull/1214) +- st-trace: Fixed clock issues ([#1251](https://github.com/stlink-org/stlink/pull/1251), [#1252](https://github.com/stlink-org/stlink/pull/1252)) +- Fixed flash regs addr for STM32L152RET6 in common_flash.c ([#1265](https://github.com/stlink-org/stlink/pull/1265)) +- Fixed flash, dbgmcu and rcc registers for STM32L1 ([#1266](https://github.com/stlink-org/stlink/pull/1266)) # v1.7.0 diff --git a/contributors.txt b/contributors.txt index cffef89f6..2425ae7f0 100644 --- a/contributors.txt +++ b/contributors.txt @@ -51,8 +51,10 @@ Greg Alexander [galexander1] Greg Meiste [meisteg] Grzegorz Szymaszek [gszy] Guillaume Revaillot [grevaillot] +Gwenhael Goavec-Merou [trabucayre] Hakkavélin Halt Hammerzeit +[hydroconstructor] htk Ian Griffiths Jack Peel @@ -115,6 +117,7 @@ Sean Simmons Sergey Alirzaev Simon Derr [sderr] Simon Wright +[simplerobot] Stany Marcel Stefan Misik Sven Wegener diff --git a/doc/compiling.md b/doc/compiling.md index a82941e8a..5d32385bd 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -119,7 +119,7 @@ or execute (Debian-based systems only): `apt-get install gcc build-essential cma 1. Change into the project source directory: `cd stlink` 2. Run `make clean` -- required by some linux variants. -3. Run `make release` to create the _Release_ target +3. Run `make release` to create the _Release_ target. 4. Run `make install` to full install the package with complete system integration. This might require sudo permissions. 5. Run `make debug` to create the _Debug_ target (_optional_)
      The debug target is only necessary in order to modify the sources and to run under a debugger. @@ -127,6 +127,10 @@ or execute (Debian-based systems only): `apt-get install gcc build-essential cma As an option you may also install to an individual user-defined folder e.g `$HOME` with `make install DESTDIR=$HOME`. +### How to avoid the error message: "Can not open shared object file" + +When installing system-wide (`sudo make install`) the dynamic library cache needs to be updated with the command `ldconfig`. + #### Removal: 1. Run `make uninstall` to perform a clean uninstall of the package from the system. @@ -216,7 +220,7 @@ To do this with only one simple command, type: 2. Run `make clean` to clean remnants of any previous builds. 3. Run `make release` to create the _Release_ target 4. Run `make install` to full install the package with complete system integration. This might require sudo permissions. -5. Run `make debug` to create the _Debug_ target (_optional_)
      +5. Run `make debug` to create the _Debug_ target. (_optional_)
      The debug target is only necessary in order to modify the sources and to run under a debugger. As an option you may also install to an individual user-defined folder e.g `$HOME` with `make install DESTDIR=$HOME`. From 8835d387f21755ddb20699c9cece82cf52d54249 Mon Sep 17 00:00:00 2001 From: Robert Jenssen Date: Mon, 29 Aug 2022 10:23:59 +1000 Subject: [PATCH 1326/1435] Fix compilation with gcc-12 --- cmake/modules/c_flags.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/modules/c_flags.cmake b/cmake/modules/c_flags.cmake index 44052bba8..6e22d4ff3 100644 --- a/cmake/modules/c_flags.cmake +++ b/cmake/modules/c_flags.cmake @@ -20,6 +20,7 @@ endfunction() add_cflag_if_supported("-Wall") add_cflag_if_supported("-Wextra") add_cflag_if_supported("-Wshadow") +add_cflag_if_supported("-O") add_cflag_if_supported("-D_FORTIFY_SOURCE=2") add_cflag_if_supported("-fstrict-aliasing") add_cflag_if_supported("-Wundef") From 2087711c23d38280ad5f69c39f23e06e19f8f214 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 23 Oct 2022 20:22:16 +0200 Subject: [PATCH 1327/1435] General Project Update - Updated CHANGELOG.md - Updated README.md - Removed support for macOS (Closes #1269) --- .github/ISSUE_TEMPLATE/bug-report.md | 2 +- .github/workflows/c-cpp.yml | 82 --- CHANGELOG.md | 3 +- README.md | 14 +- cmake/modules/Findlibusb.cmake | 19 +- cmake/packaging/cpack_config.cmake | 7 +- cmake/packaging/deb/copyright | 1 - doc/compiling.md | 42 -- doc/dev/app-example/CMakeLists.txt | 3 +- doc/version_support.md | 9 - src/win32/getopt/getopt.c | 2 +- stlinkv1_macos_driver/Makefile | 58 --- stlinkv1_macos_driver/README.md | 39 -- stlinkv1_macos_driver/install.sh | 16 - .../Contents/Info.plist | 82 --- .../Contents/MacOS/stlink_shield_10_15 | Bin 33840 -> 0 bytes .../stlink_shield_10_15.kext/Contents/PkgInfo | 1 - .../Contents/_CodeSignature/CodeResources | 115 ----- .../stlink_shield_xcode/Info.plist | 60 --- .../stlink_shield.xcodeproj/project.pbxproj | 480 ------------------ .../contents.xcworkspacedata | 7 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcshareddata/WorkspaceSettings.xcsettings | 8 - .../UserInterfaceState.xcuserstate | Bin 187405 -> 0 bytes .../WorkspaceSettings.xcsettings | 24 - .../xcschemes/stlink_shield_10.14.xcscheme | 67 --- .../xcschemes/stlink_shield_10.15.xcscheme | 67 --- .../xcschemes/xcschememanagement.plist | 37 -- 28 files changed, 8 insertions(+), 1245 deletions(-) delete mode 100644 stlinkv1_macos_driver/Makefile delete mode 100644 stlinkv1_macos_driver/README.md delete mode 100644 stlinkv1_macos_driver/install.sh delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/Info.plist delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/MacOS/stlink_shield_10_15 delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/PkgInfo delete mode 100644 stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/_CodeSignature/CodeResources delete mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/Info.plist delete mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj delete mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings delete mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/UserInterfaceState.xcuserstate delete mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/WorkspaceSettings.xcsettings delete mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.14.xcscheme delete mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.15.xcscheme delete mode 100644 stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index c733c2c2e..690bceb3e 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -20,7 +20,7 @@ labels: "" In order to allow developers to isolate and target your respective issue, please take some time to select the check boxes below and fill out each of the following items appropriate to your specific problem. - [ ] Programmer/board type: [enter here] (e.g STLINK /V1, /V2, /V2-onboard, /V2-clone, /V3) -- [ ] Operating system an version: [enter here] (e.g Linux, macOS, Windows) +- [ ] Operating system an version: [enter here] (e.g Linux, Windows) - [ ] **stlink tools version** and/or git commit hash: [enter here] (e.g v1.6.1/git-d0416149) - [ ] stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-trace`, `st-util`) - [ ] Target chip (and board, if applicable): [enter here] (e.g STM32F103C8T6 (NUCLEO-F103RB)) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 442b3ba43..8e798269b 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -188,88 +188,6 @@ jobs: run: sudo make package - name: sudo make uninstall run: sudo make uninstall && sudo make clean - - # macOS - - job_macos_10_15_gcc: - name: macos-10.15 gcc - runs-on: macos-10.15 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: brew install gcc libusb gtk+3 - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean - - job_macos_10_15_clang: - name: macos-10.15 clang - runs-on: macos-10.15 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: brew install llvm libusb gtk+3 - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean - - # job_macos_11_gcc: - # name: macos-11.0 gcc - # runs-on: macos-11.0 - # steps: - # - uses: actions/checkout@v2 - # - name: Install dependencies - # run: brew install gcc libusb gtk+3 - # - name: make debug - # run: sudo make clean && make debug - # - name: make test - # run: sudo make clean && make test - # - name: make release - # run: sudo make clean && make release - # - name: sudo make install - # run: sudo make clean && sudo make install - # - name: sudo make package - # run: sudo make package - # - name: sudo make uninstall - # run: sudo make uninstall && sudo make clean - # job_macos_11_clang: - # name: macos-11.0 clang - # runs-on: macos-11.0 - # steps: - # - uses: actions/checkout@v2 - # - name: Install dependencies - # run: brew install llvm libusb gtk+3 - # - name: make debug - # run: sudo make clean && make debug - # - name: make test - # run: sudo make clean && make test - # - name: make release - # run: sudo make clean && make release - # - name: sudo make install - # run: sudo make clean && sudo make install - # - name: sudo make package - # run: sudo make package - # - name: sudo make uninstall - # run: sudo make uninstall && sudo make clean - # Linux MinGW cross compliation # job_linux_20_04_cross: diff --git a/CHANGELOG.md b/CHANGELOG.md index 629b53233..f48840c3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,7 +42,7 @@ Updates & changes: - [refactoring] Sourcefile 'common.c' ([#1218](https://github.com/stlink-org/stlink/pull/1218), [#1220](https://github.com/stlink-org/stlink/pull/1220)) - Set C standard through cmake variables ([#1221](https://github.com/stlink-org/stlink/pull/1221)) - [doc] Added make install to the macOS compiling instructions ([#1259](https://github.com/stlink-org/stlink/pull/1259)) -- [doc] Linux Install from code Documentation improvement ([#1263](https://github.com/stlink-org/stlink/pull/1263), (commit [#2926648](https://github.com/stlink-org/stlink/commit/2926648be78f32919c0624bf1060b17fffde8b0d)) +- [doc] Linux Install from code Documentation improvement ([#1263](https://github.com/stlink-org/stlink/pull/1263), (commit [#43498de](https://github.com/stlink-org/stlink/commit/43498dedf651260ef34197e512d35e3ad7142401)) Fixes: - cmake: Install shared libraries in proper directories ([#1142](https://github.com/stlink-org/stlink/pull/1142)) @@ -63,6 +63,7 @@ Fixes: - Included 'SSIZE_MAX' from 'limits.h' in 'src/common.c' ([#1207](https://github.com/stlink-org/stlink/pull/1207)) - Fix for libusb_kernel_driver_active & error handling for st.st_size () ([#1210](https://github.com/stlink-org/stlink/pull/1210), [#1211](https://github.com/stlink-org/stlink/pull/1211), [#1214](https://github.com/stlink-org/stlink/pull/1214) - st-trace: Fixed clock issues ([#1251](https://github.com/stlink-org/stlink/pull/1251), [#1252](https://github.com/stlink-org/stlink/pull/1252)) +- Fixed compilation with gcc-12 ([#1257](https://github.com/stlink-org/stlink/pull/1257), [#1267](https://github.com/stlink-org/stlink/pull/1267)) - Fixed flash regs addr for STM32L152RET6 in common_flash.c ([#1265](https://github.com/stlink-org/stlink/pull/1265)) - Fixed flash, dbgmcu and rcc registers for STM32L1 ([#1266](https://github.com/stlink-org/stlink/pull/1266)) diff --git a/README.md b/README.md index bc491189e..b889de389 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ [![CodeQL](https://github.com/stlink-org/stlink/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/stlink-org/stlink/actions/workflows/codeql-analysis.yml) [![C/C++ CI](https://github.com/stlink-org/stlink/actions/workflows/c-cpp.yml/badge.svg?branch=testing)](https://github.com/stlink-org/stlink/actions/workflows/c-cpp.yml) [![Linux Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=linux&label=linux)](https://travis-ci.org/stlink-org/stlink) -[![macOS Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=osx&label=osx)](https://travis-ci.org/stlink-org/stlink) Recent new features and bugfixes can be found in the [Changelog](CHANGELOG.md) of this software project. @@ -22,7 +21,7 @@ The stlink library and tools are licensed under the **[BSD-3 License](LICENSE.md stlink is an open source toolset to program and debug STM32 devices and boards manufactured by STMicroelectronics. It supports several so called STLINK programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG/SWD. There are four generations available on the market which are _all_ supported by this toolset: -- **STLINK/V1** _[obsolete as of 21-11-2019, continued support by this toolset] \*)_ +- **STLINK/V1** _[obsolete as of 21-11-2019, continued support by this toolset]_ - transport layer: SCSI passthru commands over USB - stand-alone programmer - on-board on STM32VL Discovery boards @@ -38,8 +37,6 @@ It supports several so called STLINK programmer boards (and clones thereof) whic - stand-alone programmer (STLINK-V3SET, STLINK-V3MINI, STLINK-V3MODS) - on-board on some STM32 Nucleo boards (STLINK-V3E) -_\*)_ *Note: Support for the STLINK/V1 on macOS is limited to 10.15. Due to the deprecation and removal of macOS Kernel Extensions (KEXT) there will be no support for this programmer on macOS 11 or any later version.* - On the user level there is no difference in handling or operation between these different revisions. The STlink toolset includes: @@ -70,15 +67,6 @@ Please ensure to select the correct version for your system (i686 or x86_64). Th Alternatively one may compile and install from source as described in our [compiling manual](doc/compiling.md#Windows). -**macOS**: - -We recommend to install from: - -- [homebrew](https://formulae.brew.sh/formula/stlink) or -- [MacPorts](https://ports.macports.org/port/stlink) - -Alternatively one can compile and install from source as described in our [compiling manual](doc/compiling.md#macOS). - **Linux**: We recommend to install `stlink-tools` from the package repository of the used distribution: diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index de3712eca..7442c8cc4 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -10,24 +10,7 @@ include(FindPackageHandleStandardArgs) -if (APPLE) # macOS - FIND_PATH( - LIBUSB_INCLUDE_DIR NAMES libusb.h - HINTS /usr /usr/local /opt - PATH_SUFFIXES libusb-1.0 - ) - set(LIBUSB_NAME libusb-1.0.a) - find_library( - LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS /usr /usr/local /opt - ) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) - mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) - if (NOT LIBUSB_FOUND) - message(FATAL_ERROR "No libusb library found on your system! Install libusb-1.0 from Homebrew or MacPorts") - endif () - -elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated into the system +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated into the system FIND_PATH( LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr/include diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake index a4f1ae073..8766fb2e0 100644 --- a/cmake/packaging/cpack_config.cmake +++ b/cmake/packaging/cpack_config.cmake @@ -15,12 +15,7 @@ set(CPACK_SET_DESTDIR "ON") file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/dist) set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/dist") -if (APPLE) # macOS - set(CPACK_GENERATOR "ZIP") - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-macos-amd64") - set(CPACK_INSTALL_PREFIX "") - -elseif (WIN32 AND (NOT EXISTS "/etc/debian_version")) # Windows +if (WIN32 AND (NOT EXISTS "/etc/debian_version")) # Windows set(CPACK_GENERATOR "ZIP") set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-win32") set(CPACK_INSTALL_PREFIX "") diff --git a/cmake/packaging/deb/copyright b/cmake/packaging/deb/copyright index f5dfdc51b..c8ff30973 100644 --- a/cmake/packaging/deb/copyright +++ b/cmake/packaging/deb/copyright @@ -2,7 +2,6 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: stlink Upstream-Contact: Nightwalker-87 Source: https://github.com/stlink-org/stlink -Files-Excluded: stlinkv1_macos_driver Files: * Copyright: 2011-2020 stlink-org diff --git a/doc/compiling.md b/doc/compiling.md index 5d32385bd..5f6852a93 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -183,48 +183,6 @@ Choose one of the following options _before_ connecting the device to your compu 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` 2. `modprobe -r usb-storage && modprobe usb-storage` -## macOS - -### Common requirements - -The best and recommended way is to install a package manager for open source software, -either [homebrew](https://brew.sh) or [MacPorts](https://www.macports.org/). - -Then install the following dependencies from the package repository: - -- `git` -- `gcc` or `llvm` (for clang) (C-compiler) -- `cmake` -- `libusb` -- `gtk+3` or `gtk3` (_optional_, needed for `stlink-gui`) - -To do this with only one simple command, type: - -- for homebrew: - - with gcc: `sudo brew install git gcc cmake libusb gtk+3` or - - with clang: `sudo brew install git llvm cmake libusb gtk+3` or -- for MacPorts: - - with gcc: `sudo port install git gcc10 cmake libusb gtk3` or - - with clang: `sudo port install git llvm-10 cmake libusb gtk3` - -### Installation - -1. Open a new terminal window -2. Create a new destination folder at a place of your choice e.g. at `~/git`: `mkdir $HOME/git` -3. Change to this directory: `cd ~/git` -4. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git` - -### Building - -1. Change into the project source directory: `cd stlink` -2. Run `make clean` to clean remnants of any previous builds. -3. Run `make release` to create the _Release_ target -4. Run `make install` to full install the package with complete system integration. This might require sudo permissions. -5. Run `make debug` to create the _Debug_ target. (_optional_)
      - The debug target is only necessary in order to modify the sources and to run under a debugger. - -As an option you may also install to an individual user-defined folder e.g `$HOME` with `make install DESTDIR=$HOME`. - ## Build options ### Build using a different directory for shared libs diff --git a/doc/dev/app-example/CMakeLists.txt b/doc/dev/app-example/CMakeLists.txt index 5f71a5d4f..69ba2090e 100644 --- a/doc/dev/app-example/CMakeLists.txt +++ b/doc/dev/app-example/CMakeLists.txt @@ -1,6 +1,5 @@ # Warning: This example assumes that you are building on a host with pkg-config available (e.g. linux). -# The logic required to build under windows/mingw and/or mac was intentionally omitted to keep this -# CMakeLists as small as possible. +# The logic required to build under windows/mingw was intentionally omitted to keep this CMakeLists as small as possible. cmake_minimum_required(VERSION 3.4.2) diff --git a/doc/version_support.md b/doc/version_support.md index 01d9dddb1..0f1849697 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -10,15 +10,6 @@ Up on compiling c-make will **automatically** download and install the latest co - Windows 10 - Windows 8.1 -### Apple macOS - -| Package Repository | libusb | cmake | gtk-3-dev | Supported macOS versions | -| ------------------ | ------ | ------ | ------------------ | ------------------------ | -| homebrew | 1.0.25 | 3.22.1 | 3.24.30
      gtk+3 | **10.10 - 12.x** | -| MacPorts | 1.0.25 | 3.22.1 | 3.24.31
      gtk3 | **10.4 - 12.x** | - -NOTE: In order to use a STLINK/V1 programmer on macOS, version 10.15 is required. - ### Linux-/Unix-based: | Operating System | libusb | cmake | libgtk-dev | Notes | diff --git a/src/win32/getopt/getopt.c b/src/win32/getopt/getopt.c index 85e8804d8..ff0a2fd91 100644 --- a/src/win32/getopt/getopt.c +++ b/src/win32/getopt/getopt.c @@ -179,7 +179,7 @@ int getopt_long(int argc, if (match->has_arg == required_argument) { /* Only scan the next argv for required arguments. Behavior is not - specified, but has been observed with Ubuntu and macOS. */ + specified, but has been observed with Ubuntu. */ if (optarg == NULL && ++optind < argc) { optarg = argv[optind]; } if (optarg == NULL) { retval = ':'; } diff --git a/stlinkv1_macos_driver/Makefile b/stlinkv1_macos_driver/Makefile deleted file mode 100644 index e6ba6309b..000000000 --- a/stlinkv1_macos_driver/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -### -# Makefile for STlink-v1 support -### - -VPATH=src - -SOURCES_LIB=common.c usb.c sg.c logging.c -OBJS_LIB=$(SOURCES_LIB:.c=.o) -TEST_PROGRAMS=test-flash test-sg test-usb -LDFLAGS=-L. -lstlink -lusb-1.0 - -CFLAGS+=-g -CFLAGS+=-DDEBUG=1 -CFLAGS+=-std=gnu11 -CFLAGS+=-Wall -Wextra - - -LIBRARY=libstlink.a - -all: $(LIBRARY) flash gdbserver $(TEST_PROGRAMS) - -$(LIBRARY): $(OBJS_LIB) - @echo "objs are $(OBJS_LIB)" - $(AR) -cr $@ $^ - @echo "Compilation of library completed." - - -test_sg: test_sg.o $(LIBRARY) - @echo "building test_sg" - $(CC) test_sg.o $(LDFLAGS) -o $@ - -test_usb: test_usb.o $(LIBRARY) - @echo "building test_usb" - $(CC) test_usb.o $(LDFLAGS) -o $@ - @echo "done linking" - -%.o: %.c - @echo "building $^ into $@" - $(CC) $(CFLAGS) -c $^ -o $@ - @echo "done compiling" - -clean: - rm -rf $(OBJS_LIB) - rm -rf $(LIBRARY) - rm -rf test-flash* test-sg* test-usb* - $(MAKE) -C flash clean - $(MAKE) -C gdbserver clean - -flash: - $(MAKE) -C flash - -gdbserver: - $(MAKE) -C gdbserver CONFIG_USE_LIBSG="$(CONFIG_USE_LIBSG)" - -macos_stlink_shield: - ./install.sh - -.PHONY: clean all flash gdbserver diff --git a/stlinkv1_macos_driver/README.md b/stlinkv1_macos_driver/README.md deleted file mode 100644 index e0f9256e8..000000000 --- a/stlinkv1_macos_driver/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# Installation instructions for STLINK/v1 driver - -When connecting to the STLINK/v1 on macOS via USB, the system claims the programmer as a SCSI device. Thus libusb is not able to initialise and establish a connection to it. To solve this issue Marco Cassinerio (marco.cassinerio@gmail.com) has created a so called "codeless driver" which claims the device. It is of higher priority then the default apple mass storage driver, what allows the device to be accessed through libusb. - -To make use of this alternative approach one needs to go through the following steps: - -1) Configure System Integrity Protection (SIP) - -The above system security setting introduced by Apple with OS X El Capitan (10.11) in 2015 is active per default -and prevents the operating system amongst other things to load unsigned Kernel Extension Modules (kext). -Thus the STLINK/v1 driver supplied with the tools, which installs as a kext, remains not functional, -until SIP is fully deactivated. Without SIP-deactivation, st-util would fail to detect a STLINK/v1 device later on. - -In order to deactivate SIP, boot into the recovery mode and run ```csrutil disable``` in a terminal console window. - -2) Reboot the system. - -3) Install the macOS Kernel Extension (kext) (ST-Link-v1 driver): - - Open a terminal console and navigate to this subdirectory `/stlinkv1_macos_driver` - - Use the command ```sudo sh ./install.sh``` to install the appropiate kext for your system version. - This should result in the following output: - -``` -Requesting load of /Library/Extensions/stlink_shield.kext. -/Library/Extensions/stlink_shield.kext loaded successfully (or already loaded). -``` -4) Reboot the system. - -5) Verify correct detection of the STLINK/v1 device with the following input: `st-util -1` -You should then see a similar output like in this example: - -``` -INFO common.c: Loading device parameters.... -INFO common.c: Device connected is: F1 High-density device, id 0x10036414 -INFO common.c: SRAM size: 0x10000 bytes (64 KiB), Flash: 0x80000 bytes (512 KiB) in pages of 2048 bytes -INFO sg.c: Successfully opened a stlink v1 debugger -INFO gdb-server.c: Chip ID is 00000414, Core ID is 1ba01477. -INFO gdb-server.c: Listening at *:4242... -``` diff --git a/stlinkv1_macos_driver/install.sh b/stlinkv1_macos_driver/install.sh deleted file mode 100644 index f9878bd46..000000000 --- a/stlinkv1_macos_driver/install.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -ISMACOS=$(sw_vers -productVersion) -case $ISMACOS in -10.15*) - KEXT="stlink_shield_10_15.kext" - ;; -*) - echo "OS X version not supported." - exit 1 - ;; -esac -chown -R root:wheel $KEXT/ -cp -R $KEXT /Library/Extensions/stlink_shield.kext -kextload -v /Library/Extensions/stlink_shield.kext -touch /Library/Extensions diff --git a/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/Info.plist b/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/Info.plist deleted file mode 100644 index 2077b9c8a..000000000 --- a/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/Info.plist +++ /dev/null @@ -1,82 +0,0 @@ - - - - - BuildMachineOSBuild - 18G7016 - CFBundleDevelopmentRegion - English - CFBundleIdentifier - com.libusb.stlink-shield - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - KEXT - CFBundleSignature - ???? - CFBundleSupportedPlatforms - - MacOSX - - CFBundleVersion - 1.0.0 - DTCompiler - com.apple.compilers.llvm.clang.1_0 - DTPlatformBuild - 11C504 - DTPlatformVersion - GM - DTSDKBuild - 19B90 - DTSDKName - macosx10.15 - DTXcode - 1130 - DTXcodeBuild - 11C504 - IOKitPersonalities - - DeviceDriver - - CFBundleIdentifier - com.apple.kpi.iokit - IOClass - IOService - IOProviderClass - IOUSBDevice - bcdDevice - 256 - idProduct - 14148 - idVendor - 1155 - - InterfaceDriver - - CFBundleIdentifier - com.apple.kpi.iokit - IOClass - IOService - IOProviderClass - IOUSBInterface - bConfigurationValue - 1 - bInterfaceNumber - 0 - idProduct - 14148 - idVendor - 1155 - - - LSMinimumSystemVersion - 10.15 - OSBundleLibraries - - com.apple.iokit.IOUSBFamily - 1.8 - com.apple.kpi.libkern - 11.2.0 - - - diff --git a/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/MacOS/stlink_shield_10_15 b/stlinkv1_macos_driver/stlink_shield_10_15.kext/Contents/MacOS/stlink_shield_10_15 deleted file mode 100644 index 8dfd2fb304f4ab6e7e64739030d81ed7202efdc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33840 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ТBb3*WWK z?UN6@diTogpDrt@ySev|fonG|^_`qkJ9X=Cy_cG%wtR8q$QyIwyO%FAJU?*Wb2ki~ z@X&$&53j!Bx?N(`xl`ts-8ALFi^{$}eSF`B?DzdOPyhA7O`R{?;Te7Zf~Ml-?HD}C zzy^16-@=8+zjF12Mt{AH9;;*FJ96->E63&y;CVjYi*V%3tel)XCTBuXpR0$IOfRmy zzP!}dK!-M4`OHafSFtT8*KVf;>b2WTDobqTZdXO64Lid} z%%ZKwS#Xqdvdj0MXLKpRG8)&T?uuK|NKjgbDqZckezTvSo7YKi!Ufp}r zx9W#fqzv}t$ - - - - files - - files2 - - rules - - ^Resources/ - - ^Resources/.*\.lproj/ - - optional - - weight - 1000 - - ^Resources/.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^Resources/Base\.lproj/ - - weight - 1010 - - ^version.plist$ - - - rules2 - - .*\.dSYM($|/) - - weight - 11 - - ^(.*/)?\.DS_Store$ - - omit - - weight - 2000 - - ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ - - nested - - weight - 10 - - ^.* - - ^Info\.plist$ - - omit - - weight - 20 - - ^PkgInfo$ - - omit - - weight - 20 - - ^Resources/ - - weight - 20 - - ^Resources/.*\.lproj/ - - optional - - weight - 1000 - - ^Resources/.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^Resources/Base\.lproj/ - - weight - 1010 - - ^[^/]+$ - - nested - - weight - 10 - - ^embedded\.provisionprofile$ - - weight - 20 - - ^version\.plist$ - - weight - 20 - - - - diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/Info.plist b/stlinkv1_macos_driver/stlink_shield_xcode/Info.plist deleted file mode 100644 index b0a0228d8..000000000 --- a/stlinkv1_macos_driver/stlink_shield_xcode/Info.plist +++ /dev/null @@ -1,60 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - KEXT - CFBundleSignature - ???? - CFBundleVersion - 1.0.0 - IOKitPersonalities - - DeviceDriver - - CFBundleIdentifier - com.apple.kpi.iokit - IOClass - IOService - IOProviderClass - IOUSBDevice - bcdDevice - 256 - idProduct - 14148 - idVendor - 1155 - - InterfaceDriver - - CFBundleIdentifier - com.apple.kpi.iokit - IOClass - IOService - IOProviderClass - IOUSBInterface - bConfigurationValue - 1 - bInterfaceNumber - 0 - idProduct - 14148 - idVendor - 1155 - - - OSBundleLibraries - - com.apple.iokit.IOUSBFamily - 1.8 - com.apple.kpi.libkern - 11.2.0 - - - diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj deleted file mode 100644 index 373600c64..000000000 --- a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.pbxproj +++ /dev/null @@ -1,480 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 52; - objects = { - -/* Begin PBXFileReference section */ - 8CD33C31149BB80D0033D618 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 8F90850924786F39009109AD /* stlink_shield_10_15.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = stlink_shield_10_15.kext; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXGroup section */ - 089C166AFE841209C02AAC07 /* NanosMouse */ = { - isa = PBXGroup; - children = ( - 089C167CFE841241C02AAC07 /* Resources */, - 19C28FB6FE9D52B211CA2CBB /* Products */, - ); - name = NanosMouse; - sourceTree = ""; - usesTabs = 0; - }; - 089C167CFE841241C02AAC07 /* Resources */ = { - isa = PBXGroup; - children = ( - 8CD33C31149BB80D0033D618 /* Info.plist */, - ); - name = Resources; - sourceTree = ""; - }; - 19C28FB6FE9D52B211CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 8F90850924786F39009109AD /* stlink_shield_10_15.kext */, - ); - name = Products; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 8F9084F524786F0F009109AD /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8F90850124786F39009109AD /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 8F9084FF24786F39009109AD /* stlink_shield_10_15 */ = { - isa = PBXNativeTarget; - buildConfigurationList = 8F90850624786F39009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_15" */; - buildPhases = ( - 8F90850024786F39009109AD /* ShellScript */, - 8F90850124786F39009109AD /* Headers */, - 8F90850224786F39009109AD /* Resources */, - 8F90850424786F39009109AD /* Sources */, - 8F90850524786F39009109AD /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = stlink_shield_10_15; - productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; - productName = NanosMouse; - productReference = 8F90850924786F39009109AD /* stlink_shield_10_15.kext */; - productType = "com.apple.product-type.kernel-extension.iokit"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 089C1669FE841209C02AAC07 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1130; - ORGANIZATIONNAME = "stlink-org"; - }; - buildConfigurationList = 3EEA308708D71E4B002CBB49 /* Build configuration list for PBXProject "stlink_shield" */; - compatibilityVersion = "Xcode 11.0"; - developmentRegion = en; - hasScannedForEncodings = 1; - knownRegions = ( - en, - ); - mainGroup = 089C166AFE841209C02AAC07 /* NanosMouse */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 8F9084FF24786F39009109AD /* stlink_shield_10_15 */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 8F9084F624786F0F009109AD /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8F90850224786F39009109AD /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 8F9084F424786F0F009109AD /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPreprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; - }; - 8F9084F924786F0F009109AD /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPostprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; - }; - 8F90850024786F39009109AD /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPreprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; - }; - 8F90850524786F39009109AD /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "script=\"${SYSTEM_DEVELOPER_DIR}/ProjectBuilder Extras/Kernel Extension Support/KEXTPostprocess\";\nif [ -x \"$script\" ]; then\n . \"$script\"\nfi"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 8F9084F824786F0F009109AD /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8F90850424786F39009109AD /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 3EEA308808D71E4B002CBB49 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - APPLICATION_EXTENSION_API_ONLY = YES; - APPLY_RULES_IN_COPY_FILES = YES; - APPLY_RULES_IN_COPY_HEADERS = YES; - CLANG_ADDRESS_SANITIZER_CONTAINER_OVERFLOW = YES; - CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; - CLANG_ANALYZER_GCD_PERFORMANCE = YES; - CLANG_ANALYZER_LOCALIZABILITY_EMPTY_CONTEXT = YES; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; - CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES; - CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_STATIC_ANALYZER_MODE = deep; - CLANG_UNDEFINED_BEHAVIOR_SANITIZER_INTEGER = YES; - CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES; - CLANG_WARN_ASSIGN_ENUM = YES; - CLANG_WARN_ATOMIC_IMPLICIT_SEQ_CST = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_CXX0X_EXTENSIONS = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_FLOAT_CONVERSION = YES; - CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES; - CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_INTERFACE_IVARS = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES; - CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES; - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; - COPY_HEADERS_RUN_UNIFDEF = YES; - CREATE_INFOPLIST_SECTION_IN_BINARY = YES; - DEAD_CODE_STRIPPING = YES; - DEFINES_MODULE = YES; - DEPLOYMENT_LOCATION = YES; - DEPLOYMENT_POSTPROCESSING = YES; - DONT_GENERATE_INFOPLIST_FILE = NO; - DRIVERKIT_DEPLOYMENT_TARGET = 19.0; - ENABLE_HARDENED_RUNTIME = YES; - ENABLE_PREVIEWS = YES; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_CHAR_IS_UNSIGNED_CHAR = YES; - GCC_ENABLE_FLOATING_POINT_LIBRARY_CALLS = YES; - GCC_ENABLE_KERNEL_DEVELOPMENT = YES; - GCC_ENABLE_TRIGRAPHS = YES; - GCC_FAST_MATH = YES; - GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES; - GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_SHORT_ENUMS = YES; - GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; - GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_UNROLL_LOOPS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; - GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; - GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; - GCC_WARN_SHADOW = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_STRICT_SELECTOR_MATCH = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNKNOWN_PRAGMAS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_PARAMETER = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - GENERATE_MASTER_OBJECT_FILE = YES; - GENERATE_PKGINFO_FILE = YES; - GENERATE_PROFILING_CODE = YES; - GENERATE_TEXT_BASED_STUBS = YES; - INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; - INFOPLIST_OUTPUT_FORMAT = XML; - INFOPLIST_PREPROCESS = YES; - INLINE_PRIVATE_FRAMEWORKS = YES; - KEEP_PRIVATE_EXTERNS = YES; - LD_GENERATE_MAP_FILE = YES; - LINKER_DISPLAYS_MANGLED_NAMES = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; - MODULE_NAME = com.libusb.stlink_shield; - MODULE_VERSION = 1.0; - ONLY_ACTIVE_ARCH = NO; - PLIST_FILE_OUTPUT_FORMAT = XML; - PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.libusb.stlink-shield"; - RUN_CLANG_STATIC_ANALYZER = YES; - SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; - SEPARATE_SYMBOL_EDIT = YES; - SUPPORTS_TEXT_BASED_API = YES; - TAPI_VERIFY_MODE = Pedantic; - VALIDATE_PRODUCT = YES; - VALIDATE_WORKSPACE = YES; - VERSIONING_SYSTEM = "apple-generic"; - WRAPPER_EXTENSION = kext; - }; - name = Debug; - }; - 3EEA308908D71E4B002CBB49 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - APPLICATION_EXTENSION_API_ONLY = YES; - APPLY_RULES_IN_COPY_FILES = YES; - APPLY_RULES_IN_COPY_HEADERS = YES; - CLANG_ADDRESS_SANITIZER_CONTAINER_OVERFLOW = YES; - CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; - CLANG_ANALYZER_GCD_PERFORMANCE = YES; - CLANG_ANALYZER_LOCALIZABILITY_EMPTY_CONTEXT = YES; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; - CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES; - CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_STATIC_ANALYZER_MODE = deep; - CLANG_UNDEFINED_BEHAVIOR_SANITIZER_INTEGER = YES; - CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES; - CLANG_WARN_ASSIGN_ENUM = YES; - CLANG_WARN_ATOMIC_IMPLICIT_SEQ_CST = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_CXX0X_EXTENSIONS = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_FLOAT_CONVERSION = YES; - CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES; - CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_INTERFACE_IVARS = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES; - CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES; - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; - COPY_HEADERS_RUN_UNIFDEF = YES; - CREATE_INFOPLIST_SECTION_IN_BINARY = YES; - DEAD_CODE_STRIPPING = YES; - DEFINES_MODULE = YES; - DEPLOYMENT_LOCATION = YES; - DEPLOYMENT_POSTPROCESSING = YES; - DONT_GENERATE_INFOPLIST_FILE = NO; - DRIVERKIT_DEPLOYMENT_TARGET = 19.0; - ENABLE_HARDENED_RUNTIME = YES; - ENABLE_PREVIEWS = YES; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_CHAR_IS_UNSIGNED_CHAR = YES; - GCC_ENABLE_FLOATING_POINT_LIBRARY_CALLS = YES; - GCC_ENABLE_KERNEL_DEVELOPMENT = YES; - GCC_ENABLE_TRIGRAPHS = YES; - GCC_FAST_MATH = YES; - GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES; - GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_SHORT_ENUMS = YES; - GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; - GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_UNROLL_LOOPS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; - GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; - GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; - GCC_WARN_SHADOW = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_STRICT_SELECTOR_MATCH = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNKNOWN_PRAGMAS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_PARAMETER = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - GENERATE_MASTER_OBJECT_FILE = YES; - GENERATE_PKGINFO_FILE = YES; - GENERATE_PROFILING_CODE = YES; - GENERATE_TEXT_BASED_STUBS = YES; - INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; - INFOPLIST_OUTPUT_FORMAT = XML; - INFOPLIST_PREPROCESS = YES; - INLINE_PRIVATE_FRAMEWORKS = YES; - KEEP_PRIVATE_EXTERNS = YES; - LD_GENERATE_MAP_FILE = YES; - LINKER_DISPLAYS_MANGLED_NAMES = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; - MODULE_NAME = com.libusb.stlink_shield; - MODULE_VERSION = 1.0; - ONLY_ACTIVE_ARCH = NO; - PLIST_FILE_OUTPUT_FORMAT = XML; - PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.libusb.stlink-shield"; - RUN_CLANG_STATIC_ANALYZER = YES; - SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; - SEPARATE_SYMBOL_EDIT = YES; - SUPPORTS_TEXT_BASED_API = YES; - TAPI_VERIFY_MODE = Pedantic; - VALIDATE_PRODUCT = YES; - VALIDATE_WORKSPACE = YES; - VERSIONING_SYSTEM = "apple-generic"; - WRAPPER_EXTENSION = kext; - }; - name = Release; - }; - 8F90850724786F39009109AD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - MACOSX_DEPLOYMENT_TARGET = 10.15; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 8F90850824786F39009109AD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - MACOSX_DEPLOYMENT_TARGET = 10.15; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 3EEA308708D71E4B002CBB49 /* Build configuration list for PBXProject "stlink_shield" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3EEA308808D71E4B002CBB49 /* Debug */, - 3EEA308908D71E4B002CBB49 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 8F90850624786F39009109AD /* Build configuration list for PBXNativeTarget "stlink_shield_10_15" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 8F90850724786F39009109AD /* Debug */, - 8F90850824786F39009109AD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 089C1669FE841209C02AAC07 /* Project object */; -} diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 84f174f7b..000000000 --- a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c5e..000000000 --- a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/UserInterfaceState.xcuserstate b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/project.xcworkspace/xcuserdata/vm-user.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index 913b254d69fcea63feaa9a2379a3365b4b105003..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 187405 zcmdRX2Y3@l)Bo+N-05UXvLvH|)htm$wdo}x$hHguHzc{y6k`i;Ft%}_lia5FkOJum zy@Vu?9@2ZSKtg)&y^@~%XYX_>E#J+4U)TsAM|>SEtwsi&v0-``hA=~!Vaz1vcxE!=X9}1?rihux)H4lCjG50YU=}is z%!$k*rioe1G&3zsC$p4U#hlKZ!JNsQ#hlHY!<@@p#9YN(&0ND=%WPt{GTWH#%ns&8 z=4R%0<^kqG=27Np<{9P%<|Sqy^D6Ti^A__S^AYn6^DXlo^F8we^E2~1(xNPsjcmw{ z`XU$VhX$f!&~a!IIv!0%epG-8Q4tEDAc~?BP#v0w>QMuVq4{V5T8NrZE9yX>DOwb5icZCH#VW-~3Zghoai-!N#rcZ0ic1vh6;~*(R$Qmpq}Zz1q1dIkNpZ8{ zHpQKayA}5-9#lM{cwF(6;#tKDihYWg6|XAZP`s^pPw}DR6UFC>uN2=Zeo!1z{Hpjv z@wXByRZ32&RqB*kO0&|Uv@0D-x6-TZuRKOML^)hJLOEJFPB~FIN$FP>DW@o>DNB_V z%CNFZS*x6_j4J0TW6FifMapL75@m;SnR2CajZ#pasyst^w(>mXh02SS>y(!(uToyC z+^F25+^)P{d82ZV@>b;?%Du{al@BN%Rz9YDQu&PXdF4yW1ImNS*OhN6-&KB~{8;&! z@=N76%I}pwDSuJ^uKY`dR7w@A;#HX{gUY1pqq3=TR4!Gns-J40YOrdUDql59HC8o2 zb)0Ils!&y|3aUy}<*JaXQdOgxrJAd%Q#Gg-s7_QZR<)|yRZCSXRI61dt4>j!t~yI~ zuId8SMXF0xm#MB)U8CBd+N|29+NruhwOe(I>UPy#s(V!Ts~%E4s(M28wCXw4i>m#q zS5&X5-c-G#dSCUC>QmJhs;^bwseV-btolv$r(%qsjp`RG*_hU%gg+iF&>I3iZ|M>(ranTh%+%yVN(SZ&u%?zEgd-`abo8 z>POU%tDjOotA0VfPyMp`RrMR{x7F{dKVo*NKUIIF{#yNw`UmyTtb$dtDpt+1tcf+V z*=!%y!a7(d>tp+|gV<5*Xm$)cnf0>;>{Paltzm1~nQQ|aW9PH2>=L$(J&Qe?J%>G) zJ&!$~y@0)tUCUm?UdL`=H?o`9&FmKTdUhAPo4uXg%ihi2!#>15#vWu}WnW`oXWwAo zWZz=nX5VAqXTN2?W4~vAV1HzPVt;4<;1~{ZET`oLa09txxIx@tZU{G&8^#Ui^0<6% z1UH%+%T46`T#%c_P3KCuQm&G#;;OkQ*T|j7E#jKE#auJDglpqY=FaBM;m+mGvo zmuN26T%);GvqiI2vrTi0=2p#Zn%gyZXztWJqIp#FnC2PHvziw*FKIr|e5m^{(5Ajue zHDANe=I8PCd?SA%zld+*7xPQ_PX1i}JpO$C0{%jNEq@VzF@FhvDZh!|%x~eh^4s|B z{A2u6{L}pN{0sbk{s8|f{~G@m|2F?V{{jCA|0(|^{}ulo|2=<*|C#@t|3k}YkyfQu zYjd;?tyAmLy0so{uGXvdY5Qr9;jYr=Y4f$?wG*@xwa03Uv;l3gcD8nocCI$6JwaQi zou{qWHfUqoMr|wih<1s#O}kRNO1oOSMti#U4DHq0YqZyDuhVYOZq#nlZq{zmZq@GO z4r%vj@6zto-mQID`-t{6?d#e%v~OzP(!Q;INBge!J?;D2kF{TEf6^Y({;d5wgURTV zVac#&*fQ)HeKT@092w3GSB5uZP{!blkr|^hMrVx4n3QpRMrB4-Ms-F_Ms3E-j9D48 zGv;K>&6tiy1Fv?914naUkR6j8`%aX1tp5TE<%$A7*@+@m0px8HX}{&dkizW$H5x znOT{}OjD*gGdr_SrajY>c}(V@%)yx>Ge>1k%bcEBl3AKrmRX)zkvStXlo`&f&YYVW z&0LVVP;**lW9E{~w#>6K&(1t2^W4nyGSAPvAoIe^wV4-XuFJeSb4%vd%x#%BW$w;= zEc5ZqCo-SRd@A$l%x5y6&3rEN`OJNpuVucM`F`dHnO|gnslz&jPN`Gr)H+tj=`=cC zr`73oeRNKpOE*9_P&ZjuqzmYRx@o#HUAZo-i|A@}wYoXFxw?6}dffuuLS2(?v2Ka3 zO}ARNMt73#WSyWpO?Rg5BHhKhOLUj&*6FU$U9H=u+pgQ8+o`)rw_CSIce8Gz>g)t9w!Ry6$b=JGysupX$EQeWUwP_ml3B?swfEdPdLdwfYQwrrxMG>CO5a zy-V-a57Zx{AEqCnAE_UupQJC;7wH4~Vttu@hQ3l?rJtprtv^8@)3@kb^-J_^`lb36 z`jz_A^k?bM)}N!lP=B$0y?%p!tA3k)yMBj$kN#Huo%(z9_v#%Y){qyN#s7?cK;L1W+zI)mQO*N|gy7@P)|!ENvu`WXfp1{;PL#u&yL#u>&N zCKx6fjyIGWDhx9WAw$>@F;r$0M-H^3A>z1tBv+l~eC+q&Khq4~c zdLrxTtmm>`%-WyzO4e&xZ)Uxd^?uezS)XQok@a=fcUeDX{hak%)}Kbks4%LH8e@i0 zZ!{XSjaFk{qtoay`iujNgN#FsdB%~(F~;%6V~xif3ycBdRO57GnQ?|OVyrgKG|n-e zV5~RJH#QoZj4j4CW2bSsah35TBQc(4JkxlN@qFW2<0Z!R#w(0h8?Q5NGHx~QFzzzm zWW3pUoAFNL-NyTj4;mjaK5l%<_^j~-<38id##fDR7~eL&XZ+CkiScveSH^FRKNt@g ze>MJL{M&?0DideYnslZtli6f3*-Z|U+vGL%HyvXdVj6B5VH#~3XPRi5Wb&JeOjAtL zOr@p@Q`l5xsx{3vMNRWeG1EfRB2%+ziK)Z1%(T+9#w3_dHJxEP+jO4kLes^jb*9Tr zSDCIgZ8U8$Z8u$Sy3w@9bgStO(_YiPrUy(9n;tVgX?n)=yy+#=0n!!C%@0va^ zeQf&7^rh(=)Ay#IOuv|ZH~nQsW~G@m^X5#m!E7@3G26^JW|ukF+|NAFJlH(UoNpdw z9&4UpKF&PZTxc#f2hAnsa&yRBX|6HPGS4;FnH$Ut%qN-`n_JE8=B4Hp=GEqt&8L`8 zH=kub*L;EbBJ-u@%gk4ruQ6{hZ#Hi;?=;_F-fh0ce7pHB^F8MK%@3I$H9ui~+WegP zMe~01E9TeCZ<^mRzig)WUI3^*%{gTY-4tIwl%wN zwlmw4?aLmJJt%u@nHnvyaU_KD!`0kUcefdUjd%jO<8ub@t5cIoT&E&VJ5ErTt?EcupEma&!zmg6jwErph1OVCncDYt|ym6jUIEX!O=ou$FD zz;dExv8C10ZdqzsVOecC*>Z~Ibjw+mb1fHGF0x!|xy*8<Qd%Vx_q%TCJ;mfeXUlJv zKdp>aVO3i-)(orOYP4ost=7I)r`2QiSqE4LS%+HltRt;stmCc6T93CDSOeCn*6G$V z>kMneT5X+aont-0T5p|iZL~I7TdZx?PU~{(D(gvBVm-}zru7`_`PQ}8ORVdyS6HvM zUT588-D=%o-DSPWdb9O5>z&rSt@l|Uv_4{e-1?ODS?dedeb$$)uUg-*zHNQa`l0m` z>*v<5tlwIHupYAhYW>6dw+-7=HqNHC>1s#JH|G|HrzJCHrh7M zHqkc8=C>8urr4(0N^KRku&v5gYnyG0+UD6}wuQDuwr1NBTZe6#ZKZ9EO|YG6JHvLi z?L6Cswu^1+Y?s@vvR!N2Xxn1jZoA%gqiv7vR@)u6y|#O857-{IJ!X5-_KfX$+e@|s zwu83UZExA$wS8dw*!G$2OWQZL?`=QXezE;-`^%2(N;_-k?U{Ci-DK}$x7l;-E_<%M zpM9Wxuzi?4-#*Gd);__0oPDyr&|Yj0+Dq)^_K>~OUSpqSpKGtPH`o{0PqZ(#x7yq7 zOYJM{tL-P-PqCkFKg)iu{Q~<%_Dk)T*{`%;W8YxkY~NIiKfzmGf=R4>^Z&e$DwK=Whpgs2rR_>(Du}9A<~bVRtwjZim;=-*Jp% zh-0{8gk!X0oMWP6lEd#Pa!hedbCfzN9AQV5qt-Fo5p~RS#2gD9iyY04C5{fqGRI2C z8i(LG)p3U7Y{z+y3mq3b);TVBT;;gdvC*-`vE6aK<3`6G$E}V#9D5!2Iv#L5?0C%a zq~jUK^NyDs2OI|-uRGpyyzBVD@v-AG$Cr+89N#;Ba{S`>-SL+bIh9V<$vZQh2B*o{ z$7yrsI9<+MXFuma=V0eBXTEckbF6cM^El^ZXQ8v$8FZF7%bg)-rL)F4%Q@Fs=WK8; zaGvN~>}++mJC{0FI9EGQcAnxq-FcStT;~POi=3A_FLPe$yvDh~x!JkRxzl-rbGP#r z=k3nBocB2IcRu8N)cJ(-Y3Fm!7oGc^uQ*?GzUh3&`M&cb=cmpuoL@V?bN=Z3+4-CE zPZ#4-xYRCGHUIt^uw=uA#0x*GShG*Lc^luH#(=u7GQ*Yr3n< zHNzEgRl8=o=D1F9)w|}q8eL7U7FV0A)3w~S%5{>9xK4AO={m=CzH6=P64!dy6|SpY z*SR*iwz_t>cDZhH-R!!}b*JlY*L|)BU5~gPcRl5L*7bsGpX+7UtFAX(Z@b=eedzkc z^||XS*SD@8T!&o0y8dwe?Z$4En{#X3dUs!Uj@#jOx?OI!+vD!%9^@YE9^xM39_t?G z9`8QRUFt4#m%A(6Gu$C}*j??O>3+lgw);Kzhwe|@pS!tT4A0q~^E?-NF7~YRT<*EbbFF8iXNzaM z=X%eLo;{vhJ$HEadhYc+;Ca~dnCD5)GoI%?FL@4l4tieqyybb<^MU7M&u5-5J>Ph~ z_x$Af#q+!8uUwR?%w===+{|1>Ex%s)Ha>wRQ$UQE1 za&BR6ac(fTB)2>_lv|lwn;Xk*%snx;IkzRZJ+~uwdG3nblXHb!l6z+ES-BVFUYNTs zcYW@=xgX|!l>1rk=eb|!ev|t{?vJ^@{WPKFXzqhW_q){MsFXl#oO1L z<8^yI-hSTx-a+2M-r?Rn?-a>DYcd9q&E%lapL*B5r+FRqD?VaPT z^Um|m_b%`*@-}%}y-U2E-lg7^-c{a{y@K~N@9EyNz2|r@@LuR$=Uwl;+Ix+6vv;TW zdhZ_Z&E7k`_j&L4KI(nU`;7M`??LZd-nYFUdO!Dm;r-70v-eM*!l&`+ec8UgK96sJ zZ>VpiZ@lk#U%)rrH^W!$o8znZHTqh7t-d9`Gks_I&i0+-JJ)xf?|k0{z6*V8eHZyI z_Fdw;)VI#J-nYTG(YMLB*|*DgyYCL)oxZz#dwqBN?(se5d))Vg?@8Z2-+tc#-^;#t zeDC_+^L^<1(f5<@knd;TFTOu~fA?ehp?<1<+J5?e#(utj1N$A*Z)l~jxwENhKciuI zM$2R{dd65?79O@JwxWF|{EXM~s(kfLb?xn&m`p||U_r5oF)&$zlHkXM!BK-Rf6N&F z==|cMq50!Sj2t>@{Fre=$B!uj4({dj~XVWwh*bCSJ=|r(bm$`6l;qXf>fhM7mgU3@AnrC9px_=H*{Ry*wI7B z~QZwm3h3E@f|QZfIFn+*Y?Z7B%!wd;nktb#2vk?NyEKjq{pf)r}ns!;Q@g znqu%x)G#o$VF@By77oSQJ6hW6fIQq$*AXkK>!^zwTtMot?|`~!LKo?h8f?i{TUwgt z)wKoXR-*=M@;gzY#8jATYJqlHXCC+G!(kR=$mF=Ih@Y!! z6l-r>&`cS_P$TZBYK$$D5E9(!pp_ksK-L&*m#Bix?X6HXmYSA36JWwj{~MWNW(qTv z2{O}|=}ZYz%9JtXOa(K82?=H)Tj(QL1gl^Z>_T55M{o#E!6mqFWFkx@Q^iy>HPl&{ zS@8QDW-b#2$MFawgptB1VYKKrW8wF4LJ>i)Nj{WS6r0z%U_q=cr5kQZE2W)H9gVGE zP1?bVw#LPEZ7WLZRL=7VfV)I+tVx@J<8y7dOj1{&lZmnx;Y;S2UZE1)_E8Amj zanFfE!KX8mzeWx2aI6XXA8SY&Kx`)1+z?w{QP;7M8iyJ~`W}=<|Bz*sRO>E^&94I) zD`+LYy#q#9DAw8*YlmOzI-oS)K35j6L3GHd!P_eJLT*&7*EghdMGe{V*Kym5%wRVY zh!k&96hx9@;9)h<*q)F@yGVOww4&zEC5%fh9d9WB@WJTa8C z)Qe6#H)%LJ3`B~>b&bu*kE0MV=_o0mFY_k96DA82ghFAwaD3D-yrv#T-7rwI6p}!V z)U}FQDBQ3_R10^sb=G%uw#6iudx&{tBlEB@QJA!!d5n1+Bz^*7$x}0vZB&Y_3&%nr zIc`pSM^j_-qGq?%`$=c0xjXx1<8he`868%!Q?{Wi93VxFglIV_EYwUK#o z6ScYN3b62u##aHNUYbHevYi z;WQex4_~@?XeazK90K}0Wk(Qk$gMFcl(f zOWO*Fh4qUd7V2g4sPwhe?vJ$HpM>c`-ah6Ru+y*1Z!m|~ceb@bFiOLr>_Q1aufEFs z!Tibm#rzGWbOs@Wkpd}^3aJqbziAK;?k<}-O#@|O%Hp9$rkO@$MQdzWdk6KibPa;6 z;1-aMBtlly(6?Ef;^QNtD}7elx3ry9M+0tIp1^XLbm%5hCa1$AcLfghn#P9cVBbf`+1DXgJD4`DlbtEz}6L!c1Y7Fk6@-%-w-Tq0wjz8jHrE z@n`~?C`5%5gbtxoSSqX%Rtsxr^dBGwr;!y>1Cnb*rO(2USAiAdpBV=CPFc{|*wj$5 z5PH}yQxENdx}q(%w6UeLJ*}}qn&3l%cNqFeUE6|K+->9J(|aI~i|uc3k99=q7RaKc zhm`cc^7EqkqoanNgpH$#T?@xLIzSULqM?89t*6S`bFbutt82h&m#tfjrbttj{J}I7 zVfybx(@_a3MP;ZQRiGItgu+6dFi)r#8ibfIUsxb46dHG;N>qiaQ4Oj^Gtn$G8_f|; z6c!0h!eXIWXcd+SZ9+Rubgbiw$HNLFZ`6oUW51J_)DdfgSQeEXs2fR9V|#s5OM9$=j_`IM9Wg8~DaPpTZOOvt_x9DO;^OXK z^-@Wu-Tw6Vt7*7&WJVumnN=NK=XmDRL}D%Qgrt(uiJxRzh|b zPny7eHlr126|)vbIs73vu?C%#j!4ic=^vbq&X7K+T9r4%owo*Ja7rh-x@GU*$t|9T zE@b*|Lg%9kgk{3=O=vB;NLV4Pq#ltY0gE{{sG$&4Qr8Mbp%Vm*PnYzyJh-G`4wh?e zs#`&q8j=duGmmT#CWZZpl|8x=U6tOYYtePm2NK678g4fWCkc}dply&(KvsdaqaDo4 z==$1racKf!T@Zwm1wTOty#9w@@;ANv?LfIhH=>)F{+rQFXgAs;5aATz)XnG?bSt_| zI88WRI77&=plkgUAdQbanq(8tS-h>U@ z;+Szm+-!}tb*yj~!Zf;|rA=JK+T?hWP9%Qk>$S5fmV<^;$mBM}G&_yTkwTU3dE!zt zO|voz9nmQulAc~+R_@M%b4>@)tLQcKI(h@WiQYnQqj%7|=som4`T%{1K0+U(Ptd36 zGxRz70)2_TLSLhA(6{J2^ga3k{fK@-htSXH7xXLo4gHS(K!2jY(BGKB2xF|kO02?a z%wi5}Fpsr317~6#)?)+C!bWVuW}J=tU<9_=!;xb&0EAR{)!eJc2mADF5;~HFxXX06SHlBm$;wU}=*Wr1%9yj0^ zo{tycg}4!)h!^1|ycjp*7Tk)L;5OWjJ8&mnikIQ#cm-aGSK-xo4L%8k> z1Kx-?;mvpp-io*3?RW>?iLb}I@D2Dzd=uV{_u!lHE%;V^8@?Uif$zk3;l227d=I`C z--qwV58wy!L-=9*2!0elh9AdI;3x4@_-XtMeilE6pT{rY7x7DYAKs4-;Fs|$_#l22 zzlLAOZ{RoaTlj7K4t^KEhu_B^;1BUf_+$JD{uFr9!1pD_8}m&?tC?R*|8|ROl3Xg+Y;} zFe*$6vm#s3M_~~z6fP1j7A_Gk71jysh0BD?g)4+Bg{y?Cg=>Ush3kY3!bV|}uvyq5 zY!$W%+l3v%PT_iCmvDn{qi~b3Ti7GqEZid8D%>XAF5Ds9DcmLO748=95$+Z46Ydut z5FQjB5*`*F5grvD6CM|y5S|pC5}p>G5uO#E6P_1d5MC5s67~uEg#*IN!Yjf-;Z@-^ z;dS8+;Z5N!;cej^;a%Z9;eFu);X~mg;bY+w;Zxx=;d9{&;Y;Bw;cMX=;alN5;d|i+ z;YZ;o;gImN@Qd)P@SE_v@Q3iH@R#s6K@35NAWV>gASFR6g46`D1aSmu2;vFS5|lwu zCP6xa^aL3Q$|A@}kcl8OLD>ZLA;?0Il^`2Ic7pm6ltYk%ASXdCg4_go2+AeMOOTJC zegyR=XaGS234#*eAc6)HG=!j`1Pvo-I6-*?)M01Wh1l zB0I<`NVo=mdi52%1MwJwXiw#R!^D&;o)M z64Xf0i3BYosEMG(1T_=XLQpF~O9*NssGXn=f;tIWO3*TbmJ_sspp^uzB4{;1YX~}t zppyv_2qG}46Lcy;rxA2IL1z$jCP8NrbT&cf5Ogj<=Mi*1K^G8oAwg>ix`?2Q3A%)! zO9@&>(0YO{Bj|F1t{~`2g03RyYJ#pI=vsoVBWMFb8wuJ(&}M?R5VVz`Z3Jy6Xa_+% z3A&!3T?E}g(2WG$M9^-6_7HS4LAMZeD?zsrbUQ(J5OgO&cM-Igpt}jWhoE~2x{sjy z33`B_2MKzJpoa;1grG+WdW@jQ33`H{Ckc9rpr;9XhM;E&dXAvy33`E`7wLjitFSBj zDspOJu_LVm1z6I!khrq$fK?2XINDdQ_7@ceBf;`Ae@Qf4G(9Y)O$w*N1qyEB3 zuqqJs1Ex$pgi?FEQim%mD#}BVKvA@!#2+ax50xfl7)}}bc4esYmjsJM-~{0aN;m+C zDHc^wI2?#XEBuAiqow|`U~wQEiNX>wS`i8q2Ww<;MpLFC38p}40mzVK4M&4zz)@aQ zSr~~HRF)N$1Z2)}@s7~t5;PYm^B0r^qUB}Lq5!m46b%K!<&~krKtjHWlp#OSR1cKU z7}yjn8Y~M({3RvPh<{3geG+9Kd{}ncwLqkBYP3956bQ+J`YEFgNjXp=OIy7JL%#g#v};r4`|5Q7|FEG|DnM&QjhgmbAe>CDs1ga8%NG zxH?!Ii9)B#iu|FXXi2aj^&@=fmASi;@n0MV%dKe&E4S{y1bg#jBZfe;`K-!zwOrfA*#$zM@X z5-gMq7pRE@pfC<5^j8F7SeGQ!wS@AH=qgFL&<~_AW>eG!Vt`M^MN62cgYvt(@{0j2 zt~MHNWaBKO)ZL7kpsp?tO%FqmOXzncr61obdV)S0o*t~Ipyn-_4%z~{ieJgiuAwj% zR1|A%YFR-yd?8-I$f_tVNeM{;CCW)7@|Q#cp)%T!DWUR8SlLSx$*G5ad6dhO#s$N#AXpZNP7M};rGusZDM|7R zDY-k1yeLpnQeImcD2qf($|Yx!WxtqG_wS9mqC6Y{UxXPU41+@ESx0$%U3jVjCFK=j z6Y^9PNlwa_Q;zhG7lmM&4NVV5VDd>w7x9Ot1QLF973H$0wIk0mX_mUSce*q?ZKQP0 z9`UG^qSR63K5n73<}}(O@TQa;Vmqa@4^0R!ZhbYoV~bqBdGF z)gKN(G>1_mlioo|(~T{DFGGqGsF-ZX9D6B;H4R+i2uEs@xyZegD&0-vRMNa!TUt^Yd&%>0-o5mEWIvm4elp%dERQn-0IULWElqVNWjny^4 zR@ds)q8{at9;z&hRze~NmX@{i45jz=LLa9UJu%Vu=P5^DG(FbV9BXnz<)yPJwt6*q zY-N0Qlc8UtggLzs!W0@xc-Vo%LBeF7u>L_x=rL~|E*p!5nef4T7_k@T; zr#D%~wE6GK{mz2|&O9QA<<(*)URV-@E+q{A4dqDbc!EQYGgLBJvENf-PZD0j zPNj?%z~Gk2f9irAsEIFTAjPHwPn?2e;$JASDTxh&l$A#-f(f+WDM6nk0aZa1CesK^ zQZmS2l%{`@hN?SS9gIxvJ%?5z%9EYsDfQEpLNroaA;T(_l*F7Q5!Vr^(kod?k&{9Z znF?kGw~LgQm!u{KN}f`tcyPHyS(HYUNr_TCIFUS-`om!GC@ek#u=1i)c)aUM17%53 z4>*n3dyqjkw$emtoJlFC2Lct42L`KXVnQ>!P+5Yu52YQOqy>A-s4NG%xC_G+QAwv_ zDVa;;>e7@e3uU7qDgGD=Bzz!|Tc!EFGKX^HCYw#+kXApn>GZB6)625WOlBM(pI-lZM6>0u7meLMJbYa}o zxKcd3vU)Ym>`H<&X?hIvH#7i)B~+enkqMM>_>maJm2G7(8n1B3Iy{at_d^wM3ZZU+ z7~$#SqZVug$tt7+5N08TNKIXplPSxvRF=X}fI2i?Z;Ck&SQZK{kO2Wdq_qB!yk=1r zQeJy1ub3}EQ_|EYi&aeN2By)K!@Q7CUb3mwAsM7x?o_ToO`xz6)|oJ=CKgh18zq$5 z(F-;BQnEUuET^P{Q%REofS=H5L8<{jsRzPiqFAB~QASTHW1`FM)hX40SS7J7vmEWlD-Kv!@zz zX}3mt8maLH#MSD&>Enr+gNe7^CtPT$1x#?*_THck)hw-_r5;$yoI2jrq0lvyjGAPKp0 zN<%Qo6hPfooN1HAQ{{%9kP;QQe}c4`A`R&xQ@9pVwbEn_DOI9Gl-Wi(kLj87Fe=_j z*>bwDfwANM2q8!IryD3`S0@qO;xO>LDU%z;PioQiCR8rM!6{`>evJepB>^$Y>Lr?xLKwo;Xt%{K|VMnLSAc^@~KwC=&3O z$|B!S={!lgc*PiM^$>p`yMdH25=^Xnln+sIa8OxpX`)JMC2f{^loAh25<|GE3eu9B z6trpa7nE5MC`=1;Pf#usioh9HG3}xC=qMBg64~X`lwd>(0ZnqEVl@vY1FASk%pq~{ zhha%bgPA{AQVCOp+~wye{~+LB-Z8WQj?^`{p@6%3bz=UHKztElXl_@TTr<4bGheWb zHkVjDBqB(nz5SHW)2%&8brD)TPSe^elzd<}@_2ek`;-t5c;!yL)^j5wJR~T=;#!)> zCDur9QgR=vl3wj2>KVd?xWor5i5}P`t$BxXIMX=d6k>XrmMy(cY5Vm~D`oJoh%YRW z<^QNVe5pS)JwTJTE>#ERrn^}B$JW9qqLsh z`X>roe_e3zbxVhPlGitNK_0}3|Wq!De$rBz=d#R%snO69BYd&SR~l)`%fh_Fvv*1 z9X(RbxG`WCx?}_U!+Z`q6112uBmGH{#vheT@sJ}1kwV%xsISLiR1Ad~aReB;`$jVg zr~|;7%%4&`S1Bm}aYwu1SO^=2a_&mgr;xn)snQ>9w_RgUcX82L`p|UJg4tuL5<>eI#d*o5(BMp8@nbaM6QmAa&krb-ycAZzeI`dUR^ry}wp7W5I1C;rg!!=w8fe0E6*TN(zpWRVSrEG%^#}+IT zm$;CKrc}9A(<$HB!|{m)WwD$t2WV+omt0h-$|y*e;g{awxUyj8f@oTisLZNnP|hwh zO^=)qe__zUR8>(Pq`S@Hp_tkzR3;O9d8)_}!C;{WqZkGNs~IGnnqX()cENj{17D^03&&mZ2A_;?C-fR>CACU6joHkCk2?_r3A4&l!(o3 z6t0&cCd1KqlmZ5&jQ~uX$s|+NNkMwCX)holCWiPiYTvM*jQPjqw@ZDh*PHX>E>=t-ooSR0pT#dtWEB|nLR_7WkW<6R_= z>o8s=OeDB67@=Tej#k1nutYCUqZs3k7DMi(zcNxzBdILOnG|JmuPD-!*YIfH&_Zdl zipv6ffZ!m;{w78f3_F57$zlE(!AC zWl9CA4)_zgx`ZNi@qKvyueGhE9u}11iayQ?C!FXZp-|e;Sx?!!jK7}Q<0~ssEv4Zp z;XqkpPQQYJbcst{Kzu_b=6%;@V0#p4}L6AJT6o<(+FeS0D zS8bwg%={m2qpY%|B>fnsYAbE0i$hn}wb5rt-4!iOjrH(Mk~A=AxBzWTg)<&>O*ye{cCS}^ZnPN{(w@dHX)Kf*|!l?l`5)Rw4 z^q@3d)}$4ARku;pE@hmfK=l{EehPR$O^^VxsC$NTCj|~3t+-N{5d|(PFBA_TNb5*KnY;B2pVIC@+#XiB8^T~nZaf(;`FYo|L>|PI;Pf^T&?vP_f zMI+_Wkt1NsKGFl~v;Vf|G*|5b?*)oi_%C`cE=PI*+(!Ysq>jDYH^s5(qNclLUZ!yW zCS=gu4UV-#fw3e?!)p)NuTt!z9^9#-meP~qU>|XFsJqZ_P~gD7P%3PR)AL;cs9A{{ zdWpvtRBuzrilc>0j7ISgtax@MB+i`0pa~e}A$Sgko^+M{|2>L+)Z;0EE`_;J0HShP z>d7(HhZL{qA4@B5>%d_n2x?Pdqdzf+eL@ju{9{B(LKzn}*x~F?icS*npHujw4#!;- zAj3o66Dg;qg#_$Z6!xg&N-wZwfoi(xB-`p+irJ-VcvJ%n@@;O zmnu?nFN=2Qzi3e`Yru>lm7-uzFQLU>DQxA@+CF8RiYND|!Ntc(XvUaaxk>xLvgCiz zCd&Us6X5_9?8{4Nc{l*4a01cNKxAq;B$6pJ>E9Ims3+xw7sP`L9N!Je##dtsb<_hZ zMHTVHzMG4xRTQzyV(zHiiKZU%*&8)SQI2|erpg7CPY9*um9VguqiVN+s@78Yf8+BN zu)kF57oYo!n_8`-SaXlo)YKYMS_@tjKS~W7*|M|J(Vob+yCuBpEZSC=#X|4OO=(M3 zgn- z423%C2_VH1A{0Fo4Dl|pI93n&Pm;l7Y?X;fH~c@TOnj0P&YQ|A8$r>!?AE3DM@msu z^oy!MjaX^-hZ4v7)uRtDP*;c|SfD~8N7K-%U?@@vX=o8FTV;X9QM4{ay~79u6)#9P z>EWCn>Z|IB6s&iL5JgMaE={6DtyY$6(ox8jfP!b_;NVcAf3lw@#*v?b^;|iitI@71 z3&D;M9JGgBJ$S^!Us4+mCXk9KQtz`=SEO)qRw;!;26E@7P?X-sb-JFU)G=5lK3o|s zFD`~t#pT7)(Qg@W8U^e<>~s~&A1SBX`-zDz9GDR;Oq_L6mr}GY6}H3p1eE{tYLe$8 z6S}IPFuf<8J(NPF!h(2IkUnDp5{CUyWJ?~+P=_gI?~B>qFr!74(lfM)ya;xl6HouE zt0-#ki<;h0B@yK*GOkp}Y~Z+PB)KQ2uKjm1i|F#ov3n{q`#;E>vQVJ1)`~lru*^yN zdGsI1oEV1UQ%*F?h5SSeI%1XwS*h%%^C)WX>(RsO8OoobVtAxD3eU?Vwsh1n3fcR_ z(Ho?!fwJ-dY`j$@M&`nQr`41STf!;C0-ls8$^BnM(RC zQ^ejE%snI0GBeHMAS;qlWeJy1yxs#z8eU48C3c!VIU9u!6ALDF2Sw|B!IXmLu4{%9 zks;V(>52-+_M{qz_?&NeDm>|$vTLqhMwZqY6Des)!zhf-*|52qvsTdZGqq)#T2PTA=9pyNAbq}V?1yyTE3J~E~hBR|6>$70{q3aAfK8KUDb=y zBxO;55znu}$>Z*t6GKl~xUg8<;*rI>mLksRF5b}~#-Fl_uNCQtN<4Qb!*8VUq5lzh zX~P5NcY4HH#@|Bmi~k+Is1TTR>2#5DZb7}BVvhfJm{SVn60Q1r3KRI(Fi}W2#HYl{ z5-$f)-$)_L{v9OjCKS-q$8aDl^kbW=S5&ot1DAz9l8Xe;6W zu~y(sEfv-9C~{(FS$&W;Q1L(3K4B7 z7D9eclKdtjxQj#mnfh~h?o)afF1+TJzLve~o4hxxzfgb4Kqn4Q*7M~AaMVBqAC}fc zxU;pjrLALF{JqQZ>lV^!dbk5Z{jK^t=>jB)F@AXfeW&v#_4iandO1?J@5Gles()1f z1n=AE`aO7S{i03kLzKDaFXL}NR{x^@lj*-j{j2&n_3!FG2zs5MHwb!@ptrWD|5E>r zo@Nn2ZxaLt*-y|%LVgXs8H8SmQY&5#LVuen-5DaiVVE|TxSb_&^Gm!rmSZ!aIab5+ ztd`9n=pBOICFnhZ-roWjo>ZZ=j1R6n842&ZK8C(sxo;KRlSA*sfE!t2%jl&x?V-A5 z;%krL4bb-VZ{v65gzMo2%^od9gcU~lvA-<$r^l`R7 zTvfvkU=AE(ktG<*PVB~f zEHFNieOG)3ngeu7S7svmIkfPVqOmFN+ zAq%fqJg=n*{8E0wcme@lX_06qou>dSu&9;3Nxxm9hVdnb!R{?c2^%~g-3yvH#9^fN z@-=+~7Y1W5-zKip=^daLZdsAtRaMeR2UAGo z^o}+7C`MnJ4lfCSYZIEK7v9qQ;o`S=gOjRR>KhR49+BguyoHlT5MD%`|H-@^bG zQuunNpkoGZW`bvr%bS~k%+m`Qy|^S6r?IEdbg^E~0P>6?4lO^`x$lZ5802{kJ(SyPYHGq>?GJlu$y4dR`zqyt%v=J{hHuh zm?GhB!+r$!mmNEC3jw_dLh{rBAZ&7|C)6wXb2+_wu94n&)&NggAD%MMOlRPRqjvB^ z>@U>4ekRzvk^Plm-{BnmPxdd#;STS!9Oje>P!5LtfP~L-9H&Y1SuTUKG5v4gGC3Wm z=L}pHXXH$rnak$-a29qw!QhjF2p&xE5Q2vi45}PXa2~<=1dkwiBm|QiI6K!D{%>bI zoQpa&+yLQ$zd_}r2p%K;JBr#M2&RD9Wk3BLzByN%^g*2od(c<`o+D;Oad%1tUHCjJ zm6j$S@Rr7aPZ;qkII*M0Zwo{9XSy90XDw-s1{DV*@T$r~QJ~IMQqTwlREuF3H;t=3Qa-%j7 zJX*SHWfeDO6TMqS`f41c_}qAc$I=uZa(?bu$T7I%xJlgc1dk*5ID#i9atyA33oyn_ zTp?FPFfdKn#1(T>2%bprvBKa`V?(F|#(xhtevF#2AU?XdGHyl}h!7VhcoMYRqmpQrXrAXNB?pO#F_zv+JrUC8lVDtQzVQ?2^dxv{I_@H~h;cj+w z_j<2e5@x_K$yP05Xq(X}{ngHmx}NLcI=Q9XGHyAyf?LV0;#PBO2%bi8CBd@@t|J)w zzL?;4f>#iHGQp>VU&y8rxYMY{2zLs1D#6nUE+M#dGj}?726raGWdxTK9EocTJW#$( zEb)r*R4qalQxaR=2=7>P!}A!)$3Nf?F^!Q#zJPgT6L%rEmf#A4!@{K3nf=@)+@;() zZaui-Wy}HYa_$Q5O71G|D!A=%7k4#x4ResYhPw_zR6FRGzET7{zH@PNS?A(;aDA-7 z7;A3m_F-22!n(FPxV5t_1P>p?;F?6pgqz|Q7Y3T));wT=k0f4r2WKn+C%2ONVOO{o z@UIyL$Z|pkx4>kn;8w;vsG;c{ezd+0S`goX9>3VIuC;YIoiiZ{w8O1_OJhy+nwsGi zaL*ZBO}e;!cqzT%uLe9u`XGe{-rX#Jou4->fAp~ShDF1}E8q^%#luS)=fOn1Vz?ME zmeIRkhf8lg9X6ldl1o1s9)Hm)y+d%J_z!e-cx-unOngcEu!UlT;5KoaA@sp|iM~^% z+hU#D!fmCC+1?0xUZ(eM*=x8Rsg|XxgghohZ$hjuYUzaeZs?NE7PxWM-Pl~;1owWr zb4BqRM~)klDtj(`?@n~py-<9o>=1WsIlZqIxWV!O1v;u<6qC?EZFO=&%iYM)n~{2O z{#&`*MCY#}cxHSd#@$K%_AYKO!PNxU_U5+UO*xO?`LZd$p{D$n`;K4;&9UB0`D2PH55c^0 zi2H@$2I!h0mxl2VqJ|s)_ZyQ&aGJvOYDC)09o!$H5tF?%=;9`v*^3Fq@EQmHZ>G~A zjjBh}X;=*>nrxs{v|u_-h9;BXMuHdhVmgf>#dKmypn-MpiSbdmBWk$qf4|`p z^Y1*kJw8^~+)GfUUDa4L*5n`*yJ~P6V9hTM!n$58n4BdOE&NAAIy6vN?O_aRyc(!7 zK!VszaGPw%0o0HKHL${KA$Un|h8)t(kgx!3jT`d%|6Ad7>Eh_&MxuuHH7%TK5`B#t zjvPvp@c+?_V>J_dHsf&`ScZWaI|yDbo6%3rSfGK$Qzya8dNX5jH!}taUK%&!o~Yrj z|3l+(5fl=mZ85latJg6}yL(7enldJ7cMZ1qh>RU^M5eXzAI%xkRP}7m8cnTe&Xok8 zB%5$;f}rp489bKVj)?EODv&XkNY)?18){%RI#8dK~^`)lwT z>~V|2mGwthiKI94A5Ge7=nYG|lOv9h03jSPlBP9cT4oM={%xvHzp-&e2@Z zv+>qyE)tCgn^Nb<#=DdnZ=Gg6!BAp3yEo%qkzzb4-MO0Jv*O0PBWk$kf4}h(=}!EW zCM|8zMp_r^c`2!Z9&0veHl~b7+G9gMLr&b13wyC-GVAHu(7!Zm_iFfmpi{cEn4$bcZ4cRUoMKN@Xmu zA|#cMX=Rsw52aoDI*Crr>c}UvHSV!>XR7zT@4%aV?EspQ6gA|DZw-dfAu7d(s z1Km<=FBY#XPZG#&KCXEZ_6amk5WIe)<|%?NJIv;T<~a>)ZqduZyLTl`-TO4J(@n7T zngi@5npZRj*~>JqiCd0WiaU^35e$9;tBPy3Yupm#bi1`wFl21!WYiXs%n_SRXIyiIw;2y7ojVzFMylJE62ZA>X`RRvWWYnKE zzeDKK{G$0)^Bcii2;NHYw$1Pt{7?J?{@w})Pv9U=11%g>)FukyaR^??s}q9pEWtYx z6?vZLGZJF(u)y0XMjp1K_J{*uNoTBWMFrH27el$Q4Xi1i z41hO7%1sR8N5Yumhx2)SJ`cN9Hxqmd!M758+ZLvZAI*>9$HLv@_;!NtAoxy-*@tfI zK-m|@ig+}paA8Y}=ovY%H`)=XYhMv*3DP$Q!+qs5X!G!1;r8}fq9p!$T0@2cxA<2W zikh%xC>55aJ*|Sej{1dki=I|(MeYc^6{+DBelqXp3;065h|%%^zL>e1Imie3X|;9D z^$X!r^yUS%B4i}iwzzgN1u2BRjG5rkumeR8@XQpy7DXZW9)j=U1cuLQP9Avh!SAir@Z>6s;>WE)sF73$IfCd*wph^+x0O1JUOA&NpwV4m|kuDvOga?jI ze5HJBD$%>dmtB~Wy>4!4j!Dq9{7iVsH4M;n?lk3X;%Ct|jzA^bd=4L_t^(=v{Tulc z2!4Q?)zb+^ge{Kwv9`8YL;SM&6@leY;co|<1&gF@IKBb4*7z7dpI<=mg9JZB@WXUt zTDneNKJF20Zl?w7mNpq@7{nad+?$vaN_UPlijo%C+8CJNrUy{EbIj;$tY0)W z*3=44x@r|Yr7&s@99YO7lb1KdJuYwLnl=0QX0Ub(-&zg#6gSj$)Rku`*UuAowes=~ zAgoZT)RT^{@hz3!L0;o)nMcq1wb%OS=>d4lTU*4}(b8&U&>0(c8?sqW!)r4#b=iG# ze1irL89sW<*a^o~`kG-M4#IN2J3oJfo3`#AJ7%;y5B?|qF>dTwcU813JYnQ0*nmij z0mGKVHV%DX+KJLeXyPP5H4K85WfhXU$Z!II}9+ZV8y-H$8zl%FhaF8VZyHs&S3c(;`3C3O>4Gfh$F%x&d zv17pjE!J`4L8R1nH;wBHA5T1Xc3HTnQ4El<1GZ^m-?@3q$Ih>>udf@KH*f5G7-Raf z@buVJZfgYBhoGzPX7%fiKtZS5Vv z)Y<~ap4w)?gEiFQ=;0;!I)N(bvmL$;cdTfNmDaT{f(PiOdO;QM|WK#iysor^Z0O=t_+ zhMq&Op|{aj=v(wNHsR5DEFO<1;s|cSOR#`X#b@Dl_;S1*@5QgiVccQiYPNigKDPZRtM!Os%>9Kp{M{K8Jg$DhKV%Adxc&Y!`b$)Cla4Tn$g zi$rq{(VR~-*AUJ9MDqaAJVZ1P(>cPNJpa>9r}CvR#lv|Ydr@qDU1w8=bfg$^`;J(9 zaZ4NATi!lfB#TK&H~>h0!ioS6&O!zuZYje7#uCUJ=yITmZfYh&j>IP3haob;(+Hs$ zJrWILK@NhFA49OROTYQs+UWK;z5Q1_N=OeJ0J(f}ELW4*m|N z|Bd`k{(62Fe*=Fbe-po(-^1U`-@@O@-^N1~9IGrfg6U9yf<3{leq}|BPXpx6Gh`juh0wY8Sel=>i;s1Mq;s3Gs7VuGAUD!Bb z$7nXmEXmHwtPI|k;%%u?LIhG`jUcs@LXegMB|xF2ZBE_YU8qoZck1r$?(X`Xb7yCE zW_D&Jq3{3yeZT(t!rLb2JlD=W_uPBWeWuVtDQaLYn_r>>EUFsFJ>rvqao z%hf`p-Ivd^V|3`*G{)~)NxF~eaud`~u4Y?X_NLylcmEeRR_npe*eMzPWt@3h+wz{? zmiIg4x7|m{NHt0)FEJnNJw_vTU$Si9+4J^TIe*T)m7ObQ?JU*a*sA>ZHx9wMswfRl-+l|9;ZI z`kJ{o@Jl=A;n{+HyTv}XKEJNS#q3;jS_ebda6ZHKV`u+la@%$0bIe%YU+@C$57*MPfhx$zGGoUyM zeg9yODDVvVZ|M6EK0zA^J|D%a(R47XhkqlxSavx(t&3&;5|8#97A#t@*DO418Q}VB z`q)?1VmvXyY-HR{yUNrpTCt#O0d8wBd>@o4F?;Fag$vnsV&vkvbGte*?9aqmws;<< zM9!(2PfI}kB1Gn|=~Sk6@j}Y5WjVjaL;I||uy`2s z{j+<5{)3JCtXoq&T>l69{$>8Jd%~c5ztuN&sW`cKZ1HB8_+31%cvJB80UvHUPbePW zy$XDNyNB;Y6|AFGzq4!CIjI+)nCd%k+5AB0MFU~m;)#SXp?Ev+ap2>v2<>yRo=#mu zadPnvWJXhp>x#E8o?2XA+)&(D+*I5QJ`sEp`1*lw1Mn4t&kw#5@RfqEY;AE%%8aHJ zPcNQ;6UzqGD@}C_o9obc&9nB>>ng_msVMlwA9qn1Xkp6(LKlsY^ zzq=;{ilT!ij<%apSMdtnl$JA7QpgZik|~9{hda$@VUlM#8_y&M)AovD>Z}8gUlS~(M zI&(p1fp19K1^G7AUC{9VOs8$Roh#7=;UDm!bNWmFyL*B$gx43} zq?^l)%v?62QNM-EW#de95o!#rJB#soA9{X+>)K&r}LF6~Bh2;zt)=mogRq zU^Er~kmBL=2YlNzw?cn+PmuREMsX8A@(f@|!0kO;;#c=3;0^W*9N|J@J$2Xbnwjp z-%RlBxYj?_Scd$~d)Wgo0cKwSo%ye9m_a# z5%TZh-%Ga@jBn6ZcFn^{bop7BGr^Bx4#vB?<)O0Le;Ap`{{92}2l~7H;6KQJu>TN0 zo)hm5zS-cL1HMl1%>^F@U-QAY0DOC_^&f8fm1F$JqL~~IzCA5|WfA!HCclE&;s5QJ z3XF99XOo?r1HOfZot#g8G@F~358qhF~vCi`XnD|B1IlYO+6#pEBZBEPaE z)2|GfA#ZNz-Qd4j_bWFsgXzkmXQbRNOMHf% zlt^SJCB@)7-eM;w>UMI{z+i#4)J2{`($t^VE7m=OZnrSCR7Z`(nSqTeoCX`@!gLZOz7A-^Nx{^D{POdMx zq2$Jrn@VmjxuxXRlG{pd2j89Gy9<1HMspAN?gig{;JY7u4}fpo+LAj>JGqb9$vW^o zXt9%rbvt?NKRYShPM#qbhWmHa|x@^#5KCEu2OSMq(y4<$dA{8aKY_?`qG z9>Zav`V9E6-p_&WdGNgez8BY){A!xXUt}hw=fi3`x1O#Us1YQ>E@;5OSdT9vUID` ztxLBl-L@3t8ayie1$=)4R|=d8+;HHw0B$?rYJqFDrDT;>v8z(wTlf{^La$1l_w#gh zpSr;xk>(b%+{>0u(F=PA`RKD3W`nlp2c`rshMw zhW0`MZ53x(K$~XolIeO`A0hvDugc2omYsFvPw?~dy+R%{x?_AM`Yav&Gh~;}j*dw| zO|94mdC*W<2X(HF|3ywy$sAOcdf+~?d+MlP^&tJgHnQ2rbctTdH#z$zv+lN1nEi}P z^}U{bP})_x55A}>T~@lh6i-5Mulzmuez>^kgwj=|`_kg|Blv!zRe|20bl~?`@Ixat z)pht8vD61-kjB0P8NHFdFhgKkU27eF01ZDR+op?TV&ErUDlrM&z_2FPkKTL>eC07_ zEGE`dnnWoS?Q>!2LE!tjd$In5Lm9bPYE>*fqVyPQ$C0H+mE!LFSMdD?zTc@G$CVyW z?f3(HfBt{h4tzagwBs~t2ksO9GTL#LtsUo5Zi~mEK%>OX;n^iNHy~Z2(*`a3w~k+`&3UufW|%0a$tu zaQ)~pQlP0-r?}H|{IFA4tc-ygVGO6 zKPvqgxN_hsfC~Z_1}|D)2iLFuSL$sEjys%KDc1$~fR+z{P<}TwErUiDfvNN#F(ow{c!}n$s)f z^en8BWu<7RWo2bDa2jv}^08B0FNob=rj&)s!ex=NC~$*-8w}hK;D!OWVXFJf;_2=$ z)37(n&;Ya)C1u%Q>_IGfC@XoWrRZntUe;ssh=j6&1ALQ%)38#A+U)kWemhD zUD0UXXrqtjmhC~tI16xHxdwQ4{{Bw%Ub@K-n_jwl(@_ zAJ#`+oo%#Zzp?|}#=5%<$_@e!dtwrBRmNB!iax3AFyJZ+@JZ&t9$mE0MPa%RV$g6jBqghL)ctzQjWmlD5U3Lv{XpIfPH3HWR+zv(quD3McCThS%SiE69x6u!7 z2d*ibZQ^2Nt#)b-)9Qnbd5|@x#m!=kA$+v#Nw+?Fs_f~qXMk%1t{u2(Mjt(&FZfw(x zmK%!~F~|R>vfuj*T~qdRQNOZZ%YFlHmu>{_0B+WrvOmiHEc>erH;}V|e*nY)NPF4# zjk1r$xZJMz{gj@@|Bii~`QFyD4Uq9^IBvzb-Fmx;Nx$Z`qL=9CyXV||*}`(qdg~#& zEXzUcRyiQ|m&@e};N}3=3EW)Z=B<$xIfU#n5#Z(nhpuf8;O{3#roT}ehcpQE##vAM z#RuRk7A#)gW&0s}f+))-ke(8?W$;r(-7Tu6u1d^b*;$3UEOU-q8gggf4x;#=ICFAf^@0M+-TebymxtXjXPn0M3!GxVkd6HZuSIaeWEpRJ<+XuLnz^wvq zU*Pt;RGuQ&A)z@QdKNtn+-l(OB?fc6pr!vqLmOn0h@?I*iEY7m>C0AWDS80*Ns5SJ z9Cji0yTP7~O))eOL%BghFpk-aQ3j)yu}P&q(BooNI*PSt4HSCeYyr{xYg(UuuMHGU zlBdfv%Q(h?VB`=Z}%S+_F z<)w0$yi8s$uaNhVSIVp8edYb+)$;!G0rG)zw+!+@^1<>U@}cr!^5OCk@{#gU^3n1! z^0D%9^6~Ns@`>_E^2zck@~QG^^6By!@|p5k^4an^^11SP^7--w@`dt6^2PER`4ah3 z`7-%(d98efe5HJqe6@Uye64()e7$^we4~7me6xIue5-t$e7k&ye5ZVue7Ag$e6M_; ze82pFyiR^len@^;enfs$eoTH`enNgyeoB5?enx&)eolT~enEaweo1~=enoy&eocN| zenWm!eoKB^en);+eoua1{y_dv{z(2<{zU#%{!IQ{{zCpz{!0E@{zm>*{!ad0{z3jx z{z?8>{zd*({!RW}{zLv#{!9K_{wIKsy90d#z5o~C142LyNP&KV4Fbghf1o5#8Ym0M zfk2>tpgd3!2nLiuC=d=r0?~jPhy~(-L?9W^0s{gA1A_vC149Bs1H%Fv1~v+892g$h zBrqZ{GB7GIIxr?MHZU%*X<)O!=7I5nEdpBxwhC+=*e0-TU_xNKz{EghU{ateP#vfV z)CML8rUdE&+Xtow>H`gd#z0e`Ij}>ZCD0mZ3$zEO1*QjP1ZD>JoGusX1R;DEq^f$jhV4hkF`I3#dr;IP2qfg=J(2963G9XKX%Y~Z-S@qrTpCk9Rm zoE$hMaBASR!0CZAfZHFq1AsdaxNhJ8I1Kd;2JR5x4h0Sau)~2n0=OfAI|{g?fjb5` zjM|O^?s(u%0PaNKP6F;^;7$SVRNzhn?sVV~^Gx8*0`6?!&H?UR;4nTrAGiyEyAU{x zi7+Z#1KcIRT?*V~z+Dd9THw%s;uiTT;I0M^1FUO-yAHVPfx7{?8-cqCxSN5y1vuQ& z-v-?6z}*4doxt4%+}*(41Khp9-3Q$Lz&!xmI^Zx?dI-3OfqMkFM}d0`ICL;i0QV$t zPXYHda2O6f3*2+SJrCRqz`Y3EOTfJh+$+Gn3fybJy$&3{%zhKNw}5*axOaei7r6I; zdmp$Dfcp@*kAV9axKDul6u8fT`y9A0fcp}-uYmg+xNm^_7P#+#`yRL-fcp`+pMd)r zxL<(#6}aDk`yIGHfcq1;zkvH2xPO4}1AGzieS!A@&jHT^F90tBF9F{V_zi$B2Hp>R z3Gk)BmjN#W9{|2T@a4c)03QTi0X_tL82AYAQQ%eJW5CCOPXM0;UITsr@B@J#1pHv& zhX6km_+h|r2>eFCZw&l!;5Pw&1n?t)9|inq;Ku+z7Wi?%ZwmZoz;6!xc;L4HeoNrD z0)A`Yw*h`z;3ojT9qw1LfxiOyD}lcX_^W}x2KZ}%zYh58fxiLx8-c$G_?v;h1^8QmzYX}?fxiRz zJAuCo_`89>hc+3-zNk+PoYQ>*K6WZ%OdrcII$OS!z6xAfji;)35L#K^fh79ICx8Rz zlW;IYxTR`}DRL2sgq$J>LSN-J3cZAcG^Y@Ku$g@jd0Gv9PI`(VeK|=Fa!R+hH#ax6 z(ATV+>nq#nQ?6zmt|SH3sW7dw9*JrQ*c7~m1cwz>;^#w_QL9^9YuY-RE32l`=ZfoU zYw&m(i5fbZTWV_SW*F7Eo|HB*m1^+2uLx_Zw&Eu>QKPB49S@o(;U~`PjgPtqZb~&I zRa{MDB_2rA*PyFwu)J#gzH4h!drMV~S-)FJVT@UnizNGgXB`d`e(1b-fZ><eiVJ)?vKQLkzzGYZY5ZVnbZe zrm#=HV-@I|->n_hb!G(~CY8-nD&{xBE9<9M&TQ?_d%SgeU2R(jHoCF8vZcBMzmeNg z*;1G8yT=G(q!VINdtJRDjNcW-i-T&sL};m-)K2DZwEs!cO}Oh$!%`|6&97_*o*`M) zDLc8Us$*JB3tc7{pwE-whE73b+iIVTqsP8QOm(12HB_2YDzdoX` zzFIy%ANY!N$2x1$T2+akoy9q8=`O4W+GMI~=J0$=`kGUpIkZ%_k+(4h=LeF`7)(=o zI)1RU6`h>fzdw`wmY(RQd`Iily5?pY-s-8?TR5)lS4OeF5lpD4x^v0G#jA)F2mJ-k ztmfK!i%a^GgkmAD8|vb`x@OyZhN-14ng`hvT~ z)ATPT>7icI%}uRsXp6WawBn>l^-TW&=?r%0OslDHYHq+Ud7Dd7o4L;QuOJP3!>e2B z&_7MBYjgV&Eej3$he#`GE5}%6tRvMw>Mds*r#Q(aT=8g>@GH-iW*aqt zi2j2}B4U#;YS&!ZW&{uYhmx563%thSjC5vojV#R3uab@a-H231*pSVY8Q0eq{Khg) z0{rY@T@_ZkvZ1ct__%QYO)@J*lg3z`jS@zYSlm`ZRa5iKj^-(qtu^S)an=~3V@cFL z*zETPB-SL=9z$a@(g@qYb&b}xnPx1~e+!bbn`uf)Usq=~Olqn(je2X69%jR=Yo5~7 zSkr_)GV@Euy8TQbC41Lon8&cLG7*PZaI zX{g8;R4-&)2wb1F4y>hb_Z?;sU$O0+FM%4K{rq+;nF zG#b`=tb;k&Cy`7dUCXI8HO=UZ>!wjGL&0E6qbYkT$&OFU;&|-P-h^@~6UJ4gomOu> z{xidSeU&yUbq0Z0?6IZBv;i|5v)lgJq%kmEtVKiLFwL~fpO;&n7FV-b7m~cigt1xZ zKuH7>vS_P~yJ?H~8WOkkSZhslWefF|Zo({=%V_LnBx@O2V+3p?dj$za((P--aZH($ zCF<;dwWFHtjb_KWO`huIqP_IO1^Y5K z%GIkW7_6_`ks@kb^05G%EGk=%whxh7l}%+5;}Wu20bl9p!Gs+mz!)s9gtw&r&9h}NTs{_kcf%vMY~ zur?jV2U!Z!MWeqGZCzXK? z6@6gc*35E+}fbjI*o*xMHcvxq@)$KE||B7t-*A*+0j}z8BYvxcDB{mu)xnKVoa(snbP`f zZZnqK@=Zw+`^iPJkp;B0dvGmdJZVPUG_7X@XjZuH)vJsPz>2r>TXTGafo9llY`WFU6v0b~lXDDxS*Q;x!;>^v1 z=|Rl$T1am|MtOSIwb6OAt=HN~e8UX!RCq{jGOLHWMx$o97sB8%K&h*pNr9ZPM=IZm z#0M9psHJt&PHpjVV3-Bk!2lo-f+jKtnBxgxV@*As#~X{2(ZW**X;_X9s;{5c&{5ykWGJ0ZN~3cqQSmJ`6e6UeP(%AH z(jJ$GHjV|J@-*N!dJ-N3m?;+J=MunXc>pvuhn}8P(#Dp9Wx`(iV7^|se zUs8TCVQrEFi+ZCLkJ9k`!n}AXzck;5v`xXax4N~mmO2xgleUDl1d(h0vx%EJ0d=>| zs|aRP9&KoEY-z&l*!rfXX44w4CFNX`U++vZ2e%G2Y~u!ka?aP~_*tC2H2Ne7ez$6= zR=aT4JluDrLL%FmezRL|WL0mjZ*QePHkjK8#%ZDMFvhu8l?~udmuA%CO0*pLmoWlD zTd2awucNLN?@=hq#Q>0gVD!R0q(0I<8g}*6ysm6*pof}x$6Rgb-cP!Yk+kbpb1S_nsnm0dHq-ZLQXK;=;18J34n1^>h!ugwSDSn#nHzCjB$9Gz&6d+F=-5f!@$aZHdOu^ zA!Hp%SG6~D7M$u#mIQ*Qo3-tY_JHIaLU7Dr*G_G&Y{d?AE)MULx??@EtG7_S{{ZqnmI8&o=3?i$B4>#hwsu?r9XVDh~<1qzY zU|3d`xnupBlq=oaVpmR$L{)QhYEi)TT@MhOT1?;k9l?1_F$0eLkp&EoHfnI;v;>(y z5{So`dVsXxF|c9HzmWQL&nD@2zv$6Z5jkBPVjR|}pNNy2)YF*QX}r1ZOP!aS4gH-8 znVfGS`bi!oFSW9>abs0XxpSlDe-WsMhrotAYM$!D)G47E;HJPT`ViRW`PR?|X0)=x zM;Ke=i(#~~vc0W|JgHF=flwxTqUawH#CPE%s`SMwRTsPiL_={}M@2tEb1eUsSz|-f zhnRVFhGswZsPGfi*7;RThq6`;BV?n6Wd!61kh9mx3N*c@((J4LgygV&e3-Rl>EhYA zp=3Mylqx1gQHpDeb?Q_EN!>C3+|^S%E7mOyt&>}88jUr*B1|9-zvKX+IgB11<5S9n zqMS`LbH_9um0%j}y;}eb&PmMmZN*rHW$)@4sYZt<2z#0xyB$BBfFF#-gP%#A^Jn2x zwxyZ-Z%qEBiX!Nwnkkjj>agbNtvD{WHIvPaeZ>GOW5@MeMq_(@y*+cYVlb8CFzD&C zmeR?j*1VX$MN9eL)Z^qXus5b)jtA|D>)8)*K{3007(qF#Ckqs24r1PHooU7!le)u< z-PPOJ;atjnks)@}w6vtxfr=4?P8rvan#W+HB9OLAHS~&^tQ_%V; zKtjmsj0mM-a{{i*x4OEUVO>$(RK*ey^!+4lO)YsX6J498JJc(pyiGn(guIfXC_H^|L5?PzQ27&jKL?Au&Wr}nhv6sx-6H4qs*$0}wMUUk8>HLi6q*$AE56ujs+*RZ*SxI@8+dJPR+ zykN)NA4{K@@Cyh&Z+GnI00SQ5p0*}BS}(TjnXt+@k?! zFHk6AOz+(EdtjsH`%w{1Jt(5J1`q6;>gjm62D5N#IvQ%)rZiz7X<11RAn?2wWzz~$ z&IQwVTg<@+g35bhS-K(>*k_vPA%y7I%;jZH6nYrBHx-8yO5W4cS}#2LL|59>jvH&k zt7baXqX@nyHs6f*OAVFmsh}~`#}d}A`3^OWh91_U6{S+CFpg4=$(Sjl5%Tb0)#&ZN=ty zLse!M(`shm))L)Di<#D6aZ~mRIU%ZXgNlJ1g`v~xTH4w%46Vj(t5Km_3C(e+m!(2@ z;)UTRCFi)DuU6baVBQA7s%DOztw!cqtx>PL^Qe~zh0p3RamZ|+VW;Lix{tuzPY!4| z>g=)>yb;1gd%V@dCmxmcGh6FSq;-Vky-GQeTGOja111?5jeD3-yyvyOpY+hNu93aR z>}aa3#jN6{T0QmK0DO!9z1@zpT9s{0biHpbbgeZzbX1wSP8ClQn&X5mi%sD1|L7U% z{7AE}o*@|Tpws0jR6kf?se<&z0&Cb>iHB_I)QpPf3DbKs>xJ1--L5~oHRB?@c{T|H zDqbQ~?@f&ts$NB7iA;4WMmCr(+LpePt9Z3%b!O98mdqf*06-y>A-{b=@n#^cYHT6~4vf$wF^E1ilD3DSGv z@PagYps}e2FW#EXnfXc2dew5mW*P-Mz|#XIqy3)~x_7)`tE}0psfZa94E4k(o8^8* zh~67!cSJg7rYH`hA_LW^;kSh6?MQ5RmN1JonjYJB;1AOqrXL8+d&6Ww(`GHgjK~(e zVsWBk+Ma&K!JY=UPQk~qmRs|RpQ(rz&xkXxB1}JsCkUAAMxA0tp1-XJe7uRE7ctdz zUw{t0!+N9gC*kMidR)7R5~1)IrLGzmtSZW=!By3A^Yag(k7;VHOy!HK-yp17y_#Op>LX8Q-?%ohg%>jrQ-&Fo2&pL#Bv%xchDyXKDOkoDV;*V+iwS(& zUV$6+EG4MwOemHWiJef_)wP^1O!R6Rt;ArevYO>0(!Vfv4r3V&1_*Id!H5kt4NWbW ze~U#-X0FJnVFlrBQ7|4F79C$2C?P`Gu3!|J0hP6MAa99>f>Do7(>sgoh2^he=5c1v zG1t@BT2;%gc#P`B32}$a>g9u&dS#c|E7FWI-`yGT8o{@$7kK@`1J`#-u{Q7r5q@pY z@L7l8qD#w#C2t`(lrXpK8Rq0FwVJez&UmDzk@T#&jJtrPIBg{WB0k>v{!^iJEvmg~3+(IZ3dYU}y9S z7W2ia@-_6p1(WgUQoRP>G|g;p!VMifEO>aImx_?v@loI(>8?a-XykEzu5#f! z1D`Wma7^$7@!imk{F9Ge96Yh;#vsy4KHiNiluuC2tlYwOMr)JLFI)BX zp*Vx8h}@J5`tyN~HU_R`>*;3XzQ zGyfEbWnf`w)={rwY{r$rtAp1BuMJ)oygqnC@W$Xx!JC7(1aA%A7Q8)pNAS+zUBSD9 z_XO_^-WR+-_&{)7@WJ3i!H0v71Ro7P7JNMTMDWSrQ^BW$&jg@WbFo!H~f+R4G$rC7|?I%9RQws3=NE2`dpLs;Ej#i7N>usc6aoWuP)h8LSLZhAP99 z4V8_Qjg{fbCdvq9q%ukwt&CB|D&v$*mCcmRmGR0J%9hGj%GSy@%C^b`Wjke}QmIT* zs+4M_MyXXMD^rv@WqW0+Qm-^9jY^Z!tn8q)D6LAH(ymNXrYkd)naYmJPRh>8F3PS- zhq9Y8OW9qSt;|t6mAT41WxldN*+bb=S*Yx#EK(LLOO(BprAn8wOj)k1Q1($)Dyx)z zmHm{}%Kpj$%7IF^0?I+k!O9`Zp~_*(;mQ%pk;+lZ(aJH(vC47E@yZFxiONaJ$;v6p zsmf`}>B#g~~f$cqjHmSvvP}at8$xiyK;wer*fBaw{nkiuX3Mqzw&^xPI*vyNO@R!M0r$s zOnF>+LU~eoN_kp&MtN3wPI+E=L3vSmNqJd$MR`?uO?h2;LwQqqOL<#)M|oFyPkCSY zK>1MlNcmX#MEO+tO!-{-Litkp3izjie+KwxfqxG8=Yf9#_!ohH3HX6eI{{;9?f&UEn&w>8}_%DG+{I7xk z2KaA*{|@-?f&T&cAA$b~_@9CQ1^8cq{|)%xf&T;eKY{-X_`iYw2ZTN#6oJqe1Rn?- z2s{V^2qFj)2>n3V0EA)?{2-KoPzpjB2r>u(5c-2q4nhS8K@b!WLLh`eh=33UK?NZO zLL7ty2uTn$5C(uS5QIS>3_2Ev9QYy`r_APfg#6A(s#FcO4OAdCiK3wgzDv5Vi$j0tnlIFcE}G5GH|81wu6lH6YZ2Fd2j? zAk=}dJqS}ls0X0|ghmjWKxhVG2M}67Xa%7Sgmw_7fiN9}86eCAVMh>l0%2zmb^&2m z5IR8E4TM=B><+?g5axi;3Bp_u=7BIDgash%0m7ajECgXM5Eg;37=$Gt>R)DY%2rEHY1;V}{><7YX5cUV*01yrYp&JAM;UEwW2H_A84h7*b5Do|72oR10 z;V2M}2H_YGjs@X35RM1o1Q1RH;Uo}F2H_MCP6gpK5Kaf-3=qx);Vcl&2H_kK&IRE- z5Y7kT0uU|);UW+&24M{dmw<372$z9yIS6Y(xB`SLLAVNpt3kL1glj>#4utDLxB-M4 zLAVKon?bk*gj+$l4TRf4xC4YcLAVQqyFs`IgnL1_4}|+ccmRZTAUp`dLm)g1!XqF& z3c_O`JPyJWAUp}eQy@GI!ZRQ|3&L|CJP*PPAiM~|OCY=q!Yd%W3c_n3ybi(}AiN2} zTOhm*!aE?m3&MLKybr<$AbbeIM<9F*!Y3en3c_a~d=A1FAbbhJS0H>1!Z#p%3&M9G zd=J78Ap8izPaymZ!Y?5F3c_z7{0_n&Ap8l!Um*Mq!apGP0kH_gz99NQ6hIU~ zltAnU;sziVgXjmb1jJG^Mo`#efINwe6_)g$mB?6OiTycWuIpd&*nvB9Aa7J`4Jh1SY~)0M8+YO_gyHF zafqdR_khSa#In2dBr*=MbnOi8+tee5Od{hDOT;dm$T-CEtP3PE4zVoijKWfBWO#YQ z$iLYeZyN_#h^0)gFCya*%aqQrr@V-aLo7kM=S0RKmJppUk#UHnI%f=~Cy{Z8B{BD! z$T-Aumvayqhgd#xK19YLmTK%JX(h-FvBcp#h>Sxl5!lY>n`TkQ6Ipg0N*P`Bl-sy@ z2(et>yoroMEP2J#Vri&3iHt)mmDJ9ri}&&D zD+B50P&Ojt5K9p45s`6-C4|~5Sxl@6v9jI&SI%0X71T5X+n#W+NERNn{*iX^;i55{FoRqkS^uVkHi-|RB@VHiy8>B>LoBzhC#=LFmP%(~fyJi>*;$E0EMLyja8rZm zSmm%1Rt!Nn_bqi9;;$D<4+k5KHE=Sg@XzVW*D`v79W61)JR^kxL zV#+RWixOC#lEs9vSy@<#LoDaW(qmazi9;-Z$TG6V2w3xMLM#a=Co6G?W%F37nVpq5 z%(8bZsFYnv*~E6U3bPy?OKY(47R$1cr-oS;P7hd#!z{z5hpfb5mQ!P+Ep_8MwT7-? zmNaAIxy_rEILs1cY)rEHt851=ahRpR*ce8ubF&hMS+0wXe>Mv%ahT22&&yjY3DECC@;R^l*AE6Bx49A;?&g|HHb**(8)6mqf>huQ7D&1cZw1341( zQ=An0v4fR3%r53_Q_hQ(ILxluorJSFSc${C)08fVl{nl~8VROmwwMfD zncrdvcau`Sti<7iQY!c`>D{=Td(l4BqIDDbIUM^PR@EXz^kU=x7ukjhI z#No?Gyiiu+@D=Wbc(4+OuO{(ASc${ekw$*3#NiuBwjfsG@GY6}UaZ97+etQGR^sqo zIizi@#Nm50>ye7@Xcu8)B@RD8vU#%-haVzw2jj*1U?mPeO2Cenem!C(4nL7UQg&A2 z@Y96kcuwb0r_{ZZ8!K`6IfCgqD{=Tm(sw-0%%}#vIx?ewleEpjN*sQLpd61zvqO2a z5{F+WFb6A?E0{rgX=5c0zm;#Za#)j!9!gA1}W?)f!oUFv*U-NB;KE8ADI(=ulV9&l_DIdj6`ktPR9{9of^yDRcRpZ! zUAM6TM?|;Y$g1wfN*vjMV4N1}4r82q+3Qi_(hP$XF*hr5L?-o~u@XnhN!Kxwj-oyJ zR3i#0XXUbWVa66SlHdf-uwglrb1zlilti+Ltr0jTe?p_BY zp3BBc9H}BWk11xM^;cd4uein z)D*}{99czB4(rJR;9e%w>v9w91M;;`so=jHb08bC@jgbD4-t?kD^qRp+ z9C@5zy-Btl)?{gM-mJutr>Ka3iIq6=EP>~}D4SN`!b%)@fuQo9SeC9x1@@UH`Z6Ip zHgkEIla-Y?@*1J!Jw2`UO7lmWBxM;KH<339z9%-H$x0k~hp_%Pti+M`sVv84!Mk&5 zz|c4@+slw?G`P=nw6C}@&&=>ZN=t<@Ma~Bd`*as!-VV| z&B8%XLB0n zVkM4_BUJDGX!d?~WhIVoPLSRUhZm&L0}fW==$1X}Rm%yRX%v~P#L;aC-89-eXqcXd9{bf|WQrodDJcD{*v3 zLULiu%iuTGtls_^+`NN0$=(zsE`(T~7Gxmz6lWk}!MCN*vvfV6w5Y zW*I9aH+Eqqjvhde*$6AMK;~d2jsjt?e^%n?A-(7ZcUI!);RNY2(al+4SuZn~WZ7D2 zVKH!E@UG(yd0|2ap= z$x0kOv)2`MVI_{9L#Vx@uk~Ohj-F4@>z$Q2dJ)0?+pNUVOQ@88k(D@lITi44u@XnG zB=p`5tCc#~!b%*yhM=>}@4|?KapRI^C5~QC;MtsfVc=<2;^>XYN*uijMA>8RhzU!WisUn-0B1_9YTK)o?b3 z;cUNSJi*Z?k$pId6v7b;L2~rj=yTEMi>?4M2BHdL6d95+332X%g`HcC8a1lDt8;1B zs1+V8&!b;Nzl?qr{Tjr9APxd?Fo;7y917yFON$gwk5 zH_cFF58cR|p(;BFFOcC9Dach`XQ);MRa7OlpSpostoqdwwNx!rWi_DoSIgB3HK;0T zNDZqIHL9v=OpU7vHK}Uq0Ck``NFA&WQHQF-)D6{*)Q#2Q>L%(4b)-5<9j%U0$ExGh zP1ViR&DHVh7V4JjR_fO3HtM$O1a&)gqFSj=QmfQzwMMN~C#zG`I(2(>s#>o$sEulq z+N|!Nwy3RYo7%2UQ>Uvl)S2pz>Q3s;>MrW8YKOX;I!oPMovqGMJJq@BJaxXhK;1*# zQ(dU;r7ltzt4q|q)un2ex=dZJu2A<;SE{SjebxQc)$0E00qTKjw+iY(>cQ$E>Y?gk z>f!1U>XGVE>e1>k>apr^>hbCc>WS(}>dERU>Z$5!>gnnk>Y3_U>e=c!>bdH9>iOyg z>V@h>>c#3B^%C_`^)mHxb**}ZdZl`mdbN6udaZh$dcAssdZT)idb4_qdaHVydb@gu zdZ&7qdbfIydart)dcXRBx=wvieMo&+eMEg!eN25^eL{UweM)^=eMWs&eNKH|eL;Ou zeMx;;eMNm$eNBB`eM5ayeM@~?eMfy)eNTN~{XqRt{Yd>-{Y3p#{Y?E_{X+dx{Yw2> z{YL#({Z9Q}{XzXv{Ym{<{YCv%{Z0K{{X_jz{Y(8@{U_EZRutxFv{N zfw(n@+km(&h!a5E4#bHdR)RPQ#3~T0L9780F(-pK1;jcKw+C@5i1i>gfY=CP6Nt?q z?f_y7h^-*Df!Ge>G!UnQI0M9)Anpj_P9W|K;w~WW3StL{yMZ_h#N9!h4dNUSJ3*Wa z;ye)NgSY_1JwV(O#DyU41>zzQ7lVlYb8irrg4hM(G7y)8xB|p|KwJspDiHStaX%1O zgSbD42Y`4Wh}|FphzEgqFo=hMcqoX6fp|EGM}T-Fh)02VG>FH5cr1v=fp|QKCxCb& zh$n$~GKi;ucq)jefp|KIXMlJnh-ZO#Hi+kdcrJ+Nfp|WM7l3#nh!=r)F^FqGyadEc zLA(sa%RyWVA}%vmf_N2(SA%#Bh}VL69f;S1cms$xf_M{%H-mT!h_`}x8;G}qcn64g zf_N8*cY}Bji1&hcABgvZ_yCCOKztCyhd_K7#797U6vW3sd>q6lKztI!r$Brf#AiT! z7R2X3d>+IXKztFzmq2_O#8*Ik6~xy-d>zC$KztL#w?KRw#CJe^7sU5Kd>_OQK>QHI zk3jqw#7{u{6vWR!{2atDK>QNKuR#17#BV_S7R2vB{2s&~K>QKJpFsQ>#9u)C6~x~_ z{2jzUK>QQLzd-yO#D75Q15y!4eL?bp#DTB!ScqqzynS2FVXn2}q?Nm4PIK z6ac9|NaY|^fD{Bt0VxC$Ml%tRq9Cat#XyRKlmICSk_OTMkOqP@2&BOv4FPE=NW(zd z5TuPj+8CtaAZ-HD2#`jCGzz5AAdLZOEJ))(+7zVCK-wIn@gQvh(v~1?1=7|aZ3EJ_ zAWZ;iJCG)VR0+}~kg7nc2B`+5T977#GzFwOkhTYDDoFJpHGtFzQWHqcAngEB3rMXX zwSm+Q(ln5!gERxAnIP>5(oP`l4AL$j?Fv!{NV|bF3#8panhnw%kUBw{3(`E0=7Y2V zq&+~|(_D>W+f#6wCqs3tfrPU%RL7c0BnLxvtd)fFWvGr#Bk2Mds$(-rArFS?*v=$a zAVYPmgOmzfzl(iQpBmde)sTD{s$-p`&|`+`*nCp&0Yi0cPf~QDp2o+c7V7EPA`dY< zk+F*HO=1NxRL7Q)O0O8IWBU+92BUCZ4ArrHNjE=+>e&7yn+HR6teXT2WvGrFOj*ig_|r$Brc73{vCNgO*H&>ew+PpFtXpZ-VOE={x9Nq|veCNv}YL>exxHg_(Rg zo`s!Cdh3g!I(7!3W!O_*4Arr-Nw?<=)v@zPKVOFG*o7pWF_@kV)v+}s-)n~I*kuHh zgP}Th1qpfaPET%WYB#W4Dl2-VD{T+ezF` z{cAaSaWGWJ?jmVBDX&G^m7zLzFX`Axi?cIS#~vUJd&6@xRL347EqCT=+ekg?EoU32 zCrB?gu zhU(Z`B$gLLb?jXdwGTF>MR+q*$37qpy8-GNZrszck4d^f?&;WPq-5_@uR}&-9KIx# z0_dt^-;jcRX5^x)j(tx$`O{U$ej@oo=&EDCl7<(zw1u%a_6G^(LsuR9I~$~ht~y>s zg89)^$2pR^8@lW2i-)$wvt>Iq$S zTp>*hJ+MhW%@VmPCn2>El^X<-@d#;H8g6PBPRBC%@fZnPNOZH)RmYPK>}+(^ z@qr|qg|0e2gaj;n%r11*@eN6)FuLmaaMH<2R~;WoBH8Gw<6}r7AG+%JrX*>xU^lwz z_;?bsSg=Ve+}Ux4f0EI$lrm78A}+R~>I6aZ8V7p{tI!kgR27jS;X??#A0m$U-cQpImKg zYNVt4RmXR7pc=G2cDm~Lt|Vq@O%}T9_$-p`0bO-`4k`AKt~x%Clx=*r zZX~!?y6X5Iq+;VF&YP|}z8C4*D283>s^d#Y&PF|(2VHf%i?nRS#1;Z-BB*L?O@GuS zzJjD}M70)aoy{f{bi`MYXb;9^LrRc>L%rh2>zAh#!}wFnu)abk*?_Nx{|w`V&S6U3L5v zlCxPwx(CvgGKTtelC}{g=cKESpG7)0CTZhQWr{tzqqeD@T#jW!5kHrd@~5kgUyxCV z+f237RmU$TCEN5iHZ5Ls)$vP7B~QBQ_*xRqMOPiailhpmtBzkw8n#i$Nmm`efply> zgSIO<=&Iv4la|d3c+pkISxSVHi8u#cb^K1kFNm%>eh;bSPgfnkpX3XmtByZN3VG61 z#~&f#^+8u1f7}hpJbo*Ht~&k{A@zi=I{qwa7ED(ie}UBUp{tI+Op;C`$w5~ge~py# zrK^s=nW{`qy6X5lB-siGMlnUk(M{t=1grmK#BN^*JARmZ;|@jU6O<6o0-p>);p z??@{PU3L6N66iTyb^I67FPyGA{=2(gF1qUYU!<2eU3H=li5E&&o$$FA;z3uP5J^AMl5E~|)rka& zJE&0B2VHey00BFmfM#&I>TgFFS6v5%SuOb13S;gLD_d@2aQ;Zy>8caM2+8rz(xXnP zODH$G>cqwb({sA�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 - - - - BuildLocationStyle - UseTargetSettings - BuildSystemType - Latest - CustomBuildIntermediatesPath - Build/Intermediates.noindex - CustomBuildLocationType - RelativeToDerivedData - CustomBuildProductsPath - Build/Products - DerivedDataLocationStyle - Default - IssueFilterStyle - ShowAll - LiveSourceIssuesEnabled - - SharedBuildFolderName - Build - - diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.14.xcscheme b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.14.xcscheme deleted file mode 100644 index 79299d7a5..000000000 --- a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.14.xcscheme +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.15.xcscheme b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.15.xcscheme deleted file mode 100644 index e72a90366..000000000 --- a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcshareddata/xcschemes/stlink_shield_10.15.xcscheme +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist b/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index c9d1a75b6..000000000 --- a/stlinkv1_macos_driver/stlink_shield_xcode/stlink_shield.xcodeproj/xcuserdata/vm-user.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,37 +0,0 @@ - - - - - SchemeUserState - - stlink_shield_10.14.xcscheme_^#shared#^_ - - orderHint - 0 - - stlink_shield_10.15.xcscheme_^#shared#^_ - - orderHint - 1 - - - SuppressBuildableAutocreation - - 8F9084E724786F0B009109AD - - primary - - - 8F9084F324786F0F009109AD - - primary - - - 8F9084FF24786F39009109AD - - primary - - - - - From ff8114895a9fc32cae6a9374e58eac6256d68183 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 23 Oct 2022 20:40:43 +0200 Subject: [PATCH 1328/1435] Corrected sram_size for L496x/L4A6x devices (Closes #1268) --- config/chips/L496x_L4A6x.chip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/chips/L496x_L4A6x.chip b/config/chips/L496x_L4A6x.chip index df1f084ff..6657d5484 100644 --- a/config/chips/L496x_L4A6x.chip +++ b/config/chips/L496x_L4A6x.chip @@ -6,7 +6,7 @@ chip_id 0x461 // STM32_CHIPID_L496x_L4A6x flash_type L4_L4P flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB -sram_size 0x40000 // 256 KB +sram_size 0x50000 // 320 KB bootrom_base 0x1fff0000 bootrom_size 0x7000 // 28 KB option_base 0x1fff7800 // STM32_L4_OPTION_BYTES_BASE From f93adb92f2e4ecf05a9361cb723c98693586929d Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 24 Oct 2022 01:49:03 +0200 Subject: [PATCH 1329/1435] Fixes for project compilation - Cleanup for CMakeLists.txt - [doc] Added list of cmake path variables - Fixed stlink-gui install path (Closes #1270) (Closes #1271) - Replaced path variable for chips directory --- CMakeLists.txt | 105 +++++++++++++++++++---------- cmake/packaging/cpack_config.cmake | 2 +- doc/man/CMakeLists.txt | 2 +- src/st-flash/flash.c | 2 +- src/st-info/info.c | 2 +- src/st-trace/trace.c | 2 +- src/st-util/gdb-server.c | 2 +- src/stlink-gui/CMakeLists.txt | 10 +-- src/stlink-gui/gui.c | 2 +- tests/CMakeLists.txt | 2 +- 10 files changed, 83 insertions(+), 48 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 67f76ec08..94721f213 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,22 +13,69 @@ set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS ON) +### +# +# Default cmake directories: +# +# | Target Type | GNUInstallDirs Variable | Built-In Default | +# | --- | --- | --- | +# | RUNTIME | ${CMAKE_INSTALL_BINDIR} | bin | +# | LIBRARY | ${CMAKE_INSTALL_LIBDIR} | lib | +# | ARCHIVE | ${CMAKE_INSTALL_LIBDIR} | lib | +# | PRIVATE_HEADER | ${CMAKE_INSTALL_INCLUDEDIR} | include | +# | PUBLIC_HEADER | ${CMAKE_INSTALL_INCLUDEDIR} | include | +# | FILE_SET (type HEADERS) | ${CMAKE_INSTALL_INCLUDEDIR} | include | +# +# | TYPE Argument | GNUInstallDirs Variable | Built-In Default | +# | --- | --- | --- | +# | BIN | ${CMAKE_INSTALL_BINDIR} | bin | +# | SBIN | ${CMAKE_INSTALL_SBINDIR} | sbin | +# | LIB | ${CMAKE_INSTALL_LIBDIR} | lib | +# | INCLUDE | ${CMAKE_INSTALL_INCLUDEDIR} | include | +# | SYSCONF | ${CMAKE_INSTALL_SYSCONFDIR} | etc | +# | SHAREDSTATE | ${CMAKE_INSTALL_SHARESTATEDIR} | com | +# | LOCALSTATE | ${CMAKE_INSTALL_LOCALSTATEDIR} | var | +# | RUNSTATE | ${CMAKE_INSTALL_RUNSTATEDIR} | /run | +# | DATA | ${CMAKE_INSTALL_DATADIR} | | +# | INFO | ${CMAKE_INSTALL_INFODIR} | /info | +# | LOCALE | ${CMAKE_INSTALL_LOCALEDIR} | /locale | +# | MAN | ${CMAKE_INSTALL_MANDIR} | /man | +# | DOC | ${CMAKE_INSTALL_DOCDIR} | /doc | +# +# ${CMAKE_BINARY_DIR} +# This is the full path to the top level of the current CMake build tree. +# For an in-source build, this would be the same as CMAKE_SOURCE_DIR. +# +# ${CMAKE_SOURCE_DIR} +# This is the full path to the top level of the current CMake source tree. +# For an in-source build, this would be the same as CMAKE_BINARY_DIR. +# +# ${CMAKE_CURRENT_BINARY_DIR} +# The path to the binary directory currently being processed. +# This is the full path to the build directory that is currently being processed by cmake. +# Each directory added by add_subdirectory() will create a binary directory in the build tree, +# and as it is being processed this variable will be set. +# For in-source builds this is the current source directory being processed. +# +# ${CMAKE_CURRENT_SOURCE_DIR} +# The path to the source directory currently being processed. +# This is the full path to the source directory that is currently being processed by cmake. +# +### + ### -# General project settings +# General Project Settings ### project(stlink C) set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics ST-LINK Tools") -include(GNUInstallDirs) # Define GNU standard installation directories +include(${CMAKE_MODULE_PATH}/get_version.cmake) # Determine project version -## MCU configuration files -set(CMAKE_CHIPS_SUBDIR stlink/chips) -set(CMAKE_CHIPS_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_CHIPS_SUBDIR}) -add_definitions( -DETC_STLINK_DIR="${CMAKE_CHIPS_DIR}" ) +include(GNUInstallDirs) # Define GNU standard installation directories -## Determine project version -include(${CMAKE_MODULE_PATH}/get_version.cmake) +# Define install directory /usr/share +set(CMAKE_INSTALL_SHAREDIR /usr/share/) ## Set C build flags if (NOT MSVC) @@ -178,8 +225,6 @@ endif () # Libraries ### -set(STLINK_LIBRARY_PATH ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Main library install directory") - # Set the environment variable LD_LIBRARY_PATH to point to /usr/local/lib (per default). execute_process(COMMAND bash -c "export LD_LIBRARY_PATH=${CMAKE_INSTALL_LIBDIR}") @@ -205,21 +250,15 @@ set_target_properties(${STLINK_LIB_SHARED} PROPERTIES ) # Link shared library -if (APPLE) # ... with Apple macOS libraries - find_library(ObjC objc) - find_library(CoreFoundation CoreFoundation) - find_library(IOKit IOKit) - find_library(Security Security) - target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB} ${ObjC} ${CoreFoundation} ${IOKit} ${Security}) -elseif (WIN32) # ... with Windows libraries +if (WIN32) # ... with Windows libraries target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB} wsock32 ws2_32) else () target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB}) endif () install(TARGETS ${STLINK_LIB_SHARED} - ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH} - LIBRARY DESTINATION ${STLINK_LIBRARY_PATH} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) @@ -248,19 +287,13 @@ set_target_properties(${STLINK_LIB_STATIC} PROPERTIES ) # Link static library -if (APPLE) # ... with Apple macOS libraries - find_library(ObjC objc) - find_library(CoreFoundation CoreFoundation) - find_library(IOKit IOKit) - find_library(Security Security) - target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB} ${ObjC} ${CoreFoundation} ${IOKit} ${Security}) -elseif (WIN32) # ... with Windows libraries +if (WIN32) # ... with Windows libraries target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB} wsock32 ws2_32) else () target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB}) endif () -install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${STLINK_LIBRARY_PATH}) +install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) ### @@ -284,7 +317,7 @@ add_executable(st-info ${ST-INFO_SOURCES}) add_executable(st-util ${ST-UTIL_SOURCES}) add_executable(st-trace ${ST-TRACE_SOURCES}) -if (WIN32 OR APPLE) +if (WIN32) target_link_libraries(st-flash ${STLINK_LIB_STATIC} ${SSP_LIB}) target_link_libraries(st-info ${STLINK_LIB_STATIC} ${SSP_LIB}) target_link_libraries(st-util ${STLINK_LIB_STATIC} ${SSP_LIB}) @@ -301,10 +334,6 @@ install(TARGETS st-info DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS st-util DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS st-trace DESTINATION ${CMAKE_INSTALL_BINDIR}) -# Install MCU configuration files -file(GLOB CHIP_FILES ${CMAKE_SOURCE_DIR}/config/chips/*.chip) -install(FILES ${CHIP_FILES} DESTINATION ${CMAKE_CHIPS_DIR}) - ### # Device configuration (Linux only) @@ -326,13 +355,19 @@ endif () # Additional build tasks ### -add_subdirectory(src/stlink-gui) # contains subordinate CMakeLists to build GUI -add_subdirectory(tests) # contains subordinate CMakeLists to build test executables -add_subdirectory(cmake/packaging) # contains subordinate CMakeLists to build packages +# MCU configuration files +set(CMAKE_CHIPS_DIR ${CMAKE_INSTALL_SHAREDIR}/${PROJECT_NAME}/chips) +add_definitions( -DSTLINK_CHIPS_DIR="${CMAKE_CHIPS_DIR}" ) +file(GLOB CHIP_FILES ${CMAKE_SOURCE_DIR}/config/chips/*.chip) +install(FILES ${CHIP_FILES} DESTINATION ${CMAKE_CHIPS_DIR}) +# Documentation / manpages option(STLINK_GENERATE_MANPAGES "Generate manpages with pandoc" OFF) add_subdirectory(doc/man) # contains subordinate CMakeLists to generate manpages +add_subdirectory(src/stlink-gui) # contains subordinate CMakeLists to build GUI +add_subdirectory(tests) # contains subordinate CMakeLists to build test executables +add_subdirectory(cmake/packaging) # contains subordinate CMakeLists to build packages ### # Uninstall target diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake index 8766fb2e0..55a859189 100644 --- a/cmake/packaging/cpack_config.cmake +++ b/cmake/packaging/cpack_config.cmake @@ -20,7 +20,7 @@ if (WIN32 AND (NOT EXISTS "/etc/debian_version")) # Wi set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-win32") set(CPACK_INSTALL_PREFIX "") -elseif (WIN32) # Windows cross-build on Debian/Ubuntu +elseif (WIN32) # Windows cross-build on Debian/Ubuntu set(CPACK_GENERATOR "ZIP") set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-${TOOLCHAIN_PREFIX}") set(CPACK_INSTALL_PREFIX "") diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 9b3c50764..1b7d6501f 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -30,7 +30,7 @@ foreach (manpage ${MANPAGES}) endif () if (f AND NOT WIN32) - install(FILES ${f} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/man/man1) + install(FILES ${f} DESTINATION ${CMAKE_INSTALL_DATADIR}/man/man1) unset(f) endif () endforeach () diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index a9952dd34..058501ad6 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -62,7 +62,7 @@ int main(int ac, char** av) { } printf("st-flash %s\n", STLINK_VERSION); - init_chipids (ETC_STLINK_DIR); + init_chipids (STLINK_CHIPS_DIR); sl = stlink_open_usb(o.log_level, o.connect, (char *)o.serial, o.freq); diff --git a/src/st-info/info.c b/src/st-info/info.c index d02653bc5..9963606e3 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -68,7 +68,7 @@ static int print_data(int ac, char **av) { return(0); } - init_chipids(ETC_STLINK_DIR); + init_chipids(STLINK_CHIPS_DIR); for (int i=2; i Date: Sun, 13 Nov 2022 17:51:07 -0800 Subject: [PATCH 1330/1435] Update CMakeLists.txt --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94721f213..4048928bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,8 +74,8 @@ include(${CMAKE_MODULE_PATH}/get_version.cmake) # Determine project version include(GNUInstallDirs) # Define GNU standard installation directories -# Define install directory /usr/share -set(CMAKE_INSTALL_SHAREDIR /usr/share/) +# Define install directory /usr/local/share [the new MacOS does not allow changes to /usr/share ] +set(CMAKE_INSTALL_SHAREDIR /usr/local/share/) ## Set C build flags if (NOT MSVC) From 0d96e362696c5b9be0f98ea3187bbfcca12dfd66 Mon Sep 17 00:00:00 2001 From: Wingman Shen Date: Sun, 13 Nov 2022 17:53:59 -0800 Subject: [PATCH 1331/1435] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b889de389..571db49fd 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ We recommend to install `stlink-tools` from the package repository of the used d - RedHat/CentOS 8: Users can install from [EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel8) - FreeBSD: Users can install from [freshports](https://www.freshports.org/devel/stlink) +- MacOS: Users can open a terminal window and then follow the same procedure as for installing on Linux ## Installation from source (advanced users) @@ -103,4 +104,4 @@ Please also refer to our [Contribution Guidelines](CONTRIBUTING.md). *I hope it's not to out of topic, but I've been so frustrated with AVR related things on OpenBSD, the fact that stlink built out of the box without needing to touch anything was so relieving. Literally made my whole weekend better! I take it's thanks to @Crest and also to the stlink-org team (@Nightwalker-87 and @xor-gate it seems) to have made a software that's not unfriendly to the "fringe" OSes. -Thank you <3"* - nbonfils, 11.12.2021 \ No newline at end of file +Thank you <3"* - nbonfils, 11.12.2021 From eb35054ea646ef80b1d57cd3a26bc00583f38d08 Mon Sep 17 00:00:00 2001 From: Angel Iglesias Date: Tue, 22 Nov 2022 10:28:49 +0100 Subject: [PATCH 1332/1435] config: udev: Add rule for the V3 MINIE programmer --- config/udev/rules.d/49-stlinkv3.rules | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config/udev/rules.d/49-stlinkv3.rules b/config/udev/rules.d/49-stlinkv3.rules index 5161947a9..98c33eddf 100644 --- a/config/udev/rules.d/49-stlinkv3.rules +++ b/config/udev/rules.d/49-stlinkv3.rules @@ -7,7 +7,12 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3752", \ SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3753", \ MODE:="0666", \ SYMLINK+="stlinkv3_%n" - + +# STLink V3SET MINIE +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3754", \ + MODE:="0666", \ + SYMLINK+="stlinkv3_%n" + # STLink V3SET SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374d", \ MODE:="0666", \ From 44ec93d80c191ad22cdecf974d3cc345db654de6 Mon Sep 17 00:00:00 2001 From: Wingman Date: Sat, 3 Dec 2022 05:11:59 -0800 Subject: [PATCH 1333/1435] add if-clause for macOS --- CMakeLists.txt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4048928bb..124f12f5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,8 +74,17 @@ include(${CMAKE_MODULE_PATH}/get_version.cmake) # Determine project version include(GNUInstallDirs) # Define GNU standard installation directories -# Define install directory /usr/local/share [the new MacOS does not allow changes to /usr/share ] -set(CMAKE_INSTALL_SHAREDIR /usr/local/share/) +# Define install directory /usr/local/share [not /usr/share on MacOS] +cmake_host_system_information(RESULT OS_NAME QUERY OS_NAME) +message(STATUS "Checking for OS_NAME: ${OS_NAME}") + +if (OS_NAME STREQUAL "macOS") + message(STATUS "set(CMAKE_INSTALL_SHAREDIR /usr/local/share)") + set(CMAKE_INSTALL_SHAREDIR /usr/local/share/) +else () + message(STATUS "set(CMAKE_INSTALL_SHAREDIR /usr/share)") + set(CMAKE_INSTALL_SHAREDIR /usr/share/) +endif () ## Set C build flags if (NOT MSVC) From 33430783b3b18ab88ff89d10d7a2a24dadae2472 Mon Sep 17 00:00:00 2001 From: Marcus Lindemann Date: Sun, 4 Dec 2022 18:11:51 +0100 Subject: [PATCH 1334/1435] [#1] fFix GUI compilation fail on OpenBSD i386 Explicitely convert from goffset to gsize with prior overflow check. Implicit conversion is forbidden by compiler settings. --- src/stlink-gui/gui.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index a58d59247..d7e74c547 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -301,7 +301,14 @@ static gpointer stlink_gui_populate_filemem_view(gpointer data) { if (gui->file_mem.memory) { g_free(gui->file_mem.memory); } - gui->file_mem.size = g_file_info_get_size(file_info); + goffset file_size = g_file_info_get_size(file_info); + + if (G_MAXSIZE < file_size) { + stlink_gui_set_info_error_message(gui, "File too large."); + goto out_input; + } + + gui->file_mem.size = (gsize) file_info; gui->file_mem.memory = g_malloc(gui->file_mem.size); for (off = 0; off < (gint)gui->file_mem.size; off += MEM_READ_SIZE) { From 014907144840b8a45f3dabd83b6b07b0c0cad72b Mon Sep 17 00:00:00 2001 From: Marcus Lindemann Date: Sun, 4 Dec 2022 18:11:51 +0100 Subject: [PATCH 1335/1435] Fix GUI compilation fail on OpenBSD i386 Explicitely convert from goffset to gsize with prior overflow check. Implicit conversion is forbidden by compiler settings. --- src/stlink-gui/gui.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index a58d59247..d7e74c547 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -301,7 +301,14 @@ static gpointer stlink_gui_populate_filemem_view(gpointer data) { if (gui->file_mem.memory) { g_free(gui->file_mem.memory); } - gui->file_mem.size = g_file_info_get_size(file_info); + goffset file_size = g_file_info_get_size(file_info); + + if (G_MAXSIZE < file_size) { + stlink_gui_set_info_error_message(gui, "File too large."); + goto out_input; + } + + gui->file_mem.size = (gsize) file_info; gui->file_mem.memory = g_malloc(gui->file_mem.size); for (off = 0; off < (gint)gui->file_mem.size; off += MEM_READ_SIZE) { From d063c1159f0574f143edb42b2a5f05a3f0b20044 Mon Sep 17 00:00:00 2001 From: Marcus Lindemann Date: Sun, 4 Dec 2022 18:11:51 +0100 Subject: [PATCH 1336/1435] Fix GUI compilation fail on OpenBSD i386 Explicitely convert from goffset to gsize with prior overflow check. Implicit conversion is forbidden by compiler settings. --- src/stlink-gui/gui.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index a58d59247..b45f5f126 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -301,7 +301,14 @@ static gpointer stlink_gui_populate_filemem_view(gpointer data) { if (gui->file_mem.memory) { g_free(gui->file_mem.memory); } - gui->file_mem.size = g_file_info_get_size(file_info); + goffset file_size = g_file_info_get_size(file_info); + + if ((0 > file_size) && (G_MAXSIZE <= file_size)) { + stlink_gui_set_info_error_message(gui, "File too large."); + goto out_input; + } + + gui->file_mem.size = (gsize) file_info; gui->file_mem.memory = g_malloc(gui->file_mem.size); for (off = 0; off < (gint)gui->file_mem.size; off += MEM_READ_SIZE) { From 53e9252cc0c5b348ee7d9cc954c2752168658e34 Mon Sep 17 00:00:00 2001 From: Marcus Lindemann Date: Sun, 4 Dec 2022 18:11:51 +0100 Subject: [PATCH 1337/1435] Resolve merge conflict for diverging branch. Explicitely convert from goffset to gsize with prior overflow check. Implicit conversion is forbidden by compiler settings. --- src/stlink-gui/gui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index d7e74c547..b45f5f126 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -303,7 +303,7 @@ static gpointer stlink_gui_populate_filemem_view(gpointer data) { goffset file_size = g_file_info_get_size(file_info); - if (G_MAXSIZE < file_size) { + if ((0 > file_size) && (G_MAXSIZE <= file_size)) { stlink_gui_set_info_error_message(gui, "File too large."); goto out_input; } From 32fc9f11ef044c27bf48b091e9463c3c9f466271 Mon Sep 17 00:00:00 2001 From: Marcus Lindemann Date: Tue, 6 Dec 2022 21:41:07 +0100 Subject: [PATCH 1338/1435] Fix resulting compilation error on Ubuntu --- src/stlink-gui/gui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index b45f5f126..2bf1f9d32 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -303,7 +303,7 @@ static gpointer stlink_gui_populate_filemem_view(gpointer data) { goffset file_size = g_file_info_get_size(file_info); - if ((0 > file_size) && (G_MAXSIZE <= file_size)) { + if ((0 > file_size) && ((goffset)G_MAXSIZE <= file_size)) { stlink_gui_set_info_error_message(gui, "File too large."); goto out_input; } From a4105f4ce89a110bd3b1fd168e194f8690f43ee6 Mon Sep 17 00:00:00 2001 From: Phil Date: Sun, 18 Dec 2022 16:27:40 +0100 Subject: [PATCH 1339/1435] Adding device ID for GD32F303VET6 --- doc/devices_boards.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/devices_boards.md b/doc/devices_boards.md index 1a5099b72..06f58fe21 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -89,8 +89,9 @@ Tested non-official ST boards [incl. STLINK programmers]: | Product-Code | Chip-ID | STLINK
      Programmer | Boards | | ------------ | ------- | ---------------------- | ---------------------------------- | -| GD32F303VGT6 | 0x430 | [v2] | STM32F303 clone from GigaDevice GD | | GD32F303CGT6 | 0x430 | [v2] | STM32F303 clone from GigaDevice GD | +| GD32F303VET6 | 0x414 | [v2] | STM32F303 clone from GigaDevice GD | +| GD32F303VGT6 | 0x430 | [v2] | STM32F303 clone from GigaDevice GD | ## STM32F4 / ARM Cortex M4F From 194e6e9c6b9f3f1c40bf5c6b724aff8087fb443e Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 28 Dec 2022 22:21:47 +0100 Subject: [PATCH 1340/1435] General project clean-up - Removed orphaned old dev-documentation - Rearranged src files belonging to stlink-lib - Revised & sorted option byte source code - Updated devices_boards.md --- CMakeLists.txt | 18 +- doc/dev/app-example/CMakeLists.txt | 22 - doc/dev/app-example/README.md | 2 - doc/dev/app-example/main.c | 28 - doc/dev/developer.txt | 411 --------- doc/dev/pkg-config/CMakeLists.txt | 15 - doc/dev/pkg-config/pkgconfig.pc.cmake | 11 - doc/devices_boards.md | 7 +- inc/stlink.h | 17 - src/st-flash/flash.c | 1 + src/st-util/gdb-server.c | 1 + src/{ => stlink-lib}/calculate.c | 0 src/{ => stlink-lib}/calculate.h | 0 src/{ => stlink-lib}/common.c | 0 src/{ => stlink-lib}/common.h | 0 src/{ => stlink-lib}/common_flash.c | 1 + src/{ => stlink-lib}/common_flash.h | 0 src/stlink-lib/flash_loader.h | 5 +- src/{ => stlink-lib}/flashloader.c | 1 + src/stlink-lib/flashloader.h | 13 + src/{ => stlink-lib}/map_file.c | 0 src/{ => stlink-lib}/map_file.h | 0 src/{ => stlink-lib}/option_bytes.c | 1210 ++++++++++++------------- src/stlink-lib/option_bytes.h | 21 + src/{ => stlink-lib}/read_write.c | 0 25 files changed, 644 insertions(+), 1140 deletions(-) delete mode 100644 doc/dev/app-example/CMakeLists.txt delete mode 100644 doc/dev/app-example/README.md delete mode 100644 doc/dev/app-example/main.c delete mode 100644 doc/dev/developer.txt delete mode 100644 doc/dev/pkg-config/CMakeLists.txt delete mode 100644 doc/dev/pkg-config/pkgconfig.pc.cmake rename src/{ => stlink-lib}/calculate.c (100%) rename src/{ => stlink-lib}/calculate.h (100%) rename src/{ => stlink-lib}/common.c (100%) rename src/{ => stlink-lib}/common.h (100%) rename src/{ => stlink-lib}/common_flash.c (99%) rename src/{ => stlink-lib}/common_flash.h (100%) rename src/{ => stlink-lib}/flashloader.c (99%) create mode 100644 src/stlink-lib/flashloader.h rename src/{ => stlink-lib}/map_file.c (100%) rename src/{ => stlink-lib}/map_file.h (100%) rename src/{ => stlink-lib}/option_bytes.c (73%) create mode 100644 src/stlink-lib/option_bytes.h rename src/{ => stlink-lib}/read_write.c (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 124f12f5a..3a22fdedc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -170,8 +170,8 @@ add_subdirectory(inc) set(STLINK_HEADERS inc/backend.h inc/stlink.h - src/common_flash.h - src/calculate.h + src/stlink-lib/common_flash.h + src/stlink-lib/calculate.h src/stlink-lib/commands.h src/stlink-lib/libusb_settings.h src/stlink-lib/reg.h @@ -185,13 +185,13 @@ set(STLINK_HEADERS ) set(STLINK_SOURCE - src/read_write.c - src/common.c - src/option_bytes.c - src/common_flash.c - src/map_file.c - src/flashloader.c - src/calculate.c + src/stlink-lib/read_write.c + src/stlink-lib/common.c + src/stlink-lib/option_bytes.c + src/stlink-lib/common_flash.c + src/stlink-lib/map_file.c + src/stlink-lib/flashloader.c + src/stlink-lib/calculate.c src/stlink-lib/chipid.c src/stlink-lib/flash_loader.c src/stlink-lib/logging.c diff --git a/doc/dev/app-example/CMakeLists.txt b/doc/dev/app-example/CMakeLists.txt deleted file mode 100644 index 69ba2090e..000000000 --- a/doc/dev/app-example/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -# Warning: This example assumes that you are building on a host with pkg-config available (e.g. linux). -# The logic required to build under windows/mingw was intentionally omitted to keep this CMakeLists as small as possible. - -cmake_minimum_required(VERSION 3.4.2) - -project(st-hello) -set(PROJECT_VERSION 0.1) - -set(SRCS main.c) - -include_directories(${STLINK_INCLUDE_DIRS}) - -find_package(PkgConfig) -pkg_check_modules(STLINK REQUIRED stlink) - -set(CMAKE_C_FLAGS " ${STLINK_CFLAGS_OTHER} -Wall -Werror") - -add_executable(${PROJECT_NAME} ${SRCS}) - -target_link_libraries(${PROJECT_NAME} ${STLINK_LIBRARIES}) - -install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/doc/dev/app-example/README.md b/doc/dev/app-example/README.md deleted file mode 100644 index f3a0bf9bb..000000000 --- a/doc/dev/app-example/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This is a simple standalone application example that uses libstlink. -It can be used as a boilerplate for app development. diff --git a/doc/dev/app-example/main.c b/doc/dev/app-example/main.c deleted file mode 100644 index b8e64b259..000000000 --- a/doc/dev/app-example/main.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include - -static stlink_t *stlink_open_first(void) { - stlink_t* sl = NULL; - sl = stlink_v1_open(0, 1); - if (sl == NULL) - sl = stlink_open_usb(0, 1, NULL); - - return sl; -} - - -int main() { - stlink_t* sl = NULL; - sl = stlink_open_first(); - - if (sl == NULL) { - fprintf(stderr, "Failed to open stlink device ;(\n"); - exit(1); - } - - fprintf(stderr, "STlink device opened, that's cool!\n"); - stlink_close(sl); - - return 0; -} diff --git a/doc/dev/developer.txt b/doc/dev/developer.txt deleted file mode 100644 index e3091c003..000000000 --- a/doc/dev/developer.txt +++ /dev/null @@ -1,411 +0,0 @@ -=== Compilation with pkg-config === - -In order to use pkg-config for development purposes, add the following lines to the toplevel CMakeLists.txt file: - -### -# Additional build tasks -### - -## Package configuration (pkg-config) on unix-based systems -if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) - add_subdirectory(doc/dev/pkg-config) # external tool pkg-config -endif () - -=== Target Identification === - -The following information is available about the target: -- chip id: 0xE0042000 or 0x40015800, primary information to derive flash and sram architection -- core id: Result from the STLINK_DEBUGREADCOREID call, additionally used for flash/sram architection -- cpu id: 0xE000ED00 (CMSIS System Control Block CPU ID), not used in stlink - - -=== Backend === - -The "backend" implements the interface to the adapter hardware. -There are two backends for two different adapters: "sg" (stlink v1?) and "usb" (stlink v2?). - - - -Include stlink/backend.h - typedef struct _stlink_backend { - void (*close) (stlink_t * sl); - int (*exit_debug_mode) (stlink_t * sl); - int (*enter_swd_mode) (stlink_t * sl); - int (*enter_jtag_mode) (stlink_t * stl); - int (*exit_dfu_mode) (stlink_t * stl); - int (*core_id) (stlink_t * stl); - int (*reset) (stlink_t * stl); - int (*jtag_reset) (stlink_t * stl, int value); - int (*run) (stlink_t * stl); - int (*status) (stlink_t * stl); - int (*version) (stlink_t *sl); - int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); - int (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); - int (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); - int (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); - int (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); - int (*read_all_regs) (stlink_t *sl, struct stlink_reg * regp); - int (*read_reg) (stlink_t *sl, int r_idx, struct stlink_reg * regp); - int (*read_all_unsupported_regs) (stlink_t *sl, struct stlink_reg *regp); - int (*read_unsupported_reg) (stlink_t *sl, int r_idx, struct stlink_reg *regp); - int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, struct stlink_reg *regp); - int (*write_reg) (stlink_t *sl, uint32_t reg, int idx); - int (*step) (stlink_t * stl); - int (*current_mode) (stlink_t * stl); - int (*force_debug) (stlink_t *sl); - int32_t (*target_voltage) (stlink_t *sl); - int (*set_swdclk) (stlink_t * stl, uint16_t divisor); - } stlink_backend_t; - -Descriptions below describe the actions of the usb.h backend: - -void (*close) (stlink_t * sl); -int (*exit_debug_mode) (stlink_t * sl); - __stlink_usb_exit_debug_mode: Send STLINK_DEBUG_EXIT - returns -1 or 0 - -int (*enter_swd_mode) (stlink_t * sl); - _stlink_usb_enter_swd_mode: Send STLINK_DEBUG_ENTER+STLINK_DEBUG_ENTER_SWD - returns -1 or 0 - -int (*enter_jtag_mode) (stlink_t * stl); - -int (*exit_dfu_mode) (stlink_t * stl); - _stlink_usb_exit_dfu_mode: Send STLINK_DFU_EXIT - returns -1 or 0 - -int (*core_id) (stlink_t * stl); - _stlink_usb_core_id: Assign the result from STLINK_DEBUG_READCOREID to stl->core_id - returns -1 or 0 - -int (*reset) (stlink_t * stl); - _stlink_usb_reset: Send STLINK_DEBUG_RESETSYS and reset via AIRCR - AIRCR is part of the CMSIS System Control Block (SCB), which is located in - the System Control Space at 0xE000ED0C - returns -1 or 0 ? - -int (*jtag_reset) (stlink_t * stl, int value); - _stlink_usb_jtag_reset: Send STLINK_JTAG_DRIVE_NRST. - "value" is sent as argument for STLINK_JTAG_DRIVE_NRST and probably contains - the status of the NRST line (0: low, 1: high). Also the value 2 is used in the software. - returns -1 or 0 - -int (*run) (stlink_t * stl); - _stlink_usb_run: Send STLINK_DEBUG_RUNCORE - returns -1 or 0 - -int (*status) (stlink_t * stl); - _stlink_usb_status: Assign the result from STLINK_DEBUG_GETSTATUS to stl->q_len - returns -1 or 0 - -int (*version) (stlink_t *sl); - _stlink_usb_version: Read version with STLINK_GET_VERSION. - Result is stored in sl->q_buf (6 bytes????) - returns -1 or 0 - -int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); - _stlink_usb_read_debug32: Send STLINK_JTAG_READDEBUG_32BIT - to read 32 bits from "addr". The result data is stored at "*data". - returns -1 or 0 - -int (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); - _stlink_usb_read_mem32: Use STLINK_DEBUG_READMEM_32BIT - to read "len" bytes from "addr" - Result is returned in sl->q_buf, sl->q_len returns the size of the data (should be - equal to "len"???). - returns -1 or 0 - -int (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); - _stlink_usb_write_debug32: Use STLINK_JTAG_WRITEDEBUG_32BIT - to store "data" at "addr" - returns -1 or 0 - -int (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); - _stlink_usb_write_mem32: Use STLINK_DEBUG_WRITEMEM_32BIT to - send data stored in sl->q_buf to the target at "addr". - "len" is the size data (???? not clear whether this are bytes ) - returns -1 or 0 - -int (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); - _stlink_usb_write_mem8: Use STLINK_DEBUG_WRITEMEM_8BIT to - send data stored in sl->q_buf to the target at "addr". - "len" is the size in bytes (probably). - returns -1 or 0 - -int (*read_all_regs) (stlink_t *sl, struct stlink_reg * regp); - _stlink_usb_read_all_regs: Send STLINK_DEBUG_READALLREGS to read - all register values and store them into *regp; - returns -1 or 0 - -int (*read_reg) (stlink_t *sl, int r_idx, struct stlink_reg * regp); - _stlink_usb_read_reg: Send STLINK_DEBUG_READREG to read specific register "r_idx". - The result is then stored in *regp in the correct register. - Example if "r_idx" is 18, then the result is stored in regp->process_sp - returns -1 or 0 - -int (*read_all_unsupported_regs) (stlink_t *sl, struct stlink_reg *regp); - _stlink_usb_read_all_unsupported_regs: Calls "_stlink_usb_read_unsupported_reg" - (see below) to read all registers. - returns -1 or 0 - -int (*read_unsupported_reg) (stlink_t *sl, int r_idx, struct stlink_reg *regp); - _stlink_usb_read_unsupported_reg Use DCRSR and DCRDR to access some - of the internal registers (primask, basepri, faultmask, control, fpscr). - Also will fill regp->s (???) for some specific "r_idx" values. - WARNING: Some r_idx values may lead to a out of array bound problem in C. - returns -1 or 0 - -int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, struct stlink_reg *regp); - _stlink_usb_write_unsupported_reg: - Updates one of the following registers: - primask (idx=0x1c), basepri (idx=0x1d), faultmask (idx=0x1e), control (idx=0x1f) - The new value is given as "value" as fn argument. - Corresponding values are refreshed in regp, however the old value for is kept in regp: - If basepri has to be updated (idx=0x1d), then all register values are fetched and - basepri is updated in the core, but not in *regp (BUG???). - returns -1 or 0 - -int (*write_reg) (stlink_t *sl, uint32_t reg, int idx); - _stlink_usb_write_reg: Use STLINK_DEBUG_WRITEREG to update register "idx" - with value "reg". - returns -1 or 0 - -int (*step) (stlink_t * stl); - _stlink_usb_step: Send STLINK_DEBUG_STEPCORE - returns -1 or 0 - -int (*current_mode) (stlink_t * stl); - _stlink_usb_current_mode: Send STLINK_GET_CURRENT_MODE and return - the current mode. - returns -1 or the value for the current mode. - Modes probably are: - STLINK_DEV_DFU_MODE 0x00 - STLINK_DEV_MASS_MODE 0x01 - STLINK_DEV_DEBUG_MODE 0x02 - -int (*force_debug) (stlink_t *sl); - _stlink_usb_force_debug: Sends STLINK_DEBUG_FORCEDEBUG. No other side effects - returns -1 or 0 - -int32_t (*target_voltage) (stlink_t *sl); - _stlink_usb_target_voltage: Send STLINK_GET_TARGET_VOLTAGE - returns -1 or the target voltage. (??? dimension is not clear...) - -int (*set_swdclk) (stlink_t * stl, uint16_t divisor); - _stlink_usb_set_swdclk: Send STLINK_DEBUG_APIV2_SWD_SET_FREQ and "divisor" value - returns -1 or 0 - - -=== Other Functions === - - -Include: stlink.h - - -Prototype: void stlink_close(stlink_t *sl); -Include: inc/stlink.h -Definition: src/common.c -Description: - Calls the backend "close" procedure and frees 'sl' -Backend: "close" -Arguments: - sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() -Return: - - -Include: inc/stlink.h -Prototype: int stlink_core_id(stlink_t *sl); -Definition: src/common.c -Description: - Calls the backend "core_id", calls stlink_print_data() on higher verbose levels. - Assigns the core id returned by STLINK_DEBUGREADCOREID to sl->core_id - Only some specific core ids are used: See include/stm32.h - Usage includes the selection of the correct flash algorithm. -Backend: "core_id" -Arguments: - sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() -Return: -1 for error. 0 for success. - -Include: inc/stlink.h -Prototype: int stlink_reset(stlink_t *sl); -Definition: src/common.c -Description: - Just calls the backend "reset" procedure (reset via STLINK_DEBUG_RESETSYS - and reset via AIRCR register at 0xE000ED0C) -Backend: "reset" -Arguments: - sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() -Return: -1 for error. 0 for success. - -Include: inc/stlink.h -Prototype: int stlink_jtag_reset(stlink_t *sl, int value); -Definition: src/common.c -Description: - Just calls the backend "jtag_reset" procedure -Backend: "jtag_reset" -Arguments: - sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() - value: 0: drive low, 1: drive high, 2: pulse -Return: -1 for error. 0 for success. - - -Include: inc/stlink.h -Prototype: int stlink_run(stlink_t *sl, enum run_type type); -Definition: src/common.c -Description: - Just calls the backend "run" procedure. -Backend: "run" -Arguments: - sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() - type: RUN_NORMAL - run target, RUN_FLASH_LOADER - run target with masking interrupts -Return: -1 for error. 0 for success. - -Include: inc/stlink.h -Prototype: int stlink_status(stlink_t *sl); -Definition: src/common.c -Description: - Calls the backend "status" procedure and the procedure "stlink_core_stat()" to - store the status in "sl->core_stat". Possible value for "sl->core_stat" are: - STLINK_CORE_RUNNING - STLINK_CORE_HALTED - STLINK_CORE_STAT_UNKNOWN -Backend: "status" -Arguments: - sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() -Return: -1 for error. 0 for success. - - -Include: inc/stlink.h -Prototype: int stlink_version(stlink_t *sl); -Definition: src/common.c -Description: - Calls the backend "version" procedure, parses the result and puts the result into sl->version - This version probably refers to the version of the adapter. -Backend: "version" -Arguments: - sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() -Return: -1 for error. 0 for success. - - - int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); - int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); - int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp); - int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); - int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); - int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); - int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, struct stlink_reg *regp); - int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); - int stlink_step(stlink_t *sl); - int stlink_current_mode(stlink_t *sl); - int stlink_force_debug(stlink_t *sl); - int stlink_target_voltage(stlink_t *sl); - int stlink_set_swdclk(stlink_t *sl, int freq_khz); - - int stlink_erase_flash_mass(stlink_t* sl); - int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); - int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); - uint8_t stlink_get_erased_pattern(stlink_t *sl); - int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); - int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); - int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); - int stlink_fwrite_option_bytes_32bit(stlink_t *sl,uint32_t val); - int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, 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); - -Include: inc/stlink.h -Prototype: int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); -Definition: src/common.c -Description: - Tries to read out the chip id via memory read from the device. - Note: sl->chip_id is NOT updated by this procedure. Instead this happens in stlink_load_device_params(): - Do not call this function, but instead call stlink_load_device_params() -Backend: - -Arguments: - sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() - chip_id: Pointer. Result is stored via this pointer. -Return: -1 for error. 0 for success. - - -Include: inc/stlink.h -Prototype: int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); -Definition: src/common.c -Description: - Reads the CPU id from STLINK_REG_CM3_CPUID (0xE000ED00, first value of - the SCB, system control block) and splits this into - cpuid->implementer_id - cpuid->variant - cpuid->part - cpuid->revision - The result is not used in the tools, but only in the usb test program. -Backend: - -Arguments: - sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() - cpuid: Pointer. Result is stored via this pointer. -Return: -1 for error. 0 for success. - - - - - int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); - uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); - uint16_t read_uint16(const unsigned char *c, const int pt); - void stlink_core_stat(stlink_t *sl); - - -Include: inc/stlink.h -Prototype: void stlink_print_data(stlink_t *sl); -Definition: src/common.c -Description: - If debug logging is enabled: Print the HEX content of the q_buf array. - q_buf will contain the result of the last "backend" command. -Backend: - -Arguments: - sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() -Return: - - - - unsigned int is_bigendian(void); - uint32_t read_uint32(const unsigned char *c, const int pt); - void write_uint32(unsigned char* buf, uint32_t ui); - void write_uint16(unsigned char* buf, uint16_t ui); - bool stlink_is_core_halted(stlink_t *sl); - int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); - int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); - int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); - - -Include: inc/stlink.h -Prototype: int stlink_load_device_params(stlink_t *sl); -Definition: src/common.c -Description: - This is one of the most important procedures. It will get all the device info - and store the results in the "sl" structure. Many other procedures will depend - on this information. - The identification is based on the stlink_chip_id() result and the flash_size register value -Backend: - -Arguments: - sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() -Return: -1 for error. 0 for success. - - int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte); - int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte); - - -Include "flash_loader.h" - -int stlink_flash_loader_init(stlink_t *sl, flash_loader_t* fl); -int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); -int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size); - - -Inlcude "sg.h" -stlink_t* stlink_v1_open(const int verbose, int reset); - -Include "usb.h" - -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE]); -size_t stlink_probe_usb(stlink_t **stdevs[]); -void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); diff --git a/doc/dev/pkg-config/CMakeLists.txt b/doc/dev/pkg-config/CMakeLists.txt deleted file mode 100644 index 53870fee4..000000000 --- a/doc/dev/pkg-config/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -set(PKG_CONFIG_LIBDIR "\${prefix}/lib/\${deb_host_multiarch}") -set(PKG_CONFIG_INCLUDEDIR "\${prefix}/include/\${deb_host_multiarch}/${PROJECT_NAME}") -set(PKG_CONFIG_LIBS "-L\${libdir} -l:libstlink.so.${PROJECT_VERSION_MAJOR}") -set(PKG_CONFIG_CFLAGS "-I\${includedir}") -set(PKG_CONFIG_REQUIRES "libusb-1.0") - -configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig.pc.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" - ) - -install( - FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" - DESTINATION ${STLINK_LIBRARY_PATH}/pkgconfig - ) diff --git a/doc/dev/pkg-config/pkgconfig.pc.cmake b/doc/dev/pkg-config/pkgconfig.pc.cmake deleted file mode 100644 index 4f881daec..000000000 --- a/doc/dev/pkg-config/pkgconfig.pc.cmake +++ /dev/null @@ -1,11 +0,0 @@ -prefix=${CMAKE_INSTALL_PREFIX} -deb_host_multiarch=${CMAKE_LIBRARY_PATH} -libdir=${PKG_CONFIG_LIBDIR} -includedir=${PKG_CONFIG_INCLUDEDIR} - -Name: ${PROJECT_NAME} -Description: ${PROJECT_DESCRIPTION} -Version: ${PROJECT_VERSION} -Libs: ${PKG_CONFIG_LIBS} -Cflags: ${PKG_CONFIG_CFLAGS} -Requires: ${PKG_CONFIG_REQUIRES} diff --git a/doc/devices_boards.md b/doc/devices_boards.md index 1a5099b72..feab9ffa9 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -53,10 +53,9 @@ Tested non-official ST boards [incl. STLINK programmers]: ## STM32F1 Clone / ARM Cortex M3 (Core-ID: 0x2ba01477) [may work, but without support!] -| Product-Code | Chip-ID | STLink
      Programmer | Boards | -| ------------- | ------- | ---------------------- | ----------------------------------------------------------------------------------------------- | -| CKS32F103C8Tx | 0x410 | v2 | "STM32"-Bluepill ( _**Fake-Marking !**_ )
      STM32F103C8T6 clone from China Key Systems (CKS) | -| CKS32F103C8Tx | 0x410 | v2 | CKS32-Bluepill (Clone)
      STM32F103C8T6 clone from China Key Systems (CKS) | +| Product-Code | Chip-ID | STLink
      Programmer | Boards | +| ------------- | ------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| CKS32F103C8Tx | 0x410 | v2 | STM32F103C8T6 clone from China Key Systems (CKS) either as
      CKS32-Bluepill or even as "STM32"-Bluepill with _**Fake-Marking !**_ | ## STM32F3 / ARM Cortex M4F diff --git a/inc/stlink.h b/inc/stlink.h index 17601fda8..b9379e03d 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -296,23 +296,6 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); int stlink_load_device_params(stlink_t *sl); -int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); -int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte); -int stlink_read_option_control_register32(stlink_t *sl, uint32_t* option_byte); -int stlink_read_option_control_register1_32(stlink_t *sl, uint32_t* option_byte); - -int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); -int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add); -int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_control_register); -int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_control_register1); - -int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); -int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); - -int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); -int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len); -int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl); - int stlink_target_connect(stlink_t *sl, enum connect_type connect); #include diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 058501ad6..0985c75c2 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -11,6 +11,7 @@ #include #include #include "flash.h" +#include "option_bytes.h" static stlink_t *connected_stlink = NULL; diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index cef79ddc1..802e23c06 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -28,6 +28,7 @@ #include #include #include +#include "flashloader.h" #include "gdb-remote.h" #include "gdb-server.h" #include "semihosting.h" diff --git a/src/calculate.c b/src/stlink-lib/calculate.c similarity index 100% rename from src/calculate.c rename to src/stlink-lib/calculate.c diff --git a/src/calculate.h b/src/stlink-lib/calculate.h similarity index 100% rename from src/calculate.h rename to src/stlink-lib/calculate.h diff --git a/src/common.c b/src/stlink-lib/common.c similarity index 100% rename from src/common.c rename to src/stlink-lib/common.c diff --git a/src/common.h b/src/stlink-lib/common.h similarity index 100% rename from src/common.h rename to src/stlink-lib/common.h diff --git a/src/common_flash.c b/src/stlink-lib/common_flash.c similarity index 99% rename from src/common_flash.c rename to src/stlink-lib/common_flash.c index 17352974c..b21929ddf 100644 --- a/src/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -3,6 +3,7 @@ #include #include #include "calculate.h" +#include "flashloader.h" #include "common_flash.h" #include "map_file.h" #include "common.h" diff --git a/src/common_flash.h b/src/stlink-lib/common_flash.h similarity index 100% rename from src/common_flash.h rename to src/stlink-lib/common_flash.h diff --git a/src/stlink-lib/flash_loader.h b/src/stlink-lib/flash_loader.h index 85b92bef3..368b6ab8b 100644 --- a/src/stlink-lib/flash_loader.h +++ b/src/stlink-lib/flash_loader.h @@ -1,8 +1,7 @@ /* - * File: stlink.h + * File: flash_loader.h * - * This should contain all the common top level stlink interfaces, - * regardless of how the backend does the work.... + * Flash loader */ #ifndef STLINK_FLASH_LOADER_H_ diff --git a/src/flashloader.c b/src/stlink-lib/flashloader.c similarity index 99% rename from src/flashloader.c rename to src/stlink-lib/flashloader.c index b9c26bf4c..abb140fdd 100644 --- a/src/flashloader.c +++ b/src/stlink-lib/flashloader.c @@ -1,6 +1,7 @@ #include #include #include +#include "flashloader.h" #include "common_flash.h" #define L1_WRITE_BLOCK_SIZE 0x80 diff --git a/src/stlink-lib/flashloader.h b/src/stlink-lib/flashloader.h new file mode 100644 index 000000000..ff16d183c --- /dev/null +++ b/src/stlink-lib/flashloader.h @@ -0,0 +1,13 @@ +/* + * File: flashloader.h + * + * Flash loader + */ + +#include +#include + +int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); +int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len); +int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl); + diff --git a/src/map_file.c b/src/stlink-lib/map_file.c similarity index 100% rename from src/map_file.c rename to src/stlink-lib/map_file.c diff --git a/src/map_file.h b/src/stlink-lib/map_file.h similarity index 100% rename from src/map_file.h rename to src/stlink-lib/map_file.h diff --git a/src/option_bytes.c b/src/stlink-lib/option_bytes.c similarity index 73% rename from src/option_bytes.c rename to src/stlink-lib/option_bytes.c index c1a418232..44cd3930b 100644 --- a/src/option_bytes.c +++ b/src/stlink-lib/option_bytes.c @@ -1,152 +1,32 @@ #include #include #include +#include "option_bytes.h" #include "common_flash.h" #include "map_file.h" #include "common.h" -/** - * Read option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_Gx(stlink_t *sl, - uint32_t *option_byte) { - return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); -} - -/** - * Read option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t *option_byte) { - return stlink_read_option_control_register_Gx(sl, option_byte); -} - -/** - * Read first option bytes - * @param sl - * @param option_byte option value - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte) { - DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); - return stlink_read_debug32(sl, sl->option_base, option_byte); -} - -/** - * Read option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_f2(stlink_t *sl, - uint32_t *option_byte) { - return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); -} - -/** - * Read option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t *option_byte) { - return stlink_read_option_control_register_f2(sl, option_byte); -} - -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_f4(stlink_t *sl, - uint32_t *option_byte) { - return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); -} - -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t *option_byte) { - return stlink_read_option_control_register_f4(sl, option_byte); -} /** - * Read option bytes + * Read option control register F0 * @param sl - * @param option_byte value to read + * @param option_byte * @return 0 on success, -ve on failure. - * - * Since multiple bytes can be read, we read and print all but one here - * and then return the last one just like other devices */ -int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t *option_byte) { - int err = -1; - for (uint32_t counter = 0; counter < (sl->option_size / 4 - 1); counter++) { - err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), - option_byte); - if (err == -1) { - return err; - } else { - printf("%08x\n", *option_byte); - } - } - - return stlink_read_debug32( - sl, - sl->option_base + (uint32_t)(sl->option_size / 4 - 1) * sizeof(uint32_t), - option_byte); -} - -/** - * Read option bytes - * @param sl - * @param option_byte option value - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); - return (-1); - } - - switch (sl->chip_id) { - case STM32_CHIPID_F2: - return stlink_read_option_bytes_f2(sl, option_byte); - case STM32_CHIPID_F4: - case STM32_CHIPID_F446: - return stlink_read_option_bytes_f4(sl, option_byte); - case STM32_CHIPID_F76xxx: - return stlink_read_option_bytes_f7(sl, option_byte); - case STM32_CHIPID_G0_CAT1: - case STM32_CHIPID_G0_CAT2: - case STM32_CHIPID_G4_CAT2: - case STM32_CHIPID_G4_CAT3: - return stlink_read_option_bytes_Gx(sl, option_byte); - default: - return stlink_read_option_bytes_generic(sl, option_byte); - } +int stlink_read_option_control_register_f0(stlink_t *sl, uint32_t *option_byte) { + DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_OBR); + return stlink_read_debug32(sl, FLASH_OBR, option_byte); } - /** - * Write option bytes + * Write option bytes F0 * @param sl - * @param base option bytes to write * @param addr of the memory mapped option bytes - * @param len of options bytes to write + * @param base option bytes + * @param len of option bytes * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f0( - stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { +static int stlink_write_option_bytes_f0(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { int ret = 0; if (len < 12 || addr != STM32_F0_OPTION_BYTES_BASE) { @@ -196,133 +76,139 @@ static int stlink_write_option_bytes_f0( } /** - * Write option bytes + * Write option control register F0 * @param sl - * @param addr of the memory mapped option bytes - * @param base option bytes to write + * @param option_cr * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - /* Write options bytes */ - uint32_t val; +static int stlink_write_option_control_register_f0(stlink_t *sl, uint32_t option_cr) { int ret = 0; - (void)len; - uint32_t data; + uint16_t opt_val[8]; + unsigned protection, optiondata; + uint16_t user_options, user_data, rdp; + unsigned option_offset, user_data_offset; + + ILOG("Asked to write option control register %#10x to %#010x.\n", option_cr, FLASH_OBR); + /* Clear errors */ clear_flash_error(sl); - write_uint32((unsigned char *)&data, *(uint32_t *)(base)); - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); + /* Retrieve current values */ + ret = stlink_read_debug32(sl, FLASH_OBR, &optiondata); + if (ret) { + return ret; + } + ret = stlink_read_debug32(sl, FLASH_WRPR, &protection); + if (ret) { + return ret; + } - // Set Options Start bit - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + /* Translate OBR value to flash store structure + * F0: RM0091, Option byte description, pp. 75-78 + * F1: PM0075, Option byte description, pp. 19-22 + * F3: RM0316, Option byte description, pp. 85-87 */ + switch(sl->chip_id) + { + case 0x422: /* STM32F30x */ + case 0x432: /* STM32F37x */ + case 0x438: /* STM32F303x6/8 and STM32F328 */ + case 0x446: /* STM32F303xD/E and STM32F398xE */ + case 0x439: /* STM32F302x6/8 */ + case 0x440: /* STM32F05x */ + case 0x444: /* STM32F03x */ + case 0x445: /* STM32F04x */ + case 0x448: /* STM32F07x */ + case 0x442: /* STM32F09x */ + option_offset = 6; + user_data_offset = 16; + rdp = 0x55AA; + break; + default: + option_offset = 0; + user_data_offset = 10; + rdp = 0x5AA5; + break; + } - wait_flash_busy(sl); + user_options = (option_cr >> option_offset >> 2) & 0xFFFF; + user_data = (option_cr >> user_data_offset) & 0xFFFF; - ret = check_flash_error(sl); +#define VAL_WITH_COMPLEMENT(v) (uint16_t)(((v)&0xFF) | (((~(v))<<8)&0xFF00)) - // Reload options - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + opt_val[0] = (option_cr & (1 << 1/*OPT_READOUT*/)) ? 0xFFFF : rdp; + opt_val[1] = VAL_WITH_COMPLEMENT(user_options); + opt_val[2] = VAL_WITH_COMPLEMENT(user_data); + opt_val[3] = VAL_WITH_COMPLEMENT(user_data >> 8); + opt_val[4] = VAL_WITH_COMPLEMENT(protection); + opt_val[5] = VAL_WITH_COMPLEMENT(protection >> 8); + opt_val[6] = VAL_WITH_COMPLEMENT(protection >> 16); + opt_val[7] = VAL_WITH_COMPLEMENT(protection >> 24); - return (ret); +#undef VAL_WITH_COMPLEMENT + + /* Write bytes and check errors */ + ret = stlink_write_option_bytes_f0(sl, STM32_F0_OPTION_BYTES_BASE, (uint8_t*)opt_val, sizeof(opt_val)); + if (ret) + return ret; + + ret = check_flash_error(sl); + if (!ret) { + ILOG("Wrote option bytes %#010x to %#010x!\n", option_cr, + FLASH_OBR); + } + + return ret; } /** - * Write option bytes + * Read option control register F2 * @param sl - * @param addr of the memory mapped option bytes - * @param base option bytes to write + * @param option_byte * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - uint32_t flash_base = get_stm32l0_flash_base(sl); - uint32_t val; - uint32_t data; - int ret = 0; - - // Clear errors - clear_flash_error(sl); - - while (len != 0) { - write_uint32((unsigned char *)&data, - *(uint32_t *)(base)); // write options bytes - - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - stlink_write_debug32(sl, addr, data); - wait_flash_busy(sl); - - if ((ret = check_flash_error(sl))) { - break; - } - - len -= 4; - addr += 4; - base += 4; - } - - // Reload options - stlink_read_debug32(sl, flash_base + FLASH_PECR_OFF, &val); - val |= (1 << STM32L0_FLASH_OBL_LAUNCH); - stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); - - return (ret); +int stlink_read_option_control_register_f2(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); } /** - * Write option bytes + * Read option bytes F2 * @param sl - * @param addr of the memory mapped option bytes - * @param base option bytes to write + * @param option_byte * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l4(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { - - uint32_t val; - int ret = 0; - (void)addr; - (void)len; - - // Clear errors - clear_flash_error(sl); - - // write options bytes - uint32_t data; - write_uint32((unsigned char *)&data, *(uint32_t *)(base)); - WLOG("Writing option bytes 0x%04x\n", data); - stlink_write_debug32(sl, STM32L4_FLASH_OPTR, data); - - // set options start bit - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1 << STM32L4_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - - wait_flash_busy(sl); - ret = check_flash_error(sl); +int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_f2(sl, option_byte); +} - // apply options bytes immediate - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); +/** + * Read option control register F4 + * @param sl + * @param option_byte + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f4(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); +} - return (ret); +/** + * Read option bytes F4 + * @param sl + * @param option_byte + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_f4(sl, option_byte); } /** - * Write option bytes + * Write option bytes F4 * @param sl - * @param option_byte value to write + * @param addr of the memory mapped option bytes + * @param base option bytes + * @param len of option bytes * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { +static int stlink_write_option_bytes_f4(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { uint32_t option_byte; int ret = 0; (void)addr; @@ -346,13 +232,40 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t *base, } /** - * Write option bytes + * Read option bytes F7 * @param sl - * @param option_byte value to write + * @param option_byte * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { +// Since multiple bytes can be read, we read and print all, but one here +// and then return the last one just like other devices. +int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t *option_byte) { + int err = -1; + for (uint32_t counter = 0; counter < (sl->option_size / 4 - 1); counter++) { + err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), + option_byte); + if (err == -1) { + return err; + } else { + printf("%08x\n", *option_byte); + } + } + + return stlink_read_debug32( + sl, + sl->option_base + (uint32_t)(sl->option_size / 4 - 1) * sizeof(uint32_t), + option_byte); +} + +/** + * Write option bytes F7 + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes + * @param len of option bytes + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_f7(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { uint32_t option_byte; int ret = 0; @@ -392,25 +305,193 @@ static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t *base, wait_flash_busy(sl); ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t *)base, - addr); + if (!ret) + ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t *)base, + addr); + + /* option bytes are reloaded at reset only, no obl. */ + + return ret; +} + +/** + * Read option control register F7 + * @param sl + * @param option_byte + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_f7(stlink_t *sl, uint32_t *option_byte) { + DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_F7_OPTCR); + return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte); +} + +/** + * Write option control register F7 + * @param sl + * @param option_cr + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option_cr) { + int ret = 0; + + // Clear errors + clear_flash_error(sl); + + ILOG("Asked to write option control register 1 %#10x to %#010x.\n", + option_cr, FLASH_F7_OPTCR); + + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F7_OPTCR, + (option_cr & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_cr, + FLASH_F7_OPTCR); + + return ret; +} + +/** + * Read option control register1 F7 + * @param sl + * @param option_byte + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register1_f7(stlink_t *sl, uint32_t *option_byte) { + DLOG("@@@@ Read option control register 1 byte from %#10x\n", + FLASH_F7_OPTCR1); + return stlink_read_debug32(sl, FLASH_F7_OPTCR1, option_byte); +} + +/** + * Write option control register1 F7 + * @param sl + * @param option_cr1 + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t option_cr1) { + int ret = 0; + + // Clear errors + clear_flash_error(sl); + + ILOG("Asked to write option control register 1 %#010x to %#010x.\n", + option_cr1, FLASH_F7_OPTCR1); + + /* write option byte, ensuring we dont lock opt, and set strt bit */ + uint32_t current_control_register_value; + stlink_read_debug32(sl, FLASH_F7_OPTCR, ¤t_control_register_value); + + /* write option byte */ + stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_cr1); + stlink_write_debug32( + sl, FLASH_F7_OPTCR, + (current_control_register_value & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_cr1, FLASH_F7_OPTCR1); + + return ret; +} + +/** + * Read option bytes boot address F7 + * @param sl + * @param option_byte + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t *option_byte) { + DLOG("@@@@ Read option byte boot address\n"); + return stlink_read_option_control_register1_f7(sl, option_byte); +} + +/** + * Write option bytes boot address F7 + * @param sl + * @param option_byte + * @return 0 on success, -ve on failure. + */ +static int +stlink_write_option_bytes_boot_add_f7(stlink_t *sl, uint32_t option_byte_boot_add) { + ILOG("Asked to write option byte boot add %#010x.\n", option_byte_boot_add); + return stlink_write_option_control_register1_f7(sl, option_byte_boot_add); +} + +/** + * Read option control register Gx + * @param sl + * @param option_byte + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_gx(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); +} + +/** + * Read option bytes Gx + * @param sl + * @param option_byte + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_gx(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_gx(sl, option_byte); +} + +/** + * Write option bytes Gx + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes + * @param len of option bytes + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_gx(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { + /* Write options bytes */ + uint32_t val; + int ret = 0; + (void)len; + uint32_t data; + + clear_flash_error(sl); + + write_uint32((unsigned char *)&data, *(uint32_t *)(base)); + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); + + // Set Options Start bit + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); - /* option bytes are reloaded at reset only, no obl. */ + // Reload options + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - return ret; + return (ret); } /** - * Write STM32H7xx option bytes + * Write option bytes H7 * @param sl - * @param base option bytes to write * @param addr of the memory mapped option bytes - * @param len number of bytes to write (must be multiple of 4) + * @param base option bytes + * @param len of option bytes * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_h7(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { +static int stlink_write_option_bytes_h7(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { uint32_t val; uint32_t data; @@ -473,14 +554,96 @@ static int stlink_write_option_bytes_h7(stlink_t *sl, uint8_t *base, } /** - * Write option bytes + * Write option bytes L0 + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes + * @param len of option bytes + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_l0(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { + uint32_t flash_base = get_stm32l0_flash_base(sl); + uint32_t val; + uint32_t data; + int ret = 0; + + // Clear errors + clear_flash_error(sl); + + while (len != 0) { + write_uint32((unsigned char *)&data, + *(uint32_t *)(base)); // write options bytes + + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + stlink_write_debug32(sl, addr, data); + wait_flash_busy(sl); + + if ((ret = check_flash_error(sl))) { + break; + } + + len -= 4; + addr += 4; + base += 4; + } + + // Reload options + stlink_read_debug32(sl, flash_base + FLASH_PECR_OFF, &val); + val |= (1 << STM32L0_FLASH_OBL_LAUNCH); + stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); + + return (ret); +} + +/** + * Write option bytes L4 + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes + * @param len of option bytes + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_bytes_l4(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { + + uint32_t val; + int ret = 0; + (void)addr; + (void)len; + + // Clear errors + clear_flash_error(sl); + + // write options bytes + uint32_t data; + write_uint32((unsigned char *)&data, *(uint32_t *)(base)); + WLOG("Writing option bytes 0x%04x\n", data); + stlink_write_debug32(sl, STM32L4_FLASH_OPTR, data); + + // set options start bit + stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); + val |= (1 << STM32L4_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + + wait_flash_busy(sl); + ret = check_flash_error(sl); + + // apply options bytes immediate + stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); + val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); + stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + + return (ret); +} + +/** + * Write option bytes WB * @param sl * @param addr of the memory mapped option bytes - * @param base option bytes to write + * @param base option bytes + * @param len of option bytes * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_wb(stlink_t *sl, uint8_t *base, - stm32_addr_t addr, uint32_t len) { +static int stlink_write_option_bytes_wb(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { /* Write options bytes */ uint32_t val; int ret = 0; @@ -490,8 +653,7 @@ static int stlink_write_option_bytes_wb(stlink_t *sl, uint8_t *base, clear_flash_error(sl); while (len != 0) { - write_uint32((unsigned char *)&data, - *(uint32_t *)(base)); // write options bytes + write_uint32((unsigned char *)&data, *(uint32_t *)(base)); // write options bytes WLOG("Writing option bytes %#10x to %#10x\n", data, addr); stlink_write_debug32(sl, addr, data); @@ -523,15 +685,71 @@ static int stlink_write_option_bytes_wb(stlink_t *sl, uint8_t *base, return (ret); } +/** + * Read option control register WB + * @param sl + * @param option_byte + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_control_register_wb(stlink_t *sl, uint32_t *option_byte) { + DLOG("@@@@ Read option control register byte from %#10x\n", STM32WB_FLASH_OPTR); + return stlink_read_debug32(sl, STM32WB_FLASH_OPTR, option_byte); +} + +/** + * Write option control register WB + * @param sl + * @param option_cr + * @return 0 on success, -ve on failure. + */ +static int stlink_write_option_control_register_wb(stlink_t *sl, uint32_t option_cr) { + int ret = 0; + + // Clear errors + clear_flash_error(sl); + + ILOG("Asked to write option control register 1 %#10x to %#010x.\n", + option_cr, STM32WB_FLASH_OPTR); + + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, STM32WB_FLASH_OPTR, option_cr); + + wait_flash_busy(sl); + + // Set Options Start bit + uint32_t val = (1 << STM32WB_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_cr, STM32WB_FLASH_OPTR); + + return ret; +} + +/** + * Read option bytes generic + * @param sl + * @param option_byte + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte) { + DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); + return stlink_read_debug32(sl, sl->option_base, option_byte); +} + + /** * Write option bytes * @param sl * @param addr of the memory mapped option bytes - * @param base option bytes to write + * @param base option bytes + * @param len of option bytes * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, - uint32_t len) { +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { int ret = -1; if (sl->option_base == 0) { @@ -566,29 +784,29 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, switch (sl->flash_type) { case STM32_FLASH_TYPE_F0_F1_F3: case STM32_FLASH_TYPE_F1_XL: - ret = stlink_write_option_bytes_f0(sl, base, addr, len); + ret = stlink_write_option_bytes_f0(sl, addr, base, len); break; case STM32_FLASH_TYPE_F2_F4: - ret = stlink_write_option_bytes_f4(sl, base, addr, len); + ret = stlink_write_option_bytes_f4(sl, addr, base, len); break; case STM32_FLASH_TYPE_F7: - ret = stlink_write_option_bytes_f7(sl, base, addr, len); + ret = stlink_write_option_bytes_f7(sl, addr, base, len); break; case STM32_FLASH_TYPE_L0_L1: - ret = stlink_write_option_bytes_l0(sl, base, addr, len); + ret = stlink_write_option_bytes_l0(sl, addr, base, len); break; case STM32_FLASH_TYPE_L4_L4P: - ret = stlink_write_option_bytes_l4(sl, base, addr, len); + ret = stlink_write_option_bytes_l4(sl, addr, base, len); break; case STM32_FLASH_TYPE_G0: case STM32_FLASH_TYPE_G4: - ret = stlink_write_option_bytes_gx(sl, base, addr, len); + ret = stlink_write_option_bytes_gx(sl, addr, base, len); break; case STM32_FLASH_TYPE_H7: - ret = stlink_write_option_bytes_h7(sl, base, addr, len); + ret = stlink_write_option_bytes_h7(sl, addr, base, len); break; case STM32_FLASH_TYPE_WB_WL: - ret = stlink_write_option_bytes_wb(sl, base, addr, len); + ret = stlink_write_option_bytes_wb(sl, addr, base, len); break; default: ELOG("Option bytes writing is currently not implemented for connected " @@ -603,216 +821,72 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, } /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); - - return ret; -} - - -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -static int -stlink_write_option_control_register_f0(stlink_t *sl, - uint32_t option_control_register) { - int ret = 0; - uint16_t opt_val[8]; - unsigned protection, optiondata; - uint16_t user_options, user_data, rdp; - unsigned option_offset, user_data_offset; - - ILOG("Asked to write option control register %#10x to %#010x.\n", - option_control_register, FLASH_OBR); - - /* Clear errors */ - clear_flash_error(sl); - - /* Retrieve current values */ - ret = stlink_read_debug32(sl, FLASH_OBR, &optiondata); - if (ret) { - return ret; - } - ret = stlink_read_debug32(sl, FLASH_WRPR, &protection); - if (ret) { - return ret; - } - - /* Translate OBR value to flash store structure - * F0: RM0091, Option byte description, pp. 75-78 - * F1: PM0075, Option byte description, pp. 19-22 - * F3: RM0316, Option byte description, pp. 85-87 */ - switch(sl->chip_id) - { - case 0x422: /* STM32F30x */ - case 0x432: /* STM32F37x */ - case 0x438: /* STM32F303x6/8 and STM32F328 */ - case 0x446: /* STM32F303xD/E and STM32F398xE */ - case 0x439: /* STM32F302x6/8 */ - case 0x440: /* STM32F05x */ - case 0x444: /* STM32F03x */ - case 0x445: /* STM32F04x */ - case 0x448: /* STM32F07x */ - case 0x442: /* STM32F09x */ - option_offset = 6; - user_data_offset = 16; - rdp = 0x55AA; - break; - default: - option_offset = 0; - user_data_offset = 10; - rdp = 0x5AA5; - break; - } - - user_options = (option_control_register >> option_offset >> 2) & 0xFFFF; - user_data = (option_control_register >> user_data_offset) & 0xFFFF; - -#define VAL_WITH_COMPLEMENT(v) (uint16_t)(((v)&0xFF) | (((~(v))<<8)&0xFF00)) - - opt_val[0] = (option_control_register & (1 << 1/*OPT_READOUT*/)) ? 0xFFFF : rdp; - opt_val[1] = VAL_WITH_COMPLEMENT(user_options); - opt_val[2] = VAL_WITH_COMPLEMENT(user_data); - opt_val[3] = VAL_WITH_COMPLEMENT(user_data >> 8); - opt_val[4] = VAL_WITH_COMPLEMENT(protection); - opt_val[5] = VAL_WITH_COMPLEMENT(protection >> 8); - opt_val[6] = VAL_WITH_COMPLEMENT(protection >> 16); - opt_val[7] = VAL_WITH_COMPLEMENT(protection >> 24); - -#undef VAL_WITH_COMPLEMENT - - /* Write bytes and check errors */ - ret = stlink_write_option_bytes_f0(sl, (uint8_t*)opt_val, STM32_F0_OPTION_BYTES_BASE, sizeof(opt_val)); - if (ret) - return ret; - - ret = check_flash_error(sl); - if (!ret) { - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, - FLASH_OBR); - } - - return ret; -} - - -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -static int -stlink_write_option_control_register1_f7(stlink_t *sl, - uint32_t option_control_register1) { - int ret = 0; - - // Clear errors - clear_flash_error(sl); - - ILOG("Asked to write option control register 1 %#010x to %#010x.\n", - option_control_register1, FLASH_F7_OPTCR1); - - /* write option byte, ensuring we dont lock opt, and set strt bit */ - uint32_t current_control_register_value; - stlink_read_debug32(sl, FLASH_F7_OPTCR, ¤t_control_register_value); - - /* write option byte */ - stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_control_register1); - stlink_write_debug32( - sl, FLASH_F7_OPTCR, - (current_control_register_value & ~(1 << FLASH_F7_OPTCR_LOCK)) | - (1 << FLASH_F7_OPTCR_START)); - - wait_flash_busy(sl); - - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register1, - FLASH_F7_OPTCR1); + lock_flash_option(sl); + lock_flash(sl); return ret; } /** - * Write option bytes + * Write the given binary file with option bytes * @param sl - * @param option_byte value to write + * @param path readable file path, should be binary image + * @param addr of the memory mapped option bytes * @return 0 on success, -ve on failure. */ -static int -stlink_write_option_control_register_f7(stlink_t *sl, - uint32_t option_control_register) { - int ret = 0; - - // Clear errors - clear_flash_error(sl); - - ILOG("Asked to write option control register 1 %#10x to %#010x.\n", - option_control_register, FLASH_F7_OPTCR); +int stlink_fwrite_option_bytes(stlink_t *sl, const char *path, stm32_addr_t addr) { + /* Write the file in flash at addr */ + int err; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; - /* write option byte, ensuring we dont lock opt, and set strt bit */ - stlink_write_debug32(sl, FLASH_F7_OPTCR, - (option_control_register & ~(1 << FLASH_F7_OPTCR_LOCK)) | - (1 << FLASH_F7_OPTCR_START)); + if (map_file(&mf, path) == -1) { + ELOG("map_file() == -1\n"); + return (-1); + } - wait_flash_busy(sl); + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, - FLASH_F7_OPTCR); + err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t)mf.len); + stlink_fwrite_finalize(sl, addr); + unmap_file(&mf); - return ret; + return (err); } /** - * Write option bytes + * Read option control register 32 * @param sl - * @param option_byte value to write + * @param option_byte * @return 0 on success, -ve on failure. */ -static int -stlink_write_option_control_register_wb(stlink_t *sl, - uint32_t option_control_register) { - int ret = 0; - - // Clear errors - clear_flash_error(sl); - - ILOG("Asked to write option control register 1 %#10x to %#010x.\n", - option_control_register, STM32WB_FLASH_OPTR); - - /* write option byte, ensuring we dont lock opt, and set strt bit */ - stlink_write_debug32(sl, STM32WB_FLASH_OPTR, option_control_register); - - wait_flash_busy(sl); - - // Set Options Start bit - uint32_t val = (1 << STM32WB_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - - wait_flash_busy(sl); - - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, - STM32WB_FLASH_OPTR); +int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } - return ret; + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + return stlink_read_option_control_register_f0(sl, option_byte); + case STM32_FLASH_TYPE_F7: + return stlink_read_option_control_register_f7(sl, option_byte); + case STM32_FLASH_TYPE_WB_WL: + return stlink_read_option_control_register_wb(sl, option_byte); + default: + return -1; + } } /** - * Write option bytes + * Write option control register 32 * @param sl - * @param option bytes boot address to write + * @param option_cr * @return 0 on success, -ve on failure. */ -int stlink_write_option_control_register32(stlink_t *sl, - uint32_t option_control_register) { +int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_cr) { int ret = -1; wait_flash_busy(sl); @@ -831,14 +905,14 @@ int stlink_write_option_control_register32(stlink_t *sl, switch (sl->flash_type) { case STM32_FLASH_TYPE_F0_F1_F3: case STM32_FLASH_TYPE_F1_XL: - ret = stlink_write_option_control_register_f0(sl, option_control_register); + ret = stlink_write_option_control_register_f0(sl, option_cr); break; case STM32_FLASH_TYPE_F7: - ret = stlink_write_option_control_register_f7(sl, option_control_register); + ret = stlink_write_option_control_register_f7(sl, option_cr); break; case STM32_FLASH_TYPE_WB_WL: ret = - stlink_write_option_control_register_wb(sl, option_control_register); + stlink_write_option_control_register_wb(sl, option_cr); break; default: ELOG("Option control register writing is currently not implemented for " @@ -849,7 +923,7 @@ int stlink_write_option_control_register32(stlink_t *sl, if (ret) ELOG("Flash option write failed!\n"); else - ILOG("Wrote option control register %#010x!\n", option_control_register); + ILOG("Wrote option control register %#010x!\n", option_cr); /* Re-lock flash. */ lock_flash_option(sl); @@ -859,72 +933,33 @@ int stlink_write_option_control_register32(stlink_t *sl, } /** - * Write option bytes + * Read option control register1 32 * @param sl - * @param option bytes boot address to write + * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_write_option_control_register1_32( - stlink_t *sl, uint32_t option_control_register1) { - int ret = -1; - - wait_flash_busy(sl); - - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it " - "again!\n"); - return -1; - } - - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); +int stlink_read_option_control_register1_32(stlink_t *sl, uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); return -1; } switch (sl->flash_type) { case STM32_FLASH_TYPE_F7: - ret = - stlink_write_option_control_register1_f7(sl, option_control_register1); - break; + return stlink_read_option_control_register1_f7(sl, option_byte); default: - ELOG("Option control register 1 writing is currently not implemented for " - "connected chip\n"); - break; + return -1; + // return stlink_read_option_control_register1_generic(sl, option_byte); } - - if (ret) - ELOG("Flash option write failed!\n"); - else - ILOG("Wrote option control register 1 %#010x!\n", option_control_register1); - - lock_flash_option(sl); - lock_flash(sl); - - return (ret); -} - - -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -static int -stlink_write_option_bytes_boot_add_f7(stlink_t *sl, - uint32_t option_byte_boot_add) { - ILOG("Asked to write option byte boot add %#010x.\n", option_byte_boot_add); - return stlink_write_option_control_register1_f7(sl, option_byte_boot_add); } /** - * Write option bytes + * Write option control register1 32 * @param sl - * @param option bytes boot address to write + * @param option_cr * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes_boot_add32(stlink_t *sl, - uint32_t option_bytes_boot_add) { +int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_cr1) { int ret = -1; wait_flash_busy(sl); @@ -942,10 +977,11 @@ int stlink_write_option_bytes_boot_add32(stlink_t *sl, switch (sl->flash_type) { case STM32_FLASH_TYPE_F7: - ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); + ret = + stlink_write_option_control_register1_f7(sl, option_cr1); break; default: - ELOG("Option bytes boot address writing is currently not implemented for " + ELOG("Option control register 1 writing is currently not implemented for " "connected chip\n"); break; } @@ -953,108 +989,63 @@ int stlink_write_option_bytes_boot_add32(stlink_t *sl, if (ret) ELOG("Flash option write failed!\n"); else - ILOG("Wrote option bytes boot address %#010x!\n", option_bytes_boot_add); + ILOG("Wrote option control register 1 %#010x!\n", option_cr1); - /* Re-lock flash. */ lock_flash_option(sl); lock_flash(sl); - return ret; -} - -/** - * Write option bytes - * @param sl - * @param option_byte value to write - * @return 0 on success, -ve on failure. - */ -int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { - WLOG("About to write option byte %#10x to %#10x.\n", option_byte, - sl->option_base); - return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *)&option_byte, - 4); -} - -/** - * Write the given binary file with option bytes - * @param sl - * @param path readable file path, should be binary image - * @param addr of the memory mapped option bytes - * @return 0 on success, -ve on failure. - */ -int stlink_fwrite_option_bytes(stlink_t *sl, const char *path, - stm32_addr_t addr) { - /* Write the file in flash at addr */ - int err; - mapped_file_t mf = MAPPED_FILE_INITIALIZER; - - if (map_file(&mf, path) == -1) { - ELOG("map_file() == -1\n"); - return (-1); - } - - printf("file %s ", path); - md5_calculate(&mf); - stlink_checksum(&mf); - - err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t)mf.len); - stlink_fwrite_finalize(sl, addr); - unmap_file(&mf); - - return (err); -} - -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register1_f7(stlink_t *sl, - uint32_t *option_byte) { - DLOG("@@@@ Read option control register 1 byte from %#10x\n", - FLASH_F7_OPTCR1); - return stlink_read_debug32(sl, FLASH_F7_OPTCR1, option_byte); + return (ret); } /** - * Read option bytes + * Read option bytes 32 * @param sl - * @param option_byte option value + * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register1_32(stlink_t *sl, - uint32_t *option_byte) { +int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { if (sl->option_base == 0) { ELOG("Option bytes read is currently not supported for connected chip\n"); - return -1; + return (-1); } - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F7: - return stlink_read_option_control_register1_f7(sl, option_byte); + switch (sl->chip_id) { + case STM32_CHIPID_F2: + return stlink_read_option_bytes_f2(sl, option_byte); + case STM32_CHIPID_F4: + case STM32_CHIPID_F446: + return stlink_read_option_bytes_f4(sl, option_byte); + case STM32_CHIPID_F76xxx: + return stlink_read_option_bytes_f7(sl, option_byte); + case STM32_CHIPID_G0_CAT1: + return stlink_read_option_bytes_gx(sl, option_byte); + case STM32_CHIPID_G0_CAT2: + return stlink_read_option_bytes_gx(sl, option_byte); + case STM32_CHIPID_G4_CAT2: + return stlink_read_option_bytes_gx(sl, option_byte); + case STM32_CHIPID_G4_CAT3: + return stlink_read_option_bytes_gx(sl, option_byte); default: - return -1; - // return stlink_read_option_control_register1_generic(sl, option_byte); + return stlink_read_option_bytes_generic(sl, option_byte); } } - /** - * Read option bytes + * Write option bytes 32 * @param sl - * @param option_byte value to read + * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t *option_byte) { - DLOG("@@@@ Read option byte boot address\n"); - return stlink_read_option_control_register1_f7(sl, option_byte); +int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { + WLOG("About to write option byte %#10x to %#10x.\n", option_byte, + sl->option_base); + return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *)&option_byte, 4); } /** - * Read option bytes + * Read option bytes boot address 32 * @param sl - * @param option_byte option value + * @param option_byte * @return 0 on success, -ve on failure. */ int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { @@ -1074,62 +1065,45 @@ int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { } /** - * Read option bytes + * Write option bytes boot address 32 * @param sl - * @param option_byte value to read + * @param option_bytes_boot_add * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_f7(stlink_t *sl, - uint32_t *option_byte) { - DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_F7_OPTCR); - return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte); -} +int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add) { + int ret = -1; -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_f0(stlink_t *sl, - uint32_t *option_byte) { - DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_OBR); - return stlink_read_debug32(sl, FLASH_OBR, option_byte); -} + wait_flash_busy(sl); -/** - * Read option bytes - * @param sl - * @param option_byte value to read - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register_wb(stlink_t *sl, - uint32_t *option_byte) { - DLOG("@@@@ Read option control register byte from %#10x\n", STM32WB_FLASH_OPTR); - return stlink_read_debug32(sl, STM32WB_FLASH_OPTR, option_byte); -} + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return -1; + } -/** - * Read option bytes - * @param sl - * @param option_byte option value - * @return 0 on success, -ve on failure. - */ -int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); return -1; } switch (sl->flash_type) { - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - return stlink_read_option_control_register_f0(sl, option_byte); case STM32_FLASH_TYPE_F7: - return stlink_read_option_control_register_f7(sl, option_byte); - case STM32_FLASH_TYPE_WB_WL: - return stlink_read_option_control_register_wb(sl, option_byte); + ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); + break; default: - return -1; + ELOG("Option bytes boot address writing is currently not implemented for " + "connected chip\n"); + break; } + + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option bytes boot address %#010x!\n", option_bytes_boot_add); + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; } diff --git a/src/stlink-lib/option_bytes.h b/src/stlink-lib/option_bytes.h new file mode 100644 index 000000000..b9f88c508 --- /dev/null +++ b/src/stlink-lib/option_bytes.h @@ -0,0 +1,21 @@ +/* + * File: option_bytes.h + * + * Read and write option bytes and option control registers + */ + +#include +#include + +int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); +int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte); +int stlink_read_option_control_register32(stlink_t *sl, uint32_t* option_byte); +int stlink_read_option_control_register1_32(stlink_t *sl, uint32_t* option_byte); + +int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); +int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add); +int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_cr); +int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_cr1); + +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); +int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); diff --git a/src/read_write.c b/src/stlink-lib/read_write.c similarity index 100% rename from src/read_write.c rename to src/stlink-lib/read_write.c From aee9a47e3551d3cac9449ef1cceed30ecdcff133 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 30 Dec 2022 18:01:06 +0100 Subject: [PATCH 1341/1435] General fixes and improvements - Bugfix: "Failed to parse flash type or unrecognized flash type" (Closes #1240) (Closes #1242) (Closes #1290) (Closes #1291) - Updated README.md on OS-support - Updated version_support.md - Removed remnants of macOS support in CMakeLists.txt - Minor code formatting fixes - Updated CHANGELOG.md --- CHANGELOG.md | 17 +++-- CMakeLists.txt | 10 +-- README.md | 8 +-- doc/version_support.md | 154 +++++++++++++++++++++------------------- src/st-flash/flash.c | 24 ++++--- src/st-trace/trace.c | 3 +- src/stlink-lib/chipid.c | 28 ++++++-- src/stlink-lib/common.c | 2 +- 8 files changed, 134 insertions(+), 112 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f48840c3f..82656d50b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # v1.7.1 -Release date: 2022-xx-xx +Release date: 2023-xx-xx This release drops support for some older operating systems. Check project README for details. @@ -18,7 +18,7 @@ Features: - Added option byte info for STM32F411XX ([#1141](https://github.com/stlink-org/stlink/pull/1141)) - Expanded and revised list of chips ([#1145](https://github.com/stlink-org/stlink/pull/1145), [#1164](https://github.com/stlink-org/stlink/pull/1164)) - [STM32H72X/3X]: Added full access to all device memory ([#1158](https://github.com/stlink-org/stlink/pull/1158), [#1159](https://github.com/stlink-org/stlink/pull/1159)) -- Added support for STM32WLEx ([#1173](https://github.com/stlink-org/stlink/pull/1173)) +- Added support for STM32WLEx ([#1173](https://github.com/stlink-org/stlink/pull/1173), [#1273](https://github.com/stlink-org/stlink/pull/1273)) - Added support for STLINK-V3 devices with no MSD ([#1185](https://github.com/stlink-org/stlink/pull/1185)) - Updated gdb-server.c to allow external memory access on STM32H73xx ([#1196](https://github.com/stlink-org/stlink/pull/1196), [#1197](https://github.com/stlink-org/stlink/pull/1197)) - Erase addr size / section of the flash memory with st-flash ([#1213](https://github.com/stlink-org/stlink/pull/1213)) @@ -26,10 +26,12 @@ Features: - Added parametres option_base, option_size for F401xD_xE ([#1235](https://github.com/stlink-org/stlink/pull/1235)) - Added support for option bytes to F1xx_XLD (GD32F30x) ([#1250](https://github.com/stlink-org/stlink/pull/1250)) - Added option byte address for L4Rx devices ([#1254](https://github.com/stlink-org/stlink/pull/1254)) +- Added udev-rule rule for the STLink v3 MINIE programmer ([#1274](https://github.com/stlink-org/stlink/pull/1274), [#1281](https://github.com/stlink-org/stlink/pull/1281)) Updates & changes: - [refactoring] Moved chip-specific parameters into separate files ([#237](https://github.com/stlink-org/stlink/pull/237), [#1129](https://github.com/stlink-org/stlink/pull/1129)) +- [refactoring] General maintenance for code structure ([#903](https://github.com/stlink-org/stlink/pull/903), [#1090](https://github.com/stlink-org/stlink/pull/1090), [#1199](https://github.com/stlink-org/stlink/pull/1199), [#1212](https://github.com/stlink-org/stlink/pull/1212), [#1216](https://github.com/stlink-org/stlink/pull/1216)) - Added instructions for bug-reports and feature-requests to contribution guidelines ([#906](https://github.com/stlink-org/stlink/pull/906)) - Added travis CI configuration for macOS 10.14 to maintain capability for 32-bit compilation (commit [#f5ada94](https://github.com/stlink-org/stlink/commit/f5ada9474cdb87ff37de0d4eb9e75622b5870646)) - Updated description of chip id 0x0457 to L01x/L02x ([#1143](https://github.com/stlink-org/stlink/pull/1143), [#1144](https://github.com/stlink-org/stlink/pull/1144)) @@ -45,6 +47,7 @@ Updates & changes: - [doc] Linux Install from code Documentation improvement ([#1263](https://github.com/stlink-org/stlink/pull/1263), (commit [#43498de](https://github.com/stlink-org/stlink/commit/43498dedf651260ef34197e512d35e3ad7142401)) Fixes: +- cmake: Install shared libraries in proper directories ([#1098](https://github.com/stlink-org/stlink/pull/1098), [#1138](https://github.com/stlink-org/stlink/pull/1138), [#1154](https://github.com/stlink-org/stlink/pull/1154)) - cmake: Install shared libraries in proper directories ([#1142](https://github.com/stlink-org/stlink/pull/1142)) - Fixed clearance of the H7 dual bank flag ([#1146](https://github.com/stlink-org/stlink/pull/1146), [#1147](https://github.com/stlink-org/stlink/pull/1147)) - Fix for 'libusb_devices were leaked' when no ST-LINK programmer was found ([#1150](https://github.com/stlink-org/stlink/pull/1150)) @@ -66,6 +69,10 @@ Fixes: - Fixed compilation with gcc-12 ([#1257](https://github.com/stlink-org/stlink/pull/1257), [#1267](https://github.com/stlink-org/stlink/pull/1267)) - Fixed flash regs addr for STM32L152RET6 in common_flash.c ([#1265](https://github.com/stlink-org/stlink/pull/1265)) - Fixed flash, dbgmcu and rcc registers for STM32L1 ([#1266](https://github.com/stlink-org/stlink/pull/1266)) +- Fixed compilation with gcc-12 ([#1257](https://github.com/stlink-org/stlink/pull/1257), [#1267](https://github.com/stlink-org/stlink/pull/1267)) +- Fixes for project compilation ([#1270](https://github.com/stlink-org/stlink/pull/1270), [#1271](https://github.com/stlink-org/stlink/pull/1271), [#1283](https://github.com/stlink-org/stlink/pull/1283), [#1286](https://github.com/stlink-org/stlink/pull/1286),commit [#f93adb9](https://github.com/stlink-org/stlink/commit/f93adb92f2e4ecf05a9361cb723c98693586929d)) +- [compilation] Corrected path to stlink/chips subdirectory ([#1276](https://github.com/stlink-org/stlink/pull/1276), [#1279](https://github.com/stlink-org/stlink/pull/1279)) +- [compilation] Fixed GUI compilation failure on OpenBSD i386 ([#1284](https://github.com/stlink-org/stlink/pull/1284)) # v1.7.0 @@ -96,7 +103,7 @@ Updates & changes: - [doc] Updated documentation on target resetting ([#261](https://github.com/stlink-org/stlink/pull/261), [#533](https://github.com/stlink-org/stlink/pull/533), [#1107](https://github.com/stlink-org/stlink/pull/1107)) - [doc] Added note on `(gdb) run` command (commit [#03793d4](https://github.com/stlink-org/stlink/commit/03793d42b6078344a9ef8ad55f1d5d0fc19e486e), [#267](https://github.com/stlink-org/stlink/pull/267)) - [doc] `st-flash --reset` parameter (one solution for #356) ([#642](https://github.com/stlink-org/stlink/pull/642)) -- [refactoring] General maintenance ([#864](https://github.com/stlink-org/stlink/pull/864), [#976](https://github.com/stlink-org/stlink/pull/976), [#978](https://github.com/stlink-org/stlink/pull/978)) +- [refactoring] General maintenance ([#864](https://github.com/stlink-org/stlink/pull/864). [#978](https://github.com/stlink-org/stlink/pull/978)) - Imported debian pkg-settings ([#986](https://github.com/stlink-org/stlink/pull/986)) - Add support for FreeBSD's `libusb` reimplementation ([#992](https://github.com/stlink-org/stlink/pull/992), [#993](https://github.com/stlink-org/stlink/pull/993)) - [doc] Added explanation about STM32F103 fake chips (commit [#a66557a](https://github.com/stlink-org/stlink/commit/a66557a102d48e69feb0a9746e8e42c4baf31fe2), [#1024](https://github.com/stlink-org/stlink/pull/1024)) @@ -117,7 +124,7 @@ Fixes: - doc/man: Fixed installation directory ([#970](https://github.com/stlink-org/stlink/pull/970)) - Fixed installation path for desktop-file and icons ([#972](https://github.com/stlink-org/stlink/pull/972)) - Fix for static linking of `libssp` ([#973](https://github.com/stlink-org/stlink/pull/973), [#974](https://github.com/stlink-org/stlink/pull/974)) -- [regression] Fixed wrong formatting for library install path ([#978](https://github.com/stlink-org/stlink/pull/978), [#1089](https://github.com/stlink-org/stlink/pull/1089)) +- [regression] Fixed wrong formatting for library install path ([#978](https://github.com/stlink-org/stlink/pull/978), [#1089](https://github.com/stlink-org/stlink/pull/1089), [#1277](https://github.com/stlink-org/stlink/pull/1277)) - Fixed installation of header files needed for compiling with `libstlink.so.1.6.1` (commit [#31b1fa1](https://github.com/stlink-org/stlink/commit/31b1fa16201521e2aaf464576f2f169981abede0), [#982](https://github.com/stlink-org/stlink/pull/982)) - Fixed `connect under reset` for `st-flash` and `st-util` ([#983](https://github.com/stlink-org/stlink/pull/983)) - Fix for `mmap() size_t overflow` in `st-flash` ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) @@ -190,7 +197,7 @@ Updates & changes: - [doc] `st-flash --flash=n[k][m]` command line option to override device model ([#902](https://github.com/stlink-org/stlink/pull/902)) - [refactoring] Improved cmake build process ([#912](https://github.com/stlink-org/stlink/pull/912)) - Set up a `libusb` log level accordingly to verbosity ([#894](https://github.com/stlink-org/stlink/pull/894) - - [compatibility] Updated `libusb` to v1.0.23 ([#895](https://github.com/stlink-org/stlink/pull/895, [#1089](https://github.com/stlink-org/stlink/pull/1089)) + - [compatibility] Updated `libusb` to v1.0.23 ([#895](https://github.com/stlink-org/stlink/pull/895) - Updated compiling doc & version support ([#896](https://github.com/stlink-org/stlink/pull/896), [#897](https://github.com/stlink-org/stlink/pull/897), [#899](https://github.com/stlink-org/stlink/pull/899)) - Version requirements & pkg-maintainer - Fixed install paths in build script diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a22fdedc..f7bbe6f12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,13 +78,9 @@ include(GNUInstallDirs) # Define GNU standard installation directories cmake_host_system_information(RESULT OS_NAME QUERY OS_NAME) message(STATUS "Checking for OS_NAME: ${OS_NAME}") -if (OS_NAME STREQUAL "macOS") - message(STATUS "set(CMAKE_INSTALL_SHAREDIR /usr/local/share)") - set(CMAKE_INSTALL_SHAREDIR /usr/local/share/) -else () - message(STATUS "set(CMAKE_INSTALL_SHAREDIR /usr/share)") - set(CMAKE_INSTALL_SHAREDIR /usr/share/) -endif () +message(STATUS "set(CMAKE_INSTALL_SHAREDIR /usr/share)") +set(CMAKE_INSTALL_SHAREDIR /usr/share/) + ## Set C build flags if (NOT MSVC) diff --git a/README.md b/README.md index 571db49fd..9a36f0fbb 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ Please ensure to select the correct version for your system (i686 or x86_64). Th Alternatively one may compile and install from source as described in our [compiling manual](doc/compiling.md#Windows). -**Linux**: +**Linux / Unix**: We recommend to install `stlink-tools` from the package repository of the used distribution: @@ -78,13 +78,7 @@ We recommend to install `stlink-tools` from the package repository of the used d - Arch Linux: [(Link)](https://www.archlinux.org/packages/community/x86_64/stlink) - Alpine Linux: [(Link)](https://pkgs.alpinelinux.org/packages?name=stlink) - Fedora: [(Link)](https://src.fedoraproject.org/rpms/stlink) -- Gentoo Linux: [(Link)](https://packages.gentoo.org/packages/dev-embedded/stlink) - -**Other Operating Systems**: - -- RedHat/CentOS 8: Users can install from [EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel8) - FreeBSD: Users can install from [freshports](https://www.freshports.org/devel/stlink) -- MacOS: Users can open a terminal window and then follow the same procedure as for installing on Linux ## Installation from source (advanced users) diff --git a/doc/version_support.md b/doc/version_support.md index 0f1849697..593c86549 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -8,88 +8,94 @@ On Windows users should ensure that cmake **3.10.2** or any later version is ins Up on compiling c-make will **automatically** download and install the latest compatible version of `libusb`. - Windows 10 -- Windows 8.1 +- Windows 11 ### Linux-/Unix-based: -| Operating System | libusb | cmake | libgtk-dev | Notes | -| ------------------------- | ------------------------------ | ---------- | ----------- | ------------------------ | -| Debian Sid | 1.0.24 | 3.22.1 | 3.24.31 | | -| Debian 11 (Bullseye) | 1.0.24 | 3.18.4 | 3.24.24 | | -| Debian 10 (Buster) | 1.0.**22** | **3.13.4** | 3.24.**5** | | -| | | | | | -| Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.16.3 | 3.24.**18** | | -| Ubuntu 18.04 LTS (Bionic) | 1.0.**21** | **3.10.2** | 3.**22.30** | End of Support: Apr 2023 | -| | | | | | -| Fedora Rawhide [x64] | 1.0.24 | 3.22.3 | 3.24.31 | | -| Fedora 35 [x64] | 1.0.24 | 3.21.3 | 3.24.30 | | -| Fedora 34 [x64] | 1.0.24 (`libusbx`) | 3.19.7 | 3.24.28 | | -| | | | | | -| openSUSE Tumbleweed [x64] | 1.0.24 | 3.22.1 | 3.24.31 | | -| openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.17.0 | 3.24.20 | End of Support: Dec 2022 | -| | | | | | -| Alpine 3.15 | 1.0.24 | 3.21.3 | 3.24.30 | | -| Alpine 3.14 | 1.0.24 | 3.20.3 | 3.24.28 | | -| Alpine 3.13 | 1.0.24 | 3.18.4 | 3.24.23 | End of Support: Nov 2022 | -| Alpine 3.12 | 1.0.23 | 3.17.2 | 3.24.22 | End of Support: May 2022 | -| | | | | | -| FreeBSD 13.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | -| FreeBSD 12.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | -| | | | | | -| NetBSD 9.x | 1.0.24 | 3.21.2 | 3.24.30 | | -| NetBSD 8.x | 1.0.24 | 3.19.7 | 3.24.27 | | -| | | | | | -| CentOS 9 Stream [x64] | 1.0.24 (`libusbx`) | 3.20.3 | 3.24.30 | | -| CentOS 8 Stream [x64] | 1.0.23 (`libusbx`) | 3.20.2 | 3.**22.30** | | -| | | | | | -| ALT Linux Sisyphus | 1.0.24 | 3.22.1 | 3.24.31 | | -| ALT Linux P10 | 1.0.24 | 3.20.5 | 3.24.31 | | -| ALT Linux P9 | 1.0.**22** | 3.16.3 | 3.24.29 | | -| | | | | | -| OpenMandriva Rolling | 1.0.24 | 3.22.1 | 3.24.31 | | -| OpenMandriva Cooker | 1.0.24 | 3.22.1 | 3.24.31 | | -| OpenMandriva Lx 4.2 | 1.0.24 | 3.19.3 | 3.24.24 | | -| | | | | | -| Arch Linux | 1.0.24 | 3.22.1 | - | | -| KaOS [x64] | 1.0.24 | 3.22.1 | 3.24.31 | | -| Mageia Cauldron | 1.0.24 | 3.22.1 | 3.24.31 | | -| PCLinuxOS [x64] | ? | 3.22.1 | 3.24.31 | | -| Solus [x64] | 1.0.24 | 3.22.1 | 3.24.30 | | -| Void Linux | 1.0.24 | 3.22.1 | 3.24.31 | | -| Slackware Current | 1.0.24 | 3.21.4 | 3.24.31 | | -| AlmaLinux 8 | 1.0.23 (`libusbx`) | 3.20.2 | 3.**22.30** | | -| Rocky Linux 8 [x64] | 1.0.23 | 3.20.2 | 3.**22.30** | | -| Mageia 8 | 1.0.24 | 3.19.2 | 3.24.24 | End of Support: Aug 2022 | -| Adélie 1.0 | 1.0.23 | 3.16.4 | 3.24.23 | | +Maintained versions of: +- Debian +- Ubuntu +- Fedora +- openSUSE +- OpenMandriva +- Arch Linux +- FreeBSD +- NetBSD + +Other Linux-/Unix-based Operating Systems: + +| Operating System | libusb | cmake | libgtk-dev | Notes | +| ------------------------ | ------------------------------ | ---------- | ----------- | ------------------------ | +| Debian Sid | 1.0.24 | 3.22.1 | 3.24.31 | | +| Debian 11 (Bullseye) | 1.0.24 | 3.**18.4** | 3.24.24 | | +| Debian 10 (Buster) | 1.0.**22** | 3.**13.4** | 3.24.**5** | | +| | | | | | +| Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.**16.3** | 3.24.**18** | | +| | | | | | +| Alpine 3.15 | 1.0.24 | 3.21.3 | 3.24.30 | End of Support: Nov 2023 | +| Alpine 3.14 | 1.0.24 | 3.20.3 | 3.24.28 | End of Support: May 2023 | +| | | | | | +| FreeBSD 13.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | +| FreeBSD 12.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | +| | | | | | +| NetBSD 9.x | 1.0.24 | 3.21.2 | 3.24.30 | | +| NetBSD 8.x | 1.0.24 | 3.**19.7** | 3.24.27 | | +| | | | | | +| CentOS 9 Stream [x64] | 1.0.24 (`libusbx`) | 3.20.3 | 3.24.30 | | +| CentOS 8 Stream [x64] | 1.0.23 (`libusbx`) | 3.20.2 | 3.**22.30** | | +| | | | | | +| ALT Linux Sisyphus | 1.0.24 | 3.22.1 | 3.24.31 | | +| ALT Linux P10 | 1.0.24 | 3.20.5 | 3.24.31 | | +| ALT Linux P9 | 1.0.**22** | 3.**16.3** | 3.24.29 | | +| | | | | | +| OpenMandriva Rolling | 1.0.24 | 3.22.1 | 3.24.31 | | +| OpenMandriva Cooker | 1.0.24 | 3.22.1 | 3.24.31 | | +| OpenMandriva Lx 4.2 | 1.0.24 | 3.**19.3** | 3.24.24 | | +| | | | | | +| Arch Linux | 1.0.24 | 3.22.1 | - | | +| KaOS [x64] | 1.0.24 | 3.22.1 | 3.24.31 | | +| Mageia Cauldron | 1.0.24 | 3.22.1 | 3.24.31 | | +| PCLinuxOS [x64] | (?) | 3.22.1 | 3.24.31 | | +| Solus [x64] | 1.0.24 | 3.22.1 | 3.24.30 | | +| Void Linux | 1.0.24 | 3.22.1 | 3.24.31 | | +| Slackware Current | 1.0.24 | 3.21.4 | 3.24.31 | | +| AlmaLinux 8 | 1.0.23 (`libusbx`) | 3.20.2 | 3.**22.30** | | +| Rocky Linux 8 [x64] | 1.0.23 | 3.20.2 | 3.**22.30** | | +| Adélie 1.0 | 1.0.23 | 3.**16.4** | 3.24.23 | | ## Unsupported Operating Systems (as of Release v1.7.1) Systems with highlighted versions remain compatible with this toolset. -| Operating System | libusb | cmake | End of
      OS-Support | -| ------------------------ | ------------------------------ | ---------- | ---------------------- | -| CentOS 8 [x64] | 1.0.**23** (`libusbx`) | 3.**20.3** | Dec 2021 | -| Ubuntu 21.04 (Hirsute) | 1.0.**24** | 3.**18.4** | Jan 2022 | -| Fedora 33 [x64] | 1.0.**23** (`libusbx`) | 3.**18.3** | Nov 2021 | -| Fedora 32 [x64] | 1.0.**23** (`libusbx`) | 3.**17.0** | May 2021 | -| openSUSE Leap 15.2 [x64] | 1.0.**21** | 3.**17.0** | Dec 2021 | -| Ubuntu 20.10 (Groovy) | 1.0.**23** | 3.**16.3** | Jul 2021 | -| NetBSD 7.x | 1.0.**22** | 3.**16.1** | Jun 2020 | -| Alpine 3.11 | 1.0.**23** | 3.**15.5** | Nov 2021 | -| FreeBSD 11.x | 1.0.**16-18** (API 0x01000102) | 3.**15.5** | Sep 2021 | -| Alpine 3.10 | 1.0.**22** | 3.**14.5** | May 2021 | -| Fedora 31 [x64] | 1.0.**22**(`libusbx`) | 3.**14.5** | Nov 2020 | -| Mageia 7.1 | 1.0.**22** | 3.**14.3** | Jun 2021 | -| Fedora 30 | 1.0.**22**(`libusbx`) | 3.**14.2** | May 2020 | -| Ubuntu 19.10 (Eoan) | 1.0.**23** | 3.**13.4** | Jul 2020 | -| Alpine 3.9 | 1.0.**22** | 3.**13.0** | Jan 2021 | -| openSUSE Leap 15.1 [x64] | 1.0.**21** | 3.**10.2** | Jan 2021 | -| Debian 9 (Stretch) | 1.0.**21** | 3.7.2 | Jun 2022 | -| Slackware 14.2 | 1.0.20 | 3.5.2 | | -| OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | | -| CentOS 7 [x64] | 1.0.**21** (`libusbx`) | 2.8.12.2 | Jun 2024 | -| Slackware 14.1 | 1.0.9 | 2.8.12 | | -| Slackware 14.0 | 1.0.9 | 2.8.8 | | +| Operating System | libusb | cmake | End of
      OS-Support | +| ------------------------- | ------------------------------ | ---------- | ---------------------- | +| Fedora 35 [x64] | 1.0.**24** | 3.**21.3** | Dec 2022 | +| CentOS 8 [x64] | 1.0.**23** (`libusbx`) | 3.**20.3** | Dec 2021 | +| Fedora 34 [x64] | 1.0.**24** (`libusbx`) | 3.**19.7** | Jun 2022 | +| Mageia 8 | 1.0.**24** | 3.**19.2** | Aug 2022 | +| Alpine 3.13 | 1.0.**24** | 3.**18.4** | Nov 2022 | +| Ubuntu 21.04 (Hirsute) | 1.0.**24** | 3.**18.4** | Jan 2022 | +| Fedora 33 [x64] | 1.0.**23** (`libusbx`) | 3.**18.3** | Nov 2021 | +| Alpine 3.12 | 1.0.**23** | 3.**17.2** | May 2022 | +| openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.**17.0** | Dec 2022 | +| Fedora 32 [x64] | 1.0.**23** (`libusbx`) | 3.**17.0** | May 2021 | +| openSUSE Leap 15.2 [x64] | 1.0.**21** | 3.**17.0** | Dec 2021 | +| Ubuntu 20.10 (Groovy) | 1.0.**23** | 3.**16.3** | Jul 2021 | +| NetBSD 7.x | 1.0.**22** | 3.**16.1** | Jun 2020 | +| Alpine 3.11 | 1.0.**23** | 3.**15.5** | Nov 2021 | +| FreeBSD 11.x | 1.0.**16-18** (API 0x01000102) | 3.**15.5** | Sep 2021 | +| Alpine 3.10 | 1.0.**22** | 3.**14.5** | May 2021 | +| Fedora 31 [x64] | 1.0.**22**(`libusbx`) | 3.**14.5** | Nov 2020 | +| Mageia 7.1 | 1.0.**22** | 3.**14.3** | Jun 2021 | +| Fedora 30 | 1.0.**22**(`libusbx`) | 3.**14.2** | May 2020 | +| Ubuntu 19.10 (Eoan) | 1.0.**23** | 3.**13.4** | Jul 2020 | +| Alpine 3.9 | 1.0.**22** | 3.**13.0** | Jan 2021 | +| Ubuntu 18.04 LTS (Bionic) | 1.0.**21** | 3.**10.2** | **Apr 2023** | +| openSUSE Leap 15.1 [x64] | 1.0.**21** | 3.**10.2** | Jan 2021 | +| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | Jun 2022 | +| Slackware 14.2 | 1.0.20 | 3.5.2 | | +| OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | | +| CentOS 7 [x64] | 1.0.21 (`libusbx`) | 2.8.12.2 | Jun 2024 | _All other operating systems which are not listed are unsupported._ diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 0985c75c2..4b8e37fef 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -71,6 +71,7 @@ int main(int ac, char** av) { if (sl->flash_type == STM32_FLASH_TYPE_UNKNOWN) { printf("Failed to connect to target\n"); + fprintf(stderr, "Failed to parse flash type or unrecognized flash type\n"); goto on_error; } @@ -98,8 +99,10 @@ int main(int ac, char** av) { goto on_error; } - if (o.cmd == FLASH_CMD_WRITE) { // write + if (o.cmd == FLASH_CMD_WRITE) { size_t size = 0; + + // write if (o.format == FLASH_FORMAT_IHEX) { err = stlink_parse_ihex(o.filename, stlink_get_erased_pattern(sl), &mem, &size, &o.addr); @@ -108,8 +111,7 @@ int main(int ac, char** av) { goto on_error; } } - if ((o.addr >= sl->flash_base) && - (o.addr < sl->flash_base + sl->flash_size)) { + if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { if (o.format == FLASH_FORMAT_IHEX) { err = stlink_mwrite_flash(sl, mem, (uint32_t)size, o.addr); } else { @@ -120,8 +122,7 @@ int main(int ac, char** av) { printf("stlink_fwrite_flash() == -1\n"); goto on_error; } - } else if ((o.addr >= sl->sram_base) && - (o.addr < sl->sram_base + sl->sram_size)) { + } else if ((o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { if (o.format == FLASH_FORMAT_IHEX) { err = stlink_mwrite_sram(sl, mem, (uint32_t)size, o.addr); } else { @@ -132,8 +133,7 @@ int main(int ac, char** av) { printf("stlink_fwrite_sram() == -1\n"); goto on_error; } - } else if ((o.addr >= sl->option_base) && - (o.addr < sl->option_base + sl->option_size)) { + } else if ((o.addr >= sl->option_base) && (o.addr < sl->option_base + sl->option_size)) { err = stlink_fwrite_option_bytes(sl, o.filename, o.addr); if (err == -1) { @@ -170,11 +170,11 @@ int main(int ac, char** av) { goto on_error; } } else if (o.cmd == FLASH_CMD_ERASE) { - if (o.size > 0 && o.addr > 0) + if (o.size > 0 && o.addr > 0) { err = stlink_erase_flash_section(sl, o.addr, o.size, false); - else + } else { err = stlink_erase_flash_mass(sl); - + } if (err == -1) { printf("stlink_erase_flash_mass() == -1\n"); goto on_error; @@ -184,7 +184,9 @@ int main(int ac, char** av) { printf("Failed to reset device\n"); goto on_error; } - } else { // read + } else { + + // read if ((o.area == FLASH_MAIN_MEMORY) || (o.area == FLASH_SYSTEM_MEMORY)) { if ((o.size == 0) && (o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { o.size = sl->flash_size; diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 9fcf8e358..83bfeac8c 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -171,8 +171,7 @@ bool parse_options(int argc, char **argv, st_settings_t *settings) { settings->serial_number = NULL; ugly_init(settings->logging_level); - while ((c = getopt_long(argc, argv, "hVv::c:ns:f", long_options, - &option_index)) != -1) { + while ((c = getopt_long(argc, argv, "hVv::c:ns:f", long_options, &option_index)) != -1) { switch (c) { case 'h': settings->show_help = true; diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index e36c150a6..7ff6c77a9 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -67,20 +67,22 @@ void process_chipfile(char *fname) { sscanf(buf, "%s %s", word, value); if (strcmp (word, "dev_type") == 0) { - // ts->dev_type = strdup (value); buf[strlen(buf) - 1] = 0; // chomp newline sscanf(buf, "%*s %n", &nc); ts->dev_type = strdup(buf + nc); } else if (strcmp(word, "ref_manual_id") == 0) { - // ts->ref_manual_id = strdup (value); buf[strlen(buf) - 1] = 0; // chomp newline sscanf(buf, "%*s %n", &nc); ts->ref_manual_id = strdup(buf + nc); } else if (strcmp(word, "chip_id") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); if (sscanf(value, "%i", &ts->chip_id) < 1) { fprintf(stderr, "Failed to parse chip-id\n"); } } else if (strcmp(word, "flash_type") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); if (strcmp(value, "F0_F1_F3") == 0) { ts->flash_type = STM32_FLASH_TYPE_F0_F1_F3; } else if (strcmp(value, "F1_XL") == 0) { @@ -105,37 +107,52 @@ void process_chipfile(char *fname) { ts->flash_type = STM32_FLASH_TYPE_WB_WL; } else { ts->flash_type = STM32_FLASH_TYPE_UNKNOWN; - fprintf(stderr, "Failed to parse flash type or unrecognized flash type\n"); } } else if (strcmp(word, "flash_size_reg") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); if (sscanf(value, "%i", &ts->flash_size_reg) < 1) { fprintf(stderr, "Failed to parse flash size reg\n"); } } else if (strcmp(word, "flash_pagesize") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); if (sscanf(value, "%i", &ts->flash_pagesize) < 1) { fprintf(stderr, "Failed to parse flash page size\n"); } } else if (strcmp(word, "sram_size") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); if (sscanf(value, "%i", &ts->sram_size) < 1) { fprintf(stderr, "Failed to parse SRAM size\n"); } } else if (strcmp(word, "bootrom_base") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); if (sscanf(value, "%i", &ts->bootrom_base) < 1) { fprintf(stderr, "Failed to parse BootROM base\n"); } } else if (strcmp(word, "bootrom_size") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); if (sscanf(value, "%i", &ts->bootrom_size) < 1) { fprintf(stderr, "Failed to parse BootROM size\n"); } } else if (strcmp(word, "option_base") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); if (sscanf(value, "%i", &ts->option_base) < 1) { fprintf(stderr, "Failed to parse option base\n"); } } else if (strcmp(word, "option_size") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); if (sscanf(value, "%i", &ts->option_size) < 1) { fprintf(stderr, "Failed to parse option size\n"); } } else if (strcmp(word, "flags") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); p = strtok (buf, " \t\n"); while ((p = strtok (NULL, " \t\n"))) { @@ -153,8 +170,7 @@ void process_chipfile(char *fname) { sscanf(value, "%x", &ts->flags); } else { - fprintf(stderr, "Unknown keyword in %s: %s\n", - fname, word); + fprintf(stderr, "Unknown keyword in %s: %s\n", fname, word); } } fclose(fp); @@ -164,6 +180,7 @@ void process_chipfile(char *fname) { #if defined(STLINK_HAVE_DIRENT_H) #include + void init_chipids(char *dir_to_scan) { DIR *d; size_t nl; // namelen @@ -198,6 +215,7 @@ void init_chipids(char *dir_to_scan) { #if defined(_WIN32) && !defined(STLINK_HAVE_DIRENT_H) #include #include + void init_chipids(char *dir_to_scan) { HANDLE hFind = INVALID_HANDLE_VALUE; WIN32_FIND_DATAA ffd; diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index d360b5d03..041b55f64 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -414,7 +414,7 @@ int stlink_status(stlink_t *sl) { } // 257 int stlink_version(stlink_t *sl) { - DLOG("*** looking up stlink version\n"); + DLOG("*** looking up stlink version ***\n"); if (sl->backend->version(sl)) { return (-1); From dfff59d39f8a3c7cc68e3281b72d237baa109751 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 31 Dec 2022 14:49:39 +0100 Subject: [PATCH 1342/1435] Added support for STM32L4Q5 (Closes #1224) --- config/chips/L41x_L42x.chip | 2 +- config/chips/L43x_L44x.chip | 2 +- config/chips/L45x_L46x.chip | 2 +- config/chips/L47x_L48x.chip | 2 +- config/chips/L496x_L4A6x.chip | 2 +- config/chips/{L4Px.chip => L4Px_L4Qx.chip} | 10 +++---- config/chips/L4Rx.chip | 2 +- config/chips/L5x5.chip.txt | 15 ---------- inc/stm32.h | 2 +- src/stlink-lib/chipid.c | 2 +- src/stlink-lib/common.c | 2 +- src/stlink-lib/common_flash.c | 32 +++++++++++----------- src/stlink-lib/flashloader.c | 12 ++++---- src/stlink-lib/option_bytes.c | 2 +- 14 files changed, 37 insertions(+), 52 deletions(-) rename config/chips/{L4Px.chip => L4Px_L4Qx.chip} (62%) delete mode 100644 config/chips/L5x5.chip.txt diff --git a/config/chips/L41x_L42x.chip b/config/chips/L41x_L42x.chip index 11e545bb7..18730b4a2 100644 --- a/config/chips/L41x_L42x.chip +++ b/config/chips/L41x_L42x.chip @@ -3,7 +3,7 @@ dev_type STM32L41x_L42x ref_manual_id 0394 chip_id 0x464 // STM32_CHIPID_L41x_L42x -flash_type L4_L4P +flash_type L4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0xa000 // 40 KB diff --git a/config/chips/L43x_L44x.chip b/config/chips/L43x_L44x.chip index f0a959693..1e4b593ed 100644 --- a/config/chips/L43x_L44x.chip +++ b/config/chips/L43x_L44x.chip @@ -3,7 +3,7 @@ dev_type STM32L41x_L42x ref_manual_id 0392 chip_id 0x435 // STM32_CHIPID_L43x_L44x -flash_type L4_L4P +flash_type L4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0xc000 // 48 KB diff --git a/config/chips/L45x_L46x.chip b/config/chips/L45x_L46x.chip index 267122f87..cbe948c1f 100644 --- a/config/chips/L45x_L46x.chip +++ b/config/chips/L45x_L46x.chip @@ -3,7 +3,7 @@ dev_type STM32L45x_L46x ref_manual_id 0394 chip_id 0x462 // STM32_CHIPID_L45x_L46x -flash_type L4_L4P +flash_type L4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x20000 // 128 KB diff --git a/config/chips/L47x_L48x.chip b/config/chips/L47x_L48x.chip index 421663e58..5475ee77b 100644 --- a/config/chips/L47x_L48x.chip +++ b/config/chips/L47x_L48x.chip @@ -3,7 +3,7 @@ dev_type STM32L47x_L48x ref_manual_id 0351 chip_id 0x415 // STM32_CHIPID_L4 -flash_type L4_L4P +flash_type L4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x18000 // 96 KB diff --git a/config/chips/L496x_L4A6x.chip b/config/chips/L496x_L4A6x.chip index 6657d5484..24788c092 100644 --- a/config/chips/L496x_L4A6x.chip +++ b/config/chips/L496x_L4A6x.chip @@ -3,7 +3,7 @@ dev_type STM32L496x_L4A6x ref_manual_id 0351 chip_id 0x461 // STM32_CHIPID_L496x_L4A6x -flash_type L4_L4P +flash_type L4 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB sram_size 0x50000 // 320 KB diff --git a/config/chips/L4Px.chip b/config/chips/L4Px_L4Qx.chip similarity index 62% rename from config/chips/L4Px.chip rename to config/chips/L4Px_L4Qx.chip index 39788eabe..881fd8188 100644 --- a/config/chips/L4Px.chip +++ b/config/chips/L4Px_L4Qx.chip @@ -1,14 +1,14 @@ -# Chip-ID file for STM32L4Px device +# Chip-ID file for STM32L4Px / STM32L4Qx device # -dev_type STM32L4Px +dev_type STM32L4Px_L4Qx ref_manual_id 0432 chip_id 0x471 // STM32_CHIPID_L4PX -flash_type L4_L4P +flash_type L4 flash_size_reg 0x1fff75e0 flash_pagesize 0x1000 // 4 KB sram_size 0xa0000 // 640 KB bootrom_base 0x1fff0000 bootrom_size 0x7000 // 28 KB -option_base 0x0 -option_size 0x0 +option_base 0x1ff00000 +option_size 0x4 // 4 B flags swo diff --git a/config/chips/L4Rx.chip b/config/chips/L4Rx.chip index 428a0c21e..80cd02d55 100644 --- a/config/chips/L4Rx.chip +++ b/config/chips/L4Rx.chip @@ -3,7 +3,7 @@ dev_type STM32L4Rx ref_manual_id 0432 chip_id 0x470 // STM32_CHIPID_L4RX -flash_type L4_L4P +flash_type L4 flash_size_reg 0x1fff75e0 flash_pagesize 0x1000 // 4 KB sram_size 0xa0000 // 640 KB diff --git a/config/chips/L5x5.chip.txt b/config/chips/L5x5.chip.txt deleted file mode 100644 index ce268148b..000000000 --- a/config/chips/L5x5.chip.txt +++ /dev/null @@ -1,15 +0,0 @@ -# Chip-ID file for STM32L5x2 device -# -dev_type STM32L5x2 -ref_manual_id 0438 -chip_id 0x0 // (temporary setting only!) -flash_type 0 // (temporary setting only!) -flash_size_reg 0x0bfa07a0 -flash_pagesize 0x2000 // 8 KB -sram_size 0x40000 // 256 KB -bootrom_base 0x0bf90000 -bootrom_size 0x8000 // 32 KB -option_base 0x0 -option_size 0x0 -flags none - diff --git a/inc/stm32.h b/inc/stm32.h index 2d533eca2..856d6e4bd 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -51,7 +51,7 @@ enum stm32_flash_type { STM32_FLASH_TYPE_G4 = 6, STM32_FLASH_TYPE_H7 = 7, STM32_FLASH_TYPE_L0_L1 = 8, - STM32_FLASH_TYPE_L4_L4P = 9, + STM32_FLASH_TYPE_L4 = 9, STM32_FLASH_TYPE_L5_U5 = 10, STM32_FLASH_TYPE_WB_WL = 11, }; diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 7ff6c77a9..51a1200ad 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -100,7 +100,7 @@ void process_chipfile(char *fname) { } else if (strcmp(value, "L0_L1") == 0) { ts->flash_type = STM32_FLASH_TYPE_L0_L1; } else if (strcmp(value, "L4_L4P") == 0) { - ts->flash_type = STM32_FLASH_TYPE_L4_L4P; + ts->flash_type = STM32_FLASH_TYPE_L4; } else if (strcmp(value, "L5_U5") == 0) { ts->flash_type = STM32_FLASH_TYPE_L5_U5; } else if (strcmp(value, "WB_WL") == 0) { diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index 041b55f64..34a8ac573 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -984,7 +984,7 @@ static void stop_wdg_in_debug(stlink_t *sl) { break; case STM32_FLASH_TYPE_F2_F4: case STM32_FLASH_TYPE_F7: - case STM32_FLASH_TYPE_L4_L4P: + case STM32_FLASH_TYPE_L4: dbgmcu_cr = STM32F4_DBGMCU_APB1FZR1; set = (1 << STM32F4_DBGMCU_APB1FZR1_IWDG_STOP) | (1 << STM32F4_DBGMCU_APB1FZR1_WWDG_STOP); diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index b21929ddf..0ed4734ad 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -38,7 +38,7 @@ uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { reg = FLASH_F4_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { reg = FLASH_F7_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { reg = STM32L4_FLASH_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { @@ -79,7 +79,7 @@ void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = STM32L0_FLASH_PELOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || @@ -124,7 +124,7 @@ static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { sr_reg = FLASH_F4_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { sr_reg = STM32L4_FLASH_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { @@ -163,7 +163,7 @@ void clear_flash_error(stlink_t *sl) { write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); } break; - case STM32_FLASH_TYPE_L4_L4P: + case STM32_FLASH_TYPE_L4: write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); break; case STM32_FLASH_TYPE_H7: @@ -192,7 +192,7 @@ uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { sr_reg = FLASH_F4_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { sr_reg = STM32L4_FLASH_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { @@ -222,7 +222,7 @@ unsigned int is_flash_busy(stlink_t *sl) { sr_busy_shift = FLASH_F4_SR_BSY; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { sr_busy_shift = FLASH_F7_SR_BSY; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { sr_busy_shift = STM32L4_FLASH_SR_BSY; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { @@ -297,7 +297,7 @@ int check_flash_error(stlink_t *sl) { WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); break; - case STM32_FLASH_TYPE_L4_L4P: + case STM32_FLASH_TYPE_L4: res = read_flash_sr(sl, BANK_1) & STM32L4_FLASH_SR_ERROR_MASK; WRPERR = (1 << STM32L4_FLASH_SR_WRPERR); PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); @@ -360,7 +360,7 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = STM32L0_FLASH_PELOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || @@ -404,7 +404,7 @@ static void unlock_flash(stlink_t *sl) { key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; flash_key1 = FLASH_L0_PEKEY1; flash_key2 = FLASH_L0_PEKEY2; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { key_reg = STM32L4_FLASH_KEYR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { @@ -468,7 +468,7 @@ int lock_flash_option(stlink_t *sl) { optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; optlock_shift = STM32L0_FLASH_OPTLOCK; break; - case STM32_FLASH_TYPE_L4_L4P: + case STM32_FLASH_TYPE_L4: optcr_reg = STM32L4_FLASH_CR; optlock_shift = STM32L4_FLASH_CR_OPTLOCK; break; @@ -541,7 +541,7 @@ static bool is_flash_option_locked(stlink_t *sl) { optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; optlock_shift = STM32L0_FLASH_OPTLOCK; break; - case STM32_FLASH_TYPE_L4_L4P: + case STM32_FLASH_TYPE_L4: optcr_reg = STM32L4_FLASH_CR; optlock_shift = STM32L4_FLASH_CR_OPTLOCK; break; @@ -595,7 +595,7 @@ static int unlock_flash_option(stlink_t *sl) { optkey1 = FLASH_L0_OPTKEY1; optkey2 = FLASH_L0_OPTKEY2; break; - case STM32_FLASH_TYPE_L4_L4P: + case STM32_FLASH_TYPE_L4: optkey_reg = STM32L4_FLASH_OPTKEYR; break; case STM32_FLASH_TYPE_G0: @@ -672,7 +672,7 @@ void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { cr_reg = FLASH_F4_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { @@ -796,7 +796,7 @@ static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; cr_strt = 1 << FLASH_F7_CR_STRT; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_strt = (1 << STM32L4_FLASH_CR_STRT); } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || @@ -830,7 +830,7 @@ static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { cr_reg = FLASH_F7_CR; cr_mer = 1 << FLASH_CR_MER; cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); cr_pg = (1 << STM32L4_FLASH_CR_PG); @@ -890,7 +890,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if (sl->flash_type == STM32_FLASH_TYPE_F2_F4 || sl->flash_type == STM32_FLASH_TYPE_F7 || - sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + sl->flash_type == STM32_FLASH_TYPE_L4) { // unlock if locked unlock_flash_if(sl); diff --git a/src/stlink-lib/flashloader.c b/src/stlink-lib/flashloader.c index abb140fdd..d9542ebbc 100644 --- a/src/stlink-lib/flashloader.c +++ b/src/stlink-lib/flashloader.c @@ -80,7 +80,7 @@ static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; x &= ~STM32L4_FLASH_CR_OPBITS; x |= (1 << STM32L4_FLASH_CR_PG); @@ -123,7 +123,7 @@ static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { rcc_dma_mask = STM32G0_RCC_DMAEN; break; case STM32_FLASH_TYPE_G4: - case STM32_FLASH_TYPE_L4_L4P: + case STM32_FLASH_TYPE_L4: rcc = STM32G4_RCC_AHB1ENR; rcc_dma_mask = STM32G4_RCC_DMAEN; break; @@ -170,7 +170,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || (sl->flash_type == STM32_FLASH_TYPE_F7) || - (sl->flash_type == STM32_FLASH_TYPE_L4_L4P)) { + (sl->flash_type == STM32_FLASH_TYPE_L4)) { ILOG("Starting Flash write for F2/F4/F7/L4\n"); // Flash loader initialisation @@ -194,7 +194,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { return (-1); } - if (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) { + if (sl->flash_type == STM32_FLASH_TYPE_L4) { // L4 does not have a byte-write mode if (voltage < 1710) { ELOG("Target voltage (%d mV) too low for flash writes!\n", voltage); @@ -304,7 +304,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, size_t off; if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || (sl->flash_type == STM32_FLASH_TYPE_F7) || - (sl->flash_type == STM32_FLASH_TYPE_L4_L4P)) { + (sl->flash_type == STM32_FLASH_TYPE_L4)) { size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; for (off = 0; off < len;) { size_t size = len - off > buf_size ? buf_size : len - off; @@ -451,7 +451,7 @@ int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || (sl->flash_type == STM32_FLASH_TYPE_F2_F4) || (sl->flash_type == STM32_FLASH_TYPE_F7) || - (sl->flash_type == STM32_FLASH_TYPE_L4_L4P) || + (sl->flash_type == STM32_FLASH_TYPE_L4) || (sl->flash_type == STM32_FLASH_TYPE_WB_WL) || (sl->flash_type == STM32_FLASH_TYPE_G0) || (sl->flash_type == STM32_FLASH_TYPE_G4) || diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c index 44cd3930b..3d332f49d 100644 --- a/src/stlink-lib/option_bytes.c +++ b/src/stlink-lib/option_bytes.c @@ -795,7 +795,7 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, ui case STM32_FLASH_TYPE_L0_L1: ret = stlink_write_option_bytes_l0(sl, addr, base, len); break; - case STM32_FLASH_TYPE_L4_L4P: + case STM32_FLASH_TYPE_L4: ret = stlink_write_option_bytes_l4(sl, addr, base, len); break; case STM32_FLASH_TYPE_G0: From f025d756b7781cfb15c0aab15e47deddf5c17f7d Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 1 Jan 2023 13:20:02 +0100 Subject: [PATCH 1343/1435] Minor corrections regarding os support --- .github/ISSUE_TEMPLATE/feature-request.md | 2 +- CMakeLists.txt | 2 +- doc/compiling.md | 2 +- src/stlink-lib/libusb_settings.h | 3 +-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index d57dbefed..b16cbf92b 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -20,7 +20,7 @@ labels: code/feature-request In order to allow developers to isolate and target your respective issue, please take some time to select the check boxes below and fill out each of the following items appropriate to your specific request. - [ ] Programmer/board type: [enter here] (e.g STLINK /V1, /V2, /V2-onboard, /V2-clone, /V3) -- [ ] Operating system an version: [enter here] (e.g Linux, macOS, Windows) +- [ ] Operating system an version: [enter here] (e.g Linux, Windows) - [ ] **stlink tools version** and/or git commit hash: [enter here] (e.g v1.6.1/git-d0416149) - [ ] stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-trace`, `st-util`) - [ ] Target chip (and board, if applicable): [enter here] (e.g STM32F103C8T6 (NUCLEO-F103RB)) diff --git a/CMakeLists.txt b/CMakeLists.txt index f7bbe6f12..b25291992 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,7 @@ include(${CMAKE_MODULE_PATH}/get_version.cmake) # Determine project version include(GNUInstallDirs) # Define GNU standard installation directories -# Define install directory /usr/local/share [not /usr/share on MacOS] +# Define install directory /usr/local/share cmake_host_system_information(RESULT OS_NAME QUERY OS_NAME) message(STATUS "Checking for OS_NAME: ${OS_NAME}") diff --git a/doc/compiling.md b/doc/compiling.md index 5f6852a93..eec46bb3d 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -1,6 +1,6 @@ # Compiling from sources -## Microsoft Windows (10, 8.1) +## Microsoft Windows (10, 11) ### Common Requirements diff --git a/src/stlink-lib/libusb_settings.h b/src/stlink-lib/libusb_settings.h index 2a595238a..ee690e0b1 100644 --- a/src/stlink-lib/libusb_settings.h +++ b/src/stlink-lib/libusb_settings.h @@ -19,6 +19,7 @@ * v1.0.23 | 0x01000107 * v1.0.24 | 0x01000108 * v1.0.25 | 0x01000109 + * v1.0.26 | 0x01000110 */ #if defined (__FreeBSD__) @@ -35,8 +36,6 @@ #define MINIMAL_API_VERSION 0x01000105 // v1.0.21 #elif defined (__linux__) #define MINIMAL_API_VERSION 0x01000105 // v1.0.21 -#elif defined (__APPLE__) - #define MINIMAL_API_VERSION 0x01000109 // v1.0.25 #elif defined (_WIN32) #define MINIMAL_API_VERSION 0x01000109 // v1.0.25 #endif From b60a03540402bb71a318c6303ad4199ef5c25983 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 1 Jan 2023 13:32:14 +0100 Subject: [PATCH 1344/1435] Initial support for STM32 L5 & U5 devices (References: #1005 #1096 #1247) --- config/chips/L5x5.chip | 14 + config/chips/{U5x5.chip.txt => U5x5.chip} | 9 +- inc/stm32.h | 8 + inc/stm32flash.h | 39 ++- src/st-flash/flash.c | 1 + src/stlink-lib/common.c | 198 +++++++------- src/stlink-lib/common_flash.c | 300 ++++++++++++++-------- src/stlink-lib/flashloader.c | 29 ++- src/stlink-lib/option_bytes.c | 33 +-- 9 files changed, 392 insertions(+), 239 deletions(-) create mode 100644 config/chips/L5x5.chip rename config/chips/{U5x5.chip.txt => U5x5.chip} (52%) diff --git a/config/chips/L5x5.chip b/config/chips/L5x5.chip new file mode 100644 index 000000000..0f205a62b --- /dev/null +++ b/config/chips/L5x5.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32L5x2xx device +# +dev_type STM32L5x2xx +ref_manual_id 0438 +chip_id 0x472 // STM32_CHIPID_L5x2xx +flash_type L5_U5 +flash_size_reg 0x0bfa05e0 +flash_pagesize 0x1000 // 4 KB +sram_size 0x40000 // 256 KB +bootrom_base 0x0bf90000 +bootrom_size 0x8000 // 32 KB +option_base 0x0 +option_size 0x0 +flags dualbank diff --git a/config/chips/U5x5.chip.txt b/config/chips/U5x5.chip similarity index 52% rename from config/chips/U5x5.chip.txt rename to config/chips/U5x5.chip index 177359cc3..be19d04af 100644 --- a/config/chips/U5x5.chip.txt +++ b/config/chips/U5x5.chip @@ -2,14 +2,13 @@ # dev_type STM32U5x5 ref_manual_id 0456 -chip_id 0x0 // (temporary setting only!) -flash_type 0 // (temporary setting only!) +chip_id 0x482 // STM32_CHIPID_U5x5 +flash_type L5_U5 flash_size_reg 0x0bfa07a0 -flash_pagesize 0x2000 // 8 KB +flash_pagesize 0x200000 // 2048 KB sram_size 0xc4800 // 786 KB bootrom_base 0x0bf90000 -bootrom_size 0x8000 // 32 KB +bootrom_size 0x10000 // 64 KB option_base 0x0 option_size 0x0 flags none - diff --git a/inc/stm32.h b/inc/stm32.h index 856d6e4bd..8557c9ce7 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -117,8 +117,10 @@ enum stm32_chipids { STM32_CHIPID_G4_CAT3 = 0x469, STM32_CHIPID_L4Rx = 0x470, /* RM0432, p.2247, found on the STM32L4R9I-DISCO board */ STM32_CHIPID_L4PX = 0x471, /* RM0432, p.2247 */ + STM32_CHIPID_L5x2xx = 0x472, /* RM0438, p.2157 */ STM32_CHIPID_G4_CAT4 = 0x479, STM32_CHIPID_H7Ax = 0x480, /* RM0455, p.2863 */ + STM32_CHIPID_U5x5 = 0x482, /* RM0456, p.2991 */ STM32_CHIPID_H72x = 0x483, /* RM0468, p.3199 */ STM32_CHIPID_WB55 = 0x495, STM32_CHIPID_WLE = 0x497, @@ -196,10 +198,16 @@ enum stm32_chipids { #define STM32L1_RCC_AHBENR 0x4002381C #define STM32L1_RCC_DMAEN 0x30000000 // DMA2EN | DMA1EN +#define STM32L5_RCC_AHB1ENR 0x40021048 // RM0438, p. 91,377 +#define STM32L5_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN // RM0438, p. 378 + #define STM32H7_RCC_AHB1ENR 0x58024538 #define STM32H7_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN #define STM32WB_RCC_AHB1ENR 0x58000048 #define STM32WB_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN +#define STM32L5_PWR_CR1 0x40007000 // RM0438, p. 93,324 +#define STM32L5_PWR_CR1_VOS 8 + #endif // STM32_H diff --git a/inc/stm32flash.h b/inc/stm32flash.h index 5e7ad2e4a..07f824837 100644 --- a/inc/stm32flash.h +++ b/inc/stm32flash.h @@ -72,7 +72,7 @@ #define FLASH_L1_FPRG 10 #define FLASH_L1_PROG 3 -// Flash registers common to STM32G0 and STM32G4 series. +// Flash registers common to STM32G0 and STM32G4 series (RM0440, p. 146) #define STM32Gx_FLASH_REGS_ADDR ((uint32_t)0x40022000) #define STM32Gx_FLASH_ACR (STM32Gx_FLASH_REGS_ADDR + 0x00) #define STM32Gx_FLASH_KEYR (STM32Gx_FLASH_REGS_ADDR + 0x08) @@ -207,6 +207,43 @@ #define STM32L4_FLASH_OPTR_DUALBANK 21 +// Flash registers common to STM32L5 series (RM0438, p. 241) +#define STM32L5_FLASH_REGS_ADDR ((uint32_t)0x40022000) +#define STM32L5_FLASH_ACR (STM32L5_FLASH_REGS_ADDR + 0x00) +#define STM32L5_FLASH_NSKEYR (STM32L5_FLASH_REGS_ADDR + 0x08) +#define STM32L5_FLASH_OPTKEYR (STM32L5_FLASH_REGS_ADDR + 0x10) +#define STM32L5_FLASH_NSSR (STM32L5_FLASH_REGS_ADDR + 0x20) +#define STM32L5_FLASH_NSCR (STM32L5_FLASH_REGS_ADDR + 0x28) +#define STM32L5_FLASH_ECCR (STM32L5_FLASH_REGS_ADDR + 0x30) +#define STM32L5_FLASH_OPTR (STM32L5_FLASH_REGS_ADDR + 0x40) + +// FLASH_NSCR (RM0438, p. 242) +#define STM32L5_FLASH_NSCR_NSPG 0 /* Program */ +#define STM32L5_FLASH_NSCR_NSPER 1 /* Page erase */ +#define STM32L5_FLASH_NSCR_NSMER1 2 /* Bank 1 erase */ +#define STM32L5_FLASH_NSCR_NSPNB 3 /* Page number (7 bits) */ +#define STM32L5_FLASH_NSCR_NSBKER 11 /* Bank select for page erase */ +#define STM32L5_FLASH_NSCR_NSMER2 15 /* Bank 2 erase */ +#define STM32L5_FLASH_NSCR_NSSTRT 16 /* Start command */ +#define STM32L5_FLASH_NSCR_NSOPTSTRT 17 /* Start writing option bytes */ +#define STM32L5_FLASH_NSCR_NSEOPIE 24 +#define STM32L5_FLASH_NSCR_NSERRIE 25 +#define STM32L5_FLASH_NSCR_OBL_LAUNCH 27 /* Option bytes reload */ +#define STM32L5_FLASH_NSCR_OPTLOCK 30 /* Lock option bytes */ +#define STM32L5_FLASH_NSCR_NSLOCK 31 /* Lock control register */ + +// FLASH_NSSR (RM0438, p. 241) +#define STM32L5_FLASH_NSSR_NSEOP 0 /* End of Operation */ +#define STM32L5_FLASH_NSSR_NSOPERR 1 +#define STM32L5_FLASH_NSSR_NSPROGERR 3 +#define STM32L5_FLASH_NSSR_NSWRPERR 4 +#define STM32L5_FLASH_NSSR_NSPGAERR 5 +#define STM32L5_FLASH_NSSR_NSSIZERR 6 +#define STM32L5_FLASH_NSSR_NSPGSERR 7 +#define STM32L5_FLASH_NSSR_OPTWERR 12 +#define STM32L5_FLASH_NSSR_BSY 16 /* Busy */ +#define STM32L5_FLASH_NSSR_ERROR_MASK (0x20fa) + // STM32L0x flash register base and offsets RM0090 - DM00031020.pdf #define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 4b8e37fef..cef0b639f 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -254,6 +254,7 @@ int main(int ac, char** av) { if (o.reset) { stlink_reset(sl, RESET_AUTO); + stlink_run(sl, RUN_NORMAL); } err = 0; // success diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index 34a8ac573..fe5574706 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -62,6 +62,7 @@ void stlink_close(stlink_t *sl) { sl->backend->close(sl); free(sl); } + // 250 int stlink_exit_debug_mode(stlink_t *sl) { DLOG("*** stlink_exit_debug_mode ***\n"); @@ -74,11 +75,13 @@ int stlink_exit_debug_mode(stlink_t *sl) { return (sl->backend->exit_debug_mode(sl)); } + //248 int stlink_enter_swd_mode(stlink_t *sl) { DLOG("*** stlink_enter_swd_mode ***\n"); return (sl->backend->enter_swd_mode(sl)); } + // 271 // Force the core into the debug mode -> halted state. int stlink_force_debug(stlink_t *sl) { @@ -91,11 +94,13 @@ int stlink_force_debug(stlink_t *sl) { stop_wdg_in_debug(sl); return (0); } + // 251 int stlink_exit_dfu_mode(stlink_t *sl) { DLOG("*** stlink_exit_dfu_mode ***\n"); return (sl->backend->exit_dfu_mode(sl)); } + // 253 int stlink_core_id(stlink_t *sl) { int ret; @@ -115,6 +120,7 @@ int stlink_core_id(stlink_t *sl) { DLOG("core_id = 0x%08x\n", sl->core_id); return (ret); } + // 287 // stlink_chip_id() is called by stlink_load_device_params() // do not call this procedure directly. @@ -132,7 +138,6 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { /* * the chip_id register in the reference manual have * DBGMCU_IDCODE / DBG_IDCODE name - * */ if ((sl->core_id == STM32_CORE_ID_M7F_H7_SWD || sl->core_id == STM32_CORE_ID_M7F_H7_JTAG) && @@ -178,6 +183,7 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { return (ret); } + // 288 /** * Cortex M tech ref manual, CPUID register description @@ -201,6 +207,7 @@ int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { cpuid->revision = raw & 0xf; return (0); } + // 303 /** * Reads and decodes the flash parameters, as dynamically as possible @@ -300,6 +307,7 @@ int stlink_load_device_params(stlink_t *sl) { return (0); } + // 254 int stlink_reset(stlink_t *sl, enum reset_type type) { uint32_t dhcsr; @@ -361,6 +369,81 @@ int stlink_reset(stlink_t *sl, enum reset_type type) { return (0); } + +int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { + int ret; + unsigned timeout; + uint32_t dhcsr, dfsr; + + DLOG("*** stlink_soft_reset %s***\n", halt_on_reset ? "(halt) " : ""); + + // halt core and enable debugging (if not already done) + // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_DEBUGEN); + + // enable Halt on reset by set VC_CORERESET and TRCENA (DDI0337E, p. 10-10) + if (halt_on_reset) { + stlink_write_debug32( + sl, STLINK_REG_CM3_DEMCR, + STLINK_REG_CM3_DEMCR_TRCENA | STLINK_REG_CM3_DEMCR_VC_HARDERR | + STLINK_REG_CM3_DEMCR_VC_BUSERR | STLINK_REG_CM3_DEMCR_VC_CORERESET); + + // clear VCATCH in the DFSR register + stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_VCATCH); + } else { + stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, + STLINK_REG_CM3_DEMCR_TRCENA | + STLINK_REG_CM3_DEMCR_VC_HARDERR | + STLINK_REG_CM3_DEMCR_VC_BUSERR); + } + + // clear S_RESET_ST in the DHCSR register + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + + // soft reset (core reset) by SYSRESETREQ (DDI0337E, p. 8-23) + ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, + STLINK_REG_AIRCR_VECTKEY | + STLINK_REG_AIRCR_SYSRESETREQ); + if (ret) { + ELOG("Soft reset failed: error write to AIRCR\n"); + return (ret); + } + + // waiting for a reset within 500ms + // DDI0337E, p. 10-4, Debug Halting Control and Status Register + timeout = time_ms() + 500; + while (time_ms() < timeout) { + // DDI0337E, p. 10-4, Debug Halting Control and Status Register + dhcsr = STLINK_REG_DHCSR_S_RESET_ST; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + if (halt_on_reset) { + // waiting halt by the SYSRESETREQ exception + // DDI0403E, p. C1-699, Debug Fault Status Register + dfsr = 0; + stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); + if ((dfsr & STLINK_REG_DFSR_VCATCH) == 0) { + continue; + } + } + timeout = 0; + break; + } + } + + // reset DFSR register. DFSR is power-on reset only (DDI0337H, p. 7-5) + stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_CLEAR); + + if (timeout) { + ELOG("Soft reset failed: timeout\n"); + return (-1); + } + + return (0); +} + // 255 int stlink_run(stlink_t *sl, enum run_type type) { struct stlink_reg rr; @@ -377,11 +460,13 @@ int stlink_run(stlink_t *sl, enum run_type type) { return (sl->backend->run(sl, type)); } + // 273 int stlink_set_swdclk(stlink_t *sl, int freq_khz) { DLOG("*** set_swdclk ***\n"); return (sl->backend->set_swdclk(sl, freq_khz)); } + // 293 // this function is called by stlink_status() // do not call stlink_core_stat() directly, always use stlink_status() @@ -403,6 +488,7 @@ void stlink_core_stat(stlink_t *sl) { DLOG(" core status: unknown\n"); } } + // 256 int stlink_status(stlink_t *sl) { int ret; @@ -412,6 +498,7 @@ int stlink_status(stlink_t *sl) { stlink_core_stat(sl); return (ret); } + // 257 int stlink_version(stlink_t *sl) { DLOG("*** looking up stlink version ***\n"); @@ -435,6 +522,7 @@ int stlink_version(stlink_t *sl) { return (0); } + // 272 int stlink_target_voltage(stlink_t *sl) { int voltage = -1; @@ -454,16 +542,19 @@ int stlink_target_voltage(stlink_t *sl) { return (voltage); } + // 299 bool stlink_is_core_halted(stlink_t *sl) { stlink_status(sl); return (sl->core_stat == TARGET_HALTED); } + // 269 int stlink_step(stlink_t *sl) { DLOG("*** stlink_step ***\n"); return (sl->backend->step(sl)); } + // 270 int stlink_current_mode(stlink_t *sl) { int mode = sl->backend->current_mode(sl); @@ -483,20 +574,24 @@ int stlink_current_mode(stlink_t *sl) { DLOG("stlink mode: unknown!\n"); return (STLINK_DEV_UNKNOWN_MODE); } + // 274 int stlink_trace_enable(stlink_t *sl, uint32_t frequency) { DLOG("*** stlink_trace_enable ***\n"); return (sl->backend->trace_enable(sl, frequency)); } + // 275 int stlink_trace_disable(stlink_t *sl) { DLOG("*** stlink_trace_disable ***\n"); return (sl->backend->trace_disable(sl)); } + // 276 int stlink_trace_read(stlink_t *sl, uint8_t *buf, size_t size) { return (sl->backend->trace_read(sl, buf, size)); } + // 294 void stlink_print_data(stlink_t *sl) { if (sl->q_len <= 0 || sl->verbose < UDEBUG) { @@ -523,9 +618,9 @@ void stlink_print_data(stlink_t *sl) { // DLOG("\n\n"); fprintf(stderr, "\n"); } + // 283 -int stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, - stm32_addr_t addr) { +int stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, stm32_addr_t addr) { // write the file in sram at addr int error = -1; @@ -581,6 +676,7 @@ int stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, on_error: return (error); } + //284 int stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { // write the file in sram at addr @@ -655,9 +751,9 @@ int stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { unmap_file(&mf); return (error); } + // 302 -int stlink_fread(stlink_t *sl, const char *path, bool is_ihex, - stm32_addr_t addr, size_t size) { +int stlink_fread(stlink_t *sl, const char *path, bool is_ihex, stm32_addr_t addr, size_t size) { // read size bytes from addr to file ILOG("read from address %#010x size %u\n", addr, (unsigned)size); @@ -689,9 +785,9 @@ int stlink_fread(stlink_t *sl, const char *path, bool is_ihex, close(fd); return (error); } + // 300 -int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, - size_t size) { +int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, size_t size) { // write the buffer right after the loader int ret = 0; size_t chunk = size & ~0x3; @@ -709,6 +805,7 @@ int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, return (ret); } + // 291 uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { if ((sl->chip_id == STM32_CHIPID_F2) || @@ -749,6 +846,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { return ((uint32_t)sl->flash_pgsz); } + // 279 int stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **mem, size_t *size, uint32_t *begin) { @@ -910,6 +1008,7 @@ int stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **mem, return (res); } + // 280 uint8_t stlink_get_erased_pattern(stlink_t *sl) { if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { @@ -1024,79 +1123,6 @@ int stlink_jtag_reset(stlink_t *sl, int value) { return (sl->backend->jtag_reset(sl, value)); } -int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { - int ret; - unsigned timeout; - uint32_t dhcsr, dfsr; - - DLOG("*** stlink_soft_reset %s***\n", halt_on_reset ? "(halt) " : ""); - - // halt core and enable debugging (if not already done) - // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) - stlink_write_debug32(sl, STLINK_REG_DHCSR, - STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | - STLINK_REG_DHCSR_C_DEBUGEN); - - // enable Halt on reset by set VC_CORERESET and TRCENA (DDI0337E, p. 10-10) - if (halt_on_reset) { - stlink_write_debug32( - sl, STLINK_REG_CM3_DEMCR, - STLINK_REG_CM3_DEMCR_TRCENA | STLINK_REG_CM3_DEMCR_VC_HARDERR | - STLINK_REG_CM3_DEMCR_VC_BUSERR | STLINK_REG_CM3_DEMCR_VC_CORERESET); - - // clear VCATCH in the DFSR register - stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_VCATCH); - } else { - stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, - STLINK_REG_CM3_DEMCR_TRCENA | - STLINK_REG_CM3_DEMCR_VC_HARDERR | - STLINK_REG_CM3_DEMCR_VC_BUSERR); - } - - // clear S_RESET_ST in the DHCSR register - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - - // soft reset (core reset) by SYSRESETREQ (DDI0337E, p. 8-23) - ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, - STLINK_REG_AIRCR_VECTKEY | - STLINK_REG_AIRCR_SYSRESETREQ); - if (ret) { - ELOG("Soft reset failed: error write to AIRCR\n"); - return (ret); - } - - // waiting for a reset within 500ms - // DDI0337E, p. 10-4, Debug Halting Control and Status Register - timeout = time_ms() + 500; - while (time_ms() < timeout) { - // DDI0337E, p. 10-4, Debug Halting Control and Status Register - dhcsr = STLINK_REG_DHCSR_S_RESET_ST; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { - if (halt_on_reset) { - // waiting halt by the SYSRESETREQ exception - // DDI0403E, p. C1-699, Debug Fault Status Register - dfsr = 0; - stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); - if ((dfsr & STLINK_REG_DFSR_VCATCH) == 0) { - continue; - } - } - timeout = 0; - break; - } - } - - // reset DFSR register. DFSR is power-on reset only (DDI0337H, p. 7-5) - stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_CLEAR); - - if (timeout) { - ELOG("Soft reset failed: timeout\n"); - return (-1); - } - - return (0); -} /** * Decode the version bits, originally from -sg, verified with usb * @param sl stlink context, assumed to contain valid data in the buffer @@ -1283,8 +1309,7 @@ static int stlink_read(stlink_t *sl, stm32_addr_t addr, size_t size, } static bool stlink_fread_worker(void *arg, uint8_t *block, ssize_t len) { - struct stlink_fread_worker_arg *the_arg = - (struct stlink_fread_worker_arg *)arg; + struct stlink_fread_worker_arg *the_arg = (struct stlink_fread_worker_arg *)arg; if (write(the_arg->fd, block, len) != len) { fprintf(stderr, "write() != aligned_size\n"); @@ -1315,8 +1340,7 @@ static uint8_t stlink_parse_hex(const char *hex) { return ((d[0] << 4) | (d[1])); } -static bool -stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg *the_arg) { +static bool stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg *the_arg) { uint32_t addr = the_arg->addr; uint8_t sum = 2 + 4 + (uint8_t)((addr & 0xFF000000) >> 24) + (uint8_t)((addr & 0x00FF0000) >> 16); @@ -1330,8 +1354,7 @@ stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg *the_arg) { return (true); } -static bool -stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg *the_arg) { +static bool stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg *the_arg) { uint8_t count = the_arg->buf_pos; if (count == 0) { @@ -1399,8 +1422,7 @@ static bool stlink_fread_ihex_worker(void *arg, uint8_t *block, ssize_t len) { return (true); } -static bool -stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg *the_arg) { +static bool stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg *the_arg) { if (!stlink_fread_ihex_writeline(the_arg)) { return (false); } diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 0ed4734ad..5b8075ea7 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -38,15 +38,17 @@ uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { reg = FLASH_F4_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { reg = FLASH_F7_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - reg = STM32L4_FLASH_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - reg = STM32WB_FLASH_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { + reg = STM32L4_FLASH_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + reg = STM32L5_FLASH_NSCR; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + reg = STM32WB_FLASH_CR; } else { reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; } @@ -60,7 +62,7 @@ uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { } void lock_flash(stlink_t *sl) { - uint32_t cr_lock_shift, cr_reg, n, cr2_reg = 0; + uint32_t cr_lock_shift = 0, cr_reg = 0, n = 0, cr2_reg = 0; uint32_t cr_mask = 0xffffffffu; if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { @@ -76,21 +78,24 @@ void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; cr_lock_shift = FLASH_F7_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = STM32L0_FLASH_PELOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + cr_reg = STM32L5_FLASH_NSCR; + cr_lock_shift = STM32L5_FLASH_NSCR_NSLOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { cr2_reg = FLASH_H7_CR2; } @@ -118,21 +123,23 @@ static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { sr_reg = FLASH_F4_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - sr_reg = STM32L4_FLASH_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { sr_reg = STM32Gx_FLASH_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - sr_reg = STM32WB_FLASH_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { + sr_reg = STM32L4_FLASH_SR; + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + sr_reg = STM32L5_FLASH_NSSR; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + sr_reg = STM32WB_FLASH_SR; } else { ELOG("method 'write_flash_sr' is unsupported\n"); return (-1); @@ -156,6 +163,12 @@ void clear_flash_error(stlink_t *sl) { case STM32_FLASH_TYPE_G4: write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); break; + case STM32_FLASH_TYPE_H7: + write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_sr(sl, BANK_2, FLASH_H7_SR_ERROR_MASK); + } + break; case STM32_FLASH_TYPE_L0_L1: if (get_stm32l0_flash_base(sl) == STM32L_FLASH_REGS_ADDR) { write_flash_sr(sl, BANK_1, STM32L1_FLASH_SR_ERROR_MASK); @@ -166,11 +179,8 @@ void clear_flash_error(stlink_t *sl) { case STM32_FLASH_TYPE_L4: write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); break; - case STM32_FLASH_TYPE_H7: - write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_sr(sl, BANK_2, FLASH_H7_SR_ERROR_MASK); - } + case STM32_FLASH_TYPE_L5_U5: + write_flash_sr(sl, BANK_1, STM32L5_FLASH_NSSR_ERROR_MASK); break; case STM32_FLASH_TYPE_WB_WL: write_flash_sr(sl, BANK_1, STM32WB_FLASH_SR_ERROR_MASK); @@ -186,21 +196,23 @@ uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { sr_reg = FLASH_F4_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - sr_reg = STM32L4_FLASH_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { sr_reg = STM32Gx_FLASH_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - sr_reg = STM32WB_FLASH_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { + sr_reg = STM32L4_FLASH_SR; + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + sr_reg = STM32L5_FLASH_NSSR; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + sr_reg = STM32WB_FLASH_SR; } else { ELOG("method 'read_flash_sr' is unsupported\n"); return (-1); @@ -222,15 +234,17 @@ unsigned int is_flash_busy(stlink_t *sl) { sr_busy_shift = FLASH_F4_SR_BSY; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { sr_busy_shift = FLASH_F7_SR_BSY; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - sr_busy_shift = STM32L4_FLASH_SR_BSY; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { sr_busy_shift = STM32Gx_FLASH_SR_BSY; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - sr_busy_shift = STM32WB_FLASH_SR_BSY; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { sr_busy_shift = FLASH_H7_SR_QW; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { + sr_busy_shift = STM32L4_FLASH_SR_BSY; + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + sr_busy_shift = STM32L5_FLASH_NSSR_BSY; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + sr_busy_shift = STM32WB_FLASH_SR_BSY; } else { ELOG("method 'is_flash_busy' is unsupported\n"); return (-1); @@ -286,6 +300,13 @@ int check_flash_error(stlink_t *sl) { PROGERR = (1 << STM32Gx_FLASH_SR_PROGERR); PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); break; + case STM32_FLASH_TYPE_H7: + res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; + } + WRPERR = (1 << FLASH_H7_SR_WRPERR); + break; case STM32_FLASH_TYPE_L0_L1: res = read_flash_sr(sl, BANK_1); if (get_stm32l0_flash_base(sl) == STM32L_FLASH_REGS_ADDR) { @@ -303,12 +324,11 @@ int check_flash_error(stlink_t *sl) { PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); PGAERR = (1 << STM32L4_FLASH_SR_PGAERR); break; - case STM32_FLASH_TYPE_H7: - res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; - } - WRPERR = (1 << FLASH_H7_SR_WRPERR); + case STM32_FLASH_TYPE_L5_U5: + res = read_flash_sr(sl, BANK_1) & STM32L5_FLASH_NSSR_ERROR_MASK; + WRPERR = (1 << STM32L5_FLASH_NSSR_NSWRPERR); + PROGERR = (1 << STM32L5_FLASH_NSSR_NSPROGERR); + PGAERR = (1 << STM32L5_FLASH_NSSR_NSPGAERR); break; case STM32_FLASH_TYPE_WB_WL: res = read_flash_sr(sl, BANK_1) & STM32WB_FLASH_SR_ERROR_MASK; @@ -357,22 +377,25 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; cr_lock_shift = FLASH_F7_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + cr_lock_shift = FLASH_H7_CR_LOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = STM32L0_FLASH_PELOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + cr_reg = STM32L5_FLASH_NSCR; + cr_lock_shift = STM32L5_FLASH_NSCR_NSLOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; - cr_lock_shift = FLASH_H7_CR_LOCK; } else { ELOG("unsupported flash method, abort\n"); return (-1); @@ -400,22 +423,32 @@ static void unlock_flash(stlink_t *sl) { key_reg = FLASH_F4_KEYR; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { key_reg = FLASH_F7_KEYR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; - flash_key1 = FLASH_L0_PEKEY1; - flash_key2 = FLASH_L0_PEKEY2; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - key_reg = STM32L4_FLASH_KEYR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { key_reg = STM32Gx_FLASH_KEYR; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - key_reg = STM32WB_FLASH_KEYR; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { key_reg = FLASH_H7_KEYR1; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { key2_reg = FLASH_H7_KEYR2; } + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; + flash_key1 = FLASH_L0_PEKEY1; + flash_key2 = FLASH_L0_PEKEY2; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { + key_reg = STM32L4_FLASH_KEYR; + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + // Set voltage scaling to range 0 to perform flash operations (RM0438 p. 183) + uint32_t mask = (0b11 << STM32L5_PWR_CR1_VOS); + uint32_t val; + stlink_read_debug32(sl, STM32L5_PWR_CR1, &val); + if ((val & mask) > (1 << STM32L5_PWR_CR1_VOS)) { + val &= ~mask; + stlink_write_debug32(sl, STM32L5_PWR_CR1, val); + } + key_reg = STM32L5_FLASH_NSKEYR; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + key_reg = STM32WB_FLASH_KEYR; } else { ELOG("unsupported flash method, abort\n"); return; @@ -464,6 +497,17 @@ int lock_flash_option(stlink_t *sl) { optcr_reg = FLASH_F7_OPTCR; optlock_shift = FLASH_F7_OPTCR_LOCK; break; + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STM32_FLASH_TYPE_H7: + optcr_reg = FLASH_H7_OPTCR; + optlock_shift = FLASH_H7_OPTCR_OPTLOCK; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) + optcr2_reg = FLASH_H7_OPTCR2; + break; case STM32_FLASH_TYPE_L0_L1: optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; optlock_shift = STM32L0_FLASH_OPTLOCK; @@ -472,21 +516,14 @@ int lock_flash_option(stlink_t *sl) { optcr_reg = STM32L4_FLASH_CR; optlock_shift = STM32L4_FLASH_CR_OPTLOCK; break; - case STM32_FLASH_TYPE_G0: - case STM32_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + case STM32_FLASH_TYPE_L5_U5: + optcr_reg = STM32L5_FLASH_NSCR; + optlock_shift = STM32L5_FLASH_NSCR_OPTLOCK; break; case STM32_FLASH_TYPE_WB_WL: optcr_reg = STM32WB_FLASH_CR; optlock_shift = STM32WB_FLASH_CR_OPTLOCK; break; - case STM32_FLASH_TYPE_H7: - optcr_reg = FLASH_H7_OPTCR; - optlock_shift = FLASH_H7_OPTCR_OPTLOCK; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) - optcr2_reg = FLASH_H7_OPTCR2; - break; default: ELOG("unsupported flash method, abort\n"); return -1; @@ -537,6 +574,15 @@ static bool is_flash_option_locked(stlink_t *sl) { optcr_reg = FLASH_F7_OPTCR; optlock_shift = FLASH_F7_OPTCR_LOCK; break; + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STM32_FLASH_TYPE_H7: + optcr_reg = FLASH_H7_OPTCR; + optlock_shift = FLASH_H7_OPTCR_OPTLOCK; + break; case STM32_FLASH_TYPE_L0_L1: optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; optlock_shift = STM32L0_FLASH_OPTLOCK; @@ -545,19 +591,14 @@ static bool is_flash_option_locked(stlink_t *sl) { optcr_reg = STM32L4_FLASH_CR; optlock_shift = STM32L4_FLASH_CR_OPTLOCK; break; - case STM32_FLASH_TYPE_G0: - case STM32_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + case STM32_FLASH_TYPE_L5_U5: + optcr_reg = STM32L5_FLASH_NSCR; + optlock_shift = STM32L5_FLASH_NSCR_OPTLOCK; break; case STM32_FLASH_TYPE_WB_WL: optcr_reg = STM32WB_FLASH_CR; optlock_shift = STM32WB_FLASH_CR_OPTLOCK; break; - case STM32_FLASH_TYPE_H7: - optcr_reg = FLASH_H7_OPTCR; - optlock_shift = FLASH_H7_OPTCR_OPTLOCK; - break; default: ELOG("unsupported flash method, abort\n"); return -1; @@ -590,6 +631,15 @@ static int unlock_flash_option(stlink_t *sl) { case STM32_FLASH_TYPE_F7: optkey_reg = FLASH_F7_OPT_KEYR; break; + case STM32_FLASH_TYPE_G0: + case STM32_FLASH_TYPE_G4: + optkey_reg = STM32Gx_FLASH_OPTKEYR; + break; + case STM32_FLASH_TYPE_H7: + optkey_reg = FLASH_H7_OPT_KEYR; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) + optkey2_reg = FLASH_H7_OPT_KEYR2; + break; case STM32_FLASH_TYPE_L0_L1: optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; optkey1 = FLASH_L0_OPTKEY1; @@ -598,18 +648,12 @@ static int unlock_flash_option(stlink_t *sl) { case STM32_FLASH_TYPE_L4: optkey_reg = STM32L4_FLASH_OPTKEYR; break; - case STM32_FLASH_TYPE_G0: - case STM32_FLASH_TYPE_G4: - optkey_reg = STM32Gx_FLASH_OPTKEYR; + case STM32_FLASH_TYPE_L5_U5: + optkey_reg = STM32L5_FLASH_OPTKEYR; break; case STM32_FLASH_TYPE_WB_WL: optkey_reg = STM32WB_FLASH_OPT_KEYR; break; - case STM32_FLASH_TYPE_H7: - optkey_reg = FLASH_H7_OPT_KEYR; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) - optkey2_reg = FLASH_H7_OPT_KEYR2; - break; default: ELOG("unsupported flash method, abort\n"); return (-1); @@ -672,16 +716,18 @@ void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { cr_reg = FLASH_F4_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; bit = FLASH_H7_CR_PG; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + cr_reg = STM32L5_FLASH_NSCR; + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + cr_reg = STM32WB_FLASH_CR; } else { cr_reg = FLASH_CR; } @@ -744,6 +790,8 @@ static void set_flash_cr_per(stlink_t *sl, unsigned bank) { if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + cr_reg = STM32L5_FLASH_NSCR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; } else { @@ -761,6 +809,8 @@ static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + cr_reg = STM32L5_FLASH_NSCR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = STM32WB_FLASH_CR; } else { @@ -796,19 +846,22 @@ static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; cr_strt = 1 << FLASH_F7_CR_STRT; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_strt = (1 << STM32L4_FLASH_CR_STRT); } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_strt = (1 << STM32Gx_FLASH_CR_STRT); - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; - cr_strt = (1 << STM32WB_FLASH_CR_STRT); } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; cr_strt = 1 << FLASH_H7_CR_START(sl->chip_id); + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_strt = (1 << STM32L4_FLASH_CR_STRT); + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + cr_reg = STM32L5_FLASH_NSCR; + cr_strt = (1 << STM32L5_FLASH_NSCR_NSSTRT); + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + cr_reg = STM32WB_FLASH_CR; + cr_strt = (1 << STM32WB_FLASH_CR_STRT); } else { cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; cr_strt = (1 << FLASH_CR_STRT); @@ -830,28 +883,30 @@ static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { cr_reg = FLASH_F7_CR; cr_mer = 1 << FLASH_CR_MER; cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); - cr_pg = (1 << STM32L4_FLASH_CR_PG); } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_mer = (1 << STM32Gx_FLASH_CR_MER1); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); } - - cr_pg = (1 << FLASH_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; - cr_mer = (1 << FLASH_CR_MER); cr_pg = (1 << FLASH_CR_PG); } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; cr_mer = (1 << FLASH_H7_CR_BER); cr_pg = (1 << FLASH_H7_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); + cr_pg = (1 << STM32L4_FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + cr_reg = STM32L5_FLASH_NSCR; + cr_mer = (1 << STM32L5_FLASH_NSCR_NSMER1) | (1 << STM32L5_FLASH_NSCR_NSMER2); + cr_pg = (1 << STM32L5_FLASH_NSCR_NSPG); + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + cr_reg = STM32WB_FLASH_CR; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); } else { cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; cr_mer = (1 << FLASH_CR_MER); @@ -993,25 +1048,16 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || - sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4 || + sl->flash_type == STM32_FLASH_TYPE_L5_U5 || + sl->flash_type == STM32_FLASH_TYPE_WB_WL) { uint32_t val; unlock_flash_if(sl); set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit // set the page to erase - if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - uint32_t flash_page = - ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - - // sec 3.10.5 - PNB[7:0] is offset by 3. - val &= ~(0xFF << 3); // Clear previously set page number (if any) - val |= ((flash_page & 0xFF) << 3); - - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - } else if (sl->flash_type == STM32_FLASH_TYPE_G0) { + if (sl->flash_type == STM32_FLASH_TYPE_G0) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); @@ -1027,6 +1073,34 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { val &= ~(0x7F << 3); val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + uint32_t flash_page; + stlink_read_debug32(sl, STM32L5_FLASH_NSCR, &val); + if (sl->flash_pgsz == 0x800 && (flashaddr - STM32_FLASH_BASE) >= sl->flash_size/2) { + flash_page = (flashaddr - STM32_FLASH_BASE - sl->flash_size/2) / + (uint32_t)(sl->flash_pgsz); + // set bank 2 for erasure + val |= (1 << STM32L5_FLASH_NSCR_NSBKER); + } else { + flash_page = + ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + // set bank 1 for erasure + val &= ~(1 << STM32L5_FLASH_NSCR_NSBKER); + } + // sec 6.9.9 + val &= ~(0x7F << 3); + val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); + stlink_write_debug32(sl, STM32L5_FLASH_NSCR, val); + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + uint32_t flash_page = + ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + + // sec 3.10.5 - PNB[7:0] is offset by 3. + val &= ~(0xFF << 3); // Clear previously set page number (if any) + val |= ((flash_page & 0xFF) << 3); + + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); } set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit diff --git a/src/stlink-lib/flashloader.c b/src/stlink-lib/flashloader.c index d9542ebbc..7164983cd 100644 --- a/src/stlink-lib/flashloader.c +++ b/src/stlink-lib/flashloader.c @@ -46,8 +46,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, } if (ret) { - WLOG("l1_stlink_flash_loader_run(%#x) failed! == -1\n", - addr + count * pagesize); + WLOG("l1_stlink_flash_loader_run(%#x) failed! == -1\n", addr + count * pagesize); break; } @@ -84,6 +83,9 @@ static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { cr_reg = STM32L4_FLASH_CR; x &= ~STM32L4_FLASH_CR_OPBITS; x |= (1 << STM32L4_FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + cr_reg = STM32L5_FLASH_NSCR; + x |= (1 << FLASH_CR_PG); } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; @@ -136,6 +138,10 @@ static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { rcc_dma_mask = STM32L0_RCC_DMAEN; } break; + case STM32_FLASH_TYPE_L5_U5: + rcc = STM32L5_RCC_AHB1ENR; + rcc_dma_mask = STM32L5_RCC_DMAEN; + break; case STM32_FLASH_TYPE_H7: rcc = STM32H7_RCC_AHB1ENR; rcc_dma_mask = STM32H7_RCC_DMAEN; @@ -216,8 +222,9 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { set_flash_cr_pg(sl, BANK_1); } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - ILOG("Starting Flash write for WB/G0/G4\n"); + sl->flash_type == STM32_FLASH_TYPE_G4 || + sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + ILOG("Starting Flash write for WB/G0/G4/L5/U5\n"); unlock_flash_if(sl); // unlock flash if necessary set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit @@ -320,14 +327,15 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, } } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { + sl->flash_type == STM32_FLASH_TYPE_G4 || + sl->flash_type == STM32_FLASH_TYPE_L5_U5) { DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); for (off = 0; off < len; off += sizeof(uint32_t)) { uint32_t data; if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off / sl->flash_pgsz), + (unsigned int)(off / sl->flash_pgsz + 1), (unsigned int)(len / sl->flash_pgsz)); fflush(stdout); } @@ -368,7 +376,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off / sl->flash_pgsz), + (unsigned int)(off / sl->flash_pgsz + 1), (unsigned int)(len / sl->flash_pgsz)); fflush(stdout); } @@ -451,11 +459,12 @@ int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || (sl->flash_type == STM32_FLASH_TYPE_F2_F4) || (sl->flash_type == STM32_FLASH_TYPE_F7) || - (sl->flash_type == STM32_FLASH_TYPE_L4) || - (sl->flash_type == STM32_FLASH_TYPE_WB_WL) || (sl->flash_type == STM32_FLASH_TYPE_G0) || (sl->flash_type == STM32_FLASH_TYPE_G4) || - (sl->flash_type == STM32_FLASH_TYPE_H7)) { + (sl->flash_type == STM32_FLASH_TYPE_H7) || + (sl->flash_type == STM32_FLASH_TYPE_L4) || + (sl->flash_type == STM32_FLASH_TYPE_L5_U5) || + (sl->flash_type == STM32_FLASH_TYPE_WB_WL)) { clear_flash_cr_pg(sl, BANK_1); if ((sl->flash_type == STM32_FLASH_TYPE_H7 && diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c index 3d332f49d..2d4898001 100644 --- a/src/stlink-lib/option_bytes.c +++ b/src/stlink-lib/option_bytes.c @@ -510,8 +510,7 @@ static int stlink_write_option_bytes_h7(stlink_t *sl, stm32_addr_t addr, uint8_t case FLASH_H7_REGS_ADDR + 0x3c: // FLASH_WPSN_PRG1 case FLASH_H7_REGS_ADDR + 0x44: // FLASH_BOOT_PRG /* Write to FLASH_xxx_PRG registers */ - write_uint32((unsigned char *)&data, - *(uint32_t *)(base)); // write options bytes + write_uint32((unsigned char *)&data, *(uint32_t *)(base)); // write options bytes WLOG("Writing option bytes %#10x to %#10x\n", data, addr); @@ -534,8 +533,7 @@ static int stlink_write_option_bytes_h7(stlink_t *sl, stm32_addr_t addr, uint8_t /* Check for errors */ if ((val & (1 << FLASH_H7_OPTSR_OPTCHANGEERR)) != 0) { - stlink_write_debug32(sl, FLASH_H7_OPTCCR, - 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); + stlink_write_debug32(sl, FLASH_H7_OPTCCR, 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); return -1; } break; @@ -753,8 +751,7 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, ui int ret = -1; if (sl->option_base == 0) { - ELOG( - "Option bytes writing is currently not supported for connected chip\n"); + ELOG("Option bytes writing is currently not supported for connected chip\n"); return (-1); } @@ -771,8 +768,7 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, ui wait_flash_busy(sl); if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it " - "again!\n"); + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); return (-1); } @@ -809,8 +805,7 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, ui ret = stlink_write_option_bytes_wb(sl, addr, base, len); break; default: - ELOG("Option bytes writing is currently not implemented for connected " - "chip\n"); + ELOG("Option bytes writing is currently not implemented for connected chip\n"); break; } @@ -892,8 +887,7 @@ int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_cr) { wait_flash_busy(sl); if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it " - "again!\n"); + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); return -1; } @@ -915,8 +909,7 @@ int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_cr) { stlink_write_option_control_register_wb(sl, option_cr); break; default: - ELOG("Option control register writing is currently not implemented for " - "connected chip\n"); + ELOG("Option control register writing is currently not implemented for connected chip\n"); break; } @@ -965,8 +958,7 @@ int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_cr1) wait_flash_busy(sl); if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it " - "again!\n"); + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); return -1; } @@ -1050,8 +1042,7 @@ int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { */ int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { if (sl->option_base == 0) { - ELOG("Option bytes boot address read is currently not supported for " - "connected chip\n"); + ELOG("Option bytes boot address read is currently not supported for connected chip\n"); return -1; } @@ -1076,8 +1067,7 @@ int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boo wait_flash_busy(sl); if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it " - "again!\n"); + ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); return -1; } @@ -1091,8 +1081,7 @@ int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boo ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); break; default: - ELOG("Option bytes boot address writing is currently not implemented for " - "connected chip\n"); + ELOG("Option bytes boot address writing is currently not implemented for connected chip\n"); break; } From 893523d74ed83abf26b994cb7e608f87b39bfda0 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 1 Jan 2023 16:27:13 +0100 Subject: [PATCH 1345/1435] Updated CHANGELOG.md --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82656d50b..ddd795c37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ Features: - Added chip-IDs for STM32G0B0/G0B1/G0C1/G050/G051/G061 ([#1140](https://github.com/stlink-org/stlink/pull/1140)) - Added option byte info for STM32F411XX ([#1141](https://github.com/stlink-org/stlink/pull/1141)) - Expanded and revised list of chips ([#1145](https://github.com/stlink-org/stlink/pull/1145), [#1164](https://github.com/stlink-org/stlink/pull/1164)) -- [STM32H72X/3X]: Added full access to all device memory ([#1158](https://github.com/stlink-org/stlink/pull/1158), [#1159](https://github.com/stlink-org/stlink/pull/1159)) +- STM32H72X/3X: Added full access to all device memory ([#1158](https://github.com/stlink-org/stlink/pull/1158), [#1159](https://github.com/stlink-org/stlink/pull/1159)) - Added support for STM32WLEx ([#1173](https://github.com/stlink-org/stlink/pull/1173), [#1273](https://github.com/stlink-org/stlink/pull/1273)) - Added support for STLINK-V3 devices with no MSD ([#1185](https://github.com/stlink-org/stlink/pull/1185)) - Updated gdb-server.c to allow external memory access on STM32H73xx ([#1196](https://github.com/stlink-org/stlink/pull/1196), [#1197](https://github.com/stlink-org/stlink/pull/1197)) @@ -51,7 +51,7 @@ Fixes: - cmake: Install shared libraries in proper directories ([#1142](https://github.com/stlink-org/stlink/pull/1142)) - Fixed clearance of the H7 dual bank flag ([#1146](https://github.com/stlink-org/stlink/pull/1146), [#1147](https://github.com/stlink-org/stlink/pull/1147)) - Fix for 'libusb_devices were leaked' when no ST-LINK programmer was found ([#1150](https://github.com/stlink-org/stlink/pull/1150)) -- Set of fixes and improvements ([#1154](https://github.com/stlink-org/stlink/pull/1154)) +- Set of fixes and improvements ([#1153](https://github.com/stlink-org/stlink/pull/1153), [#1154](https://github.com/stlink-org/stlink/pull/1154)) - Removed limit check for WRITEMEM_32BIT ([#1157](https://github.com/stlink-org/stlink/pull/1157)) - Fixed get_stm32l0_flash_base address for STM32L152RE ([#1161](https://github.com/stlink-org/stlink/pull/1161), [#1162](https://github.com/stlink-org/stlink/pull/1162)) - Fixed segfault if chip was not found in chip config files ([#1138](https://github.com/stlink-org/stlink/pull/1138), [#1163](https://github.com/stlink-org/stlink/pull/1163), [#1165](https://github.com/stlink-org/stlink/pull/1165), [#1166](https://github.com/stlink-org/stlink/pull/1166), [#1170](https://github.com/stlink-org/stlink/pull/1170)) @@ -65,7 +65,7 @@ Fixes: - Fixed compliation for OpenBSD 7.0 ([#1202](https://github.com/stlink-org/stlink/pull/1202)) - Included 'SSIZE_MAX' from 'limits.h' in 'src/common.c' ([#1207](https://github.com/stlink-org/stlink/pull/1207)) - Fix for libusb_kernel_driver_active & error handling for st.st_size () ([#1210](https://github.com/stlink-org/stlink/pull/1210), [#1211](https://github.com/stlink-org/stlink/pull/1211), [#1214](https://github.com/stlink-org/stlink/pull/1214) -- st-trace: Fixed clock issues ([#1251](https://github.com/stlink-org/stlink/pull/1251), [#1252](https://github.com/stlink-org/stlink/pull/1252)) +- st-trace: Fixed clock issues ([#1248](https://github.com/stlink-org/stlink/pull/1248), [#1251](https://github.com/stlink-org/stlink/pull/1251), [#1252](https://github.com/stlink-org/stlink/pull/1252)) - Fixed compilation with gcc-12 ([#1257](https://github.com/stlink-org/stlink/pull/1257), [#1267](https://github.com/stlink-org/stlink/pull/1267)) - Fixed flash regs addr for STM32L152RET6 in common_flash.c ([#1265](https://github.com/stlink-org/stlink/pull/1265)) - Fixed flash, dbgmcu and rcc registers for STM32L1 ([#1266](https://github.com/stlink-org/stlink/pull/1266)) From 54e4bc5251933bbd6206d3548918e52a1b85d66c Mon Sep 17 00:00:00 2001 From: John Hall Date: Sun, 1 Jan 2023 16:01:58 -0800 Subject: [PATCH 1346/1435] Updating windows signal handling to not terminate the application before cleanup. --- src/st-trace/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 9fcf8e358..e0bf3c88d 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -88,7 +88,7 @@ static void abort_trace() { g_abort_trace = true; } BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { (void)fdwCtrlType; abort_trace(); - return FALSE; + return TRUE; } #endif From 750a92cdc40ef33d0e3fc7208da9c30496d22aae Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 2 Jan 2023 11:59:26 +0100 Subject: [PATCH 1347/1435] Log message improvements for st-flash --- src/st-flash/flash.c | 1 + src/stlink-lib/common.c | 8 +++----- src/stlink-lib/common_flash.c | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index cef0b639f..39b31f219 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -179,6 +179,7 @@ int main(int ac, char** av) { printf("stlink_erase_flash_mass() == -1\n"); goto on_error; } + printf("Mass erase completed successfully.\n"); } else if (o.cmd == CMD_RESET) { if (stlink_reset(sl, RESET_AUTO)) { printf("Failed to reset device\n"); diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index fe5574706..cb037fb2f 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -342,11 +342,9 @@ int stlink_reset(stlink_t *sl, enum reset_type type) { dhcsr = 0; int res = stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0 && !res) { - // reset not done yet - // try reset through AIRCR so that NRST does not need to be connected - - WLOG("NRST is not connected\n"); - DLOG("Using reset through SYSRESETREQ\n"); + // reset not done yet --> try reset through AIRCR so that NRST does not need to be connected + ILOG("NRST is not connected --> using software reset via AIRCR\n"); + DLOG("NRST not connected --> Reset through SYSRESETREQ\n"); return stlink_soft_reset(sl, 0); } diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 5b8075ea7..e84b307eb 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -739,7 +739,7 @@ void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { static void wait_flash_busy_progress(stlink_t *sl) { int i = 0; - fprintf(stdout, "Mass erasing"); + fprintf(stdout, "Mass erasing..."); fflush(stdout); while (is_flash_busy(sl)) { From 2a8a36efba2cf6bae3506f0d92c24ebea46674ba Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 2 Jan 2023 12:21:18 +0100 Subject: [PATCH 1348/1435] Updated GitHub Actions C/C++ CI workflow --- .github/workflows/c-cpp.yml | 106 +++++++++++++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 8 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 8e798269b..fe07c6e44 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: install dependencies - run: sudo apt update && sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt update && sudo apt-get install gcc-8 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug run: sudo make clean && make debug - name: make test @@ -35,7 +35,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: install dependencies - run: sudo apt update && sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt update && sudo apt-get install gcc-8 libusb-1.0.0-dev libgtk-3-dev rpm - name: Set compiler flags run: | CFLAGS="$CFLAGS -m32" @@ -150,7 +150,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt update && sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt update && sudo apt-get install clang-12 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug run: sudo make clean && make debug - name: make test @@ -170,7 +170,97 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt update && sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt update && sudo apt-get install clang-12 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean + + job_linux_22_04_64_gcc: + name: ubuntu-22.04 gcc + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt update && sudo apt-get install gcc-12 libusb-1.0.0-dev libgtk-4-dev rpm + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean + + job_linux_22_04_32_gcc: + name: ubuntu-22.04 gcc 32-bit + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt update && sudo apt-get install gcc-12 libusb-1.0.0-dev libgtk-4-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean + + job_linux_22_04_64_clang: + name: ubuntu-22.04 clang + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt update && sudo apt-get install clang-14 libusb-1.0.0-dev libgtk-4-dev rpm + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean + + job_linux_22_04_32_clang: + name: ubuntu-22.04 clang 32-bit + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt update && sudo apt-get install clang-14 libusb-1.0.0-dev libgtk-4-dev rpm - name: Set compiler flags run: | CFLAGS="$CFLAGS -m32" @@ -190,13 +280,13 @@ jobs: run: sudo make uninstall && sudo make clean # Linux MinGW cross compliation -# job_linux_20_04_cross: -# name: ubuntu-20.04 mingw64 -# runs-on: ubuntu-20.04 +# job_linux_22_04_cross: +# name: ubuntu-22.04 mingw64 +# runs-on: ubuntu-22.04 # steps: # - uses: actions/checkout@v2 # - name: Install dependencies -# run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm mingw-w64 +# run: sudo apt-get install gcc-12 libusb-1.0.0-dev libgtk-4-dev rpm mingw-w64 # - name: Building Release for Windows (x86-64) ... # run: sudo mkdir -p build-mingw && cd build-mingw && sudo cmake \ # -DCMAKE_SYSTEM_NAME=Windows \ From 61ff09e5274d46a46ae58bc4ffe44fe90a887ea6 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 14 Jan 2023 12:14:35 +0100 Subject: [PATCH 1349/1435] [doc] End of support for macOS (Closes #1296) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 571db49fd..661a60764 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ We recommend to install `stlink-tools` from the package repository of the used d - RedHat/CentOS 8: Users can install from [EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel8) - FreeBSD: Users can install from [freshports](https://www.freshports.org/devel/stlink) -- MacOS: Users can open a terminal window and then follow the same procedure as for installing on Linux +- MacOS: **Support for macOS will end with v1.7.1.** Please use v1.7.0 (current ***master*** branch) and the related documentation instead. ## Installation from source (advanced users) From 82fb1cc773bd481c93c8b7260e1d64cb020f20b9 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 15 Jan 2023 14:14:25 +0100 Subject: [PATCH 1350/1435] Updated header files in CMakeLists.txt --- CMakeLists.txt | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b25291992..7d8bce8cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -166,35 +166,41 @@ add_subdirectory(inc) set(STLINK_HEADERS inc/backend.h inc/stlink.h - src/stlink-lib/common_flash.h + inc/stm32.h + inc/stm32flash.h src/stlink-lib/calculate.h - src/stlink-lib/commands.h - src/stlink-lib/libusb_settings.h - src/stlink-lib/reg.h src/stlink-lib/chipid.h + src/stlink-lib/commands.h + src/stlink-lib/common_flash.h + src/stlink-lib/common.h src/stlink-lib/flash_loader.h + src/stlink-lib/flashloader.h + src/stlink-lib/helper.h + src/stlink-lib/libusb_settings.h src/stlink-lib/logging.h + src/stlink-lib/map_file.h src/stlink-lib/md5.h + src/stlink-lib/option_bytes.h + src/stlink-lib/reg.h src/stlink-lib/sg.h src/stlink-lib/usb.h - src/stlink-lib/helper.h ) set(STLINK_SOURCE - src/stlink-lib/read_write.c - src/stlink-lib/common.c - src/stlink-lib/option_bytes.c - src/stlink-lib/common_flash.c - src/stlink-lib/map_file.c - src/stlink-lib/flashloader.c src/stlink-lib/calculate.c src/stlink-lib/chipid.c + src/stlink-lib/common_flash.c + src/stlink-lib/common.c src/stlink-lib/flash_loader.c + src/stlink-lib/flashloader.c + src/stlink-lib/helper.c src/stlink-lib/logging.c + src/stlink-lib/map_file.c src/stlink-lib/md5.c + src/stlink-lib/option_bytes.c + src/stlink-lib/read_write.c src/stlink-lib/sg.c src/stlink-lib/usb.c - src/stlink-lib/helper.c ) if (WIN32) From 1bec78c4289ec82f8e43565d610489e8782d5ce6 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 15 Jan 2023 14:20:48 +0100 Subject: [PATCH 1351/1435] Updated libusb checksum for WIN32 --- cmake/modules/Findlibusb.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index 7442c8cc4..fbbda5ba3 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -72,7 +72,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download - ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 + ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 aabe177bde869bfad34278335eaf8955 ) endif () From c18293a82e9fa98c34f99f31217959c554197738 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 13 Feb 2023 23:59:11 +0100 Subject: [PATCH 1352/1435] Minor fixes - Updated Standards-Version for deb-package - Fix for strcmp(value, "L4") in chipid.c - Minor formatting fixes --- cmake/packaging/deb/control | 2 +- src/stlink-lib/chipid.c | 422 ++++++++++++++++++------------------ 2 files changed, 212 insertions(+), 212 deletions(-) diff --git a/cmake/packaging/deb/control b/cmake/packaging/deb/control index 7c8d13e47..2ed3b6b11 100644 --- a/cmake/packaging/deb/control +++ b/cmake/packaging/deb/control @@ -2,7 +2,7 @@ Source: stlink Priority: optional Maintainer: Nightwalker-87 Build-Depends: cmake (>= 3.10.2), dh-cmake, debhelper (>= 9), libusb-1.0-0-dev (>= 1.0.21), libgtk-3-dev (>= 3.22.30) -Standards-Version: 4.5.0 +Standards-Version: 4.6.2 Rules-Requires-Root: no Section: electronics Homepage: https://github.com/stlink-org/stlink diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 51a1200ad..075c19c17 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1,248 +1,248 @@ -#include -#include #include "chipid.h" +#include +#include -#include +#include #include #include -#include #include +#include static struct stlink_chipid_params *devicelist; -void dump_a_chip (struct stlink_chipid_params *dev) { - DLOG("# Device Type: %s\n", dev->dev_type); - DLOG("# Reference Manual: RM%s\n", dev->ref_manual_id); - DLOG("#\n"); - DLOG("chip_id 0x%x\n", dev->chip_id); - DLOG("flash_type %d\n", dev->flash_type); - DLOG("flash_size_reg 0x%x\n", dev->flash_size_reg); - DLOG("flash_pagesize 0x%x\n", dev->flash_pagesize); - DLOG("sram_size 0x%x\n", dev->sram_size); - DLOG("bootrom_base 0x%x\n", dev->bootrom_base); - DLOG("bootrom_size 0x%x\n", dev->bootrom_size); - DLOG("option_base 0x%x\n", dev->option_base); - DLOG("option_size 0x%x\n", dev->option_size); - DLOG("flags %d\n\n", dev->flags); +void dump_a_chip(struct stlink_chipid_params *dev) { + DLOG("# Device Type: %s\n", dev->dev_type); + DLOG("# Reference Manual: RM%s\n", dev->ref_manual_id); + DLOG("#\n"); + DLOG("chip_id 0x%x\n", dev->chip_id); + DLOG("flash_type %d\n", dev->flash_type); + DLOG("flash_size_reg 0x%x\n", dev->flash_size_reg); + DLOG("flash_pagesize 0x%x\n", dev->flash_pagesize); + DLOG("sram_size 0x%x\n", dev->sram_size); + DLOG("bootrom_base 0x%x\n", dev->bootrom_base); + DLOG("bootrom_size 0x%x\n", dev->bootrom_size); + DLOG("option_base 0x%x\n", dev->option_base); + DLOG("option_size 0x%x\n", dev->option_size); + DLOG("flags %d\n\n", dev->flags); } struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chip_id) { - struct stlink_chipid_params *params = NULL; - for (params = devicelist; params != NULL; params = params->next) - if (params->chip_id == chip_id) { - DLOG("detected chip_id parameters\n\n"); - dump_a_chip(params); - break; - } + struct stlink_chipid_params *params = NULL; + for (params = devicelist; params != NULL; params = params->next) + if (params->chip_id == chip_id) { + DLOG("detected chip_id parameters\n\n"); + dump_a_chip(params); + break; + } - return(params); + return (params); } void process_chipfile(char *fname) { - FILE *fp; - char *p, buf[256]; - char word[64], value[64]; - struct stlink_chipid_params *ts; - int nc; - - // fprintf (stderr, "processing chip-id file %s.\n", fname); - fp = fopen(fname, "r"); - - if (!fp) { - perror(fname); - return; - } - - ts = calloc(sizeof(struct stlink_chipid_params), 1); - - while (fgets(buf, sizeof(buf), fp) != NULL) { - - if (strncmp(buf, "#", strlen("#")) == 0) - continue; // ignore comments - - if ((strncmp(buf, "\n", strlen("\n")) == 0) || - (strncmp(buf, " ", strlen(" ")) == 0)) - continue; // ignore empty lines - - sscanf(buf, "%s %s", word, value); - - if (strcmp (word, "dev_type") == 0) { - buf[strlen(buf) - 1] = 0; // chomp newline - sscanf(buf, "%*s %n", &nc); - ts->dev_type = strdup(buf + nc); - } else if (strcmp(word, "ref_manual_id") == 0) { - buf[strlen(buf) - 1] = 0; // chomp newline - sscanf(buf, "%*s %n", &nc); - ts->ref_manual_id = strdup(buf + nc); - } else if (strcmp(word, "chip_id") == 0) { - buf[strlen(buf) - 1] = 0; // chomp newline - sscanf(buf, "%*s %n", &nc); - if (sscanf(value, "%i", &ts->chip_id) < 1) { - fprintf(stderr, "Failed to parse chip-id\n"); - } - } else if (strcmp(word, "flash_type") == 0) { - buf[strlen(buf) - 1] = 0; // chomp newline - sscanf(buf, "%*s %n", &nc); - if (strcmp(value, "F0_F1_F3") == 0) { - ts->flash_type = STM32_FLASH_TYPE_F0_F1_F3; - } else if (strcmp(value, "F1_XL") == 0) { - ts->flash_type = STM32_FLASH_TYPE_F1_XL; - } else if (strcmp(value, "F2_F4") == 0) { - ts->flash_type = STM32_FLASH_TYPE_F2_F4; - } else if (strcmp(value, "F7") == 0) { - ts->flash_type = STM32_FLASH_TYPE_F7; - } else if (strcmp(value, "G0") == 0) { - ts->flash_type = STM32_FLASH_TYPE_G0; - } else if (strcmp(value, "G4") == 0) { - ts->flash_type = STM32_FLASH_TYPE_G4; - } else if (strcmp(value, "H7") == 0) { - ts->flash_type = STM32_FLASH_TYPE_H7; - } else if (strcmp(value, "L0_L1") == 0) { - ts->flash_type = STM32_FLASH_TYPE_L0_L1; - } else if (strcmp(value, "L4_L4P") == 0) { - ts->flash_type = STM32_FLASH_TYPE_L4; - } else if (strcmp(value, "L5_U5") == 0) { - ts->flash_type = STM32_FLASH_TYPE_L5_U5; - } else if (strcmp(value, "WB_WL") == 0) { - ts->flash_type = STM32_FLASH_TYPE_WB_WL; - } else { - ts->flash_type = STM32_FLASH_TYPE_UNKNOWN; - } - } else if (strcmp(word, "flash_size_reg") == 0) { - buf[strlen(buf) - 1] = 0; // chomp newline - sscanf(buf, "%*s %n", &nc); - if (sscanf(value, "%i", &ts->flash_size_reg) < 1) { - fprintf(stderr, "Failed to parse flash size reg\n"); - } - } else if (strcmp(word, "flash_pagesize") == 0) { - buf[strlen(buf) - 1] = 0; // chomp newline - sscanf(buf, "%*s %n", &nc); - if (sscanf(value, "%i", &ts->flash_pagesize) < 1) { - fprintf(stderr, "Failed to parse flash page size\n"); - } - } else if (strcmp(word, "sram_size") == 0) { - buf[strlen(buf) - 1] = 0; // chomp newline - sscanf(buf, "%*s %n", &nc); - if (sscanf(value, "%i", &ts->sram_size) < 1) { - fprintf(stderr, "Failed to parse SRAM size\n"); - } - } else if (strcmp(word, "bootrom_base") == 0) { - buf[strlen(buf) - 1] = 0; // chomp newline - sscanf(buf, "%*s %n", &nc); - if (sscanf(value, "%i", &ts->bootrom_base) < 1) { - fprintf(stderr, "Failed to parse BootROM base\n"); - } - } else if (strcmp(word, "bootrom_size") == 0) { - buf[strlen(buf) - 1] = 0; // chomp newline - sscanf(buf, "%*s %n", &nc); - if (sscanf(value, "%i", &ts->bootrom_size) < 1) { - fprintf(stderr, "Failed to parse BootROM size\n"); - } - } else if (strcmp(word, "option_base") == 0) { - buf[strlen(buf) - 1] = 0; // chomp newline - sscanf(buf, "%*s %n", &nc); - if (sscanf(value, "%i", &ts->option_base) < 1) { - fprintf(stderr, "Failed to parse option base\n"); - } - } else if (strcmp(word, "option_size") == 0) { - buf[strlen(buf) - 1] = 0; // chomp newline - sscanf(buf, "%*s %n", &nc); - if (sscanf(value, "%i", &ts->option_size) < 1) { - fprintf(stderr, "Failed to parse option size\n"); - } - } else if (strcmp(word, "flags") == 0) { - buf[strlen(buf) - 1] = 0; // chomp newline - sscanf(buf, "%*s %n", &nc); - p = strtok (buf, " \t\n"); - - while ((p = strtok (NULL, " \t\n"))) { - if (strcmp(p, "none") == 0) { - // NOP - } else if (strcmp(p, "dualbank") == 0) { - ts->flags |= CHIP_F_HAS_DUAL_BANK; - } else if (strcmp(p, "swo") == 0) { - ts->flags |= CHIP_F_HAS_SWO_TRACING; - } else { - fprintf(stderr, "Unknown flags word in %s: '%s'\n", - fname, p); - } - } - - sscanf(value, "%x", &ts->flags); + FILE *fp; + char *p, buf[256]; + char word[64], value[64]; + struct stlink_chipid_params *ts; + int nc; + + // fprintf (stderr, "processing chip-id file %s.\n", fname); + fp = fopen(fname, "r"); + + if (!fp) { + perror(fname); + return; + } + + ts = calloc(sizeof(struct stlink_chipid_params), 1); + + while (fgets(buf, sizeof(buf), fp) != NULL) { + + if (strncmp(buf, "#", strlen("#")) == 0) + continue; // ignore comments + + if ((strncmp(buf, "\n", strlen("\n")) == 0) || + (strncmp(buf, " ", strlen(" ")) == 0)) + continue; // ignore empty lines + + sscanf(buf, "%s %s", word, value); + + if (strcmp(word, "dev_type") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + ts->dev_type = strdup(buf + nc); + } else if (strcmp(word, "ref_manual_id") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + ts->ref_manual_id = strdup(buf + nc); + } else if (strcmp(word, "chip_id") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + if (sscanf(value, "%i", &ts->chip_id) < 1) { + fprintf(stderr, "Failed to parse chip-id\n"); + } + } else if (strcmp(word, "flash_type") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + if (strcmp(value, "F0_F1_F3") == 0) { + ts->flash_type = STM32_FLASH_TYPE_F0_F1_F3; + } else if (strcmp(value, "F1_XL") == 0) { + ts->flash_type = STM32_FLASH_TYPE_F1_XL; + } else if (strcmp(value, "F2_F4") == 0) { + ts->flash_type = STM32_FLASH_TYPE_F2_F4; + } else if (strcmp(value, "F7") == 0) { + ts->flash_type = STM32_FLASH_TYPE_F7; + } else if (strcmp(value, "G0") == 0) { + ts->flash_type = STM32_FLASH_TYPE_G0; + } else if (strcmp(value, "G4") == 0) { + ts->flash_type = STM32_FLASH_TYPE_G4; + } else if (strcmp(value, "H7") == 0) { + ts->flash_type = STM32_FLASH_TYPE_H7; + } else if (strcmp(value, "L0_L1") == 0) { + ts->flash_type = STM32_FLASH_TYPE_L0_L1; + } else if (strcmp(value, "L4") == 0) { + ts->flash_type = STM32_FLASH_TYPE_L4; + } else if (strcmp(value, "L5_U5") == 0) { + ts->flash_type = STM32_FLASH_TYPE_L5_U5; + } else if (strcmp(value, "WB_WL") == 0) { + ts->flash_type = STM32_FLASH_TYPE_WB_WL; + } else { + ts->flash_type = STM32_FLASH_TYPE_UNKNOWN; + } + } else if (strcmp(word, "flash_size_reg") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + if (sscanf(value, "%i", &ts->flash_size_reg) < 1) { + fprintf(stderr, "Failed to parse flash size reg\n"); + } + } else if (strcmp(word, "flash_pagesize") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + if (sscanf(value, "%i", &ts->flash_pagesize) < 1) { + fprintf(stderr, "Failed to parse flash page size\n"); + } + } else if (strcmp(word, "sram_size") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + if (sscanf(value, "%i", &ts->sram_size) < 1) { + fprintf(stderr, "Failed to parse SRAM size\n"); + } + } else if (strcmp(word, "bootrom_base") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + if (sscanf(value, "%i", &ts->bootrom_base) < 1) { + fprintf(stderr, "Failed to parse BootROM base\n"); + } + } else if (strcmp(word, "bootrom_size") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + if (sscanf(value, "%i", &ts->bootrom_size) < 1) { + fprintf(stderr, "Failed to parse BootROM size\n"); + } + } else if (strcmp(word, "option_base") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + if (sscanf(value, "%i", &ts->option_base) < 1) { + fprintf(stderr, "Failed to parse option base\n"); + } + } else if (strcmp(word, "option_size") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + if (sscanf(value, "%i", &ts->option_size) < 1) { + fprintf(stderr, "Failed to parse option size\n"); + } + } else if (strcmp(word, "flags") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + p = strtok(buf, " \t\n"); + + while ((p = strtok(NULL, " \t\n"))) { + if (strcmp(p, "none") == 0) { + // NOP + } else if (strcmp(p, "dualbank") == 0) { + ts->flags |= CHIP_F_HAS_DUAL_BANK; + } else if (strcmp(p, "swo") == 0) { + ts->flags |= CHIP_F_HAS_SWO_TRACING; } else { - fprintf(stderr, "Unknown keyword in %s: %s\n", fname, word); + fprintf(stderr, "Unknown flags word in %s: '%s'\n", fname, p); } + } + + sscanf(value, "%x", &ts->flags); + } else { + fprintf(stderr, "Unknown keyword in %s: %s\n", fname, word); } - fclose(fp); - ts->next = devicelist; - devicelist = ts; + } + fclose(fp); + ts->next = devicelist; + devicelist = ts; } #if defined(STLINK_HAVE_DIRENT_H) #include void init_chipids(char *dir_to_scan) { - DIR *d; - size_t nl; // namelen - struct dirent *dir; - - if (!dir_to_scan) { - dir_to_scan = "./"; + DIR *d; + size_t nl; // namelen + struct dirent *dir; + + if (!dir_to_scan) { + dir_to_scan = "./"; + } + + devicelist = NULL; + d = opendir(dir_to_scan); + + if (d) { + while ((dir = readdir(d)) != NULL) { + nl = strlen(dir->d_name); + + if (strcmp(dir->d_name + nl - 5, ".chip") == 0) { + char buf[1024]; + sprintf(buf, "%s/%s", dir_to_scan, dir->d_name); + process_chipfile(buf); + } } - devicelist = NULL; - d = opendir(dir_to_scan); - - if (d) { - while ((dir = readdir(d)) != NULL) { - nl = strlen(dir->d_name); - - if (strcmp(dir->d_name + nl - 5, ".chip") == 0) { - char buf[1024]; - sprintf(buf, "%s/%s", dir_to_scan, dir->d_name); - process_chipfile(buf); - } - } - - closedir(d); - } else { - perror (dir_to_scan); - return; - } + closedir(d); + } else { + perror(dir_to_scan); + return; + } } -#endif //STLINK_HAVE_DIRENT_H +#endif // STLINK_HAVE_DIRENT_H #if defined(_WIN32) && !defined(STLINK_HAVE_DIRENT_H) #include #include void init_chipids(char *dir_to_scan) { - HANDLE hFind = INVALID_HANDLE_VALUE; - WIN32_FIND_DATAA ffd; - char filepath[MAX_PATH] = {0}; + HANDLE hFind = INVALID_HANDLE_VALUE; + WIN32_FIND_DATAA ffd; + char filepath[MAX_PATH] = {0}; + StringCchCopyA(filepath, STLINK_ARRAY_SIZE(filepath), dir_to_scan); + + if (FAILED( + StringCchCatA(filepath, STLINK_ARRAY_SIZE(filepath), "\\*.chip"))) { + ELOG("Path to chips's dir too long.\n"); + return; + } + + hFind = FindFirstFileA(filepath, &ffd); + + if (INVALID_HANDLE_VALUE == hFind) { + ELOG("Can't find any chip description file in %s.\n", filepath); + return; + } + + do { + memset(filepath, 0, STLINK_ARRAY_SIZE(filepath)); StringCchCopyA(filepath, STLINK_ARRAY_SIZE(filepath), dir_to_scan); + StringCchCatA(filepath, STLINK_ARRAY_SIZE(filepath), "\\"); + StringCchCatA(filepath, STLINK_ARRAY_SIZE(filepath), ffd.cFileName); + process_chipfile(filepath); + } while (FindNextFileA(hFind, &ffd) != 0); - if (FAILED(StringCchCatA(filepath, STLINK_ARRAY_SIZE(filepath), "\\*.chip"))) { - ELOG("Path to chips's dir too long.\n"); - return; - } - - hFind = FindFirstFileA(filepath, &ffd); - - if (INVALID_HANDLE_VALUE == hFind) { - ELOG("Can't find any chip description file in %s.\n", filepath); - return; - } - - do { - memset(filepath, 0, STLINK_ARRAY_SIZE(filepath)); - StringCchCopyA(filepath, STLINK_ARRAY_SIZE(filepath), dir_to_scan); - StringCchCatA(filepath, STLINK_ARRAY_SIZE(filepath), "\\"); - StringCchCatA(filepath, STLINK_ARRAY_SIZE(filepath), ffd.cFileName); - process_chipfile(filepath); - } while (FindNextFileA(hFind, &ffd) != 0); - - FindClose(hFind); + FindClose(hFind); } -#endif //defined(_WIN32) && !defined(STLINK_HAVE_DIRENT_H) +#endif // defined(_WIN32) && !defined(STLINK_HAVE_DIRENT_H) From 2ff79959f4a8f17c64ca30552e86f35bf89f0fa0 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 18 Mar 2023 21:19:15 +0100 Subject: [PATCH 1353/1435] Minor fixes & additions - Corrected flash_pagesize for STM32U5 - Updated STM32 core IDs - Added chip-id file for STM32H5 devices --- config/chips/H5xx.chip | 14 ++++++++++ config/chips/U5x5.chip | 2 +- inc/stm32.h | 61 +++++++++++++++++++++-------------------- src/stlink-lib/common.c | 2 +- 4 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 config/chips/H5xx.chip diff --git a/config/chips/H5xx.chip b/config/chips/H5xx.chip new file mode 100644 index 000000000..a1c438999 --- /dev/null +++ b/config/chips/H5xx.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32H5xx device +# +dev_type STM32H5xx +ref_manual_id 0481 +chip_id 0x484 // STM32_CHIPID_H5xx +flash_type L5_U5 // ? +flash_size_reg 0x08fff80c +flash_pagesize 0x2000 // 8 KB +sram_size 0xa0000 // 640 KB +bootrom_base 0x0bf80000 +bootrom_size 0x8000 // 32 KB +option_base 0x0 +option_size 0x0 +flags dualbank diff --git a/config/chips/U5x5.chip b/config/chips/U5x5.chip index be19d04af..5f71436ef 100644 --- a/config/chips/U5x5.chip +++ b/config/chips/U5x5.chip @@ -5,7 +5,7 @@ ref_manual_id 0456 chip_id 0x482 // STM32_CHIPID_U5x5 flash_type L5_U5 flash_size_reg 0x0bfa07a0 -flash_pagesize 0x200000 // 2048 KB +flash_pagesize 0x2000 // 8 KB sram_size 0xc4800 // 786 KB bootrom_base 0x0bf90000 bootrom_size 0x10000 // 64 KB diff --git a/inc/stm32.h b/inc/stm32.h index 8557c9ce7..746f4c0f3 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -9,35 +9,37 @@ /* STM32 Cortex-M core ids (CPUTAPID) */ enum stm32_core_id { - STM32_CORE_ID_M0_SWD = 0x0bb11477, // (RM0091 Section 32.5.3) F0 SW-DP - // (RM0444 Section 40.5.3) G0 SW-DP - STM32_CORE_ID_M0P_SWD = 0x0bc11477, // (RM0385 Section 27.5.3) L0 SW-DP - STM32_CORE_ID_M3_r1p1_SWD = 0x1ba01477, // (RM0008 Section 31.8.3) F1 SW-DP - STM32_CORE_ID_M3_r1p1_JTAG = 0x3ba00477, // (RM0008 Section 31.6.3) F1 JTAG - STM32_CORE_ID_M3_r2p0_SWD = 0x2ba01477, // (RM0033 Section 32.8.3) F2 SW-DP - // (RM0038 Section 30.8.3) L1 SW-DP - STM32_CORE_ID_M3_r2p0_JTAG = 0x0ba00477, // (RM0033 Section 32.6.3) F2 JTAG - // (RM0038 Section 30.6.2) L1 JTAG - STM32_CORE_ID_M4_r0p1_SWD = 0x1ba01477, // (RM0316 Section 33.8.3) F3 SW-DP - // (RM0351 Section 48.8.3) L4 SW-DP - // (RM0432 Section 57.8.3) L4+ SW-DP - STM32_CORE_ID_M4_r0p1_JTAG = 0x4ba00477, // (RM0316 Section 33.6.3) F3 JTAG - // (RM0351 Section 48.6.3) L4 JTAG - // (RM0432 Section 57.6.3) L4+ JTAG - STM32_CORE_ID_M4F_r0p1_SWD = 0x2ba01477, // (RM0090 Section 38.8.3) F4 SW-DP - // (RM0090 Section 47.8.3) G4 SW-DP - STM32_CORE_ID_M4F_r0p1_JTAG = 0x4ba00477, // (RM0090 Section 38.6.3) F4 JTAG - // (RM0090 Section 47.6.3) G4 JTAG - STM32_CORE_ID_M7F_SWD = 0x5ba02477, // (RM0385 Section 40.8.3) F7 SW-DP - STM32_CORE_ID_M7F_JTAG = 0x5ba00477, // (RM0385 Section 40.6.3) F7 JTAG - STM32_CORE_ID_M7F_H7_SWD = 0x6ba02477, // (RM0433 Section 60.4.1) H7 SW-DP - STM32_CORE_ID_M7F_H7_JTAG = 0x6ba00477, // (RM0433 Section 60.4.1) H7 JTAG - STM32_CORE_ID_M33_SWD = 0x0be02477, // (RM0438 Section 52.2.10) L5 SW-DP - // (RM0456 Section 65.3.3) U5 SW-DP - STM32_CORE_ID_M33_JTAGD = 0x0be01477, // (RM0438 Section 52.2.10) L5 JTAG-DP - // (RM0456 Section 65.3.3) U5 JTAG-DP - STM32_CORE_ID_M33_JTAG = 0x0ba04477, // (RM0438 Section 52.2.8) L5 JTAG - // (RM0456 Section 56.3.1) U5 JTAG + STM32_CORE_ID_M0_SWD = 0x0bb11477, // (RM0091 Section 32.5.3) F0 SW-DP + // (RM0444 Section 40.5.3) G0 SW-DP + STM32_CORE_ID_M0P_SWD = 0x0bc11477, // (RM0385 Section 27.5.3) L0 SW-DP + STM32_CORE_ID_M3_r1p1_SWD = 0x1ba01477, // (RM0008 Section 31.8.3) F1 SW-DP + STM32_CORE_ID_M3_r1p1_JTAG = 0x3ba00477, // (RM0008 Section 31.6.3) F1 JTAG + STM32_CORE_ID_M3_r2p0_SWD = 0x2ba01477, // (RM0033 Section 32.8.3) F2 SW-DP + // (RM0038 Section 30.8.3) L1 SW-DP + STM32_CORE_ID_M3_r2p0_JTAG = 0x0ba00477, // (RM0033 Section 32.6.3) F2 JTAG + // (RM0038 Section 30.6.2) L1 JTAG + STM32_CORE_ID_M4_r0p1_SWD = 0x1ba01477, // (RM0316 Section 33.8.3) F3 SW-DP + // (RM0351 Section 48.8.3) L4 SW-DP + // (RM0432 Section 57.8.3) L4+ SW-DP + STM32_CORE_ID_M4_r0p1_JTAG = 0x4ba00477, // (RM0316 Section 33.6.3) F3 JTAG + // (RM0351 Section 48.6.3) L4 JTAG + // (RM0432 Section 57.6.3) L4+ JTAG + STM32_CORE_ID_M4F_r0p1_SWD = 0x2ba01477, // (RM0090 Section 38.8.3) F4 SW-DP + // (RM0090 Section 47.8.3) G4 SW-DP + STM32_CORE_ID_M4F_r0p1_JTAG = 0x4ba00477, // (RM0090 Section 38.6.3) F4 JTAG + // (RM0090 Section 47.6.3) G4 JTAG + STM32_CORE_ID_M7F_SWD = 0x5ba02477, // (RM0385 Section 40.8.3) F7 SW-DP + STM32_CORE_ID_M7F_JTAG = 0x5ba00477, // (RM0385 Section 40.6.3) F7 JTAG + STM32_CORE_ID_M7F_M33_SWD = 0x6ba02477, // (RM0481 Section 58.3.3) H5 SW-DP + // (RM0433 Section 60.4.1) H7 SW-DP + STM32_CORE_ID_M7F_M33_JTAG = 0x6ba00477, // (RM0481 Section 58.3.1) H5 JTAG + // (RM0433 Section 60.4.1) H7 SW-DP + STM32_CORE_ID_M33_SWD = 0x0be02477, // (RM0438 Section 52.2.10) L5 SW-DP + // (RM0456 Section 65.3.3) U5 SW-DP + STM32_CORE_ID_M33_JTAGD = 0x0be01477, // (RM0438 Section 52.2.10) L5 JTAG-DP + // (RM0456 Section 65.3.3) U5 JTAG-DP + STM32_CORE_ID_M33_JTAG = 0x0ba04477, // (RM0438 Section 52.2.8) L5 JTAG + // (RM0456 Section 56.3.1) U5 JTAG }; /* STM32 flash types */ @@ -122,6 +124,7 @@ enum stm32_chipids { STM32_CHIPID_H7Ax = 0x480, /* RM0455, p.2863 */ STM32_CHIPID_U5x5 = 0x482, /* RM0456, p.2991 */ STM32_CHIPID_H72x = 0x483, /* RM0468, p.3199 */ + STM32_CHIPID_H5xx = 0x484, /* RM0481, p.3085 */ STM32_CHIPID_WB55 = 0x495, STM32_CHIPID_WLE = 0x497, }; diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index cb037fb2f..65d292235 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -140,7 +140,7 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { * DBGMCU_IDCODE / DBG_IDCODE name */ - if ((sl->core_id == STM32_CORE_ID_M7F_H7_SWD || sl->core_id == STM32_CORE_ID_M7F_H7_JTAG) && + if ((sl->core_id == STM32_CORE_ID_M7F_M33_SWD || sl->core_id == STM32_CORE_ID_M7F_M33_JTAG) && cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) ret = stlink_read_debug32(sl, 0x5c001000, chip_id); From 186e38a0faac5f546f8b378e625ebe177baf281d Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 18 Mar 2023 21:53:27 +0100 Subject: [PATCH 1354/1435] Minor fixes & additions - [doc] Update on OS version support - Minor fixes for G0-series from #1293 - [doc] Added core-IDs for WB/WL-series - [doc] Correction for G0/L0-series core-IDs - Set option_size to 128 B for G0-series (#1194) --- config/chips/F401xD_xE.chip | 4 +- config/chips/F446.chip | 2 +- config/chips/G03x_G04x.chip | 2 +- config/chips/G05x_G06x.chip | 6 +-- config/chips/G07x_G08x.chip | 4 +- config/chips/G0Bx_G0Cx.chip | 6 +-- doc/version_support.md | 60 ++++++++++++++--------------- inc/stm32.h | 72 ++++++++++++++++++----------------- src/stlink-lib/common.c | 3 +- src/stlink-lib/option_bytes.c | 9 ++--- 10 files changed, 83 insertions(+), 85 deletions(-) diff --git a/config/chips/F401xD_xE.chip b/config/chips/F401xD_xE.chip index f817175f4..e90f4a78e 100644 --- a/config/chips/F401xD_xE.chip +++ b/config/chips/F401xD_xE.chip @@ -9,6 +9,6 @@ flash_pagesize 0x4000 // 16 KB sram_size 0x18000 // 96 KB bootrom_base 0x1fff0000 bootrom_size 0x7800 // 30 KB -option_base 0x40023C14 -option_size 0x4 +option_base 0x40023C14 // STM32_F4_OPTION_BYTES_BASE +option_size 0x4 // 4 B flags swo diff --git a/config/chips/F446.chip b/config/chips/F446.chip index e4d0bdec2..25f22d9b6 100644 --- a/config/chips/F446.chip +++ b/config/chips/F446.chip @@ -10,5 +10,5 @@ sram_size 0x20000 // 128 KB bootrom_base 0x1fff0000 bootrom_size 0x7800 // 30 KB option_base 0x40023c14 // STM32_F4_OPTION_BYTES_BASE -option_size 0x4 // 4 B +option_size 0x10 // 16 B flags swo diff --git a/config/chips/G03x_G04x.chip b/config/chips/G03x_G04x.chip index a414b52ab..2010940c7 100644 --- a/config/chips/G03x_G04x.chip +++ b/config/chips/G03x_G04x.chip @@ -10,5 +10,5 @@ sram_size 0x2000 // 8 KB bootrom_base 0x1fff0000 bootrom_size 0x2000 // 8 KB option_base 0x1fff7800 // STM32_G0_OPTION_BYTES_BASE -option_size 0x4 // 4 B +option_size 0x80 // 128 B flags none diff --git a/config/chips/G05x_G06x.chip b/config/chips/G05x_G06x.chip index ae074e584..ba556b53a 100644 --- a/config/chips/G05x_G06x.chip +++ b/config/chips/G05x_G06x.chip @@ -1,14 +1,14 @@ # Chip-ID file for STM32G05x / STM32G06x device # dev_type STM32G05x_G06x -ref_manual_id 0444 +ref_manual_id 0444 // also RM454 chip_id 0x456 // STM32_CHIPID_G0_CAT4 flash_type G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB -sram_size 0x9000 // 36 KB +sram_size 0x4800 // 18 KB bootrom_base 0x1fff0000 bootrom_size 0x7000 // 28 KB option_base 0x1fff7800 // STM32_G0_OPTION_BYTES_BASE -option_size 0x4 // 4 B +option_size 0x80 // 128 B flags none diff --git a/config/chips/G07x_G08x.chip b/config/chips/G07x_G08x.chip index 82b3992c2..60a6bec7a 100644 --- a/config/chips/G07x_G08x.chip +++ b/config/chips/G07x_G08x.chip @@ -1,7 +1,7 @@ # Chip-ID file for STM32G07x / STM32G08x device # dev_type STM32G07x_G08x -ref_manual_id 0444 +ref_manual_id 0444 // also RM454 chip_id 0x460 // STM32_CHIPID_G0_CAT2 flash_type G0 flash_size_reg 0x1fff75e0 @@ -10,5 +10,5 @@ sram_size 0x9000 // 36 KB bootrom_base 0x1fff0000 bootrom_size 0x7000 // 28 KB option_base 0x1fff7800 // STM32_G0_OPTION_BYTES_BASE -option_size 0x4 // 4 B +option_size 0x80 // 128 B flags none diff --git a/config/chips/G0Bx_G0Cx.chip b/config/chips/G0Bx_G0Cx.chip index f21fd65a0..a9bae1f08 100644 --- a/config/chips/G0Bx_G0Cx.chip +++ b/config/chips/G0Bx_G0Cx.chip @@ -1,14 +1,14 @@ # Chip-ID file for STM32G0Bx / STM32G0Cx device # dev_type STM32G0Bx_G0Cx -ref_manual_id 0444 +ref_manual_id 0444 // also RM454 chip_id 0x467 // STM32_CHIPID_G0_CAT3 flash_type G0 flash_size_reg 0x1fff75e0 flash_pagesize 0x800 // 2 KB -sram_size 0x9000 // 36 KB +sram_size 0x24000 // 144 KB bootrom_base 0x1fff0000 bootrom_size 0x7000 // 28 KB option_base 0x1fff7800 // STM32_G0_OPTION_BYTES_BASE -option_size 0x4 // 4 B +option_size 0x80 // 128 B flags dualbank diff --git a/doc/version_support.md b/doc/version_support.md index 593c86549..e7d8f444b 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -59,43 +59,41 @@ Other Linux-/Unix-based Operating Systems: | Solus [x64] | 1.0.24 | 3.22.1 | 3.24.30 | | | Void Linux | 1.0.24 | 3.22.1 | 3.24.31 | | | Slackware Current | 1.0.24 | 3.21.4 | 3.24.31 | | -| AlmaLinux 8 | 1.0.23 (`libusbx`) | 3.20.2 | 3.**22.30** | | -| Rocky Linux 8 [x64] | 1.0.23 | 3.20.2 | 3.**22.30** | | | Adélie 1.0 | 1.0.23 | 3.**16.4** | 3.24.23 | | ## Unsupported Operating Systems (as of Release v1.7.1) Systems with highlighted versions remain compatible with this toolset. -| Operating System | libusb | cmake | End of
      OS-Support | -| ------------------------- | ------------------------------ | ---------- | ---------------------- | -| Fedora 35 [x64] | 1.0.**24** | 3.**21.3** | Dec 2022 | -| CentOS 8 [x64] | 1.0.**23** (`libusbx`) | 3.**20.3** | Dec 2021 | -| Fedora 34 [x64] | 1.0.**24** (`libusbx`) | 3.**19.7** | Jun 2022 | -| Mageia 8 | 1.0.**24** | 3.**19.2** | Aug 2022 | -| Alpine 3.13 | 1.0.**24** | 3.**18.4** | Nov 2022 | -| Ubuntu 21.04 (Hirsute) | 1.0.**24** | 3.**18.4** | Jan 2022 | -| Fedora 33 [x64] | 1.0.**23** (`libusbx`) | 3.**18.3** | Nov 2021 | -| Alpine 3.12 | 1.0.**23** | 3.**17.2** | May 2022 | -| openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.**17.0** | Dec 2022 | -| Fedora 32 [x64] | 1.0.**23** (`libusbx`) | 3.**17.0** | May 2021 | -| openSUSE Leap 15.2 [x64] | 1.0.**21** | 3.**17.0** | Dec 2021 | -| Ubuntu 20.10 (Groovy) | 1.0.**23** | 3.**16.3** | Jul 2021 | -| NetBSD 7.x | 1.0.**22** | 3.**16.1** | Jun 2020 | -| Alpine 3.11 | 1.0.**23** | 3.**15.5** | Nov 2021 | -| FreeBSD 11.x | 1.0.**16-18** (API 0x01000102) | 3.**15.5** | Sep 2021 | -| Alpine 3.10 | 1.0.**22** | 3.**14.5** | May 2021 | -| Fedora 31 [x64] | 1.0.**22**(`libusbx`) | 3.**14.5** | Nov 2020 | -| Mageia 7.1 | 1.0.**22** | 3.**14.3** | Jun 2021 | -| Fedora 30 | 1.0.**22**(`libusbx`) | 3.**14.2** | May 2020 | -| Ubuntu 19.10 (Eoan) | 1.0.**23** | 3.**13.4** | Jul 2020 | -| Alpine 3.9 | 1.0.**22** | 3.**13.0** | Jan 2021 | -| Ubuntu 18.04 LTS (Bionic) | 1.0.**21** | 3.**10.2** | **Apr 2023** | -| openSUSE Leap 15.1 [x64] | 1.0.**21** | 3.**10.2** | Jan 2021 | -| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | Jun 2022 | -| Slackware 14.2 | 1.0.20 | 3.5.2 | | -| OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | | -| CentOS 7 [x64] | 1.0.21 (`libusbx`) | 2.8.12.2 | Jun 2024 | +| Operating System | libusb | cmake | End of
      OS-Support | +| ---------------------------------------- | ------------------------------ | ---------- | ---------------------- | +| Fedora 35 [x64] | 1.0.**24** | 3.**21.3** | Dec 2022 | +| CentOS / Rocky Linux / AlmaLinux 8 [x64] | 1.0.**23** (`libusbx`) | 3.**20.3** | Dec 2021 | +| Fedora 34 [x64] | 1.0.**24** (`libusbx`) | 3.**19.7** | Jun 2022 | +| Mageia 8 | 1.0.**24** | 3.**19.2** | Aug 2022 | +| Alpine 3.13 | 1.0.**24** | 3.**18.4** | Nov 2022 | +| Ubuntu 21.04 (Hirsute) | 1.0.**24** | 3.**18.4** | Jan 2022 | +| Fedora 33 [x64] | 1.0.**23** (`libusbx`) | 3.**18.3** | Nov 2021 | +| Alpine 3.12 | 1.0.**23** | 3.**17.2** | May 2022 | +| openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.**17.0** | Dec 2022 | +| Fedora 32 [x64] | 1.0.**23** (`libusbx`) | 3.**17.0** | May 2021 | +| openSUSE Leap 15.2 [x64] | 1.0.**21** | 3.**17.0** | Dec 2021 | +| Ubuntu 20.10 (Groovy) | 1.0.**23** | 3.**16.3** | Jul 2021 | +| NetBSD 7.x | 1.0.**22** | 3.**16.1** | Jun 2020 | +| Alpine 3.11 | 1.0.**23** | 3.**15.5** | Nov 2021 | +| FreeBSD 11.x | 1.0.**16-18** (API 0x01000102) | 3.**15.5** | Sep 2021 | +| Alpine 3.10 | 1.0.**22** | 3.**14.5** | May 2021 | +| Fedora 31 [x64] | 1.0.**22**(`libusbx`) | 3.**14.5** | Nov 2020 | +| Mageia 7.1 | 1.0.**22** | 3.**14.3** | Jun 2021 | +| Fedora 30 | 1.0.**22**(`libusbx`) | 3.**14.2** | May 2020 | +| Ubuntu 19.10 (Eoan) | 1.0.**23** | 3.**13.4** | Jul 2020 | +| Alpine 3.9 | 1.0.**22** | 3.**13.0** | Jan 2021 | +| Ubuntu 18.04 LTS (Bionic) | 1.0.**21** | 3.**10.2** | **Apr 2023** | +| openSUSE Leap 15.1 [x64] | 1.0.**21** | 3.**10.2** | Jan 2021 | +| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | Jun 2022 | +| Slackware 14.2 | 1.0.20 | 3.5.2 | | +| OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | | +| CentOS / Rocky Linux / AlmaLinux 7 [x64] | 1.0.21 (`libusbx`) | 2.8.12.2 | Jun 2024 | _All other operating systems which are not listed are unsupported._ diff --git a/inc/stm32.h b/inc/stm32.h index 746f4c0f3..92770bd44 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -9,37 +9,41 @@ /* STM32 Cortex-M core ids (CPUTAPID) */ enum stm32_core_id { - STM32_CORE_ID_M0_SWD = 0x0bb11477, // (RM0091 Section 32.5.3) F0 SW-DP - // (RM0444 Section 40.5.3) G0 SW-DP - STM32_CORE_ID_M0P_SWD = 0x0bc11477, // (RM0385 Section 27.5.3) L0 SW-DP - STM32_CORE_ID_M3_r1p1_SWD = 0x1ba01477, // (RM0008 Section 31.8.3) F1 SW-DP - STM32_CORE_ID_M3_r1p1_JTAG = 0x3ba00477, // (RM0008 Section 31.6.3) F1 JTAG - STM32_CORE_ID_M3_r2p0_SWD = 0x2ba01477, // (RM0033 Section 32.8.3) F2 SW-DP - // (RM0038 Section 30.8.3) L1 SW-DP - STM32_CORE_ID_M3_r2p0_JTAG = 0x0ba00477, // (RM0033 Section 32.6.3) F2 JTAG - // (RM0038 Section 30.6.2) L1 JTAG - STM32_CORE_ID_M4_r0p1_SWD = 0x1ba01477, // (RM0316 Section 33.8.3) F3 SW-DP - // (RM0351 Section 48.8.3) L4 SW-DP - // (RM0432 Section 57.8.3) L4+ SW-DP - STM32_CORE_ID_M4_r0p1_JTAG = 0x4ba00477, // (RM0316 Section 33.6.3) F3 JTAG - // (RM0351 Section 48.6.3) L4 JTAG - // (RM0432 Section 57.6.3) L4+ JTAG - STM32_CORE_ID_M4F_r0p1_SWD = 0x2ba01477, // (RM0090 Section 38.8.3) F4 SW-DP - // (RM0090 Section 47.8.3) G4 SW-DP - STM32_CORE_ID_M4F_r0p1_JTAG = 0x4ba00477, // (RM0090 Section 38.6.3) F4 JTAG - // (RM0090 Section 47.6.3) G4 JTAG - STM32_CORE_ID_M7F_SWD = 0x5ba02477, // (RM0385 Section 40.8.3) F7 SW-DP - STM32_CORE_ID_M7F_JTAG = 0x5ba00477, // (RM0385 Section 40.6.3) F7 JTAG - STM32_CORE_ID_M7F_M33_SWD = 0x6ba02477, // (RM0481 Section 58.3.3) H5 SW-DP - // (RM0433 Section 60.4.1) H7 SW-DP - STM32_CORE_ID_M7F_M33_JTAG = 0x6ba00477, // (RM0481 Section 58.3.1) H5 JTAG - // (RM0433 Section 60.4.1) H7 SW-DP - STM32_CORE_ID_M33_SWD = 0x0be02477, // (RM0438 Section 52.2.10) L5 SW-DP - // (RM0456 Section 65.3.3) U5 SW-DP - STM32_CORE_ID_M33_JTAGD = 0x0be01477, // (RM0438 Section 52.2.10) L5 JTAG-DP - // (RM0456 Section 65.3.3) U5 JTAG-DP - STM32_CORE_ID_M33_JTAG = 0x0ba04477, // (RM0438 Section 52.2.8) L5 JTAG - // (RM0456 Section 56.3.1) U5 JTAG + STM32_CORE_ID_M0_SWD = 0x0bb11477, // (RM0091 Section 32.5.3) F0 SW-DP + STM32_CORE_ID_M0P_SWD = 0x0bc11477, // (RM0444 Section 40.5.3) G0 SW-DP + // (RM0377 Section 27.5.3) L0 SW-DP + STM32_CORE_ID_M3_r1p1_SWD = 0x1ba01477, // (RM0008 Section 31.8.3) F1 SW-DP + STM32_CORE_ID_M3_r1p1_JTAG = 0x3ba00477, // (RM0008 Section 31.6.3) F1 JTAG + STM32_CORE_ID_M3_r2p0_SWD = 0x2ba01477, // (RM0033 Section 32.8.3) F2 SW-DP + // (RM0038 Section 30.8.3) L1 SW-DP + STM32_CORE_ID_M3_r2p0_JTAG = 0x0ba00477, // (RM0033 Section 32.6.3) F2 JTAG + // (RM0038 Section 30.6.2) L1 JTAG + STM32_CORE_ID_M4_r0p1_SWD = 0x1ba01477, // (RM0316 Section 33.8.3) F3 SW-DP + // (RM0351 Section 48.8.3) L4 SW-DP + // (RM0432 Section 57.8.3) L4+ SW-DP + STM32_CORE_ID_M4_r0p1_JTAG = 0x4ba00477, // (RM0316 Section 33.6.3) F3 JTAG + // (RM0351 Section 48.6.3) L4 JTAG + // (RM0432 Section 57.6.3) L4+ JTAG + STM32_CORE_ID_M4F_r0p1_SWD = 0x2ba01477, // (RM0090 Section 38.8.3) F4 SW-DP + // (RM0090 Section 47.8.3) G4 SW-DP + STM32_CORE_ID_M4F_r0p1_JTAG = 0x4ba00477, // (RM0090 Section 38.6.3) F4 JTAG + // (RM0090 Section 47.6.3) G4 JTAG + STM32_CORE_ID_M7F_SWD = 0x5ba02477, // (RM0385 Section 40.8.3) F7 SW-DP + // (RM0473 Section 33.4.4) WB SW-DP + // (RM0453 Section 38.4.1) WL SW-DP + STM32_CORE_ID_M7F_JTAG = 0x5ba00477, // (RM0385 Section 40.6.3) F7 JTAG + STM32_CORE_ID_M7F_M33_SWD = 0x6ba02477, // (RM0481 Section 58.3.3) H5 SW-DP + // (RM0433 Section 60.4.1) H7 SW-DP + STM32_CORE_ID_M7F_M33_JTAG = 0x6ba00477, // (RM0481 Section 58.3.1) H5 JTAG + // (RM0433 Section 60.4.1) H7 JTAG + // (RM0473 Section 33.4.1) WB JTAG + // (RM0453 Section 38.3.8) WL JTAG + STM32_CORE_ID_M33_SWD = 0x0be02477, // (RM0438 Section 52.2.10) L5 SW-DP + // (RM0456 Section 65.3.3) U5 SW-DP + STM32_CORE_ID_M33_JTAGD = 0x0be01477, // (RM0438 Section 52.2.10) L5 JTAG-DP + // (RM0456 Section 65.3.3) U5 JTAG-DP + STM32_CORE_ID_M33_JTAG = 0x0ba04477, // (RM0438 Section 52.2.8) L5 JTAG + // (RM0456 Section 56.3.1) U5 JTAG }; /* STM32 flash types */ @@ -108,13 +112,13 @@ enum stm32_chipids { STM32_CHIPID_G0_CAT4 = 0x456, /* G051/G061 */ STM32_CHIPID_L011 = 0x457, STM32_CHIPID_F410 = 0x458, - STM32_CHIPID_G0_CAT2 = 0x460, /* G070/G071/G081 */ + STM32_CHIPID_G0_CAT2 = 0x460, /* G07x/G08x */ STM32_CHIPID_L496x_L4A6x = 0x461, STM32_CHIPID_L45x_L46x = 0x462, STM32_CHIPID_F413 = 0x463, STM32_CHIPID_L41x_L42x = 0x464, - STM32_CHIPID_G0_CAT1 = 0x466, /* G030/G031/G041 */ - STM32_CHIPID_G0_CAT3 = 0x467, /* G0B1/G0C1 */ + STM32_CHIPID_G0_CAT1 = 0x466, /* G03x/G04x */ + STM32_CHIPID_G0_CAT3 = 0x467, /* G0Bx/G0Cx */ STM32_CHIPID_G4_CAT2 = 0x468, /* RM0440, section 46.6.1 "MCU device ID code" */ STM32_CHIPID_G4_CAT3 = 0x469, STM32_CHIPID_L4Rx = 0x470, /* RM0432, p.2247, found on the STM32L4R9I-DISCO board */ diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index 65d292235..ccce342a4 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -279,8 +279,7 @@ int stlink_load_device_params(stlink_t *sl) { // medium and low devices have the same chipid. ram size depends on flash // size. STM32F100xx datasheet Doc ID 16455 Table 2 - if (sl->chip_id == STM32_CHIPID_F1_VL_MD_LD && - sl->flash_size < 64 * 1024) { + if (sl->chip_id == STM32_CHIPID_F1_VL_MD_LD && sl->flash_size < 64 * 1024) { sl->sram_size = 0x1000; } diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c index 2d4898001..32becc5cf 100644 --- a/src/stlink-lib/option_bytes.c +++ b/src/stlink-lib/option_bytes.c @@ -242,8 +242,7 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, stm32_addr_t addr, uint8_t int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t *option_byte) { int err = -1; for (uint32_t counter = 0; counter < (sl->option_size / 4 - 1); counter++) { - err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), - option_byte); + err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), option_byte); if (err == -1) { return err; } else { @@ -272,8 +271,7 @@ static int stlink_write_option_bytes_f7(stlink_t *sl, stm32_addr_t addr, uint8_t // Clear errors clear_flash_error(sl); - ILOG("Asked to write option byte %#10x to %#010x.\n", *(uint32_t *)(base), - addr); + ILOG("Asked to write option byte %#10x to %#010x.\n", *(uint32_t *)(base), addr); write_uint32((unsigned char *)&option_byte, *(uint32_t *)(base)); ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); @@ -306,8 +304,7 @@ static int stlink_write_option_bytes_f7(stlink_t *sl, stm32_addr_t addr, uint8_t ret = check_flash_error(sl); if (!ret) - ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t *)base, - addr); + ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t *)base, addr); /* option bytes are reloaded at reset only, no obl. */ From 21633df34ae0bf4a0f9aae3ad5271965160b40f8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 19 Mar 2023 15:43:37 +0100 Subject: [PATCH 1355/1435] Minor compilation fixes - Corrected install path for gui executable - Changed directory for chip-id files --- CMakeLists.txt | 4 ++-- src/stlink-gui/CMakeLists.txt | 9 +-------- src/stlink-lib/flashloader.c | 3 +-- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d8bce8cf..4ce0ee126 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,8 +78,8 @@ include(GNUInstallDirs) # Define GNU standard installation directories cmake_host_system_information(RESULT OS_NAME QUERY OS_NAME) message(STATUS "Checking for OS_NAME: ${OS_NAME}") -message(STATUS "set(CMAKE_INSTALL_SHAREDIR /usr/share)") -set(CMAKE_INSTALL_SHAREDIR /usr/share/) +message(STATUS "set(CMAKE_INSTALL_SHAREDIR /usr/local/share)") +set(CMAKE_INSTALL_SHAREDIR /usr/local/share/) ## Set C build flags diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index d2edf0d9f..fb4478bdc 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -24,19 +24,12 @@ if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) set(GUI_SOURCES gui.c gui.h) - ## stlink-gui-local - add_executable(stlink-gui-local ${GUI_SOURCES}) - file(COPY stlink-gui.ui DESTINATION ${CMAKE_BINARY_DIR}/bin) - set_target_properties(stlink-gui-local PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_BINARY_DIR}/bin") - target_link_libraries(stlink-gui-local ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) - ## stlink-gui add_executable(stlink-gui ${GUI_SOURCES}) install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_SHAREDIR}/${PROJECT_NAME}) set_target_properties(stlink-gui PROPERTIES COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_SHAREDIR}/${PROJECT_NAME}") target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) - install(TARGETS stlink-gui DESTINATION ${CMAKE_INSTALL_SHAREDIR}/${PROJECT_NAME}) + install(TARGETS stlink-gui DESTINATION ${CMAKE_BINDIR}) endif () endif () diff --git a/src/stlink-lib/flashloader.c b/src/stlink-lib/flashloader.c index 7164983cd..4adf93a86 100644 --- a/src/stlink-lib/flashloader.c +++ b/src/stlink-lib/flashloader.c @@ -51,8 +51,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, } if (sl->verbose >= 1) { - // show progress; writing procedure is slow and previous errors are - // misleading + // show progress; writing procedure is slow and previous errors are misleading fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); fflush(stdout); } From e93fa5798bfc247faa9ae55e217286f0491d2602 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 19 Mar 2023 18:46:22 +0100 Subject: [PATCH 1356/1435] Updated CHANGELOG.md --- CHANGELOG.md | 17 +++++++++++------ src/st-flash/flash.c | 7 +++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddd795c37..551a4ba09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,7 @@ Features: Updates & changes: - [refactoring] Moved chip-specific parameters into separate files ([#237](https://github.com/stlink-org/stlink/pull/237), [#1129](https://github.com/stlink-org/stlink/pull/1129)) -- [refactoring] General maintenance for code structure ([#903](https://github.com/stlink-org/stlink/pull/903), [#1090](https://github.com/stlink-org/stlink/pull/1090), [#1199](https://github.com/stlink-org/stlink/pull/1199), [#1212](https://github.com/stlink-org/stlink/pull/1212), [#1216](https://github.com/stlink-org/stlink/pull/1216)) +- [refactoring] General maintenance for code structure ([#903](https://github.com/stlink-org/stlink/pull/903), [#1090](https://github.com/stlink-org/stlink/pull/1090), [#1199](https://github.com/stlink-org/stlink/pull/1199), [#1212](https://github.com/stlink-org/stlink/pull/1212), [#1216](https://github.com/stlink-org/stlink/pull/1216), [#1228](https://github.com/stlink-org/stlink/pull/1228)) - Added instructions for bug-reports and feature-requests to contribution guidelines ([#906](https://github.com/stlink-org/stlink/pull/906)) - Added travis CI configuration for macOS 10.14 to maintain capability for 32-bit compilation (commit [#f5ada94](https://github.com/stlink-org/stlink/commit/f5ada9474cdb87ff37de0d4eb9e75622b5870646)) - Updated description of chip id 0x0457 to L01x/L02x ([#1143](https://github.com/stlink-org/stlink/pull/1143), [#1144](https://github.com/stlink-org/stlink/pull/1144)) @@ -44,9 +44,12 @@ Updates & changes: - [refactoring] Sourcefile 'common.c' ([#1218](https://github.com/stlink-org/stlink/pull/1218), [#1220](https://github.com/stlink-org/stlink/pull/1220)) - Set C standard through cmake variables ([#1221](https://github.com/stlink-org/stlink/pull/1221)) - [doc] Added make install to the macOS compiling instructions ([#1259](https://github.com/stlink-org/stlink/pull/1259)) -- [doc] Linux Install from code Documentation improvement ([#1263](https://github.com/stlink-org/stlink/pull/1263), (commit [#43498de](https://github.com/stlink-org/stlink/commit/43498dedf651260ef34197e512d35e3ad7142401)) +- [doc] Linux Install from code Documentation improvement ([#1263](https://github.com/stlink-org/stlink/pull/1263), commit [#43498de](https://github.com/stlink-org/stlink/commit/43498dedf651260ef34197e512d35e3ad7142401)) +- End of support for macOS ([#1269](https://github.com/stlink-org/stlink/pull/1269), [#1296](https://github.com/stlink-org/stlink/pull/1296), commit [#61ff09e](https://github.com/stlink-org/stlink/commit/61ff09e5274d46a46ae58bc4ffe44fe90a887ea6)) +- [doc] Added device ID for GD32F303VET6 ([#1288](https://github.com/stlink-org/stlink/pull/1288)) Fixes: + - cmake: Install shared libraries in proper directories ([#1098](https://github.com/stlink-org/stlink/pull/1098), [#1138](https://github.com/stlink-org/stlink/pull/1138), [#1154](https://github.com/stlink-org/stlink/pull/1154)) - cmake: Install shared libraries in proper directories ([#1142](https://github.com/stlink-org/stlink/pull/1142)) - Fixed clearance of the H7 dual bank flag ([#1146](https://github.com/stlink-org/stlink/pull/1146), [#1147](https://github.com/stlink-org/stlink/pull/1147)) @@ -64,13 +67,15 @@ Fixes: - Define 'SSIZE_MAX' if not defined ([#1183](https://github.com/stlink-org/stlink/pull/1183)) - Fixed compliation for OpenBSD 7.0 ([#1202](https://github.com/stlink-org/stlink/pull/1202)) - Included 'SSIZE_MAX' from 'limits.h' in 'src/common.c' ([#1207](https://github.com/stlink-org/stlink/pull/1207)) -- Fix for libusb_kernel_driver_active & error handling for st.st_size () ([#1210](https://github.com/stlink-org/stlink/pull/1210), [#1211](https://github.com/stlink-org/stlink/pull/1211), [#1214](https://github.com/stlink-org/stlink/pull/1214) +- Fix for libusb_kernel_driver_active & error handling for st.st_size () ([#1210](https://github.com/stlink-org/stlink/pull/1210), [#1211](https://github.com/stlink-org/stlink/pull/1211), [#1214](https://github.com/stlink-org/stlink/pull/1214)) +- General fixes and improvements ([#1240](https://github.com/stlink-org/stlink/pull/1240), [#1242](https://github.com/stlink-org/stlink/pull/1242), [#1290](https://github.com/stlink-org/stlink/pull/1290), [#1291](https://github.com/stlink-org/stlink/pull/1291), [#1295](https://github.com/stlink-org/stlink/pull/1295)) +- Fixes for project compilation ([#1241](https://github.com/stlink-org/stlink/pull/1241), [#1271](https://github.com/stlink-org/stlink/pull/1271), [#1283](https://github.com/stlink-org/stlink/pull/1283), [#1286](https://github.com/stlink-org/stlink/pull/1286),commit [#f93adb9](https://github.com/stlink-org/stlink/commit/f93adb92f2e4ecf05a9361cb723c98693586929d)) - st-trace: Fixed clock issues ([#1248](https://github.com/stlink-org/stlink/pull/1248), [#1251](https://github.com/stlink-org/stlink/pull/1251), [#1252](https://github.com/stlink-org/stlink/pull/1252)) - Fixed compilation with gcc-12 ([#1257](https://github.com/stlink-org/stlink/pull/1257), [#1267](https://github.com/stlink-org/stlink/pull/1267)) - Fixed flash regs addr for STM32L152RET6 in common_flash.c ([#1265](https://github.com/stlink-org/stlink/pull/1265)) - Fixed flash, dbgmcu and rcc registers for STM32L1 ([#1266](https://github.com/stlink-org/stlink/pull/1266)) -- Fixed compilation with gcc-12 ([#1257](https://github.com/stlink-org/stlink/pull/1257), [#1267](https://github.com/stlink-org/stlink/pull/1267)) -- Fixes for project compilation ([#1270](https://github.com/stlink-org/stlink/pull/1270), [#1271](https://github.com/stlink-org/stlink/pull/1271), [#1283](https://github.com/stlink-org/stlink/pull/1283), [#1286](https://github.com/stlink-org/stlink/pull/1286),commit [#f93adb9](https://github.com/stlink-org/stlink/commit/f93adb92f2e4ecf05a9361cb723c98693586929d)) +- Fixed incorrect SRAM size for L496x and L4A6x ([#1268](https://github.com/stlink-org/stlink/pull/1268), commit [#ff81148](https://github.com/stlink-org/stlink/commit/ff8114895a9fc32cae6a9374e58eac6256d68183)) +- Fixed st-trace reconnect on Windows ([#1272](https://github.com/stlink-org/stlink/pull/1272), [#1292](https://github.com/stlink-org/stlink/pull/1292)) - [compilation] Corrected path to stlink/chips subdirectory ([#1276](https://github.com/stlink-org/stlink/pull/1276), [#1279](https://github.com/stlink-org/stlink/pull/1279)) - [compilation] Fixed GUI compilation failure on OpenBSD i386 ([#1284](https://github.com/stlink-org/stlink/pull/1284)) @@ -84,7 +89,7 @@ Features: - Extended set of cmd line arguments for st-info and st-util ([#332](https://github.com/stlink-org/stlink/pull/332), [#990](https://github.com/stlink-org/stlink/pull/990), [#1091](https://github.com/stlink-org/stlink/pull/1091), [#1114](https://github.com/stlink-org/stlink/pull/1114)) - Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#801](https://github.com/stlink-org/stlink/pull/801), [#868](https://github.com/stlink-org/stlink/pull/868), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) -- Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052)) +- Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052), [#1184](https://github.com/stlink-org/stlink/pull/1184)) - Official support for STLINK-V3 programmers (commit [#5e0a502](https://github.com/stlink-org/stlink/commit/5e0a502df812495bfa96fa9116a19f1306152b17), [#820](https://github.com/stlink-org/stlink/pull/820), [#1022](https://github.com/stlink-org/stlink/pull/1022), [#1025](https://github.com/stlink-org/stlink/pull/1025)) - Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) - Option bytes on the STM32F767 ZIT6 Nucleo-144 ([#968](https://github.com/stlink-org/stlink/pull/968), [#997](https://github.com/stlink-org/stlink/pull/997)) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 39b31f219..3b25dc214 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -169,7 +169,10 @@ int main(int ac, char** av) { printf("Unknown memory region\n"); goto on_error; } + } else if (o.cmd == FLASH_CMD_ERASE) { + + // erase if (o.size > 0 && o.addr > 0) { err = stlink_erase_flash_section(sl, o.addr, o.size, false); } else { @@ -180,11 +183,15 @@ int main(int ac, char** av) { goto on_error; } printf("Mass erase completed successfully.\n"); + } else if (o.cmd == CMD_RESET) { + + // reset if (stlink_reset(sl, RESET_AUTO)) { printf("Failed to reset device\n"); goto on_error; } + } else { // read From 8af1dcb71e870e3c8f20e28bb123e10808696e55 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 4 Apr 2023 23:32:51 +0200 Subject: [PATCH 1357/1435] Minor changes & fixes - Simplified listing of supported devices - Corrected #define STM32L5_PWR_CR1_VOS - Check the return code of stlink_read_debug32 - Fix for flash register reading on L5x2 devices --- doc/devices_boards.md | 207 ---------------------------------- doc/supported devices.md | 59 ++++++++++ inc/stm32.h | 2 +- src/stlink-lib/common.c | 9 ++ src/stlink-lib/common_flash.c | 3 +- 5 files changed, 70 insertions(+), 210 deletions(-) delete mode 100644 doc/devices_boards.md create mode 100644 doc/supported devices.md diff --git a/doc/devices_boards.md b/doc/devices_boards.md deleted file mode 100644 index 13aa0361a..000000000 --- a/doc/devices_boards.md +++ /dev/null @@ -1,207 +0,0 @@ -# MCUs supported by the STlink toolset - -The following devices are supported by the stlink toolset. - -## STM32F0 / ARM Cortex M0 - -| Chip-ID | Product-Code | -| ------- | ------------------- | -| 0x440 | STM32F0**30**x**8** | -| 0x442 | STM32F0**30**x**C** | -| 0x444 | STM32F0**3**xx**4** | -| 0x444 | STM32F0**3**xx**6** | -| 0x445 | STM32F0**4**xxx | -| 0x440 | STM32F0**5**xxx | -| 0x445 | STM32F0**70**x**6** | -| 0x448 | STM32F0**70**x**B** | -| 0x448 | STM32F0**71**xx | -| 0x448 | STM32F0**72**xx | -| 0x442 | STM32F0**9**xxx | - - -## STM32F1 / ARM Cortex M3 - -| Product-Code | Product Line | -| ----------------- | ----------------------- | -| STM32F10**0**yyxx | Value line (V) | -| STM32F10**1**yyxx | Access line (A) | -| STM32F10**2**yyxx | USB Access line (USB-A) | -| STM32F10**3**yyxx | Performance line (P) | -| STM32F10**5**yyxx | Connectivity line (C) | -| STM32F10**7**yyxx | Connectivity line (C) | - -| Chip-ID | Product Line | Code (yy) | V | A | USB-A | P | C | -| ------- | -------------------- | --------- | ---- | ---- | ----- | ---- | -------------- | -| 0x412 | Low-Density | x4 x6 | F100 | F101 | F102 | F103 | | -| 0x410 | Medium Density | x8 xB | | F101 | F102 | F103 | | -| 0x414 | High density | xC xD xE | | F101 | F103 | | | -| 0x418 | STM32F105xx/107xx | x8 xB xC | | | | | F105
      F107 | -| 0x420 | Medium density value | x8 xB | F100 | | | | | -| 0x428 | High density Value | xC xD xE | F100 | | | | | -| 0x430 | XL-Density | xF xG | | F101 | | F103 | | - -Tested non-official ST boards [incl. STLINK programmers]: - -- HY-STM32 (STM32F103VETx) [v1, v2] -- DecaWave EVB1000 (STM32F105RCTx) [v1, v2] - -## STM32F2 / ARM Cortex M3 - -| Chip-ID | Product-Code | Product Line | -| ------- | ------------ | ------------- | -| 0x411 | STM32F2yyxx | (all devices) | - -## STM32F1 Clone / ARM Cortex M3 (Core-ID: 0x2ba01477) [may work, but without support!] - -| Product-Code | Chip-ID | STLink
      Programmer | Boards | -| ------------- | ------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | -| CKS32F103C8Tx | 0x410 | v2 | STM32F103C8T6 clone from China Key Systems (CKS) either as
      CKS32-Bluepill or even as "STM32"-Bluepill with _**Fake-Marking !**_ | - -## STM32F3 / ARM Cortex M4F - -| Product-Code | Product Line | -| ----------------- | ------------------------------------------------------------- | -| STM32F3**01**yyxx | Access line (A) | -| STM32F3**02**yyxx | USB & CAN line (USB/CAN) | -| STM32F3**03**yyxx | Performance line (P) | -| STM32F3**34**yy | Digital Power line (DP) | -| STM32F3**73**yy | Precision Measurement line (PM) 64k/16k / 128k/24k / 265k/32k | -| STM32F3**18**yy | General Purpose line (GP) 64k/16k | -| STM32F3**28**yy | General Purpose line (GP) 64k/16k | -| STM32F3**58**yy | General Purpose line (GP) 265k/48k | -| STM32F3**78**yy | Precision Measurement line (PM) 265k/32k | -| STM32F3**98**yy | General Purpose line (GP) 512k/80k | - -| Chip-ID | Product Line | Code (yy) | A | USB/CAN | P | others | -| ------- | ------------ | --------- | ---- | ------- | ---- | -------------- | -| 0x422 | _N/A_ | xB xC | | F302 | F303 | | -| 0x422 | _N/A_ | - | | | | F358 | -| 0x432 | _N/A_ | - | | | | F373
      F378 | -| 0x438 | _N/A_ | x4 x6 x8 | | | F303 | | -| 0x438 | _N/A_ | - | | | | F334
      F328 | -| 0x439 | _N/A_ | x4 x6 x8 | F301 | F302 | | | -| 0x439 | _N/A_ | - | | | | F318 | -| 0x446 | _N/A_ | xD xE | | F302 | F303 | | -| 0x446 | _N/A_ | - | | | | F398 | - -## STM32F3 Clone / ARM Cortex M4F (Core-ID: 0x2ba01477) [may work, but without support!] - -| Product-Code | Chip-ID | STLINK
      Programmer | Boards | -| ------------ | ------- | ---------------------- | ---------------------------------- | -| GD32F303CGT6 | 0x430 | [v2] | STM32F303 clone from GigaDevice GD | -| GD32F303VET6 | 0x414 | [v2] | STM32F303 clone from GigaDevice GD | -| GD32F303VGT6 | 0x430 | [v2] | STM32F303 clone from GigaDevice GD | - -## STM32F4 / ARM Cortex M4F - -| Chip-ID | Product-Code | -| ------- | ------------------- | -| 0x413 | STM32F4**0**xxx | -| 0x413 | STM32F4**1**xxx | -| 0x419 | STM32F4**2**xxx | -| 0x419 | STM32F4**3**xxx | -| 0x423 | STM32F4**01**x**B** | -| 0x423 | STM32F4**01**x**C** | -| 0x433 | STM32F4**01**x**D** | -| 0x433 | STM32F4**01**x**E** | -| 0x458 | STM32F4**10**xx | -| 0x431 | STM32F4**11**xx | -| 0x441 | STM32F4**12**xx | -| 0x421 | STM32F4**46**xx | -| 0x434 | STM32F4**69**xx | -| 0x434 | STM32F4**79**xx | -| 0x463 | STM32F4**13**xx | -| 0x463 | STM32F4**23**xx | - -## STM32F7 / ARM Cortex M7F - -| Chip-ID | Product-Code | -| ------- | --------------- | -| 0x452 | STM32F7**2**xxx | -| 0x452 | STM32F7**3**xxx | -| 0x449 | STM32F7**4**xxx | -| 0x449 | STM32F7**5**xxx | -| 0x451 | STM32F7**6**xxx | -| 0x451 | STM32F7**7**xxx | - -## STM32H7 / ARM Cortex M7F - -| Chip-ID | Product-Code | -| ------- | ------------- | -| 0x450 | STM32H7**4**x | -| 0x450 | STM32H7**5**x | -| 0x480 | STM32H7**A**x | -| 0x480 | STM32H7**B**x | - -## STM32G0 / ARM Cortex M0+ - -| Chip-ID | Product-Code | -| ------- | --------------- | -| 0x466 | STM32G0**3**xxx | -| 0x466 | STM32G0**4**xxx | -| 0x460 | STM32G0**7**xxx | -| 0x460 | STM32G0**8**xxx | - -## STM32G4 / ARM Cortex M4F - -| Chip-ID | Product-Code | -| ------- | --------------- | -| 0x468 | STM32G4**31**xx | -| 0x468 | STM32G4**41**xx | -| 0x469 | STM32G4**7**xxx | -| 0x469 | STM32G4**8**xxx | -| 0x479 | STM32G4**91**xx | - -## STM32L0 / ARM Cortex M0+ - -| Chip-ID | Product-Code | -| ------- | --------------- | -| 0x457 | STM32L0**1**xxx | -| 0x457 | STM32L0**2**xxx | -| 0x425 | STM32L0**31**xx | -| 0x425 | STM32L0**41**xx | -| 0x417 | STM32L0**5**xxx | -| 0x417 | STM32L0**6**xxx | -| 0x447 | STM32L0**7**xxx | -| 0x447 | STM32L0**8**xxx | - -## STM32L1 / ARM Cortex M3 - -| Chip-ID | Product-Code | -| ------- | ---------------- | -| 0x416 | STM32L1xxx**6** | -| 0x416 | STM32L1xxx**8** | -| 0x416 | STM32L1xxx**B** | -| 0x429 | STM32L1xxx**6A** | -| 0x429 | STM32L1xxx**8A** | -| 0x429 | STM32L1xxx**BA** | -| 0x427 | STM32L1xxx**C** | -| 0x436 | STM32L1xxx**D** | -| 0x437 | STM32L1xxx**E** | - -## STM32L4 / ARM Cortex M4F - -| Chip-ID | Product-Code | -| ------- | --------------- | -| 0x464 | STM32L4**12**xx | -| 0x464 | STM32L4**22**xx | -| 0x435 | STM32L4**3**xxx | -| 0x435 | STM32L4**4**xxx | -| 0x462 | STM32L4**5**xxx | -| 0x462 | STM32L4**6**xxx | -| 0x415 | STM32L4**7**xxx | -| 0x415 | STM32L4**8**xxx | -| 0x461 | STM32L4**96**xx | -| 0x461 | STM32L4**A6**xx | -| 0x470 | STM32L4**R**xx | -| 0x470 | STM32L4**S**xx | -| 0x471 | STM32L4**P5**xx | -| 0x471 | STM32L4**Q5**xx | - -## STM32W / ARM Cortex M3 - -| Chip-ID | Product-Code | -| ------- | --------------- | -| 0x495 | STM32WB**50**xx | -| 0x495 | STM32WB**55**xx | -| 0x497 | STM32WLE**5**xx | diff --git a/doc/supported devices.md b/doc/supported devices.md new file mode 100644 index 000000000..2e96dcd39 --- /dev/null +++ b/doc/supported devices.md @@ -0,0 +1,59 @@ +# MCUs supported by the STlink toolset + +A list of devices supported by the stlink toolset can be found in */inc/stm32.h*. +More commonly these are: + +| Product-Family | ARM Cortex Core | Product Line | +| -------------- | --------------- | ---------------------------------------------------------- | +| STM32F0 | M0 | | +| STM32G0 | M0+ | | +| STM32L0 | M0+ | | +| STM32F10**0** | M3 | Value line | +| STM32F10**1** | M3 | Access line | +| STM32F10**2** | M3 | USB Access line | +| STM32F10**3** | M3 | Performance line | +| STM32F10**5** | M3 | Connectivity line | +| STM32F10**7** | M3 | Connectivity line | +| STM32L1 | M3 | | +| STM32F2 | M3 | | +| STM32F3**01** | M4F | Access line | +| STM32F3**02** | M4F | USB & CAN line | +| STM32F3**03** | M4F | Performance line | +| STM32F3**34** | M4F | Digital Power line | +| STM32F3**73** | M4F | Precision Measurement line (64k/16k / 128k/24k / 265k/32k) | +| STM32F3**18** | M4F | General Purpose line (64k/16k) | +| STM32F3**28** | M4F | General Purpose line (64k/16k) | +| STM32F3**58** | M4F | General Purpose line (265k/48k) | +| STM32F3**78** | M4F | Precision Measurement line (265k/32k) | +| STM32F3**98** | M4F | General Purpose line (512k/80k) | +| STM32F4 | M4F | | +| STM32G4 | M4F | | +| STM32L4 | M4F | | +| STM32F7 | M4F | | +| STM32H7 | M4F | | +| STM32WB | M4F | | +| STM32WL | M4 | | + + +# Chinese Clone-Chips [may work, but without support!] + +## STM32F1 Clone / ARM Cortex M3 (Core-ID: 0x2ba01477) (mostly on Bluepill-Boards) + +**(!) Attention:** Some MCUs may come with with _**Fake-STM32-Marking !**_ + +**(!) Attention:** The Core-ID of these MCUs is in conflict with the one of the original STM32F1-devices. + +| Product-Code | Chip-ID | Comment | +| ------------- | ------- | ------------------------------------------------------------------------- | +| CKS32F103C8T6 | 0x410 | STM32F103C8T6 clone from China Key Systems (CKS) | +| CH32F103C8T6 | 0x410 | STM32F103C8T6 clone from Nanjing Qinheng Microelectronics Co., Ltd. (WCH) | + +## STM32F3 Clone / ARM Cortex M4F (Core-ID: 0x2ba01477) + +**(!) Attention:** The Chip-IDs of these MCUs are in conflict with such of original STM32F1-devices. + +| Product-Code | Chip-ID | Comment | +| ------------ | ------- | ------------------------------------ | +| GD32F303VET6 | 0x414 | STM32F303 clone from GigaDevice (GD) | +| GD32F303CGT6 | 0x430 | STM32F303 clone from GigaDevice (GD) | +| GD32F303VGT6 | 0x430 | STM32F303 clone from GigaDevice (GD) | diff --git a/inc/stm32.h b/inc/stm32.h index 92770bd44..d3c4e5512 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -215,6 +215,6 @@ enum stm32_chipids { #define STM32WB_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN #define STM32L5_PWR_CR1 0x40007000 // RM0438, p. 93,324 -#define STM32L5_PWR_CR1_VOS 8 +#define STM32L5_PWR_CR1_VOS 9 #endif // STM32_H diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index ccce342a4..e7c2392c1 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -292,6 +292,15 @@ int stlink_load_device_params(stlink_t *sl) { } } + if (sl->chip_id == STM32_CHIPID_L5x2xx) { + uint32_t flash_optr; + stlink_read_debug32(sl, STM32L5_FLASH_OPTR, &flash_optr); + + if (sl->flash_size == 512*1024 && (flash_optr & (1 << 22)) != 0) { + sl->flash_pgsz = 0x800; + } + } + // H7 devices with small flash has one bank if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK && sl->flash_type == STM32_FLASH_TYPE_H7) { diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index e84b307eb..000f9279d 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -441,8 +441,7 @@ static void unlock_flash(stlink_t *sl) { // Set voltage scaling to range 0 to perform flash operations (RM0438 p. 183) uint32_t mask = (0b11 << STM32L5_PWR_CR1_VOS); uint32_t val; - stlink_read_debug32(sl, STM32L5_PWR_CR1, &val); - if ((val & mask) > (1 << STM32L5_PWR_CR1_VOS)) { + if (!stlink_read_debug32(sl, STM32L5_PWR_CR1, &val) && (val & mask) > (1 << STM32L5_PWR_CR1_VOS)) { val &= ~mask; stlink_write_debug32(sl, STM32L5_PWR_CR1, val); } From 5946076723d77f4283b7e5483c74d66c12f43c76 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 4 Apr 2023 23:54:56 +0200 Subject: [PATCH 1358/1435] General maintenance - Updated pkg-version requirements - Updated version_support.md - Removed Ubuntu 18.04 from GH workflow --- .github/workflows/c-cpp.yml | 90 ------------------------------ cmake/packaging/cpack_config.cmake | 2 +- cmake/packaging/deb/control | 2 +- doc/version_support.md | 12 ++-- 4 files changed, 8 insertions(+), 98 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index fe07c6e44..72163fdf7 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -9,96 +9,6 @@ on: jobs: # Linux - job_linux_18_04_64_gcc: - name: ubuntu-18.04 gcc - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v2 - - name: install dependencies - run: sudo apt update && sudo apt-get install gcc-8 libusb-1.0.0-dev libgtk-3-dev rpm - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean - - job_linux_18_04_32_gcc: - name: ubuntu-18.04 gcc 32-bit - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v2 - - name: install dependencies - run: sudo apt update && sudo apt-get install gcc-8 libusb-1.0.0-dev libgtk-3-dev rpm - - name: Set compiler flags - run: | - CFLAGS="$CFLAGS -m32" - CXXFLAGS="$CXXFLAGS -m32" - LDFLAGS="$LDFLAGS -m32" - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean - - job_linux_18_04_64_clang: - name: ubuntu-18.04 clang - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v2 - - name: install dependencies - run: sudo apt update && sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean - - job_linux_18_04_32_clang: - name: ubuntu-18.04 clang 32-bit - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: sudo apt update && sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm - - name: Set compiler flags - run: | - CFLAGS="$CFLAGS -m32" - CXXFLAGS="$CXXFLAGS -m32" - LDFLAGS="$LDFLAGS -m32" - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean - job_linux_20_04_64_gcc: name: ubuntu-20.04 gcc runs-on: ubuntu-20.04 diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake index 55a859189..57d4803d7 100644 --- a/cmake/packaging/cpack_config.cmake +++ b/cmake/packaging/cpack_config.cmake @@ -48,7 +48,7 @@ elseif (EXISTS "/etc/debian_version" AND NOT EXISTS WIN32) # Package-build is av set(CPACK_DEBIAN_PACKAGE_RELEASE "1") # CPACK_DEBIAN_PACKAGE_ARCHITECTURE --> Default: Output of dpkg --print-architecture - set(CPACK_DEBIAN_PACKAGE_DEPENDS "pkg-config, build-essential, debhelper (>=9), cmake (>= 3.10.2), libusb-1.0-0-dev (>= 1.0.21)") + set(CPACK_DEBIAN_PACKAGE_DEPENDS "pkg-config, build-essential, debhelper (>=9), cmake (>= 3.13.0), libusb-1.0-0-dev (>= 1.0.22)") set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Nightwalker-87 ") # CPACK_DEBIAN_PACKAGE_DESCRIPTION --> Default: CPACK_DEBIAN_PACKAGE_DESCRIPTION (as it is set) # CPACK_DEBIAN_PACKAGE_SECTION --> Default: “devel” diff --git a/cmake/packaging/deb/control b/cmake/packaging/deb/control index 2ed3b6b11..7c2ab8fe7 100644 --- a/cmake/packaging/deb/control +++ b/cmake/packaging/deb/control @@ -1,7 +1,7 @@ Source: stlink Priority: optional Maintainer: Nightwalker-87 -Build-Depends: cmake (>= 3.10.2), dh-cmake, debhelper (>= 9), libusb-1.0-0-dev (>= 1.0.21), libgtk-3-dev (>= 3.22.30) +Build-Depends: cmake (>= 3.13.0), dh-cmake, debhelper (>= 9), libusb-1.0-0-dev (>= 1.0.22), libgtk-3-dev (>= 3.22.30) Standards-Version: 4.6.2 Rules-Requires-Root: no Section: electronics diff --git a/doc/version_support.md b/doc/version_support.md index e7d8f444b..43924e502 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -1,10 +1,10 @@ -_Source:_ [pkgs.org](https://pkgs.org/search) - libusb, cmake, gtk, libgtk) (as of Jan 2022) +_Source:_ [pkgs.org](https://pkgs.org/search) - libusb, cmake, gtk, libgtk (as of Apr 2023) ## Supported Operating Systems ### Microsoft Windows -On Windows users should ensure that cmake **3.10.2** or any later version is installed.
      +On Windows users should ensure that cmake **3.13.0** or any later version is installed.
      Up on compiling c-make will **automatically** download and install the latest compatible version of `libusb`. - Windows 10 @@ -61,7 +61,7 @@ Other Linux-/Unix-based Operating Systems: | Slackware Current | 1.0.24 | 3.21.4 | 3.24.31 | | | Adélie 1.0 | 1.0.23 | 3.**16.4** | 3.24.23 | | -## Unsupported Operating Systems (as of Release v1.7.1) +## Unsupported Operating Systems (as of Release v1.8.0) Systems with highlighted versions remain compatible with this toolset. @@ -77,7 +77,7 @@ Systems with highlighted versions remain compatible with this toolset. | Alpine 3.12 | 1.0.**23** | 3.**17.2** | May 2022 | | openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.**17.0** | Dec 2022 | | Fedora 32 [x64] | 1.0.**23** (`libusbx`) | 3.**17.0** | May 2021 | -| openSUSE Leap 15.2 [x64] | 1.0.**21** | 3.**17.0** | Dec 2021 | +| openSUSE Leap 15.2 [x64] | 1.0.21 | 3.**17.0** | Dec 2021 | | Ubuntu 20.10 (Groovy) | 1.0.**23** | 3.**16.3** | Jul 2021 | | NetBSD 7.x | 1.0.**22** | 3.**16.1** | Jun 2020 | | Alpine 3.11 | 1.0.**23** | 3.**15.5** | Nov 2021 | @@ -88,8 +88,8 @@ Systems with highlighted versions remain compatible with this toolset. | Fedora 30 | 1.0.**22**(`libusbx`) | 3.**14.2** | May 2020 | | Ubuntu 19.10 (Eoan) | 1.0.**23** | 3.**13.4** | Jul 2020 | | Alpine 3.9 | 1.0.**22** | 3.**13.0** | Jan 2021 | -| Ubuntu 18.04 LTS (Bionic) | 1.0.**21** | 3.**10.2** | **Apr 2023** | -| openSUSE Leap 15.1 [x64] | 1.0.**21** | 3.**10.2** | Jan 2021 | +| Ubuntu 18.04 LTS (Bionic) | 1.0.21 | 3.10.2 | Apr 2023 | +| openSUSE Leap 15.1 [x64] | 1.0.21 | 3.10.2 | Jan 2021 | | Debian 9 (Stretch) | 1.0.21 | 3.7.2 | Jun 2022 | | Slackware 14.2 | 1.0.20 | 3.5.2 | | | OpenMandriva Lx 3.0x | 1.0.20 | 3.4.2 | | From 982408e6ee4504b9eac3e679fc94e2d6c95e02e4 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 5 Apr 2023 21:33:49 +0200 Subject: [PATCH 1359/1435] Fixes regarding version support - Updated version_support.md - Updated version requirements for libusb --- config/chips/{L5x5.chip => L5x5xx.chip} | 0 doc/version_support.md | 3 ++- src/stlink-lib/libusb_settings.h | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) rename config/chips/{L5x5.chip => L5x5xx.chip} (100%) diff --git a/config/chips/L5x5.chip b/config/chips/L5x5xx.chip similarity index 100% rename from config/chips/L5x5.chip rename to config/chips/L5x5xx.chip diff --git a/doc/version_support.md b/doc/version_support.md index 43924e502..358e65fb9 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -21,6 +21,7 @@ Maintained versions of: - Arch Linux - FreeBSD - NetBSD +- OpenBSD Other Linux-/Unix-based Operating Systems: @@ -75,7 +76,7 @@ Systems with highlighted versions remain compatible with this toolset. | Ubuntu 21.04 (Hirsute) | 1.0.**24** | 3.**18.4** | Jan 2022 | | Fedora 33 [x64] | 1.0.**23** (`libusbx`) | 3.**18.3** | Nov 2021 | | Alpine 3.12 | 1.0.**23** | 3.**17.2** | May 2022 | -| openSUSE Leap 15.3 [x64] | 1.0.**21** | 3.**17.0** | Dec 2022 | +| openSUSE Leap 15.3 [x64] | 1.0.21 | 3.**17.0** | Dec 2022 | | Fedora 32 [x64] | 1.0.**23** (`libusbx`) | 3.**17.0** | May 2021 | | openSUSE Leap 15.2 [x64] | 1.0.21 | 3.**17.0** | Dec 2021 | | Ubuntu 20.10 (Groovy) | 1.0.**23** | 3.**16.3** | Jul 2021 | diff --git a/src/stlink-lib/libusb_settings.h b/src/stlink-lib/libusb_settings.h index ee690e0b1..3777f720b 100644 --- a/src/stlink-lib/libusb_settings.h +++ b/src/stlink-lib/libusb_settings.h @@ -33,9 +33,9 @@ #if defined (__FreeBSD__) #define MINIMAL_API_VERSION 0x01000102 // v1.0.16 #elif defined (__OpenBSD__) - #define MINIMAL_API_VERSION 0x01000105 // v1.0.21 + #define MINIMAL_API_VERSION 0x01000106 // v1.0.22 #elif defined (__linux__) - #define MINIMAL_API_VERSION 0x01000105 // v1.0.21 + #define MINIMAL_API_VERSION 0x01000106 // v1.0.22 #elif defined (_WIN32) #define MINIMAL_API_VERSION 0x01000109 // v1.0.25 #endif From 1d301a5498433900250fe2a8c0e10dfb7f44d7a4 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 7 Apr 2023 23:33:28 +0200 Subject: [PATCH 1360/1435] Fix for option byte read (Closes #1156) --- src/st-flash/flash.c | 38 ++++++++++++++++++++++------------- src/st-util/semihosting.c | 9 +++++---- src/stlink-lib/common.c | 15 ++++++++------ src/stlink-lib/option_bytes.c | 3 --- 4 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 3b25dc214..d7d17f66f 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -1,17 +1,22 @@ /* Simple wrapper around the stlink_flash_write function */ -// TODO - this should be done as just a simple flag to the st-util command line... - -#include #include #include #include + +#include +#include #include +#include #include #include + +#include +#include +#include + #include "flash.h" -#include "option_bytes.h" static stlink_t *connected_stlink = NULL; @@ -215,20 +220,25 @@ int main(int ac, char** av) { (unsigned)remaining_option_length, sl->option_base); - if (NULL != o.filename) { - if (0 == o.size) { - o.size = sl->option_size; + uint32_t option_byte = 0; + err = stlink_read_option_bytes32(sl, &option_byte); + if (err == -1) { + printf("could not read option bytes (%d)\n", err); + goto on_error; + } else if (NULL != o.filename) { + int fd = open(o.filename, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); + if (fd == -1) { + fprintf(stderr, "open(%s) == -1\n", o.filename); + goto on_error; } - err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, sl->option_base, o.size); - } else { - uint32_t option_byte = 0; - err = stlink_read_option_bytes32(sl, &option_byte); + err = (uint32_t)write(fd, &option_byte, 4); if (err == -1) { - printf("could not read option bytes (%d)\n", err); + printf("could not write buffer to file (%d)\n", err); goto on_error; - } else { - printf("%08x\n", option_byte); } + close(fd); + } else { + printf("%08x\n", option_byte); } } else if (o.area == FLASH_OPTION_BYTES_BOOT_ADD) { uint32_t option_byte = 0; diff --git a/src/st-util/semihosting.c b/src/st-util/semihosting.c index 32169c812..f603f6224 100644 --- a/src/st-util/semihosting.c +++ b/src/st-util/semihosting.c @@ -1,11 +1,13 @@ #include +#include #include + +#include #include #include -#include -#include #include + #include #include "semihosting.h" @@ -256,8 +258,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { return(-1); } - DLOG("Semihosting: write(%d, target_addr:0x%08x, %u)\n", fd, buffer_address, - buffer_len); + DLOG("Semihosting: write(%d, target_addr:0x%08x, %u)\n", fd, buffer_address, buffer_len); *ret = (uint32_t)write(fd, buffer, buffer_len); saved_errno = errno; diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index e7c2392c1..fac97278e 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -1,18 +1,21 @@ -#include +#include +#include +#include + #include +#include #include #include #include -#include -#include -#include -#include + #include #include -#include "common_flash.h" #include "calculate.h" +#include "common_flash.h" #include "map_file.h" +#include "md5.h" + #include "common.h" #ifndef O_BINARY diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c index 32becc5cf..9cbdd097b 100644 --- a/src/stlink-lib/option_bytes.c +++ b/src/stlink-lib/option_bytes.c @@ -1007,11 +1007,8 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { case STM32_CHIPID_F76xxx: return stlink_read_option_bytes_f7(sl, option_byte); case STM32_CHIPID_G0_CAT1: - return stlink_read_option_bytes_gx(sl, option_byte); case STM32_CHIPID_G0_CAT2: - return stlink_read_option_bytes_gx(sl, option_byte); case STM32_CHIPID_G4_CAT2: - return stlink_read_option_bytes_gx(sl, option_byte); case STM32_CHIPID_G4_CAT3: return stlink_read_option_bytes_gx(sl, option_byte); default: From 1745bf5193c4d3186d4f6fde59cc86e9bad6e61b Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 8 Apr 2023 02:16:48 +0200 Subject: [PATCH 1361/1435] [doc] Human-readable flash_type in chip-id files (Closes #1155) --- src/stlink-lib/chipid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 075c19c17..3d122a02e 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -83,6 +83,7 @@ void process_chipfile(char *fname) { } else if (strcmp(word, "flash_type") == 0) { buf[strlen(buf) - 1] = 0; // chomp newline sscanf(buf, "%*s %n", &nc); + // Match human readable flash_type with enum stm32_flash_type { }. if (strcmp(value, "F0_F1_F3") == 0) { ts->flash_type = STM32_FLASH_TYPE_F0_F1_F3; } else if (strcmp(value, "F1_XL") == 0) { From 39f306feaa932729c06a3f546721f3659886f46c Mon Sep 17 00:00:00 2001 From: Nicolas signed-log FORMICHELLA Date: Sat, 15 Apr 2023 08:02:19 +0200 Subject: [PATCH 1362/1435] Fix broken doc link --- doc/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index e694bf8d0..7e87a7bd9 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -81,7 +81,7 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", \ and the `idVendor` of `0483` and `idProduct` of `374b` matches the vendor id from the `lsusb` output. -Make sure that you have all 3 files from here: https://github.com/stlink-org/stlink/tree/master/etc/udev/rules.d in your `/etc/udev/rules.d` directory. After copying new files or editing existing files in `/etc/udev/ruled.d` you should run the following: +Make sure that you have all 3 files from [/config/udev/rules.d](https://github.com/stlink-org/stlink/tree/master/config/udev/rules.d) in your `/etc/udev/rules.d` directory. After copying new files or editing existing files in `/etc/udev/ruled.d` you should run the following: ``` sudo udevadm control --reload-rules From 0a5cad7ee8e6950f8816b654b41d6bbaa96f6846 Mon Sep 17 00:00:00 2001 From: Mingjie Shen Date: Sat, 22 Apr 2023 00:03:54 -0400 Subject: [PATCH 1363/1435] Fix unbounded write of sscanf Format string "%s" that does not control the length of data written may overflow. --- src/stlink-lib/chipid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 3d122a02e..44d93fedd 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -64,7 +64,7 @@ void process_chipfile(char *fname) { (strncmp(buf, " ", strlen(" ")) == 0)) continue; // ignore empty lines - sscanf(buf, "%s %s", word, value); + sscanf(buf, "%63s %63s", word, value); if (strcmp(word, "dev_type") == 0) { buf[strlen(buf) - 1] = 0; // chomp newline From 98902c271ef20564e95b73cf8e0ee4a8600a8bd1 Mon Sep 17 00:00:00 2001 From: Mingjie Shen Date: Sat, 22 Apr 2023 00:53:29 -0400 Subject: [PATCH 1364/1435] Add null check for return value of stlink_chipid_get_params() Pass a null pointer to "%s" is undefined behaviour. --- src/st-trace/trace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 20e04c080..8c6e3c62b 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -591,7 +591,8 @@ int main(int argc, char **argv) { if (!(stlink->chip_flags & CHIP_F_HAS_SWO_TRACING)) { const struct stlink_chipid_params *params = stlink_chipid_get_params(stlink->chip_id); - ELOG("We do not support SWO output for device '%s'\n", params->dev_type); + ELOG("We do not support SWO output for device '%s'\n", + params ? params->dev_type : ""); if (!settings.force) return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; } From 8f97e62708f5eff3e66669976d17cd0ecbf29125 Mon Sep 17 00:00:00 2001 From: Mingjie Shen Date: Sat, 22 Apr 2023 18:10:31 -0400 Subject: [PATCH 1365/1435] Check return values of sscanf() Failing to check that a call to 'scanf' actually writes to an output variable can lead to unexpected behavior at reading time. --- src/st-util/gdb-server.c | 6 ++++-- src/stlink-lib/chipid.c | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 802e23c06..d64073cf7 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -160,8 +160,10 @@ int parse_options(int argc, char** argv, st_state_t *st) { break; case 'p': - sscanf(optarg, "%i", &q); - if (q < 0) { + if (sscanf(optarg, "%i", &q) != 1) { + fprintf(stderr, "Invalid port %s\n", optarg); + exit(EXIT_FAILURE); + } else if (q < 0) { fprintf(stderr, "Can't use a negative port to listen on: %d\n", q); exit(EXIT_FAILURE); } diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 44d93fedd..347d89e14 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -64,7 +64,10 @@ void process_chipfile(char *fname) { (strncmp(buf, " ", strlen(" ")) == 0)) continue; // ignore empty lines - sscanf(buf, "%63s %63s", word, value); + if (sscanf(buf, "%63s %63s", word, value) != 2) { + fprintf(stderr, "Failed to read keyword or value\n"); + continue; + } if (strcmp(word, "dev_type") == 0) { buf[strlen(buf) - 1] = 0; // chomp newline From 222ff4716520a815f0c3ed7360f93227a080e64a Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Fri, 28 Apr 2023 17:59:47 +0300 Subject: [PATCH 1366/1435] fix warn in a few *.cmake --- cmake/modules/Findlibusb.cmake | 4 ++-- cmake/modules/get_version.cmake | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index fbbda5ba3..6f0a21da6 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -60,7 +60,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3rdparty/libusb-${LIBUSB_WIN_VERSION}) - else (EXISTS "/etc/debian_version" AND MINGW) # ... only for cross-building on Debian + elseif (EXISTS "/etc/debian_version" AND MINGW) # ... only for cross-building on Debian set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_SOURCE_DIR}/build-mingw-${ARCH}/${LIBUSB_WIN_ARCHIVE}) set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_SOURCE_DIR}/build-mingw-${ARCH}/3rdparty/libusb-${LIBUSB_WIN_VERSION}) endif () @@ -102,7 +102,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to NO_CMAKE_FIND_ROOT_PATH ) - else (MSVC) + elseif (MSVC) set(LIBUSB_NAME libusb-1.0.lib) find_library( LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} diff --git a/cmake/modules/get_version.cmake b/cmake/modules/get_version.cmake index 70fbde816..8211d9c84 100644 --- a/cmake/modules/get_version.cmake +++ b/cmake/modules/get_version.cmake @@ -55,7 +55,7 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") message(STATUS "Rewrite ${PROJECT_SOURCE_DIR}/.version with ${__version_str}!") endif () - else (NOT EXISTS "${PROJECT_SOURCE_DIR}/.version") + elseif (NOT EXISTS "${PROJECT_SOURCE_DIR}/.version") # No local .version file found: Create a new one... file(WRITE "${PROJECT_SOURCE_DIR}/.version" ${__version_str}) From 1775184084f189409d91522e1d14f8d5fb84b61e Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 30 Apr 2023 14:31:50 +0200 Subject: [PATCH 1367/1435] General Project Update - Updated CHANGELOG.md - Updated README.md - Merged flash loader source files --- CHANGELOG.md | 13 +- CMakeLists.txt | 2 - README.md | 1 - src/st-util/gdb-server.c | 2 +- src/stlink-lib/common_flash.c | 2 +- src/stlink-lib/flash_loader.c | 500 +++++++++++++++++++++++++++++++++- src/stlink-lib/flash_loader.h | 5 + src/stlink-lib/flashloader.c | 496 --------------------------------- src/stlink-lib/flashloader.h | 13 - 9 files changed, 517 insertions(+), 517 deletions(-) delete mode 100644 src/stlink-lib/flashloader.c delete mode 100644 src/stlink-lib/flashloader.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 551a4ba09..c930999cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,11 @@ # stlink Changelog -# v1.7.1 +# v1.8.0 Release date: 2023-xx-xx -This release drops support for some older operating systems. Check project README for details. +This release drops support for macOS and some older operating systems. Check project README for details. +Removed Travis CI integration as it is no longer functional. Updated system requirements: - `cmake` >= 3.10.2 @@ -14,6 +15,7 @@ Updated system requirements: Features: - Support for writing option bytes on STM32F0/F1/F3 ([#346](https://github.com/stlink-org/stlink/pull/346), [#458](https://github.com/stlink-org/stlink/pull/458), [#808](https://github.com/stlink-org/stlink/pull/808), [#1084](https://github.com/stlink-org/stlink/pull/1084), [#1112](https://github.com/stlink-org/stlink/pull/1112)) +- Initial support for STM32 L5 & U5 devices and minor changes ([#1005](https://github.com/stlink-org/stlink/pull/1005), [#1096](https://github.com/stlink-org/stlink/pull/1096), [#1247](https://github.com/stlink-org/stlink/pull/1247), [#1300](https://github.com/stlink-org/stlink/pull/1300), [#1301](https://github.com/stlink-org/stlink/pull/1301)) - Added chip-IDs for STM32G0B0/G0B1/G0C1/G050/G051/G061 ([#1140](https://github.com/stlink-org/stlink/pull/1140)) - Added option byte info for STM32F411XX ([#1141](https://github.com/stlink-org/stlink/pull/1141)) - Expanded and revised list of chips ([#1145](https://github.com/stlink-org/stlink/pull/1145), [#1164](https://github.com/stlink-org/stlink/pull/1164)) @@ -22,6 +24,7 @@ Features: - Added support for STLINK-V3 devices with no MSD ([#1185](https://github.com/stlink-org/stlink/pull/1185)) - Updated gdb-server.c to allow external memory access on STM32H73xx ([#1196](https://github.com/stlink-org/stlink/pull/1196), [#1197](https://github.com/stlink-org/stlink/pull/1197)) - Erase addr size / section of the flash memory with st-flash ([#1213](https://github.com/stlink-org/stlink/pull/1213)) +- Added support for STM32L4Q5 ([#1224](https://github.com/stlink-org/stlink/pull/1224), [#1295](https://github.com/stlink-org/stlink/pull/1295)) - Added writing and reading for STM32WL option bytes ([#1226](https://github.com/stlink-org/stlink/pull/1226), [#1227](https://github.com/stlink-org/stlink/pull/1227)) - Added parametres option_base, option_size for F401xD_xE ([#1235](https://github.com/stlink-org/stlink/pull/1235)) - Added support for option bytes to F1xx_XLD (GD32F30x) ([#1250](https://github.com/stlink-org/stlink/pull/1250)) @@ -35,6 +38,7 @@ Updates & changes: - Added instructions for bug-reports and feature-requests to contribution guidelines ([#906](https://github.com/stlink-org/stlink/pull/906)) - Added travis CI configuration for macOS 10.14 to maintain capability for 32-bit compilation (commit [#f5ada94](https://github.com/stlink-org/stlink/commit/f5ada9474cdb87ff37de0d4eb9e75622b5870646)) - Updated description of chip id 0x0457 to L01x/L02x ([#1143](https://github.com/stlink-org/stlink/pull/1143), [#1144](https://github.com/stlink-org/stlink/pull/1144)) +- [doc] Human-readable flash_type in chip-id files ([#1155](https://github.com/stlink-org/stlink/pull/1155), commit [#1745bf5](https://github.com/stlink-org/stlink/commit/1745bf5193c4d3186d4f6fde59cc86e9bad6e61b)) - Dropped execute bits from source code files ([#1167](https://github.com/stlink-org/stlink/pull/1167)) - Use proper Markdown headers for supported MCUs ([#1168](https://github.com/stlink-org/stlink/pull/1168)) - Removed redundant array ([#1178](https://github.com/stlink-org/stlink/pull/1178)) @@ -58,6 +62,7 @@ Fixes: - Removed limit check for WRITEMEM_32BIT ([#1157](https://github.com/stlink-org/stlink/pull/1157)) - Fixed get_stm32l0_flash_base address for STM32L152RE ([#1161](https://github.com/stlink-org/stlink/pull/1161), [#1162](https://github.com/stlink-org/stlink/pull/1162)) - Fixed segfault if chip was not found in chip config files ([#1138](https://github.com/stlink-org/stlink/pull/1138), [#1163](https://github.com/stlink-org/stlink/pull/1163), [#1165](https://github.com/stlink-org/stlink/pull/1165), [#1166](https://github.com/stlink-org/stlink/pull/1166), [#1170](https://github.com/stlink-org/stlink/pull/1170)) +- Fixed parsing hex numbers in chip config files ([#1156](https://github.com/stlink-org/stlink/pull/1156), commit [#1d301a5](https://github.com/stlink-org/stlink/commit/1d301a5498433900250fe2a8c0e10dfb7f44d7a4)) - Fixed parsing hex numbers in chip config files ([#1169](https://github.com/stlink-org/stlink/pull/1169)) - Corrected flash_pagesize to use hex format ([#1172](https://github.com/stlink-org/stlink/pull/1172)) - Fixed compilation for MSVC ([#1176](https://github.com/stlink-org/stlink/pull/1176)) @@ -65,6 +70,7 @@ Fixes: - st-flash and other utilities search for chip files in the wrong directory ([#1180](https://github.com/stlink-org/stlink/pull/1180), commit [#c8fc656](https://github.com/stlink-org/stlink/commit/c8fc6561fead79ad49c09d82bab864745086792c)) - Fixed broken build on 32 bit systems ([#985](https://github.com/stlink-org/stlink/pull/985), [#1175](https://github.com/stlink-org/stlink/pull/1175), commit [#c8fc656](https://github.com/stlink-org/stlink/commit/c8fc6561fead79ad49c09d82bab864745086792c)) - Define 'SSIZE_MAX' if not defined ([#1183](https://github.com/stlink-org/stlink/pull/1183)) +- STM32G031G8: BOOT_LOCK is not possible to change on option bytes address 0x1FFF7870 ([#1194](https://github.com/stlink-org/stlink/pull/1194)) - Fixed compliation for OpenBSD 7.0 ([#1202](https://github.com/stlink-org/stlink/pull/1202)) - Included 'SSIZE_MAX' from 'limits.h' in 'src/common.c' ([#1207](https://github.com/stlink-org/stlink/pull/1207)) - Fix for libusb_kernel_driver_active & error handling for st.st_size () ([#1210](https://github.com/stlink-org/stlink/pull/1210), [#1211](https://github.com/stlink-org/stlink/pull/1211), [#1214](https://github.com/stlink-org/stlink/pull/1214)) @@ -78,6 +84,9 @@ Fixes: - Fixed st-trace reconnect on Windows ([#1272](https://github.com/stlink-org/stlink/pull/1272), [#1292](https://github.com/stlink-org/stlink/pull/1292)) - [compilation] Corrected path to stlink/chips subdirectory ([#1276](https://github.com/stlink-org/stlink/pull/1276), [#1279](https://github.com/stlink-org/stlink/pull/1279)) - [compilation] Fixed GUI compilation failure on OpenBSD i386 ([#1284](https://github.com/stlink-org/stlink/pull/1284)) +- Fixed unbounded write and check return values of sscanf ([#1306](https://github.com/stlink-org/stlink/pull/1306)) +- Added null check for return value of stlink_chipid_get_params() ([#1307](https://github.com/stlink-org/stlink/pull/1307)) +- Fixed warning in a few *.cmake files ([#1309](https://github.com/stlink-org/stlink/pull/1309)) # v1.7.0 diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ce0ee126..bce4def8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -174,7 +174,6 @@ set(STLINK_HEADERS src/stlink-lib/common_flash.h src/stlink-lib/common.h src/stlink-lib/flash_loader.h - src/stlink-lib/flashloader.h src/stlink-lib/helper.h src/stlink-lib/libusb_settings.h src/stlink-lib/logging.h @@ -192,7 +191,6 @@ set(STLINK_SOURCE src/stlink-lib/common_flash.c src/stlink-lib/common.c src/stlink-lib/flash_loader.c - src/stlink-lib/flashloader.c src/stlink-lib/helper.c src/stlink-lib/logging.c src/stlink-lib/map_file.c diff --git a/README.md b/README.md index 3101fb560..0e846b336 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ ![GitHub contributors](https://img.shields.io/github/contributors/stlink-org/stlink) [![CodeQL](https://github.com/stlink-org/stlink/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/stlink-org/stlink/actions/workflows/codeql-analysis.yml) [![C/C++ CI](https://github.com/stlink-org/stlink/actions/workflows/c-cpp.yml/badge.svg?branch=testing)](https://github.com/stlink-org/stlink/actions/workflows/c-cpp.yml) -[![Linux Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=linux&label=linux)](https://travis-ci.org/stlink-org/stlink) Recent new features and bugfixes can be found in the [Changelog](CHANGELOG.md) of this software project. diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index d64073cf7..99cc0170b 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -28,7 +28,7 @@ #include #include #include -#include "flashloader.h" +#include "flash_loader.h" #include "gdb-remote.h" #include "gdb-server.h" #include "semihosting.h" diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 000f9279d..740c93690 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -3,7 +3,7 @@ #include #include #include "calculate.h" -#include "flashloader.h" +#include "flash_loader.h" #include "common_flash.h" #include "map_file.h" #include "common.h" diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 94978a51f..852ba6c20 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -6,6 +6,7 @@ #include #include #include "flash_loader.h" +#include "common_flash.h" #define FLASH_REGS_BANK2_OFS 0x40 #define FLASH_BANK2_START_ADDR 0x08080000 @@ -386,7 +387,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe * The chunk size for loading is not rounded. The flash loader * subtracts the size of the written block (1-8 bytes) from * the remaining size each time. A negative value may mean that - * several bytes garbage has been written due to the unaligned + * several bytes garbage have been written due to the unaligned * firmware size. */ if ((int32_t)rr.r[2] > 0 || (int32_t)rr.r[2] < -7) { @@ -412,3 +413,500 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe return(-1); } + + +/* ================================================== + * === Content from old source file flashloader.c === + * ================================================== + */ + +#define L1_WRITE_BLOCK_SIZE 0x80 +#define L0_WRITE_BLOCK_SIZE 0x40 + +int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, + uint32_t len, uint32_t pagesize) { + unsigned int count, off; + unsigned int num_half_pages = len / pagesize; + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + flash_loader_t fl; + bool use_loader = true; + int ret = 0; + + // enable half page write + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << FLASH_L1_FPRG); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + val |= (1 << FLASH_L1_PROG); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + + wait_flash_busy(sl); + + for (count = 0; count < num_half_pages; count++) { + if (use_loader) { + ret = stlink_flash_loader_run(sl, &fl, addr + count * pagesize, + base + count * pagesize, pagesize); + if (ret && count == 0) { + /* It seems that stm32lx devices have a problem when it is blank */ + WLOG("Failed to use flash loader, fallback to soft write\n"); + use_loader = false; + } + } + if (!use_loader) { + ret = 0; + for (off = 0; off < pagesize && !ret; off += 64) { + size_t chunk = (pagesize - off > 64) ? 64 : pagesize - off; + memcpy(sl->q_buf, base + count * pagesize + off, chunk); + ret = stlink_write_mem32(sl, addr + count * pagesize + off, (uint16_t)chunk); + } + } + + if (ret) { + WLOG("l1_stlink_flash_loader_run(%#x) failed! == -1\n", addr + count * pagesize); + break; + } + + if (sl->verbose >= 1) { + // show progress; writing procedure is slow and previous errors are misleading + fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); + fflush(stdout); + } + + // wait for sr.busy to be cleared + wait_flash_busy(sl); + } + + // disable half page write + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + return (ret); +} + +static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { + uint32_t cr_reg, x; + + x = read_flash_cr(sl, bank); + + if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + cr_reg = FLASH_F4_CR; + x |= 1 << FLASH_CR_PG; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + x |= 1 << FLASH_CR_PG; + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + x &= ~STM32L4_FLASH_CR_OPBITS; + x |= (1 << STM32L4_FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + cr_reg = STM32L5_FLASH_NSCR; + x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + cr_reg = STM32WB_FLASH_CR; + x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + x |= (1 << FLASH_H7_CR_PG); + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + x = (1 << FLASH_CR_PG); + } + + stlink_write_debug32(sl, cr_reg, x); +} + +static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { + uint32_t rcc, rcc_dma_mask, value; + + rcc = rcc_dma_mask = value = 0; + + switch (sl->flash_type) { + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + rcc = STM32F1_RCC_AHBENR; + rcc_dma_mask = STM32F1_RCC_DMAEN; + break; + case STM32_FLASH_TYPE_F2_F4: + case STM32_FLASH_TYPE_F7: + rcc = STM32F4_RCC_AHB1ENR; + rcc_dma_mask = STM32F4_RCC_DMAEN; + break; + case STM32_FLASH_TYPE_G0: + rcc = STM32G0_RCC_AHBENR; + rcc_dma_mask = STM32G0_RCC_DMAEN; + break; + case STM32_FLASH_TYPE_G4: + case STM32_FLASH_TYPE_L4: + rcc = STM32G4_RCC_AHB1ENR; + rcc_dma_mask = STM32G4_RCC_DMAEN; + break; + case STM32_FLASH_TYPE_L0_L1: + if (get_stm32l0_flash_base(sl) == STM32L_FLASH_REGS_ADDR) { + rcc = STM32L1_RCC_AHBENR; + rcc_dma_mask = STM32L1_RCC_DMAEN; + } else { + rcc = STM32L0_RCC_AHBENR; + rcc_dma_mask = STM32L0_RCC_DMAEN; + } + break; + case STM32_FLASH_TYPE_L5_U5: + rcc = STM32L5_RCC_AHB1ENR; + rcc_dma_mask = STM32L5_RCC_DMAEN; + break; + case STM32_FLASH_TYPE_H7: + rcc = STM32H7_RCC_AHB1ENR; + rcc_dma_mask = STM32H7_RCC_DMAEN; + break; + case STM32_FLASH_TYPE_WB_WL: + rcc = STM32WB_RCC_AHB1ENR; + rcc_dma_mask = STM32WB_RCC_DMAEN; + break; + default: + return; + } + + if (!stlink_read_debug32(sl, rcc, &value)) { + if (bckpRstr) { + value = (value & (~rcc_dma_mask)) | fl->rcc_dma_bkp; + } else { + fl->rcc_dma_bkp = value & rcc_dma_mask; + value &= ~rcc_dma_mask; + } + stlink_write_debug32(sl, rcc, value); + } +} + +int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { + // disable DMA + set_dma_state(sl, fl, 0); + + // wait for ongoing op to finish + wait_flash_busy(sl); + // Clear errors + clear_flash_error(sl); + + if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || + (sl->flash_type == STM32_FLASH_TYPE_F7) || + (sl->flash_type == STM32_FLASH_TYPE_L4)) { + ILOG("Starting Flash write for F2/F4/F7/L4\n"); + + // Flash loader initialisation + if (stlink_flash_loader_init(sl, fl) == -1) { + ELOG("stlink_flash_loader_init() == -1\n"); + return (-1); + } + + unlock_flash_if(sl); // first unlock the cr + + int voltage; + if (sl->version.stlink_v == 1) { + WLOG("STLINK V1 cannot read voltage, use default voltage 3.2V\n"); + voltage = 3200; + } else { + voltage = stlink_target_voltage(sl); + } + + if (voltage == -1) { + ELOG("Failed to read Target voltage\n"); + return (-1); + } + + if (sl->flash_type == STM32_FLASH_TYPE_L4) { + // L4 does not have a byte-write mode + if (voltage < 1710) { + ELOG("Target voltage (%d mV) too low for flash writes!\n", voltage); + return (-1); + } + } else { + if (voltage > 2700) { + ILOG("enabling 32-bit flash writes\n"); + write_flash_cr_psiz(sl, 2, BANK_1); + } else { + ILOG("Target voltage (%d mV) too low for 32-bit flash, " + "using 8-bit flash writes\n", + voltage); + write_flash_cr_psiz(sl, 0, BANK_1); + } + } + + // set programming mode + set_flash_cr_pg(sl, BANK_1); + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || + sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4 || + sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + ILOG("Starting Flash write for WB/G0/G4/L5/U5\n"); + + unlock_flash_if(sl); // unlock flash if necessary + set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + ILOG("Starting Flash write for L0\n"); + + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + + // disable pecr protection + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY2); + + // check pecr.pelock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 0)) { + ELOG("pecr.pelock not clear\n"); + return (-1); + } + + // unlock program memory + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY2); + + // check pecr.prglock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 1)) { + ELOG("pecr.prglock not clear\n"); + return (-1); + } + + /* Flash loader initialisation */ + if (stlink_flash_loader_init(sl, fl) == -1) { + // L0/L1 have fallback to soft write + WLOG("stlink_flash_loader_init() == -1\n"); + } + } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { + ILOG("Starting Flash write for VL/F0/F3/F1_XL\n"); + + // flash loader initialisation + if (stlink_flash_loader_init(sl, fl) == -1) { + ELOG("stlink_flash_loader_init() == -1\n"); + return (-1); + } + + // unlock flash + unlock_flash_if(sl); + + // set programming mode + set_flash_cr_pg(sl, BANK_1); + if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { + set_flash_cr_pg(sl, BANK_2); + } + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + ILOG("Starting Flash write for H7\n"); + + unlock_flash_if(sl); // unlock the cr + set_flash_cr_pg(sl, BANK_1); // set programming mode + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + set_flash_cr_pg(sl, BANK_2); + } + if (sl->chip_id != STM32_CHIPID_H7Ax) { + // set parallelism + write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); + } + } + } else { + ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); + return (-1); + } + + return (0); +} + +int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, + stm32_addr_t addr, uint8_t *base, uint32_t len) { + size_t off; + if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || + (sl->flash_type == STM32_FLASH_TYPE_F7) || + (sl->flash_type == STM32_FLASH_TYPE_L4)) { + size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; + for (off = 0; off < len;) { + size_t size = len - off > buf_size ? buf_size : len - off; + if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, + size) == -1) { + ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", + (unsigned)(addr + off)); + check_flash_error(sl); + return (-1); + } + + off += size; + } + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || + sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4 || + sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); + for (off = 0; off < len; off += sizeof(uint32_t)) { + uint32_t data; + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { + fprintf(stdout, "\r%3u/%3u pages written", + (unsigned int)(off / sl->flash_pgsz + 1), + (unsigned int)(len / sl->flash_pgsz)); + fflush(stdout); + } + + write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); + stlink_write_debug32(sl, addr + (uint32_t)off, data); + wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear + } + fprintf(stdout, "\n"); + + // flash writes happen as 2 words at a time + if ((off / sizeof(uint32_t)) % 2 != 0) { + stlink_write_debug32(sl, addr + (uint32_t)off, + 0); // write a single word of zeros + wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear + } + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + uint32_t pagesize = (flash_regs_base==STM32L0_FLASH_REGS_ADDR)? + L0_WRITE_BLOCK_SIZE:L1_WRITE_BLOCK_SIZE; + + DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); + + off = 0; + + if (len > pagesize) { + if (stm32l1_write_half_pages(sl, addr, base, len, pagesize)) { + return (-1); + } else { + off = (size_t)(len / pagesize) * pagesize; + } + } + + // write remaining word in program memory + for (; off < len; off += sizeof(uint32_t)) { + uint32_t data; + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { + fprintf(stdout, "\r%3u/%3u pages written", + (unsigned int)(off / sl->flash_pgsz + 1), + (unsigned int)(len / sl->flash_pgsz)); + fflush(stdout); + } + + write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); + stlink_write_debug32(sl, addr + (uint32_t)off, data); + + // wait for sr.busy to be cleared + do { + stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); + } while ((val & (1 << 0)) != 0); + + // TODO: check redo write operation + } + fprintf(stdout, "\n"); + } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { + int write_block_count = 0; + for (off = 0; off < len; off += sl->flash_pgsz) { + // adjust last write size + size_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; + + // unlock and set programming mode + unlock_flash_if(sl); + + DLOG("Finished unlocking flash, running loader!\n"); + + if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, + size) == -1) { + ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", + (unsigned)(addr + off)); + check_flash_error(sl); + return (-1); + } + + lock_flash(sl); + + if (sl->verbose >= 1) { + // show progress; writing procedure is slow and previous errors are + // misleading + fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, + (unsigned int)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); + fflush(stdout); + } + } + if (sl->verbose >= 1) { + fprintf(stdout, "\n"); + } + } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { + for (off = 0; off < len;) { + // Program STM32H7x with 64-byte Flash words + size_t chunk = (len - off > 64) ? 64 : len - off; + memcpy(sl->q_buf, base + off, chunk); + stlink_write_mem32(sl, addr + (uint32_t)off, 64); + wait_flash_busy(sl); + + off += chunk; + + if (sl->verbose >= 1) { + // show progress + fprintf(stdout, "\r%u/%u bytes written", (unsigned int)off, + (unsigned int)len); + fflush(stdout); + } + } + if (sl->verbose >= 1) { + fprintf(stdout, "\n"); + } + } else { + return (-1); + } + + return check_flash_error(sl); +} + +int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { + uint32_t dhcsr; + + if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || + (sl->flash_type == STM32_FLASH_TYPE_F2_F4) || + (sl->flash_type == STM32_FLASH_TYPE_F7) || + (sl->flash_type == STM32_FLASH_TYPE_G0) || + (sl->flash_type == STM32_FLASH_TYPE_G4) || + (sl->flash_type == STM32_FLASH_TYPE_H7) || + (sl->flash_type == STM32_FLASH_TYPE_L4) || + (sl->flash_type == STM32_FLASH_TYPE_L5_U5) || + (sl->flash_type == STM32_FLASH_TYPE_WB_WL)) { + + clear_flash_cr_pg(sl, BANK_1); + if ((sl->flash_type == STM32_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK) || + sl->flash_type == STM32_FLASH_TYPE_F1_XL) { + clear_flash_cr_pg(sl, BANK_2); + } + lock_flash(sl); + } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + + // reset lock bits + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + } + + // enable interrupt + if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) { + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + (dhcsr & (~STLINK_REG_DHCSR_C_MASKINTS))); + } + + // restore DMA state + set_dma_state(sl, fl, 1); + + return (0); +} diff --git a/src/stlink-lib/flash_loader.h b/src/stlink-lib/flash_loader.h index 368b6ab8b..0d39a9a48 100644 --- a/src/stlink-lib/flash_loader.h +++ b/src/stlink-lib/flash_loader.h @@ -7,6 +7,7 @@ #ifndef STLINK_FLASH_LOADER_H_ #define STLINK_FLASH_LOADER_H_ +#include #include #include @@ -16,4 +17,8 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t* fl); int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size); +int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); +int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len); +int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl); + #endif // STLINK_FLASH_LOADER_H_ diff --git a/src/stlink-lib/flashloader.c b/src/stlink-lib/flashloader.c deleted file mode 100644 index 4adf93a86..000000000 --- a/src/stlink-lib/flashloader.c +++ /dev/null @@ -1,496 +0,0 @@ -#include -#include -#include -#include "flashloader.h" -#include "common_flash.h" - -#define L1_WRITE_BLOCK_SIZE 0x80 -#define L0_WRITE_BLOCK_SIZE 0x40 - -int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, - uint32_t len, uint32_t pagesize) { - unsigned int count, off; - unsigned int num_half_pages = len / pagesize; - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - flash_loader_t fl; - bool use_loader = true; - int ret = 0; - - // enable half page write - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << FLASH_L1_FPRG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - val |= (1 << FLASH_L1_PROG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - - wait_flash_busy(sl); - - for (count = 0; count < num_half_pages; count++) { - if (use_loader) { - ret = stlink_flash_loader_run(sl, &fl, addr + count * pagesize, - base + count * pagesize, pagesize); - if (ret && count == 0) { - /* It seems that stm32lx devices have a problem when it is blank */ - WLOG("Failed to use flash loader, fallback to soft write\n"); - use_loader = false; - } - } - if (!use_loader) { - ret = 0; - for (off = 0; off < pagesize && !ret; off += 64) { - size_t chunk = (pagesize - off > 64) ? 64 : pagesize - off; - memcpy(sl->q_buf, base + count * pagesize + off, chunk); - ret = stlink_write_mem32(sl, addr + count * pagesize + off, (uint16_t)chunk); - } - } - - if (ret) { - WLOG("l1_stlink_flash_loader_run(%#x) failed! == -1\n", addr + count * pagesize); - break; - } - - if (sl->verbose >= 1) { - // show progress; writing procedure is slow and previous errors are misleading - fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); - fflush(stdout); - } - - // wait for sr.busy to be cleared - wait_flash_busy(sl); - } - - // disable half page write - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - return (ret); -} - -static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { - uint32_t cr_reg, x; - - x = read_flash_cr(sl, bank); - - if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - cr_reg = FLASH_F4_CR; - x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - x &= ~STM32L4_FLASH_CR_OPBITS; - x |= (1 << STM32L4_FLASH_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - cr_reg = STM32L5_FLASH_NSCR; - x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; - x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; - x |= (1 << FLASH_H7_CR_PG); - } else { - cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; - x = (1 << FLASH_CR_PG); - } - - stlink_write_debug32(sl, cr_reg, x); -} - -static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { - uint32_t rcc, rcc_dma_mask, value; - - rcc = rcc_dma_mask = value = 0; - - switch (sl->flash_type) { - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - rcc = STM32F1_RCC_AHBENR; - rcc_dma_mask = STM32F1_RCC_DMAEN; - break; - case STM32_FLASH_TYPE_F2_F4: - case STM32_FLASH_TYPE_F7: - rcc = STM32F4_RCC_AHB1ENR; - rcc_dma_mask = STM32F4_RCC_DMAEN; - break; - case STM32_FLASH_TYPE_G0: - rcc = STM32G0_RCC_AHBENR; - rcc_dma_mask = STM32G0_RCC_DMAEN; - break; - case STM32_FLASH_TYPE_G4: - case STM32_FLASH_TYPE_L4: - rcc = STM32G4_RCC_AHB1ENR; - rcc_dma_mask = STM32G4_RCC_DMAEN; - break; - case STM32_FLASH_TYPE_L0_L1: - if (get_stm32l0_flash_base(sl) == STM32L_FLASH_REGS_ADDR) { - rcc = STM32L1_RCC_AHBENR; - rcc_dma_mask = STM32L1_RCC_DMAEN; - } else { - rcc = STM32L0_RCC_AHBENR; - rcc_dma_mask = STM32L0_RCC_DMAEN; - } - break; - case STM32_FLASH_TYPE_L5_U5: - rcc = STM32L5_RCC_AHB1ENR; - rcc_dma_mask = STM32L5_RCC_DMAEN; - break; - case STM32_FLASH_TYPE_H7: - rcc = STM32H7_RCC_AHB1ENR; - rcc_dma_mask = STM32H7_RCC_DMAEN; - break; - case STM32_FLASH_TYPE_WB_WL: - rcc = STM32WB_RCC_AHB1ENR; - rcc_dma_mask = STM32WB_RCC_DMAEN; - break; - default: - return; - } - - if (!stlink_read_debug32(sl, rcc, &value)) { - if (bckpRstr) { - value = (value & (~rcc_dma_mask)) | fl->rcc_dma_bkp; - } else { - fl->rcc_dma_bkp = value & rcc_dma_mask; - value &= ~rcc_dma_mask; - } - stlink_write_debug32(sl, rcc, value); - } -} - -int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { - // disable DMA - set_dma_state(sl, fl, 0); - - // wait for ongoing op to finish - wait_flash_busy(sl); - // Clear errors - clear_flash_error(sl); - - if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || - (sl->flash_type == STM32_FLASH_TYPE_F7) || - (sl->flash_type == STM32_FLASH_TYPE_L4)) { - ILOG("Starting Flash write for F2/F4/F7/L4\n"); - - // Flash loader initialisation - if (stlink_flash_loader_init(sl, fl) == -1) { - ELOG("stlink_flash_loader_init() == -1\n"); - return (-1); - } - - unlock_flash_if(sl); // first unlock the cr - - int voltage; - if (sl->version.stlink_v == 1) { - WLOG("STLINK V1 cannot read voltage, use default voltage 3.2V\n"); - voltage = 3200; - } else { - voltage = stlink_target_voltage(sl); - } - - if (voltage == -1) { - ELOG("Failed to read Target voltage\n"); - return (-1); - } - - if (sl->flash_type == STM32_FLASH_TYPE_L4) { - // L4 does not have a byte-write mode - if (voltage < 1710) { - ELOG("Target voltage (%d mV) too low for flash writes!\n", voltage); - return (-1); - } - } else { - if (voltage > 2700) { - ILOG("enabling 32-bit flash writes\n"); - write_flash_cr_psiz(sl, 2, BANK_1); - } else { - ILOG("Target voltage (%d mV) too low for 32-bit flash, " - "using 8-bit flash writes\n", - voltage); - write_flash_cr_psiz(sl, 0, BANK_1); - } - } - - // set programming mode - set_flash_cr_pg(sl, BANK_1); - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || - sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4 || - sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - ILOG("Starting Flash write for WB/G0/G4/L5/U5\n"); - - unlock_flash_if(sl); // unlock flash if necessary - set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - ILOG("Starting Flash write for L0\n"); - - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - - // disable pecr protection - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, - FLASH_L0_PEKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, - FLASH_L0_PEKEY2); - - // check pecr.pelock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if (val & (1 << 0)) { - ELOG("pecr.pelock not clear\n"); - return (-1); - } - - // unlock program memory - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, - FLASH_L0_PRGKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, - FLASH_L0_PRGKEY2); - - // check pecr.prglock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if (val & (1 << 1)) { - ELOG("pecr.prglock not clear\n"); - return (-1); - } - - /* Flash loader initialisation */ - if (stlink_flash_loader_init(sl, fl) == -1) { - // L0/L1 have fallback to soft write - WLOG("stlink_flash_loader_init() == -1\n"); - } - } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { - ILOG("Starting Flash write for VL/F0/F3/F1_XL\n"); - - // flash loader initialisation - if (stlink_flash_loader_init(sl, fl) == -1) { - ELOG("stlink_flash_loader_init() == -1\n"); - return (-1); - } - - // unlock flash - unlock_flash_if(sl); - - // set programming mode - set_flash_cr_pg(sl, BANK_1); - if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { - set_flash_cr_pg(sl, BANK_2); - } - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - ILOG("Starting Flash write for H7\n"); - - unlock_flash_if(sl); // unlock the cr - set_flash_cr_pg(sl, BANK_1); // set programming mode - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - set_flash_cr_pg(sl, BANK_2); - } - if (sl->chip_id != STM32_CHIPID_H7Ax) { - // set parallelism - write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); - } - } - } else { - ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); - return (-1); - } - - return (0); -} - -int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, - stm32_addr_t addr, uint8_t *base, uint32_t len) { - size_t off; - if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || - (sl->flash_type == STM32_FLASH_TYPE_F7) || - (sl->flash_type == STM32_FLASH_TYPE_L4)) { - size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; - for (off = 0; off < len;) { - size_t size = len - off > buf_size ? buf_size : len - off; - if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, - size) == -1) { - ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", - (unsigned)(addr + off)); - check_flash_error(sl); - return (-1); - } - - off += size; - } - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || - sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4 || - sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); - for (off = 0; off < len; off += sizeof(uint32_t)) { - uint32_t data; - - if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { - fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off / sl->flash_pgsz + 1), - (unsigned int)(len / sl->flash_pgsz)); - fflush(stdout); - } - - write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); - stlink_write_debug32(sl, addr + (uint32_t)off, data); - wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear - } - fprintf(stdout, "\n"); - - // flash writes happen as 2 words at a time - if ((off / sizeof(uint32_t)) % 2 != 0) { - stlink_write_debug32(sl, addr + (uint32_t)off, - 0); // write a single word of zeros - wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear - } - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - uint32_t pagesize = (flash_regs_base==STM32L0_FLASH_REGS_ADDR)? - L0_WRITE_BLOCK_SIZE:L1_WRITE_BLOCK_SIZE; - - DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); - - off = 0; - - if (len > pagesize) { - if (stm32l1_write_half_pages(sl, addr, base, len, pagesize)) { - return (-1); - } else { - off = (size_t)(len / pagesize) * pagesize; - } - } - - // write remaining word in program memory - for (; off < len; off += sizeof(uint32_t)) { - uint32_t data; - - if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { - fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off / sl->flash_pgsz + 1), - (unsigned int)(len / sl->flash_pgsz)); - fflush(stdout); - } - - write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); - stlink_write_debug32(sl, addr + (uint32_t)off, data); - - // wait for sr.busy to be cleared - do { - stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); - } while ((val & (1 << 0)) != 0); - - // TODO: check redo write operation - } - fprintf(stdout, "\n"); - } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { - int write_block_count = 0; - for (off = 0; off < len; off += sl->flash_pgsz) { - // adjust last write size - size_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; - - // unlock and set programming mode - unlock_flash_if(sl); - - DLOG("Finished unlocking flash, running loader!\n"); - - if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, - size) == -1) { - ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", - (unsigned)(addr + off)); - check_flash_error(sl); - return (-1); - } - - lock_flash(sl); - - if (sl->verbose >= 1) { - // show progress; writing procedure is slow and previous errors are - // misleading - fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, - (unsigned int)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); - fflush(stdout); - } - } - if (sl->verbose >= 1) { - fprintf(stdout, "\n"); - } - } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - for (off = 0; off < len;) { - // Program STM32H7x with 64-byte Flash words - size_t chunk = (len - off > 64) ? 64 : len - off; - memcpy(sl->q_buf, base + off, chunk); - stlink_write_mem32(sl, addr + (uint32_t)off, 64); - wait_flash_busy(sl); - - off += chunk; - - if (sl->verbose >= 1) { - // show progress - fprintf(stdout, "\r%u/%u bytes written", (unsigned int)off, - (unsigned int)len); - fflush(stdout); - } - } - if (sl->verbose >= 1) { - fprintf(stdout, "\n"); - } - } else { - return (-1); - } - - return check_flash_error(sl); -} - -int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { - uint32_t dhcsr; - - if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || - (sl->flash_type == STM32_FLASH_TYPE_F2_F4) || - (sl->flash_type == STM32_FLASH_TYPE_F7) || - (sl->flash_type == STM32_FLASH_TYPE_G0) || - (sl->flash_type == STM32_FLASH_TYPE_G4) || - (sl->flash_type == STM32_FLASH_TYPE_H7) || - (sl->flash_type == STM32_FLASH_TYPE_L4) || - (sl->flash_type == STM32_FLASH_TYPE_L5_U5) || - (sl->flash_type == STM32_FLASH_TYPE_WB_WL)) { - - clear_flash_cr_pg(sl, BANK_1); - if ((sl->flash_type == STM32_FLASH_TYPE_H7 && - sl->chip_flags & CHIP_F_HAS_DUAL_BANK) || - sl->flash_type == STM32_FLASH_TYPE_F1_XL) { - clear_flash_cr_pg(sl, BANK_2); - } - lock_flash(sl); - } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - - // reset lock bits - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } - - // enable interrupt - if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) { - stlink_write_debug32(sl, STLINK_REG_DHCSR, - STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | - (dhcsr & (~STLINK_REG_DHCSR_C_MASKINTS))); - } - - // restore DMA state - set_dma_state(sl, fl, 1); - - return (0); -} diff --git a/src/stlink-lib/flashloader.h b/src/stlink-lib/flashloader.h deleted file mode 100644 index ff16d183c..000000000 --- a/src/stlink-lib/flashloader.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * File: flashloader.h - * - * Flash loader - */ - -#include -#include - -int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); -int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len); -int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl); - From ab286988b4135067b7c45d40f8e15e6b2f69d7a0 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 30 Apr 2023 18:52:14 +0200 Subject: [PATCH 1368/1435] Corrected preprocessor header includes --- inc/backend.h | 6 +++--- inc/stlink.h | 6 +++--- inc/stm32.h | 6 +++--- inc/stm32flash.h | 6 +++--- inc/version.h.in | 6 +++--- src/st-flash/flash.h | 6 +++--- src/st-util/gdb-remote.h | 6 +++--- src/st-util/gdb-server.h | 6 +++--- src/st-util/semihosting.h | 6 +++--- src/stlink-gui/gui.h | 6 +++--- src/stlink-lib/calculate.h | 6 +++--- src/stlink-lib/chipid.h | 6 +++--- src/stlink-lib/commands.h | 6 +++--- src/stlink-lib/common.h | 6 +++--- src/stlink-lib/common_flash.h | 7 ++++--- src/stlink-lib/flash_loader.h | 6 +++--- src/stlink-lib/helper.h | 6 +++--- src/stlink-lib/libusb_settings.h | 6 +++--- src/stlink-lib/logging.h | 6 +++--- src/stlink-lib/map_file.h | 6 +++--- src/stlink-lib/md5.h | 11 +++++++++++ src/stlink-lib/option_bytes.h | 5 +++++ src/stlink-lib/reg.h | 6 +++--- src/stlink-lib/sg.h | 6 +++--- src/stlink-lib/usb.h | 6 +++--- src/win32/getopt/getopt.h | 6 +++--- src/win32/mmap.h | 8 ++++---- src/win32/sys_time.h | 10 ++++++---- src/win32/unistd/unistd.h | 6 +++--- 29 files changed, 102 insertions(+), 83 deletions(-) diff --git a/inc/backend.h b/inc/backend.h index a45dccd82..abbf4bbf0 100644 --- a/inc/backend.h +++ b/inc/backend.h @@ -1,5 +1,5 @@ -#ifndef STLINK_BACKEND_H_ -#define STLINK_BACKEND_H_ +#ifndef BACKEND_H_ +#define BACKEND_H_ typedef struct _stlink_backend { void (*close) (stlink_t * sl); @@ -34,4 +34,4 @@ int (*trace_read) (stlink_t * sl, uint8_t* buf, size_t size); } stlink_backend_t; -#endif // STLINK_BACKEND_H_ +#endif // BACKEND_H_ diff --git a/inc/stlink.h b/inc/stlink.h index b9379e03d..2a192876f 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -6,8 +6,8 @@ * regardless of how the backend does the work.... */ -#ifndef STLINK_H -#define STLINK_H +#ifndef STLINK_H_ +#define STLINK_H_ #include #include @@ -311,4 +311,4 @@ int stlink_target_connect(stlink_t *sl, enum connect_type connect); } #endif -#endif // STLINK_H +#endif // STLINK_H_ diff --git a/inc/stm32.h b/inc/stm32.h index d3c4e5512..abc7f1ded 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -4,8 +4,8 @@ * STM32-specific defines & identification parametres */ -#ifndef STM32_H -#define STM32_H +#ifndef STM32_H_ +#define STM32_H_ /* STM32 Cortex-M core ids (CPUTAPID) */ enum stm32_core_id { @@ -217,4 +217,4 @@ enum stm32_chipids { #define STM32L5_PWR_CR1 0x40007000 // RM0438, p. 93,324 #define STM32L5_PWR_CR1_VOS 9 -#endif // STM32_H +#endif // STM32_H_ diff --git a/inc/stm32flash.h b/inc/stm32flash.h index 07f824837..f5f662cb6 100644 --- a/inc/stm32flash.h +++ b/inc/stm32flash.h @@ -1,5 +1,5 @@ -#ifndef STM32FLASH_H -#define STM32FLASH_H +#ifndef STM32FLASH_H_ +#define STM32FLASH_H_ /* stm32f FPEC flash controller interface, pm0063 manual */ // STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, August 2012) @@ -378,4 +378,4 @@ #define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) #define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) -#endif // STM32FLASH_H +#endif // STM32FLASH_H_ diff --git a/inc/version.h.in b/inc/version.h.in index 66159e0e5..b5ccd6e31 100644 --- a/inc/version.h.in +++ b/inc/version.h.in @@ -1,9 +1,9 @@ -#ifndef STLINK_VERSION_H_ -#define STLINK_VERSION_H_ +#ifndef VERSION_H_ +#define VERSION_H_ #define STLINK_VERSION "@PROJECT_VERSION@" #define STLINK_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ #define STLINK_VERSION_MINOR @PROJECT_VERSION_MINOR@ #define STLINK_VERSION_PATCH @PROJECT_VERSION_PATCH@ -#endif // STLINK_VERSION_H_ +#endif // VERSION_H_ diff --git a/src/st-flash/flash.h b/src/st-flash/flash.h index f3d431d65..aab57878f 100644 --- a/src/st-flash/flash.h +++ b/src/st-flash/flash.h @@ -1,5 +1,5 @@ -#ifndef STLINK_TOOLS_FLASH_H_ -#define STLINK_TOOLS_FLASH_H_ +#ifndef FLASH_H_ +#define FLASH_H_ #include @@ -33,4 +33,4 @@ struct flash_opts { int flash_get_opts(struct flash_opts* o, int ac, char** av); -#endif // STLINK_FLASH_H_ +#endif // FLASH_H_ diff --git a/src/st-util/gdb-remote.h b/src/st-util/gdb-remote.h index 6e76746b7..bcf1dbd01 100644 --- a/src/st-util/gdb-remote.h +++ b/src/st-util/gdb-remote.h @@ -1,8 +1,8 @@ -#ifndef _GDB_REMOTE_H_ -#define _GDB_REMOTE_H_ +#ifndef GDB_REMOTE_H_ +#define GDB_REMOTE_H_ int gdb_send_packet(int fd, char* data); int gdb_recv_packet(int fd, char** buffer); int gdb_check_for_interrupt(int fd); -#endif // _GDB_REMOTE_H_ +#endif // GDB_REMOTE_H_ diff --git a/src/st-util/gdb-server.h b/src/st-util/gdb-server.h index b50a7941d..3fbb16dad 100644 --- a/src/st-util/gdb-server.h +++ b/src/st-util/gdb-server.h @@ -1,5 +1,5 @@ -#ifndef _GDB_SERVER_H -#define _GDB_SERVER_H +#ifndef GDB_SERVER_H_ +#define GDB_SERVER_H_ #define STRINGIFY_inner(name) #name #define STRINGIFY(name) STRINGIFY_inner(name) @@ -8,4 +8,4 @@ #define DEBUG_LOGGING_LEVEL 100 #define DEFAULT_GDB_LISTEN_PORT 4242 -#endif // _GDB_SERVER_H +#endif // GDB_SERVER_H_ diff --git a/src/st-util/semihosting.h b/src/st-util/semihosting.h index 8c1ac15f0..2e34b4307 100644 --- a/src/st-util/semihosting.h +++ b/src/st-util/semihosting.h @@ -1,5 +1,5 @@ -#ifndef _SEMIHOSTING_H_ -#define _SEMIHOSTING_H_ +#ifndef SEMIHOSTING_H_ +#define SEMIHOSTING_H_ #include @@ -31,4 +31,4 @@ int do_semihosting(stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret); -#endif // _SEMIHOSTING_H_ +#endif // SEMIHOSTING_H_ diff --git a/src/stlink-gui/gui.h b/src/stlink-gui/gui.h index b3d5dfff8..f29ee5031 100644 --- a/src/stlink-gui/gui.h +++ b/src/stlink-gui/gui.h @@ -1,5 +1,5 @@ -#ifndef __STLINK_GUI_H__ -#define __STLINK_GUI_H__ +#ifndef GUI_H_ +#define GUI_H_ #include @@ -89,4 +89,4 @@ struct _STlinkGUIClass { GType stlink_gui_get_type(void); int export_to_file(const char*filename, const struct mem_t flash_mem); -#endif // __STLINK_GUI_H__ +#endif // GUI_H_ diff --git a/src/stlink-lib/calculate.h b/src/stlink-lib/calculate.h index 64dfb51b2..beb064297 100644 --- a/src/stlink-lib/calculate.h +++ b/src/stlink-lib/calculate.h @@ -4,12 +4,12 @@ * Calculation of sector numbers and pages */ -#ifndef CALCULATE_H -#define CALCULATE_H +#ifndef CALCULATE_H_ +#define CALCULATE_H_ uint32_t calculate_F4_sectornum(uint32_t); uint32_t calculate_F7_sectornum(uint32_t); uint32_t calculate_H7_sectornum(stlink_t *, uint32_t, unsigned); uint32_t calculate_L4_page(stlink_t *, uint32_t); -#endif // CALCULATE_H +#endif // CALCULATE_H_ diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index 1eae2cc34..b93a3f2d6 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -1,5 +1,5 @@ -#ifndef STLINK_CHIPID_H_ -#define STLINK_CHIPID_H_ +#ifndef CHIPID_H_ +#define CHIPID_H_ #include #include @@ -24,4 +24,4 @@ struct stlink_chipid_params { struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); void init_chipids(char *dir_to_scan); -#endif // STLINK_CHIPID_H_ +#endif // CHIPID_H_ diff --git a/src/stlink-lib/commands.h b/src/stlink-lib/commands.h index 136adf80e..4fa919858 100644 --- a/src/stlink-lib/commands.h +++ b/src/stlink-lib/commands.h @@ -1,5 +1,5 @@ -#ifndef STLINK_COMMANDS_H_ -#define STLINK_COMMANDS_H_ +#ifndef COMMANDS_H_ +#define COMMANDS_H_ enum stlink_commands { STLINK_GET_VERSION = 0xF1, @@ -54,4 +54,4 @@ enum stlink_dfu_commands { STLINK_DFU_EXIT = 0x07 }; -#endif // STLINK_COMMANDS_H_ +#endif // COMMANDS_H_ diff --git a/src/stlink-lib/common.h b/src/stlink-lib/common.h index dd6cf95b2..902493610 100644 --- a/src/stlink-lib/common.h +++ b/src/stlink-lib/common.h @@ -4,12 +4,12 @@ * General helper functions */ -#ifndef COMMON_H -#define COMMON_H +#ifndef COMMON_H_ +#define COMMON_H_ int check_file(stlink_t *, mapped_file_t *, stm32_addr_t); void md5_calculate(mapped_file_t *); void stlink_checksum(mapped_file_t *); void stlink_fwrite_finalize(stlink_t *, stm32_addr_t); -#endif // COMMON_H +#endif // COMMON_H_ diff --git a/src/stlink-lib/common_flash.h b/src/stlink-lib/common_flash.h index 3b6b0404a..269f8196e 100644 --- a/src/stlink-lib/common_flash.h +++ b/src/stlink-lib/common_flash.h @@ -4,8 +4,8 @@ * Flash operations */ -#ifndef COMMON_FLASH_H -#define COMMON_FLASH_H +#ifndef COMMON_FLASH_H_ +#define COMMON_FLASH_H_ void lock_flash(stlink_t *); void clear_flash_error(stlink_t *); @@ -24,4 +24,5 @@ void clear_flash_cr_pg(stlink_t *, unsigned); uint32_t read_flash_cr(stlink_t *, unsigned); uint32_t get_stm32l0_flash_base(stlink_t *); -#endif // STLINK_H + +#endif // COMMON_FLASH_H_ diff --git a/src/stlink-lib/flash_loader.h b/src/stlink-lib/flash_loader.h index 0d39a9a48..781fab74a 100644 --- a/src/stlink-lib/flash_loader.h +++ b/src/stlink-lib/flash_loader.h @@ -4,8 +4,8 @@ * Flash loader */ -#ifndef STLINK_FLASH_LOADER_H_ -#define STLINK_FLASH_LOADER_H_ +#ifndef FLASH_LOADER_H_ +#define FLASH_LOADER_H_ #include #include @@ -21,4 +21,4 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len); int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl); -#endif // STLINK_FLASH_LOADER_H_ +#endif // FLASH_LOADER_H_ diff --git a/src/stlink-lib/helper.h b/src/stlink-lib/helper.h index 96467377a..58023aff2 100644 --- a/src/stlink-lib/helper.h +++ b/src/stlink-lib/helper.h @@ -1,8 +1,8 @@ -#ifndef SYS_HELPER_H -#define SYS_HELPER_H +#ifndef HELPER_H_ +#define HELPER_H_ unsigned time_ms(); int arg_parse_freq(const char *str); -#endif /* SYS_HELPER_H */ +#endif // HELPER_H_ diff --git a/src/stlink-lib/libusb_settings.h b/src/stlink-lib/libusb_settings.h index 3777f720b..639f9e4a4 100644 --- a/src/stlink-lib/libusb_settings.h +++ b/src/stlink-lib/libusb_settings.h @@ -1,5 +1,5 @@ -#ifndef LIBUSB_SETTINGS_H -#define LIBUSB_SETTINGS_H +#ifndef LIBUSB_SETTINGS_H_ +#define LIBUSB_SETTINGS_H_ #include @@ -44,4 +44,4 @@ #error unsupported libusb version #endif -#endif // LIBUSB_SETTINGS_H +#endif // LIBUSB_SETTINGS_H_ diff --git a/src/stlink-lib/logging.h b/src/stlink-lib/logging.h index 7f3994492..7510d573e 100644 --- a/src/stlink-lib/logging.h +++ b/src/stlink-lib/logging.h @@ -2,8 +2,8 @@ * Ugly, low performance, configurable level, logging "framework" */ -#ifndef UGLYLOGGING_H -#define UGLYLOGGING_H +#ifndef LOGGING_H_ +#define LOGGING_H_ #ifdef __cplusplus extern "C" { @@ -45,4 +45,4 @@ int ugly_libusb_log_level(enum ugly_loglevel v); } #endif -#endif // UGLYLOGGING_H +#endif // LOGGING_H_ diff --git a/src/stlink-lib/map_file.h b/src/stlink-lib/map_file.h index f50a201f0..d69f6c3b5 100644 --- a/src/stlink-lib/map_file.h +++ b/src/stlink-lib/map_file.h @@ -4,8 +4,8 @@ * File mapping */ -#ifndef MAP_FILE_H -#define MAP_FILE_H +#ifndef MAP_FILE_H_ +#define MAP_FILE_H_ #ifndef O_BINARY #define O_BINARY 0 @@ -29,4 +29,4 @@ typedef struct mapped_file { int map_file(mapped_file_t *, const char *); void unmap_file(mapped_file_t *); -#endif // MAP_FILE_H +#endif // MAP_FILE_H_ diff --git a/src/stlink-lib/md5.h b/src/stlink-lib/md5.h index a69d7fc6b..7b853a4f6 100644 --- a/src/stlink-lib/md5.h +++ b/src/stlink-lib/md5.h @@ -5,6 +5,15 @@ * This is free and unencumbered software released into the public domain - June 2013 - waterjuice.org */ +/* + * File: md5.h + * + * MD5 hash function + */ + +#ifndef MD5_H_ +#define MD5_H_ + #pragma once #include @@ -61,3 +70,5 @@ void Md5Finalise(Md5Context* Context /* [in out] */, MD5_HASH* Digest /* [in] */ * Calculates the MD5 hash of the buffer. */ void Md5Calculate(void const* Buffer /* [in] */, uint32_t BufferSize /* [in] */, MD5_HASH* Digest /* [in] */); + +#endif // MD5_H_ \ No newline at end of file diff --git a/src/stlink-lib/option_bytes.h b/src/stlink-lib/option_bytes.h index b9f88c508..481a69f0a 100644 --- a/src/stlink-lib/option_bytes.h +++ b/src/stlink-lib/option_bytes.h @@ -4,6 +4,9 @@ * Read and write option bytes and option control registers */ +#ifndef OPTION_BYTES_H_ +#define OPTION_BYTES_H_ + #include #include @@ -19,3 +22,5 @@ int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_cr1); int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); + +#endif // OPTION_BYTES_H_ \ No newline at end of file diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index b581a269c..2046f8a6a 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -1,5 +1,5 @@ -#ifndef STLINK_REG_H_ -#define STLINK_REG_H_ +#ifndef REG_H_ +#define REG_H_ #define STLINK_REG_CM3_CPUID 0xE000ED00 @@ -123,4 +123,4 @@ #define STLINK_REG_CM7_ICIALLU 0xE000EF50 #define STLINK_REG_CM7_CCSIDR 0xE000ED80 -#endif // STLINK_REG_H_ +#endif // REG_H_ diff --git a/src/stlink-lib/sg.h b/src/stlink-lib/sg.h index 212d03b27..e30043fcc 100644 --- a/src/stlink-lib/sg.h +++ b/src/stlink-lib/sg.h @@ -3,8 +3,8 @@ * Author: karl */ -#ifndef STLINK_SG_H -#define STLINK_SG_H +#ifndef SG_H_ +#define SG_H_ #include #include @@ -56,4 +56,4 @@ struct stlink_libsg { stlink_t* stlink_v1_open(const int verbose, int reset); -#endif // STLINK_SG_H +#endif // SG_H_ diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index 3f4b71e51..ff6f9088e 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -3,8 +3,8 @@ * Author: karl */ -#ifndef STLINK_USB_H -#define STLINK_USB_H +#ifndef USB_H_ +#define USB_H_ #include @@ -70,4 +70,4 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int freq); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); -#endif // STLINK_USB_H +#endif // USB_H_ diff --git a/src/win32/getopt/getopt.h b/src/win32/getopt/getopt.h index 3aaf73bed..2a1bd735b 100644 --- a/src/win32/getopt/getopt.h +++ b/src/win32/getopt/getopt.h @@ -1,5 +1,5 @@ -#ifndef INCLUDED_GETOPT_PORT_H -#define INCLUDED_GETOPT_PORT_H +#ifndef GETOPT_H_ +#define GETOPT_H_ #if defined(__cplusplus) extern "C" { @@ -38,4 +38,4 @@ int getopt_long(int argc, } #endif -#endif // INCLUDED_GETOPT_PORT_H +#endif // GETOPT_H_ diff --git a/src/win32/mmap.h b/src/win32/mmap.h index 06079a9bc..ff01f4286 100644 --- a/src/win32/mmap.h +++ b/src/win32/mmap.h @@ -1,5 +1,5 @@ -#ifndef STLINK_MMAP_H -#define STLINK_MMAP_H +#ifndef MMAP_H_ +#define MMAP_H_ #ifdef STLINK_HAVE_SYS_MMAN_H #include @@ -16,6 +16,6 @@ void *mmap(void *addr, size_t len, int prot, int flags, int fd, long long offset); int munmap(void *addr, size_t len); -#endif /* HAVE_SYS_MMAN_H */ +#endif // STLINK_HAVE_SYS_MMAN_H -#endif /* STLINK_MMAP_H */ +#endif // MMAP_H_ diff --git a/src/win32/sys_time.h b/src/win32/sys_time.h index d314509b7..cb767fc31 100644 --- a/src/win32/sys_time.h +++ b/src/win32/sys_time.h @@ -1,8 +1,10 @@ -#ifndef STLINK_TIME_H -#define STLINK_TIME_H +#ifndef SYS_TIME_H_ +#define SYS_TIME_H_ #ifdef STLINK_HAVE_SYS_TIME_H + #include + #else #include @@ -14,6 +16,6 @@ struct timezone { int gettimeofday(struct timeval *tv, struct timezone *tz); -#endif /* STLINK_HAVE_SYS_TIME_H */ +#endif // STLINK_HAVE_SYS_TIME_H -#endif /* STLINK_TIME_H */ +#endif // SYS_TIME_H_ diff --git a/src/win32/unistd/unistd.h b/src/win32/unistd/unistd.h index 389c44664..b8a3db746 100644 --- a/src/win32/unistd/unistd.h +++ b/src/win32/unistd/unistd.h @@ -1,5 +1,5 @@ -#ifndef _UNISTD_H -#define _UNISTD_H 1 +#ifndef UNISTD_H_ +#define UNISTD_H_ /* * This file intended to serve as a drop-in replacement for unistd.h on Windows @@ -72,4 +72,4 @@ typedef unsigned __int64 uint64_t; int usleep(unsigned int waitTime); #endif -#endif // _UNISTD_H +#endif // UNISTD_H_ From 7c2c953ff6051c2adfdd5aa8f312bc98f9cb627c Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 30 Apr 2023 19:21:17 +0200 Subject: [PATCH 1369/1435] Unified chipid enum naming for L0 series --- config/chips/L0xxx_Cat_1.chip | 2 +- config/chips/L0xxx_Cat_3.chip | 2 +- inc/stm32.h | 4 ++-- src/stlink-lib/common_flash.c | 6 +++--- src/stlink-lib/flash_loader.c | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/config/chips/L0xxx_Cat_1.chip b/config/chips/L0xxx_Cat_1.chip index 2cce4e23c..2c6bea0eb 100644 --- a/config/chips/L0xxx_Cat_1.chip +++ b/config/chips/L0xxx_Cat_1.chip @@ -2,7 +2,7 @@ # dev_type STM32L0xxx_Cat_1 ref_manual_id 0451 // also RM0377 -chip_id 0x457 // STM32_CHIPID_L011 +chip_id 0x457 // STM32_CHIPID_L0_CAT1 flash_type L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B diff --git a/config/chips/L0xxx_Cat_3.chip b/config/chips/L0xxx_Cat_3.chip index a04dc8376..e6ad3586a 100644 --- a/config/chips/L0xxx_Cat_3.chip +++ b/config/chips/L0xxx_Cat_3.chip @@ -2,7 +2,7 @@ # dev_type STM32L0xxx_Cat_3 ref_manual_id 0451 // also RM0367 & RM0377 -chip_id 0x417 // STM32_CHIPID_L0 +chip_id 0x417 // STM32_CHIPID_L0_CAT3 flash_type L0_L1 flash_size_reg 0x1ff8007c flash_pagesize 0x80 // 128 B diff --git a/inc/stm32.h b/inc/stm32.h index abc7f1ded..ab80ff25e 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -76,7 +76,7 @@ enum stm32_chipids { STM32_CHIPID_F1_HD = 0x414, /* high density */ STM32_CHIPID_L4 = 0x415, STM32_CHIPID_L1_MD = 0x416, /* medium density */ - STM32_CHIPID_L0 = 0x417, + STM32_CHIPID_L0_CAT3 = 0x417, STM32_CHIPID_F1_CONN = 0x418, /* connectivity line */ STM32_CHIPID_F4_HD = 0x419, /* high density */ STM32_CHIPID_F1_VL_MD_LD = 0x420, /* value line medium & low density */ @@ -110,7 +110,7 @@ enum stm32_chipids { STM32_CHIPID_F76xxx = 0x451, STM32_CHIPID_F72xxx = 0x452, /* Nucleo F722ZE board */ STM32_CHIPID_G0_CAT4 = 0x456, /* G051/G061 */ - STM32_CHIPID_L011 = 0x457, + STM32_CHIPID_L0_CAT1 = 0x457, STM32_CHIPID_F410 = 0x458, STM32_CHIPID_G0_CAT2 = 0x460, /* G07x/G08x */ STM32_CHIPID_L496x_L4A6x = 0x461, diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 740c93690..dbae1c694 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -12,10 +12,10 @@ uint32_t get_stm32l0_flash_base(stlink_t *sl) { switch (sl->chip_id) { - case STM32_CHIPID_L0: - case STM32_CHIPID_L0_CAT5: + case STM32_CHIPID_L0_CAT1: case STM32_CHIPID_L0_CAT2: - case STM32_CHIPID_L011: + case STM32_CHIPID_L0_CAT3: + case STM32_CHIPID_L0_CAT5: return (STM32L0_FLASH_REGS_ADDR); case STM32_CHIPID_L1_CAT2: diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 852ba6c20..c46392cbe 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -238,10 +238,10 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STM32_CHIPID_L1_MD_PLUS || sl->chip_id == STM32_CHIPID_L1_MD_PLUS_HD || sl->chip_id == STM32_CHIPID_L152_RE || - sl->chip_id == STM32_CHIPID_L011 || - sl->chip_id == STM32_CHIPID_L0 || - sl->chip_id == STM32_CHIPID_L0_CAT5 || - sl->chip_id == STM32_CHIPID_L0_CAT2) { + sl->chip_id == STM32_CHIPID_L0_CAT1 || + sl->chip_id == STM32_CHIPID_L0_CAT2 || + sl->chip_id == STM32_CHIPID_L0_CAT3 || + sl->chip_id == STM32_CHIPID_L0_CAT5) { loader_code = loader_code_stm32lx; loader_size = sizeof(loader_code_stm32lx); } else if (sl->core_id == STM32_CORE_ID_M3_r1p1_SWD || From 823187216afbaccfcfe07da4c3c5739b65820239 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 30 Apr 2023 20:46:37 +0200 Subject: [PATCH 1370/1435] st-flash: auto-reset after mass erase --- flashloaders/Makefile | 4 ++-- flashloaders/linker.ld | 4 ++-- src/st-flash/flash.c | 6 ++++++ src/stlink-lib/flash_loader.c | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/flashloaders/Makefile b/flashloaders/Makefile index 8b01d5293..68ce5a881 100644 --- a/flashloaders/Makefile +++ b/flashloaders/Makefile @@ -1,5 +1,5 @@ -# The flash loader code cannot be compiled by the system gcc. This -# makefile use arm-none-eabi-gcc for this purpose +# The flash loader code cannot be compiled by the system gcc. +# This makefile uses arm-none-eabi-gcc for this purpose. CROSS_COMPILE ?= arm-none-eabi- diff --git a/flashloaders/linker.ld b/flashloaders/linker.ld index 7267fe10f..2d8c192ce 100644 --- a/flashloaders/linker.ld +++ b/flashloaders/linker.ld @@ -1,9 +1,9 @@ /* Entry Point */ -ENTRY( copy ) +ENTRY(copy) /* Specify the memory areas */ MEMORY { - RAM ( xrw) : ORIGIN = 0x20000000 , LENGTH = 64K + RAM (xrw) : ORIGIN = 0x20000000 , LENGTH = 64K } diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index d7d17f66f..bbb52d80c 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -188,6 +188,12 @@ int main(int ac, char** av) { goto on_error; } printf("Mass erase completed successfully.\n"); + + // reset after erase + if (stlink_reset(sl, RESET_AUTO)) { + printf("Failed to reset device\n"); + goto on_error; + } } else if (o.cmd == CMD_RESET) { diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index c46392cbe..ebdf0a44e 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -391,7 +391,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe * firmware size. */ if ((int32_t)rr.r[2] > 0 || (int32_t)rr.r[2] < -7) { - ELOG("Write error\n"); + ELOG("Flash loader write error\n"); goto error; } From 800c8616fbc8115716258b2140b667a643beadc8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 30 Apr 2023 22:32:59 +0200 Subject: [PATCH 1371/1435] Unified #define names for STM32 devices --- inc/stm32flash.h | 320 +++++++++++++++++----------------- src/stlink-lib/calculate.c | 4 +- src/stlink-lib/common.c | 8 +- src/stlink-lib/common_flash.c | 278 ++++++++++++++--------------- src/stlink-lib/flash_loader.c | 16 +- src/stlink-lib/option_bytes.c | 58 +++--- 6 files changed, 342 insertions(+), 342 deletions(-) diff --git a/inc/stm32flash.h b/inc/stm32flash.h index f5f662cb6..ccbc0289d 100644 --- a/inc/stm32flash.h +++ b/inc/stm32flash.h @@ -59,206 +59,206 @@ #define FLASH_CR_OPTWRE 9 #define FLASH_CR_OBL_LAUNCH 13 -#define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00) -#define STM32L_FLASH_ACR (STM32L_FLASH_REGS_ADDR + 0x00) -#define STM32L_FLASH_PECR (STM32L_FLASH_REGS_ADDR + 0x04) -#define STM32L_FLASH_PDKEYR (STM32L_FLASH_REGS_ADDR + 0x08) -#define STM32L_FLASH_PEKEYR (STM32L_FLASH_REGS_ADDR + 0x0c) -#define STM32L_FLASH_PRGKEYR (STM32L_FLASH_REGS_ADDR + 0x10) -#define STM32L_FLASH_OPTKEYR (STM32L_FLASH_REGS_ADDR + 0x14) -#define STM32L_FLASH_SR (STM32L_FLASH_REGS_ADDR + 0x18) -#define STM32L_FLASH_OBR (STM32L_FLASH_REGS_ADDR + 0x1c) -#define STM32L_FLASH_WRPR (STM32L_FLASH_REGS_ADDR + 0x20) +#define FLASH_Lx_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_Lx_ACR (FLASH_Lx_REGS_ADDR + 0x00) +#define FLASH_Lx_PECR (FLASH_Lx_REGS_ADDR + 0x04) +#define FLASH_Lx_PDKEYR (FLASH_Lx_REGS_ADDR + 0x08) +#define FLASH_Lx_PEKEYR (FLASH_Lx_REGS_ADDR + 0x0c) +#define FLASH_Lx_PRGKEYR (FLASH_Lx_REGS_ADDR + 0x10) +#define FLASH_Lx_OPTKEYR (FLASH_Lx_REGS_ADDR + 0x14) +#define FLASH_Lx_SR (FLASH_Lx_REGS_ADDR + 0x18) +#define FLASH_Lx_OBR (FLASH_Lx_REGS_ADDR + 0x1c) +#define FLASH_Lx_WRPR (FLASH_Lx_REGS_ADDR + 0x20) #define FLASH_L1_FPRG 10 #define FLASH_L1_PROG 3 // Flash registers common to STM32G0 and STM32G4 series (RM0440, p. 146) -#define STM32Gx_FLASH_REGS_ADDR ((uint32_t)0x40022000) -#define STM32Gx_FLASH_ACR (STM32Gx_FLASH_REGS_ADDR + 0x00) -#define STM32Gx_FLASH_KEYR (STM32Gx_FLASH_REGS_ADDR + 0x08) -#define STM32Gx_FLASH_OPTKEYR (STM32Gx_FLASH_REGS_ADDR + 0x0c) -#define STM32Gx_FLASH_SR (STM32Gx_FLASH_REGS_ADDR + 0x10) -#define STM32Gx_FLASH_CR (STM32Gx_FLASH_REGS_ADDR + 0x14) -#define STM32Gx_FLASH_ECCR (STM32Gx_FLASH_REGS_ADDR + 0x18) -#define STM32Gx_FLASH_OPTR (STM32Gx_FLASH_REGS_ADDR + 0x20) +#define FLASH_Gx_REGS_ADDR ((uint32_t)0x40022000) +#define FLASH_Gx_ACR (FLASH_Gx_REGS_ADDR + 0x00) +#define FLASH_Gx_KEYR (FLASH_Gx_REGS_ADDR + 0x08) +#define FLASH_Gx_OPTKEYR (FLASH_Gx_REGS_ADDR + 0x0c) +#define FLASH_Gx_SR (FLASH_Gx_REGS_ADDR + 0x10) +#define FLASH_Gx_CR (FLASH_Gx_REGS_ADDR + 0x14) +#define FLASH_Gx_ECCR (FLASH_Gx_REGS_ADDR + 0x18) +#define FLASH_Gx_OPTR (FLASH_Gx_REGS_ADDR + 0x20) // G0 (RM0444 Table 1, sec 3.7) // Mostly the same as G4 chips, but the notation // varies a bit after the 'OPTR' register. -#define STM32G0_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) -#define STM32G0_FLASH_PCROP1ASR (STM32G0_FLASH_REGS_ADDR + 0x24) -#define STM32G0_FLASH_PCROP1AER (STM32G0_FLASH_REGS_ADDR + 0x28) -#define STM32G0_FLASH_WRP1AR (STM32G0_FLASH_REGS_ADDR + 0x2C) -#define STM32G0_FLASH_WRP1BR (STM32G0_FLASH_REGS_ADDR + 0x30) -#define STM32G0_FLASH_PCROP1BSR (STM32G0_FLASH_REGS_ADDR + 0x34) -#define STM32G0_FLASH_PCROP1BER (STM32G0_FLASH_REGS_ADDR + 0x38) -#define STM32G0_FLASH_SECR (STM32G0_FLASH_REGS_ADDR + 0x80) +#define FLASH_G0_REGS_ADDR (FLASH_Gx_REGS_ADDR) +#define FLASH_G0_PCROP1ASR (FLASH_G0_REGS_ADDR + 0x24) +#define FLASH_G0_PCROP1AER (FLASH_G0_REGS_ADDR + 0x28) +#define FLASH_G0_WRP1AR (FLASH_G0_REGS_ADDR + 0x2C) +#define FLASH_G0_WRP1BR (FLASH_G0_REGS_ADDR + 0x30) +#define FLASH_G0_PCROP1BSR (FLASH_G0_REGS_ADDR + 0x34) +#define FLASH_G0_PCROP1BER (FLASH_G0_REGS_ADDR + 0x38) +#define FLASH_G0_SECR (FLASH_G0_REGS_ADDR + 0x80) // G4 (RM0440 Table 17, sec 3.7.19) // Mostly the same as STM32G0 chips, but there are a few extra // registers because 'cat 3' devices can have two Flash banks. -#define STM32G4_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) -#define STM32G4_FLASH_PDKEYR (STM32G4_FLASH_REGS_ADDR + 0x04) -#define STM32G4_FLASH_PCROP1SR (STM32G4_FLASH_REGS_ADDR + 0x24) -#define STM32G4_FLASH_PCROP1ER (STM32G4_FLASH_REGS_ADDR + 0x28) -#define STM32G4_FLASH_WRP1AR (STM32G4_FLASH_REGS_ADDR + 0x2C) -#define STM32G4_FLASH_WRP1BR (STM32G4_FLASH_REGS_ADDR + 0x30) -#define STM32G4_FLASH_PCROP2SR (STM32G4_FLASH_REGS_ADDR + 0x44) -#define STM32G4_FLASH_PCROP2ER (STM32G4_FLASH_REGS_ADDR + 0x48) -#define STM32G4_FLASH_WRP2AR (STM32G4_FLASH_REGS_ADDR + 0x4C) -#define STM32G4_FLASH_WRP2BR (STM32G4_FLASH_REGS_ADDR + 0x50) -#define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70) -#define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74) +#define FLASH_G4_REGS_ADDR (FLASH_Gx_REGS_ADDR) +#define FLASH_G4_PDKEYR (FLASH_G4_REGS_ADDR + 0x04) +#define FLASH_G4_PCROP1SR (FLASH_G4_REGS_ADDR + 0x24) +#define FLASH_G4_PCROP1ER (FLASH_G4_REGS_ADDR + 0x28) +#define FLASH_G4_WRP1AR (FLASH_G4_REGS_ADDR + 0x2C) +#define FLASH_G4_WRP1BR (FLASH_G4_REGS_ADDR + 0x30) +#define FLASH_G4_PCROP2SR (FLASH_G4_REGS_ADDR + 0x44) +#define FLASH_G4_PCROP2ER (FLASH_G4_REGS_ADDR + 0x48) +#define FLASH_G4_WRP2AR (FLASH_G4_REGS_ADDR + 0x4C) +#define FLASH_G4_WRP2BR (FLASH_G4_REGS_ADDR + 0x50) +#define FLASH_G4_SEC1R (FLASH_G4_REGS_ADDR + 0x70) +#define FLASH_G4_SEC2R (FLASH_G4_REGS_ADDR + 0x74) // G0/G4 FLASH control register -#define STM32Gx_FLASH_CR_PG (0) /* Program */ -#define STM32Gx_FLASH_CR_PER (1) /* Page erase */ -#define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */ -#define STM32Gx_FLASH_CR_PNB (3) /* Page number */ -#define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ -#define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ -#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ -#define STM32Gx_FLASH_CR_STRT (16) /* Start */ -#define STM32Gx_FLASH_CR_OPTSTRT \ +#define FLASH_Gx_CR_PG (0) /* Program */ +#define FLASH_Gx_CR_PER (1) /* Page erase */ +#define FLASH_Gx_CR_MER1 (2) /* Mass erase */ +#define FLASH_Gx_CR_PNB (3) /* Page number */ +#define FLASH_G0_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ +#define FLASH_G4_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ +#define FLASH_Gx_CR_MER2 (15) /* Mass erase (2nd bank)*/ +#define FLASH_Gx_CR_STRT (16) /* Start */ +#define FLASH_Gx_CR_OPTSTRT \ (17) /* Start of modification of option bytes */ -#define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ -#define STM32Gx_FLASH_CR_EOPIE (24) /* End of operation interrupt enable */ -#define STM32Gx_FLASH_CR_ERRIE (25) /* Error interrupt enable */ -#define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ -#define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ -#define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ +#define FLASH_Gx_CR_FSTPG (18) /* Fast programming */ +#define FLASH_Gx_CR_EOPIE (24) /* End of operation interrupt enable */ +#define FLASH_Gx_CR_ERRIE (25) /* Error interrupt enable */ +#define FLASH_Gx_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ +#define FLASH_Gx_CR_OPTLOCK (30) /* Options Lock */ +#define FLASH_Gx_CR_LOCK (31) /* FLASH_CR Lock */ // G0/G4 FLASH status register -#define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) -#define STM32Gx_FLASH_SR_PROGERR (3) -#define STM32Gx_FLASH_SR_WRPERR (4) -#define STM32Gx_FLASH_SR_PGAERR (5) -#define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ -#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ +#define FLASH_Gx_SR_ERROR_MASK (0x3fa) +#define FLASH_Gx_SR_PROGERR (3) +#define FLASH_Gx_SR_WRPERR (4) +#define FLASH_Gx_SR_PGAERR (5) +#define FLASH_Gx_SR_BSY (16) /* FLASH_SR Busy */ +#define FLASH_Gx_SR_EOP (0) /* FLASH_EOP End of Operation */ // G4 FLASH option register -#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ +#define FLASH_G4_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ // WB (RM0434) -#define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) -#define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) -#define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) -#define STM32WB_FLASH_OPT_KEYR (STM32WB_FLASH_REGS_ADDR + 0x0C) -#define STM32WB_FLASH_SR (STM32WB_FLASH_REGS_ADDR + 0x10) -#define STM32WB_FLASH_CR (STM32WB_FLASH_REGS_ADDR + 0x14) -#define STM32WB_FLASH_ECCR (STM32WB_FLASH_REGS_ADDR + 0x18) -#define STM32WB_FLASH_OPTR (STM32WB_FLASH_REGS_ADDR + 0x20) -#define STM32WB_FLASH_PCROP1ASR (STM32WB_FLASH_REGS_ADDR + 0x24) -#define STM32WB_FLASH_PCROP1AER (STM32WB_FLASH_REGS_ADDR + 0x28) -#define STM32WB_FLASH_WRP1AR (STM32WB_FLASH_REGS_ADDR + 0x2C) -#define STM32WB_FLASH_WRP1BR (STM32WB_FLASH_REGS_ADDR + 0x30) -#define STM32WB_FLASH_PCROP1BSR (STM32WB_FLASH_REGS_ADDR + 0x34) -#define STM32WB_FLASH_PCROP1BER (STM32WB_FLASH_REGS_ADDR + 0x38) -#define STM32WB_FLASH_IPCCBR (STM32WB_FLASH_REGS_ADDR + 0x3C) -#define STM32WB_FLASH_C2ACR (STM32WB_FLASH_REGS_ADDR + 0x5C) -#define STM32WB_FLASH_C2SR (STM32WB_FLASH_REGS_ADDR + 0x60) -#define STM32WB_FLASH_C2CR (STM32WB_FLASH_REGS_ADDR + 0x64) -#define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) -#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) +#define FLASH_WB_REGS_ADDR ((uint32_t)0x58004000) +#define FLASH_WB_ACR (FLASH_WB_REGS_ADDR + 0x00) +#define FLASH_WB_KEYR (FLASH_WB_REGS_ADDR + 0x08) +#define FLASH_WB_OPT_KEYR (FLASH_WB_REGS_ADDR + 0x0C) +#define FLASH_WB_SR (FLASH_WB_REGS_ADDR + 0x10) +#define FLASH_WB_CR (FLASH_WB_REGS_ADDR + 0x14) +#define FLASH_WB_ECCR (FLASH_WB_REGS_ADDR + 0x18) +#define FLASH_WB_OPTR (FLASH_WB_REGS_ADDR + 0x20) +#define FLASH_WB_PCROP1ASR (FLASH_WB_REGS_ADDR + 0x24) +#define FLASH_WB_PCROP1AER (FLASH_WB_REGS_ADDR + 0x28) +#define FLASH_WB_WRP1AR (FLASH_WB_REGS_ADDR + 0x2C) +#define FLASH_WB_WRP1BR (FLASH_WB_REGS_ADDR + 0x30) +#define FLASH_WB_PCROP1BSR (FLASH_WB_REGS_ADDR + 0x34) +#define FLASH_WB_PCROP1BER (FLASH_WB_REGS_ADDR + 0x38) +#define FLASH_WB_IPCCBR (FLASH_WB_REGS_ADDR + 0x3C) +#define FLASH_WB_C2ACR (FLASH_WB_REGS_ADDR + 0x5C) +#define FLASH_WB_C2SR (FLASH_WB_REGS_ADDR + 0x60) +#define FLASH_WB_C2CR (FLASH_WB_REGS_ADDR + 0x64) +#define FLASH_WB_SFR (FLASH_WB_REGS_ADDR + 0x80) +#define FLASH_WB_SRRVR (FLASH_WB_REGS_ADDR + 0x84) // WB Flash control register. -#define STM32WB_FLASH_CR_STRT (16) /* Start */ -#define STM32WB_FLASH_CR_OPTSTRT (17) /* Start writing option bytes */ -#define STM32WB_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ -#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ -#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ +#define FLASH_WB_CR_STRT (16) /* Start */ +#define FLASH_WB_CR_OPTSTRT (17) /* Start writing option bytes */ +#define FLASH_WB_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ +#define FLASH_WB_CR_OPTLOCK (30) /* Option Lock */ +#define FLASH_WB_CR_LOCK (31) /* Lock */ // WB Flash status register. -#define STM32WB_FLASH_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ -#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ -#define STM32WB_FLASH_SR_WRPERR (4) /* Write protection error */ -#define STM32WB_FLASH_SR_PGAERR (5) /* Programming error */ -#define STM32WB_FLASH_SR_BSY (16) /* Busy */ +#define FLASH_WB_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ +#define FLASH_WB_SR_PROGERR (3) /* Programming alignment error */ +#define FLASH_WB_SR_WRPERR (4) /* Write protection error */ +#define FLASH_WB_SR_PGAERR (5) /* Programming error */ +#define FLASH_WB_SR_BSY (16) /* Busy */ // 32L4 register base is at FLASH_REGS_ADDR (0x40022000) -#define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) -#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) -#define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) -#define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) -#define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) - -#define STM32L4_FLASH_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ -#define STM32L4_FLASH_SR_PROGERR 3 -#define STM32L4_FLASH_SR_WRPERR 4 -#define STM32L4_FLASH_SR_PGAERR 5 -#define STM32L4_FLASH_SR_BSY 16 - -#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ -#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ -#define STM32L4_FLASH_CR_PG 0 /* Program */ -#define STM32L4_FLASH_CR_PER 1 /* Page erase */ -#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ -#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ -#define STM32L4_FLASH_CR_STRT 16 /* Start command */ -#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ -#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ -#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ -#define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ +#define FLASH_L4_KEYR (FLASH_REGS_ADDR + 0x08) +#define FLASH_L4_OPTKEYR (FLASH_REGS_ADDR + 0x0C) +#define FLASH_L4_SR (FLASH_REGS_ADDR + 0x10) +#define FLASH_L4_CR (FLASH_REGS_ADDR + 0x14) +#define FLASH_L4_OPTR (FLASH_REGS_ADDR + 0x20) + +#define FLASH_L4_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ +#define FLASH_L4_SR_PROGERR 3 +#define FLASH_L4_SR_WRPERR 4 +#define FLASH_L4_SR_PGAERR 5 +#define FLASH_L4_SR_BSY 16 + +#define FLASH_L4_CR_LOCK 31 /* Lock control register */ +#define FLASH_L4_CR_OPTLOCK 30 /* Lock option bytes */ +#define FLASH_L4_CR_PG 0 /* Program */ +#define FLASH_L4_CR_PER 1 /* Page erase */ +#define FLASH_L4_CR_MER1 2 /* Bank 1 erase */ +#define FLASH_L4_CR_MER2 15 /* Bank 2 erase */ +#define FLASH_L4_CR_STRT 16 /* Start command */ +#define FLASH_L4_CR_OPTSTRT 17 /* Start writing option bytes */ +#define FLASH_L4_CR_BKER 11 /* Bank select for page erase */ +#define FLASH_L4_CR_PNB 3 /* Page number (8 bits) */ +#define FLASH_L4_CR_OBL_LAUNCH 27 /* Option bytes reload */ // Bits requesting flash operations (useful when we want to clear them) -#define STM32L4_FLASH_CR_OPBITS \ - (uint32_t)((1lu << STM32L4_FLASH_CR_PG) | (1lu << STM32L4_FLASH_CR_PER) | \ - (1lu << STM32L4_FLASH_CR_MER1) | (1lu << STM32L4_FLASH_CR_MER1)) +#define FLASH_L4_CR_OPBITS \ + (uint32_t)((1lu << FLASH_L4_CR_PG) | (1lu << FLASH_L4_CR_PER) | \ + (1lu << FLASH_L4_CR_MER1) | (1lu << FLASH_L4_CR_MER1)) // Page is fully specified by BKER and PNB -#define STM32L4_FLASH_CR_PAGEMASK (uint32_t)(0x1fflu << STM32L4_FLASH_CR_PNB) +#define FLASH_L4_CR_PAGEMASK (uint32_t)(0x1fflu << FLASH_L4_CR_PNB) -#define STM32L4_FLASH_OPTR_DUALBANK 21 +#define FLASH_L4_OPTR_DUALBANK 21 // Flash registers common to STM32L5 series (RM0438, p. 241) -#define STM32L5_FLASH_REGS_ADDR ((uint32_t)0x40022000) -#define STM32L5_FLASH_ACR (STM32L5_FLASH_REGS_ADDR + 0x00) -#define STM32L5_FLASH_NSKEYR (STM32L5_FLASH_REGS_ADDR + 0x08) -#define STM32L5_FLASH_OPTKEYR (STM32L5_FLASH_REGS_ADDR + 0x10) -#define STM32L5_FLASH_NSSR (STM32L5_FLASH_REGS_ADDR + 0x20) -#define STM32L5_FLASH_NSCR (STM32L5_FLASH_REGS_ADDR + 0x28) -#define STM32L5_FLASH_ECCR (STM32L5_FLASH_REGS_ADDR + 0x30) -#define STM32L5_FLASH_OPTR (STM32L5_FLASH_REGS_ADDR + 0x40) +#define FLASH_L5_REGS_ADDR ((uint32_t)0x40022000) +#define FLASH_L5_ACR (FLASH_L5_REGS_ADDR + 0x00) +#define FLASH_L5_NSKEYR (FLASH_L5_REGS_ADDR + 0x08) +#define FLASH_L5_OPTKEYR (FLASH_L5_REGS_ADDR + 0x10) +#define FLASH_L5_NSSR (FLASH_L5_REGS_ADDR + 0x20) +#define FLASH_L5_NSCR (FLASH_L5_REGS_ADDR + 0x28) +#define FLASH_L5_ECCR (FLASH_L5_REGS_ADDR + 0x30) +#define FLASH_L5_OPTR (FLASH_L5_REGS_ADDR + 0x40) // FLASH_NSCR (RM0438, p. 242) -#define STM32L5_FLASH_NSCR_NSPG 0 /* Program */ -#define STM32L5_FLASH_NSCR_NSPER 1 /* Page erase */ -#define STM32L5_FLASH_NSCR_NSMER1 2 /* Bank 1 erase */ -#define STM32L5_FLASH_NSCR_NSPNB 3 /* Page number (7 bits) */ -#define STM32L5_FLASH_NSCR_NSBKER 11 /* Bank select for page erase */ -#define STM32L5_FLASH_NSCR_NSMER2 15 /* Bank 2 erase */ -#define STM32L5_FLASH_NSCR_NSSTRT 16 /* Start command */ -#define STM32L5_FLASH_NSCR_NSOPTSTRT 17 /* Start writing option bytes */ -#define STM32L5_FLASH_NSCR_NSEOPIE 24 -#define STM32L5_FLASH_NSCR_NSERRIE 25 -#define STM32L5_FLASH_NSCR_OBL_LAUNCH 27 /* Option bytes reload */ -#define STM32L5_FLASH_NSCR_OPTLOCK 30 /* Lock option bytes */ -#define STM32L5_FLASH_NSCR_NSLOCK 31 /* Lock control register */ +#define FLASH_L5_NSCR_NSPG 0 /* Program */ +#define FLASH_L5_NSCR_NSPER 1 /* Page erase */ +#define FLASH_L5_NSCR_NSMER1 2 /* Bank 1 erase */ +#define FLASH_L5_NSCR_NSPNB 3 /* Page number (7 bits) */ +#define FLASH_L5_NSCR_NSBKER 11 /* Bank select for page erase */ +#define FLASH_L5_NSCR_NSMER2 15 /* Bank 2 erase */ +#define FLASH_L5_NSCR_NSSTRT 16 /* Start command */ +#define FLASH_L5_NSCR_NSOPTSTRT 17 /* Start writing option bytes */ +#define FLASH_L5_NSCR_NSEOPIE 24 +#define FLASH_L5_NSCR_NSERRIE 25 +#define FLASH_L5_NSCR_OBL_LAUNCH 27 /* Option bytes reload */ +#define FLASH_L5_NSCR_OPTLOCK 30 /* Lock option bytes */ +#define FLASH_L5_NSCR_NSLOCK 31 /* Lock control register */ // FLASH_NSSR (RM0438, p. 241) -#define STM32L5_FLASH_NSSR_NSEOP 0 /* End of Operation */ -#define STM32L5_FLASH_NSSR_NSOPERR 1 -#define STM32L5_FLASH_NSSR_NSPROGERR 3 -#define STM32L5_FLASH_NSSR_NSWRPERR 4 -#define STM32L5_FLASH_NSSR_NSPGAERR 5 -#define STM32L5_FLASH_NSSR_NSSIZERR 6 -#define STM32L5_FLASH_NSSR_NSPGSERR 7 -#define STM32L5_FLASH_NSSR_OPTWERR 12 -#define STM32L5_FLASH_NSSR_BSY 16 /* Busy */ -#define STM32L5_FLASH_NSSR_ERROR_MASK (0x20fa) +#define FLASH_L5_NSSR_NSEOP 0 /* End of Operation */ +#define FLASH_L5_NSSR_NSOPERR 1 +#define FLASH_L5_NSSR_NSPROGERR 3 +#define FLASH_L5_NSSR_NSWRPERR 4 +#define FLASH_L5_NSSR_NSPGAERR 5 +#define FLASH_L5_NSSR_NSSIZERR 6 +#define FLASH_L5_NSSR_NSPGSERR 7 +#define FLASH_L5_NSSR_OPTWERR 12 +#define FLASH_L5_NSSR_BSY 16 /* Busy */ +#define FLASH_L5_NSSR_ERROR_MASK (0x20fa) // STM32L0x flash register base and offsets RM0090 - DM00031020.pdf -#define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) +#define FLASH_L0_REGS_ADDR ((uint32_t)0x40022000) -#define STM32L0_FLASH_PELOCK (0) -#define STM32L0_FLASH_OPTLOCK (2) -#define STM32L0_FLASH_OBL_LAUNCH (18) +#define FLASH_L0_PELOCK (0) +#define FLASH_L0_OPTLOCK (2) +#define FLASH_L0_OBL_LAUNCH (18) -#define STM32L0_FLASH_SR_ERROR_MASK 0x00013F00 -#define STM32L0_FLASH_SR_WRPERR 8 -#define STM32L0_FLASH_SR_PGAERR 9 -#define STM32L0_FLASH_SR_NOTZEROERR 16 +#define FLASH_L0_SR_ERROR_MASK 0x00013F00 +#define FLASH_L0_SR_WRPERR 8 +#define FLASH_L0_SR_PGAERR 9 +#define FLASH_L0_SR_NOTZEROERR 16 -#define STM32L1_FLASH_SR_ERROR_MASK 0x00003F00 -#define STM32L1_FLASH_SR_WRPERR 8 -#define STM32L1_FLASH_SR_PGAERR 9 +#define FLASH_L1_SR_ERROR_MASK 0x00003F00 +#define FLASH_L1_SR_WRPERR 8 +#define FLASH_L1_SR_PGAERR 9 #define FLASH_ACR_OFF ((uint32_t)0x00) #define FLASH_PECR_OFF ((uint32_t)0x04) diff --git a/src/stlink-lib/calculate.c b/src/stlink-lib/calculate.c index ed3b65873..ddab5ed08 100644 --- a/src/stlink-lib/calculate.c +++ b/src/stlink-lib/calculate.c @@ -51,14 +51,14 @@ uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { uint32_t bker = 0; uint32_t flashopt; - stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); + stlink_read_debug32(sl, FLASH_L4_OPTR, &flashopt); flashaddr -= STM32_FLASH_BASE; if (sl->chip_id == STM32_CHIPID_L4 || sl->chip_id == STM32_CHIPID_L496x_L4A6x || sl->chip_id == STM32_CHIPID_L4Rx) { // this chip use dual banked flash - if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { + if (flashopt & (uint32_t)(1lu << FLASH_L4_OPTR_DUALBANK)) { uint32_t banksize = (uint32_t)sl->flash_size / 2; if (flashaddr >= banksize) { diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index fac97278e..f2d60ce45 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -288,16 +288,16 @@ int stlink_load_device_params(stlink_t *sl) { if (sl->chip_id == STM32_CHIPID_G4_CAT3) { uint32_t flash_optr; - stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); + stlink_read_debug32(sl, FLASH_Gx_OPTR, &flash_optr); - if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { + if (!(flash_optr & (1 << FLASH_G4_OPTR_DBANK))) { sl->flash_pgsz <<= 1; } } if (sl->chip_id == STM32_CHIPID_L5x2xx) { uint32_t flash_optr; - stlink_read_debug32(sl, STM32L5_FLASH_OPTR, &flash_optr); + stlink_read_debug32(sl, FLASH_L5_OPTR, &flash_optr); if (sl->flash_size == 512*1024 && (flash_optr & (1 << 22)) != 0) { sl->flash_pgsz = 0x800; @@ -1099,7 +1099,7 @@ static void stop_wdg_in_debug(stlink_t *sl) { break; case STM32_FLASH_TYPE_L0_L1: case STM32_FLASH_TYPE_G0: - if (get_stm32l0_flash_base(sl) == STM32L_FLASH_REGS_ADDR) { + if (get_stm32l0_flash_base(sl) == FLASH_Lx_REGS_ADDR) { dbgmcu_cr = STM32L1_DBGMCU_APB1_FZ; set = (1 << STM32L1_DBGMCU_APB1_FZ_IWDG_STOP) | (1 << STM32L1_DBGMCU_APB1_FZ_WWDG_STOP); diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index dbae1c694..dc33fdfcb 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -16,18 +16,18 @@ uint32_t get_stm32l0_flash_base(stlink_t *sl) { case STM32_CHIPID_L0_CAT2: case STM32_CHIPID_L0_CAT3: case STM32_CHIPID_L0_CAT5: - return (STM32L0_FLASH_REGS_ADDR); + return (FLASH_L0_REGS_ADDR); case STM32_CHIPID_L1_CAT2: case STM32_CHIPID_L1_MD: case STM32_CHIPID_L1_MD_PLUS: case STM32_CHIPID_L1_MD_PLUS_HD: case STM32_CHIPID_L152_RE: - return (STM32L_FLASH_REGS_ADDR); + return (FLASH_Lx_REGS_ADDR); default: WLOG("Flash base use default L0 address\n"); - return (STM32L0_FLASH_REGS_ADDR); + return (FLASH_L0_REGS_ADDR); } } @@ -40,15 +40,15 @@ uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { reg = FLASH_F7_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { - reg = STM32Gx_FLASH_CR; + reg = FLASH_Gx_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - reg = STM32L4_FLASH_CR; + reg = FLASH_L4_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - reg = STM32L5_FLASH_NSCR; + reg = FLASH_L5_NSCR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - reg = STM32WB_FLASH_CR; + reg = FLASH_WB_CR; } else { reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; } @@ -80,22 +80,22 @@ void lock_flash(stlink_t *sl) { cr_lock_shift = FLASH_F7_CR_LOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + cr_reg = FLASH_Gx_CR; + cr_lock_shift = FLASH_Gx_CR_LOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = FLASH_H7_CR1; } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - cr_lock_shift = STM32L0_FLASH_PELOCK; + cr_lock_shift = FLASH_L0_PELOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_lock_shift = STM32L4_FLASH_CR_LOCK; + cr_reg = FLASH_L4_CR; + cr_lock_shift = FLASH_L4_CR_LOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - cr_reg = STM32L5_FLASH_NSCR; - cr_lock_shift = STM32L5_FLASH_NSCR_NSLOCK; + cr_reg = FLASH_L5_NSCR; + cr_lock_shift = FLASH_L5_NSCR_NSLOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; - cr_lock_shift = STM32WB_FLASH_CR_LOCK; + cr_reg = FLASH_WB_CR; + cr_lock_shift = FLASH_WB_CR_LOCK; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { cr2_reg = FLASH_H7_CR2; } @@ -129,17 +129,17 @@ static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { sr_reg = FLASH_F7_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { - sr_reg = STM32Gx_FLASH_SR; + sr_reg = FLASH_Gx_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - sr_reg = STM32L4_FLASH_SR; + sr_reg = FLASH_L4_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - sr_reg = STM32L5_FLASH_NSSR; + sr_reg = FLASH_L5_NSSR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - sr_reg = STM32WB_FLASH_SR; + sr_reg = FLASH_WB_SR; } else { ELOG("method 'write_flash_sr' is unsupported\n"); return (-1); @@ -161,7 +161,7 @@ void clear_flash_error(stlink_t *sl) { break; case STM32_FLASH_TYPE_G0: case STM32_FLASH_TYPE_G4: - write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); + write_flash_sr(sl, BANK_1, FLASH_Gx_SR_ERROR_MASK); break; case STM32_FLASH_TYPE_H7: write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); @@ -170,20 +170,20 @@ void clear_flash_error(stlink_t *sl) { } break; case STM32_FLASH_TYPE_L0_L1: - if (get_stm32l0_flash_base(sl) == STM32L_FLASH_REGS_ADDR) { - write_flash_sr(sl, BANK_1, STM32L1_FLASH_SR_ERROR_MASK); + if (get_stm32l0_flash_base(sl) == FLASH_Lx_REGS_ADDR) { + write_flash_sr(sl, BANK_1, FLASH_L1_SR_ERROR_MASK); } else { - write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); + write_flash_sr(sl, BANK_1, FLASH_L0_SR_ERROR_MASK); } break; case STM32_FLASH_TYPE_L4: - write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); + write_flash_sr(sl, BANK_1, FLASH_L4_SR_ERROR_MASK); break; case STM32_FLASH_TYPE_L5_U5: - write_flash_sr(sl, BANK_1, STM32L5_FLASH_NSSR_ERROR_MASK); + write_flash_sr(sl, BANK_1, FLASH_L5_NSSR_ERROR_MASK); break; case STM32_FLASH_TYPE_WB_WL: - write_flash_sr(sl, BANK_1, STM32WB_FLASH_SR_ERROR_MASK); + write_flash_sr(sl, BANK_1, FLASH_WB_SR_ERROR_MASK); break; default: break; @@ -202,17 +202,17 @@ uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { sr_reg = FLASH_F7_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { - sr_reg = STM32Gx_FLASH_SR; + sr_reg = FLASH_Gx_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - sr_reg = STM32L4_FLASH_SR; + sr_reg = FLASH_L4_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - sr_reg = STM32L5_FLASH_NSSR; + sr_reg = FLASH_L5_NSSR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - sr_reg = STM32WB_FLASH_SR; + sr_reg = FLASH_WB_SR; } else { ELOG("method 'read_flash_sr' is unsupported\n"); return (-1); @@ -236,15 +236,15 @@ unsigned int is_flash_busy(stlink_t *sl) { sr_busy_shift = FLASH_F7_SR_BSY; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { - sr_busy_shift = STM32Gx_FLASH_SR_BSY; + sr_busy_shift = FLASH_Gx_SR_BSY; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { sr_busy_shift = FLASH_H7_SR_QW; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - sr_busy_shift = STM32L4_FLASH_SR_BSY; + sr_busy_shift = FLASH_L4_SR_BSY; } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - sr_busy_shift = STM32L5_FLASH_NSSR_BSY; + sr_busy_shift = FLASH_L5_NSSR_BSY; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - sr_busy_shift = STM32WB_FLASH_SR_BSY; + sr_busy_shift = FLASH_WB_SR_BSY; } else { ELOG("method 'is_flash_busy' is unsupported\n"); return (-1); @@ -295,10 +295,10 @@ int check_flash_error(stlink_t *sl) { break; case STM32_FLASH_TYPE_G0: case STM32_FLASH_TYPE_G4: - res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32Gx_FLASH_SR_WRPERR); - PROGERR = (1 << STM32Gx_FLASH_SR_PROGERR); - PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); + res = read_flash_sr(sl, BANK_1) & FLASH_Gx_SR_ERROR_MASK; + WRPERR = (1 << FLASH_Gx_SR_WRPERR); + PROGERR = (1 << FLASH_Gx_SR_PROGERR); + PGAERR = (1 << FLASH_Gx_SR_PGAERR); break; case STM32_FLASH_TYPE_H7: res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; @@ -309,32 +309,32 @@ int check_flash_error(stlink_t *sl) { break; case STM32_FLASH_TYPE_L0_L1: res = read_flash_sr(sl, BANK_1); - if (get_stm32l0_flash_base(sl) == STM32L_FLASH_REGS_ADDR) { - res &= STM32L1_FLASH_SR_ERROR_MASK; + if (get_stm32l0_flash_base(sl) == FLASH_Lx_REGS_ADDR) { + res &= FLASH_L1_SR_ERROR_MASK; } else { - res &= STM32L0_FLASH_SR_ERROR_MASK; - PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); + res &= FLASH_L0_SR_ERROR_MASK; + PROGERR = (1 << FLASH_L0_SR_NOTZEROERR); } - WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); - PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); + WRPERR = (1 << FLASH_L0_SR_WRPERR); + PGAERR = (1 << FLASH_L0_SR_PGAERR); break; case STM32_FLASH_TYPE_L4: - res = read_flash_sr(sl, BANK_1) & STM32L4_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32L4_FLASH_SR_WRPERR); - PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); - PGAERR = (1 << STM32L4_FLASH_SR_PGAERR); + res = read_flash_sr(sl, BANK_1) & FLASH_L4_SR_ERROR_MASK; + WRPERR = (1 << FLASH_L4_SR_WRPERR); + PROGERR = (1 << FLASH_L4_SR_PROGERR); + PGAERR = (1 << FLASH_L4_SR_PGAERR); break; case STM32_FLASH_TYPE_L5_U5: - res = read_flash_sr(sl, BANK_1) & STM32L5_FLASH_NSSR_ERROR_MASK; - WRPERR = (1 << STM32L5_FLASH_NSSR_NSWRPERR); - PROGERR = (1 << STM32L5_FLASH_NSSR_NSPROGERR); - PGAERR = (1 << STM32L5_FLASH_NSSR_NSPGAERR); + res = read_flash_sr(sl, BANK_1) & FLASH_L5_NSSR_ERROR_MASK; + WRPERR = (1 << FLASH_L5_NSSR_NSWRPERR); + PROGERR = (1 << FLASH_L5_NSSR_NSPROGERR); + PGAERR = (1 << FLASH_L5_NSSR_NSPGAERR); break; case STM32_FLASH_TYPE_WB_WL: - res = read_flash_sr(sl, BANK_1) & STM32WB_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32WB_FLASH_SR_WRPERR); - PROGERR = (1 << STM32WB_FLASH_SR_PROGERR); - PGAERR = (1 << STM32WB_FLASH_SR_PGAERR); + res = read_flash_sr(sl, BANK_1) & FLASH_WB_SR_ERROR_MASK; + WRPERR = (1 << FLASH_WB_SR_WRPERR); + PROGERR = (1 << FLASH_WB_SR_PROGERR); + PGAERR = (1 << FLASH_WB_SR_PGAERR); break; default: break; @@ -379,23 +379,23 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { cr_lock_shift = FLASH_F7_CR_LOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + cr_reg = FLASH_Gx_CR; + cr_lock_shift = FLASH_Gx_CR_LOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = FLASH_H7_CR1; cr_lock_shift = FLASH_H7_CR_LOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - cr_lock_shift = STM32L0_FLASH_PELOCK; + cr_lock_shift = FLASH_L0_PELOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_lock_shift = STM32L4_FLASH_CR_LOCK; + cr_reg = FLASH_L4_CR; + cr_lock_shift = FLASH_L4_CR_LOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - cr_reg = STM32L5_FLASH_NSCR; - cr_lock_shift = STM32L5_FLASH_NSCR_NSLOCK; + cr_reg = FLASH_L5_NSCR; + cr_lock_shift = FLASH_L5_NSCR_NSLOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; - cr_lock_shift = STM32WB_FLASH_CR_LOCK; + cr_reg = FLASH_WB_CR; + cr_lock_shift = FLASH_WB_CR_LOCK; } else { ELOG("unsupported flash method, abort\n"); return (-1); @@ -425,7 +425,7 @@ static void unlock_flash(stlink_t *sl) { key_reg = FLASH_F7_KEYR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { - key_reg = STM32Gx_FLASH_KEYR; + key_reg = FLASH_Gx_KEYR; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { key_reg = FLASH_H7_KEYR1; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { @@ -436,7 +436,7 @@ static void unlock_flash(stlink_t *sl) { flash_key1 = FLASH_L0_PEKEY1; flash_key2 = FLASH_L0_PEKEY2; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - key_reg = STM32L4_FLASH_KEYR; + key_reg = FLASH_L4_KEYR; } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { // Set voltage scaling to range 0 to perform flash operations (RM0438 p. 183) uint32_t mask = (0b11 << STM32L5_PWR_CR1_VOS); @@ -445,9 +445,9 @@ static void unlock_flash(stlink_t *sl) { val &= ~mask; stlink_write_debug32(sl, STM32L5_PWR_CR1, val); } - key_reg = STM32L5_FLASH_NSKEYR; + key_reg = FLASH_L5_NSKEYR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - key_reg = STM32WB_FLASH_KEYR; + key_reg = FLASH_WB_KEYR; } else { ELOG("unsupported flash method, abort\n"); return; @@ -498,8 +498,8 @@ int lock_flash_option(stlink_t *sl) { break; case STM32_FLASH_TYPE_G0: case STM32_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + optcr_reg = FLASH_Gx_CR; + optlock_shift = FLASH_Gx_CR_OPTLOCK; break; case STM32_FLASH_TYPE_H7: optcr_reg = FLASH_H7_OPTCR; @@ -509,19 +509,19 @@ int lock_flash_option(stlink_t *sl) { break; case STM32_FLASH_TYPE_L0_L1: optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - optlock_shift = STM32L0_FLASH_OPTLOCK; + optlock_shift = FLASH_L0_OPTLOCK; break; case STM32_FLASH_TYPE_L4: - optcr_reg = STM32L4_FLASH_CR; - optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + optcr_reg = FLASH_L4_CR; + optlock_shift = FLASH_L4_CR_OPTLOCK; break; case STM32_FLASH_TYPE_L5_U5: - optcr_reg = STM32L5_FLASH_NSCR; - optlock_shift = STM32L5_FLASH_NSCR_OPTLOCK; + optcr_reg = FLASH_L5_NSCR; + optlock_shift = FLASH_L5_NSCR_OPTLOCK; break; case STM32_FLASH_TYPE_WB_WL: - optcr_reg = STM32WB_FLASH_CR; - optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + optcr_reg = FLASH_WB_CR; + optlock_shift = FLASH_WB_CR_OPTLOCK; break; default: ELOG("unsupported flash method, abort\n"); @@ -575,8 +575,8 @@ static bool is_flash_option_locked(stlink_t *sl) { break; case STM32_FLASH_TYPE_G0: case STM32_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + optcr_reg = FLASH_Gx_CR; + optlock_shift = FLASH_Gx_CR_OPTLOCK; break; case STM32_FLASH_TYPE_H7: optcr_reg = FLASH_H7_OPTCR; @@ -584,19 +584,19 @@ static bool is_flash_option_locked(stlink_t *sl) { break; case STM32_FLASH_TYPE_L0_L1: optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - optlock_shift = STM32L0_FLASH_OPTLOCK; + optlock_shift = FLASH_L0_OPTLOCK; break; case STM32_FLASH_TYPE_L4: - optcr_reg = STM32L4_FLASH_CR; - optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + optcr_reg = FLASH_L4_CR; + optlock_shift = FLASH_L4_CR_OPTLOCK; break; case STM32_FLASH_TYPE_L5_U5: - optcr_reg = STM32L5_FLASH_NSCR; - optlock_shift = STM32L5_FLASH_NSCR_OPTLOCK; + optcr_reg = FLASH_L5_NSCR; + optlock_shift = FLASH_L5_NSCR_OPTLOCK; break; case STM32_FLASH_TYPE_WB_WL: - optcr_reg = STM32WB_FLASH_CR; - optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + optcr_reg = FLASH_WB_CR; + optlock_shift = FLASH_WB_CR_OPTLOCK; break; default: ELOG("unsupported flash method, abort\n"); @@ -632,7 +632,7 @@ static int unlock_flash_option(stlink_t *sl) { break; case STM32_FLASH_TYPE_G0: case STM32_FLASH_TYPE_G4: - optkey_reg = STM32Gx_FLASH_OPTKEYR; + optkey_reg = FLASH_Gx_OPTKEYR; break; case STM32_FLASH_TYPE_H7: optkey_reg = FLASH_H7_OPT_KEYR; @@ -645,13 +645,13 @@ static int unlock_flash_option(stlink_t *sl) { optkey2 = FLASH_L0_OPTKEY2; break; case STM32_FLASH_TYPE_L4: - optkey_reg = STM32L4_FLASH_OPTKEYR; + optkey_reg = FLASH_L4_OPTKEYR; break; case STM32_FLASH_TYPE_L5_U5: - optkey_reg = STM32L5_FLASH_OPTKEYR; + optkey_reg = FLASH_L5_OPTKEYR; break; case STM32_FLASH_TYPE_WB_WL: - optkey_reg = STM32WB_FLASH_OPT_KEYR; + optkey_reg = FLASH_WB_OPT_KEYR; break; default: ELOG("unsupported flash method, abort\n"); @@ -717,16 +717,16 @@ void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { cr_reg = FLASH_F7_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; + cr_reg = FLASH_Gx_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; bit = FLASH_H7_CR_PG; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; + cr_reg = FLASH_L4_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - cr_reg = STM32L5_FLASH_NSCR; + cr_reg = FLASH_L5_NSCR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; + cr_reg = FLASH_WB_CR; } else { cr_reg = FLASH_CR; } @@ -788,11 +788,11 @@ static void set_flash_cr_per(stlink_t *sl, unsigned bank) { if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; + cr_reg = FLASH_Gx_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - cr_reg = STM32L5_FLASH_NSCR; + cr_reg = FLASH_L5_NSCR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; + cr_reg = FLASH_WB_CR; } else { cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; } @@ -807,11 +807,11 @@ static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; + cr_reg = FLASH_Gx_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - cr_reg = STM32L5_FLASH_NSCR; + cr_reg = FLASH_L5_NSCR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; + cr_reg = FLASH_WB_CR; } else { cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; } @@ -821,19 +821,19 @@ static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { } static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { - stlink_write_debug32(sl, STM32L4_FLASH_SR, - 0xFFFFFFFF & ~(1 << STM32L4_FLASH_SR_BSY)); + stlink_write_debug32(sl, FLASH_L4_SR, + 0xFFFFFFFF & ~(1 << FLASH_L4_SR_BSY)); uint32_t x = read_flash_cr(sl, BANK_1); - x &= ~STM32L4_FLASH_CR_OPBITS; - x &= ~STM32L4_FLASH_CR_PAGEMASK; - x &= ~(1 << STM32L4_FLASH_CR_MER1); - x &= ~(1 << STM32L4_FLASH_CR_MER2); - x |= (n << STM32L4_FLASH_CR_PNB); - x |= (uint32_t)(1lu << STM32L4_FLASH_CR_PER); + x &= ~FLASH_L4_CR_OPBITS; + x &= ~FLASH_L4_CR_PAGEMASK; + x &= ~(1 << FLASH_L4_CR_MER1); + x &= ~(1 << FLASH_L4_CR_MER2); + x |= (n << FLASH_L4_CR_PNB); + x |= (uint32_t)(1lu << FLASH_L4_CR_PER); #if DEBUG_FLASH fprintf(stdout, "BKER:PNB:0x%x 0x%x\n", x, n); #endif - stlink_write_debug32(sl, STM32L4_FLASH_CR, x); + stlink_write_debug32(sl, FLASH_L4_CR, x); } static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { @@ -847,20 +847,20 @@ static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { cr_strt = 1 << FLASH_F7_CR_STRT; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_strt = (1 << STM32Gx_FLASH_CR_STRT); + cr_reg = FLASH_Gx_CR; + cr_strt = (1 << FLASH_Gx_CR_STRT); } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; cr_strt = 1 << FLASH_H7_CR_START(sl->chip_id); } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_strt = (1 << STM32L4_FLASH_CR_STRT); + cr_reg = FLASH_L4_CR; + cr_strt = (1 << FLASH_L4_CR_STRT); } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - cr_reg = STM32L5_FLASH_NSCR; - cr_strt = (1 << STM32L5_FLASH_NSCR_NSSTRT); + cr_reg = FLASH_L5_NSCR; + cr_strt = (1 << FLASH_L5_NSCR_NSSTRT); } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; - cr_strt = (1 << STM32WB_FLASH_CR_STRT); + cr_reg = FLASH_WB_CR; + cr_strt = (1 << FLASH_WB_CR_STRT); } else { cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; cr_strt = (1 << FLASH_CR_STRT); @@ -884,10 +884,10 @@ static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { cr_pg = 1 << FLASH_CR_PG; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_mer = (1 << STM32Gx_FLASH_CR_MER1); + cr_reg = FLASH_Gx_CR; + cr_mer = (1 << FLASH_Gx_CR_MER1); if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); + cr_mer |= (1 << FLASH_Gx_CR_MER2); } cr_pg = (1 << FLASH_CR_PG); } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { @@ -895,15 +895,15 @@ static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { cr_mer = (1 << FLASH_H7_CR_BER); cr_pg = (1 << FLASH_H7_CR_PG); } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); - cr_pg = (1 << STM32L4_FLASH_CR_PG); + cr_reg = FLASH_L4_CR; + cr_mer = (1 << FLASH_L4_CR_MER1) | (1 << FLASH_L4_CR_MER2); + cr_pg = (1 << FLASH_L4_CR_PG); } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - cr_reg = STM32L5_FLASH_NSCR; - cr_mer = (1 << STM32L5_FLASH_NSCR_NSMER1) | (1 << STM32L5_FLASH_NSCR_NSMER2); - cr_pg = (1 << STM32L5_FLASH_NSCR_NSPG); + cr_reg = FLASH_L5_NSCR; + cr_mer = (1 << FLASH_L5_NSCR_NSMER1) | (1 << FLASH_L5_NSCR_NSMER2); + cr_pg = (1 << FLASH_L5_NSCR_NSPG); } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; + cr_reg = FLASH_WB_CR; cr_mer = (1 << FLASH_CR_MER); cr_pg = (1 << FLASH_CR_PG); } else { @@ -1059,47 +1059,47 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if (sl->flash_type == STM32_FLASH_TYPE_G0) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + stlink_read_debug32(sl, FLASH_Gx_CR, &val); // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. val &= ~(0x3F << 3); val |= ((flash_page & 0x3F) << 3) | (1 << FLASH_CR_PER); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + stlink_write_debug32(sl, FLASH_Gx_CR, val); } else if (sl->flash_type == STM32_FLASH_TYPE_G4) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + stlink_read_debug32(sl, FLASH_Gx_CR, &val); // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. val &= ~(0x7F << 3); val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + stlink_write_debug32(sl, FLASH_Gx_CR, val); } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { uint32_t flash_page; - stlink_read_debug32(sl, STM32L5_FLASH_NSCR, &val); + stlink_read_debug32(sl, FLASH_L5_NSCR, &val); if (sl->flash_pgsz == 0x800 && (flashaddr - STM32_FLASH_BASE) >= sl->flash_size/2) { flash_page = (flashaddr - STM32_FLASH_BASE - sl->flash_size/2) / (uint32_t)(sl->flash_pgsz); // set bank 2 for erasure - val |= (1 << STM32L5_FLASH_NSCR_NSBKER); + val |= (1 << FLASH_L5_NSCR_NSBKER); } else { flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); // set bank 1 for erasure - val &= ~(1 << STM32L5_FLASH_NSCR_NSBKER); + val &= ~(1 << FLASH_L5_NSCR_NSBKER); } // sec 6.9.9 val &= ~(0x7F << 3); val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); - stlink_write_debug32(sl, STM32L5_FLASH_NSCR, val); + stlink_write_debug32(sl, FLASH_L5_NSCR, val); } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + stlink_read_debug32(sl, FLASH_WB_CR, &val); // sec 3.10.5 - PNB[7:0] is offset by 3. val &= ~(0xFF << 3); // Clear previously set page number (if any) val |= ((flash_page & 0xFF) << 3); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + stlink_write_debug32(sl, FLASH_WB_CR, val); } set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index ebdf0a44e..f0ce9be42 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -495,18 +495,18 @@ static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { cr_reg = FLASH_F7_CR; x |= 1 << FLASH_CR_PG; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - x &= ~STM32L4_FLASH_CR_OPBITS; - x |= (1 << STM32L4_FLASH_CR_PG); + cr_reg = FLASH_L4_CR; + x &= ~FLASH_L4_CR_OPBITS; + x |= (1 << FLASH_L4_CR_PG); } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - cr_reg = STM32L5_FLASH_NSCR; + cr_reg = FLASH_L5_NSCR; x |= (1 << FLASH_CR_PG); } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; + cr_reg = FLASH_Gx_CR; x |= (1 << FLASH_CR_PG); } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - cr_reg = STM32WB_FLASH_CR; + cr_reg = FLASH_WB_CR; x |= (1 << FLASH_CR_PG); } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; @@ -545,7 +545,7 @@ static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { rcc_dma_mask = STM32G4_RCC_DMAEN; break; case STM32_FLASH_TYPE_L0_L1: - if (get_stm32l0_flash_base(sl) == STM32L_FLASH_REGS_ADDR) { + if (get_stm32l0_flash_base(sl) == FLASH_Lx_REGS_ADDR) { rcc = STM32L1_RCC_AHBENR; rcc_dma_mask = STM32L1_RCC_DMAEN; } else { @@ -770,7 +770,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { uint32_t val; uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - uint32_t pagesize = (flash_regs_base==STM32L0_FLASH_REGS_ADDR)? + uint32_t pagesize = (flash_regs_base == FLASH_L0_REGS_ADDR)? L0_WRITE_BLOCK_SIZE:L1_WRITE_BLOCK_SIZE; DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c index 9cbdd097b..f5932a7b9 100644 --- a/src/stlink-lib/option_bytes.c +++ b/src/stlink-lib/option_bytes.c @@ -429,7 +429,7 @@ stlink_write_option_bytes_boot_add_f7(stlink_t *sl, uint32_t option_byte_boot_ad * @return 0 on success, -ve on failure. */ int stlink_read_option_control_register_gx(stlink_t *sl, uint32_t *option_byte) { - return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); + return stlink_read_debug32(sl, FLASH_Gx_OPTR, option_byte); } /** @@ -461,21 +461,21 @@ static int stlink_write_option_bytes_gx(stlink_t *sl, stm32_addr_t addr, uint8_t write_uint32((unsigned char *)&data, *(uint32_t *)(base)); WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); + stlink_write_debug32(sl, FLASH_Gx_OPTR, data); // Set Options Start bit - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + stlink_read_debug32(sl, FLASH_Gx_CR, &val); + val |= (1 << FLASH_Gx_CR_OPTSTRT); + stlink_write_debug32(sl, FLASH_Gx_CR, val); wait_flash_busy(sl); ret = check_flash_error(sl); // Reload options - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + stlink_read_debug32(sl, FLASH_Gx_CR, &val); + val |= (1 << FLASH_Gx_CR_OBL_LAUNCH); + stlink_write_debug32(sl, FLASH_Gx_CR, val); return (ret); } @@ -584,7 +584,7 @@ static int stlink_write_option_bytes_l0(stlink_t *sl, stm32_addr_t addr, uint8_t // Reload options stlink_read_debug32(sl, flash_base + FLASH_PECR_OFF, &val); - val |= (1 << STM32L0_FLASH_OBL_LAUNCH); + val |= (1 << FLASH_L0_OBL_LAUNCH); stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); return (ret); @@ -612,20 +612,20 @@ static int stlink_write_option_bytes_l4(stlink_t *sl, stm32_addr_t addr, uint8_t uint32_t data; write_uint32((unsigned char *)&data, *(uint32_t *)(base)); WLOG("Writing option bytes 0x%04x\n", data); - stlink_write_debug32(sl, STM32L4_FLASH_OPTR, data); + stlink_write_debug32(sl, FLASH_L4_OPTR, data); // set options start bit - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1 << STM32L4_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + stlink_read_debug32(sl, FLASH_L4_CR, &val); + val |= (1 << FLASH_L4_CR_OPTSTRT); + stlink_write_debug32(sl, FLASH_L4_CR, val); wait_flash_busy(sl); ret = check_flash_error(sl); // apply options bytes immediate - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + stlink_read_debug32(sl, FLASH_L4_CR, &val); + val |= (1 << FLASH_L4_CR_OBL_LAUNCH); + stlink_write_debug32(sl, FLASH_L4_CR, val); return (ret); } @@ -664,18 +664,18 @@ static int stlink_write_option_bytes_wb(stlink_t *sl, stm32_addr_t addr, uint8_t } // Set Options Start bit - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - val |= (1 << STM32WB_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + stlink_read_debug32(sl, FLASH_WB_CR, &val); + val |= (1 << FLASH_WB_CR_OPTSTRT); + stlink_write_debug32(sl, FLASH_WB_CR, val); wait_flash_busy(sl); ret = check_flash_error(sl); // Reload options - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - val |= (1 << STM32WB_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + stlink_read_debug32(sl, FLASH_WB_CR, &val); + val |= (1 << FLASH_WB_CR_OBL_LAUNCH); + stlink_write_debug32(sl, FLASH_WB_CR, val); return (ret); } @@ -687,8 +687,8 @@ static int stlink_write_option_bytes_wb(stlink_t *sl, stm32_addr_t addr, uint8_t * @return 0 on success, -ve on failure. */ int stlink_read_option_control_register_wb(stlink_t *sl, uint32_t *option_byte) { - DLOG("@@@@ Read option control register byte from %#10x\n", STM32WB_FLASH_OPTR); - return stlink_read_debug32(sl, STM32WB_FLASH_OPTR, option_byte); + DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_WB_OPTR); + return stlink_read_debug32(sl, FLASH_WB_OPTR, option_byte); } /** @@ -704,22 +704,22 @@ static int stlink_write_option_control_register_wb(stlink_t *sl, uint32_t option clear_flash_error(sl); ILOG("Asked to write option control register 1 %#10x to %#010x.\n", - option_cr, STM32WB_FLASH_OPTR); + option_cr, FLASH_WB_OPTR); /* write option byte, ensuring we dont lock opt, and set strt bit */ - stlink_write_debug32(sl, STM32WB_FLASH_OPTR, option_cr); + stlink_write_debug32(sl, FLASH_WB_OPTR, option_cr); wait_flash_busy(sl); // Set Options Start bit - uint32_t val = (1 << STM32WB_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + uint32_t val = (1 << FLASH_WB_CR_OPTSTRT); + stlink_write_debug32(sl, FLASH_WB_CR, val); wait_flash_busy(sl); ret = check_flash_error(sl); if (!ret) - ILOG("Wrote option bytes %#010x to %#010x!\n", option_cr, STM32WB_FLASH_OPTR); + ILOG("Wrote option bytes %#010x to %#010x!\n", option_cr, FLASH_WB_OPTR); return ret; } From 5621d541d9b175e0fb6d1354fedd1da5ff5c1902 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 3 May 2023 13:55:19 +0200 Subject: [PATCH 1372/1435] Resorted #defines in stm32flash.h --- inc/stm32flash.h | 498 ++++++++++++++++++---------------- src/stlink-lib/common.c | 3 +- src/stlink-lib/common_flash.c | 2 +- src/stlink-lib/flash_loader.c | 4 +- 4 files changed, 269 insertions(+), 238 deletions(-) diff --git a/inc/stm32flash.h b/inc/stm32flash.h index ccbc0289d..12d2f5a7b 100644 --- a/inc/stm32flash.h +++ b/inc/stm32flash.h @@ -1,8 +1,8 @@ #ifndef STM32FLASH_H_ #define STM32FLASH_H_ -/* stm32f FPEC flash controller interface, pm0063 manual */ -// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, August 2012) +/* STM32Fx FPEC flash controller interface, PM0063 manual */ +// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev.2, Aug 2012) #define FLASH_REGS_ADDR 0x40022000 #define FLASH_REGS_SIZE 0x28 @@ -15,32 +15,19 @@ #define FLASH_OBR (FLASH_REGS_ADDR + 0x1c) #define FLASH_WRPR (FLASH_REGS_ADDR + 0x20) -// STM32F10x_XL has two flash memory banks with separate registers to control -// the second bank. +// STM32F10x_XL has two flash memory banks +// with separate registers to control the second bank. #define FLASH_KEYR2 (FLASH_REGS_ADDR + 0x44) #define FLASH_SR2 (FLASH_REGS_ADDR + 0x4c) #define FLASH_CR2 (FLASH_REGS_ADDR + 0x50) #define FLASH_AR2 (FLASH_REGS_ADDR + 0x54) -// For STM32F05x, the RDPTR_KEY may be wrong, but as it is not used anywhere... #define FLASH_RDPTR_KEY 0x00a5 #define FLASH_KEY1 0x45670123 #define FLASH_KEY2 0xcdef89ab -#define FLASH_L0_PRGKEY1 0x8c9daebf -#define FLASH_L0_PRGKEY2 0x13141516 - -#define FLASH_L0_PEKEY1 0x89abcdef -#define FLASH_L0_PEKEY2 0x02030405 - -#define FLASH_OPTKEY1 0x08192A3B -#define FLASH_OPTKEY2 0x4C5D6E7F - -#define FLASH_F0_OPTKEY1 0x45670123 -#define FLASH_F0_OPTKEY2 0xCDEF89AB - -#define FLASH_L0_OPTKEY1 0xFBEAD9C8 -#define FLASH_L0_OPTKEY2 0x24252627 +#define FLASH_OPTKEY1 0x08192a3b +#define FLASH_OPTKEY2 0x4c5d6e7f #define FLASH_SR_BSY 0 #define FLASH_SR_PG_ERR 2 @@ -59,20 +46,99 @@ #define FLASH_CR_OPTWRE 9 #define FLASH_CR_OBL_LAUNCH 13 -#define FLASH_Lx_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_Lx_ACR (FLASH_Lx_REGS_ADDR + 0x00) -#define FLASH_Lx_PECR (FLASH_Lx_REGS_ADDR + 0x04) -#define FLASH_Lx_PDKEYR (FLASH_Lx_REGS_ADDR + 0x08) -#define FLASH_Lx_PEKEYR (FLASH_Lx_REGS_ADDR + 0x0c) -#define FLASH_Lx_PRGKEYR (FLASH_Lx_REGS_ADDR + 0x10) -#define FLASH_Lx_OPTKEYR (FLASH_Lx_REGS_ADDR + 0x14) -#define FLASH_Lx_SR (FLASH_Lx_REGS_ADDR + 0x18) -#define FLASH_Lx_OBR (FLASH_Lx_REGS_ADDR + 0x1c) -#define FLASH_Lx_WRPR (FLASH_Lx_REGS_ADDR + 0x20) -#define FLASH_L1_FPRG 10 -#define FLASH_L1_PROG 3 +#define FLASH_ACR_OFF ((uint32_t)0x00) +#define FLASH_PECR_OFF ((uint32_t)0x04) +#define FLASH_PDKEYR_OFF ((uint32_t)0x08) +#define FLASH_PEKEYR_OFF ((uint32_t)0x0c) +#define FLASH_PRGKEYR_OFF ((uint32_t)0x10) +#define FLASH_OPTKEYR_OFF ((uint32_t)0x14) +#define FLASH_SR_OFF ((uint32_t)0x18) +#define FLASH_OBR_OFF ((uint32_t)0x1c) +#define FLASH_WRPR_OFF ((uint32_t)0x20) + +// == STM32F0 == +#define FLASH_F0_OPTKEY1 0x45670123 +#define FLASH_F0_OPTKEY2 0xcdef89ab + +// == STM32F2 == +#define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F2_KEYR (FLASH_F2_REGS_ADDR + 0x04) +#define FLASH_F2_OPT_KEYR (FLASH_F2_REGS_ADDR + 0x08) +#define FLASH_F2_SR (FLASH_F2_REGS_ADDR + 0x0c) +#define FLASH_F2_CR (FLASH_F2_REGS_ADDR + 0x10) +#define FLASH_F2_OPT_CR (FLASH_F2_REGS_ADDR + 0x14) +#define FLASH_F2_OPT_LOCK_BIT (1u << 0) + +// F2 Flash control register +#define FLASH_F2_CR_STRT 16 +#define FLASH_F2_CR_LOCK 31 +#define FLASH_F2_CR_SER 1 +#define FLASH_F2_CR_SNB 3 +#define FLASH_F2_CR_SNB_MASK 0x78 + +// F2 Flash status register +#define FLASH_F2_SR_BSY 16 + +// == STM32F4 == +// F4 Flash registers +#define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) +#define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08) +#define FLASH_F4_SR (FLASH_F4_REGS_ADDR + 0x0c) +#define FLASH_F4_CR (FLASH_F4_REGS_ADDR + 0x10) +#define FLASH_F4_OPTCR (FLASH_F4_REGS_ADDR + 0x14) +#define FLASH_F4_OPTCR_LOCK 0 +#define FLASH_F4_OPTCR_START 1 + +// F4 Flash control register +#define FLASH_F4_CR_STRT 16 +#define FLASH_F4_CR_LOCK 31 +#define FLASH_F4_CR_SER 1 +#define FLASH_F4_CR_SNB 3 +#define FLASH_F4_CR_SNB_MASK 0xf8 + +// F4 Flash status register +#define FLASH_F4_SR_ERROR_MASK 0x000000F0 +#define FLASH_F4_SR_PGAERR 5 +#define FLASH_F4_SR_WRPERR 4 +#define FLASH_F4_SR_BSY 16 -// Flash registers common to STM32G0 and STM32G4 series (RM0440, p. 146) +// == STM32F7 == +// F7 Flash registers +#define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) +#define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) +#define FLASH_F7_SR (FLASH_F7_REGS_ADDR + 0x0c) +#define FLASH_F7_CR (FLASH_F7_REGS_ADDR + 0x10) +#define FLASH_F7_OPTCR (FLASH_F7_REGS_ADDR + 0x14) +#define FLASH_F7_OPTCR1 (FLASH_F7_REGS_ADDR + 0x18) +#define FLASH_F7_OPTCR_LOCK 0 +#define FLASH_F7_OPTCR_START 1 +#define FLASH_F7_OPTCR1_BOOT_ADD0 0 +#define FLASH_F7_OPTCR1_BOOT_ADD1 16 + +// F7 Flash control register +#define FLASH_F7_CR_STRT 16 +#define FLASH_F7_CR_LOCK 31 +#define FLASH_F7_CR_SER 1 +#define FLASH_F7_CR_SNB 3 +#define FLASH_F7_CR_SNB_MASK 0xf8 + +// F7 Flash status register +#define FLASH_F7_SR_BSY 16 +#define FLASH_F7_SR_ERS_ERR 7 /* Erase Sequence Error */ +#define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ +#define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ +#define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ +#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ +#define FLASH_F7_SR_EOP 0 /* End of operation */ +#define FLASH_F7_SR_ERROR_MASK \ + ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | \ + (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | \ + (1 << FLASH_F7_SR_OP_ERR)) + +// == STM32G0/G4 == +// G0/G4 Flash registers (RM0440, p.146) #define FLASH_Gx_REGS_ADDR ((uint32_t)0x40022000) #define FLASH_Gx_ACR (FLASH_Gx_REGS_ADDR + 0x00) #define FLASH_Gx_KEYR (FLASH_Gx_REGS_ADDR + 0x08) @@ -82,111 +148,171 @@ #define FLASH_Gx_ECCR (FLASH_Gx_REGS_ADDR + 0x18) #define FLASH_Gx_OPTR (FLASH_Gx_REGS_ADDR + 0x20) -// G0 (RM0444 Table 1, sec 3.7) +// G0/G4 Flash control register +#define FLASH_Gx_CR_PG (0) /* Program */ +#define FLASH_Gx_CR_PER (1) /* Page erase */ +#define FLASH_Gx_CR_MER1 (2) /* Mass erase */ +#define FLASH_Gx_CR_PNB (3) /* Page number */ +#define FLASH_G0_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ +#define FLASH_G4_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ +#define FLASH_Gx_CR_MER2 (15) /* Mass erase (2nd bank)*/ +#define FLASH_Gx_CR_STRT (16) /* Start */ +#define FLASH_Gx_CR_OPTSTRT (17) /* Start of modification of option bytes */ +#define FLASH_Gx_CR_FSTPG (18) /* Fast programming */ +#define FLASH_Gx_CR_EOPIE (24) /* End of operation interrupt enable */ +#define FLASH_Gx_CR_ERRIE (25) /* Error interrupt enable */ +#define FLASH_Gx_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ +#define FLASH_Gx_CR_OPTLOCK (30) /* Options Lock */ +#define FLASH_Gx_CR_LOCK (31) /* FLASH_CR Lock */ + +// G0/G4 Flash status register +#define FLASH_Gx_SR_ERROR_MASK (0x3fa) +#define FLASH_Gx_SR_PROGERR (3) +#define FLASH_Gx_SR_WRPERR (4) +#define FLASH_Gx_SR_PGAERR (5) +#define FLASH_Gx_SR_BSY (16) /* FLASH_SR Busy */ +#define FLASH_Gx_SR_EOP (0) /* FLASH_EOP End of Operation */ + +// == STM32G0 == (RM0444 Table 1, sec. 3.7) // Mostly the same as G4 chips, but the notation // varies a bit after the 'OPTR' register. #define FLASH_G0_REGS_ADDR (FLASH_Gx_REGS_ADDR) #define FLASH_G0_PCROP1ASR (FLASH_G0_REGS_ADDR + 0x24) #define FLASH_G0_PCROP1AER (FLASH_G0_REGS_ADDR + 0x28) -#define FLASH_G0_WRP1AR (FLASH_G0_REGS_ADDR + 0x2C) +#define FLASH_G0_WRP1AR (FLASH_G0_REGS_ADDR + 0x2c) #define FLASH_G0_WRP1BR (FLASH_G0_REGS_ADDR + 0x30) #define FLASH_G0_PCROP1BSR (FLASH_G0_REGS_ADDR + 0x34) #define FLASH_G0_PCROP1BER (FLASH_G0_REGS_ADDR + 0x38) #define FLASH_G0_SECR (FLASH_G0_REGS_ADDR + 0x80) -// G4 (RM0440 Table 17, sec 3.7.19) -// Mostly the same as STM32G0 chips, but there are a few extra -// registers because 'cat 3' devices can have two Flash banks. +// == STM32G4 == (RM0440 Table 17, sec. 3.7.19) + +#define FLASH_G4_OPTR_DBANK (22) /* FLASH option register FLASH_OPTR Dual-Bank Mode */ + +// There are a few extra registers because 'cat 3' devices can have +// two Flash banks. #define FLASH_G4_REGS_ADDR (FLASH_Gx_REGS_ADDR) #define FLASH_G4_PDKEYR (FLASH_G4_REGS_ADDR + 0x04) #define FLASH_G4_PCROP1SR (FLASH_G4_REGS_ADDR + 0x24) #define FLASH_G4_PCROP1ER (FLASH_G4_REGS_ADDR + 0x28) -#define FLASH_G4_WRP1AR (FLASH_G4_REGS_ADDR + 0x2C) +#define FLASH_G4_WRP1AR (FLASH_G4_REGS_ADDR + 0x2c) #define FLASH_G4_WRP1BR (FLASH_G4_REGS_ADDR + 0x30) #define FLASH_G4_PCROP2SR (FLASH_G4_REGS_ADDR + 0x44) #define FLASH_G4_PCROP2ER (FLASH_G4_REGS_ADDR + 0x48) -#define FLASH_G4_WRP2AR (FLASH_G4_REGS_ADDR + 0x4C) +#define FLASH_G4_WRP2AR (FLASH_G4_REGS_ADDR + 0x4c) #define FLASH_G4_WRP2BR (FLASH_G4_REGS_ADDR + 0x50) #define FLASH_G4_SEC1R (FLASH_G4_REGS_ADDR + 0x70) #define FLASH_G4_SEC2R (FLASH_G4_REGS_ADDR + 0x74) -// G0/G4 FLASH control register -#define FLASH_Gx_CR_PG (0) /* Program */ -#define FLASH_Gx_CR_PER (1) /* Page erase */ -#define FLASH_Gx_CR_MER1 (2) /* Mass erase */ -#define FLASH_Gx_CR_PNB (3) /* Page number */ -#define FLASH_G0_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ -#define FLASH_G4_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ -#define FLASH_Gx_CR_MER2 (15) /* Mass erase (2nd bank)*/ -#define FLASH_Gx_CR_STRT (16) /* Start */ -#define FLASH_Gx_CR_OPTSTRT \ - (17) /* Start of modification of option bytes */ -#define FLASH_Gx_CR_FSTPG (18) /* Fast programming */ -#define FLASH_Gx_CR_EOPIE (24) /* End of operation interrupt enable */ -#define FLASH_Gx_CR_ERRIE (25) /* Error interrupt enable */ -#define FLASH_Gx_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ -#define FLASH_Gx_CR_OPTLOCK (30) /* Options Lock */ -#define FLASH_Gx_CR_LOCK (31) /* FLASH_CR Lock */ +// == STM32H7 == +// H7 Flash registers +#define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) +#define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) +#define FLASH_H7_KEYR2 (FLASH_H7_REGS_ADDR + 0x104) +#define FLASH_H7_OPT_KEYR (FLASH_H7_REGS_ADDR + 0x08) +#define FLASH_H7_OPT_KEYR2 (FLASH_H7_REGS_ADDR + 0x108) +#define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c) +#define FLASH_H7_CR2 (FLASH_H7_REGS_ADDR + 0x10c) +#define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) +#define FLASH_H7_SR2 (FLASH_H7_REGS_ADDR + 0x110) +#define FLASH_H7_CCR1 (FLASH_H7_REGS_ADDR + 0x14) +#define FLASH_H7_CCR2 (FLASH_H7_REGS_ADDR + 0x114) +#define FLASH_H7_OPTCR (FLASH_H7_REGS_ADDR + 0x18) +#define FLASH_H7_OPTCR2 (FLASH_H7_REGS_ADDR + 0x118) +#define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) +#define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) -// G0/G4 FLASH status register -#define FLASH_Gx_SR_ERROR_MASK (0x3fa) -#define FLASH_Gx_SR_PROGERR (3) -#define FLASH_Gx_SR_WRPERR (4) -#define FLASH_Gx_SR_PGAERR (5) -#define FLASH_Gx_SR_BSY (16) /* FLASH_SR Busy */ -#define FLASH_Gx_SR_EOP (0) /* FLASH_EOP End of Operation */ +#define FLASH_H7_OPTCR_OPTLOCK 0 +#define FLASH_H7_OPTCR_OPTSTART 1 +#define FLASH_H7_OPTCR_MER 4 -// G4 FLASH option register -#define FLASH_G4_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ +#define FLASH_H7_OPTSR_OPT_BUSY 0 +#define FLASH_H7_OPTSR_OPTCHANGEERR 30 -// WB (RM0434) -#define FLASH_WB_REGS_ADDR ((uint32_t)0x58004000) -#define FLASH_WB_ACR (FLASH_WB_REGS_ADDR + 0x00) -#define FLASH_WB_KEYR (FLASH_WB_REGS_ADDR + 0x08) -#define FLASH_WB_OPT_KEYR (FLASH_WB_REGS_ADDR + 0x0C) -#define FLASH_WB_SR (FLASH_WB_REGS_ADDR + 0x10) -#define FLASH_WB_CR (FLASH_WB_REGS_ADDR + 0x14) -#define FLASH_WB_ECCR (FLASH_WB_REGS_ADDR + 0x18) -#define FLASH_WB_OPTR (FLASH_WB_REGS_ADDR + 0x20) -#define FLASH_WB_PCROP1ASR (FLASH_WB_REGS_ADDR + 0x24) -#define FLASH_WB_PCROP1AER (FLASH_WB_REGS_ADDR + 0x28) -#define FLASH_WB_WRP1AR (FLASH_WB_REGS_ADDR + 0x2C) -#define FLASH_WB_WRP1BR (FLASH_WB_REGS_ADDR + 0x30) -#define FLASH_WB_PCROP1BSR (FLASH_WB_REGS_ADDR + 0x34) -#define FLASH_WB_PCROP1BER (FLASH_WB_REGS_ADDR + 0x38) -#define FLASH_WB_IPCCBR (FLASH_WB_REGS_ADDR + 0x3C) -#define FLASH_WB_C2ACR (FLASH_WB_REGS_ADDR + 0x5C) -#define FLASH_WB_C2SR (FLASH_WB_REGS_ADDR + 0x60) -#define FLASH_WB_C2CR (FLASH_WB_REGS_ADDR + 0x64) -#define FLASH_WB_SFR (FLASH_WB_REGS_ADDR + 0x80) -#define FLASH_WB_SRRVR (FLASH_WB_REGS_ADDR + 0x84) +#define FLASH_H7_OPTCCR_CLR_OPTCHANGEERR 30 -// WB Flash control register. -#define FLASH_WB_CR_STRT (16) /* Start */ -#define FLASH_WB_CR_OPTSTRT (17) /* Start writing option bytes */ -#define FLASH_WB_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ -#define FLASH_WB_CR_OPTLOCK (30) /* Option Lock */ -#define FLASH_WB_CR_LOCK (31) /* Lock */ -// WB Flash status register. -#define FLASH_WB_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ -#define FLASH_WB_SR_PROGERR (3) /* Programming alignment error */ -#define FLASH_WB_SR_WRPERR (4) /* Write protection error */ -#define FLASH_WB_SR_PGAERR (5) /* Programming error */ -#define FLASH_WB_SR_BSY (16) /* Busy */ +// H7 Flash control register +#define FLASH_H7_CR_LOCK 0 +#define FLASH_H7_CR_PG 1 +#define FLASH_H7_CR_SER 2 +#define FLASH_H7_CR_BER 3 +#define FLASH_H7_CR_PSIZE 4 +#define FLASH_H7_CR_START(chipid) (chipid == STM32_CHIPID_H7Ax ? 5 : 7) +#define FLASH_H7_CR_SNB 8 +#define FLASH_H7_CR_SNB_MASK 0x700 -// 32L4 register base is at FLASH_REGS_ADDR (0x40022000) +// H7 Flash status register +#define FLASH_H7_SR_QW 2 +#define FLASH_H7_SR_WRPERR 17 +#define FLASH_H7_SR_PGSERR 18 +#define FLASH_H7_SR_STRBERR 19 +#define FLASH_H7_SR_ERROR_MASK \ + ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | \ + (1 << FLASH_H7_SR_WRPERR)) + +// == STM32L0/L1/L4/L5 == +// Lx Flash registers +#define FLASH_Lx_REGS_ADDR ((uint32_t)0x40023c00) +#define FLASH_Lx_ACR (FLASH_Lx_REGS_ADDR + 0x00) +#define FLASH_Lx_PECR (FLASH_Lx_REGS_ADDR + 0x04) +#define FLASH_Lx_PDKEYR (FLASH_Lx_REGS_ADDR + 0x08) +#define FLASH_Lx_PEKEYR (FLASH_Lx_REGS_ADDR + 0x0c) +#define FLASH_Lx_PRGKEYR (FLASH_Lx_REGS_ADDR + 0x10) +#define FLASH_Lx_OPTKEYR (FLASH_Lx_REGS_ADDR + 0x14) +#define FLASH_Lx_SR (FLASH_Lx_REGS_ADDR + 0x18) +#define FLASH_Lx_OBR (FLASH_Lx_REGS_ADDR + 0x1c) +#define FLASH_Lx_WRPR (FLASH_Lx_REGS_ADDR + 0x20) + +// == STM32L0 == +// L0 Flash registers +#define FLASH_L0_PEKEY1 0x89abcdef +#define FLASH_L0_PEKEY2 0x02030405 + +#define FLASH_L0_PRGKEY1 0x8c9daebf +#define FLASH_L0_PRGKEY2 0x13141516 + +#define FLASH_L0_OPTKEY1 0xFBEAD9C8 +#define FLASH_L0_OPTKEY2 0x24252627 + +#define FLASH_L0_REGS_ADDR ((uint32_t)0x40022000) + +#define FLASH_L0_PELOCK (0) +#define FLASH_L0_OPTLOCK (2) +#define FLASH_L0_OBL_LAUNCH (18) + +// L0 Flash status register +#define FLASH_L0_SR_ERROR_MASK 0x00013f00 +#define FLASH_L0_SR_WRPERR 8 +#define FLASH_L0_SR_PGAERR 9 +#define FLASH_L0_SR_NOTZEROERR 16 + +// == STM32L1 == +// L1 Flash registers +#define FLASH_L1_FPRG 10 +#define FLASH_L1_PROG 3 + +// L1 Flash status register +#define FLASH_L1_SR_ERROR_MASK 0x00003f00 +#define FLASH_L1_SR_WRPERR 8 +#define FLASH_L1_SR_PGAERR 9 + +// == STM32L4 == +// L4 Flash registers +// L4 register base is at FLASH_REGS_ADDR (0x40022000) #define FLASH_L4_KEYR (FLASH_REGS_ADDR + 0x08) -#define FLASH_L4_OPTKEYR (FLASH_REGS_ADDR + 0x0C) +#define FLASH_L4_OPTKEYR (FLASH_REGS_ADDR + 0x0c) #define FLASH_L4_SR (FLASH_REGS_ADDR + 0x10) #define FLASH_L4_CR (FLASH_REGS_ADDR + 0x14) #define FLASH_L4_OPTR (FLASH_REGS_ADDR + 0x20) +// L4 Flash status register #define FLASH_L4_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ #define FLASH_L4_SR_PROGERR 3 #define FLASH_L4_SR_WRPERR 4 #define FLASH_L4_SR_PGAERR 5 #define FLASH_L4_SR_BSY 16 +// L4 Flash control register #define FLASH_L4_CR_LOCK 31 /* Lock control register */ #define FLASH_L4_CR_OPTLOCK 30 /* Lock option bytes */ #define FLASH_L4_CR_PG 0 /* Program */ @@ -207,7 +333,8 @@ #define FLASH_L4_OPTR_DUALBANK 21 -// Flash registers common to STM32L5 series (RM0438, p. 241) +// == STM32L5 == (RM0438, p.241) +// L5 Flash registers #define FLASH_L5_REGS_ADDR ((uint32_t)0x40022000) #define FLASH_L5_ACR (FLASH_L5_REGS_ADDR + 0x00) #define FLASH_L5_NSKEYR (FLASH_L5_REGS_ADDR + 0x08) @@ -217,7 +344,7 @@ #define FLASH_L5_ECCR (FLASH_L5_REGS_ADDR + 0x30) #define FLASH_L5_OPTR (FLASH_L5_REGS_ADDR + 0x40) -// FLASH_NSCR (RM0438, p. 242) +// FLASH_NSCR control registers (RM0438, p. 242) #define FLASH_L5_NSCR_NSPG 0 /* Program */ #define FLASH_L5_NSCR_NSPER 1 /* Page erase */ #define FLASH_L5_NSCR_NSMER1 2 /* Bank 1 erase */ @@ -232,7 +359,7 @@ #define FLASH_L5_NSCR_OPTLOCK 30 /* Lock option bytes */ #define FLASH_L5_NSCR_NSLOCK 31 /* Lock control register */ -// FLASH_NSSR (RM0438, p. 241) +// FLASH_NSSR status register (RM0438, p. 241) #define FLASH_L5_NSSR_NSEOP 0 /* End of Operation */ #define FLASH_L5_NSSR_NSOPERR 1 #define FLASH_L5_NSSR_NSPROGERR 3 @@ -244,138 +371,41 @@ #define FLASH_L5_NSSR_BSY 16 /* Busy */ #define FLASH_L5_NSSR_ERROR_MASK (0x20fa) -// STM32L0x flash register base and offsets RM0090 - DM00031020.pdf -#define FLASH_L0_REGS_ADDR ((uint32_t)0x40022000) - -#define FLASH_L0_PELOCK (0) -#define FLASH_L0_OPTLOCK (2) -#define FLASH_L0_OBL_LAUNCH (18) - -#define FLASH_L0_SR_ERROR_MASK 0x00013F00 -#define FLASH_L0_SR_WRPERR 8 -#define FLASH_L0_SR_PGAERR 9 -#define FLASH_L0_SR_NOTZEROERR 16 - -#define FLASH_L1_SR_ERROR_MASK 0x00003F00 -#define FLASH_L1_SR_WRPERR 8 -#define FLASH_L1_SR_PGAERR 9 - -#define FLASH_ACR_OFF ((uint32_t)0x00) -#define FLASH_PECR_OFF ((uint32_t)0x04) -#define FLASH_PDKEYR_OFF ((uint32_t)0x08) -#define FLASH_PEKEYR_OFF ((uint32_t)0x0c) -#define FLASH_PRGKEYR_OFF ((uint32_t)0x10) -#define FLASH_OPTKEYR_OFF ((uint32_t)0x14) -#define FLASH_SR_OFF ((uint32_t)0x18) -#define FLASH_OBR_OFF ((uint32_t)0x1c) -#define FLASH_WRPR_OFF ((uint32_t)0x20) - -// STM32F7 -#define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) -#define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) -#define FLASH_F7_SR (FLASH_F7_REGS_ADDR + 0x0c) -#define FLASH_F7_CR (FLASH_F7_REGS_ADDR + 0x10) -#define FLASH_F7_OPTCR (FLASH_F7_REGS_ADDR + 0x14) -#define FLASH_F7_OPTCR1 (FLASH_F7_REGS_ADDR + 0x18) -#define FLASH_F7_OPTCR_LOCK 0 -#define FLASH_F7_OPTCR_START 1 -#define FLASH_F7_CR_STRT 16 -#define FLASH_F7_CR_LOCK 31 -#define FLASH_F7_CR_SER 1 -#define FLASH_F7_CR_SNB 3 -#define FLASH_F7_CR_SNB_MASK 0xf8 -#define FLASH_F7_SR_BSY 16 -#define FLASH_F7_SR_ERS_ERR 7 /* Erase Sequence Error */ -#define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ -#define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ -#define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ -#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ -#define FLASH_F7_SR_EOP 0 /* End of operation */ -#define FLASH_F7_OPTCR1_BOOT_ADD0 0 -#define FLASH_F7_OPTCR1_BOOT_ADD1 16 - -#define FLASH_F7_SR_ERROR_MASK \ - ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | \ - (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | \ - (1 << FLASH_F7_SR_OP_ERR)) - -// STM32F4 -#define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) -#define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08) -#define FLASH_F4_SR (FLASH_F4_REGS_ADDR + 0x0c) -#define FLASH_F4_CR (FLASH_F4_REGS_ADDR + 0x10) -#define FLASH_F4_OPTCR (FLASH_F4_REGS_ADDR + 0x14) -#define FLASH_F4_OPTCR_LOCK 0 -#define FLASH_F4_OPTCR_START 1 -#define FLASH_F4_CR_STRT 16 -#define FLASH_F4_CR_LOCK 31 -#define FLASH_F4_CR_SER 1 -#define FLASH_F4_CR_SNB 3 -#define FLASH_F4_CR_SNB_MASK 0xf8 -#define FLASH_F4_SR_ERROR_MASK 0x000000F0 -#define FLASH_F4_SR_PGAERR 5 -#define FLASH_F4_SR_WRPERR 4 -#define FLASH_F4_SR_BSY 16 - -// STM32F2 -#define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) -#define FLASH_F2_KEYR (FLASH_F2_REGS_ADDR + 0x04) -#define FLASH_F2_OPT_KEYR (FLASH_F2_REGS_ADDR + 0x08) -#define FLASH_F2_SR (FLASH_F2_REGS_ADDR + 0x0c) -#define FLASH_F2_CR (FLASH_F2_REGS_ADDR + 0x10) -#define FLASH_F2_OPT_CR (FLASH_F2_REGS_ADDR + 0x14) -#define FLASH_F2_OPT_LOCK_BIT (1u << 0) -#define FLASH_F2_CR_STRT 16 -#define FLASH_F2_CR_LOCK 31 - -#define FLASH_F2_CR_SER 1 -#define FLASH_F2_CR_SNB 3 -#define FLASH_F2_CR_SNB_MASK 0x78 -#define FLASH_F2_SR_BSY 16 - -// STM32H7xx -#define FLASH_H7_CR_LOCK 0 -#define FLASH_H7_CR_PG 1 -#define FLASH_H7_CR_SER 2 -#define FLASH_H7_CR_BER 3 -#define FLASH_H7_CR_PSIZE 4 -#define FLASH_H7_CR_START(chipid) (chipid == STM32_CHIPID_H7Ax ? 5 : 7) -#define FLASH_H7_CR_SNB 8 -#define FLASH_H7_CR_SNB_MASK 0x700 - -#define FLASH_H7_SR_QW 2 -#define FLASH_H7_SR_WRPERR 17 -#define FLASH_H7_SR_PGSERR 18 -#define FLASH_H7_SR_STRBERR 19 -#define FLASH_H7_SR_ERROR_MASK \ - ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | \ - (1 << FLASH_H7_SR_WRPERR)) - -#define FLASH_H7_OPTCR_OPTLOCK 0 -#define FLASH_H7_OPTCR_OPTSTART 1 -#define FLASH_H7_OPTCR_MER 4 - -#define FLASH_H7_OPTSR_OPT_BUSY 0 -#define FLASH_H7_OPTSR_OPTCHANGEERR 30 +// == STM32WB == (RM0434) +// WB Flash registers +#define FLASH_WB_REGS_ADDR ((uint32_t)0x58004000) +#define FLASH_WB_ACR (FLASH_WB_REGS_ADDR + 0x00) +#define FLASH_WB_KEYR (FLASH_WB_REGS_ADDR + 0x08) +#define FLASH_WB_OPT_KEYR (FLASH_WB_REGS_ADDR + 0x0c) +#define FLASH_WB_SR (FLASH_WB_REGS_ADDR + 0x10) +#define FLASH_WB_CR (FLASH_WB_REGS_ADDR + 0x14) +#define FLASH_WB_ECCR (FLASH_WB_REGS_ADDR + 0x18) +#define FLASH_WB_OPTR (FLASH_WB_REGS_ADDR + 0x20) +#define FLASH_WB_PCROP1ASR (FLASH_WB_REGS_ADDR + 0x24) +#define FLASH_WB_PCROP1AER (FLASH_WB_REGS_ADDR + 0x28) +#define FLASH_WB_WRP1AR (FLASH_WB_REGS_ADDR + 0x2c) +#define FLASH_WB_WRP1BR (FLASH_WB_REGS_ADDR + 0x30) +#define FLASH_WB_PCROP1BSR (FLASH_WB_REGS_ADDR + 0x34) +#define FLASH_WB_PCROP1BER (FLASH_WB_REGS_ADDR + 0x38) +#define FLASH_WB_IPCCBR (FLASH_WB_REGS_ADDR + 0x3c) +#define FLASH_WB_C2ACR (FLASH_WB_REGS_ADDR + 0x5c) +#define FLASH_WB_C2SR (FLASH_WB_REGS_ADDR + 0x60) +#define FLASH_WB_C2CR (FLASH_WB_REGS_ADDR + 0x64) +#define FLASH_WB_SFR (FLASH_WB_REGS_ADDR + 0x80) +#define FLASH_WB_SRRVR (FLASH_WB_REGS_ADDR + 0x84) -#define FLASH_H7_OPTCCR_CLR_OPTCHANGEERR 30 +// WB Flash control register +#define FLASH_WB_CR_STRT (16) /* Start */ +#define FLASH_WB_CR_OPTSTRT (17) /* Start writing option bytes */ +#define FLASH_WB_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ +#define FLASH_WB_CR_OPTLOCK (30) /* Option Lock */ +#define FLASH_WB_CR_LOCK (31) /* Lock */ -#define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) -#define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) -#define FLASH_H7_KEYR2 (FLASH_H7_REGS_ADDR + 0x104) -#define FLASH_H7_OPT_KEYR (FLASH_H7_REGS_ADDR + 0x08) -#define FLASH_H7_OPT_KEYR2 (FLASH_H7_REGS_ADDR + 0x108) -#define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c) -#define FLASH_H7_CR2 (FLASH_H7_REGS_ADDR + 0x10c) -#define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) -#define FLASH_H7_SR2 (FLASH_H7_REGS_ADDR + 0x110) -#define FLASH_H7_CCR1 (FLASH_H7_REGS_ADDR + 0x14) -#define FLASH_H7_CCR2 (FLASH_H7_REGS_ADDR + 0x114) -#define FLASH_H7_OPTCR (FLASH_H7_REGS_ADDR + 0x18) -#define FLASH_H7_OPTCR2 (FLASH_H7_REGS_ADDR + 0x118) -#define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) -#define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) +// WB Flash status register +#define FLASH_WB_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ +#define FLASH_WB_SR_PROGERR (3) /* Programming alignment error */ +#define FLASH_WB_SR_WRPERR (4) /* Write protection error */ +#define FLASH_WB_SR_PGAERR (5) /* Programming error */ +#define FLASH_WB_SR_BSY (16) /* Busy */ #endif // STM32FLASH_H_ diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index f2d60ce45..8e4b9a716 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -348,7 +348,8 @@ int stlink_reset(stlink_t *sl, enum reset_type type) { if (type == RESET_AUTO) { /* Check if the S_RESET_ST bit is set in DHCSR * This means that a reset has occurred - * DDI0337E, p. 10-4, Debug Halting Control and Status Register */ + * DDI0337E, p. 10-4, Debug Halting Control and Status Register + */ dhcsr = 0; int res = stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index dc33fdfcb..a74d88b16 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -1154,7 +1154,7 @@ int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size // Check if size is aligned with a page, unless we want to completely erase the last page if ((addr + page_size) > (base_addr + size) && !align_size) { ELOG("Invalid size (not aligned with a page). Page size at address %#x is %#lx\n", addr, page_size); - return -1; + return (-1); } if (stlink_erase_flash_page(sl, addr)) { diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index f0ce9be42..231a5d4d6 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -708,9 +708,9 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { } if (sl->chip_id != STM32_CHIPID_H7Ax) { // set parallelism - write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); + write_flash_cr_psiz(sl, 3 /* 64bit */, BANK_1); if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); + write_flash_cr_psiz(sl, 3 /* 64bit */, BANK_2); } } } else { From b1c4de647c9cbea8483e742262a30f1b308e881f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 3 May 2023 14:02:26 +0200 Subject: [PATCH 1373/1435] Naming convention for header includes --- inc/backend.h | 6 +++--- inc/stlink.h | 6 +++--- inc/stm32.h | 6 +++--- inc/stm32flash.h | 6 +++--- inc/version.h.in | 6 +++--- src/st-flash/flash.h | 6 +++--- src/st-util/gdb-remote.h | 6 +++--- src/st-util/gdb-server.h | 6 +++--- src/st-util/semihosting.h | 6 +++--- src/stlink-gui/gui.h | 6 +++--- src/stlink-lib/calculate.h | 6 +++--- src/stlink-lib/chipid.h | 6 +++--- src/stlink-lib/commands.h | 6 +++--- src/stlink-lib/common.h | 6 +++--- src/stlink-lib/common_flash.h | 6 +++--- src/stlink-lib/flash_loader.h | 6 +++--- src/stlink-lib/helper.h | 6 +++--- src/stlink-lib/libusb_settings.h | 6 +++--- src/stlink-lib/logging.h | 6 +++--- src/stlink-lib/map_file.h | 6 +++--- src/stlink-lib/md5.h | 6 +++--- src/stlink-lib/option_bytes.h | 6 +++--- src/stlink-lib/reg.h | 6 +++--- src/stlink-lib/sg.h | 6 +++--- src/stlink-lib/usb.h | 6 +++--- src/win32/getopt/getopt.h | 6 +++--- src/win32/mmap.h | 6 +++--- src/win32/sys_time.h | 6 +++--- src/win32/unistd/unistd.h | 6 +++--- 29 files changed, 87 insertions(+), 87 deletions(-) diff --git a/inc/backend.h b/inc/backend.h index abbf4bbf0..75c569fcf 100644 --- a/inc/backend.h +++ b/inc/backend.h @@ -1,5 +1,5 @@ -#ifndef BACKEND_H_ -#define BACKEND_H_ +#ifndef BACKEND_H +#define BACKEND_H typedef struct _stlink_backend { void (*close) (stlink_t * sl); @@ -34,4 +34,4 @@ int (*trace_read) (stlink_t * sl, uint8_t* buf, size_t size); } stlink_backend_t; -#endif // BACKEND_H_ +#endif // BACKEND_H diff --git a/inc/stlink.h b/inc/stlink.h index 2a192876f..b9379e03d 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -6,8 +6,8 @@ * regardless of how the backend does the work.... */ -#ifndef STLINK_H_ -#define STLINK_H_ +#ifndef STLINK_H +#define STLINK_H #include #include @@ -311,4 +311,4 @@ int stlink_target_connect(stlink_t *sl, enum connect_type connect); } #endif -#endif // STLINK_H_ +#endif // STLINK_H diff --git a/inc/stm32.h b/inc/stm32.h index ab80ff25e..f91269a34 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -4,8 +4,8 @@ * STM32-specific defines & identification parametres */ -#ifndef STM32_H_ -#define STM32_H_ +#ifndef STM32_H +#define STM32_H /* STM32 Cortex-M core ids (CPUTAPID) */ enum stm32_core_id { @@ -217,4 +217,4 @@ enum stm32_chipids { #define STM32L5_PWR_CR1 0x40007000 // RM0438, p. 93,324 #define STM32L5_PWR_CR1_VOS 9 -#endif // STM32_H_ +#endif // STM32_H diff --git a/inc/stm32flash.h b/inc/stm32flash.h index 12d2f5a7b..5cb0ee1df 100644 --- a/inc/stm32flash.h +++ b/inc/stm32flash.h @@ -1,5 +1,5 @@ -#ifndef STM32FLASH_H_ -#define STM32FLASH_H_ +#ifndef STM32FLASH_H +#define STM32FLASH_H /* STM32Fx FPEC flash controller interface, PM0063 manual */ // STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev.2, Aug 2012) @@ -408,4 +408,4 @@ #define FLASH_WB_SR_PGAERR (5) /* Programming error */ #define FLASH_WB_SR_BSY (16) /* Busy */ -#endif // STM32FLASH_H_ +#endif // STM32FLASH_H diff --git a/inc/version.h.in b/inc/version.h.in index b5ccd6e31..39020c0ba 100644 --- a/inc/version.h.in +++ b/inc/version.h.in @@ -1,9 +1,9 @@ -#ifndef VERSION_H_ -#define VERSION_H_ +#ifndef VERSION_H +#define VERSION_H #define STLINK_VERSION "@PROJECT_VERSION@" #define STLINK_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ #define STLINK_VERSION_MINOR @PROJECT_VERSION_MINOR@ #define STLINK_VERSION_PATCH @PROJECT_VERSION_PATCH@ -#endif // VERSION_H_ +#endif // VERSION_H diff --git a/src/st-flash/flash.h b/src/st-flash/flash.h index aab57878f..4aa6033f8 100644 --- a/src/st-flash/flash.h +++ b/src/st-flash/flash.h @@ -1,5 +1,5 @@ -#ifndef FLASH_H_ -#define FLASH_H_ +#ifndef FLASH_H +#define FLASH_H #include @@ -33,4 +33,4 @@ struct flash_opts { int flash_get_opts(struct flash_opts* o, int ac, char** av); -#endif // FLASH_H_ +#endif // FLASH_H diff --git a/src/st-util/gdb-remote.h b/src/st-util/gdb-remote.h index bcf1dbd01..03d6aea10 100644 --- a/src/st-util/gdb-remote.h +++ b/src/st-util/gdb-remote.h @@ -1,8 +1,8 @@ -#ifndef GDB_REMOTE_H_ -#define GDB_REMOTE_H_ +#ifndef GDB_REMOTE_H +#define GDB_REMOTE_H int gdb_send_packet(int fd, char* data); int gdb_recv_packet(int fd, char** buffer); int gdb_check_for_interrupt(int fd); -#endif // GDB_REMOTE_H_ +#endif // GDB_REMOTE_H diff --git a/src/st-util/gdb-server.h b/src/st-util/gdb-server.h index 3fbb16dad..03c37e416 100644 --- a/src/st-util/gdb-server.h +++ b/src/st-util/gdb-server.h @@ -1,5 +1,5 @@ -#ifndef GDB_SERVER_H_ -#define GDB_SERVER_H_ +#ifndef GDB_SERVER_H +#define GDB_SERVER_H #define STRINGIFY_inner(name) #name #define STRINGIFY(name) STRINGIFY_inner(name) @@ -8,4 +8,4 @@ #define DEBUG_LOGGING_LEVEL 100 #define DEFAULT_GDB_LISTEN_PORT 4242 -#endif // GDB_SERVER_H_ +#endif // GDB_SERVER_H diff --git a/src/st-util/semihosting.h b/src/st-util/semihosting.h index 2e34b4307..e7ddfcd97 100644 --- a/src/st-util/semihosting.h +++ b/src/st-util/semihosting.h @@ -1,5 +1,5 @@ -#ifndef SEMIHOSTING_H_ -#define SEMIHOSTING_H_ +#ifndef SEMIHOSTING_H +#define SEMIHOSTING_H #include @@ -31,4 +31,4 @@ int do_semihosting(stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret); -#endif // SEMIHOSTING_H_ +#endif // SEMIHOSTING_H diff --git a/src/stlink-gui/gui.h b/src/stlink-gui/gui.h index f29ee5031..08519ea56 100644 --- a/src/stlink-gui/gui.h +++ b/src/stlink-gui/gui.h @@ -1,5 +1,5 @@ -#ifndef GUI_H_ -#define GUI_H_ +#ifndef GUI_H +#define GUI_H #include @@ -89,4 +89,4 @@ struct _STlinkGUIClass { GType stlink_gui_get_type(void); int export_to_file(const char*filename, const struct mem_t flash_mem); -#endif // GUI_H_ +#endif // GUI_H diff --git a/src/stlink-lib/calculate.h b/src/stlink-lib/calculate.h index beb064297..64dfb51b2 100644 --- a/src/stlink-lib/calculate.h +++ b/src/stlink-lib/calculate.h @@ -4,12 +4,12 @@ * Calculation of sector numbers and pages */ -#ifndef CALCULATE_H_ -#define CALCULATE_H_ +#ifndef CALCULATE_H +#define CALCULATE_H uint32_t calculate_F4_sectornum(uint32_t); uint32_t calculate_F7_sectornum(uint32_t); uint32_t calculate_H7_sectornum(stlink_t *, uint32_t, unsigned); uint32_t calculate_L4_page(stlink_t *, uint32_t); -#endif // CALCULATE_H_ +#endif // CALCULATE_H diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index b93a3f2d6..d6afc4525 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -1,5 +1,5 @@ -#ifndef CHIPID_H_ -#define CHIPID_H_ +#ifndef CHIPID_H +#define CHIPID_H #include #include @@ -24,4 +24,4 @@ struct stlink_chipid_params { struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); void init_chipids(char *dir_to_scan); -#endif // CHIPID_H_ +#endif // CHIPID_H diff --git a/src/stlink-lib/commands.h b/src/stlink-lib/commands.h index 4fa919858..5f0904971 100644 --- a/src/stlink-lib/commands.h +++ b/src/stlink-lib/commands.h @@ -1,5 +1,5 @@ -#ifndef COMMANDS_H_ -#define COMMANDS_H_ +#ifndef COMMANDS_H +#define COMMANDS_H enum stlink_commands { STLINK_GET_VERSION = 0xF1, @@ -54,4 +54,4 @@ enum stlink_dfu_commands { STLINK_DFU_EXIT = 0x07 }; -#endif // COMMANDS_H_ +#endif // COMMANDS_H diff --git a/src/stlink-lib/common.h b/src/stlink-lib/common.h index 902493610..dd6cf95b2 100644 --- a/src/stlink-lib/common.h +++ b/src/stlink-lib/common.h @@ -4,12 +4,12 @@ * General helper functions */ -#ifndef COMMON_H_ -#define COMMON_H_ +#ifndef COMMON_H +#define COMMON_H int check_file(stlink_t *, mapped_file_t *, stm32_addr_t); void md5_calculate(mapped_file_t *); void stlink_checksum(mapped_file_t *); void stlink_fwrite_finalize(stlink_t *, stm32_addr_t); -#endif // COMMON_H_ +#endif // COMMON_H diff --git a/src/stlink-lib/common_flash.h b/src/stlink-lib/common_flash.h index 269f8196e..aa92b2143 100644 --- a/src/stlink-lib/common_flash.h +++ b/src/stlink-lib/common_flash.h @@ -4,8 +4,8 @@ * Flash operations */ -#ifndef COMMON_FLASH_H_ -#define COMMON_FLASH_H_ +#ifndef COMMON_FLASH_H +#define COMMON_FLASH_H void lock_flash(stlink_t *); void clear_flash_error(stlink_t *); @@ -25,4 +25,4 @@ void clear_flash_cr_pg(stlink_t *, unsigned); uint32_t read_flash_cr(stlink_t *, unsigned); uint32_t get_stm32l0_flash_base(stlink_t *); -#endif // COMMON_FLASH_H_ +#endif // COMMON_FLASH_H diff --git a/src/stlink-lib/flash_loader.h b/src/stlink-lib/flash_loader.h index 781fab74a..51448395f 100644 --- a/src/stlink-lib/flash_loader.h +++ b/src/stlink-lib/flash_loader.h @@ -4,8 +4,8 @@ * Flash loader */ -#ifndef FLASH_LOADER_H_ -#define FLASH_LOADER_H_ +#ifndef FLASH_LOADER_H +#define FLASH_LOADER_H #include #include @@ -21,4 +21,4 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len); int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl); -#endif // FLASH_LOADER_H_ +#endif // FLASH_LOADER_H diff --git a/src/stlink-lib/helper.h b/src/stlink-lib/helper.h index 58023aff2..cf45bbf43 100644 --- a/src/stlink-lib/helper.h +++ b/src/stlink-lib/helper.h @@ -1,8 +1,8 @@ -#ifndef HELPER_H_ -#define HELPER_H_ +#ifndef HELPER_H +#define HELPER_H unsigned time_ms(); int arg_parse_freq(const char *str); -#endif // HELPER_H_ +#endif // HELPER_H diff --git a/src/stlink-lib/libusb_settings.h b/src/stlink-lib/libusb_settings.h index 639f9e4a4..3777f720b 100644 --- a/src/stlink-lib/libusb_settings.h +++ b/src/stlink-lib/libusb_settings.h @@ -1,5 +1,5 @@ -#ifndef LIBUSB_SETTINGS_H_ -#define LIBUSB_SETTINGS_H_ +#ifndef LIBUSB_SETTINGS_H +#define LIBUSB_SETTINGS_H #include @@ -44,4 +44,4 @@ #error unsupported libusb version #endif -#endif // LIBUSB_SETTINGS_H_ +#endif // LIBUSB_SETTINGS_H diff --git a/src/stlink-lib/logging.h b/src/stlink-lib/logging.h index 7510d573e..893a02c24 100644 --- a/src/stlink-lib/logging.h +++ b/src/stlink-lib/logging.h @@ -2,8 +2,8 @@ * Ugly, low performance, configurable level, logging "framework" */ -#ifndef LOGGING_H_ -#define LOGGING_H_ +#ifndef LOGGING_H +#define LOGGING_H #ifdef __cplusplus extern "C" { @@ -45,4 +45,4 @@ int ugly_libusb_log_level(enum ugly_loglevel v); } #endif -#endif // LOGGING_H_ +#endif // LOGGING_H diff --git a/src/stlink-lib/map_file.h b/src/stlink-lib/map_file.h index d69f6c3b5..f50a201f0 100644 --- a/src/stlink-lib/map_file.h +++ b/src/stlink-lib/map_file.h @@ -4,8 +4,8 @@ * File mapping */ -#ifndef MAP_FILE_H_ -#define MAP_FILE_H_ +#ifndef MAP_FILE_H +#define MAP_FILE_H #ifndef O_BINARY #define O_BINARY 0 @@ -29,4 +29,4 @@ typedef struct mapped_file { int map_file(mapped_file_t *, const char *); void unmap_file(mapped_file_t *); -#endif // MAP_FILE_H_ +#endif // MAP_FILE_H diff --git a/src/stlink-lib/md5.h b/src/stlink-lib/md5.h index 7b853a4f6..23c5d971b 100644 --- a/src/stlink-lib/md5.h +++ b/src/stlink-lib/md5.h @@ -11,8 +11,8 @@ * MD5 hash function */ -#ifndef MD5_H_ -#define MD5_H_ +#ifndef MD5_H +#define MD5_H #pragma once @@ -71,4 +71,4 @@ void Md5Finalise(Md5Context* Context /* [in out] */, MD5_HASH* Digest /* [in] */ */ void Md5Calculate(void const* Buffer /* [in] */, uint32_t BufferSize /* [in] */, MD5_HASH* Digest /* [in] */); -#endif // MD5_H_ \ No newline at end of file +#endif // MD5_H \ No newline at end of file diff --git a/src/stlink-lib/option_bytes.h b/src/stlink-lib/option_bytes.h index 481a69f0a..9c81fba8a 100644 --- a/src/stlink-lib/option_bytes.h +++ b/src/stlink-lib/option_bytes.h @@ -4,8 +4,8 @@ * Read and write option bytes and option control registers */ -#ifndef OPTION_BYTES_H_ -#define OPTION_BYTES_H_ +#ifndef OPTION_BYTES_H +#define OPTION_BYTES_H #include #include @@ -23,4 +23,4 @@ int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_cr1); int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); -#endif // OPTION_BYTES_H_ \ No newline at end of file +#endif // OPTION_BYTES_H \ No newline at end of file diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 2046f8a6a..c2976d050 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -1,5 +1,5 @@ -#ifndef REG_H_ -#define REG_H_ +#ifndef REG_H +#define REG_H #define STLINK_REG_CM3_CPUID 0xE000ED00 @@ -123,4 +123,4 @@ #define STLINK_REG_CM7_ICIALLU 0xE000EF50 #define STLINK_REG_CM7_CCSIDR 0xE000ED80 -#endif // REG_H_ +#endif // REG_H diff --git a/src/stlink-lib/sg.h b/src/stlink-lib/sg.h index e30043fcc..5ba809f59 100644 --- a/src/stlink-lib/sg.h +++ b/src/stlink-lib/sg.h @@ -3,8 +3,8 @@ * Author: karl */ -#ifndef SG_H_ -#define SG_H_ +#ifndef SG_H +#define SG_H #include #include @@ -56,4 +56,4 @@ struct stlink_libsg { stlink_t* stlink_v1_open(const int verbose, int reset); -#endif // SG_H_ +#endif // SG_H diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index ff6f9088e..8c98bcaf4 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -3,8 +3,8 @@ * Author: karl */ -#ifndef USB_H_ -#define USB_H_ +#ifndef USB_H +#define USB_H #include @@ -70,4 +70,4 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int freq); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); -#endif // USB_H_ +#endif // USB_H diff --git a/src/win32/getopt/getopt.h b/src/win32/getopt/getopt.h index 2a1bd735b..b1dd35ef1 100644 --- a/src/win32/getopt/getopt.h +++ b/src/win32/getopt/getopt.h @@ -1,5 +1,5 @@ -#ifndef GETOPT_H_ -#define GETOPT_H_ +#ifndef GETOPT_H +#define GETOPT_H #if defined(__cplusplus) extern "C" { @@ -38,4 +38,4 @@ int getopt_long(int argc, } #endif -#endif // GETOPT_H_ +#endif // GETOPT_H diff --git a/src/win32/mmap.h b/src/win32/mmap.h index ff01f4286..c6390aede 100644 --- a/src/win32/mmap.h +++ b/src/win32/mmap.h @@ -1,5 +1,5 @@ -#ifndef MMAP_H_ -#define MMAP_H_ +#ifndef MMAP_H +#define MMAP_H #ifdef STLINK_HAVE_SYS_MMAN_H #include @@ -18,4 +18,4 @@ int munmap(void *addr, size_t len); #endif // STLINK_HAVE_SYS_MMAN_H -#endif // MMAP_H_ +#endif // MMAP_H diff --git a/src/win32/sys_time.h b/src/win32/sys_time.h index cb767fc31..98ecaddfc 100644 --- a/src/win32/sys_time.h +++ b/src/win32/sys_time.h @@ -1,5 +1,5 @@ -#ifndef SYS_TIME_H_ -#define SYS_TIME_H_ +#ifndef SYS_TIME_H +#define SYS_TIME_H #ifdef STLINK_HAVE_SYS_TIME_H @@ -18,4 +18,4 @@ int gettimeofday(struct timeval *tv, struct timezone *tz); #endif // STLINK_HAVE_SYS_TIME_H -#endif // SYS_TIME_H_ +#endif // SYS_TIME_H diff --git a/src/win32/unistd/unistd.h b/src/win32/unistd/unistd.h index b8a3db746..5f2b5433b 100644 --- a/src/win32/unistd/unistd.h +++ b/src/win32/unistd/unistd.h @@ -1,5 +1,5 @@ -#ifndef UNISTD_H_ -#define UNISTD_H_ +#ifndef UNISTD_H +#define UNISTD_H /* * This file intended to serve as a drop-in replacement for unistd.h on Windows @@ -72,4 +72,4 @@ typedef unsigned __int64 uint64_t; int usleep(unsigned int waitTime); #endif -#endif // UNISTD_H_ +#endif // UNISTD_H From e4b2594b5a0700a43c68fcbe2aa0c91b5a62cec3 Mon Sep 17 00:00:00 2001 From: Andras Gemes Date: Fri, 5 May 2023 15:39:04 +0200 Subject: [PATCH 1374/1435] Fixed broken links --- README.md | 2 +- doc/tutorial.md | 2 +- doc/version_support.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0e846b336..b6fca5fe2 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ The STlink toolset includes: ## Supported operating systems and hardware combinations -Currently known working MCU targets are listed in [devices_boards.md](doc/devices_boards.md). +Currently known working MCU targets are listed in [supported devices.md](). A list of supported operating can be found in [version_support.md](doc/version_support.md). diff --git a/doc/tutorial.md b/doc/tutorial.md index 7e87a7bd9..53ecabe7d 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -104,7 +104,7 @@ In this known example one finds the counterfeited "STM32F103C8T6" MCUs to identi In the following you find some hints on how to identify your chip and track down fraud: - [How to Detect STM32 Fakes](https://www.cnx-software.com/2020/03/22/how-to-detect-stm32-fakes/) -- [Confirmation by STMicroelectronics](https://www.mikrocontroller.net/attachment/442839/couterfeit_STM.png) (Marking: 991KA 93 MYS 807) +- [Confirmation by STMicroelectronics](https://www.mikrocontroller.net/attachment/442839/couterfeit_STM.PNG) (Marking: 991KA 93 MYS 807) - [STM32 Clones: The Good, The Bad And The Ugly](https://hackaday.com/2020/10/22/stm32-clones-the-good-the-bad-and-the-ugly/) However it appears that not all counterfeited parts cause problems during operation, but some are known to not even being able to execute a basic "blinky" example binary. Further there can be problems that may not even show up or affect you directly, but somewhen later in time (or maybe never). diff --git a/doc/version_support.md b/doc/version_support.md index 358e65fb9..022fb5e4d 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -1,4 +1,4 @@ -_Source:_ [pkgs.org](https://pkgs.org/search) - libusb, cmake, gtk, libgtk (as of Apr 2023) +_Source:_ [pkgs.org](https://pkgs.org) - libusb, cmake, gtk, libgtk (as of Apr 2023) ## Supported Operating Systems From 623570e3cc6e8b577c25dd8c23840ad688358f9c Mon Sep 17 00:00:00 2001 From: Andras Gemes Date: Sun, 7 May 2023 12:39:03 +0200 Subject: [PATCH 1375/1435] Renamed 'supported devices.md' to 'supported_devices.md' --- README.md | 2 +- doc/{supported devices.md => supported_devices.md} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename doc/{supported devices.md => supported_devices.md} (100%) diff --git a/README.md b/README.md index b6fca5fe2..e103ac301 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ The STlink toolset includes: ## Supported operating systems and hardware combinations -Currently known working MCU targets are listed in [supported devices.md](). +Currently known working MCU targets are listed in [supported_devices.md](doc/supported_devices.md). A list of supported operating can be found in [version_support.md](doc/version_support.md). diff --git a/doc/supported devices.md b/doc/supported_devices.md similarity index 100% rename from doc/supported devices.md rename to doc/supported_devices.md From 5e85fd063908f89499180c28fe5e9ba74868b272 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 8 May 2023 02:05:55 +0200 Subject: [PATCH 1376/1435] Replace data types with fixed width typedefs (C99) - Unified variable types (Closes #909) short --> int16_t unsigned short --> uint16_t int --> int32_t unsigned int --> uint32_t long --> int32_t unsigned long --> uint32_t long long --> int64_t unsigned long long --> uint64_t - Added missing header includes --- inc/backend.h | 58 ++++---- inc/stlink.h | 108 +++++++-------- inc/stm32.h | 2 + inc/stm32flash.h | 2 + src/st-flash/flash.c | 15 +- src/st-flash/flash.h | 10 +- src/st-flash/flash_opts.c | 15 +- src/st-info/info.c | 17 +-- src/st-trace/trace.c | 15 +- src/st-util/gdb-remote.c | 18 +-- src/st-util/gdb-remote.h | 8 +- src/st-util/gdb-server.c | 251 +++++++++++++++++----------------- src/st-util/semihosting.c | 57 ++++---- src/st-util/semihosting.h | 4 +- src/stlink-gui/gui.c | 8 +- src/stlink-gui/gui.h | 3 +- src/stlink-lib/calculate.c | 4 +- src/stlink-lib/calculate.h | 2 + src/stlink-lib/chipid.c | 11 +- src/stlink-lib/chipid.h | 2 + src/stlink-lib/common.c | 133 +++++++++--------- src/stlink-lib/common.h | 7 +- src/stlink-lib/common_flash.c | 108 ++++++++------- src/stlink-lib/common_flash.h | 10 +- src/stlink-lib/flash_loader.c | 67 ++++----- src/stlink-lib/flash_loader.h | 14 +- src/stlink-lib/helper.c | 13 +- src/stlink-lib/helper.h | 6 +- src/stlink-lib/logging.c | 9 +- src/stlink-lib/logging.h | 8 +- src/stlink-lib/map_file.c | 15 +- src/stlink-lib/map_file.h | 4 +- src/stlink-lib/md5.c | 3 +- src/stlink-lib/option_bytes.c | 116 ++++++++-------- src/stlink-lib/option_bytes.h | 22 +-- src/stlink-lib/read_write.c | 34 ++--- src/stlink-lib/sg.c | 126 ++++++++--------- src/stlink-lib/sg.h | 16 ++- src/stlink-lib/usb.c | 238 ++++++++++++++++---------------- src/stlink-lib/usb.h | 19 +-- src/win32/getopt/getopt.c | 23 ++-- src/win32/getopt/getopt.h | 18 +-- src/win32/mmap.c | 9 +- src/win32/mmap.h | 6 +- src/win32/sys_time.c | 10 +- src/win32/sys_time.h | 8 +- src/win32/unistd/unistd.h | 5 +- src/win32/win32_socket.c | 40 +++--- src/win32/win32_socket.h | 24 ++-- tests/flash.c | 9 +- tests/sg.c | 7 +- tests/usb.c | 7 +- 52 files changed, 908 insertions(+), 836 deletions(-) diff --git a/inc/backend.h b/inc/backend.h index 75c569fcf..a9a7d6e03 100644 --- a/inc/backend.h +++ b/inc/backend.h @@ -1,37 +1,39 @@ #ifndef BACKEND_H #define BACKEND_H +#include + typedef struct _stlink_backend { void (*close) (stlink_t * sl); - int (*exit_debug_mode) (stlink_t * sl); - int (*enter_swd_mode) (stlink_t * sl); - int (*enter_jtag_mode) (stlink_t * stl); - int (*exit_dfu_mode) (stlink_t * stl); - int (*core_id) (stlink_t * stl); - int (*reset) (stlink_t * stl); - int (*jtag_reset) (stlink_t * stl, int value); - int (*run) (stlink_t * stl, enum run_type type); - int (*status) (stlink_t * stl); - int (*version) (stlink_t *sl); - int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); - int (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); - int (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); - int (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); - int (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); - int (*read_all_regs) (stlink_t *sl, struct stlink_reg * regp); - int (*read_reg) (stlink_t *sl, int r_idx, struct stlink_reg * regp); - int (*read_all_unsupported_regs) (stlink_t *sl, struct stlink_reg *regp); - int (*read_unsupported_reg) (stlink_t *sl, int r_idx, struct stlink_reg *regp); - int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, struct stlink_reg *regp); - int (*write_reg) (stlink_t *sl, uint32_t reg, int idx); - int (*step) (stlink_t * stl); - int (*current_mode) (stlink_t * stl); - int (*force_debug) (stlink_t *sl); + int32_t (*exit_debug_mode) (stlink_t * sl); + int32_t (*enter_swd_mode) (stlink_t * sl); + int32_t (*enter_jtag_mode) (stlink_t * stl); + int32_t (*exit_dfu_mode) (stlink_t * stl); + int32_t (*core_id) (stlink_t * stl); + int32_t (*reset) (stlink_t * stl); + int32_t (*jtag_reset) (stlink_t * stl, int32_t value); + int32_t (*run) (stlink_t * stl, enum run_type type); + int32_t (*status) (stlink_t * stl); + int32_t (*version) (stlink_t *sl); + int32_t (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); + int32_t (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); + int32_t (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); + int32_t (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); + int32_t (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); + int32_t (*read_all_regs) (stlink_t *sl, struct stlink_reg * regp); + int32_t (*read_reg) (stlink_t *sl, int32_t r_idx, struct stlink_reg * regp); + int32_t (*read_all_unsupported_regs) (stlink_t *sl, struct stlink_reg *regp); + int32_t (*read_unsupported_reg) (stlink_t *sl, int32_t r_idx, struct stlink_reg *regp); + int32_t (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int32_t idx, struct stlink_reg *regp); + int32_t (*write_reg) (stlink_t *sl, uint32_t reg, int32_t idx); + int32_t (*step) (stlink_t * stl); + int32_t (*current_mode) (stlink_t * stl); + int32_t (*force_debug) (stlink_t *sl); int32_t (*target_voltage) (stlink_t *sl); - int (*set_swdclk) (stlink_t * stl, int freq_khz); - int (*trace_enable) (stlink_t * sl, uint32_t frequency); - int (*trace_disable) (stlink_t * sl); - int (*trace_read) (stlink_t * sl, uint8_t* buf, size_t size); + int32_t (*set_swdclk) (stlink_t * stl, int32_t freq_khz); + int32_t (*trace_enable) (stlink_t * sl, uint32_t frequency); + int32_t (*trace_disable) (stlink_t * sl); + int32_t (*trace_read) (stlink_t * sl, uint8_t* buf, size_t size); } stlink_backend_t; #endif // BACKEND_H diff --git a/inc/stlink.h b/inc/stlink.h index b9379e03d..ca07a6a89 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -196,17 +196,17 @@ struct _stlink { unsigned char c_buf[C_BUF_LEN]; // data transferred from or to device unsigned char q_buf[Q_BUF_LEN]; - int q_len; + int32_t q_len; // transport layer verboseness: 0 for no debug info, 10 for lots - int verbose; - int opt; + int32_t verbose; + int32_t opt; uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram enum target_state core_stat; // set by stlink_status() char serial[STLINK_SERIAL_BUFFER_SIZE]; - int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR + int32_t freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR enum stm32_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STM32_FLASH_TYPE_xx @@ -236,67 +236,67 @@ struct _stlink { uint32_t max_trace_freq; // set by stlink_open_usb() }; -int stlink_enter_swd_mode(stlink_t *sl); -int stlink_enter_jtag_mode(stlink_t *sl); -int stlink_exit_debug_mode(stlink_t *sl); -int stlink_exit_dfu_mode(stlink_t *sl); +int32_t stlink_enter_swd_mode(stlink_t *sl); +int32_t stlink_enter_jtag_mode(stlink_t *sl); +int32_t stlink_exit_debug_mode(stlink_t *sl); +int32_t stlink_exit_dfu_mode(stlink_t *sl); void stlink_close(stlink_t *sl); -int stlink_core_id(stlink_t *sl); -int stlink_reset(stlink_t *sl, enum reset_type type); -int stlink_run(stlink_t *sl, enum run_type type); -int stlink_status(stlink_t *sl); -int stlink_version(stlink_t *sl); -int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); -int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); -int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); -int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); -int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); -int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp); -int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); -int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); -int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); -int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, struct stlink_reg *regp); -int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); -int stlink_step(stlink_t *sl); -int stlink_current_mode(stlink_t *sl); -int stlink_force_debug(stlink_t *sl); -int stlink_target_voltage(stlink_t *sl); -int stlink_set_swdclk(stlink_t *sl, int freq_khz); -int stlink_trace_enable(stlink_t* sl, uint32_t frequency); -int stlink_trace_disable(stlink_t* sl); -int stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size); -int stlink_erase_flash_mass(stlink_t* sl); -int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size); -int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); -int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); +int32_t stlink_core_id(stlink_t *sl); +int32_t stlink_reset(stlink_t *sl, enum reset_type type); +int32_t stlink_run(stlink_t *sl, enum run_type type); +int32_t stlink_status(stlink_t *sl); +int32_t stlink_version(stlink_t *sl); +int32_t stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); +int32_t stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int32_t stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); +int32_t stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int32_t stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); +int32_t stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp); +int32_t stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); +int32_t stlink_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp); +int32_t stlink_read_unsupported_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp); +int32_t stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int32_t r_idx, struct stlink_reg *regp); +int32_t stlink_write_reg(stlink_t *sl, uint32_t reg, int32_t idx); +int32_t stlink_step(stlink_t *sl); +int32_t stlink_current_mode(stlink_t *sl); +int32_t stlink_force_debug(stlink_t *sl); +int32_t stlink_target_voltage(stlink_t *sl); +int32_t stlink_set_swdclk(stlink_t *sl, int32_t freq_khz); +int32_t stlink_trace_enable(stlink_t* sl, uint32_t frequency); +int32_t stlink_trace_disable(stlink_t* sl); +int32_t stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size); +int32_t stlink_erase_flash_mass(stlink_t* sl); +int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size); +int32_t stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); +int32_t stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); uint8_t stlink_get_erased_pattern(stlink_t *sl); -int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); -int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); -int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, 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); +int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); +int32_t stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); +int32_t stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); +int32_t stlink_fwrite_sram(stlink_t *sl, const char* path, stm32_addr_t addr); +int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length); -//int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); -int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); +//int32_t stlink_chip_id(stlink_t *sl, uint32_t *chip_id); +int32_t stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); -int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); +int32_t stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); -int stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size); -int stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr); -uint16_t read_uint16(const unsigned char *c, const int pt); +int32_t stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size); +int32_t stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr); +uint16_t read_uint16(const unsigned char *c, const int32_t pt); //void stlink_core_stat(stlink_t *sl); void stlink_print_data(stlink_t *sl); -unsigned int is_bigendian(void); -uint32_t read_uint32(const unsigned char *c, const int pt); +uint32_t is_bigendian(void); +uint32_t read_uint32(const unsigned char *c, const int32_t pt); void write_uint32(unsigned char* buf, uint32_t ui); void write_uint16(unsigned char* buf, uint16_t ui); bool stlink_is_core_halted(stlink_t *sl); -int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); -int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); -int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); -int stlink_load_device_params(stlink_t *sl); +int32_t write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); +int32_t write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); +int32_t stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); +int32_t stlink_load_device_params(stlink_t *sl); -int stlink_target_connect(stlink_t *sl, enum connect_type connect); +int32_t stlink_target_connect(stlink_t *sl, enum connect_type connect); #include #include diff --git a/inc/stm32.h b/inc/stm32.h index f91269a34..eee1b0433 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -7,6 +7,8 @@ #ifndef STM32_H #define STM32_H +#include + /* STM32 Cortex-M core ids (CPUTAPID) */ enum stm32_core_id { STM32_CORE_ID_M0_SWD = 0x0bb11477, // (RM0091 Section 32.5.3) F0 SW-DP diff --git a/inc/stm32flash.h b/inc/stm32flash.h index 5cb0ee1df..69c6206ee 100644 --- a/inc/stm32flash.h +++ b/inc/stm32flash.h @@ -1,6 +1,8 @@ #ifndef STM32FLASH_H #define STM32FLASH_H +#include + /* STM32Fx FPEC flash controller interface, PM0063 manual */ // STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev.2, Aug 2012) #define FLASH_REGS_ADDR 0x40022000 diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index bbb52d80c..6b4a10cfc 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -1,6 +1,7 @@ /* Simple wrapper around the stlink_flash_write function */ #include +#include #include #include @@ -20,7 +21,7 @@ static stlink_t *connected_stlink = NULL; -static void cleanup(int signum) { +static void cleanup(int32_t signum) { (void)signum; if (connected_stlink) { // switch back to mass storage mode before closing @@ -52,10 +53,10 @@ static void usage(void) { puts("example write option control register1 byte: ./st-flash --area=optcr1 write 0xXXXXXXXX"); } -int main(int ac, char** av) { +int32_t main(int32_t ac, char** av) { stlink_t* sl = NULL; struct flash_opts o; - int err = -1; + int32_t err = -1; uint8_t * mem = NULL; o.size = 0; @@ -82,7 +83,7 @@ int main(int ac, char** av) { if ( o.flash_size != 0u && o.flash_size != sl->flash_size ) { sl->flash_size = o.flash_size; - printf("Forcing flash size: --flash=0x%08X\n", (unsigned int)sl->flash_size); + printf("Forcing flash size: --flash=0x%08X\n", (uint32_t)sl->flash_size); } sl->verbose = o.log_level; @@ -222,8 +223,8 @@ int main(int ac, char** av) { } else if (o.area == FLASH_OPTION_BYTES) { size_t remaining_option_length = sl->option_size / 4; DLOG("@@@@ Read %u (%#x) option bytes from %#10x\n", - (unsigned)remaining_option_length, - (unsigned)remaining_option_length, + (uint32_t)remaining_option_length, + (uint32_t)remaining_option_length, sl->option_base); uint32_t option_byte = 0; @@ -232,7 +233,7 @@ int main(int ac, char** av) { printf("could not read option bytes (%d)\n", err); goto on_error; } else if (NULL != o.filename) { - int fd = open(o.filename, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); + int32_t fd = open(o.filename, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); if (fd == -1) { fprintf(stderr, "open(%s) == -1\n", o.filename); goto on_error; diff --git a/src/st-flash/flash.h b/src/st-flash/flash.h index 4aa6033f8..1a509a660 100644 --- a/src/st-flash/flash.h +++ b/src/st-flash/flash.h @@ -18,19 +18,19 @@ struct flash_opts { const char* filename; stm32_addr_t addr; size_t size; - int reset; - int log_level; + int32_t reset; + int32_t log_level; enum flash_format format; enum flash_area area; uint32_t val; size_t flash_size; // --flash=n[k, M] - int opt; // enable empty tail data drop optimization - int freq; // --freq=n[k, M] frequency of JTAG/SWD + int32_t opt; // enable empty tail data drop optimization + int32_t freq; // --freq=n[k, M] frequency of JTAG/SWD enum connect_type connect; }; #define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -int flash_get_opts(struct flash_opts* o, int ac, char** av); +int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av); #endif // FLASH_H diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 984156aa3..e133d52c7 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -18,7 +19,7 @@ static bool starts_with(const char * str, const char * prefix) { // support decimal, hexadecimal, octal, binary format like 0xff 12 1k 1M, 0b1001 // negative numbers are not supported // return 0 if success else return -1 -static int get_long_integer_from_char_array (const char *const str, uint64_t *read_value) { +static int32_t get_long_integer_from_char_array (const char *const str, uint64_t *read_value) { uint64_t value; char *tail; @@ -50,9 +51,9 @@ static int get_long_integer_from_char_array (const char *const str, uint64_t *re // support decimal, hexadecimal, octal, binary format like 0xff 12 1k 1M, 0b1001 // negative numbers are not supported // return 0 if success else return -1 -static int get_integer_from_char_array (const char *const str, uint32_t *read_value) { +static int32_t get_integer_from_char_array (const char *const str, uint32_t *read_value) { uint64_t value; - int result = get_long_integer_from_char_array (str, &value); + int32_t result = get_long_integer_from_char_array (str, &value); if (result != 0) { return(result); @@ -65,24 +66,24 @@ static int get_integer_from_char_array (const char *const str, uint32_t *read_va } } -static int invalid_args(const char *expected) { +static int32_t invalid_args(const char *expected) { fprintf(stderr, "*** Error: Expected args for this command: %s\n", expected); return(-1); } -static int bad_arg(const char *arg) { +static int32_t bad_arg(const char *arg) { fprintf(stderr, "*** Error: Invalid value for %s\n", arg); return(-1); } -int flash_get_opts(struct flash_opts* o, int ac, char** av) { +int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { // defaults memset(o, 0, sizeof(*o)); o->log_level = STND_LOG_LEVEL; // options - int result; + int32_t result; while (ac >= 1) { if (strcmp(av[0], "--version") == 0) { diff --git a/src/st-info/info.c b/src/st-info/info.c index 9963606e3..86a1c2d8f 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -42,26 +43,26 @@ static void stlink_print_info(stlink_t *sl) { if (params) { printf(" dev-type: %s\n", params->dev_type); } } -static void stlink_probe(enum connect_type connect, int freq) { +static void stlink_probe(enum connect_type connect, int32_t freq) { stlink_t **stdevs; size_t size; size = stlink_probe_usb(&stdevs, connect, freq); - printf("Found %u stlink programmers\n", (unsigned int)size); + printf("Found %u stlink programmers\n", (uint32_t)size); for (size_t n = 0; n < size; n++) { - if (size > 1) printf("%u.\n", (unsigned int)n+1); + if (size > 1) printf("%u.\n", (uint32_t)n+1); stlink_print_info(stdevs[n]); } stlink_probe_usb_free(&stdevs, size); } -static int print_data(int ac, char **av) { +static int32_t print_data(int32_t ac, char **av) { stlink_t* sl = NULL; enum connect_type connect = CONNECT_NORMAL; - int freq = 0; + int32_t freq = 0; if (strcmp(av[1], "--version") == 0) { printf("v%s\n", STLINK_VERSION); @@ -70,7 +71,7 @@ static int print_data(int ac, char **av) { init_chipids(STLINK_CHIPS_DIR); - for (int i=2; i #include #include +#include #include #include #include @@ -41,7 +42,7 @@ typedef struct { bool show_help; bool show_version; - int logging_level; + int32_t logging_level; uint32_t core_frequency; uint32_t trace_frequency; bool reset_board; @@ -144,7 +145,7 @@ static bool parse_frequency(char* text, uint32_t* result) return true; } -bool parse_options(int argc, char **argv, st_settings_t *settings) { +bool parse_options(int32_t argc, char **argv, st_settings_t *settings) { static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, @@ -157,8 +158,8 @@ bool parse_options(int argc, char **argv, st_settings_t *settings) { {"force", no_argument, NULL, 'f'}, {0, 0, 0, 0}, }; - int option_index = 0; - int c; + int32_t option_index = 0; + int32_t c; bool error = false; settings->show_help = false; @@ -421,7 +422,7 @@ static trace_state update_trace(st_trace_t *trace, uint8_t c) { static bool read_trace(stlink_t *stlink, st_trace_t *trace) { uint8_t buffer[STLINK_TRACE_BUF_LEN]; - int length = stlink_trace_read(stlink, buffer, sizeof(buffer)); + int32_t length = stlink_trace_read(stlink, buffer, sizeof(buffer)); if (length < 0) { ELOG("Error reading trace (%d)\n", length); @@ -441,7 +442,7 @@ static bool read_trace(stlink_t *stlink, st_trace_t *trace) { trace->state = TRACE_STATE_UNKNOWN; } - for (int i = 0; i < length; i++) { + for (int32_t i = 0; i < length; i++) { trace->state = update_trace(trace, buffer[i]); } @@ -531,7 +532,7 @@ static void check_for_configuration_error(stlink_t *stlink, st_trace_t *trace, WLOG("****\n"); } -int main(int argc, char **argv) { +int32_t main(int32_t argc, char **argv) { #if defined(_WIN32) SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); #else diff --git a/src/st-util/gdb-remote.c b/src/st-util/gdb-remote.c index bdf8afd24..7d0f2c731 100644 --- a/src/st-util/gdb-remote.c +++ b/src/st-util/gdb-remote.c @@ -5,8 +5,8 @@ #include #include -#include #include +#include #if defined(_WIN32) #include @@ -19,9 +19,9 @@ static const char hex[] = "0123456789abcdef"; -int gdb_send_packet(int fd, char* data) { - unsigned int data_length = (unsigned int)strlen(data); - int length = data_length + 4; +int32_t gdb_send_packet(int32_t fd, char* data) { + uint32_t data_length = (uint32_t)strlen(data); + int32_t length = data_length + 4; char* packet = malloc(length); // '$' data (hex) '#' cksum (hex) memset(packet, 0, length); @@ -30,7 +30,7 @@ int gdb_send_packet(int fd, char* data) { uint8_t cksum = 0; - for (unsigned int i = 0; i < data_length; i++) { + for (uint32_t i = 0; i < data_length; i++) { packet[i + 1] = data[i]; cksum += data[i]; } @@ -61,12 +61,12 @@ int gdb_send_packet(int fd, char* data) { #define ALLOC_STEP 1024 -int gdb_recv_packet(int fd, char** buffer) { - unsigned packet_size = ALLOC_STEP + 1, packet_idx = 0; +int32_t gdb_recv_packet(int32_t fd, char** buffer) { + uint32_t packet_size = ALLOC_STEP + 1, packet_idx = 0; uint8_t cksum = 0; char recv_cksum[3] = {0}; char* packet_buffer = malloc(packet_size); - unsigned state; + uint32_t state; if (packet_buffer == NULL) { return(-2); @@ -167,7 +167,7 @@ int gdb_recv_packet(int fd, char** buffer) { * As we use the mode with ACK, in a (very unlikely) situation of a packet lost * because of this skipping, it will be resent anyway. */ -int gdb_check_for_interrupt(int fd) { +int32_t gdb_check_for_interrupt(int32_t fd) { struct pollfd pfd; pfd.fd = fd; pfd.events = POLLIN; diff --git a/src/st-util/gdb-remote.h b/src/st-util/gdb-remote.h index 03d6aea10..ec990455b 100644 --- a/src/st-util/gdb-remote.h +++ b/src/st-util/gdb-remote.h @@ -1,8 +1,10 @@ #ifndef GDB_REMOTE_H #define GDB_REMOTE_H -int gdb_send_packet(int fd, char* data); -int gdb_recv_packet(int fd, char** buffer); -int gdb_check_for_interrupt(int fd); +#include + +int32_t gdb_send_packet(int32_t fd, char* data); +int32_t gdb_recv_packet(int32_t fd, char** buffer); +int32_t gdb_check_for_interrupt(int32_t fd); #endif // GDB_REMOTE_H diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 99cc0170b..557a24f5f 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -57,18 +58,18 @@ static const char hex[] = "0123456789abcdef"; typedef struct _st_state_t { // things from command line, bleh - int logging_level; - int listen_port; - int persistent; + int32_t logging_level; + int32_t listen_port; + int32_t persistent; enum connect_type connect_mode; - int freq; + int32_t freq; char serialnumber[STLINK_SERIAL_BUFFER_SIZE]; bool semihosting; const char* current_memory_map; } st_state_t; -int serve(stlink_t *sl, st_state_t *st); +int32_t serve(stlink_t *sl, st_state_t *st); char* make_memory_map(stlink_t *sl); static void init_cache(stlink_t *sl); @@ -81,7 +82,7 @@ static void _cleanup() { } } -static void cleanup(int signum) { +static void cleanup(int32_t signum) { printf("Receive signal %i. Exiting...\n", signum); _cleanup(); exit(1); @@ -90,13 +91,13 @@ static void cleanup(int signum) { #if defined(_WIN32) BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { - printf("Receive signal %i. Exiting...\r\n", (int)fdwCtrlType); + printf("Receive signal %i. Exiting...\r\n", (int32_t)fdwCtrlType); _cleanup(); return FALSE; } #endif -int parse_options(int argc, char** argv, st_state_t *st) { +int32_t parse_options(int32_t argc, char** argv, st_state_t *st) { static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"verbose", optional_argument, NULL, 'v'}, @@ -139,9 +140,9 @@ int parse_options(int argc, char** argv, st_state_t *st) { ; - int option_index = 0; - int c; - int q; + int32_t option_index = 0; + int32_t c; + int32_t q; while ((c = getopt_long(argc, argv, "hv::p:mn", long_options, &option_index)) != -1) switch (c) { @@ -211,7 +212,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { return(0); } -int main(int argc, char** argv) { +int32_t main(int32_t argc, char** argv) { stlink_t *sl = NULL; st_state_t state; memset(&state, 0, sizeof(state)); @@ -564,42 +565,42 @@ char* make_memory_map(stlink_t *sl) { strcpy(map, memory_map_template_F4_DE); } else if (sl->core_id == STM32_CORE_ID_M7F_SWD) { snprintf(map, sz, memory_map_template_F7, - (unsigned int)sl->sram_size); + (uint32_t)sl->sram_size); } else if (sl->chip_id == STM32_CHIPID_H74xxx) { snprintf(map, sz, memory_map_template_H7, - (unsigned int)sl->flash_size, - (unsigned int)sl->flash_pgsz); + (uint32_t)sl->flash_size, + (uint32_t)sl->flash_pgsz); } else if (sl->chip_id == STM32_CHIPID_F4_HD) { strcpy(map, memory_map_template_F4_HD); } else if (sl->chip_id == STM32_CHIPID_F2) { snprintf(map, sz, memory_map_template_F2, - (unsigned int)sl->flash_size, - (unsigned int)sl->sram_size, - (unsigned int)sl->flash_size - 0x20000, - (unsigned int)sl->sys_base, - (unsigned int)sl->sys_size); + (uint32_t)sl->flash_size, + (uint32_t)sl->sram_size, + (uint32_t)sl->flash_size - 0x20000, + (uint32_t)sl->sys_base, + (uint32_t)sl->sys_size); } else if ((sl->chip_id == STM32_CHIPID_L4) || (sl->chip_id == STM32_CHIPID_L43x_L44x) || (sl->chip_id == STM32_CHIPID_L45x_L46x)) { snprintf(map, sz, memory_map_template_L4, - (unsigned int)sl->flash_size, - (unsigned int)sl->flash_size); + (uint32_t)sl->flash_size, + (uint32_t)sl->flash_size); } else if (sl->chip_id == STM32_CHIPID_L496x_L4A6x) { snprintf(map, sz, memory_map_template_L496, - (unsigned int)sl->flash_size, - (unsigned int)sl->flash_size); + (uint32_t)sl->flash_size, + (uint32_t)sl->flash_size); } else if (sl->chip_id == STM32_CHIPID_H72x) { snprintf(map, sz, memory_map_template_H72x3x, - (unsigned int)sl->flash_size, - (unsigned int)sl->flash_pgsz); + (uint32_t)sl->flash_size, + (uint32_t)sl->flash_pgsz); } else { snprintf(map, sz, memory_map_template, - (unsigned int)sl->flash_size, - (unsigned int)sl->sram_size, - (unsigned int)sl->flash_size, - (unsigned int)sl->flash_pgsz, - (unsigned int)sl->sys_base, - (unsigned int)sl->sys_size); + (uint32_t)sl->flash_size, + (uint32_t)sl->sram_size, + (uint32_t)sl->flash_size, + (uint32_t)sl->flash_pgsz, + (uint32_t)sl->sys_base, + (uint32_t)sl->sys_size); } return(map); @@ -627,14 +628,14 @@ static void init_data_watchpoints(stlink_t *sl) { stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, data); // make sure all watchpoints are cleared - for (int i = 0; i < DATA_WATCH_NUM; i++) { + for (int32_t i = 0; i < DATA_WATCH_NUM; i++) { data_watches[i].fun = WATCHDISABLED; stlink_write_debug32(sl, STLINK_REG_CM3_DWT_FUNn(i), 0); } } -static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr, unsigned int len) { - int i = 0; +static int32_t add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr, uint32_t len) { + int32_t i = 0; uint32_t mask, dummy; // computer mask @@ -678,8 +679,8 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr return(-1); } -static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { - int i; +static int32_t delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { + int32_t i; for (i = 0; i < DATA_WATCH_NUM; i++) { if ((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) { @@ -697,9 +698,9 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { return(-1); } -static int code_break_num; -static int code_lit_num; -static int code_break_rev; +static int32_t code_break_num; +static int32_t code_lit_num; +static int32_t code_break_rev; #define CODE_BREAK_NUM_MAX 15 #define CODE_BREAK_LOW 0x01 #define CODE_BREAK_HIGH 0x02 @@ -709,13 +710,13 @@ static int code_break_rev; struct code_hw_breakpoint { stm32_addr_t addr; - int type; + int32_t type; }; static struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM_MAX]; static void init_code_breakpoints(stlink_t *sl) { - unsigned int val; + uint32_t val; memset(sl->q_buf, 0, 4); stlink_write_debug32(sl, STLINK_REG_CM3_FP_CTRL, 0x03 /* KEY | ENABLE */); stlink_read_debug32(sl, STLINK_REG_CM3_FP_CTRL, &val); @@ -732,22 +733,22 @@ static void init_code_breakpoints(stlink_t *sl) { stlink_write_debug32(sl, STLINK_REG_CM7_FP_LAR, STLINK_REG_CM7_FP_LAR_KEY); } - for (int i = 0; i < code_break_num; i++) { + for (int32_t i = 0; i < code_break_num; i++) { code_breaks[i].type = 0; stlink_write_debug32(sl, STLINK_REG_CM3_FP_COMPn(i), 0); } } -static int has_breakpoint(stm32_addr_t addr) { - for (int i = 0; i < code_break_num; i++) +static int32_t has_breakpoint(stm32_addr_t addr) { + for (int32_t i = 0; i < code_break_num; i++) if (code_breaks[i].addr == addr) { return(1); } return(0); } -static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { +static int32_t update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int32_t set) { uint32_t mask; - int type; + int32_t type; stm32_addr_t fpb_addr; if (addr & 1) { @@ -763,8 +764,8 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { fpb_addr = addr; } - int id = -1; - for (int i = 0; i < code_break_num; i++) + int32_t id = -1; + for (int32_t i = 0; i < code_break_num; i++) if (fpb_addr == code_breaks[i].addr || (set && code_breaks[i].type == 0)) { id = i; break; @@ -802,7 +803,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { struct flash_block { stm32_addr_t addr; - unsigned length; + uint32_t length; uint8_t* data; struct flash_block* next; @@ -810,7 +811,7 @@ struct flash_block { static struct flash_block* flash_root; -static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { +static int32_t flash_add_block(stm32_addr_t addr, uint32_t length, stlink_t *sl) { if (addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) { ELOG("flash_add_block: incorrect bounds\n"); @@ -835,8 +836,8 @@ static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { return(0); } -static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { - unsigned int fit_blocks = 0, fit_length = 0; +static int32_t flash_populate(stm32_addr_t addr, uint8_t* data, uint32_t length) { + uint32_t fit_blocks = 0, fit_length = 0; for (struct flash_block* fb = flash_root; fb; fb = fb->next) { /* @@ -848,13 +849,13 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { * a < Y && b > x */ - unsigned X = fb->addr, Y = fb->addr + fb->length; - unsigned a = addr, b = addr + length; + uint32_t X = fb->addr, Y = fb->addr + fb->length; + uint32_t a = addr, b = addr + length; if (a < Y && b > X) { // from start of the block - unsigned start = (a > X ? a : X) - X; - unsigned end = (b > Y ? Y : b) - X; + uint32_t start = (a > X ? a : X) - X; + uint32_t end = (b > Y ? Y : b) - X; memcpy(fb->data + start, data, end - start); @@ -876,9 +877,9 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { return(0); } -static int flash_go(stlink_t *sl, st_state_t *st) { - int error = -1; - int ret; +static int32_t flash_go(stlink_t *sl, st_state_t *st) { + int32_t error = -1; + int32_t ret; flash_loader_t fl; stlink_target_connect(sl, st->connect_mode); @@ -904,13 +905,13 @@ static int flash_go(stlink_t *sl, st_state_t *st) { ILOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length); for (stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += (uint32_t)FLASH_PAGE) { - unsigned length = fb->length - (page - fb->addr); + uint32_t length = fb->length - (page - fb->addr); // update FLASH_PAGE stlink_calculate_pagesize(sl, page); ILOG("flash_do: page %08x\n", page); - unsigned len = (length > FLASH_PAGE) ? (unsigned int)FLASH_PAGE : length; + uint32_t len = (length > FLASH_PAGE) ? (uint32_t)FLASH_PAGE : length; ret = stlink_flashloader_write(sl, &fl, page, fb->data + (page - fb->addr), len); if (ret) { goto error; } } @@ -933,21 +934,21 @@ static int flash_go(stlink_t *sl, st_state_t *st) { } struct cache_level_desc { - unsigned int nsets; - unsigned int nways; - unsigned int log2_nways; - unsigned int width; + uint32_t nsets; + uint32_t nways; + uint32_t log2_nways; + uint32_t width; }; struct cache_desc_t { - unsigned used; + uint32_t used; // minimal line size in bytes - unsigned int dminline; - unsigned int iminline; + uint32_t dminline; + uint32_t iminline; // last level of unification (uniprocessor) - unsigned int louu; + uint32_t louu; struct cache_level_desc icache[7]; struct cache_level_desc dcache[7]; @@ -956,8 +957,8 @@ struct cache_desc_t { static struct cache_desc_t cache_desc; // return the smallest R so that V <= (1 << R); not performance critical -static unsigned ceil_log2(unsigned v) { - unsigned res; +static uint32_t ceil_log2(uint32_t v) { + uint32_t res; for (res = 0; (1U << res) < v; res++); @@ -965,8 +966,8 @@ static unsigned ceil_log2(unsigned v) { } static void read_cache_level_desc(stlink_t *sl, struct cache_level_desc *desc) { - unsigned int ccsidr; - unsigned int log2_nsets; + uint32_t ccsidr; + uint32_t log2_nsets; stlink_read_debug32(sl, STLINK_REG_CM7_CCSIDR, &ccsidr); desc->nsets = ((ccsidr >> 13) & 0x3fff) + 1; @@ -979,10 +980,10 @@ static void read_cache_level_desc(stlink_t *sl, struct cache_level_desc *desc) { } static void init_cache (stlink_t *sl) { - unsigned int clidr; - unsigned int ccr; - unsigned int ctr; - int i; + uint32_t clidr; + uint32_t ccr; + uint32_t ctr; + int32_t i; // Check have cache stlink_read_debug32(sl, STLINK_REG_CM7_CTR, &ctr); @@ -1006,7 +1007,7 @@ static void init_cache (stlink_t *sl) { cache_desc.dminline, cache_desc.iminline); for (i = 0; i < 7; i++) { - unsigned int ct = (clidr >> (3 * i)) & 0x07; + uint32_t ct = (clidr >> (3 * i)) & 0x07; cache_desc.dcache[i].width = 0; cache_desc.icache[i].width = 0; @@ -1024,19 +1025,19 @@ static void init_cache (stlink_t *sl) { } } -static void cache_flush(stlink_t *sl, unsigned ccr) { - int level; +static void cache_flush(stlink_t *sl, uint32_t ccr) { + int32_t level; if (ccr & STLINK_REG_CM7_CCR_DC) { for (level = cache_desc.louu - 1; level >= 0; level--) { struct cache_level_desc *desc = &cache_desc.dcache[level]; - unsigned addr; - unsigned max_addr = 1 << desc->width; - unsigned way_sh = 32 - desc->log2_nways; + uint32_t addr; + uint32_t max_addr = 1 << desc->width; + uint32_t way_sh = 32 - desc->log2_nways; // D-cache clean by set-ways. for (addr = (level << 1); addr < max_addr; addr += cache_desc.dminline) { - unsigned int way; + uint32_t way; for (way = 0; way < desc->nways; way++) { stlink_write_debug32(sl, STLINK_REG_CM7_DCCSW, addr | (way << way_sh)); @@ -1051,9 +1052,9 @@ static void cache_flush(stlink_t *sl, unsigned ccr) { } } -static int cache_modified; +static int32_t cache_modified; -static void cache_change(stm32_addr_t start, unsigned count) { +static void cache_change(stm32_addr_t start, uint32_t count) { if (count == 0) { return; } (void)start; @@ -1061,7 +1062,7 @@ static void cache_change(stm32_addr_t start, unsigned count) { } static void cache_sync(stlink_t *sl) { - unsigned ccr; + uint32_t ccr; if (!cache_desc.used) { return; } @@ -1074,7 +1075,7 @@ static void cache_sync(stlink_t *sl) { static size_t unhexify(const char *in, char *out, size_t out_count) { size_t i; - unsigned int c; + uint32_t c; for (i = 0; i < out_count; i++) { if (sscanf(in + (2 * i), "%02x", &c) != 1) { return(i); } @@ -1085,7 +1086,7 @@ static size_t unhexify(const char *in, char *out, size_t out_count) { return(i); } -int serve(stlink_t *sl, st_state_t *st) { +int32_t serve(stlink_t *sl, st_state_t *st) { SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); if (!IS_SOCK_VALID(sock)) { @@ -1093,7 +1094,7 @@ int serve(stlink_t *sl, st_state_t *st) { return(1); } - unsigned int val = 1; + uint32_t val = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); struct sockaddr_in serv_addr; @@ -1149,16 +1150,16 @@ int serve(stlink_t *sl, st_state_t *st) { * To allow resetting the chip from GDB it is required to emulate attaching * and detaching to target. */ - unsigned int attached = 1; + uint32_t attached = 1; // if a critical error is detected, break from the loop - int critical_error = 0; - int ret; + int32_t critical_error = 0; + int32_t ret; while (1) { ret = 0; char* packet; - int status = gdb_recv_packet(client, &packet); + int32_t status = gdb_recv_packet(client, &packet); if (status < 0) { ELOG("cannot recv: %d\n", status); @@ -1186,7 +1187,7 @@ int serve(stlink_t *sl, st_state_t *st) { params = separator + 1; } - unsigned queryNameLength = (unsigned int)(separator - &packet[1]); + uint32_t queryNameLength = (uint32_t)(separator - &packet[1]); char* queryName = calloc(queryNameLength + 1, 1); strncpy(queryName, &packet[1], queryNameLength); @@ -1205,8 +1206,8 @@ int serve(stlink_t *sl, st_state_t *st) { __s_addr = strsep(&tok, ","); s_length = tok; - unsigned addr = (unsigned int)strtoul(__s_addr, NULL, 16), - length = (unsigned int)strtoul(s_length, NULL, 16); + uint32_t addr = (uint32_t)strtoul(__s_addr, NULL, 16), + length = (uint32_t)strtoul(s_length, NULL, 16); DLOG("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", type, op, annex, addr, length); @@ -1223,7 +1224,7 @@ int serve(stlink_t *sl, st_state_t *st) { } if (data) { - unsigned data_length = (unsigned int)strlen(data); + uint32_t data_length = (uint32_t)strlen(data); if (addr + length > data_length) { length = data_length - addr; } @@ -1366,8 +1367,8 @@ int serve(stlink_t *sl, st_state_t *st) { __s_addr = strsep(&tok, ","); s_length = tok; - unsigned addr = (unsigned int)strtoul(__s_addr, NULL, 16), - length = (unsigned int)strtoul(s_length, NULL, 16); + uint32_t addr = (uint32_t)strtoul(__s_addr, NULL, 16), + length = (uint32_t)strtoul(s_length, NULL, 16); DLOG("FlashErase: addr:%08x,len:%04x\n", addr, length); @@ -1384,15 +1385,15 @@ int serve(stlink_t *sl, st_state_t *st) { __s_addr = strsep(&tok, ":"); data = tok; - unsigned addr = (unsigned int)strtoul(__s_addr, NULL, 16); - unsigned data_length = status - (unsigned int)(data - packet); + uint32_t addr = (uint32_t)strtoul(__s_addr, NULL, 16); + uint32_t data_length = status - (uint32_t)(data - packet); // Length of decoded data cannot be more than encoded, as escapes are removed. // Additional byte is reserved for alignment fix. uint8_t *decoded = calloc(data_length + 1, 1); - unsigned dec_index = 0; + uint32_t dec_index = 0; - for (unsigned int i = 0; i < data_length; i++) { + for (uint32_t i = 0; i < data_length; i++) { if (data[i] == 0x7d) { i++; decoded[dec_index++] = data[i] ^ 0x20; @@ -1457,7 +1458,7 @@ int serve(stlink_t *sl, st_state_t *st) { struct stlink_reg reg; stm32_addr_t pc; stm32_addr_t addr; - int offset = 0; + int32_t offset = 0; uint16_t insn; if (!st->semihosting) { break; } @@ -1547,15 +1548,15 @@ int serve(stlink_t *sl, st_state_t *st) { reply = calloc(8 * 16 + 1, 1); - for (int i = 0; i < 16; i++) { + for (int32_t i = 0; i < 16; i++) { sprintf(&reply[i * 8], "%08x", (uint32_t)htonl(regp.r[i])); } break; case 'p': { - unsigned id = (unsigned int)strtoul(&packet[1], NULL, 16); - unsigned myreg = 0xDEADDEAD; + uint32_t id = (uint32_t)strtoul(&packet[1], NULL, 16); + uint32_t myreg = 0xDEADDEAD; if (id < 16) { ret = stlink_read_reg(sl, id, ®p); @@ -1607,8 +1608,8 @@ int serve(stlink_t *sl, st_state_t *st) { char* s_reg = &packet[1]; char* s_value = strstr(&packet[1], "=") + 1; - unsigned reg = (unsigned int)strtoul(s_reg, NULL, 16); - unsigned value = (unsigned int)strtoul(s_value, NULL, 16); + uint32_t reg = (uint32_t)strtoul(s_reg, NULL, 16); + uint32_t value = (uint32_t)strtoul(s_value, NULL, 16); if (reg < 16) { @@ -1645,7 +1646,7 @@ int serve(stlink_t *sl, st_state_t *st) { case 'G': - for (int i = 0; i < 16; i++) { + for (int32_t i = 0; i < 16; i++) { char str[9] = {0}; strncpy(str, &packet[1 + i * 8], 8); uint32_t reg = (uint32_t)strtoul(str, NULL, 16); @@ -1662,12 +1663,12 @@ int serve(stlink_t *sl, st_state_t *st) { char* s_count = strstr(&packet[1], ",") + 1; stm32_addr_t start = (stm32_addr_t)strtoul(s_start, NULL, 16); - unsigned count = (unsigned int)strtoul(s_count, NULL, 16); + uint32_t count = (uint32_t)strtoul(s_count, NULL, 16); - unsigned adj_start = start % 4; - unsigned count_rnd = (count + adj_start + 4 - 1) / 4 * 4; + uint32_t adj_start = start % 4; + uint32_t count_rnd = (count + adj_start + 4 - 1) / 4 * 4; - if (count_rnd > sl->flash_pgsz) { count_rnd = (unsigned int)sl->flash_pgsz; } + if (count_rnd > sl->flash_pgsz) { count_rnd = (uint32_t)sl->flash_pgsz; } if (count_rnd > 0x1800) { count_rnd = 0x1800; } @@ -1679,7 +1680,7 @@ int serve(stlink_t *sl, st_state_t *st) { reply = calloc(count * 2 + 1, 1); - for (unsigned int i = 0; i < count; i++) { + for (uint32_t i = 0; i < count; i++) { reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4]; reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf]; } @@ -1693,15 +1694,15 @@ int serve(stlink_t *sl, st_state_t *st) { char* hexdata = strstr(packet, ":") + 1; stm32_addr_t start = (stm32_addr_t)strtoul(s_start, NULL, 16); - unsigned count = (unsigned int)strtoul(s_count, NULL, 16); - int err = 0; + uint32_t count = (uint32_t)strtoul(s_count, NULL, 16); + int32_t err = 0; if (start % 4) { - unsigned align_count = 4 - start % 4; + uint32_t align_count = 4 - start % 4; if (align_count > count) { align_count = count; } - for (unsigned int i = 0; i < align_count; i++) { + for (uint32_t i = 0; i < align_count; i++) { char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 }; uint8_t byte = (uint8_t)strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; @@ -1715,9 +1716,9 @@ int serve(stlink_t *sl, st_state_t *st) { } if (count - count % 4) { - unsigned aligned_count = count - count % 4; + uint32_t aligned_count = count - count % 4; - for (unsigned int i = 0; i < aligned_count; i++) { + for (uint32_t i = 0; i < aligned_count; i++) { char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 }; uint8_t byte = (uint8_t)strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; @@ -1731,7 +1732,7 @@ int serve(stlink_t *sl, st_state_t *st) { } if (count) { - for (unsigned int i = 0; i < count; i++) { + for (uint32_t i = 0; i < count; i++) { char hextmp[3] = { hexdata[i * 2], hexdata[i * 2 + 1], 0 }; uint8_t byte = (uint8_t)strtoul(hextmp, NULL, 16); sl->q_buf[i] = byte; @@ -1871,7 +1872,7 @@ int serve(stlink_t *sl, st_state_t *st) { if (reply) { DLOG("send: %s\n", reply); - int result = gdb_send_packet(client, reply); + int32_t result = gdb_send_packet(client, reply); if (result != 0) { ELOG("cannot send: %d\n", result); diff --git a/src/st-util/semihosting.c b/src/st-util/semihosting.c index f603f6224..93a6cf7cc 100644 --- a/src/st-util/semihosting.c +++ b/src/st-util/semihosting.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -11,9 +12,9 @@ #include #include "semihosting.h" -static int mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) { - int offset = addr % 4; - int len = 4; +static int32_t mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) { + int32_t offset = addr % 4; + int32_t len = 4; if (sl == NULL || data == NULL) { return(-1); } @@ -25,9 +26,9 @@ static int mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) { } #ifdef UNUSED -static int mem_read_u16(stlink_t *sl, uint32_t addr, uint16_t *data) { - int offset = addr % 4; - int len = (offset > 2 ? 8 : 4); +static int32_t mem_read_u16(stlink_t *sl, uint32_t addr, uint16_t *data) { + int32_t offset = addr % 4; + int32_t len = (offset > 2 ? 8 : 4); if (sl == NULL || data == NULL) { return(-1); } @@ -38,9 +39,9 @@ static int mem_read_u16(stlink_t *sl, uint32_t addr, uint16_t *data) { return(0); } -static int mem_read_u32(stlink_t *sl, uint32_t addr, uint32_t *data) { - int offset = addr % 4; - int len = (offset > 0 ? 8 : 4); +static int32_t mem_read_u32(stlink_t *sl, uint32_t addr, uint32_t *data) { + int32_t offset = addr % 4; + int32_t len = (offset > 0 ? 8 : 4); if (sl == NULL || data == NULL) { return(-1); } @@ -52,9 +53,9 @@ static int mem_read_u32(stlink_t *sl, uint32_t addr, uint32_t *data) { } #endif -static int mem_read(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { - int offset = addr % 4; - int read_len = len + offset; +static int32_t mem_read(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { + int32_t offset = addr % 4; + int32_t read_len = len + offset; if (sl == NULL || data == NULL) { return(-1); } @@ -68,7 +69,7 @@ static int mem_read(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { return(0); } -static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { +static int32_t mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { /* Note: this function can write more than it is asked to! * If addr is not an even 32 bit boundary, or len is not a multiple of 4. * If only 32 bit values can be written to the target, then this function should read @@ -78,8 +79,8 @@ static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { * Just return when the length is zero avoiding unneeded work. */ if (len == 0) { return(0); } - int offset = addr % 4; - int write_len = len + offset; + int32_t offset = addr % 4; + int32_t write_len = len + offset; if (sl == NULL || data == NULL) { return(-1); } @@ -112,7 +113,7 @@ static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { #define O_BINARY 0 #endif -static int open_mode_flags[12] = { +static int32_t open_mode_flags[12] = { O_RDONLY, O_RDONLY | O_BINARY, O_RDWR, @@ -127,9 +128,9 @@ static int open_mode_flags[12] = { O_RDWR | O_CREAT | O_APPEND | O_BINARY }; -static int saved_errno = 0; +static int32_t saved_errno = 0; -int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { +int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (sl == NULL || ret == NULL) { return(-1); } @@ -200,7 +201,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { case SEMIHOST_SYS_CLOSE: { uint32_t args[1]; - int fd; + int32_t fd; if (mem_read(sl, r1, args, sizeof(args)) != 0) { DLOG("Semihosting SYS_CLOSE error: cannot read args from target memory\n"); @@ -208,7 +209,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { return(-1); } - fd = (int)args[0]; + fd = (int32_t)args[0]; DLOG("Semihosting: close(%d)\n", fd); @@ -222,7 +223,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { { uint32_t args[3]; uint32_t buffer_address; - int fd; + int32_t fd; uint32_t buffer_len; void *buffer; @@ -232,7 +233,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { return(-1); } - fd = (int)args[0]; + fd = (int32_t)args[0]; buffer_address = args[1]; buffer_len = args[2]; @@ -277,7 +278,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { { uint32_t args[3]; uint32_t buffer_address; - int fd; + int32_t fd; uint32_t buffer_len; void *buffer; ssize_t read_result; @@ -288,7 +289,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { return(-1); } - fd = (int)args[0]; + fd = (int32_t)args[0]; buffer_address = args[1]; buffer_len = args[2]; @@ -388,7 +389,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { case SEMIHOST_SYS_SEEK: { uint32_t args[2]; - int fd; + int32_t fd; off_t offset; if (mem_read(sl, r1, args, sizeof(args)) != 0) { @@ -397,10 +398,10 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { return(-1); } - fd = (int)args[0]; + fd = (int32_t)args[0]; offset = (off_t)args[1]; - DLOG("Semihosting: lseek(%d, %d, SEEK_SET)\n", fd, (int)offset); + DLOG("Semihosting: lseek(%d, %d, SEEK_SET)\n", fd, (int32_t)offset); *ret = (uint32_t)lseek(fd, offset, SEEK_SET); saved_errno = errno; @@ -437,7 +438,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { return(-1); } - for (int i = 0; i < WRITE0_BUFFER_SIZE; i++) { + for (int32_t i = 0; i < WRITE0_BUFFER_SIZE; i++) { if (buf[i] == 0) { return(0); } fprintf(stderr, "%c", buf[i]); diff --git a/src/st-util/semihosting.h b/src/st-util/semihosting.h index e7ddfcd97..fd3990ba2 100644 --- a/src/st-util/semihosting.h +++ b/src/st-util/semihosting.h @@ -1,6 +1,8 @@ #ifndef SEMIHOSTING_H #define SEMIHOSTING_H +#include + #include #define SEMIHOST_SYS_OPEN 0x01 @@ -29,6 +31,6 @@ #define SEMIHOST_SYS_ELAPSED 0x30 #define SEMIHOST_SYS_TICKFREQ 0x31 -int do_semihosting(stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret); +int32_t do_semihosting(stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret); #endif // SEMIHOSTING_H diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index 2bf1f9d32..f0426f577 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -263,7 +263,7 @@ static gpointer stlink_gui_populate_filemem_view(gpointer data) { uint8_t* mem = NULL; size_t size = 0; uint32_t begin = 0; - int res = stlink_parse_ihex(gui->filename, 0, &mem, &size, &begin); + int32_t res = stlink_parse_ihex(gui->filename, 0, &mem, &size, &begin); if (res == 0) { if (gui->file_mem.memory) { @@ -440,7 +440,7 @@ static gchar *dev_format_chip_id(guint32 chip_id) { } static gchar *dev_format_mem_size(gsize flash_size) { - return(g_strdup_printf("%u kB", (unsigned int)(flash_size / 1024))); + return(g_strdup_printf("%u kB", (uint32_t)(flash_size / 1024))); } @@ -640,7 +640,7 @@ static void flash_button_cb(GtkWidget *widget, gpointer data) { } } -int export_to_file(const char*filename, const struct mem_t flash_mem) { +int32_t export_to_file(const char*filename, const struct mem_t flash_mem) { printf("%s\n", filename); FILE * f = fopen(filename, "w"); @@ -885,7 +885,7 @@ static void stlink_gui_build_ui(STlinkGUI *gui) { stlink_gui_set_disconnected(gui); } -int main(int argc, char **argv) { +int32_t main(int32_t argc, char **argv) { STlinkGUI *gui; gtk_init(&argc, &argv); diff --git a/src/stlink-gui/gui.h b/src/stlink-gui/gui.h index 08519ea56..2d7f31913 100644 --- a/src/stlink-gui/gui.h +++ b/src/stlink-gui/gui.h @@ -1,6 +1,7 @@ #ifndef GUI_H #define GUI_H +#include #include #define STLINK_TYPE_GUI (stlink_gui_get_type()) @@ -87,6 +88,6 @@ struct _STlinkGUIClass { }; GType stlink_gui_get_type(void); -int export_to_file(const char*filename, const struct mem_t flash_mem); +int32_t export_to_file(const char*filename, const struct mem_t flash_mem); #endif // GUI_H diff --git a/src/stlink-lib/calculate.c b/src/stlink-lib/calculate.c index ddab5ed08..132875a66 100644 --- a/src/stlink-lib/calculate.c +++ b/src/stlink-lib/calculate.c @@ -1,3 +1,5 @@ +#include + #include #include "calculate.h" #include "common_flash.h" @@ -39,7 +41,7 @@ uint32_t calculate_F7_sectornum(uint32_t flashaddr) { } uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, - unsigned bank) { + uint32_t bank) { flashaddr &= ~((bank == BANK_1) ? STM32_FLASH_BASE diff --git a/src/stlink-lib/calculate.h b/src/stlink-lib/calculate.h index 64dfb51b2..bdff782ae 100644 --- a/src/stlink-lib/calculate.h +++ b/src/stlink-lib/calculate.h @@ -7,6 +7,8 @@ #ifndef CALCULATE_H #define CALCULATE_H +#include + uint32_t calculate_F4_sectornum(uint32_t); uint32_t calculate_F7_sectornum(uint32_t); uint32_t calculate_H7_sectornum(stlink_t *, uint32_t, unsigned); diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 347d89e14..7e99a8730 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1,13 +1,14 @@ -#include "chipid.h" -#include -#include - #include #include #include +#include #include #include +#include "chipid.h" +#include +#include + static struct stlink_chipid_params *devicelist; void dump_a_chip(struct stlink_chipid_params *dev) { @@ -43,7 +44,7 @@ void process_chipfile(char *fname) { char *p, buf[256]; char word[64], value[64]; struct stlink_chipid_params *ts; - int nc; + int32_t nc; // fprintf (stderr, "processing chip-id file %s.\n", fname); fp = fopen(fname, "r"); diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index d6afc4525..9eaac722d 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -1,6 +1,8 @@ #ifndef CHIPID_H #define CHIPID_H +#include + #include #include diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index 8e4b9a716..cb87f5f36 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -1,16 +1,15 @@ +#include #include #include #include - +#include #include #include #include #include -#include #include #include - #include "calculate.h" #include "common_flash.h" #include "map_file.h" @@ -28,7 +27,7 @@ // Private structs and functions defines struct stlink_fread_worker_arg { - int fd; + int32_t fd; }; struct stlink_fread_ihex_worker_arg { @@ -42,12 +41,12 @@ struct stlink_fread_ihex_worker_arg { typedef bool (*save_block_fn)(void *arg, uint8_t *block, ssize_t len); static void stop_wdg_in_debug(stlink_t *); -int stlink_jtag_reset(stlink_t *, int); -int stlink_soft_reset(stlink_t *, int); +int32_t stlink_jtag_reset(stlink_t *, int); +int32_t stlink_soft_reset(stlink_t *, int); void _parse_version(stlink_t *, stlink_version_t *); static uint8_t stlink_parse_hex(const char *); -static int stlink_read(stlink_t *, stm32_addr_t, size_t, save_block_fn, void *); -static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg *, int, stm32_addr_t); +static int32_t stlink_read(stlink_t *, stm32_addr_t, size_t, save_block_fn, void *); +static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg *, int32_t, stm32_addr_t); static bool stlink_fread_ihex_worker(void *, uint8_t *, ssize_t); static bool stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg *); static bool stlink_fread_worker(void *, uint8_t *, ssize_t); @@ -67,7 +66,7 @@ void stlink_close(stlink_t *sl) { } // 250 -int stlink_exit_debug_mode(stlink_t *sl) { +int32_t stlink_exit_debug_mode(stlink_t *sl) { DLOG("*** stlink_exit_debug_mode ***\n"); if (sl->flash_type != STM32_FLASH_TYPE_UNKNOWN && @@ -80,16 +79,16 @@ int stlink_exit_debug_mode(stlink_t *sl) { } //248 -int stlink_enter_swd_mode(stlink_t *sl) { +int32_t stlink_enter_swd_mode(stlink_t *sl) { DLOG("*** stlink_enter_swd_mode ***\n"); return (sl->backend->enter_swd_mode(sl)); } // 271 // Force the core into the debug mode -> halted state. -int stlink_force_debug(stlink_t *sl) { +int32_t stlink_force_debug(stlink_t *sl) { DLOG("*** stlink_force_debug_mode ***\n"); - int res = sl->backend->force_debug(sl); + int32_t res = sl->backend->force_debug(sl); if (res) { return (res); } @@ -99,14 +98,14 @@ int stlink_force_debug(stlink_t *sl) { } // 251 -int stlink_exit_dfu_mode(stlink_t *sl) { +int32_t stlink_exit_dfu_mode(stlink_t *sl) { DLOG("*** stlink_exit_dfu_mode ***\n"); return (sl->backend->exit_dfu_mode(sl)); } // 253 -int stlink_core_id(stlink_t *sl) { - int ret; +int32_t stlink_core_id(stlink_t *sl) { + int32_t ret; DLOG("*** stlink_core_id ***\n"); ret = sl->backend->core_id(sl); @@ -127,8 +126,8 @@ int stlink_core_id(stlink_t *sl) { // 287 // stlink_chip_id() is called by stlink_load_device_params() // do not call this procedure directly. -int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { - int ret; +int32_t stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { + int32_t ret; cortex_m3_cpuid_t cpu_id; // Read the CPU ID to determine where to read the core id @@ -193,7 +192,7 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { * @param sl stlink context * @param cpuid pointer to the result object */ -int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { +int32_t stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { uint32_t raw; if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &raw)) { @@ -217,7 +216,7 @@ int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { * @param sl * @return 0 for success, or -1 for unsupported core type. */ -int stlink_load_device_params(stlink_t *sl) { +int32_t stlink_load_device_params(stlink_t *sl) { // This seems to normally work so is unnecessary info for a normal user. // Demoted to debug. -- REW DLOG("Loading device parameters....\n"); @@ -312,17 +311,17 @@ int stlink_load_device_params(stlink_t *sl) { } ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", - params->dev_type, (unsigned)(sl->sram_size / 1024), (unsigned)(sl->flash_size / 1024), - (sl->flash_pgsz < 1024) ? (unsigned)(sl->flash_pgsz) : (unsigned)(sl->flash_pgsz / 1024), + params->dev_type, (uint32_t)(sl->sram_size / 1024), (uint32_t)(sl->flash_size / 1024), + (sl->flash_pgsz < 1024) ? (uint32_t)(sl->flash_pgsz) : (uint32_t)(sl->flash_pgsz / 1024), (sl->flash_pgsz < 1024) ? "byte" : "KiB"); return (0); } // 254 -int stlink_reset(stlink_t *sl, enum reset_type type) { +int32_t stlink_reset(stlink_t *sl, enum reset_type type) { uint32_t dhcsr; - unsigned timeout; + uint32_t timeout; DLOG("*** stlink_reset ***\n"); @@ -352,7 +351,7 @@ int stlink_reset(stlink_t *sl, enum reset_type type) { */ dhcsr = 0; - int res = stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + int32_t res = stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0 && !res) { // reset not done yet --> try reset through AIRCR so that NRST does not need to be connected ILOG("NRST is not connected --> using software reset via AIRCR\n"); @@ -380,9 +379,9 @@ int stlink_reset(stlink_t *sl, enum reset_type type) { return (0); } -int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { - int ret; - unsigned timeout; +int32_t stlink_soft_reset(stlink_t *sl, int32_t halt_on_reset) { + int32_t ret; + uint32_t timeout; uint32_t dhcsr, dfsr; DLOG("*** stlink_soft_reset %s***\n", halt_on_reset ? "(halt) " : ""); @@ -455,7 +454,7 @@ int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { } // 255 -int stlink_run(stlink_t *sl, enum run_type type) { +int32_t stlink_run(stlink_t *sl, enum run_type type) { struct stlink_reg rr; DLOG("*** stlink_run ***\n"); @@ -472,7 +471,7 @@ int stlink_run(stlink_t *sl, enum run_type type) { } // 273 -int stlink_set_swdclk(stlink_t *sl, int freq_khz) { +int32_t stlink_set_swdclk(stlink_t *sl, int32_t freq_khz) { DLOG("*** set_swdclk ***\n"); return (sl->backend->set_swdclk(sl, freq_khz)); } @@ -500,8 +499,8 @@ void stlink_core_stat(stlink_t *sl) { } // 256 -int stlink_status(stlink_t *sl) { - int ret; +int32_t stlink_status(stlink_t *sl) { + int32_t ret; DLOG("*** stlink_status ***\n"); ret = sl->backend->status(sl); @@ -510,7 +509,7 @@ int stlink_status(stlink_t *sl) { } // 257 -int stlink_version(stlink_t *sl) { +int32_t stlink_version(stlink_t *sl) { DLOG("*** looking up stlink version ***\n"); if (sl->backend->version(sl)) { @@ -534,8 +533,8 @@ int stlink_version(stlink_t *sl) { } // 272 -int stlink_target_voltage(stlink_t *sl) { - int voltage = -1; +int32_t stlink_target_voltage(stlink_t *sl) { + int32_t voltage = -1; DLOG("*** reading target voltage\n"); if (sl->backend->target_voltage != NULL) { @@ -560,14 +559,14 @@ bool stlink_is_core_halted(stlink_t *sl) { } // 269 -int stlink_step(stlink_t *sl) { +int32_t stlink_step(stlink_t *sl) { DLOG("*** stlink_step ***\n"); return (sl->backend->step(sl)); } // 270 -int stlink_current_mode(stlink_t *sl) { - int mode = sl->backend->current_mode(sl); +int32_t stlink_current_mode(stlink_t *sl) { + int32_t mode = sl->backend->current_mode(sl); switch (mode) { case STLINK_DEV_DFU_MODE: @@ -586,19 +585,19 @@ int stlink_current_mode(stlink_t *sl) { } // 274 -int stlink_trace_enable(stlink_t *sl, uint32_t frequency) { +int32_t stlink_trace_enable(stlink_t *sl, uint32_t frequency) { DLOG("*** stlink_trace_enable ***\n"); return (sl->backend->trace_enable(sl, frequency)); } // 275 -int stlink_trace_disable(stlink_t *sl) { +int32_t stlink_trace_disable(stlink_t *sl) { DLOG("*** stlink_trace_disable ***\n"); return (sl->backend->trace_disable(sl)); } // 276 -int stlink_trace_read(stlink_t *sl, uint8_t *buf, size_t size) { +int32_t stlink_trace_read(stlink_t *sl, uint8_t *buf, size_t size) { return (sl->backend->trace_read(sl, buf, size)); } @@ -612,7 +611,7 @@ void stlink_print_data(stlink_t *sl) { DLOG("data_len = %d 0x%x\n", sl->q_len, sl->q_len); } - for (int i = 0; i < sl->q_len; i++) { + for (int32_t i = 0; i < sl->q_len; i++) { if (i % 16 == 0) { /* if (sl->q_data_dir == Q_DATA_OUT) { @@ -622,18 +621,18 @@ void stlink_print_data(stlink_t *sl) { } */ } - // DLOG(" %02x", (unsigned int) sl->q_buf[i]); - fprintf(stderr, " %02x", (unsigned int)sl->q_buf[i]); + // DLOG(" %02x", (uint32_t) sl->q_buf[i]); + fprintf(stderr, " %02x", (uint32_t)sl->q_buf[i]); } // DLOG("\n\n"); fprintf(stderr, "\n"); } // 283 -int stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, stm32_addr_t addr) { +int32_t stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, stm32_addr_t addr) { // write the file in sram at addr - int error = -1; + int32_t error = -1; size_t off; size_t len; @@ -688,10 +687,10 @@ int stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, stm32_addr_ } //284 -int stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { +int32_t stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { // write the file in sram at addr - int error = -1; + int32_t error = -1; size_t off; size_t len; mapped_file_t mf = MAPPED_FILE_INITIALIZER; @@ -763,12 +762,12 @@ int stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { } // 302 -int stlink_fread(stlink_t *sl, const char *path, bool is_ihex, stm32_addr_t addr, size_t size) { +int32_t stlink_fread(stlink_t *sl, const char *path, bool is_ihex, stm32_addr_t addr, size_t size) { // read size bytes from addr to file - ILOG("read from address %#010x size %u\n", addr, (unsigned)size); + ILOG("read from address %#010x size %u\n", addr, (uint32_t)size); - int error; - int fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); + int32_t error; + int32_t fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); if (fd == -1) { fprintf(stderr, "open(%s) == -1\n", path); @@ -797,9 +796,9 @@ int stlink_fread(stlink_t *sl, const char *path, bool is_ihex, stm32_addr_t addr } // 300 -int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, size_t size) { +int32_t write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, size_t size) { // write the buffer right after the loader - int ret = 0; + int32_t ret = 0; size_t chunk = size & ~0x3; size_t rem = size & 0x3; @@ -858,15 +857,15 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { } // 279 -int stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **mem, +int32_t stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **mem, size_t *size, uint32_t *begin) { - int res = 0; + int32_t res = 0; *begin = UINT32_MAX; uint8_t *data = NULL; uint32_t end = 0; bool eof_found = false; - for (int scan = 0; (res == 0) && (scan < 2); ++scan) { + for (int32_t scan = 0; (res == 0) && (scan < 2); ++scan) { // parse file two times - first to find memory range, second - to fill it if (scan == 1) { if (!eof_found) { @@ -885,7 +884,7 @@ int stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **mem, data = calloc(*size, 1); // use calloc to get NULL if out of memory if (!data) { - ELOG("Cannot allocate %u bytes\n", (unsigned)(*size)); + ELOG("Cannot allocate %u bytes\n", (uint32_t)(*size)); res = -1; break; } @@ -1029,7 +1028,7 @@ uint8_t stlink_get_erased_pattern(stlink_t *sl) { } // 322 -int stlink_target_connect(stlink_t *sl, enum connect_type connect) { +int32_t stlink_target_connect(stlink_t *sl, enum connect_type connect) { if (connect == CONNECT_UNDER_RESET) { stlink_enter_swd_mode(sl); @@ -1045,7 +1044,7 @@ int stlink_target_connect(stlink_t *sl, enum connect_type connect) { stlink_jtag_reset(sl, STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH); // try to halt the core after reset - unsigned timeout = time_ms() + 10; + uint32_t timeout = time_ms() + 10; while (time_ms() < timeout) { sl->backend->force_debug(sl); usleep(100); @@ -1128,7 +1127,7 @@ static void stop_wdg_in_debug(stlink_t *sl) { } } -int stlink_jtag_reset(stlink_t *sl, int value) { +int32_t stlink_jtag_reset(stlink_t *sl, int32_t value) { DLOG("*** stlink_jtag_reset %d ***\n", value); return (sl->backend->jtag_reset(sl, value)); } @@ -1207,7 +1206,7 @@ void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { /* Limit the block size to compare to 0x1800 as anything larger will stall the * STLINK2 Maybe STLINK V1 needs smaller value! */ -int check_file(stlink_t *sl, mapped_file_t *mf, stm32_addr_t addr) { +int32_t check_file(stlink_t *sl, mapped_file_t *mf, stm32_addr_t addr) { size_t off; size_t n_cmp = sl->flash_pgsz; @@ -1249,7 +1248,7 @@ void md5_calculate(mapped_file_t *mf) { Md5Finalise(&md5Context, &md5Hash); printf("md5 checksum: "); - for (int i = 0; i < (int)sizeof(md5Hash); i++) { + for (int32_t i = 0; i < (int32_t)sizeof(md5Hash); i++) { printf("%x", md5Hash.bytes[i]); } @@ -1269,17 +1268,17 @@ void stlink_checksum(mapped_file_t *mp) { } void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { - unsigned int val; + uint32_t val; // set PC to the reset routine stlink_read_debug32(sl, addr + 4, &val); stlink_write_reg(sl, val, 15); stlink_run(sl, RUN_NORMAL); } -static int stlink_read(stlink_t *sl, stm32_addr_t addr, size_t size, +static int32_t stlink_read(stlink_t *sl, stm32_addr_t addr, size_t size, save_block_fn fn, void *fn_arg) { - int error = -1; + int32_t error = -1; if (size < 1) { size = sl->flash_size; @@ -1333,7 +1332,7 @@ static bool stlink_fread_worker(void *arg, uint8_t *block, ssize_t len) { static uint8_t stlink_parse_hex(const char *hex) { uint8_t d[2]; - for (int i = 0; i < 2; ++i) { + for (int32_t i = 0; i < 2; ++i) { char c = *(hex + i); if (c >= '0' && c <= '9') { @@ -1406,7 +1405,7 @@ static bool stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg *the } static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg *the_arg, - int fd, stm32_addr_t addr) { + int32_t fd, stm32_addr_t addr) { the_arg->file = fdopen(fd, "w"); the_arg->addr = addr; the_arg->lba = 0; diff --git a/src/stlink-lib/common.h b/src/stlink-lib/common.h index dd6cf95b2..c60b49199 100644 --- a/src/stlink-lib/common.h +++ b/src/stlink-lib/common.h @@ -7,7 +7,12 @@ #ifndef COMMON_H #define COMMON_H -int check_file(stlink_t *, mapped_file_t *, stm32_addr_t); +#include + +#include "map_file.h" +#include "md5.h" + +int32_t check_file(stlink_t *, mapped_file_t *, stm32_addr_t); void md5_calculate(mapped_file_t *); void stlink_checksum(mapped_file_t *); void stlink_fwrite_finalize(stlink_t *, stm32_addr_t); diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index a74d88b16..e2a394946 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -1,7 +1,9 @@ +#include #include -#include #include #include + +#include #include "calculate.h" #include "flash_loader.h" #include "common_flash.h" @@ -31,7 +33,7 @@ uint32_t get_stm32l0_flash_base(stlink_t *sl) { } } -uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { +uint32_t read_flash_cr(stlink_t *sl, uint32_t bank) { uint32_t reg, res; if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { @@ -117,7 +119,7 @@ void lock_flash(stlink_t *sl) { } } -static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { +static inline int32_t write_flash_sr(stlink_t *sl, uint32_t bank, uint32_t val) { uint32_t sr_reg; if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || @@ -190,7 +192,7 @@ void clear_flash_error(stlink_t *sl) { } } -uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { +uint32_t read_flash_sr(stlink_t *sl, uint32_t bank) { uint32_t res, sr_reg; if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || @@ -222,9 +224,9 @@ uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { return (res); } -unsigned int is_flash_busy(stlink_t *sl) { +uint32_t is_flash_busy(stlink_t *sl) { uint32_t sr_busy_shift; - unsigned int res; + uint32_t res; if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || @@ -267,7 +269,7 @@ void wait_flash_busy(stlink_t *sl) { ; } -int check_flash_error(stlink_t *sl) { +int32_t check_flash_error(stlink_t *sl) { uint32_t res = 0; uint32_t WRPERR, PROGERR, PGAERR; @@ -361,7 +363,7 @@ int check_flash_error(stlink_t *sl) { return (0); } -static inline unsigned int is_flash_locked(stlink_t *sl) { +static inline uint32_t is_flash_locked(stlink_t *sl) { /* return non zero for true */ uint32_t cr_lock_shift; uint32_t cr_reg; @@ -463,7 +465,7 @@ static void unlock_flash(stlink_t *sl) { } /* unlock flash if already locked */ -int unlock_flash_if(stlink_t *sl) { +int32_t unlock_flash_if(stlink_t *sl) { if (is_flash_locked(sl)) { unlock_flash(sl); @@ -477,9 +479,9 @@ int unlock_flash_if(stlink_t *sl) { return (0); } -int lock_flash_option(stlink_t *sl) { +int32_t lock_flash_option(stlink_t *sl) { uint32_t optlock_shift, optcr_reg, n, optcr2_reg = 0; - int active_bit_level = 1; + int32_t active_bit_level = 1; switch (sl->flash_type) { case STM32_FLASH_TYPE_F0_F1_F3: @@ -555,7 +557,7 @@ int lock_flash_option(stlink_t *sl) { static bool is_flash_option_locked(stlink_t *sl) { uint32_t optlock_shift, optcr_reg; - int active_bit_level = 1; + int32_t active_bit_level = 1; uint32_t n; switch (sl->flash_type) { @@ -612,7 +614,7 @@ static bool is_flash_option_locked(stlink_t *sl) { return (n & (1u << optlock_shift)); } -static int unlock_flash_option(stlink_t *sl) { +static int32_t unlock_flash_option(stlink_t *sl) { uint32_t optkey_reg, optkey2_reg = 0; uint32_t optkey1 = FLASH_OPTKEY1; uint32_t optkey2 = FLASH_OPTKEY2; @@ -669,7 +671,7 @@ static int unlock_flash_option(stlink_t *sl) { return (0); } -int unlock_flash_option_if(stlink_t *sl) { +int32_t unlock_flash_option_if(stlink_t *sl) { if (is_flash_option_locked(sl)) { if (unlock_flash_option(sl)) { ELOG("Could not unlock flash option!\n"); @@ -687,7 +689,7 @@ int unlock_flash_option_if(stlink_t *sl) { } void write_flash_cr_psiz(stlink_t *sl, uint32_t n, - unsigned bank) { + uint32_t bank) { uint32_t cr_reg, psize_shift; uint32_t x = read_flash_cr(sl, bank); @@ -707,7 +709,7 @@ void write_flash_cr_psiz(stlink_t *sl, uint32_t n, stlink_write_debug32(sl, cr_reg, x); } -void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { +void clear_flash_cr_pg(stlink_t *sl, uint32_t bank) { uint32_t cr_reg, n; uint32_t bit = FLASH_CR_PG; @@ -737,7 +739,7 @@ void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { /* ------------------------------------------------------------------------ */ static void wait_flash_busy_progress(stlink_t *sl) { - int i = 0; + int32_t i = 0; fprintf(stdout, "Mass erasing..."); fflush(stdout); @@ -754,11 +756,11 @@ static void wait_flash_busy_progress(stlink_t *sl) { fprintf(stdout, "\n"); } -static inline void write_flash_ar(stlink_t *sl, uint32_t n, unsigned bank) { +static inline void write_flash_ar(stlink_t *sl, uint32_t n, uint32_t bank) { stlink_write_debug32(sl, (bank == BANK_1) ? FLASH_AR : FLASH_AR2, n); } -static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, unsigned bank) { +static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, uint32_t bank) { uint32_t cr_reg, snb_mask, snb_shift, ser_shift; uint32_t x = read_flash_cr(sl, bank); @@ -783,7 +785,7 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, unsigned bank) { stlink_write_debug32(sl, cr_reg, x); } -static void set_flash_cr_per(stlink_t *sl, unsigned bank) { +static void set_flash_cr_per(stlink_t *sl, uint32_t bank) { uint32_t cr_reg, val; if (sl->flash_type == STM32_FLASH_TYPE_G0 || @@ -802,7 +804,7 @@ static void set_flash_cr_per(stlink_t *sl, unsigned bank) { stlink_write_debug32(sl, cr_reg, val); } -static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { +static void clear_flash_cr_per(stlink_t *sl, uint32_t bank) { uint32_t cr_reg; if (sl->flash_type == STM32_FLASH_TYPE_G0 || @@ -836,7 +838,7 @@ static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { stlink_write_debug32(sl, FLASH_L4_CR, x); } -static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { +static void set_flash_cr_strt(stlink_t *sl, uint32_t bank) { uint32_t val, cr_reg, cr_strt; if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { @@ -871,7 +873,7 @@ static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { stlink_write_debug32(sl, cr_reg, val); } -static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { +static void set_flash_cr_mer(stlink_t *sl, bool v, uint32_t bank) { uint32_t val, cr_reg, cr_mer, cr_pg; if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { @@ -936,7 +938,7 @@ static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { * @param flashaddr an address in the flash page to erase * @return 0 on success -ve on failure */ -int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { +int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { // wait for ongoing op to finish wait_flash_busy(sl); // clear flash IO errors @@ -1108,7 +1110,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { lock_flash(sl); } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3 || sl->flash_type == STM32_FLASH_TYPE_F1_XL) { - unsigned bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; + uint32_t bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; unlock_flash_if(sl); clear_flash_cr_pg(sl, bank); // clear the pg bit set_flash_cr_per(sl, bank); // set the page erase bit @@ -1119,7 +1121,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { clear_flash_cr_per(sl, bank); // clear the page erase bit lock_flash(sl); } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { - unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; + uint32_t bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; unlock_flash_if(sl); // unlock if locked uint32_t sector = calculate_H7_sectornum( sl, flashaddr, bank); // calculate the actual page from the address @@ -1135,7 +1137,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { return check_flash_error(sl); } -int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size) { +int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size) { // Check the address and size validity if (stlink_check_address_range_validity(sl, base_addr, size) < 0) { return -1; @@ -1149,11 +1151,11 @@ int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size stm32_addr_t addr = base_addr; do { - long unsigned int page_size = stlink_calculate_pagesize(sl, addr); + uint32_t page_size = stlink_calculate_pagesize(sl, addr); // Check if size is aligned with a page, unless we want to completely erase the last page if ((addr + page_size) > (base_addr + size) && !align_size) { - ELOG("Invalid size (not aligned with a page). Page size at address %#x is %#lx\n", addr, page_size); + ELOG("Invalid size (not aligned with a page). Page size at address %#x is %#x\n", addr, page_size); return (-1); } @@ -1162,7 +1164,7 @@ int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size return (-1); } - fprintf(stdout, "-> Flash page at %#x erased (size: %#lx)\n", addr, page_size); + fprintf(stdout, "-> Flash page at %#x erased (size: %#x)\n", addr, page_size); fflush(stdout); // check the next page is within the range to erase @@ -1173,8 +1175,8 @@ int stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size return 0; } -int stlink_erase_flash_mass(stlink_t *sl) { - int err = 0; +int32_t stlink_erase_flash_mass(stlink_t *sl) { + int32_t err = 0; // TODO: User MER bit to mass-erase WB series. if (sl->flash_type == STM32_FLASH_TYPE_L0_L1 || @@ -1224,11 +1226,11 @@ int stlink_erase_flash_mass(stlink_t *sl) { return (err); } -int stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, +int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_addr_t addr) { /* Write the block in flash at addr */ - int err; - unsigned int num_empty, idx; + int32_t err; + uint32_t num_empty, idx; uint8_t erased_pattern = stlink_get_erased_pattern(sl); /* @@ -1236,7 +1238,7 @@ int stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, * Therfore it is turned off by default. */ if (sl->opt) { - idx = (unsigned int)length; + idx = (uint32_t)length; for (num_empty = 0; num_empty != length; ++num_empty) if (data[--idx] != erased_pattern) { @@ -1273,10 +1275,10 @@ int stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, * @param addr where to start writing * @return 0 on success, -ve on failure. */ -int stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { +int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { /* Write the file in flash at addr */ - int err; - unsigned int num_empty, idx; + int32_t err; + uint32_t num_empty, idx; uint8_t erased_pattern = stlink_get_erased_pattern(sl); mapped_file_t mf = MAPPED_FILE_INITIALIZER; @@ -1290,7 +1292,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { stlink_checksum(&mf); if (sl->opt) { - idx = (unsigned int)mf.len; + idx = (uint32_t)mf.len; for (num_empty = 0; num_empty != mf.len; ++num_empty) { if (mf.base[--idx] != erased_pattern) { @@ -1323,10 +1325,10 @@ int stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { } -int stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { +int32_t stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { // check the contents of path are at addr - int res; + int32_t res; mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { @@ -1346,8 +1348,8 @@ int stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { * @param length how much * @return 0 for success, -ve for failure */ -int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, - unsigned length) { +int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, + uint32_t length) { size_t off; size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; ILOG("Starting verification of write complete\n"); @@ -1369,7 +1371,7 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, stlink_read_mem32(sl, address + (uint32_t)off, (uint16_t)aligned_size); if (memcmp(sl->q_buf, data + off, cmp_size)) { - ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); + ELOG("Verification of flash failed at offset: %u\n", (uint32_t)off); return (-1); } } @@ -1379,23 +1381,23 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, } // Check if an address and size are within the flash -int stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size) { - long unsigned int logvar; +int32_t stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size) { + uint32_t logvar; if (addr < sl->flash_base || addr >= (sl->flash_base + sl->flash_size)) { logvar = sl->flash_base + sl->flash_size - 1; - ELOG("Invalid address, it should be within 0x%08x - 0x%08lx\n", sl->flash_base, logvar); + ELOG("Invalid address, it should be within 0x%08x - 0x%08x\n", sl->flash_base, logvar); return (-1); } if ((addr + size) > (sl->flash_base + sl->flash_size)) { logvar = sl->flash_base + sl->flash_size - addr; - ELOG("The size exceeds the size of the flash (0x%08lx bytes available)\n", logvar); + ELOG("The size exceeds the size of the flash (0x%08x bytes available)\n", logvar); return (-1); } return 0; } // Check if an address is aligned with the beginning of a page -int stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr) { +int32_t stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr) { stm32_addr_t page = sl->flash_base; while (page < addr) { @@ -1409,9 +1411,9 @@ int stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr) { return 0; } -int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, +int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint8_t eraseonly) { - int ret; + int32_t ret; flash_loader_t fl; ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr); @@ -1428,7 +1430,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, ELOG("addr not a multiple of current pagesize (%u bytes), not supported, " "check page start address and compare with flash module organisation " "in related ST reference manual of your device.\n", - (unsigned)(sl->flash_pgsz)); + (uint32_t)(sl->flash_pgsz)); return (-1); } diff --git a/src/stlink-lib/common_flash.h b/src/stlink-lib/common_flash.h index aa92b2143..04e9134b5 100644 --- a/src/stlink-lib/common_flash.h +++ b/src/stlink-lib/common_flash.h @@ -7,13 +7,15 @@ #ifndef COMMON_FLASH_H #define COMMON_FLASH_H +#include + void lock_flash(stlink_t *); void clear_flash_error(stlink_t *); void wait_flash_busy(stlink_t *); -int check_flash_error(stlink_t *); -int unlock_flash_if(stlink_t *); -int lock_flash_option(stlink_t *); -int unlock_flash_option_if(stlink_t *); +int32_t check_flash_error(stlink_t *); +int32_t unlock_flash_if(stlink_t *); +int32_t lock_flash_option(stlink_t *); +int32_t unlock_flash_option_if(stlink_t *); void write_flash_cr_psiz(stlink_t *, uint32_t, unsigned); void clear_flash_cr_pg(stlink_t *, unsigned); diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 231a5d4d6..99a8260f7 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -151,7 +152,7 @@ static const uint8_t loader_code_stm32f7_lv[] = { }; -int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { +int32_t stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { size_t size = 0; uint32_t dfsr, cfsr, hfsr; @@ -199,18 +200,18 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { return(0); } -static int loader_v_dependent_assignment(stlink_t *sl, +static int32_t loader_v_dependent_assignment(stlink_t *sl, const uint8_t **loader_code, size_t *loader_size, const uint8_t *high_v_loader, size_t high_v_loader_size, const uint8_t *low_v_loader, size_t low_v_loader_size) { - int retval = 0; + int32_t retval = 0; if ( sl->version.stlink_v == 1) { printf("STLINK V1 cannot read voltage, defaulting to 32-bit writes\n"); *loader_code = high_v_loader; *loader_size = high_v_loader_size; } else { - int voltage = stlink_target_voltage(sl); + int32_t voltage = stlink_target_voltage(sl); if (voltage == -1) { retval = -1; @@ -229,7 +230,7 @@ static int loader_v_dependent_assignment(stlink_t *sl, return(retval); } -int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { +int32_t stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { const uint8_t* loader_code; size_t loader_size; @@ -270,7 +271,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STM32_CHIPID_F412 || sl->chip_id == STM32_CHIPID_F413 || sl->chip_id == STM32_CHIPID_F446) { - int retval; + int32_t retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, loader_code_stm32f4, sizeof(loader_code_stm32f4), @@ -281,7 +282,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STM32_CHIPID_F7 || sl->chip_id == STM32_CHIPID_F76xxx || sl->chip_id == STM32_CHIPID_F72xxx) { - int retval; + int32_t retval; retval = loader_v_dependent_assignment(sl, &loader_code, &loader_size, loader_code_stm32f7, sizeof(loader_code_stm32f7), @@ -310,7 +311,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* } memcpy(sl->q_buf, loader_code, loader_size); - int ret = stlink_write_mem32(sl, sl->sram_base, (uint16_t)loader_size); + int32_t ret = stlink_write_mem32(sl, sl->sram_base, (uint16_t)loader_size); if (ret) { return(ret); } @@ -320,13 +321,13 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* return(0); // success } -int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { +int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { struct stlink_reg rr; - unsigned timeout; + uint32_t timeout; uint32_t flash_base = 0; uint32_t dhcsr, dfsr, cfsr, hfsr; - DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); + DLOG("Running flash loader, write address:%#x, size: %u\n", target, (uint32_t)size); if (write_buffer_to_sram(sl, fl, buf, size) == -1) { ELOG("write_buffer_to_sram() == -1\n"); @@ -423,15 +424,15 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 -int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, +int32_t stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint32_t pagesize) { - unsigned int count, off; - unsigned int num_half_pages = len / pagesize; + uint32_t count, off; + uint32_t num_half_pages = len / pagesize; uint32_t val; uint32_t flash_regs_base = get_stm32l0_flash_base(sl); flash_loader_t fl; bool use_loader = true; - int ret = 0; + int32_t ret = 0; // enable half page write stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -483,7 +484,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, return (ret); } -static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { +static void set_flash_cr_pg(stlink_t *sl, uint32_t bank) { uint32_t cr_reg, x; x = read_flash_cr(sl, bank); @@ -519,7 +520,7 @@ static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { stlink_write_debug32(sl, cr_reg, x); } -static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { +static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int32_t bckpRstr) { uint32_t rcc, rcc_dma_mask, value; rcc = rcc_dma_mask = value = 0; @@ -580,7 +581,7 @@ static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { } } -int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { +int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { // disable DMA set_dma_state(sl, fl, 0); @@ -602,7 +603,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { unlock_flash_if(sl); // first unlock the cr - int voltage; + int32_t voltage; if (sl->version.stlink_v == 1) { WLOG("STLINK V1 cannot read voltage, use default voltage 3.2V\n"); voltage = 3200; @@ -721,7 +722,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { return (0); } -int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, +int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t *base, uint32_t len) { size_t off; if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || @@ -733,7 +734,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", - (unsigned)(addr + off)); + (uint32_t)(addr + off)); check_flash_error(sl); return (-1); } @@ -744,14 +745,14 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4 || sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); + DLOG("Starting %3u page write\r\n", (uint32_t)(len / sl->flash_pgsz)); for (off = 0; off < len; off += sizeof(uint32_t)) { uint32_t data; if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off / sl->flash_pgsz + 1), - (unsigned int)(len / sl->flash_pgsz)); + (uint32_t)(off / sl->flash_pgsz + 1), + (uint32_t)(len / sl->flash_pgsz)); fflush(stdout); } @@ -773,7 +774,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, uint32_t pagesize = (flash_regs_base == FLASH_L0_REGS_ADDR)? L0_WRITE_BLOCK_SIZE:L1_WRITE_BLOCK_SIZE; - DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); + DLOG("Starting %3u page write\r\n", (uint32_t)(len / sl->flash_pgsz)); off = 0; @@ -791,8 +792,8 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off / sl->flash_pgsz + 1), - (unsigned int)(len / sl->flash_pgsz)); + (uint32_t)(off / sl->flash_pgsz + 1), + (uint32_t)(len / sl->flash_pgsz)); fflush(stdout); } @@ -809,7 +810,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, fprintf(stdout, "\n"); } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { - int write_block_count = 0; + int32_t write_block_count = 0; for (off = 0; off < len; off += sl->flash_pgsz) { // adjust last write size size_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; @@ -822,7 +823,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", - (unsigned)(addr + off)); + (uint32_t)(addr + off)); check_flash_error(sl); return (-1); } @@ -833,7 +834,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, // show progress; writing procedure is slow and previous errors are // misleading fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, - (unsigned int)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); + (uint32_t)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); fflush(stdout); } } @@ -852,8 +853,8 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, if (sl->verbose >= 1) { // show progress - fprintf(stdout, "\r%u/%u bytes written", (unsigned int)off, - (unsigned int)len); + fprintf(stdout, "\r%u/%u bytes written", (uint32_t)off, + (uint32_t)len); fflush(stdout); } } @@ -867,7 +868,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, return check_flash_error(sl); } -int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { +int32_t stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { uint32_t dhcsr; if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || diff --git a/src/stlink-lib/flash_loader.h b/src/stlink-lib/flash_loader.h index 51448395f..5b7b0945d 100644 --- a/src/stlink-lib/flash_loader.h +++ b/src/stlink-lib/flash_loader.h @@ -7,18 +7,18 @@ #ifndef FLASH_LOADER_H #define FLASH_LOADER_H -#include #include +#include #include #include -int stlink_flash_loader_init(stlink_t *sl, flash_loader_t* fl); -int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); -int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size); +int32_t stlink_flash_loader_init(stlink_t *sl, flash_loader_t* fl); +int32_t stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); +int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size); -int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); -int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len); -int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl); +int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); +int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len); +int32_t stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl); #endif // FLASH_LOADER_H diff --git a/src/stlink-lib/helper.c b/src/stlink-lib/helper.c index 15e6397bf..a6155925f 100644 --- a/src/stlink-lib/helper.c +++ b/src/stlink-lib/helper.c @@ -1,23 +1,24 @@ -#include - #include +#include #include +#include "helper.h" + #ifdef STLINK_HAVE_SYS_TIME_H #include #else #include #endif -unsigned time_ms() { +uint32_t time_ms() { struct timeval tv; gettimeofday(&tv, NULL); - return (unsigned)(tv.tv_sec * 1000 + tv.tv_usec / 1000); + return (uint32_t)(tv.tv_sec * 1000 + tv.tv_usec / 1000); } -int arg_parse_freq(const char *str) { +int32_t arg_parse_freq(const char *str) { char *tail; - int value = (int)strtol(str, &tail, 10); + int32_t value = (int32_t)strtol(str, &tail, 10); if (tail[0] == 'M' && tail[1] == '\0') { value = value*1000; diff --git a/src/stlink-lib/helper.h b/src/stlink-lib/helper.h index cf45bbf43..dbd760a52 100644 --- a/src/stlink-lib/helper.h +++ b/src/stlink-lib/helper.h @@ -1,8 +1,10 @@ #ifndef HELPER_H #define HELPER_H -unsigned time_ms(); +#include -int arg_parse_freq(const char *str); +uint32_t time_ms(); + +int32_t arg_parse_freq(const char *str); #endif // HELPER_H diff --git a/src/stlink-lib/logging.c b/src/stlink-lib/logging.c index 79924fc20..a64ec4ef2 100644 --- a/src/stlink-lib/logging.c +++ b/src/stlink-lib/logging.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #define __STDC_WANT_LIB_EXT1__ 1 @@ -14,14 +15,14 @@ #include "logging.h" -static int max_level = UDEBUG; +static int32_t max_level = UDEBUG; -int ugly_init(int maximum_threshold) { +int32_t ugly_init(int32_t maximum_threshold) { max_level = maximum_threshold; return (0); } -int ugly_log(int level, const char *tag, const char *format, ...) { +int32_t ugly_log(int32_t level, const char *tag, const char *format, ...) { if (level > max_level) { return (0); } @@ -84,7 +85,7 @@ int ugly_log(int level, const char *tag, const char *format, ...) { * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are * printed to stderr */ -int ugly_libusb_log_level(enum ugly_loglevel v) { +int32_t ugly_libusb_log_level(enum ugly_loglevel v) { #ifdef __FreeBSD__ // FreeBSD includes its own reimplementation of libusb. // Its libusb_set_debug() function expects a lib_debug_level diff --git a/src/stlink-lib/logging.h b/src/stlink-lib/logging.h index 893a02c24..471933096 100644 --- a/src/stlink-lib/logging.h +++ b/src/stlink-lib/logging.h @@ -5,6 +5,8 @@ #ifndef LOGGING_H #define LOGGING_H +#include + #ifdef __cplusplus extern "C" { #endif @@ -22,9 +24,9 @@ enum ugly_loglevel { #define PRINTF_ARRT #endif -int ugly_init(int maximum_threshold); -int ugly_log(int level, const char *tag, const char *format, ...) PRINTF_ARRT; -int ugly_libusb_log_level(enum ugly_loglevel v); +int32_t ugly_init(int32_t maximum_threshold); +int32_t ugly_log(int32_t level, const char *tag, const char *format, ...) PRINTF_ARRT; +int32_t ugly_libusb_log_level(enum ugly_loglevel v); #define UGLY_LOG_FILE (strstr(__FILE__, "/") != NULL ? \ strrchr(__FILE__, '/') + 1 : strstr(__FILE__, "\\") != NULL ? \ diff --git a/src/stlink-lib/map_file.c b/src/stlink-lib/map_file.c index 3bb7555d5..bb83ff7be 100644 --- a/src/stlink-lib/map_file.c +++ b/src/stlink-lib/map_file.c @@ -1,11 +1,12 @@ #include -#include -#include +#include #include -#include -#include +#include +#include +#include "logging.h" #include "map_file.h" +#include "md5.h" #ifndef O_BINARY #define O_BINARY 0 @@ -15,11 +16,11 @@ #define MAX_FILE_SIZE (1<<20) // 1 GB max file size #endif -int map_file(mapped_file_t *mf, const char *path) { - int error = -1; +int32_t map_file(mapped_file_t *mf, const char *path) { + int32_t error = -1; struct stat st; - const int fd = open(path, O_RDONLY | O_BINARY); + const int32_t fd = open(path, O_RDONLY | O_BINARY); if (fd == -1) { fprintf(stderr, "open(%s) == -1\n", path); diff --git a/src/stlink-lib/map_file.h b/src/stlink-lib/map_file.h index f50a201f0..b33ebf5db 100644 --- a/src/stlink-lib/map_file.h +++ b/src/stlink-lib/map_file.h @@ -7,6 +7,8 @@ #ifndef MAP_FILE_H #define MAP_FILE_H +#include + #ifndef O_BINARY #define O_BINARY 0 #endif @@ -26,7 +28,7 @@ typedef struct mapped_file { #define MAPPED_FILE_INITIALIZER \ { NULL, 0 } -int map_file(mapped_file_t *, const char *); +int32_t map_file(mapped_file_t *, const char *); void unmap_file(mapped_file_t *); #endif // MAP_FILE_H diff --git a/src/stlink-lib/md5.c b/src/stlink-lib/md5.c index 4c353bfd6..19ec86b91 100644 --- a/src/stlink-lib/md5.c +++ b/src/stlink-lib/md5.c @@ -5,6 +5,7 @@ * This is free and unencumbered software released into the public domain - June 2013 - waterjuice.org */ +#include #include #include "md5.h" @@ -205,7 +206,7 @@ void Md5Update(Md5Context* Context /* [in out] */, void const* Buffer /* [in] */ } if ( BufferSize >= 64 ) { - Buffer = TransformFunction( Context, Buffer, BufferSize & ~(unsigned long)0x3f ); + Buffer = TransformFunction( Context, Buffer, BufferSize & ~(uint32_t)0x3f ); BufferSize &= 0x3f; } diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c index f5932a7b9..e2d966b7a 100644 --- a/src/stlink-lib/option_bytes.c +++ b/src/stlink-lib/option_bytes.c @@ -1,10 +1,12 @@ +#include #include #include + #include -#include "option_bytes.h" +#include "common.h" #include "common_flash.h" #include "map_file.h" -#include "common.h" +#include "option_bytes.h" /** @@ -13,7 +15,7 @@ * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_f0(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_control_register_f0(stlink_t *sl, uint32_t *option_byte) { DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_OBR); return stlink_read_debug32(sl, FLASH_OBR, option_byte); } @@ -26,8 +28,8 @@ int stlink_read_option_control_register_f0(stlink_t *sl, uint32_t *option_byte) * @param len of option bytes * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f0(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { - int ret = 0; +static int32_t stlink_write_option_bytes_f0(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { + int32_t ret = 0; if (len < 12 || addr != STM32_F0_OPTION_BYTES_BASE) { WLOG("Only full write of option bytes area is supported\n"); @@ -81,12 +83,12 @@ static int stlink_write_option_bytes_f0(stlink_t *sl, stm32_addr_t addr, uint8_t * @param option_cr * @return 0 on success, -ve on failure. */ -static int stlink_write_option_control_register_f0(stlink_t *sl, uint32_t option_cr) { - int ret = 0; +static int32_t stlink_write_option_control_register_f0(stlink_t *sl, uint32_t option_cr) { + int32_t ret = 0; uint16_t opt_val[8]; - unsigned protection, optiondata; + uint32_t protection, optiondata; uint16_t user_options, user_data, rdp; - unsigned option_offset, user_data_offset; + uint32_t option_offset, user_data_offset; ILOG("Asked to write option control register %#10x to %#010x.\n", option_cr, FLASH_OBR); @@ -166,7 +168,7 @@ static int stlink_write_option_control_register_f0(stlink_t *sl, uint32_t option * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_f2(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_control_register_f2(stlink_t *sl, uint32_t *option_byte) { return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); } @@ -176,7 +178,7 @@ int stlink_read_option_control_register_f2(stlink_t *sl, uint32_t *option_byte) * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_bytes_f2(stlink_t *sl, uint32_t *option_byte) { return stlink_read_option_control_register_f2(sl, option_byte); } @@ -186,7 +188,7 @@ int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t *option_byte) { * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_f4(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_control_register_f4(stlink_t *sl, uint32_t *option_byte) { return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); } @@ -196,7 +198,7 @@ int stlink_read_option_control_register_f4(stlink_t *sl, uint32_t *option_byte) * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_bytes_f4(stlink_t *sl, uint32_t *option_byte) { return stlink_read_option_control_register_f4(sl, option_byte); } @@ -208,9 +210,9 @@ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t *option_byte) { * @param len of option bytes * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f4(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { +static int32_t stlink_write_option_bytes_f4(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { uint32_t option_byte; - int ret = 0; + int32_t ret = 0; (void)addr; (void)len; @@ -237,10 +239,10 @@ static int stlink_write_option_bytes_f4(stlink_t *sl, stm32_addr_t addr, uint8_t * @param option_byte * @return 0 on success, -ve on failure. */ -// Since multiple bytes can be read, we read and print all, but one here +// Since multiple bytes can be read, we read and print32_t all, but one here // and then return the last one just like other devices. -int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t *option_byte) { - int err = -1; +int32_t stlink_read_option_bytes_f7(stlink_t *sl, uint32_t *option_byte) { + int32_t err = -1; for (uint32_t counter = 0; counter < (sl->option_size / 4 - 1); counter++) { err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), option_byte); if (err == -1) { @@ -264,9 +266,9 @@ int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t *option_byte) { * @param len of option bytes * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f7(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { +static int32_t stlink_write_option_bytes_f7(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { uint32_t option_byte; - int ret = 0; + int32_t ret = 0; // Clear errors clear_flash_error(sl); @@ -317,7 +319,7 @@ static int stlink_write_option_bytes_f7(stlink_t *sl, stm32_addr_t addr, uint8_t * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_f7(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_control_register_f7(stlink_t *sl, uint32_t *option_byte) { DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_F7_OPTCR); return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte); } @@ -328,8 +330,8 @@ int stlink_read_option_control_register_f7(stlink_t *sl, uint32_t *option_byte) * @param option_cr * @return 0 on success, -ve on failure. */ -static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option_cr) { - int ret = 0; +static int32_t stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option_cr) { + int32_t ret = 0; // Clear errors clear_flash_error(sl); @@ -358,7 +360,7 @@ static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register1_f7(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_control_register1_f7(stlink_t *sl, uint32_t *option_byte) { DLOG("@@@@ Read option control register 1 byte from %#10x\n", FLASH_F7_OPTCR1); return stlink_read_debug32(sl, FLASH_F7_OPTCR1, option_byte); @@ -370,8 +372,8 @@ int stlink_read_option_control_register1_f7(stlink_t *sl, uint32_t *option_byte) * @param option_cr1 * @return 0 on success, -ve on failure. */ -static int stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t option_cr1) { - int ret = 0; +static int32_t stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t option_cr1) { + int32_t ret = 0; // Clear errors clear_flash_error(sl); @@ -405,7 +407,7 @@ static int stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t optio * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t *option_byte) { DLOG("@@@@ Read option byte boot address\n"); return stlink_read_option_control_register1_f7(sl, option_byte); } @@ -428,7 +430,7 @@ stlink_write_option_bytes_boot_add_f7(stlink_t *sl, uint32_t option_byte_boot_ad * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_gx(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_control_register_gx(stlink_t *sl, uint32_t *option_byte) { return stlink_read_debug32(sl, FLASH_Gx_OPTR, option_byte); } @@ -438,7 +440,7 @@ int stlink_read_option_control_register_gx(stlink_t *sl, uint32_t *option_byte) * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_gx(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_bytes_gx(stlink_t *sl, uint32_t *option_byte) { return stlink_read_option_control_register_gx(sl, option_byte); } @@ -450,10 +452,10 @@ int stlink_read_option_bytes_gx(stlink_t *sl, uint32_t *option_byte) { * @param len of option bytes * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_gx(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { +static int32_t stlink_write_option_bytes_gx(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { /* Write options bytes */ uint32_t val; - int ret = 0; + int32_t ret = 0; (void)len; uint32_t data; @@ -488,7 +490,7 @@ static int stlink_write_option_bytes_gx(stlink_t *sl, stm32_addr_t addr, uint8_t * @param len of option bytes * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_h7(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { +static int32_t stlink_write_option_bytes_h7(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { uint32_t val; uint32_t data; @@ -556,11 +558,11 @@ static int stlink_write_option_bytes_h7(stlink_t *sl, stm32_addr_t addr, uint8_t * @param len of option bytes * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l0(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { +static int32_t stlink_write_option_bytes_l0(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { uint32_t flash_base = get_stm32l0_flash_base(sl); uint32_t val; uint32_t data; - int ret = 0; + int32_t ret = 0; // Clear errors clear_flash_error(sl); @@ -598,10 +600,10 @@ static int stlink_write_option_bytes_l0(stlink_t *sl, stm32_addr_t addr, uint8_t * @param len of option bytes * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l4(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { +static int32_t stlink_write_option_bytes_l4(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { uint32_t val; - int ret = 0; + int32_t ret = 0; (void)addr; (void)len; @@ -638,10 +640,10 @@ static int stlink_write_option_bytes_l4(stlink_t *sl, stm32_addr_t addr, uint8_t * @param len of option bytes * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_wb(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { +static int32_t stlink_write_option_bytes_wb(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { /* Write options bytes */ uint32_t val; - int ret = 0; + int32_t ret = 0; (void)len; uint32_t data; @@ -686,7 +688,7 @@ static int stlink_write_option_bytes_wb(stlink_t *sl, stm32_addr_t addr, uint8_t * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_wb(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_control_register_wb(stlink_t *sl, uint32_t *option_byte) { DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_WB_OPTR); return stlink_read_debug32(sl, FLASH_WB_OPTR, option_byte); } @@ -697,8 +699,8 @@ int stlink_read_option_control_register_wb(stlink_t *sl, uint32_t *option_byte) * @param option_cr * @return 0 on success, -ve on failure. */ -static int stlink_write_option_control_register_wb(stlink_t *sl, uint32_t option_cr) { - int ret = 0; +static int32_t stlink_write_option_control_register_wb(stlink_t *sl, uint32_t option_cr) { + int32_t ret = 0; // Clear errors clear_flash_error(sl); @@ -730,7 +732,7 @@ static int stlink_write_option_control_register_wb(stlink_t *sl, uint32_t option * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte) { DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); return stlink_read_debug32(sl, sl->option_base, option_byte); } @@ -744,8 +746,8 @@ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte) { * @param len of option bytes * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { - int ret = -1; +int32_t stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { + int32_t ret = -1; if (sl->option_base == 0) { ELOG("Option bytes writing is currently not supported for connected chip\n"); @@ -826,9 +828,9 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, ui * @param addr of the memory mapped option bytes * @return 0 on success, -ve on failure. */ -int stlink_fwrite_option_bytes(stlink_t *sl, const char *path, stm32_addr_t addr) { +int32_t stlink_fwrite_option_bytes(stlink_t *sl, const char *path, stm32_addr_t addr) { /* Write the file in flash at addr */ - int err; + int32_t err; mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { @@ -853,7 +855,7 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char *path, stm32_addr_t addr * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { if (sl->option_base == 0) { ELOG("Option bytes read is currently not supported for connected chip\n"); return -1; @@ -878,8 +880,8 @@ int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { * @param option_cr * @return 0 on success, -ve on failure. */ -int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_cr) { - int ret = -1; +int32_t stlink_write_option_control_register32(stlink_t *sl, uint32_t option_cr) { + int32_t ret = -1; wait_flash_busy(sl); @@ -928,7 +930,7 @@ int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_cr) { * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register1_32(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_control_register1_32(stlink_t *sl, uint32_t *option_byte) { if (sl->option_base == 0) { ELOG("Option bytes read is currently not supported for connected chip\n"); return -1; @@ -949,8 +951,8 @@ int stlink_read_option_control_register1_32(stlink_t *sl, uint32_t *option_byte) * @param option_cr * @return 0 on success, -ve on failure. */ -int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_cr1) { - int ret = -1; +int32_t stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_cr1) { + int32_t ret = -1; wait_flash_busy(sl); @@ -992,7 +994,7 @@ int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_cr1) * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { if (sl->option_base == 0) { ELOG("Option bytes read is currently not supported for connected chip\n"); return (-1); @@ -1022,7 +1024,7 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { +int32_t stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { WLOG("About to write option byte %#10x to %#10x.\n", option_byte, sl->option_base); return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *)&option_byte, 4); @@ -1034,7 +1036,7 @@ int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { * @param option_byte * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { +int32_t stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { if (sl->option_base == 0) { ELOG("Option bytes boot address read is currently not supported for connected chip\n"); return -1; @@ -1055,8 +1057,8 @@ int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { * @param option_bytes_boot_add * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add) { - int ret = -1; +int32_t stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add) { + int32_t ret = -1; wait_flash_busy(sl); diff --git a/src/stlink-lib/option_bytes.h b/src/stlink-lib/option_bytes.h index 9c81fba8a..c0a1c9a6d 100644 --- a/src/stlink-lib/option_bytes.h +++ b/src/stlink-lib/option_bytes.h @@ -7,20 +7,22 @@ #ifndef OPTION_BYTES_H #define OPTION_BYTES_H +#include #include + #include -int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); -int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte); -int stlink_read_option_control_register32(stlink_t *sl, uint32_t* option_byte); -int stlink_read_option_control_register1_32(stlink_t *sl, uint32_t* option_byte); +int32_t stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); +int32_t stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte); +int32_t stlink_read_option_control_register32(stlink_t *sl, uint32_t* option_byte); +int32_t stlink_read_option_control_register1_32(stlink_t *sl, uint32_t* option_byte); -int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); -int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add); -int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_cr); -int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_cr1); +int32_t stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); +int32_t stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add); +int32_t stlink_write_option_control_register32(stlink_t *sl, uint32_t option_cr); +int32_t stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_cr1); -int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); -int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); +int32_t stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); +int32_t stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); #endif // OPTION_BYTES_H \ No newline at end of file diff --git a/src/stlink-lib/read_write.c b/src/stlink-lib/read_write.c index efaa5a25f..f9c060bb2 100644 --- a/src/stlink-lib/read_write.c +++ b/src/stlink-lib/read_write.c @@ -1,5 +1,7 @@ +#include #include #include + #include // Endianness @@ -18,17 +20,17 @@ void write_uint16(unsigned char *buf, uint16_t ui) { buf[1] = (uint8_t)(ui >> 8); } -uint32_t read_uint32(const unsigned char *c, const int pt) { +uint32_t read_uint32(const unsigned char *c, const int32_t pt) { return ((uint32_t)c[pt]) | ((uint32_t)c[pt + 1] << 8) | ((uint32_t)c[pt + 2] << 16) | ((uint32_t)c[pt + 3] << 24); } -uint16_t read_uint16(const unsigned char *c, const int pt) { +uint16_t read_uint16(const unsigned char *c, const int32_t pt) { return ((uint16_t)c[pt]) | ((uint16_t)c[pt + 1] << 8); } -int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { - int ret; +int32_t stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { + int32_t ret; ret = sl->backend->read_debug32(sl, addr, data); if (!ret) @@ -37,12 +39,12 @@ int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { return (ret); } -int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { +int32_t stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { DLOG("*** stlink_write_debug32 %#010x to %#010x\n", data, addr); return sl->backend->write_debug32(sl, addr, data); } -int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int32_t stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); if (len % 4 != 0) { @@ -53,7 +55,7 @@ int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { return (sl->backend->write_mem32(sl, addr, len)); } -int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int32_t stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_read_mem32 ***\n"); if (len % 4 != 0) { // !!! never ever: fw gives just wrong values @@ -64,27 +66,27 @@ int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { return (sl->backend->read_mem32(sl, addr, len)); } -int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { +int32_t stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem8 ***\n"); return (sl->backend->write_mem8(sl, addr, len)); } -int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { +int32_t stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { DLOG("*** stlink_read_all_regs ***\n"); return (sl->backend->read_all_regs(sl, regp)); } -int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { +int32_t stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { DLOG("*** stlink_read_all_unsupported_regs ***\n"); return (sl->backend->read_all_unsupported_regs(sl, regp)); } -int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) { +int32_t stlink_write_reg(stlink_t *sl, uint32_t reg, int32_t idx) { DLOG("*** stlink_write_reg\n"); return (sl->backend->write_reg(sl, reg, idx)); } -int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { +int32_t stlink_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp) { DLOG("*** stlink_read_reg\n"); DLOG(" (%d) ***\n", r_idx); @@ -96,9 +98,9 @@ int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { return (sl->backend->read_reg(sl, r_idx, regp)); } -int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, +int32_t stlink_read_unsupported_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp) { - int r_convert; + int32_t r_convert; DLOG("*** stlink_read_unsupported_reg\n"); DLOG(" (%d) ***\n", r_idx); @@ -119,9 +121,9 @@ int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, return (sl->backend->read_unsupported_reg(sl, r_convert, regp)); } -int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, +int32_t stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int32_t r_idx, struct stlink_reg *regp) { - int r_convert; + int32_t r_convert; DLOG("*** stlink_write_unsupported_reg\n"); DLOG(" (%d) ***\n", r_idx); diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index feab40c13..c0f79c7cf 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -75,10 +75,12 @@ */ #define __USE_GNU + #include +#include #include -#include #include +#include #include #include @@ -109,12 +111,12 @@ void _stlink_sg_close(stlink_t *sl) { } } -static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t endpoint, uint32_t *tag) { +static int32_t get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t endpoint, uint32_t *tag) { unsigned char csw[13]; memset(csw, 0, sizeof(csw)); - int transferred; - int ret; - int try = 0; + int32_t transferred; + int32_t ret; + int32_t try = 0; do { ret = libusb_bulk_transfer(handle, endpoint, (unsigned char *)&csw, sizeof(csw), @@ -150,13 +152,13 @@ static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t end return(rstatus); } -static int dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) { +static int32_t dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) { char dbugblah[100]; char *dbugp = dbugblah; dbugp += sprintf(dbugp, "Sending CDB ["); for (uint8_t i = 0; i < cdb_len; i++) { - dbugp += sprintf(dbugp, " %#02x", (unsigned int)cdb[i]); + dbugp += sprintf(dbugp, " %#02x", (uint32_t)cdb[i]); } sprintf(dbugp, "]\n"); @@ -175,7 +177,7 @@ static int dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) { * @param expected_rx_size * @return */ -int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint_out, +int32_t send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint_out, uint8_t *cdb, uint8_t cdb_length, uint8_t lun, uint8_t flags, uint32_t expected_rx_size) { DLOG("Sending usb m-s cmd: cdblen:%d, rxsize=%d\n", cdb_length, expected_rx_size); @@ -185,10 +187,10 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint if (tag == 0) { tag = 1; } - int try = 0; - int ret = 0; - int real_transferred; - int i = 0; + int32_t try = 0; + int32_t ret = 0; + int32_t real_transferred; + int32_t i = 0; uint8_t c_buf[STLINK_SG_SIZE]; // tag is allegedly ignored... TODO - verify @@ -209,7 +211,7 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint assert(cdb_length <= CDB_SL); memcpy(&(c_buf[i]), cdb, cdb_length); - int sending_length = STLINK_SG_SIZE; + int32_t sending_length = STLINK_SG_SIZE; // send.... do { @@ -254,9 +256,9 @@ static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t } unsigned char sense[REQUEST_SENSE_LENGTH]; - int transferred; - int ret; - int try = 0; + int32_t transferred; + int32_t ret; + int32_t try = 0; do { ret = libusb_bulk_transfer(handle, endpoint_in, sense, sizeof(sense), @@ -273,11 +275,11 @@ static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t } if (transferred != sizeof(sense)) { - WLOG("received unexpected amount of sense: %d != %u\n", transferred, (unsigned)sizeof(sense)); + WLOG("received unexpected amount of sense: %d != %u\n", transferred, (uint32_t)sizeof(sense)); } uint32_t received_tag; - int status = get_usb_mass_storage_status(handle, endpoint_in, &received_tag); + int32_t status = get_usb_mass_storage_status(handle, endpoint_in, &received_tag); if (status != 0) { WLOG("receiving sense failed with status: %02x\n", status); @@ -301,11 +303,11 @@ static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t * @param length how much to send * @return number of bytes actually sent, or -1 for failures. */ -int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, - unsigned char endpoint_in, unsigned char *cbuf, unsigned int length) { - int ret; - int real_transferred; - int try = 0; +int32_t send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, + unsigned char endpoint_in, unsigned char *cbuf, uint32_t length) { + int32_t ret; + int32_t real_transferred; + int32_t try = 0; do { ret = libusb_bulk_transfer(handle, endpoint_out, cbuf, length, @@ -324,7 +326,7 @@ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, // now, swallow up the status, so that things behave nicely... uint32_t received_tag; // -ve is for my errors, 0 is good, +ve is libusb sense status bytes - int status = get_usb_mass_storage_status(handle, endpoint_in, &received_tag); + int32_t status = get_usb_mass_storage_status(handle, endpoint_in, &received_tag); if (status < 0) { WLOG("receiving status failed: %d\n", status); @@ -343,7 +345,7 @@ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, return(real_transferred); } -int stlink_q(stlink_t *sl) { +int32_t stlink_q(stlink_t *sl) { struct stlink_libsg* sg = sl->backend_data; // uint8_t cdb_len = 6; // FIXME varies!!! uint8_t cdb_len = 10; // FIXME varies!!! @@ -355,10 +357,10 @@ int stlink_q(stlink_t *sl) { // now wait for our response... // length copied from stlink-usb... - int rx_length = sl->q_len; - int try = 0; - int real_transferred; - int ret; + int32_t rx_length = sl->q_len; + int32_t try = 0; + int32_t real_transferred; + int32_t ret; if (rx_length > 0) { do { @@ -382,7 +384,7 @@ int stlink_q(stlink_t *sl) { uint32_t received_tag; // -ve is for my errors, 0 is good, +ve is libusb sense status bytes - int status = get_usb_mass_storage_status(sg->usb_handle, sg->ep_rep, &received_tag); + int32_t status = get_usb_mass_storage_status(sg->usb_handle, sg->ep_rep, &received_tag); if (status < 0) { WLOG("receiving status failed: %d\n", status); @@ -428,7 +430,7 @@ void stlink_stat(stlink_t *stl, char *txt) { } } -int _stlink_sg_version(stlink_t *stl) { +int32_t _stlink_sg_version(stlink_t *stl) { struct stlink_libsg *sl = stl->backend_data; clear_cdb(sl); sl->cdb_cmd_blk[0] = STLINK_GET_VERSION; @@ -440,7 +442,7 @@ int _stlink_sg_version(stlink_t *stl) { // Get stlink mode: // STLINK_DEV_DFU_MODE || STLINK_DEV_MASS_MODE || STLINK_DEV_DEBUG_MODE // usb dfu || usb mass || jtag or swd -int _stlink_sg_current_mode(stlink_t *stl) { +int32_t _stlink_sg_current_mode(stlink_t *stl) { struct stlink_libsg *sl = stl->backend_data; clear_cdb(sl); sl->cdb_cmd_blk[0] = STLINK_GET_CURRENT_MODE; @@ -453,7 +455,7 @@ int _stlink_sg_current_mode(stlink_t *stl) { } // exit the mass mode and enter the swd debug mode. -int _stlink_sg_enter_swd_mode(stlink_t *sl) { +int32_t _stlink_sg_enter_swd_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_ENTER; @@ -464,7 +466,7 @@ int _stlink_sg_enter_swd_mode(stlink_t *sl) { // exit the mass mode and enter the jtag debug mode. // (jtag is disabled in the discovery's stlink firmware) -int _stlink_sg_enter_jtag_mode(stlink_t *sl) { +int32_t _stlink_sg_enter_jtag_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_enter_jtag_mode ***\n"); clear_cdb(sg); @@ -476,7 +478,7 @@ int _stlink_sg_enter_jtag_mode(stlink_t *sl) { // XXX kernel driver performs reset, the device temporally disappears // Suspect this is no longer the case when we have ignore on? RECHECK -int _stlink_sg_exit_dfu_mode(stlink_t *sl) { +int32_t _stlink_sg_exit_dfu_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_exit_dfu_mode ***\n"); clear_cdb(sg); @@ -529,9 +531,9 @@ int _stlink_sg_exit_dfu_mode(stlink_t *sl) { */ } -int _stlink_sg_core_id(stlink_t *sl) { +int32_t _stlink_sg_core_id(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; - int ret; + int32_t ret; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READCOREID; sl->q_len = 4; @@ -545,7 +547,7 @@ int _stlink_sg_core_id(stlink_t *sl) { } // arm-core reset -> halted state. -int _stlink_sg_reset(stlink_t *sl) { +int32_t _stlink_sg_reset(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_RESETSYS; @@ -566,7 +568,7 @@ int _stlink_sg_reset(stlink_t *sl) { } // arm-core reset -> halted state. -int _stlink_sg_jtag_reset(stlink_t *sl, int value) { +int32_t _stlink_sg_jtag_reset(stlink_t *sl, int32_t value) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV2_DRIVE_NRST; @@ -582,7 +584,7 @@ int _stlink_sg_jtag_reset(stlink_t *sl, int value) { } // arm-core status: halted or running. -int _stlink_sg_status(stlink_t *sl) { +int32_t _stlink_sg_status(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_GETSTATUS; @@ -592,7 +594,7 @@ int _stlink_sg_status(stlink_t *sl) { } // force the core into the debug mode -> halted state. -int _stlink_sg_force_debug(stlink_t *sl) { +int32_t _stlink_sg_force_debug(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_FORCEDEBUG; @@ -606,7 +608,7 @@ int _stlink_sg_force_debug(stlink_t *sl) { } // read all arm-core registers. -int _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { +int32_t _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -622,7 +624,7 @@ int _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71 | 72-75 | 76-79 | 80-83 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 - for (int i = 0; i < 16; i++) { + for (int32_t i = 0; i < 16; i++) { regp->r[i] = read_uint32(sl->q_buf, 4 * i); if (sl->verbose > 1) { DLOG("r%2d = 0x%08x\n", i, regp->r[i]); } @@ -649,7 +651,7 @@ int _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 -int _stlink_sg_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { +int32_t _stlink_sg_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_READREG; @@ -694,7 +696,7 @@ int _stlink_sg_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 -int _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) { +int32_t _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int32_t idx) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_WRITEREG; @@ -730,7 +732,7 @@ void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { } // force the core exit the debug mode. -int _stlink_sg_run(stlink_t *sl, enum run_type type) { +int32_t _stlink_sg_run(stlink_t *sl, enum run_type type) { struct stlink_libsg *sg = sl->backend_data; (void)(type); //unused clear_cdb(sg); @@ -746,7 +748,7 @@ int _stlink_sg_run(stlink_t *sl, enum run_type type) { } // step the arm-core. -int _stlink_sg_step(stlink_t *sl) { +int32_t _stlink_sg_step(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_STEPCORE; @@ -761,7 +763,7 @@ int _stlink_sg_step(stlink_t *sl) { // TODO: test and make delegate! // see Cortex-M3 Technical Reference Manual -void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) { +void stlink_set_hw_bp(stlink_t *sl, int32_t fp_nr, uint32_t addr, int32_t fp) { DLOG("\n*** stlink_set_hw_bp ***\n"); struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); @@ -779,7 +781,7 @@ void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) { } // TODO: test and make delegate! -void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) { +void stlink_clr_hw_bp(stlink_t *sl, int32_t fp_nr) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_clr_hw_bp ***\n"); clear_cdb(sg); @@ -792,7 +794,7 @@ void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) { } // read a "len" bytes to the sl->q_buf from the memory, max 6kB (6144 bytes) -int _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int32_t _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READMEM_32BIT; @@ -816,9 +818,9 @@ int _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { } // write a "len" bytes from the sl->q_buf to the memory, max 64 Bytes. -int _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { +int32_t _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; - int ret; + int32_t ret; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEMEM_8BIT; @@ -844,9 +846,9 @@ int _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { } // write a "len" bytes from the sl->q_buf to the memory, max Q_BUF_LEN bytes. -int _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int32_t _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; - int ret; + int32_t ret; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEMEM_32BIT; @@ -872,7 +874,7 @@ int _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { } // write one DWORD data to memory -int _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { +int32_t _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV2_WRITEDEBUGREG; @@ -884,7 +886,7 @@ int _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { } // read one DWORD data from memory -int _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { +int32_t _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV2_READDEBUGREG; @@ -899,7 +901,7 @@ int _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { } // exit the jtag or swd mode and enter the mass mode. -int _stlink_sg_exit_debug_mode(stlink_t *stl) { +int32_t _stlink_sg_exit_debug_mode(stlink_t *stl) { if (stl) { struct stlink_libsg* sl = stl->backend_data; clear_cdb(sl); @@ -950,7 +952,7 @@ static stlink_backend_t _stlink_sg_backend = { NULL, // trace_read }; -static stlink_t* stlink_open(const int verbose) { +static stlink_t* stlink_open(const int32_t verbose) { stlink_t *sl = malloc(sizeof(stlink_t)); struct stlink_libsg *slsg = malloc(sizeof(struct stlink_libsg)); @@ -993,7 +995,7 @@ static stlink_t* stlink_open(const int verbose) { // TODO: Could read the interface config descriptor, and assert lots of the assumptions // assumption: numInterfaces is always 1... if (libusb_kernel_driver_active(slsg->usb_handle, 0) == 1) { - int r = libusb_detach_kernel_driver(slsg->usb_handle, 0); + int32_t r = libusb_detach_kernel_driver(slsg->usb_handle, 0); if (r < 0) { WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-r)); @@ -1007,7 +1009,7 @@ static stlink_t* stlink_open(const int verbose) { DLOG("Kernel driver was successfully detached\n"); } - int config; + int32_t config; if (libusb_get_configuration(slsg->usb_handle, &config)) { /* this may fail for a previous configured device */ @@ -1062,7 +1064,7 @@ static stlink_t* stlink_open(const int verbose) { } -stlink_t* stlink_v1_open_inner(const int verbose) { +stlink_t* stlink_v1_open_inner(const int32_t verbose) { ugly_init(verbose); stlink_t *sl = stlink_open(verbose); @@ -1105,7 +1107,7 @@ stlink_t* stlink_v1_open_inner(const int verbose) { return(sl); } -stlink_t* stlink_v1_open(const int verbose, int reset) { +stlink_t* stlink_v1_open(const int32_t verbose, int32_t reset) { stlink_t *sl = stlink_v1_open_inner(verbose); if (sl == NULL) { return(NULL); } diff --git a/src/stlink-lib/sg.h b/src/stlink-lib/sg.h index 5ba809f59..d4792c49a 100644 --- a/src/stlink-lib/sg.h +++ b/src/stlink-lib/sg.h @@ -6,8 +6,10 @@ #ifndef SG_H #define SG_H +#include + #include -#include +#include "libusb_settings.h" /* Device access */ #define RDWR 0 @@ -35,15 +37,15 @@ struct stlink_libsg { libusb_context* libusb_ctx; libusb_device_handle *usb_handle; - unsigned ep_rep; - unsigned ep_req; + uint32_t ep_rep; + uint32_t ep_req; - int sg_fd; - int do_scsi_pt_err; + int32_t sg_fd; + int32_t do_scsi_pt_err; unsigned char cdb_cmd_blk[CDB_SL]; - int q_data_dir; // Q_DATA_IN, Q_DATA_OUT + int32_t q_data_dir; // Q_DATA_IN, Q_DATA_OUT // the start of the query data in the device memory space uint32_t q_addr; @@ -54,6 +56,6 @@ struct stlink_libsg { struct stlink_reg reg; }; -stlink_t* stlink_v1_open(const int verbose, int reset); +stlink_t* stlink_v1_open(const int32_t verbose, int32_t reset); #endif // SG_H diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 2e99e82be..d404c2e94 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1,8 +1,8 @@ +#include +#include #include #include #include -#include -#include #if !defined(_MSC_VER) #include @@ -17,7 +17,7 @@ #endif #include -#include +#include "helper.h" #include "usb.h" enum SCSI_Generic_Direction {SG_DXFER_TO_DEV = 0, SG_DXFER_FROM_DEV = 0x80}; @@ -26,11 +26,11 @@ static inline uint32_t le_to_h_u32(const uint8_t* buf) { return((uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24)); } -static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, uint32_t khz) { - unsigned int i; - int speed_index = -1; - int speed_diff = INT_MAX; - int last_valid_speed = -1; +static int32_t _stlink_match_speed_map(const uint32_t *map, uint32_t map_size, uint32_t khz) { + uint32_t i; + int32_t speed_index = -1; + int32_t speed_diff = INT_MAX; + int32_t last_valid_speed = -1; bool match = true; for (i = 0; i < map_size; i++) { @@ -42,7 +42,7 @@ static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, u speed_index = i; break; } else { - int current_diff = khz - map[i]; + int32_t current_diff = khz - map[i]; // get abs value for comparison current_diff = (current_diff > 0) ? current_diff : -current_diff; @@ -83,26 +83,26 @@ void _stlink_usb_close(stlink_t* sl) { } } -ssize_t send_recv(struct stlink_libusb* handle, int terminate, +ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char* txbuf, size_t txsize, unsigned char* rxbuf, - size_t rxsize, int check_error, const char *cmd) { + size_t rxsize, int32_t check_error, const char *cmd) { // Note: txbuf and rxbuf can point to the same area - int res, t, retry = 0; + int32_t res, t, retry = 0; while (1) { res = 0; - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, (int)txsize, &res, 3000); + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_req, txbuf, (int32_t)txsize, &res, 3000); if (t) { ELOG("%s send request failed: %s\n", cmd, libusb_error_name(t)); return(-1); } else if ((size_t)res != txsize) { ELOG("%s send request wrote %u bytes, instead of %u\n", - cmd, (unsigned int)res, (unsigned int)txsize); + cmd, (uint32_t)res, (uint32_t)txsize); } if (rxsize != 0) { - t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int)rxsize, &res, 3000); + t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, rxbuf, (int32_t)rxsize, &res, 3000); if (t) { ELOG("%s read reply failed: %s\n", cmd, libusb_error_name(t)); @@ -116,7 +116,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, case STLINK_DEBUG_ERR_AP_WAIT: case STLINK_DEBUG_ERR_DP_WAIT: if (check_error == CMD_CHECK_RETRY && retry < 3) { - unsigned int delay_us = (1<backend_data; unsigned char* const cmd = sl->c_buf; - int i = 0; + int32_t i = 0; memset(cmd, 0, sizeof(sl->c_buf)); if (slu->protocoll == 1) { @@ -189,13 +189,13 @@ static int fill_command(stlink_t * sl, enum SCSI_Generic_Direction dir, uint32_t return(i); } -int _stlink_usb_version(stlink_t *sl) { +int32_t _stlink_usb_version(stlink_t *sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t rep_len; - int i; + int32_t i; if (sl->version.stlink_v == 3) { // STLINK-V3 version is determined by another command @@ -219,9 +219,9 @@ int32_t _stlink_usb_target_voltage(stlink_t *sl) { unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t rep_len = 8; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); uint32_t factor, reading; - int voltage; + int32_t voltage; cmd[i++] = STLINK_GET_TARGET_VOLTAGE; @@ -238,14 +238,14 @@ int32_t _stlink_usb_target_voltage(stlink_t *sl) { return(voltage); } -int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { +int32_t _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const rdata = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; - const int rep_len = 8; + const int32_t rep_len = 8; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_READDEBUGREG; write_uint32(&cmd[i], addr); @@ -260,14 +260,14 @@ int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { return(0); } -int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { +int32_t _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const rdata = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; - const int rep_len = 2; + const int32_t rep_len = 2; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_WRITEDEBUGREG; write_uint32(&cmd[i], addr); @@ -277,13 +277,13 @@ int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { return(size<0?-1:0); } -int _stlink_usb_get_rw_status(stlink_t *sl) { +int32_t _stlink_usb_get_rw_status(stlink_t *sl) { if (sl->version.jtag_api == STLINK_JTAG_API_V1) { return(0); } unsigned char* const rdata = sl->q_buf; struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; - int i; + int32_t i; int16_t ret = 0; i = fill_command(sl, SG_DXFER_FROM_DEV, 12); @@ -300,11 +300,11 @@ int _stlink_usb_get_rw_status(stlink_t *sl) { return(ret<0?-1:0); } -int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int32_t _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; - int i, ret; + int32_t i, ret; i = fill_command(sl, SG_DXFER_TO_DEV, len); cmd[i++] = STLINK_DEBUG_COMMAND; @@ -322,11 +322,11 @@ int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { return(_stlink_usb_get_rw_status(sl)); } -int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { +int32_t _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; - int i, ret; + int32_t i, ret; if ((sl->version.jtag_api < STLINK_JTAG_API_V3 && len > 64) || (sl->version.jtag_api >= STLINK_JTAG_API_V3 && len > 512)) { @@ -351,13 +351,13 @@ int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { } -int _stlink_usb_current_mode(stlink_t * sl) { +int32_t _stlink_usb_current_mode(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; unsigned char* const data = sl->q_buf; ssize_t size; - int rep_len = 2; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + int32_t rep_len = 2; + int32_t 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, CMD_CHECK_NO, "GET_CURRENT_MODE"); @@ -369,13 +369,13 @@ int _stlink_usb_current_mode(stlink_t * sl) { return(sl->q_buf[0]); } -int _stlink_usb_core_id(stlink_t * sl) { +int32_t _stlink_usb_core_id(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; unsigned char* const data = sl->q_buf; ssize_t size; - int offset, rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 12; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + int32_t offset, rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 12; + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; @@ -398,8 +398,8 @@ int _stlink_usb_core_id(stlink_t * sl) { return(0); } -int _stlink_usb_status_v2(stlink_t *sl) { - int result; +int32_t _stlink_usb_status_v2(stlink_t *sl) { + int32_t result; uint32_t status = 0; result = _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &status); @@ -420,15 +420,15 @@ int _stlink_usb_status_v2(stlink_t *sl) { return(result); } -int _stlink_usb_status(stlink_t * sl) { +int32_t _stlink_usb_status(stlink_t * sl) { if (sl->version.jtag_api != STLINK_JTAG_API_V1) { return(_stlink_usb_status_v2(sl)); } struct stlink_libusb * const slu = sl->backend_data; 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); + int32_t rep_len = 2; + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_GETSTATUS; @@ -449,10 +449,10 @@ int _stlink_usb_status(stlink_t * sl) { return(size<0?-1:0); } -int _stlink_usb_force_debug(stlink_t *sl) { +int32_t _stlink_usb_force_debug(stlink_t *sl) { struct stlink_libusb *slu = sl->backend_data; - int res; + int32_t res; if (sl->version.jtag_api != STLINK_JTAG_API_V1) { res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_DEBUGEN); @@ -462,8 +462,8 @@ int _stlink_usb_force_debug(stlink_t *sl) { 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); + int32_t rep_len = 2; + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_FORCEDEBUG; @@ -472,13 +472,13 @@ int _stlink_usb_force_debug(stlink_t *sl) { return(size<0?-1:0); } -int _stlink_usb_enter_swd_mode(stlink_t * sl) { +int32_t _stlink_usb_enter_swd_mode(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; ssize_t size; unsigned char* const data = sl->q_buf; const uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 2; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; // select correct API-Version for entering SWD mode: V1 API (0x20) or V2 API (0x30). @@ -489,11 +489,11 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { return(size<0?-1:0); } -int _stlink_usb_exit_dfu_mode(stlink_t* sl) { +int32_t _stlink_usb_exit_dfu_mode(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; ssize_t size; - int i = fill_command(sl, SG_DXFER_FROM_DEV, 0); + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, 0); cmd[i++] = STLINK_DFU_COMMAND; cmd[i++] = STLINK_DFU_EXIT; @@ -503,12 +503,12 @@ int _stlink_usb_exit_dfu_mode(stlink_t* sl) { } -int _stlink_usb_reset(stlink_t * sl) { +int32_t _stlink_usb_reset(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; - int i, rep_len = 2; + int32_t i, rep_len = 2; // send reset command i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); @@ -525,13 +525,13 @@ int _stlink_usb_reset(stlink_t * sl) { return(size<0?-1:0); } -int _stlink_usb_jtag_reset(stlink_t * sl, int value) { +int32_t _stlink_usb_jtag_reset(stlink_t * sl, int32_t value) { struct stlink_libusb * const slu = sl->backend_data; 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); + int32_t rep_len = 2; + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_DRIVE_NRST; @@ -542,7 +542,7 @@ int _stlink_usb_jtag_reset(stlink_t * sl, int value) { } -int _stlink_usb_step(stlink_t* sl) { +int32_t _stlink_usb_step(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; if (sl->version.jtag_api != STLINK_JTAG_API_V1) { @@ -558,8 +558,8 @@ int _stlink_usb_step(stlink_t* sl) { 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); + int32_t rep_len = 2; + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_STEPCORE; @@ -573,10 +573,10 @@ int _stlink_usb_step(stlink_t* sl) { * @param sl * @param type */ -int _stlink_usb_run(stlink_t* sl, enum run_type type) { +int32_t _stlink_usb_run(stlink_t* sl, enum run_type type) { struct stlink_libusb * const slu = sl->backend_data; - int res; + int32_t res; if (sl->version.jtag_api != STLINK_JTAG_API_V1) { res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, @@ -589,8 +589,8 @@ int _stlink_usb_run(stlink_t* sl, enum run_type type) { 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); + int32_t rep_len = 2; + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_RUNCORE; @@ -599,20 +599,20 @@ int _stlink_usb_run(stlink_t* sl, enum run_type type) { return(size<0?-1:0); } -int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { +int32_t _stlink_usb_set_swdclk(stlink_t* sl, int32_t clk_freq) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; - int rep_len = 2; - int i; + int32_t rep_len = 2; + int32_t i; // clock speed only supported by stlink/v2 and for firmware >= 22 if (sl->version.stlink_v == 2 && sl->version.jtag_v >= 22) { uint16_t clk_divisor; if (clk_freq) { const uint32_t map[] = {5, 15, 25, 50, 100, 125, 240, 480, 950, 1200, 1800, 4000}; - int speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), clk_freq); + int32_t speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), clk_freq); switch (map[speed_index]) { case 5: clk_divisor = STLINK_SWDCLK_5KHZ_DIVISOR; break; case 15: clk_divisor = STLINK_SWDCLK_15KHZ_DIVISOR; break; @@ -641,7 +641,7 @@ int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { return(size<0?-1:0); } else if (sl->version.stlink_v == 3) { - int speed_index; + int32_t speed_index; uint32_t map[STLINK_V3_MAX_FREQ_NB]; i = fill_command(sl, SG_DXFER_FROM_DEV, 16); @@ -654,7 +654,7 @@ int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { return(-1); } - int speeds_size = data[8]; + int32_t speeds_size = data[8]; if (speeds_size > STLINK_V3_MAX_FREQ_NB) { speeds_size = STLINK_V3_MAX_FREQ_NB; } @@ -688,11 +688,11 @@ int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { return(-1); } -int _stlink_usb_exit_debug_mode(stlink_t *sl) { +int32_t _stlink_usb_exit_debug_mode(stlink_t *sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; ssize_t size; - int i = fill_command(sl, SG_DXFER_FROM_DEV, 0); + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, 0); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_EXIT; @@ -702,12 +702,12 @@ int _stlink_usb_exit_debug_mode(stlink_t *sl) { return(size<0?-1:0); } -int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int32_t _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libusb * const slu = sl->backend_data; 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); + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_READMEM_32BIT; @@ -719,19 +719,19 @@ int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { return(-1); } - sl->q_len = (int)size; + sl->q_len = (int32_t)size; stlink_print_data(sl); return(0); } -int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { +int32_t _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; unsigned char* const data = sl->q_buf; ssize_t size; uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 84 : 88; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; @@ -749,8 +749,8 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { /* V1: regs data from offset 0 */ /* V2: status at offset 0, regs data from offset 4 */ - int reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; - sl->q_len = (int)size; + int32_t reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; + sl->q_len = (int32_t)size; stlink_print_data(sl); for (i = 0; i < 16; i++) regp->r[i] = read_uint32(sl->q_buf, reg_offset + i * 4); @@ -772,15 +772,15 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { return(0); } -int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { +int32_t _stlink_usb_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t r; uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 8; - int reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + int32_t reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; @@ -797,7 +797,7 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { return(-1); } - sl->q_len = (int)size; + sl->q_len = (int32_t)size; stlink_print_data(sl); r = read_uint32(sl->q_buf, reg_offset); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); @@ -826,13 +826,13 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { } /* See section C1.6 of the ARMv7-M Architecture Reference Manual */ -int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { +int32_t _stlink_usb_read_unsupported_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp) { uint32_t r; - int ret; + int32_t ret; sl->q_buf[0] = (unsigned char)r_idx; - for (int i = 1; i < 4; i++) sl->q_buf[i] = 0; + for (int32_t i = 1; i < 4; i++) sl->q_buf[i] = 0; ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4); @@ -863,8 +863,8 @@ int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg return(0); } -int _stlink_usb_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { - int ret; +int32_t _stlink_usb_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { + int32_t ret; ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); @@ -874,7 +874,7 @@ int _stlink_usb_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) if (ret == -1) { return(ret); } - for (int i = 0; i < 32; i++) { + for (int32_t i = 0; i < 32; i++) { ret = _stlink_usb_read_unsupported_reg(sl, 0x40 + i, regp); if (ret == -1) { return(ret); } @@ -884,8 +884,8 @@ int _stlink_usb_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) } /* See section C1.6 of the ARMv7-M Architecture Reference Manual */ -int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, struct stlink_reg *regp) { - int ret; +int32_t _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int32_t r_idx, struct stlink_reg *regp) { + int32_t ret; if (r_idx >= 0x1C && r_idx <= 0x1F) { // primask, basepri, faultmask, or control /* These are held in the same register */ @@ -939,13 +939,13 @@ int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, str return(_stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4)); } -int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { +int32_t _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int32_t idx) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t rep_len = 2; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; @@ -962,14 +962,14 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { return(size<0?-1:0); } -int _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { +int32_t _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t rep_len = 2; - int i = fill_command(sl, SG_DXFER_TO_DEV, rep_len); + int32_t i = fill_command(sl, SG_DXFER_TO_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_START_TRACE_RX; write_uint16(&cmd[i + 0], 2 * STLINK_TRACE_BUF_LEN); @@ -980,14 +980,14 @@ int _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { return(size<0?-1:0); } -int _stlink_usb_disable_trace(stlink_t* sl) { +int32_t _stlink_usb_disable_trace(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t rep_len = 2; - int i = fill_command(sl, SG_DXFER_TO_DEV, rep_len); + int32_t i = fill_command(sl, SG_DXFER_TO_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_STOP_TRACE_RX; @@ -996,12 +996,12 @@ int _stlink_usb_disable_trace(stlink_t* sl) { return(size<0?-1:0); } -int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { +int32_t _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; uint32_t rep_len = 2; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + int32_t i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_GET_TRACE_NB; @@ -1010,7 +1010,7 @@ int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { if (send_size < 0) { return(-1); } else if (send_size != 2) { - ELOG("STLINK_DEBUG_APIV2_GET_TRACE_NB reply size %d\n", (int)send_size); + ELOG("STLINK_DEBUG_APIV2_GET_TRACE_NB reply size %d\n", (int32_t)send_size); return(-1); } @@ -1022,10 +1022,10 @@ int _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { } if (trace_count != 0) { - int res = 0; - int t = libusb_bulk_transfer(slu->usb_handle, slu->ep_trace, buf, trace_count, &res, 3000); + int32_t res = 0; + int32_t t = libusb_bulk_transfer(slu->usb_handle, slu->ep_trace, buf, trace_count, &res, 3000); - if (t || res != (int)trace_count) { + if (t || res != (int32_t)trace_count) { ELOG("read_trace read error %d\n", t); return(-1); } @@ -1075,7 +1075,7 @@ size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_d serial[0] = '\0'; /* get the LANGID from String Descriptor Zero */ - int ret = libusb_get_string_descriptor(handle, 0, 0, desc_serial, sizeof(desc_serial)); + int32_t ret = libusb_get_string_descriptor(handle, 0, 0, desc_serial, sizeof(desc_serial)); if (ret < 4) return 0; uint32_t langid = desc_serial[2] | (desc_serial[3] << 8); @@ -1094,7 +1094,7 @@ size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_d if (ret < 0) return 0; } else if (len == ((STLINK_SERIAL_LENGTH / 2 + 1) * 2)) { /* len == 26 */ /* fix-up the buggy serial */ - for (unsigned int i = 0; i < STLINK_SERIAL_LENGTH; i += 2) + for (uint32_t i = 0; i < STLINK_SERIAL_LENGTH; i += 2) sprintf(serial + i, "%02X", desc_serial[i + 2]); serial[STLINK_SERIAL_LENGTH] = '\0'; } else { @@ -1104,11 +1104,11 @@ size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_d return strlen(serial); } -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq) { +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int32_t freq) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; - int ret = -1; - int config; + int32_t ret = -1; + int32_t config; sl = calloc(1, sizeof(stlink_t)); if (sl == NULL) { goto on_malloc_error; } @@ -1246,7 +1246,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, // initialize stlink version (sl->version) stlink_version(sl); - int mode = stlink_current_mode(sl); + int32_t mode = stlink_current_mode(sl); if (mode == STLINK_DEV_DFU_MODE) { DLOG("-- exit_dfu_mode\n"); _stlink_usb_exit_dfu_mode(sl); @@ -1288,17 +1288,17 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, return(NULL); } -static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], enum connect_type connect, int freq) { +static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], enum connect_type connect, int32_t freq) { stlink_t **_sldevs; libusb_device *dev; - int i = 0; + int32_t i = 0; size_t slcnt = 0; size_t slcur = 0; /* Count STLINKs */ while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; - int ret = libusb_get_device_descriptor(dev, &desc); + int32_t ret = libusb_get_device_descriptor(dev, &desc); if (ret < 0) { WLOG("failed to get libusb device descriptor (libusb error: %d)\n", ret); @@ -1327,7 +1327,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], e while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; - int ret = libusb_get_device_descriptor(dev, &desc); + int32_t ret = libusb_get_device_descriptor(dev, &desc); if (ret < 0) { WLOG("failed to get libusb device descriptor (libusb error: %d)\n", ret); @@ -1372,12 +1372,12 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], e return(slcur); } -size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int freq) { +size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int32_t freq) { libusb_device **devs; stlink_t **sldevs; size_t slcnt = 0; - int r; + int32_t r; ssize_t cnt; r = libusb_init(NULL); diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index 8c98bcaf4..b5c1835ec 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -7,9 +7,10 @@ #define USB_H #include +#include #include -#include +#include "libusb_settings.h" #include "logging.h" #define STLINK_USB_VID_ST 0x0483 @@ -49,12 +50,12 @@ struct stlink_libusb { libusb_context* libusb_ctx; libusb_device_handle* usb_handle; - unsigned int ep_req; - unsigned int ep_rep; - unsigned int ep_trace; - int protocoll; - unsigned int sg_transfer_idx; - unsigned int cmd_len; + uint32_t ep_req; + uint32_t ep_rep; + uint32_t ep_trace; + int32_t protocoll; + uint32_t sg_transfer_idx; + uint32_t cmd_len; }; /** @@ -66,8 +67,8 @@ struct stlink_libusb { * @retval !NULL Stlink found and ready to use */ -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq); -size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int freq); +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int32_t freq); +size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int32_t freq); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); #endif // USB_H diff --git a/src/win32/getopt/getopt.c b/src/win32/getopt/getopt.c index ff0a2fd91..7bc8d2d20 100644 --- a/src/win32/getopt/getopt.c +++ b/src/win32/getopt/getopt.c @@ -1,18 +1,19 @@ #include +#include #include #include "getopt.h" #if !defined(_MSC_VER) -const int no_argument = 0; -const int required_argument = 1; -const int optional_argument = 2; +const int32_t no_argument = 0; +const int32_t required_argument = 1; +const int32_t optional_argument = 2; #endif char* optarg; -int optopt; -int optind = 1; // The variable optind [...] shall be initialized to 1 by the system -int opterr; +int32_t optopt; +int32_t optind = 1; // The variable optind [...] shall be initialized to 1 by the system +int32_t opterr; static char* optcursor = NULL; @@ -24,8 +25,8 @@ static char* optcursor = NULL; * [2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html * [3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE */ -int getopt(int argc, char* const argv[], const char* optstring) { - int optchar = -1; +int32_t getopt(int32_t argc, char* const argv[], const char* optstring) { + int32_t optchar = -1; const char* optdecl = NULL; optarg = NULL; @@ -125,17 +126,17 @@ int getopt(int argc, char* const argv[], const char* optstring) { } /* Implementation based on http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html */ -int getopt_long(int argc, +int32_t getopt_long(int32_t argc, char* const argv[], const char* optstring, const struct option* longopts, int* longindex) { const struct option* o = longopts; const struct option* match = NULL; - int num_matches = 0; + int32_t num_matches = 0; size_t argument_name_length = 0; const char* current_argument = NULL; - int retval = -1; + int32_t retval = -1; optarg = NULL; optopt = 0; diff --git a/src/win32/getopt/getopt.h b/src/win32/getopt/getopt.h index b1dd35ef1..4f21e69dc 100644 --- a/src/win32/getopt/getopt.h +++ b/src/win32/getopt/getopt.h @@ -1,6 +1,8 @@ #ifndef GETOPT_H #define GETOPT_H +#include + #if defined(__cplusplus) extern "C" { #endif @@ -11,24 +13,24 @@ extern "C" { #define required_argument 1 #define optional_argument 2 #else -extern const int no_argument; -extern const int required_argument; -extern const int optional_argument; +extern const int32_t no_argument; +extern const int32_t required_argument; +extern const int32_t optional_argument; #endif extern char* optarg; -extern int optind, opterr, optopt; +extern int32_t optind, opterr, optopt; struct option { const char* name; - int has_arg; + int32_t has_arg; int* flag; - int val; + int32_t val; }; -int getopt(int argc, char* const argv[], const char* optstring); +int32_t getopt(int32_t argc, char* const argv[], const char* optstring); -int getopt_long(int argc, +int32_t getopt_long(int32_t argc, char* const argv[], const char* optstring, const struct option* longopts, diff --git a/src/win32/mmap.c b/src/win32/mmap.c index d702a78f6..ea8a3cb37 100644 --- a/src/win32/mmap.c +++ b/src/win32/mmap.c @@ -1,11 +1,12 @@ -#include -#include +#include #include +#include #include +#include #include "mmap.h" -void *mmap (void *addr, size_t len, int prot, int flags, int fd, long long offset) { +void *mmap (void *addr, size_t len, int32_t prot, int32_t flags, int32_t fd, int64_t offset) { void *buf; ssize_t count; @@ -31,7 +32,7 @@ void *mmap (void *addr, size_t len, int prot, int flags, int fd, long long offse (void)flags; } -int munmap (void *addr, size_t len) { +int32_t munmap (void *addr, size_t len) { free (addr); return(0); (void)len; diff --git a/src/win32/mmap.h b/src/win32/mmap.h index c6390aede..e8bbab0bc 100644 --- a/src/win32/mmap.h +++ b/src/win32/mmap.h @@ -1,6 +1,8 @@ #ifndef MMAP_H #define MMAP_H +#include + #ifdef STLINK_HAVE_SYS_MMAN_H #include #else @@ -13,8 +15,8 @@ #define MAP_ANONYMOUS (1 << 5) #define MAP_FAILED ((void *)-1) -void *mmap(void *addr, size_t len, int prot, int flags, int fd, long long offset); -int munmap(void *addr, size_t len); +void *mmap(void *addr, size_t len, int32_t prot, int32_t flags, int32_t fd, int64_t offset); +int32_t munmap(void *addr, size_t len); #endif // STLINK_HAVE_SYS_MMAN_H diff --git a/src/win32/sys_time.c b/src/win32/sys_time.c index 422731b3f..a09d8df67 100644 --- a/src/win32/sys_time.c +++ b/src/win32/sys_time.c @@ -1,3 +1,5 @@ +#include + #include "sys_time.h" #ifndef STLINK_HAVE_SYS_TIME_H @@ -5,18 +7,18 @@ #include /* Simple gettimeofday implementation without converting Windows time to Linux time */ -int gettimeofday(struct timeval *tv, struct timezone *tz) { +int32_t gettimeofday(struct timeval *tv, struct timezone *tz) { FILETIME ftime; ULARGE_INTEGER ulint; - static int tzflag = 0; + static int32_t tzflag = 0; if(NULL != tv) { GetSystemTimeAsFileTime(&ftime); ulint.LowPart = ftime.dwLowDateTime; ulint.HighPart = ftime.dwHighDateTime; - tv->tv_sec = (long)(ulint.QuadPart / 10000000L); - tv->tv_usec = (long)(ulint.QuadPart % 10000000L); + tv->tv_sec = (int32_t)(ulint.QuadPart / 10000000L); + tv->tv_usec = (int32_t)(ulint.QuadPart % 10000000L); } if(NULL != tz) { diff --git a/src/win32/sys_time.h b/src/win32/sys_time.h index 98ecaddfc..ca6e0a761 100644 --- a/src/win32/sys_time.h +++ b/src/win32/sys_time.h @@ -1,6 +1,8 @@ #ifndef SYS_TIME_H #define SYS_TIME_H +#include + #ifdef STLINK_HAVE_SYS_TIME_H #include @@ -10,11 +12,11 @@ #include struct timezone { - int tz_minuteswest; - int tz_dsttime; + int32_t tz_minuteswest; + int32_t tz_dsttime; }; -int gettimeofday(struct timeval *tv, struct timezone *tz); +int32_t gettimeofday(struct timeval *tv, struct timezone *tz); #endif // STLINK_HAVE_SYS_TIME_H diff --git a/src/win32/unistd/unistd.h b/src/win32/unistd/unistd.h index 5f2b5433b..d61b75b67 100644 --- a/src/win32/unistd/unistd.h +++ b/src/win32/unistd/unistd.h @@ -6,8 +6,9 @@ * Please add functionality as needed. */ -#include +#include #include +#include #if defined(_MSC_VER) #pragma warning(push) @@ -69,7 +70,7 @@ typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; #ifndef STLINK_HAVE_UNISTD_H -int usleep(unsigned int waitTime); +int32_t usleep(uint32_t waitTime); #endif #endif // UNISTD_H diff --git a/src/win32/win32_socket.c b/src/win32/win32_socket.c index 3f4d28bbd..46b4532a7 100644 --- a/src/win32/win32_socket.c +++ b/src/win32/win32_socket.c @@ -1,5 +1,7 @@ #if defined(_WIN32) +#include + #include "win32_socket.h" #undef socket @@ -11,11 +13,11 @@ #include #include -int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) { +int32_t win32_poll(struct pollfd *fds, uint32_t nfds, int32_t timo) { struct timeval timeout, *toptr; fd_set ifds, ofds, efds, *ip, *op; - unsigned int i; - int rc; + uint32_t i; + int32_t rc; #ifdef _MSC_VER #pragma warning(disable: 4548) @@ -99,7 +101,7 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) { return(rc); } -static void set_connect_errno(int winsock_err) { +static void set_connect_errno(int32_t winsock_err) { switch (winsock_err) { case WSAEINVAL: case WSAEALREADY: @@ -112,7 +114,7 @@ static void set_connect_errno(int winsock_err) { } } -static void set_socket_errno(int winsock_err) { +static void set_socket_errno(int32_t winsock_err) { switch (winsock_err) { case WSAEWOULDBLOCK: errno = EAGAIN; @@ -128,7 +130,7 @@ static void set_socket_errno(int winsock_err) { * The purpose of this wrapper is to ensure that the global errno symbol is set if an error occurs, * even if we are using winsock. */ -SOCKET win32_socket(int domain, int type, int protocol) { +SOCKET win32_socket(int32_t domain, int32_t type, int32_t protocol) { SOCKET fd = socket(domain, type, protocol); if (fd == INVALID_SOCKET) { set_socket_errno(WSAGetLastError()); } @@ -141,8 +143,8 @@ SOCKET win32_socket(int domain, int type, int protocol) { * The purpose of this wrapper is to ensure that the global errno symbol is set if an error occurs, * even if we are using winsock. */ -int win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len) { - int rc = connect(fd, addr, addr_len); +int32_t win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len) { + int32_t rc = connect(fd, addr, addr_len); assert(rc == 0 || rc == SOCKET_ERROR); if (rc == SOCKET_ERROR) { set_connect_errno(WSAGetLastError()); } @@ -169,8 +171,8 @@ SOCKET win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len) { * The purpose of this wrapper is to ensure that the global errno symbol is set if an error occurs, * even if we are using winsock. */ -int win32_shutdown(SOCKET fd, int mode) { - int rc = shutdown(fd, mode); +int32_t win32_shutdown(SOCKET fd, int32_t mode) { + int32_t rc = shutdown(fd, mode); assert(rc == 0 || rc == SOCKET_ERROR); if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } @@ -178,24 +180,24 @@ int win32_shutdown(SOCKET fd, int mode) { return(rc); } -int win32_close_socket(SOCKET fd) { - int rc = closesocket(fd); +int32_t win32_close_socket(SOCKET fd) { + int32_t rc = closesocket(fd); if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } return(rc); } -ssize_t win32_write_socket(SOCKET fd, void *buf, int n) { - int rc = send(fd, buf, n, 0); +ssize_t win32_write_socket(SOCKET fd, void *buf, int32_t n) { + int32_t rc = send(fd, buf, n, 0); if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } return(rc); } -ssize_t win32_read_socket(SOCKET fd, void *buf, int n) { - int rc = recv(fd, buf, n, 0); +ssize_t win32_read_socket(SOCKET fd, void *buf, int32_t n) { + int32_t rc = recv(fd, buf, n, 0); if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } @@ -205,7 +207,7 @@ ssize_t win32_read_socket(SOCKET fd, void *buf, int n) { char * win32_strtok_r(char *s, const char *delim, char **lasts) { register char *spanp; - register int c, sc; + register int32_t c, sc; char *tok; @@ -254,7 +256,7 @@ char * win32_strtok_r(char *s, const char *delim, char **lasts) { char *win32_strsep (char **stringp, const char *delim) { register char *s; register const char *spanp; - register int c, sc; + register int32_t c, sc; char *tok; if ((s = *stringp) == NULL) { @@ -284,7 +286,7 @@ char *win32_strsep (char **stringp, const char *delim) { } #ifndef STLINK_HAVE_UNISTD_H -int usleep(unsigned int waitTime) { +int32_t usleep(uint32_t waitTime) { if (waitTime >= 1000) { /* Don't do long busy-waits. * However much it seems like the QPC code would be more accurate, diff --git a/src/win32/win32_socket.h b/src/win32/win32_socket.h index 614046a6f..e7ea398e9 100644 --- a/src/win32/win32_socket.h +++ b/src/win32/win32_socket.h @@ -1,5 +1,7 @@ #if defined(_WIN32) +#include + #define _USE_W32_SOCKETS 1 #if defined(_MSC_VER) @@ -35,8 +37,8 @@ #define POLLNVAL 0x0020 /* Invalid request: fd not open */ struct pollfd { SOCKET fd; /* file descriptor */ - short events; /* requested events */ - short revents; /* returned events */ + int16_t events; /* requested events */ + int16_t revents; /* returned events */ }; #endif #define poll(x, y, z) win32_poll(x, y, z) @@ -54,15 +56,15 @@ struct pollfd { #define read(x, y, z) win32_read_socket(x, y, z) #define write(x, y, z) win32_write_socket(x, y, z) -/* Winsock uses int instead of the usual socklen_t */ -typedef int socklen_t; +/* Winsock uses int32_t instead of the usual socklen_t */ +typedef int32_t socklen_t; -int win32_poll(struct pollfd *, unsigned int, int); -SOCKET win32_socket(int, int, int); -int win32_connect(SOCKET, struct sockaddr*, socklen_t); +int32_t win32_poll(struct pollfd *, uint32_t, int); +SOCKET win32_socket(int32_t, int32_t, int); +int32_t win32_connect(SOCKET, struct sockaddr*, socklen_t); SOCKET win32_accept(SOCKET, struct sockaddr*, socklen_t *); -int win32_shutdown(SOCKET, int); -int win32_close_socket(SOCKET fd); +int32_t win32_shutdown(SOCKET, int); +int32_t win32_close_socket(SOCKET fd); #define strtok_r(x, y, z) win32_strtok_r(x, y, z) #define strsep(x,y) win32_strsep(x,y) @@ -70,7 +72,7 @@ int win32_close_socket(SOCKET fd); char *win32_strtok_r(char *s, const char *delim, char **lasts); char *win32_strsep(char **stringp, const char *delim); -ssize_t win32_read_socket(SOCKET fd, void *buf, int n); -ssize_t win32_write_socket(SOCKET fd, void *buf, int n); +ssize_t win32_read_socket(SOCKET fd, void *buf, int32_t n); +ssize_t win32_write_socket(SOCKET fd, void *buf, int32_t n); #endif // defined(_WIN32) diff --git a/tests/flash.c b/tests/flash.c index 1140566af..f66428dcd 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -11,7 +12,7 @@ struct Test { const char * cmd_line; - int res; + int32_t res; struct flash_opts opts; }; @@ -32,7 +33,7 @@ static bool cmp_mem(const uint8_t * s1, const uint8_t * s2, size_t size) { } static bool execute_test(const struct Test * test) { - int ac = 0; + int32_t ac = 0; char* av[32]; /* parse (tokenize) the test command line */ @@ -53,7 +54,7 @@ static bool execute_test(const struct Test * test) { /* Call */ struct flash_opts opts; - int res = flash_get_opts(&opts, ac, av); + int32_t res = flash_get_opts(&opts, ac, av); /* Compare results */ bool ret = (res == test->res); @@ -225,7 +226,7 @@ static struct Test tests[] = { }, }; -int main() { +int32_t main() { bool allOk = true; for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) diff --git a/tests/sg.c b/tests/sg.c index d88fbe760..cd601b6d6 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -24,7 +25,7 @@ static void __attribute__((unused)) mark_buf(stlink_t *sl) { } -int main(void) { // main() ripped out of old stlink-hw.c +int32_t main(void) { // main() ripped out of old stlink-hw.c /* Avoid unused parameter warning */ // set scpi lib debug level: 0 for no debug info, 10 for lots fputs( @@ -81,7 +82,7 @@ int main(void) { // main() ripped out of old stlink-hw.c memset(sl->q_buf, 0, sizeof(sl->q_buf)); - for (int i = 0; i < 100; i++) { + for (int32_t i = 0; i < 100; i++) { write_uint32(sl->q_buf, LED_BLUE | LED_GREEN); stlink_write_mem32(sl, GPIOC_ODR, 4); // stlink_read_mem32(sl, 0x4001100c, 4); @@ -184,7 +185,7 @@ int main(void) { // main() ripped out of old stlink-hw.c #if 0 /* check file contents */ fputs("\n+++++++ check flash memory\n\n", stderr); { - const int res = stlink_fcheck_flash(sl, "/tmp/foobar", 0x08000000); + const int32_t res = stlink_fcheck_flash(sl, "/tmp/foobar", 0x08000000); printf("_____ stlink_fcheck_flash() == %d\n", res); } #endif diff --git a/tests/usb.c b/tests/usb.c index 742f5c578..2d928e5f0 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -1,17 +1,18 @@ +#include #include +#include #include -#include static void usage(void) { puts("test-usb --reset"); puts("test-usb --no-reset"); } -int main(int ac, char** av) { +int32_t main(int32_t ac, char** av) { stlink_t* sl; struct stlink_reg regs; - int reset = 0; + int32_t reset = 0; if (ac == 2) { if (strcmp(av[1], "--reset") == 0) From 92ad99fe35d03adbe411eba5afabbb30c0c734b4 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 7 Jun 2023 22:01:56 +0200 Subject: [PATCH 1377/1435] Minor fixes & additions - G49x_G4Ax & WLEx: Added dualbank support - G49x_G4Ax: Added option byte support - Minor formatting improvements - Replaced leftovers for non-fixed length types --- config/chips/G49x_G4Ax.chip | 2 +- config/chips/{WLx5.chip => WLEx.chip} | 2 +- src/stlink-lib/common.c | 11 +- src/stlink-lib/common_flash.c | 3 +- src/stlink-lib/flash_loader.c | 141 +++++++++++++------------- src/stlink-lib/flash_loader.h | 12 ++- src/stlink-lib/option_bytes.c | 1 + src/win32/win32_socket.h | 6 +- 8 files changed, 92 insertions(+), 86 deletions(-) rename config/chips/{WLx5.chip => WLEx.chip} (95%) diff --git a/config/chips/G49x_G4Ax.chip b/config/chips/G49x_G4Ax.chip index 3e8aacf4b..079dc01ae 100644 --- a/config/chips/G49x_G4Ax.chip +++ b/config/chips/G49x_G4Ax.chip @@ -11,4 +11,4 @@ bootrom_base 0x1fff0000 bootrom_size 0x7000 // 28 KB option_base 0x1ffff800 // STM32_G4_OPTION_BYTES_BASE option_size 0x4 // 4 B -flags swo +flags swo dualbank diff --git a/config/chips/WLx5.chip b/config/chips/WLEx.chip similarity index 95% rename from config/chips/WLx5.chip rename to config/chips/WLEx.chip index 8337b0aee..265514211 100644 --- a/config/chips/WLx5.chip +++ b/config/chips/WLEx.chip @@ -11,4 +11,4 @@ bootrom_base 0x1fff0000 bootrom_size 0x7000 // 28 KB option_base 0x1fff7800 option_size 0x10 // 16 B -flags swo +flags swo dualbank diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index cb87f5f36..43d2b9a9e 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -41,8 +41,8 @@ struct stlink_fread_ihex_worker_arg { typedef bool (*save_block_fn)(void *arg, uint8_t *block, ssize_t len); static void stop_wdg_in_debug(stlink_t *); -int32_t stlink_jtag_reset(stlink_t *, int); -int32_t stlink_soft_reset(stlink_t *, int); +int32_t stlink_jtag_reset(stlink_t *, int32_t); +int32_t stlink_soft_reset(stlink_t *, int32_t); void _parse_version(stlink_t *, stlink_version_t *); static uint8_t stlink_parse_hex(const char *); static int32_t stlink_read(stlink_t *, stm32_addr_t, size_t, save_block_fn, void *); @@ -253,8 +253,8 @@ int32_t stlink_load_device_params(stlink_t *sl) { flash_size = flash_size & 0xffff; if ((sl->chip_id == STM32_CHIPID_L1_MD || - sl->chip_id == STM32_CHIPID_F1_VL_MD_LD || - sl->chip_id == STM32_CHIPID_L1_MD_PLUS) && + sl->chip_id == STM32_CHIPID_F1_VL_MD_LD || + sl->chip_id == STM32_CHIPID_L1_MD_PLUS) && (flash_size == 0)) { sl->flash_size = 128 * 1024; } else if (sl->chip_id == STM32_CHIPID_L1_CAT2) { @@ -285,7 +285,8 @@ int32_t stlink_load_device_params(stlink_t *sl) { sl->sram_size = 0x1000; } - if (sl->chip_id == STM32_CHIPID_G4_CAT3) { + if (sl->chip_id == STM32_CHIPID_G4_CAT3 || + sl->chip_id == STM32_CHIPID_G4_CAT4) { uint32_t flash_optr; stlink_read_debug32(sl, FLASH_Gx_OPTR, &flash_optr); diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index e2a394946..31ea02c07 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -1348,8 +1348,7 @@ int32_t stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { * @param length how much * @return 0 for success, -ve for failure */ -int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, - uint32_t length) { +int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length) { size_t off; size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; ILOG("Starting verification of write complete\n"); diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 99a8260f7..23b2713a8 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -24,7 +24,7 @@ * flash loaders must be aligned by 4 (it's written by stlink_write_mem32) */ -/* flashloaders/stm32f0.s -- compiled with thumb2 */ +// flashloaders/stm32f0.s -- compiled with thumb2 static const uint8_t loader_code_stm32vl[] = { 0x00, 0xbf, 0x00, 0xbf, 0x09, 0x4f, 0x1f, 0x44, @@ -41,7 +41,7 @@ static const uint8_t loader_code_stm32vl[] = { 0x0c, 0x00, 0x00, 0x00 }; -/* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ +// flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored static const uint8_t loader_code_stm32f0[] = { 0xc0, 0x46, 0xc0, 0x46, 0x08, 0x4f, 0x1f, 0x44, @@ -59,8 +59,8 @@ static const uint8_t loader_code_stm32f0[] = { 0x14, 0x00, 0x00, 0x00 }; +// flashloaders/stm32lx.s static const uint8_t loader_code_stm32lx[] = { - // flashloaders/stm32lx.s 0x04, 0x68, 0x0c, 0x60, 0x00, 0xf1, 0x04, 0x00, 0x01, 0xf1, 0x04, 0x01, @@ -68,8 +68,8 @@ static const uint8_t loader_code_stm32lx[] = { 0x00, 0xbe, 0x00, 0x00 }; +// flashloaders/stm32f4.s static const uint8_t loader_code_stm32f4[] = { - // flashloaders/stm32f4.s 0xdf, 0xf8, 0x24, 0xc0, 0xdf, 0xf8, 0x24, 0xa0, 0xe2, 0x44, 0x04, 0x68, @@ -84,8 +84,8 @@ static const uint8_t loader_code_stm32f4[] = { 0x0e, 0x00, 0x00, 0x00 }; +// flashloaders/stm32f4lv.s static const uint8_t loader_code_stm32f4_lv[] = { - // flashloaders/stm32f4lv.s 0xdf, 0xf8, 0x24, 0xc0, 0xdf, 0xf8, 0x24, 0xa0, 0xe2, 0x44, 0x04, 0x78, @@ -100,8 +100,8 @@ static const uint8_t loader_code_stm32f4_lv[] = { 0x0e, 0x00, 0x00, 0x00 }; +// flashloaders/stm32l4.s static const uint8_t loader_code_stm32l4[] = { - // flashloaders/stm32l4.s 0xdf, 0xf8, 0x28, 0xc0, 0xdf, 0xf8, 0x28, 0xa0, 0xe2, 0x44, 0x05, 0x68, @@ -117,8 +117,8 @@ static const uint8_t loader_code_stm32l4[] = { 0x10, 0x00, 0x00, 0x00 }; +// flashloaders/stm32f7.s static const uint8_t loader_code_stm32f7[] = { - // flashloaders/stm32f7.s 0xdf, 0xf8, 0x28, 0xc0, 0xdf, 0xf8, 0x28, 0xa0, 0xe2, 0x44, 0x04, 0x68, @@ -134,8 +134,8 @@ static const uint8_t loader_code_stm32f7[] = { 0x0e, 0x00, 0x00, 0x00 }; +// flashloaders/stm32f7lv.s static const uint8_t loader_code_stm32f7_lv[] = { - // flashloaders/stm32f7lv.s 0xdf, 0xf8, 0x28, 0xc0, 0xdf, 0xf8, 0x28, 0xa0, 0xe2, 0x44, 0x04, 0x78, @@ -201,9 +201,9 @@ int32_t stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { } static int32_t loader_v_dependent_assignment(stlink_t *sl, - const uint8_t **loader_code, size_t *loader_size, - const uint8_t *high_v_loader, size_t high_v_loader_size, - const uint8_t *low_v_loader, size_t low_v_loader_size) { + const uint8_t **loader_code, size_t *loader_size, + const uint8_t *high_v_loader, size_t high_v_loader_size, + const uint8_t *low_v_loader, size_t low_v_loader_size) { int32_t retval = 0; if ( sl->version.stlink_v == 1) { @@ -338,21 +338,21 @@ int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t t flash_base = FLASH_REGS_BANK2_OFS; } - /* Setup core */ - stlink_write_reg(sl, fl->buf_addr, 0); // source - stlink_write_reg(sl, target, 1); // target - stlink_write_reg(sl, (uint32_t)size, 2); // count - stlink_write_reg(sl, flash_base, 3); // flash register base - // only used on VL/F1_XL, but harmless for others - stlink_write_reg(sl, fl->loader_addr, 15); // pc register + /* Setup core */ + stlink_write_reg(sl, fl->buf_addr, 0); // source + stlink_write_reg(sl, target, 1); // target + stlink_write_reg(sl, (uint32_t)size, 2); // count + stlink_write_reg(sl, flash_base, 3); // flash register base + // only used on VL/F1_XL, but harmless for others + stlink_write_reg(sl, fl->loader_addr, 15); // pc register - /* Reset IWDG */ - if (fl->iwdg_kr) { - stlink_write_debug32(sl, fl->iwdg_kr, STM32F0_WDG_KR_KEY_RELOAD); - } + /* Reset IWDG */ + if (fl->iwdg_kr) { + stlink_write_debug32(sl, fl->iwdg_kr, STM32F0_WDG_KR_KEY_RELOAD); + } - /* Run loader */ - stlink_run(sl, RUN_FLASH_LOADER); + /* Run loader */ + stlink_run(sl, RUN_FLASH_LOADER); /* * This piece of code used to try to spin for .1 second by waiting doing 10000 rounds of 10 µs. @@ -365,67 +365,63 @@ int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t t * as what was intended. -- REW. */ - // wait until done (reaches breakpoint) - timeout = time_ms() + 500; - while (time_ms() < timeout) { - usleep(10000); - - if (stlink_is_core_halted(sl)) { - timeout = 0; - break; - } - } + // wait until done (reaches breakpoint) + timeout = time_ms() + 500; + while (time_ms() < timeout) { + usleep(10000); - if (timeout) { - ELOG("Flash loader run error\n"); - goto error; - } + if (stlink_is_core_halted(sl)) { + timeout = 0; + break; + } + } - // check written byte count - stlink_read_reg(sl, 2, &rr); + if (timeout) { + ELOG("Flash loader run error\n"); + goto error; + } - /* - * The chunk size for loading is not rounded. The flash loader - * subtracts the size of the written block (1-8 bytes) from - * the remaining size each time. A negative value may mean that - * several bytes garbage have been written due to the unaligned - * firmware size. - */ - if ((int32_t)rr.r[2] > 0 || (int32_t)rr.r[2] < -7) { - ELOG("Flash loader write error\n"); - goto error; - } + // check written byte count + stlink_read_reg(sl, 2, &rr); + + /* + * The chunk size for loading is not rounded. The flash loader + * subtracts the size of the written block (1-8 bytes) from + * the remaining size each time. A negative value may mean that + * several bytes garbage have been written due to the unaligned + * firmware size. + */ + if ((int32_t)rr.r[2] > 0 || (int32_t)rr.r[2] < -7) { + ELOG("Flash loader write error\n"); + goto error; + } - return(0); + return(0); -error: - dhcsr = dfsr = cfsr = hfsr = 0; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); - stlink_read_debug32(sl, STLINK_REG_CFSR, &cfsr); - stlink_read_debug32(sl, STLINK_REG_HFSR, &hfsr); - stlink_read_all_regs(sl, &rr); + error: + dhcsr = dfsr = cfsr = hfsr = 0; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); + stlink_read_debug32(sl, STLINK_REG_CFSR, &cfsr); + stlink_read_debug32(sl, STLINK_REG_HFSR, &hfsr); + stlink_read_all_regs(sl, &rr); - WLOG("Loader state: R2 0x%X R15 0x%X\n", rr.r[2], rr.r[15]); - if (dhcsr != 0x3000B || dfsr || cfsr || hfsr) { - WLOG("MCU state: DHCSR 0x%X DFSR 0x%X CFSR 0x%X HFSR 0x%X\n", - dhcsr, dfsr, cfsr, hfsr); - } + WLOG("Loader state: R2 0x%X R15 0x%X\n", rr.r[2], rr.r[15]); + if (dhcsr != 0x3000B || dfsr || cfsr || hfsr) { + WLOG("MCU state: DHCSR 0x%X DFSR 0x%X CFSR 0x%X HFSR 0x%X\n", + dhcsr, dfsr, cfsr, hfsr); + } - return(-1); + return(-1); } -/* ================================================== - * === Content from old source file flashloader.c === - * ================================================== - */ +/* === Content from old source file flashloader.c === */ #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 -int32_t stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, - uint32_t len, uint32_t pagesize) { +int32_t stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint32_t pagesize) { uint32_t count, off; uint32_t num_half_pages = len / pagesize; uint32_t val; @@ -722,8 +718,7 @@ int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { return (0); } -int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, - stm32_addr_t addr, uint8_t *base, uint32_t len) { +int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t *base, uint32_t len) { size_t off; if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || (sl->flash_type == STM32_FLASH_TYPE_F7) || diff --git a/src/stlink-lib/flash_loader.h b/src/stlink-lib/flash_loader.h index 5b7b0945d..46cacba30 100644 --- a/src/stlink-lib/flash_loader.h +++ b/src/stlink-lib/flash_loader.h @@ -14,11 +14,21 @@ #include int32_t stlink_flash_loader_init(stlink_t *sl, flash_loader_t* fl); +static int32_t loader_v_dependent_assignment(stlink_t *sl, + const uint8_t **loader_code, size_t *loader_size, + const uint8_t *high_v_loader, size_t high_v_loader_size, + const uint8_t *low_v_loader, size_t low_v_loader_size); int32_t stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size); + +/* === Functions from old header file flashloader.h === */ + +int32_t stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint32_t pagesize); +static void set_flash_cr_pg(stlink_t *sl, uint32_t bank); +static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int32_t bckpRstr); int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); -int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len); +int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t *base, uint32_t len); int32_t stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl); #endif // FLASH_LOADER_H diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c index e2d966b7a..3300ee15e 100644 --- a/src/stlink-lib/option_bytes.c +++ b/src/stlink-lib/option_bytes.c @@ -1012,6 +1012,7 @@ int32_t stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { case STM32_CHIPID_G0_CAT2: case STM32_CHIPID_G4_CAT2: case STM32_CHIPID_G4_CAT3: + case STM32_CHIPID_G4_CAT4: return stlink_read_option_bytes_gx(sl, option_byte); default: return stlink_read_option_bytes_generic(sl, option_byte); diff --git a/src/win32/win32_socket.h b/src/win32/win32_socket.h index e7ea398e9..fb622f546 100644 --- a/src/win32/win32_socket.h +++ b/src/win32/win32_socket.h @@ -59,11 +59,11 @@ struct pollfd { /* Winsock uses int32_t instead of the usual socklen_t */ typedef int32_t socklen_t; -int32_t win32_poll(struct pollfd *, uint32_t, int); -SOCKET win32_socket(int32_t, int32_t, int); +int32_t win32_poll(struct pollfd *, uint32_t, int32_t); +SOCKET win32_socket(int32_t, int32_t, int32_t); int32_t win32_connect(SOCKET, struct sockaddr*, socklen_t); SOCKET win32_accept(SOCKET, struct sockaddr*, socklen_t *); -int32_t win32_shutdown(SOCKET, int); +int32_t win32_shutdown(SOCKET, int32_t); int32_t win32_close_socket(SOCKET fd); #define strtok_r(x, y, z) win32_strtok_r(x, y, z) From c8eaebc58eb7b027ab53c16ef4e8ad6fd72a10d7 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 7 Jun 2023 22:44:59 +0200 Subject: [PATCH 1378/1435] Improvents for library documentation - Renamed header file reg.h to register.h - Added unified header comments for files - [doc] flash_loader.h: // Static functions --- CMakeLists.txt | 2 +- inc/stlink.h | 6 ++---- src/st-trace/trace.c | 2 +- src/stlink-lib/calculate.c | 6 ++++++ src/stlink-lib/chipid.c | 6 ++++++ src/stlink-lib/chipid.h | 6 ++++++ src/stlink-lib/commands.h | 6 ++++++ src/stlink-lib/common_flash.c | 6 ++++++ src/stlink-lib/flash_loader.c | 6 ++++++ src/stlink-lib/flash_loader.h | 14 +++++++------- src/stlink-lib/helper.c | 6 ++++++ src/stlink-lib/helper.h | 6 ++++++ src/stlink-lib/libusb_settings.h | 6 ++++++ src/stlink-lib/logging.c | 3 +-- src/stlink-lib/map_file.c | 6 ++++++ src/stlink-lib/md5.c | 6 ++++++ src/stlink-lib/option_bytes.c | 6 ++++++ src/stlink-lib/{reg.h => register.h} | 10 ++++++++-- src/stlink-lib/sg.c | 6 ++++++ src/stlink-lib/sg.h | 5 +++-- src/stlink-lib/usb.c | 6 ++++++ src/stlink-lib/usb.h | 5 +++-- 22 files changed, 110 insertions(+), 21 deletions(-) rename src/stlink-lib/{reg.h => register.h} (98%) diff --git a/CMakeLists.txt b/CMakeLists.txt index bce4def8f..4ff18b815 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,7 +180,7 @@ set(STLINK_HEADERS src/stlink-lib/map_file.h src/stlink-lib/md5.h src/stlink-lib/option_bytes.h - src/stlink-lib/reg.h + src/stlink-lib/register.h src/stlink-lib/sg.h src/stlink-lib/usb.h ) diff --git a/inc/stlink.h b/inc/stlink.h index ca07a6a89..2ed34a074 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -1,9 +1,7 @@ - /* * File: stlink.h * - * This should contain all the common top level stlink interfaces, - * regardless of how the backend does the work.... + * All common top level stlink interfaces, regardless of how the backend does the work.... */ #ifndef STLINK_H @@ -300,7 +298,7 @@ int32_t stlink_target_connect(stlink_t *sl, enum connect_type connect); #include #include -#include +#include #include #include #include diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 8b148f463..ccbd74e16 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include #define DEFAULT_LOGGING_LEVEL 50 diff --git a/src/stlink-lib/calculate.c b/src/stlink-lib/calculate.c index 132875a66..2a708b551 100644 --- a/src/stlink-lib/calculate.c +++ b/src/stlink-lib/calculate.c @@ -1,3 +1,9 @@ +/* + * File: calculate.c + * + * Calculation of sector numbers and pages + */ + #include #include diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 7e99a8730..65ca2842a 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -1,3 +1,9 @@ +/* + * File: chipid.c + * + * Chip-ID parametres + */ + #include #include #include diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index 9eaac722d..9955811fa 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -1,3 +1,9 @@ +/* + * File: chipid.h + * + * Chip-ID parametres + */ + #ifndef CHIPID_H #define CHIPID_H diff --git a/src/stlink-lib/commands.h b/src/stlink-lib/commands.h index 5f0904971..64cecce16 100644 --- a/src/stlink-lib/commands.h +++ b/src/stlink-lib/commands.h @@ -1,3 +1,9 @@ +/* + * File: commands.h + * + * stlink commands + */ + #ifndef COMMANDS_H #define COMMANDS_H diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 31ea02c07..d2063851f 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -1,3 +1,9 @@ +/* + * File: common_flash.c + * + * Flash operations + */ + #include #include #include diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 23b2713a8..0f171d223 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -1,3 +1,9 @@ +/* + * File: flash_loader.c + * + * Flash loaders + */ + #include #include #include diff --git a/src/stlink-lib/flash_loader.h b/src/stlink-lib/flash_loader.h index 46cacba30..8888875a7 100644 --- a/src/stlink-lib/flash_loader.h +++ b/src/stlink-lib/flash_loader.h @@ -1,7 +1,7 @@ /* * File: flash_loader.h * - * Flash loader + * Flash loaders */ #ifndef FLASH_LOADER_H @@ -14,10 +14,10 @@ #include int32_t stlink_flash_loader_init(stlink_t *sl, flash_loader_t* fl); -static int32_t loader_v_dependent_assignment(stlink_t *sl, - const uint8_t **loader_code, size_t *loader_size, - const uint8_t *high_v_loader, size_t high_v_loader_size, - const uint8_t *low_v_loader, size_t low_v_loader_size); +// static int32_t loader_v_dependent_assignment(stlink_t *sl, +// const uint8_t **loader_code, size_t *loader_size, +// const uint8_t *high_v_loader, size_t high_v_loader_size, +// const uint8_t *low_v_loader, size_t low_v_loader_size); int32_t stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size); @@ -25,8 +25,8 @@ int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t t /* === Functions from old header file flashloader.h === */ int32_t stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint32_t pagesize); -static void set_flash_cr_pg(stlink_t *sl, uint32_t bank); -static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int32_t bckpRstr); +// static void set_flash_cr_pg(stlink_t *sl, uint32_t bank); +// static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int32_t bckpRstr); int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t *base, uint32_t len); int32_t stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl); diff --git a/src/stlink-lib/helper.c b/src/stlink-lib/helper.c index a6155925f..d7420691a 100644 --- a/src/stlink-lib/helper.c +++ b/src/stlink-lib/helper.c @@ -1,3 +1,9 @@ +/* + * File: helper.c + * + * General helper functions + */ + #include #include #include diff --git a/src/stlink-lib/helper.h b/src/stlink-lib/helper.h index dbd760a52..43a96368d 100644 --- a/src/stlink-lib/helper.h +++ b/src/stlink-lib/helper.h @@ -1,3 +1,9 @@ +/* + * File: helper.h + * + * General helper functions + */ + #ifndef HELPER_H #define HELPER_H diff --git a/src/stlink-lib/libusb_settings.h b/src/stlink-lib/libusb_settings.h index 3777f720b..b0a51ad31 100644 --- a/src/stlink-lib/libusb_settings.h +++ b/src/stlink-lib/libusb_settings.h @@ -1,3 +1,9 @@ +/* + * File: libusb_settings.h + * + * Settings for libusb library + */ + #ifndef LIBUSB_SETTINGS_H #define LIBUSB_SETTINGS_H diff --git a/src/stlink-lib/logging.c b/src/stlink-lib/logging.c index a64ec4ef2..1463eb925 100644 --- a/src/stlink-lib/logging.c +++ b/src/stlink-lib/logging.c @@ -1,8 +1,7 @@ /* * UglyLogging * - * Slow, yet another wheel reinvented, but enough to make the rest of our code - * pretty enough. + * Slow, yet another wheel reinvented, but enough to make the rest of our code pretty enough. */ #include diff --git a/src/stlink-lib/map_file.c b/src/stlink-lib/map_file.c index bb83ff7be..cfd2d1876 100644 --- a/src/stlink-lib/map_file.c +++ b/src/stlink-lib/map_file.c @@ -1,3 +1,9 @@ +/* + * File: map_file.c + * + * File mapping + */ + #include #include #include diff --git a/src/stlink-lib/md5.c b/src/stlink-lib/md5.c index 19ec86b91..f7af43ac3 100644 --- a/src/stlink-lib/md5.c +++ b/src/stlink-lib/md5.c @@ -5,6 +5,12 @@ * This is free and unencumbered software released into the public domain - June 2013 - waterjuice.org */ +/* + * File: md5.c + * + * MD5 hash function + */ + #include #include diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c index 3300ee15e..6a12333cd 100644 --- a/src/stlink-lib/option_bytes.c +++ b/src/stlink-lib/option_bytes.c @@ -1,3 +1,9 @@ +/* + * File: option_bytes.c + * + * Read and write option bytes and option control registers + */ + #include #include #include diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/register.h similarity index 98% rename from src/stlink-lib/reg.h rename to src/stlink-lib/register.h index c2976d050..7b63154c8 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/register.h @@ -1,5 +1,11 @@ -#ifndef REG_H -#define REG_H +/* + * File: register.h + * + * Common STM32 registers + */ + +#ifndef REGISTER_H +#define REGISTER_H #define STLINK_REG_CM3_CPUID 0xE000ED00 diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index c0f79c7cf..7c16a5336 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -74,6 +74,12 @@ * part to an existing options line for usb-storage). */ +/* + * File: sg.c + * + * + */ + #define __USE_GNU #include diff --git a/src/stlink-lib/sg.h b/src/stlink-lib/sg.h index d4792c49a..ce69f7a09 100644 --- a/src/stlink-lib/sg.h +++ b/src/stlink-lib/sg.h @@ -1,6 +1,7 @@ /* - * File: sg.h - * Author: karl + * File: sg.h + * + * */ #ifndef SG_H diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index d404c2e94..e9f45574f 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1,3 +1,9 @@ +/* + * File: usb.c + * + * + */ + #include #include #include diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index b5c1835ec..55d506c5b 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -1,6 +1,7 @@ /* - * File: usb.h - * Author: karl + * File: usb.h + * + * */ #ifndef USB_H From dbe13dedae12059fe5ee7b80848d564f82151f0e Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 7 Jun 2023 23:12:00 +0200 Subject: [PATCH 1379/1435] [doc] Added header comments for lib modules - common.c/.h - sg.c/.h - usb.c/.h --- src/stlink-lib/common.c | 9 +++++++++ src/stlink-lib/common.h | 5 ++++- src/stlink-lib/sg.c | 2 ++ src/stlink-lib/sg.h | 2 ++ src/stlink-lib/usb.c | 2 +- src/stlink-lib/usb.h | 2 +- 6 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index 43d2b9a9e..479aa4943 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -1,3 +1,12 @@ +/* == nightwalker-87: TODO: CONTENT AND USE OF THIS SOURCE FILE IS TO BE VERIFIED (07.06.2023) == */ +/* TODO: This file should be split up into new or existing modules. */ + +/* + * File: common.c + * + * + */ + #include #include #include diff --git a/src/stlink-lib/common.h b/src/stlink-lib/common.h index c60b49199..1f7e0804d 100644 --- a/src/stlink-lib/common.h +++ b/src/stlink-lib/common.h @@ -1,7 +1,10 @@ +/* == nightwalker-87: TODO: CONTENT AND USE OF THIS SOURCE FILE IS TO BE VERIFIED (07.06.2023) == */ +/* TODO: This file should be split up into new or existing modules. */ + /* * File: common.h * - * General helper functions + * */ #ifndef COMMON_H diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index 7c16a5336..4db8c6164 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -1,3 +1,5 @@ +/* == nightwalker-87: TODO: CONTENT AND USE OF THIS SOURCE FILE IS TO BE VERIFIED (07.06.2023) == */ + /* * Copyright (c) 2010 "Capt'ns Missing Link" Authors. All rights reserved. * Use of this source code is governed by a BSD-style diff --git a/src/stlink-lib/sg.h b/src/stlink-lib/sg.h index ce69f7a09..1ab433142 100644 --- a/src/stlink-lib/sg.h +++ b/src/stlink-lib/sg.h @@ -1,3 +1,5 @@ +/* == nightwalker-87: TODO: CONTENT AND USE OF THIS HEADER FILE IS TO BE VERIFIED (07.06.2023) == */ + /* * File: sg.h * diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index e9f45574f..9dc4a0ebd 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1,7 +1,7 @@ /* * File: usb.c * - * + * USB commands & interaction with ST-LINK devices */ #include diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index 55d506c5b..83c0c2481 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -1,7 +1,7 @@ /* * File: usb.h * - * + * USB commands & interaction with ST-LINK devices */ #ifndef USB_H From 67ae7a12d8636795f08f1004bf5cd26f596e1eee Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 9 Jun 2023 01:16:18 +0200 Subject: [PATCH 1380/1435] Added comments for testing modules --- README.md | 2 +- tests/flash.c | 2 ++ tests/sg.c | 2 ++ tests/usb.c | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e103ac301..6d188f0df 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ We recommend to install `stlink-tools` from the package repository of the used d - Alpine Linux: [(Link)](https://pkgs.alpinelinux.org/packages?name=stlink) - Fedora: [(Link)](https://src.fedoraproject.org/rpms/stlink) - FreeBSD: Users can install from [freshports](https://www.freshports.org/devel/stlink) -- MacOS: **Support for macOS will end with v1.7.1.** Please use v1.7.0 (current ***master*** branch) and the related documentation instead. +- MacOS: **Support for macOS will end with v1.8.0.** Please use v1.7.0 (current ***master*** branch) and the related documentation instead. ## Installation from source (advanced users) diff --git a/tests/flash.c b/tests/flash.c index f66428dcd..a40be0c74 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -1,3 +1,5 @@ +/* == nightwalker-87: TODO: CONTENT AND USE OF THIS SOURCE FILE IS TO BE VERIFIED (07.06.2023) == */ + #include #include #include diff --git a/tests/sg.c b/tests/sg.c index cd601b6d6..32dcd9a62 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -1,3 +1,5 @@ +/* == nightwalker-87: TODO: CONTENT AND USE OF THIS SOURCE FILE IS TO BE VERIFIED (07.06.2023) == */ + #include #include #include diff --git a/tests/usb.c b/tests/usb.c index 2d928e5f0..56f0d9c1f 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -1,3 +1,5 @@ +/* == nightwalker-87: TODO: CONTENT AND USE OF THIS SOURCE FILE IS TO BE VERIFIED (07.06.2023) == */ + #include #include #include From be2e7e3883646eadbda4e2a56bdb21f84c06444d Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 9 Jun 2023 01:28:22 +0200 Subject: [PATCH 1381/1435] [refactoring] Clean-up for stlink-lib - Ensure proper function declaration - Moved some functions to related modules - Checked & revised header includes - Renamed "md5" to "lib_md5" - New source file "md5" --- CMakeLists.txt | 3 +- inc/stlink.h | 18 +-- src/st-util/gdb-server.c | 3 +- src/stlink-gui/gui.c | 1 + src/stlink-lib/calculate.c | 1 + src/stlink-lib/chipid.c | 13 +- src/stlink-lib/chipid.h | 3 - src/stlink-lib/common.c | 86 +--------- src/stlink-lib/common.h | 23 --- src/stlink-lib/common_flash.c | 32 ++-- src/stlink-lib/common_flash.h | 43 +++-- src/stlink-lib/flash_loader.c | 9 +- src/stlink-lib/flash_loader.h | 4 - src/stlink-lib/helper.c | 15 +- src/stlink-lib/helper.h | 2 + src/stlink-lib/lib_md5.c | 280 ++++++++++++++++++++++++++++++++ src/stlink-lib/lib_md5.h | 68 ++++++++ src/stlink-lib/logging.c | 12 +- src/stlink-lib/logging.h | 3 + src/stlink-lib/map_file.c | 46 +++++- src/stlink-lib/map_file.h | 1 + src/stlink-lib/md5.c | 293 +++------------------------------- src/stlink-lib/md5.h | 63 +------- src/stlink-lib/option_bytes.c | 8 +- src/stlink-lib/option_bytes.h | 3 - src/stlink-lib/read_write.c | 2 + src/stlink-lib/sg.c | 14 +- src/stlink-lib/sg.h | 3 +- src/stlink-lib/usb.c | 25 +-- src/stlink-lib/usb.h | 2 - 30 files changed, 554 insertions(+), 525 deletions(-) delete mode 100644 src/stlink-lib/common.h create mode 100644 src/stlink-lib/lib_md5.c create mode 100644 src/stlink-lib/lib_md5.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ff18b815..2a82ea983 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -172,10 +172,10 @@ set(STLINK_HEADERS src/stlink-lib/chipid.h src/stlink-lib/commands.h src/stlink-lib/common_flash.h - src/stlink-lib/common.h src/stlink-lib/flash_loader.h src/stlink-lib/helper.h src/stlink-lib/libusb_settings.h + src/stlink-lib/lib_md5.h src/stlink-lib/logging.h src/stlink-lib/map_file.h src/stlink-lib/md5.h @@ -194,6 +194,7 @@ set(STLINK_SOURCE src/stlink-lib/helper.c src/stlink-lib/logging.c src/stlink-lib/map_file.c + src/stlink-lib/lib_md5.c src/stlink-lib/md5.c src/stlink-lib/option_bytes.c src/stlink-lib/read_write.c diff --git a/inc/stlink.h b/inc/stlink.h index 2ed34a074..b2516c90c 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -11,8 +11,8 @@ #include #include -#include "stm32.h" -#include "stm32flash.h" +#include +#include #ifdef __cplusplus extern "C" { @@ -263,24 +263,13 @@ int32_t stlink_set_swdclk(stlink_t *sl, int32_t freq_khz); int32_t stlink_trace_enable(stlink_t* sl, uint32_t frequency); int32_t stlink_trace_disable(stlink_t* sl); int32_t stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size); -int32_t stlink_erase_flash_mass(stlink_t* sl); -int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size); -int32_t stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); int32_t stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); uint8_t stlink_get_erased_pattern(stlink_t *sl); -int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); -int32_t stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); int32_t stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); int32_t stlink_fwrite_sram(stlink_t *sl, const char* path, stm32_addr_t addr); -int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length); - //int32_t stlink_chip_id(stlink_t *sl, uint32_t *chip_id); int32_t stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); - -int32_t stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); -int32_t stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size); -int32_t stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr); uint16_t read_uint16(const unsigned char *c, const int32_t pt); //void stlink_core_stat(stlink_t *sl); void stlink_print_data(stlink_t *sl); @@ -293,7 +282,6 @@ int32_t write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* bu int32_t write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int32_t stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); int32_t stlink_load_device_params(stlink_t *sl); - int32_t stlink_target_connect(stlink_t *sl, enum connect_type connect); #include @@ -301,8 +289,8 @@ int32_t stlink_target_connect(stlink_t *sl, enum connect_type connect); #include #include #include -#include #include +#include #include #ifdef __cplusplus diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 557a24f5f..431e37eec 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -29,7 +29,8 @@ #include #include #include -#include "flash_loader.h" +#include +#include #include "gdb-remote.h" #include "gdb-server.h" #include "semihosting.h" diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index f0426f577..f1e9382d0 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -5,6 +5,7 @@ #include #include +#include #include "gui.h" #define MEM_READ_SIZE 1024 diff --git a/src/stlink-lib/calculate.c b/src/stlink-lib/calculate.c index 2a708b551..b13a1c961 100644 --- a/src/stlink-lib/calculate.c +++ b/src/stlink-lib/calculate.c @@ -8,6 +8,7 @@ #include #include "calculate.h" + #include "common_flash.h" uint32_t calculate_F4_sectornum(uint32_t flashaddr) { diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 65ca2842a..c622abcbb 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -4,16 +4,19 @@ * Chip-ID parametres */ -#include -#include -#include #include +#include #include #include -#include "chipid.h" -#include #include +#include +#include "chipid.h" + +#include "logging.h" + +// #include // TODO: Check use +// #include // TODO: Check use static struct stlink_chipid_params *devicelist; diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index 9955811fa..d7319f569 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -9,9 +9,6 @@ #include -#include -#include - /* Chipid parametres */ struct stlink_chipid_params { char *dev_type; diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index 479aa4943..d6477281d 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -13,18 +13,20 @@ #include #include #include -#include -#include -#include +// #include // TODO: Check use +// #include // TODO: Check use #include -#include + #include "calculate.h" +#include "chipid.h" #include "common_flash.h" +#include "helper.h" +#include "logging.h" #include "map_file.h" #include "md5.h" - -#include "common.h" +#include "register.h" +#include "usb.h" #ifndef O_BINARY #define O_BINARY 0 @@ -1213,78 +1215,6 @@ void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { } } -/* Limit the block size to compare to 0x1800 as anything larger will stall the - * STLINK2 Maybe STLINK V1 needs smaller value! - */ -int32_t check_file(stlink_t *sl, mapped_file_t *mf, stm32_addr_t addr) { - size_t off; - size_t n_cmp = sl->flash_pgsz; - - if (n_cmp > 0x1800) { - n_cmp = 0x1800; - } - - for (off = 0; off < mf->len; off += n_cmp) { - size_t aligned_size; - - size_t cmp_size = n_cmp; // adjust last page size - - if ((off + n_cmp) > mf->len) { - cmp_size = mf->len - off; - } - - aligned_size = cmp_size; - - if (aligned_size & (4 - 1)) { - aligned_size = (cmp_size + 4) & ~(4 - 1); - } - - stlink_read_mem32(sl, addr + (uint32_t)off, (uint16_t)aligned_size); - - if (memcmp(sl->q_buf, mf->base + off, cmp_size)) { - return (-1); - } - } - - return (0); -} - -void md5_calculate(mapped_file_t *mf) { - // calculate md5 checksum of given binary file - Md5Context md5Context; - MD5_HASH md5Hash; - Md5Initialise(&md5Context); - Md5Update(&md5Context, mf->base, (uint32_t)mf->len); - Md5Finalise(&md5Context, &md5Hash); - printf("md5 checksum: "); - - for (int32_t i = 0; i < (int32_t)sizeof(md5Hash); i++) { - printf("%x", md5Hash.bytes[i]); - } - - printf(", "); -} - -void stlink_checksum(mapped_file_t *mp) { - /* checksum that backward compatible with official ST tools */ - uint32_t sum = 0; - uint8_t *mp_byte = (uint8_t *)mp->base; - - for (size_t i = 0; i < mp->len; ++i) { - sum += mp_byte[i]; - } - - printf("stlink checksum: 0x%08x\n", sum); -} - -void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { - uint32_t val; - // set PC to the reset routine - stlink_read_debug32(sl, addr + 4, &val); - stlink_write_reg(sl, val, 15); - stlink_run(sl, RUN_NORMAL); -} - static int32_t stlink_read(stlink_t *sl, stm32_addr_t addr, size_t size, save_block_fn fn, void *fn_arg) { diff --git a/src/stlink-lib/common.h b/src/stlink-lib/common.h deleted file mode 100644 index 1f7e0804d..000000000 --- a/src/stlink-lib/common.h +++ /dev/null @@ -1,23 +0,0 @@ -/* == nightwalker-87: TODO: CONTENT AND USE OF THIS SOURCE FILE IS TO BE VERIFIED (07.06.2023) == */ -/* TODO: This file should be split up into new or existing modules. */ - -/* - * File: common.h - * - * - */ - -#ifndef COMMON_H -#define COMMON_H - -#include - -#include "map_file.h" -#include "md5.h" - -int32_t check_file(stlink_t *, mapped_file_t *, stm32_addr_t); -void md5_calculate(mapped_file_t *); -void stlink_checksum(mapped_file_t *); -void stlink_fwrite_finalize(stlink_t *, stm32_addr_t); - -#endif // COMMON_H diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index d2063851f..6ade87311 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -5,16 +5,19 @@ */ #include + #include -#include #include +#include #include +#include "common_flash.h" + #include "calculate.h" #include "flash_loader.h" -#include "common_flash.h" +#include "logging.h" #include "map_file.h" -#include "common.h" +#include "md5.h" #define DEBUG_FLASH 0 @@ -742,6 +745,7 @@ void clear_flash_cr_pg(stlink_t *sl, uint32_t bank) { n = read_flash_cr(sl, bank) & ~(1 << bit); stlink_write_debug32(sl, cr_reg, n); } + /* ------------------------------------------------------------------------ */ static void wait_flash_busy_progress(stlink_t *sl) { @@ -1170,7 +1174,7 @@ int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t return (-1); } - fprintf(stdout, "-> Flash page at %#x erased (size: %#x)\n", addr, page_size); + fprintf(stdout, "-> Flash page at %#x erased (size: %#x)\r", addr, page_size); fflush(stdout); // check the next page is within the range to erase @@ -1232,8 +1236,7 @@ int32_t stlink_erase_flash_mass(stlink_t *sl) { return (err); } -int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, - stm32_addr_t addr) { +int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_addr_t addr) { /* Write the block in flash at addr */ int32_t err; uint32_t num_empty, idx; @@ -1416,12 +1419,10 @@ int32_t stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr) { return 0; } -int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, - uint32_t len, uint8_t eraseonly) { +int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint8_t eraseonly) { int32_t ret; flash_loader_t fl; - ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, - len, addr, addr); + ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr); // check addr range is inside the flash stlink_calculate_pagesize(sl, addr); @@ -1438,6 +1439,9 @@ int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, (uint32_t)(sl->flash_pgsz)); return (-1); } + if ((len % 16 <= 8) & (sl->flash_type == STM32_FLASH_TYPE_L5_U5)) { + len += 8; + } // make sure we've loaded the context with the chip details stlink_core_id(sl); @@ -1464,3 +1468,11 @@ int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, return (stlink_verify_write_flash(sl, addr, base, len)); } + +void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { + uint32_t val; + // set PC to the reset routine + stlink_read_debug32(sl, addr + 4, &val); + stlink_write_reg(sl, val, 15); + stlink_run(sl, RUN_NORMAL); +} diff --git a/src/stlink-lib/common_flash.h b/src/stlink-lib/common_flash.h index 04e9134b5..092bdcbf4 100644 --- a/src/stlink-lib/common_flash.h +++ b/src/stlink-lib/common_flash.h @@ -9,22 +9,45 @@ #include +#define BANK_1 0 +#define BANK_2 1 + +uint32_t get_stm32l0_flash_base(stlink_t *); +uint32_t read_flash_cr(stlink_t *, uint32_t); void lock_flash(stlink_t *); +// static inline int32_t write_flash_sr(stlink_t *sl, uint32_t bank, uint32_t val); void clear_flash_error(stlink_t *); +uint32_t read_flash_sr(stlink_t *sl, uint32_t bank); +uint32_t is_flash_busy(stlink_t *sl); void wait_flash_busy(stlink_t *); int32_t check_flash_error(stlink_t *); +// static inline uint32_t is_flash_locked(stlink_t *sl); +// static void unlock_flash(stlink_t *sl); int32_t unlock_flash_if(stlink_t *); int32_t lock_flash_option(stlink_t *); +// static bool is_flash_option_locked(stlink_t *sl); +// static int32_t unlock_flash_option(stlink_t *sl); int32_t unlock_flash_option_if(stlink_t *); -void write_flash_cr_psiz(stlink_t *, uint32_t, unsigned); -void clear_flash_cr_pg(stlink_t *, unsigned); - -// TODO: move to private defines if possible - -#define BANK_1 0 -#define BANK_2 1 - -uint32_t read_flash_cr(stlink_t *, unsigned); -uint32_t get_stm32l0_flash_base(stlink_t *); +void write_flash_cr_psiz(stlink_t *, uint32_t, uint32_t); +void clear_flash_cr_pg(stlink_t *, uint32_t); +// static void wait_flash_busy_progress(stlink_t *sl); +// static inline void write_flash_ar(stlink_t *sl, uint32_t n, uint32_t bank); +// static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, uint32_t bank); +// static void set_flash_cr_per(stlink_t *sl, uint32_t bank); +// static void clear_flash_cr_per(stlink_t *sl, uint32_t bank); +// static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n); +// static void set_flash_cr_strt(stlink_t *sl, uint32_t bank); +// static void set_flash_cr_mer(stlink_t *sl, bool v, uint32_t bank); +int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr); +int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size); +int32_t stlink_erase_flash_mass(stlink_t *sl); +int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_addr_t addr); +int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr); +int32_t stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr); +int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length); +int32_t stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size); +int32_t stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr); +int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint8_t eraseonly); +void stlink_fwrite_finalize(stlink_t *, stm32_addr_t); #endif // COMMON_FLASH_H diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 0f171d223..3472e2a61 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -11,9 +11,12 @@ #include #include -#include #include "flash_loader.h" + #include "common_flash.h" +#include "helper.h" +#include "logging.h" +#include "register.h" #define FLASH_REGS_BANK2_OFS 0x40 #define FLASH_BANK2_START_ADDR 0x08080000 @@ -757,7 +760,9 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t fflush(stdout); } - write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); + // write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); + data = 0; + memcpy(&data, base + off, (len - off) < 4 ? (len - off) : 4); stlink_write_debug32(sl, addr + (uint32_t)off, data); wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear } diff --git a/src/stlink-lib/flash_loader.h b/src/stlink-lib/flash_loader.h index 8888875a7..61a2a0c19 100644 --- a/src/stlink-lib/flash_loader.h +++ b/src/stlink-lib/flash_loader.h @@ -8,10 +8,6 @@ #define FLASH_LOADER_H #include -#include -#include - -#include int32_t stlink_flash_loader_init(stlink_t *sl, flash_loader_t* fl); // static int32_t loader_v_dependent_assignment(stlink_t *sl, diff --git a/src/stlink-lib/helper.c b/src/stlink-lib/helper.c index d7420691a..97d6eb316 100644 --- a/src/stlink-lib/helper.c +++ b/src/stlink-lib/helper.c @@ -1,21 +1,22 @@ +/* == nightwalker-87: TODO: CONTENT AND USE OF THIS SOURCE FILE IS TO BE VERIFIED (07.06.2023) == */ + /* * File: helper.c * * General helper functions */ - -#include -#include -#include - -#include "helper.h" - #ifdef STLINK_HAVE_SYS_TIME_H #include #else #include #endif +#include +#include +#include + +#include "helper.h" + uint32_t time_ms() { struct timeval tv; gettimeofday(&tv, NULL); diff --git a/src/stlink-lib/helper.h b/src/stlink-lib/helper.h index 43a96368d..a42fd480e 100644 --- a/src/stlink-lib/helper.h +++ b/src/stlink-lib/helper.h @@ -1,3 +1,5 @@ +/* == nightwalker-87: TODO: CONTENT AND USE OF THIS SOURCE FILE IS TO BE VERIFIED (07.06.2023) == */ + /* * File: helper.h * diff --git a/src/stlink-lib/lib_md5.c b/src/stlink-lib/lib_md5.c new file mode 100644 index 000000000..42f337ac3 --- /dev/null +++ b/src/stlink-lib/lib_md5.c @@ -0,0 +1,280 @@ +/* + * WjCryptLib_Md5 (https://github.com/WaterJuice/WjCryptLib) + * Implementation of MD5 hash function. Originally written by Alexander Peslyak. + * Modified by WaterJuice retaining Public Domain license. + * This is free and unencumbered software released into the public domain - June 2013 - waterjuice.org + */ + +#include +#include + +#include "lib_md5.h" + +/* INTERNAL FUNCTIONS */ + +/* F, G, H, I + * + * The basic MD5 functions. + * F and G are optimised compared to their RFC 1321 definitions for architectures + * that lack an AND-NOT instruction, just like in Colin Plumb's implementation. + */ +#define F( x, y, z ) ((z) ^ ((x) & ((y) ^ (z)))) +#define G( x, y, z ) ((y) ^ ((z) & ((x) ^ (y)))) +#define H( x, y, z ) ((x) ^ (y) ^ (z)) +#define I( x, y, z ) ((y) ^ ((x) | ~(z))) + +/* STEP: The MD5 transformation for all four rounds. */ +#define STEP( f, a, b, c, d, x, t, s ) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); + +/* TransformFunction + * This processes one or more 64-byte data blocks, but does NOT update the bit counters. + * There are no alignment requirements. + */ +static void* TransformFunction(Md5Context* ctx, void const* data, uintmax_t size) { + uint8_t* ptr; + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; + uint32_t saved_a; + uint32_t saved_b; + uint32_t saved_c; + uint32_t saved_d; + + #define GET(n) (ctx->block[(n)]) + #define SET(n) (ctx->block[(n)] = ((uint32_t)ptr[(n) * 4 + 0] << 0) | \ + ((uint32_t)ptr[(n) * 4 + 1] << 8) | \ + ((uint32_t)ptr[(n) * 4 + 2] << 16) | \ + ((uint32_t)ptr[(n) * 4 + 3] << 24)) + + ptr = (uint8_t*)data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + + // Round 1 + STEP( F, a, b, c, d, SET(0), 0xd76aa478, 7 ) + STEP( F, d, a, b, c, SET(1), 0xe8c7b756, 12 ) + STEP( F, c, d, a, b, SET(2), 0x242070db, 17 ) + STEP( F, b, c, d, a, SET(3), 0xc1bdceee, 22 ) + STEP( F, a, b, c, d, SET(4), 0xf57c0faf, 7 ) + STEP( F, d, a, b, c, SET(5), 0x4787c62a, 12 ) + STEP( F, c, d, a, b, SET(6), 0xa8304613, 17 ) + STEP( F, b, c, d, a, SET(7), 0xfd469501, 22 ) + STEP( F, a, b, c, d, SET(8 ), 0x698098d8, 7 ) + STEP( F, d, a, b, c, SET(9 ), 0x8b44f7af, 12 ) + STEP( F, c, d, a, b, SET(10 ), 0xffff5bb1, 17 ) + STEP( F, b, c, d, a, SET(11 ), 0x895cd7be, 22 ) + STEP( F, a, b, c, d, SET(12 ), 0x6b901122, 7 ) + STEP( F, d, a, b, c, SET(13 ), 0xfd987193, 12 ) + STEP( F, c, d, a, b, SET(14 ), 0xa679438e, 17 ) + STEP( F, b, c, d, a, SET(15 ), 0x49b40821, 22 ) + + // Round 2 + STEP( G, a, b, c, d, GET(1), 0xf61e2562, 5 ) + STEP( G, d, a, b, c, GET(6), 0xc040b340, 9 ) + STEP( G, c, d, a, b, GET(11), 0x265e5a51, 14 ) + STEP( G, b, c, d, a, GET(0), 0xe9b6c7aa, 20 ) + STEP( G, a, b, c, d, GET(5), 0xd62f105d, 5 ) + STEP( G, d, a, b, c, GET(10), 0x02441453, 9 ) + STEP( G, c, d, a, b, GET(15), 0xd8a1e681, 14 ) + STEP( G, b, c, d, a, GET(4), 0xe7d3fbc8, 20 ) + STEP( G, a, b, c, d, GET(9), 0x21e1cde6, 5 ) + STEP( G, d, a, b, c, GET(14), 0xc33707d6, 9 ) + STEP( G, c, d, a, b, GET(3), 0xf4d50d87, 14 ) + STEP( G, b, c, d, a, GET(8), 0x455a14ed, 20 ) + STEP( G, a, b, c, d, GET(13), 0xa9e3e905, 5 ) + STEP( G, d, a, b, c, GET(2), 0xfcefa3f8, 9 ) + STEP( G, c, d, a, b, GET(7), 0x676f02d9, 14 ) + STEP( G, b, c, d, a, GET(12), 0x8d2a4c8a, 20 ) + + // Round 3 + STEP( H, a, b, c, d, GET(5), 0xfffa3942, 4 ) + STEP( H, d, a, b, c, GET(8), 0x8771f681, 11 ) + STEP( H, c, d, a, b, GET(11), 0x6d9d6122, 16 ) + STEP( H, b, c, d, a, GET(14), 0xfde5380c, 23 ) + STEP( H, a, b, c, d, GET(1), 0xa4beea44, 4 ) + STEP( H, d, a, b, c, GET(4), 0x4bdecfa9, 11 ) + STEP( H, c, d, a, b, GET(7), 0xf6bb4b60, 16 ) + STEP( H, b, c, d, a, GET(10), 0xbebfbc70, 23 ) + STEP( H, a, b, c, d, GET(13), 0x289b7ec6, 4 ) + STEP( H, d, a, b, c, GET(0), 0xeaa127fa, 11 ) + STEP( H, c, d, a, b, GET(3), 0xd4ef3085, 16 ) + STEP( H, b, c, d, a, GET(6), 0x04881d05, 23 ) + STEP( H, a, b, c, d, GET(9), 0xd9d4d039, 4 ) + STEP( H, d, a, b, c, GET(12), 0xe6db99e5, 11 ) + STEP( H, c, d, a, b, GET(15), 0x1fa27cf8, 16 ) + STEP( H, b, c, d, a, GET(2), 0xc4ac5665, 23 ) + + // Round 4 + STEP( I, a, b, c, d, GET(0), 0xf4292244, 6 ) + STEP( I, d, a, b, c, GET(7), 0x432aff97, 10 ) + STEP( I, c, d, a, b, GET(14), 0xab9423a7, 15 ) + STEP( I, b, c, d, a, GET(5), 0xfc93a039, 21 ) + STEP( I, a, b, c, d, GET(12), 0x655b59c3, 6 ) + STEP( I, d, a, b, c, GET(3), 0x8f0ccc92, 10 ) + STEP( I, c, d, a, b, GET(10), 0xffeff47d, 15 ) + STEP( I, b, c, d, a, GET(1), 0x85845dd1, 21 ) + STEP( I, a, b, c, d, GET(8), 0x6fa87e4f, 6 ) + STEP( I, d, a, b, c, GET(15), 0xfe2ce6e0, 10 ) + STEP( I, c, d, a, b, GET(6), 0xa3014314, 15 ) + STEP( I, b, c, d, a, GET(13), 0x4e0811a1, 21 ) + STEP( I, a, b, c, d, GET(4), 0xf7537e82, 6 ) + STEP( I, d, a, b, c, GET(11), 0xbd3af235, 10 ) + STEP( I, c, d, a, b, GET(2), 0x2ad7d2bb, 15 ) + STEP( I, b, c, d, a, GET(9), 0xeb86d391, 21 ) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while ( size -= 64 ); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + + #undef GET + #undef SET + + return(ptr); +} + +/* EXPORTED FUNCTIONS */ + +/* Md5Initialise + * Initialises an MD5 Context. + * Use this to initialise/reset a context. + */ +void Md5Initialise(Md5Context* Context /* [out] */) { + Context->a = 0x67452301; + Context->b = 0xefcdab89; + Context->c = 0x98badcfe; + Context->d = 0x10325476; + + Context->lo = 0; + Context->hi = 0; +} + +/* Md5Update + * Adds data to the MD5 context. + * This will process the data and update the internal state of the context. + * Keep on calling this function until all the data has been added. + * Then call Md5Finalise to calculate the hash. + */ +void Md5Update(Md5Context* Context /* [in out] */, void const* Buffer /* [in] */, uint32_t BufferSize /* [in] */) { + uint32_t saved_lo; + uint32_t used; + uint32_t free; + + saved_lo = Context->lo; + + if ((Context->lo = (saved_lo + BufferSize) & 0x1fffffff) < saved_lo) { + Context->hi++; + } + + Context->hi += (uint32_t)(BufferSize >> 29); + + used = saved_lo & 0x3f; + + if ( used ) { + free = 64 - used; + + if ( BufferSize < free ) { + memcpy( &Context->buffer[used], Buffer, BufferSize ); + return; + } + + memcpy( &Context->buffer[used], Buffer, free ); + Buffer = (uint8_t*)Buffer + free; + BufferSize -= free; + TransformFunction(Context, Context->buffer, 64); + } + + if ( BufferSize >= 64 ) { + Buffer = TransformFunction( Context, Buffer, BufferSize & ~(uint32_t)0x3f ); + BufferSize &= 0x3f; + } + + memcpy( Context->buffer, Buffer, BufferSize ); +} + +/* Md5Finalise + * Performs the final calculation of the hash and returns the digest + * (16 byte buffer containing 128bit hash). + * After calling this, Md5Initialised must be used to reuse the context. + */ +void Md5Finalise(Md5Context* Context /* [in out] */, MD5_HASH* Digest /* [in] */) { + uint32_t used; + uint32_t free; + + used = Context->lo & 0x3f; + + Context->buffer[used++] = 0x80; + + free = 64 - used; + + if (free < 8) { + memset( &Context->buffer[used], 0, free ); + TransformFunction( Context, Context->buffer, 64 ); + used = 0; + free = 64; + } + + memset( &Context->buffer[used], 0, free - 8 ); + + Context->lo <<= 3; + Context->buffer[56] = (uint8_t)(Context->lo); + Context->buffer[57] = (uint8_t)(Context->lo >> 8); + Context->buffer[58] = (uint8_t)(Context->lo >> 16); + Context->buffer[59] = (uint8_t)(Context->lo >> 24); + Context->buffer[60] = (uint8_t)(Context->hi); + Context->buffer[61] = (uint8_t)(Context->hi >> 8); + Context->buffer[62] = (uint8_t)(Context->hi >> 16); + Context->buffer[63] = (uint8_t)(Context->hi >> 24); + + TransformFunction( Context, Context->buffer, 64 ); + + Digest->bytes[0] = (uint8_t)(Context->a); + Digest->bytes[1] = (uint8_t)(Context->a >> 8); + Digest->bytes[2] = (uint8_t)(Context->a >> 16); + Digest->bytes[3] = (uint8_t)(Context->a >> 24); + Digest->bytes[4] = (uint8_t)(Context->b); + Digest->bytes[5] = (uint8_t)(Context->b >> 8); + Digest->bytes[6] = (uint8_t)(Context->b >> 16); + Digest->bytes[7] = (uint8_t)(Context->b >> 24); + Digest->bytes[8] = (uint8_t)(Context->c); + Digest->bytes[9] = (uint8_t)(Context->c >> 8); + Digest->bytes[10] = (uint8_t)(Context->c >> 16); + Digest->bytes[11] = (uint8_t)(Context->c >> 24); + Digest->bytes[12] = (uint8_t)(Context->d); + Digest->bytes[13] = (uint8_t)(Context->d >> 8); + Digest->bytes[14] = (uint8_t)(Context->d >> 16); + Digest->bytes[15] = (uint8_t)(Context->d >> 24); +} + +/* Md5Calculate + * Combines Md5Initialise, Md5Update, and Md5Finalise into one function. + * Calculates the MD5 hash of the buffer. + */ +void Md5Calculate(void const* Buffer /* [in] */, uint32_t BufferSize /* [in] */, MD5_HASH* Digest /* [in] */) { + Md5Context context; + + Md5Initialise( &context ); + Md5Update( &context, Buffer, BufferSize ); + Md5Finalise( &context, Digest ); +} diff --git a/src/stlink-lib/lib_md5.h b/src/stlink-lib/lib_md5.h new file mode 100644 index 000000000..abe1131ae --- /dev/null +++ b/src/stlink-lib/lib_md5.h @@ -0,0 +1,68 @@ +/* + * WjCryptLib_Md5 (https://github.com/WaterJuice/WjCryptLib) + * Implementation of MD5 hash function. Originally written by Alexander Peslyak. + * Modified by WaterJuice retaining Public Domain license. + * This is free and unencumbered software released into the public domain - June 2013 - waterjuice.org + */ + +#ifndef LIB_MD5_H +#define LIB_MD5_H + +#pragma once + +#include +#include + +/* TYPES */ + +/* Md5Context + * This must be initialised using Md5Initialised. + * Do not modify the contents of this structure directly. + */ +typedef struct { + uint32_t lo; + uint32_t hi; + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; + uint8_t buffer[64]; + uint32_t block[16]; +} Md5Context; + +#define MD5_HASH_SIZE (128 / 8) + +typedef struct { + uint8_t bytes [MD5_HASH_SIZE]; +} MD5_HASH; + +/* PUBLIC FUNCTIONS */ + +/* Md5Initialise + * Initialises an MD5 Context. + * Use this to initialise/reset a context. + */ +void Md5Initialise(Md5Context* Context /* [out] */); + +/* Md5Update + * Adds data to the MD5 context. + * This will process the data and update the internal state of the context. + * Keep on calling this function until all the data has been added. + * Then call Md5Finalise to calculate the hash. + */ +void Md5Update(Md5Context* Context /* [in out] */, void const* Buffer /* [in] */, uint32_t BufferSize /* [in] */); + +/* Md5Finalise + * Performs the final calculation of the hash and returns the digest + * (16 byte buffer containing 128bit hash). + * After calling this, Md5Initialised must be used to reuse the context. + */ +void Md5Finalise(Md5Context* Context /* [in out] */, MD5_HASH* Digest /* [in] */); + +/* Md5Calculate + * Combines Md5Initialise, Md5Update, and Md5Finalise into one function. + * Calculates the MD5 hash of the buffer. + */ +void Md5Calculate(void const* Buffer /* [in] */, uint32_t BufferSize /* [in] */, MD5_HASH* Digest /* [in] */); + +#endif // LIB_MD5_H \ No newline at end of file diff --git a/src/stlink-lib/logging.c b/src/stlink-lib/logging.c index 1463eb925..92092f3d0 100644 --- a/src/stlink-lib/logging.c +++ b/src/stlink-lib/logging.c @@ -1,15 +1,15 @@ /* - * UglyLogging + * File: logging.c * - * Slow, yet another wheel reinvented, but enough to make the rest of our code pretty enough. + * UglyLogging: Slow, yet another wheel reinvented, but enough to make the rest of our code pretty enough. */ -#include -#include +#define __STDC_WANT_LIB_EXT1__ 1 + #include #include -#include -#define __STDC_WANT_LIB_EXT1__ 1 + +#include #include #include "logging.h" diff --git a/src/stlink-lib/logging.h b/src/stlink-lib/logging.h index 471933096..d07db797d 100644 --- a/src/stlink-lib/logging.h +++ b/src/stlink-lib/logging.h @@ -1,4 +1,7 @@ /* + * File: logging.h + * + * UglyLogging: Slow, yet another wheel reinvented, but enough to make the rest of our code pretty enough. * Ugly, low performance, configurable level, logging "framework" */ diff --git a/src/stlink-lib/map_file.c b/src/stlink-lib/map_file.c index cfd2d1876..5e3d14a5d 100644 --- a/src/stlink-lib/map_file.c +++ b/src/stlink-lib/map_file.c @@ -4,24 +4,62 @@ * File mapping */ -#include #include +#include +#include + +#include #include #include #include -#include "logging.h" #include "map_file.h" -#include "md5.h" #ifndef O_BINARY #define O_BINARY 0 #endif +// 1 GB max file size #ifndef MAX_FILE_SIZE -#define MAX_FILE_SIZE (1<<20) // 1 GB max file size +#define MAX_FILE_SIZE (1<<20) #endif +/* Limit the block size to compare to 0x1800 as anything larger will stall the + * STLINK2 Maybe STLINK V1 needs smaller value! + */ +int32_t check_file(stlink_t *sl, mapped_file_t *mf, stm32_addr_t addr) { + size_t off; + size_t n_cmp = sl->flash_pgsz; + + if (n_cmp > 0x1800) { + n_cmp = 0x1800; + } + + for (off = 0; off < mf->len; off += n_cmp) { + size_t aligned_size; + + size_t cmp_size = n_cmp; // adjust last page size + + if ((off + n_cmp) > mf->len) { + cmp_size = mf->len - off; + } + + aligned_size = cmp_size; + + if (aligned_size & (4 - 1)) { + aligned_size = (cmp_size + 4) & ~(4 - 1); + } + + stlink_read_mem32(sl, addr + (uint32_t)off, (uint16_t)aligned_size); + + if (memcmp(sl->q_buf, mf->base + off, cmp_size)) { + return (-1); + } + } + + return (0); +} + int32_t map_file(mapped_file_t *mf, const char *path) { int32_t error = -1; struct stat st; diff --git a/src/stlink-lib/map_file.h b/src/stlink-lib/map_file.h index b33ebf5db..ddedad93c 100644 --- a/src/stlink-lib/map_file.h +++ b/src/stlink-lib/map_file.h @@ -28,6 +28,7 @@ typedef struct mapped_file { #define MAPPED_FILE_INITIALIZER \ { NULL, 0 } +int32_t check_file(stlink_t *, mapped_file_t *, stm32_addr_t); int32_t map_file(mapped_file_t *, const char *); void unmap_file(mapped_file_t *); diff --git a/src/stlink-lib/md5.c b/src/stlink-lib/md5.c index f7af43ac3..070d9af91 100644 --- a/src/stlink-lib/md5.c +++ b/src/stlink-lib/md5.c @@ -1,10 +1,3 @@ -/* - * WjCryptLib_Md5 (https://github.com/WaterJuice/WjCryptLib) - * Implementation of MD5 hash function. Originally written by Alexander Peslyak. - * Modified by WaterJuice retaining Public Domain license. - * This is free and unencumbered software released into the public domain - June 2013 - waterjuice.org - */ - /* * File: md5.c * @@ -12,275 +5,37 @@ */ #include -#include +#include #include "md5.h" -/* INTERNAL FUNCTIONS */ - -/* F, G, H, I - * - * The basic MD5 functions. - * F and G are optimised compared to their RFC 1321 definitions for architectures - * that lack an AND-NOT instruction, just like in Colin Plumb's implementation. - */ -#define F( x, y, z ) ((z) ^ ((x) & ((y) ^ (z)))) -#define G( x, y, z ) ((y) ^ ((z) & ((x) ^ (y)))) -#define H( x, y, z ) ((x) ^ (y) ^ (z)) -#define I( x, y, z ) ((y) ^ ((x) | ~(z))) - -/* STEP: The MD5 transformation for all four rounds. */ -#define STEP( f, a, b, c, d, x, t, s ) \ - (a) += f((b), (c), (d)) + (x) + (t); \ - (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ - (a) += (b); - -/* TransformFunction - * This processes one or more 64-byte data blocks, but does NOT update the bit counters. - * There are no alignment requirements. - */ -static void* TransformFunction(Md5Context* ctx, void const* data, uintmax_t size) { - uint8_t* ptr; - uint32_t a; - uint32_t b; - uint32_t c; - uint32_t d; - uint32_t saved_a; - uint32_t saved_b; - uint32_t saved_c; - uint32_t saved_d; - - #define GET(n) (ctx->block[(n)]) - #define SET(n) (ctx->block[(n)] = ((uint32_t)ptr[(n) * 4 + 0] << 0) | \ - ((uint32_t)ptr[(n) * 4 + 1] << 8) | \ - ((uint32_t)ptr[(n) * 4 + 2] << 16) | \ - ((uint32_t)ptr[(n) * 4 + 3] << 24)) - - ptr = (uint8_t*)data; - - a = ctx->a; - b = ctx->b; - c = ctx->c; - d = ctx->d; - - do { - saved_a = a; - saved_b = b; - saved_c = c; - saved_d = d; - - // Round 1 - STEP( F, a, b, c, d, SET(0), 0xd76aa478, 7 ) - STEP( F, d, a, b, c, SET(1), 0xe8c7b756, 12 ) - STEP( F, c, d, a, b, SET(2), 0x242070db, 17 ) - STEP( F, b, c, d, a, SET(3), 0xc1bdceee, 22 ) - STEP( F, a, b, c, d, SET(4), 0xf57c0faf, 7 ) - STEP( F, d, a, b, c, SET(5), 0x4787c62a, 12 ) - STEP( F, c, d, a, b, SET(6), 0xa8304613, 17 ) - STEP( F, b, c, d, a, SET(7), 0xfd469501, 22 ) - STEP( F, a, b, c, d, SET(8 ), 0x698098d8, 7 ) - STEP( F, d, a, b, c, SET(9 ), 0x8b44f7af, 12 ) - STEP( F, c, d, a, b, SET(10 ), 0xffff5bb1, 17 ) - STEP( F, b, c, d, a, SET(11 ), 0x895cd7be, 22 ) - STEP( F, a, b, c, d, SET(12 ), 0x6b901122, 7 ) - STEP( F, d, a, b, c, SET(13 ), 0xfd987193, 12 ) - STEP( F, c, d, a, b, SET(14 ), 0xa679438e, 17 ) - STEP( F, b, c, d, a, SET(15 ), 0x49b40821, 22 ) - - // Round 2 - STEP( G, a, b, c, d, GET(1), 0xf61e2562, 5 ) - STEP( G, d, a, b, c, GET(6), 0xc040b340, 9 ) - STEP( G, c, d, a, b, GET(11), 0x265e5a51, 14 ) - STEP( G, b, c, d, a, GET(0), 0xe9b6c7aa, 20 ) - STEP( G, a, b, c, d, GET(5), 0xd62f105d, 5 ) - STEP( G, d, a, b, c, GET(10), 0x02441453, 9 ) - STEP( G, c, d, a, b, GET(15), 0xd8a1e681, 14 ) - STEP( G, b, c, d, a, GET(4), 0xe7d3fbc8, 20 ) - STEP( G, a, b, c, d, GET(9), 0x21e1cde6, 5 ) - STEP( G, d, a, b, c, GET(14), 0xc33707d6, 9 ) - STEP( G, c, d, a, b, GET(3), 0xf4d50d87, 14 ) - STEP( G, b, c, d, a, GET(8), 0x455a14ed, 20 ) - STEP( G, a, b, c, d, GET(13), 0xa9e3e905, 5 ) - STEP( G, d, a, b, c, GET(2), 0xfcefa3f8, 9 ) - STEP( G, c, d, a, b, GET(7), 0x676f02d9, 14 ) - STEP( G, b, c, d, a, GET(12), 0x8d2a4c8a, 20 ) - - // Round 3 - STEP( H, a, b, c, d, GET(5), 0xfffa3942, 4 ) - STEP( H, d, a, b, c, GET(8), 0x8771f681, 11 ) - STEP( H, c, d, a, b, GET(11), 0x6d9d6122, 16 ) - STEP( H, b, c, d, a, GET(14), 0xfde5380c, 23 ) - STEP( H, a, b, c, d, GET(1), 0xa4beea44, 4 ) - STEP( H, d, a, b, c, GET(4), 0x4bdecfa9, 11 ) - STEP( H, c, d, a, b, GET(7), 0xf6bb4b60, 16 ) - STEP( H, b, c, d, a, GET(10), 0xbebfbc70, 23 ) - STEP( H, a, b, c, d, GET(13), 0x289b7ec6, 4 ) - STEP( H, d, a, b, c, GET(0), 0xeaa127fa, 11 ) - STEP( H, c, d, a, b, GET(3), 0xd4ef3085, 16 ) - STEP( H, b, c, d, a, GET(6), 0x04881d05, 23 ) - STEP( H, a, b, c, d, GET(9), 0xd9d4d039, 4 ) - STEP( H, d, a, b, c, GET(12), 0xe6db99e5, 11 ) - STEP( H, c, d, a, b, GET(15), 0x1fa27cf8, 16 ) - STEP( H, b, c, d, a, GET(2), 0xc4ac5665, 23 ) - - // Round 4 - STEP( I, a, b, c, d, GET(0), 0xf4292244, 6 ) - STEP( I, d, a, b, c, GET(7), 0x432aff97, 10 ) - STEP( I, c, d, a, b, GET(14), 0xab9423a7, 15 ) - STEP( I, b, c, d, a, GET(5), 0xfc93a039, 21 ) - STEP( I, a, b, c, d, GET(12), 0x655b59c3, 6 ) - STEP( I, d, a, b, c, GET(3), 0x8f0ccc92, 10 ) - STEP( I, c, d, a, b, GET(10), 0xffeff47d, 15 ) - STEP( I, b, c, d, a, GET(1), 0x85845dd1, 21 ) - STEP( I, a, b, c, d, GET(8), 0x6fa87e4f, 6 ) - STEP( I, d, a, b, c, GET(15), 0xfe2ce6e0, 10 ) - STEP( I, c, d, a, b, GET(6), 0xa3014314, 15 ) - STEP( I, b, c, d, a, GET(13), 0x4e0811a1, 21 ) - STEP( I, a, b, c, d, GET(4), 0xf7537e82, 6 ) - STEP( I, d, a, b, c, GET(11), 0xbd3af235, 10 ) - STEP( I, c, d, a, b, GET(2), 0x2ad7d2bb, 15 ) - STEP( I, b, c, d, a, GET(9), 0xeb86d391, 21 ) - - a += saved_a; - b += saved_b; - c += saved_c; - d += saved_d; - - ptr += 64; - } while ( size -= 64 ); - - ctx->a = a; - ctx->b = b; - ctx->c = c; - ctx->d = d; - - #undef GET - #undef SET - - return(ptr); -} - -/* EXPORTED FUNCTIONS */ +#include "map_file.h" +#include "lib_md5.h" -/* Md5Initialise - * Initialises an MD5 Context. - * Use this to initialise/reset a context. - */ -void Md5Initialise(Md5Context* Context /* [out] */) { - Context->a = 0x67452301; - Context->b = 0xefcdab89; - Context->c = 0x98badcfe; - Context->d = 0x10325476; - - Context->lo = 0; - Context->hi = 0; -} - -/* Md5Update - * Adds data to the MD5 context. - * This will process the data and update the internal state of the context. - * Keep on calling this function until all the data has been added. - * Then call Md5Finalise to calculate the hash. - */ -void Md5Update(Md5Context* Context /* [in out] */, void const* Buffer /* [in] */, uint32_t BufferSize /* [in] */) { - uint32_t saved_lo; - uint32_t used; - uint32_t free; - - saved_lo = Context->lo; - - if ((Context->lo = (saved_lo + BufferSize) & 0x1fffffff) < saved_lo) { - Context->hi++; - } - - Context->hi += (uint32_t)(BufferSize >> 29); - - used = saved_lo & 0x3f; - - if ( used ) { - free = 64 - used; - - if ( BufferSize < free ) { - memcpy( &Context->buffer[used], Buffer, BufferSize ); - return; - } - - memcpy( &Context->buffer[used], Buffer, free ); - Buffer = (uint8_t*)Buffer + free; - BufferSize -= free; - TransformFunction(Context, Context->buffer, 64); - } +void md5_calculate(mapped_file_t *mf) { + // calculate md5 checksum of given binary file + Md5Context md5Context; + MD5_HASH md5Hash; + Md5Initialise(&md5Context); + Md5Update(&md5Context, mf->base, (uint32_t)mf->len); + Md5Finalise(&md5Context, &md5Hash); + printf("md5 checksum: "); - if ( BufferSize >= 64 ) { - Buffer = TransformFunction( Context, Buffer, BufferSize & ~(uint32_t)0x3f ); - BufferSize &= 0x3f; - } + for (int32_t i = 0; i < (int32_t)sizeof(md5Hash); i++) { + printf("%x", md5Hash.bytes[i]); + } - memcpy( Context->buffer, Buffer, BufferSize ); + printf(", "); } -/* Md5Finalise - * Performs the final calculation of the hash and returns the digest - * (16 byte buffer containing 128bit hash). - * After calling this, Md5Initialised must be used to reuse the context. - */ -void Md5Finalise(Md5Context* Context /* [in out] */, MD5_HASH* Digest /* [in] */) { - uint32_t used; - uint32_t free; - - used = Context->lo & 0x3f; - - Context->buffer[used++] = 0x80; - - free = 64 - used; - - if (free < 8) { - memset( &Context->buffer[used], 0, free ); - TransformFunction( Context, Context->buffer, 64 ); - used = 0; - free = 64; - } - - memset( &Context->buffer[used], 0, free - 8 ); +void stlink_checksum(mapped_file_t *mp) { + /* checksum that backward compatible with official ST tools */ + uint32_t sum = 0; + uint8_t *mp_byte = (uint8_t *)mp->base; - Context->lo <<= 3; - Context->buffer[56] = (uint8_t)(Context->lo); - Context->buffer[57] = (uint8_t)(Context->lo >> 8); - Context->buffer[58] = (uint8_t)(Context->lo >> 16); - Context->buffer[59] = (uint8_t)(Context->lo >> 24); - Context->buffer[60] = (uint8_t)(Context->hi); - Context->buffer[61] = (uint8_t)(Context->hi >> 8); - Context->buffer[62] = (uint8_t)(Context->hi >> 16); - Context->buffer[63] = (uint8_t)(Context->hi >> 24); + for (size_t i = 0; i < mp->len; ++i) { + sum += mp_byte[i]; + } - TransformFunction( Context, Context->buffer, 64 ); - - Digest->bytes[0] = (uint8_t)(Context->a); - Digest->bytes[1] = (uint8_t)(Context->a >> 8); - Digest->bytes[2] = (uint8_t)(Context->a >> 16); - Digest->bytes[3] = (uint8_t)(Context->a >> 24); - Digest->bytes[4] = (uint8_t)(Context->b); - Digest->bytes[5] = (uint8_t)(Context->b >> 8); - Digest->bytes[6] = (uint8_t)(Context->b >> 16); - Digest->bytes[7] = (uint8_t)(Context->b >> 24); - Digest->bytes[8] = (uint8_t)(Context->c); - Digest->bytes[9] = (uint8_t)(Context->c >> 8); - Digest->bytes[10] = (uint8_t)(Context->c >> 16); - Digest->bytes[11] = (uint8_t)(Context->c >> 24); - Digest->bytes[12] = (uint8_t)(Context->d); - Digest->bytes[13] = (uint8_t)(Context->d >> 8); - Digest->bytes[14] = (uint8_t)(Context->d >> 16); - Digest->bytes[15] = (uint8_t)(Context->d >> 24); -} - -/* Md5Calculate - * Combines Md5Initialise, Md5Update, and Md5Finalise into one function. - * Calculates the MD5 hash of the buffer. - */ -void Md5Calculate(void const* Buffer /* [in] */, uint32_t BufferSize /* [in] */, MD5_HASH* Digest /* [in] */) { - Md5Context context; - - Md5Initialise( &context ); - Md5Update( &context, Buffer, BufferSize ); - Md5Finalise( &context, Digest ); -} + printf("stlink checksum: 0x%08x\n", sum); +} \ No newline at end of file diff --git a/src/stlink-lib/md5.h b/src/stlink-lib/md5.h index 23c5d971b..eb36d64cc 100644 --- a/src/stlink-lib/md5.h +++ b/src/stlink-lib/md5.h @@ -1,10 +1,3 @@ -/* - * WjCryptLib_Md5 (https://github.com/WaterJuice/WjCryptLib) - * Implementation of MD5 hash function. Originally written by Alexander Peslyak. - * Modified by WaterJuice retaining Public Domain license. - * This is free and unencumbered software released into the public domain - June 2013 - waterjuice.org - */ - /* * File: md5.h * @@ -14,61 +7,11 @@ #ifndef MD5_H #define MD5_H -#pragma once - #include -#include - -/* TYPES */ - -/* Md5Context - * This must be initialised using Md5Initialised. - * Do not modify the contents of this structure directly. - */ -typedef struct { - uint32_t lo; - uint32_t hi; - uint32_t a; - uint32_t b; - uint32_t c; - uint32_t d; - uint8_t buffer[64]; - uint32_t block[16]; -} Md5Context; - -#define MD5_HASH_SIZE (128 / 8) -typedef struct { - uint8_t bytes [MD5_HASH_SIZE]; -} MD5_HASH; +#include "map_file.h" -/* PUBLIC FUNCTIONS */ - -/* Md5Initialise - * Initialises an MD5 Context. - * Use this to initialise/reset a context. - */ -void Md5Initialise(Md5Context* Context /* [out] */); - -/* Md5Update - * Adds data to the MD5 context. - * This will process the data and update the internal state of the context. - * Keep on calling this function until all the data has been added. - * Then call Md5Finalise to calculate the hash. - */ -void Md5Update(Md5Context* Context /* [in out] */, void const* Buffer /* [in] */, uint32_t BufferSize /* [in] */); - -/* Md5Finalise - * Performs the final calculation of the hash and returns the digest - * (16 byte buffer containing 128bit hash). - * After calling this, Md5Initialised must be used to reuse the context. - */ -void Md5Finalise(Md5Context* Context /* [in out] */, MD5_HASH* Digest /* [in] */); - -/* Md5Calculate - * Combines Md5Initialise, Md5Update, and Md5Finalise into one function. - * Calculates the MD5 hash of the buffer. - */ -void Md5Calculate(void const* Buffer /* [in] */, uint32_t BufferSize /* [in] */, MD5_HASH* Digest /* [in] */); +void md5_calculate(mapped_file_t *); +void stlink_checksum(mapped_file_t *); #endif // MD5_H \ No newline at end of file diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c index 6a12333cd..624d43a0a 100644 --- a/src/stlink-lib/option_bytes.c +++ b/src/stlink-lib/option_bytes.c @@ -9,11 +9,13 @@ #include #include -#include "common.h" -#include "common_flash.h" -#include "map_file.h" #include "option_bytes.h" +#include "common_flash.h" +#include "flash_loader.h" +#include "logging.h" +#include "map_file.h" +#include "md5.h" /** * Read option control register F0 diff --git a/src/stlink-lib/option_bytes.h b/src/stlink-lib/option_bytes.h index c0a1c9a6d..a58ea3857 100644 --- a/src/stlink-lib/option_bytes.h +++ b/src/stlink-lib/option_bytes.h @@ -8,9 +8,6 @@ #define OPTION_BYTES_H #include -#include - -#include int32_t stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); int32_t stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte); diff --git a/src/stlink-lib/read_write.c b/src/stlink-lib/read_write.c index f9c060bb2..6ee697d66 100644 --- a/src/stlink-lib/read_write.c +++ b/src/stlink-lib/read_write.c @@ -4,6 +4,8 @@ #include +#include "logging.h" + // Endianness // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html // These functions encode and decode little endian uint16 and uint32 values. diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index 4db8c6164..860b92b70 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -1,5 +1,3 @@ -/* == nightwalker-87: TODO: CONTENT AND USE OF THIS SOURCE FILE IS TO BE VERIFIED (07.06.2023) == */ - /* * Copyright (c) 2010 "Capt'ns Missing Link" Authors. All rights reserved. * Use of this source code is governed by a BSD-style @@ -84,17 +82,21 @@ #define __USE_GNU -#include #include #include #include #include -#include +#include +// #include -#include -#include "logging.h" #include "sg.h" +#include "commands.h" +#include "logging.h" +#include "register.h" +#include "usb.h" +// #include + #define STLINK_OK 0x80 #define STLINK_FALSE 0x81 diff --git a/src/stlink-lib/sg.h b/src/stlink-lib/sg.h index 1ab433142..cc3ea725e 100644 --- a/src/stlink-lib/sg.h +++ b/src/stlink-lib/sg.h @@ -1,5 +1,3 @@ -/* == nightwalker-87: TODO: CONTENT AND USE OF THIS HEADER FILE IS TO BE VERIFIED (07.06.2023) == */ - /* * File: sg.h * @@ -12,6 +10,7 @@ #include #include + #include "libusb_settings.h" /* Device access */ diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 9dc4a0ebd..907a32190 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -4,28 +4,31 @@ * USB commands & interaction with ST-LINK devices */ -#include -#include -#include -#include -#include - #if !defined(_MSC_VER) #include #endif -#include -#include -#include - #if defined(_WIN32) #include #endif +#include +#include +#include +#include + +#include +#include +#include +#include + #include -#include "helper.h" #include "usb.h" +#include "commands.h" +#include "logging.h" +#include "register.h" + enum SCSI_Generic_Direction {SG_DXFER_TO_DEV = 0, SG_DXFER_FROM_DEV = 0x80}; static inline uint32_t le_to_h_u32(const uint8_t* buf) { diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index 83c0c2481..b99e46f53 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -7,10 +7,8 @@ #ifndef USB_H #define USB_H -#include #include -#include #include "libusb_settings.h" #include "logging.h" From fc990648c4a0b91bdea539e699248f59d1157f51 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 9 Jun 2023 12:55:25 +0200 Subject: [PATCH 1382/1435] [refactoring] Clean-up for stlink-lib - Ensure proper function declaration - Checked & revised header includes --- src/stlink-lib/calculate.h | 2 -- src/stlink-lib/chipid.c | 1 + src/stlink-lib/chipid.h | 7 +++-- src/stlink-lib/common_flash.h | 2 -- src/stlink-lib/flash_loader.h | 2 -- src/stlink-lib/helper.c | 5 ++-- src/stlink-lib/helper.h | 5 ---- src/stlink-lib/lib_md5.c | 1 + src/stlink-lib/lib_md5.h | 3 -- src/stlink-lib/logging.h | 10 +++---- src/stlink-lib/map_file.h | 6 ++-- src/stlink-lib/md5.c | 1 + src/stlink-lib/md5.h | 2 -- src/stlink-lib/option_bytes.c | 3 +- src/stlink-lib/option_bytes.h | 44 +++++++++++++++++++++------- src/stlink-lib/register.h | 2 +- src/stlink-lib/sg.c | 12 ++++---- src/stlink-lib/sg.h | 42 +++++++++++++++++++++++++++ src/stlink-lib/usb.c | 27 ++++++++++-------- src/stlink-lib/usb.h | 54 +++++++++++++++++++++++++++++------ 20 files changed, 159 insertions(+), 72 deletions(-) diff --git a/src/stlink-lib/calculate.h b/src/stlink-lib/calculate.h index bdff782ae..64dfb51b2 100644 --- a/src/stlink-lib/calculate.h +++ b/src/stlink-lib/calculate.h @@ -7,8 +7,6 @@ #ifndef CALCULATE_H #define CALCULATE_H -#include - uint32_t calculate_F4_sectornum(uint32_t); uint32_t calculate_F7_sectornum(uint32_t); uint32_t calculate_H7_sectornum(stlink_t *, uint32_t, unsigned); diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index c622abcbb..a4abf90d8 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -223,6 +223,7 @@ void init_chipids(char *dir_to_scan) { return; } } + #endif // STLINK_HAVE_DIRENT_H #if defined(_WIN32) && !defined(STLINK_HAVE_DIRENT_H) diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index d7319f569..a72a40be9 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -7,8 +7,6 @@ #ifndef CHIPID_H #define CHIPID_H -#include - /* Chipid parametres */ struct stlink_chipid_params { char *dev_type; @@ -27,6 +25,9 @@ struct stlink_chipid_params { }; struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); - void init_chipids(char *dir_to_scan); + +void dump_a_chip(struct stlink_chipid_params *dev); +void process_chipfile(char *fname); +void init_chipids(char *dir_to_scan); #endif // CHIPID_H diff --git a/src/stlink-lib/common_flash.h b/src/stlink-lib/common_flash.h index 092bdcbf4..fd1e51b9d 100644 --- a/src/stlink-lib/common_flash.h +++ b/src/stlink-lib/common_flash.h @@ -7,8 +7,6 @@ #ifndef COMMON_FLASH_H #define COMMON_FLASH_H -#include - #define BANK_1 0 #define BANK_2 1 diff --git a/src/stlink-lib/flash_loader.h b/src/stlink-lib/flash_loader.h index 61a2a0c19..06eb53d12 100644 --- a/src/stlink-lib/flash_loader.h +++ b/src/stlink-lib/flash_loader.h @@ -7,8 +7,6 @@ #ifndef FLASH_LOADER_H #define FLASH_LOADER_H -#include - int32_t stlink_flash_loader_init(stlink_t *sl, flash_loader_t* fl); // static int32_t loader_v_dependent_assignment(stlink_t *sl, // const uint8_t **loader_code, size_t *loader_size, diff --git a/src/stlink-lib/helper.c b/src/stlink-lib/helper.c index 97d6eb316..1e756f1de 100644 --- a/src/stlink-lib/helper.c +++ b/src/stlink-lib/helper.c @@ -1,15 +1,14 @@ -/* == nightwalker-87: TODO: CONTENT AND USE OF THIS SOURCE FILE IS TO BE VERIFIED (07.06.2023) == */ - /* * File: helper.c * * General helper functions */ + #ifdef STLINK_HAVE_SYS_TIME_H #include #else #include -#endif +#endif // STLINK_HAVE_SYS_TIME_H #include #include diff --git a/src/stlink-lib/helper.h b/src/stlink-lib/helper.h index a42fd480e..ef374a5b6 100644 --- a/src/stlink-lib/helper.h +++ b/src/stlink-lib/helper.h @@ -1,5 +1,3 @@ -/* == nightwalker-87: TODO: CONTENT AND USE OF THIS SOURCE FILE IS TO BE VERIFIED (07.06.2023) == */ - /* * File: helper.h * @@ -9,10 +7,7 @@ #ifndef HELPER_H #define HELPER_H -#include - uint32_t time_ms(); - int32_t arg_parse_freq(const char *str); #endif // HELPER_H diff --git a/src/stlink-lib/lib_md5.c b/src/stlink-lib/lib_md5.c index 42f337ac3..71703273c 100644 --- a/src/stlink-lib/lib_md5.c +++ b/src/stlink-lib/lib_md5.c @@ -6,6 +6,7 @@ */ #include +#include #include #include "lib_md5.h" diff --git a/src/stlink-lib/lib_md5.h b/src/stlink-lib/lib_md5.h index abe1131ae..7275fd0bd 100644 --- a/src/stlink-lib/lib_md5.h +++ b/src/stlink-lib/lib_md5.h @@ -10,9 +10,6 @@ #pragma once -#include -#include - /* TYPES */ /* Md5Context diff --git a/src/stlink-lib/logging.h b/src/stlink-lib/logging.h index d07db797d..cb49a7af3 100644 --- a/src/stlink-lib/logging.h +++ b/src/stlink-lib/logging.h @@ -8,11 +8,9 @@ #ifndef LOGGING_H #define LOGGING_H -#include - #ifdef __cplusplus extern "C" { -#endif +#endif // __cplusplus enum ugly_loglevel { UDEBUG = 90, @@ -25,7 +23,7 @@ enum ugly_loglevel { #define PRINTF_ARRT __attribute__ ((format (printf, 3, 4))) #else #define PRINTF_ARRT -#endif +#endif // __GNUC__ int32_t ugly_init(int32_t maximum_threshold); int32_t ugly_log(int32_t level, const char *tag, const char *format, ...) PRINTF_ARRT; @@ -48,6 +46,6 @@ int32_t ugly_libusb_log_level(enum ugly_loglevel v); #ifdef __cplusplus } -#endif +#endif // __cplusplus -#endif // LOGGING_H +#endif // LOGGING_H diff --git a/src/stlink-lib/map_file.h b/src/stlink-lib/map_file.h index ddedad93c..ba50e25e9 100644 --- a/src/stlink-lib/map_file.h +++ b/src/stlink-lib/map_file.h @@ -7,17 +7,15 @@ #ifndef MAP_FILE_H #define MAP_FILE_H -#include - #ifndef O_BINARY #define O_BINARY 0 -#endif +#endif // O_BINARY #ifdef STLINK_HAVE_SYS_MMAN_H #include #else #include -#endif +#endif // STLINK_HAVE_SYS_MMAN_H /* Memory mapped file */ typedef struct mapped_file { diff --git a/src/stlink-lib/md5.c b/src/stlink-lib/md5.c index 070d9af91..9481acf0f 100644 --- a/src/stlink-lib/md5.c +++ b/src/stlink-lib/md5.c @@ -5,6 +5,7 @@ */ #include +#include #include #include "md5.h" diff --git a/src/stlink-lib/md5.h b/src/stlink-lib/md5.h index eb36d64cc..f5591e2c3 100644 --- a/src/stlink-lib/md5.h +++ b/src/stlink-lib/md5.h @@ -7,8 +7,6 @@ #ifndef MD5_H #define MD5_H -#include - #include "map_file.h" void md5_calculate(mapped_file_t *); diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c index 624d43a0a..c84ace348 100644 --- a/src/stlink-lib/option_bytes.c +++ b/src/stlink-lib/option_bytes.c @@ -426,8 +426,7 @@ int32_t stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t *option_byte * @param option_byte * @return 0 on success, -ve on failure. */ -static int -stlink_write_option_bytes_boot_add_f7(stlink_t *sl, uint32_t option_byte_boot_add) { +static int32_t stlink_write_option_bytes_boot_add_f7(stlink_t *sl, uint32_t option_byte_boot_add) { ILOG("Asked to write option byte boot add %#010x.\n", option_byte_boot_add); return stlink_write_option_control_register1_f7(sl, option_byte_boot_add); } diff --git a/src/stlink-lib/option_bytes.h b/src/stlink-lib/option_bytes.h index a58ea3857..ffeef8a0f 100644 --- a/src/stlink-lib/option_bytes.h +++ b/src/stlink-lib/option_bytes.h @@ -7,19 +7,41 @@ #ifndef OPTION_BYTES_H #define OPTION_BYTES_H -#include - +int32_t stlink_read_option_control_register_f0(stlink_t *sl, uint32_t *option_byte); +// static int32_t stlink_write_option_bytes_f0(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); +// static int32_t stlink_write_option_control_register_f0(stlink_t *sl, uint32_t option_cr); +int32_t stlink_read_option_control_register_f2(stlink_t *sl, uint32_t *option_byte); +int32_t stlink_read_option_bytes_f2(stlink_t *sl, uint32_t *option_byte); +int32_t stlink_read_option_control_register_f4(stlink_t *sl, uint32_t *option_byte); +int32_t stlink_read_option_bytes_f4(stlink_t *sl, uint32_t *option_byte); +// static int32_t stlink_write_option_bytes_f4(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len); +int32_t stlink_read_option_bytes_f7(stlink_t *sl, uint32_t *option_byte); +// static int32_t stlink_write_option_bytes_f7(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len); +int32_t stlink_read_option_control_register_f7(stlink_t *sl, uint32_t *option_byte); +// static int32_t stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option_cr); +int32_t stlink_read_option_control_register1_f7(stlink_t *sl, uint32_t *option_byte); +// static int32_t stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t option_cr1); +int32_t stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t *option_byte); +// static int32_t stlink_write_option_bytes_boot_add_f7(stlink_t *sl, uint32_t option_byte_boot_add); +int32_t stlink_read_option_control_register_gx(stlink_t *sl, uint32_t *option_byte); +int32_t stlink_read_option_bytes_gx(stlink_t *sl, uint32_t *option_byte); +// static int32_t stlink_write_option_bytes_gx(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len); +// static int32_t stlink_write_option_bytes_h7(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len); +// static int32_t stlink_write_option_bytes_l0(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len); +// static int32_t stlink_write_option_bytes_l4(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len); +// static int32_t stlink_write_option_bytes_wb(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len); +int32_t stlink_read_option_control_register_wb(stlink_t *sl, uint32_t *option_byte); +// static int32_t stlink_write_option_control_register_wb(stlink_t *sl, uint32_t option_cr); +int32_t stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte); +int32_t stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len); +int32_t stlink_fwrite_option_bytes(stlink_t *sl, const char *path, stm32_addr_t addr); +int32_t stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte); +int32_t stlink_write_option_control_register32(stlink_t *sl, uint32_t option_cr); +int32_t stlink_read_option_control_register1_32(stlink_t *sl, uint32_t *option_byte); +int32_t stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_cr1); int32_t stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); -int32_t stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte); -int32_t stlink_read_option_control_register32(stlink_t *sl, uint32_t* option_byte); -int32_t stlink_read_option_control_register1_32(stlink_t *sl, uint32_t* option_byte); - int32_t stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); +int32_t stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte); int32_t stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add); -int32_t stlink_write_option_control_register32(stlink_t *sl, uint32_t option_cr); -int32_t stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_cr1); - -int32_t stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); -int32_t stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); #endif // OPTION_BYTES_H \ No newline at end of file diff --git a/src/stlink-lib/register.h b/src/stlink-lib/register.h index 7b63154c8..f1e9574cd 100644 --- a/src/stlink-lib/register.h +++ b/src/stlink-lib/register.h @@ -129,4 +129,4 @@ #define STLINK_REG_CM7_ICIALLU 0xE000EF50 #define STLINK_REG_CM7_CCSIDR 0xE000ED80 -#endif // REG_H +#endif // REGISTER_H diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index 860b92b70..0aa7a0d68 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -1,3 +1,5 @@ +/* == nightwalker-87: TODO: CONTENT AND USE OF THIS SOURCE FILE IS TO BE VERIFIED (07.06.2023) == */ + /* * Copyright (c) 2010 "Capt'ns Missing Link" Authors. All rights reserved. * Use of this source code is governed by a BSD-style @@ -87,7 +89,7 @@ #include #include #include -// #include +// #include // TODO: Check use #include "sg.h" @@ -95,7 +97,7 @@ #include "logging.h" #include "register.h" #include "usb.h" -// #include +// #include // TODO: Check use #define STLINK_OK 0x80 #define STLINK_FALSE 0x81 @@ -150,6 +152,7 @@ static int32_t get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t uint32_t rsig = read_uint32(csw, 0); uint32_t rtag = read_uint32(csw, 4); /* uint32_t residue = read_uint32(csw, 8); */ + #define USB_CSW_SIGNATURE 0x53425355 // 'U' 'S' 'B' 'S' (reversed) if (rsig != USB_CSW_SIGNATURE) { @@ -187,9 +190,8 @@ static int32_t dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) { * @param expected_rx_size * @return */ -int32_t send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint_out, - uint8_t *cdb, uint8_t cdb_length, - uint8_t lun, uint8_t flags, uint32_t expected_rx_size) { +int32_t send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint_out, uint8_t *cdb, uint8_t cdb_length, + uint8_t lun, uint8_t flags, uint32_t expected_rx_size) { DLOG("Sending usb m-s cmd: cdblen:%d, rxsize=%d\n", cdb_length, expected_rx_size); dump_CDB_command(cdb, cdb_length); diff --git a/src/stlink-lib/sg.h b/src/stlink-lib/sg.h index cc3ea725e..b10d0f6f0 100644 --- a/src/stlink-lib/sg.h +++ b/src/stlink-lib/sg.h @@ -1,3 +1,5 @@ +/* == nightwalker-87: TODO: CONTENT AND USE OF THIS SOURCE FILE IS TO BE VERIFIED (07.06.2023) == */ + /* * File: sg.h * @@ -58,6 +60,46 @@ struct stlink_libsg { struct stlink_reg reg; }; +// static void clear_cdb(struct stlink_libsg *sl); +void _stlink_sg_close(stlink_t *sl); +// static int32_t get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t endpoint, uint32_t *tag); +// static int32_t dump_CDB_command(uint8_t *cdb, uint8_t cdb_len); +int32_t send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint_out, uint8_t *cdb, uint8_t cdb_length, + uint8_t lun, uint8_t flags, uint32_t expected_rx_size); +// static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out); +int32_t send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, + unsigned char endpoint_in, unsigned char *cbuf, uint32_t length); +int32_t stlink_q(stlink_t *sl); +void stlink_stat(stlink_t *stl, char *txt); +int32_t _stlink_sg_version(stlink_t *stl); +int32_t _stlink_sg_current_mode(stlink_t *stl); +int32_t _stlink_sg_enter_swd_mode(stlink_t *sl); +int32_t _stlink_sg_enter_jtag_mode(stlink_t *sl); +int32_t _stlink_sg_exit_dfu_mode(stlink_t *sl); +int32_t _stlink_sg_core_id(stlink_t *sl); +int32_t _stlink_sg_reset(stlink_t *sl); +int32_t _stlink_sg_jtag_reset(stlink_t *sl, int32_t value); +int32_t _stlink_sg_status(stlink_t *sl); +int32_t _stlink_sg_force_debug(stlink_t *sl); +int32_t _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp); +int32_t _stlink_sg_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp); +int32_t _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int32_t idx); +void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr); +int32_t _stlink_sg_run(stlink_t *sl, enum run_type type); +int32_t _stlink_sg_step(stlink_t *sl); +void stlink_set_hw_bp(stlink_t *sl, int32_t fp_nr, uint32_t addr, int32_t fp); +void stlink_clr_hw_bp(stlink_t *sl, int32_t fp_nr); +int32_t _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int32_t _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); +int32_t _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int32_t _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); +int32_t _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); +int32_t _stlink_sg_exit_debug_mode(stlink_t *stl); + +// static stlink_backend_t _stlink_sg_backend = { }; + +// static stlink_t* stlink_open(const int32_t verbose); +stlink_t* stlink_v1_open_inner(const int32_t verbose); stlink_t* stlink_v1_open(const int32_t verbose, int32_t reset); #endif // SG_H diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 907a32190..fc1dcbb4e 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -6,11 +6,11 @@ #if !defined(_MSC_VER) #include -#endif +#endif // _MSC_VER #if defined(_WIN32) #include -#endif +#endif // _WIN32 #include #include @@ -29,8 +29,6 @@ #include "logging.h" #include "register.h" -enum SCSI_Generic_Direction {SG_DXFER_TO_DEV = 0, SG_DXFER_FROM_DEV = 0x80}; - static inline uint32_t le_to_h_u32(const uint8_t* buf) { return((uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24)); } @@ -92,9 +90,8 @@ void _stlink_usb_close(stlink_t* sl) { } } -ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, - unsigned char* txbuf, size_t txsize, unsigned char* rxbuf, - size_t rxsize, int32_t check_error, const char *cmd) { +ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char* txbuf, size_t txsize, + unsigned char* rxbuf, size_t rxsize, int32_t check_error, const char *cmd) { // Note: txbuf and rxbuf can point to the same area int32_t res, t, retry = 0; @@ -170,9 +167,8 @@ ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, } } -static inline int32_t send_only(struct stlink_libusb* handle, int32_t terminate, - unsigned char* txbuf, size_t txsize, - const char *cmd) { +static inline int32_t send_only(struct stlink_libusb* handle, int32_t terminate, unsigned char* txbuf, + size_t txsize, const char *cmd) { return((int32_t)send_recv(handle, terminate, txbuf, txsize, NULL, 0, CMD_CHECK_NO, cmd)); } @@ -359,7 +355,6 @@ int32_t _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { return(0); } - int32_t _stlink_usb_current_mode(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; @@ -1113,6 +1108,14 @@ size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_d return strlen(serial); } +/** + * Open a stlink + * @param verbose Verbosity loglevel + * @param connect Type of connect to target + * @param serial Serial number to search for, when NULL the first stlink found is opened (binary format) + * @retval NULL Error while opening the stlink + * @retval !NULL Stlink found and ready to use + */ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int32_t freq) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; @@ -1208,7 +1211,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, goto on_libusb_error; } } -#endif +#endif // NOT _WIN32 if (libusb_get_configuration(slu->usb_handle, &config)) { // this may fail for a previous configured device diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index b99e46f53..dd30cc529 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -46,6 +46,8 @@ #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 +enum SCSI_Generic_Direction {SG_DXFER_TO_DEV = 0, SG_DXFER_FROM_DEV = 0x80}; + struct stlink_libusb { libusb_context* libusb_ctx; libusb_device_handle* usb_handle; @@ -57,16 +59,50 @@ struct stlink_libusb { uint32_t cmd_len; }; -/** - * Open a stlink - * @param verbose Verbosity loglevel - * @param connect Type of connect to target - * @param serial Serial number to search for, when NULL the first stlink found is opened (binary format) - * @retval NULL Error while opening the stlink - * @retval !NULL Stlink found and ready to use - */ - +// static inline uint32_t le_to_h_u32(const uint8_t* buf); +// static int32_t _stlink_match_speed_map(const uint32_t *map, uint32_t map_size, uint32_t khz); +void _stlink_usb_close(stlink_t* sl); +ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char* txbuf, size_t txsize, + unsigned char* rxbuf, size_t rxsize, int32_t check_error, const char *cmd); +// static inline int32_t send_only(struct stlink_libusb* handle, int32_t terminate, unsigned char* txbuf, +// size_t txsize, const char *cmd); +// static int32_t fill_command(stlink_t * sl, enum SCSI_Generic_Direction dir, uint32_t len); +int32_t _stlink_usb_version(stlink_t *sl); +int32_t _stlink_usb_target_voltage(stlink_t *sl); +int32_t _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); +int32_t _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); +int32_t _stlink_usb_get_rw_status(stlink_t *sl); +int32_t _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int32_t _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); +int32_t _stlink_usb_current_mode(stlink_t * sl); +int32_t _stlink_usb_core_id(stlink_t * sl); +int32_t _stlink_usb_status_v2(stlink_t *sl); +int32_t _stlink_usb_status(stlink_t * sl); +int32_t _stlink_usb_force_debug(stlink_t *sl); +int32_t _stlink_usb_enter_swd_mode(stlink_t * sl); +int32_t _stlink_usb_exit_dfu_mode(stlink_t* sl); +int32_t _stlink_usb_reset(stlink_t * sl); +int32_t _stlink_usb_jtag_reset(stlink_t * sl, int32_t value); +int32_t _stlink_usb_step(stlink_t* sl); +int32_t _stlink_usb_run(stlink_t* sl, enum run_type type); +int32_t _stlink_usb_set_swdclk(stlink_t* sl, int32_t clk_freq); +int32_t _stlink_usb_exit_debug_mode(stlink_t *sl); +int32_t _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int32_t _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp); +int32_t _stlink_usb_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp); +int32_t _stlink_usb_read_unsupported_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp); +int32_t _stlink_usb_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); +int32_t _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int32_t r_idx, struct stlink_reg *regp); +int32_t _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int32_t idx); +int32_t _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency); +int32_t _stlink_usb_disable_trace(stlink_t* sl); +int32_t _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size); + +// static stlink_backend_t _stlink_usb_backend = { }; + +size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_descriptor *desc, char *serial); stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int32_t freq); +// static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], enum connect_type connect, int32_t freq); size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int32_t freq); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); From efc5c3713d3124a1e8c6189a6cab960c700a50b9 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 9 Jun 2023 14:51:57 +0200 Subject: [PATCH 1383/1435] Fixed flash-write/verify error (Closes #1303) --- src/stlink-lib/common_flash.c | 3 --- src/stlink-lib/flash_loader.c | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 6ade87311..194fa7aab 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -1439,9 +1439,6 @@ int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint3 (uint32_t)(sl->flash_pgsz)); return (-1); } - if ((len % 16 <= 8) & (sl->flash_type == STM32_FLASH_TYPE_L5_U5)) { - len += 8; - } // make sure we've loaded the context with the chip details stlink_core_id(sl); diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 3472e2a61..2bac1ace0 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -474,7 +474,7 @@ int32_t stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, if (sl->verbose >= 1) { // show progress; writing procedure is slow and previous errors are misleading - fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); + fprintf(stdout, "\r%3u/%3u halfpages written", count + 1, num_half_pages); fflush(stdout); } From 755c20c08ea026549439a97be2351540069c7f9e Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 10 Jun 2023 20:07:19 +0200 Subject: [PATCH 1384/1435] Replace data types with fixed width typedefs (C99) - Unified variable type: size_t --> uint32_t - Removed unnecessary explicit casts - Minor formatting fixes --- inc/backend.h | 2 +- inc/stlink.h | 18 +++--- src/st-flash/flash.c | 14 ++--- src/st-flash/flash.h | 4 +- src/st-flash/flash_opts.c | 12 ++-- src/st-info/info.c | 18 +++--- src/st-util/gdb-server.c | 54 +++++++++--------- src/stlink-gui/gui.c | 2 +- src/stlink-lib/calculate.c | 7 +-- src/stlink-lib/calculate.h | 2 +- src/stlink-lib/chipid.c | 2 +- src/stlink-lib/common.c | 61 ++++++++++---------- src/stlink-lib/common_flash.c | 47 +++++++--------- src/stlink-lib/common_flash.h | 4 +- src/stlink-lib/flash_loader.c | 103 ++++++++++++++-------------------- src/stlink-lib/flash_loader.h | 10 ++-- src/stlink-lib/map_file.c | 12 ++-- src/stlink-lib/map_file.h | 2 +- src/stlink-lib/md5.c | 2 +- src/stlink-lib/option_bytes.h | 2 +- src/stlink-lib/read_write.c | 2 +- src/stlink-lib/sg.c | 2 +- src/stlink-lib/usb.c | 24 ++++---- src/stlink-lib/usb.h | 12 ++-- src/win32/getopt/getopt.c | 2 +- src/win32/mmap.c | 4 +- src/win32/mmap.h | 4 +- tests/flash.c | 4 +- 28 files changed, 200 insertions(+), 232 deletions(-) diff --git a/inc/backend.h b/inc/backend.h index a9a7d6e03..6b9c9c0a8 100644 --- a/inc/backend.h +++ b/inc/backend.h @@ -33,7 +33,7 @@ int32_t (*set_swdclk) (stlink_t * stl, int32_t freq_khz); int32_t (*trace_enable) (stlink_t * sl, uint32_t frequency); int32_t (*trace_disable) (stlink_t * sl); - int32_t (*trace_read) (stlink_t * sl, uint8_t* buf, size_t size); + int32_t (*trace_read) (stlink_t * sl, uint8_t* buf, uint32_t size); } stlink_backend_t; #endif // BACKEND_H diff --git a/inc/stlink.h b/inc/stlink.h index b2516c90c..d5d036725 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -210,22 +210,22 @@ struct _stlink { // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STM32_FLASH_TYPE_xx stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() - size_t flash_size; // calculated by stlink_load_device_params() - size_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() + uint32_t flash_size; // calculated by stlink_load_device_params() + uint32_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() /* sram settings */ stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() - size_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() + uint32_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() /* option settings */ stm32_addr_t option_base; - size_t option_size; + uint32_t option_size; // bootloader // sys_base and sys_size are not used by the tools, but are only there to download the bootloader code // (see tests/sg.c) stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() - size_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() + uint32_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() struct stlink_version_ version; @@ -262,8 +262,8 @@ int32_t stlink_target_voltage(stlink_t *sl); int32_t stlink_set_swdclk(stlink_t *sl, int32_t freq_khz); int32_t stlink_trace_enable(stlink_t* sl, uint32_t frequency); int32_t stlink_trace_disable(stlink_t* sl); -int32_t stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size); -int32_t stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); +int32_t stlink_trace_read(stlink_t* sl, uint8_t* buf, uint32_t size); +int32_t stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, uint32_t * size, uint32_t * begin); uint8_t stlink_get_erased_pattern(stlink_t *sl); int32_t stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); int32_t stlink_fwrite_sram(stlink_t *sl, const char* path, stm32_addr_t addr); @@ -278,9 +278,9 @@ uint32_t read_uint32(const unsigned char *c, const int32_t pt); void write_uint32(unsigned char* buf, uint32_t ui); void write_uint16(unsigned char* buf, uint16_t ui); bool stlink_is_core_halted(stlink_t *sl); -int32_t write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); +int32_t write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, uint32_t size); int32_t write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); -int32_t stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); +int32_t stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, uint32_t size); int32_t stlink_load_device_params(stlink_t *sl); int32_t stlink_target_connect(stlink_t *sl, enum connect_type connect); diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 6b4a10cfc..9a648bd63 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -83,7 +83,7 @@ int32_t main(int32_t ac, char** av) { if ( o.flash_size != 0u && o.flash_size != sl->flash_size ) { sl->flash_size = o.flash_size; - printf("Forcing flash size: --flash=0x%08X\n", (uint32_t)sl->flash_size); + printf("Forcing flash size: --flash=0x%08X\n", sl->flash_size); } sl->verbose = o.log_level; @@ -106,7 +106,7 @@ int32_t main(int32_t ac, char** av) { } if (o.cmd == FLASH_CMD_WRITE) { - size_t size = 0; + uint32_t size = 0; // write if (o.format == FLASH_FORMAT_IHEX) { @@ -119,7 +119,7 @@ int32_t main(int32_t ac, char** av) { } if ((o.addr >= sl->flash_base) && (o.addr < sl->flash_base + sl->flash_size)) { if (o.format == FLASH_FORMAT_IHEX) { - err = stlink_mwrite_flash(sl, mem, (uint32_t)size, o.addr); + err = stlink_mwrite_flash(sl, mem, size, o.addr); } else { err = stlink_fwrite_flash(sl, o.filename, o.addr); } @@ -130,7 +130,7 @@ int32_t main(int32_t ac, char** av) { } } else if ((o.addr >= sl->sram_base) && (o.addr < sl->sram_base + sl->sram_size)) { if (o.format == FLASH_FORMAT_IHEX) { - err = stlink_mwrite_sram(sl, mem, (uint32_t)size, o.addr); + err = stlink_mwrite_sram(sl, mem, size, o.addr); } else { err = stlink_fwrite_sram(sl, o.filename, o.addr); } @@ -221,10 +221,10 @@ int32_t main(int32_t ac, char** av) { goto on_error; } } else if (o.area == FLASH_OPTION_BYTES) { - size_t remaining_option_length = sl->option_size / 4; + uint32_t remaining_option_length = sl->option_size / 4; DLOG("@@@@ Read %u (%#x) option bytes from %#10x\n", - (uint32_t)remaining_option_length, - (uint32_t)remaining_option_length, + remaining_option_length, + remaining_option_length, sl->option_base); uint32_t option_byte = 0; diff --git a/src/st-flash/flash.h b/src/st-flash/flash.h index 1a509a660..84c171158 100644 --- a/src/st-flash/flash.h +++ b/src/st-flash/flash.h @@ -17,13 +17,13 @@ struct flash_opts { uint8_t serial[STLINK_SERIAL_BUFFER_SIZE]; const char* filename; stm32_addr_t addr; - size_t size; + uint32_t size; int32_t reset; int32_t log_level; enum flash_format format; enum flash_area area; uint32_t val; - size_t flash_size; // --flash=n[k, M] + uint32_t flash_size; // --flash=n[k, M] int32_t opt; // enable empty tail data drop optimization int32_t freq; // --freq=n[k, M] frequency of JTAG/SWD enum connect_type connect; diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index e133d52c7..35763ad50 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -8,7 +8,7 @@ #include "flash.h" static bool starts_with(const char * str, const char * prefix) { - size_t n = strlen(prefix); + uint32_t n = strlen(prefix); if (strlen(str) < n) { return(false); } @@ -61,7 +61,7 @@ static int32_t get_integer_from_char_array (const char *const str, uint32_t *rea fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, cannot convert to int32_t\n"); return(-1); } else { - *read_value = (uint32_t)value; + *read_value = value; return(0); } } @@ -318,7 +318,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { if (result != 0) { return bad_arg ("val"); } else { - o->val = (uint32_t) val; + o->val = val; } } else if (o->area == FLASH_OPTION_BYTES_BOOT_ADD) { // expect option bytes boot address if (ac != 1) { return invalid_args("option bytes boot_add write "); } @@ -329,7 +329,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { if (result != 0) { return(bad_arg ("val")); } else { - o->val = (uint32_t)val; + o->val = val; } } else if (o->area == FLASH_OPTCR) { // expect option control register value if (ac != 1) { return invalid_args("option control register write "); } @@ -340,7 +340,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { if (result != 0) { return bad_arg ("val"); } else { - o->val = (uint32_t) val; + o->val = val; } } else if (o->area == FLASH_OPTCR1) { // expect option control register 1 value if (ac != 1) { return invalid_args("option control register 1 write "); } @@ -350,7 +350,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { if (result != 0) { return bad_arg ("val"); } else { - o->val = (uint32_t) val; + o->val = val; } } else if (o->format == FLASH_FORMAT_BINARY) { // expect filename and addr if (ac != 2) { return invalid_args("write "); } diff --git a/src/st-info/info.c b/src/st-info/info.c index 86a1c2d8f..b6ec0ccd2 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -35,8 +35,8 @@ static void stlink_print_info(stlink_t *sl) { printf(" version: "); stlink_print_version(sl); printf(" serial: %s\n", sl->serial); - printf(" flash: %u (pagesize: %u)\n", (uint32_t)sl->flash_size, (uint32_t)sl->flash_pgsz); - printf(" sram: %u\n", (uint32_t)sl->sram_size); + printf(" flash: %u (pagesize: %u)\n", sl->flash_size, sl->flash_pgsz); + printf(" sram: %u\n", sl->sram_size); printf(" chipid: 0x%.3x\n", sl->chip_id); params = stlink_chipid_get_params(sl->chip_id); @@ -45,14 +45,14 @@ static void stlink_print_info(stlink_t *sl) { static void stlink_probe(enum connect_type connect, int32_t freq) { stlink_t **stdevs; - size_t size; + uint32_t size; size = stlink_probe_usb(&stdevs, connect, freq); - printf("Found %u stlink programmers\n", (uint32_t)size); + printf("Found %u stlink programmers\n", size); - for (size_t n = 0; n < size; n++) { - if (size > 1) printf("%u.\n", (uint32_t)n+1); + for (uint32_t n = 0; n < size; n++) { + if (size > 1) printf("%u.\n", n+1); stlink_print_info(stdevs[n]); } @@ -107,11 +107,11 @@ static int32_t print_data(int32_t ac, char **av) { if (strcmp(av[1], "--serial") == 0) { printf("%s\n", sl->serial); } else if (strcmp(av[1], "--flash") == 0) { - printf("0x%x\n", (uint32_t)sl->flash_size); + printf("0x%x\n", sl->flash_size); } else if (strcmp(av[1], "--pagesize") == 0) { - printf("0x%x\n", (uint32_t)sl->flash_pgsz); + printf("0x%x\n", sl->flash_pgsz); } else if (strcmp(av[1], "--sram") == 0) { - printf("0x%x\n", (uint32_t)sl->sram_size); + printf("0x%x\n", sl->sram_size); } else if (strcmp(av[1], "--chipid") == 0) { printf("0x%.4x\n", sl->chip_id); } else if (strcmp(av[1], "--descr") == 0) { diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 431e37eec..7232f0f69 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -554,7 +554,7 @@ static const char* const memory_map_template_F4_DE = char* make_memory_map(stlink_t *sl) { // this will be freed in serve() - const size_t sz = 4096; + const uint32_t sz = 4096; char* map = malloc(sz); map[0] = '\0'; @@ -566,42 +566,42 @@ char* make_memory_map(stlink_t *sl) { strcpy(map, memory_map_template_F4_DE); } else if (sl->core_id == STM32_CORE_ID_M7F_SWD) { snprintf(map, sz, memory_map_template_F7, - (uint32_t)sl->sram_size); + sl->sram_size); } else if (sl->chip_id == STM32_CHIPID_H74xxx) { snprintf(map, sz, memory_map_template_H7, - (uint32_t)sl->flash_size, - (uint32_t)sl->flash_pgsz); + sl->flash_size, + sl->flash_pgsz); } else if (sl->chip_id == STM32_CHIPID_F4_HD) { strcpy(map, memory_map_template_F4_HD); } else if (sl->chip_id == STM32_CHIPID_F2) { snprintf(map, sz, memory_map_template_F2, - (uint32_t)sl->flash_size, - (uint32_t)sl->sram_size, - (uint32_t)sl->flash_size - 0x20000, - (uint32_t)sl->sys_base, - (uint32_t)sl->sys_size); + sl->flash_size, + sl->sram_size, + sl->flash_size - 0x20000, + sl->sys_base, + sl->sys_size); } else if ((sl->chip_id == STM32_CHIPID_L4) || (sl->chip_id == STM32_CHIPID_L43x_L44x) || (sl->chip_id == STM32_CHIPID_L45x_L46x)) { snprintf(map, sz, memory_map_template_L4, - (uint32_t)sl->flash_size, - (uint32_t)sl->flash_size); + sl->flash_size, + sl->flash_size); } else if (sl->chip_id == STM32_CHIPID_L496x_L4A6x) { snprintf(map, sz, memory_map_template_L496, - (uint32_t)sl->flash_size, - (uint32_t)sl->flash_size); + sl->flash_size, + sl->flash_size); } else if (sl->chip_id == STM32_CHIPID_H72x) { snprintf(map, sz, memory_map_template_H72x3x, - (uint32_t)sl->flash_size, - (uint32_t)sl->flash_pgsz); + sl->flash_size, + sl->flash_pgsz); } else { snprintf(map, sz, memory_map_template, - (uint32_t)sl->flash_size, - (uint32_t)sl->sram_size, - (uint32_t)sl->flash_size, - (uint32_t)sl->flash_pgsz, - (uint32_t)sl->sys_base, - (uint32_t)sl->sys_size); + sl->flash_size, + sl->sram_size, + sl->flash_size, + sl->flash_pgsz, + sl->sys_base, + sl->sys_size); } return(map); @@ -1074,8 +1074,8 @@ static void cache_sync(stlink_t *sl) { if (ccr & (STLINK_REG_CM7_CCR_IC | STLINK_REG_CM7_CCR_DC)) { cache_flush(sl, ccr); } } -static size_t unhexify(const char *in, char *out, size_t out_count) { - size_t i; +static uint32_t unhexify(const char *in, char *out, uint32_t out_count) { + uint32_t i; uint32_t c; for (i = 0; i < out_count; i++) { @@ -1248,9 +1248,9 @@ int32_t serve(stlink_t *sl, st_state_t *st) { params = separator + 1; } - size_t hex_len = strlen(params); - size_t alloc_size = (hex_len / 2) + 1; - size_t cmd_len; + uint32_t hex_len = strlen(params); + uint32_t alloc_size = (hex_len / 2) + 1; + uint32_t cmd_len; char *cmd = malloc(alloc_size); if (cmd == NULL) { @@ -1669,7 +1669,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) { uint32_t adj_start = start % 4; uint32_t count_rnd = (count + adj_start + 4 - 1) / 4 * 4; - if (count_rnd > sl->flash_pgsz) { count_rnd = (uint32_t)sl->flash_pgsz; } + if (count_rnd > sl->flash_pgsz) { count_rnd = sl->flash_pgsz; } if (count_rnd > 0x1800) { count_rnd = 0x1800; } diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index f1e9382d0..af2afcdbf 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -262,7 +262,7 @@ static gpointer stlink_gui_populate_filemem_view(gpointer data) { */ uint8_t* mem = NULL; - size_t size = 0; + uint32_t size = 0; uint32_t begin = 0; int32_t res = stlink_parse_ihex(gui->filename, 0, &mem, &size, &begin); diff --git a/src/stlink-lib/calculate.c b/src/stlink-lib/calculate.c index b13a1c961..027239694 100644 --- a/src/stlink-lib/calculate.c +++ b/src/stlink-lib/calculate.c @@ -47,8 +47,7 @@ uint32_t calculate_F7_sectornum(uint32_t flashaddr) { } } -uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, - uint32_t bank) { +uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, uint32_t bank) { flashaddr &= ~((bank == BANK_1) ? STM32_FLASH_BASE @@ -68,7 +67,7 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { sl->chip_id == STM32_CHIPID_L4Rx) { // this chip use dual banked flash if (flashopt & (uint32_t)(1lu << FLASH_L4_OPTR_DUALBANK)) { - uint32_t banksize = (uint32_t)sl->flash_size / 2; + uint32_t banksize = sl->flash_size / 2; if (flashaddr >= banksize) { flashaddr -= banksize; @@ -79,5 +78,5 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { // For 1MB chips without the dual-bank option set, the page address will // overflow into the BKER bit, which gives us the correct bank:page value. - return (bker | flashaddr / (uint32_t)sl->flash_pgsz); + return (bker | flashaddr / sl->flash_pgsz); } diff --git a/src/stlink-lib/calculate.h b/src/stlink-lib/calculate.h index 64dfb51b2..ca0a39df6 100644 --- a/src/stlink-lib/calculate.h +++ b/src/stlink-lib/calculate.h @@ -9,7 +9,7 @@ uint32_t calculate_F4_sectornum(uint32_t); uint32_t calculate_F7_sectornum(uint32_t); -uint32_t calculate_H7_sectornum(stlink_t *, uint32_t, unsigned); +uint32_t calculate_H7_sectornum(stlink_t *, uint32_t, uint32_t); uint32_t calculate_L4_page(stlink_t *, uint32_t); #endif // CALCULATE_H diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index a4abf90d8..0392f15ff 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -196,7 +196,7 @@ void process_chipfile(char *fname) { void init_chipids(char *dir_to_scan) { DIR *d; - size_t nl; // namelen + uint32_t nl; // namelen struct dirent *dir; if (!dir_to_scan) { diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index d6477281d..70ecdd3a2 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -56,7 +56,7 @@ int32_t stlink_jtag_reset(stlink_t *, int32_t); int32_t stlink_soft_reset(stlink_t *, int32_t); void _parse_version(stlink_t *, stlink_version_t *); static uint8_t stlink_parse_hex(const char *); -static int32_t stlink_read(stlink_t *, stm32_addr_t, size_t, save_block_fn, void *); +static int32_t stlink_read(stlink_t *, stm32_addr_t, uint32_t, save_block_fn, void *); static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg *, int32_t, stm32_addr_t); static bool stlink_fread_ihex_worker(void *, uint8_t *, ssize_t); static bool stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg *); @@ -323,8 +323,8 @@ int32_t stlink_load_device_params(stlink_t *sl) { } ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", - params->dev_type, (uint32_t)(sl->sram_size / 1024), (uint32_t)(sl->flash_size / 1024), - (sl->flash_pgsz < 1024) ? (uint32_t)(sl->flash_pgsz) : (uint32_t)(sl->flash_pgsz / 1024), + params->dev_type, (sl->sram_size / 1024), (sl->flash_size / 1024), + (sl->flash_pgsz < 1024) ? sl->flash_pgsz : (sl->flash_pgsz / 1024), (sl->flash_pgsz < 1024) ? "byte" : "KiB"); return (0); @@ -609,7 +609,7 @@ int32_t stlink_trace_disable(stlink_t *sl) { } // 276 -int32_t stlink_trace_read(stlink_t *sl, uint8_t *buf, size_t size) { +int32_t stlink_trace_read(stlink_t *sl, uint8_t *buf, uint32_t size) { return (sl->backend->trace_read(sl, buf, size)); } @@ -645,8 +645,8 @@ int32_t stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, stm32_a // write the file in sram at addr int32_t error = -1; - size_t off; - size_t len; + uint32_t off; + uint32_t len; // check addr range is inside the sram if (addr < sl->sram_base) { @@ -671,7 +671,7 @@ int32_t stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, stm32_a // do the copy by 1kB blocks for (off = 0; off < len; off += 1024) { - size_t size = 1024; + uint32_t size = 1024; if ((off + size) > len) { size = len - off; @@ -683,12 +683,12 @@ int32_t stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, stm32_a size += 2; } // round size if needed - stlink_write_mem32(sl, addr + (uint32_t)off, (uint16_t)size); + stlink_write_mem32(sl, addr + off, (uint16_t)size); } if (length > len) { memcpy(sl->q_buf, data + len, length - len); - stlink_write_mem8(sl, addr + (uint32_t)len, (uint16_t)(length - len)); + stlink_write_mem8(sl, addr + len, (uint16_t)(length - len)); } error = 0; // success @@ -703,8 +703,8 @@ int32_t stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { // write the file in sram at addr int32_t error = -1; - size_t off; - size_t len; + uint32_t off; + uint32_t len; mapped_file_t mf = MAPPED_FILE_INITIALIZER; if (map_file(&mf, path) == -1) { @@ -739,7 +739,7 @@ int32_t stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { // do the copy by 1kB blocks for (off = 0; off < len; off += 1024) { - size_t size = 1024; + uint32_t size = 1024; if ((off + size) > len) { size = len - off; @@ -751,12 +751,12 @@ int32_t stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { size += 2; } // round size if needed - stlink_write_mem32(sl, addr + (uint32_t)off, (uint16_t)size); + stlink_write_mem32(sl, addr + off, (uint16_t)size); } if (mf.len > len) { memcpy(sl->q_buf, mf.base + len, mf.len - len); - stlink_write_mem8(sl, addr + (uint32_t)len, (uint16_t)(mf.len - len)); + stlink_write_mem8(sl, addr + len, (uint16_t)(mf.len - len)); } // check the file has been written @@ -774,9 +774,9 @@ int32_t stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { } // 302 -int32_t stlink_fread(stlink_t *sl, const char *path, bool is_ihex, stm32_addr_t addr, size_t size) { +int32_t stlink_fread(stlink_t *sl, const char *path, bool is_ihex, stm32_addr_t addr, uint32_t size) { // read size bytes from addr to file - ILOG("read from address %#010x size %u\n", addr, (uint32_t)size); + ILOG("read from address %#010x size %u\n", addr, size); int32_t error; int32_t fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); @@ -808,11 +808,11 @@ int32_t stlink_fread(stlink_t *sl, const char *path, bool is_ihex, stm32_addr_t } // 300 -int32_t write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, size_t size) { +int32_t write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, uint32_t size) { // write the buffer right after the loader int32_t ret = 0; - size_t chunk = size & ~0x3; - size_t rem = size & 0x3; + uint32_t chunk = size & ~0x3; + uint32_t rem = size & 0x3; if (chunk) { memcpy(sl->q_buf, buf, chunk); @@ -821,7 +821,7 @@ int32_t write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *bu if (rem && !ret) { memcpy(sl->q_buf, buf + chunk, rem); - ret = stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, (uint16_t)rem); + ret = stlink_write_mem8(sl, (fl->buf_addr) + chunk, (uint16_t)rem); } return (ret); @@ -865,12 +865,12 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { } } - return ((uint32_t)sl->flash_pgsz); + return (sl->flash_pgsz); } // 279 int32_t stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **mem, - size_t *size, uint32_t *begin) { + uint32_t *size, uint32_t *begin) { int32_t res = 0; *begin = UINT32_MAX; uint8_t *data = NULL; @@ -896,7 +896,7 @@ int32_t stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **me data = calloc(*size, 1); // use calloc to get NULL if out of memory if (!data) { - ELOG("Cannot allocate %u bytes\n", (uint32_t)(*size)); + ELOG("Cannot allocate %u bytes\n", (*size)); res = -1; break; } @@ -926,7 +926,7 @@ int32_t stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **me break; } - size_t l = strlen(line); + uint32_t l = strlen(line); while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r')) { --l; @@ -942,7 +942,7 @@ int32_t stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **me uint8_t chksum = 0; // check sum - for (size_t i = 1; i < l; i += 2) { + for (uint32_t i = 1; i < l; i += 2) { chksum += stlink_parse_hex(line + i); } @@ -1215,8 +1215,7 @@ void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { } } -static int32_t stlink_read(stlink_t *sl, stm32_addr_t addr, size_t size, - save_block_fn fn, void *fn_arg) { +static int32_t stlink_read(stlink_t *sl, stm32_addr_t addr, uint32_t size, save_block_fn fn, void *fn_arg) { int32_t error = -1; @@ -1228,10 +1227,10 @@ static int32_t stlink_read(stlink_t *sl, stm32_addr_t addr, size_t size, size = sl->flash_size; } - size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; + uint32_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; - for (size_t off = 0; off < size; off += cmp_size) { - size_t aligned_size; + for (uint32_t off = 0; off < size; off += cmp_size) { + uint32_t aligned_size; // adjust last page size if ((off + cmp_size) > size) { @@ -1244,7 +1243,7 @@ static int32_t stlink_read(stlink_t *sl, stm32_addr_t addr, size_t size, aligned_size = (cmp_size + 4) & ~(4 - 1); } - stlink_read_mem32(sl, addr + (uint32_t)off, (uint16_t)aligned_size); + stlink_read_mem32(sl, addr + off, (uint16_t)aligned_size); if (!fn(fn_arg, sl->q_buf, aligned_size)) { goto on_error; diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 194fa7aab..70c8a2216 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -1027,10 +1027,8 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } // unlock program memory - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, - FLASH_L0_PRGKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, - FLASH_L0_PRGKEY2); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY2); // check pecr.prglock is cleared stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -1069,16 +1067,14 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { // set the page to erase if (sl->flash_type == STM32_FLASH_TYPE_G0) { - uint32_t flash_page = - ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); stlink_read_debug32(sl, FLASH_Gx_CR, &val); // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. val &= ~(0x3F << 3); val |= ((flash_page & 0x3F) << 3) | (1 << FLASH_CR_PER); stlink_write_debug32(sl, FLASH_Gx_CR, val); } else if (sl->flash_type == STM32_FLASH_TYPE_G4) { - uint32_t flash_page = - ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); stlink_read_debug32(sl, FLASH_Gx_CR, &val); // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. val &= ~(0x7F << 3); @@ -1088,13 +1084,11 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { uint32_t flash_page; stlink_read_debug32(sl, FLASH_L5_NSCR, &val); if (sl->flash_pgsz == 0x800 && (flashaddr - STM32_FLASH_BASE) >= sl->flash_size/2) { - flash_page = (flashaddr - STM32_FLASH_BASE - sl->flash_size/2) / - (uint32_t)(sl->flash_pgsz); + flash_page = (flashaddr - STM32_FLASH_BASE - sl->flash_size/2) / sl->flash_pgsz; // set bank 2 for erasure val |= (1 << FLASH_L5_NSCR_NSBKER); } else { - flash_page = - ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); // set bank 1 for erasure val &= ~(1 << FLASH_L5_NSCR_NSBKER); } @@ -1103,8 +1097,7 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); stlink_write_debug32(sl, FLASH_L5_NSCR, val); } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { - uint32_t flash_page = - ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); stlink_read_debug32(sl, FLASH_WB_CR, &val); // sec 3.10.5 - PNB[7:0] is offset by 3. @@ -1133,8 +1126,7 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { uint32_t bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; unlock_flash_if(sl); // unlock if locked - uint32_t sector = calculate_H7_sectornum( - sl, flashaddr, bank); // calculate the actual page from the address + uint32_t sector = calculate_H7_sectornum(sl, flashaddr, bank); // calculate the actual page from the address write_flash_cr_snb(sl, sector, bank); // select the page to erase set_flash_cr_strt(sl, bank); // start erase operation wait_flash_busy(sl); // wait for completion @@ -1147,7 +1139,7 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { return check_flash_error(sl); } -int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size) { +int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, uint32_t size, bool align_size) { // Check the address and size validity if (stlink_check_address_range_validity(sl, base_addr, size) < 0) { return -1; @@ -1247,7 +1239,7 @@ int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_ * Therfore it is turned off by default. */ if (sl->opt) { - idx = (uint32_t)length; + idx = length; for (num_empty = 0; num_empty != length; ++num_empty) if (data[--idx] != erased_pattern) { @@ -1270,9 +1262,8 @@ int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_ * still flash the whole file even if ignoring message is printed. */ err = stlink_write_flash(sl, addr, data, - (num_empty == length) ? (uint32_t)length - : (uint32_t)length - num_empty, - num_empty == length); + (num_empty == length) ? length : length - num_empty, + num_empty == length); stlink_fwrite_finalize(sl, addr); return (err); } @@ -1358,12 +1349,12 @@ int32_t stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { * @return 0 for success, -ve for failure */ int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length) { - size_t off; - size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; + uint32_t off; + uint32_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; ILOG("Starting verification of write complete\n"); for (off = 0; off < length; off += cmp_size) { - size_t aligned_size; + uint32_t aligned_size; // adjust last page size if ((off + cmp_size) > length) { @@ -1376,10 +1367,10 @@ int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *d aligned_size = (cmp_size + 4) & ~(4 - 1); } - stlink_read_mem32(sl, address + (uint32_t)off, (uint16_t)aligned_size); + stlink_read_mem32(sl, address + off, (uint16_t)aligned_size); if (memcmp(sl->q_buf, data + off, cmp_size)) { - ELOG("Verification of flash failed at offset: %u\n", (uint32_t)off); + ELOG("Verification of flash failed at offset: %u\n", off); return (-1); } } @@ -1389,7 +1380,7 @@ int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *d } // Check if an address and size are within the flash -int32_t stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size) { +int32_t stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, uint32_t size) { uint32_t logvar; if (addr < sl->flash_base || addr >= (sl->flash_base + sl->flash_size)) { logvar = sl->flash_base + sl->flash_size - 1; @@ -1436,7 +1427,7 @@ int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint3 ELOG("addr not a multiple of current pagesize (%u bytes), not supported, " "check page start address and compare with flash module organisation " "in related ST reference manual of your device.\n", - (uint32_t)(sl->flash_pgsz)); + sl->flash_pgsz); return (-1); } diff --git a/src/stlink-lib/common_flash.h b/src/stlink-lib/common_flash.h index fd1e51b9d..9b2b84057 100644 --- a/src/stlink-lib/common_flash.h +++ b/src/stlink-lib/common_flash.h @@ -37,13 +37,13 @@ void clear_flash_cr_pg(stlink_t *, uint32_t); // static void set_flash_cr_strt(stlink_t *sl, uint32_t bank); // static void set_flash_cr_mer(stlink_t *sl, bool v, uint32_t bank); int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr); -int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, size_t size, bool align_size); +int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, uint32_t size, bool align_size); int32_t stlink_erase_flash_mass(stlink_t *sl); int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_addr_t addr); int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr); int32_t stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr); int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length); -int32_t stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, size_t size); +int32_t stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, uint32_t size); int32_t stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr); int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint8_t eraseonly); void stlink_fwrite_finalize(stlink_t *, stm32_addr_t); diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 2bac1ace0..a862bd0e7 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -162,7 +162,7 @@ static const uint8_t loader_code_stm32f7_lv[] = { int32_t stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { - size_t size = 0; + uint32_t size = 0; uint32_t dfsr, cfsr, hfsr; /* Interrupt masking according to DDI0419C, Table C1-7 firstly force halt */ @@ -172,8 +172,7 @@ int32_t stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { /* and only then disable interrupts */ stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | - STLINK_REG_DHCSR_C_HALT | - STLINK_REG_DHCSR_C_MASKINTS); + STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_MASKINTS); // allocate the loader in SRAM if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { @@ -182,7 +181,7 @@ int32_t stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { } // allocate a one page buffer in SRAM right after loader - fl->buf_addr = fl->loader_addr + (uint32_t)size; + fl->buf_addr = fl->loader_addr + size; ILOG("Successfully loaded flash loader in sram\n"); // set address of IWDG key register for reset it @@ -210,9 +209,9 @@ int32_t stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { } static int32_t loader_v_dependent_assignment(stlink_t *sl, - const uint8_t **loader_code, size_t *loader_size, - const uint8_t *high_v_loader, size_t high_v_loader_size, - const uint8_t *low_v_loader, size_t low_v_loader_size) { + const uint8_t **loader_code, uint32_t *loader_size, + const uint8_t *high_v_loader, uint32_t high_v_loader_size, + const uint8_t *low_v_loader, uint32_t low_v_loader_size) { int32_t retval = 0; if ( sl->version.stlink_v == 1) { @@ -239,9 +238,9 @@ static int32_t loader_v_dependent_assignment(stlink_t *sl, return(retval); } -int32_t stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { +int32_t stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, uint32_t* size) { const uint8_t* loader_code; - size_t loader_size; + uint32_t loader_size; if (sl->chip_id == STM32_CHIPID_L1_MD || sl->chip_id == STM32_CHIPID_L1_CAT2 || @@ -330,13 +329,13 @@ int32_t stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size return(0); // success } -int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { +int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, uint32_t size) { struct stlink_reg rr; uint32_t timeout; uint32_t flash_base = 0; uint32_t dhcsr, dfsr, cfsr, hfsr; - DLOG("Running flash loader, write address:%#x, size: %u\n", target, (uint32_t)size); + DLOG("Running flash loader, write address:%#x, size: %u\n", target, size); if (write_buffer_to_sram(sl, fl, buf, size) == -1) { ELOG("write_buffer_to_sram() == -1\n"); @@ -350,7 +349,7 @@ int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t t /* Setup core */ stlink_write_reg(sl, fl->buf_addr, 0); // source stlink_write_reg(sl, target, 1); // target - stlink_write_reg(sl, (uint32_t)size, 2); // count + stlink_write_reg(sl, size, 2); // count stlink_write_reg(sl, flash_base, 3); // flash register base // only used on VL/F1_XL, but harmless for others stlink_write_reg(sl, fl->loader_addr, 15); // pc register @@ -417,8 +416,7 @@ int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t t WLOG("Loader state: R2 0x%X R15 0x%X\n", rr.r[2], rr.r[15]); if (dhcsr != 0x3000B || dfsr || cfsr || hfsr) { - WLOG("MCU state: DHCSR 0x%X DFSR 0x%X CFSR 0x%X HFSR 0x%X\n", - dhcsr, dfsr, cfsr, hfsr); + WLOG("MCU state: DHCSR 0x%X DFSR 0x%X CFSR 0x%X HFSR 0x%X\n", dhcsr, dfsr, cfsr, hfsr); } return(-1); @@ -450,8 +448,7 @@ int32_t stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, for (count = 0; count < num_half_pages; count++) { if (use_loader) { - ret = stlink_flash_loader_run(sl, &fl, addr + count * pagesize, - base + count * pagesize, pagesize); + ret = stlink_flash_loader_run(sl, &fl, addr + count * pagesize, base + count * pagesize, pagesize); if (ret && count == 0) { /* It seems that stm32lx devices have a problem when it is blank */ WLOG("Failed to use flash loader, fallback to soft write\n"); @@ -461,7 +458,7 @@ int32_t stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, if (!use_loader) { ret = 0; for (off = 0; off < pagesize && !ret; off += 64) { - size_t chunk = (pagesize - off > 64) ? 64 : pagesize - off; + uint32_t chunk = (pagesize - off > 64) ? 64 : pagesize - off; memcpy(sl->q_buf, base + count * pagesize + off, chunk); ret = stlink_write_mem32(sl, addr + count * pagesize + off, (uint16_t)chunk); } @@ -632,9 +629,7 @@ int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { ILOG("enabling 32-bit flash writes\n"); write_flash_cr_psiz(sl, 2, BANK_1); } else { - ILOG("Target voltage (%d mV) too low for 32-bit flash, " - "using 8-bit flash writes\n", - voltage); + ILOG("Target voltage (%d mV) too low for 32-bit flash, using 8-bit flash writes\n", voltage); write_flash_cr_psiz(sl, 0, BANK_1); } } @@ -656,10 +651,8 @@ int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { uint32_t flash_regs_base = get_stm32l0_flash_base(sl); // disable pecr protection - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, - FLASH_L0_PEKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, - FLASH_L0_PEKEY2); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY2); // check pecr.pelock is cleared stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -669,10 +662,8 @@ int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { } // unlock program memory - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, - FLASH_L0_PRGKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, - FLASH_L0_PRGKEY2); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY2); // check pecr.prglock is cleared stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -728,17 +719,15 @@ int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { } int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t *base, uint32_t len) { - size_t off; + uint32_t off; if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || (sl->flash_type == STM32_FLASH_TYPE_F7) || (sl->flash_type == STM32_FLASH_TYPE_L4)) { - size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; + uint32_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; for (off = 0; off < len;) { - size_t size = len - off > buf_size ? buf_size : len - off; - if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, - size) == -1) { - ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", - (uint32_t)(addr + off)); + uint32_t size = len - off > buf_size ? buf_size : len - off; + if (stlink_flash_loader_run(sl, fl, addr + off, base + off, size) == -1) { + ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", (addr + off)); check_flash_error(sl); return (-1); } @@ -749,38 +738,34 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4 || sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - DLOG("Starting %3u page write\r\n", (uint32_t)(len / sl->flash_pgsz)); + DLOG("Starting %3u page write\n", len / sl->flash_pgsz); for (off = 0; off < len; off += sizeof(uint32_t)) { uint32_t data; if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { - fprintf(stdout, "\r%3u/%3u pages written", - (uint32_t)(off / sl->flash_pgsz + 1), - (uint32_t)(len / sl->flash_pgsz)); + fprintf(stdout, "\r%3u/%3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); fflush(stdout); } // write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); data = 0; memcpy(&data, base + off, (len - off) < 4 ? (len - off) : 4); - stlink_write_debug32(sl, addr + (uint32_t)off, data); + stlink_write_debug32(sl, addr + off, data); wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear } fprintf(stdout, "\n"); // flash writes happen as 2 words at a time if ((off / sizeof(uint32_t)) % 2 != 0) { - stlink_write_debug32(sl, addr + (uint32_t)off, - 0); // write a single word of zeros - wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear + stlink_write_debug32(sl, addr + off, 0); // write a single word of zeros + wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear } } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { uint32_t val; uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - uint32_t pagesize = (flash_regs_base == FLASH_L0_REGS_ADDR)? - L0_WRITE_BLOCK_SIZE:L1_WRITE_BLOCK_SIZE; + uint32_t pagesize = (flash_regs_base == FLASH_L0_REGS_ADDR)? L0_WRITE_BLOCK_SIZE : L1_WRITE_BLOCK_SIZE; - DLOG("Starting %3u page write\r\n", (uint32_t)(len / sl->flash_pgsz)); + DLOG("Starting %3u page write\r\n", len / sl->flash_pgsz); off = 0; @@ -797,14 +782,12 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t uint32_t data; if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { - fprintf(stdout, "\r%3u/%3u pages written", - (uint32_t)(off / sl->flash_pgsz + 1), - (uint32_t)(len / sl->flash_pgsz)); + fprintf(stdout, "\r%3u/%3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); fflush(stdout); } write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); - stlink_write_debug32(sl, addr + (uint32_t)off, data); + stlink_write_debug32(sl, addr + off, data); // wait for sr.busy to be cleared do { @@ -814,22 +797,19 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t // TODO: check redo write operation } fprintf(stdout, "\n"); - } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { + } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { int32_t write_block_count = 0; for (off = 0; off < len; off += sl->flash_pgsz) { // adjust last write size - size_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; + uint32_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; // unlock and set programming mode unlock_flash_if(sl); DLOG("Finished unlocking flash, running loader!\n"); - if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, - size) == -1) { - ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", - (uint32_t)(addr + off)); + if (stlink_flash_loader_run(sl, fl, addr + off, base + off, size) == -1) { + ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", (addr + off)); check_flash_error(sl); return (-1); } @@ -840,7 +820,7 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t // show progress; writing procedure is slow and previous errors are // misleading fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, - (uint32_t)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); + (len + sl->flash_pgsz - 1) / sl->flash_pgsz); fflush(stdout); } } @@ -850,17 +830,16 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { for (off = 0; off < len;) { // Program STM32H7x with 64-byte Flash words - size_t chunk = (len - off > 64) ? 64 : len - off; + uint32_t chunk = (len - off > 64) ? 64 : len - off; memcpy(sl->q_buf, base + off, chunk); - stlink_write_mem32(sl, addr + (uint32_t)off, 64); + stlink_write_mem32(sl, addr + off, 64); wait_flash_busy(sl); off += chunk; if (sl->verbose >= 1) { // show progress - fprintf(stdout, "\r%u/%u bytes written", (uint32_t)off, - (uint32_t)len); + fprintf(stdout, "\r%u/%u bytes written", off, len); fflush(stdout); } } diff --git a/src/stlink-lib/flash_loader.h b/src/stlink-lib/flash_loader.h index 06eb53d12..33edc7ac6 100644 --- a/src/stlink-lib/flash_loader.h +++ b/src/stlink-lib/flash_loader.h @@ -9,11 +9,11 @@ int32_t stlink_flash_loader_init(stlink_t *sl, flash_loader_t* fl); // static int32_t loader_v_dependent_assignment(stlink_t *sl, -// const uint8_t **loader_code, size_t *loader_size, -// const uint8_t *high_v_loader, size_t high_v_loader_size, -// const uint8_t *low_v_loader, size_t low_v_loader_size); -int32_t stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); -int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size); +// const uint8_t **loader_code, uint32_t *loader_size, +// const uint8_t *high_v_loader, uint32_t high_v_loader_size, +// const uint8_t *low_v_loader, uint32_t low_v_loader_size); +int32_t stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, uint32_t* size); +int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, uint32_t size); /* === Functions from old header file flashloader.h === */ diff --git a/src/stlink-lib/map_file.c b/src/stlink-lib/map_file.c index 5e3d14a5d..e8c4b71a3 100644 --- a/src/stlink-lib/map_file.c +++ b/src/stlink-lib/map_file.c @@ -28,17 +28,17 @@ * STLINK2 Maybe STLINK V1 needs smaller value! */ int32_t check_file(stlink_t *sl, mapped_file_t *mf, stm32_addr_t addr) { - size_t off; - size_t n_cmp = sl->flash_pgsz; + uint32_t off; + uint32_t n_cmp = sl->flash_pgsz; if (n_cmp > 0x1800) { n_cmp = 0x1800; } for (off = 0; off < mf->len; off += n_cmp) { - size_t aligned_size; + uint32_t aligned_size; - size_t cmp_size = n_cmp; // adjust last page size + uint32_t cmp_size = n_cmp; // adjust last page size if ((off + n_cmp) > mf->len) { cmp_size = mf->len - off; @@ -50,7 +50,7 @@ int32_t check_file(stlink_t *sl, mapped_file_t *mf, stm32_addr_t addr) { aligned_size = (cmp_size + 4) & ~(4 - 1); } - stlink_read_mem32(sl, addr + (uint32_t)off, (uint16_t)aligned_size); + stlink_read_mem32(sl, addr + off, (uint16_t)aligned_size); if (memcmp(sl->q_buf, mf->base + off, cmp_size)) { return (-1); @@ -80,7 +80,7 @@ int32_t map_file(mapped_file_t *mf, const char *path) { // on 32 bit systems, check if there is an overflow if (st.st_size > (off_t)MAX_FILE_SIZE /*1 GB*/ ) { // limit file size to 1 GB - fprintf(stderr, "mmap() size_t overflow for file %s\n", path); + fprintf(stderr, "mmap() uint32_t overflow for file %s\n", path); goto on_error; } } diff --git a/src/stlink-lib/map_file.h b/src/stlink-lib/map_file.h index ba50e25e9..f25602d1e 100644 --- a/src/stlink-lib/map_file.h +++ b/src/stlink-lib/map_file.h @@ -20,7 +20,7 @@ /* Memory mapped file */ typedef struct mapped_file { uint8_t *base; - size_t len; + uint32_t len; } mapped_file_t; #define MAPPED_FILE_INITIALIZER \ diff --git a/src/stlink-lib/md5.c b/src/stlink-lib/md5.c index 9481acf0f..a5347de59 100644 --- a/src/stlink-lib/md5.c +++ b/src/stlink-lib/md5.c @@ -34,7 +34,7 @@ void stlink_checksum(mapped_file_t *mp) { uint32_t sum = 0; uint8_t *mp_byte = (uint8_t *)mp->base; - for (size_t i = 0; i < mp->len; ++i) { + for (uint32_t i = 0; i < mp->len; ++i) { sum += mp_byte[i]; } diff --git a/src/stlink-lib/option_bytes.h b/src/stlink-lib/option_bytes.h index ffeef8a0f..7ab3e2952 100644 --- a/src/stlink-lib/option_bytes.h +++ b/src/stlink-lib/option_bytes.h @@ -44,4 +44,4 @@ int32_t stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); int32_t stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte); int32_t stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add); -#endif // OPTION_BYTES_H \ No newline at end of file +#endif // OPTION_BYTES_H diff --git a/src/stlink-lib/read_write.c b/src/stlink-lib/read_write.c index 6ee697d66..9149080af 100644 --- a/src/stlink-lib/read_write.c +++ b/src/stlink-lib/read_write.c @@ -36,7 +36,7 @@ int32_t stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { ret = sl->backend->read_debug32(sl, addr, data); if (!ret) - DLOG("*** stlink_read_debug32 %#010x at %#010x\n", *data, addr); + DLOG("*** stlink_read_debug32 %#010x at %#010x\n", *data, addr); return (ret); } diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index 0aa7a0d68..d7f844b51 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -103,7 +103,7 @@ #define STLINK_FALSE 0x81 static void clear_cdb(struct stlink_libsg *sl) { - for (size_t i = 0; i < sizeof(sl->cdb_cmd_blk); i++) { sl->cdb_cmd_blk[i] = 0; } + for (uint32_t i = 0; i < sizeof(sl->cdb_cmd_blk); i++) { sl->cdb_cmd_blk[i] = 0; } // set default sl->cdb_cmd_blk[0] = STLINK_DEBUG_COMMAND; diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index fc1dcbb4e..772fb147f 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -90,8 +90,8 @@ void _stlink_usb_close(stlink_t* sl) { } } -ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char* txbuf, size_t txsize, - unsigned char* rxbuf, size_t rxsize, int32_t check_error, const char *cmd) { +ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char* txbuf, uint32_t txsize, + unsigned char* rxbuf, uint32_t rxsize, int32_t check_error, const char *cmd) { // Note: txbuf and rxbuf can point to the same area int32_t res, t, retry = 0; @@ -168,7 +168,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char } static inline int32_t send_only(struct stlink_libusb* handle, int32_t terminate, unsigned char* txbuf, - size_t txsize, const char *cmd) { + uint32_t txsize, const char *cmd) { return((int32_t)send_recv(handle, terminate, txbuf, txsize, NULL, 0, CMD_CHECK_NO, cmd)); } @@ -1000,7 +1000,7 @@ int32_t _stlink_usb_disable_trace(stlink_t* sl) { return(size<0?-1:0); } -int32_t _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size) { +int32_t _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, uint32_t size) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -1160,7 +1160,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, if (ret) { continue; } // could not open device - size_t serial_len = stlink_serial(handle, &desc, sl->serial); + uint32_t serial_len = stlink_serial(handle, &desc, sl->serial); libusb_close(handle); @@ -1300,12 +1300,12 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, return(NULL); } -static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], enum connect_type connect, int32_t freq) { +static uint32_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], enum connect_type connect, int32_t freq) { stlink_t **_sldevs; libusb_device *dev; int32_t i = 0; - size_t slcnt = 0; - size_t slcur = 0; + uint32_t slcnt = 0; + uint32_t slcur = 0; /* Count STLINKs */ while ((dev = devs[i++]) != NULL) { @@ -1363,7 +1363,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], e break; } - size_t serial_len = stlink_serial(handle, &desc, serial); + uint32_t serial_len = stlink_serial(handle, &desc, serial); libusb_close(handle); @@ -1388,7 +1388,7 @@ size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int32_t libusb_device **devs; stlink_t **sldevs; - size_t slcnt = 0; + uint32_t slcnt = 0; int32_t r; ssize_t cnt; @@ -1410,10 +1410,10 @@ size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int32_t return(slcnt); } -void stlink_probe_usb_free(stlink_t ***stdevs, size_t size) { +void stlink_probe_usb_free(stlink_t ***stdevs, uint32_t size) { if (stdevs == NULL || *stdevs == NULL || size == 0) { return; } - for (size_t n = 0; n < size; n++) { stlink_close((*stdevs)[n]); } + for (uint32_t n = 0; n < size; n++) { stlink_close((*stdevs)[n]); } free(*stdevs); *stdevs = NULL; diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index dd30cc529..2ec7490ad 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -62,10 +62,10 @@ struct stlink_libusb { // static inline uint32_t le_to_h_u32(const uint8_t* buf); // static int32_t _stlink_match_speed_map(const uint32_t *map, uint32_t map_size, uint32_t khz); void _stlink_usb_close(stlink_t* sl); -ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char* txbuf, size_t txsize, - unsigned char* rxbuf, size_t rxsize, int32_t check_error, const char *cmd); +ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char* txbuf, uint32_t txsize, + unsigned char* rxbuf, uint32_t rxsize, int32_t check_error, const char *cmd); // static inline int32_t send_only(struct stlink_libusb* handle, int32_t terminate, unsigned char* txbuf, -// size_t txsize, const char *cmd); +// uint32_t txsize, const char *cmd); // static int32_t fill_command(stlink_t * sl, enum SCSI_Generic_Direction dir, uint32_t len); int32_t _stlink_usb_version(stlink_t *sl); int32_t _stlink_usb_target_voltage(stlink_t *sl); @@ -96,14 +96,14 @@ int32_t _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int32_t r_ int32_t _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int32_t idx); int32_t _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency); int32_t _stlink_usb_disable_trace(stlink_t* sl); -int32_t _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, size_t size); +int32_t _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, uint32_t size); // static stlink_backend_t _stlink_usb_backend = { }; size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_descriptor *desc, char *serial); stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int32_t freq); -// static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], enum connect_type connect, int32_t freq); +// static uint32_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], enum connect_type connect, int32_t freq); size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int32_t freq); -void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); +void stlink_probe_usb_free(stlink_t **stdevs[], uint32_t size); #endif // USB_H diff --git a/src/win32/getopt/getopt.c b/src/win32/getopt/getopt.c index 7bc8d2d20..417b0aecf 100644 --- a/src/win32/getopt/getopt.c +++ b/src/win32/getopt/getopt.c @@ -134,7 +134,7 @@ int32_t getopt_long(int32_t argc, const struct option* o = longopts; const struct option* match = NULL; int32_t num_matches = 0; - size_t argument_name_length = 0; + uint32_t argument_name_length = 0; const char* current_argument = NULL; int32_t retval = -1; diff --git a/src/win32/mmap.c b/src/win32/mmap.c index ea8a3cb37..7e76b3344 100644 --- a/src/win32/mmap.c +++ b/src/win32/mmap.c @@ -6,7 +6,7 @@ #include "mmap.h" -void *mmap (void *addr, size_t len, int32_t prot, int32_t flags, int32_t fd, int64_t offset) { +void *mmap (void *addr, uint32_t len, int32_t prot, int32_t flags, int32_t fd, int64_t offset) { void *buf; ssize_t count; @@ -32,7 +32,7 @@ void *mmap (void *addr, size_t len, int32_t prot, int32_t flags, int32_t fd, int (void)flags; } -int32_t munmap (void *addr, size_t len) { +int32_t munmap (void *addr, uint32_t len) { free (addr); return(0); (void)len; diff --git a/src/win32/mmap.h b/src/win32/mmap.h index e8bbab0bc..633816b50 100644 --- a/src/win32/mmap.h +++ b/src/win32/mmap.h @@ -15,8 +15,8 @@ #define MAP_ANONYMOUS (1 << 5) #define MAP_FAILED ((void *)-1) -void *mmap(void *addr, size_t len, int32_t prot, int32_t flags, int32_t fd, int64_t offset); -int32_t munmap(void *addr, size_t len); +void *mmap(void *addr, uint32_t len, int32_t prot, int32_t flags, int32_t fd, int64_t offset); +int32_t munmap(void *addr, uint32_t len); #endif // STLINK_HAVE_SYS_MMAN_H diff --git a/tests/flash.c b/tests/flash.c index a40be0c74..67436ecb1 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -26,7 +26,7 @@ static bool cmp_strings(const char * s1, const char * s2) { } } -static bool cmp_mem(const uint8_t * s1, const uint8_t * s2, size_t size) { +static bool cmp_mem(const uint8_t * s1, const uint8_t * s2, uint32_t size) { if (s1 == NULL || s2 == NULL) { return (s1 == s2); } else { @@ -231,7 +231,7 @@ static struct Test tests[] = { int32_t main() { bool allOk = true; - for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) + for (uint32_t i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) if (!execute_test(&tests[i])) allOk = false; From 5d3f3ec7f492b76ce7f1ba4327eeeeeff13c5be8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 10 Jun 2023 21:37:01 +0200 Subject: [PATCH 1385/1435] Set flash_type for STM32H5 devices --- config/chips/H5xx.chip | 2 +- config/chips/L5x5xx.chip | 2 +- config/chips/U5x5.chip | 2 +- inc/stm32.h | 2 +- src/stlink-lib/chipid.c | 4 +-- src/stlink-lib/common_flash.c | 52 ++++++++++++++++------------------- src/stlink-lib/flash_loader.c | 12 ++++---- 7 files changed, 36 insertions(+), 40 deletions(-) diff --git a/config/chips/H5xx.chip b/config/chips/H5xx.chip index a1c438999..8484fbc18 100644 --- a/config/chips/H5xx.chip +++ b/config/chips/H5xx.chip @@ -3,7 +3,7 @@ dev_type STM32H5xx ref_manual_id 0481 chip_id 0x484 // STM32_CHIPID_H5xx -flash_type L5_U5 // ? +flash_type L5_U5_H5 flash_size_reg 0x08fff80c flash_pagesize 0x2000 // 8 KB sram_size 0xa0000 // 640 KB diff --git a/config/chips/L5x5xx.chip b/config/chips/L5x5xx.chip index 0f205a62b..eace313d0 100644 --- a/config/chips/L5x5xx.chip +++ b/config/chips/L5x5xx.chip @@ -3,7 +3,7 @@ dev_type STM32L5x2xx ref_manual_id 0438 chip_id 0x472 // STM32_CHIPID_L5x2xx -flash_type L5_U5 +flash_type L5_U5_H5 flash_size_reg 0x0bfa05e0 flash_pagesize 0x1000 // 4 KB sram_size 0x40000 // 256 KB diff --git a/config/chips/U5x5.chip b/config/chips/U5x5.chip index 5f71436ef..82964b1c3 100644 --- a/config/chips/U5x5.chip +++ b/config/chips/U5x5.chip @@ -3,7 +3,7 @@ dev_type STM32U5x5 ref_manual_id 0456 chip_id 0x482 // STM32_CHIPID_U5x5 -flash_type L5_U5 +flash_type L5_U5_H5 flash_size_reg 0x0bfa07a0 flash_pagesize 0x2000 // 8 KB sram_size 0xc4800 // 786 KB diff --git a/inc/stm32.h b/inc/stm32.h index eee1b0433..cf9a8a2ad 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -60,7 +60,7 @@ enum stm32_flash_type { STM32_FLASH_TYPE_H7 = 7, STM32_FLASH_TYPE_L0_L1 = 8, STM32_FLASH_TYPE_L4 = 9, - STM32_FLASH_TYPE_L5_U5 = 10, + STM32_FLASH_TYPE_L5_U5_H5 = 10, STM32_FLASH_TYPE_WB_WL = 11, }; diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 0392f15ff..06edb26f3 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -115,8 +115,8 @@ void process_chipfile(char *fname) { ts->flash_type = STM32_FLASH_TYPE_L0_L1; } else if (strcmp(value, "L4") == 0) { ts->flash_type = STM32_FLASH_TYPE_L4; - } else if (strcmp(value, "L5_U5") == 0) { - ts->flash_type = STM32_FLASH_TYPE_L5_U5; + } else if (strcmp(value, "L5_U5_H5") == 0) { + ts->flash_type = STM32_FLASH_TYPE_L5_U5_H5; } else if (strcmp(value, "WB_WL") == 0) { ts->flash_type = STM32_FLASH_TYPE_WB_WL; } else { diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 70c8a2216..f2281ac11 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -56,7 +56,7 @@ uint32_t read_flash_cr(stlink_t *sl, uint32_t bank) { reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { reg = FLASH_L4_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { reg = FLASH_L5_NSCR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { reg = FLASH_WB_CR; @@ -101,7 +101,7 @@ void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { cr_reg = FLASH_L4_CR; cr_lock_shift = FLASH_L4_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { cr_reg = FLASH_L5_NSCR; cr_lock_shift = FLASH_L5_NSCR_NSLOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { @@ -147,7 +147,7 @@ static inline int32_t write_flash_sr(stlink_t *sl, uint32_t bank, uint32_t val) sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { sr_reg = FLASH_L4_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { sr_reg = FLASH_L5_NSSR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { sr_reg = FLASH_WB_SR; @@ -190,7 +190,7 @@ void clear_flash_error(stlink_t *sl) { case STM32_FLASH_TYPE_L4: write_flash_sr(sl, BANK_1, FLASH_L4_SR_ERROR_MASK); break; - case STM32_FLASH_TYPE_L5_U5: + case STM32_FLASH_TYPE_L5_U5_H5: write_flash_sr(sl, BANK_1, FLASH_L5_NSSR_ERROR_MASK); break; case STM32_FLASH_TYPE_WB_WL: @@ -220,7 +220,7 @@ uint32_t read_flash_sr(stlink_t *sl, uint32_t bank) { sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { sr_reg = FLASH_L4_SR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { sr_reg = FLASH_L5_NSSR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { sr_reg = FLASH_WB_SR; @@ -252,7 +252,7 @@ uint32_t is_flash_busy(stlink_t *sl) { sr_busy_shift = FLASH_H7_SR_QW; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { sr_busy_shift = FLASH_L4_SR_BSY; - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { sr_busy_shift = FLASH_L5_NSSR_BSY; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { sr_busy_shift = FLASH_WB_SR_BSY; @@ -335,7 +335,7 @@ int32_t check_flash_error(stlink_t *sl) { PROGERR = (1 << FLASH_L4_SR_PROGERR); PGAERR = (1 << FLASH_L4_SR_PGAERR); break; - case STM32_FLASH_TYPE_L5_U5: + case STM32_FLASH_TYPE_L5_U5_H5: res = read_flash_sr(sl, BANK_1) & FLASH_L5_NSSR_ERROR_MASK; WRPERR = (1 << FLASH_L5_NSSR_NSWRPERR); PROGERR = (1 << FLASH_L5_NSSR_NSPROGERR); @@ -401,7 +401,7 @@ static inline uint32_t is_flash_locked(stlink_t *sl) { } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { cr_reg = FLASH_L4_CR; cr_lock_shift = FLASH_L4_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { cr_reg = FLASH_L5_NSCR; cr_lock_shift = FLASH_L5_NSCR_NSLOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { @@ -448,7 +448,7 @@ static void unlock_flash(stlink_t *sl) { flash_key2 = FLASH_L0_PEKEY2; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { key_reg = FLASH_L4_KEYR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { // Set voltage scaling to range 0 to perform flash operations (RM0438 p. 183) uint32_t mask = (0b11 << STM32L5_PWR_CR1_VOS); uint32_t val; @@ -526,7 +526,7 @@ int32_t lock_flash_option(stlink_t *sl) { optcr_reg = FLASH_L4_CR; optlock_shift = FLASH_L4_CR_OPTLOCK; break; - case STM32_FLASH_TYPE_L5_U5: + case STM32_FLASH_TYPE_L5_U5_H5: optcr_reg = FLASH_L5_NSCR; optlock_shift = FLASH_L5_NSCR_OPTLOCK; break; @@ -601,7 +601,7 @@ static bool is_flash_option_locked(stlink_t *sl) { optcr_reg = FLASH_L4_CR; optlock_shift = FLASH_L4_CR_OPTLOCK; break; - case STM32_FLASH_TYPE_L5_U5: + case STM32_FLASH_TYPE_L5_U5_H5: optcr_reg = FLASH_L5_NSCR; optlock_shift = FLASH_L5_NSCR_OPTLOCK; break; @@ -658,7 +658,7 @@ static int32_t unlock_flash_option(stlink_t *sl) { case STM32_FLASH_TYPE_L4: optkey_reg = FLASH_L4_OPTKEYR; break; - case STM32_FLASH_TYPE_L5_U5: + case STM32_FLASH_TYPE_L5_U5_H5: optkey_reg = FLASH_L5_OPTKEYR; break; case STM32_FLASH_TYPE_WB_WL: @@ -734,7 +734,7 @@ void clear_flash_cr_pg(stlink_t *sl, uint32_t bank) { bit = FLASH_H7_CR_PG; } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { cr_reg = FLASH_L4_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { cr_reg = FLASH_L5_NSCR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = FLASH_WB_CR; @@ -801,7 +801,7 @@ static void set_flash_cr_per(stlink_t *sl, uint32_t bank) { if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = FLASH_Gx_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { cr_reg = FLASH_L5_NSCR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = FLASH_WB_CR; @@ -820,7 +820,7 @@ static void clear_flash_cr_per(stlink_t *sl, uint32_t bank) { if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = FLASH_Gx_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { cr_reg = FLASH_L5_NSCR; } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = FLASH_WB_CR; @@ -867,7 +867,7 @@ static void set_flash_cr_strt(stlink_t *sl, uint32_t bank) { } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { cr_reg = FLASH_L4_CR; cr_strt = (1 << FLASH_L4_CR_STRT); - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { cr_reg = FLASH_L5_NSCR; cr_strt = (1 << FLASH_L5_NSCR_NSSTRT); } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { @@ -910,7 +910,7 @@ static void set_flash_cr_mer(stlink_t *sl, bool v, uint32_t bank) { cr_reg = FLASH_L4_CR; cr_mer = (1 << FLASH_L4_CR_MER1) | (1 << FLASH_L4_CR_MER2); cr_pg = (1 << FLASH_L4_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { cr_reg = FLASH_L5_NSCR; cr_mer = (1 << FLASH_L5_NSCR_NSMER1) | (1 << FLASH_L5_NSCR_NSMER2); cr_pg = (1 << FLASH_L5_NSCR_NSPG); @@ -1059,7 +1059,7 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4 || - sl->flash_type == STM32_FLASH_TYPE_L5_U5 || + sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5 || sl->flash_type == STM32_FLASH_TYPE_WB_WL) { uint32_t val; unlock_flash_if(sl); @@ -1080,7 +1080,7 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { val &= ~(0x7F << 3); val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); stlink_write_debug32(sl, FLASH_Gx_CR, val); - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { uint32_t flash_page; stlink_read_debug32(sl, FLASH_L5_NSCR, &val); if (sl->flash_pgsz == 0x800 && (flashaddr - STM32_FLASH_BASE) >= sl->flash_size/2) { @@ -1182,7 +1182,7 @@ int32_t stlink_erase_flash_mass(stlink_t *sl) { // TODO: User MER bit to mass-erase WB series. if (sl->flash_type == STM32_FLASH_TYPE_L0_L1 || - sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + sl->flash_type == STM32_FLASH_TYPE_WB_WL) { err = stlink_erase_flash_section(sl, sl->flash_base, sl->flash_size, false); @@ -1191,8 +1191,7 @@ int32_t stlink_erase_flash_mass(stlink_t *sl) { clear_flash_error(sl); unlock_flash_if(sl); - if (sl->flash_type == STM32_FLASH_TYPE_H7 && - sl->chip_id != STM32_CHIPID_H7Ax) { + if (sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_id != STM32_CHIPID_H7Ax) { // set parallelism write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { @@ -1205,8 +1204,7 @@ int32_t stlink_erase_flash_mass(stlink_t *sl) { sl, BANK_1); // start erase operation, reset by hw with busy bit if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || - (sl->flash_type == STM32_FLASH_TYPE_H7 && - sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { + (sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { set_flash_cr_mer(sl, 1, BANK_2); // set the mass erase bit in bank 2 set_flash_cr_strt(sl, BANK_2); // start erase operation in bank 2 } @@ -1217,8 +1215,7 @@ int32_t stlink_erase_flash_mass(stlink_t *sl) { // reset the mass erase bit set_flash_cr_mer(sl, 0, BANK_1); if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || - (sl->flash_type == STM32_FLASH_TYPE_H7 && - sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { + (sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { set_flash_cr_mer(sl, 0, BANK_2); } @@ -1316,8 +1313,7 @@ int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { * still flash the whole file even if ignoring message is printed. */ err = stlink_write_flash(sl, addr, mf.base, - (num_empty == mf.len) ? (uint32_t)mf.len - : (uint32_t)mf.len - num_empty, + (num_empty == mf.len) ? (uint32_t)mf.len : (uint32_t)mf.len - num_empty, num_empty == mf.len); stlink_fwrite_finalize(sl, addr); unmap_file(&mf); diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index a862bd0e7..0ab8cf6c1 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -501,7 +501,7 @@ static void set_flash_cr_pg(stlink_t *sl, uint32_t bank) { cr_reg = FLASH_L4_CR; x &= ~FLASH_L4_CR_OPBITS; x |= (1 << FLASH_L4_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { cr_reg = FLASH_L5_NSCR; x |= (1 << FLASH_CR_PG); } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || @@ -556,7 +556,7 @@ static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int32_t bckpRstr) { rcc_dma_mask = STM32L0_RCC_DMAEN; } break; - case STM32_FLASH_TYPE_L5_U5: + case STM32_FLASH_TYPE_L5_U5_H5: rcc = STM32L5_RCC_AHB1ENR; rcc_dma_mask = STM32L5_RCC_DMAEN; break; @@ -639,8 +639,8 @@ int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4 || - sl->flash_type == STM32_FLASH_TYPE_L5_U5) { - ILOG("Starting Flash write for WB/G0/G4/L5/U5\n"); + sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { + ILOG("Starting Flash write for WB/G0/G4/L5/U5/H5\n"); unlock_flash_if(sl); // unlock flash if necessary set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit @@ -737,7 +737,7 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4 || - sl->flash_type == STM32_FLASH_TYPE_L5_U5) { + sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { DLOG("Starting %3u page write\n", len / sl->flash_pgsz); for (off = 0; off < len; off += sizeof(uint32_t)) { uint32_t data; @@ -864,7 +864,7 @@ int32_t stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { (sl->flash_type == STM32_FLASH_TYPE_G4) || (sl->flash_type == STM32_FLASH_TYPE_H7) || (sl->flash_type == STM32_FLASH_TYPE_L4) || - (sl->flash_type == STM32_FLASH_TYPE_L5_U5) || + (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) || (sl->flash_type == STM32_FLASH_TYPE_WB_WL)) { clear_flash_cr_pg(sl, BANK_1); From 2c337615c945f79fa882ca6714279125e2619d11 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 11 Jun 2023 14:29:23 +0200 Subject: [PATCH 1386/1435] [refactoring] Clean-up for stlink-flash & -info - Ensure proper function declaration - Checked & revised header includes --- CMakeLists.txt | 3 +++ inc/stlink.h | 9 ++------- src/st-flash/flash.c | 20 ++++++++++++++----- src/st-flash/flash.h | 36 +++++++++------------------------ src/st-flash/flash_opts.c | 15 +++++++++++--- src/st-flash/flash_opts.h | 40 +++++++++++++++++++++++++++++++++++++ src/st-info/info.c | 14 ++++++++++--- src/st-info/info.h | 18 +++++++++++++++++ src/st-trace/trace.c | 5 ++++- src/st-util/gdb-server.c | 14 ++++++++----- src/stlink-gui/gui.c | 5 ++++- src/stlink-lib/chipid.h | 2 +- src/stlink-lib/usb.c | 42 +++++++++++++++++++-------------------- tests/flash.c | 1 + tests/sg.c | 3 +++ tests/usb.c | 3 +++ 16 files changed, 155 insertions(+), 75 deletions(-) create mode 100644 src/st-flash/flash_opts.h create mode 100644 src/st-info/info.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a82ea983..511144eae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,6 +154,9 @@ include_directories(${PROJECT_BINARY_DIR}/inc) # contains version.h include_directories(src) include_directories(src/st-flash) +include_directories(src/st-info) +include_directories(src/st-trace) +include_directories(src/st-util) include_directories(src/stlink-lib) ## Set installation directory for header files diff --git a/inc/stlink.h b/inc/stlink.h index d5d036725..ed93b34b7 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -234,6 +234,8 @@ struct _stlink { uint32_t max_trace_freq; // set by stlink_open_usb() }; +/* Functions defined in common.c */ + int32_t stlink_enter_swd_mode(stlink_t *sl); int32_t stlink_enter_jtag_mode(stlink_t *sl); int32_t stlink_exit_debug_mode(stlink_t *sl); @@ -284,14 +286,7 @@ int32_t stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t int32_t stlink_load_device_params(stlink_t *sl); int32_t stlink_target_connect(stlink_t *sl, enum connect_type connect); -#include -#include -#include -#include -#include #include -#include -#include #ifdef __cplusplus } diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 9a648bd63..711d7d2eb 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -1,23 +1,33 @@ -/* Simple wrapper around the stlink_flash_write function */ +/* + * File: flash.c + * + * Tool st-flash - Simple wrapper around the stlink_flash_write function + */ -#include #include +#include #include #include #include #include -#include + +#if defined(_WIN32) +#include +#else #include +#endif // _WIN32 #include #include +#include "flash.h" +#include "flash_opts.h" +#include #include #include #include - -#include "flash.h" +#include static stlink_t *connected_stlink = NULL; diff --git a/src/st-flash/flash.h b/src/st-flash/flash.h index 84c171158..889b2e4c4 100644 --- a/src/st-flash/flash.h +++ b/src/st-flash/flash.h @@ -1,36 +1,18 @@ +/* + * File: flash.h + * + * Tool st-flash + */ + #ifndef FLASH_H #define FLASH_H -#include - -#include - #define DEBUG_LOG_LEVEL 100 #define STND_LOG_LEVEL 50 #define ENABLE_OPT 1 -enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3, CMD_RESET = 4}; -enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1}; -enum flash_area {FLASH_MAIN_MEMORY = 0, FLASH_SYSTEM_MEMORY = 1, FLASH_OTP = 2, FLASH_OPTION_BYTES = 3, FLASH_OPTION_BYTES_BOOT_ADD = 4, FLASH_OPTCR = 5, FLASH_OPTCR1 = 6}; -struct flash_opts { - enum flash_cmd cmd; - uint8_t serial[STLINK_SERIAL_BUFFER_SIZE]; - const char* filename; - stm32_addr_t addr; - uint32_t size; - int32_t reset; - int32_t log_level; - enum flash_format format; - enum flash_area area; - uint32_t val; - uint32_t flash_size; // --flash=n[k, M] - int32_t opt; // enable empty tail data drop optimization - int32_t freq; // --freq=n[k, M] frequency of JTAG/SWD - enum connect_type connect; -}; - -#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - -int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av); +// static stlink_t *connected_stlink = NULL; +// static void cleanup(int32_t signum); +// static void usage(void); #endif // FLASH_H diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 35763ad50..358074793 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -1,12 +1,21 @@ +/* + * File: flash_opts.c + * + * Flash Options + */ + #include -#include #include +#include #include -#include - +#include +#include +#include "flash_opts.h" #include "flash.h" +#include + static bool starts_with(const char * str, const char * prefix) { uint32_t n = strlen(prefix); diff --git a/src/st-flash/flash_opts.h b/src/st-flash/flash_opts.h new file mode 100644 index 000000000..0c0083db6 --- /dev/null +++ b/src/st-flash/flash_opts.h @@ -0,0 +1,40 @@ +/* + * File: flash_opts.h + * + * Flash Options + */ + +#ifndef FLASH_OPTS_H +#define FLASH_OPTS_H + +#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3, CMD_RESET = 4}; +enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1}; +enum flash_area {FLASH_MAIN_MEMORY = 0, FLASH_SYSTEM_MEMORY = 1, FLASH_OTP = 2, FLASH_OPTION_BYTES = 3, FLASH_OPTION_BYTES_BOOT_ADD = 4, FLASH_OPTCR = 5, FLASH_OPTCR1 = 6}; + +struct flash_opts { + enum flash_cmd cmd; + uint8_t serial[STLINK_SERIAL_BUFFER_SIZE]; + const char* filename; + stm32_addr_t addr; + uint32_t size; + int32_t reset; + int32_t log_level; + enum flash_format format; + enum flash_area area; + uint32_t val; + uint32_t flash_size; // --flash=n[k, M] + int32_t opt; // enable empty tail data drop optimization + int32_t freq; // --freq=n[k, M] frequency of JTAG/SWD + enum connect_type connect; +}; + +// static bool starts_with(const char * str, const char * prefix); +// static int32_t get_long_integer_from_char_array (const char *const str, uint64_t *read_value); +// static int32_t get_integer_from_char_array (const char *const str, uint32_t *read_value); +// static int32_t invalid_args(const char *expected); +// static int32_t bad_arg(const char *arg); +int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av); + +#endif // FLASH_OPTS_H diff --git a/src/st-info/info.c b/src/st-info/info.c index b6ec0ccd2..664db7b2a 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -1,11 +1,19 @@ -#include +/* + * File: stinfo.c + * + * Tool st-info + */ + #include -#include +#include #include -#include #include +#include "info.h" + +#include #include +#include static void usage(void) { puts("st-info --version"); diff --git a/src/st-info/info.h b/src/st-info/info.h new file mode 100644 index 000000000..8e978e678 --- /dev/null +++ b/src/st-info/info.h @@ -0,0 +1,18 @@ +/* + * File: info.h + * + * Tool st-info + */ + +#ifndef INFO_H +#define INFO_H + +// static void usage(void); +// static void stlink_print_version(stlink_t *sl); +// static void stlink_print_info(stlink_t *sl); + +// static void stlink_probe(enum connect_type connect, int32_t freq) { }; +static int32_t print_data(int32_t ac, char **av); +int32_t main(int32_t ac, char** av); + +#endif // INFO_H \ No newline at end of file diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index ccbd74e16..56170d7c0 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -10,9 +10,12 @@ #include #include +#include + +#include #include #include -#include +#include #define DEFAULT_LOGGING_LEVEL 50 #define DEBUG_LOGGING_LEVEL 100 diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 7232f0f69..9f9d93844 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -27,14 +27,18 @@ #endif #include -#include -#include -#include -#include -#include "gdb-remote.h" #include "gdb-server.h" +#include "gdb-remote.h" #include "semihosting.h" +#include +#include +#include +#include +#include +#include +#include + #define FLASH_BASE 0x08000000 // Semihosting doesn't have a short option, we define a value to identify it diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index af2afcdbf..5853e5ec4 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -5,9 +5,12 @@ #include #include -#include #include "gui.h" +#include +#include +#include + #define MEM_READ_SIZE 1024 #ifndef G_VALUE_INIT diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index a72a40be9..6726a7420 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -21,7 +21,7 @@ struct stlink_chipid_params { uint32_t option_base; uint32_t option_size; uint32_t flags; - struct stlink_chipid_params * next; + struct stlink_chipid_params *next; }; struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid); diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 772fb147f..c2425b6cd 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -103,8 +103,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char ELOG("%s send request failed: %s\n", cmd, libusb_error_name(t)); return(-1); } else if ((size_t)res != txsize) { - ELOG("%s send request wrote %u bytes, instead of %u\n", - cmd, (uint32_t)res, (uint32_t)txsize); + ELOG("%s send request wrote %u bytes, instead of %u\n", cmd, (uint32_t)res, (uint32_t)txsize); } if (rxsize != 0) { @@ -215,7 +214,7 @@ int32_t _stlink_usb_version(stlink_t *sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_REP_LEN, "GET_VERSION"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } int32_t _stlink_usb_target_voltage(stlink_t *sl) { @@ -279,7 +278,7 @@ int32_t _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { write_uint32(&cmd[i + 4], data); size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, CMD_CHECK_RETRY, "WRITEDEBUGREG"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } int32_t _stlink_usb_get_rw_status(stlink_t *sl) { @@ -302,7 +301,7 @@ int32_t _stlink_usb_get_rw_status(stlink_t *sl) { ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 2, CMD_CHECK_STATUS, "GETLASTRWSTATUS"); } - return(ret<0?-1:0); + return(ret < 0 ? -1 : 0); } int32_t _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { @@ -450,7 +449,7 @@ int32_t _stlink_usb_status(stlink_t * sl) { sl->core_stat = TARGET_UNKNOWN; } - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } int32_t _stlink_usb_force_debug(stlink_t *sl) { @@ -473,7 +472,7 @@ int32_t _stlink_usb_force_debug(stlink_t *sl) { cmd[i++] = STLINK_DEBUG_FORCEDEBUG; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "FORCEDEBUG"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } int32_t _stlink_usb_enter_swd_mode(stlink_t * sl) { @@ -490,7 +489,7 @@ int32_t _stlink_usb_enter_swd_mode(stlink_t * sl) { cmd[i++] = STLINK_DEBUG_ENTER_SWD; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "ENTER_SWD"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } int32_t _stlink_usb_exit_dfu_mode(stlink_t* sl) { @@ -503,7 +502,7 @@ int32_t _stlink_usb_exit_dfu_mode(stlink_t* sl) { cmd[i++] = STLINK_DFU_EXIT; size = send_only(slu, 1, cmd, slu->cmd_len, "DFU_EXIT"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } @@ -526,7 +525,7 @@ int32_t _stlink_usb_reset(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "RESETSYS"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } int32_t _stlink_usb_jtag_reset(stlink_t * sl, int32_t value) { @@ -542,7 +541,7 @@ int32_t _stlink_usb_jtag_reset(stlink_t * sl, int32_t value) { cmd[i++] = value; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "DRIVE_NRST"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } @@ -556,7 +555,7 @@ int32_t _stlink_usb_step(stlink_t* sl) { _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_STEP | STLINK_REG_DHCSR_C_MASKINTS | STLINK_REG_DHCSR_C_DEBUGEN); return _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | - STLINK_REG_DHCSR_C_DEBUGEN); + STLINK_REG_DHCSR_C_DEBUGEN); } unsigned char* const data = sl->q_buf; @@ -569,7 +568,7 @@ int32_t _stlink_usb_step(stlink_t* sl) { cmd[i++] = STLINK_DEBUG_STEPCORE; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "STEPCORE"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } /** @@ -583,8 +582,7 @@ int32_t _stlink_usb_run(stlink_t* sl, enum run_type type) { int32_t res; if (sl->version.jtag_api != STLINK_JTAG_API_V1) { - res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, - STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | ((type==RUN_FLASH_LOADER)?STLINK_REG_DHCSR_C_MASKINTS:0)); return(res); } @@ -600,7 +598,7 @@ int32_t _stlink_usb_run(stlink_t* sl, enum run_type type) { cmd[i++] = STLINK_DEBUG_RUNCORE; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "RUNCORE"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } int32_t _stlink_usb_set_swdclk(stlink_t* sl, int32_t clk_freq) { @@ -643,7 +641,7 @@ int32_t _stlink_usb_set_swdclk(stlink_t* sl, int32_t clk_freq) { cmd[i++] = (clk_divisor >> 8) & 0xFF; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "SWD_SET_FREQ"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } else if (sl->version.stlink_v == 3) { int32_t speed_index; uint32_t map[STLINK_V3_MAX_FREQ_NB]; @@ -684,7 +682,7 @@ int32_t _stlink_usb_set_swdclk(stlink_t* sl, int32_t clk_freq) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8, CMD_CHECK_STATUS, "SET_COM_FREQ"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } else if (clk_freq) { WLOG("ST-Link firmware does not support frequency setup\n"); } @@ -703,7 +701,7 @@ int32_t _stlink_usb_exit_debug_mode(stlink_t *sl) { size = send_only(slu, 1, cmd, slu->cmd_len, "DEBUG_EXIT"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } int32_t _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { @@ -963,7 +961,7 @@ int32_t _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int32_t idx) { write_uint32(&cmd[i], reg); size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "WRITEREG"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } int32_t _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { @@ -981,7 +979,7 @@ int32_t _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "START_TRACE_RX"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } int32_t _stlink_usb_disable_trace(stlink_t* sl) { @@ -997,7 +995,7 @@ int32_t _stlink_usb_disable_trace(stlink_t* sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "STOP_TRACE_RX"); - return(size<0?-1:0); + return(size < 0 ? -1 : 0); } int32_t _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, uint32_t size) { diff --git a/tests/flash.c b/tests/flash.c index 67436ecb1..f4c838d5d 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -7,6 +7,7 @@ #include #include +#include #if defined(_MSC_VER) #include diff --git a/tests/sg.c b/tests/sg.c index 32dcd9a62..6881266ab 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -7,6 +7,9 @@ #include +#include +#include + #if defined(_MSC_VER) #define __attribute__(x) #endif diff --git a/tests/usb.c b/tests/usb.c index 56f0d9c1f..9acd0b02d 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -6,6 +6,9 @@ #include +#include +#include + static void usage(void) { puts("test-usb --reset"); puts("test-usb --no-reset"); From b72f5b5acf8997a299d9eac4d6cc2dfc5322e144 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 12 Jun 2023 11:56:21 +0200 Subject: [PATCH 1387/1435] Fixed compilation on Windows - [doc] Updated installation instructions - Fixed cmd bug in mingw64-build.bat - Fixed cmake building for WIN32 --- CMakeLists.txt | 19 ++++++++++++++++++- doc/compiling.md | 16 +++++++++------- mingw64-build.bat | 5 +++-- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 511144eae..7e7d92705 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,7 @@ include(${CMAKE_MODULE_PATH}/get_version.cmake) # Determine project version include(GNUInstallDirs) # Define GNU standard installation directories -# Define install directory /usr/local/share +# Define install directory for st-link shared files cmake_host_system_information(RESULT OS_NAME QUERY OS_NAME) message(STATUS "Checking for OS_NAME: ${OS_NAME}") @@ -160,7 +160,11 @@ include_directories(src/st-util) include_directories(src/stlink-lib) ## Set installation directory for header files +if (WIN32) +set(STLINK_INCLUDE_PATH ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Main include install directory") +else () set(STLINK_INCLUDE_PATH ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} CACHE PATH "Main include install directory") +endif () ## Subordinate CMakeLists for version config & header installation add_subdirectory(inc) @@ -275,6 +279,15 @@ install(TARGETS ${STLINK_LIB_SHARED} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) +# Copy libusb DLL-library to binary output folder +if (WIN32) +file(COPY ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/dll/libusb-1.0.dll + DESTINATION ${CMAKE_INSTALL_BINDIR}) +file(COPY ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/dll/libusb-1.0.dll + DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}) +endif () + + ### # Static library ### @@ -369,7 +382,11 @@ endif () ### # MCU configuration files +if (WIN32) +set(CMAKE_CHIPS_DIR ${CMAKE_INSTALL_PREFIX}/config/chips) +else () set(CMAKE_CHIPS_DIR ${CMAKE_INSTALL_SHAREDIR}/${PROJECT_NAME}/chips) +endif () add_definitions( -DSTLINK_CHIPS_DIR="${CMAKE_CHIPS_DIR}" ) file(GLOB CHIP_FILES ${CMAKE_SOURCE_DIR}/config/chips/*.chip) install(FILES ${CHIP_FILES} DESTINATION ${CMAKE_CHIPS_DIR}) diff --git a/doc/compiling.md b/doc/compiling.md index eec46bb3d..775d2363e 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -8,7 +8,8 @@ On Windows users should ensure that the following software is installed: - `git` (_optional, but recommended_) - `cmake` -- `MinGW-w64` (7.0.0 or later) with GCC toolchain 8.1.0 +- `7-zip` +- `MinGW-w64` ### Installation @@ -17,13 +18,13 @@ On Windows users should ensure that the following software is installed: Ensure that you add cmake to the $PATH system variable when following the instructions by the setup assistant. 3. Install -- _EITHER_: **MinGW-w64** from (mingw-w64-install.exe)
      -- _OR_: **MSVC toolchain** from Visual Studio Build Tools 2019 + - _EITHER_: Download **MinGW-w64** from . Extract content to `C:\mingw-w64\` and add `C:\mingw-w64\bin\` to PATH-Variable.
      + - _OR_: **MSVC toolchain** from Visual Studio Build Tools 2019 4. Create a new destination folder at a place of your choice 5. Open the command-line (cmd.exe) and execute `cd C:\$Path-to-your-destination-folder$\` 6. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git`from the command-line (cmd.exe)
      - or download the stlink zip-sourcefolder from the Release page on GitHub + or download and extract the stlink zip-sourcefolder from the Release page on GitHub. #### MSVC toolchain - minimal installation @@ -48,11 +49,12 @@ Visual Studio IDE is not necessary, only Windows SDK & build tools are required #### MinGW-w64 -1. Use the command-line to move to the `scripts` directory within the source-folder: `cd stlink\scripts\` -2. Execute `./mingw64-build.bat` +1. Open command-line with administrator privileges +2. Move to the `stlink` directory +3. Execute `mingw64-build.bat` NOTE:
      -Per default the build script (currently) uses `C:\Program Files\mingw-w64\x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0\mingw64\bin`.
      +Per default the build script (currently) uses `C:\mingw-w64\x86_64-8.1.0-release-win32-sjlj-rt_v6-rev0\mingw64\bin`.
      When installing different toolchains make sure to update the path in the `mingw64-build.bat`.
      This can be achieved by opening the .bat file with a common text editor. diff --git a/mingw64-build.bat b/mingw64-build.bat index eeaacddab..b52e529e2 100644 --- a/mingw64-build.bat +++ b/mingw64-build.bat @@ -2,8 +2,9 @@ mkdir build-mingw cd build-mingw -set PATH=C:\Program Files (x86)\CMake\bin;C:\Program Files\CMake\bin;C:\Program Files\mingw-w64\x86_64-8.1.0-win32-sjlj-rt_v6-rev0\mingw64\bin;%PATH% +set PATH=C:\Program Files (x86)\CMake\bin;C:\Program Files\CMake\bin;C:\mingw-w64\x86_64-8.1.0-win32-sjlj-rt_v6-rev0\mingw64\bin;%PATH% cmake -G "MinGW Makefiles" .. mingw32-make -mingw32-make install DESTDIR=install +mingw32-make install mingw32-make package +cd .. From 101d77bf7e6c32c9e9b565301bd6dd9092c033cc Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 24 Jun 2023 23:55:12 +0200 Subject: [PATCH 1388/1435] Formatting & style fixes. --- CMakeLists.txt | 36 +++---- cmake/modules/Findlibusb.cmake | 18 ++-- cmake/modules/c_flags.cmake | 8 +- cmake/modules/get_version.cmake | 16 +-- cmake/modules/pandocology.cmake | 38 ++++---- cmake/packaging/cpack_config.cmake | 2 +- doc/man/CMakeLists.txt | 6 +- src/st-flash/flash.c | 6 +- src/st-flash/flash_opts.c | 56 +++++------ src/st-info/info.c | 16 +-- src/st-util/gdb-remote.c | 24 ++--- src/st-util/gdb-server.c | 66 ++++++------- src/st-util/semihosting.c | 80 +++++++-------- src/stlink-gui/CMakeLists.txt | 4 +- src/stlink-gui/gui.c | 38 ++++---- src/stlink-lib/flash_loader.c | 30 +++--- src/stlink-lib/lib_md5.c | 2 +- src/stlink-lib/sg.c | 144 +++++++++++++-------------- src/stlink-lib/usb.c | 150 ++++++++++++++--------------- src/win32/getopt/getopt.c | 10 +- src/win32/mmap.c | 12 +-- src/win32/sys_time.c | 4 +- src/win32/win32_socket.c | 28 +++--- tests/flash.c | 4 +- tests/sg.c | 4 +- tests/usb.c | 4 +- 26 files changed, 402 insertions(+), 404 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e7d92705..c0957a034 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,7 +91,7 @@ else () set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") -endif () +endif() ### @@ -111,10 +111,10 @@ if (_stack_chk_fail_exists) set(SSP_LIB -static ssp) else () set(SSP_LIB ssp) - endif () + endif() else () set(SSP_LIB "") -endif () +endif() CHECK_INCLUDE_FILE(sys/mman.h STLINK_HAVE_SYS_MMAN_H) if (STLINK_HAVE_SYS_MMAN_H) @@ -129,17 +129,17 @@ endif() CHECK_INCLUDE_FILE(unistd.h STLINK_HAVE_UNISTD_H) if (STLINK_HAVE_UNISTD_H) add_definitions(-DSTLINK_HAVE_UNISTD_H) -endif () +endif() CHECK_INCLUDE_FILE(dirent.h STLINK_HAVE_DIRENT_H) if (STLINK_HAVE_DIRENT_H) add_definitions(-DSTLINK_HAVE_DIRENT_H) -endif () +endif() if (MSVC) # Use string.h rather than strings.h and disable annoying warnings add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710) -endif () +endif() ### @@ -164,7 +164,7 @@ if (WIN32) set(STLINK_INCLUDE_PATH ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Main include install directory") else () set(STLINK_INCLUDE_PATH ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} CACHE PATH "Main include install directory") -endif () +endif() ## Subordinate CMakeLists for version config & header installation add_subdirectory(inc) @@ -218,7 +218,7 @@ if (WIN32) # Add drop-in replacement for unistd.h to sources include_directories(src/win32/unistd) set(STLINK_HEADERS "${STLINK_HEADERS};src/win32/unistd/unistd.h") - endif () + endif() if (NOT STLINK_HAVE_SYS_MMAN_H) include_directories(src/win32/mmap) @@ -230,12 +230,12 @@ if (WIN32) set(STLINK_SOURCE "${STLINK_SOURCE};src/win32/sys_time.c") set(STLINK_HEADERS "${STLINK_HEADERS};src/win32/sys_time.h") endif() -endif () +endif() ## Include test execution for test-targets for target Debug if (${CMAKE_BUILD_TYPE} MATCHES "Debug") include(CTest) -endif () +endif() ### @@ -271,7 +271,7 @@ if (WIN32) # ... with Windows libraries target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB} wsock32 ws2_32) else () target_link_libraries(${STLINK_LIB_SHARED} ${LIBUSB_LIBRARY} ${SSP_LIB}) -endif () +endif() install(TARGETS ${STLINK_LIB_SHARED} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} @@ -285,7 +285,7 @@ file(COPY ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/dll/libusb-1.0.dll DESTINATION ${CMAKE_INSTALL_BINDIR}) file(COPY ${LIBUSB_WIN_OUTPUT_FOLDER}/MinGW64/dll/libusb-1.0.dll DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}) -endif () +endif() ### @@ -317,7 +317,7 @@ if (WIN32) # ... with Windows libraries target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB} wsock32 ws2_32) else () target_link_libraries(${STLINK_LIB_STATIC} ${LIBUSB_LIBRARY} ${SSP_LIB}) -endif () +endif() install(TARGETS ${STLINK_LIB_STATIC} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) @@ -336,7 +336,7 @@ if (MSVC) include_directories(src/win32/getopt) set(ST-UTIL_SOURCES "${ST-UTIL_SOURCES};src/win32/getopt/getopt.c") set(ST-TRACE_SOURCES "${ST-TRACE_SOURCES};src/win32/getopt/getopt.c") -endif () +endif() add_executable(st-flash ${ST-FLASH_SOURCES}) add_executable(st-info ${ST-INFO_SOURCES}) @@ -353,7 +353,7 @@ else () target_link_libraries(st-info ${STLINK_LIB_SHARED} ${SSP_LIB}) target_link_libraries(st-util ${STLINK_LIB_SHARED} ${SSP_LIB}) target_link_libraries(st-trace ${STLINK_LIB_SHARED} ${SSP_LIB}) -endif () +endif() install(TARGETS st-flash DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS st-info DESTINATION ${CMAKE_INSTALL_BINDIR}) @@ -374,7 +374,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux") set(STLINK_UDEV_RULES_DIR "/lib/udev/rules.d" CACHE PATH "udev rules directory") file(GLOB RULES_FILES ${CMAKE_SOURCE_DIR}/config/udev/rules.d/*.rules) install(FILES ${RULES_FILES} DESTINATION ${STLINK_UDEV_RULES_DIR}) -endif () +endif() ### @@ -386,7 +386,7 @@ if (WIN32) set(CMAKE_CHIPS_DIR ${CMAKE_INSTALL_PREFIX}/config/chips) else () set(CMAKE_CHIPS_DIR ${CMAKE_INSTALL_SHAREDIR}/${PROJECT_NAME}/chips) -endif () +endif() add_definitions( -DSTLINK_CHIPS_DIR="${CMAKE_CHIPS_DIR}" ) file(GLOB CHIP_FILES ${CMAKE_SOURCE_DIR}/config/chips/*.chip) install(FILES ${CHIP_FILES} DESTINATION ${CMAKE_CHIPS_DIR}) @@ -413,4 +413,4 @@ if (NOT TARGET uninstall) uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake ) -endif () +endif() diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index 6f0a21da6..830060486 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -24,7 +24,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) if (NOT LIBUSB_FOUND) message(FATAL_ERROR "Expected libusb library not found on your system! Verify your system integrity.") - endif () + endif() elseif (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") # OpenBSD; libusb-1.0 is available from ports FIND_PATH( @@ -41,7 +41,7 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") # OpenBSD; libusb-1.0 mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) if (NOT LIBUSB_FOUND) message(FATAL_ERROR "No libusb-1.0 library found on your system! Install libusb-1.0 from ports or packages.") - endif () + endif() elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-toolchain on Debian # MinGW/MSYS/MSVC: 64-bit or 32-bit? @@ -51,7 +51,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to else () message(STATUS "=== Building for Windows (i686) ===") set(ARCH 32) - endif () + endif() if (WIN32 AND NOT EXISTS "/etc/debian_version") # Skip this for Debian... # Preparations for installing libusb library @@ -63,7 +63,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to elseif (EXISTS "/etc/debian_version" AND MINGW) # ... only for cross-building on Debian set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_SOURCE_DIR}/build-mingw-${ARCH}/${LIBUSB_WIN_ARCHIVE}) set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_SOURCE_DIR}/build-mingw-${ARCH}/3rdparty/libusb-${LIBUSB_WIN_VERSION}) - endif () + endif() # Get libusb package if (EXISTS ${LIBUSB_WIN_ARCHIVE_PATH}) # ... should the package be already there (for whatever reason) @@ -74,7 +74,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 aabe177bde869bfad34278335eaf8955 ) - endif () + endif() file(MAKE_DIRECTORY ${LIBUSB_WIN_OUTPUT_FOLDER}) @@ -110,9 +110,9 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) - endif () + endif() message(STATUS "Missing libusb library has been installed") - endif () + endif() FIND_PACKAGE_HANDLE_STANDARD_ARGS(libusb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR) mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY) @@ -132,5 +132,5 @@ else () if (NOT LIBUSB_FOUND) message(FATAL_ERROR "libusb library not found on your system! Install libusb 1.0.x from your package repository.") - endif () -endif () + endif() +endif() diff --git a/cmake/modules/c_flags.cmake b/cmake/modules/c_flags.cmake index 6e22d4ff3..d30f45ec9 100644 --- a/cmake/modules/c_flags.cmake +++ b/cmake/modules/c_flags.cmake @@ -14,7 +14,7 @@ function(add_cflag_if_supported flag) if (C_SUPPORTS${flagclean}) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE) - endif () + endif() endfunction() add_cflag_if_supported("-Wall") @@ -38,14 +38,14 @@ add_cflag_if_supported("-Wimplicit-function-declaration") ## if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") add_cflag_if_supported("-Wredundant-decls") -endif () +endif() if (NOT (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW))) add_cflag_if_supported("-fPIC") -endif () +endif() if (${CMAKE_BUILD_TYPE} MATCHES "Debug") add_cflag_if_supported("-ggdb") else () add_cflag_if_supported("-Werror") -endif () +endif() diff --git a/cmake/modules/get_version.cmake b/cmake/modules/get_version.cmake index 8211d9c84..07c5793df 100644 --- a/cmake/modules/get_version.cmake +++ b/cmake/modules/get_version.cmake @@ -28,7 +28,7 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") ) if (res EQUAL 1) set(PROJECT_VERSION "${PROJECT_VERSION}-dirty") - endif () + endif() # Strip a leading v off of the version as proceeding code expects just the version numbering. string(REGEX REPLACE "^v" "" PROJECT_VERSION ${PROJECT_VERSION}) @@ -53,14 +53,14 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") # ...the version does not match with git-version string if (NOT __version_str STREQUAL __version_file) message(STATUS "Rewrite ${PROJECT_SOURCE_DIR}/.version with ${__version_str}!") - endif () + endif() elseif (NOT EXISTS "${PROJECT_SOURCE_DIR}/.version") # No local .version file found: Create a new one... file(WRITE "${PROJECT_SOURCE_DIR}/.version" ${__version_str}) - endif () + endif() message(STATUS "stlink version: ${PROJECT_VERSION}") message(STATUS "Major ${PROJECT_VERSION_MAJOR} Minor ${PROJECT_VERSION_MINOR} Patch ${PROJECT_VERSION_PATCH}") @@ -68,13 +68,13 @@ if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") else (len EQUAL 3) message(STATUS "Failed to extract version parts from \"${PROJECT_VERSION}\"") set(ERROR_FLAG "1") - endif (len EQUAL 3) + endif(len EQUAL 3) else (GIT_DESCRIBE_RESULT EQUAL 0) message(WARNING "git describe failed: ${GIT_DESCRIBE_ERROR}") set(ERROR_FLAG "1") endif(GIT_DESCRIBE_RESULT EQUAL 0) -endif () +endif() ## # Failure to read version via git @@ -101,9 +101,9 @@ if (NOT GIT_FOUND OR NOT EXISTS "${PROJECT_SOURCE_DIR}/.git" OR ERROR_FLAG EQUAL set(__detect_version 1) else () message(STATUS "Fail to extract version parts from \"${PROJECT_VERSION}\"") - endif () + endif() else (EXISTS ${PROJECT_SOURCE_DIR}/.version) message(STATUS "File \"${PROJECT_SOURCE_DIR}/.version\" does not exist.") message(FATAL_ERROR "Unable to determine project version") - endif () -endif () + endif() +endif() diff --git a/cmake/modules/pandocology.cmake b/cmake/modules/pandocology.cmake index ff9053197..24cd4b9a1 100644 --- a/cmake/modules/pandocology.cmake +++ b/cmake/modules/pandocology.cmake @@ -45,7 +45,7 @@ include(CMakeParseArguments) if (NOT EXISTS ${PANDOC_EXECUTABLE}) find_program(PANDOC_EXECUTABLE pandoc) mark_as_advanced(PANDOC_EXECUTABLE) -endif () +endif() ############################################################################### # Based on code from UseLATEX @@ -133,7 +133,7 @@ This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. Please delete them: $ rm -r CMakeFiles/ CmakeCache.txt ") - ENDif () + endif() endfunction() # This builds a document @@ -171,7 +171,7 @@ function(add_document target_name) if (NOT PANDOC_EXECUTABLE) message(WARNING "Pandoc not found. Install Pandoc (http://johnmacfarlane.net/pandoc/) or set cache variable PANDOC_EXECUTABLE.") return() - endif () + endif() set(options EXPORT_ARCHIVE NO_EXPORT_PRODUCT EXPORT_PDF DIRECT_TEX_TO_PDF VERBOSE) set(oneValueArgs PRODUCT_DIRECTORY) @@ -188,29 +188,29 @@ function(add_document target_name) if (NOT "${target_extension}" STREQUAL ".tex" AND NOT "${target_extension}" STREQUAL ".latex") # if (NOT "${target_extension}" STREQUAL ".tex") MESSAGE(FATAL_ERROR "Target '${target_name}': Cannot use 'EXPORT_PDF' for target of type '${target_extension}': target type must be '.tex' or '.latex'") - endif () - endif () + endif() + endif() if (${ADD_DOCUMENT_DIRECT_TEX_TO_PDF}) list(LENGTH ${ADD_DOCUMENT_SOURCES} SOURCE_LEN) if (SOURCE_LEN GREATER 1) MESSAGE(FATAL_ERROR "Target '${target_name}': Only one source can be specified when using the 'DIRECT_TEX_TO_PDF' option") - endif () + endif() # set(ADD_DOCUMENT_SOURCES, list(GET ${ADD_DOCUMENT_SOURCES} 1)) pandocology_get_file_stemname(source_stemname ${ADD_DOCUMENT_SOURCES}) pandocology_get_file_extension(source_extension ${ADD_DOCUMENT_SOURCES}) if (NOT "${source_extension}" STREQUAL ".tex" AND NOT "${source_extension}" STREQUAL ".latex") MESSAGE(FATAL_ERROR "Target '${target_name}': Cannot use 'DIRECT_TEX_TO_PDF' for source of type '${source_extension}': source type must be '.tex' or '.latex'") - endif () + endif() SET(check_target ${source_stemname}.pdf) IF (NOT ${check_target} STREQUAL ${target_name}) MESSAGE(FATAL_ERROR "Target '${target_name}': Must use target name of '${check_target}' if using 'DIRECT_TEX_TO_PDF'") - endif () - endif () + endif() + endif() ## set up output directory if ("${ADD_DOCUMENT_PRODUCT_DIRECTORY}" STREQUAL "") set(ADD_DOCUMENT_PRODUCT_DIRECTORY "product") - endif () + endif() get_filename_component(product_directory ${CMAKE_BINARY_DIR}/${ADD_DOCUMENT_PRODUCT_DIRECTORY} ABSOLUTE) # get_filename_component(absolute_product_path ${product_directory}/${target_name} ABSOLUTE) @@ -232,7 +232,7 @@ function(add_document target_name) pandocology_add_input_dir(${CMAKE_CURRENT_SOURCE_DIR}/${resource_dir} ${CMAKE_CURRENT_BINARY_DIR} build_resources) if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) pandocology_add_input_dir(${CMAKE_CURRENT_SOURCE_DIR}/${resource_dir} ${product_directory} exported_resources) - endif () + endif() endforeach() ## primary command @@ -255,7 +255,7 @@ function(add_document target_name) # we produce the target in the source directory, in case other build targets require it as a source COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${build_sources} 2>/dev/null >/dev/null || (grep --no-messages -A8 ".*:[0-9]*:.*" ${target_stemname}.log && false) ) - endif () + endif() add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_name}) else() add_custom_command( @@ -267,7 +267,7 @@ function(add_document target_name) COMMAND ${PANDOC_EXECUTABLE} ${build_sources} ${ADD_DOCUMENT_PANDOC_DIRECTIVES} -o ${target_name} ) add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_name}) - endif () + endif() ## figure out what all is going to be produced by this build set, and set ## those as dependencies of the primary target @@ -275,14 +275,14 @@ function(add_document target_name) set(primary_target_dependencies ${primary_target_dependencies} ${CMAKE_CURRENT_BINARY_DIR}/${target_name}) if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT}) set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_name}) - endif () + endif() if (${ADD_DOCUMENT_EXPORT_PDF}) set(primary_target_dependencies ${primary_target_dependencies} ${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf) set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_stemname}.pdf) - endif () + endif() if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_stemname}.tbz) - endif () + endif() ## primary target # # target cannot have same (absolute name) as dependencies: @@ -326,7 +326,7 @@ function(add_document target_name) ) add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf) add_to_make_clean(${product_directory}/${target_stemname}.pdf) - endif () + endif() ## copy products if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT}) @@ -336,7 +336,7 @@ function(add_document target_name) COMMAND ${CMAKE_COMMAND} -E copy ${target_name} ${product_directory} ) add_to_make_clean(${product_directory}/${target_name}) - endif () + endif() ## copy resources if (${ADD_DOCUMENT_EXPORT_ARCHIVE}) @@ -359,7 +359,7 @@ function(add_document target_name) # ALL # DEPENDS ${product_directory}/${target_stemname}.tbz # ) - endif () + endif() endfunction(add_document) diff --git a/cmake/packaging/cpack_config.cmake b/cmake/packaging/cpack_config.cmake index 57d4803d7..17de607ef 100644 --- a/cmake/packaging/cpack_config.cmake +++ b/cmake/packaging/cpack_config.cmake @@ -101,7 +101,7 @@ elseif (EXISTS "/etc/debian_version" AND NOT EXISTS WIN32) # Package-build is av else () # No package configuration on other platforms ... -endif () +endif() ### diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 1b7d6501f..f225c85b7 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -17,7 +17,7 @@ if (${STLINK_GENERATE_MANPAGES}) endforeach () else () message(STATUS "Manpage generation disabled") -endif () +endif() # Install from output folder or this folder foreach (manpage ${MANPAGES}) @@ -27,10 +27,10 @@ foreach (manpage ${MANPAGES}) set(f "${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.1") else() message(AUTHOR_WARNING "Manpage ${manpage} not generated") - endif () + endif() if (f AND NOT WIN32) install(FILES ${f} DESTINATION ${CMAKE_INSTALL_DATADIR}/man/man1) unset(f) - endif () + endif() endforeach () diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 711d7d2eb..ba6d1f4bb 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -75,7 +75,7 @@ int32_t main(int32_t ac, char** av) { if (flash_get_opts(&o, ac - 1, av + 1) == -1) { printf("invalid command line\n"); usage(); - return(-1); + return (-1); } printf("st-flash %s\n", STLINK_VERSION); @@ -83,7 +83,7 @@ int32_t main(int32_t ac, char** av) { sl = stlink_open_usb(o.log_level, o.connect, (char *)o.serial, o.freq); - if (sl == NULL) { return(-1); } + if (sl == NULL) { return (-1); } if (sl->flash_type == STM32_FLASH_TYPE_UNKNOWN) { printf("Failed to connect to target\n"); @@ -299,5 +299,5 @@ int32_t main(int32_t ac, char** av) { stlink_close(sl); free(mem); - return(err); + return (err); } diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 358074793..300203a3f 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -19,7 +19,7 @@ static bool starts_with(const char * str, const char * prefix) { uint32_t n = strlen(prefix); - if (strlen(str) < n) { return(false); } + if (strlen(str) < n) { return (false); } return (0 == strncmp(str, prefix, n)); } @@ -49,11 +49,11 @@ static int32_t get_long_integer_from_char_array (const char *const str, uint64_t } else if (tail[0] == '\0') { /* value not changed */ } else { - return(-1); + return (-1); } *read_value = value; - return(0); + return (0); } // support positive integer from 0 to UINT32_MAX @@ -65,24 +65,24 @@ static int32_t get_integer_from_char_array (const char *const str, uint32_t *rea int32_t result = get_long_integer_from_char_array (str, &value); if (result != 0) { - return(result); + return (result); } else if (value > UINT32_MAX) { fprintf (stderr, "*** Error: Integer greater than UINT32_MAX, cannot convert to int32_t\n"); - return(-1); + return (-1); } else { *read_value = value; - return(0); + return (0); } } static int32_t invalid_args(const char *expected) { fprintf(stderr, "*** Error: Expected args for this command: %s\n", expected); - return(-1); + return (-1); } static int32_t bad_arg(const char *arg) { fprintf(stderr, "*** Error: Invalid value for %s\n", arg); - return(-1); + return (-1); } int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { @@ -111,7 +111,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { ac--; av++; - if (ac < 1) { return(-1); } + if (ac < 1) { return (-1); } serial = av[0]; } else { @@ -127,7 +127,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { ac--; av++; - if (ac < 1) { return(-1); } + if (ac < 1) { return (-1); } area = av[0]; } else { @@ -149,7 +149,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { } else if (strcmp(area, "optcr1") == 0) { o->area = FLASH_OPTCR1; } else { - return(-1); + return (-1); } } else if (strcmp(av[0], "--freq") == 0) { @@ -157,17 +157,17 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { av++; if (ac < 1) { - return(-1); + return (-1); } o->freq = arg_parse_freq(av[0]); if (o->freq < 0) { - return(-1); + return (-1); } } else if (starts_with(av[0], "--freq=")) { o->freq = arg_parse_freq(av[0] + strlen("--freq=")); if (o->freq < 0) { - return(-1); + return (-1); } } else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { const char * format; @@ -176,7 +176,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { ac--; av++; - if (ac < 1) { return(-1); } + if (ac < 1) { return (-1); } format = av[0]; } else { @@ -188,7 +188,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { } else if (strcmp(format, "ihex") == 0) { o->format = FLASH_FORMAT_IHEX; } else { - return(bad_arg("format")); + return (bad_arg("format")); } } else if ( starts_with(av[0], "--flash=")) { const char *arg = av[0] + strlen("--flash="); @@ -197,7 +197,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { result = get_integer_from_char_array(arg, &flash_size); if (result != 0) { - return(bad_arg ("--flash")); + return (bad_arg ("--flash")); } else { o->flash_size = (size_t)flash_size; } @@ -217,18 +217,18 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { // command and (optional) device name while (ac >= 1) { if (strcmp(av[0], "erase") == 0) { - if (o->cmd != FLASH_CMD_NONE) { return(-1); } + if (o->cmd != FLASH_CMD_NONE) { return (-1); } o->cmd = FLASH_CMD_ERASE; } else if (strcmp(av[0], "read") == 0) { - if (o->cmd != FLASH_CMD_NONE) { return(-1); } + if (o->cmd != FLASH_CMD_NONE) { return (-1); } o->cmd = FLASH_CMD_READ; } else if (strcmp(av[0], "write") == 0) { - if (o->cmd != FLASH_CMD_NONE) { return(-1); } + if (o->cmd != FLASH_CMD_NONE) { return (-1); } o->cmd = FLASH_CMD_WRITE; } else if (strcmp(av[0], "reset") == 0) { - if (o->cmd != FLASH_CMD_NONE) { return(-1); } + if (o->cmd != FLASH_CMD_NONE) { return (-1); } o->cmd = CMD_RESET; } else { @@ -241,10 +241,10 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { switch (o->cmd) { case FLASH_CMD_NONE: // no command found - return(-1); + return (-1); case FLASH_CMD_ERASE: // no more arguments expected - if (ac != 0 && ac != 2) { return(-1); } + if (ac != 0 && ac != 2) { return (-1); } if (ac == 2) { uint32_t address; result = get_integer_from_char_array(av[0], &address); @@ -336,7 +336,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { result = get_integer_from_char_array(av[0], &val); if (result != 0) { - return(bad_arg ("val")); + return (bad_arg ("val")); } else { o->val = val; } @@ -369,16 +369,16 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { result = get_integer_from_char_array(av[1], &addr); if (result != 0) { - return(bad_arg ("addr")); + return (bad_arg ("addr")); } else { o->addr = (stm32_addr_t)addr; } } else if (o->format == FLASH_FORMAT_IHEX) { // expect filename - if (ac != 1) { return(invalid_args("write ")); } + if (ac != 1) { return (invalid_args("write ")); } o->filename = av[0]; } else { - return(-1); // should have been caught during format parsing + return (-1); // should have been caught during format parsing } break; @@ -386,5 +386,5 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { default: break; } - return(0); + return (0); } diff --git a/src/st-info/info.c b/src/st-info/info.c index 664db7b2a..ffdf521cc 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -74,7 +74,7 @@ static int32_t print_data(int32_t ac, char **av) { if (strcmp(av[1], "--version") == 0) { printf("v%s\n", STLINK_VERSION); - return(0); + return (0); } init_chipids(STLINK_CHIPS_DIR); @@ -99,18 +99,18 @@ static int32_t print_data(int32_t ac, char **av) { printf("Incorrect argument: %s\n\n", av[i]); usage(); - return(-1); + return (-1); } // probe needs all devices unclaimed if (strcmp(av[1], "--probe") == 0) { stlink_probe(connect, freq); - return(0); + return (0); } // open first st-link device sl = stlink_open_usb(0, connect, NULL, freq); - if (sl == NULL) { return(-1); } + if (sl == NULL) { return (-1); } if (strcmp(av[1], "--serial") == 0) { printf("%s\n", sl->serial); @@ -124,7 +124,7 @@ static int32_t print_data(int32_t ac, char **av) { printf("0x%.4x\n", sl->chip_id); } else if (strcmp(av[1], "--descr") == 0) { const struct stlink_chipid_params *params = stlink_chipid_get_params(sl->chip_id); - if (params == NULL) { return(-1); } + if (params == NULL) { return (-1); } printf("%s\n", params->dev_type); } @@ -134,7 +134,7 @@ static int32_t print_data(int32_t ac, char **av) { stlink_close(sl); } - return(0); + return (0); } int32_t main(int32_t ac, char** av) { @@ -142,10 +142,10 @@ int32_t main(int32_t ac, char** av) { if (ac < 2) { usage(); - return(-1); + return (-1); } err = print_data(ac, av); - return(err); + return (err); } diff --git a/src/st-util/gdb-remote.c b/src/st-util/gdb-remote.c index 7d0f2c731..25ca4da5b 100644 --- a/src/st-util/gdb-remote.c +++ b/src/st-util/gdb-remote.c @@ -42,19 +42,19 @@ int32_t gdb_send_packet(int32_t fd, char* data) { while (1) { if (write(fd, packet, length) != length) { free(packet); - return(-2); + return (-2); } char ack; if (read(fd, &ack, 1) != 1) { free(packet); - return(-2); + return (-2); } if (ack == '+') { free(packet); - return(0); + return (0); } } } @@ -69,7 +69,7 @@ int32_t gdb_recv_packet(int32_t fd, char** buffer) { uint32_t state; if (packet_buffer == NULL) { - return(-2); + return (-2); } start: @@ -88,7 +88,7 @@ int32_t gdb_recv_packet(int32_t fd, char** buffer) { while (state != 4) { if (read(fd, &c, 1) != 1) { free(packet_buffer); - return(-2); + return (-2); } switch (state) { @@ -117,7 +117,7 @@ int32_t gdb_recv_packet(int32_t fd, char** buffer) { packet_buffer = p; } else { free(packet_buffer); - return(-2); + return (-2); } } } @@ -143,7 +143,7 @@ int32_t gdb_recv_packet(int32_t fd, char** buffer) { if (write(fd, &nack, 1) != 1) { free(packet_buffer); - return(-2); + return (-2); } goto start; @@ -152,14 +152,14 @@ int32_t gdb_recv_packet(int32_t fd, char** buffer) { if (write(fd, &ack, 1) != 1) { free(packet_buffer); - return(-2); + return (-2); } } packet_buffer[packet_idx] = 0; *buffer = packet_buffer; - return(packet_idx); + return (packet_idx); } /* @@ -176,13 +176,13 @@ int32_t gdb_check_for_interrupt(int32_t fd) { char c; if (read(fd, &c, 1) != 1) { - return(-2); + return (-2); } if (c == '\x03') { - return(1); // ^C + return (1); // ^C } } - return(0); + return (0); } diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 9f9d93844..8a187fb24 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -214,7 +214,7 @@ int32_t parse_options(int32_t argc, char** argv, st_state_t *st) { printf("\n"); } - return(0); + return (0); } int32_t main(int32_t argc, char** argv) { @@ -233,11 +233,11 @@ int32_t main(int32_t argc, char** argv) { init_chipids (STLINK_CHIPS_DIR); sl = stlink_open_usb(state.logging_level, state.connect_mode, state.serialnumber, state.freq); - if (sl == NULL) { return(1); } + if (sl == NULL) { return (1); } if (sl->chip_id == STM32_CHIPID_UNKNOWN) { ELOG("Unsupported Target (Chip ID is %#010x, Core ID is %#010x).\n", sl->chip_id, sl->core_id); - return(1); + return (1); } sl->verbose = 0; @@ -275,7 +275,7 @@ int32_t main(int32_t argc, char** argv) { stlink_exit_debug_mode(sl); stlink_close(sl); - return(0); + return (0); } static const char* const target_description = @@ -608,7 +608,7 @@ char* make_memory_map(stlink_t *sl) { sl->sys_size); } - return(map); + return (map); } #define DATA_WATCH_NUM 4 @@ -676,12 +676,12 @@ static int32_t add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t // just to make sure the matched bit is clear ! stlink_read_debug32(sl, STLINK_REG_CM3_DWT_FUNn(i), &dummy); - return(0); + return (0); } } DLOG("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len); - return(-1); + return (-1); } static int32_t delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { @@ -694,13 +694,13 @@ static int32_t delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { data_watches[i].fun = WATCHDISABLED; stlink_write_debug32(sl, STLINK_REG_CM3_DWT_FUNn(i), 0); - return(0); + return (0); } } DLOG("failure: delete watchpoint addr %x\n", addr); - return(-1); + return (-1); } static int32_t code_break_num; @@ -746,9 +746,9 @@ static void init_code_breakpoints(stlink_t *sl) { static int32_t has_breakpoint(stm32_addr_t addr) { for (int32_t i = 0; i < code_break_num; i++) - if (code_breaks[i].addr == addr) { return(1); } + if (code_breaks[i].addr == addr) { return (1); } - return(0); + return (0); } static int32_t update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int32_t set) { @@ -758,7 +758,7 @@ static int32_t update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int32_t s if (addr & 1) { ELOG("update_code_breakpoint: unaligned address %08x\n", addr); - return(-1); + return (-1); } if (code_break_rev == CODE_BREAK_REV_V1) { @@ -778,9 +778,9 @@ static int32_t update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int32_t s if (id == -1) { if (set) - return(-1); // free slot not found + return (-1); // free slot not found else - return(0); // breakpoint is already removed + return (0); // breakpoint is already removed } struct code_hw_breakpoint* bp = &code_breaks[id]; @@ -802,7 +802,7 @@ static int32_t update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int32_t s stlink_write_debug32(sl, STLINK_REG_CM3_FP_COMPn(id), mask); } - return(0); + return (0); } @@ -820,14 +820,14 @@ static int32_t flash_add_block(stm32_addr_t addr, uint32_t length, stlink_t *sl) if (addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) { ELOG("flash_add_block: incorrect bounds\n"); - return(-1); + return (-1); } stlink_calculate_pagesize(sl, addr); if (addr % FLASH_PAGE != 0 || length % FLASH_PAGE != 0) { ELOG("flash_add_block: unaligned block\n"); - return(-1); + return (-1); } struct flash_block* new = malloc(sizeof(struct flash_block)); @@ -838,7 +838,7 @@ static int32_t flash_add_block(stm32_addr_t addr, uint32_t length, stlink_t *sl) memset(new->data, stlink_get_erased_pattern(sl), length); flash_root = new; - return(0); + return (0); } static int32_t flash_populate(stm32_addr_t addr, uint8_t* data, uint32_t length) { @@ -871,7 +871,7 @@ static int32_t flash_populate(stm32_addr_t addr, uint8_t* data, uint32_t length) if (fit_blocks == 0) { ELOG("Unfit data block %08x -> %04x\n", addr, length); - return(-1); + return (-1); } if (fit_length != length) { @@ -879,7 +879,7 @@ static int32_t flash_populate(stm32_addr_t addr, uint8_t* data, uint32_t length) WLOG("(this is not an error, just a GDB glitch)\n"); } - return(0); + return (0); } static int32_t flash_go(stlink_t *sl, st_state_t *st) { @@ -935,7 +935,7 @@ static int32_t flash_go(stlink_t *sl, st_state_t *st) { } flash_root = NULL; - return(error); + return (error); } struct cache_level_desc { @@ -967,7 +967,7 @@ static uint32_t ceil_log2(uint32_t v) { for (res = 0; (1U << res) < v; res++); - return(res); + return (res); } static void read_cache_level_desc(stlink_t *sl, struct cache_level_desc *desc) { @@ -1083,12 +1083,12 @@ static uint32_t unhexify(const char *in, char *out, uint32_t out_count) { uint32_t c; for (i = 0; i < out_count; i++) { - if (sscanf(in + (2 * i), "%02x", &c) != 1) { return(i); } + if (sscanf(in + (2 * i), "%02x", &c) != 1) { return (i); } out[i] = (char)c; } - return(i); + return (i); } int32_t serve(stlink_t *sl, st_state_t *st) { @@ -1096,7 +1096,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) { if (!IS_SOCK_VALID(sock)) { perror("socket"); - return(1); + return (1); } uint32_t val = 1; @@ -1111,13 +1111,13 @@ int32_t serve(stlink_t *sl, st_state_t *st) { if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("bind"); close_socket(sock); - return(1); + return (1); } if (listen(sock, 5) < 0) { perror("listen"); close_socket(sock); - return(1); + return (1); } ILOG("Listening at *:%d...\n", st->listen_port); @@ -1128,7 +1128,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) { if (!IS_SOCK_VALID(client)) { perror("accept"); close_socket(sock); - return(1); + return (1); } close_socket(sock); @@ -1169,7 +1169,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) { if (status < 0) { ELOG("cannot recv: %d\n", status); close_socket(client); - return(1); + return (1); } DLOG("recv: %s\n", packet); @@ -1447,7 +1447,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) { if (status < 0) { ELOG("cannot check for int: %d\n", status); close_socket(client); - return(1); + return (1); } if (status == 1) { @@ -1884,7 +1884,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) { free(reply); free(packet); close_socket(client); - return(1); + return (1); } free(reply); @@ -1892,12 +1892,12 @@ int32_t serve(stlink_t *sl, st_state_t *st) { if (critical_error) { close_socket(client); - return(1); + return (1); } free(packet); } close_socket(client); - return(0); + return (0); } diff --git a/src/st-util/semihosting.c b/src/st-util/semihosting.c index 93a6cf7cc..a200a7408 100644 --- a/src/st-util/semihosting.c +++ b/src/st-util/semihosting.c @@ -16,13 +16,13 @@ static int32_t mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) { int32_t offset = addr % 4; int32_t len = 4; - if (sl == NULL || data == NULL) { return(-1); } + if (sl == NULL || data == NULL) { return (-1); } // read address and length must be aligned - if (stlink_read_mem32(sl, addr - offset, len) != 0) { return(-1); } + if (stlink_read_mem32(sl, addr - offset, len) != 0) { return (-1); } *data = sl->q_buf[offset]; - return(0); + return (0); } #ifdef UNUSED @@ -30,26 +30,26 @@ static int32_t mem_read_u16(stlink_t *sl, uint32_t addr, uint16_t *data) { int32_t offset = addr % 4; int32_t len = (offset > 2 ? 8 : 4); - if (sl == NULL || data == NULL) { return(-1); } + if (sl == NULL || data == NULL) { return (-1); } // read address and length must be aligned - if (stlink_read_mem32(sl, addr - offset, len) != 0) { return(-1); } + if (stlink_read_mem32(sl, addr - offset, len) != 0) { return (-1); } memcpy(data, &sl->q_buf[offset], sizeof(*data)); - return(0); + return (0); } static int32_t mem_read_u32(stlink_t *sl, uint32_t addr, uint32_t *data) { int32_t offset = addr % 4; int32_t len = (offset > 0 ? 8 : 4); - if (sl == NULL || data == NULL) { return(-1); } + if (sl == NULL || data == NULL) { return (-1); } // read address and length must be aligned - if (stlink_read_mem32(sl, addr - offset, len) != 0) { return(-1); } + if (stlink_read_mem32(sl, addr - offset, len) != 0) { return (-1); } memcpy(data, &sl->q_buf[offset], sizeof(*data)); - return(0); + return (0); } #endif @@ -57,16 +57,16 @@ static int32_t mem_read(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { int32_t offset = addr % 4; int32_t read_len = len + offset; - if (sl == NULL || data == NULL) { return(-1); } + if (sl == NULL || data == NULL) { return (-1); } // align read size if ((read_len % 4) != 0) { read_len += 4 - (read_len % 4); } // address and length must be aligned - if (stlink_read_mem32(sl, addr - offset, read_len) != 0) { return(-1); } + if (stlink_read_mem32(sl, addr - offset, read_len) != 0) { return (-1); } memcpy(data, &sl->q_buf[offset], len); - return(0); + return (0); } static int32_t mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) { @@ -77,12 +77,12 @@ static int32_t mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) * the requested bytes. (perhaps reading the whole area is faster??). * If 16 and 8 bit writes are available, then they could be used instead. * Just return when the length is zero avoiding unneeded work. */ - if (len == 0) { return(0); } + if (len == 0) { return (0); } int32_t offset = addr % 4; int32_t write_len = len + offset; - if (sl == NULL || data == NULL) { return(-1); } + if (sl == NULL || data == NULL) { return (-1); } // align read size if ((write_len % 4) != 0) { write_len += 4 - (write_len % 4); } @@ -90,9 +90,9 @@ static int32_t mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) memcpy(&sl->q_buf[offset], data, len); // address and length must be aligned - if (stlink_write_mem32(sl, addr - offset, write_len) != 0) { return(-1); } + if (stlink_write_mem32(sl, addr - offset, write_len) != 0) { return (-1); } - return(0); + return (0); } /* For the SYS_WRITE0 call, we don't know the size of the null-terminated buffer @@ -132,7 +132,7 @@ static int32_t saved_errno = 0; int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { - if (sl == NULL || ret == NULL) { return(-1); } + if (sl == NULL || ret == NULL) { return (-1); } DLOG("Do semihosting R0=0x%08x R1=0x%08x\n", r0, r1); @@ -148,7 +148,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (mem_read(sl, r1, args, sizeof(args)) != 0) { DLOG("Semihosting SYS_OPEN error: cannot read args from target memory\n"); *ret = -1; - return(-1); + return (-1); } name_address = args[0]; @@ -159,7 +159,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { /* Invalid mode */ DLOG("Semihosting SYS_OPEN error: invalid mode %d\n", mode); *ret = -1; - return(-1); + return (-1); } /* Add the trailing zero that is not counted in the length argument (see @@ -170,7 +170,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (name_len > MAX_BUFFER_SIZE) { DLOG("Semihosting SYS_OPEN error: name buffer size is too big %d\n", name_len); *ret = -1; - return(-1); + return (-1); } name = malloc(name_len); @@ -178,14 +178,14 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (name == NULL) { DLOG("Semihosting SYS_OPEN error: cannot allocate name buffer\n"); *ret = -1; - return(-1); + return (-1); } if (mem_read(sl, name_address, name, name_len) != 0) { free(name); *ret = -1; DLOG("Semihosting SYS_OPEN error: cannot read name from target memory\n"); - return(-1); + return (-1); } DLOG("Semihosting: open('%s', (SH open mode)%d, 0644)\n", name, mode); @@ -206,7 +206,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (mem_read(sl, r1, args, sizeof(args)) != 0) { DLOG("Semihosting SYS_CLOSE error: cannot read args from target memory\n"); *ret = -1; - return(-1); + return (-1); } fd = (int32_t)args[0]; @@ -230,7 +230,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (mem_read(sl, r1, args, sizeof(args)) != 0) { DLOG("Semihosting SYS_WRITE error: cannot read args from target memory\n"); *ret = -1; - return(-1); + return (-1); } fd = (int32_t)args[0]; @@ -241,7 +241,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { DLOG("Semihosting SYS_WRITE error: buffer size is too big %d\n", buffer_len); *ret = buffer_len; - return(-1); + return (-1); } buffer = malloc(buffer_len); @@ -249,14 +249,14 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (buffer == NULL) { DLOG("Semihosting SYS_WRITE error: cannot allocate buffer\n"); *ret = buffer_len; - return(-1); + return (-1); } if (mem_read(sl, buffer_address, buffer, buffer_len) != 0) { DLOG("Semihosting SYS_WRITE error: cannot read buffer from target memory\n"); free(buffer); *ret = buffer_len; - return(-1); + return (-1); } DLOG("Semihosting: write(%d, target_addr:0x%08x, %u)\n", fd, buffer_address, buffer_len); @@ -286,7 +286,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (mem_read(sl, r1, args, sizeof(args)) != 0) { DLOG("Semihosting SYS_READ error: cannot read args from target memory\n"); *ret = -1; - return(-1); + return (-1); } fd = (int32_t)args[0]; @@ -296,7 +296,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (buffer_len > MAX_BUFFER_SIZE) { DLOG("Semihosting SYS_READ error: buffer size is too big %d\n", buffer_len); *ret = buffer_len; - return(-1); + return (-1); } buffer = malloc(buffer_len); @@ -304,7 +304,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (buffer == NULL) { DLOG("Semihosting SYS_READ error: cannot allocatebuffer\n"); *ret = buffer_len; - return(-1); + return (-1); } DLOG("Semihosting: read(%d, target_addr:0x%08x, %u)\n", fd, buffer_address, @@ -320,7 +320,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { DLOG("Semihosting SYS_READ error: cannot write buffer to target memory\n"); free(buffer); *ret = buffer_len; - return(-1); + return (-1); } else { *ret = buffer_len - (uint32_t)read_result; } @@ -346,7 +346,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (mem_read(sl, r1, args, sizeof(args)) != 0) { DLOG("Semihosting SYS_REMOVE error: cannot read args from target memory\n"); *ret = -1; - return(-1); + return (-1); } name_address = args[0]; @@ -361,7 +361,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { DLOG("Semihosting SYS_REMOVE error: name buffer size is too big %d\n", name_len); *ret = -1; - return(-1); + return (-1); } name = malloc(name_len); @@ -369,14 +369,14 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (name == NULL) { DLOG("Semihosting SYS_REMOVE error: cannot allocate name buffer\n"); *ret = -1; - return(-1); + return (-1); } if (mem_read(sl, name_address, name, name_len) != 0) { free(name); *ret = -1; DLOG("Semihosting SYS_REMOVE error: cannot read name from target memory\n"); - return(-1); + return (-1); } DLOG("Semihosting: unlink('%s')\n", name); @@ -395,7 +395,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { if (mem_read(sl, r1, args, sizeof(args)) != 0) { DLOG("Semihosting SYS_SEEK error: cannot read args from target memory\n"); *ret = -1; - return(-1); + return (-1); } fd = (int32_t)args[0]; @@ -435,11 +435,11 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { while (true) { if (mem_read(sl, r1, buf, WRITE0_BUFFER_SIZE) != 0) { DLOG("Semihosting WRITE0: cannot read target memory at 0x%08x\n", r1); - return(-1); + return (-1); } for (int32_t i = 0; i < WRITE0_BUFFER_SIZE; i++) { - if (buf[i] == 0) { return(0); } + if (buf[i] == 0) { return (0); } fprintf(stderr, "%c", buf[i]); } @@ -451,7 +451,7 @@ int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { } default: fprintf(stderr, "semihosting: unsupported call %#x\n", r0); - return(-1); + return (-1); } - return(0); + return (0); } diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index fb4478bdc..bbfcc20a3 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -31,5 +31,5 @@ if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_SHAREDIR}/${PROJECT_NAME}") target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) install(TARGETS stlink-gui DESTINATION ${CMAKE_BINDIR}) - endif () -endif () + endif() +endif() diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index 5853e5ec4..4b312c8a1 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -63,7 +63,7 @@ static gboolean set_info_error_message_idle(STlinkGUI *gui) { gui->error_message = NULL; } - return(FALSE); + return (FALSE); } static void stlink_gui_set_info_error_message(STlinkGUI *gui, const gchar *message) { @@ -156,15 +156,15 @@ static guint32 hexstr_to_guint32(const gchar *str, GError **err) { if ((errno == ERANGE && val == UINT_MAX) || (errno != 0 && val == 0)) { g_set_error(err, g_quark_from_string("hextou32"), 1, "Invalid hexstring"); - return(UINT32_MAX); + return (UINT32_MAX); } if (end_ptr == str) { g_set_error(err, g_quark_from_string("hextou32"), 2, "Invalid hexstring"); - return(UINT32_MAX); + return (UINT32_MAX); } - return(val); + return (val); } static void stlink_gui_update_mem_view(STlinkGUI *gui, struct mem_t *mem, GtkTreeView *view) { @@ -182,7 +182,7 @@ static void stlink_gui_update_mem_view(STlinkGUI *gui, struct mem_t *mem, GtkTre static gboolean stlink_gui_update_devmem_view(STlinkGUI *gui) { stlink_gui_update_mem_view(gui, &gui->flash_mem, gui->devmem_treeview); - return(FALSE); + return (FALSE); } static gpointer stlink_gui_populate_devmem_view(gpointer data) { @@ -220,7 +220,7 @@ static gpointer stlink_gui_populate_devmem_view(gpointer data) { stlink_gui_set_info_error_message(gui, "Failed to read memory"); g_free(gui->flash_mem.memory); gui->flash_mem.memory = NULL; - return(NULL); + return (NULL); } memcpy(gui->flash_mem.memory + off, gui->sl->q_buf, n_read); @@ -228,7 +228,7 @@ static gpointer stlink_gui_populate_devmem_view(gpointer data) { } g_idle_add((GSourceFunc)stlink_gui_update_devmem_view, gui); - return(NULL); + return (NULL); } static gboolean stlink_gui_update_filemem_view(STlinkGUI *gui) { @@ -240,7 +240,7 @@ static gboolean stlink_gui_update_filemem_view(STlinkGUI *gui) { g_free(basename); stlink_gui_update_mem_view(gui, &gui->file_mem, gui->filemem_treeview); - return(FALSE); + return (FALSE); } static gpointer stlink_gui_populate_filemem_view(gpointer data) { @@ -338,7 +338,7 @@ out: g_object_unref(file); } g_idle_add((GSourceFunc)stlink_gui_update_filemem_view, gui); - return(NULL); + return (NULL); } static void mem_jmp(GtkTreeView *view, @@ -438,13 +438,13 @@ static gchar *dev_format_chip_id(guint32 chip_id) { params = stlink_chipid_get_params(chip_id); - if (!params) { return(g_strdup_printf("0x%x", chip_id)); } + if (!params) { return (g_strdup_printf("0x%x", chip_id)); } - return(g_strdup(params->dev_type)); + return (g_strdup(params->dev_type)); } static gchar *dev_format_mem_size(gsize flash_size) { - return(g_strdup_printf("%u kB", (uint32_t)(flash_size / 1024))); + return (g_strdup_printf("%u kB", (uint32_t)(flash_size / 1024))); } @@ -585,7 +585,7 @@ static gboolean stlink_gui_write_flash_update(STlinkGUI *gui) { stlink_gui_set_sensitivity(gui, TRUE); gui->progress.activity_mode = FALSE; gtk_widget_hide(GTK_WIDGET(gui->progress.bar)); - return(FALSE); + return (FALSE); } static gpointer stlink_gui_write_flash(gpointer data) { @@ -601,7 +601,7 @@ static gpointer stlink_gui_write_flash(gpointer data) { } g_idle_add((GSourceFunc)stlink_gui_write_flash_update, gui); - return(NULL); + return (NULL); } static void flash_button_cb(GtkWidget *widget, gpointer data) { @@ -648,13 +648,13 @@ int32_t export_to_file(const char*filename, const struct mem_t flash_mem) { printf("%s\n", filename); FILE * f = fopen(filename, "w"); - if (f == NULL) { return(-1); } + if (f == NULL) { return (-1); } for (gsize i = 0; i < flash_mem.size; i++) - if (fputc(flash_mem.memory[i], f) == EOF) { return(-1); } + if (fputc(flash_mem.memory[i], f) == EOF) { return (-1); } fclose(f); - return(0); + return (0); } static void export_button_cb(GtkWidget *widget, gpointer data) { @@ -697,7 +697,7 @@ static gboolean progress_pulse_timeout(STlinkGUI *gui) { gtk_progress_bar_set_fraction(gui->progress.bar, gui->progress.fraction); } - return(TRUE); + return (TRUE); } static void notebook_switch_page_cb(GtkNotebook *notebook, @@ -901,5 +901,5 @@ int32_t main(int32_t argc, char **argv) { stlink_gui_init_dnd(gui); gtk_main(); - return(0); + return (0); } diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 0ab8cf6c1..0f12c3131 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -177,7 +177,7 @@ int32_t stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { // allocate the loader in SRAM if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { WLOG("Failed to write flash loader to sram!\n"); - return(-1); + return (-1); } // allocate a one page buffer in SRAM right after loader @@ -205,7 +205,7 @@ int32_t stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { stlink_write_debug32(sl, STLINK_REG_HFSR, hfsr); } - return(0); + return (0); } static int32_t loader_v_dependent_assignment(stlink_t *sl, @@ -235,7 +235,7 @@ static int32_t loader_v_dependent_assignment(stlink_t *sl, } } - return(retval); + return (retval); } int32_t stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, uint32_t* size) { @@ -285,7 +285,7 @@ int32_t stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, uint loader_code_stm32f4, sizeof(loader_code_stm32f4), loader_code_stm32f4_lv, sizeof(loader_code_stm32f4_lv)); - if (retval == -1) { return(retval); } + if (retval == -1) { return (retval); } } else if (sl->core_id == STM32_CORE_ID_M7F_SWD || sl->chip_id == STM32_CHIPID_F7 || sl->chip_id == STM32_CHIPID_F76xxx || @@ -296,7 +296,7 @@ int32_t stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, uint loader_code_stm32f7, sizeof(loader_code_stm32f7), loader_code_stm32f7_lv, sizeof(loader_code_stm32f7_lv)); - if (retval == -1) { return(retval); } + if (retval == -1) { return (retval); } } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F04 || sl->chip_id == STM32_CHIPID_F0_CAN || @@ -315,18 +315,18 @@ int32_t stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, uint } else { ELOG("unknown coreid, not sure what flash loader to use, aborting! coreid: %x, chipid: %x\n", sl->core_id, sl->chip_id); - return(-1); + return (-1); } memcpy(sl->q_buf, loader_code, loader_size); int32_t ret = stlink_write_mem32(sl, sl->sram_base, (uint16_t)loader_size); - if (ret) { return(ret); } + if (ret) { return (ret); } *addr = sl->sram_base; *size = loader_size; - return(0); // success + return (0); // success } int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, uint32_t size) { @@ -339,7 +339,7 @@ int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t t if (write_buffer_to_sram(sl, fl, buf, size) == -1) { ELOG("write_buffer_to_sram() == -1\n"); - return(-1); + return (-1); } if ((sl->flash_type == STM32_FLASH_TYPE_F1_XL) && (target >= FLASH_BANK2_START_ADDR)) { @@ -404,7 +404,7 @@ int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t t goto error; } - return(0); + return (0); error: dhcsr = dfsr = cfsr = hfsr = 0; @@ -419,7 +419,7 @@ int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t t WLOG("MCU state: DHCSR 0x%X DFSR 0x%X CFSR 0x%X HFSR 0x%X\n", dhcsr, dfsr, cfsr, hfsr); } - return(-1); + return (-1); } @@ -868,8 +868,7 @@ int32_t stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { (sl->flash_type == STM32_FLASH_TYPE_WB_WL)) { clear_flash_cr_pg(sl, BANK_1); - if ((sl->flash_type == STM32_FLASH_TYPE_H7 && - sl->chip_flags & CHIP_F_HAS_DUAL_BANK) || + if ((sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK) || sl->flash_type == STM32_FLASH_TYPE_F1_XL) { clear_flash_cr_pg(sl, BANK_2); } @@ -886,9 +885,8 @@ int32_t stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { // enable interrupt if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) { - stlink_write_debug32(sl, STLINK_REG_DHCSR, - STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | - (dhcsr & (~STLINK_REG_DHCSR_C_MASKINTS))); + stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + (dhcsr & (~STLINK_REG_DHCSR_C_MASKINTS))); } // restore DMA state diff --git a/src/stlink-lib/lib_md5.c b/src/stlink-lib/lib_md5.c index 71703273c..62e77252e 100644 --- a/src/stlink-lib/lib_md5.c +++ b/src/stlink-lib/lib_md5.c @@ -152,7 +152,7 @@ static void* TransformFunction(Md5Context* ctx, void const* data, uintmax_t size #undef GET #undef SET - return(ptr); + return (ptr); } /* EXPORTED FUNCTIONS */ diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index d7f844b51..b744389ba 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -141,12 +141,12 @@ static int32_t get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t if (ret != LIBUSB_SUCCESS) { WLOG("%s: receiving failed: %d\n", __func__, ret); - return(-1); + return (-1); } if (transferred != sizeof(csw)) { WLOG("%s: received unexpected amount: %d\n", __func__, transferred); - return(-1); + return (-1); } uint32_t rsig = read_uint32(csw, 0); @@ -157,12 +157,12 @@ static int32_t get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t if (rsig != USB_CSW_SIGNATURE) { WLOG("status signature was invalid: %#x\n", rsig); - return(-1); + return (-1); } *tag = rtag; uint8_t rstatus = csw[12]; - return(rstatus); + return (rstatus); } static int32_t dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) { @@ -176,7 +176,7 @@ static int32_t dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) { sprintf(dbugp, "]\n"); DLOG("%s",dbugblah); - return(0); + return (0); } /** @@ -239,10 +239,10 @@ int32_t send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endp if (ret != LIBUSB_SUCCESS) { WLOG("sending failed: %d\n", ret); - return(-1); + return (-1); } - return(this_tag); + return (this_tag); } /** @@ -332,7 +332,7 @@ int32_t send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_ if (ret != LIBUSB_SUCCESS) { WLOG("sending failed: %d\n", ret); - return(-1); + return (-1); } // now, swallow up the status, so that things behave nicely... @@ -342,7 +342,7 @@ int32_t send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_ if (status < 0) { WLOG("receiving status failed: %d\n", status); - return(-1); + return (-1); } if (status != 0) { @@ -351,10 +351,10 @@ int32_t send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_ if (status == 1) { get_sense(handle, endpoint_in, endpoint_out); - return(-1); + return (-1); } - return(real_transferred); + return (real_transferred); } int32_t stlink_q(stlink_t *sl) { @@ -386,7 +386,7 @@ int32_t stlink_q(stlink_t *sl) { if (ret != LIBUSB_SUCCESS) { WLOG("Receiving failed: %d\n", ret); - return(-1); + return (-1); } if (real_transferred != rx_length) { @@ -400,7 +400,7 @@ int32_t stlink_q(stlink_t *sl) { if (status < 0) { WLOG("receiving status failed: %d\n", status); - return(-1); + return (-1); } if (status != 0) { @@ -409,7 +409,7 @@ int32_t stlink_q(stlink_t *sl) { if (status == 1) { get_sense(sg->usb_handle, sg->ep_rep, sg->ep_req); - return(-1); + return (-1); } if (received_tag != tag) { @@ -418,10 +418,10 @@ int32_t stlink_q(stlink_t *sl) { } if (rx_length > 0 && real_transferred != rx_length) { - return(-1); + return (-1); } - return(0); + return (0); } // TODO: thinking, cleanup @@ -448,7 +448,7 @@ int32_t _stlink_sg_version(stlink_t *stl) { sl->cdb_cmd_blk[0] = STLINK_GET_VERSION; stl->q_len = 6; sl->q_addr = 0; - return(stlink_q(stl)); + return (stlink_q(stl)); } // Get stlink mode: @@ -461,9 +461,9 @@ int32_t _stlink_sg_current_mode(stlink_t *stl) { stl->q_len = 2; sl->q_addr = 0; - if (stlink_q(stl)) { return(-1); } + if (stlink_q(stl)) { return (-1); } - return(stl->q_buf[0]); + return (stl->q_buf[0]); } // exit the mass mode and enter the swd debug mode. @@ -473,7 +473,7 @@ int32_t _stlink_sg_enter_swd_mode(stlink_t *sl) { sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_SWD; sl->q_len = 0; // >0 -> aboard - return(stlink_q(sl)); + return (stlink_q(sl)); } // exit the mass mode and enter the jtag debug mode. @@ -485,7 +485,7 @@ int32_t _stlink_sg_enter_jtag_mode(stlink_t *sl) { sg->cdb_cmd_blk[1] = STLINK_DEBUG_APIV1_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_JTAG_RESET; sl->q_len = 0; - return(stlink_q(sl)); + return (stlink_q(sl)); } // XXX kernel driver performs reset, the device temporally disappears @@ -497,7 +497,7 @@ int32_t _stlink_sg_exit_dfu_mode(stlink_t *sl) { sg->cdb_cmd_blk[0] = STLINK_DFU_COMMAND; sg->cdb_cmd_blk[1] = STLINK_DFU_EXIT; sl->q_len = 0; // ?? - return(stlink_q(sl)); + return (stlink_q(sl)); /* [135121.844564] sd 19:0:0:0: [sdb] Unhandled error code [135121.844569] sd 19:0:0:0: [sdb] Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK @@ -552,10 +552,10 @@ int32_t _stlink_sg_core_id(stlink_t *sl) { sg->q_addr = 0; ret = stlink_q(sl); - if (ret) { return(ret); } + if (ret) { return (ret); } sl->core_id = read_uint32(sl->q_buf, 0); - return(0); + return (0); } // arm-core reset -> halted state. @@ -566,17 +566,17 @@ int32_t _stlink_sg_reset(stlink_t *sl) { sl->q_len = 2; sg->q_addr = 0; - if (stlink_q(sl)) { return(-1); } + if (stlink_q(sl)) { return (-1); } // Reset through AIRCR so NRST does not need to be connected if (stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | \ STLINK_REG_AIRCR_SYSRESETREQ)) { - return(-1); + return (-1); } stlink_stat(sl, "core reset"); - return(0); + return (0); } // arm-core reset -> halted state. @@ -588,11 +588,11 @@ int32_t _stlink_sg_jtag_reset(stlink_t *sl, int32_t value) { sl->q_len = 3; sg->q_addr = 2; - if (stlink_q(sl)) { return(-1); } + if (stlink_q(sl)) { return (-1); } stlink_stat(sl, "core reset"); - return(0); + return (0); } // arm-core status: halted or running. @@ -602,7 +602,7 @@ int32_t _stlink_sg_status(stlink_t *sl) { sg->cdb_cmd_blk[1] = STLINK_DEBUG_GETSTATUS; sl->q_len = 2; sg->q_addr = 0; - return(stlink_q(sl)); + return (stlink_q(sl)); } // force the core into the debug mode -> halted state. @@ -613,10 +613,10 @@ int32_t _stlink_sg_force_debug(stlink_t *sl) { sl->q_len = 2; sg->q_addr = 0; - if (stlink_q(sl)) { return(-1); } + if (stlink_q(sl)) { return (-1); } stlink_stat(sl, "force debug"); - return(0); + return (0); } // read all arm-core registers. @@ -628,7 +628,7 @@ int32_t _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { sl->q_len = 84; sg->q_addr = 0; - if (stlink_q(sl)) { return(-1); } + if (stlink_q(sl)) { return (-1); } stlink_print_data(sl); @@ -648,7 +648,7 @@ int32_t _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { regp->rw = read_uint32(sl->q_buf, 76); regp->rw2 = read_uint32(sl->q_buf, 80); - if (sl->verbose < 2) { return(0); } + if (sl->verbose < 2) { return (0); } DLOG("xpsr = 0x%08x\n", regp->xpsr); DLOG("main_sp = 0x%08x\n", regp->main_sp); @@ -656,7 +656,7 @@ int32_t _stlink_sg_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { DLOG("rw = 0x%08x\n", regp->rw); DLOG("rw2 = 0x%08x\n", regp->rw2); - return(0); + return (0); } // read an arm-core register, the index must be in the range 0..20. @@ -671,7 +671,7 @@ int32_t _stlink_sg_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp sl->q_len = 4; sg->q_addr = 0; - if (stlink_q(sl)) { return(-1); } + if (stlink_q(sl)) { return (-1); } // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71 | 72-75 | 76-79 | 80-83 @@ -701,7 +701,7 @@ int32_t _stlink_sg_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp regp->r[r_idx] = r; } - return(0); + return (0); } // write an arm-core register. Index: @@ -719,10 +719,10 @@ int32_t _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int32_t idx) { sl->q_len = 2; sg->q_addr = 0; - if (stlink_q(sl)) { return(-1); } + if (stlink_q(sl)) { return (-1); } stlink_stat(sl, "write reg"); - return(0); + return (0); } // write a register of the debug module of the core. @@ -752,11 +752,11 @@ int32_t _stlink_sg_run(stlink_t *sl, enum run_type type) { sl->q_len = 2; sg->q_addr = 0; - if (stlink_q(sl)) { return(-1); } + if (stlink_q(sl)) { return (-1); } stlink_stat(sl, "run core"); - return(0); + return (0); } // step the arm-core. @@ -767,10 +767,10 @@ int32_t _stlink_sg_step(stlink_t *sl) { sl->q_len = 2; sg->q_addr = 0; - if (stlink_q(sl)) { return(-1); } + if (stlink_q(sl)) { return (-1); } stlink_stat(sl, "step core"); - return(0); + return (0); } // TODO: test and make delegate! @@ -823,10 +823,10 @@ int32_t _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { sl->q_len = len; sg->q_addr = addr; - if (stlink_q(sl)) { return(-1); } + if (stlink_q(sl)) { return (-1); } stlink_print_data(sl); - return(0); + return (0); } // write a "len" bytes from the sl->q_buf to the memory, max 64 Bytes. @@ -845,16 +845,16 @@ int32_t _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { ret = send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } // This sends the data... ret = send_usb_data_only(sg->usb_handle, sg->ep_req, sg->ep_rep, sl->q_buf, len); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } stlink_print_data(sl); - return(0); + return (0); } // write a "len" bytes from the sl->q_buf to the memory, max Q_BUF_LEN bytes. @@ -873,16 +873,16 @@ int32_t _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { ret = send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } // This sends the data... ret = send_usb_data_only(sg->usb_handle, sg->ep_req, sg->ep_rep, sl->q_buf, len); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } stlink_print_data(sl); - return(0); + return (0); } // write one DWORD data to memory @@ -894,7 +894,7 @@ int32_t _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { write_uint32(sg->cdb_cmd_blk + 2, addr); write_uint32(sg->cdb_cmd_blk + 6, data); sl->q_len = 2; - return(stlink_q(sl)); + return (stlink_q(sl)); } // read one DWORD data from memory @@ -906,10 +906,10 @@ int32_t _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { write_uint32(sg->cdb_cmd_blk + 2, addr); sl->q_len = 8; - if (stlink_q(sl)) { return(-1); } + if (stlink_q(sl)) { return (-1); } *data = read_uint32(sl->q_buf, 4); - return(0); + return (0); } // exit the jtag or swd mode and enter the mass mode. @@ -919,10 +919,10 @@ int32_t _stlink_sg_exit_debug_mode(stlink_t *stl) { clear_cdb(sl); sl->cdb_cmd_blk[1] = STLINK_DEBUG_EXIT; stl->q_len = 0; // >0 -> aboard - return(stlink_q(stl)); + return (stlink_q(stl)); } - return(0); + return (0); } // 1) open a sg device, switch the stlink from dfu to mass mode @@ -975,7 +975,7 @@ static stlink_t* stlink_open(const int32_t verbose) { if (slsg != NULL) { free(slsg); } - return(NULL); + return (NULL); } memset(sl, 0, sizeof(stlink_t)); @@ -984,7 +984,7 @@ static stlink_t* stlink_open(const int32_t verbose) { WLOG("failed to init libusb context, wrong version of libraries?\n"); free(sl); free(slsg); - return(NULL); + return (NULL); } #if LIBUSB_API_VERSION < 0x01000106 @@ -1001,7 +1001,7 @@ static stlink_t* stlink_open(const int32_t verbose) { libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); - return(NULL); + return (NULL); } // TODO: Could read the interface config descriptor, and assert lots of the assumptions @@ -1015,7 +1015,7 @@ static stlink_t* stlink_open(const int32_t verbose) { libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); - return(NULL); + return (NULL); } DLOG("Kernel driver was successfully detached\n"); @@ -1030,7 +1030,7 @@ static stlink_t* stlink_open(const int32_t verbose) { libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); - return(NULL); + return (NULL); } @@ -1046,7 +1046,7 @@ static stlink_t* stlink_open(const int32_t verbose) { libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); - return(NULL); + return (NULL); } } @@ -1056,7 +1056,7 @@ static stlink_t* stlink_open(const int32_t verbose) { libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); - return(NULL); + return (NULL); } // assumption: endpoint config is fixed mang. really. @@ -1072,7 +1072,7 @@ static stlink_t* stlink_open(const int32_t verbose) { sl->core_stat = TARGET_UNKNOWN; slsg->q_addr = 0; - return(sl); + return (sl); } @@ -1082,24 +1082,24 @@ stlink_t* stlink_v1_open_inner(const int32_t verbose) { if (sl == NULL) { ELOG("Could not open stlink device\n"); - return(NULL); + return (NULL); } stlink_version(sl); if ((sl->version.st_vid != STLINK_USB_VID_ST) || (sl->version.stlink_pid != STLINK_USB_PID_STLINK)) { ELOG("WTF? successfully opened, but unable to read version details. BROKEN!\n"); - return(NULL); + return (NULL); } DLOG("Reading current mode...\n"); switch (stlink_current_mode(sl)) { case STLINK_DEV_MASS_MODE: - return(sl); + return (sl); case STLINK_DEV_DEBUG_MODE: // TODO go to mass? - return(sl); + return (sl); default: ILOG("Current mode unusable, trying to get back to a useful state...\n"); break; @@ -1113,16 +1113,16 @@ stlink_t* stlink_v1_open_inner(const int32_t verbose) { if ((sl->version.st_vid != STLINK_USB_VID_ST) || (sl->version.stlink_pid != STLINK_USB_PID_STLINK)) { ELOG("WTF? successfully opened, but unable to read version details. BROKEN!\n"); - return(NULL); + return (NULL); } - return(sl); + return (sl); } stlink_t* stlink_v1_open(const int32_t verbose, int32_t reset) { stlink_t *sl = stlink_v1_open_inner(verbose); - if (sl == NULL) { return(NULL); } + if (sl == NULL) { return (NULL); } // by now, it _must_ be fully open and in a useful mode.... stlink_enter_swd_mode(sl); @@ -1132,5 +1132,5 @@ stlink_t* stlink_v1_open(const int32_t verbose, int32_t reset) { stlink_load_device_params(sl); ILOG("Successfully opened a stlink v1 debugger\n"); - return(sl); + return (sl); } diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index c2425b6cd..0934fe368 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -30,7 +30,7 @@ #include "register.h" static inline uint32_t le_to_h_u32(const uint8_t* buf) { - return((uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24)); + return ((uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24)); } static int32_t _stlink_match_speed_map(const uint32_t *map, uint32_t map_size, uint32_t khz) { @@ -73,7 +73,7 @@ static int32_t _stlink_match_speed_map(const uint32_t *map, uint32_t map_size, u ILOG("Unable to match requested speed %d kHz, using %d kHz\n", khz, map[speed_index]); } - return(speed_index); + return (speed_index); } void _stlink_usb_close(stlink_t* sl) { @@ -101,7 +101,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char if (t) { ELOG("%s send request failed: %s\n", cmd, libusb_error_name(t)); - return(-1); + return (-1); } else if ((size_t)res != txsize) { ELOG("%s send request wrote %u bytes, instead of %u\n", cmd, (uint32_t)res, (uint32_t)txsize); } @@ -111,7 +111,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char if (t) { ELOG("%s read reply failed: %s\n", cmd, libusb_error_name(t)); - return(-1); + return (-1); } /* Checking the command execution status stored in the first byte of the response */ @@ -139,7 +139,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char default: DLOG("%s error (0x%02X)\n", cmd, rxbuf[0]); break; } - return(-1); + return (-1); } if (check_error == CMD_CHECK_REP_LEN && res != (int32_t)rxsize) { @@ -155,20 +155,20 @@ ssize_t send_recv(struct stlink_libusb* handle, int32_t terminate, unsigned char if (t) { ELOG("%s read storage failed: %s\n", cmd, libusb_error_name(t)); - return(-1); + return (-1); } // The STLink doesn't seem to evaluate the sequence number. handle->sg_transfer_idx++; } - return(res); + return (res); } } static inline int32_t send_only(struct stlink_libusb* handle, int32_t terminate, unsigned char* txbuf, uint32_t txsize, const char *cmd) { - return((int32_t)send_recv(handle, terminate, txbuf, txsize, NULL, 0, CMD_CHECK_NO, cmd)); + return ((int32_t)send_recv(handle, terminate, txbuf, txsize, NULL, 0, CMD_CHECK_NO, cmd)); } @@ -190,7 +190,7 @@ static int32_t fill_command(stlink_t * sl, enum SCSI_Generic_Direction dir, uint cmd[i++] = 0; // logical unit cmd[i++] = 0xa; // command length } - return(i); + return (i); } int32_t _stlink_usb_version(stlink_t *sl) { @@ -214,7 +214,7 @@ int32_t _stlink_usb_version(stlink_t *sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_REP_LEN, "GET_VERSION"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } int32_t _stlink_usb_target_voltage(stlink_t *sl) { @@ -232,14 +232,14 @@ int32_t _stlink_usb_target_voltage(stlink_t *sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, CMD_CHECK_REP_LEN, "GET_TARGET_VOLTAGE"); if (size < 0) { - return(-1); + return (-1); } factor = (rdata[3] << 24) | (rdata[2] << 16) | (rdata[1] << 8) | (rdata[0] << 0); reading = (rdata[7] << 24) | (rdata[6] << 16) | (rdata[5] << 8) | (rdata[4] << 0); voltage = 2400 * reading / factor; - return(voltage); + return (voltage); } int32_t _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { @@ -256,12 +256,12 @@ int32_t _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, CMD_CHECK_RETRY, "READDEBUGREG"); if (size < 0) { - return(-1); + return (-1); } *data = read_uint32(rdata, 4); - return(0); + return (0); } int32_t _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { @@ -278,11 +278,11 @@ int32_t _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { write_uint32(&cmd[i + 4], data); size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len, CMD_CHECK_RETRY, "WRITEDEBUGREG"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } int32_t _stlink_usb_get_rw_status(stlink_t *sl) { - if (sl->version.jtag_api == STLINK_JTAG_API_V1) { return(0); } + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { return (0); } unsigned char* const rdata = sl->q_buf; struct stlink_libusb * const slu = sl->backend_data; @@ -301,7 +301,7 @@ int32_t _stlink_usb_get_rw_status(stlink_t *sl) { ret = send_recv(slu, 1, cmd, slu->cmd_len, rdata, 2, CMD_CHECK_STATUS, "GETLASTRWSTATUS"); } - return(ret < 0 ? -1 : 0); + return (ret < 0 ? -1 : 0); } int32_t _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { @@ -317,13 +317,13 @@ int32_t _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { write_uint16(&cmd[i + 4], len); ret = send_only(slu, 0, cmd, slu->cmd_len, "WRITEMEM_32BIT"); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } ret = send_only(slu, 1, data, len, "WRITEMEM_32BIT"); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } - return(_stlink_usb_get_rw_status(sl)); + return (_stlink_usb_get_rw_status(sl)); } int32_t _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { @@ -345,13 +345,13 @@ int32_t _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { write_uint16(&cmd[i + 4], len); ret = send_only(slu, 0, cmd, slu->cmd_len, "WRITEMEM_8BIT"); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } ret = send_only(slu, 1, data, len, "WRITEMEM_8BIT"); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } - return(0); + return (0); } int32_t _stlink_usb_current_mode(stlink_t * sl) { @@ -366,10 +366,10 @@ int32_t _stlink_usb_current_mode(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_NO, "GET_CURRENT_MODE"); if (size < 0) { - return(-1); + return (-1); } - return(sl->q_buf[0]); + return (sl->q_buf[0]); } int32_t _stlink_usb_core_id(stlink_t * sl) { @@ -393,12 +393,12 @@ int32_t _stlink_usb_core_id(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "READ_IDCODES"); if (size < 0) { - return(-1); + return (-1); } sl->core_id = read_uint32(data, offset); - return(0); + return (0); } int32_t _stlink_usb_status_v2(stlink_t *sl) { @@ -420,11 +420,11 @@ int32_t _stlink_usb_status_v2(stlink_t *sl) { } } - return(result); + return (result); } int32_t _stlink_usb_status(stlink_t * sl) { - if (sl->version.jtag_api != STLINK_JTAG_API_V1) { return(_stlink_usb_status_v2(sl)); } + if (sl->version.jtag_api != STLINK_JTAG_API_V1) { return (_stlink_usb_status_v2(sl)); } struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; @@ -449,7 +449,7 @@ int32_t _stlink_usb_status(stlink_t * sl) { sl->core_stat = TARGET_UNKNOWN; } - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } int32_t _stlink_usb_force_debug(stlink_t *sl) { @@ -459,7 +459,7 @@ int32_t _stlink_usb_force_debug(stlink_t *sl) { if (sl->version.jtag_api != STLINK_JTAG_API_V1) { res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_DEBUGEN); - return(res); + return (res); } unsigned char* const data = sl->q_buf; @@ -472,7 +472,7 @@ int32_t _stlink_usb_force_debug(stlink_t *sl) { cmd[i++] = STLINK_DEBUG_FORCEDEBUG; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "FORCEDEBUG"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } int32_t _stlink_usb_enter_swd_mode(stlink_t * sl) { @@ -489,7 +489,7 @@ int32_t _stlink_usb_enter_swd_mode(stlink_t * sl) { cmd[i++] = STLINK_DEBUG_ENTER_SWD; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "ENTER_SWD"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } int32_t _stlink_usb_exit_dfu_mode(stlink_t* sl) { @@ -502,7 +502,7 @@ int32_t _stlink_usb_exit_dfu_mode(stlink_t* sl) { cmd[i++] = STLINK_DFU_EXIT; size = send_only(slu, 1, cmd, slu->cmd_len, "DFU_EXIT"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } @@ -525,7 +525,7 @@ int32_t _stlink_usb_reset(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "RESETSYS"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } int32_t _stlink_usb_jtag_reset(stlink_t * sl, int32_t value) { @@ -541,7 +541,7 @@ int32_t _stlink_usb_jtag_reset(stlink_t * sl, int32_t value) { cmd[i++] = value; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "DRIVE_NRST"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } @@ -568,7 +568,7 @@ int32_t _stlink_usb_step(stlink_t* sl) { cmd[i++] = STLINK_DEBUG_STEPCORE; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "STEPCORE"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } /** @@ -584,7 +584,7 @@ int32_t _stlink_usb_run(stlink_t* sl, enum run_type type) { if (sl->version.jtag_api != STLINK_JTAG_API_V1) { res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | ((type==RUN_FLASH_LOADER)?STLINK_REG_DHCSR_C_MASKINTS:0)); - return(res); + return (res); } @@ -598,7 +598,7 @@ int32_t _stlink_usb_run(stlink_t* sl, enum run_type type) { cmd[i++] = STLINK_DEBUG_RUNCORE; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "RUNCORE"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } int32_t _stlink_usb_set_swdclk(stlink_t* sl, int32_t clk_freq) { @@ -641,7 +641,7 @@ int32_t _stlink_usb_set_swdclk(stlink_t* sl, int32_t clk_freq) { cmd[i++] = (clk_divisor >> 8) & 0xFF; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "SWD_SET_FREQ"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } else if (sl->version.stlink_v == 3) { int32_t speed_index; uint32_t map[STLINK_V3_MAX_FREQ_NB]; @@ -653,7 +653,7 @@ int32_t _stlink_usb_set_swdclk(stlink_t* sl, int32_t clk_freq) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, 52, CMD_CHECK_STATUS, "GET_COM_FREQ"); if (size < 0) { - return(-1); + return (-1); } int32_t speeds_size = data[8]; @@ -682,12 +682,12 @@ int32_t _stlink_usb_set_swdclk(stlink_t* sl, int32_t clk_freq) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, 8, CMD_CHECK_STATUS, "SET_COM_FREQ"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } else if (clk_freq) { WLOG("ST-Link firmware does not support frequency setup\n"); } - return(-1); + return (-1); } int32_t _stlink_usb_exit_debug_mode(stlink_t *sl) { @@ -701,7 +701,7 @@ int32_t _stlink_usb_exit_debug_mode(stlink_t *sl) { size = send_only(slu, 1, cmd, slu->cmd_len, "DEBUG_EXIT"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } int32_t _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { @@ -718,13 +718,13 @@ int32_t _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, len, CMD_CHECK_NO, "READMEM_32BIT"); if (size < 0) { - return(-1); + return (-1); } sl->q_len = (int32_t)size; stlink_print_data(sl); - return(0); + return (0); } int32_t _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { @@ -746,7 +746,7 @@ int32_t _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "READALLREGS"); if (size < 0) { - return(-1); + return (-1); } /* V1: regs data from offset 0 */ @@ -763,7 +763,7 @@ int32_t _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { regp->rw = read_uint32(sl->q_buf, reg_offset + 76); regp->rw2 = read_uint32(sl->q_buf, reg_offset + 80); - if (sl->verbose < 2) { return(0); } + if (sl->verbose < 2) { return (0); } DLOG("xpsr = 0x%08x\n", regp->xpsr); DLOG("main_sp = 0x%08x\n", regp->main_sp); @@ -771,7 +771,7 @@ int32_t _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { DLOG("rw = 0x%08x\n", regp->rw); DLOG("rw2 = 0x%08x\n", regp->rw2); - return(0); + return (0); } int32_t _stlink_usb_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp) { @@ -796,7 +796,7 @@ int32_t _stlink_usb_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *reg size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "READREG"); if (size < 0) { - return(-1); + return (-1); } sl->q_len = (int32_t)size; @@ -824,7 +824,7 @@ int32_t _stlink_usb_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *reg regp->r[r_idx] = r; } - return(0); + return (0); } /* See section C1.6 of the ARMv7-M Architecture Reference Manual */ @@ -838,11 +838,11 @@ int32_t _stlink_usb_read_unsupported_reg(stlink_t *sl, int32_t r_idx, struct stl ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } ret = _stlink_usb_read_mem32(sl, STLINK_REG_DCRDR, 4); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } r = read_uint32(sl->q_buf, 0); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); @@ -862,7 +862,7 @@ int32_t _stlink_usb_read_unsupported_reg(stlink_t *sl, int32_t r_idx, struct stl break; } - return(0); + return (0); } int32_t _stlink_usb_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { @@ -870,19 +870,19 @@ int32_t _stlink_usb_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *r ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } ret = _stlink_usb_read_unsupported_reg(sl, 0x21, regp); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } for (int32_t i = 0; i < 32; i++) { ret = _stlink_usb_read_unsupported_reg(sl, 0x40 + i, regp); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } } - return(0); + return (0); } /* See section C1.6 of the ARMv7-M Architecture Reference Manual */ @@ -893,7 +893,7 @@ int32_t _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int32_t r_ /* These are held in the same register */ ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } val = (uint8_t)(val >> 24); @@ -931,14 +931,14 @@ int32_t _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int32_t r_ ret = _stlink_usb_write_mem32(sl, STLINK_REG_DCRDR, 4); - if (ret == -1) { return(ret); } + if (ret == -1) { return (ret); } sl->q_buf[0] = (unsigned char)r_idx; sl->q_buf[1] = 0; sl->q_buf[2] = 0x01; sl->q_buf[3] = 0; - return(_stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4)); + return (_stlink_usb_write_mem32(sl, STLINK_REG_DCRSR, 4)); } int32_t _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int32_t idx) { @@ -961,7 +961,7 @@ int32_t _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int32_t idx) { write_uint32(&cmd[i], reg); size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_RETRY, "WRITEREG"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } int32_t _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { @@ -979,7 +979,7 @@ int32_t _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "START_TRACE_RX"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } int32_t _stlink_usb_disable_trace(stlink_t* sl) { @@ -995,7 +995,7 @@ int32_t _stlink_usb_disable_trace(stlink_t* sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "STOP_TRACE_RX"); - return(size < 0 ? -1 : 0); + return (size < 0 ? -1 : 0); } int32_t _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, uint32_t size) { @@ -1010,10 +1010,10 @@ int32_t _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, uint32_t size) { ssize_t send_size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_NO, "GET_TRACE_NB"); if (send_size < 0) { - return(-1); + return (-1); } else if (send_size != 2) { ELOG("STLINK_DEBUG_APIV2_GET_TRACE_NB reply size %d\n", (int32_t)send_size); - return(-1); + return (-1); } uint16_t trace_count = read_uint16(sl->q_buf, 0); @@ -1029,7 +1029,7 @@ int32_t _stlink_usb_read_trace(stlink_t* sl, uint8_t* buf, uint32_t size) { if (t || res != (int32_t)trace_count) { ELOG("read_trace read error %d\n", t); - return(-1); + return (-1); } } @@ -1282,11 +1282,11 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, _stlink_usb_set_swdclk(sl, freq); stlink_target_connect(sl, connect); - return(sl); + return (sl); on_libusb_error: stlink_close(sl); - return(NULL); + return (NULL); on_error: if (slu->libusb_ctx) { libusb_exit(slu->libusb_ctx); } @@ -1295,7 +1295,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, if (sl != NULL) { free(sl); } if (slu != NULL) { free(slu); } - return(NULL); + return (NULL); } static uint32_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], enum connect_type connect, int32_t freq) { @@ -1329,7 +1329,7 @@ static uint32_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], if (!_sldevs) { *sldevs = NULL; - return(0); + return (0); } /* Open STLINKS and attach them to list */ @@ -1379,7 +1379,7 @@ static uint32_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], *sldevs = _sldevs; - return(slcur); + return (slcur); } size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int32_t freq) { @@ -1392,11 +1392,11 @@ size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int32_t r = libusb_init(NULL); - if (r < 0) { return(0); } + if (r < 0) { return (0); } cnt = libusb_get_device_list(NULL, &devs); - if (cnt < 0) { return(0); } + if (cnt < 0) { return (0); } slcnt = stlink_probe_usb_devs(devs, &sldevs, connect, freq); libusb_free_device_list(devs, 1); @@ -1405,7 +1405,7 @@ size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int32_t *stdevs = sldevs; - return(slcnt); + return (slcnt); } void stlink_probe_usb_free(stlink_t ***stdevs, uint32_t size) { diff --git a/src/win32/getopt/getopt.c b/src/win32/getopt/getopt.c index 417b0aecf..3347da34d 100644 --- a/src/win32/getopt/getopt.c +++ b/src/win32/getopt/getopt.c @@ -118,11 +118,11 @@ int32_t getopt(int32_t argc, char* const argv[], const char* optstring) { if (optcursor == NULL || *++optcursor == '\0') { ++optind; } - return(optchar); + return (optchar); no_more_optchars: optcursor = NULL; - return(-1); + return (-1); } /* Implementation based on http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html */ @@ -141,10 +141,10 @@ int32_t getopt_long(int32_t argc, optarg = NULL; optopt = 0; - if (optind >= argc) { return(-1); } + if (optind >= argc) { return (-1); } if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0) { - return(getopt(argc, argv, optstring)); + return (getopt(argc, argv, optstring)); } // it's an option; starts with -- and is longer than two chars @@ -198,5 +198,5 @@ int32_t getopt_long(int32_t argc, } ++optind; - return(retval); + return (retval); } diff --git a/src/win32/mmap.c b/src/win32/mmap.c index 7e76b3344..8bddb5094 100644 --- a/src/win32/mmap.c +++ b/src/win32/mmap.c @@ -10,30 +10,30 @@ void *mmap (void *addr, uint32_t len, int32_t prot, int32_t flags, int32_t fd, i void *buf; ssize_t count; - if ( addr || fd == -1 || (prot & PROT_WRITE)) { return(MAP_FAILED); } + if ( addr || fd == -1 || (prot & PROT_WRITE)) { return (MAP_FAILED); } buf = malloc(len); - if ( NULL == buf ) { return(MAP_FAILED); } + if ( NULL == buf ) { return (MAP_FAILED); } if (lseek(fd, offset, SEEK_SET) != offset) { free(buf); - return(MAP_FAILED); + return (MAP_FAILED); } count = read(fd, buf, len); if (count != (ssize_t)len) { free (buf); - return(MAP_FAILED); + return (MAP_FAILED); } - return(buf); + return (buf); (void)flags; } int32_t munmap (void *addr, uint32_t len) { free (addr); - return(0); + return (0); (void)len; } diff --git a/src/win32/sys_time.c b/src/win32/sys_time.c index a09d8df67..f1ebd63b9 100644 --- a/src/win32/sys_time.c +++ b/src/win32/sys_time.c @@ -12,7 +12,7 @@ int32_t gettimeofday(struct timeval *tv, struct timezone *tz) { ULARGE_INTEGER ulint; static int32_t tzflag = 0; - if(NULL != tv) { + if (NULL != tv) { GetSystemTimeAsFileTime(&ftime); ulint.LowPart = ftime.dwLowDateTime; ulint.HighPart = ftime.dwHighDateTime; @@ -21,7 +21,7 @@ int32_t gettimeofday(struct timeval *tv, struct timezone *tz) { tv->tv_usec = (int32_t)(ulint.QuadPart % 10000000L); } - if(NULL != tz) { + if (NULL != tz) { if (!tzflag) { _tzset(); tzflag++; diff --git a/src/win32/win32_socket.c b/src/win32/win32_socket.c index 46b4532a7..d3038882b 100644 --- a/src/win32/win32_socket.c +++ b/src/win32/win32_socket.c @@ -68,7 +68,7 @@ int32_t win32_poll(struct pollfd *fds, uint32_t nfds, int32_t timo) { printf("Exiting select rc=%d\n", rc); #endif - if (rc <= 0) { return(rc); } + if (rc <= 0) { return (rc); } if (rc > 0) { for ( i = 0; i < nfds; ++i) { @@ -98,7 +98,7 @@ int32_t win32_poll(struct pollfd *fds, uint32_t nfds, int32_t timo) { } } - return(rc); + return (rc); } static void set_connect_errno(int32_t winsock_err) { @@ -135,7 +135,7 @@ SOCKET win32_socket(int32_t domain, int32_t type, int32_t protocol) { if (fd == INVALID_SOCKET) { set_socket_errno(WSAGetLastError()); } - return(fd); + return (fd); } /* @@ -149,7 +149,7 @@ int32_t win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len) { if (rc == SOCKET_ERROR) { set_connect_errno(WSAGetLastError()); } - return(rc); + return (rc); } /* A wrapper around the accept() function. @@ -164,7 +164,7 @@ SOCKET win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len) { newfd = (SOCKET)-1; } - return(newfd); + return (newfd); } /* A wrapper around the shutdown() function. @@ -177,7 +177,7 @@ int32_t win32_shutdown(SOCKET fd, int32_t mode) { if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } - return(rc); + return (rc); } int32_t win32_close_socket(SOCKET fd) { @@ -185,7 +185,7 @@ int32_t win32_close_socket(SOCKET fd) { if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } - return(rc); + return (rc); } ssize_t win32_write_socket(SOCKET fd, void *buf, int32_t n) { @@ -193,7 +193,7 @@ ssize_t win32_write_socket(SOCKET fd, void *buf, int32_t n) { if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } - return(rc); + return (rc); } ssize_t win32_read_socket(SOCKET fd, void *buf, int32_t n) { @@ -201,7 +201,7 @@ ssize_t win32_read_socket(SOCKET fd, void *buf, int32_t n) { if (rc == SOCKET_ERROR) { set_socket_errno(WSAGetLastError()); } - return(rc); + return (rc); } @@ -244,7 +244,7 @@ char * win32_strtok_r(char *s, const char *delim, char **lasts) { } *lasts = s; - return(tok); + return (tok); } } while (sc != 0); @@ -260,7 +260,7 @@ char *win32_strsep (char **stringp, const char *delim) { char *tok; if ((s = *stringp) == NULL) { - return(NULL); + return (NULL); } for (tok = s; ;) { @@ -276,7 +276,7 @@ char *win32_strsep (char **stringp, const char *delim) { } *stringp = s; - return(tok); + return (tok); } } while (sc != 0); @@ -301,7 +301,7 @@ int32_t usleep(uint32_t waitTime) { WaitForSingleObject(timer, INFINITE); CloseHandle(timer); - return(0); + return (0); } LARGE_INTEGER perf_cnt, start, now; @@ -313,7 +313,7 @@ int32_t usleep(uint32_t waitTime) { QueryPerformanceCounter((LARGE_INTEGER*)&now); } while ((now.QuadPart - start.QuadPart) / (float)perf_cnt.QuadPart * 1000 * 1000 < waitTime); - return(0); + return (0); } #endif diff --git a/tests/flash.c b/tests/flash.c index f4c838d5d..4d9ac5185 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -49,7 +49,7 @@ static bool execute_test(const struct Test * test) { strcpy(cmd_line, test->cmd_line); for (char * tok = strtok(cmd_line, " "); tok; tok = strtok(NULL, " ")) { - if ((size_t)ac >= sizeof(av) / sizeof(av[0])) return(false); + if ((size_t)ac >= sizeof(av) / sizeof(av[0])) return (false); av[ac] = tok; ++ac; @@ -75,7 +75,7 @@ static bool execute_test(const struct Test * test) { } printf("[%s] (%d) %s\n", ret ? "OK" : "ERROR", res, test->cmd_line); - return(ret); + return (ret); } static struct Test tests[] = { diff --git a/tests/sg.c b/tests/sg.c index 6881266ab..67d804b23 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -44,7 +44,7 @@ int32_t main(void) { // main() ripped out of old stlink-hw.c stlink_t *sl = stlink_v1_open(99, 1); - if (sl == NULL) return(0); + if (sl == NULL) return (0); // we are in mass mode, go to swd stlink_enter_swd_mode(sl); @@ -212,5 +212,5 @@ int32_t main(void) { // main() ripped out of old stlink-hw.c // fflush(stderr); // fflush(stdout); - return(EXIT_SUCCESS); + return (EXIT_SUCCESS); } diff --git a/tests/usb.c b/tests/usb.c index 9acd0b02d..5dbb1d83c 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -29,7 +29,7 @@ int32_t main(int32_t ac, char** av) { if (reset == 0) { usage(); - return(0); + return (0); } sl = stlink_open_usb(10, reset, NULL, 0); @@ -125,5 +125,5 @@ int32_t main(int32_t ac, char** av) { stlink_close(sl); } - return(0); + return (0); } From 041517bd4a8caf7dbf17b0c7d8004272cbaefa43 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 25 Jun 2023 15:31:13 +0200 Subject: [PATCH 1389/1435] Fixed flashing on STM32G0/G4 dual bank devices (Closes #1310) --- src/stlink-lib/common_flash.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index f2281ac11..885be9c74 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -307,6 +307,9 @@ int32_t check_flash_error(stlink_t *sl) { case STM32_FLASH_TYPE_G0: case STM32_FLASH_TYPE_G4: res = read_flash_sr(sl, BANK_1) & FLASH_Gx_SR_ERROR_MASK; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + res |= read_flash_sr(sl, BANK_2) & FLASH_Gx_SR_ERROR_MASK; + } WRPERR = (1 << FLASH_Gx_SR_WRPERR); PROGERR = (1 << FLASH_Gx_SR_PROGERR); PGAERR = (1 << FLASH_Gx_SR_PGAERR); @@ -1013,10 +1016,8 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if ((val & (1 << 0)) || (val & (1 << 1))) { // disable pecr protection - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, - FLASH_L0_PEKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, - FLASH_L0_PEKEY2); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY2); // check pecr.pelock is cleared stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -1118,8 +1119,7 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { clear_flash_cr_pg(sl, bank); // clear the pg bit set_flash_cr_per(sl, bank); // set the page erase bit write_flash_ar(sl, flashaddr, bank); // select the page to erase - set_flash_cr_strt(sl, - bank); // start erase operation, reset by hw with busy bit + set_flash_cr_strt(sl, bank); // start erase operation, reset by hw with busy bit wait_flash_busy(sl); clear_flash_cr_per(sl, bank); // clear the page erase bit lock_flash(sl); @@ -1180,7 +1180,7 @@ int32_t stlink_erase_flash_section(stlink_t *sl, stm32_addr_t base_addr, uint32_ int32_t stlink_erase_flash_mass(stlink_t *sl) { int32_t err = 0; - // TODO: User MER bit to mass-erase WB series. + // TODO: Use MER bit to mass-erase WB series. if (sl->flash_type == STM32_FLASH_TYPE_L0_L1 || sl->flash_type == STM32_FLASH_TYPE_WB_WL) { @@ -1193,15 +1193,14 @@ int32_t stlink_erase_flash_mass(stlink_t *sl) { if (sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_id != STM32_CHIPID_H7Ax) { // set parallelism - write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); + write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_1); if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); } } set_flash_cr_mer(sl, 1, BANK_1); // set the mass erase bit - set_flash_cr_strt( - sl, BANK_1); // start erase operation, reset by hw with busy bit + set_flash_cr_strt(sl, BANK_1); // start erase operation, reset by hw with busy bit if (sl->flash_type == STM32_FLASH_TYPE_F1_XL || (sl->flash_type == STM32_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { @@ -1246,8 +1245,7 @@ int32_t stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, stm32_ num_empty -= (num_empty & 3); // Round down to words if (num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, - erased_pattern); + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); } } else { num_empty = 0; @@ -1300,8 +1298,7 @@ int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { num_empty -= (num_empty & 3); // round down to words if (num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, - erased_pattern); + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); } } else { num_empty = 0; From 8fad9be9d0b055069b3f4fcdc3dc17014a6ce9cb Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 25 Jun 2023 15:45:33 +0200 Subject: [PATCH 1390/1435] [refactoring] Clean-up for stlink-lib - Moved declarations for read/write functions to read_write.h . - Checked & revised header includes - Changed some datatypes for write_buffer_to_sram() to avoid explicit casting. --- SECURITY.md | 2 +- inc/stlink.h | 24 +++---------- src/st-trace/trace.c | 1 + src/st-util/gdb-server.c | 1 + src/st-util/semihosting.c | 3 +- src/stlink-gui/gui.c | 1 + src/stlink-lib/calculate.c | 1 + src/stlink-lib/common.c | 11 +++--- src/stlink-lib/common_flash.c | 1 + src/stlink-lib/flash_loader.c | 1 + src/stlink-lib/map_file.c | 2 ++ src/stlink-lib/option_bytes.c | 1 + src/stlink-lib/read_write.c | 67 +++++++++++++++++++---------------- src/stlink-lib/read_write.h | 27 ++++++++++++++ src/stlink-lib/sg.c | 1 + src/stlink-lib/usb.c | 1 + tests/sg.c | 1 + tests/usb.c | 1 + 18 files changed, 90 insertions(+), 57 deletions(-) create mode 100644 src/stlink-lib/read_write.h diff --git a/SECURITY.md b/SECURITY.md index 9ace47066..054641822 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -7,7 +7,7 @@ The following versions of the stlink toolset are currently being supported.
      #include +#include #include #include diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 8a187fb24..d001395e9 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/src/st-util/semihosting.c b/src/st-util/semihosting.c index a200a7408..8e9828ce8 100644 --- a/src/st-util/semihosting.c +++ b/src/st-util/semihosting.c @@ -8,9 +8,10 @@ #include #include +#include "semihosting.h" #include -#include "semihosting.h" +#include static int32_t mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) { int32_t offset = addr % 4; diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index 4b312c8a1..e3eec34b8 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -9,6 +9,7 @@ #include #include +#include #include #define MEM_READ_SIZE 1024 diff --git a/src/stlink-lib/calculate.c b/src/stlink-lib/calculate.c index 027239694..a7344e0b0 100644 --- a/src/stlink-lib/calculate.c +++ b/src/stlink-lib/calculate.c @@ -10,6 +10,7 @@ #include "calculate.h" #include "common_flash.h" +#include "read_write.h" uint32_t calculate_F4_sectornum(uint32_t flashaddr) { uint32_t offset = 0; diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index 70ecdd3a2..dbfcc8b9e 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -25,6 +25,7 @@ #include "logging.h" #include "map_file.h" #include "md5.h" +#include "read_write.h" #include "register.h" #include "usb.h" @@ -808,20 +809,20 @@ int32_t stlink_fread(stlink_t *sl, const char *path, bool is_ihex, stm32_addr_t } // 300 -int32_t write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, uint32_t size) { +int32_t write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, uint16_t size) { // write the buffer right after the loader int32_t ret = 0; - uint32_t chunk = size & ~0x3; - uint32_t rem = size & 0x3; + uint16_t chunk = size & ~0x3; + uint16_t rem = size & 0x3; if (chunk) { memcpy(sl->q_buf, buf, chunk); - ret = stlink_write_mem32(sl, fl->buf_addr, (uint16_t)chunk); + ret = stlink_write_mem32(sl, fl->buf_addr, chunk); } if (rem && !ret) { memcpy(sl->q_buf, buf + chunk, rem); - ret = stlink_write_mem8(sl, (fl->buf_addr) + chunk, (uint16_t)rem); + ret = stlink_write_mem8(sl, (fl->buf_addr) + chunk, rem); } return (ret); diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 885be9c74..3038b53e7 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -18,6 +18,7 @@ #include "logging.h" #include "map_file.h" #include "md5.h" +#include "read_write.h" #define DEBUG_FLASH 0 diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 0f12c3131..e1e9e9995 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -16,6 +16,7 @@ #include "common_flash.h" #include "helper.h" #include "logging.h" +#include "read_write.h" #include "register.h" #define FLASH_REGS_BANK2_OFS 0x40 diff --git a/src/stlink-lib/map_file.c b/src/stlink-lib/map_file.c index e8c4b71a3..118c80d34 100644 --- a/src/stlink-lib/map_file.c +++ b/src/stlink-lib/map_file.c @@ -15,6 +15,8 @@ #include #include "map_file.h" +#include "read_write.h" + #ifndef O_BINARY #define O_BINARY 0 #endif diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c index c84ace348..ee03dced9 100644 --- a/src/stlink-lib/option_bytes.c +++ b/src/stlink-lib/option_bytes.c @@ -16,6 +16,7 @@ #include "logging.h" #include "map_file.h" #include "md5.h" +#include "read_write.h" /** * Read option control register F0 diff --git a/src/stlink-lib/read_write.c b/src/stlink-lib/read_write.c index 9149080af..4e43d8aa5 100644 --- a/src/stlink-lib/read_write.c +++ b/src/stlink-lib/read_write.c @@ -1,8 +1,15 @@ +/* + * File: read_write.c + * + * Read and write operations + */ + #include #include #include #include +#include "read_write.h" #include "logging.h" @@ -10,11 +17,8 @@ // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html // These functions encode and decode little endian uint16 and uint32 values. -void write_uint32(unsigned char *buf, uint32_t ui) { - buf[0] = ui; - buf[1] = ui >> 8; - buf[2] = ui >> 16; - buf[3] = ui >> 24; +uint16_t read_uint16(const unsigned char *c, const int32_t pt) { + return ((uint16_t)c[pt]) | ((uint16_t)c[pt + 1] << 8); } void write_uint16(unsigned char *buf, uint16_t ui) { @@ -27,8 +31,11 @@ uint32_t read_uint32(const unsigned char *c, const int32_t pt) { ((uint32_t)c[pt + 2] << 16) | ((uint32_t)c[pt + 3] << 24); } -uint16_t read_uint16(const unsigned char *c, const int32_t pt) { - return ((uint16_t)c[pt]) | ((uint16_t)c[pt + 1] << 8); +void write_uint32(unsigned char *buf, uint32_t ui) { + buf[0] = ui; + buf[1] = ui >> 8; + buf[2] = ui >> 16; + buf[3] = ui >> 24; } int32_t stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { @@ -46,26 +53,26 @@ int32_t stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { return sl->backend->write_debug32(sl, addr, data); } -int32_t stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); +int32_t stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { + DLOG("*** stlink_read_mem32 ***\n"); - if (len % 4 != 0) { + if (len % 4 != 0) { // !!! never ever: fw gives just wrong values ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); return (-1); } - return (sl->backend->write_mem32(sl, addr, len)); + return (sl->backend->read_mem32(sl, addr, len)); } -int32_t stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_read_mem32 ***\n"); +int32_t stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { + DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); - if (len % 4 != 0) { // !!! never ever: fw gives just wrong values + if (len % 4 != 0) { ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); return (-1); } - return (sl->backend->read_mem32(sl, addr, len)); + return (sl->backend->write_mem32(sl, addr, len)); } int32_t stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { @@ -73,21 +80,6 @@ int32_t stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { return (sl->backend->write_mem8(sl, addr, len)); } -int32_t stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { - DLOG("*** stlink_read_all_regs ***\n"); - return (sl->backend->read_all_regs(sl, regp)); -} - -int32_t stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { - DLOG("*** stlink_read_all_unsupported_regs ***\n"); - return (sl->backend->read_all_unsupported_regs(sl, regp)); -} - -int32_t stlink_write_reg(stlink_t *sl, uint32_t reg, int32_t idx) { - DLOG("*** stlink_write_reg\n"); - return (sl->backend->write_reg(sl, reg, idx)); -} - int32_t stlink_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp) { DLOG("*** stlink_read_reg\n"); DLOG(" (%d) ***\n", r_idx); @@ -100,6 +92,11 @@ int32_t stlink_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp) { return (sl->backend->read_reg(sl, r_idx, regp)); } +int32_t stlink_write_reg(stlink_t *sl, uint32_t reg, int32_t idx) { + DLOG("*** stlink_write_reg\n"); + return (sl->backend->write_reg(sl, reg, idx)); +} + int32_t stlink_read_unsupported_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp) { int32_t r_convert; @@ -145,3 +142,13 @@ int32_t stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int32_t r_idx, return (sl->backend->write_unsupported_reg(sl, val, r_convert, regp)); } + +int32_t stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { + DLOG("*** stlink_read_all_regs ***\n"); + return (sl->backend->read_all_regs(sl, regp)); +} + +int32_t stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { + DLOG("*** stlink_read_all_unsupported_regs ***\n"); + return (sl->backend->read_all_unsupported_regs(sl, regp)); +} diff --git a/src/stlink-lib/read_write.h b/src/stlink-lib/read_write.h new file mode 100644 index 000000000..b9ca082c8 --- /dev/null +++ b/src/stlink-lib/read_write.h @@ -0,0 +1,27 @@ +/* + * File: read_write.h + * + * Read and write operations + */ + +#ifndef READ_WRITE_H +#define READ_WRITE_H + +uint16_t read_uint16(const unsigned char *c, const int32_t pt); +void write_uint16(unsigned char *buf, uint16_t ui); +uint32_t read_uint32(const unsigned char *c, const int32_t pt); +void write_uint32(unsigned char *buf, uint32_t ui); + +int32_t stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); +int32_t stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); +int32_t stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int32_t stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int32_t stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); +int32_t stlink_read_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp); +int32_t stlink_write_reg(stlink_t *sl, uint32_t reg, int32_t idx); +int32_t stlink_read_unsupported_reg(stlink_t *sl, int32_t r_idx, struct stlink_reg *regp); +int32_t stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int32_t r_idx, struct stlink_reg *regp); +int32_t stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp); +int32_t stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); + +#endif // READ_WRITE_H diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index b744389ba..d9bd8ab6a 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -95,6 +95,7 @@ #include "commands.h" #include "logging.h" +#include "read_write.h" #include "register.h" #include "usb.h" // #include // TODO: Check use diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 0934fe368..30134e161 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -27,6 +27,7 @@ #include "commands.h" #include "logging.h" +#include "read_write.h" #include "register.h" static inline uint32_t le_to_h_u32(const uint8_t* buf) { diff --git a/tests/sg.c b/tests/sg.c index 67d804b23..1284bb15b 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -8,6 +8,7 @@ #include #include +#include #include #if defined(_MSC_VER) diff --git a/tests/usb.c b/tests/usb.c index 5dbb1d83c..f8b60c306 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -6,6 +6,7 @@ #include +#include #include #include From 2f27e8ec98db7dcba9437aae3c6e33e90ca3b674 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 27 Jun 2023 08:24:09 +0200 Subject: [PATCH 1391/1435] Fixed chip recovery after reset (Closes #1260) --- src/st-flash/flash.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index ba6d1f4bb..0577ee179 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -287,10 +287,9 @@ int32_t main(int32_t ac, char** av) { } } - if (o.reset) { - stlink_reset(sl, RESET_AUTO); - stlink_run(sl, RUN_NORMAL); - } + if (o.reset) stlink_reset(sl, RESET_AUTO); + + stlink_run(sl, RUN_NORMAL); err = 0; // success From 457d971a40e8882765baaea1fa4015489825b09f Mon Sep 17 00:00:00 2001 From: Meo Date: Mon, 3 Jul 2023 09:59:26 +0800 Subject: [PATCH 1392/1435] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d188f0df..80d39a28a 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ We recommend to install `stlink-tools` from the package repository of the used d - Debian Linux: [(Link)](https://github.com/stlink-org/stlink/releases) - Ubuntu Linux: [(Link)](https://github.com/stlink-org/stlink/releases) -- Arch Linux: [(Link)](https://www.archlinux.org/packages/community/x86_64/stlink) +- Arch Linux: [(Link)](https://archlinux.org/packages/extra/x86_64/stlink/) - Alpine Linux: [(Link)](https://pkgs.alpinelinux.org/packages?name=stlink) - Fedora: [(Link)](https://src.fedoraproject.org/rpms/stlink) - FreeBSD: Users can install from [freshports](https://www.freshports.org/devel/stlink) From 682ec389b720f164c42aafe1b0d7614abc29a12f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 9 Jul 2023 00:38:49 +0200 Subject: [PATCH 1393/1435] [doc] Corrected compiling manual (Closes #1317) --- doc/compiling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/compiling.md b/doc/compiling.md index 775d2363e..45cf38aa1 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -125,7 +125,7 @@ or execute (Debian-based systems only): `apt-get install gcc build-essential cma 4. Run `make install` to full install the package with complete system integration. This might require sudo permissions. 5. Run `make debug` to create the _Debug_ target (_optional_)
      The debug target is only necessary in order to modify the sources and to run under a debugger. -6. Run `make package`to build a Debian Package. The generated packages can be found in the subdirectory `./build/dist`. +6. Run `make package`to build a Debian Package. The generated packages can be found in the subdirectory `./build/Release/dist`. As an option you may also install to an individual user-defined folder e.g `$HOME` with `make install DESTDIR=$HOME`. From 4b69bdd3e95f7077991d198550aaa76405e54ce4 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Tue, 15 Aug 2023 10:44:18 +0200 Subject: [PATCH 1394/1435] CMake: Avoid hard-wired /usr/local/share Instead of defining own CMAKE_INSTALL_SHAREDIR, use existing CMAKE_INSTALL_FULL_DATADIR. This way, CMAKE_INSTALL_PREFIX is respected. --- CMakeLists.txt | 5 +---- src/stlink-gui/CMakeLists.txt | 8 ++++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e7d92705..31825945f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,9 +78,6 @@ include(GNUInstallDirs) # Define GNU standard installation directories cmake_host_system_information(RESULT OS_NAME QUERY OS_NAME) message(STATUS "Checking for OS_NAME: ${OS_NAME}") -message(STATUS "set(CMAKE_INSTALL_SHAREDIR /usr/local/share)") -set(CMAKE_INSTALL_SHAREDIR /usr/local/share/) - ## Set C build flags if (NOT MSVC) @@ -385,7 +382,7 @@ endif () if (WIN32) set(CMAKE_CHIPS_DIR ${CMAKE_INSTALL_PREFIX}/config/chips) else () -set(CMAKE_CHIPS_DIR ${CMAKE_INSTALL_SHAREDIR}/${PROJECT_NAME}/chips) +set(CMAKE_CHIPS_DIR ${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/chips) endif () add_definitions( -DSTLINK_CHIPS_DIR="${CMAKE_CHIPS_DIR}" ) file(GLOB CHIP_FILES ${CMAKE_SOURCE_DIR}/config/chips/*.chip) diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index fb4478bdc..f9b6c3fb9 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -16,19 +16,19 @@ if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) # Install desktop application entry install(FILES stlink-gui.desktop - DESTINATION ${CMAKE_INSTALL_SHAREDIR}/applications) + DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/applications) # Install icons install(FILES icons/stlink-gui.svg - DESTINATION ${CMAKE_INSTALL_SHAREDIR}/icons/hicolor/scalable/apps) + DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/scalable/apps) set(GUI_SOURCES gui.c gui.h) ## stlink-gui add_executable(stlink-gui ${GUI_SOURCES}) - install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_SHAREDIR}/${PROJECT_NAME}) + install(FILES stlink-gui.ui DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}) set_target_properties(stlink-gui PROPERTIES - COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_SHAREDIR}/${PROJECT_NAME}") + COMPILE_DEFINITIONS STLINK_UI_DIR="${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}") target_link_libraries(stlink-gui ${STLINK_LIB_SHARED} ${SSP_LIB} ${GTK3_LDFLAGS}) install(TARGETS stlink-gui DESTINATION ${CMAKE_BINDIR}) endif () From 270efb3535a968ec639dfe5d20bb69462ab71fd6 Mon Sep 17 00:00:00 2001 From: ArmoredPony Date: Wed, 16 Aug 2023 18:05:37 +0400 Subject: [PATCH 1395/1435] fixed unknown option -u --- src/st-util/gdb-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 9f9d93844..629eb4c6f 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -149,7 +149,7 @@ int32_t parse_options(int32_t argc, char** argv, st_state_t *st) { int32_t c; int32_t q; - while ((c = getopt_long(argc, argv, "hv::p:mn", long_options, &option_index)) != -1) + while ((c = getopt_long(argc, argv, "hv::p:mnu", long_options, &option_index)) != -1) switch (c) { case 0: break; From 2e6cf7d806cf8ec0a88c88119e5d69bf4f67e564 Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 27 Aug 2023 01:45:57 -0700 Subject: [PATCH 1396/1435] Fix use of uninitialized flash_loader_t in stm32l1_write_half_pages stm32l1_write_half_pages uses a local flash_loader_t that is never initialized. This results in stlink_flash_loader_run using uninitialized values for fl->buf_addr and fl->loader_addr when copying the buffer and initializing the source register and PC before running the core to execute the flashloader. Pass the flash_loader_t from stlink_flashloader_write through to stm32l1_write_half_pages and use that one instead of an uninitialized local structure. --- src/stlink-lib/flash_loader.c | 7 +++---- src/stlink-lib/flash_loader.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 0ab8cf6c1..94a0dc41f 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -428,12 +428,11 @@ int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t t #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 -int32_t stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint32_t pagesize) { +int32_t stm32l1_write_half_pages(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint32_t pagesize) { uint32_t count, off; uint32_t num_half_pages = len / pagesize; uint32_t val; uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - flash_loader_t fl; bool use_loader = true; int32_t ret = 0; @@ -448,7 +447,7 @@ int32_t stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, for (count = 0; count < num_half_pages; count++) { if (use_loader) { - ret = stlink_flash_loader_run(sl, &fl, addr + count * pagesize, base + count * pagesize, pagesize); + ret = stlink_flash_loader_run(sl, fl, addr + count * pagesize, base + count * pagesize, pagesize); if (ret && count == 0) { /* It seems that stm32lx devices have a problem when it is blank */ WLOG("Failed to use flash loader, fallback to soft write\n"); @@ -770,7 +769,7 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t off = 0; if (len > pagesize) { - if (stm32l1_write_half_pages(sl, addr, base, len, pagesize)) { + if (stm32l1_write_half_pages(sl, fl, addr, base, len, pagesize)) { return (-1); } else { off = (size_t)(len / pagesize) * pagesize; diff --git a/src/stlink-lib/flash_loader.h b/src/stlink-lib/flash_loader.h index 33edc7ac6..6ac2e4f80 100644 --- a/src/stlink-lib/flash_loader.h +++ b/src/stlink-lib/flash_loader.h @@ -18,7 +18,7 @@ int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t t /* === Functions from old header file flashloader.h === */ -int32_t stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint32_t pagesize); +int32_t stm32l1_write_half_pages(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint32_t pagesize); // static void set_flash_cr_pg(stlink_t *sl, uint32_t bank); // static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int32_t bckpRstr); int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); From 1861b8dc9f7e70f4034bddabfe3b1e112dcd483f Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 27 Aug 2023 11:01:45 -0700 Subject: [PATCH 1397/1435] Fix stm32lx flash loader on STM32L0 STM32L0 chips use loader_code_stm32lx, but this flash loader is built for armv7-m and uses instructions that are unsupported on STM32L0 (which have Cortex M0+ cores implementing armv6-m). In particular, loader_code_stm32lx uses variants of add-immediate that do not update the condition flags ( `add r0, r0, #4` ). These are 32bit instructions in armv7-m and are not available in armv6-m. Enable loader_code_stm32lx to run on both armv6-m and armv7-m by building for armv6-m, which requires changing the `add` instructions to `adds` instructions that do update condition flags (which is ok because the subs updates the condition flags again before the branch). --- flashloaders/Makefile | 5 +++++ flashloaders/stm32lx.s | 4 ++-- src/stlink-lib/flash_loader.c | 8 ++++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/flashloaders/Makefile b/flashloaders/Makefile index 68ce5a881..73080c644 100644 --- a/flashloaders/Makefile +++ b/flashloaders/Makefile @@ -30,6 +30,11 @@ stm32f0.o: stm32f0.s stm32vl.o: stm32f0.s $(CC) stm32f0.s $(CFLAGS_ARMV7_M) -o stm32vl.o +# separate rule for STM32Lx. +# Built for ARMv6-M target to be compatible with both Cortex M0 and Cortex M3. +stm32lx.o: stm32lx.s + $(CC) stm32lx.s $(CFLAGS_ARMV6_M) -o stm32lx.o + # generic rule for all other ARMv7-M %.o: %.s $(CC) $< $(CFLAGS_ARMV7_M) -o $@ diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index 69acdea7b..263f1f829 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -17,8 +17,8 @@ loop: str r4, [r1] # increment address - add r0, r0, #4 - add r1, r1, #4 + adds r0, r0, #4 + adds r1, r1, #4 # loop if count > 0 subs r2, r2, #4 diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 94a0dc41f..040a7ab09 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -68,12 +68,12 @@ static const uint8_t loader_code_stm32f0[] = { 0x14, 0x00, 0x00, 0x00 }; -// flashloaders/stm32lx.s +// flashloaders/stm32lx.s -- compiled for armv6-m for compatibility with both +// armv6-m cores (STM32L0) and armv7-m cores (STM32L1) static const uint8_t loader_code_stm32lx[] = { 0x04, 0x68, 0x0c, 0x60, - 0x00, 0xf1, 0x04, 0x00, - 0x01, 0xf1, 0x04, 0x01, - 0x04, 0x3a, 0xf7, 0xdc, + 0x04, 0x30, 0x04, 0x31, + 0x04, 0x3a, 0xf9, 0xdc, 0x00, 0xbe, 0x00, 0x00 }; From 7475ec7f30edcff72b7c38cc221b29aaefe93220 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 2 Sep 2023 17:18:09 +0200 Subject: [PATCH 1398/1435] General Project Update - Updated CHANGELOG.md - Updated README.md - Minor fixes & updates in documentation. --- CHANGELOG.md | 9 ++- README.md | 7 ++- SECURITY.md | 2 +- doc/compiling.md | 2 + flashloaders/cleanroom.md | 125 ++------------------------------------ 5 files changed, 22 insertions(+), 123 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c930999cd..9b6cccdf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ Updates & changes: - [refactoring] General maintenance for code structure ([#903](https://github.com/stlink-org/stlink/pull/903), [#1090](https://github.com/stlink-org/stlink/pull/1090), [#1199](https://github.com/stlink-org/stlink/pull/1199), [#1212](https://github.com/stlink-org/stlink/pull/1212), [#1216](https://github.com/stlink-org/stlink/pull/1216), [#1228](https://github.com/stlink-org/stlink/pull/1228)) - Added instructions for bug-reports and feature-requests to contribution guidelines ([#906](https://github.com/stlink-org/stlink/pull/906)) - Added travis CI configuration for macOS 10.14 to maintain capability for 32-bit compilation (commit [#f5ada94](https://github.com/stlink-org/stlink/commit/f5ada9474cdb87ff37de0d4eb9e75622b5870646)) +- [refactoring] Clean code with unified variable type ([#909](https://github.com/stlink-org/stlink/pull/909), commit [#5e85fd0](https://github.com/stlink-org/stlink/commit/5e85fd063908f89499180c28fe5e9ba74868b272)) - Updated description of chip id 0x0457 to L01x/L02x ([#1143](https://github.com/stlink-org/stlink/pull/1143), [#1144](https://github.com/stlink-org/stlink/pull/1144)) - [doc] Human-readable flash_type in chip-id files ([#1155](https://github.com/stlink-org/stlink/pull/1155), commit [#1745bf5](https://github.com/stlink-org/stlink/commit/1745bf5193c4d3186d4f6fde59cc86e9bad6e61b)) - Dropped execute bits from source code files ([#1167](https://github.com/stlink-org/stlink/pull/1167)) @@ -51,9 +52,13 @@ Updates & changes: - [doc] Linux Install from code Documentation improvement ([#1263](https://github.com/stlink-org/stlink/pull/1263), commit [#43498de](https://github.com/stlink-org/stlink/commit/43498dedf651260ef34197e512d35e3ad7142401)) - End of support for macOS ([#1269](https://github.com/stlink-org/stlink/pull/1269), [#1296](https://github.com/stlink-org/stlink/pull/1296), commit [#61ff09e](https://github.com/stlink-org/stlink/commit/61ff09e5274d46a46ae58bc4ffe44fe90a887ea6)) - [doc] Added device ID for GD32F303VET6 ([#1288](https://github.com/stlink-org/stlink/pull/1288)) +- [doc] Fixed broken links ([#1312](https://github.com/stlink-org/stlink/pull/1312)) +- [doc] Updated package source link for Arch Linux ([#1318](https://github.com/stlink-org/stlink/pull/1318)) +- CMake: Avoid hard-wired /usr/local/share ([#1325](https://github.com/stlink-org/stlink/pull/1325)) Fixes: +- Fixed some flashing issues on STM32L0 ([#681](https://github.com/stlink-org/stlink/pull/681), [#1203](https://github.com/stlink-org/stlink/pull/1203), [#1225](https://github.com/stlink-org/stlink/pull/1225), [#1253](https://github.com/stlink-org/stlink/pull/1253), [#1289](https://github.com/stlink-org/stlink/pull/1289), [#1330](https://github.com/stlink-org/stlink/pull/1330)) - cmake: Install shared libraries in proper directories ([#1098](https://github.com/stlink-org/stlink/pull/1098), [#1138](https://github.com/stlink-org/stlink/pull/1138), [#1154](https://github.com/stlink-org/stlink/pull/1154)) - cmake: Install shared libraries in proper directories ([#1142](https://github.com/stlink-org/stlink/pull/1142)) - Fixed clearance of the H7 dual bank flag ([#1146](https://github.com/stlink-org/stlink/pull/1146), [#1147](https://github.com/stlink-org/stlink/pull/1147)) @@ -84,9 +89,11 @@ Fixes: - Fixed st-trace reconnect on Windows ([#1272](https://github.com/stlink-org/stlink/pull/1272), [#1292](https://github.com/stlink-org/stlink/pull/1292)) - [compilation] Corrected path to stlink/chips subdirectory ([#1276](https://github.com/stlink-org/stlink/pull/1276), [#1279](https://github.com/stlink-org/stlink/pull/1279)) - [compilation] Fixed GUI compilation failure on OpenBSD i386 ([#1284](https://github.com/stlink-org/stlink/pull/1284)) +- [STM32U5x5]: Last bytes are not written (flashed) when len()%16 <= 8 ([#1303](https://github.com/stlink-org/stlink/pull/1303), [#1315](https://github.com/stlink-org/stlink/pull/1315)) - Fixed unbounded write and check return values of sscanf ([#1306](https://github.com/stlink-org/stlink/pull/1306)) - Added null check for return value of stlink_chipid_get_params() ([#1307](https://github.com/stlink-org/stlink/pull/1307)) - Fixed warning in a few *.cmake files ([#1309](https://github.com/stlink-org/stlink/pull/1309)) +- Notification "unknown option -- u" in tool st-util ([#1326](https://github.com/stlink-org/stlink/pull/1326), [#1327](https://github.com/stlink-org/stlink/pull/1327)) # v1.7.0 @@ -98,7 +105,7 @@ Features: - Extended set of cmd line arguments for st-info and st-util ([#332](https://github.com/stlink-org/stlink/pull/332), [#990](https://github.com/stlink-org/stlink/pull/990), [#1091](https://github.com/stlink-org/stlink/pull/1091), [#1114](https://github.com/stlink-org/stlink/pull/1114)) - Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#801](https://github.com/stlink-org/stlink/pull/801), [#868](https://github.com/stlink-org/stlink/pull/868), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) -- Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052), [#1184](https://github.com/stlink-org/stlink/pull/1184)) +- Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052), [#1184](https://github.com/stlink-org/stlink/pull/1184), [#1324](https://github.com/stlink-org/stlink/pull/1324)) - Official support for STLINK-V3 programmers (commit [#5e0a502](https://github.com/stlink-org/stlink/commit/5e0a502df812495bfa96fa9116a19f1306152b17), [#820](https://github.com/stlink-org/stlink/pull/820), [#1022](https://github.com/stlink-org/stlink/pull/1022), [#1025](https://github.com/stlink-org/stlink/pull/1025)) - Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) - Option bytes on the STM32F767 ZIT6 Nucleo-144 ([#968](https://github.com/stlink-org/stlink/pull/968), [#997](https://github.com/stlink-org/stlink/pull/997)) diff --git a/README.md b/README.md index 6d188f0df..05f87658d 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,12 @@ We recommend to install `stlink-tools` from the package repository of the used d - Alpine Linux: [(Link)](https://pkgs.alpinelinux.org/packages?name=stlink) - Fedora: [(Link)](https://src.fedoraproject.org/rpms/stlink) - FreeBSD: Users can install from [freshports](https://www.freshports.org/devel/stlink) -- MacOS: **Support for macOS will end with v1.8.0.** Please use v1.7.0 (current ***master*** branch) and the related documentation instead. + +**macOS**: + +**Support for macOS will be dropped with v1.8.0.** + +Please use v1.7.0 instead, **but note that this version is no longer maintained and supported!** ## Installation from source (advanced users) diff --git a/SECURITY.md b/SECURITY.md index 054641822..13432b927 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -7,7 +7,7 @@ The following versions of the stlink toolset are currently being supported.
      Date: Mon, 4 Sep 2023 16:21:55 +0200 Subject: [PATCH 1399/1435] Prefix all CDB bytes with 0x, including zeros --- src/stlink-lib/sg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index d7f844b51..c0e43547b 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -171,7 +171,7 @@ static int32_t dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) { dbugp += sprintf(dbugp, "Sending CDB ["); for (uint8_t i = 0; i < cdb_len; i++) { - dbugp += sprintf(dbugp, " %#02x", (uint32_t)cdb[i]); + dbugp += sprintf(dbugp, " 0x%02x", (uint32_t)cdb[i]); } sprintf(dbugp, "]\n"); From a0c02161085401ecfce3dfcfd9c7ee63931a6b05 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 14 Sep 2023 11:35:35 +0200 Subject: [PATCH 1400/1435] Updated behaviour on Reset Fixes an issue where early breakpoints did not trigger. (Closes #1198) (Closes #1246) (Closes #1319) --- src/st-util/gdb-server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index a0bc3f0a1..71f24fb60 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -1318,7 +1318,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) { reply = strdup("E00"); } - ret = stlink_reset(sl, RESET_AUTO); + ret = stlink_reset(sl, RESET_SOFT_AND_HALT); if (ret) { DLOG("Rcmd: reset failed with reset\n"); reply = strdup("E00"); @@ -1835,7 +1835,7 @@ int32_t serve(stlink_t *sl, st_state_t *st) { case 'R': { // reset the core. - ret = stlink_reset(sl, RESET_AUTO); + ret = stlink_reset(sl, RESET_SOFT_AND_HALT); if (ret) { DLOG("R packet : stlink_reset failed\n"); } init_code_breakpoints(sl); From df7c7d21728f9804225c04912b45e34578b0d9ca Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 11 Oct 2023 19:55:50 -0400 Subject: [PATCH 1401/1435] Add CodeQL Workflow for Code Security Analysis Add CodeQL Workflow for Code Security Analysis This pull request introduces a CodeQL workflow to enhance the security analysis of our repository. CodeQL is a powerful static analysis tool that helps identify and mitigate security vulnerabilities in our codebase. By integrating this workflow into our GitHub Actions, we can proactively identify and address potential issues before they become security threats. We added a new CodeQL workflow file (.github/workflows/codeql.yml) that - Runs on every push and pull request to the main branch. - Excludes queries with a high false positive rate or low-severity findings. - Does not display results for third-party code, focusing only on our own codebase. Testing: To validate the functionality of this workflow, we have run several test scans on the codebase and reviewed the results. The workflow successfully compiles the project, identifies issues, and provides actionable insights while reducing noise by excluding certain queries and third-party code. Deployment: Once this pull request is merged, the CodeQL workflow will be active and automatically run on every push and pull request to the main branch. To view the results of these code scans, please follow these steps: 1. Under the repository name, click on the Security tab. 2. In the left sidebar, click Code scanning alerts. Additional Information: - You can further customize the workflow to adapt to your specific needs by modifying the workflow file. - For more information on CodeQL and how to interpret its results, refer to the GitHub documentation and the CodeQL documentation. Signed-off-by: Brian --- .github/workflows/codeql-buildscript.sh | 6 ++ .github/workflows/codeql.yml | 123 ++++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 .github/workflows/codeql-buildscript.sh create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql-buildscript.sh b/.github/workflows/codeql-buildscript.sh new file mode 100644 index 000000000..d626d4283 --- /dev/null +++ b/.github/workflows/codeql-buildscript.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +sudo apt-get -y update +sudo apt-get -y install libusb-1.0 libusb-1.0-0-dev libgtk-3-dev +make clean +make release -j$(nproc) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000..eaa9599bd --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,123 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ "main", "master" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "main", "master" ] + schedule: + - cron: '28 21 * * 0' + +jobs: + analyze: + name: Analyze + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners + # Consider using larger runners for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-20.04' }} + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'cpp' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ] + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + queries: security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). + # If this step fails, then you should remove it and run the build manually (see below) + #- name: Autobuild + # uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + - run: | + ./.github/workflows/codeql-buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" + upload: false + id: step1 + + # Filter out rules with low severity or high false positve rate + # Also filter out warnings in third-party code + - name: Filter out unwanted errors and warnings + uses: advanced-security/filter-sarif@v1 + with: + patterns: | + -**:cpp/path-injection + -**:cpp/world-writable-file-creation + -**:cpp/poorly-documented-function + -**:cpp/potentially-dangerous-function + -**:cpp/use-of-goto + -**:cpp/integer-multiplication-cast-to-long + -**:cpp/comparison-with-wider-type + -**:cpp/leap-year/* + -**:cpp/ambiguously-signed-bit-field + -**:cpp/suspicious-pointer-scaling + -**:cpp/suspicious-pointer-scaling-void + -**:cpp/unsigned-comparison-zero + -**/third*party/** + -**/3rd*party/** + -**/external/** + input: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif + output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif + + - name: Upload SARIF + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: ${{ steps.step1.outputs.sarif-output }} + category: "/language:${{matrix.language}}" + + - name: Archive CodeQL results + uses: actions/upload-artifact@v3 + with: + name: codeql-results + path: ${{ steps.step1.outputs.sarif-output }} + retention-days: 5 \ No newline at end of file From 3387ca5b425072b06c95831665ab9c9a63caf811 Mon Sep 17 00:00:00 2001 From: Daniele Cattaneo Date: Sat, 14 Oct 2023 17:48:17 +0200 Subject: [PATCH 1402/1435] Do not crash when the STLink chip returns a voltage factor of zero. --- src/stlink-lib/usb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 30134e161..d3a57c33f 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -238,7 +238,13 @@ int32_t _stlink_usb_target_voltage(stlink_t *sl) { factor = (rdata[3] << 24) | (rdata[2] << 16) | (rdata[1] << 8) | (rdata[0] << 0); reading = (rdata[7] << 24) | (rdata[6] << 16) | (rdata[5] << 8) | (rdata[4] << 0); - voltage = 2400 * reading / factor; + DLOG("target voltage factor=%08x reading=%08x\n", factor, reading); + if (factor != 0 && reading != 0) { + voltage = 2400 * reading / factor; + } else { + DLOG("voltage reading failed at device side, bad STLink chip?\n"); + voltage = 0; + } return (voltage); } From ed8fa62d098ad52bafc78507146899b5738f01d8 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 18 Oct 2023 16:49:46 -0400 Subject: [PATCH 1403/1435] Add CodeQL Workflow for Code Security Analysis Add CodeQL Workflow for Code Security Analysis This pull request introduces a CodeQL workflow to enhance the security analysis of our repository. CodeQL is a powerful static analysis tool that helps identify and mitigate security vulnerabilities in our codebase. By integrating this workflow into our GitHub Actions, we can proactively identify and address potential issues before they become security threats. We added a new CodeQL workflow file (.github/workflows/codeql.yml) that - Runs on every pull request (functionality to run on every push to main branches is included as a comment for convenience). - Runs daily. - Excludes queries with a high false positive rate or low-severity findings. - Does not display results for git submodules, focusing only on our own codebase. Testing: To validate the functionality of this workflow, we have run several test scans on the codebase and reviewed the results. The workflow successfully compiles the project, identifies issues, and provides actionable insights while reducing noise by excluding certain queries and third-party code. Deployment: Once this pull request is merged, the CodeQL workflow will be active and automatically run on every push and pull request to the main branch. To view the results of these code scans, please follow these steps: 1. Under the repository name, click on the Security tab. 2. In the left sidebar, click Code scanning alerts. Additional Information: - You can further customize the workflow to adapt to your specific needs by modifying the workflow file. - For more information on CodeQL and how to interpret its results, refer to the GitHub documentation and the CodeQL documentation (https://codeql.github.com/ and https://codeql.github.com/docs/). Signed-off-by: Brian --- .github/workflows/codeql.yml | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index eaa9599bd..3ef873fc8 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -14,11 +14,10 @@ name: "CodeQL" on: push: branches: [ "main", "master" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "main", "master" ] schedule: - - cron: '28 21 * * 0' + - cron: '0 0 * * *' + pull_request: + branches: '*' jobs: analyze: @@ -103,21 +102,25 @@ jobs: -**:cpp/suspicious-pointer-scaling -**:cpp/suspicious-pointer-scaling-void -**:cpp/unsigned-comparison-zero - -**/third*party/** - -**/3rd*party/** - -**/external/** + -**/cmake*/Modules/** input: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif - - name: Upload SARIF + - name: Upload CodeQL results to code scanning uses: github/codeql-action/upload-sarif@v2 with: sarif_file: ${{ steps.step1.outputs.sarif-output }} category: "/language:${{matrix.language}}" - - name: Archive CodeQL results + - name: Upload CodeQL results as an artifact + if: success() || failure() uses: actions/upload-artifact@v3 with: name: codeql-results path: ${{ steps.step1.outputs.sarif-output }} - retention-days: 5 \ No newline at end of file + retention-days: 5 + + - name: Fail if an error is found + run: | + ./.github/workflows/fail_on_error.py \ + ${{ steps.step1.outputs.sarif-output }}/cpp.sarif From b9a0a49a5423706433796605fb1511882603f635 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 20 Oct 2023 01:02:15 -0400 Subject: [PATCH 1404/1435] Add CodeQL Workflow for Code Security Analysis Add CodeQL Workflow for Code Security Analysis This pull request introduces a CodeQL workflow to enhance the security analysis of our repository. CodeQL is a powerful static analysis tool that helps identify and mitigate security vulnerabilities in our codebase. By integrating this workflow into our GitHub Actions, we can proactively identify and address potential issues before they become security threats. We added a new CodeQL workflow file (.github/workflows/codeql.yml) that - Runs on every pull request (functionality to run on every push to main branches is included as a comment for convenience). - Runs daily. - Excludes queries with a high false positive rate or low-severity findings. - Does not display results for git submodules, focusing only on our own codebase. Testing: To validate the functionality of this workflow, we have run several test scans on the codebase and reviewed the results. The workflow successfully compiles the project, identifies issues, and provides actionable insights while reducing noise by excluding certain queries and third-party code. Deployment: Once this pull request is merged, the CodeQL workflow will be active and automatically run on every push and pull request to the main branch. To view the results of these code scans, please follow these steps: 1. Under the repository name, click on the Security tab. 2. In the left sidebar, click Code scanning alerts. Additional Information: - You can further customize the workflow to adapt to your specific needs by modifying the workflow file. - For more information on CodeQL and how to interpret its results, refer to the GitHub documentation and the CodeQL documentation (https://codeql.github.com/ and https://codeql.github.com/docs/). Signed-off-by: Brian --- .github/workflows/fail_on_error.py | 34 ++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100755 .github/workflows/fail_on_error.py diff --git a/.github/workflows/fail_on_error.py b/.github/workflows/fail_on_error.py new file mode 100755 index 000000000..29791742b --- /dev/null +++ b/.github/workflows/fail_on_error.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 + +import json +import sys + +# Return whether SARIF file contains error-level results +def codeql_sarif_contain_error(filename): + with open(filename, 'r') as f: + s = json.load(f) + + for run in s.get('runs', []): + rules_metadata = run['tool']['driver']['rules'] + if not rules_metadata: + rules_metadata = run['tool']['extensions'][0]['rules'] + + for res in run.get('results', []): + if 'ruleIndex' in res: + rule_index = res['ruleIndex'] + elif 'rule' in res and 'index' in res['rule']: + rule_index = res['rule']['index'] + else: + continue + try: + rule_level = rules_metadata[rule_index]['defaultConfiguration']['level'] + except IndexError as e: + print(e, rule_index, len(rules_metadata)) + else: + if rule_level == 'error': + return True + return False + +if __name__ == "__main__": + if codeql_sarif_contain_error(sys.argv[1]): + sys.exit(1) From abf354a1558215fe9909c5d2c4947dd9aa35eb6c Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 29 Oct 2023 15:28:16 -0400 Subject: [PATCH 1405/1435] Add CodeQL Workflow for Code Security Analysis Add CodeQL Workflow for Code Security Analysis This pull request introduces a CodeQL workflow to enhance the security analysis of our repository. CodeQL is a powerful static analysis tool that helps identify and mitigate security vulnerabilities in our codebase. By integrating this workflow into our GitHub Actions, we can proactively identify and address potential issues before they become security threats. We added a new CodeQL workflow file (.github/workflows/codeql.yml) that - Runs on every pull request (functionality to run on every push to main branches is included as a comment for convenience). - Runs daily. - Excludes queries with a high false positive rate or low-severity findings. - Does not display results for git submodules, focusing only on our own codebase. Testing: To validate the functionality of this workflow, we have run several test scans on the codebase and reviewed the results. The workflow successfully compiles the project, identifies issues, and provides actionable insights while reducing noise by excluding certain queries and third-party code. Deployment: Once this pull request is merged, the CodeQL workflow will be active and automatically run on every push and pull request to the main branch. To view the results of these code scans, please follow these steps: 1. Under the repository name, click on the Security tab. 2. In the left sidebar, click Code scanning alerts. Additional Information: - You can further customize the workflow to adapt to your specific needs by modifying the workflow file. - For more information on CodeQL and how to interpret its results, refer to the GitHub documentation and the CodeQL documentation (https://codeql.github.com/ and https://codeql.github.com/docs/). Signed-off-by: Brian --- .github/workflows/codeql.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3ef873fc8..816492278 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -12,8 +12,8 @@ name: "CodeQL" on: - push: - branches: [ "main", "master" ] + # push: + # branches: [ "main", "master" ] schedule: - cron: '0 0 * * *' pull_request: From 2d21188cdce20cfdcf9126044a2368a6ccc8dfc0 Mon Sep 17 00:00:00 2001 From: Mirko Date: Wed, 8 Nov 2023 14:51:19 +0000 Subject: [PATCH 1406/1435] first commit --- config/chips/L45x_L46x.chip | 2 ++ config/chips/L496x_L4A6x.chip | 2 ++ src/st-flash/flash.c | 24 +++++++++++++++ src/st-flash/flash_opts.c | 18 +++++------- src/stlink-lib/chipid.c | 16 ++++++++-- src/stlink-lib/chipid.h | 2 ++ src/stlink-lib/common.c | 3 ++ src/stlink-lib/common_flash.c | 55 ++++++++++++++++++++++++++++++++++- src/stlink-lib/common_flash.h | 2 ++ 9 files changed, 111 insertions(+), 13 deletions(-) diff --git a/config/chips/L45x_L46x.chip b/config/chips/L45x_L46x.chip index cbe948c1f..1c8fc2e1f 100644 --- a/config/chips/L45x_L46x.chip +++ b/config/chips/L45x_L46x.chip @@ -12,3 +12,5 @@ bootrom_size 0x7000 // 28 KB option_base 0x0 option_size 0x0 flags swo +otp_base 0x1fff7000 +otp_size 0x400 // 1 KB \ No newline at end of file diff --git a/config/chips/L496x_L4A6x.chip b/config/chips/L496x_L4A6x.chip index 24788c092..8a4a93b1c 100644 --- a/config/chips/L496x_L4A6x.chip +++ b/config/chips/L496x_L4A6x.chip @@ -12,3 +12,5 @@ bootrom_size 0x7000 // 28 KB option_base 0x1fff7800 // STM32_L4_OPTION_BYTES_BASE option_size 0x4 // 4 B flags swo +otp_base 0x1fff7000 +otp_size 0x400 // 1 KB \ No newline at end of file diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 0577ee179..6553298c3 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -61,6 +61,7 @@ static void usage(void) { puts("example write option control register1 byte: ./st-flash --area=optcr write 0xXXXXXXXX"); puts("example read option control register1 byte: ./st-flash --area=optcr1 read"); puts("example write option control register1 byte: ./st-flash --area=optcr1 write 0xXXXXXXXX"); + puts("example read OTP area: ./st-flash --area=otp read [path]"); } int32_t main(int32_t ac, char** av) { @@ -180,6 +181,18 @@ int32_t main(int32_t ac, char** av) { DLOG("@@@@ Write %d (%0#10x) to option bytes boot address\n", o.val, o.val); err = stlink_write_option_bytes_boot_add32(sl, o.val); + } else if (o.area == FLASH_OTP) { + if(sl->otp_base == 0) { + err = -1; + printf("OTP Write Not implimented\n"); + goto on_error; + } + err = stlink_fwrite_flash(sl, o.filename, o.addr); + + if (err == -1) { + printf("stlink_fwrite_flash() == -1\n"); + goto on_error; + } } else { err = -1; printf("Unknown memory region\n"); @@ -284,6 +297,17 @@ int32_t main(int32_t ac, char** av) { } else { printf("%08x\n",option_byte); } + } else if (o.area == FLASH_OTP) { + if(sl->otp_base == 0) { + err = -1; + printf("OTP Read not implimented\n"); + goto on_error; + } + err = stlink_fread(sl, o.filename, 0, sl->otp_base, sl->otp_size); + if (err == -1) { + printf("could not read OTP area (%d)\n", err); + goto on_error; + } } } diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 300203a3f..cf80407d1 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -86,7 +86,6 @@ static int32_t bad_arg(const char *arg) { } int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { - // defaults memset(o, 0, sizeof(*o)); o->log_level = STND_LOG_LEVEL; @@ -270,13 +269,13 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { if (ac != 3) { return invalid_args("read "); } o->filename = av[0]; - uint32_t address; - result = get_integer_from_char_array(av[1], &address); - if (result != 0) { - return bad_arg ("addr"); - } else { - o->addr = (stm32_addr_t) address; - } + uint32_t address; + result = get_integer_from_char_array(av[1], &address); + if (result != 0) { + return bad_arg ("addr"); + } else { + o->addr = (stm32_addr_t) address; + } uint32_t size; result = get_integer_from_char_array(av[2], &size); @@ -288,8 +287,7 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { break; } else if (o->area == FLASH_OTP) { - return bad_arg("TODO: otp not implemented yet"); - if (ac > 1) { return invalid_args("otp read: [path]"); } + if (ac > 1 || ac ==0 ) { return invalid_args("otp read: [path]"); } if (ac > 0) { o->filename = av[0]; } break; } else if (o->area == FLASH_OPTION_BYTES) { diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 06edb26f3..1b6fc13f7 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -34,6 +34,7 @@ void dump_a_chip(struct stlink_chipid_params *dev) { DLOG("option_base 0x%x\n", dev->option_base); DLOG("option_size 0x%x\n", dev->option_size); DLOG("flags %d\n\n", dev->flags); + DLOG("otp_base %d\n\n", dev->otp_base); } struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chip_id) { @@ -57,7 +58,6 @@ void process_chipfile(char *fname) { // fprintf (stderr, "processing chip-id file %s.\n", fname); fp = fopen(fname, "r"); - if (!fp) { perror(fname); return; @@ -180,8 +180,19 @@ void process_chipfile(char *fname) { fprintf(stderr, "Unknown flags word in %s: '%s'\n", fname, p); } } - sscanf(value, "%x", &ts->flags); + } else if (strcmp(word, "otp_base") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + if (sscanf(value, "%i", &ts->otp_base) < 1) { + fprintf(stderr, "Failed to parse option size\n"); + } + } else if (strcmp(word, "otp_size") == 0) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + if (sscanf(value, "%i", &ts->otp_size) < 1) { + fprintf(stderr, "Failed to parse option size\n"); + } } else { fprintf(stderr, "Unknown keyword in %s: %s\n", fname, word); } @@ -191,6 +202,7 @@ void process_chipfile(char *fname) { devicelist = ts; } + #if defined(STLINK_HAVE_DIRENT_H) #include diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index 6726a7420..cf97e6609 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -21,6 +21,8 @@ struct stlink_chipid_params { uint32_t option_base; uint32_t option_size; uint32_t flags; + uint32_t otp_base; + uint32_t otp_size; struct stlink_chipid_params *next; }; diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index dbfcc8b9e..c470f9095 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -290,6 +290,9 @@ int32_t stlink_load_device_params(stlink_t *sl) { sl->option_base = params->option_base; sl->option_size = params->option_size; sl->chip_flags = params->flags; + sl->otp_base = params->otp_base; + sl->otp_size = params->otp_size; + // medium and low devices have the same chipid. ram size depends on flash // size. STM32F100xx datasheet Doc ID 16455 Table 2 diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 3038b53e7..60d8f42fb 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -1310,9 +1310,17 @@ int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { * If the file is identified to be all-empty and four-bytes aligned, * still flash the whole file even if ignoring message is printed. */ - err = stlink_write_flash(sl, addr, mf.base, + + /* In case the address is within the OTP area we use a different flash method */ + if(addr >= sl->otp_base && addr <= sl->otp_base + sl->otp_size) { + err = stlink_write_otp(sl, addr, mf.base, + (num_empty == mf.len) ? (uint32_t)mf.len : (uint32_t)mf.len - num_empty); + } else { + err = stlink_write_flash(sl, addr, mf.base, (num_empty == mf.len) ? (uint32_t)mf.len : (uint32_t)mf.len - num_empty, num_empty == mf.len); + } + stlink_fwrite_finalize(sl, addr); unmap_file(&mf); return (err); @@ -1389,6 +1397,22 @@ int32_t stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, uin return 0; } +// Check if an address and size are within the flash (otp area) +int32_t stlink_check_address_range_validity_otp(stlink_t *sl, stm32_addr_t addr, uint32_t size) { + uint32_t logvar; + if (addr < sl->otp_base || addr >= (sl->otp_base + sl->otp_size)) { + logvar = sl->otp_base + sl->otp_size - 1; + ELOG("Invalid address, it should be within 0x%08x - 0x%08x\n", sl->otp_base, logvar); + return (-1); + } + if ((addr + size) > (sl->otp_base + sl->otp_size)) { + logvar = sl->otp_base + sl->otp_size - addr; + ELOG("The size exceeds the size of the OTP Area (0x%08x bytes available)\n", logvar); + return (-1); + } + return 0; +} + // Check if an address is aligned with the beginning of a page int32_t stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr) { stm32_addr_t page = sl->flash_base; @@ -1408,6 +1432,9 @@ int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint3 int32_t ret; flash_loader_t fl; ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr); + + (void)eraseonly; + // check addr range is inside the flash stlink_calculate_pagesize(sl, addr); @@ -1437,7 +1464,33 @@ int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint3 if (eraseonly) { return (0); } + + ret = stlink_flashloader_start(sl, &fl); + if (ret) + return ret; + ret = stlink_flashloader_write(sl, &fl, addr, base, len); + if (ret) + return ret; + ret = stlink_flashloader_stop(sl, &fl); + if (ret) + return ret; + + return (stlink_verify_write_flash(sl, addr, base, len)); +} + +int32_t stlink_write_otp(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { + int32_t ret; + flash_loader_t fl; + ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr); + + // Check the address and size validity + if (stlink_check_address_range_validity_otp(sl, addr, len) < 0) { + return (-1); + } + // make sure we've loaded the context with the chip details + stlink_core_id(sl); + ret = stlink_flashloader_start(sl, &fl); if (ret) return ret; diff --git a/src/stlink-lib/common_flash.h b/src/stlink-lib/common_flash.h index 9b2b84057..238f0403e 100644 --- a/src/stlink-lib/common_flash.h +++ b/src/stlink-lib/common_flash.h @@ -44,8 +44,10 @@ int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr); int32_t stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr); int32_t stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length); int32_t stlink_check_address_range_validity(stlink_t *sl, stm32_addr_t addr, uint32_t size); +int32_t stlink_check_address_range_validity_otp(stlink_t *sl, stm32_addr_t addr, uint32_t size); int32_t stlink_check_address_alignment(stlink_t *sl, stm32_addr_t addr); int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint8_t eraseonly); +int32_t stlink_write_otp(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len); void stlink_fwrite_finalize(stlink_t *, stm32_addr_t); #endif // COMMON_FLASH_H From b1d99a2fc22af6935f714525641a01483c076b3c Mon Sep 17 00:00:00 2001 From: Mirko Date: Wed, 8 Nov 2023 15:04:10 +0000 Subject: [PATCH 1407/1435] cleaning ident --- config/chips/L45x_L46x.chip | 2 +- config/chips/L496x_L4A6x.chip | 2 +- src/st-flash/flash.c | 4 ++-- src/st-flash/flash_opts.c | 15 ++++++++------- src/stlink-lib/chipid.c | 2 +- src/stlink-lib/common.c | 1 - 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/config/chips/L45x_L46x.chip b/config/chips/L45x_L46x.chip index 1c8fc2e1f..c32030be9 100644 --- a/config/chips/L45x_L46x.chip +++ b/config/chips/L45x_L46x.chip @@ -13,4 +13,4 @@ option_base 0x0 option_size 0x0 flags swo otp_base 0x1fff7000 -otp_size 0x400 // 1 KB \ No newline at end of file +otp_size 0x400 // 1 KB diff --git a/config/chips/L496x_L4A6x.chip b/config/chips/L496x_L4A6x.chip index 8a4a93b1c..65fa3dcbc 100644 --- a/config/chips/L496x_L4A6x.chip +++ b/config/chips/L496x_L4A6x.chip @@ -13,4 +13,4 @@ option_base 0x1fff7800 // STM32_L4_OPTION_BYTES_BASE option_size 0x4 // 4 B flags swo otp_base 0x1fff7000 -otp_size 0x400 // 1 KB \ No newline at end of file +otp_size 0x400 // 1 KB diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 6553298c3..c2cd77a47 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -184,7 +184,7 @@ int32_t main(int32_t ac, char** av) { } else if (o.area == FLASH_OTP) { if(sl->otp_base == 0) { err = -1; - printf("OTP Write Not implimented\n"); + printf("OTP Write NOT implemented\n"); goto on_error; } err = stlink_fwrite_flash(sl, o.filename, o.addr); @@ -300,7 +300,7 @@ int32_t main(int32_t ac, char** av) { } else if (o.area == FLASH_OTP) { if(sl->otp_base == 0) { err = -1; - printf("OTP Read not implimented\n"); + printf("OTP Read NOT implemented\n"); goto on_error; } err = stlink_fread(sl, o.filename, 0, sl->otp_base, sl->otp_size); diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index cf80407d1..8f88f6ea7 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -86,6 +86,7 @@ static int32_t bad_arg(const char *arg) { } int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { + // defaults memset(o, 0, sizeof(*o)); o->log_level = STND_LOG_LEVEL; @@ -269,13 +270,13 @@ int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { if (ac != 3) { return invalid_args("read "); } o->filename = av[0]; - uint32_t address; - result = get_integer_from_char_array(av[1], &address); - if (result != 0) { - return bad_arg ("addr"); - } else { - o->addr = (stm32_addr_t) address; - } + uint32_t address; + result = get_integer_from_char_array(av[1], &address); + if (result != 0) { + return bad_arg ("addr"); + } else { + o->addr = (stm32_addr_t) address; + } uint32_t size; result = get_integer_from_char_array(av[2], &size); diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 1b6fc13f7..77cbfb15d 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -58,6 +58,7 @@ void process_chipfile(char *fname) { // fprintf (stderr, "processing chip-id file %s.\n", fname); fp = fopen(fname, "r"); + if (!fp) { perror(fname); return; @@ -202,7 +203,6 @@ void process_chipfile(char *fname) { devicelist = ts; } - #if defined(STLINK_HAVE_DIRENT_H) #include diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index c470f9095..337fe6efa 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -293,7 +293,6 @@ int32_t stlink_load_device_params(stlink_t *sl) { sl->otp_base = params->otp_base; sl->otp_size = params->otp_size; - // medium and low devices have the same chipid. ram size depends on flash // size. STM32F100xx datasheet Doc ID 16455 Table 2 if (sl->chip_id == STM32_CHIPID_F1_VL_MD_LD && sl->flash_size < 64 * 1024) { From 3cb15d7da2deb69a38940d1fa82570771252951b Mon Sep 17 00:00:00 2001 From: Mirko Date: Wed, 8 Nov 2023 15:14:19 +0000 Subject: [PATCH 1408/1435] final --- src/st-flash/flash.c | 1 + src/st-flash/flash_opts.c | 2 +- src/stlink-lib/chipid.c | 2 ++ src/stlink-lib/common_flash.c | 3 --- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index c2cd77a47..0b7c0cfca 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -62,6 +62,7 @@ static void usage(void) { puts("example read option control register1 byte: ./st-flash --area=optcr1 read"); puts("example write option control register1 byte: ./st-flash --area=optcr1 write 0xXXXXXXXX"); puts("example read OTP area: ./st-flash --area=otp read [path]"); + puts("example write OTP area: ./st-flash --area=otp write [path] 0xXXXXXXXX"); } int32_t main(int32_t ac, char** av) { diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 8f88f6ea7..e2d4154fe 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -86,7 +86,7 @@ static int32_t bad_arg(const char *arg) { } int32_t flash_get_opts(struct flash_opts* o, int32_t ac, char** av) { - + // defaults memset(o, 0, sizeof(*o)); o->log_level = STND_LOG_LEVEL; diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 77cbfb15d..ceeed3114 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -35,6 +35,7 @@ void dump_a_chip(struct stlink_chipid_params *dev) { DLOG("option_size 0x%x\n", dev->option_size); DLOG("flags %d\n\n", dev->flags); DLOG("otp_base %d\n\n", dev->otp_base); + DLOG("otp_size %d\n\n", dev->otp_size); } struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chip_id) { @@ -181,6 +182,7 @@ void process_chipfile(char *fname) { fprintf(stderr, "Unknown flags word in %s: '%s'\n", fname, p); } } + sscanf(value, "%x", &ts->flags); } else if (strcmp(word, "otp_base") == 0) { buf[strlen(buf) - 1] = 0; // chomp newline diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 60d8f42fb..5005a632f 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -1320,7 +1320,6 @@ int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { (num_empty == mf.len) ? (uint32_t)mf.len : (uint32_t)mf.len - num_empty, num_empty == mf.len); } - stlink_fwrite_finalize(sl, addr); unmap_file(&mf); return (err); @@ -1433,8 +1432,6 @@ int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint3 flash_loader_t fl; ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr); - (void)eraseonly; - // check addr range is inside the flash stlink_calculate_pagesize(sl, addr); From e122764f214fb9821b173a63f7ae18690611dc0a Mon Sep 17 00:00:00 2001 From: Mirko Date: Wed, 8 Nov 2023 22:58:05 +0000 Subject: [PATCH 1409/1435] forgot to include this --- inc/stlink.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/inc/stlink.h b/inc/stlink.h index dec608e97..557a9eeaa 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -232,6 +232,9 @@ struct _stlink { uint32_t chip_flags; // stlink_chipid_params.flags, set by stlink_load_device_params(), values: CHIP_F_xxx uint32_t max_trace_freq; // set by stlink_open_usb() + + uint32_t otp_base; + uint32_t otp_size; }; /* Functions defined in common.c */ From 99a2be4d287198ea8072e0db1865fc1757255b7b Mon Sep 17 00:00:00 2001 From: rcubee Date: Sat, 11 Nov 2023 17:27:05 +0100 Subject: [PATCH 1410/1435] initial commit --- c0.patch | 618 ++++++++++++++++++++++++++++++++++ doc/supported_devices.md | 1 + inc/stm32.h | 30 +- inc/stm32flash.h | 24 ++ src/stlink-lib/chipid.c | 4 +- src/stlink-lib/common_flash.c | 98 ++++-- src/stlink-lib/flash_loader.c | 31 +- src/stlink-lib/option_bytes.c | 107 +++++- 8 files changed, 870 insertions(+), 43 deletions(-) create mode 100644 c0.patch diff --git a/c0.patch b/c0.patch new file mode 100644 index 000000000..5b59834d6 --- /dev/null +++ b/c0.patch @@ -0,0 +1,618 @@ +diff --git a/doc/supported_devices.md b/doc/supported_devices.md +index 2e96dcd..103c7fb 100644 +--- a/doc/supported_devices.md ++++ b/doc/supported_devices.md +@@ -6,6 +6,7 @@ More commonly these are: + | Product-Family | ARM Cortex Core | Product Line | + | -------------- | --------------- | ---------------------------------------------------------- | + | STM32F0 | M0 | | ++| STM32C0 | M0+ | | + | STM32G0 | M0+ | | + | STM32L0 | M0+ | | + | STM32F10**0** | M3 | Value line | +diff --git a/inc/stm32.h b/inc/stm32.h +index cf9a8a2..017ea0a 100644 +--- a/inc/stm32.h ++++ b/inc/stm32.h +@@ -51,17 +51,18 @@ enum stm32_core_id { + /* STM32 flash types */ + enum stm32_flash_type { + STM32_FLASH_TYPE_UNKNOWN = 0, +- STM32_FLASH_TYPE_F0_F1_F3 = 1, +- STM32_FLASH_TYPE_F1_XL = 2, +- STM32_FLASH_TYPE_F2_F4 = 3, +- STM32_FLASH_TYPE_F7 = 4, +- STM32_FLASH_TYPE_G0 = 5, +- STM32_FLASH_TYPE_G4 = 6, +- STM32_FLASH_TYPE_H7 = 7, +- STM32_FLASH_TYPE_L0_L1 = 8, +- STM32_FLASH_TYPE_L4 = 9, +- STM32_FLASH_TYPE_L5_U5_H5 = 10, +- STM32_FLASH_TYPE_WB_WL = 11, ++ STM32_FLASH_TYPE_C0 = 1, ++ STM32_FLASH_TYPE_F0_F1_F3 = 2, ++ STM32_FLASH_TYPE_F1_XL = 3, ++ STM32_FLASH_TYPE_F2_F4 = 4, ++ STM32_FLASH_TYPE_F7 = 5, ++ STM32_FLASH_TYPE_G0 = 6, ++ STM32_FLASH_TYPE_G4 = 7, ++ STM32_FLASH_TYPE_H7 = 8, ++ STM32_FLASH_TYPE_L0_L1 = 9, ++ STM32_FLASH_TYPE_L4 = 10, ++ STM32_FLASH_TYPE_L5_U5_H5 = 11, ++ STM32_FLASH_TYPE_WB_WL = 12, + }; + + /* STM32 chip-ids */ +@@ -102,6 +103,7 @@ enum stm32_chipids { + STM32_CHIPID_F0 = 0x440, + STM32_CHIPID_F412 = 0x441, + STM32_CHIPID_F09x = 0x442, ++ STM32_CHIPID_C011xx = 0x443, /* RM0490 (revision 3), section 26.10.1 "DBG device ID code register (DBG_IDCODE)" */ + STM32_CHIPID_F0xx_SMALL = 0x444, + STM32_CHIPID_F04 = 0x445, + STM32_CHIPID_F303_HD = 0x446, /* high density */ +@@ -111,6 +113,7 @@ enum stm32_chipids { + STM32_CHIPID_H74xxx = 0x450, /* RM0433, p.3189 */ + STM32_CHIPID_F76xxx = 0x451, + STM32_CHIPID_F72xxx = 0x452, /* Nucleo F722ZE board */ ++ STM32_CHIPID_C031xx = 0x453, /* RM0490 (revision 3), section 26.10.1 "DBG device ID code register (DBG_IDCODE)" */ + STM32_CHIPID_G0_CAT4 = 0x456, /* G051/G061 */ + STM32_CHIPID_L0_CAT1 = 0x457, + STM32_CHIPID_F410 = 0x458, +@@ -136,6 +139,8 @@ enum stm32_chipids { + }; + + /* Constant STM32 option bytes base memory address */ ++#define STM32_C0_OPTION_BYTES_BASE ((uint32_t)0x1fff7800) ++ + #define STM32_F4_OPTION_BYTES_BASE ((uint32_t)0x40023c14) + + #define STM32_H7_OPTION_BYTES_BASE ((uint32_t)0x5200201c) +@@ -189,6 +194,9 @@ enum stm32_chipids { + #define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11 + #define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12 + ++#define STM32C0_RCC_AHBENR 0x40021038 // RM0490 (revision 3), section 5.4.25 "RCC register map" ++#define STM32C0_RCC_DMAEN 0x00000001 // DMAEN // RM0490 (revision 3), section 5.4.25 "RCC register map" ++ + #define STM32F1_RCC_AHBENR 0x40021014 + #define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +diff --git a/inc/stm32flash.h b/inc/stm32flash.h +index 69c6206..b5e47e0 100644 +--- a/inc/stm32flash.h ++++ b/inc/stm32flash.h +@@ -58,6 +58,30 @@ + #define FLASH_OBR_OFF ((uint32_t)0x1c) + #define FLASH_WRPR_OFF ((uint32_t)0x20) + ++// == STM32C0 == (RM0490) ++// C0 Flash registers ++#define FLASH_C0_REGS_ADDR ((uint32_t)0x40022000) ++#define FLASH_C0_KEYR (FLASH_C0_REGS_ADDR + 0x08) ++#define FLASH_C0_OPT_KEYR (FLASH_C0_REGS_ADDR + 0x0C) ++#define FLASH_C0_SR (FLASH_C0_REGS_ADDR + 0x10) ++#define FLASH_C0_CR (FLASH_C0_REGS_ADDR + 0x14) ++#define FLASH_C0_OPTR (FLASH_C0_REGS_ADDR + 0x20) ++ ++// C0 Flash control register ++#define FLASH_C0_CR_PNB 3 ++#define FLASH_C0_CR_STRT 16 ++#define FLASH_C0_CR_OPTSTRT 17 ++#define FLASH_C0_CR_OBL_LAUNCH 27 ++#define FLASH_C0_CR_OPTLOCK 30 ++#define FLASH_C0_CR_LOCK 31 ++ ++// C0 Flash status register ++#define FLASH_C0_SR_ERROR_MASK 0xC3F8 // [15:14], [9:3] ++#define FLASH_C0_SR_PROGERR 3 ++#define FLASH_C0_SR_WRPERR 4 ++#define FLASH_C0_SR_PGAERR 5 ++#define FLASH_C0_SR_BSY 16 ++ + // == STM32F0 == + #define FLASH_F0_OPTKEY1 0x45670123 + #define FLASH_F0_OPTKEY2 0xcdef89ab +diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c +index 06edb26..86f01f4 100644 +--- a/src/stlink-lib/chipid.c ++++ b/src/stlink-lib/chipid.c +@@ -97,7 +97,9 @@ void process_chipfile(char *fname) { + buf[strlen(buf) - 1] = 0; // chomp newline + sscanf(buf, "%*s %n", &nc); + // Match human readable flash_type with enum stm32_flash_type { }. +- if (strcmp(value, "F0_F1_F3") == 0) { ++ if(strcmp(value, "C0") == 0) { ++ ts->flash_type = STM32_FLASH_TYPE_C0; ++ } else if (strcmp(value, "F0_F1_F3") == 0) { + ts->flash_type = STM32_FLASH_TYPE_F0_F1_F3; + } else if (strcmp(value, "F1_XL") == 0) { + ts->flash_type = STM32_FLASH_TYPE_F1_XL; +diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c +index 3038b53..491cf46 100644 +--- a/src/stlink-lib/common_flash.c ++++ b/src/stlink-lib/common_flash.c +@@ -46,7 +46,9 @@ uint32_t get_stm32l0_flash_base(stlink_t *sl) { + uint32_t read_flash_cr(stlink_t *sl, uint32_t bank) { + uint32_t reg, res; + +- if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { ++ if (sl->flash_type == STM32_FLASH_TYPE_C0) { ++ reg = FLASH_C0_CR; ++ } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + reg = FLASH_F4_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + reg = FLASH_F7_CR; +@@ -77,7 +79,10 @@ void lock_flash(stlink_t *sl) { + uint32_t cr_lock_shift = 0, cr_reg = 0, n = 0, cr2_reg = 0; + uint32_t cr_mask = 0xffffffffu; + +- if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { ++ if (sl->flash_type == STM32_FLASH_TYPE_C0) { ++ cr_reg = FLASH_C0_CR; ++ cr_lock_shift = FLASH_C0_CR_LOCK; ++ } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { +@@ -132,8 +137,10 @@ void lock_flash(stlink_t *sl) { + static inline int32_t write_flash_sr(stlink_t *sl, uint32_t bank, uint32_t val) { + uint32_t sr_reg; + +- if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || +- (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { ++ if (sl->flash_type == STM32_FLASH_TYPE_C0) { ++ sr_reg = FLASH_C0_SR; ++ } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3 || ++ sl->flash_type == STM32_FLASH_TYPE_F1_XL) { + sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + sr_reg = FLASH_F4_SR; +@@ -162,6 +169,9 @@ static inline int32_t write_flash_sr(stlink_t *sl, uint32_t bank, uint32_t val) + + void clear_flash_error(stlink_t *sl) { + switch (sl->flash_type) { ++ case STM32_FLASH_TYPE_C0: ++ write_flash_sr(sl, BANK_1, FLASH_C0_SR_ERROR_MASK); ++ break; + case STM32_FLASH_TYPE_F0_F1_F3: + write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); + break; +@@ -205,8 +215,10 @@ void clear_flash_error(stlink_t *sl) { + uint32_t read_flash_sr(stlink_t *sl, uint32_t bank) { + uint32_t res, sr_reg; + +- if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || +- (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { ++ if (sl->flash_type == STM32_FLASH_TYPE_C0) { ++ sr_reg = FLASH_C0_SR; ++ } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || ++ (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { + sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + sr_reg = FLASH_F4_SR; +@@ -238,9 +250,11 @@ uint32_t is_flash_busy(stlink_t *sl) { + uint32_t sr_busy_shift; + uint32_t res; + +- if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || +- (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || +- (sl->flash_type == STM32_FLASH_TYPE_L0_L1)) { ++ if (sl->flash_type == STM32_FLASH_TYPE_C0) { ++ sr_busy_shift = FLASH_C0_SR_BSY; ++ } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3 || ++ sl->flash_type == STM32_FLASH_TYPE_F1_XL || ++ sl->flash_type == STM32_FLASH_TYPE_L0_L1) { + sr_busy_shift = FLASH_SR_BSY; + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + sr_busy_shift = FLASH_F4_SR_BSY; +@@ -286,6 +300,12 @@ int32_t check_flash_error(stlink_t *sl) { + WRPERR = PROGERR = PGAERR = 0; + + switch (sl->flash_type) { ++ case STM32_FLASH_TYPE_C0: ++ res = read_flash_sr(sl, BANK_1) & FLASH_C0_SR_ERROR_MASK; ++ WRPERR = (1 << FLASH_C0_SR_WRPERR); ++ PROGERR = (1 << FLASH_C0_SR_PROGERR); ++ PGAERR = (1 << FLASH_C0_SR_PGAERR); ++ break; + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; +@@ -382,8 +402,11 @@ static inline uint32_t is_flash_locked(stlink_t *sl) { + uint32_t cr_reg; + uint32_t n; + +- if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || +- (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { ++ if (sl->flash_type == STM32_FLASH_TYPE_C0) { ++ cr_reg = FLASH_C0_CR; ++ cr_lock_shift = FLASH_C0_CR_LOCK; ++ } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3 || ++ sl->flash_type == STM32_FLASH_TYPE_F1_XL) { + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { +@@ -429,7 +452,9 @@ static void unlock_flash(stlink_t *sl) { + * definitive lock of the FPEC block until next reset. + */ + +- if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { ++ if (sl->flash_type == STM32_FLASH_TYPE_C0) { ++ key_reg = FLASH_C0_KEYR; ++ } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { + key_reg = FLASH_KEYR; + } else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { + key_reg = FLASH_KEYR; +@@ -497,6 +522,10 @@ int32_t lock_flash_option(stlink_t *sl) { + int32_t active_bit_level = 1; + + switch (sl->flash_type) { ++ case STM32_FLASH_TYPE_C0: ++ optcr_reg = FLASH_C0_CR; ++ optlock_shift = FLASH_C0_CR_OPTLOCK; ++ break; + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; +@@ -574,6 +603,10 @@ static bool is_flash_option_locked(stlink_t *sl) { + uint32_t n; + + switch (sl->flash_type) { ++ case STM32_FLASH_TYPE_C0: ++ optcr_reg = FLASH_C0_CR; ++ optlock_shift = FLASH_C0_CR_OPTLOCK; ++ break; + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; +@@ -633,6 +666,9 @@ static int32_t unlock_flash_option(stlink_t *sl) { + uint32_t optkey2 = FLASH_OPTKEY2; + + switch (sl->flash_type) { ++ case STM32_FLASH_TYPE_C0: ++ optkey_reg = FLASH_C0_OPT_KEYR; ++ break; + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + optkey_reg = FLASH_OPTKEYR; +@@ -726,7 +762,9 @@ void clear_flash_cr_pg(stlink_t *sl, uint32_t bank) { + uint32_t cr_reg, n; + uint32_t bit = FLASH_CR_PG; + +- if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { ++ if (sl->flash_type == STM32_FLASH_TYPE_C0) { ++ cr_reg = FLASH_C0_CR; ++ } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + cr_reg = FLASH_F4_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; +@@ -802,8 +840,10 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, uint32_t bank) { + static void set_flash_cr_per(stlink_t *sl, uint32_t bank) { + uint32_t cr_reg, val; + +- if (sl->flash_type == STM32_FLASH_TYPE_G0 || +- sl->flash_type == STM32_FLASH_TYPE_G4) { ++ if (sl->flash_type == STM32_FLASH_TYPE_C0) { ++ cr_reg = FLASH_C0_CR; ++ } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || ++ sl->flash_type == STM32_FLASH_TYPE_G4) { + cr_reg = FLASH_Gx_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { + cr_reg = FLASH_L5_NSCR; +@@ -821,8 +861,10 @@ static void set_flash_cr_per(stlink_t *sl, uint32_t bank) { + static void clear_flash_cr_per(stlink_t *sl, uint32_t bank) { + uint32_t cr_reg; + +- if (sl->flash_type == STM32_FLASH_TYPE_G0 || +- sl->flash_type == STM32_FLASH_TYPE_G4) { ++ if (sl->flash_type == STM32_FLASH_TYPE_C0) { ++ cr_reg = FLASH_C0_CR; ++ } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || ++ sl->flash_type == STM32_FLASH_TYPE_G4) { + cr_reg = FLASH_Gx_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { + cr_reg = FLASH_L5_NSCR; +@@ -855,7 +897,10 @@ static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { + static void set_flash_cr_strt(stlink_t *sl, uint32_t bank) { + uint32_t val, cr_reg, cr_strt; + +- if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { ++ if (sl->flash_type == STM32_FLASH_TYPE_C0) { ++ cr_reg = FLASH_C0_CR; ++ cr_strt = 1 << FLASH_C0_CR_STRT; ++ } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + cr_reg = FLASH_F4_CR; + cr_strt = 1 << FLASH_F4_CR_STRT; + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { +@@ -890,7 +935,11 @@ static void set_flash_cr_strt(stlink_t *sl, uint32_t bank) { + static void set_flash_cr_mer(stlink_t *sl, bool v, uint32_t bank) { + uint32_t val, cr_reg, cr_mer, cr_pg; + +- if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { ++ if (sl->flash_type == STM32_FLASH_TYPE_C0) { ++ cr_reg = FLASH_C0_CR; ++ cr_mer = 1 << FLASH_CR_MER; ++ cr_pg = 1 << FLASH_CR_PG; ++ } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + cr_reg = FLASH_F4_CR; + cr_mer = 1 << FLASH_CR_MER; + cr_pg = 1 << FLASH_CR_PG; +@@ -1062,7 +1111,8 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4 || + sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5 || +- sl->flash_type == STM32_FLASH_TYPE_WB_WL) { ++ sl->flash_type == STM32_FLASH_TYPE_WB_WL || ++ sl->flash_type == STM32_FLASH_TYPE_C0) { + uint32_t val; + unlock_flash_if(sl); + set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit +@@ -1107,6 +1157,14 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { + val |= ((flash_page & 0xFF) << 3); + + stlink_write_debug32(sl, FLASH_WB_CR, val); ++ } else if (sl->flash_type == STM32_FLASH_TYPE_C0) { ++ uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); ++ stlink_read_debug32(sl, FLASH_C0_CR, &val); ++ ++ val &= ~(0xF << FLASH_C0_CR_PNB); ++ val |= ((flash_page & 0xF) << FLASH_C0_CR_PNB); ++ ++ stlink_write_debug32(sl, FLASH_C0_CR, val); + } + + set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit +diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c +index ea1f6d9..0d01dfd 100644 +--- a/src/stlink-lib/flash_loader.c ++++ b/src/stlink-lib/flash_loader.c +@@ -491,12 +491,15 @@ static void set_flash_cr_pg(stlink_t *sl, uint32_t bank) { + + x = read_flash_cr(sl, bank); + +- if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { ++ if (sl->flash_type == STM32_FLASH_TYPE_C0) { ++ cr_reg = FLASH_C0_CR; ++ x |= (1 << FLASH_CR_PG); ++ } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + cr_reg = FLASH_F4_CR; +- x |= 1 << FLASH_CR_PG; ++ x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; +- x |= 1 << FLASH_CR_PG; ++ x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { + cr_reg = FLASH_L4_CR; + x &= ~FLASH_L4_CR_OPBITS; +@@ -528,6 +531,10 @@ static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int32_t bckpRstr) { + rcc = rcc_dma_mask = value = 0; + + switch (sl->flash_type) { ++ case STM32_FLASH_TYPE_C0: ++ rcc = STM32C0_RCC_AHBENR; ++ rcc_dma_mask = STM32C0_RCC_DMAEN; ++ break; + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + rcc = STM32F1_RCC_AHBENR; +@@ -639,8 +646,9 @@ int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || + sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4 || +- sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { +- ILOG("Starting Flash write for WB/G0/G4/L5/U5/H5\n"); ++ sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5 || ++ sl->flash_type == STM32_FLASH_TYPE_C0) { ++ ILOG("Starting Flash write for WB/G0/G4/L5/U5/H5/C0\n"); + + unlock_flash_if(sl); // unlock flash if necessary + set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit +@@ -720,6 +728,7 @@ int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { + + int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t *base, uint32_t len) { + uint32_t off; ++ + if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || + (sl->flash_type == STM32_FLASH_TYPE_F7) || + (sl->flash_type == STM32_FLASH_TYPE_L4)) { +@@ -737,13 +746,14 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t + } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || + sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4 || +- sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { ++ sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5 || ++ sl->flash_type == STM32_FLASH_TYPE_C0) { + DLOG("Starting %3u page write\n", len / sl->flash_pgsz); + for (off = 0; off < len; off += sizeof(uint32_t)) { + uint32_t data; + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { +- fprintf(stdout, "\r%3u/%3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); ++ fprintf(stdout, "\r%3u/%-3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); + fflush(stdout); + } + +@@ -782,7 +792,7 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t + uint32_t data; + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { +- fprintf(stdout, "\r%3u/%3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); ++ fprintf(stdout, "\r%3u/%-3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); + fflush(stdout); + } + +@@ -819,7 +829,7 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t + if (sl->verbose >= 1) { + // show progress; writing procedure is slow and previous errors are + // misleading +- fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, ++ fprintf(stdout, "\r%3u/%-3u pages written", ++write_block_count, + (len + sl->flash_pgsz - 1) / sl->flash_pgsz); + fflush(stdout); + } +@@ -856,7 +866,8 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t + int32_t stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { + uint32_t dhcsr; + +- if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || ++ if ((sl->flash_type == STM32_FLASH_TYPE_C0) || ++ (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || + (sl->flash_type == STM32_FLASH_TYPE_F2_F4) || + (sl->flash_type == STM32_FLASH_TYPE_F7) || +diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c +index ee03dce..2ee45c9 100644 +--- a/src/stlink-lib/option_bytes.c ++++ b/src/stlink-lib/option_bytes.c +@@ -18,6 +18,101 @@ + #include "md5.h" + #include "read_write.h" + ++/** ++ * Read option control register C0 ++ * @param sl ++ * @param option_byte ++ * @return 0 on success, -ve on failure. ++ */ ++static int32_t stlink_read_option_control_register_c0(stlink_t *sl, uint32_t *option_byte) { ++ return stlink_read_debug32(sl, FLASH_C0_OPTR, option_byte); ++} ++ ++/** ++ * Read option bytes C0 ++ * @param sl ++ * @param option_byte ++ * @return 0 on success, -ve on failure. ++ */ ++static int32_t stlink_read_option_bytes_c0(stlink_t *sl, uint32_t *option_byte) { ++ return stlink_read_option_control_register_c0(sl, option_byte); ++} ++ ++/** ++ * Write option control register C0 ++ * @param sl ++ * @param option_cr ++ * @return 0 on success, -ve on failure. ++ */ ++static int32_t stlink_write_option_control_register_c0(stlink_t *sl, uint32_t option_cr) { ++ int32_t ret = 0; ++ ++ clear_flash_error(sl); ++ ++ if ((ret = stlink_write_debug32(sl, FLASH_C0_OPTR, option_cr))) ++ return ret; ++ ++ wait_flash_busy(sl); ++ ++ uint32_t cr_reg = (1 << FLASH_C0_CR_OPTSTRT); ++ if ((ret = stlink_write_debug32(sl, FLASH_C0_CR, cr_reg))) ++ return ret; ++ ++ wait_flash_busy(sl); ++ ++ if ((ret = check_flash_error(sl))) ++ return ret; ++ ++ // trigger the load of option bytes into option registers ++ cr_reg = (1 << FLASH_C0_CR_OBL_LAUNCH); ++ stlink_write_debug32(sl, FLASH_C0_CR, cr_reg); ++ ++ return ret; ++} ++ ++/** ++ * Write option bytes C0 ++ * @param sl ++ * @param addr of the memory mapped option bytes ++ * @param base option bytes ++ * @param len of option bytes ++ * @return 0 on success, -ve on failure. ++ */ ++static int32_t stlink_write_option_bytes_c0(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { ++#if 0 ++ uint32_t val; ++ int32_t ret = 0; ++ (void)len; ++ uint32_t data; ++ ++ clear_flash_error(sl); ++ ++ write_uint32((unsigned char *)&data, *(uint32_t *)(base)); ++ WLOG("Writing option bytes %#10x to %#10x\n", data, addr); ++ stlink_write_debug32(sl, FLASH_C0_OPTR, data); ++ ++ stlink_read_debug32(sl, FLASH_C0_CR, &val); ++ val |= (1 << FLASH_C0_CR_OPTSTRT); ++ stlink_write_debug32(sl, FLASH_C0_CR, val); ++ ++ wait_flash_busy(sl); ++ ++ ret = check_flash_error(sl); ++ ++ // trigger the load of option bytes into option registers ++ stlink_read_debug32(sl, FLASH_C0_CR, &val); ++ val |= (1 << FLASH_C0_CR_OBL_LAUNCH); ++ stlink_write_debug32(sl, FLASH_C0_CR, val); ++ ++ return (ret); ++#else ++ (void)addr; ++ (void)len; ++ ++ return stlink_write_option_control_register_c0(sl, *(uint32_t*)base); ++#endif ++} ++ + /** + * Read option control register F0 + * @param sl +@@ -745,7 +840,6 @@ int32_t stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_debug32(sl, sl->option_base, option_byte); + } + +- + /** + * Write option bytes + * @param sl +@@ -785,6 +879,9 @@ int32_t stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base + } + + switch (sl->flash_type) { ++ case STM32_FLASH_TYPE_C0: ++ ret = stlink_write_option_bytes_c0(sl, addr, base, len); ++ break; + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + ret = stlink_write_option_bytes_f0(sl, addr, base, len); +@@ -870,6 +967,8 @@ int32_t stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byt + } + + switch (sl->flash_type) { ++ case STM32_FLASH_TYPE_C0: ++ return stlink_read_option_control_register_c0(sl, option_byte); + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + return stlink_read_option_control_register_f0(sl, option_byte); +@@ -904,6 +1003,9 @@ int32_t stlink_write_option_control_register32(stlink_t *sl, uint32_t option_cr) + } + + switch (sl->flash_type) { ++ case STM32_FLASH_TYPE_C0: ++ ret = stlink_write_option_control_register_c0(sl, option_cr); ++ break; + case STM32_FLASH_TYPE_F0_F1_F3: + case STM32_FLASH_TYPE_F1_XL: + ret = stlink_write_option_control_register_f0(sl, option_cr); +@@ -1009,6 +1111,9 @@ int32_t stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { + } + + switch (sl->chip_id) { ++ case STM32_CHIPID_C011xx: ++ case STM32_CHIPID_C031xx: ++ return stlink_read_option_bytes_c0(sl, option_byte); + case STM32_CHIPID_F2: + return stlink_read_option_bytes_f2(sl, option_byte); + case STM32_CHIPID_F4: diff --git a/doc/supported_devices.md b/doc/supported_devices.md index 2e96dcd39..103c7fb5f 100644 --- a/doc/supported_devices.md +++ b/doc/supported_devices.md @@ -6,6 +6,7 @@ More commonly these are: | Product-Family | ARM Cortex Core | Product Line | | -------------- | --------------- | ---------------------------------------------------------- | | STM32F0 | M0 | | +| STM32C0 | M0+ | | | STM32G0 | M0+ | | | STM32L0 | M0+ | | | STM32F10**0** | M3 | Value line | diff --git a/inc/stm32.h b/inc/stm32.h index cf9a8a2ad..017ea0af6 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -51,17 +51,18 @@ enum stm32_core_id { /* STM32 flash types */ enum stm32_flash_type { STM32_FLASH_TYPE_UNKNOWN = 0, - STM32_FLASH_TYPE_F0_F1_F3 = 1, - STM32_FLASH_TYPE_F1_XL = 2, - STM32_FLASH_TYPE_F2_F4 = 3, - STM32_FLASH_TYPE_F7 = 4, - STM32_FLASH_TYPE_G0 = 5, - STM32_FLASH_TYPE_G4 = 6, - STM32_FLASH_TYPE_H7 = 7, - STM32_FLASH_TYPE_L0_L1 = 8, - STM32_FLASH_TYPE_L4 = 9, - STM32_FLASH_TYPE_L5_U5_H5 = 10, - STM32_FLASH_TYPE_WB_WL = 11, + STM32_FLASH_TYPE_C0 = 1, + STM32_FLASH_TYPE_F0_F1_F3 = 2, + STM32_FLASH_TYPE_F1_XL = 3, + STM32_FLASH_TYPE_F2_F4 = 4, + STM32_FLASH_TYPE_F7 = 5, + STM32_FLASH_TYPE_G0 = 6, + STM32_FLASH_TYPE_G4 = 7, + STM32_FLASH_TYPE_H7 = 8, + STM32_FLASH_TYPE_L0_L1 = 9, + STM32_FLASH_TYPE_L4 = 10, + STM32_FLASH_TYPE_L5_U5_H5 = 11, + STM32_FLASH_TYPE_WB_WL = 12, }; /* STM32 chip-ids */ @@ -102,6 +103,7 @@ enum stm32_chipids { STM32_CHIPID_F0 = 0x440, STM32_CHIPID_F412 = 0x441, STM32_CHIPID_F09x = 0x442, + STM32_CHIPID_C011xx = 0x443, /* RM0490 (revision 3), section 26.10.1 "DBG device ID code register (DBG_IDCODE)" */ STM32_CHIPID_F0xx_SMALL = 0x444, STM32_CHIPID_F04 = 0x445, STM32_CHIPID_F303_HD = 0x446, /* high density */ @@ -111,6 +113,7 @@ enum stm32_chipids { STM32_CHIPID_H74xxx = 0x450, /* RM0433, p.3189 */ STM32_CHIPID_F76xxx = 0x451, STM32_CHIPID_F72xxx = 0x452, /* Nucleo F722ZE board */ + STM32_CHIPID_C031xx = 0x453, /* RM0490 (revision 3), section 26.10.1 "DBG device ID code register (DBG_IDCODE)" */ STM32_CHIPID_G0_CAT4 = 0x456, /* G051/G061 */ STM32_CHIPID_L0_CAT1 = 0x457, STM32_CHIPID_F410 = 0x458, @@ -136,6 +139,8 @@ enum stm32_chipids { }; /* Constant STM32 option bytes base memory address */ +#define STM32_C0_OPTION_BYTES_BASE ((uint32_t)0x1fff7800) + #define STM32_F4_OPTION_BYTES_BASE ((uint32_t)0x40023c14) #define STM32_H7_OPTION_BYTES_BASE ((uint32_t)0x5200201c) @@ -189,6 +194,9 @@ enum stm32_chipids { #define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11 #define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12 +#define STM32C0_RCC_AHBENR 0x40021038 // RM0490 (revision 3), section 5.4.25 "RCC register map" +#define STM32C0_RCC_DMAEN 0x00000001 // DMAEN // RM0490 (revision 3), section 5.4.25 "RCC register map" + #define STM32F1_RCC_AHBENR 0x40021014 #define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN diff --git a/inc/stm32flash.h b/inc/stm32flash.h index 69c6206ee..b5e47e0d3 100644 --- a/inc/stm32flash.h +++ b/inc/stm32flash.h @@ -58,6 +58,30 @@ #define FLASH_OBR_OFF ((uint32_t)0x1c) #define FLASH_WRPR_OFF ((uint32_t)0x20) +// == STM32C0 == (RM0490) +// C0 Flash registers +#define FLASH_C0_REGS_ADDR ((uint32_t)0x40022000) +#define FLASH_C0_KEYR (FLASH_C0_REGS_ADDR + 0x08) +#define FLASH_C0_OPT_KEYR (FLASH_C0_REGS_ADDR + 0x0C) +#define FLASH_C0_SR (FLASH_C0_REGS_ADDR + 0x10) +#define FLASH_C0_CR (FLASH_C0_REGS_ADDR + 0x14) +#define FLASH_C0_OPTR (FLASH_C0_REGS_ADDR + 0x20) + +// C0 Flash control register +#define FLASH_C0_CR_PNB 3 +#define FLASH_C0_CR_STRT 16 +#define FLASH_C0_CR_OPTSTRT 17 +#define FLASH_C0_CR_OBL_LAUNCH 27 +#define FLASH_C0_CR_OPTLOCK 30 +#define FLASH_C0_CR_LOCK 31 + +// C0 Flash status register +#define FLASH_C0_SR_ERROR_MASK 0xC3F8 // [15:14], [9:3] +#define FLASH_C0_SR_PROGERR 3 +#define FLASH_C0_SR_WRPERR 4 +#define FLASH_C0_SR_PGAERR 5 +#define FLASH_C0_SR_BSY 16 + // == STM32F0 == #define FLASH_F0_OPTKEY1 0x45670123 #define FLASH_F0_OPTKEY2 0xcdef89ab diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 06edb26f3..86f01f4df 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -97,7 +97,9 @@ void process_chipfile(char *fname) { buf[strlen(buf) - 1] = 0; // chomp newline sscanf(buf, "%*s %n", &nc); // Match human readable flash_type with enum stm32_flash_type { }. - if (strcmp(value, "F0_F1_F3") == 0) { + if(strcmp(value, "C0") == 0) { + ts->flash_type = STM32_FLASH_TYPE_C0; + } else if (strcmp(value, "F0_F1_F3") == 0) { ts->flash_type = STM32_FLASH_TYPE_F0_F1_F3; } else if (strcmp(value, "F1_XL") == 0) { ts->flash_type = STM32_FLASH_TYPE_F1_XL; diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 3038b53e7..491cf462d 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -46,7 +46,9 @@ uint32_t get_stm32l0_flash_base(stlink_t *sl) { uint32_t read_flash_cr(stlink_t *sl, uint32_t bank) { uint32_t reg, res; - if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_C0) { + reg = FLASH_C0_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { reg = FLASH_F4_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { reg = FLASH_F7_CR; @@ -77,7 +79,10 @@ void lock_flash(stlink_t *sl) { uint32_t cr_lock_shift = 0, cr_reg = 0, n = 0, cr2_reg = 0; uint32_t cr_mask = 0xffffffffu; - if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { + if (sl->flash_type == STM32_FLASH_TYPE_C0) { + cr_reg = FLASH_C0_CR; + cr_lock_shift = FLASH_C0_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { cr_reg = FLASH_CR; cr_lock_shift = FLASH_CR_LOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { @@ -132,8 +137,10 @@ void lock_flash(stlink_t *sl) { static inline int32_t write_flash_sr(stlink_t *sl, uint32_t bank, uint32_t val) { uint32_t sr_reg; - if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { + if (sl->flash_type == STM32_FLASH_TYPE_C0) { + sr_reg = FLASH_C0_SR; + } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3 || + sl->flash_type == STM32_FLASH_TYPE_F1_XL) { sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { sr_reg = FLASH_F4_SR; @@ -162,6 +169,9 @@ static inline int32_t write_flash_sr(stlink_t *sl, uint32_t bank, uint32_t val) void clear_flash_error(stlink_t *sl) { switch (sl->flash_type) { + case STM32_FLASH_TYPE_C0: + write_flash_sr(sl, BANK_1, FLASH_C0_SR_ERROR_MASK); + break; case STM32_FLASH_TYPE_F0_F1_F3: write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); break; @@ -205,8 +215,10 @@ void clear_flash_error(stlink_t *sl) { uint32_t read_flash_sr(stlink_t *sl, uint32_t bank) { uint32_t res, sr_reg; - if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { + if (sl->flash_type == STM32_FLASH_TYPE_C0) { + sr_reg = FLASH_C0_SR; + } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { sr_reg = FLASH_F4_SR; @@ -238,9 +250,11 @@ uint32_t is_flash_busy(stlink_t *sl) { uint32_t sr_busy_shift; uint32_t res; - if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || - (sl->flash_type == STM32_FLASH_TYPE_L0_L1)) { + if (sl->flash_type == STM32_FLASH_TYPE_C0) { + sr_busy_shift = FLASH_C0_SR_BSY; + } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3 || + sl->flash_type == STM32_FLASH_TYPE_F1_XL || + sl->flash_type == STM32_FLASH_TYPE_L0_L1) { sr_busy_shift = FLASH_SR_BSY; } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { sr_busy_shift = FLASH_F4_SR_BSY; @@ -286,6 +300,12 @@ int32_t check_flash_error(stlink_t *sl) { WRPERR = PROGERR = PGAERR = 0; switch (sl->flash_type) { + case STM32_FLASH_TYPE_C0: + res = read_flash_sr(sl, BANK_1) & FLASH_C0_SR_ERROR_MASK; + WRPERR = (1 << FLASH_C0_SR_WRPERR); + PROGERR = (1 << FLASH_C0_SR_PROGERR); + PGAERR = (1 << FLASH_C0_SR_PGAERR); + break; case STM32_FLASH_TYPE_F0_F1_F3: case STM32_FLASH_TYPE_F1_XL: res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; @@ -382,8 +402,11 @@ static inline uint32_t is_flash_locked(stlink_t *sl) { uint32_t cr_reg; uint32_t n; - if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { + if (sl->flash_type == STM32_FLASH_TYPE_C0) { + cr_reg = FLASH_C0_CR; + cr_lock_shift = FLASH_C0_CR_LOCK; + } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3 || + sl->flash_type == STM32_FLASH_TYPE_F1_XL) { cr_reg = FLASH_CR; cr_lock_shift = FLASH_CR_LOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { @@ -429,7 +452,9 @@ static void unlock_flash(stlink_t *sl) { * definitive lock of the FPEC block until next reset. */ - if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { + if (sl->flash_type == STM32_FLASH_TYPE_C0) { + key_reg = FLASH_C0_KEYR; + } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { key_reg = FLASH_KEYR; } else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { key_reg = FLASH_KEYR; @@ -497,6 +522,10 @@ int32_t lock_flash_option(stlink_t *sl) { int32_t active_bit_level = 1; switch (sl->flash_type) { + case STM32_FLASH_TYPE_C0: + optcr_reg = FLASH_C0_CR; + optlock_shift = FLASH_C0_CR_OPTLOCK; + break; case STM32_FLASH_TYPE_F0_F1_F3: case STM32_FLASH_TYPE_F1_XL: optcr_reg = FLASH_CR; @@ -574,6 +603,10 @@ static bool is_flash_option_locked(stlink_t *sl) { uint32_t n; switch (sl->flash_type) { + case STM32_FLASH_TYPE_C0: + optcr_reg = FLASH_C0_CR; + optlock_shift = FLASH_C0_CR_OPTLOCK; + break; case STM32_FLASH_TYPE_F0_F1_F3: case STM32_FLASH_TYPE_F1_XL: optcr_reg = FLASH_CR; @@ -633,6 +666,9 @@ static int32_t unlock_flash_option(stlink_t *sl) { uint32_t optkey2 = FLASH_OPTKEY2; switch (sl->flash_type) { + case STM32_FLASH_TYPE_C0: + optkey_reg = FLASH_C0_OPT_KEYR; + break; case STM32_FLASH_TYPE_F0_F1_F3: case STM32_FLASH_TYPE_F1_XL: optkey_reg = FLASH_OPTKEYR; @@ -726,7 +762,9 @@ void clear_flash_cr_pg(stlink_t *sl, uint32_t bank) { uint32_t cr_reg, n; uint32_t bit = FLASH_CR_PG; - if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_C0) { + cr_reg = FLASH_C0_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; @@ -802,8 +840,10 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, uint32_t bank) { static void set_flash_cr_per(stlink_t *sl, uint32_t bank) { uint32_t cr_reg, val; - if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { + if (sl->flash_type == STM32_FLASH_TYPE_C0) { + cr_reg = FLASH_C0_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = FLASH_Gx_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { cr_reg = FLASH_L5_NSCR; @@ -821,8 +861,10 @@ static void set_flash_cr_per(stlink_t *sl, uint32_t bank) { static void clear_flash_cr_per(stlink_t *sl, uint32_t bank) { uint32_t cr_reg; - if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4) { + if (sl->flash_type == STM32_FLASH_TYPE_C0) { + cr_reg = FLASH_C0_CR; + } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || + sl->flash_type == STM32_FLASH_TYPE_G4) { cr_reg = FLASH_Gx_CR; } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { cr_reg = FLASH_L5_NSCR; @@ -855,7 +897,10 @@ static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { static void set_flash_cr_strt(stlink_t *sl, uint32_t bank) { uint32_t val, cr_reg, cr_strt; - if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_C0) { + cr_reg = FLASH_C0_CR; + cr_strt = 1 << FLASH_C0_CR_STRT; + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; cr_strt = 1 << FLASH_F4_CR_STRT; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { @@ -890,7 +935,11 @@ static void set_flash_cr_strt(stlink_t *sl, uint32_t bank) { static void set_flash_cr_mer(stlink_t *sl, bool v, uint32_t bank) { uint32_t val, cr_reg, cr_mer, cr_pg; - if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_C0) { + cr_reg = FLASH_C0_CR; + cr_mer = 1 << FLASH_CR_MER; + cr_pg = 1 << FLASH_CR_PG; + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; cr_mer = 1 << FLASH_CR_MER; cr_pg = 1 << FLASH_CR_PG; @@ -1062,7 +1111,8 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4 || sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5 || - sl->flash_type == STM32_FLASH_TYPE_WB_WL) { + sl->flash_type == STM32_FLASH_TYPE_WB_WL || + sl->flash_type == STM32_FLASH_TYPE_C0) { uint32_t val; unlock_flash_if(sl); set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit @@ -1107,6 +1157,14 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { val |= ((flash_page & 0xFF) << 3); stlink_write_debug32(sl, FLASH_WB_CR, val); + } else if (sl->flash_type == STM32_FLASH_TYPE_C0) { + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); + stlink_read_debug32(sl, FLASH_C0_CR, &val); + + val &= ~(0xF << FLASH_C0_CR_PNB); + val |= ((flash_page & 0xF) << FLASH_C0_CR_PNB); + + stlink_write_debug32(sl, FLASH_C0_CR, val); } set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index ea1f6d97a..0d01dfd61 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -491,12 +491,15 @@ static void set_flash_cr_pg(stlink_t *sl, uint32_t bank) { x = read_flash_cr(sl, bank); - if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { + if (sl->flash_type == STM32_FLASH_TYPE_C0) { + cr_reg = FLASH_C0_CR; + x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { cr_reg = FLASH_F4_CR; - x |= 1 << FLASH_CR_PG; + x |= (1 << FLASH_CR_PG); } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; - x |= 1 << FLASH_CR_PG; + x |= (1 << FLASH_CR_PG); } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { cr_reg = FLASH_L4_CR; x &= ~FLASH_L4_CR_OPBITS; @@ -528,6 +531,10 @@ static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int32_t bckpRstr) { rcc = rcc_dma_mask = value = 0; switch (sl->flash_type) { + case STM32_FLASH_TYPE_C0: + rcc = STM32C0_RCC_AHBENR; + rcc_dma_mask = STM32C0_RCC_DMAEN; + break; case STM32_FLASH_TYPE_F0_F1_F3: case STM32_FLASH_TYPE_F1_XL: rcc = STM32F1_RCC_AHBENR; @@ -639,8 +646,9 @@ int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4 || - sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { - ILOG("Starting Flash write for WB/G0/G4/L5/U5/H5\n"); + sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5 || + sl->flash_type == STM32_FLASH_TYPE_C0) { + ILOG("Starting Flash write for WB/G0/G4/L5/U5/H5/C0\n"); unlock_flash_if(sl); // unlock flash if necessary set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit @@ -720,6 +728,7 @@ int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t *base, uint32_t len) { uint32_t off; + if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || (sl->flash_type == STM32_FLASH_TYPE_F7) || (sl->flash_type == STM32_FLASH_TYPE_L4)) { @@ -737,13 +746,14 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4 || - sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { + sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5 || + sl->flash_type == STM32_FLASH_TYPE_C0) { DLOG("Starting %3u page write\n", len / sl->flash_pgsz); for (off = 0; off < len; off += sizeof(uint32_t)) { uint32_t data; if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { - fprintf(stdout, "\r%3u/%3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); + fprintf(stdout, "\r%3u/%-3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); fflush(stdout); } @@ -782,7 +792,7 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t uint32_t data; if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { - fprintf(stdout, "\r%3u/%3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); + fprintf(stdout, "\r%3u/%-3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); fflush(stdout); } @@ -819,7 +829,7 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t if (sl->verbose >= 1) { // show progress; writing procedure is slow and previous errors are // misleading - fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, + fprintf(stdout, "\r%3u/%-3u pages written", ++write_block_count, (len + sl->flash_pgsz - 1) / sl->flash_pgsz); fflush(stdout); } @@ -856,7 +866,8 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t int32_t stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { uint32_t dhcsr; - if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || + if ((sl->flash_type == STM32_FLASH_TYPE_C0) || + (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || (sl->flash_type == STM32_FLASH_TYPE_F2_F4) || (sl->flash_type == STM32_FLASH_TYPE_F7) || diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c index ee03dced9..2ee45c901 100644 --- a/src/stlink-lib/option_bytes.c +++ b/src/stlink-lib/option_bytes.c @@ -18,6 +18,101 @@ #include "md5.h" #include "read_write.h" +/** + * Read option control register C0 + * @param sl + * @param option_byte + * @return 0 on success, -ve on failure. + */ +static int32_t stlink_read_option_control_register_c0(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_debug32(sl, FLASH_C0_OPTR, option_byte); +} + +/** + * Read option bytes C0 + * @param sl + * @param option_byte + * @return 0 on success, -ve on failure. + */ +static int32_t stlink_read_option_bytes_c0(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_c0(sl, option_byte); +} + +/** + * Write option control register C0 + * @param sl + * @param option_cr + * @return 0 on success, -ve on failure. + */ +static int32_t stlink_write_option_control_register_c0(stlink_t *sl, uint32_t option_cr) { + int32_t ret = 0; + + clear_flash_error(sl); + + if ((ret = stlink_write_debug32(sl, FLASH_C0_OPTR, option_cr))) + return ret; + + wait_flash_busy(sl); + + uint32_t cr_reg = (1 << FLASH_C0_CR_OPTSTRT); + if ((ret = stlink_write_debug32(sl, FLASH_C0_CR, cr_reg))) + return ret; + + wait_flash_busy(sl); + + if ((ret = check_flash_error(sl))) + return ret; + + // trigger the load of option bytes into option registers + cr_reg = (1 << FLASH_C0_CR_OBL_LAUNCH); + stlink_write_debug32(sl, FLASH_C0_CR, cr_reg); + + return ret; +} + +/** + * Write option bytes C0 + * @param sl + * @param addr of the memory mapped option bytes + * @param base option bytes + * @param len of option bytes + * @return 0 on success, -ve on failure. + */ +static int32_t stlink_write_option_bytes_c0(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { +#if 0 + uint32_t val; + int32_t ret = 0; + (void)len; + uint32_t data; + + clear_flash_error(sl); + + write_uint32((unsigned char *)&data, *(uint32_t *)(base)); + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + stlink_write_debug32(sl, FLASH_C0_OPTR, data); + + stlink_read_debug32(sl, FLASH_C0_CR, &val); + val |= (1 << FLASH_C0_CR_OPTSTRT); + stlink_write_debug32(sl, FLASH_C0_CR, val); + + wait_flash_busy(sl); + + ret = check_flash_error(sl); + + // trigger the load of option bytes into option registers + stlink_read_debug32(sl, FLASH_C0_CR, &val); + val |= (1 << FLASH_C0_CR_OBL_LAUNCH); + stlink_write_debug32(sl, FLASH_C0_CR, val); + + return (ret); +#else + (void)addr; + (void)len; + + return stlink_write_option_control_register_c0(sl, *(uint32_t*)base); +#endif +} + /** * Read option control register F0 * @param sl @@ -745,7 +840,6 @@ int32_t stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte) { return stlink_read_debug32(sl, sl->option_base, option_byte); } - /** * Write option bytes * @param sl @@ -785,6 +879,9 @@ int32_t stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base } switch (sl->flash_type) { + case STM32_FLASH_TYPE_C0: + ret = stlink_write_option_bytes_c0(sl, addr, base, len); + break; case STM32_FLASH_TYPE_F0_F1_F3: case STM32_FLASH_TYPE_F1_XL: ret = stlink_write_option_bytes_f0(sl, addr, base, len); @@ -870,6 +967,8 @@ int32_t stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byt } switch (sl->flash_type) { + case STM32_FLASH_TYPE_C0: + return stlink_read_option_control_register_c0(sl, option_byte); case STM32_FLASH_TYPE_F0_F1_F3: case STM32_FLASH_TYPE_F1_XL: return stlink_read_option_control_register_f0(sl, option_byte); @@ -904,6 +1003,9 @@ int32_t stlink_write_option_control_register32(stlink_t *sl, uint32_t option_cr) } switch (sl->flash_type) { + case STM32_FLASH_TYPE_C0: + ret = stlink_write_option_control_register_c0(sl, option_cr); + break; case STM32_FLASH_TYPE_F0_F1_F3: case STM32_FLASH_TYPE_F1_XL: ret = stlink_write_option_control_register_f0(sl, option_cr); @@ -1009,6 +1111,9 @@ int32_t stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { } switch (sl->chip_id) { + case STM32_CHIPID_C011xx: + case STM32_CHIPID_C031xx: + return stlink_read_option_bytes_c0(sl, option_byte); case STM32_CHIPID_F2: return stlink_read_option_bytes_f2(sl, option_byte); case STM32_CHIPID_F4: From eb083ae7539eccd3532156a829b3a8008736485b Mon Sep 17 00:00:00 2001 From: rcubee Date: Sat, 11 Nov 2023 17:40:28 +0100 Subject: [PATCH 1411/1435] removed redundant lines --- src/stlink-lib/option_bytes.c | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c index 2ee45c901..d49c346ef 100644 --- a/src/stlink-lib/option_bytes.c +++ b/src/stlink-lib/option_bytes.c @@ -79,38 +79,10 @@ static int32_t stlink_write_option_control_register_c0(stlink_t *sl, uint32_t op * @return 0 on success, -ve on failure. */ static int32_t stlink_write_option_bytes_c0(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { -#if 0 - uint32_t val; - int32_t ret = 0; - (void)len; - uint32_t data; - - clear_flash_error(sl); - - write_uint32((unsigned char *)&data, *(uint32_t *)(base)); - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - stlink_write_debug32(sl, FLASH_C0_OPTR, data); - - stlink_read_debug32(sl, FLASH_C0_CR, &val); - val |= (1 << FLASH_C0_CR_OPTSTRT); - stlink_write_debug32(sl, FLASH_C0_CR, val); - - wait_flash_busy(sl); - - ret = check_flash_error(sl); - - // trigger the load of option bytes into option registers - stlink_read_debug32(sl, FLASH_C0_CR, &val); - val |= (1 << FLASH_C0_CR_OBL_LAUNCH); - stlink_write_debug32(sl, FLASH_C0_CR, val); - - return (ret); -#else (void)addr; (void)len; return stlink_write_option_control_register_c0(sl, *(uint32_t*)base); -#endif } /** From 4a7b8cdb2678e64fccedf4f49508c4f5ce80868e Mon Sep 17 00:00:00 2001 From: rcubee Date: Sat, 11 Nov 2023 18:19:04 +0100 Subject: [PATCH 1412/1435] removed the patch file itself --- c0.patch | 618 ------------------------------------------------------- 1 file changed, 618 deletions(-) delete mode 100644 c0.patch diff --git a/c0.patch b/c0.patch deleted file mode 100644 index 5b59834d6..000000000 --- a/c0.patch +++ /dev/null @@ -1,618 +0,0 @@ -diff --git a/doc/supported_devices.md b/doc/supported_devices.md -index 2e96dcd..103c7fb 100644 ---- a/doc/supported_devices.md -+++ b/doc/supported_devices.md -@@ -6,6 +6,7 @@ More commonly these are: - | Product-Family | ARM Cortex Core | Product Line | - | -------------- | --------------- | ---------------------------------------------------------- | - | STM32F0 | M0 | | -+| STM32C0 | M0+ | | - | STM32G0 | M0+ | | - | STM32L0 | M0+ | | - | STM32F10**0** | M3 | Value line | -diff --git a/inc/stm32.h b/inc/stm32.h -index cf9a8a2..017ea0a 100644 ---- a/inc/stm32.h -+++ b/inc/stm32.h -@@ -51,17 +51,18 @@ enum stm32_core_id { - /* STM32 flash types */ - enum stm32_flash_type { - STM32_FLASH_TYPE_UNKNOWN = 0, -- STM32_FLASH_TYPE_F0_F1_F3 = 1, -- STM32_FLASH_TYPE_F1_XL = 2, -- STM32_FLASH_TYPE_F2_F4 = 3, -- STM32_FLASH_TYPE_F7 = 4, -- STM32_FLASH_TYPE_G0 = 5, -- STM32_FLASH_TYPE_G4 = 6, -- STM32_FLASH_TYPE_H7 = 7, -- STM32_FLASH_TYPE_L0_L1 = 8, -- STM32_FLASH_TYPE_L4 = 9, -- STM32_FLASH_TYPE_L5_U5_H5 = 10, -- STM32_FLASH_TYPE_WB_WL = 11, -+ STM32_FLASH_TYPE_C0 = 1, -+ STM32_FLASH_TYPE_F0_F1_F3 = 2, -+ STM32_FLASH_TYPE_F1_XL = 3, -+ STM32_FLASH_TYPE_F2_F4 = 4, -+ STM32_FLASH_TYPE_F7 = 5, -+ STM32_FLASH_TYPE_G0 = 6, -+ STM32_FLASH_TYPE_G4 = 7, -+ STM32_FLASH_TYPE_H7 = 8, -+ STM32_FLASH_TYPE_L0_L1 = 9, -+ STM32_FLASH_TYPE_L4 = 10, -+ STM32_FLASH_TYPE_L5_U5_H5 = 11, -+ STM32_FLASH_TYPE_WB_WL = 12, - }; - - /* STM32 chip-ids */ -@@ -102,6 +103,7 @@ enum stm32_chipids { - STM32_CHIPID_F0 = 0x440, - STM32_CHIPID_F412 = 0x441, - STM32_CHIPID_F09x = 0x442, -+ STM32_CHIPID_C011xx = 0x443, /* RM0490 (revision 3), section 26.10.1 "DBG device ID code register (DBG_IDCODE)" */ - STM32_CHIPID_F0xx_SMALL = 0x444, - STM32_CHIPID_F04 = 0x445, - STM32_CHIPID_F303_HD = 0x446, /* high density */ -@@ -111,6 +113,7 @@ enum stm32_chipids { - STM32_CHIPID_H74xxx = 0x450, /* RM0433, p.3189 */ - STM32_CHIPID_F76xxx = 0x451, - STM32_CHIPID_F72xxx = 0x452, /* Nucleo F722ZE board */ -+ STM32_CHIPID_C031xx = 0x453, /* RM0490 (revision 3), section 26.10.1 "DBG device ID code register (DBG_IDCODE)" */ - STM32_CHIPID_G0_CAT4 = 0x456, /* G051/G061 */ - STM32_CHIPID_L0_CAT1 = 0x457, - STM32_CHIPID_F410 = 0x458, -@@ -136,6 +139,8 @@ enum stm32_chipids { - }; - - /* Constant STM32 option bytes base memory address */ -+#define STM32_C0_OPTION_BYTES_BASE ((uint32_t)0x1fff7800) -+ - #define STM32_F4_OPTION_BYTES_BASE ((uint32_t)0x40023c14) - - #define STM32_H7_OPTION_BYTES_BASE ((uint32_t)0x5200201c) -@@ -189,6 +194,9 @@ enum stm32_chipids { - #define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11 - #define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12 - -+#define STM32C0_RCC_AHBENR 0x40021038 // RM0490 (revision 3), section 5.4.25 "RCC register map" -+#define STM32C0_RCC_DMAEN 0x00000001 // DMAEN // RM0490 (revision 3), section 5.4.25 "RCC register map" -+ - #define STM32F1_RCC_AHBENR 0x40021014 - #define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN - -diff --git a/inc/stm32flash.h b/inc/stm32flash.h -index 69c6206..b5e47e0 100644 ---- a/inc/stm32flash.h -+++ b/inc/stm32flash.h -@@ -58,6 +58,30 @@ - #define FLASH_OBR_OFF ((uint32_t)0x1c) - #define FLASH_WRPR_OFF ((uint32_t)0x20) - -+// == STM32C0 == (RM0490) -+// C0 Flash registers -+#define FLASH_C0_REGS_ADDR ((uint32_t)0x40022000) -+#define FLASH_C0_KEYR (FLASH_C0_REGS_ADDR + 0x08) -+#define FLASH_C0_OPT_KEYR (FLASH_C0_REGS_ADDR + 0x0C) -+#define FLASH_C0_SR (FLASH_C0_REGS_ADDR + 0x10) -+#define FLASH_C0_CR (FLASH_C0_REGS_ADDR + 0x14) -+#define FLASH_C0_OPTR (FLASH_C0_REGS_ADDR + 0x20) -+ -+// C0 Flash control register -+#define FLASH_C0_CR_PNB 3 -+#define FLASH_C0_CR_STRT 16 -+#define FLASH_C0_CR_OPTSTRT 17 -+#define FLASH_C0_CR_OBL_LAUNCH 27 -+#define FLASH_C0_CR_OPTLOCK 30 -+#define FLASH_C0_CR_LOCK 31 -+ -+// C0 Flash status register -+#define FLASH_C0_SR_ERROR_MASK 0xC3F8 // [15:14], [9:3] -+#define FLASH_C0_SR_PROGERR 3 -+#define FLASH_C0_SR_WRPERR 4 -+#define FLASH_C0_SR_PGAERR 5 -+#define FLASH_C0_SR_BSY 16 -+ - // == STM32F0 == - #define FLASH_F0_OPTKEY1 0x45670123 - #define FLASH_F0_OPTKEY2 0xcdef89ab -diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c -index 06edb26..86f01f4 100644 ---- a/src/stlink-lib/chipid.c -+++ b/src/stlink-lib/chipid.c -@@ -97,7 +97,9 @@ void process_chipfile(char *fname) { - buf[strlen(buf) - 1] = 0; // chomp newline - sscanf(buf, "%*s %n", &nc); - // Match human readable flash_type with enum stm32_flash_type { }. -- if (strcmp(value, "F0_F1_F3") == 0) { -+ if(strcmp(value, "C0") == 0) { -+ ts->flash_type = STM32_FLASH_TYPE_C0; -+ } else if (strcmp(value, "F0_F1_F3") == 0) { - ts->flash_type = STM32_FLASH_TYPE_F0_F1_F3; - } else if (strcmp(value, "F1_XL") == 0) { - ts->flash_type = STM32_FLASH_TYPE_F1_XL; -diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c -index 3038b53..491cf46 100644 ---- a/src/stlink-lib/common_flash.c -+++ b/src/stlink-lib/common_flash.c -@@ -46,7 +46,9 @@ uint32_t get_stm32l0_flash_base(stlink_t *sl) { - uint32_t read_flash_cr(stlink_t *sl, uint32_t bank) { - uint32_t reg, res; - -- if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { -+ if (sl->flash_type == STM32_FLASH_TYPE_C0) { -+ reg = FLASH_C0_CR; -+ } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - reg = FLASH_F4_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - reg = FLASH_F7_CR; -@@ -77,7 +79,10 @@ void lock_flash(stlink_t *sl) { - uint32_t cr_lock_shift = 0, cr_reg = 0, n = 0, cr2_reg = 0; - uint32_t cr_mask = 0xffffffffu; - -- if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { -+ if (sl->flash_type == STM32_FLASH_TYPE_C0) { -+ cr_reg = FLASH_C0_CR; -+ cr_lock_shift = FLASH_C0_CR_LOCK; -+ } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { - cr_reg = FLASH_CR; - cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { -@@ -132,8 +137,10 @@ void lock_flash(stlink_t *sl) { - static inline int32_t write_flash_sr(stlink_t *sl, uint32_t bank, uint32_t val) { - uint32_t sr_reg; - -- if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || -- (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { -+ if (sl->flash_type == STM32_FLASH_TYPE_C0) { -+ sr_reg = FLASH_C0_SR; -+ } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3 || -+ sl->flash_type == STM32_FLASH_TYPE_F1_XL) { - sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; - } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - sr_reg = FLASH_F4_SR; -@@ -162,6 +169,9 @@ static inline int32_t write_flash_sr(stlink_t *sl, uint32_t bank, uint32_t val) - - void clear_flash_error(stlink_t *sl) { - switch (sl->flash_type) { -+ case STM32_FLASH_TYPE_C0: -+ write_flash_sr(sl, BANK_1, FLASH_C0_SR_ERROR_MASK); -+ break; - case STM32_FLASH_TYPE_F0_F1_F3: - write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); - break; -@@ -205,8 +215,10 @@ void clear_flash_error(stlink_t *sl) { - uint32_t read_flash_sr(stlink_t *sl, uint32_t bank) { - uint32_t res, sr_reg; - -- if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || -- (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { -+ if (sl->flash_type == STM32_FLASH_TYPE_C0) { -+ sr_reg = FLASH_C0_SR; -+ } else if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || -+ (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { - sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; - } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - sr_reg = FLASH_F4_SR; -@@ -238,9 +250,11 @@ uint32_t is_flash_busy(stlink_t *sl) { - uint32_t sr_busy_shift; - uint32_t res; - -- if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || -- (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || -- (sl->flash_type == STM32_FLASH_TYPE_L0_L1)) { -+ if (sl->flash_type == STM32_FLASH_TYPE_C0) { -+ sr_busy_shift = FLASH_C0_SR_BSY; -+ } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3 || -+ sl->flash_type == STM32_FLASH_TYPE_F1_XL || -+ sl->flash_type == STM32_FLASH_TYPE_L0_L1) { - sr_busy_shift = FLASH_SR_BSY; - } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - sr_busy_shift = FLASH_F4_SR_BSY; -@@ -286,6 +300,12 @@ int32_t check_flash_error(stlink_t *sl) { - WRPERR = PROGERR = PGAERR = 0; - - switch (sl->flash_type) { -+ case STM32_FLASH_TYPE_C0: -+ res = read_flash_sr(sl, BANK_1) & FLASH_C0_SR_ERROR_MASK; -+ WRPERR = (1 << FLASH_C0_SR_WRPERR); -+ PROGERR = (1 << FLASH_C0_SR_PROGERR); -+ PGAERR = (1 << FLASH_C0_SR_PGAERR); -+ break; - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; -@@ -382,8 +402,11 @@ static inline uint32_t is_flash_locked(stlink_t *sl) { - uint32_t cr_reg; - uint32_t n; - -- if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || -- (sl->flash_type == STM32_FLASH_TYPE_F1_XL)) { -+ if (sl->flash_type == STM32_FLASH_TYPE_C0) { -+ cr_reg = FLASH_C0_CR; -+ cr_lock_shift = FLASH_C0_CR_LOCK; -+ } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3 || -+ sl->flash_type == STM32_FLASH_TYPE_F1_XL) { - cr_reg = FLASH_CR; - cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { -@@ -429,7 +452,9 @@ static void unlock_flash(stlink_t *sl) { - * definitive lock of the FPEC block until next reset. - */ - -- if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { -+ if (sl->flash_type == STM32_FLASH_TYPE_C0) { -+ key_reg = FLASH_C0_KEYR; -+ } else if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) { - key_reg = FLASH_KEYR; - } else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) { - key_reg = FLASH_KEYR; -@@ -497,6 +522,10 @@ int32_t lock_flash_option(stlink_t *sl) { - int32_t active_bit_level = 1; - - switch (sl->flash_type) { -+ case STM32_FLASH_TYPE_C0: -+ optcr_reg = FLASH_C0_CR; -+ optlock_shift = FLASH_C0_CR_OPTLOCK; -+ break; - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - optcr_reg = FLASH_CR; -@@ -574,6 +603,10 @@ static bool is_flash_option_locked(stlink_t *sl) { - uint32_t n; - - switch (sl->flash_type) { -+ case STM32_FLASH_TYPE_C0: -+ optcr_reg = FLASH_C0_CR; -+ optlock_shift = FLASH_C0_CR_OPTLOCK; -+ break; - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - optcr_reg = FLASH_CR; -@@ -633,6 +666,9 @@ static int32_t unlock_flash_option(stlink_t *sl) { - uint32_t optkey2 = FLASH_OPTKEY2; - - switch (sl->flash_type) { -+ case STM32_FLASH_TYPE_C0: -+ optkey_reg = FLASH_C0_OPT_KEYR; -+ break; - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - optkey_reg = FLASH_OPTKEYR; -@@ -726,7 +762,9 @@ void clear_flash_cr_pg(stlink_t *sl, uint32_t bank) { - uint32_t cr_reg, n; - uint32_t bit = FLASH_CR_PG; - -- if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { -+ if (sl->flash_type == STM32_FLASH_TYPE_C0) { -+ cr_reg = FLASH_C0_CR; -+ } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - cr_reg = FLASH_F4_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; -@@ -802,8 +840,10 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, uint32_t bank) { - static void set_flash_cr_per(stlink_t *sl, uint32_t bank) { - uint32_t cr_reg, val; - -- if (sl->flash_type == STM32_FLASH_TYPE_G0 || -- sl->flash_type == STM32_FLASH_TYPE_G4) { -+ if (sl->flash_type == STM32_FLASH_TYPE_C0) { -+ cr_reg = FLASH_C0_CR; -+ } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || -+ sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = FLASH_Gx_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { - cr_reg = FLASH_L5_NSCR; -@@ -821,8 +861,10 @@ static void set_flash_cr_per(stlink_t *sl, uint32_t bank) { - static void clear_flash_cr_per(stlink_t *sl, uint32_t bank) { - uint32_t cr_reg; - -- if (sl->flash_type == STM32_FLASH_TYPE_G0 || -- sl->flash_type == STM32_FLASH_TYPE_G4) { -+ if (sl->flash_type == STM32_FLASH_TYPE_C0) { -+ cr_reg = FLASH_C0_CR; -+ } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || -+ sl->flash_type == STM32_FLASH_TYPE_G4) { - cr_reg = FLASH_Gx_CR; - } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { - cr_reg = FLASH_L5_NSCR; -@@ -855,7 +897,10 @@ static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { - static void set_flash_cr_strt(stlink_t *sl, uint32_t bank) { - uint32_t val, cr_reg, cr_strt; - -- if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { -+ if (sl->flash_type == STM32_FLASH_TYPE_C0) { -+ cr_reg = FLASH_C0_CR; -+ cr_strt = 1 << FLASH_C0_CR_STRT; -+ } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - cr_reg = FLASH_F4_CR; - cr_strt = 1 << FLASH_F4_CR_STRT; - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { -@@ -890,7 +935,11 @@ static void set_flash_cr_strt(stlink_t *sl, uint32_t bank) { - static void set_flash_cr_mer(stlink_t *sl, bool v, uint32_t bank) { - uint32_t val, cr_reg, cr_mer, cr_pg; - -- if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { -+ if (sl->flash_type == STM32_FLASH_TYPE_C0) { -+ cr_reg = FLASH_C0_CR; -+ cr_mer = 1 << FLASH_CR_MER; -+ cr_pg = 1 << FLASH_CR_PG; -+ } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - cr_reg = FLASH_F4_CR; - cr_mer = 1 << FLASH_CR_MER; - cr_pg = 1 << FLASH_CR_PG; -@@ -1062,7 +1111,8 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4 || - sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5 || -- sl->flash_type == STM32_FLASH_TYPE_WB_WL) { -+ sl->flash_type == STM32_FLASH_TYPE_WB_WL || -+ sl->flash_type == STM32_FLASH_TYPE_C0) { - uint32_t val; - unlock_flash_if(sl); - set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit -@@ -1107,6 +1157,14 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - val |= ((flash_page & 0xFF) << 3); - - stlink_write_debug32(sl, FLASH_WB_CR, val); -+ } else if (sl->flash_type == STM32_FLASH_TYPE_C0) { -+ uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); -+ stlink_read_debug32(sl, FLASH_C0_CR, &val); -+ -+ val &= ~(0xF << FLASH_C0_CR_PNB); -+ val |= ((flash_page & 0xF) << FLASH_C0_CR_PNB); -+ -+ stlink_write_debug32(sl, FLASH_C0_CR, val); - } - - set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit -diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c -index ea1f6d9..0d01dfd 100644 ---- a/src/stlink-lib/flash_loader.c -+++ b/src/stlink-lib/flash_loader.c -@@ -491,12 +491,15 @@ static void set_flash_cr_pg(stlink_t *sl, uint32_t bank) { - - x = read_flash_cr(sl, bank); - -- if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { -+ if (sl->flash_type == STM32_FLASH_TYPE_C0) { -+ cr_reg = FLASH_C0_CR; -+ x |= (1 << FLASH_CR_PG); -+ } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { - cr_reg = FLASH_F4_CR; -- x |= 1 << FLASH_CR_PG; -+ x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; -- x |= 1 << FLASH_CR_PG; -+ x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STM32_FLASH_TYPE_L4) { - cr_reg = FLASH_L4_CR; - x &= ~FLASH_L4_CR_OPBITS; -@@ -528,6 +531,10 @@ static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int32_t bckpRstr) { - rcc = rcc_dma_mask = value = 0; - - switch (sl->flash_type) { -+ case STM32_FLASH_TYPE_C0: -+ rcc = STM32C0_RCC_AHBENR; -+ rcc_dma_mask = STM32C0_RCC_DMAEN; -+ break; - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - rcc = STM32F1_RCC_AHBENR; -@@ -639,8 +646,9 @@ int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || - sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4 || -- sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { -- ILOG("Starting Flash write for WB/G0/G4/L5/U5/H5\n"); -+ sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5 || -+ sl->flash_type == STM32_FLASH_TYPE_C0) { -+ ILOG("Starting Flash write for WB/G0/G4/L5/U5/H5/C0\n"); - - unlock_flash_if(sl); // unlock flash if necessary - set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit -@@ -720,6 +728,7 @@ int32_t stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { - - int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t *base, uint32_t len) { - uint32_t off; -+ - if ((sl->flash_type == STM32_FLASH_TYPE_F2_F4) || - (sl->flash_type == STM32_FLASH_TYPE_F7) || - (sl->flash_type == STM32_FLASH_TYPE_L4)) { -@@ -737,13 +746,14 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t - } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL || - sl->flash_type == STM32_FLASH_TYPE_G0 || - sl->flash_type == STM32_FLASH_TYPE_G4 || -- sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { -+ sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5 || -+ sl->flash_type == STM32_FLASH_TYPE_C0) { - DLOG("Starting %3u page write\n", len / sl->flash_pgsz); - for (off = 0; off < len; off += sizeof(uint32_t)) { - uint32_t data; - - if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { -- fprintf(stdout, "\r%3u/%3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); -+ fprintf(stdout, "\r%3u/%-3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); - fflush(stdout); - } - -@@ -782,7 +792,7 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t - uint32_t data; - - if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { -- fprintf(stdout, "\r%3u/%3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); -+ fprintf(stdout, "\r%3u/%-3u pages written", (off / sl->flash_pgsz + 1), (len / sl->flash_pgsz)); - fflush(stdout); - } - -@@ -819,7 +829,7 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t - if (sl->verbose >= 1) { - // show progress; writing procedure is slow and previous errors are - // misleading -- fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, -+ fprintf(stdout, "\r%3u/%-3u pages written", ++write_block_count, - (len + sl->flash_pgsz - 1) / sl->flash_pgsz); - fflush(stdout); - } -@@ -856,7 +866,8 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t - int32_t stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { - uint32_t dhcsr; - -- if ((sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || -+ if ((sl->flash_type == STM32_FLASH_TYPE_C0) || -+ (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) || - (sl->flash_type == STM32_FLASH_TYPE_F1_XL) || - (sl->flash_type == STM32_FLASH_TYPE_F2_F4) || - (sl->flash_type == STM32_FLASH_TYPE_F7) || -diff --git a/src/stlink-lib/option_bytes.c b/src/stlink-lib/option_bytes.c -index ee03dce..2ee45c9 100644 ---- a/src/stlink-lib/option_bytes.c -+++ b/src/stlink-lib/option_bytes.c -@@ -18,6 +18,101 @@ - #include "md5.h" - #include "read_write.h" - -+/** -+ * Read option control register C0 -+ * @param sl -+ * @param option_byte -+ * @return 0 on success, -ve on failure. -+ */ -+static int32_t stlink_read_option_control_register_c0(stlink_t *sl, uint32_t *option_byte) { -+ return stlink_read_debug32(sl, FLASH_C0_OPTR, option_byte); -+} -+ -+/** -+ * Read option bytes C0 -+ * @param sl -+ * @param option_byte -+ * @return 0 on success, -ve on failure. -+ */ -+static int32_t stlink_read_option_bytes_c0(stlink_t *sl, uint32_t *option_byte) { -+ return stlink_read_option_control_register_c0(sl, option_byte); -+} -+ -+/** -+ * Write option control register C0 -+ * @param sl -+ * @param option_cr -+ * @return 0 on success, -ve on failure. -+ */ -+static int32_t stlink_write_option_control_register_c0(stlink_t *sl, uint32_t option_cr) { -+ int32_t ret = 0; -+ -+ clear_flash_error(sl); -+ -+ if ((ret = stlink_write_debug32(sl, FLASH_C0_OPTR, option_cr))) -+ return ret; -+ -+ wait_flash_busy(sl); -+ -+ uint32_t cr_reg = (1 << FLASH_C0_CR_OPTSTRT); -+ if ((ret = stlink_write_debug32(sl, FLASH_C0_CR, cr_reg))) -+ return ret; -+ -+ wait_flash_busy(sl); -+ -+ if ((ret = check_flash_error(sl))) -+ return ret; -+ -+ // trigger the load of option bytes into option registers -+ cr_reg = (1 << FLASH_C0_CR_OBL_LAUNCH); -+ stlink_write_debug32(sl, FLASH_C0_CR, cr_reg); -+ -+ return ret; -+} -+ -+/** -+ * Write option bytes C0 -+ * @param sl -+ * @param addr of the memory mapped option bytes -+ * @param base option bytes -+ * @param len of option bytes -+ * @return 0 on success, -ve on failure. -+ */ -+static int32_t stlink_write_option_bytes_c0(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len) { -+#if 0 -+ uint32_t val; -+ int32_t ret = 0; -+ (void)len; -+ uint32_t data; -+ -+ clear_flash_error(sl); -+ -+ write_uint32((unsigned char *)&data, *(uint32_t *)(base)); -+ WLOG("Writing option bytes %#10x to %#10x\n", data, addr); -+ stlink_write_debug32(sl, FLASH_C0_OPTR, data); -+ -+ stlink_read_debug32(sl, FLASH_C0_CR, &val); -+ val |= (1 << FLASH_C0_CR_OPTSTRT); -+ stlink_write_debug32(sl, FLASH_C0_CR, val); -+ -+ wait_flash_busy(sl); -+ -+ ret = check_flash_error(sl); -+ -+ // trigger the load of option bytes into option registers -+ stlink_read_debug32(sl, FLASH_C0_CR, &val); -+ val |= (1 << FLASH_C0_CR_OBL_LAUNCH); -+ stlink_write_debug32(sl, FLASH_C0_CR, val); -+ -+ return (ret); -+#else -+ (void)addr; -+ (void)len; -+ -+ return stlink_write_option_control_register_c0(sl, *(uint32_t*)base); -+#endif -+} -+ - /** - * Read option control register F0 - * @param sl -@@ -745,7 +840,6 @@ int32_t stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte) { - return stlink_read_debug32(sl, sl->option_base, option_byte); - } - -- - /** - * Write option bytes - * @param sl -@@ -785,6 +879,9 @@ int32_t stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base - } - - switch (sl->flash_type) { -+ case STM32_FLASH_TYPE_C0: -+ ret = stlink_write_option_bytes_c0(sl, addr, base, len); -+ break; - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - ret = stlink_write_option_bytes_f0(sl, addr, base, len); -@@ -870,6 +967,8 @@ int32_t stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byt - } - - switch (sl->flash_type) { -+ case STM32_FLASH_TYPE_C0: -+ return stlink_read_option_control_register_c0(sl, option_byte); - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - return stlink_read_option_control_register_f0(sl, option_byte); -@@ -904,6 +1003,9 @@ int32_t stlink_write_option_control_register32(stlink_t *sl, uint32_t option_cr) - } - - switch (sl->flash_type) { -+ case STM32_FLASH_TYPE_C0: -+ ret = stlink_write_option_control_register_c0(sl, option_cr); -+ break; - case STM32_FLASH_TYPE_F0_F1_F3: - case STM32_FLASH_TYPE_F1_XL: - ret = stlink_write_option_control_register_f0(sl, option_cr); -@@ -1009,6 +1111,9 @@ int32_t stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { - } - - switch (sl->chip_id) { -+ case STM32_CHIPID_C011xx: -+ case STM32_CHIPID_C031xx: -+ return stlink_read_option_bytes_c0(sl, option_byte); - case STM32_CHIPID_F2: - return stlink_read_option_bytes_f2(sl, option_byte); - case STM32_CHIPID_F4: From e286f243efaf73e4fec1cf99e532e695c6383316 Mon Sep 17 00:00:00 2001 From: Marcelo Barros de Almeida Date: Tue, 14 Nov 2023 00:27:19 -0300 Subject: [PATCH 1413/1435] Fixing support for U5 chips (original U5x5.chip was not handling all U5 chips ) --- config/chips/U535_U545.chip | 14 ++++++++++++++ config/chips/U55Fx_U5Gx.chip | 14 ++++++++++++++ config/chips/{U5x5.chip => U575_U585.chip} | 6 +++--- config/chips/U59x_U5Ax.chip | 14 ++++++++++++++ inc/stm32.h | 5 ++++- src/stlink-lib/common_flash.c | 12 ++++++++---- 6 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 config/chips/U535_U545.chip create mode 100644 config/chips/U55Fx_U5Gx.chip rename config/chips/{U5x5.chip => U575_U585.chip} (67%) create mode 100644 config/chips/U59x_U5Ax.chip diff --git a/config/chips/U535_U545.chip b/config/chips/U535_U545.chip new file mode 100644 index 000000000..84ca3c914 --- /dev/null +++ b/config/chips/U535_U545.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32U535 / STM32U545 device +# +dev_type STM32U535_U545 +ref_manual_id 0456 +chip_id 0x455 // STM32U535/545 +flash_type L5_U5_H5 +flash_size_reg 0x0bfa07a0 +flash_pagesize 0x2000 // 8 KB +sram_size 0x44800 // 274 KB +bootrom_base 0x0bf90000 +bootrom_size 0x8000 // 32 KB +option_base 0x0 +option_size 0x0 +flags none diff --git a/config/chips/U55Fx_U5Gx.chip b/config/chips/U55Fx_U5Gx.chip new file mode 100644 index 000000000..6c7eca784 --- /dev/null +++ b/config/chips/U55Fx_U5Gx.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32U5Fx / STM32U5Gx device +# +dev_type STM32U5Fx_U5Gx +ref_manual_id 0456 +chip_id 0x476 // STM32U5Fx5/5Gx +flash_type L5_U5_H5 +flash_size_reg 0x0bfa07a0 +flash_pagesize 0x2000 // 8 KB +sram_size 0x2f4800 // 3026 KB +bootrom_base 0x0bf90000 +bootrom_size 0x8000 // 32 KB +option_base 0x0 +option_size 0x0 +flags none diff --git a/config/chips/U5x5.chip b/config/chips/U575_U585.chip similarity index 67% rename from config/chips/U5x5.chip rename to config/chips/U575_U585.chip index 82964b1c3..fa2fb86fa 100644 --- a/config/chips/U5x5.chip +++ b/config/chips/U575_U585.chip @@ -1,8 +1,8 @@ -# Chip-ID file for STM32U5x5 device +# Chip-ID file for STM32U575 / STM32U585 device # -dev_type STM32U5x5 +dev_type STM32U575_U585 ref_manual_id 0456 -chip_id 0x482 // STM32_CHIPID_U5x5 +chip_id 0x482 // STM32U575/585 flash_type L5_U5_H5 flash_size_reg 0x0bfa07a0 flash_pagesize 0x2000 // 8 KB diff --git a/config/chips/U59x_U5Ax.chip b/config/chips/U59x_U5Ax.chip new file mode 100644 index 000000000..6be20855e --- /dev/null +++ b/config/chips/U59x_U5Ax.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32U59x / STM32U5Ax device +# +dev_type STM32U59x_U5Ax +ref_manual_id 0456 +chip_id 0x481 // STM32U59x/5Ax +flash_type L5_U5_H5 +flash_size_reg 0x0bfa07a0 +flash_pagesize 0x2000 // 8 KB +sram_size 0x274800 // 2514 KB +bootrom_base 0x0bf90000 +bootrom_size 0x8000 // 32 KB +option_base 0x0 +option_size 0x0 +flags none diff --git a/inc/stm32.h b/inc/stm32.h index cf9a8a2ad..b716ac44e 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -111,6 +111,7 @@ enum stm32_chipids { STM32_CHIPID_H74xxx = 0x450, /* RM0433, p.3189 */ STM32_CHIPID_F76xxx = 0x451, STM32_CHIPID_F72xxx = 0x452, /* Nucleo F722ZE board */ + STM32_CHIPID_U535_U545 = 0x455, /* RM0456, p.3604 */ STM32_CHIPID_G0_CAT4 = 0x456, /* G051/G061 */ STM32_CHIPID_L0_CAT1 = 0x457, STM32_CHIPID_F410 = 0x458, @@ -126,9 +127,11 @@ enum stm32_chipids { STM32_CHIPID_L4Rx = 0x470, /* RM0432, p.2247, found on the STM32L4R9I-DISCO board */ STM32_CHIPID_L4PX = 0x471, /* RM0432, p.2247 */ STM32_CHIPID_L5x2xx = 0x472, /* RM0438, p.2157 */ + STM32_CHIPID_U5Fx_U5Gx = 0x476, /* RM0456, p.3604 */ STM32_CHIPID_G4_CAT4 = 0x479, STM32_CHIPID_H7Ax = 0x480, /* RM0455, p.2863 */ - STM32_CHIPID_U5x5 = 0x482, /* RM0456, p.2991 */ + STM32_CHIPID_U59x_U5Ax = 0x481, /* RM0456, p.3604 */ + STM32_CHIPID_U575_U585 = 0x482, /* RM0456, p.3604 */ STM32_CHIPID_H72x = 0x483, /* RM0468, p.3199 */ STM32_CHIPID_H5xx = 0x484, /* RM0481, p.3085 */ STM32_CHIPID_WB55 = 0x495, diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 3038b53e7..ab754cb77 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -1082,10 +1082,12 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { val &= ~(0x7F << 3); val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); stlink_write_debug32(sl, FLASH_Gx_CR, val); + // STM32L5x2xx has two banks with 2k pages or single with 4k pages + // STM32H5xx, STM32U535, STM32U545, STM32U575 or STM32U585 have 2 banks with 8k pages } else if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5) { uint32_t flash_page; stlink_read_debug32(sl, FLASH_L5_NSCR, &val); - if (sl->flash_pgsz == 0x800 && (flashaddr - STM32_FLASH_BASE) >= sl->flash_size/2) { + if ((sl->flash_pgsz == 0x800 || sl->flash_pgsz == 0x2000) && (flashaddr - STM32_FLASH_BASE) >= sl->flash_size/2) { flash_page = (flashaddr - STM32_FLASH_BASE - sl->flash_size/2) / sl->flash_pgsz; // set bank 2 for erasure val |= (1 << FLASH_L5_NSCR_NSBKER); @@ -1094,9 +1096,11 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { // set bank 1 for erasure val &= ~(1 << FLASH_L5_NSCR_NSBKER); } - // sec 6.9.9 - val &= ~(0x7F << 3); - val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); + // sec 7.9.9 for U5, 6.9.9 for L5 (for L7 we have 7 bits instead 8 bits for U5 but + // the bit position for 8th bit reserved. + // Maybe the best solution is to handle each one separately. + val &= ~(0xFF << 3); + val |= ((flash_page & 0xFF) << 3) | (1 << FLASH_CR_PER); stlink_write_debug32(sl, FLASH_L5_NSCR, val); } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); From 5df53adb2c65f100c307824034b49eccd24931f3 Mon Sep 17 00:00:00 2001 From: Marcelo Barros de Almeida Date: Tue, 14 Nov 2023 07:39:56 -0300 Subject: [PATCH 1414/1435] Missing swo and dualback flags in U6 chip models --- config/chips/U535_U545.chip | 2 +- config/chips/U55Fx_U5Gx.chip | 2 +- config/chips/U575_U585.chip | 2 +- config/chips/U59x_U5Ax.chip | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/chips/U535_U545.chip b/config/chips/U535_U545.chip index 84ca3c914..adc0560dd 100644 --- a/config/chips/U535_U545.chip +++ b/config/chips/U535_U545.chip @@ -11,4 +11,4 @@ bootrom_base 0x0bf90000 bootrom_size 0x8000 // 32 KB option_base 0x0 option_size 0x0 -flags none +flags swo dualbank diff --git a/config/chips/U55Fx_U5Gx.chip b/config/chips/U55Fx_U5Gx.chip index 6c7eca784..b9c79b235 100644 --- a/config/chips/U55Fx_U5Gx.chip +++ b/config/chips/U55Fx_U5Gx.chip @@ -11,4 +11,4 @@ bootrom_base 0x0bf90000 bootrom_size 0x8000 // 32 KB option_base 0x0 option_size 0x0 -flags none +flags swo dualbank diff --git a/config/chips/U575_U585.chip b/config/chips/U575_U585.chip index fa2fb86fa..6724d00f5 100644 --- a/config/chips/U575_U585.chip +++ b/config/chips/U575_U585.chip @@ -11,4 +11,4 @@ bootrom_base 0x0bf90000 bootrom_size 0x10000 // 64 KB option_base 0x0 option_size 0x0 -flags none +flags swo dualbank diff --git a/config/chips/U59x_U5Ax.chip b/config/chips/U59x_U5Ax.chip index 6be20855e..9b45a411c 100644 --- a/config/chips/U59x_U5Ax.chip +++ b/config/chips/U59x_U5Ax.chip @@ -11,4 +11,4 @@ bootrom_base 0x0bf90000 bootrom_size 0x8000 // 32 KB option_base 0x0 option_size 0x0 -flags none +flags swo dualbank From 3fd714052485156f7be332d0da1d8bbc30ccbce8 Mon Sep 17 00:00:00 2001 From: rcubee Date: Tue, 14 Nov 2023 17:30:00 +0100 Subject: [PATCH 1415/1435] forgot to include these --- config/chips/C011xx.chip | 14 ++++++++++++++ config/chips/C031xx.chip | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 config/chips/C011xx.chip create mode 100644 config/chips/C031xx.chip diff --git a/config/chips/C011xx.chip b/config/chips/C011xx.chip new file mode 100644 index 000000000..9124c6a1e --- /dev/null +++ b/config/chips/C011xx.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32C011xx device +# +dev_type STM32C011xx +ref_manual_id 0490 +chip_id 0x453 // STM32_CHIPID_C011xx +flash_type C0 +flash_size_reg 0x1fff75a0 +flash_pagesize 0x800 // 2 KB +sram_size 0x1800 // 6 KB +bootrom_base 0x1fff0000 +bootrom_size 0x1800 // 6 KB +option_base 0x1fff7800 // STM32_C0_OPTION_BYTES_BASE +option_size 0x80 // 128 B +flags none diff --git a/config/chips/C031xx.chip b/config/chips/C031xx.chip new file mode 100644 index 000000000..30017ae90 --- /dev/null +++ b/config/chips/C031xx.chip @@ -0,0 +1,14 @@ +# Chip-ID file for STM32C031xx device +# +dev_type STM32C031xx +ref_manual_id 0490 +chip_id 0x453 // STM32_CHIPID_C031xx +flash_type C0 +flash_size_reg 0x1fff75a0 +flash_pagesize 0x800 // 2 KB +sram_size 0x3000 // 12 KB +bootrom_base 0x1fff0000 +bootrom_size 0x1800 // 6 KB +option_base 0x1fff7800 // STM32_C0_OPTION_BYTES_BASE +option_size 0x80 // 128 B +flags none From cf840b5f3d8d4154efb8058adeddb20e14c934cd Mon Sep 17 00:00:00 2001 From: rcubee Date: Tue, 14 Nov 2023 17:38:12 +0100 Subject: [PATCH 1416/1435] fixed formatting --- config/chips/C011xx.chip | 4 ++-- config/chips/C031xx.chip | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/chips/C011xx.chip b/config/chips/C011xx.chip index 9124c6a1e..b961a18f8 100644 --- a/config/chips/C011xx.chip +++ b/config/chips/C011xx.chip @@ -9,6 +9,6 @@ flash_pagesize 0x800 // 2 KB sram_size 0x1800 // 6 KB bootrom_base 0x1fff0000 bootrom_size 0x1800 // 6 KB -option_base 0x1fff7800 // STM32_C0_OPTION_BYTES_BASE -option_size 0x80 // 128 B +option_base 0x1fff7800 // STM32_C0_OPTION_BYTES_BASE +option_size 0x80 // 128 B flags none diff --git a/config/chips/C031xx.chip b/config/chips/C031xx.chip index 30017ae90..921c1f1fa 100644 --- a/config/chips/C031xx.chip +++ b/config/chips/C031xx.chip @@ -9,6 +9,6 @@ flash_pagesize 0x800 // 2 KB sram_size 0x3000 // 12 KB bootrom_base 0x1fff0000 bootrom_size 0x1800 // 6 KB -option_base 0x1fff7800 // STM32_C0_OPTION_BYTES_BASE -option_size 0x80 // 128 B +option_base 0x1fff7800 // STM32_C0_OPTION_BYTES_BASE +option_size 0x80 // 128 B flags none From 0d16dbac9a7cb89dddc92f1c5b1a1274362d6906 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 22 Nov 2023 01:13:44 +0100 Subject: [PATCH 1417/1435] CodeQL Workflow Maintenance - Removed incompatible workflow - Updated existing workflow --- .github/workflows/codeql-analysis.yml | 14 +-- .github/workflows/codeql-buildscript.sh | 6 -- .github/workflows/codeql.yml | 126 ------------------------ .github/workflows/fail_on_error.py | 34 ------- 4 files changed, 7 insertions(+), 173 deletions(-) delete mode 100644 .github/workflows/codeql-buildscript.sh delete mode 100644 .github/workflows/codeql.yml delete mode 100755 .github/workflows/fail_on_error.py diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 55a21294f..94f256249 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,12 +13,12 @@ name: "CodeQL" on: push: - branches: [ testing, develop, master ] + branches: [testing, develop, master] pull_request: # The branches below must be a subset of the branches above - branches: [ testing, develop ] + branches: [testing, develop] schedule: - - cron: '00 20 * * 1' + - cron: "00 20 * * 1" jobs: analyze: @@ -28,7 +28,7 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'cpp' ] + language: ["cpp"] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed @@ -41,7 +41,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -52,7 +52,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -66,4 +66,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/codeql-buildscript.sh b/.github/workflows/codeql-buildscript.sh deleted file mode 100644 index d626d4283..000000000 --- a/.github/workflows/codeql-buildscript.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -sudo apt-get -y update -sudo apt-get -y install libusb-1.0 libusb-1.0-0-dev libgtk-3-dev -make clean -make release -j$(nproc) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 816492278..000000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,126 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - # push: - # branches: [ "main", "master" ] - schedule: - - cron: '0 0 * * *' - pull_request: - branches: '*' - -jobs: - analyze: - name: Analyze - # Runner size impacts CodeQL analysis time. To learn more, please see: - # - https://gh.io/recommended-hardware-resources-for-running-codeql - # - https://gh.io/supported-runners-and-hardware-resources - # - https://gh.io/using-larger-runners - # Consider using larger runners for possible analysis time improvements. - runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-20.04' }} - timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'cpp' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ] - # Use only 'java' to analyze code written in Java, Kotlin or both - # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - submodules: recursive - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - queries: security-and-quality - - - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). - # If this step fails, then you should remove it and run the build manually (see below) - #- name: Autobuild - # uses: github/codeql-action/autobuild@v2 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - - run: | - ./.github/workflows/codeql-buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" - upload: false - id: step1 - - # Filter out rules with low severity or high false positve rate - # Also filter out warnings in third-party code - - name: Filter out unwanted errors and warnings - uses: advanced-security/filter-sarif@v1 - with: - patterns: | - -**:cpp/path-injection - -**:cpp/world-writable-file-creation - -**:cpp/poorly-documented-function - -**:cpp/potentially-dangerous-function - -**:cpp/use-of-goto - -**:cpp/integer-multiplication-cast-to-long - -**:cpp/comparison-with-wider-type - -**:cpp/leap-year/* - -**:cpp/ambiguously-signed-bit-field - -**:cpp/suspicious-pointer-scaling - -**:cpp/suspicious-pointer-scaling-void - -**:cpp/unsigned-comparison-zero - -**/cmake*/Modules/** - input: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif - output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif - - - name: Upload CodeQL results to code scanning - uses: github/codeql-action/upload-sarif@v2 - with: - sarif_file: ${{ steps.step1.outputs.sarif-output }} - category: "/language:${{matrix.language}}" - - - name: Upload CodeQL results as an artifact - if: success() || failure() - uses: actions/upload-artifact@v3 - with: - name: codeql-results - path: ${{ steps.step1.outputs.sarif-output }} - retention-days: 5 - - - name: Fail if an error is found - run: | - ./.github/workflows/fail_on_error.py \ - ${{ steps.step1.outputs.sarif-output }}/cpp.sarif diff --git a/.github/workflows/fail_on_error.py b/.github/workflows/fail_on_error.py deleted file mode 100755 index 29791742b..000000000 --- a/.github/workflows/fail_on_error.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python3 - -import json -import sys - -# Return whether SARIF file contains error-level results -def codeql_sarif_contain_error(filename): - with open(filename, 'r') as f: - s = json.load(f) - - for run in s.get('runs', []): - rules_metadata = run['tool']['driver']['rules'] - if not rules_metadata: - rules_metadata = run['tool']['extensions'][0]['rules'] - - for res in run.get('results', []): - if 'ruleIndex' in res: - rule_index = res['ruleIndex'] - elif 'rule' in res and 'index' in res['rule']: - rule_index = res['rule']['index'] - else: - continue - try: - rule_level = rules_metadata[rule_index]['defaultConfiguration']['level'] - except IndexError as e: - print(e, rule_index, len(rules_metadata)) - else: - if rule_level == 'error': - return True - return False - -if __name__ == "__main__": - if codeql_sarif_contain_error(sys.argv[1]): - sys.exit(1) From 033007fd2713aba630d28c706499959dc8792277 Mon Sep 17 00:00:00 2001 From: Mirko Matonti Date: Thu, 23 Nov 2023 17:46:09 +0000 Subject: [PATCH 1418/1435] pr adjustment --- src/stlink-lib/common_flash.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 5005a632f..7172352ee 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -1312,7 +1312,7 @@ int32_t stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { */ /* In case the address is within the OTP area we use a different flash method */ - if(addr >= sl->otp_base && addr <= sl->otp_base + sl->otp_size) { + if(addr >= sl->otp_base && addr < sl->otp_base + sl->otp_size) { err = stlink_write_otp(sl, addr, mf.base, (num_empty == mf.len) ? (uint32_t)mf.len : (uint32_t)mf.len - num_empty); } else { @@ -1404,7 +1404,7 @@ int32_t stlink_check_address_range_validity_otp(stlink_t *sl, stm32_addr_t addr, ELOG("Invalid address, it should be within 0x%08x - 0x%08x\n", sl->otp_base, logvar); return (-1); } - if ((addr + size) > (sl->otp_base + sl->otp_size)) { + if ((addr + size) >= (sl->otp_base + sl->otp_size)) { logvar = sl->otp_base + sl->otp_size - addr; ELOG("The size exceeds the size of the OTP Area (0x%08x bytes available)\n", logvar); return (-1); @@ -1431,7 +1431,7 @@ int32_t stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint3 int32_t ret; flash_loader_t fl; ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr); - + // check addr range is inside the flash stlink_calculate_pagesize(sl, addr); From 7dcb1302d8b91b2217c4ce50cb255aa8e78ab001 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 24 Nov 2023 18:21:31 +0100 Subject: [PATCH 1419/1435] Fixes for STM32H7 & STM32G0B1 devices - Fixed flash lock for STM32H7 dual bank devices - Fixed flash erase issue on STM32G0B1 (Closes #1321) --- src/stlink-lib/calculate.c | 2 +- src/stlink-lib/common_flash.c | 28 ++++++++++++---------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/stlink-lib/calculate.c b/src/stlink-lib/calculate.c index a7344e0b0..1230875fd 100644 --- a/src/stlink-lib/calculate.c +++ b/src/stlink-lib/calculate.c @@ -66,7 +66,7 @@ uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { if (sl->chip_id == STM32_CHIPID_L4 || sl->chip_id == STM32_CHIPID_L496x_L4A6x || sl->chip_id == STM32_CHIPID_L4Rx) { - // this chip use dual banked flash + // these chips use dual bank flash if (flashopt & (uint32_t)(1lu << FLASH_L4_OPTR_DUALBANK)) { uint32_t banksize = sl->flash_size / 2; diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 6f2a47f43..ef6b8370c 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -101,6 +101,11 @@ void lock_flash(stlink_t *sl) { cr_lock_shift = FLASH_Gx_CR_LOCK; } else if (sl->flash_type == STM32_FLASH_TYPE_H7) { cr_reg = FLASH_H7_CR1; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + cr2_reg = FLASH_H7_CR2; + } + cr_lock_shift = FLASH_H7_CR_LOCK; + cr_mask = ~(1u << FLASH_H7_CR_SER); } else if (sl->flash_type == STM32_FLASH_TYPE_L0_L1) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = FLASH_L0_PELOCK; @@ -113,11 +118,6 @@ void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STM32_FLASH_TYPE_WB_WL) { cr_reg = FLASH_WB_CR; cr_lock_shift = FLASH_WB_CR_LOCK; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - cr2_reg = FLASH_H7_CR2; - } - cr_lock_shift = FLASH_H7_CR_LOCK; - cr_mask = ~(1u << FLASH_H7_CR_SER); } else { ELOG("unsupported flash method, abort\n"); return; @@ -1014,11 +1014,7 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { unlock_flash_if(sl); // select the page to erase - if ((sl->chip_id == STM32_CHIPID_L4) || - (sl->chip_id == STM32_CHIPID_L43x_L44x) || - (sl->chip_id == STM32_CHIPID_L45x_L46x) || - (sl->chip_id == STM32_CHIPID_L496x_L4A6x) || - (sl->chip_id == STM32_CHIPID_L4Rx)) { + if (sl->flash_type == STM32_FLASH_TYPE_L4) { // calculate the actual bank+page from the address uint32_t page = calculate_L4_page(sl, flashaddr); @@ -1121,16 +1117,16 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { if (sl->flash_type == STM32_FLASH_TYPE_G0) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); stlink_read_debug32(sl, FLASH_Gx_CR, &val); - // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. - val &= ~(0x3F << 3); - val |= ((flash_page & 0x3F) << 3) | (1 << FLASH_CR_PER); + // sec 3.7.5 - PNB[9:0] is offset by 3. PER is 0x2. + val &= ~(0x3FF << 3); + val |= ((flash_page & 0x3FF) << 3) | (1 << FLASH_CR_PER); stlink_write_debug32(sl, FLASH_Gx_CR, val); } else if (sl->flash_type == STM32_FLASH_TYPE_G4) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / sl->flash_pgsz); stlink_read_debug32(sl, FLASH_Gx_CR, &val); - // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. - val &= ~(0x7F << 3); - val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); + // sec 3.7.5 - PNB[9:0] is offset by 3. PER is 0x2. + val &= ~(0x7FF << 3); + val |= ((flash_page & 0x7FF) << 3) | (1 << FLASH_CR_PER); stlink_write_debug32(sl, FLASH_Gx_CR, val); // STM32L5x2xx has two banks with 2k pages or single with 4k pages // STM32H5xx, STM32U535, STM32U545, STM32U575 or STM32U585 have 2 banks with 8k pages From 3efa7932fb7f062f31693c6a2a00941ecf64431b Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 24 Nov 2023 20:22:50 +0100 Subject: [PATCH 1420/1435] Fixed memory allocation for stlink-gui (Closes #1356) --- src/stlink-gui/gui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index e3eec34b8..51ee293e8 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -313,7 +313,7 @@ static gpointer stlink_gui_populate_filemem_view(gpointer data) { goto out_input; } - gui->file_mem.size = (gsize) file_info; + gui->file_mem.size = file_size; gui->file_mem.memory = g_malloc(gui->file_mem.size); for (off = 0; off < (gint)gui->file_mem.size; off += MEM_READ_SIZE) { From ba335a47ab3ad820461ac0175dc0d540090c978c Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 27 Nov 2023 22:00:27 +0100 Subject: [PATCH 1421/1435] STM32F76xxx: Added flashing in dual bank mode (Closes #1174) --- inc/stlink.h | 28 ++++++----- inc/stm32flash.h | 59 +++++++++++----------- src/stlink-lib/calculate.c | 8 ++- src/stlink-lib/common.c | 94 ++++++++++++++++++++++++++++++++++- src/stlink-lib/common_flash.c | 4 +- src/stlink-lib/flash_loader.c | 4 +- 6 files changed, 145 insertions(+), 52 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 557a9eeaa..920822a85 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -199,23 +199,23 @@ struct _stlink { // transport layer verboseness: 0 for no debug info, 10 for lots int32_t verbose; int32_t opt; - uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID - uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram - enum target_state core_stat; // set by stlink_status() + uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID + uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram + enum target_state core_stat; // set by stlink_status() char serial[STLINK_SERIAL_BUFFER_SIZE]; - int32_t freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR + int32_t freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR enum stm32_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STM32_FLASH_TYPE_xx - stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() - uint32_t flash_size; // calculated by stlink_load_device_params() - uint32_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() + stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() + uint32_t flash_size; // calculated by stlink_load_device_params() + uint32_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() /* sram settings */ - stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() - uint32_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() + stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() + uint32_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() /* option settings */ stm32_addr_t option_base; @@ -224,14 +224,16 @@ struct _stlink { // bootloader // sys_base and sys_size are not used by the tools, but are only there to download the bootloader code // (see tests/sg.c) - stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() - uint32_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() + stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() + uint32_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() struct stlink_version_ version; - uint32_t chip_flags; // stlink_chipid_params.flags, set by stlink_load_device_params(), values: CHIP_F_xxx + uint32_t chip_flags; // stlink_chipid_params.flags, set by stlink_load_device_params(), values: CHIP_F_xxx - uint32_t max_trace_freq; // set by stlink_open_usb() + uint32_t max_trace_freq; // set by stlink_open_usb() + + bool dual_bank; // set for F7xxx devices by reading optcr uint32_t otp_base; uint32_t otp_size; diff --git a/inc/stm32flash.h b/inc/stm32flash.h index b5e47e0d3..4fed8b597 100644 --- a/inc/stm32flash.h +++ b/inc/stm32flash.h @@ -142,6 +142,7 @@ #define FLASH_F7_OPTCR_START 1 #define FLASH_F7_OPTCR1_BOOT_ADD0 0 #define FLASH_F7_OPTCR1_BOOT_ADD1 16 +#define FLASH_F7_OPTCR_DBANK (29) /* FLASH_OPTCR Dual Bank Mode */ // F7 Flash control register #define FLASH_F7_CR_STRT 16 @@ -152,12 +153,12 @@ // F7 Flash status register #define FLASH_F7_SR_BSY 16 -#define FLASH_F7_SR_ERS_ERR 7 /* Erase Sequence Error */ -#define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ -#define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ -#define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ -#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ -#define FLASH_F7_SR_EOP 0 /* End of operation */ +#define FLASH_F7_SR_ERS_ERR 7 /* Erase Sequence Error */ +#define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ +#define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ +#define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ +#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ +#define FLASH_F7_SR_EOP 0 /* End of operation */ #define FLASH_F7_SR_ERROR_MASK \ ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | \ (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | \ @@ -196,8 +197,8 @@ #define FLASH_Gx_SR_PROGERR (3) #define FLASH_Gx_SR_WRPERR (4) #define FLASH_Gx_SR_PGAERR (5) -#define FLASH_Gx_SR_BSY (16) /* FLASH_SR Busy */ -#define FLASH_Gx_SR_EOP (0) /* FLASH_EOP End of Operation */ +#define FLASH_Gx_SR_BSY (16) /* FLASH_SR Busy */ +#define FLASH_Gx_SR_EOP (0) /* FLASH_EOP End of Operation */ // == STM32G0 == (RM0444 Table 1, sec. 3.7) // Mostly the same as G4 chips, but the notation @@ -272,8 +273,8 @@ #define FLASH_H7_SR_WRPERR 17 #define FLASH_H7_SR_PGSERR 18 #define FLASH_H7_SR_STRBERR 19 -#define FLASH_H7_SR_ERROR_MASK \ - ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | \ +#define FLASH_H7_SR_ERROR_MASK \ + ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | \ (1 << FLASH_H7_SR_WRPERR)) // == STM32L0/L1/L4/L5 == @@ -332,27 +333,27 @@ #define FLASH_L4_OPTR (FLASH_REGS_ADDR + 0x20) // L4 Flash status register -#define FLASH_L4_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ +#define FLASH_L4_SR_ERROR_MASK 0x3f8 // SR [9:3] #define FLASH_L4_SR_PROGERR 3 #define FLASH_L4_SR_WRPERR 4 #define FLASH_L4_SR_PGAERR 5 #define FLASH_L4_SR_BSY 16 // L4 Flash control register -#define FLASH_L4_CR_LOCK 31 /* Lock control register */ -#define FLASH_L4_CR_OPTLOCK 30 /* Lock option bytes */ -#define FLASH_L4_CR_PG 0 /* Program */ -#define FLASH_L4_CR_PER 1 /* Page erase */ -#define FLASH_L4_CR_MER1 2 /* Bank 1 erase */ -#define FLASH_L4_CR_MER2 15 /* Bank 2 erase */ -#define FLASH_L4_CR_STRT 16 /* Start command */ -#define FLASH_L4_CR_OPTSTRT 17 /* Start writing option bytes */ -#define FLASH_L4_CR_BKER 11 /* Bank select for page erase */ -#define FLASH_L4_CR_PNB 3 /* Page number (8 bits) */ -#define FLASH_L4_CR_OBL_LAUNCH 27 /* Option bytes reload */ +#define FLASH_L4_CR_LOCK 31 /* Lock control register */ +#define FLASH_L4_CR_OPTLOCK 30 /* Lock option bytes */ +#define FLASH_L4_CR_PG 0 /* Program */ +#define FLASH_L4_CR_PER 1 /* Page erase */ +#define FLASH_L4_CR_MER1 2 /* Bank 1 erase */ +#define FLASH_L4_CR_MER2 15 /* Bank 2 erase */ +#define FLASH_L4_CR_STRT 16 /* Start command */ +#define FLASH_L4_CR_OPTSTRT 17 /* Start writing option bytes */ +#define FLASH_L4_CR_BKER 11 /* Bank select for page erase */ +#define FLASH_L4_CR_PNB 3 /* Page number (8 bits) */ +#define FLASH_L4_CR_OBL_LAUNCH 27 /* Option bytes reload */ // Bits requesting flash operations (useful when we want to clear them) -#define FLASH_L4_CR_OPBITS \ - (uint32_t)((1lu << FLASH_L4_CR_PG) | (1lu << FLASH_L4_CR_PER) | \ +#define FLASH_L4_CR_OPBITS \ + (uint32_t)((1lu << FLASH_L4_CR_PG) | (1lu << FLASH_L4_CR_PER) | \ (1lu << FLASH_L4_CR_MER1) | (1lu << FLASH_L4_CR_MER1)) // Page is fully specified by BKER and PNB #define FLASH_L4_CR_PAGEMASK (uint32_t)(0x1fflu << FLASH_L4_CR_PNB) @@ -428,10 +429,10 @@ #define FLASH_WB_CR_LOCK (31) /* Lock */ // WB Flash status register -#define FLASH_WB_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ -#define FLASH_WB_SR_PROGERR (3) /* Programming alignment error */ -#define FLASH_WB_SR_WRPERR (4) /* Write protection error */ -#define FLASH_WB_SR_PGAERR (5) /* Programming error */ -#define FLASH_WB_SR_BSY (16) /* Busy */ +#define FLASH_WB_SR_ERROR_MASK (0x3f8) // SR [9:3] +#define FLASH_WB_SR_PROGERR (3) /* Programming alignment error */ +#define FLASH_WB_SR_WRPERR (4) /* Write protection error */ +#define FLASH_WB_SR_PGAERR (5) /* Programming error */ +#define FLASH_WB_SR_BSY (16) /* Busy */ #endif // STM32FLASH_H diff --git a/src/stlink-lib/calculate.c b/src/stlink-lib/calculate.c index 1230875fd..a8a66a844 100644 --- a/src/stlink-lib/calculate.c +++ b/src/stlink-lib/calculate.c @@ -36,7 +36,7 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr) { } } -uint32_t calculate_F7_sectornum(uint32_t flashaddr) { +uint32_t calculate_F7_sectornum_old(uint32_t flashaddr) { flashaddr &= ~STM32_FLASH_BASE; // Page now holding the actual flash address if (flashaddr < 0x20000) { @@ -49,10 +49,8 @@ uint32_t calculate_F7_sectornum(uint32_t flashaddr) { } uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, uint32_t bank) { - flashaddr &= - ~((bank == BANK_1) - ? STM32_FLASH_BASE - : STM32_H7_FLASH_BANK2_BASE); // sector holding the flash address + // sector holding the flash address + flashaddr &= ~((bank == BANK_1) ? STM32_FLASH_BASE : STM32_H7_FLASH_BANK2_BASE); return (flashaddr / sl->flash_pgsz); } diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index 337fe6efa..4ff90ef3d 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -318,6 +318,19 @@ int32_t stlink_load_device_params(stlink_t *sl) { } } + // F76xxx device with dual bank + if (sl->chip_id == STM32_CHIPID_F76xxx) { + // Check the nDBANK bit in OPTCR + uint32_t optcr; + stlink_read_option_control_register32(sl, & optcr); + + if (!(optcr & (1 << STM32F7_FLASH_OPTCR_DBANK))) + { + sl->dual_bank = true; + } + DLOG("*** stm32f76xx dual-bank %d ***\n", sl->dual_bank); + } + // H7 devices with small flash has one bank if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK && sl->flash_type == STM32_FLASH_TYPE_H7) { @@ -830,8 +843,87 @@ int32_t write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *bu return (ret); } +/* STM32F7 Series Flash memory dual bank mode + * See application note AN4826 pp.18 + */ + +struct sectors_f7 { + int sector; + uint32_t base; + uint32_t size; +}; + +static const struct sectors_f7 f7_single[] = { + { 0, 0x08000000, 0x8000 }, + { 1, 0x08008000, 0x8000 }, + { 2, 0x08010000, 0x8000 }, + { 3, 0x08018000, 0x8000 }, + { 4, 0x08020000, 0x20000 }, + { 5, 0x08040000, 0x40000 }, + { 6, 0x08080000, 0x40000 }, + { 7, 0x080C0000, 0x40000 }, + { 0, 0, 0 }, +}; + +static const struct sectors_f7 f7_dual[] = { + { 0, 0x08000000, 0x4000 }, + { 1, 0x08004000, 0x4000 }, + { 2, 0x08008000, 0x4000 }, + { 3, 0x0800C000, 0x4000 }, + { 4, 0x08010000, 0x10000 }, + { 5, 0x08020000, 0x20000 }, + { 6, 0x08040000, 0x20000 }, + { 7, 0x08060000, 0x20000 }, + { 8, 0x08080000, 0x20000 }, + { 9, 0x080A0000, 0x20000 }, + { 10, 0x080C0000, 0x20000 }, + { 11, 0x080E0000, 0x20000 }, + { 12, 0x08100000, 0x4000 }, + { 13, 0x08104000, 0x4000 }, + { 14, 0x08108000, 0x4000 }, + { 15, 0x0810C000, 0x4000 }, + { 16, 0x08110000, 0x10000 }, + { 17, 0x08120000, 0x20000 }, + { 18, 0x08140000, 0x20000 }, + { 19, 0x08160000, 0x20000 }, + { 20, 0x08180000, 0x20000 }, + { 21, 0x081A0000, 0x20000 }, + { 22, 0x081C0000, 0x20000 }, + { 23, 0x081E0000, 0x20000 }, + { 0, 0, 0 }, +}; + +static const struct sectors_f7 *get_f7_info(stlink_t *sl) { + return sl->dual_bank ? f7_dual : f7_single; +} + +static const struct sectors_f7 *find_sector(stlink_t *sl, uint32_t flashaddr) { + for (const struct sectors_f7 *s = get_f7_info(sl); s->base; s++) { + const uint32_t end = s->base + s->size; + if ((s->base <= flashaddr) && (flashaddr < end)) { + return s; + } + } + fprintf(stderr, "Bad address %#x\n", flashaddr); + exit(0); +} + +uint32_t calculate_F7_sectornum(stlink_t *sl, uint32_t flashaddr) { + if (sl->chip_id == STM32_CHIPID_F76xxx) { + const struct sectors_f7 *s = find_sector(sl, flashaddr); + return s->sector; + } + return calculate_F7_sectornum_old(flashaddr); +} + // 291 uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { + + if (sl->chip_id == STM32_CHIPID_F76xxx) { + const struct sectors_f7 *s = find_sector(sl, flashaddr); + return s->size; + } + if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || @@ -857,7 +949,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { } } else if (sl->chip_id == STM32_CHIPID_F7 || sl->chip_id == STM32_CHIPID_F76xxx) { - uint32_t sector = calculate_F7_sectornum(flashaddr); + uint32_t sector = calculate_F7_sectornum(sl, flashaddr); if (sector < 4) { sl->flash_pgsz = 0x8000; diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index ef6b8370c..fc377a471 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -145,7 +145,7 @@ static inline int32_t write_flash_sr(stlink_t *sl, uint32_t bank, uint32_t val) } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { sr_reg = FLASH_F4_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - sr_reg = FLASH_F7_SR; + sr_reg = (bank == BANK_1) ? FLASH_F7_SR1 : FLASH_F7_SR2; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { sr_reg = FLASH_Gx_SR; @@ -1025,7 +1025,7 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } else if (sl->chip_id == STM32_CHIPID_F7 || sl->chip_id == STM32_CHIPID_F76xxx) { // calculate the actual page from the address - uint32_t sector = calculate_F7_sectornum(flashaddr); + uint32_t sector = calculate_F7_sectornum(sl, flashaddr); fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, stlink_calculate_pagesize(sl, flashaddr)); diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 0d01dfd61..9511c9282 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -363,7 +363,7 @@ int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t t /* Run loader */ stlink_run(sl, RUN_FLASH_LOADER); -/* +/* * This piece of code used to try to spin for .1 second by waiting doing 10000 rounds of 10 µs. * But because this usually runs on Unix-like OSes, the 10 µs get rounded up to the "tick" * (actually almost two ticks) of the system. 1 ms. Thus, the ten thousand attempts, when @@ -393,7 +393,7 @@ int32_t stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t t // check written byte count stlink_read_reg(sl, 2, &rr); - /* + /* * The chunk size for loading is not rounded. The flash loader * subtracts the size of the written block (1-8 bytes) from * the remaining size each time. A negative value may mean that From 8f2b289f20372583ae5f2889069e56df3c71477c Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 27 Nov 2023 23:41:27 +0100 Subject: [PATCH 1422/1435] Info on HW breakpoints for external bus - [doc] Updated tutorial.md (Closes #1219) - Moved memory maps into separate file. --- doc/tutorial.md | 32 +++--- src/st-util/gdb-server.c | 214 +------------------------------------- src/st-util/memory-map.h | 217 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 238 insertions(+), 225 deletions(-) create mode 100644 src/st-util/memory-map.h diff --git a/doc/tutorial.md b/doc/tutorial.md index 53ecabe7d..736c4283b 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -2,18 +2,18 @@ ## Available tools and options -| Option | Tool | Description | Available
      since | -| --------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| --flash=n[k, M] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k for the STM32F103C8T6
      to assume 128k of flash being present. This option accepts decimal (128k), octal 0200k, or hex 0x80k values.
      Leaving the multiplier out is equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional
      "k" or "M" to multiply the given value by 1k (1024) or 1M (1024 x 1024) respectively.
      One can read arbitary addresses of memory out to a binary file with: `st-flash read out.bin 0x8000000 4096`.
      In this example `4096 bytes` are read and subsequently written to `out.bin`.
      Binary files (here: `in.bin`) are written into flash memory with: `st-flash write in.bin 0x8000000` | v1.4.0 | -| --format | st-flash | Specify file image format to read or write. Valid formats are `binary` and `ihex`. | v1.3.0 | -| --freq=n[k, M] | st-info
      st-flash
      st-util | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
      This option solely accepts decimal values with the unit `Hz` being left out. Valid frequencies are:
      `5k, 15k, 25k, 50k, 100k, 125k, 240k, 480k, 950k, 1200k (1.2M), 1800k (1.8M), 4000k (4M)`. | v1.6.1 | -| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
      This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | -| --reset | st-flash | Trigger a reset after flashing. The default uses the hardware reset through `NRST` pin.
      A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | -| --connect-under-reset | st-info
      st-flash
      st-util | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
      when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | -| --hot-plug | st-info
      st-flash
      st-util | Connect to the target without reset. | v1.6.2 | -| --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | -| --version | st-info
      st-flash
      st-util | Print version information. | v1.3.0 | -| --help | st-flash
      st-util | Print list of available commands. | | +| Option | Tool | Description | Available
      since | +| --------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | +| --flash=n[k, M] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k for the STM32F103C8T6 to assume 128k of flash being present. This option accepts decimal (128k), octal 0200k, or hex 0x80k values.
      Leaving the multiplier out is equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional "k" or "M" to multiply the given value by 1k (1024) or 1M (1024 x 1024) respectively.
      One can read arbitary addresses of memory out to a binary file with: `st-flash read out.bin 0x8000000 4096`. In this example `4096 bytes` are read and subsequently written to `out.bin`.
      Binary files (here: `in.bin`) are written into flash memory with: `st-flash write in.bin 0x8000000` | v1.4.0 | +| --format | st-flash | Specify file image format to read or write.
      Valid formats are `binary` and `ihex`. | v1.3.0 | +| --freq=n[k, M] | st-info
      st-flash
      st-util | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
      This option solely accepts decimal values with the unit `Hz` being left out. Valid frequencies are:
      `5k, 15k, 25k, 50k, 100k, 125k, 240k, 480k, 950k, 1200k (1.2M), 1800k (1.8M), 4000k (4M)`. | v1.6.1 | +| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
      This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | +| --reset | st-flash | Trigger a reset after flashing. The default uses the hardware reset through `NRST` pin.
      A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | +| --connect-under-reset | st-info
      st-flash
      st-util | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | +| --hot-plug | st-info
      st-flash
      st-util | Connect to the target without reset. | v1.6.2 | +| --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | +| --version | st-info
      st-flash
      st-util | Print version information. | v1.3.0 | +| --help | st-flash
      st-util | Print list of available commands. | | ### Reading & Writing Option Bytes @@ -156,6 +156,14 @@ Here flashing of the device is now possible with and without the `--reset` optio The debug command `(gdb) monitor jtag_reset` sends a _hard reset_ signal via the `NRST` pin to reset the device and allows for flashing it (again). +### e) Note on setting hardware breakpoints for external bus (Example: STM32H735-DK) + +GDB is setting breakpoints based on the XML memory map designation of `rom` or `ram`, which is hardcoded in st-util for a given processor. +However the external bus can be *RAM* or *ROM* depending on design. + +The STM32H735-DK has external FLASH at address 0x90000000. As a result, because the entire external memory range is `ram` as it could be either, +software breakpoints (Z0) get sent when a breakpoint is created and they never get tripped as the memory area is read only. + --- ( Content below is currently unrevised and may be outdated as of Mar 2021. ) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 71f24fb60..28e06231a 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -29,6 +29,7 @@ #include #include "gdb-server.h" #include "gdb-remote.h" +#include "memory-map.h" #include "semihosting.h" #include @@ -344,219 +345,6 @@ static const char* const target_description = " " ""; -static const char* const memory_map_template_F4 = - "" - "" - "" - " " // code = sram, bootrom or flash; flash is bigger - " " // ccm ram - " " // sram - " " // Sectors 0..3 - " 0x4000" // 16kB - " " - " " // Sector 4 - " 0x10000" // 64kB - " " - " " // Sectors 5..11 - " 0x20000" // 128kB - " " - " " // peripheral regs - " " // AHB3 Peripherals - " " // cortex regs - " " // bootrom - " " // option byte area - ""; - -static const char* const memory_map_template_F4_HD = - "" - "" - "" - " " // code = sram, bootrom or flash; flash is bigger - " " // ccm ram - " " // sram - " " // fmc bank 1 (nor/psram/sram) - " " // fmc bank 2 & 3 (nand flash) - " " // fmc bank 4 (pc card) - " " // fmc sdram bank 1 & 2 - " " // Sectors 0..3 - " 0x4000" // 16kB - " " - " " // Sector 4 - " 0x10000" // 64kB - " " - " " // Sectors 5..11 - " 0x20000" // 128kB - " " - " " // peripheral regs - " " // cortex regs - " " // bootrom - " " // option byte area - ""; - -static const char* const memory_map_template_F2 = - "" - "" - "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram - " " // Sectors 0..3 - " 0x4000" // 16kB - " " - " " // Sector 4 - " 0x10000" // 64kB - " " - " " // Sectors 5.. - " 0x20000" // 128kB - " " - " " // peripheral regs - " " // cortex regs - " " // bootrom - " " // option byte area - ""; - -static const char* const memory_map_template_L4 = - "" - "" - "" - " " // code = sram, bootrom or flash; flash is bigger - " " // SRAM2 (32kB) - " " // SRAM1 (96kB) - " " - " 0x800" - " " - " " // peripheral regs - " " // AHB3 Peripherals - " " // cortex regs - " " // bootrom - " " // option byte area - " " // option byte area - ""; - -static const char* const memory_map_template_L496 = - "" - "" - "" - " " // code = sram, bootrom or flash; flash is bigger - " " // SRAM2 (64kB) - " " // SRAM1 + aliased SRAM2 (256 + 64 = 320kB) - " " - " 0x800" - " " - " " // peripheral regs - " " // AHB3 Peripherals - " " // cortex regs - " " // bootrom - " " // option byte area - " " // option byte area - ""; - -static const char* const memory_map_template = - "" - "" - "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram 8kB - " " - " 0x%x" - " " - " " // peripheral regs - " " // cortex regs - " " // bootrom - " " // option byte area - ""; - -static const char* const memory_map_template_F7 = - "" - "" - "" - " " // ITCM ram 16kB - " " // ITCM flash - " " // sram - " " // Sectors 0..3 - " 0x8000" // 32kB - " " - " " // Sector 4 - " 0x20000" // 128kB - " " - " " // Sectors 5..7 - " 0x40000" // 128kB - " " - " " // peripheral regs - " " // AHB3 Peripherals - " " // cortex regs - " " // bootrom - " " // option byte area - ""; - -static const char* const memory_map_template_H7 = - "" - "" - "" - " " // ITCMRAM 64kB - " " // DTCMRAM 128kB - " " // RAM D1 512kB - " " // RAM D2 288kB - " " // RAM D3 64kB - " " - " 0x%x" - " " - " " // peripheral regs - " " // cortex regs - " " // bootrom - ""; - -static const char* const memory_map_template_H72x3x = - "" - "" - "" - " " // ITCMRAM 64kB + Optional remap - " " // DTCMRAM 128kB - " " // RAM D1 320kB - " " // RAM D2 23kB - " " // RAM D3 16kB - " " // Backup RAM 4kB - " " - " 0x%x" - " " - " " // peripheral regs - " " // External Memory - " " // External device - " " // cortex regs - " " // bootrom - ""; - -static const char* const memory_map_template_F4_DE = - "" - "" - "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram - " " // Sectors 0..3 - " 0x4000" // 16kB - " " - " " // Sector 4 - " 0x10000" // 64kB - " " - " " // Sectors 5..7 - " 0x20000" // 128kB - " " - " " // peripheral regs - " " // cortex regs - " " // bootrom - " " // otp - " " // option byte area - ""; - char* make_memory_map(stlink_t *sl) { // this will be freed in serve() const uint32_t sz = 4096; diff --git a/src/st-util/memory-map.h b/src/st-util/memory-map.h new file mode 100644 index 000000000..6f34eedac --- /dev/null +++ b/src/st-util/memory-map.h @@ -0,0 +1,217 @@ +#ifndef MEMORY_MAP_H +#define MEMORY_MAP_H + +static const char* const memory_map_template_F4 = + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // ccm ram + " " // sram + " " // Sectors 0...3 + " 0x4000" // 16 kB + " " + " " // Sector 4 + " 0x10000" // 64 kB + " " + " " // Sectors 5...11 + " 0x20000" // 128 kB + " " + " " // peripheral regs + " " // AHB3 Peripherals + " " // cortex regs + " " // bootrom + " " // option byte area + ""; + +static const char* const memory_map_template_F4_HD = + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // ccm ram + " " // sram + " " // fmc bank 1 (nor/psram/sram) + " " // fmc bank 2 & 3 (nand flash) + " " // fmc bank 4 (pc card) + " " // fmc sdram bank 1 & 2 + " " // Sectors 0...3 + " 0x4000" // 16 kB + " " + " " // Sector 4 + " 0x10000" // 64 kB + " " + " " // Sectors 5...11 + " 0x20000" // 128 kB + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + " " // option byte area + ""; + +static const char* const memory_map_template_F2 = + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // SRAM + " " // Sectors 0...3 + " 0x4000" // 16 kB + " " + " " // Sector 4 + " 0x10000" // 64 kB + " " + " " // Sectors 5... + " 0x20000" // 128 kB + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + " " // option byte area + ""; + +static const char* const memory_map_template_L4 = + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // SRAM2 (32 kB) + " " // SRAM1 (96 kB) + " " + " 0x800" + " " + " " // peripheral regs + " " // AHB3 Peripherals + " " // cortex regs + " " // bootrom + " " // option byte area + " " // option byte area + ""; + +static const char* const memory_map_template_L496 = + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // SRAM2 (64 kB) + " " // SRAM1 + aliased SRAM2 (256 + 64 = 320 kB) + " " + " 0x800" + " " + " " // peripheral regs + " " // AHB3 Peripherals + " " // cortex regs + " " // bootrom + " " // option byte area + " " // option byte area + ""; + +static const char* const memory_map_template = + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // SRAM (8 kB) + " " + " 0x%x" + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + " " // option byte area + ""; + +static const char* const memory_map_template_F7 = + "" + "" + "" + " " // ITCM ram 16 kB + " " // ITCM flash + " " // SRAM + " " // Sectors 0...3 + " 0x8000" // 32 kB + " " + " " // Sector 4 + " 0x20000" // 128 kB + " " + " " // Sectors 5...7 + " 0x40000" // 128 kB + " " + " " // peripheral regs + " " // AHB3 Peripherals + " " // cortex regs + " " // bootrom + " " // option byte area + ""; + +static const char* const memory_map_template_H7 = + "" + "" + "" + " " // ITCMRAM 64 kB + " " // DTCMRAM 128 kB + " " // RAM D1 512 kB + " " // RAM D2 288 kB + " " // RAM D3 64 kB + " " + " 0x%x" + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + ""; + +static const char* const memory_map_template_H72x3x = + "" + "" + "" + " " // ITCMRAM 64 kB + Optional remap + " " // DTCMRAM 128 kB + " " // RAM D1 320 kB + " " // RAM D2 23 kB + " " // RAM D3 16 kB + " " // Backup RAM 4 kB + " " + " 0x%x" + " " + " " // peripheral regs + " " // External Memory + " " // External device + " " // cortex regs + " " // bootrom + ""; + +static const char* const memory_map_template_F4_DE = + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // SRAM + " " // Sectors 0..3 + " 0x4000" // 16 kB + " " + " " // Sector 4 + " 0x10000" // 64 kB + " " + " " // Sectors 5..7 + " 0x20000" // 128 kB + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + " " // otp + " " // option byte area + ""; + +#endif // MEMORY_MAP_H \ No newline at end of file From 81575cb2d9fd1db32dd12581baf642447e5ab623 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 23 Dec 2023 17:45:17 +0100 Subject: [PATCH 1423/1435] [doc] Updated udev directory (#1358) --- doc/compiling.md | 2 +- doc/tutorial.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/compiling.md b/doc/compiling.md index 8936f6a58..e2c686c0a 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -165,7 +165,7 @@ Within the sourcefolder of the project, these rules are located in the subdirect Afterwards it may be necessary to reload the udev rules: ```sh -$ sudo cp -a config/udev/rules.d/* /etc/udev/rules.d/ +$ sudo cp -a config/udev/rules.d/* /lib/udev/rules.d/ $ sudo udevadm control --reload-rules $ sudo udevadm trigger ``` diff --git a/doc/tutorial.md b/doc/tutorial.md index 736c4283b..36c80c674 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -62,7 +62,7 @@ On my system I see the following: crw-rw-rw- 1 root root 189, 528 Jan 24 17:52 /dev/bus/usb/005/017 ``` -which is world writable (this is from the `MODE:="0666"` below). I have several files in my `/etc/udev/rules.d` directory. In this particular case, the `49-stlinkv2-1.rules` file contains the following: +which is world writable (this is from the `MODE:="0666"` below). I have several files in my `/lib/udev/rules.d` directory. In this particular case, the `49-stlinkv2-1.rules` file contains the following: ``` # STM32 nucleo boards, with onboard STLINK/V2-1 @@ -81,7 +81,7 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", \ and the `idVendor` of `0483` and `idProduct` of `374b` matches the vendor id from the `lsusb` output. -Make sure that you have all 3 files from [/config/udev/rules.d](https://github.com/stlink-org/stlink/tree/master/config/udev/rules.d) in your `/etc/udev/rules.d` directory. After copying new files or editing existing files in `/etc/udev/ruled.d` you should run the following: +Make sure that you have all 3 files from [/config/udev/rules.d](https://github.com/stlink-org/stlink/tree/master/config/udev/rules.d) in your `/lib/udev/rules.d` directory. After copying new files or editing existing files in `/lib/udev/rules.d` you should run the following: ``` sudo udevadm control --reload-rules From 135a5472d9fd52d252774dce2b5d05cdc25dd458 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 24 Dec 2023 00:01:35 +0100 Subject: [PATCH 1424/1435] Reverted commit ba335a47 "STM32F76xxx: Added flashing in dual bank mode" --- inc/stlink.h | 2 - inc/stm32flash.h | 1 - src/stlink-lib/calculate.c | 2 +- src/stlink-lib/common.c | 91 ----------------------------------- src/stlink-lib/common_flash.c | 4 +- 5 files changed, 3 insertions(+), 97 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 920822a85..788392d72 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -233,8 +233,6 @@ struct _stlink { uint32_t max_trace_freq; // set by stlink_open_usb() - bool dual_bank; // set for F7xxx devices by reading optcr - uint32_t otp_base; uint32_t otp_size; }; diff --git a/inc/stm32flash.h b/inc/stm32flash.h index 4fed8b597..a5081d694 100644 --- a/inc/stm32flash.h +++ b/inc/stm32flash.h @@ -142,7 +142,6 @@ #define FLASH_F7_OPTCR_START 1 #define FLASH_F7_OPTCR1_BOOT_ADD0 0 #define FLASH_F7_OPTCR1_BOOT_ADD1 16 -#define FLASH_F7_OPTCR_DBANK (29) /* FLASH_OPTCR Dual Bank Mode */ // F7 Flash control register #define FLASH_F7_CR_STRT 16 diff --git a/src/stlink-lib/calculate.c b/src/stlink-lib/calculate.c index a8a66a844..95a94143b 100644 --- a/src/stlink-lib/calculate.c +++ b/src/stlink-lib/calculate.c @@ -36,7 +36,7 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr) { } } -uint32_t calculate_F7_sectornum_old(uint32_t flashaddr) { +uint32_t calculate_F7_sectornum(uint32_t flashaddr) { flashaddr &= ~STM32_FLASH_BASE; // Page now holding the actual flash address if (flashaddr < 0x20000) { diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index 4ff90ef3d..57aa53a25 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -318,19 +318,6 @@ int32_t stlink_load_device_params(stlink_t *sl) { } } - // F76xxx device with dual bank - if (sl->chip_id == STM32_CHIPID_F76xxx) { - // Check the nDBANK bit in OPTCR - uint32_t optcr; - stlink_read_option_control_register32(sl, & optcr); - - if (!(optcr & (1 << STM32F7_FLASH_OPTCR_DBANK))) - { - sl->dual_bank = true; - } - DLOG("*** stm32f76xx dual-bank %d ***\n", sl->dual_bank); - } - // H7 devices with small flash has one bank if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK && sl->flash_type == STM32_FLASH_TYPE_H7) { @@ -843,87 +830,9 @@ int32_t write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *bu return (ret); } -/* STM32F7 Series Flash memory dual bank mode - * See application note AN4826 pp.18 - */ - -struct sectors_f7 { - int sector; - uint32_t base; - uint32_t size; -}; - -static const struct sectors_f7 f7_single[] = { - { 0, 0x08000000, 0x8000 }, - { 1, 0x08008000, 0x8000 }, - { 2, 0x08010000, 0x8000 }, - { 3, 0x08018000, 0x8000 }, - { 4, 0x08020000, 0x20000 }, - { 5, 0x08040000, 0x40000 }, - { 6, 0x08080000, 0x40000 }, - { 7, 0x080C0000, 0x40000 }, - { 0, 0, 0 }, -}; - -static const struct sectors_f7 f7_dual[] = { - { 0, 0x08000000, 0x4000 }, - { 1, 0x08004000, 0x4000 }, - { 2, 0x08008000, 0x4000 }, - { 3, 0x0800C000, 0x4000 }, - { 4, 0x08010000, 0x10000 }, - { 5, 0x08020000, 0x20000 }, - { 6, 0x08040000, 0x20000 }, - { 7, 0x08060000, 0x20000 }, - { 8, 0x08080000, 0x20000 }, - { 9, 0x080A0000, 0x20000 }, - { 10, 0x080C0000, 0x20000 }, - { 11, 0x080E0000, 0x20000 }, - { 12, 0x08100000, 0x4000 }, - { 13, 0x08104000, 0x4000 }, - { 14, 0x08108000, 0x4000 }, - { 15, 0x0810C000, 0x4000 }, - { 16, 0x08110000, 0x10000 }, - { 17, 0x08120000, 0x20000 }, - { 18, 0x08140000, 0x20000 }, - { 19, 0x08160000, 0x20000 }, - { 20, 0x08180000, 0x20000 }, - { 21, 0x081A0000, 0x20000 }, - { 22, 0x081C0000, 0x20000 }, - { 23, 0x081E0000, 0x20000 }, - { 0, 0, 0 }, -}; - -static const struct sectors_f7 *get_f7_info(stlink_t *sl) { - return sl->dual_bank ? f7_dual : f7_single; -} - -static const struct sectors_f7 *find_sector(stlink_t *sl, uint32_t flashaddr) { - for (const struct sectors_f7 *s = get_f7_info(sl); s->base; s++) { - const uint32_t end = s->base + s->size; - if ((s->base <= flashaddr) && (flashaddr < end)) { - return s; - } - } - fprintf(stderr, "Bad address %#x\n", flashaddr); - exit(0); -} - -uint32_t calculate_F7_sectornum(stlink_t *sl, uint32_t flashaddr) { - if (sl->chip_id == STM32_CHIPID_F76xxx) { - const struct sectors_f7 *s = find_sector(sl, flashaddr); - return s->sector; - } - return calculate_F7_sectornum_old(flashaddr); -} - // 291 uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { - if (sl->chip_id == STM32_CHIPID_F76xxx) { - const struct sectors_f7 *s = find_sector(sl, flashaddr); - return s->size; - } - if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) || diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index fc377a471..ef6b8370c 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -145,7 +145,7 @@ static inline int32_t write_flash_sr(stlink_t *sl, uint32_t bank, uint32_t val) } else if (sl->flash_type == STM32_FLASH_TYPE_F2_F4) { sr_reg = FLASH_F4_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_F7) { - sr_reg = (bank == BANK_1) ? FLASH_F7_SR1 : FLASH_F7_SR2; + sr_reg = FLASH_F7_SR; } else if (sl->flash_type == STM32_FLASH_TYPE_G0 || sl->flash_type == STM32_FLASH_TYPE_G4) { sr_reg = FLASH_Gx_SR; @@ -1025,7 +1025,7 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } else if (sl->chip_id == STM32_CHIPID_F7 || sl->chip_id == STM32_CHIPID_F76xxx) { // calculate the actual page from the address - uint32_t sector = calculate_F7_sectornum(sl, flashaddr); + uint32_t sector = calculate_F7_sectornum(flashaddr); fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, stlink_calculate_pagesize(sl, flashaddr)); From a60c24cbc040fe63b12172e93d0d99778b30eaca Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 24 Dec 2023 00:34:29 +0100 Subject: [PATCH 1425/1435] General Project Update - [doc] Updated system requirements - Updated CHANGELOG.md - Updated list of contributors --- CHANGELOG.md | 19 +++++++--- contributors.txt | 16 +++++---- doc/version_support.md | 67 ++++++++++++++++------------------- src/stlink-gui/CMakeLists.txt | 2 +- 4 files changed, 55 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b6cccdf9..c477eb54a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # v1.8.0 -Release date: 2023-xx-xx +Release date: 2024-xx-xx This release drops support for macOS and some older operating systems. Check project README for details. Removed Travis CI integration as it is no longer functional. @@ -16,7 +16,7 @@ Features: - Support for writing option bytes on STM32F0/F1/F3 ([#346](https://github.com/stlink-org/stlink/pull/346), [#458](https://github.com/stlink-org/stlink/pull/458), [#808](https://github.com/stlink-org/stlink/pull/808), [#1084](https://github.com/stlink-org/stlink/pull/1084), [#1112](https://github.com/stlink-org/stlink/pull/1112)) - Initial support for STM32 L5 & U5 devices and minor changes ([#1005](https://github.com/stlink-org/stlink/pull/1005), [#1096](https://github.com/stlink-org/stlink/pull/1096), [#1247](https://github.com/stlink-org/stlink/pull/1247), [#1300](https://github.com/stlink-org/stlink/pull/1300), [#1301](https://github.com/stlink-org/stlink/pull/1301)) -- Added chip-IDs for STM32G0B0/G0B1/G0C1/G050/G051/G061 ([#1140](https://github.com/stlink-org/stlink/pull/1140)) +- Added chip-IDs for STM32G0B0/G0B1/G0C1/G050/G051/G061 ([#1140](https://github.com/stlink-org/stlink/pull/1140), [#1359](https://github.com/stlink-org/stlink/pull/1359)) - Added option byte info for STM32F411XX ([#1141](https://github.com/stlink-org/stlink/pull/1141)) - Expanded and revised list of chips ([#1145](https://github.com/stlink-org/stlink/pull/1145), [#1164](https://github.com/stlink-org/stlink/pull/1164)) - STM32H72X/3X: Added full access to all device memory ([#1158](https://github.com/stlink-org/stlink/pull/1158), [#1159](https://github.com/stlink-org/stlink/pull/1159)) @@ -29,7 +29,9 @@ Features: - Added parametres option_base, option_size for F401xD_xE ([#1235](https://github.com/stlink-org/stlink/pull/1235)) - Added support for option bytes to F1xx_XLD (GD32F30x) ([#1250](https://github.com/stlink-org/stlink/pull/1250)) - Added option byte address for L4Rx devices ([#1254](https://github.com/stlink-org/stlink/pull/1254)) -- Added udev-rule rule for the STLink v3 MINIE programmer ([#1274](https://github.com/stlink-org/stlink/pull/1274), [#1281](https://github.com/stlink-org/stlink/pull/1281)) +- Added udev-rule rule for the STLink v3 MINIE programmer ([#1274](https://github.com/stlink-org/stlink/pull/1274), [#1281](https://github.com/stlink-org/stlink/pull/1281), [#1358](https://github.com/stlink-org/stlink/pull/1358)) +- Added support for STM32C0x1 devices ([#1329](https://github.com/stlink-org/stlink/pull/1329), [#1354](https://github.com/stlink-org/stlink/pull/1354)) +- First Implementation of the OTP Read/Write function ([#1352](https://github.com/stlink-org/stlink/pull/1352), [#1353](https://github.com/stlink-org/stlink/pull/1353)) Updates & changes: @@ -42,11 +44,13 @@ Updates & changes: - [doc] Human-readable flash_type in chip-id files ([#1155](https://github.com/stlink-org/stlink/pull/1155), commit [#1745bf5](https://github.com/stlink-org/stlink/commit/1745bf5193c4d3186d4f6fde59cc86e9bad6e61b)) - Dropped execute bits from source code files ([#1167](https://github.com/stlink-org/stlink/pull/1167)) - Use proper Markdown headers for supported MCUs ([#1168](https://github.com/stlink-org/stlink/pull/1168)) +- Ability to flash F7 devices when in dual-bank mode ([#1174](https://github.com/stlink-org/stlink/pull/1174)) - Removed redundant array ([#1178](https://github.com/stlink-org/stlink/pull/1178)) - Updated chip config files from the library structs ([#1181](https://github.com/stlink-org/stlink/pull/1181)) - [doc] Corrected file path in tutorial ([#1186](https://github.com/stlink-org/stlink/pull/1186)) - Improved chipid checks and printouts ([#1188](https://github.com/stlink-org/stlink/pull/1188)) - [refactoring] Sourcefile 'common.c' ([#1218](https://github.com/stlink-org/stlink/pull/1218), [#1220](https://github.com/stlink-org/stlink/pull/1220)) +- [STM32H735]: Set hardware breakpoints for external bus ([#1219](https://github.com/stlink-org/stlink/pull/1219)) - Set C standard through cmake variables ([#1221](https://github.com/stlink-org/stlink/pull/1221)) - [doc] Added make install to the macOS compiling instructions ([#1259](https://github.com/stlink-org/stlink/pull/1259)) - [doc] Linux Install from code Documentation improvement ([#1263](https://github.com/stlink-org/stlink/pull/1263), commit [#43498de](https://github.com/stlink-org/stlink/commit/43498dedf651260ef34197e512d35e3ad7142401)) @@ -56,12 +60,13 @@ Updates & changes: - [doc] Updated package source link for Arch Linux ([#1318](https://github.com/stlink-org/stlink/pull/1318)) - CMake: Avoid hard-wired /usr/local/share ([#1325](https://github.com/stlink-org/stlink/pull/1325)) + Fixes: - Fixed some flashing issues on STM32L0 ([#681](https://github.com/stlink-org/stlink/pull/681), [#1203](https://github.com/stlink-org/stlink/pull/1203), [#1225](https://github.com/stlink-org/stlink/pull/1225), [#1253](https://github.com/stlink-org/stlink/pull/1253), [#1289](https://github.com/stlink-org/stlink/pull/1289), [#1330](https://github.com/stlink-org/stlink/pull/1330)) - cmake: Install shared libraries in proper directories ([#1098](https://github.com/stlink-org/stlink/pull/1098), [#1138](https://github.com/stlink-org/stlink/pull/1138), [#1154](https://github.com/stlink-org/stlink/pull/1154)) - cmake: Install shared libraries in proper directories ([#1142](https://github.com/stlink-org/stlink/pull/1142)) -- Fixed clearance of the H7 dual bank flag ([#1146](https://github.com/stlink-org/stlink/pull/1146), [#1147](https://github.com/stlink-org/stlink/pull/1147)) +- Fixed clearance of the H7 dual bank flag ([#1146](https://github.com/stlink-org/stlink/pull/1146), [#1147](https://github.com/stlink-org/stlink/pull/1147), [#1342](https://github.com/stlink-org/stlink/pull/1342)) - Fix for 'libusb_devices were leaked' when no ST-LINK programmer was found ([#1150](https://github.com/stlink-org/stlink/pull/1150)) - Set of fixes and improvements ([#1153](https://github.com/stlink-org/stlink/pull/1153), [#1154](https://github.com/stlink-org/stlink/pull/1154)) - Removed limit check for WRITEMEM_32BIT ([#1157](https://github.com/stlink-org/stlink/pull/1157)) @@ -75,7 +80,7 @@ Fixes: - st-flash and other utilities search for chip files in the wrong directory ([#1180](https://github.com/stlink-org/stlink/pull/1180), commit [#c8fc656](https://github.com/stlink-org/stlink/commit/c8fc6561fead79ad49c09d82bab864745086792c)) - Fixed broken build on 32 bit systems ([#985](https://github.com/stlink-org/stlink/pull/985), [#1175](https://github.com/stlink-org/stlink/pull/1175), commit [#c8fc656](https://github.com/stlink-org/stlink/commit/c8fc6561fead79ad49c09d82bab864745086792c)) - Define 'SSIZE_MAX' if not defined ([#1183](https://github.com/stlink-org/stlink/pull/1183)) -- STM32G031G8: BOOT_LOCK is not possible to change on option bytes address 0x1FFF7870 ([#1194](https://github.com/stlink-org/stlink/pull/1194)) +- [STM32G031G8]: BOOT_LOCK is not possible to change on option bytes address 0x1FFF7870 ([#1194](https://github.com/stlink-org/stlink/pull/1194)) - Fixed compliation for OpenBSD 7.0 ([#1202](https://github.com/stlink-org/stlink/pull/1202)) - Included 'SSIZE_MAX' from 'limits.h' in 'src/common.c' ([#1207](https://github.com/stlink-org/stlink/pull/1207)) - Fix for libusb_kernel_driver_active & error handling for st.st_size () ([#1210](https://github.com/stlink-org/stlink/pull/1210), [#1211](https://github.com/stlink-org/stlink/pull/1211), [#1214](https://github.com/stlink-org/stlink/pull/1214)) @@ -93,7 +98,11 @@ Fixes: - Fixed unbounded write and check return values of sscanf ([#1306](https://github.com/stlink-org/stlink/pull/1306)) - Added null check for return value of stlink_chipid_get_params() ([#1307](https://github.com/stlink-org/stlink/pull/1307)) - Fixed warning in a few *.cmake files ([#1309](https://github.com/stlink-org/stlink/pull/1309)) +- Fixed support for STM32U5 chips ([#1320](https://github.com/stlink-org/stlink/pull/1320), [#1355](https://github.com/stlink-org/stlink/pull/1355)) +- [STM32G0B1]: Erase fails starting page 64 ([#1321](https://github.com/stlink-org/stlink/pull/1321)) - Notification "unknown option -- u" in tool st-util ([#1326](https://github.com/stlink-org/stlink/pull/1326), [#1327](https://github.com/stlink-org/stlink/pull/1327)) +- Do not crash when the STLink chip returns a voltage factor of zero ([#1343](https://github.com/stlink-org/stlink/pull/1343)) +- stlink-gui: failed to allocate 139988352155568 bytes ([#1356](https://github.com/stlink-org/stlink/pull/1356)) # v1.7.0 diff --git a/contributors.txt b/contributors.txt index 2425ae7f0..dacb4e4af 100644 --- a/contributors.txt +++ b/contributors.txt @@ -4,7 +4,7 @@ Alexey Cherevatenko Alexey Panarin Anatoli Klassen [dev26th] Andrea Mucignat -Andrew Andrianov [necromant] +Andrew Andrianov [nekromant] Andrey Yurovsky Andy Isaacson Andreas Sandberg [andysan] @@ -52,10 +52,10 @@ Greg Meiste [meisteg] Grzegorz Szymaszek [gszy] Guillaume Revaillot [grevaillot] Gwenhael Goavec-Merou [trabucayre] -Hakkavélin +[Hakkavélin] Halt Hammerzeit +Hsu Pu [hsupu] [hydroconstructor] -htk Ian Griffiths Jack Peel Jakub Tyszkowski @@ -68,6 +68,7 @@ Jens Hoffmann Jerome Lambourg Jim Paris Jiří Netolický +Jerry Jacobs [xor-gate] Jerry Nosky [jnosky] Jochen Wilhelmy [Jochen0x90h] John Hall [simplerobot] @@ -90,7 +91,6 @@ Michael Pratt [prattmic] Michael Sparmann Mike Szczys Magnus Lundin [mlu] -mux Ned Konz Nic McDonald Nicolas Schodet @@ -98,7 +98,7 @@ Oleksiy Slyshyk [slyshykO] Olivier Croquette Olivier Gay Onno Kortmann -orangeudav +[orangeudav] Pavel Kirienko Pekka Nikander Pete Nelson @@ -107,6 +107,7 @@ Peter Zotov Petteri Aimonen Piotr Haber [RafaelLeeImg] +[rcubee] Rene Hopf [rene-dev] Robin Kreis Roger Wolff [rewolff] @@ -117,11 +118,11 @@ Sean Simmons Sergey Alirzaev Simon Derr [sderr] Simon Wright -[simplerobot] Stany Marcel Stefan Misik Sven Wegener -Tarek Bochkati [tarek-bochkati] (STMicroelectronics) +Tarek Bochkati [tarek-bochkati] +[texane] Timothy Lee [timothytylee] Tuomo Kaikkonen Theodore A. Roth @@ -136,6 +137,7 @@ Vasiliy Glazov [Vascom] Vegard Storheil Eriksen Viacheslav Dobromyslov Victor Mayoral Vilches +[whitequark] William Ransohoff [WRansohoff] Wojciech A. Koszek Woodrow Douglass diff --git a/doc/version_support.md b/doc/version_support.md index 022fb5e4d..c87ad1772 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -25,42 +25,34 @@ Maintained versions of: Other Linux-/Unix-based Operating Systems: -| Operating System | libusb | cmake | libgtk-dev | Notes | -| ------------------------ | ------------------------------ | ---------- | ----------- | ------------------------ | -| Debian Sid | 1.0.24 | 3.22.1 | 3.24.31 | | -| Debian 11 (Bullseye) | 1.0.24 | 3.**18.4** | 3.24.24 | | -| Debian 10 (Buster) | 1.0.**22** | 3.**13.4** | 3.24.**5** | | -| | | | | | -| Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.**16.3** | 3.24.**18** | | -| | | | | | -| Alpine 3.15 | 1.0.24 | 3.21.3 | 3.24.30 | End of Support: Nov 2023 | -| Alpine 3.14 | 1.0.24 | 3.20.3 | 3.24.28 | End of Support: May 2023 | -| | | | | | -| FreeBSD 13.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | -| FreeBSD 12.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | -| | | | | | -| NetBSD 9.x | 1.0.24 | 3.21.2 | 3.24.30 | | -| NetBSD 8.x | 1.0.24 | 3.**19.7** | 3.24.27 | | -| | | | | | -| CentOS 9 Stream [x64] | 1.0.24 (`libusbx`) | 3.20.3 | 3.24.30 | | -| CentOS 8 Stream [x64] | 1.0.23 (`libusbx`) | 3.20.2 | 3.**22.30** | | -| | | | | | -| ALT Linux Sisyphus | 1.0.24 | 3.22.1 | 3.24.31 | | -| ALT Linux P10 | 1.0.24 | 3.20.5 | 3.24.31 | | -| ALT Linux P9 | 1.0.**22** | 3.**16.3** | 3.24.29 | | -| | | | | | -| OpenMandriva Rolling | 1.0.24 | 3.22.1 | 3.24.31 | | -| OpenMandriva Cooker | 1.0.24 | 3.22.1 | 3.24.31 | | -| OpenMandriva Lx 4.2 | 1.0.24 | 3.**19.3** | 3.24.24 | | -| | | | | | -| Arch Linux | 1.0.24 | 3.22.1 | - | | -| KaOS [x64] | 1.0.24 | 3.22.1 | 3.24.31 | | -| Mageia Cauldron | 1.0.24 | 3.22.1 | 3.24.31 | | -| PCLinuxOS [x64] | (?) | 3.22.1 | 3.24.31 | | -| Solus [x64] | 1.0.24 | 3.22.1 | 3.24.30 | | -| Void Linux | 1.0.24 | 3.22.1 | 3.24.31 | | -| Slackware Current | 1.0.24 | 3.21.4 | 3.24.31 | | -| Adélie 1.0 | 1.0.23 | 3.**16.4** | 3.24.23 | | +| Operating System | libusb | cmake | libgtk-dev | End of
      OS-Support | +| ------------------------ | ------------------------------ | ---------- | ----------- | ---------------------- | +| Debian Sid | 1.0.24 | 3.22.1 | 3.24.31 | | +| Debian 11 (Bullseye) | 1.0.24 | 3.**18.4** | 3.24.24 | | +| Debian 10 (Buster) | 1.0.**22** | 3.**13.4** | 3.24.**5** | Jun 2024 | +| | | | | | +| Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.**16.3** | 3.24.**18** | May 2025 | +| | | | | | +| FreeBSD 13.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | +| FreeBSD 12.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | Dec 2023 | +| | | | | | +| NetBSD 9.x | 1.0.24 | 3.21.2 | 3.24.30 | | +| NetBSD 8.x | 1.0.24 | 3.**19.7** | 3.24.27 | | +| | | | | | +| CentOS 9 Stream [x64] | 1.0.24 (`libusbx`) | 3.20.3 | 3.24.30 | | +| CentOS 8 Stream [x64] | 1.0.23 (`libusbx`) | 3.20.2 | 3.**22.30** | May 2024 | +| | | | | | +| ALT Linux Sisyphus | 1.0.24 | 3.22.1 | 3.24.31 | | +| ALT Linux P10 | 1.0.24 | 3.20.5 | 3.24.31 | | +| ALT Linux P9 | 1.0.**22** | 3.**16.3** | 3.24.29 | | +| | | | | | +| KaOS [x64] | 1.0.24 | 3.22.1 | 3.24.31 | | +| Mageia Cauldron | 1.0.24 | 3.22.1 | 3.24.31 | | +| PCLinuxOS [x64] | (?) | 3.22.1 | 3.24.31 | | +| Solus [x64] | 1.0.24 | 3.22.1 | 3.24.30 | | +| Void Linux | 1.0.24 | 3.22.1 | 3.24.31 | | +| Slackware Current | 1.0.24 | 3.21.4 | 3.24.31 | | +| Adélie 1.0 | 1.0.23 | 3.**16.4** | 3.24.23 | | ## Unsupported Operating Systems (as of Release v1.8.0) @@ -68,9 +60,12 @@ Systems with highlighted versions remain compatible with this toolset. | Operating System | libusb | cmake | End of
      OS-Support | | ---------------------------------------- | ------------------------------ | ---------- | ---------------------- | +| Alpine 3.15 | 1.0.**24** | 3.**21.3** | Nov 2023 | | Fedora 35 [x64] | 1.0.**24** | 3.**21.3** | Dec 2022 | +| Alpine 3.14 | 1.0.**24** | 3.**20.3** | May 2023 | | CentOS / Rocky Linux / AlmaLinux 8 [x64] | 1.0.**23** (`libusbx`) | 3.**20.3** | Dec 2021 | | Fedora 34 [x64] | 1.0.**24** (`libusbx`) | 3.**19.7** | Jun 2022 | +| OpenMandriva Lx 4.2 | 1.0.**24** | 3.**19.3** | Mar 2023 | | Mageia 8 | 1.0.**24** | 3.**19.2** | Aug 2022 | | Alpine 3.13 | 1.0.**24** | 3.**18.4** | Nov 2022 | | Ubuntu 21.04 (Hirsute) | 1.0.**24** | 3.**18.4** | Jan 2022 | diff --git a/src/stlink-gui/CMakeLists.txt b/src/stlink-gui/CMakeLists.txt index 042e8d37d..062814e42 100644 --- a/src/stlink-gui/CMakeLists.txt +++ b/src/stlink-gui/CMakeLists.txt @@ -2,7 +2,7 @@ # Build GUI ### -if (NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) +if (NOT WIN32) find_package(PkgConfig) pkg_check_modules(GTK3 gtk+-3.0) From 5613f281c5b8b4abe0e0f94149e5d6a4b7afa1c1 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 24 Dec 2023 00:46:56 +0100 Subject: [PATCH 1426/1435] Fixed compilation error. --- src/stlink-lib/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index 57aa53a25..c9bf67157 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -858,7 +858,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { } } else if (sl->chip_id == STM32_CHIPID_F7 || sl->chip_id == STM32_CHIPID_F76xxx) { - uint32_t sector = calculate_F7_sectornum(sl, flashaddr); + uint32_t sector = calculate_F7_sectornum(flashaddr); if (sector < 4) { sl->flash_pgsz = 0x8000; From c1efbec7a77eec1dc9611d448c4870cb6121ea2e Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 24 Dec 2023 11:47:51 +0100 Subject: [PATCH 1427/1435] Fixed incorrect chip-ID for STM32C01x MCU --- config/chips/C011xx.chip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/chips/C011xx.chip b/config/chips/C011xx.chip index b961a18f8..eac66ca68 100644 --- a/config/chips/C011xx.chip +++ b/config/chips/C011xx.chip @@ -2,7 +2,7 @@ # dev_type STM32C011xx ref_manual_id 0490 -chip_id 0x453 // STM32_CHIPID_C011xx +chip_id 0x443 // STM32_CHIPID_C011xx flash_type C0 flash_size_reg 0x1fff75a0 flash_pagesize 0x800 // 2 KB From e7f41b2965d95eff75114c6f89f13c24cb7357a2 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 24 Dec 2023 12:08:08 +0100 Subject: [PATCH 1428/1435] Support for STLINK/v2 & /v3 max trace buffers --- inc/stlink.h | 9 ++++++++- src/st-trace/trace.c | 2 +- src/stlink-lib/usb.c | 9 ++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 788392d72..0c3675083 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -66,7 +66,8 @@ enum target_state { #define STLINK_V3_MAX_FREQ_NB 10 -#define STLINK_TRACE_BUF_LEN 2048 +#define STLINK_V2_TRACE_BUF_LEN 2048 +#define STLINK_V3_TRACE_BUF_LEN 8192 #define STLINK_V2_MAX_TRACE_FREQUENCY 2000000 #define STLINK_V3_MAX_TRACE_FREQUENCY 24000000 #define STLINK_DEFAULT_TRACE_FREQUENCY 2000000 @@ -273,7 +274,13 @@ int32_t stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t int32_t stlink_load_device_params(stlink_t *sl); int32_t stlink_target_connect(stlink_t *sl, enum connect_type connect); +#include +#include +#include +#include +#include #include +#include #ifdef __cplusplus } diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 04557794a..4ef03c07b 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -425,7 +425,7 @@ static trace_state update_trace(st_trace_t *trace, uint8_t c) { } static bool read_trace(stlink_t *stlink, st_trace_t *trace) { - uint8_t buffer[STLINK_TRACE_BUF_LEN]; + uint8_t buffer[max_trace_buf_len]; int32_t length = stlink_trace_read(stlink, buffer, sizeof(buffer)); if (length < 0) { diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index d3a57c33f..b0d0494cf 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -977,11 +977,18 @@ int32_t _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t rep_len = 2; + uint32_t max_trace_buf_len; + + if(sl->version.stlink_v == 2) { + max_trace_buf_len = STLINK_V2_TRACE_BUF_LEN; + } else (sl->version.stlink_v == 3) { + max_trace_buf_len = STLINK_V3_TRACE_BUF_LEN; + } int32_t i = fill_command(sl, SG_DXFER_TO_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_APIV2_START_TRACE_RX; - write_uint16(&cmd[i + 0], 2 * STLINK_TRACE_BUF_LEN); + write_uint16(&cmd[i + 0], 2 * max_trace_buf_len); write_uint32(&cmd[i + 2], frequency); size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len, CMD_CHECK_STATUS, "START_TRACE_RX"); From 45c31e91696db3f44f2fb4aee51ba2c869fa81f7 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 24 Dec 2023 12:26:01 +0100 Subject: [PATCH 1429/1435] Added interface for spdlog (optional) --- src/stlink-lib/logging.h | 17 +++++++++++++++++ src/stlink-lib/spdlog_wrapper.h | 14 ++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/stlink-lib/spdlog_wrapper.h diff --git a/src/stlink-lib/logging.h b/src/stlink-lib/logging.h index cb49a7af3..560e20eca 100644 --- a/src/stlink-lib/logging.h +++ b/src/stlink-lib/logging.h @@ -8,10 +8,16 @@ #ifndef LOGGING_H #define LOGGING_H +#include +#include "spdlog_wrapper.h" + #ifdef __cplusplus extern "C" { #endif // __cplusplus +/* Optional: Enable interface for SPDLOG to replace UglyLogging */ +// #define SPDLOG_LOGGING + enum ugly_loglevel { UDEBUG = 90, UINFO = 50, @@ -44,6 +50,17 @@ int32_t ugly_libusb_log_level(enum ugly_loglevel v); #define ELOG_HELPER(format, ...) ugly_log(UERROR, UGLY_LOG_FILE, format, __VA_ARGS__) #define ELOG(...) ugly_log(UERROR, UGLY_LOG_FILE, __VA_ARGS__) +#if defined(SPDLOG_LOGGING) +#undef DLOG_HELPER +#undef ILOG_HELPER +#undef WLOG_HELPER +#undef ELOG_HELPER +#define DLOG(...) spdlogLog(UDEBUG, __VA_ARGS__) +#define ILOG(...) spdlogLog(UINFO, __VA_ARGS__) +#define WLOG(...) spdlogLog(UWARN, __VA_ARGS__) +#define ELOG(...) spdlogLog(UERROR, __VA_ARGS__) +#endif // SPDLOG_LOGGING + #ifdef __cplusplus } #endif // __cplusplus diff --git a/src/stlink-lib/spdlog_wrapper.h b/src/stlink-lib/spdlog_wrapper.h new file mode 100644 index 000000000..26f34c8b5 --- /dev/null +++ b/src/stlink-lib/spdlog_wrapper.h @@ -0,0 +1,14 @@ +#ifndef _SPDLOG_WRAPPER_ +#define _SPDLOG_WRAPPER_ + +#ifdef __cplusplus +#define EXTERNC extern "C" +#else +#define EXTERNC +#endif + +EXTERNC int spdlogLog(int level, const char *str, ...); + +#undef EXTERNC + +#endif \ No newline at end of file From 816730f4f7517611e5ff3a03067ae0a673fb72bd Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 24 Dec 2023 19:15:03 +0100 Subject: [PATCH 1430/1435] [refactoring] Clean-up & bugfix for st-trace --- inc/stlink.h | 3 - src/st-trace/trace.c | 159 ++++++++++++++++------------------------ src/st-trace/trace.h | 24 ++++++ src/stlink-lib/common.c | 17 ----- src/stlink-lib/usb.c | 6 +- 5 files changed, 90 insertions(+), 119 deletions(-) create mode 100644 src/st-trace/trace.h diff --git a/inc/stlink.h b/inc/stlink.h index 0c3675083..d516e5c4f 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -255,9 +255,6 @@ int32_t stlink_current_mode(stlink_t *sl); int32_t stlink_force_debug(stlink_t *sl); int32_t stlink_target_voltage(stlink_t *sl); int32_t stlink_set_swdclk(stlink_t *sl, int32_t freq_khz); -int32_t stlink_trace_enable(stlink_t* sl, uint32_t frequency); -int32_t stlink_trace_disable(stlink_t* sl); -int32_t stlink_trace_read(stlink_t* sl, uint8_t* buf, uint32_t size); int32_t stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t* *mem, uint32_t* size, uint32_t* begin); uint8_t stlink_get_erased_pattern(stlink_t *sl); int32_t stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 4ef03c07b..591e29252 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -97,6 +97,20 @@ BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { } #endif +int32_t stlink_trace_enable(stlink_t *sl, uint32_t frequency) { + DLOG("*** stlink_trace_enable ***\n"); + return (sl->backend->trace_enable(sl, frequency)); +} + +int32_t stlink_trace_disable(stlink_t *sl) { + DLOG("*** stlink_trace_disable ***\n"); + return (sl->backend->trace_disable(sl)); +} + +int32_t stlink_trace_read(stlink_t *sl, uint8_t *buf, uint32_t size) { + return (sl->backend->trace_read(sl, buf, size)); +} + static void usage(void) { puts("st-trace - usage:"); puts(" -h, --help Print this help"); @@ -112,8 +126,7 @@ static void usage(void) { puts(" -f, --force Ignore most initialization errors"); } -static bool parse_frequency(char* text, uint32_t* result) -{ +static bool parse_frequency(char* text, uint32_t* result) { if (text == NULL) { ELOG("Invalid frequency.\n"); return false; @@ -193,12 +206,10 @@ bool parse_options(int32_t argc, char **argv, st_settings_t *settings) { ugly_init(settings->logging_level); break; case 'c': - if (!parse_frequency(optarg, &settings->core_frequency)) - error = true; + if (!parse_frequency(optarg, &settings->core_frequency)) error = true; break; case 't': - if (!parse_frequency(optarg, &settings->trace_frequency)) - error = true; + if (!parse_frequency(optarg, &settings->trace_frequency)) error = true; break; case 'n': settings->reset_board = false; @@ -226,29 +237,24 @@ bool parse_options(int32_t argc, char **argv, st_settings_t *settings) { error = true; } - if (error && !settings->force) - return false; + if (error && !settings->force) return false; return true; } static stlink_t *stlink_connect(const st_settings_t *settings) { - return stlink_open_usb(settings->logging_level, false, - settings->serial_number, 0); + return stlink_open_usb(settings->logging_level, false, settings->serial_number, 0); } -static bool enable_trace(stlink_t *stlink, const st_settings_t *settings, - uint32_t trace_frequency) { +static bool enable_trace(stlink_t *stlink, const st_settings_t *settings, uint32_t trace_frequency) { if (stlink_force_debug(stlink)) { ELOG("Unable to debug device\n"); - if (!settings->force) - return false; + if (!settings->force) return false; } if (settings->reset_board && stlink_reset(stlink, RESET_SOFT_AND_HALT)) { ELOG("Unable to reset device\n"); - if (!settings->force) - return false; + if (!settings->force) return false; } stlink_write_debug32(stlink, STLINK_REG_DHCSR, @@ -262,29 +268,24 @@ static bool enable_trace(stlink_t *stlink, const st_settings_t *settings, stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION2, 0); stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION3, 0); stlink_write_debug32(stlink, STLINK_REG_DWT_CTRL, 0); - stlink_write_debug32( - stlink, STLINK_REG_DBGMCU_CR, + stlink_write_debug32(stlink, STLINK_REG_DBGMCU_CR, STLINK_REG_DBGMCU_CR_DBG_SLEEP | STLINK_REG_DBGMCU_CR_DBG_STOP | STLINK_REG_DBGMCU_CR_DBG_STANDBY | STLINK_REG_DBGMCU_CR_TRACE_IOEN | STLINK_REG_DBGMCU_CR_TRACE_MODE_ASYNC); if (stlink_trace_enable(stlink, trace_frequency)) { ELOG("Unable to turn on tracing in stlink\n"); - if (!settings->force) - return false; + if (!settings->force) return false; } - stlink_write_debug32(stlink, STLINK_REG_TPI_CSPSR, - STLINK_REG_TPI_CSPSR_PORT_SIZE_1); + stlink_write_debug32(stlink, STLINK_REG_TPI_CSPSR, STLINK_REG_TPI_CSPSR_PORT_SIZE_1); if (settings->core_frequency) { uint32_t prescaler = settings->core_frequency / trace_frequency - 1; if (prescaler > STLINK_REG_TPI_ACPR_MAX) { - ELOG("Trace frequency prescaler %d out of range. Try setting a faster " - "trace frequency.\n", - prescaler); - if (!settings->force) - return false; + ELOG("Trace frequency prescaler %d out of range. Try setting a faster " + "trace frequency.\n", prescaler); + if (!settings->force) return false; } stlink_write_debug32(stlink, STLINK_REG_TPI_ACPR, prescaler); // Set TPIU_ACPR clock divisor @@ -294,12 +295,11 @@ static bool enable_trace(stlink_t *stlink, const st_settings_t *settings, stlink_write_debug32(stlink, STLINK_REG_TPI_SPPR, STLINK_REG_TPI_SPPR_SWO_NRZ); stlink_write_debug32(stlink, STLINK_REG_ITM_LAR, STLINK_REG_ITM_LAR_KEY); - stlink_write_debug32(stlink, STLINK_REG_ITM_TCC, - 0x00000400); // Set sync counter + stlink_write_debug32(stlink, STLINK_REG_ITM_TCC, 0x00000400); // Set sync counter stlink_write_debug32(stlink, STLINK_REG_ITM_TCR, STLINK_REG_ITM_TCR_TRACE_BUS_ID_1 | - STLINK_REG_ITM_TCR_TS_ENA | - STLINK_REG_ITM_TCR_ITM_ENA); + STLINK_REG_ITM_TCR_TS_ENA | + STLINK_REG_ITM_TCR_ITM_ENA); stlink_write_debug32(stlink, STLINK_REG_ITM_TER, STLINK_REG_ITM_TER_PORTS_ALL); stlink_write_debug32(stlink, STLINK_REG_ITM_TPR, @@ -333,9 +333,7 @@ static bool enable_trace(stlink_t *stlink, const st_settings_t *settings, static trace_state update_trace_idle(st_trace_t *trace, uint8_t c) { // Handle a trace byte when we are in the idle state. - if (TRACE_OP_IS_TARGET_SOURCE(c)) { - return TRACE_STATE_TARGET_SOURCE; - } + if (TRACE_OP_IS_TARGET_SOURCE(c)) return TRACE_STATE_TARGET_SOURCE; if (TRACE_OP_IS_SOURCE(c)) { uint8_t size = TRACE_OP_GET_SOURCE_SIZE(c); @@ -345,36 +343,28 @@ static trace_state update_trace_idle(st_trace_t *trace, uint8_t c) { WLOG("Unsupported source 0x%x size %d\n", addr, size); trace->unknown_sources |= (1 << addr); } - if (size == 1) - return TRACE_STATE_SKIP_1; - if (size == 2) - return TRACE_STATE_SKIP_2; - if (size == 3) - return TRACE_STATE_SKIP_4; + if (size == 1) return TRACE_STATE_SKIP_1; + if (size == 2) return TRACE_STATE_SKIP_2; + if (size == 3) return TRACE_STATE_SKIP_4; } if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { trace->count_time_packets++; - return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME - : TRACE_STATE_IDLE; + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; } if (TRACE_OP_IS_EXTENSION(c)) { - return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME - : TRACE_STATE_IDLE; + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; } - if (TRACE_OP_IS_OVERFLOW(c)) { - trace->count_hw_overflow++; - } + if (TRACE_OP_IS_OVERFLOW(c)) trace->count_hw_overflow++; if (!(trace->unknown_opcodes[c / 8] & (1 << c % 8))) WLOG("Unknown opcode 0x%02x\n", c); trace->unknown_opcodes[c / 8] |= (1 << c % 8); trace->count_error++; - return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME - : TRACE_STATE_IDLE; + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; } static trace_state update_trace(st_trace_t *trace, uint8_t c) { @@ -383,8 +373,7 @@ static trace_state update_trace(st_trace_t *trace, uint8_t c) { // Parse the input using a state machine. if (trace->state == TRACE_STATE_UNKNOWN) { - if (TRACE_OP_IS_TARGET_SOURCE(c) || TRACE_OP_IS_LOCAL_TIME(c) || - TRACE_OP_IS_GLOBAL_TIME(c)) + if (TRACE_OP_IS_TARGET_SOURCE(c) || TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) trace->state = TRACE_STATE_IDLE; } @@ -394,14 +383,12 @@ static trace_state update_trace(st_trace_t *trace, uint8_t c) { case TRACE_STATE_TARGET_SOURCE: putchar(c); - if (c == '\n') - fflush(stdout); + if (c == '\n') fflush(stdout); trace->count_target_data++; return TRACE_STATE_IDLE; case TRACE_STATE_SKIP_FRAME: - return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME - : TRACE_STATE_IDLE; + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; case TRACE_STATE_SKIP_4: return TRACE_STATE_SKIP_3; @@ -425,7 +412,7 @@ static trace_state update_trace(st_trace_t *trace, uint8_t c) { } static bool read_trace(stlink_t *stlink, st_trace_t *trace) { - uint8_t buffer[max_trace_buf_len]; + uint8_t* buffer = 0; int32_t length = stlink_trace_read(stlink, buffer, sizeof(buffer)); if (length < 0) { @@ -453,8 +440,7 @@ static bool read_trace(stlink_t *stlink, st_trace_t *trace) { return true; } -static void check_for_configuration_error(stlink_t *stlink, st_trace_t *trace, - uint32_t trace_frequency) { +static void check_for_configuration_error(stlink_t *stlink, st_trace_t *trace, uint32_t trace_frequency) { // Only check configuration one time after the first 10 seconds of running. time_t elapsed_time_s = time(NULL) - trace->start_time; if (trace->configuration_checked || elapsed_time_s < 10) { @@ -469,8 +455,7 @@ static void check_for_configuration_error(stlink_t *stlink, st_trace_t *trace, bool error_bad_data = (trace->count_error > 1 || trace->unknown_sources > 0); bool error_dropped_data = (trace->count_sw_overflow > 0); - if (!error_no_data && !error_low_data && !error_bad_data && - !error_dropped_data) + if (!error_no_data && !error_low_data && !error_bad_data && !error_dropped_data) return; WLOG("****\n"); @@ -487,8 +472,7 @@ static void check_for_configuration_error(stlink_t *stlink, st_trace_t *trace, stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR, &prescaler); if (prescaler) { uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; - WLOG("Verify the system clock is running at %d Hz.\n", - system_clock_speed); + WLOG("Verify the system clock is running at %d Hz.\n", system_clock_speed); } WLOG("Try specifying the system clock with the --clock=XX command line " "option.\n"); @@ -510,11 +494,8 @@ static void check_for_configuration_error(stlink_t *stlink, st_trace_t *trace, uint32_t offset = 0; for (uint32_t i = 0; i <= 0xFF; i++) if (trace->unknown_opcodes[i / 8] & (1 << i % 8)) { - uint32_t n = - snprintf(buffer + offset, sizeof(buffer) - offset, "%02x, ", i); - if (n >= sizeof(buffer) - offset) { - break; - } + uint32_t n = snprintf(buffer + offset, sizeof(buffer) - offset, "%02x, ", i); + if (n >= sizeof(buffer) - offset) break; offset += n; } WLOG("Unknown Opcodes: %s\n", buffer); @@ -523,11 +504,8 @@ static void check_for_configuration_error(stlink_t *stlink, st_trace_t *trace, offset = 0; for (uint32_t i = 0; i < 32; i++) if (trace->unknown_sources & (1 << i)) { - uint32_t n = - snprintf(buffer + offset, sizeof(buffer) - offset, "%d, ", i); - if (n >= sizeof(buffer) - offset) { - break; - } + uint32_t n = snprintf(buffer + offset, sizeof(buffer) - offset, "%d, ", i); + if (n >= sizeof(buffer) - offset) break; offset += n; } WLOG("Unknown Sources: %s\n", buffer); @@ -583,48 +561,38 @@ int32_t main(int32_t argc, char **argv) { if (stlink->chip_id == STM32_CHIPID_UNKNOWN) { ELOG("Your stlink is not connected to a device\n"); - if (!settings.force) - return APP_RESULT_STLINK_MISSING_DEVICE; + if (!settings.force) return APP_RESULT_STLINK_MISSING_DEVICE; } if (!(stlink->version.flags & STLINK_F_HAS_TRACE)) { ELOG("Your stlink does not support tracing\n"); - if (!settings.force) - return APP_RESULT_STLINK_UNSUPPORTED_LINK; + if (!settings.force) return APP_RESULT_STLINK_UNSUPPORTED_LINK; } if (!(stlink->chip_flags & CHIP_F_HAS_SWO_TRACING)) { - const struct stlink_chipid_params *params = - stlink_chipid_get_params(stlink->chip_id); - ELOG("We do not support SWO output for device '%s'\n", - params ? params->dev_type : ""); - if (!settings.force) - return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; + const struct stlink_chipid_params *params = stlink_chipid_get_params(stlink->chip_id); + ELOG("We do not support SWO output for device '%s'\n", params ? params->dev_type : ""); + if (!settings.force) return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; } uint32_t trace_frequency = settings.trace_frequency; - if (!trace_frequency) - trace_frequency = STLINK_DEFAULT_TRACE_FREQUENCY; + if (!trace_frequency) trace_frequency = STLINK_DEFAULT_TRACE_FREQUENCY; uint32_t max_trace_freq = stlink->max_trace_freq; uint32_t min_trace_freq = 0; if (settings.core_frequency != 0) { - if (max_trace_freq > settings.core_frequency / 5) - max_trace_freq = settings.core_frequency / 5; + if (max_trace_freq > settings.core_frequency / 5) max_trace_freq = settings.core_frequency / 5; min_trace_freq = settings.core_frequency / (STLINK_REG_TPI_ACPR_MAX + 1); } - if (trace_frequency > max_trace_freq || - trace_frequency < min_trace_freq) { - ELOG("Invalid trace frequency %d (min %d max %d)\n", trace_frequency, - min_trace_freq, max_trace_freq); - if (!settings.force) - return APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY; + if (trace_frequency > max_trace_freq || trace_frequency < min_trace_freq) { + ELOG("Invalid trace frequency %d (min %d max %d)\n", trace_frequency, min_trace_freq, + max_trace_freq); + if (!settings.force) return APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY; } if (!enable_trace(stlink, &settings, trace_frequency)) { ELOG("Unable to enable trace mode\n"); - if (!settings.force) - return APP_RESULT_STLINK_STATE_ERROR; + if (!settings.force) return APP_RESULT_STLINK_STATE_ERROR; } ILOG("Reading Trace\n"); @@ -634,8 +602,7 @@ int32_t main(int32_t argc, char **argv) { if (stlink_run(stlink, RUN_NORMAL)) { ELOG("Unable to run device\n"); - if (!settings.force) - return APP_RESULT_STLINK_STATE_ERROR; + if (!settings.force) return APP_RESULT_STLINK_STATE_ERROR; } while (!g_abort_trace && read_trace(stlink, &trace)) { diff --git a/src/st-trace/trace.h b/src/st-trace/trace.h new file mode 100644 index 000000000..8dfc7e42d --- /dev/null +++ b/src/st-trace/trace.h @@ -0,0 +1,24 @@ +/* + * File: trace.h + * + * Tool st-trace + */ + +#ifndef TRACE_H +#define TRACE_H + +int32_t stlink_trace_enable(stlink_t* sl, uint32_t frequency); +int32_t stlink_trace_disable(stlink_t* sl); +int32_t stlink_trace_read(stlink_t* sl, uint8_t* buf, uint32_t size); + +static void usage(void); +static bool parse_frequency(char* text, uint32_t* result); +bool parse_options(int32_t argc, char **argv, st_settings_t *settings); +static stlink_t *stlink_connect(const st_settings_t *settings); +static bool enable_trace(stlink_t *stlink, const st_settings_t *settings, uint32_t trace_frequency); +static trace_state update_trace_idle(st_trace_t *trace, uint8_t c); +static trace_state update_trace(st_trace_t *trace, uint8_t c); +static bool read_trace(stlink_t *stlink, st_trace_t *trace); +static void check_for_configuration_error(stlink_t *stlink, st_trace_t *trace, uint32_t trace_frequency); + +#endif // TRACE_H \ No newline at end of file diff --git a/src/stlink-lib/common.c b/src/stlink-lib/common.c index c9bf67157..3e49a779d 100644 --- a/src/stlink-lib/common.c +++ b/src/stlink-lib/common.c @@ -599,23 +599,6 @@ int32_t stlink_current_mode(stlink_t *sl) { return (STLINK_DEV_UNKNOWN_MODE); } -// 274 -int32_t stlink_trace_enable(stlink_t *sl, uint32_t frequency) { - DLOG("*** stlink_trace_enable ***\n"); - return (sl->backend->trace_enable(sl, frequency)); -} - -// 275 -int32_t stlink_trace_disable(stlink_t *sl) { - DLOG("*** stlink_trace_disable ***\n"); - return (sl->backend->trace_disable(sl)); -} - -// 276 -int32_t stlink_trace_read(stlink_t *sl, uint8_t *buf, uint32_t size) { - return (sl->backend->trace_read(sl, buf, size)); -} - // 294 void stlink_print_data(stlink_t *sl) { if (sl->q_len <= 0 || sl->verbose < UDEBUG) { diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index b0d0494cf..83e2652ea 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -977,13 +977,13 @@ int32_t _stlink_usb_enable_trace(stlink_t* sl, uint32_t frequency) { unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t rep_len = 2; - uint32_t max_trace_buf_len; + uint32_t max_trace_buf_len = 0; if(sl->version.stlink_v == 2) { max_trace_buf_len = STLINK_V2_TRACE_BUF_LEN; - } else (sl->version.stlink_v == 3) { + } else if (sl->version.stlink_v == 3) { max_trace_buf_len = STLINK_V3_TRACE_BUF_LEN; - } + }; int32_t i = fill_command(sl, SG_DXFER_TO_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; From 8c581c3eec91248de028c332a06ea276bbb2e969 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 25 Dec 2023 14:40:10 +0100 Subject: [PATCH 1431/1435] Updated CHANGELOG.md --- CHANGELOG.md | 1 + src/stlink-lib/common_flash.c | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c477eb54a..c1f998600 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -95,6 +95,7 @@ Fixes: - [compilation] Corrected path to stlink/chips subdirectory ([#1276](https://github.com/stlink-org/stlink/pull/1276), [#1279](https://github.com/stlink-org/stlink/pull/1279)) - [compilation] Fixed GUI compilation failure on OpenBSD i386 ([#1284](https://github.com/stlink-org/stlink/pull/1284)) - [STM32U5x5]: Last bytes are not written (flashed) when len()%16 <= 8 ([#1303](https://github.com/stlink-org/stlink/pull/1303), [#1315](https://github.com/stlink-org/stlink/pull/1315)) +- [STM32WLE]: Erase flash fails on second page ([#1305](https://github.com/stlink-org/stlink/pull/1305), commit [#7dcb130](https://github.com/stlink-org/stlink/commit/7dcb1302d8b91b2217c4ce50cb255aa8e78ab001)) - Fixed unbounded write and check return values of sscanf ([#1306](https://github.com/stlink-org/stlink/pull/1306)) - Added null check for return value of stlink_chipid_get_params() ([#1307](https://github.com/stlink-org/stlink/pull/1307)) - Fixed warning in a few *.cmake files ([#1309](https://github.com/stlink-org/stlink/pull/1309)) diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index ef6b8370c..6a519f1fc 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -387,9 +387,7 @@ int32_t check_flash_error(stlink_t *sl) { res &= ~PGAERR; } - if (res) { - ELOG("Flash programming error: %#010x\n", res); - } + if (res) ELOG("Flash programming error: %#010x\n", res); return (-1); } From 0145baeb2e3bac31bf9d3cbd0dab38d70618d46b Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 20 Jan 2024 13:00:52 +0100 Subject: [PATCH 1432/1435] Fixed memory alignment for STM32L5/U5/H5 chips (Closes #1362) --- src/stlink-lib/common_flash.c | 2 +- src/stlink-lib/flash_loader.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/stlink-lib/common_flash.c b/src/stlink-lib/common_flash.c index 6a519f1fc..aa8db5bfd 100644 --- a/src/stlink-lib/common_flash.c +++ b/src/stlink-lib/common_flash.c @@ -1140,7 +1140,7 @@ int32_t stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { // set bank 1 for erasure val &= ~(1 << FLASH_L5_NSCR_NSBKER); } - // sec 7.9.9 for U5, 6.9.9 for L5 (for L7 we have 7 bits instead 8 bits for U5 but + // sec 7.9.9 for U5, 6.9.9 for L5 (for L7 we have 7 bits instead of 8 bits for U5 but // the bit position for 8th bit reserved. // Maybe the best solution is to handle each one separately. val &= ~(0xFF << 3); diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 9511c9282..16c717ca7 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -748,6 +748,11 @@ int32_t stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t sl->flash_type == STM32_FLASH_TYPE_G4 || sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5 || sl->flash_type == STM32_FLASH_TYPE_C0) { + + if (sl->flash_type == STM32_FLASH_TYPE_L5_U5_H5 && (len % 16)) { + WLOG("Data size is aligned to 16 byte"); + len += 16 - len%16; + } DLOG("Starting %3u page write\n", len / sl->flash_pgsz); for (off = 0; off < len; off += sizeof(uint32_t)) { uint32_t data; From 32e8dcc8b5dbed7b6412e7838ea1b2c41f0247fd Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 21 Jan 2024 14:43:22 +0100 Subject: [PATCH 1433/1435] [doc] Updated tutorial: Access to the UART via a virtual COM port (Closes #1334) --- doc/tutorial.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 36c80c674..da09978e7 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -43,7 +43,7 @@ The stlink-gui offers the following features: Within the GUI main window tooltips explain the available user elements. -## Solutions to common problems +## HowTos & solutions to common problems ### a) Verify if udev rules are set correctly (by Dave Hylands) @@ -164,6 +164,17 @@ However the external bus can be *RAM* or *ROM* depending on design. The STM32H735-DK has external FLASH at address 0x90000000. As a result, because the entire external memory range is `ram` as it could be either, software breakpoints (Z0) get sent when a breakpoint is created and they never get tripped as the memory area is read only. +### f) UART-Access via a virtual COM port + +Access to the Universal Asynchronous Receiver Transmitter (UART) via a virtual COM port is not related to the stlink toolset itself. It is an independent feature that should natively be available on UNIX-based operating systems. Windows operating systems require the installation of a virtual COM device driver. The appropriate device driver is downloaded and installed automatically via Windows Update in the background as soon as the device is plugged-in for the first time. A connected ST-LINK programmer with UART functionality is detected as a CDC (ACM) USB device. After each reset the device will be reloaded and will pop up as `/dev/ttyACM0` or `/dev/ttyACM1` depending on the specific design. + +UART connections to the interface are typically initiated with a serial terminal. For UNIX operating systems we recommend to use either [minicom](https://en.wikipedia.org/wiki/Minicom) (terminal-based) or [cutecom](https://cutecom.sourceforge.net/) (GUI-based). Windows users should have a look at [Teraterm](https://github.com/TeraTermProject/teraterm). + +Most common and established settings for the interface are 115200 or 9600 baud together with the `8-N-1` configuration, standing for (8) data bits, no parity bit (N) and (1) stop bit. Please refer to relevant literature on the UART interface for more detailed technical information and limitations. + +Note: On some debian-based UNIX-based systems the `modemmanager` package is installed by default. In has been reported that this tool unfortunately may delay the release of the serial port to applications which is handled by the operating system in the background. Subseqently the CDC/ACM device is also delayed after each reset. This typically includes not only the connection itself, but also some programming operations (at least those using the mass storage emulation). However one can not predict the behaviour exactly - in some cases the boards may be essentially useless or even working fairly well. +Proper determined functionality can be achieved by uninstalling the `modemmanager` package or by setting an appropriate `udev` device rule. + --- ( Content below is currently unrevised and may be outdated as of Mar 2021. ) From 926e7efe4c44fdf1deac0138c6c78965d49e7dc3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 30 Jan 2024 23:40:04 +0100 Subject: [PATCH 1434/1435] General Project Update - Updated build script for Windows - [doc] Updated documentation on: --> compile instructions --> release preparation steps --> list of supported devices --> OS version support status --- doc/compiling.md | 38 ++------------------------------------ doc/release.md | 14 +++++++------- doc/supported_devices.md | 7 +++++-- doc/version_support.md | 2 +- mingw64-build.bat | 2 +- 5 files changed, 16 insertions(+), 47 deletions(-) diff --git a/doc/compiling.md b/doc/compiling.md index e2c686c0a..804781faa 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -16,35 +16,14 @@ On Windows users should ensure that the following software is installed: 1. Install `git` from 2. Install `cmake` from
      Ensure that you add cmake to the $PATH system variable when following the instructions by the setup assistant. -3. Install - - - _EITHER_: Download **MinGW-w64** from . Extract content to `C:\mingw-w64\` and add `C:\mingw-w64\bin\` to PATH-Variable.
      - - _OR_: **MSVC toolchain** from Visual Studio Build Tools 2019 +3. Install MinGW-w64
      + Download **MinGW-w64** from . Extract content to `C:\mingw-w64\` and add `C:\mingw-w64\bin\` to PATH-Variable.
      4. Create a new destination folder at a place of your choice 5. Open the command-line (cmd.exe) and execute `cd C:\$Path-to-your-destination-folder$\` 6. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git`from the command-line (cmd.exe)
      or download and extract the stlink zip-sourcefolder from the Release page on GitHub. -#### MSVC toolchain - minimal installation - -Visual Studio IDE is not necessary, only Windows SDK & build tools are required (~3,3GB). - -1. Open -2. Navigate through menus as follows (might change overtime) - - `All downloads > Tools for Visual Studio 2019 > Build Tools for Visual Studio 2019 > Download` - -3. Start downloaded executable. After Visual Studio Installer bootstraps and main window pops up, open `Individual Components` tab, and pick - -- latest build tools (eg. `MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.25)`) -- latest Windows SDK (eg. `Windows 10 SDK (10.0.18362.0)`) - -4. After installation finishes, you can press `Launch` button in Visual Studio Installer's main menu. - - Thus you can open `Developer Command Prompt for VS 2019`. It is `cmd.exe` instance with adjusted PATHs including eg. `msbuild`. - - Alternatively, you can use `Developer Powershell for VS 2019` which is the same thing for `powershell.exe`. Both are available from Start menu. - - Another option is to add `msbuild` to PATH manually. Its location should be `C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin`. Then, it should be available from any `powershell.exe` or `cmd.exe` session. - ### Building #### MinGW-w64 @@ -58,19 +37,6 @@ Per default the build script (currently) uses `C:\mingw-w64\x86_64-8.1.0-release When installing different toolchains make sure to update the path in the `mingw64-build.bat`.
      This can be achieved by opening the .bat file with a common text editor. -#### MSVC toolchain - -1. In a command prompt, change the directory to the folder where the stlink files were cloned (or unzipped) to. -2. Make sure the build folder exists (`mkdir build` if not). -3. From the build folder, run cmake (`cd build; cmake ..`). - -This will create a solution file `stlink.sln` in the build folder. -Now, you can build whole `stlink` suite using following command: - -``` -msbuild /m /p:Configuration=Release stlink.sln -``` - Options: - `/m` - compilation runs in parallel utilizing multiple cores diff --git a/doc/release.md b/doc/release.md index 7d5ead83c..25cb2d5ff 100644 --- a/doc/release.md +++ b/doc/release.md @@ -3,12 +3,12 @@ Release This document describes the necessary steps for developers to create a release: -1. Update `CHANGELOG.md`, `cmake/packaging/deb/changelog` & `cmake/packaging/rpm/changelog` +1. Update changelog (`CHANGELOG.md`, `cmake/packaging/deb/changelog` & `cmake/packaging/rpm/changelog`) 2. Update `.version` with semantic version: `x.x.x` 3. Update `README.md` with semantic version `x.x.x` in commits badge -4. Merge `develop` into `master` -5. Create and push git tag and commits `git tag x.x.x` -6. Create binary packages (.rpm / .deb / .zip) with `make package && sh ./cmake/packaging/windows/generate_binaries.sh` -7. Upload packages to the [release page](https://github.com/stlink-org/stlink/releases) of this project -8. Merge `master` into `develop` -9. Update GitHub security policy (/SECURITY.md) +4. Update GitHub security policy (`SECURITY.md`) +5. Merge `develop` into `master` +6. Create and push git tag and commits `git tag x.x.x` +7. Create binary packages (.rpm / .deb / .zip) with `make package && sh ./cmake/packaging/windows/generate_binaries.sh` +8. Upload packages to the [release page](https://github.com/stlink-org/stlink/releases) of this project +9. Merge `master` into `develop` diff --git a/doc/supported_devices.md b/doc/supported_devices.md index 103c7fb5f..b22b1c11a 100644 --- a/doc/supported_devices.md +++ b/doc/supported_devices.md @@ -30,10 +30,13 @@ More commonly these are: | STM32F4 | M4F | | | STM32G4 | M4F | | | STM32L4 | M4F | | -| STM32F7 | M4F | | -| STM32H7 | M4F | | +| STM32F7 | M7F | | +| STM32H7 | M7F | | | STM32WB | M4F | | | STM32WL | M4 | | +| STM32L5 | M33 | | +| STM32H5 | M33 | | +| STM32U5 | M33 | | # Chinese Clone-Chips [may work, but without support!] diff --git a/doc/version_support.md b/doc/version_support.md index c87ad1772..c0c8389dd 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -34,7 +34,6 @@ Other Linux-/Unix-based Operating Systems: | Ubuntu 20.04 LTS (Focal) | 1.0.23 | 3.**16.3** | 3.24.**18** | May 2025 | | | | | | | | FreeBSD 13.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | | -| FreeBSD 12.x | 1.0.**16-18** (API 0x01000102) | 3.22.1 | 3.24.31 | Dec 2023 | | | | | | | | NetBSD 9.x | 1.0.24 | 3.21.2 | 3.24.30 | | | NetBSD 8.x | 1.0.24 | 3.**19.7** | 3.24.27 | | @@ -60,6 +59,7 @@ Systems with highlighted versions remain compatible with this toolset. | Operating System | libusb | cmake | End of
      OS-Support | | ---------------------------------------- | ------------------------------ | ---------- | ---------------------- | +| FreeBSD 12.x | 1.0.**16-18** (API 0x01000102) | 3.**22.1** | Dec 2023 | | Alpine 3.15 | 1.0.**24** | 3.**21.3** | Nov 2023 | | Fedora 35 [x64] | 1.0.**24** | 3.**21.3** | Dec 2022 | | Alpine 3.14 | 1.0.**24** | 3.**20.3** | May 2023 | diff --git a/mingw64-build.bat b/mingw64-build.bat index b52e529e2..bc50c97a3 100644 --- a/mingw64-build.bat +++ b/mingw64-build.bat @@ -2,7 +2,7 @@ mkdir build-mingw cd build-mingw -set PATH=C:\Program Files (x86)\CMake\bin;C:\Program Files\CMake\bin;C:\mingw-w64\x86_64-8.1.0-win32-sjlj-rt_v6-rev0\mingw64\bin;%PATH% +set PATH=C:\Program Files\CMake\bin;C:\mingw-w64\x86_64-13.2.0-release-win32-seh-msvcrt-rt_v11-rev1\mingw64\bin;%PATH% cmake -G "MinGW Makefiles" .. mingw32-make mingw32-make install From 133c2564dee478ed2fcf634ae217441ac723b3e3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 1 Feb 2024 00:00:02 +0100 Subject: [PATCH 1435/1435] Release v1.8.0 --- .version | 2 +- CHANGELOG.md | 9 +++++---- README.md | 4 ++-- SECURITY.md | 1 + cmake/packaging/deb/changelog | 6 ++++++ cmake/packaging/rpm/changelog | 3 +++ 6 files changed, 18 insertions(+), 7 deletions(-) diff --git a/.version b/.version index bd8bf882d..27f9cd322 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.7.0 +1.8.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index c1f998600..5c618a752 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,14 @@ # v1.8.0 -Release date: 2024-xx-xx +Release date: 2024-02-01 This release drops support for macOS and some older operating systems. Check project README for details. Removed Travis CI integration as it is no longer functional. Updated system requirements: -- `cmake` >= 3.10.2 -- `libusb` >= 1.0.21 +- `cmake` >= 3.13.0 +- `libusb` >= 1.0.22 - `libgtk-dev` >= 3.22.30 Features: @@ -59,7 +59,7 @@ Updates & changes: - [doc] Fixed broken links ([#1312](https://github.com/stlink-org/stlink/pull/1312)) - [doc] Updated package source link for Arch Linux ([#1318](https://github.com/stlink-org/stlink/pull/1318)) - CMake: Avoid hard-wired /usr/local/share ([#1325](https://github.com/stlink-org/stlink/pull/1325)) - +- [doc] Provide access to the UART via virtual com port ([#1334](https://github.com/stlink-org/stlink/pull/1334), commit [#32e8dcc](https://github.com/stlink-org/stlink/commit/32e8dcc8b5dbed7b6412e7838ea1b2c41f0247fd)) Fixes: @@ -104,6 +104,7 @@ Fixes: - Notification "unknown option -- u" in tool st-util ([#1326](https://github.com/stlink-org/stlink/pull/1326), [#1327](https://github.com/stlink-org/stlink/pull/1327)) - Do not crash when the STLink chip returns a voltage factor of zero ([#1343](https://github.com/stlink-org/stlink/pull/1343)) - stlink-gui: failed to allocate 139988352155568 bytes ([#1356](https://github.com/stlink-org/stlink/pull/1356)) +- [STM32U575RGT6]: Verification failed at offset 43008 ([#1362](https://github.com/stlink-org/stlink/pull/1362), commit [#0145bae](https://github.com/stlink-org/stlink/commit/0145baeb2e3bac31bf9d3cbd0dab38d70618d46b)) # v1.7.0 diff --git a/README.md b/README.md index ad1bfe910..93cdac07d 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/stlink-org/stlink.svg)](https://github.com/stlink-org/stlink/releases/latest) [![Downloads](https://img.shields.io/github/downloads/stlink-org/stlink/total)](https://github.com/stlink-org/stlink/releases/latest) -![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.7.0/develop) +![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.8.0/develop) ![GitHub activity](https://img.shields.io/github/commit-activity/m/stlink-org/stlink) ![GitHub contributors](https://img.shields.io/github/contributors/stlink-org/stlink) [![CodeQL](https://github.com/stlink-org/stlink/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/stlink-org/stlink/actions/workflows/codeql-analysis.yml) @@ -81,7 +81,7 @@ We recommend to install `stlink-tools` from the package repository of the used d **macOS**: -**Support for macOS will be dropped with v1.8.0.** +**Support for macOS has been dropped with v1.8.0.** Please use v1.7.0 instead, **but note that this version is no longer maintained and supported!** diff --git a/SECURITY.md b/SECURITY.md index 13432b927..3a357bafc 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -7,6 +7,7 @@ The following versions of the stlink toolset are currently being supported.
      Thu, 01 Feb 2024 00:00:00 +0100 + stlink (1.7.0) unstable; urgency=medium * Release v1.7.0 diff --git a/cmake/packaging/rpm/changelog b/cmake/packaging/rpm/changelog index 3d1c76996..36853060d 100644 --- a/cmake/packaging/rpm/changelog +++ b/cmake/packaging/rpm/changelog @@ -1,3 +1,6 @@ +* Thu Feb 01 2024 Nightwalker-87 - 1.8.0 +- Release v1.8.0 + * Sun Apr 25 2021 Nightwalker-87 - 1.7.0 - Release v1.7.0

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 delta 55055 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ø|Me-&gP);|dJFPuis(f9aHYwo-g-TJYIbLI)sc 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 diff --git a/doc/tutorial/tutorial.tex b/doc/tutorial/tutorial.tex index 9f8694d06..4aafa2024 100644 --- a/doc/tutorial/tutorial.tex +++ b/doc/tutorial/tutorial.tex @@ -24,7 +24,7 @@ \section{Overview} \paragraph{} This guide details the use of STMicroelectronics STM32 discovery kits in -an opensource environment. +an open source environment. \newpage @@ -48,18 +48,18 @@ \section{Installing a GNU toolchain} \section{Installing STLINK} \paragraph{} -STLINK is an opensource software to program and debug the discovery kits. Those +STLINK is open source software to program and debug ST's STM32 Discovery kits. Those kits have an onboard chip that translates USB commands sent by the host PC into -JTAG commands. This chip is called STLINK, which is confusing since the software -has the same name. It comes into 2 versions (STLINK v1 and v2). From a software +JTAG/SWD commands. This chip is called STLINK, (yes, isn't that confusing? suggest a better +name!) and comes in 2 versions (STLINK v1 and v2). From a software point of view, those versions differ only in the transport layer used to communicate -(v1 uses SCSI passthru commands, while v2 uses raw USB). +(v1 uses SCSI passthru commands, while v2 uses raw USB). From a user point of view, they +are identical. \paragraph{} Before continuing, the following dependencies must be met: \begin{itemize} \item libusb-1.0 -\item libsgutils2 (optionnal) \end{itemize} \paragraph{} @@ -78,7 +78,7 @@ \section{Installing STLINK} \begin{small} \begin{lstlisting}[frame=tb] $> cd stlink.git -$> make CONFIG_USE_LIBSG=0 +$> make \end{lstlisting} \end{small} It includes: @@ -95,13 +95,20 @@ \section{Building and running a program} 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 \end{lstlisting} \end{small} This builds three files, one for each of the Discovery boards currently -available. +available, linked to run from SRAM. (So no risk of overwriting anything you didn't mean to) +These blink examples can safely be used to verify that: + +\begin{itemize} +\item Your installed toolchain is capable of compiling for cortex M3/M4 targets +\item stlink is functional +\item Your arm-none-eabi-gdb is functional +\item Your board is functional +\end{itemize} \paragraph{} A GDB server must be started to interact with the STM32. Depending on the discovery kit you @@ -109,10 +116,10 @@ \section{Building and running a program} \begin{small} \begin{lstlisting}[frame=tb] # STM32VL discovery kit (onboard ST-link) -$> sudo ./st-util --stlinkv1 [-d /dev/sg2] +$> ./st-util --stlinkv1 # STM32L or STM32F4 discovery kit (onboard ST-link/V2) -$> sudo ./st-util +$> ./st-util # Full help for other options (listen port, version) $> ./st-util --help @@ -140,7 +147,8 @@ \section{Building and running a program} memory map, GDB knows this address belongs to SRAM. To load the program in SRAM, simply use:\\ \begin{small} \begin{lstlisting}[frame=tb] -$> load blink.elf +$> # Choose one as appropriate for your Discovery kit +$> load blink_32L.elf | load blink_32VL.elf | load blink_F4.elf \end{lstlisting} \end{small} @@ -154,8 +162,7 @@ \section{Building and running a program} \end{small} \paragraph{} -The board BLUE and GREEN leds should be blinking (those leds are near the user and reset buttons). - +All the LEDs on the board should now be blinking in time (those leds are near the user and reset buttons). \newpage \section{Reading and writing to flash} @@ -168,13 +175,13 @@ \section{Reading and writing to flash} $> cd stlink.git/flash ; # stlinkv1 command to read 4096 from flash into out.bin -$> ./flash read /dev/sg2 out.bin 0x8000000 4096 +$> ./flash read v1 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 +$> ./flash write v1 in.bin 0x8000000 # stlinkv2 command $> ./flash write in.bin 0x8000000 @@ -225,16 +232,6 @@ \subsection{libstm32l\_discovery} \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} diff --git a/flash/main.c b/flash/main.c index 849b5d6cd..44157816e 100644 --- a/flash/main.c +++ b/flash/main.c @@ -88,8 +88,7 @@ int main(int ac, char** av) if (o.devname != NULL) /* stlinkv1 */ { - static const int scsi_verbose = 2; - sl = stlink_v1_open(o.devname, scsi_verbose); + sl = stlink_v1_open(100); if (sl == NULL) goto on_error; } else /* stlinkv2 */ From e2245196082f8cac03b0a57a12198d9396c3ca85 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 4 Nov 2011 02:30:13 +0000 Subject: [PATCH 0036/1435] Include a udev rules file for v1 boards too, for permissions --- 49-stlinkv1.rules | 11 +++++++++++ README | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 49-stlinkv1.rules diff --git a/49-stlinkv1.rules b/49-stlinkv1.rules new file mode 100644 index 000000000..d474d6a40 --- /dev/null +++ b/49-stlinkv1.rules @@ -0,0 +1,11 @@ +# stm32 discovery boards, with onboard st/linkv1 +# ie, STM32VL + +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3744", \ + MODE:="0666", \ + SYMLINK+="stlinkv1_%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/README b/README index 109aa2500..470c52a59 100644 --- a/README +++ b/README @@ -75,13 +75,13 @@ for GDB. Setting up udev rules ===================== -For convenience, you may install udev rules file, 49-stlinkv2.rules, located +For convenience, you may install udev rules file, 49-stlinkv*.rules, located in the root of repository. You will need to copy it to /etc/udev/rules.d, and then either reboot or execute $ udevadm control --reload-rules -Udev will now create a /dev/stlinkv2_XX file, with the appropriate permissions. -This is currently all the device is for, (only one stlinkv2 is supported at +Udev will now create a /dev/stlinkv2_XX or /dev/stlinkv1_XX file, with the appropriate permissions. +This is currently all the device is for, (only one stlink of each version is supported at any time presently) Running programs from SRAM From 52b626bd16ae76df6c40d93c1d10efd334f01cec Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 4 Nov 2011 02:31:17 +0000 Subject: [PATCH 0037/1435] netbeans project update for flash utility --- nbproject/configurations.xml | 365 +++++++++++++++++++++++++++++++++++ nbproject/project.xml | 4 + 2 files changed, 369 insertions(+) diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index 47cfb040a..e129c44f6 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -839,5 +839,370 @@ + + + LOCAL_SOURCES + default + + + + flash + ${MAKE} -f Makefile + ${MAKE} -f Makefile clean + + + + DEBUG + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + src + + + CONFIG_USE_LIBSG=1 + CONFIG_USE_LIBUSB=1 + + + + + + + src + + + CONFIG_USE_LIBSG=1 + CONFIG_USE_LIBUSB=1 + + + + + + + . + + + DEBUG=1 + + + + + + + + + + diff --git a/nbproject/project.xml b/nbproject/project.xml index 580df1074..946c06f6f 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -21,6 +21,10 @@ gdbserver 0 + + flash + 0 + From fb9d6399a71ddd962d466692fc9d026e1b057c46 Mon Sep 17 00:00:00 2001 From: Petteri Aimonen Date: Thu, 10 Nov 2011 21:38:16 +0200 Subject: [PATCH 0038/1435] Fixed a bug that caused gdb to display wrong registers when using stlink ver 1. --- src/stlink-sg.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 2bbbaf9d9..1868eba18 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -707,9 +707,6 @@ void _stlink_sg_force_debug(stlink_t *sl) { void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { struct stlink_libsg *sg = sl->backend_data; - /* unused */ - regp = regp; - clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READALLREGS; sl->q_len = 84; @@ -722,23 +719,23 @@ void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71 | 72-75 | 76-79 | 80-83 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 for (int i = 0; i < 16; i++) { - sg->reg.r[i] = read_uint32(sl->q_buf, 4 * i); + regp->r[i] = read_uint32(sl->q_buf, 4 * i); if (sl->verbose > 1) - DLOG("r%2d = 0x%08x\n", i, sg->reg.r[i]); + DLOG("r%2d = 0x%08x\n", i, regp->r[i]); } - sg->reg.xpsr = read_uint32(sl->q_buf, 64); - sg->reg.main_sp = read_uint32(sl->q_buf, 68); - sg->reg.process_sp = read_uint32(sl->q_buf, 72); - sg->reg.rw = read_uint32(sl->q_buf, 76); - sg->reg.rw2 = read_uint32(sl->q_buf, 80); + 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); if (sl->verbose < 2) return; - DLOG("xpsr = 0x%08x\n", sg->reg.xpsr); - DLOG("main_sp = 0x%08x\n", sg->reg.main_sp); - DLOG("process_sp = 0x%08x\n", sg->reg.process_sp); - DLOG("rw = 0x%08x\n", sg->reg.rw); - DLOG("rw2 = 0x%08x\n", sg->reg.rw2); + DLOG("xpsr = 0x%08x\n", regp->xpsr); + DLOG("main_sp = 0x%08x\n", regp->main_sp); + DLOG("process_sp = 0x%08x\n", regp->process_sp); + DLOG("rw = 0x%08x\n", regp->rw); + DLOG("rw2 = 0x%08x\n", regp->rw2); } // Read an arm-core register, the index must be in the range 0..20. From e9a205ff98bea6a3a902352711a3980ccd4518be Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Fri, 11 Nov 2011 15:38:09 +0000 Subject: [PATCH 0039/1435] Finish removing sg-utils dependencies. The code deps were removed, but the flags stayed in some makefiles. --- flash/Makefile | 16 ---------------- gdbserver/Makefile | 15 --------------- 2 files changed, 31 deletions(-) diff --git a/flash/Makefile b/flash/Makefile index 8a30b4113..6e1675422 100644 --- a/flash/Makefile +++ b/flash/Makefile @@ -1,10 +1,3 @@ -# make ... for both libusb and libsg -# -# make CONFIG_USE_LIBSG=0 ... -# for just libusb -# -CC=gcc - CFLAGS+=-g CFLAGS+=-DCONFIG_USE_LIBUSB=1 CFLAGS+=-DDEBUG @@ -14,15 +7,6 @@ CFLAGS+=-I../src 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/gdbserver/Makefile b/gdbserver/Makefile index a8d1b90aa..e73103dfb 100644 --- a/gdbserver/Makefile +++ b/gdbserver/Makefile @@ -1,9 +1,3 @@ -# make ... for both libusb and libsg -# -# make CONFIG_USE_LIBSG=0 ... -# for just libusb -# - PRG := st-util OBJS = gdb-remote.o gdb-server.o @@ -11,15 +5,6 @@ CFLAGS+=-g -Wall -Werror -std=gnu99 -I../src 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) $(PRG): $(OBJS) From 5a5d36fdc3f1732d595fe923e45433d9e32077af Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 12 Nov 2011 20:36:43 +0000 Subject: [PATCH 0040/1435] Move all the flash size mapping from gdb server into core. All the device params like flash size and page size should all be in the core open routines, not _only_ in the gdbserver. (This should stop it from ending up duplicated in the core, and get rid of some of the hacks that were turning up. All of this is chip specific!) --- gdbserver/gdb-server.c | 76 +++------------------- src/stlink-common.c | 44 +++++++++++++ src/stlink-common.h | 141 +++++++++++++++++++++++++++++++++++++---- src/stlink-sg.c | 16 +---- src/stlink-usb.c | 40 +----------- 5 files changed, 185 insertions(+), 132 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index bcb3c974b..ce0549e7a 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -45,39 +45,6 @@ static const char* current_memory_map = NULL; #define CORE_M3_R2 0x4BA00477 #define CORE_M4_R0 0x2BA01477 -struct chip_params { - uint32_t chip_id; - char* description; - uint32_t flash_size_reg; - uint32_t max_flash_size, flash_pagesize; - uint32_t sram_size; - uint32_t bootrom_base, bootrom_size; -} const devices[] = { - { 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, 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, 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, - // not the sector write protection...) - { 0x416, "L1 Med-density device", 0x1FF8004C, // table 1, pm0062 - 0x20000, 0x100, 0x4000, 0x1ff00000, 0x1000 }, - { 0x418, "F1 Connectivity line device", 0x1ffff7e0, - 0x40000, 0x800, 0x10000, 0x1fffb000, 0x4800 }, - { 0x420, "F1 Medium-density value line device", 0x1ffff7e0, - 0x20000, 0x400, 0x2000, 0x1ffff000, 0x800 }, - { 0x428, "F1 High-density value line device", 0x1ffff7e0, - 0x80000, 0x800, 0x8000, 0x1ffff000, 0x800 }, - { 0x430, "F1 XL-density device", 0x1ffff7e0, // pm0068 - 0x100000, 0x800, 0x18000, 0x1fffe000, 0x1800 }, - { 0 } -}; - typedef struct _st_state_t { // things from command line, bleh int stlink_version; @@ -89,7 +56,7 @@ typedef struct _st_state_t { int serve(stlink_t *sl, int port); -char* make_memory_map(const struct chip_params *params, uint32_t flash_size); +char* make_memory_map(stlink_t *sl); int parse_options(int argc, char** argv, st_state_t *st) { @@ -201,6 +168,8 @@ int main(int argc, char** argv) { if(sl == NULL) return 1; break; } + + // ALLLL of this should move into "stlink_open_xxx" if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { @@ -220,34 +189,7 @@ int main(int argc, char** argv) { printf("Chip ID is %08x, Core ID is %08x.\n", chip_id, core_id); - const struct chip_params* params = NULL; - - for(int i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { - if(devices[i].chip_id == (chip_id & 0xFFF)) { - params = &devices[i]; - break; - } - } - - if(params == NULL) { - fprintf(stderr, "Cannot recognize the connected device!\n"); - return 0; - } - - printf("Device connected: %s\n", params->description); - printf("Device parameters: SRAM: 0x%x bytes, Flash: up to 0x%x bytes in pages of 0x%x bytes\n", - params->sram_size, params->max_flash_size, params->flash_pagesize); - - FLASH_PAGE = params->flash_pagesize; - - uint32_t flash_size; - - stlink_read_mem32(sl, params->flash_size_reg, 4); - flash_size = sl->q_buf[0] | (sl->q_buf[1] << 8); - - printf("Flash size is %d KiB.\n", flash_size); - // memory map is in 1k blocks. - current_memory_map = make_memory_map(params, flash_size * 0x400); + current_memory_map = make_memory_map(sl); while(serve(sl, state.listen_port) == 0); @@ -275,16 +217,16 @@ static const char* const memory_map_template = " " // option byte area ""; -char* make_memory_map(const struct chip_params *params, uint32_t flash_size) { +char* make_memory_map(stlink_t *sl) { /* This will be freed in serve() */ char* map = malloc(4096); map[0] = '\0'; snprintf(map, 4096, memory_map_template, - flash_size, - params->sram_size, - flash_size, params->flash_pagesize, - params->bootrom_base, params->bootrom_size); + sl->flash_size, + sl->sram_size, + sl->flash_size, sl->flash_pgsz, + sl->sys_base, sl->sys_size); return map; } diff --git a/src/stlink-common.c b/src/stlink-common.c index f58c34405..89c263046 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -305,6 +305,50 @@ void stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { return; } +/** + * reads and decodes the flash parameters, as dynamically as possible + * @param sl + * @return 0 for success, or -1 for unsupported core type. + */ +int stlink_load_device_params(stlink_t *sl) { + ILOG("Loading device parameters....\n"); + chip_params_t *params = NULL; + uint32_t chip_id = stlink_chip_id(sl); + for(size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { + if(devices[i].chip_id == (chip_id & 0xFFF)) { + params = &devices[i]; + break; + } + } + if (params == NULL) { + WLOG("unknown chip id! %#x\n", chip_id); + return -1; + } + + // These are fixed... + sl->flash_base = STM32_FLASH_BASE; + sl->sram_base = STM32_SRAM_BASE; + + // read flash size from hardware, if possible... + if ((chip_id & 0xFFF) == STM32_CHIPID_F2) { + sl->flash_size = 0; // FIXME - need to work this out some other way, just set to max possible? + } else { + stlink_read_mem32(sl, params->flash_size_reg, 4); + uint32_t flash_size = sl->q_buf[0] | (sl->q_buf[1] << 8); + sl->flash_size = flash_size * 1024; + } + sl->flash_pgsz = params->flash_pagesize; + sl->sram_size = params->sram_size; + sl->sys_base = params->bootrom_base; + sl->sys_size = params->bootrom_size; + + ILOG("Device connected is: %s\n", params->description); + ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %zd bytes\n", + sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, + sl->flash_pgsz); + return 0; +} + void stlink_reset(stlink_t *sl) { DLOG("*** stlink_reset ***\n"); sl->backend->reset(sl); diff --git a/src/stlink-common.h b/src/stlink-common.h index bcd60aae1..5534b6f32 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -80,10 +80,134 @@ extern "C" { #define STM32VL_CORE_ID 0x1ba01477 #define STM32L_CORE_ID 0x2ba01477 #define STM32F4_CORE_ID 0x2ba01477 + +// stm32 chipids, only lower 12 bits.. +#define STM32_CHIPID_F1_MEDIUM 0x410 +#define STM32_CHIPID_F2 0x411 +#define STM32_CHIPID_F1_LOW 0x412 +#define STM32_CHIPID_F4 0x413 +#define STM32_CHIPID_F1_HIGH 0x414 +#define STM32_CHIPID_L1_MEDIUM 0x416 +#define STM32_CHIPID_F1_CONN 0x418 +#define STM32_CHIPID_F1_VL_MEDIUM 0x420 +#define STM32_CHIPID_F1_VL_HIGH 0x428 +#define STM32_CHIPID_F1_XL 0x430 + +// Constant STM32 memory map figures +#define STM32_FLASH_BASE 0x08000000 +#define STM32_SRAM_BASE 0x20000000 /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ #define C_BUF_LEN 32 + typedef struct chip_params_ { + uint32_t chip_id; + char* description; + uint32_t flash_size_reg; + uint32_t flash_pagesize; + 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[] = { + { // table 2, PM0063 + .chip_id = 0x410, + .description = "F1 Medium-density device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x5000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { // table 1, PM0059 + .chip_id = 0x411, + .description = "F2 device", + .flash_size_reg = 0, /* no flash size reg found in the docs! */ + .flash_pagesize = 0x20000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { // PM0063 + .chip_id = 0x412, + .description = "F1 Low-density device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2800, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + .chip_id = 0x413, + .description = "F4 device", + .flash_size_reg = 0x1FFF7A10, + .flash_pagesize = 0x20000, + .sram_size = 0x30000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 + }, + { + .chip_id = 0x414, + .description = "F1 High-density device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + // This ignores the EEPROM! (and uses the page erase size, + // not the sector write protection...) + .chip_id = 0x416, + .description = "L1 Med-density device", + .flash_size_reg = 0x1ff8004c, + .flash_pagesize = 0x100, + .sram_size = 0x4000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, + { + .chip_id = 0x418, + .description = "F1 Connectivity line device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1fffb000, + .bootrom_size = 0x4800 + }, + { + .chip_id = 0x420, + .description = "F1 Medium-density Value Line device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + .chip_id = 0x428, + .description = "F1 High-density value line device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x8000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + .chip_id = 0x430, + .description = "F1 XL-density device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x18000, + .bootrom_base = 0x1fffe000, + .bootrom_size = 0x1800 + } + }; + + typedef struct { uint32_t r[16]; uint32_t xpsr; @@ -161,29 +285,21 @@ extern "C" { uint32_t core_id; int core_stat; - - - /* medium density stm32 flash settings */ -#define STM32_FLASH_BASE 0x08000000 -#define STM32_FLASH_SIZE (128 * 1024) #define STM32_FLASH_PGSZ 1024 #define STM32L_FLASH_PGSZ 256 stm32_addr_t flash_base; size_t flash_size; size_t flash_pgsz; - /* in flash system memory */ -#define STM32_SYSTEM_BASE 0x1ffff000 -#define STM32_SYSTEM_SIZE (2 * 1024) - stm32_addr_t sys_base; - size_t sys_size; - /* 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; + + // bootloader + stm32_addr_t sys_base; + size_t sys_size; struct stlink_version_ version; }; @@ -236,6 +352,7 @@ extern "C" { int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size); int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size); + int stlink_load_device_params(stlink_t *sl); diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 1868eba18..fd10c16eb 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -1100,19 +1100,6 @@ static stlink_t* stlink_open(const int verbose) { sl->core_stat = STLINK_CORE_STAT_UNKNOWN; slsg->q_addr = 0; - /* flash memory settings */ - sl->flash_base = STM32_FLASH_BASE; - sl->flash_size = STM32_FLASH_SIZE; - sl->flash_pgsz = STM32_FLASH_PGSZ; - - /* 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 = STM32_SRAM_SIZE; - return sl; } @@ -1127,7 +1114,7 @@ stlink_t* stlink_v1_open(const int verbose) { } stlink_version(sl); - + stlink_load_device_params(sl); if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { ugly_log(UERROR, LOG_TAG, "WTF? successfully opened, but unable to read version details. BROKEN!\n"); @@ -1160,5 +1147,6 @@ stlink_t* stlink_v1_open(const int verbose) { } // re-query device info stlink_version(sl); + stlink_load_device_params(sl); return sl; } diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 785f7beca..b4df70efb 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -673,45 +673,7 @@ stlink_t* stlink_open_usb(const int verbose) { } stlink_version(sl); - - /* per device family initialization */ - stlink_core_id(sl); - if (sl->core_id == STM32L_CORE_ID) { - - /* flash memory settings */ - sl->flash_base = STM32_FLASH_BASE; - sl->flash_size = STM32_FLASH_SIZE; - sl->flash_pgsz = STM32L_FLASH_PGSZ; - - /* 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; - - } else if (sl->core_id == STM32VL_CORE_ID) { - - /* flash memory settings */ - sl->flash_base = STM32_FLASH_BASE; - sl->flash_size = STM32_FLASH_SIZE; - sl->flash_pgsz = STM32_FLASH_PGSZ; - - /* 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 = STM32_SRAM_SIZE; - - } else { - - fprintf(stderr, "unknown coreid: %x\n", sl->core_id); - goto on_libusb_error; - - } + stlink_load_device_params(sl); error = 0; From 0c587eedfd33396cc6da94850e0dfcac15a953f2 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Sat, 12 Nov 2011 20:45:41 +0000 Subject: [PATCH 0041/1435] Read chip and core id in device param loading. Instead of expecting everyone to read it every time they need to check it. Just assume it's always there. --- src/stlink-common.c | 5 +++-- src/stlink-common.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 89c263046..3391f4ff6 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -314,6 +314,7 @@ int stlink_load_device_params(stlink_t *sl) { ILOG("Loading device parameters....\n"); chip_params_t *params = NULL; uint32_t chip_id = stlink_chip_id(sl); + sl->chip_id = chip_id; for(size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { if(devices[i].chip_id == (chip_id & 0xFFF)) { params = &devices[i]; @@ -342,6 +343,8 @@ int stlink_load_device_params(stlink_t *sl) { sl->sys_base = params->bootrom_base; sl->sys_size = params->bootrom_size; + sl->core_id = stlink_core_id(sl); + ILOG("Device connected is: %s\n", params->description); ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %zd bytes\n", sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, @@ -742,7 +745,6 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page) { /* page an addr in the page to erase */ - stlink_core_id(sl); if (sl->core_id == STM32L_CORE_ID) { #define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00) @@ -1020,7 +1022,6 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned } } - stlink_core_id(sl); if (sl->core_id == STM32L_CORE_ID) { /* use fast word write. todo: half page. */ diff --git a/src/stlink-common.h b/src/stlink-common.h index 5534b6f32..9279c37f5 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -283,6 +283,7 @@ extern "C" { // transport layer verboseness: 0 for no debug info, 10 for lots int verbose; uint32_t core_id; + uint32_t chip_id; int core_stat; #define STM32_FLASH_PGSZ 1024 From 3c6f2f5231a11bc73e3bce0003318d0f87614ad1 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 14 Nov 2011 01:25:56 +0000 Subject: [PATCH 0042/1435] Fix flash writing for VL cores. The change from run->step breaks the VL cores. Need to double check that this still works for L cores. The whole flash writing needs to be better abstracted. Lots more informational debug. --- src/stlink-common.c | 112 ++++++++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 51 deletions(-) diff --git a/src/stlink-common.c b/src/stlink-common.c index 3391f4ff6..4286cf001 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -24,7 +24,7 @@ /* todo: stm32l15xxx flash memory, pm0062 manual */ /* stm32f FPEC flash controller interface, pm0063 manual */ - +// TODO - all of this needs to be abstracted out.... #define FLASH_REGS_ADDR 0x40022000 #define FLASH_REGS_SIZE 0x28 @@ -412,7 +412,7 @@ void stlink_version(stlink_t *sl) { } void stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_write_mem32 ***\n"); + DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); if (len % 4 != 0) { fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); return; @@ -744,7 +744,7 @@ int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, s int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page) { /* page an addr in the page to erase */ - + ILOG("Erasing flash page at addr: %#x\n", page); if (sl->core_id == STM32L_CORE_ID) { #define STM32L_FLASH_REGS_ADDR ((uint32_t)0x40023c00) @@ -853,7 +853,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t page) lock_flash(sl); } else { - fprintf(stderr, "unknown coreid: %x\n", sl->core_id); + WLOG("unknown coreid: %x\n", sl->core_id); return -1; } @@ -891,13 +891,13 @@ int init_flash_loader(stlink_t *sl, flash_loader_t* fl) { /* allocate the loader in sram */ if (write_loader_to_sram(sl, &fl->loader_addr, &size) == -1) { - fprintf(stderr, "write_loader_to_sram() == -1\n"); + WLOG("Failed to write flash loader to sram!\n"); return -1; } /* allocate a one page buffer in sram right after loader */ fl->buf_addr = fl->loader_addr + size; - + ILOG("Successfully loaded flash loader in sram\n"); return 0; } @@ -960,7 +960,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { } else { - fprintf(stderr, "unknown coreid: %x\n", sl->core_id); + WLOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); return -1; } @@ -994,33 +994,38 @@ int stlink_fcheck_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned len) { size_t off; flash_loader_t fl; - + ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", + len, len, addr, addr); /* check addr range is inside the flash */ if (addr < sl->flash_base) { - fprintf(stderr, "addr too low\n"); + WLOG("addr too low\n"); return -1; } else if ((addr + len) < addr) { - fprintf(stderr, "addr overruns\n"); + WLOG("addr overruns\n"); return -1; } else if ((addr + len) > (sl->flash_base + sl->flash_size)) { - fprintf(stderr, "addr too high\n"); + WLOG("addr too high\n"); return -1; } else if ((addr & 1) || (len & 1)) { - fprintf(stderr, "unaligned addr or size\n"); + WLOG("unaligned addr or size\n"); return -1; } else if (addr & (sl->flash_pgsz - 1)) { - fprintf(stderr, "addr not a multiple of pagesize, not supported\n"); + WLOG("addr not a multiple of pagesize, not supported\n"); return -1; } /* erase each page */ + int page_count = 0; for (off = 0; off < len; off += sl->flash_pgsz) { /* addr must be an addr inside the page */ if (stlink_erase_flash_page(sl, addr + off) == -1) { - fprintf(stderr, "erase_flash_page(0x%zx) == -1\n", addr + off); - return -1; + WLOG("Failed to erase_flash_page(%#zx) == -1\n", addr + off); + return -1; } + page_count++; } + ILOG("Finished erasing %d pages of %d (%#x) bytes\n", + page_count, sl->flash_pgsz, sl->flash_pgsz); if (sl->core_id == STM32L_CORE_ID) { @@ -1139,39 +1144,41 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned val = read_uint32(sl->q_buf, 0) | (1 << 0) | (1 << 1) | (1 << 2); write_uint32(sl->q_buf, val); stlink_write_mem32(sl, STM32L_FLASH_PECR, sizeof(uint32_t)); - } - else if (sl->core_id == STM32VL_CORE_ID) - { - /* flash loader initialization */ - if (init_flash_loader(sl, &fl) == -1) { - fprintf(stderr, "init_flash_loader() == -1\n"); - return -1; - } + } else if (sl->core_id == STM32VL_CORE_ID) { + ILOG("Starting Flash write for VL core id\n"); + /* flash loader initialization */ + if (init_flash_loader(sl, &fl) == -1) { + WLOG("init_flash_loader() == -1\n"); + return -1; + } - /* write each page. above WRITE_BLOCK_SIZE fails? */ + /* write each page. above WRITE_BLOCK_SIZE fails? */ #define WRITE_BLOCK_SIZE 0x40 - for (off = 0; off < len; off += WRITE_BLOCK_SIZE) - { - /* adjust last write size */ - size_t size = WRITE_BLOCK_SIZE; - if ((off + WRITE_BLOCK_SIZE) > len) size = len - off; - - /* unlock and set programming mode */ - unlock_flash_if(sl); - set_flash_cr_pg(sl); - - if (run_flash_loader(sl, &fl, addr + off, base + off, size) == -1) { - fprintf(stderr, "run_flash_loader(0x%zx) == -1\n", addr + off); - return -1; + int write_block_count = 0; + for (off = 0; off < len; off += WRITE_BLOCK_SIZE) { + ILOG("Writing flash block %d of size %d (%#x)\n", write_block_count, + WRITE_BLOCK_SIZE, WRITE_BLOCK_SIZE); + /* adjust last write size */ + size_t size = WRITE_BLOCK_SIZE; + if ((off + WRITE_BLOCK_SIZE) > len) size = len - off; + + /* unlock and set programming mode */ + unlock_flash_if(sl); + set_flash_cr_pg(sl); + //DLOG("Finished setting flash cr pg, running loader!\n"); + if (run_flash_loader(sl, &fl, addr + off, base + off, size) == -1) { + WLOG("run_flash_loader(%#zx) failed! == -1\n", addr + off); + return -1; + } + lock_flash(sl); + DLOG("Finished writing block %d\n", write_block_count++); } - - lock_flash(sl); - } } else { - fprintf(stderr, "unknown coreid: %x\n", sl->core_id); - return -1; + WLOG("unknown coreid, not sure how to write: %x\n", sl->core_id); + return -1; } + ILOG("Starting verification of write complete\n"); for (off = 0; off < len; off += sl->flash_pgsz) { size_t aligned_size; @@ -1189,32 +1196,35 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned if (memcmp(sl->q_buf, base + off, cmp_size)) return -1; } - + ILOG("Flash written and verified! jolly good!\n"); return 0; } +/** + * Write the given binary file into flash at address "addr" + * @param sl + * @param path readable file path, should be binary image + * @param addr where to start writing + * @return 0 on success, -ve on failure. + */ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { /* write the file in flash at addr */ - int err; mapped_file_t mf = MAPPED_FILE_INITIALIZER; - if (map_file(&mf, path) == -1) { - fprintf(stderr, "map_file() == -1\n"); + WLOG("map_file() == -1\n"); return -1; } - err = stlink_write_flash(sl, addr, mf.base, mf.len); - unmap_file(&mf); - return err; } int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { reg rr; - + DLOG("Running flash loader, write address:%#x, size: %zd\n", target, size); + // FIXME This can never return -1 if (write_buffer_to_sram(sl, fl, buf, size) == -1) { fprintf(stderr, "write_buffer_to_sram() == -1\n"); return -1; @@ -1250,7 +1260,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } /* run loader */ - stlink_step(sl); + stlink_run(sl); /* wait until done (reaches breakpoint) */ while (is_core_halted(sl) == 0) ; From 77f2d8b76c218e9edceaba71c6cc4f8724da49a1 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 14 Nov 2011 02:25:31 +0000 Subject: [PATCH 0043/1435] Don't try reading device params in bad USB modes. You cannot read device params when we're not in debug mode and trying to will fill the USB buffer with garbage, and you will have to unplug and replug and start again. (which will fail, because, you're in the wrong mode... :) --- src/stlink-sg.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/stlink-sg.c b/src/stlink-sg.c index fd10c16eb..c4392dbfe 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -1104,8 +1104,7 @@ static stlink_t* stlink_open(const int verbose) { } - -stlink_t* stlink_v1_open(const int verbose) { +stlink_t* stlink_v1_open_inner(const int verbose) { ugly_init(verbose); stlink_t *sl = stlink_open(verbose); if (sl == NULL) { @@ -1114,7 +1113,6 @@ stlink_t* stlink_v1_open(const int verbose) { } stlink_version(sl); - stlink_load_device_params(sl); if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { ugly_log(UERROR, LOG_TAG, "WTF? successfully opened, but unable to read version details. BROKEN!\n"); @@ -1123,11 +1121,14 @@ stlink_t* stlink_v1_open(const int verbose) { DLOG("Reading current mode...\n"); switch (stlink_current_mode(sl)) { - case STLINK_DEV_MASS_MODE: - return sl; - case STLINK_DEV_DEBUG_MODE: - // TODO go to mass? + case STLINK_DEV_MASS_MODE: return sl; + case STLINK_DEV_DEBUG_MODE: + // TODO go to mass? + return sl; + default: + ILOG("Current mode unusable, trying to get back to a useful state...\n"); + break; } DLOG("Attempting to exit DFU mode\n"); @@ -1145,8 +1146,25 @@ stlink_t* stlink_v1_open(const int verbose) { fputs("Error: could not open stlink device\n", stderr); return NULL; } - // re-query device info + // re-query device info (and retest) stlink_version(sl); - stlink_load_device_params(sl); + if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { + ugly_log(UERROR, LOG_TAG, + "WTF? successfully opened, but unable to read version details. BROKEN!\n"); + return NULL; + } + return sl; +} + +stlink_t* stlink_v1_open(const int verbose) { + stlink_t *sl = stlink_v1_open_inner(verbose); + if (sl == NULL) { + fputs("Error: could not open stlink device\n", stderr); + return NULL; + } + // by now, it _must_ be fully open and in a useful mode.... + stlink_enter_swd_mode(sl); + stlink_load_device_params(sl); + ILOG("Successfully opened a stlink v1 debugger\n"); return sl; } From 29cf5d590c76ef157d9697a5871b12b8af770f00 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 7 Nov 2011 22:00:13 +0000 Subject: [PATCH 0044/1435] Restructure libs source to support multi platform The "libstm32l_discovery" was actually the ST std periph library, plus the CMSIS core files. Renamed it as such, and restructured the directories and naming to make this easier to contain the std periph drivers for more than just one board. Verified with the LCD demo makefile, and loading it in sram again. --- example/lcd/Makefile | 21 +++++--- example/libs_stm/build/Makefile | 37 ++++++++++++++ .../inc/base/stdint.h | 0 .../inc/core_support/core_cm3.c | 0 .../inc/core_support/core_cm3.h | 0 .../inc/device_support/stm32l1xx.h | 0 .../inc/device_support/system_stm32l1xx.h | 0 .../inc => libs_stm/inc/stm32l1xx}/misc.h | 0 .../inc/stm32l1xx}/stm32l1xx_adc.h | 0 .../inc/stm32l1xx}/stm32l1xx_comp.h | 0 .../inc/stm32l1xx}/stm32l1xx_crc.h | 0 .../inc/stm32l1xx}/stm32l1xx_dac.h | 0 .../inc/stm32l1xx}/stm32l1xx_dbgmcu.h | 0 .../inc/stm32l1xx}/stm32l1xx_dma.h | 0 .../inc/stm32l1xx}/stm32l1xx_exti.h | 0 .../inc/stm32l1xx}/stm32l1xx_flash.h | 0 .../inc/stm32l1xx}/stm32l1xx_gpio.h | 0 .../inc/stm32l1xx}/stm32l1xx_i2c.h | 0 .../inc/stm32l1xx}/stm32l1xx_iwdg.h | 0 .../inc/stm32l1xx}/stm32l1xx_lcd.h | 0 .../inc/stm32l1xx}/stm32l1xx_pwr.h | 0 .../inc/stm32l1xx}/stm32l1xx_rcc.h | 0 .../inc/stm32l1xx}/stm32l1xx_rtc.h | 0 .../inc/stm32l1xx}/stm32l1xx_spi.h | 0 .../inc/stm32l1xx}/stm32l1xx_syscfg.h | 0 .../inc/stm32l1xx}/stm32l1xx_tim.h | 0 .../inc/stm32l1xx}/stm32l1xx_usart.h | 0 .../inc/stm32l1xx}/stm32l1xx_wwdg.h | 0 .../src => libs_stm/src/stm32l1xx}/misc.c | 0 .../src/stm32l1xx}/stm32l1xx_adc.c | 0 .../src/stm32l1xx}/stm32l1xx_comp.c | 0 .../src/stm32l1xx}/stm32l1xx_crc.c | 0 .../src/stm32l1xx}/stm32l1xx_dac.c | 0 .../src/stm32l1xx}/stm32l1xx_dbgmcu.c | 0 .../src/stm32l1xx}/stm32l1xx_dma.c | 0 .../src/stm32l1xx}/stm32l1xx_exti.c | 0 .../src/stm32l1xx}/stm32l1xx_flash.c | 0 .../src/stm32l1xx}/stm32l1xx_flash_ramfunc.c | 0 .../src/stm32l1xx}/stm32l1xx_gpio.c | 0 .../src/stm32l1xx}/stm32l1xx_i2c.c | 0 .../src/stm32l1xx}/stm32l1xx_iwdg.c | 0 .../src/stm32l1xx}/stm32l1xx_lcd.c | 0 .../src/stm32l1xx}/stm32l1xx_pwr.c | 0 .../src/stm32l1xx}/stm32l1xx_rcc.c | 0 .../src/stm32l1xx}/stm32l1xx_rtc.c | 0 .../src/stm32l1xx}/stm32l1xx_spi.c | 0 .../src/stm32l1xx}/stm32l1xx_syscfg.c | 0 .../src/stm32l1xx}/stm32l1xx_tim.c | 0 .../src/stm32l1xx}/stm32l1xx_usart.c | 0 .../src/stm32l1xx}/stm32l1xx_wwdg.c | 0 example/libstm32l_discovery/build/Makefile | 51 ------------------- 51 files changed, 52 insertions(+), 57 deletions(-) create mode 100644 example/libs_stm/build/Makefile rename example/{libstm32l_discovery => libs_stm}/inc/base/stdint.h (100%) rename example/{libstm32l_discovery => libs_stm}/inc/core_support/core_cm3.c (100%) rename example/{libstm32l_discovery => libs_stm}/inc/core_support/core_cm3.h (100%) rename example/{libstm32l_discovery => libs_stm}/inc/device_support/stm32l1xx.h (100%) rename example/{libstm32l_discovery => libs_stm}/inc/device_support/system_stm32l1xx.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/misc.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_adc.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_comp.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_crc.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_dac.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_dbgmcu.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_dma.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_exti.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_flash.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_gpio.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_i2c.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_iwdg.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_lcd.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_pwr.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_rcc.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_rtc.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_spi.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_syscfg.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_tim.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_usart.h (100%) rename example/{libstm32l_discovery/inc => libs_stm/inc/stm32l1xx}/stm32l1xx_wwdg.h (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/misc.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_adc.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_comp.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_crc.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_dac.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_dbgmcu.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_dma.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_exti.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_flash.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_flash_ramfunc.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_gpio.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_i2c.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_iwdg.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_lcd.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_pwr.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_rcc.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_rtc.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_spi.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_syscfg.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_tim.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_usart.c (100%) rename example/{libstm32l_discovery/src => libs_stm/src/stm32l1xx}/stm32l1xx_wwdg.c (100%) delete mode 100644 example/libstm32l_discovery/build/Makefile diff --git a/example/lcd/Makefile b/example/lcd/Makefile index 0f31ae68b..8bfdbbbfa 100644 --- a/example/lcd/Makefile +++ b/example/lcd/Makefile @@ -7,11 +7,20 @@ CFLAGS+=-mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc CFLAGS+=-I. -# stm32l_discovery lib -CFLAGS+=-I../libstm32l_discovery/inc -CFLAGS+=-I../libstm32l_discovery/inc/base -CFLAGS+=-I../libstm32l_discovery/inc/core_support -CFLAGS+=-I../libstm32l_discovery/inc/device_support + +PLATFORM=stm32l1xx +LIBS_STM_PATH=../libs_stm + +INC_CORE_SUPPORT=$(LIBS_STM_PATH)/inc/core_support +SRC_CORE_SUPPORT=$(LIBS_STM_PATH)/inc/core_support +INC_DEVICE_SUPPORT=$(LIBS_STM_PATH)/inc/device_support +INC_PLATFORM=$(LIBS_STM_PATH)/inc/$(PLATFORM) + +CFLAGS+=-I$(INC_CORE_SUPPORT) +CFLAGS+=-I$(INC_DEVICE_SUPPORT) +CFLAGS+=-I$(INC_PLATFORM) +CFLAGS+=-I$(LIBS_STM_PATH)/inc/base + # to run from SRAM CFLAGS+=-Wl,-T,linker_stm32l.lds @@ -25,7 +34,7 @@ OBJS=$(SRCS:.c=.o) all: $(ELF) $(ELF): $(OBJS) - $(CC) $(CFLAGS) -o $@ $(OBJS) -L../libstm32l_discovery/build -lstm32l_discovery + $(CC) $(CFLAGS) -o $@ $(OBJS) -L$(LIBS_STM_PATH)/build -lstm32l_discovery %.o: %.c $(CC) $(CFLAGS) -c -o $@ $^ diff --git a/example/libs_stm/build/Makefile b/example/libs_stm/build/Makefile new file mode 100644 index 000000000..d96e48c59 --- /dev/null +++ b/example/libs_stm/build/Makefile @@ -0,0 +1,37 @@ +LIB = libstm32l_discovery.a + +CC = arm-none-eabi-gcc +AR = arm-none-eabi-ar +RANLIB = arm-none-eabi-ranlib + +PLATFORM=stm32l1xx + +INC_CORE_SUPPORT=../inc/core_support +SRC_CORE_SUPPORT=../inc/core_support +INC_DEVICE_SUPPORT=../inc/device_support +INC_PLATFORM=../inc/$(PLATFORM) +SRC_PLATFORM=../src/$(PLATFORM) + +CFLAGS = -Wall -O2 -mlittle-endian -mthumb +CFLAGS += -mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc +CFLAGS += -I$(INC_PLATFORM) -I$(INC_DEVICE_SUPPORT) -I$(INC_CORE_SUPPORT) -I../inc/base + +SRCS=$(wildcard $(SRC_PLATFORM)/*.c) +SRCS+=$(SRC_CORE_SUPPORT)/core_cm3.c + +OBJS = $(SRCS:.c=.o) + +all: $(LIB) + +$(LIB): $(OBJS) + $(AR) -r $(LIB) $(OBJS) + $(RANLIB) $(LIB) + +%.o : %.c + $(CC) $(CFLAGS) -c -o $@ $^ + +clean: + -rm -f $(OBJS) + -rm -f $(LIB) + +.PHONY: all clean diff --git a/example/libstm32l_discovery/inc/base/stdint.h b/example/libs_stm/inc/base/stdint.h similarity index 100% rename from example/libstm32l_discovery/inc/base/stdint.h rename to example/libs_stm/inc/base/stdint.h diff --git a/example/libstm32l_discovery/inc/core_support/core_cm3.c b/example/libs_stm/inc/core_support/core_cm3.c similarity index 100% rename from example/libstm32l_discovery/inc/core_support/core_cm3.c rename to example/libs_stm/inc/core_support/core_cm3.c diff --git a/example/libstm32l_discovery/inc/core_support/core_cm3.h b/example/libs_stm/inc/core_support/core_cm3.h similarity index 100% rename from example/libstm32l_discovery/inc/core_support/core_cm3.h rename to example/libs_stm/inc/core_support/core_cm3.h diff --git a/example/libstm32l_discovery/inc/device_support/stm32l1xx.h b/example/libs_stm/inc/device_support/stm32l1xx.h similarity index 100% rename from example/libstm32l_discovery/inc/device_support/stm32l1xx.h rename to example/libs_stm/inc/device_support/stm32l1xx.h diff --git a/example/libstm32l_discovery/inc/device_support/system_stm32l1xx.h b/example/libs_stm/inc/device_support/system_stm32l1xx.h similarity index 100% rename from example/libstm32l_discovery/inc/device_support/system_stm32l1xx.h rename to example/libs_stm/inc/device_support/system_stm32l1xx.h diff --git a/example/libstm32l_discovery/inc/misc.h b/example/libs_stm/inc/stm32l1xx/misc.h similarity index 100% rename from example/libstm32l_discovery/inc/misc.h rename to example/libs_stm/inc/stm32l1xx/misc.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_adc.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_adc.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_adc.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_adc.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_comp.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_comp.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_comp.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_comp.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_crc.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_crc.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_crc.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_crc.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_dac.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_dac.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_dac.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_dac.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_dbgmcu.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_dbgmcu.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_dbgmcu.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_dbgmcu.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_dma.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_dma.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_dma.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_dma.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_exti.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_exti.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_exti.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_exti.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_flash.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_flash.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_flash.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_flash.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_gpio.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_gpio.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_gpio.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_gpio.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_i2c.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_i2c.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_i2c.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_i2c.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_iwdg.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_iwdg.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_iwdg.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_iwdg.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_lcd.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_lcd.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_lcd.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_lcd.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_pwr.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_pwr.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_pwr.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_pwr.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_rcc.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_rcc.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_rcc.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_rcc.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_rtc.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_rtc.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_rtc.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_rtc.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_spi.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_spi.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_spi.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_spi.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_syscfg.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_syscfg.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_syscfg.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_syscfg.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_tim.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_tim.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_tim.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_tim.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_usart.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_usart.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_usart.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_usart.h diff --git a/example/libstm32l_discovery/inc/stm32l1xx_wwdg.h b/example/libs_stm/inc/stm32l1xx/stm32l1xx_wwdg.h similarity index 100% rename from example/libstm32l_discovery/inc/stm32l1xx_wwdg.h rename to example/libs_stm/inc/stm32l1xx/stm32l1xx_wwdg.h diff --git a/example/libstm32l_discovery/src/misc.c b/example/libs_stm/src/stm32l1xx/misc.c similarity index 100% rename from example/libstm32l_discovery/src/misc.c rename to example/libs_stm/src/stm32l1xx/misc.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_adc.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_adc.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_adc.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_adc.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_comp.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_comp.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_comp.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_comp.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_crc.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_crc.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_crc.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_crc.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_dac.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_dac.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_dac.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_dac.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_dbgmcu.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_dbgmcu.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_dbgmcu.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_dbgmcu.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_dma.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_dma.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_dma.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_dma.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_exti.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_exti.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_exti.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_exti.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_flash.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_flash.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_flash.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_flash.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_flash_ramfunc.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_flash_ramfunc.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_flash_ramfunc.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_flash_ramfunc.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_gpio.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_gpio.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_gpio.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_gpio.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_i2c.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_i2c.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_i2c.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_i2c.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_iwdg.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_iwdg.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_iwdg.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_iwdg.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_lcd.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_lcd.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_lcd.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_lcd.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_pwr.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_pwr.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_pwr.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_pwr.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_rcc.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_rcc.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_rcc.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_rcc.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_rtc.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_rtc.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_rtc.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_rtc.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_spi.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_spi.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_spi.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_spi.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_syscfg.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_syscfg.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_syscfg.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_syscfg.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_tim.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_tim.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_tim.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_tim.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_usart.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_usart.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_usart.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_usart.c diff --git a/example/libstm32l_discovery/src/stm32l1xx_wwdg.c b/example/libs_stm/src/stm32l1xx/stm32l1xx_wwdg.c similarity index 100% rename from example/libstm32l_discovery/src/stm32l1xx_wwdg.c rename to example/libs_stm/src/stm32l1xx/stm32l1xx_wwdg.c diff --git a/example/libstm32l_discovery/build/Makefile b/example/libstm32l_discovery/build/Makefile deleted file mode 100644 index 09d3b71f0..000000000 --- a/example/libstm32l_discovery/build/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -LIB = libstm32l_discovery.a - -CC = arm-none-eabi-gcc -AR = arm-none-eabi-ar -RANLIB = arm-none-eabi-ranlib - -CFLAGS = -Wall -O2 -mlittle-endian -mthumb -CFLAGS += -mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc -CFLAGS += -I../inc -I../inc/device_support -I../inc/core_support -I../inc/base - -SRCS = \ -../src/misc.c \ -../src/stm32l1xx_adc.c \ -../src/stm32l1xx_comp.c \ -../src/stm32l1xx_crc.c \ -../src/stm32l1xx_dac.c \ -../src/stm32l1xx_dbgmcu.c \ -../src/stm32l1xx_dma.c \ -../src/stm32l1xx_exti.c \ -../src/stm32l1xx_flash.c \ -../src/stm32l1xx_flash_ramfunc.c \ -../src/stm32l1xx_gpio.c \ -../src/stm32l1xx_i2c.c \ -../src/stm32l1xx_iwdg.c \ -../src/stm32l1xx_lcd.c \ -../src/stm32l1xx_pwr.c \ -../src/stm32l1xx_rcc.c \ -../src/stm32l1xx_rtc.c \ -../src/stm32l1xx_spi.c \ -../src/stm32l1xx_syscfg.c \ -../src/stm32l1xx_tim.c \ -../src/stm32l1xx_usart.c \ -../src/stm32l1xx_wwdg.c \ -../inc/core_support/core_cm3.c - -OBJS = $(SRCS:.c=.o) - -all: $(LIB) - -$(LIB): $(OBJS) - $(AR) -r $(LIB) $(OBJS) - $(RANLIB) $(LIB) - -%.o : %.c - $(CC) $(CFLAGS) -c -o $@ $^ - -clean: - -rm -f $(OBJS) - -rm -f $(LIB) - -.PHONY: all clean From 3ec53a0d34016839cf6583117dd549da88aa63c7 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 7 Nov 2011 22:55:20 +0000 Subject: [PATCH 0045/1435] Rename 32L specific examples --- example/{lcd => 32l_lcd}/Makefile | 16 ++++++---------- example/{lcd => 32l_lcd}/discover_board.h | 0 example/{lcd => 32l_lcd}/linker_stm32l.lds | 0 example/{lcd => 32l_lcd}/main.c | 0 example/{lcd => 32l_lcd}/stm32l_discovery_lcd.c | 0 example/{lcd => 32l_lcd}/stm32l_discovery_lcd.h | 0 6 files changed, 6 insertions(+), 10 deletions(-) rename example/{lcd => 32l_lcd}/Makefile (56%) rename example/{lcd => 32l_lcd}/discover_board.h (100%) rename example/{lcd => 32l_lcd}/linker_stm32l.lds (100%) rename example/{lcd => 32l_lcd}/main.c (100%) rename example/{lcd => 32l_lcd}/stm32l_discovery_lcd.c (100%) rename example/{lcd => 32l_lcd}/stm32l_discovery_lcd.h (100%) diff --git a/example/lcd/Makefile b/example/32l_lcd/Makefile similarity index 56% rename from example/lcd/Makefile rename to example/32l_lcd/Makefile index 8bfdbbbfa..fce21946e 100644 --- a/example/lcd/Makefile +++ b/example/32l_lcd/Makefile @@ -11,20 +11,16 @@ CFLAGS+=-I. PLATFORM=stm32l1xx LIBS_STM_PATH=../libs_stm -INC_CORE_SUPPORT=$(LIBS_STM_PATH)/inc/core_support -SRC_CORE_SUPPORT=$(LIBS_STM_PATH)/inc/core_support -INC_DEVICE_SUPPORT=$(LIBS_STM_PATH)/inc/device_support -INC_PLATFORM=$(LIBS_STM_PATH)/inc/$(PLATFORM) - -CFLAGS+=-I$(INC_CORE_SUPPORT) -CFLAGS+=-I$(INC_DEVICE_SUPPORT) -CFLAGS+=-I$(INC_PLATFORM) CFLAGS+=-I$(LIBS_STM_PATH)/inc/base - +CFLAGS+=-I$(LIBS_STM_PATH)/inc/core_support +CFLAGS+=-I$(LIBS_STM_PATH)/inc/device_support +CFLAGS+=-I$(LIBS_STM_PATH)/inc/$(PLATFORM) # to run from SRAM CFLAGS+=-Wl,-T,linker_stm32l.lds +LDFLAGS+=-L$(LIBS_STM_PATH)/build -lstm32l_discovery + SRCS=\ main.c\ stm32l_discovery_lcd.c @@ -34,7 +30,7 @@ OBJS=$(SRCS:.c=.o) all: $(ELF) $(ELF): $(OBJS) - $(CC) $(CFLAGS) -o $@ $(OBJS) -L$(LIBS_STM_PATH)/build -lstm32l_discovery + $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) %.o: %.c $(CC) $(CFLAGS) -c -o $@ $^ diff --git a/example/lcd/discover_board.h b/example/32l_lcd/discover_board.h similarity index 100% rename from example/lcd/discover_board.h rename to example/32l_lcd/discover_board.h diff --git a/example/lcd/linker_stm32l.lds b/example/32l_lcd/linker_stm32l.lds similarity index 100% rename from example/lcd/linker_stm32l.lds rename to example/32l_lcd/linker_stm32l.lds diff --git a/example/lcd/main.c b/example/32l_lcd/main.c similarity index 100% rename from example/lcd/main.c rename to example/32l_lcd/main.c diff --git a/example/lcd/stm32l_discovery_lcd.c b/example/32l_lcd/stm32l_discovery_lcd.c similarity index 100% rename from example/lcd/stm32l_discovery_lcd.c rename to example/32l_lcd/stm32l_discovery_lcd.c diff --git a/example/lcd/stm32l_discovery_lcd.h b/example/32l_lcd/stm32l_discovery_lcd.h similarity index 100% rename from example/lcd/stm32l_discovery_lcd.h rename to example/32l_lcd/stm32l_discovery_lcd.h From d69cad884996b01fb993b3df16c1050adaca5daa Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 7 Nov 2011 22:56:15 +0000 Subject: [PATCH 0046/1435] Rename board specific demos as appropriate --- example/{dac => 32l_dac}/Makefile | 0 example/{dac => 32l_dac}/discover_board.h | 0 example/{dac => 32l_dac}/main.c | 0 example/{dac => 32l_dac}/startup_stm32l1xx_md.s | 0 example/{dac => 32l_dac}/stm32_flash.ld | 0 example/{dac => 32l_dac}/system_stm32l1xx.c | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename example/{dac => 32l_dac}/Makefile (100%) rename example/{dac => 32l_dac}/discover_board.h (100%) rename example/{dac => 32l_dac}/main.c (100%) rename example/{dac => 32l_dac}/startup_stm32l1xx_md.s (100%) rename example/{dac => 32l_dac}/stm32_flash.ld (100%) rename example/{dac => 32l_dac}/system_stm32l1xx.c (100%) diff --git a/example/dac/Makefile b/example/32l_dac/Makefile similarity index 100% rename from example/dac/Makefile rename to example/32l_dac/Makefile diff --git a/example/dac/discover_board.h b/example/32l_dac/discover_board.h similarity index 100% rename from example/dac/discover_board.h rename to example/32l_dac/discover_board.h diff --git a/example/dac/main.c b/example/32l_dac/main.c similarity index 100% rename from example/dac/main.c rename to example/32l_dac/main.c diff --git a/example/dac/startup_stm32l1xx_md.s b/example/32l_dac/startup_stm32l1xx_md.s similarity index 100% rename from example/dac/startup_stm32l1xx_md.s rename to example/32l_dac/startup_stm32l1xx_md.s diff --git a/example/dac/stm32_flash.ld b/example/32l_dac/stm32_flash.ld similarity index 100% rename from example/dac/stm32_flash.ld rename to example/32l_dac/stm32_flash.ld diff --git a/example/dac/system_stm32l1xx.c b/example/32l_dac/system_stm32l1xx.c similarity index 100% rename from example/dac/system_stm32l1xx.c rename to example/32l_dac/system_stm32l1xx.c From 518fe1b0d0b45ab6a9ec217f8b1ce51850077e97 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 7 Nov 2011 22:56:34 +0000 Subject: [PATCH 0047/1435] Fix compile error with new libraries --- example/32l_dac/Makefile | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/example/32l_dac/Makefile b/example/32l_dac/Makefile index 84db69ec3..4bd6eb454 100644 --- a/example/32l_dac/Makefile +++ b/example/32l_dac/Makefile @@ -5,25 +5,22 @@ CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy CFLAGS=-O3 -mlittle-endian -mthumb -ifeq ($(CONFIG_STM32L_DISCOVERY), 1) - CFLAGS+=-mcpu=cortex-m3 -DCONFIG_STM32L_DISCOVERY=1 -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+=-mcpu=cortex-m3 -DCONFIG_STM32L_DISCOVERY=1 CFLAGS+=-ffreestanding -nostdlib -nostdinc # to run from FLASH CFLAGS+=-Wl,-T,stm32_flash.ld +PLATFORM=stm32l1xx +LIBS_STM_PATH=../libs_stm + # stm32l_discovery lib -CFLAGS+=-I../libstm32l_discovery/inc -CFLAGS+=-I../libstm32l_discovery/inc/base -CFLAGS+=-I../libstm32l_discovery/inc/core_support -CFLAGS+=-I../libstm32l_discovery/inc/device_support +CFLAGS+=-I$(LIBS_STM_PATH)/inc/base +CFLAGS+=-I$(LIBS_STM_PATH)/inc/core_support +CFLAGS+=-I$(LIBS_STM_PATH)/inc/device_support +CFLAGS+=-I$(LIBS_STM_PATH)/inc/$(PLATFORM) + +LDFLAGS+=-L$(LIBS_STM_PATH)/build -lstm32l_discovery all: $(BIN_IMAGE) @@ -31,7 +28,7 @@ $(BIN_IMAGE): $(EXECUTABLE) $(OBJCOPY) -O binary $^ $@ $(EXECUTABLE): main.c system_stm32l1xx.c startup_stm32l1xx_md.s - $(CC) $(CFLAGS) $^ -o $@ -L../libstm32l_discovery/build -lstm32l_discovery + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) clean: rm -rf $(EXECUTABLE) From fd1e3f5f2eba9e3a0b0d3e665737dd1c232b4a73 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 8 Nov 2011 00:57:54 +0000 Subject: [PATCH 0048/1435] Build libraries for stm32l1xx and stm32f10x These libraries IGNORE assert_param. Maybe later. --- example/32l_lcd/Makefile | 2 +- example/libs_stm/README | 9 + example/libs_stm/build/Makefile | 37 +- example/libs_stm/build/Makefile.common | 34 + example/libs_stm/build/Makefile.f10x | 5 + example/libs_stm/build/Makefile.l1xx | 5 + .../libs_stm/inc/device_support/stm32f10x.h | 8227 +++++++++++++++++ .../inc/device_support/system_stm32f10x.h | 97 + example/libs_stm/inc/stm32f10x/misc.h | 219 + .../libs_stm/inc/stm32f10x/stm32f10x_adc.h | 482 + .../libs_stm/inc/stm32f10x/stm32f10x_bkp.h | 194 + .../libs_stm/inc/stm32f10x/stm32f10x_can.h | 535 ++ .../libs_stm/inc/stm32f10x/stm32f10x_cec.h | 209 + .../libs_stm/inc/stm32f10x/stm32f10x_crc.h | 93 + .../libs_stm/inc/stm32f10x/stm32f10x_dac.h | 316 + .../libs_stm/inc/stm32f10x/stm32f10x_dbgmcu.h | 118 + .../libs_stm/inc/stm32f10x/stm32f10x_dma.h | 437 + .../libs_stm/inc/stm32f10x/stm32f10x_exti.h | 183 + .../libs_stm/inc/stm32f10x/stm32f10x_flash.h | 425 + .../libs_stm/inc/stm32f10x/stm32f10x_fsmc.h | 716 ++ .../libs_stm/inc/stm32f10x/stm32f10x_gpio.h | 379 + .../libs_stm/inc/stm32f10x/stm32f10x_i2c.h | 670 ++ .../libs_stm/inc/stm32f10x/stm32f10x_iwdg.h | 139 + .../libs_stm/inc/stm32f10x/stm32f10x_pwr.h | 155 + .../libs_stm/inc/stm32f10x/stm32f10x_rcc.h | 726 ++ .../libs_stm/inc/stm32f10x/stm32f10x_rtc.h | 134 + .../libs_stm/inc/stm32f10x/stm32f10x_sdio.h | 530 ++ .../libs_stm/inc/stm32f10x/stm32f10x_spi.h | 490 + .../libs_stm/inc/stm32f10x/stm32f10x_tim.h | 1133 +++ .../libs_stm/inc/stm32f10x/stm32f10x_usart.h | 411 + .../libs_stm/inc/stm32f10x/stm32f10x_wwdg.h | 114 + ..._Notes_for_STM32F10x_StdPeriph_Driver.html | 203 + example/libs_stm/src/stm32f10x/misc.c | 223 + .../libs_stm/src/stm32f10x/stm32f10x_adc.c | 1306 +++ .../libs_stm/src/stm32f10x/stm32f10x_bkp.c | 311 + .../libs_stm/src/stm32f10x/stm32f10x_can.c | 990 ++ .../libs_stm/src/stm32f10x/stm32f10x_cec.c | 432 + .../libs_stm/src/stm32f10x/stm32f10x_crc.c | 163 + .../libs_stm/src/stm32f10x/stm32f10x_dac.c | 579 ++ .../libs_stm/src/stm32f10x/stm32f10x_dbgmcu.c | 161 + .../libs_stm/src/stm32f10x/stm32f10x_dma.c | 693 ++ .../libs_stm/src/stm32f10x/stm32f10x_exti.c | 268 + .../libs_stm/src/stm32f10x/stm32f10x_flash.c | 1735 ++++ .../libs_stm/src/stm32f10x/stm32f10x_fsmc.c | 858 ++ .../libs_stm/src/stm32f10x/stm32f10x_gpio.c | 642 ++ .../libs_stm/src/stm32f10x/stm32f10x_i2c.c | 1285 +++ .../libs_stm/src/stm32f10x/stm32f10x_iwdg.c | 189 + .../libs_stm/src/stm32f10x/stm32f10x_pwr.c | 316 + .../libs_stm/src/stm32f10x/stm32f10x_rcc.c | 1477 +++ .../libs_stm/src/stm32f10x/stm32f10x_rtc.c | 341 + .../libs_stm/src/stm32f10x/stm32f10x_sdio.c | 798 ++ .../libs_stm/src/stm32f10x/stm32f10x_spi.c | 907 ++ .../libs_stm/src/stm32f10x/stm32f10x_tim.c | 2834 ++++++ .../libs_stm/src/stm32f10x/stm32f10x_usart.c | 1054 +++ .../libs_stm/src/stm32f10x/stm32f10x_wwdg.c | 223 + 55 files changed, 35179 insertions(+), 33 deletions(-) create mode 100644 example/libs_stm/README create mode 100644 example/libs_stm/build/Makefile.common create mode 100644 example/libs_stm/build/Makefile.f10x create mode 100644 example/libs_stm/build/Makefile.l1xx create mode 100644 example/libs_stm/inc/device_support/stm32f10x.h create mode 100644 example/libs_stm/inc/device_support/system_stm32f10x.h create mode 100644 example/libs_stm/inc/stm32f10x/misc.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_adc.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_bkp.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_can.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_cec.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_crc.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_dac.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_dbgmcu.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_dma.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_exti.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_flash.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_fsmc.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_gpio.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_i2c.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_iwdg.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_pwr.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_rcc.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_rtc.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_sdio.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_spi.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_tim.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_usart.h create mode 100644 example/libs_stm/inc/stm32f10x/stm32f10x_wwdg.h create mode 100644 example/libs_stm/src/stm32f10x/Release_Notes_for_STM32F10x_StdPeriph_Driver.html create mode 100644 example/libs_stm/src/stm32f10x/misc.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_adc.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_bkp.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_can.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_cec.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_crc.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_dac.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_dbgmcu.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_dma.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_exti.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_flash.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_fsmc.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_gpio.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_i2c.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_iwdg.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_pwr.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_rcc.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_rtc.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_sdio.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_spi.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_tim.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_usart.c create mode 100644 example/libs_stm/src/stm32f10x/stm32f10x_wwdg.c diff --git a/example/32l_lcd/Makefile b/example/32l_lcd/Makefile index fce21946e..fdb79c304 100644 --- a/example/32l_lcd/Makefile +++ b/example/32l_lcd/Makefile @@ -19,7 +19,7 @@ CFLAGS+=-I$(LIBS_STM_PATH)/inc/$(PLATFORM) # to run from SRAM CFLAGS+=-Wl,-T,linker_stm32l.lds -LDFLAGS+=-L$(LIBS_STM_PATH)/build -lstm32l_discovery +LDFLAGS+=-L$(LIBS_STM_PATH)/build -lstm32_stdperiph_l1xx SRCS=\ main.c\ diff --git a/example/libs_stm/README b/example/libs_stm/README new file mode 100644 index 000000000..c3dcc4e4b --- /dev/null +++ b/example/libs_stm/README @@ -0,0 +1,9 @@ +This directory contains the StdPeriph libraries from ST, and the CMSIS core and device +support, all from ST. + +Issues: +* No tracking of which version of which library (yet) +* Both of these define assert_param() as empty. That may not be what you + want! + + diff --git a/example/libs_stm/build/Makefile b/example/libs_stm/build/Makefile index d96e48c59..d35e3d69f 100644 --- a/example/libs_stm/build/Makefile +++ b/example/libs_stm/build/Makefile @@ -1,37 +1,10 @@ -LIB = libstm32l_discovery.a -CC = arm-none-eabi-gcc -AR = arm-none-eabi-ar -RANLIB = arm-none-eabi-ranlib - -PLATFORM=stm32l1xx - -INC_CORE_SUPPORT=../inc/core_support -SRC_CORE_SUPPORT=../inc/core_support -INC_DEVICE_SUPPORT=../inc/device_support -INC_PLATFORM=../inc/$(PLATFORM) -SRC_PLATFORM=../src/$(PLATFORM) - -CFLAGS = -Wall -O2 -mlittle-endian -mthumb -CFLAGS += -mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc -CFLAGS += -I$(INC_PLATFORM) -I$(INC_DEVICE_SUPPORT) -I$(INC_CORE_SUPPORT) -I../inc/base - -SRCS=$(wildcard $(SRC_PLATFORM)/*.c) -SRCS+=$(SRC_CORE_SUPPORT)/core_cm3.c - -OBJS = $(SRCS:.c=.o) - -all: $(LIB) - -$(LIB): $(OBJS) - $(AR) -r $(LIB) $(OBJS) - $(RANLIB) $(LIB) - -%.o : %.c - $(CC) $(CFLAGS) -c -o $@ $^ +all: + make -f Makefile.f10x + make -f Makefile.l1xx clean: - -rm -f $(OBJS) - -rm -f $(LIB) + make -f Makefile.f10x clean + make -f Makefile.l1xx clean .PHONY: all clean diff --git a/example/libs_stm/build/Makefile.common b/example/libs_stm/build/Makefile.common new file mode 100644 index 000000000..954413e1b --- /dev/null +++ b/example/libs_stm/build/Makefile.common @@ -0,0 +1,34 @@ +CC = arm-none-eabi-gcc +AR = arm-none-eabi-ar +RANLIB = arm-none-eabi-ranlib + + +INC_CORE_SUPPORT=../inc/core_support +SRC_CORE_SUPPORT=../inc/core_support +INC_DEVICE_SUPPORT=../inc/device_support +INC_PLATFORM=../inc/$(PLATFORM) +SRC_PLATFORM=../src/$(PLATFORM) + +CFLAGS += -Wall -O2 -mlittle-endian -mthumb +CFLAGS += -mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc +CFLAGS += -I$(INC_PLATFORM) -I$(INC_DEVICE_SUPPORT) -I$(INC_CORE_SUPPORT) -I../inc/base + +SRCS=$(wildcard $(SRC_PLATFORM)/*.c) +SRCS+=$(SRC_CORE_SUPPORT)/core_cm3.c + +OBJS = $(SRCS:.c=.o) + +all: $(LIB) + +$(LIB): $(OBJS) + $(AR) -r $(LIB) $(OBJS) + $(RANLIB) $(LIB) + +%.o : %.c + $(CC) $(CFLAGS) -c -o $@ $^ + +clean: + -rm -f $(OBJS) + -rm -f $(LIB) + +.PHONY: all clean diff --git a/example/libs_stm/build/Makefile.f10x b/example/libs_stm/build/Makefile.f10x new file mode 100644 index 000000000..dfe0376ab --- /dev/null +++ b/example/libs_stm/build/Makefile.f10x @@ -0,0 +1,5 @@ +LIB = libstm32_stdperiph_f10x.a +PLATFORM=stm32f10x +CFLAGS+= -mcpu=cortex-m3 + +include Makefile.common diff --git a/example/libs_stm/build/Makefile.l1xx b/example/libs_stm/build/Makefile.l1xx new file mode 100644 index 000000000..7469ff58f --- /dev/null +++ b/example/libs_stm/build/Makefile.l1xx @@ -0,0 +1,5 @@ +LIB = libstm32_stdperiph_l1xx.a +PLATFORM=stm32l1xx +CFLAGS+=-mcpu=cortex-m3 + +include Makefile.common diff --git a/example/libs_stm/inc/device_support/stm32f10x.h b/example/libs_stm/inc/device_support/stm32f10x.h new file mode 100644 index 000000000..9d124002e --- /dev/null +++ b/example/libs_stm/inc/device_support/stm32f10x.h @@ -0,0 +1,8227 @@ +/** + ****************************************************************************** + * @file stm32f10x.h + * @author MCD Application Team + * @version V3.3.0 + * @date 04/16/2010 + * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File. + * This file contains all the peripheral register's definitions, bits + * definitions and memory mapping for STM32F10x Connectivity line, High + * density, Medium density, Medium density Value line, Low density + * and Low density Value line and XL-density devices. + ****************************************************************************** + * + * 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. + * + *